[nft] nftables: Fixing Bug 1219 - handle rt0 and rt2 properly

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Type 0 and 2 of the IPv6 Routing extension header are not handled
properly by exthdr_init_raw() in src/exthdr.c

In order to fix the bug, we extended the "enum nft_exthdr_op" to
differentiate between rt, rt0, and rt2.

This patch should fix the bug. We tested the patch against the
same configuration reported in the bug and the output is as
shown below.

table ip6 filter {
	chain input {
		type filter hook input priority 0; policy accept;
		rt0 addr[1] a::2
	}
}

Signed-off-by: Ahmed Abdelsalam <amsalam20@xxxxxxxxx>
---
 include/exthdr.h                    |  1 +
 include/linux/netfilter/nf_tables.h |  3 +++
 src/exthdr.c                        | 23 ++++++++++++++++++++++-
 3 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/include/exthdr.h b/include/exthdr.h
index 97ccc38..06bf628 100644
--- a/include/exthdr.h
+++ b/include/exthdr.h
@@ -14,6 +14,7 @@
 struct exthdr_desc {
 	const char			*name;
 	uint8_t				type;
+	int				proto_key;
 	struct proto_hdr_template	templates[10];
 };
 
diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
index 2efbf97..baa7caf 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -721,6 +721,9 @@ enum nft_exthdr_flags {
 enum nft_exthdr_op {
 	NFT_EXTHDR_OP_IPV6,
 	NFT_EXTHDR_OP_TCPOPT,
+	NFT_EXTHDR_OP_RT0,
+	NFT_EXTHDR_OP_RT2,
+	NFT_EXTHDR_OP_RT4,
 	__NFT_EXTHDR_OP_MAX
 };
 #define NFT_EXTHDR_OP_MAX	(__NFT_EXTHDR_OP_MAX - 1)
diff --git a/src/exthdr.c b/src/exthdr.c
index f5c20ac..3757f33 100644
--- a/src/exthdr.c
+++ b/src/exthdr.c
@@ -93,6 +93,16 @@ struct expr *exthdr_expr_alloc(const struct location *loc,
 			  BYTEORDER_BIG_ENDIAN, tmpl->len);
 	expr->exthdr.desc = desc;
 	expr->exthdr.tmpl = tmpl;
+	if (desc != NULL && desc->proto_key >= 0) {
+		switch (desc->proto_key) {
+		case 0:
+			expr->exthdr.op = NFT_EXTHDR_OP_RT0;
+			break;
+		case 2:
+			expr->exthdr.op = NFT_EXTHDR_OP_RT2;
+			break;
+		}
+	}
 	return expr;
 }
 
@@ -151,7 +161,11 @@ void exthdr_init_raw(struct expr *expr, uint8_t type,
 	expr->exthdr.offset = offset;
 	expr->exthdr.desc = NULL;
 
-	if (type < array_size(exthdr_protocols))
+	if (op == NFT_EXTHDR_OP_RT0)
+		expr->exthdr.desc = &exthdr_rt0;
+	else if (op == NFT_EXTHDR_OP_RT2)
+		expr->exthdr.desc = &exthdr_rt2;
+	else if (type < array_size(exthdr_protocols))
 		expr->exthdr.desc = exthdr_protocols[type];
 
 	if (expr->exthdr.desc == NULL)
@@ -236,6 +250,9 @@ const struct exthdr_desc exthdr_hbh = {
  */
 
 const struct exthdr_desc exthdr_rt2 = {
+	.name           = "rt2",
+	.type           = IPPROTO_ROUTING,
+	.proto_key	= 2,
 	.templates	= {
 		[RT2HDR_RESERVED]	= {},
 		[RT2HDR_ADDR]		= {},
@@ -246,6 +263,9 @@ const struct exthdr_desc exthdr_rt2 = {
 	HDR_TEMPLATE(__name, __dtype, struct ip6_rthdr0, __member)
 
 const struct exthdr_desc exthdr_rt0 = {
+	.name           = "rt0",
+	.type           = IPPROTO_ROUTING,
+	.proto_key      = 0,
 	.templates	= {
 		[RT0HDR_RESERVED]	= RT0_FIELD("reserved", ip6r0_reserved, &integer_type),
 		[RT0HDR_ADDR_1]		= RT0_FIELD("addr[1]", ip6r0_addr[0], &ip6addr_type),
@@ -260,6 +280,7 @@ const struct exthdr_desc exthdr_rt0 = {
 const struct exthdr_desc exthdr_rt = {
 	.name		= "rt",
 	.type		= IPPROTO_ROUTING,
+	.proto_key      = -1,
 #if 0
 	.protocol_key	= RTHDR_TYPE,
 	.protocols	= {
-- 
2.1.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



[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux