Recheck-request: github-robot-_ovn-kubernetes



On 24.04.2026 17:10, Alexandra Rukomoinikova wrote:
> Enable east-west traffic rerouting for locally connected networks between
> Availability Zones (AZs). This allows traffic destined to a locally connected
> network to be forcibly forwarded to a remote AZ for processing (e.g.,
> firewalling, inspection, service chaining) and then delivered back.
>
> Introduce new option (override-connected) for static routes. Static route with
> this option set overrides local directly connected route. ovn-ic is extended 
> to
> pass this option during advertise-learn processing. Also, route_table column 
> in
> ic database now used for connected routes too.
>
> IC route priorities are changed to raise the priority of learned connected
> routes that have a route table set. The new priority order for the same
> prefix (highest to lowest) is:
>
>    1. Static routes (local or IC-learned) with override-connected=true
>    2. IC-learned connected routes with route_table set (auto-marked)
>    3. All other connected routes (local and learned)
>    4. All other static routes
>    5. Routes learned from external sources (e.g., BGP)
>    6. Source-IP routes (lowest priority)
>
> (It's also now described in ovn-northd manpage)
>
> Signed-off-by: Alexandra Rukomoinikova <[email protected]>
> ---
> v5 --> v6: 1) fixed review comments in docs
>             2) fixed ovn-k test: problem was in the incorrect
>                calculation of metrics for src-ip static routes
> v4 --> v5: Rebased, added documentation to ovn-northd manpage AD for routing
> v4 
> (https://patchwork.ozlabs.org/project/ovn/patch/[email protected]/)
> ---
>   NEWS                           |   4 +
>   ic/ovn-ic.c                    |  81 ++++++++---
>   lib/ovn-util.h                 |   3 +
>   northd/en-learned-route-sync.c |   2 +-
>   northd/northd.c                | 158 +++++++++++++---------
>   northd/northd.h                |   8 +-
>   northd/ovn-northd.8.xml        |  44 ++++++
>   ovn-ic-sb.ovsschema            |   7 +-
>   ovn-ic-sb.xml                  |  27 ++++
>   ovn-nb.xml                     |   8 ++
>   tests/ovn-ic.at                | 182 ++++++++++++++++++++++++-
>   tests/ovn-northd.at            | 238 ++++++++++++++++-----------------
>   utilities/ovn-nbctl.8.xml      |   6 +
>   utilities/ovn-nbctl.c          |  28 +++-
>   14 files changed, 585 insertions(+), 211 deletions(-)
>
> diff --git a/NEWS b/NEWS
> index 8633ba8bb..fdc02b4a8 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -3,6 +3,10 @@ Post v26.03.0
>      - Dynamic Routing:
>        * Add support for hub-and-spoke propagation via the "hub-spoke" option
>          in dynamic-routing-redistribute settings.
> +   - Added "override-connected" option to Logical Router Static Routes to 
> mark
> +     static routes as higher-priority than connected routes, which in turn 
> led
> +     to changes in administrative distance for specific route types. Please 
> see
> +     the "Route Administrative Distance" section of the ovn-northd manpage.
>   
>   OVN v26.03.0 - xxx xx xxxx
>   --------------------------
> diff --git a/ic/ovn-ic.c b/ic/ovn-ic.c
> index ba9490658..fb7723641 100644
> --- a/ic/ovn-ic.c
> +++ b/ic/ovn-ic.c
> @@ -1309,6 +1309,7 @@ struct ic_route_info {
>       const char *origin;
>       const char *route_table;
>       const char *route_tag;
> +    bool override_connected;
>       struct uuid ic_route_uuid;
>   
>       const struct nbrec_logical_router *nb_lr;
> @@ -1326,16 +1327,25 @@ struct ic_route_info {
>       const struct nbrec_load_balancer *nb_lb;
>   };
>   
> +static inline bool
> +get_override_connected(const struct smap *options)
> +{
> +    return smap_get_bool(options, ROUTE_OVERRIDE_CONNECTED, false);
> +}
> +
>   static uint32_t
>   ic_route_hash(const struct in6_addr *prefix, unsigned int plen,
>                 const struct in6_addr *nexthop, const char *origin,
> -              const char *route_table, const struct uuid *ic_route_uuid)
> +              const char *route_table,
> +              const struct uuid *ic_route_uuid,
> +              bool override_connected)
>   {
>       uint32_t basis = ic_route_uuid ? uuid_hash(ic_route_uuid) : 0;
>       basis = hash_bytes(prefix, sizeof *prefix, basis);
>       basis = hash_int((uint32_t) plen, basis);
>       basis = hash_string(origin, basis);
>       basis = hash_string(route_table, basis);
> +    basis = hash_boolean(override_connected, basis);
>       return hash_bytes(nexthop, sizeof *nexthop, basis);
>   }
>   
> @@ -1343,16 +1353,18 @@ static struct ic_route_info *
>   ic_route_find(struct hmap *routes, const struct in6_addr *prefix,
>                 unsigned int plen, const struct in6_addr *nexthop,
>                 const char *origin, const char *route_table,
> -              const struct uuid *ic_route_uuid, uint32_t hash)
> +              const struct uuid *ic_route_uuid,
> +              bool override_connected, uint32_t hash)
>   {
>       struct ic_route_info *r;
>       if (!hash) {
>           hash = ic_route_hash(prefix, plen, nexthop, origin, route_table,
> -                             ic_route_uuid);
> +                             ic_route_uuid, override_connected);
>       }
>       HMAP_FOR_EACH_WITH_HASH (r, node, hash, routes) {
>           if (ipv6_addr_equals(&r->prefix, prefix) &&
>               r->plen == plen &&
> +            r->override_connected == override_connected &&
>               ipv6_addr_equals(&r->nexthop, nexthop) &&
>               !strcmp(r->origin, origin) &&
>               !strcmp(r->route_table ? r->route_table : "", route_table) &&
> @@ -1410,11 +1422,14 @@ add_to_routes_learned(struct hmap *routes_learned,
>           return false;
>       }
>       const char *origin = smap_get_def(&nb_route->options, "origin", "");
> +    bool override_connected = get_override_connected(&nb_route->options);
>   
>       uint32_t hash = ic_route_hash(&prefix, plen, &nexthop, origin,
> -                                  nb_route->route_table, ic_route_uuid);
> +                                  nb_route->route_table, ic_route_uuid,
> +                                  override_connected);
>       if (ic_route_find(routes_learned, &prefix, plen, &nexthop, origin,
> -                      nb_route->route_table, ic_route_uuid, hash)) {
> +                      nb_route->route_table, ic_route_uuid,
> +                      override_connected, hash)) {
>           /* Route was added to learned on previous iteration. */
>           return true;
>       }
> @@ -1428,6 +1443,7 @@ add_to_routes_learned(struct hmap *routes_learned,
>       ic_route->route_table = nb_route->route_table;
>       ic_route->nb_lr = nb_lr;
>       ic_route->ic_route_uuid = *ic_route_uuid;
> +    ic_route->override_connected = override_connected;
>       hmap_insert(routes_learned, &ic_route->node, hash);
>   
>       return true;
> @@ -1588,7 +1604,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 override_connected)
>   {
>       ovs_assert(nb_route || nb_lrp || nb_lb || nb_lr);
>   
> @@ -1597,10 +1613,10 @@ add_to_routes_ad(struct hmap *routes_ad, const struct 
> in6_addr prefix,
>       }
>   
>       uint hash = ic_route_hash(&prefix, plen, &nexthop, origin,
> -                              route_table, NULL);
> +                              route_table, NULL, override_connected);
>   
>       if (!ic_route_find(routes_ad, &prefix, plen, &nexthop, origin, 
> route_table,
> -                       NULL, hash)) {
> +                       NULL, override_connected, hash)) {
>           struct ic_route_info *ic_route = xzalloc(sizeof *ic_route);
>           ic_route->prefix = prefix;
>           ic_route->plen = plen;
> @@ -1612,6 +1628,7 @@ add_to_routes_ad(struct hmap *routes_ad, const struct 
> in6_addr prefix,
>           ic_route->nb_lr = nb_lr;
>           ic_route->nb_lb = nb_lb;
>           ic_route->route_tag = route_tag;
> +        ic_route->override_connected = override_connected;
>           hmap_insert(routes_ad, &ic_route->node, hash);
>       } else {
>           static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1);
> @@ -1645,6 +1662,8 @@ add_static_to_routes_ad(
>   {
>       struct in6_addr prefix, nexthop;
>       unsigned int plen;
> +    bool override_connected = get_override_connected(&nb_route->options);
> +
>       if (!parse_route(nb_route->ip_prefix, nb_route->nexthop,
>                        &prefix, &plen, &nexthop)) {
>           return;
> @@ -1684,7 +1703,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, override_connected);
>   }
>   
>   static void
> @@ -1693,8 +1712,9 @@ add_network_to_routes_ad(struct hmap *routes_ad, const 
> char *network,
>                            const struct lport_addresses *nexthop_addresses,
>                            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 char *route_tag,
> +                         const char *ts_route_table,
>                            bool is_src_dynamic)
>   {
>       struct in6_addr prefix, nexthop;
> @@ -1745,11 +1765,25 @@ add_network_to_routes_ad(struct hmap *routes_ad, 
> const char *network,
>           ds_destroy(&msg);
>       }
>   
> +    /* Create additional route to local and remote networks that have
> +     * common route table name with port attached to transit switch having
> +     * same route table name.
> +     * As a result, traffic that is processed within such route table and is
> +     * routed cross az will select port attached to transit switch specially
> +     * allocated to process traffic within that route table.
> +     */
> +
> +    if (*ts_route_table) {
> +        add_to_routes_ad(routes_ad, prefix, plen, nexthop,
> +                         ROUTE_ORIGIN_CONNECTED, ts_route_table,
> +                         nb_lrp, NULL, nb_lr, NULL, route_tag, true);
> +    }
> +
>       const char *origin = is_src_dynamic ? ROUTE_ORIGIN_CONNECTED_DYNAMIC :
>                                             ROUTE_ORIGIN_CONNECTED;
>       /* directly-connected routes go to <main> route table */
>       add_to_routes_ad(routes_ad, prefix, plen, nexthop, origin,
> -                     NULL, nb_lrp, NULL, nb_lr, NULL, route_tag);
> +                     NULL, nb_lrp, NULL, nb_lr, NULL, route_tag, false);
>   }
>   
>   static void
> @@ -1807,7 +1841,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);
>   }
> @@ -2189,11 +2223,15 @@ sync_learned_routes(struct ic_context *ctx,
>                   continue;
>               }
>   
> +            bool override_connected =
> +                get_override_connected(&isb_route->options);
>               struct ic_route_info *route_learned
>                   = ic_route_find(&ic_lr->routes_learned, &prefix, plen,
>                                   &nexthop, isb_route->origin,
>                                   isb_route->route_table,
> -                                &isb_route->header_.uuid, 0);
> +                                &isb_route->header_.uuid,
> +                                override_connected, 0);
> +
>               if (route_learned) {
>                   hmap_remove(&ic_lr->routes_learned, &route_learned->node);
>                   free(route_learned);
> @@ -2214,6 +2252,10 @@ sync_learned_routes(struct ic_context *ctx,
>                   nbrec_logical_router_static_route_update_options_setkey(
>                       nb_route, "origin", isb_route->origin);
>                   free(uuid_s);
> +                if (override_connected) {
> +                    nbrec_logical_router_static_route_update_options_setkey(
> +                        nb_route, ROUTE_OVERRIDE_CONNECTED, "true");
> +                }
>                   
> nbrec_logical_router_update_static_routes_addvalue(ic_lr->lr,
>                       nb_route);
>               }
> @@ -2300,9 +2342,11 @@ advertise_routes(struct ic_context *ctx,
>               icsbrec_route_delete(isb_route);
>               continue;
>           }
> +        bool override_connected = 
> get_override_connected(&isb_route->options);
>           struct ic_route_info *route_adv =
>               ic_route_find(routes_ad, &prefix, plen, &nexthop,
> -                          isb_route->origin, isb_route->route_table, NULL, 
> 0);
> +                          isb_route->origin, isb_route->route_table,
> +                          NULL, override_connected, 0);
>           if (!route_adv) {
>               /* Delete the extra route from IC-SB. */
>               VLOG_DBG("Delete route %s -> %s from IC-SB, which is not found"
> @@ -2346,6 +2390,10 @@ advertise_routes(struct ic_context *ctx,
>           icsbrec_route_set_route_table(isb_route, route_adv->route_table
>                                                    ? route_adv->route_table
>                                                    : "");
> +        if (route_adv->override_connected) {
> +            icsbrec_route_update_options_setkey(isb_route,
> +                ROUTE_OVERRIDE_CONNECTED, "true");
> +        }
>           free(prefix_s);
>           free(nexthop_s);
>   
> @@ -2400,7 +2448,8 @@ 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, false);
> +                                         lr, ts_lrp, route_tag,
> +                                         ts_route_table, false);
>               }
>           } else {
>               /* The router port of the TS port is ignored. */
> @@ -2455,7 +2504,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, true);
> +                                 lr, ts_lrp, route_tag, ts_route_table, 
> true);
>       }
>       sbrec_learned_route_index_destroy_row(filter);
>   }
> diff --git a/lib/ovn-util.h b/lib/ovn-util.h
> index b44c9c770..4e8cf6f52 100644
> --- a/lib/ovn-util.h
> +++ b/lib/ovn-util.h
> @@ -34,6 +34,7 @@
>   #define ROUTE_ORIGIN_STATIC "static"
>   #define ROUTE_ORIGIN_LB "loadbalancer"
>   #define ROUTE_ORIGIN_CONNECTED_DYNAMIC "connected-dynamic"
> +#define ROUTE_OVERRIDE_CONNECTED "override-connected"
>   
>   #define ETH_CRC_LENGTH 4
>   #define ETHERNET_OVERHEAD (ETH_HEADER_LEN + ETH_CRC_LENGTH)
> @@ -43,6 +44,8 @@
>   
>   #define IDL_LOOP_MAX_DURATION_MS 500
>   
> +#define MAX_PREFIX_LEN 128
> +
>   struct eth_addr;
>   struct nbrec_logical_router;
>   struct nbrec_logical_router_port;
> diff --git a/northd/en-learned-route-sync.c b/northd/en-learned-route-sync.c
> index 4f7a12a28..0d1953276 100644
> --- a/northd/en-learned-route-sync.c
> +++ b/northd/en-learned-route-sync.c
> @@ -200,7 +200,7 @@ parse_route_from_sbrec_route(struct hmap 
> *parsed_routes_out,
>       }
>   
>       return parsed_route_add(od, nexthop, &prefix, plen, false, lrp_addr_s,
> -                            out_port, 0, false, false, NULL,
> +                            out_port, 0, false, false, false, NULL,
>                               ROUTE_SOURCE_LEARNED, &route->header_, NULL,
>                               parsed_routes_out);
>   }
> diff --git a/northd/northd.c b/northd/northd.c
> index 0b52db6cf..6028bb8d3 100644
> --- a/northd/northd.c
> +++ b/northd/northd.c
> @@ -377,14 +377,23 @@ static const char *reg_ct_state[] = {
>   /*
>    * Route offsets implement logic to prioritize traffic for routes with
>    * same ip_prefix values:
> - *  1. (highest priority) connected routes
> - *  2. static routes
> - *  3. routes learned from the outside via ovn-controller (e.g. bgp)
> - *  4. (lowest priority) src-ip routes */
> -#define ROUTE_PRIO_OFFSET_MULTIPLIER 8
> -#define ROUTE_PRIO_OFFSET_LEARNED 2
> -#define ROUTE_PRIO_OFFSET_STATIC 4
> + *  1. High-priority static routes,
> + *     (override-connected option is set), including ic-learned with
> + *     override-connected option set to true.
> + *  2. ic-learned connected routes with route_table set.
> + *  3. connected routes, including ic-learned.
> + *  4. static routes, including ic-learned.
> + *  5. routes learned from the outside via ovn-controller (e.g. bgp)
> + *  6. (lowest priority) src-ip routes */
> +#define ROUTE_PRIO_OFFSET_MULTIPLIER 12
> +#define ROUTE_PRIO_OFFSET_PRIORITY_STATIC 10
> +#define ROUTE_PRIO_OFFSET_IC_LEARNED_CONNECTED_WITH_TABLEID 8
>   #define ROUTE_PRIO_OFFSET_CONNECTED 6
> +#define ROUTE_PRIO_OFFSET_STATIC 4
> +#define ROUTE_PRIO_OFFSET_LEARNED 2
> +
> +#define ROUTE_PRIO_BASE_SHIFT ((MAX_PREFIX_LEN + 1) * \
> +                              ROUTE_PRIO_OFFSET_MULTIPLIER)
>   
>   /* ovn_stages used by northd for logical switches and logical routers.
>    * The first three components are combined to form the constant stage's
> @@ -12145,6 +12154,10 @@ parsed_route_lookup(struct hmap *routes, size_t hash,
>               continue;
>           }
>   
> +        if (pr->override_connected != new_pr->override_connected) {
> +            continue;
> +        }
> +
>           if (pr->is_discard_route != new_pr->is_discard_route) {
>               continue;
>           }
> @@ -12175,6 +12188,7 @@ parsed_route_init(const struct ovn_datapath *od,
>                     uint32_t route_table_id,
>                     bool is_src_route,
>                     bool ecmp_symmetric_reply,
> +                  bool override_connected,
>                     const struct sset *ecmp_selection_fields,
>                     enum route_source source,
>                     const struct ovn_port *tracked_port,
> @@ -12190,6 +12204,7 @@ parsed_route_init(const struct ovn_datapath *od,
>       new_pr->is_src_route = is_src_route;
>       new_pr->od = od;
>       new_pr->ecmp_symmetric_reply = ecmp_symmetric_reply;
> +    new_pr->override_connected = override_connected;
>       new_pr->is_discard_route = is_discard_route;
>       new_pr->lrp_addr_s = nullable_xstrdup(lrp_addr_s);
>       new_pr->out_port = out_port;
> @@ -12218,7 +12233,8 @@ parsed_route_clone(const struct parsed_route *pr)
>       struct parsed_route *new_pr = parsed_route_init(
>           pr->od, nexthop, pr->prefix, pr->plen, pr->is_discard_route,
>           pr->lrp_addr_s, pr->out_port, pr->route_table_id, pr->is_src_route,
> -        pr->ecmp_symmetric_reply, &pr->ecmp_selection_fields, pr->source,
> +        pr->ecmp_symmetric_reply, pr->override_connected,
> +        &pr->ecmp_selection_fields, pr->source,
>           pr->tracked_port, pr->source_hint);
>   
>       new_pr->hash = pr->hash;
> @@ -12279,6 +12295,7 @@ parsed_route_add(const struct ovn_datapath *od,
>                    uint32_t route_table_id,
>                    bool is_src_route,
>                    bool ecmp_symmetric_reply,
> +                 bool override_connected,
>                    const struct sset *ecmp_selection_fields,
>                    enum route_source source,
>                    const struct ovsdb_idl_row *source_hint,
> @@ -12286,10 +12303,12 @@ parsed_route_add(const struct ovn_datapath *od,
>                    struct hmap *routes)
>   {
>   
> -    struct parsed_route *new_pr = parsed_route_init(
> -        od, nexthop, *prefix, plen, is_discard_route, lrp_addr_s, out_port,
> -        route_table_id, is_src_route, ecmp_symmetric_reply,
> -        ecmp_selection_fields, source, tracked_port, source_hint);
> +    struct parsed_route *new_pr
> +        = parsed_route_init(od, nexthop, *prefix, plen, is_discard_route,
> +                            lrp_addr_s, out_port, route_table_id,
> +                            is_src_route, ecmp_symmetric_reply,
> +                            override_connected, ecmp_selection_fields,
> +                            source, tracked_port, source_hint);
>   
>       new_pr->hash = route_hash(new_pr);
>   
> @@ -12417,6 +12436,8 @@ parsed_routes_add_static(const struct ovn_datapath 
> *od,
>       bool ecmp_symmetric_reply = smap_get_bool(&route->options,
>                                            "ecmp_symmetric_reply",
>                                            false);
> +    bool override_connected = smap_get_bool(&route->options,
> +                                            ROUTE_OVERRIDE_CONNECTED, false);
>   
>       const char *origin = smap_get_def(&route->options, "origin", "");
>       enum route_source source;
> @@ -12430,7 +12451,8 @@ parsed_routes_add_static(const struct ovn_datapath 
> *od,
>   
>       parsed_route_add(od, nexthop, &prefix, plen, is_discard_route, 
> lrp_addr_s,
>                        out_port, route_table_id, is_src_route,
> -                     ecmp_symmetric_reply, &ecmp_selection_fields, source,
> +                     ecmp_symmetric_reply, override_connected,
> +                     &ecmp_selection_fields, source,
>                        &route->header_, NULL, routes);
>       sset_destroy(&ecmp_selection_fields);
>   }
> @@ -12446,8 +12468,7 @@ parsed_routes_add_connected(const struct ovn_datapath 
> *od,
>   
>           in6_addr_set_mapped_ipv4(&prefix, addr->network);
>           parsed_route_add(od, NULL, &prefix, addr->plen,
> -                         false, addr->addr_s, op,
> -                         0, false,
> +                         false, addr->addr_s, op, 0, false, false,
>                            false, NULL, ROUTE_SOURCE_CONNECTED,
>                            &op->nbrp->header_, NULL, routes);
>       }
> @@ -12455,10 +12476,9 @@ parsed_routes_add_connected(const struct 
> ovn_datapath *od,
>       for (size_t i = 0; i < op->lrp_networks.n_ipv6_addrs; i++) {
>           const struct ipv6_netaddr *addr = &op->lrp_networks.ipv6_addrs[i];
>   
> -        parsed_route_add(od, NULL, &addr->network, addr->plen,
> -                         false, addr->addr_s, op,
> -                         0, false,
> -                         false, NULL, ROUTE_SOURCE_CONNECTED,
> +        parsed_route_add(od, NULL, &addr->network, addr->plen, false,
> +                         addr->addr_s, op, 0, false, false, false,
> +                         NULL, ROUTE_SOURCE_CONNECTED,
>                            &op->nbrp->header_, NULL, routes);
>       }
>   }
> @@ -12513,17 +12533,25 @@ build_route_prefix_s(const struct in6_addr *prefix, 
> unsigned int plen)
>       return prefix_s;
>   }
>   
> -static uint16_t
> -route_source_to_offset(enum route_source source)
> +static int
> +get_route_offset(enum route_source source,
> +                 bool override_connected)
>   {
>       switch (source) {
>       case ROUTE_SOURCE_CONNECTED:
>       case ROUTE_SOURCE_IC_DYNAMIC:
> -        return ROUTE_PRIO_OFFSET_CONNECTED;
> +        return (override_connected)
> +               ? ROUTE_PRIO_OFFSET_IC_LEARNED_CONNECTED_WITH_TABLEID
> +               : ROUTE_PRIO_OFFSET_CONNECTED;
> +
>       case ROUTE_SOURCE_STATIC:
> -        return ROUTE_PRIO_OFFSET_STATIC;
> +        return (override_connected)
> +               ? ROUTE_PRIO_OFFSET_PRIORITY_STATIC
> +               : ROUTE_PRIO_OFFSET_STATIC;
> +
>       case ROUTE_SOURCE_LEARNED:
>           return ROUTE_PRIO_OFFSET_LEARNED;
> +
>       /* Dynamic route types (NAT, LB, and connected-as-host) are not used. */
>       case ROUTE_SOURCE_NAT:
>       case ROUTE_SOURCE_LB:
> @@ -12533,39 +12561,19 @@ route_source_to_offset(enum route_source source)
>       }
>   }
>   
> -static void
> -build_route_match(const struct ovn_port *op_inport, uint32_t rtb_id,
> -                  const char *network_s, int plen, bool is_src_route,
> -                  bool is_ipv4, struct ds *match, uint16_t *priority,
> -                  enum route_source source, bool has_protocol_match)
> +static uint16_t
> +calc_priority(int plen,
> +              enum route_source source,
> +              bool override_connected,
> +              bool is_src_route,
> +              bool has_protocol_match)
>   {
> -    const char *dir;
> -    int ofs = route_source_to_offset(source);
> -
> -    /* The priority here is calculated to implement longest-prefix-match
> -     * routing. */
> -    if (is_src_route) {
> -        dir = "src";
> -        ofs = 0;
> -    } else {
> -        dir = "dst";
> -    }
> +    int priority = is_src_route ? 0 :
> +                   get_route_offset(source, override_connected);
>   
> -    if (op_inport) {
> -        ds_put_format(match, "inport == %s && ", op_inport->json_key);
> -    }
> -    if (rtb_id || source == ROUTE_SOURCE_STATIC ||
> -            source == ROUTE_SOURCE_LEARNED) {
> -        ds_put_format(match, "%s == %d && ", REG_ROUTE_TABLE_ID, rtb_id);
> -    }
> +    priority += (plen * ROUTE_PRIO_OFFSET_MULTIPLIER) + has_protocol_match;
>   
> -    if (has_protocol_match) {
> -        ofs += 1;
> -    }
> -    *priority = (plen * ROUTE_PRIO_OFFSET_MULTIPLIER) + ofs;
> -
> -    ds_put_format(match, "ip%s.%s == %s/%d", is_ipv4 ? "4" : "6", dir,
> -                  network_s, plen);
> +    return priority + ROUTE_PRIO_BASE_SHIFT;
>   }
>   
>   bool
> @@ -12756,10 +12764,21 @@ build_ecmp_route_flow(struct lflow_table *lflows,
>       struct ds route_match = DS_EMPTY_INITIALIZER;
>   
>       char *prefix_s = build_route_prefix_s(&eg->prefix, eg->plen);
> -    build_route_match(NULL, eg->route_table_id, prefix_s, eg->plen,
> -                      eg->is_src_route, is_ipv4_prefix, &route_match,
> -                      &priority, eg->source,
> -                      protocol != NULL);
> +
> +    if (eg->route_table_id || eg->source == ROUTE_SOURCE_STATIC
> +        || eg->source == ROUTE_SOURCE_LEARNED) {
> +        ds_put_format(&route_match, "%s == %d && ", REG_ROUTE_TABLE_ID,
> +                      eg->route_table_id);
> +    }
> +
> +    ds_put_format(&route_match, "ip%s.%s == %s/%d",
> +                  is_ipv4_prefix ? "4" : "6",
> +                  eg->is_src_route ? "src" : "dst",
> +                  prefix_s, eg->plen);
> +
> +    priority = calc_priority(eg->plen, eg->source, false,
> +                             eg->is_src_route, protocol != NULL);
> +
>       free(prefix_s);
>   
>       struct ds actions = DS_EMPTY_INITIALIZER;
> @@ -12886,10 +12905,12 @@ add_route(struct lflow_table *lflows, const struct 
> ovn_datapath *od,
>             const struct sset *bfd_ports,
>             const struct ovsdb_idl_row *stage_hint, bool is_discard_route,
>             enum route_source source, struct lflow_ref *lflow_ref,
> -          bool is_ipv4_prefix, bool is_ipv4_nexthop)
> +          bool is_ipv4_prefix, bool is_ipv4_nexthop,
> +          bool override_connected)
>   {
>       struct ds match = DS_EMPTY_INITIALIZER;
> -    uint16_t priority;
> +    uint16_t priority = calc_priority(plen, source, override_connected,
> +                                      is_src_route, false);
>       const struct ovn_port *op_inport = NULL;
>   
>       /* IPv6 link-local addresses must be scoped to the local router port. */
> @@ -12900,8 +12921,19 @@ add_route(struct lflow_table *lflows, const struct 
> ovn_datapath *od,
>               op_inport = op;
>           }
>       }
> -    build_route_match(op_inport, rtb_id, network_s, plen, is_src_route,
> -                      is_ipv4_prefix, &match, &priority, source, false);
> +
> +    if (op_inport) {
> +        ds_put_format(&match, "inport == %s && ", op_inport->json_key);
> +    }
> +    if (rtb_id || source == ROUTE_SOURCE_STATIC ||
> +        source == ROUTE_SOURCE_LEARNED) {
> +        ds_put_format(&match, "%s == %d && ", REG_ROUTE_TABLE_ID, rtb_id);
> +    }
> +
> +    ds_put_format(&match, "ip%s.%s == %s/%d",
> +                  is_ipv4_prefix ? "4" : "6",
> +                  is_src_route ? "src" : "dst",
> +                  network_s, plen);
>   
>       struct ds common_actions = DS_EMPTY_INITIALIZER;
>       struct ds actions = DS_EMPTY_INITIALIZER;
> @@ -12966,7 +12998,7 @@ build_route_flow(struct lflow_table *lflows, const 
> struct ovn_datapath *od,
>                 route->route_table_id, bfd_ports,
>                 route->source_hint,
>                 route->is_discard_route, route->source, lflow_ref,
> -              is_ipv4_prefix, is_ipv4_nexthop);
> +              is_ipv4_prefix, is_ipv4_nexthop, route->override_connected);
>   
>       free(prefix_s);
>   }
> @@ -18706,7 +18738,7 @@ build_routable_flows_for_router_port(
>                                 bfd_ports, &router_port->nbrp->header_,
>                                 false, ROUTE_SOURCE_CONNECTED,
>                                 lrp->stateful_lflow_ref,
> -                              true, is_ipv4_nexthop ? true : false);
> +                              true, is_ipv4_nexthop ? true : false, false);
>                   }
>               }
>           }
> diff --git a/northd/northd.h b/northd/northd.h
> index e86d39f9a..22c752c8a 100644
> --- a/northd/northd.h
> +++ b/northd/northd.h
> @@ -840,15 +840,16 @@ enum route_source {
>   struct parsed_route {
>       struct hmap_node key_node;
>       struct in6_addr prefix;
> -    unsigned int plen;
>       struct in6_addr *nexthop; /* NULL for ROUTE_SOURCE_CONNECTED */
> -    bool is_src_route;
> +    unsigned int plen;
>       uint32_t route_table_id;
>       uint32_t hash;
> +    bool is_src_route;
>       bool ecmp_symmetric_reply;
> +    bool override_connected;
>       bool is_discard_route;
> -    const struct ovn_datapath *od;
>       bool stale;
> +    const struct ovn_datapath *od;
>       struct sset ecmp_selection_fields;
>       enum route_source source;
>       const struct ovsdb_idl_row *source_hint;
> @@ -875,6 +876,7 @@ struct parsed_route *parsed_route_add(
>       uint32_t route_table_id,
>       bool is_src_route,
>       bool ecmp_symmetric_reply,
> +    bool override_connected,
>       const struct sset *ecmp_selection_fields,
>       enum route_source source,
>       const struct ovsdb_idl_row *source_hint,
> diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml
> index 4d6370da6..1d9e6b587 100644
> --- a/northd/ovn-northd.8.xml
> +++ b/northd/ovn-northd.8.xml
> @@ -6293,6 +6293,50 @@ clone {
>         </ul>
>       </p>
>   
> +    <h1>Route Administrative Distance in OVN</h1>
> +
> +    <p>
> +      In OVN, routes are selected based on an administrative distance, 
> similar
> +      to traditional networking but with some differences.
> +      Routes with higher priority are preferred over those with lower 
> priority.
> +      The priority order, from highest to lowest, is as follows:
> +    </p>
> +
> +    <p>
> +      <ol>
> +        <li>
> +          High-priority static routes - includes routes with
> +          <code>override-connected</code> option set, as well as ic-learned
> +          routes with <code>override-connected</code> option set to true.
> +        </li>
> +
> +        <li>
> +          Ic-learned connected routes with route_table - connected routes
> +          learned via IC that have the <code>route_table</code> parameter 
> set.
> +        </li>
> +
> +        <li>
> +          Connected routes - directly connected routes, including ic-learned
> +          connected routes that do not have a <code>route_table</code> set.
> +        </li>
> +
> +        <li>
> +          Static routes - manually configured static routes.
> +        </li>
> +
> +        <li>
> +          Learned routes - routes learned from outside via ovn-controller.
> +        </li>
> +
> +        <li>
> +          Src-ip routes - source-based static IP routes.
> +          Please see the <code>OVN_Northbound</code> database
> +          <code>Logical_Router_Static_Route</code> table documentation in
> +          <code>ovn-nb</code> for details.
> +        </li>
> +      </ol>
> +    </p>
> +
>       <h1>Drop sampling</h1>
>   
>       <p>
> diff --git a/ovn-ic-sb.ovsschema b/ovn-ic-sb.ovsschema
> index e0e0fef5e..9208e7ab5 100644
> --- a/ovn-ic-sb.ovsschema
> +++ b/ovn-ic-sb.ovsschema
> @@ -1,7 +1,7 @@
>   {
>       "name": "OVN_IC_Southbound",
> -    "version": "2.5.0",
> -    "cksum": "1892994110 9713",
> +    "version": "2.6.0",
> +    "cksum": "2842701319 9868",
>       "tables": {
>           "IC_SB_Global": {
>               "columns": {
> @@ -118,6 +118,9 @@
>                       "enum": ["set",
>                                ["connected", "static", "loadbalancer",
>                                 "connected-dynamic"]]}}},
> +                "options": {
> +                    "type": {"key": "string", "value": "string",
> +                             "min": 0, "max": "unlimited"}},
>                   "external_ids": {
>                       "type": {"key": "string", "value": "string",
>                                "min": 0, "max": "unlimited"}}},
> diff --git a/ovn-ic-sb.xml b/ovn-ic-sb.xml
> index f30760100..f0d450681 100644
> --- a/ovn-ic-sb.xml
> +++ b/ovn-ic-sb.xml
> @@ -358,6 +358,14 @@
>           have more than one Transit Switch, which interconnects them,
>           directly-connected routes will be added via each transit switch port
>           and configured as ECMP routes.
> +        Additionally, these routes will be advertised to other AZ and learned
> +        into route table that has the same name in the remote logical router.
> +        When learned, these routes are automatically marked with
> +        the <code>override-connected</code> option, giving them higher 
> priority
> +        than any local connected route with same prefix in that route table.
> +        This enables policy-based routing scenarios where traffic processed
> +        within a specific route table can be forcibly forwarded to remote AZ
> +        even when local connected route exists.
>           </p>
>           <p>
>           Static routes within route tables will be advertised and learned 
> only
> @@ -399,6 +407,25 @@
>           </p>
>         </column>
>       </group>
> +
> +    <group title="Options">
> +      <column name="options">
> +        This column provides general key/value settings. The supported
> +        options are described individually below.
> +      </column>
> +
> +      <column name="options" key="override-connected"
> +              type='{"type": "boolean"}'>
> +        <p>
> +            This option is a copy of its Northbound DB counterpart.
> +        </p>
> +        <p>
> +            For connected routes this option is set to true if there is a 
> route
> +            table associated with given connected route, i.e.
> +            <ref table="Route" column="route_table"/> is not empty.
> +        </p>
> +     </column>
> +    </group>
>     </table>
>   
>     <table name="Connection" title="OVSDB client connections.">
> diff --git a/ovn-nb.xml b/ovn-nb.xml
> index 592008745..916ae811e 100644
> --- a/ovn-nb.xml
> +++ b/ovn-nb.xml
> @@ -5056,6 +5056,14 @@ or
>             <li>static</li>
>           </ol>
>         </column>
> +      <column name="options" key="override-connected">
> +        This option can be manually set for local static routes and
> +        automatically set for ovn-interconnected learned routes.
> +        Default value: <code>false</code>.
> +
> +        This option raises route's priority to be highest among routes
> +        with same prefix.
> +      </column>
>       </group>
>   
>     </table>
> diff --git a/tests/ovn-ic.at b/tests/ovn-ic.at
> index 0fa7c4f29..bf50da5de 100644
> --- a/tests/ovn-ic.at
> +++ b/tests/ovn-ic.at
> @@ -885,9 +885,10 @@ check ovn_as az1 ovn-nbctl lb-add lb_v6 [[4242::1]]:80 
> "[[4242::2]]:80"
>   check ovn_as az1 ovn-nbctl lr-lb-add lr1 lb_v6
>   OVS_WAIT_UNTIL([ovn_as az2 ovn-nbctl lr-route-list lr2 | grep learned | 
> grep 4242])
>   
> -AT_CHECK([ovn-ic-sbctl list route | grep 'ip_prefix.*4242' -A 2], [0], [dnl
> +AT_CHECK([ovn-ic-sbctl list route | grep 'ip_prefix.*4242' -A 3], [0], [dnl
>   ip_prefix           : "4242::1/128"
>   nexthop             : "2001:db8:1::1"
> +options             : {}
>   origin              : loadbalancer
>   ])
>   
> @@ -1211,6 +1212,7 @@ Route Table <main>:
>   Route Table rtb1:
>                10.11.1.0/24             169.254.100.1 dst-ip (learned)
>                10.11.2.0/24               169.254.0.1 dst-ip
> +           192.168.0.0/24             169.254.100.1 dst-ip (learned) 
> override-connected
>                10.22.2.0/24               169.254.0.2 src-ip
>                   0.0.0.0/0             169.254.100.1 dst-ip (learned)
>   ])
> @@ -1332,8 +1334,11 @@ check ovn-ic-nbctl --wait=sb sync
>   OVS_WAIT_FOR_OUTPUT([ovn_as az1 ovn-nbctl lr-route-list lr11 | grep 192.168 
> |
>                grep learned | awk '{print $1, $2, $5}' | sort ], [0], [dnl
>   192.168.0.0/24 169.254.101.2 ecmp
> +192.168.0.0/24 169.254.101.2 override-connected
>   192.168.0.0/24 169.254.102.2 ecmp
> +192.168.0.0/24 169.254.102.2 override-connected
>   192.168.0.0/24 169.254.103.2 ecmp
> +192.168.0.0/24 169.254.103.2 override-connected
>   ])
>   
>   # Test static routes from lr12 rtbs rtb1,rtb2,rtb3 were learned to lr11
> @@ -1341,22 +1346,27 @@ OVS_WAIT_FOR_OUTPUT([ovn_as az1 ovn-nbctl 
> --route-table=rtb1 lr-route-list lr11]
>   IPv4 Routes
>   Route Table rtb1:
>               10.10.10.0/24             169.254.101.2 dst-ip (learned)
> +           192.168.0.0/24             169.254.101.2 dst-ip (learned) 
> override-connected
>   ])
>   OVS_WAIT_FOR_OUTPUT([ovn_as az1 ovn-nbctl --route-table=rtb2 lr-route-list 
> lr11], [0], [dnl
>   IPv4 Routes
>   Route Table rtb2:
>               10.10.10.0/24             169.254.102.2 dst-ip (learned)
> +           192.168.0.0/24             169.254.102.2 dst-ip (learned) 
> override-connected
>   ])
>   OVS_WAIT_FOR_OUTPUT([ovn_as az1 ovn-nbctl --route-table=rtb3 lr-route-list 
> lr11], [0], [dnl
>   IPv4 Routes
>   Route Table rtb3:
>               10.10.10.0/24             169.254.103.2 dst-ip (learned)
> +           192.168.0.0/24             169.254.103.2 dst-ip (learned) 
> override-connected
>   ])
>   
>   # Test routes from lr12 didn't leak as learned to lr21
>   OVS_WAIT_FOR_OUTPUT([ovn_as az1 ovn-nbctl lr-route-list lr21 | grep 192.168 
> | sort], [0], [dnl
>              192.168.0.0/24             169.254.101.2 dst-ip (learned) ecmp
> +           192.168.0.0/24             169.254.101.2 dst-ip (learned) 
> override-connected
>              192.168.0.0/24             169.254.102.2 dst-ip (learned) ecmp
> +           192.168.0.0/24             169.254.102.2 dst-ip (learned) 
> override-connected
>   ])
>   
>   OVN_CLEANUP_IC([az1], [az2])
> @@ -1457,8 +1467,11 @@ check ovn-ic-nbctl --wait=sb sync
>   AT_CHECK([ovn_as az1 ovn-nbctl lr-route-list lr11 | grep 2001:db8:200 |
>                grep learned | awk '{print $1, $2, $5}' | sort], [0], [dnl
>   2001:db8:200::/64 2001:db8:1::2 ecmp
> +2001:db8:200::/64 2001:db8:1::2 override-connected
>   2001:db8:200::/64 2001:db8:2::2 ecmp
> +2001:db8:200::/64 2001:db8:2::2 override-connected
>   2001:db8:200::/64 2001:db8:3::2 ecmp
> +2001:db8:200::/64 2001:db8:3::2 override-connected
>   ])
>   
>   # Test static routes from lr12 rtbs rtb1,rtb2,rtb3 were learned to lr11
> @@ -1466,18 +1479,21 @@ OVS_WAIT_UNTIL([ovn_as az1 ovn-nbctl 
> --route-table=rtb1 lr-route-list lr11 | gre
>   AT_CHECK([ovn_as az1 ovn-nbctl --route-table=rtb1 lr-route-list lr11], [0], 
> [dnl
>   IPv6 Routes
>   Route Table rtb1:
> +        2001:db8:200::/64             2001:db8:1::2 dst-ip (learned) 
> override-connected
>          2001:db8:aaaa::/64             2001:db8:1::2 dst-ip (learned)
>   ])
>   OVS_WAIT_UNTIL([ovn_as az1 ovn-nbctl --route-table=rtb2 lr-route-list lr11 
> | grep learned])
>   AT_CHECK([ovn_as az1 ovn-nbctl --route-table=rtb2 lr-route-list lr11], [0], 
> [dnl
>   IPv6 Routes
>   Route Table rtb2:
> +        2001:db8:200::/64             2001:db8:2::2 dst-ip (learned) 
> override-connected
>          2001:db8:aaaa::/64             2001:db8:2::2 dst-ip (learned)
>   ])
>   OVS_WAIT_UNTIL([ovn_as az1 ovn-nbctl --route-table=rtb3 lr-route-list lr11 
> | grep learned])
>   AT_CHECK([ovn_as az1 ovn-nbctl --route-table=rtb3 lr-route-list lr11], [0], 
> [dnl
>   IPv6 Routes
>   Route Table rtb3:
> +        2001:db8:200::/64             2001:db8:3::2 dst-ip (learned) 
> override-connected
>          2001:db8:aaaa::/64             2001:db8:3::2 dst-ip (learned)
>   ])
>   
> @@ -1485,7 +1501,9 @@ Route Table rtb3:
>   OVS_WAIT_UNTIL([ovn_as az1 ovn-nbctl lr-route-list lr21 | grep 
> "2001:db8:2::2" | grep learned])
>   AT_CHECK([ovn_as az1 ovn-nbctl lr-route-list lr21 | grep 2001 | sort], [0], 
> [dnl
>           2001:db8:200::/64             2001:db8:1::2 dst-ip (learned) ecmp
> +        2001:db8:200::/64             2001:db8:1::2 dst-ip (learned) 
> override-connected
>           2001:db8:200::/64             2001:db8:2::2 dst-ip (learned) ecmp
> +        2001:db8:200::/64             2001:db8:2::2 dst-ip (learned) 
> override-connected
>   ])
>   
>   OVN_CLEANUP_IC([az1], [az2])
> @@ -4839,3 +4857,165 @@ OVN_CLEANUP_IC
>   
>   AT_CLEANUP
>   ])
> +
> +OVN_FOR_EACH_NORTHD([
> +AT_SETUP([ovn-ic -- east-west - 2az])
> +
> +ovn_init_ic_db
> +ovn-ic-nbctl ts-add rtb-1
> +ovn-ic-nbctl ts-add rtb-2
> +
> +ovn_start az1
> +ovn_as az1
> +
> +check ovn_as az1 ovn-ic-nbctl --wait=sb sync
> +check ovn_as az1 ovn-nbctl set nb_global . options:ic-route-learn=true
> +check ovn_as az1 ovn-nbctl set nb_global . options:ic-route-adv=true
> +
> +check ovn_as az1 ovn-nbctl ls-add subnet-A
> +check ovn_as az1 ovn-nbctl lsp-add subnet-A subnet-A-up -- lsp-set-type 
> subnet-A-up router -- lsp-set-addresses subnet-A-up router -- lsp-set-options 
> subnet-A-up router-port=subnet-A
> +check ovn_as az1 ovn-nbctl lsp-add subnet-A client -- lsp-set-addresses 
> client "0a:00:43:1e:92:20 172.31.0.4"
> +
> +check ovn_as az1 ovn-nbctl ls-add subnet-B
> +check ovn_as az1 ovn-nbctl lsp-add subnet-B subnet-B-up -- lsp-set-type 
> subnet-B-up router -- lsp-set-addresses subnet-B-up router -- lsp-set-options 
> subnet-B-up router-port=subnet-B
> +check ovn_as az1 ovn-nbctl lsp-add subnet-B server -- lsp-set-addresses 
> server "0a:00:b9:86:a4:00 172.31.1.4"
> +
> +check ovn_as az1 ovn-nbctl lsp-add rtb-1 rtb-1-down1 -- lsp-set-type 
> rtb-1-down1 router -- lsp-set-addresses rtb-1-down1 router -- lsp-set-options 
> rtb-1-down1 router-port=rtb-1
> +check ovn_as az1 ovn-nbctl lsp-add rtb-2 rtb-2-down1 -- lsp-set-type 
> rtb-2-down1 router -- lsp-set-addresses rtb-2-down1 router -- lsp-set-options 
> rtb-2-down1 router-port=rtb-2
> +
> +check ovn_as az1 ovn-nbctl lr-add rt1
> +check ovn_as az1 ovn-nbctl lrp-add rt1 subnet-A "d0:fe:00:00:00:14" 
> "172.31.0.1/24" -- lrp-set-options subnet-A route_table=table1
> +check ovn_as az1 ovn-nbctl lrp-add rt1 subnet-B "d0:fe:00:00:00:15" 
> "172.31.1.1/24" -- lrp-set-options subnet-B route_table=table1
> +check ovn_as az1 ovn-nbctl lrp-add rt1 rtb-1 "00:00:a0:9e:9d:40" 
> "169.254.100.1/27" -- lrp-set-options rtb-1 route_table=table1
> +check ovn_as az1 ovn-nbctl lrp-add rt1 rtb-2 "00:00:60:15:b8:20" 
> "169.254.100.33/27" -- lrp-set-options rtb-2 route_table=table2
> +
> +ovn_start az2
> +ovn_as az2
> +
> +check ovn_as az2 ovn-ic-nbctl --wait=sb sync
> +check ovn_as az2 ovn-nbctl set nb_global . options:ic-route-learn=true
> +check ovn_as az2 ovn-nbctl set nb_global . options:ic-route-adv=true
> +
> +check ovn_as az2 ovn-nbctl ls-add subnet-C
> +check ovn_as az2 ovn-nbctl lsp-add subnet-C subnet-C-up -- lsp-set-type 
> subnet-C-up router -- lsp-set-addresses subnet-C-up router -- lsp-set-options 
> subnet-C-up router-port=subnet-C
> +check ovn_as az2 ovn-nbctl lsp-add subnet-C filter1 -- lsp-set-addresses 
> filter1 "0a:01:4f:43:ce:e1 172.31.2.4"
> +
> +check ovn_as az2 ovn-nbctl ls-add subnet-D
> +check ovn_as az2 ovn-nbctl lsp-add subnet-D subnet-D-up -- lsp-set-type 
> subnet-D-up router -- lsp-set-addresses subnet-D-up router -- lsp-set-options 
> subnet-D-up router-port=subnet-D
> +check ovn_as az2 ovn-nbctl lsp-add subnet-D filter2 -- lsp-set-addresses 
> filter2 "0a:01:39:eb:b1:41 172.31.3.4"
> +
> +check ovn_as az2 ovn-nbctl lsp-add rtb-1 rtb-1-down2 -- lsp-set-type 
> rtb-1-down2 router -- lsp-set-addresses rtb-1-down2 router -- lsp-set-options 
> rtb-1-down2 router-port=rtb-1
> +check ovn_as az2 ovn-nbctl lsp-add rtb-2 rtb-2-down2 -- lsp-set-type 
> rtb-2-down2 router -- lsp-set-addresses rtb-2-down2 router -- lsp-set-options 
> rtb-2-down2 router-port=rtb-2
> +
> +check ovn_as az2 ovn-nbctl lr-add rt1
> +check ovn_as az2 ovn-nbctl lrp-add rt1 subnet-C "d0:fe:00:00:00:16" 
> "172.31.2.1/24" -- lrp-set-options subnet-C route_table=table2
> +check ovn_as az2 ovn-nbctl lrp-add rt1 subnet-D "d0:fe:00:00:00:17" 
> "172.31.3.1/24" -- lrp-set-options subnet-D route_table=table2
> +check ovn_as az2 ovn-nbctl lrp-add rt1 rtb-1 "00:01:a0:9e:9d:40" 
> "169.254.100.2/27" -- lrp-set-options rtb-1 route_table=table1
> +check ovn_as az2 ovn-nbctl lrp-add rt1 rtb-2 "00:01:60:15:b8:20" 
> "169.254.100.34/27" -- lrp-set-options rtb-2 route_table=table2
> +
> +check ovn_as az2 ovn-nbctl --route-table=table1 --override-connected 
> lr-route-add rt1 "172.31.0.0/24" "172.31.2.4"
> +check ovn_as az2 ovn-nbctl --route-table=table1 --override-connected 
> lr-route-add rt1 "172.31.1.0/24" "172.31.3.4"
> +
> +check ovn-ic-nbctl --wait=sb sync
> +
> +AT_CHECK([ovn_as az1 ovn-nbctl lr-route-list rt1], [0], [dnl
> +IPv4 Routes
> +Route Table <main>:
> +            172.31.2.0/24             169.254.100.2 dst-ip (learned) ecmp
> +            172.31.2.0/24            169.254.100.34 dst-ip (learned) ecmp
> +            172.31.3.0/24             169.254.100.2 dst-ip (learned) ecmp
> +            172.31.3.0/24            169.254.100.34 dst-ip (learned) ecmp
> +
> +Route Table table1:
> +            172.31.0.0/24             169.254.100.2 dst-ip (learned) 
> override-connected
> +            172.31.1.0/24             169.254.100.2 dst-ip (learned) 
> override-connected
> +            172.31.2.0/24             169.254.100.2 dst-ip (learned) 
> override-connected
> +            172.31.3.0/24             169.254.100.2 dst-ip (learned) 
> override-connected
> +
> +Route Table table2:
> +            172.31.2.0/24            169.254.100.34 dst-ip (learned) 
> override-connected
> +            172.31.3.0/24            169.254.100.34 dst-ip (learned) 
> override-connected
> +])
> +
> +AT_CHECK([ovn_as az2 ovn-nbctl lr-route-list rt1], [0], [dnl
> +IPv4 Routes
> +Route Table <main>:
> +            172.31.0.0/24             169.254.100.1 dst-ip (learned) ecmp
> +            172.31.0.0/24            169.254.100.33 dst-ip (learned) ecmp
> +            172.31.1.0/24             169.254.100.1 dst-ip (learned) ecmp
> +            172.31.1.0/24            169.254.100.33 dst-ip (learned) ecmp
> +
> +Route Table table1:
> +            172.31.0.0/24                172.31.2.4 dst-ip override-connected
> +            172.31.0.0/24             169.254.100.1 dst-ip (learned) 
> override-connected
> +            172.31.1.0/24                172.31.3.4 dst-ip override-connected
> +            172.31.1.0/24             169.254.100.1 dst-ip (learned) 
> override-connected
> +
> +Route Table table2:
> +            172.31.0.0/24            169.254.100.33 dst-ip (learned) 
> override-connected
> +            172.31.1.0/24            169.254.100.33 dst-ip (learned) 
> override-connected
> +])
> +
> +AZF1="az1/az1_flow.txt"
> +AZF2="az2/az2_flow.txt"
> +ovn_as az1 ovn-sbctl lflow-list rt1 > $AZF1
> +ovn_as az2 ovn-sbctl lflow-list rt1 > $AZF2
> +
> +VA1=$(grep "ip_routing_pre.*rtb-1" $AZF1 | sed -n 's/.*reg7 = 
> \([[0-9]]*\).*/\1/p')
> +VA2=$(grep "ip_routing_pre.*rtb-2" $AZF1 | sed -n 's/.*reg7 = 
> \([[0-9]]*\).*/\1/p')
> +
> +#grep "ip_routing[[^_]]" $AZF1 | sed "s/reg7 == $VA1/reg7 == rtb-1/g" | sed 
> "s/reg7 == $VA2/reg7 == rtb-2/g" |  ovn_strip_lflows > az1/az1_parsed.txt
> +
> +AT_CHECK([grep "ip_routing[[^_]]" $AZF1 | sed "s/reg7 == $VA1/reg7 == 
> rtb-1/g" | sed "s/reg7 == $VA2/reg7 == rtb-2/g" |  ovn_strip_lflows], [0], 
> [dnl
> +  table=??(lr_in_ip_routing   ), priority=0    , match=(1), action=(drop;)
> +  table=??(lr_in_ip_routing   ), priority=10550, match=(nd_rs || nd_ra), 
> action=(drop;)
> +  table=??(lr_in_ip_routing   ), priority=1842 , match=(ip4.dst == 
> 172.31.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 172.31.0.1; eth.src = d0:fe:00:00:00:14; outport = "subnet-A"; flags.loopback 
> = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1842 , match=(ip4.dst == 
> 172.31.1.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 172.31.1.1; eth.src = d0:fe:00:00:00:15; outport = "subnet-B"; flags.loopback 
> = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1842 , match=(ip4.dst == 
> 172.31.2.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 169.254.100.2; 
> reg5 = 169.254.100.1; eth.src = 00:00:a0:9e:9d:40; outport = "rtb-1"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1842 , match=(ip4.dst == 
> 172.31.2.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 169.254.100.34; 
> reg5 = 169.254.100.33; eth.src = 00:00:60:15:b8:20; outport = "rtb-2"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1842 , match=(ip4.dst == 
> 172.31.3.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 169.254.100.2; 
> reg5 = 169.254.100.1; eth.src = 00:00:a0:9e:9d:40; outport = "rtb-1"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1842 , match=(ip4.dst == 
> 172.31.3.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 169.254.100.34; 
> reg5 = 169.254.100.33; eth.src = 00:00:60:15:b8:20; outport = "rtb-2"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1844 , match=(reg7 == rtb-1 && 
> ip4.dst == 172.31.2.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 
> 169.254.100.2; reg5 = 169.254.100.1; eth.src = 00:00:a0:9e:9d:40; outport = 
> "rtb-1"; flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1844 , match=(reg7 == rtb-1 && 
> ip4.dst == 172.31.3.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 
> 169.254.100.2; reg5 = 169.254.100.1; eth.src = 00:00:a0:9e:9d:40; outport = 
> "rtb-1"; flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1844 , match=(reg7 == rtb-2 && 
> ip4.dst == 172.31.2.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 
> 169.254.100.34; reg5 = 169.254.100.33; eth.src = 00:00:60:15:b8:20; outport = 
> "rtb-2"; flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1844 , match=(reg7 == rtb-2 && 
> ip4.dst == 172.31.3.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 
> 169.254.100.34; reg5 = 169.254.100.33; eth.src = 00:00:60:15:b8:20; outport = 
> "rtb-2"; flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1846 , match=(reg7 == rtb-1 && 
> ip4.dst == 172.31.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 
> 169.254.100.2; reg5 = 169.254.100.1; eth.src = 00:00:a0:9e:9d:40; outport = 
> "rtb-1"; flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1846 , match=(reg7 == rtb-1 && 
> ip4.dst == 172.31.1.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 
> 169.254.100.2; reg5 = 169.254.100.1; eth.src = 00:00:a0:9e:9d:40; outport = 
> "rtb-1"; flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1878 , match=(ip4.dst == 
> 169.254.100.0/27), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 
> = 169.254.100.1; eth.src = 00:00:a0:9e:9d:40; outport = "rtb-1"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1878 , match=(ip4.dst == 
> 169.254.100.32/27), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 
> = 169.254.100.33; eth.src = 00:00:60:15:b8:20; outport = "rtb-2"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(inport == "rtb-1" && 
> ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = ip6.dst; 
> xxreg1 = fe80::200:a0ff:fe9e:9d40; eth.src = 00:00:a0:9e:9d:40; outport = 
> "rtb-1"; flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(inport == "rtb-2" && 
> ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = ip6.dst; 
> xxreg1 = fe80::200:60ff:fe15:b820; eth.src = 00:00:60:15:b8:20; outport = 
> "rtb-2"; flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(inport == "subnet-A" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::d2fe:ff:fe00:14; eth.src = d0:fe:00:00:00:14; outport 
> = "subnet-A"; flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(inport == "subnet-B" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::d2fe:ff:fe00:15; eth.src = d0:fe:00:00:00:15; outport 
> = "subnet-B"; flags.loopback = 1; reg9[[9]] = 0; next;)
> +])
> +
> +VA1=$(grep "ip_routing_pre.*rtb-1" $AZF2 | sed -n 's/.*reg7 = 
> \([[0-9]]*\).*/\1/p')
> +VA2=$(grep "ip_routing_pre.*rtb-2" $AZF2 | sed -n 's/.*reg7 = 
> \([[0-9]]*\).*/\1/p')
> +
> +AT_CHECK([grep "ip_routing[[^_]]" $AZF2 | sed "s/reg7 == $VA1/reg7 == 
> rtb-1/g" | sed "s/reg7 == $VA2/reg7 == rtb-2/g" |  ovn_strip_lflows], [0], 
> [dnl
> +  table=??(lr_in_ip_routing   ), priority=0    , match=(1), action=(drop;)
> +  table=??(lr_in_ip_routing   ), priority=10550, match=(nd_rs || nd_ra), 
> action=(drop;)
> +  table=??(lr_in_ip_routing   ), priority=1842 , match=(ip4.dst == 
> 172.31.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 169.254.100.1; 
> reg5 = 169.254.100.2; eth.src = 00:01:a0:9e:9d:40; outport = "rtb-1"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1842 , match=(ip4.dst == 
> 172.31.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 169.254.100.33; 
> reg5 = 169.254.100.34; eth.src = 00:01:60:15:b8:20; outport = "rtb-2"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1842 , match=(ip4.dst == 
> 172.31.1.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 169.254.100.1; 
> reg5 = 169.254.100.2; eth.src = 00:01:a0:9e:9d:40; outport = "rtb-1"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1842 , match=(ip4.dst == 
> 172.31.1.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 169.254.100.33; 
> reg5 = 169.254.100.34; eth.src = 00:01:60:15:b8:20; outport = "rtb-2"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1842 , match=(ip4.dst == 
> 172.31.2.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 172.31.2.1; eth.src = d0:fe:00:00:00:16; outport = "subnet-C"; flags.loopback 
> = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1842 , match=(ip4.dst == 
> 172.31.3.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 172.31.3.1; eth.src = d0:fe:00:00:00:17; outport = "subnet-D"; flags.loopback 
> = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1844 , match=(reg7 == rtb-1 && 
> ip4.dst == 172.31.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 
> 169.254.100.1; reg5 = 169.254.100.2; eth.src = 00:01:a0:9e:9d:40; outport = 
> "rtb-1"; flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1844 , match=(reg7 == rtb-1 && 
> ip4.dst == 172.31.1.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 
> 169.254.100.1; reg5 = 169.254.100.2; eth.src = 00:01:a0:9e:9d:40; outport = 
> "rtb-1"; flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1844 , match=(reg7 == rtb-2 && 
> ip4.dst == 172.31.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 
> 169.254.100.33; reg5 = 169.254.100.34; eth.src = 00:01:60:15:b8:20; outport = 
> "rtb-2"; flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1844 , match=(reg7 == rtb-2 && 
> ip4.dst == 172.31.1.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 
> 169.254.100.33; reg5 = 169.254.100.34; eth.src = 00:01:60:15:b8:20; outport = 
> "rtb-2"; flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1846 , match=(reg7 == rtb-1 && 
> ip4.dst == 172.31.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 
> 172.31.2.4; reg5 = 172.31.2.1; eth.src = d0:fe:00:00:00:16; outport = 
> "subnet-C"; flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1846 , match=(reg7 == rtb-1 && 
> ip4.dst == 172.31.1.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 
> 172.31.3.4; reg5 = 172.31.3.1; eth.src = d0:fe:00:00:00:17; outport = 
> "subnet-D"; flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1878 , match=(ip4.dst == 
> 169.254.100.0/27), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 
> = 169.254.100.2; eth.src = 00:01:a0:9e:9d:40; outport = "rtb-1"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1878 , match=(ip4.dst == 
> 169.254.100.32/27), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 
> = 169.254.100.34; eth.src = 00:01:60:15:b8:20; outport = "rtb-2"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(inport == "rtb-1" && 
> ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = ip6.dst; 
> xxreg1 = fe80::201:a0ff:fe9e:9d40; eth.src = 00:01:a0:9e:9d:40; outport = 
> "rtb-1"; flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(inport == "rtb-2" && 
> ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = ip6.dst; 
> xxreg1 = fe80::201:60ff:fe15:b820; eth.src = 00:01:60:15:b8:20; outport = 
> "rtb-2"; flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(inport == "subnet-C" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::d2fe:ff:fe00:16; eth.src = d0:fe:00:00:00:16; outport 
> = "subnet-C"; flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(inport == "subnet-D" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::d2fe:ff:fe00:17; eth.src = d0:fe:00:00:00:17; outport 
> = "subnet-D"; flags.loopback = 1; reg9[[9]] = 0; next;)
> +])
> +
> +OVN_CLEANUP_IC([az1], [az2])
> +
> +AT_CLEANUP
> +])
> diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
> index 1d7bd6c28..da023c260 100644
> --- a/tests/ovn-northd.at
> +++ b/tests/ovn-northd.at
> @@ -7278,9 +7278,9 @@ AT_CHECK([grep -w "lr_in_ip_routing" lr0flows | 
> ovn_strip_lflows], [0], [dnl
>     table=??(lr_in_ip_routing   ), priority=0    , match=(1), action=(drop;)
>     table=??(lr_in_ip_routing   ), priority=10300, 
> match=(ct_mark.ecmp_reply_port == 1 && reg7 == 0 && ip4.dst == 1.0.0.1/32), 
> action=(ip.ttl--; flags.loopback = 1; eth.src = 00:00:20:20:12:13; reg5 = 
> 192.168.0.1; outport = "lr0-public"; next;)
>     table=??(lr_in_ip_routing   ), priority=10550, match=(nd_rs || nd_ra), 
> action=(drop;)
> -  table=??(lr_in_ip_routing   ), priority=198  , match=(ip4.dst == 
> 192.168.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 192.168.0.1; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=260  , match=(reg7 == 0 && ip4.dst 
> == 1.0.0.1/32), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = 1; 
> reg8[[16..31]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=518  , match=(inport == 
> "lr0-public" && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; 
> xxreg0 = ip6.dst; xxreg1 = fe80::200:20ff:fe20:1213; eth.src = 
> 00:00:20:20:12:13; outport = "lr0-public"; flags.loopback = 1; reg9[[9]] = 0; 
> next;)
> +  table=??(lr_in_ip_routing   ), priority=1842 , match=(ip4.dst == 
> 192.168.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 192.168.0.1; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1936 , match=(reg7 == 0 && ip4.dst 
> == 1.0.0.1/32), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = 1; 
> reg8[[16..31]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(inport == 
> "lr0-public" && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; 
> xxreg0 = ip6.dst; xxreg1 = fe80::200:20ff:fe20:1213; eth.src = 
> 00:00:20:20:12:13; outport = "lr0-public"; flags.loopback = 1; reg9[[9]] = 0; 
> next;)
>   ])
>   
>   AT_CHECK([grep -e "lr_in_ip_routing_ecmp" lr0flows | ovn_strip_lflows], 
> [0], [dnl
> @@ -7304,9 +7304,9 @@ AT_CHECK([grep -w "lr_in_ip_routing" lr0flows | 
> ovn_strip_lflows], [0], [dnl
>     table=??(lr_in_ip_routing   ), priority=0    , match=(1), action=(drop;)
>     table=??(lr_in_ip_routing   ), priority=10300, 
> match=(ct_mark.ecmp_reply_port == 1 && reg7 == 0 && ip4.dst == 1.0.0.1/32), 
> action=(ip.ttl--; flags.loopback = 1; eth.src = 00:00:20:20:12:13; reg5 = 
> 192.168.0.1; outport = "lr0-public"; next;)
>     table=??(lr_in_ip_routing   ), priority=10550, match=(nd_rs || nd_ra), 
> action=(drop;)
> -  table=??(lr_in_ip_routing   ), priority=198  , match=(ip4.dst == 
> 192.168.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 192.168.0.1; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=260  , match=(reg7 == 0 && ip4.dst 
> == 1.0.0.1/32), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = 1; 
> reg8[[16..31]] = select(1, 2);)
> -  table=??(lr_in_ip_routing   ), priority=518  , match=(inport == 
> "lr0-public" && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; 
> xxreg0 = ip6.dst; xxreg1 = fe80::200:20ff:fe20:1213; eth.src = 
> 00:00:20:20:12:13; outport = "lr0-public"; flags.loopback = 1; reg9[[9]] = 0; 
> next;)
> +  table=??(lr_in_ip_routing   ), priority=1842 , match=(ip4.dst == 
> 192.168.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 192.168.0.1; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1936 , match=(reg7 == 0 && ip4.dst 
> == 1.0.0.1/32), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = 1; 
> reg8[[16..31]] = select(1, 2);)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(inport == 
> "lr0-public" && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; 
> xxreg0 = ip6.dst; xxreg1 = fe80::200:20ff:fe20:1213; eth.src = 
> 00:00:20:20:12:13; outport = "lr0-public"; flags.loopback = 1; reg9[[9]] = 0; 
> next;)
>   ])
>   AT_CHECK([grep -e "lr_in_ip_routing_ecmp" lr0flows | sed 
> 's/192\.168\.0\..0/192.168.0.??/' | ovn_strip_lflows], [0], [dnl
>     table=??(lr_in_ip_routing_ecmp), priority=0    , match=(1), action=(drop;)
> @@ -7346,9 +7346,9 @@ AT_CHECK([grep -w "lr_in_ip_routing" lr0flows | 
> ovn_strip_lflows], [0], [dnl
>     table=??(lr_in_ip_routing   ), priority=0    , match=(1), action=(drop;)
>     table=??(lr_in_ip_routing   ), priority=10300, 
> match=(ct_mark.ecmp_reply_port == 1 && reg7 == 0 && ip4.dst == 1.0.0.1/32), 
> action=(ip.ttl--; flags.loopback = 1; eth.src = 00:00:20:20:12:13; reg5 = 
> 192.168.0.1; outport = "lr0-public"; next;)
>     table=??(lr_in_ip_routing   ), priority=10550, match=(nd_rs || nd_ra), 
> action=(drop;)
> -  table=??(lr_in_ip_routing   ), priority=198  , match=(ip4.dst == 
> 192.168.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 192.168.0.1; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=260  , match=(reg7 == 0 && ip4.dst 
> == 1.0.0.1/32), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = 1; 
> reg8[[16..31]] = select(1, 2);)
> -  table=??(lr_in_ip_routing   ), priority=518  , match=(inport == 
> "lr0-public" && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; 
> xxreg0 = ip6.dst; xxreg1 = fe80::200:20ff:fe20:1213; eth.src = 
> 00:00:20:20:12:13; outport = "lr0-public"; flags.loopback = 1; reg9[[9]] = 0; 
> next;)
> +  table=??(lr_in_ip_routing   ), priority=1842 , match=(ip4.dst == 
> 192.168.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 192.168.0.1; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1936 , match=(reg7 == 0 && ip4.dst 
> == 1.0.0.1/32), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = 1; 
> reg8[[16..31]] = select(1, 2);)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(inport == 
> "lr0-public" && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; 
> xxreg0 = ip6.dst; xxreg1 = fe80::200:20ff:fe20:1213; eth.src = 
> 00:00:20:20:12:13; outport = "lr0-public"; flags.loopback = 1; reg9[[9]] = 0; 
> next;)
>   ])
>   AT_CHECK([grep -e "lr_in_ip_routing_ecmp" lr0flows | sed 
> 's/192\.168\.0\..0/192.168.0.??/' | ovn_strip_lflows], [0], [dnl
>     table=??(lr_in_ip_routing_ecmp), priority=0    , match=(1), action=(drop;)
> @@ -7370,14 +7370,14 @@ check ovn-nbctl --wait=sb lr-route-add lr0 1.0.0.0/24 
> 192.168.0.10
>   ovn-sbctl dump-flows lr0 > lr0flows
>   
>   AT_CHECK([grep -e "lr_in_ip_routing.*192.168.0.10" lr0flows | 
> ovn_strip_lflows], [0], [dnl
> -  table=??(lr_in_ip_routing   ), priority=196  , match=(reg7 == 0 && ip4.dst 
> == 1.0.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 192.168.0.10; 
> reg5 = 192.168.0.1; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1840 , match=(reg7 == 0 && ip4.dst 
> == 1.0.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 192.168.0.10; 
> reg5 = 192.168.0.1; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
>   ])
>   
>   check ovn-nbctl --wait=sb lr-route-add lr0 2.0.0.0/24 lr0-public
>   
>   ovn-sbctl dump-flows lr0 > lr0flows
>   AT_CHECK([grep -e "lr_in_ip_routing.*2.0.0.0" lr0flows | ovn_strip_lflows], 
> [0], [dnl
> -  table=??(lr_in_ip_routing   ), priority=196  , match=(reg7 == 0 && ip4.dst 
> == 2.0.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 192.168.0.1; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1840 , match=(reg7 == 0 && ip4.dst 
> == 2.0.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 192.168.0.1; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
>   ])
>   
>   check ovn-nbctl lr-route-add lr0 3.3.0.0/16 192.168.0.11
> @@ -7392,7 +7392,7 @@ check ovn-nbctl set logical_router_static_route 
> $route2_uuid selection_fields="i
>   check ovn-nbctl --wait=sb sync
>   ovn-sbctl dump-flows lr0 > lr0flows
>   AT_CHECK([grep -e "(lr_in_ip_routing   ).*3.3.0.0" lr0flows | sed 
> 's/table=../table=??/' | sort], [0], [dnl
> -  table=??(lr_in_ip_routing   ), priority=132  , match=(reg7 == 0 && ip4.dst 
> == 3.3.0.0/16), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = 1; 
> reg8[[16..31]] = select(values=(1, 2); hash_fields="ip_dst,ip_proto,ip_src");)
> +  table=??(lr_in_ip_routing   ), priority=1744 , match=(reg7 == 0 && ip4.dst 
> == 3.3.0.0/16), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = 1; 
> reg8[[16..31]] = select(values=(1, 2); hash_fields="ip_dst,ip_proto,ip_src");)
>   ])
>   
>   check ovn-nbctl set logical_router_static_route $route1_uuid 
> selection_fields="ip_src,ip_dst,tp_src,tp_dst"
> @@ -7401,10 +7401,10 @@ check ovn-nbctl set logical_router_static_route 
> $route2_uuid selection_fields="i
>   check ovn-nbctl --wait=sb sync
>   ovn-sbctl dump-flows lr0 > lr0flows
>   AT_CHECK([grep -e "(lr_in_ip_routing   ).*3.3.0.0" lr0flows | sed 
> 's/table=../table=??/' | sort], [0], [dnl
> -  table=??(lr_in_ip_routing   ), priority=132  , match=(reg7 == 0 && ip4.dst 
> == 3.3.0.0/16), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = 1; 
> reg8[[16..31]] = select(values=(1, 2); hash_fields="ip_dst,ip_proto,ip_src");)
> -  table=??(lr_in_ip_routing   ), priority=133  , match=(reg7 == 0 && ip4.dst 
> == 3.3.0.0/16 && sctp), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = 
> 1; reg8[[16..31]] = select(values=(1, 2); 
> hash_fields="ip_dst,ip_proto,ip_src,sctp_dst,sctp_src");)
> -  table=??(lr_in_ip_routing   ), priority=133  , match=(reg7 == 0 && ip4.dst 
> == 3.3.0.0/16 && tcp), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = 
> 1; reg8[[16..31]] = select(values=(1, 2); 
> hash_fields="ip_dst,ip_proto,ip_src,tcp_dst,tcp_src");)
> -  table=??(lr_in_ip_routing   ), priority=133  , match=(reg7 == 0 && ip4.dst 
> == 3.3.0.0/16 && udp), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = 
> 1; reg8[[16..31]] = select(values=(1, 2); 
> hash_fields="ip_dst,ip_proto,ip_src,udp_dst,udp_src");)
> +  table=??(lr_in_ip_routing   ), priority=1744 , match=(reg7 == 0 && ip4.dst 
> == 3.3.0.0/16), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = 1; 
> reg8[[16..31]] = select(values=(1, 2); hash_fields="ip_dst,ip_proto,ip_src");)
> +  table=??(lr_in_ip_routing   ), priority=1745 , match=(reg7 == 0 && ip4.dst 
> == 3.3.0.0/16 && sctp), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = 
> 1; reg8[[16..31]] = select(values=(1, 2); 
> hash_fields="ip_dst,ip_proto,ip_src,sctp_dst,sctp_src");)
> +  table=??(lr_in_ip_routing   ), priority=1745 , match=(reg7 == 0 && ip4.dst 
> == 3.3.0.0/16 && tcp), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = 
> 1; reg8[[16..31]] = select(values=(1, 2); 
> hash_fields="ip_dst,ip_proto,ip_src,tcp_dst,tcp_src");)
> +  table=??(lr_in_ip_routing   ), priority=1745 , match=(reg7 == 0 && ip4.dst 
> == 3.3.0.0/16 && udp), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = 
> 1; reg8[[16..31]] = select(values=(1, 2); 
> hash_fields="ip_dst,ip_proto,ip_src,udp_dst,udp_src");)
>   ])
>   
>   AT_CHECK([grep -e "lr_in_ecmp_stateful_egr" lr0flows | ovn_strip_lflows], 
> [0], [dnl
> @@ -7446,15 +7446,15 @@ ovn-sbctl dump-flows lr0 > lr0flows
>   AT_CHECK([grep -e "lr_in_ip_routing " lr0flows | ovn_strip_lflows], [0], 
> [dnl
>     table=??(lr_in_ip_routing   ), priority=0    , match=(1), action=(drop;)
>     table=??(lr_in_ip_routing   ), priority=10550, match=(nd_rs || nd_ra), 
> action=(drop;)
> -  table=??(lr_in_ip_routing   ), priority=196  , match=(reg7 == 0 && ip4.dst 
> == 10.0.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 192.168.0.10; 
> reg5 = 192.168.0.1; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=196  , match=(reg7 == 0 && ip4.dst 
> == 11.0.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 2001:db8::10; 
> xxreg1 = 2001:db8::1; eth.src = 00:00:20:20:12:14; outport = "lr0-private"; 
> flags.loopback = 1; reg9[[9]] = 0; next;)
> -  table=??(lr_in_ip_routing   ), priority=198  , match=(ip4.dst == 
> 192.168.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 192.168.0.1; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=516  , match=(reg7 == 0 && ip6.dst 
> == 2001:db8:1::/64), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 
> 192.168.0.20; reg5 = 192.168.0.1; eth.src = 00:00:20:20:12:13; outport = 
> "lr0-public"; flags.loopback = 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=516  , match=(reg7 == 0 && ip6.dst 
> == 2001:db8:2::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> 2001:db8::20; xxreg1 = 2001:db8::1; eth.src = 00:00:20:20:12:14; outport = 
> "lr0-private"; flags.loopback = 1; reg9[[9]] = 0; next;)
> -  table=??(lr_in_ip_routing   ), priority=516  , match=(reg7 == 0 && ip6.dst 
> == 2001:db8:3::/64), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 
> 192.168.1.10; reg5 = 192.168.0.1; eth.src = 00:00:20:20:12:13; outport = 
> "lr0-public"; flags.loopback = 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=518  , match=(inport == 
> "lr0-private" && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; 
> xxreg0 = ip6.dst; xxreg1 = fe80::200:20ff:fe20:1214; eth.src = 
> 00:00:20:20:12:14; outport = "lr0-private"; flags.loopback = 1; reg9[[9]] = 
> 0; next;)
> -  table=??(lr_in_ip_routing   ), priority=518  , match=(inport == 
> "lr0-public" && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; 
> xxreg0 = ip6.dst; xxreg1 = fe80::200:20ff:fe20:1213; eth.src = 
> 00:00:20:20:12:13; outport = "lr0-public"; flags.loopback = 1; reg9[[9]] = 0; 
> next;)
> -  table=??(lr_in_ip_routing   ), priority=518  , match=(ip6.dst == 
> 2001:db8::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = ip6.dst; xxreg1 
> = 2001:db8::1; eth.src = 00:00:20:20:12:14; outport = "lr0-private"; 
> flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=1840 , match=(reg7 == 0 && ip4.dst 
> == 10.0.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 192.168.0.10; 
> reg5 = 192.168.0.1; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1840 , match=(reg7 == 0 && ip4.dst 
> == 11.0.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 2001:db8::10; 
> xxreg1 = 2001:db8::1; eth.src = 00:00:20:20:12:14; outport = "lr0-private"; 
> flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=1842 , match=(ip4.dst == 
> 192.168.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 192.168.0.1; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=2320 , match=(reg7 == 0 && ip6.dst 
> == 2001:db8:1::/64), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 
> 192.168.0.20; reg5 = 192.168.0.1; eth.src = 00:00:20:20:12:13; outport = 
> "lr0-public"; flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=2320 , match=(reg7 == 0 && ip6.dst 
> == 2001:db8:2::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> 2001:db8::20; xxreg1 = 2001:db8::1; eth.src = 00:00:20:20:12:14; outport = 
> "lr0-private"; flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=2320 , match=(reg7 == 0 && ip6.dst 
> == 2001:db8:3::/64), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 
> 192.168.1.10; reg5 = 192.168.0.1; eth.src = 00:00:20:20:12:13; outport = 
> "lr0-public"; flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(inport == 
> "lr0-private" && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; 
> xxreg0 = ip6.dst; xxreg1 = fe80::200:20ff:fe20:1214; eth.src = 
> 00:00:20:20:12:14; outport = "lr0-private"; flags.loopback = 1; reg9[[9]] = 
> 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(inport == 
> "lr0-public" && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; 
> xxreg0 = ip6.dst; xxreg1 = fe80::200:20ff:fe20:1213; eth.src = 
> 00:00:20:20:12:13; outport = "lr0-public"; flags.loopback = 1; reg9[[9]] = 0; 
> next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(ip6.dst == 
> 2001:db8::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = ip6.dst; xxreg1 
> = 2001:db8::1; eth.src = 00:00:20:20:12:14; outport = "lr0-private"; 
> flags.loopback = 1; reg9[[9]] = 0; next;)
>   ])
>   
>   AT_CHECK([grep -e "lr_in_arp_resolve" lr0flows | ovn_strip_lflows], [0], 
> [dnl
> @@ -7970,16 +7970,16 @@ AT_CHECK([grep "lr_in_ip_routing_pre" lr0flows | 
> ovn_strip_lflows], [0], [dnl
>   grep -e "(lr_in_ip_routing   ).*outport" lr0flows
>   
>   AT_CHECK([grep -e "(lr_in_ip_routing   ).*outport" lr0flows | 
> ovn_strip_lflows], [0], [dnl
> -  table=??(lr_in_ip_routing   ), priority=196  , match=(reg7 == 1 && ip4.dst 
> == 192.168.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 192.168.1.10; 
> reg5 = 192.168.1.1; eth.src = 00:00:00:00:01:01; outport = "lrp1"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=198  , match=(ip4.dst == 
> 192.168.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 192.168.0.1; eth.src = 00:00:00:00:00:01; outport = "lrp0"; flags.loopback = 
> 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=198  , match=(ip4.dst == 
> 192.168.1.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 192.168.1.1; eth.src = 00:00:00:00:01:01; outport = "lrp1"; flags.loopback = 
> 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=198  , match=(ip4.dst == 
> 192.168.2.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 192.168.2.1; eth.src = 00:00:00:00:02:01; outport = "lrp2"; flags.loopback = 
> 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=260  , match=(reg7 == 2 && ip4.dst 
> == 1.1.1.1/32), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 192.168.0.20; 
> reg5 = 192.168.0.1; eth.src = 00:00:00:00:00:01; outport = "lrp0"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=4    , match=(reg7 == 0 && ip4.dst 
> == 0.0.0.0/0), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 192.168.0.10; reg5 
> = 192.168.0.1; eth.src = 00:00:00:00:00:01; outport = "lrp0"; flags.loopback 
> = 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=4    , match=(reg7 == 2 && ip4.dst 
> == 0.0.0.0/0), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 192.168.0.10; reg5 
> = 192.168.0.1; eth.src = 00:00:00:00:00:01; outport = "lrp0"; flags.loopback 
> = 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=518  , match=(inport == "lrp0" && 
> ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = ip6.dst; 
> xxreg1 = fe80::200:ff:fe00:1; eth.src = 00:00:00:00:00:01; outport = "lrp0"; 
> flags.loopback = 1; reg9[[9]] = 0; next;)
> -  table=??(lr_in_ip_routing   ), priority=518  , match=(inport == "lrp1" && 
> ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = ip6.dst; 
> xxreg1 = fe80::200:ff:fe00:101; eth.src = 00:00:00:00:01:01; outport = 
> "lrp1"; flags.loopback = 1; reg9[[9]] = 0; next;)
> -  table=??(lr_in_ip_routing   ), priority=518  , match=(inport == "lrp2" && 
> ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = ip6.dst; 
> xxreg1 = fe80::200:ff:fe00:201; eth.src = 00:00:00:00:02:01; outport = 
> "lrp2"; flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=1552 , match=(reg7 == 0 && ip4.dst 
> == 0.0.0.0/0), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 192.168.0.10; reg5 
> = 192.168.0.1; eth.src = 00:00:00:00:00:01; outport = "lrp0"; flags.loopback 
> = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1552 , match=(reg7 == 2 && ip4.dst 
> == 0.0.0.0/0), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 192.168.0.10; reg5 
> = 192.168.0.1; eth.src = 00:00:00:00:00:01; outport = "lrp0"; flags.loopback 
> = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1840 , match=(reg7 == 1 && ip4.dst 
> == 192.168.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 192.168.1.10; 
> reg5 = 192.168.1.1; eth.src = 00:00:00:00:01:01; outport = "lrp1"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1842 , match=(ip4.dst == 
> 192.168.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 192.168.0.1; eth.src = 00:00:00:00:00:01; outport = "lrp0"; flags.loopback = 
> 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1842 , match=(ip4.dst == 
> 192.168.1.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 192.168.1.1; eth.src = 00:00:00:00:01:01; outport = "lrp1"; flags.loopback = 
> 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1842 , match=(ip4.dst == 
> 192.168.2.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 192.168.2.1; eth.src = 00:00:00:00:02:01; outport = "lrp2"; flags.loopback = 
> 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1936 , match=(reg7 == 2 && ip4.dst 
> == 1.1.1.1/32), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 192.168.0.20; 
> reg5 = 192.168.0.1; eth.src = 00:00:00:00:00:01; outport = "lrp0"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(inport == "lrp0" && 
> ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = ip6.dst; 
> xxreg1 = fe80::200:ff:fe00:1; eth.src = 00:00:00:00:00:01; outport = "lrp0"; 
> flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(inport == "lrp1" && 
> ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = ip6.dst; 
> xxreg1 = fe80::200:ff:fe00:101; eth.src = 00:00:00:00:01:01; outport = 
> "lrp1"; flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(inport == "lrp2" && 
> ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = ip6.dst; 
> xxreg1 = fe80::200:ff:fe00:201; eth.src = 00:00:00:00:02:01; outport = 
> "lrp2"; flags.loopback = 1; reg9[[9]] = 0; next;)
>   ])
>   
>   OVN_CLEANUP_NORTHD
> @@ -15879,12 +15879,12 @@ ovn-sbctl dump-flows lr0 > lr0flows
>   AT_CHECK([grep -w "lr_in_ip_routing" lr0flows | ovn_strip_lflows], [0], [dnl
>     table=??(lr_in_ip_routing   ), priority=0    , match=(1), action=(drop;)
>     table=??(lr_in_ip_routing   ), priority=10550, match=(nd_rs || nd_ra), 
> action=(drop;)
> -  table=??(lr_in_ip_routing   ), priority=196  , match=(reg7 == 0 && ip4.dst 
> == 192.168.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 10.0.0.10; 
> reg5 = 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=198  , match=(ip4.dst == 
> 10.0.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; flags.loopback = 
> 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=516  , match=(reg7 == 0 && ip6.dst 
> == 2001:db8:1::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> 2001:db8::10; xxreg1 = 2001:db8::1; eth.src = 00:00:00:00:ff:02; outport = 
> "lr0-sw1"; flags.loopback = 1; reg9[[9]] = 0; next;)
> -  table=??(lr_in_ip_routing   ), priority=518  , match=(inport == "lr0-sw0" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::200:ff:fe00:ff01; eth.src = 00:00:00:00:ff:01; 
> outport = "lr0-sw0"; flags.loopback = 1; reg9[[9]] = 0; next;)
> -  table=??(lr_in_ip_routing   ), priority=518  , match=(inport == "lr0-sw1" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::200:ff:fe00:ff02; eth.src = 00:00:00:00:ff:02; 
> outport = "lr0-sw1"; flags.loopback = 1; reg9[[9]] = 0; next;)
> -  table=??(lr_in_ip_routing   ), priority=518  , match=(ip6.dst == 
> 2001:db8::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = ip6.dst; xxreg1 
> = 2001:db8::1; eth.src = 00:00:00:00:ff:02; outport = "lr0-sw1"; 
> flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=1840 , match=(reg7 == 0 && ip4.dst 
> == 192.168.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 10.0.0.10; 
> reg5 = 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1842 , match=(ip4.dst == 
> 10.0.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; flags.loopback = 
> 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=2320 , match=(reg7 == 0 && ip6.dst 
> == 2001:db8:1::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> 2001:db8::10; xxreg1 = 2001:db8::1; eth.src = 00:00:00:00:ff:02; outport = 
> "lr0-sw1"; flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(inport == "lr0-sw0" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::200:ff:fe00:ff01; eth.src = 00:00:00:00:ff:01; 
> outport = "lr0-sw0"; flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(inport == "lr0-sw1" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::200:ff:fe00:ff02; eth.src = 00:00:00:00:ff:02; 
> outport = "lr0-sw1"; flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(ip6.dst == 
> 2001:db8::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = ip6.dst; xxreg1 
> = 2001:db8::1; eth.src = 00:00:00:00:ff:02; outport = "lr0-sw1"; 
> flags.loopback = 1; reg9[[9]] = 0; next;)
>   ])
>   
>   # Learn a route to 172.16.0.0/24 via 10.0.0.11 learned on lr0-sw0.
> @@ -15900,13 +15900,13 @@ ovn-sbctl dump-flows lr0 > lr0flows
>   AT_CHECK([grep -w "lr_in_ip_routing" lr0flows | ovn_strip_lflows], [0], [dnl
>     table=??(lr_in_ip_routing   ), priority=0    , match=(1), action=(drop;)
>     table=??(lr_in_ip_routing   ), priority=10550, match=(nd_rs || nd_ra), 
> action=(drop;)
> -  table=??(lr_in_ip_routing   ), priority=194  , match=(reg7 == 0 && ip4.dst 
> == 172.16.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 10.0.0.11; 
> reg5 = 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=196  , match=(reg7 == 0 && ip4.dst 
> == 192.168.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 10.0.0.10; 
> reg5 = 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=198  , match=(ip4.dst == 
> 10.0.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; flags.loopback = 
> 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=516  , match=(reg7 == 0 && ip6.dst 
> == 2001:db8:1::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> 2001:db8::10; xxreg1 = 2001:db8::1; eth.src = 00:00:00:00:ff:02; outport = 
> "lr0-sw1"; flags.loopback = 1; reg9[[9]] = 0; next;)
> -  table=??(lr_in_ip_routing   ), priority=518  , match=(inport == "lr0-sw0" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::200:ff:fe00:ff01; eth.src = 00:00:00:00:ff:01; 
> outport = "lr0-sw0"; flags.loopback = 1; reg9[[9]] = 0; next;)
> -  table=??(lr_in_ip_routing   ), priority=518  , match=(inport == "lr0-sw1" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::200:ff:fe00:ff02; eth.src = 00:00:00:00:ff:02; 
> outport = "lr0-sw1"; flags.loopback = 1; reg9[[9]] = 0; next;)
> -  table=??(lr_in_ip_routing   ), priority=518  , match=(ip6.dst == 
> 2001:db8::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = ip6.dst; xxreg1 
> = 2001:db8::1; eth.src = 00:00:00:00:ff:02; outport = "lr0-sw1"; 
> flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=1838 , match=(reg7 == 0 && ip4.dst 
> == 172.16.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 10.0.0.11; 
> reg5 = 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1840 , match=(reg7 == 0 && ip4.dst 
> == 192.168.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 10.0.0.10; 
> reg5 = 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1842 , match=(ip4.dst == 
> 10.0.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; flags.loopback = 
> 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=2320 , match=(reg7 == 0 && ip6.dst 
> == 2001:db8:1::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> 2001:db8::10; xxreg1 = 2001:db8::1; eth.src = 00:00:00:00:ff:02; outport = 
> "lr0-sw1"; flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(inport == "lr0-sw0" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::200:ff:fe00:ff01; eth.src = 00:00:00:00:ff:01; 
> outport = "lr0-sw0"; flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(inport == "lr0-sw1" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::200:ff:fe00:ff02; eth.src = 00:00:00:00:ff:02; 
> outport = "lr0-sw1"; flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(ip6.dst == 
> 2001:db8::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = ip6.dst; xxreg1 
> = 2001:db8::1; eth.src = 00:00:00:00:ff:02; outport = "lr0-sw1"; 
> flags.loopback = 1; reg9[[9]] = 0; next;)
>   ])
>   
>   # Learn a route to 2001:db8:2::/64 via 2001:db8:ffff::20 learned on lr0-sw1.
> @@ -15923,14 +15923,14 @@ ovn-sbctl dump-flows lr0 > lr0flows
>   AT_CHECK([grep -w "lr_in_ip_routing" lr0flows | ovn_strip_lflows], [0], [dnl
>     table=??(lr_in_ip_routing   ), priority=0    , match=(1), action=(drop;)
>     table=??(lr_in_ip_routing   ), priority=10550, match=(nd_rs || nd_ra), 
> action=(drop;)
> -  table=??(lr_in_ip_routing   ), priority=194  , match=(reg7 == 0 && ip4.dst 
> == 172.16.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 10.0.0.11; 
> reg5 = 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=196  , match=(reg7 == 0 && ip4.dst 
> == 192.168.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 10.0.0.10; 
> reg5 = 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=198  , match=(ip4.dst == 
> 10.0.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; flags.loopback = 
> 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=514  , match=(reg7 == 0 && ip6.dst 
> == 2001:db8:2::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> 2001:db8:ffff::20; xxreg1 = 2001:db8::1; eth.src = 00:00:00:00:ff:02; outport 
> = "lr0-sw1"; flags.loopback = 1; reg9[[9]] = 0; next;)
> -  table=??(lr_in_ip_routing   ), priority=516  , match=(reg7 == 0 && ip6.dst 
> == 2001:db8:1::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> 2001:db8::10; xxreg1 = 2001:db8::1; eth.src = 00:00:00:00:ff:02; outport = 
> "lr0-sw1"; flags.loopback = 1; reg9[[9]] = 0; next;)
> -  table=??(lr_in_ip_routing   ), priority=518  , match=(inport == "lr0-sw0" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::200:ff:fe00:ff01; eth.src = 00:00:00:00:ff:01; 
> outport = "lr0-sw0"; flags.loopback = 1; reg9[[9]] = 0; next;)
> -  table=??(lr_in_ip_routing   ), priority=518  , match=(inport == "lr0-sw1" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::200:ff:fe00:ff02; eth.src = 00:00:00:00:ff:02; 
> outport = "lr0-sw1"; flags.loopback = 1; reg9[[9]] = 0; next;)
> -  table=??(lr_in_ip_routing   ), priority=518  , match=(ip6.dst == 
> 2001:db8::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = ip6.dst; xxreg1 
> = 2001:db8::1; eth.src = 00:00:00:00:ff:02; outport = "lr0-sw1"; 
> flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=1838 , match=(reg7 == 0 && ip4.dst 
> == 172.16.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 10.0.0.11; 
> reg5 = 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1840 , match=(reg7 == 0 && ip4.dst 
> == 192.168.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 10.0.0.10; 
> reg5 = 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1842 , match=(ip4.dst == 
> 10.0.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; flags.loopback = 
> 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=2318 , match=(reg7 == 0 && ip6.dst 
> == 2001:db8:2::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> 2001:db8:ffff::20; xxreg1 = 2001:db8::1; eth.src = 00:00:00:00:ff:02; outport 
> = "lr0-sw1"; flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=2320 , match=(reg7 == 0 && ip6.dst 
> == 2001:db8:1::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> 2001:db8::10; xxreg1 = 2001:db8::1; eth.src = 00:00:00:00:ff:02; outport = 
> "lr0-sw1"; flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(inport == "lr0-sw0" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::200:ff:fe00:ff01; eth.src = 00:00:00:00:ff:01; 
> outport = "lr0-sw0"; flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(inport == "lr0-sw1" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::200:ff:fe00:ff02; eth.src = 00:00:00:00:ff:02; 
> outport = "lr0-sw1"; flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(ip6.dst == 
> 2001:db8::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = ip6.dst; xxreg1 
> = 2001:db8::1; eth.src = 00:00:00:00:ff:02; outport = "lr0-sw1"; 
> flags.loopback = 1; reg9[[9]] = 0; next;)
>   ])
>   
>   # If we now add 2001:db8:ffff::1/64 as an additional network to lr0-sw1 we
> @@ -15944,15 +15944,15 @@ ovn-sbctl dump-flows lr0 > lr0flows
>   AT_CHECK([grep -w "lr_in_ip_routing" lr0flows | ovn_strip_lflows], [0], [dnl
>     table=??(lr_in_ip_routing   ), priority=0    , match=(1), action=(drop;)
>     table=??(lr_in_ip_routing   ), priority=10550, match=(nd_rs || nd_ra), 
> action=(drop;)
> -  table=??(lr_in_ip_routing   ), priority=194  , match=(reg7 == 0 && ip4.dst 
> == 172.16.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 10.0.0.11; 
> reg5 = 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=196  , match=(reg7 == 0 && ip4.dst 
> == 192.168.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 10.0.0.10; 
> reg5 = 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=198  , match=(ip4.dst == 
> 10.0.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; flags.loopback = 
> 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=514  , match=(reg7 == 0 && ip6.dst 
> == 2001:db8:2::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> 2001:db8:ffff::20; xxreg1 = 2001:db8:ffff::1; eth.src = 00:00:00:00:ff:02; 
> outport = "lr0-sw1"; flags.loopback = 1; reg9[[9]] = 0; next;)
> -  table=??(lr_in_ip_routing   ), priority=516  , match=(reg7 == 0 && ip6.dst 
> == 2001:db8:1::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> 2001:db8::10; xxreg1 = 2001:db8::1; eth.src = 00:00:00:00:ff:02; outport = 
> "lr0-sw1"; flags.loopback = 1; reg9[[9]] = 0; next;)
> -  table=??(lr_in_ip_routing   ), priority=518  , match=(inport == "lr0-sw0" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::200:ff:fe00:ff01; eth.src = 00:00:00:00:ff:01; 
> outport = "lr0-sw0"; flags.loopback = 1; reg9[[9]] = 0; next;)
> -  table=??(lr_in_ip_routing   ), priority=518  , match=(inport == "lr0-sw1" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::200:ff:fe00:ff02; eth.src = 00:00:00:00:ff:02; 
> outport = "lr0-sw1"; flags.loopback = 1; reg9[[9]] = 0; next;)
> -  table=??(lr_in_ip_routing   ), priority=518  , match=(ip6.dst == 
> 2001:db8::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = ip6.dst; xxreg1 
> = 2001:db8::1; eth.src = 00:00:00:00:ff:02; outport = "lr0-sw1"; 
> flags.loopback = 1; reg9[[9]] = 0; next;)
> -  table=??(lr_in_ip_routing   ), priority=518  , match=(ip6.dst == 
> 2001:db8:ffff::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = ip6.dst; 
> xxreg1 = 2001:db8:ffff::1; eth.src = 00:00:00:00:ff:02; outport = "lr0-sw1"; 
> flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=1838 , match=(reg7 == 0 && ip4.dst 
> == 172.16.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 10.0.0.11; 
> reg5 = 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1840 , match=(reg7 == 0 && ip4.dst 
> == 192.168.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 10.0.0.10; 
> reg5 = 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1842 , match=(ip4.dst == 
> 10.0.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; flags.loopback = 
> 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=2318 , match=(reg7 == 0 && ip6.dst 
> == 2001:db8:2::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> 2001:db8:ffff::20; xxreg1 = 2001:db8:ffff::1; eth.src = 00:00:00:00:ff:02; 
> outport = "lr0-sw1"; flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=2320 , match=(reg7 == 0 && ip6.dst 
> == 2001:db8:1::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> 2001:db8::10; xxreg1 = 2001:db8::1; eth.src = 00:00:00:00:ff:02; outport = 
> "lr0-sw1"; flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(inport == "lr0-sw0" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::200:ff:fe00:ff01; eth.src = 00:00:00:00:ff:01; 
> outport = "lr0-sw0"; flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(inport == "lr0-sw1" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::200:ff:fe00:ff02; eth.src = 00:00:00:00:ff:02; 
> outport = "lr0-sw1"; flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(ip6.dst == 
> 2001:db8::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = ip6.dst; xxreg1 
> = 2001:db8::1; eth.src = 00:00:00:00:ff:02; outport = "lr0-sw1"; 
> flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(ip6.dst == 
> 2001:db8:ffff::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = ip6.dst; 
> xxreg1 = 2001:db8:ffff::1; eth.src = 00:00:00:00:ff:02; outport = "lr0-sw1"; 
> flags.loopback = 1; reg9[[9]] = 0; next;)
>   ])
>   
>   # Learn a route to 2001:db8:3::/64 via 10.0.0.20 learned on lr0-sw0.
> @@ -15968,16 +15968,16 @@ ovn-sbctl dump-flows lr0 > lr0flows
>   AT_CHECK([grep -w "lr_in_ip_routing" lr0flows | ovn_strip_lflows], [0], [dnl
>     table=??(lr_in_ip_routing   ), priority=0    , match=(1), action=(drop;)
>     table=??(lr_in_ip_routing   ), priority=10550, match=(nd_rs || nd_ra), 
> action=(drop;)
> -  table=??(lr_in_ip_routing   ), priority=194  , match=(reg7 == 0 && ip4.dst 
> == 172.16.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 10.0.0.11; 
> reg5 = 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=196  , match=(reg7 == 0 && ip4.dst 
> == 192.168.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 10.0.0.10; 
> reg5 = 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=198  , match=(ip4.dst == 
> 10.0.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; flags.loopback = 
> 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=514  , match=(reg7 == 0 && ip6.dst 
> == 2001:db8:2::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> 2001:db8:ffff::20; xxreg1 = 2001:db8:ffff::1; eth.src = 00:00:00:00:ff:02; 
> outport = "lr0-sw1"; flags.loopback = 1; reg9[[9]] = 0; next;)
> -  table=??(lr_in_ip_routing   ), priority=514  , match=(reg7 == 0 && ip6.dst 
> == 2001:db8:3::/64), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 10.0.0.20; 
> reg5 = 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=516  , match=(reg7 == 0 && ip6.dst 
> == 2001:db8:1::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> 2001:db8::10; xxreg1 = 2001:db8::1; eth.src = 00:00:00:00:ff:02; outport = 
> "lr0-sw1"; flags.loopback = 1; reg9[[9]] = 0; next;)
> -  table=??(lr_in_ip_routing   ), priority=518  , match=(inport == "lr0-sw0" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::200:ff:fe00:ff01; eth.src = 00:00:00:00:ff:01; 
> outport = "lr0-sw0"; flags.loopback = 1; reg9[[9]] = 0; next;)
> -  table=??(lr_in_ip_routing   ), priority=518  , match=(inport == "lr0-sw1" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::200:ff:fe00:ff02; eth.src = 00:00:00:00:ff:02; 
> outport = "lr0-sw1"; flags.loopback = 1; reg9[[9]] = 0; next;)
> -  table=??(lr_in_ip_routing   ), priority=518  , match=(ip6.dst == 
> 2001:db8::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = ip6.dst; xxreg1 
> = 2001:db8::1; eth.src = 00:00:00:00:ff:02; outport = "lr0-sw1"; 
> flags.loopback = 1; reg9[[9]] = 0; next;)
> -  table=??(lr_in_ip_routing   ), priority=518  , match=(ip6.dst == 
> 2001:db8:ffff::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = ip6.dst; 
> xxreg1 = 2001:db8:ffff::1; eth.src = 00:00:00:00:ff:02; outport = "lr0-sw1"; 
> flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=1838 , match=(reg7 == 0 && ip4.dst 
> == 172.16.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 10.0.0.11; 
> reg5 = 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1840 , match=(reg7 == 0 && ip4.dst 
> == 192.168.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 10.0.0.10; 
> reg5 = 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1842 , match=(ip4.dst == 
> 10.0.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; flags.loopback = 
> 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=2318 , match=(reg7 == 0 && ip6.dst 
> == 2001:db8:2::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> 2001:db8:ffff::20; xxreg1 = 2001:db8:ffff::1; eth.src = 00:00:00:00:ff:02; 
> outport = "lr0-sw1"; flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=2318 , match=(reg7 == 0 && ip6.dst 
> == 2001:db8:3::/64), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 10.0.0.20; 
> reg5 = 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=2320 , match=(reg7 == 0 && ip6.dst 
> == 2001:db8:1::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> 2001:db8::10; xxreg1 = 2001:db8::1; eth.src = 00:00:00:00:ff:02; outport = 
> "lr0-sw1"; flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(inport == "lr0-sw0" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::200:ff:fe00:ff01; eth.src = 00:00:00:00:ff:01; 
> outport = "lr0-sw0"; flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(inport == "lr0-sw1" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::200:ff:fe00:ff02; eth.src = 00:00:00:00:ff:02; 
> outport = "lr0-sw1"; flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(ip6.dst == 
> 2001:db8::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = ip6.dst; xxreg1 
> = 2001:db8::1; eth.src = 00:00:00:00:ff:02; outport = "lr0-sw1"; 
> flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(ip6.dst == 
> 2001:db8:ffff::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = ip6.dst; 
> xxreg1 = 2001:db8:ffff::1; eth.src = 00:00:00:00:ff:02; outport = "lr0-sw1"; 
> flags.loopback = 1; reg9[[9]] = 0; next;)
>   ])
>   
>   # Learn a route to 172.16.1.0/24 via 2001:db8:ffff::30 learned on lr0-sw1.
> @@ -15993,17 +15993,17 @@ ovn-sbctl dump-flows lr0 > lr0flows
>   AT_CHECK([grep -w "lr_in_ip_routing" lr0flows | ovn_strip_lflows], [0], [dnl
>     table=??(lr_in_ip_routing   ), priority=0    , match=(1), action=(drop;)
>     table=??(lr_in_ip_routing   ), priority=10550, match=(nd_rs || nd_ra), 
> action=(drop;)
> -  table=??(lr_in_ip_routing   ), priority=194  , match=(reg7 == 0 && ip4.dst 
> == 172.16.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 10.0.0.11; 
> reg5 = 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=194  , match=(reg7 == 0 && ip4.dst 
> == 172.16.1.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> 2001:db8:ffff::30; xxreg1 = 2001:db8:ffff::1; eth.src = 00:00:00:00:ff:02; 
> outport = "lr0-sw1"; flags.loopback = 1; reg9[[9]] = 0; next;)
> -  table=??(lr_in_ip_routing   ), priority=196  , match=(reg7 == 0 && ip4.dst 
> == 192.168.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 10.0.0.10; 
> reg5 = 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=198  , match=(ip4.dst == 
> 10.0.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; flags.loopback = 
> 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=514  , match=(reg7 == 0 && ip6.dst 
> == 2001:db8:2::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> 2001:db8:ffff::20; xxreg1 = 2001:db8:ffff::1; eth.src = 00:00:00:00:ff:02; 
> outport = "lr0-sw1"; flags.loopback = 1; reg9[[9]] = 0; next;)
> -  table=??(lr_in_ip_routing   ), priority=514  , match=(reg7 == 0 && ip6.dst 
> == 2001:db8:3::/64), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 10.0.0.20; 
> reg5 = 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=516  , match=(reg7 == 0 && ip6.dst 
> == 2001:db8:1::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> 2001:db8::10; xxreg1 = 2001:db8::1; eth.src = 00:00:00:00:ff:02; outport = 
> "lr0-sw1"; flags.loopback = 1; reg9[[9]] = 0; next;)
> -  table=??(lr_in_ip_routing   ), priority=518  , match=(inport == "lr0-sw0" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::200:ff:fe00:ff01; eth.src = 00:00:00:00:ff:01; 
> outport = "lr0-sw0"; flags.loopback = 1; reg9[[9]] = 0; next;)
> -  table=??(lr_in_ip_routing   ), priority=518  , match=(inport == "lr0-sw1" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::200:ff:fe00:ff02; eth.src = 00:00:00:00:ff:02; 
> outport = "lr0-sw1"; flags.loopback = 1; reg9[[9]] = 0; next;)
> -  table=??(lr_in_ip_routing   ), priority=518  , match=(ip6.dst == 
> 2001:db8::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = ip6.dst; xxreg1 
> = 2001:db8::1; eth.src = 00:00:00:00:ff:02; outport = "lr0-sw1"; 
> flags.loopback = 1; reg9[[9]] = 0; next;)
> -  table=??(lr_in_ip_routing   ), priority=518  , match=(ip6.dst == 
> 2001:db8:ffff::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = ip6.dst; 
> xxreg1 = 2001:db8:ffff::1; eth.src = 00:00:00:00:ff:02; outport = "lr0-sw1"; 
> flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=1838 , match=(reg7 == 0 && ip4.dst 
> == 172.16.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 10.0.0.11; 
> reg5 = 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1838 , match=(reg7 == 0 && ip4.dst 
> == 172.16.1.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> 2001:db8:ffff::30; xxreg1 = 2001:db8:ffff::1; eth.src = 00:00:00:00:ff:02; 
> outport = "lr0-sw1"; flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=1840 , match=(reg7 == 0 && ip4.dst 
> == 192.168.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 10.0.0.10; 
> reg5 = 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1842 , match=(ip4.dst == 
> 10.0.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; flags.loopback = 
> 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=2318 , match=(reg7 == 0 && ip6.dst 
> == 2001:db8:2::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> 2001:db8:ffff::20; xxreg1 = 2001:db8:ffff::1; eth.src = 00:00:00:00:ff:02; 
> outport = "lr0-sw1"; flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=2318 , match=(reg7 == 0 && ip6.dst 
> == 2001:db8:3::/64), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 10.0.0.20; 
> reg5 = 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=2320 , match=(reg7 == 0 && ip6.dst 
> == 2001:db8:1::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> 2001:db8::10; xxreg1 = 2001:db8::1; eth.src = 00:00:00:00:ff:02; outport = 
> "lr0-sw1"; flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(inport == "lr0-sw0" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::200:ff:fe00:ff01; eth.src = 00:00:00:00:ff:01; 
> outport = "lr0-sw0"; flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(inport == "lr0-sw1" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::200:ff:fe00:ff02; eth.src = 00:00:00:00:ff:02; 
> outport = "lr0-sw1"; flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(ip6.dst == 
> 2001:db8::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = ip6.dst; xxreg1 
> = 2001:db8::1; eth.src = 00:00:00:00:ff:02; outport = "lr0-sw1"; 
> flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(ip6.dst == 
> 2001:db8:ffff::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = ip6.dst; 
> xxreg1 = 2001:db8:ffff::1; eth.src = 00:00:00:00:ff:02; outport = "lr0-sw1"; 
> flags.loopback = 1; reg9[[9]] = 0; next;)
>   ])
>   
>   # Deleting lr0-sw1 will remove the flows and also the learned route.
> @@ -16015,11 +16015,11 @@ ovn-sbctl dump-flows lr0 > lr0flows
>   AT_CHECK([grep -w "lr_in_ip_routing" lr0flows | ovn_strip_lflows], [0], [dnl
>     table=??(lr_in_ip_routing   ), priority=0    , match=(1), action=(drop;)
>     table=??(lr_in_ip_routing   ), priority=10550, match=(nd_rs || nd_ra), 
> action=(drop;)
> -  table=??(lr_in_ip_routing   ), priority=194  , match=(reg7 == 0 && ip4.dst 
> == 172.16.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 10.0.0.11; 
> reg5 = 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=196  , match=(reg7 == 0 && ip4.dst 
> == 192.168.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 10.0.0.10; 
> reg5 = 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=198  , match=(ip4.dst == 
> 10.0.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; flags.loopback = 
> 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=514  , match=(reg7 == 0 && ip6.dst 
> == 2001:db8:3::/64), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 10.0.0.20; 
> reg5 = 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=518  , match=(inport == "lr0-sw0" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::200:ff:fe00:ff01; eth.src = 00:00:00:00:ff:01; 
> outport = "lr0-sw0"; flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=1838 , match=(reg7 == 0 && ip4.dst 
> == 172.16.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 10.0.0.11; 
> reg5 = 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1840 , match=(reg7 == 0 && ip4.dst 
> == 192.168.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 10.0.0.10; 
> reg5 = 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1842 , match=(ip4.dst == 
> 10.0.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; flags.loopback = 
> 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=2318 , match=(reg7 == 0 && ip6.dst 
> == 2001:db8:3::/64), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 10.0.0.20; 
> reg5 = 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(inport == "lr0-sw0" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::200:ff:fe00:ff01; eth.src = 00:00:00:00:ff:01; 
> outport = "lr0-sw0"; flags.loopback = 1; reg9[[9]] = 0; next;)
>   ])
>   
>   OVN_CLEANUP_NORTHD
> @@ -16049,11 +16049,11 @@ ovn-sbctl dump-flows lr0 > lr0flows
>   AT_CHECK([grep -w "lr_in_ip_routing" lr0flows | ovn_strip_lflows], [0], [dnl
>     table=??(lr_in_ip_routing   ), priority=0    , match=(1), action=(drop;)
>     table=??(lr_in_ip_routing   ), priority=10550, match=(nd_rs || nd_ra), 
> action=(drop;)
> -  table=??(lr_in_ip_routing   ), priority=196  , match=(reg7 == 0 && ip4.dst 
> == 192.168.0.0/24), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = 1; 
> reg8[[16..31]] = select(1, 2);)
> -  table=??(lr_in_ip_routing   ), priority=198  , match=(ip4.dst == 
> 10.0.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; flags.loopback = 
> 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=198  , match=(ip4.dst == 
> 10.0.1.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 10.0.1.1; eth.src = 00:00:00:00:ff:02; outport = "lr0-sw1"; flags.loopback = 
> 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=518  , match=(inport == "lr0-sw0" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::200:ff:fe00:ff01; eth.src = 00:00:00:00:ff:01; 
> outport = "lr0-sw0"; flags.loopback = 1; reg9[[9]] = 0; next;)
> -  table=??(lr_in_ip_routing   ), priority=518  , match=(inport == "lr0-sw1" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::200:ff:fe00:ff02; eth.src = 00:00:00:00:ff:02; 
> outport = "lr0-sw1"; flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=1840 , match=(reg7 == 0 && ip4.dst 
> == 192.168.0.0/24), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = 1; 
> reg8[[16..31]] = select(1, 2);)
> +  table=??(lr_in_ip_routing   ), priority=1842 , match=(ip4.dst == 
> 10.0.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; flags.loopback = 
> 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1842 , match=(ip4.dst == 
> 10.0.1.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 10.0.1.1; eth.src = 00:00:00:00:ff:02; outport = "lr0-sw1"; flags.loopback = 
> 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(inport == "lr0-sw0" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::200:ff:fe00:ff01; eth.src = 00:00:00:00:ff:01; 
> outport = "lr0-sw0"; flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(inport == "lr0-sw1" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::200:ff:fe00:ff02; eth.src = 00:00:00:00:ff:02; 
> outport = "lr0-sw1"; flags.loopback = 1; reg9[[9]] = 0; next;)
>   ])
>   AT_CHECK([grep -e "lr_in_ip_routing_ecmp" lr0flows | sed -e 
> 's/10\.0\..\./10.0.??./g' -e 's/lr0-sw./lr0-sw??/' -e 's/00:ff:0./00:ff:0?/' 
> | ovn_strip_lflows], [0], [dnl
>     table=??(lr_in_ip_routing_ecmp), priority=0    , match=(1), action=(drop;)
> @@ -16075,12 +16075,12 @@ ovn-sbctl dump-flows lr0 > lr0flows
>   AT_CHECK([grep -w "lr_in_ip_routing" lr0flows | ovn_strip_lflows], [0], [dnl
>     table=??(lr_in_ip_routing   ), priority=0    , match=(1), action=(drop;)
>     table=??(lr_in_ip_routing   ), priority=10550, match=(nd_rs || nd_ra), 
> action=(drop;)
> -  table=??(lr_in_ip_routing   ), priority=194  , match=(reg7 == 0 && ip4.dst 
> == 192.168.1.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 10.0.0.20; 
> reg5 = 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=196  , match=(reg7 == 0 && ip4.dst 
> == 192.168.0.0/24), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = 1; 
> reg8[[16..31]] = select(1, 2);)
> -  table=??(lr_in_ip_routing   ), priority=198  , match=(ip4.dst == 
> 10.0.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; flags.loopback = 
> 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=198  , match=(ip4.dst == 
> 10.0.1.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 10.0.1.1; eth.src = 00:00:00:00:ff:02; outport = "lr0-sw1"; flags.loopback = 
> 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=518  , match=(inport == "lr0-sw0" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::200:ff:fe00:ff01; eth.src = 00:00:00:00:ff:01; 
> outport = "lr0-sw0"; flags.loopback = 1; reg9[[9]] = 0; next;)
> -  table=??(lr_in_ip_routing   ), priority=518  , match=(inport == "lr0-sw1" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::200:ff:fe00:ff02; eth.src = 00:00:00:00:ff:02; 
> outport = "lr0-sw1"; flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=1838 , match=(reg7 == 0 && ip4.dst 
> == 192.168.1.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 10.0.0.20; 
> reg5 = 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; 
> flags.loopback = 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1840 , match=(reg7 == 0 && ip4.dst 
> == 192.168.0.0/24), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = 1; 
> reg8[[16..31]] = select(1, 2);)
> +  table=??(lr_in_ip_routing   ), priority=1842 , match=(ip4.dst == 
> 10.0.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; flags.loopback = 
> 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1842 , match=(ip4.dst == 
> 10.0.1.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 10.0.1.1; eth.src = 00:00:00:00:ff:02; outport = "lr0-sw1"; flags.loopback = 
> 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(inport == "lr0-sw0" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::200:ff:fe00:ff01; eth.src = 00:00:00:00:ff:01; 
> outport = "lr0-sw0"; flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(inport == "lr0-sw1" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::200:ff:fe00:ff02; eth.src = 00:00:00:00:ff:02; 
> outport = "lr0-sw1"; flags.loopback = 1; reg9[[9]] = 0; next;)
>   ])
>   AT_CHECK([grep -e "lr_in_ip_routing_ecmp" lr0flows | sed -e 
> 's/10\.0\..\./10.0.??./g' -e 's/lr0-sw./lr0-sw??/' -e 's/00:ff:0./00:ff:0?/' 
> | ovn_strip_lflows], [0], [dnl
>     table=??(lr_in_ip_routing_ecmp), priority=0    , match=(1), action=(drop;)
> @@ -16103,12 +16103,12 @@ ovn-sbctl dump-flows lr0 > lr0flows
>   AT_CHECK([grep -w "lr_in_ip_routing" lr0flows | ovn_strip_lflows], [0], [dnl
>     table=??(lr_in_ip_routing   ), priority=0    , match=(1), action=(drop;)
>     table=??(lr_in_ip_routing   ), priority=10550, match=(nd_rs || nd_ra), 
> action=(drop;)
> -  table=??(lr_in_ip_routing   ), priority=194  , match=(reg7 == 0 && ip4.dst 
> == 192.168.1.0/24), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = 2; 
> reg8[[16..31]] = select(1, 2);)
> -  table=??(lr_in_ip_routing   ), priority=196  , match=(reg7 == 0 && ip4.dst 
> == 192.168.0.0/24), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = 1; 
> reg8[[16..31]] = select(1, 2);)
> -  table=??(lr_in_ip_routing   ), priority=198  , match=(ip4.dst == 
> 10.0.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; flags.loopback = 
> 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=198  , match=(ip4.dst == 
> 10.0.1.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 10.0.1.1; eth.src = 00:00:00:00:ff:02; outport = "lr0-sw1"; flags.loopback = 
> 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=518  , match=(inport == "lr0-sw0" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::200:ff:fe00:ff01; eth.src = 00:00:00:00:ff:01; 
> outport = "lr0-sw0"; flags.loopback = 1; reg9[[9]] = 0; next;)
> -  table=??(lr_in_ip_routing   ), priority=518  , match=(inport == "lr0-sw1" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::200:ff:fe00:ff02; eth.src = 00:00:00:00:ff:02; 
> outport = "lr0-sw1"; flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=1838 , match=(reg7 == 0 && ip4.dst 
> == 192.168.1.0/24), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = 2; 
> reg8[[16..31]] = select(1, 2);)
> +  table=??(lr_in_ip_routing   ), priority=1840 , match=(reg7 == 0 && ip4.dst 
> == 192.168.0.0/24), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = 1; 
> reg8[[16..31]] = select(1, 2);)
> +  table=??(lr_in_ip_routing   ), priority=1842 , match=(ip4.dst == 
> 10.0.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; flags.loopback = 
> 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1842 , match=(ip4.dst == 
> 10.0.1.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 10.0.1.1; eth.src = 00:00:00:00:ff:02; outport = "lr0-sw1"; flags.loopback = 
> 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(inport == "lr0-sw0" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::200:ff:fe00:ff01; eth.src = 00:00:00:00:ff:01; 
> outport = "lr0-sw0"; flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(inport == "lr0-sw1" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::200:ff:fe00:ff02; eth.src = 00:00:00:00:ff:02; 
> outport = "lr0-sw1"; flags.loopback = 1; reg9[[9]] = 0; next;)
>   ])
>   AT_CHECK([grep -e "lr_in_ip_routing_ecmp" lr0flows | sed -e 
> 's/10\.0\..\./10.0.??./g' -e 's/lr0-sw./lr0-sw??/' -e 's/00:ff:0./00:ff:0?/' 
> | ovn_strip_lflows], [0], [dnl
>     table=??(lr_in_ip_routing_ecmp), priority=0    , match=(1), action=(drop;)
> @@ -16145,13 +16145,13 @@ ovn-sbctl dump-flows lr0 > lr0flows
>   AT_CHECK([grep -w "lr_in_ip_routing" lr0flows | sed -e 's/reg8\[[0..15\]] = 
> [[123]]/reg8\[[0..15\]] = ??/' | ovn_strip_lflows], [0], [dnl
>     table=??(lr_in_ip_routing   ), priority=0    , match=(1), action=(drop;)
>     table=??(lr_in_ip_routing   ), priority=10550, match=(nd_rs || nd_ra), 
> action=(drop;)
> -  table=??(lr_in_ip_routing   ), priority=194  , match=(reg7 == 0 && ip4.dst 
> == 192.168.0.0/24), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = ??; 
> reg8[[16..31]] = select(1, 2);)
> -  table=??(lr_in_ip_routing   ), priority=194  , match=(reg7 == 0 && ip4.dst 
> == 192.168.1.0/24), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = ??; 
> reg8[[16..31]] = select(1, 2);)
> -  table=??(lr_in_ip_routing   ), priority=196  , match=(reg7 == 0 && ip4.dst 
> == 192.168.0.0/24), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = ??; 
> reg8[[16..31]] = select(1, 2);)
> -  table=??(lr_in_ip_routing   ), priority=198  , match=(ip4.dst == 
> 10.0.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; flags.loopback = 
> 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=198  , match=(ip4.dst == 
> 10.0.1.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 10.0.1.1; eth.src = 00:00:00:00:ff:02; outport = "lr0-sw1"; flags.loopback = 
> 1; reg9[[9]] = 1; next;)
> -  table=??(lr_in_ip_routing   ), priority=518  , match=(inport == "lr0-sw0" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::200:ff:fe00:ff01; eth.src = 00:00:00:00:ff:01; 
> outport = "lr0-sw0"; flags.loopback = 1; reg9[[9]] = 0; next;)
> -  table=??(lr_in_ip_routing   ), priority=518  , match=(inport == "lr0-sw1" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::200:ff:fe00:ff02; eth.src = 00:00:00:00:ff:02; 
> outport = "lr0-sw1"; flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=1838 , match=(reg7 == 0 && ip4.dst 
> == 192.168.0.0/24), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = ??; 
> reg8[[16..31]] = select(1, 2);)
> +  table=??(lr_in_ip_routing   ), priority=1838 , match=(reg7 == 0 && ip4.dst 
> == 192.168.1.0/24), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = ??; 
> reg8[[16..31]] = select(1, 2);)
> +  table=??(lr_in_ip_routing   ), priority=1840 , match=(reg7 == 0 && ip4.dst 
> == 192.168.0.0/24), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = ??; 
> reg8[[16..31]] = select(1, 2);)
> +  table=??(lr_in_ip_routing   ), priority=1842 , match=(ip4.dst == 
> 10.0.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; flags.loopback = 
> 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=1842 , match=(ip4.dst == 
> 10.0.1.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 = 
> 10.0.1.1; eth.src = 00:00:00:00:ff:02; outport = "lr0-sw1"; flags.loopback = 
> 1; reg9[[9]] = 1; next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(inport == "lr0-sw0" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::200:ff:fe00:ff01; eth.src = 00:00:00:00:ff:01; 
> outport = "lr0-sw0"; flags.loopback = 1; reg9[[9]] = 0; next;)
> +  table=??(lr_in_ip_routing   ), priority=2322 , match=(inport == "lr0-sw1" 
> && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = 
> ip6.dst; xxreg1 = fe80::200:ff:fe00:ff02; eth.src = 00:00:00:00:ff:02; 
> outport = "lr0-sw1"; flags.loopback = 1; reg9[[9]] = 0; next;)
>   ])
>   
>   OVN_CLEANUP_NORTHD
> @@ -20473,7 +20473,7 @@ check ovn-nbctl --wait=sb sync
>   
>   ovn-sbctl dump-flows lr0 > lr0flows
>   AT_CHECK([grep 'lr_in_ip_routing' lr0flows | grep 'select' | 
> ovn_strip_lflows], [0], [dnl
> -  table=??(lr_in_ip_routing   ), priority=196  , match=(reg7 == 0 && ip4.dst 
> == 192.168.10.0/24), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = 1; 
> reg8[[16..31]] = select(1, 2);)
> +  table=??(lr_in_ip_routing   ), priority=1840 , match=(reg7 == 0 && ip4.dst 
> == 192.168.10.0/24), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = 1; 
> reg8[[16..31]] = select(1, 2);)
>   ])
>   
>   AT_CHECK([grep 'lr_in_ip_routing_ecmp' lr0flows | sed -E 's/== 
> [[1-9]]+\)/== \?)/' | ovn_strip_lflows], [0], [dnl
> @@ -20491,7 +20491,7 @@ check ovn-nbctl --wait=sb set 
> Logical_Router_Static_Route $ecmp1 nexthop="discar
>   
>   ovn-sbctl dump-flows lr0 > lr0flows
>   AT_CHECK([grep 'lr_in_ip_routing' lr0flows | grep 'select' | 
> ovn_strip_lflows], [0], [dnl
> -  table=??(lr_in_ip_routing   ), priority=196  , match=(reg7 == 0 && ip4.dst 
> == 192.168.10.0/24), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = 1; 
> reg8[[16..31]] = select(1, 2);)
> +  table=??(lr_in_ip_routing   ), priority=1840 , match=(reg7 == 0 && ip4.dst 
> == 192.168.10.0/24), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = 1; 
> reg8[[16..31]] = select(1, 2);)
>   ])
>   
>   AT_CHECK([grep 'lr_in_ip_routing_ecmp' lr0flows | sed -E 's/== 
> [[1-9]]+\)/== \?)/' | ovn_strip_lflows], [0], [dnl
> @@ -20506,7 +20506,7 @@ check ovn-nbctl --wait=sb set 
> Logical_Router_Static_Route $ecmp2 nexthop="discar
>   
>   ovn-sbctl dump-flows lr0 > lr0flows
>   AT_CHECK([grep 'lr_in_ip_routing' lr0flows | grep 'select' | 
> ovn_strip_lflows], [0], [dnl
> -  table=??(lr_in_ip_routing   ), priority=196  , match=(reg7 == 0 && ip4.dst 
> == 192.168.10.0/24), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = 1; 
> reg8[[16..31]] = select(1, 2);)
> +  table=??(lr_in_ip_routing   ), priority=1840 , match=(reg7 == 0 && ip4.dst 
> == 192.168.10.0/24), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = 1; 
> reg8[[16..31]] = select(1, 2);)
>   ])
>   
>   AT_CHECK([grep 'lr_in_ip_routing_ecmp' lr0flows | sed -E 's/== 
> [[1-9]]+\)/== \?)/' | ovn_strip_lflows], [0], [dnl
> @@ -20522,7 +20522,7 @@ check ovn-nbctl --wait=sb set 
> Logical_Router_Static_Route $ecmp2 nexthop="10.0.2
>   
>   ovn-sbctl dump-flows lr0 > lr0flows
>   AT_CHECK([grep 'lr_in_ip_routing' lr0flows | grep 'select' | 
> ovn_strip_lflows], [0], [dnl
> -  table=??(lr_in_ip_routing   ), priority=196  , match=(reg7 == 0 && ip4.dst 
> == 192.168.10.0/24), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = 1; 
> reg8[[16..31]] = select(1, 2);)
> +  table=??(lr_in_ip_routing   ), priority=1840 , match=(reg7 == 0 && ip4.dst 
> == 192.168.10.0/24), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = 1; 
> reg8[[16..31]] = select(1, 2);)
>   ])
>   
>   AT_CHECK([grep 'lr_in_ip_routing_ecmp' lr0flows | sed -E 's/== 
> [[1-9]]+\)/== \?)/' | ovn_strip_lflows], [0], [dnl
> diff --git a/utilities/ovn-nbctl.8.xml b/utilities/ovn-nbctl.8.xml
> index 4fbd0bb0e..1c67bbd1f 100644
> --- a/utilities/ovn-nbctl.8.xml
> +++ b/utilities/ovn-nbctl.8.xml
> @@ -1146,6 +1146,7 @@
>         <dt>[<code>--may-exist</code>] 
> [<code>--policy</code>=<var>POLICY</var>]
>           [<code>--route-table</code>=<var>ROUTE_TABLE</var>]
>           [<code>--ecmp</code>] [<code>--ecmp-symmetric-reply</code>]
> +        [<code>--override-connected</code>]
>           [<code>--bfd[=<var>UUID</var></code>]]
>           <code>lr-route-add</code> <var>router</var>
>           <var>prefix</var> <var>nexthop</var> [<var>port</var>]</dt>
> @@ -1194,6 +1195,11 @@
>             it is not necessary to set both.
>           </p>
>   
> +        <p>
> +          The <code>--override-connected</code> option makes it so that
> +          route's priority to be highest among routes with same prefix.
> +        </p>
> +
>           <p>
>             <code>--bfd</code> option is used to link a BFD session to the
>             OVN route. If the BFD session UUID is provided, it will be used
> diff --git a/utilities/ovn-nbctl.c b/utilities/ovn-nbctl.c
> index 0ef207272..abc172b57 100644
> --- a/utilities/ovn-nbctl.c
> +++ b/utilities/ovn-nbctl.c
> @@ -448,6 +448,7 @@ Route commands:\n\
>     [--policy=POLICY]\n\
>     [--ecmp]\n\
>     [--ecmp-symmetric-reply]\n\
> +  [--override-connected]\n\
>     [--route-table=ROUTE_TABLE]\n\
>     [--bfd]\n\
>     lr-route-add ROUTER PREFIX NEXTHOP [PORT]\n\
> @@ -5236,6 +5237,8 @@ nbctl_lr_route_add(struct ctl_context *ctx)
>                                              "--ecmp-symmetric-reply") != 
> NULL;
>       bool ecmp = shash_find(&ctx->options, "--ecmp") != NULL ||
>                   ecmp_symmetric_reply;
> +    bool override_connected = shash_find(&ctx->options,
> +                                           "--override-connected") != NULL;
>       struct nbrec_logical_router_static_route *route =
>           nbctl_lr_get_route(lr, prefix, next_hop, is_src_route, ecmp,
>                              route_table);
> @@ -5323,11 +5326,20 @@ nbctl_lr_route_add(struct ctl_context *ctx)
>           nbrec_logical_router_static_route_set_route_table(route, 
> route_table);
>       }
>   
> -    if (ecmp_symmetric_reply) {
> -        const struct smap options = SMAP_CONST1(&options,
> -                                                "ecmp_symmetric_reply",
> -                                                "true");
> +    if (ecmp_symmetric_reply || override_connected) {
> +        struct smap options = SMAP_INITIALIZER(&options);
> +
> +        if (ecmp_symmetric_reply) {
> +            smap_add(&options, "ecmp_symmetric_reply", "true");
> +        }
> +
> +        if (override_connected) {
> +            smap_add(&options, ROUTE_OVERRIDE_CONNECTED, "true");
> +        }
> +
>           nbrec_logical_router_static_route_set_options(route, &options);
> +
> +        smap_destroy(&options);
>       }
>   
>       nbrec_logical_router_update_static_routes_addvalue(lr, route);
> @@ -7437,6 +7449,10 @@ print_route(const struct 
> nbrec_logical_router_static_route *route,
>           ds_put_cstr(s, " ecmp-symmetric-reply");
>       }
>   
> +    if (smap_get_bool(&route->options, ROUTE_OVERRIDE_CONNECTED, false)) {
> +        ds_put_cstr(s, " override-connected");
> +    }
> +
>       if (route->bfd) {
>           ds_put_cstr(s, " bfd");
>       }
> @@ -9420,8 +9436,8 @@ static const struct ctl_command_syntax nbctl_commands[] 
> = {
>       /* logical router route commands. */
>       { "lr-route-add", 3, 4, "ROUTER PREFIX NEXTHOP [PORT]",
>         nbctl_pre_lr_route_add, nbctl_lr_route_add, NULL,
> -      "--may-exist,--ecmp,--ecmp-symmetric-reply,--policy=,"
> -      "--route-table=,--bfd?", RW },
> +      "--may-exist,--ecmp,--ecmp-symmetric-reply,--override-connected,"
> +      "--policy=,--route-table=,--bfd?", RW },
>       { "lr-route-del", 1, 4, "ROUTER [PREFIX [NEXTHOP [PORT]]]",
>         nbctl_pre_lr_route_del, nbctl_lr_route_del, NULL,
>         "--if-exists,--policy=,--route-table=", RW },


_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to