1
0
Fork 0
mirror of https://github.com/Ysurac/openmptcprouter.git synced 2025-02-12 11:21:55 +00:00

Update OpenWRT for 6.1 kernel

This commit is contained in:
Ycarus (Yannick Chabanois) 2023-09-27 17:02:46 +02:00
parent 71b3b8aac9
commit 46d5683e1d
8 changed files with 3 additions and 1230 deletions

View file

@ -1,15 +0,0 @@
--- a/src/linux/ifxos_linux_thread_drv.c 2023-05-22 08:50:14.087507831 +0200
+++ b/src/linux/ifxos_linux_thread_drv.c 2023-05-22 08:51:32.702129369 +0200
@@ -154,8 +154,11 @@
retVal = pThrCntrl->pThrFct(&pThrCntrl->thrParams);
pThrCntrl->thrParams.bRunning = IFX_FALSE;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,17,0))
complete_and_exit(&pThrCntrl->thrCompletion, (long)retVal);
-
+#else
+ kthread_complete_and_exit(&pThrCntrl->thrCompletion, (long)retVal);
+#endif
IFXOS_PRN_USR_DBG_NL( IFXOS, IFXOS_PRN_LEVEL_NORMAL,
("EXIT - Kernel Thread Startup <%s>" IFXOS_CRLF,
pThrCntrl->thrParams.pName));

View file

@ -1,22 +0,0 @@
--- a/src/drv_mei_cpe_linux.c 2023-05-22 14:07:34.356721319 +0200
+++ b/src/drv_mei_cpe_linux.c 2023-05-22 14:08:02.328250656 +0200
@@ -2062,7 +2062,7 @@
static int mei_proc_single_open(struct inode *inode, struct file *file)
{
- return single_open(file, mei_seq_single_show, PDE_DATA(inode));
+ return single_open(file, mei_seq_single_show, pde_data(inode));
}
static void mei_proc_entry_create(struct proc_dir_entry *parent_node,
--- a/src/drv_mei_cpe_linux_proc_config.c 2023-05-22 14:12:26.251818708 +0200
+++ b/src/drv_mei_cpe_linux_proc_config.c 2023-05-22 14:12:51.219401891 +0200
@@ -1274,7 +1274,7 @@
static int mei_proc_single_open(struct inode *inode, struct file *file)
{
- return single_open(file, mei_seq_single_show, PDE_DATA(inode));
+ return single_open(file, mei_seq_single_show, pde_data(inode));
}
static struct proc_ops proc_ops = {

View file

@ -1,18 +0,0 @@
--- a/ep.c 2023-05-22 10:23:11.790142567 +0200
+++ b/ep.c 2023-05-22 10:27:23.029791914 +0200
@@ -589,13 +589,13 @@
/* Target structures have a limit of 32 bit DMA pointers.
* DMA pointers can be wider than 32 bits by default on some systems.
*/
- ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+ ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
if (ret) {
dev_err(&pdev->dev, "32-bit DMA not available: %d\n", ret);
goto err_region;
}
- ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
+ ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
if (ret) {
dev_err(&pdev->dev, "cannot enable 32-bit consistent DMA\n");
goto err_region;

View file

@ -1,336 +0,0 @@
--- a/dcdp/ptm_tc.c 2023-05-22 11:06:09.177510131 +0200
+++ b/dcdp/ptm_tc.c 2023-05-22 11:37:23.765131033 +0200
@@ -659,7 +659,11 @@
memcpy(ptm_tc->outq_map, def_outq_map, sizeof(def_outq_map));
SET_NETDEV_DEV(ptm_tc->dev, tc_priv->ep_dev[id].dev);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,0,0)
+ netif_napi_add(ptm_tc->dev, &ptm_tc->napi_rx, tc_priv->tc_ops.napi_rx);
+#else
netif_napi_add(ptm_tc->dev, &ptm_tc->napi_rx, tc_priv->tc_ops.napi_rx, NAPI_POLL_WEIGHT);
+#endif
netif_tx_napi_add(ptm_tc->dev, &ptm_tc->napi_tx, tc_priv->tc_ops.napi_tx, NAPI_POLL_WEIGHT);
err = register_netdev(ptm_tc->dev);
@@ -3125,7 +3129,7 @@
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- priv = (struct ptm_ep_priv *)PDE_DATA(file_inode(file));
+ priv = (struct ptm_ep_priv *)pde_data(file_inode(file));
len = count < sizeof(str) ? count : sizeof(str) - 1;
rlen = len - copy_from_user(str, buf, len);
@@ -3335,7 +3339,7 @@
local_buf[len] = 0;
num = vrx_split_buffer(local_buf, param_list, ARRAY_SIZE(param_list));
- priv = (struct ptm_ep_priv *)PDE_DATA(file_inode(file));
+ priv = (struct ptm_ep_priv *)pde_data(file_inode(file));
if (priv == NULL) {
pr_err("%s: Invalid private data\n", __func__);
return -EINVAL;
--- a/dcdp/inc/ptm_tc.h 2023-05-22 11:24:47.982177396 +0200
+++ b/dcdp/inc/ptm_tc.h 2023-05-22 11:25:34.313376656 +0200
@@ -76,6 +76,9 @@
#define SFSM_DBACE 0x6000
#define SFSM_CBACE 0x7100
+
+#define netif_tx_napi_add netif_napi_add_tx_weight
+
enum {
US_DMA_PRE_RXCH = 0,
US_DMA_PRE_TXCH,
--- a/dcdp/tc_proc.c 2023-05-22 11:58:32.715356238 +0200
+++ b/dcdp/tc_proc.c 2023-05-22 11:59:13.454660657 +0200
@@ -343,7 +343,7 @@
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- priv = ((struct tc_comm *)PDE_DATA(file_inode(file)));
+ priv = ((struct tc_comm *)pde_data(file_inode(file)));
if (priv == NULL) {
pr_err("%s: Invalid priv data\n", __func__);
return -EFAULT;
@@ -476,7 +476,7 @@
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- priv = ((struct tc_comm *)PDE_DATA(file_inode(file)));
+ priv = ((struct tc_comm *)pde_data(file_inode(file)));
if (priv == NULL) {
pr_err("%s: priv pointer is NULL!!!\n", __func__);
return -EINVAL;
@@ -746,7 +746,7 @@
static int proc_read_pp32_seq_open(struct inode *inode, struct file *file)
{
- return single_open(file, proc_read_pp32, PDE_DATA(inode));
+ return single_open(file, proc_read_pp32, pde_data(inode));
}
static const struct proc_ops pp32_proc_fops = {
@@ -822,7 +822,7 @@
len = count < sizeof(str) ? count : sizeof(str) - 1;
rlen = len - copy_from_user(str, buf, len);
str[rlen] = 0;
- priv = (struct tc_priv *)PDE_DATA(file_inode(file));
+ priv = (struct tc_priv *)pde_data(file_inode(file));
if (priv == NULL)
return count;
@@ -862,7 +862,7 @@
static int proc_read_tc_cfg_seq_open(struct inode *inode, struct file *file)
{
- return single_open(file, proc_read_tc_cfg, PDE_DATA(inode));
+ return single_open(file, proc_read_tc_cfg, pde_data(inode));
}
static const struct proc_ops tc_cfg_proc_fops = {
@@ -888,7 +888,7 @@
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- priv = (struct tc_priv *)PDE_DATA(file_inode(file));
+ priv = (struct tc_priv *)pde_data(file_inode(file));
if (priv == NULL)
return count;
@@ -947,7 +947,7 @@
static int proc_read_dbg_seq_open(struct inode *inode, struct file *file)
{
- return single_open(file, proc_read_dbg, PDE_DATA(inode));
+ return single_open(file, proc_read_dbg, pde_data(inode));
}
static const struct proc_ops tc_dbg_proc_fops = {
@@ -970,7 +970,7 @@
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- priv = (struct tc_priv *)PDE_DATA(file_inode(file));
+ priv = (struct tc_priv *)pde_data(file_inode(file));
len = count < sizeof(str) ? count : sizeof(str) - 1;
rlen = len - copy_from_user(str, buf, len);
@@ -1033,7 +1033,7 @@
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- priv = (struct tc_priv *)PDE_DATA(file_inode(file));
+ priv = (struct tc_priv *)pde_data(file_inode(file));
len = count < sizeof(str) ? count : sizeof(str) - 1;
rlen = len - copy_from_user(str, buf, len);
@@ -1125,7 +1125,7 @@
static int proc_read_ver_seq_open(struct inode *inode, struct file *file)
{
- return single_open(file, proc_read_ver, PDE_DATA(inode));
+ return single_open(file, proc_read_ver, pde_data(inode));
}
static const struct proc_ops tc_ver_proc_fops = {
@@ -1159,7 +1159,7 @@
static int proc_read_soc_seq_open(struct inode *inode, struct file *file)
{
- return single_open(file, proc_read_soc, PDE_DATA(inode));
+ return single_open(file, proc_read_soc, pde_data(inode));
}
static const struct proc_ops tc_soc_proc_fops = {
@@ -1185,7 +1185,7 @@
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- priv = (struct tc_priv *)PDE_DATA(file_inode(file));
+ priv = (struct tc_priv *)pde_data(file_inode(file));
if (priv == NULL)
return count;
@@ -1264,7 +1264,7 @@
static int proc_read_desc_conf_seq_open(struct inode *inode, struct file *file)
{
- return single_open(file, proc_read_desc_conf, PDE_DATA(inode));
+ return single_open(file, proc_read_desc_conf, pde_data(inode));
}
#endif
@@ -1343,7 +1343,7 @@
static int proc_read_ptm_wanmib_seq_open(struct inode *inode, struct file *file)
{
- return single_open(file, proc_read_ptm_wanmib, PDE_DATA(inode));
+ return single_open(file, proc_read_ptm_wanmib, pde_data(inode));
}
static const struct proc_ops ptm_wanmib_proc_fops = {
@@ -1382,7 +1382,7 @@
static int proc_read_cfg_seq_open(struct inode *inode, struct file *file)
{
- return single_open(file, proc_ptm_read_cfg, PDE_DATA(inode));
+ return single_open(file, proc_ptm_read_cfg, pde_data(inode));
}
static ssize_t ptm_cfg_proc_write(struct file *file,
@@ -1398,7 +1398,7 @@
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- priv = (struct ptm_ep_priv *)PDE_DATA(file_inode(file));
+ priv = (struct ptm_ep_priv *)pde_data(file_inode(file));
if (priv == NULL) {
pr_err("%s: Invalid private data\n", __func__);
return -EINVAL;
@@ -1478,7 +1478,7 @@
p1 = local_buf;
num = vrx_split_buffer(local_buf, param_list, ARRAY_SIZE(param_list));
- priv = (struct ptm_ep_priv *)PDE_DATA(file_inode(file));
+ priv = (struct ptm_ep_priv *)pde_data(file_inode(file));
if (priv == NULL) {
pr_err("%s: Invalid private data\n", __func__);
@@ -1554,7 +1554,7 @@
static int proc_ptm_read_prio_seq_open(struct inode *inode, struct file *file)
{
- return single_open(file, proc_ptm_read_prio, PDE_DATA(inode));
+ return single_open(file, proc_ptm_read_prio, pde_data(inode));
}
static const struct proc_ops ptm_prio_proc_fops = {
@@ -1567,7 +1567,7 @@
static int proc_ptm_read_bond_seq_open(struct inode *inode, struct file *file)
{
- return single_open(file, proc_ptm_read_bond, PDE_DATA(inode));
+ return single_open(file, proc_ptm_read_bond, pde_data(inode));
}
static const struct proc_ops ptm_bond_proc_fops = {
@@ -1580,7 +1580,7 @@
static int proc_ptm_read_bondmib_seq_open(struct inode *inode,
struct file *file)
{
- return single_open(file, proc_ptm_read_bondmib, PDE_DATA(inode));
+ return single_open(file, proc_ptm_read_bondmib, pde_data(inode));
}
static const struct proc_ops ptm_bondmib_proc_fops = {
@@ -1983,7 +1983,7 @@
num = vrx_split_buffer(local_buf, param_list,
ARRAY_SIZE(param_list));
- priv = (struct tc_comm *)PDE_DATA(file_inode(file));
+ priv = (struct tc_comm *)pde_data(file_inode(file));
if (priv == NULL) {
pr_err("<%s>: Invalid private data\n", __func__);
return count;
@@ -2158,7 +2158,7 @@
static int proc_read_atm_cfg_seq_open(struct inode *inode, struct file *file)
{
- return single_open(file, proc_read_atm_cfg, PDE_DATA(inode));
+ return single_open(file, proc_read_atm_cfg, pde_data(inode));
}
static ssize_t atm_cfg_proc_write(struct file *file,
@@ -2174,7 +2174,7 @@
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- priv = (struct atm_priv *)PDE_DATA(file_inode(file));
+ priv = (struct atm_priv *)pde_data(file_inode(file));
if (!access_ok(buf, count))
return -EFAULT;
@@ -2238,7 +2238,7 @@
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- priv = (struct atm_priv *)PDE_DATA(file_inode(file));
+ priv = (struct atm_priv *)pde_data(file_inode(file));
if (priv == NULL) {
pr_err("%s: Invalid private data\n", __func__);
return -EINVAL;
@@ -2266,7 +2266,7 @@
static int proc_read_atm_wanmib_seq_open(struct inode *inode,
struct file *file)
{
- return single_open(file, proc_read_atm_wanmib, PDE_DATA(inode));
+ return single_open(file, proc_read_atm_wanmib, pde_data(inode));
}
@@ -2281,7 +2281,7 @@
static int proc_read_htu_seq_open(struct inode *inode, struct file *file)
{
- return single_open(file, proc_read_htu, PDE_DATA(inode));
+ return single_open(file, proc_read_htu, pde_data(inode));
}
static const struct proc_ops htu_proc_fops = {
@@ -2293,7 +2293,7 @@
static int proc_read_queue_seq_open(struct inode *inode, struct file *file)
{
- return single_open(file, proc_read_queue, PDE_DATA(inode));
+ return single_open(file, proc_read_queue, pde_data(inode));
}
static const struct proc_ops queue_proc_fops = {
@@ -2350,7 +2350,7 @@
p1 = local_buf;
num = vrx_split_buffer(local_buf, param_list, ARRAY_SIZE(param_list));
- priv = (struct atm_priv *)PDE_DATA(file_inode(file));
+ priv = (struct atm_priv *)pde_data(file_inode(file));
if (vrx_strcmpi(param_list[0], "help") == 0)
goto proc_atm_prio_help;
else if (vrx_strcmpi(param_list[0], "pvc") == 0) {
@@ -2513,7 +2513,7 @@
static int proc_atm_read_prio_seq_open(struct inode *inode, struct file *file)
{
- return single_open(file, proc_atm_read_prio, PDE_DATA(inode));
+ return single_open(file, proc_atm_read_prio, pde_data(inode));
}
static const struct seq_operations pvc_mib_seq_ops = {
@@ -2536,7 +2536,7 @@
int ret = seq_open(file, &pvc_mib_seq_ops);
if (ret == 0) {
struct seq_file *m = file->private_data;
- m->private = PDE_DATA(inode);
+ m->private = pde_data(inode);
}
return ret;
}
@@ -2574,7 +2574,7 @@
local_buf[len] = 0;
num = vrx_split_buffer(local_buf, param_list, ARRAY_SIZE(param_list));
- priv = (struct atm_priv *)PDE_DATA(file_inode(file));
+ priv = (struct atm_priv *)pde_data(file_inode(file));
if (priv == NULL) {
pr_err("<%s>: Invalid private data\n", __func__);
return count;
--- a/dcdp/ptm_tc.c 2023-06-29 11:30:37.060472655 +0200
+++ b/dcdp/ptm_tc.c 2023-06-29 11:31:01.376064210 +0200
@@ -88,7 +88,7 @@
unsigned int *data_addr, unsigned int *desc_addr);
-static inline void tc_ether_addr_copy(u8 *dst, const u8 *src)
+static inline void tc_ether_addr_copy(const u8 *dst, const u8 *src)
{
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
*(u32 *)dst = *(const u32 *)src;

View file

@ -1,12 +0,0 @@
--- a/drivers/net/wireless/ath/carl9170/tx.c 2023-06-27 09:18:10.616850964 +0200
+++ b/drivers/net/wireless/ath/carl9170/tx.c 2023-06-27 09:18:39.260374789 +0200
@@ -280,7 +280,8 @@
* carl9170_tx_fill_rateinfo() has filled the rate information
* before we get to this point.
*/
- memset_after(&txinfo->status, 0, rates);
+ memset(&txinfo->pad, 0, sizeof(txinfo->pad));
+ memset(&txinfo->rate_driver_data, 0, sizeof(txinfo->rate_driver_data));
if (atomic_read(&ar->tx_total_queued))
ar->tx_schedule = true;

View file

@ -1,762 +0,0 @@
From 986e43b19ae9176093da35e0a844e65c8bf9ede7 Mon Sep 17 00:00:00 2001
From: Felix Fietkau <nbd@nbd.name>
Date: Mon, 13 Feb 2023 11:08:54 +0100
Subject: [PATCH] wifi: mac80211: fix receiving A-MSDU frames on mesh
interfaces
The current mac80211 mesh A-MSDU receive path fails to parse A-MSDU packets
on mesh interfaces, because it assumes that the Mesh Control field is always
directly after the 802.11 header.
802.11-2020 9.3.2.2.2 Figure 9-70 shows that the Mesh Control field is
actually part of the A-MSDU subframe header.
This makes more sense, since it allows packets for multiple different
destinations to be included in the same A-MSDU, as long as RA and TID are
still the same.
Another issue is the fact that the A-MSDU subframe length field was apparently
accidentally defined as little-endian in the standard.
In order to fix this, the mesh forwarding path needs happen at a different
point in the receive path.
ieee80211_data_to_8023_exthdr is changed to ignore the mesh control field
and leave it in after the ethernet header. This also affects the source/dest
MAC address fields, which now in the case of mesh point to the mesh SA/DA.
ieee80211_amsdu_to_8023s is changed to deal with the endian difference and
to add the Mesh Control length to the subframe length, since it's not covered
by the MSDU length field.
With these changes, the mac80211 will get the same packet structure for
converted regular data packets and unpacked A-MSDU subframes.
The mesh forwarding checks are now only performed after the A-MSDU decap.
For locally received packets, the Mesh Control header is stripped away.
For forwarded packets, a new 802.11 header gets added.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Link: https://lore.kernel.org/r/20230213100855.34315-4-nbd@nbd.name
[fix fortify build error]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
.../wireless/marvell/mwifiex/11n_rxreorder.c | 2 +-
include/net/cfg80211.h | 27 +-
net/mac80211/rx.c | 350 ++++++++++--------
net/wireless/util.c | 120 +++---
4 files changed, 297 insertions(+), 202 deletions(-)
--- a/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c
+++ b/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c
@@ -33,7 +33,7 @@ static int mwifiex_11n_dispatch_amsdu_pk
skb_trim(skb, le16_to_cpu(local_rx_pd->rx_pkt_length));
ieee80211_amsdu_to_8023s(skb, &list, priv->curr_addr,
- priv->wdev.iftype, 0, NULL, NULL);
+ priv->wdev.iftype, 0, NULL, NULL, false);
while (!skb_queue_empty(&list)) {
struct rx_packet_hdr *rx_hdr;
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -6208,11 +6208,36 @@ static inline int ieee80211_data_to_8023
* @extra_headroom: The hardware extra headroom for SKBs in the @list.
* @check_da: DA to check in the inner ethernet header, or NULL
* @check_sa: SA to check in the inner ethernet header, or NULL
+ * @mesh_control: A-MSDU subframe header includes the mesh control field
*/
void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list,
const u8 *addr, enum nl80211_iftype iftype,
const unsigned int extra_headroom,
- const u8 *check_da, const u8 *check_sa);
+ const u8 *check_da, const u8 *check_sa,
+ bool mesh_control);
+
+/**
+ * ieee80211_get_8023_tunnel_proto - get RFC1042 or bridge tunnel encap protocol
+ *
+ * Check for RFC1042 or bridge tunnel header and fetch the encapsulated
+ * protocol.
+ *
+ * @hdr: pointer to the MSDU payload
+ * @proto: destination pointer to store the protocol
+ * Return: true if encapsulation was found
+ */
+bool ieee80211_get_8023_tunnel_proto(const void *hdr, __be16 *proto);
+
+/**
+ * ieee80211_strip_8023_mesh_hdr - strip mesh header from converted 802.3 frames
+ *
+ * Strip the mesh header, which was left in by ieee80211_data_to_8023 as part
+ * of the MSDU data. Also move any source/destination addresses from the mesh
+ * header to the ethernet header (if present).
+ *
+ * @skb: The 802.3 frame with embedded mesh header
+ */
+int ieee80211_strip_8023_mesh_hdr(struct sk_buff *skb);
/**
* cfg80211_classify8021d - determine the 802.1p/1d tag for a data frame
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2720,6 +2720,174 @@ ieee80211_deliver_skb(struct ieee80211_r
}
}
+static ieee80211_rx_result
+ieee80211_rx_mesh_data(struct ieee80211_sub_if_data *sdata, struct sta_info *sta,
+ struct sk_buff *skb)
+{
+#ifdef CPTCFG_MAC80211_MESH
+ struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
+ struct ieee80211_local *local = sdata->local;
+ uint16_t fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA;
+ struct ieee80211_hdr hdr = {
+ .frame_control = cpu_to_le16(fc)
+ };
+ struct ieee80211_hdr *fwd_hdr;
+ struct ieee80211s_hdr *mesh_hdr;
+ struct ieee80211_tx_info *info;
+ struct sk_buff *fwd_skb;
+ struct ethhdr *eth;
+ bool multicast;
+ int tailroom = 0;
+ int hdrlen, mesh_hdrlen;
+ u8 *qos;
+
+ if (!ieee80211_vif_is_mesh(&sdata->vif))
+ return RX_CONTINUE;
+
+ if (!pskb_may_pull(skb, sizeof(*eth) + 6))
+ return RX_DROP_MONITOR;
+
+ mesh_hdr = (struct ieee80211s_hdr *)(skb->data + sizeof(*eth));
+ mesh_hdrlen = ieee80211_get_mesh_hdrlen(mesh_hdr);
+
+ if (!pskb_may_pull(skb, sizeof(*eth) + mesh_hdrlen))
+ return RX_DROP_MONITOR;
+
+ eth = (struct ethhdr *)skb->data;
+ multicast = is_multicast_ether_addr(eth->h_dest);
+
+ mesh_hdr = (struct ieee80211s_hdr *)(eth + 1);
+ if (!mesh_hdr->ttl)
+ return RX_DROP_MONITOR;
+
+ /* frame is in RMC, don't forward */
+ if (is_multicast_ether_addr(eth->h_dest) &&
+ mesh_rmc_check(sdata, eth->h_source, mesh_hdr))
+ return RX_DROP_MONITOR;
+
+ /* Frame has reached destination. Don't forward */
+ if (ether_addr_equal(sdata->vif.addr, eth->h_dest))
+ goto rx_accept;
+
+ if (!ifmsh->mshcfg.dot11MeshForwarding) {
+ if (is_multicast_ether_addr(eth->h_dest))
+ goto rx_accept;
+
+ return RX_DROP_MONITOR;
+ }
+
+ /* forward packet */
+ if (sdata->crypto_tx_tailroom_needed_cnt)
+ tailroom = IEEE80211_ENCRYPT_TAILROOM;
+
+ if (!--mesh_hdr->ttl) {
+ if (multicast)
+ goto rx_accept;
+
+ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl);
+ return RX_DROP_MONITOR;
+ }
+
+ if (mesh_hdr->flags & MESH_FLAGS_AE) {
+ struct mesh_path *mppath;
+ char *proxied_addr;
+
+ if (multicast)
+ proxied_addr = mesh_hdr->eaddr1;
+ else if ((mesh_hdr->flags & MESH_FLAGS_AE) == MESH_FLAGS_AE_A5_A6)
+ /* has_a4 already checked in ieee80211_rx_mesh_check */
+ proxied_addr = mesh_hdr->eaddr2;
+ else
+ return RX_DROP_MONITOR;
+
+ rcu_read_lock();
+ mppath = mpp_path_lookup(sdata, proxied_addr);
+ if (!mppath) {
+ mpp_path_add(sdata, proxied_addr, eth->h_source);
+ } else {
+ spin_lock_bh(&mppath->state_lock);
+ if (!ether_addr_equal(mppath->mpp, eth->h_source))
+ memcpy(mppath->mpp, eth->h_source, ETH_ALEN);
+ mppath->exp_time = jiffies;
+ spin_unlock_bh(&mppath->state_lock);
+ }
+ rcu_read_unlock();
+ }
+
+ skb_set_queue_mapping(skb, ieee802_1d_to_ac[skb->priority]);
+
+ ieee80211_fill_mesh_addresses(&hdr, &hdr.frame_control,
+ eth->h_dest, eth->h_source);
+ hdrlen = ieee80211_hdrlen(hdr.frame_control);
+ if (multicast) {
+ int extra_head = sizeof(struct ieee80211_hdr) - sizeof(*eth);
+
+ fwd_skb = skb_copy_expand(skb, local->tx_headroom + extra_head +
+ IEEE80211_ENCRYPT_HEADROOM,
+ tailroom, GFP_ATOMIC);
+ if (!fwd_skb)
+ goto rx_accept;
+ } else {
+ fwd_skb = skb;
+ skb = NULL;
+
+ if (skb_cow_head(fwd_skb, hdrlen - sizeof(struct ethhdr)))
+ return RX_DROP_UNUSABLE;
+ }
+
+ fwd_hdr = skb_push(fwd_skb, hdrlen - sizeof(struct ethhdr));
+ memcpy(fwd_hdr, &hdr, hdrlen - 2);
+ qos = ieee80211_get_qos_ctl(fwd_hdr);
+ qos[0] = qos[1] = 0;
+
+ skb_reset_mac_header(fwd_skb);
+ hdrlen += mesh_hdrlen;
+ if (ieee80211_get_8023_tunnel_proto(fwd_skb->data + hdrlen,
+ &fwd_skb->protocol))
+ hdrlen += ETH_ALEN;
+ else
+ fwd_skb->protocol = htons(fwd_skb->len - hdrlen);
+ skb_set_network_header(fwd_skb, hdrlen);
+
+ info = IEEE80211_SKB_CB(fwd_skb);
+ memset(info, 0, sizeof(*info));
+ info->control.flags |= IEEE80211_TX_INTCFL_NEED_TXPROCESSING;
+ info->control.vif = &sdata->vif;
+ info->control.jiffies = jiffies;
+ 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 (!mesh_nexthop_lookup(sdata, fwd_skb)) {
+ /* mesh power mode flags updated in mesh_nexthop_lookup */
+ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_unicast);
+ } else {
+ /* unable to resolve next hop */
+ if (sta)
+ mesh_path_error_tx(sdata, ifmsh->mshcfg.element_ttl,
+ hdr.addr3, 0,
+ WLAN_REASON_MESH_PATH_NOFORWARD,
+ sta->sta.addr);
+ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_no_route);
+ kfree_skb(fwd_skb);
+ goto rx_accept;
+ }
+
+ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_frames);
+ fwd_skb->dev = sdata->dev;
+ ieee80211_add_pending_skb(local, fwd_skb);
+
+rx_accept:
+ if (!skb)
+ return RX_QUEUED;
+
+ ieee80211_strip_8023_mesh_hdr(skb);
+#endif
+
+ return RX_CONTINUE;
+}
+
static ieee80211_rx_result debug_noinline
__ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx, u8 data_offset)
{
@@ -2728,8 +2896,10 @@ __ieee80211_rx_h_amsdu(struct ieee80211_
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
__le16 fc = hdr->frame_control;
struct sk_buff_head frame_list;
+ static ieee80211_rx_result res;
struct ethhdr ethhdr;
const u8 *check_da = ethhdr.h_dest, *check_sa = ethhdr.h_source;
+ bool mesh = false;
if (unlikely(ieee80211_has_a4(hdr->frame_control))) {
check_da = NULL;
@@ -2746,6 +2916,8 @@ __ieee80211_rx_h_amsdu(struct ieee80211_
break;
case NL80211_IFTYPE_MESH_POINT:
check_sa = NULL;
+ check_da = NULL;
+ mesh = true;
break;
default:
break;
@@ -2763,17 +2935,29 @@ __ieee80211_rx_h_amsdu(struct ieee80211_
ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr,
rx->sdata->vif.type,
rx->local->hw.extra_tx_headroom,
- check_da, check_sa);
+ check_da, check_sa, mesh);
while (!skb_queue_empty(&frame_list)) {
rx->skb = __skb_dequeue(&frame_list);
- if (!ieee80211_frame_allowed(rx, fc)) {
- dev_kfree_skb(rx->skb);
+ res = ieee80211_rx_mesh_data(rx->sdata, rx->sta, rx->skb);
+ switch (res) {
+ case RX_QUEUED:
continue;
+ case RX_CONTINUE:
+ break;
+ default:
+ goto free;
}
+ if (!ieee80211_frame_allowed(rx, fc))
+ goto free;
+
ieee80211_deliver_skb(rx);
+ continue;
+
+free:
+ dev_kfree_skb(rx->skb);
}
return RX_QUEUED;
@@ -2806,6 +2990,8 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx
if (!rx->sdata->u.mgd.use_4addr)
return RX_DROP_UNUSABLE;
break;
+ case NL80211_IFTYPE_MESH_POINT:
+ break;
default:
return RX_DROP_UNUSABLE;
}
@@ -2834,155 +3020,6 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx
return __ieee80211_rx_h_amsdu(rx, 0);
}
-#ifdef CPTCFG_MAC80211_MESH
-static ieee80211_rx_result
-ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
-{
- struct ieee80211_hdr *fwd_hdr, *hdr;
- struct ieee80211_tx_info *info;
- struct ieee80211s_hdr *mesh_hdr;
- struct sk_buff *skb = rx->skb, *fwd_skb;
- struct ieee80211_local *local = rx->local;
- struct ieee80211_sub_if_data *sdata = rx->sdata;
- struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
- u16 ac, q, hdrlen;
- int tailroom = 0;
-
- hdr = (struct ieee80211_hdr *) skb->data;
- hdrlen = ieee80211_hdrlen(hdr->frame_control);
-
- /* make sure fixed part of mesh header is there, also checks skb len */
- if (!pskb_may_pull(rx->skb, hdrlen + 6))
- return RX_DROP_MONITOR;
-
- mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen);
-
- /* make sure full mesh header is there, also checks skb len */
- if (!pskb_may_pull(rx->skb,
- hdrlen + ieee80211_get_mesh_hdrlen(mesh_hdr)))
- return RX_DROP_MONITOR;
-
- /* reload pointers */
- hdr = (struct ieee80211_hdr *) skb->data;
- mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen);
-
- if (ieee80211_drop_unencrypted(rx, hdr->frame_control)) {
- int offset = hdrlen + ieee80211_get_mesh_hdrlen(mesh_hdr) +
- sizeof(rfc1042_header);
- __be16 ethertype;
-
- if (!ether_addr_equal(hdr->addr1, rx->sdata->vif.addr) ||
- skb_copy_bits(rx->skb, offset, &ethertype, 2) != 0 ||
- ethertype != rx->sdata->control_port_protocol)
- return RX_DROP_MONITOR;
- }
-
- /* frame is in RMC, don't forward */
- if (ieee80211_is_data(hdr->frame_control) &&
- is_multicast_ether_addr(hdr->addr1) &&
- mesh_rmc_check(rx->sdata, hdr->addr3, mesh_hdr))
- return RX_DROP_MONITOR;
-
- if (!ieee80211_is_data(hdr->frame_control))
- return RX_CONTINUE;
-
- if (!mesh_hdr->ttl)
- return RX_DROP_MONITOR;
-
- if (mesh_hdr->flags & MESH_FLAGS_AE) {
- struct mesh_path *mppath;
- char *proxied_addr;
- char *mpp_addr;
-
- if (is_multicast_ether_addr(hdr->addr1)) {
- mpp_addr = hdr->addr3;
- proxied_addr = mesh_hdr->eaddr1;
- } else if ((mesh_hdr->flags & MESH_FLAGS_AE) ==
- MESH_FLAGS_AE_A5_A6) {
- /* has_a4 already checked in ieee80211_rx_mesh_check */
- mpp_addr = hdr->addr4;
- proxied_addr = mesh_hdr->eaddr2;
- } else {
- return RX_DROP_MONITOR;
- }
-
- rcu_read_lock();
- mppath = mpp_path_lookup(sdata, proxied_addr);
- if (!mppath) {
- mpp_path_add(sdata, proxied_addr, mpp_addr);
- } else {
- spin_lock_bh(&mppath->state_lock);
- if (!ether_addr_equal(mppath->mpp, mpp_addr))
- memcpy(mppath->mpp, mpp_addr, ETH_ALEN);
- mppath->exp_time = jiffies;
- spin_unlock_bh(&mppath->state_lock);
- }
- rcu_read_unlock();
- }
-
- /* Frame has reached destination. Don't forward */
- if (!is_multicast_ether_addr(hdr->addr1) &&
- ether_addr_equal(sdata->vif.addr, hdr->addr3))
- return RX_CONTINUE;
-
- ac = ieee802_1d_to_ac[skb->priority];
- skb_set_queue_mapping(skb, ac);
-
- if (!--mesh_hdr->ttl) {
- if (!is_multicast_ether_addr(hdr->addr1))
- IEEE80211_IFSTA_MESH_CTR_INC(ifmsh,
- dropped_frames_ttl);
- goto out;
- }
-
- if (!ifmsh->mshcfg.dot11MeshForwarding)
- goto out;
-
- if (sdata->crypto_tx_tailroom_needed_cnt)
- tailroom = IEEE80211_ENCRYPT_TAILROOM;
-
- fwd_skb = skb_copy_expand(skb, local->tx_headroom +
- IEEE80211_ENCRYPT_HEADROOM,
- tailroom, GFP_ATOMIC);
- if (!fwd_skb)
- goto out;
-
- fwd_skb->dev = sdata->dev;
- fwd_hdr = (struct ieee80211_hdr *) fwd_skb->data;
- fwd_hdr->frame_control &= ~cpu_to_le16(IEEE80211_FCTL_RETRY);
- info = IEEE80211_SKB_CB(fwd_skb);
- memset(info, 0, sizeof(*info));
- info->control.flags |= IEEE80211_TX_INTCFL_NEED_TXPROCESSING;
- info->control.vif = &rx->sdata->vif;
- info->control.jiffies = jiffies;
- if (is_multicast_ether_addr(fwd_hdr->addr1)) {
- 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 (!mesh_nexthop_lookup(sdata, fwd_skb)) {
- /* mesh power mode flags updated in mesh_nexthop_lookup */
- IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_unicast);
- } else {
- /* unable to resolve next hop */
- mesh_path_error_tx(sdata, ifmsh->mshcfg.element_ttl,
- fwd_hdr->addr3, 0,
- WLAN_REASON_MESH_PATH_NOFORWARD,
- fwd_hdr->addr2);
- IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_no_route);
- kfree_skb(fwd_skb);
- return RX_DROP_MONITOR;
- }
-
- IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_frames);
- ieee80211_add_pending_skb(local, fwd_skb);
- out:
- if (is_multicast_ether_addr(hdr->addr1))
- return RX_CONTINUE;
- return RX_DROP_MONITOR;
-}
-#endif
-
static ieee80211_rx_result debug_noinline
ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
{
@@ -2991,6 +3028,7 @@ ieee80211_rx_h_data(struct ieee80211_rx_
struct net_device *dev = sdata->dev;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
__le16 fc = hdr->frame_control;
+ static ieee80211_rx_result res;
bool port_control;
int err;
@@ -3017,6 +3055,10 @@ ieee80211_rx_h_data(struct ieee80211_rx_
if (unlikely(err))
return RX_DROP_UNUSABLE;
+ res = ieee80211_rx_mesh_data(rx->sdata, rx->sta, rx->skb);
+ if (res != RX_CONTINUE)
+ return res;
+
if (!ieee80211_frame_allowed(rx, fc))
return RX_DROP_MONITOR;
@@ -3987,10 +4029,6 @@ static void ieee80211_rx_handlers(struct
CALL_RXH(ieee80211_rx_h_defragment);
CALL_RXH(ieee80211_rx_h_michael_mic_verify);
/* must be after MMIC verify so header is counted in MPDU mic */
-#ifdef CPTCFG_MAC80211_MESH
- if (ieee80211_vif_is_mesh(&rx->sdata->vif))
- CALL_RXH(ieee80211_rx_h_mesh_fwding);
-#endif
CALL_RXH(ieee80211_rx_h_amsdu);
CALL_RXH(ieee80211_rx_h_data);
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -542,7 +542,7 @@ unsigned int ieee80211_get_mesh_hdrlen(s
}
EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen);
-static bool ieee80211_get_8023_tunnel_proto(const void *hdr, __be16 *proto)
+bool ieee80211_get_8023_tunnel_proto(const void *hdr, __be16 *proto)
{
const __be16 *hdr_proto = hdr + ETH_ALEN;
@@ -556,6 +556,49 @@ static bool ieee80211_get_8023_tunnel_pr
return true;
}
+EXPORT_SYMBOL(ieee80211_get_8023_tunnel_proto);
+
+int ieee80211_strip_8023_mesh_hdr(struct sk_buff *skb)
+{
+ const void *mesh_addr;
+ struct {
+ struct ethhdr eth;
+ u8 flags;
+ } payload;
+ int hdrlen;
+ int ret;
+
+ ret = skb_copy_bits(skb, 0, &payload, sizeof(payload));
+ if (ret)
+ return ret;
+
+ hdrlen = sizeof(payload.eth) + __ieee80211_get_mesh_hdrlen(payload.flags);
+
+ if (likely(pskb_may_pull(skb, hdrlen + 8) &&
+ ieee80211_get_8023_tunnel_proto(skb->data + hdrlen,
+ &payload.eth.h_proto)))
+ hdrlen += ETH_ALEN + 2;
+ else if (!pskb_may_pull(skb, hdrlen))
+ return -EINVAL;
+
+ mesh_addr = skb->data + sizeof(payload.eth) + ETH_ALEN;
+ switch (payload.flags & MESH_FLAGS_AE) {
+ case MESH_FLAGS_AE_A4:
+ memcpy(&payload.eth.h_source, mesh_addr, ETH_ALEN);
+ break;
+ case MESH_FLAGS_AE_A5_A6:
+ memcpy(&payload.eth, mesh_addr, 2 * ETH_ALEN);
+ break;
+ default:
+ break;
+ }
+
+ pskb_pull(skb, hdrlen - sizeof(payload.eth));
+ memcpy(skb->data, &payload.eth, sizeof(payload.eth));
+
+ return 0;
+}
+EXPORT_SYMBOL(ieee80211_strip_8023_mesh_hdr);
int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr,
const u8 *addr, enum nl80211_iftype iftype,
@@ -568,7 +611,6 @@ int ieee80211_data_to_8023_exthdr(struct
} payload;
struct ethhdr tmp;
u16 hdrlen;
- u8 mesh_flags = 0;
if (unlikely(!ieee80211_is_data_present(hdr->frame_control)))
return -1;
@@ -589,12 +631,6 @@ int ieee80211_data_to_8023_exthdr(struct
memcpy(tmp.h_dest, ieee80211_get_DA(hdr), ETH_ALEN);
memcpy(tmp.h_source, ieee80211_get_SA(hdr), ETH_ALEN);
- if (iftype == NL80211_IFTYPE_MESH_POINT &&
- skb_copy_bits(skb, hdrlen, &mesh_flags, 1) < 0)
- return -1;
-
- mesh_flags &= MESH_FLAGS_AE;
-
switch (hdr->frame_control &
cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) {
case cpu_to_le16(IEEE80211_FCTL_TODS):
@@ -608,17 +644,6 @@ int ieee80211_data_to_8023_exthdr(struct
iftype != NL80211_IFTYPE_AP_VLAN &&
iftype != NL80211_IFTYPE_STATION))
return -1;
- if (iftype == NL80211_IFTYPE_MESH_POINT) {
- if (mesh_flags == MESH_FLAGS_AE_A4)
- return -1;
- if (mesh_flags == MESH_FLAGS_AE_A5_A6 &&
- skb_copy_bits(skb, hdrlen +
- offsetof(struct ieee80211s_hdr, eaddr1),
- tmp.h_dest, 2 * ETH_ALEN) < 0)
- return -1;
-
- hdrlen += __ieee80211_get_mesh_hdrlen(mesh_flags);
- }
break;
case cpu_to_le16(IEEE80211_FCTL_FROMDS):
if ((iftype != NL80211_IFTYPE_STATION &&
@@ -627,16 +652,6 @@ int ieee80211_data_to_8023_exthdr(struct
(is_multicast_ether_addr(tmp.h_dest) &&
ether_addr_equal(tmp.h_source, addr)))
return -1;
- if (iftype == NL80211_IFTYPE_MESH_POINT) {
- if (mesh_flags == MESH_FLAGS_AE_A5_A6)
- return -1;
- if (mesh_flags == MESH_FLAGS_AE_A4 &&
- skb_copy_bits(skb, hdrlen +
- offsetof(struct ieee80211s_hdr, eaddr1),
- tmp.h_source, ETH_ALEN) < 0)
- return -1;
- hdrlen += __ieee80211_get_mesh_hdrlen(mesh_flags);
- }
break;
case cpu_to_le16(0):
if (iftype != NL80211_IFTYPE_ADHOC &&
@@ -646,7 +661,7 @@ int ieee80211_data_to_8023_exthdr(struct
break;
}
- if (likely(!is_amsdu &&
+ if (likely(!is_amsdu && iftype != NL80211_IFTYPE_MESH_POINT &&
skb_copy_bits(skb, hdrlen, &payload, sizeof(payload)) == 0 &&
ieee80211_get_8023_tunnel_proto(&payload, &tmp.h_proto))) {
/* remove RFC1042 or Bridge-Tunnel encapsulation */
@@ -722,7 +737,8 @@ __ieee80211_amsdu_copy_frag(struct sk_bu
static struct sk_buff *
__ieee80211_amsdu_copy(struct sk_buff *skb, unsigned int hlen,
- int offset, int len, bool reuse_frag)
+ int offset, int len, bool reuse_frag,
+ int min_len)
{
struct sk_buff *frame;
int cur_len = len;
@@ -736,7 +752,7 @@ __ieee80211_amsdu_copy(struct sk_buff *s
* in the stack later.
*/
if (reuse_frag)
- cur_len = min_t(int, len, 32);
+ cur_len = min_t(int, len, min_len);
/*
* Allocate and reserve two bytes more for payload
@@ -746,6 +762,7 @@ __ieee80211_amsdu_copy(struct sk_buff *s
if (!frame)
return NULL;
+ frame->priority = skb->priority;
skb_reserve(frame, hlen + sizeof(struct ethhdr) + 2);
skb_copy_bits(skb, offset, skb_put(frame, cur_len), cur_len);
@@ -762,23 +779,37 @@ __ieee80211_amsdu_copy(struct sk_buff *s
void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list,
const u8 *addr, enum nl80211_iftype iftype,
const unsigned int extra_headroom,
- const u8 *check_da, const u8 *check_sa)
+ const u8 *check_da, const u8 *check_sa,
+ bool mesh_control)
{
unsigned int hlen = ALIGN(extra_headroom, 4);
struct sk_buff *frame = NULL;
int offset = 0, remaining;
- struct ethhdr eth;
+ struct {
+ struct ethhdr eth;
+ uint8_t flags;
+ } hdr;
bool reuse_frag = skb->head_frag && !skb_has_frag_list(skb);
bool reuse_skb = false;
bool last = false;
+ int copy_len = sizeof(hdr.eth);
+
+ if (iftype == NL80211_IFTYPE_MESH_POINT)
+ copy_len = sizeof(hdr);
while (!last) {
unsigned int subframe_len;
- int len;
+ int len, mesh_len = 0;
u8 padding;
- skb_copy_bits(skb, offset, &eth, sizeof(eth));
- len = ntohs(eth.h_proto);
+ skb_copy_bits(skb, offset, &hdr, copy_len);
+ if (iftype == NL80211_IFTYPE_MESH_POINT)
+ mesh_len = __ieee80211_get_mesh_hdrlen(hdr.flags);
+ if (mesh_control)
+ len = le16_to_cpu(*(__le16 *)&hdr.eth.h_proto) + mesh_len;
+ else
+ len = ntohs(hdr.eth.h_proto);
+
subframe_len = sizeof(struct ethhdr) + len;
padding = (4 - subframe_len) & 0x3;
@@ -787,16 +818,16 @@ void ieee80211_amsdu_to_8023s(struct sk_
if (subframe_len > remaining)
goto purge;
/* mitigate A-MSDU aggregation injection attacks */
- if (ether_addr_equal(eth.h_dest, rfc1042_header))
+ if (ether_addr_equal(hdr.eth.h_dest, rfc1042_header))
goto purge;
offset += sizeof(struct ethhdr);
last = remaining <= subframe_len + padding;
/* FIXME: should we really accept multicast DA? */
- if ((check_da && !is_multicast_ether_addr(eth.h_dest) &&
- !ether_addr_equal(check_da, eth.h_dest)) ||
- (check_sa && !ether_addr_equal(check_sa, eth.h_source))) {
+ if ((check_da && !is_multicast_ether_addr(hdr.eth.h_dest) &&
+ !ether_addr_equal(check_da, hdr.eth.h_dest)) ||
+ (check_sa && !ether_addr_equal(check_sa, hdr.eth.h_source))) {
offset += len + padding;
continue;
}
@@ -808,7 +839,7 @@ void ieee80211_amsdu_to_8023s(struct sk_
reuse_skb = true;
} else {
frame = __ieee80211_amsdu_copy(skb, hlen, offset, len,
- reuse_frag);
+ reuse_frag, 32 + mesh_len);
if (!frame)
goto purge;
@@ -819,10 +850,11 @@ void ieee80211_amsdu_to_8023s(struct sk_
frame->dev = skb->dev;
frame->priority = skb->priority;
- if (likely(ieee80211_get_8023_tunnel_proto(frame->data, &eth.h_proto)))
+ if (likely(iftype != NL80211_IFTYPE_MESH_POINT &&
+ ieee80211_get_8023_tunnel_proto(frame->data, &hdr.eth.h_proto)))
skb_pull(frame, ETH_ALEN + 2);
- memcpy(skb_push(frame, sizeof(eth)), &eth, sizeof(eth));
+ memcpy(skb_push(frame, sizeof(hdr.eth)), &hdr.eth, sizeof(hdr.eth));
__skb_queue_tail(list, frame);
}

View file

@ -1,62 +0,0 @@
From: Ryder Lee <ryder.lee@mediatek.com>
Date: Sat, 18 Feb 2023 01:49:25 +0800
Subject: [PATCH] wifi: mac80211: add LDPC related flags in ieee80211_bss_conf
This is utilized to pass LDPC configurations from user space
(i.e. hostapd) to driver.
Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
Link: https://lore.kernel.org/r/1de696aaa34efd77a926eb657b8c0fda05aaa177.1676628065.git.ryder.lee@mediatek.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -653,6 +653,9 @@ struct ieee80211_fils_discovery {
* write-protected by sdata_lock and local->mtx so holding either is fine
* for read access.
* @color_change_color: the bss color that will be used after the change.
+ * @ht_ldpc: in AP mode, indicates interface has HT LDPC capability.
+ * @vht_ldpc: in AP mode, indicates interface has VHT LDPC capability.
+ * @he_ldpc: in AP mode, indicates interface has HE LDPC capability.
* @vht_su_beamformer: in AP mode, does this BSS support operation as an VHT SU
* beamformer
* @vht_su_beamformee: in AP mode, does this BSS support operation as an VHT SU
@@ -744,6 +747,9 @@ struct ieee80211_bss_conf {
bool color_change_active;
u8 color_change_color;
+ bool ht_ldpc;
+ bool vht_ldpc;
+ bool he_ldpc;
bool vht_su_beamformer;
bool vht_su_beamformee;
bool vht_mu_beamformer;
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1252,7 +1252,15 @@ static int ieee80211_start_ap(struct wip
prev_beacon_int = link_conf->beacon_int;
link_conf->beacon_int = params->beacon_interval;
+ if (params->ht_cap)
+ link_conf->ht_ldpc =
+ params->ht_cap->cap_info &
+ cpu_to_le16(IEEE80211_HT_CAP_LDPC_CODING);
+
if (params->vht_cap) {
+ link_conf->vht_ldpc =
+ params->vht_cap->vht_cap_info &
+ cpu_to_le32(IEEE80211_VHT_CAP_RXLDPC);
link_conf->vht_su_beamformer =
params->vht_cap->vht_cap_info &
cpu_to_le32(IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE);
@@ -1282,6 +1290,9 @@ static int ieee80211_start_ap(struct wip
}
if (params->he_cap) {
+ link_conf->he_ldpc =
+ params->he_cap->phy_cap_info[1] &
+ IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD;
link_conf->he_su_beamformer =
params->he_cap->phy_cap_info[3] &
IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER;

View file

@ -111,9 +111,9 @@ if [ "$OMR_OPENWRT" = "default" ]; then
_get_repo feeds/${OMR_KERNEL}/packages https://github.com/openwrt/packages "8939b43659dabe9b737feee02976949ad0355adc"
_get_repo feeds/${OMR_KERNEL}/luci https://github.com/openwrt/luci "3e14e055a177dec4bd3a4bd40883b56a6930fd7c"
elif [ "$OMR_KERNEL" = "6.1" ]; then
_get_repo "$OMR_TARGET/${OMR_KERNEL}/source" https://github.com/openwrt/openwrt "ce6ad123e76311d2a882054b4ea532d1bfb643c8"
_get_repo feeds/${OMR_KERNEL}/packages https://github.com/openwrt/packages "f3a6491674ab451535e392b63e94a545abf3f292"
_get_repo feeds/${OMR_KERNEL}/luci https://github.com/openwrt/luci "b17650fbd23ee9028b8a7aa55e3a9615ddf934f8"
_get_repo "$OMR_TARGET/${OMR_KERNEL}/source" https://github.com/openwrt/openwrt "74e7f8ebbdc19c58ac59c792154041a6b3c124f5"
_get_repo feeds/${OMR_KERNEL}/packages https://github.com/openwrt/packages "b738e42c4de80bcc59559c436618e42845d62fc1"
_get_repo feeds/${OMR_KERNEL}/luci https://github.com/openwrt/luci "957a6313bd6371e5afae20573a43f5440948e66e"
fi
elif [ "$OMR_OPENWRT" = "coolsnowwolfmix" ]; then
_get_repo "$OMR_TARGET/${OMR_KERNEL}/source" https://github.com/coolsnowwolf/lede.git "master"