From a7b2036e9547088a52e8fa4da8efc6141702515d Mon Sep 17 00:00:00 2001
From: Aloka Dixit <alokad@codeaurora.org>
Date: Mon, 14 Dec 2020 11:41:59 -0800
Subject: [PATCH 9/9] hostapd: Netlink changes for RNR offsets

This patch adds new nested netlink attribute NL80211_ATTR_RNR_OFFSETS
used to send RNR groups to kernel when EMA is enabled.
This attribute includes the count of RNR groups and data at each index.
While generating EMA beacons, kernel will include RNR group at a given
index along with MBSSID group.
Last group, if present, has RNR data common for all EMA beacons.

Signed-off-by: Aloka Dixit <alokad@codeaurora.org>
---
 src/drivers/driver_nl80211.c | 31 +++++++++++++++++++++++++++++
 src/drivers/nl80211_copy.h   | 38 ++++++++++++++++++++++++++++++++++++
 2 files changed, 69 insertions(+)

Index: hostapd-2021-02-18/src/drivers/driver_nl80211.c
===================================================================
--- hostapd-2021-02-18.orig/src/drivers/driver_nl80211.c
+++ hostapd-2021-02-18/src/drivers/driver_nl80211.c
@@ -4867,6 +4867,37 @@ static int wpa_driver_nl80211_set_ap(voi
 		nla_nest_end(msg, ies);
 	}
 
+	if (params->rnr_ie_len) {
+		struct nlattr *rnr, *ies;
+		u8 **off;
+		int i;
+
+		rnr = nla_nest_start(msg, NL80211_ATTR_RNR_OFFSETS);
+		if (!rnr || nla_put_u8(msg, NL80211_RNR_IES_ATTR_COUNT,
+				       params->rnr_ie_count)) {
+			wpa_printf(MSG_ERROR,
+				   "nl80211: Failed to build reduced neighbor report msg for %s\n",
+				   bss->ifname);
+			goto fail;
+		}
+
+		ies = nla_nest_start(msg, NL80211_RNR_IES_ATTR_DATA);
+		if (!ies)
+			goto fail;
+		off = params->rnr_ie_offsets;
+		for (i = 0; i < params->rnr_ie_count - 1; i++) {
+			if (nla_put(msg, i + 1, off[i + 1] - off[i], off[i])) {
+				wpa_printf(MSG_ERROR,
+					   "nl80211: Failed to build reduced neighbor report msg for %s\n",
+					   bss->ifname);
+				goto fail;
+			}
+		}
+		nla_put(msg, i + 1, *off + params->rnr_ie_len - off[i], off[i]);
+		nla_nest_end(msg, ies);
+		nla_nest_end(msg, rnr);
+	}
+
 	ret = send_and_recv_msgs_owner(drv, msg, get_connect_handle(bss), 1,
 				       NULL, NULL, NULL, NULL);
 	if (ret) {
Index: hostapd-2021-02-18/src/drivers/nl80211_copy.h
===================================================================
--- hostapd-2021-02-18.orig/src/drivers/nl80211_copy.h
+++ hostapd-2021-02-18/src/drivers/nl80211_copy.h
@@ -2587,6 +2587,17 @@ enum nl80211_commands {
  *
  * @NL80211_ATTR_MULTIPLE_BSSID_EMA: Shall the multiple BSS beacons be sent out in EMA mode.
  *
+ * @NL80211_ATTR_RNR_OFFSETS: Offsets for Reduced neighbor element (RNR) of
+ *	type &enum nl80211_rnr_ies_attributes.
+ *	RNR is split into multiple groups when EMA (Enhanced multi-BSSID
+ *	advertisements) feature is enabled. Each group excludes the profiles
+ *	already included in MBSSID group (%NL80211_ATTR_MULTIPLE_BSSID_IES) at
+ *	the same index. Each EMA beacon will be generated by adding MBSSID and
+ *	RNR groups at the same index.
+ *	The last additional RNR group, if present, points to information
+ *	for co-located APs and neighbor APs in ESS to be added in all
+ *	EMA beacons.
+ *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -3098,6 +3109,8 @@ enum nl80211_attrs {
 	NL80211_ATTR_COLOR_CHANGE_ANNOUNCEMENT_COLOR,
 	NL80211_ATTR_COLOR_CHANGE_ANNOUNCEMENT_IES,
 
+	NL80211_ATTR_RNR_OFFSETS,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
@@ -7325,4 +7338,27 @@ enum nl80211_sar_specs_attrs {
 	NL80211_SAR_ATTR_SPECS_MAX = __NL80211_SAR_ATTR_SPECS_LAST - 1,
 };
 
+/**
+ * enum nl80211_rnr_ies_attributes - Reduced neighbor report (RNR) offsets.
+ *	Used only when enhanced multi-BSSID advertisements (EMA) are enabled.
+ *
+ * @__NL80211_RNR_IES_ATTR_INVALID: Invalid
+ *
+ * @NL80211_RNR_IES_ATTR_COUNT: Count of RNR offsets
+ *
+ * @NL80211_RNR_IES_ATTR_COUNT: RNR offsets and length for each.
+ *
+ * @__NL80211_RNR_IES_ATTR_LAST: Internal
+ * @NL80211_RNR_IES_ATTR_MAX: highest attribute
+ */
+enum nl80211_rnr_ies_attributes {
+	__NL80211_RNR_IES_ATTR_INVALID,
+
+	NL80211_RNR_IES_ATTR_COUNT,
+	NL80211_RNR_IES_ATTR_DATA,
+
+	/* keep last */
+	__NL80211_RNR_IES_ATTR_LAST,
+	NL80211_RNR_IES_ATTR_MAX = __NL80211_RNR_IES_ATTR_LAST - 1
+};
 #endif /* __LINUX_NL80211_H */
