All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH iptables 0/4] add arptables-translate
@ 2023-11-03 10:23 Florian Westphal
  2023-11-03 10:23 ` [PATCH iptables 1/4] arptables-nft: use ARPT_INV flags consistently Florian Westphal
                   ` (4 more replies)
  0 siblings, 5 replies; 16+ messages in thread
From: Florian Westphal @ 2023-11-03 10:23 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Florian Westphal

iptables-nft lacks a translate variant for arptables.

Add it.  First patch fixes a bug in existing arptables-nft,
second patch adds missing mask matching.
Patch 3 is the main arptables-translate support.

Last patch adds a few test cases.

Florian Westphal (4):
  arptables-nft: use ARPT_INV flags consistently
  nft-arp: add missing mask support
  nft-arp: add arptables-translate
  arptables-txlate: add test cases

 extensions/generic.txlate        |   6 +
 extensions/libarpt_mangle.c      |  47 +++++++
 extensions/libarpt_mangle.txlate |   6 +
 iptables/nft-arp.c               | 230 +++++++++++++++++++++++++++----
 iptables/nft-ruleparse-arp.c     |  24 ++--
 iptables/xtables-multi.h         |   1 +
 iptables/xtables-nft-multi.c     |   1 +
 iptables/xtables-translate.c     |  35 ++++-
 xlate-test.py                    |   2 +-
 9 files changed, 312 insertions(+), 40 deletions(-)
 create mode 100644 extensions/libarpt_mangle.txlate

-- 
2.41.0


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH iptables 1/4] arptables-nft: use ARPT_INV flags consistently
  2023-11-03 10:23 [PATCH iptables 0/4] add arptables-translate Florian Westphal
