summaryrefslogtreecommitdiffstats
path: root/net/mac80211/tx.c
diff options
context:
space:
mode:
authorRajkumar Manoharan <rmanohar@codeaurora.org>2019-04-11 22:47:26 +0200
committerJohannes Berg <johannes.berg@intel.com>2019-04-26 13:02:11 +0200
commit8828f81ad4a2f4e89ebe6e7793c06ed767c31d53 (patch)
tree71415b59b1233bbca345250bcbdc622ba99fdc47 /net/mac80211/tx.c
parentmac80211: add option for setting control flags (diff)
downloadlinux-8828f81ad4a2f4e89ebe6e7793c06ed767c31d53.tar.xz
linux-8828f81ad4a2f4e89ebe6e7793c06ed767c31d53.zip
mac80211: probe unexercised mesh links
The requirement for mesh link metric refreshing, is that from one mesh point we be able to send some data frames to other mesh points which are not currently selected as a primary traffic path, but which are only 1 hop away. The absence of the primary path to the chosen node makes it necessary to apply some form of marking on a chosen packet stream so that the packets can be properly steered to the selected node for testing, and not by the regular mesh path lookup. Tested-by: Pradeep Kumar Chitrapu <pradeepc@codeaurora.org> Signed-off-by: Rajkumar Manoharan <rmanohar@codeaurora.org> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to '')
-rw-r--r--net/mac80211/tx.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 9e3678675f3b..8037384fc06e 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -2607,6 +2607,13 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata,
goto free;
}
band = chanctx_conf->def.chan->band;
+
+ /* For injected frames, fill RA right away as nexthop lookup
+ * will be skipped.
+ */
+ if ((ctrl_flags & IEEE80211_TX_CTRL_SKIP_MPATH_LOOKUP) &&
+ is_zero_ether_addr(hdr.addr1))
+ memcpy(hdr.addr1, skb->data, ETH_ALEN);
break;
#endif
case NL80211_IFTYPE_STATION:
@@ -5091,3 +5098,32 @@ int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
return 0;
}
+
+int ieee80211_probe_mesh_link(struct wiphy *wiphy, struct net_device *dev,
+ const u8 *buf, size_t len)
+{
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ struct ieee80211_local *local = sdata->local;
+ struct sk_buff *skb;
+
+ skb = dev_alloc_skb(local->hw.extra_tx_headroom + len +
+ 30 + /* header size */
+ 18); /* 11s header size */
+ if (!skb)
+ return -ENOMEM;
+
+ skb_reserve(skb, local->hw.extra_tx_headroom);
+ skb_put_data(skb, buf, len);
+
+ skb->dev = dev;
+ skb->protocol = htons(ETH_P_802_3);
+ skb_reset_network_header(skb);
+ skb_reset_mac_header(skb);
+
+ local_bh_disable();
+ __ieee80211_subif_start_xmit(skb, skb->dev, 0,
+ IEEE80211_TX_CTRL_SKIP_MPATH_LOOKUP);
+ local_bh_enable();
+
+ return 0;
+}