Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

netfilter: netns nf_conntrack: per-netns conntrack accounting

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: Patrick McHardy <kaber@trash.net>

authored by

Alexey Dobriyan and committed by
Patrick McHardy
d716a4df c2a2c7e0

+83 -37
+5 -5
include/net/netfilter/nf_conntrack_acct.h
··· 8 8 9 9 #ifndef _NF_CONNTRACK_ACCT_H 10 10 #define _NF_CONNTRACK_ACCT_H 11 + #include <net/net_namespace.h> 11 12 #include <linux/netfilter/nf_conntrack_common.h> 12 13 #include <linux/netfilter/nf_conntrack_tuple_common.h> 13 14 #include <net/netfilter/nf_conntrack.h> ··· 19 18 u_int64_t bytes; 20 19 }; 21 20 22 - extern int nf_ct_acct; 23 - 24 21 static inline 25 22 struct nf_conn_counter *nf_conn_acct_find(const struct nf_conn *ct) 26 23 { ··· 28 29 static inline 29 30 struct nf_conn_counter *nf_ct_acct_ext_add(struct nf_conn *ct, gfp_t gfp) 30 31 { 32 + struct net *net = nf_ct_net(ct); 31 33 struct nf_conn_counter *acct; 32 34 33 - if (!nf_ct_acct) 35 + if (!net->ct.sysctl_acct) 34 36 return NULL; 35 37 36 38 acct = nf_ct_ext_add(ct, NF_CT_EXT_ACCT, gfp); ··· 45 45 extern unsigned int 46 46 seq_print_acct(struct seq_file *s, const struct nf_conn *ct, int dir); 47 47 48 - extern int nf_conntrack_acct_init(void); 49 - extern void nf_conntrack_acct_fini(void); 48 + extern int nf_conntrack_acct_init(struct net *net); 49 + extern void nf_conntrack_acct_fini(struct net *net); 50 50 51 51 #endif /* _NF_CONNTRACK_ACCT_H */
+2
include/net/netns/conntrack.h
··· 17 17 #ifdef CONFIG_NF_CONNTRACK_EVENTS 18 18 struct nf_conntrack_ecache *ecache; 19 19 #endif 20 + int sysctl_acct; 20 21 int sysctl_checksum; 21 22 unsigned int sysctl_log_invalid; /* Log invalid packets */ 22 23 #ifdef CONFIG_SYSCTL 23 24 struct ctl_table_header *sysctl_header; 25 + struct ctl_table_header *acct_sysctl_header; 24 26 #endif 25 27 int hash_vmalloc; 26 28 int expect_vmalloc;
+74 -30
net/netfilter/nf_conntrack_acct.c
··· 22 22 #define NF_CT_ACCT_DEFAULT 0 23 23 #endif 24 24 25 - int nf_ct_acct __read_mostly = NF_CT_ACCT_DEFAULT; 26 - EXPORT_SYMBOL_GPL(nf_ct_acct); 25 + static int nf_ct_acct __read_mostly = NF_CT_ACCT_DEFAULT; 27 26 28 27 module_param_named(acct, nf_ct_acct, bool, 0644); 29 28 MODULE_PARM_DESC(acct, "Enable connection tracking flow accounting."); 30 29 31 30 #ifdef CONFIG_SYSCTL 32 - static struct ctl_table_header *acct_sysctl_header; 33 31 static struct ctl_table acct_sysctl_table[] = { 34 32 { 35 33 .ctl_name = CTL_UNNUMBERED, 36 34 .procname = "nf_conntrack_acct", 37 - .data = &nf_ct_acct, 35 + .data = &init_net.ct.sysctl_acct, 38 36 .maxlen = sizeof(unsigned int), 39 37 .mode = 0644, 40 38 .proc_handler = &proc_dointvec, ··· 62 64 .id = NF_CT_EXT_ACCT, 63 65 }; 64 66 65 - int nf_conntrack_acct_init(void) 66 - { 67 - int ret; 68 - 69 - #ifdef CONFIG_NF_CT_ACCT 70 - printk(KERN_WARNING "CONFIG_NF_CT_ACCT is deprecated and will be removed soon. Plase use\n"); 71 - printk(KERN_WARNING "nf_conntrack.acct=1 kernel paramater, acct=1 nf_conntrack module option or\n"); 72 - printk(KERN_WARNING "sysctl net.netfilter.nf_conntrack_acct=1 to enable it.\n"); 73 - #endif 74 - 75 - ret = nf_ct_extend_register(&acct_extend); 76 - if (ret < 0) { 77 - printk(KERN_ERR "nf_conntrack_acct: Unable to register extension\n"); 78 - return ret; 79 - } 80 - 81 67 #ifdef CONFIG_SYSCTL 82 - acct_sysctl_header = register_sysctl_paths(nf_net_netfilter_sysctl_path, 83 - acct_sysctl_table); 68 + static int nf_conntrack_acct_init_sysctl(struct net *net) 69 + { 70 + struct ctl_table *table; 84 71 85 - if (!acct_sysctl_header) { 86 - nf_ct_extend_unregister(&acct_extend); 72 + table = kmemdup(acct_sysctl_table, sizeof(acct_sysctl_table), 73 + GFP_KERNEL); 74 + if (!table) 75 + goto out; 87 76 77 + table[0].data = &net->ct.sysctl_acct; 78 + 79 + net->ct.acct_sysctl_header = register_net_sysctl_table(net, 80 + nf_net_netfilter_sysctl_path, table); 81 + if (!net->ct.acct_sysctl_header) { 88 82 printk(KERN_ERR "nf_conntrack_acct: can't register to sysctl.\n"); 89 - return -ENOMEM; 83 + goto out_register; 90 84 } 91 - #endif 85 + return 0; 92 86 87 + out_register: 88 + kfree(table); 89 + out: 90 + return -ENOMEM; 91 + } 92 + 93 + static void nf_conntrack_acct_fini_sysctl(struct net *net) 94 + { 95 + struct ctl_table *table; 96 + 97 + table = net->ct.acct_sysctl_header->ctl_table_arg; 98 + unregister_net_sysctl_table(net->ct.acct_sysctl_header); 99 + kfree(table); 100 + } 101 + #else 102 + static int nf_conntrack_acct_init_sysctl(struct net *net) 103 + { 93 104 return 0; 94 105 } 95 106 96 - void nf_conntrack_acct_fini(void) 107 + static void nf_conntrack_acct_fini_sysctl(struct net *net) 97 108 { 98 - #ifdef CONFIG_SYSCTL 99 - unregister_sysctl_table(acct_sysctl_header); 109 + } 100 110 #endif 101 - nf_ct_extend_unregister(&acct_extend); 111 + 112 + int nf_conntrack_acct_init(struct net *net) 113 + { 114 + int ret; 115 + 116 + net->ct.sysctl_acct = nf_ct_acct; 117 + 118 + if (net_eq(net, &init_net)) { 119 + #ifdef CONFIG_NF_CT_ACCT 120 + printk(KERN_WARNING "CONFIG_NF_CT_ACCT is deprecated and will be removed soon. Plase use\n"); 121 + printk(KERN_WARNING "nf_conntrack.acct=1 kernel paramater, acct=1 nf_conntrack module option or\n"); 122 + printk(KERN_WARNING "sysctl net.netfilter.nf_conntrack_acct=1 to enable it.\n"); 123 + #endif 124 + 125 + ret = nf_ct_extend_register(&acct_extend); 126 + if (ret < 0) { 127 + printk(KERN_ERR "nf_conntrack_acct: Unable to register extension\n"); 128 + goto out_extend_register; 129 + } 130 + } 131 + 132 + ret = nf_conntrack_acct_init_sysctl(net); 133 + if (ret < 0) 134 + goto out_sysctl; 135 + 136 + return 0; 137 + 138 + out_sysctl: 139 + if (net_eq(net, &init_net)) 140 + nf_ct_extend_unregister(&acct_extend); 141 + out_extend_register: 142 + return ret; 143 + } 144 + 145 + void nf_conntrack_acct_fini(struct net *net) 146 + { 147 + nf_conntrack_acct_fini_sysctl(net); 148 + if (net_eq(net, &init_net)) 149 + nf_ct_extend_unregister(&acct_extend); 102 150 }
+2 -2
net/netfilter/nf_conntrack_core.c
··· 1039 1039 nf_ct_free_hashtable(net->ct.hash, net->ct.hash_vmalloc, 1040 1040 nf_conntrack_htable_size); 1041 1041 1042 - nf_conntrack_acct_fini(); 1042 + nf_conntrack_acct_fini(net); 1043 1043 nf_conntrack_expect_fini(net); 1044 1044 free_percpu(net->ct.stat); 1045 1045 nf_conntrack_helper_fini(); ··· 1191 1191 if (ret < 0) 1192 1192 goto out_fini_expect; 1193 1193 1194 - ret = nf_conntrack_acct_init(); 1194 + ret = nf_conntrack_acct_init(net); 1195 1195 if (ret < 0) 1196 1196 goto out_fini_helper; 1197 1197