diff mbox

[ovs-dev,3/3] xlate: Translate openflow clone into odp sample action.

Message ID 1487293868-21605-3-git-send-email-azhou@ovn.org
State Accepted
Headers show

Commit Message

Andy Zhou Feb. 17, 2017, 1:11 a.m. UTC
When datapath does not support the 'clone' action directly, generate
sample action (with 100% probability) instead.

Specifically, currently, there is no plan to support the 'clone'
action on the Linux kernel datapath directly, so the sample action
will be used to translate the openflow clone action for this datapath.

Signed-off-by: Andy Zhou <azhou@ovn.org>
---
 ofproto/ofproto-dpif-xlate.c | 38 ++++++++++++++++++++++++++++----------
 tests/ofproto-dpif.at        |  2 +-
 2 files changed, 29 insertions(+), 11 deletions(-)

Comments

Jarno Rajahalme March 2, 2017, 10:59 p.m. UTC | #1
Acked-by: Jarno Rajahalme <jarno@ovn.org>

> On Feb 16, 2017, at 5:11 PM, Andy Zhou <azhou@ovn.org> wrote:
> 
> When datapath does not support the 'clone' action directly, generate
> sample action (with 100% probability) instead.
> 
> Specifically, currently, there is no plan to support the 'clone'
> action on the Linux kernel datapath directly, so the sample action
> will be used to translate the openflow clone action for this datapath.
> 
> Signed-off-by: Andy Zhou <azhou@ovn.org>
> ---
> ofproto/ofproto-dpif-xlate.c | 38 ++++++++++++++++++++++++++++----------
> tests/ofproto-dpif.at        |  2 +-
> 2 files changed, 29 insertions(+), 11 deletions(-)
> 
> diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
> index c4ca5d2..1a5fdf8 100644
> --- a/ofproto/ofproto-dpif-xlate.c
> +++ b/ofproto/ofproto-dpif-xlate.c
> @@ -4659,18 +4659,36 @@ 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. */
> +/* Use datapath 'clone' or sample to enclose the translation of 'oc'.   */
> 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);
> +}
> +
> +/* Use datapath 'sample' action to translate clone.  */
> +static void
> +compose_clone_action_using_sample(struct xlate_ctx *ctx,
> +                                  const struct ofpact_nest *oc)
> +{
> +    size_t offset = nl_msg_start_nested(ctx->odp_actions,
> +                                        OVS_ACTION_ATTR_SAMPLE);
> +
> +    size_t ac_offset = nl_msg_start_nested(ctx->odp_actions,
> +                                           OVS_SAMPLE_ATTR_ACTIONS);
> 
>     do_xlate_actions(oc->actions, ofpact_nest_get_action_len(oc), ctx);
> 
> -    nl_msg_end_non_empty_nested(ctx->odp_actions, clone_offset);
> +    if (nl_msg_end_non_empty_nested(ctx->odp_actions, ac_offset)) {
> +        nl_msg_cancel_nested(ctx->odp_actions, offset);
> +    } else {
> +        nl_msg_put_u32(ctx->odp_actions, OVS_SAMPLE_ATTR_PROBABILITY,
> +                       UINT32_MAX); /* 100% probability. */
> +        nl_msg_end_nested(ctx->odp_actions, offset);
> +    }
> }
> 
> static void
> @@ -4690,16 +4708,16 @@ xlate_clone(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);
> 
> +    /* 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;
>     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);
> +        compose_clone_action_using_sample(ctx, oc);
>     }
> +    ctx->base_flow = old_base_flow;
> 
>     ofpbuf_uninit(&ctx->action_set);
>     ctx->action_set = old_action_set;
> diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at
> index e861d9f..f1415e4 100644
> --- a/tests/ofproto-dpif.at
> +++ b/tests/ofproto-dpif.at
> @@ -6457,7 +6457,7 @@ AT_CHECK([ovs-appctl dpif/disable-dp-clone br0], [0],
> 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
> +Datapath actions: sample(sample=100.0%,actions(set(ipv4(src=10.10.10.2,dst=192.168.4.4)),2)),sample(sample=100.0%,actions(set(eth(src=80:81:81:81:81:81)),set(ipv4(src=10.10.10.2,dst=192.168.5.5)),3)),4
> ])
> 
> OVS_VSWITCHD_STOP
> -- 
> 1.8.3.1
> 
> _______________________________________________
> dev mailing list
> dev@openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
diff mbox

Patch

diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index c4ca5d2..1a5fdf8 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -4659,18 +4659,36 @@  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. */
+/* Use datapath 'clone' or sample to enclose the translation of 'oc'.   */
 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);
+}
+
+/* Use datapath 'sample' action to translate clone.  */
+static void
+compose_clone_action_using_sample(struct xlate_ctx *ctx,
+                                  const struct ofpact_nest *oc)
+{
+    size_t offset = nl_msg_start_nested(ctx->odp_actions,
+                                        OVS_ACTION_ATTR_SAMPLE);
+
+    size_t ac_offset = nl_msg_start_nested(ctx->odp_actions,
+                                           OVS_SAMPLE_ATTR_ACTIONS);
 
     do_xlate_actions(oc->actions, ofpact_nest_get_action_len(oc), ctx);
 
-    nl_msg_end_non_empty_nested(ctx->odp_actions, clone_offset);
+    if (nl_msg_end_non_empty_nested(ctx->odp_actions, ac_offset)) {
+        nl_msg_cancel_nested(ctx->odp_actions, offset);
+    } else {
+        nl_msg_put_u32(ctx->odp_actions, OVS_SAMPLE_ATTR_PROBABILITY,
+                       UINT32_MAX); /* 100% probability. */
+        nl_msg_end_nested(ctx->odp_actions, offset);
+    }
 }
 
 static void
@@ -4690,16 +4708,16 @@  xlate_clone(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);
 
+    /* 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;
     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);
+        compose_clone_action_using_sample(ctx, oc);
     }
+    ctx->base_flow = old_base_flow;
 
     ofpbuf_uninit(&ctx->action_set);
     ctx->action_set = old_action_set;
diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at
index e861d9f..f1415e4 100644
--- a/tests/ofproto-dpif.at
+++ b/tests/ofproto-dpif.at
@@ -6457,7 +6457,7 @@  AT_CHECK([ovs-appctl dpif/disable-dp-clone br0], [0],
 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
+Datapath actions: sample(sample=100.0%,actions(set(ipv4(src=10.10.10.2,dst=192.168.4.4)),2)),sample(sample=100.0%,actions(set(eth(src=80:81:81:81:81:81)),set(ipv4(src=10.10.10.2,dst=192.168.5.5)),3)),4
 ])
 
 OVS_VSWITCHD_STOP