diff options
-rw-r--r-- | src/expression.c | 35 | ||||
-rw-r--r-- | tests/py/any/tcpopt.t | 2 | ||||
-rw-r--r-- | tests/py/any/tcpopt.t.json | 11 | ||||
-rw-r--r-- | tests/py/any/tcpopt.t.payload | 10 |
4 files changed, 49 insertions, 9 deletions
diff --git a/src/expression.c b/src/expression.c index 53d4c521..d2fa4650 100644 --- a/src/expression.c +++ b/src/expression.c @@ -1485,6 +1485,32 @@ static void set_ref_expr_destroy(struct expr *expr) set_free(expr->set); } +static void set_ref_expr_set_type(const struct expr *expr, + const struct datatype *dtype, + enum byteorder byteorder) +{ + const struct set *s = expr->set; + + /* normal sets already have a precise datatype that is given in + * the set definition via type foo. + * + * Anon sets do not have this, and need to rely on type info + * generated at rule creation time. + * + * For most cases, the type info is correct. + * In some cases however, the kernel only stores TYPE_INTEGER. + * + * This happens with expressions that only use an integer alias + * type, e.g. the mptcpopt_subtype datatype. + * + * In this case nft will print the elements as numerical values + * because the base type lacks the ->sym_tbl information of the + * subtypes. + */ + if (s->init && set_is_anonymous(s->flags)) + expr_set_type(s->init, dtype, byteorder); +} + static const struct expr_ops set_ref_expr_ops = { .type = EXPR_SET_REF, .name = "set reference", @@ -1492,6 +1518,7 @@ static const struct expr_ops set_ref_expr_ops = { .json = set_ref_expr_json, .clone = set_ref_expr_clone, .destroy = set_ref_expr_destroy, + .set_type = set_ref_expr_set_type, }; struct expr *set_ref_expr_alloc(const struct location *loc, struct set *set) @@ -1556,6 +1583,13 @@ static void set_elem_expr_clone(struct expr *new, const struct expr *expr) __set_elem_expr_clone(new, expr); } +static void set_elem_expr_set_type(const struct expr *expr, + const struct datatype *dtype, + enum byteorder byteorder) +{ + expr_set_type(expr->key, dtype, byteorder); +} + static const struct expr_ops set_elem_expr_ops = { .type = EXPR_SET_ELEM, .name = "set element", @@ -1563,6 +1597,7 @@ static const struct expr_ops set_elem_expr_ops = { .print = set_elem_expr_print, .json = set_elem_expr_json, .destroy = set_elem_expr_destroy, + .set_type = set_elem_expr_set_type, }; struct expr *set_elem_expr_alloc(const struct location *loc, struct expr *key) diff --git a/tests/py/any/tcpopt.t b/tests/py/any/tcpopt.t index a2fcdb3a..79699e23 100644 --- a/tests/py/any/tcpopt.t +++ b/tests/py/any/tcpopt.t @@ -53,7 +53,7 @@ tcp option mptcp exists;ok tcp option mptcp subtype mp-capable;ok tcp option mptcp subtype 1;ok;tcp option mptcp subtype mp-join -tcp option mptcp subtype { 0, 2};ok +tcp option mptcp subtype { mp-capable, mp-join, remove-addr, mp-prio, mp-fail, mp-fastclose, mp-tcprst };ok reset tcp option mptcp;ok reset tcp option 2;ok;reset tcp option maxseg diff --git a/tests/py/any/tcpopt.t.json b/tests/py/any/tcpopt.t.json index ea580473..a02e71b6 100644 --- a/tests/py/any/tcpopt.t.json +++ b/tests/py/any/tcpopt.t.json @@ -565,7 +565,7 @@ } ] -# tcp option mptcp subtype { 0, 2} +# tcp option mptcp subtype { mp-capable, mp-join, remove-addr, mp-prio, mp-fail, mp-fastclose, mp-tcprst } [ { "match": { @@ -578,8 +578,13 @@ "op": "==", "right": { "set": [ - 0, - 2 + "mp-capable", + "mp-join", + "remove-addr", + "mp-prio", + "mp-fail", + "mp-fastclose", + "mp-tcprst" ] } } diff --git a/tests/py/any/tcpopt.t.payload b/tests/py/any/tcpopt.t.payload index e3cf500b..af8c4317 100644 --- a/tests/py/any/tcpopt.t.payload +++ b/tests/py/any/tcpopt.t.payload @@ -180,11 +180,11 @@ inet [ bitwise reg 1 = ( reg 1 & 0x000000f0 ) ^ 0x00000000 ] [ cmp eq reg 1 0x00000010 ] -# tcp option mptcp subtype { 0, 2} -__set%d test-inet 3 size 2 -__set%d test-inet 0 - element 00000000 : 0 [end] element 00000020 : 0 [end] -inet +# tcp option mptcp subtype { mp-capable, mp-join, remove-addr, mp-prio, mp-fail, mp-fastclose, mp-tcprst } +__set%d test-ip4 3 size 7 +__set%d test-ip4 0 + element 00000000 : 0 [end] element 00000010 : 0 [end] element 00000040 : 0 [end] element 00000050 : 0 [end] element 00000060 : 0 [end] element 00000070 : 0 [end] element 00000080 : 0 [end] +ip test-ip4 input [ exthdr load tcpopt 1b @ 30 + 2 => reg 1 ] [ bitwise reg 1 = ( reg 1 & 0x000000f0 ) ^ 0x00000000 ] [ lookup reg 1 set __set%d ] |