summaryrefslogtreecommitdiffstats
path: root/src/parser_bison.y
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser_bison.y')
-rw-r--r--src/parser_bison.y66
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);