Merge Official Source

Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
Tianling Shen
2026-05-21 15:22:06 +08:00
9 changed files with 179 additions and 102 deletions
+1 -1
View File
@@ -22,7 +22,7 @@ $(eval $(call KernelPackage,pse-pd))
define AddDepends/pse-pd
SUBMENU:=$(PSE_MENU)
DEPENDS+=kmod-pse-pd $(1)
DEPENDS+=+kmod-pse-pd $(1)
endef
define KernelPackage/pse-regulator
+3 -3
View File
@@ -9,9 +9,9 @@ PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=$(PROJECT_GIT)/project/uhttpd.git
PKG_SOURCE_DATE:=2026-05-15
PKG_SOURCE_VERSION:=6fadf0da50509a510ac4f85d2adb70a83de2e1fc
PKG_MIRROR_HASH:=66775a84eec4dbfdea35d460f7978a0cedd1a58ac84d90bd1ff388020f8eddcc
PKG_SOURCE_DATE:=2026-05-20
PKG_SOURCE_VERSION:=6ab9abb56bcb28684f382f7a94c170fad02348ea
PKG_MIRROR_HASH:=5edf4161ae48fd38db530f12091821d445d7346e72c69b76097f2f3e07e53a65
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
PKG_LICENSE:=ISC
@@ -39,7 +39,7 @@ proto_qmi_setup() {
local connstat dataformat mcc mnc plmn_mode
local cid_4 cid_6 pdh_4 pdh_6
local dns1_6 dns2_6 gateway_6 ip_6 ip_prefix_length
local profile_pdptype
local profile_pdptype profile_id
local delegate ip4table ip6table mtu sourcefilter $PROTO_DEFAULT_OPTIONS
json_get_vars delegate ip4table ip6table mtu sourcefilter $PROTO_DEFAULT_OPTIONS
@@ -331,12 +331,13 @@ proto_qmi_setup() {
[ "$pdptype" = "ip" -o "$pdptype" = "ipv6" -o "$pdptype" = "ipv4v6" ] || pdptype="ip"
# Configure PDP type and APN for profile 1.
# Configure PDP type and APN.
# In case GGSN rejects IPv4v6 PDP, modem might not be able to
# establish a non-LTE data session.
profile_pdptype="$pdptype"
profile_id="${profile:-1}"
[ "$profile_pdptype" = "ip" ] && profile_pdptype="ipv4"
uqmi -s -d "$device" -t 1000 --modify-profile "3gpp,1" --apn "$apn" --pdp-type "$profile_pdptype" > /dev/null 2>&1
uqmi -s -d "$device" -t 1000 --modify-profile "3gpp,$profile_id" --apn "$apn" --pdp-type "$profile_pdptype" > /dev/null 2>&1
if [ "$pdptype" = "ip" ]; then
[ -z "$autoconnect" ] && autoconnect=1
@@ -21,7 +21,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
#include <uapi/linux/ppp_defs.h>
#include "airoha_regs.h"
@@ -439,6 +440,41 @@ static void airoha_fe_crsn_qsel_init(str
@@ -439,6 +440,47 @@ static void airoha_fe_crsn_qsel_init(str
CDM_CRSN_QSEL_Q1));
}
@@ -59,11 +59,17 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+ for (i = 0; i < AIROHA_MAX_NUM_LRO_QUEUES; i++)
+ airoha_fe_clear(eth, REG_CDM_LRO_RXQ(id, i), LRO_RXQ_MASK(i));
+}
+
+static bool airoha_fe_lro_is_enabled(struct airoha_eth *eth, int qdma_id)
+{
+ return airoha_fe_get(eth, REG_CDM_LRO_EN(qdma_id + 1),
+ LRO_RXQ_EN_MASK);
+}
+
static int airoha_fe_init(struct airoha_eth *eth)
{
airoha_fe_maccr_init(eth);
@@ -603,9 +639,78 @@ static int airoha_qdma_get_gdm_port(stru
@@ -603,9 +645,78 @@ static int airoha_qdma_get_gdm_port(stru
return port >= ARRAY_SIZE(eth->ports) ? -EINVAL : port;
}
@@ -142,7 +148,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
struct airoha_qdma *qdma = q->qdma;
struct airoha_eth *eth = qdma->eth;
int qid = q - &qdma->q_rx[0];
@@ -652,9 +757,14 @@ static int airoha_qdma_rx_process(struct
@@ -652,9 +763,14 @@ static int airoha_qdma_rx_process(struct
__skb_put(q->skb, len);
skb_mark_for_recycle(q->skb);
q->skb->dev = port->dev;
@@ -158,7 +164,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
} else { /* scattered frame */
struct skb_shared_info *shinfo = skb_shinfo(q->skb);
int nr_frags = shinfo->nr_frags;
@@ -743,23 +853,19 @@ static int airoha_qdma_rx_napi_poll(stru
@@ -743,23 +859,19 @@ static int airoha_qdma_rx_napi_poll(stru
static int airoha_qdma_init_rx_queue(struct airoha_queue *q,
struct airoha_qdma *qdma, int ndesc)
{
@@ -185,7 +191,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
q->entry = devm_kzalloc(eth->dev, ndesc * sizeof(*q->entry),
GFP_KERNEL);
if (!q->entry)
@@ -770,6 +876,12 @@ static int airoha_qdma_init_rx_queue(str
@@ -770,6 +882,12 @@ static int airoha_qdma_init_rx_queue(str
if (!q->desc)
return -ENOMEM;
@@ -198,7 +204,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
q->page_pool = page_pool_create(&pp_params);
if (IS_ERR(q->page_pool)) {
int err = PTR_ERR(q->page_pool);
@@ -778,6 +890,7 @@ static int airoha_qdma_init_rx_queue(str
@@ -778,6 +896,7 @@ static int airoha_qdma_init_rx_queue(str
return err;
}
@@ -206,7 +212,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
q->ndesc = ndesc;
netif_napi_add(eth->napi_dev, &q->napi, airoha_qdma_rx_napi_poll);
@@ -2032,6 +2145,45 @@ int airoha_get_fe_port(struct airoha_gdm
@@ -2032,6 +2151,64 @@ int airoha_get_fe_port(struct airoha_gdm
}
}
@@ -219,13 +225,17 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+ struct airoha_qdma *qdma = port->qdma;
+ struct airoha_eth *eth = qdma->eth;
+ int qdma_id = qdma - &eth->qdma[0];
+ int i;
+
+ if (!(diff & NETIF_F_LRO))
+ return 0;
+
+ /* reset LRO configuration */
+ if (features & NETIF_F_LRO) {
+ int i, lro_queue_index = 0;
+ int lro_queue_index = 0;
+
+ if (airoha_fe_lro_is_enabled(eth, qdma_id))
+ return 0;
+
+ for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) {
+ struct airoha_queue *q = &qdma->q_rx[i];
@@ -243,6 +253,21 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+ lro_queue_index++;
+ }
+ } else {
+ for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
+ struct airoha_gdm_port *p = eth->ports[i];
+
+ if (!p)
+ continue;
+
+ if (p->qdma != qdma)
+ continue;
+
+ if (p->dev == dev)
+ continue;
+
+ if (p->dev->features & NETIF_F_LRO)
+ return 0;
+ }
+ airoha_fe_lro_disable(eth, qdma_id);
+ }
+
@@ -252,7 +277,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
struct net_device *dev)
{
@@ -2931,6 +3083,7 @@ static const struct net_device_ops airoh
@@ -2931,6 +3108,7 @@ static const struct net_device_ops airoh
.ndo_stop = airoha_dev_stop,
.ndo_change_mtu = airoha_dev_change_mtu,
.ndo_select_queue = airoha_dev_select_queue,
@@ -260,7 +285,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
.ndo_start_xmit = airoha_dev_xmit,
.ndo_get_stats64 = airoha_dev_get_stats64,
.ndo_set_mac_address = airoha_dev_set_macaddr,
@@ -3153,12 +3306,9 @@ static int airoha_alloc_gdm_port(struct
@@ -3148,12 +3326,9 @@ static int airoha_alloc_gdm_port(struct
dev->ethtool_ops = &airoha_ethtool_ops;
dev->max_mtu = AIROHA_MAX_MTU;
dev->watchdog_timeo = 5 * HZ;
@@ -1,6 +1,7 @@
From 55a5d8fca8365312ed53bc93ae1af67ee35c2915 Mon Sep 17 00:00:00 2001
From: Felix Fietkau <nbd@nbd.name>
Date: Tue, 15 Jul 2025 12:37:45 +0200
Subject: [PATCH] net: pppoe: implement GRO support
Date: Wed, 13 May 2026 09:33:48 +0800
Subject: [PATCH] net: pppoe: implement GRO/GSO support
Only handles packets where the pppoe header length field matches the exact
packet length. Significantly improves rx throughput.
@@ -11,7 +12,15 @@ that the device is able to handle improves from ~130 Mbit/s to ~630 Mbit/s,
using fraglist GRO.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Qingfang Deng <qingfang.deng@linux.dev>
Tested-by: Pablo Neira Ayuso <pablo@netfilter.org>
Link: https://patch.msgid.link/20260513013400.7467-1-qingfang.deng@linux.dev
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
drivers/net/ppp/pppoe.c | 161 +++++++++++++++++++++++++++++++++++++++-
net/ipv4/af_inet.c | 2 +
net/ipv6/ip6_offload.c | 2 +
3 files changed, 164 insertions(+), 1 deletion(-)
--- a/drivers/net/ppp/pppoe.c
+++ b/drivers/net/ppp/pppoe.c
@@ -32,28 +41,34 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
goto drop;
ph = pppoe_hdr(skb);
@@ -1176,6 +1177,161 @@ static struct pernet_operations pppoe_ne
@@ -1176,6 +1177,160 @@ static struct pernet_operations pppoe_ne
.size = sizeof(struct pppoe_net),
};
+static u16
+compare_pppoe_header(struct pppoe_hdr *phdr, struct pppoe_hdr *phdr2)
+compare_pppoe_header(const struct pppoe_hdr *phdr,
+ const struct pppoe_hdr *phdr2)
+{
+ return (__force __u16)((phdr->sid ^ phdr2->sid) |
+ (phdr->tag[0].tag_type ^ phdr2->tag[0].tag_type));
+ __be16 proto = *(const __be16 *)(phdr + 1);
+ __be16 proto2 = *(const __be16 *)(phdr2 + 1);
+
+ return (__force u16)((phdr->sid ^ phdr2->sid) | (proto ^ proto2));
+}
+
+static __be16 pppoe_hdr_proto(struct pppoe_hdr *phdr)
+static __be16 pppoe_hdr_proto(const struct pppoe_hdr *phdr)
+{
+ switch (phdr->tag[0].tag_type) {
+ __be16 proto = *(const __be16 *)(phdr + 1);
+
+ switch (proto) {
+ case cpu_to_be16(PPP_IP):
+ return cpu_to_be16(ETH_P_IP);
+#if IS_ENABLED(CONFIG_IPV6)
+ case cpu_to_be16(PPP_IPV6):
+ return cpu_to_be16(ETH_P_IPV6);
+#endif
+ default:
+ return 0;
+ }
+
+}
+
+static struct sk_buff *pppoe_gro_receive(struct list_head *head,
@@ -61,26 +76,27 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+{
+ const struct packet_offload *ptype;
+ unsigned int hlen, off_pppoe;
+ const struct pppoe_hdr *phdr;
+ struct sk_buff *pp = NULL;
+ struct pppoe_hdr *phdr;
+ struct sk_buff *p;
+ int flush = 1;
+ __be16 type;
+
+ off_pppoe = skb_gro_offset(skb);
+ hlen = off_pppoe + sizeof(*phdr);
+ phdr = skb_gro_header(skb, hlen + 2, off_pppoe);
+ hlen = off_pppoe + PPPOE_SES_HLEN;
+ phdr = skb_gro_header(skb, hlen, off_pppoe);
+ if (unlikely(!phdr))
+ goto out;
+
+ /* filter for session packets (type:1, ver:1, code:0) */
+ if (*(const __be16 *)phdr != cpu_to_be16(0x1100))
+ goto out;
+
+ /* ignore packets with padding or invalid length */
+ if (skb_gro_len(skb) != be16_to_cpu(phdr->length) + hlen)
+ if (skb_gro_len(skb) != be16_to_cpu(phdr->length) + sizeof(*phdr))
+ goto out;
+
+ type = pppoe_hdr_proto(phdr);
+ if (!type)
+ goto out;
+
+ ptype = gro_find_receive_by_type(type);
+ if (!ptype)
+ goto out;
@@ -88,18 +104,18 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+ flush = 0;
+
+ list_for_each_entry(p, head, list) {
+ struct pppoe_hdr *phdr2;
+ const struct pppoe_hdr *phdr2;
+
+ if (!NAPI_GRO_CB(p)->same_flow)
+ continue;
+
+ phdr2 = (struct pppoe_hdr *)(p->data + off_pppoe);
+ phdr2 = (const struct pppoe_hdr *)(p->data + off_pppoe);
+ if (compare_pppoe_header(phdr, phdr2))
+ NAPI_GRO_CB(p)->same_flow = 0;
+ }
+
+ skb_gro_pull(skb, sizeof(*phdr) + 2);
+ skb_gro_postpull_rcsum(skb, phdr, sizeof(*phdr) + 2);
+ skb_gro_pull(skb, PPPOE_SES_HLEN);
+ skb_gro_postpull_rcsum(skb, phdr, PPPOE_SES_HLEN);
+
+ pp = indirect_call_gro_receive_inet(ptype->callbacks.gro_receive,
+ ipv6_gro_receive, inet_gro_receive,
@@ -116,32 +132,26 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+ struct pppoe_hdr *phdr = (struct pppoe_hdr *)(skb->data + nhoff);
+ __be16 type = pppoe_hdr_proto(phdr);
+ struct packet_offload *ptype;
+ int len, err;
+ unsigned int len;
+
+ ptype = gro_find_complete_by_type(type);
+ if (!ptype)
+ return -ENOENT;
+
+ err = INDIRECT_CALL_INET(ptype->callbacks.gro_complete,
+ ipv6_gro_complete, inet_gro_complete,
+ skb, nhoff + sizeof(*phdr) + 2);
+ if (err)
+ return err;
+
+ len = skb->len - (nhoff + sizeof(*phdr));
+ len = min(len, 0xFFFFU);
+ phdr->length = cpu_to_be16(len);
+
+ return 0;
+ return INDIRECT_CALL_INET(ptype->callbacks.gro_complete,
+ ipv6_gro_complete, inet_gro_complete,
+ skb, nhoff + PPPOE_SES_HLEN);
+}
+
+static struct sk_buff *pppoe_gso_segment(struct sk_buff *skb,
+ netdev_features_t features)
+{
+ unsigned int pppoe_hlen = sizeof(struct pppoe_hdr) + 2;
+ struct sk_buff *segs = ERR_PTR(-EINVAL);
+ u16 mac_offset = skb->mac_header;
+ struct packet_offload *ptype;
+ u16 mac_len = skb->mac_len;
+ struct pppoe_hdr *phdr;
+ __be16 orig_type, type;
+ int len, nhoff;
@@ -149,7 +159,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+ skb_reset_network_header(skb);
+ nhoff = skb_network_header(skb) - skb_mac_header(skb);
+
+ if (unlikely(!pskb_may_pull(skb, pppoe_hlen)))
+ if (unlikely(!pskb_may_pull(skb, PPPOE_SES_HLEN)))
+ goto out;
+
+ phdr = (struct pppoe_hdr *)skb_network_header(skb);
@@ -159,13 +169,11 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+ goto out;
+
+ orig_type = skb->protocol;
+ __skb_pull(skb, pppoe_hlen);
+ __skb_pull(skb, PPPOE_SES_HLEN);
+ features &= ~NETIF_F_GSO_SOFTWARE;
+ segs = ptype->callbacks.gso_segment(skb, features);
+ if (IS_ERR_OR_NULL(segs)) {
+ skb_gso_error_unwind(skb, orig_type, pppoe_hlen, mac_offset,
+ mac_len);
+ if (IS_ERR_OR_NULL(segs))
+ goto out;
+ }
+
+ skb = segs;
+ do {
@@ -194,19 +202,21 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
static int __init pppoe_init(void)
{
int err;
@@ -1192,6 +1348,7 @@ static int __init pppoe_init(void)
@@ -1192,6 +1347,8 @@ static int __init pppoe_init(void)
if (err)
goto out_unregister_pppoe_proto;
+ dev_add_offload(&pppoe_packet_offload);
+ if (IS_ENABLED(CONFIG_INET))
+ dev_add_offload(&pppoe_packet_offload);
dev_add_pack(&pppoes_ptype);
dev_add_pack(&pppoed_ptype);
register_netdevice_notifier(&pppoe_notifier);
@@ -1211,6 +1368,7 @@ static void __exit pppoe_exit(void)
@@ -1211,6 +1368,8 @@ static void __exit pppoe_exit(void)
unregister_netdevice_notifier(&pppoe_notifier);
dev_remove_pack(&pppoed_ptype);
dev_remove_pack(&pppoes_ptype);
+ dev_remove_offload(&pppoe_packet_offload);
+ if (IS_ENABLED(CONFIG_INET))
+ dev_remove_offload(&pppoe_packet_offload);
unregister_pppox_proto(PX_PROTO_OE);
proto_unregister(&pppoe_sk_proto);
unregister_pernet_device(&pppoe_net_ops);
@@ -0,0 +1,33 @@
From 33d35975cbead3fa6b738ee57e5e45e14fbe0886 Mon Sep 17 00:00:00 2001
From: Jonas Jelonek <jelonek.jonas@gmail.com>
Date: Fri, 15 May 2026 14:31:03 +0000
Subject: [PATCH] net: pse-pd: fix sign on -ENOENT check in of_load_pse_pis()
of_count_phandle_with_args() returns the count on success and a negative
errno on failure, including -ENOENT when the "pairsets" property is
absent. The existing comparison in of_load_pse_pis() checks against
ENOENT (positive 2) instead of -ENOENT, so the branch is taken for any
error return: legitimate DTs that omit "pairsets" trigger a spurious
"wrong number of pairsets" error and probe fails with -EINVAL.
Compare against -ENOENT so a missing "pairsets" property is correctly
treated as "this PI has no pairsets, continue".
Fixes: 9be9567a7c59 ("net: pse-pd: Add support for PSE PIs")
Cc: stable@vger.kernel.org
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
Acked-by: Oleksij Rempel <o.rempel@pengutronix.de>
Link: https://patch.msgid.link/20260515143103.1721888-1-jelonek.jonas@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
--- a/drivers/net/pse-pd/pse_core.c
+++ b/drivers/net/pse-pd/pse_core.c
@@ -210,7 +210,7 @@ static int of_load_pse_pis(struct pse_co
ret = of_load_pse_pi_pairsets(node, &pi, ret);
if (ret)
goto out;
- } else if (ret != ENOENT) {
+ } else if (ret != -ENOENT) {
dev_err(pcdev->dev,
"error: wrong number of pairsets. Should be 1 or 2, got %d (%pOF)\n",
ret, node);
@@ -1,6 +1,7 @@
From 55a5d8fca8365312ed53bc93ae1af67ee35c2915 Mon Sep 17 00:00:00 2001
From: Felix Fietkau <nbd@nbd.name>
Date: Tue, 15 Jul 2025 12:37:45 +0200
Subject: [PATCH] net: pppoe: implement GRO support
Date: Wed, 13 May 2026 09:33:48 +0800
Subject: [PATCH] net: pppoe: implement GRO/GSO support
Only handles packets where the pppoe header length field matches the exact
packet length. Significantly improves rx throughput.
@@ -11,7 +12,15 @@ that the device is able to handle improves from ~130 Mbit/s to ~630 Mbit/s,
using fraglist GRO.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Qingfang Deng <qingfang.deng@linux.dev>
Tested-by: Pablo Neira Ayuso <pablo@netfilter.org>
Link: https://patch.msgid.link/20260513013400.7467-1-qingfang.deng@linux.dev
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
drivers/net/ppp/pppoe.c | 161 +++++++++++++++++++++++++++++++++++++++-
net/ipv4/af_inet.c | 2 +
net/ipv6/ip6_offload.c | 2 +
3 files changed, 164 insertions(+), 1 deletion(-)
--- a/drivers/net/ppp/pppoe.c
+++ b/drivers/net/ppp/pppoe.c
@@ -32,28 +41,34 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
goto drop;
ph = pppoe_hdr(skb);
@@ -1176,6 +1177,161 @@ static struct pernet_operations pppoe_ne
@@ -1176,6 +1177,160 @@ static struct pernet_operations pppoe_ne
.size = sizeof(struct pppoe_net),
};
+static u16
+compare_pppoe_header(struct pppoe_hdr *phdr, struct pppoe_hdr *phdr2)
+compare_pppoe_header(const struct pppoe_hdr *phdr,
+ const struct pppoe_hdr *phdr2)
+{
+ return (__force __u16)((phdr->sid ^ phdr2->sid) |
+ (phdr->tag[0].tag_type ^ phdr2->tag[0].tag_type));
+ __be16 proto = *(const __be16 *)(phdr + 1);
+ __be16 proto2 = *(const __be16 *)(phdr2 + 1);
+
+ return (__force u16)((phdr->sid ^ phdr2->sid) | (proto ^ proto2));
+}
+
+static __be16 pppoe_hdr_proto(struct pppoe_hdr *phdr)
+static __be16 pppoe_hdr_proto(const struct pppoe_hdr *phdr)
+{
+ switch (phdr->tag[0].tag_type) {
+ __be16 proto = *(const __be16 *)(phdr + 1);
+
+ switch (proto) {
+ case cpu_to_be16(PPP_IP):
+ return cpu_to_be16(ETH_P_IP);
+#if IS_ENABLED(CONFIG_IPV6)
+ case cpu_to_be16(PPP_IPV6):
+ return cpu_to_be16(ETH_P_IPV6);
+#endif
+ default:
+ return 0;
+ }
+
+}
+
+static struct sk_buff *pppoe_gro_receive(struct list_head *head,
@@ -61,26 +76,27 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+{
+ const struct packet_offload *ptype;
+ unsigned int hlen, off_pppoe;
+ const struct pppoe_hdr *phdr;
+ struct sk_buff *pp = NULL;
+ struct pppoe_hdr *phdr;
+ struct sk_buff *p;
+ int flush = 1;
+ __be16 type;
+
+ off_pppoe = skb_gro_offset(skb);
+ hlen = off_pppoe + sizeof(*phdr);
+ phdr = skb_gro_header(skb, hlen + 2, off_pppoe);
+ hlen = off_pppoe + PPPOE_SES_HLEN;
+ phdr = skb_gro_header(skb, hlen, off_pppoe);
+ if (unlikely(!phdr))
+ goto out;
+
+ /* filter for session packets (type:1, ver:1, code:0) */
+ if (*(const __be16 *)phdr != cpu_to_be16(0x1100))
+ goto out;
+
+ /* ignore packets with padding or invalid length */
+ if (skb_gro_len(skb) != be16_to_cpu(phdr->length) + hlen)
+ if (skb_gro_len(skb) != be16_to_cpu(phdr->length) + sizeof(*phdr))
+ goto out;
+
+ type = pppoe_hdr_proto(phdr);
+ if (!type)
+ goto out;
+
+ ptype = gro_find_receive_by_type(type);
+ if (!ptype)
+ goto out;
@@ -88,18 +104,18 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+ flush = 0;
+
+ list_for_each_entry(p, head, list) {
+ struct pppoe_hdr *phdr2;
+ const struct pppoe_hdr *phdr2;
+
+ if (!NAPI_GRO_CB(p)->same_flow)
+ continue;
+
+ phdr2 = (struct pppoe_hdr *)(p->data + off_pppoe);
+ phdr2 = (const struct pppoe_hdr *)(p->data + off_pppoe);
+ if (compare_pppoe_header(phdr, phdr2))
+ NAPI_GRO_CB(p)->same_flow = 0;
+ }
+
+ skb_gro_pull(skb, sizeof(*phdr) + 2);
+ skb_gro_postpull_rcsum(skb, phdr, sizeof(*phdr) + 2);
+ skb_gro_pull(skb, PPPOE_SES_HLEN);
+ skb_gro_postpull_rcsum(skb, phdr, PPPOE_SES_HLEN);
+
+ pp = indirect_call_gro_receive_inet(ptype->callbacks.gro_receive,
+ ipv6_gro_receive, inet_gro_receive,
@@ -116,32 +132,26 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+ struct pppoe_hdr *phdr = (struct pppoe_hdr *)(skb->data + nhoff);
+ __be16 type = pppoe_hdr_proto(phdr);
+ struct packet_offload *ptype;
+ int len, err;
+ unsigned int len;
+
+ ptype = gro_find_complete_by_type(type);
+ if (!ptype)
+ return -ENOENT;
+
+ err = INDIRECT_CALL_INET(ptype->callbacks.gro_complete,
+ ipv6_gro_complete, inet_gro_complete,
+ skb, nhoff + sizeof(*phdr) + 2);
+ if (err)
+ return err;
+
+ len = skb->len - (nhoff + sizeof(*phdr));
+ len = min(len, 0xFFFFU);
+ phdr->length = cpu_to_be16(len);
+
+ return 0;
+ return INDIRECT_CALL_INET(ptype->callbacks.gro_complete,
+ ipv6_gro_complete, inet_gro_complete,
+ skb, nhoff + PPPOE_SES_HLEN);
+}
+
+static struct sk_buff *pppoe_gso_segment(struct sk_buff *skb,
+ netdev_features_t features)
+{
+ unsigned int pppoe_hlen = sizeof(struct pppoe_hdr) + 2;
+ struct sk_buff *segs = ERR_PTR(-EINVAL);
+ u16 mac_offset = skb->mac_header;
+ struct packet_offload *ptype;
+ u16 mac_len = skb->mac_len;
+ struct pppoe_hdr *phdr;
+ __be16 orig_type, type;
+ int len, nhoff;
@@ -149,7 +159,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+ skb_reset_network_header(skb);
+ nhoff = skb_network_header(skb) - skb_mac_header(skb);
+
+ if (unlikely(!pskb_may_pull(skb, pppoe_hlen)))
+ if (unlikely(!pskb_may_pull(skb, PPPOE_SES_HLEN)))
+ goto out;
+
+ phdr = (struct pppoe_hdr *)skb_network_header(skb);
@@ -159,13 +169,11 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+ goto out;
+
+ orig_type = skb->protocol;
+ __skb_pull(skb, pppoe_hlen);
+ __skb_pull(skb, PPPOE_SES_HLEN);
+ features &= ~NETIF_F_GSO_SOFTWARE;
+ segs = ptype->callbacks.gso_segment(skb, features);
+ if (IS_ERR_OR_NULL(segs)) {
+ skb_gso_error_unwind(skb, orig_type, pppoe_hlen, mac_offset,
+ mac_len);
+ if (IS_ERR_OR_NULL(segs))
+ goto out;
+ }
+
+ skb = segs;
+ do {
@@ -194,19 +202,21 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
static int __init pppoe_init(void)
{
int err;
@@ -1192,6 +1348,7 @@ static int __init pppoe_init(void)
@@ -1192,6 +1347,8 @@ static int __init pppoe_init(void)
if (err)
goto out_unregister_pppoe_proto;
+ dev_add_offload(&pppoe_packet_offload);
+ if (IS_ENABLED(CONFIG_INET))
+ dev_add_offload(&pppoe_packet_offload);
dev_add_pack(&pppoes_ptype);
dev_add_pack(&pppoed_ptype);
register_netdevice_notifier(&pppoe_notifier);
@@ -1211,6 +1368,7 @@ static void __exit pppoe_exit(void)
@@ -1211,6 +1368,8 @@ static void __exit pppoe_exit(void)
unregister_netdevice_notifier(&pppoe_notifier);
dev_remove_pack(&pppoed_ptype);
dev_remove_pack(&pppoes_ptype);
+ dev_remove_offload(&pppoe_packet_offload);
+ if (IS_ENABLED(CONFIG_INET))
+ dev_remove_offload(&pppoe_packet_offload);
unregister_pppox_proto(PX_PROTO_OE);
proto_unregister(&pppoe_sk_proto);
unregister_pernet_device(&pppoe_net_ops);
-2
View File
@@ -3259,8 +3259,6 @@ define Device/tplink_f65-v1
endef
TARGET_DEVICES += tplink_f65-v1
define Device/tplink_fr365-v1
define Device/tplink_re6000xd
DEVICE_VENDOR := TP-Link
DEVICE_MODEL := RE6000XD
@@ -19,7 +19,7 @@
led-failsafe = &led_status_green;
led-running = &led_status_green;
led-upgrade = &led_status_green;
label-mac-device = &gmac1;
label-mac-device = &gmac0;
};
gpio_export {