diff mbox

[ovs-dev,v3] ovn: support ARP response for known IPs

Message ID 1448401400-13171-1-git-send-email-zhouhan@gmail.com
State Changes Requested
Headers show

Commit Message

Han Zhou Nov. 24, 2015, 9:43 p.m. UTC
For lswitch ports with known IPs, ARP is responded directly from
local ovn-controller to avoid flooding.

Signed-off-by: Han Zhou <zhouhan@gmail.com>
---

Notes:
    v1->v2: remove the extra arg of xasprintf()
    v2->v3: update ovn-northd.8.xml to describe the new flows

 ovn/northd/ovn-northd.8.xml | 18 ++++++++++++++++++
 ovn/northd/ovn-northd.c     | 38 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 56 insertions(+)

Comments

Ben Pfaff Nov. 30, 2015, 12:33 a.m. UTC | #1
On Tue, Nov 24, 2015 at 01:43:20PM -0800, Han Zhou wrote:
> For lswitch ports with known IPs, ARP is responded directly from
> local ovn-controller to avoid flooding.
> 
> Signed-off-by: Han Zhou <zhouhan@gmail.com>
> ---
> 
> Notes:
>     v1->v2: remove the extra arg of xasprintf()
>     v2->v3: update ovn-northd.8.xml to describe the new flows

Sorry to bother you with another change request, but I'd very much
appreciate if you could adapt one of the OVN tests to verify that this
works properly.
Han Zhou Nov. 30, 2015, 7:50 p.m. UTC | #2
On Sun, Nov 29, 2015 at 4:33 PM, Ben Pfaff <blp@ovn.org> wrote:
> On Tue, Nov 24, 2015 at 01:43:20PM -0800, Han Zhou wrote:
>> For lswitch ports with known IPs, ARP is responded directly from
>> local ovn-controller to avoid flooding.
>>
>> Signed-off-by: Han Zhou <zhouhan@gmail.com>
>> ---
>>
>> Notes:
>>     v1->v2: remove the extra arg of xasprintf()
>>     v2->v3: update ovn-northd.8.xml to describe the new flows
>
> Sorry to bother you with another change request, but I'd very much
> appreciate if you could adapt one of the OVN tests to verify that this
> works properly.

Done :) I just submitted v4 for review.
diff mbox

Patch

diff --git a/ovn/northd/ovn-northd.8.xml b/ovn/northd/ovn-northd.8.xml
index e7dec72..2cd2818 100644
--- a/ovn/northd/ovn-northd.8.xml
+++ b/ovn/northd/ovn-northd.8.xml
@@ -204,6 +204,24 @@ 
 
     <ul>
       <li>
+        Priority-150 flows that matches ARP requests to each known IP address
+        <var>A</var> of logical port <var>P</var>, and respond ARP replies
+        directly with corresponding Ethernet address <var>E</var>:
+        <pre>
+eth.dst = eth.src;
+eth.src = <var>E</var>;
+arp.op = 2; /* ARP reply. */
+arp.tha = arp.sha;
+arp.sha = <var>E</var>;
+arp.tpa = arp.spa;
+arp.spa = <var>A</var>;
+outport = <var>P</var>;
+inport = ""; /* Allow sending out inport. */
+output;
+        </pre>
+      </li>
+
+      <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 8fe0c2c..ec13171 100644
--- a/ovn/northd/ovn-northd.c
+++ b/ovn/northd/ovn-northd.c
@@ -1151,6 +1151,44 @@  build_lswitch_flows(struct hmap *datapaths, struct hmap *ports,
         ds_destroy(&match);
     }
 
+    /* Ingress table 3: Destination lookup, ARP reply for known IPs.
+     * (priority 150). */
+    HMAP_FOR_EACH (op, key_node, ports) {
+        if (!op->nbs) {
+            continue;
+        }
+
+        for (size_t i = 0; i < op->nbs->n_addresses; i++) {
+            struct eth_addr ea;
+            ovs_be32 ip;
+
+            if (ovs_scan(op->nbs->addresses[i],
+                         ETH_ADDR_SCAN_FMT" "IP_SCAN_FMT,
+                         ETH_ADDR_SCAN_ARGS(ea), IP_SCAN_ARGS(&ip))) {
+                char *match = xasprintf(
+                    "arp.tpa == "IP_FMT" && arp.op == 1", IP_ARGS(ip));
+                char *actions = xasprintf(
+                    "eth.dst = eth.src; "
+                    "eth.src = "ETH_ADDR_FMT"; "
+                    "arp.op = 2; /* ARP reply */ "
+                    "arp.tha = arp.sha; "
+                    "arp.sha = "ETH_ADDR_FMT"; "
+                    "arp.tpa = arp.spa; "
+                    "arp.spa = "IP_FMT"; "
+                    "outport = inport; "
+                    "inport = \"\"; /* Allow sending out inport. */ "
+                    "output;",
+                    ETH_ADDR_ARGS(ea),
+                    ETH_ADDR_ARGS(ea),
+                    IP_ARGS(ip));
+                ovn_lflow_add(lflows, op->od, S_SWITCH_IN_L2_LKUP, 150,
+                              match, actions);
+                free(match);
+                free(actions);
+            }
+        }
+    }
+
     /* Ingress table 3: Destination lookup, broadcast and multicast handling
      * (priority 100). */
     HMAP_FOR_EACH (op, key_node, ports) {