]> git.ipfire.org Git - thirdparty/bird.git/blame - conf/flowspec.Y
Minor cleanups and fixes
[thirdparty/bird.git] / conf / flowspec.Y
CommitLineData
77234bbb
OZ
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
9CF_HDR
10
11#define PARSER 1
12
13#include "nest/bird.h"
14#include "conf/conf.h"
15#include "lib/resource.h"
16#include "lib/socket.h"
17#include "sysdep/unix/timer.h"
18#include "lib/string.h"
19#include "nest/protocol.h"
20#include "nest/iface.h"
21#include "nest/route.h"
22#include "nest/cli.h"
23#include "filter/filter.h"
24#include "lib/flowspec.h"
25
26
27CF_DEFINES
28
29struct flow_builder *this_flow;
30
31
32CF_DECLS
33
34%type <i32> flow_num_op flow_srcdst flow_logic_op flow_num_type_ flow_frag_val flow_neg
35%type <net_ptr> net_flow4_ net_flow6_ net_flow_
36
37CF_KEYWORDS(FLOW4, FLOW6, DST, SRC, PROTO, NEXT, HEADER, DPORT, SPORT, ICMP,
38 TYPE, CODE, TCP, FLAGS, LENGTH, DSCP, DONT_FRAGMENT, IS_FRAGMENT,
39 FIRST_FRAGMENT, LAST_FRAGMENT, FRAGMENT, LABEL, OFFSET)
40
41
42CF_GRAMMAR
43
44/* Network Flow Specification */
45
46flow_num_op:
734e9fb8
OZ
47 TRUE { $$ = FLOW_OP_TRUE; }
48 | '=' { $$ = FLOW_OP_EQ; }
49 | NEQ { $$ = FLOW_OP_NEQ; }
50 | '<' { $$ = FLOW_OP_LT; }
51 | LEQ { $$ = FLOW_OP_LEQ; }
52 | '>' { $$ = FLOW_OP_GT; }
53 | GEQ { $$ = FLOW_OP_GEQ; }
54 | FALSE { $$ = FLOW_OP_FALSE; }
77234bbb
OZ
55 ;
56
57flow_logic_op:
734e9fb8
OZ
58 OR { $$ = FLOW_OP_OR; }
59 | AND { $$ = FLOW_OP_AND; }
77234bbb
OZ
60 ;
61
62flow_num_type_:
63 PROTO { $$ = FLOW_TYPE_IP_PROTOCOL; }
64 | NEXT HEADER { $$ = FLOW_TYPE_NEXT_HEADER; }
65 | PORT { $$ = FLOW_TYPE_PORT; }
66 | DPORT { $$ = FLOW_TYPE_DST_PORT; }
67 | SPORT { $$ = FLOW_TYPE_SRC_PORT; }
68 | ICMP TYPE { $$ = FLOW_TYPE_ICMP_TYPE; }
69 | ICMP CODE { $$ = FLOW_TYPE_ICMP_CODE; }
70 | LENGTH { $$ = FLOW_TYPE_PACKET_LENGTH; }
71 | DSCP { $$ = FLOW_TYPE_DSCP; }
72 ;
73
74flow_num_type: flow_num_type_{ flow_builder_set_type(this_flow, $1); };
75flow_flag_type: TCP FLAGS { flow_builder_set_type(this_flow, FLOW_TYPE_TCP_FLAGS); };
76flow_frag_type: FRAGMENT { flow_builder_set_type(this_flow, FLOW_TYPE_FRAGMENT); };
77flow_label_type: LABEL { flow_builder_set_type(this_flow, FLOW_TYPE_LABEL); };
78
79flow_srcdst:
80 DST { $$ = FLOW_TYPE_DST_PREFIX; }
81 | SRC { $$ = FLOW_TYPE_SRC_PREFIX; }
82 ;
83
84flow_num_opts:
85 flow_num_op expr {
86 flow_check_cf_value_length(this_flow, $2);
87 flow_builder_add_op_val(this_flow, $1, $2);
88 }
89 | flow_num_opts flow_logic_op flow_num_op expr {
90 flow_check_cf_value_length(this_flow, $4);
91 flow_builder_add_op_val(this_flow, $2 | $3, $4);
92 }
93 | flow_num_opt_ext
94 | flow_num_opts OR flow_num_opt_ext
95 ;
96
97flow_num_opt_ext_expr:
98 expr {
99 flow_check_cf_value_length(this_flow, $1);
734e9fb8 100 flow_builder_add_op_val(this_flow, FLOW_OP_EQ, $1);
77234bbb
OZ
101 }
102 | expr DDOT expr {
103 flow_check_cf_value_length(this_flow, $1);
104 flow_check_cf_value_length(this_flow, $3);
734e9fb8
OZ
105 flow_builder_add_op_val(this_flow, FLOW_OP_GEQ, $1);
106 flow_builder_add_op_val(this_flow, FLOW_OP_AND | FLOW_OP_LEQ, $3);
77234bbb
OZ
107 }
108 ;
109
110flow_num_opt_ext:
111 flow_num_opt_ext_expr
112 | flow_num_opt_ext ',' flow_num_opt_ext_expr
113 ;
114
115flow_bmk_opts:
116 flow_neg expr '/' expr {
117 flow_check_cf_bmk_values(this_flow, $1, $2, $4);
118 flow_builder_add_val_mask(this_flow, $1, $2, $4);
119 }
120 | flow_bmk_opts flow_logic_op flow_neg expr '/' expr {
121 flow_check_cf_bmk_values(this_flow, $3, $4, $6);
122 flow_builder_add_val_mask(this_flow, $2 | $3, $4, $6);
123 }
124 | flow_bmk_opts ',' flow_neg expr '/' expr {
125 flow_check_cf_bmk_values(this_flow, $3, $4, $6);
126 flow_builder_add_val_mask(this_flow, 0x40 | $3, $4, $6); /* AND */
127 }
128 ;
129
130flow_neg:
131 /* empty */ { $$ = 0x00; }
132 | '!' { $$ = 0x02; }
133 ;
134
135flow_frag_val:
136 DONT_FRAGMENT { $$ = 1; }
137 | IS_FRAGMENT { $$ = 2; }
138 | FIRST_FRAGMENT { $$ = 4; }
139 | LAST_FRAGMENT { $$ = 8; }
140 ;
141
142flow_frag_opts:
143 flow_neg flow_frag_val {
144 flow_builder_add_val_mask(this_flow, 0, ($1 ? 0 : $2), $2);
145 }
146 | flow_frag_opts flow_logic_op flow_neg flow_frag_val {
147 flow_builder_add_val_mask(this_flow, $2, ($3 ? 0 : $4), $4);
148 }
149 | flow_frag_opts ',' flow_neg flow_frag_val {
150 flow_builder_add_val_mask(this_flow, 0x40, ($3 ? 0 : $4), $4); /* AND */
151 }
152 ;
153
154flow4_item:
155 flow_srcdst net_ip {
156 flow_builder_set_type(this_flow, $1);
157 flow_builder4_add_pfx(this_flow, (net_addr_ip4 *) &($2));
158 }
159 | flow_num_type flow_num_opts
160 | flow_flag_type flow_bmk_opts
161 | flow_frag_type flow_frag_opts
162 ;
163
164flow6_item:
165 flow_srcdst net_ip6 {
166 flow_builder_set_type(this_flow, $1);
167 flow_builder6_add_pfx(this_flow, (net_addr_ip6 *) &($2), 0);
168 }
169 | flow_srcdst net_ip6 OFFSET NUM {
170 if ($4 > $2.pxlen)
171 cf_error("Prefix offset is higher than prefix length");
172 flow_builder_set_type(this_flow, $1);
173 flow_builder6_add_pfx(this_flow, (net_addr_ip6 *) &($2), $4);
174 }
175 | flow_num_type flow_num_opts
176 | flow_flag_type flow_bmk_opts
177 | flow_frag_type flow_frag_opts
178 | flow_label_type flow_bmk_opts
179 ;
180
181flow4_opts:
182 /* empty */
183 | flow4_opts flow4_item ';'
184 ;
185
186flow6_opts:
187 /* empty */
188 | flow6_opts flow6_item ';'
189 ;
190
191flow_builder_init:
192{
193 if (this_flow == NULL)
194 this_flow = flow_builder_init(&root_pool);
195 else
196 flow_builder_clear(this_flow);
197};
198
199flow_builder_set_ipv4: { this_flow->ipv6 = 0; };
200flow_builder_set_ipv6: { this_flow->ipv6 = 1; };
201
202net_flow4_: FLOW4 '{' flow_builder_init flow_builder_set_ipv4 flow4_opts '}'
203{
204 $$ = (net_addr *) flow_builder4_finalize(this_flow, cfg_mem);
205 flow4_validate_cf((net_addr_flow4 *) $$);
206};
207
208net_flow6_: FLOW6 '{' flow_builder_init flow_builder_set_ipv6 flow6_opts '}'
209{
210 $$ = (net_addr *) flow_builder6_finalize(this_flow, cfg_mem);
211 flow6_validate_cf((net_addr_flow6 *) $$);
212};
213
214net_flow_: net_flow4_ | net_flow6_ ;
215
216
217CF_CODE
218
219CF_END