[ovs-dev] [PATCH 3/3] xlate: Generate of datapath clone action when supported

Jarno Rajahalme jarno at ovn.org
Fri Jan 20 02:22:50 UTC 2017


Needs rebasing if you address my comments to the previous patch.

  Jarno

> On Jan 13, 2017, at 4:13 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 | 44 ++++++++++++++++++++++++++++++++++++++++++--
> ofproto/ofproto-dpif-xlate.h |  2 ++
> ofproto/ofproto-dpif.c       | 23 +++++++++++++++++++++++
> tests/ofproto-dpif.at        | 11 +++++++++++
> 4 files changed, 78 insertions(+), 2 deletions(-)
> 
> diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
> index e02771e..89801f7 100644
> --- a/ofproto/ofproto-dpif-xlate.c
> +++ b/ofproto/ofproto-dpif-xlate.c
> @@ -4520,9 +4520,29 @@ 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;
> +    size_t actions_offset;
> +
> +    clone_offset = nl_msg_start_nested(ctx->odp_actions,
> +                                       OVS_ACTION_ATTR_CLONE);
> +    actions_offset = nl_msg_start_nested(ctx->odp_actions,
> +                                         OVS_CLONE_ATTR_ACTIONS);
> +
> +    do_xlate_actions(oc->actions, ofpact_nest_get_action_len(oc), ctx);
> +
> +    nl_msg_end_non_empty_nested(ctx->odp_actions, actions_offset);
> +    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 +4557,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 +5412,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 +6198,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 fca93a0..327aac9 100644
> --- a/ofproto/ofproto-dpif.c
> +++ b/ofproto/ofproto-dpif.c
> @@ -5015,6 +5015,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;
> @@ -5043,6 +5063,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
> ])
> 
> -- 
> 2.7.4
> 
> _______________________________________________
> dev mailing list
> dev at openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev



More information about the dev mailing list