Statistics
| Branch: | Revision:

iof-bird / bird-2.0.1 / conf / flowspec.Y @ 6b3f1a54

History | View | Annotate | Download (5.22 KB)

1
/*
2
 *	BIRD -- Flow specification (RFC 5575) grammar
3
 *
4
 *	(c) 2016 CZ.NIC z.s.p.o.
5
 *
6
 *	Can be freely distributed and used under the terms of the GNU GPL.
7
 */
8

    
9
CF_HDR
10

    
11
#define PARSER 1
12

    
13
#include "nest/bird.h"
14
#include "lib/flowspec.h"
15

    
16

    
17
CF_DEFINES
18

    
19
struct flow_builder *this_flow;
20

    
21

    
22
CF_DECLS
23

    
24
%type <i32> flow_num_op flow_srcdst flow_logic_op flow_num_type_ flow_frag_val flow_neg
25
%type <net_ptr> net_flow4_ net_flow6_ net_flow_
26

    
27
CF_KEYWORDS(FLOW4, FLOW6, DST, SRC, PROTO, NEXT, HEADER, DPORT, SPORT, ICMP,
28
	    TYPE, CODE, TCP, FLAGS, LENGTH, DSCP, DONT_FRAGMENT, IS_FRAGMENT,
29
	    FIRST_FRAGMENT, LAST_FRAGMENT, FRAGMENT, LABEL, OFFSET)
30

    
31

    
32
CF_GRAMMAR
33

    
34
/* Network Flow Specification */
35

    
36
flow_num_op:
37
   TRUE		{ $$ = FLOW_OP_TRUE; }
38
 | '='		{ $$ = FLOW_OP_EQ;  }
39
 | NEQ		{ $$ = FLOW_OP_NEQ; }
40
 | '<'		{ $$ = FLOW_OP_LT;  }
41
 | LEQ		{ $$ = FLOW_OP_LEQ; }
42
 | '>'		{ $$ = FLOW_OP_GT;  }
43
 | GEQ		{ $$ = FLOW_OP_GEQ; }
44
 | FALSE	{ $$ = FLOW_OP_FALSE; }
45
 ;
46

    
47
flow_logic_op:
48
   OR		{ $$ = FLOW_OP_OR; }
49
 | AND		{ $$ = FLOW_OP_AND; }
50
 ;
51

    
52
flow_num_type_:
53
   PROTO	{ $$ = FLOW_TYPE_IP_PROTOCOL; }
54
 | NEXT HEADER  { $$ = FLOW_TYPE_NEXT_HEADER; }
55
 | PORT		{ $$ = FLOW_TYPE_PORT; }
56
 | DPORT	{ $$ = FLOW_TYPE_DST_PORT; }
57
 | SPORT	{ $$ = FLOW_TYPE_SRC_PORT; }
58
 | ICMP TYPE	{ $$ = FLOW_TYPE_ICMP_TYPE; }
59
 | ICMP CODE	{ $$ = FLOW_TYPE_ICMP_CODE; }
60
 | LENGTH	{ $$ = FLOW_TYPE_PACKET_LENGTH; }
61
 | DSCP		{ $$ = FLOW_TYPE_DSCP; }
62
 ;
63

    
64
flow_num_type: flow_num_type_{ flow_builder_set_type(this_flow, $1); };
65
flow_flag_type: TCP FLAGS    { flow_builder_set_type(this_flow, FLOW_TYPE_TCP_FLAGS); };
66
flow_frag_type: FRAGMENT     { flow_builder_set_type(this_flow, FLOW_TYPE_FRAGMENT); };
67
flow_label_type: LABEL       { flow_builder_set_type(this_flow, FLOW_TYPE_LABEL); };
68

    
69
flow_srcdst:
70
   DST		{ $$ = FLOW_TYPE_DST_PREFIX; }
71
 | SRC		{ $$ = FLOW_TYPE_SRC_PREFIX; }
72
 ;
73

    
74
flow_num_opts:
75
   flow_num_op expr {
76
     flow_check_cf_value_length(this_flow, $2);
77
     flow_builder_add_op_val(this_flow, $1, $2);
78
   }
79
 | flow_num_opts flow_logic_op flow_num_op expr {
80
     flow_check_cf_value_length(this_flow, $4);
81
     flow_builder_add_op_val(this_flow, $2 | $3, $4);
82
   }
83
 | flow_num_opt_ext
84
 | flow_num_opts OR flow_num_opt_ext
85
 ;
86

    
87
flow_num_opt_ext_expr:
88
   expr {
89
     flow_check_cf_value_length(this_flow, $1);
90
     flow_builder_add_op_val(this_flow, FLOW_OP_EQ, $1);
91
   }
92
 | expr DDOT expr {
93
     flow_check_cf_value_length(this_flow, $1);
94
     flow_check_cf_value_length(this_flow, $3);
95
     flow_builder_add_op_val(this_flow, FLOW_OP_GEQ, $1);
96
     flow_builder_add_op_val(this_flow, FLOW_OP_AND | FLOW_OP_LEQ, $3);
97
   }
