Hi Lorenzo Thanks for the review. I'll adjust the patch with your suggestions.
Regards, Lucas Em ter., 3 de fev. de 2026 às 08:31, Lorenzo Bianconi < [email protected]> escreveu: > > Consider the scenario with multiple points of dynamic routing and > > interconnection between different AZs, dynamic routes could be exchanged > > inside ovn interconnection. This options enables that scenario. > > Also, if scenario is multihomed and user doesn't want to re-route the > same ip prefix > > between the point of distribution, it could be disable this option. > > > > scenario 1 (hub-spoke enable): > > Dynamic Routing 1 (adv 10.10.10.0/24, learn 11.11.11.0/24) -> | TS | <- > (adv 11.11.11.0/24, learn 10.10.10.0/24) Dynamic Routing 2 > > > > scenario 2 (hub-spoke disable), same ip prefix is advertised for > redundancy, but it is not exchanged between them: > > ________ > > Dynamic Routing 1 (adv 10.10.10.0/24) -> | TS | > > Dynamic Routing 2 (adv 10.10.10.0/24) -> |________| <- logical_router > (learn both paths by ovn-ic) > > > > Signed-off-by: Lucas Vargas Dias <[email protected]> > > Hi Lucas, > > I guess you need to add an entry in NEWS for this new feature. > > > --- > > ic/ovn-ic.c | 28 ++++++--- > > northd/en-advertised-route-sync.c | 3 + > > northd/northd.c | 13 ++++- > > northd/northd.h | 5 +- > > northd/ovn-northd.c | 1 - > > ovn-nb.xml | 12 ++++ > > tests/ovn-ic.at | 97 +++++++++++++++++++++++++++++++ > > 7 files changed, 149 insertions(+), 10 deletions(-) > > > > diff --git a/ic/ovn-ic.c b/ic/ovn-ic.c > > index fd5ecefb3..e9fff2d4d 100644 > > --- a/ic/ovn-ic.c > > +++ b/ic/ovn-ic.c > > @@ -1283,6 +1283,7 @@ struct ic_route_info { > > struct in6_addr prefix; > > unsigned int plen; > > struct in6_addr nexthop; > > + bool is_src_dynamic; > > const char *origin; > > const char *route_table; > > const char *route_tag; > > @@ -1554,7 +1555,7 @@ add_to_routes_ad(struct hmap *routes_ad, const > struct in6_addr prefix, > > const struct nbrec_logical_router_static_route > *nb_route, > > const struct nbrec_logical_router *nb_lr, > > const struct nbrec_load_balancer *nb_lb, > > - const char *route_tag) > > + const char *route_tag, bool is_src_dynamic) > > { > > ovs_assert(nb_route || nb_lrp || nb_lb || nb_lr); > > > > @@ -1573,6 +1574,7 @@ add_to_routes_ad(struct hmap *routes_ad, const > struct in6_addr prefix, > > ic_route->nb_route = nb_route; > > ic_route->origin = origin; > > ic_route->route_table = route_table; > > + ic_route->is_src_dynamic = is_src_dynamic; > > ic_route->nb_lrp = nb_lrp; > > ic_route->nb_lr = nb_lr; > > ic_route->nb_lb = nb_lb; > > @@ -1649,7 +1651,7 @@ add_static_to_routes_ad( > > > > add_to_routes_ad(routes_ad, prefix, plen, nexthop, > ROUTE_ORIGIN_STATIC, > > nb_route->route_table, NULL, nb_route, nb_lr, > > - NULL, route_tag); > > + NULL, route_tag, false); > > } > > > > static void > > @@ -1659,7 +1661,8 @@ add_network_to_routes_ad(struct hmap *routes_ad, > const char *network, > > const struct smap *nb_options, > > const struct nbrec_logical_router *nb_lr, > > const char *route_tag, > > - const struct nbrec_logical_router_port *ts_lrp) > > + const struct nbrec_logical_router_port *ts_lrp, > > + bool is_src_dynamic) > > { > > struct in6_addr prefix, nexthop; > > unsigned int plen; > > @@ -1711,7 +1714,8 @@ add_network_to_routes_ad(struct hmap *routes_ad, > const char *network, > > > > /* directly-connected routes go to <main> route table */ > > add_to_routes_ad(routes_ad, prefix, plen, nexthop, > ROUTE_ORIGIN_CONNECTED, > > - NULL, nb_lrp, NULL, nb_lr, NULL, route_tag); > > + NULL, nb_lrp, NULL, nb_lr, NULL, route_tag, > > + is_src_dynamic); > > } > > > > static void > > @@ -1769,7 +1773,7 @@ add_lb_vip_to_routes_ad(struct hmap *routes_ad, > const char *vip_key, > > > > /* Lb vip routes go to <main> route table */ > > add_to_routes_ad(routes_ad, vip_ip, plen, nexthop, ROUTE_ORIGIN_LB, > > - NULL, NULL, NULL, nb_lr, nb_lb, route_tag); > > + NULL, NULL, NULL, nb_lr, nb_lb, route_tag, false); > > out: > > free(vip_str); > > } > > @@ -2187,6 +2191,12 @@ sync_learned_routes(struct ic_context *ctx, > > nbrec_logical_router_static_route_update_options_setkey( > > nb_route, "origin", isb_route->origin); > > free(uuid_s); > > + bool is_src_dynamic = > smap_get_bool(&isb_route->external_ids, > > + "ic-source-dynamic", false); > > please document "ic-source-dynamic" as other ic parameters > > > + char *ic_source_dynamic_str = is_src_dynamic ? > > + "true" : "false"; > > + > nbrec_logical_router_static_route_update_external_ids_setkey( > > + nb_route, "ic-source-dynamic", > ic_source_dynamic_str); > > > nbrec_logical_router_update_static_routes_addvalue(ic_lr->lr, > > nb_route); > > } > > @@ -2243,6 +2253,10 @@ ad_route_sync_external_ids(const struct > ic_route_info *route_adv, > > "ic-route-tag"); > > } > > } > > + > > + char *ic_src_dynamic_str = route_adv->is_src_dynamic ? "true" : > "false"; > > + icsbrec_route_update_external_ids_setkey(isb_route, > "ic-source-dynamic", > > + ic_src_dynamic_str); > > } > > > > /* Sync routes from routes_ad to IC-SB. */ > > @@ -2372,7 +2386,7 @@ build_ts_routes_to_adv(struct ic_context *ctx, > > add_network_to_routes_ad(routes_ad, lrp->networks[j], > lrp, > > ts_port_addrs, > > &nb_global->options, > > - lr, route_tag, ts_lrp); > > + lr, route_tag, ts_lrp, false); > > } > > } else { > > /* The router port of the TS port is ignored. */ > > @@ -2427,7 +2441,7 @@ build_ts_routes_to_adv(struct ic_context *ctx, > > add_network_to_routes_ad(routes_ad, sb_route->ip_prefix, NULL, > > ts_port_addrs, > > &nb_global->options, > > - lr, route_tag, ts_lrp); > > + lr, route_tag, ts_lrp, true); > > } > > sbrec_learned_route_index_destroy_row(filter); > > } > > diff --git a/northd/en-advertised-route-sync.c > b/northd/en-advertised-route-sync.c > > index be771391d..be046769f 100644 > > --- a/northd/en-advertised-route-sync.c > > +++ b/northd/en-advertised-route-sync.c > > @@ -675,6 +675,8 @@ should_advertise_route(const struct uuidset > *host_route_lrps, > > return drr_mode_NAT_is_set(drr); > > case ROUTE_SOURCE_LB: > > return drr_mode_LB_is_set(drr); > > + case ROUTE_SOURCE_IC_DYNAMIC: > > + return drr_mode_IC_DYNAMIC_is_set(drr); > > case ROUTE_SOURCE_LEARNED: > > OVS_NOT_REACHED(); > > default: > > @@ -745,6 +747,7 @@ advertise_route_track_od(struct > advertised_route_sync_data *data, > > &tracked_op->od->nbr->header_.uuid); > > } > > break; > > + case ROUTE_SOURCE_IC_DYNAMIC: > > case ROUTE_SOURCE_CONNECTED: > > case ROUTE_SOURCE_STATIC: > > break; > > diff --git a/northd/northd.c b/northd/northd.c > > index adaa94e85..3cbc41386 100644 > > --- a/northd/northd.c > > +++ b/northd/northd.c > > @@ -868,6 +868,10 @@ parse_dynamic_routing_redistribute( > > out |= DRRM_LB; > > continue; > > } > > + if (!strcmp(token, "hub-spoke")) { > > + out |= DRRM_IC_DYNAMIC; > > + continue; > > + } > > static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1); > > VLOG_WARN_RL(&rl, > > "unknown dynamic-routing-redistribute option '%s' > on %s", > > @@ -11894,7 +11898,13 @@ parsed_routes_add_static(const struct > ovn_datapath *od, > > enum route_source source; > > if (!strcmp(smap_get_def(&route->options, "origin", ""), > > ROUTE_ORIGIN_CONNECTED)) { > > - source = ROUTE_SOURCE_CONNECTED; > > + bool ic_src_dynamic = smap_get_bool(&route->external_ids, > > + "ic-source-dynamic", false); > > + if (ic_src_dynamic) { > > + source = ROUTE_SOURCE_IC_DYNAMIC; > > + } else { > > + source = ROUTE_SOURCE_CONNECTED; > > please fix indentation here > > > + } > > } else { > > source = ROUTE_SOURCE_STATIC; > > } > > @@ -11989,6 +11999,7 @@ route_source_to_offset(enum route_source source) > > { > > switch (source) { > > case ROUTE_SOURCE_CONNECTED: > > + case ROUTE_SOURCE_IC_DYNAMIC: > > return ROUTE_PRIO_OFFSET_CONNECTED; > > case ROUTE_SOURCE_STATIC: > > return ROUTE_PRIO_OFFSET_STATIC; > > diff --git a/northd/northd.h b/northd/northd.h > > index e4d7de9f9..62e2cf689 100644 > > --- a/northd/northd.h > > +++ b/northd/northd.h > > @@ -372,7 +372,8 @@ struct mcast_port_info { > > DRR_MODE(CONNECTED_AS_HOST, 1) \ > > DRR_MODE(STATIC, 2) \ > > DRR_MODE(NAT, 3) \ > > - DRR_MODE(LB, 4) > > + DRR_MODE(LB, 4) \ > > + DRR_MODE(IC_DYNAMIC, 5) > > > > enum dynamic_routing_redistribute_mode_bits { > > #define DRR_MODE(PROTOCOL, BIT) DRRM_##PROTOCOL##_BIT = BIT, > > @@ -825,6 +826,8 @@ enum route_source { > > ROUTE_SOURCE_NAT, > > /* The route is derived from a LB's VIP. */ > > ROUTE_SOURCE_LB, > > + /* The route is derived from an ovn-controller and advertised to > IC. */ > > + ROUTE_SOURCE_IC_DYNAMIC, > > }; > > > > struct parsed_route { > > diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c > > index 7d7568c6f..bc3969053 100644 > > --- a/northd/ovn-northd.c > > +++ b/northd/ovn-northd.c > > @@ -905,7 +905,6 @@ main(int argc, char *argv[]) > > &nbrec_load_balancer_col_external_ids, > > &nbrec_load_balancer_health_check_col_external_ids, > > &nbrec_logical_router_policy_col_external_ids, > > - &nbrec_logical_router_static_route_col_external_ids, > > &nbrec_meter_col_external_ids, > > &nbrec_meter_band_col_external_ids, > > &nbrec_mirror_col_external_ids, > > diff --git a/ovn-nb.xml b/ovn-nb.xml > > index e9ca27413..aedda71da 100644 > > --- a/ovn-nb.xml > > +++ b/ovn-nb.xml > > @@ -3371,6 +3371,12 @@ or > > Logical Switch. > > </p> > > > > + <p> > > + If <code>hub-spoke</code> is in the list then northd will > synchronize > > + all dynamic routes from other router that announce them in > ovn-ic in > > + <ref table="Advertised_Route" db="OVN_Southbound"/> table. > > + </p> > > this explanation is not very clear (at least to me), can you please > elaborate? > > > + > > <p> > > This value can be overwritten on a per LRP basis using > > <ref column="options" key="dynamic-routing-redistribute" > > @@ -4458,6 +4464,12 @@ or > > via shared Logical Switch. > > </p> > > > > + <p> > > + If <code>hub-spoke</code> is in the list then northd will > synchronize > > + all dynamic routes from other router that announce them in > ovn-ic in > > + <ref table="Advertised_Route" db="OVN_Southbound"/> table. > > + </p> > > + > > ditto > > > <p> > > If not set the value from <ref column="options" > > key="dynamic-routing-redistribute" table="Logical_Router"/> > on the > > diff --git a/tests/ovn-ic.at b/tests/ovn-ic.at > > index 370a755be..77c5d0034 100644 > > --- a/tests/ovn-ic.at > > +++ b/tests/ovn-ic.at > > @@ -4586,3 +4586,100 @@ OVN_CLEANUP_IC([az1], [az2]) > > > > AT_CLEANUP > > ]) > > + > > + > > +OVN_FOR_EACH_NORTHD([ > > +AT_SETUP([ovn-ic -- Check ovn-ic adv and learn from SB Learned Route - > hub and spoke mode]) > > + > > +ovn_init_ic_db > > + > > +for i in 1 2; do > > + ovn_start az$i > > + ovn_as az$i > > + > > + # Enable route learning at AZ level > > + check ovn-nbctl set nb_global . options:ic-route-learn=true > > + # Enable route advertising at AZ level > > + check ovn-nbctl set nb_global . options:ic-route-adv=true > > +done > > + > > +# Create new transit switches and LRs. Test topology is next: > > +# > > +# > > +# logical router (lr11) - transit switch (ts11) - logical router (lr12) > > +# > > +# > > + > > +# Create lr11, lr12 and ts11 and connect them > > +for i in 1 2; do > > + ovn_as az$i > > + > > + lr=lr1$i > > + check ovn-nbctl lr-add $lr > > + > > + for j in 1; do > > you do not need this for loop here > > > + ts=ts1$j > > + check ovn-ic-nbctl --wait=sb --may-exist ts-add $ts > > + > > + lrp=lrp-$lr-$ts > > + lsp=lsp-$ts-$lr > > + # Create LRP and connect to TS > > + check ovn-nbctl lrp-add $lr $lrp aa:aa:aa:aa:a$j:0$i > 169.254.10$j.$i/24 > > + check ovn-nbctl lsp-add $ts $lsp \ > > + -- lsp-set-addresses $lsp router \ > > + -- lsp-set-type $lsp router \ > > + -- lsp-set-options $lsp router-port=$lrp > > + done > > +done > > + > > +# Create directly-connected route in lr11 > > it should be lr12 > > Regards, > Lorenzo > > > +check ovn_as az2 ovn-nbctl lrp-add lr12 lrp-lr12 aa:aa:aa:aa:bb:01 " > 192.168.0.1/24" > > +OVS_WAIT_FOR_OUTPUT([ovn_as az1 ovn-nbctl lr-route-list lr11 | grep > 192.168 | > > + grep learned | awk '{print $1, $2}' | sort ], [0], [dnl > > +192.168.0.0/24 169.254.101.2 > > +]) > > + > > +ovn_as az2 > > +check ovn-nbctl --wait=sb set Logical_Router lr12 > option:dynamic-routing=true \ > > + option:dynamic-routing-redistribute="connected,static" > > +check ovn_as az2 ovn-nbctl --wait=sb lrp-add lr12 lr12-dr1 > 00:00:00:00:ff:01 10.0.0.1/24 > > +dr1=$(fetch_column port_binding _uuid logical_port=lr12-dr1) > > +datapath=$(fetch_column datapath_binding _uuid external_ids:name=lr12) > > + > > +check_uuid ovn-sbctl create Learned_Route \ > > + datapath=$datapath \ > > + logical_port=$dr1 \ > > + ip_prefix=192.168.1.0/24 \ > > + nexthop=10.0.0.20 > > + > > +# Check Learned_Route adv in ovn-ic > > +OVS_WAIT_FOR_OUTPUT([ovn_as az1 ovn-nbctl lr-route-list lr11 | > > + grep learned | awk '{print $1, $2}' | sort ], [0], [dnl > > +10.0.0.0/24 169.254.101.2 > > +192.168.0.0/24 169.254.101.2 > > +192.168.1.0/24 169.254.101.2 > > +]) > > + > > +ovn_as az1 > > +check ovn-nbctl --wait=sb set Logical_Router lr11 > option:dynamic-routing=true \ > > + option:dynamic-routing-redistribute="connected,static" > > +# Advertise just 10.0.0.0/24 and 192.168.0.0/24 routes > > +check_row_count Advertised_Route 1 ip_prefix=192.168.0.0/24 > > +check_row_count Advertised_Route 1 ip_prefix=10.0.0.0/24 > > +check_row_count Advertised_Route 0 ip_prefix=192.168.1.0/24 > > + > > + > > +ovn_as az1 > > +check ovn-nbctl --wait=sb set Logical_Router lr11 \ > > + option:dynamic-routing-redistribute="connected,static,hub-spoke" > > +# Advertise just 10.0.0.0/24, 192.168.0.0/24 and 192.168.1.0/24 routes > > +# Route 192.168.1.0/24 is learned by DR from other logical routes > (lr12) > > +# And lr12 Advertised it in ovn-ic. Hub-spoke option enable re-routing > in lr11 > > +check_row_count Advertised_Route 1 ip_prefix=192.168.0.0/24 > > +check_row_count Advertised_Route 1 ip_prefix=10.0.0.0/24 > > +check_row_count Advertised_Route 1 ip_prefix=192.168.1.0/24 > > + > > +OVN_CLEANUP_IC([az1], [az2]) > > + > > +AT_CLEANUP > > +]) > > -- > > 2.43.0 > > > > > > -- > > > > > > > > > > _'Esta mensagem é direcionada apenas para os endereços constantes no > > cabeçalho inicial. Se você não está listado nos endereços constantes no > > cabeçalho, pedimos-lhe que desconsidere completamente o conteúdo dessa > > mensagem e cuja cópia, encaminhamento e/ou execução das ações citadas > estão > > imediatamente anuladas e proibidas'._ > > > > > > * **'Apesar do Magazine Luiza tomar > > todas as precauções razoáveis para assegurar que nenhum vírus esteja > > presente nesse e-mail, a empresa não poderá aceitar a responsabilidade > por > > quaisquer perdas ou danos causados por esse e-mail ou por seus anexos'.* > > > > > > > > _______________________________________________ > > dev mailing list > > [email protected] > > https://mail.openvswitch.org/mailman/listinfo/ovs-dev > > > -- _‘Esta mensagem é direcionada apenas para os endereços constantes no cabeçalho inicial. Se você não está listado nos endereços constantes no cabeçalho, pedimos-lhe que desconsidere completamente o conteúdo dessa mensagem e cuja cópia, encaminhamento e/ou execução das ações citadas estão imediatamente anuladas e proibidas’._ * **‘Apesar do Magazine Luiza tomar todas as precauções razoáveis para assegurar que nenhum vírus esteja presente nesse e-mail, a empresa não poderá aceitar a responsabilidade por quaisquer perdas ou danos causados por esse e-mail ou por seus anexos’.* _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
