aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/rx.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/rx.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/rx.c')
-rw-r--r--net/mac80211/rx.c32
1 files changed, 28 insertions, 4 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 3ab9670f1809..2efa4dd47b5d 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1107,10 +1107,6 @@ ieee80211_data_to_8023(struct ieee80211_rx_data *rx)
1107 1107
1108 hdrlen = ieee80211_hdrlen(hdr->frame_control); 1108 hdrlen = ieee80211_hdrlen(hdr->frame_control);
1109 1109
1110 if (ieee80211_vif_is_mesh(&sdata->vif))
1111 hdrlen += ieee80211_get_mesh_hdrlen(
1112 (struct ieee80211s_hdr *) (skb->data + hdrlen));
1113
1114 /* convert IEEE 802.11 header + possible LLC headers into Ethernet 1110 /* convert IEEE 802.11 header + possible LLC headers into Ethernet
1115 * header 1111 * header
1116 * IEEE 802.11 address fields: 1112 * IEEE 802.11 address fields:
@@ -1134,6 +1130,15 @@ ieee80211_data_to_8023(struct ieee80211_rx_data *rx)
1134 if (unlikely(sdata->vif.type != NL80211_IFTYPE_WDS && 1130 if (unlikely(sdata->vif.type != NL80211_IFTYPE_WDS &&
1135 sdata->vif.type != NL80211_IFTYPE_MESH_POINT)) 1131 sdata->vif.type != NL80211_IFTYPE_MESH_POINT))
1136 return -1; 1132 return -1;
1133 if (ieee80211_vif_is_mesh(&sdata->vif)) {
1134 struct ieee80211s_hdr *meshdr = (struct ieee80211s_hdr *)
1135 (skb->data + hdrlen);
1136 hdrlen += ieee80211_get_mesh_hdrlen(meshdr);
1137 if (meshdr->flags & MESH_FLAGS_AE_A5_A6) {
1138 memcpy(dst, meshdr->eaddr1, ETH_ALEN);
1139 memcpy(src, meshdr->eaddr2, ETH_ALEN);
1140 }
1141 }
1137 break; 1142 break;
1138 case __constant_cpu_to_le16(IEEE80211_FCTL_FROMDS): 1143 case __constant_cpu_to_le16(IEEE80211_FCTL_FROMDS):
1139 if (sdata->vif.type != NL80211_IFTYPE_STATION || 1144 if (sdata->vif.type != NL80211_IFTYPE_STATION ||
@@ -1393,6 +1398,25 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
1393 /* illegal frame */ 1398 /* illegal frame */
1394 return RX_DROP_MONITOR; 1399 return RX_DROP_MONITOR;
1395 1400
1401 if (mesh_hdr->flags & MESH_FLAGS_AE_A5_A6){
1402 struct ieee80211_sub_if_data *sdata;
1403 struct mesh_path *mppath;
1404
1405 sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev);
1406 rcu_read_lock();
1407 mppath = mpp_path_lookup(mesh_hdr->eaddr2, sdata);
1408 if (!mppath) {
1409 mpp_path_add(mesh_hdr->eaddr2, hdr->addr4, sdata);
1410 } else {
1411 spin_lock_bh(&mppath->state_lock);
1412 mppath->exp_time = jiffies;
1413 if (compare_ether_addr(mppath->mpp, hdr->addr4) != 0)
1414 memcpy(mppath->mpp, hdr->addr4, ETH_ALEN);
1415 spin_unlock_bh(&mppath->state_lock);
1416 }
1417 rcu_read_unlock();
1418 }
1419
1396 if (compare_ether_addr(rx->dev->dev_addr, hdr->addr3) == 0) 1420 if (compare_ether_addr(rx->dev->dev_addr, hdr->addr3) == 0)
1397 return RX_CONTINUE; 1421 return RX_CONTINUE;
1398 1422