Commit 584015727a3b88b46602b20077b46cd04f8b4ab3
Committed by
David S. Miller
1 parent
07a7c1070e
Exists in
master
and in
4 other branches
netfilter: accounting rework: ct_extend + 64bit counters (v4)
Initially netfilter has had 64bit counters for conntrack-based accounting, but it was changed in 2.6.14 to save memory. Unfortunately in-kernel 64bit counters are still required, for example for "connbytes" extension. However, 64bit counters waste a lot of memory and it was not possible to enable/disable it runtime. This patch: - reimplements accounting with respect to the extension infrastructure, - makes one global version of seq_print_acct() instead of two seq_print_counters(), - makes it possible to enable it at boot time (for CONFIG_SYSCTL/CONFIG_SYSFS=n), - makes it possible to enable/disable it at runtime by sysctl or sysfs, - extends counters from 32bit to 64bit, - renames ip_conntrack_counter -> nf_conn_counter, - enables accounting code unconditionally (no longer depends on CONFIG_NF_CT_ACCT), - set initial accounting enable state based on CONFIG_NF_CT_ACCT - removes buggy IPCT_COUNTER_FILLING event handling. If accounting is enabled newly created connections get additional acct extend. Old connections are not changed as it is not possible to add a ct_extend area to confirmed conntrack. Accounting is performed for all connections with acct extend regardless of a current state of "net.netfilter.nf_conntrack_acct". Signed-off-by: Krzysztof Piotr Oledzki <ole@ans.pl> Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Showing 15 changed files with 248 additions and 86 deletions Side-by-side Diff
- Documentation/feature-removal-schedule.txt
- Documentation/kernel-parameters.txt
- include/linux/netfilter/nf_conntrack_common.h
- include/linux/netfilter/nfnetlink_conntrack.h
- include/net/netfilter/nf_conntrack.h
- include/net/netfilter/nf_conntrack_acct.h
- include/net/netfilter/nf_conntrack_extend.h
- net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
- net/netfilter/Kconfig
- net/netfilter/Makefile
- net/netfilter/nf_conntrack_acct.c
- net/netfilter/nf_conntrack_core.c
- net/netfilter/nf_conntrack_netlink.c
- net/netfilter/nf_conntrack_standalone.c
- net/netfilter/xt_connbytes.c
Documentation/feature-removal-schedule.txt
... | ... | @@ -336,4 +336,13 @@ |
336 | 336 | Why: Over 1K .text/.data size reduction, data is available in other |
337 | 337 | ways (ioctls) |
338 | 338 | Who: Johannes Berg <johannes@sipsolutions.net> |
339 | + | |
340 | +--------------------------- | |
341 | + | |
342 | +What: CONFIG_NF_CT_ACCT | |
343 | +When: 2.6.29 | |
344 | +Why: Accounting can now be enabled/disabled without kernel recompilation. | |
345 | + Currently used only to set a default value for a feature that is also | |
346 | + controlled by a kernel/module/sysfs/sysctl parameter. | |
347 | +Who: Krzysztof Piotr Oledzki <ole@ans.pl> |
Documentation/kernel-parameters.txt
... | ... | @@ -1279,6 +1279,13 @@ |
1279 | 1279 | This usage is only documented in each driver source |
1280 | 1280 | file if at all. |
1281 | 1281 | |
1282 | + nf_conntrack.acct= | |
1283 | + [NETFILTER] Enable connection tracking flow accounting | |
1284 | + 0 to disable accounting | |
1285 | + 1 to enable accounting | |
1286 | + Default value depends on CONFIG_NF_CT_ACCT that is | |
1287 | + going to be removed in 2.6.29. | |
1288 | + | |
1282 | 1289 | nfsaddrs= [NFS] |
1283 | 1290 | See Documentation/filesystems/nfsroot.txt. |
1284 | 1291 |
include/linux/netfilter/nf_conntrack_common.h
... | ... | @@ -122,7 +122,7 @@ |
122 | 122 | IPCT_NATINFO_BIT = 10, |
123 | 123 | IPCT_NATINFO = (1 << IPCT_NATINFO_BIT), |
124 | 124 | |
125 | - /* Counter highest bit has been set */ | |
125 | + /* Counter highest bit has been set, unused */ | |
126 | 126 | IPCT_COUNTER_FILLING_BIT = 11, |
127 | 127 | IPCT_COUNTER_FILLING = (1 << IPCT_COUNTER_FILLING_BIT), |
128 | 128 | |
... | ... | @@ -145,12 +145,6 @@ |
145 | 145 | }; |
146 | 146 | |
147 | 147 | #ifdef __KERNEL__ |
148 | -struct ip_conntrack_counter | |
149 | -{ | |
150 | - u_int32_t packets; | |
151 | - u_int32_t bytes; | |
152 | -}; | |
153 | - | |
154 | 148 | struct ip_conntrack_stat |
155 | 149 | { |
156 | 150 | unsigned int searched; |
include/linux/netfilter/nfnetlink_conntrack.h
... | ... | @@ -115,10 +115,10 @@ |
115 | 115 | |
116 | 116 | enum ctattr_counters { |
117 | 117 | CTA_COUNTERS_UNSPEC, |
118 | - CTA_COUNTERS_PACKETS, /* old 64bit counters */ | |
119 | - CTA_COUNTERS_BYTES, /* old 64bit counters */ | |
120 | - CTA_COUNTERS32_PACKETS, | |
121 | - CTA_COUNTERS32_BYTES, | |
118 | + CTA_COUNTERS_PACKETS, /* 64bit counters */ | |
119 | + CTA_COUNTERS_BYTES, /* 64bit counters */ | |
120 | + CTA_COUNTERS32_PACKETS, /* old 32bit counters, unused */ | |
121 | + CTA_COUNTERS32_BYTES, /* old 32bit counters, unused */ | |
122 | 122 | __CTA_COUNTERS_MAX |
123 | 123 | }; |
124 | 124 | #define CTA_COUNTERS_MAX (__CTA_COUNTERS_MAX - 1) |
include/net/netfilter/nf_conntrack.h
... | ... | @@ -88,7 +88,6 @@ |
88 | 88 | u8 expecting[NF_CT_MAX_EXPECT_CLASSES]; |
89 | 89 | }; |
90 | 90 | |
91 | - | |
92 | 91 | #include <net/netfilter/ipv4/nf_conntrack_ipv4.h> |
93 | 92 | #include <net/netfilter/ipv6/nf_conntrack_ipv6.h> |
94 | 93 | |
... | ... | @@ -110,11 +109,6 @@ |
110 | 109 | |
111 | 110 | /* Timer function; drops refcnt when it goes off. */ |
112 | 111 | struct timer_list timeout; |
113 | - | |
114 | -#ifdef CONFIG_NF_CT_ACCT | |
115 | - /* Accounting Information (same cache line as other written members) */ | |
116 | - struct ip_conntrack_counter counters[IP_CT_DIR_MAX]; | |
117 | -#endif | |
118 | 112 | |
119 | 113 | #if defined(CONFIG_NF_CONNTRACK_MARK) |
120 | 114 | u_int32_t mark; |
include/net/netfilter/nf_conntrack_acct.h
1 | +/* | |
2 | + * (C) 2008 Krzysztof Piotr Oledzki <ole@ans.pl> | |
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. | |
7 | + */ | |
8 | + | |
9 | +#ifndef _NF_CONNTRACK_ACCT_H | |
10 | +#define _NF_CONNTRACK_ACCT_H | |
11 | +#include <linux/netfilter/nf_conntrack_common.h> | |
12 | +#include <linux/netfilter/nf_conntrack_tuple_common.h> | |
13 | +#include <net/netfilter/nf_conntrack.h> | |
14 | +#include <net/netfilter/nf_conntrack_extend.h> | |
15 | + | |
16 | +struct nf_conn_counter { | |
17 | + u_int64_t packets; | |
18 | + u_int64_t bytes; | |
19 | +}; | |
20 | + | |
21 | +extern int nf_ct_acct; | |
22 | + | |
23 | +static inline | |
24 | +struct nf_conn_counter *nf_conn_acct_find(const struct nf_conn *ct) | |
25 | +{ | |
26 | + return nf_ct_ext_find(ct, NF_CT_EXT_ACCT); | |
27 | +} | |
28 | + | |
29 | +static inline | |
30 | +struct nf_conn_counter *nf_ct_acct_ext_add(struct nf_conn *ct, gfp_t gfp) | |
31 | +{ | |
32 | + struct nf_conn_counter *acct; | |
33 | + | |
34 | + if (!nf_ct_acct) | |
35 | + return NULL; | |
36 | + | |
37 | + acct = nf_ct_ext_add(ct, NF_CT_EXT_ACCT, gfp); | |
38 | + if (!acct) | |
39 | + pr_debug("failed to add accounting extension area"); | |
40 | + | |
41 | + | |
42 | + return acct; | |
43 | +}; | |
44 | + | |
45 | +extern unsigned int | |
46 | +seq_print_acct(struct seq_file *s, const struct nf_conn *ct, int dir); | |
47 | + | |
48 | +extern int nf_conntrack_acct_init(void); | |
49 | +extern void nf_conntrack_acct_fini(void); | |
50 | + | |
51 | +#endif /* _NF_CONNTRACK_ACCT_H */ |
include/net/netfilter/nf_conntrack_extend.h
... | ... | @@ -7,11 +7,13 @@ |
7 | 7 | { |
8 | 8 | NF_CT_EXT_HELPER, |
9 | 9 | NF_CT_EXT_NAT, |
10 | + NF_CT_EXT_ACCT, | |
10 | 11 | NF_CT_EXT_NUM, |
11 | 12 | }; |
12 | 13 | |
13 | 14 | #define NF_CT_EXT_HELPER_TYPE struct nf_conn_help |
14 | 15 | #define NF_CT_EXT_NAT_TYPE struct nf_conn_nat |
16 | +#define NF_CT_EXT_ACCT_TYPE struct nf_conn_counter | |
15 | 17 | |
16 | 18 | /* Extensions: optional stuff which isn't permanently in struct. */ |
17 | 19 | struct nf_ct_ext { |
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
... | ... | @@ -18,20 +18,8 @@ |
18 | 18 | #include <net/netfilter/nf_conntrack_l3proto.h> |
19 | 19 | #include <net/netfilter/nf_conntrack_l4proto.h> |
20 | 20 | #include <net/netfilter/nf_conntrack_expect.h> |
21 | +#include <net/netfilter/nf_conntrack_acct.h> | |
21 | 22 | |
22 | -#ifdef CONFIG_NF_CT_ACCT | |
23 | -static unsigned int | |
24 | -seq_print_counters(struct seq_file *s, | |
25 | - const struct ip_conntrack_counter *counter) | |
26 | -{ | |
27 | - return seq_printf(s, "packets=%llu bytes=%llu ", | |
28 | - (unsigned long long)counter->packets, | |
29 | - (unsigned long long)counter->bytes); | |
30 | -} | |
31 | -#else | |
32 | -#define seq_print_counters(x, y) 0 | |
33 | -#endif | |
34 | - | |
35 | 23 | struct ct_iter_state { |
36 | 24 | unsigned int bucket; |
37 | 25 | }; |
... | ... | @@ -127,7 +115,7 @@ |
127 | 115 | l3proto, l4proto)) |
128 | 116 | return -ENOSPC; |
129 | 117 | |
130 | - if (seq_print_counters(s, &ct->counters[IP_CT_DIR_ORIGINAL])) | |
118 | + if (seq_print_acct(s, ct, IP_CT_DIR_ORIGINAL)) | |
131 | 119 | return -ENOSPC; |
132 | 120 | |
133 | 121 | if (!(test_bit(IPS_SEEN_REPLY_BIT, &ct->status))) |
... | ... | @@ -138,7 +126,7 @@ |
138 | 126 | l3proto, l4proto)) |
139 | 127 | return -ENOSPC; |
140 | 128 | |
141 | - if (seq_print_counters(s, &ct->counters[IP_CT_DIR_REPLY])) | |
129 | + if (seq_print_acct(s, ct, IP_CT_DIR_REPLY)) | |
142 | 130 | return -ENOSPC; |
143 | 131 | |
144 | 132 | if (test_bit(IPS_ASSURED_BIT, &ct->status)) |
net/netfilter/Kconfig
... | ... | @@ -49,6 +49,15 @@ |
49 | 49 | Those counters can be used for flow-based accounting or the |
50 | 50 | `connbytes' match. |
51 | 51 | |
52 | + Please note that currently this option only sets a default state. | |
53 | + You may change it at boot time with nf_conntrack.acct=0/1 kernel | |
54 | + paramater or by loading the nf_conntrack module with acct=0/1. | |
55 | + | |
56 | + You may also disable/enable it on a running system with: | |
57 | + sysctl net.netfilter.nf_conntrack_acct=0/1 | |
58 | + | |
59 | + This option will be removed in 2.6.29. | |
60 | + | |
52 | 61 | If unsure, say `N'. |
53 | 62 | |
54 | 63 | config NF_CONNTRACK_MARK |
net/netfilter/Makefile
1 | 1 | netfilter-objs := core.o nf_log.o nf_queue.o nf_sockopt.o |
2 | 2 | |
3 | -nf_conntrack-y := nf_conntrack_core.o nf_conntrack_standalone.o nf_conntrack_expect.o nf_conntrack_helper.o nf_conntrack_proto.o nf_conntrack_l3proto_generic.o nf_conntrack_proto_generic.o nf_conntrack_proto_tcp.o nf_conntrack_proto_udp.o nf_conntrack_extend.o | |
3 | +nf_conntrack-y := nf_conntrack_core.o nf_conntrack_standalone.o nf_conntrack_expect.o nf_conntrack_helper.o nf_conntrack_proto.o nf_conntrack_l3proto_generic.o nf_conntrack_proto_generic.o nf_conntrack_proto_tcp.o nf_conntrack_proto_udp.o nf_conntrack_extend.o nf_conntrack_acct.o | |
4 | 4 | nf_conntrack-$(CONFIG_NF_CONNTRACK_EVENTS) += nf_conntrack_ecache.o |
5 | 5 | |
6 | 6 | obj-$(CONFIG_NETFILTER) = netfilter.o |
net/netfilter/nf_conntrack_acct.c
1 | +/* Accouting handling for netfilter. */ | |
2 | + | |
3 | +/* | |
4 | + * (C) 2008 Krzysztof Piotr Oledzki <ole@ans.pl> | |
5 | + * | |
6 | + * This program is free software; you can redistribute it and/or modify | |
7 | + * it under the terms of the GNU General Public License version 2 as | |
8 | + * published by the Free Software Foundation. | |
9 | + */ | |
10 | + | |
11 | +#include <linux/netfilter.h> | |
12 | +#include <linux/kernel.h> | |
13 | +#include <linux/moduleparam.h> | |
14 | + | |
15 | +#include <net/netfilter/nf_conntrack.h> | |
16 | +#include <net/netfilter/nf_conntrack_extend.h> | |
17 | +#include <net/netfilter/nf_conntrack_acct.h> | |
18 | + | |
19 | +#ifdef CONFIG_NF_CT_ACCT | |
20 | +#define NF_CT_ACCT_DEFAULT 1 | |
21 | +#else | |
22 | +#define NF_CT_ACCT_DEFAULT 0 | |
23 | +#endif | |
24 | + | |
25 | +int nf_ct_acct __read_mostly = NF_CT_ACCT_DEFAULT; | |
26 | +EXPORT_SYMBOL_GPL(nf_ct_acct); | |
27 | + | |
28 | +module_param_named(acct, nf_ct_acct, bool, 0644); | |
29 | +MODULE_PARM_DESC(acct, "Enable connection tracking flow accounting."); | |
30 | + | |
31 | +#ifdef CONFIG_SYSCTL | |
32 | +static struct ctl_table_header *acct_sysctl_header; | |
33 | +static struct ctl_table acct_sysctl_table[] = { | |
34 | + { | |
35 | + .ctl_name = CTL_UNNUMBERED, | |
36 | + .procname = "nf_conntrack_acct", | |
37 | + .data = &nf_ct_acct, | |
38 | + .maxlen = sizeof(unsigned int), | |
39 | + .mode = 0644, | |
40 | + .proc_handler = &proc_dointvec, | |
41 | + }, | |
42 | + {} | |
43 | +}; | |
44 | +#endif /* CONFIG_SYSCTL */ | |
45 | + | |
46 | +unsigned int | |
47 | +seq_print_acct(struct seq_file *s, const struct nf_conn *ct, int dir) | |
48 | +{ | |
49 | + struct nf_conn_counter *acct; | |
50 | + | |
51 | + acct = nf_conn_acct_find(ct); | |
52 | + if (!acct) | |
53 | + return 0; | |
54 | + | |
55 | + return seq_printf(s, "packets=%llu bytes=%llu ", | |
56 | + (unsigned long long)acct[dir].packets, | |
57 | + (unsigned long long)acct[dir].bytes); | |
58 | +}; | |
59 | +EXPORT_SYMBOL_GPL(seq_print_acct); | |
60 | + | |
61 | +static struct nf_ct_ext_type acct_extend __read_mostly = { | |
62 | + .len = sizeof(struct nf_conn_counter[IP_CT_DIR_MAX]), | |
63 | + .align = __alignof__(struct nf_conn_counter[IP_CT_DIR_MAX]), | |
64 | + .id = NF_CT_EXT_ACCT, | |
65 | +}; | |
66 | + | |
67 | +int nf_conntrack_acct_init(void) | |
68 | +{ | |
69 | + int ret; | |
70 | + | |
71 | +#ifdef CONFIG_NF_CT_ACCT | |
72 | + printk(KERN_WARNING "CONFIG_NF_CT_ACCT is deprecated and will be removed soon. Plase use\n"); | |
73 | + printk(KERN_WARNING "nf_conntrack.acct=1 kernel paramater, acct=1 nf_conntrack module option or\n"); | |
74 | + printk(KERN_WARNING "sysctl net.netfilter.nf_conntrack_acct=1 to enable it.\n"); | |
75 | +#endif | |
76 | + | |
77 | + ret = nf_ct_extend_register(&acct_extend); | |
78 | + if (ret < 0) { | |
79 | + printk(KERN_ERR "nf_conntrack_acct: Unable to register extension\n"); | |
80 | + return ret; | |
81 | + } | |
82 | + | |
83 | +#ifdef CONFIG_SYSCTL | |
84 | + acct_sysctl_header = register_sysctl_paths(nf_net_netfilter_sysctl_path, | |
85 | + acct_sysctl_table); | |
86 | + | |
87 | + if (!acct_sysctl_header) { | |
88 | + nf_ct_extend_unregister(&acct_extend); | |
89 | + | |
90 | + printk(KERN_ERR "nf_conntrack_acct: can't register to sysctl.\n"); | |
91 | + return -ENOMEM; | |
92 | + } | |
93 | +#endif | |
94 | + | |
95 | + return 0; | |
96 | +} | |
97 | + | |
98 | +void nf_conntrack_acct_fini(void) | |
99 | +{ | |
100 | +#ifdef CONFIG_SYSCTL | |
101 | + unregister_sysctl_table(acct_sysctl_header); | |
102 | +#endif | |
103 | + nf_ct_extend_unregister(&acct_extend); | |
104 | +} |
net/netfilter/nf_conntrack_core.c
... | ... | @@ -37,6 +37,7 @@ |
37 | 37 | #include <net/netfilter/nf_conntrack_helper.h> |
38 | 38 | #include <net/netfilter/nf_conntrack_core.h> |
39 | 39 | #include <net/netfilter/nf_conntrack_extend.h> |
40 | +#include <net/netfilter/nf_conntrack_acct.h> | |
40 | 41 | |
41 | 42 | #define NF_CONNTRACK_VERSION "0.5.0" |
42 | 43 | |
... | ... | @@ -555,6 +556,8 @@ |
555 | 556 | return NULL; |
556 | 557 | } |
557 | 558 | |
559 | + nf_ct_acct_ext_add(ct, GFP_ATOMIC); | |
560 | + | |
558 | 561 | spin_lock_bh(&nf_conntrack_lock); |
559 | 562 | exp = nf_ct_find_expectation(tuple); |
560 | 563 | if (exp) { |
561 | 564 | |
562 | 565 | |
563 | 566 | |
... | ... | @@ -828,17 +831,16 @@ |
828 | 831 | } |
829 | 832 | |
830 | 833 | acct: |
831 | -#ifdef CONFIG_NF_CT_ACCT | |
832 | 834 | if (do_acct) { |
833 | - ct->counters[CTINFO2DIR(ctinfo)].packets++; | |
834 | - ct->counters[CTINFO2DIR(ctinfo)].bytes += | |
835 | - skb->len - skb_network_offset(skb); | |
835 | + struct nf_conn_counter *acct; | |
836 | 836 | |
837 | - if ((ct->counters[CTINFO2DIR(ctinfo)].packets & 0x80000000) | |
838 | - || (ct->counters[CTINFO2DIR(ctinfo)].bytes & 0x80000000)) | |
839 | - event |= IPCT_COUNTER_FILLING; | |
837 | + acct = nf_conn_acct_find(ct); | |
838 | + if (acct) { | |
839 | + acct[CTINFO2DIR(ctinfo)].packets++; | |
840 | + acct[CTINFO2DIR(ctinfo)].bytes += | |
841 | + skb->len - skb_network_offset(skb); | |
842 | + } | |
840 | 843 | } |
841 | -#endif | |
842 | 844 | |
843 | 845 | spin_unlock_bh(&nf_conntrack_lock); |
844 | 846 | |
845 | 847 | |
846 | 848 | |
847 | 849 | |
... | ... | @@ -853,15 +855,19 @@ |
853 | 855 | const struct sk_buff *skb, |
854 | 856 | int do_acct) |
855 | 857 | { |
856 | -#ifdef CONFIG_NF_CT_ACCT | |
857 | 858 | if (do_acct) { |
859 | + struct nf_conn_counter *acct; | |
860 | + | |
858 | 861 | spin_lock_bh(&nf_conntrack_lock); |
859 | - ct->counters[CTINFO2DIR(ctinfo)].packets++; | |
860 | - ct->counters[CTINFO2DIR(ctinfo)].bytes += | |
861 | - skb->len - skb_network_offset(skb); | |
862 | + acct = nf_conn_acct_find(ct); | |
863 | + if (acct) { | |
864 | + acct[CTINFO2DIR(ctinfo)].packets++; | |
865 | + acct[CTINFO2DIR(ctinfo)].bytes += | |
866 | + skb->len - skb_network_offset(skb); | |
867 | + } | |
862 | 868 | spin_unlock_bh(&nf_conntrack_lock); |
863 | 869 | } |
864 | -#endif | |
870 | + | |
865 | 871 | if (del_timer(&ct->timeout)) { |
866 | 872 | ct->timeout.function((unsigned long)ct); |
867 | 873 | return true; |
... | ... | @@ -1029,6 +1035,7 @@ |
1029 | 1035 | nf_conntrack_proto_fini(); |
1030 | 1036 | nf_conntrack_helper_fini(); |
1031 | 1037 | nf_conntrack_expect_fini(); |
1038 | + nf_conntrack_acct_fini(); | |
1032 | 1039 | } |
1033 | 1040 | |
1034 | 1041 | struct hlist_head *nf_ct_alloc_hashtable(unsigned int *sizep, int *vmalloced) |
... | ... | @@ -1168,6 +1175,10 @@ |
1168 | 1175 | if (ret < 0) |
1169 | 1176 | goto out_fini_expect; |
1170 | 1177 | |
1178 | + ret = nf_conntrack_acct_init(); | |
1179 | + if (ret < 0) | |
1180 | + goto out_fini_helper; | |
1181 | + | |
1171 | 1182 | /* For use by REJECT target */ |
1172 | 1183 | rcu_assign_pointer(ip_ct_attach, nf_conntrack_attach); |
1173 | 1184 | rcu_assign_pointer(nf_ct_destroy, destroy_conntrack); |
... | ... | @@ -1180,6 +1191,8 @@ |
1180 | 1191 | |
1181 | 1192 | return ret; |
1182 | 1193 | |
1194 | +out_fini_helper: | |
1195 | + nf_conntrack_helper_fini(); | |
1183 | 1196 | out_fini_expect: |
1184 | 1197 | nf_conntrack_expect_fini(); |
1185 | 1198 | out_fini_proto: |
net/netfilter/nf_conntrack_netlink.c
... | ... | @@ -37,6 +37,7 @@ |
37 | 37 | #include <net/netfilter/nf_conntrack_l3proto.h> |
38 | 38 | #include <net/netfilter/nf_conntrack_l4proto.h> |
39 | 39 | #include <net/netfilter/nf_conntrack_tuple.h> |
40 | +#include <net/netfilter/nf_conntrack_acct.h> | |
40 | 41 | #ifdef CONFIG_NF_NAT_NEEDED |
41 | 42 | #include <net/netfilter/nf_nat_core.h> |
42 | 43 | #include <net/netfilter/nf_nat_protocol.h> |
43 | 44 | |
44 | 45 | |
45 | 46 | |
... | ... | @@ -206,22 +207,26 @@ |
206 | 207 | return -1; |
207 | 208 | } |
208 | 209 | |
209 | -#ifdef CONFIG_NF_CT_ACCT | |
210 | 210 | static int |
211 | 211 | ctnetlink_dump_counters(struct sk_buff *skb, const struct nf_conn *ct, |
212 | 212 | enum ip_conntrack_dir dir) |
213 | 213 | { |
214 | 214 | enum ctattr_type type = dir ? CTA_COUNTERS_REPLY: CTA_COUNTERS_ORIG; |
215 | 215 | struct nlattr *nest_count; |
216 | + const struct nf_conn_counter *acct; | |
216 | 217 | |
218 | + acct = nf_conn_acct_find(ct); | |
219 | + if (!acct) | |
220 | + return 0; | |
221 | + | |
217 | 222 | nest_count = nla_nest_start(skb, type | NLA_F_NESTED); |
218 | 223 | if (!nest_count) |
219 | 224 | goto nla_put_failure; |
220 | 225 | |
221 | - NLA_PUT_BE32(skb, CTA_COUNTERS32_PACKETS, | |
222 | - htonl(ct->counters[dir].packets)); | |
223 | - NLA_PUT_BE32(skb, CTA_COUNTERS32_BYTES, | |
224 | - htonl(ct->counters[dir].bytes)); | |
226 | + NLA_PUT_BE64(skb, CTA_COUNTERS_PACKETS, | |
227 | + cpu_to_be64(acct[dir].packets)); | |
228 | + NLA_PUT_BE64(skb, CTA_COUNTERS_BYTES, | |
229 | + cpu_to_be64(acct[dir].bytes)); | |
225 | 230 | |
226 | 231 | nla_nest_end(skb, nest_count); |
227 | 232 | |
... | ... | @@ -230,9 +235,6 @@ |
230 | 235 | nla_put_failure: |
231 | 236 | return -1; |
232 | 237 | } |
233 | -#else | |
234 | -#define ctnetlink_dump_counters(a, b, c) (0) | |
235 | -#endif | |
236 | 238 | |
237 | 239 | #ifdef CONFIG_NF_CONNTRACK_MARK |
238 | 240 | static inline int |
... | ... | @@ -501,11 +503,6 @@ |
501 | 503 | goto nla_put_failure; |
502 | 504 | #endif |
503 | 505 | |
504 | - if (events & IPCT_COUNTER_FILLING && | |
505 | - (ctnetlink_dump_counters(skb, ct, IP_CT_DIR_ORIGINAL) < 0 || | |
506 | - ctnetlink_dump_counters(skb, ct, IP_CT_DIR_REPLY) < 0)) | |
507 | - goto nla_put_failure; | |
508 | - | |
509 | 506 | if (events & IPCT_RELATED && |
510 | 507 | ctnetlink_dump_master(skb, ct) < 0) |
511 | 508 | goto nla_put_failure; |
512 | 509 | |
... | ... | @@ -576,11 +573,15 @@ |
576 | 573 | cb->args[1] = (unsigned long)ct; |
577 | 574 | goto out; |
578 | 575 | } |
579 | -#ifdef CONFIG_NF_CT_ACCT | |
576 | + | |
580 | 577 | if (NFNL_MSG_TYPE(cb->nlh->nlmsg_type) == |
581 | - IPCTNL_MSG_CT_GET_CTRZERO) | |
582 | - memset(&ct->counters, 0, sizeof(ct->counters)); | |
583 | -#endif | |
578 | + IPCTNL_MSG_CT_GET_CTRZERO) { | |
579 | + struct nf_conn_counter *acct; | |
580 | + | |
581 | + acct = nf_conn_acct_find(ct); | |
582 | + if (acct) | |
583 | + memset(acct, 0, sizeof(struct nf_conn_counter[IP_CT_DIR_MAX])); | |
584 | + } | |
584 | 585 | } |
585 | 586 | if (cb->args[1]) { |
586 | 587 | cb->args[1] = 0; |
587 | 588 | |
... | ... | @@ -832,14 +833,9 @@ |
832 | 833 | u_int8_t u3 = nfmsg->nfgen_family; |
833 | 834 | int err = 0; |
834 | 835 | |
835 | - if (nlh->nlmsg_flags & NLM_F_DUMP) { | |
836 | -#ifndef CONFIG_NF_CT_ACCT | |
837 | - if (NFNL_MSG_TYPE(nlh->nlmsg_type) == IPCTNL_MSG_CT_GET_CTRZERO) | |
838 | - return -ENOTSUPP; | |
839 | -#endif | |
836 | + if (nlh->nlmsg_flags & NLM_F_DUMP) | |
840 | 837 | return netlink_dump_start(ctnl, skb, nlh, ctnetlink_dump_table, |
841 | 838 | ctnetlink_done); |
842 | - } | |
843 | 839 | |
844 | 840 | if (cda[CTA_TUPLE_ORIG]) |
845 | 841 | err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG, u3); |
... | ... | @@ -1151,6 +1147,8 @@ |
1151 | 1147 | if (err < 0) |
1152 | 1148 | goto err; |
1153 | 1149 | } |
1150 | + | |
1151 | + nf_ct_acct_ext_add(ct, GFP_KERNEL); | |
1154 | 1152 | |
1155 | 1153 | #if defined(CONFIG_NF_CONNTRACK_MARK) |
1156 | 1154 | if (cda[CTA_MARK]) |
net/netfilter/nf_conntrack_standalone.c
... | ... | @@ -25,6 +25,7 @@ |
25 | 25 | #include <net/netfilter/nf_conntrack_l4proto.h> |
26 | 26 | #include <net/netfilter/nf_conntrack_expect.h> |
27 | 27 | #include <net/netfilter/nf_conntrack_helper.h> |
28 | +#include <net/netfilter/nf_conntrack_acct.h> | |
28 | 29 | |
29 | 30 | MODULE_LICENSE("GPL"); |
30 | 31 | |
... | ... | @@ -38,19 +39,6 @@ |
38 | 39 | } |
39 | 40 | EXPORT_SYMBOL_GPL(print_tuple); |
40 | 41 | |
41 | -#ifdef CONFIG_NF_CT_ACCT | |
42 | -static unsigned int | |
43 | -seq_print_counters(struct seq_file *s, | |
44 | - const struct ip_conntrack_counter *counter) | |
45 | -{ | |
46 | - return seq_printf(s, "packets=%llu bytes=%llu ", | |
47 | - (unsigned long long)counter->packets, | |
48 | - (unsigned long long)counter->bytes); | |
49 | -} | |
50 | -#else | |
51 | -#define seq_print_counters(x, y) 0 | |
52 | -#endif | |
53 | - | |
54 | 42 | struct ct_iter_state { |
55 | 43 | unsigned int bucket; |
56 | 44 | }; |
... | ... | @@ -146,7 +134,7 @@ |
146 | 134 | l3proto, l4proto)) |
147 | 135 | return -ENOSPC; |
148 | 136 | |
149 | - if (seq_print_counters(s, &ct->counters[IP_CT_DIR_ORIGINAL])) | |
137 | + if (seq_print_acct(s, ct, IP_CT_DIR_ORIGINAL)) | |
150 | 138 | return -ENOSPC; |
151 | 139 | |
152 | 140 | if (!(test_bit(IPS_SEEN_REPLY_BIT, &ct->status))) |
... | ... | @@ -157,7 +145,7 @@ |
157 | 145 | l3proto, l4proto)) |
158 | 146 | return -ENOSPC; |
159 | 147 | |
160 | - if (seq_print_counters(s, &ct->counters[IP_CT_DIR_REPLY])) | |
148 | + if (seq_print_acct(s, ct, IP_CT_DIR_REPLY)) | |
161 | 149 | return -ENOSPC; |
162 | 150 | |
163 | 151 | if (test_bit(IPS_ASSURED_BIT, &ct->status)) |
net/netfilter/xt_connbytes.c
... | ... | @@ -8,6 +8,7 @@ |
8 | 8 | #include <linux/netfilter/x_tables.h> |
9 | 9 | #include <linux/netfilter/xt_connbytes.h> |
10 | 10 | #include <net/netfilter/nf_conntrack.h> |
11 | +#include <net/netfilter/nf_conntrack_acct.h> | |
11 | 12 | |
12 | 13 | MODULE_LICENSE("GPL"); |
13 | 14 | MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); |
14 | 15 | |
... | ... | @@ -27,12 +28,15 @@ |
27 | 28 | u_int64_t what = 0; /* initialize to make gcc happy */ |
28 | 29 | u_int64_t bytes = 0; |
29 | 30 | u_int64_t pkts = 0; |
30 | - const struct ip_conntrack_counter *counters; | |
31 | + const struct nf_conn_counter *counters; | |
31 | 32 | |
32 | 33 | ct = nf_ct_get(skb, &ctinfo); |
33 | 34 | if (!ct) |
34 | 35 | return false; |
35 | - counters = ct->counters; | |
36 | + | |
37 | + counters = nf_conn_acct_find(ct); | |
38 | + if (!counters) | |
39 | + return false; | |
36 | 40 | |
37 | 41 | switch (sinfo->what) { |
38 | 42 | case XT_CONNBYTES_PKTS: |