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@xxxxxxxxxxx> --- 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 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap