diff options
author | William Tu <u9012063@gmail.com> | 2016-12-18 00:13:02 -0800 |
---|---|---|
committer | Ben Pfaff <blp@ovn.org> | 2016-12-19 21:02:10 -0800 |
commit | 7ae62a676d3a754aa5a0dcb310eff6e1b93c91b9 (patch) | |
tree | ff8afcba14c0420db7babf453070d2166700ec22 /ofproto | |
parent | 4b1a2aef1a0546d16cff25bfae2798256a3cdd5d (diff) | |
download | openvswitch-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.c | 14 |
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; |