1 Drop stale AP nodes from the client list when disconnecting.
2 Fixes some reassoc issues.
4 Signed-off-by: Felix Fietkau <nbd@openwrt.org>
6 --- a/net80211/ieee80211_proto.c
7 +++ b/net80211/ieee80211_proto.c
9 IEEE80211_SEND_MGMT(ni,
10 IEEE80211_FC0_SUBTYPE_DISASSOC,
11 IEEE80211_REASON_ASSOC_LEAVE);
12 - ieee80211_sta_leave(ni);
13 + ieee80211_node_leave(ni);
15 case IEEE80211_M_HOSTAP:
16 ieee80211_iterate_nodes(&ic->ic_sta,
17 @@ -1358,12 +1358,14 @@
21 + case IEEE80211_S_AUTH:
22 case IEEE80211_S_ASSOC:
23 switch (vap->iv_opmode) {
25 IEEE80211_SEND_MGMT(ni,
26 IEEE80211_FC0_SUBTYPE_DEAUTH,
27 IEEE80211_REASON_AUTH_LEAVE);
28 + ieee80211_node_leave(ni);
30 case IEEE80211_M_HOSTAP:
31 ieee80211_iterate_nodes(&ic->ic_sta,
33 case IEEE80211_S_SCAN:
34 ieee80211_cancel_scan(vap);
36 - case IEEE80211_S_AUTH:
38 ieee80211_reset_bss(vap);
40 @@ -1429,10 +1430,12 @@
41 IEEE80211_SCAN_FOREVER,
42 vap->iv_des_nssid, vap->iv_des_ssid,
45 + ieee80211_node_leave(vap->iv_bss);
47 case IEEE80211_S_RUN: /* beacon miss */
48 if (vap->iv_opmode == IEEE80211_M_STA) {
49 - ieee80211_sta_leave(ni);
50 + ieee80211_node_leave(ni);
51 vap->iv_flags &= ~IEEE80211_F_SIBSS; /* XXX */
52 if (ic->ic_roaming == IEEE80211_ROAMING_AUTO)
53 ieee80211_check_scan(vap,
55 vap->iv_state = ostate; /* stay RUN */
57 case IEEE80211_FC0_SUBTYPE_DEAUTH:
58 - ieee80211_sta_leave(ni);
59 + ieee80211_node_leave(ni);
60 if (ic->ic_roaming == IEEE80211_ROAMING_AUTO) {
62 IEEE80211_SEND_MGMT(ni,
64 IEEE80211_FC0_SUBTYPE_ASSOC_REQ, 0);
67 - ieee80211_sta_leave(ni);
68 + ieee80211_node_leave(ni);
69 if (ic->ic_roaming == IEEE80211_ROAMING_AUTO) {
70 /* NB: caller specifies ASSOC/REASSOC by arg */
71 IEEE80211_SEND_MGMT(ni, arg ?
73 ieee80211_state_name[nstate],
74 ieee80211_state_name[dstate]);
76 + ieee80211_update_link_status(vap, nstate, ostate);
78 case IEEE80211_S_AUTH:
79 case IEEE80211_S_ASSOC:
80 --- a/net80211/ieee80211_linux.c
81 +++ b/net80211/ieee80211_linux.c
86 -ieee80211_notify_node_join(struct ieee80211_node *ni, int newassoc)
87 +ieee80211_update_link_status(struct ieee80211vap *vap, int nstate, int ostate)
89 - struct ieee80211vap *vap = ni->ni_vap;
90 struct net_device *dev = vap->iv_dev;
91 union iwreq_data wreq;
94 + if (vap->iv_opmode != IEEE80211_M_STA)
97 + if (ostate == nstate)
100 + if (nstate == IEEE80211_S_RUN)
102 + else if ((ostate >= IEEE80211_S_AUTH) && (nstate < ostate))
107 + if (active && !vap->iv_bss)
110 + memset(&wreq, 0, sizeof(wreq));
111 + wreq.ap_addr.sa_family = ARPHRD_ETHER;
113 - if (ni == vap->iv_bss) {
115 - netif_carrier_on(dev);
116 - memset(&wreq, 0, sizeof(wreq));
118 + //netif_carrier_on(vap->iv_dev);
119 IEEE80211_ADDR_COPY(wreq.addr.sa_data, vap->iv_bssid);
120 - wreq.addr.sa_family = ARPHRD_ETHER;
121 -#ifdef ATH_SUPERG_XR
122 - if (vap->iv_xrvap && vap->iv_flags & IEEE80211_F_XR)
123 - dev = vap->iv_xrvap->iv_dev;
125 - wireless_send_event(dev, SIOCGIWAP, &wreq, NULL);
127 - memset(&wreq, 0, sizeof(wreq));
128 - IEEE80211_ADDR_COPY(wreq.addr.sa_data, ni->ni_macaddr);
129 - wreq.addr.sa_family = ARPHRD_ETHER;
130 + //netif_carrier_off(vap->iv_dev);
131 + memset(wreq.ap_addr.sa_data, 0, ETHER_ADDR_LEN);
133 + wireless_send_event(dev, SIOCGIWAP, &wreq, NULL);
137 +ieee80211_notify_node_join(struct ieee80211_node *ni, int newassoc)
139 + struct ieee80211vap *vap = ni->ni_vap;
140 + struct net_device *dev = vap->iv_dev;
141 + union iwreq_data wreq;
143 + if (ni == vap->iv_bss)
146 + memset(&wreq, 0, sizeof(wreq));
147 + IEEE80211_ADDR_COPY(wreq.addr.sa_data, ni->ni_macaddr);
148 + wreq.addr.sa_family = ARPHRD_ETHER;
150 - if (vap->iv_xrvap && vap->iv_flags & IEEE80211_F_XR)
151 - dev = vap->iv_xrvap->iv_dev;
152 + if (vap->iv_xrvap && vap->iv_flags & IEEE80211_F_XR)
153 + dev = vap->iv_xrvap->iv_dev;
155 - wireless_send_event(dev, IWEVREGISTERED, &wreq, NULL);
157 + wireless_send_event(dev, IWEVREGISTERED, &wreq, NULL);
161 @@ -269,18 +295,14 @@
162 struct net_device *dev = vap->iv_dev;
163 union iwreq_data wreq;
165 - if (ni == vap->iv_bss) {
166 - netif_carrier_off(dev);
167 - memset(wreq.ap_addr.sa_data, 0, ETHER_ADDR_LEN);
168 - wreq.ap_addr.sa_family = ARPHRD_ETHER;
169 - wireless_send_event(dev, SIOCGIWAP, &wreq, NULL);
171 - /* fire off wireless event station leaving */
172 - memset(&wreq, 0, sizeof(wreq));
173 - IEEE80211_ADDR_COPY(wreq.addr.sa_data, ni->ni_macaddr);
174 - wreq.addr.sa_family = ARPHRD_ETHER;
175 - wireless_send_event(dev, IWEVEXPIRED, &wreq, NULL);
177 + if (ni == vap->iv_bss)
180 + /* fire off wireless event station leaving */
181 + memset(&wreq, 0, sizeof(wreq));
182 + IEEE80211_ADDR_COPY(wreq.addr.sa_data, ni->ni_macaddr);
183 + wreq.addr.sa_family = ARPHRD_ETHER;
184 + wireless_send_event(dev, IWEVEXPIRED, &wreq, NULL);
188 --- a/net80211/ieee80211_node.c
189 +++ b/net80211/ieee80211_node.c
190 @@ -2332,6 +2332,7 @@
191 count_suppchans(ic, ni, -1);
192 IEEE80211_UNLOCK_IRQ(ic);
196 * Cleanup station state. In particular clear various
197 * state that might otherwise be reused if the node
198 @@ -2339,7 +2340,7 @@
199 * (and memory is reclaimed).
201 ieee80211_sta_leave(ni);
205 #ifdef IEEE80211_DEBUG_REFCNT
206 ic->ic_node_cleanup_debug(ni, __func__, __LINE__);
207 --- a/net80211/ieee80211_node.h
208 +++ b/net80211/ieee80211_node.h
210 #define IEEE80211_INACT_PROBE (30/IEEE80211_INACT_WAIT) /* probe */
211 #define IEEE80211_INACT_SCAN (300/IEEE80211_INACT_WAIT) /* scanned */
213 -#define IEEE80211_TRANS_WAIT 5 /* mgt frame tx timer (secs) */
214 +#define IEEE80211_TRANS_WAIT 300 /* mgt frame tx timer (msecs) */
216 #define IEEE80211_NODE_HASHSIZE 32
217 /* simple hash is enough for variation of macaddr */
218 --- a/net80211/ieee80211_output.c
219 +++ b/net80211/ieee80211_output.c
220 @@ -2141,7 +2141,7 @@
222 ieee80211_mgmt_output(ieee80211_ref_node(ni), skb, type);
224 - mod_timer(&vap->iv_mgtsend, jiffies + timer * HZ);
225 + mod_timer(&vap->iv_mgtsend, jiffies + msecs_to_jiffies(timer));
229 --- a/net80211/ieee80211_wireless.c
230 +++ b/net80211/ieee80211_wireless.c
232 vap->iv_flags |= IEEE80211_F_DESBSSID;
234 IEEE80211_ADDR_COPY(vap->iv_des_bssid, &ap_addr->sa_data);
235 - if (IS_UP_AUTO(vap))
236 + if (IS_UP(vap->iv_dev)) {
237 ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);
242 --- a/net80211/ieee80211_linux.h
243 +++ b/net80211/ieee80211_linux.h
245 #define free_netdev(dev) kfree(dev)
248 +void ieee80211_update_link_status(struct ieee80211vap *vap, int nstate, int ostate);
249 void ieee80211_ioctl_vattach(struct ieee80211vap *);
250 void ieee80211_ioctl_vdetach(struct ieee80211vap *);