summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/netlink_linearize.c38
-rw-r--r--tests/py/inet/tcp.t2
-rw-r--r--tests/py/inet/tcp.t.json52
-rw-r--r--tests/py/inet/tcp.t.payload16
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 ]