summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJo-Philipp Wich2022-04-02 18:27:25 +0000
committerJo-Philipp Wich2022-04-02 18:27:25 +0000
commita3788839d61742799b6c62f2d8790c464b7374fc (patch)
tree1faf6c7af6145f5491f609f6f09af15a0b3e3579
parent11feddff95a47f292d84784112a71b69cfa951b6 (diff)
downloadfirewall4-a3788839d61742799b6c62f2d8790c464b7374fc.tar.gz
fw4: fix emitting family specific redirect rules without any addrs
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
-rw-r--r--root/usr/share/ucode/fw4.uc10
-rw-r--r--tests/03_rules/07_redirect24
2 files changed, 31 insertions, 3 deletions
diff --git a/root/usr/share/ucode/fw4.uc b/root/usr/share/ucode/fw4.uc
index 8e38a5c..0659af6 100644
--- a/root/usr/share/ucode/fw4.uc
+++ b/root/usr/share/ucode/fw4.uc
@@ -2830,8 +2830,12 @@ return {
if (length(rip[0]) > 1 || length(rip[1]) > 1)
this.warn_section(data, "specifies multiple rewrite addresses, using only first one");
+ let has_ip4_addr = length(sip[0]) || length(dip[0]) || length(rip[0]),
+ has_ip6_addr = length(sip[1]) || length(dip[1]) || length(rip[1]),
+ has_any_addr = has_ip4_addr || has_ip6_addr;
+
/* check if there's no AF specific bits, in this case we can do an AF agnostic rule */
- if (!family && !length(sip[0]) && !length(sip[1]) && !length(dip[0]) && !length(dip[1]) && !length(rip[0]) && !length(rip[1])) {
+ if (!family && !has_any_addr) {
/* for backwards compatibility, treat unspecified family as IPv4 unless user explicitly requested any (0) */
if (family == null)
family = 4;
@@ -2841,13 +2845,13 @@ return {
/* we need to emit one or two AF specific rules */
else {
- if ((!family || family == 4) && (length(sip[0]) || length(dip[0]) || length(rip[0]))) {
+ if ((!family || family == 4) && (!has_any_addr || has_ip4_addr)) {
for (let saddrs in subnets_group_by_masking(sip[0]))
for (let daddrs in subnets_group_by_masking(dip[0]))
add_rule(4, proto, saddrs, daddrs, rip[0], sport, dport, rport, ipset, redir);
}
- if ((!family || family == 6) && (length(sip[1]) || length(dip[1]) || length(rip[1]))) {
+ if ((!family || family == 6) && (!has_any_addr || has_ip6_addr)) {
for (let saddrs in subnets_group_by_masking(sip[1]))
for (let daddrs in subnets_group_by_masking(dip[1]))
add_rule(6, proto, saddrs, daddrs, rip[1], sport, dport, rport, ipset, redir);
diff --git a/tests/03_rules/07_redirect b/tests/03_rules/07_redirect
index f9292ea..90b845b 100644
--- a/tests/03_rules/07_redirect
+++ b/tests/03_rules/07_redirect
@@ -97,6 +97,28 @@ Test various address selection rules in redirect rules.
"dest_ip": "2001:db8:1000:1::1234",
"dest_port": "25",
"target": "dnat"
+ },
+ {
+ ".description": "Ensure that family restricted redirect rules work properly",
+ "name": "Redirect test #7",
+ "family": "ipv4",
+ "src": "wan",
+ "dest": "lan",
+ "proto": "tcp",
+ "src_dport": "26",
+ "dest_port": "26",
+ "target": "dnat"
+ },
+ {
+ ".description": "Ensure that family restricted redirect rules work properly",
+ "name": "Redirect test #8",
+ "family": "ipv6",
+ "src": "wan",
+ "dest": "lan",
+ "proto": "tcp",
+ "src_dport": "27",
+ "dest_port": "27",
+ "target": "dnat"
}
]
}
@@ -268,6 +290,8 @@ table inet fw4 {
meta nfproto ipv4 tcp dport 22 counter dnat 192.168.26.100:22 comment "!fw4: Redirect test #3"
meta nfproto ipv4 tcp dport 23 counter dnat 192.168.26.100:23 comment "!fw4: Redirect test #4"
meta nfproto ipv6 tcp dport 25 counter dnat [2001:db8:1000:1::1234]:25 comment "!fw4: Redirect test #6"
+ meta nfproto ipv4 tcp dport 26 counter redirect to 26 comment "!fw4: Redirect test #7"
+ meta nfproto ipv6 tcp dport 27 counter redirect to 27 comment "!fw4: Redirect test #8"
}
chain srcnat_wan {