aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/ieee80211.h1
-rw-r--r--net/mac80211/mesh.c32
-rw-r--r--net/mac80211/mesh.h4
-rw-r--r--net/mac80211/tx.c4
4 files changed, 16 insertions, 25 deletions
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index cd681681d211..6042228954a7 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -536,7 +536,6 @@ struct ieee80211s_hdr {
536 __le32 seqnum; 536 __le32 seqnum;
537 u8 eaddr1[6]; 537 u8 eaddr1[6];
538 u8 eaddr2[6]; 538 u8 eaddr2[6];
539 u8 eaddr3[6];
540} __attribute__ ((packed)); 539} __attribute__ ((packed));
541 540
542/* Mesh flags */ 541/* Mesh flags */
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 8b5906c83f93..ca3af4685b0a 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -410,39 +410,33 @@ int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc,
410 * ieee80211_new_mesh_header - create a new mesh header 410 * ieee80211_new_mesh_header - create a new mesh header
411 * @meshhdr: uninitialized mesh header 411 * @meshhdr: uninitialized mesh header
412 * @sdata: mesh interface to be used 412 * @sdata: mesh interface to be used
413 * @addr4: addr4 of the mesh frame (1st in ae header) 413 * @addr4or5: 1st address in the ae header, which may correspond to address 4
414 * may be NULL 414 * (if addr6 is NULL) or address 5 (if addr6 is present). It may
415 * @addr5: addr5 of the mesh frame (1st or 2nd in ae header) 415 * be NULL.
416 * may be NULL unless addr6 is present 416 * @addr6: 2nd address in the ae header, which corresponds to addr6 of the
417 * @addr6: addr6 of the mesh frame (2nd or 3rd in ae header) 417 * mesh frame
418 * may be NULL unless addr5 is present
419 * 418 *
420 * Return the header length. 419 * Return the header length.
421 */ 420 */
422int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr, 421int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr,
423 struct ieee80211_sub_if_data *sdata, char *addr4, 422 struct ieee80211_sub_if_data *sdata, char *addr4or5,
424 char *addr5, char *addr6) 423 char *addr6)
425{ 424{
426 int aelen = 0; 425 int aelen = 0;
426 BUG_ON(!addr4or5 && addr6);
427 memset(meshhdr, 0, sizeof(*meshhdr)); 427 memset(meshhdr, 0, sizeof(*meshhdr));
428 meshhdr->ttl = sdata->u.mesh.mshcfg.dot11MeshTTL; 428 meshhdr->ttl = sdata->u.mesh.mshcfg.dot11MeshTTL;
429 put_unaligned(cpu_to_le32(sdata->u.mesh.mesh_seqnum), &meshhdr->seqnum); 429 put_unaligned(cpu_to_le32(sdata->u.mesh.mesh_seqnum), &meshhdr->seqnum);
430 sdata->u.mesh.mesh_seqnum++; 430 sdata->u.mesh.mesh_seqnum++;
431 if (addr4) { 431 if (addr4or5 && !addr6) {
432 meshhdr->flags |= MESH_FLAGS_AE_A4; 432 meshhdr->flags |= MESH_FLAGS_AE_A4;
433 aelen += ETH_ALEN; 433 aelen += ETH_ALEN;
434 memcpy(meshhdr->eaddr1, addr4, ETH_ALEN); 434 memcpy(meshhdr->eaddr1, addr4or5, ETH_ALEN);
435 } 435 } else if (addr4or5 && addr6) {
436 if (addr5 && addr6) {
437 meshhdr->flags |= MESH_FLAGS_AE_A5_A6; 436 meshhdr->flags |= MESH_FLAGS_AE_A5_A6;
438 aelen += 2 * ETH_ALEN; 437 aelen += 2 * ETH_ALEN;
439 if (!addr4) { 438 memcpy(meshhdr->eaddr1, addr4or5, ETH_ALEN);
440 memcpy(meshhdr->eaddr1, addr5, ETH_ALEN); 439 memcpy(meshhdr->eaddr2, addr6, ETH_ALEN);
441 memcpy(meshhdr->eaddr2, addr6, ETH_ALEN);
442 } else {
443 memcpy(meshhdr->eaddr2, addr5, ETH_ALEN);
444 memcpy(meshhdr->eaddr3, addr6, ETH_ALEN);
445 }
446 } 440 }
447 return 6 + aelen; 441 return 6 + aelen;
448} 442}
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 890dd19c2eca..b99e230fe31c 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -187,8 +187,8 @@ struct mesh_rmc {
187int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc, 187int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc,
188 const u8 *da, const u8 *sa); 188 const u8 *da, const u8 *sa);
189int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr, 189int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr,
190 struct ieee80211_sub_if_data *sdata, char *addr4, 190 struct ieee80211_sub_if_data *sdata, char *addr4or5,
191 char *addr5, char *addr6); 191 char *addr6);
192int mesh_rmc_check(u8 *addr, struct ieee80211s_hdr *mesh_hdr, 192int mesh_rmc_check(u8 *addr, struct ieee80211s_hdr *mesh_hdr,
193 struct ieee80211_sub_if_data *sdata); 193 struct ieee80211_sub_if_data *sdata);
194bool mesh_matches_local(struct ieee802_11_elems *ie, 194bool mesh_matches_local(struct ieee802_11_elems *ie,
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index f4b1b624ea9f..807dcd06e268 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1811,7 +1811,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1811 hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc, 1811 hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc,
1812 skb->data, skb->data + ETH_ALEN); 1812 skb->data, skb->data + ETH_ALEN);
1813 meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr, 1813 meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr,
1814 sdata, NULL, NULL, NULL); 1814 sdata, NULL, NULL);
1815 } else { 1815 } else {
1816 /* packet from other interface */ 1816 /* packet from other interface */
1817 struct mesh_path *mppath; 1817 struct mesh_path *mppath;
@@ -1844,13 +1844,11 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1844 ieee80211_new_mesh_header(&mesh_hdr, 1844 ieee80211_new_mesh_header(&mesh_hdr,
1845 sdata, 1845 sdata,
1846 skb->data + ETH_ALEN, 1846 skb->data + ETH_ALEN,
1847 NULL,
1848 NULL); 1847 NULL);
1849 else 1848 else
1850 meshhdrlen = 1849 meshhdrlen =
1851 ieee80211_new_mesh_header(&mesh_hdr, 1850 ieee80211_new_mesh_header(&mesh_hdr,
1852 sdata, 1851 sdata,
1853 NULL,
1854 skb->data, 1852 skb->data,
1855 skb->data + ETH_ALEN); 1853 skb->data + ETH_ALEN);
1856 1854