/* increase the UDP timeout of the master connection as replies from
* Amanda clients to the server can be quite delayed */
- ip_ct_refresh(ct, master_timeout * HZ);
+ ip_ct_refresh_acct(ct, ctinfo, NULL, master_timeout * HZ);
/* No data? */
dataoff = skb->nh.iph->ihl*4 + sizeof(struct udphdr);
synchronize_net();
}
-/* Refresh conntrack for this many jiffies. */
-void ip_ct_refresh(struct ip_conntrack *ct, unsigned long extra_jiffies)
+static inline void ct_add_counters(struct ip_conntrack *ct,
+ enum ip_conntrack_info ctinfo,
+ const struct sk_buff *skb)
+{
+#ifdef CONFIG_IP_NF_CT_ACCT
+ if (skb) {
+ ct->counters[CTINFO2DIR(ctinfo)].packets++;
+ ct->counters[CTINFO2DIR(ctinfo)].bytes +=
+ ntohs(skb->nh.iph->tot_len);
+ }
+#endif
+}
+
+/* Refresh conntrack for this many jiffies and do accounting (if skb != NULL) */
+void ip_ct_refresh_acct(struct ip_conntrack *ct,
+ enum ip_conntrack_info ctinfo,
+ const struct sk_buff *skb,
+ unsigned long extra_jiffies)
{
IP_NF_ASSERT(ct->timeout.data == (unsigned long)ct);
/* If not in hash table, timer will not be active yet */
- if (!is_confirmed(ct))
+ if (!is_confirmed(ct)) {
ct->timeout.expires = extra_jiffies;
- else {
+ ct_add_counters(ct, ctinfo, skb);
+ } else {
WRITE_LOCK(&ip_conntrack_lock);
/* Need del_timer for race avoidance (may already be dying). */
if (del_timer(&ct->timeout)) {
ct->timeout.expires = jiffies + extra_jiffies;
add_timer(&ct->timeout);
}
+ ct_add_counters(ct, ctinfo, skb);
WRITE_UNLOCK(&ip_conntrack_lock);
}
}
/* Returns verdict for packet, or -1 for invalid. */
static int packet(struct ip_conntrack *conntrack,
const struct sk_buff *skb,
- enum ip_conntrack_info conntrackinfo)
+ enum ip_conntrack_info ctinfo)
{
- ip_ct_refresh(conntrack, ip_ct_generic_timeout);
+ ip_ct_refresh_acct(conntrack, ctinfo, skb, ip_ct_generic_timeout);
return NF_ACCEPT;
}
ct->timeout.function((unsigned long)ct);
} else {
atomic_inc(&ct->proto.icmp.count);
- ip_ct_refresh(ct, ip_ct_icmp_timeout);
+ ip_ct_refresh_acct(ct, ctinfo, skb, ip_ct_icmp_timeout);
}
return NF_ACCEPT;
set_bit(IPS_ASSURED_BIT, &conntrack->status);
out: WRITE_UNLOCK(&tcp_lock);
- ip_ct_refresh(conntrack, *tcp_timeouts[newconntrack]);
+ ip_ct_refresh_acct(conntrack, ctinfo, skb, *tcp_timeouts[newconntrack]);
return NF_ACCEPT;
}
/* Returns verdict for packet, and may modify conntracktype */
static int udp_packet(struct ip_conntrack *conntrack,
const struct sk_buff *skb,
- enum ip_conntrack_info conntrackinfo)
+ enum ip_conntrack_info ctinfo)
{
/* If we've seen traffic both ways, this is some kind of UDP
stream. Extend timeout. */
if (test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)) {
- ip_ct_refresh(conntrack, ip_ct_udp_timeout_stream);
+ ip_ct_refresh_acct(conntrack, ctinfo, skb,
+ ip_ct_udp_timeout_stream);
/* Also, more likely to be important, and not a probe */
set_bit(IPS_ASSURED_BIT, &conntrack->status);
} else
- ip_ct_refresh(conntrack, ip_ct_udp_timeout);
+ ip_ct_refresh_acct(conntrack, ctinfo, skb, ip_ct_udp_timeout);
return NF_ACCEPT;
}
return len;
}
+#ifdef CONFIG_IP_NF_CT_ACCT
+static unsigned int
+print_counters(char *buffer, struct ip_conntrack_counter *counter)
+{
+ return sprintf(buffer, "packets=%llu bytes=%llu ",
+ counter->packets, counter->bytes);
+}
+#else
+#define print_counters(x, y) 0
+#endif
+
static unsigned int
print_conntrack(char *buffer, struct ip_conntrack *conntrack)
{
&conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
proto);
len += sprintf(buffer + len, "xid=%d ", conntrack->xid[IP_CT_DIR_ORIGINAL]);
+ len += print_counters(buffer + len,
+ &conntrack->counters[IP_CT_DIR_ORIGINAL]);
if (!(test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)))
len += sprintf(buffer + len, "[UNREPLIED] ");
len += print_tuple(buffer + len,
&conntrack->tuplehash[IP_CT_DIR_REPLY].tuple,
proto);
len += sprintf(buffer + len, "xid=%d ", conntrack->xid[IP_CT_DIR_REPLY]);
+ len += print_counters(buffer + len,
+ &conntrack->counters[IP_CT_DIR_REPLY]);
if (test_bit(IPS_ASSURED_BIT, &conntrack->status))
len += sprintf(buffer + len, "[ASSURED] ");
len += sprintf(buffer + len, "use=%u ",
EXPORT_SYMBOL(ip_conntrack_helper_register);
EXPORT_SYMBOL(ip_conntrack_helper_unregister);
EXPORT_SYMBOL(ip_ct_selective_cleanup);
-EXPORT_SYMBOL(ip_ct_refresh);
+EXPORT_SYMBOL(ip_ct_refresh_acct);
EXPORT_SYMBOL(ip_ct_find_proto);
EXPORT_SYMBOL(__ip_ct_find_proto);
EXPORT_SYMBOL(ip_ct_find_helper);