extern int exthdr_gen_dependency(struct eval_ctx *ctx, const struct expr *expr,
struct stmt **res);
-extern bool payload_is_adjacent(const struct expr *e1, const struct expr *e2);
+extern bool payload_can_merge(const struct expr *e1, const struct expr *e2);
extern struct expr *payload_expr_join(const struct expr *e1,
const struct expr *e2);
list_add_tail(&new->list, list);
}
+static bool payload_is_adjacent(const struct expr *e1, const struct expr *e2)
+{
+ if (e1->payload.base == e2->payload.base &&
+ e1->payload.offset + e1->len == e2->payload.offset)
+ return true;
+ return false;
+}
+
/**
- * payload_is_adjacent - return whether two payload expressions refer to
- * adjacent header locations
+ * payload_can_merge - return whether two payload expressions can be merged
*
* @e1: first payload expression
* @e2: second payload expression
*/
-bool payload_is_adjacent(const struct expr *e1, const struct expr *e2)
+bool payload_can_merge(const struct expr *e1, const struct expr *e2)
{
+ unsigned int total;
+
+ if (!payload_is_adjacent(e1, e2))
+ return false;
+
if (e1->payload.offset % BITS_PER_BYTE || e1->len % BITS_PER_BYTE ||
e2->payload.offset % BITS_PER_BYTE || e2->len % BITS_PER_BYTE)
return false;
- if (e1->payload.base == e2->payload.base &&
- e1->payload.offset + e1->len == e2->payload.offset)
- return true;
- return false;
+ total = e1->len + e2->len;
+ if (total < e1->len || total > (NFT_REG_SIZE * BITS_PER_BYTE))
+ return false;
+
+ return true;
}
/**
stmt = sa[i];
this = stmt->expr;
- if (!payload_is_adjacent(last->left, this->left) ||
+ if (!payload_can_merge(last->left, this->left) ||
last->op != this->op) {
last = this;
j = i;
# v61 ({v610}|{v611})
# v60 (::)
ip6 saddr ::/64;ok
+ip6 saddr ::1 ip6 daddr ::2;ok
- ip6 daddr != {::1234:1234:1234:1234:1234:1234:1234, 1234:1234::1234:1234:1234:1234:1234 };ok
ip6 daddr != ::1234:1234:1234:1234:1234:1234:1234-1234:1234::1234:1234:1234:1234:1234;ok;ip6 daddr != 0:1234:1234:1234:1234:1234:1234:1234-1234:1234:0:1234:1234:1234:1234:1234
[ bitwise reg 1 = (reg=1 & 0xffffffff 0xffffffff 0x00000000 0x00000000 ) ^ 0x00000000 0x00000000 0x00000000 0x00000000 ]
[ cmp eq reg 1 0x00000000 0x00000000 0x00000000 0x00000000 ]
+# ip6 saddr ::1 ip6 daddr ::2
+inet test-inet input
+ [ meta load nfproto => reg 1 ]
+ [ cmp eq reg 1 0x0000000a ]
+ [ payload load 16b @ network header + 8 => reg 1 ]
+ [ cmp eq reg 1 0x00000000 0x00000000 0x00000000 0x01000000 ]
+ [ payload load 16b @ network header + 24 => reg 1 ]
+ [ cmp eq reg 1 0x00000000 0x00000000 0x00000000 0x02000000 ]
+
# ip6 daddr != ::1234:1234:1234:1234:1234:1234:1234-1234:1234::1234:1234:1234:1234:1234
inet test-inet input
[ meta load nfproto => reg 1 ]
[ bitwise reg 1 = (reg=1 & 0xffffffff 0xffffffff 0x00000000 0x00000000 ) ^ 0x00000000 0x00000000 0x00000000 0x00000000 ]
[ cmp eq reg 1 0x00000000 0x00000000 0x00000000 0x00000000 ]
+# ip6 saddr ::1 ip6 daddr ::2
+ip6 test-ip6 input
+ [ payload load 16b @ network header + 8 => reg 1 ]
+ [ cmp eq reg 1 0x00000000 0x00000000 0x00000000 0x01000000 ]
+ [ payload load 16b @ network header + 24 => reg 1 ]
+ [ cmp eq reg 1 0x00000000 0x00000000 0x00000000 0x02000000 ]
+
# ip6 daddr != ::1234:1234:1234:1234:1234:1234:1234-1234:1234::1234:1234:1234:1234:1234
ip6 test-ip6 input
[ payload load 16b @ network header + 24 => reg 1 ]