nf_conntrack_timestamp.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. /*
  2. * (C) 2010 Pablo Neira Ayuso <pablo@netfilter.org>
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2 as
  6. * published by the Free Software Foundation (or any later at your option).
  7. */
  8. #include <linux/netfilter.h>
  9. #include <linux/slab.h>
  10. #include <linux/kernel.h>
  11. #include <linux/moduleparam.h>
  12. #include <net/netfilter/nf_conntrack.h>
  13. #include <net/netfilter/nf_conntrack_extend.h>
  14. #include <net/netfilter/nf_conntrack_timestamp.h>
  15. static bool nf_ct_tstamp __read_mostly;
  16. module_param_named(tstamp, nf_ct_tstamp, bool, 0644);
  17. MODULE_PARM_DESC(tstamp, "Enable connection tracking flow timestamping.");
  18. #ifdef CONFIG_SYSCTL
  19. static struct ctl_table tstamp_sysctl_table[] = {
  20. {
  21. .procname = "nf_conntrack_timestamp",
  22. .data = &init_net.ct.sysctl_tstamp,
  23. .maxlen = sizeof(unsigned int),
  24. .mode = 0644,
  25. .proc_handler = proc_dointvec,
  26. },
  27. {}
  28. };
  29. #endif /* CONFIG_SYSCTL */
  30. static struct nf_ct_ext_type tstamp_extend __read_mostly = {
  31. .len = sizeof(struct nf_conn_tstamp),
  32. .align = __alignof__(struct nf_conn_tstamp),
  33. .id = NF_CT_EXT_TSTAMP,
  34. };
  35. #ifdef CONFIG_SYSCTL
  36. static int nf_conntrack_tstamp_init_sysctl(struct net *net)
  37. {
  38. struct ctl_table *table;
  39. table = kmemdup(tstamp_sysctl_table, sizeof(tstamp_sysctl_table),
  40. GFP_KERNEL);
  41. if (!table)
  42. goto out;
  43. table[0].data = &net->ct.sysctl_tstamp;
  44. /* Don't export sysctls to unprivileged users */
  45. if (net->user_ns != &init_user_ns)
  46. table[0].procname = NULL;
  47. net->ct.tstamp_sysctl_header = register_net_sysctl(net, "net/netfilter",
  48. table);
  49. if (!net->ct.tstamp_sysctl_header) {
  50. printk(KERN_ERR "nf_ct_tstamp: can't register to sysctl.\n");
  51. goto out_register;
  52. }
  53. return 0;
  54. out_register:
  55. kfree(table);
  56. out:
  57. return -ENOMEM;
  58. }
  59. static void nf_conntrack_tstamp_fini_sysctl(struct net *net)
  60. {
  61. struct ctl_table *table;
  62. table = net->ct.tstamp_sysctl_header->ctl_table_arg;
  63. unregister_net_sysctl_table(net->ct.tstamp_sysctl_header);
  64. kfree(table);
  65. }
  66. #else
  67. static int nf_conntrack_tstamp_init_sysctl(struct net *net)
  68. {
  69. return 0;
  70. }
  71. static void nf_conntrack_tstamp_fini_sysctl(struct net *net)
  72. {
  73. }
  74. #endif
  75. int nf_conntrack_tstamp_pernet_init(struct net *net)
  76. {
  77. net->ct.sysctl_tstamp = nf_ct_tstamp;
  78. return nf_conntrack_tstamp_init_sysctl(net);
  79. }
  80. void nf_conntrack_tstamp_pernet_fini(struct net *net)
  81. {
  82. nf_conntrack_tstamp_fini_sysctl(net);
  83. }
  84. int nf_conntrack_tstamp_init(void)
  85. {
  86. int ret;
  87. ret = nf_ct_extend_register(&tstamp_extend);
  88. if (ret < 0)
  89. pr_err("nf_ct_tstamp: Unable to register extension\n");
  90. return ret;
  91. }
  92. void nf_conntrack_tstamp_fini(void)
  93. {
  94. nf_ct_extend_unregister(&tstamp_extend);
  95. }