diff options
Diffstat (limited to 'src')
55 files changed, 393 insertions, 313 deletions
diff --git a/src/chain.c b/src/chain.c index dcfcd04..0b68939 100644 --- a/src/chain.c +++ b/src/chain.c @@ -185,6 +185,9 @@ void nftnl_chain_unset(struct nftnl_chain *c, uint16_t attr) xfree(c->dev_array[i]); xfree(c->dev_array); break; + case NFTNL_CHAIN_USERDATA: + xfree(c->user.data); + break; default: return; } @@ -196,6 +199,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 +220,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 +250,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) @@ -74,6 +74,13 @@ int nftnl_expr_set(struct nftnl_expr *expr, uint16_t type, 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 dab1690..e99131a 100644 --- a/src/expr/bitwise.c +++ b/src/expr/bitwise.c @@ -39,16 +39,16 @@ 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: return nftnl_data_cpy(&bitwise->mask, data, data_len); diff --git a/src/expr/byteorder.c b/src/expr/byteorder.c index d4e85a8..383e80d 100644 --- a/src/expr/byteorder.c +++ b/src/expr/byteorder.c @@ -37,19 +37,19 @@ 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; } return 0; diff --git a/src/expr/cmp.c b/src/expr/cmp.c index 2937d7e..d1f0f64 100644 --- a/src/expr/cmp.c +++ b/src/expr/cmp.c @@ -36,10 +36,10 @@ 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: return nftnl_data_cpy(&cmp->data, data, data_len); diff --git a/src/expr/connlimit.c b/src/expr/connlimit.c index 1c78c71..fcac8bf 100644 --- a/src/expr/connlimit.c +++ b/src/expr/connlimit.c @@ -33,10 +33,10 @@ 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; } return 0; diff --git a/src/expr/counter.c b/src/expr/counter.c index 2c6f2a7..cef9119 100644 --- a/src/expr/counter.c +++ b/src/expr/counter.c @@ -35,10 +35,10 @@ 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; } return 0; diff --git a/src/expr/ct.c b/src/expr/ct.c index f7dd40d..bea0522 100644 --- a/src/expr/ct.c +++ b/src/expr/ct.c @@ -39,16 +39,16 @@ 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; } return 0; diff --git a/src/expr/dup.c b/src/expr/dup.c index 6a5e4ca..28d686b 100644 --- a/src/expr/dup.c +++ b/src/expr/dup.c @@ -32,10 +32,10 @@ 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; } return 0; diff --git a/src/expr/dynset.c b/src/expr/dynset.c index c1f79b5..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; diff --git a/src/expr/exthdr.c b/src/expr/exthdr.c index 93b7521..453902c 100644 --- a/src/expr/exthdr.c +++ b/src/expr/exthdr.c @@ -46,25 +46,25 @@ 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; } return 0; diff --git a/src/expr/fib.c b/src/expr/fib.c index 5f7bef4..20bc125 100644 --- a/src/expr/fib.c +++ b/src/expr/fib.c @@ -35,13 +35,13 @@ 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; } return 0; diff --git a/src/expr/fwd.c b/src/expr/fwd.c index 566d6f4..04cb089 100644 --- a/src/expr/fwd.c +++ b/src/expr/fwd.c @@ -33,13 +33,13 @@ 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; } return 0; diff --git a/src/expr/hash.c b/src/expr/hash.c index 4cd9006..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; diff --git a/src/expr/immediate.c b/src/expr/immediate.c index b77ccea..ab1276a 100644 --- a/src/expr/immediate.c +++ b/src/expr/immediate.c @@ -33,12 +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: 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)) @@ -49,7 +49,7 @@ 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; } return 0; diff --git a/src/expr/inner.c b/src/expr/inner.c index 45ef4fb..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) diff --git a/src/expr/last.c b/src/expr/last.c index 074f463..8e5b88e 100644 --- a/src/expr/last.c +++ b/src/expr/last.c @@ -32,10 +32,10 @@ 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; } return 0; diff --git a/src/expr/limit.c b/src/expr/limit.c index 935d449..5b82108 100644 --- a/src/expr/limit.c +++ b/src/expr/limit.c @@ -38,19 +38,19 @@ 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; } return 0; @@ -158,16 +158,28 @@ nftnl_expr_limit_parse(struct nftnl_expr *e, struct nlattr *attr) return 0; } -static const char *get_unit(uint64_t u) +static const char *get_time(uint64_t seconds, uint64_t *val) { - switch (u) { - case 1: return "second"; - case 60: return "minute"; - case 60 * 60: return "hour"; - case 60 * 60 * 24: return "day"; - case 60 * 60 * 24 * 7: return "week"; + static const struct { + unsigned int size; + const char *name; + } units[] = { + { 0, "second" }, + { 60, "minute" }, + { 60, "hour" }, + { 24, "day" }, + { 7, "week" } + }; + int i; + + for (i = 1; i < array_size(units); i++) { + if (seconds % units[i].size) + break; + seconds /= units[i].size; } - return "error"; + if (val) + *val = seconds; + return units[i - 1].name; } static const char *limit_to_type(enum nft_limit_type type) @@ -186,10 +198,26 @@ nftnl_expr_limit_snprintf(char *buf, size_t len, uint32_t flags, const struct nftnl_expr *e) { struct nftnl_expr_limit *limit = nftnl_expr_data(e); + unsigned int offset = 0; + const char *time_unit; + uint64_t time_val; + int ret; + + ret = snprintf(buf, len, "rate %"PRIu64"/", limit->rate); + SNPRINTF_BUFFER_SIZE(ret, len, offset); + + time_unit = get_time(limit->unit, &time_val); + if (time_val > 1) { + ret = snprintf(buf + offset, len, "%"PRIu64" ", time_val); + SNPRINTF_BUFFER_SIZE(ret, len, offset); + } + + ret = snprintf(buf + offset, len, "%s burst %u type %s flags 0x%x ", + time_unit, limit->burst, limit_to_type(limit->type), + limit->flags); + SNPRINTF_BUFFER_SIZE(ret, len, offset); - return snprintf(buf, len, "rate %"PRIu64"/%s burst %u type %s flags 0x%x ", - limit->rate, get_unit(limit->unit), limit->burst, - limit_to_type(limit->type), limit->flags); + return offset; } static struct attr_policy limit_attr_policy[__NFTNL_EXPR_LIMIT_MAX] = { diff --git a/src/expr/log.c b/src/expr/log.c index d6d6910..18ec2b6 100644 --- a/src/expr/log.c +++ b/src/expr/log.c @@ -46,19 +46,19 @@ 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; } return 0; diff --git a/src/expr/lookup.c b/src/expr/lookup.c index be04528..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,10 +48,10 @@ 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; } return 0; diff --git a/src/expr/masq.c b/src/expr/masq.c index 4be5a9c..e0565db 100644 --- a/src/expr/masq.c +++ b/src/expr/masq.c @@ -34,13 +34,13 @@ 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; } return 0; diff --git a/src/expr/match.c b/src/expr/match.c index 68288dc..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)) diff --git a/src/expr/meta.c b/src/expr/meta.c index cd49c34..136a450 100644 --- a/src/expr/meta.c +++ b/src/expr/meta.c @@ -39,13 +39,13 @@ 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; } return 0; diff --git a/src/expr/nat.c b/src/expr/nat.c index f3f8644..1235ba4 100644 --- a/src/expr/nat.c +++ b/src/expr/nat.c @@ -42,25 +42,25 @@ 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; } diff --git a/src/expr/numgen.c b/src/expr/numgen.c index c5e8772..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; diff --git a/src/expr/objref.c b/src/expr/objref.c index 59e1ddd..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,7 +55,7 @@ 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; } return 0; diff --git a/src/expr/osf.c b/src/expr/osf.c index 1e4ceb0..293a814 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; @@ -89,12 +89,12 @@ nftnl_expr_osf_build(struct nlmsghdr *nlh, const struct nftnl_expr *e) struct nftnl_expr_osf *osf = nftnl_expr_data(e); if (e->flags & (1 << NFTNL_EXPR_OSF_DREG)) - mnl_attr_put_u32(nlh, NFTNL_EXPR_OSF_DREG, htonl(osf->dreg)); + mnl_attr_put_u32(nlh, NFTA_OSF_DREG, htonl(osf->dreg)); if (e->flags & (1 << NFTNL_EXPR_OSF_TTL)) - mnl_attr_put_u8(nlh, NFTNL_EXPR_OSF_TTL, osf->ttl); + mnl_attr_put_u8(nlh, NFTA_OSF_TTL, osf->ttl); if (e->flags & (1 << NFTNL_EXPR_OSF_FLAGS)) if (osf->flags) - mnl_attr_put_u32(nlh, NFTNL_EXPR_OSF_FLAGS, htonl(osf->flags)); + mnl_attr_put_u32(nlh, NFTA_OSF_FLAGS, htonl(osf->flags)); } static int diff --git a/src/expr/payload.c b/src/expr/payload.c index 76d38f7..35cd10c 100644 --- a/src/expr/payload.c +++ b/src/expr/payload.c @@ -43,28 +43,28 @@ 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; } return 0; diff --git a/src/expr/queue.c b/src/expr/queue.c index 54792ef..09220c4 100644 --- a/src/expr/queue.c +++ b/src/expr/queue.c @@ -34,16 +34,16 @@ 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; } return 0; diff --git a/src/expr/quota.c b/src/expr/quota.c index 60631fe..ddf232f 100644 --- a/src/expr/quota.c +++ b/src/expr/quota.c @@ -33,13 +33,13 @@ static int nftnl_expr_quota_set(struct nftnl_expr *e, uint16_t type, switch (type) { case NFTNL_EXPR_QUOTA_BYTES: - memcpy("a->bytes, data, sizeof(quota->bytes)); + memcpy("a->bytes, data, data_len); break; case NFTNL_EXPR_QUOTA_CONSUMED: - memcpy("a->consumed, data, sizeof(quota->consumed)); + memcpy("a->consumed, data, data_len); break; case NFTNL_EXPR_QUOTA_FLAGS: - memcpy("a->flags, data, sizeof(quota->flags)); + memcpy("a->flags, data, data_len); break; } return 0; diff --git a/src/expr/range.c b/src/expr/range.c index 6310b79..96bb140 100644 --- a/src/expr/range.c +++ b/src/expr/range.c @@ -34,10 +34,10 @@ 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: return nftnl_data_cpy(&range->data_from, data, data_len); diff --git a/src/expr/redir.c b/src/expr/redir.c index 69095bd..9971306 100644 --- a/src/expr/redir.c +++ b/src/expr/redir.c @@ -34,13 +34,13 @@ 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; } return 0; diff --git a/src/expr/reject.c b/src/expr/reject.c index f97011a..9090db3 100644 --- a/src/expr/reject.c +++ b/src/expr/reject.c @@ -33,10 +33,10 @@ 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; } return 0; diff --git a/src/expr/rt.c b/src/expr/rt.c index 0ab2556..ff4fd03 100644 --- a/src/expr/rt.c +++ b/src/expr/rt.c @@ -32,10 +32,10 @@ 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; } return 0; diff --git a/src/expr/socket.c b/src/expr/socket.c index d0d8e23..7a25cdf 100644 --- a/src/expr/socket.c +++ b/src/expr/socket.c @@ -33,13 +33,13 @@ 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; } return 0; diff --git a/src/expr/synproxy.c b/src/expr/synproxy.c index 898d292..b5a1fef 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; @@ -90,13 +90,13 @@ nftnl_expr_synproxy_build(struct nlmsghdr *nlh, const struct nftnl_expr *e) struct nftnl_expr_synproxy *synproxy = nftnl_expr_data(e); if (e->flags & (1 << NFTNL_EXPR_SYNPROXY_MSS)) - mnl_attr_put_u16(nlh, NFTNL_EXPR_SYNPROXY_MSS, + mnl_attr_put_u16(nlh, NFTA_SYNPROXY_MSS, htons(synproxy->mss)); if (e->flags & (1 << NFTNL_EXPR_SYNPROXY_WSCALE)) - mnl_attr_put_u8(nlh, NFTNL_EXPR_SYNPROXY_WSCALE, + mnl_attr_put_u8(nlh, NFTA_SYNPROXY_WSCALE, synproxy->wscale); if (e->flags & (1 << NFTNL_EXPR_SYNPROXY_FLAGS)) - mnl_attr_put_u32(nlh, NFTNL_EXPR_SYNPROXY_FLAGS, + mnl_attr_put_u32(nlh, NFTA_SYNPROXY_FLAGS, htonl(synproxy->flags)); } diff --git a/src/expr/target.c b/src/expr/target.c index 9bfd25b..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)) diff --git a/src/expr/tproxy.c b/src/expr/tproxy.c index 4948392..9391ce8 100644 --- a/src/expr/tproxy.c +++ b/src/expr/tproxy.c @@ -34,13 +34,13 @@ 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; } diff --git a/src/expr/tunnel.c b/src/expr/tunnel.c index 8089d0b..861e56d 100644 --- a/src/expr/tunnel.c +++ b/src/expr/tunnel.c @@ -31,10 +31,10 @@ 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; } return 0; diff --git a/src/expr/xfrm.c b/src/expr/xfrm.c index dc867a2..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; 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/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 fedf9e3..b9b688e 100644 --- a/src/obj/ct_timeout.c +++ b/src/obj/ct_timeout.c @@ -150,10 +150,10 @@ 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) @@ -162,8 +162,6 @@ static int nftnl_obj_ct_timeout_set(struct nftnl_obj *e, uint16_t type, memcpy(timeout->timeout, data, sizeof(uint32_t) * NFTNL_CTTIMEOUT_ARRAY_MAX); break; - default: - return -1; } return 0; } @@ -310,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("a->bytes, data, sizeof(quota->bytes)); + memcpy("a->bytes, data, data_len); break; case NFTNL_OBJ_QUOTA_CONSUMED: - memcpy("a->consumed, data, sizeof(quota->consumed)); + memcpy("a->consumed, data, data_len); break; case NFTNL_OBJ_QUOTA_FLAGS: - memcpy("a->flags, data, sizeof(quota->flags)); + memcpy("a->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 0814be7..19cb7d0 100644 --- a/src/object.c +++ b/src/object.c @@ -98,31 +98,31 @@ void nftnl_obj_unset(struct nftnl_obj *obj, uint16_t 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)); @@ -139,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; @@ -158,33 +168,33 @@ 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); @@ -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; @@ -128,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), @@ -145,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; diff --git a/src/table.c b/src/table.c index 59e7053..1a5f6f3 100644 --- a/src/table.c +++ b/src/table.c @@ -74,6 +74,9 @@ void nftnl_table_unset(struct nftnl_table *t, uint16_t attr) case NFTNL_TABLE_NAME: xfree(t->name); break; + case NFTNL_TABLE_USERDATA: + xfree(t->user.data); + break; case NFTNL_TABLE_FLAGS: case NFTNL_TABLE_HANDLE: case NFTNL_TABLE_FAMILY: @@ -88,6 +91,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 +104,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/utils.c b/src/utils.c index ffbad89..2f1ffd6 100644 --- a/src/utils.c +++ b/src/utils.c @@ -136,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; +} |