diff options
author | Javier Cardona <javier@cozybit.com> | 2009-08-10 15:15:48 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-08-14 09:14:00 -0400 |
commit | 3c5772a5279de9eadfff7adb5ddea08106495fff (patch) | |
tree | 297772521c18283ccfa19aacb090f396fa2b399e /net/wireless/util.c | |
parent | a9e3091bf08ddea35f172549a8a21d5bd6ee6129 (diff) |
mac80211: Use 3-address format for mesh broadcast frames.
The 11s task group recently changed the frame mesh multicast/broadcast frame
format to use 3-address. This was done to avoid interactions with widely
deployed lazy-WDS access points.
This patch changes the format of group addressed frames, both mesh-originated
and proxied, to use the data format defined in draft D2.08 and forward. The
address fields used for group addressed frames is:
In 802.11 header
ToDS:0 FromDS:1
addr1: DA (broadcast/multicast address)
addr2: TA
addr3: Mesh SA
In address extension header:
addr4: SA (only present if frame was proxied)
Note that this change breaks backward compatibility with earlier mesh stack
versions.
Signed-off-by: Andrey Yurovsky <andrey@cozybit.com>
Signed-off-by: Javier Cardona <javier@cozybit.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
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) |