aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Pfaff <blp@nicira.com>2013-02-15 20:29:22 -0500
committerJesse Gross <jesse@nicira.com>2013-02-22 19:29:22 -0500
commit4490108b4a5ada14c7be712260829faecc814ae5 (patch)
tree1a8aa00a6e518cd597b8ffda27f5e357c998a33b
parent14408dba8440ef629a3a2827bc4c7b5045889295 (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.h11
-rw-r--r--net/openvswitch/datapath.c11
-rw-r--r--net/openvswitch/datapath.h2
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 */
395enum ovs_userspace_attr { 396enum 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