ipq806x: convert to using qca8k
[openwrt/staging/blogic.git] / target / linux / ipq806x / patches-4.9 / 901-netfilter-qca8k-add-CT-extension.patch
1 From 8541425fb399861a3c92f4a02f16f98e7e6aa47a Mon Sep 17 00:00:00 2001
2 From: John Crispin <john@phrozen.org>
3 Date: Tue, 1 Nov 2016 01:55:27 +0100
4 Subject: [PATCH 05/22] netfilter: qca8k: add CT extension
5
6 this allows us to track our offloaded state inside the actual conntrack
7 entry.
8
9 Signed-off-by: John Crispin <john@phrozen.org>
10 ---
11 include/net/netfilter/nf_conntrack_extend.h | 4 ++
12 include/net/netfilter/nf_conntrack_qca8k.h | 70 +++++++++++++++++++++++++++
13 net/netfilter/Kconfig | 11 +++++
14 net/netfilter/Makefile | 3 ++
15 net/netfilter/nf_conntrack_core.c | 15 ++++++
16 net/netfilter/nf_conntrack_proto_tcp.c | 7 ++-
17 net/netfilter/nf_conntrack_qca8k.c | 58 ++++++++++++++++++++++
18 7 files changed, 167 insertions(+), 1 deletion(-)
19 create mode 100644 include/net/netfilter/nf_conntrack_qca8k.h
20 create mode 100644 net/netfilter/nf_conntrack_qca8k.c
21
22 Index: linux-4.9.34/include/net/netfilter/nf_conntrack_extend.h
23 ===================================================================
24 --- linux-4.9.34.orig/include/net/netfilter/nf_conntrack_extend.h
25 +++ linux-4.9.34/include/net/netfilter/nf_conntrack_extend.h
26 @@ -30,6 +30,9 @@ enum nf_ct_ext_id {
27 #if IS_ENABLED(CONFIG_NF_CONNTRACK_RTCACHE)
28 NF_CT_EXT_RTCACHE,
29 #endif
30 +#if IS_ENABLED(CONFIG_NF_CONNTRACK_QCA8K)
31 + NF_CT_EXT_QCA8K,
32 +#endif
33 NF_CT_EXT_NUM,
34 };
35
36 @@ -43,6 +46,7 @@ enum nf_ct_ext_id {
37 #define NF_CT_EXT_LABELS_TYPE struct nf_conn_labels
38 #define NF_CT_EXT_SYNPROXY_TYPE struct nf_conn_synproxy
39 #define NF_CT_EXT_RTCACHE_TYPE struct nf_conn_rtcache
40 +#define NF_CT_EXT_QCA8K_TYPE struct nf_conn_qca8k
41
42 /* Extensions: optional stuff which isn't permanently in struct. */
43 struct nf_ct_ext {
44 Index: linux-4.9.34/include/net/netfilter/nf_conntrack_qca8k.h
45 ===================================================================
46 --- /dev/null
47 +++ linux-4.9.34/include/net/netfilter/nf_conntrack_qca8k.h
48 @@ -0,0 +1,70 @@
49 +#ifndef _NF_CONNTRACK_QCA8K_H
50 +#define _NF_CONNTRACK_QCA8K_H
51 +
52 +#include <net/net_namespace.h>
53 +#include <linux/netfilter/nf_conntrack_common.h>
54 +#include <linux/netfilter/nf_conntrack_tuple_common.h>
55 +#include <net/netfilter/nf_conntrack.h>
56 +#include <net/netfilter/nf_conntrack_extend.h>
57 +
58 +struct qca8k_priv;
59 +
60 +struct nf_conn_qca8k {
61 + struct nf_conn *ct;
62 + int idx;
63 + u64 counter;
64 + int fail;
65 + struct qca8k_priv *priv;
66 +};
67 +
68 +static inline
69 +struct nf_conn_qca8k *nf_ct_qca8k_find(const struct nf_conn *ct)
70 +{
71 +#if defined(CONFIG_NF_CONNTRACK_QCA8K) || defined(CONFIG_NF_CONNTRACK_QCA8K_MODULE)
72 + return nf_ct_ext_find(ct, NF_CT_EXT_QCA8K);
73 +#else
74 + return NULL;
75 +#endif
76 +}
77 +
78 +static inline
79 +struct nf_conn_qca8k *nf_ct_qca8k_ext_add(struct nf_conn *ct,
80 + gfp_t gfp)
81 +{
82 +#if defined(CONFIG_NF_CONNTRACK_QCA8K) || defined(CONFIG_NF_CONNTRACK_QCA8K_MODULE)
83 + struct nf_conn_qca8k *qca8k_ext;
84 +
85 + qca8k_ext = nf_ct_ext_add(ct, NF_CT_EXT_QCA8K, gfp);
86 + if (qca8k_ext == NULL)
87 + return NULL;
88 +
89 + qca8k_ext->idx = -1;
90 + qca8k_ext->ct = ct;
91 + qca8k_ext->counter = qca8k_ext->fail = 0;
92 +
93 + return qca8k_ext;
94 +#else
95 + return NULL;
96 +#endif
97 +};
98 +
99 +#if defined(CONFIG_NF_CONNTRACK_QCA8K) || defined(CONFIG_NF_CONNTRACK_QCA8K_MODULE)
100 +int nf_conntrack_qca8k_init(void);
101 +void nf_conntrack_qca8k_fini(void);
102 +#else
103 +static inline int nf_conntrack_qca8k_init(void)
104 +{
105 + return 0;
106 +}
107 +
108 +static inline void nf_conntrack_qca8k_fini(void)
109 +{
110 + return;
111 +}
112 +#endif /* CONFIG_NF_CONNTRACK_QCA8K */
113 +
114 +#if defined(CONFIG_NF_CONNTRACK_QCA8K) || defined(CONFIG_NF_CONNTRACK_QCA8K_MODULE)
115 +extern void (*nf_ct_qca8k_destroy)(struct nf_conn *ct, struct nf_conn_qca8k *conn);
116 +#endif
117 +
118 +#endif /* _NF_CONNTRACK_QCA8K_H */
119 Index: linux-4.9.34/net/netfilter/Kconfig
120 ===================================================================
121 --- linux-4.9.34.orig/net/netfilter/Kconfig
122 +++ linux-4.9.34/net/netfilter/Kconfig
123 @@ -147,6 +147,17 @@ config NF_CONNTRACK_TIMESTAMP
124
125 If unsure, say `N'.
126
127 +config NF_CONNTRACK_QCA8K
128 + tristate "QCA8K offload entries in conntrack objectt"
129 + depends on NETFILTER_ADVANCED
130 + depends on NF_CONNTRACK
131 + help
132 + If this option is enabled, the connection tracking code will
133 + be able to track connections offloaded to the QCA8K switch core
134 +
135 + To compile it as a module, choose M here. If unsure, say N.
136 + The module will be called nf_conntrack_rtcache.
137 +
138 config NF_CONNTRACK_LABELS
139 bool
140 help
141 Index: linux-4.9.34/net/netfilter/Makefile
142 ===================================================================
143 --- linux-4.9.34.orig/net/netfilter/Makefile
144 +++ linux-4.9.34/net/netfilter/Makefile
145 @@ -1,6 +1,7 @@
146 netfilter-objs := core.o nf_log.o nf_queue.o nf_sockopt.o
147
148 -nf_conntrack-y := nf_conntrack_core.o nf_conntrack_standalone.o nf_conntrack_expect.o nf_conntrack_helper.o nf_conntrack_proto.o nf_conntrack_l3proto_generic.o nf_conntrack_proto_generic.o nf_conntrack_proto_tcp.o nf_conntrack_proto_udp.o nf_conntrack_extend.o nf_conntrack_acct.o nf_conntrack_seqadj.o
149 +nf_conntrack-y := nf_conntrack_core.o nf_conntrack_standalone.o nf_conntrack_expect.o nf_conntrack_helper.o nf_conntrack_proto.o nf_conntrack_l3proto_generic.o nf_conntrack_proto_generic.o nf_conntrack_proto_tcp.o nf_conntrack_proto_udp.o nf_conntrack_extend.o nf_conntrack_acct.o nf_conntrack_seqadj.o nf_conntrack_qca8k.o
150 +
151 nf_conntrack-$(CONFIG_NF_CONNTRACK_TIMEOUT) += nf_conntrack_timeout.o
152 nf_conntrack-$(CONFIG_NF_CONNTRACK_TIMESTAMP) += nf_conntrack_timestamp.o
153 nf_conntrack-$(CONFIG_NF_CONNTRACK_EVENTS) += nf_conntrack_ecache.o
154 @@ -19,6 +20,7 @@ obj-$(CONFIG_NF_CONNTRACK) += nf_conntra
155 # optional conntrack route cache extension
156 obj-$(CONFIG_NF_CONNTRACK_RTCACHE) += nf_conntrack_rtcache.o
157
158 +
159 # SCTP protocol connection tracking
160 obj-$(CONFIG_NF_CT_PROTO_DCCP) += nf_conntrack_proto_dccp.o
161 obj-$(CONFIG_NF_CT_PROTO_GRE) += nf_conntrack_proto_gre.o
162 Index: linux-4.9.34/net/netfilter/nf_conntrack_core.c
163 ===================================================================
164 --- linux-4.9.34.orig/net/netfilter/nf_conntrack_core.c
165 +++ linux-4.9.34/net/netfilter/nf_conntrack_core.c
166 @@ -51,6 +51,7 @@
167 #include <net/netfilter/nf_conntrack_timeout.h>
168 #include <net/netfilter/nf_conntrack_labels.h>
169 #include <net/netfilter/nf_conntrack_synproxy.h>
170 +#include <net/netfilter/nf_conntrack_qca8k.h>
171 #include <net/netfilter/nf_nat.h>
172 #include <net/netfilter/nf_nat_core.h>
173 #include <net/netfilter/nf_nat_helper.h>
174 @@ -1153,6 +1154,8 @@ init_conntrack(struct net *net, struct n
175 timeouts = l4proto->get_timeouts(net);
176 }
177
178 + nf_ct_qca8k_ext_add(ct, GFP_ATOMIC);
179 +
180 if (!l4proto->new(ct, skb, dataoff, timeouts)) {
181 nf_conntrack_free(ct);
182 pr_debug("can't track with proto module\n");
183 @@ -1591,6 +1594,12 @@ void nf_ct_iterate_cleanup(struct net *n
184 return;
185
186 while ((ct = get_next_corpse(net, iter, data, &bucket)) != NULL) {
187 + struct nf_conn_qca8k *qca8k_ext;
188 +
189 + qca8k_ext = nf_ct_qca8k_find(ct);
190 + if (qca8k_ext && qca8k_ext->idx >= 0)
191 + continue;
192 +
193 /* Time to push up daises... */
194
195 nf_ct_delete(ct, portid, report);
196 @@ -1906,6 +1915,10 @@ int nf_conntrack_init_start(void)
197 if (ret < 0)
198 goto err_proto;
199
200 + ret = nf_conntrack_qca8k_init();
201 + if (ret < 0)
202 + goto err_qca8k;
203 +
204 /* Set up fake conntrack: to never be deleted, not in any hashes */
205 for_each_possible_cpu(cpu) {
206 struct nf_conn *ct = &per_cpu(nf_conntrack_untracked, cpu);
207 @@ -1922,6 +1935,8 @@ int nf_conntrack_init_start(void)
208
209 err_proto:
210 nf_conntrack_seqadj_fini();
211 +err_qca8k:
212 + nf_conntrack_qca8k_fini();
213 err_seqadj:
214 nf_conntrack_labels_fini();
215 err_labels:
216 Index: linux-4.9.34/net/netfilter/nf_conntrack_proto_tcp.c
217 ===================================================================
218 --- linux-4.9.34.orig/net/netfilter/nf_conntrack_proto_tcp.c
219 +++ linux-4.9.34/net/netfilter/nf_conntrack_proto_tcp.c
220 @@ -29,6 +29,7 @@
221 #include <net/netfilter/nf_conntrack_ecache.h>
222 #include <net/netfilter/nf_conntrack_seqadj.h>
223 #include <net/netfilter/nf_conntrack_synproxy.h>
224 +#include <net/netfilter/nf_conntrack_qca8k.h>
225 #include <net/netfilter/nf_log.h>
226 #include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
227 #include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
228 @@ -823,6 +824,7 @@ static int tcp_packet(struct nf_conn *ct
229 {
230 struct net *net = nf_ct_net(ct);
231 struct nf_tcp_net *tn = tcp_pernet(net);
232 + struct nf_conn_qca8k *qca8k_ext;
233 struct nf_conntrack_tuple *tuple;
234 enum tcp_conntrack new_state, old_state;
235 enum ip_conntrack_dir dir;
236 @@ -1037,7 +1039,10 @@ static int tcp_packet(struct nf_conn *ct
237 break;
238 }
239
240 - if (!tcp_in_window(ct, &ct->proto.tcp, dir, index,
241 + qca8k_ext = nf_ct_qca8k_find(ct);
242 +// if (qca8k_ext)
243 +// printk("%s:%s[%d]%d\n", __FILE__, __func__, __LINE__, qca8k_ext->idx);
244 + if ((!qca8k_ext || (qca8k_ext->idx < 0)) && !tcp_in_window(ct, &ct->proto.tcp, dir, index,
245 skb, dataoff, th, pf)) {
246 spin_unlock_bh(&ct->lock);
247 return -NF_ACCEPT;
248 Index: linux-4.9.34/net/netfilter/nf_conntrack_qca8k.c
249 ===================================================================
250 --- /dev/null
251 +++ linux-4.9.34/net/netfilter/nf_conntrack_qca8k.c
252 @@ -0,0 +1,64 @@
253 +/*
254 + * (C) 2016 John Crispin <john@phrozen.org>
255 + *
256 + * This program is free software; you can redistribute it and/or modify
257 + * it under the terms of the GNU General Public License version 2 as
258 + * published by the Free Software Foundation (or any later at your option).
259 + */
260 +
261 +#include <linux/types.h>
262 +#include <linux/netfilter.h>
263 +#include <linux/skbuff.h>
264 +#include <linux/vmalloc.h>
265 +#include <linux/stddef.h>
266 +#include <linux/err.h>
267 +#include <linux/percpu.h>
268 +#include <linux/kernel.h>
269 +#include <linux/netdevice.h>
270 +#include <linux/slab.h>
271 +#include <linux/export.h>
272 +
273 +#include <net/netfilter/nf_conntrack.h>
274 +#include <net/netfilter/nf_conntrack_core.h>
275 +#include <net/netfilter/nf_conntrack_extend.h>
276 +#include <net/netfilter/nf_conntrack_qca8k.h>
277 +
278 +void (*nf_ct_qca8k_destroy)(struct nf_conn *ct, struct nf_conn_qca8k *conn) __read_mostly;
279 +EXPORT_SYMBOL_GPL(nf_ct_qca8k_destroy);
280 +
281 +static void nf_conn_qca8k_destroy(struct nf_conn *ct)
282 +{
283 + struct nf_conn_qca8k *conn = nf_ct_qca8k_find(ct);
284 +
285 + if (!conn || !nf_ct_qca8k_destroy)
286 + return;
287 +
288 + nf_ct_qca8k_destroy(ct, conn);
289 +}
290 +
291 +static struct nf_ct_ext_type qca8k_extend __read_mostly = {
292 + .len = sizeof(struct nf_conn_qca8k),
293 + .align = __alignof__(struct nf_conn_qca8k),
294 + .id = NF_CT_EXT_QCA8K,
295 + .destroy = nf_conn_qca8k_destroy,
296 +};
297 +
298 +int nf_conntrack_qca8k_init(void)
299 +{
300 + int ret = nf_ct_extend_register(&qca8k_extend);
301 + if (ret < 0)
302 + pr_err("nf_ct_qca8k: Unable to register qca8k extension.\n");
303 + nf_ct_qca8k_destroy = NULL;
304 + return ret;
305 +}
306 +EXPORT_SYMBOL_GPL(nf_conntrack_qca8k_init);
307 +
308 +void nf_conntrack_qca8k_fini(void)
309 +{
310 + nf_ct_extend_unregister(&qca8k_extend);
311 +}
312 +EXPORT_SYMBOL_GPL(nf_conntrack_qca8k_fini);
313 +
314 +MODULE_DESCRIPTION("Qualcomm switch offloading driver");
315 +MODULE_AUTHOR("John Crispin <john@phrozen.org");
316 +MODULE_LICENSE("GPL v2");