[ovs-dev] [PATCH v7 1/2] ovn: Avoid ARP responder for packets from localnet port

Han Zhou zhouhan at gmail.com
Fri Feb 26 04:26:23 UTC 2016


This is required by next commit that allows lswitch with localnet
port to be attached to multiple chassises. Without this patch, if
an ARP request comes from localnet port, on each chassis there will
be an ARP response, which is not desired.

An new stage ls_in_arp_rsp is introduced for ARP responder before
ls_in_l2_lkup.

Suggested-by: Russell Bryant <russell at ovn.org>
Signed-off-by: Han Zhou <zhouhan at gmail.com>
---
 ovn/northd/ovn-northd.8.xml | 27 +++++++++++++++++++++++----
 ovn/northd/ovn-northd.c     | 40 +++++++++++++++++++++++++++++++++-------
 2 files changed, 56 insertions(+), 11 deletions(-)

diff --git a/ovn/northd/ovn-northd.8.xml b/ovn/northd/ovn-northd.8.xml
index 1b2912e..cacd760 100644
--- a/ovn/northd/ovn-northd.8.xml
+++ b/ovn/northd/ovn-northd.8.xml
@@ -195,17 +195,22 @@
       </li>
     </ul>
 
-    <h3>Ingress Table 3: Destination Lookup</h3>
+    <h3>Ingress Table 3: ARP responder</h3>
 
     <p>
-      This table implements switching behavior.  It contains these logical
-      flows:
+      This table implements ARP responder for known IPs.  It contains these
+      logical flows:
     </p>
 
     <ul>
       <li>
+        Priority-100 flows to skip ARP responder if inport is of type
+        <code>localnet</code>, and advances directly to table 3.
+      </li>
+
+      <li>
         <p>
-          Priority-150 flows that matches ARP requests to each known IP address
+          Priority-50 flows that matches ARP requests to each known IP address
           <var>A</var> of logical port <var>P</var>, and respond with ARP
           replies directly with corresponding Ethernet address <var>E</var>:
         </p>
@@ -230,6 +235,20 @@ output;
       </li>
 
       <li>
+        One priority-0 fallback flow that matches all packets and advances to
+        table 4.
+      </li>
+    </ul>
+
+    <h3>Ingress Table 4: Destination Lookup</h3>
+
+    <p>
+      This table implements switching behavior.  It contains these logical
+      flows:
+    </p>
+
+    <ul>
+      <li>
         A priority-100 flow that outputs all packets with an Ethernet broadcast
         or multicast <code>eth.dst</code> to the <code>MC_FLOOD</code>
         multicast group, which <code>ovn-northd</code> populates with all
diff --git a/ovn/northd/ovn-northd.c b/ovn/northd/ovn-northd.c
index b2b1a45..1c71418 100644
--- a/ovn/northd/ovn-northd.c
+++ b/ovn/northd/ovn-northd.c
@@ -88,7 +88,8 @@ enum ovn_stage {
     PIPELINE_STAGE(SWITCH, IN,  PORT_SEC,    0, "ls_in_port_sec")     \
     PIPELINE_STAGE(SWITCH, IN,  PRE_ACL,     1, "ls_in_pre_acl")      \
     PIPELINE_STAGE(SWITCH, IN,  ACL,         2, "ls_in_acl")          \
-    PIPELINE_STAGE(SWITCH, IN,  L2_LKUP,     3, "ls_in_l2_lkup")      \
+    PIPELINE_STAGE(SWITCH, IN,  ARP_RSP,     3, "ls_in_arp_rsp")      \
+    PIPELINE_STAGE(SWITCH, IN,  L2_LKUP,     4, "ls_in_l2_lkup")      \
                                                                       \
     /* Logical switch egress stages. */                               \
     PIPELINE_STAGE(SWITCH, OUT, PRE_ACL,     0, "ls_out_pre_acl")     \
@@ -1283,8 +1284,23 @@ build_lswitch_flows(struct hmap *datapaths, struct hmap *ports,
         ds_destroy(&match);
     }
 
-    /* Ingress table 3: Destination lookup, ARP reply for known IPs.
-     * (priority 150). */
+    /* Ingress table 3: ARP responder, skip requests coming from localnet ports.
+     * (priority 100). */
+    HMAP_FOR_EACH (op, key_node, ports) {
+        if (!op->nbs) {
+            continue;
+        }
+
+        if (!strcmp(op->nbs->type, "localnet")) {
+            char *match = xasprintf("inport == %s", op->json_key);
+            ovn_lflow_add(lflows, op->od, S_SWITCH_IN_ARP_RSP, 100,
+                          match, "next;");
+            free(match);
+        }
+    }
+
+    /* Ingress table 3: ARP responder, reply for known IPs.
+     * (priority 50). */
     HMAP_FOR_EACH (op, key_node, ports) {
         if (!op->nbs) {
             continue;
@@ -1323,7 +1339,7 @@ build_lswitch_flows(struct hmap *datapaths, struct hmap *ports,
                     ETH_ADDR_ARGS(laddrs.ea),
                     ETH_ADDR_ARGS(laddrs.ea),
                     IP_ARGS(laddrs.ipv4_addrs[j].addr));
-                ovn_lflow_add(lflows, op->od, S_SWITCH_IN_L2_LKUP, 150,
+                ovn_lflow_add(lflows, op->od, S_SWITCH_IN_ARP_RSP, 50,
                               match, actions);
                 free(match);
                 free(actions);
@@ -1333,7 +1349,17 @@ build_lswitch_flows(struct hmap *datapaths, struct hmap *ports,
         }
     }
 
-    /* Ingress table 3: Destination lookup, broadcast and multicast handling
+    /* Ingress table 3: ARP responder, by default goto next.
+     * (priority 0)*/
+    HMAP_FOR_EACH (od, key_node, datapaths) {
+        if (!od->nbs) {
+            continue;
+        }
+
+        ovn_lflow_add(lflows, od, S_SWITCH_IN_ARP_RSP, 0, "1", "next;");
+    }
+
+    /* Ingress table 4: Destination lookup, broadcast and multicast handling
      * (priority 100). */
     HMAP_FOR_EACH (op, key_node, ports) {
         if (!op->nbs) {
@@ -1353,7 +1379,7 @@ build_lswitch_flows(struct hmap *datapaths, struct hmap *ports,
                       "outport = \""MC_FLOOD"\"; output;");
     }
 
-    /* Ingress table 3: Destination lookup, unicast handling (priority 50), */
+    /* Ingress table 4: Destination lookup, unicast handling (priority 50), */
     HMAP_FOR_EACH (op, key_node, ports) {
         if (!op->nbs) {
             continue;
@@ -1390,7 +1416,7 @@ build_lswitch_flows(struct hmap *datapaths, struct hmap *ports,
         }
     }
 
-    /* Ingress table 3: Destination lookup for unknown MACs (priority 0). */
+    /* Ingress table 4: Destination lookup for unknown MACs (priority 0). */
     HMAP_FOR_EACH (od, key_node, datapaths) {
         if (!od->nbs) {
             continue;
-- 
2.1.0




More information about the dev mailing list