On Tue, Aug 25, 2026 at 3:16 PM Dumitru Ceara <[email protected]> wrote:
> On 8/19/26 8:39 AM, Ales Musil via dev wrote:
> > EVPN-learned MAC bindings (Type-2 routes from FRR via
> > the kernel neighbor table) were only installed as local
> > OpenFlow flows on the chassis running FRR. When a VM on
> > a different chassis routed traffic through a logical
> > router that needed to resolve an EVPN-learned next-hop,
> > the MAC binding lookup failed because the flow only
> > existed on the FRR chassis.
> >
> > Add a new engine node, en_evpn_mac_binding_sync, that
> > writes EVPN-learned MAC bindings to the SB MAC_Binding
> > table. Once in SB, every chassis consumes them through
> > the existing lflow MAC_Binding pipeline at the same
> > priority as regular ARP/ND-learned entries.
> >
> > The sync node tracks which (logical_port, ip, mac)
> > tuples it has written so it only deletes its own entries
> > without interfering with pinctrl-written dynamic
> > bindings, and skips SB writes when the MAC has not
> > changed. A companion waker node periodically triggers
> > timestamp refreshes on synced entries to prevent northd
> > aging from removing entries that are still present in
> > the kernel neighbor table but not actively carrying
> > traffic.
> >
> > The router-side consider_neighbor_flow() call is removed
> > from physical_consider_evpn_arp() since those flows now
> > come from the SB path. The switch-side EVPN ARP lookup
> > flows (table 113, used for ARP/ND suppression) remain
> > local-only.
> >
> > Note: the dynamic-routing-arp-prefer-local option no
> > longer affects the router MAC_Binding table priority for
> > EVPN entries (they are now always at the same priority
> > as dynamic entries). It still controls the EVPN ARP
> > lookup side table (table 113) priority. Removal of the
> > option is planned as a follow-up.
> >
> > Fixes: 93ae6396e225 ("controller, northd: Add support for learning IP
> neighbors through EVPN.")
> > Reported-at: https://redhat.atlassian.net/browse/FDP-3587
> > Reported-at: https://redhat.atlassian.net/browse/FDP-4001
> > Assisted-by: Claude Opus 4.6, OpenCode
> > Signed-off-by: Ales Musil <[email protected]>
> > ---
>
> Hi Ales,
>
> Thanks for the fix!
>
> Overall this looks good to me, please see some minor items inline.
>
Hi Dumitru,
thank you for the review.
>
> > NEWS | 5 +
> > TODO.rst | 3 -
> > controller/automake.mk | 2 +
> > controller/evpn-mac-binding-sync.c | 243 +++++++++++++++++++++
> > controller/evpn-mac-binding-sync.h | 68 ++++++
> > controller/garp_rarp.c | 2 +-
> > controller/ovn-controller.c | 133 +++++++++++-
> > controller/physical.c | 29 +--
> > controller/physical.h | 3 +-
> > controller/pinctrl.c | 2 +-
> > lib/mac-binding-index.c | 25 ++-
> > lib/mac-binding-index.h | 5 +-
> > ovn-sb.xml | 8 +
> > tests/ovn-inc-proc-graph-dump.at | 9 +
> > tests/system-ovn.at | 336 +++++++++++++++++++----------
> > 15 files changed, 710 insertions(+), 163 deletions(-)
> > create mode 100644 controller/evpn-mac-binding-sync.c
> > create mode 100644 controller/evpn-mac-binding-sync.h
> >
> > diff --git a/NEWS b/NEWS
> > index fcee8b8c2..385e35590 100644
> > --- a/NEWS
> > +++ b/NEWS
> > @@ -65,6 +65,11 @@ Post v26.03.0
> > "external_ids:dynamic-routing-port-mapping" for veth-based
> routing
> > daemon integrations. This feature is Linux-only and requires
> > OVS version >= 4.0.
> > + * EVPN-learned MAC bindings (Type-2 routes from FRR) are now stored
> > + in the SB MAC_Binding table so they are distributed to all
> chassis.
> > + Previously these bindings were local-only OpenFlow flows on the
> > + chassis running FRR, causing MAC resolution failures for traffic
> > + originating on other chassis.
>
> Arguably we don't need this NEWS item. It's a bit of an implementation
> detail, I don't think users care that much about it. I'd remove it.
>
Ok I can remove it.
>
> > - Added "override-connected" option to Logical Router Static Routes
> to mark
> > static routes as higher-priority than connected routes, which in
> turn led
> > to changes in administrative distance for specific route types.
> Please see
> > diff --git a/TODO.rst b/TODO.rst
> > index beca38daf..25ac01ee9 100644
> > --- a/TODO.rst
> > +++ b/TODO.rst
> > @@ -156,9 +156,6 @@ OVN To-do List
> > Otherwise we could try to add duplicated Learned_Routes and the
> ovnsb
> > commit would fail.
> >
> > - * Add support for EVPN L3, that involves MAC Binding learning and
> > - advertisement.
> > -
> > * Datapath sync nodes
> >
> > * Migrate data stored in the ovn\_datapath structure to
> > diff --git a/controller/automake.mk b/controller/automake.mk
> > index a779250cb..bf126d257 100644
> > --- a/controller/automake.mk
> > +++ b/controller/automake.mk
> > @@ -16,6 +16,8 @@ controller_ovn_controller_SOURCES = \
> > controller/evpn-binding.h \
> > controller/evpn-fdb.c \
> > controller/evpn-fdb.h \
> > + controller/evpn-mac-binding-sync.c \
> > + controller/evpn-mac-binding-sync.h \
> > controller/ha-chassis.c \
> > controller/ha-chassis.h \
> > controller/if-status.c \
> > diff --git a/controller/evpn-mac-binding-sync.c
> b/controller/evpn-mac-binding-sync.c
> > new file mode 100644
> > index 000000000..8d927d2ce
> > --- /dev/null
> > +++ b/controller/evpn-mac-binding-sync.c
> > @@ -0,0 +1,243 @@
> > +/* Copyright (c) 2026, Red Hat, Inc.
> > + *
> > + * Licensed under the Apache License, Version 2.0 (the "License");
> > + * you may not use this file except in compliance with the License.
> > + * You may obtain a copy of the License at:
> > + *
> > + * http://www.apache.org/licenses/LICENSE-2.0
> > + *
> > + * Unless required by applicable law or agreed to in writing, software
> > + * distributed under the License is distributed on an "AS IS" BASIS,
> > + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> > + * See the License for the specific language governing permissions and
> > + * limitations under the License.
> > + */
> > +
> > +#include <config.h>
> > +
> > +#include "openvswitch/poll-loop.h"
> > +#include "packets.h"
> > +#include "timeval.h"
> > +
> > +#include "evpn-arp.h"
> > +#include "evpn-mac-binding-sync.h"
> > +#include "lib/mac-binding-index.h"
> > +#include "local_data.h"
> > +#include "mac-cache.h"
> > +#include "ovn-sb-idl.h"
> > +#include "ovn-util.h"
> > +#include "vec.h"
> > +
> > +/* Hash a (logical_port, ip) pair. */
> > +static uint32_t
> > +evpn_mb_hash(const char *logical_port, const char *ip)
> > +{
> > + uint32_t hash = hash_string(logical_port, 0);
> > + return hash_string(ip, hash);
> > +}
> > +
> > +static struct evpn_mb_synced_entry *
> > +evpn_mb_synced_find(const struct hmap *synced, const char *logical_port,
> > + const char *ip)
> > +{
> > + uint32_t hash = evpn_mb_hash(logical_port, ip);
> > +
> > + struct evpn_mb_synced_entry *entry;
> > + HMAP_FOR_EACH_WITH_HASH (entry, hmap_node, hash, synced) {
> > + if (!strcmp(entry->logical_port, logical_port) &&
> > + !strcmp(entry->ip, ip)) {
> > + return entry;
> > + }
> > + }
> > +
> > + return NULL;
> > +}
> > +
> > +static struct evpn_mb_synced_entry *
> > +evpn_mb_synced_add(struct hmap *synced, const char *logical_port,
> > + const char *ip)
> > +{
> > + struct evpn_mb_synced_entry *entry = xmalloc(sizeof *entry);
> > + entry->logical_port = xstrdup(logical_port);
> > + entry->ip = xstrdup(ip);
>
> Nit: designated initializers like we do in other cases?
>
You are right.
>
> > + hmap_insert(synced, &entry->hmap_node,
> > + evpn_mb_hash(logical_port, ip));
> > + return entry;
> > +}
> > +
> > +static void
> > +evpn_mb_synced_remove(struct hmap *synced, struct evpn_mb_synced_entry
> *entry)
> > +{
> > + hmap_remove(synced, &entry->hmap_node);
> > + free(entry->logical_port);
> > + free(entry->ip);
> > + free(entry);
> > +}
> > +
> > +/* Schedule the waker to fire after 'delay_ms' milliseconds. */
> > +static void
> > +evpn_mb_sync_waker_schedule(struct evpn_mb_sync_waker *waker,
> > + int64_t delay_ms)
> > +{
> > + if (delay_ms < INT64_MAX) {
> > + waker->should_schedule = true;
> > + waker->next_wake_msec = time_msec() + delay_ms;
> > + poll_timer_wait_until(waker->next_wake_msec);
> > + }
> > +}
> > +
> > +/* Sync a single EVPN ARP entry to the SB MAC_Binding table for one
> > + * router port. Caller must ensure 'ovnsb_idl_txn' is valid.
> > + * Returns the remaining time (in ms) until the next timestamp
> > + * refresh is needed, or INT64_MAX if none. */
> > +static int64_t
> > +sync_evpn_mb_for_router_port(
> > + struct ovsdb_idl_txn *ovnsb_idl_txn,
> > + struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip,
> > + const struct sbrec_mac_binding_table *mb_table,
> > + const struct sbrec_port_binding *router_pb,
> > + const struct evpn_arp *arp,
> > + struct mac_cache_data *mac_cache_data,
> > + struct ed_type_evpn_mac_binding_sync *data,
> > + long long timewall_now)
> > +{
> > + char *ip_s = normalize_v46(&arp->ip);
> > + struct evpn_mb_synced_entry *existing =
> > + evpn_mb_synced_find(&data->synced_entries,
> > + router_pb->logical_port, ip_s);
> > +
> > + /* Resolve the cached UUID to a row pointer. This is a cheap
> > + * single-key hash lookup that avoids the heavier two-column
> > + * index lookup inside mac_binding_add_to_sb(). */
>
> Nit: this comment is a bit of AI slop, I think. I'd remove it, it's
> obvious what's going on below and we know that lookup by UUID is O(1)
> amortized.
>
Indded I will get rid of it.
>
> > + const struct sbrec_mac_binding *sb_mb = existing
> > + ? sbrec_mac_binding_table_get_for_uuid(mb_table,
> &existing->mb_uuid)
> > + : NULL;
> > +
> > + /* Insert or update the SB MAC_Binding row. */
> > + const struct sbrec_mac_binding *b =
> > + mac_binding_add_to_sb(ovnsb_idl_txn,
> > + sbrec_mac_binding_by_lport_ip,
> > + router_pb->logical_port,
> > + router_pb->datapath,
> > + arp->mac, ip_s, false,
> > + sb_mb);
> > +
> > + if (!existing) {
> > + existing = evpn_mb_synced_add(&data->synced_entries,
> > + router_pb->logical_port, ip_s);
> > + }
> > +
> > + free(ip_s);
> > + existing->mb_uuid = b->header_.uuid;
> > + existing->stale = false;
> > +
> > + /* Refresh timestamp to prevent aging. */
> > + struct mac_cache_threshold *threshold =
> > + mac_cache_threshold_find(mac_cache_data,
> > + router_pb->datapath->tunnel_key);
> > + if (!threshold) {
> > + return INT64_MAX;
> > + }
> > +
> > + uint64_t since_updated = timewall_now - b->timestamp;
> > + if (since_updated >= threshold->cooldown_period) {
> > + sbrec_mac_binding_set_timestamp(b, timewall_now);
> > + return threshold->cooldown_period;
> > + }
> > +
> > + return threshold->cooldown_period - since_updated;
> > +}
> > +
> > +void
> > +evpn_mac_binding_sync_run(
> > + struct ovsdb_idl_txn *ovnsb_idl_txn,
> > + struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip,
> > + const struct sbrec_mac_binding_table *mb_table,
> > + const struct hmap *local_datapaths,
> > + const struct hmap *evpn_arps,
> > + struct mac_cache_data *mac_cache_data,
> > + struct ed_type_evpn_mac_binding_sync *data,
> > + struct evpn_mb_sync_waker *waker)
> > +{
> > + if (!ovnsb_idl_txn) {
> > + data->sb_changes_pending = true;
>
> Isn't this a bit too conservative? We might not have any pending
> changes, right? Should we delay setting data->sb_changes_pending until
> we actually need to update the SB somewhere later in this function?
>
So I had a design that actually deffered the sb_changed_pending
for later, but it turned out to be a mess. So I have decided to make
it easier. Let me know if I should invest time in trying to come up
with better solution.
>
> > + return;
> > + }
> > +
> > + long long timewall_now = time_wall_msec();
> > + int64_t min_next_refresh_ms = INT64_MAX;
> > +
> > + /* Mark all synced entries as stale. SB row pointers are resolved
> > + * lazily by UUID only where needed (insert/update, timestamp
> > + * refresh, delete), avoiding a per-entry index lookup here. */
> > + struct evpn_mb_synced_entry *synced_entry;
> > + HMAP_FOR_EACH (synced_entry, hmap_node, &data->synced_entries) {
> > + synced_entry->stale = true;
> > + }
> > +
> > + /* Walk current EVPN ARPs and sync to SB. */
> > + const struct evpn_arp *arp;
> > + HMAP_FOR_EACH (arp, hmap_node, evpn_arps) {
> > + const struct peer_ports *peers;
> > + VECTOR_FOR_EACH_PTR (&arp->ldp->peer_ports, peers) {
> > + const struct sbrec_port_binding *remote_pb = peers->remote;
> > + struct local_datapath *peer_ld =
> > + get_local_datapath(local_datapaths,
> > + remote_pb->datapath->tunnel_key);
> > + if (!peer_ld || peer_ld->is_switch) {
> > + continue;
> > + }
> > +
> > + int64_t remaining =
> > + sync_evpn_mb_for_router_port(ovnsb_idl_txn,
> > +
> sbrec_mac_binding_by_lport_ip,
> > + mb_table,
> > + remote_pb, arp,
> > + mac_cache_data, data,
> > + timewall_now);
> > + if (remaining < min_next_refresh_ms) {
> > + min_next_refresh_ms = remaining;
> > + }
> > + }
> > + }
> > +
> > + /* Delete stale entries from SB. */
> > + HMAP_FOR_EACH_SAFE (synced_entry, hmap_node, &data->synced_entries)
> {
> > + if (!synced_entry->stale) {
> > + continue;
> > + }
> > +
> > + const struct sbrec_mac_binding *sb_mb =
> > + sbrec_mac_binding_table_get_for_uuid(
> > + mb_table, &synced_entry->mb_uuid);
> > + if (sb_mb) {
> > + sbrec_mac_binding_delete(sb_mb);
> > + }
> > +
> > + evpn_mb_synced_remove(&data->synced_entries, synced_entry);
> > + }
> > +
> > + /* Schedule the waker for the next timestamp refresh. */
> > + if (min_next_refresh_ms < INT64_MAX) {
> > + evpn_mb_sync_waker_schedule(waker, min_next_refresh_ms);
> > + }
> > +}
> > +
> > +void
> > +evpn_mac_binding_sync_init(struct ed_type_evpn_mac_binding_sync *data)
> > +{
> > + hmap_init(&data->synced_entries);
> > + data->sb_changes_pending = false;
> > +}
> > +
> > +void
> > +evpn_mac_binding_sync_cleanup(struct ed_type_evpn_mac_binding_sync
> *data)
> > +{
> > + struct evpn_mb_synced_entry *entry;
> > + HMAP_FOR_EACH_POP (entry, hmap_node, &data->synced_entries) {
> > + free(entry->logical_port);
> > + free(entry->ip);
> > + free(entry);
> > + }
> > + hmap_destroy(&data->synced_entries);
> > +}
> > diff --git a/controller/evpn-mac-binding-sync.h
> b/controller/evpn-mac-binding-sync.h
> > new file mode 100644
> > index 000000000..dc1e63a6a
> > --- /dev/null
> > +++ b/controller/evpn-mac-binding-sync.h
> > @@ -0,0 +1,68 @@
> > +/* Copyright (c) 2026, Red Hat, Inc.
> > + *
> > + * Licensed under the Apache License, Version 2.0 (the "License");
> > + * you may not use this file except in compliance with the License.
> > + * You may obtain a copy of the License at:
> > + *
> > + * http://www.apache.org/licenses/LICENSE-2.0
> > + *
> > + * Unless required by applicable law or agreed to in writing, software
> > + * distributed under the License is distributed on an "AS IS" BASIS,
> > + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> > + * See the License for the specific language governing permissions and
> > + * limitations under the License.
> > + */
> > +
> > +#ifndef EVPN_MAC_BINDING_SYNC_H
> > +#define EVPN_MAC_BINDING_SYNC_H 1
> > +
> > +#include "openvswitch/hmap.h"
> > +#include "openvswitch/uuid.h"
> > +
> > +struct mac_cache_data;
> > +struct ovsdb_idl_index;
> > +struct ovsdb_idl_txn;
> > +struct sbrec_mac_binding_table;
> > +
> > +/* Tracks a MAC_Binding row that was written to SB by the EVPN sync. */
> > +struct evpn_mb_synced_entry {
> > + struct hmap_node hmap_node;
> > + char *logical_port; /* Router port name. */
> > + char *ip; /* Normalized IP string. */
> > + struct uuid mb_uuid; /* UUID of the SB MAC_Binding
> row.
> > + * All-zeros when not yet
> synced. */
> > + bool stale; /* Marked true at start of
> sync,
> > + * cleared when still desired.
> */
> > +};
> > +
> > +/* Persistent state for the en_evpn_mac_binding_sync engine node. */
> > +struct ed_type_evpn_mac_binding_sync {
> > + /* Contains 'struct evpn_mb_synced_entry'. Tracks which
> > + * (logical_port, ip) pairs we have written to SB. */
> > + struct hmap synced_entries;
> > +
> > + /* True when an SB write was skipped because ovnsb_idl_txn was
> NULL. */
> > + bool sb_changes_pending;
> > +};
> > +
> > +/* Timer that periodically wakes the sync node so it can refresh
> > + * timestamps on SB MAC_Binding rows it owns. */
> > +struct evpn_mb_sync_waker {
> > + bool should_schedule; /* Whether a wake is pending. */
> > + long long next_wake_msec; /* Absolute time of next wake. */
> > +};
> > +
> > +void evpn_mac_binding_sync_run(
> > + struct ovsdb_idl_txn *ovnsb_idl_txn,
> > + struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip,
> > + const struct sbrec_mac_binding_table *mb_table,
> > + const struct hmap *local_datapaths,
> > + const struct hmap *evpn_arps,
> > + struct mac_cache_data *mac_cache_data,
> > + struct ed_type_evpn_mac_binding_sync *data,
> > + struct evpn_mb_sync_waker *waker);
> > +
> > +void evpn_mac_binding_sync_init(struct ed_type_evpn_mac_binding_sync *);
> > +void evpn_mac_binding_sync_cleanup(struct ed_type_evpn_mac_binding_sync
> *);
> > +
> > +#endif /* EVPN_MAC_BINDING_SYNC_H */
> > diff --git a/controller/garp_rarp.c b/controller/garp_rarp.c
> > index 1cf415a9f..9de8345c7 100644
> > --- a/controller/garp_rarp.c
> > +++ b/controller/garp_rarp.c
> > @@ -365,7 +365,7 @@ send_garp_locally(const struct garp_rarp_ctx_in
> *r_ctx_in,
> > mac_binding_add_to_sb(r_ctx_in->ovnsb_idl_txn,
> > r_ctx_in->sbrec_mac_binding_by_lport_ip,
> > remote->logical_port, remote->datapath,
> > - ea, ds_cstr(&ip_s), update_only);
> > + ea, ds_cstr(&ip_s), update_only, NULL);
> > ds_destroy(&ip_s);
> > }
> > }
> > diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c
> > index 6551a4e30..c57695ec1 100644
> > --- a/controller/ovn-controller.c
> > +++ b/controller/ovn-controller.c
> > @@ -104,6 +104,7 @@
> > #include "evpn-arp.h"
> > #include "evpn-binding.h"
> > #include "evpn-fdb.h"
> > +#include "evpn-mac-binding-sync.h"
> >
> > VLOG_DEFINE_THIS_MODULE(main);
> >
> > @@ -5157,13 +5158,10 @@ static enum engine_input_handler_result
> > pflow_output_arp_handler(struct engine_node *node, void *data)
> > {
> > struct ed_type_pflow_output *pfo = data;
> > - struct ed_type_runtime_data *rt_data =
> > - engine_get_input_data("runtime_data", node);
> > struct ed_type_evpn_arp *ea_data =
> > engine_get_input_data("evpn_arp", node);
> >
> > - physical_handle_evpn_arp_changes(&rt_data->local_datapaths,
> > - &pfo->flow_table,
> > + physical_handle_evpn_arp_changes(&pfo->flow_table,
> > &ea_data->updated_arps,
> > &ea_data->removed_arps);
> > return EN_HANDLED_UPDATED;
> > @@ -5238,6 +5236,14 @@ controller_output_garp_rarp_handler(struct
> engine_node *node OVS_UNUSED,
> > return EN_HANDLED_UPDATED;
> > }
> >
> > +static enum engine_input_handler_result
> > +controller_output_evpn_mac_binding_sync_handler(
> > + struct engine_node *node OVS_UNUSED,
> > + void *data OVS_UNUSED)
> > +{
> > + return EN_HANDLED_UPDATED;
> > +}
> > +
> > static enum engine_input_handler_result
> > controller_output_datapaths_updated_handler(
> > struct engine_node *node OVS_UNUSED,
> > @@ -7189,6 +7195,106 @@ evpn_arp_vtep_binding_handler(struct engine_node
> *node, void *data OVS_UNUSED)
> > return EN_UNHANDLED;
> > }
> >
> > +/* EVPN MAC binding sync waker: a timer-based input node that
> > + * periodically fires EN_UPDATED to trigger the sync node so it
> > + * can refresh timestamps on SB MAC_Binding rows. */
> > +static void *
> > +en_evpn_mac_binding_sync_waker_init(struct engine_node *node OVS_UNUSED,
> > + struct engine_arg *arg OVS_UNUSED)
> > +{
> > + struct evpn_mb_sync_waker *waker = xzalloc(sizeof *waker);
> > + return waker;
> > +}
> > +
> > +static enum engine_node_state
> > +en_evpn_mac_binding_sync_waker_run(struct engine_node *node OVS_UNUSED,
> > + void *data)
> > +{
> > + struct evpn_mb_sync_waker *waker = data;
> > +
> > + if (!waker->should_schedule) {
> > + return EN_UNCHANGED;
> > + }
> > +
> > + if (time_msec() >= waker->next_wake_msec) {
> > + waker->should_schedule = false;
> > + return EN_UPDATED;
> > + }
> > +
> > + poll_timer_wait_until(waker->next_wake_msec);
> > + return EN_UNCHANGED;
> > +}
> > +
> > +static void
> > +en_evpn_mac_binding_sync_waker_cleanup(void *data OVS_UNUSED)
> > +{
> > +}
> > +
> > +/* EVPN MAC binding sync node: syncs EVPN-learned MAC bindings
> > + * to the SB MAC_Binding table so they are distributed to all
> > + * chassis. */
> > +static void *
> > +en_evpn_mac_binding_sync_init(struct engine_node *node OVS_UNUSED,
> > + struct engine_arg *arg OVS_UNUSED)
> > +{
> > + struct ed_type_evpn_mac_binding_sync *data = xmalloc(sizeof *data);
> > + evpn_mac_binding_sync_init(data);
> > + return data;
> > +}
> > +
> > +static enum engine_node_state
> > +en_evpn_mac_binding_sync_run(struct engine_node *node, void *data_)
> > +{
> > + struct ed_type_evpn_mac_binding_sync *data = data_;
> > +
> > + struct ed_type_evpn_arp *earp_data =
> > + engine_get_input_data("evpn_arp", node);
> > + struct ed_type_runtime_data *rt_data =
> > + engine_get_input_data("runtime_data", node);
> > + struct mac_cache_data *mac_cache_data =
> > + engine_get_input_data("mac_cache", node);
> > + struct engine_node *sb_mb_node =
> > + engine_get_input("SB_mac_binding", node);
> > + struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip =
> > + engine_ovsdb_node_get_index(sb_mb_node, "lport_ip");
> > + const struct sbrec_mac_binding_table *mb_table =
> > + EN_OVSDB_GET(sb_mb_node);
> > +
> > + struct evpn_mb_sync_waker *waker =
> > + engine_get_input_data("evpn_mac_binding_sync_waker", node);
> > +
> > + data->sb_changes_pending = false;
> > +
> > + evpn_mac_binding_sync_run(engine_get_context()->ovnsb_idl_txn,
> > + sbrec_mac_binding_by_lport_ip,
> > + mb_table,
> > + &rt_data->local_datapaths,
> > + &earp_data->arps,
> > + mac_cache_data,
> > + data, waker);
> > +
> > + return EN_UPDATED;
> > +}
> > +
> > +static void
> > +en_evpn_mac_binding_sync_cleanup(void *data_)
> > +{
> > + struct ed_type_evpn_mac_binding_sync *data = data_;
> > + evpn_mac_binding_sync_cleanup(data);
> > +}
> > +
> > +static enum engine_input_handler_result
> > +evpn_mac_binding_sync_sb_ro_handler(struct engine_node *node OVS_UNUSED,
> > + void *data_)
> > +{
> > + struct ed_type_evpn_mac_binding_sync *data = data_;
> > + if (data->sb_changes_pending) {
> > + return EN_UNHANDLED;
> > + }
> > +
> > + return EN_HANDLED_UNCHANGED;
> > +}
> > +
> > /* Define engine node functions for nodes that represent SB tables.
> > *
> > * en_sb_<TABLE_NAME>_run()
> > @@ -7314,6 +7420,8 @@ static ENGINE_NODE(nexthop_exchange);
> > static ENGINE_NODE(evpn_vtep_binding, CLEAR_TRACKED_DATA);
> > static ENGINE_NODE(evpn_fdb, CLEAR_TRACKED_DATA);
> > static ENGINE_NODE(evpn_arp, CLEAR_TRACKED_DATA);
> > +static ENGINE_NODE(evpn_mac_binding_sync_waker);
> > +static ENGINE_NODE(evpn_mac_binding_sync, SB_WRITE);
> > static ENGINE_NODE(datapaths_updated);
> > static ENGINE_NODE(sb_cond_seqno);
> >
> > @@ -7603,6 +7711,21 @@ inc_proc_ovn_controller_init(
> > engine_add_input(&en_evpn_arp, &en_evpn_vtep_binding,
> > evpn_arp_vtep_binding_handler);
> >
> > + engine_add_input(&en_evpn_mac_binding_sync,
> > + &en_evpn_mac_binding_sync_waker, NULL);
> > + engine_add_input(&en_evpn_mac_binding_sync, &en_evpn_arp, NULL);
> > + /* MAC_Binding data is only used via an index for lookups. */
> > + engine_add_input(&en_evpn_mac_binding_sync, &en_sb_mac_binding,
> > + engine_noop_handler);
> > + /* Runtime data is only used for local_datapaths access. */
> > + engine_add_input(&en_evpn_mac_binding_sync, &en_runtime_data,
> > + engine_noop_handler);
> > + /* MAC cache data is only used for aging threshold lookup. */
> > + engine_add_input(&en_evpn_mac_binding_sync, &en_mac_cache,
> > + engine_noop_handler);
> > + engine_add_input(&en_evpn_mac_binding_sync, &en_sb_ro,
> > + evpn_mac_binding_sync_sb_ro_handler);
> > +
> > engine_add_input(&en_pflow_output, &en_evpn_vtep_binding,
> > pflow_output_evpn_binding_handler);
> > engine_add_input(&en_pflow_output, &en_evpn_fdb,
> > @@ -7624,6 +7747,8 @@ inc_proc_ovn_controller_init(
> > controller_output_route_exchange_handler);
> > engine_add_input(&en_controller_output, &en_garp_rarp,
> > controller_output_garp_rarp_handler);
> > + engine_add_input(&en_controller_output, &en_evpn_mac_binding_sync,
> > + controller_output_evpn_mac_binding_sync_handler);
> >
> > engine_add_input(&en_acl_id, &en_sb_acl_id, NULL);
> > engine_add_input(&en_controller_output, &en_acl_id,
> > diff --git a/controller/physical.c b/controller/physical.c
> > index 452256e7a..8a70f913c 100644
> > --- a/controller/physical.c
> > +++ b/controller/physical.c
> > @@ -58,7 +58,6 @@
> > #include "vec.h"
> > #include "vswitch-idl.h"
> > #include "hmapx.h"
> > -#include "neighbor-of.h"
> >
> > VLOG_DEFINE_THIS_MODULE(physical);
> >
> > @@ -3706,28 +3705,11 @@ physical_consider_evpn_fdb(const struct evpn_fdb
> *fdb,
> > }
> >
> > static void
> > -physical_consider_evpn_arp(const struct hmap *local_datapaths,
> > - const struct evpn_arp *arp,
> > +physical_consider_evpn_arp(const struct evpn_arp *arp,
> > struct ofpbuf *ofpacts,
> > struct match *match,
> > struct ovn_desired_flow_table *flow_table)
> > {
> > - /* Walk connected OVN routers and install neighbor flows for the
> ARPs
> > - * learned on EVPN datapaths.*/
> > - const struct peer_ports *peers;
> > - VECTOR_FOR_EACH_PTR (&arp->ldp->peer_ports, peers) {
> > - const struct sbrec_port_binding *remote_pb = peers->remote;
> > - struct local_datapath *peer_ld =
> > - get_local_datapath(local_datapaths,
> > - remote_pb->datapath->tunnel_key);
> > - if (!peer_ld || peer_ld->is_switch) {
> > - continue;
> > - }
> > -
> > - consider_neighbor_flow(remote_pb, &arp->flow_uuid, &arp->ip,
> arp->mac,
> > - flow_table, arp->priority, false);
> > - }
> > -
> > /* Install EVPN ARP lookup flows in the dedicated side table for the
> > * switch datapath. These flows are matched by the chk_evpn_arp()
> > * action. On a hit they load the resolved MAC into eth.dst
> > @@ -3806,8 +3788,7 @@ physical_eval_evpn_flows(const struct physical_ctx
> *ctx,
> >
> > const struct evpn_arp *arp;
> > HMAP_FOR_EACH (arp, hmap_node, ctx->evpn_arps) {
> > - physical_consider_evpn_arp(ctx->local_datapaths, arp, ofpacts,
> > - &match, flow_table);
> > + physical_consider_evpn_arp(arp, ofpacts, &match, flow_table);
> > }
> > }
> >
> > @@ -4016,8 +3997,7 @@ physical_handle_evpn_fdb_changes(struct
> ovn_desired_flow_table *flow_table,
> > }
> >
> > void
> > -physical_handle_evpn_arp_changes(const struct hmap *local_datapaths,
> > - struct ovn_desired_flow_table
> *flow_table,
> > +physical_handle_evpn_arp_changes(struct ovn_desired_flow_table
> *flow_table,
> > const struct hmapx *updated_arps,
> > const struct uuidset *removed_arps)
> > {
> > @@ -4030,8 +4010,7 @@ physical_handle_evpn_arp_changes(const struct hmap
> *local_datapaths,
> > const struct evpn_arp *arp = node->data;
> >
> > ofctrl_remove_flows(flow_table, &arp->flow_uuid);
> > - physical_consider_evpn_arp(local_datapaths, arp, &ofpacts,
> > - &match, flow_table);
> > + physical_consider_evpn_arp(arp, &ofpacts, &match, flow_table);
> > }
> > ofpbuf_uninit(&ofpacts);
> >
> > diff --git a/controller/physical.h b/controller/physical.h
> > index b02caea88..8218096d5 100644
> > --- a/controller/physical.h
> > +++ b/controller/physical.h
> > @@ -106,8 +106,7 @@ void physical_handle_evpn_fdb_changes(struct
> ovn_desired_flow_table *,
> > struct ovn_extend_table
> *group_table,
> > const struct hmapx *updated_fdbs,
> > const struct uuidset
> *removed_fdbs);
> > -void physical_handle_evpn_arp_changes(const struct hmap
> *local_datapaths,
> > - struct ovn_desired_flow_table *,
> > +void physical_handle_evpn_arp_changes(struct ovn_desired_flow_table *,
> > const struct hmapx *updated_arps,
> > const struct uuidset
> *removed_arps);
> > #endif /* controller/physical.h */
> > diff --git a/controller/pinctrl.c b/controller/pinctrl.c
> > index 216831e6e..333dcedb6 100644
> > --- a/controller/pinctrl.c
> > +++ b/controller/pinctrl.c
> > @@ -4918,7 +4918,7 @@ run_put_mac_binding(struct ovsdb_idl_txn
> *ovnsb_idl_txn,
> > ipv6_format_mapped(&mb->data.ip, &ip_s);
> > mac_binding_add_to_sb(ovnsb_idl_txn, sbrec_mac_binding_by_lport_ip,
> > pb->logical_port, pb->datapath, mb->data.mac,
> > - ds_cstr(&ip_s), false);
> > + ds_cstr(&ip_s), false, NULL);
> > ds_destroy(&ip_s);
> > }
> >
> > diff --git a/lib/mac-binding-index.c b/lib/mac-binding-index.c
> > index ad6be0a4e..3e49b07f3 100644
> > --- a/lib/mac-binding-index.c
> > +++ b/lib/mac-binding-index.c
> > @@ -52,27 +52,34 @@ mac_binding_lookup(struct ovsdb_idl_index
> *sbrec_mac_binding_by_lport_ip,
> > }
> >
> > /* Update or add an IP-MAC binding for 'logical_port'.
> > - * Caller should make sure that 'ovnsb_idl_txn' is valid. */
> > -void
> > + * Caller should make sure that 'ovnsb_idl_txn' is valid.
> > + * Returns the SB row that was inserted or updated, or NULL
> > + * if 'update_only' is true and no existing row was found. */
> > +const struct sbrec_mac_binding *
> > mac_binding_add_to_sb(struct ovsdb_idl_txn *ovnsb_idl_txn,
> > struct ovsdb_idl_index
> *sbrec_mac_binding_by_lport_ip,
> > const char *logical_port,
> > const struct sbrec_datapath_binding *dp,
> > struct eth_addr ea, const char *ip,
> > - bool update_only)
> > + bool update_only,
> > + const struct sbrec_mac_binding *sb_mb)
> > {
> > /* Convert ethernet argument to string form for database. */
> > char mac_string[ETH_ADDR_STRLEN + 1];
> > snprintf(mac_string, sizeof mac_string, ETH_ADDR_FMT,
> ETH_ADDR_ARGS(ea));
> >
> > - const struct sbrec_mac_binding *b =
> > - mac_binding_lookup(sbrec_mac_binding_by_lport_ip,
> > - logical_port, ip);
> > + const struct sbrec_mac_binding *b = sb_mb
> > + ? sb_mb
> > + : mac_binding_lookup(sbrec_mac_binding_by_lport_ip,
> > + logical_port, ip);
> > if (!b) {
> > if (update_only) {
> > - return;
> > + return NULL;
> > }
> > - b = sbrec_mac_binding_insert(ovnsb_idl_txn);
> > +
> > + /* Make sure the uuid persists between txn inserts. */
> > + struct uuid uuid = uuid_random();
> > + b = sbrec_mac_binding_insert_persist_uuid(ovnsb_idl_txn, &uuid);
> > sbrec_mac_binding_set_logical_port(b, logical_port);
> > sbrec_mac_binding_set_ip(b, ip);
> > sbrec_mac_binding_set_datapath(b, dp);
> > @@ -91,4 +98,6 @@ mac_binding_add_to_sb(struct ovsdb_idl_txn
> *ovnsb_idl_txn,
> > sbrec_mac_binding_set_timestamp(b, time_wall_msec());
> > }
> > }
> > +
> > + return b;
> > }
> > diff --git a/lib/mac-binding-index.h b/lib/mac-binding-index.h
> > index 3bcb29359..8832eda16 100644
> > --- a/lib/mac-binding-index.h
> > +++ b/lib/mac-binding-index.h
> > @@ -27,10 +27,11 @@ const struct sbrec_mac_binding *
> > mac_binding_lookup(struct ovsdb_idl_index
> *sbrec_mac_binding_by_lport_ip,
> > const char *logical_port, const char *ip);
> >
> > -void mac_binding_add_to_sb(
> > +const struct sbrec_mac_binding *mac_binding_add_to_sb(
> > struct ovsdb_idl_txn *,
> > struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip,
> > const char *logical_port, const struct sbrec_datapath_binding *,
> > - struct eth_addr, const char *ip, bool update_only);
> > + struct eth_addr, const char *ip, bool update_only,
> > + const struct sbrec_mac_binding *sb_mb);
> >
> > #endif /* lib/mac-binding-index.h */
> > diff --git a/ovn-sb.xml b/ovn-sb.xml
> > index d5c5210dc..a147f2675 100644
> > --- a/ovn-sb.xml
> > +++ b/ovn-sb.xml
> > @@ -4185,6 +4185,14 @@ tcp.flags = RST;
> > </li>
> > </ol>
> >
> > + <p>
> > + In EVPN deployments, <code>ovn-controller</code> also writes rows
> to
> > + this table for MAC bindings learned through EVPN Type-2 routes
> (via
> > + FRR and the kernel neighbor table). These entries are keyed by
> the
> > + router port connected to the EVPN logical switch and behave
> identically
> > + to ARP/ND-learned bindings for consumption and aging purposes.
> > + </p>
> > +
> > <column name="logical_port">
> > The logical port on which the binding was discovered.
> > </column>
> > diff --git a/tests/ovn-inc-proc-graph-dump.at b/tests/
> ovn-inc-proc-graph-dump.at
> > index ea70293ce..a56fa8bd8 100644
> > --- a/tests/ovn-inc-proc-graph-dump.at
> > +++ b/tests/ovn-inc-proc-graph-dump.at
> > @@ -483,6 +483,14 @@ digraph "Incremental-Processing-Engine" {
> > SB_datapath_binding -> garp_rarp
> [[label="garp_rarp_sb_datapath_binding_handler"]];
> > SB_mac_binding -> garp_rarp [[label="engine_noop_handler"]];
> > runtime_data -> garp_rarp
> [[label="garp_rarp_runtime_data_handler"]];
> > + evpn_mac_binding_sync_waker [[style=filled, shape=box,
> fillcolor=white, label="evpn_mac_binding_sync_waker"]];
> > + evpn_mac_binding_sync [[style=filled, shape=box, fillcolor=white,
> label="evpn_mac_binding_sync"]];
> > + evpn_mac_binding_sync_waker -> evpn_mac_binding_sync [[label=""]];
> > + evpn_arp -> evpn_mac_binding_sync [[label=""]];
> > + SB_mac_binding -> evpn_mac_binding_sync
> [[label="engine_noop_handler"]];
> > + runtime_data -> evpn_mac_binding_sync
> [[label="engine_noop_handler"]];
> > + mac_cache -> evpn_mac_binding_sync [[label="engine_noop_handler"]];
> > + sb_ro -> evpn_mac_binding_sync
> [[label="evpn_mac_binding_sync_sb_ro_handler"]];
> > SB_acl_id [[style=filled, shape=box, fillcolor=white,
> label="SB_acl_id"]];
> > acl_id [[style=filled, shape=box, fillcolor=white,
> label="acl_id"]];
> > SB_acl_id -> acl_id [[label=""]];
> > @@ -498,6 +506,7 @@ digraph "Incremental-Processing-Engine" {
> > bfd_chassis -> controller_output
> [[label="controller_output_bfd_chassis_handler"]];
> > route_exchange -> controller_output
> [[label="controller_output_route_exchange_handler"]];
> > garp_rarp -> controller_output
> [[label="controller_output_garp_rarp_handler"]];
> > + evpn_mac_binding_sync -> controller_output
> [[label="controller_output_evpn_mac_binding_sync_handler"]];
> > acl_id -> controller_output
> [[label="controller_output_acl_id_handler"]];
> > datapaths_updated -> controller_output
> [[label="controller_output_datapaths_updated_handler"]];
> > }
> > diff --git a/tests/system-ovn.at b/tests/system-ovn.at
> > index d4f2ce69e..9fc27f976 100644
> > --- a/tests/system-ovn.at
> > +++ b/tests/system-ovn.at
> > @@ -18505,9 +18505,9 @@ 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.
> > +# EVPN-learned MAC bindings are written to the SB MAC_Binding table and
> > +# distributed to all chassis. These entries do not age out
> automatically,
> > +# their lifetime is controlled by the BGP-EVPN control plane.
> > check ip neigh add dev $BR_NAME 172.16.1.50 lladdr f0:00:0f:16:10:50
> nud noarp extern_learn
> > check ip neigh add dev $BR_NAME 172.16.1.60 lladdr f0:00:0f:16:10:60
> nud noarp extern_learn
> > check ip neigh add dev $BR_NAME 172.16.1.70 lladdr f0:00:0f:16:10:70
> nud noarp extern_learn
> > @@ -18525,35 +18525,52 @@ OVS_WAIT_FOR_OUTPUT_UNQUOTED([ovn-appctl
> evpn/vtep-arp-list | cut -d',' -f2- | s
> > VNI: 10, MAC: f0:00:0f:16:10:70, IP: 172:16::70, dp_key: $dp_key
> > ])
> >
> > +dnl Verify EVPN-learned MAC bindings appear in the SB MAC_Binding table.
> > +wait_row_count MAC_Binding 1 ip=172.16.1.50
> > +wait_row_count MAC_Binding 1 ip=172.16.1.60
> > +wait_row_count MAC_Binding 1 ip=172.16.1.70
> > +wait_row_count MAC_Binding 1 ip="172\:16\:\:50"
> > +wait_row_count MAC_Binding 1 ip="172\:16\:\:60"
> > +wait_row_count MAC_Binding 1 ip="172\:16\:\:70"
> > +
> > 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]]
> >
> +priority=100,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=100,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=100,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=100,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=100,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=100,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]]
> >
> +priority=100,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=100,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=100,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=100,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=100,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=100,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,arp,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:50,arp_spa=172.16.1.50,arp_op=2
> actions=drop
> >
> +priority=100,arp,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:60,arp_spa=172.16.1.60,arp_op=2
> actions=drop
> >
> +priority=100,arp,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:70,arp_spa=172.16.1.70,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
> >
> +priority=100,ip,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:50,nw_src=172.16.1.50
> actions=drop
> >
> +priority=100,ip,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:60,nw_src=172.16.1.60
> actions=drop
> >
> +priority=100,ip,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:70,nw_src=172.16.1.70
> actions=drop
> >
> +priority=100,ipv6,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:50,ipv6_src=172:16::50
> actions=drop
> >
> +priority=100,ipv6,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:60,ipv6_src=172:16::60
> actions=drop
> >
> +priority=100,ipv6,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:70,ipv6_src=172:16::70
> actions=drop
> > ])
> >
> > AS_BOX([Check dynamic-routing-arp-prefer-local=false])
> > @@ -18562,29 +18579,38 @@ check ovn-nbctl --wait=hv set Logical_Switch
> ls-evpn other_config:dynamic-routin
> > 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]]
> >
> +priority=100,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=100,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=100,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=100,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=100,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=100,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]]
> >
> +priority=100,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=100,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=100,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=100,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=100,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=100,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,arp,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:50,arp_spa=172.16.1.50,arp_op=2
> actions=drop
> >
> +priority=100,arp,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:60,arp_spa=172.16.1.60,arp_op=2
> actions=drop
> >
> +priority=100,arp,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:70,arp_spa=172.16.1.70,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
> >
> +priority=100,ip,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:50,nw_src=172.16.1.50
> actions=drop
> >
> +priority=100,ip,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:60,nw_src=172.16.1.60
> actions=drop
> >
> +priority=100,ip,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:70,nw_src=172.16.1.70
> actions=drop
> >
> +priority=100,ipv6,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:50,ipv6_src=172:16::50
> actions=drop
> >
> +priority=100,ipv6,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:60,ipv6_src=172:16::60
> actions=drop
> >
> +priority=100,ipv6,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:70,ipv6_src=172:16::70
> actions=drop
> > ])
> >
> > # Check that the recompute won't change the UUIDs and flows.
> > @@ -18651,6 +18677,14 @@ check ip -6 neigh del dev $BR_NAME 172:16::70
> > OVS_WAIT_UNTIL([test "$(ovs-ofctl dump-flows br-int
> table=OFTABLE_EVPN_ARP_LOOKUP | \
> > grep -c priority)" = "0"])
> >
> > +dnl Verify EVPN MAC_Binding rows are deleted from SB.
> > +wait_row_count MAC_Binding 0 ip=172.16.1.50
> > +wait_row_count MAC_Binding 0 ip=172.16.1.60
> > +wait_row_count MAC_Binding 0 ip=172.16.1.70
> > +wait_row_count MAC_Binding 0 ip="172\:16\:\:50"
> > +wait_row_count MAC_Binding 0 ip="172\:16\:\:60"
> > +wait_row_count MAC_Binding 0 ip="172\:16\:\:70"
> > +
> > dnl Re-add the EVPN entries for subsequent tests.
> > check ip neigh add dev $BR_NAME 172.16.1.50 lladdr f0:00:0f:16:10:50
> nud noarp extern_learn
> > check ip neigh add dev $BR_NAME 172.16.1.60 lladdr f0:00:0f:16:10:60
> nud noarp extern_learn
> > @@ -18790,23 +18824,23 @@ OVS_WAIT_FOR_OUTPUT_UNQUOTED([ovn-appctl
> evpn/vtep-arp-list | cut -d',' -f2- | s
> > 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]]
> >
> +priority=100,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=100,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=100,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=100,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=100,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=100,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]]
> >
> +priority=100,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=100,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=100,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=100,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=100,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=100,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
> > @@ -19191,9 +19225,9 @@ 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.
> > +# EVPN-learned MAC bindings are written to the SB MAC_Binding table and
> > +# distributed to all chassis. These entries do not age out
> automatically,
> > +# their lifetime is controlled by the BGP-EVPN control plane.
> > check ip neigh add dev $BR_NAME 172.16.1.50 lladdr f0:00:0f:16:10:50
> nud noarp extern_learn
> > check ip neigh add dev $BR_NAME 172.16.1.60 lladdr f0:00:0f:16:10:60
> nud noarp extern_learn
> > check ip neigh add dev $BR_NAME 172.16.1.70 lladdr f0:00:0f:16:10:70
> nud noarp extern_learn
> > @@ -19211,35 +19245,52 @@ OVS_WAIT_FOR_OUTPUT_UNQUOTED([ovn-appctl
> evpn/vtep-arp-list | cut -d',' -f2- | s
> > VNI: 10, MAC: f0:00:0f:16:10:70, IP: 172:16::70, dp_key: $dp_key
> > ])
> >
> > +dnl Verify EVPN-learned MAC bindings appear in the SB MAC_Binding table.
> > +wait_row_count MAC_Binding 1 ip=172.16.1.50
> > +wait_row_count MAC_Binding 1 ip=172.16.1.60
> > +wait_row_count MAC_Binding 1 ip=172.16.1.70
> > +wait_row_count MAC_Binding 1 ip="172\:16\:\:50"
> > +wait_row_count MAC_Binding 1 ip="172\:16\:\:60"
> > +wait_row_count MAC_Binding 1 ip="172\:16\:\:70"
> > +
> > 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]]
> >
> +priority=100,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=100,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=100,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=100,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=100,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=100,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]]
> >
> +priority=100,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=100,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=100,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=100,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=100,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=100,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,arp,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:50,arp_spa=172.16.1.50,arp_op=2
> actions=drop
> >
> +priority=100,arp,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:60,arp_spa=172.16.1.60,arp_op=2
> actions=drop
> >
> +priority=100,arp,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:70,arp_spa=172.16.1.70,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
> >
> +priority=100,ip,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:50,nw_src=172.16.1.50
> actions=drop
> >
> +priority=100,ip,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:60,nw_src=172.16.1.60
> actions=drop
> >
> +priority=100,ip,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:70,nw_src=172.16.1.70
> actions=drop
> >
> +priority=100,ipv6,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:50,ipv6_src=172:16::50
> actions=drop
> >
> +priority=100,ipv6,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:60,ipv6_src=172:16::60
> actions=drop
> >
> +priority=100,ipv6,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:70,ipv6_src=172:16::70
> actions=drop
> > ])
> >
> > AS_BOX([Check dynamic-routing-arp-prefer-local=false])
> > @@ -19248,29 +19299,38 @@ check ovn-nbctl --wait=hv set Logical_Switch
> ls-evpn other_config:dynamic-routin
> > 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]]
> >
> +priority=100,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=100,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=100,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=100,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=100,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=100,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]]
> >
> +priority=100,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=100,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=100,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=100,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=100,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=100,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,arp,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:50,arp_spa=172.16.1.50,arp_op=2
> actions=drop
> >
> +priority=100,arp,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:60,arp_spa=172.16.1.60,arp_op=2
> actions=drop
> >
> +priority=100,arp,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:70,arp_spa=172.16.1.70,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
> >
> +priority=100,ip,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:50,nw_src=172.16.1.50
> actions=drop
> >
> +priority=100,ip,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:60,nw_src=172.16.1.60
> actions=drop
> >
> +priority=100,ip,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:70,nw_src=172.16.1.70
> actions=drop
> >
> +priority=100,ipv6,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:50,ipv6_src=172:16::50
> actions=drop
> >
> +priority=100,ipv6,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:60,ipv6_src=172:16::60
> actions=drop
> >
> +priority=100,ipv6,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:70,ipv6_src=172:16::70
> actions=drop
> > ])
> >
> > # Check that the recompute won't change the UUIDs and flows.
> > @@ -19295,6 +19355,14 @@ check ip -6 neigh del dev $BR_NAME 172:16::70
> > OVS_WAIT_FOR_OUTPUT_UNQUOTED([ovn-appctl evpn/vtep-arp-list | cut -d','
> -f2- | sort], [0], [dnl
> > ])
> >
> > +dnl Verify EVPN MAC_Binding rows are deleted from SB.
> > +wait_row_count MAC_Binding 0 ip=172.16.1.50
> > +wait_row_count MAC_Binding 0 ip=172.16.1.60
> > +wait_row_count MAC_Binding 0 ip=172.16.1.70
> > +wait_row_count MAC_Binding 0 ip="172\:16\:\:50"
> > +wait_row_count MAC_Binding 0 ip="172\:16\:\:60"
> > +wait_row_count MAC_Binding 0 ip="172\:16\:\:70"
> > +
> > 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]]
> > @@ -19334,23 +19402,23 @@ OVS_WAIT_FOR_OUTPUT_UNQUOTED([ovn-appctl
> evpn/vtep-arp-list | cut -d',' -f2- | s
> > 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]]
> >
> +priority=100,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=100,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=100,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=100,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=100,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=100,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]]
> >
> +priority=100,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=100,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=100,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=100,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=100,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=100,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
> > @@ -19774,9 +19842,9 @@ 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.
> > +# EVPN-learned MAC bindings are written to the SB MAC_Binding table and
> > +# distributed to all chassis. These entries do not age out
> automatically,
> > +# their lifetime is controlled by the BGP-EVPN control plane.
> > check ip neigh add dev $BR_NAME 172.16.1.50 lladdr f0:00:0f:16:10:50
> nud noarp extern_learn
> > check ip neigh add dev $BR_NAME 172.16.1.60 lladdr f0:00:0f:16:10:60
> nud noarp extern_learn
> > check ip neigh add dev $BR_NAME 172.16.1.70 lladdr f0:00:0f:16:10:70
> nud noarp extern_learn
> > @@ -19794,35 +19862,52 @@ OVS_WAIT_FOR_OUTPUT_UNQUOTED([ovn-appctl
> evpn/vtep-arp-list | cut -d',' -f2- | s
> > VNI: 10, MAC: f0:00:0f:16:10:70, IP: 172:16::70, dp_key: $dp_key
> > ])
> >
> > +dnl Verify EVPN-learned MAC bindings appear in the SB MAC_Binding table.
> > +wait_row_count MAC_Binding 1 ip=172.16.1.50
> > +wait_row_count MAC_Binding 1 ip=172.16.1.60
> > +wait_row_count MAC_Binding 1 ip=172.16.1.70
> > +wait_row_count MAC_Binding 1 ip="172\:16\:\:50"
> > +wait_row_count MAC_Binding 1 ip="172\:16\:\:60"
> > +wait_row_count MAC_Binding 1 ip="172\:16\:\:70"
> > +
> > 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]]
> >
> +priority=100,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=100,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=100,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=100,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=100,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=100,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]]
> >
> +priority=100,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=100,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=100,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=100,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=100,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=100,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,arp,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:50,arp_spa=172.16.1.50,arp_op=2
> actions=drop
> >
> +priority=100,arp,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:60,arp_spa=172.16.1.60,arp_op=2
> actions=drop
> >
> +priority=100,arp,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:70,arp_spa=172.16.1.70,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
> >
> +priority=100,ip,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:50,nw_src=172.16.1.50
> actions=drop
> >
> +priority=100,ip,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:60,nw_src=172.16.1.60
> actions=drop
> >
> +priority=100,ip,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:70,nw_src=172.16.1.70
> actions=drop
> >
> +priority=100,ipv6,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:50,ipv6_src=172:16::50
> actions=drop
> >
> +priority=100,ipv6,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:60,ipv6_src=172:16::60
> actions=drop
> >
> +priority=100,ipv6,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:70,ipv6_src=172:16::70
> actions=drop
> > ])
> >
> > AS_BOX([Check dynamic-routing-arp-prefer-local=false])
> > @@ -19831,29 +19916,38 @@ check ovn-nbctl --wait=hv set Logical_Switch
> ls-evpn other_config:dynamic-routin
> > 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]]
> >
> +priority=100,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=100,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=100,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=100,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=100,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=100,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]]
> >
> +priority=100,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=100,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=100,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=100,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=100,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=100,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,arp,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:50,arp_spa=172.16.1.50,arp_op=2
> actions=drop
> >
> +priority=100,arp,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:60,arp_spa=172.16.1.60,arp_op=2
> actions=drop
> >
> +priority=100,arp,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:70,arp_spa=172.16.1.70,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
> >
> +priority=100,ip,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:50,nw_src=172.16.1.50
> actions=drop
> >
> +priority=100,ip,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:60,nw_src=172.16.1.60
> actions=drop
> >
> +priority=100,ip,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:70,nw_src=172.16.1.70
> actions=drop
> >
> +priority=100,ipv6,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:50,ipv6_src=172:16::50
> actions=drop
> >
> +priority=100,ipv6,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:60,ipv6_src=172:16::60
> actions=drop
> >
> +priority=100,ipv6,reg14=0x$rtr_port_key,metadata=0x$rtr_dp_key,dl_src=f0:00:0f:16:10:70,ipv6_src=172:16::70
> actions=drop
> > ])
> >
> > # Check that the recompute won't change the UUIDs and flows.
> > @@ -19878,6 +19972,14 @@ check ip -6 neigh del dev $BR_NAME 172:16::70
> > OVS_WAIT_FOR_OUTPUT_UNQUOTED([ovn-appctl evpn/vtep-arp-list | cut -d','
> -f2- | sort], [0], [dnl
> > ])
> >
> > +dnl Verify EVPN MAC_Binding rows are deleted from SB.
> > +wait_row_count MAC_Binding 0 ip=172.16.1.50
> > +wait_row_count MAC_Binding 0 ip=172.16.1.60
> > +wait_row_count MAC_Binding 0 ip=172.16.1.70
> > +wait_row_count MAC_Binding 0 ip="172\:16\:\:50"
> > +wait_row_count MAC_Binding 0 ip="172\:16\:\:60"
> > +wait_row_count MAC_Binding 0 ip="172\:16\:\:70"
> > +
> > 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]]
> > @@ -19917,23 +20019,23 @@ OVS_WAIT_FOR_OUTPUT_UNQUOTED([ovn-appctl
> evpn/vtep-arp-list | cut -d',' -f2- | s
> > 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]]
> >
> +priority=100,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=100,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=100,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=100,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=100,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=100,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]]
> >
> +priority=100,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=100,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=100,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=100,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=100,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=100,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
>
> Regards,
> Dumitru
>
>
Regards,
Ales
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev