Commit a051a8f7 authored by Harald Welte's avatar Harald Welte Committed by David S. Miller

[NETFILTER]: Use only 32bit counters for CONNTRACK_ACCT

Initially we used 64bit counters for conntrack-based accounting, since we
had no event mechanism to tell userspace that our counters are about to
overflow.  With nfnetlink_conntrack, we now have such a event mechanism and
thus can save 16bytes per connection.
Signed-off-by: default avatarHarald Welte <laforge@netfilter.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d4875b04
...@@ -84,8 +84,10 @@ enum ctattr_protoinfo_tcp { ...@@ -84,8 +84,10 @@ enum ctattr_protoinfo_tcp {
enum ctattr_counters { enum ctattr_counters {
CTA_COUNTERS_UNSPEC, CTA_COUNTERS_UNSPEC,
CTA_COUNTERS_PACKETS, CTA_COUNTERS_PACKETS, /* old 64bit counters */
CTA_COUNTERS_BYTES, CTA_COUNTERS_BYTES, /* old 64bit counters */
CTA_COUNTERS32_PACKETS,
CTA_COUNTERS32_BYTES,
__CTA_COUNTERS_MAX __CTA_COUNTERS_MAX
}; };
#define CTA_COUNTERS_MAX (__CTA_COUNTERS_MAX - 1) #define CTA_COUNTERS_MAX (__CTA_COUNTERS_MAX - 1)
......
...@@ -117,6 +117,10 @@ enum ip_conntrack_events ...@@ -117,6 +117,10 @@ enum ip_conntrack_events
/* NAT info */ /* NAT info */
IPCT_NATINFO_BIT = 10, IPCT_NATINFO_BIT = 10,
IPCT_NATINFO = (1 << IPCT_NATINFO_BIT), IPCT_NATINFO = (1 << IPCT_NATINFO_BIT),
/* Counter highest bit has been set */
IPCT_COUNTER_FILLING_BIT = 11,
IPCT_COUNTER_FILLING = (1 << IPCT_COUNTER_FILLING_BIT),
}; };
enum ip_conntrack_expect_events { enum ip_conntrack_expect_events {
...@@ -192,8 +196,8 @@ do { \ ...@@ -192,8 +196,8 @@ do { \
struct ip_conntrack_counter struct ip_conntrack_counter
{ {
u_int64_t packets; u_int32_t packets;
u_int64_t bytes; u_int32_t bytes;
}; };
struct ip_conntrack_helper; struct ip_conntrack_helper;
......
...@@ -1119,7 +1119,7 @@ void __ip_ct_refresh_acct(struct ip_conntrack *ct, ...@@ -1119,7 +1119,7 @@ void __ip_ct_refresh_acct(struct ip_conntrack *ct,
unsigned long extra_jiffies, unsigned long extra_jiffies,
int do_acct) int do_acct)
{ {
int do_event = 0; int event = 0;
IP_NF_ASSERT(ct->timeout.data == (unsigned long)ct); IP_NF_ASSERT(ct->timeout.data == (unsigned long)ct);
IP_NF_ASSERT(skb); IP_NF_ASSERT(skb);
...@@ -1129,13 +1129,13 @@ void __ip_ct_refresh_acct(struct ip_conntrack *ct, ...@@ -1129,13 +1129,13 @@ void __ip_ct_refresh_acct(struct ip_conntrack *ct,
/* If not in hash table, timer will not be active yet */ /* If not in hash table, timer will not be active yet */
if (!is_confirmed(ct)) { if (!is_confirmed(ct)) {
ct->timeout.expires = extra_jiffies; ct->timeout.expires = extra_jiffies;
do_event = 1; event = IPCT_REFRESH;
} else { } else {
/* Need del_timer for race avoidance (may already be dying). */ /* Need del_timer for race avoidance (may already be dying). */
if (del_timer(&ct->timeout)) { if (del_timer(&ct->timeout)) {
ct->timeout.expires = jiffies + extra_jiffies; ct->timeout.expires = jiffies + extra_jiffies;
add_timer(&ct->timeout); add_timer(&ct->timeout);
do_event = 1; event = IPCT_REFRESH;
} }
} }
...@@ -1144,14 +1144,17 @@ void __ip_ct_refresh_acct(struct ip_conntrack *ct, ...@@ -1144,14 +1144,17 @@ void __ip_ct_refresh_acct(struct ip_conntrack *ct,
ct->counters[CTINFO2DIR(ctinfo)].packets++; ct->counters[CTINFO2DIR(ctinfo)].packets++;
ct->counters[CTINFO2DIR(ctinfo)].bytes += ct->counters[CTINFO2DIR(ctinfo)].bytes +=
ntohs(skb->nh.iph->tot_len); ntohs(skb->nh.iph->tot_len);
if ((ct->counters[CTINFO2DIR(ctinfo)].packets & 0x80000000)
|| (ct->counters[CTINFO2DIR(ctinfo)].bytes & 0x80000000))
event |= IPCT_COUNTER_FILLING;
} }
#endif #endif
write_unlock_bh(&ip_conntrack_lock); write_unlock_bh(&ip_conntrack_lock);
/* must be unlocked when calling event cache */ /* must be unlocked when calling event cache */
if (do_event) if (event)
ip_conntrack_event_cache(IPCT_REFRESH, skb); ip_conntrack_event_cache(event, skb);
} }
#if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \ #if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \
......
...@@ -177,11 +177,11 @@ ctnetlink_dump_counters(struct sk_buff *skb, const struct ip_conntrack *ct, ...@@ -177,11 +177,11 @@ ctnetlink_dump_counters(struct sk_buff *skb, const struct ip_conntrack *ct,
struct nfattr *nest_count = NFA_NEST(skb, type); struct nfattr *nest_count = NFA_NEST(skb, type);
u_int64_t tmp; u_int64_t tmp;
tmp = cpu_to_be64(ct->counters[dir].packets); tmp = htonl(ct->counters[dir].packets);
NFA_PUT(skb, CTA_COUNTERS_PACKETS, sizeof(u_int64_t), &tmp); NFA_PUT(skb, CTA_COUNTERS32_PACKETS, sizeof(u_int32_t), &tmp);
tmp = cpu_to_be64(ct->counters[dir].bytes); tmp = htonl(ct->counters[dir].bytes);
NFA_PUT(skb, CTA_COUNTERS_BYTES, sizeof(u_int64_t), &tmp); NFA_PUT(skb, CTA_COUNTERS32_BYTES, sizeof(u_int32_t), &tmp);
NFA_NEST_END(skb, nest_count); NFA_NEST_END(skb, nest_count);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment