• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0
2 
3 #include <linux/types.h>
4 #include <linux/netfilter.h>
5 #include <linux/module.h>
6 #include <linux/slab.h>
7 #include <linux/mutex.h>
8 #include <linux/vmalloc.h>
9 #include <linux/stddef.h>
10 #include <linux/err.h>
11 #include <linux/percpu.h>
12 #include <linux/notifier.h>
13 #include <linux/kernel.h>
14 #include <linux/netdevice.h>
15 
16 #include <net/netfilter/nf_conntrack.h>
17 #include <net/netfilter/nf_conntrack_l4proto.h>
18 #include <net/netfilter/nf_conntrack_core.h>
19 #include <net/netfilter/nf_conntrack_bridge.h>
20 #include <net/netfilter/nf_log.h>
21 
22 #include <linux/ip.h>
23 #include <linux/icmp.h>
24 #include <linux/sysctl.h>
25 #include <net/route.h>
26 #include <net/ip.h>
27 
28 #include <linux/netfilter_ipv4.h>
29 #include <linux/netfilter_ipv6.h>
30 #include <linux/netfilter_ipv6/ip6_tables.h>
31 #include <net/netfilter/nf_conntrack_helper.h>
32 #include <net/netfilter/nf_conntrack_zones.h>
33 #include <net/netfilter/nf_conntrack_seqadj.h>
34 #include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
35 #include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
36 #include <net/netfilter/nf_nat_helper.h>
37 #include <net/netfilter/ipv4/nf_defrag_ipv4.h>
38 #include <net/netfilter/ipv6/nf_defrag_ipv6.h>
39 
40 #include <linux/ipv6.h>
41 #include <linux/in6.h>
42 #include <net/ipv6.h>
43 #include <net/inet_frag.h>
44 
45 static DEFINE_MUTEX(nf_ct_proto_mutex);
46 
47 #ifdef CONFIG_SYSCTL
48 __printf(4, 5)
nf_l4proto_log_invalid(const struct sk_buff * skb,const struct nf_hook_state * state,u8 protonum,const char * fmt,...)49 void nf_l4proto_log_invalid(const struct sk_buff *skb,
50 			    const struct nf_hook_state *state,
51 			    u8 protonum,
52 			    const char *fmt, ...)
53 {
54 	struct net *net = state->net;
55 	struct va_format vaf;
56 	va_list args;
57 
58 	if (net->ct.sysctl_log_invalid != protonum &&
59 	    net->ct.sysctl_log_invalid != IPPROTO_RAW)
60 		return;
61 
62 	va_start(args, fmt);
63 	vaf.fmt = fmt;
64 	vaf.va = &args;
65 
66 	nf_log_packet(net, state->pf, 0, skb, state->in, state->out,
67 		      NULL, "nf_ct_proto_%d: %pV ", protonum, &vaf);
68 	va_end(args);
69 }
70 EXPORT_SYMBOL_GPL(nf_l4proto_log_invalid);
71 
72 __printf(4, 5)
nf_ct_l4proto_log_invalid(const struct sk_buff * skb,const struct nf_conn * ct,const struct nf_hook_state * state,const char * fmt,...)73 void nf_ct_l4proto_log_invalid(const struct sk_buff *skb,
74 			       const struct nf_conn *ct,
75 			       const struct nf_hook_state *state,
76 			       const char *fmt, ...)
77 {
78 	struct va_format vaf;
79 	struct net *net;
80 	va_list args;
81 
82 	net = nf_ct_net(ct);
83 	if (likely(net->ct.sysctl_log_invalid == 0))
84 		return;
85 
86 	va_start(args, fmt);
87 	vaf.fmt = fmt;
88 	vaf.va = &args;
89 
90 	nf_l4proto_log_invalid(skb, state,
91 			       nf_ct_protonum(ct), "%pV", &vaf);
92 	va_end(args);
93 }
94 EXPORT_SYMBOL_GPL(nf_ct_l4proto_log_invalid);
95 #endif
96 
nf_ct_l4proto_find(u8 l4proto)97 const struct nf_conntrack_l4proto *nf_ct_l4proto_find(u8 l4proto)
98 {
99 	switch (l4proto) {
100 	case IPPROTO_UDP: return &nf_conntrack_l4proto_udp;
101 	case IPPROTO_TCP: return &nf_conntrack_l4proto_tcp;
102 	case IPPROTO_ICMP: return &nf_conntrack_l4proto_icmp;
103 #ifdef CONFIG_NF_CT_PROTO_DCCP
104 	case IPPROTO_DCCP: return &nf_conntrack_l4proto_dccp;
105 #endif
106 #ifdef CONFIG_NF_CT_PROTO_SCTP
107 	case IPPROTO_SCTP: return &nf_conntrack_l4proto_sctp;
108 #endif
109 #ifdef CONFIG_NF_CT_PROTO_UDPLITE
110 	case IPPROTO_UDPLITE: return &nf_conntrack_l4proto_udplite;
111 #endif
112 #ifdef CONFIG_NF_CT_PROTO_GRE
113 	case IPPROTO_GRE: return &nf_conntrack_l4proto_gre;
114 #endif
115 #if IS_ENABLED(CONFIG_IPV6)
116 	case IPPROTO_ICMPV6: return &nf_conntrack_l4proto_icmpv6;
117 #endif /* CONFIG_IPV6 */
118 	}
119 
120 	return &nf_conntrack_l4proto_generic;
121 };
122 EXPORT_SYMBOL_GPL(nf_ct_l4proto_find);
123 
nf_confirm(struct sk_buff * skb,unsigned int protoff,struct nf_conn * ct,enum ip_conntrack_info ctinfo)124 unsigned int nf_confirm(struct sk_buff *skb, unsigned int protoff,
125 			struct nf_conn *ct, enum ip_conntrack_info ctinfo)
126 {
127 	const struct nf_conn_help *help;
128 
129 	help = nfct_help(ct);
130 	if (help) {
131 		const struct nf_conntrack_helper *helper;
132 		int ret;
133 
134 		/* rcu_read_lock()ed by nf_hook_thresh */
135 		helper = rcu_dereference(help->helper);
136 		if (helper) {
137 			ret = helper->help(skb,
138 					   protoff,
139 					   ct, ctinfo);
140 			if (ret != NF_ACCEPT)
141 				return ret;
142 		}
143 	}
144 
145 	if (test_bit(IPS_SEQ_ADJUST_BIT, &ct->status) &&
146 	    !nf_is_loopback_packet(skb)) {
147 		if (!nf_ct_seq_adjust(skb, ct, ctinfo, protoff)) {
148 			NF_CT_STAT_INC_ATOMIC(nf_ct_net(ct), drop);
149 			return NF_DROP;
150 		}
151 	}
152 
153 	/* We've seen it coming out the other side: confirm it */
154 	return nf_conntrack_confirm(skb);
155 }
156 EXPORT_SYMBOL_GPL(nf_confirm);
157 
in_vrf_postrouting(const struct nf_hook_state * state)158 static bool in_vrf_postrouting(const struct nf_hook_state *state)
159 {
160 #if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV)
161 	if (state->hook == NF_INET_POST_ROUTING &&
162 	    netif_is_l3_master(state->out))
163 		return true;
164 #endif
165 	return false;
166 }
167 
ipv4_confirm(void * priv,struct sk_buff * skb,const struct nf_hook_state * state)168 static unsigned int ipv4_confirm(void *priv,
169 				 struct sk_buff *skb,
170 				 const struct nf_hook_state *state)
171 {
172 	enum ip_conntrack_info ctinfo;
173 	struct nf_conn *ct;
174 
175 	ct = nf_ct_get(skb, &ctinfo);
176 	if (!ct || ctinfo == IP_CT_RELATED_REPLY)
177 		return nf_conntrack_confirm(skb);
178 
179 	if (in_vrf_postrouting(state))
180 		return NF_ACCEPT;
181 
182 	return nf_confirm(skb,
183 			  skb_network_offset(skb) + ip_hdrlen(skb),
184 			  ct, ctinfo);
185 }
186 
ipv4_conntrack_in(void * priv,struct sk_buff * skb,const struct nf_hook_state * state)187 static unsigned int ipv4_conntrack_in(void *priv,
188 				      struct sk_buff *skb,
189 				      const struct nf_hook_state *state)
190 {
191 	return nf_conntrack_in(skb, state);
192 }
193 
ipv4_conntrack_local(void * priv,struct sk_buff * skb,const struct nf_hook_state * state)194 static unsigned int ipv4_conntrack_local(void *priv,
195 					 struct sk_buff *skb,
196 					 const struct nf_hook_state *state)
197 {
198 	if (ip_is_fragment(ip_hdr(skb))) { /* IP_NODEFRAG setsockopt set */
199 		enum ip_conntrack_info ctinfo;
200 		struct nf_conn *tmpl;
201 
202 		tmpl = nf_ct_get(skb, &ctinfo);
203 		if (tmpl && nf_ct_is_template(tmpl)) {
204 			/* when skipping ct, clear templates to avoid fooling
205 			 * later targets/matches
206 			 */
207 			skb->_nfct = 0;
208 			nf_ct_put(tmpl);
209 		}
210 		return NF_ACCEPT;
211 	}
212 
213 	return nf_conntrack_in(skb, state);
214 }
215 
216 /* Connection tracking may drop packets, but never alters them, so
217  * make it the first hook.
218  */
219 static const struct nf_hook_ops ipv4_conntrack_ops[] = {
220 	{
221 		.hook		= ipv4_conntrack_in,
222 		.pf		= NFPROTO_IPV4,
223 		.hooknum	= NF_INET_PRE_ROUTING,
224 		.priority	= NF_IP_PRI_CONNTRACK,
225 	},
226 	{
227 		.hook		= ipv4_conntrack_local,
228 		.pf		= NFPROTO_IPV4,
229 		.hooknum	= NF_INET_LOCAL_OUT,
230 		.priority	= NF_IP_PRI_CONNTRACK,
231 	},
232 	{
233 		.hook		= ipv4_confirm,
234 		.pf		= NFPROTO_IPV4,
235 		.hooknum	= NF_INET_POST_ROUTING,
236 		.priority	= NF_IP_PRI_CONNTRACK_CONFIRM,
237 	},
238 	{
239 		.hook		= ipv4_confirm,
240 		.pf		= NFPROTO_IPV4,
241 		.hooknum	= NF_INET_LOCAL_IN,
242 		.priority	= NF_IP_PRI_CONNTRACK_CONFIRM,
243 	},
244 };
245 
246 /* Fast function for those who don't want to parse /proc (and I don't
247  * blame them).
248  * Reversing the socket's dst/src point of view gives us the reply
249  * mapping.
250  */
251 static int
getorigdst(struct sock * sk,int optval,void __user * user,int * len)252 getorigdst(struct sock *sk, int optval, void __user *user, int *len)
253 {
254 	const struct inet_sock *inet = inet_sk(sk);
255 	const struct nf_conntrack_tuple_hash *h;
256 	struct nf_conntrack_tuple tuple;
257 
258 	memset(&tuple, 0, sizeof(tuple));
259 
260 	lock_sock(sk);
261 	tuple.src.u3.ip = inet->inet_rcv_saddr;
262 	tuple.src.u.tcp.port = inet->inet_sport;
263 	tuple.dst.u3.ip = inet->inet_daddr;
264 	tuple.dst.u.tcp.port = inet->inet_dport;
265 	tuple.src.l3num = PF_INET;
266 	tuple.dst.protonum = sk->sk_protocol;
267 	release_sock(sk);
268 
269 	/* We only do TCP and SCTP at the moment: is there a better way? */
270 	if (tuple.dst.protonum != IPPROTO_TCP &&
271 	    tuple.dst.protonum != IPPROTO_SCTP) {
272 		pr_debug("SO_ORIGINAL_DST: Not a TCP/SCTP socket\n");
273 		return -ENOPROTOOPT;
274 	}
275 
276 	if ((unsigned int)*len < sizeof(struct sockaddr_in)) {
277 		pr_debug("SO_ORIGINAL_DST: len %d not %zu\n",
278 			 *len, sizeof(struct sockaddr_in));
279 		return -EINVAL;
280 	}
281 
282 	h = nf_conntrack_find_get(sock_net(sk), &nf_ct_zone_dflt, &tuple);
283 	if (h) {
284 		struct sockaddr_in sin;
285 		struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h);
286 
287 		sin.sin_family = AF_INET;
288 		sin.sin_port = ct->tuplehash[IP_CT_DIR_ORIGINAL]
289 			.tuple.dst.u.tcp.port;
290 		sin.sin_addr.s_addr = ct->tuplehash[IP_CT_DIR_ORIGINAL]
291 			.tuple.dst.u3.ip;
292 		memset(sin.sin_zero, 0, sizeof(sin.sin_zero));
293 
294 		pr_debug("SO_ORIGINAL_DST: %pI4 %u\n",
295 			 &sin.sin_addr.s_addr, ntohs(sin.sin_port));
296 		nf_ct_put(ct);
297 		if (copy_to_user(user, &sin, sizeof(sin)) != 0)
298 			return -EFAULT;
299 		else
300 			return 0;
301 	}
302 	pr_debug("SO_ORIGINAL_DST: Can't find %pI4/%u-%pI4/%u.\n",
303 		 &tuple.src.u3.ip, ntohs(tuple.src.u.tcp.port),
304 		 &tuple.dst.u3.ip, ntohs(tuple.dst.u.tcp.port));
305 	return -ENOENT;
306 }
307 
308 static struct nf_sockopt_ops so_getorigdst = {
309 	.pf		= PF_INET,
310 	.get_optmin	= SO_ORIGINAL_DST,
311 	.get_optmax	= SO_ORIGINAL_DST + 1,
312 	.get		= getorigdst,
313 	.owner		= THIS_MODULE,
314 };
315 
316 #if IS_ENABLED(CONFIG_IPV6)
317 static int
ipv6_getorigdst(struct sock * sk,int optval,void __user * user,int * len)318 ipv6_getorigdst(struct sock *sk, int optval, void __user *user, int *len)
319 {
320 	struct nf_conntrack_tuple tuple = { .src.l3num = NFPROTO_IPV6 };
321 	const struct ipv6_pinfo *inet6 = inet6_sk(sk);
322 	const struct inet_sock *inet = inet_sk(sk);
323 	const struct nf_conntrack_tuple_hash *h;
324 	struct sockaddr_in6 sin6;
325 	struct nf_conn *ct;
326 	__be32 flow_label;
327 	int bound_dev_if;
328 
329 	lock_sock(sk);
330 	tuple.src.u3.in6 = sk->sk_v6_rcv_saddr;
331 	tuple.src.u.tcp.port = inet->inet_sport;
332 	tuple.dst.u3.in6 = sk->sk_v6_daddr;
333 	tuple.dst.u.tcp.port = inet->inet_dport;
334 	tuple.dst.protonum = sk->sk_protocol;
335 	bound_dev_if = sk->sk_bound_dev_if;
336 	flow_label = inet6->flow_label;
337 	release_sock(sk);
338 
339 	if (tuple.dst.protonum != IPPROTO_TCP &&
340 	    tuple.dst.protonum != IPPROTO_SCTP)
341 		return -ENOPROTOOPT;
342 
343 	if (*len < 0 || (unsigned int)*len < sizeof(sin6))
344 		return -EINVAL;
345 
346 	h = nf_conntrack_find_get(sock_net(sk), &nf_ct_zone_dflt, &tuple);
347 	if (!h) {
348 		pr_debug("IP6T_SO_ORIGINAL_DST: Can't find %pI6c/%u-%pI6c/%u.\n",
349 			 &tuple.src.u3.ip6, ntohs(tuple.src.u.tcp.port),
350 			 &tuple.dst.u3.ip6, ntohs(tuple.dst.u.tcp.port));
351 		return -ENOENT;
352 	}
353 
354 	ct = nf_ct_tuplehash_to_ctrack(h);
355 
356 	sin6.sin6_family = AF_INET6;
357 	sin6.sin6_port = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u.tcp.port;
358 	sin6.sin6_flowinfo = flow_label & IPV6_FLOWINFO_MASK;
359 	memcpy(&sin6.sin6_addr,
360 	       &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.in6,
361 	       sizeof(sin6.sin6_addr));
362 
363 	nf_ct_put(ct);
364 	sin6.sin6_scope_id = ipv6_iface_scope_id(&sin6.sin6_addr, bound_dev_if);
365 	return copy_to_user(user, &sin6, sizeof(sin6)) ? -EFAULT : 0;
366 }
367 
368 static struct nf_sockopt_ops so_getorigdst6 = {
369 	.pf		= NFPROTO_IPV6,
370 	.get_optmin	= IP6T_SO_ORIGINAL_DST,
371 	.get_optmax	= IP6T_SO_ORIGINAL_DST + 1,
372 	.get		= ipv6_getorigdst,
373 	.owner		= THIS_MODULE,
374 };
375 
ipv6_confirm(void * priv,struct sk_buff * skb,const struct nf_hook_state * state)376 static unsigned int ipv6_confirm(void *priv,
377 				 struct sk_buff *skb,
378 				 const struct nf_hook_state *state)
379 {
380 	struct nf_conn *ct;
381 	enum ip_conntrack_info ctinfo;
382 	unsigned char pnum = ipv6_hdr(skb)->nexthdr;
383 	__be16 frag_off;
384 	int protoff;
385 
386 	ct = nf_ct_get(skb, &ctinfo);
387 	if (!ct || ctinfo == IP_CT_RELATED_REPLY)
388 		return nf_conntrack_confirm(skb);
389 
390 	if (in_vrf_postrouting(state))
391 		return NF_ACCEPT;
392 
393 	protoff = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &pnum,
394 				   &frag_off);
395 	if (protoff < 0 || (frag_off & htons(~0x7)) != 0) {
396 		pr_debug("proto header not found\n");
397 		return nf_conntrack_confirm(skb);
398 	}
399 
400 	return nf_confirm(skb, protoff, ct, ctinfo);
401 }
402 
ipv6_conntrack_in(void * priv,struct sk_buff * skb,const struct nf_hook_state * state)403 static unsigned int ipv6_conntrack_in(void *priv,
404 				      struct sk_buff *skb,
405 				      const struct nf_hook_state *state)
406 {
407 	return nf_conntrack_in(skb, state);
408 }
409 
ipv6_conntrack_local(void * priv,struct sk_buff * skb,const struct nf_hook_state * state)410 static unsigned int ipv6_conntrack_local(void *priv,
411 					 struct sk_buff *skb,
412 					 const struct nf_hook_state *state)
413 {
414 	return nf_conntrack_in(skb, state);
415 }
416 
417 static const struct nf_hook_ops ipv6_conntrack_ops[] = {
418 	{
419 		.hook		= ipv6_conntrack_in,
420 		.pf		= NFPROTO_IPV6,
421 		.hooknum	= NF_INET_PRE_ROUTING,
422 		.priority	= NF_IP6_PRI_CONNTRACK,
423 	},
424 	{
425 		.hook		= ipv6_conntrack_local,
426 		.pf		= NFPROTO_IPV6,
427 		.hooknum	= NF_INET_LOCAL_OUT,
428 		.priority	= NF_IP6_PRI_CONNTRACK,
429 	},
430 	{
431 		.hook		= ipv6_confirm,
432 		.pf		= NFPROTO_IPV6,
433 		.hooknum	= NF_INET_POST_ROUTING,
434 		.priority	= NF_IP6_PRI_LAST,
435 	},
436 	{
437 		.hook		= ipv6_confirm,
438 		.pf		= NFPROTO_IPV6,
439 		.hooknum	= NF_INET_LOCAL_IN,
440 		.priority	= NF_IP6_PRI_LAST - 1,
441 	},
442 };
443 #endif
444 
nf_ct_tcp_fixup(struct nf_conn * ct,void * _nfproto)445 static int nf_ct_tcp_fixup(struct nf_conn *ct, void *_nfproto)
446 {
447 	u8 nfproto = (unsigned long)_nfproto;
448 
449 	if (nf_ct_l3num(ct) != nfproto)
450 		return 0;
451 
452 	if (nf_ct_protonum(ct) == IPPROTO_TCP &&
453 	    ct->proto.tcp.state == TCP_CONNTRACK_ESTABLISHED) {
454 		ct->proto.tcp.seen[0].td_maxwin = 0;
455 		ct->proto.tcp.seen[1].td_maxwin = 0;
456 	}
457 
458 	return 0;
459 }
460 
461 static struct nf_ct_bridge_info *nf_ct_bridge_info;
462 
nf_ct_netns_do_get(struct net * net,u8 nfproto)463 static int nf_ct_netns_do_get(struct net *net, u8 nfproto)
464 {
465 	struct nf_conntrack_net *cnet = nf_ct_pernet(net);
466 	bool fixup_needed = false, retry = true;
467 	int err = 0;
468 retry:
469 	mutex_lock(&nf_ct_proto_mutex);
470 
471 	switch (nfproto) {
472 	case NFPROTO_IPV4:
473 		cnet->users4++;
474 		if (cnet->users4 > 1)
475 			goto out_unlock;
476 		err = nf_defrag_ipv4_enable(net);
477 		if (err) {
478 			cnet->users4 = 0;
479 			goto out_unlock;
480 		}
481 
482 		err = nf_register_net_hooks(net, ipv4_conntrack_ops,
483 					    ARRAY_SIZE(ipv4_conntrack_ops));
484 		if (err)
485 			cnet->users4 = 0;
486 		else
487 			fixup_needed = true;
488 		break;
489 #if IS_ENABLED(CONFIG_IPV6)
490 	case NFPROTO_IPV6:
491 		cnet->users6++;
492 		if (cnet->users6 > 1)
493 			goto out_unlock;
494 		err = nf_defrag_ipv6_enable(net);
495 		if (err < 0) {
496 			cnet->users6 = 0;
497 			goto out_unlock;
498 		}
499 
500 		err = nf_register_net_hooks(net, ipv6_conntrack_ops,
501 					    ARRAY_SIZE(ipv6_conntrack_ops));
502 		if (err)
503 			cnet->users6 = 0;
504 		else
505 			fixup_needed = true;
506 		break;
507 #endif
508 	case NFPROTO_BRIDGE:
509 		if (!nf_ct_bridge_info) {
510 			if (!retry) {
511 				err = -EPROTO;
512 				goto out_unlock;
513 			}
514 			mutex_unlock(&nf_ct_proto_mutex);
515 			request_module("nf_conntrack_bridge");
516 			retry = false;
517 			goto retry;
518 		}
519 		if (!try_module_get(nf_ct_bridge_info->me)) {
520 			err = -EPROTO;
521 			goto out_unlock;
522 		}
523 		cnet->users_bridge++;
524 		if (cnet->users_bridge > 1)
525 			goto out_unlock;
526 
527 		err = nf_register_net_hooks(net, nf_ct_bridge_info->ops,
528 					    nf_ct_bridge_info->ops_size);
529 		if (err)
530 			cnet->users_bridge = 0;
531 		else
532 			fixup_needed = true;
533 		break;
534 	default:
535 		err = -EPROTO;
536 		break;
537 	}
538  out_unlock:
539 	mutex_unlock(&nf_ct_proto_mutex);
540 
541 	if (fixup_needed) {
542 		struct nf_ct_iter_data iter_data = {
543 			.net	= net,
544 			.data	= (void *)(unsigned long)nfproto,
545 		};
546 		nf_ct_iterate_cleanup_net(nf_ct_tcp_fixup, &iter_data);
547 	}
548 
549 	return err;
550 }
551 
nf_ct_netns_do_put(struct net * net,u8 nfproto)552 static void nf_ct_netns_do_put(struct net *net, u8 nfproto)
553 {
554 	struct nf_conntrack_net *cnet = nf_ct_pernet(net);
555 
556 	mutex_lock(&nf_ct_proto_mutex);
557 	switch (nfproto) {
558 	case NFPROTO_IPV4:
559 		if (cnet->users4 && (--cnet->users4 == 0)) {
560 			nf_unregister_net_hooks(net, ipv4_conntrack_ops,
561 						ARRAY_SIZE(ipv4_conntrack_ops));
562 			nf_defrag_ipv4_disable(net);
563 		}
564 		break;
565 #if IS_ENABLED(CONFIG_IPV6)
566 	case NFPROTO_IPV6:
567 		if (cnet->users6 && (--cnet->users6 == 0)) {
568 			nf_unregister_net_hooks(net, ipv6_conntrack_ops,
569 						ARRAY_SIZE(ipv6_conntrack_ops));
570 			nf_defrag_ipv6_disable(net);
571 		}
572 		break;
573 #endif
574 	case NFPROTO_BRIDGE:
575 		if (!nf_ct_bridge_info)
576 			break;
577 		if (cnet->users_bridge && (--cnet->users_bridge == 0))
578 			nf_unregister_net_hooks(net, nf_ct_bridge_info->ops,
579 						nf_ct_bridge_info->ops_size);
580 
581 		module_put(nf_ct_bridge_info->me);
582 		break;
583 	}
584 	mutex_unlock(&nf_ct_proto_mutex);
585 }
586 
nf_ct_netns_inet_get(struct net * net)587 static int nf_ct_netns_inet_get(struct net *net)
588 {
589 	int err;
590 
591 	err = nf_ct_netns_do_get(net, NFPROTO_IPV4);
592 #if IS_ENABLED(CONFIG_IPV6)
593 	if (err < 0)
594 		goto err1;
595 	err = nf_ct_netns_do_get(net, NFPROTO_IPV6);
596 	if (err < 0)
597 		goto err2;
598 
599 	return err;
600 err2:
601 	nf_ct_netns_put(net, NFPROTO_IPV4);
602 err1:
603 #endif
604 	return err;
605 }
606 
nf_ct_netns_get(struct net * net,u8 nfproto)607 int nf_ct_netns_get(struct net *net, u8 nfproto)
608 {
609 	int err;
610 
611 	switch (nfproto) {
612 	case NFPROTO_INET:
613 		err = nf_ct_netns_inet_get(net);
614 		break;
615 	case NFPROTO_BRIDGE:
616 		err = nf_ct_netns_do_get(net, NFPROTO_BRIDGE);
617 		if (err < 0)
618 			return err;
619 
620 		err = nf_ct_netns_inet_get(net);
621 		if (err < 0) {
622 			nf_ct_netns_put(net, NFPROTO_BRIDGE);
623 			return err;
624 		}
625 		break;
626 	default:
627 		err = nf_ct_netns_do_get(net, nfproto);
628 		break;
629 	}
630 	return err;
631 }
632 EXPORT_SYMBOL_GPL(nf_ct_netns_get);
633 
nf_ct_netns_put(struct net * net,uint8_t nfproto)634 void nf_ct_netns_put(struct net *net, uint8_t nfproto)
635 {
636 	switch (nfproto) {
637 	case NFPROTO_BRIDGE:
638 		nf_ct_netns_do_put(net, NFPROTO_BRIDGE);
639 		fallthrough;
640 	case NFPROTO_INET:
641 		nf_ct_netns_do_put(net, NFPROTO_IPV4);
642 		nf_ct_netns_do_put(net, NFPROTO_IPV6);
643 		break;
644 	default:
645 		nf_ct_netns_do_put(net, nfproto);
646 		break;
647 	}
648 }
649 EXPORT_SYMBOL_GPL(nf_ct_netns_put);
650 
nf_ct_bridge_register(struct nf_ct_bridge_info * info)651 void nf_ct_bridge_register(struct nf_ct_bridge_info *info)
652 {
653 	WARN_ON(nf_ct_bridge_info);
654 	mutex_lock(&nf_ct_proto_mutex);
655 	nf_ct_bridge_info = info;
656 	mutex_unlock(&nf_ct_proto_mutex);
657 }
658 EXPORT_SYMBOL_GPL(nf_ct_bridge_register);
659 
nf_ct_bridge_unregister(struct nf_ct_bridge_info * info)660 void nf_ct_bridge_unregister(struct nf_ct_bridge_info *info)
661 {
662 	WARN_ON(!nf_ct_bridge_info);
663 	mutex_lock(&nf_ct_proto_mutex);
664 	nf_ct_bridge_info = NULL;
665 	mutex_unlock(&nf_ct_proto_mutex);
666 }
667 EXPORT_SYMBOL_GPL(nf_ct_bridge_unregister);
668 
nf_conntrack_proto_init(void)669 int nf_conntrack_proto_init(void)
670 {
671 	int ret;
672 
673 	ret = nf_register_sockopt(&so_getorigdst);
674 	if (ret < 0)
675 		return ret;
676 
677 #if IS_ENABLED(CONFIG_IPV6)
678 	ret = nf_register_sockopt(&so_getorigdst6);
679 	if (ret < 0)
680 		goto cleanup_sockopt;
681 #endif
682 
683 	return ret;
684 
685 #if IS_ENABLED(CONFIG_IPV6)
686 cleanup_sockopt:
687 	nf_unregister_sockopt(&so_getorigdst);
688 #endif
689 	return ret;
690 }
691 
nf_conntrack_proto_fini(void)692 void nf_conntrack_proto_fini(void)
693 {
694 	nf_unregister_sockopt(&so_getorigdst);
695 #if IS_ENABLED(CONFIG_IPV6)
696 	nf_unregister_sockopt(&so_getorigdst6);
697 #endif
698 }
699 
nf_conntrack_proto_pernet_init(struct net * net)700 void nf_conntrack_proto_pernet_init(struct net *net)
701 {
702 	nf_conntrack_generic_init_net(net);
703 	nf_conntrack_udp_init_net(net);
704 	nf_conntrack_tcp_init_net(net);
705 	nf_conntrack_icmp_init_net(net);
706 #if IS_ENABLED(CONFIG_IPV6)
707 	nf_conntrack_icmpv6_init_net(net);
708 #endif
709 #ifdef CONFIG_NF_CT_PROTO_DCCP
710 	nf_conntrack_dccp_init_net(net);
711 #endif
712 #ifdef CONFIG_NF_CT_PROTO_SCTP
713 	nf_conntrack_sctp_init_net(net);
714 #endif
715 #ifdef CONFIG_NF_CT_PROTO_GRE
716 	nf_conntrack_gre_init_net(net);
717 #endif
718 }
719 
720 module_param_call(hashsize, nf_conntrack_set_hashsize, param_get_uint,
721 		  &nf_conntrack_htable_size, 0600);
722 
723 MODULE_ALIAS("ip_conntrack");
724 MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET));
725 MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET6));
726 MODULE_LICENSE("GPL");
727