diff options
-rw-r--r-- | include/datatype.h | 10 | ||||
-rw-r--r-- | src/ct.c | 16 | ||||
-rw-r--r-- | src/datatype.c | 75 | ||||
-rw-r--r-- | src/evaluate.c | 8 | ||||
-rw-r--r-- | src/expression.c | 5 | ||||
-rw-r--r-- | src/exthdr.c | 8 | ||||
-rw-r--r-- | src/meta.c | 29 | ||||
-rw-r--r-- | 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); @@ -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 <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] = ð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); +} @@ -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); +} |