Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Some IBSS support code for cfg80211.
0004  *
0005  * Copyright 2009   Johannes Berg <johannes@sipsolutions.net>
0006  * Copyright (C) 2020-2022 Intel Corporation
0007  */
0008 
0009 #include <linux/etherdevice.h>
0010 #include <linux/if_arp.h>
0011 #include <linux/slab.h>
0012 #include <linux/export.h>
0013 #include <net/cfg80211.h>
0014 #include "wext-compat.h"
0015 #include "nl80211.h"
0016 #include "rdev-ops.h"
0017 
0018 
0019 void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid,
0020                 struct ieee80211_channel *channel)
0021 {
0022     struct wireless_dev *wdev = dev->ieee80211_ptr;
0023     struct cfg80211_bss *bss;
0024 #ifdef CONFIG_CFG80211_WEXT
0025     union iwreq_data wrqu;
0026 #endif
0027 
0028     if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
0029         return;
0030 
0031     if (!wdev->u.ibss.ssid_len)
0032         return;
0033 
0034     bss = cfg80211_get_bss(wdev->wiphy, channel, bssid, NULL, 0,
0035                    IEEE80211_BSS_TYPE_IBSS, IEEE80211_PRIVACY_ANY);
0036 
0037     if (WARN_ON(!bss))
0038         return;
0039 
0040     if (wdev->u.ibss.current_bss) {
0041         cfg80211_unhold_bss(wdev->u.ibss.current_bss);
0042         cfg80211_put_bss(wdev->wiphy, &wdev->u.ibss.current_bss->pub);
0043     }
0044 
0045     cfg80211_hold_bss(bss_from_pub(bss));
0046     wdev->u.ibss.current_bss = bss_from_pub(bss);
0047 
0048     if (!(wdev->wiphy->flags & WIPHY_FLAG_HAS_STATIC_WEP))
0049         cfg80211_upload_connect_keys(wdev);
0050 
0051     nl80211_send_ibss_bssid(wiphy_to_rdev(wdev->wiphy), dev, bssid,
0052                 GFP_KERNEL);
0053 #ifdef CONFIG_CFG80211_WEXT
0054     memset(&wrqu, 0, sizeof(wrqu));
0055     memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN);
0056     wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
0057 #endif
0058 }
0059 
0060 void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid,
0061               struct ieee80211_channel *channel, gfp_t gfp)
0062 {
0063     struct wireless_dev *wdev = dev->ieee80211_ptr;
0064     struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
0065     struct cfg80211_event *ev;
0066     unsigned long flags;
0067 
0068     trace_cfg80211_ibss_joined(dev, bssid, channel);
0069 
0070     if (WARN_ON(!channel))
0071         return;
0072 
0073     ev = kzalloc(sizeof(*ev), gfp);
0074     if (!ev)
0075         return;
0076 
0077     ev->type = EVENT_IBSS_JOINED;
0078     memcpy(ev->ij.bssid, bssid, ETH_ALEN);
0079     ev->ij.channel = channel;
0080 
0081     spin_lock_irqsave(&wdev->event_lock, flags);
0082     list_add_tail(&ev->list, &wdev->event_list);
0083     spin_unlock_irqrestore(&wdev->event_lock, flags);
0084     queue_work(cfg80211_wq, &rdev->event_work);
0085 }
0086 EXPORT_SYMBOL(cfg80211_ibss_joined);
0087 
0088 int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
0089              struct net_device *dev,
0090              struct cfg80211_ibss_params *params,
0091              struct cfg80211_cached_keys *connkeys)
0092 {
0093     struct wireless_dev *wdev = dev->ieee80211_ptr;
0094     int err;
0095 
0096     lockdep_assert_held(&rdev->wiphy.mtx);
0097     ASSERT_WDEV_LOCK(wdev);
0098 
0099     if (wdev->u.ibss.ssid_len)
0100         return -EALREADY;
0101 
0102     if (!params->basic_rates) {
0103         /*
0104         * If no rates were explicitly configured,
0105         * use the mandatory rate set for 11b or
0106         * 11a for maximum compatibility.
0107         */
0108         struct ieee80211_supported_band *sband;
0109         enum nl80211_band band;
0110         u32 flag;
0111         int j;
0112 
0113         band = params->chandef.chan->band;
0114         if (band == NL80211_BAND_5GHZ ||
0115             band == NL80211_BAND_6GHZ)
0116             flag = IEEE80211_RATE_MANDATORY_A;
0117         else
0118             flag = IEEE80211_RATE_MANDATORY_B;
0119 
0120         sband = rdev->wiphy.bands[band];
0121         for (j = 0; j < sband->n_bitrates; j++) {
0122             if (sband->bitrates[j].flags & flag)
0123                 params->basic_rates |= BIT(j);
0124         }
0125     }
0126 
0127     if (WARN_ON(connkeys && connkeys->def < 0))
0128         return -EINVAL;
0129 
0130     if (WARN_ON(wdev->connect_keys))
0131         kfree_sensitive(wdev->connect_keys);
0132     wdev->connect_keys = connkeys;
0133 
0134     wdev->u.ibss.chandef = params->chandef;
0135     if (connkeys) {
0136         params->wep_keys = connkeys->params;
0137         params->wep_tx_key = connkeys->def;
0138     }
0139 
0140 #ifdef CONFIG_CFG80211_WEXT
0141     wdev->wext.ibss.chandef = params->chandef;
0142 #endif
0143     err = rdev_join_ibss(rdev, dev, params);
0144     if (err) {
0145         wdev->connect_keys = NULL;
0146         return err;
0147     }
0148 
0149     memcpy(wdev->u.ibss.ssid, params->ssid, params->ssid_len);
0150     wdev->u.ibss.ssid_len = params->ssid_len;
0151 
0152     return 0;
0153 }
0154 
0155 static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext)
0156 {
0157     struct wireless_dev *wdev = dev->ieee80211_ptr;
0158     struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
0159     int i;
0160 
0161     ASSERT_WDEV_LOCK(wdev);
0162 
0163     kfree_sensitive(wdev->connect_keys);
0164     wdev->connect_keys = NULL;
0165 
0166     rdev_set_qos_map(rdev, dev, NULL);
0167 
0168     /*
0169      * Delete all the keys ... pairwise keys can't really
0170      * exist any more anyway, but default keys might.
0171      */
0172     if (rdev->ops->del_key)
0173         for (i = 0; i < 6; i++)
0174             rdev_del_key(rdev, dev, i, false, NULL);
0175 
0176     if (wdev->u.ibss.current_bss) {
0177         cfg80211_unhold_bss(wdev->u.ibss.current_bss);
0178         cfg80211_put_bss(wdev->wiphy, &wdev->u.ibss.current_bss->pub);
0179     }
0180 
0181     wdev->u.ibss.current_bss = NULL;
0182     wdev->u.ibss.ssid_len = 0;
0183     memset(&wdev->u.ibss.chandef, 0, sizeof(wdev->u.ibss.chandef));
0184 #ifdef CONFIG_CFG80211_WEXT
0185     if (!nowext)
0186         wdev->wext.ibss.ssid_len = 0;
0187 #endif
0188     cfg80211_sched_dfs_chan_update(rdev);
0189 }
0190 
0191 void cfg80211_clear_ibss(struct net_device *dev, bool nowext)
0192 {
0193     struct wireless_dev *wdev = dev->ieee80211_ptr;
0194 
0195     wdev_lock(wdev);
0196     __cfg80211_clear_ibss(dev, nowext);
0197     wdev_unlock(wdev);
0198 }
0199 
0200 int __cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
0201               struct net_device *dev, bool nowext)
0202 {
0203     struct wireless_dev *wdev = dev->ieee80211_ptr;
0204     int err;
0205 
0206     ASSERT_WDEV_LOCK(wdev);
0207 
0208     if (!wdev->u.ibss.ssid_len)
0209         return -ENOLINK;
0210 
0211     err = rdev_leave_ibss(rdev, dev);
0212 
0213     if (err)
0214         return err;
0215 
0216     wdev->conn_owner_nlportid = 0;
0217     __cfg80211_clear_ibss(dev, nowext);
0218 
0219     return 0;
0220 }
0221 
0222 int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
0223             struct net_device *dev, bool nowext)
0224 {
0225     struct wireless_dev *wdev = dev->ieee80211_ptr;
0226     int err;
0227 
0228     wdev_lock(wdev);
0229     err = __cfg80211_leave_ibss(rdev, dev, nowext);
0230     wdev_unlock(wdev);
0231 
0232     return err;
0233 }
0234 
0235 #ifdef CONFIG_CFG80211_WEXT
0236 int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
0237                 struct wireless_dev *wdev)
0238 {
0239     struct cfg80211_cached_keys *ck = NULL;
0240     enum nl80211_band band;
0241     int i, err;
0242 
0243     ASSERT_WDEV_LOCK(wdev);
0244 
0245     if (!wdev->wext.ibss.beacon_interval)
0246         wdev->wext.ibss.beacon_interval = 100;
0247 
0248     /* try to find an IBSS channel if none requested ... */
0249     if (!wdev->wext.ibss.chandef.chan) {
0250         struct ieee80211_channel *new_chan = NULL;
0251 
0252         for (band = 0; band < NUM_NL80211_BANDS; band++) {
0253             struct ieee80211_supported_band *sband;
0254             struct ieee80211_channel *chan;
0255 
0256             sband = rdev->wiphy.bands[band];
0257             if (!sband)
0258                 continue;
0259 
0260             for (i = 0; i < sband->n_channels; i++) {
0261                 chan = &sband->channels[i];
0262                 if (chan->flags & IEEE80211_CHAN_NO_IR)
0263                     continue;
0264                 if (chan->flags & IEEE80211_CHAN_DISABLED)
0265                     continue;
0266                 new_chan = chan;
0267                 break;
0268             }
0269 
0270             if (new_chan)
0271                 break;
0272         }
0273 
0274         if (!new_chan)
0275             return -EINVAL;
0276 
0277         cfg80211_chandef_create(&wdev->wext.ibss.chandef, new_chan,
0278                     NL80211_CHAN_NO_HT);
0279     }
0280 
0281     /* don't join -- SSID is not there */
0282     if (!wdev->wext.ibss.ssid_len)
0283         return 0;
0284 
0285     if (!netif_running(wdev->netdev))
0286         return 0;
0287 
0288     if (wdev->wext.keys)
0289         wdev->wext.keys->def = wdev->wext.default_key;
0290 
0291     wdev->wext.ibss.privacy = wdev->wext.default_key != -1;
0292 
0293     if (wdev->wext.keys && wdev->wext.keys->def != -1) {
0294         ck = kmemdup(wdev->wext.keys, sizeof(*ck), GFP_KERNEL);
0295         if (!ck)
0296             return -ENOMEM;
0297         for (i = 0; i < CFG80211_MAX_WEP_KEYS; i++)
0298             ck->params[i].key = ck->data[i];
0299     }
0300     err = __cfg80211_join_ibss(rdev, wdev->netdev,
0301                    &wdev->wext.ibss, ck);
0302     if (err)
0303         kfree(ck);
0304 
0305     return err;
0306 }
0307 
0308 int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
0309                    struct iw_request_info *info,
0310                    struct iw_freq *wextfreq, char *extra)
0311 {
0312     struct wireless_dev *wdev = dev->ieee80211_ptr;
0313     struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
0314     struct ieee80211_channel *chan = NULL;
0315     int err, freq;
0316 
0317     /* call only for ibss! */
0318     if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
0319         return -EINVAL;
0320 
0321     if (!rdev->ops->join_ibss)
0322         return -EOPNOTSUPP;
0323 
0324     freq = cfg80211_wext_freq(wextfreq);
0325     if (freq < 0)
0326         return freq;
0327 
0328     if (freq) {
0329         chan = ieee80211_get_channel(wdev->wiphy, freq);
0330         if (!chan)
0331             return -EINVAL;
0332         if (chan->flags & IEEE80211_CHAN_NO_IR ||
0333             chan->flags & IEEE80211_CHAN_DISABLED)
0334             return -EINVAL;
0335     }
0336 
0337     if (wdev->wext.ibss.chandef.chan == chan)
0338         return 0;
0339 
0340     wdev_lock(wdev);
0341     err = 0;
0342     if (wdev->u.ibss.ssid_len)
0343         err = __cfg80211_leave_ibss(rdev, dev, true);
0344     wdev_unlock(wdev);
0345 
0346     if (err)
0347         return err;
0348 
0349     if (chan) {
0350         cfg80211_chandef_create(&wdev->wext.ibss.chandef, chan,
0351                     NL80211_CHAN_NO_HT);
0352         wdev->wext.ibss.channel_fixed = true;
0353     } else {
0354         /* cfg80211_ibss_wext_join will pick one if needed */
0355         wdev->wext.ibss.channel_fixed = false;
0356     }
0357 
0358     wdev_lock(wdev);
0359     err = cfg80211_ibss_wext_join(rdev, wdev);
0360     wdev_unlock(wdev);
0361 
0362     return err;
0363 }
0364 
0365 int cfg80211_ibss_wext_giwfreq(struct net_device *dev,
0366                    struct iw_request_info *info,
0367                    struct iw_freq *freq, char *extra)
0368 {
0369     struct wireless_dev *wdev = dev->ieee80211_ptr;
0370     struct ieee80211_channel *chan = NULL;
0371 
0372     /* call only for ibss! */
0373     if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
0374         return -EINVAL;
0375 
0376     wdev_lock(wdev);
0377     if (wdev->u.ibss.current_bss)
0378         chan = wdev->u.ibss.current_bss->pub.channel;
0379     else if (wdev->wext.ibss.chandef.chan)
0380         chan = wdev->wext.ibss.chandef.chan;
0381     wdev_unlock(wdev);
0382 
0383     if (chan) {
0384         freq->m = chan->center_freq;
0385         freq->e = 6;
0386         return 0;
0387     }
0388 
0389     /* no channel if not joining */
0390     return -EINVAL;
0391 }
0392 
0393 int cfg80211_ibss_wext_siwessid(struct net_device *dev,
0394                 struct iw_request_info *info,
0395                 struct iw_point *data, char *ssid)
0396 {
0397     struct wireless_dev *wdev = dev->ieee80211_ptr;
0398     struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
0399     size_t len = data->length;
0400     int err;
0401 
0402     /* call only for ibss! */
0403     if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
0404         return -EINVAL;
0405 
0406     if (!rdev->ops->join_ibss)
0407         return -EOPNOTSUPP;
0408 
0409     wdev_lock(wdev);
0410     err = 0;
0411     if (wdev->u.ibss.ssid_len)
0412         err = __cfg80211_leave_ibss(rdev, dev, true);
0413     wdev_unlock(wdev);
0414 
0415     if (err)
0416         return err;
0417 
0418     /* iwconfig uses nul termination in SSID.. */
0419     if (len > 0 && ssid[len - 1] == '\0')
0420         len--;
0421 
0422     memcpy(wdev->u.ibss.ssid, ssid, len);
0423     wdev->wext.ibss.ssid = wdev->u.ibss.ssid;
0424     wdev->wext.ibss.ssid_len = len;
0425 
0426     wdev_lock(wdev);
0427     err = cfg80211_ibss_wext_join(rdev, wdev);
0428     wdev_unlock(wdev);
0429 
0430     return err;
0431 }
0432 
0433 int cfg80211_ibss_wext_giwessid(struct net_device *dev,
0434                 struct iw_request_info *info,
0435                 struct iw_point *data, char *ssid)
0436 {
0437     struct wireless_dev *wdev = dev->ieee80211_ptr;
0438 
0439     /* call only for ibss! */
0440     if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
0441         return -EINVAL;
0442 
0443     data->flags = 0;
0444 
0445     wdev_lock(wdev);
0446     if (wdev->u.ibss.ssid_len) {
0447         data->flags = 1;
0448         data->length = wdev->u.ibss.ssid_len;
0449         memcpy(ssid, wdev->u.ibss.ssid, data->length);
0450     } else if (wdev->wext.ibss.ssid && wdev->wext.ibss.ssid_len) {
0451         data->flags = 1;
0452         data->length = wdev->wext.ibss.ssid_len;
0453         memcpy(ssid, wdev->wext.ibss.ssid, data->length);
0454     }
0455     wdev_unlock(wdev);
0456 
0457     return 0;
0458 }
0459 
0460 int cfg80211_ibss_wext_siwap(struct net_device *dev,
0461                  struct iw_request_info *info,
0462                  struct sockaddr *ap_addr, char *extra)
0463 {
0464     struct wireless_dev *wdev = dev->ieee80211_ptr;
0465     struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
0466     u8 *bssid = ap_addr->sa_data;
0467     int err;
0468 
0469     /* call only for ibss! */
0470     if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
0471         return -EINVAL;
0472 
0473     if (!rdev->ops->join_ibss)
0474         return -EOPNOTSUPP;
0475 
0476     if (ap_addr->sa_family != ARPHRD_ETHER)
0477         return -EINVAL;
0478 
0479     /* automatic mode */
0480     if (is_zero_ether_addr(bssid) || is_broadcast_ether_addr(bssid))
0481         bssid = NULL;
0482 
0483     if (bssid && !is_valid_ether_addr(bssid))
0484         return -EINVAL;
0485 
0486     /* both automatic */
0487     if (!bssid && !wdev->wext.ibss.bssid)
0488         return 0;
0489 
0490     /* fixed already - and no change */
0491     if (wdev->wext.ibss.bssid && bssid &&
0492         ether_addr_equal(bssid, wdev->wext.ibss.bssid))
0493         return 0;
0494 
0495     wdev_lock(wdev);
0496     err = 0;
0497     if (wdev->u.ibss.ssid_len)
0498         err = __cfg80211_leave_ibss(rdev, dev, true);
0499     wdev_unlock(wdev);
0500 
0501     if (err)
0502         return err;
0503 
0504     if (bssid) {
0505         memcpy(wdev->wext.bssid, bssid, ETH_ALEN);
0506         wdev->wext.ibss.bssid = wdev->wext.bssid;
0507     } else
0508         wdev->wext.ibss.bssid = NULL;
0509 
0510     wdev_lock(wdev);
0511     err = cfg80211_ibss_wext_join(rdev, wdev);
0512     wdev_unlock(wdev);
0513 
0514     return err;
0515 }
0516 
0517 int cfg80211_ibss_wext_giwap(struct net_device *dev,
0518                  struct iw_request_info *info,
0519                  struct sockaddr *ap_addr, char *extra)
0520 {
0521     struct wireless_dev *wdev = dev->ieee80211_ptr;
0522 
0523     /* call only for ibss! */
0524     if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
0525         return -EINVAL;
0526 
0527     ap_addr->sa_family = ARPHRD_ETHER;
0528 
0529     wdev_lock(wdev);
0530     if (wdev->u.ibss.current_bss)
0531         memcpy(ap_addr->sa_data, wdev->u.ibss.current_bss->pub.bssid,
0532                ETH_ALEN);
0533     else if (wdev->wext.ibss.bssid)
0534         memcpy(ap_addr->sa_data, wdev->wext.ibss.bssid, ETH_ALEN);
0535     else
0536         eth_zero_addr(ap_addr->sa_data);
0537 
0538     wdev_unlock(wdev);
0539 
0540     return 0;
0541 }
0542 #endif