* [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, ®);
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, ®);
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, ®);
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* 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* 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
* [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] 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 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
* [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, ®);
+ if (fw->arp.arhrd_mask != 0xffff)
+ add_bitwise_u16(h, r, fw->arp.arhrd_mask, 0, 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, ®);
+ if (fw->arp.arpro_mask != 0xffff)
+ add_bitwise_u16(h, r, fw->arp.arpro_mask, 0, 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, ®);
+ if (fw->arp.arhln_mask != 255)
+ add_bitwise(h, r, &fw->arp.arhln_mask, 1, 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, ®);
+ if (fw->arp.arpop_mask != 0xffff)
+ add_bitwise_u16(h, r, fw->arp.arpop_mask, 0, 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* 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 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
* [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* 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
* [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