| Message ID | 20260831132353.50733-1-ARukomoinikova@k2.cloud |
|---|---|
| State | New |
| Headers | show |
| Series | [ovs-dev] northd: Add per-LRP option to advertise an explicit prefix list. | expand |
| Context | Check | Description |
|---|---|---|
| ovsrobot/apply-robot | success | apply and check: success |
Thanks for the patch, Alexandra. I have a few comments. On Mon, Aug 31, 2026 at 9:25 AM Alexandra Rukomoinikova via dev < ovs-dev@openvswitch.org> wrote: > Add the "options:dynamic-routing-advertise-prefixes" key to the > Logical_Router_Port table. If it is set, only the listed prefixes are > synced to the SB Advertised_Route table for that port and every route > selected by "dynamic-routing-redistribute" (connected, static, nat, lb, > hub-spoke) is skipped on it. This lets the CMS announce an aggregated > prefix instead of many individual NAT or LB addresses. > > Signed-off-by: Alexandra Rukomoinikova <ARukomoinikova@k2.cloud> > --- > NEWS | 4 ++ > northd/en-advertised-route-sync.c | 69 ++++++++++++++++++- > ovn-nb.xml | 30 +++++++++ > tests/ovn-northd.at | 108 ++++++++++++++++++++++++++++++ > 4 files changed, 210 insertions(+), 1 deletion(-) > > diff --git a/NEWS b/NEWS > index 40a1b9867..78af38f9f 100644 > --- a/NEWS > +++ b/NEWS > @@ -120,6 +120,10 @@ OVN v26.09.0 - xxx xx xxxx > filter the routes learned through the port by route tag. This > supersedes > "ic-route-filter-tag", which is now deprecated and is ignored when > "ic-route-learn-tag-rules" is set. > + - Logical_Router_Port: Added a new > + "options:dynamic-routing-advertise-prefixes" key that contains an > + explicit list of prefixes to be advertised via this port. If it is > + set, only these prefixes will be announced. > > OVN v26.03.0 - xxx xx xxxx > -------------------------- > diff --git a/northd/en-advertised-route-sync.c > b/northd/en-advertised-route-sync.c > index eb8a24a39..c623d9ba0 100644 > --- a/northd/en-advertised-route-sync.c > +++ b/northd/en-advertised-route-sync.c > @@ -29,6 +29,8 @@ > > VLOG_DEFINE_THIS_MODULE(en_advertised_route_sync); > > +#define DYNAMIC_ROUTING_ADVERTISE_PREFIXES > "dynamic-routing-advertise-prefixes" > + > struct ar_entry { > struct hmap_node hmap_node; > > @@ -50,6 +52,8 @@ struct ar_entry { > * unmonitored listener must remain reachable regardless. */ > bool has_ungated_lb; > struct sset health_checks; > + > + bool advertise_prefix; > Could you add an inline comment? Other members of this struct have them. > }; > > /* Add a new entries to the to-be-advertised routes. > @@ -871,6 +875,61 @@ build_connected_as_host_routes(const struct > ovn_datapath *od, > } > } > > +static const char * > +lrp_advertise_prefixes(const struct ovn_port *op) > could you add a comment describing what this function does and returns > +{ > + if (!op || !op->nbrp) { > + return NULL; > + } > + > + return smap_get(&op->nbrp->options, > DYNAMIC_ROUTING_ADVERTISE_PREFIXES); > +} > + > +static void > +build_advertise_prefix_routes(const struct ovn_datapath *od, > + struct hmap *routes) > same as lrp_advertise_prefixes > +{ > + const struct ovn_port *op; > + HMAP_FOR_EACH (op, dp_node, &od->ports) { > + const char *prefixes = lrp_advertise_prefixes(op); > + if (!prefixes || !op->sb) { > + continue; > + } > + > + char *save_ptr = NULL; > + char *tokstr = xstrdup(prefixes); > + for (char *token = strtok_r(tokstr, ",", &save_ptr); > + token != NULL; > + token = strtok_r(NULL, ",", &save_ptr)) { > + struct in6_addr prefix; > + unsigned int plen; > + > + if (!ip46_parse_cidr(token, &prefix, &plen)) { > + static struct vlog_rate_limit rl = > VLOG_RATE_LIMIT_INIT(5, 1); > + VLOG_WARN_RL(&rl, "bad prefix '%s' in option %s of %s", > + token, DYNAMIC_ROUTING_ADVERTISE_PREFIXES, > + op->nbrp->name); > + continue; > + } > + > + char *ip_prefix = normalize_v46_prefix(&prefix, plen); > + struct ar_entry *dup = ar_entry_find(routes, od->sdp->sb_dp, > + op->sb, ip_prefix, NULL); > + if (dup && dup->advertise_prefix) { > + /* The same prefix is listed twice in the option. */ > + free(ip_prefix); > + continue; > + } > + > + struct ar_entry *route_e = > + ar_entry_add_nocopy(routes, od, op, ip_prefix, NULL, > + ROUTE_SOURCE_STATIC); > This is misleading. ROUTE_SOURCE_STATIC is derived from the northbound static route table which is not happening here. The source is only inspected by should_advertise_route, which the advertise_prefix flag buypasses and in ar_entry_sync_external_ids which only cares about ROUTE_SOURCE_LB so it is not functionally wrong. Adding another enum for ROUTE_SOURCE_EXPLICITLY_ADVERTISED or something would make the code cleaner and no one would wonder why ROUTE_SOURCE_STATIC is used. > + route_e->advertise_prefix = true; > + } > + free(tokstr); > + } > +} > + > void * > en_dynamic_routes_init(struct engine_node *node OVS_UNUSED, > struct engine_arg *arg OVS_UNUSED) > @@ -989,6 +1048,8 @@ en_dynamic_routes_run(struct engine_node *node, void > *data) > build_connected_as_host_routes(od, &northd_data->ls_ports, > dynamic_routes_data); > > + build_advertise_prefix_routes(od, &dynamic_routes_data->routes); > + > const struct lr_stateful_record *lr_stateful_rec = > lr_stateful_table_find_by_uuid(&lr_stateful_data->table, > od->key); > if (!lr_stateful_rec) { > @@ -1105,6 +1166,11 @@ should_advertise_route(const struct ovn_datapath > *advertising_od, > return false; > } > > + if (lrp_advertise_prefixes(advertising_op)) { > + /* This port advertises only the explicitly configured prefixes. > */ > + return false; > + } > + > enum dynamic_routing_redistribute_mode drr = > advertising_op->dynamic_routing_redistribute; > > @@ -1178,7 +1244,8 @@ advertised_route_table_sync( > /* Then add the set of dynamic routes that need sync-ing. */ > struct ar_entry *route_e; > HMAP_FOR_EACH (route_e, hmap_node, dynamic_routes) { > - if (!should_advertise_route(route_e->od, route_e->op, > + if (!route_e->advertise_prefix && > + !should_advertise_route(route_e->od, route_e->op, > route_e->source)) { > continue; > } > diff --git a/ovn-nb.xml b/ovn-nb.xml > index c741a3b32..c771b7e05 100644 > --- a/ovn-nb.xml > +++ b/ovn-nb.xml > @@ -4850,6 +4850,36 @@ or > > </column> > > + <column name="options" key="dynamic-routing-advertise-prefixes" > + type='{"type": "string"}'> > + <p> > + Only relevant if <ref column="options" key="dynamic-routing" > + table="Logical_Router"/> on the respective Logical_Router is set > + to <code>true</code>. > + </p> > + > + <p> > + This is a list of IPv4 and/or IPv6 prefixes in CIDR notation, > + separated by <code>,</code>, e.g. > + <code>10.0.0.0/8,2001:db8::/32</code>. > + </p> > + > + <p> > + If this option is set, northd creates entries in the <ref > + table="Advertised_Route" db="OVN_Southbound"/> table only for > the > + prefixes listed here. Every route that would otherwise be > + advertised via this port because of <ref column="options" > + key="dynamic-routing-redistribute" > + table="Logical_Router_Port"/> (or its Logical_Router > counterpart), > + i.e. <code>connected</code>, <code>connected-as-host</code>, > + <code>static</code>, <code>nat</code>, <code>lb</code> and > + <code>hub-spoke</code> routes, is not advertised via this port. > + Setting the option to an empty string disables all > advertisements > + on this port. > + </p> > + > + </column> > + > <column name="options" key="dynamic-routing-advertise"> > If the CMS sets <ref column="options" > key="dynamic-routing-redistribute" > table="Logical_Router_Port"/> to <code>connected-as-host</code>, > diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at > index 6d191c1a0..45322ffcb 100644 > --- a/tests/ovn-northd.at > +++ b/tests/ovn-northd.at > @@ -16525,6 +16525,114 @@ OVN_CLEANUP_NORTHD > AT_CLEANUP > ]) > > +OVN_FOR_EACH_NORTHD_NO_HV([ > +AT_SETUP([dynamic-routing - advertise only configured prefixes]) > +AT_KEYWORDS([dynamic-routing]) > +ovn_start > + > +# Start with a GW router that advertises connected, static, nat and lb > routes > +# via both of its LRPs. > +check ovn-nbctl lr-add lr0 > +check ovn-nbctl set Logical_Router lr0 \ > + options:dynamic-routing=true \ > + options:chassis=hv1 \ > + options:dynamic-routing-redistribute="connected,static,nat,lb" > +check ovn-nbctl lrp-add lr0 lr0-sw0 00:00:00:00:ff:01 10.0.0.1/24 > +check ovn-nbctl lrp-add lr0 lr0-sw1 00:00:00:00:ff:02 10.0.1.1/24 > +check ovn-nbctl lr-route-add lr0 192.168.0.0/24 10.0.0.10 > +check ovn-nbctl lr-nat-add lr0 dnat_and_snat 172.16.1.10 10.0.0.20 > +check ovn-nbctl lb-add lb0 172.16.2.10:80 10.0.0.30:80 > +check ovn-nbctl lr-lb-add lr0 lb0 > +check ovn-nbctl --wait=sb sync > + > +datapath=$(fetch_column Datapath_Binding _uuid external_ids:name=lr0) > +sw0=$(fetch_column Port_Binding _uuid logical_port=lr0-sw0) > +sw1=$(fetch_column Port_Binding _uuid logical_port=lr0-sw1) > + > +check_row_count Advertised_Route 7 > +check_row_count Advertised_Route 4 logical_port=$sw0 > +check_row_count Advertised_Route 1 logical_port=$sw0 ip_prefix= > 10.0.0.0/24 > +check_row_count Advertised_Route 1 logical_port=$sw0 ip_prefix= > 192.168.0.0/24 > +check_row_count Advertised_Route 1 logical_port=$sw0 ip_prefix=172.16.1.10 > +check_row_count Advertised_Route 1 logical_port=$sw0 ip_prefix=172.16.2.10 > +check_row_count Advertised_Route 3 logical_port=$sw1 > + > +# Setting dynamic-routing-advertise-prefixes on lr0-sw0 replaces every > route > +# advertised via this port with the configured ones. Both IPv4 and IPv6 > +# prefixes are supported. The other LRP is not affected. > +check ovn-nbctl --wait=sb set Logical_Router_Port lr0-sw0 \ > + options:dynamic-routing-advertise-prefixes=" > 172.16.0.0/16,2001:db8:1::/64" > +check_row_count Advertised_Route 5 > +check_row_count Advertised_Route 2 logical_port=$sw0 > +check_row_count Advertised_Route 1 \ > + ip_prefix="172.16.0.0/16" \ > + datapath=$datapath \ > + logical_port=$sw0 \ > + tracked_port=[[]] > +check_row_count Advertised_Route 1 \ > + ip_prefix='"2001:db8:1::/64"' \ > + datapath=$datapath \ > + logical_port=$sw0 \ > + tracked_port=[[]] > +check_row_count Advertised_Route 3 logical_port=$sw1 > +check_row_count Advertised_Route 1 logical_port=$sw1 ip_prefix= > 10.0.1.0/24 > +check_row_count Advertised_Route 1 logical_port=$sw1 ip_prefix=172.16.1.10 > +check_row_count Advertised_Route 1 logical_port=$sw1 ip_prefix=172.16.2.10 > + > +# The prefixes are normalized and duplicates are advertised only once. > +check ovn-nbctl --wait=sb set Logical_Router_Port lr0-sw0 \ > + options:dynamic-routing-advertise-prefixes=" > 10.10.10.5/24,10.10.10.0/24" > +check_row_count Advertised_Route 1 logical_port=$sw0 > +check_row_count Advertised_Route 1 logical_port=$sw0 ip_prefix= > 10.10.10.0/24 > + > +# Invalid prefixes are ignored, the valid ones are still advertised. > +check ovn-nbctl --wait=sb set Logical_Router_Port lr0-sw0 \ > + options:dynamic-routing-advertise-prefixes="not-a-prefix,10.20.0.0/16 > " > +check_row_count Advertised_Route 1 logical_port=$sw0 > +check_row_count Advertised_Route 1 logical_port=$sw0 ip_prefix= > 10.20.0.0/16 > + > +# An empty list blocks all advertisements on this port. > +check ovn-nbctl --wait=sb set Logical_Router_Port lr0-sw0 \ > + options:dynamic-routing-advertise-prefixes='""' > +check_row_count Advertised_Route 0 logical_port=$sw0 > +check_row_count Advertised_Route 3 logical_port=$sw1 > + > +# The option also overrides the redistribute modes set on the LRP itself. > +check ovn-nbctl --wait=sb set Logical_Router_Port lr0-sw0 \ > + options:dynamic-routing-redistribute="connected,static,nat,lb" \ > + options:dynamic-routing-advertise-prefixes="10.30.0.0/16" > +check_row_count Advertised_Route 1 logical_port=$sw0 > +check_row_count Advertised_Route 1 logical_port=$sw0 ip_prefix= > 10.30.0.0/16 > + > +# Removing the option brings the redistributed routes back. > +check ovn-nbctl --wait=sb remove Logical_Router_Port lr0-sw0 \ > + options dynamic-routing-advertise-prefixes > +check_row_count Advertised_Route 4 logical_port=$sw0 > +check_row_count Advertised_Route 1 logical_port=$sw0 ip_prefix= > 10.0.0.0/24 > +check_row_count Advertised_Route 1 logical_port=$sw0 ip_prefix= > 192.168.0.0/24 > +check_row_count Advertised_Route 1 logical_port=$sw0 ip_prefix=172.16.1.10 > +check_row_count Advertised_Route 1 logical_port=$sw0 ip_prefix=172.16.2.10 > + > +# The configured prefixes are advertised only while dynamic routing is > +# enabled on the Logical_Router. > +check ovn-nbctl --wait=sb set Logical_Router_Port lr0-sw0 \ > + options:dynamic-routing-advertise-prefixes="10.30.0.0/16" > +check ovn-nbctl --wait=sb remove Logical_Router lr0 options > dynamic-routing > +check_row_count Advertised_Route 0 > +check ovn-nbctl --wait=sb set Logical_Router lr0 > options:dynamic-routing=true > +check_row_count Advertised_Route 4 > +check_row_count Advertised_Route 1 logical_port=$sw0 ip_prefix= > 10.30.0.0/16 > +check_row_count Advertised_Route 3 logical_port=$sw1 > + > Could you add a dynamic-routing-advertised-prefixes entry that does not correspond to an existing OVN object? The entry in the Advertised_Route table is created if there is a matching OVN object or not and the test should exercise that. > +# Removing the LRP removes its advertised prefixes. > +check ovn-nbctl --wait=sb lrp-del lr0-sw0 > +check_row_count Advertised_Route 3 > +check_row_count Advertised_Route 0 logical_port=$sw0 > + > +OVN_CLEANUP_NORTHD > +AT_CLEANUP > +]) > + > OVN_FOR_EACH_NORTHD_NO_HV([ > AT_SETUP([dynamic-routing - learning routes from sb]) > AT_KEYWORDS([dynamic-routing]) > -- > 2.48.1 > > _______________________________________________ > dev mailing list > dev@openvswitch.org > https://mail.openvswitch.org/mailman/listinfo/ovs-dev > > Thanks, Jacob
diff --git a/NEWS b/NEWS index 40a1b9867..78af38f9f 100644 --- a/NEWS +++ b/NEWS @@ -120,6 +120,10 @@ OVN v26.09.0 - xxx xx xxxx filter the routes learned through the port by route tag. This supersedes "ic-route-filter-tag", which is now deprecated and is ignored when "ic-route-learn-tag-rules" is set. + - Logical_Router_Port: Added a new + "options:dynamic-routing-advertise-prefixes" key that contains an + explicit list of prefixes to be advertised via this port. If it is + set, only these prefixes will be announced. OVN v26.03.0 - xxx xx xxxx -------------------------- diff --git a/northd/en-advertised-route-sync.c b/northd/en-advertised-route-sync.c index eb8a24a39..c623d9ba0 100644 --- a/northd/en-advertised-route-sync.c +++ b/northd/en-advertised-route-sync.c @@ -29,6 +29,8 @@ VLOG_DEFINE_THIS_MODULE(en_advertised_route_sync); +#define DYNAMIC_ROUTING_ADVERTISE_PREFIXES "dynamic-routing-advertise-prefixes" + struct ar_entry { struct hmap_node hmap_node; @@ -50,6 +52,8 @@ struct ar_entry { * unmonitored listener must remain reachable regardless. */ bool has_ungated_lb; struct sset health_checks; + + bool advertise_prefix; }; /* Add a new entries to the to-be-advertised routes. @@ -871,6 +875,61 @@ build_connected_as_host_routes(const struct ovn_datapath *od, } } +static const char * +lrp_advertise_prefixes(const struct ovn_port *op) +{ + if (!op || !op->nbrp) { + return NULL; + } + + return smap_get(&op->nbrp->options, DYNAMIC_ROUTING_ADVERTISE_PREFIXES); +} + +static void +build_advertise_prefix_routes(const struct ovn_datapath *od, + struct hmap *routes) +{ + const struct ovn_port *op; + HMAP_FOR_EACH (op, dp_node, &od->ports) { + const char *prefixes = lrp_advertise_prefixes(op); + if (!prefixes || !op->sb) { + continue; + } + + char *save_ptr = NULL; + char *tokstr = xstrdup(prefixes); + for (char *token = strtok_r(tokstr, ",", &save_ptr); + token != NULL; + token = strtok_r(NULL, ",", &save_ptr)) { + struct in6_addr prefix; + unsigned int plen; + + if (!ip46_parse_cidr(token, &prefix, &plen)) { + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1); + VLOG_WARN_RL(&rl, "bad prefix '%s' in option %s of %s", + token, DYNAMIC_ROUTING_ADVERTISE_PREFIXES, + op->nbrp->name); + continue; + } + + char *ip_prefix = normalize_v46_prefix(&prefix, plen); + struct ar_entry *dup = ar_entry_find(routes, od->sdp->sb_dp, + op->sb, ip_prefix, NULL); + if (dup && dup->advertise_prefix) { + /* The same prefix is listed twice in the option. */ + free(ip_prefix); + continue; + } + + struct ar_entry *route_e = + ar_entry_add_nocopy(routes, od, op, ip_prefix, NULL, + ROUTE_SOURCE_STATIC); + route_e->advertise_prefix = true; + } + free(tokstr); + } +} + void * en_dynamic_routes_init(struct engine_node *node OVS_UNUSED, struct engine_arg *arg OVS_UNUSED) @@ -989,6 +1048,8 @@ en_dynamic_routes_run(struct engine_node *node, void *data) build_connected_as_host_routes(od, &northd_data->ls_ports, dynamic_routes_data); + build_advertise_prefix_routes(od, &dynamic_routes_data->routes); + const struct lr_stateful_record *lr_stateful_rec = lr_stateful_table_find_by_uuid(&lr_stateful_data->table, od->key); if (!lr_stateful_rec) { @@ -1105,6 +1166,11 @@ should_advertise_route(const struct ovn_datapath *advertising_od, return false; } + if (lrp_advertise_prefixes(advertising_op)) { + /* This port advertises only the explicitly configured prefixes. */ + return false; + } + enum dynamic_routing_redistribute_mode drr = advertising_op->dynamic_routing_redistribute; @@ -1178,7 +1244,8 @@ advertised_route_table_sync( /* Then add the set of dynamic routes that need sync-ing. */ struct ar_entry *route_e; HMAP_FOR_EACH (route_e, hmap_node, dynamic_routes) { - if (!should_advertise_route(route_e->od, route_e->op, + if (!route_e->advertise_prefix && + !should_advertise_route(route_e->od, route_e->op, route_e->source)) { continue; } diff --git a/ovn-nb.xml b/ovn-nb.xml index c741a3b32..c771b7e05 100644 --- a/ovn-nb.xml +++ b/ovn-nb.xml @@ -4850,6 +4850,36 @@ or </column> + <column name="options" key="dynamic-routing-advertise-prefixes" + type='{"type": "string"}'> + <p> + Only relevant if <ref column="options" key="dynamic-routing" + table="Logical_Router"/> on the respective Logical_Router is set + to <code>true</code>. + </p> + + <p> + This is a list of IPv4 and/or IPv6 prefixes in CIDR notation, + separated by <code>,</code>, e.g. + <code>10.0.0.0/8,2001:db8::/32</code>. + </p> + + <p> + If this option is set, northd creates entries in the <ref + table="Advertised_Route" db="OVN_Southbound"/> table only for the + prefixes listed here. Every route that would otherwise be + advertised via this port because of <ref column="options" + key="dynamic-routing-redistribute" + table="Logical_Router_Port"/> (or its Logical_Router counterpart), + i.e. <code>connected</code>, <code>connected-as-host</code>, + <code>static</code>, <code>nat</code>, <code>lb</code> and + <code>hub-spoke</code> routes, is not advertised via this port. + Setting the option to an empty string disables all advertisements + on this port. + </p> + + </column> + <column name="options" key="dynamic-routing-advertise"> If the CMS sets <ref column="options" key="dynamic-routing-redistribute" table="Logical_Router_Port"/> to <code>connected-as-host</code>, diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at index 6d191c1a0..45322ffcb 100644 --- a/tests/ovn-northd.at +++ b/tests/ovn-northd.at @@ -16525,6 +16525,114 @@ OVN_CLEANUP_NORTHD AT_CLEANUP ]) +OVN_FOR_EACH_NORTHD_NO_HV([ +AT_SETUP([dynamic-routing - advertise only configured prefixes]) +AT_KEYWORDS([dynamic-routing]) +ovn_start + +# Start with a GW router that advertises connected, static, nat and lb routes +# via both of its LRPs. +check ovn-nbctl lr-add lr0 +check ovn-nbctl set Logical_Router lr0 \ + options:dynamic-routing=true \ + options:chassis=hv1 \ + options:dynamic-routing-redistribute="connected,static,nat,lb" +check ovn-nbctl lrp-add lr0 lr0-sw0 00:00:00:00:ff:01 10.0.0.1/24 +check ovn-nbctl lrp-add lr0 lr0-sw1 00:00:00:00:ff:02 10.0.1.1/24 +check ovn-nbctl lr-route-add lr0 192.168.0.0/24 10.0.0.10 +check ovn-nbctl lr-nat-add lr0 dnat_and_snat 172.16.1.10 10.0.0.20 +check ovn-nbctl lb-add lb0 172.16.2.10:80 10.0.0.30:80 +check ovn-nbctl lr-lb-add lr0 lb0 +check ovn-nbctl --wait=sb sync + +datapath=$(fetch_column Datapath_Binding _uuid external_ids:name=lr0) +sw0=$(fetch_column Port_Binding _uuid logical_port=lr0-sw0) +sw1=$(fetch_column Port_Binding _uuid logical_port=lr0-sw1) + +check_row_count Advertised_Route 7 +check_row_count Advertised_Route 4 logical_port=$sw0 +check_row_count Advertised_Route 1 logical_port=$sw0 ip_prefix=10.0.0.0/24 +check_row_count Advertised_Route 1 logical_port=$sw0 ip_prefix=192.168.0.0/24 +check_row_count Advertised_Route 1 logical_port=$sw0 ip_prefix=172.16.1.10 +check_row_count Advertised_Route 1 logical_port=$sw0 ip_prefix=172.16.2.10 +check_row_count Advertised_Route 3 logical_port=$sw1 + +# Setting dynamic-routing-advertise-prefixes on lr0-sw0 replaces every route +# advertised via this port with the configured ones. Both IPv4 and IPv6 +# prefixes are supported. The other LRP is not affected. +check ovn-nbctl --wait=sb set Logical_Router_Port lr0-sw0 \ + options:dynamic-routing-advertise-prefixes="172.16.0.0/16,2001:db8:1::/64" +check_row_count Advertised_Route 5 +check_row_count Advertised_Route 2 logical_port=$sw0 +check_row_count Advertised_Route 1 \ + ip_prefix="172.16.0.0/16" \ + datapath=$datapath \ + logical_port=$sw0 \ + tracked_port=[[]] +check_row_count Advertised_Route 1 \ + ip_prefix='"2001:db8:1::/64"' \ + datapath=$datapath \ + logical_port=$sw0 \ + tracked_port=[[]] +check_row_count Advertised_Route 3 logical_port=$sw1 +check_row_count Advertised_Route 1 logical_port=$sw1 ip_prefix=10.0.1.0/24 +check_row_count Advertised_Route 1 logical_port=$sw1 ip_prefix=172.16.1.10 +check_row_count Advertised_Route 1 logical_port=$sw1 ip_prefix=172.16.2.10 + +# The prefixes are normalized and duplicates are advertised only once. +check ovn-nbctl --wait=sb set Logical_Router_Port lr0-sw0 \ + options:dynamic-routing-advertise-prefixes="10.10.10.5/24,10.10.10.0/24" +check_row_count Advertised_Route 1 logical_port=$sw0 +check_row_count Advertised_Route 1 logical_port=$sw0 ip_prefix=10.10.10.0/24 + +# Invalid prefixes are ignored, the valid ones are still advertised. +check ovn-nbctl --wait=sb set Logical_Router_Port lr0-sw0 \ + options:dynamic-routing-advertise-prefixes="not-a-prefix,10.20.0.0/16" +check_row_count Advertised_Route 1 logical_port=$sw0 +check_row_count Advertised_Route 1 logical_port=$sw0 ip_prefix=10.20.0.0/16 + +# An empty list blocks all advertisements on this port. +check ovn-nbctl --wait=sb set Logical_Router_Port lr0-sw0 \ + options:dynamic-routing-advertise-prefixes='""' +check_row_count Advertised_Route 0 logical_port=$sw0 +check_row_count Advertised_Route 3 logical_port=$sw1 + +# The option also overrides the redistribute modes set on the LRP itself. +check ovn-nbctl --wait=sb set Logical_Router_Port lr0-sw0 \ + options:dynamic-routing-redistribute="connected,static,nat,lb" \ + options:dynamic-routing-advertise-prefixes="10.30.0.0/16" +check_row_count Advertised_Route 1 logical_port=$sw0 +check_row_count Advertised_Route 1 logical_port=$sw0 ip_prefix=10.30.0.0/16 + +# Removing the option brings the redistributed routes back. +check ovn-nbctl --wait=sb remove Logical_Router_Port lr0-sw0 \ + options dynamic-routing-advertise-prefixes +check_row_count Advertised_Route 4 logical_port=$sw0 +check_row_count Advertised_Route 1 logical_port=$sw0 ip_prefix=10.0.0.0/24 +check_row_count Advertised_Route 1 logical_port=$sw0 ip_prefix=192.168.0.0/24 +check_row_count Advertised_Route 1 logical_port=$sw0 ip_prefix=172.16.1.10 +check_row_count Advertised_Route 1 logical_port=$sw0 ip_prefix=172.16.2.10 + +# The configured prefixes are advertised only while dynamic routing is +# enabled on the Logical_Router. +check ovn-nbctl --wait=sb set Logical_Router_Port lr0-sw0 \ + options:dynamic-routing-advertise-prefixes="10.30.0.0/16" +check ovn-nbctl --wait=sb remove Logical_Router lr0 options dynamic-routing +check_row_count Advertised_Route 0 +check ovn-nbctl --wait=sb set Logical_Router lr0 options:dynamic-routing=true +check_row_count Advertised_Route 4 +check_row_count Advertised_Route 1 logical_port=$sw0 ip_prefix=10.30.0.0/16 +check_row_count Advertised_Route 3 logical_port=$sw1 + +# Removing the LRP removes its advertised prefixes. +check ovn-nbctl --wait=sb lrp-del lr0-sw0 +check_row_count Advertised_Route 3 +check_row_count Advertised_Route 0 logical_port=$sw0 + +OVN_CLEANUP_NORTHD +AT_CLEANUP +]) + OVN_FOR_EACH_NORTHD_NO_HV([ AT_SETUP([dynamic-routing - learning routes from sb]) AT_KEYWORDS([dynamic-routing])
Add the "options:dynamic-routing-advertise-prefixes" key to the Logical_Router_Port table. If it is set, only the listed prefixes are synced to the SB Advertised_Route table for that port and every route selected by "dynamic-routing-redistribute" (connected, static, nat, lb, hub-spoke) is skipped on it. This lets the CMS announce an aggregated prefix instead of many individual NAT or LB addresses. Signed-off-by: Alexandra Rukomoinikova <ARukomoinikova@k2.cloud> --- NEWS | 4 ++ northd/en-advertised-route-sync.c | 69 ++++++++++++++++++- ovn-nb.xml | 30 +++++++++ tests/ovn-northd.at | 108 ++++++++++++++++++++++++++++++ 4 files changed, 210 insertions(+), 1 deletion(-)