From 581a8b0feeed8877aab3a8ca4c972419790cd07f Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Thu, 7 Apr 2011 15:08:27 -0700 Subject: nl80211: rename NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE To NL80211_MESH_SETUP_IE. This reflects our ability to insert any ie into a mesh beacon, not simply path selection ies. Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- net/wireless/mesh.c | 4 ++-- net/wireless/nl80211.c | 11 ++++++----- 2 files changed, 8 insertions(+), 7 deletions(-) (limited to 'net/wireless') diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c index 73e39c171ffb..0d4b2260f96f 100644 --- a/net/wireless/mesh.c +++ b/net/wireless/mesh.c @@ -53,8 +53,8 @@ const struct mesh_config default_mesh_config = { const struct mesh_setup default_mesh_setup = { .path_sel_proto = IEEE80211_PATH_PROTOCOL_HWMP, .path_metric = IEEE80211_PATH_METRIC_AIRTIME, - .vendor_ie = NULL, - .vendor_ie_len = 0, + .ie = NULL, + .ie_len = 0, }; int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 297d7ce4117b..ccd825a5857e 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -2823,7 +2823,7 @@ static const struct nla_policy nl80211_mesh_setup_params_policy[NL80211_MESH_SETUP_ATTR_MAX+1] = { [NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 }, [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 }, - [NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE] = { .type = NLA_BINARY, + [NL80211_MESH_SETUP_IE] = { .type = NLA_BINARY, .len = IEEE80211_MAX_DATA_LEN }, }; @@ -2925,13 +2925,14 @@ static int nl80211_parse_mesh_setup(struct genl_info *info, IEEE80211_PATH_METRIC_VENDOR : IEEE80211_PATH_METRIC_AIRTIME; - if (tb[NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE]) { + + if (tb[NL80211_MESH_SETUP_IE]) { struct nlattr *ieattr = - tb[NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE]; + tb[NL80211_MESH_SETUP_IE]; if (!is_valid_ie_attr(ieattr)) return -EINVAL; - setup->vendor_ie = nla_data(ieattr); - setup->vendor_ie_len = nla_len(ieattr); + setup->ie = nla_data(ieattr); + setup->ie_len = nla_len(ieattr); } return 0; -- cgit v1.2.3 From 15d5dda623139bbf6165030fc251bbd5798f4130 Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Thu, 7 Apr 2011 15:08:28 -0700 Subject: cfg80211/nl80211: Add userspace authentication flag to mesh setup During mesh setup, use NL80211_MESH_SETUP_USERSPACE_AUTH flag to create a secure mesh and route management frames to userspace. Also, NL80211_CMD_GET_WIPHY now returns a flag NL80211_SUPPORT_MESH_AUTH if the wiphy's mesh implementation supports routing of mesh auth frames to userspace. This is useful for forward compatibility between old kernels and new userspace tools. Signed-off-by: Javier Cardona Signed-off-by: Thomas Pedersen Signed-off-by: John W. Linville --- net/wireless/mesh.c | 4 ++++ net/wireless/nl80211.c | 5 +++++ 2 files changed, 9 insertions(+) (limited to 'net/wireless') diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c index 0d4b2260f96f..0e5c122ce324 100644 --- a/net/wireless/mesh.c +++ b/net/wireless/mesh.c @@ -72,6 +72,10 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) return -EOPNOTSUPP; + if (!(rdev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) && + setup->is_secure) + return -EOPNOTSUPP; + if (wdev->mesh_id_len) return -EALREADY; diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index ccd825a5857e..cbedfc2a42a2 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] = { [NL80211_ATTR_BSS_HT_OPMODE] = { .type = NLA_U16 }, [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED }, + [NL80211_ATTR_SUPPORT_MESH_AUTH] = { .type = NLA_FLAG }, [NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY, .len = NL80211_HT_CAPABILITY_LEN }, @@ -594,6 +595,8 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, if (dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_IBSS_RSN); + if (dev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) + NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_MESH_AUTH); NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES, sizeof(u32) * dev->wiphy.n_cipher_suites, @@ -2823,6 +2826,7 @@ static const struct nla_policy nl80211_mesh_setup_params_policy[NL80211_MESH_SETUP_ATTR_MAX+1] = { [NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 }, [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 }, + [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG }, [NL80211_MESH_SETUP_IE] = { .type = NLA_BINARY, .len = IEEE80211_MAX_DATA_LEN }, }; @@ -2934,6 +2938,7 @@ static int nl80211_parse_mesh_setup(struct genl_info *info, setup->ie = nla_data(ieattr); setup->ie_len = nla_len(ieattr); } + setup->is_secure = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AUTH]); return 0; } -- cgit v1.2.3 From 5cff5e01e818029a5d2c3c31b7ae5e5e7ee70452 Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Thu, 7 Apr 2011 15:08:29 -0700 Subject: mac80211: ignore peers if security is enabled for this mesh Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- net/wireless/mesh.c | 1 + 1 file changed, 1 insertion(+) (limited to 'net/wireless') diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c index 0e5c122ce324..e0226e8265a3 100644 --- a/net/wireless/mesh.c +++ b/net/wireless/mesh.c @@ -55,6 +55,7 @@ const struct mesh_setup default_mesh_setup = { .path_metric = IEEE80211_PATH_METRIC_AIRTIME, .ie = NULL, .ie_len = 0, + .is_secure = false, }; int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, -- cgit v1.2.3 From b39c48fac1fc915a5dcd024bf6e9aabc855ed591 Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Thu, 7 Apr 2011 15:08:30 -0700 Subject: nl80211/mac80211: let userspace authenticate stations Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- net/wireless/nl80211.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'net/wireless') diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index cbedfc2a42a2..ce29a0d0e88e 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -1925,6 +1925,7 @@ static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = { [NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG }, [NL80211_STA_FLAG_WME] = { .type = NLA_FLAG }, [NL80211_STA_FLAG_MFP] = { .type = NLA_FLAG }, + [NL80211_STA_FLAG_AUTHENTICATED] = { .type = NLA_FLAG }, }; static int parse_station_flags(struct genl_info *info, @@ -2284,7 +2285,9 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) err = -EINVAL; if (params.supported_rates) err = -EINVAL; - if (params.sta_flags_mask) + if (params.sta_flags_mask & + ~(BIT(NL80211_STA_FLAG_AUTHENTICATED) | + BIT(NL80211_STA_FLAG_AUTHORIZED))) err = -EINVAL; break; default: -- cgit v1.2.3 From 96b78dff0321d881ef27d858a462c476e0444619 Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Thu, 7 Apr 2011 15:08:33 -0700 Subject: nl80211/mac80211: Perform PLINK_ACTION on new station Modify the NEW_STATION command to accept PLINK_ACTIONS, in case userspace wants to create stations and initiate a peer link right away (for authenticated stations) or create a blocked station (for debugging). Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- net/wireless/nl80211.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'net/wireless') diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index ce29a0d0e88e..f4cb8efe2e5f 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -2349,11 +2349,16 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) params.ht_capa = nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]); + if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION]) + params.plink_action = + nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]); + if (parse_station_flags(info, ¶ms)) return -EINVAL; if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT && dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) return -EINVAL; -- cgit v1.2.3 From c93b5e717ec47b57abfe0229360bc11e77520984 Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Thu, 7 Apr 2011 15:08:34 -0700 Subject: nl80211: New notification to discover mesh peer candidates. Notify userspace when a beacon/presp is received from a suitable mesh peer candidate for whom no sta information exists. Userspace can then decide to create a sta info for the candidate. If userspace is not ready to authenticate the peer right away, it can create the sta info with the authenticated flag unset and set it later. Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- net/wireless/mesh.c | 14 ++++++++++++++ net/wireless/nl80211.c | 38 ++++++++++++++++++++++++++++++++++++++ net/wireless/nl80211.h | 4 ++++ 3 files changed, 56 insertions(+) (limited to 'net/wireless') diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c index e0226e8265a3..5c116083eeca 100644 --- a/net/wireless/mesh.c +++ b/net/wireless/mesh.c @@ -1,5 +1,6 @@ #include #include +#include "nl80211.h" #include "core.h" /* Default values, timeouts in ms */ @@ -110,6 +111,19 @@ int cfg80211_join_mesh(struct cfg80211_registered_device *rdev, return err; } +void cfg80211_notify_new_peer_candidate(struct net_device *dev, + const u8 *macaddr, const u8* ie, u8 ie_len, gfp_t gfp) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + + if (WARN_ON(wdev->iftype != NL80211_IFTYPE_MESH_POINT)) + return; + + nl80211_send_new_peer_candidate(wiphy_to_dev(wdev->wiphy), dev, + macaddr, ie, ie_len, gfp); +} +EXPORT_SYMBOL(cfg80211_notify_new_peer_candidate); + static int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, struct net_device *dev) { diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index f4cb8efe2e5f..58f501a35022 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -5818,6 +5818,44 @@ void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev, nlmsg_free(msg); } +void nl80211_send_new_peer_candidate(struct cfg80211_registered_device *rdev, + struct net_device *netdev, + const u8 *macaddr, const u8* ie, u8 ie_len, + gfp_t gfp) +{ + struct sk_buff *msg; + void *hdr; + + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); + if (!msg) + return; + + hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NEW_PEER_CANDIDATE); + if (!hdr) { + nlmsg_free(msg); + return; + } + + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); + NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); + NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, macaddr); + if (ie_len && ie) + NLA_PUT(msg, NL80211_ATTR_IE, ie_len , ie); + + if (genlmsg_end(msg, hdr) < 0) { + nlmsg_free(msg); + return; + } + + genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, + nl80211_mlme_mcgrp.id, gfp); + return; + + nla_put_failure: + genlmsg_cancel(msg, hdr); + nlmsg_free(msg); +} + void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev, struct net_device *netdev, const u8 *addr, 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, struct net_device *netdev, u16 reason, const u8 *ie, size_t ie_len, bool from_ap); +void nl80211_send_new_peer_candidate(struct cfg80211_registered_device *rdev, + struct net_device *netdev, + const u8 *macaddr, const u8* ie, u8 ie_len, + gfp_t gfp); void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev, struct net_device *netdev, const u8 *addr, -- cgit v1.2.3 From ebe27c91af8b7f4810ae906fbd3eeb2d87850026 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Fri, 8 Apr 2011 21:24:24 +0530 Subject: {mac|nl}80211: Add station connected time Add station connected time in debugfs. This will be helpful to get a measure of stability of the connection and for debugging stress issues Cc: Senthilkumar Balasubramanian Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- net/wireless/nl80211.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'net/wireless') diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 58f501a35022..0efa7fd01150 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -2020,6 +2020,9 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq, sinfoattr = nla_nest_start(msg, NL80211_ATTR_STA_INFO); if (!sinfoattr) goto nla_put_failure; + if (sinfo->filled & STATION_INFO_CONNECTED_TIME) + NLA_PUT_U32(msg, NL80211_STA_INFO_CONNECTED_TIME, + sinfo->connected_time); if (sinfo->filled & STATION_INFO_INACTIVE_TIME) NLA_PUT_U32(msg, NL80211_STA_INFO_INACTIVE_TIME, sinfo->inactive_time); -- cgit v1.2.3