]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
D-Bus: Allow changing an interface bridge via D-Bus
authorBeniamino Galvani <bgalvani@redhat.com>
Wed, 30 Sep 2020 16:34:36 +0000 (18:34 +0200)
committerJouni Malinen <j@w1.fi>
Fri, 9 Oct 2020 12:18:10 +0000 (15:18 +0300)
D-Bus clients can call CreateInterface() once and use the resulting
Interface object to connect multiple times to different networks.

However, if the network interface gets added to a bridge, clients
currently have to remove the Interface object and create a new one.

Improve this by supporting the change of the BridgeIfname property of
an existing Interface object.

Signed-off-by: Beniamino Galvani <bgalvani@redhat.com>
src/rsn_supp/tdls.c
wpa_supplicant/dbus/dbus_new.c
wpa_supplicant/dbus/dbus_new_handlers.c
wpa_supplicant/dbus/dbus_new_handlers.h
wpa_supplicant/wpa_supplicant.c
wpa_supplicant/wpa_supplicant_i.h

index 7b47e3ac52f137a14a2e81f6af7391840f4221a4..eff8cd829522333fe635aa01a8a99fcd15b63b2d 100644 (file)
@@ -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,
index 793a881efb0edbdc4549765e51d70015578228e3..ab7628f87057b02e1a3f98bef455b40d62a1790e 100644 (file)
@@ -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",
index 34abab7527a75005665bcfa6b227317a284214ce..2cfc87fa80280e1c4d1f76bb0314dfef42b624d6 100644 (file)
@@ -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
index afa26efed675bd1bb995ffb7b9bbe32bdc7af57a..d528c0816771b774210f09b1d7d99d07d73a530a 100644 (file)
@@ -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);
index 39e92fb68228b826983934eba4edead0e78ec08e..a7e9e459ee038dcec325a7ceaebad433f6994736 100644 (file)
@@ -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
index 31a9b7427585978bf359b3faac9c0b0da49bc02f..eac3491cc0956ed5bf4da047137617467ec91c09 100644 (file)
@@ -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);