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        net->ct.tstamp_sysctl_header = register_net_sysctl(net, "net/netfilter",
  55                                                           table);
  56        if (!net->ct.tstamp_sysctl_header) {
  57                printk(KERN_ERR "nf_ct_tstamp: can't register to sysctl.\n");
  58                goto out_register;
  59        }
  60        return 0;
  61
  62out_register:
  63        kfree(table);
  64out:
  65        return -ENOMEM;
  66}
  67
  68static void nf_conntrack_tstamp_fini_sysctl(struct net *net)
  69{
  70        struct ctl_table *table;
  71
  72        table = net->ct.tstamp_sysctl_header->ctl_table_arg;
  73        unregister_net_sysctl_table(net->ct.tstamp_sysctl_header);
  74        kfree(table);
  75}
  76#else
  77static int nf_conntrack_tstamp_init_sysctl(struct net *net)
  78{
  79        return 0;
  80}
  81
  82static void nf_conntrack_tstamp_fini_sysctl(struct net *net)
  83{
  84}
  85#endif
  86
  87int nf_conntrack_tstamp_init(struct net *net)
  88{
  89        int ret;
  90
  91        net->ct.sysctl_tstamp = nf_ct_tstamp;
  92
  93        if (net_eq(net, &init_net)) {
  94                ret = nf_ct_extend_register(&tstamp_extend);
  95                if (ret < 0) {
  96                        printk(KERN_ERR "nf_ct_tstamp: Unable to register "
  97                                        "extension\n");
  98                        goto out_extend_register;
  99                }
 100        }
 101
 102        ret = nf_conntrack_tstamp_init_sysctl(net);
 103        if (ret < 0)
 104                goto out_sysctl;
 105
 106        return 0;
 107
 108out_sysctl:
 109        if (net_eq(net, &init_net))
 110                nf_ct_extend_unregister(&tstamp_extend);
 111out_extend_register:
 112        return ret;
 113}
 114
 115void nf_conntrack_tstamp_fini(struct net *net)
 116{
 117        nf_conntrack_tstamp_fini_sysctl(net);
 118        if (net_eq(net, &init_net))
 119                nf_ct_extend_unregister(&tstamp_extend);
 120}
 121
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.