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