An upcoming commit will use this as a building block in adding ARP support
to the OVN L3 logical router implementation.

Signed-off-by: Ben Pfaff <b...@ovn.org>
---
 ovn/lib/actions.c | 33 +++++++++++++++++++++++++++++++++
 ovn/ovn-sb.xml    | 21 +++++++++++++--------
 tests/ovn.at      |  3 +++
 3 files changed, 49 insertions(+), 8 deletions(-)

diff --git a/ovn/lib/actions.c b/ovn/lib/actions.c
index 6bc452a..4505b6b 100644
--- a/ovn/lib/actions.c
+++ b/ovn/lib/actions.c
@@ -199,6 +199,37 @@ add_prerequisite(struct action_context *ctx, const char 
*prerequisite)
 }
 
 static void
+parse_arp_action(struct action_context *ctx)
+{
+    if (!lexer_match(ctx->lexer, LEX_T_LCURLY)) {
+        action_syntax_error(ctx, "expecting `{'");
+        return;
+    }
+
+    size_t arp_offset = ctx->ofpacts->size;
+    ofpact_put_ARP(ctx->ofpacts);
+
+    /* XXX What is the right thing to do about prerequisites? */
+    struct expr *save_prereqs = ctx->prereqs;
+    ctx->prereqs = NULL;
+
+    while (!lexer_match(ctx->lexer, LEX_T_RCURLY)) {
+        if (!parse_action(ctx)) {
+            break;
+        }
+    }
+
+    struct ofpact_nest *arp = ofpbuf_at(ctx->ofpacts, arp_offset, sizeof *arp);
+    ctx->ofpacts->header = arp;
+    ofpact_update_len(ctx->ofpacts, &arp->ofpact);
+
+    /* Restore prerequisites. */
+    expr_destroy(ctx->prereqs);
+    ctx->prereqs = save_prereqs;
+    add_prerequisite(ctx, "ip4");
+}
+
+static void
 emit_ct(struct action_context *ctx, bool recirc_next, bool commit)
 {
     struct ofpact_conntrack *ct = ofpact_put_CT(ctx->ofpacts);
@@ -254,6 +285,8 @@ parse_action(struct action_context *ctx)
         emit_ct(ctx, true, false);
     } else if (lexer_match_id(ctx->lexer, "ct_commit")) {
         emit_ct(ctx, false, true);
+    } else if (lexer_match_id(ctx->lexer, "arp")) {
+        parse_arp_action(ctx);
     } else {
         action_syntax_error(ctx, "expecting action");
     }
diff --git a/ovn/ovn-sb.xml b/ovn/ovn-sb.xml
index e674f3a..8ce2e74 100644
--- a/ovn/ovn-sb.xml
+++ b/ovn/ovn-sb.xml
@@ -907,14 +907,6 @@
           Commit the flow to the connection tracking entry associated
           with it by a previous call to <code>ct_next</code>.
         </dd>
-      </dl>
-
-      <p>
-        The following actions will likely be useful later, but they have not
-        been thought out carefully.
-      </p>
-
-      <dl>
 
         <dt><code>arp { <var>action</var>; </code>...<code> };</code></dt>
         <dd>
@@ -942,9 +934,22 @@
             <li><code>arp.tpa</code> copied from <code>ip4.dst</code></li>
           </ul>
 
+          <p>
+            The ARP packet has the same VLAN header, if any, as the IP packet
+            it replaces.
+          </p>
+
           <p><b>Prerequisite:</b> <code>ip4</code></p>
         </dd>
 
+      </dl>
+
+      <p>
+        The following actions will likely be useful later, but they have not
+        been thought out carefully.
+      </p>
+
+      <dl>
         <dt><code>icmp4 { <var>action</var>; </code>...<code> };</code></dt>
         <dd>
           <p>
diff --git a/tests/ovn.at b/tests/ovn.at
index e00674d..6ce9339 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -462,6 +462,9 @@ outport <-> inport; => 
actions=push:NXM_NX_REG6[],push:NXM_NX_REG7[],pop:NXM_NX_
 ip.ttl--; => actions=dec_ttl, prereqs=ip
 ip.ttl = 4; => actions=set_field:4->nw_ttl, prereqs=eth.type == 0x800 || 
eth.type == 0x86dd
 
+# arp
+arp { eth.dst = ff:ff:ff:ff:ff:ff; output; }; => 
actions=arp(set_field:ff:ff:ff:ff:ff:ff->eth_dst,resubmit(,64)), prereqs=ip4
+
 # Contradictionary prerequisites (allowed but not useful):
 ip4.src = ip6.src[0..31]; => 
actions=move:NXM_NX_IPV6_SRC[0..31]->NXM_OF_IP_SRC[], prereqs=eth.type == 0x800 
&& eth.type == 0x86dd
 ip4.src <-> ip6.src[0..31]; => 
actions=push:NXM_NX_IPV6_SRC[0..31],push:NXM_OF_IP_SRC[],pop:NXM_NX_IPV6_SRC[0..31],pop:NXM_OF_IP_SRC[],
 prereqs=eth.type == 0x800 && eth.type == 0x86dd
-- 
2.1.3

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to