summaryrefslogtreecommitdiffstats
path: root/iptables
Commit message (Collapse)AuthorAgeFilesLines
* Simplify static build extension loadingPhil Sutter2022-03-1511-29/+0
| | | | | | | | | | Instead of guarding all calls to init_extensions*(), define stubs if not used. While at it, also add the missing prototypes for arp- and ebtables extension initializers. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Don't pass command state opaque to family ops callbacksPhil Sutter2022-03-108-102/+84
| | | | | | | | | | | There are no family-specific versions of struct iptables_command_state anymore, so no need to hide it behind void pointer. Pass the type as-is and save a few casts. While at it, drop unused callbacks parse_bitwise and parse_cmp. Signed-off-by: Phil Sutter <phil@nwl.cc> Acked-by: Florian Westphal <fw@strlen.de>
* xshared: Prefer xtables_chain_protos lookup over getprotoentPhil Sutter2022-03-101-4/+4
| | | | | | | | | | | | | | | | | | | | | | | When dumping a large ruleset, common protocol matches such as for TCP port number significantly slow down rule printing due to repeated calls for getprotobynumber(). The latter does not involve any caching, so /etc/protocols is consulted over and over again. As a simple countermeasure, make functions converting between proto number and name prefer the built-in list of "well-known" protocols. This is not a perfect solution, repeated rules for protocol names libxtables does not cache (e.g. igmp or dccp) will still be slow. Implementing getprotoent() result caching could solve this. As a side-effect, explicit check for pseudo-protocol "all" may be dropped as it is contained in the built-in list and therefore immutable. Also update xtables_chain_protos entries a bit to align with typical /etc/protocols contents. The testsuite assumes those names, so the preferred ones prior to this patch are indeed uncommon nowadays. Signed-off-by: Phil Sutter <phil@nwl.cc> Acked-by: Florian Westphal <fw@strlen.de>
* nft: Speed up immediate parsingPhil Sutter2022-03-102-19/+19
| | | | | | | | | | | | | | | | | | | | | | | | | Parsing of rules which jump to a chain pointlessly causes a call to xtables_find_target() despite the code already knowing the outcome. Avoid the significant delay for rulesets with many chain jumps by performing the (standard) target lookup only for accept/drop/return verdicts. From a biased test-case on my VM: | # iptables-nft-save | grep -c -- '-j' | 133943 | # time ./old/iptables-nft-save >/dev/null | real 0m45.566s | user 0m1.308s | sys 0m8.430s | # time ./new/iptables-nft-save >/dev/null | real 0m3.547s | user 0m0.762s | sys 0m2.476s Signed-off-by: Phil Sutter <phil@nwl.cc> Acked-by: Florian Westphal <fw@strlen.de>
* nft: Simplify immediate parsingPhil Sutter2022-03-106-47/+14
| | | | | | | | | | Implementations of parse_immediate callback are mostly trivial, the only relevant part is access to family-specific parts of struct iptables_command_state when setting goto flag for iptables and ip6tables. Refactor them into simple set_goto_flag callbacks. Signed-off-by: Phil Sutter <phil@nwl.cc> Acked-by: Florian Westphal <fw@strlen.de>
* Improve error messages for unsupported extensionsPhil Sutter2022-03-021-3/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | If a given extension was not supported by the kernel, iptables would print a rather confusing error message if extension parameters were given: | # rm /lib/modules/$(uname -r)/kernel/net/netfilter/xt_LOG.ko | # iptables -A FORWARD -j LOG --log-prefix foo | iptables v1.8.7 (legacy): unknown option "--log-prefix" Avoid this by pretending extension revision 0 is always supported. It is the same hack as used to successfully print extension help texts as unprivileged user, extended to all error codes to serve privileged ones as well. In addition, print a warning if kernel rejected revision 0 and it's not a permissions problem. This helps users find out which extension in a rule the kernel didn't like. Finally, the above commands result in these messages: | Warning: Extension LOG revision 0 not supported, missing kernel module? | iptables: No chain/target/match by that name. Or, for iptables-nft: | Warning: Extension LOG revision 0 not supported, missing kernel module? | iptables v1.8.7 (nf_tables): RULE_APPEND failed (No such file or directory): rule in chain FORWARD Signed-off-by: Phil Sutter <phil@nwl.cc>
* xshared: Implement xtables lock timeout using signalsJethro Beekman2022-02-158-77/+36
| | | | | | | | | | | | | | | | | | | | | | | Previously, if a lock timeout is specified using `-wN `, flock() is called using LOCK_NB in a loop with a sleep. This results in two issues. The first issue is that the process may wait longer than necessary when the lock becomes available. For this the `-W` option was added, but this requires fine-tuning. The second issue is that if lock contention is high, invocations using `-w` (without a timeout) will always win lock acquisition from invocations that use `-w N`. This is because invocations using `-w` are actively waiting on the lock whereas those using `-w N` only check from time to time whether the lock is free, which will never be the case. This patch removes the sleep loop and deprecates the `-W` option (making it non-functional). Instead, flock() is always called in a blocking fashion, but the alarm() function is used with a non-SA_RESTART signal handler to cancel the system call. Signed-off-by: Jethro Beekman <jethro@fortanix.com> Signed-off-by: Florian Westphal <fw@strlen.de>
* iptables.8: Describe the effect of multiple -v flagsPhil Sutter2022-02-111-1/+5
| | | | | | | Functionality differs between legacy and nft variants, detail the effects a bit. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: cache: Dump rules if debuggingPhil Sutter2022-02-081-2/+16
| | | | | | | | If verbose flag was given twice, dump rules while populating the cache. This not only applies to list commands, but all requiring a rule cache - e.g. insert with position. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Add debug output to table creationPhil Sutter2022-02-081-0/+15
| | | | | | | This at least allows to inspect how tables are created on demand. Also requires setting NFTNL_TABLE_FAMILY for clean output. Signed-off-by: Phil Sutter <phil@nwl.cc>
* ebtables: Support verbose modePhil Sutter2022-02-083-9/+30
| | | | | | | | Accept '-v' flag in both ebtables-nft and ebtables-nft-restore. Mostly interesting because it allows for netlink debug output when specified multiple times. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Set NFTNL_CHAIN_FAMILY in new chainsPhil Sutter2022-02-081-4/+8
| | | | | | | | | | | | | | | | | | | | | | Kernel doesn't need it, but debug output improves significantly. Before this patch: | # iptables-nft -vv -A INPUT | [...] | unknown filter INPUT use 0 type filter hook unknown prio 0 policy accept packets 0 bytes 0 | [...] and after: | # iptables-nft -vv -A INPUT | [...] | ip filter INPUT use 0 type filter hook input prio 0 policy accept packets 0 bytes 0 | [...] While being at it, make nft_chain_builtin_alloc() take only the builtin table's name as parameter - it's the only field it accesses. Signed-off-by: Phil Sutter <phil@nwl.cc>
* iptables-restore: Support for extra debug outputPhil Sutter2022-02-044-5/+17
| | | | | | | | | | | | | | Treat --verbose just like iptables itself, increasing debug level with number of invocations. To propagate the level into do_command() callback, insert virtual '-v' flags into rule lines. The only downside of this is that simple verbose output is changed and now also prints the rules as they are added - which would be useful if the lines contained the chain they apply to. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Use verbose flag to toggle debug outputPhil Sutter2022-02-044-19/+22
| | | | | | | | | | | Copy legacy iptables' behaviour, printing debug output if verbose flag is given more than once. Since nft debug output applies to netlink messages which are not created until nft_action() phase, carrying verbose value is non-trivial - introduce a field in struct nft_handle for that. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: add support for native tcp flag matchingFlorian Westphal2022-01-291-2/+29
| | | | | | prefer payload + bitwise + cmp to nft_compat match. Signed-off-by: Florian Westphal <fw@strlen.de>
* nft-shared: add tcp flag dissectionFlorian Westphal2022-01-291-0/+26
| | | | | | | Detect payload load of th->flags and convert it to xt tcp match structure. Signed-off-by: Florian Westphal <fw@strlen.de>
* nft: prefer native expressions instead of tcp matchFlorian Westphal2022-01-291-0/+32
| | | | | | | | | | | | | | Instead of using nft_compat+xtables tcp match, prefer to emit payload+cmp or payload+range expression. Unlike udp, tcp has flag bits that can be matched too but we have to fall back to the xt expression for now. We also don't support tcp option match, but thats a rarely used feature anyway. Delinearization support for ports was added in previous patches. Signed-off-by: Florian Westphal <fw@strlen.de>
* nft: prefer native expressions instead of udp matchFlorian Westphal2022-01-291-0/+122
| | | | | | | | | Instead of using nft_compat+xtables udp match, prefer to emit payload+cmp or payload+range expression. Delinearization support was added in previous patches. Signed-off-by: Florian Westphal <fw@strlen.de>
* nft-shared: support native udp port delinearizeFlorian Westphal2022-01-292-4/+122
| | | | | | same as previous patch, but for udp. Signed-off-by: Florian Westphal <fw@strlen.de>
* nft-shared: support native tcp port range delinearizeFlorian Westphal2022-01-293-1/+116
| | | | | | | adds support for nft ... tcp dport != min-max Signed-off-by: Florian Westphal <fw@strlen.de>
* nft-shared: support native tcp port delinearizeFlorian Westphal2022-01-292-2/+179
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This extends iptables-nft dissector to decode native tcp port matching. nft ruleset: table ip filter { chain INPUT { type filter hook input priority filter; policy accept; tcp sport 12345 tcp sport 12345 tcp dport 6789 tcp sport < 1024 tcp dport >= 1024 } } $ iptables-nft-save -A INPUT -p tcp -m tcp --sport 12345 -A INPUT -p tcp -m tcp --sport 12345 --dport 6789 -A INPUT -p tcp -m tcp --sport 0:1023 -A INPUT -p tcp -m tcp --dport 1024:65535 This would allow to extend iptables-nft to prefer native payload expressions for --sport,dport in the future. Also, parse_cmp must not clear the "payload" flag, this is because cmp-based range expressions will contain following sequence: payload => reg1 cmp reg1 > minv cmp reg1 < maxv ... so second cmp would work. Signed-off-by: Florian Westphal <fw@strlen.de>
* xshared: Fix response to unprivileged usersPhil Sutter2022-01-203-2/+66
| | | | | | | | | | | | | | | | | | | | | Expected behaviour in both variants is: * Print help without error, append extension help if -m and/or -j options are present * Indicate lack of permissions in an error message for anything else With iptables-nft, this was broken basically from day 1. Shared use of do_parse() then somewhat broke legacy: it started complaining about inability to create a lock file. Fix this by making iptables-nft assume extension revision 0 is present if permissions don't allow to verify. This is consistent with legacy. Second part is to exit directly after printing help - this avoids having to make the following code "nop-aware" to prevent privileged actions. Signed-off-by: Phil Sutter <phil@nwl.cc> Reviewed-by: Florian Westphal <fw@strlen.de>
* extensions: libxt_NFLOG: don't truncate log prefix on print/saveKyle Bowman2022-01-182-0/+56
| | | | | | | | | | | | | | | | | | | | | | | | When parsing the rule, use a struct with a layout compatible to that of struct xt_nflog_info, but with a buffer large enough to contain the whole 128-character nft prefix. We always send the nflog-group to the kernel since, for nft, log and nflog targets are handled by the same kernel module, and are distinguished by whether they define an nflog-group. Therefore, we must send the group even if it is zero, or the kernel will configure the target as a log, not an nflog. Changes to nft_is_expr_compatible were made since only targets which have an `nflog-group` are compatible. Since nflog targets are distinguished by having an nflog-group, we ignore targets without one. We also set the copy-len flag if the snap-len is set since without this, iptables will mistake `nflog-size` for `nflog-range`. Signed-off-by: Kyle Bowman <kbowman@cloudflare.com> Signed-off-by: Alex Forster <aforster@cloudflare.com> Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Florian Westphal <fw@strlen.de>
* extensions: libxt_NFLOG: use nft built-in logging instead of xt_NFLOGKyle Bowman2022-01-182-0/+29
| | | | | | | | | | | | | | | Replaces the use of xt_NFLOG with the nft built-in log statement. This additionally adds support for using longer log prefixes of 128 characters in size. Until now NFLOG has truncated the log-prefix to the 64-character limit supported by iptables-legacy. We now use the struct xtables_target's udata member to store the longer 128-character prefix supported by iptables-nft. Signed-off-by: Kyle Bowman <kbowman@cloudflare.com> Signed-off-by: Alex Forster <aforster@cloudflare.com> Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Florian Westphal <fw@strlen.de>
* nft: fix indentation error.Jeremy Sowden2022-01-151-21/+21
| | | | | | | `add_action` was indented with 7 spaces. Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Florian Westphal <fw@strlen.de>
* ip6tables: Use the shared do_parse, tooPhil Sutter2022-01-122-466/+40
| | | | | | | Same change as with iptables, merely have to set IP6T_F_PROTO flag in ipv6_proto_parse(). Signed-off-by: Phil Sutter <phil@nwl.cc>
* iptables: Use xtables' do_parse() functionPhil Sutter2022-01-122-451/+39
| | | | | | | | | | To do so, a few conversions are needed: - Make use of xt_params->optstring - Make use of xt_params->print_help callback - Switch to using a proto_parse callback Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Move proto_parse and post_parse callbacks to xsharedPhil Sutter2022-01-124-131/+139
| | | | | | | They are not nft-variant-specific and may therefore be shared with legacy. Signed-off-by: Phil Sutter <phil@nwl.cc>
* xshared: Store parsed wait and wait_interval in xtables_argsPhil Sutter2022-01-122-5/+5
| | | | | | While nft-variants don't care, legacy ones do. Signed-off-by: Phil Sutter <phil@nwl.cc>
* xshared: Move do_parse to shared spacePhil Sutter2022-01-125-559/+560
| | | | | | | | | | | Small adjustments were needed: - Pass line variable via xt_cmd_parse, xshared.c does not have it in namespace. - Replace opts, prog_name and prog_vers defines by the respective xt_params field reference. Signed-off-by: Phil Sutter <phil@nwl.cc>
* xtables: Do not pass nft_handle to do_parse()Phil Sutter2022-01-128-50/+64
| | | | | | | | | Make it fit for sharing with legacy iptables, drop nft-specific parameter. This requires to mirror proto_parse and post_parse callbacks from family_ops somewhere reachable - use xt_cmd_parse, it holds other "parser setup data" as well. Signed-off-by: Phil Sutter <phil@nwl.cc>
* xtables: Pass xtables_args to check_inverse()Phil Sutter2022-01-121-13/+13
| | | | | | | It holds the accessed family field as well and is more generic than nft_handle. Signed-off-by: Phil Sutter <phil@nwl.cc>
* xtables: Pass xtables_args to check_empty_interface()Phil Sutter2022-01-121-4/+4
| | | | | | | It holds the accessed family field as well and is more generic than nft_handle. Signed-off-by: Phil Sutter <phil@nwl.cc>
* xtables: Move struct nft_xt_cmd_parse to xshared.hPhil Sutter2022-01-125-21/+21
| | | | | | | Preparing for shared use with legacy variants, move it to "neutral ground" and give it a more generic name. Signed-off-by: Phil Sutter <phil@nwl.cc>
* xtables: Pull table validity check out of do_parse()Phil Sutter2022-01-121-4/+4
| | | | | | | Makes do_parse() more generic, error codes don't change so this should be safe. Signed-off-by: Phil Sutter <phil@nwl.cc>
* xtables: Drop xtables' family on demand featurePhil Sutter2022-01-121-4/+0
| | | | | | | | | | | | | This conditional h->family assignment was added by commit 3f7877e6be987 ("xtables-restore: add -4 and -6 support") with the intention to support something like 'xtables-restore -6 <ip6tables.dump', i.e. having family-agnostic commands which accept flags to set the family. Yet commit be70918eab26e ("xtables: rename xt-multi binaries to -nft, -legacy") removed support for such command names back in 2018 and nobody has complained so far. Therefore drop this leftover as it makes do_parse() more generic. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft-shared: set correct register valueFlorian Westphal2021-12-231-1/+1
| | | | | | | | | | | NFTNL_EXPR_META_DREG equals NFTNL_EXPR_PAYLOAD_BASE, so we set dreg to the payload base instead. It "works" because the simple nft rules currently generated via ipables-nft have base == register-number but this is a coincidence. Signed-off-by: Florian Westphal <fw@strlen.de>
* iptables-*-restore: Drop pointless line referencePhil Sutter2021-12-164-8/+8
| | | | | | | | | There's no need to mention the offending line number in error message when calling xtables_error() with a status of PARAMETER_PROBLEM as that will cause a call to xtables_exit_tryhelp() which in turn prints "Error occurred at line: N". Signed-off-by: Phil Sutter <phil@nwl.cc>
* libxtables: Extend basic_exit_err()Phil Sutter2021-12-165-72/+0
| | | | | | | Basically merge the function with xtables_exit_error, printing a status-specific footer for parameter or version problems. Signed-off-by: Phil Sutter <phil@nwl.cc>
* xtables_globals: Embed variant name in .program_versionPhil Sutter2021-12-169-16/+16
| | | | | | Both are constant strings, so precompiler may concat them. Signed-off-by: Phil Sutter <phil@nwl.cc>
* xshared: Share exit_tryhelp()Phil Sutter2021-12-165-46/+24
| | | | | | | The function existed three times in identical form. Avoid having to declare extern int line in xshared.c by making it a parameter. Signed-off-by: Phil Sutter <phil@nwl.cc>
* xshared: Share a common printhelp functionPhil Sutter2021-12-165-239/+108
| | | | | | | | | | | | | Help texts in legacy and nft variants are supposed to be identical, but those of iptables and ip6tables largely overlapped already. By referring to xt_params and afinfo pointers, it is relatively trivial to craft a suitable help text on demand, so duplicated help texts can be eliminated. As a side-effect, this fixes ip6tables-nft help text - it was identical to that of iptables-nft. Signed-off-by: Phil Sutter <phil@nwl.cc>
* xshared: Share print_match_save() between legacy ip*tablesPhil Sutter2021-12-164-62/+32
| | | | | | | | The only difference between the former two copies was the type of ip*_entry parameter. But since it is treated opaque, just hide that detail by casting to void. Signed-off-by: Phil Sutter <phil@nwl.cc>
* xshared: Make load_proto() staticPhil Sutter2021-11-232-2/+1
| | | | | | | The last outside users vanished ten years ago. Fixes: 449cdd6bcc8d1 ("src: combine default_command functions") Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft-shared: Drop unused function print_proto()Phil Sutter2021-11-232-16/+0
| | | | | | | | | The last users vanished back in 2013. There is identical code in save_rule_details(), but with only a single user there's not much point in keeping the function. Fixes: cdc78b1d6bd7b ("nft: convert rule into a command state structure") Signed-off-by: Phil Sutter <phil@nwl.cc>
* xshared: Share print_header() with legacy iptablesPhil Sutter2021-11-239-161/+82
| | | | | | | | | | | | | | | Legacy iptables fetches the relevant data via libiptc before calling the shared routine which merely prints data as requested. Drop the 'basechain' parameter, instead make sure a policy name is passed only with base chains. Since the function is not shared with ebtables (which uses a very rudimental header instead), this is safe. In order to support legacy iptables' checking of iptc_get_references() return code (printing an error message instead of the reference count), make refs parameter signed and print the error message if it's negative. Signed-off-by: Phil Sutter <phil@nwl.cc>
* xshared: Share print_fragment() with legacyPhil Sutter2021-11-236-35/+25
| | | | | | | | | | | Also add a fake mode to make it suitable for ip6tables. This is required because IPT_F_FRAG value clashes with IP6T_F_PROTO, so ip6tables rules might seem to have IPT_F_FRAG bit set. While being at it, drop the local variable 'flags' from print_firewall(). Signed-off-by: Phil Sutter <phil@nwl.cc>
* xshared: Share print_rule_details() with legacyPhil Sutter2021-11-238-76/+37
| | | | | | | | | | Have to pass pointer to counters directly since different fields are being used for some reason. Since proto_to_name() is not used outside of xshared.c anymore, make it static. Signed-off-by: Phil Sutter <phil@nwl.cc>
* xshared: Share save_ipv{4,6}_addr() with legacyPhil Sutter2021-11-236-119/+70
| | | | | | | While being at it, make save_ipv4_addr() accept an in_addr* as mask - mask_to_str() needs it anyway. Signed-off-by: Phil Sutter <phil@nwl.cc>
* xshared: Share save_rule_details() with legacyPhil Sutter2021-11-238-91/+50
| | | | | | | | | | The function combines printing of input and output interfaces and protocol parameter, all being IP family independent. Extend the function to print fragment option ('-f'), too if requested. While being at it, drop unused iptables_command_state parameter and reorder the remaining ones a bit. Signed-off-by: Phil Sutter <phil@nwl.cc>