]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
mesh: Add MESH_PEER_ADD command
authorMasashi Honma <masashi.honma@gmail.com>
Wed, 9 Mar 2016 09:16:11 +0000 (18:16 +0900)
committerJouni Malinen <j@w1.fi>
Sun, 20 Mar 2016 15:37:53 +0000 (17:37 +0200)
This allows a mesh peer connection to be initiated manually in
no_auto_peer mesh networks.

Signed-off-by: Natsuki Itaya <Natsuki.Itaya@jp.sony.com>
Signed-off-by: Masashi Honma <masashi.honma@gmail.com>
wpa_supplicant/ctrl_iface.c
wpa_supplicant/mesh.c
wpa_supplicant/mesh.h
wpa_supplicant/mesh_mpm.c
wpa_supplicant/mesh_mpm.h
wpa_supplicant/wpa_cli.c

index cc75514a0f1e5f065c40999e4aca8233a3d70e8d..36fc4b44df597a4ec9b5e5382c999175512cddec 100644 (file)
@@ -2739,6 +2739,18 @@ static int wpa_supplicant_ctrl_iface_mesh_peer_remove(
        return wpas_mesh_peer_remove(wpa_s, addr);
 }
 
+
+static int wpa_supplicant_ctrl_iface_mesh_peer_add(
+       struct wpa_supplicant *wpa_s, char *cmd)
+{
+       u8 addr[ETH_ALEN];
+
+       if (hwaddr_aton(cmd, addr))
+               return -1;
+
+       return wpas_mesh_peer_add(wpa_s, addr);
+}
+
 #endif /* CONFIG_MESH */
 
 
