We could end up with a stale neighbor entry when advertised DGP
migrates to a different chassis, that would be the case until the
next recompute. Make sure we check the chassis and properly reflect
the migration.
Fixes: 32d5252ceb65 ("controller, northd: Add an option to advertise FDB over
EVPN.")
Assisted-by: GPT-6.1 Sol, OpenCode
Signed-off-by: Ales Musil <[email protected]>
---
controller/ovn-controller.c | 27 ++++++++++++-
tests/multinode.at | 77 +++++++++++++++++++++++++++++++++++++
2 files changed, 102 insertions(+), 2 deletions(-)
diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c
index 7bc3139ab..f4ec67e89 100644
--- a/controller/ovn-controller.c
+++ b/controller/ovn-controller.c
@@ -6742,6 +6742,18 @@ neighbor_sb_port_binding_handler(struct engine_node
*node, void *data)
struct ed_type_neighbor *ne_data = data;
const struct sbrec_port_binding_table *pb_table =
EN_OVSDB_GET(engine_get_input("SB_port_binding", node));
+ const struct ovsrec_open_vswitch_table *ovs_table =
+ EN_OVSDB_GET(engine_get_input("OVS_open_vswitch", node));
+ struct ovsdb_idl_index *sbrec_chassis_by_name =
+ engine_ovsdb_node_get_index(
+ engine_get_input("SB_chassis", node),
+ "name");
+
+ const char *chassis_id = get_ovs_chassis_id(ovs_table);
+ ovs_assert(chassis_id);
+ const struct sbrec_chassis *chassis =
+ chassis_lookup_by_name(sbrec_chassis_by_name, chassis_id);
+ ovs_assert(chassis);
const struct sbrec_port_binding *pb;
SBREC_PORT_BINDING_TABLE_FOR_EACH_TRACKED (pb, pb_table) {
@@ -6751,8 +6763,19 @@ neighbor_sb_port_binding_handler(struct engine_node
*node, void *data)
return EN_HANDLED_UNCHANGED;
}
- if (sbrec_port_binding_is_updated(pb, SBREC_PORT_BINDING_COL_MAC) &&
- sset_contains(&ne_data->advertised_pbs, pb->logical_port)) {
+ bool local = lport_pb_is_chassis_resident(chassis, pb);
+ enum sbrec_port_binding_column_id mac_col = SBREC_PORT_BINDING_COL_MAC;
+ if (sset_contains(&ne_data->advertised_pbs, pb->logical_port) &&
+ (sbrec_port_binding_is_updated(pb, mac_col) || !local)) {
+ return EN_UNHANDLED;
+ }
+
+ enum en_lport_type type = get_lport_type(pb);
+ enum sbrec_port_binding_column_id chassis_col =
+ SBREC_PORT_BINDING_COL_CHASSIS;
+ if (type == LP_CHASSISREDIRECT &&
+ sbrec_port_binding_is_updated(pb, chassis_col) &&
+ local) {
return EN_UNHANDLED;
}
}
diff --git a/tests/multinode.at b/tests/multinode.at
index bd556b8f5..6292cc40b 100644
--- a/tests/multinode.at
+++ b/tests/multinode.at
@@ -4466,6 +4466,83 @@ OVS_WAIT_FOR_OUTPUT([m_as ovn-gw-2 ovs-ofctl dump-flows
br-int table=OFTABLE_GET
1
])
+AS_BOX([Check gateway EVPN advertisements follow HA ownership])
+# Both gateways already have local workloads on ls. Migrating only the
+# chassisredirect binding must refresh advertisements even when neither
+# the local datapaths nor the Advertised_MAC_Binding rows change.
+gw1_chassis=$(m_fetch_column Chassis _uuid name=ovn-gw-1)
+gw2_chassis=$(m_fetch_column Chassis _uuid name=ovn-gw-2)
+check multinode_nbctl \
+ -- ha-chassis-group-add evpn-ha \
+ -- ha-chassis-group-add-chassis evpn-ha ovn-gw-1 20 \
+ -- ha-chassis-group-add-chassis evpn-ha ovn-gw-2 10
+evpn_ha=$(m_fetch_column nb:HA_Chassis_Group _uuid name=evpn-ha)
+check multinode_nbctl --wait=hv set logical_router_port lr-ls
ha_chassis_group=$evpn_ha
+
+priority=20
+for gw in 1 2 1; do
+ active=ovn-gw-$gw
+ standby=ovn-gw-$((3 - gw))
+ if test "$gw" = 1; then
+ chassis=$gw1_chassis
+ host_ip=$host_bgp_ip_gw1
+ else
+ chassis=$gw2_chassis
+ host_ip=$host_bgp_ip_gw2
+ fi
+ check multinode_nbctl ha-chassis-group-add-chassis evpn-ha $active
$priority
+ m_wait_row_count Port_Binding 1 logical_port=cr-lr-ls chassis=$chassis
+
+ # Ignore VLAN 1 copies, which are not managed by neighbor exchange.
+ # A desired static entry may retain extern_learn; do not require it
+ # to be cleared in order to recognize the local advertisement.
+ OVS_WAIT_UNTIL([m_as $active bridge fdb show dev lo-10 | \
+ grep -v ' vlan ' | grep '^00:00:00:01:00:00 ' | grep -q ' static'])
+ OVS_WAIT_FOR_OUTPUT([m_as $standby bridge fdb show dev lo-10 | \
+ grep -v ' vlan ' | grep -q '^00:00:00:01:00:00 '], [1])
+ OVS_WAIT_UNTIL([m_as $active ip -4 neigh show to 10.0.0.1 dev br-10 nud
all | \
+ grep 'lladdr 00:00:00:01:00:00 ' | grep -q NOARP])
+ OVS_WAIT_UNTIL([m_as $active ip -6 neigh show to 10::1 dev br-10 nud all |
\
+ grep 'lladdr 00:00:00:01:00:00 ' | grep -q NOARP])
+ OVS_WAIT_FOR_OUTPUT([m_as $standby ip -4 neigh show to 10.0.0.1 dev br-10
nud all | \
+ grep -q 'lladdr 00:00:00:01:00:00 '], [1])
+ OVS_WAIT_FOR_OUTPUT([m_as $standby ip -6 neigh show to 10::1 dev br-10 nud
all | \
+ grep -q 'lladdr 00:00:00:01:00:00 '], [1])
+
+ OVS_WAIT_FOR_OUTPUT_UNQUOTED([m_as $active ip netns exec frr-ns \
+ vtysh --vty_socket /run/frr/frr-ns -c 'show bgp l2vpn evpn route' | \
+ grep --no-group-separator -A1 00:00:00:01:00:00 | \
+ sed 's/ RD [[0-9.:]]*//g'], [0], [dnl
+ *> [[2]]:[[0]]:[[48]]:[[00:00:00:01:00:00]]
+ $host_ip 0 4210000000 i
+ *> [[2]]:[[0]]:[[48]]:[[00:00:00:01:00:00]]:[[32]]:[[10.0.0.1]]
+ $host_ip 0 4210000000 i
+ *> [[2]]:[[0]]:[[48]]:[[00:00:00:01:00:00]]:[[128]]:[[10::1]]
+ $host_ip 0 4210000000 i
+])
+ OVS_WAIT_FOR_OUTPUT([m_as $standby ip netns exec frr-ns \
+ vtysh --vty_socket /run/frr/frr-ns -c 'show bgp l2vpn evpn route' | \
+ grep -q 00:00:00:01:00:00], [1])
+ priority=$((priority + 10))
+done
+
+# Restore the distributed router before the exact workload cleanup checks.
+check multinode_nbctl --wait=hv \
+ -- clear logical_router_port lr-ls ha_chassis_group \
+ -- ha-chassis-group-del evpn-ha
+m_wait_row_count Port_Binding 0 logical_port=cr-lr-ls
+for gw in ovn-gw-1 ovn-gw-2; do
+ OVS_WAIT_FOR_OUTPUT([m_as $gw bridge fdb show dev lo-10 | \
+ grep -v ' vlan ' | grep -q '^00:00:00:01:00:00 '], [1])
+ OVS_WAIT_FOR_OUTPUT([m_as $gw ip -4 neigh show to 10.0.0.1 dev br-10 nud
all | \
+ grep -q 'lladdr 00:00:00:01:00:00 '], [1])
+ OVS_WAIT_FOR_OUTPUT([m_as $gw ip -6 neigh show to 10::1 dev br-10 nud all
| \
+ grep -q 'lladdr 00:00:00:01:00:00 '], [1])
+ OVS_WAIT_FOR_OUTPUT([m_as $gw ip netns exec frr-ns \
+ vtysh --vty_socket /run/frr/frr-ns -c 'show bgp l2vpn evpn route' | \
+ grep -q 00:00:00:01:00:00], [1])
+done
+
# Remove "workloads" (VIF LSPs) on both chassis.
check multinode_nbctl --wait=hv lsp-del w1 -- lsp-del w2
--
2.56.0
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev