diff options
author | Florian Westphal <fw@strlen.de> | 2016-08-17 18:19:26 +0200 |
---|---|---|
committer | Florian Westphal <fw@strlen.de> | 2016-08-22 18:36:43 +0200 |
commit | 0b4bdb894f1225f1045fd9d12f6d975f27e6c368 (patch) | |
tree | fe9e7c023443054f00a8e06f6cb2e31d977d021f /src | |
parent | 81595230a20ebb500763a68dd1969a2a6db5a9de (diff) |
ct: allow numeric conntrack labels
When dumping labels in rule list we try to print a symbolic name.
If we don't find one, we print the bit number instead.
This changes nft to also allow use of the number instead of a name
when adding ct label rules so that such dumps can also be restored
again.
This is similar to other cases, e.g. skuid root vs skuid 0 which
are both valid.
Signed-off-by: Florian Westphal <fw@strlen.de>
Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/ct.c | 30 |
1 files changed, 22 insertions, 8 deletions
@@ -13,13 +13,14 @@ #include <stddef.h> #include <stdlib.h> #include <stdio.h> -#include <stdint.h> +#include <inttypes.h> #include <string.h> #include <linux/netfilter/nf_tables.h> #include <linux/netfilter/nf_conntrack_common.h> #include <linux/netfilter/nf_conntrack_tuple_common.h> +#include <errno.h> #include <erec.h> #include <expression.h> #include <datatype.h> @@ -121,6 +122,7 @@ static struct error_record *ct_label_type_parse(const struct expr *sym, const struct symbolic_constant *s; const struct datatype *dtype; uint8_t data[CT_LABEL_BIT_SIZE]; + uint64_t bit; mpz_t value; for (s = ct_label_tbl->symbols; s->identifier != NULL; s++) { @@ -129,16 +131,28 @@ static struct error_record *ct_label_type_parse(const struct expr *sym, } dtype = sym->dtype; - if (s->identifier == NULL) - return error(&sym->location, "%s: could not parse %s \"%s\"", - CONNLABEL_CONF, dtype->desc, sym->identifier); + if (s->identifier == NULL) { + char *ptr; + + errno = 0; + bit = strtoull(sym->identifier, &ptr, 0); + if (*ptr) + return error(&sym->location, "%s: could not parse %s \"%s\"", + CONNLABEL_CONF, dtype->desc, sym->identifier); + if (errno) + return error(&sym->location, "%s: could not parse %s \"%s\": %s", + CONNLABEL_CONF, dtype->desc, sym->identifier, strerror(errno)); + + } else { + bit = s->value; + } - if (s->value >= CT_LABEL_BIT_SIZE) - return error(&sym->location, "%s: out of range (%u max)", - s->identifier, s->value, CT_LABEL_BIT_SIZE); + if (bit >= CT_LABEL_BIT_SIZE) + return error(&sym->location, "%s: bit %" PRIu64 " out of range (%u max)", + sym->identifier, bit, CT_LABEL_BIT_SIZE); mpz_init2(value, dtype->size); - mpz_setbit(value, s->value); + mpz_setbit(value, bit); mpz_export_data(data, value, BYTEORDER_HOST_ENDIAN, sizeof(data)); *res = constant_expr_alloc(&sym->location, dtype, |