diff options
Diffstat (limited to 'net/wireless/util.c')
-rw-r--r-- | net/wireless/util.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/net/wireless/util.c b/net/wireless/util.c index ba387d85dcfd..693275a16a26 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c | |||
@@ -274,11 +274,11 @@ static int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr) | |||
274 | switch (ae) { | 274 | switch (ae) { |
275 | case 0: | 275 | case 0: |
276 | return 6; | 276 | return 6; |
277 | case 1: | 277 | case MESH_FLAGS_AE_A4: |
278 | return 12; | 278 | return 12; |
279 | case 2: | 279 | case MESH_FLAGS_AE_A5_A6: |
280 | return 18; | 280 | return 18; |
281 | case 3: | 281 | case (MESH_FLAGS_AE_A4 | MESH_FLAGS_AE_A5_A6): |
282 | return 24; | 282 | return 24; |
283 | default: | 283 | default: |
284 | return 6; | 284 | return 6; |
@@ -333,10 +333,18 @@ int ieee80211_data_to_8023(struct sk_buff *skb, u8 *addr, | |||
333 | } | 333 | } |
334 | break; | 334 | break; |
335 | case cpu_to_le16(IEEE80211_FCTL_FROMDS): | 335 | case cpu_to_le16(IEEE80211_FCTL_FROMDS): |
336 | if (iftype != NL80211_IFTYPE_STATION || | 336 | if ((iftype != NL80211_IFTYPE_STATION && |
337 | iftype != NL80211_IFTYPE_MESH_POINT) || | ||
337 | (is_multicast_ether_addr(dst) && | 338 | (is_multicast_ether_addr(dst) && |
338 | !compare_ether_addr(src, addr))) | 339 | !compare_ether_addr(src, addr))) |
339 | return -1; | 340 | return -1; |
341 | if (iftype == NL80211_IFTYPE_MESH_POINT) { | ||
342 | struct ieee80211s_hdr *meshdr = | ||
343 | (struct ieee80211s_hdr *) (skb->data + hdrlen); | ||
344 | hdrlen += ieee80211_get_mesh_hdrlen(meshdr); | ||
345 | if (meshdr->flags & MESH_FLAGS_AE_A4) | ||
346 | memcpy(src, meshdr->eaddr1, ETH_ALEN); | ||
347 | } | ||
340 | break; | 348 | break; |
341 | case cpu_to_le16(0): | 349 | case cpu_to_le16(0): |
342 | if (iftype != NL80211_IFTYPE_ADHOC) | 350 | if (iftype != NL80211_IFTYPE_ADHOC) |