diff --git a/src/rsn_supp/tdls.c b/src/rsn_supp/tdls.c index 7b47e3ac5..eff8cd829 100644 --- a/src/rsn_supp/tdls.c +++ b/src/rsn_supp/tdls.c @@ -2807,6 +2807,11 @@ int wpa_tdls_init(struct wpa_sm *sm) if (sm == NULL) return -1; + if (sm->l2_tdls) { + l2_packet_deinit(sm->l2_tdls); + sm->l2_tdls = NULL; + } + sm->l2_tdls = l2_packet_init(sm->bridge_ifname ? sm->bridge_ifname : sm->ifname, sm->own_addr, diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c index 793a881ef..ab7628f87 100644 --- a/wpa_supplicant/dbus/dbus_new.c +++ b/wpa_supplicant/dbus/dbus_new.c @@ -3613,7 +3613,7 @@ static const struct wpa_dbus_property_desc wpas_dbus_interface_properties[] = { }, { "BridgeIfname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s", wpas_dbus_getter_bridge_ifname, - NULL, + wpas_dbus_setter_bridge_ifname, NULL }, { "ConfigFile", WPAS_DBUS_NEW_IFACE_INTERFACE, "s", diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c index 34abab752..2cfc87fa8 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers.c +++ b/wpa_supplicant/dbus/dbus_new_handlers.c @@ -3635,6 +3635,43 @@ dbus_bool_t wpas_dbus_getter_bridge_ifname( } +dbus_bool_t wpas_dbus_setter_bridge_ifname( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) +{ + struct wpa_supplicant *wpa_s = user_data; + const char *bridge_ifname = NULL; + const char *msg; + int r; + + if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_STRING, + &bridge_ifname)) + return FALSE; + + r = wpa_supplicant_update_bridge_ifname(wpa_s, bridge_ifname); + if (r != 0) { + switch (r) { + case -EINVAL: + msg = "invalid interface name"; + break; + case -EBUSY: + msg = "interface is busy"; + break; + case -EIO: + msg = "socket error"; + break; + default: + msg = "unknown error"; + break; + } + dbus_set_error_const(error, DBUS_ERROR_FAILED, msg); + return FALSE; + } + + return TRUE; +} + + /** * wpas_dbus_getter_config_file - Get interface configuration file path * @iter: Pointer to incoming dbus message iter diff --git a/wpa_supplicant/dbus/dbus_new_handlers.h b/wpa_supplicant/dbus/dbus_new_handlers.h index afa26efed..d528c0816 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers.h +++ b/wpa_supplicant/dbus/dbus_new_handlers.h @@ -167,6 +167,7 @@ DECLARE_ACCESSOR(wpas_dbus_setter_scan_interval); DECLARE_ACCESSOR(wpas_dbus_getter_ifname); DECLARE_ACCESSOR(wpas_dbus_getter_driver); DECLARE_ACCESSOR(wpas_dbus_getter_bridge_ifname); +DECLARE_ACCESSOR(wpas_dbus_setter_bridge_ifname); DECLARE_ACCESSOR(wpas_dbus_getter_config_file); DECLARE_ACCESSOR(wpas_dbus_getter_current_bss); DECLARE_ACCESSOR(wpas_dbus_getter_current_network); diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 39e92fb68..a7e9e459e 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -4906,6 +4906,65 @@ static void wpa_supplicant_rx_eapol_bridge(void *ctx, const u8 *src_addr, } +int wpa_supplicant_update_bridge_ifname(struct wpa_supplicant *wpa_s, + const char *bridge_ifname) +{ + if (wpa_s->wpa_state > WPA_SCANNING) + return -EBUSY; + + if (bridge_ifname && + os_strlen(bridge_ifname) >= sizeof(wpa_s->bridge_ifname)) + return -EINVAL; + + if (!bridge_ifname) + bridge_ifname = ""; + + if (os_strcmp(wpa_s->bridge_ifname, bridge_ifname) == 0) + return 0; + + if (wpa_s->l2_br) { + l2_packet_deinit(wpa_s->l2_br); + wpa_s->l2_br = NULL; + } + + os_strlcpy(wpa_s->bridge_ifname, bridge_ifname, + sizeof(wpa_s->bridge_ifname)); + + if (wpa_s->bridge_ifname[0]) { + wpa_dbg(wpa_s, MSG_DEBUG, + "Receiving packets from bridge interface '%s'", + wpa_s->bridge_ifname); + wpa_s->l2_br = l2_packet_init_bridge( + wpa_s->bridge_ifname, wpa_s->ifname, wpa_s->own_addr, + ETH_P_EAPOL, wpa_supplicant_rx_eapol_bridge, wpa_s, 1); + if (!wpa_s->l2_br) { + wpa_msg(wpa_s, MSG_ERROR, + "Failed to open l2_packet connection for the bridge interface '%s'", + wpa_s->bridge_ifname); + goto fail; + } + } + +#ifdef CONFIG_TDLS + if (!wpa_s->p2p_mgmt && wpa_tdls_init(wpa_s->wpa)) + goto fail; +#endif /* CONFIG_TDLS */ + + return 0; +fail: + wpa_s->bridge_ifname[0] = 0; + if (wpa_s->l2_br) { + l2_packet_deinit(wpa_s->l2_br); + wpa_s->l2_br = NULL; + } +#ifdef CONFIG_TDLS + if (!wpa_s->p2p_mgmt) + wpa_tdls_init(wpa_s->wpa); +#endif /* CONFIG_TDLS */ + return -EIO; +} + + /** * wpa_supplicant_driver_init - Initialize driver interface parameters * @wpa_s: Pointer to wpa_supplicant data diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 31a9b7427..eac3491cc 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -1351,6 +1351,8 @@ int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s); const char * wpa_supplicant_state_txt(enum wpa_states state); int wpa_supplicant_update_mac_addr(struct wpa_supplicant *wpa_s); int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s); +int wpa_supplicant_update_bridge_ifname(struct wpa_supplicant *wpa_s, + const char *bridge_ifname); int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, struct wpa_ssid *ssid, u8 *wpa_ie, size_t *wpa_ie_len);