Skip to content

Commit

Permalink
nl80211: New notification to discover mesh peer candidates.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Javier Cardona authored and John W. Linville committed Apr 12, 2011
1 parent 96b78df commit c93b5e7
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 0 deletions.
12 changes: 12 additions & 0 deletions include/linux/nl80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,16 @@
* notification. This event is used to indicate that an unprotected
* disassociation frame was dropped when MFP is in use.
*
* @NL80211_CMD_NEW_PEER_CANDIDATE: Notification on the reception of a
* beacon or probe response from a compatible mesh peer. This is only
* sent while no station information (sta_info) exists for the new peer
* candidate and when @NL80211_MESH_SETUP_USERSPACE_AUTH is set. On
* reception of this notification, userspace may decide to create a new
* station (@NL80211_CMD_NEW_STATION). To stop this notification from
* reoccurring, the userspace authentication daemon may want to create the
* new station with the AUTHENTICATED flag unset and maybe change it later
* depending on the authentication result.
*
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
*/
Expand Down Expand Up @@ -522,6 +532,8 @@ enum nl80211_commands {
NL80211_CMD_UNPROT_DEAUTHENTICATE,
NL80211_CMD_UNPROT_DISASSOCIATE,

NL80211_CMD_NEW_PEER_CANDIDATE,

/* add new commands above here */

/* used to define NL80211_CMD_MAX below */
Expand Down
16 changes: 16 additions & 0 deletions include/net/cfg80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -2488,6 +2488,22 @@ void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr,
*/
void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp);

/**
* cfg80211_notify_new_candidate - notify cfg80211 of a new mesh peer candidate
*
* @dev: network device
* @macaddr: the MAC address of the new candidate
* @ie: information elements advertised by the peer candidate
* @ie_len: lenght of the information elements buffer
* @gfp: allocation flags
*
* This function notifies cfg80211 that the mesh peer candidate has been
* detected, most likely via a beacon or, less likely, via a probe response.
* cfg80211 then sends a notification to userspace.
*/
void cfg80211_notify_new_peer_candidate(struct net_device *dev,
const u8 *macaddr, const u8 *ie, u8 ie_len, gfp_t gfp);

/**
* DOC: RFkill integration
*
Expand Down
14 changes: 14 additions & 0 deletions net/wireless/mesh.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <linux/ieee80211.h>
#include <net/cfg80211.h>
#include "nl80211.h"
#include "core.h"

/* Default values, timeouts in ms */
Expand Down Expand Up @@ -110,6 +111,19 @@ int cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
return err;
}

void cfg80211_notify_new_peer_candidate(struct net_device *dev,
const u8 *macaddr, const u8* ie, u8 ie_len, gfp_t gfp)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;

if (WARN_ON(wdev->iftype != NL80211_IFTYPE_MESH_POINT))
return;

nl80211_send_new_peer_candidate(wiphy_to_dev(wdev->wiphy), dev,
macaddr, ie, ie_len, gfp);
}
EXPORT_SYMBOL(cfg80211_notify_new_peer_candidate);

static int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
struct net_device *dev)
{
Expand Down
38 changes: 38 additions & 0 deletions net/wireless/nl80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -5818,6 +5818,44 @@ void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
nlmsg_free(msg);
}

void nl80211_send_new_peer_candidate(struct cfg80211_registered_device *rdev,
struct net_device *netdev,
const u8 *macaddr, const u8* ie, u8 ie_len,
gfp_t gfp)
{
struct sk_buff *msg;
void *hdr;

msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
if (!msg)
return;

hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NEW_PEER_CANDIDATE);
if (!hdr) {
nlmsg_free(msg);
return;
}

NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, macaddr);
if (ie_len && ie)
NLA_PUT(msg, NL80211_ATTR_IE, ie_len , ie);

if (genlmsg_end(msg, hdr) < 0) {
nlmsg_free(msg);
return;
}

genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
nl80211_mlme_mcgrp.id, gfp);
return;

nla_put_failure:
genlmsg_cancel(msg, hdr);
nlmsg_free(msg);
}

void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
struct net_device *netdev, const u8 *addr,
enum nl80211_key_type key_type, int key_id,
Expand Down
4 changes: 4 additions & 0 deletions net/wireless/nl80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
struct net_device *netdev, u16 reason,
const u8 *ie, size_t ie_len, bool from_ap);

void nl80211_send_new_peer_candidate(struct cfg80211_registered_device *rdev,
struct net_device *netdev,
const u8 *macaddr, const u8* ie, u8 ie_len,
gfp_t gfp);
void
nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
struct net_device *netdev, const u8 *addr,
Expand Down

0 comments on commit c93b5e7

Please sign in to comment.