madwifi: clean up handling of various timings such as slot time, ack timeout, eifs...
[openwrt.git] / package / madwifi / patches / 309-micfail_detect.patch
1 --- a/ath/if_ath.c
2 +++ b/ath/if_ath.c
3 @@ -6457,6 +6457,7 @@ ath_rx_poll(struct net_device *dev, int 
4         int type;
5         u_int phyerr;
6         u_int processed = 0, early_stop = 0;
7 +       u_int mic_fail = 0;
8  
9         DPRINTF(sc, ATH_DEBUG_RX_PROC, "invoked\n");
10  process_rx_again:
11 @@ -6558,24 +6559,8 @@ process_rx_again:
12                         }
13                         if (rs->rs_status & HAL_RXERR_MIC) {
14                                 sc->sc_stats.ast_rx_badmic++;
15 -                               /*
16 -                                * Do minimal work required to hand off
17 -                                * the 802.11 header for notification.
18 -                                */
19 -                               /* XXX frag's and QoS frames */
20 -                               if (len >= sizeof (struct ieee80211_frame)) {
21 -                                       bus_dma_sync_single(sc->sc_bdev,
22 -                                           bf->bf_skbaddr, len,
23 -                                           BUS_DMA_FROMDEVICE);
24 -#if 0
25 -/* XXX revalidate MIC, lookup ni to find VAP */
26 -                                       ieee80211_notify_michael_failure(ic,
27 -                                           (struct ieee80211_frame *)skb->data,
28 -                                           sc->sc_splitmic ?
29 -                                               rs->rs_keyix - 32 : rs->rs_keyix
30 -                                       );
31 -#endif
32 -                               }
33 +                               mic_fail = 1;
34 +                               goto rx_accept;
35                         }
36                         /*
37                          * Reject error frames if we have no vaps that
38 @@ -6614,8 +6599,9 @@ rx_accept:
39                 /*
40                  * Finished monitor mode handling, now reject
41                  * error frames before passing to other vaps
42 +                * Ignore MIC failures here, as we need to recheck them
43                  */
44 -               if (rs->rs_status != 0) {
45 +               if (rs->rs_status & ~(HAL_RXERR_MIC | HAL_RXERR_DECRYPT)) {
46                         ieee80211_dev_kfree_skb(&skb);
47                         goto rx_next;
48                 }
49 @@ -6623,6 +6609,26 @@ rx_accept:
50                 /* remove the CRC */
51                 skb_trim(skb, skb->len - IEEE80211_CRC_LEN);
52  
53 +               if (mic_fail) {
54 +                       /* Ignore control frames which are reported with mic error */
55 +                   if ((((struct ieee80211_frame *)skb->data)->i_fc[0] &
56 +                                       IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL)
57 +                               goto drop_micfail;
58 +
59 +                       ni = ieee80211_find_rxnode(ic, (const struct ieee80211_frame_min *) skb->data);
60 +
61 +                       if (ni && ni->ni_table) {
62 +                               ieee80211_check_mic(ni, skb);
63 +                               ieee80211_unref_node(&ni);
64 +                       }
65 +
66 +drop_micfail:
67 +                       dev_kfree_skb_any(skb);
68 +                       skb = NULL;
69 +                       mic_fail = 0;
70 +                       goto rx_next;
71 +               }
72 +
73                 /*
74                  * From this point on we assume the frame is at least
75                  * as large as ieee80211_frame_min; verify that.
76 @@ -6635,6 +6641,7 @@ rx_accept:
77                         goto rx_next;
78                 }
79  
80 +               /* MIC failure. Drop the packet in any case */
81                 /*
82                  * Normal receive.
83                  */
84 --- a/net80211/ieee80211_crypto_ccmp.c
85 +++ b/net80211/ieee80211_crypto_ccmp.c
86 @@ -73,7 +73,7 @@ static int ccmp_setkey(struct ieee80211_
87  static int ccmp_encap(struct ieee80211_key *, struct sk_buff *, u_int8_t);
88  static int ccmp_decap(struct ieee80211_key *, struct sk_buff *, int);
89  static int ccmp_enmic(struct ieee80211_key *, struct sk_buff *, int);
90 -static int ccmp_demic(struct ieee80211_key *, struct sk_buff *, int);
91 +static int ccmp_demic(struct ieee80211_key *, struct sk_buff *, int, int);
92  
93  static const struct ieee80211_cipher ccmp = {
94         .ic_name        = "AES-CCM",
95 @@ -308,7 +308,7 @@ ccmp_decap(struct ieee80211_key *k, stru
96   * Verify and strip MIC from the frame.
97   */
98  static int
99 -ccmp_demic(struct ieee80211_key *k, struct sk_buff *skb, int hdrlen)
100 +ccmp_demic(struct ieee80211_key *k, struct sk_buff *skb, int hdrlen, int force)
101  {
102         return 1;
103  }
104 --- a/net80211/ieee80211_crypto.h
105 +++ b/net80211/ieee80211_crypto.h
106 @@ -145,7 +145,7 @@ struct ieee80211_cipher {
107         int (*ic_encap)(struct ieee80211_key *, struct sk_buff *, u_int8_t);
108         int (*ic_decap)(struct ieee80211_key *, struct sk_buff *, int);
109         int (*ic_enmic)(struct ieee80211_key *, struct sk_buff *, int);
110 -       int (*ic_demic)(struct ieee80211_key *, struct sk_buff *, int);
111 +       int (*ic_demic)(struct ieee80211_key *, struct sk_buff *, int, int);
112  };
113  extern const struct ieee80211_cipher ieee80211_cipher_none;
114  
115 @@ -163,10 +163,10 @@ struct ieee80211_key *ieee80211_crypto_d
116   */
117  static __inline int
118  ieee80211_crypto_demic(struct ieee80211vap *vap, struct ieee80211_key *k,
119 -       struct sk_buff *skb, int hdrlen)
120 +       struct sk_buff *skb, int hdrlen, int force)
121  {
122         const struct ieee80211_cipher *cip = k->wk_cipher;
123 -       return (cip->ic_miclen > 0 ? cip->ic_demic(k, skb, hdrlen) : 1);
124 +       return (cip->ic_miclen > 0 ? cip->ic_demic(k, skb, hdrlen, force) : 1);
125  }
126  
127  /*
128 --- a/net80211/ieee80211_crypto_none.c
129 +++ b/net80211/ieee80211_crypto_none.c
130 @@ -52,7 +52,7 @@ static int none_setkey(struct ieee80211_
131  static int none_encap(struct ieee80211_key *, struct sk_buff *, u_int8_t);
132  static int none_decap(struct ieee80211_key *, struct sk_buff *, int);
133  static int none_enmic(struct ieee80211_key *, struct sk_buff *, int);
134 -static int none_demic(struct ieee80211_key *, struct sk_buff *, int);
135 +static int none_demic(struct ieee80211_key *, struct sk_buff *, int, int);
136  
137  const struct ieee80211_cipher ieee80211_cipher_none = {
138         .ic_name        = "NONE",
139 @@ -137,7 +137,7 @@ none_enmic(struct ieee80211_key *k, stru
140  }
141  
142  static int
143 -none_demic(struct ieee80211_key *k, struct sk_buff *skb, int hdrlen)
144 +none_demic(struct ieee80211_key *k, struct sk_buff *skb, int hdrlen, int force)
145  {
146         struct ieee80211vap *vap = k->wk_private;
147  
148 --- a/net80211/ieee80211_crypto_tkip.c
149 +++ b/net80211/ieee80211_crypto_tkip.c
150 @@ -57,7 +57,7 @@ static int tkip_setkey(struct ieee80211_
151  static int tkip_encap(struct ieee80211_key *, struct sk_buff *, u_int8_t);
152  static int tkip_enmic(struct ieee80211_key *, struct sk_buff *, int);
153  static int tkip_decap(struct ieee80211_key *, struct sk_buff *, int);
154 -static int tkip_demic(struct ieee80211_key *, struct sk_buff *, int);
155 +static int tkip_demic(struct ieee80211_key *, struct sk_buff *, int, int);
156  
157  static const struct ieee80211_cipher tkip  = {
158         .ic_name        = "TKIP",
159 @@ -339,7 +339,7 @@ tkip_decap(struct ieee80211_key *k, stru
160   * Verify and strip MIC from the frame.
161   */
162  static int
163 -tkip_demic(struct ieee80211_key *k, struct sk_buff *skb0, int hdrlen)
164 +tkip_demic(struct ieee80211_key *k, struct sk_buff *skb0, int hdrlen, int force)
165  {
166         struct tkip_ctx *ctx = k->wk_private;
167         struct sk_buff *skb;
168 @@ -355,7 +355,7 @@ tkip_demic(struct ieee80211_key *k, stru
169         }
170         wh = (struct ieee80211_frame *) skb0->data;
171         /* NB: skb left pointing at last in chain */
172 -       if (k->wk_flags & IEEE80211_KEY_SWMIC) {
173 +       if ((k->wk_flags & IEEE80211_KEY_SWMIC) || force) {
174                 struct ieee80211vap *vap = ctx->tc_vap;
175                 u8 mic[IEEE80211_WEP_MICLEN];
176                 u8 mic0[IEEE80211_WEP_MICLEN];
177 --- a/net80211/ieee80211_crypto_wep.c
178 +++ b/net80211/ieee80211_crypto_wep.c
179 @@ -54,7 +54,7 @@ static int wep_setkey(struct ieee80211_k
180  static int wep_encap(struct ieee80211_key *, struct sk_buff *, u_int8_t);
181  static int wep_decap(struct ieee80211_key *, struct sk_buff *, int);
182  static int wep_enmic(struct ieee80211_key *, struct sk_buff *, int);
183 -static int wep_demic(struct ieee80211_key *, struct sk_buff *, int);
184 +static int wep_demic(struct ieee80211_key *, struct sk_buff *, int, int);
185  
186  static const struct ieee80211_cipher wep = {
187         .ic_name        = "WEP",
188 @@ -244,7 +244,7 @@ wep_decap(struct ieee80211_key *k, struc
189   * Verify and strip MIC from the frame.
190   */
191  static int
192 -wep_demic(struct ieee80211_key *k, struct sk_buff *skb, int hdrlen)
193 +wep_demic(struct ieee80211_key *k, struct sk_buff *skb, int hdrlen, int force)
194  {
195         return 1;
196  }
197 --- a/net80211/ieee80211_input.c
198 +++ b/net80211/ieee80211_input.c
199 @@ -669,7 +669,7 @@ ieee80211_input(struct ieee80211vap * va
200                  * Next strip any MSDU crypto bits.
201                  */
202                 if (key != NULL &&
203 -                   !ieee80211_crypto_demic(vap, key, skb, hdrspace)) {
204 +                   !ieee80211_crypto_demic(vap, key, skb, hdrspace, 0)) {
205                         IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
206                                 ni->ni_macaddr, "data", "%s", "demic error");
207                         IEEE80211_NODE_STAT(ni, rx_demicfail);
208 @@ -4293,6 +4293,47 @@ ath_eth_type_trans(struct sk_buff *skb, 
209  }
210  #endif
211  
212 +/*
213 + * Process a frame w/ hw detected MIC failure.
214 + * The frame will be dropped in any case.
215 + */
216 +void
217 +ieee80211_check_mic(struct ieee80211_node *ni, struct sk_buff *skb)
218 +{
219 +       struct ieee80211vap *vap = ni->ni_vap;
220 +
221 +       struct ieee80211_frame *wh;
222 +       struct ieee80211_key *key;
223 +       int hdrspace;
224 +       struct ieee80211com *ic = vap->iv_ic;
225 +
226 +       if (skb->len < sizeof(struct ieee80211_frame_min)) {
227 +               IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY,
228 +                   ni->ni_macaddr, NULL,
229 +                   "too short (1): len %u", skb->len);
230 +               vap->iv_stats.is_rx_tooshort++;
231 +               return;
232 +       }
233 +
234 +       wh = (struct ieee80211_frame *)skb->data;
235 +
236 +       hdrspace = ieee80211_hdrspace(ic, wh);
237 +       key = ieee80211_crypto_decap(ni, skb, hdrspace);
238 +       if (key == NULL) {
239 +               /* NB: stats+msgs handled in crypto_decap */
240 +               IEEE80211_NODE_STAT(ni, rx_wepfail);
241 +               return;
242 +       }
243 +
244 +       if (!ieee80211_crypto_demic(vap, key, skb, hdrspace, 1)) {
245 +               IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
246 +                       ni->ni_macaddr, "data", "%s", "demic error");
247 +                       IEEE80211_NODE_STAT(ni, rx_demicfail);
248 +       }
249 +       return;
250 +}
251 +EXPORT_SYMBOL(ieee80211_check_mic);
252 +
253  #ifdef IEEE80211_DEBUG
254  /*
255   * Debugging support.
256 --- a/net80211/ieee80211_proto.h
257 +++ b/net80211/ieee80211_proto.h
258 @@ -90,6 +90,7 @@ int ieee80211_iserp_rateset(struct ieee8
259  void ieee80211_set11gbasicrates(struct ieee80211_rateset *, enum ieee80211_phymode);
260  enum ieee80211_phymode ieee80211_get11gbasicrates(struct ieee80211_rateset *);
261  void ieee80211_send_pspoll(struct ieee80211_node *);
262 +void ieee80211_check_mic(struct ieee80211_node *, struct sk_buff *);
263  
264  /*
265   * Return the size of the 802.11 header for a management or data frame.
266 --- a/net80211/ieee80211_linux.c
267 +++ b/net80211/ieee80211_linux.c
268 @@ -337,8 +337,8 @@ ieee80211_notify_replay_failure(struct i
269         /* TODO: needed parameters: count, keyid, key type, src address, TSC */
270         snprintf(buf, sizeof(buf), "%s(keyid=%d %scast addr=" MAC_FMT ")", tag,
271                 k->wk_keyix,
272 -               IEEE80211_IS_MULTICAST(wh->i_addr1) ?  "broad" : "uni",
273 -               MAC_ADDR(wh->i_addr1));
274 +               IEEE80211_IS_MULTICAST(wh->i_addr2) ?  "broad" : "uni",
275 +               MAC_ADDR(wh->i_addr2));
276         memset(&wrqu, 0, sizeof(wrqu));
277         wrqu.data.length = strlen(buf);
278         wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
279 --- a/net80211/ieee80211_output.c
280 +++ b/net80211/ieee80211_output.c
281 @@ -1074,13 +1074,16 @@ ieee80211_encap(struct ieee80211_node *n
282                         cip = (struct ieee80211_cipher *) key->wk_cipher;
283                         ciphdrsize = cip->ic_header;
284                         tailsize += (cip->ic_trailer + cip->ic_miclen);
285 +
286 +                       /* add the 8 bytes MIC length */
287 +                       if (cip->ic_cipher == IEEE80211_CIPHER_TKIP)
288 +                               pktlen += IEEE80211_WEP_MICLEN;
289                 }
290  
291                 pdusize = vap->iv_fragthreshold - (hdrsize_nopad + ciphdrsize);
292                 fragcnt = *framecnt =
293 -                       ((pktlen - (hdrsize_nopad + ciphdrsize)) / pdusize) +
294 -                       (((pktlen - (hdrsize_nopad + ciphdrsize)) %
295 -                               pdusize == 0) ? 0 : 1);
296 +                       ((pktlen - hdrsize_nopad) / pdusize) +
297 +                       (((pktlen - hdrsize_nopad) % pdusize == 0) ? 0 : 1);
298  
299                 /*
300                  * Allocate sk_buff for each subsequent fragment; First fragment
301 --- a/net80211/ieee80211_node.c
302 +++ b/net80211/ieee80211_node.c
303 @@ -2264,11 +2264,13 @@ ieee80211_node_leave(struct ieee80211_no
304         /* From this point onwards we can no longer find the node,
305          * so no more references are generated
306          */
307 -       ieee80211_remove_wds_addr(nt, ni->ni_macaddr);
308 -       ieee80211_del_wds_node(nt, ni);
309 -       IEEE80211_NODE_TABLE_LOCK_IRQ(nt);
310 -       node_table_leave_locked(nt, ni);
311 -       IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);
312 +       if (nt) {
313 +               ieee80211_remove_wds_addr(nt, ni->ni_macaddr);
314 +               ieee80211_del_wds_node(nt, ni);
315 +               IEEE80211_NODE_TABLE_LOCK_IRQ(nt);
316 +               node_table_leave_locked(nt, ni);
317 +               IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);
318 +       }
319  
320         /*
321          * If node wasn't previously associated all