@ 2023-11-03 10:23 ` Florian Westphal
  2023-11-03 15:56   ` Phil Sutter
  2023-11-03 10:23 ` [PATCH iptables 2/4] nft-arp: add missing mask support Florian Westphal
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 16+ messages in thread
From: Florian Westphal @ 2023-11-03 10:23 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Florian Westphal

These values are not always interchangeable, e.g.:

define IPT_INV_SRCDEVADDR	0x0080
but:
define ARPT_INV_SRCDEVADDR	0x0010

as these flags can be tested by libarp_foo.so such
checks can yield incorrect results.

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 iptables/nft-arp.c           | 56 ++++++++++++++++++------------------
 iptables/nft-ruleparse-arp.c | 16 +++++------
 2 files changed, 36 insertions(+), 36 deletions(-)

diff --git a/iptables/nft-arp.c b/iptables/nft-arp.c
index aed39ebdd516..a0f4e1547f4e 100644
--- a/iptables/nft-arp.c
+++ b/iptables/nft-arp.c
@@ -48,38 +48,38 @@ static int nft_arp_add(struct nft_handle *h, struct nft_rule_ctx *ctx,
 	int ret = 0;
 
 	if (fw->arp.iniface[0] != '\0') {
-		op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_VIA_IN);
+		op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_VIA_IN);
 		add_iface(h, r, fw->arp.iniface, NFT_META_IIFNAME, op);
 	}
 
 	if (fw->arp.outiface[0] != '\0') {
-		op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_VIA_OUT);
+		op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_VIA_OUT);
 		add_iface(h, r, fw->arp.outiface, NFT_META_OIFNAME, op);
 	}
 
 	if (fw->arp.arhrd != 0 ||
-	    fw->arp.invflags & IPT_INV_ARPHRD) {
+	    fw->arp.invflags & ARPT_INV_ARPHRD) {
 		uint8_t reg;
 
-		op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_ARPHRD);
+		op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_ARPHRD);
 		add_payload(h, r, offsetof(struct arphdr, ar_hrd), 2,
 			    NFT_PAYLOAD_NETWORK_HEADER, &reg);
 		add_cmp_u16(r, fw->arp.arhrd, op, reg);
 	}
 
 	if (fw->arp.arpro != 0 ||
-	    fw->arp.invflags & IPT_INV_PROTO) {
+	    fw->arp.invflags & ARPT_INV_ARPPRO) {
 		uint8_t reg;
 
-		op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_PROTO);
+		op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_ARPPRO);
 	        add_payload(h, r, offsetof(struct arphdr, ar_pro), 2,
 			    NFT_PAYLOAD_NETWORK_HEADER, &reg);
 		add_cmp_u16(r, fw->arp.arpro, op, reg);
 	}
 
 	if (fw->arp.arhln != 0 ||
-	    fw->arp.invflags & IPT_INV_ARPHLN) {
-		op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_ARPHLN);
+	    fw->arp.invflags & ARPT_INV_ARPHLN) {
+		op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_ARPHLN);
 		add_proto(h, r, offsetof(struct arphdr, ar_hln), 1,
 			  fw->arp.arhln, op);
 	}
@@ -87,17 +87,17 @@ static int nft_arp_add(struct nft_handle *h, struct nft_rule_ctx *ctx,
 	add_proto(h, r, offsetof(struct arphdr, ar_pln), 1, 4, NFT_CMP_EQ);
 
 	if (fw->arp.arpop != 0 ||
-	    fw->arp.invflags & IPT_INV_ARPOP) {
+	    fw->arp.invflags & ARPT_INV_ARPOP) {
 		uint8_t reg;
 
-		op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_ARPOP);
+		op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_ARPOP);
 		add_payload(h, r, offsetof(struct arphdr, ar_op), 2,
 			    NFT_PAYLOAD_NETWORK_HEADER, &reg);
 		add_cmp_u16(r, fw->arp.arpop, op, reg);
 	}
 
 	if (need_devaddr(&fw->arp.src_devaddr)) {
-		op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_SRCDEVADDR);
+		op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_SRCDEVADDR);
 		add_addr(h, r, NFT_PAYLOAD_NETWORK_HEADER,
 			 sizeof(struct arphdr),
 			 &fw->arp.src_devaddr.addr,
@@ -108,8 +108,8 @@ static int nft_arp_add(struct nft_handle *h, struct nft_rule_ctx *ctx,
 
 	if (fw->arp.src.s_addr != 0 ||
 	    fw->arp.smsk.s_addr != 0 ||
-	    fw->arp.invflags & IPT_INV_SRCIP) {
-		op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_SRCIP);
+	    fw->arp.invflags & ARPT_INV_SRCIP) {
+		op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_SRCIP);
 		add_addr(h, r, NFT_PAYLOAD_NETWORK_HEADER,
 			 sizeof(struct arphdr) + fw->arp.arhln,
 			 &fw->arp.src.s_addr, &fw->arp.smsk.s_addr,
@@ -118,7 +118,7 @@ static int nft_arp_add(struct nft_handle *h, struct nft_rule_ctx *ctx,
 
 
 	if (need_devaddr(&fw->arp.tgt_devaddr)) {
-		op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_TGTDEVADDR);
+		op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_TGTDEVADDR);
 		add_addr(h, r, NFT_PAYLOAD_NETWORK_HEADER,
 			 sizeof(struct arphdr) + fw->arp.arhln + sizeof(struct in_addr),
 			 &fw->arp.tgt_devaddr.addr,
@@ -128,8 +128,8 @@ static int nft_arp_add(struct nft_handle *h, struct nft_rule_ctx *ctx,
 
 	if (fw->arp.tgt.s_addr != 0 ||
 	    fw->arp.tmsk.s_addr != 0 ||
-	    fw->arp.invflags & IPT_INV_DSTIP) {
-		op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_DSTIP);
+	    fw->arp.invflags & ARPT_INV_TGTIP) {
+		op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_TGTIP);
 		add_addr(h, r, NFT_PAYLOAD_NETWORK_HEADER,
 			 sizeof(struct arphdr) + fw->arp.arhln + sizeof(struct in_addr) + fw->arp.arhln,
 			 &fw->arp.tgt.s_addr, &fw->arp.tmsk.s_addr,
@@ -207,7 +207,7 @@ static void nft_arp_print_rule_details(const struct iptables_command_state *cs,
 		else strcat(iface, "any");
 	}
 	if (print_iface) {
-		printf("%s%s-i %s", sep, fw->arp.invflags & IPT_INV_VIA_IN ?
+		printf("%s%s-i %s", sep, fw->arp.invflags & ARPT_INV_VIA_IN ?
 				   "! " : "", iface);
 		sep = " ";
 	}
@@ -225,14 +225,14 @@ static void nft_arp_print_rule_details(const struct iptables_command_state *cs,
 		else strcat(iface, "any");
 	}
 	if (print_iface) {
-		printf("%s%s-o %s", sep, fw->arp.invflags & IPT_INV_VIA_OUT ?
+		printf("%s%s-o %s", sep, fw->arp.invflags & ARPT_INV_VIA_OUT ?
 				   "! " : "", iface);
 		sep = " ";
 	}
 
 	if (fw->arp.smsk.s_addr != 0L) {
 		printf("%s%s-s %s", sep,
-		       fw->arp.invflags & IPT_INV_SRCIP ? "! " : "",
+		       fw->arp.invflags & ARPT_INV_SRCIP ? "! " : "",
 		       ipv4_addr_to_string(&fw->arp.src,
 					   &fw->arp.smsk, format));
 		sep = " ";
@@ -243,7 +243,7 @@ static void nft_arp_print_rule_details(const struct iptables_command_state *cs,
 			break;
 	if (i == ARPT_DEV_ADDR_LEN_MAX)
 		goto after_devsrc;
-	printf("%s%s", sep, fw->arp.invflags & IPT_INV_SRCDEVADDR
+	printf("%s%s", sep, fw->arp.invflags & ARPT_INV_SRCDEVADDR
 		? "! " : "");
 	printf("--src-mac ");
 	xtables_print_mac_and_mask((unsigned char *)fw->arp.src_devaddr.addr,
@@ -253,7 +253,7 @@ after_devsrc:
 
 	if (fw->arp.tmsk.s_addr != 0L) {
 		printf("%s%s-d %s", sep,
-		       fw->arp.invflags & IPT_INV_DSTIP ? "! " : "",
+		       fw->arp.invflags & ARPT_INV_TGTIP ? "! " : "",
 		       ipv4_addr_to_string(&fw->arp.tgt,
 					   &fw->arp.tmsk, format));
 		sep = " ";
@@ -264,7 +264,7 @@ after_devsrc:
 			break;
 	if (i == ARPT_DEV_ADDR_LEN_MAX)
 		goto after_devdst;
-	printf("%s%s", sep, fw->arp.invflags & IPT_INV_TGTDEVADDR
+	printf("%s%s", sep, fw->arp.invflags & ARPT_INV_TGTDEVADDR
 		? "! " : "");
 	printf("--dst-mac ");
 	xtables_print_mac_and_mask((unsigned char *)fw->arp.tgt_devaddr.addr,
@@ -274,8 +274,8 @@ after_devsrc:
 after_devdst:
 
 	if (fw->arp.arhln_mask != 255 || fw->arp.arhln != 6 ||
-	    fw->arp.invflags & IPT_INV_ARPHLN) {
-		printf("%s%s", sep, fw->arp.invflags & IPT_INV_ARPHLN
+	    fw->arp.invflags & ARPT_INV_ARPHLN) {
+		printf("%s%s", sep, fw->arp.invflags & ARPT_INV_ARPHLN
 			? "! " : "");
 		printf("--h-length %d", fw->arp.arhln);
 		if (fw->arp.arhln_mask != 255)
@@ -286,7 +286,7 @@ after_devdst:
 	if (fw->arp.arpop_mask != 0) {
 		int tmp = ntohs(fw->arp.arpop);
 
-		printf("%s%s", sep, fw->arp.invflags & IPT_INV_ARPOP
+		printf("%s%s", sep, fw->arp.invflags & ARPT_INV_ARPOP
 			? "! " : "");
 		if (tmp <= ARP_NUMOPCODES && !(format & FMT_NUMERIC))
 			printf("--opcode %s", arp_opcodes[tmp-1]);
@@ -299,10 +299,10 @@ after_devdst:
 	}
 
 	if (fw->arp.arhrd_mask != 65535 || fw->arp.arhrd != htons(1) ||
-	    fw->arp.invflags & IPT_INV_ARPHRD) {
+	    fw->arp.invflags & ARPT_INV_ARPHRD) {
 		uint16_t tmp = ntohs(fw->arp.arhrd);
 
-		printf("%s%s", sep, fw->arp.invflags & IPT_INV_ARPHRD
+		printf("%s%s", sep, fw->arp.invflags & ARPT_INV_ARPHRD
 			? "! " : "");
 		if (tmp == 1 && !(format & FMT_NUMERIC))
 			printf("--h-type %s", "Ethernet");
@@ -316,7 +316,7 @@ after_devdst:
 	if (fw->arp.arpro_mask != 0) {
 		int tmp = ntohs(fw->arp.arpro);
 
-		printf("%s%s", sep, fw->arp.invflags & IPT_INV_PROTO
+		printf("%s%s", sep, fw->arp.invflags & ARPT_INV_ARPPRO
 			? "! " : "");
 		if (tmp == 0x0800 && !(format & FMT_NUMERIC))
 			printf("--proto-type %s", "IPv4");
diff --git a/iptables/nft-ruleparse-arp.c b/iptables/nft-ruleparse-arp.c
index d80ca922955c..a9b92d8048f4 100644
--- a/iptables/nft-ruleparse-arp.c
+++ b/iptables/nft-ruleparse-arp.c
@@ -89,28 +89,28 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx,
 		fw->arp.arhrd = ar_hrd;
 		fw->arp.arhrd_mask = 0xffff;
 		if (inv)
-			fw->arp.invflags |= IPT_INV_ARPHRD;
+			fw->arp.invflags |= ARPT_INV_ARPHRD;
 		break;
 	case offsetof(struct arphdr, ar_pro):
 		get_cmp_data(e, &ar_pro, sizeof(ar_pro), &inv);
 		fw->arp.arpro = ar_pro;
 		fw->arp.arpro_mask = 0xffff;
 		if (inv)
-			fw->arp.invflags |= IPT_INV_PROTO;
+			fw->arp.invflags |= ARPT_INV_ARPPRO;
 		break;
 	case offsetof(struct arphdr, ar_op):
 		get_cmp_data(e, &ar_op, sizeof(ar_op), &inv);
 		fw->arp.arpop = ar_op;
 		fw->arp.arpop_mask = 0xffff;
 		if (inv)
-			fw->arp.invflags |= IPT_INV_ARPOP;
+			fw->arp.invflags |= ARPT_INV_ARPOP;
 		break;
 	case offsetof(struct arphdr, ar_hln):
 		get_cmp_data(e, &ar_hln, sizeof(ar_hln), &inv);
 		fw->arp.arhln = ar_hln;
 		fw->arp.arhln_mask = 0xff;
 		if (inv)
-			fw->arp.invflags |= IPT_INV_ARPHLN;
+			fw->arp.invflags |= ARPT_INV_ARPHLN;
 		break;
 	case offsetof(struct arphdr, ar_pln):
 		get_cmp_data(e, &ar_pln, sizeof(ar_pln), &inv);
@@ -120,7 +120,7 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx,
 	default:
 		if (reg->payload.offset == sizeof(struct arphdr)) {
 			if (nft_arp_parse_devaddr(reg, e, &fw->arp.src_devaddr))
-				fw->arp.invflags |= IPT_INV_SRCDEVADDR;
+				fw->arp.invflags |= ARPT_INV_SRCDEVADDR;
 		} else if (reg->payload.offset == sizeof(struct arphdr) +
 					   fw->arp.arhln) {
 			get_cmp_data(e, &addr, sizeof(addr), &inv);
@@ -133,12 +133,12 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx,
 					   sizeof(struct in_addr)));
 
 			if (inv)
-				fw->arp.invflags |= IPT_INV_SRCIP;
+				fw->arp.invflags |= ARPT_INV_SRCIP;
 		} else if (reg->payload.offset == sizeof(struct arphdr) +
 						  fw->arp.arhln +
 						  sizeof(struct in_addr)) {
 			if (nft_arp_parse_devaddr(reg, e, &fw->arp.tgt_devaddr))
-				fw->arp.invflags |= IPT_INV_TGTDEVADDR;
+				fw->arp.invflags |= ARPT_INV_TGTDEVADDR;
 		} else if (reg->payload.offset == sizeof(struct arphdr) +
 						  fw->arp.arhln +
 						  sizeof(struct in_addr) +
@@ -153,7 +153,7 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx,
 					   sizeof(struct in_addr)));
 
 			if (inv)
-				fw->arp.invflags |= IPT_INV_DSTIP;
+				fw->arp.invflags |= ARPT_INV_TGTIP;
 		} else {
 			ctx->errmsg = "unknown payload offset";
 		}
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH iptables 2/4] nft-arp: add missing mask support
  2023-11-03 10:23 [PATCH iptables 0/4] add arptables-translate Florian Westphal
  2023-11-03 10:23 ` [PATCH iptables 1/4] arptables-nft: use ARPT_INV flags consistently Florian Westphal
