[PATCH 2/9] supplicant: Allow user-defined defaults for Interworking network blocks.

[email protected]
Newsgroups gmane.linux.drivers.hostap
Message-ID <[email protected]>
From: Ben Greear <[email protected]>

This way users can still configure the HT over-rides and some other
constraints that Interworking has no interest or ability to configure.

Example config file (to disable HT-40 on an Interworking/HS20 interface):

ctrl_interface=/var/run/wpa_supplicant
fast_reauth=1

interworking=1
auto_interworking=1
access_network_type=0

hs20=1

bss_max_count=2000
network={
    interworking_defaults=1
    disable_ht=0
    disable_ht40=1
    disable_sgi=0
    ht_mcs=""
    disable_max_amsdu=-1
    ampdu_factor=-1
    ampdu_density=-1

}

cred={
    username="client2"
    password="lanforge"
    ca_cert="/home/lanforge/ca.pem"
    private_key="/home/lanforge/client.p12"
    private_key_passwd="lanforge"
    realm="lanforge.org"
    domain="lanforge.org"
    eap=TLS

}

Signed-off-by: Ben Greear <[email protected]>
---
 src/utils/common.c                 |  3 ++
 wpa_supplicant/config.c            | 72 ++++++++++++++++++++++++++++++
 wpa_supplicant/config.h            |  1 +
 wpa_supplicant/config_ssid.h       |  7 +++
 wpa_supplicant/interworking.c      |  3 ++
 wpa_supplicant/scan.h              |  1 +
 wpa_supplicant/wpa_supplicant.conf | 10 +++++
 7 files changed, 97 insertions(+)

diff --git a/src/utils/common.c b/src/utils/common.c
index 27bf435d9..a0199ed21 100644
--- a/src/utils/common.c
+++ b/src/utils/common.c
@@ -891,6 +891,9 @@ void int_array_concat(int **res, const int *a)
 	reslen = int_array_len(*res);
 	alen = int_array_len(a);
 
+	if (alen == 0)
+		return; /* nothing to concat */
+
 	n = os_realloc_array(*res, reslen + alen + 1, sizeof(int));
 	if (n == NULL) {
 		os_free(*res);
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index 1bc798b89..0f6003bc0 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -2558,6 +2558,7 @@ static const struct parse_data ssid_fields[] = {
 	{ INT_RANGE(pbss, 0, 2) },
 	{ INT_RANGE(wps_disabled, 0, 1) },
 	{ INT_RANGE(fils_dh_group, 0, 65535) },
+	{ INT_RANGE(interworking_defaults, 0, 1) },
 #ifdef CONFIG_DPP
 	{ STR(dpp_connector) },
 	{ STR_LEN(dpp_netaccesskey) },
@@ -3009,6 +3010,76 @@ int wpa_config_remove_network(struct wpa_config *config, int id)
 }
 
 
+/**
+ * wpa_set_user_network_defalts - Configure ssid with network defaults.
+ * @config: Configuration data from wpa_config_read()
+ * @ssid: The SSID to configure.
+ * Looks for first wpa_ssid that has interworking_defaults=1.  If found,
+ * select values are applied to the ssid.  In this way one may configure
+ * options not explicitly dealt with by interworking, such as
+ *   disable_ht=0
+ *   disable_ht40=0
+ *   etc.
+ * If no ssid is found, no action is taken.
+ */
+void wpa_config_set_user_network_defaults(struct wpa_config *config, struct wpa_ssid *ssid)
+{
+	struct wpa_ssid *s = config->ssid;
+
+	while (s) {
+		if (s->interworking_defaults) {
+			os_free(ssid->scan_freq);
+			ssid->scan_freq = NULL;
+			int_array_concat(&ssid->scan_freq, s->scan_freq);
+
+			os_free(ssid->freq_list);
+			ssid->freq_list = NULL;
+			int_array_concat(&ssid->freq_list, s->freq_list);
+
+			ssid->bg_scan_period = s->bg_scan_period;
+#ifdef CONFIG_HT_OVERRIDES
+			ssid->disable_ht = s->disable_ht;
+			ssid->disable_ht40 = s->disable_ht40;
+			ssid->disable_sgi = s->disable_sgi;
+			ssid->disable_max_amsdu = s->disable_max_amsdu;
+			ssid->ampdu_factor = s->ampdu_factor;
+			ssid->ampdu_density = s->ampdu_density;
+
+			os_free(ssid->ht_mcs);
+			ssid->ht_mcs = NULL;
+			if (s->ht_mcs) {
+				ssid->ht_mcs = strdup(s->ht_mcs);
+			}
+#endif
+#ifdef CONFIG_VHT_OVERRIDES
+			ssid->disable_vht = s->disable_vht;
+			ssid->vht_capa = s->vht_capa;
+			ssid->vht_capa_mask = s->vht_capa_mask;
+			ssid->vht_rx_mcs_nss_1 = s->vht_rx_mcs_nss_1;
+			ssid->vht_rx_mcs_nss_2 = s->vht_rx_mcs_nss_2;
+			ssid->vht_rx_mcs_nss_3 = s->vht_rx_mcs_nss_3;
+			ssid->vht_rx_mcs_nss_4 = s->vht_rx_mcs_nss_4;
+			ssid->vht_rx_mcs_nss_5 = s->vht_rx_mcs_nss_5;
+			ssid->vht_rx_mcs_nss_6 = s->vht_rx_mcs_nss_6;
+			ssid->vht_rx_mcs_nss_7 = s->vht_rx_mcs_nss_7;
+			ssid->vht_rx_mcs_nss_8 = s->vht_rx_mcs_nss_8;
+			ssid->vht_tx_mcs_nss_1 = s->vht_tx_mcs_nss_1;
+			ssid->vht_tx_mcs_nss_2 = s->vht_tx_mcs_nss_2;
+			ssid->vht_tx_mcs_nss_3 = s->vht_tx_mcs_nss_3;
+			ssid->vht_tx_mcs_nss_4 = s->vht_tx_mcs_nss_4;
+			ssid->vht_tx_mcs_nss_5 = s->vht_tx_mcs_nss_5;
+			ssid->vht_tx_mcs_nss_6 = s->vht_tx_mcs_nss_6;
+			ssid->vht_tx_mcs_nss_7 = s->vht_tx_mcs_nss_7;
+			ssid->vht_tx_mcs_nss_8 = s->vht_tx_mcs_nss_8;
+#endif /* CONFIG_VHT_OVERRIDES */
+			return;
+		}
+		else {
+			s = s->next;
+		}
+	}
+} /* wpa_set_user_network_defaults */
+
 /**
  * wpa_config_set_network_defaults - Set network default values
  * @ssid: Pointer to network configuration data
@@ -3070,6 +3141,7 @@ void wpa_config_set_network_defaults(struct wpa_ssid *ssid)
 #endif /* CONFIG_MACSEC */
 	ssid->mac_addr = -1;
 	ssid->max_oper_chwidth = DEFAULT_MAX_OPER_CHWIDTH;
+	ssid->interworking_defaults = DEFAULT_INTERWORKING_DEFAULTS;
 }
 
 
diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h
index b3c779233..41fa21298 100644
--- a/wpa_supplicant/config.h
+++ b/wpa_supplicant/config.h
@@ -1584,6 +1584,7 @@ struct wpa_ssid * wpa_config_get_network(struct wpa_config *config, int id);
 struct wpa_ssid * wpa_config_add_network(struct wpa_config *config);
 int wpa_config_remove_network(struct wpa_config *config, int id);
 void wpa_config_set_network_defaults(struct wpa_ssid *ssid);
