aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/tx.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/tx.c')
-rw-r--r--net/mac80211/tx.c44
1 files changed, 38 insertions, 6 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 00d798cc9e04..00d96e63dce9 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1498,18 +1498,50 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
1498#ifdef CONFIG_MAC80211_MESH 1498#ifdef CONFIG_MAC80211_MESH
1499 case NL80211_IFTYPE_MESH_POINT: 1499 case NL80211_IFTYPE_MESH_POINT:
1500 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); 1500 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS);
1501 /* RA TA DA SA */
1502 memset(hdr.addr1, 0, ETH_ALEN);
1503 memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN);
1504 memcpy(hdr.addr3, skb->data, ETH_ALEN);
1505 memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN);
1506 if (!sdata->u.mesh.mshcfg.dot11MeshTTL) { 1501 if (!sdata->u.mesh.mshcfg.dot11MeshTTL) {
1507 /* Do not send frames with mesh_ttl == 0 */ 1502 /* Do not send frames with mesh_ttl == 0 */
1508 sdata->u.mesh.mshstats.dropped_frames_ttl++; 1503 sdata->u.mesh.mshstats.dropped_frames_ttl++;
1509 ret = 0; 1504 ret = 0;
1510 goto fail; 1505 goto fail;
1511 } 1506 }
1512 meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr, sdata); 1507 memset(&mesh_hdr, 0, sizeof(mesh_hdr));
1508
1509 if (compare_ether_addr(dev->dev_addr,
1510 skb->data + ETH_ALEN) == 0) {
1511 /* RA TA DA SA */
1512 memset(hdr.addr1, 0, ETH_ALEN);
1513 memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN);
1514 memcpy(hdr.addr3, skb->data, ETH_ALEN);
1515 memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN);
1516 meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr, sdata);
1517 } else {
1518 /* packet from other interface */
1519 struct mesh_path *mppath;
1520
1521 memset(hdr.addr1, 0, ETH_ALEN);
1522 memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN);
1523 memcpy(hdr.addr4, dev->dev_addr, ETH_ALEN);
1524
1525 if (is_multicast_ether_addr(skb->data))
1526 memcpy(hdr.addr3, skb->data, ETH_ALEN);
1527 else {
1528 rcu_read_lock();
1529 mppath = mpp_path_lookup(skb->data, sdata);
1530 if (mppath)
1531 memcpy(hdr.addr3, mppath->mpp, ETH_ALEN);
1532 else
1533 memset(hdr.addr3, 0xff, ETH_ALEN);
1534 rcu_read_unlock();
1535 }
1536
1537 mesh_hdr.flags |= MESH_FLAGS_AE_A5_A6;
1538 mesh_hdr.ttl = sdata->u.mesh.mshcfg.dot11MeshTTL;
1539 put_unaligned(cpu_to_le32(sdata->u.mesh.mesh_seqnum), &mesh_hdr.seqnum);
1540 memcpy(mesh_hdr.eaddr1, skb->data, ETH_ALEN);
1541 memcpy(mesh_hdr.eaddr2, skb->data + ETH_ALEN, ETH_ALEN);
1542 sdata->u.mesh.mesh_seqnum++;
1543 meshhdrlen = 18;
1544 }
1513 hdrlen = 30; 1545 hdrlen = 30;
1514 break; 1546 break;
1515#endif 1547#endif