]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
mesh: Fix peer link counting when a mesh peer reconnects
authorSrinivasa Duvvuri <sduvvuri@google.com>
Sun, 31 Jan 2016 02:45:30 +0000 (18:45 -0800)
committerJouni Malinen <j@w1.fi>
Sat, 6 Feb 2016 19:22:29 +0000 (21:22 +0200)
When a mesh point reconnects by starting from Authentication frame
sequence, the plink count was not decremented from its last connection.
This resulted in leaking peer link count and causing wpa_supplicant to
reject the connection after max_peer_links (default: 99) reconnects.

This was reproduced by pre-configuring 2 mesh points with mesh
credentials. Boot both mesh points and make sure they connect to each
other. Then in a loop reboot one of the mesh points after it
successfully connects while leaving the other mesh point up and running.
After 99 iterations the supplicant on mesh point that is not rebooting
will reject the connection request from the other mesh point.

Fix this by decrementing num_plinks when freeing a STA entry that is
still in PLINK_ESTAB state.

Signed-off-by: Srinivasa Duvvuri <sduvvuri@chromium.org>
src/ap/hostapd.h
src/ap/sta_info.c
wpa_supplicant/mesh_mpm.c
wpa_supplicant/mesh_mpm.h

index b3d702e245180c3773b74b47f24561cba0a61b07..0f31dd45b71d805a37aede9fc0d5287572dafe8d 100644 (file)
@@ -258,7 +258,8 @@ struct hostapd_data {
 #ifdef CONFIG_MESH
        int num_plinks;
        int max_plinks;
-       void (*mesh_sta_free_cb)(struct sta_info *sta);
+       void (*mesh_sta_free_cb)(struct hostapd_data *hapd,
+                                struct sta_info *sta);
        struct wpabuf *mesh_pending_auth;
        struct os_reltime mesh_pending_auth_time;
 #endif /* CONFIG_MESH */
index 0583a313ba46e770ee483274be7af8a77c676d0e..3d7c83913c53f82bdc5c5c3ef0194d28ae67999f 100644 (file)
@@ -238,7 +238,7 @@ void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
 
 #ifdef CONFIG_MESH
        if (hapd->mesh_sta_free_cb)
-               hapd->mesh_sta_free_cb(sta);
+               hapd->mesh_sta_free_cb(hapd, sta);
 #endif /* CONFIG_MESH */
 
        if (set_beacon)
index d509d7d750835a45523b50b119a9c33889c15637..27be46cd175439baa5575ce71f49c9aac1bd99f4 100644 (file)
@@ -1095,8 +1095,10 @@ void mesh_mpm_action_rx(struct wpa_supplicant *wpa_s,
 
 
 /* called by ap_free_sta */
-void mesh_mpm_free_sta(struct sta_info *sta)
+void mesh_mpm_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
 {
+       if (sta->plink_state == PLINK_ESTAB)
+               hapd->num_plinks--;
        eloop_cancel_timeout(plink_timer, ELOOP_ALL_CTX, sta);
        eloop_cancel_timeout(mesh_auth_timer, ELOOP_ALL_CTX, sta);
 }
index 7ebaef0cd087d3045c0d62babeeaa2d5f9e9bcb6..9af75635627a2701c3d736e149254f4d6a8b52cd 100644 (file)
@@ -14,7 +14,7 @@ void wpa_mesh_new_mesh_peer(struct wpa_supplicant *wpa_s, const u8 *addr,
                            struct ieee802_11_elems *elems);
 void mesh_mpm_deinit(struct wpa_supplicant *wpa_s, struct hostapd_iface *ifmsh);
 void mesh_mpm_auth_peer(struct wpa_supplicant *wpa_s, const u8 *addr);
-void mesh_mpm_free_sta(struct sta_info *sta);
+void mesh_mpm_free_sta(struct hostapd_data *hapd, struct sta_info *sta);
 void wpa_mesh_set_plink_state(struct wpa_supplicant *wpa_s,
                              struct sta_info *sta,
                              enum mesh_plink_state state);