@ 2023-11-03 10:23 ` Florian Westphal
  2023-11-03 20:49   ` Phil Sutter
  2023-11-03 10:23 ` [PATCH iptables 3/4] nft-arp: add arptables-translate Florian Westphal
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 16+ messages in thread
From: Florian Westphal @ 2023-11-03 10:23 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Florian Westphal

arptables-legacy supports masks for --h-type, --opcode
and --proto-type, but arptables-nft did not.

Add this.

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 iptables/nft-arp.c           | 21 +++++++++++++++++++--
 iptables/nft-ruleparse-arp.c |  8 ++++++++
 2 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/iptables/nft-arp.c b/iptables/nft-arp.c
index a0f4e1547f4e..6ca9ae8ffb87 100644
--- a/iptables/nft-arp.c
+++ b/iptables/nft-arp.c
@@ -58,41 +58,56 @@ static int nft_arp_add(struct nft_handle *h, struct nft_rule_ctx *ctx,
 	}
 
 	if (fw->arp.arhrd != 0 ||
+	    fw->arp.arhrd_mask != 0xffff ||
 	    fw->arp.invflags & ARPT_INV_ARPHRD) {
 		uint8_t reg;
 
 		op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_ARPHRD);
 		add_payload(h, r, offsetof(struct arphdr, ar_hrd), 2,
 			    NFT_PAYLOAD_NETWORK_HEADER, &reg);
+		if (fw->arp.arhrd_mask != 0xffff)
+			add_bitwise_u16(h, r, fw->arp.arhrd_mask, 0, reg, &reg);
 		add_cmp_u16(r, fw->arp.arhrd, op, reg);
 	}
 
 	if (fw->arp.arpro != 0 ||
+	    fw->arp.arpro_mask != 0xffff ||
 	    fw->arp.invflags & ARPT_INV_ARPPRO) {
 		uint8_t reg;
 
 		op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_ARPPRO);
 	        add_payload(h, r, offsetof(struct arphdr, ar_pro), 2,
 			    NFT_PAYLOAD_NETWORK_HEADER, &reg);
+		if (fw->arp.arpro_mask != 0xffff)
+			add_bitwise_u16(h, r, fw->arp.arpro_mask, 0, reg, &reg);
 		add_cmp_u16(r, fw->arp.arpro, op, reg);
 	}
 
 	if (fw->arp.arhln != 0 ||
+	    fw->arp.arhln_mask != 255 ||
 	    fw->arp.invflags & ARPT_INV_ARPHLN) {
+		uint8_t reg;
+
 		op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_ARPHLN);
-		add_proto(h, r, offsetof(struct arphdr, ar_hln), 1,
-			  fw->arp.arhln, op);
+		add_payload(h, r, offsetof(struct arphdr, ar_hln), 1,
+			    NFT_PAYLOAD_NETWORK_HEADER, &reg);
+		if (fw->arp.arhln_mask != 255)
+			add_bitwise(h, r, &fw->arp.arhln_mask, 1, reg, &reg);
+		add_cmp_u8(r, fw->arp.arhln, op, reg);
 	}
 
 	add_proto(h, r, offsetof(struct arphdr, ar_pln), 1, 4, NFT_CMP_EQ);
 
 	if (fw->arp.arpop != 0 ||
+	    fw->arp.arpop_mask != 0xffff ||
 	    fw->arp.invflags & ARPT_INV_ARPOP) {
 		uint8_t reg;
 
 		op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_ARPOP);
 		add_payload(h, r, offsetof(struct arphdr, ar_op), 2,
 			    NFT_PAYLOAD_NETWORK_HEADER, &reg);
+		if (fw->arp.arpop_mask != 0xffff)
+			add_bitwise_u16(h, r, fw->arp.arpop_mask, 0, reg, &reg);
 		add_cmp_u16(r, fw->arp.arpop, op, reg);
 	}
 
@@ -556,6 +571,8 @@ static void nft_arp_init_cs(struct iptables_command_state *cs)
 	cs->arp.arp.arhln_mask = 255;
 	cs->arp.arp.arhrd = htons(ARPHRD_ETHER);
 	cs->arp.arp.arhrd_mask = 65535;
+	cs->arp.arp.arpop_mask = 65535;
+	cs->arp.arp.arpro_mask = 65535;
 }
 
 static int
diff --git a/iptables/nft-ruleparse-arp.c b/iptables/nft-ruleparse-arp.c
index a9b92d8048f4..7cd0f9fcd97c 100644
--- a/iptables/nft-ruleparse-arp.c
+++ b/iptables/nft-ruleparse-arp.c
@@ -90,6 +90,8 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx,
 		fw->arp.arhrd_mask = 0xffff;
 		if (inv)
 			fw->arp.invflags |= ARPT_INV_ARPHRD;
+		if (reg->bitwise.set)
+			fw->arp.arhrd_mask = reg->bitwise.mask[0];
 		break;
 	case offsetof(struct arphdr, ar_pro):
 		get_cmp_data(e, &ar_pro, sizeof(ar_pro), &inv);
@@ -97,6 +99,8 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx,
 		fw->arp.arpro_mask = 0xffff;
 		if (inv)
 			fw->arp.invflags |= ARPT_INV_ARPPRO;
+		if (reg->bitwise.set)
+			fw->arp.arpro_mask = reg->bitwise.mask[0];
 		break;
 	case offsetof(struct arphdr, ar_op):
 		get_cmp_data(e, &ar_op, sizeof(ar_op), &inv);
@@ -104,6 +108,8 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx,
 		fw->arp.arpop_mask = 0xffff;
 		if (inv)
 			fw->arp.invflags |= ARPT_INV_ARPOP;
+		if (reg->bitwise.set)
+			fw->arp.arpop_mask = reg->bitwise.mask[0];
 		break;
 	case offsetof(struct arphdr, ar_hln):
 		get_cmp_data(e, &ar_hln, sizeof(ar_hln), &inv);
@@ -111,6 +117,8 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx,
 		fw->arp.arhln_mask = 0xff;
 		if (inv)
 			fw->arp.invflags |= ARPT_INV_ARPHLN;
+		if (reg->bitwise.set)
+			fw->arp.arhln_mask = reg->bitwise.mask[0];
 		break;
 	case offsetof(struct arphdr, ar_pln):
 		get_cmp_data(e, &ar_pln, sizeof(ar_pln), &inv);
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH iptables 3/4] nft-arp: add arptables-translate
  2023-11-03 10:23 [PATCH iptables 0/4] add arptables-translate Florian Westphal
  2023-11-03 10:23 ` [PATCH iptables 1/4] arptables-nft: use ARPT_INV flags consistently Florian Westphal
  2023-11-03 10:23 ` [PATCH iptables 2/4] nft-arp: add missing mask support Florian Westphal
@ 2023-11-03 10:23 ` Florian Westphal
  2023-11-03 20:55   ` Phil Sutter
  2023-11-03 10:23 ` [PATCH iptables 4/4] arptables-txlate: add test cases Florian Westphal
  2023-11-03 11:43 ` [PATCH iptables 0/4] add arptables-translate Pablo Neira Ayuso
  4 siblings, 1 reply; 16+ messages in thread
From: Florian Westphal @ 2023-11-03 10:23 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Florian Westphal

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 extensions/libarpt_mangle.c  |  47 +++++++++++
 iptables/nft-arp.c           | 153 +++++++++++++++++++++++++++++++++++
 iptables/xtables-multi.h     |   1 +
 iptables/xtables-nft-multi.c |   1 +
 iptables/xtables-translate.c |  35 +++++++-
 5 files changed, 236 insertions(+), 1 deletion(-)

diff --git a/extensions/libarpt_mangle.c b/extensions/libarpt_mangle.c
index 765edf34781f..104f603bf6b0 100644
--- a/extensions/libarpt_mangle.c
+++ b/extensions/libarpt_mangle.c
@@ -170,6 +170,52 @@ static void arpmangle_save(const void *ip, const struct xt_entry_target *target)
 	arpmangle_print(ip, target, 0);
 }
 
+static void print_devaddr_xlate(const char *macaddress, struct xt_xlate *xl)
+{
+	unsigned int i;
+
+	xt_xlate_add(xl, "%02x", macaddress[0]);
+	for (i = 1; i < ETH_ALEN; ++i)
+		xt_xlate_add(xl, ":%02x", macaddress[i]);
+}
+
+static int arpmangle_xlate(struct xt_xlate *xl,
+			 const struct xt_xlate_tg_params *params)
+{
+	const struct arpt_mangle *m = (const void *)params->target->data;
+
+	if (m->flags & ARPT_MANGLE_SIP)
+		xt_xlate_add(xl, "arp saddr ip set %s ",
+			     xtables_ipaddr_to_numeric(&m->u_s.src_ip));
+
+	if (m->flags & ARPT_MANGLE_SDEV) {
+		xt_xlate_add(xl, "arp %caddr ether set ", 's');
+		print_devaddr_xlate(m->src_devaddr, xl);
+	}
+
+	if (m->flags & ARPT_MANGLE_TIP)
+		xt_xlate_add(xl, "arp daddr ip set %s ",
+			     xtables_ipaddr_to_numeric(&m->u_t.tgt_ip));
+
+	if (m->flags & ARPT_MANGLE_TDEV) {
+		xt_xlate_add(xl, "arp %caddr ether set ", 'd');
+		print_devaddr_xlate(m->tgt_devaddr, xl);
+	}
+
+	switch (m->target) {
+	case NF_ACCEPT:
+		xt_xlate_add(xl, "accept");
+		break;
+	case NF_DROP:
+		xt_xlate_add(xl, "drop");
+		break;
+	default:
+		break;
+	}
+
+	return 1;
+}
+
 static struct xtables_target arpmangle_target = {
 	.name		= "mangle",
 	.revision	= 0,
@@ -184,6 +230,7 @@ static struct xtables_target arpmangle_target = {
 	.print		= arpmangle_print,
 	.save		= arpmangle_save,
 	.extra_opts	= arpmangle_opts,
+	.xlate		= arpmangle_xlate,
 };
 
 void _init(void)
diff --git a/iptables/nft-arp.c b/iptables/nft-arp.c
index 6ca9ae8ffb87..36166c733956 100644
--- a/iptables/nft-arp.c
+++ b/iptables/nft-arp.c
@@ -18,6 +18,7 @@
 
 #include <xtables.h>
 #include <libiptc/libxtc.h>
+#include <arpa/inet.h>
 #include <net/if_arp.h>
 #include <netinet/if_ether.h>
 
@@ -663,6 +664,157 @@ nft_arp_replace_entry(struct nft_handle *h,
 	return nft_cmd_rule_replace(h, chain, table, cs, rulenum, verbose);
 }
 
+static void nft_arp_xlate_mac_and_mask(const struct arpt_devaddr_info *devaddr,
+				       const char *addr,
+				       bool invert,
+				       struct xt_xlate *xl)
+{
+	unsigned int i;
+
+	for (i = 0; i < 6; ++i) {
+		if (devaddr->mask[i])
+			break;
+	}
+
+	if (i == 6)
+		return;
+
+	xt_xlate_add(xl, "arp %s ether ", addr);
+	if (invert)
+		xt_xlate_add(xl, "!= ");
+
+	xt_xlate_add(xl, "%02x", (uint8_t)devaddr->addr[0]);
+	for (i = 1; i < 6; ++i)
+		xt_xlate_add(xl, ":%02x", (uint8_t)devaddr->addr[i]);
+
+	for (i = 0; i < 6; ++i) {
+		int j;
+
+		if ((uint8_t)devaddr->mask[i] == 0xff)
+			continue;
+
+		xt_xlate_add(xl, "/%02x", (uint8_t)devaddr->mask[0]);
+
+		for (j = 1; j < 6; ++j)
+			xt_xlate_add(xl, ":%02x", (uint8_t)devaddr->mask[j]);
+		return;
+	}
+}
+
+static void nft_arp_xlate16(uint16_t v, uint16_t m, const char *what,
+			    bool hex, bool inverse,
+			    struct xt_xlate *xl)
+{
+	const char *fmt = hex ? "0x%x " : "%d ";
+
+	if (m) {
+		xt_xlate_add(xl, "arp %s ", what);
+		if (inverse)
+			xt_xlate_add(xl, " !=");
+		if (m != 0xffff) {
+			xt_xlate_add(xl, "& ");
+			xt_xlate_add(xl, fmt, ntohs(m));;
+
+		}
+		xt_xlate_add(xl, fmt, ntohs(v));
+	}
+}
+
+static void nft_arp_xlate_ipv4_addr(const char *what, const struct in_addr *addr,
+				    const struct in_addr *mask,
+				    bool inv, struct xt_xlate *xl)
+{
+	char mbuf[INET_ADDRSTRLEN], abuf[INET_ADDRSTRLEN];
+	const char *op = inv ? "!= " : "";
+	int cidr;
+
+	if (!inv && !addr->s_addr && !mask->s_addr)
+		return;
+
+	inet_ntop(AF_INET, addr, abuf, sizeof(abuf));
+
+	cidr = xtables_ipmask_to_cidr(mask);
+	switch (cidr) {
+	case -1:
+		xt_xlate_add(xl, "arp %s ip & %s %s %s ", what,
+			     inet_ntop(AF_INET, mask, mbuf, sizeof(mbuf)),
+			     inv ? "!=" : "==", abuf);
+		break;
+	case 32:
+		xt_xlate_add(xl, "arp %s ip %s%s ", what, op, abuf);
+		break;
+	default:
+		xt_xlate_add(xl, "arp %s ip %s%s/%d ", what, op, abuf, cidr);
+	}
+}
+
+static int nft_arp_xlate(const struct iptables_command_state *cs,
+			 struct xt_xlate *xl)
+{
+	const struct arpt_entry *fw = &cs->arp;
+	int ret;
+
+	xlate_ifname(xl, "iifname", fw->arp.iniface,
+		     fw->arp.invflags & ARPT_INV_VIA_IN);
+	xlate_ifname(xl, "oifname", fw->arp.outiface,
+		     fw->arp.invflags & ARPT_INV_VIA_OUT);
+
+	if (fw->arp.arhrd ||
+	    fw->arp.arhrd_mask != 0xffff ||
+	    fw->arp.invflags & ARPT_INV_ARPHRD)
+		nft_arp_xlate16(fw->arp.arhrd, fw->arp.arhrd_mask,
+				"htype", false,
+				 fw->arp.invflags & ARPT_INV_ARPHRD, xl);
+
+	if (fw->arp.arhln_mask != 255 || fw->arp.arhln ||
+	    fw->arp.invflags & ARPT_INV_ARPHLN) {
+		xt_xlate_add(xl, "arp hlen ");
+		if (fw->arp.invflags & ARPT_INV_ARPHLN)
+			xt_xlate_add(xl, " !=");
+		if (fw->arp.arhln_mask != 255)
+			xt_xlate_add(xl, "& %d ", fw->arp.arhln_mask);
+		xt_xlate_add(xl, "%d ", fw->arp.arhln);
+	}
+
+	/* added implicitly by arptables-nft */
+	xt_xlate_add(xl, "arp plen %d", 4);
+
+	if (fw->arp.arpop_mask != 65535 ||
+	    fw->arp.arpop != 0 ||
+	    fw->arp.invflags & ARPT_INV_ARPOP)
+		nft_arp_xlate16(fw->arp.arpop, fw->arp.arpop_mask,
+				"operation", false,
+				fw->arp.invflags & ARPT_INV_ARPOP, xl);
+
+	if (fw->arp.arpro_mask != 65535 ||
+	    fw->arp.invflags & ARPT_INV_ARPPRO ||
+	    fw->arp.arpro)
+		nft_arp_xlate16(fw->arp.arpro, fw->arp.arpro_mask,
+				"ptype", true,
+				fw->arp.invflags & ARPT_INV_ARPPRO, xl);
+
+	if (fw->arp.smsk.s_addr != 0L)
+		nft_arp_xlate_ipv4_addr("saddr", &fw->arp.src, &fw->arp.smsk,
+					fw->arp.invflags & ARPT_INV_SRCIP, xl);
+
+	if (fw->arp.tmsk.s_addr != 0L)
+		nft_arp_xlate_ipv4_addr("daddr", &fw->arp.tgt, &fw->arp.tmsk,
+					fw->arp.invflags & ARPT_INV_TGTIP, xl);
+
+	nft_arp_xlate_mac_and_mask(&fw->arp.src_devaddr, "saddr",
+				   fw->arp.invflags & ARPT_INV_SRCDEVADDR, xl);
+	nft_arp_xlate_mac_and_mask(&fw->arp.tgt_devaddr, "daddr",
+				   fw->arp.invflags & ARPT_INV_TGTDEVADDR, xl);
+
+	ret = xlate_matches(cs, xl);
+	if (!ret)
+		return ret;
+
+	/* Always add counters per rule, as in iptables */
+	xt_xlate_add(xl, "counter");
+	return xlate_action(cs, false, xl);
+}
+
 struct nft_family_ops nft_family_ops_arp = {
 	.add			= nft_arp_add,
 	.is_same		= nft_arp_is_same,
@@ -678,6 +830,7 @@ struct nft_family_ops nft_family_ops_arp = {
 	.rule_to_cs		= nft_rule_to_iptables_command_state,
 	.init_cs		= nft_arp_init_cs,
 	.clear_cs		= xtables_clear_iptables_command_state,
+	.xlate			= nft_arp_xlate,
 	.add_entry		= nft_arp_add_entry,
 	.delete_entry		= nft_arp_delete_entry,
 	.check_entry		= nft_arp_check_entry,
diff --git a/iptables/xtables-multi.h b/iptables/xtables-multi.h
index 833c11a2ac91..760d3e4f2b6e 100644
--- a/iptables/xtables-multi.h
+++ b/iptables/xtables-multi.h
@@ -9,6 +9,7 @@ extern int xtables_ip4_restore_main(int, char **);
 extern int xtables_ip6_main(int, char **);
 extern int xtables_ip6_save_main(int, char **);
 extern int xtables_ip6_restore_main(int, char **);
+extern int xtables_arp_xlate_main(int, char **);
 extern int xtables_ip4_xlate_main(int, char **);
 extern int xtables_ip6_xlate_main(int, char **);
 extern int xtables_eb_xlate_main(int, char **);
diff --git a/iptables/xtables-nft-multi.c b/iptables/xtables-nft-multi.c
index e2b7c641f85d..48265d8e0afa 100644
--- a/iptables/xtables-nft-multi.c
+++ b/iptables/xtables-nft-multi.c
@@ -30,6 +30,7 @@ static const struct subcommand multi_subcommands[] = {
 	{"ip6tables-translate",		xtables_ip6_xlate_main},
 	{"iptables-restore-translate",	xtables_ip4_xlate_restore_main},
 	{"ip6tables-restore-translate",	xtables_ip6_xlate_restore_main},
+	{"arptables-translate",		xtables_arp_xlate_main},
 	{"arptables",			xtables_arp_main},
 	{"arptables-nft",		xtables_arp_main},
 	{"arptables-restore",		xtables_arp_restore_main},
diff --git a/iptables/xtables-translate.c b/iptables/xtables-translate.c
index 88e0a6b63949..ea9dce204dfc 100644
--- a/iptables/xtables-translate.c
+++ b/iptables/xtables-translate.c
@@ -140,6 +140,7 @@ bool xlate_find_match(const struct iptables_command_state *cs, const char *p_nam
 }
 
 const char *family2str[] = {
+	[NFPROTO_ARP]	= "arp",
 	[NFPROTO_IPV4]	= "ip",
 	[NFPROTO_IPV6]	= "ip6",
 };
@@ -196,6 +197,15 @@ static int xlate(struct nft_handle *h, struct xt_cmd_parse *p,
 
 	for (i = 0; i < args->s.naddrs; i++) {
 		switch (h->family) {
+		case NFPROTO_ARP:
+			cs->arp.arp.src.s_addr = args->s.addr.v4[i].s_addr;
+			cs->arp.arp.smsk.s_addr = args->s.mask.v4[i].s_addr;
+			for (j = 0; j < args->d.naddrs; j++) {
+				cs->arp.arp.tgt.s_addr = args->d.addr.v4[j].s_addr;
+				cs->arp.arp.tmsk.s_addr = args->d.mask.v4[j].s_addr;
+				ret = cb(h, p, cs, append);
+			}
+			break;
 		case AF_INET:
 			cs->fw.ip.src.s_addr = args->s.addr.v4[i].s_addr;
 			cs->fw.ip.smsk.s_addr = args->s.mask.v4[i].s_addr;
@@ -475,7 +485,24 @@ static int xtables_xlate_main_common(struct nft_handle *h,
 
 	xtables_globals.program_name = progname;
 	xtables_globals.compat_rev = dummy_compat_rev;
-	ret = xtables_init_all(&xtables_globals, family);
+
+	switch (family) {
+	case NFPROTO_IPV4:
+		ret = xtables_init_all(&xtables_globals, family);
+		break;
+	case NFPROTO_IPV6:
+		ret = xtables_init_all(&xtables_globals, family);
+		break;
+	case NFPROTO_ARP:
+		arptables_globals.program_name = progname;
+		arptables_globals.compat_rev = dummy_compat_rev;
+		ret = xtables_init_all(&arptables_globals, family);
+		break;
+	default:
+		ret = -1;
+		break;
+	}
+
 	if (ret < 0) {
 		fprintf(stderr, "%s/%s Failed to initialize xtables\n",
 			xtables_globals.program_name,
@@ -590,6 +617,12 @@ static int xtables_restore_xlate_main(int family, const char *progname,
 	exit(0);
 }
 
+int xtables_arp_xlate_main(int argc, char *argv[])
+{
+	return xtables_xlate_main(NFPROTO_ARP, "arptables-translate",
+				  argc, argv);
+}
+
 int xtables_ip4_xlate_main(int argc, char *argv[])
 {
 	return xtables_xlate_main(NFPROTO_IPV4, "iptables-translate",
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH iptables 4/4] arptables-txlate: add test cases
  2023-11-03 10:23 [PATCH iptables 0/4] add arptables-translate Florian Westphal
                   ` (2 preceding siblings ...)
  2023-11-03 10:23 ` [PATCH iptables 3/4] nft-arp: add arptables-translate Florian Westphal
@ 2023-11-03 10:23 ` Florian Westphal
  2023-11-03 11:43 ` [PATCH iptables 0/4] add arptables-translate Pablo Neira Ayuso
  4 siblings, 0 replies; 16+ messages in thread
From: Florian Westphal @ 2023-11-03 10:23 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Florian Westphal

Add test cases for libarpt_mangle and extend the generic
tests to cover basic arptables matches.

Note that there are several historic artefacts that could be revised.
For example, arptables-legacy and arptables-nft both ignore "-p"
instead of returning an error about an unsupported option.

The ptype could be hard-wired to 0x800 and set unconditionally.
OTOH, this should always match for ethernet arp packets anyway.

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 extensions/generic.txlate        | 6 ++++++
 extensions/libarpt_mangle.txlate | 6 ++++++
 xlate-test.py                    | 4 +++-
 3 files changed, 15 insertions(+), 1 deletion(-)
 create mode 100644 extensions/libarpt_mangle.txlate

diff --git a/extensions/generic.txlate b/extensions/generic.txlate
index c24ed1568884..b79239f1a063 100644
--- a/extensions/generic.txlate
+++ b/extensions/generic.txlate
@@ -1,3 +1,9 @@
+arptables-translate -A OUTPUT --proto-type ipv4 -s 1.2.3.4 -j ACCEPT
+nft 'add rule arp filter OUTPUT arp htype 1 arp hlen 6 arp plen 4 arp ptype 0x800 arp saddr ip 1.2.3.4 counter accept'
+
+arptables-translate -I OUTPUT -o oifname
+nft 'insert rule arp filter OUTPUT oifname "oifname" arp htype 1 arp hlen 6 arp plen 4 counter'
+
 iptables-translate -I OUTPUT -p udp -d 8.8.8.8 -j ACCEPT
 nft 'insert rule ip filter OUTPUT ip protocol udp ip daddr 8.8.8.8 counter accept'
 
diff --git a/extensions/libarpt_mangle.txlate b/extensions/libarpt_mangle.txlate
new file mode 100644
index 000000000000..e884d3289a76
--- /dev/null
+++ b/extensions/libarpt_mangle.txlate
@@ -0,0 +1,6 @@
+arptables-translate -A OUTPUT -d 10.21.22.129 -j mangle --mangle-ip-s 10.21.22.161
+nft 'add rule arp filter OUTPUT arp htype 1 arp hlen 6 arp plen 4 arp daddr ip 10.21.22.129 counter arp saddr ip set 10.21.22.161 accept'
+arptables-translate -A OUTPUT -d 10.2.22.129/24 -j mangle --mangle-ip-d 10.2.22.1 --mangle-target CONTINUE
+nft 'add rule arp filter OUTPUT arp htype 1 arp hlen 6 arp plen 4 arp daddr ip 10.2.22.0/24 counter arp daddr ip set 10.2.22.1'
+arptables-translate -A OUTPUT -d 10.2.22.129/24 -j mangle --mangle-ip-d 10.2.22.1 --mangle-mac-d a:b:c:d:e:f
+nft 'add rule arp filter OUTPUT arp htype 1 arp hlen 6 arp plen 4 arp daddr ip 10.2.22.0/24 counter arp daddr ip set 10.2.22.1 arp daddr ether set 0a:0b:0c:0d:0e:0f accept'
diff --git a/xlate-test.py b/xlate-test.py
index 6a1165986847..ddd68b91d3a7 100755
--- a/xlate-test.py
+++ b/xlate-test.py
@@ -14,7 +14,7 @@ def run_proc(args, shell = False, input = None):
     output, error = process.communicate(input)
     return (process.returncode, output, error)
 
-keywords = ("iptables-translate", "ip6tables-translate", "ebtables-translate")
+keywords = ("iptables-translate", "ip6tables-translate", "arptables-translate", "ebtables-translate")
 xtables_nft_multi = 'xtables-nft-multi'
 
 if sys.stdout.isatty():
@@ -95,6 +95,8 @@ def test_one_replay(name, sourceline, expected, result):
     fam = ""
     if srccmd.startswith("ip6"):
         fam = "ip6 "
+    elif srccmd.startswith("arp"):
+        fam = "arp "
     elif srccmd.startswith("ebt"):
         fam = "bridge "
 
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH iptables 0/4] add arptables-translate
  2023-11-03 10:23 [PATCH iptables 0/4] add arptables-translate Florian Westphal
                   ` (3 preceding siblings ...)
  2023-11-03 10:23 ` [PATCH iptables 4/4] arptables-txlate: add test cases Florian Westphal
@ 2023-11-03 11:43 ` Pablo Neira Ayuso
  4 siblings, 0 replies; 16+ messages in thread
