aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJavier Cardona <javier@cozybit.com>2011-04-07 18:08:34 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-04-12 16:57:39 -0400
commitc93b5e717ec47b57abfe0229360bc11e77520984 (patch)
tree1e6f703c3c1b1c2e55b759b4e992ef04e81f973e
parent96b78dff0321d881ef27d858a462c476e0444619 (diff)
nl80211: New notification to discover mesh peer candidates.
Notify userspace when a beacon/presp is received from a suitable mesh peer candidate for whom no sta information exists. Userspace can then decide to create a sta info for the candidate. If userspace is not ready to authenticate the peer right away, it can create the sta info with the authenticated flag unset and set it later. Signed-off-by: Javier Cardona <javier@cozybit.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--include/linux/nl80211.h12
-rw-r--r--include/net/cfg80211.h16
-rw-r--r--net/wireless/mesh.c14
-rw-r--r--net/wireless/nl80211.c38
-rw-r--r--net/wireless/nl80211.h4
5 files changed, 84 insertions, 0 deletions
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 5ec4ac3a0ef4..b87481866dde 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -410,6 +410,16 @@
410 * notification. This event is used to indicate that an unprotected 410 * notification. This event is used to indicate that an unprotected
411 * disassociation frame was dropped when MFP is in use. 411 * disassociation frame was dropped when MFP is in use.
412 * 412 *
413 * @NL80211_CMD_NEW_PEER_CANDIDATE: Notification on the reception of a
414 * beacon or probe response from a compatible mesh peer. This is only
415 * sent while no station information (sta_info) exists for the new peer
416 * candidate and when @NL80211_MESH_SETUP_USERSPACE_AUTH is set. On
417 * reception of this notification, userspace may decide to create a new
418 * station (@NL80211_CMD_NEW_STATION). To stop this notification from
419 * reoccurring, the userspace authentication daemon may want to create the
420 * new station with the AUTHENTICATED flag unset and maybe change it later
421 * depending on the authentication result.
422 *
413 * @NL80211_CMD_MAX: highest used command number 423 * @NL80211_CMD_MAX: highest used command number
414 * @__NL80211_CMD_AFTER_LAST: internal use 424 * @__NL80211_CMD_AFTER_LAST: internal use
415 */ 425 */
@@ -522,6 +532,8 @@ enum nl80211_commands {
522 NL80211_CMD_UNPROT_DEAUTHENTICATE, 532 NL80211_CMD_UNPROT_DEAUTHENTICATE,
523 NL80211_CMD_UNPROT_DISASSOCIATE, 533 NL80211_CMD_UNPROT_DISASSOCIATE,
524 534
535 NL80211_CMD_NEW_PEER_CANDIDATE,
536
525 /* add new commands above here */ 537 /* add new commands above here */
526 538
527 /* used to define NL80211_CMD_MAX below */ 539 /* used to define NL80211_CMD_MAX below */
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index e77603bd1630..f40cd30847de 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2489,6 +2489,22 @@ void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr,
2489void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp); 2489void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp);
2490 2490
2491/** 2491/**
2492 * cfg80211_notify_new_candidate - notify cfg80211 of a new mesh peer candidate
2493 *
2494 * @dev: network device
2495 * @macaddr: the MAC address of the new candidate
2496 * @ie: information elements advertised by the peer candidate
2497 * @ie_len: lenght of the information elements buffer
2498 * @gfp: allocation flags
2499 *
2500 * This function notifies cfg80211 that the mesh peer candidate has been
2501 * detected, most likely via a beacon or, less likely, via a probe response.
2502 * cfg80211 then sends a notification to userspace.
2503 */
2504void cfg80211_notify_new_peer_candidate(struct net_device *dev,
2505 const u8 *macaddr, const u8 *ie, u8 ie_len, gfp_t gfp);
2506
2507/**
2492 * DOC: RFkill integration 2508 * DOC: RFkill integration
2493 * 2509 *
2494 * RFkill integration in cfg80211 is almost invisible to drivers, 2510 * RFkill integration in cfg80211 is almost invisible to drivers,
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index e0226e8265a3..5c116083eeca 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -1,5 +1,6 @@
1#include <linux/ieee80211.h> 1#include <linux/ieee80211.h>
2#include <net/cfg80211.h> 2#include <net/cfg80211.h>
3#include "nl80211.h"
3#include "core.h" 4#include "core.h"
4 5
5/* Default values, timeouts in ms */ 6/* Default values, timeouts in ms */
@@ -110,6 +111,19 @@ int cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
110 return err; 111 return err;
111} 112}
112 113
114void cfg80211_notify_new_peer_candidate(struct net_device *dev,
115 const u8 *macaddr, const u8* ie, u8 ie_len, gfp_t gfp)
116{
117 struct wireless_dev *wdev = dev->ieee80211_ptr;
118
119 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_MESH_POINT))
120 return;
121
122 nl80211_send_new_peer_candidate(wiphy_to_dev(wdev->wiphy), dev,
123 macaddr, ie, ie_len, gfp);
124}
125EXPORT_SYMBOL(cfg80211_notify_new_peer_candidate);
126
113static int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, 127static int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
114 struct net_device *dev) 128 struct net_device *dev)
115{ 129{
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index f4cb8efe2e5f..58f501a35022 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -5818,6 +5818,44 @@ void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
5818 nlmsg_free(msg); 5818 nlmsg_free(msg);
5819} 5819}
5820 5820
5821void nl80211_send_new_peer_candidate(struct cfg80211_registered_device *rdev,
5822 struct net_device *netdev,
5823 const u8 *macaddr, const u8* ie, u8 ie_len,
5824 gfp_t gfp)
5825{
5826 struct sk_buff *msg;
5827 void *hdr;
5828
5829 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
5830 if (!msg)
5831 return;
5832
5833 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NEW_PEER_CANDIDATE);
5834 if (!hdr) {
5835 nlmsg_free(msg);
5836 return;
5837 }
5838
5839 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
5840 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
5841 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, macaddr);
5842 if (ie_len && ie)
5843 NLA_PUT(msg, NL80211_ATTR_IE, ie_len , ie);
5844
5845 if (genlmsg_end(msg, hdr) < 0) {
5846 nlmsg_free(msg);
5847 return;
5848 }
5849
5850 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
5851 nl80211_mlme_mcgrp.id, gfp);
5852 return;
5853
5854 nla_put_failure:
5855 genlmsg_cancel(msg, hdr);
5856 nlmsg_free(msg);
5857}
5858
5821void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev, 5859void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
5822 struct net_device *netdev, const u8 *addr, 5860 struct net_device *netdev, const u8 *addr,
5823 enum nl80211_key_type key_type, int key_id, 5861 enum nl80211_key_type key_type, int key_id,
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index dcac5cd6f017..f2af6955a665 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -50,6 +50,10 @@ void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
50 struct net_device *netdev, u16 reason, 50 struct net_device *netdev, u16 reason,
51 const u8 *ie, size_t ie_len, bool from_ap); 51 const u8 *ie, size_t ie_len, bool from_ap);
52 52
53void nl80211_send_new_peer_candidate(struct cfg80211_registered_device *rdev,
54 struct net_device *netdev,
55 const u8 *macaddr, const u8* ie, u8 ie_len,
56 gfp_t gfp);
53void 57void
54nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev, 58nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
55 struct net_device *netdev, const u8 *addr, 59 struct net_device *netdev, const u8 *addr,