diff options
author | Ben Pfaff <blp@nicira.com> | 2013-02-15 20:29:22 -0500 |
---|---|---|
committer | Jesse Gross <jesse@nicira.com> | 2013-02-22 19:29:22 -0500 |
commit | 4490108b4a5ada14c7be712260829faecc814ae5 (patch) | |
tree | 1a8aa00a6e518cd597b8ffda27f5e357c998a33b | |
parent | 14408dba8440ef629a3a2827bc4c7b5045889295 (diff) |
openvswitch: Allow OVS_USERSPACE_ATTR_USERDATA to be variable length.
Until now, the optional OVS_USERSPACE_ATTR_USERDATA attribute had to be
exactly 64 bits long, if it was present. However, 64 bits is not enough
space to associate as much information with a flow as would be convenient
for some userspace features now under development. This commit generalizes
the attribute, allowing it to be any length.
This generalization is backward-compatible: if userspace only uses 64-bit
attributes, then it will not see any change in behavior.
CC: Romain Lenglet <rlenglet@vmware.com>
Signed-off-by: Ben Pfaff <blp@nicira.com>
Signed-off-by: Jesse Gross <jesse@nicira.com>
-rw-r--r-- | include/linux/openvswitch.h | 11 | ||||
-rw-r--r-- | net/openvswitch/datapath.c | 11 | ||||
-rw-r--r-- | net/openvswitch/datapath.h | 2 |
3 files changed, 13 insertions, 11 deletions
diff --git a/include/linux/openvswitch.h b/include/linux/openvswitch.h index 99e6414a40d9..67d6c7b03581 100644 --- a/include/linux/openvswitch.h +++ b/include/linux/openvswitch.h | |||
@@ -127,7 +127,8 @@ enum ovs_packet_cmd { | |||
127 | * for %OVS_PACKET_CMD_EXECUTE. It has nested %OVS_ACTION_ATTR_* attributes. | 127 | * for %OVS_PACKET_CMD_EXECUTE. It has nested %OVS_ACTION_ATTR_* attributes. |
128 | * @OVS_PACKET_ATTR_USERDATA: Present for an %OVS_PACKET_CMD_ACTION | 128 | * @OVS_PACKET_ATTR_USERDATA: Present for an %OVS_PACKET_CMD_ACTION |
129 | * notification if the %OVS_ACTION_ATTR_USERSPACE action specified an | 129 | * notification if the %OVS_ACTION_ATTR_USERSPACE action specified an |
130 | * %OVS_USERSPACE_ATTR_USERDATA attribute. | 130 | * %OVS_USERSPACE_ATTR_USERDATA attribute, with the same length and content |
131 | * specified there. | ||
131 | * | 132 | * |
132 | * These attributes follow the &struct ovs_header within the Generic Netlink | 133 | * These attributes follow the &struct ovs_header within the Generic Netlink |
133 | * payload for %OVS_PACKET_* commands. | 134 | * payload for %OVS_PACKET_* commands. |
@@ -137,7 +138,7 @@ enum ovs_packet_attr { | |||
137 | OVS_PACKET_ATTR_PACKET, /* Packet data. */ | 138 | OVS_PACKET_ATTR_PACKET, /* Packet data. */ |
138 | OVS_PACKET_ATTR_KEY, /* Nested OVS_KEY_ATTR_* attributes. */ | 139 | OVS_PACKET_ATTR_KEY, /* Nested OVS_KEY_ATTR_* attributes. */ |
139 | OVS_PACKET_ATTR_ACTIONS, /* Nested OVS_ACTION_ATTR_* attributes. */ | 140 | OVS_PACKET_ATTR_ACTIONS, /* Nested OVS_ACTION_ATTR_* attributes. */ |
140 | OVS_PACKET_ATTR_USERDATA, /* u64 OVS_ACTION_ATTR_USERSPACE arg. */ | 141 | OVS_PACKET_ATTR_USERDATA, /* OVS_ACTION_ATTR_USERSPACE arg. */ |
141 | __OVS_PACKET_ATTR_MAX | 142 | __OVS_PACKET_ATTR_MAX |
142 | }; | 143 | }; |
143 | 144 | ||
@@ -389,13 +390,13 @@ enum ovs_sample_attr { | |||
389 | * enum ovs_userspace_attr - Attributes for %OVS_ACTION_ATTR_USERSPACE action. | 390 | * enum ovs_userspace_attr - Attributes for %OVS_ACTION_ATTR_USERSPACE action. |
390 | * @OVS_USERSPACE_ATTR_PID: u32 Netlink PID to which the %OVS_PACKET_CMD_ACTION | 391 | * @OVS_USERSPACE_ATTR_PID: u32 Netlink PID to which the %OVS_PACKET_CMD_ACTION |
391 | * message should be sent. Required. | 392 | * message should be sent. Required. |
392 | * @OVS_USERSPACE_ATTR_USERDATA: If present, its u64 argument is copied to the | 393 | * @OVS_USERSPACE_ATTR_USERDATA: If present, its variable-length argument is |
393 | * %OVS_PACKET_CMD_ACTION message as %OVS_PACKET_ATTR_USERDATA, | 394 | * copied to the %OVS_PACKET_CMD_ACTION message as %OVS_PACKET_ATTR_USERDATA. |
394 | */ | 395 | */ |
395 | enum ovs_userspace_attr { | 396 | enum ovs_userspace_attr { |
396 | OVS_USERSPACE_ATTR_UNSPEC, | 397 | OVS_USERSPACE_ATTR_UNSPEC, |
397 | OVS_USERSPACE_ATTR_PID, /* u32 Netlink PID to receive upcalls. */ | 398 | OVS_USERSPACE_ATTR_PID, /* u32 Netlink PID to receive upcalls. */ |
398 | OVS_USERSPACE_ATTR_USERDATA, /* u64 optional user-specified cookie. */ | 399 | OVS_USERSPACE_ATTR_USERDATA, /* Optional user-specified cookie. */ |
399 | __OVS_USERSPACE_ATTR_MAX | 400 | __OVS_USERSPACE_ATTR_MAX |
400 | }; | 401 | }; |
401 | 402 | ||
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index f9d2438e6437..96cd5b243d57 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c | |||
@@ -370,8 +370,8 @@ static int queue_userspace_packet(struct net *net, int dp_ifindex, | |||
370 | len = sizeof(struct ovs_header); | 370 | len = sizeof(struct ovs_header); |
371 | len += nla_total_size(skb->len); | 371 | len += nla_total_size(skb->len); |
372 | len += nla_total_size(FLOW_BUFSIZE); | 372 | len += nla_total_size(FLOW_BUFSIZE); |
373 | if (upcall_info->cmd == OVS_PACKET_CMD_ACTION) | 373 | if (upcall_info->userdata) |
374 | len += nla_total_size(8); | 374 | len += NLA_ALIGN(upcall_info->userdata->nla_len); |
375 | 375 | ||
376 | user_skb = genlmsg_new(len, GFP_ATOMIC); | 376 | user_skb = genlmsg_new(len, GFP_ATOMIC); |
377 | if (!user_skb) { | 377 | if (!user_skb) { |
@@ -388,8 +388,9 @@ static int queue_userspace_packet(struct net *net, int dp_ifindex, | |||
388 | nla_nest_end(user_skb, nla); | 388 | nla_nest_end(user_skb, nla); |
389 | 389 | ||
390 | if (upcall_info->userdata) | 390 | if (upcall_info->userdata) |
391 | nla_put_u64(user_skb, OVS_PACKET_ATTR_USERDATA, | 391 | __nla_put(user_skb, OVS_PACKET_ATTR_USERDATA, |
392 | nla_get_u64(upcall_info->userdata)); | 392 | nla_len(upcall_info->userdata), |
393 | nla_data(upcall_info->userdata)); | ||
393 | 394 | ||
394 | nla = __nla_reserve(user_skb, OVS_PACKET_ATTR_PACKET, skb->len); | 395 | nla = __nla_reserve(user_skb, OVS_PACKET_ATTR_PACKET, skb->len); |
395 | 396 | ||
@@ -544,7 +545,7 @@ static int validate_userspace(const struct nlattr *attr) | |||
544 | { | 545 | { |
545 | static const struct nla_policy userspace_policy[OVS_USERSPACE_ATTR_MAX + 1] = { | 546 | static const struct nla_policy userspace_policy[OVS_USERSPACE_ATTR_MAX + 1] = { |
546 | [OVS_USERSPACE_ATTR_PID] = {.type = NLA_U32 }, | 547 | [OVS_USERSPACE_ATTR_PID] = {.type = NLA_U32 }, |
547 | [OVS_USERSPACE_ATTR_USERDATA] = {.type = NLA_U64 }, | 548 | [OVS_USERSPACE_ATTR_USERDATA] = {.type = NLA_UNSPEC }, |
548 | }; | 549 | }; |
549 | struct nlattr *a[OVS_USERSPACE_ATTR_MAX + 1]; | 550 | struct nlattr *a[OVS_USERSPACE_ATTR_MAX + 1]; |
550 | int error; | 551 | int error; |
diff --git a/net/openvswitch/datapath.h b/net/openvswitch/datapath.h index 031dfbf37c93..9125ad5c5aeb 100644 --- a/net/openvswitch/datapath.h +++ b/net/openvswitch/datapath.h | |||
@@ -119,7 +119,7 @@ struct ovs_skb_cb { | |||
119 | * struct dp_upcall - metadata to include with a packet to send to userspace | 119 | * struct dp_upcall - metadata to include with a packet to send to userspace |
120 | * @cmd: One of %OVS_PACKET_CMD_*. | 120 | * @cmd: One of %OVS_PACKET_CMD_*. |
121 | * @key: Becomes %OVS_PACKET_ATTR_KEY. Must be nonnull. | 121 | * @key: Becomes %OVS_PACKET_ATTR_KEY. Must be nonnull. |
122 | * @userdata: If nonnull, its u64 value is extracted and passed to userspace as | 122 | * @userdata: If nonnull, its variable-length value is passed to userspace as |
123 | * %OVS_PACKET_ATTR_USERDATA. | 123 | * %OVS_PACKET_ATTR_USERDATA. |
124 | * @pid: Netlink PID to which packet should be sent. If @pid is 0 then no | 124 | * @pid: Netlink PID to which packet should be sent. If @pid is 0 then no |
125 | * packet is sent and the packet is accounted in the datapath's @n_lost | 125 | * packet is sent and the packet is accounted in the datapath's @n_lost |