From 57c2b152c5f0866be5bf1acda2f341ba26ba9448 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Eckl?= Date: Wed, 5 Sep 2018 11:16:44 +0200 Subject: src: add ipsec (xfrm) expression MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows matching on ipsec tunnel/beet addresses in xfrm state associated with a packet, ipsec request id and the SPI. Examples: ipsec in ip saddr 192.168.1.0/24 ipsec out ip6 daddr @endpoints ipsec in spi 1-65536 Joint work with Florian Westphal. Cc: Máté Eckl Signed-off-by: Florian Westphal --- src/parser_bison.y | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) (limited to 'src/parser_bison.y') diff --git a/src/parser_bison.y b/src/parser_bison.y index 5fd304a9..1c68b4f4 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -511,6 +512,15 @@ int nft_lex(void *, void *, void *); %token EXTHDR "exthdr" %token IPSEC "ipsec" +%token MODE "mode" +%token REQID "reqid" +%token SPNUM "spnum" +%token TRANSPORT "transport" +%token TUNNEL "tunnel" + +%token IN "in" +%token OUT "out" + %type identifier type_identifier string comment_spec %destructor { xfree($$); } identifier type_identifier string comment_spec @@ -759,6 +769,10 @@ int nft_lex(void *, void *, void *); %type timeout_states timeout_state %destructor { xfree($$); } timeout_states timeout_state +%type xfrm_state_key xfrm_state_proto_key xfrm_dir xfrm_spnum +%type xfrm_expr +%destructor { expr_free($$); } xfrm_expr + %% input : /* empty */ @@ -3043,6 +3057,7 @@ primary_expr : symbol_expr { $$ = $1; } | hash_expr { $$ = $1; } | fib_expr { $$ = $1; } | osf_expr { $$ = $1; } + | xfrm_expr { $$ = $1; } | '(' basic_expr ')' { $$ = $2; } ; @@ -3785,6 +3800,57 @@ numgen_expr : NUMGEN numgen_type MOD NUM offset_opt } ; +xfrm_spnum : SPNUM NUM { $$ = $2; } + | { $$ = 0; } + ; + +xfrm_dir : IN { $$ = XFRM_POLICY_IN; } + | OUT { $$ = XFRM_POLICY_OUT; } + ; + +xfrm_state_key : SPI { $$ = NFT_XFRM_KEY_SPI; } + | REQID { $$ = NFT_XFRM_KEY_REQID; } + ; + +xfrm_state_proto_key : DADDR { $$ = NFT_XFRM_KEY_DADDR_IP4; } + | SADDR { $$ = NFT_XFRM_KEY_SADDR_IP4; } + ; + +xfrm_expr : IPSEC xfrm_dir xfrm_spnum xfrm_state_key + { + if ($3 > 255) { + erec_queue(error(&@3, "value too large"), state->msgs); + YYERROR; + } + $$ = xfrm_expr_alloc(&@$, $2, $3, $4); + } + | IPSEC xfrm_dir xfrm_spnum nf_key_proto xfrm_state_proto_key + { + enum nft_xfrm_keys xfrmk = $5; + + switch ($4) { + case NFPROTO_IPV4: + break; + case NFPROTO_IPV6: + if ($5 == NFT_XFRM_KEY_SADDR_IP4) + xfrmk = NFT_XFRM_KEY_SADDR_IP6; + else if ($5 == NFT_XFRM_KEY_DADDR_IP4) + xfrmk = NFT_XFRM_KEY_DADDR_IP6; + break; + default: + YYERROR; + break; + } + + if ($3 > 255) { + erec_queue(error(&@3, "value too large"), state->msgs); + YYERROR; + } + + $$ = xfrm_expr_alloc(&@$, $2, $3, xfrmk); + } + ; + hash_expr : JHASH expr MOD NUM SEED NUM offset_opt { $$ = hash_expr_alloc(&@$, $4, true, $6, $7, NFT_HASH_JENKINS); -- cgit v1.2.3