1 // SPDX-License-Identifier: GPL-2.0 2 #include <linux/types.h> 3 #include <linux/netfilter.h> 4 #include <linux/slab.h> 5 #include <linux/module.h> 6 #include <linux/skbuff.h> 7 #include <linux/proc_fs.h> 8 #include <linux/seq_file.h> 9 #include <linux/percpu.h> 10 #include <linux/netdevice.h> 11 #include <linux/security.h> 12 #include <net/net_namespace.h> 13 #ifdef CONFIG_SYSCTL 14 #include <linux/sysctl.h> 15 #endif 16 17 #include <net/netfilter/nf_conntrack.h> 18 #include <net/netfilter/nf_conntrack_core.h> 19 #include <net/netfilter/nf_conntrack_l4proto.h> 20 #include <net/netfilter/nf_conntrack_expect.h> 21 #include <net/netfilter/nf_conntrack_helper.h> 22 #include <net/netfilter/nf_conntrack_acct.h> 23 #include <net/netfilter/nf_conntrack_zones.h> 24 #include <net/netfilter/nf_conntrack_timestamp.h> 25 #include <linux/rculist_nulls.h> 26 27 static bool enable_hooks __read_mostly; 28 MODULE_PARM_DESC(enable_hooks, "Always enable conntrack hooks"); 29 module_param(enable_hooks, bool, 0000); 30 31 unsigned int nf_conntrack_net_id __read_mostly; 32 33 #ifdef CONFIG_NF_CONNTRACK_PROCFS 34 void 35 print_tuple(struct seq_file *s, const struct nf_conntrack_tuple *tuple, 36 const struct nf_conntrack_l4proto *l4proto) 37 { 38 switch (tuple->src.l3num) { 39 case NFPROTO_IPV4: 40 seq_printf(s, "src=%pI4 dst=%pI4 ", 41 &tuple->src.u3.ip, &tuple->dst.u3.ip); 42 break; 43 case NFPROTO_IPV6: 44 seq_printf(s, "src=%pI6 dst=%pI6 ", 45 tuple->src.u3.ip6, tuple->dst.u3.ip6); 46 break; 47 default: 48 break; 49 } 50 51 switch (l4proto->l4proto) { 52 case IPPROTO_ICMP: 53 seq_printf(s, "type=%u code=%u id=%u ", 54 tuple->dst.u.icmp.type, 55 tuple->dst.u.icmp.code, 56 ntohs(tuple->src.u.icmp.id)); 57 break; 58 case IPPROTO_TCP: 59 seq_printf(s, "sport=%hu dport=%hu ", 60 ntohs(tuple->src.u.tcp.port), 61 ntohs(tuple->dst.u.tcp.port)); 62 break; 63 case IPPROTO_UDPLITE: /* fallthrough */ 64 case IPPROTO_UDP: 65 seq_printf(s, "sport=%hu dport=%hu ", 66 ntohs(tuple->src.u.udp.port), 67 ntohs(tuple->dst.u.udp.port)); 68 69 break; 70 case IPPROTO_DCCP: 71 seq_printf(s, "sport=%hu dport=%hu ", 72 ntohs(tuple->src.u.dccp.port), 73 ntohs(tuple->dst.u.dccp.port)); 74 break; 75 case IPPROTO_SCTP: 76 seq_printf(s, "sport=%hu dport=%hu ", 77 ntohs(tuple->src.u.sctp.port), 78 ntohs(tuple->dst.u.sctp.port)); 79 break; 80 case IPPROTO_ICMPV6: 81 seq_printf(s, "type=%u code=%u id=%u ", 82 tuple->dst.u.icmp.type, 83 tuple->dst.u.icmp.code, 84 ntohs(tuple->src.u.icmp.id)); 85 break; 86 case IPPROTO_GRE: 87 seq_printf(s, "srckey=0x%x dstkey=0x%x ", 88 ntohs(tuple->src.u.gre.key), 89 ntohs(tuple->dst.u.gre.key)); 90 break; 91 default: 92 break; 93 } 94 } 95 EXPORT_SYMBOL_GPL(print_tuple); 96 97 struct ct_iter_state { 98 struct seq_net_private p; 99 struct hlist_nulls_head *hash; 100 unsigned int htable_size; 101 unsigned int bucket; 102 u_int64_t time_now; 103 }; 104 105 static struct hlist_nulls_node *ct_get_first(struct seq_file *seq) 106 { 107 struct ct_iter_state *st = seq->private; 108 struct hlist_nulls_node *n; 109 110 for (st->bucket = 0; 111 st->bucket < st->htable_size; 112 st->bucket++) { 113 n = rcu_dereference( 114 hlist_nulls_first_rcu(&st->hash[st->bucket])); 115 if (!is_a_nulls(n)) 116 return n; 117 } 118 return NULL; 119 } 120 121 static struct hlist_nulls_node *ct_get_next(struct seq_file *seq, 122 struct hlist_nulls_node *head) 123 { 124 struct ct_iter_state *st = seq->private; 125 126 head = rcu_dereference(hlist_nulls_next_rcu(head)); 127 while (is_a_nulls(head)) { 128 if (likely(get_nulls_value(head) == st->bucket)) { 129 if (++st->bucket >= st->htable_size) 130 return NULL; 131 } 132 head = rcu_dereference( 133 hlist_nulls_first_rcu(&st->hash[st->bucket])); 134 } 135 return head; 136 } 137 138 static struct hlist_nulls_node *ct_get_idx(struct seq_file *seq, loff_t pos) 139 { 140 struct hlist_nulls_node *head = ct_get_first(seq); 141 142 if (head) 143 while (pos && (head = ct_get_next(seq, head))) 144 pos--; 145 return pos ? NULL : head; 146 } 147 148 static void *ct_seq_start(struct seq_file *seq, loff_t *pos) 149 __acquires(RCU) 150 { 151 struct ct_iter_state *st = seq->private; 152 153 st->time_now = ktime_get_real_ns(); 154 rcu_read_lock(); 155 156 nf_conntrack_get_ht(&st->hash, &st->htable_size); 157 return ct_get_idx(seq, *pos); 158 } 159 160 static void *ct_seq_next(struct seq_file *s, void *v, loff_t *pos) 161 { 162 (*pos)++; 163 return ct_get_next(s, v); 164 } 165 166 static void ct_seq_stop(struct seq_file *s, void *v) 167 __releases(RCU) 168 { 169 rcu_read_unlock(); 170 } 171 172 #ifdef CONFIG_NF_CONNTRACK_SECMARK 173 static void ct_show_secctx(struct seq_file *s, const struct nf_conn *ct) 174 { 175 int ret; 176 u32 len; 177 char *secctx; 178 179 ret = security_secid_to_secctx(ct->secmark, &secctx, &len); 180 if (ret) 181 return; 182 183 seq_printf(s, "secctx=%s ", secctx); 184 185 security_release_secctx(secctx, len); 186 } 187 #else 188 static inline void ct_show_secctx(struct seq_file *s, const struct nf_conn *ct) 189 { 190 } 191 #endif 192 193 #ifdef CONFIG_NF_CONNTRACK_ZONES 194 static void ct_show_zone(struct seq_file *s, const struct nf_conn *ct, 195 int dir) 196 { 197 const struct nf_conntrack_zone *zone = nf_ct_zone(ct); 198 199 if (zone->dir != dir) 200 return; 201 switch (zone->dir) { 202 case NF_CT_DEFAULT_ZONE_DIR: 203 seq_printf(s, "zone=%u ", zone->id); 204 break; 205 case NF_CT_ZONE_DIR_ORIG: 206 seq_printf(s, "zone-orig=%u ", zone->id); 207 break; 208 case NF_CT_ZONE_DIR_REPL: 209 seq_printf(s, "zone-reply=%u ", zone->id); 210 break; 211 default: 212 break; 213 } 214 } 215 #else 216 static inline void ct_show_zone(struct seq_file *s, const struct nf_conn *ct, 217 int dir) 218 { 219 } 220 #endif 221 222 #ifdef CONFIG_NF_CONNTRACK_TIMESTAMP 223 static void ct_show_delta_time(struct seq_file *s, const struct nf_conn *ct) 224 { 225 struct ct_iter_state *st = s->private; 226 struct nf_conn_tstamp *tstamp; 227 s64 delta_time; 228 229 tstamp = nf_conn_tstamp_find(ct); 230 if (tstamp) { 231 delta_time = st->time_now - tstamp->start; 232 if (delta_time > 0) 233 delta_time = div_s64(delta_time, NSEC_PER_SEC); 234 else 235 delta_time = 0; 236 237 seq_printf(s, "delta-time=%llu ", 238 (unsigned long long)delta_time); 239 } 240 return; 241 } 242 #else 243 static inline void 244 ct_show_delta_time(struct seq_file *s, const struct nf_conn *ct) 245 { 246 } 247 #endif 248 249 static const char* l3proto_name(u16 proto) 250 { 251 switch (proto) { 252 case AF_INET: return "ipv4"; 253 case AF_INET6: return "ipv6"; 254 } 255 256 return "unknown"; 257 } 258 259 static const char* l4proto_name(u16 proto) 260 { 261 switch (proto) { 262 case IPPROTO_ICMP: return "icmp"; 263 case IPPROTO_TCP: return "tcp"; 264 case IPPROTO_UDP: return "udp"; 265 case IPPROTO_DCCP: return "dccp"; 266 case IPPROTO_GRE: return "gre"; 267 case IPPROTO_SCTP: return "sctp"; 268 case IPPROTO_UDPLITE: return "udplite"; 269 } 270 271 return "unknown"; 272 } 273 274 static unsigned int 275 seq_print_acct(struct seq_file *s, const struct nf_conn *ct, int dir) 276 { 277 struct nf_conn_acct *acct; 278 struct nf_conn_counter *counter; 279 280 acct = nf_conn_acct_find(ct); 281 if (!acct) 282 return 0; 283 284 counter = acct->counter; 285 seq_printf(s, "packets=%llu bytes=%llu ", 286 (unsigned long long)atomic64_read(&counter[dir].packets), 287 (unsigned long long)atomic64_read(&counter[dir].bytes)); 288 289 return 0; 290 } 291 292 /* return 0 on success, 1 in case of error */ 293 static int ct_seq_show(struct seq_file *s, void *v) 294 { 295 struct nf_conntrack_tuple_hash *hash = v; 296 struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(hash); 297 const struct nf_conntrack_l4proto *l4proto; 298 struct net *net = seq_file_net(s); 299 int ret = 0; 300 301 WARN_ON(!ct); 302 if (unlikely(!atomic_inc_not_zero(&ct->ct_general.use))) 303 return 0; 304 305 if (nf_ct_should_gc(ct)) { 306 nf_ct_kill(ct); 307 goto release; 308 } 309 310 /* we only want to print DIR_ORIGINAL */ 311 if (NF_CT_DIRECTION(hash)) 312 goto release; 313 314 if (!net_eq(nf_ct_net(ct), net)) 315 goto release; 316 317 l4proto = nf_ct_l4proto_find(nf_ct_protonum(ct)); 318 319 ret = -ENOSPC; 320 seq_printf(s, "%-8s %u %-8s %u ", 321 l3proto_name(nf_ct_l3num(ct)), nf_ct_l3num(ct), 322 l4proto_name(l4proto->l4proto), nf_ct_protonum(ct)); 323 324 if (!test_bit(IPS_OFFLOAD_BIT, &ct->status)) 325 seq_printf(s, "%ld ", nf_ct_expires(ct) / HZ); 326 327 if (l4proto->print_conntrack) 328 l4proto->print_conntrack(s, ct); 329 330 print_tuple(s, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple, 331 l4proto); 332 333 ct_show_zone(s, ct, NF_CT_ZONE_DIR_ORIG); 334 335 if (seq_has_overflowed(s)) 336 goto release; 337 338 if (seq_print_acct(s, ct, IP_CT_DIR_ORIGINAL)) 339 goto release; 340 341 if (!(test_bit(IPS_SEEN_REPLY_BIT, &ct->status))) 342 seq_puts(s, "[UNREPLIED] "); 343 344 print_tuple(s, &ct->tuplehash[IP_CT_DIR_REPLY].tuple, l4proto); 345 346 ct_show_zone(s, ct, NF_CT_ZONE_DIR_REPL); 347 348 if (seq_print_acct(s, ct, IP_CT_DIR_REPLY)) 349 goto release; 350 351 if (test_bit(IPS_OFFLOAD_BIT, &ct->status)) 352 seq_puts(s, "[OFFLOAD] "); 353 else if (test_bit(IPS_ASSURED_BIT, &ct->status)) 354 seq_puts(s, "[ASSURED] "); 355 356 if (seq_has_overflowed(s)) 357 goto release; 358 359 #if defined(CONFIG_NF_CONNTRACK_MARK) 360 seq_printf(s, "mark=%u ", ct->mark); 361 #endif 362 363 ct_show_secctx(s, ct); 364 ct_show_zone(s, ct, NF_CT_DEFAULT_ZONE_DIR); 365 ct_show_delta_time(s, ct); 366 367 seq_printf(s, "use=%u\n", atomic_read(&ct->ct_general.use)); 368 369 if (seq_has_overflowed(s)) 370 goto release; 371 372 ret = 0; 373 release: 374 nf_ct_put(ct); 375 return ret; 376 } 377 378 static const struct seq_operations ct_seq_ops = { 379 .start = ct_seq_start, 380 .next = ct_seq_next, 381 .stop = ct_seq_stop, 382 .show = ct_seq_show 383 }; 384 385 static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos) 386 { 387 struct net *net = seq_file_net(seq); 388 int cpu; 389 390 if (*pos == 0) 391 return SEQ_START_TOKEN; 392 393 for (cpu = *pos-1; cpu < nr_cpu_ids; ++cpu) { 394 if (!cpu_possible(cpu)) 395 continue; 396 *pos = cpu + 1; 397 return per_cpu_ptr(net->ct.stat, cpu); 398 } 399 400 return NULL; 401 } 402 403 static void *ct_cpu_seq_next(struct seq_file *seq, void *v, loff_t *pos) 404 { 405 struct net *net = seq_file_net(seq); 406 int cpu; 407 408 for (cpu = *pos; cpu < nr_cpu_ids; ++cpu) { 409 if (!cpu_possible(cpu)) 410 continue; 411 *pos = cpu + 1; 412 return per_cpu_ptr(net->ct.stat, cpu); 413 } 414 415 return NULL; 416 } 417 418 static void ct_cpu_seq_stop(struct seq_file *seq, void *v) 419 { 420 } 421 422 static int ct_cpu_seq_show(struct seq_file *seq, void *v) 423 { 424 struct net *net = seq_file_net(seq); 425 unsigned int nr_conntracks = atomic_read(&net->ct.count); 426 const struct ip_conntrack_stat *st = v; 427 428 if (v == SEQ_START_TOKEN) { 429 seq_puts(seq, "entries searched found new invalid ignore delete delete_list insert insert_failed drop early_drop icmp_error expect_new expect_create expect_delete search_restart\n"); 430 return 0; 431 } 432 433 seq_printf(seq, "%08x %08x %08x %08x %08x %08x %08x %08x " 434 "%08x %08x %08x %08x %08x %08x %08x %08x %08x\n", 435 nr_conntracks, 436 0, 437 st->found, 438 0, 439 st->invalid, 440 st->ignore, 441 0, 442 0, 443 st->insert, 444 st->insert_failed, 445 st->drop, 446 st->early_drop, 447 st->error, 448 449 st->expect_new, 450 st->expect_create, 451 st->expect_delete, 452 st->search_restart 453 ); 454 return 0; 455 } 456 457 static const struct seq_operations ct_cpu_seq_ops = { 458 .start = ct_cpu_seq_start, 459 .next = ct_cpu_seq_next, 460 .stop = ct_cpu_seq_stop, 461 .show = ct_cpu_seq_show, 462 }; 463 464 static int nf_conntrack_standalone_init_proc(struct net *net) 465 { 466 struct proc_dir_entry *pde; 467 kuid_t root_uid; 468 kgid_t root_gid; 469 470 pde = proc_create_net("nf_conntrack", 0440, net->proc_net, &ct_seq_ops, 471 sizeof(struct ct_iter_state)); 472 if (!pde) 473 goto out_nf_conntrack; 474 475 root_uid = make_kuid(net->user_ns, 0); 476 root_gid = make_kgid(net->user_ns, 0); 477 if (uid_valid(root_uid) && gid_valid(root_gid)) 478 proc_set_user(pde, root_uid, root_gid); 479 480 pde = proc_create_net("nf_conntrack", 0444, net->proc_net_stat, 481 &ct_cpu_seq_ops, sizeof(struct seq_net_private)); 482 if (!pde) 483 goto out_stat_nf_conntrack; 484 return 0; 485 486 out_stat_nf_conntrack: 487 remove_proc_entry("nf_conntrack", net->proc_net); 488 out_nf_conntrack: 489 return -ENOMEM; 490 } 491 492 static void nf_conntrack_standalone_fini_proc(struct net *net) 493 { 494 remove_proc_entry("nf_conntrack", net->proc_net_stat); 495 remove_proc_entry("nf_conntrack", net->proc_net); 496 } 497 #else 498 static int nf_conntrack_standalone_init_proc(struct net *net) 499 { 500 return 0; 501 } 502 503 static void nf_conntrack_standalone_fini_proc(struct net *net) 504 { 505 } 506 #endif /* CONFIG_NF_CONNTRACK_PROCFS */ 507 508 /* Sysctl support */ 509 510 #ifdef CONFIG_SYSCTL 511 /* Log invalid packets of a given protocol */ 512 static int log_invalid_proto_min __read_mostly; 513 static int log_invalid_proto_max __read_mostly = 255; 514 static int zero; 515 static int one = 1; 516 517 /* size the user *wants to set */ 518 static unsigned int nf_conntrack_htable_size_user __read_mostly; 519 520 static int 521 nf_conntrack_hash_sysctl(struct ctl_table *table, int write, 522 void __user *buffer, size_t *lenp, loff_t *ppos) 523 { 524 int ret; 525 526 ret = proc_dointvec(table, write, buffer, lenp, ppos); 527 if (ret < 0 || !write) 528 return ret; 529 530 /* update ret, we might not be able to satisfy request */ 531 ret = nf_conntrack_hash_resize(nf_conntrack_htable_size_user); 532 533 /* update it to the actual value used by conntrack */ 534 nf_conntrack_htable_size_user = nf_conntrack_htable_size; 535 return ret; 536 } 537 538 static struct ctl_table_header *nf_ct_netfilter_header; 539 540 enum nf_ct_sysctl_index { 541 NF_SYSCTL_CT_MAX, 542 NF_SYSCTL_CT_COUNT, 543 NF_SYSCTL_CT_BUCKETS, 544 NF_SYSCTL_CT_CHECKSUM, 545 NF_SYSCTL_CT_LOG_INVALID, 546 NF_SYSCTL_CT_EXPECT_MAX, 547 NF_SYSCTL_CT_ACCT, 548 NF_SYSCTL_CT_HELPER, 549 #ifdef CONFIG_NF_CONNTRACK_EVENTS 550 NF_SYSCTL_CT_EVENTS, 551 #endif 552 #ifdef CONFIG_NF_CONNTRACK_TIMESTAMP 553 NF_SYSCTL_CT_TIMESTAMP, 554 #endif 555 NF_SYSCTL_CT_PROTO_TIMEOUT_GENERIC, 556 NF_SYSCTL_CT_PROTO_TIMEOUT_TCP_SYN_SENT, 557 NF_SYSCTL_CT_PROTO_TIMEOUT_TCP_SYN_RECV, 558 NF_SYSCTL_CT_PROTO_TIMEOUT_TCP_ESTABLISHED, 559 NF_SYSCTL_CT_PROTO_TIMEOUT_TCP_FIN_WAIT, 560 NF_SYSCTL_CT_PROTO_TIMEOUT_TCP_CLOSE_WAIT, 561 NF_SYSCTL_CT_PROTO_TIMEOUT_TCP_LAST_ACK, 562 NF_SYSCTL_CT_PROTO_TIMEOUT_TCP_TIME_WAIT, 563 NF_SYSCTL_CT_PROTO_TIMEOUT_TCP_CLOSE, 564 NF_SYSCTL_CT_PROTO_TIMEOUT_TCP_RETRANS, 565 NF_SYSCTL_CT_PROTO_TIMEOUT_TCP_UNACK, 566 NF_SYSCTL_CT_PROTO_TCP_LOOSE, 567 NF_SYSCTL_CT_PROTO_TCP_LIBERAL, 568 NF_SYSCTL_CT_PROTO_TCP_MAX_RETRANS, 569 NF_SYSCTL_CT_PROTO_TIMEOUT_UDP, 570 NF_SYSCTL_CT_PROTO_TIMEOUT_UDP_STREAM, 571 NF_SYSCTL_CT_PROTO_TIMEOUT_ICMP, 572 NF_SYSCTL_CT_PROTO_TIMEOUT_ICMPV6, 573 #ifdef CONFIG_NF_CT_PROTO_SCTP 574 NF_SYSCTL_CT_PROTO_TIMEOUT_SCTP_CLOSED, 575 NF_SYSCTL_CT_PROTO_TIMEOUT_SCTP_COOKIE_WAIT, 576 NF_SYSCTL_CT_PROTO_TIMEOUT_SCTP_COOKIE_ECHOED, 577 NF_SYSCTL_CT_PROTO_TIMEOUT_SCTP_ESTABLISHED, 578 NF_SYSCTL_CT_PROTO_TIMEOUT_SCTP_SHUTDOWN_SENT, 579 NF_SYSCTL_CT_PROTO_TIMEOUT_SCTP_SHUTDOWN_RECD, 580 NF_SYSCTL_CT_PROTO_TIMEOUT_SCTP_SHUTDOWN_ACK_SENT, 581 NF_SYSCTL_CT_PROTO_TIMEOUT_SCTP_HEARTBEAT_SENT, 582 NF_SYSCTL_CT_PROTO_TIMEOUT_SCTP_HEARTBEAT_ACKED, 583 #endif 584 #ifdef CONFIG_NF_CT_PROTO_DCCP 585 NF_SYSCTL_CT_PROTO_TIMEOUT_DCCP_REQUEST, 586 NF_SYSCTL_CT_PROTO_TIMEOUT_DCCP_RESPOND, 587 NF_SYSCTL_CT_PROTO_TIMEOUT_DCCP_PARTOPEN, 588 NF_SYSCTL_CT_PROTO_TIMEOUT_DCCP_OPEN, 589 NF_SYSCTL_CT_PROTO_TIMEOUT_DCCP_CLOSEREQ, 590 NF_SYSCTL_CT_PROTO_TIMEOUT_DCCP_CLOSING, 591 NF_SYSCTL_CT_PROTO_TIMEOUT_DCCP_TIMEWAIT, 592 NF_SYSCTL_CT_PROTO_DCCP_LOOSE, 593 #endif 594 #ifdef CONFIG_NF_CT_PROTO_GRE 595 NF_SYSCTL_CT_PROTO_TIMEOUT_GRE, 596 NF_SYSCTL_CT_PROTO_TIMEOUT_GRE_STREAM, 597 #endif 598 599 __NF_SYSCTL_CT_LAST_SYSCTL, 600 }; 601 602 #define NF_SYSCTL_CT_LAST_SYSCTL (__NF_SYSCTL_CT_LAST_SYSCTL + 1) 603 604 static struct ctl_table nf_ct_sysctl_table[] = { 605 [NF_SYSCTL_CT_MAX] = { 606 .procname = "nf_conntrack_max", 607 .data = &nf_conntrack_max, 608 .maxlen = sizeof(int), 609 .mode = 0644, 610 .proc_handler = proc_dointvec, 611 }, 612 [NF_SYSCTL_CT_COUNT] = { 613 .procname = "nf_conntrack_count", 614 .data = &init_net.ct.count, 615 .maxlen = sizeof(int), 616 .mode = 0444, 617 .proc_handler = proc_dointvec, 618 }, 619 [NF_SYSCTL_CT_BUCKETS] = { 620 .procname = "nf_conntrack_buckets", 621 .data = &nf_conntrack_htable_size_user, 622 .maxlen = sizeof(unsigned int), 623 .mode = 0644, 624 .proc_handler = nf_conntrack_hash_sysctl, 625 }, 626 [NF_SYSCTL_CT_CHECKSUM] = { 627 .procname = "nf_conntrack_checksum", 628 .data = &init_net.ct.sysctl_checksum, 629 .maxlen = sizeof(int), 630 .mode = 0644, 631 .proc_handler = proc_dointvec_minmax, 632 .extra1 = &zero, 633 .extra2 = &one, 634 }, 635 [NF_SYSCTL_CT_LOG_INVALID] = { 636 .procname = "nf_conntrack_log_invalid", 637 .data = &init_net.ct.sysctl_log_invalid, 638 .maxlen = sizeof(unsigned int), 639 .mode = 0644, 640 .proc_handler = proc_dointvec_minmax, 641 .extra1 = &log_invalid_proto_min, 642 .extra2 = &log_invalid_proto_max, 643 }, 644 [NF_SYSCTL_CT_EXPECT_MAX] = { 645 .procname = "nf_conntrack_expect_max", 646 .data = &nf_ct_expect_max, 647 .maxlen = sizeof(int), 648 .mode = 0644, 649 .proc_handler = proc_dointvec, 650 }, 651 [NF_SYSCTL_CT_ACCT] = { 652 .procname = "nf_conntrack_acct", 653 .data = &init_net.ct.sysctl_acct, 654 .maxlen = sizeof(int), 655 .mode = 0644, 656 .proc_handler = proc_dointvec_minmax, 657 .extra1 = &zero, 658 .extra2 = &one, 659 }, 660 [NF_SYSCTL_CT_HELPER] = { 661 .procname = "nf_conntrack_helper", 662 .data = &init_net.ct.sysctl_auto_assign_helper, 663 .maxlen = sizeof(int), 664 .mode = 0644, 665 .proc_handler = proc_dointvec_minmax, 666 .extra1 = &zero, 667 .extra2 = &one, 668 }, 669 #ifdef CONFIG_NF_CONNTRACK_EVENTS 670 [NF_SYSCTL_CT_EVENTS] = { 671 .procname = "nf_conntrack_events", 672 .data = &init_net.ct.sysctl_events, 673 .maxlen = sizeof(int), 674 .mode = 0644, 675 .proc_handler = proc_dointvec_minmax, 676 .extra1 = &zero, 677 .extra2 = &one, 678 }, 679 #endif 680 #ifdef CONFIG_NF_CONNTRACK_TIMESTAMP 681 [NF_SYSCTL_CT_TIMESTAMP] = { 682 .procname = "nf_conntrack_timestamp", 683 .data = &init_net.ct.sysctl_tstamp, 684 .maxlen = sizeof(int), 685 .mode = 0644, 686 .proc_handler = proc_dointvec_minmax, 687 .extra1 = &zero, 688 .extra2 = &one, 689 }, 690 #endif 691 [NF_SYSCTL_CT_PROTO_TIMEOUT_GENERIC] = { 692 .procname = "nf_conntrack_generic_timeout", 693 .maxlen = sizeof(unsigned int), 694 .mode = 0644, 695 .proc_handler = proc_dointvec_jiffies, 696 }, 697 [NF_SYSCTL_CT_PROTO_TIMEOUT_TCP_SYN_SENT] = { 698 .procname = "nf_conntrack_tcp_timeout_syn_sent", 699 .maxlen = sizeof(unsigned int), 700 .mode = 0644, 701 .proc_handler = proc_dointvec_jiffies, 702 }, 703 [NF_SYSCTL_CT_PROTO_TIMEOUT_TCP_SYN_RECV] = { 704 .procname = "nf_conntrack_tcp_timeout_syn_recv", 705 .maxlen = sizeof(unsigned int), 706 .mode = 0644, 707 .proc_handler = proc_dointvec_jiffies, 708 }, 709 [NF_SYSCTL_CT_PROTO_TIMEOUT_TCP_ESTABLISHED] = { 710 .procname = "nf_conntrack_tcp_timeout_established", 711 .maxlen = sizeof(unsigned int), 712 .mode = 0644, 713 .proc_handler = proc_dointvec_jiffies, 714 }, 715 [NF_SYSCTL_CT_PROTO_TIMEOUT_TCP_FIN_WAIT] = { 716 .procname = "nf_conntrack_tcp_timeout_fin_wait", 717 .maxlen = sizeof(unsigned int), 718 .mode = 0644, 719 .proc_handler = proc_dointvec_jiffies, 720 }, 721 [NF_SYSCTL_CT_PROTO_TIMEOUT_TCP_CLOSE_WAIT] = { 722 .procname = "nf_conntrack_tcp_timeout_close_wait", 723 .maxlen = sizeof(unsigned int), 724 .mode = 0644, 725 .proc_handler = proc_dointvec_jiffies, 726 }, 727 [NF_SYSCTL_CT_PROTO_TIMEOUT_TCP_LAST_ACK] = { 728 .procname = "nf_conntrack_tcp_timeout_last_ack", 729 .maxlen = sizeof(unsigned int), 730 .mode = 0644, 731 .proc_handler = proc_dointvec_jiffies, 732 }, 733 [NF_SYSCTL_CT_PROTO_TIMEOUT_TCP_TIME_WAIT] = { 734 .procname = "nf_conntrack_tcp_timeout_time_wait", 735 .maxlen = sizeof(unsigned int), 736 .mode = 0644, 737 .proc_handler = proc_dointvec_jiffies, 738 }, 739 [NF_SYSCTL_CT_PROTO_TIMEOUT_TCP_CLOSE] = { 740 .procname = "nf_conntrack_tcp_timeout_close", 741 .maxlen = sizeof(unsigned int), 742 .mode = 0644, 743 .proc_handler = proc_dointvec_jiffies, 744 }, 745 [NF_SYSCTL_CT_PROTO_TIMEOUT_TCP_RETRANS] = { 746 .procname = "nf_conntrack_tcp_timeout_max_retrans", 747 .maxlen = sizeof(unsigned int), 748 .mode = 0644, 749 .proc_handler = proc_dointvec_jiffies, 750 }, 751 [NF_SYSCTL_CT_PROTO_TIMEOUT_TCP_UNACK] = { 752 .procname = "nf_conntrack_tcp_timeout_unacknowledged", 753 .maxlen = sizeof(unsigned int), 754 .mode = 0644, 755 .proc_handler = proc_dointvec_jiffies, 756 }, 757 [NF_SYSCTL_CT_PROTO_TCP_LOOSE] = { 758 .procname = "nf_conntrack_tcp_loose", 759 .maxlen = sizeof(int), 760 .mode = 0644, 761 .proc_handler = proc_dointvec_minmax, 762 .extra1 = &zero, 763 .extra2 = &one, 764 }, 765 [NF_SYSCTL_CT_PROTO_TCP_LIBERAL] = { 766 .procname = "nf_conntrack_tcp_be_liberal", 767 .maxlen = sizeof(int), 768 .mode = 0644, 769 .proc_handler = proc_dointvec_minmax, 770 .extra1 = &zero, 771 .extra2 = &one, 772 }, 773 [NF_SYSCTL_CT_PROTO_TCP_MAX_RETRANS] = { 774 .procname = "nf_conntrack_tcp_max_retrans", 775 .maxlen = sizeof(unsigned int), 776 .mode = 0644, 777 .proc_handler = proc_dointvec, 778 }, 779 [NF_SYSCTL_CT_PROTO_TIMEOUT_UDP] = { 780 .procname = "nf_conntrack_udp_timeout", 781 .maxlen = sizeof(unsigned int), 782 .mode = 0644, 783 .proc_handler = proc_dointvec_jiffies, 784 }, 785 [NF_SYSCTL_CT_PROTO_TIMEOUT_UDP_STREAM] = { 786 .procname = "nf_conntrack_udp_timeout_stream", 787 .maxlen = sizeof(unsigned int), 788 .mode = 0644, 789 .proc_handler = proc_dointvec_jiffies, 790 }, 791 [NF_SYSCTL_CT_PROTO_TIMEOUT_ICMP] = { 792 .procname = "nf_conntrack_icmp_timeout", 793 .maxlen = sizeof(unsigned int), 794 .mode = 0644, 795 .proc_handler = proc_dointvec_jiffies, 796 }, 797 [NF_SYSCTL_CT_PROTO_TIMEOUT_ICMPV6] = { 798 .procname = "nf_conntrack_icmpv6_timeout", 799 .maxlen = sizeof(unsigned int), 800 .mode = 0644, 801 .proc_handler = proc_dointvec_jiffies, 802 }, 803 #ifdef CONFIG_NF_CT_PROTO_SCTP 804 [NF_SYSCTL_CT_PROTO_TIMEOUT_SCTP_CLOSED] = { 805 .procname = "nf_conntrack_sctp_timeout_closed", 806 .maxlen = sizeof(unsigned int), 807 .mode = 0644, 808 .proc_handler = proc_dointvec_jiffies, 809 }, 810 [NF_SYSCTL_CT_PROTO_TIMEOUT_SCTP_COOKIE_WAIT] = { 811 .procname = "nf_conntrack_sctp_timeout_cookie_wait", 812 .maxlen = sizeof(unsigned int), 813 .mode = 0644, 814 .proc_handler = proc_dointvec_jiffies, 815 }, 816 [NF_SYSCTL_CT_PROTO_TIMEOUT_SCTP_COOKIE_ECHOED] = { 817 .procname = "nf_conntrack_sctp_timeout_cookie_echoed", 818 .maxlen = sizeof(unsigned int), 819 .mode = 0644, 820 .proc_handler = proc_dointvec_jiffies, 821 }, 822 [NF_SYSCTL_CT_PROTO_TIMEOUT_SCTP_ESTABLISHED] = { 823 .procname = "nf_conntrack_sctp_timeout_established", 824 .maxlen = sizeof(unsigned int), 825 .mode = 0644, 826 .proc_handler = proc_dointvec_jiffies, 827 }, 828 [NF_SYSCTL_CT_PROTO_TIMEOUT_SCTP_SHUTDOWN_SENT] = { 829 .procname = "nf_conntrack_sctp_timeout_shutdown_sent", 830 .maxlen = sizeof(unsigned int), 831 .mode = 0644, 832 .proc_handler = proc_dointvec_jiffies, 833 }, 834 [NF_SYSCTL_CT_PROTO_TIMEOUT_SCTP_SHUTDOWN_RECD] = { 835 .procname = "nf_conntrack_sctp_timeout_shutdown_recd", 836 .maxlen = sizeof(unsigned int), 837 .mode = 0644, 838 .proc_handler = proc_dointvec_jiffies, 839 }, 840 [NF_SYSCTL_CT_PROTO_TIMEOUT_SCTP_SHUTDOWN_ACK_SENT] = { 841 .procname = "nf_conntrack_sctp_timeout_shutdown_ack_sent", 842 .maxlen = sizeof(unsigned int), 843 .mode = 0644, 844 .proc_handler = proc_dointvec_jiffies, 845 }, 846 [NF_SYSCTL_CT_PROTO_TIMEOUT_SCTP_HEARTBEAT_SENT] = { 847 .procname = "nf_conntrack_sctp_timeout_heartbeat_sent", 848 .maxlen = sizeof(unsigned int), 849 .mode = 0644, 850 .proc_handler = proc_dointvec_jiffies, 851 }, 852 [NF_SYSCTL_CT_PROTO_TIMEOUT_SCTP_HEARTBEAT_ACKED] = { 853 .procname = "nf_conntrack_sctp_timeout_heartbeat_acked", 854 .maxlen = sizeof(unsigned int), 855 .mode = 0644, 856 .proc_handler = proc_dointvec_jiffies, 857 }, 858 #endif 859 #ifdef CONFIG_NF_CT_PROTO_DCCP 860 [NF_SYSCTL_CT_PROTO_TIMEOUT_DCCP_REQUEST] = { 861 .procname = "nf_conntrack_dccp_timeout_request", 862 .maxlen = sizeof(unsigned int), 863 .mode = 0644, 864 .proc_handler = proc_dointvec_jiffies, 865 }, 866 [NF_SYSCTL_CT_PROTO_TIMEOUT_DCCP_RESPOND] = { 867 .procname = "nf_conntrack_dccp_timeout_respond", 868 .maxlen = sizeof(unsigned int), 869 .mode = 0644, 870 .proc_handler = proc_dointvec_jiffies, 871 }, 872 [NF_SYSCTL_CT_PROTO_TIMEOUT_DCCP_PARTOPEN] = { 873 .procname = "nf_conntrack_dccp_timeout_partopen", 874 .maxlen = sizeof(unsigned int), 875 .mode = 0644, 876 .proc_handler = proc_dointvec_jiffies, 877 }, 878 [NF_SYSCTL_CT_PROTO_TIMEOUT_DCCP_OPEN] = { 879 .procname = "nf_conntrack_dccp_timeout_open", 880 .maxlen = sizeof(unsigned int), 881 .mode = 0644, 882 .proc_handler = proc_dointvec_jiffies, 883 }, 884 [NF_SYSCTL_CT_PROTO_TIMEOUT_DCCP_CLOSEREQ] = { 885 .procname = "nf_conntrack_dccp_timeout_closereq", 886 .maxlen = sizeof(unsigned int), 887 .mode = 0644, 888 .proc_handler = proc_dointvec_jiffies, 889 }, 890 [NF_SYSCTL_CT_PROTO_TIMEOUT_DCCP_CLOSING] = { 891 .procname = "nf_conntrack_dccp_timeout_closing", 892 .maxlen = sizeof(unsigned int), 893 .mode = 0644, 894 .proc_handler = proc_dointvec_jiffies, 895 }, 896 [NF_SYSCTL_CT_PROTO_TIMEOUT_DCCP_TIMEWAIT] = { 897 .procname = "nf_conntrack_dccp_timeout_timewait", 898 .maxlen = sizeof(unsigned int), 899 .mode = 0644, 900 .proc_handler = proc_dointvec_jiffies, 901 }, 902 [NF_SYSCTL_CT_PROTO_DCCP_LOOSE] = { 903 .procname = "nf_conntrack_dccp_loose", 904 .maxlen = sizeof(int), 905 .mode = 0644, 906 .proc_handler = proc_dointvec_minmax, 907 .extra1 = &zero, 908 .extra2 = &one, 909 }, 910 #endif 911 #ifdef CONFIG_NF_CT_PROTO_GRE 912 [NF_SYSCTL_CT_PROTO_TIMEOUT_GRE] = { 913 .procname = "nf_conntrack_gre_timeout", 914 .maxlen = sizeof(unsigned int), 915 .mode = 0644, 916 .proc_handler = proc_dointvec_jiffies, 917 }, 918 [NF_SYSCTL_CT_PROTO_TIMEOUT_GRE_STREAM] = { 919 .procname = "nf_conntrack_gre_timeout_stream", 920 .maxlen = sizeof(unsigned int), 921 .mode = 0644, 922 .proc_handler = proc_dointvec_jiffies, 923 }, 924 #endif 925 {} 926 }; 927 928 static struct ctl_table nf_ct_netfilter_table[] = { 929 { 930 .procname = "nf_conntrack_max", 931 .data = &nf_conntrack_max, 932 .maxlen = sizeof(int), 933 .mode = 0644, 934 .proc_handler = proc_dointvec, 935 }, 936 { } 937 }; 938 939 static void nf_conntrack_standalone_init_tcp_sysctl(struct net *net, 940 struct ctl_table *table) 941 { 942 struct nf_tcp_net *tn = nf_tcp_pernet(net); 943 944 #define XASSIGN(XNAME, tn) \ 945 table[NF_SYSCTL_CT_PROTO_TIMEOUT_TCP_ ## XNAME].data = \ 946 &(tn)->timeouts[TCP_CONNTRACK_ ## XNAME] 947 948 XASSIGN(SYN_SENT, tn); 949 XASSIGN(SYN_RECV, tn); 950 XASSIGN(ESTABLISHED, tn); 951 XASSIGN(FIN_WAIT, tn); 952 XASSIGN(CLOSE_WAIT, tn); 953 XASSIGN(LAST_ACK, tn); 954 XASSIGN(TIME_WAIT, tn); 955 XASSIGN(CLOSE, tn); 956 XASSIGN(RETRANS, tn); 957 XASSIGN(UNACK, tn); 958 #undef XASSIGN 959 #define XASSIGN(XNAME, rval) \ 960 table[NF_SYSCTL_CT_PROTO_TCP_ ## XNAME].data = (rval) 961 962 XASSIGN(LOOSE, &tn->tcp_loose); 963 XASSIGN(LIBERAL, &tn->tcp_be_liberal); 964 XASSIGN(MAX_RETRANS, &tn->tcp_max_retrans); 965 #undef XASSIGN 966 } 967 968 static void nf_conntrack_standalone_init_sctp_sysctl(struct net *net, 969 struct ctl_table *table) 970 { 971 #ifdef CONFIG_NF_CT_PROTO_SCTP 972 struct nf_sctp_net *sn = nf_sctp_pernet(net); 973 974 #define XASSIGN(XNAME, sn) \ 975 table[NF_SYSCTL_CT_PROTO_TIMEOUT_SCTP_ ## XNAME].data = \ 976 &(sn)->timeouts[SCTP_CONNTRACK_ ## XNAME] 977 978 XASSIGN(CLOSED, sn); 979 XASSIGN(COOKIE_WAIT, sn); 980 XASSIGN(COOKIE_ECHOED, sn); 981 XASSIGN(ESTABLISHED, sn); 982 XASSIGN(SHUTDOWN_SENT, sn); 983 XASSIGN(SHUTDOWN_RECD, sn); 984 XASSIGN(SHUTDOWN_ACK_SENT, sn); 985 XASSIGN(HEARTBEAT_SENT, sn); 986 XASSIGN(HEARTBEAT_ACKED, sn); 987 #undef XASSIGN 988 #endif 989 } 990 991 static void nf_conntrack_standalone_init_dccp_sysctl(struct net *net, 992 struct ctl_table *table) 993 { 994 #ifdef CONFIG_NF_CT_PROTO_DCCP 995 struct nf_dccp_net *dn = nf_dccp_pernet(net); 996 997 #define XASSIGN(XNAME, dn) \ 998 table[NF_SYSCTL_CT_PROTO_TIMEOUT_DCCP_ ## XNAME].data = \ 999 &(dn)->dccp_timeout[CT_DCCP_ ## XNAME] 1000 1001 XASSIGN(REQUEST, dn); 1002 XASSIGN(RESPOND, dn); 1003 XASSIGN(PARTOPEN, dn); 1004 XASSIGN(OPEN, dn); 1005 XASSIGN(CLOSEREQ, dn); 1006 XASSIGN(CLOSING, dn); 1007 XASSIGN(TIMEWAIT, dn); 1008 #undef XASSIGN 1009 1010 table[NF_SYSCTL_CT_PROTO_DCCP_LOOSE].data = &dn->dccp_loose; 1011 #endif 1012 } 1013 1014 static void nf_conntrack_standalone_init_gre_sysctl(struct net *net, 1015 struct ctl_table *table) 1016 { 1017 #ifdef CONFIG_NF_CT_PROTO_GRE 1018 struct nf_gre_net *gn = nf_gre_pernet(net); 1019 1020 table[NF_SYSCTL_CT_PROTO_TIMEOUT_GRE].data = &gn->timeouts[GRE_CT_UNREPLIED]; 1021 table[NF_SYSCTL_CT_PROTO_TIMEOUT_GRE_STREAM].data = &gn->timeouts[GRE_CT_REPLIED]; 1022 #endif 1023 } 1024 1025 static int nf_conntrack_standalone_init_sysctl(struct net *net) 1026 { 1027 struct nf_udp_net *un = nf_udp_pernet(net); 1028 struct ctl_table *table; 1029 1030 BUILD_BUG_ON(ARRAY_SIZE(nf_ct_sysctl_table) != NF_SYSCTL_CT_LAST_SYSCTL); 1031 1032 table = kmemdup(nf_ct_sysctl_table, sizeof(nf_ct_sysctl_table), 1033 GFP_KERNEL); 1034 if (!table) 1035 return -ENOMEM; 1036 1037 table[NF_SYSCTL_CT_COUNT].data = &net->ct.count; 1038 table[NF_SYSCTL_CT_CHECKSUM].data = &net->ct.sysctl_checksum; 1039 table[NF_SYSCTL_CT_LOG_INVALID].data = &net->ct.sysctl_log_invalid; 1040 table[NF_SYSCTL_CT_ACCT].data = &net->ct.sysctl_acct; 1041 table[NF_SYSCTL_CT_HELPER].data = &net->ct.sysctl_auto_assign_helper; 1042 #ifdef CONFIG_NF_CONNTRACK_EVENTS 1043 table[NF_SYSCTL_CT_EVENTS].data = &net->ct.sysctl_events; 1044 #endif 1045 #ifdef CONFIG_NF_CONNTRACK_TIMESTAMP 1046 table[NF_SYSCTL_CT_TIMESTAMP].data = &net->ct.sysctl_tstamp; 1047 #endif 1048 table[NF_SYSCTL_CT_PROTO_TIMEOUT_GENERIC].data = &nf_generic_pernet(net)->timeout; 1049 table[NF_SYSCTL_CT_PROTO_TIMEOUT_ICMP].data = &nf_icmp_pernet(net)->timeout; 1050 table[NF_SYSCTL_CT_PROTO_TIMEOUT_ICMPV6].data = &nf_icmpv6_pernet(net)->timeout; 1051 table[NF_SYSCTL_CT_PROTO_TIMEOUT_UDP].data = &un->timeouts[UDP_CT_UNREPLIED]; 1052 table[NF_SYSCTL_CT_PROTO_TIMEOUT_UDP_STREAM].data = &un->timeouts[UDP_CT_REPLIED]; 1053 1054 nf_conntrack_standalone_init_tcp_sysctl(net, table); 1055 nf_conntrack_standalone_init_sctp_sysctl(net, table); 1056 nf_conntrack_standalone_init_dccp_sysctl(net, table); 1057 nf_conntrack_standalone_init_gre_sysctl(net, table); 1058 1059 /* Don't export sysctls to unprivileged users */ 1060 if (net->user_ns != &init_user_ns) { 1061 table[NF_SYSCTL_CT_MAX].procname = NULL; 1062 table[NF_SYSCTL_CT_ACCT].procname = NULL; 1063 table[NF_SYSCTL_CT_HELPER].procname = NULL; 1064 #ifdef CONFIG_NF_CONNTRACK_TIMESTAMP 1065 table[NF_SYSCTL_CT_TIMESTAMP].procname = NULL; 1066 #endif 1067 #ifdef CONFIG_NF_CONNTRACK_EVENTS 1068 table[NF_SYSCTL_CT_EVENTS].procname = NULL; 1069 #endif 1070 } 1071 1072 if (!net_eq(&init_net, net)) 1073 table[NF_SYSCTL_CT_BUCKETS].mode = 0444; 1074 1075 net->ct.sysctl_header = register_net_sysctl(net, "net/netfilter", table); 1076 if (!net->ct.sysctl_header) 1077 goto out_unregister_netfilter; 1078 1079 return 0; 1080 1081 out_unregister_netfilter: 1082 kfree(table); 1083 return -ENOMEM; 1084 } 1085 1086 static void nf_conntrack_standalone_fini_sysctl(struct net *net) 1087 { 1088 struct ctl_table *table; 1089 1090 table = net->ct.sysctl_header->ctl_table_arg; 1091 unregister_net_sysctl_table(net->ct.sysctl_header); 1092 kfree(table); 1093 } 1094 #else 1095 static int nf_conntrack_standalone_init_sysctl(struct net *net) 1096 { 1097 return 0; 1098 } 1099 1100 static void nf_conntrack_standalone_fini_sysctl(struct net *net) 1101 { 1102 } 1103 #endif /* CONFIG_SYSCTL */ 1104 1105 static void nf_conntrack_fini_net(struct net *net) 1106 { 1107 if (enable_hooks) 1108 nf_ct_netns_put(net, NFPROTO_INET); 1109 1110 nf_conntrack_standalone_fini_proc(net); 1111 nf_conntrack_standalone_fini_sysctl(net); 1112 } 1113 1114 static int nf_conntrack_pernet_init(struct net *net) 1115 { 1116 int ret; 1117 1118 net->ct.sysctl_checksum = 1; 1119 1120 ret = nf_conntrack_standalone_init_sysctl(net); 1121 if (ret < 0) 1122 return ret; 1123 1124 ret = nf_conntrack_standalone_init_proc(net); 1125 if (ret < 0) 1126 goto out_proc; 1127 1128 ret = nf_conntrack_init_net(net); 1129 if (ret < 0) 1130 goto out_init_net; 1131 1132 if (enable_hooks) { 1133 ret = nf_ct_netns_get(net, NFPROTO_INET); 1134 if (ret < 0) 1135 goto out_hooks; 1136 } 1137 1138 return 0; 1139 1140 out_hooks: 1141 nf_conntrack_cleanup_net(net); 1142 out_init_net: 1143 nf_conntrack_standalone_fini_proc(net); 1144 out_proc: 1145 nf_conntrack_standalone_fini_sysctl(net); 1146 return ret; 1147 } 1148 1149 static void nf_conntrack_pernet_exit(struct list_head *net_exit_list) 1150 { 1151 struct net *net; 1152 1153 list_for_each_entry(net, net_exit_list, exit_list) 1154 nf_conntrack_fini_net(net); 1155 1156 nf_conntrack_cleanup_net_list(net_exit_list); 1157 } 1158 1159 static struct pernet_operations nf_conntrack_net_ops = { 1160 .init = nf_conntrack_pernet_init, 1161 .exit_batch = nf_conntrack_pernet_exit, 1162 .id = &nf_conntrack_net_id, 1163 .size = sizeof(struct nf_conntrack_net), 1164 }; 1165 1166 static int __init nf_conntrack_standalone_init(void) 1167 { 1168 int ret = nf_conntrack_init_start(); 1169 if (ret < 0) 1170 goto out_start; 1171 1172 BUILD_BUG_ON(SKB_NFCT_PTRMASK != NFCT_PTRMASK); 1173 BUILD_BUG_ON(NFCT_INFOMASK <= IP_CT_NUMBER); 1174 1175 #ifdef CONFIG_SYSCTL 1176 nf_ct_netfilter_header = 1177 register_net_sysctl(&init_net, "net", nf_ct_netfilter_table); 1178 if (!nf_ct_netfilter_header) { 1179 pr_err("nf_conntrack: can't register to sysctl.\n"); 1180 ret = -ENOMEM; 1181 goto out_sysctl; 1182 } 1183 1184 nf_conntrack_htable_size_user = nf_conntrack_htable_size; 1185 #endif 1186 1187 ret = register_pernet_subsys(&nf_conntrack_net_ops); 1188 if (ret < 0) 1189 goto out_pernet; 1190 1191 nf_conntrack_init_end(); 1192 return 0; 1193 1194 out_pernet: 1195 #ifdef CONFIG_SYSCTL 1196 unregister_net_sysctl_table(nf_ct_netfilter_header); 1197 out_sysctl: 1198 #endif 1199 nf_conntrack_cleanup_end(); 1200 out_start: 1201 return ret; 1202 } 1203 1204 static void __exit nf_conntrack_standalone_fini(void) 1205 { 1206 nf_conntrack_cleanup_start(); 1207 unregister_pernet_subsys(&nf_conntrack_net_ops); 1208 #ifdef CONFIG_SYSCTL 1209 unregister_net_sysctl_table(nf_ct_netfilter_header); 1210 #endif 1211 nf_conntrack_cleanup_end(); 1212 } 1213 1214 module_init(nf_conntrack_standalone_init); 1215 module_exit(nf_conntrack_standalone_fini); 1216
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.