On Dec 17, Dumitru Ceara wrote:
> On 12/16/25 4:32 PM, Lorenzo Bianconi wrote:
> > Introduce the capability to specify multiple ips for ovn-evpn-local-ip
> > option in order to enable dual-stack for EVPN vxlan tunnels.
> > The IPs used for vxlan tunnel can be specified using the following
> > syntax in the external_ids column of Open_vSwitch table:
> > 
> > external_ids:ovn-evpn-local-ip=10:1.1.1.1,20:[2::2],30:3.3.3.3,40:[4::4],30:[3::3]
> > 
> > Reported-at: https://issues.redhat.com/browse/FDP-2768
> > Signed-off-by: Lorenzo Bianconi <[email protected]>
> > ---
> 
> Hi Lorenzo,
> 
> Thanks for the patch!

Hi Dumitru,

thx for the review.

> 
> >  controller/physical.c | 155 +++++++++---
> >  tests/system-ovn.at   | 534 ++++++++++++++++++++++++++++++++++++++++++
> 
> We also need a NEWS item for this new feature.
> 
> We should also update the documentation about ovn-evpn-local-ip in
> ovn-controller.8.xml and also update the TODO.rst file removing the item
> we had for this feature.

ack, I will fix in v2.

> 
> >  2 files changed, 651 insertions(+), 38 deletions(-)
> > 
> > diff --git a/controller/physical.c b/controller/physical.c
> > index b9c60c8ab..8f66f1774 100644
> > --- a/controller/physical.c
> > +++ b/controller/physical.c
> > @@ -3178,13 +3178,87 @@ physical_eval_remote_chassis_flows(const struct 
> > physical_ctx *ctx,
> >      ofpbuf_uninit(&ingress_ofpacts);
> >  }
> >  
> > +#define DEFAULT_VNI     (1 << 24) /* VNI used for the default local IP. */
> > +struct vni_local_ip {
> > +    struct in6_addr ip;
> > +    uint32_t vni;
> > +};
> > +
> > +static struct in6_addr *
> > +evpn_local_ip_lookup_by_vni(const struct vector *map,
> > +                            uint32_t vni, bool ipv4)
> > +{
> > +    struct vni_local_ip *e, *def_e = NULL;
> > +    VECTOR_FOR_EACH_PTR (map, e) {
> > +        if (e->vni == vni && IN6_IS_ADDR_V4MAPPED(&e->ip) == ipv4) {
> > +            return &e->ip;
> > +        }
> > +        if (e->vni == DEFAULT_VNI) {
> > +            def_e = e;
> > +        }
> > +    }
> > +
> > +    return def_e ? &def_e->ip : NULL;
> 
> At this point, def_e->ip's family might not match the requested family
> (argument "ipv4").  I guess we need to check that too.
> 
> > +}
> > +
> > +static void
> > +evpn_vni_local_ip_map_parse(struct vector *map, const char *local_ip_str)
> > +{
> > +    char *tokstr = xstrdup(local_ip_str);
> > +    char *token, *ptr0 = NULL;
> > +
> > +    for (token = strtok_r(tokstr, ",", &ptr0); token;
> > +         token = strtok_r(NULL, ",", &ptr0)) {
> > +        char *ptr1 = NULL, *vni_str = strtok_r(token, ":", &ptr1);
> > +        char *ip_str = strtok_r(NULL, "", &ptr1);
> > +        char *ip_address = NULL;
> > +        struct vni_local_ip e = {
> > +            .vni = DEFAULT_VNI,
> > +        };
> > +        int addr_family;
> > +        uint16_t port;
> > +
> > +        if (!ip_str) {
> > +            /* Default local IP. */
> > +            ip_str = vni_str;
> > +            vni_str = NULL;
> > +        }
> > +
> > +        if (!ip_address_and_port_from_lb_key(ip_str, &ip_address, &e.ip, 
> > &port,
> > +                                             &addr_family)) {
> 
> It's odd to use ip_address_and_port_from_lb_key().  That's a LB specific
> function that also allows TCP/UDP ports to be listed after the IP
> address.  Let's add a new helper in ovn-util.[ch] that uses
> inet_parse_active() and ss_format_address_nobracks() and errors out if
> port is specified.

ack, I will fix it in v2.

> 
> > +            static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1);
> > +            VLOG_WARN_RL(&rl, "EVPN enabled, but required 'evpn-local-ip' 
> > is "
> > +                         "missing or invalid %s ", local_ip_str);
> > +            continue;
> > +        }
> > +        free(ip_address);
> > +
> > +        if (vni_str) {
> > +            if (!ovs_scan(vni_str, "%u", &e.vni) || 
> > !ovn_is_valid_vni(e.vni)) {
> > +                continue;
> > +            }
> > +        }
> > +        vector_push(map, &e);
> > +    }
> > +    free(tokstr);
> > +}
> > +
> >  static void
> >  physical_consider_evpn_binding(const struct evpn_binding *binding,
> > -                               const struct in6_addr *local_ip,
> > +                               const struct vector *vni_ip_map,
> >                                 struct ofpbuf *ofpacts, struct match *match,
> > -                               struct ovn_desired_flow_table *flow_table,
> > -                               bool ipv4)
> > +                               struct ovn_desired_flow_table *flow_table)
> >  {
> > +    bool ipv4 = IN6_IS_ADDR_V4MAPPED(&binding->remote_ip);
> > +    const struct in6_addr *local_ip = 
> > evpn_local_ip_lookup_by_vni(vni_ip_map,
> > +                                                                  
> > binding->vni,
> > +                                                                  ipv4);
> > +    if (!local_ip) {
> > +        static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1);
> > +        VLOG_WARN_RL(&rl, "failed to get local tunnel ip");
> > +        return;
> > +    }
> > +
> >      /* Ingress flows. */
> >      ofpbuf_clear(ofpacts);
> >      match_init_catchall(match);
> > @@ -3308,29 +3382,40 @@ physical_consider_evpn_binding(const struct 
> > evpn_binding *binding,
> >  
> >  static void
> >  physical_consider_evpn_multicast(const struct evpn_multicast_group 
> > *mc_group,
> > -                                 const struct in6_addr *local_ip,
> > +                                 const struct vector *vni_ip_map,
> >                                   struct ofpbuf *ofpacts, struct match 
> > *match,
> > -                                 struct ovn_desired_flow_table *flow_table,
> > -                                 bool ipv4)
> > +                                 struct ovn_desired_flow_table *flow_table)
> >  {
> >      const struct evpn_binding *binding = NULL;
> > +    const struct in6_addr *local_ip = NULL;
> >  
> >      ofpbuf_clear(ofpacts);
> >      uint32_t multicast_tunnel_keys[] = {OVN_MCAST_FLOOD_TUNNEL_KEY,
> >                                          OVN_MCAST_UNKNOWN_TUNNEL_KEY,
> >                                          OVN_MCAST_FLOOD_L2_TUNNEL_KEY};
> > -    if (ipv4) {
> > -        ovs_be32 ip4 = in6_addr_get_mapped_ipv4(local_ip);
> > -        put_load_bytes(&ip4, sizeof ip4, MFF_TUN_SRC, 0, 32, ofpacts);
> > -    } else {
> > -        put_load_bytes(local_ip, sizeof *local_ip, MFF_TUN_IPV6_SRC,
> > -                       0, 128, ofpacts);
> > -    }
> > -    put_load(mc_group->vni, MFF_TUN_ID, 0, 24, ofpacts);
> > -
> >      const struct hmapx_node *node;
> >      HMAPX_FOR_EACH (node, &mc_group->bindings) {
> 
> If I'm not wrong the mc_group can contain a mix of IPv4 and IPv6
> bindings here, that's fine.
> 
> >          binding = node->data;
> > +        bool ipv4 = IN6_IS_ADDR_V4MAPPED(&binding->remote_ip);
> > +        if (!local_ip) {
> > +            local_ip = evpn_local_ip_lookup_by_vni(vni_ip_map, 
> > binding->vni,
> > +                                                   ipv4);
> 
> But now we only use the first binding to determine the address family
> and therefore always set the TUN_SRC to either the local IPv4 or local
> IPv6 address.  Even if the remote binding family is different.
> 
> > +            if (!local_ip) {
> > +                static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 
> > 1);
> > +                VLOG_WARN_RL(&rl, "failed to get local tunnel ip");
> > +                return;
> > +            }
> > +
> > +            if (ipv4) {
> > +                ovs_be32 ip4 = in6_addr_get_mapped_ipv4(local_ip);
> > +                put_load_bytes(&ip4, sizeof ip4, MFF_TUN_SRC, 0, 32, 
> > ofpacts);
> > +            } else {
> > +                put_load_bytes(local_ip, sizeof *local_ip, 
> > MFF_TUN_IPV6_SRC,
> > +                               0, 128, ofpacts);
> > +            }
> > +            put_load(mc_group->vni, MFF_TUN_ID, 0, 24, ofpacts);
> > +        }
> > +
> >          if (ipv4) {
> >              ovs_be32 ip4 = in6_addr_get_mapped_ipv4(&binding->remote_ip);
> >              put_load_bytes(&ip4, sizeof ip4, MFF_TUN_DST, 0, 32, ofpacts);
> 
> That means that at this point we might end up with inconsistent actions,
> e.g.:
> 
> MFF_TUN_IPV6_SRC=<ipv6-address>,MFF_TUN_DST=<ipv4-address>,output:x,MFF_TUN_IPV6_DST=<ipv6-address>,output:y

ack, I will fix it in v2.

> 
> > @@ -3420,28 +3505,24 @@ physical_eval_evpn_flows(const struct physical_ctx 
> > *ctx,
> >  
> >      const char *local_ip_str = smap_get_def(&ctx->chassis->other_config,
> >                                              "ovn-evpn-local-ip", "");
> > -    struct in6_addr local_ip;
> > -    if (!ip46_parse(local_ip_str, &local_ip)) {
> > -        static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1);
> > -        VLOG_WARN_RL(&rl, "EVPN enabled, but required 'evpn-local-ip' is "
> > -                          "missing or invalid %s ", local_ip_str);
> > -        return;
> > -    }
> > +    struct vector vni_ip_map =
> > +        VECTOR_EMPTY_INITIALIZER(const struct vni_local_ip);
> > +    evpn_vni_local_ip_map_parse(&vni_ip_map, local_ip_str);
> >  
> >      struct match match = MATCH_CATCHALL_INITIALIZER;
> > -    bool ipv4 = IN6_IS_ADDR_V4MAPPED(&local_ip);
> > -
> >      const struct evpn_binding *binding;
> > +
> >      HMAP_FOR_EACH (binding, hmap_node, ctx->evpn_bindings) {
> > -        physical_consider_evpn_binding(binding, &local_ip, ofpacts,
> > -                                       &match, flow_table, ipv4);
> > +        physical_consider_evpn_binding(binding, &vni_ip_map, ofpacts,
> > +                                       &match, flow_table);
> >      }
> >  
> >      const struct evpn_multicast_group *mc_group;
> >      HMAP_FOR_EACH (mc_group, hmap_node, ctx->evpn_multicast_groups) {
> > -        physical_consider_evpn_multicast(mc_group, &local_ip, ofpacts,
> > -                                         &match, flow_table, ipv4);
> > +        physical_consider_evpn_multicast(mc_group, &vni_ip_map, ofpacts,
> > +                                         &match, flow_table);
> >      }
> > +    vector_destroy(&vni_ip_map);
> >  
> >      const struct evpn_fdb *fdb;
> >      HMAP_FOR_EACH (fdb, hmap_node, ctx->evpn_fdbs) {
> > @@ -3571,32 +3652,30 @@ physical_handle_evpn_binding_changes(
> >  {
> >      const char *local_ip_str = smap_get_def(&ctx->chassis->other_config,
> >                                              "ovn-evpn-local-ip", "");
> > -    struct in6_addr local_ip;
> > -    if (!ip46_parse(local_ip_str, &local_ip)) {
> > -        return;
> > -    }
> > +    struct vector vni_ip_map =
> > +        VECTOR_EMPTY_INITIALIZER(const struct vni_local_ip);
> > +    evpn_vni_local_ip_map_parse(&vni_ip_map, local_ip_str);
> >  
> >      struct ofpbuf ofpacts;
> >      ofpbuf_init(&ofpacts, 0);
> >      struct match match = MATCH_CATCHALL_INITIALIZER;
> > -    bool ipv4 = IN6_IS_ADDR_V4MAPPED(&local_ip);
> >  
> >      const struct hmapx_node *node;
> >      HMAPX_FOR_EACH (node, updated_bindings) {
> >          const struct evpn_binding *binding = node->data;
> > -
> >          ofctrl_remove_flows(flow_table, &binding->flow_uuid);
> > -        physical_consider_evpn_binding(binding, &local_ip, &ofpacts,
> > -                                       &match, flow_table, ipv4);
> > +        physical_consider_evpn_binding(binding, &vni_ip_map, &ofpacts,
> > +                                       &match, flow_table);
> >      }
> >  
> >      HMAPX_FOR_EACH (node, updated_multicast_groups) {
> >          const struct evpn_multicast_group *mc_group = node->data;
> >  
> >          ofctrl_remove_flows(flow_table, &mc_group->flow_uuid);
> > -        physical_consider_evpn_multicast(mc_group, &local_ip, &ofpacts,
> > -                                         &match, flow_table, ipv4);
> > +        physical_consider_evpn_multicast(mc_group, &vni_ip_map, &ofpacts,
> > +                                         &match, flow_table);
> >      }
> > +    vector_destroy(&vni_ip_map);
> >  
> >      ofpbuf_uninit(&ofpacts);
> >  
> > diff --git a/tests/system-ovn.at b/tests/system-ovn.at
> > index 1b4b30743..9980927ba 100644
> > --- a/tests/system-ovn.at
> > +++ b/tests/system-ovn.at
> > @@ -18160,6 +18160,540 @@ AT_CLEANUP
> >  EVPN_SWITCH_TESTS([default])
> >  EVPN_SWITCH_TESTS([custom])
> >  
> > +OVN_FOR_EACH_NORTHD([
> > +AT_SETUP([dynamic-routing - EVPN - IPv6])
> 
> We can move this test above, inside the EVPN_SWITCH_TESTS define and
> parametrize the EVPN host interface names like we do for the current
> EVPN tests.
> 
> That will make it such the test is run with both default and custom
> interface names.
> 
> > +AT_KEYWORDS([dynamic-routing])
> > +
> > +CHECK_VRF()
> > +CHECK_CONNTRACK()
> > +CHECK_CONNTRACK_NAT()
> > +
> > +vni=10
> > +VRF_RESERVE([$vni])
> > +ovn_start
> > +OVS_TRAFFIC_VSWITCHD_START()
> > +ADD_BR([br-int])
> > +ADD_BR([br-ext], [set Bridge br-ext fail-mode=standalone])
> > +
> > +# Set external-ids in br-int needed for ovn-controller.
> > +check ovs-vsctl \
> > +    -- set Open_vSwitch . external-ids:system-id=hv1 \
> > +    -- set Open_vSwitch . 
> > external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
> > +    -- set Open_vSwitch . external-ids:ovn-encap-type=geneve \
> > +    -- set Open_vSwitch . external-ids:ovn-encap-ip=169::1 \
> > +    -- set Open_vSwitch . external-ids:ovn-bridge-mappings=phynet:br-ext \
> > +    -- set Open_vSwitch . 
> > external-ids:ovn-evpn-local-ip=10:169.0.0.1,10:[169::1] \
> 
> This configures a "dual stack" local IP for EVPN VTEPs.
> 
> > +    -- set Open_vSwitch . external-ids:ovn-evpn-vxlan-ports=4789 \
> > +    -- set bridge br-int fail-mode=secure other-config:disable-in-band=true
> > +
> > +# Start ovn-controller.
> > +start_daemon ovn-controller
> > +
> > +OVS_WAIT_WHILE([ip link | grep -q ovnvrf$vni:.*UP])
> > +
> > +check ovn-nbctl                                                            
> >    \
> > +    -- ls-add ls-evpn                                                      
> >    \
> > +    -- lsp-add ls-evpn workload1                                           
> >    \
> > +    -- lsp-set-addresses workload1 "f0:00:0f:16:01:10 172.16.1.10 
> > 172:16::10" \
> > +    -- lsp-add ls-evpn workload2                                           
> >    \
> > +    -- lsp-set-addresses workload2 "f0:00:0f:16:01:20 172.16.1.20 
> > 172:16::20" \
> > +    -- lsp-add-localnet-port ls-evpn ln_port phynet
> > +
> > +ADD_NAMESPACES(workload1)
> > +ADD_VETH(workload1, workload1, br-int, "172:16::10/64", 
> > "f0:00:0f:16:01:10", \
> > +         "172:16::1", "nodad", "172.16.1.10/24", "172.16.1.1")
> > +
> > +ADD_NAMESPACES(workload2)
> > +ADD_VETH(workload2, workload2, br-int, "172:16::20/64", 
> > "f0:00:0f:16:01:20", \
> > +         "172:16::1", "nodad", "172.16.1.20/24", "172.16.1.1")
> > +
> > +OVN_POPULATE_ARP
> > +check ovn-nbctl --wait=hv sync
> > +wait_for_ports_up
> > +
> > +# Setup a VRF for the VNI.
> > +check ip link add vrf-$vni type vrf table $vni
> > +on_exit "ip link del vrf-$vni"
> > +check ip link set vrf-$vni up
> > +
> > +# Add VNI bridge.
> > +check ip link add br-$vni type bridge
> > +on_exit "ip link del br-$vni"
> > +check ip link set br-$vni master vrf-$vni addrgenmode none
> > +check ip link set dev br-$vni up
> > +
> > +# Add VXLAN VTEP for the VNI (linked to the OVS vxlan_sys_<port> 
> > interface).
> > +# Use a dstport different than the one used by OVS.
> > +# This is fine because we don't actually want traffic to pass through
> > +# the $vxlan interface.  FRR should read the dstport from the linked
> > +# vxlan_sys_${vxlan_port} device.
> > +dstport=$((60000 + $vni))
> > +check ip link add vxlan-$vni type vxlan \
> > +    id $vni dstport $dstport local 169::1 nolearning
> 
> But here we create a single VXLAN interface, only for IPv6.  We should
> also add one for IPv4.
> 
> But raises the point that even with commit
> https://github.com/ovn-org/ovn/commit/3673730 we still can't monitor the
> two vxlan interfaces (the one for IPv4 and the one for IPv6).
> 
> We need a follow up of that patch to replace
> "dynamic-routing-vxlan-ifname" with "dynamic-routing-vxlan-v4-ifname"
> and "dynamic-routing-vxlan-v6-ifname".

ack, I will fix it in v2.

Regards,
Lorenzo

> 
> > +on_exit "ip link del vxlan-$vni"
> > +check ip link set dev vxlan-$vni up
> > +check ip link set vxlan-$vni master br-$vni
> > +
> > +# Add a dummy loopback to the VNI bridge to be used for advertising local
> > +# MACs.
> > +check ip link add name lo-$vni type dummy
> > +on_exit "ip link del lo-$vni"
> > +check ip link set lo-$vni master br-$vni
> > +check ip link set lo-$vni up
> > +
> > +AS_BOX([L2 EVPN VTEP and FDB learning])
> > +
> > +check ovn-nbctl --wait=hv set logical_switch ls-evpn 
> > other_config:dynamic-routing-vni=$vni
> > +ofport=$(ovs-vsctl --bare --columns ofport find Interface 
> > name="ovn-evpn-4789")
> > +dp_key=$(fetch_column Datapath tunnel_key external_ids:name=ls-evpn)
> > +
> > +AT_CHECK([ovn-appctl evpn/remote-vtep-list], [0], [dnl
> > +])
> > +
> > +AT_CHECK([ovn-appctl evpn/vtep-binding-list], [0], [dnl
> > +])
> > +
> > +AT_CHECK([ovn-appctl evpn/vtep-multicast-group-list], [0], [dnl
> > +])
> > +
> > +# Simulate remote VTEP.
> > +check bridge fdb append 00:00:00:00:00:00 dev vxlan-$vni dst 169::a static 
> > permanent
> > +
> > +OVS_WAIT_FOR_OUTPUT_UNQUOTED([ovn-appctl evpn/remote-vtep-list], [0], [dnl
> > +IP: 169::a, port: 4789, vni: $vni
> > +])
> > +
> > +OVS_WAIT_FOR_OUTPUT_UNQUOTED([ovn-appctl evpn/vtep-binding-list | cut 
> > -d',' -f2-], [0], [dnl
> > + Remote IP: 169::a, vni: $vni, binding_key: 0x80000001, tunnel_ofport: 
> > $ofport, dp_key: $dp_key
> > +])
> > +
> > +OVS_WAIT_FOR_OUTPUT_UNQUOTED([ovn-appctl evpn/vtep-multicast-group-list | 
> > cut -d',' -f2-], [0], [dnl
> > + Remote IPs: 169::a, vni: $vni
> > +])
> > +
> > +AT_CHECK_UNQUOTED([ovs-ofctl dump-flows br-int table=OFTABLE_PHY_TO_LOG | 
> > grep priority=1050 | \
> > +                   awk '{print $7, $8}' | sort], [0], [dnl
> > +priority=1050,tun_id=0xa,tun_ipv6_src=169::a,tun_ipv6_dst=169::1,in_port=$ofport
> >  
> > actions=load:0x$dp_key->OXM_OF_METADATA[[0..31]],load:0x80000001->NXM_NX_REG14[[]],resubmit(,OFTABLE_LEARN_REMOTE_FDB),resubmit(,OFTABLE_LOG_INGRESS_PIPELINE)
> > +])
> > +
> > +AT_CHECK_UNQUOTED([ovs-ofctl dump-flows br-int 
> > table=OFTABLE_REMOTE_VTEP_OUTPUT | grep output | \
> > +                   awk '{print $7, $8}' | sort], [0], [dnl
> > +priority=50,reg15=0x8000,metadata=0x$dp_key 
> > actions=load:0x1->NXM_NX_TUN_IPV6_SRC[[0..63]],load:0x169000000000000->NXM_NX_TUN_IPV6_SRC[[64..127]],load:0xa->NXM_NX_TUN_ID[[0..23]],load:0xa->NXM_NX_TUN_IPV6_DST[[0..63]],load:0x169000000000000->NXM_NX_TUN_IPV6_DST[[64..127]],output:$ofport,resubmit(,OFTABLE_LOCAL_OUTPUT)
> > +priority=50,reg15=0x80000001,metadata=0x$dp_key 
> > actions=load:0x1->NXM_NX_TUN_IPV6_SRC[[0..63]],load:0x169000000000000->NXM_NX_TUN_IPV6_SRC[[64..127]],load:0xa->NXM_NX_TUN_IPV6_DST[[0..63]],load:0x169000000000000->NXM_NX_TUN_IPV6_DST[[64..127]],load:0xa->NXM_NX_TUN_ID[[0..23]],output:$ofport
> > +priority=50,reg15=0x8001,metadata=0x$dp_key 
> > actions=load:0x1->NXM_NX_TUN_IPV6_SRC[[0..63]],load:0x169000000000000->NXM_NX_TUN_IPV6_SRC[[64..127]],load:0xa->NXM_NX_TUN_ID[[0..23]],load:0xa->NXM_NX_TUN_IPV6_DST[[0..63]],load:0x169000000000000->NXM_NX_TUN_IPV6_DST[[64..127]],output:$ofport,resubmit(,OFTABLE_LOCAL_OUTPUT)
> > +priority=50,reg15=0x8004,metadata=0x$dp_key 
> > actions=load:0x1->NXM_NX_TUN_IPV6_SRC[[0..63]],load:0x169000000000000->NXM_NX_TUN_IPV6_SRC[[64..127]],load:0xa->NXM_NX_TUN_ID[[0..23]],load:0xa->NXM_NX_TUN_IPV6_DST[[0..63]],load:0x169000000000000->NXM_NX_TUN_IPV6_DST[[64..127]],output:$ofport,resubmit(,OFTABLE_LOCAL_OUTPUT)
> > +priority=55,reg10=0x1/0x1,reg15=0x80000001,metadata=0x$dp_key 
> > actions=load:0x1->NXM_NX_TUN_IPV6_SRC[[0..63]],load:0x169000000000000->NXM_NX_TUN_IPV6_SRC[[64..127]],load:0xa->NXM_NX_TUN_IPV6_DST[[0..63]],load:0x169000000000000->NXM_NX_TUN_IPV6_DST[[64..127]],load:0xa->NXM_NX_TUN_ID[[0..23]],load:0xffff->NXM_OF_IN_PORT[[]],output:$ofport
> > +])
> > +
> > +AT_CHECK_UNQUOTED([ovs-ofctl dump-flows br-int 
> > table=OFTABLE_LEARN_REMOTE_FDB | grep priority | \
> > +                   awk '{print $7, $8}' | strip_cookie | sort], [0], [dnl
> > +priority=100,reg14=0x80000001,metadata=0x$dp_key 
> > actions=learn(table=OFTABLE_GET_REMOTE_FDB,priority=150,delete_learned,OXM_OF_METADATA[[]],NXM_OF_ETH_DST[[]]=NXM_OF_ETH_SRC[[]],load:NXM_NX_REG14[[]]->NXM_NX_REG1[[]])
> > +])
> > +
> > +# Simulate more remote VTEPs.
> > +check bridge fdb append 00:00:00:00:00:00 dev vxlan-$vni dst 169::14 
> > static permanent
> > +check bridge fdb append 00:00:00:00:00:01 dev vxlan-$vni dst 169::1e 
> > extern_learn
> 
> We should also add IPv4 remote VTEPs to check that the dual-stack
> implementation works fine.
> 
> > +
> > +OVS_WAIT_FOR_OUTPUT_UNQUOTED([ovn-appctl evpn/remote-vtep-list | sort], 
> > [0], [dnl
> > +IP: 169::14, port: 4789, vni: $vni
> > +IP: 169::1e, port: 4789, vni: $vni
> > +IP: 169::a, port: 4789, vni: $vni
> > +])
> > +
> > +OVS_WAIT_FOR_OUTPUT_UNQUOTED([ovn-appctl evpn/vtep-binding-list | cut 
> > -d',' -f2- | sort], [0], [dnl
> > + Remote IP: 169::14, vni: $vni, binding_key: 0x80000002, tunnel_ofport: 
> > $ofport, dp_key: $dp_key
> > + Remote IP: 169::1e, vni: $vni, binding_key: 0x80000003, tunnel_ofport: 
> > $ofport, dp_key: $dp_key
> > + Remote IP: 169::a, vni: $vni, binding_key: 0x80000001, tunnel_ofport: 
> > $ofport, dp_key: $dp_key
> > +])
> > +
> > +# We cannot check the output directly because the order might change.
> > +OVS_WAIT_UNTIL([ovn-appctl evpn/vtep-multicast-group-list | grep -q 
> > "169::a"])
> > +OVS_WAIT_UNTIL([ovn-appctl evpn/vtep-multicast-group-list | grep -q 
> > "169::14"])
> > +OVS_WAIT_UNTIL([ovn-appctl evpn/vtep-multicast-group-list | grep -q 
> > "169::1e"])
> > +AT_CHECK([ovn-appctl evpn/vtep-multicast-group-list | wc -l], [0], [1
> > +])
> > +
> > +AT_CHECK_UNQUOTED([ovs-ofctl dump-flows br-int table=OFTABLE_PHY_TO_LOG | 
> > grep priority=1050 | \
> > +                   awk '{print $7, $8}' | sort], [0], [dnl
> > +priority=1050,tun_id=0xa,tun_ipv6_src=169::14,tun_ipv6_dst=169::1,in_port=$ofport
> >  
> > actions=load:0x$dp_key->OXM_OF_METADATA[[0..31]],load:0x80000002->NXM_NX_REG14[[]],resubmit(,OFTABLE_LEARN_REMOTE_FDB),resubmit(,OFTABLE_LOG_INGRESS_PIPELINE)
> > +priority=1050,tun_id=0xa,tun_ipv6_src=169::1e,tun_ipv6_dst=169::1,in_port=$ofport
> >  
> > actions=load:0x$dp_key->OXM_OF_METADATA[[0..31]],load:0x80000003->NXM_NX_REG14[[]],resubmit(,OFTABLE_LEARN_REMOTE_FDB),resubmit(,OFTABLE_LOG_INGRESS_PIPELINE)
> > +priority=1050,tun_id=0xa,tun_ipv6_src=169::a,tun_ipv6_dst=169::1,in_port=$ofport
> >  
> > actions=load:0x$dp_key->OXM_OF_METADATA[[0..31]],load:0x80000001->NXM_NX_REG14[[]],resubmit(,OFTABLE_LEARN_REMOTE_FDB),resubmit(,OFTABLE_LOG_INGRESS_PIPELINE)
> > +])
> > +
> > +ovs-ofctl dump-flows br-int table=OFTABLE_REMOTE_VTEP_OUTPUT > 
> > oftable_remote_vtep_output
> > +AT_CHECK_UNQUOTED([grep "output" oftable_remote_vtep_output | grep -v 
> > resubmit | \
> > +                   awk '{print $7, $8}' | sort], [0], [dnl
> > +priority=50,reg15=0x80000001,metadata=0x$dp_key 
> > actions=load:0x1->NXM_NX_TUN_IPV6_SRC[[0..63]],load:0x169000000000000->NXM_NX_TUN_IPV6_SRC[[64..127]],load:0xa->NXM_NX_TUN_IPV6_DST[[0..63]],load:0x169000000000000->NXM_NX_TUN_IPV6_DST[[64..127]],load:0xa->NXM_NX_TUN_ID[[0..23]],output:$ofport
> > +priority=50,reg15=0x80000002,metadata=0x$dp_key 
> > actions=load:0x1->NXM_NX_TUN_IPV6_SRC[[0..63]],load:0x169000000000000->NXM_NX_TUN_IPV6_SRC[[64..127]],load:0x14->NXM_NX_TUN_IPV6_DST[[0..63]],load:0x169000000000000->NXM_NX_TUN_IPV6_DST[[64..127]],load:0xa->NXM_NX_TUN_ID[[0..23]],output:$ofport
> > +priority=50,reg15=0x80000003,metadata=0x$dp_key 
> > actions=load:0x1->NXM_NX_TUN_IPV6_SRC[[0..63]],load:0x169000000000000->NXM_NX_TUN_IPV6_SRC[[64..127]],load:0x1e->NXM_NX_TUN_IPV6_DST[[0..63]],load:0x169000000000000->NXM_NX_TUN_IPV6_DST[[64..127]],load:0xa->NXM_NX_TUN_ID[[0..23]],output:$ofport
> > +priority=55,reg10=0x1/0x1,reg15=0x80000001,metadata=0x$dp_key 
> > actions=load:0x1->NXM_NX_TUN_IPV6_SRC[[0..63]],load:0x169000000000000->NXM_NX_TUN_IPV6_SRC[[64..127]],load:0xa->NXM_NX_TUN_IPV6_DST[[0..63]],load:0x169000000000000->NXM_NX_TUN_IPV6_DST[[64..127]],load:0xa->NXM_NX_TUN_ID[[0..23]],load:0xffff->NXM_OF_IN_PORT[[]],output:$ofport
> > +priority=55,reg10=0x1/0x1,reg15=0x80000002,metadata=0x$dp_key 
> > actions=load:0x1->NXM_NX_TUN_IPV6_SRC[[0..63]],load:0x169000000000000->NXM_NX_TUN_IPV6_SRC[[64..127]],load:0x14->NXM_NX_TUN_IPV6_DST[[0..63]],load:0x169000000000000->NXM_NX_TUN_IPV6_DST[[64..127]],load:0xa->NXM_NX_TUN_ID[[0..23]],load:0xffff->NXM_OF_IN_PORT[[]],output:$ofport
> > +priority=55,reg10=0x1/0x1,reg15=0x80000003,metadata=0x$dp_key 
> > actions=load:0x1->NXM_NX_TUN_IPV6_SRC[[0..63]],load:0x169000000000000->NXM_NX_TUN_IPV6_SRC[[64..127]],load:0x1e->NXM_NX_TUN_IPV6_DST[[0..63]],load:0x169000000000000->NXM_NX_TUN_IPV6_DST[[64..127]],load:0xa->NXM_NX_TUN_ID[[0..23]],load:0xffff->NXM_OF_IN_PORT[[]],output:$ofport
> > +])
> > +
> > +AT_CHECK_UNQUOTED([ovs-ofctl dump-flows br-int 
> > table=OFTABLE_LEARN_REMOTE_FDB | grep priority | \
> > +                   awk '{print $7, $8}' | strip_cookie | sort], [0], [dnl
> > +priority=100,reg14=0x80000001,metadata=0x$dp_key 
> > actions=learn(table=OFTABLE_GET_REMOTE_FDB,priority=150,delete_learned,OXM_OF_METADATA[[]],NXM_OF_ETH_DST[[]]=NXM_OF_ETH_SRC[[]],load:NXM_NX_REG14[[]]->NXM_NX_REG1[[]])
> > +priority=100,reg14=0x80000002,metadata=0x$dp_key 
> > actions=learn(table=OFTABLE_GET_REMOTE_FDB,priority=150,delete_learned,OXM_OF_METADATA[[]],NXM_OF_ETH_DST[[]]=NXM_OF_ETH_SRC[[]],load:NXM_NX_REG14[[]]->NXM_NX_REG1[[]])
> > +priority=100,reg14=0x80000003,metadata=0x$dp_key 
> > actions=learn(table=OFTABLE_GET_REMOTE_FDB,priority=150,delete_learned,OXM_OF_METADATA[[]],NXM_OF_ETH_DST[[]]=NXM_OF_ETH_SRC[[]],load:NXM_NX_REG14[[]]->NXM_NX_REG1[[]])
> > +priority=150,reg14=0x80000003,metadata=0x1,dl_src=00:00:00:00:00:01 
> > actions=drop
> > +])
> > +
> > +AT_CHECK([grep "resubmit" oftable_remote_vtep_output | grep 
> > "load:0xa->NXM_NX_TUN_IPV6_DST" | grep -c 
> > "load:0x169000000000000->NXM_NX_TUN_IPV6_DST"], [0], [3
> > +])
> > +AT_CHECK([grep "resubmit" oftable_remote_vtep_output | grep 
> > "load:0x14->NXM_NX_TUN_IPV6_DST" | grep -c 
> > "load:0x169000000000000->NXM_NX_TUN_IPV6_DST"], [0], [3
> > +])
> > +AT_CHECK([grep "resubmit" oftable_remote_vtep_output | grep 
> > "load:0x1e->NXM_NX_TUN_IPV6_DST" | grep -c 
> > "load:0x169000000000000->NXM_NX_TUN_IPV6_DST"], [0], [3
> > +])
> > +
> > +# Simulate remote workload.
> > +check bridge fdb add f0:00:0f:16:10:50 dev vxlan-$vni dst 169::a static 
> > extern_learn
> > +check bridge fdb add f0:00:0f:16:10:60 dev vxlan-$vni dst 169::14 static 
> > extern_learn
> > +check bridge fdb add f0:00:0f:16:10:70 dev vxlan-$vni dst 169::1e static 
> > extern_learn
> > +
> > +OVS_WAIT_FOR_OUTPUT_UNQUOTED([ovn-appctl evpn/vtep-fdb-list | cut -d',' 
> > -f2- | sort], [0], [dnl
> > + MAC: 00:00:00:00:00:01, vni: $vni, binding_key: 0x80000003, dp_key: 
> > $dp_key
> > + MAC: f0:00:0f:16:10:50, vni: $vni, binding_key: 0x80000001, dp_key: 
> > $dp_key
> > + MAC: f0:00:0f:16:10:60, vni: $vni, binding_key: 0x80000002, dp_key: 
> > $dp_key
> > + MAC: f0:00:0f:16:10:70, vni: $vni, binding_key: 0x80000003, dp_key: 
> > $dp_key
> > +])
> > +
> > +AT_CHECK_UNQUOTED([ovs-ofctl dump-flows br-int 
> > table=OFTABLE_GET_REMOTE_FDB | grep priority | \
> > +                   awk '{print $7, $8}' | sort], [0], [dnl
> > +priority=0 actions=load:0->NXM_NX_REG1[[]]
> > +priority=150,metadata=0x$dp_key,dl_dst=00:00:00:00:00:01 
> > actions=load:0x80000003->NXM_NX_REG1[[]]
> > +priority=150,metadata=0x$dp_key,dl_dst=f0:00:0f:16:10:50 
> > actions=load:0x80000001->NXM_NX_REG1[[]]
> > +priority=150,metadata=0x$dp_key,dl_dst=f0:00:0f:16:10:60 
> > actions=load:0x80000002->NXM_NX_REG1[[]]
> > +priority=150,metadata=0x$dp_key,dl_dst=f0:00:0f:16:10:70 
> > actions=load:0x80000003->NXM_NX_REG1[[]]
> > +])
> > +
> > +AT_CHECK_UNQUOTED([ovs-ofctl dump-flows br-int 
> > table=OFTABLE_LEARN_REMOTE_FDB | grep priority | \
> > +                   awk '{print $7, $8}' | strip_cookie | sort], [0], [dnl
> > +priority=100,reg14=0x80000001,metadata=0x$dp_key 
> > actions=learn(table=OFTABLE_GET_REMOTE_FDB,priority=150,delete_learned,OXM_OF_METADATA[[]],NXM_OF_ETH_DST[[]]=NXM_OF_ETH_SRC[[]],load:NXM_NX_REG14[[]]->NXM_NX_REG1[[]])
> > +priority=100,reg14=0x80000002,metadata=0x$dp_key 
> > actions=learn(table=OFTABLE_GET_REMOTE_FDB,priority=150,delete_learned,OXM_OF_METADATA[[]],NXM_OF_ETH_DST[[]]=NXM_OF_ETH_SRC[[]],load:NXM_NX_REG14[[]]->NXM_NX_REG1[[]])
> > +priority=100,reg14=0x80000003,metadata=0x$dp_key 
> > actions=learn(table=OFTABLE_GET_REMOTE_FDB,priority=150,delete_learned,OXM_OF_METADATA[[]],NXM_OF_ETH_DST[[]]=NXM_OF_ETH_SRC[[]],load:NXM_NX_REG14[[]]->NXM_NX_REG1[[]])
> > +priority=150,reg14=0x80000001,metadata=0x$dp_key,dl_src=f0:00:0f:16:10:50 
> > actions=drop
> > +priority=150,reg14=0x80000002,metadata=0x$dp_key,dl_src=f0:00:0f:16:10:60 
> > actions=drop
> > +priority=150,reg14=0x80000003,metadata=0x$dp_key,dl_src=00:00:00:00:00:01 
> > actions=drop
> > +priority=150,reg14=0x80000003,metadata=0x$dp_key,dl_src=f0:00:0f:16:10:70 
> > actions=drop
> > +])
> > +
> > +# Check that the recompute won't change the UUIDs and tunnel keys.
> > +ovn-appctl evpn/vtep-binding-list > bindings_before
> > +ovn-appctl evpn/vtep-multicast-group-list > mc_groups_before
> > +ovn-appctl evpn/vtep-fdb-list > fdb_before
> > +
> > +check ovn-appctl inc-engine/recompute
> > +check ovn-nbctl --wait=hv sync
> > +
> > +ovn-appctl evpn/vtep-binding-list > bindings_after
> > +ovn-appctl evpn/vtep-multicast-group-list > mc_groups_after
> > +ovn-appctl evpn/vtep-fdb-list > fdb_after
> > +
> > +check diff -q bindings_before bindings_after
> > +check diff -q mc_groups_before mc_groups_after
> > +check diff -q fdb_before fdb_after
> > +
> > +AS_BOX([L2 EVPN FDB advertising])
> > +
> > +check ovn-nbctl --wait=hv set logical_switch ls-evpn 
> > other_config:dynamic-routing-redistribute=fdb
> > +OVS_WAIT_FOR_OUTPUT([bridge fdb show | grep "lo-10" | grep 
> > "f0:00:0f:16:01" | sort], [0], [dnl
> > +f0:00:0f:16:01:10 dev lo-10 master br-10 static
> > +f0:00:0f:16:01:10 dev lo-10 vlan 1 master br-10 static
> > +f0:00:0f:16:01:20 dev lo-10 master br-10 static
> > +f0:00:0f:16:01:20 dev lo-10 vlan 1 master br-10 static
> > +])
> > +
> > +check ovn-nbctl --wait=hv lsp-del workload2
> > +OVS_WAIT_FOR_OUTPUT([bridge fdb show | grep "lo-10" | grep 
> > "f0:00:0f:16:01" | sort], [0], [dnl
> > +f0:00:0f:16:01:10 dev lo-10 master br-10 static
> > +f0:00:0f:16:01:10 dev lo-10 vlan 1 master br-10 static
> > +])
> > +
> > +check ovn-nbctl --wait=hv remove logical_switch ls-evpn other_config 
> > dynamic-routing-redistribute
> > +OVS_WAIT_FOR_OUTPUT([bridge fdb show | grep "lo-10" | grep 
> > "f0:00:0f:16:01" | sort], [0], [dnl
> > +])
> > +
> > +check ovn-nbctl --wait=hv set logical_switch ls-evpn 
> > other_config:fdb_age_threshold=300
> > +ovs-ofctl dump-flows br-int table=OFTABLE_LEARN_REMOTE_FDB
> > +AT_CHECK_UNQUOTED([ovs-ofctl dump-flows br-int 
> > table=OFTABLE_LEARN_REMOTE_FDB | grep priority | \
> > +                   awk '{print $7, $8}' | strip_cookie | sort], [0], [dnl
> > +priority=100,reg14=0x80000001,metadata=0x$dp_key 
> > actions=learn(table=OFTABLE_GET_REMOTE_FDB,hard_timeout=300,priority=150,delete_learned,OXM_OF_METADATA[[]],NXM_OF_ETH_DST[[]]=NXM_OF_ETH_SRC[[]],load:NXM_NX_REG14[[]]->NXM_NX_REG1[[]])
> > +priority=100,reg14=0x80000002,metadata=0x$dp_key 
> > actions=learn(table=OFTABLE_GET_REMOTE_FDB,hard_timeout=300,priority=150,delete_learned,OXM_OF_METADATA[[]],NXM_OF_ETH_DST[[]]=NXM_OF_ETH_SRC[[]],load:NXM_NX_REG14[[]]->NXM_NX_REG1[[]])
> > +priority=100,reg14=0x80000003,metadata=0x$dp_key 
> > actions=learn(table=OFTABLE_GET_REMOTE_FDB,hard_timeout=300,priority=150,delete_learned,OXM_OF_METADATA[[]],NXM_OF_ETH_DST[[]]=NXM_OF_ETH_SRC[[]],load:NXM_NX_REG14[[]]->NXM_NX_REG1[[]])
> > +priority=150,reg14=0x80000001,metadata=0x$dp_key,dl_src=f0:00:0f:16:10:50 
> > actions=drop
> > +priority=150,reg14=0x80000002,metadata=0x$dp_key,dl_src=f0:00:0f:16:10:60 
> > actions=drop
> > +priority=150,reg14=0x80000003,metadata=0x$dp_key,dl_src=00:00:00:00:00:01 
> > actions=drop
> > +priority=150,reg14=0x80000003,metadata=0x$dp_key,dl_src=f0:00:0f:16:10:70 
> > actions=drop
> > +])
> > +
> > +check ovn-nbctl --wait=hv remove logical_switch ls-evpn other_config 
> > fdb_age_threshold
> > +AT_CHECK_UNQUOTED([ovs-ofctl dump-flows br-int 
> > table=OFTABLE_LEARN_REMOTE_FDB | grep priority | \
> > +                   awk '{print $7, $8}' | strip_cookie | sort], [0], [dnl
> > +priority=100,reg14=0x80000001,metadata=0x$dp_key 
> > actions=learn(table=OFTABLE_GET_REMOTE_FDB,priority=150,delete_learned,OXM_OF_METADATA[[]],NXM_OF_ETH_DST[[]]=NXM_OF_ETH_SRC[[]],load:NXM_NX_REG14[[]]->NXM_NX_REG1[[]])
> > +priority=100,reg14=0x80000002,metadata=0x$dp_key 
> > actions=learn(table=OFTABLE_GET_REMOTE_FDB,priority=150,delete_learned,OXM_OF_METADATA[[]],NXM_OF_ETH_DST[[]]=NXM_OF_ETH_SRC[[]],load:NXM_NX_REG14[[]]->NXM_NX_REG1[[]])
> > +priority=100,reg14=0x80000003,metadata=0x$dp_key 
> > actions=learn(table=OFTABLE_GET_REMOTE_FDB,priority=150,delete_learned,OXM_OF_METADATA[[]],NXM_OF_ETH_DST[[]]=NXM_OF_ETH_SRC[[]],load:NXM_NX_REG14[[]]->NXM_NX_REG1[[]])
> > +priority=150,reg14=0x80000001,metadata=0x$dp_key,dl_src=f0:00:0f:16:10:50 
> > actions=drop
> > +priority=150,reg14=0x80000002,metadata=0x$dp_key,dl_src=f0:00:0f:16:10:60 
> > actions=drop
> > +priority=150,reg14=0x80000003,metadata=0x$dp_key,dl_src=00:00:00:00:00:01 
> > actions=drop
> > +priority=150,reg14=0x80000003,metadata=0x$dp_key,dl_src=f0:00:0f:16:10:70 
> > actions=drop
> > +])
> > +
> > +AS_BOX([L2 EVPN ARP learning])
> > +# Add a router connected to the EVPN logical switch.
> > +check ovn-nbctl --wait=hv                                                 \
> > +    -- lr-add lr                                                          \
> > +    -- lrp-add lr lr-ls-evpn f0:00:0f:16:01:01 172.16.1.1/24 172:16::1/64 \
> > +    -- lsp-add-router-port ls-evpn ls-evpn-lr lr-ls-evpn
> > +
> > +rtr_dp_key=$(fetch_column Datapath tunnel_key external_ids:name=lr)
> > +rtr_port_key=$(fetch_column Port_Binding tunnel_key 
> > logical_port=lr-ls-evpn)
> > +
> > +# Simulate remote workload ARPs (type-2 MAC+IP EVPN route).
> > +# ovn-controller needs to add OF rules for ARP lookup but no rules for
> > +# MAC_CACHE use.  These entries do not age out automatically, their 
> > lifetime
> > +# is controlled by the BGP-EVPN control plane.
> > +check ip neigh add dev br-10 172.16.1.50 lladdr f0:00:0f:16:10:50 nud 
> > noarp extern_learn
> > +check ip neigh add dev br-10 172.16.1.60 lladdr f0:00:0f:16:10:60 nud 
> > noarp extern_learn
> > +check ip neigh add dev br-10 172.16.1.70 lladdr f0:00:0f:16:10:70 nud 
> > noarp extern_learn
> > +
> > +check ip -6 neigh add dev br-10 172:16::50 lladdr f0:00:0f:16:10:50 nud 
> > noarp extern_learn
> > +check ip -6 neigh add dev br-10 172:16::60 lladdr f0:00:0f:16:10:60 nud 
> > noarp extern_learn
> > +check ip -6 neigh add dev br-10 172:16::70 lladdr f0:00:0f:16:10:70 nud 
> > noarp extern_learn
> > +
> > +OVS_WAIT_FOR_OUTPUT_UNQUOTED([ovn-appctl evpn/vtep-arp-list | cut -d',' 
> > -f2- | sort], [0], [dnl
> > + VNI: 10, MAC: f0:00:0f:16:10:50, IP: 172.16.1.50, dp_key: $dp_key
> > + VNI: 10, MAC: f0:00:0f:16:10:50, IP: 172:16::50, dp_key: $dp_key
> > + VNI: 10, MAC: f0:00:0f:16:10:60, IP: 172.16.1.60, dp_key: $dp_key
> > + VNI: 10, MAC: f0:00:0f:16:10:60, IP: 172:16::60, dp_key: $dp_key
> > + VNI: 10, MAC: f0:00:0f:16:10:70, IP: 172.16.1.70, dp_key: $dp_key
> > + VNI: 10, MAC: f0:00:0f:16:10:70, IP: 172:16::70, dp_key: $dp_key
> > +])
> > +
> > +AS_BOX([Check dynamic-routing-arp-prefer-local=true])
> > +check ovn-nbctl --wait=hv set Logical_Switch ls-evpn 
> > other_config:dynamic-routing-arp-prefer-local=true
> > +
> > +AT_CHECK_UNQUOTED([ovs-ofctl dump-flows br-int table=OFTABLE_MAC_BINDING | 
> > grep priority | \
> > +                   awk '{print $7, $8}' | sort], [0], [dnl
> > +priority=100,reg0=0xac10010a,reg15=0x$rtr_port_key,metadata=0x$rtr_dp_key 
> > actions=mod_dl_dst:f0:00:0f:16:01:10,load:0x1->NXM_NX_REG10[[6]]
> > +priority=20,reg0=0xac100132,reg15=0x$rtr_port_key,metadata=0x$rtr_dp_key 
> > actions=mod_dl_dst:f0:00:0f:16:10:50,load:0x1->NXM_NX_REG10[[6]]
> > +priority=20,reg0=0xac10013c,reg15=0x$rtr_port_key,metadata=0x$rtr_dp_key 
> > actions=mod_dl_dst:f0:00:0f:16:10:60,load:0x1->NXM_NX_REG10[[6]]
> > +priority=20,reg0=0xac100146,reg15=0x$rtr_port_key,metadata=0x$rtr_dp_key 
> > actions=mod_dl_dst:f0:00:0f:16:10:70,load:0x1->NXM_NX_REG10[[6]]
> > +priority=20,reg4=0x1720016,reg5=0,reg6=0,reg7=0x50,reg15=0x$rtr_port_key,metadata=0x$rtr_dp_key
> >  actions=mod_dl_dst:f0:00:0f:16:10:50,load:0x1->NXM_NX_REG10[[6]]
> > +priority=20,reg4=0x1720016,reg5=0,reg6=0,reg7=0x60,reg15=0x$rtr_port_key,metadata=0x$rtr_dp_key
> >  actions=mod_dl_dst:f0:00:0f:16:10:60,load:0x1->NXM_NX_REG10[[6]]
> > +priority=20,reg4=0x1720016,reg5=0,reg6=0,reg7=0x70,reg15=0x$rtr_port_key,metadata=0x$rtr_dp_key
> >  actions=mod_dl_dst:f0:00:0f:16:10:70,load:0x1->NXM_NX_REG10[[6]]
> > +])
> > +
> > +AT_CHECK_UNQUOTED([ovs-ofctl dump-flows br-int table=OFTABLE_MAC_LOOKUP | 
> > grep priority | \
> > +                   awk '{print $7, $8}' | sort], [0], [dnl
> > +priority=100,arp,reg0=0xac10010a,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:01:10
> >  actions=load:0x1->NXM_NX_REG10[[6]]
> > +priority=20,arp,reg0=0xac100132,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:50
> >  actions=load:0x1->NXM_NX_REG10[[6]]
> > +priority=20,arp,reg0=0xac10013c,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:60
> >  actions=load:0x1->NXM_NX_REG10[[6]]
> > +priority=20,arp,reg0=0xac100146,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:70
> >  actions=load:0x1->NXM_NX_REG10[[6]]
> > +priority=20,icmp6,reg0=0x1720016,reg1=0,reg2=0,reg3=0x50,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:50,icmp_code=0
> >  actions=load:0x1->NXM_NX_REG10[[6]]
> > +priority=20,icmp6,reg0=0x1720016,reg1=0,reg2=0,reg3=0x60,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:60,icmp_code=0
> >  actions=load:0x1->NXM_NX_REG10[[6]]
> > +priority=20,icmp6,reg0=0x1720016,reg1=0,reg2=0,reg3=0x70,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:70,icmp_code=0
> >  actions=load:0x1->NXM_NX_REG10[[6]]
> > +])
> > +
> > +AT_CHECK_UNQUOTED([ovs-ofctl dump-flows br-int table=OFTABLE_MAC_CACHE_USE 
> > | grep priority | \
> > +                   awk '{print $7, $8}' | sort], [0], [dnl
> > +priority=100,arp,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:01:10,arp_spa=172.16.1.10,arp_op=2
> >  actions=drop
> > +priority=100,ip,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:01:10,nw_src=172.16.1.10
> >  actions=drop
> > +])
> > +
> > +AS_BOX([Check dynamic-routing-arp-prefer-local=false])
> > +check ovn-nbctl --wait=hv set Logical_Switch ls-evpn 
> > other_config:dynamic-routing-arp-prefer-local=false
> > +
> > +AT_CHECK_UNQUOTED([ovs-ofctl dump-flows br-int table=OFTABLE_MAC_BINDING | 
> > grep priority | \
> > +                   awk '{print $7, $8}' | sort], [0], [dnl
> > +priority=100,reg0=0xac10010a,reg15=0x$rtr_port_key,metadata=0x$rtr_dp_key 
> > actions=mod_dl_dst:f0:00:0f:16:01:10,load:0x1->NXM_NX_REG10[[6]]
> > +priority=200,reg0=0xac100132,reg15=0x$rtr_port_key,metadata=0x$rtr_dp_key 
> > actions=mod_dl_dst:f0:00:0f:16:10:50,load:0x1->NXM_NX_REG10[[6]]
> > +priority=200,reg0=0xac10013c,reg15=0x$rtr_port_key,metadata=0x$rtr_dp_key 
> > actions=mod_dl_dst:f0:00:0f:16:10:60,load:0x1->NXM_NX_REG10[[6]]
> > +priority=200,reg0=0xac100146,reg15=0x$rtr_port_key,metadata=0x$rtr_dp_key 
> > actions=mod_dl_dst:f0:00:0f:16:10:70,load:0x1->NXM_NX_REG10[[6]]
> > +priority=200,reg4=0x1720016,reg5=0,reg6=0,reg7=0x50,reg15=0x$rtr_port_key,metadata=0x$rtr_dp_key
> >  actions=mod_dl_dst:f0:00:0f:16:10:50,load:0x1->NXM_NX_REG10[[6]]
> > +priority=200,reg4=0x1720016,reg5=0,reg6=0,reg7=0x60,reg15=0x$rtr_port_key,metadata=0x$rtr_dp_key
> >  actions=mod_dl_dst:f0:00:0f:16:10:60,load:0x1->NXM_NX_REG10[[6]]
> > +priority=200,reg4=0x1720016,reg5=0,reg6=0,reg7=0x70,reg15=0x$rtr_port_key,metadata=0x$rtr_dp_key
> >  actions=mod_dl_dst:f0:00:0f:16:10:70,load:0x1->NXM_NX_REG10[[6]]
> > +])
> > +
> > +AT_CHECK_UNQUOTED([ovs-ofctl dump-flows br-int table=OFTABLE_MAC_LOOKUP | 
> > grep priority | \
> > +                   awk '{print $7, $8}' | sort], [0], [dnl
> > +priority=100,arp,reg0=0xac10010a,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:01:10
> >  actions=load:0x1->NXM_NX_REG10[[6]]
> > +priority=200,arp,reg0=0xac100132,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:50
> >  actions=load:0x1->NXM_NX_REG10[[6]]
> > +priority=200,arp,reg0=0xac10013c,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:60
> >  actions=load:0x1->NXM_NX_REG10[[6]]
> > +priority=200,arp,reg0=0xac100146,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:70
> >  actions=load:0x1->NXM_NX_REG10[[6]]
> > +priority=200,icmp6,reg0=0x1720016,reg1=0,reg2=0,reg3=0x50,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:50,icmp_code=0
> >  actions=load:0x1->NXM_NX_REG10[[6]]
> > +priority=200,icmp6,reg0=0x1720016,reg1=0,reg2=0,reg3=0x60,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:60,icmp_code=0
> >  actions=load:0x1->NXM_NX_REG10[[6]]
> > +priority=200,icmp6,reg0=0x1720016,reg1=0,reg2=0,reg3=0x70,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:70,icmp_code=0
> >  actions=load:0x1->NXM_NX_REG10[[6]]
> > +])
> > +
> > +AT_CHECK_UNQUOTED([ovs-ofctl dump-flows br-int table=OFTABLE_MAC_CACHE_USE 
> > | grep priority | \
> > +                   awk '{print $7, $8}' | sort], [0], [dnl
> > +priority=100,arp,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:01:10,arp_spa=172.16.1.10,arp_op=2
> >  actions=drop
> > +priority=100,ip,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:01:10,nw_src=172.16.1.10
> >  actions=drop
> > +])
> > +
> > +# Check that the recompute won't change the UUIDs and flows.
> > +ovn-appctl evpn/vtep-arp-list > arp_before
> > +
> > +check ovn-appctl inc-engine/recompute
> > +check ovn-nbctl --wait=hv sync
> > +
> > +ovn-appctl evpn/vtep-arp-list > arp_after
> > +
> > +check diff -q arp_before arp_after
> > +
> > +# Remove remote workload ARP entries and check ovn-controller's state.
> > +check ip neigh del dev br-10 172.16.1.50
> > +check ip neigh del dev br-10 172.16.1.60
> > +check ip neigh del dev br-10 172.16.1.70
> > +
> > +check ip -6 neigh del dev br-10 172:16::50
> > +check ip -6 neigh del dev br-10 172:16::60
> > +check ip -6 neigh del dev br-10 172:16::70
> > +
> > +OVS_WAIT_FOR_OUTPUT_UNQUOTED([ovn-appctl evpn/vtep-arp-list | cut -d',' 
> > -f2- | sort], [0], [dnl
> > +])
> > +
> > +AT_CHECK_UNQUOTED([ovs-ofctl dump-flows br-int table=OFTABLE_MAC_BINDING | 
> > grep priority | \
> > +                   awk '{print $7, $8}' | sort], [0], [dnl
> > +priority=100,reg0=0xac10010a,reg15=0x$rtr_port_key,metadata=0x$rtr_dp_key 
> > actions=mod_dl_dst:f0:00:0f:16:01:10,load:0x1->NXM_NX_REG10[[6]]
> > +])
> > +
> > +AT_CHECK_UNQUOTED([ovs-ofctl dump-flows br-int table=OFTABLE_MAC_LOOKUP | 
> > grep priority | \
> > +                   awk '{print $7, $8}' | sort], [0], [dnl
> > +priority=100,arp,reg0=0xac10010a,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:01:10
> >  actions=load:0x1->NXM_NX_REG10[[6]]
> > +])
> > +
> > +AT_CHECK_UNQUOTED([ovs-ofctl dump-flows br-int table=OFTABLE_MAC_CACHE_USE 
> > | grep priority | \
> > +                   awk '{print $7, $8}' | sort], [0], [dnl
> > +priority=100,arp,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:01:10,arp_spa=172.16.1.10,arp_op=2
> >  actions=drop
> > +priority=100,ip,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:01:10,nw_src=172.16.1.10
> >  actions=drop
> > +])
> > +
> > +# Re-add the remote workload ARPs, remove the router, check that flows are
> > +# removed (vtep-arp-list should still list the ARPs as they're learned on
> > +# the logical switch that still exists).
> > +check ip neigh add dev br-10 172.16.1.50 lladdr f0:00:0f:16:10:50 nud 
> > noarp extern_learn
> > +check ip neigh add dev br-10 172.16.1.60 lladdr f0:00:0f:16:10:60 nud 
> > noarp extern_learn
> > +check ip neigh add dev br-10 172.16.1.70 lladdr f0:00:0f:16:10:70 nud 
> > noarp extern_learn
> > +
> > +check ip -6 neigh add dev br-10 172:16::50 lladdr f0:00:0f:16:10:50 nud 
> > noarp extern_learn
> > +check ip -6 neigh add dev br-10 172:16::60 lladdr f0:00:0f:16:10:60 nud 
> > noarp extern_learn
> > +check ip -6 neigh add dev br-10 172:16::70 lladdr f0:00:0f:16:10:70 nud 
> > noarp extern_learn
> > +
> > +OVS_WAIT_FOR_OUTPUT_UNQUOTED([ovn-appctl evpn/vtep-arp-list | cut -d',' 
> > -f2- | sort], [0], [dnl
> > + VNI: 10, MAC: f0:00:0f:16:10:50, IP: 172.16.1.50, dp_key: $dp_key
> > + VNI: 10, MAC: f0:00:0f:16:10:50, IP: 172:16::50, dp_key: $dp_key
> > + VNI: 10, MAC: f0:00:0f:16:10:60, IP: 172.16.1.60, dp_key: $dp_key
> > + VNI: 10, MAC: f0:00:0f:16:10:60, IP: 172:16::60, dp_key: $dp_key
> > + VNI: 10, MAC: f0:00:0f:16:10:70, IP: 172.16.1.70, dp_key: $dp_key
> > + VNI: 10, MAC: f0:00:0f:16:10:70, IP: 172:16::70, dp_key: $dp_key
> > +])
> > +
> > +AT_CHECK_UNQUOTED([ovs-ofctl dump-flows br-int table=OFTABLE_MAC_BINDING | 
> > grep priority | \
> > +                   awk '{print $7, $8}' | sort], [0], [dnl
> > +priority=100,reg0=0xac10010a,reg15=0x$rtr_port_key,metadata=0x$rtr_dp_key 
> > actions=mod_dl_dst:f0:00:0f:16:01:10,load:0x1->NXM_NX_REG10[[6]]
> > +priority=200,reg0=0xac100132,reg15=0x$rtr_port_key,metadata=0x$rtr_dp_key 
> > actions=mod_dl_dst:f0:00:0f:16:10:50,load:0x1->NXM_NX_REG10[[6]]
> > +priority=200,reg0=0xac10013c,reg15=0x$rtr_port_key,metadata=0x$rtr_dp_key 
> > actions=mod_dl_dst:f0:00:0f:16:10:60,load:0x1->NXM_NX_REG10[[6]]
> > +priority=200,reg0=0xac100146,reg15=0x$rtr_port_key,metadata=0x$rtr_dp_key 
> > actions=mod_dl_dst:f0:00:0f:16:10:70,load:0x1->NXM_NX_REG10[[6]]
> > +priority=200,reg4=0x1720016,reg5=0,reg6=0,reg7=0x50,reg15=0x$rtr_port_key,metadata=0x$rtr_dp_key
> >  actions=mod_dl_dst:f0:00:0f:16:10:50,load:0x1->NXM_NX_REG10[[6]]
> > +priority=200,reg4=0x1720016,reg5=0,reg6=0,reg7=0x60,reg15=0x$rtr_port_key,metadata=0x$rtr_dp_key
> >  actions=mod_dl_dst:f0:00:0f:16:10:60,load:0x1->NXM_NX_REG10[[6]]
> > +priority=200,reg4=0x1720016,reg5=0,reg6=0,reg7=0x70,reg15=0x$rtr_port_key,metadata=0x$rtr_dp_key
> >  actions=mod_dl_dst:f0:00:0f:16:10:70,load:0x1->NXM_NX_REG10[[6]]
> > +])
> > +
> > +AT_CHECK_UNQUOTED([ovs-ofctl dump-flows br-int table=OFTABLE_MAC_LOOKUP | 
> > grep priority | \
> > +                   awk '{print $7, $8}' | sort], [0], [dnl
> > +priority=100,arp,reg0=0xac10010a,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:01:10
> >  actions=load:0x1->NXM_NX_REG10[[6]]
> > +priority=200,arp,reg0=0xac100132,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:50
> >  actions=load:0x1->NXM_NX_REG10[[6]]
> > +priority=200,arp,reg0=0xac10013c,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:60
> >  actions=load:0x1->NXM_NX_REG10[[6]]
> > +priority=200,arp,reg0=0xac100146,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:70
> >  actions=load:0x1->NXM_NX_REG10[[6]]
> > +priority=200,icmp6,reg0=0x1720016,reg1=0,reg2=0,reg3=0x50,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:50,icmp_code=0
> >  actions=load:0x1->NXM_NX_REG10[[6]]
> > +priority=200,icmp6,reg0=0x1720016,reg1=0,reg2=0,reg3=0x60,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:60,icmp_code=0
> >  actions=load:0x1->NXM_NX_REG10[[6]]
> > +priority=200,icmp6,reg0=0x1720016,reg1=0,reg2=0,reg3=0x70,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:70,icmp_code=0
> >  actions=load:0x1->NXM_NX_REG10[[6]]
> > +])
> > +
> > +check ovn-nbctl --wait=hv lr-del lr
> > +AT_CHECK_UNQUOTED([ovn-appctl evpn/vtep-arp-list | cut -d',' -f2- | sort], 
> > [0], [dnl
> > + VNI: 10, MAC: f0:00:0f:16:10:50, IP: 172.16.1.50, dp_key: $dp_key
> > + VNI: 10, MAC: f0:00:0f:16:10:50, IP: 172:16::50, dp_key: $dp_key
> > + VNI: 10, MAC: f0:00:0f:16:10:60, IP: 172.16.1.60, dp_key: $dp_key
> > + VNI: 10, MAC: f0:00:0f:16:10:60, IP: 172:16::60, dp_key: $dp_key
> > + VNI: 10, MAC: f0:00:0f:16:10:70, IP: 172.16.1.70, dp_key: $dp_key
> > + VNI: 10, MAC: f0:00:0f:16:10:70, IP: 172:16::70, dp_key: $dp_key
> > +])
> > +
> > +AT_CHECK_UNQUOTED([ovs-ofctl dump-flows br-int table=OFTABLE_MAC_BINDING | 
> > grep priority | \
> > +                   awk '{print $7, $8}' | sort], [0], [dnl
> > +])
> > +
> > +AT_CHECK_UNQUOTED([ovs-ofctl dump-flows br-int table=OFTABLE_MAC_LOOKUP | 
> > grep priority | \
> > +                   awk '{print $7, $8}' | sort], [0], [dnl
> > +])
> > +
> > +AS_BOX([L2 EVPN ARP advertising])
> > +# Add a router connected to the EVPN logical switch.
> > +check ovn-nbctl --wait=hv                                                 \
> > +    -- lr-add lr                                                          \
> > +    -- set Logical_Router lr options:chassis=hv1                          \
> > +    -- lrp-add lr lr-ls-evpn f0:00:0f:16:01:01 172.16.1.1/24 172:16::1/64
> > +
> > +ls_evpn_uuid=$(fetch_column Datapath_Binding _uuid 
> > external_ids:name=ls-evpn)
> > +check ovn-nbctl --wait=hv set logical_switch ls-evpn 
> > other_config:dynamic-routing-redistribute=fdb,ip
> > +check_row_count Advertised_MAC_Binding 1 ip='172.16.1.10' 
> > mac='f0\:00\:0f\:16\:01\:10' datapath=$ls_evpn_uuid
> > +check_row_count Advertised_MAC_Binding 1 ip='172.16.1.1' 
> > mac='f0\:00\:0f\:16\:01\:01' datapath=$ls_evpn_uuid
> > +check_row_count Advertised_MAC_Binding 1 ip='172\:16\:\:10' 
> > mac='f0\:00\:0f\:16\:01\:10' datapath=$ls_evpn_uuid
> > +check_row_count Advertised_MAC_Binding 1 ip='172\:16\:\:1' 
> > mac='f0\:00\:0f\:16\:01\:01' datapath=$ls_evpn_uuid
> > +check_row_count Advertised_MAC_Binding 4
> > +
> > +AT_CHECK([ip neigh show dev br-10 nud noarp | grep -q '172.16.1.10 lladdr 
> > f0:00:0f:16:01:10 NOARP'])
> > +AT_CHECK([ip neigh show dev br-10 nud noarp | grep -q '172.16.1.1 lladdr 
> > f0:00:0f:16:01:01 NOARP'])
> > +AT_CHECK([ip -6 neigh show dev br-10 nud noarp | grep -q '172:16::10 
> > lladdr f0:00:0f:16:01:10 NOARP'])
> > +AT_CHECK([ip -6 neigh show dev br-10 nud noarp | grep -q '172:16::1 lladdr 
> > f0:00:0f:16:01:01 NOARP'])
> > +
> > +OVS_WAIT_FOR_OUTPUT([bridge fdb show | grep "lo-10" | grep 
> > "f0:00:0f:16:01" | sort], [0], [dnl
> > +f0:00:0f:16:01:01 dev lo-10 master br-10 static
> > +f0:00:0f:16:01:01 dev lo-10 vlan 1 master br-10 static
> > +f0:00:0f:16:01:10 dev lo-10 master br-10 static
> > +f0:00:0f:16:01:10 dev lo-10 vlan 1 master br-10 static
> > +])
> > +
> > +check ovn-nbctl --wait=hv lsp-add ls-evpn workload2 \
> > +    -- lsp-set-addresses workload2 "f0:00:0f:16:01:20 172.16.1.20 
> > 172:16::20"
> > +
> > +check_row_count Advertised_MAC_Binding 1 ip='172.16.1.20' 
> > mac='f0\:00\:0f\:16\:01\:20' datapath=$ls_evpn_uuid
> > +AT_CHECK([ip neigh show dev br-10 nud noarp | grep -q '172.16.1.20 lladdr 
> > f0:00:0f:16:01:20 NOARP'])
> > +
> > +check_row_count Advertised_MAC_Binding 1 ip='172\:16\:\:20' 
> > mac='f0\:00\:0f\:16\:01\:20' datapath=$ls_evpn_uuid
> > +AT_CHECK([ip -6 neigh show dev br-10 nud noarp | grep -q '172:16::20 
> > lladdr f0:00:0f:16:01:20 NOARP'])
> > +
> > +check ovn-nbctl --wait=hv lsp-del workload2
> > +AT_CHECK([ip neigh show dev br-10 nud noarp | grep -q '172.16.1.20 lladdr 
> > f0:00:0f:16:01:20 NOARP'], [1])
> > +AT_CHECK([ip -6 neigh show dev br-10 nud noarp | grep -q '172:16::20 
> > lladdr f0:00:0f:16:01:20 NOARP'], [1])
> > +
> > +check ovn-nbctl --wait=hv lsp-del workload1
> > +check_row_count Advertised_MAC_Binding 2
> > +AT_CHECK([ip neigh show dev br-10 nud noarp | grep -q '172.16.1.10 lladdr 
> > f0:00:0f:16:01:10 NOARP'], [1])
> > +AT_CHECK([ip -6 neigh show dev br-10 nud noarp | grep -q '172:16::10 
> > lladdr f0:00:0f:16:01:10 NOARP'], [1])
> > +
> > +check ovn-nbctl --wait=hv lrp-del lr-ls-evpn
> > +check_row_count Advertised_MAC_Binding 0
> > +AT_CHECK([ip neigh show dev br-10 nud noarp | grep -q '172.16.1.1 lladdr 
> > f0:00:0f:16:01:01 NOARP'], [1])
> > +AT_CHECK([ip -6 neigh show dev br-10 nud noarp | grep -q '172:16::1 lladdr 
> > f0:00:0f:16:01:01 NOARP'], [1])
> > +
> > +check ovn-nbctl --wait=hv ls-del ls-evpn
> > +check ovn-nbctl --wait=hv lr-del lr
> > +
> > +OVN_CLEANUP_CONTROLLER([hv1])
> > +
> > +OVN_CLEANUP_NORTHD
> > +
> > +as
> > +OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d
> > +/Failed to acquire.*/d
> > +/connection dropped.*/d"])
> > +AT_CLEANUP
> > +])
> > +
> >  OVN_FOR_EACH_NORTHD([
> >  AT_SETUP([Router reroute policies - output port])
> >  AT_SKIP_IF([test $HAVE_NC = no])
> 
> Regards,
> Dumitru
> 
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to