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