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 		nf_ct_iterate_cleanup_net(net, nf_ct_tcp_fixup,
543 					  (void *)(unsigned long)nfproto, 0, 0);
544 
545 	return err;
546 }
547 
nf_ct_netns_do_put(struct net * net,u8 nfproto)548 static void nf_ct_netns_do_put(struct net *net, u8 nfproto)
549 {
550 	struct nf_conntrack_net *cnet = nf_ct_pernet(net);
551 
552 	mutex_lock(&nf_ct_proto_mutex);
553 	switch (nfproto) {
554 	case NFPROTO_IPV4:
555 		if (cnet->users4 && (--cnet->users4 == 0)) {
556 			nf_unregister_net_hooks(net, ipv4_conntrack_ops,
557 						ARRAY_SIZE(ipv4_conntrack_ops));
558 			nf_defrag_ipv4_disable(net);
559 		}
560 		break;
561 #if IS_ENABLED(CONFIG_IPV6)
562 	case NFPROTO_IPV6:
563 		if (cnet->users6 && (--cnet->users6 == 0)) {
564 			nf_unregister_net_hooks(net, ipv6_conntrack_ops,
565 						ARRAY_SIZE(ipv6_conntrack_ops));
566 			nf_defrag_ipv6_disable(net);
567 		}
568 		break;
569 #endif
570 	case NFPROTO_BRIDGE:
571 		if (!nf_ct_bridge_info)
572 			break;
573 		if (cnet->users_bridge && (--cnet->users_bridge == 0))
574 			nf_unregister_net_hooks(net, nf_ct_bridge_info->ops,
575 						nf_ct_bridge_info->ops_size);
576 
577 		module_put(nf_ct_bridge_info->me);
578 		break;
579 	}
580 	mutex_unlock(&nf_ct_proto_mutex);
581 }
582 
nf_ct_netns_inet_get(struct net * net)583 static int nf_ct_netns_inet_get(struct net *net)
584 {
585 	int err;
586 
587 	err = nf_ct_netns_do_get(net, NFPROTO_IPV4);
588 #if IS_ENABLED(CONFIG_IPV6)
589 	if (err < 0)
590 		goto err1;
591 	err = nf_ct_netns_do_get(net, NFPROTO_IPV6);
592 	if (err < 0)
593 		goto err2;
594 
595 	return err;
596 err2:
597 	nf_ct_netns_put(net, NFPROTO_IPV4);
598 err1:
599 #endif
600 	return err;
601 }
602 
nf_ct_netns_get(struct net * net,u8 nfproto)603 int nf_ct_netns_get(struct net *net, u8 nfproto)
604 {
605 	int err;
606 
607 	switch (nfproto) {
608 	case NFPROTO_INET:
609 		err = nf_ct_netns_inet_get(net);
610 		break;
611 	case NFPROTO_BRIDGE:
612 		err = nf_ct_netns_do_get(net, NFPROTO_BRIDGE);
613 		if (err < 0)
614 			return err;
615 
616 		err = nf_ct_netns_inet_get(net);
617 		if (err < 0) {
618 			nf_ct_netns_put(net, NFPROTO_BRIDGE);
619 			return err;
620 		}
621 		break;
622 	default:
623 		err = nf_ct_netns_do_get(net, nfproto);
624 		break;
625 	}
626 	return err;
627 }
628 EXPORT_SYMBOL_GPL(nf_ct_netns_get);
629 
nf_ct_netns_put(struct net * net,uint8_t nfproto)630 void nf_ct_netns_put(struct net *net, uint8_t nfproto)
631 {
632 	switch (nfproto) {
633 	case NFPROTO_BRIDGE:
634 		nf_ct_netns_do_put(net, NFPROTO_BRIDGE);
635 		fallthrough;
636 	case NFPROTO_INET:
637 		nf_ct_netns_do_put(net, NFPROTO_IPV4);
638 		nf_ct_netns_do_put(net, NFPROTO_IPV6);
639 		break;
640 	default:
641 		nf_ct_netns_do_put(net, nfproto);
642 		break;
643 	}
644 }
645 EXPORT_SYMBOL_GPL(nf_ct_netns_put);
646 
nf_ct_bridge_register(struct nf_ct_bridge_info * info)647 void nf_ct_bridge_register(struct nf_ct_bridge_info *info)
648 {
649 	WARN_ON(nf_ct_bridge_info);
650 	mutex_lock(&nf_ct_proto_mutex);
651 	nf_ct_bridge_info = info;
652 	mutex_unlock(&nf_ct_proto_mutex);
653 }
654 EXPORT_SYMBOL_GPL(nf_ct_bridge_register);
655 
nf_ct_bridge_unregister(struct nf_ct_bridge_info * info)656 void nf_ct_bridge_unregister(struct nf_ct_bridge_info *info)
657 {
658 	WARN_ON(!nf_ct_bridge_info);
659 	mutex_lock(&nf_ct_proto_mutex);
660 	nf_ct_bridge_info = NULL;
661 	mutex_unlock(&nf_ct_proto_mutex);
662 }
663 EXPORT_SYMBOL_GPL(nf_ct_bridge_unregister);
664 
nf_conntrack_proto_init(void)665 int nf_conntrack_proto_init(void)
666 {
667 	int ret;
668 
669 	ret = nf_register_sockopt(&so_getorigdst);
670 	if (ret < 0)
671 		return ret;
672 
673 #if IS_ENABLED(CONFIG_IPV6)
674 	ret = nf_register_sockopt(&so_getorigdst6);
675 	if (ret < 0)
676 		goto cleanup_sockopt;
677 #endif
678 
679 	return ret;
680 
681 #if IS_ENABLED(CONFIG_IPV6)
682 cleanup_sockopt:
683 	nf_unregister_sockopt(&so_getorigdst);
684 #endif
685 	return ret;
686 }
687 
nf_conntrack_proto_fini(void)688 void nf_conntrack_proto_fini(void)
689 {
690 	nf_unregister_sockopt(&so_getorigdst);
691 #if IS_ENABLED(CONFIG_IPV6)
692 	nf_unregister_sockopt(&so_getorigdst6);
693 #endif
694 }
695 
nf_conntrack_proto_pernet_init(struct net * net)696 void nf_conntrack_proto_pernet_init(struct net *net)
697 {
698 	nf_conntrack_generic_init_net(net);
699 	nf_conntrack_udp_init_net(net);
700 	nf_conntrack_tcp_init_net(net);
701 	nf_conntrack_icmp_init_net(net);
702 #if IS_ENABLED(CONFIG_IPV6)
703 	nf_conntrack_icmpv6_init_net(net);
704 #endif
705 #ifdef CONFIG_NF_CT_PROTO_DCCP
706 	nf_conntrack_dccp_init_net(net);
707 #endif
708 #ifdef CONFIG_NF_CT_PROTO_SCTP
709 	nf_conntrack_sctp_init_net(net);
710 #endif
711 #ifdef CONFIG_NF_CT_PROTO_GRE
712 	nf_conntrack_gre_init_net(net);
713 #endif
714 }
715 
716 module_param_call(hashsize, nf_conntrack_set_hashsize, param_get_uint,
717 		  &nf_conntrack_htable_size, 0600);
718 
719 MODULE_ALIAS("ip_conntrack");
720 MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET));
721 MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET6));
722 MODULE_LICENSE("GPL");
723