aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/mesh.c23
-rw-r--r--net/wireless/nl80211.c67
-rw-r--r--net/wireless/nl80211.h4
3 files changed, 86 insertions, 8 deletions
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index 73e39c171ffb..5c116083eeca 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -1,5 +1,6 @@
1#include <linux/ieee80211.h> 1#include <linux/ieee80211.h>
2#include <net/cfg80211.h> 2#include <net/cfg80211.h>
3#include "nl80211.h"
3#include "core.h" 4#include "core.h"
4 5
5/* Default values, timeouts in ms */ 6/* Default values, timeouts in ms */
@@ -53,8 +54,9 @@ const struct mesh_config default_mesh_config = {
53const struct mesh_setup default_mesh_setup = { 54const struct mesh_setup default_mesh_setup = {
54 .path_sel_proto = IEEE80211_PATH_PROTOCOL_HWMP, 55 .path_sel_proto = IEEE80211_PATH_PROTOCOL_HWMP,
55 .path_metric = IEEE80211_PATH_METRIC_AIRTIME, 56 .path_metric = IEEE80211_PATH_METRIC_AIRTIME,
56 .vendor_ie = NULL, 57 .ie = NULL,
57 .vendor_ie_len = 0, 58 .ie_len = 0,
59 .is_secure = false,
58}; 60};
59 61
60int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, 62int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
@@ -72,6 +74,10 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
72 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) 74 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
73 return -EOPNOTSUPP; 75 return -EOPNOTSUPP;
74 76
77 if (!(rdev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) &&
78 setup->is_secure)
79 return -EOPNOTSUPP;
80
75 if (wdev->mesh_id_len) 81 if (wdev->mesh_id_len)
76 return -EALREADY; 82 return -EALREADY;
77 83
@@ -105,6 +111,19 @@ int cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
105 return err; 111 return err;
106} 112}
107 113
114void cfg80211_notify_new_peer_candidate(struct net_device *dev,
115 const u8 *macaddr, const u8* ie, u8 ie_len, gfp_t gfp)
116{
117 struct wireless_dev *wdev = dev->ieee80211_ptr;
118
119 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_MESH_POINT))
120 return;
121
122 nl80211_send_new_peer_candidate(wiphy_to_dev(wdev->wiphy), dev,
123 macaddr, ie, ie_len, gfp);
124}
125EXPORT_SYMBOL(cfg80211_notify_new_peer_candidate);
126
108static int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, 127static int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
109 struct net_device *dev) 128 struct net_device *dev)
110{ 129{
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 297d7ce4117b..0efa7fd01150 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -124,6 +124,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
124 [NL80211_ATTR_BSS_HT_OPMODE] = { .type = NLA_U16 }, 124 [NL80211_ATTR_BSS_HT_OPMODE] = { .type = NLA_U16 },
125 125
126 [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED }, 126 [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED },
127 [NL80211_ATTR_SUPPORT_MESH_AUTH] = { .type = NLA_FLAG },
127 128
128 [NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY, 129 [NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY,
129 .len = NL80211_HT_CAPABILITY_LEN }, 130 .len = NL80211_HT_CAPABILITY_LEN },
@@ -594,6 +595,8 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
594 595
595 if (dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) 596 if (dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)
596 NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_IBSS_RSN); 597 NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_IBSS_RSN);
598 if (dev->wiphy.flags & WIPHY_FLAG_MESH_AUTH)
599 NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_MESH_AUTH);
597 600
598 NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES, 601 NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES,
599 sizeof(u32) * dev->wiphy.n_cipher_suites, 602 sizeof(u32) * dev->wiphy.n_cipher_suites,
@@ -1922,6 +1925,7 @@ static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {
1922 [NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG }, 1925 [NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG },
1923 [NL80211_STA_FLAG_WME] = { .type = NLA_FLAG }, 1926 [NL80211_STA_FLAG_WME] = { .type = NLA_FLAG },
1924 [NL80211_STA_FLAG_MFP] = { .type = NLA_FLAG }, 1927 [NL80211_STA_FLAG_MFP] = { .type = NLA_FLAG },
1928 [NL80211_STA_FLAG_AUTHENTICATED] = { .type = NLA_FLAG },
1925}; 1929};
1926 1930
1927static int parse_station_flags(struct genl_info *info, 1931static int parse_station_flags(struct genl_info *info,
@@ -2016,6 +2020,9 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
2016 sinfoattr = nla_nest_start(msg, NL80211_ATTR_STA_INFO); 2020 sinfoattr = nla_nest_start(msg, NL80211_ATTR_STA_INFO);
2017 if (!sinfoattr) 2021 if (!sinfoattr)
2018 goto nla_put_failure; 2022 goto nla_put_failure;
2023 if (sinfo->filled & STATION_INFO_CONNECTED_TIME)
2024 NLA_PUT_U32(msg, NL80211_STA_INFO_CONNECTED_TIME,
2025 sinfo->connected_time);
2019 if (sinfo->filled & STATION_INFO_INACTIVE_TIME) 2026 if (sinfo->filled & STATION_INFO_INACTIVE_TIME)
2020 NLA_PUT_U32(msg, NL80211_STA_INFO_INACTIVE_TIME, 2027 NLA_PUT_U32(msg, NL80211_STA_INFO_INACTIVE_TIME,
2021 sinfo->inactive_time); 2028 sinfo->inactive_time);
@@ -2281,7 +2288,9 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
2281 err = -EINVAL; 2288 err = -EINVAL;
2282 if (params.supported_rates) 2289 if (params.supported_rates)
2283 err = -EINVAL; 2290 err = -EINVAL;
2284 if (params.sta_flags_mask) 2291 if (params.sta_flags_mask &
2292 ~(BIT(NL80211_STA_FLAG_AUTHENTICATED) |
2293 BIT(NL80211_STA_FLAG_AUTHORIZED)))
2285 err = -EINVAL; 2294 err = -EINVAL;
2286 break; 2295 break;
2287 default: 2296 default:
@@ -2343,11 +2352,16 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
2343 params.ht_capa = 2352 params.ht_capa =
2344 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]); 2353 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
2345 2354
2355 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION])
2356 params.plink_action =
2357 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
2358
2346 if (parse_station_flags(info, &params)) 2359 if (parse_station_flags(info, &params))
2347 return -EINVAL; 2360 return -EINVAL;
2348 2361
2349 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && 2362 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
2350 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && 2363 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
2364 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
2351 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) 2365 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
2352 return -EINVAL; 2366 return -EINVAL;
2353 2367
@@ -2823,7 +2837,8 @@ static const struct nla_policy
2823 nl80211_mesh_setup_params_policy[NL80211_MESH_SETUP_ATTR_MAX+1] = { 2837 nl80211_mesh_setup_params_policy[NL80211_MESH_SETUP_ATTR_MAX+1] = {
2824 [NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 }, 2838 [NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 },
2825 [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 }, 2839 [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 },
2826 [NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE] = { .type = NLA_BINARY, 2840 [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG },
2841 [NL80211_MESH_SETUP_IE] = { .type = NLA_BINARY,
2827 .len = IEEE80211_MAX_DATA_LEN }, 2842 .len = IEEE80211_MAX_DATA_LEN },
2828}; 2843};
2829 2844
@@ -2925,14 +2940,16 @@ static int nl80211_parse_mesh_setup(struct genl_info *info,
2925 IEEE80211_PATH_METRIC_VENDOR : 2940 IEEE80211_PATH_METRIC_VENDOR :
2926 IEEE80211_PATH_METRIC_AIRTIME; 2941 IEEE80211_PATH_METRIC_AIRTIME;
2927 2942
2928 if (tb[NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE]) { 2943
2944 if (tb[NL80211_MESH_SETUP_IE]) {
2929 struct nlattr *ieattr = 2945 struct nlattr *ieattr =
2930 tb[NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE]; 2946 tb[NL80211_MESH_SETUP_IE];
2931 if (!is_valid_ie_attr(ieattr)) 2947 if (!is_valid_ie_attr(ieattr))
2932 return -EINVAL; 2948 return -EINVAL;
2933 setup->vendor_ie = nla_data(ieattr); 2949 setup->ie = nla_data(ieattr);
2934 setup->vendor_ie_len = nla_len(ieattr); 2950 setup->ie_len = nla_len(ieattr);
2935 } 2951 }
2952 setup->is_secure = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AUTH]);
2936 2953
2937 return 0; 2954 return 0;
2938} 2955}
@@ -5804,6 +5821,44 @@ void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
5804 nlmsg_free(msg); 5821 nlmsg_free(msg);
5805} 5822}
5806 5823
5824void nl80211_send_new_peer_candidate(struct cfg80211_registered_device *rdev,
5825 struct net_device *netdev,
5826 const u8 *macaddr, const u8* ie, u8 ie_len,
5827 gfp_t gfp)
5828{
5829 struct sk_buff *msg;
5830 void *hdr;
5831
5832 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
5833 if (!msg)
5834 return;
5835
5836 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NEW_PEER_CANDIDATE);
5837 if (!hdr) {
5838 nlmsg_free(msg);
5839 return;
5840 }
5841
5842 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
5843 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
5844 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, macaddr);
5845 if (ie_len && ie)
5846 NLA_PUT(msg, NL80211_ATTR_IE, ie_len , ie);
5847
5848 if (genlmsg_end(msg, hdr) < 0) {
5849 nlmsg_free(msg);
5850 return;
5851 }
5852
5853 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
5854 nl80211_mlme_mcgrp.id, gfp);
5855 return;
5856
5857 nla_put_failure:
5858 genlmsg_cancel(msg, hdr);
5859 nlmsg_free(msg);
5860}
5861
5807void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev, 5862void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
5808 struct net_device *netdev, const u8 *addr, 5863 struct net_device *netdev, const u8 *addr,
5809 enum nl80211_key_type key_type, int key_id, 5864 enum nl80211_key_type key_type, int key_id,
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index dcac5cd6f017..f2af6955a665 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -50,6 +50,10 @@ void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
50 struct net_device *netdev, u16 reason, 50 struct net_device *netdev, u16 reason,
51 const u8 *ie, size_t ie_len, bool from_ap); 51 const u8 *ie, size_t ie_len, bool from_ap);
52 52
53void nl80211_send_new_peer_candidate(struct cfg80211_registered_device *rdev,
54 struct net_device *netdev,
55 const u8 *macaddr, const u8* ie, u8 ie_len,
56 gfp_t gfp);
53void 57void
54nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev, 58nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
55 struct net_device *netdev, const u8 *addr, 59 struct net_device *netdev, const u8 *addr,