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