Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 277781
b: refs/heads/master
c: 28946da
h: refs/heads/master
i:
  277779: ece4fc2
v: v3
  • Loading branch information
Johannes Berg authored and John W. Linville committed Nov 9, 2011
1 parent bcb756a commit c8d187d
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 665c93a93e35cafcd8c84073824f1ef1b19f0a7d
refs/heads/master: 28946da763e8b8d8ffd01ab861b684a4afb4bc3b
12 changes: 12 additions & 0 deletions trunk/include/linux/nl80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,16 @@
* @NL80211_CMD_TDLS_OPER: Perform a high-level TDLS command (e.g. link setup).
* @NL80211_CMD_TDLS_MGMT: Send a TDLS management frame.
*
* @NL80211_CMD_UNEXPECTED_FRAME: Used by an application controlling an AP
* (or GO) interface (i.e. hostapd) to ask for unexpected frames to
* implement sending deauth to stations that send unexpected class 3
* frames. Also used as the event sent by the kernel when such a frame
* is received.
* For the event, the %NL80211_ATTR_MAC attribute carries the TA and
* other attributes like the interface index are present.
* If used as the command it must have an interface index and you can
* only unsubscribe from the event by closing the socket.
*
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
*/
Expand Down Expand Up @@ -638,6 +648,8 @@ enum nl80211_commands {
NL80211_CMD_TDLS_OPER,
NL80211_CMD_TDLS_MGMT,

NL80211_CMD_UNEXPECTED_FRAME,

/* add new commands above here */

/* used to define NL80211_CMD_MAX below */
Expand Down
17 changes: 17 additions & 0 deletions trunk/include/net/cfg80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -2183,6 +2183,8 @@ struct wireless_dev {

int beacon_interval;

u32 ap_unexpected_nlpid;

#ifdef CONFIG_CFG80211_WEXT
/* wext data */
struct {
Expand Down Expand Up @@ -3193,6 +3195,21 @@ void cfg80211_gtk_rekey_notify(struct net_device *dev, const u8 *bssid,
void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index,
const u8 *bssid, bool preauth, gfp_t gfp);

/**
* cfg80211_rx_spurious_frame - inform userspace about a spurious frame
* @dev: The device the frame matched to
* @addr: the transmitter address
* @gfp: context flags
*
* This function is used in AP mode (only!) to inform userspace that
* a spurious class 3 frame was received, to be able to deauth the
* sender.
* Returns %true if the frame was passed to userspace (or this failed
* for a reason other than not having a subscription.)
*/
bool cfg80211_rx_spurious_frame(struct net_device *dev,
const u8 *addr, gfp_t gfp);

/* Logging, debugging and troubleshooting/diagnostic helpers. */

/* wiphy_printk helpers, similar to dev_printk */
Expand Down
16 changes: 16 additions & 0 deletions trunk/net/wireless/mlme.c
Original file line number Diff line number Diff line change
Expand Up @@ -879,6 +879,9 @@ void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid)
}

spin_unlock_bh(&wdev->mgmt_registrations_lock);

if (nlpid == wdev->ap_unexpected_nlpid)
wdev->ap_unexpected_nlpid = 0;
}

void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev)
Expand Down Expand Up @@ -1107,3 +1110,16 @@ void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index,
nl80211_pmksa_candidate_notify(rdev, dev, index, bssid, preauth, gfp);
}
EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify);

bool cfg80211_rx_spurious_frame(struct net_device *dev,
const u8 *addr, gfp_t gfp)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;

if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
wdev->iftype != NL80211_IFTYPE_P2P_GO))
return false;

return nl80211_unexpected_frame(dev, addr, gfp);
}
EXPORT_SYMBOL(cfg80211_rx_spurious_frame);
66 changes: 66 additions & 0 deletions trunk/net/wireless/nl80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -5832,6 +5832,23 @@ static int nl80211_set_rekey_data(struct sk_buff *skb, struct genl_info *info)
return err;
}

static int nl80211_register_unexpected_frame(struct sk_buff *skb,
struct genl_info *info)
{
struct net_device *dev = info->user_ptr[1];
struct wireless_dev *wdev = dev->ieee80211_ptr;

if (wdev->iftype != NL80211_IFTYPE_AP &&
wdev->iftype != NL80211_IFTYPE_P2P_GO)
return -EINVAL;

if (wdev->ap_unexpected_nlpid)
return -EBUSY;

wdev->ap_unexpected_nlpid = info->snd_pid;
return 0;
}

#define NL80211_FLAG_NEED_WIPHY 0x01
#define NL80211_FLAG_NEED_NETDEV 0x02
#define NL80211_FLAG_NEED_RTNL 0x04
Expand Down Expand Up @@ -6387,6 +6404,14 @@ static struct genl_ops nl80211_ops[] = {
.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_UNEXPECTED_FRAME,
.doit = nl80211_register_unexpected_frame,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
.internal_flags = NL80211_FLAG_NEED_NETDEV |
NL80211_FLAG_NEED_RTNL,
},
};

static struct genl_multicast_group nl80211_mlme_mcgrp = {
Expand Down Expand Up @@ -7171,6 +7196,47 @@ void nl80211_send_sta_del_event(struct cfg80211_registered_device *rdev,
nlmsg_free(msg);
}

bool nl80211_unexpected_frame(struct net_device *dev, const u8 *addr, gfp_t gfp)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
struct sk_buff *msg;
void *hdr;
int err;
u32 nlpid = ACCESS_ONCE(wdev->ap_unexpected_nlpid);

if (!nlpid)
return false;

msg = nlmsg_new(100, gfp);
if (!msg)
return true;

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

NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);

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

genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlpid);
return true;

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

int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
struct net_device *netdev, u32 nlpid,
int freq, const u8 *buf, size_t len, gfp_t gfp)
Expand Down
3 changes: 3 additions & 0 deletions trunk/net/wireless/nl80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,4 +117,7 @@ void nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev,
struct net_device *netdev, int index,
const u8 *bssid, bool preauth, gfp_t gfp);

bool nl80211_unexpected_frame(struct net_device *dev,
const u8 *addr, gfp_t gfp);

#endif /* __NET_WIRELESS_NL80211_H */

0 comments on commit c8d187d

Please sign in to comment.