2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-31 06:15:47 +00:00

dpif: Allow execute to modify the packet.

Allowing the packet to be modified by execution allows less data
copying for userspace action execution.  Some users of the
dpif_execute already expect that the packet may be modified.  This
patch makes this behavior uniform and makes the userspace datapath and
the execution helpers modify the packet as it is being executed.
Userspace action now steals the packet if given permission, as the
packet is normally not needed after it.  The only exception is the
sample action, and this is accounted for my keeping track of any
actions that could be following the userspace action.

The packet in dpif_upcall is changed from a pointer to a struct,
allowing the packet to be honest about it's headroom.  After this
change the packet can safely be pushed on over the precarious 4 byte
limit earlier allowed by the netlink data preceding the packet.

Signed-off-by: Jarno Rajahalme <jrajahalme@nicira.com>
Acked-by: Ben Pfaff <blp@nicira.com>
This commit is contained in:
Jarno Rajahalme
2013-12-16 08:14:52 -08:00
parent 881d47a9fa
commit da546e0764
11 changed files with 135 additions and 112 deletions

View File

@@ -1461,14 +1461,20 @@ parse_odp_packet(struct ofpbuf *buf, struct dpif_upcall *upcall,
memset(upcall, 0, sizeof *upcall);
upcall->type = type;
upcall->packet = buf;
upcall->packet->data = CONST_CAST(struct nlattr *,
nl_attr_get(a[OVS_PACKET_ATTR_PACKET]));
upcall->packet->size = nl_attr_get_size(a[OVS_PACKET_ATTR_PACKET]);
upcall->key = CONST_CAST(struct nlattr *,
nl_attr_get(a[OVS_PACKET_ATTR_KEY]));
upcall->key_len = nl_attr_get_size(a[OVS_PACKET_ATTR_KEY]);
upcall->userdata = a[OVS_PACKET_ATTR_USERDATA];
/* Allow overwriting the netlink attribute header without reallocating. */
ofpbuf_use_stub(&upcall->packet,
CONST_CAST(struct nlattr *,
nl_attr_get(a[OVS_PACKET_ATTR_PACKET])) - 1,
nl_attr_get_size(a[OVS_PACKET_ATTR_PACKET]) +
sizeof(struct nlattr));
upcall->packet.data = (char *)upcall->packet.data + sizeof(struct nlattr);
upcall->packet.size -= sizeof(struct nlattr);
*dp_ifindex = ovs_header->dp_ifindex;
return 0;