2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-31 14:25:26 +00:00

ofproto-dpif-xlate: Optimize datapath action set by removing last clone action.

When OFPROTO non-reversible actions are translated to data plane
actions, the only thing looked at is if there are more actions
pending. If this is the case, the action is encapsulated in a
clone().

This could lead to unnecessary clones if no meaningful data
plane actions are added. For example, the register pop in the
included test case.

The best solution would probably be to build the full action
path and determine if the clone is needed. However, this would
be a huge change in the existing design, so for now, we just try
to optimize the generated datapath flow. We can revisit this
later, as some of the pending CT issues might need this rework.

Fixes: feee58b958 ("ofproto-dpif-xlate: Keep track of the last action")
Fixes: dadd8357f2 ("ofproto-dpif: Fix issue with non-reversible actions on a patch ports.")
Acked-by: Ales Musil <amusil@redhat.com>
Signed-off-by: Eelco Chaudron <echaudro@redhat.com>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
This commit is contained in:
Eelco Chaudron
2022-07-26 11:40:27 +02:00
committed by Ilya Maximets
parent d046453b56
commit 4f5decf4ab
4 changed files with 74 additions and 3 deletions

View File

@@ -7671,6 +7671,39 @@ xlate_wc_finish(struct xlate_ctx *ctx)
} }
} }
/* This will optimize the odp actions generated. For now, it will remove
* trailing clone actions that are unnecessary. */
static void
xlate_optimize_odp_actions(struct xlate_in *xin)
{
struct ofpbuf *actions = xin->odp_actions;
struct nlattr *last_action = NULL;
struct nlattr *a;
int left;
if (!actions) {
return;
}
/* Find the last action in the set. */
NL_ATTR_FOR_EACH (a, left, actions->data, actions->size) {
last_action = a;
}
/* Remove the trailing clone() action, by directly embedding the nested
* actions. */
if (last_action && nl_attr_type(last_action) == OVS_ACTION_ATTR_CLONE) {
void *dest;
nl_msg_reset_size(actions,
(unsigned char *) last_action -
(unsigned char *) actions->data);
dest = nl_msg_put_uninit(actions, nl_attr_get_size(last_action));
memmove(dest, nl_attr_get(last_action), nl_attr_get_size(last_action));
}
}
/* Translates the flow, actions, or rule in 'xin' into datapath actions in /* Translates the flow, actions, or rule in 'xin' into datapath actions in
* 'xout'. * 'xout'.
* The caller must take responsibility for eventually freeing 'xout', with * The caller must take responsibility for eventually freeing 'xout', with
@@ -8096,6 +8129,10 @@ exit:
if (xin->odp_actions) { if (xin->odp_actions) {
ofpbuf_clear(xin->odp_actions); ofpbuf_clear(xin->odp_actions);
} }
} else {
/* In the non-error case, see if we can further optimize the datapath
* rules by removing redundant (clone) actions. */
xlate_optimize_odp_actions(xin);
} }
/* Install drop action if datapath supports explicit drop action. */ /* Install drop action if datapath supports explicit drop action. */

View File

