ip_conntrack_standalone.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962
  1. /* This file contains all the functions required for the standalone
  2. ip_conntrack module.
  3. These are not required by the compatibility layer.
  4. */
  5. /* (C) 1999-2001 Paul `Rusty' Russell
  6. * (C) 2002-2005 Netfilter Core Team <coreteam@netfilter.org>
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License version 2 as
  10. * published by the Free Software Foundation.
  11. */
  12. #include <linux/types.h>
  13. #include <linux/ip.h>
  14. #include <linux/netfilter.h>
  15. #include <linux/netfilter_ipv4.h>
  16. #include <linux/module.h>
  17. #include <linux/skbuff.h>
  18. #include <linux/proc_fs.h>
  19. #include <linux/seq_file.h>
  20. #include <linux/percpu.h>
  21. #ifdef CONFIG_SYSCTL
  22. #include <linux/sysctl.h>
  23. #endif
  24. #include <net/checksum.h>
  25. #include <net/ip.h>
  26. #include <net/route.h>
  27. #include <linux/netfilter_ipv4/ip_conntrack.h>
  28. #include <linux/netfilter_ipv4/ip_conntrack_protocol.h>
  29. #include <linux/netfilter_ipv4/ip_conntrack_core.h>
  30. #include <linux/netfilter_ipv4/ip_conntrack_helper.h>
  31. #if 0
  32. #define DEBUGP printk
  33. #else
  34. #define DEBUGP(format, args...)
  35. #endif
  36. MODULE_LICENSE("GPL");
  37. extern atomic_t ip_conntrack_count;
  38. DECLARE_PER_CPU(struct ip_conntrack_stat, ip_conntrack_stat);
  39. static int kill_proto(struct ip_conntrack *i, void *data)
  40. {
  41. return (i->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum ==
  42. *((u_int8_t *) data));
  43. }
  44. #ifdef CONFIG_PROC_FS
  45. static int
  46. print_tuple(struct seq_file *s, const struct ip_conntrack_tuple *tuple,
  47. struct ip_conntrack_protocol *proto)
  48. {
  49. seq_printf(s, "src=%u.%u.%u.%u dst=%u.%u.%u.%u ",
  50. NIPQUAD(tuple->src.ip), NIPQUAD(tuple->dst.ip));
  51. return proto->print_tuple(s, tuple);
  52. }
  53. #ifdef CONFIG_IP_NF_CT_ACCT
  54. static unsigned int
  55. seq_print_counters(struct seq_file *s,
  56. const struct ip_conntrack_counter *counter)
  57. {
  58. return seq_printf(s, "packets=%llu bytes=%llu ",
  59. (unsigned long long)counter->packets,
  60. (unsigned long long)counter->bytes);
  61. }
  62. #else
  63. #define seq_print_counters(x, y) 0
  64. #endif
  65. struct ct_iter_state {
  66. unsigned int bucket;
  67. };
  68. static struct list_head *ct_get_first(struct seq_file *seq)
  69. {
  70. struct ct_iter_state *st = seq->private;
  71. for (st->bucket = 0;
  72. st->bucket < ip_conntrack_htable_size;
  73. st->bucket++) {
  74. if (!list_empty(&ip_conntrack_hash[st->bucket]))
  75. return ip_conntrack_hash[st->bucket].next;
  76. }
  77. return NULL;
  78. }
  79. static struct list_head *ct_get_next(struct seq_file *seq, struct list_head *head)
  80. {
  81. struct ct_iter_state *st = seq->private;
  82. head = head->next;
  83. while (head == &ip_conntrack_hash[st->bucket]) {
  84. if (++st->bucket >= ip_conntrack_htable_size)
  85. return NULL;
  86. head = ip_conntrack_hash[st->bucket].next;
  87. }
  88. return head;
  89. }
  90. static struct list_head *ct_get_idx(struct seq_file *seq, loff_t pos)
  91. {
  92. struct list_head *head = ct_get_first(seq);
  93. if (head)
  94. while (pos && (head = ct_get_next(seq, head)))
  95. pos--;
  96. return pos ? NULL : head;
  97. }
  98. static void *ct_seq_start(struct seq_file *seq, loff_t *pos)
  99. {
  100. read_lock_bh(&ip_conntrack_lock);
  101. return ct_get_idx(seq, *pos);
  102. }
  103. static void *ct_seq_next(struct seq_file *s, void *v, loff_t *pos)
  104. {
  105. (*pos)++;
  106. return ct_get_next(s, v);
  107. }
  108. static void ct_seq_stop(struct seq_file *s, void *v)
  109. {
  110. read_unlock_bh(&ip_conntrack_lock);
  111. }
  112. static int ct_seq_show(struct seq_file *s, void *v)
  113. {
  114. const struct ip_conntrack_tuple_hash *hash = v;
  115. const struct ip_conntrack *conntrack = tuplehash_to_ctrack(hash);
  116. struct ip_conntrack_protocol *proto;
  117. IP_NF_ASSERT(conntrack);
  118. /* we only want to print DIR_ORIGINAL */
  119. if (DIRECTION(hash))
  120. return 0;
  121. proto = __ip_conntrack_proto_find(conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum);
  122. IP_NF_ASSERT(proto);
  123. if (seq_printf(s, "%-8s %u %ld ",
  124. proto->name,
  125. conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum,
  126. timer_pending(&conntrack->timeout)
  127. ? (long)(conntrack->timeout.expires - jiffies)/HZ
  128. : 0) != 0)
  129. return -ENOSPC;
  130. if (proto->print_conntrack(s, conntrack))
  131. return -ENOSPC;
  132. if (print_tuple(s, &conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
  133. proto))
  134. return -ENOSPC;
  135. if (seq_print_counters(s, &conntrack->counters[IP_CT_DIR_ORIGINAL]))
  136. return -ENOSPC;
  137. if (!(test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)))
  138. if (seq_printf(s, "[UNREPLIED] "))
  139. return -ENOSPC;
  140. if (print_tuple(s, &conntrack->tuplehash[IP_CT_DIR_REPLY].tuple,
  141. proto))
  142. return -ENOSPC;
  143. if (seq_print_counters(s, &conntrack->counters[IP_CT_DIR_REPLY]))
  144. return -ENOSPC;
  145. if (test_bit(IPS_ASSURED_BIT, &conntrack->status))
  146. if (seq_printf(s, "[ASSURED] "))
  147. return -ENOSPC;
  148. #if defined(CONFIG_IP_NF_CONNTRACK_MARK)
  149. if (seq_printf(s, "mark=%u ", conntrack->mark))
  150. return -ENOSPC;
  151. #endif
  152. #ifdef CONFIG_IP_NF_CONNTRACK_SECMARK
  153. if (seq_printf(s, "secmark=%u ", conntrack->secmark))
  154. return -ENOSPC;
  155. #endif
  156. if (seq_printf(s, "use=%u\n", atomic_read(&conntrack->ct_general.use)))
  157. return -ENOSPC;
  158. return 0;
  159. }
  160. static struct seq_operations ct_seq_ops = {
  161. .start = ct_seq_start,
  162. .next = ct_seq_next,
  163. .stop = ct_seq_stop,
  164. .show = ct_seq_show
  165. };
  166. static int ct_open(struct inode *inode, struct file *file)
  167. {
  168. struct seq_file *seq;
  169. struct ct_iter_state *st;
  170. int ret;
  171. st = kmalloc(sizeof(struct ct_iter_state), GFP_KERNEL);
  172. if (st == NULL)
  173. return -ENOMEM;
  174. ret = seq_open(file, &ct_seq_ops);
  175. if (ret)
  176. goto out_free;
  177. seq = file->private_data;
  178. seq->private = st;
  179. memset(st, 0, sizeof(struct ct_iter_state));
  180. return ret;
  181. out_free:
  182. kfree(st);
  183. return ret;
  184. }
  185. static const struct file_operations ct_file_ops = {
  186. .owner = THIS_MODULE,
  187. .open = ct_open,
  188. .read = seq_read,
  189. .llseek = seq_lseek,
  190. .release = seq_release_private,
  191. };
  192. /* expects */
  193. static void *exp_seq_start(struct seq_file *s, loff_t *pos)
  194. {
  195. struct list_head *e = &ip_conntrack_expect_list;
  196. loff_t i;
  197. /* strange seq_file api calls stop even if we fail,
  198. * thus we need to grab lock since stop unlocks */
  199. read_lock_bh(&ip_conntrack_lock);
  200. if (list_empty(e))
  201. return NULL;
  202. for (i = 0; i <= *pos; i++) {
  203. e = e->next;
  204. if (e == &ip_conntrack_expect_list)
  205. return NULL;
  206. }
  207. return e;
  208. }
  209. static void *exp_seq_next(struct seq_file *s, void *v, loff_t *pos)
  210. {
  211. struct list_head *e = v;
  212. ++*pos;
  213. e = e->next;
  214. if (e == &ip_conntrack_expect_list)
  215. return NULL;
  216. return e;
  217. }
  218. static void exp_seq_stop(struct seq_file *s, void *v)
  219. {
  220. read_unlock_bh(&ip_conntrack_lock);
  221. }
  222. static int exp_seq_show(struct seq_file *s, void *v)
  223. {
  224. struct ip_conntrack_expect *expect = v;
  225. if (expect->timeout.function)
  226. seq_printf(s, "%ld ", timer_pending(&expect->timeout)
  227. ? (long)(expect->timeout.expires - jiffies)/HZ : 0);
  228. else
  229. seq_printf(s, "- ");
  230. seq_printf(s, "proto=%u ", expect->tuple.dst.protonum);
  231. print_tuple(s, &expect->tuple,
  232. __ip_conntrack_proto_find(expect->tuple.dst.protonum));
  233. return seq_putc(s, '\n');
  234. }
  235. static struct seq_operations exp_seq_ops = {
  236. .start = exp_seq_start,
  237. .next = exp_seq_next,
  238. .stop = exp_seq_stop,
  239. .show = exp_seq_show
  240. };
  241. static int exp_open(struct inode *inode, struct file *file)
  242. {
  243. return seq_open(file, &exp_seq_ops);
  244. }
  245. static const struct file_operations exp_file_ops = {
  246. .owner = THIS_MODULE,
  247. .open = exp_open,
  248. .read = seq_read,
  249. .llseek = seq_lseek,
  250. .release = seq_release
  251. };
  252. static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos)
  253. {
  254. int cpu;
  255. if (*pos == 0)
  256. return SEQ_START_TOKEN;
  257. for (cpu = *pos-1; cpu < NR_CPUS; ++cpu) {
  258. if (!cpu_possible(cpu))
  259. continue;
  260. *pos = cpu+1;
  261. return &per_cpu(ip_conntrack_stat, cpu);
  262. }
  263. return NULL;
  264. }
  265. static void *ct_cpu_seq_next(struct seq_file *seq, void *v, loff_t *pos)
  266. {
  267. int cpu;
  268. for (cpu = *pos; cpu < NR_CPUS; ++cpu) {
  269. if (!cpu_possible(cpu))
  270. continue;
  271. *pos = cpu+1;
  272. return &per_cpu(ip_conntrack_stat, cpu);
  273. }
  274. return NULL;
  275. }
  276. static void ct_cpu_seq_stop(struct seq_file *seq, void *v)
  277. {
  278. }
  279. static int ct_cpu_seq_show(struct seq_file *seq, void *v)
  280. {
  281. unsigned int nr_conntracks = atomic_read(&ip_conntrack_count);
  282. struct ip_conntrack_stat *st = v;
  283. if (v == SEQ_START_TOKEN) {
  284. seq_printf(seq, "entries searched found new invalid ignore delete delete_list insert insert_failed drop early_drop icmp_error expect_new expect_create expect_delete\n");
  285. return 0;
  286. }
  287. seq_printf(seq, "%08x %08x %08x %08x %08x %08x %08x %08x "
  288. "%08x %08x %08x %08x %08x %08x %08x %08x \n",
  289. nr_conntracks,
  290. st->searched,
  291. st->found,
  292. st->new,
  293. st->invalid,
  294. st->ignore,
  295. st->delete,
  296. st->delete_list,
  297. st->insert,
  298. st->insert_failed,
  299. st->drop,
  300. st->early_drop,
  301. st->error,
  302. st->expect_new,
  303. st->expect_create,
  304. st->expect_delete
  305. );
  306. return 0;
  307. }
  308. static struct seq_operations ct_cpu_seq_ops = {
  309. .start = ct_cpu_seq_start,
  310. .next = ct_cpu_seq_next,
  311. .stop = ct_cpu_seq_stop,
  312. .show = ct_cpu_seq_show,
  313. };
  314. static int ct_cpu_seq_open(struct inode *inode, struct file *file)
  315. {
  316. return seq_open(file, &ct_cpu_seq_ops);
  317. }
  318. static const struct file_operations ct_cpu_seq_fops = {
  319. .owner = THIS_MODULE,
  320. .open = ct_cpu_seq_open,
  321. .read = seq_read,
  322. .llseek = seq_lseek,
  323. .release = seq_release_private,
  324. };
  325. #endif
  326. static unsigned int ip_confirm(unsigned int hooknum,
  327. struct sk_buff **pskb,
  328. const struct net_device *in,
  329. const struct net_device *out,
  330. int (*okfn)(struct sk_buff *))
  331. {
  332. /* We've seen it coming out the other side: confirm it */
  333. return ip_conntrack_confirm(pskb);
  334. }
  335. static unsigned int ip_conntrack_help(unsigned int hooknum,
  336. struct sk_buff **pskb,
  337. const struct net_device *in,
  338. const struct net_device *out,
  339. int (*okfn)(struct sk_buff *))
  340. {
  341. struct ip_conntrack *ct;
  342. enum ip_conntrack_info ctinfo;
  343. /* This is where we call the helper: as the packet goes out. */
  344. ct = ip_conntrack_get(*pskb, &ctinfo);
  345. if (ct && ct->helper && ctinfo != IP_CT_RELATED + IP_CT_IS_REPLY) {
  346. unsigned int ret;
  347. ret = ct->helper->help(pskb, ct, ctinfo);
  348. if (ret != NF_ACCEPT)
  349. return ret;
  350. }
  351. return NF_ACCEPT;
  352. }
  353. static unsigned int ip_conntrack_defrag(unsigned int hooknum,
  354. struct sk_buff **pskb,
  355. const struct net_device *in,
  356. const struct net_device *out,
  357. int (*okfn)(struct sk_buff *))
  358. {
  359. #if !defined(CONFIG_IP_NF_NAT) && !defined(CONFIG_IP_NF_NAT_MODULE)
  360. /* Previously seen (loopback)? Ignore. Do this before
  361. fragment check. */
  362. if ((*pskb)->nfct)
  363. return NF_ACCEPT;
  364. #endif
  365. /* Gather fragments. */
  366. if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
  367. *pskb = ip_ct_gather_frags(*pskb,
  368. hooknum == NF_IP_PRE_ROUTING ?
  369. IP_DEFRAG_CONNTRACK_IN :
  370. IP_DEFRAG_CONNTRACK_OUT);
  371. if (!*pskb)
  372. return NF_STOLEN;
  373. }
  374. return NF_ACCEPT;
  375. }
  376. static unsigned int ip_conntrack_local(unsigned int hooknum,
  377. struct sk_buff **pskb,
  378. const struct net_device *in,
  379. const struct net_device *out,
  380. int (*okfn)(struct sk_buff *))
  381. {
  382. /* root is playing with raw sockets. */
  383. if ((*pskb)->len < sizeof(struct iphdr)
  384. || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr)) {
  385. if (net_ratelimit())
  386. printk("ipt_hook: happy cracking.\n");
  387. return NF_ACCEPT;
  388. }
  389. return ip_conntrack_in(hooknum, pskb, in, out, okfn);
  390. }
  391. /* Connection tracking may drop packets, but never alters them, so
  392. make it the first hook. */
  393. static struct nf_hook_ops ip_conntrack_ops[] = {
  394. {
  395. .hook = ip_conntrack_defrag,
  396. .owner = THIS_MODULE,
  397. .pf = PF_INET,
  398. .hooknum = NF_IP_PRE_ROUTING,
  399. .priority = NF_IP_PRI_CONNTRACK_DEFRAG,
  400. },
  401. {
  402. .hook = ip_conntrack_in,
  403. .owner = THIS_MODULE,
  404. .pf = PF_INET,
  405. .hooknum = NF_IP_PRE_ROUTING,
  406. .priority = NF_IP_PRI_CONNTRACK,
  407. },
  408. {
  409. .hook = ip_conntrack_defrag,
  410. .owner = THIS_MODULE,
  411. .pf = PF_INET,
  412. .hooknum = NF_IP_LOCAL_OUT,
  413. .priority = NF_IP_PRI_CONNTRACK_DEFRAG,
  414. },
  415. {
  416. .hook = ip_conntrack_local,
  417. .owner = THIS_MODULE,
  418. .pf = PF_INET,
  419. .hooknum = NF_IP_LOCAL_OUT,
  420. .priority = NF_IP_PRI_CONNTRACK,
  421. },
  422. {
  423. .hook = ip_conntrack_help,
  424. .owner = THIS_MODULE,
  425. .pf = PF_INET,
  426. .hooknum = NF_IP_POST_ROUTING,
  427. .priority = NF_IP_PRI_CONNTRACK_HELPER,
  428. },
  429. {
  430. .hook = ip_conntrack_help,
  431. .owner = THIS_MODULE,
  432. .pf = PF_INET,
  433. .hooknum = NF_IP_LOCAL_IN,
  434. .priority = NF_IP_PRI_CONNTRACK_HELPER,
  435. },
  436. {
  437. .hook = ip_confirm,
  438. .owner = THIS_MODULE,
  439. .pf = PF_INET,
  440. .hooknum = NF_IP_POST_ROUTING,
  441. .priority = NF_IP_PRI_CONNTRACK_CONFIRM,
  442. },
  443. {
  444. .hook = ip_confirm,
  445. .owner = THIS_MODULE,
  446. .pf = PF_INET,
  447. .hooknum = NF_IP_LOCAL_IN,
  448. .priority = NF_IP_PRI_CONNTRACK_CONFIRM,
  449. },
  450. };
  451. /* Sysctl support */
  452. int ip_conntrack_checksum __read_mostly = 1;
  453. #ifdef CONFIG_SYSCTL
  454. /* From ip_conntrack_core.c */
  455. extern int ip_conntrack_max;
  456. extern unsigned int ip_conntrack_htable_size;
  457. /* From ip_conntrack_proto_tcp.c */
  458. extern unsigned int ip_ct_tcp_timeout_syn_sent;
  459. extern unsigned int ip_ct_tcp_timeout_syn_recv;
  460. extern unsigned int ip_ct_tcp_timeout_established;
  461. extern unsigned int ip_ct_tcp_timeout_fin_wait;
  462. extern unsigned int ip_ct_tcp_timeout_close_wait;
  463. extern unsigned int ip_ct_tcp_timeout_last_ack;
  464. extern unsigned int ip_ct_tcp_timeout_time_wait;
  465. extern unsigned int ip_ct_tcp_timeout_close;
  466. extern unsigned int ip_ct_tcp_timeout_max_retrans;
  467. extern int ip_ct_tcp_loose;
  468. extern int ip_ct_tcp_be_liberal;
  469. extern int ip_ct_tcp_max_retrans;
  470. /* From ip_conntrack_proto_udp.c */
  471. extern unsigned int ip_ct_udp_timeout;
  472. extern unsigned int ip_ct_udp_timeout_stream;
  473. /* From ip_conntrack_proto_icmp.c */
  474. extern unsigned int ip_ct_icmp_timeout;
  475. /* From ip_conntrack_proto_generic.c */
  476. extern unsigned int ip_ct_generic_timeout;
  477. /* Log invalid packets of a given protocol */
  478. static int log_invalid_proto_min = 0;
  479. static int log_invalid_proto_max = 255;
  480. static struct ctl_table_header *ip_ct_sysctl_header;
  481. static ctl_table ip_ct_sysctl_table[] = {
  482. {
  483. .ctl_name = NET_IPV4_NF_CONNTRACK_MAX,
  484. .procname = "ip_conntrack_max",
  485. .data = &ip_conntrack_max,
  486. .maxlen = sizeof(int),
  487. .mode = 0644,
  488. .proc_handler = &proc_dointvec,
  489. },
  490. {
  491. .ctl_name = NET_IPV4_NF_CONNTRACK_COUNT,
  492. .procname = "ip_conntrack_count",
  493. .data = &ip_conntrack_count,
  494. .maxlen = sizeof(int),
  495. .mode = 0444,
  496. .proc_handler = &proc_dointvec,
  497. },
  498. {
  499. .ctl_name = NET_IPV4_NF_CONNTRACK_BUCKETS,
  500. .procname = "ip_conntrack_buckets",
  501. .data = &ip_conntrack_htable_size,
  502. .maxlen = sizeof(unsigned int),
  503. .mode = 0444,
  504. .proc_handler = &proc_dointvec,
  505. },
  506. {
  507. .ctl_name = NET_IPV4_NF_CONNTRACK_CHECKSUM,
  508. .procname = "ip_conntrack_checksum",
  509. .data = &ip_conntrack_checksum,
  510. .maxlen = sizeof(int),
  511. .mode = 0644,
  512. .proc_handler = &proc_dointvec,
  513. },
  514. {
  515. .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT,
  516. .procname = "ip_conntrack_tcp_timeout_syn_sent",
  517. .data = &ip_ct_tcp_timeout_syn_sent,
  518. .maxlen = sizeof(unsigned int),
  519. .mode = 0644,
  520. .proc_handler = &proc_dointvec_jiffies,
  521. },
  522. {
  523. .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV,
  524. .procname = "ip_conntrack_tcp_timeout_syn_recv",
  525. .data = &ip_ct_tcp_timeout_syn_recv,
  526. .maxlen = sizeof(unsigned int),
  527. .mode = 0644,
  528. .proc_handler = &proc_dointvec_jiffies,
  529. },
  530. {
  531. .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED,
  532. .procname = "ip_conntrack_tcp_timeout_established",
  533. .data = &ip_ct_tcp_timeout_established,
  534. .maxlen = sizeof(unsigned int),
  535. .mode = 0644,
  536. .proc_handler = &proc_dointvec_jiffies,
  537. },
  538. {
  539. .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT,
  540. .procname = "ip_conntrack_tcp_timeout_fin_wait",
  541. .data = &ip_ct_tcp_timeout_fin_wait,
  542. .maxlen = sizeof(unsigned int),
  543. .mode = 0644,
  544. .proc_handler = &proc_dointvec_jiffies,
  545. },
  546. {
  547. .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT,
  548. .procname = "ip_conntrack_tcp_timeout_close_wait",
  549. .data = &ip_ct_tcp_timeout_close_wait,
  550. .maxlen = sizeof(unsigned int),
  551. .mode = 0644,
  552. .proc_handler = &proc_dointvec_jiffies,
  553. },
  554. {
  555. .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK,
  556. .procname = "ip_conntrack_tcp_timeout_last_ack",
  557. .data = &ip_ct_tcp_timeout_last_ack,
  558. .maxlen = sizeof(unsigned int),
  559. .mode = 0644,
  560. .proc_handler = &proc_dointvec_jiffies,
  561. },
  562. {
  563. .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT,
  564. .procname = "ip_conntrack_tcp_timeout_time_wait",
  565. .data = &ip_ct_tcp_timeout_time_wait,
  566. .maxlen = sizeof(unsigned int),
  567. .mode = 0644,
  568. .proc_handler = &proc_dointvec_jiffies,
  569. },
  570. {
  571. .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE,
  572. .procname = "ip_conntrack_tcp_timeout_close",
  573. .data = &ip_ct_tcp_timeout_close,
  574. .maxlen = sizeof(unsigned int),
  575. .mode = 0644,
  576. .proc_handler = &proc_dointvec_jiffies,
  577. },
  578. {
  579. .ctl_name = NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT,
  580. .procname = "ip_conntrack_udp_timeout",
  581. .data = &ip_ct_udp_timeout,
  582. .maxlen = sizeof(unsigned int),
  583. .mode = 0644,
  584. .proc_handler = &proc_dointvec_jiffies,
  585. },
  586. {
  587. .ctl_name = NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT_STREAM,
  588. .procname = "ip_conntrack_udp_timeout_stream",
  589. .data = &ip_ct_udp_timeout_stream,
  590. .maxlen = sizeof(unsigned int),
  591. .mode = 0644,
  592. .proc_handler = &proc_dointvec_jiffies,
  593. },
  594. {
  595. .ctl_name = NET_IPV4_NF_CONNTRACK_ICMP_TIMEOUT,
  596. .procname = "ip_conntrack_icmp_timeout",
  597. .data = &ip_ct_icmp_timeout,
  598. .maxlen = sizeof(unsigned int),
  599. .mode = 0644,
  600. .proc_handler = &proc_dointvec_jiffies,
  601. },
  602. {
  603. .ctl_name = NET_IPV4_NF_CONNTRACK_GENERIC_TIMEOUT,
  604. .procname = "ip_conntrack_generic_timeout",
  605. .data = &ip_ct_generic_timeout,
  606. .maxlen = sizeof(unsigned int),
  607. .mode = 0644,
  608. .proc_handler = &proc_dointvec_jiffies,
  609. },
  610. {
  611. .ctl_name = NET_IPV4_NF_CONNTRACK_LOG_INVALID,
  612. .procname = "ip_conntrack_log_invalid",
  613. .data = &ip_ct_log_invalid,
  614. .maxlen = sizeof(unsigned int),
  615. .mode = 0644,
  616. .proc_handler = &proc_dointvec_minmax,
  617. .strategy = &sysctl_intvec,
  618. .extra1 = &log_invalid_proto_min,
  619. .extra2 = &log_invalid_proto_max,
  620. },
  621. {
  622. .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS,
  623. .procname = "ip_conntrack_tcp_timeout_max_retrans",
  624. .data = &ip_ct_tcp_timeout_max_retrans,
  625. .maxlen = sizeof(unsigned int),
  626. .mode = 0644,
  627. .proc_handler = &proc_dointvec_jiffies,
  628. },
  629. {
  630. .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_LOOSE,
  631. .procname = "ip_conntrack_tcp_loose",
  632. .data = &ip_ct_tcp_loose,
  633. .maxlen = sizeof(unsigned int),
  634. .mode = 0644,
  635. .proc_handler = &proc_dointvec,
  636. },
  637. {
  638. .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_BE_LIBERAL,
  639. .procname = "ip_conntrack_tcp_be_liberal",
  640. .data = &ip_ct_tcp_be_liberal,
  641. .maxlen = sizeof(unsigned int),
  642. .mode = 0644,
  643. .proc_handler = &proc_dointvec,
  644. },
  645. {
  646. .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_MAX_RETRANS,
  647. .procname = "ip_conntrack_tcp_max_retrans",
  648. .data = &ip_ct_tcp_max_retrans,
  649. .maxlen = sizeof(unsigned int),
  650. .mode = 0644,
  651. .proc_handler = &proc_dointvec,
  652. },
  653. { .ctl_name = 0 }
  654. };
  655. #define NET_IP_CONNTRACK_MAX 2089
  656. static ctl_table ip_ct_netfilter_table[] = {
  657. {
  658. .ctl_name = NET_IPV4_NETFILTER,
  659. .procname = "netfilter",
  660. .mode = 0555,
  661. .child = ip_ct_sysctl_table,
  662. },
  663. {
  664. .ctl_name = NET_IP_CONNTRACK_MAX,
  665. .procname = "ip_conntrack_max",
  666. .data = &ip_conntrack_max,
  667. .maxlen = sizeof(int),
  668. .mode = 0644,
  669. .proc_handler = &proc_dointvec
  670. },
  671. { .ctl_name = 0 }
  672. };
  673. static ctl_table ip_ct_ipv4_table[] = {
  674. {
  675. .ctl_name = NET_IPV4,
  676. .procname = "ipv4",
  677. .mode = 0555,
  678. .child = ip_ct_netfilter_table,
  679. },
  680. { .ctl_name = 0 }
  681. };
  682. static ctl_table ip_ct_net_table[] = {
  683. {
  684. .ctl_name = CTL_NET,
  685. .procname = "net",
  686. .mode = 0555,
  687. .child = ip_ct_ipv4_table,
  688. },
  689. { .ctl_name = 0 }
  690. };
  691. EXPORT_SYMBOL(ip_ct_log_invalid);
  692. #endif /* CONFIG_SYSCTL */
  693. /* FIXME: Allow NULL functions and sub in pointers to generic for
  694. them. --RR */
  695. int ip_conntrack_protocol_register(struct ip_conntrack_protocol *proto)
  696. {
  697. int ret = 0;
  698. write_lock_bh(&ip_conntrack_lock);
  699. if (ip_ct_protos[proto->proto] != &ip_conntrack_generic_protocol) {
  700. ret = -EBUSY;
  701. goto out;
  702. }
  703. rcu_assign_pointer(ip_ct_protos[proto->proto], proto);
  704. out:
  705. write_unlock_bh(&ip_conntrack_lock);
  706. return ret;
  707. }
  708. void ip_conntrack_protocol_unregister(struct ip_conntrack_protocol *proto)
  709. {
  710. write_lock_bh(&ip_conntrack_lock);
  711. rcu_assign_pointer(ip_ct_protos[proto->proto],
  712. &ip_conntrack_generic_protocol);
  713. write_unlock_bh(&ip_conntrack_lock);
  714. synchronize_rcu();
  715. /* Remove all contrack entries for this protocol */
  716. ip_ct_iterate_cleanup(kill_proto, &proto->proto);
  717. }
  718. static int __init ip_conntrack_standalone_init(void)
  719. {
  720. #ifdef CONFIG_PROC_FS
  721. struct proc_dir_entry *proc, *proc_exp, *proc_stat;
  722. #endif
  723. int ret = 0;
  724. ret = ip_conntrack_init();
  725. if (ret < 0)
  726. return ret;
  727. #ifdef CONFIG_PROC_FS
  728. ret = -ENOMEM;
  729. proc = proc_net_fops_create("ip_conntrack", 0440, &ct_file_ops);
  730. if (!proc) goto cleanup_init;
  731. proc_exp = proc_net_fops_create("ip_conntrack_expect", 0440,
  732. &exp_file_ops);
  733. if (!proc_exp) goto cleanup_proc;
  734. proc_stat = create_proc_entry("ip_conntrack", S_IRUGO, proc_net_stat);
  735. if (!proc_stat)
  736. goto cleanup_proc_exp;
  737. proc_stat->proc_fops = &ct_cpu_seq_fops;
  738. proc_stat->owner = THIS_MODULE;
  739. #endif
  740. ret = nf_register_hooks(ip_conntrack_ops, ARRAY_SIZE(ip_conntrack_ops));
  741. if (ret < 0) {
  742. printk("ip_conntrack: can't register hooks.\n");
  743. goto cleanup_proc_stat;
  744. }
  745. #ifdef CONFIG_SYSCTL
  746. ip_ct_sysctl_header = register_sysctl_table(ip_ct_net_table);
  747. if (ip_ct_sysctl_header == NULL) {
  748. printk("ip_conntrack: can't register to sysctl.\n");
  749. ret = -ENOMEM;
  750. goto cleanup_hooks;
  751. }
  752. #endif
  753. return ret;
  754. #ifdef CONFIG_SYSCTL
  755. cleanup_hooks:
  756. nf_unregister_hooks(ip_conntrack_ops, ARRAY_SIZE(ip_conntrack_ops));
  757. #endif
  758. cleanup_proc_stat:
  759. #ifdef CONFIG_PROC_FS
  760. remove_proc_entry("ip_conntrack", proc_net_stat);
  761. cleanup_proc_exp:
  762. proc_net_remove("ip_conntrack_expect");
  763. cleanup_proc:
  764. proc_net_remove("ip_conntrack");
  765. cleanup_init:
  766. #endif /* CONFIG_PROC_FS */
  767. ip_conntrack_cleanup();
  768. return ret;
  769. }
  770. static void __exit ip_conntrack_standalone_fini(void)
  771. {
  772. synchronize_net();
  773. #ifdef CONFIG_SYSCTL
  774. unregister_sysctl_table(ip_ct_sysctl_header);
  775. #endif
  776. nf_unregister_hooks(ip_conntrack_ops, ARRAY_SIZE(ip_conntrack_ops));
  777. #ifdef CONFIG_PROC_FS
  778. remove_proc_entry("ip_conntrack", proc_net_stat);
  779. proc_net_remove("ip_conntrack_expect");
  780. proc_net_remove("ip_conntrack");
  781. #endif /* CONFIG_PROC_FS */
  782. ip_conntrack_cleanup();
  783. }
  784. module_init(ip_conntrack_standalone_init);
  785. module_exit(ip_conntrack_standalone_fini);
  786. /* Some modules need us, but don't depend directly on any symbol.
  787. They should call this. */
  788. void need_conntrack(void)
  789. {
  790. }
  791. #ifdef CONFIG_IP_NF_CONNTRACK_EVENTS
  792. EXPORT_SYMBOL_GPL(ip_conntrack_chain);
  793. EXPORT_SYMBOL_GPL(ip_conntrack_expect_chain);
  794. EXPORT_SYMBOL_GPL(ip_conntrack_register_notifier);
  795. EXPORT_SYMBOL_GPL(ip_conntrack_unregister_notifier);
  796. EXPORT_SYMBOL_GPL(__ip_ct_event_cache_init);
  797. EXPORT_PER_CPU_SYMBOL_GPL(ip_conntrack_ecache);
  798. #endif
  799. EXPORT_SYMBOL(ip_conntrack_protocol_register);
  800. EXPORT_SYMBOL(ip_conntrack_protocol_unregister);
  801. EXPORT_SYMBOL(ip_ct_get_tuple);
  802. EXPORT_SYMBOL(invert_tuplepr);
  803. EXPORT_SYMBOL(ip_conntrack_alter_reply);
  804. EXPORT_SYMBOL(ip_conntrack_destroyed);
  805. EXPORT_SYMBOL(need_conntrack);
  806. EXPORT_SYMBOL(ip_conntrack_helper_register);
  807. EXPORT_SYMBOL(ip_conntrack_helper_unregister);
  808. EXPORT_SYMBOL(ip_ct_iterate_cleanup);
  809. EXPORT_SYMBOL(__ip_ct_refresh_acct);
  810. EXPORT_SYMBOL(ip_conntrack_expect_alloc);
  811. EXPORT_SYMBOL(ip_conntrack_expect_put);
  812. EXPORT_SYMBOL_GPL(__ip_conntrack_expect_find);
  813. EXPORT_SYMBOL_GPL(ip_conntrack_expect_find_get);
  814. EXPORT_SYMBOL(ip_conntrack_expect_related);
  815. EXPORT_SYMBOL(ip_conntrack_unexpect_related);
  816. EXPORT_SYMBOL_GPL(ip_conntrack_expect_list);
  817. EXPORT_SYMBOL_GPL(ip_ct_unlink_expect);
  818. EXPORT_SYMBOL(ip_conntrack_tuple_taken);
  819. EXPORT_SYMBOL(ip_ct_gather_frags);
  820. EXPORT_SYMBOL(ip_conntrack_htable_size);
  821. EXPORT_SYMBOL(ip_conntrack_lock);
  822. EXPORT_SYMBOL(ip_conntrack_hash);
  823. EXPORT_SYMBOL(ip_conntrack_untracked);
  824. EXPORT_SYMBOL_GPL(ip_conntrack_find_get);
  825. #ifdef CONFIG_IP_NF_NAT_NEEDED
  826. EXPORT_SYMBOL(ip_conntrack_tcp_update);
  827. #endif
  828. EXPORT_SYMBOL_GPL(ip_conntrack_flush);
  829. EXPORT_SYMBOL_GPL(__ip_conntrack_find);
  830. EXPORT_SYMBOL_GPL(ip_conntrack_alloc);
  831. EXPORT_SYMBOL_GPL(ip_conntrack_free);
  832. EXPORT_SYMBOL_GPL(ip_conntrack_hash_insert);
  833. EXPORT_SYMBOL_GPL(ip_ct_remove_expectations);
  834. EXPORT_SYMBOL_GPL(ip_conntrack_helper_find_get);
  835. EXPORT_SYMBOL_GPL(ip_conntrack_helper_put);
  836. EXPORT_SYMBOL_GPL(__ip_conntrack_helper_find_byname);
  837. EXPORT_SYMBOL_GPL(ip_conntrack_proto_find_get);
  838. EXPORT_SYMBOL_GPL(ip_conntrack_proto_put);
  839. EXPORT_SYMBOL_GPL(__ip_conntrack_proto_find);
  840. EXPORT_SYMBOL_GPL(ip_conntrack_checksum);
  841. #if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \
  842. defined(CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE)
  843. EXPORT_SYMBOL_GPL(ip_ct_port_tuple_to_nfattr);
  844. EXPORT_SYMBOL_GPL(ip_ct_port_nfattr_to_tuple);
  845. #endif