From: Pablo Neira Ayuso @ 2023-11-03 11:43 UTC (permalink / raw)
  To: Florian Westphal; +Cc: netfilter-devel

On Fri, Nov 03, 2023 at 11:23:22AM +0100, Florian Westphal wrote:
> iptables-nft lacks a translate variant for arptables.
> 
> Add it.  First patch fixes a bug in existing arptables-nft,
> second patch adds missing mask matching.
> Patch 3 is the main arptables-translate support.
> 
> Last patch adds a few test cases.

Thanks a lot for working on this, this has been a long overdue.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH iptables 1/4] arptables-nft: use ARPT_INV flags consistently
  2023-11-03 10:23 ` [PATCH iptables 1/4] arptables-nft: use ARPT_INV flags consistently Florian Westphal
@ 2023-11-03 15:56   ` Phil Sutter
  2023-11-03 16:01     ` Florian Westphal
  0 siblings, 1 reply; 16+ messages in thread
From: Phil Sutter @ 2023-11-03 15:56 UTC (permalink / raw)
  To: Florian Westphal; +Cc: netfilter-devel

On Fri, Nov 03, 2023 at 11:23:23AM +0100, Florian Westphal wrote:
> These values are not always interchangeable, e.g.:
> 
> define IPT_INV_SRCDEVADDR	0x0080
> but:
> define ARPT_INV_SRCDEVADDR	0x0010
> 
> as these flags can be tested by libarp_foo.so such
> checks can yield incorrect results.

Hmm. This is a partial revert of 44457c0805905 ("xtables-arp: Don't use
ARPT_INV_*") and therefore very likely incomplete - e.g. it does not
reinstate ipt_to_arpt_flags() which was used in nft_arp_parse_meta().

Above commit introduced IPT_INV_SRCDEVADDR in the first place, iptables
does not make use of it.

A revert of that commit requires a thorough review of later changes in
arptables code as it may have allowed for some code-sharing which is no
longer possible then. So please hold back with this a bit, I'll check if
any follow-ups are required.

Thanks, Phil

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH iptables 1/4] arptables-nft: use ARPT_INV flags consistently
  2023-11-03 15:56   ` Phil Sutter
