blob: b09b3bc5e81dc07024de45f1da88dc4935ddc59b [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001From: Felix Fietkau <nbd@nbd.name>
2Date: Thu, 15 Mar 2018 21:15:00 +0100
3Subject: [PATCH] net: pppoe: support hardware flow table offload
4
5Pass on the PPPoE session ID and the remote MAC address
6
7Signed-off-by: Felix Fietkau <nbd@nbd.name>
8---
9
10--- a/drivers/net/ppp/ppp_generic.c
11+++ b/drivers/net/ppp/ppp_generic.c
12@@ -53,6 +53,11 @@
13 #include <net/net_namespace.h>
14 #include <net/netns/generic.h>
15
16+#if IS_ENABLED(CONFIG_NF_FLOW_TABLE)
17+#include <linux/netfilter.h>
18+#include <net/netfilter/nf_flow_table.h>
19+#endif
20+
21 #define PPP_VERSION "2.4.2"
22
23 /*
24@@ -1378,12 +1383,37 @@ static void ppp_dev_priv_destructor(stru
25 ppp_destroy_interface(ppp);
26 }
27
28+#if IS_ENABLED(CONFIG_NF_FLOW_TABLE)
29+static int ppp_flow_offload_check(struct flow_offload_hw_path *path)
30+{
31+ struct ppp *ppp = netdev_priv(path->dev);
32+ struct ppp_channel *chan;
33+ struct channel *pch;
34+
35+ if (ppp->flags & SC_MULTILINK)
36+ return -EOPNOTSUPP;
37+
38+ if (list_empty(&ppp->channels))
39+ return -ENODEV;
40+
41+ pch = list_first_entry(&ppp->channels, struct channel, clist);
42+ chan = pch->chan;
43+ if (!chan->ops->flow_offload_check)
44+ return -EOPNOTSUPP;
45+
46+ return chan->ops->flow_offload_check(chan, path);
47+}
48+#endif /* CONFIG_NF_FLOW_TABLE */
49+
50 static const struct net_device_ops ppp_netdev_ops = {
51 .ndo_init = ppp_dev_init,
52 .ndo_uninit = ppp_dev_uninit,
53 .ndo_start_xmit = ppp_start_xmit,
54 .ndo_do_ioctl = ppp_net_ioctl,
55 .ndo_get_stats64 = ppp_get_stats64,
56+#if IS_ENABLED(CONFIG_NF_FLOW_TABLE)
57+ .ndo_flow_offload_check = ppp_flow_offload_check,
58+#endif
59 };
60
61 static struct device_type ppp_type = {
62--- a/drivers/net/ppp/pppoe.c
63+++ b/drivers/net/ppp/pppoe.c
64@@ -73,6 +73,11 @@
65 #include <linux/proc_fs.h>
66 #include <linux/seq_file.h>
67
68+#if IS_ENABLED(CONFIG_NF_FLOW_TABLE)
69+#include <linux/netfilter.h>
70+#include <net/netfilter/nf_flow_table.h>
71+#endif
72+
73 #include <linux/nsproxy.h>
74 #include <net/net_namespace.h>
75 #include <net/netns/generic.h>
76@@ -974,8 +979,36 @@ static int pppoe_xmit(struct ppp_channel
77 return __pppoe_xmit(sk, skb);
78 }
79
80+#if IS_ENABLED(CONFIG_NF_FLOW_TABLE)
81+static int pppoe_flow_offload_check(struct ppp_channel *chan,
82+ struct flow_offload_hw_path *path)
83+{
84+ struct sock *sk = (struct sock *)chan->private;
85+ struct pppox_sock *po = pppox_sk(sk);
86+ struct net_device *dev = po->pppoe_dev;
87+
88+ if (sock_flag(sk, SOCK_DEAD) ||
89+ !(sk->sk_state & PPPOX_CONNECTED) || !dev)
90+ return -ENODEV;
91+
92+ path->dev = po->pppoe_dev;
93+ path->flags |= FLOW_OFFLOAD_PATH_PPPOE;
94+ memcpy(path->eth_src, po->pppoe_dev->dev_addr, ETH_ALEN);
95+ memcpy(path->eth_dest, po->pppoe_pa.remote, ETH_ALEN);
96+ path->pppoe_sid = be16_to_cpu(po->num);
97+
98+ if (path->dev->netdev_ops->ndo_flow_offload_check)
99+ return path->dev->netdev_ops->ndo_flow_offload_check(path);
100+
101+ return 0;
102+}
103+#endif /* CONFIG_NF_FLOW_TABLE */
104+
105 static const struct ppp_channel_ops pppoe_chan_ops = {
106 .start_xmit = pppoe_xmit,
107+#if IS_ENABLED(CONFIG_NF_FLOW_TABLE)
108+ .flow_offload_check = pppoe_flow_offload_check,
109+#endif
110 };
111
112 static int pppoe_recvmsg(struct socket *sock, struct msghdr *m,
113--- a/include/linux/ppp_channel.h
114+++ b/include/linux/ppp_channel.h
115@@ -28,6 +28,10 @@ struct ppp_channel_ops {
116 int (*start_xmit)(struct ppp_channel *, struct sk_buff *);
117 /* Handle an ioctl call that has come in via /dev/ppp. */
118 int (*ioctl)(struct ppp_channel *, unsigned int, unsigned long);
119+
120+#if IS_ENABLED(CONFIG_NF_FLOW_TABLE)
121+ int (*flow_offload_check)(struct ppp_channel *, struct flow_offload_hw_path *);
122+#endif
123 };
124
125 struct ppp_channel {