Phil Sutter [Mon, 19 Mar 2018 17:02:05 +0000 (18:02 +0100)]
flowtable: Make parsing a little more robust
It was surprisingly easy to crash nft with invalid syntax in 'add
flowtable' command. Catch at least three possible ways (illustrated in
provided test case) by making evaluation phase survive so that bison
gets a chance to complain.
Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Phil Sutter [Mon, 19 Mar 2018 17:02:04 +0000 (18:02 +0100)]
tests/shell: Fix flowtable test cases
The major problem here was that existence of network interfaces 'eth0'
and 'wlan0' was assumed. Overcome this by just using 'lo' instead, which
exists even in newly created netns by default.
Another minor issue was false naming of 0004delete_after_add0 - the
expected return code is supposed to be separated by '_' from the
remaining filename.
Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Phil Sutter [Mon, 19 Mar 2018 17:02:03 +0000 (18:02 +0100)]
tests/shell: Fix dump of chains/0016delete_handle_0
The purpose of this test is to delete some chains by their handle and
that is supposed to succeed. So the respective dump should not contain
them anymore.
Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Phil Sutter [Mon, 19 Mar 2018 17:02:02 +0000 (18:02 +0100)]
Support 'nft -f -' to read from stdin
In libnftables, detect if given filename is '-' and treat it as the
common way of requesting to read from stdin, then open /dev/stdin
instead. (Calling 'nft -f /dev/stdin' worked before as well, but this
makes it official.)
With this in place and bash's support for here strings, review all tests
in tests/shell for needless use of temp files. Note that two categories
of test cases were intentionally left unchanged:
- Tests creating potentially large rulesets to avoid running into shell
parameter length limits.
- Tests for 'include' directive for obvious reasons.
Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Phil Sutter [Sat, 17 Mar 2018 09:39:27 +0000 (10:39 +0100)]
Combine redir and masq statements into nat
All these statements are very similar, handling them with the same code
is obvious. The only thing required here is a custom extension of enum
nft_nat_types which is used in nat_stmt to distinguish between snat and
dnat already. Though since enum nft_nat_types is part of kernel uAPI,
create a local extended version containing the additional fields.
Note that nat statement printing got a bit more complicated to get the
number of spaces right for every possible combination of attributes.
Note also that there wasn't a case for STMT_MASQ in
rule_parse_postprocess(), which seems like a bug. Since STMT_MASQ became
just a variant of STMT_NAT, postprocessing will take place for it now
anyway.
Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Unlike plain "ip dscp { 4, 63 }", we don't have a relational operation in
case of vmap. Binop fixups need to be done when evaluating map statements.
This patch is incomplete. 'ip dscp' works, but this won't:
nft add rule --debug=netlink ip6 test-ip6 input ip6 dscp vmap { 0x04 : accept, 0x3f : continue }
The generated expressions look sane, however there is disagreement on
the sets key size vs. the sizes of the individual elements in the set.
This is because ip6 dscp spans a byte boundary.
Key set size is still set to one byte (dscp type is 6bits).
However, binop expansion requirements result in 2 byte loads, i.e.
set members will be 2 bytes in size as well.
This can hopefully get addressed in an incremental patch.
Florian Westphal [Thu, 11 Jan 2018 15:30:22 +0000 (16:30 +0100)]
evaluate: handle binop adjustment recursively
currently this is fine, but a followup commit will add
EXPR_SET_ELEM handling.
And unlike RANGE we cannot assume the key is a value.
Therefore make binop_can_transfer and binop_transfer_one handle
right hand recursively if needed. For RANGE, call it again with
from/to.
For future SET_ELEM, we can then just call the function recursively
again with right->key as new RHS.
Florian Westphal [Thu, 11 Jan 2018 15:30:20 +0000 (16:30 +0100)]
src: segtree: use value expression length
In case of EXPR_MAPPING, expr->len is 0, we need to use
the length of the key instead.
Without this we can get assertion failure later on:
nft: netlink_delinearize.c:1484: binop_adjust_one: Assertion `value->len >= binop->right->len' failed.
Phil Sutter [Thu, 15 Mar 2018 23:03:20 +0000 (00:03 +0100)]
netlink: Fold netlink_gen_cmp() into netlink_gen_relational()
Since netlink_gen_relational() didn't do much anymore after meta OP
treating had been removed, it makes sense to merge it with the only
function it dispached to.
Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Phil Sutter [Thu, 15 Mar 2018 23:03:19 +0000 (00:03 +0100)]
relational: Eliminate meta OPs
With a bit of code reorganization, relational meta OPs OP_RANGE,
OP_FLAGCMP and OP_LOOKUP become unused and can be removed. The only meta
OP left is OP_IMPLICIT which is usually treated as alias to OP_EQ.
Though it needs to stay in place for one reason: When matching against a
bitmask (e.g. TCP flags or conntrack states), it has a different
meaning:
| nft --debug=netlink add rule ip t c tcp flags syn
| ip t c
| [ meta load l4proto => reg 1 ]
| [ cmp eq reg 1 0x00000006 ]
| [ payload load 1b @ transport header + 13 => reg 1 ]
| [ bitwise reg 1 = (reg=1 & 0x00000002 ) ^ 0x00000000 ]
| [ cmp neq reg 1 0x00000000 ]
| nft --debug=netlink add rule ip t c tcp flags == syn
| ip t c
| [ meta load l4proto => reg 1 ]
| [ cmp eq reg 1 0x00000006 ]
| [ payload load 1b @ transport header + 13 => reg 1 ]
| [ cmp eq reg 1 0x00000002 ]
OP_IMPLICIT creates a match which just checks the given flag is present,
while OP_EQ creates a match which ensures the given flag and no other is
present.
Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
You need a Linux kernel >= 4.15 to use this feature.
This patch allows us to dump the content of an existing set.
# nft list ruleset
table ip x {
set x {
type ipv4_addr
flags interval
elements = { 1.1.1.1-2.2.2.2, 3.3.3.3,
5.5.5.5-6.6.6.6 }
}
}
You check if a single element exists in the set:
# nft get element x x { 1.1.1.5 }
table ip x {
set x {
type ipv4_addr
flags interval
elements = { 1.1.1.1-2.2.2.2 }
}
}
Output means '1.1.1.5' belongs to the '1.1.1.1-2.2.2.2' interval.
You can also check for intervals:
# nft get element x x { 1.1.1.1-2.2.2.2 }
table ip x {
set x {
type ipv4_addr
flags interval
elements = { 1.1.1.1-2.2.2.2 }
}
}
If you try to check for an element that doesn't exist, an error is
displayed.
# nft get element x x { 1.1.1.0 }
Error: Could not receive set elements: No such file or directory
get element x x { 1.1.1.0 }
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
You can also check for multiple elements in one go:
# nft get element x x { 1.1.1.5, 5.5.5.10 }
table ip x {
set x {
type ipv4_addr
flags interval
elements = { 1.1.1.1-2.2.2.2, 5.5.5.5-6.6.6.6 }
}
}
You can also use this to fetch the existing timeout for specific
elements, in case you have a set with timeouts in place:
# nft get element w z { 2.2.2.2 }
table ip w {
set z {
type ipv4_addr
timeout 30s
elements = { 2.2.2.2 expires 17s }
}
}
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Harsha Sharma [Mon, 8 Jan 2018 17:57:07 +0000 (23:27 +0530)]
parser_bison: delete table via table handle
This patch allows deletion of table via unique table handles and table
family which can be listed with '-a' option.
For.eg.
nft delete table [<family>] [handle <handle>]
Signed-off-by: Harsha Sharma <harshasharmaiitr@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This patch allows us to refer to existing flowtables:
# nft add rule x x flow offload @m
Packets matching this rule create an entry in the flow table 'm', hence,
follow up packets that get to the flowtable at ingress bypass the
classic forwarding path.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
# nft add table x
# nft add flowtable x m { hook ingress priority 10\; devices = { eth0, wlan0 }\; }
You have to specify hook and priority. So far, only the ingress hook is
supported. The priority represents where this flowtable is placed in the
ingress hook, which is registered to the devices that the user
specifies.
You can also use the 'create' command instead to bail out in case that
there is an existing flowtable with this name.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
src: add variable expression and use it to allow redefinitions
Add new variable expression that we can use to attach symbols in
runtime, this allows us to redefine variables via new keyword, eg.
table ip x {
chain y {
define address = { 1.1.1.1, 2.2.2.2 }
ip saddr $address
redefine address = { 3.3.3.3 }
ip saddr $address
}
}
# nft list ruleset
table ip x {
chain y {
ip saddr { 1.1.1.1, 2.2.2.2 }
ip saddr { 3.3.3.3 }
}
}
Note that redefinition just places a new symbol version before the
existing one, so symbol lookups always find the latest version. The
undefine keyword decrements the reference counter and removes the symbol
from the list, so it cannot be used anymore. Still, previous references
to this symbol via variable expression are still valid.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* AC_PREREQ checks for 2.61, which is not supported any contemporary
distribution.
* AC_COPYRIGHT, autoconf documentation states "in addition to the Free
Software Foundation's copyright on the Autoconf macros, parts of your
configure are covered by the copyright-notice.".
This only refers to the autoconf infrastructure: we are doing simple
and standard usage of autoconf infrastructure, we also don't use this
macro in other existing userspace software available at netfilter.org.
The comment above at the beginning of this file shows text that is
available in many configure.ac templates on the Internet.
* AC_CANONICAL_HOST, we don't need the canonical host-system type to
build this software.
* AC_CONFIG_SRCDIR is not used in other userspace software in the tree.
* AC_DEFINE _GNU_SOURCE, define this where it's needed instead.
* AC_DEFINE _STDC_FORMAT_MACROS is not used in this codebase.
* AC_HEADER_STDC checks for ANSI C89 headers, however, we need more than
just this C standard, so this doesn't guarantee anything at all.
* Remove "Checks for libraries" comment, it's obvious.
* AC_HEADER_ASSERT allows us to disable assertions, this is bad because
this is helping us to diagnose bugs and incomplete features.
* AC_CHECK_HEADERS is checking for an arbitrary list of headers,
this still doesn't even guarantee that we can actually do a successful
compilation in a broken system.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: Florian Westphal <fw@strlen.de>
Phil Sutter [Thu, 1 Mar 2018 14:00:32 +0000 (15:00 +0100)]
netlink_delinearize: Fix resource leaks
Most of the cases are basically the same: Error path fails to free the
previously allocated statement or expression. A few cases received
special treatment though:
- In netlink_parse_payload_stmt(), the leak is easily avoided by code
reordering.
- In netlink_parse_exthdr(), there's no point in introducing a goto
label since there is but a single affected error check.
- In netlink_parse_hash() non-error path leaked as well if sreg
contained a concatenated expression.
Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Phil Sutter [Thu, 1 Mar 2018 14:00:31 +0000 (15:00 +0100)]
netlink: Complain if setting O_NONBLOCK fails
Assuming that code is not aware that reads from netlink socket may
block, treat inability to set O_NONBLOCK flag as fatal initialization
error aborting program execution.
Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
will call expr_cmp() in case e1->hash.expr is NULL, causing null-pointer
dereference. This is probably a typo, the intention when introducing
this was to avoid the call to expr_cmp() for symmetric hash expressions
which don't use expr->hash.expr. Inverting the existence check should
fix this.
Fixes: 3a86406729782 ("src: hash: support of symmetric hash") Cc: Laura Garcia Liebana <nevola@gmail.com> Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Phil Sutter [Thu, 1 Mar 2018 14:00:27 +0000 (15:00 +0100)]
cli: Drop pointless check in cli_append_multiline()
The function is called from cli_complete after it has checked for line
to be != NULL. The other part of the conditional, namely multiline being
NULL, is perfectly valid (if the last read line didn't end with
backslash. Hence drop the conditional completely.
Since variable eof is not used anywhere outside of the dropped
conditional, get rid of it completely.
Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
David Fabian [Mon, 22 Jan 2018 13:02:11 +0000 (14:02 +0100)]
Added undefine/redefine keywords
This is a small patch to nft which adds two new keywords - undefine and
redefine. undefine simply undefines a variable from the current scope.
redefine allows one to change a variable definition. We have a firewall
written in bash (using iptables) that is organized by customer VLANs.
Each VLAN has its own set of bash variables holding things like uplink
iface names, gateway IPs, etc. We want to rewrite the firewall to
nftables but are stuck on the fact that nft variables cannot be
overridden in the same scope. We have each VLAN configuration in a
separate file containing pre/post-routing, input, output and forward
rules,and we include those files to a master firewall configuration. One
solution is to rename all the variables with some VLAN specific
(pre/su)ffix. But that is cumbersome.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Florian Westphal [Sun, 25 Feb 2018 18:46:04 +0000 (19:46 +0100)]
src: make raw payloads work
make syntax consistent between print and parse.
No dependency handling -- once you use raw expression, you need
to make sure the raw expression only sees the packets that you'd
want it to see.
based on an earlier patch from Laurent Fasnacht <l@libres.ch>.
Laurents patch added a different syntax:
@<protocol>,<base>,<data type>,<offset>,<length>
data_type is useful to make nftables not err when
asking for "@payload,32,32 192.168.0.1", this patch still requires
manual convsersion to an integer type (hex or decimal notation).
data_type should probably be added later by adding an explicit
cast expression, independent of the raw payload syntax.
Concatenate all family/hook examples into a single one by means of includes.
Put all example files under examples/. Use the '.nft' prefix and mark
them as executable files. Use a static shebang declaration, since these
are examples meant for final systems and users.
While at it, refresh also the sets_and_maps.nft example file and also
add the 'netdev-ingress.nft' example file.
Signed-off-by: Arturo Borrero Gonzalez <arturo@netfilter.org> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Florian Westphal [Sat, 24 Feb 2018 11:28:30 +0000 (12:28 +0100)]
tests: meta.t: fix test case for anonymous set automerge
commit fb16c8b7f795e0d
("evaluate: Enable automerge feature for anonymous sets") re-enabled
merging of adjacent ranges, so 33-55, 56-88 turns into 33-88.
Do not exercise dependency removal for protocol key network payload
expressions in bridge, netdev and inet families from meta expressions,
more specifically:
* inet: nfproto and ether type.
* netdev and bridge: meta protocol and ether type.
need to be left in place.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Payload protocol key expressions at network base are meaningful in the
netdev, bridge and inet families, do not exercise the redundant
dependency removal in those cases since it breaks rule semantics.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>