[PATCH] wpa_supplicant: add option to explicitly set 4addr mode

Konstantinos Natsakis infradead.org at aleph-0.net
Tue Jan 31 16:16:18 PST 2023


Add a new option that puts an interface in 4addr mode, for
interfaces meant to be enslaved to a bridge

Signed-off-by: Konstantinos Natsakis <infradead.org at aleph-0.net>
---
 wpa_supplicant/config.c      |  1 +
 wpa_supplicant/config_file.c |  1 +
 wpa_supplicant/config_ssid.h | 11 +++++++++++
 wpa_supplicant/events.c      | 28 +++++++++++++++++++++++-----
 4 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index 9477ad472..277a89645 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -2710,6 +2710,7 @@ static const struct parse_data ssid_fields[] = {
 	{ INT_RANGE(transition_disable, 0, 255) },
 	{ INT_RANGE(sae_pk, 0, 2) },
 	{ INT_RANGE(disable_eht, 0, 1)},
+	{ INT_RANGE(enable_4addr_mode, 0, 1)},
 };
 
 #undef OFFSET
diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c
index 4d50f44a8..e51fc407b 100644
--- a/wpa_supplicant/config_file.c
+++ b/wpa_supplicant/config_file.c
@@ -890,6 +890,7 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid)
 	INT(disable_he);
 #endif /* CONFIG_HE_OVERRIDES */
 	INT(disable_eht);
+	INT(enable_4addr_mode);
 
 #undef STR
 #undef INT
diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h
index 4d89e04b9..9b8df34f5 100644
--- a/wpa_supplicant/config_ssid.h
+++ b/wpa_supplicant/config_ssid.h
@@ -1240,6 +1240,17 @@ struct wpa_ssid {
 	 * to 1 to have it disabled.
 	 */
 	int disable_eht;
+
+	/**
+	 * enable_4addr_mode - Set 4addr mode after association
+	 * 0 = do not attempt to set 4addr mode
+	 * 1 = try to set 4addr mode after association
+	 *
+	 * Linux requires that an interface is set to 4addr mode before it can
+	 * be enslaved to a bridge. Set this to 1 for networks where you intent
+	 * to enslave the interface to a bridge.
+	 */
+	int enable_4addr_mode;
 };
 
 #endif /* CONFIG_SSID_H */
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 146191d03..e72f2f026 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -2700,6 +2700,25 @@ static void interworking_process_assoc_resp(struct wpa_supplicant *wpa_s,
 #endif /* CONFIG_INTERWORKING */
 
 
+static void wpa_supplicant_set_4addr_mode(struct wpa_supplicant *wpa_s) {
+	if (wpa_s->enabled_4addr_mode) {
+		wpa_msg(wpa_s, MSG_DEBUG, "4addr mode already set");
+		return;
+	}
+
+	if (wpa_drv_set_4addr_mode(wpa_s, 1) < 0) {
+		wpa_msg(wpa_s, MSG_ERROR, "Failed to set 4addr mode");
+		goto fail;
+	}
+	wpa_s->enabled_4addr_mode = 1;
+	wpa_msg(wpa_s, MSG_INFO, "Successfully set 4addr mode");
+	return;
+
+fail:
+	wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
+}
+
+
 static void multi_ap_process_assoc_resp(struct wpa_supplicant *wpa_s,
 					const u8 *ies, size_t ies_len)
 {
@@ -2752,11 +2771,7 @@ static void multi_ap_set_4addr_mode(struct wpa_supplicant *wpa_s)
 		goto fail;
 	}
 
-	if (wpa_drv_set_4addr_mode(wpa_s, 1) < 0) {
-		wpa_printf(MSG_ERROR, "Failed to set 4addr mode");
-		goto fail;
-	}
-	wpa_s->enabled_4addr_mode = 1;
+	wpa_supplicant_set_4addr_mode(wpa_s);
 	return;
 
 fail:
@@ -3844,6 +3859,9 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
 #ifdef CONFIG_DPP2
 	wpa_s->dpp_pfs_fallback = 0;
 #endif /* CONFIG_DPP2 */
+
+	if (wpa_s->current_ssid && wpa_s->current_ssid->enable_4addr_mode)
+		wpa_supplicant_set_4addr_mode(wpa_s);
 }
 
 
-- 
2.39.1




More information about the Hostap mailing list