diff options
author | Johannes Berg <johannes.berg@intel.com> | 2010-09-30 15:06:09 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-10-05 13:35:23 -0400 |
commit | 663fcafd977f13e6483f7d4cf2ccdbc4fae81ed0 (patch) | |
tree | b1c74fe389dff24d94c95eaeb3a52932f6671007 /net | |
parent | 4bd530f3ab51c7d656bca29d927a50e5aa87175e (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>
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/cfg.c | 7 | ||||
-rw-r--r-- | net/wireless/mlme.c | 54 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 10 |
3 files changed, 57 insertions, 14 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 9e63fc28f85..a7a78f28ff6 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 46f37116089..caf11a42750 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 0087c4323c5..cbbbe9ab452 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 | } |