Commit 584015727a3b88b46602b20077b46cd04f8b4ab3

Authored by Krzysztof Piotr Oledzki
Committed by David S. Miller
1 parent 07a7c1070e

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
... ... @@ -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: