Blame view

net/netfilter/nf_conntrack_core.c 50.2 KB
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1
2
3
4
5
  /* Connection state tracking for netfilter.  This is separated from,
     but required by, the NAT layer; it can also be used by an iptables
     extension. */
  
  /* (C) 1999-2001 Paul `Rusty' Russell
dc808fe28   Harald Welte   [NETFILTER] nf_co...
6
   * (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org>
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
7
   * (C) 2003,2004 USAGI/WIDE Project <http://www.linux-ipv6.org>
f229f6ce4   Patrick McHardy   netfilter: add my...
8
   * (C) 2005-2012 Patrick McHardy <kaber@trash.net>
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
9
10
11
12
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License version 2 as
   * published by the Free Software Foundation.
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
13
   */
ccd63c20f   Weongyo Jeong   netfilter: nf_con...
14
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
15
16
17
  #include <linux/types.h>
  #include <linux/netfilter.h>
  #include <linux/module.h>
d43c36dc6   Alexey Dobriyan   headers: remove s...
18
  #include <linux/sched.h>
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
19
20
21
22
23
24
25
26
27
28
29
30
31
32
  #include <linux/skbuff.h>
  #include <linux/proc_fs.h>
  #include <linux/vmalloc.h>
  #include <linux/stddef.h>
  #include <linux/slab.h>
  #include <linux/random.h>
  #include <linux/jhash.h>
  #include <linux/err.h>
  #include <linux/percpu.h>
  #include <linux/moduleparam.h>
  #include <linux/notifier.h>
  #include <linux/kernel.h>
  #include <linux/netdevice.h>
  #include <linux/socket.h>
d7fe0f241   Al Viro   [PATCH] severing ...
33
  #include <linux/mm.h>
d696c7bda   Patrick McHardy   netfilter: nf_con...
34
  #include <linux/nsproxy.h>
ea781f197   Eric Dumazet   netfilter: nf_con...
35
  #include <linux/rculist_nulls.h>
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
36

9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
37
38
  #include <net/netfilter/nf_conntrack.h>
  #include <net/netfilter/nf_conntrack_l3proto.h>
605dcad6c   Martin Josefsson   [NETFILTER]: nf_c...
39
  #include <net/netfilter/nf_conntrack_l4proto.h>
77ab9cff0   Martin Josefsson   [NETFILTER]: nf_c...
40
  #include <net/netfilter/nf_conntrack_expect.h>
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
41
  #include <net/netfilter/nf_conntrack_helper.h>
41d73ec05   Patrick McHardy   netfilter: nf_con...
42
  #include <net/netfilter/nf_conntrack_seqadj.h>
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
43
  #include <net/netfilter/nf_conntrack_core.h>
ecfab2c9f   Yasuyuki Kozakai   [NETFILTER]: nf_c...
44
  #include <net/netfilter/nf_conntrack_extend.h>
584015727   Krzysztof Piotr Oledzki   netfilter: accoun...
45
  #include <net/netfilter/nf_conntrack_acct.h>
a0891aa6a   Pablo Neira Ayuso   netfilter: conntr...
46
  #include <net/netfilter/nf_conntrack_ecache.h>
5d0aa2ccd   Patrick McHardy   netfilter: nf_con...
47
  #include <net/netfilter/nf_conntrack_zones.h>
a992ca2a0   Pablo Neira Ayuso   netfilter: nf_con...
48
  #include <net/netfilter/nf_conntrack_timestamp.h>
dd7050724   Pablo Neira Ayuso   netfilter: nf_ct_...
49
  #include <net/netfilter/nf_conntrack_timeout.h>
c539f0171   Florian Westphal   netfilter: add co...
50
  #include <net/netfilter/nf_conntrack_labels.h>
48b1de4c1   Patrick McHardy   netfilter: add SY...
51
  #include <net/netfilter/nf_conntrack_synproxy.h>
e6a7d3c04   Pablo Neira Ayuso   netfilter: ctnetl...
52
  #include <net/netfilter/nf_nat.h>
e17b666a4   Patrick McHardy   netfilter: nf_con...
53
  #include <net/netfilter/nf_nat_core.h>
493763684   stephen hemminger   netfilter: nf_con...
54
  #include <net/netfilter/nf_nat_helper.h>
1b8c8a9f6   Florian Westphal   netfilter: conntr...
55
  #include <net/netns/hash.h>
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
56

dc808fe28   Harald Welte   [NETFILTER] nf_co...
57
  #define NF_CONNTRACK_VERSION	"0.5.0"
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
58

e17b666a4   Patrick McHardy   netfilter: nf_con...
59
60
  int (*nfnetlink_parse_nat_setup_hook)(struct nf_conn *ct,
  				      enum nf_nat_manip_type manip,
399383246   Patrick McHardy   netfilter: nfnetl...
61
  				      const struct nlattr *attr) __read_mostly;
e6a7d3c04   Pablo Neira Ayuso   netfilter: ctnetl...
62
  EXPORT_SYMBOL_GPL(nfnetlink_parse_nat_setup_hook);
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
63
64
  __cacheline_aligned_in_smp spinlock_t nf_conntrack_locks[CONNTRACK_LOCKS];
  EXPORT_SYMBOL_GPL(nf_conntrack_locks);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
65

ca7433df3   Jesper Dangaard Brouer   netfilter: conntr...
66
67
  __cacheline_aligned_in_smp DEFINE_SPINLOCK(nf_conntrack_expect_lock);
  EXPORT_SYMBOL_GPL(nf_conntrack_expect_lock);
56d52d489   Florian Westphal   netfilter: conntr...
68
69
  struct hlist_nulls_head *nf_conntrack_hash __read_mostly;
  EXPORT_SYMBOL_GPL(nf_conntrack_hash);
0c5366b3a   Florian Westphal   netfilter: conntr...
70
  static __read_mostly struct kmem_cache *nf_conntrack_cachep;
b16c29191   Sasha Levin   netfilter: nf_con...
71
  static __read_mostly spinlock_t nf_conntrack_locks_all_lock;
a3efd8120   Florian Westphal   netfilter: conntr...
72
  static __read_mostly seqcount_t nf_conntrack_generation;
70d72b7e0   Florian Westphal   netfilter: conntr...
73
  static __read_mostly DEFINE_SPINLOCK(nf_conntrack_locks_all_lock);
b16c29191   Sasha Levin   netfilter: nf_con...
74
75
76
77
78
79
80
  static __read_mostly bool nf_conntrack_locks_all;
  
  void nf_conntrack_lock(spinlock_t *lock) __acquires(lock)
  {
  	spin_lock(lock);
  	while (unlikely(nf_conntrack_locks_all)) {
  		spin_unlock(lock);
e39365be0   Nicholas Mc Guire   netfilter: nf_con...
81
  		spin_unlock_wait(&nf_conntrack_locks_all_lock);
b16c29191   Sasha Levin   netfilter: nf_con...
82
83
84
85
  		spin_lock(lock);
  	}
  }
  EXPORT_SYMBOL_GPL(nf_conntrack_lock);
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
  static void nf_conntrack_double_unlock(unsigned int h1, unsigned int h2)
  {
  	h1 %= CONNTRACK_LOCKS;
  	h2 %= CONNTRACK_LOCKS;
  	spin_unlock(&nf_conntrack_locks[h1]);
  	if (h1 != h2)
  		spin_unlock(&nf_conntrack_locks[h2]);
  }
  
  /* return true if we need to recompute hashes (in case hash table was resized) */
  static bool nf_conntrack_double_lock(struct net *net, unsigned int h1,
  				     unsigned int h2, unsigned int sequence)
  {
  	h1 %= CONNTRACK_LOCKS;
  	h2 %= CONNTRACK_LOCKS;
  	if (h1 <= h2) {
b16c29191   Sasha Levin   netfilter: nf_con...
102
  		nf_conntrack_lock(&nf_conntrack_locks[h1]);
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
103
104
105
106
  		if (h1 != h2)
  			spin_lock_nested(&nf_conntrack_locks[h2],
  					 SINGLE_DEPTH_NESTING);
  	} else {
b16c29191   Sasha Levin   netfilter: nf_con...
107
  		nf_conntrack_lock(&nf_conntrack_locks[h2]);
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
108
109
110
  		spin_lock_nested(&nf_conntrack_locks[h1],
  				 SINGLE_DEPTH_NESTING);
  	}
a3efd8120   Florian Westphal   netfilter: conntr...
111
  	if (read_seqcount_retry(&nf_conntrack_generation, sequence)) {
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
112
113
114
115
116
117
118
119
120
  		nf_conntrack_double_unlock(h1, h2);
  		return true;
  	}
  	return false;
  }
  
  static void nf_conntrack_all_lock(void)
  {
  	int i;
b16c29191   Sasha Levin   netfilter: nf_con...
121
122
123
124
  	spin_lock(&nf_conntrack_locks_all_lock);
  	nf_conntrack_locks_all = true;
  
  	for (i = 0; i < CONNTRACK_LOCKS; i++) {
e39365be0   Nicholas Mc Guire   netfilter: nf_con...
125
  		spin_unlock_wait(&nf_conntrack_locks[i]);
b16c29191   Sasha Levin   netfilter: nf_con...
126
  	}
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
127
128
129
130
  }
  
  static void nf_conntrack_all_unlock(void)
  {
b16c29191   Sasha Levin   netfilter: nf_con...
131
132
  	nf_conntrack_locks_all = false;
  	spin_unlock(&nf_conntrack_locks_all_lock);
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
133
  }
e2b7606cd   Martin Josefsson   [NETFILTER]: More...
134
  unsigned int nf_conntrack_htable_size __read_mostly;
13b183391   Patrick McHardy   [NETFILTER]: nf_c...
135
  EXPORT_SYMBOL_GPL(nf_conntrack_htable_size);
e478075c6   Hagen Paul Pfeifer   netfilter: nf_con...
136
  unsigned int nf_conntrack_max __read_mostly;
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
137
  EXPORT_SYMBOL_GPL(nf_conntrack_max);
13b183391   Patrick McHardy   [NETFILTER]: nf_c...
138

b3c5163fe   Eric Dumazet   netfilter: nf_con...
139
140
  DEFINE_PER_CPU(struct nf_conn, nf_conntrack_untracked);
  EXPORT_PER_CPU_SYMBOL(nf_conntrack_untracked);
13b183391   Patrick McHardy   [NETFILTER]: nf_c...
141

141658fb0   Florian Westphal   netfilter: conntr...
142
  static unsigned int nf_conntrack_hash_rnd __read_mostly;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
143

1b8c8a9f6   Florian Westphal   netfilter: conntr...
144
145
  static u32 hash_conntrack_raw(const struct nf_conntrack_tuple *tuple,
  			      const struct net *net)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
146
  {
0794935e2   Patrick McHardy   [NETFILTER]: nf_c...
147
  	unsigned int n;
1b8c8a9f6   Florian Westphal   netfilter: conntr...
148
  	u32 seed;
0794935e2   Patrick McHardy   [NETFILTER]: nf_c...
149

141658fb0   Florian Westphal   netfilter: conntr...
150
  	get_random_once(&nf_conntrack_hash_rnd, sizeof(nf_conntrack_hash_rnd));
0794935e2   Patrick McHardy   [NETFILTER]: nf_c...
151
152
153
154
  	/* The direction must be ignored, so we hash everything up to the
  	 * destination ports (which is a multiple of 4) and treat the last
  	 * three bytes manually.
  	 */
1b8c8a9f6   Florian Westphal   netfilter: conntr...
155
  	seed = nf_conntrack_hash_rnd ^ net_hash_mix(net);
0794935e2   Patrick McHardy   [NETFILTER]: nf_c...
156
  	n = (sizeof(tuple->src) + sizeof(tuple->dst.u3)) / sizeof(u32);
1b8c8a9f6   Florian Westphal   netfilter: conntr...
157
  	return jhash2((u32 *)tuple, n, seed ^
99f07e91b   Changli Gao   netfilter: save t...
158
159
160
  		      (((__force __u16)tuple->dst.u.all << 16) |
  		      tuple->dst.protonum));
  }
56d52d489   Florian Westphal   netfilter: conntr...
161
  static u32 scale_hash(u32 hash)
99f07e91b   Changli Gao   netfilter: save t...
162
  {
56d52d489   Florian Westphal   netfilter: conntr...
163
  	return reciprocal_scale(hash, nf_conntrack_htable_size);
99f07e91b   Changli Gao   netfilter: save t...
164
  }
0794935e2   Patrick McHardy   [NETFILTER]: nf_c...
165

1b8c8a9f6   Florian Westphal   netfilter: conntr...
166
167
168
  static u32 __hash_conntrack(const struct net *net,
  			    const struct nf_conntrack_tuple *tuple,
  			    unsigned int size)
99f07e91b   Changli Gao   netfilter: save t...
169
  {
1b8c8a9f6   Florian Westphal   netfilter: conntr...
170
  	return reciprocal_scale(hash_conntrack_raw(tuple, net), size);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
171
  }
1b8c8a9f6   Florian Westphal   netfilter: conntr...
172
173
  static u32 hash_conntrack(const struct net *net,
  			  const struct nf_conntrack_tuple *tuple)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
174
  {
56d52d489   Florian Westphal   netfilter: conntr...
175
  	return scale_hash(hash_conntrack_raw(tuple, net));
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
176
  }
5f2b4c900   Jan Engelhardt   [NETFILTER]: nf_c...
177
  bool
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
178
179
180
181
182
  nf_ct_get_tuple(const struct sk_buff *skb,
  		unsigned int nhoff,
  		unsigned int dataoff,
  		u_int16_t l3num,
  		u_int8_t protonum,
a31f1adc0   Eric W. Biederman   netfilter: nf_con...
183
  		struct net *net,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
184
185
  		struct nf_conntrack_tuple *tuple,
  		const struct nf_conntrack_l3proto *l3proto,
605dcad6c   Martin Josefsson   [NETFILTER]: nf_c...
186
  		const struct nf_conntrack_l4proto *l4proto)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
187
  {
443a70d50   Philip Craig   netfilter: nf_con...
188
  	memset(tuple, 0, sizeof(*tuple));
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
189
190
191
  
  	tuple->src.l3num = l3num;
  	if (l3proto->pkt_to_tuple(skb, nhoff, tuple) == 0)
5f2b4c900   Jan Engelhardt   [NETFILTER]: nf_c...
192
  		return false;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
193
194
195
  
  	tuple->dst.protonum = protonum;
  	tuple->dst.dir = IP_CT_DIR_ORIGINAL;
a31f1adc0   Eric W. Biederman   netfilter: nf_con...
196
  	return l4proto->pkt_to_tuple(skb, dataoff, net, tuple);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
197
  }
13b183391   Patrick McHardy   [NETFILTER]: nf_c...
198
  EXPORT_SYMBOL_GPL(nf_ct_get_tuple);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
199

5f2b4c900   Jan Engelhardt   [NETFILTER]: nf_c...
200
  bool nf_ct_get_tuplepr(const struct sk_buff *skb, unsigned int nhoff,
a31f1adc0   Eric W. Biederman   netfilter: nf_con...
201
202
  		       u_int16_t l3num,
  		       struct net *net, struct nf_conntrack_tuple *tuple)
e2a3123fb   Yasuyuki Kozakai   [NETFILTER]: nf_c...
203
204
205
206
207
208
209
210
211
212
213
214
215
  {
  	struct nf_conntrack_l3proto *l3proto;
  	struct nf_conntrack_l4proto *l4proto;
  	unsigned int protoff;
  	u_int8_t protonum;
  	int ret;
  
  	rcu_read_lock();
  
  	l3proto = __nf_ct_l3proto_find(l3num);
  	ret = l3proto->get_l4proto(skb, nhoff, &protoff, &protonum);
  	if (ret != NF_ACCEPT) {
  		rcu_read_unlock();
5f2b4c900   Jan Engelhardt   [NETFILTER]: nf_c...
216
  		return false;
e2a3123fb   Yasuyuki Kozakai   [NETFILTER]: nf_c...
217
218
219
  	}
  
  	l4proto = __nf_ct_l4proto_find(l3num, protonum);
a31f1adc0   Eric W. Biederman   netfilter: nf_con...
220
  	ret = nf_ct_get_tuple(skb, nhoff, protoff, l3num, protonum, net, tuple,
e2a3123fb   Yasuyuki Kozakai   [NETFILTER]: nf_c...
221
222
223
224
225
226
  			      l3proto, l4proto);
  
  	rcu_read_unlock();
  	return ret;
  }
  EXPORT_SYMBOL_GPL(nf_ct_get_tuplepr);
5f2b4c900   Jan Engelhardt   [NETFILTER]: nf_c...
227
  bool
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
228
229
230
  nf_ct_invert_tuple(struct nf_conntrack_tuple *inverse,
  		   const struct nf_conntrack_tuple *orig,
  		   const struct nf_conntrack_l3proto *l3proto,
605dcad6c   Martin Josefsson   [NETFILTER]: nf_c...
231
  		   const struct nf_conntrack_l4proto *l4proto)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
232
  {
443a70d50   Philip Craig   netfilter: nf_con...
233
  	memset(inverse, 0, sizeof(*inverse));
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
234
235
236
  
  	inverse->src.l3num = orig->src.l3num;
  	if (l3proto->invert_tuple(inverse, orig) == 0)
5f2b4c900   Jan Engelhardt   [NETFILTER]: nf_c...
237
  		return false;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
238
239
240
241
  
  	inverse->dst.dir = !orig->dst.dir;
  
  	inverse->dst.protonum = orig->dst.protonum;
605dcad6c   Martin Josefsson   [NETFILTER]: nf_c...
242
  	return l4proto->invert_tuple(inverse, orig);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
243
  }
13b183391   Patrick McHardy   [NETFILTER]: nf_c...
244
  EXPORT_SYMBOL_GPL(nf_ct_invert_tuple);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
245

9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
246
247
248
  static void
  clean_from_lists(struct nf_conn *ct)
  {
0d53778e8   Patrick McHardy   [NETFILTER]: Conv...
249
250
  	pr_debug("clean_from_lists(%p)
  ", ct);
ea781f197   Eric Dumazet   netfilter: nf_con...
251
252
  	hlist_nulls_del_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode);
  	hlist_nulls_del_rcu(&ct->tuplehash[IP_CT_DIR_REPLY].hnnode);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
253
254
  
  	/* Destroy all pending expectations */
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
255
  	nf_ct_remove_expectations(ct);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
256
  }
b7779d06f   Jesper Dangaard Brouer   netfilter: conntr...
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
  /* must be called with local_bh_disable */
  static void nf_ct_add_to_dying_list(struct nf_conn *ct)
  {
  	struct ct_pcpu *pcpu;
  
  	/* add this conntrack to the (per cpu) dying list */
  	ct->cpu = smp_processor_id();
  	pcpu = per_cpu_ptr(nf_ct_net(ct)->ct.pcpu_lists, ct->cpu);
  
  	spin_lock(&pcpu->lock);
  	hlist_nulls_add_head(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode,
  			     &pcpu->dying);
  	spin_unlock(&pcpu->lock);
  }
  
  /* must be called with local_bh_disable */
  static void nf_ct_add_to_unconfirmed_list(struct nf_conn *ct)
  {
  	struct ct_pcpu *pcpu;
  
  	/* add this conntrack to the (per cpu) unconfirmed list */
  	ct->cpu = smp_processor_id();
  	pcpu = per_cpu_ptr(nf_ct_net(ct)->ct.pcpu_lists, ct->cpu);
  
  	spin_lock(&pcpu->lock);
  	hlist_nulls_add_head(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode,
  			     &pcpu->unconfirmed);
  	spin_unlock(&pcpu->lock);
  }
  
  /* must be called with local_bh_disable */
  static void nf_ct_del_from_dying_or_unconfirmed_list(struct nf_conn *ct)
  {
  	struct ct_pcpu *pcpu;
  
  	/* We overload first tuple to link into unconfirmed or dying list.*/
  	pcpu = per_cpu_ptr(nf_ct_net(ct)->ct.pcpu_lists, ct->cpu);
  
  	spin_lock(&pcpu->lock);
  	BUG_ON(hlist_nulls_unhashed(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode));
  	hlist_nulls_del_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode);
  	spin_unlock(&pcpu->lock);
  }
0838aa7fc   Pablo Neira Ayuso   netfilter: fix ne...
300
  /* Released via destroy_conntrack() */
308ac9143   Daniel Borkmann   netfilter: nf_con...
301
302
303
  struct nf_conn *nf_ct_tmpl_alloc(struct net *net,
  				 const struct nf_conntrack_zone *zone,
  				 gfp_t flags)
0838aa7fc   Pablo Neira Ayuso   netfilter: fix ne...
304
305
  {
  	struct nf_conn *tmpl;
f58e5aa7b   Joe Stringer   netfilter: conntr...
306
  	tmpl = kzalloc(sizeof(*tmpl), flags);
0838aa7fc   Pablo Neira Ayuso   netfilter: fix ne...
307
308
309
310
311
  	if (tmpl == NULL)
  		return NULL;
  
  	tmpl->status = IPS_TEMPLATE;
  	write_pnet(&tmpl->ct_net, net);
6c8dee984   Florian Westphal   netfilter: move z...
312
  	nf_ct_zone_add(tmpl, zone);
0838aa7fc   Pablo Neira Ayuso   netfilter: fix ne...
313
314
315
  	atomic_set(&tmpl->ct_general.use, 0);
  
  	return tmpl;
0838aa7fc   Pablo Neira Ayuso   netfilter: fix ne...
316
317
  }
  EXPORT_SYMBOL_GPL(nf_ct_tmpl_alloc);
9cf94eab8   Daniel Borkmann   netfilter: conntr...
318
  void nf_ct_tmpl_free(struct nf_conn *tmpl)
0838aa7fc   Pablo Neira Ayuso   netfilter: fix ne...
319
320
321
322
323
  {
  	nf_ct_ext_destroy(tmpl);
  	nf_ct_ext_free(tmpl);
  	kfree(tmpl);
  }
9cf94eab8   Daniel Borkmann   netfilter: conntr...
324
  EXPORT_SYMBOL_GPL(nf_ct_tmpl_free);
0838aa7fc   Pablo Neira Ayuso   netfilter: fix ne...
325

9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
326
327
328
329
  static void
  destroy_conntrack(struct nf_conntrack *nfct)
  {
  	struct nf_conn *ct = (struct nf_conn *)nfct;
0d55af879   Alexey Dobriyan   netfilter: netns ...
330
  	struct net *net = nf_ct_net(ct);
605dcad6c   Martin Josefsson   [NETFILTER]: nf_c...
331
  	struct nf_conntrack_l4proto *l4proto;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
332

0d53778e8   Patrick McHardy   [NETFILTER]: Conv...
333
334
  	pr_debug("destroy_conntrack(%p)
  ", ct);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
335
336
  	NF_CT_ASSERT(atomic_read(&nfct->use) == 0);
  	NF_CT_ASSERT(!timer_pending(&ct->timeout));
0838aa7fc   Pablo Neira Ayuso   netfilter: fix ne...
337
338
339
340
  	if (unlikely(nf_ct_is_template(ct))) {
  		nf_ct_tmpl_free(ct);
  		return;
  	}
923f4902f   Patrick McHardy   [NETFILTER]: nf_c...
341
  	rcu_read_lock();
5e8fbe2ac   Patrick McHardy   [NETFILTER]: nf_c...
342
  	l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct));
4b4ceb9db   Pablo Neira Ayuso   netfilter: conntr...
343
  	if (l4proto->destroy)
605dcad6c   Martin Josefsson   [NETFILTER]: nf_c...
344
  		l4proto->destroy(ct);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
345

982d9a9ce   Patrick McHardy   [NETFILTER]: nf_c...
346
  	rcu_read_unlock();
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
347

ca7433df3   Jesper Dangaard Brouer   netfilter: conntr...
348
  	local_bh_disable();
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
349
350
351
  	/* Expectations will have been removed in clean_from_lists,
  	 * except TFTP can create an expectation on the first packet,
  	 * before connection is in the list, so we need to clean here,
ca7433df3   Jesper Dangaard Brouer   netfilter: conntr...
352
353
  	 * too.
  	 */
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
354
  	nf_ct_remove_expectations(ct);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
355

b7779d06f   Jesper Dangaard Brouer   netfilter: conntr...
356
  	nf_ct_del_from_dying_or_unconfirmed_list(ct);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
357

0d55af879   Alexey Dobriyan   netfilter: netns ...
358
  	NF_CT_STAT_INC(net, delete);
ca7433df3   Jesper Dangaard Brouer   netfilter: conntr...
359
  	local_bh_enable();
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
360
361
362
  
  	if (ct->master)
  		nf_ct_put(ct->master);
0d53778e8   Patrick McHardy   [NETFILTER]: Conv...
363
364
  	pr_debug("destroy_conntrack: returning ct=%p to slab
  ", ct);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
365
366
  	nf_conntrack_free(ct);
  }
02982c27b   Florian Westphal   netfilter: nf_con...
367
  static void nf_ct_delete_from_lists(struct nf_conn *ct)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
368
  {
0d55af879   Alexey Dobriyan   netfilter: netns ...
369
  	struct net *net = nf_ct_net(ct);
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
370
  	unsigned int hash, reply_hash;
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
371
  	unsigned int sequence;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
372

9858a3ae1   Pablo Neira Ayuso   netfilter: conntr...
373
  	nf_ct_helper_destroy(ct);
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
374
375
376
  
  	local_bh_disable();
  	do {
a3efd8120   Florian Westphal   netfilter: conntr...
377
  		sequence = read_seqcount_begin(&nf_conntrack_generation);
deedb5903   Daniel Borkmann   netfilter: nf_con...
378
  		hash = hash_conntrack(net,
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
379
  				      &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
deedb5903   Daniel Borkmann   netfilter: nf_con...
380
  		reply_hash = hash_conntrack(net,
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
381
382
  					   &ct->tuplehash[IP_CT_DIR_REPLY].tuple);
  	} while (nf_conntrack_double_lock(net, hash, reply_hash, sequence));
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
383
  	clean_from_lists(ct);
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
384
  	nf_conntrack_double_unlock(hash, reply_hash);
b7779d06f   Jesper Dangaard Brouer   netfilter: conntr...
385
  	nf_ct_add_to_dying_list(ct);
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
386
387
388
  
  	NF_CT_STAT_INC(net, delete_list);
  	local_bh_enable();
dd7669a92   Pablo Neira Ayuso   netfilter: conntr...
389
  }
dd7669a92   Pablo Neira Ayuso   netfilter: conntr...
390

02982c27b   Florian Westphal   netfilter: nf_con...
391
  bool nf_ct_delete(struct nf_conn *ct, u32 portid, int report)
dd7669a92   Pablo Neira Ayuso   netfilter: conntr...
392
  {
a992ca2a0   Pablo Neira Ayuso   netfilter: nf_con...
393
394
395
396
  	struct nf_conn_tstamp *tstamp;
  
  	tstamp = nf_conn_tstamp_find(ct);
  	if (tstamp && tstamp->stop == 0)
d2de875c6   Eric Dumazet   net: use ktime_ge...
397
  		tstamp->stop = ktime_get_real_ns();
dd7669a92   Pablo Neira Ayuso   netfilter: conntr...
398

9500507c6   Florian Westphal   netfilter: conntr...
399
400
401
402
403
  	if (nf_ct_is_dying(ct))
  		goto delete;
  
  	if (nf_conntrack_event_report(IPCT_DESTROY, ct,
  				    portid, report) < 0) {
dd7669a92   Pablo Neira Ayuso   netfilter: conntr...
404
405
  		/* destroy event was not delivered */
  		nf_ct_delete_from_lists(ct);
9500507c6   Florian Westphal   netfilter: conntr...
406
  		nf_conntrack_ecache_delayed_work(nf_ct_net(ct));
02982c27b   Florian Westphal   netfilter: nf_con...
407
  		return false;
dd7669a92   Pablo Neira Ayuso   netfilter: conntr...
408
  	}
9500507c6   Florian Westphal   netfilter: conntr...
409
410
  
  	nf_conntrack_ecache_work(nf_ct_net(ct));
dd7669a92   Pablo Neira Ayuso   netfilter: conntr...
411
  	set_bit(IPS_DYING_BIT, &ct->status);
9500507c6   Florian Westphal   netfilter: conntr...
412
   delete:
dd7669a92   Pablo Neira Ayuso   netfilter: conntr...
413
  	nf_ct_delete_from_lists(ct);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
414
  	nf_ct_put(ct);
02982c27b   Florian Westphal   netfilter: nf_con...
415
416
417
418
419
420
421
  	return true;
  }
  EXPORT_SYMBOL_GPL(nf_ct_delete);
  
  static void death_by_timeout(unsigned long ul_conntrack)
  {
  	nf_ct_delete((struct nf_conn *)ul_conntrack, 0, 0);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
422
  }
c6825c097   Andrey Vagin   netfilter: nf_con...
423
424
  static inline bool
  nf_ct_key_equal(struct nf_conntrack_tuple_hash *h,
308ac9143   Daniel Borkmann   netfilter: nf_con...
425
  		const struct nf_conntrack_tuple *tuple,
e0c7d4722   Florian Westphal   netfilter: conntr...
426
427
  		const struct nf_conntrack_zone *zone,
  		const struct net *net)
c6825c097   Andrey Vagin   netfilter: nf_con...
428
429
430
431
432
433
434
  {
  	struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h);
  
  	/* A conntrack can be recreated with the equal tuple,
  	 * so we need to check that the conntrack is confirmed
  	 */
  	return nf_ct_tuple_equal(tuple, &h->tuple) &&
deedb5903   Daniel Borkmann   netfilter: nf_con...
435
  	       nf_ct_zone_equal(ct, zone, NF_CT_DIRECTION(h)) &&
e0c7d4722   Florian Westphal   netfilter: conntr...
436
437
  	       nf_ct_is_confirmed(ct) &&
  	       net_eq(net, nf_ct_net(ct));
c6825c097   Andrey Vagin   netfilter: nf_con...
438
  }
64b87639c   Liping Zhang   netfilter: conntr...
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
  /* must be called with rcu read lock held */
  void nf_conntrack_get_ht(struct hlist_nulls_head **hash, unsigned int *hsize)
  {
  	struct hlist_nulls_head *hptr;
  	unsigned int sequence, hsz;
  
  	do {
  		sequence = read_seqcount_begin(&nf_conntrack_generation);
  		hsz = nf_conntrack_htable_size;
  		hptr = nf_conntrack_hash;
  	} while (read_seqcount_retry(&nf_conntrack_generation, sequence));
  
  	*hash = hptr;
  	*hsize = hsz;
  }
  EXPORT_SYMBOL_GPL(nf_conntrack_get_ht);
ea781f197   Eric Dumazet   netfilter: nf_con...
455
456
457
458
  /*
   * Warning :
   * - Caller must take a reference on returned object
   *   and recheck nf_ct_tuple_equal(tuple, &h->tuple)
ea781f197   Eric Dumazet   netfilter: nf_con...
459
   */
99f07e91b   Changli Gao   netfilter: save t...
460
  static struct nf_conntrack_tuple_hash *
308ac9143   Daniel Borkmann   netfilter: nf_con...
461
  ____nf_conntrack_find(struct net *net, const struct nf_conntrack_zone *zone,
99f07e91b   Changli Gao   netfilter: save t...
462
  		      const struct nf_conntrack_tuple *tuple, u32 hash)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
463
464
  {
  	struct nf_conntrack_tuple_hash *h;
5e3c61f98   Florian Westphal   netfilter: conntr...
465
  	struct hlist_nulls_head *ct_hash;
ea781f197   Eric Dumazet   netfilter: nf_con...
466
  	struct hlist_nulls_node *n;
5e3c61f98   Florian Westphal   netfilter: conntr...
467
  	unsigned int bucket, sequence;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
468

ea781f197   Eric Dumazet   netfilter: nf_con...
469
  begin:
5e3c61f98   Florian Westphal   netfilter: conntr...
470
471
  	do {
  		sequence = read_seqcount_begin(&nf_conntrack_generation);
56d52d489   Florian Westphal   netfilter: conntr...
472
473
  		bucket = scale_hash(hash);
  		ct_hash = nf_conntrack_hash;
5e3c61f98   Florian Westphal   netfilter: conntr...
474
475
476
  	} while (read_seqcount_retry(&nf_conntrack_generation, sequence));
  
  	hlist_nulls_for_each_entry_rcu(h, n, &ct_hash[bucket], hnnode) {
e0c7d4722   Florian Westphal   netfilter: conntr...
477
  		if (nf_ct_key_equal(h, tuple, zone, net)) {
2cf123480   Florian Westphal   netfilter: conntr...
478
  			NF_CT_STAT_INC_ATOMIC(net, found);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
479
480
  			return h;
  		}
2cf123480   Florian Westphal   netfilter: conntr...
481
  		NF_CT_STAT_INC_ATOMIC(net, searched);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
482
  	}
ea781f197   Eric Dumazet   netfilter: nf_con...
483
484
485
486
487
  	/*
  	 * if the nulls value we got at the end of this lookup is
  	 * not the expected one, we must restart lookup.
  	 * We probably met an item that was moved to another chain.
  	 */
99f07e91b   Changli Gao   netfilter: save t...
488
  	if (get_nulls_value(n) != bucket) {
2cf123480   Florian Westphal   netfilter: conntr...
489
  		NF_CT_STAT_INC_ATOMIC(net, search_restart);
ea781f197   Eric Dumazet   netfilter: nf_con...
490
  		goto begin;
af740b2c8   Jesper Dangaard Brouer   netfilter: nf_con...
491
  	}
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
492
493
494
  
  	return NULL;
  }
99f07e91b   Changli Gao   netfilter: save t...
495

9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
496
  /* Find a connection corresponding to a tuple. */
99f07e91b   Changli Gao   netfilter: save t...
497
  static struct nf_conntrack_tuple_hash *
308ac9143   Daniel Borkmann   netfilter: nf_con...
498
  __nf_conntrack_find_get(struct net *net, const struct nf_conntrack_zone *zone,
99f07e91b   Changli Gao   netfilter: save t...
499
  			const struct nf_conntrack_tuple *tuple, u32 hash)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
500
501
  {
  	struct nf_conntrack_tuple_hash *h;
76507f69c   Patrick McHardy   [NETFILTER]: nf_c...
502
  	struct nf_conn *ct;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
503

76507f69c   Patrick McHardy   [NETFILTER]: nf_c...
504
  	rcu_read_lock();
ea781f197   Eric Dumazet   netfilter: nf_con...
505
  begin:
99f07e91b   Changli Gao   netfilter: save t...
506
  	h = ____nf_conntrack_find(net, zone, tuple, hash);
76507f69c   Patrick McHardy   [NETFILTER]: nf_c...
507
508
  	if (h) {
  		ct = nf_ct_tuplehash_to_ctrack(h);
8d8890b77   Patrick McHardy   netfilter: nf_con...
509
510
  		if (unlikely(nf_ct_is_dying(ct) ||
  			     !atomic_inc_not_zero(&ct->ct_general.use)))
76507f69c   Patrick McHardy   [NETFILTER]: nf_c...
511
  			h = NULL;
ea781f197   Eric Dumazet   netfilter: nf_con...
512
  		else {
e0c7d4722   Florian Westphal   netfilter: conntr...
513
  			if (unlikely(!nf_ct_key_equal(h, tuple, zone, net))) {
ea781f197   Eric Dumazet   netfilter: nf_con...
514
515
516
517
  				nf_ct_put(ct);
  				goto begin;
  			}
  		}
76507f69c   Patrick McHardy   [NETFILTER]: nf_c...
518
519
  	}
  	rcu_read_unlock();
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
520
521
522
  
  	return h;
  }
99f07e91b   Changli Gao   netfilter: save t...
523
524
  
  struct nf_conntrack_tuple_hash *
308ac9143   Daniel Borkmann   netfilter: nf_con...
525
  nf_conntrack_find_get(struct net *net, const struct nf_conntrack_zone *zone,
99f07e91b   Changli Gao   netfilter: save t...
526
527
528
  		      const struct nf_conntrack_tuple *tuple)
  {
  	return __nf_conntrack_find_get(net, zone, tuple,
1b8c8a9f6   Florian Westphal   netfilter: conntr...
529
  				       hash_conntrack_raw(tuple, net));
99f07e91b   Changli Gao   netfilter: save t...
530
  }
13b183391   Patrick McHardy   [NETFILTER]: nf_c...
531
  EXPORT_SYMBOL_GPL(nf_conntrack_find_get);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
532

c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
533
534
  static void __nf_conntrack_hash_insert(struct nf_conn *ct,
  				       unsigned int hash,
b476b72a0   Jesper Dangaard Brouer   netfilter: trivia...
535
  				       unsigned int reply_hash)
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
536
  {
ea781f197   Eric Dumazet   netfilter: nf_con...
537
  	hlist_nulls_add_head_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode,
56d52d489   Florian Westphal   netfilter: conntr...
538
  			   &nf_conntrack_hash[hash]);
ea781f197   Eric Dumazet   netfilter: nf_con...
539
  	hlist_nulls_add_head_rcu(&ct->tuplehash[IP_CT_DIR_REPLY].hnnode,
56d52d489   Florian Westphal   netfilter: conntr...
540
  			   &nf_conntrack_hash[reply_hash]);
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
541
  }
7d367e066   Jozsef Kadlecsik   netfilter: ctnetl...
542
543
  int
  nf_conntrack_hash_check_insert(struct nf_conn *ct)
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
544
  {
308ac9143   Daniel Borkmann   netfilter: nf_con...
545
  	const struct nf_conntrack_zone *zone;
d696c7bda   Patrick McHardy   netfilter: nf_con...
546
  	struct net *net = nf_ct_net(ct);
b476b72a0   Jesper Dangaard Brouer   netfilter: trivia...
547
  	unsigned int hash, reply_hash;
7d367e066   Jozsef Kadlecsik   netfilter: ctnetl...
548
549
  	struct nf_conntrack_tuple_hash *h;
  	struct hlist_nulls_node *n;
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
550
  	unsigned int sequence;
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
551

5d0aa2ccd   Patrick McHardy   netfilter: nf_con...
552
  	zone = nf_ct_zone(ct);
7d367e066   Jozsef Kadlecsik   netfilter: ctnetl...
553

93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
554
555
  	local_bh_disable();
  	do {
a3efd8120   Florian Westphal   netfilter: conntr...
556
  		sequence = read_seqcount_begin(&nf_conntrack_generation);
deedb5903   Daniel Borkmann   netfilter: nf_con...
557
  		hash = hash_conntrack(net,
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
558
  				      &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
deedb5903   Daniel Borkmann   netfilter: nf_con...
559
  		reply_hash = hash_conntrack(net,
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
560
561
  					   &ct->tuplehash[IP_CT_DIR_REPLY].tuple);
  	} while (nf_conntrack_double_lock(net, hash, reply_hash, sequence));
7d367e066   Jozsef Kadlecsik   netfilter: ctnetl...
562
563
  
  	/* See if there's one in the list already, including reverse */
56d52d489   Florian Westphal   netfilter: conntr...
564
  	hlist_nulls_for_each_entry(h, n, &nf_conntrack_hash[hash], hnnode)
868043485   Florian Westphal   netfilter: conntr...
565
  		if (nf_ct_key_equal(h, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
e0c7d4722   Florian Westphal   netfilter: conntr...
566
  				    zone, net))
7d367e066   Jozsef Kadlecsik   netfilter: ctnetl...
567
  			goto out;
868043485   Florian Westphal   netfilter: conntr...
568

56d52d489   Florian Westphal   netfilter: conntr...
569
  	hlist_nulls_for_each_entry(h, n, &nf_conntrack_hash[reply_hash], hnnode)
868043485   Florian Westphal   netfilter: conntr...
570
  		if (nf_ct_key_equal(h, &ct->tuplehash[IP_CT_DIR_REPLY].tuple,
e0c7d4722   Florian Westphal   netfilter: conntr...
571
  				    zone, net))
7d367e066   Jozsef Kadlecsik   netfilter: ctnetl...
572
  			goto out;
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
573

7d367e066   Jozsef Kadlecsik   netfilter: ctnetl...
574
  	add_timer(&ct->timeout);
e53376bef   Pablo Neira Ayuso   netfilter: nf_con...
575
576
577
  	smp_wmb();
  	/* The caller holds a reference to this object */
  	atomic_set(&ct->ct_general.use, 2);
b476b72a0   Jesper Dangaard Brouer   netfilter: trivia...
578
  	__nf_conntrack_hash_insert(ct, hash, reply_hash);
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
579
  	nf_conntrack_double_unlock(hash, reply_hash);
7d367e066   Jozsef Kadlecsik   netfilter: ctnetl...
580
  	NF_CT_STAT_INC(net, insert);
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
581
  	local_bh_enable();
7d367e066   Jozsef Kadlecsik   netfilter: ctnetl...
582
583
584
  	return 0;
  
  out:
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
585
  	nf_conntrack_double_unlock(hash, reply_hash);
7d367e066   Jozsef Kadlecsik   netfilter: ctnetl...
586
  	NF_CT_STAT_INC(net, insert_failed);
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
587
  	local_bh_enable();
7d367e066   Jozsef Kadlecsik   netfilter: ctnetl...
588
  	return -EEXIST;
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
589
  }
7d367e066   Jozsef Kadlecsik   netfilter: ctnetl...
590
  EXPORT_SYMBOL_GPL(nf_conntrack_hash_check_insert);
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
591

ba76738c0   Pablo Neira Ayuso   netfilter: conntr...
592
593
594
595
596
597
598
599
600
601
602
603
604
605
  static inline void nf_ct_acct_update(struct nf_conn *ct,
  				     enum ip_conntrack_info ctinfo,
  				     unsigned int len)
  {
  	struct nf_conn_acct *acct;
  
  	acct = nf_conn_acct_find(ct);
  	if (acct) {
  		struct nf_conn_counter *counter = acct->counter;
  
  		atomic64_inc(&counter[CTINFO2DIR(ctinfo)].packets);
  		atomic64_add(len, &counter[CTINFO2DIR(ctinfo)].bytes);
  	}
  }
71d8c47fc   Pablo Neira Ayuso   netfilter: conntr...
606
607
608
609
610
611
612
613
  static void nf_ct_acct_merge(struct nf_conn *ct, enum ip_conntrack_info ctinfo,
  			     const struct nf_conn *loser_ct)
  {
  	struct nf_conn_acct *acct;
  
  	acct = nf_conn_acct_find(loser_ct);
  	if (acct) {
  		struct nf_conn_counter *counter = acct->counter;
71d8c47fc   Pablo Neira Ayuso   netfilter: conntr...
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
  		unsigned int bytes;
  
  		/* u32 should be fine since we must have seen one packet. */
  		bytes = atomic64_read(&counter[CTINFO2DIR(ctinfo)].bytes);
  		nf_ct_acct_update(ct, ctinfo, bytes);
  	}
  }
  
  /* Resolve race on insertion if this protocol allows this. */
  static int nf_ct_resolve_clash(struct net *net, struct sk_buff *skb,
  			       enum ip_conntrack_info ctinfo,
  			       struct nf_conntrack_tuple_hash *h)
  {
  	/* This is the conntrack entry already in hashes that won race. */
  	struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h);
  	struct nf_conntrack_l4proto *l4proto;
  
  	l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct));
  	if (l4proto->allow_clash &&
  	    !nf_ct_is_dying(ct) &&
  	    atomic_inc_not_zero(&ct->ct_general.use)) {
  		nf_ct_acct_merge(ct, ctinfo, (struct nf_conn *)skb->nfct);
  		nf_conntrack_put(skb->nfct);
  		/* Assign conntrack already in hashes to this skbuff. Don't
  		 * modify skb->nfctinfo to ensure consistent stateful filtering.
  		 */
  		skb->nfct = &ct->ct_general;
  		return NF_ACCEPT;
  	}
  	NF_CT_STAT_INC(net, drop);
  	return NF_DROP;
  }
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
646
647
  /* Confirm a connection given skb; places it in hash table */
  int
3db05fea5   Herbert Xu   [NETFILTER]: Repl...
648
  __nf_conntrack_confirm(struct sk_buff *skb)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
649
  {
308ac9143   Daniel Borkmann   netfilter: nf_con...
650
  	const struct nf_conntrack_zone *zone;
b476b72a0   Jesper Dangaard Brouer   netfilter: trivia...
651
  	unsigned int hash, reply_hash;
df0933dcb   Patrick McHardy   [NETFILTER]: kill...
652
  	struct nf_conntrack_tuple_hash *h;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
653
  	struct nf_conn *ct;
df0933dcb   Patrick McHardy   [NETFILTER]: kill...
654
  	struct nf_conn_help *help;
a992ca2a0   Pablo Neira Ayuso   netfilter: nf_con...
655
  	struct nf_conn_tstamp *tstamp;
ea781f197   Eric Dumazet   netfilter: nf_con...
656
  	struct hlist_nulls_node *n;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
657
  	enum ip_conntrack_info ctinfo;
400dad39d   Alexey Dobriyan   netfilter: netns ...
658
  	struct net *net;
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
659
  	unsigned int sequence;
71d8c47fc   Pablo Neira Ayuso   netfilter: conntr...
660
  	int ret = NF_DROP;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
661

3db05fea5   Herbert Xu   [NETFILTER]: Repl...
662
  	ct = nf_ct_get(skb, &ctinfo);
400dad39d   Alexey Dobriyan   netfilter: netns ...
663
  	net = nf_ct_net(ct);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
664
665
666
667
668
669
670
  
  	/* ipt_REJECT uses nf_conntrack_attach to attach related
  	   ICMP/TCP RST packets in other direction.  Actual packet
  	   which created connection will be IP_CT_NEW or for an
  	   expected connection, IP_CT_RELATED. */
  	if (CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL)
  		return NF_ACCEPT;
5d0aa2ccd   Patrick McHardy   netfilter: nf_con...
671
  	zone = nf_ct_zone(ct);
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
672
673
674
  	local_bh_disable();
  
  	do {
a3efd8120   Florian Westphal   netfilter: conntr...
675
  		sequence = read_seqcount_begin(&nf_conntrack_generation);
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
676
677
  		/* reuse the hash saved before */
  		hash = *(unsigned long *)&ct->tuplehash[IP_CT_DIR_REPLY].hnnode.pprev;
56d52d489   Florian Westphal   netfilter: conntr...
678
  		hash = scale_hash(hash);
deedb5903   Daniel Borkmann   netfilter: nf_con...
679
  		reply_hash = hash_conntrack(net,
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
680
681
682
  					   &ct->tuplehash[IP_CT_DIR_REPLY].tuple);
  
  	} while (nf_conntrack_double_lock(net, hash, reply_hash, sequence));
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
683
684
  
  	/* We're not in hash table, and we refuse to set up related
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
685
686
687
  	 * connections for unconfirmed conns.  But packet copies and
  	 * REJECT will give spurious warnings here.
  	 */
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
688
  	/* NF_CT_ASSERT(atomic_read(&ct->ct_general.use) == 1); */
25985edce   Lucas De Marchi   Fix common misspe...
689
  	/* No external references means no one else could have
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
690
691
  	 * confirmed us.
  	 */
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
692
  	NF_CT_ASSERT(!nf_ct_is_confirmed(ct));
0d53778e8   Patrick McHardy   [NETFILTER]: Conv...
693
694
  	pr_debug("Confirming conntrack %p
  ", ct);
8ca3f5e97   Pablo Neira Ayuso   netfilter: conntr...
695
696
697
698
699
700
  	/* We have to check the DYING flag after unlink to prevent
  	 * a race against nf_ct_get_next_corpse() possibly called from
  	 * user context, else we insert an already 'dead' hash, blocking
  	 * further use of that particular connection -JM.
  	 */
  	nf_ct_del_from_dying_or_unconfirmed_list(ct);
71d8c47fc   Pablo Neira Ayuso   netfilter: conntr...
701
702
703
704
  	if (unlikely(nf_ct_is_dying(ct))) {
  		nf_ct_add_to_dying_list(ct);
  		goto dying;
  	}
fc350777c   Joerg Marx   netfilter: nf_con...
705

9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
706
707
708
  	/* See if there's one in the list already, including reverse:
  	   NAT could have grabbed it without realizing, since we're
  	   not in the hash.  If there is, we lost race. */
56d52d489   Florian Westphal   netfilter: conntr...
709
  	hlist_nulls_for_each_entry(h, n, &nf_conntrack_hash[hash], hnnode)
868043485   Florian Westphal   netfilter: conntr...
710
  		if (nf_ct_key_equal(h, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
e0c7d4722   Florian Westphal   netfilter: conntr...
711
  				    zone, net))
df0933dcb   Patrick McHardy   [NETFILTER]: kill...
712
  			goto out;
868043485   Florian Westphal   netfilter: conntr...
713

56d52d489   Florian Westphal   netfilter: conntr...
714
  	hlist_nulls_for_each_entry(h, n, &nf_conntrack_hash[reply_hash], hnnode)
868043485   Florian Westphal   netfilter: conntr...
715
  		if (nf_ct_key_equal(h, &ct->tuplehash[IP_CT_DIR_REPLY].tuple,
e0c7d4722   Florian Westphal   netfilter: conntr...
716
  				    zone, net))
df0933dcb   Patrick McHardy   [NETFILTER]: kill...
717
  			goto out;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
718

df0933dcb   Patrick McHardy   [NETFILTER]: kill...
719
720
721
722
723
724
  	/* Timer relative to confirmation time, not original
  	   setting time, otherwise we'd get timer wrap in
  	   weird delay cases. */
  	ct->timeout.expires += jiffies;
  	add_timer(&ct->timeout);
  	atomic_inc(&ct->ct_general.use);
45eec3419   Changli Gao   netfilter: nf_con...
725
  	ct->status |= IPS_CONFIRMED;
5c8ec910e   Patrick McHardy   netfilter: nf_con...
726

a992ca2a0   Pablo Neira Ayuso   netfilter: nf_con...
727
728
729
730
  	/* set conntrack timestamp, if enabled. */
  	tstamp = nf_conn_tstamp_find(ct);
  	if (tstamp) {
  		if (skb->tstamp.tv64 == 0)
e3192690a   Joe Perches   net: Remove casts...
731
  			__net_timestamp(skb);
a992ca2a0   Pablo Neira Ayuso   netfilter: nf_con...
732
733
734
  
  		tstamp->start = ktime_to_ns(skb->tstamp);
  	}
5c8ec910e   Patrick McHardy   netfilter: nf_con...
735
736
737
738
739
  	/* Since the lookup is lockless, hash insertion must be done after
  	 * starting the timer and setting the CONFIRMED bit. The RCU barriers
  	 * guarantee that no other CPU can find the conntrack before the above
  	 * stores are visible.
  	 */
b476b72a0   Jesper Dangaard Brouer   netfilter: trivia...
740
  	__nf_conntrack_hash_insert(ct, hash, reply_hash);
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
741
  	nf_conntrack_double_unlock(hash, reply_hash);
0d55af879   Alexey Dobriyan   netfilter: netns ...
742
  	NF_CT_STAT_INC(net, insert);
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
743
  	local_bh_enable();
5c8ec910e   Patrick McHardy   netfilter: nf_con...
744

df0933dcb   Patrick McHardy   [NETFILTER]: kill...
745
746
  	help = nfct_help(ct);
  	if (help && help->helper)
a71996fcc   Alexey Dobriyan   netfilter: netns ...
747
  		nf_conntrack_event_cache(IPCT_HELPER, ct);
17e6e4eac   Pablo Neira Ayuso   netfilter: conntr...
748

df0933dcb   Patrick McHardy   [NETFILTER]: kill...
749
  	nf_conntrack_event_cache(master_ct(ct) ?
a71996fcc   Alexey Dobriyan   netfilter: netns ...
750
  				 IPCT_RELATED : IPCT_NEW, ct);
df0933dcb   Patrick McHardy   [NETFILTER]: kill...
751
  	return NF_ACCEPT;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
752

df0933dcb   Patrick McHardy   [NETFILTER]: kill...
753
  out:
8ca3f5e97   Pablo Neira Ayuso   netfilter: conntr...
754
  	nf_ct_add_to_dying_list(ct);
71d8c47fc   Pablo Neira Ayuso   netfilter: conntr...
755
756
  	ret = nf_ct_resolve_clash(net, skb, ctinfo, h);
  dying:
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
757
  	nf_conntrack_double_unlock(hash, reply_hash);
0d55af879   Alexey Dobriyan   netfilter: netns ...
758
  	NF_CT_STAT_INC(net, insert_failed);
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
759
  	local_bh_enable();
71d8c47fc   Pablo Neira Ayuso   netfilter: conntr...
760
  	return ret;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
761
  }
13b183391   Patrick McHardy   [NETFILTER]: nf_c...
762
  EXPORT_SYMBOL_GPL(__nf_conntrack_confirm);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
763
764
765
766
767
768
769
  
  /* Returns true if a connection correspondings to the tuple (required
     for NAT). */
  int
  nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple,
  			 const struct nf_conn *ignored_conntrack)
  {
400dad39d   Alexey Dobriyan   netfilter: netns ...
770
  	struct net *net = nf_ct_net(ignored_conntrack);
308ac9143   Daniel Borkmann   netfilter: nf_con...
771
  	const struct nf_conntrack_zone *zone;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
772
  	struct nf_conntrack_tuple_hash *h;
5e3c61f98   Florian Westphal   netfilter: conntr...
773
774
  	struct hlist_nulls_head *ct_hash;
  	unsigned int hash, sequence;
ea781f197   Eric Dumazet   netfilter: nf_con...
775
  	struct hlist_nulls_node *n;
5d0aa2ccd   Patrick McHardy   netfilter: nf_con...
776
  	struct nf_conn *ct;
308ac9143   Daniel Borkmann   netfilter: nf_con...
777
778
  
  	zone = nf_ct_zone(ignored_conntrack);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
779

2cf123480   Florian Westphal   netfilter: conntr...
780
  	rcu_read_lock();
5e3c61f98   Florian Westphal   netfilter: conntr...
781
782
783
  	do {
  		sequence = read_seqcount_begin(&nf_conntrack_generation);
  		hash = hash_conntrack(net, tuple);
56d52d489   Florian Westphal   netfilter: conntr...
784
  		ct_hash = nf_conntrack_hash;
5e3c61f98   Florian Westphal   netfilter: conntr...
785
786
787
  	} while (read_seqcount_retry(&nf_conntrack_generation, sequence));
  
  	hlist_nulls_for_each_entry_rcu(h, n, &ct_hash[hash], hnnode) {
5d0aa2ccd   Patrick McHardy   netfilter: nf_con...
788
789
  		ct = nf_ct_tuplehash_to_ctrack(h);
  		if (ct != ignored_conntrack &&
e0c7d4722   Florian Westphal   netfilter: conntr...
790
  		    nf_ct_key_equal(h, tuple, zone, net)) {
2cf123480   Florian Westphal   netfilter: conntr...
791
792
  			NF_CT_STAT_INC_ATOMIC(net, found);
  			rcu_read_unlock();
ba419aff2   Patrick McHardy   [NETFILTER]: nf_c...
793
794
  			return 1;
  		}
2cf123480   Florian Westphal   netfilter: conntr...
795
  		NF_CT_STAT_INC_ATOMIC(net, searched);
ba419aff2   Patrick McHardy   [NETFILTER]: nf_c...
796
  	}
2cf123480   Florian Westphal   netfilter: conntr...
797
  	rcu_read_unlock();
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
798

ba419aff2   Patrick McHardy   [NETFILTER]: nf_c...
799
  	return 0;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
800
  }
13b183391   Patrick McHardy   [NETFILTER]: nf_c...
801
  EXPORT_SYMBOL_GPL(nf_conntrack_tuple_taken);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
802

7ae7730fd   Patrick McHardy   [NETFILTER]: nf_c...
803
  #define NF_CT_EVICTION_RANGE	8
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
804
805
  /* There's a small race here where we may free a just-assured
     connection.  Too bad: we're in trouble anyway. */
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
806
  static noinline int early_drop(struct net *net, unsigned int _hash)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
807
  {
f205c5e0c   Patrick McHardy   [NETFILTER]: nf_c...
808
  	/* Use oldest entry, which is roughly LRU */
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
809
  	struct nf_conntrack_tuple_hash *h;
3e86638e9   Florian Westphal   netfilter: conntr...
810
  	struct nf_conn *tmp;
ea781f197   Eric Dumazet   netfilter: nf_con...
811
  	struct hlist_nulls_node *n;
3e86638e9   Florian Westphal   netfilter: conntr...
812
813
  	unsigned int i, hash, sequence;
  	struct nf_conn *ct = NULL;
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
814
  	spinlock_t *lockp;
3e86638e9   Florian Westphal   netfilter: conntr...
815
816
817
  	bool ret = false;
  
  	i = 0;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
818

93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
819
820
  	local_bh_disable();
  restart:
a3efd8120   Florian Westphal   netfilter: conntr...
821
  	sequence = read_seqcount_begin(&nf_conntrack_generation);
3e86638e9   Florian Westphal   netfilter: conntr...
822
823
  	for (; i < NF_CT_EVICTION_RANGE; i++) {
  		hash = scale_hash(_hash++);
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
824
  		lockp = &nf_conntrack_locks[hash % CONNTRACK_LOCKS];
b16c29191   Sasha Levin   netfilter: nf_con...
825
  		nf_conntrack_lock(lockp);
a3efd8120   Florian Westphal   netfilter: conntr...
826
  		if (read_seqcount_retry(&nf_conntrack_generation, sequence)) {
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
827
828
829
  			spin_unlock(lockp);
  			goto restart;
  		}
56d52d489   Florian Westphal   netfilter: conntr...
830
831
  		hlist_nulls_for_each_entry_rcu(h, n, &nf_conntrack_hash[hash],
  					       hnnode) {
7ae7730fd   Patrick McHardy   [NETFILTER]: nf_c...
832
  			tmp = nf_ct_tuplehash_to_ctrack(h);
3e86638e9   Florian Westphal   netfilter: conntr...
833
834
835
836
837
838
839
  
  			if (test_bit(IPS_ASSURED_BIT, &tmp->status) ||
  			    !net_eq(nf_ct_net(tmp), net) ||
  			    nf_ct_is_dying(tmp))
  				continue;
  
  			if (atomic_inc_not_zero(&tmp->ct_general.use)) {
7ae7730fd   Patrick McHardy   [NETFILTER]: nf_c...
840
  				ct = tmp;
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
841
842
  				break;
  			}
7ae7730fd   Patrick McHardy   [NETFILTER]: nf_c...
843
  		}
76507f69c   Patrick McHardy   [NETFILTER]: nf_c...
844

93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
845
  		spin_unlock(lockp);
3e86638e9   Florian Westphal   netfilter: conntr...
846
  		if (ct)
7ae7730fd   Patrick McHardy   [NETFILTER]: nf_c...
847
  			break;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
848
  	}
3e86638e9   Florian Westphal   netfilter: conntr...
849

93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
850
  	local_bh_enable();
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
851
852
  
  	if (!ct)
3e86638e9   Florian Westphal   netfilter: conntr...
853
  		return false;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
854

3e86638e9   Florian Westphal   netfilter: conntr...
855
856
857
858
  	/* kill only if in same netns -- might have moved due to
  	 * SLAB_DESTROY_BY_RCU rules
  	 */
  	if (net_eq(nf_ct_net(ct), net) && del_timer(&ct->timeout)) {
02982c27b   Florian Westphal   netfilter: nf_con...
859
  		if (nf_ct_delete(ct, 0, 0)) {
741385119   Pablo Neira Ayuso   netfilter: nf_con...
860
  			NF_CT_STAT_INC_ATOMIC(net, early_drop);
3e86638e9   Florian Westphal   netfilter: conntr...
861
  			ret = true;
741385119   Pablo Neira Ayuso   netfilter: nf_con...
862
  		}
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
863
  	}
3e86638e9   Florian Westphal   netfilter: conntr...
864

9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
865
  	nf_ct_put(ct);
3e86638e9   Florian Westphal   netfilter: conntr...
866
  	return ret;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
867
  }
99f07e91b   Changli Gao   netfilter: save t...
868
  static struct nf_conn *
308ac9143   Daniel Borkmann   netfilter: nf_con...
869
870
  __nf_conntrack_alloc(struct net *net,
  		     const struct nf_conntrack_zone *zone,
99f07e91b   Changli Gao   netfilter: save t...
871
872
873
  		     const struct nf_conntrack_tuple *orig,
  		     const struct nf_conntrack_tuple *repl,
  		     gfp_t gfp, u32 hash)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
874
  {
cd7fcbf1c   Julia Lawall   netfilter 07/09: ...
875
  	struct nf_conn *ct;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
876

5251e2d21   Pablo Neira Ayuso   [NETFILTER]: conn...
877
  	/* We don't want any race condition at early drop stage */
49ac8713b   Alexey Dobriyan   netfilter: netns ...
878
  	atomic_inc(&net->ct.count);
5251e2d21   Pablo Neira Ayuso   [NETFILTER]: conn...
879

76eb94604   Patrick McHardy   [NETFILTER]: nf_c...
880
  	if (nf_conntrack_max &&
49ac8713b   Alexey Dobriyan   netfilter: netns ...
881
  	    unlikely(atomic_read(&net->ct.count) > nf_conntrack_max)) {
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
882
  		if (!early_drop(net, hash)) {
49ac8713b   Alexey Dobriyan   netfilter: netns ...
883
  			atomic_dec(&net->ct.count);
e87cc4728   Joe Perches   net: Convert net_...
884
885
  			net_warn_ratelimited("nf_conntrack: table full, dropping packet
  ");
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
886
887
888
  			return ERR_PTR(-ENOMEM);
  		}
  	}
941297f44   Eric Dumazet   netfilter: nf_con...
889
890
891
892
  	/*
  	 * Do not use kmem_cache_zalloc(), as this cache uses
  	 * SLAB_DESTROY_BY_RCU.
  	 */
0c5366b3a   Florian Westphal   netfilter: conntr...
893
  	ct = kmem_cache_alloc(nf_conntrack_cachep, gfp);
5e8018fc6   Daniel Borkmann   netfilter: nf_con...
894
895
  	if (ct == NULL)
  		goto out;
440f0d588   Patrick McHardy   netfilter: nf_con...
896
  	spin_lock_init(&ct->lock);
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
897
  	ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple = *orig;
941297f44   Eric Dumazet   netfilter: nf_con...
898
  	ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode.pprev = NULL;
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
899
  	ct->tuplehash[IP_CT_DIR_REPLY].tuple = *repl;
99f07e91b   Changli Gao   netfilter: save t...
900
901
  	/* save hash for reusing when confirming */
  	*(unsigned long *)(&ct->tuplehash[IP_CT_DIR_REPLY].hnnode.pprev) = hash;
c41884ce0   Florian Westphal   netfilter: conntr...
902
  	ct->status = 0;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
903
  	/* Don't set timer yet: wait for confirmation */
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
904
  	setup_timer(&ct->timeout, death_by_timeout, (unsigned long)ct);
c2d9ba9bc   Eric Dumazet   net: CONFIG_NET_N...
905
  	write_pnet(&ct->ct_net, net);
c41884ce0   Florian Westphal   netfilter: conntr...
906
907
908
  	memset(&ct->__nfct_init_offset[0], 0,
  	       offsetof(struct nf_conn, proto) -
  	       offsetof(struct nf_conn, __nfct_init_offset[0]));
5e8018fc6   Daniel Borkmann   netfilter: nf_con...
909

6c8dee984   Florian Westphal   netfilter: move z...
910
  	nf_ct_zone_add(ct, zone);
5e8018fc6   Daniel Borkmann   netfilter: nf_con...
911

e53376bef   Pablo Neira Ayuso   netfilter: nf_con...
912
913
  	/* Because we use RCU lookups, we set ct_general.use to zero before
  	 * this is inserted in any list.
941297f44   Eric Dumazet   netfilter: nf_con...
914
  	 */
e53376bef   Pablo Neira Ayuso   netfilter: nf_con...
915
  	atomic_set(&ct->ct_general.use, 0);
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
916
  	return ct;
5e8018fc6   Daniel Borkmann   netfilter: nf_con...
917
918
  out:
  	atomic_dec(&net->ct.count);
5d0aa2ccd   Patrick McHardy   netfilter: nf_con...
919
  	return ERR_PTR(-ENOMEM);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
920
  }
99f07e91b   Changli Gao   netfilter: save t...
921

308ac9143   Daniel Borkmann   netfilter: nf_con...
922
923
  struct nf_conn *nf_conntrack_alloc(struct net *net,
  				   const struct nf_conntrack_zone *zone,
99f07e91b   Changli Gao   netfilter: save t...
924
925
926
927
928
929
  				   const struct nf_conntrack_tuple *orig,
  				   const struct nf_conntrack_tuple *repl,
  				   gfp_t gfp)
  {
  	return __nf_conntrack_alloc(net, zone, orig, repl, gfp, 0);
  }
13b183391   Patrick McHardy   [NETFILTER]: nf_c...
930
  EXPORT_SYMBOL_GPL(nf_conntrack_alloc);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
931

c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
932
  void nf_conntrack_free(struct nf_conn *ct)
76507f69c   Patrick McHardy   [NETFILTER]: nf_c...
933
  {
1d45209d8   Eric Dumazet   netfilter: nf_con...
934
  	struct net *net = nf_ct_net(ct);
e53376bef   Pablo Neira Ayuso   netfilter: nf_con...
935
936
937
938
  	/* A freed object has refcnt == 0, that's
  	 * the golden rule for SLAB_DESTROY_BY_RCU
  	 */
  	NF_CT_ASSERT(atomic_read(&ct->ct_general.use) == 0);
ceeff7541   Patrick McHardy   netfilter: nf_con...
939
  	nf_ct_ext_destroy(ct);
ea781f197   Eric Dumazet   netfilter: nf_con...
940
  	nf_ct_ext_free(ct);
0c5366b3a   Florian Westphal   netfilter: conntr...
941
  	kmem_cache_free(nf_conntrack_cachep, ct);
4e857c58e   Peter Zijlstra   arch: Mass conver...
942
  	smp_mb__before_atomic();
0c3c6c00c   Pablo Neira Ayuso   netfilter: nf_con...
943
  	atomic_dec(&net->ct.count);
76507f69c   Patrick McHardy   [NETFILTER]: nf_c...
944
  }
13b183391   Patrick McHardy   [NETFILTER]: nf_c...
945
  EXPORT_SYMBOL_GPL(nf_conntrack_free);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
946

c539f0171   Florian Westphal   netfilter: add co...
947

9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
948
949
950
  /* Allocate a new conntrack: we return -ENOMEM if classification
     failed due to stress.  Otherwise it really is unclassifiable. */
  static struct nf_conntrack_tuple_hash *
b2a15a604   Patrick McHardy   netfilter: nf_con...
951
  init_conntrack(struct net *net, struct nf_conn *tmpl,
5a1fb391d   Alexey Dobriyan   netfilter: netns ...
952
  	       const struct nf_conntrack_tuple *tuple,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
953
  	       struct nf_conntrack_l3proto *l3proto,
605dcad6c   Martin Josefsson   [NETFILTER]: nf_c...
954
  	       struct nf_conntrack_l4proto *l4proto,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
955
  	       struct sk_buff *skb,
60b5f8f74   Pablo Neira Ayuso   netfilter: nf_con...
956
  	       unsigned int dataoff, u32 hash)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
957
  {
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
958
  	struct nf_conn *ct;
3c158f7f5   Patrick McHarrdy   [NETFILTER]: nf_c...
959
  	struct nf_conn_help *help;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
960
  	struct nf_conntrack_tuple repl_tuple;
b2a15a604   Patrick McHardy   netfilter: nf_con...
961
  	struct nf_conntrack_ecache *ecache;
ca7433df3   Jesper Dangaard Brouer   netfilter: conntr...
962
  	struct nf_conntrack_expect *exp = NULL;
308ac9143   Daniel Borkmann   netfilter: nf_con...
963
  	const struct nf_conntrack_zone *zone;
60b5f8f74   Pablo Neira Ayuso   netfilter: nf_con...
964
  	struct nf_conn_timeout *timeout_ext;
5e8018fc6   Daniel Borkmann   netfilter: nf_con...
965
  	struct nf_conntrack_zone tmp;
60b5f8f74   Pablo Neira Ayuso   netfilter: nf_con...
966
  	unsigned int *timeouts;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
967

605dcad6c   Martin Josefsson   [NETFILTER]: nf_c...
968
  	if (!nf_ct_invert_tuple(&repl_tuple, tuple, l3proto, l4proto)) {
0d53778e8   Patrick McHardy   [NETFILTER]: Conv...
969
970
  		pr_debug("Can't invert tuple.
  ");
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
971
972
  		return NULL;
  	}
5e8018fc6   Daniel Borkmann   netfilter: nf_con...
973
  	zone = nf_ct_zone_tmpl(tmpl, skb, &tmp);
99f07e91b   Changli Gao   netfilter: save t...
974
975
  	ct = __nf_conntrack_alloc(net, zone, tuple, &repl_tuple, GFP_ATOMIC,
  				  hash);
0a9ee8134   Joe Perches   netfilter: Remove...
976
  	if (IS_ERR(ct))
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
977
  		return (struct nf_conntrack_tuple_hash *)ct;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
978

48b1de4c1   Patrick McHardy   netfilter: add SY...
979
980
981
982
  	if (tmpl && nfct_synproxy(tmpl)) {
  		nfct_seqadj_ext_add(ct);
  		nfct_synproxy_ext_add(ct);
  	}
60b5f8f74   Pablo Neira Ayuso   netfilter: nf_con...
983
  	timeout_ext = tmpl ? nf_ct_timeout_find(tmpl) : NULL;
ae2d708ed   Pablo Neira Ayuso   netfilter: conntr...
984
985
986
987
988
  	if (timeout_ext) {
  		timeouts = nf_ct_timeout_data(timeout_ext);
  		if (unlikely(!timeouts))
  			timeouts = l4proto->get_timeouts(net);
  	} else {
60b5f8f74   Pablo Neira Ayuso   netfilter: nf_con...
989
  		timeouts = l4proto->get_timeouts(net);
ae2d708ed   Pablo Neira Ayuso   netfilter: conntr...
990
  	}
60b5f8f74   Pablo Neira Ayuso   netfilter: nf_con...
991

2c8503f55   Pablo Neira Ayuso   netfilter: nf_con...
992
  	if (!l4proto->new(ct, skb, dataoff, timeouts)) {
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
993
  		nf_conntrack_free(ct);
ccd63c20f   Weongyo Jeong   netfilter: nf_con...
994
995
  		pr_debug("can't track with proto module
  ");
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
996
997
  		return NULL;
  	}
60b5f8f74   Pablo Neira Ayuso   netfilter: nf_con...
998
  	if (timeout_ext)
ae2d708ed   Pablo Neira Ayuso   netfilter: conntr...
999
1000
  		nf_ct_timeout_ext_add(ct, rcu_dereference(timeout_ext->timeout),
  				      GFP_ATOMIC);
60b5f8f74   Pablo Neira Ayuso   netfilter: nf_con...
1001

584015727   Krzysztof Piotr Oledzki   netfilter: accoun...
1002
  	nf_ct_acct_ext_add(ct, GFP_ATOMIC);
a992ca2a0   Pablo Neira Ayuso   netfilter: nf_con...
1003
  	nf_ct_tstamp_ext_add(ct, GFP_ATOMIC);
c539f0171   Florian Westphal   netfilter: add co...
1004
  	nf_ct_labels_ext_add(ct);
b2a15a604   Patrick McHardy   netfilter: nf_con...
1005
1006
1007
1008
1009
  
  	ecache = tmpl ? nf_ct_ecache_find(tmpl) : NULL;
  	nf_ct_ecache_ext_add(ct, ecache ? ecache->ctmask : 0,
  				 ecache ? ecache->expmask : 0,
  			     GFP_ATOMIC);
584015727   Krzysztof Piotr Oledzki   netfilter: accoun...
1010

ca7433df3   Jesper Dangaard Brouer   netfilter: conntr...
1011
1012
1013
1014
1015
  	local_bh_disable();
  	if (net->ct.expect_count) {
  		spin_lock(&nf_conntrack_expect_lock);
  		exp = nf_ct_find_expectation(net, zone, tuple);
  		if (exp) {
ccd63c20f   Weongyo Jeong   netfilter: nf_con...
1016
1017
  			pr_debug("expectation arrives ct=%p exp=%p
  ",
ca7433df3   Jesper Dangaard Brouer   netfilter: conntr...
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
  				 ct, exp);
  			/* Welcome, Mr. Bond.  We've been expecting you... */
  			__set_bit(IPS_EXPECTED_BIT, &ct->status);
  			/* exp->master safe, refcnt bumped in nf_ct_find_expectation */
  			ct->master = exp->master;
  			if (exp->helper) {
  				help = nf_ct_helper_ext_add(ct, exp->helper,
  							    GFP_ATOMIC);
  				if (help)
  					rcu_assign_pointer(help->helper, exp->helper);
  			}
ceceae1b1   Yasuyuki Kozakai   [NETFILTER]: nf_c...
1029

9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1030
  #ifdef CONFIG_NF_CONNTRACK_MARK
ca7433df3   Jesper Dangaard Brouer   netfilter: conntr...
1031
  			ct->mark = exp->master->mark;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1032
  #endif
7c9728c39   James Morris   [SECMARK]: Add se...
1033
  #ifdef CONFIG_NF_CONNTRACK_SECMARK
ca7433df3   Jesper Dangaard Brouer   netfilter: conntr...
1034
  			ct->secmark = exp->master->secmark;
7c9728c39   James Morris   [SECMARK]: Add se...
1035
  #endif
ca7433df3   Jesper Dangaard Brouer   netfilter: conntr...
1036
1037
1038
1039
1040
  			NF_CT_STAT_INC(net, expect_new);
  		}
  		spin_unlock(&nf_conntrack_expect_lock);
  	}
  	if (!exp) {
b2a15a604   Patrick McHardy   netfilter: nf_con...
1041
  		__nf_ct_try_assign_helper(ct, tmpl, GFP_ATOMIC);
0d55af879   Alexey Dobriyan   netfilter: netns ...
1042
  		NF_CT_STAT_INC(net, new);
22e7410b7   Yasuyuki Kozakai   [NETFILTER]: nf_c...
1043
  	}
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1044

e53376bef   Pablo Neira Ayuso   netfilter: nf_con...
1045
1046
  	/* Now it is inserted into the unconfirmed list, bump refcount */
  	nf_conntrack_get(&ct->ct_general);
b7779d06f   Jesper Dangaard Brouer   netfilter: conntr...
1047
  	nf_ct_add_to_unconfirmed_list(ct);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1048

ca7433df3   Jesper Dangaard Brouer   netfilter: conntr...
1049
  	local_bh_enable();
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1050
1051
1052
  
  	if (exp) {
  		if (exp->expectfn)
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
1053
  			exp->expectfn(ct, exp);
6823645d6   Patrick McHardy   [NETFILTER]: nf_c...
1054
  		nf_ct_expect_put(exp);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1055
  	}
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
1056
  	return &ct->tuplehash[IP_CT_DIR_ORIGINAL];
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1057
1058
1059
1060
  }
  
  /* On success, returns conntrack ptr, sets skb->nfct and ctinfo */
  static inline struct nf_conn *
b2a15a604   Patrick McHardy   netfilter: nf_con...
1061
  resolve_normal_ct(struct net *net, struct nf_conn *tmpl,
a702a65fc   Alexey Dobriyan   netfilter: netns ...
1062
  		  struct sk_buff *skb,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1063
1064
1065
1066
  		  unsigned int dataoff,
  		  u_int16_t l3num,
  		  u_int8_t protonum,
  		  struct nf_conntrack_l3proto *l3proto,
605dcad6c   Martin Josefsson   [NETFILTER]: nf_c...
1067
  		  struct nf_conntrack_l4proto *l4proto,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1068
  		  int *set_reply,
60b5f8f74   Pablo Neira Ayuso   netfilter: nf_con...
1069
  		  enum ip_conntrack_info *ctinfo)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1070
  {
308ac9143   Daniel Borkmann   netfilter: nf_con...
1071
  	const struct nf_conntrack_zone *zone;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1072
1073
  	struct nf_conntrack_tuple tuple;
  	struct nf_conntrack_tuple_hash *h;
5e8018fc6   Daniel Borkmann   netfilter: nf_con...
1074
  	struct nf_conntrack_zone tmp;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1075
  	struct nf_conn *ct;
99f07e91b   Changli Gao   netfilter: save t...
1076
  	u32 hash;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1077

bbe735e42   Arnaldo Carvalho de Melo   [SK_BUFF]: Introd...
1078
  	if (!nf_ct_get_tuple(skb, skb_network_offset(skb),
a31f1adc0   Eric W. Biederman   netfilter: nf_con...
1079
  			     dataoff, l3num, protonum, net, &tuple, l3proto,
605dcad6c   Martin Josefsson   [NETFILTER]: nf_c...
1080
  			     l4proto)) {
ccd63c20f   Weongyo Jeong   netfilter: nf_con...
1081
1082
  		pr_debug("Can't get tuple
  ");
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1083
1084
1085
1086
  		return NULL;
  	}
  
  	/* look for tuple match */
5e8018fc6   Daniel Borkmann   netfilter: nf_con...
1087
  	zone = nf_ct_zone_tmpl(tmpl, skb, &tmp);
1b8c8a9f6   Florian Westphal   netfilter: conntr...
1088
  	hash = hash_conntrack_raw(&tuple, net);
99f07e91b   Changli Gao   netfilter: save t...
1089
  	h = __nf_conntrack_find_get(net, zone, &tuple, hash);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1090
  	if (!h) {
b2a15a604   Patrick McHardy   netfilter: nf_con...
1091
  		h = init_conntrack(net, tmpl, &tuple, l3proto, l4proto,
60b5f8f74   Pablo Neira Ayuso   netfilter: nf_con...
1092
  				   skb, dataoff, hash);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1093
1094
1095
1096
1097
1098
1099
1100
1101
  		if (!h)
  			return NULL;
  		if (IS_ERR(h))
  			return (void *)h;
  	}
  	ct = nf_ct_tuplehash_to_ctrack(h);
  
  	/* It exists; we have (non-exclusive) reference. */
  	if (NF_CT_DIRECTION(h) == IP_CT_DIR_REPLY) {
fb0488337   Eric Dumazet   netfilter: add mo...
1102
  		*ctinfo = IP_CT_ESTABLISHED_REPLY;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1103
1104
1105
1106
1107
  		/* Please set reply bit if this packet OK */
  		*set_reply = 1;
  	} else {
  		/* Once we've had two way comms, always ESTABLISHED. */
  		if (test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
ccd63c20f   Weongyo Jeong   netfilter: nf_con...
1108
1109
  			pr_debug("normal packet for %p
  ", ct);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1110
1111
  			*ctinfo = IP_CT_ESTABLISHED;
  		} else if (test_bit(IPS_EXPECTED_BIT, &ct->status)) {
ccd63c20f   Weongyo Jeong   netfilter: nf_con...
1112
1113
  			pr_debug("related packet for %p
  ", ct);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1114
1115
  			*ctinfo = IP_CT_RELATED;
  		} else {
ccd63c20f   Weongyo Jeong   netfilter: nf_con...
1116
1117
  			pr_debug("new packet for %p
  ", ct);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
  			*ctinfo = IP_CT_NEW;
  		}
  		*set_reply = 0;
  	}
  	skb->nfct = &ct->ct_general;
  	skb->nfctinfo = *ctinfo;
  	return ct;
  }
  
  unsigned int
a702a65fc   Alexey Dobriyan   netfilter: netns ...
1128
1129
  nf_conntrack_in(struct net *net, u_int8_t pf, unsigned int hooknum,
  		struct sk_buff *skb)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1130
  {
b2a15a604   Patrick McHardy   netfilter: nf_con...
1131
  	struct nf_conn *ct, *tmpl = NULL;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1132
1133
  	enum ip_conntrack_info ctinfo;
  	struct nf_conntrack_l3proto *l3proto;
605dcad6c   Martin Josefsson   [NETFILTER]: nf_c...
1134
  	struct nf_conntrack_l4proto *l4proto;
2c8503f55   Pablo Neira Ayuso   netfilter: nf_con...
1135
  	unsigned int *timeouts;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1136
1137
1138
1139
  	unsigned int dataoff;
  	u_int8_t protonum;
  	int set_reply = 0;
  	int ret;
3db05fea5   Herbert Xu   [NETFILTER]: Repl...
1140
  	if (skb->nfct) {
b2a15a604   Patrick McHardy   netfilter: nf_con...
1141
1142
1143
1144
1145
1146
1147
  		/* Previously seen (loopback or untracked)?  Ignore. */
  		tmpl = (struct nf_conn *)skb->nfct;
  		if (!nf_ct_is_template(tmpl)) {
  			NF_CT_STAT_INC_ATOMIC(net, ignore);
  			return NF_ACCEPT;
  		}
  		skb->nfct = NULL;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1148
  	}
923f4902f   Patrick McHardy   [NETFILTER]: nf_c...
1149
  	/* rcu_read_lock()ed by nf_hook_slow */
76108cea0   Jan Engelhardt   netfilter: Use un...
1150
  	l3proto = __nf_ct_l3proto_find(pf);
3db05fea5   Herbert Xu   [NETFILTER]: Repl...
1151
  	ret = l3proto->get_l4proto(skb, skb_network_offset(skb),
ffc306904   Yasuyuki Kozakai   [NETFILTER]: nf_c...
1152
1153
  				   &dataoff, &protonum);
  	if (ret <= 0) {
25985edce   Lucas De Marchi   Fix common misspe...
1154
1155
  		pr_debug("not prepared to track yet or error occurred
  ");
0d55af879   Alexey Dobriyan   netfilter: netns ...
1156
1157
  		NF_CT_STAT_INC_ATOMIC(net, error);
  		NF_CT_STAT_INC_ATOMIC(net, invalid);
b2a15a604   Patrick McHardy   netfilter: nf_con...
1158
1159
  		ret = -ret;
  		goto out;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1160
  	}
76108cea0   Jan Engelhardt   netfilter: Use un...
1161
  	l4proto = __nf_ct_l4proto_find(pf, protonum);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1162
1163
1164
1165
  
  	/* It may be an special packet, error, unclean...
  	 * inverse of the return code tells to the netfilter
  	 * core what to do with the packet. */
74c51a149   Alexey Dobriyan   netfilter: netns ...
1166
  	if (l4proto->error != NULL) {
8fea97ec1   Patrick McHardy   netfilter: nf_con...
1167
1168
  		ret = l4proto->error(net, tmpl, skb, dataoff, &ctinfo,
  				     pf, hooknum);
74c51a149   Alexey Dobriyan   netfilter: netns ...
1169
  		if (ret <= 0) {
0d55af879   Alexey Dobriyan   netfilter: netns ...
1170
1171
  			NF_CT_STAT_INC_ATOMIC(net, error);
  			NF_CT_STAT_INC_ATOMIC(net, invalid);
b2a15a604   Patrick McHardy   netfilter: nf_con...
1172
1173
  			ret = -ret;
  			goto out;
74c51a149   Alexey Dobriyan   netfilter: netns ...
1174
  		}
88ed01d17   Pablo Neira Ayuso   netfilter: nf_con...
1175
1176
1177
  		/* ICMP[v6] protocol trackers may assign one conntrack. */
  		if (skb->nfct)
  			goto out;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1178
  	}
b2a15a604   Patrick McHardy   netfilter: nf_con...
1179
  	ct = resolve_normal_ct(net, tmpl, skb, dataoff, pf, protonum,
60b5f8f74   Pablo Neira Ayuso   netfilter: nf_con...
1180
  			       l3proto, l4proto, &set_reply, &ctinfo);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1181
1182
  	if (!ct) {
  		/* Not valid part of a connection */
0d55af879   Alexey Dobriyan   netfilter: netns ...
1183
  		NF_CT_STAT_INC_ATOMIC(net, invalid);
b2a15a604   Patrick McHardy   netfilter: nf_con...
1184
1185
  		ret = NF_ACCEPT;
  		goto out;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1186
1187
1188
1189
  	}
  
  	if (IS_ERR(ct)) {
  		/* Too stressed to deal. */
0d55af879   Alexey Dobriyan   netfilter: netns ...
1190
  		NF_CT_STAT_INC_ATOMIC(net, drop);
b2a15a604   Patrick McHardy   netfilter: nf_con...
1191
1192
  		ret = NF_DROP;
  		goto out;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1193
  	}
3db05fea5   Herbert Xu   [NETFILTER]: Repl...
1194
  	NF_CT_ASSERT(skb->nfct);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1195

60b5f8f74   Pablo Neira Ayuso   netfilter: nf_con...
1196
  	/* Decide what timeout policy we want to apply to this flow. */
84b5ee939   Pablo Neira Ayuso   netfilter: nf_con...
1197
  	timeouts = nf_ct_timeout_lookup(net, ct, l4proto);
60b5f8f74   Pablo Neira Ayuso   netfilter: nf_con...
1198

2c8503f55   Pablo Neira Ayuso   netfilter: nf_con...
1199
  	ret = l4proto->packet(ct, skb, dataoff, ctinfo, pf, hooknum, timeouts);
ec8d54096   Christoph Paasch   netfilter: conntr...
1200
  	if (ret <= 0) {
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1201
1202
  		/* Invalid: inverse of the return code tells
  		 * the netfilter core what to do */
0d53778e8   Patrick McHardy   [NETFILTER]: Conv...
1203
1204
  		pr_debug("nf_conntrack_in: Can't track with proto module
  ");
3db05fea5   Herbert Xu   [NETFILTER]: Repl...
1205
1206
  		nf_conntrack_put(skb->nfct);
  		skb->nfct = NULL;
0d55af879   Alexey Dobriyan   netfilter: netns ...
1207
  		NF_CT_STAT_INC_ATOMIC(net, invalid);
7d1e04598   Pablo Neira Ayuso   netfilter: nf_con...
1208
1209
  		if (ret == -NF_DROP)
  			NF_CT_STAT_INC_ATOMIC(net, drop);
b2a15a604   Patrick McHardy   netfilter: nf_con...
1210
1211
  		ret = -ret;
  		goto out;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1212
1213
1214
  	}
  
  	if (set_reply && !test_and_set_bit(IPS_SEEN_REPLY_BIT, &ct->status))
858b31330   Patrick McHardy   netfilter: nf_con...
1215
  		nf_conntrack_event_cache(IPCT_REPLY, ct);
b2a15a604   Patrick McHardy   netfilter: nf_con...
1216
  out:
c31742864   Pablo Neira Ayuso   netfilter: nf_con...
1217
1218
1219
1220
1221
1222
1223
1224
1225
  	if (tmpl) {
  		/* Special case: we have to repeat this hook, assign the
  		 * template again to this packet. We assume that this packet
  		 * has no conntrack assigned. This is used by nf_ct_tcp. */
  		if (ret == NF_REPEAT)
  			skb->nfct = (struct nf_conntrack *)tmpl;
  		else
  			nf_ct_put(tmpl);
  	}
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1226
1227
1228
  
  	return ret;
  }
13b183391   Patrick McHardy   [NETFILTER]: nf_c...
1229
  EXPORT_SYMBOL_GPL(nf_conntrack_in);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1230

5f2b4c900   Jan Engelhardt   [NETFILTER]: nf_c...
1231
1232
  bool nf_ct_invert_tuplepr(struct nf_conntrack_tuple *inverse,
  			  const struct nf_conntrack_tuple *orig)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1233
  {
5f2b4c900   Jan Engelhardt   [NETFILTER]: nf_c...
1234
  	bool ret;
923f4902f   Patrick McHardy   [NETFILTER]: nf_c...
1235
1236
1237
1238
1239
1240
1241
1242
  
  	rcu_read_lock();
  	ret = nf_ct_invert_tuple(inverse, orig,
  				 __nf_ct_l3proto_find(orig->src.l3num),
  				 __nf_ct_l4proto_find(orig->src.l3num,
  						      orig->dst.protonum));
  	rcu_read_unlock();
  	return ret;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1243
  }
13b183391   Patrick McHardy   [NETFILTER]: nf_c...
1244
  EXPORT_SYMBOL_GPL(nf_ct_invert_tuplepr);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1245

5b1158e90   Jozsef Kadlecsik   [NETFILTER]: Add ...
1246
1247
1248
1249
1250
1251
  /* Alter reply tuple (maybe alter helper).  This is for NAT, and is
     implicitly racy: see __nf_conntrack_confirm */
  void nf_conntrack_alter_reply(struct nf_conn *ct,
  			      const struct nf_conntrack_tuple *newreply)
  {
  	struct nf_conn_help *help = nfct_help(ct);
5b1158e90   Jozsef Kadlecsik   [NETFILTER]: Add ...
1252
1253
  	/* Should be unconfirmed, so not in hash table yet */
  	NF_CT_ASSERT(!nf_ct_is_confirmed(ct));
0d53778e8   Patrick McHardy   [NETFILTER]: Conv...
1254
  	pr_debug("Altering reply tuple of %p to ", ct);
3c9fba656   Jan Engelhardt   [NETFILTER]: nf_c...
1255
  	nf_ct_dump_tuple(newreply);
5b1158e90   Jozsef Kadlecsik   [NETFILTER]: Add ...
1256
1257
  
  	ct->tuplehash[IP_CT_DIR_REPLY].tuple = *newreply;
ef1a5a50b   Patrick McHardy   [NETFILTER]: nf_c...
1258
  	if (ct->master || (help && !hlist_empty(&help->expectations)))
c52fbb410   Patrick McHardy   [NETFILTER]: nf_c...
1259
  		return;
ceceae1b1   Yasuyuki Kozakai   [NETFILTER]: nf_c...
1260

c52fbb410   Patrick McHardy   [NETFILTER]: nf_c...
1261
  	rcu_read_lock();
b2a15a604   Patrick McHardy   netfilter: nf_con...
1262
  	__nf_ct_try_assign_helper(ct, NULL, GFP_ATOMIC);
c52fbb410   Patrick McHardy   [NETFILTER]: nf_c...
1263
  	rcu_read_unlock();
5b1158e90   Jozsef Kadlecsik   [NETFILTER]: Add ...
1264
  }
13b183391   Patrick McHardy   [NETFILTER]: nf_c...
1265
  EXPORT_SYMBOL_GPL(nf_conntrack_alter_reply);
5b1158e90   Jozsef Kadlecsik   [NETFILTER]: Add ...
1266

9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1267
1268
1269
1270
1271
1272
1273
  /* Refresh conntrack for this many jiffies and do accounting if do_acct is 1 */
  void __nf_ct_refresh_acct(struct nf_conn *ct,
  			  enum ip_conntrack_info ctinfo,
  			  const struct sk_buff *skb,
  			  unsigned long extra_jiffies,
  			  int do_acct)
  {
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1274
1275
  	NF_CT_ASSERT(ct->timeout.data == (unsigned long)ct);
  	NF_CT_ASSERT(skb);
997ae831a   Eric Leblond   [NETFILTER]: conn...
1276
  	/* Only update if this is not a fixed timeout */
47d950454   Patrick McHardy   [NETFILTER]: nf_c...
1277
1278
  	if (test_bit(IPS_FIXED_TIMEOUT_BIT, &ct->status))
  		goto acct;
997ae831a   Eric Leblond   [NETFILTER]: conn...
1279

9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1280
1281
1282
  	/* If not in hash table, timer will not be active yet */
  	if (!nf_ct_is_confirmed(ct)) {
  		ct->timeout.expires = extra_jiffies;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1283
  	} else {
be00c8e48   Martin Josefsson   [NETFILTER]: nf_c...
1284
1285
1286
1287
1288
  		unsigned long newtime = jiffies + extra_jiffies;
  
  		/* Only update the timeout if the new timeout is at least
  		   HZ jiffies from the old timeout. Need del_timer for race
  		   avoidance (may already be dying). */
65cb9fda3   Patrick McHardy   netfilter: nf_con...
1289
1290
  		if (newtime - ct->timeout.expires >= HZ)
  			mod_timer_pending(&ct->timeout, newtime);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1291
  	}
47d950454   Patrick McHardy   [NETFILTER]: nf_c...
1292
  acct:
ba76738c0   Pablo Neira Ayuso   netfilter: conntr...
1293
1294
  	if (do_acct)
  		nf_ct_acct_update(ct, ctinfo, skb->len);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1295
  }
13b183391   Patrick McHardy   [NETFILTER]: nf_c...
1296
  EXPORT_SYMBOL_GPL(__nf_ct_refresh_acct);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1297

4c8894980   David S. Miller   netfilter: Let nf...
1298
1299
1300
1301
  bool __nf_ct_kill_acct(struct nf_conn *ct,
  		       enum ip_conntrack_info ctinfo,
  		       const struct sk_buff *skb,
  		       int do_acct)
51091764f   Patrick McHardy   netfilter: nf_con...
1302
  {
ba76738c0   Pablo Neira Ayuso   netfilter: conntr...
1303
1304
  	if (do_acct)
  		nf_ct_acct_update(ct, ctinfo, skb->len);
584015727   Krzysztof Piotr Oledzki   netfilter: accoun...
1305

4c8894980   David S. Miller   netfilter: Let nf...
1306
  	if (del_timer(&ct->timeout)) {
51091764f   Patrick McHardy   netfilter: nf_con...
1307
  		ct->timeout.function((unsigned long)ct);
4c8894980   David S. Miller   netfilter: Let nf...
1308
1309
1310
  		return true;
  	}
  	return false;
51091764f   Patrick McHardy   netfilter: nf_con...
1311
  }
718d4ad98   Fabian Hugelshofer   netfilter: nf_con...
1312
  EXPORT_SYMBOL_GPL(__nf_ct_kill_acct);
51091764f   Patrick McHardy   netfilter: nf_con...
1313

c0cd11566   Igor Maravić   net:netfilter: us...
1314
  #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
1315
1316
1317
  
  #include <linux/netfilter/nfnetlink.h>
  #include <linux/netfilter/nfnetlink_conntrack.h>
57b47a53e   Ingo Molnar   [NET]: sem2mutex ...
1318
  #include <linux/mutex.h>
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
1319
1320
1321
  /* Generic function for tcp/udp/sctp/dccp and alike. This needs to be
   * in ip_conntrack_core, since we don't want the protocols to autoload
   * or depend on ctnetlink */
fdf708322   Patrick McHardy   [NETFILTER]: nfne...
1322
  int nf_ct_port_tuple_to_nlattr(struct sk_buff *skb,
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
1323
1324
  			       const struct nf_conntrack_tuple *tuple)
  {
bae65be89   David S. Miller   nf_conntrack_core...
1325
1326
1327
  	if (nla_put_be16(skb, CTA_PROTO_SRC_PORT, tuple->src.u.tcp.port) ||
  	    nla_put_be16(skb, CTA_PROTO_DST_PORT, tuple->dst.u.tcp.port))
  		goto nla_put_failure;
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
1328
  	return 0;
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
1329
  nla_put_failure:
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
1330
1331
  	return -1;
  }
fdf708322   Patrick McHardy   [NETFILTER]: nfne...
1332
  EXPORT_SYMBOL_GPL(nf_ct_port_tuple_to_nlattr);
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
1333

f73e924cd   Patrick McHardy   [NETFILTER]: ctne...
1334
1335
1336
  const struct nla_policy nf_ct_port_nla_policy[CTA_PROTO_MAX+1] = {
  	[CTA_PROTO_SRC_PORT]  = { .type = NLA_U16 },
  	[CTA_PROTO_DST_PORT]  = { .type = NLA_U16 },
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
1337
  };
f73e924cd   Patrick McHardy   [NETFILTER]: ctne...
1338
  EXPORT_SYMBOL_GPL(nf_ct_port_nla_policy);
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
1339

fdf708322   Patrick McHardy   [NETFILTER]: nfne...
1340
  int nf_ct_port_nlattr_to_tuple(struct nlattr *tb[],
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
1341
1342
  			       struct nf_conntrack_tuple *t)
  {
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
1343
  	if (!tb[CTA_PROTO_SRC_PORT] || !tb[CTA_PROTO_DST_PORT])
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
1344
  		return -EINVAL;
77236b6e3   Patrick McHardy   [NETFILTER]: ctne...
1345
1346
  	t->src.u.tcp.port = nla_get_be16(tb[CTA_PROTO_SRC_PORT]);
  	t->dst.u.tcp.port = nla_get_be16(tb[CTA_PROTO_DST_PORT]);
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
1347
1348
1349
  
  	return 0;
  }
fdf708322   Patrick McHardy   [NETFILTER]: nfne...
1350
  EXPORT_SYMBOL_GPL(nf_ct_port_nlattr_to_tuple);
5c0de29d0   Holger Eitzenberger   netfilter: nf_con...
1351
1352
1353
1354
1355
1356
  
  int nf_ct_port_nlattr_tuple_size(void)
  {
  	return nla_policy_len(nf_ct_port_nla_policy, CTA_PROTO_MAX + 1);
  }
  EXPORT_SYMBOL_GPL(nf_ct_port_nlattr_tuple_size);
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
1357
  #endif
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1358
  /* Used by ipt_REJECT and ip6t_REJECT. */
312a0c16c   Patrick McHardy   netfilter: nf_con...
1359
  static void nf_conntrack_attach(struct sk_buff *nskb, const struct sk_buff *skb)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1360
1361
1362
1363
1364
1365
1366
  {
  	struct nf_conn *ct;
  	enum ip_conntrack_info ctinfo;
  
  	/* This ICMP is in reverse direction to the packet which caused it */
  	ct = nf_ct_get(skb, &ctinfo);
  	if (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL)
fb0488337   Eric Dumazet   netfilter: add mo...
1367
  		ctinfo = IP_CT_RELATED_REPLY;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1368
1369
1370
1371
1372
1373
1374
1375
  	else
  		ctinfo = IP_CT_RELATED;
  
  	/* Attach to new skbuff, and increment count */
  	nskb->nfct = &ct->ct_general;
  	nskb->nfctinfo = ctinfo;
  	nf_conntrack_get(nskb->nfct);
  }
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1376
  /* Bring out ya dead! */
df0933dcb   Patrick McHardy   [NETFILTER]: kill...
1377
  static struct nf_conn *
400dad39d   Alexey Dobriyan   netfilter: netns ...
1378
  get_next_corpse(struct net *net, int (*iter)(struct nf_conn *i, void *data),
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1379
1380
  		void *data, unsigned int *bucket)
  {
df0933dcb   Patrick McHardy   [NETFILTER]: kill...
1381
1382
  	struct nf_conntrack_tuple_hash *h;
  	struct nf_conn *ct;
ea781f197   Eric Dumazet   netfilter: nf_con...
1383
  	struct hlist_nulls_node *n;
b7779d06f   Jesper Dangaard Brouer   netfilter: conntr...
1384
  	int cpu;
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
1385
  	spinlock_t *lockp;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1386

56d52d489   Florian Westphal   netfilter: conntr...
1387
  	for (; *bucket < nf_conntrack_htable_size; (*bucket)++) {
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
1388
1389
  		lockp = &nf_conntrack_locks[*bucket % CONNTRACK_LOCKS];
  		local_bh_disable();
b16c29191   Sasha Levin   netfilter: nf_con...
1390
  		nf_conntrack_lock(lockp);
56d52d489   Florian Westphal   netfilter: conntr...
1391
1392
  		if (*bucket < nf_conntrack_htable_size) {
  			hlist_nulls_for_each_entry(h, n, &nf_conntrack_hash[*bucket], hnnode) {
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
1393
1394
1395
  				if (NF_CT_DIRECTION(h) != IP_CT_DIR_ORIGINAL)
  					continue;
  				ct = nf_ct_tuplehash_to_ctrack(h);
e0c7d4722   Florian Westphal   netfilter: conntr...
1396
1397
  				if (net_eq(nf_ct_net(ct), net) &&
  				    iter(ct, data))
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
1398
1399
  					goto found;
  			}
df0933dcb   Patrick McHardy   [NETFILTER]: kill...
1400
  		}
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
1401
1402
  		spin_unlock(lockp);
  		local_bh_enable();
d93c6258e   Florian Westphal   netfilter: conntr...
1403
  		cond_resched();
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
1404
  	}
b7779d06f   Jesper Dangaard Brouer   netfilter: conntr...
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
  
  	for_each_possible_cpu(cpu) {
  		struct ct_pcpu *pcpu = per_cpu_ptr(net->ct.pcpu_lists, cpu);
  
  		spin_lock_bh(&pcpu->lock);
  		hlist_nulls_for_each_entry(h, n, &pcpu->unconfirmed, hnnode) {
  			ct = nf_ct_tuplehash_to_ctrack(h);
  			if (iter(ct, data))
  				set_bit(IPS_DYING_BIT, &ct->status);
  		}
  		spin_unlock_bh(&pcpu->lock);
d93c6258e   Florian Westphal   netfilter: conntr...
1416
  		cond_resched();
b7779d06f   Jesper Dangaard Brouer   netfilter: conntr...
1417
  	}
df0933dcb   Patrick McHardy   [NETFILTER]: kill...
1418
1419
  	return NULL;
  found:
c073e3fa8   Martin Josefsson   [NETFILTER]: nf_c...
1420
  	atomic_inc(&ct->ct_general.use);
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
1421
1422
  	spin_unlock(lockp);
  	local_bh_enable();
df0933dcb   Patrick McHardy   [NETFILTER]: kill...
1423
  	return ct;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1424
  }
400dad39d   Alexey Dobriyan   netfilter: netns ...
1425
1426
  void nf_ct_iterate_cleanup(struct net *net,
  			   int (*iter)(struct nf_conn *i, void *data),
c655bc689   Florian Westphal   netfilter: nf_con...
1427
  			   void *data, u32 portid, int report)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1428
  {
df0933dcb   Patrick McHardy   [NETFILTER]: kill...
1429
  	struct nf_conn *ct;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1430
  	unsigned int bucket = 0;
d93c6258e   Florian Westphal   netfilter: conntr...
1431
  	might_sleep();
88b68bc52   Florian Westphal   netfilter: conntr...
1432
1433
  	if (atomic_read(&net->ct.count) == 0)
  		return;
400dad39d   Alexey Dobriyan   netfilter: netns ...
1434
  	while ((ct = get_next_corpse(net, iter, data, &bucket)) != NULL) {
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1435
1436
  		/* Time to push up daises... */
  		if (del_timer(&ct->timeout))
c655bc689   Florian Westphal   netfilter: nf_con...
1437
  			nf_ct_delete(ct, portid, report);
02982c27b   Florian Westphal   netfilter: nf_con...
1438

9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1439
1440
1441
  		/* ... else the timer will get him soon. */
  
  		nf_ct_put(ct);
d93c6258e   Florian Westphal   netfilter: conntr...
1442
  		cond_resched();
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1443
1444
  	}
  }
13b183391   Patrick McHardy   [NETFILTER]: nf_c...
1445
  EXPORT_SYMBOL_GPL(nf_ct_iterate_cleanup);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1446

274d383b9   Pablo Neira Ayuso   netfilter: conntr...
1447
1448
1449
1450
  static int kill_all(struct nf_conn *i, void *data)
  {
  	return 1;
  }
d862a6622   Patrick McHardy   netfilter: nf_con...
1451
  void nf_ct_free_hashtable(void *hash, unsigned int size)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1452
  {
d862a6622   Patrick McHardy   netfilter: nf_con...
1453
  	if (is_vmalloc_addr(hash))
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1454
1455
  		vfree(hash);
  	else
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
1456
  		free_pages((unsigned long)hash,
f205c5e0c   Patrick McHardy   [NETFILTER]: nf_c...
1457
  			   get_order(sizeof(struct hlist_head) * size));
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1458
  }
ac565e5fc   Patrick McHardy   [NETFILTER]: nf_c...
1459
  EXPORT_SYMBOL_GPL(nf_ct_free_hashtable);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1460

b3c5163fe   Eric Dumazet   netfilter: nf_con...
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
  static int untrack_refs(void)
  {
  	int cnt = 0, cpu;
  
  	for_each_possible_cpu(cpu) {
  		struct nf_conn *ct = &per_cpu(nf_conntrack_untracked, cpu);
  
  		cnt += atomic_read(&ct->ct_general.use) - 1;
  	}
  	return cnt;
  }
f94161c1b   Gao feng   netfilter: nf_con...
1472
  void nf_conntrack_cleanup_start(void)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1473
  {
f94161c1b   Gao feng   netfilter: nf_con...
1474
1475
1476
1477
1478
1479
  	RCU_INIT_POINTER(ip_ct_attach, NULL);
  }
  
  void nf_conntrack_cleanup_end(void)
  {
  	RCU_INIT_POINTER(nf_ct_destroy, NULL);
b3c5163fe   Eric Dumazet   netfilter: nf_con...
1480
  	while (untrack_refs() > 0)
9edd7ca0a   Patrick McHardy   netfilter: nf_con...
1481
  		schedule();
56d52d489   Florian Westphal   netfilter: conntr...
1482
  	nf_ct_free_hashtable(nf_conntrack_hash, nf_conntrack_htable_size);
04d870017   Gao feng   netfilter: nf_ct_...
1483
  	nf_conntrack_proto_fini();
41d73ec05   Patrick McHardy   netfilter: nf_con...
1484
  	nf_conntrack_seqadj_fini();
5f69b8f52   Gao feng   netfilter: nf_ct_...
1485
  	nf_conntrack_labels_fini();
5e615b220   Gao feng   netfilter: nf_ct_...
1486
  	nf_conntrack_helper_fini();
8684094cf   Gao feng   netfilter: nf_ct_...
1487
  	nf_conntrack_timeout_fini();
3fe0f943d   Gao feng   netfilter: nf_ct_...
1488
  	nf_conntrack_ecache_fini();
73f4001a5   Gao feng   netfilter: nf_ct_...
1489
  	nf_conntrack_tstamp_fini();
b7ff3a1fa   Gao feng   netfilter: nf_ct_...
1490
  	nf_conntrack_acct_fini();
83b4dbe19   Gao feng   netfilter: nf_ct_...
1491
  	nf_conntrack_expect_fini();
775711497   Florian Westphal   netfilter: conntr...
1492
1493
  
  	kmem_cache_destroy(nf_conntrack_cachep);
08f6547d2   Alexey Dobriyan   netfilter: netns ...
1494
  }
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1495

f94161c1b   Gao feng   netfilter: nf_con...
1496
1497
1498
1499
1500
  /*
   * Mishearing the voices in his head, our hero wonders how he's
   * supposed to kill the mall.
   */
  void nf_conntrack_cleanup_net(struct net *net)
08f6547d2   Alexey Dobriyan   netfilter: netns ...
1501
  {
dece40e84   Vladimir Davydov   netfilter: nf_con...
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
  	LIST_HEAD(single);
  
  	list_add(&net->exit_list, &single);
  	nf_conntrack_cleanup_net_list(&single);
  }
  
  void nf_conntrack_cleanup_net_list(struct list_head *net_exit_list)
  {
  	int busy;
  	struct net *net;
f94161c1b   Gao feng   netfilter: nf_con...
1512
1513
1514
1515
1516
1517
  	/*
  	 * This makes sure all current packets have passed through
  	 *  netfilter framework.  Roll on, two-stage module
  	 *  delete...
  	 */
  	synchronize_net();
dece40e84   Vladimir Davydov   netfilter: nf_con...
1518
1519
1520
  i_see_dead_people:
  	busy = 0;
  	list_for_each_entry(net, net_exit_list, exit_list) {
c655bc689   Florian Westphal   netfilter: nf_con...
1521
  		nf_ct_iterate_cleanup(net, kill_all, NULL, 0, 0);
dece40e84   Vladimir Davydov   netfilter: nf_con...
1522
1523
1524
1525
  		if (atomic_read(&net->ct.count) != 0)
  			busy = 1;
  	}
  	if (busy) {
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1526
1527
1528
  		schedule();
  		goto i_see_dead_people;
  	}
dece40e84   Vladimir Davydov   netfilter: nf_con...
1529
  	list_for_each_entry(net, net_exit_list, exit_list) {
dece40e84   Vladimir Davydov   netfilter: nf_con...
1530
1531
1532
1533
1534
1535
  		nf_conntrack_proto_pernet_fini(net);
  		nf_conntrack_helper_pernet_fini(net);
  		nf_conntrack_ecache_pernet_fini(net);
  		nf_conntrack_tstamp_pernet_fini(net);
  		nf_conntrack_acct_pernet_fini(net);
  		nf_conntrack_expect_pernet_fini(net);
dece40e84   Vladimir Davydov   netfilter: nf_con...
1536
  		free_percpu(net->ct.stat);
b7779d06f   Jesper Dangaard Brouer   netfilter: conntr...
1537
  		free_percpu(net->ct.pcpu_lists);
dece40e84   Vladimir Davydov   netfilter: nf_con...
1538
  	}
08f6547d2   Alexey Dobriyan   netfilter: netns ...
1539
  }
d862a6622   Patrick McHardy   netfilter: nf_con...
1540
  void *nf_ct_alloc_hashtable(unsigned int *sizep, int nulls)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1541
  {
ea781f197   Eric Dumazet   netfilter: nf_con...
1542
1543
1544
  	struct hlist_nulls_head *hash;
  	unsigned int nr_slots, i;
  	size_t sz;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1545

ea781f197   Eric Dumazet   netfilter: nf_con...
1546
1547
1548
1549
1550
  	BUILD_BUG_ON(sizeof(struct hlist_nulls_head) != sizeof(struct hlist_head));
  	nr_slots = *sizep = roundup(*sizep, PAGE_SIZE / sizeof(struct hlist_nulls_head));
  	sz = nr_slots * sizeof(struct hlist_nulls_head);
  	hash = (void *)__get_free_pages(GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO,
  					get_order(sz));
f0ad46218   Pablo Neira Ayuso   netfilter: nf_con...
1551
  	if (!hash)
966567b76   Eric Dumazet   net: two vzalloc(...
1552
  		hash = vzalloc(sz);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1553

ea781f197   Eric Dumazet   netfilter: nf_con...
1554
1555
1556
  	if (hash && nulls)
  		for (i = 0; i < nr_slots; i++)
  			INIT_HLIST_NULLS_HEAD(&hash[i], i);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1557
1558
1559
  
  	return hash;
  }
ac565e5fc   Patrick McHardy   [NETFILTER]: nf_c...
1560
  EXPORT_SYMBOL_GPL(nf_ct_alloc_hashtable);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1561

3183ab899   Florian Westphal   netfilter: conntr...
1562
  int nf_conntrack_hash_resize(unsigned int hashsize)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1563
  {
3183ab899   Florian Westphal   netfilter: conntr...
1564
1565
  	int i, bucket;
  	unsigned int old_size;
ea781f197   Eric Dumazet   netfilter: nf_con...
1566
  	struct hlist_nulls_head *hash, *old_hash;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1567
  	struct nf_conntrack_tuple_hash *h;
5d0aa2ccd   Patrick McHardy   netfilter: nf_con...
1568
  	struct nf_conn *ct;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1569

9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1570
1571
  	if (!hashsize)
  		return -EINVAL;
d862a6622   Patrick McHardy   netfilter: nf_con...
1572
  	hash = nf_ct_alloc_hashtable(&hashsize, 1);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1573
1574
  	if (!hash)
  		return -ENOMEM;
3183ab899   Florian Westphal   netfilter: conntr...
1575
1576
1577
1578
1579
  	old_size = nf_conntrack_htable_size;
  	if (old_size == hashsize) {
  		nf_ct_free_hashtable(hash, hashsize);
  		return 0;
  	}
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
1580
1581
  	local_bh_disable();
  	nf_conntrack_all_lock();
a3efd8120   Florian Westphal   netfilter: conntr...
1582
  	write_seqcount_begin(&nf_conntrack_generation);
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
1583

76507f69c   Patrick McHardy   [NETFILTER]: nf_c...
1584
1585
1586
  	/* Lookups in the old hash might happen in parallel, which means we
  	 * might get false negatives during connection lookup. New connections
  	 * created because of a false negative won't make it into the hash
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
1587
  	 * though since that required taking the locks.
76507f69c   Patrick McHardy   [NETFILTER]: nf_c...
1588
  	 */
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
1589

56d52d489   Florian Westphal   netfilter: conntr...
1590
1591
1592
1593
  	for (i = 0; i < nf_conntrack_htable_size; i++) {
  		while (!hlist_nulls_empty(&nf_conntrack_hash[i])) {
  			h = hlist_nulls_entry(nf_conntrack_hash[i].first,
  					      struct nf_conntrack_tuple_hash, hnnode);
5d0aa2ccd   Patrick McHardy   netfilter: nf_con...
1594
  			ct = nf_ct_tuplehash_to_ctrack(h);
ea781f197   Eric Dumazet   netfilter: nf_con...
1595
  			hlist_nulls_del_rcu(&h->hnnode);
1b8c8a9f6   Florian Westphal   netfilter: conntr...
1596
1597
  			bucket = __hash_conntrack(nf_ct_net(ct),
  						  &h->tuple, hashsize);
ea781f197   Eric Dumazet   netfilter: nf_con...
1598
  			hlist_nulls_add_head_rcu(&h->hnnode, &hash[bucket]);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1599
1600
  		}
  	}
56d52d489   Florian Westphal   netfilter: conntr...
1601
1602
  	old_size = nf_conntrack_htable_size;
  	old_hash = nf_conntrack_hash;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1603

56d52d489   Florian Westphal   netfilter: conntr...
1604
1605
  	nf_conntrack_hash = hash;
  	nf_conntrack_htable_size = hashsize;
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
1606

a3efd8120   Florian Westphal   netfilter: conntr...
1607
  	write_seqcount_end(&nf_conntrack_generation);
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
1608
1609
  	nf_conntrack_all_unlock();
  	local_bh_enable();
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1610

5e3c61f98   Florian Westphal   netfilter: conntr...
1611
  	synchronize_net();
d862a6622   Patrick McHardy   netfilter: nf_con...
1612
  	nf_ct_free_hashtable(old_hash, old_size);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1613
1614
  	return 0;
  }
3183ab899   Florian Westphal   netfilter: conntr...
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
  
  int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp)
  {
  	unsigned int hashsize;
  	int rc;
  
  	if (current->nsproxy->net_ns != &init_net)
  		return -EOPNOTSUPP;
  
  	/* On boot, we can set this without any fancy locking. */
  	if (!nf_conntrack_htable_size)
  		return param_set_uint(val, kp);
  
  	rc = kstrtouint(val, 0, &hashsize);
  	if (rc)
  		return rc;
  
  	return nf_conntrack_hash_resize(hashsize);
  }
fae718dda   Patrick McHardy   [NETFILTER]: nf_c...
1634
  EXPORT_SYMBOL_GPL(nf_conntrack_set_hashsize);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1635

fae718dda   Patrick McHardy   [NETFILTER]: nf_c...
1636
  module_param_call(hashsize, nf_conntrack_set_hashsize, param_get_uint,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1637
  		  &nf_conntrack_htable_size, 0600);
5bfddbd46   Eric Dumazet   netfilter: nf_con...
1638
1639
  void nf_ct_untracked_status_or(unsigned long bits)
  {
b3c5163fe   Eric Dumazet   netfilter: nf_con...
1640
1641
1642
1643
  	int cpu;
  
  	for_each_possible_cpu(cpu)
  		per_cpu(nf_conntrack_untracked, cpu).status |= bits;
5bfddbd46   Eric Dumazet   netfilter: nf_con...
1644
1645
  }
  EXPORT_SYMBOL_GPL(nf_ct_untracked_status_or);
f94161c1b   Gao feng   netfilter: nf_con...
1646
  int nf_conntrack_init_start(void)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1647
  {
f205c5e0c   Patrick McHardy   [NETFILTER]: nf_c...
1648
  	int max_factor = 8;
0c5366b3a   Florian Westphal   netfilter: conntr...
1649
1650
  	int ret = -ENOMEM;
  	int i, cpu;
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
1651

a3efd8120   Florian Westphal   netfilter: conntr...
1652
  	seqcount_init(&nf_conntrack_generation);
d5d20912d   Eric Dumazet   netfilter: conntr...
1653
  	for (i = 0; i < CONNTRACK_LOCKS; i++)
93bb0ceb7   Jesper Dangaard Brouer   netfilter: conntr...
1654
  		spin_lock_init(&nf_conntrack_locks[i]);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1655

9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1656
  	if (!nf_conntrack_htable_size) {
88eab472e   Marcelo Leitner   netfilter: conntr...
1657
1658
1659
1660
1661
  		/* Idea from tcp.c: use 1/16384 of memory.
  		 * On i386: 32MB machine has 512 buckets.
  		 * >= 1GB machines have 16384 buckets.
  		 * >= 4GB machines have 65536 buckets.
  		 */
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1662
  		nf_conntrack_htable_size
4481374ce   Jan Beulich   mm: replace vario...
1663
  			= (((totalram_pages << PAGE_SHIFT) / 16384)
f205c5e0c   Patrick McHardy   [NETFILTER]: nf_c...
1664
  			   / sizeof(struct hlist_head));
88eab472e   Marcelo Leitner   netfilter: conntr...
1665
1666
1667
  		if (totalram_pages > (4 * (1024 * 1024 * 1024 / PAGE_SIZE)))
  			nf_conntrack_htable_size = 65536;
  		else if (totalram_pages > (1024 * 1024 * 1024 / PAGE_SIZE))
f205c5e0c   Patrick McHardy   [NETFILTER]: nf_c...
1668
1669
1670
1671
1672
1673
1674
1675
1676
  			nf_conntrack_htable_size = 16384;
  		if (nf_conntrack_htable_size < 32)
  			nf_conntrack_htable_size = 32;
  
  		/* Use a max. factor of four by default to get the same max as
  		 * with the old struct list_heads. When a table size is given
  		 * we use the old value of 8 to avoid reducing the max.
  		 * entries. */
  		max_factor = 4;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1677
  	}
56d52d489   Florian Westphal   netfilter: conntr...
1678
1679
1680
1681
  
  	nf_conntrack_hash = nf_ct_alloc_hashtable(&nf_conntrack_htable_size, 1);
  	if (!nf_conntrack_hash)
  		return -ENOMEM;
f205c5e0c   Patrick McHardy   [NETFILTER]: nf_c...
1682
  	nf_conntrack_max = max_factor * nf_conntrack_htable_size;
8e5105a0c   Patrick McHardy   [NETFILTER]: nf_c...
1683

0c5366b3a   Florian Westphal   netfilter: conntr...
1684
1685
  	nf_conntrack_cachep = kmem_cache_create("nf_conntrack",
  						sizeof(struct nf_conn), 0,
5a75cdeba   Florian Westphal   netfilter: conntr...
1686
  						SLAB_DESTROY_BY_RCU | SLAB_HWCACHE_ALIGN, NULL);
0c5366b3a   Florian Westphal   netfilter: conntr...
1687
1688
  	if (!nf_conntrack_cachep)
  		goto err_cachep;
654d0fbdc   Stephen Hemminger   netfilter: cleanu...
1689
1690
  	printk(KERN_INFO "nf_conntrack version %s (%u buckets, %d max)
  ",
8e5105a0c   Patrick McHardy   [NETFILTER]: nf_c...
1691
1692
  	       NF_CONNTRACK_VERSION, nf_conntrack_htable_size,
  	       nf_conntrack_max);
83b4dbe19   Gao feng   netfilter: nf_ct_...
1693
1694
1695
1696
  
  	ret = nf_conntrack_expect_init();
  	if (ret < 0)
  		goto err_expect;
b7ff3a1fa   Gao feng   netfilter: nf_ct_...
1697
1698
1699
  	ret = nf_conntrack_acct_init();
  	if (ret < 0)
  		goto err_acct;
73f4001a5   Gao feng   netfilter: nf_ct_...
1700
1701
1702
  	ret = nf_conntrack_tstamp_init();
  	if (ret < 0)
  		goto err_tstamp;
3fe0f943d   Gao feng   netfilter: nf_ct_...
1703
1704
1705
  	ret = nf_conntrack_ecache_init();
  	if (ret < 0)
  		goto err_ecache;
8684094cf   Gao feng   netfilter: nf_ct_...
1706
1707
1708
  	ret = nf_conntrack_timeout_init();
  	if (ret < 0)
  		goto err_timeout;
5e615b220   Gao feng   netfilter: nf_ct_...
1709
1710
1711
  	ret = nf_conntrack_helper_init();
  	if (ret < 0)
  		goto err_helper;
5f69b8f52   Gao feng   netfilter: nf_ct_...
1712
1713
1714
  	ret = nf_conntrack_labels_init();
  	if (ret < 0)
  		goto err_labels;
41d73ec05   Patrick McHardy   netfilter: nf_con...
1715
1716
1717
  	ret = nf_conntrack_seqadj_init();
  	if (ret < 0)
  		goto err_seqadj;
04d870017   Gao feng   netfilter: nf_ct_...
1718
1719
1720
  	ret = nf_conntrack_proto_init();
  	if (ret < 0)
  		goto err_proto;
9edd7ca0a   Patrick McHardy   netfilter: nf_con...
1721
  	/* Set up fake conntrack: to never be deleted, not in any hashes */
b3c5163fe   Eric Dumazet   netfilter: nf_con...
1722
1723
  	for_each_possible_cpu(cpu) {
  		struct nf_conn *ct = &per_cpu(nf_conntrack_untracked, cpu);
b3c5163fe   Eric Dumazet   netfilter: nf_con...
1724
1725
1726
  		write_pnet(&ct->ct_net, &init_net);
  		atomic_set(&ct->ct_general.use, 1);
  	}
9edd7ca0a   Patrick McHardy   netfilter: nf_con...
1727
  	/*  - and look it like as a confirmed connection */
5bfddbd46   Eric Dumazet   netfilter: nf_con...
1728
  	nf_ct_untracked_status_or(IPS_CONFIRMED | IPS_UNTRACKED);
08f6547d2   Alexey Dobriyan   netfilter: netns ...
1729
  	return 0;
04d870017   Gao feng   netfilter: nf_ct_...
1730
  err_proto:
41d73ec05   Patrick McHardy   netfilter: nf_con...
1731
1732
  	nf_conntrack_seqadj_fini();
  err_seqadj:
04d870017   Gao feng   netfilter: nf_ct_...
1733
  	nf_conntrack_labels_fini();
5f69b8f52   Gao feng   netfilter: nf_ct_...
1734
1735
  err_labels:
  	nf_conntrack_helper_fini();
5e615b220   Gao feng   netfilter: nf_ct_...
1736
1737
  err_helper:
  	nf_conntrack_timeout_fini();
8684094cf   Gao feng   netfilter: nf_ct_...
1738
1739
  err_timeout:
  	nf_conntrack_ecache_fini();
3fe0f943d   Gao feng   netfilter: nf_ct_...
1740
1741
  err_ecache:
  	nf_conntrack_tstamp_fini();
73f4001a5   Gao feng   netfilter: nf_ct_...
1742
1743
  err_tstamp:
  	nf_conntrack_acct_fini();
b7ff3a1fa   Gao feng   netfilter: nf_ct_...
1744
1745
  err_acct:
  	nf_conntrack_expect_fini();
83b4dbe19   Gao feng   netfilter: nf_ct_...
1746
  err_expect:
0c5366b3a   Florian Westphal   netfilter: conntr...
1747
1748
  	kmem_cache_destroy(nf_conntrack_cachep);
  err_cachep:
56d52d489   Florian Westphal   netfilter: conntr...
1749
  	nf_ct_free_hashtable(nf_conntrack_hash, nf_conntrack_htable_size);
08f6547d2   Alexey Dobriyan   netfilter: netns ...
1750
1751
  	return ret;
  }
f94161c1b   Gao feng   netfilter: nf_con...
1752
1753
1754
1755
1756
  void nf_conntrack_init_end(void)
  {
  	/* For use by REJECT target */
  	RCU_INIT_POINTER(ip_ct_attach, nf_conntrack_attach);
  	RCU_INIT_POINTER(nf_ct_destroy, destroy_conntrack);
f94161c1b   Gao feng   netfilter: nf_con...
1757
  }
8cc20198c   Eric Dumazet   netfilter: nf_con...
1758
1759
1760
1761
1762
  /*
   * We need to use special "null" values, not used in hash table
   */
  #define UNCONFIRMED_NULLS_VAL	((1<<30)+0)
  #define DYING_NULLS_VAL		((1<<30)+1)
252b3e8c1   Pablo Neira Ayuso   netfilter: xt_CT:...
1763
  #define TEMPLATE_NULLS_VAL	((1<<30)+2)
8cc20198c   Eric Dumazet   netfilter: nf_con...
1764

f94161c1b   Gao feng   netfilter: nf_con...
1765
  int nf_conntrack_init_net(struct net *net)
08f6547d2   Alexey Dobriyan   netfilter: netns ...
1766
  {
b7779d06f   Jesper Dangaard Brouer   netfilter: conntr...
1767
1768
  	int ret = -ENOMEM;
  	int cpu;
ceceae1b1   Yasuyuki Kozakai   [NETFILTER]: nf_c...
1769

08f6547d2   Alexey Dobriyan   netfilter: netns ...
1770
  	atomic_set(&net->ct.count, 0);
b7779d06f   Jesper Dangaard Brouer   netfilter: conntr...
1771
1772
1773
  
  	net->ct.pcpu_lists = alloc_percpu(struct ct_pcpu);
  	if (!net->ct.pcpu_lists)
08f6547d2   Alexey Dobriyan   netfilter: netns ...
1774
  		goto err_stat;
b7779d06f   Jesper Dangaard Brouer   netfilter: conntr...
1775
1776
1777
1778
1779
1780
1781
  
  	for_each_possible_cpu(cpu) {
  		struct ct_pcpu *pcpu = per_cpu_ptr(net->ct.pcpu_lists, cpu);
  
  		spin_lock_init(&pcpu->lock);
  		INIT_HLIST_NULLS_HEAD(&pcpu->unconfirmed, UNCONFIRMED_NULLS_VAL);
  		INIT_HLIST_NULLS_HEAD(&pcpu->dying, DYING_NULLS_VAL);
08f6547d2   Alexey Dobriyan   netfilter: netns ...
1782
  	}
5b3501faa   Eric Dumazet   netfilter: nf_con...
1783

b7779d06f   Jesper Dangaard Brouer   netfilter: conntr...
1784
1785
1786
  	net->ct.stat = alloc_percpu(struct ip_conntrack_stat);
  	if (!net->ct.stat)
  		goto err_pcpu_lists;
83b4dbe19   Gao feng   netfilter: nf_ct_...
1787
  	ret = nf_conntrack_expect_pernet_init(net);
08f6547d2   Alexey Dobriyan   netfilter: netns ...
1788
1789
  	if (ret < 0)
  		goto err_expect;
b7ff3a1fa   Gao feng   netfilter: nf_ct_...
1790
  	ret = nf_conntrack_acct_pernet_init(net);
584015727   Krzysztof Piotr Oledzki   netfilter: accoun...
1791
  	if (ret < 0)
08f6547d2   Alexey Dobriyan   netfilter: netns ...
1792
  		goto err_acct;
73f4001a5   Gao feng   netfilter: nf_ct_...
1793
  	ret = nf_conntrack_tstamp_pernet_init(net);
a992ca2a0   Pablo Neira Ayuso   netfilter: nf_con...
1794
1795
  	if (ret < 0)
  		goto err_tstamp;
3fe0f943d   Gao feng   netfilter: nf_ct_...
1796
  	ret = nf_conntrack_ecache_pernet_init(net);
a0891aa6a   Pablo Neira Ayuso   netfilter: conntr...
1797
1798
  	if (ret < 0)
  		goto err_ecache;
5e615b220   Gao feng   netfilter: nf_ct_...
1799
  	ret = nf_conntrack_helper_pernet_init(net);
a90068926   Eric Leblond   netfilter: nf_ct_...
1800
1801
  	if (ret < 0)
  		goto err_helper;
04d870017   Gao feng   netfilter: nf_ct_...
1802
  	ret = nf_conntrack_proto_pernet_init(net);
f94161c1b   Gao feng   netfilter: nf_con...
1803
1804
  	if (ret < 0)
  		goto err_proto;
08f6547d2   Alexey Dobriyan   netfilter: netns ...
1805
  	return 0;
c539f0171   Florian Westphal   netfilter: add co...
1806

f94161c1b   Gao feng   netfilter: nf_con...
1807
  err_proto:
5e615b220   Gao feng   netfilter: nf_ct_...
1808
  	nf_conntrack_helper_pernet_fini(net);
a90068926   Eric Leblond   netfilter: nf_ct_...
1809
  err_helper:
3fe0f943d   Gao feng   netfilter: nf_ct_...
1810
  	nf_conntrack_ecache_pernet_fini(net);
a0891aa6a   Pablo Neira Ayuso   netfilter: conntr...
1811
  err_ecache:
73f4001a5   Gao feng   netfilter: nf_ct_...
1812
  	nf_conntrack_tstamp_pernet_fini(net);
a992ca2a0   Pablo Neira Ayuso   netfilter: nf_con...
1813
  err_tstamp:
b7ff3a1fa   Gao feng   netfilter: nf_ct_...
1814
  	nf_conntrack_acct_pernet_fini(net);
08f6547d2   Alexey Dobriyan   netfilter: netns ...
1815
  err_acct:
83b4dbe19   Gao feng   netfilter: nf_ct_...
1816
  	nf_conntrack_expect_pernet_fini(net);
08f6547d2   Alexey Dobriyan   netfilter: netns ...
1817
  err_expect:
0d55af879   Alexey Dobriyan   netfilter: netns ...
1818
  	free_percpu(net->ct.stat);
b7779d06f   Jesper Dangaard Brouer   netfilter: conntr...
1819
1820
  err_pcpu_lists:
  	free_percpu(net->ct.pcpu_lists);
0d55af879   Alexey Dobriyan   netfilter: netns ...
1821
  err_stat:
08f6547d2   Alexey Dobriyan   netfilter: netns ...
1822
1823
  	return ret;
  }