NAN: Handle A3 copying internally to simplify control interface

There is no need to copy the A3 value for follow-up frames through the
control interface events and commands since it can be handled internally
in the service with sufficient accuracy. More parallel operations with
multiple peers might need per-peer information, but that can be extended
in the future, if that level of complexity is really needed in practice.

Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
This commit is contained in:
Jouni Malinen 2024-09-14 12:54:04 +03:00 committed by Jouni Malinen
parent 650d1ab600
commit b3bd49f3c0
10 changed files with 31 additions and 47 deletions

View file

@ -3976,12 +3976,10 @@ static int hostapd_ctrl_nan_transmit(struct hostapd_data *hapd, char *cmd)
int handle = 0; int handle = 0;
int req_instance_id = 0; int req_instance_id = 0;
struct wpabuf *ssi = NULL; struct wpabuf *ssi = NULL;
u8 peer_addr[ETH_ALEN], a3[ETH_ALEN]; u8 peer_addr[ETH_ALEN];
int ret = -1; int ret = -1;
bool a3_set = false;
os_memset(peer_addr, 0, ETH_ALEN); os_memset(peer_addr, 0, ETH_ALEN);
os_memset(a3, 0, ETH_ALEN);
while ((token = str_token(cmd, " ", &context))) { while ((token = str_token(cmd, " ", &context))) {
if (sscanf(token, "handle=%i", &handle) == 1) if (sscanf(token, "handle=%i", &handle) == 1)
@ -3996,13 +3994,6 @@ static int hostapd_ctrl_nan_transmit(struct hostapd_data *hapd, char *cmd)
continue; continue;
} }
if (os_strncmp(token, "a3=", 3) == 0) {
if (hwaddr_aton(token + 3, a3) < 0)
return -1;
a3_set = true;
continue;
}
if (os_strncmp(token, "ssi=", 4) == 0) { if (os_strncmp(token, "ssi=", 4) == 0) {
if (ssi) if (ssi)
goto fail; goto fail;
@ -4031,7 +4022,7 @@ static int hostapd_ctrl_nan_transmit(struct hostapd_data *hapd, char *cmd)
} }
ret = hostapd_nan_usd_transmit(hapd, handle, ssi, NULL, peer_addr, ret = hostapd_nan_usd_transmit(hapd, handle, ssi, NULL, peer_addr,
a3_set ? a3 : NULL, req_instance_id); req_instance_id);
fail: fail:
wpabuf_free(ssi); wpabuf_free(ssi);
return ret; return ret;

View file

