Annotation of embedaddon/bird2/conf/flowspec.Y, revision 1.1.1.1
1.1 misho 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
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>