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