@ -129,7 +129,7 @@ static void hostapd_nan_de_subscribe_terminated(void *ctx, int subscribe_id,
static void hostapd_nan_de_receive(void *ctx, int id, int peer_instance_id, static void hostapd_nan_de_receive(void *ctx, int id, int peer_instance_id,
const u8 *ssi, size_t ssi_len, const u8 *ssi, size_t ssi_len,
const u8 *peer_addr, const u8 *a3) const u8 *peer_addr)
{ {
struct hostapd_data *hapd = ctx; struct hostapd_data *hapd = ctx;
char *ssi_hex; char *ssi_hex;
@ -140,9 +140,8 @@ static void hostapd_nan_de_receive(void *ctx, int id, int peer_instance_id,
if (ssi) if (ssi)
wpa_snprintf_hex(ssi_hex, 2 * ssi_len + 1, ssi, ssi_len); wpa_snprintf_hex(ssi_hex, 2 * ssi_len + 1, ssi, ssi_len);
wpa_msg(hapd->msg_ctx, MSG_INFO, NAN_RECEIVE wpa_msg(hapd->msg_ctx, MSG_INFO, NAN_RECEIVE
"id=%d peer_instance_id=%d address=" MACSTR " a3=" MACSTR "id=%d peer_instance_id=%d address=" MACSTR " ssi=%s",
" ssi=%s", id, peer_instance_id, MAC2STR(peer_addr), ssi_hex);
id, peer_instance_id, MAC2STR(peer_addr), MAC2STR(a3), ssi_hex);
os_free(ssi_hex); os_free(ssi_hex);
} }
@ -262,11 +261,11 @@ void hostapd_nan_usd_cancel_subscribe(struct hostapd_data *hapd,
int hostapd_nan_usd_transmit(struct hostapd_data *hapd, int handle, int hostapd_nan_usd_transmit(struct hostapd_data *hapd, int handle,
const struct wpabuf *ssi, const struct wpabuf *ssi,
const struct wpabuf *elems, const struct wpabuf *elems,
const u8 *peer_addr, const u8 *a3, const u8 *peer_addr,
u8 req_instance_id) u8 req_instance_id)
{ {
if (!hapd->nan_de) if (!hapd->nan_de)
return -1; return -1;
return nan_de_transmit(hapd->nan_de, handle, ssi, elems, peer_addr, a3, return nan_de_transmit(hapd->nan_de, handle, ssi, elems, peer_addr,
req_instance_id); req_instance_id);
} }

View file

@ -36,8 +36,7 @@ void hostapd_nan_usd_cancel_subscribe(struct hostapd_data *hapd,
int hostapd_nan_usd_transmit(struct hostapd_data *hapd, int handle, int hostapd_nan_usd_transmit(struct hostapd_data *hapd, int handle,
const struct wpabuf *ssi, const struct wpabuf *ssi,
const struct wpabuf *elems, const struct wpabuf *elems,
const u8 *peer_addr, const u8 *a3, const u8 *peer_addr, u8 req_instance_id);
u8 req_instance_id);
void hostapd_nan_usd_remain_on_channel_cb(struct hostapd_data *hapd, void hostapd_nan_usd_remain_on_channel_cb(struct hostapd_data *hapd,
unsigned int freq, unsigned int freq,
unsigned int duration); unsigned int duration);

View file

@ -43,6 +43,8 @@ struct nan_de_service {
unsigned int freq; unsigned int freq;
unsigned int default_freq; unsigned int default_freq;
int *freq_list; int *freq_list;
u8 a3[ETH_ALEN];
bool a3_set;
/* pauseState information for Publish function */ /* pauseState information for Publish function */
struct os_reltime pause_state_end; struct os_reltime pause_state_end;
@ -829,7 +831,7 @@ static void nan_de_rx_publish(struct nan_de *de, struct nan_de_service *srv,
/* Passive subscriber replies with a Follow-up message without /* Passive subscriber replies with a Follow-up message without
* Service Specific Info field if it received a matching * Service Specific Info field if it received a matching
* unsolicited Publish message. */ * unsolicited Publish message. */
nan_de_transmit(de, srv->id, NULL, NULL, peer_addr, a3, nan_de_transmit(de, srv->id, NULL, NULL, peer_addr,
instance_id); instance_id);
} }
@ -1004,9 +1006,12 @@ static void nan_de_rx_follow_up(struct nan_de *de, struct nan_de_service *srv,
if (srv->type == NAN_DE_PUBLISH && !ssi) if (srv->type == NAN_DE_PUBLISH && !ssi)
nan_de_pause_state(srv, peer_addr, instance_id); nan_de_pause_state(srv, peer_addr, instance_id);
os_memcpy(srv->a3, a3, ETH_ALEN);
srv->a3_set = true;
if (de->cb.receive) if (de->cb.receive)
de->cb.receive(de->cb.ctx, srv->id, instance_id, ssi, ssi_len, de->cb.receive(de->cb.ctx, srv->id, instance_id, ssi, ssi_len,
peer_addr, a3); peer_addr);
} }
@ -1441,9 +1446,10 @@ void nan_de_cancel_subscribe(struct nan_de *de, int subscribe_id)
int nan_de_transmit(struct nan_de *de, int handle, int nan_de_transmit(struct nan_de *de, int handle,
const struct wpabuf *ssi, const struct wpabuf *elems, const struct wpabuf *ssi, const struct wpabuf *elems,
const u8 *peer_addr, const u8 *a3, u8 req_instance_id) const u8 *peer_addr, u8 req_instance_id)
{ {
struct nan_de_service *srv; struct nan_de_service *srv;
const u8 *a3;
if (handle < 1 || handle > NAN_DE_MAX_SERVICE) if (handle < 1 || handle > NAN_DE_MAX_SERVICE)
return -1; return -1;
@ -1452,7 +1458,9 @@ int nan_de_transmit(struct nan_de *de, int handle,
if (!srv) if (!srv)
return -1; return -1;
if (!a3) if (srv->a3_set)
a3 = srv->a3;
else
a3 = nan_network_id; a3 = nan_network_id;
nan_de_tx_sdf(de, srv, 100, NAN_SRV_CTRL_FOLLOW_UP, nan_de_tx_sdf(de, srv, 100, NAN_SRV_CTRL_FOLLOW_UP,
peer_addr, a3, req_instance_id, ssi); peer_addr, a3, req_instance_id, ssi);

View file

@ -52,7 +52,7 @@ struct nan_callbacks {
void (*receive)(void *ctx, int id, int peer_instance_id, void (*receive)(void *ctx, int id, int peer_instance_id,
const u8 *ssi, size_t ssi_len, const u8 *ssi, size_t ssi_len,
const u8 *peer_addr, const u8 *a3); const u8 *peer_addr);
void (*process_p2p_usd_elems)(void *ctx, const u8 *buf, void (*process_p2p_usd_elems)(void *ctx, const u8 *buf,
u16 buf_len, const u8 *peer_addr, u16 buf_len, const u8 *peer_addr,
@ -149,6 +149,6 @@ void nan_de_cancel_subscribe(struct nan_de *de, int subscribe_id);
* req_instance_id = peer publish_id or subscribe_id */ * req_instance_id = peer publish_id or subscribe_id */
int nan_de_transmit(struct nan_de *de, int handle, int nan_de_transmit(struct nan_de *de, int handle,
const struct wpabuf *ssi, const struct wpabuf *elems, const struct wpabuf *ssi, const struct wpabuf *elems,
const u8 *peer_addr, const u8 *a3, u8 req_instance_id); const u8 *peer_addr, u8 req_instance_id);
#endif /* NAN_DE_H */ #endif /* NAN_DE_H */

View file

@ -12514,12 +12514,10 @@ static int wpas_ctrl_nan_transmit(struct wpa_supplicant *wpa_s, char *cmd)
int handle = 0; int handle = 0;
int req_instance_id = 0; int req_instance_id = 0;
struct wpabuf *ssi = NULL; struct wpabuf *ssi = NULL;
u8 peer_addr[ETH_ALEN], a3[ETH_ALEN]; u8 peer_addr[ETH_ALEN];
int ret = -1; int ret = -1;
bool a3_set = false;
os_memset(peer_addr, 0, ETH_ALEN); os_memset(peer_addr, 0, ETH_ALEN);
os_memset(a3, 0, ETH_ALEN);
while ((token = str_token(cmd, " ", &context))) { while ((token = str_token(cmd, " ", &context))) {
if (sscanf(token, "handle=%i", &handle) == 1) if (sscanf(token, "handle=%i", &handle) == 1)
@ -12534,13 +12532,6 @@ static int wpas_ctrl_nan_transmit(struct wpa_supplicant *wpa_s, char *cmd)
continue; continue;
} }
if (os_strncmp(token, "a3=", 3) == 0) {
if (hwaddr_aton(token + 3, a3) < 0)
return -1;
a3_set = true;
continue;
}
if (os_strncmp(token, "ssi=", 4) == 0) { if (os_strncmp(token, "ssi=", 4) == 0) {
if (ssi) if (ssi)
goto fail; goto fail;
@ -12569,7 +12560,7 @@ static int wpas_ctrl_nan_transmit(struct wpa_supplicant *wpa_s, char *cmd)
} }
ret = wpas_nan_usd_transmit(wpa_s, handle, ssi, NULL, peer_addr, ret = wpas_nan_usd_transmit(wpa_s, handle, ssi, NULL, peer_addr,
a3_set ? a3 : NULL, req_instance_id); req_instance_id);
fail: fail:
wpabuf_free(ssi); wpabuf_free(ssi);
return ret; return ret;

View file

@ -282,11 +282,11 @@ static void wpas_nan_de_subscribe_terminated(void *ctx, int subscribe_id,
static void wpas_nan_de_receive(void *ctx, int id, int peer_instance_id, static void wpas_nan_de_receive(void *ctx, int id, int peer_instance_id,
const u8 *ssi, size_t ssi_len, const u8 *ssi, size_t ssi_len,
const u8 *peer_addr, const u8 *a3) const u8 *peer_addr)
{ {
struct wpa_supplicant *wpa_s = ctx; struct wpa_supplicant *wpa_s = ctx;
wpas_notify_nan_receive(wpa_s, id, peer_instance_id, peer_addr, a3, wpas_notify_nan_receive(wpa_s, id, peer_instance_id, peer_addr,
ssi, ssi_len); ssi, ssi_len);
} }
@ -467,11 +467,11 @@ void wpas_nan_usd_cancel_subscribe(struct wpa_supplicant *wpa_s,
int wpas_nan_usd_transmit(struct wpa_supplicant *wpa_s, int handle, int wpas_nan_usd_transmit(struct wpa_supplicant *wpa_s, int handle,
const struct wpabuf *ssi, const struct wpabuf *elems, const struct wpabuf *ssi, const struct wpabuf *elems,
const u8 *peer_addr, const u8 *a3, u8 req_instance_id) const u8 *peer_addr, u8 req_instance_id)
{ {
if (!wpa_s->nan_de) if (!wpa_s->nan_de)
return -1; return -1;
return nan_de_transmit(wpa_s->nan_de, handle, ssi, elems, peer_addr, a3, return nan_de_transmit(wpa_s->nan_de, handle, ssi, elems, peer_addr,
req_instance_id); req_instance_id);
} }

View file

@ -35,8 +35,7 @@ void wpas_nan_usd_cancel_subscribe(struct wpa_supplicant *wpa_s,
int subscribe_id); int subscribe_id);
int wpas_nan_usd_transmit(struct wpa_supplicant *wpa_s, int handle, int wpas_nan_usd_transmit(struct wpa_supplicant *wpa_s, int handle,
const struct wpabuf *ssi, const struct wpabuf *elems, const struct wpabuf *ssi, const struct wpabuf *elems,
const u8 *peer_addr, const u8 *a3, const u8 *peer_addr, u8 req_instance_id);
u8 req_instance_id);
void wpas_nan_usd_remain_on_channel_cb(struct wpa_supplicant *wpa_s, void wpas_nan_usd_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
unsigned int freq, unsigned int freq,
unsigned int duration); unsigned int duration);

View file

@ -1121,7 +1121,6 @@ void wpas_notify_nan_replied(struct wpa_supplicant *wpa_s,
void wpas_notify_nan_receive(struct wpa_supplicant *wpa_s, int id, void wpas_notify_nan_receive(struct wpa_supplicant *wpa_s, int id,
int peer_instance_id, const u8 *peer_addr, int peer_instance_id, const u8 *peer_addr,
const u8 *a3,
const u8 *ssi, size_t ssi_len) const u8 *ssi, size_t ssi_len)
{ {
char *ssi_hex; char *ssi_hex;
@ -1132,9 +1131,8 @@ void wpas_notify_nan_receive(struct wpa_supplicant *wpa_s, int id,
if (ssi) if (ssi)
wpa_snprintf_hex(ssi_hex, 2 * ssi_len + 1, ssi, ssi_len); wpa_snprintf_hex(ssi_hex, 2 * ssi_len + 1, ssi, ssi_len);
wpa_msg(wpa_s, MSG_INFO, NAN_RECEIVE wpa_msg(wpa_s, MSG_INFO, NAN_RECEIVE
"id=%d peer_instance_id=%d address=" MACSTR " a3=" MACSTR "id=%d peer_instance_id=%d address=" MACSTR " ssi=%s",
" ssi=%s", id, peer_instance_id, MAC2STR(peer_addr), ssi_hex);
id, peer_instance_id, MAC2STR(peer_addr), MAC2STR(a3), ssi_hex);
os_free(ssi_hex); os_free(ssi_hex);
} }

View file

@ -192,7 +192,6 @@ void wpas_notify_nan_replied(struct wpa_supplicant *wpa_s,
const u8 *ssi, size_t ssi_len); const u8 *ssi, size_t ssi_len);
void wpas_notify_nan_receive(struct wpa_supplicant *wpa_s, int id, void wpas_notify_nan_receive(struct wpa_supplicant *wpa_s, int id,
int peer_instance_id, const u8 *peer_addr, int peer_instance_id, const u8 *peer_addr,
const u8 *a3,
const u8 *ssi, size_t ssi_len); const u8 *ssi, size_t ssi_len);
void wpas_notify_nan_publish_terminated(struct wpa_supplicant *wpa_s, void wpas_notify_nan_publish_terminated(struct wpa_supplicant *wpa_s,
int publish_id, int publish_id,