summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/libnetfilter_acct/libnetfilter_acct.h2
-rw-r--r--include/linux/netfilter/nfnetlink.h4
-rw-r--r--include/linux/netfilter/nfnetlink_acct.h9
-rw-r--r--src/libnetfilter_acct.c67
4 files changed, 78 insertions, 4 deletions
diff --git a/include/libnetfilter_acct/libnetfilter_acct.h b/include/libnetfilter_acct/libnetfilter_acct.h
index b00e366..c6ed858 100644
--- a/include/libnetfilter_acct/libnetfilter_acct.h
+++ b/include/libnetfilter_acct/libnetfilter_acct.h
@@ -14,6 +14,8 @@ enum nfacct_attr_type {
NFACCT_ATTR_NAME = 0,
NFACCT_ATTR_PKTS,
NFACCT_ATTR_BYTES,
+ NFACCT_ATTR_FLAGS,
+ NFACCT_ATTR_QUOTA,
};
struct nfacct *nfacct_alloc(void);
diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h
index 4a4efaf..d3e0ea8 100644
--- a/include/linux/netfilter/nfnetlink.h
+++ b/include/linux/netfilter/nfnetlink.h
@@ -18,6 +18,10 @@ enum nfnetlink_groups {
#define NFNLGRP_CONNTRACK_EXP_UPDATE NFNLGRP_CONNTRACK_EXP_UPDATE
NFNLGRP_CONNTRACK_EXP_DESTROY,
#define NFNLGRP_CONNTRACK_EXP_DESTROY NFNLGRP_CONNTRACK_EXP_DESTROY
+ NFNLGRP_NFTABLES,
+#define NFNLGRP_NFTABLES NFNLGRP_NFTABLES
+ NFNLGRP_ACCT_QUOTA,
+#define NFNLGRP_ACCT_QUOTA NFNLGRP_ACCT_QUOTA
__NFNLGRP_MAX,
};
#define NFNLGRP_MAX (__NFNLGRP_MAX - 1)
diff --git a/include/linux/netfilter/nfnetlink_acct.h b/include/linux/netfilter/nfnetlink_acct.h
index c7b6269..6b8c935 100644
--- a/include/linux/netfilter/nfnetlink_acct.h
+++ b/include/linux/netfilter/nfnetlink_acct.h
@@ -10,15 +10,24 @@ enum nfnl_acct_msg_types {
NFNL_MSG_ACCT_GET,
NFNL_MSG_ACCT_GET_CTRZERO,
NFNL_MSG_ACCT_DEL,
+ NFNL_MSG_ACCT_OVERQUOTA,
NFNL_MSG_ACCT_MAX
};
+enum nfnl_acct_flags {
+ NFACCT_F_QUOTA_PKTS = (1 << 0),
+ NFACCT_F_QUOTA_BYTES = (1 << 1),
+ NFACCT_F_OVERQUOTA = (1 << 2), /* can't be set from userspace */
+};
+
enum nfnl_acct_type {
NFACCT_UNSPEC,
NFACCT_NAME,
NFACCT_PKTS,
NFACCT_BYTES,
NFACCT_USE,
+ NFACCT_FLAGS,
+ NFACCT_QUOTA,
__NFACCT_MAX
};
#define NFACCT_MAX (__NFACCT_MAX - 1)
diff --git a/src/libnetfilter_acct.c b/src/libnetfilter_acct.c
index 77f58ce..0c1a758 100644
--- a/src/libnetfilter_acct.c
+++ b/src/libnetfilter_acct.c
@@ -61,6 +61,8 @@ struct nfacct {
uint64_t pkts;
uint64_t bytes;
uint32_t bitset;
+ uint32_t flags;
+ uint64_t quota;
};
/**
@@ -114,6 +116,14 @@ nfacct_attr_set(struct nfacct *nfacct, enum nfacct_attr_type type,
nfacct->bytes = *((uint64_t *) data);
nfacct->bitset |= (1 << NFACCT_ATTR_BYTES);
break;
+ case NFACCT_ATTR_FLAGS:
+ nfacct->flags = *((uint32_t *) data);
+ nfacct->bitset |= (1 << NFACCT_ATTR_FLAGS);
+ break;
+ case NFACCT_ATTR_QUOTA:
+ nfacct->quota = *((uint64_t *) data);
+ nfacct->bitset |= (1 << NFACCT_ATTR_QUOTA);
+ break;
}
}
EXPORT_SYMBOL(nfacct_attr_set);
@@ -164,6 +174,12 @@ nfacct_attr_unset(struct nfacct *nfacct, enum nfacct_attr_type type)
case NFACCT_ATTR_BYTES:
nfacct->bitset &= ~(1 << NFACCT_ATTR_BYTES);
break;
+ case NFACCT_ATTR_FLAGS:
+ nfacct->bitset &= ~(1 << NFACCT_ATTR_FLAGS);
+ break;
+ case NFACCT_ATTR_QUOTA:
+ nfacct->bitset &= ~(1 << NFACCT_ATTR_QUOTA);
+ break;
}
}
EXPORT_SYMBOL(nfacct_attr_unset);
@@ -193,6 +209,14 @@ const void *nfacct_attr_get(struct nfacct *nfacct, enum nfacct_attr_type type)
if (nfacct->bitset & (1 << NFACCT_ATTR_BYTES))
ret = &nfacct->bytes;
break;
+ case NFACCT_ATTR_FLAGS:
+ if (nfacct->bitset & (1 << NFACCT_ATTR_FLAGS))
+ ret = &nfacct->flags;
+ break;
+ case NFACCT_ATTR_QUOTA:
+ if (nfacct->bitset & (1 << NFACCT_ATTR_QUOTA))
+ ret = &nfacct->quota;
+ break;
}
return ret;
}
@@ -232,13 +256,35 @@ static int
nfacct_snprintf_plain(char *buf, size_t rem, struct nfacct *nfacct,
uint16_t flags)
{
- int ret;
+ int ret, temp;
+ char *walking_buf;
+
+ temp = rem;
+ walking_buf = buf;
if (flags & NFACCT_SNPRINTF_F_FULL) {
- ret = snprintf(buf, rem,
- "{ pkts = %.20"PRIu64", bytes = %.20"PRIu64" } = %s;",
+ ret = snprintf(walking_buf, temp,
+ "{ pkts = %.20"PRIu64", bytes = %.20"PRIu64"",
nfacct_attr_get_u64(nfacct, NFACCT_ATTR_PKTS),
- nfacct_attr_get_u64(nfacct, NFACCT_ATTR_BYTES),
+ nfacct_attr_get_u64(nfacct, NFACCT_ATTR_BYTES));
+
+ if (nfacct->flags) {
+ uint32_t mode;
+
+ mode = nfacct_attr_get_u64(nfacct, NFACCT_ATTR_FLAGS);
+
+ walking_buf += ret;
+ temp -= ret;
+ ret = snprintf(walking_buf, temp,
+ ", quota = %.20"PRIu64", mode = %s",
+ nfacct_attr_get_u64(nfacct, NFACCT_ATTR_QUOTA),
+ mode == NFACCT_F_QUOTA_BYTES ?
+ "byte" : "packet");
+ }
+
+ walking_buf += ret;
+ temp -= ret;
+ ret = snprintf(walking_buf, temp, " } = %s;",
nfacct_attr_get_str(nfacct, NFACCT_ATTR_NAME));
} else {
ret = snprintf(buf, rem, "%s\n",
@@ -424,6 +470,12 @@ void nfacct_nlmsg_build_payload(struct nlmsghdr *nlh, struct nfacct *nfacct)
if (nfacct->bitset & (1 << NFACCT_ATTR_BYTES))
mnl_attr_put_u64(nlh, NFACCT_BYTES, htobe64(nfacct->bytes));
+
+ if (nfacct->bitset & (1 << NFACCT_ATTR_FLAGS))
+ mnl_attr_put_u32(nlh, NFACCT_FLAGS, htobe32(nfacct->flags));
+
+ if (nfacct->bitset & (1 << NFACCT_ATTR_QUOTA))
+ mnl_attr_put_u64(nlh, NFACCT_QUOTA, htobe64(nfacct->quota));
}
EXPORT_SYMBOL(nfacct_nlmsg_build_payload);
@@ -479,6 +531,13 @@ nfacct_nlmsg_parse_payload(const struct nlmsghdr *nlh, struct nfacct *nfacct)
nfacct_attr_set_u64(nfacct, NFACCT_ATTR_BYTES,
be64toh(mnl_attr_get_u64(tb[NFACCT_BYTES])));
+ if (tb[NFACCT_FLAGS] && tb[NFACCT_QUOTA]) {
+ uint32_t flags = be32toh(mnl_attr_get_u32(tb[NFACCT_FLAGS]));
+ nfacct_attr_set(nfacct, NFACCT_ATTR_FLAGS, &flags);
+ nfacct_attr_set_u64(nfacct, NFACCT_ATTR_QUOTA,
+ be64toh(mnl_attr_get_u64(tb[NFACCT_QUOTA])));
+ }
+
return 0;
}
EXPORT_SYMBOL(nfacct_nlmsg_parse_payload);