diff options
author | Johannes Berg <johannes.berg@intel.com> | 2019-02-06 06:17:19 -0500 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2019-02-22 07:46:43 -0500 |
commit | 55c1fdf0d6c57e02c2279e0ba0c6f8ec502b46df (patch) | |
tree | c34fe2456d1ae2dda1b7eea1ff9ca20f2016b5c8 /net/wireless | |
parent | 7976b1e9e3bfdd7ed1cfb21afc4a195655017f13 (diff) |
cfg80211: allow sending vendor events unicast
Sometimes, we may want to transport higher bandwidth data
through vendor events, and in that case sending it multicast
is a bad idea. Allow vendor events to be unicast.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless')
-rw-r--r-- | net/wireless/nl80211.c | 30 |
1 files changed, 24 insertions, 6 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index d5badbbb28a3..c5df5211d29a 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> | 4 | * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> |
5 | * Copyright 2013-2014 Intel Mobile Communications GmbH | 5 | * Copyright 2013-2014 Intel Mobile Communications GmbH |
6 | * Copyright 2015-2017 Intel Deutschland GmbH | 6 | * Copyright 2015-2017 Intel Deutschland GmbH |
7 | * Copyright (C) 2018 Intel Corporation | 7 | * Copyright (C) 2018-2019 Intel Corporation |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/if.h> | 10 | #include <linux/if.h> |
@@ -9306,6 +9306,7 @@ struct sk_buff *__cfg80211_alloc_event_skb(struct wiphy *wiphy, | |||
9306 | struct wireless_dev *wdev, | 9306 | struct wireless_dev *wdev, |
9307 | enum nl80211_commands cmd, | 9307 | enum nl80211_commands cmd, |
9308 | enum nl80211_attrs attr, | 9308 | enum nl80211_attrs attr, |
9309 | unsigned int portid, | ||
9309 | int vendor_event_idx, | 9310 | int vendor_event_idx, |
9310 | int approxlen, gfp_t gfp) | 9311 | int approxlen, gfp_t gfp) |
9311 | { | 9312 | { |
@@ -9329,7 +9330,7 @@ struct sk_buff *__cfg80211_alloc_event_skb(struct wiphy *wiphy, | |||
9329 | return NULL; | 9330 | return NULL; |
9330 | } | 9331 | } |
9331 | 9332 | ||
9332 | return __cfg80211_alloc_vendor_skb(rdev, wdev, approxlen, 0, 0, | 9333 | return __cfg80211_alloc_vendor_skb(rdev, wdev, approxlen, portid, 0, |
9333 | cmd, attr, info, gfp); | 9334 | cmd, attr, info, gfp); |
9334 | } | 9335 | } |
9335 | EXPORT_SYMBOL(__cfg80211_alloc_event_skb); | 9336 | EXPORT_SYMBOL(__cfg80211_alloc_event_skb); |
@@ -9338,6 +9339,7 @@ void __cfg80211_send_event_skb(struct sk_buff *skb, gfp_t gfp) | |||
9338 | { | 9339 | { |
9339 | struct cfg80211_registered_device *rdev = ((void **)skb->cb)[0]; | 9340 | struct cfg80211_registered_device *rdev = ((void **)skb->cb)[0]; |
9340 | void *hdr = ((void **)skb->cb)[1]; | 9341 | void *hdr = ((void **)skb->cb)[1]; |
9342 | struct nlmsghdr *nlhdr = nlmsg_hdr(skb); | ||
9341 | struct nlattr *data = ((void **)skb->cb)[2]; | 9343 | struct nlattr *data = ((void **)skb->cb)[2]; |
9342 | enum nl80211_multicast_groups mcgrp = NL80211_MCGRP_TESTMODE; | 9344 | enum nl80211_multicast_groups mcgrp = NL80211_MCGRP_TESTMODE; |
9343 | 9345 | ||
@@ -9347,11 +9349,16 @@ void __cfg80211_send_event_skb(struct sk_buff *skb, gfp_t gfp) | |||
9347 | nla_nest_end(skb, data); | 9349 | nla_nest_end(skb, data); |
9348 | genlmsg_end(skb, hdr); | 9350 | genlmsg_end(skb, hdr); |
9349 | 9351 | ||
9350 | if (data->nla_type == NL80211_ATTR_VENDOR_DATA) | 9352 | if (nlhdr->nlmsg_pid) { |
9351 | mcgrp = NL80211_MCGRP_VENDOR; | 9353 | genlmsg_unicast(wiphy_net(&rdev->wiphy), skb, |
9354 | nlhdr->nlmsg_pid); | ||
9355 | } else { | ||
9356 | if (data->nla_type == NL80211_ATTR_VENDOR_DATA) | ||
9357 | mcgrp = NL80211_MCGRP_VENDOR; | ||
9352 | 9358 | ||
9353 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), skb, 0, | 9359 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), |
9354 | mcgrp, gfp); | 9360 | skb, 0, mcgrp, gfp); |
9361 | } | ||
9355 | } | 9362 | } |
9356 | EXPORT_SYMBOL(__cfg80211_send_event_skb); | 9363 | EXPORT_SYMBOL(__cfg80211_send_event_skb); |
9357 | 9364 | ||
@@ -12736,6 +12743,17 @@ int cfg80211_vendor_cmd_reply(struct sk_buff *skb) | |||
12736 | } | 12743 | } |
12737 | EXPORT_SYMBOL_GPL(cfg80211_vendor_cmd_reply); | 12744 | EXPORT_SYMBOL_GPL(cfg80211_vendor_cmd_reply); |
12738 | 12745 | ||
12746 | unsigned int cfg80211_vendor_cmd_get_sender(struct wiphy *wiphy) | ||
12747 | { | ||
12748 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); | ||
12749 | |||
12750 | if (WARN_ON(!rdev->cur_cmd_info)) | ||
12751 | return 0; | ||
12752 | |||
12753 | return rdev->cur_cmd_info->snd_portid; | ||
12754 | } | ||
12755 | EXPORT_SYMBOL_GPL(cfg80211_vendor_cmd_get_sender); | ||
12756 | |||
12739 | static int nl80211_set_qos_map(struct sk_buff *skb, | 12757 | static int nl80211_set_qos_map(struct sk_buff *skb, |
12740 | struct genl_info *info) | 12758 | struct genl_info *info) |
12741 | { | 12759 | { |