msm: net: Add support to packet threshold events.
Add support to send conntrack event when
configured packet threshold is met.
Change-Id: I11fe78a74512d901d260deead3354461fc4990ab
Acked-by: Chaitanya Pratapa <cpratapa@qti.qualcomm.com>
Signed-off-by: Mohammed Javid <mjavid@codeaurora.org>
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
index d9d52c0..7815545 100644
--- a/include/net/netfilter/nf_conntrack.h
+++ b/include/net/netfilter/nf_conntrack.h
@@ -314,6 +314,7 @@
extern unsigned int nf_conntrack_htable_size;
extern seqcount_t nf_conntrack_generation;
extern unsigned int nf_conntrack_max;
+extern unsigned int nf_conntrack_pkt_threshold;
/* must be called with rcu read lock held */
static inline void
diff --git a/include/uapi/linux/netfilter/nf_conntrack_common.h b/include/uapi/linux/netfilter/nf_conntrack_common.h
index 6d074d1..1d7cd67 100644
--- a/include/uapi/linux/netfilter/nf_conntrack_common.h
+++ b/include/uapi/linux/netfilter/nf_conntrack_common.h
@@ -113,8 +113,11 @@
IPCT_NATSEQADJ = IPCT_SEQADJ,
IPCT_SECMARK, /* new security mark has been set */
IPCT_LABEL, /* new connlabel has been set */
+ IPCT_COUNTER, /* Packet counters have matched. */
};
+#define IPCT_COUNTER IPCT_COUNTER
+
enum ip_conntrack_expect_events {
IPEXP_NEW, /* new expectation */
IPEXP_DESTROY, /* destroyed expectation */
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index ff2d32e..d5b49fc 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -181,6 +181,9 @@
unsigned int nf_conntrack_max __read_mostly;
seqcount_t nf_conntrack_generation __read_mostly;
+unsigned int nf_conntrack_pkt_threshold __read_mostly;
+EXPORT_SYMBOL(nf_conntrack_pkt_threshold);
+
DEFINE_PER_CPU(struct nf_conn, nf_conntrack_untracked);
EXPORT_PER_CPU_SYMBOL(nf_conntrack_untracked);
@@ -1434,6 +1437,9 @@
unsigned long extra_jiffies,
int do_acct)
{
+ struct nf_conn_acct *acct;
+ u64 pkts;
+
NF_CT_ASSERT(skb);
/* Only update if this is not a fixed timeout */
@@ -1446,8 +1452,27 @@
ct->timeout = extra_jiffies;
acct:
- if (do_acct)
- nf_ct_acct_update(ct, ctinfo, skb->len);
+ if (do_acct) {
+ acct = nf_conn_acct_find(ct);
+ if (acct) {
+ struct nf_conn_counter *counter = acct->counter;
+
+ atomic64_inc(&counter[CTINFO2DIR(ctinfo)].packets);
+ atomic64_add(skb->len, &counter
+ [CTINFO2DIR(ctinfo)].bytes);
+
+ pkts =
+ atomic64_read(&counter[CTINFO2DIR(ctinfo)].packets) +
+ atomic64_read(&counter[!CTINFO2DIR(ctinfo)].packets);
+ /* Report if the packet threshold is reached. */
+ if ((nf_conntrack_pkt_threshold > 0) &&
+ (pkts == nf_conntrack_pkt_threshold)) {
+ nf_conntrack_event_cache(IPCT_COUNTER, ct);
+ nf_conntrack_event_cache(IPCT_PROTOINFO, ct);
+ nf_ct_deliver_cached_events(ct);
+ }
+ }
+ }
}
EXPORT_SYMBOL_GPL(__nf_ct_refresh_acct);
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 04111c1..08b24a9 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -729,6 +729,10 @@
if (events & (1 << IPCT_SEQADJ) &&
ctnetlink_dump_ct_seq_adj(skb, ct) < 0)
goto nla_put_failure;
+
+ if (events & (1 << IPCT_COUNTER) &&
+ ctnetlink_dump_acct(skb, ct, 0) < 0)
+ goto nla_put_failure;
}
#ifdef CONFIG_NF_CONNTRACK_MARK
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
index 5f446cd..2f1014e 100644
--- a/net/netfilter/nf_conntrack_standalone.c
+++ b/net/netfilter/nf_conntrack_standalone.c
@@ -517,6 +517,14 @@
.mode = 0644,
.proc_handler = proc_dointvec,
},
+ {
+ .procname = "nf_conntrack_pkt_threshold",
+ .data = &nf_conntrack_pkt_threshold,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec,
+ },
+
{ }
};