diff options
author | Máté Eckl <ecklm94@gmail.com> | 2018-09-05 11:16:44 +0200 |
---|---|---|
committer | Florian Westphal <fw@strlen.de> | 2018-09-21 12:06:27 +0200 |
commit | 57c2b152c5f0866be5bf1acda2f341ba26ba9448 (patch) | |
tree | 091cabd5ef590d0d0edf0dc972d3cf53ae0008cb /src/parser_bison.y | |
parent | 8f55ed41d007061bd8aae94fee2bda172c0e8996 (diff) |
src: add ipsec (xfrm) expression
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 <ecklm94@gmail.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
Diffstat (limited to 'src/parser_bison.y')
-rw-r--r-- | src/parser_bison.y | 66 |
1 files changed, 66 insertions, 0 deletions
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 <linux/netfilter/nf_conntrack_tuple_common.h> #include <linux/netfilter/nf_nat.h> #include <linux/netfilter/nf_log.h> +#include <linux/xfrm.h> #include <netinet/ip_icmp.h> #include <netinet/icmp6.h> #include <libnftnl/common.h> @@ -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 <string> 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 <list> timeout_states timeout_state %destructor { xfree($$); } timeout_states timeout_state +%type <val> xfrm_state_key xfrm_state_proto_key xfrm_dir xfrm_spnum +%type <expr> 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); |