Hi Ales Thanks for the patch!
On Tue, Jan 28, 2025 at 10:45 AM Ales Musil <amu...@redhat.com> wrote: > The registers used in actions and lflow created by controller are > hardcoded, which causes upgrade issues. When the register are changed > the "old" version might be still propagated by northd until upgraded. > > To prevent that add flag that will be populated only by northd that > is using the "new" version of registers. The controller checks > this flag and uses proper registers in lflows/actions. > > Reported-by: Xavier Simonart <xsimo...@redhat.com> > Suggested-by: Dumitru Ceara <dce...@redhat.com> > Signed-off-by: Ales Musil <amu...@redhat.com> > --- > controller/lflow.c | 52 +++++++++++++++++++++++------------- > controller/lflow.h | 1 + > controller/ovn-controller.c | 19 +++++++++++++ > include/ovn/actions.h | 4 +++ > include/ovn/logical-fields.h | 7 +++++ > lib/actions.c | 10 +++++-- > northd/en-global-config.c | 4 +++ > tests/test-ovn.c | 1 + > 8 files changed, 78 insertions(+), 20 deletions(-) > > diff --git a/controller/lflow.c b/controller/lflow.c > index 856261f40..a77d07d22 100644 > --- a/controller/lflow.c > +++ b/controller/lflow.c > @@ -100,7 +100,8 @@ consider_logical_flow(const struct sbrec_logical_flow > *lflow, > static void > consider_lb_hairpin_flows(const struct ovn_controller_lb *lb, > const struct hmap *local_datapaths, > - struct ovn_desired_flow_table *flow_table); > + struct ovn_desired_flow_table *flow_table, > + bool register_consolidation); > > static void add_port_sec_flows(const struct shash *binding_lports, > const struct sbrec_chassis *, > @@ -878,6 +879,7 @@ add_matches_to_flow_table(const struct > sbrec_logical_flow *lflow, > .lflow_uuid = lflow->header_.uuid, > .dp_key = ldp->datapath->tunnel_key, > .explicit_arp_ns_output = l_ctx_in->explicit_arp_ns_output, > + .register_consolidation = l_ctx_in->register_consolidation, > > .pipeline = ingress ? OVNACT_P_INGRESS : OVNACT_P_EGRESS, > .ingress_ptable = OFTABLE_LOG_INGRESS_PIPELINE, > @@ -1645,7 +1647,8 @@ static void > add_lb_vip_hairpin_flows(const struct ovn_controller_lb *lb, > struct ovn_lb_vip *lb_vip, > struct ovn_lb_backend *lb_backend, > - struct ovn_desired_flow_table *flow_table) > + struct ovn_desired_flow_table *flow_table, > + bool register_consolidation) > { > uint64_t stub[1024 / 8]; > struct ofpbuf ofpacts = OFPBUF_STUB_INITIALIZER(stub); > @@ -1677,9 +1680,10 @@ add_lb_vip_hairpin_flows(const struct > ovn_controller_lb *lb, > if (!lb->hairpin_orig_tuple) { > match_set_ct_nw_dst(&hairpin_match, vip4); > } else { > - match_set_reg(&hairpin_match, > - MFF_LOG_LB_ORIG_DIP_IPV4 - MFF_LOG_REG0, > - ntohl(vip4)); > + enum mf_field_id id = register_consolidation > + ? MFF_LOG_LB_ORIG_DIP_IPV4 > + : MFF_LOG_LB_ORIG_DIP_IPV4_OLD; > + match_set_reg(&hairpin_match, id - MFF_LOG_REG0, ntohl(vip4)); > } > > add_lb_vip_hairpin_reply_action(NULL, snat_vip4, lb->proto, > @@ -1788,7 +1792,8 @@ static void > add_lb_ct_snat_hairpin_vip_flow(const struct ovn_controller_lb *lb, > const struct ovn_lb_vip *lb_vip, > const struct hmap *local_datapaths, > - struct ovn_desired_flow_table *flow_table) > + struct ovn_desired_flow_table *flow_table, > + bool register_consolidation) > { > uint64_t stub[1024 / 8]; > struct ofpbuf ofpacts = OFPBUF_STUB_INITIALIZER(stub); > @@ -1845,8 +1850,10 @@ add_lb_ct_snat_hairpin_vip_flow(const struct > ovn_controller_lb *lb, > if (!lb->hairpin_orig_tuple) { > match_set_ct_nw_dst(&match, vip4); > } else { > - match_set_reg(&match, MFF_LOG_LB_ORIG_DIP_IPV4 - MFF_LOG_REG0, > - ntohl(vip4)); > + enum mf_field_id id = register_consolidation > + ? MFF_LOG_LB_ORIG_DIP_IPV4 > + : MFF_LOG_LB_ORIG_DIP_IPV4_OLD; > + match_set_reg(&match, id - MFF_LOG_REG0, ntohl(vip4)); > } > } else { > match_set_dl_type(&match, htons(ETH_TYPE_IPV6)); > @@ -1922,7 +1929,8 @@ add_lb_ct_snat_hairpin_vip_flow(const struct > ovn_controller_lb *lb, > static void > add_lb_ct_snat_hairpin_flows(const struct ovn_controller_lb *lb, > const struct hmap *local_datapaths, > - struct ovn_desired_flow_table *flow_table) > + struct ovn_desired_flow_table *flow_table, > + bool register_consolidation) > { > /* We must add a flow for each LB VIP. In the general case, this flow > is added to the OFTABLE_CT_SNAT_HAIRPIN table. If it matches, we > @@ -1956,14 +1964,15 @@ add_lb_ct_snat_hairpin_flows(const struct > ovn_controller_lb *lb, > > for (int i = 0; i < lb->n_vips; i++) { > add_lb_ct_snat_hairpin_vip_flow(lb, &lb->vips[i], local_datapaths, > - flow_table); > + flow_table, > register_consolidation); > } > } > > static void > consider_lb_hairpin_flows(const struct ovn_controller_lb *lb, > const struct hmap *local_datapaths, > - struct ovn_desired_flow_table *flow_table) > + struct ovn_desired_flow_table *flow_table, > + bool register_consolidation) > { > for (size_t i = 0; i < lb->n_vips; i++) { > struct ovn_lb_vip *lb_vip = &lb->vips[i]; > @@ -1971,11 +1980,13 @@ consider_lb_hairpin_flows(const struct > ovn_controller_lb *lb, > for (size_t j = 0; j < lb_vip->n_backends; j++) { > struct ovn_lb_backend *lb_backend = &lb_vip->backends[j]; > > - add_lb_vip_hairpin_flows(lb, lb_vip, lb_backend, flow_table); > + add_lb_vip_hairpin_flows(lb, lb_vip, lb_backend, flow_table, > + register_consolidation); > } > } > > - add_lb_ct_snat_hairpin_flows(lb, local_datapaths, flow_table); > + add_lb_ct_snat_hairpin_flows(lb, local_datapaths, flow_table, > + register_consolidation); > } > > /* Adds OpenFlow flows to flow tables for each Load balancer VIPs and > @@ -1983,11 +1994,13 @@ consider_lb_hairpin_flows(const struct > ovn_controller_lb *lb, > static void > add_lb_hairpin_flows(const struct hmap *local_lbs, > const struct hmap *local_datapaths, > - struct ovn_desired_flow_table *flow_table) > + struct ovn_desired_flow_table *flow_table, > + bool register_consolidation) > { > const struct ovn_controller_lb *lb; > HMAP_FOR_EACH (lb, hmap_node, local_lbs) { > - consider_lb_hairpin_flows(lb, local_datapaths, flow_table); > + consider_lb_hairpin_flows(lb, local_datapaths, flow_table, > + register_consolidation); > } > } > > @@ -2147,7 +2160,8 @@ lflow_run(struct lflow_ctx_in *l_ctx_in, struct > lflow_ctx_out *l_ctx_out) > l_ctx_out->flow_table); > add_lb_hairpin_flows(l_ctx_in->local_lbs, > l_ctx_in->local_datapaths, > - l_ctx_out->flow_table); > + l_ctx_out->flow_table, > + l_ctx_in->register_consolidation); > add_fdb_flows(l_ctx_in->fdb_table, l_ctx_in->local_datapaths, > l_ctx_out->flow_table, > l_ctx_in->sbrec_port_binding_by_key, > @@ -2401,7 +2415,8 @@ lflow_handle_changed_lbs(struct lflow_ctx_in > *l_ctx_in, > UUID_FMT, UUID_ARGS(&uuid_node->uuid)); > ofctrl_remove_flows(l_ctx_out->flow_table, &uuid_node->uuid); > consider_lb_hairpin_flows(lb, l_ctx_in->local_datapaths, > - l_ctx_out->flow_table); > + l_ctx_out->flow_table, > + l_ctx_in->register_consolidation); > } > > UUIDSET_FOR_EACH (uuid_node, new_lbs) { > @@ -2410,7 +2425,8 @@ lflow_handle_changed_lbs(struct lflow_ctx_in > *l_ctx_in, > VLOG_DBG("Add load balancer hairpin flows for "UUID_FMT, > UUID_ARGS(&uuid_node->uuid)); > consider_lb_hairpin_flows(lb, l_ctx_in->local_datapaths, > - l_ctx_out->flow_table); > + l_ctx_out->flow_table, > + l_ctx_in->register_consolidation); > } > > return true; > diff --git a/controller/lflow.h b/controller/lflow.h > index 206328f9e..93a9f3b7e 100644 > --- a/controller/lflow.h > +++ b/controller/lflow.h > @@ -135,6 +135,7 @@ struct lflow_ctx_in { > bool localnet_learn_fdb; > bool localnet_learn_fdb_changed; > bool explicit_arp_ns_output; > + bool register_consolidation; > }; > > struct lflow_ctx_out { > diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c > index 910963e25..63c787bde 100644 > --- a/controller/ovn-controller.c > +++ b/controller/ovn-controller.c > @@ -3520,6 +3520,7 @@ struct ed_type_northd_options { > * switch (i.e with localnet port) should > * be tunnelled or sent via the localnet > * port. Default value is 'false'. */ > + bool register_consolidation; > }; > > > @@ -3557,6 +3558,12 @@ en_northd_options_run(struct engine_node *node, > void *data) > false) > : false; > > + n_opts->register_consolidation = > + sb_global > + ? smap_get_bool(&sb_global->options, "register_consolidation", > + false) > + : false; > + > engine_set_node_state(node, EN_UPDATED); > } > > @@ -3591,6 +3598,17 @@ en_northd_options_sb_sb_global_handler(struct > engine_node *node, void *data) > engine_set_node_state(node, EN_UPDATED); > } > > + bool register_consolidation = > + sb_global > + ? smap_get_bool(&sb_global->options, "register_consolidation", > + false) > + : false; > + > + if (register_consolidation != n_opts->register_consolidation) { > + n_opts->register_consolidation = register_consolidation; > + engine_set_node_state(node, EN_UPDATED); > + } > + > return true; > } > > @@ -3820,6 +3838,7 @@ init_lflow_ctx(struct engine_node *node, > l_ctx_in->localnet_learn_fdb_changed = > rt_data->localnet_learn_fdb_changed; > l_ctx_in->chassis_tunnels = &non_vif_data->chassis_tunnels; > l_ctx_in->explicit_arp_ns_output = n_opts->explicit_arp_ns_output; > + l_ctx_in->register_consolidation = n_opts->register_consolidation; > l_ctx_in->nd_ra_opts = &fo->nd_ra_opts; > l_ctx_in->dhcp_opts = &dhcp_opts->v4_opts; > l_ctx_in->dhcpv6_opts = &dhcp_opts->v6_opts; > diff --git a/include/ovn/actions.h b/include/ovn/actions.h > index db7342f1d..3c3d06570 100644 > --- a/include/ovn/actions.h > +++ b/include/ovn/actions.h > @@ -893,6 +893,10 @@ struct ovnact_encode_params { > /* Indication if we should add explicit output after arp/nd_ns > action. */ > bool explicit_arp_ns_output; > > + /* Indication if we should use the "old" version of registers. */ > + bool register_consolidation; > + > + > /* OVN maps each logical flow table (ltable), one-to-one, onto a > physical > * OpenFlow flow table (ptable). A number of parameters describe this > * mapping and data related to flow tables: > diff --git a/include/ovn/logical-fields.h b/include/ovn/logical-fields.h > index 6a87fc386..f853b1f61 100644 > --- a/include/ovn/logical-fields.h > +++ b/include/ovn/logical-fields.h > @@ -64,6 +64,13 @@ enum ovn_controller_event { > #define MFF_LOG_CT_ORIG_TP_DST_PORT MFF_REG2 /* > REG_ORIG_TP_DPORT > * (bits 0..15). */ > > +/* Logical registers that are needed for backwards > + * compatibility with older northd versions. > + * XXX: All of them can be removed in 26.09. */ > +#define MFF_LOG_LB_ORIG_DIP_IPV4_OLD MFF_REG1 > +#define MFF_LOG_LB_AFF_MATCH_PORT_OLD MFF_REG8 > +#define MFF_LOG_LB_AFF_MATCH_LS_IP6_ADDR_OLD MFF_XXREG0 > + > void ovn_init_symtab(struct shash *symtab); > > /* MFF_LOG_FLAGS_REG bit assignments */ > diff --git a/lib/actions.c b/lib/actions.c > index 62e73b2c5..5dbcfe324 100644 > --- a/lib/actions.c > +++ b/lib/actions.c > @@ -5371,7 +5371,10 @@ encode_COMMIT_LB_AFF(const struct > ovnact_commit_lb_aff *lb_aff, > imm_backend_ip = (union mf_value) { > .ipv6 = lb_aff->backend, > }; > - ol_spec->dst.field = mf_from_id(MFF_LOG_LB_AFF_MATCH_IP6_ADDR); > + enum mf_field_id id = !ep->register_consolidation && ep->is_switch > + ? MFF_LOG_LB_AFF_MATCH_LS_IP6_ADDR_OLD > + : MFF_LOG_LB_AFF_MATCH_IP6_ADDR; > + ol_spec->dst.field = mf_from_id(id); > } else { > ovs_be32 ip4 = in6_addr_get_mapped_ipv4(&lb_aff->backend); > imm_backend_ip = (union mf_value) { > @@ -5399,7 +5402,10 @@ encode_COMMIT_LB_AFF(const struct > ovnact_commit_lb_aff *lb_aff, > .be16 = htons(lb_aff->backend_port), > }; > > - ol_spec->dst.field = mf_from_id(MFF_LOG_LB_AFF_MATCH_PORT); > + enum mf_field_id id = !ep->register_consolidation > + ? MFF_LOG_LB_AFF_MATCH_PORT_OLD > + : MFF_LOG_LB_AFF_MATCH_PORT; > + ol_spec->dst.field = mf_from_id(id); > ol_spec->dst_type = NX_LEARN_DST_LOAD; > ol_spec->src_type = NX_LEARN_SRC_IMMEDIATE; > ol_spec->dst.ofs = 0; > diff --git a/northd/en-global-config.c b/northd/en-global-config.c > index ce16c26f2..9aef9209f 100644 > --- a/northd/en-global-config.c > +++ b/northd/en-global-config.c > @@ -590,6 +590,10 @@ update_sb_config_options_to_sbrec(struct > ed_type_global_config *config_data, > * arp/nd_ns action. */ > smap_add(options, "arp_ns_explicit_output", "true"); > > + /* Adds indication that northd has code with consolidated > + * register usage. */ > + smap_add(options, "register_consolidation", "true"); > + > if (!smap_equal(&sb->options, options)) { > sbrec_sb_global_set_options(sb, options); > } > diff --git a/tests/test-ovn.c b/tests/test-ovn.c > index b097ec084..c310e197e 100644 > --- a/tests/test-ovn.c > +++ b/tests/test-ovn.c > @@ -1366,6 +1366,7 @@ test_parse_actions(struct ovs_cmdl_context *ctx > OVS_UNUSED) > .meter_table = &meter_table, > .collector_ids = &collector_ids, > .explicit_arp_ns_output = true, > + .register_consolidation = true, > > .pipeline = OVNACT_P_INGRESS, > .ingress_ptable = OFTABLE_LOG_INGRESS_PIPELINE, > -- > 2.48.1 > > It looks good to me. I also run some tests in an "upgrade-like" scenario (old ovn-northd with new ovn-controller), and they look ok. Acked-by: Xavier Simonart <xsimo...@redhat.com> Thanks Xavier _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev