> Sometimes we want to use individual host routes instead of the connected
> routes of LRPs.
> This allows the network fabric to know which addresses are actually in
> use and e.g. drop traffic to addresses that are not used anyway.
>
> Signed-off-by: Felix Huettner <[email protected]>
Hi Felix,
thx for the patch, just one more comment with respect to Dumitru's review.
Regards,
Lorenzo
> ---
> v3->v4:
> * fix a memory leak
> v2->v3:
> * A lot of minor review comments.
>
> NEWS | 3 +
> northd/en-advertised-route-sync.c | 225 ++++++++++++++++++++++++++++--
> northd/en-advertised-route-sync.h | 11 ++
> northd/inc-proc-northd.c | 4 +
> northd/northd.c | 32 ++---
> northd/northd.h | 20 +++
> ovn-nb.xml | 27 ++++
> tests/ovn-northd.at | 115 ++++++++++++++-
> 8 files changed, 402 insertions(+), 35 deletions(-)
>
> diff --git a/NEWS b/NEWS
> index 4a3b8bf5e..289cdd7f7 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -40,6 +40,9 @@ Post v24.09.0
> fabric. Routes entered into the "Learned_Route" table in the
> southbound
> database will be learned by the respective LR. They are included in
> the
> route table with a lower priority than static routes.
> + * Add the option "dynamic-routing-connected-as-host-routes" to LRPs. If
> + set to true then connected routes are announced as individual host
> + routes.
>
> OVN v24.09.0 - 13 Sep 2024
> --------------------------
> diff --git a/northd/en-advertised-route-sync.c
> b/northd/en-advertised-route-sync.c
> index b94bc0240..02b3aba7a 100644
> --- a/northd/en-advertised-route-sync.c
> +++ b/northd/en-advertised-route-sync.c
> @@ -21,6 +21,7 @@
> #include "northd.h"
>
> #include "en-advertised-route-sync.h"
> +#include "en-lr-stateful.h"
> #include "lib/stopwatch-names.h"
> #include "openvswitch/hmap.h"
> #include "ovn-util.h"
> @@ -29,34 +30,127 @@ static void
> advertised_route_table_sync(
> struct ovsdb_idl_txn *ovnsb_txn,
> const struct sbrec_advertised_route_table *sbrec_advertised_route_table,
> - const struct hmap *parsed_routes);
> + const struct lr_stateful_table *lr_stateful_table,
> + const struct hmap *parsed_routes,
> + struct advertised_route_sync_data *data);
> +
[...]
>
> +static void
> +publish_lport_addresses(struct hmap *sync_routes,
> + const struct sbrec_datapath_binding *sb_db,
> + const struct ovn_port *logical_port,
> + struct lport_addresses *addresses,
> + const struct ovn_port *tracking_port)
> +{
> + for (size_t i = 0; i < addresses->n_ipv4_addrs; i++) {
> + const struct ipv4_netaddr *addr = &addresses->ipv4_addrs[i];
> + char *addr_s = xasprintf("%s/32", addr->addr_s);
> + ar_alloc_entry(sync_routes, sb_db, logical_port->sb,
> + addr_s, tracking_port->sb);
> + }
> + for (size_t i = 0; i < addresses->n_ipv6_addrs; i++) {
> + if (in6_is_lla(&addresses->ipv6_addrs[i].network)) {
> + continue;
> + }
> + const struct ipv6_netaddr *addr = &addresses->ipv6_addrs[i];
> + char *addr_s = xasprintf("%s/128", addr->addr_s);
> + ar_alloc_entry(sync_routes, sb_db, logical_port->sb,
> + addr_s, tracking_port->sb);
> + }
> +}
> +
> +/* Collect all IP addresses connected to the out_port of a route.
> + * This traverses all LSPs on the LS connected to the out_port. */
> +static void
> +publish_host_routes(struct hmap *sync_routes,
> + const struct lr_stateful_table *lr_stateful_table,
> + const struct parsed_route *route,
> + struct advertised_route_sync_data *data)
> +{
> + struct ovn_port *port;
> + struct ovn_datapath *lsp_od = route->out_port->peer->od;
> +
> + if (!lsp_od->nbs) {
> + return;
> + }
Here it seems to me we are missing where two logical routers are connected
directly, right? Can we take care of it?
> +
> + /* We need to track the LS we are publishing routes from, so that we can
> + * recompute when any port on there changes. */
> + uuidset_insert(&data->nb_ls, &lsp_od->nbs->header_.uuid);
> + HMAP_FOR_EACH (port, dp_node, &lsp_od->ports) {
> + if (port->peer) {
> + /* This is a LSP connected to an LRP */
> + struct lport_addresses *addresses = &port->peer->lrp_networks;
> + publish_lport_addresses(sync_routes, route->od->sb,
> + route->out_port,
> + addresses, port->peer);
> +
> + const struct lr_stateful_record *lr_stateful_rec;
> + lr_stateful_rec = lr_stateful_table_find_by_index(
> + lr_stateful_table, port->peer->od->index);
> + /* We also need to track this LR as we need to recompute when
> + * any of its IPs change. */
> + uuidset_insert(&data->nb_lr_stateful,
> + &lr_stateful_rec->nbr_uuid);
> + struct ovn_port_routable_addresses addrs = get_op_addresses(
> + port->peer, lr_stateful_rec, false);
> + for (size_t i = 0; i < addrs.n_addrs; i++) {
> + publish_lport_addresses(sync_routes, route->od->sb,
> + route->out_port,
> + &addrs.laddrs[i],
> + port->peer);
> + }
> + destroy_routable_addresses(&addrs);
> + } else {
> + /* This is just a plain LSP */
> + for (size_t i = 0; i < port->n_lsp_addrs; i++) {
> + publish_lport_addresses(sync_routes, route->od->sb,
> + route->out_port,
> + &port->lsp_addrs[i],
> + port);
> + }
> + }
> + }
> +}
> +
> static void
> advertised_route_table_sync(
> struct ovsdb_idl_txn *ovnsb_txn,
> const struct sbrec_advertised_route_table *sbrec_advertised_route_table,
> - const struct hmap *parsed_routes)
> + const struct lr_stateful_table *lr_stateful_table,
> + const struct hmap *parsed_routes,
> + struct advertised_route_sync_data *data)
> {
> struct hmap sync_routes = HMAP_INITIALIZER(&sync_routes);
> + struct uuidset host_route_lrps = UUIDSET_INITIALIZER(&host_route_lrps);
>
> const struct parsed_route *route;
>
> @@ -152,9 +337,23 @@ advertised_route_table_sync(
> if (!route->od->dynamic_routing) {
> continue;
> }
> - if (route->source == ROUTE_SOURCE_CONNECTED &&
> - !route->out_port->dynamic_routing_connected) {
> - continue;
> + if (route->source == ROUTE_SOURCE_CONNECTED) {
> + if (!route->out_port->dynamic_routing_connected) {
> + continue;
> + }
> + /* If we advertise host routes, we only need to do so once per
> + * LRP. */
> + const struct uuid *route_uuid =
> + &route->out_port->nbrp->header_.uuid;
> + if (smap_get_bool(&route->out_port->nbrp->options,
> + "dynamic-routing-connected-as-host-routes",
> + false) &&
> + !uuidset_contains(&host_route_lrps, route_uuid)) {
> + uuidset_insert(&host_route_lrps, route_uuid);
> + publish_host_routes(&sync_routes, lr_stateful_table,
> + route, data);
> + continue;
> + }
> }
> if (route->source == ROUTE_SOURCE_STATIC &&
> !route->out_port->dynamic_routing_static) {
> @@ -164,14 +363,15 @@ advertised_route_table_sync(
> char *ip_prefix = normalize_v46_prefix(&route->prefix,
> route->plen);
> route_e = ar_alloc_entry(&sync_routes, route->od->sb,
> - route->out_port->sb, ip_prefix);
> + route->out_port->sb, ip_prefix, NULL);
> }
> + uuidset_destroy(&host_route_lrps);
>
> SBREC_ADVERTISED_ROUTE_TABLE_FOR_EACH_SAFE (sb_route,
>
> sbrec_advertised_route_table) {
> route_e = ar_find(&sync_routes, sb_route->datapath,
> - sb_route->logical_port,
> - sb_route->ip_prefix);
> + sb_route->logical_port, sb_route->ip_prefix,
> + sb_route->tracked_port);
> if (route_e) {
> hmap_remove(&sync_routes, &route_e->hmap_node);
> ar_entry_free(route_e);
> @@ -186,6 +386,7 @@ advertised_route_table_sync(
> sbrec_advertised_route_set_datapath(sr, route_e->sb_db);
> sbrec_advertised_route_set_logical_port(sr, route_e->logical_port);
> sbrec_advertised_route_set_ip_prefix(sr, route_e->ip_prefix);
> + sbrec_advertised_route_set_tracked_port(sr, route_e->tracked_port);
> ar_entry_free(route_e);
> }
>
> diff --git a/northd/en-advertised-route-sync.h
> b/northd/en-advertised-route-sync.h
> index bd27ecefa..47c2ebd62 100644
> --- a/northd/en-advertised-route-sync.h
> +++ b/northd/en-advertised-route-sync.h
> @@ -17,10 +17,21 @@
> #define EN_ADVERTISED_ROUTE_SYNC_H 1
>
> #include "lib/inc-proc-eng.h"
> +#include "lib/uuidset.h"
>
> struct advertised_route_sync_data {
> + /* Contains the uuids of all NB Logical Routers where we used a
> + * lr_stateful_record during computation. */
> + struct uuidset nb_lr_stateful;
> + /* Contains the uuids of all NB Logical Switches where we rely on port
> + * changes for host routes. */
> + struct uuidset nb_ls;
> };
>
> +bool advertised_route_sync_lr_stateful_change_handler(struct engine_node *,
> + void *data);
> +bool advertised_route_sync_northd_change_handler(struct engine_node *,
> + void *data);
> void *en_advertised_route_sync_init(struct engine_node *, struct engine_arg
> *);
> void en_advertised_route_sync_cleanup(void *data);
> void en_advertised_route_sync_run(struct engine_node *, void *data);
> diff --git a/northd/inc-proc-northd.c b/northd/inc-proc-northd.c
> index 5f5f36b45..5045ba5fc 100644
> --- a/northd/inc-proc-northd.c
> +++ b/northd/inc-proc-northd.c
> @@ -272,6 +272,10 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb,
> engine_add_input(&en_advertised_route_sync, &en_routes, NULL);
> engine_add_input(&en_advertised_route_sync, &en_sb_advertised_route,
> NULL);
> + engine_add_input(&en_advertised_route_sync, &en_lr_stateful,
> + advertised_route_sync_lr_stateful_change_handler);
> + engine_add_input(&en_advertised_route_sync, &en_northd,
> + advertised_route_sync_northd_change_handler);
>
> engine_add_input(&en_learned_route_sync, &en_routes, NULL);
> engine_add_input(&en_learned_route_sync, &en_sb_learned_route, NULL);
> diff --git a/northd/northd.c b/northd/northd.c
> index baffa7c90..c80049bfd 100644
> --- a/northd/northd.c
> +++ b/northd/northd.c
> @@ -1104,19 +1104,6 @@ build_datapaths(struct ovsdb_idl_txn *ovnsb_txn,
> ods_build_array_index(lr_datapaths);
> }
>
> -/* Structure representing logical router port
> - * routable addresses. This includes DNAT and Load Balancer
> - * addresses. This structure will only be filled in if the
> - * router port is a gateway router port. Otherwise, all pointers
> - * will be NULL and n_addrs will be 0.
> - */
> -struct ovn_port_routable_addresses {
> - /* The parsed routable addresses */
> - struct lport_addresses *laddrs;
> - /* Number of items in the laddrs array */
> - size_t n_addrs;
> -};
> -
> static bool lsp_can_be_inc_processed(const struct nbrec_logical_switch_port
> *);
>
> /* This function returns true if 'op' is a gateway router port.
> @@ -1151,7 +1138,7 @@ is_cr_port(const struct ovn_port *op)
> return op->primary_port;
> }
>
> -static void
> +void
> destroy_routable_addresses(struct ovn_port_routable_addresses *ra)
> {
> for (size_t i = 0; i < ra->n_addrs; i++) {
> @@ -1164,12 +1151,14 @@ static char **get_nat_addresses(const struct ovn_port
> *op, size_t *n,
> bool routable_only, bool include_lb_ips,
> const struct lr_stateful_record *);
>
> -static struct ovn_port_routable_addresses
> -get_op_routable_addresses(struct ovn_port *op,
> - const struct lr_stateful_record *lr_stateful_rec)
> +struct ovn_port_routable_addresses
> +get_op_addresses(struct ovn_port *op,
> + const struct lr_stateful_record *lr_stateful_rec,
> + bool routable_only)
> {
> size_t n;
> - char **nats = get_nat_addresses(op, &n, true, true, lr_stateful_rec);
> + char **nats = get_nat_addresses(op, &n, routable_only, true,
> + lr_stateful_rec);
>
> if (!nats) {
> return (struct ovn_port_routable_addresses) {
> @@ -1202,6 +1191,13 @@ get_op_routable_addresses(struct ovn_port *op,
> };
> }
>
> +static struct ovn_port_routable_addresses
> +get_op_routable_addresses(struct ovn_port *op,
> + const struct lr_stateful_record *lr_stateful_rec)
> +{
> + return get_op_addresses(op, lr_stateful_rec, true);
> +}
> +
>
> static void
> ovn_port_set_nb(struct ovn_port *op,
> diff --git a/northd/northd.h b/northd/northd.h
> index 6d0e7998a..2310c2188 100644
> --- a/northd/northd.h
> +++ b/northd/northd.h
> @@ -25,6 +25,7 @@
> #include "openvswitch/hmap.h"
> #include "simap.h"
> #include "ovs-thread.h"
> +#include "en-lr-stateful.h"
>
> struct northd_input {
> /* Northbound table references */
> @@ -947,4 +948,23 @@ ovn_port_find_bound(const struct hmap *ports, const char
> *name)
> return ovn_port_find__(ports, name, true);
> }
>
> +/* Structure representing logical router port routable addresses. This
> + * includes DNAT and Load Balancer addresses. This structure will only
> + * be filled in if the router port is a gateway router port. Otherwise,
> + * all pointers will be NULL and n_addrs will be 0.
> + */
> +struct ovn_port_routable_addresses {
> + /* The parsed routable addresses */
> + struct lport_addresses *laddrs;
> + /* Number of items in the laddrs array */
> + size_t n_addrs;
> +};
> +
> +struct ovn_port_routable_addresses get_op_addresses(
> + struct ovn_port *op,
> + const struct lr_stateful_record *lr_stateful_rec,
> + bool routable_only);
> +
> +void destroy_routable_addresses(struct ovn_port_routable_addresses *ra);
> +
> #endif /* NORTHD_H */
> diff --git a/ovn-nb.xml b/ovn-nb.xml
> index 4dddf4c60..4d4105a21 100644
> --- a/ovn-nb.xml
> +++ b/ovn-nb.xml
> @@ -3750,6 +3750,33 @@ or
> key="dynamic-routing-static" table="Logical_Router_Port"/> will be
> used.
> </column>
> + <column name="options" key="dynamic-routing-connected-as-host-routes"
> + type='{"type": "boolean"}'>
> + Only relevant if <ref column="options" key="dynamic-routing"
> + table="Logical_Router"/> on the respective Logical_Router is set
> + to <code>true</code> and also
> + <ref column="options" key="dynamic-routing-connected"/> is enabled on
> + the LR or LRP.
> +
> + If set to true the prefix connected to the LRP is not advertised as a
> + whole. Rather each individual IP address that is actually in use
> inside
> + this prefix is announced as a host route. Default is false.
> +
> + This can be used to:
> + <ul>
> + <li>
> + allow the fabric outside of OVN to drop traffic towards IP
> + addresses that are not actually used. This traffic would
> otherwise
> + hit this LR and then be dropped.
> + </li>
> +
> + <li>
> + If this LR has multiple LRPs connected to the fabric on different
> + chassis: allows the fabric outside of OVN to steer packets to the
> + chassis which already hosts this backing ip address.
> + </li>
> + </ul>
> + </column>
> </group>
>
> <group title="Attachment">
> diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
> index 0f146ee7f..fa664599a 100644
> --- a/tests/ovn-northd.at
> +++ b/tests/ovn-northd.at
> @@ -14680,6 +14680,68 @@ AT_CHECK([grep -w "lr_in_ip_routing" lr0flows |
> ovn_strip_lflows], [0], [dnl
> AT_CLEANUP
> ])
>
> +OVN_FOR_EACH_NORTHD_NO_HV([
> +AT_SETUP([dynamic-routing - host routes])
> +AT_KEYWORDS([dynamic-routing])
> +ovn_start
> +
> +# we start with announcing routes on a lr with 2 lrps
> +# lr0-sw0 is connected to ls sw0
> +check ovn-nbctl lr-add lr0
> +check ovn-nbctl set Logical_Router lr0 option:dynamic-routing=true \
> + option:dynamic-routing-connected=true \
> + option:dynamic-routing-static=true
> +check ovn-nbctl lrp-add lr0 lr0-sw0 00:00:00:00:ff:01 10.0.0.1/24
> +sw0=$(fetch_column port_binding _uuid logical_port=lr0-sw0)
> +check ovn-nbctl lrp-add lr0 lr0-sw1 00:00:00:00:ff:02 10.0.1.1/24
> +sw1=$(fetch_column port_binding _uuid logical_port=lr0-sw1)
> +check ovn-nbctl ls-add sw0
> +check ovn-nbctl lsp-add sw0 sw0-lr0
> +check ovn-nbctl --wait=sb set Logical_Switch_Port sw0-lr0 type=router
> options:router-port=lr0-sw0
> +check_row_count Advertised_Route 2 tracked_port='[[]]'
> +datapath=$(fetch_column datapath_binding _uuid external_ids:name=lr0)
> +
> +# configuring the LRP lr0-sw0 to send host routes
> +# as sw0 is quite empty we will only see the addresses of lr0-sw0
> +check ovn-nbctl --wait=sb set Logical_Router_Port lr0-sw0
> options:dynamic-routing-connected-as-host-routes=true
> +check_row_count Advertised_Route 2
> +check_column 10.0.0.1/32 Advertised_Route ip_prefix datapath=$datapath
> logical_port=$sw0
> +check_column $sw0 Advertised_Route tracked_port datapath=$datapath
> logical_port=$sw0
> +
> +# adding a VIF to the LS sw0 will advertise it as well
> +check ovn-nbctl lsp-add sw0 sw0-vif0
> +check ovn-nbctl --wait=sb lsp-set-addresses sw0-vif0 "00:aa:bb:cc:dd:ee
> 10.0.0.2"
> +vif0=$(fetch_column port_binding _uuid logical_port=sw0-vif0)
> +check_row_count Advertised_Route 3
> +check_row_count Advertised_Route 2 tracked_port!='[[]]'
> +check_column $vif0 Advertised_Route tracked_port datapath=$datapath
> logical_port=$sw0 ip_prefix=10.0.0.2/32
> +
> +# adding a LR lr1 to the LS sw0 will advertise the LRP of the new router
> +check ovn-nbctl lr-add lr1
> +check ovn-nbctl lrp-add lr1 lr1-sw0 00:00:00:01:ff:01 10.0.0.10/24
> +check ovn-nbctl lsp-add sw0 sw0-lr1
> +lr1=$(fetch_column port_binding _uuid logical_port=lr1-sw0)
> +check ovn-nbctl --wait=sb set Logical_Switch_Port sw0-lr1 type=router
> options:router-port=lr1-sw0
> +check_row_count Advertised_Route 4
> +check_row_count Advertised_Route 3 tracked_port!='[[]]'
> +check_column $lr1 Advertised_Route tracked_port datapath=$datapath
> logical_port=$sw0 ip_prefix=10.0.0.10/32
> +
> +# adding a NAT rule to lr1 will advertise it as well
> +check ovn-nbctl --wait=sb lr-nat-add lr1 dnat_and_snat 10.0.0.100 192.168.0.1
> +check_row_count Advertised_Route 5
> +check_row_count Advertised_Route 4 tracked_port!='[[]]'
> +check_column $lr1 Advertised_Route tracked_port datapath=$datapath
> logical_port=$sw0 ip_prefix=10.0.0.100/32
> +
> +# adding a static route to lr1 will be advertised just normally
> +check ovn-nbctl --wait=sb lr-route-add lr0 172.16.0.0/24 10.0.0.200
> +check_row_count Advertised_Route 6
> +check_row_count Advertised_Route 4 tracked_port!='[[]]'
> +check_row_count Advertised_Route 1 datapath=$datapath logical_port=$sw0
> ip_prefix=172.16.0.0/24
> +
> +AT_CLEANUP
> +])
> +
> +
> OVN_FOR_EACH_NORTHD_NO_HV([
> AT_SETUP([dynamic-routing incremental processing])
> AT_KEYWORDS([dynamic-routing])
> @@ -14704,13 +14766,16 @@ check_engine_stats lflow recompute nocompute
> CHECK_NO_CHANGE_AFTER_RECOMPUTE(1)
>
> check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats
> -check ovn-nbctl --wait=sb lrp-add lr0 lr0-sw0 00:00:00:00:ff:01 10.0.0.1/24
> +check ovn-nbctl lrp-add lr0 lr0-sw0 00:00:00:00:ff:01 10.0.0.1/24
> +check ovn-nbctl ls-add sw0
> +check ovn-nbctl lsp-add sw0 sw0-lr0
> +check ovn-nbctl --wait=sb set Logical_Switch_Port sw0-lr0 type=router
> options:router-port=lr0-sw0
> sw0=$(fetch_column port_binding _uuid logical_port=lr0-sw0)
> check_engine_stats northd recompute compute
> -check_engine_stats routes recompute nocompute
> -check_engine_stats advertised_route_sync recompute nocompute
> -check_engine_stats learned_route_sync recompute nocompute
> -check_engine_stats lflow recompute nocompute
> +check_engine_stats routes recompute compute
> +check_engine_stats advertised_route_sync recompute compute
> +check_engine_stats learned_route_sync recompute compute
> +check_engine_stats lflow recompute compute
> CHECK_NO_CHANGE_AFTER_RECOMPUTE
>
> check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats
> @@ -14816,6 +14881,46 @@ check_engine_stats learned_route_sync recompute
> nocompute
> check_engine_stats lflow recompute nocompute
> CHECK_NO_CHANGE_AFTER_RECOMPUTE
>
> +check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats
> +check ovn-nbctl --wait=sb set Logical_Router_Port lr0-sw0
> options:dynamic-routing-connected-as-host-routes=true
> +check_engine_stats northd recompute nocompute
> +check_engine_stats routes recompute nocompute
> +check_engine_stats advertised_route_sync recompute nocompute
> +check_engine_stats learned_route_sync recompute nocompute
> +check_engine_stats lflow recompute nocompute
> +CHECK_NO_CHANGE_AFTER_RECOMPUTE
> +
> +check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats
> +check ovn-nbctl lsp-add sw0 sw0-vif0
> +check ovn-nbctl --wait=sb lsp-set-addresses sw0-vif0 "00:aa:bb:cc:dd:ee
> 10.0.0.2"
> +check_engine_stats northd norecompute compute
> +check_engine_stats routes norecompute compute
> +check_engine_stats advertised_route_sync norecompute compute
> +check_engine_stats learned_route_sync norecompute compute
> +check_engine_stats lflow norecompute compute
> +CHECK_NO_CHANGE_AFTER_RECOMPUTE
> +
> +check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats
> +check ovn-nbctl lr-add lr1
> +check ovn-nbctl lrp-add lr1 lr1-sw0 00:00:00:01:ff:01 10.0.0.10/24
> +check ovn-nbctl lsp-add sw0 sw0-lr1
> +check ovn-nbctl --wait=sb set Logical_Switch_Port sw0-lr1 type=router
> options:router-port=lr1-sw0
> +check_engine_stats northd recompute compute
> +check_engine_stats routes recompute compute
> +check_engine_stats advertised_route_sync recompute compute
> +check_engine_stats learned_route_sync recompute compute
> +check_engine_stats lflow recompute compute
> +CHECK_NO_CHANGE_AFTER_RECOMPUTE
> +
> +check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats
> +check ovn-nbctl --wait=sb lr-nat-add lr1 dnat_and_snat 10.0.0.100 192.168.0.1
> +check_engine_stats northd norecompute compute
> +check_engine_stats routes norecompute compute
> +check_engine_stats advertised_route_sync norecompute compute
> +check_engine_stats learned_route_sync norecompute compute
> +check_engine_stats lflow norecompute compute
> +CHECK_NO_CHANGE_AFTER_RECOMPUTE
> +
> check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats
> check ovn-nbctl --wait=sb lrp-del lr0-sw0
> check_engine_stats northd recompute compute
> --
> 2.47.1
>
>
> _______________________________________________
> dev mailing list
> [email protected]
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev