summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/chain.c37
-rw-r--r--src/expr.c10
-rw-r--r--src/expr/bitwise.c35
-rw-r--r--src/expr/byteorder.c23
-rw-r--r--src/expr/cmp.c19
-rw-r--r--src/expr/connlimit.c14
-rw-r--r--src/expr/counter.c14
-rw-r--r--src/expr/ct.c20
-rw-r--r--src/expr/data_reg.c18
-rw-r--r--src/expr/dup.c14
-rw-r--r--src/expr/dynset.c27
-rw-r--r--src/expr/exthdr.c29
-rw-r--r--src/expr/fib.c17
-rw-r--r--src/expr/flow_offload.c9
-rw-r--r--src/expr/fwd.c17
-rw-r--r--src/expr/hash.c27
-rw-r--r--src/expr/immediate.c27
-rw-r--r--src/expr/inner.c18
-rw-r--r--src/expr/last.c14
-rw-r--r--src/expr/limit.c23
-rw-r--r--src/expr/log.c24
-rw-r--r--src/expr/lookup.c21
-rw-r--r--src/expr/masq.c17
-rw-r--r--src/expr/match.c13
-rw-r--r--src/expr/meta.c20
-rw-r--r--src/expr/nat.c29
-rw-r--r--src/expr/numgen.c18
-rw-r--r--src/expr/objref.c19
-rw-r--r--src/expr/osf.c15
-rw-r--r--src/expr/payload.c32
-rw-r--r--src/expr/queue.c20
-rw-r--r--src/expr/quota.c17
-rw-r--r--src/expr/range.c24
-rw-r--r--src/expr/redir.c17
-rw-r--r--src/expr/reject.c14
-rw-r--r--src/expr/rt.c14
-rw-r--r--src/expr/socket.c17
-rw-r--r--src/expr/synproxy.c15
-rw-r--r--src/expr/target.c13
-rw-r--r--src/expr/tproxy.c17
-rw-r--r--src/expr/tunnel.c14
-rw-r--r--src/expr/xfrm.c19
-rw-r--r--src/flowtable.c18
-rw-r--r--src/libnftnl.map4
-rw-r--r--src/obj/counter.c14
-rw-r--r--src/obj/ct_expect.c24
-rw-r--r--src/obj/ct_helper.c19
-rw-r--r--src/obj/ct_timeout.c26
-rw-r--r--src/obj/limit.c23
-rw-r--r--src/obj/quota.c17
-rw-r--r--src/obj/secmark.c9
-rw-r--r--src/obj/synproxy.c17
-rw-r--r--src/obj/tunnel.c56
-rw-r--r--src/object.c96
-rw-r--r--src/rule.c18
-rw-r--r--src/set.c43
-rw-r--r--src/set_elem.c12
-rw-r--r--src/table.c11
-rw-r--r--src/udata.c8
-rw-r--r--src/utils.c208
60 files changed, 790 insertions, 654 deletions
diff --git a/src/chain.c b/src/chain.c
index dcfcd04..c7026f4 100644
--- a/src/chain.c
+++ b/src/chain.c
@@ -196,6 +196,7 @@ static uint32_t nftnl_chain_validate[NFTNL_CHAIN_MAX + 1] = {
[NFTNL_CHAIN_HOOKNUM] = sizeof(uint32_t),
[NFTNL_CHAIN_PRIO] = sizeof(int32_t),
[NFTNL_CHAIN_POLICY] = sizeof(uint32_t),
+ [NFTNL_CHAIN_USE] = sizeof(uint32_t),
[NFTNL_CHAIN_BYTES] = sizeof(uint64_t),
[NFTNL_CHAIN_PACKETS] = sizeof(uint64_t),
[NFTNL_CHAIN_HANDLE] = sizeof(uint64_t),
@@ -216,21 +217,11 @@ int nftnl_chain_set_data(struct nftnl_chain *c, uint16_t attr,
switch(attr) {
case NFTNL_CHAIN_NAME:
- if (c->flags & (1 << NFTNL_CHAIN_NAME))
- xfree(c->name);
-
- c->name = strdup(data);
- if (!c->name)
- return -1;
- break;
+ return nftnl_set_str_attr(&c->name, &c->flags,
+ attr, data, data_len);
case NFTNL_CHAIN_TABLE:
- if (c->flags & (1 << NFTNL_CHAIN_TABLE))
- xfree(c->table);
-
- c->table = strdup(data);
- if (!c->table)
- return -1;
- break;
+ return nftnl_set_str_attr(&c->table, &c->flags,
+ attr, data, data_len);
case NFTNL_CHAIN_HOOKNUM:
memcpy(&c->hooknum, data, sizeof(c->hooknum));
break;
@@ -256,21 +247,11 @@ int nftnl_chain_set_data(struct nftnl_chain *c, uint16_t attr,
memcpy(&c->family, data, sizeof(c->family));
break;
case NFTNL_CHAIN_TYPE:
- if (c->flags & (1 << NFTNL_CHAIN_TYPE))
- xfree(c->type);
-
- c->type = strdup(data);
- if (!c->type)
- return -1;
- break;
+ return nftnl_set_str_attr(&c->type, &c->flags,
+ attr, data, data_len);
case NFTNL_CHAIN_DEV:
- if (c->flags & (1 << NFTNL_CHAIN_DEV))
- xfree(c->dev);
-
- c->dev = strdup(data);
- if (!c->dev)
- return -1;
- break;
+ return nftnl_set_str_attr(&c->dev, &c->flags,
+ attr, data, data_len);
case NFTNL_CHAIN_DEVICES:
dev_array = (const char **)data;
while (dev_array[len] != NULL)
diff --git a/src/expr.c b/src/expr.c
index b4581f1..4e32189 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -71,6 +71,16 @@ int nftnl_expr_set(struct nftnl_expr *expr, uint16_t type,
case NFTNL_EXPR_NAME: /* cannot be modified */
return 0;
default:
+ if (type < NFTNL_EXPR_BASE || type > expr->ops->nftnl_max_attr)
+ return -1;
+
+ if (!expr->ops->attr_policy)
+ return -1;
+
+ if (expr->ops->attr_policy[type].maxlen &&
+ expr->ops->attr_policy[type].maxlen < data_len)
+ return -1;
+
if (expr->ops->set(expr, type, data, data_len) < 0)
return -1;
}
diff --git a/src/expr/bitwise.c b/src/expr/bitwise.c
index 2d27233..e99131a 100644
--- a/src/expr/bitwise.c
+++ b/src/expr/bitwise.c
@@ -39,31 +39,23 @@ nftnl_expr_bitwise_set(struct nftnl_expr *e, uint16_t type,
switch(type) {
case NFTNL_EXPR_BITWISE_SREG:
- memcpy(&bitwise->sreg, data, sizeof(bitwise->sreg));
+ memcpy(&bitwise->sreg, data, data_len);
break;
case NFTNL_EXPR_BITWISE_DREG:
- memcpy(&bitwise->dreg, data, sizeof(bitwise->dreg));
+ memcpy(&bitwise->dreg, data, data_len);
break;
case NFTNL_EXPR_BITWISE_OP:
- memcpy(&bitwise->op, data, sizeof(bitwise->op));
+ memcpy(&bitwise->op, data, data_len);
break;
case NFTNL_EXPR_BITWISE_LEN:
- memcpy(&bitwise->len, data, sizeof(bitwise->len));
+ memcpy(&bitwise->len, data, data_len);
break;
case NFTNL_EXPR_BITWISE_MASK:
- memcpy(&bitwise->mask.val, data, data_len);
- bitwise->mask.len = data_len;
- break;
+ return nftnl_data_cpy(&bitwise->mask, data, data_len);
case NFTNL_EXPR_BITWISE_XOR:
- memcpy(&bitwise->xor.val, data, data_len);
- bitwise->xor.len = data_len;
- break;
+ return nftnl_data_cpy(&bitwise->xor, data, data_len);
case NFTNL_EXPR_BITWISE_DATA:
- memcpy(&bitwise->data.val, data, data_len);
- bitwise->data.len = data_len;
- break;
- default:
- return -1;
+ return nftnl_data_cpy(&bitwise->data, data, data_len);
}
return 0;
}
@@ -274,10 +266,21 @@ nftnl_expr_bitwise_snprintf(char *buf, size_t size,
return err;
}
+static struct attr_policy bitwise_attr_policy[__NFTNL_EXPR_BITWISE_MAX] = {
+ [NFTNL_EXPR_BITWISE_SREG] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_BITWISE_DREG] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_BITWISE_LEN] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_BITWISE_MASK] = { .maxlen = NFT_DATA_VALUE_MAXLEN },
+ [NFTNL_EXPR_BITWISE_XOR] = { .maxlen = NFT_DATA_VALUE_MAXLEN },
+ [NFTNL_EXPR_BITWISE_OP] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_BITWISE_DATA] = { .maxlen = NFT_DATA_VALUE_MAXLEN },
+};
+
struct expr_ops expr_ops_bitwise = {
.name = "bitwise",
.alloc_len = sizeof(struct nftnl_expr_bitwise),
- .max_attr = NFTA_BITWISE_MAX,
+ .nftnl_max_attr = __NFTNL_EXPR_BITWISE_MAX - 1,
+ .attr_policy = bitwise_attr_policy,
.set = nftnl_expr_bitwise_set,
.get = nftnl_expr_bitwise_get,
.parse = nftnl_expr_bitwise_parse,
diff --git a/src/expr/byteorder.c b/src/expr/byteorder.c
index 89ed0a8..383e80d 100644
--- a/src/expr/byteorder.c
+++ b/src/expr/byteorder.c
@@ -37,22 +37,20 @@ nftnl_expr_byteorder_set(struct nftnl_expr *e, uint16_t type,
switch(type) {
case NFTNL_EXPR_BYTEORDER_SREG:
- memcpy(&byteorder->sreg, data, sizeof(byteorder->sreg));
+ memcpy(&byteorder->sreg, data, data_len);
break;
case NFTNL_EXPR_BYTEORDER_DREG:
- memcpy(&byteorder->dreg, data, sizeof(byteorder->dreg));
+ memcpy(&byteorder->dreg, data, data_len);
break;
case NFTNL_EXPR_BYTEORDER_OP:
- memcpy(&byteorder->op, data, sizeof(byteorder->op));
+ memcpy(&byteorder->op, data, data_len);
break;
case NFTNL_EXPR_BYTEORDER_LEN:
- memcpy(&byteorder->len, data, sizeof(byteorder->len));
+ memcpy(&byteorder->len, data, data_len);
break;
case NFTNL_EXPR_BYTEORDER_SIZE:
- memcpy(&byteorder->size, data, sizeof(byteorder->size));
+ memcpy(&byteorder->size, data, data_len);
break;
- default:
- return -1;
}
return 0;
}
@@ -212,10 +210,19 @@ nftnl_expr_byteorder_snprintf(char *buf, size_t remain,
return offset;
}
+static struct attr_policy byteorder_attr_policy[__NFTNL_EXPR_BYTEORDER_MAX] = {
+ [NFTNL_EXPR_BYTEORDER_DREG] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_BYTEORDER_SREG] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_BYTEORDER_OP] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_BYTEORDER_LEN] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_BYTEORDER_SIZE] = { .maxlen = sizeof(uint32_t) },
+};
+
struct expr_ops expr_ops_byteorder = {
.name = "byteorder",
.alloc_len = sizeof(struct nftnl_expr_byteorder),
- .max_attr = NFTA_BYTEORDER_MAX,
+ .nftnl_max_attr = __NFTNL_EXPR_BYTEORDER_MAX - 1,
+ .attr_policy = byteorder_attr_policy,
.set = nftnl_expr_byteorder_set,
.get = nftnl_expr_byteorder_get,
.parse = nftnl_expr_byteorder_parse,
diff --git a/src/expr/cmp.c b/src/expr/cmp.c
index f9d15bb..d1f0f64 100644
--- a/src/expr/cmp.c
+++ b/src/expr/cmp.c
@@ -36,17 +36,13 @@ nftnl_expr_cmp_set(struct nftnl_expr *e, uint16_t type,
switch(type) {
case NFTNL_EXPR_CMP_SREG:
- memcpy(&cmp->sreg, data, sizeof(cmp->sreg));
+ memcpy(&cmp->sreg, data, data_len);
break;
case NFTNL_EXPR_CMP_OP:
- memcpy(&cmp->op, data, sizeof(cmp->op));
+ memcpy(&cmp->op, data, data_len);
break;
case NFTNL_EXPR_CMP_DATA:
- memcpy(&cmp->data.val, data, data_len);
- cmp->data.len = data_len;
- break;
- default:
- return -1;
+ return nftnl_data_cpy(&cmp->data, data, data_len);
}
return 0;
}
@@ -194,10 +190,17 @@ nftnl_expr_cmp_snprintf(char *buf, size_t remain,
return offset;
}
+static struct attr_policy cmp_attr_policy[__NFTNL_EXPR_CMP_MAX] = {
+ [NFTNL_EXPR_CMP_SREG] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_CMP_OP] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_CMP_DATA] = { .maxlen = NFT_DATA_VALUE_MAXLEN }
+};
+
struct expr_ops expr_ops_cmp = {
.name = "cmp",
.alloc_len = sizeof(struct nftnl_expr_cmp),
- .max_attr = NFTA_CMP_MAX,
+ .nftnl_max_attr = __NFTNL_EXPR_CMP_MAX - 1,
+ .attr_policy = cmp_attr_policy,
.set = nftnl_expr_cmp_set,
.get = nftnl_expr_cmp_get,
.parse = nftnl_expr_cmp_parse,
diff --git a/src/expr/connlimit.c b/src/expr/connlimit.c
index 549417b..fcac8bf 100644
--- a/src/expr/connlimit.c
+++ b/src/expr/connlimit.c
@@ -33,13 +33,11 @@ nftnl_expr_connlimit_set(struct nftnl_expr *e, uint16_t type,
switch(type) {
case NFTNL_EXPR_CONNLIMIT_COUNT:
- memcpy(&connlimit->count, data, sizeof(connlimit->count));
+ memcpy(&connlimit->count, data, data_len);
break;
case NFTNL_EXPR_CONNLIMIT_FLAGS:
- memcpy(&connlimit->flags, data, sizeof(connlimit->flags));
+ memcpy(&connlimit->flags, data, data_len);
break;
- default:
- return -1;
}
return 0;
}
@@ -127,10 +125,16 @@ static int nftnl_expr_connlimit_snprintf(char *buf, size_t len,
connlimit->count, connlimit->flags);
}
+static struct attr_policy connlimit_attr_policy[__NFTNL_EXPR_CONNLIMIT_MAX] = {
+ [NFTNL_EXPR_CONNLIMIT_COUNT] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_CONNLIMIT_FLAGS] = { .maxlen = sizeof(uint32_t) },
+};
+
struct expr_ops expr_ops_connlimit = {
.name = "connlimit",
.alloc_len = sizeof(struct nftnl_expr_connlimit),
- .max_attr = NFTA_CONNLIMIT_MAX,
+ .nftnl_max_attr = __NFTNL_EXPR_CONNLIMIT_MAX - 1,
+ .attr_policy = connlimit_attr_policy,
.set = nftnl_expr_connlimit_set,
.get = nftnl_expr_connlimit_get,
.parse = nftnl_expr_connlimit_parse,
diff --git a/src/expr/counter.c b/src/expr/counter.c
index d139a5f..cef9119 100644
--- a/src/expr/counter.c
+++ b/src/expr/counter.c
@@ -35,13 +35,11 @@ nftnl_expr_counter_set(struct nftnl_expr *e, uint16_t type,
switch(type) {
case NFTNL_EXPR_CTR_BYTES:
- memcpy(&ctr->bytes, data, sizeof(ctr->bytes));
+ memcpy(&ctr->bytes, data, data_len);
break;
case NFTNL_EXPR_CTR_PACKETS:
- memcpy(&ctr->pkts, data, sizeof(ctr->pkts));
+ memcpy(&ctr->pkts, data, data_len);
break;
- default:
- return -1;
}
return 0;
}
@@ -125,10 +123,16 @@ static int nftnl_expr_counter_snprintf(char *buf, size_t len,
ctr->pkts, ctr->bytes);
}
+static struct attr_policy counter_attr_policy[__NFTNL_EXPR_CTR_MAX] = {
+ [NFTNL_EXPR_CTR_PACKETS] = { .maxlen = sizeof(uint64_t) },
+ [NFTNL_EXPR_CTR_BYTES] = { .maxlen = sizeof(uint64_t) },
+};
+
struct expr_ops expr_ops_counter = {
.name = "counter",
.alloc_len = sizeof(struct nftnl_expr_counter),
- .max_attr = NFTA_COUNTER_MAX,
+ .nftnl_max_attr = __NFTNL_EXPR_CTR_MAX - 1,
+ .attr_policy = counter_attr_policy,
.set = nftnl_expr_counter_set,
.get = nftnl_expr_counter_get,
.parse = nftnl_expr_counter_parse,
diff --git a/src/expr/ct.c b/src/expr/ct.c
index f4a2aea..bea0522 100644
--- a/src/expr/ct.c
+++ b/src/expr/ct.c
@@ -39,19 +39,17 @@ nftnl_expr_ct_set(struct nftnl_expr *e, uint16_t type,
switch(type) {
case NFTNL_EXPR_CT_KEY:
- memcpy(&ct->key, data, sizeof(ct->key));
+ memcpy(&ct->key, data, data_len);
break;
case NFTNL_EXPR_CT_DIR:
- memcpy(&ct->dir, data, sizeof(ct->dir));
+ memcpy(&ct->dir, data, data_len);
break;
case NFTNL_EXPR_CT_DREG:
- memcpy(&ct->dreg, data, sizeof(ct->dreg));
+ memcpy(&ct->dreg, data, data_len);
break;
case NFTNL_EXPR_CT_SREG:
- memcpy(&ct->sreg, data, sizeof(ct->sreg));
+ memcpy(&ct->sreg, data, data_len);
break;
- default:
- return -1;
}
return 0;
}
@@ -250,10 +248,18 @@ nftnl_expr_ct_snprintf(char *buf, size_t remain,
return offset;
}
+static struct attr_policy ct_attr_policy[__NFTNL_EXPR_CT_MAX] = {
+ [NFTNL_EXPR_CT_DREG] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_CT_KEY] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_CT_DIR] = { .maxlen = sizeof(uint8_t) },
+ [NFTNL_EXPR_CT_SREG] = { .maxlen = sizeof(uint32_t) },
+};
+
struct expr_ops expr_ops_ct = {
.name = "ct",
.alloc_len = sizeof(struct nftnl_expr_ct),
- .max_attr = NFTA_CT_MAX,
+ .nftnl_max_attr = __NFTNL_EXPR_CT_MAX - 1,
+ .attr_policy = ct_attr_policy,
.set = nftnl_expr_ct_set,
.get = nftnl_expr_ct_get,
.parse = nftnl_expr_ct_parse,
diff --git a/src/expr/data_reg.c b/src/expr/data_reg.c
index 2633a77..d2ccf2e 100644
--- a/src/expr/data_reg.c
+++ b/src/expr/data_reg.c
@@ -206,14 +206,16 @@ int nftnl_parse_data(union nftnl_data_reg *data, struct nlattr *attr, int *type)
return ret;
}
-void nftnl_free_verdict(const union nftnl_data_reg *data)
+int nftnl_data_cpy(union nftnl_data_reg *dreg, const void *src, uint32_t len)
{
- switch(data->verdict) {
- case NFT_JUMP:
- case NFT_GOTO:
- xfree(data->chain);
- break;
- default:
- break;
+ int ret = 0;
+
+ if (len > sizeof(dreg->val)) {
+ len = sizeof(dreg->val);
+ ret = -1;
}
+
+ memcpy(dreg->val, src, len);
+ dreg->len = len;
+ return ret;
}
diff --git a/src/expr/dup.c b/src/expr/dup.c
index a239ff3..28d686b 100644
--- a/src/expr/dup.c
+++ b/src/expr/dup.c
@@ -32,13 +32,11 @@ static int nftnl_expr_dup_set(struct nftnl_expr *e, uint16_t type,
switch (type) {
case NFTNL_EXPR_DUP_SREG_ADDR:
- memcpy(&dup->sreg_addr, data, sizeof(dup->sreg_addr));
+ memcpy(&dup->sreg_addr, data, data_len);
break;
case NFTNL_EXPR_DUP_SREG_DEV:
- memcpy(&dup->sreg_dev, data, sizeof(dup->sreg_dev));
+ memcpy(&dup->sreg_dev, data, data_len);
break;
- default:
- return -1;
}
return 0;
}
@@ -130,10 +128,16 @@ static int nftnl_expr_dup_snprintf(char *buf, size_t remain,
return offset;
}
+static struct attr_policy dup_attr_policy[__NFTNL_EXPR_DUP_MAX] = {
+ [NFTNL_EXPR_DUP_SREG_ADDR] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_DUP_SREG_DEV] = { .maxlen = sizeof(uint32_t) },
+};
+
struct expr_ops expr_ops_dup = {
.name = "dup",
.alloc_len = sizeof(struct nftnl_expr_dup),
- .max_attr = NFTA_DUP_MAX,
+ .nftnl_max_attr = __NFTNL_EXPR_DUP_MAX - 1,
+ .attr_policy = dup_attr_policy,
.set = nftnl_expr_dup_set,
.get = nftnl_expr_dup_get,
.parse = nftnl_expr_dup_parse,
diff --git a/src/expr/dynset.c b/src/expr/dynset.c
index 5bcf1c6..8a159f8 100644
--- a/src/expr/dynset.c
+++ b/src/expr/dynset.c
@@ -41,16 +41,16 @@ nftnl_expr_dynset_set(struct nftnl_expr *e, uint16_t type,
switch (type) {
case NFTNL_EXPR_DYNSET_SREG_KEY:
- memcpy(&dynset->sreg_key, data, sizeof(dynset->sreg_key));
+ memcpy(&dynset->sreg_key, data, data_len);
break;
case NFTNL_EXPR_DYNSET_SREG_DATA:
- memcpy(&dynset->sreg_data, data, sizeof(dynset->sreg_data));
+ memcpy(&dynset->sreg_data, data, data_len);
break;
case NFTNL_EXPR_DYNSET_OP:
- memcpy(&dynset->op, data, sizeof(dynset->op));
+ memcpy(&dynset->op, data, data_len);
break;
case NFTNL_EXPR_DYNSET_TIMEOUT:
- memcpy(&dynset->timeout, data, sizeof(dynset->timeout));
+ memcpy(&dynset->timeout, data, data_len);
break;
case NFTNL_EXPR_DYNSET_SET_NAME:
dynset->set_name = strdup((const char *)data);
@@ -58,7 +58,7 @@ nftnl_expr_dynset_set(struct nftnl_expr *e, uint16_t type,
return -1;
break;
case NFTNL_EXPR_DYNSET_SET_ID:
- memcpy(&dynset->set_id, data, sizeof(dynset->set_id));
+ memcpy(&dynset->set_id, data, data_len);
break;
case NFTNL_EXPR_DYNSET_EXPR:
list_for_each_entry_safe(expr, next, &dynset->expr_list, head)
@@ -68,7 +68,7 @@ nftnl_expr_dynset_set(struct nftnl_expr *e, uint16_t type,
list_add(&expr->head, &dynset->expr_list);
break;
case NFTNL_EXPR_DYNSET_FLAGS:
- memcpy(&dynset->dynset_flags, data, sizeof(dynset->dynset_flags));
+ memcpy(&dynset->dynset_flags, data, data_len);
break;
default:
return -1;
@@ -363,10 +363,23 @@ static void nftnl_expr_dynset_free(const struct nftnl_expr *e)
nftnl_expr_free(expr);
}
+static struct attr_policy dynset_attr_policy[__NFTNL_EXPR_DYNSET_MAX] = {
+ [NFTNL_EXPR_DYNSET_SREG_KEY] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_DYNSET_SREG_DATA] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_DYNSET_OP] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_DYNSET_TIMEOUT] = { .maxlen = sizeof(uint64_t) },
+ [NFTNL_EXPR_DYNSET_SET_NAME] = { .maxlen = NFT_SET_MAXNAMELEN },
+ [NFTNL_EXPR_DYNSET_SET_ID] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_DYNSET_EXPR] = { .maxlen = 0 },
+ [NFTNL_EXPR_DYNSET_EXPRESSIONS] = { .maxlen = 0 },
+ [NFTNL_EXPR_DYNSET_FLAGS] = { .maxlen = sizeof(uint32_t) },
+};
+
struct expr_ops expr_ops_dynset = {
.name = "dynset",
.alloc_len = sizeof(struct nftnl_expr_dynset),
- .max_attr = NFTA_DYNSET_MAX,
+ .nftnl_max_attr = __NFTNL_EXPR_DYNSET_MAX - 1,
+ .attr_policy = dynset_attr_policy,
.init = nftnl_expr_dynset_init,
.free = nftnl_expr_dynset_free,
.set = nftnl_expr_dynset_set,
diff --git a/src/expr/exthdr.c b/src/expr/exthdr.c
index 739c7ff..453902c 100644
--- a/src/expr/exthdr.c
+++ b/src/expr/exthdr.c
@@ -46,28 +46,26 @@ nftnl_expr_exthdr_set(struct nftnl_expr *e, uint16_t type,
switch(type) {
case NFTNL_EXPR_EXTHDR_DREG:
- memcpy(&exthdr->dreg, data, sizeof(exthdr->dreg));
+ memcpy(&exthdr->dreg, data, data_len);
break;
case NFTNL_EXPR_EXTHDR_TYPE:
- memcpy(&exthdr->type, data, sizeof(exthdr->type));
+ memcpy(&exthdr->type, data, data_len);
break;
case NFTNL_EXPR_EXTHDR_OFFSET:
- memcpy(&exthdr->offset, data, sizeof(exthdr->offset));
+ memcpy(&exthdr->offset, data, data_len);
break;
case NFTNL_EXPR_EXTHDR_LEN:
- memcpy(&exthdr->len, data, sizeof(exthdr->len));
+ memcpy(&exthdr->len, data, data_len);
break;
case NFTNL_EXPR_EXTHDR_OP:
- memcpy(&exthdr->op, data, sizeof(exthdr->op));
+ memcpy(&exthdr->op, data, data_len);
break;
case NFTNL_EXPR_EXTHDR_FLAGS:
- memcpy(&exthdr->flags, data, sizeof(exthdr->flags));
+ memcpy(&exthdr->flags, data, data_len);
break;
case NFTNL_EXPR_EXTHDR_SREG:
- memcpy(&exthdr->sreg, data, sizeof(exthdr->sreg));
+ memcpy(&exthdr->sreg, data, data_len);
break;
- default:
- return -1;
}
return 0;
}
@@ -259,10 +257,21 @@ nftnl_expr_exthdr_snprintf(char *buf, size_t len,
}
+static struct attr_policy exthdr_attr_policy[__NFTNL_EXPR_EXTHDR_MAX] = {
+ [NFTNL_EXPR_EXTHDR_DREG] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_EXTHDR_TYPE] = { .maxlen = sizeof(uint8_t) },
+ [NFTNL_EXPR_EXTHDR_OFFSET] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_EXTHDR_LEN] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_EXTHDR_FLAGS] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_EXTHDR_OP] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_EXTHDR_SREG] = { .maxlen = sizeof(uint32_t) },
+};
+
struct expr_ops expr_ops_exthdr = {
.name = "exthdr",
.alloc_len = sizeof(struct nftnl_expr_exthdr),
- .max_attr = NFTA_EXTHDR_MAX,
+ .nftnl_max_attr = __NFTNL_EXPR_EXTHDR_MAX - 1,
+ .attr_policy = exthdr_attr_policy,
.set = nftnl_expr_exthdr_set,
.get = nftnl_expr_exthdr_get,
.parse = nftnl_expr_exthdr_parse,
diff --git a/src/expr/fib.c b/src/expr/fib.c
index 957f929..20bc125 100644
--- a/src/expr/fib.c
+++ b/src/expr/fib.c
@@ -35,16 +35,14 @@ nftnl_expr_fib_set(struct nftnl_expr *e, uint16_t result,
switch (result) {
case NFTNL_EXPR_FIB_RESULT:
- memcpy(&fib->result, data, sizeof(fib->result));
+ memcpy(&fib->result, data, data_len);
break;
case NFTNL_EXPR_FIB_DREG:
- memcpy(&fib->dreg, data, sizeof(fib->dreg));
+ memcpy(&fib->dreg, data, data_len);
break;
case NFTNL_EXPR_FIB_FLAGS:
- memcpy(&fib->flags, data, sizeof(fib->flags));
+ memcpy(&fib->flags, data, data_len);
break;
- default:
- return -1;
}
return 0;
}
@@ -190,10 +188,17 @@ nftnl_expr_fib_snprintf(char *buf, size_t remain,
return offset;
}
+static struct attr_policy fib_attr_policy[__NFTNL_EXPR_FIB_MAX] = {
+ [NFTNL_EXPR_FIB_DREG] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_FIB_RESULT] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_FIB_FLAGS] = { .maxlen = sizeof(uint32_t) },
+};
+
struct expr_ops expr_ops_fib = {
.name = "fib",
.alloc_len = sizeof(struct nftnl_expr_fib),
- .max_attr = NFTA_FIB_MAX,
+ .nftnl_max_attr = __NFTNL_EXPR_FIB_MAX - 1,
+ .attr_policy = fib_attr_policy,
.set = nftnl_expr_fib_set,
.get = nftnl_expr_fib_get,
.parse = nftnl_expr_fib_parse,
diff --git a/src/expr/flow_offload.c b/src/expr/flow_offload.c
index 4fc0563..5f209a6 100644
--- a/src/expr/flow_offload.c
+++ b/src/expr/flow_offload.c
@@ -25,8 +25,6 @@ static int nftnl_expr_flow_set(struct nftnl_expr *e, uint16_t type,
if (!flow->table_name)
return -1;
break;
- default:
- return -1;
}
return 0;
}
@@ -111,10 +109,15 @@ static void nftnl_expr_flow_free(const struct nftnl_expr *e)
xfree(flow->table_name);
}
+static struct attr_policy flow_offload_attr_policy[__NFTNL_EXPR_FLOW_MAX] = {
+ [NFTNL_EXPR_FLOW_TABLE_NAME] = { .maxlen = NFT_NAME_MAXLEN },
+};
+
struct expr_ops expr_ops_flow = {
.name = "flow_offload",
.alloc_len = sizeof(struct nftnl_expr_flow),
- .max_attr = NFTA_FLOW_MAX,
+ .nftnl_max_attr = __NFTNL_EXPR_FLOW_MAX - 1,
+ .attr_policy = flow_offload_attr_policy,
.free = nftnl_expr_flow_free,
.set = nftnl_expr_flow_set,
.get = nftnl_expr_flow_get,
diff --git a/src/expr/fwd.c b/src/expr/fwd.c
index 51f6612..04cb089 100644
--- a/src/expr/fwd.c
+++ b/src/expr/fwd.c
@@ -33,16 +33,14 @@ static int nftnl_expr_fwd_set(struct nftnl_expr *e, uint16_t type,
switch (type) {
case NFTNL_EXPR_FWD_SREG_DEV:
- memcpy(&fwd->sreg_dev, data, sizeof(fwd->sreg_dev));
+ memcpy(&fwd->sreg_dev, data, data_len);
break;
case NFTNL_EXPR_FWD_SREG_ADDR:
- memcpy(&fwd->sreg_addr, data, sizeof(fwd->sreg_addr));
+ memcpy(&fwd->sreg_addr, data, data_len);
break;
case NFTNL_EXPR_FWD_NFPROTO:
- memcpy(&fwd->nfproto, data, sizeof(fwd->nfproto));
+ memcpy(&fwd->nfproto, data, data_len);
break;
- default:
- return -1;
}
return 0;
}
@@ -150,10 +148,17 @@ static int nftnl_expr_fwd_snprintf(char *buf, size_t remain,
return offset;
}
+static struct attr_policy fwd_attr_policy[__NFTNL_EXPR_FWD_MAX] = {
+ [NFTNL_EXPR_FWD_SREG_DEV] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_FWD_SREG_ADDR] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_FWD_NFPROTO] = { .maxlen = sizeof(uint32_t) },
+};
+
struct expr_ops expr_ops_fwd = {
.name = "fwd",
.alloc_len = sizeof(struct nftnl_expr_fwd),
- .max_attr = NFTA_FWD_MAX,
+ .nftnl_max_attr = __NFTNL_EXPR_FWD_MAX - 1,
+ .attr_policy = fwd_attr_policy,
.set = nftnl_expr_fwd_set,
.get = nftnl_expr_fwd_get,
.parse = nftnl_expr_fwd_parse,
diff --git a/src/expr/hash.c b/src/expr/hash.c
index 6e2dd19..eb44b2e 100644
--- a/src/expr/hash.c
+++ b/src/expr/hash.c
@@ -37,25 +37,25 @@ nftnl_expr_hash_set(struct nftnl_expr *e, uint16_t type,
struct nftnl_expr_hash *hash = nftnl_expr_data(e);
switch (type) {
case NFTNL_EXPR_HASH_SREG:
- memcpy(&hash->sreg, data, sizeof(hash->sreg));
+ memcpy(&hash->sreg, data, data_len);
break;
case NFTNL_EXPR_HASH_DREG:
- memcpy(&hash->dreg, data, sizeof(hash->dreg));
+ memcpy(&hash->dreg, data, data_len);
break;
case NFTNL_EXPR_HASH_LEN:
- memcpy(&hash->len, data, sizeof(hash->len));
+ memcpy(&hash->len, data, data_len);
break;
case NFTNL_EXPR_HASH_MODULUS:
- memcpy(&hash->modulus, data, sizeof(hash->modulus));
+ memcpy(&hash->modulus, data, data_len);
break;
case NFTNL_EXPR_HASH_SEED:
- memcpy(&hash->seed, data, sizeof(hash->seed));
+ memcpy(&hash->seed, data, data_len);
break;
case NFTNL_EXPR_HASH_OFFSET:
- memcpy(&hash->offset, data, sizeof(hash->offset));
+ memcpy(&hash->offset, data, data_len);
break;
case NFTNL_EXPR_HASH_TYPE:
- memcpy(&hash->type, data, sizeof(hash->type));
+ memcpy(&hash->type, data, data_len);
break;
default:
return -1;
@@ -218,10 +218,21 @@ nftnl_expr_hash_snprintf(char *buf, size_t remain,
return offset;
}
+static struct attr_policy hash_attr_policy[__NFTNL_EXPR_HASH_MAX] = {
+ [NFTNL_EXPR_HASH_SREG] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_HASH_DREG] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_HASH_LEN] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_HASH_MODULUS] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_HASH_SEED] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_HASH_OFFSET] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_HASH_TYPE] = { .maxlen = sizeof(uint32_t) },
+};
+
struct expr_ops expr_ops_hash = {
.name = "hash",
.alloc_len = sizeof(struct nftnl_expr_hash),
- .max_attr = NFTA_HASH_MAX,
+ .nftnl_max_attr = __NFTNL_EXPR_HASH_MAX - 1,
+ .attr_policy = hash_attr_policy,
.set = nftnl_expr_hash_set,
.get = nftnl_expr_hash_get,
.parse = nftnl_expr_hash_parse,
diff --git a/src/expr/immediate.c b/src/expr/immediate.c
index 5d477a8..ab1276a 100644
--- a/src/expr/immediate.c
+++ b/src/expr/immediate.c
@@ -33,14 +33,12 @@ nftnl_expr_immediate_set(struct nftnl_expr *e, uint16_t type,
switch(type) {
case NFTNL_EXPR_IMM_DREG:
- memcpy(&imm->dreg, data, sizeof(imm->dreg));
+ memcpy(&imm->dreg, data, data_len);
break;
case NFTNL_EXPR_IMM_DATA:
- memcpy(&imm->data.val, data, data_len);
- imm->data.len = data_len;
- break;
+ return nftnl_data_cpy(&imm->data, data, data_len);
case NFTNL_EXPR_IMM_VERDICT:
- memcpy(&imm->data.verdict, data, sizeof(imm->data.verdict));
+ memcpy(&imm->data.verdict, data, data_len);
break;
case NFTNL_EXPR_IMM_CHAIN:
if (e->flags & (1 << NFTNL_EXPR_IMM_CHAIN))
@@ -51,10 +49,8 @@ nftnl_expr_immediate_set(struct nftnl_expr *e, uint16_t type,
return -1;
break;
case NFTNL_EXPR_IMM_CHAIN_ID:
- memcpy(&imm->data.chain_id, data, sizeof(uint32_t));
+ memcpy(&imm->data.chain_id, data, data_len);
break;
- default:
- return -1;
}
return 0;
}
@@ -216,14 +212,23 @@ static void nftnl_expr_immediate_free(const struct nftnl_expr *e)
{
struct nftnl_expr_immediate *imm = nftnl_expr_data(e);
- if (e->flags & (1 << NFTNL_EXPR_IMM_VERDICT))
- nftnl_free_verdict(&imm->data);
+ if (e->flags & (1 << NFTNL_EXPR_IMM_CHAIN))
+ xfree(imm->data.chain);
}
+static struct attr_policy immediate_attr_policy[__NFTNL_EXPR_IMM_MAX] = {
+ [NFTNL_EXPR_IMM_DREG] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_IMM_DATA] = { .maxlen = NFT_DATA_VALUE_MAXLEN },
+ [NFTNL_EXPR_IMM_VERDICT] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_IMM_CHAIN] = { .maxlen = NFT_CHAIN_MAXNAMELEN },
+ [NFTNL_EXPR_IMM_CHAIN_ID] = { .maxlen = sizeof(uint32_t) },
+};
+
struct expr_ops expr_ops_immediate = {
.name = "immediate",
.alloc_len = sizeof(struct nftnl_expr_immediate),
- .max_attr = NFTA_IMMEDIATE_MAX,
+ .nftnl_max_attr = __NFTNL_EXPR_IMM_MAX - 1,
+ .attr_policy = immediate_attr_policy,
.free = nftnl_expr_immediate_free,
.set = nftnl_expr_immediate_set,
.get = nftnl_expr_immediate_get,
diff --git a/src/expr/inner.c b/src/expr/inner.c
index 7daae4f..4f66e94 100644
--- a/src/expr/inner.c
+++ b/src/expr/inner.c
@@ -45,13 +45,13 @@ nftnl_expr_inner_set(struct nftnl_expr *e, uint16_t type,
switch(type) {
case NFTNL_EXPR_INNER_TYPE:
- memcpy(&inner->type, data, sizeof(inner->type));
+ memcpy(&inner->type, data, data_len);
break;
case NFTNL_EXPR_INNER_FLAGS:
- memcpy(&inner->flags, data, sizeof(inner->flags));
+ memcpy(&inner->flags, data, data_len);
break;
case NFTNL_EXPR_INNER_HDRSIZE:
- memcpy(&inner->hdrsize, data, sizeof(inner->hdrsize));
+ memcpy(&inner->hdrsize, data, data_len);
break;
case NFTNL_EXPR_INNER_EXPR:
if (inner->expr)
@@ -59,8 +59,6 @@ nftnl_expr_inner_set(struct nftnl_expr *e, uint16_t type,
inner->expr = (void *)data;
break;
- default:
- return -1;
}
return 0;
}
@@ -201,10 +199,18 @@ nftnl_expr_inner_snprintf(char *buf, size_t remain, uint32_t flags,
return offset;
}
+static struct attr_policy inner_attr_policy[__NFTNL_EXPR_INNER_MAX] = {
+ [NFTNL_EXPR_INNER_TYPE] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_INNER_FLAGS] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_INNER_HDRSIZE] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_INNER_EXPR] = { .maxlen = 0 },
+};
+
struct expr_ops expr_ops_inner = {
.name = "inner",
.alloc_len = sizeof(struct nftnl_expr_inner),
- .max_attr = NFTA_INNER_MAX,
+ .nftnl_max_attr = __NFTNL_EXPR_INNER_MAX - 1,
+ .attr_policy = inner_attr_policy,
.free = nftnl_expr_inner_free,
.set = nftnl_expr_inner_set,
.get = nftnl_expr_inner_get,
diff --git a/src/expr/last.c b/src/expr/last.c
index 641b713..8e5b88e 100644
--- a/src/expr/last.c
+++ b/src/expr/last.c
@@ -32,13 +32,11 @@ static int nftnl_expr_last_set(struct nftnl_expr *e, uint16_t type,
switch (type) {
case NFTNL_EXPR_LAST_MSECS:
- memcpy(&last->msecs, data, sizeof(last->msecs));
+ memcpy(&last->msecs, data, data_len);
break;
case NFTNL_EXPR_LAST_SET:
- memcpy(&last->set, data, sizeof(last->set));
+ memcpy(&last->set, data, data_len);
break;
- default:
- return -1;
}
return 0;
}
@@ -126,10 +124,16 @@ static int nftnl_expr_last_snprintf(char *buf, size_t len,
return snprintf(buf, len, "%"PRIu64" ", last->msecs);
}
+static struct attr_policy last_attr_policy[__NFTNL_EXPR_LAST_MAX] = {
+ [NFTNL_EXPR_LAST_MSECS] = { .maxlen = sizeof(uint64_t) },
+ [NFTNL_EXPR_LAST_SET] = { .maxlen = sizeof(uint32_t) },
+};
+
struct expr_ops expr_ops_last = {
.name = "last",
.alloc_len = sizeof(struct nftnl_expr_last),
- .max_attr = NFTA_LAST_MAX,
+ .nftnl_max_attr = __NFTNL_EXPR_LAST_MAX - 1,
+ .attr_policy = last_attr_policy,
.set = nftnl_expr_last_set,
.get = nftnl_expr_last_get,
.parse = nftnl_expr_last_parse,
diff --git a/src/expr/limit.c b/src/expr/limit.c
index 1870e0e..9d02592 100644
--- a/src/expr/limit.c
+++ b/src/expr/limit.c
@@ -38,22 +38,20 @@ nftnl_expr_limit_set(struct nftnl_expr *e, uint16_t type,
switch(type) {
case NFTNL_EXPR_LIMIT_RATE:
- memcpy(&limit->rate, data, sizeof(limit->rate));
+ memcpy(&limit->rate, data, data_len);
break;
case NFTNL_EXPR_LIMIT_UNIT:
- memcpy(&limit->unit, data, sizeof(limit->unit));
+ memcpy(&limit->unit, data, data_len);
break;
case NFTNL_EXPR_LIMIT_BURST:
- memcpy(&limit->burst, data, sizeof(limit->burst));
+ memcpy(&limit->burst, data, data_len);
break;
case NFTNL_EXPR_LIMIT_TYPE:
- memcpy(&limit->type, data, sizeof(limit->type));
+ memcpy(&limit->type, data, data_len);
break;
case NFTNL_EXPR_LIMIT_FLAGS:
- memcpy(&limit->flags, data, sizeof(limit->flags));
+ memcpy(&limit->flags, data, data_len);
break;
- default:
- return -1;
}
return 0;
}
@@ -194,10 +192,19 @@ nftnl_expr_limit_snprintf(char *buf, size_t len,
limit_to_type(limit->type), limit->flags);
}
+static struct attr_policy limit_attr_policy[__NFTNL_EXPR_LIMIT_MAX] = {
+ [NFTNL_EXPR_LIMIT_RATE] = { .maxlen = sizeof(uint64_t) },
+ [NFTNL_EXPR_LIMIT_UNIT] = { .maxlen = sizeof(uint64_t) },
+ [NFTNL_EXPR_LIMIT_BURST] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_LIMIT_TYPE] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_LIMIT_FLAGS] = { .maxlen = sizeof(uint32_t) },
+};
+
struct expr_ops expr_ops_limit = {
.name = "limit",
.alloc_len = sizeof(struct nftnl_expr_limit),
- .max_attr = NFTA_LIMIT_MAX,
+ .nftnl_max_attr = __NFTNL_EXPR_LIMIT_MAX - 1,
+ .attr_policy = limit_attr_policy,
.set = nftnl_expr_limit_set,
.get = nftnl_expr_limit_get,
.parse = nftnl_expr_limit_parse,
diff --git a/src/expr/log.c b/src/expr/log.c
index 180d839..18ec2b6 100644
--- a/src/expr/log.c
+++ b/src/expr/log.c
@@ -46,22 +46,20 @@ static int nftnl_expr_log_set(struct nftnl_expr *e, uint16_t type,
return -1;
break;
case NFTNL_EXPR_LOG_GROUP:
- memcpy(&log->group, data, sizeof(log->group));
+ memcpy(&log->group, data, data_len);
break;
case NFTNL_EXPR_LOG_SNAPLEN:
- memcpy(&log->snaplen, data, sizeof(log->snaplen));
+ memcpy(&log->snaplen, data, data_len);
break;
case NFTNL_EXPR_LOG_QTHRESHOLD:
- memcpy(&log->qthreshold, data, sizeof(log->qthreshold));
+ memcpy(&log->qthreshold, data, data_len);
break;
case NFTNL_EXPR_LOG_LEVEL:
- memcpy(&log->level, data, sizeof(log->level));
+ memcpy(&log->level, data, data_len);
break;
case NFTNL_EXPR_LOG_FLAGS:
- memcpy(&log->flags, data, sizeof(log->flags));
+ memcpy(&log->flags, data, data_len);
break;
- default:
- return -1;
}
return 0;
}
@@ -244,10 +242,20 @@ static void nftnl_expr_log_free(const struct nftnl_expr *e)
xfree(log->prefix);
}
+static struct attr_policy log_attr_policy[__NFTNL_EXPR_LOG_MAX] = {
+ [NFTNL_EXPR_LOG_PREFIX] = { .maxlen = NF_LOG_PREFIXLEN },
+ [NFTNL_EXPR_LOG_GROUP] = { .maxlen = sizeof(uint16_t) },
+ [NFTNL_EXPR_LOG_SNAPLEN] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_LOG_QTHRESHOLD] = { .maxlen = sizeof(uint16_t) },
+ [NFTNL_EXPR_LOG_LEVEL] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_LOG_FLAGS] = { .maxlen = sizeof(uint32_t) },
+};
+
struct expr_ops expr_ops_log = {
.name = "log",
.alloc_len = sizeof(struct nftnl_expr_log),
- .max_attr = NFTA_LOG_MAX,
+ .nftnl_max_attr = __NFTNL_EXPR_LOG_MAX - 1,
+ .attr_policy = log_attr_policy,
.free = nftnl_expr_log_free,
.set = nftnl_expr_log_set,
.get = nftnl_expr_log_get,
diff --git a/src/expr/lookup.c b/src/expr/lookup.c
index a06c338..21a7fce 100644
--- a/src/expr/lookup.c
+++ b/src/expr/lookup.c
@@ -37,10 +37,10 @@ nftnl_expr_lookup_set(struct nftnl_expr *e, uint16_t type,
switch(type) {
case NFTNL_EXPR_LOOKUP_SREG:
- memcpy(&lookup->sreg, data, sizeof(lookup->sreg));
+ memcpy(&lookup->sreg, data, data_len);
break;
case NFTNL_EXPR_LOOKUP_DREG:
- memcpy(&lookup->dreg, data, sizeof(lookup->dreg));
+ memcpy(&lookup->dreg, data, data_len);
break;
case NFTNL_EXPR_LOOKUP_SET:
lookup->set_name = strdup((const char *)data);
@@ -48,13 +48,11 @@ nftnl_expr_lookup_set(struct nftnl_expr *e, uint16_t type,
return -1;
break;
case NFTNL_EXPR_LOOKUP_SET_ID:
- memcpy(&lookup->set_id, data, sizeof(lookup->set_id));
+ memcpy(&lookup->set_id, data, data_len);
break;
case NFTNL_EXPR_LOOKUP_FLAGS:
- memcpy(&lookup->flags, data, sizeof(lookup->flags));
+ memcpy(&lookup->flags, data, data_len);
break;
- default:
- return -1;
}
return 0;
}
@@ -197,10 +195,19 @@ static void nftnl_expr_lookup_free(const struct nftnl_expr *e)
xfree(lookup->set_name);
}
+static struct attr_policy lookup_attr_policy[__NFTNL_EXPR_LOOKUP_MAX] = {
+ [NFTNL_EXPR_LOOKUP_SREG] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_LOOKUP_DREG] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_LOOKUP_SET] = { .maxlen = NFT_SET_MAXNAMELEN },
+ [NFTNL_EXPR_LOOKUP_SET_ID] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_LOOKUP_FLAGS] = { .maxlen = sizeof(uint32_t) },
+};
+
struct expr_ops expr_ops_lookup = {
.name = "lookup",
.alloc_len = sizeof(struct nftnl_expr_lookup),
- .max_attr = NFTA_LOOKUP_MAX,
+ .nftnl_max_attr = __NFTNL_EXPR_LOOKUP_MAX - 1,
+ .attr_policy = lookup_attr_policy,
.free = nftnl_expr_lookup_free,
.set = nftnl_expr_lookup_set,
.get = nftnl_expr_lookup_get,
diff --git a/src/expr/masq.c b/src/expr/masq.c
index e6e528d..e0565db 100644
--- a/src/expr/masq.c
+++ b/src/expr/masq.c
@@ -34,16 +34,14 @@ nftnl_expr_masq_set(struct nftnl_expr *e, uint16_t type,
switch (type) {
case NFTNL_EXPR_MASQ_FLAGS:
- memcpy(&masq->flags, data, sizeof(masq->flags));
+ memcpy(&masq->flags, data, data_len);
break;
case NFTNL_EXPR_MASQ_REG_PROTO_MIN:
- memcpy(&masq->sreg_proto_min, data, sizeof(masq->sreg_proto_min));
+ memcpy(&masq->sreg_proto_min, data, data_len);
break;
case NFTNL_EXPR_MASQ_REG_PROTO_MAX:
- memcpy(&masq->sreg_proto_max, data, sizeof(masq->sreg_proto_max));
+ memcpy(&masq->sreg_proto_max, data, data_len);
break;
- default:
- return -1;
}
return 0;
}
@@ -155,10 +153,17 @@ static int nftnl_expr_masq_snprintf(char *buf, size_t remain,
return offset;
}
+static struct attr_policy masq_attr_policy[__NFTNL_EXPR_MASQ_MAX] = {
+ [NFTNL_EXPR_MASQ_FLAGS] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_MASQ_REG_PROTO_MIN] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_MASQ_REG_PROTO_MAX] = { .maxlen = sizeof(uint32_t) },
+};
+
struct expr_ops expr_ops_masq = {
.name = "masq",
.alloc_len = sizeof(struct nftnl_expr_masq),
- .max_attr = NFTA_MASQ_MAX,
+ .nftnl_max_attr = __NFTNL_EXPR_MASQ_MAX - 1,
+ .attr_policy = masq_attr_policy,
.set = nftnl_expr_masq_set,
.get = nftnl_expr_masq_get,
.parse = nftnl_expr_masq_parse,
diff --git a/src/expr/match.c b/src/expr/match.c
index f472add..8c1bc74 100644
--- a/src/expr/match.c
+++ b/src/expr/match.c
@@ -46,7 +46,7 @@ nftnl_expr_match_set(struct nftnl_expr *e, uint16_t type,
(const char *)data);
break;
case NFTNL_EXPR_MT_REV:
- memcpy(&mt->rev, data, sizeof(mt->rev));
+ memcpy(&mt->rev, data, data_len);
break;
case NFTNL_EXPR_MT_INFO:
if (e->flags & (1 << NFTNL_EXPR_MT_INFO))
@@ -55,8 +55,6 @@ nftnl_expr_match_set(struct nftnl_expr *e, uint16_t type,
mt->data = data;
mt->data_len = data_len;
break;
- default:
- return -1;
}
return 0;
}
@@ -180,10 +178,17 @@ static void nftnl_expr_match_free(const struct nftnl_expr *e)
xfree(match->data);
}
+static struct attr_policy match_attr_policy[__NFTNL_EXPR_MT_MAX] = {
+ [NFTNL_EXPR_MT_NAME] = { .maxlen = XT_EXTENSION_MAXNAMELEN },
+ [NFTNL_EXPR_MT_REV] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_MT_INFO] = { .maxlen = 0 },
+};
+
struct expr_ops expr_ops_match = {
.name = "match",
.alloc_len = sizeof(struct nftnl_expr_match),
- .max_attr = NFTA_MATCH_MAX,
+ .nftnl_max_attr = __NFTNL_EXPR_MT_MAX - 1,
+ .attr_policy = match_attr_policy,
.free = nftnl_expr_match_free,
.set = nftnl_expr_match_set,
.get = nftnl_expr_match_get,
diff --git a/src/expr/meta.c b/src/expr/meta.c
index 96544a4..136a450 100644
--- a/src/expr/meta.c
+++ b/src/expr/meta.c
@@ -22,7 +22,7 @@
#include <libnftnl/rule.h>
#ifndef NFT_META_MAX
-#define NFT_META_MAX (NFT_META_SDIFNAME + 1)
+#define NFT_META_MAX (NFT_META_BRI_BROUTE + 1)
#endif
struct nftnl_expr_meta {
@@ -39,16 +39,14 @@ nftnl_expr_meta_set(struct nftnl_expr *e, uint16_t type,
switch(type) {
case NFTNL_EXPR_META_KEY:
- memcpy(&meta->key, data, sizeof(meta->key));
+ memcpy(&meta->key, data, data_len);
break;
case NFTNL_EXPR_META_DREG:
- memcpy(&meta->dreg, data, sizeof(meta->dreg));
+ memcpy(&meta->dreg, data, data_len);
break;
case NFTNL_EXPR_META_SREG:
- memcpy(&meta->sreg, data, sizeof(meta->sreg));
+ memcpy(&meta->sreg, data, data_len);
break;
- default:
- return -1;
}
return 0;
}
@@ -168,6 +166,7 @@ static const char *meta_key2str_array[NFT_META_MAX] = {
[NFT_META_TIME_HOUR] = "hour",
[NFT_META_SDIF] = "sdif",
[NFT_META_SDIFNAME] = "sdifname",
+ [NFT_META_BRI_BROUTE] = "broute",
};
static const char *meta_key2str(uint8_t key)
@@ -208,10 +207,17 @@ nftnl_expr_meta_snprintf(char *buf, size_t len,
return 0;
}
+static struct attr_policy meta_attr_policy[__NFTNL_EXPR_META_MAX] = {
+ [NFTNL_EXPR_META_KEY] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_META_DREG] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_META_SREG] = { .maxlen = sizeof(uint32_t) },
+};
+
struct expr_ops expr_ops_meta = {
.name = "meta",
.alloc_len = sizeof(struct nftnl_expr_meta),
- .max_attr = NFTA_META_MAX,
+ .nftnl_max_attr = __NFTNL_EXPR_META_MAX - 1,
+ .attr_policy = meta_attr_policy,
.set = nftnl_expr_meta_set,
.get = nftnl_expr_meta_get,
.parse = nftnl_expr_meta_parse,
diff --git a/src/expr/nat.c b/src/expr/nat.c
index ca727be..1235ba4 100644
--- a/src/expr/nat.c
+++ b/src/expr/nat.c
@@ -42,28 +42,26 @@ nftnl_expr_nat_set(struct nftnl_expr *e, uint16_t type,
switch(type) {
case NFTNL_EXPR_NAT_TYPE:
- memcpy(&nat->type, data, sizeof(nat->type));
+ memcpy(&nat->type, data, data_len);
break;
case NFTNL_EXPR_NAT_FAMILY:
- memcpy(&nat->family, data, sizeof(nat->family));
+ memcpy(&nat->family, data, data_len);
break;
case NFTNL_EXPR_NAT_REG_ADDR_MIN:
- memcpy(&nat->sreg_addr_min, data, sizeof(nat->sreg_addr_min));
+ memcpy(&nat->sreg_addr_min, data, data_len);
break;
case NFTNL_EXPR_NAT_REG_ADDR_MAX:
- memcpy(&nat->sreg_addr_max, data, sizeof(nat->sreg_addr_max));
+ memcpy(&nat->sreg_addr_max, data, data_len);
break;
case NFTNL_EXPR_NAT_REG_PROTO_MIN:
- memcpy(&nat->sreg_proto_min, data, sizeof(nat->sreg_proto_min));
+ memcpy(&nat->sreg_proto_min, data, data_len);
break;
case NFTNL_EXPR_NAT_REG_PROTO_MAX:
- memcpy(&nat->sreg_proto_max, data, sizeof(nat->sreg_proto_max));
+ memcpy(&nat->sreg_proto_max, data, data_len);
break;
case NFTNL_EXPR_NAT_FLAGS:
- memcpy(&nat->flags, data, sizeof(nat->flags));
+ memcpy(&nat->flags, data, data_len);
break;
- default:
- return -1;
}
return 0;
@@ -266,10 +264,21 @@ nftnl_expr_nat_snprintf(char *buf, size_t remain,
return offset;
}
+static struct attr_policy nat_attr_policy[__NFTNL_EXPR_NAT_MAX] = {
+ [NFTNL_EXPR_NAT_TYPE] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_NAT_FAMILY] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_NAT_REG_ADDR_MIN] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_NAT_REG_ADDR_MAX] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_NAT_REG_PROTO_MIN] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_NAT_REG_PROTO_MAX] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_NAT_FLAGS] = { .maxlen = sizeof(uint32_t) },
+};
+
struct expr_ops expr_ops_nat = {
.name = "nat",
.alloc_len = sizeof(struct nftnl_expr_nat),
- .max_attr = NFTA_NAT_MAX,
+ .nftnl_max_attr = __NFTNL_EXPR_NAT_MAX - 1,
+ .attr_policy = nat_attr_policy,
.set = nftnl_expr_nat_set,
.get = nftnl_expr_nat_get,
.parse = nftnl_expr_nat_parse,
diff --git a/src/expr/numgen.c b/src/expr/numgen.c
index d4020a6..c015b88 100644
--- a/src/expr/numgen.c
+++ b/src/expr/numgen.c
@@ -35,16 +35,16 @@ nftnl_expr_ng_set(struct nftnl_expr *e, uint16_t type,
switch (type) {
case NFTNL_EXPR_NG_DREG:
- memcpy(&ng->dreg, data, sizeof(ng->dreg));
+ memcpy(&ng->dreg, data, data_len);
break;
case NFTNL_EXPR_NG_MODULUS:
- memcpy(&ng->modulus, data, sizeof(ng->modulus));
+ memcpy(&ng->modulus, data, data_len);
break;
case NFTNL_EXPR_NG_TYPE:
- memcpy(&ng->type, data, sizeof(ng->type));
+ memcpy(&ng->type, data, data_len);
break;
case NFTNL_EXPR_NG_OFFSET:
- memcpy(&ng->offset, data, sizeof(ng->offset));
+ memcpy(&ng->offset, data, data_len);
break;
default:
return -1;
@@ -172,10 +172,18 @@ nftnl_expr_ng_snprintf(char *buf, size_t remain,
return offset;
}
+static struct attr_policy numgen_attr_policy[__NFTNL_EXPR_NG_MAX] = {
+ [NFTNL_EXPR_NG_DREG] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_NG_MODULUS] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_NG_TYPE] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_NG_OFFSET] = { .maxlen = sizeof(uint32_t) },
+};
+
struct expr_ops expr_ops_ng = {
.name = "numgen",
.alloc_len = sizeof(struct nftnl_expr_ng),
- .max_attr = NFTA_NG_MAX,
+ .nftnl_max_attr = __NFTNL_EXPR_NG_MAX - 1,
+ .attr_policy = numgen_attr_policy,
.set = nftnl_expr_ng_set,
.get = nftnl_expr_ng_get,
.parse = nftnl_expr_ng_parse,
diff --git a/src/expr/objref.c b/src/expr/objref.c
index ad0688f..0053805 100644
--- a/src/expr/objref.c
+++ b/src/expr/objref.c
@@ -39,7 +39,7 @@ static int nftnl_expr_objref_set(struct nftnl_expr *e, uint16_t type,
switch(type) {
case NFTNL_EXPR_OBJREF_IMM_TYPE:
- memcpy(&objref->imm.type, data, sizeof(objref->imm.type));
+ memcpy(&objref->imm.type, data, data_len);
break;
case NFTNL_EXPR_OBJREF_IMM_NAME:
objref->imm.name = strdup(data);
@@ -47,7 +47,7 @@ static int nftnl_expr_objref_set(struct nftnl_expr *e, uint16_t type,
return -1;
break;
case NFTNL_EXPR_OBJREF_SET_SREG:
- memcpy(&objref->set.sreg, data, sizeof(objref->set.sreg));
+ memcpy(&objref->set.sreg, data, data_len);
break;
case NFTNL_EXPR_OBJREF_SET_NAME:
objref->set.name = strdup(data);
@@ -55,10 +55,8 @@ static int nftnl_expr_objref_set(struct nftnl_expr *e, uint16_t type,
return -1;
break;
case NFTNL_EXPR_OBJREF_SET_ID:
- memcpy(&objref->set.id, data, sizeof(objref->set.id));
+ memcpy(&objref->set.id, data, data_len);
break;
- default:
- return -1;
}
return 0;
}
@@ -196,10 +194,19 @@ static void nftnl_expr_objref_free(const struct nftnl_expr *e)
xfree(objref->set.name);
}
+static struct attr_policy objref_attr_policy[__NFTNL_EXPR_OBJREF_MAX] = {
+ [NFTNL_EXPR_OBJREF_IMM_TYPE] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_OBJREF_IMM_NAME] = { .maxlen = NFT_NAME_MAXLEN },
+ [NFTNL_EXPR_OBJREF_SET_SREG] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_OBJREF_SET_NAME] = { .maxlen = NFT_NAME_MAXLEN },
+ [NFTNL_EXPR_OBJREF_SET_ID] = { .maxlen = sizeof(uint32_t) },
+};
+
struct expr_ops expr_ops_objref = {
.name = "objref",
.alloc_len = sizeof(struct nftnl_expr_objref),
- .max_attr = NFTA_OBJREF_MAX,
+ .nftnl_max_attr = __NFTNL_EXPR_OBJREF_MAX - 1,
+ .attr_policy = objref_attr_policy,
.free = nftnl_expr_objref_free,
.set = nftnl_expr_objref_set,
.get = nftnl_expr_objref_get,
diff --git a/src/expr/osf.c b/src/expr/osf.c
index f15a722..060394b 100644
--- a/src/expr/osf.c
+++ b/src/expr/osf.c
@@ -25,13 +25,13 @@ static int nftnl_expr_osf_set(struct nftnl_expr *e, uint16_t type,
switch(type) {
case NFTNL_EXPR_OSF_DREG:
- memcpy(&osf->dreg, data, sizeof(osf->dreg));
+ memcpy(&osf->dreg, data, data_len);
break;
case NFTNL_EXPR_OSF_TTL:
- memcpy(&osf->ttl, data, sizeof(osf->ttl));
+ memcpy(&osf->ttl, data, data_len);
break;
case NFTNL_EXPR_OSF_FLAGS:
- memcpy(&osf->flags, data, sizeof(osf->flags));
+ memcpy(&osf->flags, data, data_len);
break;
}
return 0;
@@ -139,10 +139,17 @@ nftnl_expr_osf_snprintf(char *buf, size_t len,
return offset;
}
+static struct attr_policy osf_attr_policy[__NFTNL_EXPR_OSF_MAX] = {
+ [NFTNL_EXPR_OSF_DREG] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_OSF_TTL] = { .maxlen = sizeof(uint8_t) },
+ [NFTNL_EXPR_OSF_FLAGS] = { .maxlen = sizeof(uint32_t) },
+};
+
struct expr_ops expr_ops_osf = {
.name = "osf",
.alloc_len = sizeof(struct nftnl_expr_osf),
- .max_attr = NFTA_OSF_MAX,
+ .nftnl_max_attr = __NFTNL_EXPR_OSF_MAX - 1,
+ .attr_policy = osf_attr_policy,
.set = nftnl_expr_osf_set,
.get = nftnl_expr_osf_get,
.parse = nftnl_expr_osf_parse,
diff --git a/src/expr/payload.c b/src/expr/payload.c
index c633e33..35cd10c 100644
--- a/src/expr/payload.c
+++ b/src/expr/payload.c
@@ -43,31 +43,29 @@ nftnl_expr_payload_set(struct nftnl_expr *e, uint16_t type,
switch(type) {
case NFTNL_EXPR_PAYLOAD_SREG:
- memcpy(&payload->sreg, data, sizeof(payload->sreg));
+ memcpy(&payload->sreg, data, data_len);
break;
case NFTNL_EXPR_PAYLOAD_DREG:
- memcpy(&payload->dreg, data, sizeof(payload->dreg));
+ memcpy(&payload->dreg, data, data_len);
break;
case NFTNL_EXPR_PAYLOAD_BASE:
- memcpy(&payload->base, data, sizeof(payload->base));
+ memcpy(&payload->base, data, data_len);
break;
case NFTNL_EXPR_PAYLOAD_OFFSET:
- memcpy(&payload->offset, data, sizeof(payload->offset));
+ memcpy(&payload->offset, data, data_len);
break;
case NFTNL_EXPR_PAYLOAD_LEN:
- memcpy(&payload->len, data, sizeof(payload->len));
+ memcpy(&payload->len, data, data_len);
break;
case NFTNL_EXPR_PAYLOAD_CSUM_TYPE:
- memcpy(&payload->csum_type, data, sizeof(payload->csum_type));
+ memcpy(&payload->csum_type, data, data_len);
break;
case NFTNL_EXPR_PAYLOAD_CSUM_OFFSET:
- memcpy(&payload->csum_offset, data, sizeof(payload->csum_offset));
+ memcpy(&payload->csum_offset, data, data_len);
break;
case NFTNL_EXPR_PAYLOAD_FLAGS:
- memcpy(&payload->csum_flags, data, sizeof(payload->csum_flags));
+ memcpy(&payload->csum_flags, data, data_len);
break;
- default:
- return -1;
}
return 0;
}
@@ -238,10 +236,22 @@ nftnl_expr_payload_snprintf(char *buf, size_t len,
payload->offset, payload->dreg);
}
+static struct attr_policy payload_attr_policy[__NFTNL_EXPR_PAYLOAD_MAX] = {
+ [NFTNL_EXPR_PAYLOAD_DREG] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_PAYLOAD_BASE] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_PAYLOAD_OFFSET] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_PAYLOAD_LEN] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_PAYLOAD_SREG] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_PAYLOAD_CSUM_TYPE] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_PAYLOAD_CSUM_OFFSET] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_PAYLOAD_FLAGS] = { .maxlen = sizeof(uint32_t) },
+};
+
struct expr_ops expr_ops_payload = {
.name = "payload",
.alloc_len = sizeof(struct nftnl_expr_payload),
- .max_attr = NFTA_PAYLOAD_MAX,
+ .nftnl_max_attr = __NFTNL_EXPR_PAYLOAD_MAX - 1,
+ .attr_policy = payload_attr_policy,
.set = nftnl_expr_payload_set,
.get = nftnl_expr_payload_get,
.parse = nftnl_expr_payload_parse,
diff --git a/src/expr/queue.c b/src/expr/queue.c
index de287f2..09220c4 100644
--- a/src/expr/queue.c
+++ b/src/expr/queue.c
@@ -34,19 +34,17 @@ static int nftnl_expr_queue_set(struct nftnl_expr *e, uint16_t type,
switch(type) {
case NFTNL_EXPR_QUEUE_NUM:
- memcpy(&queue->queuenum, data, sizeof(queue->queuenum));
+ memcpy(&queue->queuenum, data, data_len);
break;
case NFTNL_EXPR_QUEUE_TOTAL:
- memcpy(&queue->queues_total, data, sizeof(queue->queues_total));
+ memcpy(&queue->queues_total, data, data_len);
break;
case NFTNL_EXPR_QUEUE_FLAGS:
- memcpy(&queue->flags, data, sizeof(queue->flags));
+ memcpy(&queue->flags, data, data_len);
break;
case NFTNL_EXPR_QUEUE_SREG_QNUM:
- memcpy(&queue->sreg_qnum, data, sizeof(queue->sreg_qnum));
+ memcpy(&queue->sreg_qnum, data, data_len);
break;
- default:
- return -1;
}
return 0;
}
@@ -185,10 +183,18 @@ nftnl_expr_queue_snprintf(char *buf, size_t remain,
return offset;
}
+static struct attr_policy queue_attr_policy[__NFTNL_EXPR_QUEUE_MAX] = {
+ [NFTNL_EXPR_QUEUE_NUM] = { .maxlen = sizeof(uint16_t) },
+ [NFTNL_EXPR_QUEUE_TOTAL] = { .maxlen = sizeof(uint16_t) },
+ [NFTNL_EXPR_QUEUE_FLAGS] = { .maxlen = sizeof(uint16_t) },
+ [NFTNL_EXPR_QUEUE_SREG_QNUM] = { .maxlen = sizeof(uint32_t) },
+};
+
struct expr_ops expr_ops_queue = {
.name = "queue",
.alloc_len = sizeof(struct nftnl_expr_queue),
- .max_attr = NFTA_QUEUE_MAX,
+ .nftnl_max_attr = __NFTNL_EXPR_QUEUE_MAX - 1,
+ .attr_policy = queue_attr_policy,
.set = nftnl_expr_queue_set,
.get = nftnl_expr_queue_get,
.parse = nftnl_expr_queue_parse,
diff --git a/src/expr/quota.c b/src/expr/quota.c
index 835729c..ddf232f 100644
--- a/src/expr/quota.c
+++ b/src/expr/quota.c
@@ -33,16 +33,14 @@ static int nftnl_expr_quota_set(struct nftnl_expr *e, uint16_t type,
switch (type) {
case NFTNL_EXPR_QUOTA_BYTES:
- memcpy(&quota->bytes, data, sizeof(quota->bytes));
+ memcpy(&quota->bytes, data, data_len);
break;
case NFTNL_EXPR_QUOTA_CONSUMED:
- memcpy(&quota->consumed, data, sizeof(quota->consumed));
+ memcpy(&quota->consumed, data, data_len);
break;
case NFTNL_EXPR_QUOTA_FLAGS:
- memcpy(&quota->flags, data, sizeof(quota->flags));
+ memcpy(&quota->flags, data, data_len);
break;
- default:
- return -1;
}
return 0;
}
@@ -139,10 +137,17 @@ static int nftnl_expr_quota_snprintf(char *buf, size_t len,
quota->bytes, quota->consumed, quota->flags);
}
+static struct attr_policy quota_attr_policy[__NFTNL_EXPR_QUOTA_MAX] = {
+ [NFTNL_EXPR_QUOTA_BYTES] = { .maxlen = sizeof(uint64_t) },
+ [NFTNL_EXPR_QUOTA_FLAGS] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_QUOTA_CONSUMED] = { .maxlen = sizeof(uint64_t) },
+};
+
struct expr_ops expr_ops_quota = {
.name = "quota",
.alloc_len = sizeof(struct nftnl_expr_quota),
- .max_attr = NFTA_QUOTA_MAX,
+ .nftnl_max_attr = __NFTNL_EXPR_QUOTA_MAX - 1,
+ .attr_policy = quota_attr_policy,
.set = nftnl_expr_quota_set,
.get = nftnl_expr_quota_get,
.parse = nftnl_expr_quota_parse,
diff --git a/src/expr/range.c b/src/expr/range.c
index 473add8..96bb140 100644
--- a/src/expr/range.c
+++ b/src/expr/range.c
@@ -34,21 +34,15 @@ static int nftnl_expr_range_set(struct nftnl_expr *e, uint16_t type,
switch(type) {
case NFTNL_EXPR_RANGE_SREG:
- memcpy(&range->sreg, data, sizeof(range->sreg));
+ memcpy(&range->sreg, data, data_len);
break;
case NFTNL_EXPR_RANGE_OP:
- memcpy(&range->op, data, sizeof(range->op));
+ memcpy(&range->op, data, data_len);
break;
case NFTNL_EXPR_RANGE_FROM_DATA:
- memcpy(&range->data_from.val, data, data_len);
- range->data_from.len = data_len;
- break;
+ return nftnl_data_cpy(&range->data_from, data, data_len);
case NFTNL_EXPR_RANGE_TO_DATA:
- memcpy(&range->data_to.val, data, data_len);
- range->data_to.len = data_len;
- break;
- default:
- return -1;
+ return nftnl_data_cpy(&range->data_to, data, data_len);
}
return 0;
}
@@ -205,10 +199,18 @@ static int nftnl_expr_range_snprintf(char *buf, size_t remain,
return offset;
}
+static struct attr_policy range_attr_policy[__NFTNL_EXPR_RANGE_MAX] = {
+ [NFTNL_EXPR_RANGE_SREG] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_RANGE_OP] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_RANGE_FROM_DATA] = { .maxlen = NFT_DATA_VALUE_MAXLEN },
+ [NFTNL_EXPR_RANGE_TO_DATA] = { .maxlen = NFT_DATA_VALUE_MAXLEN },
+};
+
struct expr_ops expr_ops_range = {
.name = "range",
.alloc_len = sizeof(struct nftnl_expr_range),
- .max_attr = NFTA_RANGE_MAX,
+ .nftnl_max_attr = __NFTNL_EXPR_RANGE_MAX - 1,
+ .attr_policy = range_attr_policy,
.set = nftnl_expr_range_set,
.get = nftnl_expr_range_get,
.parse = nftnl_expr_range_parse,
diff --git a/src/expr/redir.c b/src/expr/redir.c
index 87c2acc..9971306 100644
--- a/src/expr/redir.c
+++ b/src/expr/redir.c
@@ -34,16 +34,14 @@ nftnl_expr_redir_set(struct nftnl_expr *e, uint16_t type,
switch (type) {
case NFTNL_EXPR_REDIR_REG_PROTO_MIN:
- memcpy(&redir->sreg_proto_min, data, sizeof(redir->sreg_proto_min));
+ memcpy(&redir->sreg_proto_min, data, data_len);
break;
case NFTNL_EXPR_REDIR_REG_PROTO_MAX:
- memcpy(&redir->sreg_proto_max, data, sizeof(redir->sreg_proto_max));
+ memcpy(&redir->sreg_proto_max, data, data_len);
break;
case NFTNL_EXPR_REDIR_FLAGS:
- memcpy(&redir->flags, data, sizeof(redir->flags));
+ memcpy(&redir->flags, data, data_len);
break;
- default:
- return -1;
}
return 0;
}
@@ -159,10 +157,17 @@ nftnl_expr_redir_snprintf(char *buf, size_t remain,
return offset;
}
+static struct attr_policy redir_attr_policy[__NFTNL_EXPR_REDIR_MAX] = {
+ [NFTNL_EXPR_REDIR_REG_PROTO_MIN] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_REDIR_REG_PROTO_MAX] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_REDIR_FLAGS] = { .maxlen = sizeof(uint32_t) },
+};
+
struct expr_ops expr_ops_redir = {
.name = "redir",
.alloc_len = sizeof(struct nftnl_expr_redir),
- .max_attr = NFTA_REDIR_MAX,
+ .nftnl_max_attr = __NFTNL_EXPR_REDIR_MAX - 1,
+ .attr_policy = redir_attr_policy,
.set = nftnl_expr_redir_set,
.get = nftnl_expr_redir_get,
.parse = nftnl_expr_redir_parse,
diff --git a/src/expr/reject.c b/src/expr/reject.c
index c7c9441..9090db3 100644
--- a/src/expr/reject.c
+++ b/src/expr/reject.c
@@ -33,13 +33,11 @@ static int nftnl_expr_reject_set(struct nftnl_expr *e, uint16_t type,
switch(type) {
case NFTNL_EXPR_REJECT_TYPE:
- memcpy(&reject->type, data, sizeof(reject->type));
+ memcpy(&reject->type, data, data_len);
break;
case NFTNL_EXPR_REJECT_CODE:
- memcpy(&reject->icmp_code, data, sizeof(reject->icmp_code));
+ memcpy(&reject->icmp_code, data, data_len);
break;
- default:
- return -1;
}
return 0;
}
@@ -126,10 +124,16 @@ nftnl_expr_reject_snprintf(char *buf, size_t len,
reject->type, reject->icmp_code);
}
+static struct attr_policy reject_attr_policy[__NFTNL_EXPR_REJECT_MAX] = {
+ [NFTNL_EXPR_REJECT_TYPE] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_REJECT_CODE] = { .maxlen = sizeof(uint8_t) },
+};
+
struct expr_ops expr_ops_reject = {
.name = "reject",
.alloc_len = sizeof(struct nftnl_expr_reject),
- .max_attr = NFTA_REJECT_MAX,
+ .nftnl_max_attr = __NFTNL_EXPR_REJECT_MAX - 1,
+ .attr_policy = reject_attr_policy,
.set = nftnl_expr_reject_set,
.get = nftnl_expr_reject_get,
.parse = nftnl_expr_reject_parse,
diff --git a/src/expr/rt.c b/src/expr/rt.c
index 695a658..ff4fd03 100644
--- a/src/expr/rt.c
+++ b/src/expr/rt.c
@@ -32,13 +32,11 @@ nftnl_expr_rt_set(struct nftnl_expr *e, uint16_t type,
switch (type) {
case NFTNL_EXPR_RT_KEY:
- memcpy(&rt->key, data, sizeof(rt->key));
+ memcpy(&rt->key, data, data_len);
break;
case NFTNL_EXPR_RT_DREG:
- memcpy(&rt->dreg, data, sizeof(rt->dreg));
+ memcpy(&rt->dreg, data, data_len);
break;
- default:
- return -1;
}
return 0;
}
@@ -154,10 +152,16 @@ nftnl_expr_rt_snprintf(char *buf, size_t len,
return 0;
}
+static struct attr_policy rt_attr_policy[__NFTNL_EXPR_RT_MAX] = {
+ [NFTNL_EXPR_RT_KEY] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_RT_DREG] = { .maxlen = sizeof(uint32_t) },
+};
+
struct expr_ops expr_ops_rt = {
.name = "rt",
.alloc_len = sizeof(struct nftnl_expr_rt),
- .max_attr = NFTA_RT_MAX,
+ .nftnl_max_attr = __NFTNL_EXPR_RT_MAX - 1,
+ .attr_policy = rt_attr_policy,
.set = nftnl_expr_rt_set,
.get = nftnl_expr_rt_get,
.parse = nftnl_expr_rt_parse,
diff --git a/src/expr/socket.c b/src/expr/socket.c
index 83045c0..7a25cdf 100644
--- a/src/expr/socket.c
+++ b/src/expr/socket.c
@@ -33,16 +33,14 @@ nftnl_expr_socket_set(struct nftnl_expr *e, uint16_t type,
switch (type) {
case NFTNL_EXPR_SOCKET_KEY:
- memcpy(&socket->key, data, sizeof(socket->key));
+ memcpy(&socket->key, data, data_len);
break;
case NFTNL_EXPR_SOCKET_DREG:
- memcpy(&socket->dreg, data, sizeof(socket->dreg));
+ memcpy(&socket->dreg, data, data_len);
break;
case NFTNL_EXPR_SOCKET_LEVEL:
- memcpy(&socket->level, data, sizeof(socket->level));
+ memcpy(&socket->level, data, data_len);
break;
- default:
- return -1;
}
return 0;
}
@@ -157,10 +155,17 @@ nftnl_expr_socket_snprintf(char *buf, size_t len,
return 0;
}
+static struct attr_policy socket_attr_policy[__NFTNL_EXPR_SOCKET_MAX] = {
+ [NFTNL_EXPR_SOCKET_KEY] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_SOCKET_DREG] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_SOCKET_LEVEL] = { .maxlen = sizeof(uint32_t) },
+};
+
struct expr_ops expr_ops_socket = {
.name = "socket",
.alloc_len = sizeof(struct nftnl_expr_socket),
- .max_attr = NFTA_SOCKET_MAX,
+ .nftnl_max_attr = __NFTNL_EXPR_SOCKET_MAX - 1,
+ .attr_policy = socket_attr_policy,
.set = nftnl_expr_socket_set,
.get = nftnl_expr_socket_get,
.parse = nftnl_expr_socket_parse,
diff --git a/src/expr/synproxy.c b/src/expr/synproxy.c
index 47fcaef..97c321b 100644
--- a/src/expr/synproxy.c
+++ b/src/expr/synproxy.c
@@ -23,13 +23,13 @@ static int nftnl_expr_synproxy_set(struct nftnl_expr *e, uint16_t type,
switch(type) {
case NFTNL_EXPR_SYNPROXY_MSS:
- memcpy(&synproxy->mss, data, sizeof(synproxy->mss));
+ memcpy(&synproxy->mss, data, data_len);
break;
case NFTNL_EXPR_SYNPROXY_WSCALE:
- memcpy(&synproxy->wscale, data, sizeof(synproxy->wscale));
+ memcpy(&synproxy->wscale, data, data_len);
break;
case NFTNL_EXPR_SYNPROXY_FLAGS:
- memcpy(&synproxy->flags, data, sizeof(synproxy->flags));
+ memcpy(&synproxy->flags, data, data_len);
break;
}
return 0;
@@ -144,10 +144,17 @@ nftnl_expr_synproxy_snprintf(char *buf, size_t len,
return offset;
}
+static struct attr_policy synproxy_attr_policy[__NFTNL_EXPR_SYNPROXY_MAX] = {
+ [NFTNL_EXPR_SYNPROXY_MSS] = { .maxlen = sizeof(uint16_t) },
+ [NFTNL_EXPR_SYNPROXY_WSCALE] = { .maxlen = sizeof(uint8_t) },
+ [NFTNL_EXPR_SYNPROXY_FLAGS] = { .maxlen = sizeof(uint32_t) },
+};
+
struct expr_ops expr_ops_synproxy = {
.name = "synproxy",
.alloc_len = sizeof(struct nftnl_expr_synproxy),
- .max_attr = NFTA_SYNPROXY_MAX,
+ .nftnl_max_attr = __NFTNL_EXPR_SYNPROXY_MAX - 1,
+ .attr_policy = synproxy_attr_policy,
.set = nftnl_expr_synproxy_set,
.get = nftnl_expr_synproxy_get,
.parse = nftnl_expr_synproxy_parse,
diff --git a/src/expr/target.c b/src/expr/target.c
index 2a3fe8a..8259a20 100644
--- a/src/expr/target.c
+++ b/src/expr/target.c
@@ -46,7 +46,7 @@ nftnl_expr_target_set(struct nftnl_expr *e, uint16_t type,
(const char *) data);
break;
case NFTNL_EXPR_TG_REV:
- memcpy(&tg->rev, data, sizeof(tg->rev));
+ memcpy(&tg->rev, data, data_len);
break;
case NFTNL_EXPR_TG_INFO:
if (e->flags & (1 << NFTNL_EXPR_TG_INFO))
@@ -55,8 +55,6 @@ nftnl_expr_target_set(struct nftnl_expr *e, uint16_t type,
tg->data = data;
tg->data_len = data_len;
break;
- default:
- return -1;
}
return 0;
}
@@ -180,10 +178,17 @@ static void nftnl_expr_target_free(const struct nftnl_expr *e)
xfree(target->data);
}
+static struct attr_policy target_attr_policy[__NFTNL_EXPR_TG_MAX] = {
+ [NFTNL_EXPR_TG_NAME] = { .maxlen = XT_EXTENSION_MAXNAMELEN },
+ [NFTNL_EXPR_TG_REV] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_TG_INFO] = { .maxlen = 0 },
+};
+
struct expr_ops expr_ops_target = {
.name = "target",
.alloc_len = sizeof(struct nftnl_expr_target),
- .max_attr = NFTA_TARGET_MAX,
+ .nftnl_max_attr = __NFTNL_EXPR_TG_MAX - 1,
+ .attr_policy = target_attr_policy,
.free = nftnl_expr_target_free,
.set = nftnl_expr_target_set,
.get = nftnl_expr_target_get,
diff --git a/src/expr/tproxy.c b/src/expr/tproxy.c
index bd5ffbf..9391ce8 100644
--- a/src/expr/tproxy.c
+++ b/src/expr/tproxy.c
@@ -34,16 +34,14 @@ nftnl_expr_tproxy_set(struct nftnl_expr *e, uint16_t type,
switch(type) {
case NFTNL_EXPR_TPROXY_FAMILY:
- memcpy(&tproxy->family, data, sizeof(tproxy->family));
+ memcpy(&tproxy->family, data, data_len);
break;
case NFTNL_EXPR_TPROXY_REG_ADDR:
- memcpy(&tproxy->sreg_addr, data, sizeof(tproxy->sreg_addr));
+ memcpy(&tproxy->sreg_addr, data, data_len);
break;
case NFTNL_EXPR_TPROXY_REG_PORT:
- memcpy(&tproxy->sreg_port, data, sizeof(tproxy->sreg_port));
+ memcpy(&tproxy->sreg_port, data, data_len);
break;
- default:
- return -1;
}
return 0;
@@ -162,10 +160,17 @@ nftnl_expr_tproxy_snprintf(char *buf, size_t remain,
return offset;
}
+static struct attr_policy tproxy_attr_policy[__NFTNL_EXPR_TPROXY_MAX] = {
+ [NFTNL_EXPR_TPROXY_FAMILY] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_TPROXY_REG_ADDR] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_TPROXY_REG_PORT] = { .maxlen = sizeof(uint32_t) },
+};
+
struct expr_ops expr_ops_tproxy = {
.name = "tproxy",
.alloc_len = sizeof(struct nftnl_expr_tproxy),
- .max_attr = NFTA_TPROXY_MAX,
+ .nftnl_max_attr = __NFTNL_EXPR_TPROXY_MAX - 1,
+ .attr_policy = tproxy_attr_policy,
.set = nftnl_expr_tproxy_set,
.get = nftnl_expr_tproxy_get,
.parse = nftnl_expr_tproxy_parse,
diff --git a/src/expr/tunnel.c b/src/expr/tunnel.c
index a00f620..861e56d 100644
--- a/src/expr/tunnel.c
+++ b/src/expr/tunnel.c
@@ -31,13 +31,11 @@ static int nftnl_expr_tunnel_set(struct nftnl_expr *e, uint16_t type,
switch(type) {
case NFTNL_EXPR_TUNNEL_KEY:
- memcpy(&tunnel->key, data, sizeof(tunnel->key));
+ memcpy(&tunnel->key, data, data_len);
break;
case NFTNL_EXPR_TUNNEL_DREG:
- memcpy(&tunnel->dreg, data, sizeof(tunnel->dreg));
+ memcpy(&tunnel->dreg, data, data_len);
break;
- default:
- return -1;
}
return 0;
}
@@ -137,10 +135,16 @@ nftnl_expr_tunnel_snprintf(char *buf, size_t len,
return 0;
}
+static struct attr_policy tunnel_attr_policy[__NFTNL_EXPR_TUNNEL_MAX] = {
+ [NFTNL_EXPR_TUNNEL_KEY] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_TUNNEL_DREG] = { .maxlen = sizeof(uint32_t) },
+};
+
struct expr_ops expr_ops_tunnel = {
.name = "tunnel",
.alloc_len = sizeof(struct nftnl_expr_tunnel),
- .max_attr = NFTA_TUNNEL_MAX,
+ .nftnl_max_attr = __NFTNL_EXPR_TUNNEL_MAX - 1,
+ .attr_policy = tunnel_attr_policy,
.set = nftnl_expr_tunnel_set,
.get = nftnl_expr_tunnel_get,
.parse = nftnl_expr_tunnel_parse,
diff --git a/src/expr/xfrm.c b/src/expr/xfrm.c
index 2db00d5..2585579 100644
--- a/src/expr/xfrm.c
+++ b/src/expr/xfrm.c
@@ -33,16 +33,16 @@ nftnl_expr_xfrm_set(struct nftnl_expr *e, uint16_t type,
switch(type) {
case NFTNL_EXPR_XFRM_KEY:
- memcpy(&x->key, data, sizeof(x->key));
+ memcpy(&x->key, data, data_len);
break;
case NFTNL_EXPR_XFRM_DIR:
- memcpy(&x->dir, data, sizeof(x->dir));
+ memcpy(&x->dir, data, data_len);
break;
case NFTNL_EXPR_XFRM_SPNUM:
- memcpy(&x->spnum, data, sizeof(x->spnum));
+ memcpy(&x->spnum, data, data_len);
break;
case NFTNL_EXPR_XFRM_DREG:
- memcpy(&x->dreg, data, sizeof(x->dreg));
+ memcpy(&x->dreg, data, data_len);
break;
default:
return -1;
@@ -188,10 +188,19 @@ nftnl_expr_xfrm_snprintf(char *buf, size_t remain,
return offset;
}
+static struct attr_policy xfrm_attr_policy[__NFTNL_EXPR_XFRM_MAX] = {
+ [NFTNL_EXPR_XFRM_DREG] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_XFRM_SREG] = { .maxlen = 0 },
+ [NFTNL_EXPR_XFRM_KEY] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_EXPR_XFRM_DIR] = { .maxlen = sizeof(uint8_t) },
+ [NFTNL_EXPR_XFRM_SPNUM] = { .maxlen = sizeof(uint32_t) },
+};
+
struct expr_ops expr_ops_xfrm = {
.name = "xfrm",
.alloc_len = sizeof(struct nftnl_expr_xfrm),
- .max_attr = NFTA_XFRM_MAX,
+ .nftnl_max_attr = __NFTNL_EXPR_XFRM_MAX - 1,
+ .attr_policy = xfrm_attr_policy,
.set = nftnl_expr_xfrm_set,
.get = nftnl_expr_xfrm_get,
.parse = nftnl_expr_xfrm_parse,
diff --git a/src/flowtable.c b/src/flowtable.c
index e6c2475..41a1456 100644
--- a/src/flowtable.c
+++ b/src/flowtable.c
@@ -102,6 +102,7 @@ static uint32_t nftnl_flowtable_validate[NFTNL_FLOWTABLE_MAX + 1] = {
[NFTNL_FLOWTABLE_HOOKNUM] = sizeof(uint32_t),
[NFTNL_FLOWTABLE_PRIO] = sizeof(int32_t),
[NFTNL_FLOWTABLE_FAMILY] = sizeof(uint32_t),
+ [NFTNL_FLOWTABLE_SIZE] = sizeof(uint32_t),
[NFTNL_FLOWTABLE_FLAGS] = sizeof(uint32_t),
[NFTNL_FLOWTABLE_HANDLE] = sizeof(uint64_t),
};
@@ -118,20 +119,11 @@ int nftnl_flowtable_set_data(struct nftnl_flowtable *c, uint16_t attr,
switch(attr) {
case NFTNL_FLOWTABLE_NAME:
- if (c->flags & (1 << NFTNL_FLOWTABLE_NAME))
- xfree(c->name);
-
- c->name = strdup(data);
- if (!c->name)
- return -1;
- break;
+ return nftnl_set_str_attr(&c->name, &c->flags,
+ attr, data, data_len);
case NFTNL_FLOWTABLE_TABLE:
- if (c->flags & (1 << NFTNL_FLOWTABLE_TABLE))
- xfree(c->table);
-
- c->table = strdup(data);
- if (!c->table)
- return -1;
+ return nftnl_set_str_attr(&c->table, &c->flags,
+ attr, data, data_len);
break;
case NFTNL_FLOWTABLE_HOOKNUM:
memcpy(&c->hooknum, data, sizeof(c->hooknum));
diff --git a/src/libnftnl.map b/src/libnftnl.map
index ad8f2af..8fffff1 100644
--- a/src/libnftnl.map
+++ b/src/libnftnl.map
@@ -47,8 +47,6 @@ global:
nftnl_chain_get_s32;
nftnl_chain_get_u64;
nftnl_chain_get_str;
- nftnl_chain_parse;
- nftnl_chain_parse_file;
nftnl_chain_snprintf;
nftnl_chain_fprintf;
nftnl_chain_nlmsg_build_payload;
@@ -174,8 +172,6 @@ global:
nftnl_set_elems_nlmsg_build_payload;
nftnl_set_elems_nlmsg_parse;
- nftnl_set_elems_foreach;
-
nftnl_set_elems_iter_create;
nftnl_set_elems_iter_cur;
nftnl_set_elems_iter_next;
diff --git a/src/obj/counter.c b/src/obj/counter.c
index ebf3e74..19e09ed 100644
--- a/src/obj/counter.c
+++ b/src/obj/counter.c
@@ -29,13 +29,11 @@ nftnl_obj_counter_set(struct nftnl_obj *e, uint16_t type,
switch(type) {
case NFTNL_OBJ_CTR_BYTES:
- memcpy(&ctr->bytes, data, sizeof(ctr->bytes));
+ memcpy(&ctr->bytes, data, data_len);
break;
case NFTNL_OBJ_CTR_PKTS:
- memcpy(&ctr->pkts, data, sizeof(ctr->pkts));
+ memcpy(&ctr->pkts, data, data_len);
break;
- default:
- return -1;
}
return 0;
}
@@ -118,11 +116,17 @@ static int nftnl_obj_counter_snprintf(char *buf, size_t len, uint32_t flags,
ctr->pkts, ctr->bytes);
}
+static struct attr_policy obj_ctr_attr_policy[__NFTNL_OBJ_CTR_MAX] = {
+ [NFTNL_OBJ_CTR_BYTES] = { .maxlen = sizeof(uint64_t) },
+ [NFTNL_OBJ_CTR_PKTS] = { .maxlen = sizeof(uint64_t) },
+};
+
struct obj_ops obj_ops_counter = {
.name = "counter",
.type = NFT_OBJECT_COUNTER,
.alloc_len = sizeof(struct nftnl_obj_counter),
- .max_attr = NFTA_COUNTER_MAX,
+ .nftnl_max_attr = __NFTNL_OBJ_CTR_MAX - 1,
+ .attr_policy = obj_ctr_attr_policy,
.set = nftnl_obj_counter_set,
.get = nftnl_obj_counter_get,
.parse = nftnl_obj_counter_parse,
diff --git a/src/obj/ct_expect.c b/src/obj/ct_expect.c
index 810ba9a..b4d6faa 100644
--- a/src/obj/ct_expect.c
+++ b/src/obj/ct_expect.c
@@ -21,22 +21,20 @@ static int nftnl_obj_ct_expect_set(struct nftnl_obj *e, uint16_t type,
switch (type) {
case NFTNL_OBJ_CT_EXPECT_L3PROTO:
- memcpy(&exp->l3proto, data, sizeof(exp->l3proto));
+ memcpy(&exp->l3proto, data, data_len);
break;
case NFTNL_OBJ_CT_EXPECT_L4PROTO:
- memcpy(&exp->l4proto, data, sizeof(exp->l4proto));
+ memcpy(&exp->l4proto, data, data_len);
break;
case NFTNL_OBJ_CT_EXPECT_DPORT:
- memcpy(&exp->dport, data, sizeof(exp->dport));
+ memcpy(&exp->dport, data, data_len);
break;
case NFTNL_OBJ_CT_EXPECT_TIMEOUT:
- memcpy(&exp->timeout, data, sizeof(exp->timeout));
+ memcpy(&exp->timeout, data, data_len);
break;
case NFTNL_OBJ_CT_EXPECT_SIZE:
- memcpy(&exp->size, data, sizeof(exp->size));
+ memcpy(&exp->size, data, data_len);
break;
- default:
- return -1;
}
return 0;
}
@@ -187,11 +185,21 @@ static int nftnl_obj_ct_expect_snprintf(char *buf, size_t remain,
return offset;
}
+static struct attr_policy
+obj_ct_expect_attr_policy[__NFTNL_OBJ_CT_EXPECT_MAX] = {
+ [NFTNL_OBJ_CT_EXPECT_L3PROTO] = { .maxlen = sizeof(uint16_t) },
+ [NFTNL_OBJ_CT_EXPECT_L4PROTO] = { .maxlen = sizeof(uint8_t) },
+ [NFTNL_OBJ_CT_EXPECT_DPORT] = { .maxlen = sizeof(uint16_t) },
+ [NFTNL_OBJ_CT_EXPECT_TIMEOUT] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_OBJ_CT_EXPECT_SIZE] = { .maxlen = sizeof(uint8_t) },
+};
+
struct obj_ops obj_ops_ct_expect = {
.name = "ct_expect",
.type = NFT_OBJECT_CT_EXPECT,
.alloc_len = sizeof(struct nftnl_obj_ct_expect),
- .max_attr = NFTA_CT_EXPECT_MAX,
+ .nftnl_max_attr = __NFTNL_OBJ_CT_EXPECT_MAX - 1,
+ .attr_policy = obj_ct_expect_attr_policy,
.set = nftnl_obj_ct_expect_set,
.get = nftnl_obj_ct_expect_get,
.parse = nftnl_obj_ct_expect_parse,
diff --git a/src/obj/ct_helper.c b/src/obj/ct_helper.c
index a31bd6f..1feccf2 100644
--- a/src/obj/ct_helper.c
+++ b/src/obj/ct_helper.c
@@ -32,13 +32,11 @@ static int nftnl_obj_ct_helper_set(struct nftnl_obj *e, uint16_t type,
snprintf(helper->name, sizeof(helper->name), "%s", (const char *)data);
break;
case NFTNL_OBJ_CT_HELPER_L3PROTO:
- memcpy(&helper->l3proto, data, sizeof(helper->l3proto));
+ memcpy(&helper->l3proto, data, data_len);
break;
case NFTNL_OBJ_CT_HELPER_L4PROTO:
- memcpy(&helper->l4proto, data, sizeof(helper->l4proto));
+ memcpy(&helper->l4proto, data, data_len);
break;
- default:
- return -1;
}
return 0;
}
@@ -141,11 +139,22 @@ static int nftnl_obj_ct_helper_snprintf(char *buf, size_t len,
helper->name, helper->l3proto, helper->l4proto);
}
+/* from kernel's include/net/netfilter/nf_conntrack_helper.h */
+#define NF_CT_HELPER_NAME_LEN 16
+
+static struct attr_policy
+obj_ct_helper_attr_policy[__NFTNL_OBJ_CT_HELPER_MAX] = {
+ [NFTNL_OBJ_CT_HELPER_NAME] = { .maxlen = NF_CT_HELPER_NAME_LEN },
+ [NFTNL_OBJ_CT_HELPER_L3PROTO] = { .maxlen = sizeof(uint16_t) },
+ [NFTNL_OBJ_CT_HELPER_L4PROTO] = { .maxlen = sizeof(uint8_t) },
+};
+
struct obj_ops obj_ops_ct_helper = {
.name = "ct_helper",
.type = NFT_OBJECT_CT_HELPER,
.alloc_len = sizeof(struct nftnl_obj_ct_helper),
- .max_attr = NFTA_CT_HELPER_MAX,
+ .nftnl_max_attr = __NFTNL_OBJ_CT_HELPER_MAX - 1,
+ .attr_policy = obj_ct_helper_attr_policy,
.set = nftnl_obj_ct_helper_set,
.get = nftnl_obj_ct_helper_get,
.parse = nftnl_obj_ct_helper_parse,
diff --git a/src/obj/ct_timeout.c b/src/obj/ct_timeout.c
index 65b48bd..b9b688e 100644
--- a/src/obj/ct_timeout.c
+++ b/src/obj/ct_timeout.c
@@ -21,7 +21,7 @@
#include "obj.h"
-static const char *const tcp_state_to_name[] = {
+static const char *const tcp_state_to_name[NFTNL_CTTIMEOUT_TCP_MAX] = {
[NFTNL_CTTIMEOUT_TCP_SYN_SENT] = "SYN_SENT",
[NFTNL_CTTIMEOUT_TCP_SYN_RECV] = "SYN_RECV",
[NFTNL_CTTIMEOUT_TCP_ESTABLISHED] = "ESTABLISHED",
@@ -35,7 +35,7 @@ static const char *const tcp_state_to_name[] = {
[NFTNL_CTTIMEOUT_TCP_UNACK] = "UNACKNOWLEDGED",
};
-static uint32_t tcp_dflt_timeout[] = {
+static uint32_t tcp_dflt_timeout[NFTNL_CTTIMEOUT_TCP_MAX] = {
[NFTNL_CTTIMEOUT_TCP_SYN_SENT] = 120,
[NFTNL_CTTIMEOUT_TCP_SYN_RECV] = 60,
[NFTNL_CTTIMEOUT_TCP_ESTABLISHED] = 432000,
@@ -49,12 +49,12 @@ static uint32_t tcp_dflt_timeout[] = {
[NFTNL_CTTIMEOUT_TCP_UNACK] = 300,
};
-static const char *const udp_state_to_name[] = {
+static const char *const udp_state_to_name[NFTNL_CTTIMEOUT_UDP_MAX] = {
[NFTNL_CTTIMEOUT_UDP_UNREPLIED] = "UNREPLIED",
[NFTNL_CTTIMEOUT_UDP_REPLIED] = "REPLIED",
};
-static uint32_t udp_dflt_timeout[] = {
+static uint32_t udp_dflt_timeout[NFTNL_CTTIMEOUT_UDP_MAX] = {
[NFTNL_CTTIMEOUT_UDP_UNREPLIED] = 30,
[NFTNL_CTTIMEOUT_UDP_REPLIED] = 180,
};
@@ -150,17 +150,18 @@ static int nftnl_obj_ct_timeout_set(struct nftnl_obj *e, uint16_t type,
switch (type) {
case NFTNL_OBJ_CT_TIMEOUT_L3PROTO:
- memcpy(&timeout->l3proto, data, sizeof(timeout->l3proto));
+ memcpy(&timeout->l3proto, data, data_len);
break;
case NFTNL_OBJ_CT_TIMEOUT_L4PROTO:
- memcpy(&timeout->l4proto, data, sizeof(timeout->l4proto));
+ memcpy(&timeout->l4proto, data, data_len);
break;
case NFTNL_OBJ_CT_TIMEOUT_ARRAY:
+ if (data_len < sizeof(uint32_t) * NFTNL_CTTIMEOUT_ARRAY_MAX)
+ return -1;
+
memcpy(timeout->timeout, data,
sizeof(uint32_t) * NFTNL_CTTIMEOUT_ARRAY_MAX);
break;
- default:
- return -1;
}
return 0;
}
@@ -307,11 +308,18 @@ static int nftnl_obj_ct_timeout_snprintf(char *buf, size_t remain,
return offset;
}
+static struct attr_policy
+obj_ct_timeout_attr_policy[__NFTNL_OBJ_CT_TIMEOUT_MAX] = {
+ [NFTNL_OBJ_CT_TIMEOUT_L3PROTO] = { .maxlen = sizeof(uint16_t) },
+ [NFTNL_OBJ_CT_TIMEOUT_L4PROTO] = { .maxlen = sizeof(uint8_t) },
+};
+
struct obj_ops obj_ops_ct_timeout = {
.name = "ct_timeout",
.type = NFT_OBJECT_CT_TIMEOUT,
.alloc_len = sizeof(struct nftnl_obj_ct_timeout),
- .max_attr = NFTA_CT_TIMEOUT_MAX,
+ .nftnl_max_attr = __NFTNL_OBJ_CT_TIMEOUT_MAX - 1,
+ .attr_policy = obj_ct_timeout_attr_policy,
.set = nftnl_obj_ct_timeout_set,
.get = nftnl_obj_ct_timeout_get,
.parse = nftnl_obj_ct_timeout_parse,
diff --git a/src/obj/limit.c b/src/obj/limit.c
index d7b1aed..cbf30b4 100644
--- a/src/obj/limit.c
+++ b/src/obj/limit.c
@@ -28,22 +28,20 @@ static int nftnl_obj_limit_set(struct nftnl_obj *e, uint16_t type,
switch (type) {
case NFTNL_OBJ_LIMIT_RATE:
- memcpy(&limit->rate, data, sizeof(limit->rate));
+ memcpy(&limit->rate, data, data_len);
break;
case NFTNL_OBJ_LIMIT_UNIT:
- memcpy(&limit->unit, data, sizeof(limit->unit));
+ memcpy(&limit->unit, data, data_len);
break;
case NFTNL_OBJ_LIMIT_BURST:
- memcpy(&limit->burst, data, sizeof(limit->burst));
+ memcpy(&limit->burst, data, data_len);
break;
case NFTNL_OBJ_LIMIT_TYPE:
- memcpy(&limit->type, data, sizeof(limit->type));
+ memcpy(&limit->type, data, data_len);
break;
case NFTNL_OBJ_LIMIT_FLAGS:
- memcpy(&limit->flags, data, sizeof(limit->flags));
+ memcpy(&limit->flags, data, data_len);
break;
- default:
- return -1;
}
return 0;
}
@@ -159,11 +157,20 @@ static int nftnl_obj_limit_snprintf(char *buf, size_t len,
limit->burst, limit->type, limit->flags);
}
+static struct attr_policy obj_limit_attr_policy[__NFTNL_OBJ_LIMIT_MAX] = {
+ [NFTNL_OBJ_LIMIT_RATE] = { .maxlen = sizeof(uint64_t) },
+ [NFTNL_OBJ_LIMIT_UNIT] = { .maxlen = sizeof(uint64_t) },
+ [NFTNL_OBJ_LIMIT_BURST] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_OBJ_LIMIT_TYPE] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_OBJ_LIMIT_FLAGS] = { .maxlen = sizeof(uint32_t) },
+};
+
struct obj_ops obj_ops_limit = {
.name = "limit",
.type = NFT_OBJECT_LIMIT,
.alloc_len = sizeof(struct nftnl_obj_limit),
- .max_attr = NFTA_LIMIT_MAX,
+ .nftnl_max_attr = __NFTNL_OBJ_LIMIT_MAX - 1,
+ .attr_policy = obj_limit_attr_policy,
.set = nftnl_obj_limit_set,
.get = nftnl_obj_limit_get,
.parse = nftnl_obj_limit_parse,
diff --git a/src/obj/quota.c b/src/obj/quota.c
index 6c7559a..526db8e 100644
--- a/src/obj/quota.c
+++ b/src/obj/quota.c
@@ -28,16 +28,14 @@ static int nftnl_obj_quota_set(struct nftnl_obj *e, uint16_t type,
switch (type) {
case NFTNL_OBJ_QUOTA_BYTES:
- memcpy(&quota->bytes, data, sizeof(quota->bytes));
+ memcpy(&quota->bytes, data, data_len);
break;
case NFTNL_OBJ_QUOTA_CONSUMED:
- memcpy(&quota->consumed, data, sizeof(quota->consumed));
+ memcpy(&quota->consumed, data, data_len);
break;
case NFTNL_OBJ_QUOTA_FLAGS:
- memcpy(&quota->flags, data, sizeof(quota->flags));
+ memcpy(&quota->flags, data, data_len);
break;
- default:
- return -1;
}
return 0;
}
@@ -135,11 +133,18 @@ static int nftnl_obj_quota_snprintf(char *buf, size_t len,
quota->bytes, quota->flags);
}
+static struct attr_policy obj_quota_attr_policy[__NFTNL_OBJ_QUOTA_MAX] = {
+ [NFTNL_OBJ_QUOTA_BYTES] = { .maxlen = sizeof(uint64_t) },
+ [NFTNL_OBJ_QUOTA_CONSUMED] = { .maxlen = sizeof(uint64_t) },
+ [NFTNL_OBJ_QUOTA_FLAGS] = { .maxlen = sizeof(uint32_t) },
+};
+
struct obj_ops obj_ops_quota = {
.name = "quota",
.type = NFT_OBJECT_QUOTA,
.alloc_len = sizeof(struct nftnl_obj_quota),
- .max_attr = NFTA_QUOTA_MAX,
+ .nftnl_max_attr = __NFTNL_OBJ_QUOTA_MAX - 1,
+ .attr_policy = obj_quota_attr_policy,
.set = nftnl_obj_quota_set,
.get = nftnl_obj_quota_get,
.parse = nftnl_obj_quota_parse,
diff --git a/src/obj/secmark.c b/src/obj/secmark.c
index e5c24b3..eea9664 100644
--- a/src/obj/secmark.c
+++ b/src/obj/secmark.c
@@ -30,8 +30,6 @@ static int nftnl_obj_secmark_set(struct nftnl_obj *e, uint16_t type,
case NFTNL_OBJ_SECMARK_CTX:
snprintf(secmark->ctx, sizeof(secmark->ctx), "%s", (const char *)data);
break;
- default:
- return -1;
}
return 0;
}
@@ -107,11 +105,16 @@ static int nftnl_obj_secmark_snprintf(char *buf, size_t len,
return snprintf(buf, len, "context %s ", secmark->ctx);
}
+static struct attr_policy obj_secmark_attr_policy[__NFTNL_OBJ_SECMARK_MAX] = {
+ [NFTNL_OBJ_SECMARK_CTX] = { .maxlen = NFT_SECMARK_CTX_MAXLEN },
+};
+
struct obj_ops obj_ops_secmark = {
.name = "secmark",
.type = NFT_OBJECT_SECMARK,
.alloc_len = sizeof(struct nftnl_obj_secmark),
- .max_attr = NFTA_SECMARK_MAX,
+ .nftnl_max_attr = __NFTNL_OBJ_SECMARK_MAX - 1,
+ .attr_policy = obj_secmark_attr_policy,
.set = nftnl_obj_secmark_set,
.get = nftnl_obj_secmark_get,
.parse = nftnl_obj_secmark_parse,
diff --git a/src/obj/synproxy.c b/src/obj/synproxy.c
index baef5c2..65fbcf7 100644
--- a/src/obj/synproxy.c
+++ b/src/obj/synproxy.c
@@ -19,16 +19,14 @@ static int nftnl_obj_synproxy_set(struct nftnl_obj *e, uint16_t type,
switch (type) {
case NFTNL_OBJ_SYNPROXY_MSS:
- synproxy->mss = *((uint16_t *)data);
+ memcpy(&synproxy->mss, data, data_len);
break;
case NFTNL_OBJ_SYNPROXY_WSCALE:
- synproxy->wscale = *((uint8_t *)data);
+ memcpy(&synproxy->wscale, data, data_len);
break;
case NFTNL_OBJ_SYNPROXY_FLAGS:
- synproxy->flags = *((uint32_t *)data);
+ memcpy(&synproxy->flags, data, data_len);
break;
- default:
- return -1;
}
return 0;
}
@@ -134,11 +132,18 @@ static int nftnl_obj_synproxy_snprintf(char *buf, size_t len,
return offset;
}
+static struct attr_policy obj_synproxy_attr_policy[__NFTNL_OBJ_SYNPROXY_MAX] = {
+ [NFTNL_OBJ_SYNPROXY_MSS] = { .maxlen = sizeof(uint16_t) },
+ [NFTNL_OBJ_SYNPROXY_WSCALE] = { .maxlen = sizeof(uint8_t) },
+ [NFTNL_OBJ_SYNPROXY_FLAGS] = { .maxlen = sizeof(uint32_t) },
+};
+
struct obj_ops obj_ops_synproxy = {
.name = "synproxy",
.type = NFT_OBJECT_SYNPROXY,
.alloc_len = sizeof(struct nftnl_obj_synproxy),
- .max_attr = NFTA_SYNPROXY_MAX,
+ .nftnl_max_attr = __NFTNL_OBJ_SYNPROXY_MAX - 1,
+ .attr_policy = obj_synproxy_attr_policy,
.set = nftnl_obj_synproxy_set,
.get = nftnl_obj_synproxy_get,
.parse = nftnl_obj_synproxy_parse,
diff --git a/src/obj/tunnel.c b/src/obj/tunnel.c
index d2503dc..0309410 100644
--- a/src/obj/tunnel.c
+++ b/src/obj/tunnel.c
@@ -29,55 +29,53 @@ nftnl_obj_tunnel_set(struct nftnl_obj *e, uint16_t type,
switch (type) {
case NFTNL_OBJ_TUNNEL_ID:
- memcpy(&tun->id, data, sizeof(tun->id));
+ memcpy(&tun->id, data, data_len);
break;
case NFTNL_OBJ_TUNNEL_IPV4_SRC:
- memcpy(&tun->src_v4, data, sizeof(tun->src_v4));
+ memcpy(&tun->src_v4, data, data_len);
break;
case NFTNL_OBJ_TUNNEL_IPV4_DST:
- memcpy(&tun->dst_v4, data, sizeof(tun->dst_v4));
+ memcpy(&tun->dst_v4, data, data_len);
break;
case NFTNL_OBJ_TUNNEL_IPV6_SRC:
- memcpy(&tun->src_v6, data, sizeof(struct in6_addr));
+ memcpy(&tun->src_v6, data, data_len);
break;
case NFTNL_OBJ_TUNNEL_IPV6_DST:
- memcpy(&tun->dst_v6, data, sizeof(struct in6_addr));
+ memcpy(&tun->dst_v6, data, data_len);
break;
case NFTNL_OBJ_TUNNEL_IPV6_FLOWLABEL:
- memcpy(&tun->flowlabel, data, sizeof(tun->flowlabel));
+ memcpy(&tun->flowlabel, data, data_len);
break;
case NFTNL_OBJ_TUNNEL_SPORT:
- memcpy(&tun->sport, data, sizeof(tun->sport));
+ memcpy(&tun->sport, data, data_len);
break;
case NFTNL_OBJ_TUNNEL_DPORT:
- memcpy(&tun->dport, data, sizeof(tun->dport));
+ memcpy(&tun->dport, data, data_len);
break;
case NFTNL_OBJ_TUNNEL_FLAGS:
- memcpy(&tun->tun_flags, data, sizeof(tun->tun_flags));
+ memcpy(&tun->tun_flags, data, data_len);
break;
case NFTNL_OBJ_TUNNEL_TOS:
- memcpy(&tun->tun_tos, data, sizeof(tun->tun_tos));
+ memcpy(&tun->tun_tos, data, data_len);
break;
case NFTNL_OBJ_TUNNEL_TTL:
- memcpy(&tun->tun_ttl, data, sizeof(tun->tun_ttl));
+ memcpy(&tun->tun_ttl, data, data_len);
break;
case NFTNL_OBJ_TUNNEL_VXLAN_GBP:
- memcpy(&tun->u.tun_vxlan.gbp, data, sizeof(tun->u.tun_vxlan.gbp));
+ memcpy(&tun->u.tun_vxlan.gbp, data, data_len);
break;
case NFTNL_OBJ_TUNNEL_ERSPAN_VERSION:
- memcpy(&tun->u.tun_erspan.version, data, sizeof(tun->u.tun_erspan.version));
+ memcpy(&tun->u.tun_erspan.version, data, data_len);
break;
case NFTNL_OBJ_TUNNEL_ERSPAN_V1_INDEX:
- memcpy(&tun->u.tun_erspan.u.v1_index, data, sizeof(tun->u.tun_erspan.u.v1_index));
+ memcpy(&tun->u.tun_erspan.u.v1_index, data, data_len);
break;
case NFTNL_OBJ_TUNNEL_ERSPAN_V2_HWID:
- memcpy(&tun->u.tun_erspan.u.v2.hwid, data, sizeof(tun->u.tun_erspan.u.v2.hwid));
+ memcpy(&tun->u.tun_erspan.u.v2.hwid, data, data_len);
break;
case NFTNL_OBJ_TUNNEL_ERSPAN_V2_DIR:
- memcpy(&tun->u.tun_erspan.u.v2.dir, data, sizeof(tun->u.tun_erspan.u.v2.dir));
+ memcpy(&tun->u.tun_erspan.u.v2.dir, data, data_len);
break;
- default:
- return -1;
}
return 0;
}
@@ -538,11 +536,31 @@ static int nftnl_obj_tunnel_snprintf(char *buf, size_t len,
return snprintf(buf, len, "id %u ", tun->id);
}
+static struct attr_policy obj_tunnel_attr_policy[__NFTNL_OBJ_TUNNEL_MAX] = {
+ [NFTNL_OBJ_TUNNEL_ID] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_OBJ_TUNNEL_IPV4_SRC] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_OBJ_TUNNEL_IPV4_DST] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_OBJ_TUNNEL_IPV6_SRC] = { .maxlen = sizeof(struct in6_addr) },
+ [NFTNL_OBJ_TUNNEL_IPV6_DST] = { .maxlen = sizeof(struct in6_addr) },
+ [NFTNL_OBJ_TUNNEL_IPV6_FLOWLABEL] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_OBJ_TUNNEL_SPORT] = { .maxlen = sizeof(uint16_t) },
+ [NFTNL_OBJ_TUNNEL_DPORT] = { .maxlen = sizeof(uint16_t) },
+ [NFTNL_OBJ_TUNNEL_FLAGS] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_OBJ_TUNNEL_TOS] = { .maxlen = sizeof(uint8_t) },
+ [NFTNL_OBJ_TUNNEL_TTL] = { .maxlen = sizeof(uint8_t) },
+ [NFTNL_OBJ_TUNNEL_VXLAN_GBP] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_OBJ_TUNNEL_ERSPAN_VERSION] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_OBJ_TUNNEL_ERSPAN_V1_INDEX] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_OBJ_TUNNEL_ERSPAN_V2_HWID] = { .maxlen = sizeof(uint8_t) },
+ [NFTNL_OBJ_TUNNEL_ERSPAN_V2_DIR] = { .maxlen = sizeof(uint8_t) },
+};
+
struct obj_ops obj_ops_tunnel = {
.name = "tunnel",
.type = NFT_OBJECT_TUNNEL,
.alloc_len = sizeof(struct nftnl_obj_tunnel),
- .max_attr = NFTA_TUNNEL_KEY_MAX,
+ .nftnl_max_attr = __NFTNL_OBJ_TUNNEL_MAX - 1,
+ .attr_policy = obj_tunnel_attr_policy,
.set = nftnl_obj_tunnel_set,
.get = nftnl_obj_tunnel_get,
.parse = nftnl_obj_tunnel_parse,
diff --git a/src/object.c b/src/object.c
index 232b97a..19cb7d0 100644
--- a/src/object.c
+++ b/src/object.c
@@ -69,32 +69,60 @@ bool nftnl_obj_is_set(const struct nftnl_obj *obj, uint16_t attr)
return obj->flags & (1 << attr);
}
+EXPORT_SYMBOL(nftnl_obj_unset);
+void nftnl_obj_unset(struct nftnl_obj *obj, uint16_t attr)
+{
+ if (!(obj->flags & (1 << attr)))
+ return;
+
+ switch (attr) {
+ case NFTNL_OBJ_TABLE:
+ xfree(obj->table);
+ break;
+ case NFTNL_OBJ_NAME:
+ xfree(obj->name);
+ break;
+ case NFTNL_OBJ_USERDATA:
+ xfree(obj->user.data);
+ break;
+ case NFTNL_OBJ_TYPE:
+ case NFTNL_OBJ_FAMILY:
+ case NFTNL_OBJ_USE:
+ case NFTNL_OBJ_HANDLE:
+ break;
+ default:
+ break;
+ }
+
+ obj->flags &= ~(1 << attr);
+}
+
static uint32_t nftnl_obj_validate[NFTNL_OBJ_MAX + 1] = {
+ [NFTNL_OBJ_TYPE] = sizeof(uint32_t),
[NFTNL_OBJ_FAMILY] = sizeof(uint32_t),
[NFTNL_OBJ_USE] = sizeof(uint32_t),
[NFTNL_OBJ_HANDLE] = sizeof(uint64_t),
};
EXPORT_SYMBOL(nftnl_obj_set_data);
-void nftnl_obj_set_data(struct nftnl_obj *obj, uint16_t attr,
- const void *data, uint32_t data_len)
+int nftnl_obj_set_data(struct nftnl_obj *obj, uint16_t attr,
+ const void *data, uint32_t data_len)
{
if (attr < NFTNL_OBJ_MAX)
nftnl_assert_validate(data, nftnl_obj_validate, attr, data_len);
switch (attr) {
case NFTNL_OBJ_TABLE:
- xfree(obj->table);
- obj->table = strdup(data);
+ return nftnl_set_str_attr(&obj->table, &obj->flags,
+ attr, data, data_len);
break;
case NFTNL_OBJ_NAME:
- xfree(obj->name);
- obj->name = strdup(data);
- break;
+ return nftnl_set_str_attr(&obj->name, &obj->flags,
+ attr, data, data_len);
case NFTNL_OBJ_TYPE:
obj->ops = nftnl_obj_ops_lookup(*((uint32_t *)data));
if (!obj->ops)
- return;
+ return -1;
break;
case NFTNL_OBJ_FAMILY:
memcpy(&obj->family, data, sizeof(obj->family));
@@ -111,16 +139,26 @@ void nftnl_obj_set_data(struct nftnl_obj *obj, uint16_t attr,
obj->user.data = malloc(data_len);
if (!obj->user.data)
- return;
+ return -1;
memcpy(obj->user.data, data, data_len);
obj->user.len = data_len;
break;
default:
- if (obj->ops)
- obj->ops->set(obj, attr, data, data_len);
- break;
+ if (!obj->ops ||
+ attr < NFTNL_OBJ_BASE ||
+ attr > obj->ops->nftnl_max_attr ||
+ !obj->ops->attr_policy)
+ return -1;
+
+ if (obj->ops->attr_policy[attr].maxlen &&
+ obj->ops->attr_policy[attr].maxlen < data_len)
+ return -1;
+
+ if (obj->ops->set(obj, attr, data, data_len) < 0)
+ return -1;
}
obj->flags |= (1 << attr);
+ return 0;
}
void nftnl_obj_set(struct nftnl_obj *obj, uint16_t attr, const void *data) __visible;
@@ -130,37 +168,37 @@ void nftnl_obj_set(struct nftnl_obj *obj, uint16_t attr, const void *data)
}
EXPORT_SYMBOL(nftnl_obj_set_u8);
-void nftnl_obj_set_u8(struct nftnl_obj *obj, uint16_t attr, uint8_t val)
+int nftnl_obj_set_u8(struct nftnl_obj *obj, uint16_t attr, uint8_t val)
{
- nftnl_obj_set_data(obj, attr, &val, sizeof(uint8_t));
+ return nftnl_obj_set_data(obj, attr, &val, sizeof(uint8_t));
}
EXPORT_SYMBOL(nftnl_obj_set_u16);
-void nftnl_obj_set_u16(struct nftnl_obj *obj, uint16_t attr, uint16_t val)
+int nftnl_obj_set_u16(struct nftnl_obj *obj, uint16_t attr, uint16_t val)
{
- nftnl_obj_set_data(obj, attr, &val, sizeof(uint16_t));
+ return nftnl_obj_set_data(obj, attr, &val, sizeof(uint16_t));
}
EXPORT_SYMBOL(nftnl_obj_set_u32);
-void nftnl_obj_set_u32(struct nftnl_obj *obj, uint16_t attr, uint32_t val)
+int nftnl_obj_set_u32(struct nftnl_obj *obj, uint16_t attr, uint32_t val)
{
- nftnl_obj_set_data(obj, attr, &val, sizeof(uint32_t));
+ return nftnl_obj_set_data(obj, attr, &val, sizeof(uint32_t));
}
EXPORT_SYMBOL(nftnl_obj_set_u64);
-void nftnl_obj_set_u64(struct nftnl_obj *obj, uint16_t attr, uint64_t val)
+int nftnl_obj_set_u64(struct nftnl_obj *obj, uint16_t attr, uint64_t val)
{
- nftnl_obj_set_data(obj, attr, &val, sizeof(uint64_t));
+ return nftnl_obj_set_data(obj, attr, &val, sizeof(uint64_t));
}
EXPORT_SYMBOL(nftnl_obj_set_str);
-void nftnl_obj_set_str(struct nftnl_obj *obj, uint16_t attr, const char *str)
+int nftnl_obj_set_str(struct nftnl_obj *obj, uint16_t attr, const char *str)
{
- nftnl_obj_set_data(obj, attr, str, 0);
+ return nftnl_obj_set_data(obj, attr, str, strlen(str) + 1);
}
EXPORT_SYMBOL(nftnl_obj_get_data);
-const void *nftnl_obj_get_data(struct nftnl_obj *obj, uint16_t attr,
+const void *nftnl_obj_get_data(const struct nftnl_obj *obj, uint16_t attr,
uint32_t *data_len)
{
if (!(obj->flags & (1 << attr)))
@@ -198,42 +236,42 @@ const void *nftnl_obj_get_data(struct nftnl_obj *obj, uint16_t attr,
}
EXPORT_SYMBOL(nftnl_obj_get);
-const void *nftnl_obj_get(struct nftnl_obj *obj, uint16_t attr)
+const void *nftnl_obj_get(const struct nftnl_obj *obj, uint16_t attr)
{
uint32_t data_len;
return nftnl_obj_get_data(obj, attr, &data_len);
}
EXPORT_SYMBOL(nftnl_obj_get_u8);
-uint8_t nftnl_obj_get_u8(struct nftnl_obj *obj, uint16_t attr)
+uint8_t nftnl_obj_get_u8(const struct nftnl_obj *obj, uint16_t attr)
{
const void *ret = nftnl_obj_get(obj, attr);
return ret == NULL ? 0 : *((uint8_t *)ret);
}
EXPORT_SYMBOL(nftnl_obj_get_u16);
-uint16_t nftnl_obj_get_u16(struct nftnl_obj *obj, uint16_t attr)
+uint16_t nftnl_obj_get_u16(const struct nftnl_obj *obj, uint16_t attr)
{
const void *ret = nftnl_obj_get(obj, attr);
return ret == NULL ? 0 : *((uint16_t *)ret);
}
EXPORT_SYMBOL(nftnl_obj_get_u32);
-uint32_t nftnl_obj_get_u32(struct nftnl_obj *obj, uint16_t attr)
+uint32_t nftnl_obj_get_u32(const struct nftnl_obj *obj, uint16_t attr)
{
const void *ret = nftnl_obj_get(obj, attr);
return ret == NULL ? 0 : *((uint32_t *)ret);
}
EXPORT_SYMBOL(nftnl_obj_get_u64);
-uint64_t nftnl_obj_get_u64(struct nftnl_obj *obj, uint16_t attr)
+uint64_t nftnl_obj_get_u64(const struct nftnl_obj *obj, uint16_t attr)
{
const void *ret = nftnl_obj_get(obj, attr);
return ret == NULL ? 0 : *((uint64_t *)ret);
}
EXPORT_SYMBOL(nftnl_obj_get_str);
-const char *nftnl_obj_get_str(struct nftnl_obj *obj, uint16_t attr)
+const char *nftnl_obj_get_str(const struct nftnl_obj *obj, uint16_t attr)
{
return nftnl_obj_get(obj, attr);
}
diff --git a/src/rule.c b/src/rule.c
index a52012b..e16e2c1 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -115,21 +115,11 @@ int nftnl_rule_set_data(struct nftnl_rule *r, uint16_t attr,
switch(attr) {
case NFTNL_RULE_TABLE:
- if (r->flags & (1 << NFTNL_RULE_TABLE))
- xfree(r->table);
-
- r->table = strdup(data);
- if (!r->table)
- return -1;
- break;
+ return nftnl_set_str_attr(&r->table, &r->flags,
+ attr, data, data_len);
case NFTNL_RULE_CHAIN:
- if (r->flags & (1 << NFTNL_RULE_CHAIN))
- xfree(r->chain);
-
- r->chain = strdup(data);
- if (!r->chain)
- return -1;
- break;
+ return nftnl_set_str_attr(&r->chain, &r->flags,
+ attr, data, data_len);
case NFTNL_RULE_HANDLE:
memcpy(&r->handle, data, sizeof(r->handle));
break;
diff --git a/src/set.c b/src/set.c
index c46f827..07e332d 100644
--- a/src/set.c
+++ b/src/set.c
@@ -54,8 +54,10 @@ void nftnl_set_free(const struct nftnl_set *s)
if (s->flags & (1 << NFTNL_SET_USERDATA))
xfree(s->user.data);
- list_for_each_entry_safe(expr, next, &s->expr_list, head)
+ list_for_each_entry_safe(expr, next, &s->expr_list, head) {
+ list_del(&expr->head);
nftnl_expr_free(expr);
+ }
list_for_each_entry_safe(elem, tmp, &s->element_list, head) {
list_del(&elem->head);
@@ -105,8 +107,10 @@ void nftnl_set_unset(struct nftnl_set *s, uint16_t attr)
break;
case NFTNL_SET_EXPR:
case NFTNL_SET_EXPRESSIONS:
- list_for_each_entry_safe(expr, tmp, &s->expr_list, head)
+ list_for_each_entry_safe(expr, tmp, &s->expr_list, head) {
+ list_del(&expr->head);
nftnl_expr_free(expr);
+ }
break;
default:
return;
@@ -124,6 +128,7 @@ static uint32_t nftnl_set_validate[NFTNL_SET_MAX + 1] = {
[NFTNL_SET_DATA_LEN] = sizeof(uint32_t),
[NFTNL_SET_OBJ_TYPE] = sizeof(uint32_t),
[NFTNL_SET_FAMILY] = sizeof(uint32_t),
+ [NFTNL_SET_ID] = sizeof(uint32_t),
[NFTNL_SET_POLICY] = sizeof(uint32_t),
[NFTNL_SET_DESC_SIZE] = sizeof(uint32_t),
[NFTNL_SET_TIMEOUT] = sizeof(uint64_t),
@@ -141,21 +146,11 @@ int nftnl_set_set_data(struct nftnl_set *s, uint16_t attr, const void *data,
switch(attr) {
case NFTNL_SET_TABLE:
- if (s->flags & (1 << NFTNL_SET_TABLE))
- xfree(s->table);
-
- s->table = strdup(data);
- if (!s->table)
- return -1;
- break;
+ return nftnl_set_str_attr(&s->table, &s->flags,
+ attr, data, data_len);
case NFTNL_SET_NAME:
- if (s->flags & (1 << NFTNL_SET_NAME))
- xfree(s->name);
-
- s->name = strdup(data);
- if (!s->name)
- return -1;
- break;
+ return nftnl_set_str_attr(&s->name, &s->flags,
+ attr, data, data_len);
case NFTNL_SET_HANDLE:
memcpy(&s->handle, data, sizeof(s->handle));
break;
@@ -190,8 +185,14 @@ int nftnl_set_set_data(struct nftnl_set *s, uint16_t attr, const void *data,
memcpy(&s->desc.size, data, sizeof(s->desc.size));
break;
case NFTNL_SET_DESC_CONCAT:
+ if (data_len > sizeof(s->desc.field_len))
+ return -1;
+
memcpy(&s->desc.field_len, data, data_len);
- while (s->desc.field_len[++s->desc.field_count]);
+ while (s->desc.field_len[++s->desc.field_count]) {
+ if (s->desc.field_count >= NFT_REG32_COUNT)
+ break;
+ }
break;
case NFTNL_SET_TIMEOUT:
memcpy(&s->timeout, data, sizeof(s->timeout));
@@ -210,8 +211,10 @@ int nftnl_set_set_data(struct nftnl_set *s, uint16_t attr, const void *data,
s->user.len = data_len;
break;
case NFTNL_SET_EXPR:
- list_for_each_entry_safe(expr, tmp, &s->expr_list, head)
+ list_for_each_entry_safe(expr, tmp, &s->expr_list, head) {
+ list_del(&expr->head);
nftnl_expr_free(expr);
+ }
expr = (void *)data;
list_add(&expr->head, &s->expr_list);
@@ -742,8 +745,10 @@ int nftnl_set_nlmsg_parse(const struct nlmsghdr *nlh, struct nftnl_set *s)
return 0;
out_set_expr:
- list_for_each_entry_safe(expr, next, &s->expr_list, head)
+ list_for_each_entry_safe(expr, next, &s->expr_list, head) {
+ list_del(&expr->head);
nftnl_expr_free(expr);
+ }
return -1;
}
diff --git a/src/set_elem.c b/src/set_elem.c
index 884faff..9207a0d 100644
--- a/src/set_elem.c
+++ b/src/set_elem.c
@@ -126,12 +126,12 @@ int nftnl_set_elem_set(struct nftnl_set_elem *s, uint16_t attr,
memcpy(&s->set_elem_flags, data, sizeof(s->set_elem_flags));
break;
case NFTNL_SET_ELEM_KEY: /* NFTA_SET_ELEM_KEY */
- memcpy(&s->key.val, data, data_len);
- s->key.len = data_len;
+ if (nftnl_data_cpy(&s->key, data, data_len) < 0)
+ return -1;
break;
case NFTNL_SET_ELEM_KEY_END: /* NFTA_SET_ELEM_KEY_END */
- memcpy(&s->key_end.val, data, data_len);
- s->key_end.len = data_len;
+ if (nftnl_data_cpy(&s->key_end, data, data_len) < 0)
+ return -1;
break;
case NFTNL_SET_ELEM_VERDICT: /* NFTA_SET_ELEM_DATA */
memcpy(&s->data.verdict, data, sizeof(s->data.verdict));
@@ -145,8 +145,8 @@ int nftnl_set_elem_set(struct nftnl_set_elem *s, uint16_t attr,
return -1;
break;
case NFTNL_SET_ELEM_DATA: /* NFTA_SET_ELEM_DATA */
- memcpy(s->data.val, data, data_len);
- s->data.len = data_len;
+ if (nftnl_data_cpy(&s->data, data, data_len) < 0)
+ return -1;
break;
case NFTNL_SET_ELEM_TIMEOUT: /* NFTA_SET_ELEM_TIMEOUT */
memcpy(&s->timeout, data, sizeof(s->timeout));
diff --git a/src/table.c b/src/table.c
index 59e7053..13f01cf 100644
--- a/src/table.c
+++ b/src/table.c
@@ -88,6 +88,8 @@ static uint32_t nftnl_table_validate[NFTNL_TABLE_MAX + 1] = {
[NFTNL_TABLE_FLAGS] = sizeof(uint32_t),
[NFTNL_TABLE_FAMILY] = sizeof(uint32_t),
[NFTNL_TABLE_HANDLE] = sizeof(uint64_t),
+ [NFTNL_TABLE_USE] = sizeof(uint32_t),
+ [NFTNL_TABLE_OWNER] = sizeof(uint32_t),
};
EXPORT_SYMBOL(nftnl_table_set_data);
@@ -99,13 +101,8 @@ int nftnl_table_set_data(struct nftnl_table *t, uint16_t attr,
switch (attr) {
case NFTNL_TABLE_NAME:
- if (t->flags & (1 << NFTNL_TABLE_NAME))
- xfree(t->name);
-
- t->name = strdup(data);
- if (!t->name)
- return -1;
- break;
+ return nftnl_set_str_attr(&t->name, &t->flags,
+ attr, data, data_len);
case NFTNL_TABLE_HANDLE:
memcpy(&t->handle, data, sizeof(t->handle));
break;
diff --git a/src/udata.c b/src/udata.c
index 0cc3520..e9bfc35 100644
--- a/src/udata.c
+++ b/src/udata.c
@@ -42,6 +42,11 @@ uint32_t nftnl_udata_buf_len(const struct nftnl_udata_buf *buf)
return (uint32_t)(buf->end - buf->data);
}
+static uint32_t nftnl_udata_buf_space(const struct nftnl_udata_buf *buf)
+{
+ return buf->size - nftnl_udata_buf_len(buf);
+}
+
EXPORT_SYMBOL(nftnl_udata_buf_data);
void *nftnl_udata_buf_data(const struct nftnl_udata_buf *buf)
{
@@ -74,7 +79,8 @@ bool nftnl_udata_put(struct nftnl_udata_buf *buf, uint8_t type, uint32_t len,
{
struct nftnl_udata *attr;
- if (len > UINT8_MAX || buf->size < len + sizeof(struct nftnl_udata))
+ if (len > UINT8_MAX ||
+ nftnl_udata_buf_space(buf) < len + sizeof(struct nftnl_udata))
return false;
attr = (struct nftnl_udata *)buf->end;
diff --git a/src/utils.c b/src/utils.c
index 3617837..2f1ffd6 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -39,146 +39,6 @@ const char *nftnl_family2str(uint32_t family)
return nftnl_family_str[family];
}
-int nftnl_str2family(const char *family)
-{
- int i;
-
- for (i = 0; i < NFPROTO_NUMPROTO; i++) {
- if (nftnl_family_str[i] == NULL)
- continue;
-
- if (strcmp(nftnl_family_str[i], family) == 0)
- return i;
- }
-
- errno = EAFNOSUPPORT;
- return -1;
-}
-
-static struct {
- int len;
- int64_t min;
- uint64_t max;
-} basetype[] = {
- [NFTNL_TYPE_U8] = { .len = sizeof(uint8_t), .max = UINT8_MAX },
- [NFTNL_TYPE_U16] = { .len = sizeof(uint16_t), .max = UINT16_MAX },
- [NFTNL_TYPE_U32] = { .len = sizeof(uint32_t), .max = UINT32_MAX },
- [NFTNL_TYPE_U64] = { .len = sizeof(uint64_t), .max = UINT64_MAX },
- [NFTNL_TYPE_S8] = { .len = sizeof(int8_t), .min = INT8_MIN, .max = INT8_MAX },
- [NFTNL_TYPE_S16] = { .len = sizeof(int16_t), .min = INT16_MIN, .max = INT16_MAX },
- [NFTNL_TYPE_S32] = { .len = sizeof(int32_t), .min = INT32_MIN, .max = INT32_MAX },
- [NFTNL_TYPE_S64] = { .len = sizeof(int64_t), .min = INT64_MIN, .max = INT64_MAX },
-};
-
-int nftnl_get_value(enum nftnl_type type, void *val, void *out)
-{
- union {
- uint8_t u8;
- uint16_t u16;
- uint32_t u32;
- int8_t s8;
- int16_t s16;
- int32_t s32;
- } values;
- void *valuep = NULL;
- int64_t sval;
- uint64_t uval;
-
- switch (type) {
- case NFTNL_TYPE_U8:
- case NFTNL_TYPE_U16:
- case NFTNL_TYPE_U32:
- case NFTNL_TYPE_U64:
- memcpy(&uval, val, sizeof(uval));
- if (uval > basetype[type].max) {
- errno = ERANGE;
- return -1;
- }
- break;
- case NFTNL_TYPE_S8:
- case NFTNL_TYPE_S16:
- case NFTNL_TYPE_S32:
- case NFTNL_TYPE_S64:
- memcpy(&sval, val, sizeof(sval));
- if (sval < basetype[type].min ||
- sval > (int64_t)basetype[type].max) {
- errno = ERANGE;
- return -1;
- }
- break;
- }
-
- switch (type) {
- case NFTNL_TYPE_U8:
- values.u8 = uval;
- valuep = &values.u8;
- break;
- case NFTNL_TYPE_U16:
- values.u16 = uval;
- valuep = &values.u16;
- break;
- case NFTNL_TYPE_U32:
- values.u32 = uval;
- valuep = &values.u32;
- break;
- case NFTNL_TYPE_U64:
- valuep = &uval;
- break;
- case NFTNL_TYPE_S8:
- values.s8 = sval;
- valuep = &values.s8;
- break;
- case NFTNL_TYPE_S16:
- values.s16 = sval;
- valuep = &values.s16;
- break;
- case NFTNL_TYPE_S32:
- values.s32 = sval;
- valuep = &values.s32;
- break;
- case NFTNL_TYPE_S64:
- valuep = &sval;
- break;
- }
- memcpy(out, valuep, basetype[type].len);
- return 0;
-}
-
-int nftnl_strtoi(const char *string, int base, void *out, enum nftnl_type type)
-{
- int ret;
- int64_t sval = 0;
- uint64_t uval = -1;
- char *endptr;
-
- switch (type) {
- case NFTNL_TYPE_U8:
- case NFTNL_TYPE_U16:
- case NFTNL_TYPE_U32:
- case NFTNL_TYPE_U64:
- uval = strtoll(string, &endptr, base);
- ret = nftnl_get_value(type, &uval, out);
- break;
- case NFTNL_TYPE_S8:
- case NFTNL_TYPE_S16:
- case NFTNL_TYPE_S32:
- case NFTNL_TYPE_S64:
- sval = strtoull(string, &endptr, base);
- ret = nftnl_get_value(type, &sval, out);
- break;
- default:
- errno = EINVAL;
- return -1;
- }
-
- if (*endptr) {
- errno = EINVAL;
- return -1;
- }
-
- return ret;
-}
-
const char *nftnl_verdict2str(uint32_t verdict)
{
switch (verdict) {
@@ -209,28 +69,6 @@ const char *nftnl_verdict2str(uint32_t verdict)
}
}
-int nftnl_str2verdict(const char *verdict, int *verdict_num)
-{
- if (strcmp(verdict, "accept") == 0) {
- *verdict_num = NF_ACCEPT;
- return 0;
- } else if (strcmp(verdict, "drop") == 0) {
- *verdict_num = NF_DROP;
- return 0;
- } else if (strcmp(verdict, "return") == 0) {
- *verdict_num = NFT_RETURN;
- return 0;
- } else if (strcmp(verdict, "jump") == 0) {
- *verdict_num = NFT_JUMP;
- return 0;
- } else if (strcmp(verdict, "goto") == 0) {
- *verdict_num = NFT_GOTO;
- return 0;
- }
-
- return -1;
-}
-
enum nftnl_cmd_type nftnl_flag2cmd(uint32_t flags)
{
if (flags & NFTNL_OF_EVENT_NEW)
@@ -241,38 +79,6 @@ enum nftnl_cmd_type nftnl_flag2cmd(uint32_t flags)
return NFTNL_CMD_UNSPEC;
}
-static const char *cmd2tag[NFTNL_CMD_MAX] = {
- [NFTNL_CMD_ADD] = "add",
- [NFTNL_CMD_INSERT] = "insert",
- [NFTNL_CMD_DELETE] = "delete",
- [NFTNL_CMD_REPLACE] = "replace",
- [NFTNL_CMD_FLUSH] = "flush",
-};
-
-const char *nftnl_cmd2tag(enum nftnl_cmd_type cmd)
-{
- if (cmd >= NFTNL_CMD_MAX)
- return "unknown";
-
- return cmd2tag[cmd];
-}
-
-uint32_t nftnl_str2cmd(const char *cmd)
-{
- if (strcmp(cmd, "add") == 0)
- return NFTNL_CMD_ADD;
- else if (strcmp(cmd, "insert") == 0)
- return NFTNL_CMD_INSERT;
- else if (strcmp(cmd, "delete") == 0)
- return NFTNL_CMD_DELETE;
- else if (strcmp(cmd, "replace") == 0)
- return NFTNL_CMD_REPLACE;
- else if (strcmp(cmd, "flush") == 0)
- return NFTNL_CMD_FLUSH;
-
- return NFTNL_CMD_UNSPEC;
-}
-
int nftnl_fprintf(FILE *fp, const void *obj, uint32_t cmd, uint32_t type,
uint32_t flags,
int (*snprintf_cb)(char *buf, size_t bufsiz, const void *obj,
@@ -330,3 +136,17 @@ void __noreturn __abi_breakage(const char *file, int line, const char *reason)
"%s:%d reason: %s\n", file, line, reason);
exit(EXIT_FAILURE);
}
+
+int nftnl_set_str_attr(const char **dptr, uint32_t *flags,
+ uint16_t attr, const void *data, uint32_t data_len)
+{
+ if (*flags & (1 << attr))
+ xfree(*dptr);
+
+ *dptr = strndup(data, data_len);
+ if (!*dptr)
+ return -1;
+
+ *flags |= (1 << attr);
+ return 0;
+}