From 4fee12b4b0a837b4d34d21be99cda8185563f784 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 31 Mar 2009 04:14:26 +0200 Subject: datatype: maintain table of all datatypes and add registration/lookup function 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 --- include/datatype.h | 10 +++++++- src/ct.c | 16 +++++++++--- src/datatype.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++-------- src/evaluate.c | 8 +++--- src/expression.c | 5 ++-- src/exthdr.c | 8 +++++- src/meta.c | 29 ++++++++++++++++----- src/payload.c | 20 ++++++++++++--- 8 files changed, 139 insertions(+), 32 deletions(-) diff --git a/include/datatype.h b/include/datatype.h index c3415223..9131d72a 100644 --- a/include/datatype.h +++ b/include/datatype.h @@ -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); diff --git a/src/ct.c b/src/ct.c index ea97d6ad..b077a5f9 100644 --- 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); +} diff --git a/src/datatype.c b/src/datatype.c index 8e17c218..256bcbe4 100644 --- a/src/datatype.c +++ b/src/datatype.c @@ -22,6 +22,49 @@ #include #include +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] = ðertype_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, }; diff --git a/src/evaluate.c b/src/evaluate.c index cf3ff7f7..c8625bbc 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -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); } diff --git a/src/expression.c b/src/expression.c index dba5331d..ba4bda17 100644 --- a/src/expression.c +++ b/src/expression.c @@ -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(")"); diff --git a/src/exthdr.c b/src/exthdr.c index 718979a5..ee02cd53 100644 --- a/src/exthdr.c +++ b/src/exthdr.c @@ -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); +} diff --git a/src/meta.c b/src/meta.c index 5998d09c..a8f728af 100644 --- a/src/meta.c +++ b/src/meta.c @@ -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); +} diff --git a/src/payload.c b/src/payload.c index f76586e3..feb6c551 100644 --- a/src/payload.c +++ b/src/payload.c @@ -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 = ðertype_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(ðertype_type); +} -- cgit v1.2.3