aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/tx.c
diff options
context:
space:
mode:
authorYanBo <dreamfly281@gmail.com>2008-09-22 01:30:32 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-09-24 16:18:02 -0400
commit79617deeebb9cf089e2bc2aad19743b1209043f6 (patch)
tree52c93b45d07ce3cd5c78be743446068602e90234 /net/mac80211/tx.c
parent31e9ab2b180bccb3977b9a82ff357ac4c6ee3c83 (diff)
mac80211: mesh portal functionality support
Currently the mesh code doesn't support bridging mesh point interfaces with wired ethernet or AP to construct an MPP or MAP. This patch adds code to support the "6 address frame format packet" functionality to mesh point interfaces. Now the mesh network can be used as backhaul for end to end communication. Signed-off-by: Li YanBo <dreamfly281@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
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