Re: [ovs-dev] [PATCH v10 2/4] ovn-controller: Add a new action - 'put_nd_ra_opts'
On Thu, Nov 02, 2017 at 06:19:24AM +0530, nusid...@redhat.com wrote: > From: Numan Siddique > > This patch adds a new OVN action 'put_nd_ra_opts' to support native > IPv6 Router Advertisement in OVN. This action can be used to respond > to the IPv6 Router Solicitation requests. Thanks for the patch! I folded in the following changes because I didn't think it made sense to mention the function name in error messages; we don't do that elsewhere. diff --git a/ovn/lib/actions.c b/ovn/lib/actions.c index 8cec5c7d0871..0df5edbaa51d 100644 --- a/ovn/lib/actions.c +++ b/ovn/lib/actions.c @@ -1851,69 +1851,57 @@ parse_put_nd_ra_opts(struct action_context *ctx, const struct expr_field *dst, o < &po->options[po->n_options]; o++) { const union expr_constant *c = o->value.values; if (o->value.n_values > 1) { -lexer_error(ctx->lexer, "parse_put_nd_ra_opts -Invalid value for" -" the option %s.", o->option->name); +lexer_error(ctx->lexer, "Invalid value for \"%s\" option", +o->option->name); return; } +bool ok = true; switch (o->option->code) { case ND_RA_FLAG_ADDR_MODE: -if (!c->string || (strcmp(c->string, "slaac") && - strcmp(c->string, "dhcpv6_stateful") && - strcmp(c->string, "dhcpv6_stateless"))) { -lexer_error(ctx->lexer, "parse_put_nd_ra_opts -Invalid value " -"for the option %s.", o->option->name); -return; -} - -if (!strcmp(c->string, "dhcpv6_stateful")) { +ok = (c->string && (!strcmp(c->string, "slaac") || +!strcmp(c->string, "dhcpv6_stateful") || +!strcmp(c->string, "dhcpv6_stateless"))); +if (ok && !strcmp(c->string, "dhcpv6_stateful")) { addr_mode_stateful = true; } break; case ND_OPT_SOURCE_LINKADDR: -if (c->format != LEX_F_ETHERNET) { -lexer_error(ctx->lexer, "parse_put_nd_ra_opts -Invalid value " - "for the option %s.", o->option->name); -} +ok = c->format == LEX_F_ETHERNET; slla_present = true; break; case ND_OPT_PREFIX_INFORMATION: -if (c->format != LEX_F_IPV6 || !c->masked) { -lexer_error(ctx->lexer, "parse_put_nd_ra_opts -Invalid value " -"for the option %s.", o->option->name); -} +ok = c->format == LEX_F_IPV6 && c->masked; prefix_set = true; break; case ND_OPT_MTU: -if (c->format != LEX_F_DECIMAL) { -lexer_error(ctx->lexer, "parse_put_nd_ra_opts -Invalid value " -"for the option %s.", o->option->name); -} +ok = c->format == LEX_F_DECIMAL; break; } -} -if (ctx->lexer->error) { -return; +if (!ok) { +lexer_error(ctx->lexer, "Invalid value for \"%s\" option", +o->option->name); +return; +} } if (!slla_present) { -lexer_error(ctx->lexer, "parse_put_nd_ra_opts - slla option not" -" present."); +lexer_error(ctx->lexer, "slla option not present"); return; } if (addr_mode_stateful && prefix_set) { -lexer_error(ctx->lexer, "parse_put_nd_ra_opts - prefix option can't be" +lexer_error(ctx->lexer, "prefix option can't be" " set when address mode is dhcpv6_stateful."); return; } if (!addr_mode_stateful && !prefix_set) { -lexer_error(ctx->lexer, "parse_put_nd_ra_opts - prefix option needs " +lexer_error(ctx->lexer, "prefix option needs " "to be set when address mode is slaac/dhcpv6_stateless."); return; } diff --git a/tests/ovn.at b/tests/ovn.at index 320ec4bb2b72..93515aa329d1 100644 --- a/tests/ovn.at +++ b/tests/ovn.at @@ -1083,25 +1083,25 @@ reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateless", slla = ae:01:02:03:04:0 encodes as controller(userdata=00.00.00.08.00.00.00.00.00.01.de.10.00.00.00.40.86.00.00.00.ff.40.ff.ff.00.00.00.00.00.00.00.00.01.01.ae.01.02.03.04.06.03.04.40.c0.ff.ff.ff.ff.ff.ff.ff.ff.00.00.00.00.ae.f0.00.00.00.00.00.00.00.00.00.00.00.00.00.00,pause) has prereqs ip6 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::/64); -parse_put_nd_ra_opts - slla option not present. +slla option not present reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateful", mtu = 1450, prefix = aef0::/64, prefix = bef0::/64, slla = ae:01:02:03:04:10); -parse_put_nd_ra_opts - prefix option can't be set when address mode is dhcpv6_statefu
[ovs-dev] [PATCH v10 2/4] ovn-controller: Add a new action - 'put_nd_ra_opts'
From: Numan Siddique This patch adds a new OVN action 'put_nd_ra_opts' to support native IPv6 Router Advertisement in OVN. This action can be used to respond to the IPv6 Router Solicitation requests. ovn-controller parses this action and adds a NXT_PACKET_IN2 OF flow with 'pause' flag set and the RA options stored in 'userdata' field. This action is similar to 'put_dhcp_opts' and 'put_dhcpv6_opts'. When a valid IPv6 RS packet is received by the pinctrl module of ovn-controller, it frames a new RA packet and sets the RA options from the 'userdata' field and resumes the packet storing 1 in the 1-bit result sub-field. If the packet is invalid, it resumes the packet without any modifications storing 0 in the 1-bit result sub-field. Eg. reg0[5] = put_nd_ra_opts(address_mode = "slaac", mtu = 1450, slla = 01:02:03:04:05:06, prefix = aef0::/64) Note that unlike DHCPv4/v6, a new table to store the supported IPv6 ND RA options is not added in SB DB since there are only 3 ND RA options. Co-authored-by: Zongkai LI Signed-off-by: Zongkai LI Signed-off-by: Numan Siddique --- include/ovn/actions.h | 14 +++- ovn/controller/lflow.c| 13 +++- ovn/controller/pinctrl.c | 96 +++ ovn/lib/actions.c | 194 +- ovn/lib/ovn-l7.h | 48 ovn/ovn-sb.xml| 77 ++ ovn/utilities/ovn-trace.c | 51 tests/ovn.at | 31 tests/test-ovn.c | 13 +++- 9 files changed, 516 insertions(+), 21 deletions(-) diff --git a/include/ovn/actions.h b/include/ovn/actions.h index d13a3747b..15cee478d 100644 --- a/include/ovn/actions.h +++ b/include/ovn/actions.h @@ -72,7 +72,8 @@ struct simap; OVNACT(PUT_DHCPV6_OPTS, ovnact_put_opts)\ OVNACT(SET_QUEUE, ovnact_set_queue) \ OVNACT(DNS_LOOKUP,ovnact_dns_lookup) \ -OVNACT(LOG, ovnact_log) +OVNACT(LOG, ovnact_log) \ +OVNACT(PUT_ND_RA_OPTS,ovnact_put_opts) /* enum ovnact_type, with a member OVNACT_ for each action. */ enum OVS_PACKED_ENUM ovnact_type { @@ -418,6 +419,14 @@ enum action_opcode { * - A variable length string containing the name. */ ACTION_OPCODE_LOG, + +/* "result = put_nd_ra_opts(option, ...)". + * Arguments follow the action_header, in this format: + * - A 32-bit or 64-bit OXM header designating the result field. + * - A 32-bit integer specifying a bit offset within the result field. + * - Any number of ICMPv6 options. + */ +ACTION_OPCODE_PUT_ND_RA_OPTS, }; /* Header. */ @@ -438,6 +447,9 @@ struct ovnact_parse_params { /* hmap of 'struct gen_opts_map' to support 'put_dhcpv6_opts' action */ const struct hmap *dhcpv6_opts; +/* hmap of 'struct gen_opts_map' to support 'put_nd_ra_opts' action */ +const struct hmap *nd_ra_opts; + /* Each OVN flow exists in a logical table within a logical pipeline. * These parameters express this context for a set of OVN actions being * parsed: diff --git a/ovn/controller/lflow.c b/ovn/controller/lflow.c index 6b6b91abc..a62ec6ebe 100644 --- a/ovn/controller/lflow.c +++ b/ovn/controller/lflow.c @@ -65,6 +65,7 @@ static void consider_logical_flow(struct controller_ctx *ctx, const struct sbrec_chassis *chassis, struct hmap *dhcp_opts, struct hmap *dhcpv6_opts, + struct hmap *nd_ra_opts, uint32_t *conj_id_ofs, const struct shash *addr_sets, struct hmap *flow_table, @@ -167,17 +168,21 @@ add_logical_flows(struct controller_ctx *ctx, dhcpv6_opt_row->type); } +struct hmap nd_ra_opts = HMAP_INITIALIZER(&nd_ra_opts); +nd_ra_opts_init(&nd_ra_opts); + SBREC_LOGICAL_FLOW_FOR_EACH (lflow, ctx->ovnsb_idl) { consider_logical_flow(ctx, chassis_index, lflow, local_datapaths, group_table, chassis, - &dhcp_opts, &dhcpv6_opts, &conj_id_ofs, - addr_sets, flow_table, active_tunnels, - local_lport_ids); + &dhcp_opts, &dhcpv6_opts, &nd_ra_opts, + &conj_id_ofs, addr_sets, flow_table, + active_tunnels, local_lport_ids); } dhcp_opts_destroy(&dhcp_opts); dhcp_opts_destroy(&dhcpv6_opts); +nd_ra_opts_destroy(&nd_ra_opts); } static void @@ -189,6 +194,7 @@ consider_logical_flow(struct controller_ctx *ctx, const struct sbrec_chassis *chassis, struct hmap *dhcp_opts, str