@ 2023-11-03 16:01     ` Florian Westphal
  2023-11-03 16:18       ` Phil Sutter
  0 siblings, 1 reply; 16+ messages in thread
From: Florian Westphal @ 2023-11-03 16:01 UTC (permalink / raw)
  To: Phil Sutter, Florian Westphal, netfilter-devel

Phil Sutter <phil@nwl.cc> wrote:
> Hmm. This is a partial revert of 44457c0805905 ("xtables-arp: Don't use
> ARPT_INV_*") and therefore very likely incomplete - e.g. it does not
> reinstate ipt_to_arpt_flags() which was used in nft_arp_parse_meta().
> 
> Above commit introduced IPT_INV_SRCDEVADDR in the first place, iptables
> does not make use of it.
> 
> A revert of that commit requires a thorough review of later changes in
> arptables code as it may have allowed for some code-sharing which is no
> longer possible then. So please hold back with this a bit, I'll check if
> any follow-ups are required.

Well, in that case it might be better to convert libarpt_mangle.c
AND remove all of the ARTP_INV?

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH iptables 1/4] arptables-nft: use ARPT_INV flags consistently
  2023-11-03 16:01     ` Florian Westphal
@ 2023-11-03 16:18       ` Phil Sutter
  2023-11-03 16:35         ` Florian Westphal
  0 siblings, 1 reply; 16+ messages in thread
From: Phil Sutter @ 2023-11-03 16:18 UTC (permalink / raw)
  To: Florian Westphal; +Cc: netfilter-devel

On Fri, Nov 03, 2023 at 05:01:29PM +0100, Florian Westphal wrote:
> Phil Sutter <phil@nwl.cc> wrote:
> > Hmm. This is a partial revert of 44457c0805905 ("xtables-arp: Don't use
> > ARPT_INV_*") and therefore very likely incomplete - e.g. it does not
> > reinstate ipt_to_arpt_flags() which was used in nft_arp_parse_meta().
> > 
> > Above commit introduced IPT_INV_SRCDEVADDR in the first place, iptables
> > does not make use of it.
> > 
> > A revert of that commit requires a thorough review of later changes in
> > arptables code as it may have allowed for some code-sharing which is no
> > longer possible then. So please hold back with this a bit, I'll check if
> > any follow-ups are required.
> 
> Well, in that case it might be better to convert libarpt_mangle.c
> AND remove all of the ARTP_INV?

Indeed, I broke the checks for ARPT_INV_ARPHLN in there. That needs a
fix either way.

The ARPT_INV_* defines are part of UAPI. They can't be removed without
breaking (or also converting?) legacy arptables. Either way, we're
breaking third-party arptables DSOs using them. Right now, they are only
broken with arptables-nft. No idea if such DSOs exist, but if
compatibility is to be taken seriously, there's no way around reverting
above commit (and reintroducing do_commandarp() or at least a wrapper
around the shared do_parse()).

Cheers, Phil

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH iptables] arptables-nft: remove ARPT_INV flags usage
  2023-11-03 16:35         ` Florian Westphal
