madwifi: handle frame classification properly if eth->h_proto contains the protocol...
[openwrt.git] / package / madwifi / patches / 360-sta_nodes.patch
1 Drop stale AP nodes from the client list when disconnecting.
2 Fixes some reassoc issues.
3
4 Signed-off-by: Felix Fietkau <nbd@openwrt.org>
5
6 --- a/net80211/ieee80211_proto.c
7 +++ b/net80211/ieee80211_proto.c
8 @@ -1348,7 +1348,7 @@ __ieee80211_newstate(struct ieee80211vap
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);
14                                 break;
15                         case IEEE80211_M_HOSTAP:
16                                 ieee80211_iterate_nodes(&ic->ic_sta,
17 @@ -1358,12 +1358,14 @@ __ieee80211_newstate(struct ieee80211vap
18                                 break;
19                         }
20                         goto reset;
21 +               case IEEE80211_S_AUTH:
22                 case IEEE80211_S_ASSOC:
23                         switch (vap->iv_opmode) {
24                         case IEEE80211_M_STA:
25                                 IEEE80211_SEND_MGMT(ni,
26                                         IEEE80211_FC0_SUBTYPE_DEAUTH,
27                                         IEEE80211_REASON_AUTH_LEAVE);
28 +                               ieee80211_node_leave(ni);
29                                 break;
30                         case IEEE80211_M_HOSTAP:
31                                 ieee80211_iterate_nodes(&ic->ic_sta,
32 @@ -1376,7 +1378,6 @@ __ieee80211_newstate(struct ieee80211vap
33                 case IEEE80211_S_SCAN:
34                         ieee80211_cancel_scan(vap);
35                         goto reset;
36 -               case IEEE80211_S_AUTH:
37                 reset:
38                         ieee80211_reset_bss(vap);
39                         break;
40 @@ -1429,10 +1430,12 @@ __ieee80211_newstate(struct ieee80211vap
41                                         IEEE80211_SCAN_FOREVER,
42                                         vap->iv_des_nssid, vap->iv_des_ssid,
43                                         NULL);
44 +                       else
45 +                               ieee80211_node_leave(vap->iv_bss);
46                         break;
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,
54 @@ -1511,7 +1514,7 @@ __ieee80211_newstate(struct ieee80211vap
55                                 IEEE80211_FC0_SUBTYPE_ASSOC_REQ, 0);
56                         break;
57                 case IEEE80211_S_RUN:
58 -                       ieee80211_sta_leave(ni);
59 +                       ieee80211_node_leave(ni);
60                         if (ic->ic_roaming == IEEE80211_ROAMING_AUTO) {
61                                 /* NB: caller specifies ASSOC/REASSOC by arg */
62                                 IEEE80211_SEND_MGMT(ni, arg ?
63 @@ -1779,6 +1782,7 @@ ieee80211_newstate(struct ieee80211vap *
64                           ieee80211_state_name[nstate], 
65                           ieee80211_state_name[dstate]);
66  
67 +       ieee80211_update_link_status(vap, nstate, ostate);
68         switch (nstate) {
69         case IEEE80211_S_AUTH:
70         case IEEE80211_S_ASSOC:
71 --- a/net80211/ieee80211_linux.c
72 +++ b/net80211/ieee80211_linux.c
73 @@ -233,33 +233,59 @@ ieee80211_vlan_vdetach(struct ieee80211v
74  }
75  
76  void
77 -ieee80211_notify_node_join(struct ieee80211_node *ni, int newassoc)
78 +ieee80211_update_link_status(struct ieee80211vap *vap, int nstate, int ostate)
79  {
80 -       struct ieee80211vap *vap = ni->ni_vap;
81         struct net_device *dev = vap->iv_dev;
82         union iwreq_data wreq;
83 +       int active;
84 +
85 +       if (vap->iv_opmode != IEEE80211_M_STA)
86 +               return;
87 +
88 +       if (ostate == nstate)
89 +               return;
90 +
91 +       if (nstate == IEEE80211_S_RUN)
92 +               active = 1;
93 +       else if ((ostate >= IEEE80211_S_AUTH) && (nstate < ostate))
94 +               active = 0;
95 +       else
96 +               return;
97 +
98 +       if (active && !vap->iv_bss)
99 +               return;
100 +
101 +       memset(&wreq, 0, sizeof(wreq));
102 +       wreq.ap_addr.sa_family = ARPHRD_ETHER;
103  
104 -       if (ni == vap->iv_bss) {
105 -               if (newassoc)
106 -                       netif_carrier_on(dev);
107 -               memset(&wreq, 0, sizeof(wreq));
108 +       if (active) {
109 +               //netif_carrier_on(vap->iv_dev);
110                 IEEE80211_ADDR_COPY(wreq.addr.sa_data, vap->iv_bssid);
111 -               wreq.addr.sa_family = ARPHRD_ETHER;
112 -#ifdef ATH_SUPERG_XR
113 -               if (vap->iv_xrvap && vap->iv_flags & IEEE80211_F_XR)
114 -                       dev = vap->iv_xrvap->iv_dev;
115 -#endif
116 -               wireless_send_event(dev, SIOCGIWAP, &wreq, NULL);
117         } else {
118 -               memset(&wreq, 0, sizeof(wreq));
119 -               IEEE80211_ADDR_COPY(wreq.addr.sa_data, ni->ni_macaddr);
120 -               wreq.addr.sa_family = ARPHRD_ETHER;
121 +               //netif_carrier_off(vap->iv_dev);
122 +               memset(wreq.ap_addr.sa_data, 0, ETHER_ADDR_LEN);
123 +       }
124 +       wireless_send_event(dev, SIOCGIWAP, &wreq, NULL);
125 +}
126 +
127 +void
128 +ieee80211_notify_node_join(struct ieee80211_node *ni, int newassoc)
129 +{
130 +       struct ieee80211vap *vap = ni->ni_vap;
131 +       struct net_device *dev = vap->iv_dev;
132 +       union iwreq_data wreq;
133 +
134 +       if (ni == vap->iv_bss)
135 +               return;
136 +
137 +       memset(&wreq, 0, sizeof(wreq));
138 +       IEEE80211_ADDR_COPY(wreq.addr.sa_data, ni->ni_macaddr);
139 +       wreq.addr.sa_family = ARPHRD_ETHER;
140  #ifdef ATH_SUPERG_XR
141 -               if (vap->iv_xrvap && vap->iv_flags & IEEE80211_F_XR)
142 -                       dev = vap->iv_xrvap->iv_dev;
143 +       if (vap->iv_xrvap && vap->iv_flags & IEEE80211_F_XR)
144 +               dev = vap->iv_xrvap->iv_dev;
145  #endif
146 -               wireless_send_event(dev, IWEVREGISTERED, &wreq, NULL);
147 -       }
148 +       wireless_send_event(dev, IWEVREGISTERED, &wreq, NULL);
149  }
150  
151  void
152 @@ -269,18 +295,14 @@ ieee80211_notify_node_leave(struct ieee8
153         struct net_device *dev = vap->iv_dev;
154         union iwreq_data wreq;
155  
156 -       if (ni == vap->iv_bss) {
157 -               netif_carrier_off(dev);
158 -               memset(wreq.ap_addr.sa_data, 0, ETHER_ADDR_LEN);
159 -               wreq.ap_addr.sa_family = ARPHRD_ETHER;
160 -               wireless_send_event(dev, SIOCGIWAP, &wreq, NULL);
161 -       } else {
162 -               /* fire off wireless event station leaving */
163 -               memset(&wreq, 0, sizeof(wreq));
164 -               IEEE80211_ADDR_COPY(wreq.addr.sa_data, ni->ni_macaddr);
165 -               wreq.addr.sa_family = ARPHRD_ETHER;
166 -               wireless_send_event(dev, IWEVEXPIRED, &wreq, NULL);
167 -       }
168 +       if (ni == vap->iv_bss)
169 +               return;
170 +
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);
176  }
177  
178  void
179 --- a/net80211/ieee80211_node.c
180 +++ b/net80211/ieee80211_node.c
181 @@ -2332,6 +2332,7 @@ ieee80211_node_leave(struct ieee80211_no
182                 count_suppchans(ic, ni, -1);
183         IEEE80211_UNLOCK_IRQ(ic);
184  
185 +done:
186         /*
187          * Cleanup station state.  In particular clear various
188          * state that might otherwise be reused if the node
189 @@ -2339,7 +2340,7 @@ ieee80211_node_leave(struct ieee80211_no
190          * (and memory is reclaimed).
191          */
192         ieee80211_sta_leave(ni);
193 -done:
194 +
195         /* Run a cleanup */
196  #ifdef IEEE80211_DEBUG_REFCNT
197         ic->ic_node_cleanup_debug(ni, __func__, __LINE__);
198 --- a/net80211/ieee80211_node.h
199 +++ b/net80211/ieee80211_node.h
200 @@ -60,7 +60,7 @@
201  #define        IEEE80211_INACT_PROBE   (30/IEEE80211_INACT_WAIT)       /* probe */
202  #define        IEEE80211_INACT_SCAN    (300/IEEE80211_INACT_WAIT)      /* scanned */
203  
204 -#define        IEEE80211_TRANS_WAIT    5                               /* mgt frame tx timer (secs) */
205 +#define        IEEE80211_TRANS_WAIT    300                             /* mgt frame tx timer (msecs) */
206  
207  #define        IEEE80211_NODE_HASHSIZE 32
208  /* simple hash is enough for variation of macaddr */
209 --- a/net80211/ieee80211_output.c
210 +++ b/net80211/ieee80211_output.c
211 @@ -2141,7 +2141,7 @@ ieee80211_send_mgmt(struct ieee80211_nod
212  
213         ieee80211_mgmt_output(ieee80211_ref_node(ni), skb, type);
214         if (timer)
215 -               mod_timer(&vap->iv_mgtsend, jiffies + timer * HZ);
216 +               mod_timer(&vap->iv_mgtsend, jiffies + msecs_to_jiffies(timer));
217         return 0;
218  bad:
219         return ret;
220 --- a/net80211/ieee80211_wireless.c
221 +++ b/net80211/ieee80211_wireless.c
222 @@ -514,8 +514,9 @@ ieee80211_ioctl_siwap(struct net_device 
223                         vap->iv_flags |= IEEE80211_F_DESBSSID;
224  
225                 IEEE80211_ADDR_COPY(vap->iv_des_bssid, &ap_addr->sa_data);
226 -               if (IS_UP_AUTO(vap))
227 +               if (IS_UP(vap->iv_dev)) {
228                         ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);
229 +               }
230         }
231         return 0;
232  }
233 --- a/net80211/ieee80211_linux.h
234 +++ b/net80211/ieee80211_linux.h
235 @@ -643,6 +643,7 @@ void ieee80211_vlan_vdetach(struct ieee8
236  #define        free_netdev(dev)        kfree(dev)
237  #endif
238  
239 +void ieee80211_update_link_status(struct ieee80211vap *vap, int nstate, int ostate);
240  void ieee80211_ioctl_vattach(struct ieee80211vap *);
241  void ieee80211_ioctl_vdetach(struct ieee80211vap *);
242  struct ifreq;