When OVS sees a tunnel push with a nested list next, it will not clone the packet, as a clone is not needed. However, a clone action will still be created with the tunnel push encapulated inside. There is no need to create the clone action in this case, as extra parsing will need to be performed, which is less efficient.
Signed-off-by: Rosemarie O'Riorden <[email protected]> --- ofproto/ofproto-dpif-xlate.c | 15 ++++++++----- tests/tunnel-push-pop.at | 43 ++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c index 9bd0b0a38..319bb6db5 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -3720,7 +3720,10 @@ native_tunnel_output(struct xlate_ctx *ctx, const struct xport *xport, size_t clone_ofs = 0; size_t push_action_size; - clone_ofs = nl_msg_start_nested(ctx->odp_actions, OVS_ACTION_ATTR_CLONE); + if (!is_last_action) { + clone_ofs = nl_msg_start_nested(ctx->odp_actions, + OVS_ACTION_ATTR_CLONE); + } odp_put_tnl_push_action(ctx->odp_actions, &tnl_push_data); push_action_size = ctx->odp_actions->size; @@ -3763,10 +3766,12 @@ native_tunnel_output(struct xlate_ctx *ctx, const struct xport *xport, } xlate_cache_steal_entries(backup_xcache, ctx->xin->xcache); - if (ctx->odp_actions->size > push_action_size) { - nl_msg_end_non_empty_nested(ctx->odp_actions, clone_ofs); - } else { - nl_msg_cancel_nested(ctx->odp_actions, clone_ofs); + if (!is_last_action) { + if (ctx->odp_actions->size > push_action_size) { + nl_msg_end_non_empty_nested(ctx->odp_actions, clone_ofs); + } else { + nl_msg_cancel_nested(ctx->odp_actions, clone_ofs); + } } /* Restore context status. */ diff --git a/tests/tunnel-push-pop.at b/tests/tunnel-push-pop.at index 985507285..b54373095 100644 --- a/tests/tunnel-push-pop.at +++ b/tests/tunnel-push-pop.at @@ -893,3 +893,46 @@ out_port(100)),8) OVS_VSWITCHD_STOP AT_CLEANUP + +AT_SETUP([tunnel_push_pop - no clone when is_last_action]) + +dnl Create bridge that has a MAC address +OVS_VSWITCHD_START([set bridge br0 dnl + datapath_type=dummy -- set Interface dnl + br0 other-config:hwaddr=aa:55:aa:55:00:00]) +AT_CHECK([ovs-vsctl add-port br0 p8 -- set Interface p8 dnl + type=dummy ofport_request=8]) + +dnl Create another bridge +AT_CHECK([ovs-vsctl add-br ovs-tun0 -- set bridge ovs-tun0 datapath_type=dummy]) + +dnl Add VXLAN port to this bridge +AT_CHECK([ovs-vsctl add-port ovs-tun0 tun0 -- set int tun0 dnl + type=vxlan options:remote_ip=10.0.0.11 -- add-port ovs-tun0 p7 dnl + -- set interface p7 type=dummy ofport_request=7]) + +dnl Set IP address and route for br0 +AT_CHECK([ovs-appctl netdev-dummy/ip4addr br0 10.0.0.2/24], [0], [OK +]) +AT_CHECK([ovs-appctl ovs/route/add 10.0.0.11/24 br0], [0], [OK +]) + +dnl Send an ARP reply to port b8 on br0, so that packets will be forwarded +dnl to learned port +AT_CHECK([ovs-ofctl add-flow br0 action=normal]) +AT_CHECK([ovs-ofctl del-flows ovs-tun0]) +AT_CHECK([ovs-ofctl add-flow ovs-tun0 "in_port=p7,actions=tun0"]) +AT_CHECK([ovs-appctl netdev-dummy/receive p8 'in_port(8),dnl + eth(src=aa:55:aa:66:00:00,dst=ff:ff:ff:ff:ff:ff),eth_type(0x0806),dnl + arp(sip=10.0.0.11,tip=10.0.0.2,op=2,sha=aa:55:aa:66:00:00,tha=00:00:00:00:00:00)']) +AT_CHECK([ovs-appctl ofproto/trace ovs-tun0 in_port=p7], [0], [stdout]) +AT_CHECK([tail -2 stdout], [0], [dnl +Megaflow: recirc_id=0,eth,in_port=7,dl_type=0x0000 +Datapath actions: tnl_push(tnl_port(4789),header(size=50,type=4,dnl +eth(dst=aa:55:aa:66:00:00,src=aa:55:aa:55:00:00,dl_type=0x0800),dnl +ipv4(src=10.0.0.2,dst=10.0.0.11,proto=17,tos=0,ttl=64,frag=0x4000),dnl +udp(src=0,dst=4789,csum=0x0),vxlan(flags=0x8000000,vni=0x0)),out_port(100)),8 +]) + +OVS_VSWITCHD_STOP +AT_CLEANUP -- 2.35.1 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
