developer | 2c78ce7 | 2023-02-24 11:26:12 +0800 | [diff] [blame] | 1 | From: Felix Fietkau <nbd@nbd.name> |
| 2 | Date: Thu, 16 Feb 2023 11:07:30 +0100 |
| 3 | Subject: [PATCH] wifi: mac80211: use mesh header cache to speed up mesh |
| 4 | forwarding |
| 5 | |
| 6 | Use it to look up the next hop address + sta pointer + key and call |
| 7 | __ieee80211_mesh_xmit_fast to queue the tx frame. |
| 8 | |
| 9 | Significantly reduces mesh forwarding path CPU usage and enables the |
| 10 | use of iTXQ. |
| 11 | |
| 12 | Signed-off-by: Felix Fietkau <nbd@nbd.name> |
| 13 | --- |
| 14 | |
| 15 | --- a/net/mac80211/rx.c |
| 16 | +++ b/net/mac80211/rx.c |
| 17 | @@ -2731,6 +2731,7 @@ ieee80211_rx_mesh_data(struct ieee80211_ |
| 18 | struct ieee80211_hdr hdr = { |
| 19 | .frame_control = cpu_to_le16(fc) |
| 20 | }; |
| 21 | + struct mhdr_cache_entry *entry = NULL; |
| 22 | struct ieee80211_hdr *fwd_hdr; |
| 23 | struct ieee80211s_hdr *mesh_hdr; |
| 24 | struct ieee80211_tx_info *info; |
| 25 | @@ -2788,7 +2789,12 @@ ieee80211_rx_mesh_data(struct ieee80211_ |
| 26 | return RX_DROP_MONITOR; |
| 27 | } |
| 28 | |
| 29 | - if (mesh_hdr->flags & MESH_FLAGS_AE) { |
| 30 | + if ((mesh_hdr->flags & MESH_FLAGS_AE) == MESH_FLAGS_AE_A5_A6) |
| 31 | + entry = mesh_get_cached_hdr(sdata, mesh_hdr->eaddr1); |
| 32 | + else if (!(mesh_hdr->flags & MESH_FLAGS_AE)) |
| 33 | + entry = mesh_get_cached_hdr(sdata, eth->h_dest); |
| 34 | + |
| 35 | + if (!entry && (mesh_hdr->flags & MESH_FLAGS_AE)) { |
| 36 | struct mesh_path *mppath; |
| 37 | char *proxied_addr; |
| 38 | bool update = false; |
| 39 | @@ -2862,11 +2868,23 @@ ieee80211_rx_mesh_data(struct ieee80211_ |
| 40 | info->control.flags |= IEEE80211_TX_INTCFL_NEED_TXPROCESSING; |
| 41 | info->control.vif = &sdata->vif; |
| 42 | info->control.jiffies = jiffies; |
| 43 | + fwd_skb->dev = sdata->dev; |
| 44 | if (multicast) { |
| 45 | IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_mcast); |
| 46 | memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN); |
| 47 | /* update power mode indication when forwarding */ |
| 48 | ieee80211_mps_set_frame_flags(sdata, NULL, fwd_hdr); |
| 49 | + } else if (entry) { |
| 50 | + struct ieee80211_hdr *ehdr = (struct ieee80211_hdr *)entry->hdr; |
| 51 | + |
| 52 | + ether_addr_copy(fwd_hdr->addr1, ehdr->addr1); |
| 53 | + ether_addr_copy(fwd_hdr->addr2, sdata->vif.addr); |
| 54 | + IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_unicast); |
| 55 | + IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_frames); |
| 56 | + qos[0] = fwd_skb->priority; |
| 57 | + qos[1] = ieee80211_get_qos_ctl(ehdr)[1]; |
| 58 | + __ieee80211_mesh_xmit_fast(sdata, entry, fwd_skb); |
| 59 | + return RX_QUEUED; |
| 60 | } else if (!mesh_nexthop_lookup(sdata, fwd_skb)) { |
| 61 | /* mesh power mode flags updated in mesh_nexthop_lookup */ |
| 62 | IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_unicast); |
| 63 | @@ -2883,7 +2901,6 @@ ieee80211_rx_mesh_data(struct ieee80211_ |
| 64 | } |
| 65 | |
| 66 | IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_frames); |
| 67 | - fwd_skb->dev = sdata->dev; |
| 68 | ieee80211_add_pending_skb(local, fwd_skb); |
| 69 | |
| 70 | rx_accept: |