diff options
Diffstat (limited to 'net/wireless')
-rw-r--r-- | net/wireless/core.c | 2 | ||||
-rw-r--r-- | net/wireless/core.h | 2 | ||||
-rw-r--r-- | net/wireless/lib80211.c | 15 | ||||
-rw-r--r-- | net/wireless/lib80211_crypt_ccmp.c | 2 | ||||
-rw-r--r-- | net/wireless/lib80211_crypt_tkip.c | 4 | ||||
-rw-r--r-- | net/wireless/lib80211_crypt_wep.c | 4 | ||||
-rw-r--r-- | net/wireless/mesh.c | 3 | ||||
-rw-r--r-- | net/wireless/mlme.c | 11 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 251 | ||||
-rw-r--r-- | net/wireless/nl80211.h | 4 | ||||
-rw-r--r-- | net/wireless/reg.c | 47 | ||||
-rw-r--r-- | net/wireless/reg.h | 2 | ||||
-rw-r--r-- | net/wireless/scan.c | 28 | ||||
-rw-r--r-- | net/wireless/util.c | 173 | ||||
-rw-r--r-- | net/wireless/wext-compat.c | 137 | ||||
-rw-r--r-- | net/wireless/wext-compat.h | 8 | ||||
-rw-r--r-- | net/wireless/wext-sme.c | 3 |
17 files changed, 570 insertions, 126 deletions
diff --git a/net/wireless/core.c b/net/wireless/core.c index c14865172da7..220f3bd176f8 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -582,7 +582,7 @@ int wiphy_register(struct wiphy *wiphy) } /* set up regulatory info */ - wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE); + regulatory_update(wiphy, NL80211_REGDOM_SET_BY_CORE); list_add_rcu(&rdev->list, &cfg80211_rdev_list); cfg80211_rdev_list_generation++; diff --git a/net/wireless/core.h b/net/wireless/core.h index 8672e028022f..796a4bdf8b0d 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -279,8 +279,6 @@ extern int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, char *newname); void ieee80211_set_bitrate_flags(struct wiphy *wiphy); -void wiphy_update_regulatory(struct wiphy *wiphy, - enum nl80211_reg_initiator setby); void cfg80211_bss_expire(struct cfg80211_registered_device *dev); void cfg80211_bss_age(struct cfg80211_registered_device *dev, diff --git a/net/wireless/lib80211.c b/net/wireless/lib80211.c index 3268fac5ab22..a55c27b75ee5 100644 --- a/net/wireless/lib80211.c +++ b/net/wireless/lib80211.c @@ -41,6 +41,11 @@ struct lib80211_crypto_alg { static LIST_HEAD(lib80211_crypto_algs); static DEFINE_SPINLOCK(lib80211_crypto_lock); +static void lib80211_crypt_deinit_entries(struct lib80211_crypt_info *info, + int force); +static void lib80211_crypt_quiescing(struct lib80211_crypt_info *info); +static void lib80211_crypt_deinit_handler(unsigned long data); + const char *print_ssid(char *buf, const char *ssid, u8 ssid_len) { const char *s = ssid; @@ -111,7 +116,8 @@ void lib80211_crypt_info_free(struct lib80211_crypt_info *info) } EXPORT_SYMBOL(lib80211_crypt_info_free); -void lib80211_crypt_deinit_entries(struct lib80211_crypt_info *info, int force) +static void lib80211_crypt_deinit_entries(struct lib80211_crypt_info *info, + int force) { struct lib80211_crypt_data *entry, *next; unsigned long flags; @@ -131,10 +137,9 @@ void lib80211_crypt_deinit_entries(struct lib80211_crypt_info *info, int force) } spin_unlock_irqrestore(info->lock, flags); } -EXPORT_SYMBOL(lib80211_crypt_deinit_entries); /* After this, crypt_deinit_list won't accept new members */ -void lib80211_crypt_quiescing(struct lib80211_crypt_info *info) +static void lib80211_crypt_quiescing(struct lib80211_crypt_info *info) { unsigned long flags; @@ -142,9 +147,8 @@ void lib80211_crypt_quiescing(struct lib80211_crypt_info *info) info->crypt_quiesced = 1; spin_unlock_irqrestore(info->lock, flags); } -EXPORT_SYMBOL(lib80211_crypt_quiescing); -void lib80211_crypt_deinit_handler(unsigned long data) +static void lib80211_crypt_deinit_handler(unsigned long data) { struct lib80211_crypt_info *info = (struct lib80211_crypt_info *)data; unsigned long flags; @@ -160,7 +164,6 @@ void lib80211_crypt_deinit_handler(unsigned long data) } spin_unlock_irqrestore(info->lock, flags); } -EXPORT_SYMBOL(lib80211_crypt_deinit_handler); void lib80211_crypt_delayed_deinit(struct lib80211_crypt_info *info, struct lib80211_crypt_data **crypt) diff --git a/net/wireless/lib80211_crypt_ccmp.c b/net/wireless/lib80211_crypt_ccmp.c index dacb3b4b1bdb..755738d26bb4 100644 --- a/net/wireless/lib80211_crypt_ccmp.c +++ b/net/wireless/lib80211_crypt_ccmp.c @@ -77,8 +77,6 @@ static void *lib80211_ccmp_init(int key_idx) priv->tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(priv->tfm)) { - printk(KERN_DEBUG "lib80211_crypt_ccmp: could not allocate " - "crypto API aes\n"); priv->tfm = NULL; goto fail; } diff --git a/net/wireless/lib80211_crypt_tkip.c b/net/wireless/lib80211_crypt_tkip.c index 7ea4f2b0770e..38734846c19e 100644 --- a/net/wireless/lib80211_crypt_tkip.c +++ b/net/wireless/lib80211_crypt_tkip.c @@ -101,7 +101,6 @@ static void *lib80211_tkip_init(int key_idx) priv->tx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(priv->tx_tfm_arc4)) { - printk(KERN_DEBUG pr_fmt("could not allocate crypto API arc4\n")); priv->tx_tfm_arc4 = NULL; goto fail; } @@ -109,7 +108,6 @@ static void *lib80211_tkip_init(int key_idx) priv->tx_tfm_michael = crypto_alloc_hash("michael_mic", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(priv->tx_tfm_michael)) { - printk(KERN_DEBUG pr_fmt("could not allocate crypto API michael_mic\n")); priv->tx_tfm_michael = NULL; goto fail; } @@ -117,7 +115,6 @@ static void *lib80211_tkip_init(int key_idx) priv->rx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(priv->rx_tfm_arc4)) { - printk(KERN_DEBUG pr_fmt("could not allocate crypto API arc4\n")); priv->rx_tfm_arc4 = NULL; goto fail; } @@ -125,7 +122,6 @@ static void *lib80211_tkip_init(int key_idx) priv->rx_tfm_michael = crypto_alloc_hash("michael_mic", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(priv->rx_tfm_michael)) { - printk(KERN_DEBUG pr_fmt("could not allocate crypto API michael_mic\n")); priv->rx_tfm_michael = NULL; goto fail; } diff --git a/net/wireless/lib80211_crypt_wep.c b/net/wireless/lib80211_crypt_wep.c index 2f265e033ae2..c1304018fc1c 100644 --- a/net/wireless/lib80211_crypt_wep.c +++ b/net/wireless/lib80211_crypt_wep.c @@ -50,16 +50,12 @@ static void *lib80211_wep_init(int keyidx) priv->tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(priv->tx_tfm)) { - printk(KERN_DEBUG "lib80211_crypt_wep: could not allocate " - "crypto API arc4\n"); priv->tx_tfm = NULL; goto fail; } priv->rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(priv->rx_tfm)) { - printk(KERN_DEBUG "lib80211_crypt_wep: could not allocate " - "crypto API arc4\n"); priv->rx_tfm = NULL; goto fail; } diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c index 5c116083eeca..4423e64c7d98 100644 --- a/net/wireless/mesh.c +++ b/net/wireless/mesh.c @@ -12,6 +12,7 @@ #define MESH_HOLD_T 100 #define MESH_PATH_TIMEOUT 5000 +#define MESH_RANN_INTERVAL 5000 /* * Minimum interval between two consecutive PREQs originated by the same @@ -49,6 +50,8 @@ const struct mesh_config default_mesh_config = { .dot11MeshHWMPmaxPREQretries = MESH_MAX_PREQ_RETRIES, .path_refresh_time = MESH_PATH_REFRESH_TIME, .min_discovery_timeout = MESH_MIN_DISCOVERY_TIMEOUT, + .dot11MeshHWMPRannInterval = MESH_RANN_INTERVAL, + .dot11MeshGateAnnouncementProtocol = false, }; const struct mesh_setup default_mesh_setup = { diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 832f6574e4ed..61adea540e02 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c @@ -1095,3 +1095,14 @@ void cfg80211_gtk_rekey_notify(struct net_device *dev, const u8 *bssid, nl80211_gtk_rekey_notify(rdev, dev, bssid, replay_ctr, gfp); } EXPORT_SYMBOL(cfg80211_gtk_rekey_notify); + +void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index, + const u8 *bssid, bool preauth, gfp_t gfp) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + struct wiphy *wiphy = wdev->wiphy; + struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); + + nl80211_pmksa_candidate_notify(rdev, dev, index, bssid, preauth, gfp); +} +EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify); diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index e83e7fee3bc0..3c6427abdf34 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -23,6 +23,12 @@ #include "nl80211.h" #include "reg.h" +static bool nl80211_valid_auth_type(enum nl80211_auth_type auth_type); +static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev, + struct genl_info *info, + struct cfg80211_crypto_settings *settings, + int cipher_limit); + static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb, struct genl_info *info); static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb, @@ -178,6 +184,13 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 }, [NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED }, [NL80211_ATTR_SCAN_SUPP_RATES] = { .type = NLA_NESTED }, + [NL80211_ATTR_HIDDEN_SSID] = { .type = NLA_U32 }, + [NL80211_ATTR_IE_PROBE_RESP] = { .type = NLA_BINARY, + .len = IEEE80211_MAX_DATA_LEN }, + [NL80211_ATTR_IE_ASSOC_RESP] = { .type = NLA_BINARY, + .len = IEEE80211_MAX_DATA_LEN }, + [NL80211_ATTR_ROAM_SUPPORT] = { .type = NLA_FLAG }, + [NL80211_ATTR_SCHED_SCAN_MATCH] = { .type = NLA_NESTED }, }; /* policy for the key attributes */ @@ -220,6 +233,12 @@ nl80211_rekey_policy[NUM_NL80211_REKEY_DATA] = { [NL80211_REKEY_DATA_REPLAY_CTR] = { .len = NL80211_REPLAY_CTR_LEN }, }; +static const struct nla_policy +nl80211_match_policy[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1] = { + [NL80211_ATTR_SCHED_SCAN_MATCH_SSID] = { .type = NLA_BINARY, + .len = IEEE80211_MAX_SSID_LEN }, +}; + /* ifidx get helper */ static int nl80211_get_ifidx(struct netlink_callback *cb) { @@ -703,11 +722,18 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, dev->wiphy.max_scan_ie_len); NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN, dev->wiphy.max_sched_scan_ie_len); + NLA_PUT_U8(msg, NL80211_ATTR_MAX_MATCH_SETS, + dev->wiphy.max_match_sets); 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); + if (dev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) + NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_AP_UAPSD); + + if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_FW_ROAM) + NLA_PUT_FLAG(msg, NL80211_ATTR_ROAM_SUPPORT); NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES, sizeof(u32) * dev->wiphy.n_cipher_suites, @@ -871,8 +897,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, NLA_PUT_U32(msg, NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION, dev->wiphy.max_remain_on_channel_duration); - /* for now at least assume all drivers have it */ - if (dev->ops->mgmt_tx) + if (dev->ops->mgmt_tx_cancel_wait) NLA_PUT_FLAG(msg, NL80211_ATTR_OFFCHANNEL_TX_OK); if (mgmt_stypes) { @@ -1985,7 +2010,10 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info) struct beacon_parameters params; int haveinfo = 0, err; - if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL])) + if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL]) || + !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]) || + !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE_PROBE_RESP]) || + !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE_ASSOC_RESP])) return -EINVAL; if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && @@ -2011,6 +2039,49 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info) if (err) return err; + /* + * In theory, some of these attributes could be required for + * NEW_BEACON, but since they were not used when the command was + * originally added, keep them optional for old user space + * programs to work with drivers that do not need the additional + * information. + */ + if (info->attrs[NL80211_ATTR_SSID]) { + params.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]); + params.ssid_len = + nla_len(info->attrs[NL80211_ATTR_SSID]); + if (params.ssid_len == 0 || + params.ssid_len > IEEE80211_MAX_SSID_LEN) + return -EINVAL; + } + + if (info->attrs[NL80211_ATTR_HIDDEN_SSID]) { + params.hidden_ssid = nla_get_u32( + info->attrs[NL80211_ATTR_HIDDEN_SSID]); + if (params.hidden_ssid != + NL80211_HIDDEN_SSID_NOT_IN_USE && + params.hidden_ssid != + NL80211_HIDDEN_SSID_ZERO_LEN && + params.hidden_ssid != + NL80211_HIDDEN_SSID_ZERO_CONTENTS) + return -EINVAL; + } + + params.privacy = !!info->attrs[NL80211_ATTR_PRIVACY]; + + if (info->attrs[NL80211_ATTR_AUTH_TYPE]) { + params.auth_type = nla_get_u32( + info->attrs[NL80211_ATTR_AUTH_TYPE]); + if (!nl80211_valid_auth_type(params.auth_type)) + return -EINVAL; + } else + params.auth_type = NL80211_AUTHTYPE_AUTOMATIC; + + err = nl80211_crypto_settings(rdev, info, ¶ms.crypto, + NL80211_MAX_NR_CIPHER_SUITES); + if (err) + return err; + call = rdev->ops->add_beacon; break; case NL80211_CMD_SET_BEACON: @@ -2041,6 +2112,25 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info) if (!haveinfo) return -EINVAL; + if (info->attrs[NL80211_ATTR_IE]) { + params.beacon_ies = nla_data(info->attrs[NL80211_ATTR_IE]); + params.beacon_ies_len = nla_len(info->attrs[NL80211_ATTR_IE]); + } + + if (info->attrs[NL80211_ATTR_IE_PROBE_RESP]) { + params.proberesp_ies = + nla_data(info->attrs[NL80211_ATTR_IE_PROBE_RESP]); + params.proberesp_ies_len = + nla_len(info->attrs[NL80211_ATTR_IE_PROBE_RESP]); + } + + if (info->attrs[NL80211_ATTR_IE_ASSOC_RESP]) { + params.assocresp_ies = + nla_data(info->attrs[NL80211_ATTR_IE_ASSOC_RESP]); + params.assocresp_ies_len = + nla_len(info->attrs[NL80211_ATTR_IE_ASSOC_RESP]); + } + err = call(&rdev->wiphy, dev, ¶ms); if (!err && params.interval) wdev->beacon_interval = params.interval; @@ -2237,6 +2327,10 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq, } nla_nest_end(msg, sinfoattr); + if (sinfo->filled & STATION_INFO_ASSOC_REQ_IES) + NLA_PUT(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len, + sinfo->assoc_req_ies); + return genlmsg_end(msg, hdr); nla_put_failure: @@ -2264,6 +2358,7 @@ static int nl80211_dump_station(struct sk_buff *skb, } while (1) { + memset(&sinfo, 0, sizeof(sinfo)); err = dev->ops->dump_station(&dev->wiphy, netdev, sta_idx, mac_addr, &sinfo); if (err == -ENOENT) @@ -2465,6 +2560,12 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) return err; } +static struct nla_policy +nl80211_sta_wme_policy[NL80211_STA_WME_MAX + 1] __read_mostly = { + [NL80211_STA_WME_UAPSD_QUEUES] = { .type = NLA_U8 }, + [NL80211_STA_WME_MAX_SP] = { .type = NLA_U8 }, +}; + static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) { struct cfg80211_registered_device *rdev = info->user_ptr[0]; @@ -2510,6 +2611,33 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) if (parse_station_flags(info, ¶ms)) return -EINVAL; + /* parse WME attributes if sta is WME capable */ + if ((rdev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) && + (params.sta_flags_set & NL80211_STA_FLAG_WME) && + info->attrs[NL80211_ATTR_STA_WME]) { + struct nlattr *tb[NL80211_STA_WME_MAX + 1]; + struct nlattr *nla; + + nla = info->attrs[NL80211_ATTR_STA_WME]; + err = nla_parse_nested(tb, NL80211_STA_WME_MAX, nla, + nl80211_sta_wme_policy); + if (err) + return err; + + if (tb[NL80211_STA_WME_UAPSD_QUEUES]) + params.uapsd_queues = + nla_get_u8(tb[NL80211_STA_WME_UAPSD_QUEUES]); + if (params.uapsd_queues & ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK) + return -EINVAL; + + if (tb[NL80211_STA_WME_MAX_SP]) + params.max_sp = + nla_get_u8(tb[NL80211_STA_WME_MAX_SP]); + + if (params.max_sp & ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK) + 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 && @@ -2955,6 +3083,10 @@ static int nl80211_get_mesh_config(struct sk_buff *skb, cur_params.dot11MeshHWMPnetDiameterTraversalTime); NLA_PUT_U8(msg, NL80211_MESHCONF_HWMP_ROOTMODE, cur_params.dot11MeshHWMPRootMode); + NLA_PUT_U16(msg, NL80211_MESHCONF_HWMP_RANN_INTERVAL, + cur_params.dot11MeshHWMPRannInterval); + NLA_PUT_U8(msg, NL80211_MESHCONF_GATE_ANNOUNCEMENTS, + cur_params.dot11MeshGateAnnouncementProtocol); nla_nest_end(msg, pinfoattr); genlmsg_end(msg, hdr); return genlmsg_reply(msg, info); @@ -2982,6 +3114,9 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A [NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT] = { .type = NLA_U32 }, [NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL] = { .type = NLA_U16 }, [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 }, + [NL80211_MESHCONF_HWMP_ROOTMODE] = { .type = NLA_U8 }, + [NL80211_MESHCONF_HWMP_RANN_INTERVAL] = { .type = NLA_U16 }, + [NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = { .type = NLA_U8 }, }; static const struct nla_policy @@ -3060,6 +3195,14 @@ do {\ dot11MeshHWMPRootMode, mask, NL80211_MESHCONF_HWMP_ROOTMODE, nla_get_u8); + FILL_IN_MESH_PARAM_IF_SET(tb, cfg, + dot11MeshHWMPRannInterval, mask, + NL80211_MESHCONF_HWMP_RANN_INTERVAL, + nla_get_u16); + FILL_IN_MESH_PARAM_IF_SET(tb, cfg, + dot11MeshGateAnnouncementProtocol, mask, + NL80211_MESHCONF_GATE_ANNOUNCEMENTS, + nla_get_u8); if (mask_out) *mask_out = mask; @@ -3503,10 +3646,11 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, struct net_device *dev = info->user_ptr[1]; struct nlattr *attr; struct wiphy *wiphy; - int err, tmp, n_ssids = 0, n_channels, i; + int err, tmp, n_ssids = 0, n_match_sets = 0, n_channels, i; u32 interval; enum ieee80211_band band; size_t ie_len; + struct nlattr *tb[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1]; if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) || !rdev->ops->sched_scan_start) @@ -3545,6 +3689,15 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, if (n_ssids > wiphy->max_sched_scan_ssids) return -EINVAL; + if (info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) + nla_for_each_nested(attr, + info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH], + tmp) + n_match_sets++; + + if (n_match_sets > wiphy->max_match_sets) + return -EINVAL; + if (info->attrs[NL80211_ATTR_IE]) ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); else @@ -3562,6 +3715,7 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, request = kzalloc(sizeof(*request) + sizeof(*request->ssids) * n_ssids + + sizeof(*request->match_sets) * n_match_sets + sizeof(*request->channels) * n_channels + ie_len, GFP_KERNEL); if (!request) { @@ -3579,6 +3733,18 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, request->ie = (void *)(request->channels + n_channels); } + if (n_match_sets) { + if (request->ie) + request->match_sets = (void *)(request->ie + ie_len); + else if (request->ssids) + request->match_sets = + (void *)(request->ssids + n_ssids); + else + request->match_sets = + (void *)(request->channels + n_channels); + } + request->n_match_sets = n_match_sets; + i = 0; if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) { /* user specified, bail out if channel not found */ @@ -3643,6 +3809,31 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, } } + i = 0; + if (info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) { + nla_for_each_nested(attr, + info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH], + tmp) { + struct nlattr *ssid; + + nla_parse(tb, NL80211_SCHED_SCAN_MATCH_ATTR_MAX, + nla_data(attr), nla_len(attr), + nl80211_match_policy); + ssid = tb[NL80211_ATTR_SCHED_SCAN_MATCH_SSID]; + if (ssid) { + if (nla_len(ssid) > IEEE80211_MAX_SSID_LEN) { + err = -EINVAL; + goto out_free; + } + memcpy(request->match_sets[i].ssid.ssid, + nla_data(ssid), nla_len(ssid)); + request->match_sets[i].ssid.ssid_len = + nla_len(ssid); + } + i++; + } + } + if (info->attrs[NL80211_ATTR_IE]) { request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); memcpy((void *)request->ie, @@ -4336,8 +4527,12 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) wiphy = &rdev->wiphy; - if (info->attrs[NL80211_ATTR_MAC]) + if (info->attrs[NL80211_ATTR_MAC]) { ibss.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); + + if (!is_valid_ether_addr(ibss.bssid)) + return -EINVAL; + } ibss.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]); ibss.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]); @@ -7075,6 +7270,52 @@ void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev, nlmsg_free(msg); } +void nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev, + struct net_device *netdev, int index, + const u8 *bssid, bool preauth, gfp_t gfp) +{ + struct sk_buff *msg; + struct nlattr *attr; + void *hdr; + + msg = nlmsg_new(NLMSG_GOODSIZE, gfp); + if (!msg) + return; + + hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PMKSA_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); + + attr = nla_nest_start(msg, NL80211_ATTR_PMKSA_CANDIDATE); + if (!attr) + goto nla_put_failure; + + NLA_PUT_U32(msg, NL80211_PMKSA_CANDIDATE_INDEX, index); + NLA_PUT(msg, NL80211_PMKSA_CANDIDATE_BSSID, ETH_ALEN, bssid); + if (preauth) + NLA_PUT_FLAG(msg, NL80211_PMKSA_CANDIDATE_PREAUTH); + + nla_nest_end(msg, attr); + + 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_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev, struct net_device *netdev, const u8 *peer, diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h index 5d69c56400ae..f24a1fbeaf19 100644 --- a/net/wireless/nl80211.h +++ b/net/wireless/nl80211.h @@ -113,4 +113,8 @@ void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev, struct net_device *netdev, const u8 *bssid, const u8 *replay_ctr, gfp_t gfp); +void nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev, + struct net_device *netdev, int index, + const u8 *bssid, bool preauth, gfp_t gfp); + #endif /* __NET_WIRELESS_NL80211_H */ diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 68a471ba193f..2520a1b7e7db 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -49,10 +49,8 @@ #include "nl80211.h" #ifdef CONFIG_CFG80211_REG_DEBUG -#define REG_DBG_PRINT(format, args...) \ - do { \ - printk(KERN_DEBUG pr_fmt(format), ##args); \ - } while (0) +#define REG_DBG_PRINT(format, args...) \ + printk(KERN_DEBUG pr_fmt(format), ##args) #else #define REG_DBG_PRINT(args...) #endif @@ -753,9 +751,10 @@ static void chan_reg_rule_print_dbg(struct ieee80211_channel *chan, chan->center_freq, KHZ_TO_MHZ(desired_bw_khz)); - REG_DBG_PRINT("%d KHz - %d KHz @ KHz), (%s mBi, %d mBm)\n", + REG_DBG_PRINT("%d KHz - %d KHz @ %d KHz), (%s mBi, %d mBm)\n", freq_range->start_freq_khz, freq_range->end_freq_khz, + freq_range->max_bandwidth_khz, max_antenna_gain, power_rule->max_eirp); } @@ -891,7 +890,7 @@ static bool ignore_reg_update(struct wiphy *wiphy, wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY) { REG_DBG_PRINT("Ignoring regulatory request %s " "since the driver uses its own custom " - "regulatory domain ", + "regulatory domain\n", reg_initiator_name(initiator)); return true; } @@ -905,7 +904,7 @@ static bool ignore_reg_update(struct wiphy *wiphy, !is_world_regdom(last_request->alpha2)) { REG_DBG_PRINT("Ignoring regulatory request %s " "since the driver requires its own regulatory " - "domain to be set first", + "domain to be set first\n", reg_initiator_name(initiator)); return true; } @@ -913,14 +912,6 @@ static bool ignore_reg_update(struct wiphy *wiphy, return false; } -static void update_all_wiphy_regulatory(enum nl80211_reg_initiator initiator) -{ - struct cfg80211_registered_device *rdev; - - list_for_each_entry(rdev, &cfg80211_rdev_list, list) - wiphy_update_regulatory(&rdev->wiphy, initiator); -} - static void handle_reg_beacon(struct wiphy *wiphy, unsigned int chan_idx, struct reg_beacon *reg_beacon) @@ -1120,11 +1111,13 @@ static void reg_process_ht_flags(struct wiphy *wiphy) } -void wiphy_update_regulatory(struct wiphy *wiphy, - enum nl80211_reg_initiator initiator) +static void wiphy_update_regulatory(struct wiphy *wiphy, + enum nl80211_reg_initiator initiator) { enum ieee80211_band band; + assert_reg_lock(); + if (ignore_reg_update(wiphy, initiator)) return; @@ -1139,6 +1132,22 @@ void wiphy_update_regulatory(struct wiphy *wiphy, wiphy->reg_notifier(wiphy, last_request); } +void regulatory_update(struct wiphy *wiphy, + enum nl80211_reg_initiator setby) +{ + mutex_lock(®_mutex); + wiphy_update_regulatory(wiphy, setby); + mutex_unlock(®_mutex); +} + +static void update_all_wiphy_regulatory(enum nl80211_reg_initiator initiator) +{ + struct cfg80211_registered_device *rdev; + + list_for_each_entry(rdev, &cfg80211_rdev_list, list) + wiphy_update_regulatory(&rdev->wiphy, initiator); +} + static void handle_channel_custom(struct wiphy *wiphy, enum ieee80211_band band, unsigned int chan_idx, @@ -1475,7 +1484,7 @@ static void reg_process_pending_hints(void) /* When last_request->processed becomes true this will be rescheduled */ if (last_request && !last_request->processed) { REG_DBG_PRINT("Pending regulatory request, waiting " - "for it to be processed..."); + "for it to be processed...\n"); goto out; } @@ -2188,7 +2197,7 @@ out: static void reg_timeout_work(struct work_struct *work) { REG_DBG_PRINT("Timeout while waiting for CRDA to reply, " - "restoring regulatory settings"); + "restoring regulatory settings\n"); restore_regulatory_settings(true); } diff --git a/net/wireless/reg.h b/net/wireless/reg.h index b67d1c3a2fb9..4a56799d868d 100644 --- a/net/wireless/reg.h +++ b/net/wireless/reg.h @@ -16,6 +16,8 @@ void regulatory_exit(void); int set_regdom(const struct ieee80211_regdomain *rd); +void regulatory_update(struct wiphy *wiphy, enum nl80211_reg_initiator setby); + /** * regulatory_hint_found_beacon - hints a beacon was found on a channel * @wiphy: the wireless device where the beacon was found on diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 2936cb809152..0fb142410404 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -12,6 +12,7 @@ #include <linux/etherdevice.h> #include <net/arp.h> #include <net/cfg80211.h> +#include <net/cfg80211-wext.h> #include <net/iw_handler.h> #include "core.h" #include "nl80211.h" @@ -227,6 +228,33 @@ const u8 *cfg80211_find_ie(u8 eid, const u8 *ies, int len) } EXPORT_SYMBOL(cfg80211_find_ie); +const u8 *cfg80211_find_vendor_ie(unsigned int oui, u8 oui_type, + const u8 *ies, int len) +{ + struct ieee80211_vendor_ie *ie; + const u8 *pos = ies, *end = ies + len; + int ie_oui; + + while (pos < end) { + pos = cfg80211_find_ie(WLAN_EID_VENDOR_SPECIFIC, pos, + end - pos); + if (!pos) + return NULL; + + if (end - pos < sizeof(*ie)) + return NULL; + + ie = (struct ieee80211_vendor_ie *)pos; + ie_oui = ie->oui[0] << 16 | ie->oui[1] << 8 | ie->oui[2]; + if (ie_oui == oui && ie->oui_type == oui_type) + return pos; + + pos += 2 + ie->len; + } + return NULL; +} +EXPORT_SYMBOL(cfg80211_find_vendor_ie); + static int cmp_ies(u8 num, u8 *ies1, size_t len1, u8 *ies2, size_t len2) { const u8 *ie1 = cfg80211_find_ie(num, ies1, len1); diff --git a/net/wireless/util.c b/net/wireless/util.c index be75a3a0424e..39dbf4ad7ca1 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -6,6 +6,7 @@ #include <linux/bitops.h> #include <linux/etherdevice.h> #include <linux/slab.h> +#include <linux/crc32.h> #include <net/cfg80211.h> #include <net/ip.h> #include "core.h" @@ -512,10 +513,9 @@ int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr, if (head_need) skb_orphan(skb); - if (pskb_expand_head(skb, head_need, 0, GFP_ATOMIC)) { - pr_err("failed to reallocate Tx buffer\n"); + if (pskb_expand_head(skb, head_need, 0, GFP_ATOMIC)) return -ENOMEM; - } + skb->truesize += head_need; } @@ -1044,3 +1044,170 @@ int ieee80211_get_ratemask(struct ieee80211_supported_band *sband, return 0; } + +u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, + struct ieee802_11_elems *elems, + u64 filter, u32 crc) +{ + size_t left = len; + u8 *pos = start; + bool calc_crc = filter != 0; + + memset(elems, 0, sizeof(*elems)); + elems->ie_start = start; + elems->total_len = len; + + while (left >= 2) { + u8 id, elen; + + id = *pos++; + elen = *pos++; + left -= 2; + + if (elen > left) + break; + + if (calc_crc && id < 64 && (filter & (1ULL << id))) + crc = crc32_be(crc, pos - 2, elen + 2); + + switch (id) { + case WLAN_EID_SSID: + elems->ssid = pos; + elems->ssid_len = elen; + break; + case WLAN_EID_SUPP_RATES: + elems->supp_rates = pos; + elems->supp_rates_len = elen; + break; + case WLAN_EID_FH_PARAMS: + elems->fh_params = pos; + elems->fh_params_len = elen; + break; + case WLAN_EID_DS_PARAMS: + elems->ds_params = pos; + elems->ds_params_len = elen; + break; + case WLAN_EID_CF_PARAMS: + elems->cf_params = pos; + elems->cf_params_len = elen; + break; + case WLAN_EID_TIM: + if (elen >= sizeof(struct ieee80211_tim_ie)) { + elems->tim = (void *)pos; + elems->tim_len = elen; + } + break; + case WLAN_EID_IBSS_PARAMS: + elems->ibss_params = pos; + elems->ibss_params_len = elen; + break; + case WLAN_EID_CHALLENGE: + elems->challenge = pos; + elems->challenge_len = elen; + break; + case WLAN_EID_VENDOR_SPECIFIC: + if (elen >= 4 && pos[0] == 0x00 && pos[1] == 0x50 && + pos[2] == 0xf2) { + /* Microsoft OUI (00:50:F2) */ + + if (calc_crc) + crc = crc32_be(crc, pos - 2, elen + 2); + + if (pos[3] == 1) { + /* OUI Type 1 - WPA IE */ + elems->wpa = pos; + elems->wpa_len = elen; + } else if (elen >= 5 && pos[3] == 2) { + /* OUI Type 2 - WMM IE */ + if (pos[4] == 0) { + elems->wmm_info = pos; + elems->wmm_info_len = elen; + } else if (pos[4] == 1) { + elems->wmm_param = pos; + elems->wmm_param_len = elen; + } + } + } + break; + case WLAN_EID_RSN: + elems->rsn = pos; + elems->rsn_len = elen; + break; + case WLAN_EID_ERP_INFO: + elems->erp_info = pos; + elems->erp_info_len = elen; + break; + case WLAN_EID_EXT_SUPP_RATES: + elems->ext_supp_rates = pos; + elems->ext_supp_rates_len = elen; + break; + case WLAN_EID_HT_CAPABILITY: + if (elen >= sizeof(struct ieee80211_ht_cap)) + elems->ht_cap_elem = (void *)pos; + break; + case WLAN_EID_HT_INFORMATION: + if (elen >= sizeof(struct ieee80211_ht_info)) + elems->ht_info_elem = (void *)pos; + break; + case WLAN_EID_MESH_ID: + elems->mesh_id = pos; + elems->mesh_id_len = elen; + break; + case WLAN_EID_MESH_CONFIG: + if (elen >= sizeof(struct ieee80211_meshconf_ie)) + elems->mesh_config = (void *)pos; + break; + case WLAN_EID_PEER_MGMT: + elems->peering = pos; + elems->peering_len = elen; + break; + case WLAN_EID_PREQ: + elems->preq = pos; + elems->preq_len = elen; + break; + case WLAN_EID_PREP: + elems->prep = pos; + elems->prep_len = elen; + break; + case WLAN_EID_PERR: + elems->perr = pos; + elems->perr_len = elen; + break; + case WLAN_EID_RANN: + if (elen >= sizeof(struct ieee80211_rann_ie)) + elems->rann = (void *)pos; + break; + case WLAN_EID_CHANNEL_SWITCH: + elems->ch_switch_elem = pos; + elems->ch_switch_elem_len = elen; + break; + case WLAN_EID_QUIET: + if (!elems->quiet_elem) { + elems->quiet_elem = pos; + elems->quiet_elem_len = elen; + } + elems->num_of_quiet_elem++; + break; + case WLAN_EID_COUNTRY: + elems->country_elem = pos; + elems->country_elem_len = elen; + break; + case WLAN_EID_PWR_CONSTRAINT: + elems->pwr_constr_elem = pos; + elems->pwr_constr_elem_len = elen; + break; + case WLAN_EID_TIMEOUT_INTERVAL: + elems->timeout_int = pos; + elems->timeout_int_len = elen; + break; + default: + break; + } + + left -= elen; + pos += elen; + } + + return crc; +} +EXPORT_SYMBOL(ieee802_11_parse_elems_crc); diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index 0bf169bb770e..62f121d1d9cb 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c @@ -15,6 +15,7 @@ #include <linux/slab.h> #include <net/iw_handler.h> #include <net/cfg80211.h> +#include <net/cfg80211-wext.h> #include "wext-compat.h" #include "core.h" @@ -363,9 +364,9 @@ int cfg80211_wext_giwfrag(struct net_device *dev, } EXPORT_SYMBOL_GPL(cfg80211_wext_giwfrag); -int cfg80211_wext_siwretry(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *retry, char *extra) +static int cfg80211_wext_siwretry(struct net_device *dev, + struct iw_request_info *info, + struct iw_param *retry, char *extra) { struct wireless_dev *wdev = dev->ieee80211_ptr; struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); @@ -402,7 +403,6 @@ int cfg80211_wext_siwretry(struct net_device *dev, return err; } -EXPORT_SYMBOL_GPL(cfg80211_wext_siwretry); int cfg80211_wext_giwretry(struct net_device *dev, struct iw_request_info *info, @@ -593,9 +593,9 @@ static int cfg80211_set_encryption(struct cfg80211_registered_device *rdev, return err; } -int cfg80211_wext_siwencode(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *erq, char *keybuf) +static int cfg80211_wext_siwencode(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *erq, char *keybuf) { struct wireless_dev *wdev = dev->ieee80211_ptr; struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); @@ -652,11 +652,10 @@ int cfg80211_wext_siwencode(struct net_device *dev, wdev->wext.default_key == -1, idx, ¶ms); } -EXPORT_SYMBOL_GPL(cfg80211_wext_siwencode); -int cfg80211_wext_siwencodeext(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *erq, char *extra) +static int cfg80211_wext_siwencodeext(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *erq, char *extra) { struct wireless_dev *wdev = dev->ieee80211_ptr; struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); @@ -744,11 +743,10 @@ int cfg80211_wext_siwencodeext(struct net_device *dev, ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY, idx, ¶ms); } -EXPORT_SYMBOL_GPL(cfg80211_wext_siwencodeext); -int cfg80211_wext_giwencode(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *erq, char *keybuf) +static int cfg80211_wext_giwencode(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *erq, char *keybuf) { struct wireless_dev *wdev = dev->ieee80211_ptr; int idx; @@ -782,11 +780,10 @@ int cfg80211_wext_giwencode(struct net_device *dev, return 0; } -EXPORT_SYMBOL_GPL(cfg80211_wext_giwencode); -int cfg80211_wext_siwfreq(struct net_device *dev, - struct iw_request_info *info, - struct iw_freq *wextfreq, char *extra) +static int cfg80211_wext_siwfreq(struct net_device *dev, + struct iw_request_info *info, + struct iw_freq *wextfreq, char *extra) { struct wireless_dev *wdev = dev->ieee80211_ptr; struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); @@ -815,11 +812,10 @@ int cfg80211_wext_siwfreq(struct net_device *dev, return -EOPNOTSUPP; } } -EXPORT_SYMBOL_GPL(cfg80211_wext_siwfreq); -int cfg80211_wext_giwfreq(struct net_device *dev, - struct iw_request_info *info, - struct iw_freq *freq, char *extra) +static int cfg80211_wext_giwfreq(struct net_device *dev, + struct iw_request_info *info, + struct iw_freq *freq, char *extra) { struct wireless_dev *wdev = dev->ieee80211_ptr; @@ -836,11 +832,10 @@ int cfg80211_wext_giwfreq(struct net_device *dev, return 0; } } -EXPORT_SYMBOL_GPL(cfg80211_wext_giwfreq); -int cfg80211_wext_siwtxpower(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *data, char *extra) +static int cfg80211_wext_siwtxpower(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *data, char *extra) { struct wireless_dev *wdev = dev->ieee80211_ptr; struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); @@ -889,11 +884,10 @@ int cfg80211_wext_siwtxpower(struct net_device *dev, return rdev->ops->set_tx_power(wdev->wiphy, type, DBM_TO_MBM(dbm)); } -EXPORT_SYMBOL_GPL(cfg80211_wext_siwtxpower); -int cfg80211_wext_giwtxpower(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *data, char *extra) +static int cfg80211_wext_giwtxpower(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *data, char *extra) { struct wireless_dev *wdev = dev->ieee80211_ptr; struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); @@ -919,7 +913,6 @@ int cfg80211_wext_giwtxpower(struct net_device *dev, return 0; } -EXPORT_SYMBOL_GPL(cfg80211_wext_giwtxpower); static int cfg80211_set_auth_alg(struct wireless_dev *wdev, s32 auth_alg) @@ -1070,9 +1063,9 @@ static int cfg80211_set_key_mgt(struct wireless_dev *wdev, u32 key_mgt) return 0; } -int cfg80211_wext_siwauth(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *data, char *extra) +static int cfg80211_wext_siwauth(struct net_device *dev, + struct iw_request_info *info, + struct iw_param *data, char *extra) { struct wireless_dev *wdev = dev->ieee80211_ptr; @@ -1102,21 +1095,19 @@ int cfg80211_wext_siwauth(struct net_device *dev, return -EOPNOTSUPP; } } -EXPORT_SYMBOL_GPL(cfg80211_wext_siwauth); -int cfg80211_wext_giwauth(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *data, char *extra) +static int cfg80211_wext_giwauth(struct net_device *dev, + struct iw_request_info *info, + struct iw_param *data, char *extra) { /* XXX: what do we need? */ return -EOPNOTSUPP; } -EXPORT_SYMBOL_GPL(cfg80211_wext_giwauth); -int cfg80211_wext_siwpower(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, char *extra) +static int cfg80211_wext_siwpower(struct net_device *dev, + struct iw_request_info *info, + struct iw_param *wrq, char *extra) { struct wireless_dev *wdev = dev->ieee80211_ptr; struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); @@ -1160,11 +1151,10 @@ int cfg80211_wext_siwpower(struct net_device *dev, return 0; } -EXPORT_SYMBOL_GPL(cfg80211_wext_siwpower); -int cfg80211_wext_giwpower(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, char *extra) +static int cfg80211_wext_giwpower(struct net_device *dev, + struct iw_request_info *info, + struct iw_param *wrq, char *extra) { struct wireless_dev *wdev = dev->ieee80211_ptr; @@ -1172,7 +1162,6 @@ int cfg80211_wext_giwpower(struct net_device *dev, return 0; } -EXPORT_SYMBOL_GPL(cfg80211_wext_giwpower); static int cfg80211_wds_wext_siwap(struct net_device *dev, struct iw_request_info *info, @@ -1218,9 +1207,9 @@ static int cfg80211_wds_wext_giwap(struct net_device *dev, return 0; } -int cfg80211_wext_siwrate(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *rate, char *extra) +static int cfg80211_wext_siwrate(struct net_device *dev, + struct iw_request_info *info, + struct iw_param *rate, char *extra) { struct wireless_dev *wdev = dev->ieee80211_ptr; struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); @@ -1268,11 +1257,10 @@ int cfg80211_wext_siwrate(struct net_device *dev, return rdev->ops->set_bitrate_mask(wdev->wiphy, dev, NULL, &mask); } -EXPORT_SYMBOL_GPL(cfg80211_wext_siwrate); -int cfg80211_wext_giwrate(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *rate, char *extra) +static int cfg80211_wext_giwrate(struct net_device *dev, + struct iw_request_info *info, + struct iw_param *rate, char *extra) { struct wireless_dev *wdev = dev->ieee80211_ptr; struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); @@ -1308,10 +1296,9 @@ int cfg80211_wext_giwrate(struct net_device *dev, return 0; } -EXPORT_SYMBOL_GPL(cfg80211_wext_giwrate); /* Get wireless statistics. Called by /proc/net/wireless and by SIOCGIWSTATS */ -struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev) +static struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev) { struct wireless_dev *wdev = dev->ieee80211_ptr; struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); @@ -1376,11 +1363,10 @@ struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev) return &wstats; } -EXPORT_SYMBOL_GPL(cfg80211_wireless_stats); -int cfg80211_wext_siwap(struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *ap_addr, char *extra) +static int cfg80211_wext_siwap(struct net_device *dev, + struct iw_request_info *info, + struct sockaddr *ap_addr, char *extra) { struct wireless_dev *wdev = dev->ieee80211_ptr; @@ -1395,11 +1381,10 @@ int cfg80211_wext_siwap(struct net_device *dev, return -EOPNOTSUPP; } } -EXPORT_SYMBOL_GPL(cfg80211_wext_siwap); -int cfg80211_wext_giwap(struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *ap_addr, char *extra) +static int cfg80211_wext_giwap(struct net_device *dev, + struct iw_request_info *info, + struct sockaddr *ap_addr, char *extra) { struct wireless_dev *wdev = dev->ieee80211_ptr; @@ -1414,11 +1399,10 @@ int cfg80211_wext_giwap(struct net_device *dev, return -EOPNOTSUPP; } } -EXPORT_SYMBOL_GPL(cfg80211_wext_giwap); -int cfg80211_wext_siwessid(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *ssid) +static int cfg80211_wext_siwessid(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *data, char *ssid) { struct wireless_dev *wdev = dev->ieee80211_ptr; @@ -1431,11 +1415,10 @@ int cfg80211_wext_siwessid(struct net_device *dev, return -EOPNOTSUPP; } } -EXPORT_SYMBOL_GPL(cfg80211_wext_siwessid); -int cfg80211_wext_giwessid(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *ssid) +static int cfg80211_wext_giwessid(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *data, char *ssid) { struct wireless_dev *wdev = dev->ieee80211_ptr; @@ -1451,11 +1434,10 @@ int cfg80211_wext_giwessid(struct net_device *dev, return -EOPNOTSUPP; } } -EXPORT_SYMBOL_GPL(cfg80211_wext_giwessid); -int cfg80211_wext_siwpmksa(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *extra) +static int cfg80211_wext_siwpmksa(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *data, char *extra) { struct wireless_dev *wdev = dev->ieee80211_ptr; struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); @@ -1493,7 +1475,6 @@ int cfg80211_wext_siwpmksa(struct net_device *dev, return -EOPNOTSUPP; } } -EXPORT_SYMBOL_GPL(cfg80211_wext_siwpmksa); static const iw_handler cfg80211_handlers[] = { [IW_IOCTL_IDX(SIOCGIWNAME)] = (iw_handler) cfg80211_wext_giwname, diff --git a/net/wireless/wext-compat.h b/net/wireless/wext-compat.h index 20b3daef6964..5d766b0118e8 100644 --- a/net/wireless/wext-compat.h +++ b/net/wireless/wext-compat.h @@ -42,6 +42,14 @@ int cfg80211_mgd_wext_giwessid(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *ssid); +int cfg80211_wext_siwmlme(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *data, char *extra); +int cfg80211_wext_siwgenie(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *data, char *extra); + + int cfg80211_wext_freq(struct wiphy *wiphy, struct iw_freq *freq); diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c index 6fffe62d7c25..0d4b8c3033ff 100644 --- a/net/wireless/wext-sme.c +++ b/net/wireless/wext-sme.c @@ -9,6 +9,7 @@ #include <linux/if_arp.h> #include <linux/slab.h> #include <net/cfg80211.h> +#include <net/cfg80211-wext.h> #include "wext-compat.h" #include "nl80211.h" @@ -365,7 +366,6 @@ int cfg80211_wext_siwgenie(struct net_device *dev, wdev_unlock(wdev); return err; } -EXPORT_SYMBOL_GPL(cfg80211_wext_siwgenie); int cfg80211_wext_siwmlme(struct net_device *dev, struct iw_request_info *info, @@ -402,4 +402,3 @@ int cfg80211_wext_siwmlme(struct net_device *dev, return err; } -EXPORT_SYMBOL_GPL(cfg80211_wext_siwmlme); |