@@ -8587,6 +8599,9 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
        } else if (os_strncmp(buf, "MESH_PEER_REMOVE ", 17) == 0) {
                if (wpa_supplicant_ctrl_iface_mesh_peer_remove(wpa_s, buf + 17))
                        reply_len = -1;
+       } else if (os_strncmp(buf, "MESH_PEER_ADD ", 14) == 0) {
+               if (wpa_supplicant_ctrl_iface_mesh_peer_add(wpa_s, buf + 14))
+                       reply_len = -1;
 #endif /* CONFIG_MESH */
 #ifdef CONFIG_P2P
        } else if (os_strncmp(buf, "P2P_FIND ", 9) == 0) {
index c6d1d7366ebda098918e7fde1bf3bafe0cdc45a4..cdb5eb0be0465295e69c145344b456b2fc4a8daa 100644 (file)
@@ -603,3 +603,9 @@ int wpas_mesh_peer_remove(struct wpa_supplicant *wpa_s, const u8 *addr)
 {
        return mesh_mpm_close_peer(wpa_s, addr);
 }
+
+
+int wpas_mesh_peer_add(struct wpa_supplicant *wpa_s, const u8 *addr)
+{
+       return mesh_mpm_connect_peer(wpa_s, addr);
+}
index 31b9f0787a3187437bf9885db5942f2554eb2cb0..b40ae6c320d3c43ba441b5ac340e26fc68a9f43a 100644 (file)
@@ -19,6 +19,7 @@ int wpas_mesh_scan_result_text(const u8 *ies, size_t ies_len, char *buf,
 int wpas_mesh_add_interface(struct wpa_supplicant *wpa_s, char *ifname,
                            size_t len);
 int wpas_mesh_peer_remove(struct wpa_supplicant *wpa_s, const u8 *addr);
+int wpas_mesh_peer_add(struct wpa_supplicant *wpa_s, const u8 *addr);
 
 #ifdef CONFIG_MESH
 
index a3b17c494cad93d7247a6529e9c8d96c7fce020f..c470d1046f1bc54732071fc84a7428680cbac232 100644 (file)
@@ -512,6 +512,50 @@ int mesh_mpm_close_peer(struct wpa_supplicant *wpa_s, const u8 *addr)
 }
 
 
+int mesh_mpm_connect_peer(struct wpa_supplicant *wpa_s, const u8 *addr)
+{
+       struct wpa_ssid *ssid = wpa_s->current_ssid;
+       struct hostapd_data *hapd;
+       struct sta_info *sta;
+       struct mesh_conf *conf;
+
+       if (!wpa_s->ifmsh) {
+               wpa_msg(wpa_s, MSG_INFO, "Mesh is not prepared yet");
+               return -1;
+       }
+
+       if (!ssid || !ssid->no_auto_peer) {
+               wpa_msg(wpa_s, MSG_INFO,
+                       "This command is available only with no_auto_peer mesh network");
+               return -1;
+       }
+
+       hapd = wpa_s->ifmsh->bss[0];
+       conf = wpa_s->ifmsh->mconf;
+
+       sta = ap_get_sta(hapd, addr);
+       if (!sta) {
+               wpa_msg(wpa_s, MSG_INFO, "No such mesh peer");
+               return -1;
+       }
+
+       if ((PLINK_OPEN_SENT <= sta->plink_state &&
+           sta->plink_state <= PLINK_ESTAB) ||
+           (sta->sae && sta->sae->state > SAE_NOTHING)) {
+               wpa_msg(wpa_s, MSG_INFO,
+                       "Specified peer is connecting/connected");
+               return -1;
+       }
+
+       if (conf->security == MESH_CONF_SEC_NONE)
+               mesh_mpm_plink_open(wpa_s, sta, PLINK_OPEN_SENT);
+       else
+               mesh_rsn_auth_sae_sta(wpa_s, sta);
+
+       return 0;
+}
+
+
 void mesh_mpm_deinit(struct wpa_supplicant *wpa_s, struct hostapd_iface *ifmsh)
 {
        struct hostapd_data *hapd = ifmsh->bss[0];
index 71880869a3f651fee88ded17fec52b184e9058ec..cbecd3714a666ef20e1fd4456462cd81e225b265 100644 (file)
@@ -19,6 +19,7 @@ void wpa_mesh_set_plink_state(struct wpa_supplicant *wpa_s,
                              struct sta_info *sta,
                              enum mesh_plink_state state);
 int mesh_mpm_close_peer(struct wpa_supplicant *wpa_s, const u8 *addr);
+int mesh_mpm_connect_peer(struct wpa_supplicant *wpa_s, const u8 *addr);
 
 #ifdef CONFIG_MESH
 
index e681d8225a045c6f4b742bf645b4180e9322cbe8..bd669e339adc13ca75b8c9ff31d40173071b1102 100644 (file)
@@ -2049,6 +2049,13 @@ static int wpa_cli_cmd_mesh_peer_remove(struct wpa_ctrl *ctrl, int argc,
        return wpa_cli_cmd(ctrl, "MESH_PEER_REMOVE", 1, argc, argv);
 }
 
+
+static int wpa_cli_cmd_mesh_peer_add(struct wpa_ctrl *ctrl, int argc,
+                                    char *argv[])
+{
+       return wpa_cli_cmd(ctrl, "MESH_PEER_ADD", 1, argc, argv);
+}
+
 #endif /* CONFIG_MESH */
 
 
@@ -3220,6 +3227,9 @@ static const struct wpa_cli_cmd wpa_cli_commands[] = {
        { "mesh_peer_remove", wpa_cli_cmd_mesh_peer_remove, NULL,
          cli_cmd_flag_none,
          "<addr> = Remove a mesh peer" },
+       { "mesh_peer_add", wpa_cli_cmd_mesh_peer_add, NULL,
+         cli_cmd_flag_none,
+         "<addr> = Add a mesh peer" },
 #endif /* CONFIG_MESH */
 #ifdef CONFIG_P2P
        { "p2p_find", wpa_cli_cmd_p2p_find, wpa_cli_complete_p2p_find,