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