src: support ct l3proto/protocol without direction syntax
Acctually, ct l3proto and ct protocol are unrelated to direction, so
it's unnecessary that we must specify dir if we want to use them.
Now add support that we can match ct l3proto/protocol without direction:
# nft add rule filter input ct l3proto ipv4
# nft add rule filter output ct protocol 17
Note: existing syntax is still preserved, so "ct reply l3proto ipv6"
is still fine.
Signed-off-by: Liping Zhang <liping.zhang@spreadtrum.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
tests: py: fix numgen case failed due to changes in libnftnl
In nftnl_expr_ng_snprintf_default, format "(%u)" was changed to
"mod %u", so numgen test case failed:
...
'[ numgen reg 1 = inc(2) ]' mismatches '[ numgen reg 1 = inc mod 2 ]'
...
ip/numgen.t: 3 unit tests, 3 error, 0 warning
Signed-off-by: Liping Zhang <liping.zhang@spreadtrum.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
src: fix compile error due to _UNTIL renamed to _MODULUS in libnftnl
In the latest libnftnl, NFTNL_EXPR_NG_UNTIL was renamed to
NFTNL_EXPR_NG_MODULUS, so compile error happened:
netlink_linearize.c: In function ‘netlink_gen_numgen’:
netlink_linearize.c:184:26: error: ‘NFTNL_EXPR_NG_UNTIL’ undeclared
(first use in this function)
Also update NFTA_NG_UNTIL to NFTA_NG_MODULUS.
Signed-off-by: Liping Zhang <liping.zhang@spreadtrum.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
tests: py: replace "eth0" with "lo" in dup expr tests
This patch follow up on Manuel's commit a8871ba6daa0 ("tests: py: any:
Make tests more generic by using other interfaces"). The ifindex of
"eth0" is not always 1, furthermore, "eth0" maybe not exist on some
systems. So replace it with "lo" will make tests more rubost.
In other test cases, "eth0" is used by iifname or oifname, so there's no
need to convert it to "lo". Even if "eth0" is not exist, test will never
fail.
This is what made ether addresses get formatted correctly with
plain payload expression (ether saddr 00:11 ...) when listing
rules. Not needed anymore since etheraddr_type is now BIG_ENDIAN.
Signed-off-by: Florian Westphal <fw@strlen.de> Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
As netlink_get_register() may return NULL, we must not pass the returned
data unchecked to expr_set_type() as that will dereference it. Since the
parser has failed at that point anyway, by returning early we can skip
the useless statement allocation that follows in
netlink_parse_ct_stmt().
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Acked-by: Phil Sutter <phil@nwl.cc>
tests: py: any: Make tests more generic by using other interfaces
Some tests use hard coded interface names and interface indexes.
This commit removes these cases by exchanging "eth0" with "dummy0" and
"lo" (depending on the test) in all ifname tests and by using "lo"
instead of "eth0" in all interface index tests (because we can assume
"lo" ifindex is 1).
Signed-off-by: Manuel Johannes Messner <manuel.johannes.messner@hs-furtwangen.de> Signed-off-by: Florian Westphal <fw@strlen.de>
evaluate: display expression, statement and command name on debug
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>
Phil Sutter [Tue, 30 Aug 2016 17:39:52 +0000 (19:39 +0200)]
evaluate: Avoid undefined behaviour in concat_subtype_id()
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>
Phil Sutter [Tue, 30 Aug 2016 17:39:51 +0000 (19:39 +0200)]
evaluate: reject: Have a generic fix for missing network context
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>
Phil Sutter [Tue, 30 Aug 2016 17:39:49 +0000 (19:39 +0200)]
evaluate: Fix datalen checks in expr_evaluate_string()
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>
set s-ext-2-int {
type ipv4_addr . inet_service
elements = { $s-ext-2-int }
}
This syntax is not correct though, since the curly braces should be
placed in the variable definition itself, so we have context to handle
this variable as a list of set elements.
The correct syntax that works after this patch is:
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>
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:
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:
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:
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>
tests: py: adapt it to new add element command semantics
Since fd33d96 ("src: create element command"), add element doesn't
fail anymore if the element exists, you have to use create instead in
case you want to check if the element already exists.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This patch adds the create command, that send the NLM_F_EXCL flag so
nf_tables bails out if the element already exists, eg.
# nft add element x y { 1.1.1.1 }
# nft create element x y { 1.1.1.1 }
<cmdline>:1:1-31: Error: Could not process rule: File exists
create element x y { 1.1.1.1 }
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This update requires nf_tables kernel patches to honor the NLM_F_EXCL.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Add support for the 'create' command, we already support this in other
existing objects, so support this for sets too, eg.
# nft add set x y { type ipv4_addr\; }
# nft create set x y { type ipv4_addr\; }
<cmdline>:1:1-35: Error: Could not process rule: File exists
create set x y { type ipv4_addr; }
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# nft add set x y { type ipv4_addr\; }
#
This command sets the NLM_F_EXCL netlink flag, so if the object already
exists, nf_tables returns -EEXIST.
This is changing the existing behaviour of 'nft add set' which was
setting this flag, this is inconsistent with regards to the way other
objects behave.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
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>
We should keep existing syntax unchanged, and this was emphasized
in the commit 850f0a56b6ad ("src: add 'to' for snat and dnat")'s
commit log: "Existing syntax is still preserved, but the listing
shows the one including 'to'."
This problem was found by running shell test:
# ./run-tests.sh
[ ... ]
W: [FAILED] ./testcases/maps/anonymous_snat_map_0
I: [OK] ./testcases/maps/map_with_flags_0
W: [FAILED] ./testcases/maps/named_snat_map_0
[ ... ]
Fixes: 850f0a56b6ad ("src: add 'to' for snat and dnat") Signed-off-by: Liping Zhang <liping.zhang@spreadtrum.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This patch adds the missing bits to scan and parse the meta priority
handle as expressed by tc classid major:minor syntax.
The :minor syntax is not support for two reason: major is always >= 1
and this clashes with port syntax in nat.
Here below, several example on how to match the packet priority field:
nft add rule filter forward meta priority abcd:0
nft add rule filter forward meta priority abcd:1234
and to set it, you have to:
nft add rule filter forward meta priority set abcd:1234
The priority expression in flex looks ahead to restrict the pattern to
avoid problems with mappings:
{classid}/[ \t\n:\-},]
So the following doesn't break:
... vmap { 25:accept }
^^^^^
The lookahead expression requires a slight change to extend the input
string in one byte.
This patch is conservative as you always have to explicity indicate
major and minor numbers even if zero.
We could consider supporting this shortcut in the future:
abcd:
However, with regards to this:
:abcd
We don't need to support it since major number is assumed to be >= 1.
However, if we ever decide to support this, we'll have problems since
this clashes with our port representation in redirect and mangle.
So let's keep this simple and start with this approach.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
scanner: allow strings starting by underscores and dots
POSIX.1-2008 (which is simultaneously IEEE Std 1003.1-2008) says:
"The set of characters from which portable filenames are constructed.
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
a b c d e f g h i j k l m n o p q r s t u v w x y z
0 1 2 3 4 5 6 7 8 9 . _ -"
On top of that it says:
"The <hyphen> character should not be used as the first character of a
portable user name."
This allows a bit more things that NAME_REGEX though, but this still
looks fine to me.
For more info, see:
http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_431
http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_278
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
scanner: don't fall back on current directory if include is not found
This resolves an ambiguity if the same file name is used both under
sysconfdir and the current working directory. You can use dot slash
./ to explicitly refer to files in the current working directory.
Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1040 Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
evaluate: add support to set IPv6 non-byte header fields
'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.
binop_adjust takes an expression whose LHS is expected to be
the binop expression that we use to adjust a payload expression
based on a mask (to match sub-byte headers like iphdr->version).
A followup patch has to pass the binop directly, so add
add a helper for it.
Signed-off-by: Florian Westphal <fw@strlen.de> Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
ct: use nftables sysconf location for connlabel configuration
Instead of using /etc/xtables use the nftables syconfdir.
Also update error message to tell which label failed translation
and which config file was used for this:
nft add filter input ct label foo
<cmdline>:1:27-29: Error: /etc/nftables/connlabel.conf: could not parse conntrack label "foo"
Suggested-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: Florian Westphal <fw@strlen.de>
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>
Nicholas Vinson [Sat, 2 Jul 2016 18:34:20 +0000 (11:34 -0700)]
nft: configure.ac: Replace magic dblatex dep.
Add a configure switch to enable and disable PDF document generation.
This switch is to replace the current method of automatically detecting
dblatex and building the PDF documentation when present.
Signed-off-by: Nicholas Vinson <nvinson234@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>