diff options
-rw-r--r-- | src/netlink_linearize.c | 38 | ||||
-rw-r--r-- | tests/py/inet/tcp.t | 2 | ||||
-rw-r--r-- | tests/py/inet/tcp.t.json | 52 | ||||
-rw-r--r-- | tests/py/inet/tcp.t.payload | 16 |
4 files changed, 93 insertions, 15 deletions
diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c index 9ab3ec3e..eb53ccec 100644 --- a/src/netlink_linearize.c +++ b/src/netlink_linearize.c @@ -481,23 +481,31 @@ static void netlink_gen_flagcmp(struct netlink_linearize_ctx *ctx, netlink_gen_raw_data(zero, expr->right->byteorder, len, &nld); netlink_gen_data(expr->right, &nld2); - nle = alloc_nft_expr("bitwise"); - netlink_put_register(nle, NFTNL_EXPR_BITWISE_SREG, sreg); - netlink_put_register(nle, NFTNL_EXPR_BITWISE_DREG, sreg); - nftnl_expr_set_u32(nle, NFTNL_EXPR_BITWISE_LEN, len); - nftnl_expr_set(nle, NFTNL_EXPR_BITWISE_MASK, &nld2.value, nld2.len); - nftnl_expr_set(nle, NFTNL_EXPR_BITWISE_XOR, &nld.value, nld.len); - nft_rule_add_expr(ctx, nle, &expr->location); - - nle = alloc_nft_expr("cmp"); - netlink_put_register(nle, NFTNL_EXPR_CMP_SREG, sreg); - if (expr->op == OP_NEG) + if (expr->left->etype == EXPR_BINOP) { + nle = alloc_nft_expr("cmp"); + netlink_put_register(nle, NFTNL_EXPR_CMP_SREG, sreg); nftnl_expr_set_u32(nle, NFTNL_EXPR_CMP_OP, NFT_CMP_EQ); - else - nftnl_expr_set_u32(nle, NFTNL_EXPR_CMP_OP, NFT_CMP_NEQ); + nftnl_expr_set(nle, NFTNL_EXPR_CMP_DATA, nld2.value, nld2.len); + nft_rule_add_expr(ctx, nle, &expr->location); + } else { + nle = alloc_nft_expr("bitwise"); + netlink_put_register(nle, NFTNL_EXPR_BITWISE_SREG, sreg); + netlink_put_register(nle, NFTNL_EXPR_BITWISE_DREG, sreg); + nftnl_expr_set_u32(nle, NFTNL_EXPR_BITWISE_LEN, len); + nftnl_expr_set(nle, NFTNL_EXPR_BITWISE_MASK, &nld2.value, nld2.len); + nftnl_expr_set(nle, NFTNL_EXPR_BITWISE_XOR, &nld.value, nld.len); + nft_rule_add_expr(ctx, nle, &expr->location); - nftnl_expr_set(nle, NFTNL_EXPR_CMP_DATA, nld.value, nld.len); - nft_rule_add_expr(ctx, nle, &expr->location); + nle = alloc_nft_expr("cmp"); + netlink_put_register(nle, NFTNL_EXPR_CMP_SREG, sreg); + if (expr->op == OP_NEG) + nftnl_expr_set_u32(nle, NFTNL_EXPR_CMP_OP, NFT_CMP_EQ); + else + nftnl_expr_set_u32(nle, NFTNL_EXPR_CMP_OP, NFT_CMP_NEQ); + + nftnl_expr_set(nle, NFTNL_EXPR_CMP_DATA, nld.value, nld.len); + nft_rule_add_expr(ctx, nle, &expr->location); + } mpz_clear(zero); release_register(ctx, expr->left); diff --git a/tests/py/inet/tcp.t b/tests/py/inet/tcp.t index 16e15b9f..983564ec 100644 --- a/tests/py/inet/tcp.t +++ b/tests/py/inet/tcp.t @@ -69,6 +69,8 @@ tcp flags != cwr;ok tcp flags == syn;ok tcp flags fin,syn / fin,syn;ok tcp flags != syn / fin,syn;ok +tcp flags & (fin | syn | rst | ack) syn;ok;tcp flags syn / fin,syn,rst,ack +tcp flags & (fin | syn | rst | ack) != syn;ok;tcp flags != syn / fin,syn,rst,ack tcp flags & (fin | syn | rst | psh | ack | urg | ecn | cwr) == fin | syn | rst | psh | ack | urg | ecn | cwr;ok;tcp flags == 0xff tcp flags { syn, syn | ack };ok tcp flags & (fin | syn | rst | psh | ack | urg) == { fin, ack, psh | ack, fin | psh | ack };ok diff --git a/tests/py/inet/tcp.t.json b/tests/py/inet/tcp.t.json index 590a3dee..033a4f22 100644 --- a/tests/py/inet/tcp.t.json +++ b/tests/py/inet/tcp.t.json @@ -1521,3 +1521,55 @@ } ] +# tcp flags & (fin | syn | rst | ack) syn +[ + { + "match": { + "left": { + "&": [ + { + "payload": { + "field": "flags", + "protocol": "tcp" + } + }, + [ + "fin", + "syn", + "rst", + "ack" + ] + ] + }, + "op": "==", + "right": "syn" + } + } +] + +# tcp flags & (fin | syn | rst | ack) != syn +[ + { + "match": { + "left": { + "&": [ + { + "payload": { + "field": "flags", + "protocol": "tcp" + } + }, + [ + "fin", + "syn", + "rst", + "ack" + ] + ] + }, + "op": "!=", + "right": "syn" + } + } +] + diff --git a/tests/py/inet/tcp.t.payload b/tests/py/inet/tcp.t.payload index 7f302080..eaa7cd09 100644 --- a/tests/py/inet/tcp.t.payload +++ b/tests/py/inet/tcp.t.payload @@ -370,6 +370,22 @@ inet test-inet input [ bitwise reg 1 = ( reg 1 & 0x00000003 ) ^ 0x00000000 ] [ cmp neq reg 1 0x00000002 ] +# tcp flags & (fin | syn | rst | ack) syn +inet test-inet input + [ meta load l4proto => reg 1 ] + [ cmp eq reg 1 0x00000006 ] + [ payload load 1b @ transport header + 13 => reg 1 ] + [ bitwise reg 1 = ( reg 1 & 0x00000017 ) ^ 0x00000000 ] + [ cmp eq reg 1 0x00000002 ] + +# tcp flags & (fin | syn | rst | ack) != syn +inet test-inet input + [ meta load l4proto => reg 1 ] + [ cmp eq reg 1 0x00000006 ] + [ payload load 1b @ transport header + 13 => reg 1 ] + [ bitwise reg 1 = ( reg 1 & 0x00000017 ) ^ 0x00000000 ] + [ cmp neq reg 1 0x00000002 ] + # tcp flags & (fin | syn | rst | psh | ack | urg | ecn | cwr) == fin | syn | rst | psh | ack | urg | ecn | cwr inet test-inet input [ meta load l4proto => reg 1 ] |