Skip to content

Commit

Permalink
ofproto-dpif-xlate: No clone when tunnel push is last action.
Browse files Browse the repository at this point in the history
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 encapsulated 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]>
Signed-off-by: Ilya Maximets <[email protected]>
  • Loading branch information
roseoriorden authored and igsilya committed Jun 29, 2022
1 parent 22ac9d6 commit c8bff84
Show file tree
Hide file tree
Showing 8 changed files with 153 additions and 65 deletions.
38 changes: 24 additions & 14 deletions lib/netdev-offload-dpdk.c
Original file line number Diff line number Diff line change
Expand Up @@ -2058,6 +2058,25 @@ parse_vlan_push_action(struct flow_actions *actions,
return 0;
}

static void
add_tunnel_push_action(struct flow_actions *actions,
const struct ovs_action_push_tnl *tnl_push)
{
struct rte_flow_action_raw_encap *raw_encap;

if (tnl_push->tnl_type == OVS_VPORT_TYPE_VXLAN &&
!add_vxlan_encap_action(actions, tnl_push->header)) {
return;
}

raw_encap = xzalloc(sizeof *raw_encap);
raw_encap->data = (uint8_t *) tnl_push->header;
raw_encap->preserve = NULL;
raw_encap->size = tnl_push->header_len;

add_flow_action(actions, RTE_FLOW_ACTION_TYPE_RAW_ENCAP, raw_encap);
}

