On 5/18/23 12:56, Ihar Hrachyshka wrote: > This will be used in a later patch to calculate the effective interface > MTU after considering tunneling overhead. > > NOTE: ideally, OVN would support Logical_Port MTU, in which case we > wouldn't have to track OVSDB for interfaces. > > Signed-off-by: Ihar Hrachyshka <ihrac...@redhat.com> > ---
Hi Ihar, > controller/binding.c | 4 +- > controller/if-status.c | 36 ++++++++++++++++-- > controller/if-status.h | 6 +++ > controller/ovn-controller.c | 76 +++++++++++++++++++++++++++++++++++++ > controller/ovsport.c | 9 +++++ > controller/ovsport.h | 2 + > controller/physical.h | 2 + > 7 files changed, 129 insertions(+), 6 deletions(-) > > diff --git a/controller/binding.c b/controller/binding.c > index bd810f669..a627618b7 100644 > --- a/controller/binding.c > +++ b/controller/binding.c > @@ -1273,7 +1273,7 @@ claim_lport(const struct sbrec_port_binding *pb, > } > set_pb_chassis_in_sbrec(pb, chassis_rec, true); > } else { > - if_status_mgr_claim_iface(if_mgr, pb, chassis_rec, > + if_status_mgr_claim_iface(if_mgr, pb, chassis_rec, iface_rec, > sb_readonly); > } > register_claim_timestamp(pb->logical_port, now); > @@ -1288,7 +1288,7 @@ claim_lport(const struct sbrec_port_binding *pb, > !smap_get_bool(&iface_rec->external_ids, > OVN_INSTALLED_EXT_ID, false)) { > if_status_mgr_claim_iface(if_mgr, pb, chassis_rec, > - sb_readonly); > + iface_rec, sb_readonly); > } > } > } > diff --git a/controller/if-status.c b/controller/if-status.c > index 8503e5daa..dc4062559 100644 > --- a/controller/if-status.c > +++ b/controller/if-status.c > @@ -18,12 +18,14 @@ > #include "binding.h" > #include "if-status.h" > #include "ofctrl-seqno.h" > +#include "ovsport.h" > #include "simap.h" > > #include "lib/hmapx.h" > #include "lib/util.h" > #include "timeval.h" > #include "openvswitch/vlog.h" > +#include "lib/vswitch-idl.h" > #include "lib/ovn-sb-idl.h" > > VLOG_DEFINE_THIS_MODULE(if_status); > @@ -181,6 +183,7 @@ struct ovs_iface { > * be fully programmed in OVS. Only used in > state > * OIF_INSTALL_FLOWS. > */ > + uint16_t mtu; /* Extracted from OVS interface.mtu field. */ > }; > > static uint64_t ifaces_usage; > @@ -205,9 +208,10 @@ struct if_status_mgr { > uint32_t iface_seqno; > }; > > -static struct ovs_iface *ovs_iface_create(struct if_status_mgr *, > - const char *iface_id, > - enum if_state ); > +static struct ovs_iface * > +ovs_iface_create(struct if_status_mgr *, const char *iface_id, > + const struct ovsrec_interface *iface_rec, > + enum if_state); > static void add_to_ovn_uninstall_hash(struct if_status_mgr *, const char *, > const struct uuid *); > static void ovs_iface_destroy(struct if_status_mgr *, struct ovs_iface *); > @@ -272,13 +276,14 @@ void > if_status_mgr_claim_iface(struct if_status_mgr *mgr, > const struct sbrec_port_binding *pb, > const struct sbrec_chassis *chassis_rec, > + const struct ovsrec_interface *iface_rec, > bool sb_readonly) > { > const char *iface_id = pb->logical_port; > struct ovs_iface *iface = shash_find_data(&mgr->ifaces, iface_id); > > if (!iface) { > - iface = ovs_iface_create(mgr, iface_id, OIF_CLAIMED); > + iface = ovs_iface_create(mgr, iface_id, iface_rec, OIF_CLAIMED); > } > > memcpy(&iface->pb_uuid, &pb->header_.uuid, sizeof(iface->pb_uuid)); > @@ -639,14 +644,37 @@ ovn_uninstall_hash_account_mem(const char *name, bool > erase) > } > } > > +uint16_t > +if_status_mgr_iface_get_mtu(const struct if_status_mgr *mgr, > + const char *iface_id) > +{ > + const struct ovs_iface *iface = shash_find_data(&mgr->ifaces, iface_id); > + return iface ? iface->mtu : 0; > +} > + > +bool > +if_status_mgr_iface_set_mtu(const struct if_status_mgr *mgr, > + const char *iface_id, > + uint16_t mtu) > +{ > + struct ovs_iface *iface = shash_find_data(&mgr->ifaces, iface_id); > + if (iface && iface->mtu != mtu) { > + iface->mtu = mtu; > + return true; > + } > + return false; > +} > + > static struct ovs_iface * > ovs_iface_create(struct if_status_mgr *mgr, const char *iface_id, > + const struct ovsrec_interface *iface_rec, > enum if_state state) > { > struct ovs_iface *iface = xzalloc(sizeof *iface); > > VLOG_DBG("Interface %s create.", iface_id); > iface->id = xstrdup(iface_id); > + iface->mtu = get_iface_mtu(iface_rec); > shash_add_nocopy(&mgr->ifaces, iface->id, iface); > ovs_iface_set_state(mgr, iface, state); > ovs_iface_account_mem(iface_id, false); > diff --git a/controller/if-status.h b/controller/if-status.h > index 8ba80acd9..0ed43431f 100644 > --- a/controller/if-status.h > +++ b/controller/if-status.h > @@ -30,6 +30,7 @@ void if_status_mgr_destroy(struct if_status_mgr *); > void if_status_mgr_claim_iface(struct if_status_mgr *, > const struct sbrec_port_binding *pb, > const struct sbrec_chassis *chassis_rec, > + const struct ovsrec_interface *iface_rec, > bool sb_readonly); > void if_status_mgr_release_iface(struct if_status_mgr *, const char > *iface_id); > void if_status_mgr_delete_iface(struct if_status_mgr *, const char > *iface_id); > @@ -56,5 +57,10 @@ bool if_status_handle_claims(struct if_status_mgr *mgr, > void if_status_mgr_remove_ovn_installed(struct if_status_mgr *mgr, > const char *name, > const struct uuid *uuid); > +uint16_t if_status_mgr_iface_get_mtu(const struct if_status_mgr *mgr, > + const char *iface_id); > +bool if_status_mgr_iface_set_mtu(const struct if_status_mgr *mgr, > + const char *iface_id, > + uint16_t mtu); > > # endif /* controller/if-status.h */ > diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c > index de90025f0..132831dde 100644 > --- a/controller/ovn-controller.c > +++ b/controller/ovn-controller.c > @@ -60,6 +60,7 @@ > #include "lib/ovn-dirs.h" > #include "lib/ovn-sb-idl.h" > #include "lib/ovn-util.h" > +#include "ovsport.h" > #include "patch.h" > #include "vif-plug.h" > #include "vif-plug-provider.h" > @@ -1056,6 +1057,7 @@ ctrl_register_ovs_idl(struct ovsdb_idl *ovs_idl) > ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_name); > ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_bfd); > ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_bfd_status); > + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_mtu); > ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_type); > ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_options); > ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_ofport); > @@ -4046,6 +4048,9 @@ static void init_physical_ctx(struct engine_node *node, > const struct ed_type_mff_ovn_geneve *ed_mff_ovn_geneve = > engine_get_input_data("mff_ovn_geneve", node); > > + const struct ovsrec_interface_table *ovs_interface_table = > + EN_OVSDB_GET(engine_get_input("OVS_interface", node)); > + > const struct ovsrec_open_vswitch_table *ovs_table = > EN_OVSDB_GET(engine_get_input("OVS_open_vswitch", node)); > const struct ovsrec_bridge_table *bridge_table = > @@ -4070,6 +4075,7 @@ static void init_physical_ctx(struct engine_node *node, > p_ctx->sbrec_port_binding_by_name = sbrec_port_binding_by_name; > p_ctx->sbrec_port_binding_by_datapath = sbrec_port_binding_by_datapath; > p_ctx->port_binding_table = port_binding_table; > + p_ctx->ovs_interface_table = ovs_interface_table; > p_ctx->mc_group_table = multicast_group_table; > p_ctx->br_int = br_int; > p_ctx->chassis_table = chassis_table; > @@ -4083,6 +4089,9 @@ static void init_physical_ctx(struct engine_node *node, > p_ctx->patch_ofports = &non_vif_data->patch_ofports; > p_ctx->chassis_tunnels = &non_vif_data->chassis_tunnels; > > + struct controller_engine_ctx *ctrl_ctx = > engine_get_context()->client_ctx; > + p_ctx->if_mgr = ctrl_ctx->if_mgr; > + > pflow_output_get_debug(node, &p_ctx->debug); > } > > @@ -4126,6 +4135,71 @@ en_pflow_output_run(struct engine_node *node, void > *data) > engine_set_node_state(node, EN_UPDATED); > } > > +static bool > +pflow_output_ovs_interface_handler(struct engine_node *node, > + void *data) > +{ > + enum engine_node_state state = EN_UNCHANGED; > + > + struct ed_type_pflow_output *pfo = data; > + struct ed_type_runtime_data *rt_data = > + engine_get_input_data("runtime_data", node); > + struct ed_type_non_vif_data *non_vif_data = > + engine_get_input_data("non_vif_data", node); > + > + struct physical_ctx p_ctx; > + init_physical_ctx(node, rt_data, non_vif_data, &p_ctx); > + > + const struct ovsrec_interface *iface; > + const struct ovsrec_interface_table *ovs_interface_table = > + p_ctx.ovs_interface_table; > + OVSREC_INTERFACE_TABLE_FOR_EACH_TRACKED (iface, ovs_interface_table) { > + const char *iface_id = smap_get(&iface->external_ids, "iface-id"); > + if (!iface_id) { > + continue; > + } > + > + uint16_t mtu = get_iface_mtu(iface); > + if (!if_status_mgr_iface_set_mtu(p_ctx.if_mgr, iface_id, mtu)) { > + continue; > + } > + const struct sbrec_port_binding *pb = lport_lookup_by_name( > + p_ctx.sbrec_port_binding_by_name, iface_id); > + if (!pb) { > + continue; > + } > + if (pb->n_additional_chassis) { > + /* Update flows for all ports in datapath. */ > + struct sbrec_port_binding *target = > + sbrec_port_binding_index_init_row( > + p_ctx.sbrec_port_binding_by_datapath); > + sbrec_port_binding_index_set_datapath(target, pb->datapath); > + > + const struct sbrec_port_binding *binding; > + SBREC_PORT_BINDING_FOR_EACH_EQUAL ( > + binding, target, p_ctx.sbrec_port_binding_by_datapath) { > + bool removed = sbrec_port_binding_is_deleted(binding); > + if (!physical_handle_flows_for_lport(binding, removed, > &p_ctx, > + &pfo->flow_table)) { > + return false; > + } > + state = EN_UPDATED; > + } > + sbrec_port_binding_index_destroy_row(target); > + } else { > + /* If any multichassis ports, update flows for the port. */ > + bool removed = sbrec_port_binding_is_deleted(pb); > + if (!physical_handle_flows_for_lport(pb, removed, &p_ctx, > + &pfo->flow_table)) { > + return false; > + } > + state = EN_UPDATED; > + } > + } > + engine_set_node_state(node, state); It's not OK to set the I-P node's state to EN_UNCHANGED from within an I-P handler. We might be overwriting EN_UPDATED set by a different I-P handler. Note: it _is_ however OK to do this from the _run() handler. Which brings me to the question: don't we need to call if_status_mgr_iface_set_mtu() from the path that processes a recompute of the pflow_output I-P node? Maybe somewhere in the en_pflow_output_run() -> physical_run() -> consider_port_binding() call chain? The rest looks OK to me. Regards, Dumitru _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev