datatype: Replace getnameinfo() by internal lookup table
PATCH v4 1/1 datatype: Replace getnameinfo() by internal lookup table
To avoid exceeding the inputs number limit of the flex scanner used, when calling getnameinfo() in inet_service_type_print().
The new symbol_table was associated with inet_service_type, to enable listing all pre-defined services using nft command line tool.
The listed services are all well-known and registered ports of my local /etc/services file, from Ubuntu 16.04. Service numbers are converted to respect network byte order.
---
v2: Used symbol_table to list the services and put them in another file. Also used network byte order on service values to replace nft_service_lookup with symbolic_constant_print.
v3: No change.
v4: Changed serv_tbl to inet_service_tbl and fixed indentation.
include/datatype.h | 2 + src/Makefile.am | 1 + src/datatype.c | 15 +-- src/services.c | 343 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 348 insertions(+), 13 deletions(-) create mode 100644 src/services.c
include/datatype.h +2 -0
@@ -185,6 +185,8 @@ struct symbol_table {struct symbolic_constant symbols[]; }; +extern const struct symbol_table inet_service_tbl; +extern struct error_record *symbolic_constant_parse (const struct expr *sym,const struct symbol_table *tbl,struct expr **res);
src/Makefile.am +1 -0
@@ -52,6 +52,7 @@ nft_SOURCES = main.c \ erec.c \ mnl.c \ iface.c \ + services.c \ scanner.l \ parser_bison.y
src/datatype.c +2 -13
@@ -559,19 +559,7 @@ const struct datatype inet_protocol_type = {static void inet_service_type_print (const struct expr *expr) { -struct sockaddr_in sin = { .sin_family =AF_INET }; -char buf[NI_MAXSERV ]; -int err; - - sin.sin_port =mpz_get_be16 (expr->value); - err =getnameinfo ((struct sockaddr *)&sin,sizeof (sin),NULL ,0 , - buf,sizeof (buf), - numeric_output <NUMERIC_PORT ?0 :NI_NUMERICSERV ); -if (err !=0 ) { -getnameinfo ((struct sockaddr *)&sin,sizeof (sin),NULL , -0 , buf,sizeof (buf),NI_NUMERICSERV ); - } -printf ("%s" , buf); +symbolic_constant_print (&inet_service_tbl, expr, false); } static struct error_record *inet_service_type_parse(const struct expr *sym,
@@ -615,6 +603,7 @@ const struct datatype inet_service_type = { .basetype = &integer_type, .print = inet_service_type_print, .parse = inet_service_type_parse, + .sym_tbl = &inet_service_tbl, };#define RT_SYM_TAB_INITIAL_SIZE 16
src/services.c new file +343 -0
343 lines not on this page · raw message
Signature · 1 line
2.7.4
Quoted 9 lines · Elise Lennion
To avoid exceeding the inputs number limit of the flex scanner used, when calling
getnameinfo()ininet_service_type_print().The new
symbol_tablewas associated withinet_service_type, to enable listing all pre-defined services using nft command line tool.The listed services are all well-known and registered ports of my local
/etc/servicesfile, from Ubuntu 16.04. Service numbers are converted to respect network byte order.
Applied, thanks Elise.
BTW, we have to fix "nft describe", look:
# nft describe tcp dport payload expression, datatype inet_service (internet network service) (basetype integer), 16 bits
pre-defined symbolic constants:
tcpmux 0x0100
echo 0x0700
...The user relies on nft describe to know what datatype and possible values are possible for a given selector. In this case, they are expressed in network byte order.
The problems seems to be in expr_describe(), the expression already provides the byteorder, so I guess symbol_table_print() needs to get this byteorder as parameter to swap bytes when required.
This is a fix, so I would appreciate if you focus on this, thanks!