blob: e0d4e60ed74008a1c7cd4163c39aabd5a5bdc9b1 [file] [log] [blame]
From: Felix Fietkau <nbd@nbd.name>
Date: Thu, 16 Feb 2023 11:07:30 +0100
Subject: [PATCH] wifi: mac80211: use mesh header cache to speed up mesh
forwarding
Use it to look up the next hop address + sta pointer + key and call
__ieee80211_mesh_xmit_fast to queue the tx frame.
Significantly reduces mesh forwarding path CPU usage and enables the
use of iTXQ.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2731,6 +2731,7 @@ ieee80211_rx_mesh_data(struct ieee80211_
struct ieee80211_hdr hdr = {
.frame_control = cpu_to_le16(fc)
};
+ struct mhdr_cache_entry *entry = NULL;
struct ieee80211_hdr *fwd_hdr;
struct ieee80211s_hdr *mesh_hdr;
struct ieee80211_tx_info *info;
@@ -2788,7 +2789,12 @@ ieee80211_rx_mesh_data(struct ieee80211_
return RX_DROP_MONITOR;
}
- if (mesh_hdr->flags & MESH_FLAGS_AE) {
+ if ((mesh_hdr->flags & MESH_FLAGS_AE) == MESH_FLAGS_AE_A5_A6)
+ entry = mesh_get_cached_hdr(sdata, mesh_hdr->eaddr1);
+ else if (!(mesh_hdr->flags & MESH_FLAGS_AE))
+ entry = mesh_get_cached_hdr(sdata, eth->h_dest);
+
+ if (!entry && (mesh_hdr->flags & MESH_FLAGS_AE)) {
struct mesh_path *mppath;
char *proxied_addr;
bool update = false;
@@ -2862,11 +2868,23 @@ ieee80211_rx_mesh_data(struct ieee80211_
info->control.flags |= IEEE80211_TX_INTCFL_NEED_TXPROCESSING;
info->control.vif = &sdata->vif;
info->control.jiffies = jiffies;
+ fwd_skb->dev = sdata->dev;
if (multicast) {
IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_mcast);
memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN);
/* update power mode indication when forwarding */
ieee80211_mps_set_frame_flags(sdata, NULL, fwd_hdr);
+ } else if (entry) {
+ struct ieee80211_hdr *ehdr = (struct ieee80211_hdr *)entry->hdr;
+
+ ether_addr_copy(fwd_hdr->addr1, ehdr->addr1);
+ ether_addr_copy(fwd_hdr->addr2, sdata->vif.addr);
+ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_unicast);
+ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_frames);
+ qos[0] = fwd_skb->priority;
+ qos[1] = ieee80211_get_qos_ctl(ehdr)[1];
+ __ieee80211_mesh_xmit_fast(sdata, entry, fwd_skb);
+ return RX_QUEUED;
} else if (!mesh_nexthop_lookup(sdata, fwd_skb)) {
/* mesh power mode flags updated in mesh_nexthop_lookup */
IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_unicast);
@@ -2883,7 +2901,6 @@ ieee80211_rx_mesh_data(struct ieee80211_
}
IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_frames);
- fwd_skb->dev = sdata->dev;
ieee80211_add_pending_skb(local, fwd_skb);
rx_accept: