On 10/27/25 1:42 PM, Dima Chumak via dev wrote:
> For route lookup based on the destination address a single routing table
> is sufficient. For a more advanced routing when a lookup needs to take
> into consideration other parameters, such as a source address, a
> multi-table lookup is needed.
> 
> This change introduces infrastructure for using multiple routing
> tables that can be added dynamically, as a pre-step towards importing
> non-default routing tables from kernel.
> 
> Signed-off-by: Dima Chumak <[email protected]>
> ---
>  lib/netdev-dummy.c            |  14 ++-
>  lib/ovs-router.c              | 166 +++++++++++++++++++++++++++-------
>  lib/ovs-router.h              |  13 ++-
>  lib/route-table.c             |   6 +-
>  tests/nsh.at                  |   9 +-
>  tests/ofproto-dpif.at         |   9 +-
>  tests/ovs-router.at           |  36 +++++---
>  tests/packet-type-aware.at    |  15 ++-
>  tests/tunnel-push-pop-ipv6.at |  30 ++++--
>  tests/tunnel-push-pop.at      |  42 ++++++---
>  tests/tunnel.at               |   6 +-
>  11 files changed, 253 insertions(+), 93 deletions(-)

Mostly LGTM.  Just a couple nits below.

> 
> diff --git a/lib/netdev-dummy.c b/lib/netdev-dummy.c
> index b72820fcc506..bad86d3c4c76 100644
> --- a/lib/netdev-dummy.c
> +++ b/lib/netdev-dummy.c
> @@ -2221,10 +2221,13 @@ netdev_dummy_ip4addr(struct unixctl_conn *conn, int 
> argc OVS_UNUSED,
>              mask.s_addr = be32_prefix_mask(plen);
>              netdev_dummy_add_in4(netdev, ip, mask);
>  
> -            /* Insert local route entry for the new address. */
>              in6_addr_set_mapped_ipv4(&ip6, ip.s_addr);
> -            ovs_router_force_insert(0, &ip6, plen + 96, true, argv[1],
> -                                    &in6addr_any, &ip6);
> +            /* Insert local route entry for the new address. */
> +            ovs_router_force_insert(CLS_MAIN, 0, &ip6, 32 + 96, true,
> +                                    argv[1], &in6addr_any, &ip6);
> +            /* Insert network route entry for the new address. */
> +            ovs_router_force_insert(CLS_MAIN, 0, &ip6, plen + 96, false,
> +                                    argv[1], &in6addr_any, &ip6);
>  
>              unixctl_command_reply(conn, "OK");
>          } else {
> @@ -2257,7 +2260,10 @@ netdev_dummy_ip6addr(struct unixctl_conn *conn, int 
> argc OVS_UNUSED,
>              netdev_dummy_add_in6(netdev, &ip6, &mask);
>  
>              /* Insert local route entry for the new address. */
> -            ovs_router_force_insert(0, &ip6, plen, true, argv[1],
> +            ovs_router_force_insert(CLS_MAIN, 0, &ip6, 128, true, argv[1],
> +                                    &in6addr_any, &ip6);
> +            /* Insert network route entry for the new address. */
> +            ovs_router_force_insert(CLS_MAIN, 0, &ip6, plen, false, argv[1],
>                                      &in6addr_any, &ip6);
>  
>              unixctl_command_reply(conn, "OK");
> diff --git a/lib/ovs-router.c b/lib/ovs-router.c
> index 2827a6e43574..70644f7bd4f2 100644
> --- a/lib/ovs-router.c
> +++ b/lib/ovs-router.c
> @@ -33,6 +33,7 @@
>  #include "classifier.h"
>  #include "command-line.h"
>  #include "compiler.h"
> +#include "cmap.h"
>  #include "dpif.h"
>  #include "fatal-signal.h"
>  #include "openvswitch/dynamic-string.h"
> @@ -50,10 +51,16 @@
>  
>  VLOG_DEFINE_THIS_MODULE(ovs_router);
>  
> +struct clsmap_node {
> +    struct cmap_node cmap_node;
> +    uint32_t table;
> +    struct classifier cls;
> +};
> +
>  static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
>  
>  static struct ovs_mutex mutex = OVS_MUTEX_INITIALIZER;
> -static struct classifier cls;
> +static struct cmap clsmap = CMAP_INITIALIZER;
>  
>  /* By default, use the system routing table.  For system-independent testing,
>   * the unit tests disable using the system routing table. */
> @@ -71,6 +78,50 @@ struct ovs_router_entry {
>      uint32_t mark;
>  };
>  
> +static void rt_entry_delete__(const struct cls_rule *, struct classifier *);
> +
> +static struct classifier *
> +cls_find(uint32_t table)
> +{
> +    struct clsmap_node *node;
> +
> +    CMAP_FOR_EACH_WITH_HASH (node, cmap_node, hash_int(table, 0), &clsmap) {
> +        if (node->table == table) {
> +            return &node->cls;
> +        }
> +    }
> +
> +    return NULL;
> +}
> +
> +static struct classifier *
> +cls_create(uint32_t table) OVS_REQUIRES(mutex)
> +{
> +    struct clsmap_node *node;
> +
> +    node = xmalloc(sizeof *node);
> +    classifier_init(&node->cls, NULL);
> +    node->table = table;
> +    cmap_insert(&clsmap, &node->cmap_node, hash_int(table, 0));
> +
> +    return &node->cls;
> +}
> +
> +static void
> +cls_flush(struct classifier *cls, bool flush_all)
> +    OVS_REQUIRES(mutex)
> +{
> +    struct ovs_router_entry *rt;
> +
> +    classifier_defer(cls);
> +    CLS_FOR_EACH (rt, cr, cls) {
> +        if (flush_all || rt->priority == rt->plen || rt->local) {
> +            rt_entry_delete__(&rt->cr, cls);
> +        }
> +    }
> +    classifier_publish(cls);
> +}
> +
>  static struct ovs_router_entry *
>  ovs_router_entry_cast(const struct cls_rule *cr)
>  {
> @@ -110,15 +161,20 @@ ovs_router_lookup(uint32_t mark, const struct in6_addr 
> *ip6_dst,
>                    char output_netdev[],
>                    struct in6_addr *src, struct in6_addr *gw)
>  {
> -    const struct cls_rule *cr;
>      struct flow flow = {.ipv6_dst = *ip6_dst, .pkt_mark = mark};
> +    struct classifier *cls_main = cls_find(CLS_MAIN);
> +    const struct cls_rule *cr;
> +
> +    if (!cls_main) {
> +        return false;
> +    }
>  
>      if (src && ipv6_addr_is_set(src)) {
>          const struct cls_rule *cr_src;
>          struct flow flow_src = {.ipv6_dst = *src, .pkt_mark = mark};
>  
> -        cr_src = classifier_lookup(&cls, OVS_VERSION_MAX, &flow_src, NULL,
> -                                   NULL);
> +        cr_src = classifier_lookup(cls_main, OVS_VERSION_MAX, &flow_src,
> +                                   NULL, NULL);
>          if (cr_src) {
>              struct ovs_router_entry *p_src = ovs_router_entry_cast(cr_src);
>              if (!p_src->local) {
> @@ -129,7 +185,7 @@ ovs_router_lookup(uint32_t mark, const struct in6_addr 
> *ip6_dst,
>          }
>      }
>  
> -    cr = classifier_lookup(&cls, OVS_VERSION_MAX, &flow, NULL, NULL);
> +    cr = classifier_lookup(cls_main, OVS_VERSION_MAX, &flow, NULL, NULL);
>      if (cr) {
>          struct ovs_router_entry *p = ovs_router_entry_cast(cr);
>  
> @@ -257,8 +313,8 @@ out:
>  }
>  
>  static int
> -ovs_router_insert__(uint32_t mark, uint8_t priority, bool local,
> -                    const struct in6_addr *ip6_dst,
> +ovs_router_insert__(uint32_t table, uint32_t mark, uint8_t priority,
> +                    bool local, const struct in6_addr *ip6_dst,
>                      uint8_t plen, const char output_netdev[],
>                      const struct in6_addr *gw,
>                      const struct in6_addr *ip6_src)
> @@ -268,6 +324,7 @@ ovs_router_insert__(uint32_t mark, uint8_t priority, bool 
> local,
>                          struct in6_addr *prefsrc);
>      const struct cls_rule *cr;
>      struct ovs_router_entry *p;
> +    struct classifier *cls;
>      struct match match;
>      int err;
>  
> @@ -308,7 +365,11 @@ ovs_router_insert__(uint32_t mark, uint8_t priority, 
> bool local,
>      cls_rule_init(&p->cr, &match, priority);
>  
>      ovs_mutex_lock(&mutex);
> -    cr = classifier_replace(&cls, &p->cr, OVS_VERSION_MIN, NULL, 0);
> +    cls = cls_find(table);
> +    if (!cls) {
> +        cls = cls_create(table);
> +    }
> +    cr = classifier_replace(cls, &p->cr, OVS_VERSION_MIN, NULL, 0);
>      ovs_mutex_unlock(&mutex);
>  
>      if (cr) {
> @@ -321,13 +382,13 @@ ovs_router_insert__(uint32_t mark, uint8_t priority, 
> bool local,
>  }
>  
>  void
> -ovs_router_insert(uint32_t mark, const struct in6_addr *ip_dst, uint8_t plen,
> -                  bool local, const char output_netdev[],
> +ovs_router_insert(uint32_t table, uint32_t mark, const struct in6_addr 
> *ip_dst,
> +                  uint8_t plen, bool local, const char output_netdev[],
>                    const struct in6_addr *gw, const struct in6_addr *prefsrc)
>  {
>      if (use_system_routing_table) {
>          uint8_t priority = local ? plen + 64 : plen;
> -        ovs_router_insert__(mark, priority, local, ip_dst, plen,
> +        ovs_router_insert__(table, mark, priority, local, ip_dst, plen,
>                              output_netdev, gw, prefsrc);
>      }
>  }
> @@ -335,24 +396,25 @@ ovs_router_insert(uint32_t mark, const struct in6_addr 
> *ip_dst, uint8_t plen,
>  /* The same as 'ovs_router_insert', but it adds the route even if updates
>   * from the system routing table are disabled.  Used for unit tests. */
>  void
> -ovs_router_force_insert(uint32_t mark, const struct in6_addr *ip_dst,
> +ovs_router_force_insert(uint32_t table, uint32_t mark,
> +                        const struct in6_addr *ip_dst,
>                          uint8_t plen, bool local, const char output_netdev[],
>                          const struct in6_addr *gw,
>                          const struct in6_addr *prefsrc)
>  {
>      uint8_t priority = local ? plen + 64 : plen;
>  
> -    ovs_router_insert__(mark, priority, local, ip_dst, plen,
> +    ovs_router_insert__(table, mark, priority, local, ip_dst, plen,
>                          output_netdev, gw, prefsrc);
>  }
>  
>  static void
> -rt_entry_delete__(const struct cls_rule *cr)
> +rt_entry_delete__(const struct cls_rule *cr, struct classifier *cls)
>  {
>      struct ovs_router_entry *p = ovs_router_entry_cast(cr);
>  
>      tnl_port_map_delete_ipdev(p->output_netdev);
> -    classifier_remove_assert(&cls, cr);
> +    classifier_remove_assert(cls, cr);
>      ovsrcu_postpone(rt_entry_free, ovs_router_entry_cast(cr));
>  }
>  
> @@ -360,20 +422,25 @@ static bool
>  rt_entry_delete(uint32_t mark, uint8_t priority,
>                  const struct in6_addr *ip6_dst, uint8_t plen)
>  {
> +    struct classifier *cls_main = cls_find(CLS_MAIN);
>      const struct cls_rule *cr;
>      struct cls_rule rule;
>      struct match match;
>      bool res = false;
>  
> +    if (!cls_main) {
> +        return false;
> +    }
> +
>      rt_init_match(&match, mark, ip6_dst, plen);
>  
>      cls_rule_init(&rule, &match, priority);
>  
>      /* Find the exact rule. */
> -    cr = classifier_find_rule_exactly(&cls, &rule, OVS_VERSION_MAX);
> +    cr = classifier_find_rule_exactly(cls_main, &rule, OVS_VERSION_MAX);
>      if (cr) {
>          ovs_mutex_lock(&mutex);
> -        rt_entry_delete__(cr);
> +        rt_entry_delete__(cr, cls_main);
>          ovs_mutex_unlock(&mutex);
>  
>          res = true;
> @@ -469,8 +536,8 @@ ovs_router_add(struct unixctl_conn *conn, int argc,
>          in6_addr_set_mapped_ipv4(&src6, src);
>      }
>  
> -    err = ovs_router_insert__(mark, plen + 32, false, &ip6, plen, argv[2],
> -                              &gw6, &src6);
> +    err = ovs_router_insert__(CLS_MAIN, mark, plen + 32, false, &ip6, plen,
> +                              argv[2], &gw6, &src6);
>      if (err) {
>          unixctl_command_reply_error(conn, "Error while inserting route.");
>      } else {
> @@ -512,12 +579,19 @@ ovs_router_del(struct unixctl_conn *conn, int argc 
> OVS_UNUSED,
>  static void
>  ovs_router_show_json(struct json **routes)
>  {
> -    int n_rules = classifier_count(&cls);
>      struct json **json_entries = NULL;
>      struct ovs_router_entry *rt;
> +    struct classifier *cls_main;
>      struct ds ds;
> +    int n_rules;
>      int i = 0;
>  
> +    cls_main = cls_find(CLS_MAIN);
> +    if (!cls_main) {
> +        goto out;
> +    }
> +
> +    n_rules = classifier_count(cls_main);
>      if (!n_rules) {
>          goto out;
>      }
> @@ -525,7 +599,7 @@ ovs_router_show_json(struct json **routes)
>      json_entries = xmalloc(n_rules * sizeof *json_entries);
>      ds_init(&ds);
>  
> -    CLS_FOR_EACH (rt, cr, &cls) {
> +    CLS_FOR_EACH (rt, cr, cls_main) {
>          bool user = rt->priority != rt->plen && !rt->local;
>          uint8_t plen = rt->plen;
>          struct json *json, *nh;
> @@ -579,9 +653,15 @@ static void
>  ovs_router_show_text(struct ds *ds)
>  {
>      struct ovs_router_entry *rt;
> +    struct classifier *cls_main;
> +
> +    cls_main = cls_find(CLS_MAIN);
> +    if (!cls_main) {
> +        return;
> +    }
>  
>      ds_put_format(ds, "Route Table:\n");
> -    CLS_FOR_EACH (rt, cr, &cls) {
> +    CLS_FOR_EACH (rt, cr, cls_main) {
>          uint8_t plen;
>          if (rt->priority == rt->plen || rt->local) {
>              ds_put_format(ds, "Cached: ");
> @@ -668,27 +748,46 @@ ovs_router_lookup_cmd(struct unixctl_conn *conn, int 
> argc,
>      }
>  }
>  
> -void
> -ovs_router_flush(void)
> +static void
> +clsmap_node_destroy_cb(struct clsmap_node *node)
>  {
> -    struct ovs_router_entry *rt;
> +    classifier_destroy(&node->cls);
> +    ovsrcu_postpone(free, node);
> +}
>  
> -    ovs_mutex_lock(&mutex);
> -    classifier_defer(&cls);
> -    CLS_FOR_EACH(rt, cr, &cls) {
> -        if (rt->priority == rt->plen || rt->local) {
> -            rt_entry_delete__(&rt->cr);
> +static void
> +ovs_router_flush_protected(bool flush_all)
> +    OVS_REQUIRES(mutex)
> +{
> +    struct clsmap_node *node;
> +
> +    CMAP_FOR_EACH (node, cmap_node, &clsmap) {
> +        cls_flush(&node->cls, flush_all);
> +        if (!node->cls.n_rules) {
> +            cmap_remove(&clsmap, &node->cmap_node, hash_int(node->table, 0));
> +            ovsrcu_postpone(clsmap_node_destroy_cb, node);
>          }
>      }
> -    classifier_publish(&cls);
> -    ovs_mutex_unlock(&mutex);
>      seq_change(tnl_conf_seq);
>  }
>  
> +void
> +ovs_router_flush(bool flush_all)
> +{
> +    ovs_mutex_lock(&mutex);
> +    ovs_router_flush_protected(flush_all);
> +    ovs_mutex_unlock(&mutex);
> +}
> +
>  static void
>  ovs_router_flush_handler(void *aux OVS_UNUSED)
>  {
> -    ovs_router_flush();
> +    ovs_mutex_lock(&mutex);
> +    ovs_router_flush_protected(true);
> +    ovs_assert(cmap_is_empty(&clsmap));
> +    cmap_destroy(&clsmap);
> +    cmap_init(&clsmap);
> +    ovs_mutex_unlock(&mutex);
>  }
>  
>  void
> @@ -698,7 +797,6 @@ ovs_router_init(void)
>  
>      if (ovsthread_once_start(&once)) {
>          fatal_signal_add_hook(ovs_router_flush_handler, NULL, NULL, true);
> -        classifier_init(&cls, NULL);
>          unixctl_command_register("ovs/route/add",
>                                   "ip/plen dev [gw] "
>                                   "[pkt_mark=mark] [src=src_ip]",
> diff --git a/lib/ovs-router.h b/lib/ovs-router.h
> index b61712707b1e..f4e6487d3dc6 100644
> --- a/lib/ovs-router.h
> +++ b/lib/ovs-router.h
> @@ -26,20 +26,27 @@
>  extern "C" {
>  #endif
>  
> +enum {
> +    CLS_MAIN = 254,
> +    CLS_ALL = UINT32_MAX,
> +};
> +
>  bool ovs_router_lookup(uint32_t mark, const struct in6_addr *ip_dst,
>                         char output_netdev[],
>                         struct in6_addr *src, struct in6_addr *gw);
>  void ovs_router_init(void);
> -void ovs_router_insert(uint32_t mark, const struct in6_addr *ip_dst,
> +void ovs_router_insert(uint32_t table, uint32_t mark,
> +                       const struct in6_addr *ip_dst,
>                         uint8_t plen, bool local,
>                         const char output_netdev[], const struct in6_addr *gw,
>                         const struct in6_addr *prefsrc);
> -void ovs_router_force_insert(uint32_t mark, const struct in6_addr *ip_dst,
> +void ovs_router_force_insert(uint32_t table, uint32_t mark,
> +                             const struct in6_addr *ip_dst,
>                               uint8_t plen, bool local,
>                               const char output_netdev[],
>                               const struct in6_addr *gw,
>                               const struct in6_addr *prefsrc);
> -void ovs_router_flush(void);
> +void ovs_router_flush(bool flush_all);
>  
>  void ovs_router_disable_system_routing_table(void);
>  
> diff --git a/lib/route-table.c b/lib/route-table.c
> index ca87ff7dbba4..0e77a9c9325e 100644
> --- a/lib/route-table.c
> +++ b/lib/route-table.c
> @@ -57,6 +57,8 @@ VLOG_DEFINE_THIS_MODULE(route_table);
>  
>  COVERAGE_DEFINE(route_table_dump);
>  
> +BUILD_ASSERT_DECL((enum rt_class_t) CLS_MAIN == RT_TABLE_MAIN);
> +
>  static struct ovs_mutex route_table_mutex = OVS_MUTEX_INITIALIZER;
>  static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 20);
>  
> @@ -565,7 +567,7 @@ route_table_handle_msg(const struct route_table_msg 
> *change,
>          rdnh = CONTAINER_OF(ovs_list_front(&change->rd.nexthops),
>                              const struct route_data_nexthop, nexthop_node);
>  
> -        ovs_router_insert(rd->rta_mark, &rd->rta_dst,
> +        ovs_router_insert(CLS_MAIN, rd->rta_mark, &rd->rta_dst,
>                            IN6_IS_ADDR_V4MAPPED(&rd->rta_dst)
>                            ? rd->rtm_dst_len + 96 : rd->rtm_dst_len,
>                            rd->rtn_local, rdnh->ifname, &rdnh->addr,
> @@ -576,7 +578,7 @@ route_table_handle_msg(const struct route_table_msg 
> *change,
>  static void
>  route_map_clear(void)
>  {
> -    ovs_router_flush();
> +    ovs_router_flush(false);
>  }
>  
>  bool
> diff --git a/tests/nsh.at b/tests/nsh.at
> index 022540dd68a4..3a2f2ed06774 100644
> --- a/tests/nsh.at
> +++ b/tests/nsh.at
> @@ -557,9 +557,12 @@ AT_CHECK([
>  AT_CHECK([
>      ovs-appctl ovs/route/show | grep Cached: | sort
>  ], [0], [dnl
> -Cached: 10.0.0.0/24 dev br-p1 SRC 10.0.0.1 local
> -Cached: 20.0.0.0/24 dev br-p2 SRC 20.0.0.2 local
> -Cached: 30.0.0.0/24 dev br-p3 SRC 30.0.0.3 local
> +Cached: 10.0.0.0/24 dev br-p1 SRC 10.0.0.1
> +Cached: 10.0.0.1/32 dev br-p1 SRC 10.0.0.1 local
> +Cached: 20.0.0.0/24 dev br-p2 SRC 20.0.0.2
> +Cached: 20.0.0.2/32 dev br-p2 SRC 20.0.0.2 local
> +Cached: 30.0.0.0/24 dev br-p3 SRC 30.0.0.3
> +Cached: 30.0.0.3/32 dev br-p3 SRC 30.0.0.3 local
>  ])
>  
>  AT_CHECK([
> diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at
> index 7ebbee56d9e6..319640aee5cb 100644
> --- a/tests/ofproto-dpif.at
> +++ b/tests/ofproto-dpif.at
> @@ -8510,7 +8510,8 @@ AT_CHECK([ovs-appctl netdev-dummy/ip4addr br0 
> 1.1.2.88/24], [0], [OK
>  AT_CHECK([ovs-ofctl add-flow br0 action=normal])
>  dnl Checking that a local route for added IP was successfully installed.
>  AT_CHECK([ovs-appctl ovs/route/show | grep Cached], [0], [dnl

Need to add sort to the end, as these are still stored in a single
classifier and the order is not defined.  This will be less important
with the next patches, but seems less brittle nevertheless.

> -Cached: 1.1.2.0/24 dev br0 SRC 1.1.2.88 local
> +Cached: 1.1.2.88/32 dev br0 SRC 1.1.2.88 local
> +Cached: 1.1.2.0/24 dev br0 SRC 1.1.2.88
>  ])
>  
>  dnl Prime ARP Cache for 1.1.2.92
> @@ -8527,8 +8528,10 @@ AT_CHECK([ovs-appctl netdev-dummy/ip4addr br0 
> 192.168.1.1/16], [0], [OK
>  ])
>  dnl Checking that a local route for added IP was successfully installed.
>  AT_CHECK([ovs-appctl ovs/route/show | grep Cached | sort], [0], [dnl
> -Cached: 1.1.2.0/24 dev br0 SRC 1.1.2.88 local
> -Cached: 192.168.0.0/16 dev br0 SRC 192.168.1.1 local
> +Cached: 1.1.2.0/24 dev br0 SRC 1.1.2.88
> +Cached: 1.1.2.88/32 dev br0 SRC 1.1.2.88 local
> +Cached: 192.168.0.0/16 dev br0 SRC 192.168.1.1
> +Cached: 192.168.1.1/32 dev br0 SRC 192.168.1.1 local
>  ])
>  
>  dnl add rule for int-br to force packet onto tunnel. There is no ifindex
> diff --git a/tests/ovs-router.at b/tests/ovs-router.at
> index 641b780a582a..d5f56da786d9 100644
> --- a/tests/ovs-router.at
> +++ b/tests/ovs-router.at
> @@ -31,14 +31,35 @@ User: 2.2.2.3/32 MARK 1 dev br0 SRC 2.2.2.2
>  AT_CHECK([ovs-appctl --format=json --pretty ovs/route/show], [0], [dnl
>  [[
>    {
> -    "dst": "2.2.2.0",
> +    "dst": "2.2.2.2",
>      "local": true,
> +    "nexthops": [
> +      {
> +        "dev": "br0"}],
> +    "prefix": 32,
> +    "prefsrc": "2.2.2.2",
> +    "priority": 192,
> +    "user": false},
> +  {
> +    "dst": "2.2.2.3",
> +    "local": false,
> +    "mark": 1,
> +    "nexthops": [
> +      {
> +        "dev": "br0"}],
> +    "prefix": 32,
> +    "prefsrc": "2.2.2.2",
> +    "priority": 160,
> +    "user": true},
> +  {
> +    "dst": "2.2.2.0",
> +    "local": false,
>      "nexthops": [
>        {
>          "dev": "br0"}],
>      "prefix": 24,
>      "prefsrc": "2.2.2.2",
> -    "priority": 184,
> +    "priority": 120,
>      "user": false},
>    {
>      "dst": "1.1.1.0",
> @@ -62,17 +83,6 @@ AT_CHECK([ovs-appctl --format=json --pretty 
> ovs/route/show], [0], [dnl
>      "prefix": 24,
>      "prefsrc": "2.2.2.2",
>      "priority": 152,
> -    "user": true},
> -  {
> -    "dst": "2.2.2.3",
> -    "local": false,
> -    "mark": 1,
> -    "nexthops": [
> -      {
> -        "dev": "br0"}],
> -    "prefix": 32,
> -    "prefsrc": "2.2.2.2",
> -    "priority": 160,
>      "user": true}]]
>  ])
>  OVS_VSWITCHD_STOP
> diff --git a/tests/packet-type-aware.at b/tests/packet-type-aware.at
> index cebd8e6eeb46..300b17209d83 100644
> --- a/tests/packet-type-aware.at
> +++ b/tests/packet-type-aware.at
> @@ -160,9 +160,12 @@ AT_CHECK([
>  AT_CHECK([
>      ovs-appctl ovs/route/show | grep Cached: | sort
>  ], [0], [dnl
> -Cached: 10.0.0.0/24 dev br-p1 SRC 10.0.0.1 local
> -Cached: 20.0.0.0/24 dev br-p2 SRC 20.0.0.2 local
> -Cached: 30.0.0.0/24 dev br-p3 SRC 30.0.0.3 local
> +Cached: 10.0.0.0/24 dev br-p1 SRC 10.0.0.1
> +Cached: 10.0.0.1/32 dev br-p1 SRC 10.0.0.1 local
> +Cached: 20.0.0.0/24 dev br-p2 SRC 20.0.0.2
> +Cached: 20.0.0.2/32 dev br-p2 SRC 20.0.0.2 local
> +Cached: 30.0.0.0/24 dev br-p3 SRC 30.0.0.3
> +Cached: 30.0.0.3/32 dev br-p3 SRC 30.0.0.3 local
>  ])
>  
>  AT_CHECK([
> @@ -684,7 +687,8 @@ AT_CHECK([
>  AT_CHECK([
>      ovs-appctl ovs/route/show | grep Cached:

sort

>  ], [0], [dnl
> -Cached: 10.0.0.0/24 dev br2 SRC 10.0.0.1 local
> +Cached: 10.0.0.1/32 dev br2 SRC 10.0.0.1 local
> +Cached: 10.0.0.0/24 dev br2 SRC 10.0.0.1
>  ])
>  
>  
> @@ -960,7 +964,8 @@ ovs-appctl time/warp 1000
>  AT_CHECK([
>      ovs-appctl ovs/route/show | grep Cached:

sort

>  ],[0], [dnl
> -Cached: 20.0.0.0/24 dev br0 SRC 20.0.0.1 local
> +Cached: 20.0.0.1/32 dev br0 SRC 20.0.0.1 local
> +Cached: 20.0.0.0/24 dev br0 SRC 20.0.0.1
>  ])
>  
>  AT_CHECK([
> diff --git a/tests/tunnel-push-pop-ipv6.at b/tests/tunnel-push-pop-ipv6.at
> index 39fbd2d35f55..2c8c9d9fb881 100644
> --- a/tests/tunnel-push-pop-ipv6.at
> +++ b/tests/tunnel-push-pop-ipv6.at
> @@ -24,7 +24,8 @@ AT_CHECK([ovs-appctl netdev-dummy/ip6addr br0 
> 2001:cafe::88/24], [0], [OK
>  ])
>  dnl Checking that a local routes for added IPs were successfully installed.
>  AT_CHECK([ovs-appctl ovs/route/show | grep Cached], [0], [dnl

sort

> -Cached: 2001:ca00::/24 dev br0 SRC 2001:cafe::88 local
> +Cached: 2001:cafe::88/128 dev br0 SRC 2001:cafe::88 local
> +Cached: 2001:ca00::/24 dev br0 SRC 2001:cafe::88
>  ])
>  AT_CHECK([ovs-appctl tnl/neigh/set br0 2001:cafe::91 aa:55:aa:55:00:01], 
> [0], [OK
>  ])
> @@ -113,8 +114,10 @@ AT_CHECK([ovs-appctl netdev-dummy/ip4addr br0 
> 1.1.2.88/24], [0], [OK
>  ])
>  dnl Checking that a local routes for added IPs were successfully installed.
>  AT_CHECK([ovs-appctl ovs/route/show | grep Cached | sort], [0], [dnl
> -Cached: 1.1.2.0/24 dev br0 SRC 1.1.2.88 local
> -Cached: 2001:ca00::/24 dev br0 SRC 2001:cafe::88 local
> +Cached: 1.1.2.0/24 dev br0 SRC 1.1.2.88
> +Cached: 1.1.2.88/32 dev br0 SRC 1.1.2.88 local
> +Cached: 2001:ca00::/24 dev br0 SRC 2001:cafe::88
> +Cached: 2001:cafe::88/128 dev br0 SRC 2001:cafe::88 local
>  ])
>  
>  AT_CHECK([ovs-ofctl add-flow br0 action=normal])
> @@ -189,8 +192,10 @@ AT_CHECK([ovs-appctl netdev-dummy/ip4addr br0 
> 1.1.2.88/24], [0], [OK
>  ])
>  dnl Checking that a local routes for added IPs were successfully installed.
>  AT_CHECK([ovs-appctl ovs/route/show | grep Cached | sort], [0], [dnl
> -Cached: 1.1.2.0/24 dev br0 SRC 1.1.2.88 local
> -Cached: 2001:ca00::/24 dev br0 SRC 2001:cafe::88 local
> +Cached: 1.1.2.0/24 dev br0 SRC 1.1.2.88
> +Cached: 1.1.2.88/32 dev br0 SRC 1.1.2.88 local
> +Cached: 2001:ca00::/24 dev br0 SRC 2001:cafe::88
> +Cached: 2001:cafe::88/128 dev br0 SRC 2001:cafe::88 local
>  ])
>  
>  AT_CHECK([ovs-ofctl add-flow br0 action=normal])
> @@ -328,8 +333,10 @@ AT_CHECK([ovs-appctl netdev-dummy/ip4addr br0 
> 1.1.2.88/24], [0], [OK
>  ])
>  dnl Checking that a local routes for added IPs were successfully installed.
>  AT_CHECK([ovs-appctl ovs/route/show | grep Cached | sort], [0], [dnl
> -Cached: 1.1.2.0/24 dev br0 SRC 1.1.2.88 local
> -Cached: 2001:ca00::/24 dev br0 SRC 2001:cafe::88 local
> +Cached: 1.1.2.0/24 dev br0 SRC 1.1.2.88
> +Cached: 1.1.2.88/32 dev br0 SRC 1.1.2.88 local
> +Cached: 2001:ca00::/24 dev br0 SRC 2001:cafe::88
> +Cached: 2001:cafe::88/128 dev br0 SRC 2001:cafe::88 local
>  ])
>  
>  AT_CHECK([ovs-ofctl add-flow br0 action=normal])
> @@ -701,8 +708,10 @@ AT_CHECK([ovs-appctl netdev-dummy/ip6addr br0 
> 2001:beef::88/64], [0], [OK
>  ])
>  dnl Checking that a local route for added IP was successfully installed.
>  AT_CHECK([ovs-appctl ovs/route/show | grep Cached | sort], [0], [dnl
> -Cached: 2001:beef::/64 dev br0 SRC 2001:beef::88 local
> -Cached: 2001:cafe::/64 dev br0 SRC 2001:cafe::88 local
> +Cached: 2001:beef::/64 dev br0 SRC 2001:beef::88
> +Cached: 2001:beef::88/128 dev br0 SRC 2001:beef::88 local
> +Cached: 2001:cafe::/64 dev br0 SRC 2001:cafe::88
> +Cached: 2001:cafe::88/128 dev br0 SRC 2001:cafe::88 local
>  ])
>  AT_CHECK([ovs-ofctl add-flow br0 action=normal])
>  AT_CHECK([ovs-ofctl add-flow int-br action=normal])
> @@ -784,7 +793,8 @@ AT_CHECK([ovs-appctl netdev-dummy/ip6addr br0 
> 2001:cafe::88/64], [0], [OK
>  ])
>  dnl Checking that a local route for added IP was successfully installed.
>  AT_CHECK([ovs-appctl ovs/route/show | grep Cached | sort], [0], [dnl
> -Cached: 2001:cafe::/64 dev br0 SRC 2001:cafe::88 local
> +Cached: 2001:cafe::/64 dev br0 SRC 2001:cafe::88
> +Cached: 2001:cafe::88/128 dev br0 SRC 2001:cafe::88 local
>  ])
>  
>  dnl Add a dp-hash selection group.
> diff --git a/tests/tunnel-push-pop.at b/tests/tunnel-push-pop.at
> index 795817d62246..4108cc4a7dac 100644
> --- a/tests/tunnel-push-pop.at
> +++ b/tests/tunnel-push-pop.at
> @@ -37,8 +37,10 @@ AT_CHECK([ovs-appctl netdev-dummy/ip6addr br0 
> 2001:cafe::88/24], [0], [OK
>  ])
>  dnl Checking that a local routes for added IPs were successfully installed.
>  AT_CHECK([ovs-appctl ovs/route/show | grep Cached | sort], [0], [dnl
> -Cached: 1.1.2.0/24 dev br0 SRC 1.1.2.88 local
> -Cached: 2001:ca00::/24 dev br0 SRC 2001:cafe::88 local
> +Cached: 1.1.2.0/24 dev br0 SRC 1.1.2.88
> +Cached: 1.1.2.88/32 dev br0 SRC 1.1.2.88 local
> +Cached: 2001:ca00::/24 dev br0 SRC 2001:cafe::88
> +Cached: 2001:cafe::88/128 dev br0 SRC 2001:cafe::88 local
>  ])
>  
>  AT_CHECK([ovs-ofctl add-flow br0 action=normal])
> @@ -241,8 +243,10 @@ AT_CHECK([ovs-appctl ovs/route/add 1.1.2.92/24 br0 
> pkt_mark=1234], [0], [OK
>  dnl Checking that local routes for added IPs and the static route with a mark
>  dnl were successfully installed.
>  AT_CHECK([ovs-appctl ovs/route/show | grep br0 | sort], [0], [dnl
> -Cached: 1.1.2.0/24 dev br0 SRC 1.1.2.88 local
> -Cached: 2001:ca00::/24 dev br0 SRC 2001:cafe::88 local
> +Cached: 1.1.2.0/24 dev br0 SRC 1.1.2.88
> +Cached: 1.1.2.88/32 dev br0 SRC 1.1.2.88 local
> +Cached: 2001:ca00::/24 dev br0 SRC 2001:cafe::88
> +Cached: 2001:cafe::88/128 dev br0 SRC 2001:cafe::88 local
>  User: 1.1.2.0/24 MARK 1234 dev br0 SRC 1.1.2.88
>  ])
>  
> @@ -778,7 +782,8 @@ AT_CHECK([ovs-appctl netdev-dummy/ip4addr br0 
> 1.1.2.88/24], [0], [OK
>  ])
>  dnl Checking that a local route for added IP was successfully installed.
>  AT_CHECK([ovs-appctl ovs/route/show | grep Cached], [0], [dnl

sort

> -Cached: 1.1.2.0/24 dev br0 SRC 1.1.2.88 local
> +Cached: 1.1.2.88/32 dev br0 SRC 1.1.2.88 local
> +Cached: 1.1.2.0/24 dev br0 SRC 1.1.2.88
>  ])
>  
>  AT_CHECK([ovs-ofctl add-flow br0 action=normal])
> @@ -821,7 +826,8 @@ AT_CHECK([ovs-appctl netdev-dummy/ip4addr br0 
> 1.1.2.88/24], [0], [OK
>  ])
>  dnl Checking that a local route for added IP was successfully installed.
>  AT_CHECK([ovs-appctl ovs/route/show | grep Cached], [0], [dnl

sort

> -Cached: 1.1.2.0/24 dev br0 SRC 1.1.2.88 local
> +Cached: 1.1.2.88/32 dev br0 SRC 1.1.2.88 local
> +Cached: 1.1.2.0/24 dev br0 SRC 1.1.2.88
>  ])
>  AT_CHECK([ovs-ofctl add-flow br0 action=normal])
>  AT_CHECK([ovs-appctl revalidator/wait])
> @@ -896,8 +902,10 @@ AT_CHECK([ovs-appctl netdev-dummy/ip4addr br0 
> 2.2.2.88/24], [0], [OK
>  ])
>  dnl Checking that a local route for added IP was successfully installed.
>  AT_CHECK([ovs-appctl ovs/route/show | grep Cached | sort], [0], [dnl
> -Cached: 1.1.2.0/24 dev br0 SRC 1.1.2.88 local
> -Cached: 2.2.2.0/24 dev br0 SRC 2.2.2.88 local
> +Cached: 1.1.2.0/24 dev br0 SRC 1.1.2.88
> +Cached: 1.1.2.88/32 dev br0 SRC 1.1.2.88 local
> +Cached: 2.2.2.0/24 dev br0 SRC 2.2.2.88
> +Cached: 2.2.2.88/32 dev br0 SRC 2.2.2.88 local
>  ])
>  AT_CHECK([ovs-ofctl add-flow br0 action=normal])
>  AT_CHECK([ovs-ofctl add-flow int-br action=normal])
> @@ -979,7 +987,8 @@ AT_CHECK([ovs-appctl netdev-dummy/ip4addr br0 
> 1.1.2.88/24], [0], [OK
>  ])
>  dnl Checking that a local route for added IP was successfully installed.
>  AT_CHECK([ovs-appctl ovs/route/show | grep Cached], [0], [dnl

sort

> -Cached: 1.1.2.0/24 dev br0 SRC 1.1.2.88 local
> +Cached: 1.1.2.88/32 dev br0 SRC 1.1.2.88 local
> +Cached: 1.1.2.0/24 dev br0 SRC 1.1.2.88
>  ])
>  
>  AT_CHECK([ovs-ofctl add-flow br0 'arp,priority=1,action=normal'])
> @@ -1031,7 +1040,8 @@ AT_CHECK([ovs-appctl netdev-dummy/ip4addr br0 
> 1.1.2.88/24], [0], [OK
>  ])
>  dnl Checking that a local route for added IP was successfully installed.
>  AT_CHECK([ovs-appctl ovs/route/show | grep Cached], [0], [dnl

sort

> -Cached: 1.1.2.0/24 dev br0 SRC 1.1.2.88 local
> +Cached: 1.1.2.88/32 dev br0 SRC 1.1.2.88 local
> +Cached: 1.1.2.0/24 dev br0 SRC 1.1.2.88
>  ])
>  AT_CHECK([ovs-ofctl add-flow br0 action=normal])
>  AT_CHECK([ovs-appctl revalidator/wait])
> @@ -1101,7 +1111,8 @@ AT_CHECK([ovs-appctl netdev-dummy/ip4addr br0 
> 10.0.0.2/24], [0], [OK
>  ])
>  dnl Checking that a local route for added IP was successfully installed.
>  AT_CHECK([ovs-appctl ovs/route/show | grep Cached], [0], [dnl

sort

> -Cached: 10.0.0.0/24 dev br0 SRC 10.0.0.2 local
> +Cached: 10.0.0.2/32 dev br0 SRC 10.0.0.2 local
> +Cached: 10.0.0.0/24 dev br0 SRC 10.0.0.2
>  ])
>  
>  dnl Send an ARP reply to port b8 on br0, so that packets will be forwarded
> @@ -1149,7 +1160,8 @@ AT_CHECK([ovs-appctl netdev-dummy/ip4addr br0 
> 10.0.0.2/24], [0], [OK
>  ])
>  dnl Checking that a local route for added IP was successfully installed.
>  AT_CHECK([ovs-appctl ovs/route/show | grep Cached], [0], [dnl

sort

> -Cached: 10.0.0.0/24 dev br0 SRC 10.0.0.2 local
> +Cached: 10.0.0.2/32 dev br0 SRC 10.0.0.2 local
> +Cached: 10.0.0.0/24 dev br0 SRC 10.0.0.2
>  ])
>  
>  dnl Send an ARP reply to port b8 on br0, so that packets will be forwarded
> @@ -1223,7 +1235,8 @@ AT_CHECK([ovs-appctl netdev-dummy/ip4addr vtep0 
> 1.1.2.88/24], [0], [OK
>  ])
>  dnl Checking that a local route for added IP was successfully installed.
>  AT_CHECK([ovs-appctl ovs/route/show | grep Cached], [0], [dnl

sort

> -Cached: 1.1.2.0/24 dev vtep0 SRC 1.1.2.88 local
> +Cached: 1.1.2.88/32 dev vtep0 SRC 1.1.2.88 local
> +Cached: 1.1.2.0/24 dev vtep0 SRC 1.1.2.88
>  ])
>  
>  AT_CHECK([ovs-ofctl add-flow br0 action=normal])
> @@ -1288,7 +1301,8 @@ AT_CHECK([ovs-appctl netdev-dummy/ip4addr br0 
> 1.1.2.88/24], [0], [OK
>  ])
>  dnl Checking that a local route for added IP was successfully installed.
>  AT_CHECK([ovs-appctl ovs/route/show | grep Cached | sort], [0], [dnl
> -Cached: 1.1.2.0/24 dev br0 SRC 1.1.2.88 local
> +Cached: 1.1.2.0/24 dev br0 SRC 1.1.2.88
> +Cached: 1.1.2.88/32 dev br0 SRC 1.1.2.88 local
>  ])
>  
>  dnl Add a dp-hash selection group.
> diff --git a/tests/tunnel.at b/tests/tunnel.at
> index e1a16138fa29..be022f3a087c 100644
> --- a/tests/tunnel.at
> +++ b/tests/tunnel.at
> @@ -529,7 +529,8 @@ AT_CHECK([ovs-appctl netdev-dummy/ip4addr br0 
> 172.31.1.1/24], [0], [OK
>  ])
>  dnl Checking that a local route for added IP was successfully installed.
>  AT_CHECK([ovs-appctl ovs/route/show | grep Cached], [0], [dnl

sort

> -Cached: 172.31.1.0/24 dev br0 SRC 172.31.1.1 local
> +Cached: 172.31.1.1/32 dev br0 SRC 172.31.1.1 local
> +Cached: 172.31.1.0/24 dev br0 SRC 172.31.1.1
>  ])
>  
>  dnl change the flow table to bump the internal table version
> @@ -1286,7 +1287,8 @@ AT_CHECK([ovs-appctl netdev-dummy/ip6addr br0 
> fc00::1/64], [0], [OK
>  ])
>  dnl Checking that a local route for added IP was successfully installed.
>  AT_CHECK([ovs-appctl ovs/route/show | grep Cached], [0], [dnl

sort

> -Cached: fc00::/64 dev br0 SRC fc00::1 local
> +Cached: fc00::1/128 dev br0 SRC fc00::1 local
> +Cached: fc00::/64 dev br0 SRC fc00::1
>  ])
>  
>  AT_DATA([flows.txt], [dnl

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

Reply via email to