aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
authorJouni Malinen <jouni.malinen@atheros.com>2009-03-19 07:39:21 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-03-27 20:13:02 -0400
commit6039f6d23fe792d615da5449e9fa1c6b43caacf6 (patch)
treeaf94d1ad78ce1e82d76328ea9a67b351f0a9174b /net/wireless
parenta299542e97ec1939fdca7db6d3d82c0aa9bf8b9a (diff)
nl80211: Event notifications for MLME events
Add new nl80211 event notifications (and a new multicast group, "mlme") for informing user space about received and processed Authentication, (Re)Association Response, Deauthentication, and Disassociation frames in station and IBSS modes (i.e., MLME SAP interface primitives MLME-AUTHENTICATE.confirm, MLME-ASSOCIATE.confirm, MLME-REASSOCIATE.confirm, MLME-DEAUTHENTICATE.indicate, and MLME-DISASSOCIATE.indication). The event data is encapsulated as the 802.11 management frame since we already have the frame in that format and it includes all the needed information. This is the initial step in providing MLME SAP interface for authentication and association with nl80211. In other words, kernel code will act as the MLME and a user space application can control it as the SME. Signed-off-by: Jouni Malinen <j@w1.fi> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/Makefile2
-rw-r--r--net/wireless/mlme.c46
-rw-r--r--net/wireless/nl80211.c72
-rw-r--r--net/wireless/nl80211.h12
4 files changed, 131 insertions, 1 deletions
diff --git a/net/wireless/Makefile b/net/wireless/Makefile
index c157b4d8014b..6d1e7b27b752 100644
--- a/net/wireless/Makefile
+++ b/net/wireless/Makefile
@@ -5,7 +5,7 @@ obj-$(CONFIG_LIB80211_CRYPT_WEP) += lib80211_crypt_wep.o
5obj-$(CONFIG_LIB80211_CRYPT_CCMP) += lib80211_crypt_ccmp.o 5obj-$(CONFIG_LIB80211_CRYPT_CCMP) += lib80211_crypt_ccmp.o
6obj-$(CONFIG_LIB80211_CRYPT_TKIP) += lib80211_crypt_tkip.o 6obj-$(CONFIG_LIB80211_CRYPT_TKIP) += lib80211_crypt_tkip.o
7 7
8cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o 8cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o mlme.o
9cfg80211-$(CONFIG_WIRELESS_EXT) += wext-compat.o 9cfg80211-$(CONFIG_WIRELESS_EXT) += wext-compat.o
10 10
11ccflags-y += -D__CHECK_ENDIAN__ 11ccflags-y += -D__CHECK_ENDIAN__
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
new file mode 100644
index 000000000000..bec5721b6f99
--- /dev/null
+++ b/net/wireless/mlme.c
@@ -0,0 +1,46 @@
1/*
2 * cfg80211 MLME SAP interface
3 *
4 * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
5 */
6
7#include <linux/kernel.h>
8#include <linux/module.h>
9#include <linux/netdevice.h>
10#include <linux/nl80211.h>
11#include <net/cfg80211.h>
12#include "core.h"
13#include "nl80211.h"
14
15void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len)
16{
17 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
18 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
19 nl80211_send_rx_auth(rdev, dev, buf, len);
20}
21EXPORT_SYMBOL(cfg80211_send_rx_auth);
22
23void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len)
24{
25 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
26 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
27 nl80211_send_rx_assoc(rdev, dev, buf, len);
28}
29EXPORT_SYMBOL(cfg80211_send_rx_assoc);
30
31void cfg80211_send_rx_deauth(struct net_device *dev, const u8 *buf, size_t len)
32{
33 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
34 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
35 nl80211_send_rx_deauth(rdev, dev, buf, len);
36}
37EXPORT_SYMBOL(cfg80211_send_rx_deauth);
38
39void cfg80211_send_rx_disassoc(struct net_device *dev, const u8 *buf,
40 size_t len)
41{
42 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
43 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
44 nl80211_send_rx_disassoc(rdev, dev, buf, len);
45}
46EXPORT_SYMBOL(cfg80211_send_rx_disassoc);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index a3ecf8d73898..c034c2418cb3 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -2830,6 +2830,9 @@ static struct genl_ops nl80211_ops[] = {
2830 .dumpit = nl80211_dump_scan, 2830 .dumpit = nl80211_dump_scan,
2831 }, 2831 },
2832}; 2832};
2833static struct genl_multicast_group nl80211_mlme_mcgrp = {
2834 .name = "mlme",
2835};
2833 2836
2834/* multicast groups */ 2837/* multicast groups */
2835static struct genl_multicast_group nl80211_config_mcgrp = { 2838static struct genl_multicast_group nl80211_config_mcgrp = {
@@ -2975,6 +2978,71 @@ nla_put_failure:
2975 nlmsg_free(msg); 2978 nlmsg_free(msg);
2976} 2979}
2977 2980
2981static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev,
2982 struct net_device *netdev,
2983 const u8 *buf, size_t len,
2984 enum nl80211_commands cmd)
2985{
2986 struct sk_buff *msg;
2987 void *hdr;
2988
2989 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
2990 if (!msg)
2991 return;
2992
2993 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
2994 if (!hdr) {
2995 nlmsg_free(msg);
2996 return;
2997 }
2998
2999 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
3000 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
3001 NLA_PUT(msg, NL80211_ATTR_FRAME, len, buf);
3002
3003 if (genlmsg_end(msg, hdr) < 0) {
3004 nlmsg_free(msg);
3005 return;
3006 }
3007
3008 genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, GFP_KERNEL);
3009 return;
3010
3011 nla_put_failure:
3012 genlmsg_cancel(msg, hdr);
3013 nlmsg_free(msg);
3014}
3015
3016void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev,
3017 struct net_device *netdev, const u8 *buf, size_t len)
3018{
3019 nl80211_send_mlme_event(rdev, netdev, buf, len,
3020 NL80211_CMD_AUTHENTICATE);
3021}
3022
3023void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
3024 struct net_device *netdev, const u8 *buf,
3025 size_t len)
3026{
3027 nl80211_send_mlme_event(rdev, netdev, buf, len, NL80211_CMD_ASSOCIATE);
3028}
3029
3030void nl80211_send_rx_deauth(struct cfg80211_registered_device *rdev,
3031 struct net_device *netdev, const u8 *buf,
3032 size_t len)
3033{
3034 nl80211_send_mlme_event(rdev, netdev, buf, len,
3035 NL80211_CMD_DEAUTHENTICATE);
3036}
3037
3038void nl80211_send_rx_disassoc(struct cfg80211_registered_device *rdev,
3039 struct net_device *netdev, const u8 *buf,
3040 size_t len)
3041{
3042 nl80211_send_mlme_event(rdev, netdev, buf, len,
3043 NL80211_CMD_DISASSOCIATE);
3044}
3045
2978/* initialisation/exit functions */ 3046/* initialisation/exit functions */
2979 3047
2980int nl80211_init(void) 3048int nl80211_init(void)
@@ -3003,6 +3071,10 @@ int nl80211_init(void)
3003 if (err) 3071 if (err)
3004 goto err_out; 3072 goto err_out;
3005 3073
3074 err = genl_register_mc_group(&nl80211_fam, &nl80211_mlme_mcgrp);
3075 if (err)
3076 goto err_out;
3077
3006 return 0; 3078 return 0;
3007 err_out: 3079 err_out:
3008 genl_unregister_family(&nl80211_fam); 3080 genl_unregister_family(&nl80211_fam);
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index 5b5fe1339de0..b77af4ab80be 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -11,5 +11,17 @@ extern void nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
11extern void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev, 11extern void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
12 struct net_device *netdev); 12 struct net_device *netdev);
13extern void nl80211_send_reg_change_event(struct regulatory_request *request); 13extern void nl80211_send_reg_change_event(struct regulatory_request *request);
14extern void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev,
15 struct net_device *netdev,
16 const u8 *buf, size_t len);
17extern void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
18 struct net_device *netdev,
19 const u8 *buf, size_t len);
20extern void nl80211_send_rx_deauth(struct cfg80211_registered_device *rdev,
21 struct net_device *netdev,
22 const u8 *buf, size_t len);
23extern void nl80211_send_rx_disassoc(struct cfg80211_registered_device *rdev,
24 struct net_device *netdev,
25 const u8 *buf, size_t len);
14 26
15#endif /* __NET_WIRELESS_NL80211_H */ 27#endif /* __NET_WIRELESS_NL80211_H */