[ovs-dev] [userspace clone v3 4/4] xlate: Generate of datapath clone action when supported
Andy Zhou
azhou at ovn.org
Sat Jan 21 02:05:55 UTC 2017
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>
Acked-by: Jarno Rajahalme <jarno 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 df291f3..e1112eb 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
More information about the dev
mailing list