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