[ovs-dev] [userspace clone v2 4/4] xlate: Generate of datapath clone action when supported
Jarno Rajahalme
jarno at ovn.org
Fri Jan 20 19:12:09 UTC 2017
Acked-by: Jarno Rajahalme <jarno at ovn.org>
> On Jan 19, 2017, at 11:07 PM, Andy Zhou <azhou at ovn.org> wrote:
>
> Add logic to detect whether datapath support clone.
> Enhance the xlate logic to make use of it.
> Added logic to turn on/off clone support for testing.
>
> Signed-off-by: Andy Zhou <azhou at ovn.org>
> ---
> ofproto/ofproto-dpif-xlate.c | 38 ++++++++++++++++++++++++++++++++++++--
> ofproto/ofproto-dpif-xlate.h | 2 ++
> ofproto/ofproto-dpif.c | 23 +++++++++++++++++++++++
> tests/ofproto-dpif.at | 11 +++++++++++
> 4 files changed, 72 insertions(+), 2 deletions(-)
>
> diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
> index 9a15ec3..0513394 100644
> --- a/ofproto/ofproto-dpif-xlate.c
> +++ b/ofproto/ofproto-dpif-xlate.c
> @@ -4520,9 +4520,23 @@ xlate_sample_action(struct xlate_ctx *ctx,
> tunnel_out_port, false);
> }
>
> +/* Only called if the datapath supports 'OVS_ACTION_ATTR_CLONE'.
> + *
> + * Translates 'oc' within OVS_ACTION_ATTR_CLONE. */
> static void
> compose_clone_action(struct xlate_ctx *ctx, const struct ofpact_nest *oc)
> {
> + size_t clone_offset = nl_msg_start_nested(ctx->odp_actions,
> + OVS_ACTION_ATTR_CLONE);
> +
> + do_xlate_actions(oc->actions, ofpact_nest_get_action_len(oc), ctx);
> +
> + nl_msg_end_non_empty_nested(ctx->odp_actions, clone_offset);
> +}
> +
> +static void
> +xlate_clone(struct xlate_ctx *ctx, const struct ofpact_nest *oc)
> +{
> bool old_was_mpls = ctx->was_mpls;
> bool old_conntracked = ctx->conntracked;
> struct flow old_flow = ctx->xin->flow;
> @@ -4537,7 +4551,16 @@ compose_clone_action(struct xlate_ctx *ctx, const struct ofpact_nest *oc)
> ofpbuf_use_stub(&ctx->action_set, actset_stub, sizeof actset_stub);
> ofpbuf_put(&ctx->action_set, old_action_set.data, old_action_set.size);
>
> - do_xlate_actions(oc->actions, ofpact_nest_get_action_len(oc), ctx);
> + if (ctx->xbridge->support.clone) {
> + /* Datapath clone action will make sure the pre clone packets
> + * are used for actions after clone. Save and restore
> + * ctx->base_flow to reflect this for the openflow pipeline. */
> + struct flow old_base_flow = ctx->base_flow;
> + compose_clone_action(ctx, oc);
> + ctx->base_flow = old_base_flow;
> + } else {
> + do_xlate_actions(oc->actions, ofpact_nest_get_action_len(oc), ctx);
> + }
>
> ofpbuf_uninit(&ctx->action_set);
> ctx->action_set = old_action_set;
> @@ -5383,7 +5406,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
> break;
>
> case OFPACT_CLONE:
> - compose_clone_action(ctx, ofpact_get_CLONE(a));
> + xlate_clone(ctx, ofpact_get_CLONE(a));
> break;
>
> case OFPACT_CT:
> @@ -6169,3 +6192,14 @@ xlate_mac_learning_update(const struct ofproto_dpif *ofproto,
>
> update_learning_table__(xbridge, xbundle, dl_src, vlan, is_grat_arp);
> }
> +
> +void
> +xlate_disable_dp_clone(const struct ofproto_dpif *ofproto)
> +{
> + struct xlate_cfg *xcfg = ovsrcu_get(struct xlate_cfg *, &xcfgp);
> + struct xbridge *xbridge = xbridge_lookup(xcfg, ofproto);
> +
> + if (xbridge) {
> + xbridge->support.clone = false;
> + }
> +}
> diff --git a/ofproto/ofproto-dpif-xlate.h b/ofproto/ofproto-dpif-xlate.h
> index 5d00d6d..3986f26 100644
> --- a/ofproto/ofproto-dpif-xlate.h
> +++ b/ofproto/ofproto-dpif-xlate.h
> @@ -206,6 +206,8 @@ void xlate_mac_learning_update(const struct ofproto_dpif *ofproto,
> ofp_port_t in_port, struct eth_addr dl_src,
> int vlan, bool is_grat_arp);
>
> +void xlate_disable_dp_clone(const struct ofproto_dpif *);
> +
> void xlate_txn_start(void);
> void xlate_txn_commit(void);
>
> diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
> index 5ef0720..72bfbbc 100644
> --- a/ofproto/ofproto-dpif.c
> +++ b/ofproto/ofproto-dpif.c
> @@ -5025,6 +5025,26 @@ disable_datapath_truncate(struct unixctl_conn *conn OVS_UNUSED,
> }
>
> static void
> +disable_datapath_clone(struct unixctl_conn *conn OVS_UNUSED,
> + int argc, const char *argv[],
> + void *aux OVS_UNUSED)
> +{
> + struct ds ds = DS_EMPTY_INITIALIZER;
> + const char *br = argv[argc -1];
> + struct ofproto_dpif *ofproto;
> +
> + ofproto = ofproto_dpif_lookup(br);
> + if (!ofproto) {
> + unixctl_command_reply_error(conn, "no such bridge");
> + return;
> + }
> + xlate_disable_dp_clone(ofproto);
> + udpif_flush(ofproto->backer->udpif);
> + ds_put_format(&ds, "Datapath clone action disabled for bridge %s", br);
> + unixctl_command_reply(conn, ds_cstr(&ds));
> +}
> +
> +static void
> ofproto_unixctl_init(void)
> {
> static bool registered;
> @@ -5053,6 +5073,9 @@ ofproto_unixctl_init(void)
>
> unixctl_command_register("dpif/disable-truncate", "", 0, 0,
> disable_datapath_truncate, NULL);
> +
> + unixctl_command_register("dpif/disable-dp-clone", "bridge", 1, 1,
> + disable_datapath_clone, NULL);
> }
>
> static odp_port_t
> diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at
> index a4bf5a3..e861d9f 100644
> --- a/tests/ofproto-dpif.at
> +++ b/tests/ofproto-dpif.at
> @@ -6446,6 +6446,17 @@ AT_CHECK([ovs-ofctl add-flows br0 flows.txt], [0], [ignore])
> AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(1),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.10.10.2,dst=10.10.10.1,proto=1,tos=1,ttl=128,frag=no),icmp(type=8,code=0)'], [0], [stdout])
>
> AT_CHECK([tail -1 stdout], [0], [dnl
> +Datapath actions: clone(set(ipv4(src=10.10.10.2,dst=192.168.4.4)),2),clone(set(eth(src=80:81:81:81:81:81)),set(ipv4(src=10.10.10.2,dst=192.168.5.5)),3),4
> +])
> +
> +dnl Test flow xlate openflow clone action without using datapath clone action.
> +AT_CHECK([ovs-appctl dpif/disable-dp-clone br0], [0],
> +[Datapath clone action disabled for bridge br0
> +])
> +
> +AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(1),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.10.10.2,dst=10.10.10.1,proto=1,tos=1,ttl=128,frag=no),icmp(type=8,code=0)'], [0], [stdout])
> +
> +AT_CHECK([tail -1 stdout], [0], [dnl
> Datapath actions: set(ipv4(src=10.10.10.2,dst=192.168.4.4)),2,set(eth(src=80:81:81:81:81:81)),set(ipv4(src=10.10.10.2,dst=192.168.5.5)),3,set(eth(src=50:54:00:00:00:09)),set(ipv4(src=10.10.10.2,dst=10.10.10.1)),4
> ])
>
> --
> 1.9.1
>
> _______________________________________________
> dev mailing list
> dev at openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
More information about the dev
mailing list