xref: /linux/net/wireless/ibss.c (revision 076fc877)
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-2023 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 
__cfg80211_ibss_joined(struct net_device * dev,const u8 * bssid,struct ieee80211_channel * channel)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 
cfg80211_ibss_joined(struct net_device * dev,const u8 * bssid,struct ieee80211_channel * channel,gfp_t gfp)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 
__cfg80211_join_ibss(struct cfg80211_registered_device * rdev,struct net_device * dev,struct cfg80211_ibss_params * params,struct cfg80211_cached_keys * connkeys)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->u.ibss.ssid_len)
98 		return -EALREADY;
99 
100 	if (!params->basic_rates) {
101 		/*
102 		* If no rates were explicitly configured,
103 		* use the mandatory rate set for 11b or
104 		* 11a for maximum compatibility.
105 		*/
106 		struct ieee80211_supported_band *sband;
107 		enum nl80211_band band;
108 		u32 flag;
109 		int j;
110 
111 		band = params->chandef.chan->band;
112 		if (band == NL80211_BAND_5GHZ ||
113 		    band == NL80211_BAND_6GHZ)
114 			flag = IEEE80211_RATE_MANDATORY_A;
115 		else
116 			flag = IEEE80211_RATE_MANDATORY_B;
117 
118 		sband = rdev->wiphy.bands[band];
119 		for (j = 0; j < sband->n_bitrates; j++) {
120 			if (sband->bitrates[j].flags & flag)
121 				params->basic_rates |= BIT(j);
122 		}
123 	}
124 
125 	if (WARN_ON(connkeys && connkeys->def < 0))
126 		return -EINVAL;
127 
128 	if (WARN_ON(wdev->connect_keys))
129 		kfree_sensitive(wdev->connect_keys);
130 	wdev->connect_keys = connkeys;
131 
132 	wdev->u.ibss.chandef = params->chandef;
133 	if (connkeys) {
134 		params->wep_keys = connkeys->params;
135 		params->wep_tx_key = connkeys->def;
136 	}
137 
138 #ifdef CONFIG_CFG80211_WEXT
139 	wdev->wext.ibss.chandef = params->chandef;
140 #endif
141 	err = rdev_join_ibss(rdev, dev, params);
142 	if (err) {
143 		wdev->connect_keys = NULL;
144 		return err;
145 	}
146 
147 	memcpy(wdev->u.ibss.ssid, params->ssid, params->ssid_len);
148 	wdev->u.ibss.ssid_len = params->ssid_len;
149 
150 	return 0;
151 }
152 
cfg80211_clear_ibss(struct net_device * dev,bool nowext)153 void cfg80211_clear_ibss(struct net_device *dev, bool nowext)
154 {
155 	struct wireless_dev *wdev = dev->ieee80211_ptr;
156 	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
157 	int i;
158 
159 	lockdep_assert_wiphy(wdev->wiphy);
160 
161 	kfree_sensitive(wdev->connect_keys);
162 	wdev->connect_keys = NULL;
163 
164 	rdev_set_qos_map(rdev, dev, NULL);
165 
166 	/*
167 	 * Delete all the keys ... pairwise keys can't really
168 	 * exist any more anyway, but default keys might.
169 	 */
170 	if (rdev->ops->del_key)
171 		for (i = 0; i < 6; i++)
172 			rdev_del_key(rdev, dev, -1, i, false, NULL);
173 
174 	if (wdev->u.ibss.current_bss) {
175 		cfg80211_unhold_bss(wdev->u.ibss.current_bss);
176 		cfg80211_put_bss(wdev->wiphy, &wdev->u.ibss.current_bss->pub);
177 	}
178 
179 	wdev->u.ibss.current_bss = NULL;
180 	wdev->u.ibss.ssid_len = 0;
181 	memset(&wdev->u.ibss.chandef, 0, sizeof(wdev->u.ibss.chandef));
182 #ifdef CONFIG_CFG80211_WEXT
183 	if (!nowext)
184 		wdev->wext.ibss.ssid_len = 0;
185 #endif
186 	cfg80211_sched_dfs_chan_update(rdev);
187 }
188 
cfg80211_leave_ibss(struct cfg80211_registered_device * rdev,struct net_device * dev,bool nowext)189 int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
190 			struct net_device *dev, bool nowext)
191 {
192 	struct wireless_dev *wdev = dev->ieee80211_ptr;
193 	int err;
194 
195 	lockdep_assert_wiphy(wdev->wiphy);
196 
197 	if (!wdev->u.ibss.ssid_len)
198 		return -ENOLINK;
199 
200 	err = rdev_leave_ibss(rdev, dev);
201 
202 	if (err)
203 		return err;
204 
205 	wdev->conn_owner_nlportid = 0;
206 	cfg80211_clear_ibss(dev, nowext);
207 
208 	return 0;
209 }
210 
211 #ifdef CONFIG_CFG80211_WEXT
cfg80211_ibss_wext_join(struct cfg80211_registered_device * rdev,struct wireless_dev * wdev)212 int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
213 			    struct wireless_dev *wdev)
214 {
215 	struct cfg80211_cached_keys *ck = NULL;
216 	enum nl80211_band band;
217 	int i, err;
218 
219 	lockdep_assert_wiphy(wdev->wiphy);
220 
221 	if (!wdev->wext.ibss.beacon_interval)
222 		wdev->wext.ibss.beacon_interval = 100;
223 
224 	/* try to find an IBSS channel if none requested ... */
225 	if (!wdev->wext.ibss.chandef.chan) {
226 		struct ieee80211_channel *new_chan = NULL;
227 
228 		for (band = 0; band < NUM_NL80211_BANDS; band++) {
229 			struct ieee80211_supported_band *sband;
230 			struct ieee80211_channel *chan;
231 
232 			sband = rdev->wiphy.bands[band];
233 			if (!sband)
234 				continue;
235 
236 			for (i = 0; i < sband->n_channels; i++) {
237 				chan = &sband->channels[i];
238 				if (chan->flags & IEEE80211_CHAN_NO_IR)
239 					continue;
240 				if (chan->flags & IEEE80211_CHAN_DISABLED)
241 					continue;
242 				new_chan = chan;
243 				break;
244 			}
245 
246 			if (new_chan)
247 				break;
248 		}
249 
250 		if (!new_chan)
251 			return -EINVAL;
252 
253 		cfg80211_chandef_create(&wdev->wext.ibss.chandef, new_chan,
254 					NL80211_CHAN_NO_HT);
255 	}
256 
257 	/* don't join -- SSID is not there */
258 	if (!wdev->wext.ibss.ssid_len)
259 		return 0;
260 
261 	if (!netif_running(wdev->netdev))
262 		return 0;
263 
264 	if (wdev->wext.keys)
265 		wdev->wext.keys->def = wdev->wext.default_key;
266 
267 	wdev->wext.ibss.privacy = wdev->wext.default_key != -1;
268 
269 	if (wdev->wext.keys && wdev->wext.keys->def != -1) {
270 		ck = kmemdup(wdev->wext.keys, sizeof(*ck), GFP_KERNEL);
271 		if (!ck)
272 			return -ENOMEM;
273 		for (i = 0; i < 4; i++)
274 			ck->params[i].key = ck->data[i];
275 	}
276 	err = __cfg80211_join_ibss(rdev, wdev->netdev,
277 				   &wdev->wext.ibss, ck);
278 	if (err)
279 		kfree(ck);
280 
281 	return err;
282 }
283 
cfg80211_ibss_wext_siwfreq(struct net_device * dev,struct iw_request_info * info,struct iw_freq * wextfreq,char * extra)284 int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
285 			       struct iw_request_info *info,
286 			       struct iw_freq *wextfreq, char *extra)
287 {
288 	struct wireless_dev *wdev = dev->ieee80211_ptr;
289 	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
290 	struct ieee80211_channel *chan = NULL;
291 	int err, freq;
292 
293 	/* call only for ibss! */
294 	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
295 		return -EINVAL;
296 
297 	if (!rdev->ops->join_ibss)
298 		return -EOPNOTSUPP;
299 
300 	freq = cfg80211_wext_freq(wextfreq);
301 	if (freq < 0)
302 		return freq;
303 
304 	if (freq) {
305 		chan = ieee80211_get_channel(wdev->wiphy, freq);
306 		if (!chan)
307 			return -EINVAL;
308 		if (chan->flags & IEEE80211_CHAN_NO_IR ||
309 		    chan->flags & IEEE80211_CHAN_DISABLED)
310 			return -EINVAL;
311 	}
312 
313 	if (wdev->wext.ibss.chandef.chan == chan)
314 		return 0;
315 
316 	err = 0;
317 	if (wdev->u.ibss.ssid_len)
318 		err = cfg80211_leave_ibss(rdev, dev, true);
319 
320 	if (err)
321 		return err;
322 
323 	if (chan) {
324 		cfg80211_chandef_create(&wdev->wext.ibss.chandef, chan,
325 					NL80211_CHAN_NO_HT);
326 		wdev->wext.ibss.channel_fixed = true;
327 	} else {
328 		/* cfg80211_ibss_wext_join will pick one if needed */
329 		wdev->wext.ibss.channel_fixed = false;
330 	}
331 
332 	return cfg80211_ibss_wext_join(rdev, wdev);
333 }
334 
cfg80211_ibss_wext_giwfreq(struct net_device * dev,struct iw_request_info * info,struct iw_freq * freq,char * extra)335 int cfg80211_ibss_wext_giwfreq(struct net_device *dev,
336 			       struct iw_request_info *info,
337 			       struct iw_freq *freq, char *extra)
338 {
339 	struct wireless_dev *wdev = dev->ieee80211_ptr;
340 	struct ieee80211_channel *chan = NULL;
341 
342 	/* call only for ibss! */
343 	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
344 		return -EINVAL;
345 
346 	if (wdev->u.ibss.current_bss)
347 		chan = wdev->u.ibss.current_bss->pub.channel;
348 	else if (wdev->wext.ibss.chandef.chan)
349 		chan = wdev->wext.ibss.chandef.chan;
350 
351 	if (chan) {
352 		freq->m = chan->center_freq;
353 		freq->e = 6;
354 		return 0;
355 	}
356 
357 	/* no channel if not joining */
358 	return -EINVAL;
359 }
360 
cfg80211_ibss_wext_siwessid(struct net_device * dev,struct iw_request_info * info,struct iw_point * data,char * ssid)361 int cfg80211_ibss_wext_siwessid(struct net_device *dev,
362 				struct iw_request_info *info,
363 				struct iw_point *data, char *ssid)
364 {
365 	struct wireless_dev *wdev = dev->ieee80211_ptr;
366 	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
367 	size_t len = data->length;
368 	int err;
369 
370 	/* call only for ibss! */
371 	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
372 		return -EINVAL;
373 
374 	if (!rdev->ops->join_ibss)
375 		return -EOPNOTSUPP;
376 
377 	err = 0;
378 	if (wdev->u.ibss.ssid_len)
379 		err = cfg80211_leave_ibss(rdev, dev, true);
380 
381 	if (err)
382 		return err;
383 
384 	/* iwconfig uses nul termination in SSID.. */
385 	if (len > 0 && ssid[len - 1] == '\0')
386 		len--;
387 
388 	memcpy(wdev->u.ibss.ssid, ssid, len);
389 	wdev->wext.ibss.ssid = wdev->u.ibss.ssid;
390 	wdev->wext.ibss.ssid_len = len;
391 
392 	return cfg80211_ibss_wext_join(rdev, wdev);
393 }
394 
cfg80211_ibss_wext_giwessid(struct net_device * dev,struct iw_request_info * info,struct iw_point * data,char * ssid)395 int cfg80211_ibss_wext_giwessid(struct net_device *dev,
396 				struct iw_request_info *info,
397 				struct iw_point *data, char *ssid)
398 {
399 	struct wireless_dev *wdev = dev->ieee80211_ptr;
400 
401 	/* call only for ibss! */
402 	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
403 		return -EINVAL;
404 
405 	data->flags = 0;
406 
407 	if (wdev->u.ibss.ssid_len) {
408 		data->flags = 1;
409 		data->length = wdev->u.ibss.ssid_len;
410 		memcpy(ssid, wdev->u.ibss.ssid, data->length);
411 	} else if (wdev->wext.ibss.ssid && wdev->wext.ibss.ssid_len) {
412 		data->flags = 1;
413 		data->length = wdev->wext.ibss.ssid_len;
414 		memcpy(ssid, wdev->wext.ibss.ssid, data->length);
415 	}
416 
417 	return 0;
418 }
419 
cfg80211_ibss_wext_siwap(struct net_device * dev,struct iw_request_info * info,struct sockaddr * ap_addr,char * extra)420 int cfg80211_ibss_wext_siwap(struct net_device *dev,
421 			     struct iw_request_info *info,
422 			     struct sockaddr *ap_addr, char *extra)
423 {
424 	struct wireless_dev *wdev = dev->ieee80211_ptr;
425 	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
426 	u8 *bssid = ap_addr->sa_data;
427 	int err;
428 
429 	/* call only for ibss! */
430 	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
431 		return -EINVAL;
432 
433 	if (!rdev->ops->join_ibss)
434 		return -EOPNOTSUPP;
435 
436 	if (ap_addr->sa_family != ARPHRD_ETHER)
437 		return -EINVAL;
438 
439 	/* automatic mode */
440 	if (is_zero_ether_addr(bssid) || is_broadcast_ether_addr(bssid))
441 		bssid = NULL;
442 
443 	if (bssid && !is_valid_ether_addr(bssid))
444 		return -EINVAL;
445 
446 	/* both automatic */
447 	if (!bssid && !wdev->wext.ibss.bssid)
448 		return 0;
449 
450 	/* fixed already - and no change */
451 	if (wdev->wext.ibss.bssid && bssid &&
452 	    ether_addr_equal(bssid, wdev->wext.ibss.bssid))
453 		return 0;
454 
455 	err = 0;
456 	if (wdev->u.ibss.ssid_len)
457 		err = cfg80211_leave_ibss(rdev, dev, true);
458 
459 	if (err)
460 		return err;
461 
462 	if (bssid) {
463 		memcpy(wdev->wext.bssid, bssid, ETH_ALEN);
464 		wdev->wext.ibss.bssid = wdev->wext.bssid;
465 	} else
466 		wdev->wext.ibss.bssid = NULL;
467 
468 	return cfg80211_ibss_wext_join(rdev, wdev);
469 }
470 
cfg80211_ibss_wext_giwap(struct net_device * dev,struct iw_request_info * info,struct sockaddr * ap_addr,char * extra)471 int cfg80211_ibss_wext_giwap(struct net_device *dev,
472 			     struct iw_request_info *info,
473 			     struct sockaddr *ap_addr, char *extra)
474 {
475 	struct wireless_dev *wdev = dev->ieee80211_ptr;
476 
477 	/* call only for ibss! */
478 	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
479 		return -EINVAL;
480 
481 	ap_addr->sa_family = ARPHRD_ETHER;
482 
483 	if (wdev->u.ibss.current_bss)
484 		memcpy(ap_addr->sa_data, wdev->u.ibss.current_bss->pub.bssid,
485 		       ETH_ALEN);
486 	else if (wdev->wext.ibss.bssid)
487 		memcpy(ap_addr->sa_data, wdev->wext.ibss.bssid, ETH_ALEN);
488 	else
489 		eth_zero_addr(ap_addr->sa_data);
490 
491 	return 0;
492 }
493 #endif
494