project/firewall4.git
5 months agofw4: skip not existing netdev names in flowtable device list master
Jo-Philipp Wich [Mon, 3 Jun 2024 14:49:40 +0000 (16:49 +0200)]
fw4: skip not existing netdev names in flowtable device list

In case interface configurations are present which refer to not existing
network devices, such device names might end up in the flowtable list,
leading to `No such file or directory` errors when attempting to load
the resulting ruleset.

Solve this issue by testing for each netdev name whether it refers to
an existing device.

Fixes: e009588 ("fw4: do not add physical devices for soft offload")
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
5 months agofw4: do not add physical devices for soft offload
Jo-Philipp Wich [Fri, 15 Mar 2024 08:49:33 +0000 (10:49 +0200)]
fw4: do not add physical devices for soft offload

Let kernel heuristics take care of offloading decapsulation.

When software flow offloading is requested, avoid manually resolving and
adding lower physical devices to the flow table in order to let kernel
heuristics deal with the proper offloading en/decapsulation.

Fixes: https://github.com/openwrt/openwrt/issues/13410
Ref: https://github.com/openwrt/openwrt/issues/10224
Submitted-by: Andris PE <neandris@gmail.com>
[refactor code, reword commit message]
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
6 months agofw4: substitute double quotes in strings
Jo-Philipp Wich [Tue, 21 May 2024 06:54:02 +0000 (08:54 +0200)]
fw4: substitute double quotes in strings

The nftables parser has no concept of escape characters in quoted strings,
nor does it support alternative quoting styles so it is currently
impossible to emit double quoted strings containing double quotes.

This could cause nftables to choke on generated rulesets that contain
strings with embedded quotes, e.g. within firewall rule comments.

Since firewall3 (iptables based) historically allowed arbitrary characters
in comments and since we want to stay backwards compatible with existing
uci configurations we can not restrict the allowed input values either.

Work around the issue by substituting all double quotes with single quotes
when quoting strings for interpolation into the ruleset.

Fixes: https://github.com/openwrt/luci/issues/7091
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
12 months agoruleset: apply egress MSS fixup later to apply final MTU before wire
Andris PE [Wed, 21 Jun 2023 10:06:24 +0000 (13:06 +0300)]
ruleset: apply egress MSS fixup later to apply final MTU before wire

Reduce scope of MSS fixup to TCP SYN packets only and relocate the fixing
of egress MSS to the mangle/postrouting chain in order to properly apply
final known MTU size.

Fixes: openwrt/openwrt#12112
Signed-off-by: Andris PE <neandris@gmail.com>
[fix S-o-b tag, fix commit author, reword commit message]
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
12 months agoruleset: do not emit redundant drop invalid rules
Andris PE [Sat, 14 Oct 2023 09:51:00 +0000 (12:51 +0300)]
ruleset: do not emit redundant drop invalid rules

The wan interface drop rule unnecessarily persists when invalid state
is dropped globally and the rule cannot catch anything at all, so remove
it as the effect is achieved by default and to global extent.

Fixes: 119ee1a ("ruleset: drop ctstate invalid traffic for masq-enabled zones")
Signed-off-by: Andris PE <neandris@gmail.com>
[fix S-o-b tag, fix commit author, reword commit subject and message]
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
12 months agotests: adjust zone log limit testcases
Jo-Philipp Wich [Fri, 3 Nov 2023 13:14:15 +0000 (14:14 +0100)]
tests: adjust zone log limit testcases

Fix testcase failure introduced by a previous commit.

Fixes: a5553da ("ruleset: reduce ksoftirqd load by refering to looopback by numeric id")
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
12 months agoruleset: reduce ksoftirqd load by refering to looopback by numeric id
Andris PE [Tue, 19 Sep 2023 15:23:59 +0000 (18:23 +0300)]
ruleset: reduce ksoftirqd load by refering to looopback by numeric id

Reduce ksoftirq load by half using more efficient reference to loopback
which always has index equal to one.

Should help a lot with openwrt/openwrt#12914, openwrt/openwrt#12121 and
similar iperf3 cases clamping against 100% CPU usage.

Signed-off-by: Andris PE <neandris@gmail.com>
[fix S-o-b tag, fix commit author, rewrap commit message]
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
12 months agoruleset: dispatch ct states using verdict map
Andris PE [Thu, 7 Sep 2023 19:04:35 +0000 (22:04 +0300)]
ruleset: dispatch ct states using verdict map

In case the dropping of invalid conntrack states is enabled, using a verdict
map allows us to use only one rule instead of two, lowering the initial rule
match overhead.

Signed-off-by: Andris PE <neandris@gmail.com>
[whitespace cleanup, rebase, extend commit subject and message]
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
12 months agoRevert "ruleset: dispatch ct states using verdict map"
Jo-Philipp Wich [Fri, 3 Nov 2023 13:09:12 +0000 (14:09 +0100)]
Revert "ruleset: dispatch ct states using verdict map"

This reverts commit 785798c8fd72ff3c4c8940922173290bb25bc18e.

Revert commit due to bad commit metadata.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
12 months agoruleset: dispatch ct states using verdict map
User User-User [Thu, 7 Sep 2023 19:04:35 +0000 (22:04 +0300)]
ruleset: dispatch ct states using verdict map

In case the dropping of invalid conntrack states is enabled, using a verdict
map allows us to use only one rule instead of two, lowering the initial rule
match overhead.

Signed-off-by: Andris PE <neandris@gmail.com>
[whitespace cleanup, rebase, extend commit subject and message]
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
12 months agofw4: add log_limit to rules and redirects
Luiz Angelo Daros de Luca [Tue, 1 Aug 2023 19:51:58 +0000 (16:51 -0300)]
fw4: add log_limit to rules and redirects

Just like zone log_limit, now you can specify a different log limit to a
single rule or redirect.

Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
[whitespace cleanup, properly format limit expressions]
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
12 months agofw4: add support for zone log_limit
Luiz Angelo Daros de Luca [Mon, 31 Jul 2023 22:18:30 +0000 (19:18 -0300)]
fw4: add support for zone log_limit

It is equivalent to the fw3 feature, affecting not accepted packets
and rules explicitily setting the log property.

Input rules not associated with a zone will not have log_limit.
Forward rules will use src zone log_limit or, if missing, dest zone
log_limit.

Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
[properly handle null zone references, whitespace and indentation cleanup,
 testcase cleanup, slight code simplification, use dot for named limit,
 properly format limit expressions]
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
12 months agofw4: pass zone to templates whenever possible
Luiz Angelo Daros de Luca [Mon, 31 Jul 2023 21:24:11 +0000 (18:24 -0300)]
fw4: pass zone to templates whenever possible

For those cases where the rule, redirect or .... are related to
a zone, pass it to the template.

Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
[whitespace cleanup]
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
13 months agofw4: perform strict validation of zone and set names
Jo-Philipp Wich [Thu, 12 Oct 2023 07:33:32 +0000 (09:33 +0200)]
fw4: perform strict validation of zone and set names

The nft syntax grammar requires unquoted chain and set names which imposes
certain format restrictions. Introduce a new `identifier` datatype and use
it for validating set and zone names.

Fixes: https://github.com/openwrt/luci/issues/6633
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
14 months agofw4: remove special cases around hw flow offloading
Felix Fietkau [Fri, 1 Sep 2023 11:35:20 +0000 (13:35 +0200)]
fw4: remove special cases around hw flow offloading

Now that a mix of hw and non-hw offload devices is supported in the kernel,
simply put all devices in a hw offload table if enabled in the config.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
15 months agofw4: fix another instance of invalid rule jump targets
Jo-Philipp Wich [Fri, 11 Aug 2023 00:11:15 +0000 (02:11 +0200)]
fw4: fix another instance of invalid rule jump targets

Ensure that action-less rules don't jump anywhere, we still emitted an
invalid jump for destination (outbound) rules.

Ref: https://github.com/openwrt/firewall4/issues/5#issuecomment-1673574359
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
15 months agofw4: avoid emitting invalid rule jump targets
Jo-Philipp Wich [Fri, 4 Aug 2023 22:46:47 +0000 (00:46 +0200)]
fw4: avoid emitting invalid rule jump targets

Avoid emitting a bogus chain jump for actionless rules bound to a
log-enabled source zone.

Fixes: https://github.com/openwrt/firewall4/issues/5
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
17 months agotests: fix expected test output
Jo-Philipp Wich [Tue, 30 May 2023 08:19:01 +0000 (10:19 +0200)]
tests: fix expected test output

A previous commit enabled flowtable counters without properly adjusting
the testcase output.

Fixes: 04a06bd ("fw4: enable flowtable counters")
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
20 months agofw4: enable flowtable counters
Felix Fietkau [Thu, 23 Mar 2023 21:01:12 +0000 (22:01 +0100)]
fw4: enable flowtable counters

This ensures that conntrack stats are updated for offloaded flows

Signed-off-by: Felix Fietkau <nbd@nbd.name>
20 months agofw4: remove accidentally committed .orig and .rej file
Felix Fietkau [Thu, 23 Mar 2023 20:56:12 +0000 (21:56 +0100)]
fw4: remove accidentally committed .orig and .rej file

Fixes: 39e8c70957c7 ("fw4: fix handling the ipset "comment" option")
Signed-off-by: Felix Fietkau <nbd@nbd.name>
21 months agofw4: fix syntax errors in ICMP type declarations
Jo-Philipp Wich [Fri, 3 Feb 2023 11:06:07 +0000 (12:06 +0100)]
fw4: fix syntax errors in ICMP type declarations

Fixes: e6e82a5 ("fw4: add further symbolic ICMP type declarations")
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
21 months agotests: add testcase for automatic includes
Jo-Philipp Wich [Fri, 3 Feb 2023 11:04:58 +0000 (12:04 +0100)]
tests: add testcase for automatic includes

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
21 months agofw4: add further symbolic ICMP type declarations
Paul D [Thu, 2 Feb 2023 16:05:36 +0000 (17:05 +0100)]
fw4: add further symbolic ICMP type declarations

Submitted-by: Paul Dee <itsascambutmailmeanyway@gmail.com>
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
21 months agofw4: fix handling the ipset "comment" option
Jo-Philipp Wich [Sat, 7 Jan 2023 16:00:18 +0000 (17:00 +0100)]
fw4: fix handling the ipset "comment" option

The comment option for ipset definitions is incorrectly declared as bool
and not actually used anywhere in the nftables output rendering.

Solve this issue by changing it to the proper "string" type and expose
the user configured comment as "comment" property in the generated nftables
output.

Also add some initial test coverage for ipset declarations to better spot
such inconsistencies in the future.

Ref: https://github.com/openwrt/luci/pull/6187#issuecomment-1374506633
Reported-by: Paul Dee <itsascambutmailmeanyway@gmail.com>
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
23 months agofw4: prevent null access when no ipsets are defined
Jo-Philipp Wich [Tue, 29 Nov 2022 10:44:15 +0000 (11:44 +0100)]
fw4: prevent null access when no ipsets are defined

When rules are configured which reference ipsets and no ipsets are declared
at all, fw4 crashed with a null reference exception while validating the
rule.

Solve the issue by using the optional chaining operator on the potentially
null filter result.

Ref: https://forum.openwrt.org/t/x/144176
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agoconfig: drop input traffic by default
Baptiste Jonglez [Wed, 2 Nov 2022 15:06:47 +0000 (16:06 +0100)]
config: drop input traffic by default

This is necessary with firewall4 to avoid a hard-to-diagnose race
condition during boot, causing DNAT rules not to be taken into account
correctly.

The root cause is that, during boot, the ruleset is mostly empty, and
interface-related rules (including DNAT rules) are added incrementally.
If a packet hits the input chain before the DNAT rules are setup, it can
create buggy conntrack entries that will persist indefinitely.

This new default should be safe because firewall4 explicitly accepts
authorized traffic and rejects the rest.  Thus, in normal operations, the
default policy is not used.

Fixes: #10749
Ref: https://github.com/openwrt/openwrt/issues/10749
Signed-off-by: Baptiste Jonglez <git@bitsofnetworks.org>
2 years agoruleset: drop ctstate invalid traffic for masq-enabled zones
Jo-Philipp Wich [Tue, 25 Oct 2022 19:03:00 +0000 (21:03 +0200)]
ruleset: drop ctstate invalid traffic for masq-enabled zones

For NAT enabled zones, stage rules to drop forwarded traffic with conntrack
state "invalid" and honor `masq_allow_invalid` option to inhibit those
rules.

This ports the corresponding firewall3 logic to firewall4.

Ref: https://forum.openwrt.org/t/x/140790
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agofw4: gracefully handle `null` return values from `fd.read("line")`
Jo-Philipp Wich [Tue, 18 Oct 2022 07:20:56 +0000 (09:20 +0200)]
fw4: gracefully handle `null` return values from `fd.read("line")`

Since ucode commit 4ae7072 "fs: use `getline()` for line wise read operations"
a call to `fs.read("line")` will yield `null` instead of an empty string when
encountering EOF, leading to an infinite loop when parsing loadfile entries.

Solve this issue by checking both for `null` and empty string return values.

Ref: https://forum.openwrt.org/t/x/139951/12
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agoruleset.uc: log forwarded traffic not matched by zone policies
Jo-Philipp Wich [Fri, 14 Oct 2022 15:56:27 +0000 (17:56 +0200)]
ruleset.uc: log forwarded traffic not matched by zone policies

When zone logging is enabled and the global forward policy set to drop or
reject, then stage an extra logging rule to log traffic that will be
dropped by subsequent rules or the global reject policy.

Ref: https://forum.openwrt.org/t/x/137182/4
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agomain.uc: reintroduce set reload restriction
Jo-Philipp Wich [Fri, 14 Oct 2022 15:45:08 +0000 (17:45 +0200)]
main.uc: reintroduce set reload restriction

Only reload sets which either declare a file to load or a set of static
entries in order to avoid clearing externally managed sets that might
take a long time to repopulate.

Also guard the entry file loading in order to avoid a stray warning
message.

Ref: https://forum.openwrt.org/t/x/138579/57
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agoruleset: fix emitting set_mark/set_xmark rules with masks
Jo-Philipp Wich [Fri, 14 Oct 2022 15:01:44 +0000 (17:01 +0200)]
ruleset: fix emitting set_mark/set_xmark rules with masks

Fix a bad variable access when emitting set_mark/set_xmark rules with
masks and add test coverage for the various mark target variants.

Fixes: #10965
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agoruleset: properly handle zone names starting with a digit
Jo-Philipp Wich [Wed, 5 Oct 2022 21:50:18 +0000 (23:50 +0200)]
ruleset: properly handle zone names starting with a digit

When forming the device and subnet define name, prepend zone name with
an underscore in case it starts with a digit in order to avoid generating
invalid syntax.

Ref: https://github.com/openwrt/openwrt/issues/10693
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agofw4: fix formatting of default log prefix
Jo-Philipp Wich [Wed, 5 Oct 2022 21:33:59 +0000 (23:33 +0200)]
fw4: fix formatting of default log prefix

When using the explicit or implicit rule name as default log prefix, ensure
that is followed by a colon and a space to yield properly formatted firewall
log messages.

Also align the processing logic of `option log` in `config nat` sections with
that in `config rule` and `config redirect`.

Ref: https://forum.openwrt.org/t/x/137182/8
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agomain.uc: remove uneeded/wrong set reload restrictions
Jo-Philipp Wich [Wed, 5 Oct 2022 11:23:57 +0000 (13:23 +0200)]
main.uc: remove uneeded/wrong set reload restrictions

Always reload sets, regardless of whether they contain entries or not.

Also don't require a set to define a `loadfile` option in order to get
reloaded by `fw4 reload-sets`.

Ref: https://forum.openwrt.org/t/x/138579/53
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agotests: fix testcases
Jo-Philipp Wich [Mon, 3 Oct 2022 12:26:02 +0000 (14:26 +0200)]
tests: fix testcases

Align expected output with the current implementation.

Fixes: a540f6d ("fw4: fix cosmetic issue with per-ruleset and per-table include paths")
Fixes: 145e159 ("fw4: recognize `option log` and `option counter` in `config nat` sections")
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agofw4: recognize `option log` and `option counter` in `config nat` sections
Jo-Philipp Wich [Thu, 8 Sep 2022 20:52:09 +0000 (22:52 +0200)]
fw4: recognize `option log` and `option counter` in `config nat` sections

Sections of type `nat` didn't honour the `log` and `counter` options so
far, add them in order to make those options avaialble to NAT rules as well.

Ref: https://forum.openwrt.org/t/x/136274/10
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agofw4: fall back to device if l3_device is not available in ifstatus
Jo-Philipp Wich [Thu, 8 Sep 2022 09:03:27 +0000 (11:03 +0200)]
fw4: fall back to device if l3_device is not available in ifstatus

If the l3_device ifstatus property of a referenced logical interface is
unavailable, e.g. due to the logical interface being down, no jump rules
to the related zone chains are emitted. This is a deviation from fw3 which
fell back to the l2 device value in this case.

Do the same in firewall4 to still produce matching rules in the majority
of cases, even if the l3 device ends up being something else.

Fixes: #10639
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agocli: introduce test mode and refuse firewall restart on errors
Jo-Philipp Wich [Thu, 1 Sep 2022 10:11:44 +0000 (12:11 +0200)]
cli: introduce test mode and refuse firewall restart on errors

 - Introduce a new `fw4 [-q] check` command which tests the rendered ruleset
   using nftables' --check mode. This is useful to assert complex rulesets
   using external includes for correctness.

 - Extend the `fw4 restart` command to check the rendered ruleset before
   flushing the existing ruleset.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agofw4: fix cosmetic issue with per-ruleset and per-table include paths
Jo-Philipp Wich [Thu, 1 Sep 2022 09:33:48 +0000 (11:33 +0200)]
fw4: fix cosmetic issue with per-ruleset and per-table include paths

Avoid adding a double slash to the file path, even though it is harmless.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agodoc: fix swapped include positions in nftables.d README
Jo-Philipp Wich [Thu, 1 Sep 2022 09:31:38 +0000 (11:31 +0200)]
doc: fix swapped include positions in nftables.d README

The README swapped the meaning of the `ruleset-pre`/`ruleset-post`
and `table-pre`/`table-post` include directories.

Ref: https://forum.openwrt.org/t/x/135594/174
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agofw4: support automatic includes
Jo-Philipp Wich [Thu, 11 Aug 2022 11:48:14 +0000 (13:48 +0200)]
fw4: support automatic includes

Introduce a new directory tree /usr/share/nftables.d/ which may contain
partial nftables files being included into the rendered ruleset.

The include position is derived from the file path;

 - Files in .../nftables.d/table-pre/ and .../nftables.d/table-post/ are
   included before and after the `table inet fw4 { ... }` declaration
   respectively

 - Files in .../nftables.d/ruleset-pre/ and .../nftables.d/ruleset-post/
   are included before the first chain and after the last chain
   declaration within the fw4 table respectively

 - Files in .../nftables.d/chain-pre/${chain}/ and .../chain-post/${chain}/
   are included before the first and after the last rule within the mentioned
   chain of the fw4 table respectively

Automatic includes can be disabled by setting the `auto_includes` option to
`0` in the global defaults section.

Also adjust testcases accordingly.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agofw4: honour enabled option of include sections
Jo-Philipp Wich [Mon, 8 Aug 2022 18:57:33 +0000 (20:57 +0200)]
fw4: honour enabled option of include sections

The `enabled` bool option was parsed but not acted upon. Fix the issue
by adding the appropriate return statement.

Ref: https://forum.openwrt.org/t/firewall4/113704/112
Fixes: 11256ff ("fw4: add support for configurable includes")
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agotests: add missing fs.stat) mock data for `nf_conntrack_dummy`
Jo-Philipp Wich [Mon, 8 Aug 2022 19:08:29 +0000 (21:08 +0200)]
tests: add missing fs.stat) mock data for `nf_conntrack_dummy`

Fixes: 111a7f7 ("fw4: don't inherit zone family from ct helpers")
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agofw4: don't inherit zone family from ct helpers
Stijn Tintel [Mon, 1 Aug 2022 09:40:14 +0000 (12:40 +0300)]
fw4: don't inherit zone family from ct helpers

It's perfectly valid to use a conntrack helper that only supports a
single address family in a zone where both IPv4 and IPv6 are used.
Restricting a zone to a certain family due to limitations of the
associated conntrack helpers may result in unexpected behaviour, which
in turn may have unintended security implications.

Don't inherit zone family from conntrack helper restrictions to avoid
this and add test coverage.

Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>
Acked-by: Jo-Philipp Wich <jo@mein.io>
2 years agofw4: add support for `option log` in rule and redirect sections
Jo-Philipp Wich [Fri, 17 Jun 2022 12:42:03 +0000 (14:42 +0200)]
fw4: add support for `option log` in rule and redirect sections

Sections of type `rule` and type `redirect` may now specify
`option log value` to enable logging matched traffic for the
corresponding rule/redirect.

The value may be either a string, in which case it is used as log prefix
verbatim or a boolean value (`1`, `on`, `true`, `yes`, `0`, `off`, `false`
or `no`).

In case a boolean false value is specified (the default), no logging is
performed. In case a true boolean value is specified, matched traffic is
logged and the rule's name (or uci section id i ncase the name is absent)
is used as log prefix.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Tested-by: Stijn Tintel <stijn@linux-ipv6.be>
2 years agofw4: support sets with timeout capability but without default expiry
Jo-Philipp Wich [Fri, 17 Jun 2022 08:13:34 +0000 (10:13 +0200)]
fw4: support sets with timeout capability but without default expiry

Configure the set timeout flag explicitly and do not rely on nftables
inferring it from the defualt timeout value.

This allows treating uci `option timeout 0` specially, means enabling
the timeout capability flag on a set but do not emit a `timeout`
statement.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Tested-by: Stijn Tintel <stijn@linux-ipv6.be>
2 years agotests: add test coverage for firewall includes
Jo-Philipp Wich [Wed, 15 Jun 2022 11:52:56 +0000 (13:52 +0200)]
tests: add test coverage for firewall includes

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agofw4: add support for configurable includes
Jo-Philipp Wich [Mon, 13 Jun 2022 13:49:14 +0000 (15:49 +0200)]
fw4: add support for configurable includes

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agofw4: fix crash in parse_cthelper() if no helpers are present
Jo-Philipp Wich [Mon, 13 Jun 2022 13:48:35 +0000 (15:48 +0200)]
fw4: fix crash in parse_cthelper() if no helpers are present

Properly deal with a possibly uninitialized helper object array.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agofw4: simplify `is_loopback_dev()`
Jo-Philipp Wich [Mon, 13 Jun 2022 13:23:23 +0000 (15:23 +0200)]
fw4: simplify `is_loopback_dev()`

Use `fs.readfile()` to simplify the code reading flag values from sysfs.

Also add a mock implementation of `fs.readfile()` using the same mock
data files as `fs.open()`.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agofw4: fix skipping invalid IPv6 ipset entries
Jo-Philipp Wich [Mon, 13 Jun 2022 13:21:01 +0000 (15:21 +0200)]
fw4: fix skipping invalid IPv6 ipset entries

The current code did not account for invalid IPv6 entries yielding `null`
after subnet parsing, leading to an incorrect warning about multiple entries
and a subsequent `null` access leading to a crash.

Fix the issue by ensuring that the length check expression yields `0` on
invalid inputs.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agoruleset: reorder declarations & output tweaks
Jo-Philipp Wich [Tue, 14 Jun 2022 14:23:50 +0000 (16:23 +0200)]
ruleset: reorder declarations & output tweaks

 - Omit "Set definitions" header if no sets are declared
 - Always emit ${zone}_devices and ${zone}_subnets defines, even if empty
 - Move CT helper definitions to the top
 - Move ${zone}_helper chain definitions after ${zone}_forward chain defs
 - Consistently use two line spacing for output sections

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agoruleset: reuse zone-jump.uc template for notrack and helper chain jumps
Jo-Philipp Wich [Tue, 14 Jun 2022 12:59:58 +0000 (14:59 +0200)]
ruleset: reuse zone-jump.uc template for notrack and helper chain jumps

Avoid some code-duplication by reusing the zone-jump.uc partial template
to emit the helper_* chain jump rules.

Also add some test coverage for notrack rules.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agoruleset: fix conntrack helpers
Stijn Tintel [Mon, 13 Jun 2022 15:00:26 +0000 (18:00 +0300)]
ruleset: fix conntrack helpers

In nftables, helper assignments need to be performed after the conntrack
lookup has completed. Using the raw priority results in the assignment
being done before the conntrack lookup, which breaks conntrack helpers.

Fix this by moving the jumps helper rule chains to a new toplevel
`prerouting` and the existing `output` chain respectively.

Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>
[new toplevel `prerouting` chain + reuse existing `output` chain]
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agotests: add test for zone helpers
Stijn Tintel [Mon, 13 Jun 2022 14:13:50 +0000 (17:13 +0300)]
tests: add test for zone helpers

Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>
2 years agofw4.uc: don't skip zone for unavailable helper
Stijn Tintel [Mon, 13 Jun 2022 08:05:10 +0000 (11:05 +0300)]
fw4.uc: don't skip zone for unavailable helper

Skipping a zone because a configured helper is not available is a bigger
security risk than not setting up the helper, as a zone might have
stricter settings than the defaults

Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>
2 years agofw4.uc: fix zone helper assignment
Stijn Tintel [Mon, 13 Jun 2022 07:57:29 +0000 (10:57 +0300)]
fw4.uc: fix zone helper assignment

Zone helpers are parsed as an array, so we need to loop over them to
check if they are available.

Suggested-by: Jo-Philipp Wich <jo@mein.io>
Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>
2 years agofw4: prefer /dev/stdin if available
Jo-Philipp Wich [Tue, 31 May 2022 18:55:36 +0000 (20:55 +0200)]
fw4: prefer /dev/stdin if available

The nftables executable treats `-` and `/dev/stdin` specially when processing
nft scripts from stdin; it will buffer the contents in order to be able to
print detailled error diagnostics. The `/proc/self/fd/0` path used by `fw4`
does not get this special treatment which will lead to nftables error
messages without any reported context.

Make the `fw4` executable prefer `/dev/stdin` in case it exists and fall back
to using `/proc/self/fd/0` as before.

Ref: https://github.com/openwrt/openwrt/issues/9927
Ref: https://git.openwrt.org/50bc06e774f89517f98c89c76a7626f35c3ff659
Ref: https://git.netfilter.org/nftables/tree/src/libnftables.c?h=v1.0.3#n733
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agofw4: make `fw4 restart` behavior more robust
Jo-Philipp Wich [Tue, 31 May 2022 07:36:20 +0000 (09:36 +0200)]
fw4: make `fw4 restart` behavior more robust

Start the firewall on `fw4 restart` even if it was not previously started.

Ref: #9935
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agoruleset: emit time ranges when both start and stop times are specified
Jo-Philipp Wich [Mon, 30 May 2022 21:46:48 +0000 (23:46 +0200)]
ruleset: emit time ranges when both start and stop times are specified

Instead of emitting two time matches checking the start and stop time/hour
respectively, emit a range when both are given. This also properly deals
with time of day ranges where start > stop since nft will take care of
implicitly inverting those.

Also add basic test coverage for time related matches.

Fixes: #9923
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agofw4: fix datetime parsing
Jo-Philipp Wich [Mon, 30 May 2022 21:44:34 +0000 (23:44 +0200)]
fw4: fix datetime parsing

 - Rework `parse_date()` to mirror the fw3 parsing logic which allows
   omitting each part of the timestamp except the year

 - Introduce `fw4.datestamp()` helper which formats the given timestamp
   either as datetime or date, depending on whether time information is
   present

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agoruleset: correct mangle_output chain type
Jo-Philipp Wich [Mon, 30 May 2022 18:59:27 +0000 (20:59 +0200)]
ruleset: correct mangle_output chain type

Use the `route` chain type for the `mangle_output` chain since rules in
this chain influence egress packet routing.

Fixes: #9955
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agofw4: fix logic flaw in testing hw flow offloading support
Jo-Philipp Wich [Mon, 30 May 2022 18:44:17 +0000 (20:44 +0200)]
fw4: fix logic flaw in testing hw flow offloading support

The revised logic failed to account for cases where zero offload capable
devices where resolved, in this case the capability check was not performed
at all.

Fixes: #9935
Fixes: 57984e0 ("fw4: always resolve lower flowtable devices")
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agofw4: ensure that negative bitcounts are properly translated
Jo-Philipp Wich [Mon, 30 May 2022 17:28:12 +0000 (19:28 +0200)]
fw4: ensure that negative bitcounts are properly translated

Set bits to `-1` after converting a negative count into an inverted mask,
in order to ensure that the resulting subnet list is properly grouped
and rendered later on.

Also add some minimal test coverage for this case.

Fixes: #9764
Fixes: c22eeef ("fw4: support negative CIDR bit notation")
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agofw4: fix typo in emitted set types
Jo-Philipp Wich [Mon, 30 May 2022 14:30:35 +0000 (16:30 +0200)]
fw4: fix typo in emitted set types

Fixes: #9927
Fixes: b0b8122 ("treewide: use modern syntax")
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agofw4: support negative CIDR bit notation
Jo-Philipp Wich [Fri, 20 May 2022 10:34:54 +0000 (12:34 +0200)]
fw4: support negative CIDR bit notation

Add support for CIDR notation with a negative bit count to be compatible
with firewall3.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agohotplug: reliably handle interfaces with ubus zone hints
Jo-Philipp Wich [Fri, 20 May 2022 10:12:38 +0000 (12:12 +0200)]
hotplug: reliably handle interfaces with ubus zone hints

So far, the firewall hotplug did not initiate a reload for interfaces which
are not covered in the firewall configuration but provide a zone hint in
their ubus data section.

Extend the hotplug script to handle this case by checking whether a zone
hint is present and if the requested zone exists in the configuration if
a direct zone lookup fails.

Fixes: #9611
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agofw4: store zone associations from ubus in statefile as well
Jo-Philipp Wich [Fri, 20 May 2022 10:10:30 +0000 (12:10 +0200)]
fw4: store zone associations from ubus in statefile as well

The current implementation already stored related subnets and devices,
but not the logical interface names themselves.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agofw4: filter non hw-offload capable devices when resolving lower devices
Jo-Philipp Wich [Mon, 9 May 2022 13:09:50 +0000 (15:09 +0200)]
fw4: filter non hw-offload capable devices when resolving lower devices

Make sure to ignore devices not capable of hardware offloading when resolving
lower devices for the flowtable declaration.

Commit 57984e0 ("fw4: always resolve lower flowtable devices") changed the
behaviour of fw4 to always resolve lower devices, even for soft offloading
but removed some a crucial check to omit incapable devices in the hardware
offloading case, regressing previously working setups due to the inclusion
of wireless devices into the hardware offloaded table declaration.

Since we need to reintroduce ubus device status information for this change,
we can utilize the devinfo value exposed there instead or resolving it from
sysfs ourselves. Also make sure to sort the deduplicated device list to
produce a deterministic result.

Fixes: 57984e0 ("fw4: always resolve lower flowtable devices")
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agofw4: always resolve lower flowtable devices
Jo-Philipp Wich [Mon, 9 May 2022 08:51:03 +0000 (10:51 +0200)]
fw4: always resolve lower flowtable devices

Do not restrict lower device resolving to hardware flow offloading, it is
required for software flow offloading as well.

While we're at it, also refactor and simplify the code to not require ubus
runtime state for device resolving anymore.

Fixes: #9854
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agotests: fix mocked `fd.read("line")` api
Jo-Philipp Wich [Mon, 9 May 2022 08:49:43 +0000 (10:49 +0200)]
tests: fix mocked `fd.read("line")` api

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agoconfig: remove restictions on DHCPv6 allow rule
Tiago Gaspar [Wed, 4 May 2022 09:36:07 +0000 (10:36 +0100)]
config: remove restictions on DHCPv6 allow rule

Remove restrictions on source and destination addresses, which aren't
specified on RFC8415, and for some reason in openwrt are configured
to allow both link-local and ULA addresses.
As cleared out in issue #5066 there are some ISPs that use Gloabal
Unicast addresses, so fix this rule to allow them.

Fixes: #5066
Signed-off-by: Tiago Gaspar <tiagogaspar8@gmail.com>
2 years agofw4: refactor family selection for forwarding rules
Jo-Philipp Wich [Fri, 29 Apr 2022 12:48:16 +0000 (14:48 +0200)]
fw4: refactor family selection for forwarding rules

Use the common `infer_family()` helper when parsing `forwarding` sections
to simplify the code. Also add some test coverage for the changed code.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agotreewide: use modern syntax
Jo-Philipp Wich [Thu, 28 Apr 2022 19:41:13 +0000 (21:41 +0200)]
treewide: use modern syntax

 - Use `||=` operator expressions instead of `expr = expr || value` patterns
 - Use optional chaining instead of `foo && foo.bar && foo.bar.baz` patterns
 - Use template strings instead of string concatenations or sprintf() calls
 - Use `const` for global default variables

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agofw4: fix emitting device jump rules for family restricted zones
Jo-Philipp Wich [Fri, 29 Apr 2022 12:29:39 +0000 (14:29 +0200)]
fw4: fix emitting device jump rules for family restricted zones

Ref: https://forum.openwrt.org/t/22-03-0-rc1-first-rc/126045/80
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agofw4: fix family auto-selection for config nat rules
Jo-Philipp Wich [Thu, 28 Apr 2022 09:49:47 +0000 (11:49 +0200)]
fw4: fix family auto-selection for config nat rules

 - Ensure that a nat rule without any AF specifics and no explictly set
   family ends up being IPv4 only

 - Ensure that an IPv6 address without explicitly set family results in
   an IPv6 rule

 - Ensure that explicitly setting family any results in a IPv4/IPv6 rule

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agoruleset: ensure that family-agnostic ICMP rules cover ICMPv6 as well
Jo-Philipp Wich [Tue, 26 Apr 2022 12:27:41 +0000 (14:27 +0200)]
ruleset: ensure that family-agnostic ICMP rules cover ICMPv6 as well

Fixes: #9765
Ref: https://github.com/openwrt/openwrt/issues/9765
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agotests: add test coverage for zone family selection logic
Jo-Philipp Wich [Thu, 21 Apr 2022 19:27:28 +0000 (21:27 +0200)]
tests: add test coverage for zone family selection logic

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agoruleset: set auto-merge directive for interval sets
Jo-Philipp Wich [Thu, 21 Apr 2022 19:21:02 +0000 (21:21 +0200)]
ruleset: set auto-merge directive for interval sets

Set the auto-merge directive for interval sets to automatically merge
overlapping CIDRs such as 192.168.1.0/24, 192.168.1.1. Without that
directive, nft will fail to apply the rendered ruleset with an error.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agofw4: fix skipping invalid ipset entries
Jo-Philipp Wich [Thu, 21 Apr 2022 19:10:26 +0000 (21:10 +0200)]
fw4: fix skipping invalid ipset entries

The current code did not account for invalid entires yielding `null` after
subnet parsing, leading to an incorrect warning about multiple entries and
a subsequent `null` access leading to a crash.

Fix the issue by ensuring that the length check expression yields `0` on
invalid inputs.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agofw4: fix applying zone flags for source bound rules
Jo-Philipp Wich [Wed, 13 Apr 2022 14:18:44 +0000 (16:18 +0200)]
fw4: fix applying zone flags for source bound rules

The rule parsing code failed to properly set the source zone flags for
rules requiring `${verdict}_from_${zone}` chains, causing those chains
to be missing, leading to errors when applying the ruleset.

Fix this issue by applying the flag to the correct property (source-
instead of destination flags).

Ref: https://github.com/openwrt/openwrt/issues/9686
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agofw4: fix emitting family specific redirect rules without any addrs
Jo-Philipp Wich [Sat, 2 Apr 2022 18:27:25 +0000 (20:27 +0200)]
fw4: fix emitting family specific redirect rules without any addrs

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agofw4: bracketize IPv6 addresses in dnat addr:port notation
Jo-Philipp Wich [Sat, 2 Apr 2022 18:06:11 +0000 (20:06 +0200)]
fw4: bracketize IPv6 addresses in dnat addr:port notation

Ref: https://github.com/openwrt/openwrt/issues/9624
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agofw4: ensure to capitalize weekday names
Jo-Philipp Wich [Wed, 30 Mar 2022 14:49:22 +0000 (16:49 +0200)]
fw4: ensure to capitalize weekday names

Despite what's being documented in the nftables wiki, nftables does not
actually accept lowercased or abbreviated weekday names, currently failing
with a "Error: Could not parse Day of week of packet reception" error for
expressions such as `meta day { "sunday", "wed" }`.

Work around the problem by explicitly emitting capitalized weekday names
while a more thorough nftables-side solution is being sent upstream.

Ref: https://forum.openwrt.org/t/firewall-time-restrictions-parental-controls-problems/123964
Ref: https://wiki.nftables.org/wiki-nftables/index.php/Matching_packet_metainformation#Matching_by_time
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agotreewide: forward compatibility changes
Jo-Philipp Wich [Tue, 22 Mar 2022 18:17:22 +0000 (19:17 +0100)]
treewide: forward compatibility changes

Adapt testsuite code and fw4 wrapper to current ucode HEAD semantics,
in particular ensure that main.uc is invoked as template since ucode now
defaults to raw mode for cli invocations.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agofw4: resolve zone layer 2 devices for hw flow offloading
Jo-Philipp Wich [Sat, 12 Feb 2022 19:32:38 +0000 (20:32 +0100)]
fw4: resolve zone layer 2 devices for hw flow offloading

Some interface protocols like PPPoE use a layer 3 device that is different
fro mthe layer 2 one and which cannot be resolved to a lower device through
sysfs, so additionally track related layer 2 devices and resolve those when
constructing a hardware flow offloading table.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agofw4: rework and fix family inheritance logic
Jo-Philipp Wich [Sat, 12 Feb 2022 19:13:06 +0000 (20:13 +0100)]
fw4: rework and fix family inheritance logic

Fix various quirks in the logic inferring the effective rule family from
referenced entities, consider subnet matches when determining family of
zones and set the zone family to the determined value in case it is
unspecified in configuration.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agotests: mocklib: fix infinite recursion in wrapped print()
Jo-Philipp Wich [Sat, 12 Feb 2022 18:36:27 +0000 (19:36 +0100)]
tests: mocklib: fix infinite recursion in wrapped print()

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agotests: change mocked wan interface type to PPPoE
Jo-Philipp Wich [Sat, 12 Feb 2022 12:16:24 +0000 (13:16 +0100)]
tests: change mocked wan interface type to PPPoE

Change the WAN interface type in the mock data to PPPoE. PPPoE interfaces
are special because their L3 device differs from the L2 one which becomes
important later for resolving hw offloaded flowtable devices.

Adjust the test cases accordingly.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agotests: mocklib: forward compatibility change
Jo-Philipp Wich [Fri, 11 Feb 2022 16:41:00 +0000 (17:41 +0100)]
tests: mocklib: forward compatibility change

Upstream ucode will change ord()'s return value type from array to integer,
add logic to handle both old and new cases.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agofw4: only stage reflection rules if all required addrs are known
Jo-Philipp Wich [Thu, 10 Feb 2022 18:52:00 +0000 (19:52 +0100)]
fw4: only stage reflection rules if all required addrs are known

Do not stage reflection rules if any of the internal, external or
rewrite IP addrs cannot be determined. Also emit a warning in this
case and extend the redirect test case to cover this.

Fixes: #5067
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agofw4: add device iifname/oifname matches to DSCP and MARK rules
Jo-Philipp Wich [Thu, 10 Feb 2022 18:17:28 +0000 (19:17 +0100)]
fw4: add device iifname/oifname matches to DSCP and MARK rules

Mirror firewall3 logic and do ingress/egress device matches for MARK
and DSCP rules. Also complete support option `device` and `option direction`
to allow overriding the automatic device matches.

Fixes: #5061
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agotests: adjust 01_ruleset test case to latest changes
Jo-Philipp Wich [Tue, 8 Feb 2022 18:22:55 +0000 (19:22 +0100)]
tests: adjust 01_ruleset test case to latest changes

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agofw4: gracefully handle unsupported hardware offloading
Jo-Philipp Wich [Mon, 7 Feb 2022 22:27:37 +0000 (23:27 +0100)]
fw4: gracefully handle unsupported hardware offloading

Try to create a hardware-offloaded flowtable using `nft -c` and fall back
to software offloading in case the test command fails.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agoinit: fix boot action in init script
Jo-Philipp Wich [Mon, 7 Feb 2022 18:01:04 +0000 (19:01 +0100)]
init: fix boot action in init script

We need to call `start()` instead of `start_service()` from `boot()` in
order to properly register the firewall service.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agofw4: parse traffic rules before forwarding rules
Jo-Philipp Wich [Mon, 7 Feb 2022 10:08:20 +0000 (11:08 +0100)]
fw4: parse traffic rules before forwarding rules

Parse traffic rules before inter-zone-forwarding rules to ensure that
those rules end up in the correct order within the rendered ruleset.

Traffic rules must preceede zone forwarding rules, like they did in
firewall3.

Fixes: FS#4258
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agofw4: consolidate helper code
Jo-Philipp Wich [Fri, 4 Feb 2022 22:44:25 +0000 (23:44 +0100)]
fw4: consolidate helper code

 - Move various local helper functions out of main.uc into the fw4 class
 - Rework settype reading to use nft JSON output as terse mode now works
 - Simplify testing flowtable enable conditions
 - Adjust testcases to changed flowtable logic

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agofw4: fix applying zone family restrictions to forwardings
Jo-Philipp Wich [Sat, 5 Feb 2022 23:30:41 +0000 (00:30 +0100)]
fw4: fix applying zone family restrictions to forwardings

The source or destination zone family may be `null` instead of `0`, so
loosen the condition to cover both `0` and `null` values.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agotests: implement fs.opendir() mock interface
Jo-Philipp Wich [Sat, 5 Feb 2022 23:29:54 +0000 (00:29 +0100)]
tests: implement fs.opendir() mock interface

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2 years agotests: fix mocked fs.popen() trace log
Jo-Philipp Wich [Sat, 5 Feb 2022 23:29:11 +0000 (00:29 +0100)]
tests: fix mocked fs.popen() trace log

Signed-off-by: Jo-Philipp Wich <jo@mein.io>