+void wpa_config_set_user_network_defaults(struct wpa_config *config, struct wpa_ssid *ssid);
 int wpa_config_set(struct wpa_ssid *ssid, const char *var, const char *value,
 		   int line);
 int wpa_config_set_quoted(struct wpa_ssid *ssid, const char *var,
diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h
index b752dfdda..57269bd5c 100644
--- a/wpa_supplicant/config_ssid.h
+++ b/wpa_supplicant/config_ssid.h
@@ -40,6 +40,7 @@
 #define DEFAULT_AMPDU_DENSITY -1 /* no change */
 #define DEFAULT_USER_SELECTED_SIM 1
 #define DEFAULT_MAX_OPER_CHWIDTH -1
+#define DEFAULT_INTERWORKING_DEFAULTS 0
 
 struct psk_list_entry {
 	struct dl_list list;
@@ -642,6 +643,12 @@ struct wpa_ssid {
 	 */
 	int temporary;
 
+	/**
+	 * interworking_defaults - Whether this network block should be used for
+	 *    network defaults when creating temporary interworking network blocks.
+	 */
+	int interworking_defaults;
+
 	/**
 	 * export_keys - Whether keys may be exported
 	 *
diff --git a/wpa_supplicant/interworking.c b/wpa_supplicant/interworking.c
index 49b9907b0..6f1e5725d 100644
--- a/wpa_supplicant/interworking.c
+++ b/wpa_supplicant/interworking.c
@@ -996,6 +996,7 @@ static int interworking_connect_3gpp(struct wpa_supplicant *wpa_s,
 
 	wpas_notify_network_added(wpa_s, ssid);
 	wpa_config_set_network_defaults(ssid);
+	wpa_config_set_user_network_defaults(wpa_s->conf, ssid);
 	ssid->priority = cred->priority;
 	ssid->temporary = 1;
 	ssid->ssid = os_zalloc(bss->ssid_len + 1);
@@ -1586,6 +1587,7 @@ static int interworking_connect_roaming_consortium(
 	ssid->parent_cred = cred;
 	wpas_notify_network_added(wpa_s, ssid);
 	wpa_config_set_network_defaults(ssid);
+	wpa_config_set_user_network_defaults(wpa_s->conf, ssid);
 	ssid->priority = cred->priority;
 	ssid->temporary = 1;
 	ssid->ssid = os_zalloc(bss->ssid_len + 1);
@@ -1806,6 +1808,7 @@ int interworking_connect(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
 	ssid->parent_cred = cred;
 	wpas_notify_network_added(wpa_s, ssid);
 	wpa_config_set_network_defaults(ssid);
+	wpa_config_set_user_network_defaults(wpa_s->conf, ssid);
 	ssid->priority = cred->priority;
 	ssid->temporary = 1;
 	ssid->ssid = os_zalloc(bss->ssid_len + 1);
diff --git a/wpa_supplicant/scan.h b/wpa_supplicant/scan.h
index c9ce2cecf..1f85606a4 100644
--- a/wpa_supplicant/scan.h
+++ b/wpa_supplicant/scan.h
@@ -86,5 +86,6 @@ unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s,
 			      const u8 *ies, size_t ies_len, int rate,
 			      int snr);
 void wpa_supplicant_set_default_scan_ies(struct wpa_supplicant *wpa_s);
+void int_array_concat(int **res, const int *a);
 
 #endif /* SCAN_H */
diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf
index d587bd340..7fa49d266 100644
--- a/wpa_supplicant/wpa_supplicant.conf
+++ b/wpa_supplicant/wpa_supplicant.conf
@@ -1450,6 +1450,16 @@ fast_reauth=1
 # 2 = like 1, but maintain OUI (with local admin bit set)
 #mac_addr=0
 
+# interworking_defaults:  Should this network block's values be used as
+#   defaults for automatically-created interworking network blocks?
+#   Not all values will be propagated, but the HT and VHT overrides,
+#   and a few other values will be.  This will only be used if
+#   Interworking is active.  Only the first interworking_defaults=1
+#   network block will be used, so users should only set this value
+#   in a single network block.
+# 0 = Not used (default)
+# 1 = Use this network block's values.
+
 # disable_ht: Whether HT (802.11n) should be disabled.
 # 0 = HT enabled (if AP supports it)
 # 1 = HT disabled
-- 
2.20.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.