From 7ae62a676d3a754aa5a0dcb310eff6e1b93c91b9 Mon Sep 17 00:00:00 2001 From: William Tu Date: Sun, 18 Dec 2016 00:13:02 -0800 Subject: 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:, output:1), clone(mod_dl_dst:, 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 [blp@ovn.org revised this to omit the "sample" action] Signed-off-by: Ben Pfaff --- ofproto/ofproto-dpif-xlate.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'ofproto') 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; -- cgit v1.2.1