From: Álvaro Neira Ayuso <alvaroneay@xxxxxxxxx> In all case that we have added a payload dependency, we have supposed that the byteorder must to be BYTEORDER_HOST_ENDIAN, the problem is when we want to add a dependency that the value has another byteorder. For example, if we try to add a new payload dependency in a bridge table and we use ether type, the byteorder is BYTEORDER_BIG_ENDIAN. The value of the type ip is 0x0800 in ether but when we add the payload dependency for this specific protocol, we will have a payload like this: [ payload load 2b @ link header + 12 => reg 1 ] [ cmp eq reg 1 0x00000008 ] This patch allows to create payload dependency with the byteorder of the template. For that I have updated the function for updating the context for using the byteorder of the template too. With this changes we have a payload with the correct format: [ payload load 2b @ link header + 12 => reg 1 ] [ cmp eq reg 1 0x00000800 ] Signed-off-by: Alvaro Neira Ayuso <alvaroneay@xxxxxxxxx> --- [tested with the rules] nft add rule filter input ip protocol tcp counter nft add rule filter input ip protocol udp counter nft add rule filter input tcp dport 22 counter src/payload.c | 9 +++++++-- src/proto.c | 8 ++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/payload.c b/src/payload.c index a1785a5..fb78ba5 100644 --- a/src/payload.c +++ b/src/payload.c @@ -69,13 +69,18 @@ static void payload_expr_pctx_update(struct proto_ctx *ctx, { const struct expr *left = expr->left, *right = expr->right; const struct proto_desc *base, *desc; + const struct proto_hdr_template *tmpl; + uint32_t value = 0; if (!(left->flags & EXPR_F_PROTOCOL)) return; assert(expr->op == OP_EQ); base = ctx->protocol[left->payload.base].desc; - desc = proto_find_upper(base, mpz_get_uint32(right->value)); + tmpl = &base->templates[base->protocol_key]; + mpz_export_data(&value, right->value, tmpl->dtype->byteorder, + div_round_up(tmpl->len, BITS_PER_BYTE)); + desc = proto_find_upper(base, value); proto_ctx_update(ctx, left->payload.base + 1, &expr->location, desc); } @@ -208,7 +213,7 @@ int payload_gen_dependency(struct eval_ctx *ctx, const struct expr *expr, left = payload_expr_alloc(&expr->location, desc, desc->protocol_key); right = constant_expr_alloc(&expr->location, tmpl->dtype, - BYTEORDER_HOST_ENDIAN, + tmpl->dtype->byteorder, tmpl->len, constant_data_ptr(protocol, tmpl->len)); diff --git a/src/proto.c b/src/proto.c index 546ef10..4192108 100644 --- a/src/proto.c +++ b/src/proto.c @@ -249,6 +249,7 @@ const struct proto_desc proto_ah = { const struct proto_desc proto_esp = { .name = "esp", .base = PROTO_BASE_TRANSPORT_HDR, + .protocol_key = IPPROTO_ESP, .templates = { [ESPHDR_SPI] = ESPHDR_FIELD("spi", spi), [ESPHDR_SEQUENCE] = ESPHDR_FIELD("sequence", seq_no), @@ -326,6 +327,7 @@ static const struct datatype icmp_type_type = { const struct proto_desc proto_icmp = { .name = "icmp", .base = PROTO_BASE_TRANSPORT_HDR, + .protocol_key = IPPROTO_ICMP, .templates = { [ICMPHDR_TYPE] = ICMPHDR_TYPE("type", &icmp_type_type, type), [ICMPHDR_CODE] = ICMPHDR_FIELD("code", code), @@ -348,6 +350,7 @@ const struct proto_desc proto_icmp = { const struct proto_desc proto_udp = { .name = "udp", .base = PROTO_BASE_TRANSPORT_HDR, + .protocol_key = IPPROTO_UDP, .templates = { [UDPHDR_SPORT] = INET_SERVICE("sport", struct udphdr, source), [UDPHDR_DPORT] = INET_SERVICE("dport", struct udphdr, dest), @@ -359,6 +362,7 @@ const struct proto_desc proto_udp = { const struct proto_desc proto_udplite = { .name = "udplite", .base = PROTO_BASE_TRANSPORT_HDR, + .protocol_key = IPPROTO_UDPLITE, .templates = { [UDPHDR_SPORT] = INET_SERVICE("sport", struct udphdr, source), [UDPHDR_DPORT] = INET_SERVICE("dport", struct udphdr, dest), @@ -403,6 +407,7 @@ static const struct datatype tcp_flag_type = { const struct proto_desc proto_tcp = { .name = "tcp", .base = PROTO_BASE_TRANSPORT_HDR, + .protocol_key = IPPROTO_TCP, .templates = { [TCPHDR_SPORT] = INET_SERVICE("sport", struct tcphdr, source), [TCPHDR_DPORT] = INET_SERVICE("dport", struct tcphdr, dest), @@ -456,6 +461,7 @@ static const struct datatype dccp_pkttype_type = { const struct proto_desc proto_dccp = { .name = "dccp", .base = PROTO_BASE_TRANSPORT_HDR, + .protocol_key = IPPROTO_DCCP, .templates = { [DCCPHDR_SPORT] = INET_SERVICE("sport", struct dccp_hdr, dccph_sport), [DCCPHDR_DPORT] = INET_SERVICE("dport", struct dccp_hdr, dccph_dport), @@ -473,6 +479,7 @@ const struct proto_desc proto_dccp = { const struct proto_desc proto_sctp = { .name = "sctp", .base = PROTO_BASE_TRANSPORT_HDR, + .protocol_key = IPPROTO_SCTP, .templates = { [SCTPHDR_SPORT] = INET_SERVICE("sport", struct sctphdr, source), [SCTPHDR_DPORT] = INET_SERVICE("dport", struct sctphdr, dest), @@ -566,6 +573,7 @@ static const struct datatype icmp6_type_type = { const struct proto_desc proto_icmp6 = { .name = "icmpv6", .base = PROTO_BASE_TRANSPORT_HDR, + .protocol_key = IPPROTO_ICMPV6, .templates = { [ICMP6HDR_TYPE] = ICMP6HDR_TYPE("type", &icmp6_type_type, icmp6_type), [ICMP6HDR_CODE] = ICMP6HDR_FIELD("code", icmp6_code), -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html