* add a 'bthr' variable to each nfacct object, allowing a bytes 'threshold' to be stored and then reported if/when traffic breaches it. Signed-off-by: Michael Zintakis <michael.zintakis@xxxxxxxxxxxxxx> --- include/uapi/linux/netfilter/nfnetlink_acct.h | 9 ++++++ net/netfilter/nfnetlink_acct.c | 43 ++++++++++++++++++++++++++- 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/include/uapi/linux/netfilter/nfnetlink_acct.h b/include/uapi/linux/netfilter/nfnetlink_acct.h index 0b65f9c1..e972970 100644 --- a/include/uapi/linux/netfilter/nfnetlink_acct.h +++ b/include/uapi/linux/netfilter/nfnetlink_acct.h @@ -19,10 +19,19 @@ enum nfnl_acct_type { NFACCT_PKTS, NFACCT_BYTES, NFACCT_USE, + NFACCT_BTHR, NFACCT_FMT, + NFACCT_FLAGS, + NFACCT_CMD, __NFACCT_MAX }; #define NFACCT_MAX (__NFACCT_MAX - 1) +enum nfnl_acct_flags { + NFACCT_FLAG_BIT_BTHR = 0, + NFACCT_FLAG_BTHR = (1 << NFACCT_FLAG_BIT_BTHR), + NFACCT_FLAG_BIT_MAX = 1, + NFACCT_FLAG_MAX = (1 << NFACCT_FLAG_BIT_MAX), +}; #endif /* _UAPI_NFNL_ACCT_H_ */ diff --git a/net/netfilter/nfnetlink_acct.c b/net/netfilter/nfnetlink_acct.c index 92ecad1..18cd28e 100644 --- a/net/netfilter/nfnetlink_acct.c +++ b/net/netfilter/nfnetlink_acct.c @@ -32,7 +32,9 @@ static LIST_HEAD(nfnl_acct_list); struct nf_acct { atomic64_t pkts; atomic64_t bytes; + u64 bthr; u16 fmt; + u16 flags; struct list_head head; atomic_t refcnt; char name[NFACCT_NAME_MAX]; @@ -44,6 +46,7 @@ nfnl_acct_new(struct sock *nfnl, struct sk_buff *skb, const struct nlmsghdr *nlh, const struct nlattr * const tb[]) { struct nf_acct *nfacct, *matching = NULL; + unsigned int flags = 0, cmd = 0; char *acct_name; if (!tb[NFACCT_NAME] || @@ -51,6 +54,21 @@ nfnl_acct_new(struct sock *nfnl, struct sk_buff *skb, (!tb[NFACCT_BYTES] && tb[NFACCT_PKTS])) return -EINVAL; + if (tb[NFACCT_CMD]) { + if (!tb[NFACCT_FLAGS]) + return -EINVAL; + + cmd = be16_to_cpu(nla_get_be16(tb[NFACCT_CMD])); + flags = be16_to_cpu(nla_get_be16(tb[NFACCT_FLAGS])); + + if (cmd & NFACCT_FLAG_BTHR && + ((flags & NFACCT_FLAG_BTHR && !tb[NFACCT_BTHR]) || + (!(flags & NFACCT_FLAG_BTHR) && tb[NFACCT_BTHR]))) + return -EINVAL; + + } else if (tb[NFACCT_FLAGS]) + return -EINVAL; + acct_name = nla_data(tb[NFACCT_NAME]); if (strlen(acct_name) == 0) return -EINVAL; @@ -86,7 +104,7 @@ nfnl_acct_new(struct sock *nfnl, struct sk_buff *skb, * and == 0. * */ - if (!tb[NFACCT_FMT]) { + if (!tb[NFACCT_FMT] && !cmd) { atomic64_set(&matching->pkts, 0); atomic64_set(&matching->bytes, 0); } @@ -96,6 +114,17 @@ nfnl_acct_new(struct sock *nfnl, struct sk_buff *skb, matching->fmt = be16_to_cpu(nla_get_be16(tb[NFACCT_FMT])); } + /* ... and finally set the bytes threshold */ + if (cmd & NFACCT_FLAG_BTHR) { + if (flags & NFACCT_FLAG_BTHR) { + matching->bthr = be64_to_cpu( + nla_get_be64(tb[NFACCT_BTHR])); + matching->flags |= NFACCT_FLAG_BTHR; + } else { + matching->bthr = 0; + matching->flags &= ~NFACCT_FLAG_BTHR; + } + } return 0; } return -EBUSY; @@ -118,6 +147,13 @@ nfnl_acct_new(struct sock *nfnl, struct sk_buff *skb, if (tb[NFACCT_FMT]) { nfacct->fmt = be16_to_cpu(nla_get_be16(tb[NFACCT_FMT])); } + if (cmd & NFACCT_FLAG_BTHR && flags & NFACCT_FLAG_BTHR) { + if (tb[NFACCT_BTHR]) + nfacct->bthr = be64_to_cpu( + nla_get_be64(tb[NFACCT_BTHR])); + + nfacct->flags |= flags & NFACCT_FLAG_BTHR; + } atomic_set(&nfacct->refcnt, 1); list_add_tail_rcu(&nfacct->head, &nfnl_acct_list); return 0; @@ -154,7 +190,9 @@ nfnl_acct_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type, } if (nla_put_be64(skb, NFACCT_PKTS, cpu_to_be64(pkts)) || nla_put_be64(skb, NFACCT_BYTES, cpu_to_be64(bytes)) || + nla_put_be64(skb, NFACCT_BTHR, cpu_to_be64(acct->bthr)) || nla_put_be16(skb, NFACCT_FMT, htons(acct->fmt)) || + nla_put_be16(skb, NFACCT_FLAGS, htons(acct->flags)) || nla_put_be32(skb, NFACCT_USE, htonl(atomic_read(&acct->refcnt)))) goto nla_put_failure; @@ -302,7 +340,10 @@ static const struct nla_policy nfnl_acct_policy[NFACCT_MAX+1] = { [NFACCT_NAME] = { .type = NLA_NUL_STRING, .len = NFACCT_NAME_MAX-1 }, [NFACCT_BYTES] = { .type = NLA_U64 }, [NFACCT_PKTS] = { .type = NLA_U64 }, + [NFACCT_BTHR] = { .type = NLA_U64 }, [NFACCT_FMT] = { .type = NLA_U16 }, + [NFACCT_FLAGS] = { .type = NLA_U16 }, + [NFACCT_CMD] = { .type = NLA_U16 }, }; static const struct nfnl_callback nfnl_acct_cb[NFNL_MSG_ACCT_MAX] = { -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html