@ 2023-11-03 16:33           ` Florian Westphal
  2023-11-03 20:48             ` Phil Sutter
  2023-11-03 16:55           ` [PATCH iptables 1/4] arptables-nft: use ARPT_INV flags consistently Phil Sutter
  1 sibling, 1 reply; 16+ messages in thread
From: Florian Westphal @ 2023-11-03 16:33 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Florian Westphal

ARPT_ and IPT_INV flags are not interchangeable, e.g.:
define IPT_INV_SRCDEVADDR	0x0080
define ARPT_INV_SRCDEVADDR	0x0010

as these flags can be tested by libarp_foo.so such checks can yield
incorrect results.

Because arptables-nft uses existing code, e.g. xt_mark, it makes
sense to unify this completely by converting the last users of
ARPT_INV_ constants.

Note that arptables-legacy does not do run-time module loading via
dlopen(). Functionaliy implemented by "extensions" in the
arptables-legacy git tree are built-in, so this doesn't break
arptables-legacy binaries.

Fixes: 44457c080590 ("xtables-arp: Don't use ARPT_INV_*")
Signed-off-by: Florian Westphal <fw@strlen.de>
---
 extensions/libarpt_mangle.c | 4 ++--
 iptables/nft-arp.c          | 2 +-
 iptables/xshared.h          | 4 +++-
 3 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/extensions/libarpt_mangle.c b/extensions/libarpt_mangle.c
index 765edf34781f..a846e97ec8f2 100644
--- a/extensions/libarpt_mangle.c
+++ b/extensions/libarpt_mangle.c
@@ -77,7 +77,7 @@ arpmangle_parse(int c, char **argv, int invert, unsigned int *flags,
 		if (e->arp.arhln_mask == 0)
 			xtables_error(PARAMETER_PROBLEM,
 				      "no --h-length defined");
-		if (e->arp.invflags & ARPT_INV_ARPHLN)
+		if (e->arp.invflags & IPT_INV_ARPHLN)
 			xtables_error(PARAMETER_PROBLEM,
 				      "! --h-length not allowed for "
 				      "--mangle-mac-s");
@@ -95,7 +95,7 @@ arpmangle_parse(int c, char **argv, int invert, unsigned int *flags,
 		if (e->arp.arhln_mask == 0)
 			xtables_error(PARAMETER_PROBLEM,
 				      "no --h-length defined");
-		if (e->arp.invflags & ARPT_INV_ARPHLN)
+		if (e->arp.invflags & IPT_INV_ARPHLN)
 			xtables_error(PARAMETER_PROBLEM,
 				      "! hln not allowed for --mangle-mac-d");
 		if (e->arp.arhln != 6)
diff --git a/iptables/nft-arp.c b/iptables/nft-arp.c
index aed39ebdd516..535dd6b83237 100644
--- a/iptables/nft-arp.c
+++ b/iptables/nft-arp.c
@@ -490,7 +490,7 @@ static void nft_arp_post_parse(int command,
 					 &args->d.naddrs);
 
 	if ((args->s.naddrs > 1 || args->d.naddrs > 1) &&
-	    (cs->arp.arp.invflags & (ARPT_INV_SRCIP | ARPT_INV_TGTIP)))
+	    (cs->arp.arp.invflags & (IPT_INV_SRCIP | IPT_INV_DSTIP)))
 		xtables_error(PARAMETER_PROBLEM,
 			      "! not allowed with multiple"
 			      " source or destination IP addresses");
diff --git a/iptables/xshared.h b/iptables/xshared.h
index a200e0d620ad..5586385456a4 100644
--- a/iptables/xshared.h
+++ b/iptables/xshared.h
@@ -80,7 +80,9 @@ struct xtables_target;
 #define ARPT_OPTSTRING	OPTSTRING_COMMON "R:S::" "h::l:nvx" /* "m:" */
 #define EBT_OPTSTRING	OPTSTRING_COMMON "hv"
 
-/* define invflags which won't collide with IPT ones */
+/* define invflags which won't collide with IPT ones.
+ * arptables-nft does NOT use the legacy ARPT_INV_* defines.
+ */
 #define IPT_INV_SRCDEVADDR	0x0080
 #define IPT_INV_TGTDEVADDR	0x0100
 #define IPT_INV_ARPHLN		0x0200
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH iptables 1/4] arptables-nft: use ARPT_INV flags consistently
  2023-11-03 16:18       ` Phil Sutter
@ 2023-11-03 16:35         ` Florian Westphal
  2023-11-03 16:33           ` [PATCH iptables] arptables-nft: remove ARPT_INV flags usage Florian Westphal
  2023-11-03 16:55           ` [PATCH iptables 1/4] arptables-nft: use ARPT_INV flags consistently Phil Sutter
  0 siblings, 2 replies; 16+ messages in thread
From: Florian Westphal @ 2023-11-03 16:35 UTC (permalink / raw)
  To: Phil Sutter, Florian Westphal, netfilter-devel

Phil Sutter <phil@nwl.cc> wrote:
> Indeed, I broke the checks for ARPT_INV_ARPHLN in there. That needs a
> fix either way.
> 
> The ARPT_INV_* defines are part of UAPI. They can't be removed without
> breaking (or also converting?) legacy arptables.

Its just a cached header.

> Either way, we're
> breaking third-party arptables DSOs using them. Right now, they are only
> broken with arptables-nft. No idea if such DSOs exist, but if
> compatibility is to be taken seriously, there's no way around reverting
> above commit (and reintroducing do_commandarp() or at least a wrapper
> around the shared do_parse()).

arptables-legacy doesn't support runtime extension loading.

I'll post a patch to convert libarpt_mangle.c.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH iptables 1/4] arptables-nft: use ARPT_INV flags consistently
  2023-11-03 16:35         ` Florian Westphal
  2023-11-03 16:33           ` [PATCH iptables] arptables-nft: remove ARPT_INV flags usage Florian Westphal
@ 2023-11-03 16:55           ` Phil Sutter
  1 sibling, 0 replies; 16+ messages in thread
From: Phil Sutter @ 2023-11-03 16:55 UTC (permalink / raw)
  To: Florian Westphal; +Cc: netfilter-devel

On Fri, Nov 03, 2023 at 05:35:19PM +0100, Florian Westphal wrote:
> Phil Sutter <phil@nwl.cc> wrote:
> > Indeed, I broke the checks for ARPT_INV_ARPHLN in there. That needs a
> > fix either way.
> > 
> > The ARPT_INV_* defines are part of UAPI. They can't be removed without
> > breaking (or also converting?) legacy arptables.
> 
> Its just a cached header.

Ah, you mean dropping them locally just to prevent reuse. Yeah, why not.

> > Either way, we're
> > breaking third-party arptables DSOs using them. Right now, they are only
> > broken with arptables-nft. No idea if such DSOs exist, but if
> > compatibility is to be taken seriously, there's no way around reverting
> > above commit (and reintroducing do_commandarp() or at least a wrapper
> > around the shared do_parse()).
> 
> arptables-legacy doesn't support runtime extension loading.

Ah, that's great news!

> I'll post a patch to convert libarpt_mangle.c.

Cool, thanks!

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH iptables] arptables-nft: remove ARPT_INV flags usage
  2023-11-03 16:33           ` [PATCH iptables] arptables-nft: remove ARPT_INV flags usage Florian Westphal
@ 2023-11-03 20:48             ` Phil Sutter
  0 siblings, 0 replies; 16+ messages in thread
From: Phil Sutter @ 2023-11-03 20:48 UTC (permalink / raw)
  To: Florian Westphal; +Cc: netfilter-devel

On Fri, Nov 03, 2023 at 05:33:22PM +0100, Florian Westphal wrote:
> ARPT_ and IPT_INV flags are not interchangeable, e.g.:
> define IPT_INV_SRCDEVADDR	0x0080
> define ARPT_INV_SRCDEVADDR	0x0010
> 
> as these flags can be tested by libarp_foo.so such checks can yield
> incorrect results.
> 
> Because arptables-nft uses existing code, e.g. xt_mark, it makes
> sense to unify this completely by converting the last users of
> ARPT_INV_ constants.
> 
> Note that arptables-legacy does not do run-time module loading via
> dlopen(). Functionaliy implemented by "extensions" in the
> arptables-legacy git tree are built-in, so this doesn't break
> arptables-legacy binaries.
> 
> Fixes: 44457c080590 ("xtables-arp: Don't use ARPT_INV_*")
> Signed-off-by: Florian Westphal <fw@strlen.de>

Patch applied, thanks!

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH iptables 2/4] nft-arp: add missing mask support
  2023-11-03 10:23 ` [PATCH iptables 2/4] nft-arp: add missing mask support Florian Westphal
@ 2023-11-03 20:49   ` Phil Sutter
  2023-11-03 21:05     ` Phil Sutter
  0 siblings, 1 reply; 16+ messages in thread
From: Phil Sutter @ 2023-11-03 20:49 UTC (permalink / raw)
  To: Florian Westphal; +Cc: netfilter-devel

On Fri, Nov 03, 2023 at 11:23:24AM +0100, Florian Westphal wrote:
> arptables-legacy supports masks for --h-type, --opcode
> and --proto-type, but arptables-nft did not.
> 
> Add this.
> 
> Signed-off-by: Florian Westphal <fw@strlen.de>

This does not apply without patch 1. Could you please rebase?

Thanks, Phil

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH iptables 3/4] nft-arp: add arptables-translate
  2023-11-03 10:23 ` [PATCH iptables 3/4] nft-arp: add arptables-translate Florian Westphal
@ 2023-11-03 20:55   ` Phil Sutter
  0 siblings, 0 replies; 16+ messages in thread
From: Phil Sutter @ 2023-11-03 20:55 UTC (permalink / raw)
  To: Florian Westphal; +Cc: netfilter-devel

On Fri, Nov 03, 2023 at 11:23:25AM +0100, Florian Westphal wrote:
> Signed-off-by: Florian Westphal <fw@strlen.de>
> ---
>  extensions/libarpt_mangle.c  |  47 +++++++++++
>  iptables/nft-arp.c           | 153 +++++++++++++++++++++++++++++++++++
>  iptables/xtables-multi.h     |   1 +
>  iptables/xtables-nft-multi.c |   1 +
>  iptables/xtables-translate.c |  35 +++++++-
>  5 files changed, 236 insertions(+), 1 deletion(-)

This misses an update to libxt_MARK.c: The contained arptables target
does not have an xlate callback (though I guess the existing
mark_tg_xlate should serve as-is).

Cheers, Phil

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH iptables 2/4] nft-arp: add missing mask support
  2023-11-03 20:49   ` Phil Sutter
@ 2023-11-03 21:05     ` Phil Sutter
  0 siblings, 0 replies; 16+ messages in thread
From: Phil Sutter @ 2023-11-03 21:05 UTC (permalink / raw)
  To: Florian Westphal, netfilter-devel

On Fri, Nov 03, 2023 at 09:49:18PM +0100, Phil Sutter wrote:
> On Fri, Nov 03, 2023 at 11:23:24AM +0100, Florian Westphal wrote:
> > arptables-legacy supports masks for --h-type, --opcode
> > and --proto-type, but arptables-nft did not.
> > 
> > Add this.
> > 
> > Signed-off-by: Florian Westphal <fw@strlen.de>
> 
> This does not apply without patch 1. Could you please rebase?

A test would be good, too. Something like:

| --h-length=6/0xffff --opcode=1/255 --h-type=1/0x00ff --proto-type=0x800/0xff00;--h-length=6/65535 --opcode=1/255 --h-type=1/255 --proto-type=0x800/0xff00=;OK

appended to extensions/libarpt_standard.t?

I notice that number bases expected on input and used on output don't
match, this could be a problem in 'arptables-save | arptables-restore'.

Cheers, Phil

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2023-11-03 21:34 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-11-03 10:23 [PATCH iptables 0/4] add arptables-translate Florian Westphal
2023-11-03 10:23 ` [PATCH iptables 1/4] arptables-nft: use ARPT_INV flags consistently Florian Westphal
2023-11-03 15:56   ` Phil Sutter
2023-11-03 16:01     ` Florian Westphal
2023-11-03 16:18       ` Phil Sutter
2023-11-03 16:35         ` Florian Westphal
2023-11-03 16:33           ` [PATCH iptables] arptables-nft: remove ARPT_INV flags usage Florian Westphal
2023-11-03 20:48             ` Phil Sutter
2023-11-03 16:55           ` [PATCH iptables 1/4] arptables-nft: use ARPT_INV flags consistently Phil Sutter
2023-11-03 10:23 ` [PATCH iptables 2/4] nft-arp: add missing mask support Florian Westphal
2023-11-03 20:49   ` Phil Sutter
2023-11-03 21:05     ` Phil Sutter
2023-11-03 10:23 ` [PATCH iptables 3/4] nft-arp: add arptables-translate Florian Westphal
2023-11-03 20:55   ` Phil Sutter
2023-11-03 10:23 ` [PATCH iptables 4/4] arptables-txlate: add test cases Florian Westphal
2023-11-03 11:43 ` [PATCH iptables 0/4] add arptables-translate Pablo Neira Ayuso

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.