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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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