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 <az...@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
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to