98
 ;
99

    
100
flow_num_opt_ext:
101
   flow_num_opt_ext_expr
102
 | flow_num_opt_ext ',' flow_num_opt_ext_expr
103
 ;
104

    
105
flow_bmk_opts:
106
   flow_neg expr '/' expr {
107
     flow_check_cf_bmk_values(this_flow, $1, $2, $4);
108
     flow_builder_add_val_mask(this_flow, $1, $2, $4);
109
   }
110
 | flow_bmk_opts flow_logic_op flow_neg expr '/' expr {
111
     flow_check_cf_bmk_values(this_flow, $3, $4, $6);
112
     flow_builder_add_val_mask(this_flow, $2 | $3, $4, $6);
113
   }
114
 | flow_bmk_opts ',' flow_neg expr '/' expr {
115
     flow_check_cf_bmk_values(this_flow, $3, $4, $6);
116
     flow_builder_add_val_mask(this_flow, 0x40 | $3, $4, $6); /* AND */
117
   }
118
 ;
119

    
120
flow_neg:
121
   /* empty */ 	{ $$ = 0x00; }
122
 | '!'		{ $$ = 0x02; }
123
 ;
124

    
125
flow_frag_val:
126
   DONT_FRAGMENT  { $$ = 1; }
127
 | IS_FRAGMENT	  { $$ = 2; }
128
 | FIRST_FRAGMENT { $$ = 4; }
129
 | LAST_FRAGMENT  { $$ = 8; }
130
 ;
131

    
132
flow_frag_opts:
133
   flow_neg flow_frag_val {
134
     flow_builder_add_val_mask(this_flow, 0, ($1 ? 0 : $2), $2);
135
   }
136
 | flow_frag_opts flow_logic_op flow_neg flow_frag_val {
137
     flow_builder_add_val_mask(this_flow, $2, ($3 ? 0 : $4), $4);
138
   }
139
 | flow_frag_opts ',' flow_neg flow_frag_val {
140
     flow_builder_add_val_mask(this_flow, 0x40, ($3 ? 0 : $4), $4); /* AND */
141
   }
142
 ;
143

    
144
flow4_item:
145
   flow_srcdst net_ip {
146
     flow_builder_set_type(this_flow, $1);
147
     flow_builder4_add_pfx(this_flow, (net_addr_ip4 *) &($2));
148
   }
149
 | flow_num_type flow_num_opts
150
 | flow_flag_type flow_bmk_opts
151
 | flow_frag_type flow_frag_opts
152
 ;
153

    
154
flow6_item:
155
   flow_srcdst net_ip6 {
156
     flow_builder_set_type(this_flow, $1);
157
     flow_builder6_add_pfx(this_flow, (net_addr_ip6 *) &($2), 0);
158
   }
159
 | flow_srcdst net_ip6 OFFSET NUM {
160
     if ($4 > $2.pxlen)
161
       cf_error("Prefix offset is higher than prefix length");
162
     flow_builder_set_type(this_flow, $1);
163
     flow_builder6_add_pfx(this_flow, (net_addr_ip6 *) &($2), $4);
164
   }
165
 | flow_num_type flow_num_opts
166
 | flow_flag_type flow_bmk_opts
167
 | flow_frag_type flow_frag_opts
168
 | flow_label_type flow_bmk_opts
169
 ;
170

    
171
flow4_opts:
172
   /* empty */
173
 | flow4_opts flow4_item ';'
174
 ;
175

    
176
flow6_opts:
177
 /* empty */
178
 | flow6_opts flow6_item ';'
179
 ;
180

    
181
flow_builder_init:
182
{
183
  if (this_flow == NULL)
184
    this_flow = flow_builder_init(&root_pool);
185
  else
186
    flow_builder_clear(this_flow);
187
};
188

    
189
flow_builder_set_ipv4: { this_flow->ipv6 = 0; };
190
flow_builder_set_ipv6: { this_flow->ipv6 = 1; };
191

    
192
net_flow4_: FLOW4 '{' flow_builder_init flow_builder_set_ipv4 flow4_opts '}'
193
{
194
  $$ = (net_addr *) flow_builder4_finalize(this_flow, cfg_mem);
195
  flow4_validate_cf((net_addr_flow4 *) $$);
196
};
197

    
198
net_flow6_: FLOW6 '{' flow_builder_init flow_builder_set_ipv6 flow6_opts '}'
199
{
200
  $$ = (net_addr *) flow_builder6_finalize(this_flow, cfg_mem);
201
  flow6_validate_cf((net_addr_flow6 *) $$);
202
};
203

    
204
net_flow_: net_flow4_ | net_flow6_ ;
205

    
206

    
207
CF_CODE
208

    
209
CF_END