diff options
Diffstat (limited to 'net/mac80211/tx.c')
-rw-r--r-- | net/mac80211/tx.c | 45 |
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, |