mirror of
https://github.com/openwrt/openwrt.git
synced 2025-01-01 11:36:49 +00:00
57db2280a2
fix forwarding received mesh a-msdu packets add fast xmit support for mesh to improve performance Signed-off-by: Felix Fietkau <nbd@nbd.name>
71 lines
2.5 KiB
Diff
71 lines
2.5 KiB
Diff
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:
|