@@ -8923,6 +8923,40 @@ AT_CHECK([tail -1 stdout], [0],
OVS_VSWITCHD_STOP OVS_VSWITCHD_STOP
AT_CLEANUP AT_CLEANUP
AT_SETUP([ofproto-dpif - patch ports - no additional clone])
OVS_VSWITCHD_START(
[add-port br0 p0 -- set Interface p0 type=dummy ofport_request=1 -- dnl
add-port br0 p1 -- set Interface p1 type=patch dnl
options:peer=p2 ofport_request=2 -- dnl
add-br br1 -- dnl
set bridge br1 other-config:hwaddr=aa:66:aa:66:00:00 -- dnl
set bridge br1 datapath-type=dummy other-config:datapath-id=1234 dnl
fail-mode=secure -- dnl
add-port br1 p2 -- set Interface p2 type=patch dnl
options:peer=p1 -- dnl
add-port br1 p3 -- set Interface p3 type=dummy ofport_request=3])
AT_DATA([flows-br0.txt], [dnl
priority=10,tcp,action=push:NXM_OF_IN_PORT[],resubmit(,65),pop:NXM_OF_IN_PORT[]
table=65,priority=10,ip,in_port=p0,action=p1
])
AT_DATA([flows-br1.txt], [dnl
priority=100,in_port=p2,tcp,ct_state=-trk,action=ct(table=0,zone=1)
priority=100,in_port=p2,tcp,ct_state=+trk+est,ct_zone=1,action=p3
])
AT_CHECK([ovs-ofctl --bundle add-flows br0 flows-br0.txt])
AT_CHECK([ovs-ofctl --bundle add-flows br1 flows-br1.txt])
AT_CHECK([ovs-appctl ofproto/trace br0 in_port=p0,tcp --ct-next 'trk,est' | dnl
grep "Datapath actions:" | grep -q clone],
[1], [], [],
[ovs-appctl ofproto/trace br0 in_port=p0,tcp --ct-next 'trk,est'])
OVS_TRAFFIC_VSWITCHD_STOP
AT_CLEANUP
dnl ---------------------------------------------------------------------- dnl ----------------------------------------------------------------------
AT_BANNER([ofproto-dpif -- megaflows]) AT_BANNER([ofproto-dpif -- megaflows])

View File

@@ -147,7 +147,7 @@ AT_CHECK([tail -1 stdout], [0],
dnl Check GRE tunnel push dnl Check GRE tunnel push
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(3),eth(dst=f9:bc:12:44:34:b6,src=af:55:aa:55:00:03),eth_type(0x0800),ipv4(src=1.1.3.88,dst=1.1.3.92,proto=1,tos=0,ttl=64,frag=no)'], [0], [stdout]) AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(3),eth(dst=f9:bc:12:44:34:b6,src=af:55:aa:55:00:03),eth_type(0x0800),ipv4(src=1.1.3.88,dst=1.1.3.92,proto=1,tos=0,ttl=64,frag=no)'], [0], [stdout])
AT_CHECK([tail -1 stdout], [0], AT_CHECK([tail -1 stdout], [0],
[Datapath actions: clone(tnl_push(tnl_port(4),header(size=38,type=3,eth(dst=f8:bc:12:44:34:b6,src=aa:55:aa:55:00:03,dl_type=0x0800),ipv4(src=1.1.2.88,dst=1.1.2.92,proto=47,tos=0,ttl=64,frag=0x4000),gre((flags=0x0,proto=0x6558))),out_port(2)),1) [Datapath actions: tnl_push(tnl_port(4),header(size=38,type=3,eth(dst=f8:bc:12:44:34:b6,src=aa:55:aa:55:00:03,dl_type=0x0800),ipv4(src=1.1.2.88,dst=1.1.2.92,proto=47,tos=0,ttl=64,frag=0x4000),gre((flags=0x0,proto=0x6558))),out_port(2)),1
]) ])
OVS_VSWITCHD_STOP OVS_VSWITCHD_STOP

View File

@@ -906,11 +906,11 @@ AT_CHECK([ovs-appctl ofproto/trace ovs-tun0 in_port=p7], [0], [stdout])
AT_CHECK([tail -2 stdout], [0], [dnl AT_CHECK([tail -2 stdout], [0], [dnl
Megaflow: recirc_id=0,eth,in_port=7,dl_src=00:00:00:00:00:00,dnl Megaflow: recirc_id=0,eth,in_port=7,dl_src=00:00:00:00:00:00,dnl
dl_dst=00:00:00:00:00:00,dl_type=0x0000 dl_dst=00:00:00:00:00:00,dl_type=0x0000
Datapath actions: push_vlan(vid=200,pcp=0),1,clone(tnl_push(tnl_port(4789),dnl Datapath actions: push_vlan(vid=200,pcp=0),1,tnl_push(tnl_port(4789),dnl
header(size=50,type=4,eth(dst=aa:55:aa:66:00:00,src=aa:55:aa:55:00:00,dnl header(size=50,type=4,eth(dst=aa:55:aa:66:00:00,src=aa:55:aa:55:00:00,dnl
dl_type=0x0800),ipv4(src=10.0.0.2,dst=10.0.0.11,proto=17,tos=0,ttl=64,dnl dl_type=0x0800),ipv4(src=10.0.0.2,dst=10.0.0.11,proto=17,tos=0,ttl=64,dnl
frag=0x4000),udp(src=0,dst=4789,csum=0x0),vxlan(flags=0x8000000,vni=0x0)),dnl frag=0x4000),udp(src=0,dst=4789,csum=0x0),vxlan(flags=0x8000000,vni=0x0)),dnl
out_port(100)),8) out_port(100)),8
]) ])
OVS_VSWITCHD_STOP OVS_VSWITCHD_STOP