git: 2872268c7f6d - main - ipfw: treat ipv6 address with zero mask as 'any'
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 17 May 2026 10:15:19 UTC
The branch main has been updated by ae:
URL: https://cgit.FreeBSD.org/src/commit/?id=2872268c7f6d473aae9b02ebb5d2c24fc2cff9b1
commit 2872268c7f6d473aae9b02ebb5d2c24fc2cff9b1
Author: Andrey V. Elsukov <ae@FreeBSD.org>
AuthorDate: 2026-05-17 10:12:20 +0000
Commit: Andrey V. Elsukov <ae@FreeBSD.org>
CommitDate: 2026-05-17 10:12:20 +0000
ipfw: treat ipv6 address with zero mask as 'any'
Make the behaviour similar for both IPv4 and IPv6. Also add
the corresponding tests.
PR: 294733
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D56618
---
sbin/ipfw/ipfw2.c | 7 ++++---
sbin/ipfw/ipv6.c | 11 +++++++----
sbin/ipfw/tests/test_add_rule.py | 24 ++++++++++++++++++++++++
tests/atf_python/sys/netpfil/ipfw/insns.py | 2 ++
4 files changed, 37 insertions(+), 7 deletions(-)
diff --git a/sbin/ipfw/ipfw2.c b/sbin/ipfw/ipfw2.c
index 06a1ee937cd7..c67eb6618c59 100644
--- a/sbin/ipfw/ipfw2.c
+++ b/sbin/ipfw/ipfw2.c
@@ -3595,12 +3595,13 @@ fill_ip(ipfw_insn_ip *cmd, char *av, int cblen, struct tidx *tstate)
* list unless it is the only item, in which case we
* report an error.
*/
- if (cmd->o.len & F_NOT) { /* "not any" never matches */
- if (av == NULL && len == 0) /* only this entry */
+ if (av == NULL && len == 0) {
+ if (cmd->o.len & F_NOT) /* "not any" never matches */
errx(EX_DATAERR, "not any never matches");
+ return;
}
/* else do nothing and skip this entry */
- return;
+ continue;
}
/* A single IP can be stored in an optimized format */
if (d[1] == (uint32_t)~0 && av == NULL && len == 0) {
diff --git a/sbin/ipfw/ipv6.c b/sbin/ipfw/ipv6.c
index e6eb07af26dc..f34a08bb6f52 100644
--- a/sbin/ipfw/ipv6.c
+++ b/sbin/ipfw/ipv6.c
@@ -396,8 +396,6 @@ fill_ip6(ipfw_insn_ip6 *cmd, char *av, int cblen, struct tidx *tstate)
n2mask(&d[1], masklen);
}
- APPLY_MASK(d, &d[1]); /* mask base address with mask */
-
av = q;
/* Check this entry */
@@ -408,11 +406,16 @@ fill_ip6(ipfw_insn_ip6 *cmd, char *av, int cblen, struct tidx *tstate)
* list unless it is the only item, in which case we
* report an error.
*/
- if (cmd->o.len & F_NOT && av == NULL && len == 0)
- errx(EX_DATAERR, "not any never matches");
+ if (av == NULL && len == 0) {
+ if (cmd->o.len & F_NOT)
+ errx(EX_DATAERR, "not any never matches");
+ return (1);
+ }
continue;
}
+ APPLY_MASK(d, &d[1]); /* mask base address with mask */
+
/*
* A single IP can be stored alone
*/
diff --git a/sbin/ipfw/tests/test_add_rule.py b/sbin/ipfw/tests/test_add_rule.py
index 4360c5f87c15..ed565f0e7c68 100755
--- a/sbin/ipfw/tests/test_add_rule.py
+++ b/sbin/ipfw/tests/test_add_rule.py
@@ -135,6 +135,30 @@ class TestAddRule(BaseTest):
},
id="test_rulenum",
),
+ pytest.param(
+ {
+ "in": "add allow ip4 from 0.0.0.0/0 to 192.0.2.1/0",
+ "out": {
+ "insns": [
+ InsnEmpty(IpFwOpcode.O_IP4),
+ InsnEmpty(IpFwOpcode.O_ACCEPT),
+ ],
+ },
+ },
+ id="test_zero_addrmask4",
+ ),
+ pytest.param(
+ {
+ "in": "add allow ip6 from ::/0 to 2001:DB8::/0",
+ "out": {
+ "insns": [
+ InsnEmpty(IpFwOpcode.O_IP6),
+ InsnEmpty(IpFwOpcode.O_ACCEPT),
+ ],
+ },
+ },
+ id="test_zero_addrmask6",
+ ),
pytest.param(
{
"in": "add allow ip from { 1.2.3.4 or 2.3.4.5 } to any",
diff --git a/tests/atf_python/sys/netpfil/ipfw/insns.py b/tests/atf_python/sys/netpfil/ipfw/insns.py
index dbb9af659794..c5f729ac4d63 100644
--- a/tests/atf_python/sys/netpfil/ipfw/insns.py
+++ b/tests/atf_python/sys/netpfil/ipfw/insns.py
@@ -682,6 +682,8 @@ insn_attrs = prepare_attrs_map(
AttrDescr(IpFwOpcode.O_NOP, InsnComment),
+ AttrDescr(IpFwOpcode.O_IP4, InsnEmpty),
+ AttrDescr(IpFwOpcode.O_IP6, InsnEmpty),
AttrDescr(IpFwOpcode.O_PROTO, InsnProto),
AttrDescr(IpFwOpcode.O_PROB, InsnProb),
AttrDescr(IpFwOpcode.O_IP_DST_ME, InsnEmpty),