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.c45
1 files changed, 24 insertions, 21 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 771ec68b848d..4788f7b91f49 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1301,6 +1301,7 @@ int ieee80211_master_start_xmit(struct sk_buff *skb,
1301 struct net_device *dev) 1301 struct net_device *dev)
1302{ 1302{
1303 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1303 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1304 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1304 struct net_device *odev = NULL; 1305 struct net_device *odev = NULL;
1305 struct ieee80211_sub_if_data *osdata; 1306 struct ieee80211_sub_if_data *osdata;
1306 int headroom; 1307 int headroom;
@@ -1328,6 +1329,20 @@ int ieee80211_master_start_xmit(struct sk_buff *skb,
1328 1329
1329 osdata = IEEE80211_DEV_TO_SUB_IF(odev); 1330 osdata = IEEE80211_DEV_TO_SUB_IF(odev);
1330 1331
1332 if (ieee80211_vif_is_mesh(&osdata->vif) &&
1333 ieee80211_is_data(hdr->frame_control)) {
1334 if (ieee80211_is_data(hdr->frame_control)) {
1335 if (is_multicast_ether_addr(hdr->addr3))
1336 memcpy(hdr->addr1, hdr->addr3, ETH_ALEN);
1337 else
1338 if (mesh_nexthop_lookup(skb, odev))
1339 return 0;
1340 if (memcmp(odev->dev_addr, hdr->addr4, ETH_ALEN) != 0)
1341 IEEE80211_IFSTA_MESH_CTR_INC(&osdata->u.sta,
1342 fwded_frames);
1343 }
1344 }
1345
1331 may_encrypt = !skb->do_not_encrypt; 1346 may_encrypt = !skb->do_not_encrypt;
1332 1347
1333 headroom = osdata->local->tx_headroom; 1348 headroom = osdata->local->tx_headroom;
@@ -1472,30 +1487,17 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
1472 case IEEE80211_IF_TYPE_MESH_POINT: 1487 case IEEE80211_IF_TYPE_MESH_POINT:
1473 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); 1488 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS);
1474 /* RA TA DA SA */ 1489 /* RA TA DA SA */
1475 if (is_multicast_ether_addr(skb->data)) 1490 memset(hdr.addr1, 0, ETH_ALEN);
1476 memcpy(hdr.addr1, skb->data, ETH_ALEN);
1477 else if (mesh_nexthop_lookup(hdr.addr1, skb, dev))
1478 return 0;
1479 memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN); 1491 memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN);
1480 memcpy(hdr.addr3, skb->data, ETH_ALEN); 1492 memcpy(hdr.addr3, skb->data, ETH_ALEN);
1481 memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN); 1493 memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN);
1482 if (skb->pkt_type == PACKET_OTHERHOST) { 1494 if (!sdata->u.sta.mshcfg.dot11MeshTTL) {
1483 /* Forwarded frame, keep mesh ttl and seqnum */ 1495 /* Do not send frames with mesh_ttl == 0 */
1484 struct ieee80211s_hdr *prev_meshhdr; 1496 sdata->u.sta.mshstats.dropped_frames_ttl++;
1485 prev_meshhdr = ((struct ieee80211s_hdr *)skb->cb); 1497 ret = 0;
1486 meshhdrlen = ieee80211_get_mesh_hdrlen(prev_meshhdr); 1498 goto fail;
1487 memcpy(&mesh_hdr, prev_meshhdr, meshhdrlen);
1488 sdata->u.sta.mshstats.fwded_frames++;
1489 } else {
1490 if (!sdata->u.sta.mshcfg.dot11MeshTTL) {
1491 /* Do not send frames with mesh_ttl == 0 */
1492 sdata->u.sta.mshstats.dropped_frames_ttl++;
1493 ret = 0;
1494 goto fail;
1495 }
1496 meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr,
1497 sdata);
1498 } 1499 }
1500 meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr, sdata);
1499 hdrlen = 30; 1501 hdrlen = 30;
1500 break; 1502 break;
1501#endif 1503#endif
@@ -1543,7 +1545,8 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
1543 * Drop unicast frames to unauthorised stations unless they are 1545 * Drop unicast frames to unauthorised stations unless they are
1544 * EAPOL frames from the local station. 1546 * EAPOL frames from the local station.
1545 */ 1547 */
1546 if (unlikely(!is_multicast_ether_addr(hdr.addr1) && 1548 if (!ieee80211_vif_is_mesh(&sdata->vif) &&
1549 unlikely(!is_multicast_ether_addr(hdr.addr1) &&
1547 !(sta_flags & WLAN_STA_AUTHORIZED) && 1550 !(sta_flags & WLAN_STA_AUTHORIZED) &&
1548 !(ethertype == ETH_P_PAE && 1551 !(ethertype == ETH_P_PAE &&
1549 compare_ether_addr(dev->dev_addr, 1552 compare_ether_addr(dev->dev_addr,