diff mbox series

[v2,1/3] ft: track FT auth/action response status

Message ID 20230829145116.279949-1-prestwoj@gmail.com (mailing list archive)
State New
Headers show
Series [v2,1/3] ft: track FT auth/action response status | expand

Checks

Context Check Description
tedd_an/pre-ci_am fail error: patch failed: src/ft.c:58 error: src/ft.c: patch does not apply hint: Use 'git am --show-current-patch' to see the failed patch

Commit Message

James Prestwood Aug. 29, 2023, 2:51 p.m. UTC
Certain return codes, though failures, can indicate that the AP is
just confused or booting up and treating it as a full failure may
not be the best route.

For example in some production deployments if an AP is rebooted it
may take some time for neighboring APs to exchange keys for
current associations. If a client roams during that time it will
reject saying the PMKID is invalid.

Use the ft_associate call return to communicate the status (if any)
that was in the auth/action response. If there was a parsing error
or no response -ENOENT is still returned.
---
 src/ft.c | 30 +++++++++++++++++++++---------
 1 file changed, 21 insertions(+), 9 deletions(-)

v2:
 * Remove 'parsed' and use the status instead. Status is now
   initialized to -ENOENT and only set to zero if parsing the
   IEs succeeds. If a non zero status reply comes in this is
   returned by ft_associate.

Comments

Denis Kenzior Aug. 31, 2023, 2:09 a.m. UTC | #1
Hi James,

On 8/29/23 09:51, James Prestwood wrote:
> Certain return codes, though failures, can indicate that the AP is
> just confused or booting up and treating it as a full failure may
> not be the best route.
> 
> For example in some production deployments if an AP is rebooted it
> may take some time for neighboring APs to exchange keys for
> current associations. If a client roams during that time it will
> reject saying the PMKID is invalid.
> 
> Use the ft_associate call return to communicate the status (if any)
> that was in the auth/action response. If there was a parsing error
> or no response -ENOENT is still returned.
> ---
>   src/ft.c | 30 +++++++++++++++++++++---------
>   1 file changed, 21 insertions(+), 9 deletions(-)
> 
> v2:
>   * Remove 'parsed' and use the status instead. Status is now
>     initialized to -ENOENT and only set to zero if parsing the
>     IEs succeeds. If a non zero status reply comes in this is
>     returned by ft_associate.
> 

<snip>

> @@ -527,8 +528,6 @@ static int ft_over_ds_parse_action_response(const uint8_t *frame,
>   		return -EINVAL;
>   
>   	status = l_get_le16(frame + 14);
> -	if (status != 0)
> -		return (int)status;

Hmm, this should really be kept since we shouldn't be assigning ies or ies_len 
in this case.

>   
>   	if (spa_out)
>   		*spa_out = spa;
> @@ -541,7 +540,7 @@ static int ft_over_ds_parse_action_response(const uint8_t *frame,
>   		*ies_len = frame_len - 16;
>   	}

Maybe something like:

if (spa_out)
	...

if (aa_out)
	...

status = l_get_le16(...);
if (status)
	goto done;

if (ies...)
	...

done:
	return (int) status;

This would also match how ft_parse_authentication_resp_frame() works.

>   
> -	return 0;
> +	return (int)status;
>   }
>   

Otherwise, LGTM.

Regards,
-Denis
diff mbox series

Patch

diff --git a/src/ft.c b/src/ft.c
index c51a1288..a7655d91 100644
--- a/src/ft.c
+++ b/src/ft.c
@@ -58,13 +58,14 @@  struct ft_info {
 	uint32_t frequency;
 	uint32_t ds_frequency;
 	uint32_t offchannel_id;
+	/* Status of Authenticate/Action frame response, or error (< 0) */
+	int status;
 
 	struct l_timeout *timeout;
 	struct wiphy_radio_work_item work;
 
 	struct ie_ft_info ft_info;
 
-	bool parsed : 1;
 	bool onchannel : 1;
 };
 
@@ -527,8 +528,6 @@  static int ft_over_ds_parse_action_response(const uint8_t *frame,
 		return -EINVAL;
 
 	status = l_get_le16(frame + 14);
-	if (status != 0)
-		return (int)status;
 
 	if (spa_out)
 		*spa_out = spa;
@@ -541,7 +540,7 @@  static int ft_over_ds_parse_action_response(const uint8_t *frame,
 		*ies_len = frame_len - 16;
 	}
 
-	return 0;
+	return (int)status;
 }
 
 int __ft_rx_associate(uint32_t ifindex, const uint8_t *frame, size_t frame_len)
@@ -825,7 +824,7 @@  void __ft_rx_action(uint32_t ifindex, const uint8_t *frame, size_t frame_len)
 
 	ret = ft_over_ds_parse_action_response(frame, frame_len, &spa, &aa,
 						&ies, &ies_len);
-	if (ret != 0) {
+	if (ret < 0) {
 		l_debug("Could not parse action response");
 		return;
 	}
@@ -836,13 +835,22 @@  void __ft_rx_action(uint32_t ifindex, const uint8_t *frame, size_t frame_len)
 		return;
 	}
 
+
+	if (ret != 0) {
+		l_debug("BSS "MAC" rejected FT action with status=%u",
+				MAC_STR(info->aa), ret);
+		info->status = ret;
+		goto done;
+	}
+
 	if (!ft_parse_ies(info, hs, ies, ies_len)) {
 		l_debug("Could not parse action response IEs");
 		goto ft_error;
 	}
 
-	info->parsed = true;
+	info->status = ret;
 
+done:
 	l_timeout_remove(info->timeout);
 	info->timeout = NULL;
 
@@ -872,6 +880,7 @@  static struct ft_info *ft_info_new(struct handshake_state *hs,
 						target_bss->rsne[1] + 2);
 
 	l_getrandom(info->snonce, 32);
+	info->status = -ENOENT;
 
 	return info;
 }
@@ -1016,6 +1025,7 @@  void __ft_rx_authenticate(uint32_t ifindex, const uint8_t *frame,
 	if (status != 0) {
 		l_debug("BSS "MAC" rejected FT auth with status=%u",
 				MAC_STR(info->aa), status);
+		info->status = status;
 		goto cancel;
 	}
 
@@ -1024,7 +1034,7 @@  void __ft_rx_authenticate(uint32_t ifindex, const uint8_t *frame,
 		goto cancel;
 	}
 
-	info->parsed = true;
+	info->status = status;
 
 cancel:
 	/*
@@ -1164,11 +1174,13 @@  int ft_associate(uint32_t ifindex, const uint8_t *addr)
 	 * Either failed or no response. This may have been an FT-over-DS
 	 * attempt so clear out the entry so FT-over-Air can try again.
 	 */
-	if (!info->parsed) {
+	if (info->status != 0) {
+		int status = info->status;
+
 		l_queue_remove(info_list, info);
 		ft_info_destroy(info);
 
-		return -ENOENT;
+		return status;
 	}
 
 	ft_prepare_handshake(info, hs);