On 8/19/25 1:59 PM, Aleksandr Smirnov wrote:
> Enable east-west traffic rerouting for locally
> connected networks. Enable east-west traffic between AZ.
> 
> Introduce new option (override-connected) for static routes.
> Static route with this option set overrides local directly
> connected route.
> 

Hi Aleksandr,

Thanks for this new version!  And sorry for the delays in reviewing it.

> ovn-ic is extended to pass this option during advertise-learn.
> Also, route_table column in ic database now used for
> connected routes too.
> 
> ic route priorities are changed to raise priority
> of learned connected routes that have route table set.
> 
> Finally, route priorities for same prefix network will be:
>  1. Static (both local and ic-learned), override-connected is set.
>  2. Ic-learned connected with route table set.

This is a significant behavior change, isn't it?  If so we need to at
least call it out in the NEWS file.

In general we should also mention the new override-connected feature in
the NEWS file.

>  3. All other connected.
>  3. All other static.
> 
> With using route tables, this approach will create possibility
> to enforce local traffic reroute to remote az for processing and
> deliver it back to original destination.
> 
> Signed-off-by: Aleksandr Smirnov <[email protected]>
> ---
>   v2: Apply minor comments from internal reviewers.
> ---

I tried to rebase this change on the current main branch but the
conflicts are quite significant.  Would you mind posting a rebased v3
instead?  I'd like to avoid introducing bugs if I do the rebasing.

In general, I think I don't have anything against the feature.

One note is that maybe we should consider an explicit way of configuring
"administrative distance" (essentially what we're doing here with the
priorities) in the future.  For the case when different users prefer
different precedence for the same IP prefix lenght.

Yet another thing to keep in mind is that maybe moving to a different
way of configuring OVN routes might be more flexible and more in line
with what the Linux kernel supports:

https://mail.openvswitch.org/pipermail/ovs-dev/2025-September/426021.html

However, I don't think your feature would block any of that (if we ever
go that way).

I have a few minor comments below too.

