From 450653a4f0822f170cb412013aa4cf9d6ef6ce3a Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Tue, 28 Feb 2017 00:59:02 +0100 Subject: src: add conntrack zone support This enables zone get/set support. As the zone can be optionally tied to a direction as well we need a new token for this (unless we turn reply/original into tokens in which case we could handle zone via STRING). There was some discussion on how zone set support should be handled, especially 'zone set 1'. There are several issues to consider: 1. its not possible to change a zone 'later on', any given conntrack flow has exactly one zone for its entire lifetime. 2. to create conntracks in a given zone, the zone therefore has to be assigned *before* the packet gets picked up by conntrack (so that lookup finds the correct existing flow or the flow is created with the desired zone id). In iptables, this is enforced because zones are assigned with CT target and this is restricted to the 'raw' table in iptables, which runs after defragmentation but before connection tracking. 3. Thus, in nftables the 'ct zone set' rule needs to hook before conntrack too, e.g. via table raw { chain pre { type filter hook prerouting priority -300; iif eth3 ct zone set 23 } chain out { type filter hook output priority -300; oif eth3 ct zone set 23 } } ... but this is not enforced. There were two alternatives to better document this. One was to use an explicit 'template' keyword: nft ... template zone set 23 ... but 'connection tracking templates' are a kernel detail that users should not and need not know about. The other one was to use the meta keyword instead since we're (from a practical point of view) assigning the zone to the packet, not the conntrack: nft ... meta zone set 23 However, next patch also supports 'directional' zones, and nft ... meta original zone 23 makes no sense because 'direction' refers to a direction as understood by the connection tracker. Signed-off-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso --- src/ct.c | 2 ++ src/parser_bison.y | 10 ++++++---- src/scanner.l | 1 + 3 files changed, 9 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/ct.c b/src/ct.c index 31c7a4b1..99f450a7 100644 --- a/src/ct.c +++ b/src/ct.c @@ -234,6 +234,8 @@ static const struct ct_template ct_templates[] = { BYTEORDER_HOST_ENDIAN, 64), [NFT_CT_AVGPKT] = CT_TEMPLATE("avgpkt", &integer_type, BYTEORDER_HOST_ENDIAN, 64), + [NFT_CT_ZONE] = CT_TEMPLATE("zone", &integer_type, + BYTEORDER_HOST_ENDIAN, 16), }; static void ct_expr_print(const struct expr *expr) diff --git a/src/parser_bison.y b/src/parser_bison.y index b295bfde..80ac2bd0 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -358,6 +358,7 @@ static void location_update(struct location *loc, struct location *rhs, int n) %token L3PROTOCOL "l3proto" %token PROTO_SRC "proto-src" %token PROTO_DST "proto-dst" +%token ZONE "zone" %token COUNTER "counter" %token NAME "name" @@ -614,7 +615,7 @@ static void location_update(struct location *loc, struct location *rhs, int n) %type ct_expr %destructor { expr_free($$); } ct_expr -%type ct_key ct_key_dir ct_key_counters +%type ct_key ct_key_dir ct_key_dir_optional %type fib_expr %destructor { expr_free($$); } fib_expr @@ -2957,7 +2958,7 @@ ct_expr : CT ct_key ct_key : L3PROTOCOL { $$ = NFT_CT_L3PROTOCOL; } | PROTOCOL { $$ = NFT_CT_PROTOCOL; } | MARK { $$ = NFT_CT_MARK; } - | ct_key_counters + | ct_key_dir_optional ; ct_key_dir : SADDR { $$ = NFT_CT_SRC; } | DADDR { $$ = NFT_CT_DST; } @@ -2965,12 +2966,13 @@ ct_key_dir : SADDR { $$ = NFT_CT_SRC; } | PROTOCOL { $$ = NFT_CT_PROTOCOL; } | PROTO_SRC { $$ = NFT_CT_PROTO_SRC; } | PROTO_DST { $$ = NFT_CT_PROTO_DST; } - | ct_key_counters + | ct_key_dir_optional ; -ct_key_counters : BYTES { $$ = NFT_CT_BYTES; } +ct_key_dir_optional : BYTES { $$ = NFT_CT_BYTES; } | PACKETS { $$ = NFT_CT_PKTS; } | AVGPKT { $$ = NFT_CT_AVGPKT; } + | ZONE { $$ = NFT_CT_ZONE; } ; ct_stmt : CT ct_key SET expr diff --git a/src/scanner.l b/src/scanner.l index 922d8ec8..e0ddcac1 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -461,6 +461,7 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr}) "l3proto" { return L3PROTOCOL; } "proto-src" { return PROTO_SRC; } "proto-dst" { return PROTO_DST; } +"zone" { return ZONE; } "numgen" { return NUMGEN; } "inc" { return INC; } -- cgit v1.2.3