Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mac80211: remove one user of ieee80211_get_hdr_info

ccmp_special_blocks was only using it to calculate data_len,
calculate that directly.

Use unaligned helpers rather than masking/shifting.

Use symbolic constants for the masked frame_control, and do it directly
on a le16 value.

Signed-off-by: Harvey Harrison <harvey.harrison@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>

authored by

Harvey Harrison and committed by
John W. Linville
f14df804 73e1f7c8

+36 -40
+36 -40
net/mac80211/wpa.c
··· 11 11 #include <linux/slab.h> 12 12 #include <linux/skbuff.h> 13 13 #include <linux/compiler.h> 14 + #include <linux/ieee80211.h> 15 + #include <asm/unaligned.h> 14 16 #include <net/mac80211.h> 15 17 16 18 #include "ieee80211_i.h" ··· 298 296 static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad, 299 297 int encrypted) 300 298 { 301 - u16 fc; 302 - int a4_included, qos_included; 303 - u8 qos_tid, *fc_pos, *data, *sa, *da; 304 - int len_a; 305 - size_t data_len; 306 - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 299 + __le16 mask_fc; 300 + int a4_included; 301 + u8 qos_tid; 302 + u16 data_len, len_a; 303 + unsigned int hdrlen; 304 + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 307 305 308 - fc_pos = (u8 *) &hdr->frame_control; 309 - fc = fc_pos[0] ^ (fc_pos[1] << 8); 310 - a4_included = (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == 311 - (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS); 306 + /* 307 + * Mask FC: zero subtype b4 b5 b6 308 + * Retry, PwrMgt, MoreData; set Protected 309 + */ 310 + mask_fc = hdr->frame_control; 311 + mask_fc &= ~cpu_to_le16(0x0070 | IEEE80211_FCTL_RETRY | 312 + IEEE80211_FCTL_PM | IEEE80211_FCTL_MOREDATA); 313 + mask_fc |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); 312 314 313 - ieee80211_get_hdr_info(skb, &sa, &da, &qos_tid, &data, &data_len); 314 - data_len -= CCMP_HDR_LEN + (encrypted ? CCMP_MIC_LEN : 0); 315 - if (qos_tid & 0x80) { 316 - qos_included = 1; 317 - qos_tid &= IEEE80211_QOS_CTL_TID_MASK; 318 - } else 319 - qos_included = 0; 315 + hdrlen = ieee80211_hdrlen(hdr->frame_control); 316 + len_a = hdrlen - 2; 317 + a4_included = ieee80211_has_a4(hdr->frame_control); 318 + 319 + if (ieee80211_is_data_qos(hdr->frame_control)) 320 + qos_tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; 321 + else 322 + qos_tid = 0; 323 + 324 + data_len = skb->len - hdrlen - CCMP_HDR_LEN; 325 + if (encrypted) 326 + data_len -= CCMP_MIC_LEN; 327 + 320 328 /* First block, b_0 */ 321 - 322 329 b_0[0] = 0x59; /* flags: Adata: 1, M: 011, L: 001 */ 323 330 /* Nonce: QoS Priority | A2 | PN */ 324 331 b_0[1] = qos_tid; 325 332 memcpy(&b_0[2], hdr->addr2, ETH_ALEN); 326 333 memcpy(&b_0[8], pn, CCMP_PN_LEN); 327 334 /* l(m) */ 328 - b_0[14] = (data_len >> 8) & 0xff; 329 - b_0[15] = data_len & 0xff; 330 - 335 + put_unaligned_be16(data_len, &b_0[14]); 331 336 332 337 /* AAD (extra authenticate-only data) / masked 802.11 header 333 338 * FC | A1 | A2 | A3 | SC | [A4] | [QC] */ 334 - 335 - len_a = a4_included ? 28 : 22; 336 - if (qos_included) 337 - len_a += IEEE80211_QOS_CTL_LEN; 338 - 339 - aad[0] = 0; /* (len_a >> 8) & 0xff; */ 340 - aad[1] = len_a & 0xff; 341 - /* Mask FC: zero subtype b4 b5 b6 */ 342 - aad[2] = fc_pos[0] & ~(BIT(4) | BIT(5) | BIT(6)); 343 - /* Retry, PwrMgt, MoreData; set Protected */ 344 - aad[3] = (fc_pos[1] & ~(BIT(3) | BIT(4) | BIT(5))) | BIT(6); 339 + put_unaligned_be16(len_a, &aad[0]); 340 + put_unaligned(mask_fc, (__le16 *)&aad[2]); 345 341 memcpy(&aad[4], &hdr->addr1, 3 * ETH_ALEN); 346 342 347 343 /* Mask Seq#, leave Frag# */ 348 344 aad[22] = *((u8 *) &hdr->seq_ctrl) & 0x0f; 349 345 aad[23] = 0; 346 + 350 347 if (a4_included) { 351 348 memcpy(&aad[24], hdr->addr4, ETH_ALEN); 352 - aad[30] = 0; 349 + aad[30] = qos_tid; 353 350 aad[31] = 0; 354 - } else 351 + } else { 355 352 memset(&aad[24], 0, ETH_ALEN + IEEE80211_QOS_CTL_LEN); 356 - if (qos_included) { 357 - u8 *dpos = &aad[a4_included ? 30 : 24]; 358 - 359 - /* Mask QoS Control field */ 360 - dpos[0] = qos_tid; 361 - dpos[1] = 0; 353 + aad[24] = qos_tid; 362 354 } 363 355 } 364 356