summaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
* tests: shell: remove redundant payload expressionsJeremy Sowden2022-01-152-5/+5
| | | | | | | | Now that we keep track of more payload dependencies, more redundant payloads are eliminated. Remove these from the shell test-cases. Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Florian Westphal <fw@strlen.de>
* tests: py: remove redundant payload expressionsJeremy Sowden2022-01-153-21/+1
| | | | | | | | Now that we keep track of more payload dependencies, more redundant payloads are eliminated. Remove these from the Python test-cases. Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Florian Westphal <fw@strlen.de>
* src: store more than one payload dependencyJeremy Sowden2022-01-153-31/+45
| | | | | | | | Change the payload-dependency context to store a dependency for every protocol layer. This allows us to eliminate more redundant protocol expressions. Signed-off-by: Florian Westphal <fw@strlen.de>
* src: add a helper that returns a payload dependency for a particular baseJeremy Sowden2022-01-153-6/+31
| | | | | | | | | | | Currently, with only one base and dependency stored this is superfluous, but it will become more useful when the next commit adds support for storing a payload for every base. Remove redundant `ctx->pbase` check. Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Florian Westphal <fw@strlen.de>
* tests: py: fix inet/ip.t bridge payloadJeremy Sowden2022-01-151-1/+1
| | | | | | | | | | | | Correct the statement used to load the protocol in the bridge payload of one of the ip tests. A previous commit was supposed, in part, to do this, but the update got lost. Fixes: 4b8e51ea5fc8 ("tests: py: fix inet/ip.t payloads") Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Florian Westphal <fw@strlen.de>
* src: silence compiler warningsFlorian Westphal2022-01-153-4/+4
| | | | | | | | | | | | cache.c:504:22: warning: ‘chain’ may be used uninitialized in this function [-Wmaybe-uninitialized] cache.c:504:22: warning: ‘table’ may be used uninitialized in this function [-Wmaybe-uninitialized] erec.c:128:16: warning: ‘line’ may be used uninitialized in this function [-Wmaybe-uninitialized] optimize.c:524:9: warning: ‘line’ may be used uninitialized in this function [-Wmaybe-uninitialized] Fixes: 8ad4056e9182 ("erec: expose print_location() and line_location()") Fixes: afbd102211dc ("src: do not use the nft_cache_filter object from mnl.c") Fixes: fb298877ece2 ("src: add ruleset optimization infrastructure") Signed-off-by: Florian Westphal <fw@strlen.de>
* libnftables: use xrealloc()Pablo Neira Ayuso2022-01-151-7/+3
| | | | | | | Instead of realloc(), so process stops execution in case memory allocation fails. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: 'nft list chain' prints anonymous chains correctlyPablo Neira Ayuso2022-01-155-0/+68
| | | | | | | | | If the user is requesting a chain listing, e.g. nft list chain x y and a rule refers to an anonymous chain that cannot be found in the cache, then fetch such anonymous chain and its ruleset. Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1577 Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* cache: add helper function to fill up the rule cachePablo Neira Ayuso2022-01-151-16/+25
| | | | | | | Add a helper function to dump the rules and add them to the corresponding chain. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* cache: do not set error code twicePablo Neira Ayuso2022-01-151-21/+7
| | | | | | | The 'ret' variable is already set to a negative value to report an error, do not set it again to a negative value. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: do not use the nft_cache_filter object from mnl.cPablo Neira Ayuso2022-01-153-9/+14
| | | | | | Pass the table and chain strings to mnl_nft_rule_dump() instead. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: merge several selectors with different verdict into verdict mapPablo Neira Ayuso2022-01-154-3/+102
| | | | | | | | | | | | | Transform: ip saddr 1.1.1.1 ip daddr 2.2.2.2 accept ip saddr 2.2.2.2 ip daddr 3.3.3.3 drop into: ip saddr . ip daddr vmap { 1.1.1.1 . 2.2.2.2 : accept, 2.2.2.2 . 3.3.3.3 : drop } Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: merge same selector with different verdict into verdict mapPablo Neira Ayuso2022-01-153-15/+164
| | | | | | | | | | | | | Transform: ct state invalid drop ct state established,related accept into: ct state vmap { established : accept, related : accept, invalid : drop } Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: merge rules with same selectors into a concatenationPablo Neira Ayuso2022-01-153-1/+61
| | | | | | | | | | | | | | | | | This patch extends the ruleset optimization infrastructure to collapse several rules with the same selectors into a concatenation. Transform: meta iifname eth1 ip saddr 1.1.1.1 ip daddr 2.2.2.3 accept meta iifname eth1 ip saddr 1.1.1.2 ip daddr 2.2.2.5 accept meta iifname eth2 ip saddr 1.1.1.3 ip daddr 2.2.2.6 accept into: meta iifname . ip saddr . ip daddr { eth1 . 1.1.1.1 . 2.2.2.6, eth1 . 1.1.1.2 . 2.2.2.5 , eth1 . 1.1.1.3 . 2.2.2.6 } accept Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: add ruleset optimization infrastructurePablo Neira Ayuso2022-01-1510-11/+586
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This patch adds a new -o/--optimize option to enable ruleset optimization. You can combine this option with the dry run mode (--check) to review the proposed ruleset updates without actually loading the ruleset, e.g. # nft -c -o -f ruleset.test Merging: ruleset.nft:16:3-37: ip daddr 192.168.0.1 counter accept ruleset.nft:17:3-37: ip daddr 192.168.0.2 counter accept ruleset.nft:18:3-37: ip daddr 192.168.0.3 counter accept into: ip daddr { 192.168.0.1, 192.168.0.2, 192.168.0.3 } counter packets 0 bytes 0 accept This infrastructure collects the common statements that are used in rules, then it builds a matrix of rules vs. statements. Then, it looks for common statements in consecutive rules which allows to merge rules. This ruleset optimization always performs an implicit dry run to validate that the original ruleset is correct. Then, on a second pass, it performs the ruleset optimization and add the rules into the kernel (unless --check has been specified by the user). From libnftables perspective, there is a new API to enable this feature: uint32_t nft_ctx_get_optimize(struct nft_ctx *ctx); void nft_ctx_set_optimize(struct nft_ctx *ctx, uint32_t flags); This patch adds support for the first optimization: Collapse a linear list of rules matching on a single selector into a set as exposed in the example above. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: remove '$' in symbol_expr_printPablo Neira Ayuso2022-01-151-2/+1
| | | | | | | This is used in --debug=eval mode to annotate symbols that have not yet been evaluated, remove it. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: error reporting with -f and read from stdinPablo Neira Ayuso2022-01-154-6/+54
| | | | | | | | | | | | | | | | | | | | | Reading from stdin requires to store the ruleset in a buffer so error reporting works accordingly, eg. # cat ruleset.nft | nft -f - /dev/stdin:3:13-13: Error: unknown identifier 'x' ip saddr $x ^ The error reporting infrastructure performs a fseek() on the file descriptor which does not work in this case since the data from the descriptor has been already consumed. This patch adds a new stdin input descriptor to perform this special handling which consists on re-routing this request through the buffer functions. Fixes: 935f82e7dd49 ("Support 'nft -f -' to read from stdin") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* erec: expose print_location() and line_location()Pablo Neira Ayuso2022-01-153-31/+56
| | | | | | | Add a few helper functions to reuse code in the new rule optimization infrastructure. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: simplify logic governing storing payload dependenciesJeremy Sowden2022-01-152-22/+8
| | | | | | | | | | | | | | | | | | | | There are several places where we check whether `ctx->pdctx.pbase` equal to `PROTO_BASE_INVALID` and don't bother trying to free the dependency if so. However, these checks are redundant. In `payload_match_expand` and `trace_gen_stmts`, we skip a call to `payload_dependency_kill`, but that calls `payload_dependency_exists` to check a dependency exists before doing anything else. In `ct_meta_common_postprocess`, we skip an open-coded equivalent to `payload_dependency_kill` which performs some different checks, but the first is the same: a call to `payload_dependency_exists`. Therefore, we can drop the redundant checks and simplify the flow- control in the functions. Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Florian Westphal <fw@strlen.de>
* src: reduce indentationJeremy Sowden2022-01-152-14/+14
| | | | | | | | Re-arrange some switch-cases and conditionals to reduce levels of indentation. Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Florian Westphal <fw@strlen.de>
* src: remove arithmetic on booleansJeremy Sowden2022-01-152-8/+10
| | | | | | | | Instead of subtracting a boolean from the protocol base for stacked payloads, just decrement the base variable itself. Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Florian Westphal <fw@strlen.de>
* netlink_delinearize: fix typoJeremy Sowden2022-01-151-1/+1
| | | | | | | Correct spelling in comment. Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Florian Westphal <fw@strlen.de>
* tests: py: fix inet/ip_tcp.t testJeremy Sowden2022-01-152-2/+14
| | | | | | | | | | | | | | | | | | Contrary to the comment and expected output, nft does _not_ eliminate the redundant `ip protocol` expression from the second test. Dependency elimination requires a higher level expression. `ip saddr` cannot lead to the elimination of `ip protocol` since they are both L3 expressions. `tcp dport` cannot because although `ip saddr` and `ip protocol` both imply that the L3 protocol is `ip`, only protocol matches are stored as dependencies, so the redundancy is not apparent, and in fact, `payload_may_dependency_kill` explicitly checks for the combination of inet, bridge or netdev family, L4 expression and L3 ipv4 or ipv6 dependency and returns false. Correct the expected output and comment. Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Florian Westphal <fw@strlen.de>
* tests: py: fix inet/ip.t payloadsJeremy Sowden2022-01-151-14/+0
| | | | | | | | | | In one of the bridge payloads, the wrong command is given to load the protocol. [ fw@strlen.de: remove the duplicated netdev payload ] Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Florian Westphal <fw@strlen.de>
* tests: py: fix inet/sets.t netdev payloadJeremy Sowden2022-01-151-3/+3
| | | | | | | | The netdev payload for one of the inet/sets.t tests was cut-and-pasted from the inet payload without being properly updated. Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Florian Westphal <fw@strlen.de>
* evaluate: attempt to set_eval flag if dynamic updates requestedFlorian Westphal2022-01-113-0/+54
| | | | | | | | | | | | | When passing no upper size limit, the dynset expression forces an internal 64k upperlimit. In some cases, this can result in 'nft -f' to restore the ruleset. Avoid this by always setting the EVAL flag on a set definition when we encounter packet-path update attempt in the batch. Reported-by: Yi Chen <yiche@redhat.com> Suggested-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: Florian Westphal <fw@strlen.de>
* parser: allow quoted string in flowtable_expr_memberStijn Tintel2021-12-231-1/+8
| | | | | | | | | | | | | | | Devices with interface names starting with a digit can not be configured in flowtables. Trying to do so throws the following error: Error: syntax error, unexpected number, expecting comma or '}' devices = { eth0, 6in4-wan6 }; This is however a perfectly valid interface name. Solve the issue by allowing the use of quoted strings. Suggested-by: Jo-Philipp Wich <jo@mein.io> Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* build: remove scanner.c and parser_bison.c with `maintainer-clean`Jeremy Sowden2021-12-171-2/+0
| | | | | | | | | | | | automake recommends shipping the output of bison and lex in distribution tar-balls and runs bison and lex during `make dist` (this has the advantage that end-users don't need to have bison or lex installed to compile the software). Accordingly, automake also recommends removing these files with `make maintainer-clean` and generates rules to do so. Therefore, remove scanner.c and parser_bison.c from `CLEANFILES`. Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* proto: revisit short-circuit loops over upper protocolsPablo Neira Ayuso2021-12-161-7/+9
| | | | | | | Move the check for NULL protocol description away from the loop to avoid too long line. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* tests: shell: extend catchall tests for mapsPablo Neira Ayuso2021-12-152-0/+11
| | | | | | Add a few tests for the catchall features and maps. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* build: fix autoconf warningsJeremy Sowden2021-12-151-5/+3
| | | | | | | | | | | | | | | | | | | | | | | autoconf complains about three obsolete macros. `AC_CONFIG_HEADER` has been superseded by `AC_CONFIG_HEADERS`, so replace it. `AM_PROG_LEX` calls `AC_PROG_LEX` with no arguments, but this usage is deprecated. The only difference between `AM_PROG_LEX` and `AC_PROG_LEX` is that the former defines `$LEX` as "./build-aux/missing lex" if no lex is found to ensure a useful error is reported when make is run. How- ever, the configure script checks that we have a working lex and exits with an error if none is available, so `$LEX` will never be called and we can replace `AM_PROG_LEX` with `AC_PROG_LEX`. `AM_PROG_LIBTOOL` has been superseded by `LT_INIT`, which is already in configure.ac, so remove it. We can also replace `AC_DISABLE_STATIC` with an argument to `LT_INIT`. Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* tests: shell: remove stray debug flag.Jeremy Sowden2021-12-151-1/+1
| | | | | | | 0040mark_shift_0 was passing --debug=eval to nft. Remove it. Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: reject: support ethernet as L2 protocol for inet tableJeremy Sowden2021-12-154-1/+52
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When we are evaluating a `reject` statement in the `inet` family, we may have `ether` and `ip` or `ip6` as the L2 and L3 protocols in the evaluation context: table inet filter { chain input { type filter hook input priority filter; ether saddr aa:bb:cc:dd:ee:ff ip daddr 192.168.0.1 reject } } Since no `reject` option is given, nft attempts to infer one and fails: BUG: unsupported familynft: evaluate.c:2766:stmt_evaluate_reject_inet_family: Assertion `0' failed. Aborted The reason it fails is that the ethernet protocol numbers for IPv4 and IPv6 (`ETH_P_IP` and `ETH_P_IPV6`) do not match `NFPROTO_IPV4` and `NFPROTO_IPV6`. Add support for the ethernet protocol numbers. Replace the current `BUG("unsupported family")` error message with something more informative that tells the user to provide an explicit reject option. Add a Python test case. Fixes: 5fdd0b6a0600 ("nft: complete reject support") Link: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1001360 Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: correct typo'sJeremy Sowden2021-12-151-2/+2
| | | | | | | There are a couple of mistakes in comments. Fix them. Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* proto: short-circuit loops over upper protocolsJeremy Sowden2021-12-151-3/+7
| | | | | | | | | Each `struct proto_desc` contains a fixed-size array of higher layer protocols. Only the first few are not NULL. Therefore, we can stop iterating over the array once we reach a NULL member. Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* netlink_delinearize: zero shift removalFlorian Westphal2021-12-093-0/+37
| | | | | | | | | | | | | | | | | | | | | | | | | | Remove shifts-by-0. These can occur after binop postprocessing has adjusted the RHS value to account for a mask operation. Example: frag frag-off @s4 Is internally represented via: [ exthdr load ipv6 2b @ 44 + 2 => reg 1 ] [ bitwise reg 1 = ( reg 1 & 0x0000f8ff ) ^ 0x00000000 ] [ bitwise reg 1 = ( reg 1 >> 0x00000003 ) ] [ lookup reg 1 set s ] First binop masks out unwanted parts of the 16-bit field. Second binop needs to left-shift so that lookups in the set will work. When decoding, the first binop is removed after the exthdr load has been adjusted accordingly. Constant propagation adjusts the shift-value to 0 on removal. This change then gets rid of the shift-by-0 entirely. After this change, 'frag frag-off @s4' input is shown as-is. Signed-off-by: Florian Westphal <fw@strlen.de>
* netlink_delinearize: and/shift postprocessingFlorian Westphal2021-12-091-0/+7
| | | | | | | | | | | | | | | | | Before this patch: in: frag frag-off @s4 in: ip version @s8 out: (@nh,0,8 & 0xf0) >> 4 == @s8 out: (frag unknown & 0xfff8 [invalid type]) >> 3 == @s4 after: out: frag frag-off >> 0 == @s4 out: ip version >> 0 == @s8 Next patch adds support for zero-shift removal. Signed-off-by: Florian Westphal <fw@strlen.de>
* payload: skip templates with meta key setFlorian Westphal2021-12-091-0/+3
| | | | | | | | | | | | | | | | | | | | meta templates are only there for ease of use (input/parsing). When listing, they should be ignored: set s4 { typeof ip version elements = { 1, } } chain c4 { ip version @s4 accept } gets listed as 'ip l4proto ...' which is nonsensical. after this patch we get: in: ip version @s4 out: (@nh,0,8 & 0xf0) >> 4 == @s4 .. which is (marginally) better. Next patch adds support for payload decoding. Signed-off-by: Florian Westphal <fw@strlen.de>
* tests: add shift+and typeof test casesFlorian Westphal2021-12-092-0/+29
| | | | | | | | | | | | | | These tests work, but I omitted a few lines that do not: in: frag frag-off @s4 accept in: ip version @s8 out: (frag unknown & 0xfff8 [invalid type]) >> 3 == @s4 out: (ip l4proto & pfsync) >> 4 == @s8 Next patches resolve this. Signed-off-by: Florian Westphal <fw@strlen.de>
* tests: shell: better parameters for the interval stack overflow testŠtěpán Němec2021-12-081-2/+2
| | | | | | | | | | | | | | | | | | Wider testing has shown that 128 kB stack is too low (e.g. for systems with 64 kB page size), leading to false failures in some environments. Based on results from a matrix of RHEL 8 and RHEL 9 systems across x86_64, aarch64, ppc64le and s390x architectures as well as some anecdotal testing of other Linux distros on x86_64 machines, 400 kB seems safe: the normal nft stack (which should stay constant during this test) on all tested systems doesn't exceed 200 kB (stays around 100 kB on typical systems with 4 kB page size), while always growing beyond 500 kB in the failing case (nftables before baecd1cf2685) with the increased set size. Fixes: d8ccad2a2b73 ("tests: cover baecd1cf2685 ("segtree: Fix segfault when restoring a huge interval set")") Signed-off-by: Štěpán Němec <snemec@redhat.com> Signed-off-by: Phil Sutter <phil@nwl.cc>
* iptopt: fix crash with invalid field/type comboFlorian Westphal2021-12-074-4/+18
| | | | | | | | | | | | | | | % nft describe ip option rr value segmentation fault after this fix, this exits with 'Error: unknown ip option type/field'. Problem is that 'rr' doesn't have a value template, so the template struct is all-zeroes, so we crash when trying to use tmpl->dtype (its NULL). Furthermore, expr_describe tries to print expr->identifier but expr is exthdr, not symbol: ->identifier contains garbage. Signed-off-by: Florian Westphal <fw@strlen.de>
* exthdr: support ip/tcp options and sctp chunks in typeof expressionsFlorian Westphal2021-12-073-7/+94
| | | | | | | | | This did not store the 'op' member and listing always treated this as ipv6 extension header. Add test cases for this. Signed-off-by: Florian Westphal <fw@strlen.de>
* ipopt: drop unused 'ptr' argumentFlorian Westphal2021-12-074-26/+7
| | | | | | | | | Its always 0, so remove it. Looks like this was intended to support variable options that have array-like members, but so far this isn't implemented, better remove dead code and implement it properly when such support is needed. Signed-off-by: Florian Westphal <fw@strlen.de>
* cache: Support filtering for a specific flowtablePhil Sutter2021-12-036-24/+103
| | | | | | | | | | Extend nft_cache_filter to hold a flowtable name so 'list flowtable' command causes fetching the requested flowtable only. Dump flowtables just once instead of for each table, merely assign fetched data to tables inside the loop. Signed-off-by: Phil Sutter <phil@nwl.cc>
* cache: Filter set list on server sidePhil Sutter2021-12-033-31/+49
| | | | | | | | | Fetch either all tables' sets at once, a specific table's sets or even a specific set if needed instead of iterating over the list of previously fetched tables and fetching for each, then ignoring anything returned that doesn't match the filter. Signed-off-by: Phil Sutter <phil@nwl.cc>
* cache: Filter chain list on kernel sidePhil Sutter2021-12-033-23/+39
| | | | | | | | | | | | | When operating on a specific chain, add payload to NFT_MSG_GETCHAIN so kernel returns only relevant data. Since ENOENT is an expected return code, do not treat this as error. While being at it, improve code in chain_cache_cb() a bit: - Check chain's family first, it is a less expensive check than comparing table names. - Do not extract chain name of uninteresting chains. Signed-off-by: Phil Sutter <phil@nwl.cc>
* cache: Filter rule list on kernel sidePhil Sutter2021-12-033-24/+24
| | | | | | | | | | | Instead of fetching all existing rules in kernel's ruleset and filtering in user space, add payload to the dump request specifying the table and chain to filter for. Since list_rule_cb() no longer needs the filter, pass only netlink_ctx to the callback and drop struct rule_cache_dump_ctx. Signed-off-by: Phil Sutter <phil@nwl.cc>
* cache: Filter tables on kernel sidePhil Sutter2021-12-035-15/+33
| | | | | | | | | | | Instead of requesting a dump of all tables and filtering the data in user space, construct a non-dump request if filter contains a table so kernel returns only that single table. This should improve nft performance in rulesets with many tables present. Signed-off-by: Phil Sutter <phil@nwl.cc>
* tests: py: add tcp subtype match test casesFlorian Westphal2021-12-013-0/+78
| | | | Signed-off-by: Florian Westphal <fw@strlen.de>
* exthdr: fix tcpopt_find_template to use length after mask adjustmentFlorian Westphal2021-12-013-30/+27
| | | | | | | | | | | | | | | | | | | | | | Unify binop handling for ipv6 extension header, ip option and tcp option processing. Pass the real offset and length expected, not the one used in the kernel. This was already done for extension headers and ip options, but tcp option parsing did not do this. This was fine before because no existing tcp option template had a non-byte sized member. With mptcp addition this isn't the case anymore, subtype field is only 4 bits wide, but tcp option delinearization passed 8bits instead. Pass the offset and mask delta, just like ip option/ipv6 exthdr. This makes nft show 'tcp option mptcp subtype 1' instead of 'tcp option mptcp unknown & 240 == 16'. Signed-off-by: Florian Westphal <fw@strlen.de>