Blob Blame History Raw
From 90a9a77f60b039ff404737d116dc16aeff84944c Mon Sep 17 00:00:00 2001
From: Numan Siddique <numans@ovn.org>
Date: Thu, 19 Mar 2020 16:52:17 +0530
Subject: [PATCH] ovn-northd: Don't add arp responder flows for lports with
 'unknown' address.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

If a logical port has 'unknown' address, it means it can send and receive
packet with any IP and MAC and generally port security is not set for
such logical ports. If an lport has addresses set to - ["MAC1 IP1", unknown],
right now we add arp responder flows for IP1 and respond MAC1 in the arp
response. But it's possible that the VIF of the logical port can use the IP1
with a different MAC. This patch supports this usecase. When another logical port
sends ARP request for IP1, the VIF of the logical port will anyway respond.

Reported-by: Maciej Józefczyk <mjozefcz@redhat.com>
Acked-by: Han Zhou <hzhou@ovn.org>
Signed-off-by: Numan Siddique <numans@ovn.org>
---
 ovn/northd/ovn-northd.8.xml |  5 +++--
 ovn/northd/ovn-northd.c     | 13 ++++++++-----
 tests/ovn.at                | 16 ++++++++++++----
 3 files changed, 23 insertions(+), 11 deletions(-)

diff --git a/ovn/northd/ovn-northd.8.xml b/ovn/northd/ovn-northd.8.xml
index f4d6c8f08..5f9809951 100644
--- a/ovn/northd/ovn-northd.8.xml
+++ b/ovn/northd/ovn-northd.8.xml
@@ -656,8 +656,9 @@ output;
 
         <p>
           These flows are omitted for logical ports (other than router ports or
-          <code>localport</code> ports) that are down and for logical ports of
-          type <code>virtual</code>.
+          <code>localport</code> ports) that are down, for logical ports of
+          type <code>virtual</code> and for logical ports with 'unknown'
+          address set.
         </p>
       </li>
 
diff --git a/ovn/northd/ovn-northd.c b/ovn/northd/ovn-northd.c
index c2ac5ce07..d734d36ee 100644
--- a/ovn/northd/ovn-northd.c
+++ b/ovn/northd/ovn-northd.c
@@ -1113,7 +1113,7 @@ struct ovn_port {
 
     bool derived; /* Indicates whether this is an additional port
                    * derived from nbsp or nbrp. */
-
+    bool has_unknown; /* If the addresses have 'unknown' defined. */
     /* The port's peer:
      *
      *     - A switch port S of type "router" has a router port R as a peer,
@@ -2026,8 +2026,11 @@ join_logical_ports(struct northd_context *ctx,
                 op->lsp_addrs
                     = xmalloc(sizeof *op->lsp_addrs * nbsp->n_addresses);
                 for (size_t j = 0; j < nbsp->n_addresses; j++) {
-                    if (!strcmp(nbsp->addresses[j], "unknown")
-                        || !strcmp(nbsp->addresses[j], "router")) {
+                    if (!strcmp(nbsp->addresses[j], "unknown")) {
+                        op->has_unknown = true;
+                        continue;
+                    }
+                    if (!strcmp(nbsp->addresses[j], "router")) {
                         continue;
                     }
                     if (is_dynamic_lsp_address(nbsp->addresses[j])) {
@@ -5834,7 +5837,7 @@ build_lswitch_flows(struct hmap *datapaths, struct hmap *ports,
         } else {
             /*
              * Add ARP/ND reply flows if either the
-             *  - port is up or
+             *  - port is up and it doesn't have 'unknown' address defined or
              *  - port type is router or
              *  - port type is localport
              */
@@ -5843,7 +5846,7 @@ build_lswitch_flows(struct hmap *datapaths, struct hmap *ports,
                 continue;
             }
 
-            if (lsp_is_external(op->nbsp)) {
+            if (lsp_is_external(op->nbsp) || op->has_unknown) {
                 continue;
             }
 
diff --git a/tests/ovn.at b/tests/ovn.at
index 9fb6e4f98..da016be9e 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -1715,11 +1715,13 @@ for is in 1 2 3; do
                 sip=`ip_to_hex 192 168 0 $is$js`
                 tip=`ip_to_hex 192 168 0 $id$jd`
                 tip_unknown=`ip_to_hex 11 11 11 11`
+                reply_ha=;
                 if test $d != $s; then
-                    reply_ha=f000000000$d
-                else
-                    reply_ha=
+                    if test $jd != 1; then
+                        reply_ha=f000000000$d
+                    fi
                 fi
+
                 test_arp $s f000000000$s $sip $tip $reply_ha               #9
                 test_arp $s f000000000$s $sip $tip_unknown                 #10
 
@@ -2158,7 +2160,13 @@ for s in 1 2 3; do
         sip=192.168.0.$s
         tip=192.168.0.$d
         tip_unknown=11.11.11.11
-        if test $d != $s; then reply_ha=f0:00:00:00:00:0$d; else reply_ha=; fi
+        reply_ha=;
+        if test $d != $s; then
+            if test $d != 1; then
+                reply_ha=f0:00:00:00:00:0$d;
+            fi
+        fi
+
         test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha                 #9
         test_arp $s f0:00:00:00:00:0$s $sip $tip_unknown                   #10
 
-- 
2.24.1