1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Some IBSS support code for cfg80211. 4 * 5 * Copyright 2009 Johannes Berg <johannes@sipsolutions.net> 6 * Copyright (C) 2020-2024 Intel Corporation 7 */ 8 9 #include <linux/etherdevice.h> 10 #include <linux/if_arp.h> 11 #include <linux/slab.h> 12 #include <linux/export.h> 13 #include <net/cfg80211.h> 14 #include "wext-compat.h" 15 #include "nl80211.h" 16 #include "rdev-ops.h" 17 18 19 void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, 20 struct ieee80211_channel *channel) 21 { 22 struct wireless_dev *wdev = dev->ieee80211_ptr; 23 struct cfg80211_bss *bss; 24 #ifdef CONFIG_CFG80211_WEXT 25 union iwreq_data wrqu; 26 #endif 27 28 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC)) 29 return; 30 31 if (!wdev->u.ibss.ssid_len) 32 return; 33 34 bss = cfg80211_get_bss(wdev->wiphy, channel, bssid, NULL, 0, 35 IEEE80211_BSS_TYPE_IBSS, IEEE80211_PRIVACY_ANY); 36 37 if (WARN_ON(!bss)) 38 return; 39 40 if (wdev->u.ibss.current_bss) { 41 cfg80211_unhold_bss(wdev->u.ibss.current_bss); 42 cfg80211_put_bss(wdev->wiphy, &wdev->u.ibss.current_bss->pub); 43 } 44 45 cfg80211_hold_bss(bss_from_pub(bss)); 46 wdev->u.ibss.current_bss = bss_from_pub(bss); 47 48 cfg80211_upload_connect_keys(wdev); 49 50 nl80211_send_ibss_bssid(wiphy_to_rdev(wdev->wiphy), dev, bssid, 51 GFP_KERNEL); 52 #ifdef CONFIG_CFG80211_WEXT 53 memset(&wrqu, 0, sizeof(wrqu)); 54 memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN); 55 wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL); 56 #endif 57 } 58 59 void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, 60 struct ieee80211_channel *channel, gfp_t gfp) 61 { 62 struct wireless_dev *wdev = dev->ieee80211_ptr; 63 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); 64 struct cfg80211_event *ev; 65 unsigned long flags; 66 67 trace_cfg80211_ibss_joined(dev, bssid, channel); 68 69 if (WARN_ON(!channel)) 70 return; 71 72 ev = kzalloc(sizeof(*ev), gfp); 73 if (!ev) 74 return; 75 76 ev->type = EVENT_IBSS_JOINED; 77 memcpy(ev->ij.bssid, bssid, ETH_ALEN); 78 ev->ij.channel = channel; 79 80 spin_lock_irqsave(&wdev->event_lock, flags); 81 list_add_tail(&ev->list, &wdev->event_list); 82 spin_unlock_irqrestore(&wdev->event_lock, flags); 83 queue_work(cfg80211_wq, &rdev->event_work); 84 } 85 EXPORT_SYMBOL(cfg80211_ibss_joined); 86 87 int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev, 88 struct net_device *dev, 89 struct cfg80211_ibss_params *params, 90 struct cfg80211_cached_keys *connkeys) 91 { 92 struct wireless_dev *wdev = dev->ieee80211_ptr; 93 int err; 94 95 lockdep_assert_held(&rdev->wiphy.mtx); 96 97 if (wdev->cac_started) 98 return -EBUSY; 99 100 if (wdev->u.ibss.ssid_len) 101 return -EALREADY; 102 103 if (!params->basic_rates) { 104 /* 105 * If no rates were explicitly configured, 106 * use the mandatory rate set for 11b or 107 * 11a for maximum compatibility. 108 */ 109 struct ieee80211_supported_band *sband; 110 enum nl80211_band band; 111 u32 flag; 112 int j; 113 114 band = params->chandef.chan->band; 115 if (band == NL80211_BAND_5GHZ || 116 band == NL80211_BAND_6GHZ) 117 flag = IEEE80211_RATE_MANDATORY_A; 118 else 119 flag = IEEE80211_RATE_MANDATORY_B; 120 121 sband = rdev->wiphy.bands[band]; 122 for (j = 0; j < sband->n_bitrates; j++) { 123 if (sband->bitrates[j].flags & flag) 124 params->basic_rates |= BIT(j); 125 } 126 } 127 128 if (WARN_ON(connkeys && connkeys->def < 0)) 129 return -EINVAL; 130 131 if (WARN_ON(wdev->connect_keys)) 132 kfree_sensitive(wdev->connect_keys); 133 wdev->connect_keys = connkeys; 134 135 wdev->u.ibss.chandef = params->chandef; 136 if (connkeys) { 137 params->wep_keys = connkeys->params; 138 params->wep_tx_key = connkeys->def; 139 } 140 141 #ifdef CONFIG_CFG80211_WEXT 142 wdev->wext.ibss.chandef = params->chandef; 143 #endif 144 err = rdev_join_ibss(rdev, dev, params); 145 if (err) { 146 wdev->connect_keys = NULL; 147 return err; 148 } 149 150 memcpy(wdev->u.ibss.ssid, params->ssid, params->ssid_len); 151 wdev->u.ibss.ssid_len = params->ssid_len; 152 153 return 0; 154 } 155 156 void cfg80211_clear_ibss(struct net_device *dev, bool nowext) 157 { 158 struct wireless_dev *wdev = dev->ieee80211_ptr; 159 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); 160 int i; 161 162 lockdep_assert_wiphy(wdev->wiphy); 163 164 kfree_sensitive(wdev->connect_keys); 165 wdev->connect_keys = NULL; 166 167 rdev_set_qos_map(rdev, dev, NULL); 168 169 /* 170 * Delete all the keys ... pairwise keys can't really 171 * exist any more anyway, but default keys might. 172 */ 173 if (rdev->ops->del_key) 174 for (i = 0; i < 6; i++) 175 rdev_del_key(rdev, dev, -1, i, false, NULL); 176 177 if (wdev->u.ibss.current_bss) { 178 cfg80211_unhold_bss(wdev->u.ibss.current_bss); 179 cfg80211_put_bss(wdev->wiphy, &wdev->u.ibss.current_bss->pub); 180 } 181 182 wdev->u.ibss.current_bss = NULL; 183 wdev->u.ibss.ssid_len = 0; 184 memset(&wdev->u.ibss.chandef, 0, sizeof(wdev->u.ibss.chandef)); 185 #ifdef CONFIG_CFG80211_WEXT 186 if (!nowext) 187 wdev->wext.ibss.ssid_len = 0; 188 #endif 189 cfg80211_sched_dfs_chan_update(rdev); 190 } 191 192 int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev, 193 struct net_device *dev, bool nowext) 194 { 195 struct wireless_dev *wdev = dev->ieee80211_ptr; 196 int err; 197 198 lockdep_assert_wiphy(wdev->wiphy); 199 200 if (!wdev->u.ibss.ssid_len) 201 return -ENOLINK; 202 203 err = rdev_leave_ibss(rdev, dev); 204 205 if (err) 206 return err; 207 208 wdev->conn_owner_nlportid = 0; 209 cfg80211_clear_ibss(dev, nowext); 210 211 return 0; 212 } 213 214 #ifdef CONFIG_CFG80211_WEXT 215 int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev, 216 struct wireless_dev *wdev) 217 { 218 struct cfg80211_cached_keys *ck = NULL; 219 enum nl80211_band band; 220 int i, err; 221 222 lockdep_assert_wiphy(wdev->wiphy); 223 224 if (!wdev->wext.ibss.beacon_interval) 225 wdev->wext.ibss.beacon_interval = 100; 226 227 /* try to find an IBSS channel if none requested ... */ 228 if (!wdev->wext.ibss.chandef.chan) { 229 struct ieee80211_channel *new_chan = NULL; 230 231 for (band = 0; band < NUM_NL80211_BANDS; band++) { 232 struct ieee80211_supported_band *sband; 233 struct ieee80211_channel *chan; 234 235 sband = rdev->wiphy.bands[band]; 236 if (!sband) 237 continue; 238 239 for (i = 0; i < sband->n_channels; i++) { 240 chan = &sband->channels[i]; 241 if (chan->flags & IEEE80211_CHAN_NO_IR) 242 continue; 243 if (chan->flags & IEEE80211_CHAN_DISABLED) 244 continue; 245 new_chan = chan; 246 break; 247 } 248 249 if (new_chan) 250 break; 251 } 252 253 if (!new_chan) 254 return -EINVAL; 255 256 cfg80211_chandef_create(&wdev->wext.ibss.chandef, new_chan, 257 NL80211_CHAN_NO_HT); 258 } 259 260 /* don't join -- SSID is not there */ 261 if (!wdev->wext.ibss.ssid_len) 262 return 0; 263 264 if (!netif_running(wdev->netdev)) 265 return 0; 266 267 if (wdev->wext.keys) 268 wdev->wext.keys->def = wdev->wext.default_key; 269 270 wdev->wext.ibss.privacy = wdev->wext.default_key != -1; 271 272 if (wdev->wext.keys && wdev->wext.keys->def != -1) { 273 ck = kmemdup(wdev->wext.keys, sizeof(*ck), GFP_KERNEL); 274 if (!ck) 275 return -ENOMEM; 276 for (i = 0; i < 4; i++) 277 ck->params[i].key = ck->data[i]; 278 } 279 err = __cfg80211_join_ibss(rdev, wdev->netdev, 280 &wdev->wext.ibss, ck); 281 if (err) 282 kfree(ck); 283 284 return err; 285 } 286 287 int cfg80211_ibss_wext_siwfreq(struct net_device *dev, 288 struct iw_request_info *info, 289 struct iw_freq *wextfreq, char *extra) 290 { 291 struct wireless_dev *wdev = dev->ieee80211_ptr; 292 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); 293 struct ieee80211_channel *chan = NULL; 294 int err, freq; 295 296 /* call only for ibss! */ 297 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC)) 298 return -EINVAL; 299 300 if (!rdev->ops->join_ibss) 301 return -EOPNOTSUPP; 302 303 freq = cfg80211_wext_freq(wextfreq); 304 if (freq < 0) 305 return freq; 306 307 if (freq) { 308 chan = ieee80211_get_channel(wdev->wiphy, freq); 309 if (!chan) 310 return -EINVAL; 311 if (chan->flags & IEEE80211_CHAN_NO_IR || 312 chan->flags & IEEE80211_CHAN_DISABLED) 313 return -EINVAL; 314 } 315 316 if (wdev->wext.ibss.chandef.chan == chan) 317 return 0; 318 319 err = 0; 320 if (wdev->u.ibss.ssid_len) 321 err = cfg80211_leave_ibss(rdev, dev, true); 322 323 if (err) 324 return err; 325 326 if (chan) { 327 cfg80211_chandef_create(&wdev->wext.ibss.chandef, chan, 328 NL80211_CHAN_NO_HT); 329 wdev->wext.ibss.channel_fixed = true; 330 } else { 331 /* cfg80211_ibss_wext_join will pick one if needed */ 332 wdev->wext.ibss.channel_fixed = false; 333 } 334 335 return cfg80211_ibss_wext_join(rdev, wdev); 336 } 337 338 int cfg80211_ibss_wext_giwfreq(struct net_device *dev, 339 struct iw_request_info *info, 340 struct iw_freq *freq, char *extra) 341 { 342 struct wireless_dev *wdev = dev->ieee80211_ptr; 343 struct ieee80211_channel *chan = NULL; 344 345 /* call only for ibss! */ 346 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC)) 347 return -EINVAL; 348 349 if (wdev->u.ibss.current_bss) 350 chan = wdev->u.ibss.current_bss->pub.channel; 351 else if (wdev->wext.ibss.chandef.chan) 352 chan = wdev->wext.ibss.chandef.chan; 353 354 if (chan) { 355 freq->m = chan->center_freq; 356 freq->e = 6; 357 return 0; 358 } 359 360 /* no channel if not joining */ 361 return -EINVAL; 362 } 363 364 int cfg80211_ibss_wext_siwessid(struct net_device *dev, 365 struct iw_request_info *info, 366 struct iw_point *data, char *ssid) 367 { 368 struct wireless_dev *wdev = dev->ieee80211_ptr; 369 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); 370 size_t len = data->length; 371 int err; 372 373 /* call only for ibss! */ 374 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC)) 375 return -EINVAL; 376 377 if (!rdev->ops->join_ibss) 378 return -EOPNOTSUPP; 379 380 err = 0; 381 if (wdev->u.ibss.ssid_len) 382 err = cfg80211_leave_ibss(rdev, dev, true); 383 384 if (err) 385 return err; 386 387 /* iwconfig uses nul termination in SSID.. */ 388 if (len > 0 && ssid[len - 1] == '\0') 389 len--; 390 391 memcpy(wdev->u.ibss.ssid, ssid, len); 392 wdev->wext.ibss.ssid = wdev->u.ibss.ssid; 393 wdev->wext.ibss.ssid_len = len; 394 395 return cfg80211_ibss_wext_join(rdev, wdev); 396 } 397 398 int cfg80211_ibss_wext_giwessid(struct net_device *dev, 399 struct iw_request_info *info, 400 struct iw_point *data, char *ssid) 401 { 402 struct wireless_dev *wdev = dev->ieee80211_ptr; 403 404 /* call only for ibss! */ 405 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC)) 406 return -EINVAL; 407 408 data->flags = 0; 409 410 if (wdev->u.ibss.ssid_len) { 411 data->flags = 1; 412 data->length = wdev->u.ibss.ssid_len; 413 memcpy(ssid, wdev->u.ibss.ssid, data->length); 414 } else if (wdev->wext.ibss.ssid && wdev->wext.ibss.ssid_len) { 415 data->flags = 1; 416 data->length = wdev->wext.ibss.ssid_len; 417 memcpy(ssid, wdev->wext.ibss.ssid, data->length); 418 } 419 420 return 0; 421 } 422 423 int cfg80211_ibss_wext_siwap(struct net_device *dev, 424 struct iw_request_info *info, 425 struct sockaddr *ap_addr, char *extra) 426 { 427 struct wireless_dev *wdev = dev->ieee80211_ptr; 428 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); 429 u8 *bssid = ap_addr->sa_data; 430 int err; 431 432 /* call only for ibss! */ 433 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC)) 434 return -EINVAL; 435 436 if (!rdev->ops->join_ibss) 437 return -EOPNOTSUPP; 438 439 if (ap_addr->sa_family != ARPHRD_ETHER) 440 return -EINVAL; 441 442 /* automatic mode */ 443 if (is_zero_ether_addr(bssid) || is_broadcast_ether_addr(bssid)) 444 bssid = NULL; 445 446 if (bssid && !is_valid_ether_addr(bssid)) 447 return -EINVAL; 448 449 /* both automatic */ 450 if (!bssid && !wdev->wext.ibss.bssid) 451 return 0; 452 453 /* fixed already - and no change */ 454 if (wdev->wext.ibss.bssid && bssid && 455 ether_addr_equal(bssid, wdev->wext.ibss.bssid)) 456 return 0; 457 458 err = 0; 459 if (wdev->u.ibss.ssid_len) 460 err = cfg80211_leave_ibss(rdev, dev, true); 461 462 if (err) 463 return err; 464 465 if (bssid) { 466 memcpy(wdev->wext.bssid, bssid, ETH_ALEN); 467 wdev->wext.ibss.bssid = wdev->wext.bssid; 468 } else 469 wdev->wext.ibss.bssid = NULL; 470 471 return cfg80211_ibss_wext_join(rdev, wdev); 472 } 473 474 int cfg80211_ibss_wext_giwap(struct net_device *dev, 475 struct iw_request_info *info, 476 struct sockaddr *ap_addr, char *extra) 477 { 478 struct wireless_dev *wdev = dev->ieee80211_ptr; 479 480 /* call only for ibss! */ 481 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC)) 482 return -EINVAL; 483 484 ap_addr->sa_family = ARPHRD_ETHER; 485 486 if (wdev->u.ibss.current_bss) 487 memcpy(ap_addr->sa_data, wdev->u.ibss.current_bss->pub.bssid, 488 ETH_ALEN); 489 else if (wdev->wext.ibss.bssid) 490 memcpy(ap_addr->sa_data, wdev->wext.ibss.bssid, ETH_ALEN); 491 else 492 eth_zero_addr(ap_addr->sa_data); 493 494 return 0; 495 } 496 #endif 497
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.