summaryrefslogtreecommitdiffstats
path: root/src/evaluate.c
Commit message (Collapse)AuthorAgeFilesLines
* src: store expr, not dtype to track data in setsFlorian Westphal2019-12-161-18/+40
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This will be needed once we add support for the 'typeof' keyword to handle maps that could e.g. store 'ct helper' "type" values. Instead of: set foo { type ipv4_addr . mark; this would allow set foo { typeof(ip saddr) . typeof(ct mark); (exact syntax TBD). This would be needed to allow sets that store variable-sized data types (string, integer and the like) that can't be used at at the moment. Adding special data types for everything is problematic due to the large amount of different types needed. For anonymous sets, e.g. "string" can be used because the needed size can be inferred from the statement, e.g. 'osf name { "Windows", "Linux }', but in case of named sets that won't work because 'type string' lacks the context needed to derive the size information. With 'typeof(osf name)' the context is there, but at the moment it won't help because the expression is discarded instantly and only the data type is retained. Signed-off-by: Florian Westphal <fw@strlen.de>
* src: add ability to set/get secmarks to/from connectionChristian Göttsche2019-11-251-2/+22
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Labeling established and related packets requires the secmark to be stored in the connection. Add the ability to store and retrieve secmarks like: ... chain input { ... # label new incoming packets ct state new meta secmark set tcp dport map @secmapping_in # add label to connection ct state new ct secmark set meta secmark # set label for est/rel packets from connection ct state established,related meta secmark set ct secmark ... } ... chain output { ... # label new outgoing packets ct state new meta secmark set tcp dport map @secmapping_out # add label to connection ct state new ct secmark set meta secmark # set label for est/rel packets from connection ct state established,related meta secmark set ct secmark ... } ... This patch also disallow constant value on the right hand side. # nft add rule x y meta secmark 12 Error: Cannot be used with right hand side constant value add rule x y meta secmark 12 ~~~~~~~~~~~~ ^^ # nft add rule x y ct secmark 12 Error: Cannot be used with right hand side constant value add rule x y ct secmark 12 ~~~~~~~~~~ ^^ # nft add rule x y ct secmark set 12 Error: ct secmark must not be set to constant value add rule x y ct secmark set 12 ^^^^^^^^^^^^^^^^^ This patch improves 3bc84e5c1fdd ("src: add support for setting secmark"). Signed-off-by: Christian Göttsche <cgzones@googlemail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: add and use `set_is_meter` helperJeremy Sowden2019-11-061-4/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The sets constructed for meters are flagged as anonymous and dynamic. However, in some places there are only checks that they are dynamic, which can lead to normal sets being classified as meters. For example: # nft add table t # nft add set t s { type ipv4_addr; size 256; flags dynamic,timeout; } # nft add chain t c # nft add rule t c tcp dport 80 meter m size 128 { ip saddr limit rate 10/second } # nft list meters table ip t { set s { type ipv4_addr size 256 flags dynamic,timeout } meter m { type ipv4_addr size 128 flags dynamic } } # nft list meter t m table ip t { meter m { type ipv4_addr size 128 flags dynamic } } # nft list meter t s Error: No such file or directory list meter t s ^ Add a new helper `set_is_meter` and use it wherever there are checks for meters. Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Florian Westphal <fw@strlen.de>
* src: flowtable: add support for named flowtable listingEric Jallot2019-10-311-0/+29
| | | | | | | | | | | | | | | | | | | | This patch allows you to dump a named flowtable. # nft list flowtable inet t f table inet t { flowtable f { hook ingress priority filter + 10 devices = { eth0, eth1 } } } Also: libnftables-json.adoc: fix missing quotes. Fixes: db0697ce7f60 ("src: support for flowtable listing") Fixes: 872f373dc50f ("doc: Add JSON schema documentation") Signed-off-by: Eric Jallot <ejallot@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: add synproxy stateful object supportFernando Fernandez Mancera2019-09-131-0/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | Add support for "synproxy" stateful object. For example (for TCP port 80 and using maps with saddr): table ip foo { synproxy https-synproxy { mss 1460 wscale 7 timestamp sack-perm } synproxy other-synproxy { mss 1460 wscale 5 } chain bar { tcp dport 80 synproxy name "https-synproxy" synproxy name ip saddr map { 192.168.1.0/24 : "https-synproxy", 192.168.2.0/24 : "other-synproxy" } } } Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: flag fwd and queue statements as terminalFlorian Westphal2019-09-071-0/+2
| | | | | | | | | | | | | | | | | | Both queue and fwd statement end evaluation of a rule: in ... fwd to "eth0" accept ... queue accept "accept" is redundant and never evaluated in the kernel. Add the missing "TERMINAL" flag so the evaluation step will catch any trailing expressions: nft add rule filter input queue counter Error: Statement after terminal statement has no effect Signed-off-by: Florian Westphal <fw@strlen.de> Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: evaluate: catch invalid 'meta day' values in eval stepFlorian Westphal2019-09-061-4/+13
| | | | Signed-off-by: Florian Westphal <fw@strlen.de>
* meta: Introduce new conditions 'time', 'day' and 'hour'Ander Juaristi2019-09-061-0/+54
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | These keywords introduce new checks for a timestamp, an absolute date (which is converted to a timestamp), an hour in the day (which is converted to the number of seconds since midnight) and a day of week. When converting an ISO date (eg. 2019-06-06 17:00) to a timestamp, we need to substract it the GMT difference in seconds, that is, the value of the 'tm_gmtoff' field in the tm structure. This is because the kernel doesn't know about time zones. And hence the kernel manages different timestamps than those that are advertised in userspace when running, for instance, date +%s. The same conversion needs to be done when converting hours (e.g 17:00) to seconds since midnight as well. The result needs to be computed modulo 86400 in case GMT offset (difference in seconds from UTC) is negative. We also introduce a new command line option (-t, --seconds) to show the actual timestamps when printing the values, rather than the ISO dates, or the hour. Some usage examples: time < "2019-06-06 17:00" drop; time < "2019-06-06 17:20:20" drop; time < 12341234 drop; day "Saturday" drop; day 6 drop; hour >= 17:00 drop; hour >= "17:00:01" drop; hour >= 63000 drop; We need to convert an ISO date to a timestamp without taking into account the time zone offset, since comparison will be done in kernel space and there is no time zone information there. Overwriting TZ is portable, but will cause problems when parsing a ruleset that has 'time' and 'hour' rules. Parsing an 'hour' type must not do time zone conversion, but that will be automatically done if TZ has been overwritten to UTC. Hence, we use timegm() to parse the 'time' type, even though it's not portable. Overwriting TZ seems to be a much worse solution. Finally, be aware that timestamps are converted to nanoseconds when transferring to the kernel (as comparison is done with nanosecond precision), and back to seconds when retrieving them for printing. We swap left and right values in a range to properly handle cross-day hour ranges (e.g. 23:15-03:22). Signed-off-by: Ander Juaristi <a@juaristi.eus> Reviewed-by: Florian Westphal <fw@strlen.de>
* evaluate: New internal helper __expr_evaluate_rangeAnder Juaristi2019-09-061-4/+16
| | | | | | | | | | | | | This is used by the followup patch to evaluate a range without emitting an error when the left value is larger than the right one. This is done to handle time-matching such as 23:00-01:00 -- expr_evaluate_range() will reject this, but we want to be able to evaluate and then handle this as a request to match from 23:00 to 1am. Signed-off-by: Ander Juaristi <a@juaristi.eus> Signed-off-by: Florian Westphal <fw@strlen.de>
* src: allow variable in chain policyFernando Fernandez Mancera2019-08-081-0/+24
| | | | | | | | | | | | This patch allows you to use variables in chain policy definition, e.g. define default_policy = "accept" add table ip foo add chain ip foo bar {type filter hook input priority filter; policy $default_policy} Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: allow variables in the chain priority specificationFernando Fernandez Mancera2019-08-081-14/+47
| | | | | | | | | | | | | | | | | This patch allows you to use variables in chain priority definitions, e.g. define prio = filter define prionum = 10 define prioffset = "filter - 150" add table ip foo add chain ip foo bar { type filter hook input priority $prio; } add chain ip foo ber { type filter hook input priority $prionum; } add chain ip foo bor { type filter hook input priority $prioffset; } Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: add parse_ctx objectPablo Neira Ayuso2019-08-081-2/+4
| | | | | | | | This object stores the dynamic symbol tables that are loaded from files. Pass this object to datatype parse functions, although this new parameter is not used yet, this is just a preparation patch. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* cache: add NFT_CACHE_UPDATE and NFT_CACHE_FLUSHED flagsPablo Neira Ayuso2019-07-231-5/+3
| | | | | | | | | | | | | | | | | | | NFT_CACHE_FLUSHED tells cache_update() to skip the netlink dump to populate the cache, since the existing ruleset is going to flushed by this batch. NFT_CACHE_UPDATE tells rule_evaluate() to perform incremental updates to the cache based on the existing batch, this is required by the rule commands that use the index and the position selectors. This patch removes cache_flush() which is not required anymore. This cache removal is coming too late, in the evaluation phase, after the initial cache_update() invocation. Be careful with NFT_CACHE_UPDATE, this flag needs to be left in place if NFT_CACHE_FLUSHED is set on. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: missing location for chain nested in table definitionPablo Neira Ayuso2019-07-221-0/+1
| | | | | | error reporting may crash because location is unset. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: evaluate: support prefix expression in statementsFlorian Westphal2019-07-221-0/+48
| | | | | | | | | | | | | | | | | | | | | | | | Currently nft dumps core when it encounters a prefix expression as part of a statement, e.g. iifname ens3 snat to 10.0.0.0/28 yields: BUG: unknown expression type prefix nft: netlink_linearize.c:688: netlink_gen_expr: Assertion `0' failed. This assertion is correct -- we can't linearize a prefix because kernel doesn't know what that is. For LHS prefixes, they get converted to a binary 'and' such as '10.0.0.0 & 255.255.255.240'. For RHS, we can do something similar and convert them into a range. snat to 10.0.0.0/28 will be converted into: iifname "ens3" snat to 10.0.0.0-10.0.0.15 Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1187 Signed-off-by: Florian Westphal <fw@strlen.de> Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: bogus error when refering to existing non-base chainPablo Neira Ayuso2019-07-181-6/+3
| | | | | | | | add rule ip testNEW test6 jump test8 ^^^^^ Error: invalid verdict chain expression value Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: introduce SYNPROXY matchingFernando Fernandez Mancera2019-07-171-0/+15
| | | | | | | | | | | | | | | | | | | | Add support for "synproxy" statement. For example (for TCP port 8888): table ip x { chain y { type filter hook prerouting priority raw; policy accept; tcp dport 8888 tcp flags syn notrack } chain z { type filter hook input priority filter; policy accept; tcp dport 8888 ct state invalid,untracked synproxy mss 1460 wscale 7 timestamp sack-perm ct state invalid drop } } Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: missing basic evaluation of expectationsPablo Neira Ayuso2019-07-161-4/+30
| | | | | | | | | | | Basic ct expectation object evaluation. This fixes tests/py errors. Error reporting is very sparse at this stage. I'm intentionally leaving this as future work to store location objects for each field, so user gets better indication on what is missing when configuring expectations. Fixes: 1dd08fcfa07a ("src: add ct expectations support") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: add ct expectations supportStéphane Veyret2019-07-161-0/+4
| | | | | | | This modification allow to directly add/list/delete expectations. Signed-off-by: Stéphane Veyret <sveyret@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: honor NFT_SET_OBJECT flagPablo Neira Ayuso2019-07-161-3/+3
| | | | | | | | | | | | | | | | | | | | This is noticeable when displaying mispelling errors, however, there are also few spots not checking for the object map flag. Before: # nft flush set inet filter countermxx Error: No such file or directory; did you mean set ‘countermap’ in table inet ‘filter’? flush set inet filter countermxx ^^^^^^^^^^ After: # nft flush set inet filter countermxx Error: No such file or directory; did you mean map ‘countermap’ in table inet ‘filter’? flush set inet filter countermxx ^^^^^^^^^^ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: use set_is_anonymous()Pablo Neira Ayuso2019-07-161-1/+1
| | | | Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: missing object maps handling in list and flush commandsPablo Neira Ayuso2019-07-161-8/+5
| | | | | | | | | | | | | | | | | | | | NFT_SET_OBJECT tells there is an object map. # nft list ruleset table inet filter { map countermap { type ipv4_addr : counter } } The following command fails: # nft flush set inet filter countermap This patch checks for NFT_SET_OBJECT from new set_is_literal() and map_is_literal() functions. This patch also adds tests for this. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: add set_is_datamap(), set_is_objmap() and set_is_map() helpersPablo Neira Ayuso2019-07-161-6/+6
| | | | | | | | | | | | | Two map types are currently possible: * data maps, ie. set_is_datamap(). * object maps, ie. set_is_objmap(). This patch adds helper functions to check for the map type. set_is_map() allows you to check for either map type. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* exthdr: add support for matching IPv4 optionsStephen Suryaputra2019-07-041-0/+17
| | | | | | | | | Add capability to have rules matching IPv4 options. This is developed mainly to support dropping of IP packets with loose and/or strict source route route options. Signed-off-by: Stephen Suryaputra <ssuryaextr@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* ct: support for NFT_CT_{SRC,DST}_{IP,IP6}Pablo Neira Ayuso2019-06-211-1/+24
| | | | | | | | | | | | | | | | | These keys are available since kernel >= 4.17. You can still use NFT_CT_{SRC,DST}, however, you need to specify 'meta protocol' in first place to provide layer 3 context. Note that NFT_CT_{SRC,DST} are broken with set, maps and concatenations. This patch is implicitly fixing these cases. If your kernel is < 4.17, you can still use address matching via explicit meta nfproto: meta nfproto ipv4 ct original saddr 1.2.3.4 Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: do not allow to list/flush anonymous sets via list commandPablo Neira Ayuso2019-06-191-6/+28
| | | | | | | | | | | | | | | | | | | | | | | | | | Don't allow this: # nft list set x __set0 table ip x { set __set0 { type ipv4_addr flags constant elements = { 1.1.1.1 } } } Constant sets never change and they are attached to a rule (anonymous flag is set on), do not list their content through this command. Do not allow flush operation either. After this patch: # nft list set x __set0 Error: No such file or directory list set x __set0 ^^^^^^ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: allow get/list/flush dynamic sets and maps via list commandPablo Neira Ayuso2019-06-191-3/+3
| | | | | | | | | | | | | | | | | | | | | | | | | Before: # nft list set ip filter untracked_unknown Error: No such file or directory; did you mean set ‘untracked_unknown’ in table ip ‘filter’? list set ip filter untracked_unknown ^^^^^^^^^^^^^^^^^ After: # nft list set ip filter untracked_unknown table ip filter { set untracked_unknown { type ipv4_addr . inet_service . ipv4_addr . inet_service . inet_proto size 100000 flags dynamic,timeout } } Add a testcase for this too. Reported-by: Václav Zindulka <vaclav.zindulka@tlapnet.cz> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: add cache level flagsPablo Neira Ayuso2019-06-171-1/+2
| | | | | | | | | | | | | The score approach based on command type is confusing. This patch introduces cache level flags, each flag specifies what kind of object type is needed. These flags are set on/off depending on the list of commands coming in this batch. cache_is_complete() now checks if the cache contains the objects that are needed through these new flags. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: remove useless parameter from cache_flush()Pablo Neira Ayuso2019-06-171-1/+1
| | | | | | Command type is never used in cache_flush(). Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: double datatype_free() with dynamic integer datatypesPablo Neira Ayuso2019-06-141-2/+0
| | | | | | datatype_set() already deals with this case, remove this. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: update byteorder only for implicit mapsPablo Neira Ayuso2019-06-141-1/+2
| | | | | | | | The byteorder adjustment for the integer datatype is only required by implicit maps. Fixes: b9b6092304ae ("evaluate: store byteorder for set keys") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: use-after-free in meterPablo Neira Ayuso2019-06-131-1/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Similar to bbe139fdf5a5 ("evaluate: use-after-free in implicit set"). ==12727== Invalid read of size 4 ==12727== at 0x72DB515: expr_free (expression.c:86) ==12727== by 0x72D3092: set_free (rule.c:367) ==12727== by 0x72DB555: expr_destroy (expression.c:79) ==12727== by 0x72DB555: expr_free (expression.c:95) ==12727== by 0x72D7A35: meter_stmt_destroy (statement.c:137) ==12727== by 0x72D7A07: stmt_free (statement.c:50) ==12727== by 0x72D7AD7: stmt_list_free (statement.c:60) ==12727== by 0x72D32EF: rule_free (rule.c:610) ==12727== by 0x72D3834: chain_free (rule.c:827) ==12727== by 0x72D45D4: table_free (rule.c:1184) ==12727== by 0x72D46A7: __cache_flush (rule.c:293) ==12727== by 0x72D472C: cache_release (rule.c:313) ==12727== by 0x72D4A79: cache_update (rule.c:264) ==12727== Address 0x64f14c8 is 56 bytes inside a block of size 128 free'd ==12727== at 0x4C2CDDB: free (vg_replace_malloc.c:530) ==12727== by 0x72D7A2C: meter_stmt_destroy (statement.c:136) ==12727== by 0x72D7A07: stmt_free (statement.c:50) ==12727== by 0x72D7AD7: stmt_list_free (statement.c:60) ==12727== by 0x72D32EF: rule_free (rule.c:610) ==12727== by 0x72D3834: chain_free (rule.c:827) ==12727== by 0x72D45D4: table_free (rule.c:1184) ==12727== by 0x72D46A7: __cache_flush (rule.c:293) ==12727== by 0x72D472C: cache_release (rule.c:313) ==12727== by 0x72D4A79: cache_update (rule.c:264) ==12727== by 0x72F82CE: nft_evaluate (libnftables.c:388) ==12727== by 0x72F8A8B: nft_run_cmd_from_buffer (libnftables.c:428) Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: add reference counter for dynamic datatypesPablo Neira Ayuso2019-06-131-18/+19
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | There are two datatypes are using runtime datatype allocation: * Concatenations. * Integer, that require byteorder adjustment. From the evaluation / postprocess step, transformations are common, hence expressions may end up fetching (infering) datatypes from an existing one. This patch adds a reference counter to release the dynamic datatype object when it is shared. The API includes the following helper functions: * datatype_set(expr, datatype), to assign a datatype to an expression. This helper already deals with reference counting for dynamic datatypes. This also drops the reference counter of any previous datatype (to deal with the datatype replacement case). * datatype_get(datatype) bumps the reference counter. This function also deals with nul-pointers, that occurs when the datatype is unset. * datatype_free() drops the reference counter, and it also releases the datatype if there are not more clients of it. Rule of thumb is: The reference counter of any newly allocated datatype is set to zero. This patch also updates every spot to use datatype_set() for non-dynamic datatypes, for consistency. In this case, the helper just makes an simple assignment. Note that expr_alloc() has been updated to call datatype_get() on the datatype that is assigned to this new expression. Moreover, expr_free() calls datatype_free(). This fixes valgrind reports like this one: ==28352== 1,350 (440 direct, 910 indirect) bytes in 5 blocks are definitely lost in loss recor 3 of 3 ==28352== at 0x4C2BBAF: malloc (vg_replace_malloc.c:299) ==28352== by 0x4E79558: xmalloc (utils.c:36) ==28352== by 0x4E7963D: xzalloc (utils.c:65) ==28352== by 0x4E6029B: dtype_alloc (datatype.c:1073) ==28352== by 0x4E6029B: concat_type_alloc (datatype.c:1127) ==28352== by 0x4E6D3B3: netlink_delinearize_set (netlink.c:578) ==28352== by 0x4E6D68E: list_set_cb (netlink.c:648) ==28352== by 0x5D74023: nftnl_set_list_foreach (set.c:780) ==28352== by 0x4E6D6F3: netlink_list_sets (netlink.c:669) ==28352== by 0x4E5A7A3: cache_init_objects (rule.c:159) ==28352== by 0x4E5A7A3: cache_init (rule.c:216) ==28352== by 0x4E5A7A3: cache_update (rule.c:266) ==28352== by 0x4E7E0EE: nft_evaluate (libnftables.c:388) ==28352== by 0x4E7EADD: nft_run_cmd_from_filename (libnftables.c:479) ==28352== by 0x109A53: main (main.c:310) This patch also removes the DTYPE_F_CLONE flag which is broken and not needed anymore since proper reference counting is in place. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: Support intra-transaction rule referencesPhil Sutter2019-06-071-20/+74
| | | | | | | | | | | | | | | | | | | | | | | A rule may be added before or after another one using index keyword. To support for the other rule being added within the same batch, one has to make use of NFTNL_RULE_ID and NFTNL_RULE_POSITION_ID attributes. This patch does just that among a few more crucial things: * If cache is complete enough to contain rules, update cache when evaluating rule commands so later index references resolve correctly. * Reduce rule_translate_index() to its core code which is the actual linking of rules and consequently rename the function. The removed bits are pulled into the calling rule_evaluate() to reduce code duplication in between cache updates with and without rule reference. * Pass the current command op to rule_evaluate() as indicator whether to insert before or after a referenced rule or at beginning or end of chain in cache. Exploit this from chain_evaluate() to avoid adding the chain's rules a second time. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: use-after-free in implicit setPablo Neira Ayuso2019-06-071-1/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | # cat example.nft table inet test { chain test { ip daddr { 2.2.2.2, 4.4.4.4} counter accept } } # valgrind nft -f example.nft valgrind reports: ==2272== Invalid read of size 4 ==2272== at 0x4E612A5: expr_free (expression.c:86) ==2272== by 0x4E58EA2: set_free (rule.c:367) ==2272== by 0x4E612DA: expr_destroy (expression.c:79) ==2272== by 0x4E612DA: expr_free (expression.c:93) ==2272== by 0x4E612DA: expr_destroy (expression.c:79) ==2272== by 0x4E612DA: expr_free (expression.c:93) ==2272== by 0x4E5D7E7: stmt_free (statement.c:50) ==2272== by 0x4E5D8B7: stmt_list_free (statement.c:60) ==2272== by 0x4E590FF: rule_free (rule.c:610) ==2272== by 0x4E5C094: cmd_free (rule.c:1420) ==2272== by 0x4E7E7EF: nft_run_cmd_from_filename (libnftables.c:490) ==2272== by 0x109A53: main (main.c:310) ==2272== Address 0x65d94c8 is 56 bytes inside a block of size 128 free'd ==2272== at 0x4C2CDDB: free (vg_replace_malloc.c:530) ==2272== by 0x4E6143C: mapping_expr_destroy (expression.c:966) ==2272== by 0x4E612DA: expr_destroy (expression.c:79) ==2272== by 0x4E612DA: expr_free (expression.c:93) ==2272== by 0x4E5D7E7: stmt_free (statement.c:50) ==2272== by 0x4E5D8B7: stmt_list_free (statement.c:60) ==2272== by 0x4E590FF: rule_free (rule.c:610) ==2272== by 0x4E5C094: cmd_free (rule.c:1420) ==2272== by 0x4E7E7EF: nft_run_cmd_from_filename (libnftables.c:490) ==2272== by 0x109A53: main (main.c:310) ==2272== Block was alloc'd at ==2272== at 0x4C2BBAF: malloc (vg_replace_malloc.c:299) ==2272== by 0x4E79248: xmalloc (utils.c:36) ==2272== by 0x4E7932D: xzalloc (utils.c:65) ==2272== by 0x4E60690: expr_alloc (expression.c:45) ==2272== by 0x4E68B1D: payload_expr_alloc (payload.c:159) ==2272== by 0x4E91013: nft_parse (parser_bison.y:4242) ==2272== by 0x4E7E722: nft_parse_bison_filename (libnftables.c:374) ==2272== by 0x4E7E722: nft_run_cmd_from_filename (libnftables.c:471) ==2272== by 0x109A53: main (main.c:310) Fixes: cc7b37d18a68 ("src: Interpret OP_NEQ against a set as OP_LOOKUP") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: single cache_update() call to build cache before evaluationPablo Neira Ayuso2019-06-061-75/+1
| | | | | | | | | | | | | | | This patch allows us to make one single cache_update() call. Thus, there is not need to rebuild an incomplete cache from the middle of the batch processing. Note that nft_run_cmd_from_filename() does not need a full netlink dump to build the cache anymore, this should speed nft -f with incremental updates and very large rulesets. cache_evaluate() calculates the netlink dump to populate the cache that this batch needs. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: Allow goto and jump to a variableFernando Fernandez Mancera2019-05-241-0/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | This patch introduces the use of nft input files variables in 'jump' and 'goto' statements, e.g. define dest = ber add table ip foo add chain ip foo bar {type filter hook input priority 0;} add chain ip foo ber add rule ip foo ber counter add rule ip foo bar jump $dest table ip foo { chain bar { type filter hook input priority filter; policy accept; jump ber } chain ber { counter packets 71 bytes 6664 } } Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: Introduce chain_expr in jump and goto statementsFernando Fernandez Mancera2019-05-241-0/+4
| | | | | | | | | Introduce expressions as a chain in jump and goto statements. This is going to be used to support variables as a chain in the following patches. Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: use definitions in include/linux/netfilter/nf_tables.hPablo Neira Ayuso2019-05-121-1/+1
| | | | | | | | | | | | | | | Use NFT_LOGLEVEL_* definitions in UAPI. Make an internal definition of NFT_OSF_F_VERSION, this was originally defined in the UAPI header in the initial patch version, however, this is not available anymore. Add a bison rule to deal with the timeout case. Otherwise, compilation breaks. Fixes: d3869cae9d62 ("include: refresh nf_tables.h cached copy") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: add nat support for the inet familyFlorian Westphal2019-04-091-40/+84
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | consider a simple ip6 nat table: table ip6 nat { chain output { type nat hook output priority 0; policy accept; dnat to dead:2::99 } Now consider same ruleset, but using 'table inet nat': nft now lacks context to determine address family to parse 'to $address'. This adds code to make the following work: table inet nat { [ .. ] # detect af from network protocol context: ip6 daddr dead::2::1 dnat to dead:2::99 # use new dnat ip6 keyword: dnat ip6 to dead:2::99 } On list side, the keyword is only shown in the inet family, else the short version (dnat to ...) is used as the family is redundant when the table already mandates the ip protocol version supported. Address mismatches such as table ip6 { .. dnat ip to 1.2.3.4 are detected/handled during the evaluation phase. Signed-off-by: Florian Westphal <fw@strlen.de> Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: improve error reporting in tproxy with inet familyPablo Neira Ayuso2019-04-041-2/+5
| | | | | | | | | | | | | | | | | # nft add rule inet filter divert ip daddr 0.0.0.0/0 meta l4proto tcp tproxy to :2000 Error: conflicting protocols specified: ip vs. unknown. You must specify ip or ip6 family in tproxy statement add rule inet filter divert ip daddr 0.0.0.0/0 meta l4proto tcp tproxy to :2000 ~~~~~~~~ ^^^^^^^^^^^^^^^ instead of: # nft add rule inet filter divert ip daddr 0.0.0.0/0 meta l4proto tcp tproxy to :2000 Error: Conflicting network layer protocols. add rule inet filter divert ip daddr 0.0.0.0/0 meta l4proto tcp tproxy to :2000 ^^^^^^^^^^^^^^^ Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1310 Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: skip binary transfer for named setsPablo Neira Ayuso2019-03-261-0/+3
| | | | | | | | Set may be empty, content might be yet unknown, we cannot do any transfer in this case. Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1327 Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: misleading error reporting with sets and mapsPablo Neira Ayuso2019-03-061-4/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When trying to list a map content, if set is used, nft reports: # nft list set filter group_7933 Error: No such file or directory; did you mean set ‘group_7933’ in table ip ‘filter’? list set filter group_7933 ^^^^^^^^^^ Which is confusing in case user wants to list an existing map: # nft list map filter group_7933 table ip filter { map group_7933 { type ipv4_addr : classid flags interval elements = { 10.4.22.0/24 : 1:c7cb } } } Instead, give a hint to user that probably wants to list a map, not a set: # nft list set filter group_7933 Error: No such file or directory; did you mean map ‘group_7933’ in table ip ‘filter’? list set filter group_7933 ^^^^^^^^^^ Fixes: 285bb67a11ad ("src: introduce simple hints on incorrect set") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: expr: add expression etypeFlorian Westphal2019-02-081-36/+36
| | | | | | | | Temporary kludge to remove all the expr->ops->type == ... patterns. Followup patch will remove expr->ops, and make expr_ops() lookup the correct expr_ops struct instead to reduce struct expr size. Signed-off-by: Florian Westphal <fw@strlen.de>
* src: expr: add and use expr_name helperFlorian Westphal2019-02-081-11/+11
| | | | | | | | Currently callers use expr->ops->name, but follouwp patch will remove the ops pointer from struct expr. So add this helper and use it everywhere. Signed-off-by: Florian Westphal <fw@strlen.de> Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: remove deprecated code for export/import commandsPablo Neira Ayuso2018-12-271-1/+1
| | | | | | | | | | | | | | | | | | Update parser to display this error message: # nft export json Error: JSON export is no longer supported, use 'nft -j list ruleset' instead export json ^^^^^^^^^^^^ Just like: # nft export vm json Error: JSON export is no longer supported, use 'nft -j list ruleset' instead export vm json ^^^^^^^^^^^^^^^ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: Reject 'export vm json' commandPhil Sutter2018-12-211-0/+3
| | | | | | | | | | | | | | | | | | Since libnftnl recently dropped JSON output support, this form of JSON export is not available anymore. Point at 'nft -j list ruleset' command for a replacement in error message. Since 'export' command is not useable anymore, remove it from documentation. Instead point out that 'list ruleset' command serves well for dumping and later restoring. To not cause pointless inconvenience for users wishing to store their ruleset in JSON format, make JSON parser fallback to CMD_ADD if no recognized command property was found. This allows to feed the output of 'nft -j list ruleset' into 'nft -f' without any modification. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: introduce simple hints on incorrect objectPablo Neira Ayuso2018-12-011-3/+20
| | | | | | | | | | # nft add counter x test # nft list counter x test Error: No such file or directory; did you mean obj ‘test’ in table ip ‘x’? list counter x text ^^^^ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: introduce simple hints on incorrect setPablo Neira Ayuso2018-11-191-27/+41
| | | | | | | | | # nft rule x y ip saddr @y Error: No such file or directory; did you mean set ‘y’ in table inet ‘x’? rule x y ip saddr @y ^^ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: introduce simple hints on incorrect chainPablo Neira Ayuso2018-11-191-9/+22
| | | | | | | | | # nft list chain x y Error: No such file or directory; did you mean chain ‘y’ in table inet ‘x’? list chain x y ^ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>