* [nft PATCH v2 0/3] Follow-up to boolean type and existence checks
@ 2017-03-11 13:31 Phil Sutter
2017-03-11 13:31 ` [nft PATCH v2 1/3] fib: Support existence check Phil Sutter
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Phil Sutter @ 2017-03-11 13:31 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
This series is a follow-up to the partially applied v1 which takes into
account the previously submitted changes to libnftnl debug output format
for fib and exthdr ops.
Phil Sutter (3):
fib: Support existence check
tests: Adjust for changed exthdr debug output
doc: Document boolean type and applications
doc/nft.xml | 134 ++++++++++++++++++++++++++++++++++++
include/expression.h | 2 +
include/linux/netfilter/nf_tables.h | 1 +
src/evaluate.c | 14 +++-
src/expression.c | 4 ++
src/fib.c | 5 +-
tests/py/inet/fib.t | 3 +
tests/py/inet/fib.t.payload | 10 +++
tests/py/inet/tcpopt.t.payload.inet | 4 +-
tests/py/ip6/exthdr.t.payload.ip6 | 24 +++----
10 files changed, 185 insertions(+), 16 deletions(-)
--
2.11.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [nft PATCH v2 1/3] fib: Support existence check
2017-03-11 13:31 [nft PATCH v2 0/3] Follow-up to boolean type and existence checks Phil Sutter
@ 2017-03-11 13:31 ` Phil Sutter
2017-03-11 13:31 ` [nft PATCH v2 2/3] tests: Adjust for changed exthdr debug output Phil Sutter
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Phil Sutter @ 2017-03-11 13:31 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
This allows to check whether a FIB entry exists for a given packet by
comparing the expression with a boolean keyword like so:
| fib daddr oif exists
The implementation requires introduction of a generic expression flag
EXPR_F_BOOLEAN which allows relational expression to signal it's LHS
that a boolean comparison is being done (indicated by boolean type on
RHS). In contrast to exthdr existence checks, fib expression can't know
this in beforehand because the LHS syntax is absolutely identical to a
non-boolean comparison.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
Changes since v1:
- Adjust tests to changed libnftnl debug output.
---
include/expression.h | 2 ++
include/linux/netfilter/nf_tables.h | 1 +
src/evaluate.c | 14 +++++++++++++-
src/expression.c | 4 ++++
src/fib.c | 5 ++++-
tests/py/inet/fib.t | 3 +++
tests/py/inet/fib.t.payload | 10 ++++++++++
7 files changed, 37 insertions(+), 2 deletions(-)
diff --git a/include/expression.h b/include/expression.h
index 423eae7128f5c..94573de087ad7 100644
--- a/include/expression.h
+++ b/include/expression.h
@@ -171,12 +171,14 @@ struct expr_ops {
* @EXPR_F_SINGLETON: singleton (implies primary and constant)
* @EXPR_F_PROTOCOL: expressions describes upper layer protocol
* @EXPR_F_INTERVAL_END: set member ends an open interval
+ * @EXPR_F_BOOLEAN: expression is boolean (set by relational expr on LHS)
*/
enum expr_flags {
EXPR_F_CONSTANT = 0x1,
EXPR_F_SINGLETON = 0x2,
EXPR_F_PROTOCOL = 0x4,
EXPR_F_INTERVAL_END = 0x8,
+ EXPR_F_BOOLEAN = 0x10,
};
#include <payload.h>
diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
index 4f7d75682c591..a9280a6541ac6 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -1257,6 +1257,7 @@ enum nft_fib_flags {
NFTA_FIB_F_MARK = 1 << 2, /* use skb->mark */
NFTA_FIB_F_IIF = 1 << 3, /* restrict to iif */
NFTA_FIB_F_OIF = 1 << 4, /* restrict to oif */
+ NFTA_FIB_F_PRESENT = 1 << 5, /* check existence only */
};
#define NFT_OBJECT_UNSPEC 0
diff --git a/src/evaluate.c b/src/evaluate.c
index 7c039cbab5ec3..7ddbb658f96fa 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -1658,6 +1658,17 @@ range:
return 0;
}
+static int expr_evaluate_fib(struct eval_ctx *ctx, struct expr **exprp)
+{
+ struct expr *expr = *exprp;
+
+ if (expr->flags & EXPR_F_BOOLEAN) {
+ expr->fib.flags |= NFTA_FIB_F_PRESENT;
+ expr->dtype = &boolean_type;
+ }
+ return expr_evaluate_primary(ctx, exprp);
+}
+
static int expr_evaluate(struct eval_ctx *ctx, struct expr **expr)
{
#ifdef DEBUG
@@ -1680,8 +1691,9 @@ static int expr_evaluate(struct eval_ctx *ctx, struct expr **expr)
return expr_evaluate_exthdr(ctx, expr);
case EXPR_VERDICT:
case EXPR_META:
- case EXPR_FIB:
return expr_evaluate_primary(ctx, expr);
+ case EXPR_FIB:
+ return expr_evaluate_fib(ctx, expr);
case EXPR_PAYLOAD:
return expr_evaluate_payload(ctx, expr);
case EXPR_RT:
diff --git a/src/expression.c b/src/expression.c
index da94b79f1d913..a6065524f8be8 100644
--- a/src/expression.c
+++ b/src/expression.c
@@ -592,6 +592,10 @@ struct expr *relational_expr_alloc(const struct location *loc, enum ops op,
expr->left = left;
expr->op = op;
expr->right = right;
+
+ if (right->dtype == &boolean_type)
+ left->flags |= EXPR_F_BOOLEAN;
+
return expr;
}
diff --git a/src/fib.c b/src/fib.c
index c65677c811abc..28ef4b50b3ea3 100644
--- a/src/fib.c
+++ b/src/fib.c
@@ -73,7 +73,7 @@ static void __fib_expr_print_f(unsigned int *flags, unsigned int f, const char *
static void fib_expr_print(const struct expr *expr)
{
- unsigned int flags = expr->fib.flags;
+ unsigned int flags = expr->fib.flags & ~NFTA_FIB_F_PRESENT;
printf("fib ");
__fib_expr_print_f(&flags, NFTA_FIB_F_SADDR, "saddr");
@@ -130,6 +130,9 @@ struct expr *fib_expr_alloc(const struct location *loc,
BUG("Unknown result %d\n", result);
}
+ if (flags & NFTA_FIB_F_PRESENT)
+ type = &boolean_type;
+
expr = expr_alloc(loc, &fib_expr_ops, type,
BYTEORDER_HOST_ENDIAN, len);
diff --git a/tests/py/inet/fib.t b/tests/py/inet/fib.t
index 9ee282ab1c93d..dbe45d95b4cfe 100644
--- a/tests/py/inet/fib.t
+++ b/tests/py/inet/fib.t
@@ -12,3 +12,6 @@ fib saddr . iif oifname "lo";ok
fib daddr . iif type local;ok
fib daddr . iif type vmap { blackhole : drop, prohibit : drop, unicast : accept };ok
fib daddr . oif type local;fail
+
+fib daddr oif exists;ok
+fib daddr oif missing;ok
diff --git a/tests/py/inet/fib.t.payload b/tests/py/inet/fib.t.payload
index f5258165384dc..1d4c3d94aa0bf 100644
--- a/tests/py/inet/fib.t.payload
+++ b/tests/py/inet/fib.t.payload
@@ -20,3 +20,13 @@ __map%d test-ip 0
ip test-ip prerouting
[ fib daddr . iif type => reg 1 ]
[ lookup reg 1 set __map%d dreg 0 ]
+
+# fib daddr oif exists
+ip test-ip prerouting
+ [ fib daddr oif present => reg 1 ]
+ [ cmp eq reg 1 0x00000001 ]
+
+# fib daddr oif missing
+ip test-ip prerouting
+ [ fib daddr oif present => reg 1 ]
+ [ cmp eq reg 1 0x00000000 ]
--
2.11.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [nft PATCH v2 2/3] tests: Adjust for changed exthdr debug output
2017-03-11 13:31 [nft PATCH v2 0/3] Follow-up to boolean type and existence checks Phil Sutter
2017-03-11 13:31 ` [nft PATCH v2 1/3] fib: Support existence check Phil Sutter
@ 2017-03-11 13:31 ` Phil Sutter
2017-03-11 13:31 ` [nft PATCH v2 3/3] doc: Document boolean type and applications Phil Sutter
2017-03-13 11:15 ` [nft PATCH v2 0/3] Follow-up to boolean type and existence checks Pablo Neira Ayuso
3 siblings, 0 replies; 5+ messages in thread
From: Phil Sutter @ 2017-03-11 13:31 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
Debug output from libnftnl has changed to include 'present' keyword if
NFT_EXTHDR_F_PRESENT flag is set in expression.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
Changes since v1:
- Patch introduced.
---
tests/py/inet/tcpopt.t.payload.inet | 4 ++--
tests/py/ip6/exthdr.t.payload.ip6 | 24 ++++++++++++------------
2 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/tests/py/inet/tcpopt.t.payload.inet b/tests/py/inet/tcpopt.t.payload.inet
index 0d14e77929cca..10cf0c00f402f 100644
--- a/tests/py/inet/tcpopt.t.payload.inet
+++ b/tests/py/inet/tcpopt.t.payload.inet
@@ -184,12 +184,12 @@ inet test-inet input
inet test-inet input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000006 ]
- [ exthdr load tcpopt 1b @ 3 + 0 => reg 1 ]
+ [ exthdr load tcpopt 1b @ 3 + 0 present => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
# tcp option window missing
inet test-inet input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000006 ]
- [ exthdr load tcpopt 1b @ 3 + 0 => reg 1 ]
+ [ exthdr load tcpopt 1b @ 3 + 0 present => reg 1 ]
[ cmp eq reg 1 0x00000000 ]
diff --git a/tests/py/ip6/exthdr.t.payload.ip6 b/tests/py/ip6/exthdr.t.payload.ip6
index b45eb8e74272f..3b6bb6219fa4b 100644
--- a/tests/py/ip6/exthdr.t.payload.ip6
+++ b/tests/py/ip6/exthdr.t.payload.ip6
@@ -1,60 +1,60 @@
# exthdr hbh exists
ip6 test-ip6 input
- [ exthdr load 1b @ 0 + 0 => reg 1 ]
+ [ exthdr load 1b @ 0 + 0 present => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
# exthdr rt exists
ip6 test-ip6 input
- [ exthdr load 1b @ 43 + 0 => reg 1 ]
+ [ exthdr load 1b @ 43 + 0 present => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
# exthdr frag exists
ip6 test-ip6 input
- [ exthdr load 1b @ 44 + 0 => reg 1 ]
+ [ exthdr load 1b @ 44 + 0 present => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
# exthdr dst exists
ip6 test-ip6 input
- [ exthdr load 1b @ 60 + 0 => reg 1 ]
+ [ exthdr load 1b @ 60 + 0 present => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
# exthdr mh exists
ip6 test-ip6 input
- [ exthdr load 1b @ 135 + 0 => reg 1 ]
+ [ exthdr load 1b @ 135 + 0 present => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
# exthdr hbh missing
ip6 test-ip6 input
- [ exthdr load 1b @ 0 + 0 => reg 1 ]
+ [ exthdr load 1b @ 0 + 0 present => reg 1 ]
[ cmp eq reg 1 0x00000000 ]
# exthdr hbh == exists
ip6 test-ip6 input
- [ exthdr load 1b @ 0 + 0 => reg 1 ]
+ [ exthdr load 1b @ 0 + 0 present => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
# exthdr hbh == missing
ip6 test-ip6 input
- [ exthdr load 1b @ 0 + 0 => reg 1 ]
+ [ exthdr load 1b @ 0 + 0 present => reg 1 ]
[ cmp eq reg 1 0x00000000 ]
# exthdr hbh != exists
ip6 test-ip6 input
- [ exthdr load 1b @ 0 + 0 => reg 1 ]
+ [ exthdr load 1b @ 0 + 0 present => reg 1 ]
[ cmp neq reg 1 0x00000001 ]
# exthdr hbh != missing
ip6 test-ip6 input
- [ exthdr load 1b @ 0 + 0 => reg 1 ]
+ [ exthdr load 1b @ 0 + 0 present => reg 1 ]
[ cmp neq reg 1 0x00000000 ]
# exthdr hbh 1
ip6 test-ip6 input
- [ exthdr load 1b @ 0 + 0 => reg 1 ]
+ [ exthdr load 1b @ 0 + 0 present => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
# exthdr hbh 0
ip6 test-ip6 input
- [ exthdr load 1b @ 0 + 0 => reg 1 ]
+ [ exthdr load 1b @ 0 + 0 present => reg 1 ]
[ cmp eq reg 1 0x00000000 ]
--
2.11.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [nft PATCH v2 3/3] doc: Document boolean type and applications
2017-03-11 13:31 [nft PATCH v2 0/3] Follow-up to boolean type and existence checks Phil Sutter
2017-03-11 13:31 ` [nft PATCH v2 1/3] fib: Support existence check Phil Sutter
2017-03-11 13:31 ` [nft PATCH v2 2/3] tests: Adjust for changed exthdr debug output Phil Sutter
@ 2017-03-11 13:31 ` Phil Sutter
2017-03-13 11:15 ` [nft PATCH v2 0/3] Follow-up to boolean type and existence checks Pablo Neira Ayuso
3 siblings, 0 replies; 5+ messages in thread
From: Phil Sutter @ 2017-03-11 13:31 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
Changes since v1:
- Nothing changed, just resubmitting.
---
doc/nft.xml | 134 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 134 insertions(+)
diff --git a/doc/nft.xml b/doc/nft.xml
index 990b93684c9c4..de86d2a18258f 100644
--- a/doc/nft.xml
+++ b/doc/nft.xml
@@ -1329,6 +1329,110 @@ filter output ip6 daddr ::1
</programlisting>
</example>
</refsect2>
+
+ <refsect2>
+ <title>Boolean type</title>
+ <para>
+ <table frame="all">
+ <tgroup cols='4' align='left' colsep='1' rowsep='1'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <colspec colname='c3'/>
+ <colspec colname='c4'/>
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Keyword</entry>
+ <entry>Size</entry>
+ <entry>Base type</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>Boolean</entry>
+ <entry>boolean</entry>
+ <entry>1 bit</entry>
+ <entry>integer</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </para>
+ <para>
+ The boolean type is a syntactical helper type in user space.
+ It's use is in the right-hand side of a (typically implicit)
+ relational expression to change the expression on the left-hand
+ side into a boolean check (usually for existence).
+ </para>
+ <para>
+ The following keywords will automatically resolve into a boolean
+ type with given value:
+ <table frame="all">
+ <tgroup cols='2' align='left' colsep='1' rowsep='1'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <thead>
+ <row>
+ <entry>Keyword</entry>
+ <entry>Value</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>exists</entry>
+ <entry>1</entry>
+ </row>
+ <row>
+ <entry>missing</entry>
+ <entry>0</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </para>
+ <example>
+ <title>Boolean specification</title>
+ <para>
+ The following expressions support a boolean comparison:
+ <table frame="all">
+ <tgroup cols='2' align='left' colsep='1' rowsep='1'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <thead>
+ <row>
+ <entry>Expression</entry>
+ <entry>Behaviour</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>fib</entry>
+ <entry>Check route existence.</entry>
+ </row>
+ <row>
+ <entry>exthdr</entry>
+ <entry>Check IPv6 extension header existence.</entry>
+ </row>
+ <row>
+ <entry>tcp option</entry>
+ <entry>Check TCP option header existence.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </para>
+ <programlisting>
+# match if route exists
+filter input fib iif saddr exists
+
+# match only non-fragmented packets in IPv6 traffic
+filter input exthdr frag missing
+
+# match if TCP timestamp option is present
+filter input tcp option timestamp exists
+ </programlisting>
+ </example>
+ </refsect2>
</refsect1>
<refsect1>
@@ -2536,6 +2640,36 @@ inet filter meta nfproto ipv6 output rt nexthop fd00::1
<arg choice="none"><replaceable>tcp_option_field</replaceable></arg>
</cmdsynopsis>
<para>
+ The following syntaxes are valid only in a relational expression
+ with boolean type on right-hand side for checking header existence only:
+ </para>
+ <cmdsynopsis>
+ <command>exthdr</command>
+ <group choice="req">
+ <arg>hbh</arg>
+ <arg>frag</arg>
+ <arg>rt</arg>
+ <arg>dst</arg>
+ <arg>mh</arg>
+ </group>
+ </cmdsynopsis>
+ <cmdsynopsis>
+ <command>tcp option</command>
+ <group choice="req">
+ <arg>eol</arg>
+ <arg>noop</arg>
+ <arg>maxseg</arg>
+ <arg>window</arg>
+ <arg>sack-permitted</arg>
+ <arg>sack</arg>
+ <arg>sack0</arg>
+ <arg>sack1</arg>
+ <arg>sack2</arg>
+ <arg>sack3</arg>
+ <arg>timestamp</arg>
+ </group>
+ </cmdsynopsis>
+ <para>
<table frame="all">
<title>IPv6 extension headers</title>
<tgroup cols='2' align='left' colsep='1' rowsep='1'>
--
2.11.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [nft PATCH v2 0/3] Follow-up to boolean type and existence checks
2017-03-11 13:31 [nft PATCH v2 0/3] Follow-up to boolean type and existence checks Phil Sutter
` (2 preceding siblings ...)
2017-03-11 13:31 ` [nft PATCH v2 3/3] doc: Document boolean type and applications Phil Sutter
@ 2017-03-13 11:15 ` Pablo Neira Ayuso
3 siblings, 0 replies; 5+ messages in thread
From: Pablo Neira Ayuso @ 2017-03-13 11:15 UTC (permalink / raw)
To: Phil Sutter; +Cc: netfilter-devel
On Sat, Mar 11, 2017 at 02:31:38PM +0100, Phil Sutter wrote:
> This series is a follow-up to the partially applied v1 which takes into
> account the previously submitted changes to libnftnl debug output format
> for fib and exthdr ops.
Series applied, thanks!
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2017-03-13 11:15 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-03-11 13:31 [nft PATCH v2 0/3] Follow-up to boolean type and existence checks Phil Sutter
2017-03-11 13:31 ` [nft PATCH v2 1/3] fib: Support existence check Phil Sutter
2017-03-11 13:31 ` [nft PATCH v2 2/3] tests: Adjust for changed exthdr debug output Phil Sutter
2017-03-11 13:31 ` [nft PATCH v2 3/3] doc: Document boolean type and applications Phil Sutter
2017-03-13 11:15 ` [nft PATCH v2 0/3] Follow-up to boolean type and existence checks Pablo Neira Ayuso
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).