linux/net/netfilter/nf_conntrack_timestamp.c
<<
>>
Prefs
   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
   9#include <linux/netfilter.h>
  10#include <linux/slab.h>
  11#include <linux/kernel.h>
  12#include <linux/moduleparam.h>
  13
  14#include <net/netfilter/nf_conntrack.h>
  15#include <net/netfilter/nf_conntrack_extend.h>
  16#include <net/netfilter/nf_conntrack_timestamp.h>
  17
  18static bool nf_ct_tstamp __read_mostly;
  19
  20module_param_named(tstamp, nf_ct_tstamp, bool, 0644);
  21MODULE_PARM_DESC(tstamp, "Enable connection tracking flow timestamping.");
  22
  23#ifdef CONFIG_SYSCTL
  24static struct ctl_table tstamp_sysctl_table[] = {
  25        {
  26                .procname       = "nf_conntrack_timestamp",
  27                .data           = &init_net.ct.sysctl_tstamp,
  28                .maxlen         = sizeof(unsigned int),
  29                .mode           = 0644,
  30                .proc_handler   = proc_dointvec,
  31        },
  32        {}
  33};
  34#endif /* CONFIG_SYSCTL */
  35
  36static struct nf_ct_ext_type tstamp_extend __read_mostly = {
  37        .len    = sizeof(struct nf_conn_tstamp),
  38        .align  = __alignof__(struct nf_conn_tstamp),
  39        .id     = NF_CT_EXT_TSTAMP,
  40};
  41
  42#ifdef CONFIG_SYSCTL
  43static int nf_conntrack_tstamp_init_sysctl(struct net *net)
  44{
  45        struct ctl_table *table;
  46
  47        table = kmemdup(tstamp_sysctl_table, sizeof(tstamp_sysctl_table),
  48                        GFP_KERNEL);
  49        if (!table)
  50                goto out;
  51
  52        table[0].data = &net->ct.sysctl_tstamp;
  53
  54        /* Don't export sysctls to unprivileged users */
  55        if (net->user_ns != &init_user_ns)
  56                table[0].procname = NULL;
  57
  58        net->ct.tstamp_sysctl_header = register_net_sysctl(net, "net/netfilter",
  59                                                           table);
  60        if (!net->ct.tstamp_sysctl_header) {
  61                printk(KERN_ERR "nf_ct_tstamp: can't register to sysctl.\n");
  62                goto out_register;
  63        }
  64        return 0;
  65
  66out_register:
  67        kfree(table);
  68out:
  69        return -ENOMEM;
  70}
  71
  72static void nf_conntrack_tstamp_fini_sysctl(struct net *net)
  73{
  74        struct ctl_table *table;
  75
  76        table = net->ct.tstamp_sysctl_header->ctl_table_arg;
  77        unregister_net_sysctl_table(net->ct.tstamp_sysctl_header);
  78        kfree(table);
  79}
  80#else
  81static int nf_conntrack_tstamp_init_sysctl(struct net *net)
  82{
  83        return 0;
  84}
  85
  86static void nf_conntrack_tstamp_fini_sysctl(struct net *net)
  87{
  88}
  89#endif
  90
  91int nf_conntrack_tstamp_pernet_init(struct net *net)
  92{
  93        net->ct.sysctl_tstamp = nf_ct_tstamp;
  94        return nf_conntrack_tstamp_init_sysctl(net);
  95}
  96
  97void nf_conntrack_tstamp_pernet_fini(struct net *net)
  98{
  99        nf_conntrack_tstamp_fini_sysctl(net);
 100}
 101
 102int nf_conntrack_tstamp_init(void)
 103{
 104        int ret;
 105        ret = nf_ct_extend_register(&tstamp_extend);
 106        if (ret < 0)
 107                pr_err("nf_ct_tstamp: Unable to register extension\n");
 108        return ret;
 109}
 110
 111void nf_conntrack_tstamp_fini(void)
 112{
 113        nf_ct_extend_unregister(&tstamp_extend);
 114}
 115