Blob Blame History Raw
From e0ca610b0ff8b3d23e871baf3b72ea4373f4fa37 Mon Sep 17 00:00:00 2001
From: Daniel Alvarez Sanchez <dalvarez@redhat.com>
Date: Wed, 24 Mar 2021 18:23:47 +0100
Subject: [PATCH 02/16] pinctrl: Don't send gARPs for localports

Ports of type 'localport' are present on every hypervisor and
ovn-controller is sending gARPs for them which makes upstream
switches to see its MAC address flapping.

In order to avoid this behavior, the current patch is skipping
localports when sending gARP/RARP packets.

Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=1939470

Signed-off-by: Daniel Alvarez Sanchez <dalvarez@redhat.com>
Co-authored-by: Dumitru Ceara <dceara@redhat.com>
Signed-off-by: Dumitru Ceara <dceara@redhat.com>
Signed-off-by: Numan Siddique <numans@ovn.org>
(cherry picked from master commit 578238b36073256c524a4c2b6ed7521f73aa0019)
---
 controller/pinctrl.c |  6 +++++
 tests/ovn.at         | 53 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+)

diff --git a/controller/pinctrl.c b/controller/pinctrl.c
index b42288ea5..523a45b9a 100644
--- a/controller/pinctrl.c
+++ b/controller/pinctrl.c
@@ -4240,6 +4240,12 @@ send_garp_rarp_update(struct ovsdb_idl_txn *ovnsb_idl_txn,
                       struct shash *nat_addresses)
 {
     volatile struct garp_rarp_data *garp_rarp = NULL;
+
+    /* Skip localports as they don't need to be announced */
+    if (!strcmp(binding_rec->type, "localport")) {
+        return;
+    }
+
     /* Update GARP for NAT IP if it exists.  Consider port bindings with type
      * "l3gateway" for logical switch ports attached to gateway routers, and
      * port bindings with type "patch" for logical switch ports attached to
diff --git a/tests/ovn.at b/tests/ovn.at
index b465784cd..a6a49bd5d 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -11494,6 +11494,59 @@ OVN_CLEANUP([hv1],[hv2])
 
 AT_CLEANUP
 
+AT_SETUP([ovn -- localport suppress gARP])
+ovn_start
+
+net_add n1
+sim_add hv1
+as hv1
+check ovs-vsctl add-br br-phys
+ovn_attach n1 br-phys 192.168.0.1
+
+check ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
+
+check ovn-nbctl ls-add ls \
+    -- lsp-add ls lp \
+    -- lsp-set-type lp localport \
+    -- lsp-set-addresses lp "00:00:00:00:00:01 10.0.0.1" \
+    -- lsp-add ls ln \
+    -- lsp-set-type ln localnet \
+    -- lsp-set-options ln network_name=phys \
+    -- lsp-add ls lsp \
+    -- lsp-set-addresses lsp "00:00:00:00:00:02 10.0.0.2"
+
+dnl First bind the localport.
+check ovs-vsctl add-port br-int vif1 \
+    -- set Interface vif1 external-ids:iface-id=lp
+check ovn-nbctl --wait=hv sync
+
+dnl Then bind the regular vif.
+check ovs-vsctl add-port br-int vif2 \
+    -- set Interface vif2 external-ids:iface-id=lsp \
+        options:tx_pcap=hv1/vif2-tx.pcap \
+        options:rxq_pcap=hv1/vif2-rx.pcap
+
+wait_for_ports_up lsp
+check ovn-nbctl --wait=hv sync
+
+dnl Wait for at least two gARPs from lsp (10.0.0.2).
+lsp_garp=ffffffffffff000000000002080600010800060400010000000000020a0000020000000000000a000002
+OVS_WAIT_UNTIL([
+    garps=`$PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | grep ${lsp_garp} -c`
+    test $garps -ge 2
+])
+
+dnl At this point it's safe to assume that ovn-controller skipped sending gARP
+dnl for the localport.  Check that there are no other packets than the gARPs
+dnl for the regular vif.
+AT_CHECK([
+    pkts=`$PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | grep -v ${lsp_garp} -c`
+    test 0 -eq $pkts
+])
+
+OVN_CLEANUP([hv1])
+AT_CLEANUP
+
 AT_SETUP([ovn -- 1 LR with HA distributed router gateway port])
 ovn_start
 
-- 
2.29.2