1
1

kernel: update pppoe patch

Use the patch version accepted upstream and move it to backports dir.

Signed-off-by: Qingfang Deng <dqfext@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/23438
Signed-off-by: Robert Marko <robimarko@gmail.com>
This commit is contained in:
Qingfang Deng 2026-05-19 21:31:40 +08:00 committed by Robert Marko
parent e75f33d0f2
commit a97dd6e8d9
2 changed files with 102 additions and 82 deletions

View File

@ -1,6 +1,7 @@
From 55a5d8fca8365312ed53bc93ae1af67ee35c2915 Mon Sep 17 00:00:00 2001
From: Felix Fietkau <nbd@nbd.name> From: Felix Fietkau <nbd@nbd.name>
Date: Tue, 15 Jul 2025 12:37:45 +0200 Date: Wed, 13 May 2026 09:33:48 +0800
Subject: [PATCH] net: pppoe: implement GRO support Subject: [PATCH] net: pppoe: implement GRO/GSO support
Only handles packets where the pppoe header length field matches the exact Only handles packets where the pppoe header length field matches the exact
packet length. Significantly improves rx throughput. 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. using fraglist GRO.
Signed-off-by: Felix Fietkau <nbd@nbd.name> 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 --- a/drivers/net/ppp/pppoe.c
+++ b/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; goto drop;
ph = pppoe_hdr(skb); 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), .size = sizeof(struct pppoe_net),
}; };
+static u16 +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) | + __be16 proto = *(const __be16 *)(phdr + 1);
+ (phdr->tag[0].tag_type ^ phdr2->tag[0].tag_type)); + __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): + case cpu_to_be16(PPP_IP):
+ return cpu_to_be16(ETH_P_IP); + return cpu_to_be16(ETH_P_IP);
+#if IS_ENABLED(CONFIG_IPV6)
+ case cpu_to_be16(PPP_IPV6): + case cpu_to_be16(PPP_IPV6):
+ return cpu_to_be16(ETH_P_IPV6); + return cpu_to_be16(ETH_P_IPV6);
+#endif
+ default: + default:
+ return 0; + return 0;
+ } + }
+
+} +}
+ +
+static struct sk_buff *pppoe_gro_receive(struct list_head *head, +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; + const struct packet_offload *ptype;
+ unsigned int hlen, off_pppoe; + unsigned int hlen, off_pppoe;
+ const struct pppoe_hdr *phdr;
+ struct sk_buff *pp = NULL; + struct sk_buff *pp = NULL;
+ struct pppoe_hdr *phdr;
+ struct sk_buff *p; + struct sk_buff *p;
+ int flush = 1; + int flush = 1;
+ __be16 type; + __be16 type;
+ +
+ off_pppoe = skb_gro_offset(skb); + off_pppoe = skb_gro_offset(skb);
+ hlen = off_pppoe + sizeof(*phdr); + hlen = off_pppoe + PPPOE_SES_HLEN;
+ phdr = skb_gro_header(skb, hlen + 2, off_pppoe); + phdr = skb_gro_header(skb, hlen, off_pppoe);
+ if (unlikely(!phdr)) + if (unlikely(!phdr))
+ goto out; + 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 */ + /* 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; + goto out;
+ +
+ type = pppoe_hdr_proto(phdr); + type = pppoe_hdr_proto(phdr);
+ if (!type)
+ goto out;
+
+ ptype = gro_find_receive_by_type(type); + ptype = gro_find_receive_by_type(type);
+ if (!ptype) + if (!ptype)
+ goto out; + goto out;
@ -88,18 +104,18 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+ flush = 0; + flush = 0;
+ +
+ list_for_each_entry(p, head, list) { + list_for_each_entry(p, head, list) {
+ struct pppoe_hdr *phdr2; + const struct pppoe_hdr *phdr2;
+ +
+ if (!NAPI_GRO_CB(p)->same_flow) + if (!NAPI_GRO_CB(p)->same_flow)
+ continue; + continue;
+ +
+ phdr2 = (struct pppoe_hdr *)(p->data + off_pppoe); + phdr2 = (const struct pppoe_hdr *)(p->data + off_pppoe);
+ if (compare_pppoe_header(phdr, phdr2)) + if (compare_pppoe_header(phdr, phdr2))
+ NAPI_GRO_CB(p)->same_flow = 0; + NAPI_GRO_CB(p)->same_flow = 0;
+ } + }
+ +
+ skb_gro_pull(skb, sizeof(*phdr) + 2); + skb_gro_pull(skb, PPPOE_SES_HLEN);
+ skb_gro_postpull_rcsum(skb, phdr, sizeof(*phdr) + 2); + skb_gro_postpull_rcsum(skb, phdr, PPPOE_SES_HLEN);
+ +
+ pp = indirect_call_gro_receive_inet(ptype->callbacks.gro_receive, + pp = indirect_call_gro_receive_inet(ptype->callbacks.gro_receive,
+ ipv6_gro_receive, inet_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); + struct pppoe_hdr *phdr = (struct pppoe_hdr *)(skb->data + nhoff);
+ __be16 type = pppoe_hdr_proto(phdr); + __be16 type = pppoe_hdr_proto(phdr);
+ struct packet_offload *ptype; + struct packet_offload *ptype;
+ int len, err; + unsigned int len;
+ +
+ ptype = gro_find_complete_by_type(type); + ptype = gro_find_complete_by_type(type);
+ if (!ptype) + if (!ptype)
+ return -ENOENT; + 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 = skb->len - (nhoff + sizeof(*phdr));
+ len = min(len, 0xFFFFU);
+ phdr->length = cpu_to_be16(len); + 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, +static struct sk_buff *pppoe_gso_segment(struct sk_buff *skb,
+ netdev_features_t features) + netdev_features_t features)
+{ +{
+ unsigned int pppoe_hlen = sizeof(struct pppoe_hdr) + 2;
+ struct sk_buff *segs = ERR_PTR(-EINVAL); + struct sk_buff *segs = ERR_PTR(-EINVAL);
+ u16 mac_offset = skb->mac_header;
+ struct packet_offload *ptype; + struct packet_offload *ptype;
+ u16 mac_len = skb->mac_len;
+ struct pppoe_hdr *phdr; + struct pppoe_hdr *phdr;
+ __be16 orig_type, type; + __be16 orig_type, type;
+ int len, nhoff; + int len, nhoff;
@ -149,7 +159,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+ skb_reset_network_header(skb); + skb_reset_network_header(skb);
+ nhoff = skb_network_header(skb) - skb_mac_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; + goto out;
+ +
+ phdr = (struct pppoe_hdr *)skb_network_header(skb); + phdr = (struct pppoe_hdr *)skb_network_header(skb);
@ -159,13 +169,11 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+ goto out; + goto out;
+ +
+ orig_type = skb->protocol; + 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); + segs = ptype->callbacks.gso_segment(skb, features);
+ if (IS_ERR_OR_NULL(segs)) { + if (IS_ERR_OR_NULL(segs))
+ skb_gso_error_unwind(skb, orig_type, pppoe_hlen, mac_offset,
+ mac_len);
+ goto out; + goto out;
+ }
+ +
+ skb = segs; + skb = segs;
+ do { + do {
@ -194,19 +202,21 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
static int __init pppoe_init(void) static int __init pppoe_init(void)
{ {
int err; int err;
@@ -1192,6 +1348,7 @@ static int __init pppoe_init(void) @@ -1192,6 +1347,8 @@ static int __init pppoe_init(void)
if (err) if (err)
goto out_unregister_pppoe_proto; 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(&pppoes_ptype);
dev_add_pack(&pppoed_ptype); dev_add_pack(&pppoed_ptype);
register_netdevice_notifier(&pppoe_notifier); 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); unregister_netdevice_notifier(&pppoe_notifier);
dev_remove_pack(&pppoed_ptype); dev_remove_pack(&pppoed_ptype);
dev_remove_pack(&pppoes_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); unregister_pppox_proto(PX_PROTO_OE);
proto_unregister(&pppoe_sk_proto); proto_unregister(&pppoe_sk_proto);
unregister_pernet_device(&pppoe_net_ops); unregister_pernet_device(&pppoe_net_ops);

View File

@ -1,6 +1,7 @@
From 55a5d8fca8365312ed53bc93ae1af67ee35c2915 Mon Sep 17 00:00:00 2001
From: Felix Fietkau <nbd@nbd.name> From: Felix Fietkau <nbd@nbd.name>
Date: Tue, 15 Jul 2025 12:37:45 +0200 Date: Wed, 13 May 2026 09:33:48 +0800
Subject: [PATCH] net: pppoe: implement GRO support Subject: [PATCH] net: pppoe: implement GRO/GSO support
Only handles packets where the pppoe header length field matches the exact Only handles packets where the pppoe header length field matches the exact
packet length. Significantly improves rx throughput. 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. using fraglist GRO.
Signed-off-by: Felix Fietkau <nbd@nbd.name> 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 --- a/drivers/net/ppp/pppoe.c
+++ b/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; goto drop;
ph = pppoe_hdr(skb); 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), .size = sizeof(struct pppoe_net),
}; };
+static u16 +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) | + __be16 proto = *(const __be16 *)(phdr + 1);
+ (phdr->tag[0].tag_type ^ phdr2->tag[0].tag_type)); + __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): + case cpu_to_be16(PPP_IP):
+ return cpu_to_be16(ETH_P_IP); + return cpu_to_be16(ETH_P_IP);
+#if IS_ENABLED(CONFIG_IPV6)
+ case cpu_to_be16(PPP_IPV6): + case cpu_to_be16(PPP_IPV6):
+ return cpu_to_be16(ETH_P_IPV6); + return cpu_to_be16(ETH_P_IPV6);
+#endif
+ default: + default:
+ return 0; + return 0;
+ } + }
+
+} +}
+ +
+static struct sk_buff *pppoe_gro_receive(struct list_head *head, +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; + const struct packet_offload *ptype;
+ unsigned int hlen, off_pppoe; + unsigned int hlen, off_pppoe;
+ const struct pppoe_hdr *phdr;
+ struct sk_buff *pp = NULL; + struct sk_buff *pp = NULL;
+ struct pppoe_hdr *phdr;
+ struct sk_buff *p; + struct sk_buff *p;
+ int flush = 1; + int flush = 1;
+ __be16 type; + __be16 type;
+ +
+ off_pppoe = skb_gro_offset(skb); + off_pppoe = skb_gro_offset(skb);
+ hlen = off_pppoe + sizeof(*phdr); + hlen = off_pppoe + PPPOE_SES_HLEN;
+ phdr = skb_gro_header(skb, hlen + 2, off_pppoe); + phdr = skb_gro_header(skb, hlen, off_pppoe);
+ if (unlikely(!phdr)) + if (unlikely(!phdr))
+ goto out; + 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 */ + /* 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; + goto out;
+ +
+ type = pppoe_hdr_proto(phdr); + type = pppoe_hdr_proto(phdr);
+ if (!type)
+ goto out;
+
+ ptype = gro_find_receive_by_type(type); + ptype = gro_find_receive_by_type(type);
+ if (!ptype) + if (!ptype)
+ goto out; + goto out;
@ -88,18 +104,18 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+ flush = 0; + flush = 0;
+ +
+ list_for_each_entry(p, head, list) { + list_for_each_entry(p, head, list) {
+ struct pppoe_hdr *phdr2; + const struct pppoe_hdr *phdr2;
+ +
+ if (!NAPI_GRO_CB(p)->same_flow) + if (!NAPI_GRO_CB(p)->same_flow)
+ continue; + continue;
+ +
+ phdr2 = (struct pppoe_hdr *)(p->data + off_pppoe); + phdr2 = (const struct pppoe_hdr *)(p->data + off_pppoe);
+ if (compare_pppoe_header(phdr, phdr2)) + if (compare_pppoe_header(phdr, phdr2))
+ NAPI_GRO_CB(p)->same_flow = 0; + NAPI_GRO_CB(p)->same_flow = 0;
+ } + }
+ +
+ skb_gro_pull(skb, sizeof(*phdr) + 2); + skb_gro_pull(skb, PPPOE_SES_HLEN);
+ skb_gro_postpull_rcsum(skb, phdr, sizeof(*phdr) + 2); + skb_gro_postpull_rcsum(skb, phdr, PPPOE_SES_HLEN);
+ +
+ pp = indirect_call_gro_receive_inet(ptype->callbacks.gro_receive, + pp = indirect_call_gro_receive_inet(ptype->callbacks.gro_receive,
+ ipv6_gro_receive, inet_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); + struct pppoe_hdr *phdr = (struct pppoe_hdr *)(skb->data + nhoff);
+ __be16 type = pppoe_hdr_proto(phdr); + __be16 type = pppoe_hdr_proto(phdr);
+ struct packet_offload *ptype; + struct packet_offload *ptype;
+ int len, err; + unsigned int len;
+ +
+ ptype = gro_find_complete_by_type(type); + ptype = gro_find_complete_by_type(type);
+ if (!ptype) + if (!ptype)
+ return -ENOENT; + 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 = skb->len - (nhoff + sizeof(*phdr));
+ len = min(len, 0xFFFFU);
+ phdr->length = cpu_to_be16(len); + 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, +static struct sk_buff *pppoe_gso_segment(struct sk_buff *skb,
+ netdev_features_t features) + netdev_features_t features)
+{ +{
+ unsigned int pppoe_hlen = sizeof(struct pppoe_hdr) + 2;
+ struct sk_buff *segs = ERR_PTR(-EINVAL); + struct sk_buff *segs = ERR_PTR(-EINVAL);
+ u16 mac_offset = skb->mac_header;
+ struct packet_offload *ptype; + struct packet_offload *ptype;
+ u16 mac_len = skb->mac_len;
+ struct pppoe_hdr *phdr; + struct pppoe_hdr *phdr;
+ __be16 orig_type, type; + __be16 orig_type, type;
+ int len, nhoff; + int len, nhoff;
@ -149,7 +159,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+ skb_reset_network_header(skb); + skb_reset_network_header(skb);
+ nhoff = skb_network_header(skb) - skb_mac_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; + goto out;
+ +
+ phdr = (struct pppoe_hdr *)skb_network_header(skb); + phdr = (struct pppoe_hdr *)skb_network_header(skb);
@ -159,13 +169,11 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+ goto out; + goto out;
+ +
+ orig_type = skb->protocol; + 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); + segs = ptype->callbacks.gso_segment(skb, features);
+ if (IS_ERR_OR_NULL(segs)) { + if (IS_ERR_OR_NULL(segs))
+ skb_gso_error_unwind(skb, orig_type, pppoe_hlen, mac_offset,
+ mac_len);
+ goto out; + goto out;
+ }
+ +
+ skb = segs; + skb = segs;
+ do { + do {
@ -194,19 +202,21 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
static int __init pppoe_init(void) static int __init pppoe_init(void)
{ {
int err; int err;
@@ -1192,6 +1348,7 @@ static int __init pppoe_init(void) @@ -1192,6 +1347,8 @@ static int __init pppoe_init(void)
if (err) if (err)
goto out_unregister_pppoe_proto; 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(&pppoes_ptype);
dev_add_pack(&pppoed_ptype); dev_add_pack(&pppoed_ptype);
register_netdevice_notifier(&pppoe_notifier); 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); unregister_netdevice_notifier(&pppoe_notifier);
dev_remove_pack(&pppoed_ptype); dev_remove_pack(&pppoed_ptype);
dev_remove_pack(&pppoes_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); unregister_pppox_proto(PX_PROTO_OE);
proto_unregister(&pppoe_sk_proto); proto_unregister(&pppoe_sk_proto);
unregister_pernet_device(&pppoe_net_ops); unregister_pernet_device(&pppoe_net_ops);