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
6 this allows us to track our offloaded state inside the actual conntrack
9 Signed-off-by: John Crispin <john@phrozen.org>
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
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)
30 +#if IS_ENABLED(CONFIG_NF_CONNTRACK_QCA8K)
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
42 /* Extensions: optional stuff which isn't permanently in struct. */
44 Index: linux-4.9.34/include/net/netfilter/nf_conntrack_qca8k.h
45 ===================================================================
47 +++ linux-4.9.34/include/net/netfilter/nf_conntrack_qca8k.h
49 +#ifndef _NF_CONNTRACK_QCA8K_H
50 +#define _NF_CONNTRACK_QCA8K_H
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>
60 +struct nf_conn_qca8k {
65 + struct qca8k_priv *priv;
69 +struct nf_conn_qca8k *nf_ct_qca8k_find(const struct nf_conn *ct)
71 +#if defined(CONFIG_NF_CONNTRACK_QCA8K) || defined(CONFIG_NF_CONNTRACK_QCA8K_MODULE)
72 + return nf_ct_ext_find(ct, NF_CT_EXT_QCA8K);
79 +struct nf_conn_qca8k *nf_ct_qca8k_ext_add(struct nf_conn *ct,
82 +#if defined(CONFIG_NF_CONNTRACK_QCA8K) || defined(CONFIG_NF_CONNTRACK_QCA8K_MODULE)
83 + struct nf_conn_qca8k *qca8k_ext;
85 + qca8k_ext = nf_ct_ext_add(ct, NF_CT_EXT_QCA8K, gfp);
86 + if (qca8k_ext == NULL)
89 + qca8k_ext->idx = -1;
91 + qca8k_ext->counter = qca8k_ext->fail = 0;
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);
103 +static inline int nf_conntrack_qca8k_init(void)
108 +static inline void nf_conntrack_qca8k_fini(void)
112 +#endif /* CONFIG_NF_CONNTRACK_QCA8K */
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);
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
127 +config NF_CONNTRACK_QCA8K
128 + tristate "QCA8K offload entries in conntrack objectt"
129 + depends on NETFILTER_ADVANCED
130 + depends on NF_CONNTRACK
132 + If this option is enabled, the connection tracking code will
133 + be able to track connections offloaded to the QCA8K switch core
135 + To compile it as a module, choose M here. If unsure, say N.
136 + The module will be called nf_conntrack_rtcache.
138 config NF_CONNTRACK_LABELS
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
146 netfilter-objs := core.o nf_log.o nf_queue.o nf_sockopt.o
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
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
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
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);
178 + nf_ct_qca8k_ext_add(ct, GFP_ATOMIC);
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
186 while ((ct = get_next_corpse(net, iter, data, &bucket)) != NULL) {
187 + struct nf_conn_qca8k *qca8k_ext;
189 + qca8k_ext = nf_ct_qca8k_find(ct);
190 + if (qca8k_ext && qca8k_ext->idx >= 0)
193 /* Time to push up daises... */
195 nf_ct_delete(ct, portid, report);
196 @@ -1906,6 +1915,10 @@ int nf_conntrack_init_start(void)
200 + ret = nf_conntrack_qca8k_init();
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)
210 nf_conntrack_seqadj_fini();
212 + nf_conntrack_qca8k_fini();
214 nf_conntrack_labels_fini();
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
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
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
240 - if (!tcp_in_window(ct, &ct->proto.tcp, dir, index,
241 + qca8k_ext = nf_ct_qca8k_find(ct);
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);
248 Index: linux-4.9.34/net/netfilter/nf_conntrack_qca8k.c
249 ===================================================================
251 +++ linux-4.9.34/net/netfilter/nf_conntrack_qca8k.c
254 + * (C) 2016 John Crispin <john@phrozen.org>
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).
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>
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>
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);
281 +static void nf_conn_qca8k_destroy(struct nf_conn *ct)
283 + struct nf_conn_qca8k *conn = nf_ct_qca8k_find(ct);
285 + if (!conn || !nf_ct_qca8k_destroy)
288 + nf_ct_qca8k_destroy(ct, conn);
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,
298 +int nf_conntrack_qca8k_init(void)
300 + int ret = nf_ct_extend_register(&qca8k_extend);
302 + pr_err("nf_ct_qca8k: Unable to register qca8k extension.\n");
303 + nf_ct_qca8k_destroy = NULL;
306 +EXPORT_SYMBOL_GPL(nf_conntrack_qca8k_init);
308 +void nf_conntrack_qca8k_fini(void)
310 + nf_ct_extend_unregister(&qca8k_extend);
312 +EXPORT_SYMBOL_GPL(nf_conntrack_qca8k_fini);
314 +MODULE_DESCRIPTION("Qualcomm switch offloading driver");
315 +MODULE_AUTHOR("John Crispin <john@phrozen.org");
316 +MODULE_LICENSE("GPL v2");