]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
DSCP: Parse WFA Capabilities element in (Re)Association Response frame
authorVeerendranath Jakkam <vjakkam@codeaurora.org>
Thu, 29 Jul 2021 14:32:22 +0000 (20:02 +0530)
committerJouni Malinen <j@w1.fi>
Wed, 29 Sep 2021 14:18:48 +0000 (17:18 +0300)
Add support to parse WFA Capabilities element from the (Re)Association
Response frame. Also register a timeout for the station to wait before
sending a new DSCP query if requested by AP.

Signed-off-by: Veerendranath Jakkam <vjakkam@codeaurora.org>
wpa_supplicant/README
wpa_supplicant/events.c
wpa_supplicant/robust_av.c
wpa_supplicant/wpa_supplicant_i.h

index 231f166612f74cf3d19390f59acd0833df19633a..98cbf3e0a74ebded7bbbe071c9e98507ddf3c753 100644 (file)
@@ -1136,6 +1136,17 @@ is as shown below:
 - External applications shall clear active DSCP policies upon receiving
   "CTRL-EVENT-DISCONNECTED" or "CTRL-EVENT-DSCP-POLICY clear_all" events.
 
+- Control interface event message format to indicate wpa_supplicant started
+  a timer to wait until the unsolicited DSCP request from the AP.
+
+  <3>CTRL-EVENT-DSCP-POLICY request_wait start
+
+- Control interface event message format to indicate timeout to receive the
+  unsolicited DSCP request. This event is expected only when an unsolicited
+  DSCP request is not received from the AP before timeout.
+
+  <3>CTRL-EVENT-DSCP-POLICY request_wait end
+
 DSCP Response:
 A QoS Management STA that enables DSCP Policy capability shall respond
 with DSCP response on receipt of a successful DSCP request from its
index e9af7585bf7b5bd5e5f05fd8618f438ed52c58c1..72a2a9c156c53d7e93c620d868a6902c88640d6d 100644 (file)
@@ -2977,6 +2977,9 @@ no_pfs:
 
        wpa_s->assoc_freq = data->assoc_info.freq;
 
+       wpas_handle_assoc_resp_qos_mgmt(wpa_s, data->assoc_info.resp_ies,
+                                       data->assoc_info.resp_ies_len);
+
        return 0;
 }
 
index eed140dbc7f206db6c73888875481d52bef350ac..4eabf2448b4bf6baf21ed678293404aae19febc6 100644 (file)
@@ -17,6 +17,7 @@
 
 
 #define SCS_RESP_TIMEOUT 1
+#define DSCP_REQ_TIMEOUT 5
 
 
 void wpas_populate_mscs_descriptor_ie(struct robust_av_data *robust_av,
@@ -550,6 +551,48 @@ void wpas_handle_assoc_resp_mscs(struct wpa_supplicant *wpa_s, const u8 *bssid,
 }
 
 
+static void wpas_wait_for_dscp_req_timer(void *eloop_ctx, void *timeout_ctx)
+{
+       struct wpa_supplicant *wpa_s = eloop_ctx;
+
+       /* Once timeout is over, reset wait flag and allow sending DSCP query */
+       wpa_printf(MSG_DEBUG,
+                  "QM: Wait time over for sending DSCP request - allow DSCP query");
+       wpa_s->wait_for_dscp_req = 0;
+       wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY "request_wait end");
+}
+
+
+void wpas_handle_assoc_resp_qos_mgmt(struct wpa_supplicant *wpa_s,
+                                    const u8 *ies, size_t ies_len)
+{
+       const u8 *wfa_capa;
+
+       wpa_s->connection_dscp = 0;
+       if (wpa_s->wait_for_dscp_req)
+               eloop_cancel_timeout(wpas_wait_for_dscp_req_timer, wpa_s, NULL);
+
+       if (!ies || ies_len == 0 || !wpa_s->enable_dscp_policy_capa)
+               return;
+
+       wfa_capa = get_vendor_ie(ies, ies_len, WFA_CAPA_IE_VENDOR_TYPE);
+       if (!wfa_capa || wfa_capa[1] < 6 || wfa_capa[6] < 1 ||
+           !(wfa_capa[7] & WFA_CAPA_QM_DSCP_POLICY))
+               return; /* AP does not enable QM DSCP Policy */
+
+       wpa_s->connection_dscp = 1;
+       wpa_s->wait_for_dscp_req = !!(wfa_capa[7] &
+                                     WFA_CAPA_QM_UNSOLIC_DSCP);
+       if (!wpa_s->wait_for_dscp_req)
+               return;
+
+       /* Register a timeout after which dscp query can be sent to AP. */
+       wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY "request_wait start");
+       eloop_register_timeout(DSCP_REQ_TIMEOUT, 0,
+                              wpas_wait_for_dscp_req_timer, wpa_s, NULL);
+}
+
+
 void wpas_handle_robust_av_scs_recv_action(struct wpa_supplicant *wpa_s,
                                           const u8 *src, const u8 *buf,
                                           size_t len)
@@ -1116,6 +1159,11 @@ void wpas_dscp_deinit(struct wpa_supplicant *wpa_s)
        wpa_printf(MSG_DEBUG, "QM: Clear all active DSCP policies");
        wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY "clear_all");
        wpa_s->dscp_req_dialog_token = 0;
+       wpa_s->connection_dscp = 0;
+       if (wpa_s->wait_for_dscp_req) {
+               wpa_s->wait_for_dscp_req = 0;
+               eloop_cancel_timeout(wpas_wait_for_dscp_req_timer, wpa_s, NULL);
+       }
 }
 
 
@@ -1194,6 +1242,12 @@ void wpas_handle_qos_mgmt_recv_action(struct wpa_supplicant *wpa_s,
                return;
        }
 
+       if (!wpa_s->connection_dscp) {
+                wpa_printf(MSG_DEBUG,
+                           "QM: DSCP Policy capability not enabled for the current association - ignore QoS Management Action frames");
+               return;
+       }
+
        if (len < 1)
                return;
 
@@ -1211,6 +1265,12 @@ void wpas_handle_qos_mgmt_recv_action(struct wpa_supplicant *wpa_s,
                return;
        }
 
+       /* Clear wait_for_dscp_req on receiving first DSCP request from AP */
+       if (wpa_s->wait_for_dscp_req) {
+               wpa_s->wait_for_dscp_req = 0;
+               eloop_cancel_timeout(wpas_wait_for_dscp_req_timer, wpa_s, NULL);
+       }
+
        wpa_s->dscp_req_dialog_token = buf[1];
        more = buf[2] & DSCP_POLICY_CTRL_MORE;
        reset = buf[2] & DSCP_POLICY_CTRL_RESET;
@@ -1289,6 +1349,13 @@ int wpas_send_dscp_response(struct wpa_supplicant *wpa_s,
                return -1;
        }
 
+       if (!wpa_s->connection_dscp) {
+               wpa_printf(MSG_ERROR,
+                          "QM: Failed to send DSCP response - DSCP capability not enabled for the current association");
+               return -1;
+
+       }
+
        buf_len = 1 +   /* Category */
                  3 +   /* OUI */
                  1 +   /* OUI Type */
index 93a38635583e567a0f2eb18d624bc1a84ad435a0..428dfe8e6a5ce7f2ea9c55a3e1ba12cd039f43bb 100644 (file)
@@ -1515,6 +1515,8 @@ struct wpa_supplicant {
        bool ongoing_scs_req;
        u8 dscp_req_dialog_token;
        unsigned int enable_dscp_policy_capa:1;
+       unsigned int connection_dscp:1;
+       unsigned int wait_for_dscp_req:1;
 };
 
 
@@ -1861,6 +1863,8 @@ void wpas_handle_qos_mgmt_recv_action(struct wpa_supplicant *wpa_s,
 void wpas_dscp_deinit(struct wpa_supplicant *wpa_s);
 int wpas_send_dscp_response(struct wpa_supplicant *wpa_s,
                            struct dscp_resp_data *resp_data);
+void wpas_handle_assoc_resp_qos_mgmt(struct wpa_supplicant *wpa_s,
+                                    const u8 *ies, size_t ies_len);
 
 int wpas_pasn_auth_start(struct wpa_supplicant *wpa_s,
                         const u8 *bssid, int akmp, int cipher,