OVS now just allow the ARP Relpy whitch the destination address is matched
against the known xbridge addresses to udpate tunnel neighbor. So when ovs
receive the gratuitous ARP from underlay gateway which the source address
and destination address are all gateway IP, tunnel neighbor will not be updated.

Fixes: ba07cf222a0c ("Handle gratuitous ARP requests and replies in 
tnl_arp_snoop()")
Fixes: 83c2757bd16e ("xlate: Move tnl_neigh_snoop() to 
terminate_native_tunnel()")
Acked-by: Paolo Valerio<pvale...@redhat.com>
Signed-off-by: Han Ding <hand...@chinatelecom.cn>
---
 ofproto/ofproto-dpif-xlate.c | 15 +++++++++++----
 tests/tunnel-push-pop.at     | 20 ++++++++++++++++++++
 2 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index 3b9b26da1..429cafe92 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -4120,7 +4120,15 @@ is_neighbor_reply_correct(const struct xlate_ctx *ctx, 
const struct flow *flow)
 {
     bool ret = false;
     int i;
-    struct xbridge_addr *xbridge_addr = xbridge_addr_ref(ctx->xbridge->addr);
+    struct xbridge_addr *xbridge_addr = NULL;
+
+    if (flow->dl_type != htons(ETH_TYPE_ARP) &&
+        flow->nw_proto != IPPROTO_ICMPV6)
+    {
+        return false;
+    }
+
+    xbridge_addr = xbridge_addr_ref(ctx->xbridge->addr);

     /* Verify if 'nw_dst' of ARP or 'ipv6_dst' of ICMPV6 is in the list. */
     for (i = 0; xbridge_addr && i < xbridge_addr->n_addr; i++) {
@@ -4192,9 +4200,8 @@ terminate_native_tunnel(struct xlate_ctx *ctx, const 
struct xport *xport,
         /* If no tunnel port was found and it's about an ARP or ICMPv6 packet,
          * do tunnel neighbor snooping. */
         if (*tnl_port == ODPP_NONE &&
-            (flow->dl_type == htons(ETH_TYPE_ARP) ||
-             flow->nw_proto == IPPROTO_ICMPV6) &&
-             is_neighbor_reply_correct(ctx, flow)) {
+            (is_neighbor_reply_correct(ctx, flow) ||
+             is_garp(flow, wc))) {
             tnl_neigh_snoop(flow, wc, ctx->xbridge->name,
                             ctx->xin->allow_side_effects);
         } else if (*tnl_port != ODPP_NONE &&
diff --git a/tests/tunnel-push-pop.at b/tests/tunnel-push-pop.at
index 92eebba2e..013ecbcaa 100644
--- a/tests/tunnel-push-pop.at
+++ b/tests/tunnel-push-pop.at
@@ -369,6 +369,26 @@ AT_CHECK([ovs-appctl tnl/neigh/show | grep br | sort], 
[0], [dnl
 1.1.2.92                                      f8:bc:12:44:34:b6   br0
 ])

+dnl Receiving Gratuitous ARP request with correct VLAN id should alter tunnel 
neighbor cache
+AT_CHECK([ovs-appctl netdev-dummy/receive p0 
'recirc_id(0),in_port(1),eth(src=f8:bc:12:44:34:c8,dst=ff:ff:ff:ff:ff:ff),eth_type(0x8100),vlan(vid=10,pcp=7),encap(eth_type(0x0806),arp(sip=1.1.2.92,tip=1.1.2.92,op=1,sha=f8:bc:12:44:34:c8,tha=00:00:00:00:00:00))'])
+
+ovs-appctl time/warp 1000
+ovs-appctl time/warp 1000
+
+AT_CHECK([ovs-appctl tnl/neigh/show | grep br | sort], [0], [dnl
+1.1.2.92                                      f8:bc:12:44:34:c8   br0
+])
+
+dnl Receiving Gratuitous ARP reply with correct VLAN id should alter tunnel 
neighbor cache
+AT_CHECK([ovs-appctl netdev-dummy/receive p0 
'recirc_id(0),in_port(1),eth(src=f8:bc:12:44:34:b2,dst=ff:ff:ff:ff:ff:ff),eth_type(0x8100),vlan(vid=10,pcp=7),encap(eth_type(0x0806),arp(sip=1.1.2.92,tip=1.1.2.92,op=2,sha=f8:bc:12:44:34:b2,tha=f8:bc:12:44:34:b2))'])
+
+ovs-appctl time/warp 1000
+ovs-appctl time/warp 1000
+
+AT_CHECK([ovs-appctl tnl/neigh/show | grep br | sort], [0], [dnl
+1.1.2.92                                      f8:bc:12:44:34:b2   br0
+])
+
 dnl Receive ARP reply without VLAN header
 AT_CHECK([ovs-vsctl set port br0 tag=0])
 AT_CHECK([ovs-appctl tnl/neigh/flush], [0], [OK
--
2.27.0




_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to