static int
parse_clone_actions(struct netdev *netdev,
struct flow_actions *actions,
Expand All @@ -2072,20 +2091,7 @@ parse_clone_actions(struct netdev *netdev,

if (clone_type == OVS_ACTION_ATTR_TUNNEL_PUSH) {
const struct ovs_action_push_tnl *tnl_push = nl_attr_get(ca);
struct rte_flow_action_raw_encap *raw_encap;

if (tnl_push->tnl_type == OVS_VPORT_TYPE_VXLAN &&
!add_vxlan_encap_action(actions, tnl_push->header)) {
continue;
}

raw_encap = xzalloc(sizeof *raw_encap);
raw_encap->data = (uint8_t *) tnl_push->header;
raw_encap->preserve = NULL;
raw_encap->size = tnl_push->header_len;

add_flow_action(actions, RTE_FLOW_ACTION_TYPE_RAW_ENCAP,
raw_encap);
add_tunnel_push_action(actions, tnl_push);
} else if (clone_type == OVS_ACTION_ATTR_OUTPUT) {
if (add_output_action(netdev, actions, ca)) {
return -1;
Expand Down Expand Up @@ -2188,6 +2194,10 @@ parse_flow_actions(struct netdev *netdev,
}
} else if (nl_attr_type(nla) == OVS_ACTION_ATTR_POP_VLAN) {
add_flow_action(actions, RTE_FLOW_ACTION_TYPE_OF_POP_VLAN, NULL);
} else if (nl_attr_type(nla) == OVS_ACTION_ATTR_TUNNEL_PUSH) {
const struct ovs_action_push_tnl *tnl_push = nl_attr_get(nla);

add_tunnel_push_action(actions, tnl_push);
} else if (nl_attr_type(nla) == OVS_ACTION_ATTR_CLONE &&
left <= NLA_ALIGN(nla->nla_len)) {
const struct nlattr *clone_actions = nl_attr_get(nla);
Expand Down
7 changes: 7 additions & 0 deletions lib/netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,13 @@ nl_msg_put_nested(struct ofpbuf *msg,
nl_msg_end_nested(msg, offset);
}

/* Reset message size to offset. */
void
nl_msg_reset_size(struct ofpbuf *msg, size_t offset)
{
msg->size = offset;
}

/* If 'buffer' begins with a valid "struct nlmsghdr", pulls the header and its
* payload off 'buffer', stores header and payload in 'msg->data' and
* 'msg->size', and returns a pointer to the header.
Expand Down
1 change: 1 addition & 0 deletions lib/netlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ void nl_msg_cancel_nested(struct ofpbuf *, size_t offset);
bool nl_msg_end_non_empty_nested(struct ofpbuf *, size_t offset);
void nl_msg_put_nested(struct ofpbuf *, uint16_t type,
const void *data, size_t size);
void nl_msg_reset_size(struct ofpbuf *, size_t offset);

/* Prepending attributes. */
void *nl_msg_push_unspec_uninit(struct ofpbuf *, uint16_t type, size_t);
Expand Down
24 changes: 18 additions & 6 deletions ofproto/ofproto-dpif-xlate.c
Original file line number Diff line number Diff line change
Expand Up @@ -3736,10 +3736,12 @@ native_tunnel_output(struct xlate_ctx *ctx, const struct xport *xport,
s_ip, tnl_params.is_ipv6,
tnl_push_data.tnl_type);

size_t clone_ofs = 0;
size_t offset;
size_t push_action_size;

clone_ofs = nl_msg_start_nested(ctx->odp_actions, OVS_ACTION_ATTR_CLONE);
offset = is_last_action
? ctx->odp_actions->size
: 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;

Expand Down Expand Up @@ -3783,9 +3785,17 @@ 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);
if (!is_last_action) {
nl_msg_end_non_empty_nested(ctx->odp_actions, offset);
}
} else {
nl_msg_cancel_nested(ctx->odp_actions, clone_ofs);
if (is_last_action) {
/* Reset size since no actions added in patch port output. */
nl_msg_reset_size(ctx->odp_actions, offset);
} else {
/* Cancel nested clone action. */
nl_msg_cancel_nested(ctx->odp_actions, offset);
}
}

/* Restore context status. */
Expand All @@ -3797,9 +3807,11 @@ native_tunnel_output(struct xlate_ctx *ctx, const struct xport *xport,
ctx->wc = backup_wc;
} else {
/* In order to maintain accurate stats, use recirc for
* natvie tunneling. */
* native tunneling. */
nl_msg_put_u32(ctx->odp_actions, OVS_ACTION_ATTR_RECIRC, 0);
nl_msg_end_nested(ctx->odp_actions, clone_ofs);
if (!is_last_action) {
nl_msg_end_nested(ctx->odp_actions, offset);
}
}

/* Restore the flows after the translation. */
Expand Down
6 changes: 3 additions & 3 deletions tests/nsh.at
Original file line number Diff line number Diff line change
Expand Up @@ -724,7 +724,7 @@ ovs-appctl time/warp 1000
AT_CHECK([
ovs-appctl dpctl/dump-flows dummy@ovs-dummy | strip_used | grep -v ipv6 | sort
], [0], [flow-dump from the main thread:
recirc_id(0),in_port(4),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(dst=192.168.10.30,frag=no), packets:1, bytes:98, used:0.0s, actions:pop_eth,push_nsh(flags=0,ttl=63,mdtype=1,np=1,spi=0x3000,si=255,c1=0x0,c2=0x0,c3=0x0,c4=0x0),clone(tnl_push(tnl_port(4789),header(size=50,type=4,eth(dst=aa:55:00:00:00:03,src=aa:55:00:00:00:01,dl_type=0x0800),ipv4(src=10.0.0.1,dst=10.0.0.3,proto=17,tos=0,ttl=64,frag=0x4000),udp(src=0,dst=4789,csum=0x0),vxlan(flags=0xc000004,vni=0x0)),out_port(1)),set(ipv4(src=30.0.0.1,dst=30.0.0.3)),tnl_pop(4789))
recirc_id(0),in_port(4),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(dst=192.168.10.30,frag=no), packets:1, bytes:98, used:0.0s, actions:pop_eth,push_nsh(flags=0,ttl=63,mdtype=1,np=1,spi=0x3000,si=255,c1=0x0,c2=0x0,c3=0x0,c4=0x0),tnl_push(tnl_port(4789),header(size=50,type=4,eth(dst=aa:55:00:00:00:03,src=aa:55:00:00:00:01,dl_type=0x0800),ipv4(src=10.0.0.1,dst=10.0.0.3,proto=17,tos=0,ttl=64,frag=0x4000),udp(src=0,dst=4789,csum=0x0),vxlan(flags=0xc000004,vni=0x0)),out_port(1)),set(ipv4(src=30.0.0.1,dst=30.0.0.3)),tnl_pop(4789)
tunnel(tun_id=0x0,src=30.0.0.1,dst=30.0.0.3,flags(-df-csum+key)),recirc_id(0),in_port(4789),packet_type(ns=1,id=0x894f),eth_type(0x894f),nsh(np=1,spi=0x3000,si=255), packets:1, bytes:108, used:0.0s, actions:pop_nsh(),recirc(0x1)
tunnel(tun_id=0x0,src=30.0.0.1,dst=30.0.0.3,flags(-df-csum+key)),recirc_id(0x1),in_port(4789),packet_type(ns=1,id=0x800),eth_type(0x0800),ipv4(frag=no), packets:1, bytes:84, used:0.0s, actions:push_eth(src=00:00:00:00:00:00,dst=aa:55:aa:55:00:03),6
])
Expand Down Expand Up @@ -778,8 +778,8 @@ ovs-appctl time/warp 1000
AT_CHECK([
ovs-appctl dpctl/dump-flows dummy@ovs-dummy | strip_used | grep -v ipv6 | sort
], [0], [flow-dump from the main thread:
recirc_id(0),in_port(4),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(dst=192.168.10.20/255.255.255.248,frag=no), packets:1, bytes:98, used:0.0s, actions:pop_eth,push_nsh(flags=0,ttl=63,mdtype=1,np=1,spi=0x3020,si=255,c1=0x0,c2=0x0,c3=0x0,c4=0x0),clone(tnl_push(tnl_port(4789),header(size=50,type=4,eth(dst=aa:55:00:00:00:02,src=aa:55:00:00:00:01,dl_type=0x0800),ipv4(src=10.0.0.1,dst=10.0.0.2,proto=17,tos=0,ttl=64,frag=0x4000),udp(src=0,dst=4789,csum=0x0),vxlan(flags=0xc000004,vni=0x0)),out_port(1)),set(ipv4(src=20.0.0.1,dst=20.0.0.2)),tnl_pop(4789))
tunnel(tun_id=0x0,src=20.0.0.1,dst=20.0.0.2,flags(-df-csum+key)),recirc_id(0),in_port(4789),packet_type(ns=1,id=0x894f),eth_type(0x894f),nsh(spi=0x3020,si=255), packets:1, bytes:108, used:0.0s, actions:push_eth(src=00:00:00:00:00:00,dst=11:22:33:44:55:66),set(nsh(spi=0x3020,si=254)),pop_eth,clone(tnl_push(tnl_port(4789),header(size=50,type=4,eth(dst=aa:55:00:00:00:03,src=aa:55:00:00:00:02,dl_type=0x0800),ipv4(src=20.0.0.2,dst=20.0.0.3,proto=17,tos=0,ttl=64,frag=0x4000),udp(src=0,dst=4789,csum=0x0),vxlan(flags=0xc000004,vni=0x0)),out_port(2)),set(ipv4(src=30.0.0.2,dst=30.0.0.3)),tnl_pop(4789))
recirc_id(0),in_port(4),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(dst=192.168.10.20/255.255.255.248,frag=no), packets:1, bytes:98, used:0.0s, actions:pop_eth,push_nsh(flags=0,ttl=63,mdtype=1,np=1,spi=0x3020,si=255,c1=0x0,c2=0x0,c3=0x0,c4=0x0),tnl_push(tnl_port(4789),header(size=50,type=4,eth(dst=aa:55:00:00:00:02,src=aa:55:00:00:00:01,dl_type=0x0800),ipv4(src=10.0.0.1,dst=10.0.0.2,proto=17,tos=0,ttl=64,frag=0x4000),udp(src=0,dst=4789,csum=0x0),vxlan(flags=0xc000004,vni=0x0)),out_port(1)),set(ipv4(src=20.0.0.1,dst=20.0.0.2)),tnl_pop(4789)
tunnel(tun_id=0x0,src=20.0.0.1,dst=20.0.0.2,flags(-df-csum+key)),recirc_id(0),in_port(4789),packet_type(ns=1,id=0x894f),eth_type(0x894f),nsh(spi=0x3020,si=255), packets:1, bytes:108, used:0.0s, actions:push_eth(src=00:00:00:00:00:00,dst=11:22:33:44:55:66),set(nsh(spi=0x3020,si=254)),pop_eth,tnl_push(tnl_port(4789),header(size=50,type=4,eth(dst=aa:55:00:00:00:03,src=aa:55:00:00:00:02,dl_type=0x0800),ipv4(src=20.0.0.2,dst=20.0.0.3,proto=17,tos=0,ttl=64,frag=0x4000),udp(src=0,dst=4789,csum=0x0),vxlan(flags=0xc000004,vni=0x0)),out_port(2)),set(ipv4(src=30.0.0.2,dst=30.0.0.3)),tnl_pop(4789)
tunnel(tun_id=0x0,src=30.0.0.2,dst=30.0.0.3,flags(-df-csum+key)),recirc_id(0),in_port(4789),packet_type(ns=1,id=0x894f),eth_type(0x894f),nsh(np=1,spi=0x3020,si=254), packets:1, bytes:108, used:0.0s, actions:pop_nsh(),recirc(0x2)
tunnel(tun_id=0x0,src=30.0.0.2,dst=30.0.0.3,flags(-df-csum+key)),recirc_id(0x2),in_port(4789),packet_type(ns=1,id=0x800),eth_type(0x0800),ipv4(frag=no), packets:1, bytes:84, used:0.0s, actions:push_eth(src=00:00:00:00:00:00,dst=aa:55:aa:55:00:03),6
])
Expand Down
Loading

0 comments on commit c8bff84

Please sign in to comment.