aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2010-09-30 15:06:09 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-10-05 13:35:23 -0400
commit663fcafd977f13e6483f7d4cf2ccdbc4fae81ed0 (patch)
treeb1c74fe389dff24d94c95eaeb3a52932f6671007
parent4bd530f3ab51c7d656bca29d927a50e5aa87175e (diff)
cfg80211/mac80211: allow management frame TX in AP mode
Enable management frame transmission and subscribing to management frames through nl80211 in both cfg80211 and mac80211. Also update a few places that I forgot to update for P2P-client mode previously, and fix a small bug with non-action frames in this API. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--net/mac80211/cfg.c7
-rw-r--r--net/wireless/mlme.c54
-rw-r--r--net/wireless/nl80211.c10
3 files changed, 57 insertions, 14 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 9e63fc28f859..a7a78f28ff6f 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1549,7 +1549,11 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
1549 1549
1550 switch (sdata->vif.type) { 1550 switch (sdata->vif.type) {
1551 case NL80211_IFTYPE_ADHOC: 1551 case NL80211_IFTYPE_ADHOC:
1552 if (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) 1552 case NL80211_IFTYPE_AP:
1553 case NL80211_IFTYPE_AP_VLAN:
1554 case NL80211_IFTYPE_P2P_GO:
1555 if (!ieee80211_is_action(mgmt->frame_control) ||
1556 mgmt->u.action.category == WLAN_CATEGORY_PUBLIC)
1553 break; 1557 break;
1554 rcu_read_lock(); 1558 rcu_read_lock();
1555 sta = sta_info_get(sdata, mgmt->da); 1559 sta = sta_info_get(sdata, mgmt->da);
@@ -1558,6 +1562,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
1558 return -ENOLINK; 1562 return -ENOLINK;
1559 break; 1563 break;
1560 case NL80211_IFTYPE_STATION: 1564 case NL80211_IFTYPE_STATION:
1565 case NL80211_IFTYPE_P2P_CLIENT:
1561 break; 1566 break;
1562 default: 1567 default:
1563 return -EOPNOTSUPP; 1568 return -EOPNOTSUPP;
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 46f371160896..caf11a427507 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -876,21 +876,53 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
876 876
877 if (ieee80211_is_action(mgmt->frame_control) && 877 if (ieee80211_is_action(mgmt->frame_control) &&
878 mgmt->u.action.category != WLAN_CATEGORY_PUBLIC) { 878 mgmt->u.action.category != WLAN_CATEGORY_PUBLIC) {
879 /* Verify that we are associated with the destination AP */ 879 int err = 0;
880
880 wdev_lock(wdev); 881 wdev_lock(wdev);
881 882
882 if (!wdev->current_bss || 883 switch (wdev->iftype) {
883 memcmp(wdev->current_bss->pub.bssid, mgmt->bssid, 884 case NL80211_IFTYPE_ADHOC:
884 ETH_ALEN) != 0 || 885 case NL80211_IFTYPE_STATION:
885 ((wdev->iftype == NL80211_IFTYPE_STATION || 886 case NL80211_IFTYPE_P2P_CLIENT:
886 wdev->iftype == NL80211_IFTYPE_P2P_CLIENT) && 887 if (!wdev->current_bss) {
887 memcmp(wdev->current_bss->pub.bssid, mgmt->da, 888 err = -ENOTCONN;
888 ETH_ALEN) != 0)) { 889 break;
889 wdev_unlock(wdev); 890 }
890 return -ENOTCONN; 891
891 } 892 if (memcmp(wdev->current_bss->pub.bssid,
893 mgmt->bssid, ETH_ALEN)) {
894 err = -ENOTCONN;
895 break;
896 }
897
898 /*
899 * check for IBSS DA must be done by driver as
900 * cfg80211 doesn't track the stations
901 */
902 if (wdev->iftype == NL80211_IFTYPE_ADHOC)
903 break;
892 904
905 /* for station, check that DA is the AP */
906 if (memcmp(wdev->current_bss->pub.bssid,
907 mgmt->da, ETH_ALEN)) {
908 err = -ENOTCONN;
909 break;
910 }
911 break;
912 case NL80211_IFTYPE_AP:
913 case NL80211_IFTYPE_P2P_GO:
914 case NL80211_IFTYPE_AP_VLAN:
915 if (memcmp(mgmt->bssid, dev->dev_addr, ETH_ALEN))
916 err = -EINVAL;
917 break;
918 default:
919 err = -EOPNOTSUPP;
920 break;
921 }
893 wdev_unlock(wdev); 922 wdev_unlock(wdev);
923
924 if (err)
925 return err;
894 } 926 }
895 927
896 if (memcmp(mgmt->sa, dev->dev_addr, ETH_ALEN) != 0) 928 if (memcmp(mgmt->sa, dev->dev_addr, ETH_ALEN) != 0)
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 0087c4323c53..cbbbe9ab452f 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -4828,7 +4828,10 @@ static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info)
4828 4828
4829 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && 4829 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4830 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC && 4830 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC &&
4831 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { 4831 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT &&
4832 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
4833 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
4834 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) {
4832 err = -EOPNOTSUPP; 4835 err = -EOPNOTSUPP;
4833 goto out; 4836 goto out;
4834 } 4837 }
@@ -4881,7 +4884,10 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
4881 4884
4882 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && 4885 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4883 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC && 4886 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC &&
4884 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { 4887 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT &&
4888 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
4889 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
4890 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) {
4885 err = -EOPNOTSUPP; 4891 err = -EOPNOTSUPP;
4886 goto out; 4892 goto out;
4887 } 4893 }