Search Linux Wireless

[RFC 09/12] mac80211: add shared-mbss transmit path

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Bob Copeland <me@xxxxxxxxxxxxxxx>

Transmit locally-originated group data frames on every interface
so that members of the mesh on every channel will see the frame.

For individually-addressed frames, when we resolve the next
hop, the outgoing interface might be different than the
originator if the best path is on a different channel.
Requeue such frames on the correct interface's pending queue.

Signed-off-by: Bob Copeland <bob@xxxxxxxxxxx>
---
 net/mac80211/mesh_hwmp.c |   12 +++++++++++-
 net/mac80211/tx.c        |    3 +++
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index d8eaccc..6ba483e 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -1115,6 +1115,7 @@ int mesh_nexthop_resolve(struct ieee80211_sub_if_data *sdata,
 			 struct sk_buff *skb)
 {
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+	struct ieee80211_sub_if_data *dest_sdata;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	struct mesh_local_bss *mbss = mbss(sdata);
 	struct mesh_path *mpath;
@@ -1128,8 +1129,17 @@ int mesh_nexthop_resolve(struct ieee80211_sub_if_data *sdata,
 
 	rcu_read_lock();
 	err = mesh_nexthop_lookup(mbss, skb);
-	if (!err)
+	if (!err) {
+		dest_sdata = vif_to_sdata(info->control.vif);
+		/* requeue if mesh path uses a different interface */
+		if (dest_sdata != sdata) {
+			info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
+			ieee80211_set_qos_hdr(dest_sdata, skb);
+			ieee80211_add_pending_skb(dest_sdata->local, skb);
+			err = -EAGAIN;
+		}
 		goto endlookup;
+	}
 
 	/* no nexthop found, start resolving */
 	mpath = mesh_path_lookup(mbss, target_addr);
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index c132c76..4b28680 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1452,6 +1452,9 @@ void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
 		} else {
 			ieee80211_mps_set_frame_flags(sdata, NULL, hdr);
 		}
+		if (is_multicast_ether_addr(hdr->addr1) &&
+		    ieee80211_is_data(hdr->frame_control))
+			mesh_bss_forward_tx(sdata, skb);
 	}
 
 	ieee80211_set_qos_hdr(sdata, skb);
-- 
1.7.10.4

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux