summaryrefslogtreecommitdiffstats
path: root/src/evaluate.c
Commit message (Collapse)AuthorAgeFilesLines
* src: add support to flush setsPablo Neira Ayuso2016-12-051-0/+3
| | | | | | | | | | You can use this new command to remove all existing elements in a set: # nft flush set filter xyz After this command, the set 'xyz' in table 'filter' becomes empty. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: return ctx->table from table_lookup_global()Pablo Neira Ayuso2016-12-011-1/+1
| | | | | | | | | | Instead of returning ctx->cmd->table. Note that ctx->cmd->table and ctx->table points to the same object when all commands are embedded into the table definition. But this is not true if we mix table definitions with linear list commands in one file that we load via nft -f. Reported-by: Martin Bednar <martin@serafean.cz> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: Update cache on flush rulesetAnatole Denis2016-12-011-1/+24
| | | | | | | | | | | | | | After a flush, the cache should be empty, otherwise the cache and the expected state are desynced, causing unwarranted errors. See tests/shell/testcases/cache/0002_interval_0. `flush table` and `flush chain` don't empty sets or destroy chains, so the cache does not need an update in those cases, since only chain names and set contents are held in cache for commands other than "list" Reported-by: Leon Merten Lohse <leon@green-side.de> Signed-off-by: Anatole Denis <anatole@rezel.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: Interpret OP_NEQ against a set as OP_LOOKUPAnatole Denis2016-11-291-0/+14
| | | | | | | | | | Now that the support for inverted matching is in the kernel and in libnftnl, add it to nftables too. This fixes bug #888 Signed-off-by: Anatole Denis <anatole@rezel.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* Revert "evaluate: check for NULL datatype in rhs in lookup expr"Anatole Denis2016-11-291-23/+8
| | | | | | | | | This reverts commit 5afa5a164ff1c066af1ec56d875b91562882bd50. This commit is obsoleted by removing the possibility for a NULL right->dtype in the first place, at set declaration. Signed-off-by: Anatole Denis <anatole@rezel.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: Add set to cache only when well-formedAnatole Denis2016-11-291-3/+3
| | | | | | | | | | | | | | | When creating a set (in set_evaluate), it is added to the table cache before being checked for correctness. When the set is ill-formed, the function returns without removing the (non-existent, since the function returned) set. Further references to this set will not result in an error (since the set is in the lookup table), but the malformed set will probably cause a segfault. The symptom (the segfault) was fixed by checking for NULL when evaluating a reference to the set (commit 5afa5a164ff1c066af1ec56d875b91562882bd50), this should fix the root cause. Signed-off-by: Anatole Denis <anatole@rezel.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: add log flags syntax supportLiping Zhang2016-11-241-5/+7
| | | | | | | | | | | | | | | | | | | | | Now NF_LOG_XXX is exposed to the userspace, we can set it explicitly. Like iptables LOG target, we can log TCP sequence numbers, TCP options, IP options, UID owning local socket and decode MAC header. Note the log flags are mutually exclusive with group. Some examples are listed below: # nft add rule t c log flags tcp sequence,options # nft add rule t c log flags ip options # nft add rule t c log flags skuid # nft add rule t c log flags ether # nft add rule t c log flags all # nft add rule t c log flags all group 1 <cmdline>:1:14-16: Error: flags and group are mutually exclusive add rule t c log flags all group 1 ^^^ Signed-off-by: Liping Zhang <zlpnobody@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: add notrack supportPablo Neira Ayuso2016-11-141-0/+1
| | | | | | | This patch adds the notrack statement, to skip connection tracking for certain packets. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: Allow concatenation of rt nexthop etc.Anders K. Pedersen2016-10-311-7/+7
| | | | | | | | | | | | | | | | | | | Concatenations of rt nexthop or ct {orignal | reply} {saddr | daddr} fail due to # nft add rule ip filter postrouting flow table acct \{ ip saddr . rt nexthop counter \} <cmdline>:1:61-70: Error: can not use variable sized data types (invalid) in concat expressions add rule ip filter postrouting flow table acct { ip saddr . rt nexthop counter } ~~~~~~~~~~~^^^^^^^^^^ Fix this by reordering the check for variable size data types in expr_evaluate_concat() to happen after expr_evaluate() has been called (via list_member_evaluate()) for the sub expression. This allows expr_evaluate_[cr]t() to call [cr]t_expr_update_type() and set the data type before the check. Signed-off-by: Anders K. Pedersen <akp@cohaesio.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* Replace tests/files/expr-rt with Python based tests, and replace ether typeAnders K. Pedersen2016-10-291-2/+2
| | | | | | | with meta nfproto, which generates a bit fewer instructions. Signed-off-by: Anders K. Pedersen <akp@cohaesio.com> Signed-off-by: Florian Westphal <fw@strlen.de>
* src: add fib expressionFlorian Westphal2016-10-281-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This adds the 'fib' expression which can be used to obtain the output interface from the route table based on either source or destination address of a packet. This can be used to e.g. add reverse path filtering: # drop if not coming from the same interface packet # arrived on # nft add rule x prerouting fib saddr . iif oif eq 0 drop # accept only if from eth0 # nft add rule x prerouting fib saddr . iif oif eq "eth0" accept # accept if from any valid interface # nft add rule x prerouting fib saddr oif accept Querying of address type is also supported. This can be used to e.g. only accept packets to addresses configured in the same interface: # fib daddr . iif type local Its also possible to use mark and verdict map, e.g.: # nft add rule x prerouting meta mark set 0xdead fib daddr . mark type vmap { blackhole : drop, prohibit : drop, unicast : accept } Signed-off-by: Florian Westphal <fw@strlen.de>
* rt: introduce routing expressionAnders K. Pedersen2016-10-281-0/+34
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Introduce rt expression for routing related data with support for nexthop (i.e. the directly connected IP address that an outgoing packet is sent to), which can be used either for matching or accounting, eg. # nft add rule filter postrouting \ ip daddr 192.168.1.0/24 rt nexthop != 192.168.0.1 drop This will drop any traffic to 192.168.1.0/24 that is not routed via 192.168.0.1. # nft add rule filter postrouting \ flow table acct { rt nexthop timeout 600s counter } # nft add rule ip6 filter postrouting \ flow table acct { rt nexthop timeout 600s counter } These rules count outgoing traffic per nexthop. Note that the timeout releases an entry if no traffic is seen for this nexthop within 10 minutes. # nft add rule inet filter postrouting \ ether type ip \ flow table acct { rt nexthop timeout 600s counter } # nft add rule inet filter postrouting \ ether type ip6 \ flow table acct { rt nexthop timeout 600s counter } Same as above, but via the inet family, where the ether type must be specified explicitly. "rt classid" is also implemented identical to "meta rtclassid", since it is more logical to have this match in the routing expression going forward. Signed-off-by: Anders K. Pedersen <akp@cohaesio.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: display expression, statement and command name on debugPablo Neira Ayuso2016-09-051-3/+31
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Extend debugging knob for evaluation to display the command, the expression and statement names. # nft --debug=eval add rule x y ip saddr 1.1.1.1 counter <cmdline>:1:1-37: Evaluate add add rule x y ip saddr 1.1.1.1 counter ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ <cmdline>:1:14-29: Evaluate expression add rule x y ip saddr 1.1.1.1 counter ^^^^^^^^^^^^^^^^ ip saddr $1.1.1.1 <cmdline>:1:14-29: Evaluate relational add rule x y ip saddr 1.1.1.1 counter ^^^^^^^^^^^^^^^^ ip saddr $1.1.1.1 <cmdline>:1:14-21: Evaluate payload add rule x y ip saddr 1.1.1.1 counter ^^^^^^^^ ip saddr <cmdline>:1:23-29: Evaluate symbol add rule x y ip saddr 1.1.1.1 counter ^^^^^^^ <cmdline>:1:23-29: Evaluate value add rule x y ip saddr 1.1.1.1 counter ^^^^^^^ 1.1.1.1 <cmdline>:1:31-37: Evaluate counter add rule x y ip saddr 1.1.1.1 counter ^^^^^^^ counter packets 0 bytes 0 Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: Avoid undefined behaviour in concat_subtype_id()Phil Sutter2016-09-051-1/+4
| | | | | | | | | | | | | For the left side of a concat expression, dtype is NULL and therefore off is 0. In that case the code expects to get a datatype of TYPE_INVALID, but this is fragile as the output of concat_subtype_id() is undefined for n > 32 / TYPE_BITS. To fix this, call datatype_lookup() directly passing the expected TYPE_INVALID as argument if off is 0. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: reject: Have a generic fix for missing network contextPhil Sutter2016-09-051-3/+1
| | | | | | | | | | | | | | | | | | Commit 17b495957b29e ("evaluate: reject: fix crash if we have transport protocol conflict from inet") took care of a crash when using inet or bridge families, but since then netdev family has been added which also does not implicitly define the network context. Therefore the crash can be reproduced again using the following example: nft add rule netdev filter e1000-ingress \ meta l4proto udp reject with tcp reset In order to fix this in a more generic way, have stmt_evaluate_reset() fall back to the generic proto_inet_service irrespective of the actual proto context. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: Fix datalen checks in expr_evaluate_string()Phil Sutter2016-09-051-1/+2
| | | | | | | | | | | | | | I have been told that the flex scanner won't return empty strings, so strlen(data) should always be greater 0. To avoid a hard to debug issue though, add an assert() to make sure this is always the case before risking an unsigned variable underrun. A real issue though is the check for 'datalen - 1 >= 0', which will never fail due to datalen being unsigned. Fix this by incrementing both sides by one, hence checking 'datalen >= 1'. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: validate maximum hash and numgen valuePablo Neira Ayuso2016-08-291-6/+22
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | We can validate that values don't get over the maximum datatype length, this is expressed in number of bits, so the maximum value is always power of 2. However, since we got the hash and numgen expressions, the user should not set a value higher that what the specified modulus option, which may not be power of 2. This patch extends the expression context with a new optional field to store the maximum value. After this patch, nft bails out if the user specifies non-sense rules like those below: # nft add rule x y jhash ip saddr mod 10 seed 0xa 10 <cmdline>:1:45-46: Error: Value 10 exceeds valid range 0-9 add rule x y jhash ip saddr mod 10 seed 0xa 10 ^^ The modulus sets a valid value range of [0, n), so n is out of the valid value range. # nft add rule x y numgen inc mod 10 eq 12 <cmdline>:1:35-36: Error: Value 12 exceeds valid range 0-9 add rule x y numgen inc mod 10 eq 12 ^^ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: add expr_evaluate_integer()Pablo Neira Ayuso2016-08-291-15/+23
| | | | | | Add a helper function to wrap the integer evaluation code. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: add hash expressionPablo Neira Ayuso2016-08-291-0/+21
| | | | | | | | | | | | | | | | | | | | | | | | | | | | This is special expression that transforms an input expression into a 32-bit unsigned integer. This expression takes a modulus parameter to scale the result and the random seed so the hash result becomes harder to predict. You can use it to set the packet mark, eg. # nft add rule x y meta mark set jhash ip saddr . ip daddr mod 2 seed 0xdeadbeef You can combine this with maps too, eg. # nft add rule x y dnat to jhash ip saddr mod 2 seed 0xdeadbeef map { \ 0 : 192.168.20.100, \ 1 : 192.168.30.100 \ } Currently, this expression implements the jenkins hash implementation available in the Linux kernel: http://lxr.free-electrons.com/source/include/linux/jhash.h But it should be possible to extend it to support any other hash function type. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: add numgen expressionPablo Neira Ayuso2016-08-291-0/+27
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This new expression allows us to generate incremental and random numbers bound to a specified modulus value. The following rule sets the conntrack mark of 0 to the first packet seen, then 1 to second packet, then 0 again to the third packet and so on: # nft add rule x y ct mark set numgen inc mod 2 A more useful example is a simple load balancing scenario, where you can also use maps to set the destination NAT address based on this new numgen expression: # nft add rule nat prerouting \ dnat to numgen inc mod 2 map { 0 : 192.168.10.100, 1 : 192.168.20.200 } So this is distributing new connections in a round-robin fashion between 192.168.10.100 and 192.168.20.200. Don't forget the special NAT chain semantics: Only the first packet evaluates the rule, follow up packets rely on conntrack to apply the NAT information. You can also emulate flow distribution with different backend weights using intervals: # nft add rule nat prerouting \ dnat to numgen inc mod 10 map { 0-5 : 192.168.10.100, 6-9 : 192.168.20.200 } So 192.168.10.100 gets 60% of the workload, while 192.168.20.200 gets 40%. We can also be mixed with dynamic sets, thus weight can be updated in runtime. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: add quota statementPablo Neira Ayuso2016-08-291-0/+1
| | | | | | | | | | | | | This new statement is stateful, so it can be used from flow tables, eg. # nft add rule filter input \ flow table http { ip saddr timeout 60s quota over 50 mbytes } drop This basically sets a quota per source IP address of 50 mbytes after which packets are dropped. Note that the timeout releases the entry if no traffic is seen from this IP after 60 seconds. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: Simplify parser rule_spec treeCarlos Falgueras García2016-08-231-67/+1
| | | | | | | | | | This patch separates the rule identification from the rule localization, so the logic moves from the evaluator to the parser. This allows to revert the patch "evaluate: improve rule managment checks" (4176c7d30c2ff1b3f52468fc9c08b8df83f979a8) and saves a lot of code. Signed-off-by: Carlos Falgueras García <carlosfg@riseup.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* netlink: make checksum fixup work with odd-sized header fieldsFlorian Westphal2016-08-011-4/+35
| | | | | | | | | | | | | | | | | | | | | The kernel checksum functions want even-sized lengths except for the last block at the end of the data. This means that nft --debug=netlink add rule filter output ip ecn set 1 must generate a two byte read and a two byte write: [ payload load 2b @ network header + 0 => reg 1 ] [ bitwise reg 1 = (reg=1 & 0x0000fcff ) ^ 0x00000100 ] [ payload write reg 1 => 2b @ network header + 0 csum_type 1 csum_off 10 ] Otherwise, while a one-byte write is enough, the kernel will generate invalid checksums (unless checksum is offloaded). Signed-off-by: Florian Westphal <fw@strlen.de> Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: add support to set IPv6 non-byte header fieldsFlorian Westphal2016-08-011-4/+76
| | | | | | | | | | | | | | | | | | | | | | | | | | 'ip6 ecn set 1' will generate a zero-sized write operation. Just like when matching on bit-sized header fields we need to round up to a byte-sized quantity and add a mask to retain those bits outside of the header bits that we want to change. Example: ip6 ecn set ce [ payload load 1b @ network header + 1 => reg 1 ] [ bitwise reg 1 = (reg=1 & 0x000000cf ) ^ 0x00000030 ] [ payload write reg 1 => 1b @ network header + 1 csum_type 0 csum_off 0 ] 1. Load the full byte containing the ecn bits 2. Mask out everything *BUT* the ecn bits 3. Set the CE mark This patch only works if the protocol doesn't need a checksum fixup. Will address this in a followup patch. This also doesn't yet include the needed reverse translation. Signed-off-by: Florian Westphal <fw@strlen.de> Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: add small helper to check if payload expr needs binop adjustmentFlorian Westphal2016-08-011-2/+7
| | | | | | | | | | | kernel can only deal with byte-sized and byte-aligned payload expressions. If the payload expression doesn't fit this requirement userspace has to add explicit binop masks to remove the unwanted part(s). Suggested-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: Florian Westphal <fw@strlen.de>
* src: add xt compat supportPablo Neira Ayuso2016-07-131-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | At compilation time, you have to pass this option. # ./configure --with-xtables And libxtables needs to be installed in your system. This patch allows to list a ruleset containing xt extensions loaded through iptables-compat-restore tool. Example: $ iptables-save > ruleset $ cat ruleset *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] -A INPUT -p tcp -m multiport --dports 80,81 -j REJECT COMMIT $ sudo iptables-compat-restore ruleset $ sudo nft list rulseset table ip filter { chain INPUT { type filter hook input priority 0; policy accept; ip protocol tcp tcp dport { 80,81} counter packets 0 bytes 0 reject } chain FORWARD { type filter hook forward priority 0; policy drop; } chain OUTPUT { type filter hook output priority 0; policy accept; } } A translation of the extension is shown if this is available. In other case, match or target definition is preceded by a hash. For example, classify target has not translation: $ sudo nft list chain mangle POSTROUTING table ip mangle { chain POSTROUTING { type filter hook postrouting priority -150; policy accept; ip protocol tcp tcp dport 80 counter packets 0 bytes 0 # CLASSIFY set 20:10 ^^^ } } If the whole ruleset is translatable, the users can (re)load it using "nft -f" and get nft native support for all their rules. This patch is joint work by the authors listed below. Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com> Signed-off-by: Pablo M. Bermudo Garay <pablombg@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: expose delinearize/linearize structures and stmt_error()Pablo Neira2016-07-131-22/+0
| | | | | | | Needed by the follow up xt compatibility layer patch. Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: fix "list set" unexpected behaviourPablo M. Bermudo Garay2016-06-011-1/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | Special sets like maps and flow tables have their own commands to be listed and inspected. Before this patch, "nft list set" was able to display these special sets content: # nft list set filter test table ip filter { map test { type ipv4_addr : inet_service elements = { 192.168.1.101 : http-alt} } } Now an error is shown: # nft list set filter test <cmdline>:1:1-20: Error: Could not process rule: Set 'test' does not exist list set filter test ^^^^^^^^^^^^^^^^^^^^ Signed-off-by: Pablo M. Bermudo Garay <pablombg@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: add support for display maps contentPablo M. Bermudo Garay2016-05-311-0/+10
| | | | | | | | | | | | | | | | | | | | | | | This commit adds a new command that displays the definition of a single map: # nft list map [family] <table> <map> If no family is specified, ip is assumed. Example: # nft list map ip6 filter test table ip6 filter { map test { type ipv6_addr : inet_service elements = { 2001:db8::ff00:42:8329 : http} } } Signed-off-by: Pablo M. Bermudo Garay <pablombg@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: add 'list maps' supportPablo M. Bermudo Garay2016-05-311-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | This commit adds a new command that lists maps: # nft list maps [family] Only the declaration is displayed. If no family is specified, all maps of all families are listed. Example: # nft list maps table ip filter { map test { type ipv4_addr : inet_service } } table ip6 filter { map test { type ipv6_addr : inet_service } } Signed-off-by: Pablo M. Bermudo Garay <pablombg@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* rule: add support for display flow tables contentPablo M. Bermudo Garay2016-05-201-0/+11
| | | | | | | | | | This commit adds a new command that displays the definition of a single flow table: If no family is specified, ip is assumed. Signed-off-by: Pablo M. Bermudo Garay <pablombg@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* rule: add 'list flow tables' supportPablo M. Bermudo Garay2016-05-201-0/+1
| | | | | | | | | | | | This commit adds a new command that lists flow tables: # nft list flow tables [family] Only the declaration is displayed. If no family is specified, all flow tables of all families are listed. Signed-off-by: Pablo M. Bermudo Garay <pablombg@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: fix crash if we add an error format ruleLiping Zhang2016-05-141-1/+1
| | | | | | | | | | | If we add a such nft rule: nft add rule filter input ip protocol icmp tcp dport 0 we will always meet the assert condition: nft: evaluate.c:536: resolve_protocol_conflict: Assertion `base < (__PROTO_BASE_MAX - 1)' failed. Aborted (core dumped) Signed-off-by: Florian Westphal <fw@strlen.de>
* src: add flow statementPatrick McHardy2016-05-131-0/+37
| | | | | | | | | | | | | | | The flow statement allows to instantiate per flow statements for user defined flows. This can so far be used for per flow accounting or limiting, similar to what the iptables hashlimit provides. Flows can be aged using the timeout option. Examples: # nft filter input flow ip saddr . tcp dport limit rate 10/second # nft filter input flow table acct iif . ip saddr timeout 60s counter Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* set: explicitly supply name to implicit set declarationsPatrick McHardy2016-05-131-3/+6
| | | | | | | | | | Support explicitly names implicitly declared sets. Also change the template names for literal sets and maps to use identifiers that can not clash with user supplied identifiers. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* set: allow non-constant implicit set declarationsPatrick McHardy2016-05-131-1/+3
| | | | | | | | | | Currently all implicitly declared sets are marked as constant. The flow statement needs to implicitly declare non-constant sets, so instead of unconditionally marking the set as constant, only do so if the declaring expression is itself a constant set. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: check for NULL datatype in rhs in lookup exprArturo Borrero2016-05-131-9/+25
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | If we are evaluating an EXPR_SET_REF, check if right->dtype is not NULL. We can hit SEGFAULT if for whatever reason the referenced object does not exist. Using this testfile (note the invalid set syntax): % cat test.nft flush ruleset add table t add chain t c add set t s {type ipv4_addr\;} add rule t c ip saddr @s Without this patch: % nft -f test.nft Segmentation fault With this patch: % nft -f test.nft t.nft:4:28-28: Error: syntax error, unexpected junk, expecting newline or semicolon add set t s {type ipv4_addr\;} ^ t.nft:4:13-29: Error: set definition does not specify key data type add set t s {type ipv4_addr\;} ^^^^^^^^^^^^^^^^^ t.nft:5:23-24: Error: the referenced set does not exist add rule t c ip saddr @s ~~~~~~~~ ^^ Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: handle payload matching split in two bytesPablo Neira Ayuso2016-05-111-8/+16
| | | | | | | | | | | | | | When the bits are split between two bytes and the payload field is smaller than one byte, we need to extend the expression length on both sides (payload and constant) of the relational expression. The existing trimming from the delinerization step handles the listing for us, so no changes on that front. This patch allows us to match the IPv6 DSCP field which falls into the case that is described above. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: move payload sub-byte matching to the evaluation stepPablo Neira Ayuso2016-05-111-8/+97
| | | | | | | | | | | | | | | | | | | | Generating the bitwise logic to match sub-byte payload fields from the linearize step has several problems: 1) When the bits are split between two bytes and the payload field is smaller than one byte, we need to extend the expression length on both sides (payload and constant) of the relational expression. 2) Explicit bitmask operations on sub-byte payload fields need to be merge to the implicit bitmask operation, otherwise we generate two bitwise instructions. This is not resolved by this patch, but we should have a look at some point to this. With this approach, we can benefit from the binary operation transfer for shifts to provide a generic way to adjust the constant side of the expression. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: transfer right shifts to set reference sidePablo Neira Ayuso2016-05-111-0/+40
| | | | | | | | This provides a generic way to transfer shifts from the left hand side to the right hand range side of a relational expression when performing transformations from the evaluation step. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: transfer right shifts to range sidePablo Neira Ayuso2016-05-111-0/+12
| | | | | | | | This provides a generic way to transfer shifts from the left hand side to the right hand range side of a relational expression when performing transformations from the evaluation step. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: transfer right shifts to constant sidePatrick McHardy2016-05-111-4/+26
| | | | | | | | | This provides a generic way to transfer shifts from the left hand side to the right hand constant side of a relational expression when performing transformations from the evaluation step. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: bail out on prefix or range to non-interval setPablo Neira Ayuso2016-04-271-0/+16
| | | | | | | | | | | | | | | | | | | | | | | If you declare a set with no interval flag, you get this bug message: # nft add element filter myset { 192.168.1.100/24 } BUG: invalid data expression type prefix nft: netlink.c:323: netlink_gen_data: Assertion `0' failed. Aborted After this patch, we provide a clue to the user: # nft add element filter myset { 192.168.1.100/24 } <cmdline>:1:23-38: Error: Set member cannot be prefix, missing interval flag on declaration add element filter myset { 192.168.1.100/24 } ^^^^^^^^^^^^^^^^ # nft add element filter myset { 192.168.1.100-192.168.1.200 } <cmdline>:1:23-49: Error: Set member cannot be range, missing interval flag on declaration add element filter myset { 192.168.1.100-192.168.1.200 } ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* nft monitor [ trace ]Patrick McHardy2016-04-241-0/+18
| | | | | | | | | | | | | | | | | | | | | | | | | ... can now display nftables nftrace debug information. $ nft filter input tcp dport 10000 nftrace set 1 $ nft filter input icmp type echo-request nftrace set 1 $ nft -nn monitor trace trace id e1f5055f ip filter input packet: iif eth0 ether saddr 63:f6:4b:00:54:52 ether daddr c9:4b:a9:00:54:52 ip saddr 192.168.122.1 ip daddr 192.168.122.83 ip tos 0 ip ttl 64 ip id 32315 ip length 84 icmp type echo-request icmp code 0 icmp id 10087 icmp sequence 1 trace id e1f5055f ip filter input rule icmp type echo-request nftrace set 1 (verdict continue) trace id e1f5055f ip filter input verdict continue trace id e1f5055f ip filter input trace id 74e47ad2 ip filter input packet: iif vlan0 ether saddr 63:f6:4b:00:54:52 ether daddr c9:4b:a9:00:54:52 vlan pcp 0 vlan cfi 1 vlan id 1000 ip saddr 10.0.0.1 ip daddr 10.0.0.2 ip tos 0 ip ttl 64 ip id 49030 ip length 84 icmp type echo-request icmp code 0 icmp id 10095 icmp sequence 1 trace id 74e47ad2 ip filter input rule icmp type echo-request nftrace set 1 (verdict continue) trace id 74e47ad2 ip filter input verdict continue trace id 74e47ad2 ip filter input trace id 3030de23 ip filter input packet: iif vlan0 ether saddr 63:f6:4b:00:54:52 ether daddr c9:4b:a9:00:54:52 vlan pcp 0 vlan cfi 1 vlan id 1000 ip saddr 10.0.0.1 ip daddr 10.0.0.2 ip tos 16 ip ttl 64 ip id 59062 ip length 60 tcp sport 55438 tcp dport 10000 tcp flags == syn tcp window 29200 trace id 3030de23 ip filter input rule tcp dport 10000 nftrace set 1 (verdict continue) trace id 3030de23 ip filter input verdict continue trace id 3030de23 ip filter input Based on a patch from Florian Westphal, which again was based on a patch from Markus Kötter. Signed-off-by: Patrick McHardy <kaber@trash.net>
* payload: fix stacked headers protocol context trackingPatrick McHardy2016-04-241-33/+11
| | | | | | | | | | | | | | | The code contains multiple scattered around fragments to fiddle with the protocol contexts to work around the fact that stacked headers update the context for the incorrect layer. Fix this by updating the correct layer in payload_expr_pctx_update() and also take care of offset adjustments there and only there. Remove all manual protocol context fiddling and change protocol context debugging to also print the offset for stacked headers. All previously successful testcases pass. Signed-off-by: Patrick McHardy <kaber@trash.net>
* src: evaluate: Show error for fanout without balanceShivani Bhardwaj2016-04-131-0/+5
| | | | | | | | | | | | | | | | | | | | The idea of fanout option is to improve the performance by indexing CPU ID to map packets to the queues. This is used for load balancing. Fanout option is not required when there is a single queue specified. According to iptables, queue balance should be specified in order to use fanout. Following that, throw an error in nftables if the range of queues for load balancing is not specified with the fanout option. After this patch, $ sudo nft add rule ip filter forward counter queue num 0 fanout <cmdline>:1:46-46: Error: fanout requires a range to be specified add rule ip filter forward counter queue num 0 fanout ^^^^^ Signed-off-by: Shivani Bhardwaj <shivanib134@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: improve rule management checksArturo Borrero2016-04-131-1/+67
| | | | | | | | | | | Improve checks (and error reporting) for basic rule management operations. This includes a fix for netfilter bug #965. Netfilter bug: http://bugzilla.netfilter.org/show_bug.cgi?id=965 Reported-by: Jesper Sander Lindgren <sander.contrib@gmail.com> Suggested-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: use table_lookup_global() from expr_evaluate_symbol()Pablo Neira Ayuso2016-03-141-15/+15
| | | | | | | | | | | | | | | | | | | | | | | | | | If there's already a table 'test' defined in the kernel and you load another table 'test' via `nft -f', table_lookup() returns the table that already exists in the kernel, so if you look up for objects that are defined in the file, nft bails out with 'Set does not exist'. Use table_lookup_global() function returns the existing table that is defined in the file and that it is set as context via ctx->handle->table. This is not a complete fix, we should splice the existing kernel objects into the userspace declaration. We just need some way to identify what objects are already in the kernel so we don't send them again (otherwise we will hit EEXIST errors). I'll follow up with this full fix asap. Anyway, this patch fixes this shell test: I: [OK] ./testcases/sets/cache_handling_0 So at least by now we have all shell test returning OK. I'll add more tests to catch the case I describe above once it is fixed too. Cc: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: revisit cache population logicPablo Neira Ayuso2016-03-141-16/+45
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | We get a partial cache (tables, chains and sets) when: * We see a set reference from a rule, since this set object may be already defined in kernelspace and we need to fetch the datatype for evaluation. * We add/delete a set element, we need this to evaluate if the element datatype is correct. * We rename a chain, since we need to know the chain handle. * We add a chain/set. This isn't needed for simple command line invocations. However, since the existing codepath is also exercised from `nft -f' context, we need to know if the object exists in the kernel. Thus, if this a newly declared object (not yet in the kernel) we add it to the cache, otherwise, we will not find follow up references to this object in our cache. We get a full cache when: * We list the ruleset. We can provide finer grain listing though, via partial cache, later. * We monitor updates, since this displays incremental updates based on the existing objects. * We export the ruleset, since this dumps all of the existing objects. * We push updates via `nft -f'. We need to know what objects are already in the kernel for incremental updates. Otherwise, cache_update() hits a bogus 'set doesn't exist' error message for just declared set in this batch. To avoid this problem, we need a way to differentiate between what objects in the lists that are already defined in the kernel and what are just declared in this batch (hint: the location structure information is set for just declared objects). We don't get a cache at all when: * We flush the ruleset, this is important in case of delinearize bugs, so you don't need to reboot or manually flush the ruleset via libnftnl examples/nft-table-flush. * We delete any object, except for set elements (as we describe above). * We add a rule, so you can generate via --debug=netlink the expression without requiring a table and chain in place. * We describe a expression. This patch also includes some intentional adjustments to the shell tests to we don't get bogus errors due to changes in the list printing. BTW, this patch also includes a revert for 97493717e738 ("evaluate: check if table and chain exists when adding rules") since that check is not possible anymore with this logic. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: Add support for masquerade port selectionShivani Bhardwaj2016-03-031-0/+6
| | | | | | | | | Provide full support for masquerading by allowing port range selection, eg. # nft add rule nat postrouting ip protocol tcp masquerade to :1024-10024 Signed-off-by: Shivani Bhardwaj <shivanib134@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>