xref: /freebsd/contrib/wpa/wpa_supplicant/robust_av.c (revision 71e72c9e91c4b8007a4292e09669e8b549c29e97)
1 /*
2  * wpa_supplicant - Robust AV procedures
3  * Copyright (c) 2020, The Linux Foundation
4  * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
5  *
6  * This software may be distributed under the terms of the BSD license.
7  * See README for more details.
8  */
9 
10 #include "utils/includes.h"
11 #include "utils/common.h"
12 #include "utils/eloop.h"
13 #include "common/wpa_ctrl.h"
14 #include "common/ieee802_11_common.h"
15 #include "wpa_supplicant_i.h"
16 #include "driver_i.h"
17 #include "bss.h"
18 
19 
20 #define SCS_RESP_TIMEOUT 1
21 #define DSCP_REQ_TIMEOUT 5
22 
23 
wpas_populate_mscs_descriptor_ie(struct robust_av_data * robust_av,struct wpabuf * buf)24 void wpas_populate_mscs_descriptor_ie(struct robust_av_data *robust_av,
25 				      struct wpabuf *buf)
26 {
27 	u8 *len, *len1;
28 
29 	/* MSCS descriptor element */
30 	wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
31 	len = wpabuf_put(buf, 1);
32 	wpabuf_put_u8(buf, WLAN_EID_EXT_MSCS_DESCRIPTOR);
33 	wpabuf_put_u8(buf, robust_av->request_type);
34 	wpabuf_put_u8(buf, robust_av->up_bitmap);
35 	wpabuf_put_u8(buf, robust_av->up_limit);
36 	wpabuf_put_le32(buf, robust_av->stream_timeout);
37 
38 	if (robust_av->request_type != SCS_REQ_REMOVE) {
39 		/* TCLAS mask element */
40 		wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
41 		len1 = wpabuf_put(buf, 1);
42 		wpabuf_put_u8(buf, WLAN_EID_EXT_TCLAS_MASK);
43 
44 		/* Frame classifier */
45 		wpabuf_put_data(buf, robust_av->frame_classifier,
46 				robust_av->frame_classifier_len);
47 		*len1 = (u8 *) wpabuf_put(buf, 0) - len1 - 1;
48 	}
49 
50 	*len = (u8 *) wpabuf_put(buf, 0) - len - 1;
51 }
52 
53 
wpas_populate_type4_classifier(struct type4_params * type4_param,struct wpabuf * buf)54 static int wpas_populate_type4_classifier(struct type4_params *type4_param,
55 					  struct wpabuf *buf)
56 {
57 	/* classifier parameters */
58 	wpabuf_put_u8(buf, type4_param->classifier_mask);
59 	if (type4_param->ip_version == IPV4) {
60 		wpabuf_put_u8(buf, IPV4); /* IP version */
61 		wpabuf_put_data(buf, &type4_param->ip_params.v4.src_ip.s_addr,
62 				4);
63 		wpabuf_put_data(buf, &type4_param->ip_params.v4.dst_ip.s_addr,
64 				4);
65 		wpabuf_put_be16(buf, type4_param->ip_params.v4.src_port);
66 		wpabuf_put_be16(buf, type4_param->ip_params.v4.dst_port);
67 		wpabuf_put_u8(buf, type4_param->ip_params.v4.dscp);
68 		wpabuf_put_u8(buf, type4_param->ip_params.v4.protocol);
69 		wpabuf_put_u8(buf, 0); /* Reserved octet */
70 	} else {
71 		wpabuf_put_u8(buf, IPV6);
72 		wpabuf_put_data(buf, &type4_param->ip_params.v6.src_ip.s6_addr,
73 				16);
74 		wpabuf_put_data(buf, &type4_param->ip_params.v6.dst_ip.s6_addr,
75 				16);
76 		wpabuf_put_be16(buf, type4_param->ip_params.v6.src_port);
77 		wpabuf_put_be16(buf, type4_param->ip_params.v6.dst_port);
78 		wpabuf_put_u8(buf, type4_param->ip_params.v6.dscp);
79 		wpabuf_put_u8(buf, type4_param->ip_params.v6.next_header);
80 		wpabuf_put_data(buf, type4_param->ip_params.v6.flow_label, 3);
81 	}
82 
83 	return 0;
84 }
85 
86 
wpas_populate_type10_classifier(struct type10_params * type10_param,struct wpabuf * buf)87 static int wpas_populate_type10_classifier(struct type10_params *type10_param,
88 					   struct wpabuf *buf)
89 {
90 	/* classifier parameters */
91 	wpabuf_put_u8(buf, type10_param->prot_instance);
92 	wpabuf_put_u8(buf, type10_param->prot_number);
93 	wpabuf_put_data(buf, type10_param->filter_value,
94 			type10_param->filter_len);
95 	wpabuf_put_data(buf, type10_param->filter_mask,
96 			type10_param->filter_len);
97 	return 0;
98 }
99 
100 
tclas_elem_required(const struct qos_characteristics * qos_elem)101 static bool tclas_elem_required(const struct qos_characteristics *qos_elem)
102 {
103 	if (!qos_elem || !qos_elem->available)
104 		return true;
105 
106 	if (qos_elem->direction == SCS_DIRECTION_DOWN)
107 		return true;
108 
109 	return false;
110 }
111 
112 
wpas_populate_scs_descriptor_ie(struct scs_desc_elem * desc_elem,struct wpabuf * buf,bool allow_scs_traffic_desc)113 static int wpas_populate_scs_descriptor_ie(struct scs_desc_elem *desc_elem,
114 					   struct wpabuf *buf,
115 					   bool allow_scs_traffic_desc)
116 {
117 	u8 *len, *len1;
118 	struct tclas_element *tclas_elem;
119 	unsigned int i;
120 	struct qos_characteristics *qos_elem;
121 	u32 control_info = 0;
122 
123 	/* SCS Descriptor element */
124 	wpabuf_put_u8(buf, WLAN_EID_SCS_DESCRIPTOR);
125 	len = wpabuf_put(buf, 1);
126 	wpabuf_put_u8(buf, desc_elem->scs_id);
127 	wpabuf_put_u8(buf, desc_elem->request_type);
128 	if (desc_elem->request_type == SCS_REQ_REMOVE)
129 		goto end;
130 
131 	if (!tclas_elem_required(&desc_elem->qos_char_elem))
132 		goto skip_tclas_elem;
133 
134 	if (desc_elem->intra_access_priority || desc_elem->scs_up_avail) {
135 		wpabuf_put_u8(buf, WLAN_EID_INTRA_ACCESS_CATEGORY_PRIORITY);
136 		wpabuf_put_u8(buf, 1);
137 		wpabuf_put_u8(buf, desc_elem->intra_access_priority);
138 	}
139 
140 	tclas_elem = desc_elem->tclas_elems;
141 
142 	if (!tclas_elem)
143 		return -1;
144 
145 	for (i = 0; i < desc_elem->num_tclas_elem; i++, tclas_elem++) {
146 		int ret;
147 
148 		/* TCLAS element */
149 		wpabuf_put_u8(buf, WLAN_EID_TCLAS);
150 		len1 = wpabuf_put(buf, 1);
151 		wpabuf_put_u8(buf, 255); /* User Priority: not compared */
152 		/* Frame Classifier */
153 		wpabuf_put_u8(buf, tclas_elem->classifier_type);
154 		/* Frame classifier parameters */
155 		switch (tclas_elem->classifier_type) {
156 		case 4:
157 			ret = wpas_populate_type4_classifier(
158 				&tclas_elem->frame_classifier.type4_param,
159 				buf);
160 			break;
161 		case 10:
162 			ret = wpas_populate_type10_classifier(
163 				&tclas_elem->frame_classifier.type10_param,
164 				buf);
165 			break;
166 		default:
167 			return -1;
168 		}
169 
170 		if (ret == -1) {
171 			wpa_printf(MSG_ERROR,
172 				   "Failed to populate frame classifier");
173 			return -1;
174 		}
175 
176 		*len1 = (u8 *) wpabuf_put(buf, 0) - len1 - 1;
177 	}
178 
179 	if (desc_elem->num_tclas_elem > 1) {
180 		/* TCLAS Processing element */
181 		wpabuf_put_u8(buf, WLAN_EID_TCLAS_PROCESSING);
182 		wpabuf_put_u8(buf, 1);
183 		wpabuf_put_u8(buf, desc_elem->tclas_processing);
184 	}
185 
186 skip_tclas_elem:
187 	if (allow_scs_traffic_desc && desc_elem->qos_char_elem.available) {
188 		qos_elem = &desc_elem->qos_char_elem;
189 		/* Element ID, Length, and Element ID Extension */
190 		wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
191 		len1 = wpabuf_put(buf, 1);
192 		wpabuf_put_u8(buf, WLAN_EID_EXT_QOS_CHARACTERISTICS);
193 
194 		/* Remove invalid mask bits */
195 
196 		/* Medium Time is applicable only for direct link */
197 		if ((qos_elem->mask & SCS_QOS_BIT_MEDIUM_TIME) &&
198 		    qos_elem->direction != SCS_DIRECTION_DIRECT)
199 			qos_elem->mask &= ~SCS_QOS_BIT_MEDIUM_TIME;
200 
201 		/* Service Start Time LinkID is valid only when Service Start
202 		 * Time is present.
203 		 */
204 		if ((qos_elem->mask & SCS_QOS_BIT_SERVICE_START_TIME_LINKID) &&
205 		    !(qos_elem->mask & SCS_QOS_BIT_SERVICE_START_TIME))
206 			qos_elem->mask &=
207 				~SCS_QOS_BIT_SERVICE_START_TIME_LINKID;
208 
209 		/* IEEE Std 802.11be-2024, 9.4.2.326 QoS Characteristics
210 		 * element, Figure 9-1074bd (Control Info field format)
211 		 */
212 		control_info = ((u32) qos_elem->direction <<
213 				EHT_QOS_CONTROL_INFO_DIRECTION_OFFSET);
214 		control_info |= ((u32) desc_elem->intra_access_priority <<
215 				 EHT_QOS_CONTROL_INFO_TID_OFFSET);
216 		control_info |= ((u32) desc_elem->intra_access_priority <<
217 				 EHT_QOS_CONTROL_INFO_USER_PRIORITY_OFFSET);
218 		control_info |= ((u32) qos_elem->mask <<
219 				 EHT_QOS_CONTROL_INFO_PRESENCE_MASK_OFFSET);
220 
221 		/* Control Info */
222 		wpabuf_put_le32(buf, control_info);
223 		/* Minimum Service Interval */
224 		wpabuf_put_le32(buf, qos_elem->min_si);
225 		/* Maximum Service Interval */
226 		wpabuf_put_le32(buf, qos_elem->max_si);
227 		/* Minimum Data Rate */
228 		wpabuf_put_le24(buf, qos_elem->min_data_rate);
229 		/* Delay Bound */
230 		wpabuf_put_le24(buf, qos_elem->delay_bound);
231 
232 		/* Maximum MSDU Size */
233 		if (qos_elem->mask & SCS_QOS_BIT_MAX_MSDU_SIZE)
234 			wpabuf_put_le16(buf, qos_elem->max_msdu_size);
235 		/* Start Service Time */
236 		if (qos_elem->mask & SCS_QOS_BIT_SERVICE_START_TIME)
237 			wpabuf_put_le32(buf, qos_elem->service_start_time);
238 		/* Service Start Time LinkID */
239 		if (qos_elem->mask & SCS_QOS_BIT_SERVICE_START_TIME_LINKID)
240 			wpabuf_put_u8(buf,
241 				      qos_elem->service_start_time_link_id);
242 		/* Mean Data Rate */
243 		if (qos_elem->mask & SCS_QOS_BIT_MEAN_DATA_RATE)
244 			wpabuf_put_le24(buf, qos_elem->mean_data_rate);
245 		/* Delayed Bounded Burst Size */
246 		if (qos_elem->mask & SCS_QOS_BIT_DELAYED_BOUNDED_BURST_SIZE)
247 			wpabuf_put_le32(buf, qos_elem->burst_size);
248 		/* MSDU Lifetime */
249 		if (qos_elem->mask & SCS_QOS_BIT_MSDU_LIFETIME)
250 			wpabuf_put_le16(buf, qos_elem->msdu_lifetime);
251 		/* MSDU Delivery Info */
252 		if (qos_elem->mask & SCS_QOS_BIT_MSDU_DELIVERY_INFO)
253 			wpabuf_put_u8(buf, qos_elem->msdu_delivery_info);
254 		/* Medium Time */
255 		if (qos_elem->mask & SCS_QOS_BIT_MEDIUM_TIME)
256 			wpabuf_put_le16(buf, qos_elem->medium_time);
257 
258 		*len1 = (u8 *) wpabuf_put(buf, 0) - len1 - 1;
259 	}
260 
261 end:
262 	*len = (u8 *) wpabuf_put(buf, 0) - len - 1;
263 	return 0;
264 }
265 
266 
populate_type10_classifier_data(const struct tclas_element * src,struct tclas_element * dst,unsigned int num_tclas_elem)267 static int populate_type10_classifier_data(const struct tclas_element *src,
268 					   struct tclas_element *dst,
269 					   unsigned int num_tclas_elem)
270 {
271 	struct type10_params *t10_param;
272 	unsigned int i;
273 	size_t filter_len;
274 
275 	if (!src)
276 		return 0;
277 
278 	if (!dst)
279 		return -1;
280 
281 	for (i = 0; i < num_tclas_elem; i++, src++, dst++) {
282 		if (src->classifier_type != 10)
283 			continue;
284 
285 		filter_len = src->frame_classifier.type10_param.filter_len;
286 		if (!filter_len)
287 			continue;
288 
289 		t10_param = &dst->frame_classifier.type10_param;
290 		t10_param->filter_value = os_memdup(
291 			src->frame_classifier.type10_param.filter_value,
292 			filter_len);
293 		if (!t10_param->filter_value)
294 			return -1;
295 
296 		t10_param->filter_mask = os_memdup(
297 			src->frame_classifier.type10_param.filter_mask,
298 			filter_len);
299 		if (!t10_param->filter_mask) {
300 			os_free(t10_param->filter_value);
301 			t10_param->filter_value = NULL;
302 			return -1;
303 		}
304 
305 		t10_param->filter_len = filter_len;
306 	}
307 
308 	return 0;
309 }
310 
311 
wpas_send_mscs_req(struct wpa_supplicant * wpa_s)312 int wpas_send_mscs_req(struct wpa_supplicant *wpa_s)
313 {
314 	struct wpabuf *buf;
315 	size_t buf_len;
316 	int ret;
317 
318 	if (wpa_s->wpa_state != WPA_COMPLETED || !wpa_s->current_ssid)
319 		return 0;
320 
321 	if (!wpa_bss_ext_capab(wpa_s->current_bss, WLAN_EXT_CAPAB_MSCS)) {
322 		wpa_dbg(wpa_s, MSG_INFO,
323 			"AP does not support MSCS - could not send MSCS Req");
324 		return -1;
325 	}
326 
327 	if (wpa_s->mscs_setup_done &&
328 	    wpa_s->robust_av.request_type == SCS_REQ_ADD) {
329 		wpa_msg(wpa_s, MSG_INFO,
330 			"MSCS: Failed to send MSCS ADD request: MSCS session already active");
331 		return -1;
332 	}
333 
334 	if (!wpa_s->mscs_setup_done &&
335 	    wpa_s->robust_av.request_type != SCS_REQ_ADD) {
336 		wpa_msg(wpa_s, MSG_INFO,
337 			"MSCS: Failed to send MSCS Request: request type invalid");
338 		return -1;
339 	}
340 
341 	buf_len = 3 +	/* Action frame header */
342 		  3 +	/* MSCS descriptor IE header */
343 		  1 +	/* Request type */
344 		  2 +	/* User priority control */
345 		  4 +	/* Stream timeout */
346 		  3 +	/* TCLAS Mask IE header */
347 		  wpa_s->robust_av.frame_classifier_len;
348 
349 	buf = wpabuf_alloc(buf_len);
350 	if (!buf) {
351 		wpa_printf(MSG_ERROR, "Failed to allocate MSCS req");
352 		return -1;
353 	}
354 
355 	wpabuf_put_u8(buf, WLAN_ACTION_ROBUST_AV_STREAMING);
356 	wpabuf_put_u8(buf, ROBUST_AV_MSCS_REQ);
357 	wpa_s->robust_av.dialog_token++;
358 	wpabuf_put_u8(buf, wpa_s->robust_av.dialog_token);
359 
360 	/* MSCS descriptor element */
361 	wpas_populate_mscs_descriptor_ie(&wpa_s->robust_av, buf);
362 
363 	wpa_hexdump_buf(MSG_MSGDUMP, "MSCS Request", buf);
364 	ret = wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
365 				  wpa_s->own_addr, wpa_s->bssid,
366 				  wpabuf_head(buf), wpabuf_len(buf), 0);
367 	if (ret < 0)
368 		wpa_dbg(wpa_s, MSG_INFO, "MSCS: Failed to send MSCS Request");
369 
370 	wpabuf_free(buf);
371 	return ret;
372 }
373 
374 
tclas_elem_len(const struct tclas_element * elem)375 static size_t tclas_elem_len(const struct tclas_element *elem)
376 {
377 	size_t buf_len = 0;
378 
379 	buf_len += 2 +	/* TCLAS element header */
380 		1 +	/* User Priority */
381 		1 ;	/* Classifier Type */
382 
383 	if (elem->classifier_type == 4) {
384 		enum ip_version ip_ver;
385 
386 		buf_len += 1 +	/* Classifier mask */
387 			1 +	/* IP version */
388 			1 +	/* user priority */
389 			2 +	/* src_port */
390 			2 +	/* dst_port */
391 			1 ;	/* dscp */
392 		ip_ver = elem->frame_classifier.type4_param.ip_version;
393 		if (ip_ver == IPV4) {
394 			buf_len += 4 +  /* src_ip */
395 				4 +	/* dst_ip */
396 				1 +	/* protocol */
397 				1 ;  /* Reserved */
398 		} else if (ip_ver == IPV6) {
399 			buf_len += 16 +  /* src_ip */
400 				16 +  /* dst_ip */
401 				1  +  /* next_header */
402 				3  ;  /* flow_label */
403 		} else {
404 			wpa_printf(MSG_ERROR, "%s: Incorrect IP version %d",
405 				   __func__, ip_ver);
406 			return 0;
407 		}
408 	} else if (elem->classifier_type == 10) {
409 		buf_len += 1 +	/* protocol instance */
410 			1 +	/* protocol number */
411 			2 * elem->frame_classifier.type10_param.filter_len;
412 	} else {
413 		wpa_printf(MSG_ERROR, "%s: Incorrect classifier type %u",
414 			   __func__, elem->classifier_type);
415 		return 0;
416 	}
417 
418 	return buf_len;
419 }
420 
421 
qos_char_len(const struct qos_characteristics * qos_elem)422 static size_t qos_char_len(const struct qos_characteristics *qos_elem)
423 {
424 	size_t buf_len = 0;
425 
426 	buf_len += 1 +	/* Element ID */
427 		1 +	/* Length */
428 		1 +	/* Element ID Extension */
429 		4 +	/* Control Info */
430 		4 +	/* Minimum Service Interval */
431 		4 +	/* Maximum Service Interval */
432 		3 +	/* Minimum Data Rate */
433 		3;	/* Delay Bound */
434 
435 	if (qos_elem->mask & SCS_QOS_BIT_MAX_MSDU_SIZE)
436 		buf_len += 2;	 /* Maximum MSDU Size */
437 
438 	if (qos_elem->mask & SCS_QOS_BIT_SERVICE_START_TIME) {
439 		buf_len += 4;	 /* Service Start Time */
440 		if (qos_elem->mask & SCS_QOS_BIT_SERVICE_START_TIME_LINKID)
441 			buf_len++;	/* Service Start Time LinkID */
442 	}
443 
444 	if (qos_elem->mask & SCS_QOS_BIT_MEAN_DATA_RATE)
445 		buf_len += 3;	 /* Mean Data Rate */
446 
447 	if (qos_elem->mask & SCS_QOS_BIT_DELAYED_BOUNDED_BURST_SIZE)
448 		buf_len += 4;	 /* Delayed Bounded Burst Size */
449 
450 	if (qos_elem->mask & SCS_QOS_BIT_MSDU_LIFETIME)
451 		buf_len += 2;	 /* MSDU Lifetime */
452 
453 	if (qos_elem->mask & SCS_QOS_BIT_MSDU_DELIVERY_INFO)
454 		buf_len++;	 /* MSDU Delivery Info */
455 
456 	if (qos_elem->mask & SCS_QOS_BIT_MEDIUM_TIME &&
457 	    qos_elem->direction == SCS_DIRECTION_DIRECT)
458 		buf_len += 2;	 /* Medium Time */
459 
460 	return buf_len;
461 }
462 
463 
allocate_scs_buf(struct scs_desc_elem * desc_elem,unsigned int num_scs_desc,bool allow_scs_traffic_desc)464 static struct wpabuf * allocate_scs_buf(struct scs_desc_elem *desc_elem,
465 					unsigned int num_scs_desc,
466 					bool allow_scs_traffic_desc)
467 {
468 	struct wpabuf *buf;
469 	size_t buf_len = 0;
470 	unsigned int i, j;
471 
472 	buf_len = 3; /* Action frame header */
473 
474 	for (i = 0; i < num_scs_desc; i++, desc_elem++) {
475 		struct tclas_element *tclas_elem;
476 
477 		buf_len += 2 +	/* SCS descriptor IE header */
478 			   1 +	/* SCSID */
479 			   1 ;	/* Request type */
480 
481 		if (desc_elem->request_type == SCS_REQ_REMOVE)
482 			continue;
483 
484 		if (allow_scs_traffic_desc &&
485 		    desc_elem->qos_char_elem.available)
486 			buf_len += qos_char_len(&desc_elem->qos_char_elem);
487 
488 		if (!tclas_elem_required(&desc_elem->qos_char_elem))
489 			continue;
490 
491 		if (desc_elem->intra_access_priority || desc_elem->scs_up_avail)
492 			buf_len += 3;
493 
494 		tclas_elem = desc_elem->tclas_elems;
495 		if (!tclas_elem) {
496 			wpa_printf(MSG_ERROR, "%s: TCLAS element null",
497 				   __func__);
498 			return NULL;
499 		}
500 
501 		for (j = 0; j < desc_elem->num_tclas_elem; j++, tclas_elem++) {
502 			size_t elen;
503 
504 			elen = tclas_elem_len(tclas_elem);
505 			if (elen == 0)
506 				return NULL;
507 			buf_len += elen;
508 		}
509 
510 		if (desc_elem->num_tclas_elem > 1) {
511 			buf_len += 1 +	/* TCLAS Processing eid */
512 				   1 +	/* length */
513 				   1 ;	/* processing */
514 		}
515 	}
516 
517 	buf = wpabuf_alloc(buf_len);
518 	if (!buf) {
519 		wpa_printf(MSG_ERROR, "Failed to allocate SCS req");
520 		return NULL;
521 	}
522 
523 	return buf;
524 }
525 
526 
scs_cleanup_descriptors(struct active_scs_elem * scs_elem)527 static void scs_cleanup_descriptors(struct active_scs_elem *scs_elem)
528 {
529 	if (!scs_elem)
530 		return;
531 	dl_list_del(&scs_elem->list);
532 	free_up_tclas_elem(&scs_elem->desc_elem);
533 	os_free(scs_elem);
534 }
535 
536 
scs_request_timer(void * eloop_ctx,void * timeout_ctx)537 static void scs_request_timer(void *eloop_ctx, void *timeout_ctx)
538 {
539 	struct wpa_supplicant *wpa_s = eloop_ctx;
540 	struct active_scs_elem *scs_desc, *prev;
541 
542 	if (wpa_s->wpa_state != WPA_COMPLETED || !wpa_s->current_ssid)
543 		return;
544 
545 	/* Once timeout is over, remove all SCS descriptors with no response */
546 	dl_list_for_each_safe(scs_desc, prev, &wpa_s->active_scs_ids,
547 			      struct active_scs_elem, list) {
548 		u8 bssid[ETH_ALEN] = { 0 };
549 		const u8 *src;
550 
551 		if (scs_desc->status == SCS_DESC_SUCCESS)
552 			continue;
553 
554 		if (wpa_s->current_bss)
555 			src = wpa_s->current_bss->bssid;
556 		else
557 			src = bssid;
558 
559 		wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_SCS_RESULT "bssid=" MACSTR
560 			" SCSID=%u status_code=timedout", MAC2STR(src),
561 			scs_desc->scs_id);
562 
563 		wpa_printf(MSG_INFO, "%s: SCSID %d removed after timeout",
564 			   __func__, scs_desc->scs_id);
565 		scs_cleanup_descriptors(scs_desc);
566 	}
567 
568 	eloop_cancel_timeout(scs_request_timer, wpa_s, NULL);
569 	wpa_s->ongoing_scs_req = false;
570 }
571 
572 
_wpa_send_scs_req(struct wpa_supplicant * wpa_s,struct scs_desc_elem * desc_elem,unsigned int num_scs_desc)573 static int _wpa_send_scs_req(struct wpa_supplicant *wpa_s,
574 			     struct scs_desc_elem *desc_elem,
575 			     unsigned int num_scs_desc)
576 {
577 	struct wpabuf *buf = NULL;
578 	const struct ieee80211_eht_capabilities *eht;
579 	const u8 *eht_ie;
580 	int ret = -1;
581 	unsigned int i;
582 	bool allow_scs_traffic_desc = false;
583 
584 	if (wpa_s->wpa_state != WPA_COMPLETED || !wpa_s->current_ssid ||
585 	    !desc_elem)
586 		return -1;
587 
588 	if (!wpa_bss_ext_capab(wpa_s->current_bss, WLAN_EXT_CAPAB_SCS)) {
589 		wpa_dbg(wpa_s, MSG_INFO,
590 			"AP does not support SCS - could not send SCS Request");
591 		return -1;
592 	}
593 
594 	if (wpa_is_non_eht_scs_traffic_desc_supported(wpa_s->current_bss))
595 		allow_scs_traffic_desc = true;
596 
597 	/* Allow SCS Traffic descriptor support for EHT connection */
598 	eht_ie = wpa_bss_get_ie_ext(wpa_s->current_bss,
599 				    WLAN_EID_EXT_EHT_CAPABILITIES);
600 	if (wpa_s->connection_eht && eht_ie &&
601 	    eht_ie[1] >= 1 + IEEE80211_EHT_CAPAB_MIN_LEN) {
602 		eht = (const struct ieee80211_eht_capabilities *) &eht_ie[3];
603 		if (le_to_host16(eht->mac_cap) & EHT_MACCAP_SCS_TRAFFIC_DESC)
604 			allow_scs_traffic_desc = true;
605 	}
606 
607 	if (!allow_scs_traffic_desc && desc_elem->qos_char_elem.available) {
608 		wpa_dbg(wpa_s, MSG_INFO,
609 			"Connection does not support EHT/non-EHT SCS Traffic Description - could not send SCS Request with QoS Characteristics");
610 		return -1;
611 	}
612 
613 	buf = allocate_scs_buf(desc_elem, num_scs_desc, allow_scs_traffic_desc);
614 	if (!buf)
615 		return -1;
616 
617 	wpabuf_put_u8(buf, WLAN_ACTION_ROBUST_AV_STREAMING);
618 	wpabuf_put_u8(buf, ROBUST_AV_SCS_REQ);
619 	wpa_s->scs_dialog_token++;
620 	if (wpa_s->scs_dialog_token == 0)
621 		wpa_s->scs_dialog_token++;
622 	wpabuf_put_u8(buf, wpa_s->scs_dialog_token);
623 
624 	for (i = 0; i < num_scs_desc; i++, desc_elem++) {
625 		/* SCS Descriptor element */
626 		if (wpas_populate_scs_descriptor_ie(desc_elem, buf,
627 						    allow_scs_traffic_desc) < 0)
628 			goto end;
629 	}
630 
631 	wpa_hexdump_buf(MSG_DEBUG, "SCS Request", buf);
632 	ret = wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
633 				  wpa_s->own_addr, wpa_s->bssid,
634 				  wpabuf_head(buf), wpabuf_len(buf), 0);
635 	if (ret < 0) {
636 		wpa_dbg(wpa_s, MSG_ERROR, "SCS: Failed to send SCS Request");
637 		wpa_s->scs_dialog_token--;
638 		goto end;
639 	}
640 
641 	/*
642 	 * Register a timeout after which this request will be removed from
643 	 * the cache.
644 	 */
645 	eloop_register_timeout(SCS_RESP_TIMEOUT, 0, scs_request_timer, wpa_s,
646 			       NULL);
647 	wpa_s->ongoing_scs_req = true;
648 
649 end:
650 	wpabuf_free(buf);
651 	return ret;
652 }
653 
654 
wpas_scs_reconfigure(struct wpa_supplicant * wpa_s)655 int wpas_scs_reconfigure(struct wpa_supplicant *wpa_s)
656 {
657 	struct scs_desc_elem *desc_elems, *desc_data, desc_elem;
658 	struct active_scs_elem *scs_desc;
659 	unsigned int num_scs_desc;
660 	unsigned int i;
661 	unsigned int num_tclas_elem;
662 	int ret = -1;
663 
664 	if (!wpa_s->scs_reconfigure)
665 		return 0;
666 
667 	num_scs_desc = dl_list_len(&wpa_s->active_scs_ids);
668 	if (!num_scs_desc)
669 		return 0;
670 
671 	desc_elems = os_calloc(num_scs_desc, sizeof(struct scs_desc_elem));
672 	if (!desc_elems) {
673 		wpa_printf(MSG_ERROR, "SCS: Failed to allocate memory");
674 		return ret;
675 	}
676 
677 	num_scs_desc = 0;
678 	dl_list_for_each(scs_desc, &wpa_s->active_scs_ids,
679 			 struct active_scs_elem, list) {
680 		os_memcpy(&desc_elem, &scs_desc->desc_elem, sizeof(desc_elem));
681 
682 		num_tclas_elem = scs_desc->desc_elem.num_tclas_elem;
683 		if (num_tclas_elem) {
684 			desc_elem.tclas_elems =
685 				os_memdup(scs_desc->desc_elem.tclas_elems,
686 					  num_tclas_elem *
687 					  sizeof(struct tclas_element));
688 			if (!desc_elem.tclas_elems)
689 				goto end;
690 
691 			if (populate_type10_classifier_data(
692 				    scs_desc->desc_elem.tclas_elems,
693 				    desc_elem.tclas_elems,
694 				    num_tclas_elem) < 0) {
695 				free_up_tclas_elem(&desc_elem);
696 				goto end;
697 			}
698 		}
699 
700 		os_memcpy(&desc_elems[num_scs_desc], &desc_elem,
701 			  sizeof(desc_elem));
702 		num_scs_desc++;
703 	}
704 
705 	if (_wpa_send_scs_req(wpa_s, desc_elems, num_scs_desc) < 0) {
706 		wpa_printf(MSG_DEBUG,
707 			   "SCS: Failed to reconfigure SCS requests - retain for next roaming");
708 	} else {
709 		dl_list_for_each(scs_desc, &wpa_s->active_scs_ids,
710 				 struct active_scs_elem, list)
711 			scs_desc->status = SCS_DESC_SENT;
712 	}
713 	ret = 0;
714 end:
715 	wpa_s->scs_reconfigure = false;
716 
717 	if (desc_elems) {
718 		desc_data = desc_elems;
719 		for (i = 0; i < num_scs_desc; i++, desc_data++) {
720 			if (desc_data->tclas_elems)
721 				free_up_tclas_elem(desc_data);
722 		}
723 		os_free(desc_elems);
724 	}
725 
726 	return ret;
727 }
728 
729 
wpas_send_scs_req(struct wpa_supplicant * wpa_s)730 int wpas_send_scs_req(struct wpa_supplicant *wpa_s)
731 {
732 	struct scs_desc_elem *desc_elem = NULL;
733 	int ret = -1;
734 	unsigned int i;
735 
736 	if (_wpa_send_scs_req(wpa_s, wpa_s->scs_robust_av_req.scs_desc_elems,
737 			      wpa_s->scs_robust_av_req.num_scs_desc) < 0)
738 		goto end;
739 
740 	desc_elem = wpa_s->scs_robust_av_req.scs_desc_elems;
741 
742 	for (i = 0; i < wpa_s->scs_robust_av_req.num_scs_desc;
743 	     i++, desc_elem++) {
744 		struct active_scs_elem *active_scs_elem;
745 		struct tclas_element *tclas_elem;
746 		unsigned int num_tclas_elem = desc_elem->num_tclas_elem;
747 
748 		if (desc_elem->request_type != SCS_REQ_ADD)
749 			continue;
750 
751 		active_scs_elem = os_zalloc(sizeof(struct active_scs_elem));
752 		if (!active_scs_elem)
753 			break;
754 
755 		os_memcpy(&active_scs_elem->desc_elem, desc_elem,
756 			  sizeof(struct scs_desc_elem));
757 
758 		if (num_tclas_elem) {
759 			tclas_elem = os_memdup(desc_elem->tclas_elems,
760 					       num_tclas_elem *
761 					       sizeof(struct tclas_element));
762 			if (!tclas_elem) {
763 				os_free(active_scs_elem);
764 				goto end;
765 			}
766 
767 			active_scs_elem->desc_elem.tclas_elems = tclas_elem;
768 
769 			if (populate_type10_classifier_data(
770 				    desc_elem->tclas_elems, tclas_elem,
771 				    num_tclas_elem) < 0) {
772 				free_up_tclas_elem(&active_scs_elem->desc_elem);
773 				os_free(active_scs_elem);
774 				goto end;
775 			}
776 		}
777 
778 		active_scs_elem->scs_id = desc_elem->scs_id;
779 		active_scs_elem->status = SCS_DESC_SENT;
780 		dl_list_add(&wpa_s->active_scs_ids, &active_scs_elem->list);
781 	}
782 	ret = 0; /* Success */
783 
784 end:
785 	free_up_scs_desc(&wpa_s->scs_robust_av_req);
786 	return ret;
787 }
788 
789 
free_up_tclas_elem(struct scs_desc_elem * elem)790 void free_up_tclas_elem(struct scs_desc_elem *elem)
791 {
792 	struct tclas_element *tclas_elems = elem->tclas_elems;
793 	unsigned int num_tclas_elem = elem->num_tclas_elem;
794 	struct tclas_element *tclas_data;
795 	unsigned int j;
796 
797 	elem->tclas_elems = NULL;
798 	elem->num_tclas_elem = 0;
799 
800 	if (!tclas_elems)
801 		return;
802 
803 	tclas_data = tclas_elems;
804 	for (j = 0; j < num_tclas_elem; j++, tclas_data++) {
805 		if (tclas_data->classifier_type != 10)
806 			continue;
807 
808 		os_free(tclas_data->frame_classifier.type10_param.filter_value);
809 		os_free(tclas_data->frame_classifier.type10_param.filter_mask);
810 	}
811 
812 	os_free(tclas_elems);
813 }
814 
815 
free_up_scs_desc(struct scs_robust_av_data * data)816 void free_up_scs_desc(struct scs_robust_av_data *data)
817 {
818 	struct scs_desc_elem *desc_elems = data->scs_desc_elems;
819 	unsigned int num_scs_desc = data->num_scs_desc;
820 	struct scs_desc_elem *desc_data;
821 	unsigned int i;
822 
823 	data->scs_desc_elems = NULL;
824 	data->num_scs_desc = 0;
825 
826 	if (!desc_elems)
827 		return;
828 
829 	desc_data = desc_elems;
830 	for (i = 0; i < num_scs_desc; i++, desc_data++) {
831 		if (desc_data->request_type == SCS_REQ_REMOVE ||
832 		    !desc_data->tclas_elems)
833 			continue;
834 
835 		free_up_tclas_elem(desc_data);
836 	}
837 	os_free(desc_elems);
838 }
839 
840 
841 /* Element ID Extension(1) + Request Type(1) + User Priority Control(2) +
842  * Stream Timeout(4) */
843 #define MSCS_DESCRIPTOR_FIXED_LEN 8
844 
wpas_parse_mscs_resp(struct wpa_supplicant * wpa_s,u16 status,const u8 * bssid,const u8 * mscs_desc_ie)845 static void wpas_parse_mscs_resp(struct wpa_supplicant *wpa_s,
846 				 u16 status, const u8 *bssid,
847 				 const u8 *mscs_desc_ie)
848 {
849 	struct robust_av_data robust_av;
850 	const u8 *pos;
851 
852 	/* The MSCS Descriptor element is optional in the MSCS Response frame */
853 	if (!mscs_desc_ie)
854 		goto event_mscs_result;
855 
856 	if (mscs_desc_ie[1] < MSCS_DESCRIPTOR_FIXED_LEN) {
857 		wpa_printf(MSG_INFO,
858 			   "MSCS: Drop received frame: invalid MSCS Descriptor element length: %d",
859 			   mscs_desc_ie[1]);
860 		return;
861 	}
862 
863 	os_memset(&robust_av, 0, sizeof(struct robust_av_data));
864 
865 	/* Skip Element ID, Length, and Element ID Extension */
866 	pos = &mscs_desc_ie[3];
867 
868 	robust_av.request_type = *pos++;
869 
870 	switch (robust_av.request_type) {
871 	case SCS_REQ_CHANGE:
872 		/*
873 		 * Inform the suggested set of parameters that could be accepted
874 		 * by the AP in response to a subsequent request by the station.
875 		 */
876 		robust_av.up_bitmap = *pos++;
877 		robust_av.up_limit = *pos++ & 0x07;
878 		robust_av.stream_timeout = WPA_GET_LE32(pos);
879 		wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_MSCS_RESULT "bssid=" MACSTR
880 			" status_code=%u change up_bitmap=%u up_limit=%u stream_timeout=%u",
881 			MAC2STR(bssid), status, robust_av.up_bitmap,
882 			robust_av.up_limit, robust_av.stream_timeout);
883 		wpa_s->mscs_setup_done = false;
884 		return;
885 	case SCS_REQ_ADD:
886 		/*
887 		 * This type is used in (Re)Association Response frame MSCS
888 		 * Descriptor element if no change is required.
889 		 */
890 		break;
891 	default:
892 		wpa_printf(MSG_INFO,
893 			   "MSCS: Drop received frame with unknown Request Type: %u",
894 			   robust_av.request_type);
895 		return;
896 	}
897 
898 event_mscs_result:
899 	wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_MSCS_RESULT "bssid=" MACSTR
900 		" status_code=%u", MAC2STR(bssid), status);
901 	wpa_s->mscs_setup_done = status == WLAN_STATUS_SUCCESS;
902 }
903 
904 
wpas_handle_robust_av_recv_action(struct wpa_supplicant * wpa_s,const u8 * dst,const u8 * src,const u8 * buf,size_t len)905 void wpas_handle_robust_av_recv_action(struct wpa_supplicant *wpa_s,
906 				       const u8 *dst, const u8 *src,
907 				       const u8 *buf, size_t len)
908 {
909 	u8 dialog_token;
910 	u16 status_code;
911 	const u8 *mscs_desc_ie;
912 
913 	if (len < 3)
914 		return;
915 
916 	dialog_token = *buf++;
917 	len--;
918 
919 	/* AP sets dialog token to 0 for unsolicited response */
920 	if (!dialog_token && !wpa_s->mscs_setup_done) {
921 		wpa_printf(MSG_INFO,
922 			   "MSCS: Drop unsolicited received frame: inactive");
923 		return;
924 	}
925 
926 	if (dialog_token && dialog_token != wpa_s->robust_av.dialog_token) {
927 		wpa_printf(MSG_INFO,
928 			   "MSCS: Drop received frame due to dialog token mismatch: received:%u expected:%u",
929 			   dialog_token, wpa_s->robust_av.dialog_token);
930 		return;
931 	}
932 
933 	if (is_multicast_ether_addr(dst)) {
934 		wpa_printf(MSG_DEBUG,
935 			   "MSCS: Ignore group-addressed MSCS Response frame (A1="
936 			   MACSTR " A2=" MACSTR ")",
937 			   MAC2STR(dst), MAC2STR(src));
938 		return;
939 	}
940 
941 	status_code = WPA_GET_LE16(buf);
942 	buf += 2;
943 	len -= 2;
944 
945 	mscs_desc_ie = get_ie_ext(buf, len, WLAN_EID_EXT_MSCS_DESCRIPTOR);
946 	wpas_parse_mscs_resp(wpa_s, status_code, src, mscs_desc_ie);
947 }
948 
949 
wpas_handle_assoc_resp_mscs(struct wpa_supplicant * wpa_s,const u8 * bssid,const u8 * ies,size_t ies_len)950 void wpas_handle_assoc_resp_mscs(struct wpa_supplicant *wpa_s, const u8 *bssid,
951 				 const u8 *ies, size_t ies_len)
952 {
953 	const u8 *mscs_desc_ie, *mscs_status;
954 	u16 status;
955 
956 	/* Process optional MSCS Status subelement when MSCS IE is in
957 	 * (Re)Association Response frame */
958 	if (!ies || ies_len == 0 || !wpa_s->robust_av.valid_config)
959 		return;
960 
961 	mscs_desc_ie = get_ie_ext(ies, ies_len, WLAN_EID_EXT_MSCS_DESCRIPTOR);
962 	if (!mscs_desc_ie || mscs_desc_ie[1] <= MSCS_DESCRIPTOR_FIXED_LEN)
963 		return;
964 
965 	/* Subelements start after element header and fixed fields */
966 	mscs_status = get_ie(&mscs_desc_ie[2 + MSCS_DESCRIPTOR_FIXED_LEN],
967 			     mscs_desc_ie[1] - MSCS_DESCRIPTOR_FIXED_LEN,
968 			     MCSC_SUBELEM_STATUS);
969 	if (!mscs_status || mscs_status[1] < 2)
970 		return;
971 
972 	status = WPA_GET_LE16(mscs_status + 2);
973 
974 	wpas_parse_mscs_resp(wpa_s, status, bssid, mscs_desc_ie);
975 }
976 
977 
wpas_wait_for_dscp_req_timer(void * eloop_ctx,void * timeout_ctx)978 static void wpas_wait_for_dscp_req_timer(void *eloop_ctx, void *timeout_ctx)
979 {
980 	struct wpa_supplicant *wpa_s = eloop_ctx;
981 
982 	/* Once timeout is over, reset wait flag and allow sending DSCP query */
983 	wpa_printf(MSG_DEBUG,
984 		   "QM: Wait time over for sending DSCP request - allow DSCP query");
985 	wpa_s->wait_for_dscp_req = 0;
986 	wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY "request_wait end");
987 }
988 
989 
wpas_handle_assoc_resp_qos_mgmt(struct wpa_supplicant * wpa_s,const u8 * ies,size_t ies_len)990 void wpas_handle_assoc_resp_qos_mgmt(struct wpa_supplicant *wpa_s,
991 				     const u8 *ies, size_t ies_len)
992 {
993 	const u8 *wfa_capa;
994 
995 	wpa_s->connection_dscp = 0;
996 	if (wpa_s->wait_for_dscp_req)
997 		eloop_cancel_timeout(wpas_wait_for_dscp_req_timer, wpa_s, NULL);
998 
999 	if (!ies || ies_len == 0 || !wpa_s->enable_dscp_policy_capa)
1000 		return;
1001 
1002 	wfa_capa = get_vendor_ie(ies, ies_len, WFA_CAPA_IE_VENDOR_TYPE);
1003 	if (!wfa_capa || wfa_capa[1] < 6 || wfa_capa[6] < 1 ||
1004 	    !(wfa_capa[7] & WFA_CAPA_QM_DSCP_POLICY))
1005 		return; /* AP does not enable QM DSCP Policy */
1006 
1007 	wpa_s->connection_dscp = 1;
1008 	wpa_s->wait_for_dscp_req = !!(wfa_capa[7] &
1009 				      WFA_CAPA_QM_UNSOLIC_DSCP);
1010 	if (!wpa_s->wait_for_dscp_req)
1011 		return;
1012 
1013 	/* Register a timeout after which dscp query can be sent to AP. */
1014 	wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY "request_wait start");
1015 	eloop_register_timeout(DSCP_REQ_TIMEOUT, 0,
1016 			       wpas_wait_for_dscp_req_timer, wpa_s, NULL);
1017 }
1018 
1019 
wpas_handle_robust_av_scs_recv_action(struct wpa_supplicant * wpa_s,const u8 * dst,const u8 * src,const u8 * buf,size_t len)1020 void wpas_handle_robust_av_scs_recv_action(struct wpa_supplicant *wpa_s,
1021 					   const u8 *dst, const u8 *src,
1022 					   const u8 *buf, size_t len)
1023 {
1024 	u8 dialog_token;
1025 	unsigned int i, count;
1026 	struct active_scs_elem *scs_desc, *prev;
1027 
1028 	if (len < 2)
1029 		return;
1030 	if (!wpa_s->ongoing_scs_req) {
1031 		wpa_printf(MSG_INFO,
1032 			   "SCS: Drop received response due to no ongoing request");
1033 		return;
1034 	}
1035 
1036 	if (is_multicast_ether_addr(dst)) {
1037 		wpa_printf(MSG_DEBUG,
1038 			   "SCS: Ignore group-addressed SCS Response frame (A1="
1039 			   MACSTR " A2=" MACSTR ")",
1040 			   MAC2STR(dst), MAC2STR(src));
1041 		return;
1042 	}
1043 
1044 	dialog_token = *buf++;
1045 	len--;
1046 	if (dialog_token != wpa_s->scs_dialog_token) {
1047 		wpa_printf(MSG_INFO,
1048 			   "SCS: Drop received frame due to dialog token mismatch: received:%u expected:%u",
1049 			   dialog_token, wpa_s->scs_dialog_token);
1050 		return;
1051 	}
1052 
1053 	/* This Count field does not exist in the IEEE Std 802.11-2020
1054 	 * definition of the SCS Response frame. However, it was accepted to
1055 	 * be added into REVme per REVme/D0.0 CC35 CID 49 (edits in document
1056 	 * 11-21-0688-07). */
1057 	count = *buf++;
1058 	len--;
1059 	if (count == 0 || count * 3 > len) {
1060 		wpa_printf(MSG_INFO,
1061 			   "SCS: Drop received frame due to invalid count: %u (remaining %zu octets)",
1062 			   count, len);
1063 		return;
1064 	}
1065 
1066 	for (i = 0; i < count; i++) {
1067 		u8 id;
1068 		u16 status;
1069 		bool scs_desc_found = false;
1070 
1071 		id = *buf++;
1072 		status = WPA_GET_LE16(buf);
1073 		buf += 2;
1074 		len -= 3;
1075 
1076 		dl_list_for_each(scs_desc, &wpa_s->active_scs_ids,
1077 				 struct active_scs_elem, list) {
1078 			if (id == scs_desc->scs_id) {
1079 				scs_desc_found = true;
1080 				break;
1081 			}
1082 		}
1083 
1084 		if (!scs_desc_found) {
1085 			wpa_printf(MSG_INFO, "SCS: SCS ID invalid %u", id);
1086 			continue;
1087 		}
1088 
1089 		if (status == WLAN_STATUS_SUCCESS)
1090 			scs_desc->status = SCS_DESC_SUCCESS;
1091 		else
1092 			scs_cleanup_descriptors(scs_desc);
1093 
1094 		wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_SCS_RESULT "bssid=" MACSTR
1095 			" SCSID=%u status_code=%u", MAC2STR(src), id, status);
1096 	}
1097 
1098 	eloop_cancel_timeout(scs_request_timer, wpa_s, NULL);
1099 	wpa_s->ongoing_scs_req = false;
1100 
1101 	dl_list_for_each_safe(scs_desc, prev, &wpa_s->active_scs_ids,
1102 			      struct active_scs_elem, list) {
1103 		if (scs_desc->status != SCS_DESC_SUCCESS) {
1104 			wpa_msg(wpa_s, MSG_INFO,
1105 				WPA_EVENT_SCS_RESULT "bssid=" MACSTR
1106 				" SCSID=%u status_code=response_not_received",
1107 				MAC2STR(src), scs_desc->scs_id);
1108 			scs_cleanup_descriptors(scs_desc);
1109 		}
1110 	}
1111 }
1112 
1113 
wpas_clear_active_scs_ids(struct wpa_supplicant * wpa_s)1114 static void wpas_clear_active_scs_ids(struct wpa_supplicant *wpa_s)
1115 {
1116 	struct active_scs_elem *scs_elem;
1117 
1118 	while ((scs_elem = dl_list_first(&wpa_s->active_scs_ids,
1119 					 struct active_scs_elem, list))) {
1120 		scs_cleanup_descriptors(scs_elem);
1121 	}
1122 }
1123 
1124 
wpas_scs_deinit(struct wpa_supplicant * wpa_s)1125 void wpas_scs_deinit(struct wpa_supplicant *wpa_s)
1126 {
1127 	free_up_scs_desc(&wpa_s->scs_robust_av_req);
1128 	wpa_s->scs_dialog_token = 0;
1129 	wpas_clear_active_scs_ids(wpa_s);
1130 	eloop_cancel_timeout(scs_request_timer, wpa_s, NULL);
1131 	wpa_s->ongoing_scs_req = false;
1132 	wpa_s->scs_reconfigure = false;
1133 }
1134 
1135 
write_ipv4_info(char * pos,int total_len,const struct ipv4_params * v4,u8 classifier_mask)1136 static int write_ipv4_info(char *pos, int total_len,
1137 			   const struct ipv4_params *v4,
1138 			   u8 classifier_mask)
1139 {
1140 	int res, rem_len;
1141 	char addr[INET_ADDRSTRLEN];
1142 
1143 	rem_len = total_len;
1144 
1145 	if (classifier_mask & BIT(1)) {
1146 		if (!inet_ntop(AF_INET, &v4->src_ip, addr, INET_ADDRSTRLEN)) {
1147 			wpa_printf(MSG_ERROR,
1148 				   "QM: Failed to set IPv4 source address");
1149 			return -1;
1150 		}
1151 
1152 		res = os_snprintf(pos, rem_len, " src_ip=%s", addr);
1153 		if (os_snprintf_error(rem_len, res))
1154 			return -1;
1155 
1156 		pos += res;
1157 		rem_len -= res;
1158 	}
1159 
1160 	if (classifier_mask & BIT(2)) {
1161 		if (!inet_ntop(AF_INET, &v4->dst_ip, addr, INET_ADDRSTRLEN)) {
1162 			wpa_printf(MSG_ERROR,
1163 				   "QM: Failed to set IPv4 destination address");
1164 			return -1;
1165 		}
1166 
1167 		res = os_snprintf(pos, rem_len, " dst_ip=%s", addr);
1168 		if (os_snprintf_error(rem_len, res))
1169 			return -1;
1170 
1171 		pos += res;
1172 		rem_len -= res;
1173 	}
1174 
1175 	if (classifier_mask & BIT(3)) {
1176 		res = os_snprintf(pos, rem_len, " src_port=%d", v4->src_port);
1177 		if (os_snprintf_error(rem_len, res))
1178 			return -1;
1179 
1180 		pos += res;
1181 		rem_len -= res;
1182 	}
1183 
1184 	if (classifier_mask & BIT(4)) {
1185 		res = os_snprintf(pos, rem_len, " dst_port=%d", v4->dst_port);
1186 		if (os_snprintf_error(rem_len, res))
1187 			return -1;
1188 
1189 		pos += res;
1190 		rem_len -= res;
1191 	}
1192 
1193 	if (classifier_mask & BIT(6)) {
1194 		res = os_snprintf(pos, rem_len, " protocol=%d", v4->protocol);
1195 		if (os_snprintf_error(rem_len, res))
1196 			return -1;
1197 
1198 		pos += res;
1199 		rem_len -= res;
1200 	}
1201 
1202 	return total_len - rem_len;
1203 }
1204 
1205 
write_ipv6_info(char * pos,int total_len,const struct ipv6_params * v6,u8 classifier_mask)1206 static int write_ipv6_info(char *pos, int total_len,
1207 			   const struct ipv6_params *v6,
1208 			   u8 classifier_mask)
1209 {
1210 	int res, rem_len;
1211 	char addr[INET6_ADDRSTRLEN];
1212 
1213 	rem_len = total_len;
1214 
1215 	if (classifier_mask & BIT(1)) {
1216 		if (!inet_ntop(AF_INET6, &v6->src_ip, addr, INET6_ADDRSTRLEN)) {
1217 			wpa_printf(MSG_ERROR,
1218 				   "QM: Failed to set IPv6 source addr");
1219 			return -1;
1220 		}
1221 
1222 		res = os_snprintf(pos, rem_len, " src_ip=%s", addr);
1223 		if (os_snprintf_error(rem_len, res))
1224 			return -1;
1225 
1226 		pos += res;
1227 		rem_len -= res;
1228 	}
1229 
1230 	if (classifier_mask & BIT(2)) {
1231 		if (!inet_ntop(AF_INET6, &v6->dst_ip, addr, INET6_ADDRSTRLEN)) {
1232 			wpa_printf(MSG_ERROR,
1233 				   "QM: Failed to set IPv6 destination addr");
1234 			return -1;
1235 		}
1236 
1237 		res = os_snprintf(pos, rem_len, " dst_ip=%s", addr);
1238 		if (os_snprintf_error(rem_len, res))
1239 			return -1;
1240 
1241 		pos += res;
1242 		rem_len -= res;
1243 	}
1244 
1245 	if (classifier_mask & BIT(3)) {
1246 		res = os_snprintf(pos, rem_len, " src_port=%d", v6->src_port);
1247 		if (os_snprintf_error(rem_len, res))
1248 			return -1;
1249 
1250 		pos += res;
1251 		rem_len -= res;
1252 	}
1253 
1254 	if (classifier_mask & BIT(4)) {
1255 		res = os_snprintf(pos, rem_len, " dst_port=%d", v6->dst_port);
1256 		if (os_snprintf_error(rem_len, res))
1257 			return -1;
1258 
1259 		pos += res;
1260 		rem_len -= res;
1261 	}
1262 
1263 	if (classifier_mask & BIT(6)) {
1264 		res = os_snprintf(pos, rem_len, " protocol=%d",
1265 				  v6->next_header);
1266 		if (os_snprintf_error(rem_len, res))
1267 			return -1;
1268 
1269 		pos += res;
1270 		rem_len -= res;
1271 	}
1272 
1273 	return total_len - rem_len;
1274 }
1275 
1276 
1277 struct dscp_policy_data {
1278 	u8 policy_id;
1279 	u8 req_type;
1280 	u8 dscp;
1281 	bool dscp_info;
1282 	const u8 *frame_classifier;
1283 	u8 frame_classifier_len;
1284 	struct type4_params type4_param;
1285 	const u8 *domain_name;
1286 	u8 domain_name_len;
1287 	u16 start_port;
1288 	u16 end_port;
1289 	bool port_range_info;
1290 };
1291 
1292 
set_frame_classifier_type4_ipv4(struct dscp_policy_data * policy)1293 static int set_frame_classifier_type4_ipv4(struct dscp_policy_data *policy)
1294 {
1295 	u8 classifier_mask;
1296 	const u8 *frame_classifier = policy->frame_classifier;
1297 	struct type4_params *type4_param = &policy->type4_param;
1298 
1299 	if (policy->frame_classifier_len < 18) {
1300 		wpa_printf(MSG_ERROR,
1301 			   "QM: Received IPv4 frame classifier with insufficient length %d",
1302 			   policy->frame_classifier_len);
1303 		return -1;
1304 	}
1305 
1306 	classifier_mask = frame_classifier[1];
1307 
1308 	/* Classifier Mask - bit 1 = Source IP Address */
1309 	if (classifier_mask & BIT(1)) {
1310 		type4_param->classifier_mask |= BIT(1);
1311 		os_memcpy(&type4_param->ip_params.v4.src_ip,
1312 			  &frame_classifier[3], 4);
1313 	}
1314 
1315 	/* Classifier Mask - bit 2 = Destination IP Address */
1316 	if (classifier_mask & BIT(2)) {
1317 		if (policy->domain_name) {
1318 			wpa_printf(MSG_ERROR,
1319 				   "QM: IPv4: Both domain name and destination IP address not expected");
1320 			return -1;
1321 		}
1322 
1323 		type4_param->classifier_mask |= BIT(2);
1324 		os_memcpy(&type4_param->ip_params.v4.dst_ip,
1325 			  &frame_classifier[7], 4);
1326 	}
1327 
1328 	/* Classifier Mask - bit 3 = Source Port */
1329 	if (classifier_mask & BIT(3)) {
1330 		type4_param->classifier_mask |= BIT(3);
1331 		type4_param->ip_params.v4.src_port =
1332 			WPA_GET_BE16(&frame_classifier[11]);
1333 	}
1334 
1335 	/* Classifier Mask - bit 4 = Destination Port */
1336 	if (classifier_mask & BIT(4)) {
1337 		if (policy->port_range_info) {
1338 			wpa_printf(MSG_ERROR,
1339 				   "QM: IPv4: Both port range and destination port not expected");
1340 			return -1;
1341 		}
1342 
1343 		type4_param->classifier_mask |= BIT(4);
1344 		type4_param->ip_params.v4.dst_port =
1345 			WPA_GET_BE16(&frame_classifier[13]);
1346 	}
1347 
1348 	/* Classifier Mask - bit 5 = DSCP (ignored) */
1349 
1350 	/* Classifier Mask - bit 6 = Protocol */
1351 	if (classifier_mask & BIT(6)) {
1352 		type4_param->classifier_mask |= BIT(6);
1353 		type4_param->ip_params.v4.protocol = frame_classifier[16];
1354 	}
1355 
1356 	return 0;
1357 }
1358 
1359 
set_frame_classifier_type4_ipv6(struct dscp_policy_data * policy)1360 static int set_frame_classifier_type4_ipv6(struct dscp_policy_data *policy)
1361 {
1362 	u8 classifier_mask;
1363 	const u8 *frame_classifier = policy->frame_classifier;
1364 	struct type4_params *type4_param = &policy->type4_param;
1365 
1366 	if (policy->frame_classifier_len < 44) {
1367 		wpa_printf(MSG_ERROR,
1368 			   "QM: Received IPv6 frame classifier with insufficient length %d",
1369 			   policy->frame_classifier_len);
1370 		return -1;
1371 	}
1372 
1373 	classifier_mask = frame_classifier[1];
1374 
1375 	/* Classifier Mask - bit 1 = Source IP Address */
1376 	if (classifier_mask & BIT(1)) {
1377 		type4_param->classifier_mask |= BIT(1);
1378 		os_memcpy(&type4_param->ip_params.v6.src_ip,
1379 			  &frame_classifier[3], 16);
1380 	}
1381 
1382 	/* Classifier Mask - bit 2 = Destination IP Address */
1383 	if (classifier_mask & BIT(2)) {
1384 		if (policy->domain_name) {
1385 			wpa_printf(MSG_ERROR,
1386 				   "QM: IPv6: Both domain name and destination IP address not expected");
1387 			return -1;
1388 		}
1389 		type4_param->classifier_mask |= BIT(2);
1390 		os_memcpy(&type4_param->ip_params.v6.dst_ip,
1391 			  &frame_classifier[19], 16);
1392 	}
1393 
1394 	/* Classifier Mask - bit 3 = Source Port */
1395 	if (classifier_mask & BIT(3)) {
1396 		type4_param->classifier_mask |= BIT(3);
1397 		type4_param->ip_params.v6.src_port =
1398 				WPA_GET_BE16(&frame_classifier[35]);
1399 	}
1400 
1401 	/* Classifier Mask - bit 4 = Destination Port */
1402 	if (classifier_mask & BIT(4)) {
1403 		if (policy->port_range_info) {
1404 			wpa_printf(MSG_ERROR,
1405 				   "IPv6: Both port range and destination port not expected");
1406 			return -1;
1407 		}
1408 
1409 		type4_param->classifier_mask |= BIT(4);
1410 		type4_param->ip_params.v6.dst_port =
1411 				WPA_GET_BE16(&frame_classifier[37]);
1412 	}
1413 
1414 	/* Classifier Mask - bit 5 = DSCP (ignored) */
1415 
1416 	/* Classifier Mask - bit 6 = Next Header */
1417 	if (classifier_mask & BIT(6)) {
1418 		type4_param->classifier_mask |= BIT(6);
1419 		type4_param->ip_params.v6.next_header = frame_classifier[40];
1420 	}
1421 
1422 	return 0;
1423 }
1424 
1425 
wpas_set_frame_classifier_params(struct dscp_policy_data * policy)1426 static int wpas_set_frame_classifier_params(struct dscp_policy_data *policy)
1427 {
1428 	const u8 *frame_classifier = policy->frame_classifier;
1429 	u8 frame_classifier_len = policy->frame_classifier_len;
1430 
1431 	if (frame_classifier_len < 3) {
1432 		wpa_printf(MSG_ERROR,
1433 			   "QM: Received frame classifier with insufficient length %d",
1434 			   frame_classifier_len);
1435 		return -1;
1436 	}
1437 
1438 	/* Only allowed Classifier Type: IP and higher layer parameters (4) */
1439 	if (frame_classifier[0] != 4) {
1440 		wpa_printf(MSG_ERROR,
1441 			   "QM: Received frame classifier with invalid classifier type %d",
1442 			   frame_classifier[0]);
1443 		return -1;
1444 	}
1445 
1446 	/* Classifier Mask - bit 0 = Version */
1447 	if (!(frame_classifier[1] & BIT(0))) {
1448 		wpa_printf(MSG_ERROR,
1449 			   "QM: Received frame classifier without IP version");
1450 		return -1;
1451 	}
1452 
1453 	/* Version (4 or 6) */
1454 	if (frame_classifier[2] == 4) {
1455 		if (set_frame_classifier_type4_ipv4(policy)) {
1456 			wpa_printf(MSG_ERROR,
1457 				   "QM: Failed to set IPv4 parameters");
1458 			return -1;
1459 		}
1460 
1461 		policy->type4_param.ip_version = IPV4;
1462 	} else if (frame_classifier[2] == 6) {
1463 		if (set_frame_classifier_type4_ipv6(policy)) {
1464 			wpa_printf(MSG_ERROR,
1465 				   "QM: Failed to set IPv6 parameters");
1466 			return -1;
1467 		}
1468 
1469 		policy->type4_param.ip_version = IPV6;
1470 	} else {
1471 		wpa_printf(MSG_ERROR,
1472 			   "QM: Received unknown IP version %d",
1473 			   frame_classifier[2]);
1474 		return -1;
1475 	}
1476 
1477 	return 0;
1478 }
1479 
1480 
dscp_valid_domain_name(const char * str)1481 static bool dscp_valid_domain_name(const char *str)
1482 {
1483 	if (!str[0])
1484 		return false;
1485 
1486 	while (*str) {
1487 		if (is_ctrl_char(*str) || *str == ' ' || *str == '=')
1488 			return false;
1489 		str++;
1490 	}
1491 
1492 	return true;
1493 }
1494 
1495 
wpas_add_dscp_policy(struct wpa_supplicant * wpa_s,struct dscp_policy_data * policy)1496 static void wpas_add_dscp_policy(struct wpa_supplicant *wpa_s,
1497 				 struct dscp_policy_data *policy)
1498 {
1499 	int ip_ver = 0, res;
1500 	char policy_str[1000], *pos;
1501 	int len;
1502 
1503 	if (!policy->frame_classifier && !policy->domain_name &&
1504 	    !policy->port_range_info) {
1505 		wpa_printf(MSG_ERROR,
1506 			   "QM: Invalid DSCP policy - no attributes present");
1507 		goto fail;
1508 	}
1509 
1510 	policy_str[0] = '\0';
1511 	pos = policy_str;
1512 	len = sizeof(policy_str);
1513 
1514 	if (policy->frame_classifier) {
1515 		struct type4_params *type4 = &policy->type4_param;
1516 
1517 		if (wpas_set_frame_classifier_params(policy)) {
1518 			wpa_printf(MSG_ERROR,
1519 				   "QM: Failed to set frame classifier parameters");
1520 			goto fail;
1521 		}
1522 
1523 		if (type4->ip_version == IPV4)
1524 			res = write_ipv4_info(pos, len, &type4->ip_params.v4,
1525 					      type4->classifier_mask);
1526 		else
1527 			res = write_ipv6_info(pos, len, &type4->ip_params.v6,
1528 					      type4->classifier_mask);
1529 
1530 		if (res <= 0) {
1531 			wpa_printf(MSG_ERROR,
1532 				   "QM: Failed to write IP parameters");
1533 			goto fail;
1534 		}
1535 
1536 		ip_ver = type4->ip_version;
1537 
1538 		pos += res;
1539 		len -= res;
1540 	}
1541 
1542 	if (policy->port_range_info) {
1543 		res = os_snprintf(pos, len, " start_port=%u end_port=%u",
1544 				  policy->start_port, policy->end_port);
1545 		if (os_snprintf_error(len, res)) {
1546 			wpa_printf(MSG_ERROR,
1547 				   "QM: Failed to write port range attributes for policy id = %d",
1548 				   policy->policy_id);
1549 			goto fail;
1550 		}
1551 
1552 		pos += res;
1553 		len -= res;
1554 	}
1555 
1556 	if (policy->domain_name) {
1557 		char domain_name_str[250];
1558 
1559 		if (policy->domain_name_len >= sizeof(domain_name_str)) {
1560 			wpa_printf(MSG_ERROR,
1561 				   "QM: Domain name length higher than max expected");
1562 			goto fail;
1563 		}
1564 		os_memcpy(domain_name_str, policy->domain_name,
1565 			  policy->domain_name_len);
1566 		domain_name_str[policy->domain_name_len] = '\0';
1567 		if (!dscp_valid_domain_name(domain_name_str)) {
1568 			wpa_printf(MSG_ERROR, "QM: Invalid domain name string");
1569 			goto fail;
1570 		}
1571 		res = os_snprintf(pos, len, " domain_name=%s", domain_name_str);
1572 		if (os_snprintf_error(len, res)) {
1573 			wpa_printf(MSG_ERROR,
1574 				   "QM: Failed to write domain name attribute for policy id = %d",
1575 				   policy->policy_id);
1576 			goto fail;
1577 		}
1578 	}
1579 
1580 	wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY
1581 		"add policy_id=%u dscp=%u ip_version=%d%s",
1582 		policy->policy_id, policy->dscp, ip_ver, policy_str);
1583 	return;
1584 fail:
1585 	wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY "reject policy_id=%u",
1586 		policy->policy_id);
1587 }
1588 
1589 
wpas_dscp_deinit(struct wpa_supplicant * wpa_s)1590 void wpas_dscp_deinit(struct wpa_supplicant *wpa_s)
1591 {
1592 	wpa_printf(MSG_DEBUG, "QM: Clear all active DSCP policies");
1593 	wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY "clear_all");
1594 	wpa_s->dscp_req_dialog_token = 0;
1595 	wpa_s->dscp_query_dialog_token = 0;
1596 	wpa_s->connection_dscp = 0;
1597 	if (wpa_s->wait_for_dscp_req) {
1598 		wpa_s->wait_for_dscp_req = 0;
1599 		eloop_cancel_timeout(wpas_wait_for_dscp_req_timer, wpa_s, NULL);
1600 	}
1601 }
1602 
1603 
wpas_fill_dscp_policy(struct dscp_policy_data * policy,u8 attr_id,u8 attr_len,const u8 * attr_data)1604 static void wpas_fill_dscp_policy(struct dscp_policy_data *policy, u8 attr_id,
1605 				  u8 attr_len, const u8 *attr_data)
1606 {
1607 	switch (attr_id) {
1608 	case QM_ATTR_PORT_RANGE:
1609 		if (attr_len < 4) {
1610 			wpa_printf(MSG_ERROR,
1611 				   "QM: Received Port Range attribute with insufficient length %d",
1612 				    attr_len);
1613 			break;
1614 		}
1615 		policy->start_port = WPA_GET_BE16(attr_data);
1616 		policy->end_port = WPA_GET_BE16(attr_data + 2);
1617 		policy->port_range_info = true;
1618 		break;
1619 	case QM_ATTR_DSCP_POLICY:
1620 		if (attr_len < 3) {
1621 			wpa_printf(MSG_ERROR,
1622 				   "QM: Received DSCP Policy attribute with insufficient length %d",
1623 				   attr_len);
1624 			return;
1625 		}
1626 		policy->policy_id = attr_data[0];
1627 		policy->req_type = attr_data[1];
1628 		policy->dscp = attr_data[2];
1629 		policy->dscp_info = true;
1630 		break;
1631 	case QM_ATTR_TCLAS:
1632 		if (attr_len < 1) {
1633 			wpa_printf(MSG_ERROR,
1634 				   "QM: Received TCLAS attribute with insufficient length %d",
1635 				   attr_len);
1636 			return;
1637 		}
1638 		policy->frame_classifier = attr_data;
1639 		policy->frame_classifier_len = attr_len;
1640 		break;
1641 	case QM_ATTR_DOMAIN_NAME:
1642 		if (attr_len < 1) {
1643 			wpa_printf(MSG_ERROR,
1644 				   "QM: Received domain name attribute with insufficient length %d",
1645 				   attr_len);
1646 			return;
1647 		}
1648 		policy->domain_name = attr_data;
1649 		policy->domain_name_len = attr_len;
1650 		break;
1651 	default:
1652 		wpa_printf(MSG_ERROR, "QM: Received invalid QoS attribute %d",
1653 			   attr_id);
1654 		break;
1655 	}
1656 }
1657 
1658 
wpas_handle_qos_mgmt_recv_action(struct wpa_supplicant * wpa_s,const u8 * dst,const u8 * src,const u8 * buf,size_t len)1659 void wpas_handle_qos_mgmt_recv_action(struct wpa_supplicant *wpa_s,
1660 				      const u8 *dst, const u8 *src,
1661 				      const u8 *buf, size_t len)
1662 {
1663 	int rem_len;
1664 	const u8 *qos_ie, *attr;
1665 	int more, reset;
1666 
1667 	if (!wpa_s->enable_dscp_policy_capa) {
1668 		wpa_printf(MSG_ERROR,
1669 			   "QM: Ignore DSCP Policy frame since the capability is not enabled");
1670 		return;
1671 	}
1672 
1673 	if (!pmf_in_use(wpa_s, src)) {
1674 		wpa_printf(MSG_ERROR,
1675 			   "QM: Ignore DSCP Policy frame since PMF is not in use");
1676 		return;
1677 	}
1678 
1679 	if (!wpa_s->connection_dscp) {
1680 		 wpa_printf(MSG_DEBUG,
1681 			    "QM: DSCP Policy capability not enabled for the current association - ignore QoS Management Action frames");
1682 		return;
1683 	}
1684 
1685 	if (len < 1)
1686 		return;
1687 
1688 	/* Handle only DSCP Policy Request frame */
1689 	if (buf[0] != QM_DSCP_POLICY_REQ) {
1690 		wpa_printf(MSG_ERROR, "QM: Received unexpected QoS action frame %d",
1691 			   buf[0]);
1692 		return;
1693 	}
1694 
1695 	if (is_multicast_ether_addr(dst)) {
1696 		wpa_printf(MSG_DEBUG,
1697 			   "QM: Ignore group-addressed DSCP Policy Request frame (A1="
1698 			   MACSTR " A2=" MACSTR ")",
1699 			   MAC2STR(dst), MAC2STR(src));
1700 		return;
1701 	}
1702 
1703 	if (len < 3) {
1704 		wpa_printf(MSG_ERROR,
1705 			   "Received QoS Management DSCP Policy Request frame with invalid length %zu",
1706 			   len);
1707 		return;
1708 	}
1709 
1710 	/* Clear wait_for_dscp_req on receiving first DSCP request from AP */
1711 	if (wpa_s->wait_for_dscp_req) {
1712 		wpa_s->wait_for_dscp_req = 0;
1713 		eloop_cancel_timeout(wpas_wait_for_dscp_req_timer, wpa_s, NULL);
1714 	}
1715 
1716 	wpa_s->dscp_req_dialog_token = buf[1];
1717 	more = buf[2] & DSCP_POLICY_CTRL_MORE;
1718 	reset = buf[2] & DSCP_POLICY_CTRL_RESET;
1719 
1720 	wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY "request_start%s%s",
1721 		reset ? " clear_all" : "", more ? " more" : "");
1722 
1723 	qos_ie = buf + 3;
1724 	rem_len = len - 3;
1725 	while (rem_len > 2) {
1726 		struct dscp_policy_data policy;
1727 		int rem_attrs_len, ie_len;
1728 
1729 		ie_len = 2 + qos_ie[1];
1730 		if (rem_len < ie_len)
1731 			break;
1732 
1733 		if (rem_len < 6 || qos_ie[0] != WLAN_EID_VENDOR_SPECIFIC ||
1734 		    qos_ie[1] < 4 ||
1735 		    WPA_GET_BE32(&qos_ie[2]) != QM_IE_VENDOR_TYPE) {
1736 			rem_len -= ie_len;
1737 			qos_ie += ie_len;
1738 			continue;
1739 		}
1740 
1741 		os_memset(&policy, 0, sizeof(struct dscp_policy_data));
1742 		attr = qos_ie + 6;
1743 		rem_attrs_len = qos_ie[1] - 4;
1744 
1745 		while (rem_attrs_len > 2) {
1746 			u8 attr_id, attr_len;
1747 
1748 			attr_id = *attr++;
1749 			attr_len = *attr++;
1750 			rem_attrs_len -= 2;
1751 			if (attr_len > rem_attrs_len)
1752 				break;
1753 			wpas_fill_dscp_policy(&policy, attr_id, attr_len, attr);
1754 			rem_attrs_len -= attr_len;
1755 			attr += attr_len;
1756 		}
1757 
1758 		rem_len -= ie_len;
1759 		qos_ie += ie_len;
1760 
1761 		if (!policy.dscp_info) {
1762 			wpa_printf(MSG_ERROR,
1763 				   "QM: Received QoS IE without DSCP Policy attribute");
1764 			continue;
1765 		}
1766 
1767 		if (policy.req_type == DSCP_POLICY_REQ_ADD)
1768 			wpas_add_dscp_policy(wpa_s, &policy);
1769 		else if (policy.req_type == DSCP_POLICY_REQ_REMOVE)
1770 			wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY
1771 				"remove policy_id=%u", policy.policy_id);
1772 		else
1773 			wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY
1774 				"reject policy_id=%u", policy.policy_id);
1775 	}
1776 
1777 	wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY "request_end");
1778 }
1779 
1780 
wpas_send_dscp_response(struct wpa_supplicant * wpa_s,struct dscp_resp_data * resp_data)1781 int wpas_send_dscp_response(struct wpa_supplicant *wpa_s,
1782 			    struct dscp_resp_data *resp_data)
1783 {
1784 	struct wpabuf *buf = NULL;
1785 	size_t buf_len;
1786 	int ret = -1, i;
1787 	u8 resp_control = 0;
1788 
1789 	if (wpa_s->wpa_state != WPA_COMPLETED || !wpa_s->current_ssid) {
1790 		wpa_printf(MSG_ERROR,
1791 			   "QM: Failed to send DSCP response - not connected to AP");
1792 		return -1;
1793 	}
1794 
1795 	if (resp_data->solicited && !wpa_s->dscp_req_dialog_token) {
1796 		wpa_printf(MSG_ERROR, "QM: No ongoing DSCP request");
1797 		return -1;
1798 	}
1799 
1800 	if (!wpa_s->connection_dscp) {
1801 		wpa_printf(MSG_ERROR,
1802 			   "QM: Failed to send DSCP response - DSCP capability not enabled for the current association");
1803 		return -1;
1804 
1805 	}
1806 
1807 	buf_len = 1 +	/* Category */
1808 		  3 +	/* OUI */
1809 		  1 +	/* OUI Type */
1810 		  1 +	/* OUI Subtype */
1811 		  1 +	/* Dialog Token */
1812 		  1 +	/* Response Control */
1813 		  1 +	/* Count */
1814 		  2 * resp_data->num_policies;  /* Status list */
1815 	buf = wpabuf_alloc(buf_len);
1816 	if (!buf) {
1817 		wpa_printf(MSG_ERROR,
1818 			   "QM: Failed to allocate DSCP policy response");
1819 		return -1;
1820 	}
1821 
1822 	wpabuf_put_u8(buf, WLAN_ACTION_VENDOR_SPECIFIC_PROTECTED);
1823 	wpabuf_put_be24(buf, OUI_WFA);
1824 	wpabuf_put_u8(buf, QM_ACTION_OUI_TYPE);
1825 	wpabuf_put_u8(buf, QM_DSCP_POLICY_RESP);
1826 
1827 	wpabuf_put_u8(buf, resp_data->solicited ?
1828 		      wpa_s->dscp_req_dialog_token : 0);
1829 
1830 	if (resp_data->more)
1831 		resp_control |= DSCP_POLICY_CTRL_MORE;
1832 	if (resp_data->reset)
1833 		resp_control |= DSCP_POLICY_CTRL_RESET;
1834 	wpabuf_put_u8(buf, resp_control);
1835 
1836 	wpabuf_put_u8(buf, resp_data->num_policies);
1837 	for (i = 0; i < resp_data->num_policies; i++) {
1838 		wpabuf_put_u8(buf, resp_data->policy[i].id);
1839 		wpabuf_put_u8(buf, resp_data->policy[i].status);
1840 	}
1841 
1842 	wpa_hexdump_buf(MSG_MSGDUMP, "DSCP response frame: ", buf);
1843 	ret = wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
1844 				  wpa_s->own_addr, wpa_s->bssid,
1845 				  wpabuf_head(buf), wpabuf_len(buf), 0);
1846 	if (ret < 0) {
1847 		wpa_msg(wpa_s, MSG_INFO, "QM: Failed to send DSCP response");
1848 		goto fail;
1849 	}
1850 
1851 	/*
1852 	 * Mark DSCP request complete whether response sent is solicited or
1853 	 * unsolicited
1854 	 */
1855 	wpa_s->dscp_req_dialog_token = 0;
1856 
1857 fail:
1858 	wpabuf_free(buf);
1859 	return ret;
1860 }
1861 
1862 
wpas_send_dscp_query(struct wpa_supplicant * wpa_s,const char * domain_name,size_t domain_name_length)1863 int wpas_send_dscp_query(struct wpa_supplicant *wpa_s, const char *domain_name,
1864 			 size_t domain_name_length)
1865 {
1866 	struct wpabuf *buf = NULL;
1867 	int ret, dscp_query_size;
1868 
1869 	if (wpa_s->wpa_state != WPA_COMPLETED || !wpa_s->current_ssid)
1870 		return -1;
1871 
1872 	if (!wpa_s->connection_dscp) {
1873 		wpa_printf(MSG_ERROR,
1874 			   "QM: Failed to send DSCP query - DSCP capability not enabled for the current association");
1875 		return -1;
1876 	}
1877 
1878 	if (wpa_s->wait_for_dscp_req) {
1879 		wpa_printf(MSG_INFO, "QM: Wait until AP sends a DSCP request");
1880 		return -1;
1881 	}
1882 
1883 #define DOMAIN_NAME_OFFSET (4 /* OUI */ + 1 /* Attr Id */ + 1 /* Attr len */)
1884 
1885 	if (domain_name_length > 255 - DOMAIN_NAME_OFFSET) {
1886 		wpa_printf(MSG_ERROR, "QM: Too long domain name");
1887 		return -1;
1888 	}
1889 
1890 	dscp_query_size = 1 + /* Category */
1891 			  4 + /* OUI Type */
1892 			  1 + /* OUI subtype */
1893 			  1; /* Dialog Token */
1894 	if (domain_name && domain_name_length)
1895 		dscp_query_size += 1 + /* Element ID */
1896 			1 + /* IE Length */
1897 			DOMAIN_NAME_OFFSET + domain_name_length;
1898 
1899 	buf = wpabuf_alloc(dscp_query_size);
1900 	if (!buf) {
1901 		wpa_printf(MSG_ERROR, "QM: Failed to allocate DSCP query");
1902 		return -1;
1903 	}
1904 
1905 	wpabuf_put_u8(buf, WLAN_ACTION_VENDOR_SPECIFIC_PROTECTED);
1906 	wpabuf_put_be32(buf, QM_ACTION_VENDOR_TYPE);
1907 	wpabuf_put_u8(buf, QM_DSCP_POLICY_QUERY);
1908 	wpa_s->dscp_query_dialog_token++;
1909 	if (wpa_s->dscp_query_dialog_token == 0)
1910 		wpa_s->dscp_query_dialog_token++;
1911 	wpabuf_put_u8(buf, wpa_s->dscp_query_dialog_token);
1912 
1913 	if (domain_name && domain_name_length) {
1914 		/* Domain Name attribute */
1915 		wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC);
1916 		wpabuf_put_u8(buf, DOMAIN_NAME_OFFSET + domain_name_length);
1917 		wpabuf_put_be32(buf, QM_IE_VENDOR_TYPE);
1918 		wpabuf_put_u8(buf, QM_ATTR_DOMAIN_NAME);
1919 		wpabuf_put_u8(buf, domain_name_length);
1920 		wpabuf_put_data(buf, domain_name, domain_name_length);
1921 	}
1922 #undef DOMAIN_NAME_OFFSET
1923 
1924 	ret = wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
1925 				  wpa_s->own_addr, wpa_s->bssid,
1926 				  wpabuf_head(buf), wpabuf_len(buf), 0);
1927 	if (ret < 0) {
1928 		wpa_dbg(wpa_s, MSG_ERROR, "QM: Failed to send DSCP query");
1929 		wpa_s->dscp_query_dialog_token--;
1930 	}
1931 
1932 	wpabuf_free(buf);
1933 	return ret;
1934 }
1935