From: Felix Fietkau 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 --- --- 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: