summaryrefslogtreecommitdiffstats
path: root/src/evaluate.c
Commit message (Collapse)AuthorAgeFilesLines
* evaluate: disregard ct address matching without familyPablo Neira Ayuso2020-07-311-0/+6
| | | | | | | | | | | | | | | | | | | | | | | | The following rule: # nft add rule ip x y ct original daddr @servers breaks with: # nft list ruleset nft: netlink_delinearize.c:124: netlink_parse_concat_expr: Assertion `consumed > 0' failed. Aborted Bail out if this syntax is used, instead users should rely on: # nft add rule ip x y ct original ip daddr @servers ~~ which uses NFT_CT_{SRC,DST}_{IP,IP6} in the bytecode generation. This issue is described in 7f742d0a9071 ("ct: support for NFT_CT_{SRC,DST}_{IP,IP6}"). Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: UAF in hook priority expressionPablo Neira Ayuso2020-07-291-1/+1
| | | | | | | | Release priority expression right before assigning the constant expression that results from the evaluation. Fixes: 627c451b2351 ("src: allow variables in the chain priority specification") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: memleak in invalid default policy definitionPablo Neira Ayuso2020-07-291-1/+3
| | | | | | | Release the clone expression from the exit path. Fixes: 5173151863d3 ("evaluate: replace variable expression by the value expression") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: remove table from cache on delete tablePablo Neira Ayuso2020-07-291-0/+15
| | | | | | | | | | | | | | | | | | | | | The following ruleset crashes nft if loaded twice, via nft -ef: add table inet filter delete table inet filter table inet filter { chain input { type filter hook input priority filter; policy drop; iifname { "eth0" } counter accept } } If the table contains anonymous sets, such as __set0, then delete + add table might result in nft reusing the existing stale __set0 in the cache. The problem is that nft gets confused and it reuses the existing stale __set0 instead of the new anonymous set __set0 with the same name. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: remove cache lookups after the evaluation phasePablo Neira Ayuso2020-07-291-5/+8
| | | | | | | | | | | | This patch adds a new field to the cmd structure for elements to store a reference to the set. This saves an extra lookup in the netlink bytecode generation step. This patch also allows to incrementally update during the evaluation phase according to the command actions, which is required by the follow up ("evaluate: remove table from cache on delete table") bugfix patch. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: flush set cache from the evaluation phasePablo Neira Ayuso2020-07-291-0/+15
| | | | | | | | This patch reworks 40ef308e19b6 ("rule: flush set cache before flush command"). This patch flushes the set cache earlier, from the command evaluation step. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: bail out with concatenations and singleton valuesPablo Neira Ayuso2020-07-241-0/+4
| | | | | | | | | | | | | | | | | | | | | | | | The rule: # nft add rule x y iifname . oifname p . q is equivalent to: # nft add rule x y iifname p oifname q Bail out with: Error: Use concatenations with sets and maps, not singleton values add rule x y iifname . oifname p . q ^^^^^^^^^^^^^^^^^ ~~~~~ instead of: BUG: invalid expression type concat nft: evaluate.c:1916: expr_evaluate_relational: Assertion `0' failed. Aborted Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: replace variable expression by the value expressionPablo Neira Ayuso2020-07-221-1/+4
| | | | | | | | The variable expression provides the binding between the variable dereference and the value expression. Replace the variable expression by the real value expression after the evaluation. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: permit get element on mapsFlorian Westphal2020-07-221-12/+0
| | | | | | | | | | | | | | | | | | | | | | Its possible to add an element to a map, but you can't read it back: before: nft add element inet filter test "{ 18.51.100.17 . ad:c1:ac:c0:ce:c0 . 3761 : 0x42 }" nft get element inet filter test "{ 18.51.100.17 . ad:c1:ac:c0:ce:c0 . 3761 : 0x42 }" Error: No such file or directory; did you mean map ‘test’ in table inet ‘filter’? get element inet filter test { 18.51.100.17 . ad:c1:ac:c0:ce:c0 . 3761 : 0x42 } ^^^^ after: nft get element inet filter test "{ 18.51.100.17 . ad:c1:ac:c0:ce:c0 . 3761 : 0x42 }" table inet filter { map test { type ipv4_addr . ether_addr . inet_service : mark flags interval,timeout elements = { 18.51.100.17 . ad:c1:ac:c0:ce:c0 . 3761 : 0x00000042 } } } Signed-off-by: Florian Westphal <fw@strlen.de>
* evaluate: use evaluate_expr_variable() for chain policy evaluationPablo Neira Ayuso2020-07-211-20/+3
| | | | | | evaluate_policy() is very similar to evaluate_expr_variable(), replace it. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: allow to use variables in flowtable and chain devicesPablo Neira Ayuso2020-07-211-0/+69
| | | | | | | | | | | | | | | This patch adds support for using variables for devices in the chain and flowtable definitions, eg. define if_main = lo table netdev filter1 { chain Main_Ingress1 { type filter hook ingress device $if_main priority -500; policy accept; } } Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: UAF in stmt_evaluate_log_prefix()Pablo Neira Ayuso2020-07-151-5/+4
| | | | | | | | Release existing list expression including variables after creating the prefix string. Fixes: 96c909ef46f0 ("src: allow for variables in the log prefix string") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: support for implicit chain bindingsPablo Neira Ayuso2020-07-151-1/+60
| | | | | | | | | | | | | | | | | | | | | | | | | | | This patch allows you to group rules in a subchain, e.g. table inet x { chain y { type filter hook input priority 0; tcp dport 22 jump { ip saddr { 127.0.0.0/8, 172.23.0.0/16, 192.168.13.0/24 } accept ip6 saddr ::1/128 accept; } } } This also supports for the `goto' chain verdict. This patch adds a new chain binding list to avoid a chain list lookup from the delinearize path for the usual chains. This can be simplified later on with a single hashtable per table for all chains. From the shell, you have to use the explicit separator ';', in bash you have to escape this: # nft add rule inet x y tcp dport 80 jump { ip saddr 127.0.0.1 accept\; ip6 saddr ::1 accept \; } Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: allow for variables in the log prefix stringPablo Neira Ayuso2020-07-081-1/+48
| | | | | | | | | | | | | | | | | | | For example: define test = "state" define foo = "match" table x { chain y { ct state invalid log prefix "invalid $test $foo:" } } This patch scans for variables in the log prefix string. The log prefix expression is a list of constant and variable expression that are converted into a constant expression from the evaluation phase. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: Allow for empty set variable definitionPablo Neira Ayuso2020-07-041-0/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Allow for empty set definition in variables if they are merged to non-empty set definition: define BASE_ALLOWED_INCOMING_TCP_PORTS = {22, 80, 443} define EXTRA_ALLOWED_INCOMING_TCP_PORTS = {} table inet filter { chain input { type filter hook input priority 0; policy drop; tcp dport {$BASE_ALLOWED_INCOMING_TCP_PORTS, $EXTRA_ALLOWED_INCOMING_TCP_PORTS} ct state new counter accept } } However, disallow this: define EXTRA_ALLOWED_INCOMING_TCP_PORTS = {} table inet filter { chain input { type filter hook input priority 0; policy drop; tcp dport {$EXTRA_ALLOWED_INCOMING_TCP_PORTS} ct state new counter accept } } # nft -f x.nft /tmp/x.nft:6:18-52: Error: Set is empty tcp dport {$EXTRA_ALLOWED_INCOMING_TCP_PORTS} ct state new counter accept ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: remove superfluous check in set_evaluate()Pablo Neira Ayuso2020-06-071-5/+0
| | | | | | If set_is_objmap() is true, then set->data is always NULL. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: missing datatype definition in implicit_set_declaration()Pablo Neira Ayuso2020-06-071-10/+12
| | | | | | | | | | | | | | | | | | | | | | set->data from implicit_set_declaration(), otherwise, set_evaluation() bails out with: # nft -f /etc/nftables/inet-filter.nft /etc/nftables/inet-filter.nft:8:32-54: Error: map definition does not specify mapping data type tcp dport vmap { 22 : jump ssh_input } ^^^^^^^^^^^^^^^^^^^^^^^ /etc/nftables/inet-filter.nft:13:26-52: Error: map definition does not specify mapping data type iif vmap { "eth0" : jump wan_input } ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Add a test to cover this case. Fixes: 7aa08d45031e ("evaluate: Perform set evaluation on implicitly declared (anonymous) sets") Closes: https://bugzilla.kernel.org/show_bug.cgi?id=208093 Reviewed-by: Stefano Brivio <sbrivio@redhat.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: add devices to an existing flowtablePablo Neira Ayuso2020-06-021-11/+10
| | | | | | | | This patch allows you to add new devices to an existing flowtables. # nft add flowtable x y { devices = { eth0 } \; } Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: Perform set evaluation on implicitly declared (anonymous) setsStefano Brivio2020-05-281-10/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | If a set is implicitly declared, set_evaluate() is not called as a result of cmd_evaluate_add(), because we're adding in fact something else (e.g. a rule). Expression-wise, evaluation still happens as the implicit set expression is eventually found in the tree and handled by expr_evaluate_set(), but context-wise evaluation (set_evaluate()) is skipped, and this might be relevant instead. This is visible in the reported case of an anonymous set including concatenated ranges: # nft add rule t c ip saddr . tcp dport { 192.0.2.1 . 20-30 } accept BUG: invalid range expression type concat nft: expression.c:1160: range_expr_value_low: Assertion `0' failed. Aborted because we reach do_add_set() without properly evaluated flags and set description, and eventually end up in expr_to_intervals(), which can't handle that expression. Explicitly call set_evaluate() as we add anonymous sets into the context, and instruct the same function to: - skip expression-wise set evaluation if the set is anonymous, as that happens later anyway as part of the general tree evaluation - skip the insertion in the set cache, as it makes no sense to have sets that shouldn't be referenced there For object maps, the allocation of the expression for set->data is already handled by set_evaluate(), so we can now drop that from stmt_evaluate_objref_map(). v2: - skip insertion of set in cache (Pablo Neira Ayuso) - drop double allocation of expression (and leak of the first one) for object maps (Pablo Neira Ayuso) Reported-by: Pablo Neira Ayuso <pablo@netfilter.org> Reported-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Stefano Brivio <sbrivio@redhat.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: enable reject with 802.1qMichael Braun2020-05-281-1/+1
| | | | | | | | | | | | This enables the use nft bridge reject with bridge vlan filtering. It depends on a kernel patch to make the kernel preserve the vlan id in nft bridge reject generation. [ pablo: update tests/py ] Signed-off-by: Michael Braun <michael-dev@fami-braun.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: rename CMD_OBJ_SETELEM to CMD_OBJ_ELEMENTSPablo Neira Ayuso2020-05-141-3/+3
| | | | | | | | The CMD_OBJ_ELEMENTS provides an expression that contains the list of set elements. This leaves room to introduce CMD_OBJ_SETELEMS in a follow up patch. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* mnl: fix error rule reporting with missing table/chain and anonymous setsPablo Neira Ayuso2020-05-141-0/+1
| | | | | | | | | | | | | | | | | handle_merge() skips handle location initialization because set name != NULL. Program received signal SIGSEGV, Segmentation fault. 0x00007ffff7f64f1e in erec_print (octx=0x55555555d2c0, erec=0x55555555fcf0, debug_mask=0) at erec.c:95 95 switch (indesc->type) { (gdb) bt buf=0x55555555db20 "add rule inet traffic-filter input tcp dport { 22, 80, 443 } accept") at libnftables.c:459 (gdb) p indesc $1 = (const struct input_descriptor *) 0x0 Closes: http://bugzilla.opensuse.org/show_bug.cgi?id=1171321 Fixes: 086ec6f30c96 ("mnl: extended error support for create command") Reported-by: Jan Engelhardt <jengelh@inai.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: fix memleak in stmt_evaluate_reject_icmp()Pablo Neira Ayuso2020-05-061-0/+2
| | | | | | | | | | | | | | | | | | ==26297==ERROR: LeakSanitizer: detected memory leaks c Direct leak of 512 byte(s) in 4 object(s) allocated from: #0 0x7f46f8167330 in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.5+0xe9330) #1 0x7f46f7b3cf1c in xmalloc /home/pablo/devel/scm/git-netfilter/nftables/src/utils.c:36 #2 0x7f46f7b3d075 in xzalloc /home/pablo/devel/scm/git-netfilter/nftables/src/utils.c:65 #3 0x7f46f7a85760 in expr_alloc /home/pablo/devel/scm/git-netfilter/nftables/src/expression.c:45 #4 0x7f46f7a8915d in constant_expr_alloc /home/pablo/devel/scm/git-netfilter/nftables/src/expression.c:388 #5 0x7f46f7a7bad4 in symbolic_constant_parse /home/pablo/devel/scm/git-netfilter/nftables/src/datatype.c:173 #6 0x7f46f7a7af5f in symbol_parse /home/pablo/devel/scm/git-netfilter/nftables/src/datatype.c:132 #7 0x7f46f7abf2bd in stmt_evaluate_reject_icmp /home/pablo/devel/scm/git-netfilter/nftables./src/evaluate.c:2739 [...] SUMMARY: AddressSanitizer: 544 byte(s) leaked in 8 allocation(s). Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: ct_timeout: release policy string and state listPablo Neira Ayuso2020-05-051-0/+1
| | | | | | | | | | | | | | | | | | | ================================================================= ==19037==ERROR: LeakSanitizer: detected memory leaks Direct leak of 18 byte(s) in 2 object(s) allocated from: #0 0x7ff6ee6f9810 in strdup (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x3a810) #1 0x7ff6ee22666d in xstrdup /home/pablo/devel/scm/git-netfilter/nftables/src/utils.c:75 #2 0x7ff6ee28cce9 in nft_parse /home/pablo/devel/scm/git-netfilter/nftables/src/parser_bison.c:5792 #3 0x4b903f302c8010a (<unknown module>) Direct leak of 16 byte(s) in 1 object(s) allocated from: #0 0x7ff6ee7a8330 in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.5+0xe9330) #1 0x7ff6ee226578 in xmalloc /home/pablo/devel/scm/git-netfilter/nftables/src/utils.c:36 SUMMARY: AddressSanitizer: 34 byte(s) leaked in 3 allocation(s). Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: add rule_stmt_insert_at() and use itPablo Neira Ayuso2020-05-051-4/+5
| | | | | | | | | | | | | | | | | | | | | | | | This helper function adds a statement at a given position and it updates the rule statement counter. This patch fixes this: flush table bridge test-bridge add rule bridge test-bridge input vlan id 1 ip saddr 10.0.0.1 rule.c:2870:5: runtime error: index 2 out of bounds for type 'stmt *[*]' ================================================================= ==1043==ERROR: AddressSanitizer: dynamic-stack-buffer-overflow on address 0x7ffdd69c1350 at pc 0x7f1036f53330 bp 0x7ffdd69c1300 sp 0x7ffdd69c12f8 WRITE of size 8 at 0x7ffdd69c1350 thread T0 #0 0x7f1036f5332f in payload_try_merge /home/mbr/nftables/src/rule.c:2870 #1 0x7f1036f534b7 in rule_postprocess /home/mbr/nftables/src/rule.c:2885 #2 0x7f1036fb2785 in rule_evaluate /home/mbr/nftables/src/evaluate.c:3744 #3 0x7f1036fb627b in cmd_evaluate_add /home/mbr/nftables/src/evaluate.c:3982 #4 0x7f1036fbb9e9 in cmd_evaluate /home/mbr/nftables/src/evaluate.c:4462 #5 0x7f10370652d2 in nft_evaluate /home/mbr/nftables/src/libnftables.c:414 #6 0x7f1037065ba1 in nft_run_cmd_from_buffer /home/mbr/nftables/src/libnftables.c:447 Reported-by: Michael Braun <michael-dev@fami-braun.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: incorrect byteorder with typeof and integer_datatypePablo Neira Ayuso2020-04-291-1/+2
| | | | | | | | | | | | | | | | | | | | table bridge t { set s3 { typeof meta ibrpvid elements = { 2, 3, 103 } } } # nft --debug=netlink -f test.nft s3 t 0 s3 t 0 element 00000100 : 0 [end] element 00000200 : 0 [end] element 00000300 : 0 [end] ^^^^^^^^ The integer_type uses BYTEORDER_INVALID byteorder (which is implicitly handled as BYTEORDER_BIG_ENDIAN). Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: fix crash when handling concatenation without mapPablo Neira Ayuso2020-04-281-0/+3
| | | | | | | | Fix a crash when map is not specified, e.g. nft add rule x y snat ip addr . port to 1.1.1.1 . 22 Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: add STMT_NAT_F_CONCAT flag and use itPablo Neira Ayuso2020-04-281-1/+1
| | | | | | Replace ipportmap boolean field by flags. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: NAT support for intervals in mapsPablo Neira Ayuso2020-04-281-2/+43
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This patch allows you to specify an interval of IP address in maps. table ip x { chain y { type nat hook postrouting priority srcnat; policy accept; snat ip interval to ip saddr map { 10.141.11.4 : 192.168.2.2-192.168.2.4 } } } The example above performs SNAT to packets that comes from 10.141.11.4 to an interval of IP addresses from 192.168.2.2 to 192.168.2.4 (both included). You can also combine this with dynamic maps: table ip x { map y { type ipv4_addr : interval ipv4_addr flags interval elements = { 10.141.10.0/24 : 192.168.2.2-192.168.2.4 } } chain y { type nat hook postrouting priority srcnat; policy accept; snat ip interval to ip saddr map @y } } Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: Set NFT_SET_CONCAT flag for sets with concatenated rangesStefano Brivio2020-04-141-1/+8
| | | | | | | | | | | | | | | | | | | | | | | Pablo reports that nft, after commit 8ac2f3b2fca3 ("src: Add support for concatenated set ranges"), crashes with older kernels (< 5.6) without support for concatenated set ranges: those sets will be sent to the kernel, which adds them without notion of the fact that different concatenated fields are actually included, and nft crashes while trying to list this kind of malformed concatenation. Use the NFT_SET_CONCAT flag introduced by kernel commit ef516e8625dd ("netfilter: nf_tables: reintroduce the NFT_SET_CONCAT flag") when sets including concatenated ranges are sent to the kernel, so that older kernels (with no knowledge of this flag itself) will refuse set creation. Note that, in expr_evaluate_set(), we have to check for the presence of the flag, also on empty sets that might carry it in context data, and actually set it in the actual set flags. Reported-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: Stefano Brivio <sbrivio@redhat.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: check for device in non-netdev chainsPablo Neira Ayuso2020-03-311-0/+3
| | | | | | | | | # nft -f /tmp/x /tmp/x:3:26-36: Error: This chain type cannot be bound to device type filter hook input device eth0 priority 0 ^^^^^^^^^^^ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: improve error reporting in netdev ingress chainPablo Neira Ayuso2020-03-311-2/+9
| | | | | | | | | | | | | | # nft -f /tmp/x.nft /tmp/x.nft:3:20-24: Error: The netdev family does not support this hook type filter hook input device eth0 priority 0 ^^^^^ # nft -f /tmp/x.nft /tmp/x.nft:3:3-49: Error: Missing `device' in this chain definition type filter hook ingress device eth0 priority 0 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* rule: add hook_specPablo Neira Ayuso2020-03-311-9/+9
| | | | | | Store location of chain hook definition. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: display error if set statement is missingPablo Neira Ayuso2020-03-271-7/+15
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | # cat /tmp/x table x { set y { type ipv4_addr elements = { 1.1.1.1 counter packets 1 bytes 67, } } } # nft -f /tmp/x /tmp/x:5:12-18: Error: missing counter statement in set definition 1.1.1.1 counter packets 1 bytes 67, ^^^^^^^^^^^^^^^^^^^^^^^^^^ Instead, this should be: table x { set y { type ipv4_addr counter <------- elements = { 1.1.1.1 counter packets 1 bytes 67, } } } Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: support for counter in set definitionPablo Neira Ayuso2020-03-201-0/+9
| | | | | | | | | | | | | | | | | | | | | This patch allows you to turn on counter for each element in the set. table ip x { set y { typeof ip saddr counter elements = { 192.168.10.35, 192.168.10.101, 192.168.10.135 } } chain z { type filter hook output priority filter; policy accept; ip daddr @y } } This example shows how to turn on counters globally in the set 'y'. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: add range specified flag setting (missing ↵Pablo Neira Ayuso2020-03-191-0/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | NF_NAT_RANGE_PROTO_SPECIFIED) Sergey reports: With nf_tables it is not possible to use port range for masquerading. Masquerade statement has option "to [:port-port]" which give no effect to translation behavior. But it must change source port of packet to one from ":port-port" range. My network: +-----------------------------+ | ROUTER | | | | Masquerade| | 10.0.0.1 1.1.1.1 | | +------+ +------+ | | | eth1 | | eth2 | | +-+--^---+-----------+---^--+-+ | | | | +----v------+ +------v----+ | | | | | 10.0.0.2 | | 1.1.1.2 | | | | | |PC1 | |PC2 | +-----------+ +-----------+ For testing i used rule like this: rule ip nat POSTROUTING oifname eth2 masquerade to :666 Run netcat for 1.1.1.2 667(UDP) and get dump from PC2: 15:22:25.591567 a8:f9:4b:aa:08:44 > a8:f9:4b:ac:e7:8f, ethertype IPv4 (0x0800), length 60: 1.1.1.1.34466 > 1.1.1.2.667: UDP, length 1 Address translation works fine, but source port are not belongs to specified range. I see in similar source code (i.e. nft_redir.c, nft_nat.c) that there is setting NF_NAT_RANGE_PROTO_SPECIFIED flag. After adding this, repeat test for kernel with this patch, and get dump: 16:16:22.324710 a8:f9:4b:aa:08:44 > a8:f9:4b:ac:e7:8f, ethertype IPv4 (0x0800), length 60: 1.1.1.1.666 > 1.1.1.2.667: UDP, length 1 Now it is works fine. Reported-by: Sergey Marinkevich <s@marinkevich.ru> Tested-by: Sergey Marinkevich <s@marinkevich.ru> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: fix leaks.Jeremy Sowden2020-03-041-0/+2
| | | | | | | Some bitmask variables are not cleared. Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Florian Westphal <fw@strlen.de>
* evaluate: no need to swap byte-order for values of fewer than 16 bits.Jeremy Sowden2020-03-041-1/+1
| | | | | | | | | Endianness is not meaningful for objects smaller than 2 bytes and the byte-order conversions are no-ops in the kernel, so just update the expression as if it were constant. Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Florian Westphal <fw@strlen.de>
* evaluate: convert the byte-order of payload statement arguments.Jeremy Sowden2020-03-041-0/+5
| | | | | | | | | | | Since shift operations require host byte-order, we need to be able to convert the result of the shift back to network byte-order, in a rule like: nft add rule ip t c tcp dport set tcp dport lshift 1 Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Florian Westphal <fw@strlen.de>
* evaluate: don't evaluate payloads twice.Jeremy Sowden2020-03-041-0/+5
| | | | | | | | | Payload munging means that evaluation of payload expressions may not be idempotent. Add a flag to prevent them from being evaluated more than once. Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Florian Westphal <fw@strlen.de>
* evaluate: simplify calculation of payload size.Jeremy Sowden2020-03-041-2/+2
| | | | | | | Use div_round_up and one statement. Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Florian Westphal <fw@strlen.de>
* evaluate: add separate variables for lshift and xor binops.Jeremy Sowden2020-03-041-17/+17
| | | | | | | | stmt_evaluate_payload has distinct variables for some, but not all, the binop expressions it creates. Add variables for the rest. Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Florian Westphal <fw@strlen.de>
* evaluate: stmt_evaluate_nat_map() only if stmt->nat.ipportmap == truePablo Neira Ayuso2020-02-251-17/+11
| | | | | | | stmt_evaluate_nat_map() is only called when the parser sets on stmt->nat.ipportmap. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: nat concatenation support with anonymous mapsPablo Neira Ayuso2020-02-241-3/+20
| | | | | | | | | This patch extends the parser to define the mapping datatypes, eg. ... dnat ip addr . port to ip saddr map { 1.1.1.1 : 2.2.2.2 . 30 } ... dnat ip addr . port to ip saddr map @y Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: allow nat maps containing both ip(6) address and portFlorian Westphal2020-02-241-0/+56
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | nft will now be able to handle map destinations { type ipv4_addr . inet_service : ipv4_addr . inet_service } chain f { dnat to ip daddr . tcp dport map @destinations } Something like this won't work though: meta l4proto tcp dnat ip6 to numgen inc mod 4 map { 0 : dead::f001 . 8080, .. as we lack the type info to properly dissect "dead::f001" as an ipv6 address. For the named map case, this info is available in the map definition, but for the anon case we'd need to resort to guesswork. Support is added by peeking into the map definition when evaluating a nat statement with a map. Right now, when a map is provided as address, we will only check that the mapped-to data type matches the expected size (of an ipv4 or ipv6 address). After this patch, if the mapped-to type is a concatenation, it will take a peek at the individual concat expressions. If its a combination of address and service, nft will translate this so that the kernel nat expression looks at the returned register that would store the inet_service part of the octet soup returned from the lookup expression. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: add two new helpersFlorian Westphal2020-02-241-29/+32
| | | | | | | | | | | In order to support 'dnat to ip saddr map @foo', where @foo returns both an address and a inet_service, we will need to peek into the map and process the concatenations sub-expressions. Add two helpers for this, will be used in followup patches. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: process concat expressions when used as mapped-to exprFlorian Westphal2020-02-241-0/+4
| | | | | | | | | Needed to avoid triggering the 'dtype->size == 0' tests. Evaluation will build a new concatenated type that holds the size of the aggregate. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: print correct statement name on family mismatchFlorian Westphal2020-02-221-2/+3
| | | | | | | | | | nft add rule inet filter c ip daddr 1.2.3.4 dnat ip6 to f00::1 Error: conflicting protocols specified: ip vs. unknown. You must specify ip or ip6 family in tproxy statement Should be: ... "in nat statement". Fixes: fbe27464dee4588d90 ("src: add nat support for the inet family") Signed-off-by: Florian Westphal <fw@strlen.de>
* evaluate: change shift byte-order to host-endian.Jeremy Sowden2020-02-071-1/+1
| | | | | | | | | | | The byte-order of the righthand operands of the right-shifts generated for payload and exthdr expressions is big-endian. However, all right operands should be host-endian. Since evaluation of the shift binop will insert a byte-order conversion to enforce this, change the endianness in order to avoid the extra operation. Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: correct variable name.Jeremy Sowden2020-02-071-6/+6
| | | | | | | | Rename the `lshift` variable used to store an right-shift expression to `rshift`. Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>