summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/libnftnl/expr.h1
-rw-r--r--include/linux/netfilter/nf_tables.h6
-rw-r--r--src/expr/limit.c28
-rw-r--r--tests/nft-expr_limit-test.c4
4 files changed, 35 insertions, 4 deletions
diff --git a/include/libnftnl/expr.h b/include/libnftnl/expr.h
index ab2c5ba..cb2e8a3 100644
--- a/include/libnftnl/expr.h
+++ b/include/libnftnl/expr.h
@@ -155,6 +155,7 @@ enum {
NFTNL_EXPR_LIMIT_UNIT,
NFTNL_EXPR_LIMIT_BURST,
NFTNL_EXPR_LIMIT_TYPE,
+ NFTNL_EXPR_LIMIT_FLAGS,
};
enum {
diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
index f77693b..9d65ac2 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -780,6 +780,10 @@ enum nft_limit_type {
NFT_LIMIT_PKT_BYTES
};
+enum nft_limit_flags {
+ NFT_LIMIT_F_INV = (1 << 0),
+};
+
/**
* enum nft_limit_attributes - nf_tables limit expression netlink attributes
*
@@ -787,6 +791,7 @@ enum nft_limit_type {
* @NFTA_LIMIT_UNIT: refill unit (NLA_U64)
* @NFTA_LIMIT_BURST: burst (NLA_U32)
* @NFTA_LIMIT_TYPE: type of limit (NLA_U32: enum nft_limit_type)
+ * @NFTA_LIMIT_FLAGS: flags (NLA_U32: enum nft_limit_flags)
*/
enum nft_limit_attributes {
NFTA_LIMIT_UNSPEC,
@@ -794,6 +799,7 @@ enum nft_limit_attributes {
NFTA_LIMIT_UNIT,
NFTA_LIMIT_BURST,
NFTA_LIMIT_TYPE,
+ NFTA_LIMIT_FLAGS,
__NFTA_LIMIT_MAX
};
#define NFTA_LIMIT_MAX (__NFTA_LIMIT_MAX - 1)
diff --git a/src/expr/limit.c b/src/expr/limit.c
index ab9ceff..2c21eb5 100644
--- a/src/expr/limit.c
+++ b/src/expr/limit.c
@@ -27,6 +27,7 @@ struct nftnl_expr_limit {
uint64_t unit;
uint32_t burst;
enum nft_limit_type type;
+ uint32_t flags;
};
static int
@@ -48,6 +49,9 @@ nftnl_expr_limit_set(struct nftnl_expr *e, uint16_t type,
case NFTNL_EXPR_LIMIT_TYPE:
limit->type = *((uint32_t *)data);
break;
+ case NFTNL_EXPR_LIMIT_FLAGS:
+ limit->flags = *((uint32_t *)data);
+ break;
default:
return -1;
}
@@ -73,6 +77,9 @@ nftnl_expr_limit_get(const struct nftnl_expr *e, uint16_t type,
case NFTNL_EXPR_LIMIT_TYPE:
*data_len = sizeof(uint32_t);
return &limit->type;
+ case NFTNL_EXPR_LIMIT_FLAGS:
+ *data_len = sizeof(uint32_t);
+ return &limit->flags;
}
return NULL;
}
@@ -93,6 +100,7 @@ static int nftnl_expr_limit_cb(const struct nlattr *attr, void *data)
break;
case NFTA_LIMIT_BURST:
case NFTA_LIMIT_TYPE:
+ case NFTA_LIMIT_FLAGS:
if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
abi_breakage();
break;
@@ -115,6 +123,8 @@ nftnl_expr_limit_build(struct nlmsghdr *nlh, struct nftnl_expr *e)
mnl_attr_put_u32(nlh, NFTA_LIMIT_BURST, htonl(limit->burst));
if (e->flags & (1 << NFTNL_EXPR_LIMIT_TYPE))
mnl_attr_put_u32(nlh, NFTA_LIMIT_TYPE, htonl(limit->type));
+ if (e->flags & (1 << NFTNL_EXPR_LIMIT_FLAGS))
+ mnl_attr_put_u32(nlh, NFTA_LIMIT_FLAGS, htonl(limit->flags));
}
static int
@@ -142,6 +152,10 @@ nftnl_expr_limit_parse(struct nftnl_expr *e, struct nlattr *attr)
limit->type = ntohl(mnl_attr_get_u32(tb[NFTA_LIMIT_TYPE]));
e->flags |= (1 << NFTNL_EXPR_LIMIT_TYPE);
}
+ if (tb[NFTA_LIMIT_FLAGS]) {
+ limit->flags = ntohl(mnl_attr_get_u32(tb[NFTA_LIMIT_FLAGS]));
+ e->flags |= (1 << NFTNL_EXPR_LIMIT_FLAGS);
+ }
return 0;
}
@@ -162,6 +176,8 @@ static int nftnl_expr_limit_json_parse(struct nftnl_expr *e, json_t *root,
nftnl_expr_set_u32(e, NFTNL_EXPR_LIMIT_BURST, uval32);
if (nftnl_jansson_parse_val(root, "type", NFTNL_TYPE_U32, &uval32, err) == 0)
nftnl_expr_set_u32(e, NFTNL_EXPR_LIMIT_TYPE, uval32);
+ if (nftnl_jansson_parse_val(root, "flags", NFTNL_TYPE_U32, &uval32, err) == 0)
+ nftnl_expr_set_u32(e, NFTNL_EXPR_LIMIT_FLAGS, uval32);
return 0;
#else
@@ -176,7 +192,7 @@ static int nftnl_expr_limit_xml_parse(struct nftnl_expr *e,
{
#ifdef XML_PARSING
uint64_t rate, unit;
- uint32_t burst, type;
+ uint32_t burst, type, flags;
if (nftnl_mxml_num_parse(tree, "rate", MXML_DESCEND_FIRST, BASE_DEC,
&rate, NFTNL_TYPE_U64, NFTNL_XML_MAND, err) == 0)
@@ -191,6 +207,9 @@ static int nftnl_expr_limit_xml_parse(struct nftnl_expr *e,
if (nftnl_mxml_num_parse(tree, "type", MXML_DESCEND_FIRST, BASE_DEC,
&type, NFTNL_TYPE_U32, NFTNL_XML_MAND, err) == 0)
nftnl_expr_set_u32(e, NFTNL_EXPR_LIMIT_TYPE, type);
+ if (nftnl_mxml_num_parse(tree, "flags", MXML_DESCEND_FIRST, BASE_DEC,
+ &flags, NFTNL_TYPE_U32, NFTNL_XML_MAND, err) == 0)
+ nftnl_expr_set_u32(e, NFTNL_EXPR_LIMIT_FLAGS, flags);
return 0;
#else
@@ -225,6 +244,8 @@ static int nftnl_expr_limit_export(char *buf, size_t size,
nftnl_buf_u32(&b, type, limit->burst, BURST);
if (e->flags & (1 << NFTNL_EXPR_LIMIT_TYPE))
nftnl_buf_u32(&b, type, limit->type, TYPE);
+ if (e->flags & (1 << NFTNL_EXPR_LIMIT_FLAGS))
+ nftnl_buf_u32(&b, type, limit->flags, FLAGS);
return nftnl_buf_done(&b);
}
@@ -246,16 +267,15 @@ static int nftnl_expr_limit_snprintf_default(char *buf, size_t len,
{
struct nftnl_expr_limit *limit = nftnl_expr_data(e);
- return snprintf(buf, len, "rate %"PRIu64"/%s burst %u type %s ",
+ return snprintf(buf, len, "rate %"PRIu64"/%s burst %u type %s flags 0x%x ",
limit->rate, get_unit(limit->unit), limit->burst,
- limit_to_type(limit->type));
+ limit_to_type(limit->type), limit->flags);
}
static int
nftnl_expr_limit_snprintf(char *buf, size_t len, uint32_t type,
uint32_t flags, struct nftnl_expr *e)
{
-
switch(type) {
case NFTNL_OUTPUT_DEFAULT:
return nftnl_expr_limit_snprintf_default(buf, len, e);
diff --git a/tests/nft-expr_limit-test.c b/tests/nft-expr_limit-test.c
index bbc82c1..29fb489 100644
--- a/tests/nft-expr_limit-test.c
+++ b/tests/nft-expr_limit-test.c
@@ -43,6 +43,9 @@ static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
if (nftnl_expr_get_u64(rule_a, NFTNL_EXPR_LIMIT_TYPE) !=
nftnl_expr_get_u64(rule_b, NFTNL_EXPR_LIMIT_TYPE))
print_err("Expr TYPE mismatches");
+ if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_LIMIT_FLAGS) !=
+ nftnl_expr_get_u32(rule_b, NFTNL_EXPR_LIMIT_FLAGS))
+ print_err("Expr FLAGS mismatches");
}
int main(int argc, char *argv[])
@@ -66,6 +69,7 @@ int main(int argc, char *argv[])
nftnl_expr_set_u64(ex, NFTNL_EXPR_LIMIT_UNIT, 0x123456789abcdef0);
nftnl_expr_set_u32(ex, NFTNL_EXPR_LIMIT_BURST, 0x89123456);
nftnl_expr_set_u32(ex, NFTNL_EXPR_LIMIT_TYPE, 0xdef01234);
+ nftnl_expr_set_u32(ex, NFTNL_EXPR_LIMIT_FLAGS, 0xdef01234);
nftnl_rule_add_expr(a, ex);