Skip to content

Commit 50bcd31

Browse files
AyalaBkrjmberg-intel
authored andcommitted
cfg80211: provide a function to report a match for NAN
Provide a function the driver can call to report a match. This will send the event to the user space. If the NAN instance is tied to the owner, the notifications will be sent to the socket that started the NAN interface only. Signed-off-by: Andrei Otcheretianski <[email protected]> Signed-off-by: Emmanuel Grumbach <[email protected]> Signed-off-by: Luca Coelho <[email protected]> Signed-off-by: Johannes Berg <[email protected]>
1 parent a5a9dcf commit 50bcd31

File tree

3 files changed

+148
-0
lines changed

3 files changed

+148
-0
lines changed

include/net/cfg80211.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5694,6 +5694,43 @@ wiphy_ext_feature_isset(struct wiphy *wiphy,
56945694
*/
56955695
void cfg80211_free_nan_func(struct cfg80211_nan_func *f);
56965696

5697+
/**
5698+
* struct cfg80211_nan_match_params - NAN match parameters
5699+
* @type: the type of the function that triggered a match. If it is
5700+
* %NL80211_NAN_FUNC_SUBSCRIBE it means that we replied to a subscriber.
5701+
* If it is %NL80211_NAN_FUNC_PUBLISH, it means that we got a discovery
5702+
* result.
5703+
* If it is %NL80211_NAN_FUNC_FOLLOW_UP, we received a follow up.
5704+
* @inst_id: the local instance id
5705+
* @peer_inst_id: the instance id of the peer's function
5706+
* @addr: the MAC address of the peer
5707+
* @info_len: the length of the &info
5708+
* @info: the Service Specific Info from the peer (if any)
5709+
* @cookie: unique identifier of the corresponding function
5710+
*/
5711+
struct cfg80211_nan_match_params {
5712+
enum nl80211_nan_function_type type;
5713+
u8 inst_id;
5714+
u8 peer_inst_id;
5715+
const u8 *addr;
5716+
u8 info_len;
5717+
const u8 *info;
5718+
u64 cookie;
5719+
};
5720+
5721+
/**
5722+
* cfg80211_nan_match - report a match for a NAN function.
5723+
* @wdev: the wireless device reporting the match
5724+
* @match: match notification parameters
5725+
* @gfp: allocation flags
5726+
*
5727+
* This function reports that the a NAN function had a match. This
5728+
* can be a subscribe that had a match or a solicited publish that
5729+
* was sent. It can also be a follow up that was received.
5730+
*/
5731+
void cfg80211_nan_match(struct wireless_dev *wdev,
5732+
struct cfg80211_nan_match_params *match, gfp_t gfp);
5733+
56975734
/* ethtool helper */
56985735
void cfg80211_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info);
56995736

include/uapi/linux/nl80211.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#define NL80211_MULTICAST_GROUP_REG "regulatory"
4949
#define NL80211_MULTICAST_GROUP_MLME "mlme"
5050
#define NL80211_MULTICAST_GROUP_VENDOR "vendor"
51+
#define NL80211_MULTICAST_GROUP_NAN "nan"
5152
#define NL80211_MULTICAST_GROUP_TESTMODE "testmode"
5253

5354
/**
@@ -866,6 +867,9 @@
866867
* must be operational (%NL80211_CMD_START_NAN was executed).
867868
* It must contain at least one of the following attributes:
868869
* %NL80211_ATTR_NAN_MASTER_PREF, %NL80211_ATTR_NAN_DUAL.
870+
* @NL80211_CMD_NAN_FUNC_MATCH: Notification sent when a match is reported.
871+
* This will contain a %NL80211_ATTR_NAN_MATCH nested attribute and
872+
* %NL80211_ATTR_COOKIE.
869873
*
870874
* @NL80211_CMD_MAX: highest used command number
871875
* @__NL80211_CMD_AFTER_LAST: internal use
@@ -1060,6 +1064,7 @@ enum nl80211_commands {
10601064
NL80211_CMD_ADD_NAN_FUNCTION,
10611065
NL80211_CMD_DEL_NAN_FUNCTION,
10621066
NL80211_CMD_CHANGE_NAN_CONFIG,
1067+
NL80211_CMD_NAN_MATCH,
10631068

10641069
/* add new commands above here */
10651070

@@ -1926,6 +1931,8 @@ enum nl80211_commands {
19261931
* @NL80211_ATTR_NAN_FUNC: a function that can be added to NAN. See
19271932
* &enum nl80211_nan_func_attributes for description of this nested
19281933
* attribute.
1934+
* @NL80211_ATTR_NAN_MATCH: used to report a match. This is a nested attribute.
1935+
* See &enum nl80211_nan_match_attributes.
19291936
*
19301937
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
19311938
* @NL80211_ATTR_MAX: highest attribute number currently defined
@@ -2324,6 +2331,7 @@ enum nl80211_attrs {
23242331
NL80211_ATTR_NAN_MASTER_PREF,
23252332
NL80211_ATTR_NAN_DUAL,
23262333
NL80211_ATTR_NAN_FUNC,
2334+
NL80211_ATTR_NAN_MATCH,
23272335

23282336
/* add attributes here, update the policy in nl80211.c */
23292337

@@ -5074,4 +5082,27 @@ enum nl80211_nan_srf_attributes {
50745082
NL80211_NAN_SRF_ATTR_MAX = NUM_NL80211_NAN_SRF_ATTR - 1,
50755083
};
50765084

5085+
/**
5086+
* enum nl80211_nan_match_attributes - NAN match attributes
5087+
* @__NL80211_NAN_MATCH_INVALID: invalid
5088+
* @NL80211_NAN_MATCH_FUNC_LOCAL: the local function that had the
5089+
* match. This is a nested attribute.
5090+
* See &enum nl80211_nan_func_attributes.
5091+
* @NL80211_NAN_MATCH_FUNC_PEER: the peer function
5092+
* that caused the match. This is a nested attribute.
5093+
* See &enum nl80211_nan_func_attributes.
5094+
*
5095+
* @NUM_NL80211_NAN_MATCH_ATTR: internal
5096+
* @NL80211_NAN_MATCH_ATTR_MAX: highest NAN match attribute
5097+
*/
5098+
enum nl80211_nan_match_attributes {
5099+
__NL80211_NAN_MATCH_INVALID,
5100+
NL80211_NAN_MATCH_FUNC_LOCAL,
5101+
NL80211_NAN_MATCH_FUNC_PEER,
5102+
5103+
/* keep last */
5104+
NUM_NL80211_NAN_MATCH_ATTR,
5105+
NL80211_NAN_MATCH_ATTR_MAX = NUM_NL80211_NAN_MATCH_ATTR - 1
5106+
};
5107+
50775108
#endif /* __LINUX_NL80211_H */

net/wireless/nl80211.c

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ enum nl80211_multicast_groups {
5656
NL80211_MCGRP_REGULATORY,
5757
NL80211_MCGRP_MLME,
5858
NL80211_MCGRP_VENDOR,
59+
NL80211_MCGRP_NAN,
5960
NL80211_MCGRP_TESTMODE /* keep last - ifdef! */
6061
};
6162

@@ -65,6 +66,7 @@ static const struct genl_multicast_group nl80211_mcgrps[] = {
6566
[NL80211_MCGRP_REGULATORY] = { .name = NL80211_MULTICAST_GROUP_REG },
6667
[NL80211_MCGRP_MLME] = { .name = NL80211_MULTICAST_GROUP_MLME },
6768
[NL80211_MCGRP_VENDOR] = { .name = NL80211_MULTICAST_GROUP_VENDOR },
69+
[NL80211_MCGRP_NAN] = { .name = NL80211_MULTICAST_GROUP_NAN },
6870
#ifdef CONFIG_NL80211_TESTMODE
6971
[NL80211_MCGRP_TESTMODE] = { .name = NL80211_MULTICAST_GROUP_TESTMODE }
7072
#endif
@@ -10953,6 +10955,84 @@ static int nl80211_nan_change_config(struct sk_buff *skb,
1095310955
return rdev_nan_change_conf(rdev, wdev, &conf, changed);
1095410956
}
1095510957

10958+
void cfg80211_nan_match(struct wireless_dev *wdev,
10959+
struct cfg80211_nan_match_params *match, gfp_t gfp)
10960+
{
10961+
struct wiphy *wiphy = wdev->wiphy;
10962+
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
10963+
struct nlattr *match_attr, *local_func_attr, *peer_func_attr;
10964+
struct sk_buff *msg;
10965+
void *hdr;
10966+
10967+
if (WARN_ON(!match->inst_id || !match->peer_inst_id || !match->addr))
10968+
return;
10969+
10970+
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
10971+
if (!msg)
10972+
return;
10973+
10974+
hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NAN_MATCH);
10975+
if (!hdr) {
10976+
nlmsg_free(msg);
10977+
return;
10978+
}
10979+
10980+
if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
10981+
(wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
10982+
wdev->netdev->ifindex)) ||
10983+
nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
10984+
NL80211_ATTR_PAD))
10985+
goto nla_put_failure;
10986+
10987+
if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, match->cookie,
10988+
NL80211_ATTR_PAD) ||
10989+
nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, match->addr))
10990+
goto nla_put_failure;
10991+
10992+
match_attr = nla_nest_start(msg, NL80211_ATTR_NAN_MATCH);
10993+
if (!match_attr)
10994+
goto nla_put_failure;
10995+
10996+
local_func_attr = nla_nest_start(msg, NL80211_NAN_MATCH_FUNC_LOCAL);
10997+
if (!local_func_attr)
10998+
goto nla_put_failure;
10999+
11000+
if (nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID, match->inst_id))
11001+
goto nla_put_failure;
11002+
11003+
nla_nest_end(msg, local_func_attr);
11004+
11005+
peer_func_attr = nla_nest_start(msg, NL80211_NAN_MATCH_FUNC_PEER);
11006+
if (!peer_func_attr)
11007+
goto nla_put_failure;
11008+
11009+
if (nla_put_u8(msg, NL80211_NAN_FUNC_TYPE, match->type) ||
11010+
nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID, match->peer_inst_id))
11011+
goto nla_put_failure;
11012+
11013+
if (match->info && match->info_len &&
11014+
nla_put(msg, NL80211_NAN_FUNC_SERVICE_INFO, match->info_len,
11015+
match->info))
11016+
goto nla_put_failure;
11017+
11018+
nla_nest_end(msg, peer_func_attr);
11019+
nla_nest_end(msg, match_attr);
11020+
genlmsg_end(msg, hdr);
11021+
11022+
if (!wdev->owner_nlportid)
11023+
genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy),
11024+
msg, 0, NL80211_MCGRP_NAN, gfp);
11025+
else
11026+
genlmsg_unicast(wiphy_net(&rdev->wiphy), msg,
11027+
wdev->owner_nlportid);
11028+
11029+
return;
11030+
11031+
nla_put_failure:
11032+
nlmsg_free(msg);
11033+
}
11034+
EXPORT_SYMBOL(cfg80211_nan_match);
11035+
1095611036
static int nl80211_get_protocol_features(struct sk_buff *skb,
1095711037
struct genl_info *info)
1095811038
{

0 commit comments

Comments
 (0)