]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
datatype: maintain table of all datatypes and add registration/lookup function
authorPatrick McHardy <kaber@trash.net>
Tue, 31 Mar 2009 02:14:26 +0000 (04:14 +0200)
committerPatrick McHardy <kaber@trash.net>
Tue, 31 Mar 2009 02:14:26 +0000 (04:14 +0200)
Add a table containing all available datatypes and registration/lookup functions.
This will be used to associate a stand-alone set in the kernel with the correct
type without parsing the entire ruleset.

Additionally it would now be possible to remove the global declarations for the
core types. Not done yet though.

Signed-off-by: Patrick McHardy <kaber@trash.net>
include/datatype.h
src/ct.c
src/datatype.c
src/evaluate.c
src/expression.c
src/exthdr.c
src/meta.c
src/payload.c

index c341522303432a49e59ff359fc738f929a821fe6..9131d72a833eaf6121602acb3509de7d9bdf1431 100644 (file)
@@ -58,7 +58,9 @@ enum datatypes {
        TYPE_CT_STATE,
        TYPE_CT_DIR,
        TYPE_CT_STATUS,
+       __TYPE_MAX
 };
+#define TYPE_MAX               (__TYPE_MAX - 1)
 
 /**
  * enum byteorder
@@ -79,7 +81,8 @@ struct expr;
  * struct datatype
  *
  * @type:      numeric identifier
- * @name:      type name for diagnostics
+ * @name:      type name
+ * @desc:      type description
  * @basetype:  basetype for subtypes, determines type compatibilty
  * @basefmt:   format string for basetype
  * @print:     function to print a constant of this type
@@ -89,6 +92,7 @@ struct expr;
 struct datatype {
        enum datatypes                  type;
        const char                      *name;
+       const char                      *desc;
        const struct datatype           *basetype;
        const char                      *basefmt;
        void                            (*print)(const struct expr *expr);
@@ -97,6 +101,10 @@ struct datatype {
        const struct symbol_table       *sym_tbl;
 };
 
+extern void datatype_register(const struct datatype *dtype);
+extern const struct datatype *datatype_lookup(enum datatypes type);
+extern const struct datatype *datatype_lookup_byname(const char *name);
+
 extern struct error_record *symbol_parse(const struct expr *sym,
                                         struct expr **res);
 extern void datatype_print(const struct expr *expr);
index ea97d6ad28c6beec2398f51e6c2289ef60fca22f..b077a5f9d0745c59a704d2fc357313888c51c3fb 100644 (file)
--- a/src/ct.c
+++ b/src/ct.c
@@ -40,7 +40,8 @@ static const struct symbol_table ct_state_tbl = {
 
 static const struct datatype ct_state_type = {
        .type           = TYPE_CT_STATE,
-       .name           = "conntrack state",
+       .name           = "ct_state",
+       .desc           = "conntrack state",
        .basetype       = &bitmask_type,
        .sym_tbl        = &ct_state_tbl,
 };
@@ -57,7 +58,8 @@ static const struct symbol_table ct_dir_tbl = {
 
 static const struct datatype ct_dir_type = {
        .type           = TYPE_CT_DIR,
-       .name           = "conntrack direction",
+       .name           = "ct_dir",
+       .desc           = "conntrack direction",
        .basetype       = &bitmask_type,
        .sym_tbl        = &ct_dir_tbl,
 };
@@ -82,7 +84,8 @@ static const struct symbol_table ct_status_tbl = {
 
 static const struct datatype ct_status_type = {
        .type           = TYPE_CT_STATUS,
-       .name           = "conntrack status",
+       .name           = "ct_status",
+       .desc           = "conntrack status",
        .basetype       = &bitmask_type,
        .sym_tbl        = &ct_status_tbl,
 };
@@ -153,3 +156,10 @@ struct expr *ct_expr_alloc(const struct location *loc, enum nft_ct_keys key)
        expr->ct.key = key;
        return expr;
 }
+
+static void __init ct_init(void)
+{
+       datatype_register(&ct_state_type);
+       datatype_register(&ct_dir_type);
+       datatype_register(&ct_status_type);
+}
index 8e17c2184bcf49eb2e957e47a5ec8864dea9d303..256bcbe4e2acf7f2cf324f2af90f7af2eb8b3002 100644 (file)
 #include <gmputil.h>
 #include <erec.h>
 
+static const struct datatype *datatypes[TYPE_MAX + 1] = {
+       [TYPE_VERDICT]          = &verdict_type,
+       [TYPE_BITMASK]          = &bitmask_type,
+       [TYPE_INTEGER]          = &integer_type,
+       [TYPE_STRING]           = &string_type,
+       [TYPE_LLADDR]           = &lladdr_type,
+       [TYPE_IPADDR]           = &ipaddr_type,
+       [TYPE_IP6ADDR]          = &ip6addr_type,
+       [TYPE_ETHERTYPE]        = &ethertype_type,
+       [TYPE_INET_PROTOCOL]    = &inet_protocol_type,
+       [TYPE_INET_SERVICE]     = &inet_service_type,
+       [TYPE_TIME]             = &time_type,
+       [TYPE_MARK]             = &mark_type,
+       [TYPE_ARPHRD]           = &arphrd_type,
+};
+
+void datatype_register(const struct datatype *dtype)
+{
+       datatypes[dtype->type] = dtype;
+}
+
+const struct datatype *datatype_lookup(enum datatypes type)
+{
+       if (type > TYPE_MAX)
+               return NULL;
+       return datatypes[type];
+}
+
+const struct datatype *datatype_lookup_byname(const char *name)
+{
+       const struct datatype *dtype;
+       enum datatypes type;
+
+       for (type = TYPE_INVALID; type <= TYPE_MAX; type++) {
+               dtype = datatypes[type];
+               if (dtype == NULL)
+                       continue;
+               if (!strcmp(dtype->name, name))
+                       return dtype;
+       }
+       return NULL;
+}
+
 void datatype_print(const struct expr *expr)
 {
        const struct datatype *dtype = expr->dtype;
@@ -49,7 +92,7 @@ struct error_record *symbol_parse(const struct expr *sym,
 
        return error(&sym->location,
                     "Can't parse symbolic %s expressions",
-                    sym->sym_type->name);
+                    sym->sym_type->desc);
 }
 
 struct error_record *symbolic_constant_parse(const struct expr *sym,
@@ -65,7 +108,7 @@ struct error_record *symbolic_constant_parse(const struct expr *sym,
 
        if (s->identifier == NULL)
                return error(&sym->location, "Could not parse %s",
-                            sym->sym_type->name);
+                            sym->sym_type->desc);
 
        *res = constant_expr_alloc(&sym->location, sym->sym_type,
                                   tbl->byteorder, tbl->size, &s->value);
@@ -106,6 +149,7 @@ static void invalid_type_print(const struct expr *expr)
 const struct datatype invalid_type = {
        .type           = TYPE_INVALID,
        .name           = "invalid",
+       .desc           = "invalid",
        .print          = invalid_type_print,
 };
 
@@ -144,12 +188,14 @@ static void verdict_type_print(const struct expr *expr)
 const struct datatype verdict_type = {
        .type           = TYPE_VERDICT,
        .name           = "verdict",
+       .desc           = "netfilter verdict",
        .print          = verdict_type_print,
 };
 
 const struct datatype bitmask_type = {
        .type           = TYPE_BITMASK,
        .name           = "bitmask",
+       .desc           = "bitmask",
        .basetype       = &integer_type,
 };
 
@@ -173,7 +219,7 @@ static struct error_record *integer_type_parse(const struct expr *sym,
                if (sym->sym_type != &integer_type)
                        return NULL;
                return error(&sym->location, "Could not parse %s",
-                            sym->sym_type->name);
+                            sym->sym_type->desc);
        }
 
        *res = constant_expr_alloc(&sym->location, sym->sym_type,
@@ -186,6 +232,7 @@ static struct error_record *integer_type_parse(const struct expr *sym,
 const struct datatype integer_type = {
        .type           = TYPE_INTEGER,
        .name           = "integer",
+       .desc           = "integer",
        .print          = integer_type_print,
        .parse          = integer_type_parse,
 };
@@ -212,6 +259,7 @@ static struct error_record *string_type_parse(const struct expr *sym,
 const struct datatype string_type = {
        .type           = TYPE_STRING,
        .name           = "string",
+       .desc           = "string",
        .print          = string_type_print,
        .parse          = string_type_parse,
 };
@@ -256,7 +304,8 @@ static struct error_record *lladdr_type_parse(const struct expr *sym,
 
 const struct datatype lladdr_type = {
        .type           = TYPE_LLADDR,
-       .name           = "LL address",
+       .name           = "lladdr",
+       .desc           = "link layer address",
        .basetype       = &integer_type,
        .print          = lladdr_type_print,
        .parse          = lladdr_type_parse,
@@ -302,7 +351,8 @@ static struct error_record *ipaddr_type_parse(const struct expr *sym,
 
 const struct datatype ipaddr_type = {
        .type           = TYPE_IPADDR,
-       .name           = "IPv4 address",
+       .name           = "ipv4_address",
+       .desc           = "IPv4 address",
        .basetype       = &integer_type,
        .print          = ipaddr_type_print,
        .parse          = ipaddr_type_parse,
@@ -350,7 +400,8 @@ static struct error_record *ip6addr_type_parse(const struct expr *sym,
 
 const struct datatype ip6addr_type = {
        .type           = TYPE_IP6ADDR,
-       .name           = "IPv6 address",
+       .name           = "ipv6_address",
+       .desc           = "IPv6 address",
        .basetype       = &integer_type,
        .print          = ip6addr_type_print,
        .parse          = ip6addr_type_parse,
@@ -387,7 +438,8 @@ static struct error_record *inet_protocol_type_parse(const struct expr *sym,
 
 const struct datatype inet_protocol_type = {
        .type           = TYPE_INET_PROTOCOL,
-       .name           = "Internet protocol",
+       .name           = "inet_protocol",
+       .desc           = "Internet protocol",
        .basetype       = &integer_type,
        .print          = inet_protocol_type_print,
        .parse          = inet_protocol_type_parse,
@@ -427,7 +479,8 @@ static struct error_record *inet_service_type_parse(const struct expr *sym,
 
 const struct datatype inet_service_type = {
        .type           = TYPE_INET_SERVICE,
-       .name           = "internet network service",
+       .name           = "inet_service",
+       .desc           = "internet network service",
        .basetype       = &integer_type,
        .print          = inet_service_type_print,
        .parse          = inet_service_type_parse,
@@ -519,7 +572,8 @@ static struct error_record *mark_type_parse(const struct expr *sym,
 
 const struct datatype mark_type = {
        .type           = TYPE_MARK,
-       .name           = "packet mark",
+       .name           = "mark",
+       .desc           = "packet mark",
        .basetype       = &integer_type,
        .basefmt        = "0x%.8Zx",
        .print          = mark_type_print,
@@ -562,7 +616,8 @@ static void time_type_print(const struct expr *expr)
 
 const struct datatype time_type = {
        .type           = TYPE_TIME,
-       .name           = "relative time",
+       .name           = "time",
+       .desc           = "relative time",
        .basetype       = &integer_type,
        .print          = time_type_print,
 };
index cf3ff7f7145da2c197e0c4c8de55eec0a02353c0..c8625bbc9813d67128ac2317ff601a0eaface4f1 100644 (file)
@@ -219,7 +219,7 @@ static int expr_evaluate_prefix(struct eval_ctx *ctx, struct expr **expr)
        if (expr_basetype(base)->type != TYPE_INTEGER)
                return expr_error(ctx, prefix,
                                  "Prefix expression is undefined for "
-                                 "%s types", base->dtype->name);
+                                 "%s types", base->dtype->desc);
 
        if (prefix->prefix_len > base->len)
                return expr_error(ctx, prefix,
@@ -259,7 +259,7 @@ static int expr_evaluate_range_expr(struct eval_ctx *ctx,
        if (expr_basetype(*expr)->type != TYPE_INTEGER)
                return expr_binary_error(ctx, *expr, range,
                                         "Range expression is undefined for "
-                                        "%s types", (*expr)->dtype->name);
+                                        "%s types", (*expr)->dtype->desc);
        if (!expr_is_constant(*expr))
                return expr_binary_error(ctx, *expr, range,
                                         "Range is not constant");
@@ -449,7 +449,7 @@ static int expr_evaluate_binop(struct eval_ctx *ctx, struct expr **expr)
                return expr_binary_error(ctx, left, op,
                                         "Binary operation (%s) is undefined "
                                         "for %s types",
-                                        sym, left->dtype->name);
+                                        sym, left->dtype->desc);
 
        if (expr_is_constant(left) && !expr_is_singleton(left))
                return expr_binary_error(ctx, left, op,
@@ -527,7 +527,7 @@ static int expr_evaluate_list(struct eval_ctx *ctx, struct expr **expr)
                if (i->dtype->basetype->type != TYPE_BITMASK)
                        return expr_error(ctx, i,
                                          "Basetype of type %s is not bitmask",
-                                         i->dtype->name);
+                                         i->dtype->desc);
                mpz_ior(val, val, i->value);
        }
 
index dba5331d4f67e08182419083fdf80d276d38379e..ba4bda172cee501d1877fc4016d304fdc1c20844 100644 (file)
@@ -78,12 +78,13 @@ void expr_describe(const struct expr *expr)
        const struct datatype *dtype = expr->dtype;
        const char *delim = "";
 
-       printf("%s expression, datatype %s", expr->ops->name, dtype->name);
+       printf("%s expression, datatype %s (%s)",
+               expr->ops->name, dtype->name, dtype->desc);
        if (dtype->basetype != NULL) {
                printf(" (basetype ");
                for (dtype = dtype->basetype; dtype != NULL;
                     dtype = dtype->basetype) {
-                       printf("%s%s", delim, dtype->name);
+                       printf("%s%s", delim, dtype->desc);
                        delim = ", ";
                }
                printf(")");
index 718979a5ff05ce6d645e450657e6cb0c8a78d100..ee02cd53cfcce04a33593a2120a165f8c3fdbea0 100644 (file)
@@ -227,7 +227,8 @@ static const struct symbol_table mh_type_tbl = {
 
 static const struct datatype mh_type_type = {
        .type           = TYPE_MH_TYPE,
-       .name           = "Mobility Header Type",
+       .name           = "mh_type",
+       .desc           = "Mobility Header Type",
        .basetype       = &integer_type,
        .sym_tbl        = &mh_type_tbl,
 };
@@ -243,3 +244,8 @@ const struct exthdr_desc exthdr_mh = {
                [MHHDR_CHECKSUM]        = MH_FIELD("checksum", ip6mh_cksum, &integer_type),
        },
 };
+
+static void __init exthdr_init(void)
+{
+       datatype_register(&mh_type_type);
+}
index 5998d09c1a31672cbf772fd93ee7298c22a561c3..a8f728af3c61a10777330e6f08c94304a36f9acf 100644 (file)
@@ -53,7 +53,8 @@ static struct error_record *realm_type_parse(const struct expr *sym,
 
 static const struct datatype realm_type = {
        .type           = TYPE_REALM,
-       .name           = "routing realm",
+       .name           = "realm",
+       .desc           = "routing realm",
        .basetype       = &integer_type,
        .print          = realm_type_print,
        .parse          = realm_type_parse,
@@ -74,7 +75,7 @@ static struct error_record *tchandle_type_parse(const struct expr *sym,
 
        if (rtnl_tc_str2handle(sym->identifier, &handle) < 0)
                return error(&sym->location, "Could not parse %s",
-                            sym->sym_type->name);
+                            sym->sym_type->desc);
 
        *res = constant_expr_alloc(&sym->location, sym->sym_type,
                                   BYTEORDER_HOST_ENDIAN,
@@ -84,7 +85,8 @@ static struct error_record *tchandle_type_parse(const struct expr *sym,
 
 static const struct datatype tchandle_type = {
        .type           = TYPE_TC_HANDLE,
-       .name           = "TC handle",
+       .name           = "tc_handle",
+       .desc           = "TC handle",
        .basetype       = &integer_type,
        .print          = tchandle_type_print,
        .parse          = tchandle_type_parse,
@@ -160,7 +162,8 @@ static void __exit ifindex_table_free(void)
 
 static const struct datatype ifindex_type = {
        .type           = TYPE_IFINDEX,
-       .name           = "interface index",
+       .name           = "ifindex",
+       .desc           = "interface index",
        .basetype       = &integer_type,
        .print          = ifindex_type_print,
        .parse          = ifindex_type_parse,
@@ -184,7 +187,8 @@ static const struct symbol_table arphrd_tbl = {
 
 const struct datatype arphrd_type = {
        .type           = TYPE_ARPHRD,
-       .name           = "hardware type",
+       .name           = "arphrd",
+       .desc           = "hardware type",
        .basetype       = &integer_type,
        .sym_tbl        = &arphrd_tbl,
 };
@@ -221,7 +225,8 @@ static struct error_record *uid_type_parse(const struct expr *sym,
 
 static const struct datatype uid_type = {
        .type           = TYPE_UID,
-       .name           = "user ID",
+       .name           = "uid",
+       .desc           = "user ID",
        .basetype       = &integer_type,
        .print          = uid_type_print,
        .parse          = uid_type_parse,
@@ -259,7 +264,8 @@ static struct error_record *gid_type_parse(const struct expr *sym,
 
 static const struct datatype gid_type = {
        .type           = TYPE_GID,
-       .name           = "group ID",
+       .name           = "gid",
+       .desc           = "group ID",
        .basetype       = &integer_type,
        .print          = gid_type_print,
        .parse          = gid_type_parse,
@@ -351,3 +357,12 @@ struct stmt *meta_stmt_alloc(const struct location *loc, enum nft_meta_keys key,
        stmt->meta.expr = expr;
        return stmt;
 }
+
+static void __init meta_init(void)
+{
+       datatype_register(&ifindex_type);
+       datatype_register(&realm_type);
+       datatype_register(&tchandle_type);
+       datatype_register(&uid_type);
+       datatype_register(&gid_type);
+}
index f76586e3f4c8c8edea298d458c9485d0b57ff9bc..feb6c55140c9f6bc3ef80d43fcec612f382591f6 100644 (file)
@@ -580,7 +580,8 @@ static const struct symbol_table icmp_type_tbl = {
 
 static const struct datatype icmp_type_type = {
        .type           = TYPE_ICMP_TYPE,
-       .name           = "ICMP type",
+       .name           = "icmp_type",
+       .desc           = "ICMP type",
        .basetype       = &integer_type,
        .sym_tbl        = &icmp_type_tbl,
 };
@@ -658,7 +659,8 @@ static const struct symbol_table tcp_flag_tbl = {
 
 static const struct datatype tcp_flag_type = {
        .type           = TYPE_TCP_FLAG,
-       .name           = "TCP flag",
+       .name           = "tcp_flag",
+       .desc           = "TCP flag",
        .basetype       = &bitmask_type,
        .sym_tbl        = &tcp_flag_tbl,
 };
@@ -818,7 +820,8 @@ static const struct symbol_table arpop_tbl = {
 
 static const struct datatype arpop_type = {
        .type           = TYPE_ARPOP,
-       .name           = "ARP operation",
+       .name           = "arp_op",
+       .desc           = "ARP operation",
        .basetype       = &integer_type,
        .sym_tbl        = &arpop_tbl,
 };
@@ -888,7 +891,8 @@ static const struct symbol_table ethertype_tbl = {
 
 const struct datatype ethertype_type = {
        .type           = TYPE_ETHERTYPE,
-       .name           = "Ethernet protocol",
+       .name           = "ethertype",
+       .desc           = "Ethernet protocol",
        .basetype       = &integer_type,
        .sym_tbl        = &ethertype_tbl,
 };
@@ -916,3 +920,11 @@ const struct payload_desc payload_eth = {
                [ETHHDR_TYPE]           = ETHHDR_TYPE("type", ether_type),
        },
 };
+
+static void __init payload_init(void)
+{
+       datatype_register(&icmp_type_type);
+       datatype_register(&tcp_flag_type);
+       datatype_register(&arpop_type);
+       datatype_register(&ethertype_type);
+}