>  ic/ovn-ic.c                    |  81 +++++++++---
>  lib/ovn-util.h                 |   2 +
>  northd/en-learned-route-sync.c |   2 +-
>  northd/northd.c                | 147 ++++++++++++---------
>  northd/northd.h                |   2 +
>  ovn-ic-sb.ovsschema            |   5 +-
>  ovn-ic-sb.xml                  |  18 +++
>  ovn-nb.xml                     |   8 ++
>  tests/ovn-ic.at                | 181 +++++++++++++++++++++++++-
>  tests/ovn-northd.at            | 226 ++++++++++++++++-----------------
>  utilities/ovn-nbctl.c          |  28 +++-
>  11 files changed, 503 insertions(+), 197 deletions(-)
> 
> diff --git a/ic/ovn-ic.c b/ic/ovn-ic.c
> index cfdbd4b40..0f27220bd 100644
> --- a/ic/ovn-ic.c
> +++ b/ic/ovn-ic.c
> @@ -947,6 +947,7 @@ struct ic_route_info {
>      const char *origin;
>      const char *route_table;
>      const char *route_tag;
> +    bool override_connected;
>  
>      const struct nbrec_logical_router *nb_lr;
>  
> @@ -963,29 +964,40 @@ struct ic_route_info {
>      const struct nbrec_load_balancer *nb_lb;
>  };
>  
> +static 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 char *route_table,
> +              bool override_connected)
>  {
>      uint32_t basis = hash_bytes(prefix, sizeof *prefix, (uint32_t)plen);
>      basis = hash_string(origin, basis);
>      basis = hash_string(route_table, basis);
> +    basis = hash_boolean(override_connected, basis);
>      return hash_bytes(nexthop, sizeof *nexthop, basis);
>  }
>  
>  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, uint32_t hash)
> +              const char *origin, const char *route_table,
> +              bool override_connected, uint32_t hash)
>  {
>      struct ic_route_info *r;
>      if (!hash) {
> -        hash = ic_route_hash(prefix, plen, nexthop, origin, route_table);
> +        hash = ic_route_hash(prefix, plen, nexthop, origin, route_table,
> +                             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)) {
> @@ -1039,8 +1051,10 @@ 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);
> +
>      if (ic_route_find(routes_learned, &prefix, plen, &nexthop, origin,
> -                      nb_route->route_table, 0)) {
> +                      nb_route->route_table, override_connected, 0)) {
>          /* Route was added to learned on previous iteration. */
>          return true;
>      }
> @@ -1053,9 +1067,11 @@ add_to_routes_learned(struct hmap *routes_learned,
>      ic_route->origin = origin;
>      ic_route->route_table = nb_route->route_table;
>      ic_route->nb_lr = nb_lr;
> +    ic_route->override_connected = override_connected;
> +
>      hmap_insert(routes_learned, &ic_route->node,
>                  ic_route_hash(&prefix, plen, &nexthop, origin,
> -                              nb_route->route_table));
> +                              nb_route->route_table, override_connected));
>      return true;
>  }
>  
> @@ -1189,7 +1205,8 @@ 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);
>  
> @@ -1197,10 +1214,11 @@ add_to_routes_ad(struct hmap *routes_ad, const struct 
> in6_addr prefix,
>          route_table = "";
>      }
>  
> -    uint hash = ic_route_hash(&prefix, plen, &nexthop, origin, route_table);
> +    uint hash = ic_route_hash(&prefix, plen, &nexthop, origin, route_table,
> +                              override_connected);
>  
>      if (!ic_route_find(routes_ad, &prefix, plen, &nexthop, origin, 
> route_table,
> -                       hash)) {
> +                       override_connected, hash)) {
>          struct ic_route_info *ic_route = xzalloc(sizeof *ic_route);
>          ic_route->prefix = prefix;
>          ic_route->plen = plen;
> @@ -1212,6 +1230,8 @@ 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);
> @@ -1281,7 +1301,8 @@ 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,
> +                     get_override_connected(&nb_route->options));
>  }
>  
>  static void
> @@ -1291,7 +1312,8 @@ add_network_to_routes_ad(struct hmap *routes_ad, const 
> char *network,
>                           const struct smap *nb_options,
>                           const struct nbrec_logical_router *nb_lr,
>                           const char *route_tag,
> -                         const struct nbrec_logical_router_port *ts_lrp)
> +                         const struct nbrec_logical_router_port *ts_lrp,
> +                         const char *ts_route_table)
>  {
>      struct in6_addr prefix, nexthop;
>      unsigned int plen;
> @@ -1329,9 +1351,23 @@ 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);
> +    }
> +
>      /* directly-connected routes go to <main> route table */
>      add_to_routes_ad(routes_ad, prefix, plen, nexthop, 
> ROUTE_ORIGIN_CONNECTED,
> -                     NULL, nb_lrp, NULL, nb_lr, NULL, route_tag);
> +                     NULL, nb_lrp, NULL, nb_lr, NULL, route_tag, false);
>  }
>  
>  static void
> @@ -1389,7 +1425,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);
>  }
> @@ -1753,7 +1789,9 @@ sync_learned_routes(struct ic_context *ctx,
>              struct ic_route_info *route_learned
>                  = ic_route_find(&ic_lr->routes_learned, &prefix, plen,
>                                  &nexthop, isb_route->origin,
> -                                isb_route->route_table, 0);
> +                                isb_route->route_table,
> +                                get_override_connected(&isb_route->options),
> +                                0);
>              if (route_learned) {
>                  /* Sync external-ids */
>                  struct uuid ext_id;
> @@ -1785,6 +1823,12 @@ sync_learned_routes(struct ic_context *ctx,
>                      nb_route, "ic-learned-route", uuid_s);
>                  nbrec_logical_router_static_route_update_options_setkey(
>                      nb_route, "origin", isb_route->origin);
> +
> +                if (get_override_connected(&isb_route->options)) {
> +                    nbrec_logical_router_static_route_update_options_setkey(
> +                        nb_route, ROUTE_OVERRIDE_CONNECTED, "true");
> +                }
> +
>                  free(uuid_s);
>                  nbrec_logical_router_update_static_routes_addvalue(ic_lr->lr,
>                      nb_route);
> @@ -1873,7 +1917,9 @@ advertise_routes(struct ic_context *ctx,
>          }
>          struct ic_route_info *route_adv =
>              ic_route_find(routes_ad, &prefix, plen, &nexthop,
> -                          isb_route->origin, isb_route->route_table, 0);
> +                          isb_route->origin, isb_route->route_table,
> +                          get_override_connected(&isb_route->options),
> +                          0);
>          if (!route_adv) {
>              /* Delete the extra route from IC-SB. */
>              VLOG_DBG("Delete route %s -> %s from IC-SB, which is not found"
> @@ -1917,6 +1963,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);
>  
> @@ -1970,7 +2020,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);
> +                                         lr, route_tag, ts_lrp,
> +                                         ts_route_table);
>              }
>          } else {
>              /* The router port of the TS port is ignored. */
> diff --git a/lib/ovn-util.h b/lib/ovn-util.h
> index 63beae3e5..4cfeb3ed4 100644
> --- a/lib/ovn-util.h
> +++ b/lib/ovn-util.h
> @@ -33,6 +33,8 @@
>  #define ROUTE_ORIGIN_STATIC "static"
>  #define ROUTE_ORIGIN_LB "loadbalancer"
>  
> +#define ROUTE_OVERRIDE_CONNECTED "override-connected"
> +
>  #define ETH_CRC_LENGTH 4
>  #define ETHERNET_OVERHEAD (ETH_HEADER_LEN + ETH_CRC_LENGTH)
>  
> diff --git a/northd/en-learned-route-sync.c b/northd/en-learned-route-sync.c
> index f14f610ac..8abb6010e 100644
> --- a/northd/en-learned-route-sync.c
> +++ b/northd/en-learned-route-sync.c
> @@ -205,7 +205,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 015f30a35..5daecd987 100644
> --- a/northd/northd.c
> +++ b/northd/northd.c
> @@ -344,15 +344,21 @@ 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)
> + *  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)
>   * (src-ip routes have lower priority than all other routes regardless of
>   * prefix length, so not included here.) */
> -#define ROUTE_PRIO_OFFSET_MULTIPLIER 6
> +#define ROUTE_PRIO_OFFSET_MULTIPLIER 10
>  #define ROUTE_PRIO_OFFSET_LEARNED 0
>  #define ROUTE_PRIO_OFFSET_STATIC 2
>  #define ROUTE_PRIO_OFFSET_CONNECTED 4
> +#define ROUTE_PRIO_OFFSET_IC_LEARNED_CONNECTED_WITH_TABLEID 6
> +#define ROUTE_PRIO_OFFSET_PRIORITY_STATIC 8
>  
>  /* Returns the type of the datapath to which a flow with the given 'stage' 
> may
>   * be added. */
> @@ -11029,6 +11035,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;
>          }
> @@ -11059,6 +11069,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,
> @@ -11074,6 +11085,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;
> @@ -11102,7 +11114,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;
> @@ -11163,6 +11176,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,
> @@ -11172,7 +11186,7 @@ parsed_route_add(const struct ovn_datapath *od,
>  
>      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,
> +        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);
> @@ -11300,6 +11314,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);
>  
>      enum route_source source;
>      if (!strcmp(smap_get_def(&route->options, "origin", ""),
> @@ -11311,7 +11327,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);
>  }
> @@ -11329,7 +11346,7 @@ parsed_routes_add_connected(const struct ovn_datapath 
> *od,
>          parsed_route_add(od, NULL, &prefix, addr->plen,
>                           false, addr->addr_s, op,
>                           0, false,
> -                         false, NULL, ROUTE_SOURCE_CONNECTED,
> +                         false, false, NULL, ROUTE_SOURCE_CONNECTED,
>                           &op->nbrp->header_, NULL, routes);
>      }
>  
> @@ -11341,7 +11358,7 @@ parsed_routes_add_connected(const struct ovn_datapath 
> *od,
>          parsed_route_add(od, NULL, &prefix, addr->plen,
>                           false, addr->addr_s, op,
>                           0, false,
> -                         false, NULL, ROUTE_SOURCE_CONNECTED,
> +                         false, false, NULL, ROUTE_SOURCE_CONNECTED,
>                           &op->nbrp->header_, NULL, routes);
>      }
>  }
> @@ -11396,62 +11413,47 @@ 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)
> +calc_priority(int plen,
> +              enum route_source source,
> +              bool override_connected,
> +              bool is_src_route,
> +              bool has_protocol_match)
>  {
> +    uint16_t pri = (plen * ROUTE_PRIO_OFFSET_MULTIPLIER) + 
> has_protocol_match;
> +
> +    if (is_src_route) {
> +        return pri;
> +    }
> +
>      switch (source) {
>      case ROUTE_SOURCE_CONNECTED:
> -        return ROUTE_PRIO_OFFSET_CONNECTED;
> +        pri += (override_connected)
> +               ? ROUTE_PRIO_OFFSET_IC_LEARNED_CONNECTED_WITH_TABLEID
> +               : ROUTE_PRIO_OFFSET_CONNECTED;
> +        break;
> +
>      case ROUTE_SOURCE_STATIC:
> -        return ROUTE_PRIO_OFFSET_STATIC;
> +        pri += (override_connected)
> +               ? ROUTE_PRIO_OFFSET_PRIORITY_STATIC
> +               : ROUTE_PRIO_OFFSET_STATIC;
> +        break;
> +
>      case ROUTE_SOURCE_LEARNED:
> -        return ROUTE_PRIO_OFFSET_LEARNED;
> +        pri += ROUTE_PRIO_OFFSET_LEARNED;
> +        break;
> +
>      case ROUTE_SOURCE_NAT:
>      case ROUTE_SOURCE_LB:
>      default:
>          OVS_NOT_REACHED();
>      }
> -}
>  
> -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)
> -{
> -    const char *dir;
> -    int ofs = route_source_to_offset(source);
> -    int base = 0;
> -
> -    /* The priority here is calculated to implement longest-prefix-match
> -     * routing. */
> -    if (is_src_route) {
> -        dir = "src";
> -        ofs = 0;
> -    } else {
> -        dir = "dst";
> -        /* dst routes have higher priority than all src routes regardless of
> -         * prefix length. */
> -        base = (128 + 1) * ROUTE_PRIO_OFFSET_MULTIPLIER;
> -    }
> -
> -    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);
> -    }
> -
> -    if (has_protocol_match) {
> -        ofs += 1;
> -    }
> -    *priority = base + (plen * ROUTE_PRIO_OFFSET_MULTIPLIER) + ofs;
> -
> -    ds_put_format(match, "ip%s.%s == %s/%d", is_ipv4 ? "4" : "6", dir,
> -                  network_s, plen);
> +    return pri + (128 + 1) * ROUTE_PRIO_OFFSET_MULTIPLIER;
>  }
>  
> +
>  bool
>  find_route_outport(const struct hmap *lr_ports, const char *output_port,
>                     const char *ip_prefix, const char *nexthop, bool is_ipv4,
> @@ -11646,10 +11648,20 @@ 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;
> @@ -11760,7 +11772,8 @@ 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;
> @@ -11774,8 +11787,22 @@ 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);
> +
> +    priority = calc_priority(plen, source, override_connected, is_src_route,
> +                             false);
>  
>      struct ds common_actions = DS_EMPTY_INITIALIZER;
>      struct ds actions = DS_EMPTY_INITIALIZER;
> @@ -11843,7 +11870,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);
>  }
> @@ -17329,7 +17356,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 8f865e8b3..a343c639f 100644
> --- a/northd/northd.h
> +++ b/northd/northd.h
> @@ -801,6 +801,7 @@ struct parsed_route {
>      uint32_t route_table_id;
>      uint32_t hash;
>      bool ecmp_symmetric_reply;
> +    bool override_connected;
>      bool is_discard_route;
>      const struct ovn_datapath *od;
>      bool stale;
> @@ -830,6 +831,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/ovn-ic-sb.ovsschema b/ovn-ic-sb.ovsschema
> index 34b5457bb..d54f6a673 100644
> --- a/ovn-ic-sb.ovsschema
> +++ b/ovn-ic-sb.ovsschema
> @@ -1,7 +1,7 @@
>  {
>      "name": "OVN_IC_Southbound",
>      "version": "2.2.0",

We need to bump the version to 2.3.0 if we add new columns.  Well, 2.4.0
on current main because more patches went in since.

> -    "cksum": "2294868959 8438",
> +    "cksum": "1724161406 8593",
>      "tables": {
>          "IC_SB_Global": {
>              "columns": {
> @@ -101,6 +101,9 @@
>                      "type": "string",
>                      "enum": ["set",
>                               ["connected", "static", "loadbalancer"]]}}},
> +                "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 35dc1f509..a33ff8a0a 100644
> --- a/ovn-ic-sb.xml
> +++ b/ovn-ic-sb.xml
> @@ -336,6 +336,8 @@
>          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 learned to the route table having
> +        this name.
>          </p>
>          <p>
>          Static routes within route tables will be advertised and learned only
> @@ -355,6 +357,22 @@
>          Nexthop IP address for this route.
>        </column>
>  
> +      <column name="options">
> +        Options of the route.
> +      </column>
> +
> +      <column name="options" key="override-connected" type='{"type": 
> "boolean"}'>
> +        <p>
> +            For static routes this options is a copy of same option
> +            from northbound database.
> +        </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>
> +
>        <column name="origin">
>          Can be one of <code>connected</code>, <code>static</code> or
>          <code>loadbalancer</code>.  Routes to directly-connected subnets -
> diff --git a/ovn-nb.xml b/ovn-nb.xml
> index b7b5b5c40..0d33d2898 100644
> --- a/ovn-nb.xml
> +++ b/ovn-nb.xml
> @@ -4617,6 +4617,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.
> +        The key's value is only "true".

I disagree with this statement. :)

There's nothing blocking users from setting it to "false".  And OVN will
correctly parse that as the <false> boolean value.  Maybe you should
change this to:

"Default value: <code>false<false>."

> +
> +        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 74ea3bad2..c19f66377 100644
> --- a/tests/ovn-ic.at
> +++ b/tests/ovn-ic.at
> @@ -912,9 +912,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
>  ])
>  
> @@ -1247,6 +1248,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)
>  ])
> @@ -1279,6 +1281,167 @@ OVN_CLEANUP_IC([az1], [az2])
>  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
> +
> +ovn_as az1 check ovn-ic-nbctl --wait=sb sync

Nit: they both work fine but I think I prefer the variant with "check
ovn_as ...".  This applies to all the checks below too.

> +ovn_as az1 check ovn-nbctl set nb_global . options:ic-route-learn=true
> +ovn_as az1 check ovn-nbctl set nb_global . options:ic-route-adv=true
> +
> +ovn_as az1 check ovn-nbctl ls-add subnet-A
> +ovn_as az1 check 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
> +ovn_as az1 check ovn-nbctl lsp-add subnet-A client -- lsp-set-addresses 
> client "0a:00:43:1e:92:20 172.31.0.4"
> +
> +ovn_as az1 check ovn-nbctl ls-add subnet-B
> +ovn_as az1 check 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
> +ovn_as az1 check ovn-nbctl lsp-add subnet-B server -- lsp-set-addresses 
> server "0a:00:b9:86:a4:00 172.31.1.4"
> +
> +ovn_as az1 check 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
> +ovn_as az1 check 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
> +
> +ovn_as az1 check ovn-nbctl lr-add rt1
> +ovn_as az1 check 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
> +ovn_as az1 check 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
> +ovn_as az1 check 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
> +ovn_as az1 check 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
> +
> +ovn_as az2 check ovn-ic-nbctl --wait=sb sync
> +ovn_as az2 check ovn-nbctl set nb_global . options:ic-route-learn=true
> +ovn_as az2 check ovn-nbctl set nb_global . options:ic-route-adv=true
> +
> +ovn_as az2 check ovn-nbctl ls-add subnet-C
> +ovn_as az2 check 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
> +ovn_as az2 check ovn-nbctl lsp-add subnet-C filter1 -- lsp-set-addresses 
> filter1 "0a:01:4f:43:ce:e1 172.31.2.4"
> +
> +ovn_as az2 check ovn-nbctl ls-add subnet-D
> +ovn_as az2 check 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
> +ovn_as az2 check ovn-nbctl lsp-add subnet-D filter2 -- lsp-set-addresses 
> filter2 "0a:01:39:eb:b1:41 172.31.3.4"
> +
> +ovn_as az2 check 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
> +ovn_as az2 check 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
> +
> +ovn_as az2 check ovn-nbctl lr-add rt1
> +ovn_as az2 check 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
> +ovn_as az2 check 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
> +ovn_as az2 check 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
> +ovn_as az2 check 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
> +
> +ovn_as az2 check ovn-nbctl --route-table=table1 --override-connected 
> lr-route-add rt1 "172.31.0.0/24" "172.31.2.4"
> +ovn_as az2 check 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=1534 , 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=1534 , 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=1534 , 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=1534 , 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=1534 , 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=1534 , 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=1536 , 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=1536 , 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=1536 , 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=1536 , 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=1538 , 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=1538 , 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=1564 , 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=1564 , 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=1934 , 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=1934 , 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=1934 , 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=1934 , 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=1534 , 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=1534 , 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=1534 , 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=1534 , 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=1534 , 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=1534 , 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=1536 , 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=1536 , 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=1536 , 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=1536 , 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=1538 , 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=1538 , 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=1564 , 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=1564 , 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=1934 , 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=1934 , 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=1934 , 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=1934 , 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
> +])
>  
>  OVN_FOR_EACH_NORTHD([
>  AT_SETUP([ovn-ic -- route sync -- multiple route tables])
> @@ -1374,8 +1537,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
> @@ -1383,22 +1549,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])
> @@ -1505,8 +1676,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
> @@ -1514,18 +1688,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)
>  ])
>  
> @@ -1533,7 +1710,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])
> diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
> index 11bbb211d..74c1db4fc 100644
> --- a/tests/ovn-northd.at
> +++ b/tests/ovn-northd.at
> @@ -7032,9 +7032,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=1162 , 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=922  , 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=968  , 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=1534 , 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=1612 , 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=1934 , 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
> @@ -7053,9 +7053,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=1162 , 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=922  , 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=968  , 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=1534 , 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=1612 , 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=1934 , 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;)
> @@ -7085,9 +7085,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=1162 , 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=922  , 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=968  , 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=1534 , 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=1612 , 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=1934 , 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;)
> @@ -7104,14 +7104,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=920  , 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=1532 , 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=920  , 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=1532 , 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
> @@ -7126,7 +7126,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=872  , 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=1452 , 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"
> @@ -7135,10 +7135,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=872  , 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=873  , 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=873  , 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=873  , 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=1452 , 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=1453 , 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=1453 , 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=1453 , 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_CLEANUP
> @@ -7176,14 +7176,14 @@ 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=1160 , 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=1160 , 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=1162 , 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=1162 , 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=1162 , 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=920  , 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=920  , 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=922  , 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=1532 , 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=1532 , 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=1534 , 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=1932 , 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=1932 , 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=1934 , 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=1934 , 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=1934 , 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
> @@ -7678,16 +7678,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=1162 , 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=1162 , 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=1162 , 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=776  , 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=776  , 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=920  , 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=922  , 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=922  , 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=922  , 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=968  , 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=1292 , 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=1292 , 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=1532 , 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=1534 , 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=1534 , 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=1534 , 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=1612 , 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=1934 , 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=1934 , 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=1934 , 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;)
>  ])
>  
>  AT_CLEANUP
> @@ -15117,12 +15117,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=1160 , 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=1162 , 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=1162 , 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=1162 , 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=920  , 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=922  , 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=1532 , 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=1534 , 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=1932 , 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=1934 , 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=1934 , 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=1934 , 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.
> @@ -15138,13 +15138,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=1160 , 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=1162 , 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=1162 , 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=1162 , 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=918  , 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=920  , 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=922  , 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=1530 , 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=1532 , 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=1534 , 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=1932 , 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=1934 , 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=1934 , 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=1934 , 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.
> @@ -15161,13 +15161,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=1160 , 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=1162 , 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=1162 , 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=1162 , 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=918  , 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=920  , 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=922  , 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=1530 , 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=1532 , 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=1534 , 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=1932 , 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=1934 , 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=1934 , 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=1934 , 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
> @@ -15181,15 +15181,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=1158 , 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=1160 , 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=1162 , 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=1162 , 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=1162 , 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=1162 , 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=918  , 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=920  , 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=922  , 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=1530 , 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=1532 , 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=1534 , 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=1930 , 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=1932 , 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=1934 , 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=1934 , 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=1934 , 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=1934 , 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.
> @@ -15205,16 +15205,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=1158 , 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=1158 , 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=1160 , 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=1162 , 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=1162 , 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=1162 , 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=1162 , 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=918  , 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=920  , 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=922  , 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=1530 , 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=1532 , 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=1534 , 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=1930 , 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=1930 , 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=1932 , 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=1934 , 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=1934 , 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=1934 , 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=1934 , 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.
> @@ -15230,17 +15230,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=1158 , 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=1158 , 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=1160 , 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=1162 , 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=1162 , 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=1162 , 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=1162 , 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=918  , 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=918  , 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=920  , 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=922  , 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=1530 , 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=1530 , 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=1532 , 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=1534 , 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=1930 , 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=1930 , 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=1932 , 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=1934 , 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=1934 , 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=1934 , 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=1934 , 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.
> @@ -15252,11 +15252,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=1158 , 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=1162 , 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=918  , 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=920  , 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=922  , 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=1530 , 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=1532 , 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=1534 , 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=1930 , 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=1934 , 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;)
>  ])
>  
>  AT_CLEANUP
> @@ -15285,11 +15285,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=1162 , 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=1162 , 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=920  , 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=922  , 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=922  , 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=1532 , 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=1534 , 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=1534 , 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=1934 , 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=1934 , 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;)
> @@ -15311,12 +15311,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=1162 , 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=1162 , 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=918  , 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=920  , 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=922  , 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=922  , 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=1530 , 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=1532 , 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=1534 , 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=1534 , 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=1934 , 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=1934 , 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;)
> @@ -15339,12 +15339,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=1162 , 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=1162 , 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=918  , 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=920  , 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=922  , 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=922  , 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=1530 , 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=1532 , 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=1534 , 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=1534 , 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=1934 , 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=1934 , 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;)
> @@ -15381,13 +15381,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=1162 , 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=1162 , 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=918  , 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=918  , 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=920  , 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=922  , 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=922  , 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=1530 , 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=1530 , 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=1532 , 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=1534 , 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=1534 , 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=1934 , 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=1934 , 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_CLEANUP
> diff --git a/utilities/ovn-nbctl.c b/utilities/ovn-nbctl.c
> index 58517f966..834915194 100644
> --- a/utilities/ovn-nbctl.c
> +++ b/utilities/ovn-nbctl.c
> @@ -410,6 +410,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\
> @@ -4766,6 +4767,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);
> @@ -4853,11 +4856,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);
> @@ -6984,6 +6996,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");
>      }
> @@ -8406,8 +8422,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 },

Regards,
Dumitru

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

Reply via email to