summaryrefslogtreecommitdiff
path: root/ofproto
diff options
context:
space:
mode:
authorWilliam Tu <u9012063@gmail.com>2016-12-18 00:13:02 -0800
committerBen Pfaff <blp@ovn.org>2016-12-19 21:02:10 -0800
commit7ae62a676d3a754aa5a0dcb310eff6e1b93c91b9 (patch)
treeff8afcba14c0420db7babf453070d2166700ec22 /ofproto
parent4b1a2aef1a0546d16cff25bfae2798256a3cdd5d (diff)
downloadopenvswitch-7ae62a676d3a754aa5a0dcb310eff6e1b93c91b9.tar.gz
ofp-actions: Add clone action.
This patch adds OpenFlow clone action with syntax as below: "clone([action][,action...])". The clone() action makes a copy of the current packet and executes the list of actions against the packet, without affecting the packet after the "clone(...)" action. In other word, the packet before the clone() and after the clone() is the same, no matter what actions executed inside the clone(). Use case 1: Set different fields and output to different ports without unset actions= clone(mod_dl_src:<mac1>, output:1), clone(mod_dl_dst:<mac2>, output:2), output:3 Since each clone() has independent packet, output:1 has only dl_src modified, output:2 has only dl_dst modified, output:3 has original packet. Similar to case1 actions= push_vlan(...), output:2, pop_vlan, push_vlan(...), output:3 can be changed to actions= clone(push_vlan(...), output:2),clone(push_vlan(...), output:3) without having to add pop_vlan. case 2: resubmit to another table without worrying packet being modified actions=clone(resubmit(1,2)), ... Signed-off-by: William Tu <u9012063@gmail.com> [blp@ovn.org revised this to omit the "sample" action] Signed-off-by: Ben Pfaff <blp@ovn.org>
Diffstat (limited to 'ofproto')
-rw-r--r--ofproto/ofproto-dpif-xlate.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index d0f9a3354..eec1dae7a 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -4290,6 +4290,14 @@ xlate_sample_action(struct xlate_ctx *ctx,
tunnel_out_port, false);
}
+static void
+compose_clone_action(struct xlate_ctx *ctx, const struct ofpact_nest *oc)
+{
+ struct flow old_flow = ctx->xin->flow;
+ do_xlate_actions(oc->actions, ofpact_nest_get_action_len(oc), ctx);
+ ctx->xin->flow = old_flow;
+}
+
static bool
may_receive(const struct xport *xport, struct xlate_ctx *ctx)
{
@@ -4448,6 +4456,7 @@ freeze_unroll_actions(const struct ofpact *a, const struct ofpact *end,
case OFPACT_WRITE_ACTIONS:
case OFPACT_METER:
case OFPACT_SAMPLE:
+ case OFPACT_CLONE:
case OFPACT_DEBUG_RECIRC:
case OFPACT_CT:
case OFPACT_NAT:
@@ -4696,6 +4705,7 @@ recirc_for_mpls(const struct ofpact *a, struct xlate_ctx *ctx)
case OFPACT_NOTE:
case OFPACT_EXIT:
case OFPACT_SAMPLE:
+ case OFPACT_CLONE:
case OFPACT_UNROLL_XLATE:
case OFPACT_CT:
case OFPACT_NAT:
@@ -5055,6 +5065,10 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
xlate_sample_action(ctx, ofpact_get_SAMPLE(a));
break;
+ case OFPACT_CLONE:
+ compose_clone_action(ctx, ofpact_get_CLONE(a));
+ break;
+
case OFPACT_CT:
compose_conntrack_action(ctx, ofpact_get_CT(a));
break;