[RFC PATCH 3/6] NAN: Add support for publishing proxied services
Benjamin Berg
benjamin at sipsolutions.net
Thu Feb 19 07:55:50 PST 2026
From: Benjamin Berg <benjamin.berg at intel.com>
This adds the ability to publish a proxied service by wrapping the
attributes in the appropriate Proxy Meta attribute.
Signed-off-by: Benjamin Berg <benjamin.berg at intel.com>
---
src/common/nan_de.c | 61 +++++++++++++++++++++++----------
src/common/nan_de.h | 4 +++
wpa_supplicant/nan_supplicant.c | 4 ++-
3 files changed, 50 insertions(+), 19 deletions(-)
diff --git a/src/common/nan_de.c b/src/common/nan_de.c
index 95d6c5621b..396b5fa5bc 100644
--- a/src/common/nan_de.c
+++ b/src/common/nan_de.c
@@ -273,6 +273,10 @@ static size_t nan_de_sdf_attrs_put(struct wpabuf *buf, struct nan_de *de,
u8 ctrl = type;
u16 sdea_ctrl = 0;
+ /* Proxy attribute, proxy attribute length and NMI address */
+ if (srv->publish.origin_id)
+ len += NAN_ATTR_HDR_LEN + ETH_ALEN;
+
/* Service Descriptor attribute */
sda_len = NAN_SERVICE_ID_LEN + 1 + 1 + 1;
if (srv->matching_filter_tx && wpabuf_len(srv->matching_filter_tx)) {
@@ -296,7 +300,14 @@ static size_t nan_de_sdf_attrs_put(struct wpabuf *buf, struct nan_de *de,
sdea_len = 1 + 2;
if (ssi)
sdea_len += 2 + 4 + wpabuf_len(ssi);
- len += NAN_ATTR_HDR_LEN + sdea_len;
+ if (srv->type == NAN_DE_PUBLISH) {
+ if (srv->publish.fsd)
+ sdea_ctrl |= NAN_SDEA_CTRL_FSD_REQ;
+ if (srv->publish.fsd_gas)
+ sdea_ctrl |= NAN_SDEA_CTRL_FSD_GAS;
+ }
+ if (ssi || sdea_ctrl)
+ len += NAN_ATTR_HDR_LEN + sdea_len;
/* Element Container attribute */
if (srv->elems)
@@ -306,11 +317,18 @@ static size_t nan_de_sdf_attrs_put(struct wpabuf *buf, struct nan_de *de,
if (!buf)
return len;
+ /* NAN Proxy Meta attribute */
+ if (srv->publish.origin_id) {
+ wpabuf_put_u8(buf, NAN_ATTR_PROXY_META);
+ wpabuf_put_le16(buf, len - NAN_ATTR_HDR_LEN);
+ wpabuf_put_data(buf, srv->publish.origin_nmi, ETH_ALEN);
+ }
+
/* Service Descriptor attribute */
wpabuf_put_u8(buf, NAN_ATTR_SDA);
wpabuf_put_le16(buf, sda_len);
wpabuf_put_data(buf, srv->service_id, NAN_SERVICE_ID_LEN);
- wpabuf_put_u8(buf, srv->id); /* Instance ID */
+ wpabuf_put_u8(buf, srv->publish.origin_id ?: srv->id);
wpabuf_put_u8(buf, req_instance_id); /* Requestor Instance ID */
wpabuf_put_u8(buf, ctrl);
@@ -337,21 +355,17 @@ static size_t nan_de_sdf_attrs_put(struct wpabuf *buf, struct nan_de *de,
/* Service Descriptor Extension attribute */
if (srv->type == NAN_DE_PUBLISH || ssi) {
- wpabuf_put_u8(buf, NAN_ATTR_SDEA);
- wpabuf_put_le16(buf, sdea_len);
- wpabuf_put_u8(buf, srv->id); /* Instance ID */
- if (srv->type == NAN_DE_PUBLISH) {
- if (srv->publish.fsd)
- sdea_ctrl |= NAN_SDEA_CTRL_FSD_REQ;
- if (srv->publish.fsd_gas)
- sdea_ctrl |= NAN_SDEA_CTRL_FSD_GAS;
- }
- wpabuf_put_le16(buf, sdea_ctrl);
- if (ssi) {
- wpabuf_put_le16(buf, 4 + wpabuf_len(ssi));
- wpabuf_put_be24(buf, OUI_WFA);
- wpabuf_put_u8(buf, srv->srv_proto_type);
- wpabuf_put_buf(buf, ssi);
+ if (sdea_ctrl || ssi) {
+ wpabuf_put_u8(buf, NAN_ATTR_SDEA);
+ wpabuf_put_le16(buf, sdea_len);
+ wpabuf_put_u8(buf, srv->id); /* Instance ID */
+ wpabuf_put_le16(buf, sdea_ctrl);
+ if (ssi) {
+ wpabuf_put_le16(buf, 4 + wpabuf_len(ssi));
+ wpabuf_put_be24(buf, OUI_WFA);
+ wpabuf_put_u8(buf, srv->srv_proto_type);
+ wpabuf_put_buf(buf, ssi);
+ }
}
}
@@ -1299,6 +1313,10 @@ static void nan_de_rx_follow_up(struct nan_de *de, struct nan_de_service *srv,
/* Follow-up function processing of a receive Follow-up message for a
* Subscribe or Publish instance */
+ /* No processing for when it is a proxied publish for another NMI */
+ if (srv->type == NAN_DE_PUBLISH && srv->publish.origin_id)
+ return;
+
if (srv->type == NAN_DE_PUBLISH &&
os_reltime_initialized(&srv->pause_state_end) &&
(!ether_addr_equal(peer_addr, srv->sel_peer_addr) ||
@@ -1658,7 +1676,8 @@ int nan_de_publish(struct nan_de *de, const char *service_name,
return -1;
}
- if (params->proximity_ranging && params->solicited && !elems) {
+ if (params->proximity_ranging && params->solicited &&
+ !elems && !params->origin_id) {
wpa_printf(MSG_INFO,
"NAN: Unable to fetch proximity ranging params");
return -1;
@@ -2065,6 +2084,12 @@ int nan_de_transmit(struct nan_de *de, int handle,
return -1;
}
+ if (srv->type == NAN_DE_PUBLISH && srv->publish.origin_id) {
+ wpa_printf(MSG_DEBUG,
+ "NAN: Cannot transmit Follow-up for proxied services");
+ return -1;
+ }
+
if (srv->is_p2p)
network_id = p2p_network_id;
else if (srv->sync)
diff --git a/src/common/nan_de.h b/src/common/nan_de.h
index b14b22b4a0..cf9b9870e7 100644
--- a/src/common/nan_de.h
+++ b/src/common/nan_de.h
@@ -106,6 +106,10 @@ struct nan_publish_params {
/* Event conditions */
bool disable_events;
+ /* When acting as a proxy */
+ int origin_id;
+ u8 origin_nmi[ETH_ALEN];
+
/* Further Service Discovery flag */
bool fsd;
diff --git a/wpa_supplicant/nan_supplicant.c b/wpa_supplicant/nan_supplicant.c
index a42c158425..f284bc8ff8 100644
--- a/wpa_supplicant/nan_supplicant.c
+++ b/wpa_supplicant/nan_supplicant.c
@@ -777,7 +777,9 @@ int wpas_nan_publish(struct wpa_supplicant *wpa_s, const char *service_name,
}
#endif /* CONFIG_NAN */
- if (p2p) {
+ if (params->origin_id) {
+ /* Do not add extra elems automatically here */
+ } else if (p2p) {
elems = wpas_p2p_usd_elems(wpa_s, service_name);
addr = wpa_s->global->p2p_dev_addr;
} else if (params->proximity_ranging) {
--
2.53.0
More information about the Hostap
mailing list