GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
#include <stdlib.h> |
||
2 |
#include <string.h> |
||
3 |
#define YYBYACC 1 |
||
4 |
#define YYMAJOR 1 |
||
5 |
#define YYMINOR 9 |
||
6 |
#define YYLEX yylex() |
||
7 |
#define YYEMPTY -1 |
||
8 |
#define yyclearin (yychar=(YYEMPTY)) |
||
9 |
#define yyerrok (yyerrflag=0) |
||
10 |
#define YYRECOVERING() (yyerrflag!=0) |
||
11 |
#define YYPREFIX "yy" |
||
12 |
#line 25 "parse.y" |
||
13 |
#include <sys/types.h> |
||
14 |
#include <sys/socket.h> |
||
15 |
#include <sys/stat.h> |
||
16 |
#include <sys/un.h> |
||
17 |
#include <netinet/in.h> |
||
18 |
#include <netinet/ip_ipsp.h> |
||
19 |
#include <arpa/inet.h> |
||
20 |
#include <netmpls/mpls.h> |
||
21 |
|||
22 |
#include <ctype.h> |
||
23 |
#include <err.h> |
||
24 |
#include <unistd.h> |
||
25 |
#include <errno.h> |
||
26 |
#include <limits.h> |
||
27 |
#include <stdarg.h> |
||
28 |
#include <stdio.h> |
||
29 |
#include <string.h> |
||
30 |
#include <syslog.h> |
||
31 |
|||
32 |
#include "bgpd.h" |
||
33 |
#include "mrt.h" |
||
34 |
#include "session.h" |
||
35 |
#include "rde.h" |
||
36 |
#include "log.h" |
||
37 |
|||
38 |
TAILQ_HEAD(files, file) files = TAILQ_HEAD_INITIALIZER(files); |
||
39 |
static struct file { |
||
40 |
TAILQ_ENTRY(file) entry; |
||
41 |
FILE *stream; |
||
42 |
char *name; |
||
43 |
int lineno; |
||
44 |
int errors; |
||
45 |
} *file, *topfile; |
||
46 |
struct file *pushfile(const char *, int); |
||
47 |
int popfile(void); |
||
48 |
int check_file_secrecy(int, const char *); |
||
49 |
int yyparse(void); |
||
50 |
int yylex(void); |
||
51 |
int yyerror(const char *, ...) |
||
52 |
__attribute__((__format__ (printf, 1, 2))) |
||
53 |
__attribute__((__nonnull__ (1))); |
||
54 |
int kw_cmp(const void *, const void *); |
||
55 |
int lookup(char *); |
||
56 |
int lgetc(int); |
||
57 |
int lungetc(int); |
||
58 |
int findeol(void); |
||
59 |
|||
60 |
TAILQ_HEAD(symhead, sym) symhead = TAILQ_HEAD_INITIALIZER(symhead); |
||
61 |
struct sym { |
||
62 |
TAILQ_ENTRY(sym) entry; |
||
63 |
int used; |
||
64 |
int persist; |
||
65 |
char *nam; |
||
66 |
char *val; |
||
67 |
}; |
||
68 |
int symset(const char *, const char *, int); |
||
69 |
char *symget(const char *); |
||
70 |
|||
71 |
static struct bgpd_config *conf; |
||
72 |
static struct network_head *netconf; |
||
73 |
static struct peer *peer_l, *peer_l_old; |
||
74 |
static struct peer *curpeer; |
||
75 |
static struct peer *curgroup; |
||
76 |
static struct rdomain *currdom; |
||
77 |
static struct filter_head *filter_l; |
||
78 |
static struct filter_head *peerfilter_l; |
||
79 |
static struct filter_head *groupfilter_l; |
||
80 |
static struct filter_rule *curpeer_filter[2]; |
||
81 |
static struct filter_rule *curgroup_filter[2]; |
||
82 |
static u_int32_t id; |
||
83 |
|||
84 |
struct filter_rib_l { |
||
85 |
struct filter_rib_l *next; |
||
86 |
char name[PEER_DESCR_LEN]; |
||
87 |
}; |
||
88 |
|||
89 |
struct filter_peers_l { |
||
90 |
struct filter_peers_l *next; |
||
91 |
struct filter_peers p; |
||
92 |
}; |
||
93 |
|||
94 |
struct filter_prefix_l { |
||
95 |
struct filter_prefix_l *next; |
||
96 |
struct filter_prefix p; |
||
97 |
}; |
||
98 |
|||
99 |
struct filter_prefixlen { |
||
100 |
enum comp_ops op; |
||
101 |
int len_min; |
||
102 |
int len_max; |
||
103 |
}; |
||
104 |
|||
105 |
struct filter_as_l { |
||
106 |
struct filter_as_l *next; |
||
107 |
struct filter_as a; |
||
108 |
}; |
||
109 |
|||
110 |
struct filter_match_l { |
||
111 |
struct filter_match m; |
||
112 |
struct filter_prefix_l *prefix_l; |
||
113 |
struct filter_as_l *as_l; |
||
114 |
} fmopts; |
||
115 |
|||
116 |
struct peer *alloc_peer(void); |
||
117 |
struct peer *new_peer(void); |
||
118 |
struct peer *new_group(void); |
||
119 |
int add_mrtconfig(enum mrt_type, char *, int, struct peer *, |
||
120 |
char *); |
||
121 |
int add_rib(char *, u_int, u_int16_t); |
||
122 |
struct rde_rib *find_rib(char *); |
||
123 |
int get_id(struct peer *); |
||
124 |
int merge_prefixspec(struct filter_prefix_l *, |
||
125 |
struct filter_prefixlen *); |
||
126 |
int expand_rule(struct filter_rule *, struct filter_rib_l *, |
||
127 |
struct filter_peers_l *, struct filter_match_l *, |
||
128 |
struct filter_set_head *); |
||
129 |
int str2key(char *, char *, size_t); |
||
130 |
int neighbor_consistent(struct peer *); |
||
131 |
int merge_filterset(struct filter_set_head *, struct filter_set *); |
||
132 |
void copy_filterset(struct filter_set_head *, |
||
133 |
struct filter_set_head *); |
||
134 |
void merge_filter_lists(struct filter_head *, struct filter_head *); |
||
135 |
struct filter_rule *get_rule(enum action_types); |
||
136 |
|||
137 |
int getcommunity(char *); |
||
138 |
int parsecommunity(struct filter_community *, char *); |
||
139 |
int64_t getlargecommunity(char *); |
||
140 |
int parselargecommunity(struct filter_largecommunity *, char *); |
||
141 |
int parsesubtype(char *, int *, int *); |
||
142 |
int parseextvalue(char *, u_int32_t *); |
||
143 |
int parseextcommunity(struct filter_extcommunity *, char *, |
||
144 |
char *); |
||
145 |
|||
146 |
typedef struct { |
||
147 |
union { |
||
148 |
int64_t number; |
||
149 |
char *string; |
||
150 |
struct bgpd_addr addr; |
||
151 |
u_int8_t u8; |
||
152 |
struct filter_rib_l *filter_rib; |
||
153 |
struct filter_peers_l *filter_peers; |
||
154 |
struct filter_match_l filter_match; |
||
155 |
struct filter_prefix_l *filter_prefix; |
||
156 |
struct filter_as_l *filter_as; |
||
157 |
struct filter_set *filter_set; |
||
158 |
struct filter_set_head *filter_set_head; |
||
159 |
struct { |
||
160 |
struct bgpd_addr prefix; |
||
161 |
u_int8_t len; |
||
162 |
} prefix; |
||
163 |
struct filter_prefixlen prefixlen; |
||
164 |
struct { |
||
165 |
u_int8_t enc_alg; |
||
166 |
char enc_key[IPSEC_ENC_KEY_LEN]; |
||
167 |
u_int8_t enc_key_len; |
||
168 |
} encspec; |
||
169 |
} v; |
||
170 |
int lineno; |
||
171 |
} YYSTYPE; |
||
172 |
|||
173 |
#line 174 "parse.c" |
||
174 |
#define AS 257 |
||
175 |
#define ROUTERID 258 |
||
176 |
#define HOLDTIME 259 |
||
177 |
#define YMIN 260 |
||
178 |
#define LISTEN 261 |
||
179 |
#define ON 262 |
||
180 |
#define FIBUPDATE 263 |
||
181 |
#define FIBPRIORITY 264 |
||
182 |
#define RTABLE 265 |
||
183 |
#define RDOMAIN 266 |
||
184 |
#define RD 267 |
||
185 |
#define EXPORTTRGT 268 |
||
186 |
#define IMPORTTRGT 269 |
||
187 |
#define RDE 270 |
||
188 |
#define RIB 271 |
||
189 |
#define EVALUATE 272 |
||
190 |
#define IGNORE 273 |
||
191 |
#define COMPARE 274 |
||
192 |
#define GROUP 275 |
||
193 |
#define NEIGHBOR 276 |
||
194 |
#define NETWORK 277 |
||
195 |
#define EBGP 278 |
||
196 |
#define IBGP 279 |
||
197 |
#define LOCALAS 280 |
||
198 |
#define REMOTEAS 281 |
||
199 |
#define DESCR 282 |
||
200 |
#define LOCALADDR 283 |
||
201 |
#define MULTIHOP 284 |
||
202 |
#define PASSIVE 285 |
||
203 |
#define MAXPREFIX 286 |
||
204 |
#define RESTART 287 |
||
205 |
#define ANNOUNCE 288 |
||
206 |
#define CAPABILITIES 289 |
||
207 |
#define REFRESH 290 |
||
208 |
#define AS4BYTE 291 |
||
209 |
#define CONNECTRETRY 292 |
||
210 |
#define DEMOTE 293 |
||
211 |
#define ENFORCE 294 |
||
212 |
#define NEIGHBORAS 295 |
||
213 |
#define REFLECTOR 296 |
||
214 |
#define DEPEND 297 |
||
215 |
#define DOWN 298 |
||
216 |
#define DUMP 299 |
||
217 |
#define IN 300 |
||
218 |
#define OUT 301 |
||
219 |
#define SOCKET 302 |
||
220 |
#define RESTRICTED 303 |
||
221 |
#define LOG 304 |
||
222 |
#define ROUTECOLL 305 |
||
223 |
#define TRANSPARENT 306 |
||
224 |
#define TCP 307 |
||
225 |
#define MD5SIG 308 |
||
226 |
#define PASSWORD 309 |
||
227 |
#define KEY 310 |
||
228 |
#define TTLSECURITY 311 |
||
229 |
#define ALLOW 312 |
||
230 |
#define DENY 313 |
||
231 |
#define MATCH 314 |
||
232 |
#define QUICK 315 |
||
233 |
#define FROM 316 |
||
234 |
#define TO 317 |
||
235 |
#define ANY 318 |
||
236 |
#define CONNECTED 319 |
||
237 |
#define STATIC 320 |
||
238 |
#define COMMUNITY 321 |
||
239 |
#define EXTCOMMUNITY 322 |
||
240 |
#define LARGECOMMUNITY 323 |
||
241 |
#define PREFIX 324 |
||
242 |
#define PREFIXLEN 325 |
||
243 |
#define SOURCEAS 326 |
||
244 |
#define TRANSITAS 327 |
||
245 |
#define PEERAS 328 |
||
246 |
#define DELETE 329 |
||
247 |
#define MAXASLEN 330 |
||
248 |
#define MAXASSEQ 331 |
||
249 |
#define SET 332 |
||
250 |
#define LOCALPREF 333 |
||
251 |
✓✗✗✓ |
168 |
#define MED 334 |
252 |
#define METRIC 335 |
||
253 |
#define NEXTHOP 336 |
||
254 |
#define REJECT 337 |
||
255 |
#define BLACKHOLE 338 |
||
256 |
#define NOMODIFY 339 |
||
257 |
#define SELF 340 |
||
258 |
#define PREPEND_SELF 341 |
||
259 |
#define PREPEND_PEER 342 |
||
260 |
#define PFTABLE 343 |
||
261 |
#define WEIGHT 344 |
||
262 |
#define RTLABEL 345 |
||
263 |
#define ORIGIN 346 |
||
264 |
#define ERROR 347 |
||
265 |
#define INCLUDE 348 |
||
266 |
#define IPSEC 349 |
||
267 |
#define ESP 350 |
||
268 |
#define AH 351 |
||
269 |
#define SPI 352 |
||
270 |
#define IKE 353 |
||
271 |
#define IPV4 354 |
||
272 |
#define IPV6 355 |
||
273 |
#define QUALIFY 356 |
||
274 |
#define VIA 357 |
||
275 |
#define NE 358 |
||
276 |
#define LE 359 |
||
277 |
#define GE 360 |
||
278 |
#define XRANGE 361 |
||
279 |
#define LONGER 362 |
||
280 |
#define STRING 363 |
||
281 |
#define NUMBER 364 |
||
282 |
#define YYERRCODE 256 |
||
283 |
const short yylhs[] = |
||
284 |
{ -1, |
||
285 |
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||
286 |
1, 2, 2, 3, 3, 13, 13, 10, 51, 49, |
||
287 |
50, 50, 50, 50, 50, 50, 50, 50, 50, 50, |
||
288 |
50, 50, 50, 50, 50, 50, 50, 50, 50, 50, |
||
289 |
50, 50, 50, 50, 50, 50, 57, 56, 56, 56, |
||
290 |
✗✓ | 32 |
11, 11, 12, 12, 14, 15, 15, 16, 16, 58, |
291 |
58, 59, 4, 4, 61, 52, 60, 60, 62, 63, |
||
292 |
63, 63, 63, 63, 63, 63, 64, 66, 53, 68, |
||
293 |
54, 67, 67, 69, 69, 69, 65, 65, 71, 71, |
||
294 |
72, 70, 70, 70, 70, 70, 70, 70, 70, 70, |
||
295 |
32 |
70, 70, 70, 70, 70, 70, 70, 70, 70, 70, |
|
296 |
70, 70, 70, 70, 70, 70, 70, 70, 70, 70, |
||
297 |
32 |
70, 70, 70, 70, 70, 70, 70, 7, 7, 6, |
|
298 |
6, 9, 9, 5, 5, 48, 48, 55, 17, 17, |
||
299 |
17, 18, 18, 19, 19, 21, 21, 21, 22, 22, |
||
300 |
23, 26, 26, 25, 25, 24, 24, 24, 24, 24, |
||
301 |
24, 42, 42, 42, 42, 43, 43, 43, 41, 41, |
||
302 |
40, 32, 32, 34, 34, 33, 33, 35, 35, 35, |
||
303 |
31, 31, 30, 30, 30, 30, 29, 74, 29, 27, |
||
304 |
27, 28, 28, 28, 28, 28, 28, 28, 28, 28, |
||
305 |
36, 36, 36, 36, 47, 47, 47, 47, 38, 38, |
||
306 |
38, 39, 39, 20, 20, 37, 37, 37, 37, 37, |
||
307 |
37, 37, 37, 37, 37, 37, 37, 37, 37, 37, |
||
308 |
37, 37, 37, 37, 37, 37, 37, 37, 37, 37, |
||
309 |
8, 73, 73, 44, 44, 44, 44, 44, 44, 45, |
||
310 |
45, 46, 46, |
||
311 |
}; |
||
312 |
const short yylen[] = |
||
313 |
{ 2, |
||
314 |
0, 2, 3, 3, 3, 3, 3, 3, 3, 3, |
||
315 |
1, 1, 1, 1, 1, 2, 1, 1, 3, 2, |
||
316 |
2, 3, 2, 2, 3, 3, 2, 2, 2, 3, |
||
317 |
5, 5, 7, 2, 2, 1, 4, 6, 1, 3, |
||
318 |
3, 4, 4, 2, 2, 3, 5, 3, 5, 4, |
||
319 |
1, 1, 1, 0, 1, 3, 3, 1, 1, 2, |
||
320 |
0, 2, 0, 1, 0, 8, 2, 1, 2, 2, |
||
321 |
3, 3, 2, 2, 1, 3, 0, 0, 5, 0, |
||
322 |
8, 2, 1, 2, 2, 2, 4, 0, 2, 1, |
||
323 |
2, 2, 2, 3, 2, 2, 2, 1, 1, 2, |
||
324 |
2, 2, 3, 3, 3, 3, 3, 3, 2, 2, |
||
325 |
3, 3, 3, 4, 4, 3, 8, 2, 2, 7, |
||
326 |
1, 1, 2, 3, 2, 2, 2, 0, 2, 1, |
||
327 |
52 |
1, 1, 1, 1, 1, 0, 2, 7, 1, 1, |
|
328 |
1, 0, 1, 1, 1, 0, 2, 4, 1, 3, |
||
329 |
52 |
1, 1, 3, 1, 3, 1, 1, 2, 2, 1, |
|
330 |
1, 2, 2, 2, 4, 1, 3, 4, 1, 3, |
||
331 |
2, 1, 3, 1, 3, 2, 4, 1, 3, 4, |
||
332 |
1, 3, 1, 1, 2, 3, 0, 0, 2, 1, |
||
333 |
2, 1, 1, 2, 2, 2, 2, 3, 2, 2, |
||
334 |
0, 1, 3, 4, 1, 1, 1, 1, 0, 2, |
||
335 |
7, 3, 1, 0, 1, 2, 3, 3, 2, 3, |
||
336 |
3, 2, 3, 3, 2, 3, 3, 2, 2, 2, |
||
337 |
2, 2, 2, 2, 2, 2, 3, 3, 4, 2, |
||
338 |
1, 1, 0, 1, 1, 1, 1, 1, 1, 1, |
||
339 |
1, 1, 1, |
||
340 |
}; |
||
341 |
✓✗ | 4 |
const short yydefred[] = |
342 |
{ 1, |
||
343 |
✗✓ | 4 |
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
344 |
0, 0, 0, 0, 0, 0, 0, 0, 0, 139, |
||
345 |
140, 141, 0, 0, 0, 2, 0, 0, 0, 0, |
||
346 |
0, 0, 0, 0, 36, 39, 0, 10, 12, 11, |
||
347 |
13, 0, 55, 23, 0, 24, 0, 18, 28, 27, |
||
348 |
44, 0, 0, 0, 0, 17, 0, 130, 131, 0, |
||
349 |
0, 0, 0, 45, 0, 0, 0, 35, 29, 34, |
||
350 |
0, 20, 0, 143, 0, 3, 4, 5, 6, 7, |
||
351 |
4 |
8, 9, 0, 22, 25, 26, 0, 0, 0, 0, |
|
352 |
40, 41, 16, 0, 0, 0, 133, 132, 0, 0, |
||
353 |
4 |
0, 48, 0, 51, 52, 0, 0, 53, 46, 0, |
|
354 |
0, 0, 0, 0, 58, 59, 78, 60, 0, 0, |
||
355 |
0, 42, 0, 56, 57, 0, 50, 0, 0, 0, |
||
356 |
8 |
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
|
357 |
✓✗ | 8 |
210, 0, 0, 64, 37, 0, 43, 151, 0, 147, |
358 |
8 |
144, 145, 0, 0, 65, 0, 31, 80, 49, 215, |
|
359 |
✓✓ | 96 |
0, 0, 0, 216, 0, 0, 219, 0, 0, 222, |
360 |
✗✓ | 40 |
0, 0, 230, 229, 231, 232, 228, 233, 234, 235, |
361 |
225, 0, 0, 236, 240, 0, 0, 0, 47, 0, |
||
362 |
149, 0, 0, 160, 161, 156, 0, 157, 152, 0, |
||
363 |
0, 79, 0, 0, 0, 237, 0, 238, 217, 218, |
||
364 |
220, 221, 223, 224, 226, 227, 0, 38, 148, 242, |
||
365 |
0, 158, 159, 154, 0, 0, 0, 0, 0, 0, |
||
366 |
✗✓ | 8 |
0, 0, 0, 0, 75, 0, 68, 0, 33, 0, |
367 |
0, 0, 0, 0, 0, 0, 0, 98, 0, 0, |
||
368 |
8 |
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
|
369 |
8 |
0, 0, 0, 121, 0, 83, 0, 239, 213, 0, |
|
370 |
✗✓ | 8 |
150, 153, 0, 138, 205, 0, 0, 0, 0, 206, |
371 |
207, 208, 0, 0, 0, 0, 0, 0, 0, 190, |
||
372 |
193, 172, 192, 0, 0, 0, 90, 74, 70, 0, |
||
373 |
0, 0, 0, 66, 67, 0, 69, 86, 0, 102, |
||
374 |
101, 0, 92, 0, 96, 97, 0, 0, 0, 0, |
||
375 |
0, 109, 110, 0, 125, 0, 0, 123, 0, 100, |
||
376 |
0, 127, 126, 0, 118, 119, 0, 134, 135, 0, |
||
377 |
85, 81, 82, 84, 0, 0, 155, 196, 0, 197, |
||
378 |
0, 0, 164, 194, 195, 200, 199, 0, 202, 162, |
||
379 |
163, 174, 0, 191, 184, 251, 14, 250, 0, 15, |
||
380 |
0, 176, 0, 91, 87, 89, 71, 72, 76, 62, |
||
381 |
103, 94, 0, 113, 107, 105, 106, 108, 104, 112, |
||
382 |
111, 124, 0, 0, 0, 116, 0, 211, 212, 198, |
||
383 |
0, 169, 0, 0, 171, 245, 246, 248, 0, 244, |
||
384 |
247, 249, 0, 173, 0, 0, 181, 0, 0, 253, |
||
385 |
252, 0, 185, 129, 0, 0, 0, 0, 0, 0, |
||
386 |
165, 0, 203, 175, 0, 0, 177, 186, 0, 0, |
||
387 |
0, 170, 204, 0, 182, 0, 0, 168, 180, 120, |
||
388 |
0, 0, 117, 137, |
||
389 |
12 |
}; |
|
390 |
✓✗ | 12 |
const short yydgoto[] = |
391 |
{ 1, |
||
392 |
370, 42, 371, 145, 340, 62, 384, 185, 100, 49, |
||
393 |
12 |
107, 109, 57, 198, 352, 117, 27, 75, 153, 161, |
|
394 |
113, 190, 150, 199, 225, 200, 289, 290, 226, 417, |
||
395 |
12 |
418, 291, 292, 363, 419, 360, 269, 102, 270, 402, |
|
396 |
403, 293, 404, 413, 373, 422, 294, 453, 28, 29, |
||
397 |
30, 31, 263, 33, 34, 235, 264, 88, 307, 236, |
||
398 |
203, 237, 238, 37, 202, 154, 265, 205, 266, 267, |
||
399 |
296, 297, 346, 227, |
||
400 |
✗✓ | 4 |
}; |
401 |
const short yysindex[] = |
||
402 |
{ 0, |
||
403 |
144, 59, -251, -290, -229, -182, -274, -271, -268, -227, |
||
404 |
4 |
-237, -236, -264, -225, -235, -234, -212, -274, -274, 0, |
|
405 |
0, 0, -192, -210, 98, 0, -146, 157, 169, 171, |
||
406 |
4 |
176, 184, 186, 202, 0, 0, -50, 0, 0, 0, |
|
407 |
0, -136, 0, 0, -129, 0, -290, 0, 0, 0, |
||
408 |
0, 208, -127, -36, -111, 0, -3, 0, 0, 193, |
||
409 |
194, -163, -85, 0, -112, -217, -51, 0, 0, 0, |
||
410 |
-101, 0, -236, 0, -17, 0, 0, 0, 0, 0, |
||
411 |
0, 0, -180, 0, 0, 0, 208, 132, -238, -92, |
||
412 |
0, 0, 0, 149, -91, -90, 0, 0, -81, -85, |
||
413 |
195, 0, -80, 0, 0, -89, -76, 0, 0, -75, |
||
414 |
-74, -97, -126, 193, 0, 0, 0, 0, 208, -84, |
||
415 |
4, 0, 208, 0, 0, -85, 0, -38, -38, -38, |
||
416 |
-39, -34, -33, -94, -69, -66, -73, -30, -67, -236, |
||
417 |
0, 188, -64, 0, 0, -89, 0, 0, -62, 0, |
||
418 |
0, 0, -86, 197, 0, 31, 0, 0, 0, 0, |
||
419 |
-54, -47, -28, 0, -31, -27, 0, -21, -20, 0, |
||
420 |
-13, -12, 0, 0, 0, 0, 0, 0, 0, 0, |
||
421 |
0, -11, 11, 0, 0, -74, 208, -89, 0, -6, |
||
422 |
0, -251, 1, 0, 0, 0, -232, 0, 0, 0, |
||
423 |
208, 0, 605, -274, 610, 0, 17, 0, 0, 0, |
||
424 |
0, 0, 0, 0, 0, 0, 675, 0, 0, 0, |
||
425 |
-62, 0, 0, 0, -2, -85, 227, 642, -274, 22, |
||
426 |
23, 24, -236, 115, 0, -68, 0, 371, 0, 371, |
||
427 |
-228, 25, -251, -251, -236, -290, 19, 0, 27, -70, |
||
428 |
29, -203, -290, 122, 32, 34, 43, -274, 85, -274, |
||
429 |
195, -153, 371, 0, 470, 0, 371, 0, 0, 58, |
||
430 |
0, 0, -232, 0, 0, 48, 50, 52, -103, 0, |
||
431 |
0, 0, 40, 53, -243, -240, -240, -154, 227, 0, |
||
432 |
0, 0, 0, -58, 371, 502, 0, 0, 0, 55, |
||
433 |
57, -74, 60, 0, 0, 208, 0, 0, 61, 0, |
||
434 |
0, -136, 0, -74, 0, 0, 107, -274, -274, -274, |
||
435 |
-274, 0, 0, 64, 0, -274, -274, 0, 66, 0, |
||
436 |
-98, 0, 0, -102, 0, 0, 293, 0, 0, -206, |
||
437 |
0, 0, 0, 0, 297, 675, 0, 0, 67, 0, |
||
438 |
-99, -240, 0, 0, 0, 0, 0, 10, 0, 0, |
||
439 |
0, 0, 7, 0, 0, 0, 0, 0, -56, 0, |
||
440 |
-29, 0, -148, 0, 0, 0, 0, 0, 0, 0, |
||
441 |
0, 0, 68, 0, 0, 0, 0, 0, 0, 0, |
||
442 |
0, 0, -236, -236, 208, 0, 72, 0, 0, 0, |
||
443 |
-140, 0, 387, 308, 0, 0, 0, 0, -29, 0, |
||
444 |
0, 0, 70, 0, -154, 77, 0, 387, 312, 0, |
||
445 |
0, -148, 0, 0, -74, -74, 675, 74, 20, -140, |
||
446 |
0, 78, 0, 0, 30, 77, 0, 0, 58, 84, |
||
447 |
-99, 0, 0, -56, 0, 326, 89, 0, 0, 0, |
||
448 |
90, 91, 0, 0,}; |
||
449 |
const short yyrindex[] = |
||
450 |
{ 0, |
||
451 |
179, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||
452 |
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||
453 |
0, 0, 0, 0, 0, 0, -208, 0, 0, 0, |
||
454 |
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||
455 |
0, 449, 0, 0, 0, 0, 0, 0, 0, 0, |
||
456 |
0, 341, 0, 0, 0, 0, 341, 0, 0, 0, |
||
457 |
0, 0, 458, 0, 0, 0, 462, 0, 0, 0, |
||
458 |
0, 0, 0, 0, -106, 0, 0, 0, 0, 0, |
||
459 |
0, 0, 0, 0, 0, 0, 303, 0, 463, 0, |
||
460 |
0, 0, 0, 0, 0, 0, 0, 0, 0, 458, |
||
461 |
341, 0, 0, 0, 0, 464, 0, 0, 0, 0, |
||
462 |
478, 0, 0, 18, 0, 0, 0, 0, 689, 0, |
||
463 |
0, 0, 556, 0, 0, 458, 0, 126, 126, 126, |
||
464 |
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||
465 |
0, 0, 0, 0, 0, 464, 0, 0, 0, 0, |
||
466 |
0, 0, 0, 480, 0, 485, 0, 0, 0, 0, |
||
467 |
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||
468 |
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||
469 |
0, 0, 0, 0, 0, 178, 691, 464, 0, 133, |
||
470 |
0, 0, 0, 0, 0, 0, 0, 0, 0, 139, |
||
471 |
696, 0, 0, 0, 179, 0, 0, 0, 0, 0, |
||
472 |
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||
473 |
0, 0, 0, 0, -197, 458, 0, 0, 0, 0, |
||
474 |
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||
475 |
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||
476 |
0, 0, 487, 0, 488, 0, 0, 0, 0, 0, |
||
477 |
341, 0, 0, 0, 179, 0, 0, 0, 0, 379, |
||
478 |
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||
479 |
0, 0, 0, 0, 0, 155, 155, 0, -8, 0, |
||
480 |
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||
481 |
0, 492, 0, 0, 0, 400, 0, 0, 0, 0, |
||
482 |
0, 493, 0, 495, 0, 0, 496, 0, 0, 0, |
||
483 |
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||
484 |
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||
485 |
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||
486 |
0, 35, 0, 0, 0, 0, 0, 0, 0, 0, |
||
487 |
0, 0, -151, 0, 0, 0, 0, 0, 0, 0, |
||
488 |
-9, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||
489 |
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||
490 |
0, 0, 0, 0, 691, 0, 0, 0, 0, 0, |
||
491 |
0, 0, -96, 0, 0, 0, 0, 0, 0, 0, |
||
492 |
0, 0, 0, 0, 0, 0, 0, 15, 0, 0, |
||
493 |
0, 0, 0, 0, 498, 505, 0, 0, -133, 0, |
||
494 |
0, 0, 0, 0, 81, 0, 0, 0, 379, 0, |
||
495 |
401, 0, 0, 402, 0, 0, 0, 0, 0, 0, |
||
496 |
522, 0, 0, 0,}; |
||
497 |
const short yygindex[] = |
||
498 |
{ 0, |
||
499 |
14, -139, -315, -87, 0, 283, 0, 0, 0, 21, |
||
500 |
203, 0, -65, 51, 41, 0, 0, 0, 0, 104, |
||
501 |
0, 0, -88, -156, 0, 0, 0, 245, 0, -273, |
||
502 |
119, 0, -265, 0, 100, -200, -83, -78, 118, -260, |
||
503 |
141, 0, 105, 0, 0, 138, 0, 0, 0, 0, |
||
504 |
0, 0, 551, 0, 0, 555, 559, -57, -152, 0, |
||
505 |
0, 325, 0, 0, 0, 0, 0, 0, 299, -178, |
||
506 |
0, 269, -176, 0, |
||
507 |
}; |
||
508 |
#define YYTABLESIZE 1045 |
||
509 |
const short yytable[] = |
||
510 |
{ 94, |
||
511 |
183, 189, 368, 165, 368, 166, 87, 111, 168, 171, |
||
512 |
169, 172, 182, 221, 183, 421, 41, 141, 353, 351, |
||
513 |
372, 127, 362, 401, 192, 149, 120, 55, 166, 118, |
||
514 |
45, 309, 356, 53, 183, 65, 197, 220, 69, 70, |
||
515 |
224, 220, 193, 142, 201, 194, 195, 159, 273, 295, |
||
516 |
220, 183, 222, 63, 44, 84, 304, 423, 189, 243, |
||
517 |
191, 155, 142, 220, 369, 158, 416, 87, 38, 411, |
||
518 |
410, 412, 43, 220, 186, 243, 326, 243, 201, 47, |
||
519 |
243, 243, 104, 105, 358, 196, 361, 308, 48, 58, |
||
520 |
59, 327, 50, 104, 105, 51, 54, 86, 60, 61, |
||
521 |
218, 220, 275, 312, 313, 243, 438, 142, 142, 121, |
||
522 |
341, 39, 40, 183, 344, 183, 347, 295, 219, 43, |
||
523 |
243, 359, 272, 116, 48, 55, 56, 66, 67, 217, |
||
524 |
43, 414, 271, 115, 46, 310, 52, 368, 64, 178, |
||
525 |
55, 243, 374, 228, 441, 106, 396, 274, 187, 434, |
||
526 |
68, 405, 72, 26, 444, 97, 98, 201, 73, 201, |
||
527 |
91, 92, 445, 71, 201, 243, 76, 302, 74, 442, |
||
528 |
192, 280, 281, 282, 243, 243, 243, 336, 77, 314, |
||
529 |
78, 99, 114, 61, 177, 79, 415, 241, 193, 151, |
||
530 |
152, 194, 195, 80, 229, 81, 338, 339, 230, 231, |
||
531 |
232, 104, 105, 337, 87, 41, 393, 394, 13, 146, |
||
532 |
146, 82, 345, 233, 367, 40, 318, 87, 319, 320, |
||
533 |
321, 241, 60, 61, 239, 83, 430, 40, 234, 243, |
||
534 |
243, 196, 162, 163, 85, 89, 365, 90, 365, 95, |
||
535 |
96, 436, 173, 174, 175, 176, 101, 183, 380, 298, |
||
536 |
103, 108, 430, 112, 119, 110, 41, 41, 436, 60, |
||
537 |
61, 188, 399, 60, 61, 148, 243, 243, 43, 322, |
||
538 |
122, 123, 124, 125, 144, 157, 43, 201, 333, 156, |
||
539 |
335, 126, 143, 58, 59, 183, 146, 147, 93, 180, |
||
540 |
160, 201, 323, 204, 178, 184, 315, 179, 188, 366, |
||
541 |
148, 366, 241, 328, 367, 40, 367, 40, 206, 243, |
||
542 |
187, 183, 183, 183, 183, 207, 183, 183, 183, 201, |
||
543 |
183, 183, 183, 189, 164, 382, 183, 425, 426, 167, |
||
544 |
170, 420, 209, 181, 208, 357, 210, 427, 385, 386, |
||
545 |
387, 388, 211, 212, 183, 183, 390, 391, 183, 288, |
||
546 |
213, 214, 215, 183, 183, 201, 201, 201, 201, 93, |
||
547 |
201, 201, 201, 223, 201, 201, 201, 406, 407, 408, |
||
548 |
201, 365, 243, 409, 216, 243, 303, 243, 243, 268, |
||
549 |
306, 446, 316, 329, 299, 300, 301, 311, 201, 201, |
||
550 |
317, 325, 334, 383, 330, 188, 331, 201, 201, 2, |
||
551 |
3, 4, 5, 354, 6, 332, 7, 8, 9, 10, |
||
552 |
348, 201, 349, 11, 350, 395, 355, 377, 12, 378, |
||
553 |
13, 398, 379, 428, 381, 61, 389, 61, 392, 400, |
||
554 |
220, 424, 431, 433, 366, 14, 437, 440, 243, 367, |
||
555 |
40, 443, 15, 243, 243, 16, 447, 17, 18, 19, |
||
556 |
450, 451, 452, 454, 77, 20, 21, 22, 21, 188, |
||
557 |
188, 188, 188, 61, 188, 188, 188, 209, 188, 188, |
||
558 |
187, 54, 30, 63, 188, 201, 201, 201, 201, 23, |
||
559 |
201, 201, 201, 275, 201, 201, 201, 19, 214, 88, |
||
560 |
201, 24, 188, 188, 32, 243, 122, 99, 241, 241, |
||
561 |
241, 73, 93, 61, 95, 128, 25, 114, 201, 201, |
||
562 |
241, 241, 241, 241, 115, 128, 129, 130, 241, 241, |
||
563 |
241, 241, 241, 241, 61, 167, 179, 131, 132, 133, |
||
564 |
134, 136, 324, 364, 435, 135, 136, 137, 138, 139, |
||
565 |
140, 429, 397, 449, 439, 448, 432, 276, 277, 278, |
||
566 |
279, 32, 280, 281, 282, 35, 283, 284, 61, 36, |
||
567 |
305, 61, 285, 343, 376, 61, 0, 0, 0, 61, |
||
568 |
61, 61, 0, 61, 0, 0, 0, 0, 61, 61, |
||
569 |
286, 287, 61, 61, 61, 61, 61, 61, 61, 0, |
||
570 |
61, 0, 0, 0, 342, 61, 61, 0, 61, 61, |
||
571 |
61, 61, 0, 0, 0, 0, 61, 0, 61, 61, |
||
572 |
0, 0, 0, 61, 0, 0, 0, 0, 0, 0, |
||
573 |
0, 0, 0, 61, 61, 61, 375, 0, 0, 0, |
||
574 |
0, 0, 0, 0, 61, 61, 61, 61, 61, 0, |
||
575 |
0, 0, 0, 61, 61, 61, 61, 61, 61, 0, |
||
576 |
0, 61, 0, 0, 0, 61, 0, 0, 61, 0, |
||
577 |
0, 0, 61, 0, 0, 0, 61, 61, 61, 0, |
||
578 |
61, 0, 0, 0, 0, 61, 61, 0, 0, 61, |
||
579 |
61, 61, 61, 61, 61, 61, 0, 61, 0, 0, |
||
580 |
0, 0, 61, 61, 0, 61, 61, 61, 61, 243, |
||
581 |
243, 243, 0, 61, 0, 61, 61, 0, 0, 0, |
||
582 |
61, 243, 243, 243, 243, 0, 0, 0, 0, 243, |
||
583 |
243, 243, 243, 243, 243, 240, 0, 0, 241, 0, |
||
584 |
0, 61, 0, 0, 0, 0, 0, 0, 0, 0, |
||
585 |
242, 0, 0, 0, 0, 0, 0, 0, 61, 243, |
||
586 |
244, 245, 246, 247, 248, 249, 0, 250, 0, 0, |
||
587 |
241, 0, 251, 252, 0, 253, 254, 255, 256, 0, |
||
588 |
0, 0, 242, 257, 0, 258, 259, 0, 0, 0, |
||
589 |
260, 243, 244, 245, 246, 247, 248, 249, 0, 250, |
||
590 |
0, 0, 0, 0, 251, 252, 0, 253, 254, 255, |
||
591 |
256, 261, 0, 0, 0, 257, 0, 258, 259, 0, |
||
592 |
0, 61, 260, 0, 61, 0, 0, 0, 262, 0, |
||
593 |
0, 0, 0, 0, 0, 0, 61, 0, 0, 0, |
||
594 |
0, 61, 0, 261, 0, 61, 61, 61, 61, 61, |
||
595 |
61, 61, 0, 61, 0, 0, 0, 0, 61, 61, |
||
596 |
262, 61, 61, 61, 61, 0, 0, 0, 0, 61, |
||
597 |
0, 61, 61, 0, 0, 240, 61, 229, 241, 0, |
||
598 |
0, 230, 231, 232, 0, 0, 0, 0, 0, 0, |
||
599 |
242, 13, 0, 0, 0, 0, 233, 61, 0, 243, |
||
600 |
244, 245, 246, 247, 248, 249, 0, 250, 0, 0, |
||
601 |
241, 234, 251, 252, 61, 253, 254, 255, 256, 0, |
||
602 |
0, 0, 242, 257, 0, 258, 259, 0, 0, 0, |
||
603 |
260, 243, 244, 245, 246, 247, 248, 249, 0, 250, |
||
604 |
0, 0, 0, 0, 251, 252, 0, 253, 254, 255, |
||
605 |
256, 261, 0, 0, 0, 257, 0, 258, 259, 0, |
||
606 |
0, 61, 260, 0, 61, 61, 61, 61, 262, 0, |
||
607 |
0, 0, 0, 0, 0, 61, 61, 0, 0, 0, |
||
608 |
61, 0, 0, 261, 0, 61, 61, 61, 61, 61, |
||
609 |
61, 61, 0, 61, 0, 61, 0, 0, 61, 61, |
||
610 |
262, 61, 61, 61, 61, 128, 129, 130, 0, 61, |
||
611 |
0, 61, 61, 0, 0, 0, 61, 131, 132, 133, |
||
612 |
134, 61, 61, 61, 0, 135, 136, 137, 138, 139, |
||
613 |
140, 0, 0, 61, 61, 61, 61, 61, 0, 0, |
||
614 |
0, 61, 61, 61, 61, 61, 61, 0, 0, 0, |
||
615 |
0, 0, 0, 0, 61, |
||
616 |
}; |
||
617 |
const short yycheck[] = |
||
618 |
{ 57, |
||
619 |
10, 10, 61, 43, 61, 45, 10, 73, 43, 43, |
||
620 |
45, 45, 43, 190, 45, 45, 3, 101, 279, 123, |
||
621 |
294, 100, 288, 123, 257, 123, 265, 10, 125, 87, |
||
622 |
260, 260, 276, 271, 44, 271, 123, 44, 18, 19, |
||
623 |
197, 44, 275, 101, 10, 278, 279, 126, 225, 228, |
||
624 |
44, 61, 192, 13, 4, 42, 125, 373, 146, 257, |
||
625 |
149, 119, 271, 44, 123, 123, 123, 10, 10, 60, |
||
626 |
61, 62, 363, 44, 140, 61, 280, 275, 44, 262, |
||
627 |
278, 279, 300, 301, 325, 318, 287, 240, 363, 354, |
||
628 |
355, 295, 364, 300, 301, 364, 334, 47, 363, 364, |
||
629 |
188, 44, 257, 243, 244, 257, 422, 316, 317, 89, |
||
630 |
263, 363, 364, 123, 267, 125, 273, 296, 125, 363, |
||
631 |
318, 362, 125, 83, 363, 363, 363, 363, 363, 187, |
||
632 |
363, 125, 221, 83, 364, 364, 364, 61, 364, 125, |
||
633 |
123, 61, 295, 201, 125, 363, 353, 226, 10, 415, |
||
634 |
363, 352, 363, 10, 125, 319, 320, 123, 61, 125, |
||
635 |
272, 273, 436, 356, 10, 363, 10, 233, 315, 430, |
||
636 |
257, 326, 327, 328, 326, 327, 328, 261, 10, 245, |
||
637 |
10, 345, 363, 364, 134, 10, 363, 10, 275, 316, |
||
638 |
317, 278, 279, 10, 263, 10, 350, 351, 267, 268, |
||
639 |
269, 300, 301, 261, 10, 192, 309, 310, 277, 316, |
||
640 |
317, 10, 270, 282, 363, 364, 287, 10, 289, 290, |
||
641 |
291, 44, 363, 364, 204, 276, 403, 364, 297, 363, |
||
642 |
364, 318, 129, 130, 364, 363, 295, 274, 295, 47, |
||
643 |
47, 418, 337, 338, 339, 340, 332, 257, 306, 229, |
||
644 |
363, 303, 429, 271, 123, 357, 243, 244, 435, 363, |
||
645 |
364, 123, 346, 363, 364, 363, 363, 364, 363, 340, |
||
646 |
363, 123, 364, 364, 364, 272, 363, 123, 258, 364, |
||
647 |
260, 363, 363, 354, 355, 295, 363, 363, 363, 363, |
||
648 |
329, 257, 363, 263, 364, 363, 246, 364, 363, 358, |
||
649 |
363, 358, 125, 253, 363, 364, 363, 364, 363, 295, |
||
650 |
123, 321, 322, 323, 324, 363, 326, 327, 328, 123, |
||
651 |
330, 331, 332, 332, 364, 312, 336, 393, 394, 364, |
||
652 |
364, 361, 364, 364, 363, 285, 364, 395, 318, 319, |
||
653 |
320, 321, 364, 364, 354, 355, 326, 327, 358, 123, |
||
654 |
364, 364, 364, 363, 364, 321, 322, 323, 324, 363, |
||
655 |
326, 327, 328, 363, 330, 331, 332, 358, 359, 360, |
||
656 |
336, 295, 358, 364, 364, 295, 262, 363, 364, 363, |
||
657 |
10, 439, 364, 262, 363, 363, 363, 363, 354, 355, |
||
658 |
364, 363, 308, 287, 363, 257, 363, 363, 364, 256, |
||
659 |
257, 258, 259, 364, 261, 363, 263, 264, 265, 266, |
||
660 |
363, 257, 363, 270, 363, 123, 364, 363, 275, 363, |
||
661 |
277, 125, 363, 352, 364, 123, 363, 125, 363, 363, |
||
662 |
44, 364, 125, 364, 358, 292, 125, 364, 358, 363, |
||
663 |
364, 364, 299, 363, 364, 302, 363, 304, 305, 306, |
||
664 |
125, 363, 363, 363, 276, 312, 313, 314, 10, 321, |
||
665 |
322, 323, 324, 123, 326, 327, 328, 10, 330, 331, |
||
666 |
332, 10, 10, 10, 336, 321, 322, 323, 324, 336, |
||
667 |
326, 327, 328, 257, 330, 331, 332, 10, 363, 10, |
||
668 |
336, 348, 354, 355, 10, 363, 10, 10, 321, 322, |
||
669 |
323, 10, 10, 125, 10, 10, 363, 10, 354, 355, |
||
670 |
333, 334, 335, 336, 10, 321, 322, 323, 341, 342, |
||
671 |
343, 344, 345, 346, 125, 125, 125, 333, 334, 335, |
||
672 |
336, 10, 250, 289, 416, 341, 342, 343, 344, 345, |
||
673 |
346, 401, 340, 444, 427, 441, 409, 321, 322, 323, |
||
674 |
324, 1, 326, 327, 328, 1, 330, 331, 256, 1, |
||
675 |
236, 259, 336, 265, 296, 263, -1, -1, -1, 267, |
||
676 |
268, 269, -1, 271, -1, -1, -1, -1, 276, 277, |
||
677 |
354, 355, 280, 281, 282, 283, 284, 285, 286, -1, |
||
678 |
288, -1, -1, -1, 125, 293, 294, -1, 296, 297, |
||
679 |
298, 299, -1, -1, -1, -1, 304, -1, 306, 307, |
||
680 |
-1, -1, -1, 311, -1, -1, -1, -1, -1, -1, |
||
681 |
-1, -1, -1, 321, 322, 323, 125, -1, -1, -1, |
||
682 |
-1, -1, -1, -1, 332, 333, 334, 335, 336, -1, |
||
683 |
-1, -1, -1, 341, 342, 343, 344, 345, 346, -1, |
||
684 |
-1, 349, -1, -1, -1, 256, -1, -1, 259, -1, |
||
685 |
-1, -1, 263, -1, -1, -1, 267, 268, 269, -1, |
||
686 |
271, -1, -1, -1, -1, 276, 277, -1, -1, 280, |
||
687 |
281, 282, 283, 284, 285, 286, -1, 288, -1, -1, |
||
688 |
-1, -1, 293, 294, -1, 296, 297, 298, 299, 321, |
||
689 |
322, 323, -1, 304, -1, 306, 307, -1, -1, -1, |
||
690 |
311, 333, 334, 335, 336, -1, -1, -1, -1, 341, |
||
691 |
342, 343, 344, 345, 346, 256, -1, -1, 259, -1, |
||
692 |
-1, 332, -1, -1, -1, -1, -1, -1, -1, -1, |
||
693 |
271, -1, -1, -1, -1, -1, -1, -1, 349, 280, |
||
694 |
281, 282, 283, 284, 285, 286, -1, 288, -1, -1, |
||
695 |
259, -1, 293, 294, -1, 296, 297, 298, 299, -1, |
||
696 |
-1, -1, 271, 304, -1, 306, 307, -1, -1, -1, |
||
697 |
311, 280, 281, 282, 283, 284, 285, 286, -1, 288, |
||
698 |
-1, -1, -1, -1, 293, 294, -1, 296, 297, 298, |
||
699 |
299, 332, -1, -1, -1, 304, -1, 306, 307, -1, |
||
700 |
-1, 256, 311, -1, 259, -1, -1, -1, 349, -1, |
||
701 |
-1, -1, -1, -1, -1, -1, 271, -1, -1, -1, |
||
702 |
-1, 276, -1, 332, -1, 280, 281, 282, 283, 284, |
||
703 |
285, 286, -1, 288, -1, -1, -1, -1, 293, 294, |
||
704 |
349, 296, 297, 298, 299, -1, -1, -1, -1, 304, |
||
705 |
-1, 306, 307, -1, -1, 256, 311, 263, 259, -1, |
||
706 |
-1, 267, 268, 269, -1, -1, -1, -1, -1, -1, |
||
707 |
271, 277, -1, -1, -1, -1, 282, 332, -1, 280, |
||
708 |
281, 282, 283, 284, 285, 286, -1, 288, -1, -1, |
||
709 |
259, 297, 293, 294, 349, 296, 297, 298, 299, -1, |
||
710 |
-1, -1, 271, 304, -1, 306, 307, -1, -1, -1, |
||
711 |
311, 280, 281, 282, 283, 284, 285, 286, -1, 288, |
||
712 |
-1, -1, -1, -1, 293, 294, -1, 296, 297, 298, |
||
713 |
299, 332, -1, -1, -1, 304, -1, 306, 307, -1, |
||
714 |
-1, 263, 311, -1, 259, 267, 268, 269, 349, -1, |
||
715 |
-1, -1, -1, -1, -1, 277, 271, -1, -1, -1, |
||
716 |
282, -1, -1, 332, -1, 280, 281, 282, 283, 284, |
||
717 |
285, 286, -1, 288, -1, 297, -1, -1, 293, 294, |
||
718 |
349, 296, 297, 298, 299, 321, 322, 323, -1, 304, |
||
719 |
-1, 306, 307, -1, -1, -1, 311, 333, 334, 335, |
||
720 |
336, 321, 322, 323, -1, 341, 342, 343, 344, 345, |
||
721 |
346, -1, -1, 333, 334, 335, 336, 332, -1, -1, |
||
722 |
-1, 341, 342, 343, 344, 345, 346, -1, -1, -1, |
||
723 |
-1, -1, -1, -1, 349, |
||
724 |
}; |
||
725 |
#define YYFINAL 1 |
||
726 |
#ifndef YYDEBUG |
||
727 |
#define YYDEBUG 0 |
||
728 |
#endif |
||
729 |
#define YYMAXTOKEN 364 |
||
730 |
#if YYDEBUG |
||
731 |
const char * const yyname[] = |
||
732 |
{ |
||
733 |
"end-of-file",0,0,0,0,0,0,0,0,0,"'\\n'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
||
734 |
0,0,0,0,0,0,0,0,0,0,0,0,"'+'","','","'-'",0,"'/'",0,0,0,0,0,0,0,0,0,0,0,0,"'<'", |
||
735 |
"'='","'>'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
||
736 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'{'",0,"'}'",0,0,0,0,0,0,0, |
||
737 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
||
738 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
||
739 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
||
740 |
4 |
0,0,0,0,"AS","ROUTERID","HOLDTIME","YMIN","LISTEN","ON","FIBUPDATE", |
|
741 |
8 |
"FIBPRIORITY","RTABLE","RDOMAIN","RD","EXPORTTRGT","IMPORTTRGT","RDE","RIB", |
|
742 |
4 |
"EVALUATE","IGNORE","COMPARE","GROUP","NEIGHBOR","NETWORK","EBGP","IBGP", |
|
743 |
"LOCALAS","REMOTEAS","DESCR","LOCALADDR","MULTIHOP","PASSIVE","MAXPREFIX", |
||
744 |
"RESTART","ANNOUNCE","CAPABILITIES","REFRESH","AS4BYTE","CONNECTRETRY","DEMOTE", |
||
745 |
"ENFORCE","NEIGHBORAS","REFLECTOR","DEPEND","DOWN","DUMP","IN","OUT","SOCKET", |
||
746 |
"RESTRICTED","LOG","ROUTECOLL","TRANSPARENT","TCP","MD5SIG","PASSWORD","KEY", |
||
747 |
"TTLSECURITY","ALLOW","DENY","MATCH","QUICK","FROM","TO","ANY","CONNECTED", |
||
748 |
"STATIC","COMMUNITY","EXTCOMMUNITY","LARGECOMMUNITY","PREFIX","PREFIXLEN", |
||
749 |
52 |
"SOURCEAS","TRANSITAS","PEERAS","DELETE","MAXASLEN","MAXASSEQ","SET", |
|
750 |
"LOCALPREF","MED","METRIC","NEXTHOP","REJECT","BLACKHOLE","NOMODIFY","SELF", |
||
751 |
✗✓ | 52 |
"PREPEND_SELF","PREPEND_PEER","PFTABLE","WEIGHT","RTLABEL","ORIGIN","ERROR", |
752 |
"INCLUDE","IPSEC","ESP","AH","SPI","IKE","IPV4","IPV6","QUALIFY","VIA","NE", |
||
753 |
"LE","GE","XRANGE","LONGER","STRING","NUMBER", |
||
754 |
}; |
||
755 |
const char * const yyrule[] = |
||
756 |
{"$accept : grammar", |
||
757 |
52 |
"grammar :", |
|
758 |
"grammar : grammar '\\n'", |
||
759 |
✓✗✓✗ ✗✗ |
104 |
"grammar : grammar include '\\n'", |
760 |
✗✓ | 52 |
"grammar : grammar conf_main '\\n'", |
761 |
"grammar : grammar varset '\\n'", |
||
762 |
"grammar : grammar rdomain '\\n'", |
||
763 |
"grammar : grammar neighbor '\\n'", |
||
764 |
"grammar : grammar group '\\n'", |
||
765 |
"grammar : grammar filterrule '\\n'", |
||
766 |
✗✓ | 104 |
"grammar : grammar error '\\n'", |
767 |
"asnumber : NUMBER", |
||
768 |
"as4number : STRING", |
||
769 |
"as4number : asnumber", |
||
770 |
100 |
"as4number_any : STRING", |
|
771 |
"as4number_any : asnumber", |
||
772 |
✓✗✗✓ |
200 |
"string : string STRING", |
773 |
"string : STRING", |
||
774 |
"yesno : STRING", |
||
775 |
"varset : STRING '=' string", |
||
776 |
"include : INCLUDE STRING", |
||
777 |
✗✓ | 100 |
"conf_main : AS as4number", |
778 |
"conf_main : AS as4number asnumber", |
||
779 |
100 |
"conf_main : ROUTERID address", |
|
780 |
"conf_main : HOLDTIME NUMBER", |
||
781 |
✗✓ | 100 |
"conf_main : HOLDTIME YMIN NUMBER", |
782 |
"conf_main : LISTEN ON address", |
||
783 |
"conf_main : FIBPRIORITY NUMBER", |
||
784 |
"conf_main : FIBUPDATE yesno", |
||
785 |
"conf_main : ROUTECOLL yesno", |
||
786 |
100 |
"conf_main : RDE RIB STRING", |
|
787 |
✗✓ | 200 |
"conf_main : RDE RIB STRING yesno EVALUATE", |
788 |
"conf_main : RDE RIB STRING RTABLE NUMBER", |
||
789 |
"conf_main : RDE RIB STRING RTABLE NUMBER FIBUPDATE yesno", |
||
790 |
"conf_main : TRANSPARENT yesno", |
||
791 |
"conf_main : LOG STRING", |
||
792 |
"conf_main : network", |
||
793 |
"conf_main : DUMP STRING STRING optnumber", |
||
794 |
"conf_main : DUMP RIB STRING STRING STRING optnumber", |
||
795 |
"conf_main : mrtdump", |
||
796 |
"conf_main : RDE STRING EVALUATE", |
||
797 |
"conf_main : RDE STRING IGNORE", |
||
798 |
"conf_main : RDE MED COMPARE STRING", |
||
799 |
"conf_main : NEXTHOP QUALIFY VIA STRING", |
||
800 |
"conf_main : RTABLE NUMBER", |
||
801 |
"conf_main : CONNECTRETRY NUMBER", |
||
802 |
"conf_main : SOCKET STRING restricted", |
||
803 |
"mrtdump : DUMP STRING inout STRING optnumber", |
||
804 |
"network : NETWORK prefix filter_set", |
||
805 |
"network : NETWORK family RTLABEL STRING filter_set", |
||
806 |
"network : NETWORK family nettype filter_set", |
||
807 |
"inout : IN", |
||
808 |
"inout : OUT", |
||
809 |
28 |
"restricted : RESTRICTED", |
|
810 |
28 |
"restricted :", |
|
811 |
"address : STRING", |
||
812 |
"prefix : STRING '/' NUMBER", |
||
813 |
"prefix : NUMBER '/' NUMBER", |
||
814 |
"addrspec : address", |
||
815 |
28 |
"addrspec : prefix", |
|
816 |
"optnl : '\\n' optnl", |
||
817 |
"optnl :", |
||
818 |
"nl : '\\n' optnl", |
||
819 |
"optnumber :", |
||
820 |
"optnumber : NUMBER", |
||
821 |
"$$1 :", |
||
822 |
"rdomain : RDOMAIN NUMBER optnl '{' optnl $$1 rdomainopts_l '}'", |
||
823 |
"rdomainopts_l : rdomainopts_l rdomainoptsl", |
||
824 |
"rdomainopts_l : rdomainoptsl", |
||
825 |
"rdomainoptsl : rdomainopts nl", |
||
826 |
"rdomainopts : RD STRING", |
||
827 |
"rdomainopts : EXPORTTRGT STRING STRING", |
||
828 |
"rdomainopts : IMPORTTRGT STRING STRING", |
||
829 |
"rdomainopts : DESCR string", |
||
830 |
"rdomainopts : FIBUPDATE yesno", |
||
831 |
"rdomainopts : network", |
||
832 |
"rdomainopts : DEPEND ON STRING", |
||
833 |
"$$2 :", |
||
834 |
"$$3 :", |
||
835 |
"neighbor : $$2 NEIGHBOR addrspec $$3 peeropts_h", |
||
836 |
"$$4 :", |
||
837 |
"group : GROUP string optnl '{' optnl $$4 groupopts_l '}'", |
||
838 |
"groupopts_l : groupopts_l groupoptsl", |
||
839 |
"groupopts_l : groupoptsl", |
||
840 |
"groupoptsl : peeropts nl", |
||
841 |
"groupoptsl : neighbor nl", |
||
842 |
"groupoptsl : error nl", |
||
843 |
"peeropts_h : '{' optnl peeropts_l '}'", |
||
844 |
"peeropts_h :", |
||
845 |
"peeropts_l : peeropts_l peeroptsl", |
||
846 |
"peeropts_l : peeroptsl", |
||
847 |
"peeroptsl : peeropts nl", |
||
848 |
"peeropts : REMOTEAS as4number", |
||
849 |
"peeropts : LOCALAS as4number", |
||
850 |
"peeropts : LOCALAS as4number asnumber", |
||
851 |
"peeropts : DESCR string", |
||
852 |
"peeropts : LOCALADDR address", |
||
853 |
"peeropts : MULTIHOP NUMBER", |
||
854 |
"peeropts : PASSIVE", |
||
855 |
"peeropts : DOWN", |
||
856 |
"peeropts : DOWN STRING", |
||
857 |
"peeropts : RIB STRING", |
||
858 |
"peeropts : HOLDTIME NUMBER", |
||
859 |
"peeropts : HOLDTIME YMIN NUMBER", |
||
860 |
"peeropts : ANNOUNCE family STRING", |
||
861 |
"peeropts : ANNOUNCE CAPABILITIES yesno", |
||
862 |
"peeropts : ANNOUNCE REFRESH yesno", |
||
863 |
"peeropts : ANNOUNCE RESTART yesno", |
||
864 |
"peeropts : ANNOUNCE AS4BYTE yesno", |
||
865 |
"peeropts : ANNOUNCE SELF", |
||
866 |
"peeropts : ANNOUNCE STRING", |
||
867 |
"peeropts : ENFORCE NEIGHBORAS yesno", |
||
868 |
"peeropts : ENFORCE LOCALAS yesno", |
||
869 |
"peeropts : MAXPREFIX NUMBER restart", |
||
870 |
"peeropts : TCP MD5SIG PASSWORD string", |
||
871 |
"peeropts : TCP MD5SIG KEY string", |
||
872 |
"peeropts : IPSEC espah IKE", |
||
873 |
"peeropts : IPSEC espah inout SPI NUMBER STRING STRING encspec", |
||
874 |
"peeropts : TTLSECURITY yesno", |
||
875 |
"peeropts : SET filter_set_opt", |
||
876 |
"peeropts : SET optnl '{' optnl filter_set_l optnl '}'", |
||
877 |
"peeropts : mrtdump", |
||
878 |
"peeropts : REFLECTOR", |
||
879 |
"peeropts : REFLECTOR address", |
||
880 |
"peeropts : DEPEND ON STRING", |
||
881 |
"peeropts : DEMOTE STRING", |
||
882 |
"peeropts : TRANSPARENT yesno", |
||
883 |
"peeropts : LOG STRING", |
||
884 |
"restart :", |
||
885 |
"restart : RESTART NUMBER", |
||
886 |
"family : IPV4", |
||
887 |
"family : IPV6", |
||
888 |
"nettype : STATIC", |
||
889 |
"nettype : CONNECTED", |
||
890 |
"espah : ESP", |
||
891 |
"espah : AH", |
||
892 |
"encspec :", |
||
893 |
"encspec : STRING STRING", |
||
894 |
"filterrule : action quick filter_rib_h direction filter_peer_h filter_match_h filter_set", |
||
895 |
"action : ALLOW", |
||
896 |
"action : DENY", |
||
897 |
"action : MATCH", |
||
898 |
"quick :", |
||
899 |
"quick : QUICK", |
||
900 |
"direction : FROM", |
||
901 |
"direction : TO", |
||
902 |
"filter_rib_h :", |
||
903 |
"filter_rib_h : RIB filter_rib", |
||
904 |
"filter_rib_h : RIB '{' filter_rib_l '}'", |
||
905 |
"filter_rib_l : filter_rib", |
||
906 |
"filter_rib_l : filter_rib_l comma filter_rib", |
||
907 |
"filter_rib : STRING", |
||
908 |
"filter_peer_h : filter_peer", |
||
909 |
"filter_peer_h : '{' filter_peer_l '}'", |
||
910 |
"filter_peer_l : filter_peer", |
||
911 |
"filter_peer_l : filter_peer_l comma filter_peer", |
||
912 |
"filter_peer : ANY", |
||
913 |
"filter_peer : address", |
||
914 |
"filter_peer : AS as4number", |
||
915 |
"filter_peer : GROUP STRING", |
||
916 |
"filter_peer : EBGP", |
||
917 |
"filter_peer : IBGP", |
||
918 |
"filter_prefix_h : IPV4 prefixlenop", |
||
919 |
"filter_prefix_h : IPV6 prefixlenop", |
||
920 |
"filter_prefix_h : PREFIX filter_prefix", |
||
921 |
"filter_prefix_h : PREFIX '{' filter_prefix_m '}'", |
||
922 |
"filter_prefix_m : filter_prefix_l", |
||
923 |
"filter_prefix_m : '{' filter_prefix_l '}'", |
||
924 |
"filter_prefix_m : '{' filter_prefix_l '}' filter_prefix_m", |
||
925 |
"filter_prefix_l : filter_prefix", |
||
926 |
"filter_prefix_l : filter_prefix_l comma filter_prefix", |
||
927 |
"filter_prefix : prefix prefixlenop", |
||
928 |
"filter_as_h : filter_as_t", |
||
929 |
"filter_as_h : '{' filter_as_t_l '}'", |
||
930 |
"filter_as_t_l : filter_as_t", |
||
931 |
"filter_as_t_l : filter_as_t_l comma filter_as_t", |
||
932 |
"filter_as_t : filter_as_type filter_as", |
||
933 |
"filter_as_t : filter_as_type '{' filter_as_l_h '}'", |
||
934 |
"filter_as_l_h : filter_as_l", |
||
935 |
"filter_as_l_h : '{' filter_as_l '}'", |
||
936 |
"filter_as_l_h : '{' filter_as_l '}' filter_as_l_h", |
||
937 |
"filter_as_l : filter_as", |
||
938 |
"filter_as_l : filter_as_l comma filter_as", |
||
939 |
"filter_as : as4number_any", |
||
940 |
"filter_as : NEIGHBORAS", |
||
941 |
"filter_as : equalityop as4number_any", |
||
942 |
"filter_as : as4number_any binaryop as4number_any", |
||
943 |
"filter_match_h :", |
||
944 |
"$$5 :", |
||
945 |
"filter_match_h : $$5 filter_match", |
||
946 |
"filter_match : filter_elm", |
||
947 |
"filter_match : filter_match filter_elm", |
||
948 |
"filter_elm : filter_prefix_h", |
||
949 |
"filter_elm : filter_as_h", |
||
950 |
"filter_elm : MAXASLEN NUMBER", |
||
951 |
"filter_elm : MAXASSEQ NUMBER", |
||
952 |
"filter_elm : COMMUNITY STRING", |
||
953 |
"filter_elm : LARGECOMMUNITY STRING", |
||
954 |
"filter_elm : EXTCOMMUNITY STRING STRING", |
||
955 |
"filter_elm : NEXTHOP address", |
||
956 |
"filter_elm : NEXTHOP NEIGHBOR", |
||
957 |
"prefixlenop :", |
||
958 |
"prefixlenop : LONGER", |
||
959 |
"prefixlenop : PREFIXLEN unaryop NUMBER", |
||
960 |
"prefixlenop : PREFIXLEN NUMBER binaryop NUMBER", |
||
961 |
32 |
"filter_as_type : AS", |
|
962 |
32 |
"filter_as_type : SOURCEAS", |
|
963 |
32 |
"filter_as_type : TRANSITAS", |
|
964 |
"filter_as_type : PEERAS", |
||
965 |
32 |
"filter_set :", |
|
966 |
✓✗✓✓ ✗✗ |
64 |
"filter_set : SET filter_set_opt", |
967 |
✗✓ | 28 |
"filter_set : SET optnl '{' optnl filter_set_l optnl '}'", |
968 |
4 |
"filter_set_l : filter_set_l comma filter_set_opt", |
|
969 |
✓✗ | 96 |
"filter_set_l : filter_set_opt", |
970 |
64 |
"delete :", |
|
971 |
32 |
"delete : DELETE", |
|
972 |
32 |
"filter_set_opt : LOCALPREF NUMBER", |
|
973 |
✗✓ | 32 |
"filter_set_opt : LOCALPREF '+' NUMBER", |
974 |
"filter_set_opt : LOCALPREF '-' NUMBER", |
||
975 |
"filter_set_opt : MED NUMBER", |
||
976 |
"filter_set_opt : MED '+' NUMBER", |
||
977 |
"filter_set_opt : MED '-' NUMBER", |
||
978 |
"filter_set_opt : METRIC NUMBER", |
||
979 |
✗✓ | 32 |
"filter_set_opt : METRIC '+' NUMBER", |
980 |
"filter_set_opt : METRIC '-' NUMBER", |
||
981 |
"filter_set_opt : WEIGHT NUMBER", |
||
982 |
✗✓ | 32 |
"filter_set_opt : WEIGHT '+' NUMBER", |
983 |
"filter_set_opt : WEIGHT '-' NUMBER", |
||
984 |
"filter_set_opt : NEXTHOP address", |
||
985 |
32 |
"filter_set_opt : NEXTHOP BLACKHOLE", |
|
986 |
32 |
"filter_set_opt : NEXTHOP REJECT", |
|
987 |
"filter_set_opt : NEXTHOP NOMODIFY", |
||
988 |
✗✓ | 32 |
"filter_set_opt : NEXTHOP SELF", |
989 |
"filter_set_opt : PREPEND_SELF NUMBER", |
||
990 |
32 |
"filter_set_opt : PREPEND_PEER NUMBER", |
|
991 |
32 |
"filter_set_opt : PFTABLE STRING", |
|
992 |
32 |
"filter_set_opt : RTLABEL STRING", |
|
993 |
"filter_set_opt : COMMUNITY delete STRING", |
||
994 |
32 |
"filter_set_opt : LARGECOMMUNITY delete STRING", |
|
995 |
"filter_set_opt : EXTCOMMUNITY delete STRING STRING", |
||
996 |
"filter_set_opt : ORIGIN origincode", |
||
997 |
8 |
"origincode : string", |
|
998 |
✗✓ | 16 |
"comma : ','", |
999 |
8 |
"comma :", |
|
1000 |
"unaryop : '='", |
||
1001 |
"unaryop : NE", |
||
1002 |
"unaryop : LE", |
||
1003 |
"unaryop : '<'", |
||
1004 |
"unaryop : GE", |
||
1005 |
"unaryop : '>'", |
||
1006 |
8 |
"equalityop : '='", |
|
1007 |
✗✓ | 8 |
"equalityop : NE", |
1008 |
"binaryop : '-'", |
||
1009 |
"binaryop : XRANGE", |
||
1010 |
}; |
||
1011 |
#endif |
||
1012 |
#ifdef YYSTACKSIZE |
||
1013 |
✗✓ | 8 |
#undef YYMAXDEPTH |
1014 |
#define YYMAXDEPTH YYSTACKSIZE |
||
1015 |
#else |
||
1016 |
✗✓ | 8 |
#ifdef YYMAXDEPTH |
1017 |
#define YYSTACKSIZE YYMAXDEPTH |
||
1018 |
#else |
||
1019 |
8 |
#define YYSTACKSIZE 10000 |
|
1020 |
8 |
#define YYMAXDEPTH 10000 |
|
1021 |
#endif |
||
1022 |
8 |
#endif |
|
1023 |
8 |
#define YYINITSTACKSIZE 200 |
|
1024 |
/* LINTUSED */ |
||
1025 |
8 |
int yydebug; |
|
1026 |
int yynerrs; |
||
1027 |
int yyerrflag; |
||
1028 |
int yychar; |
||
1029 |
short *yyssp; |
||
1030 |
YYSTYPE *yyvsp; |
||
1031 |
YYSTYPE yyval; |
||
1032 |
YYSTYPE yylval; |
||
1033 |
short *yyss; |
||
1034 |
short *yysslim; |
||
1035 |
YYSTYPE *yyvs; |
||
1036 |
unsigned int yystacksize; |
||
1037 |
int yyparse(void); |
||
1038 |
#line 2328 "parse.y" |
||
1039 |
|||
1040 |
struct keywords { |
||
1041 |
const char *k_name; |
||
1042 |
int k_val; |
||
1043 |
}; |
||
1044 |
|||
1045 |
int |
||
1046 |
yyerror(const char *fmt, ...) |
||
1047 |
{ |
||
1048 |
20 |
va_list ap; |
|
1049 |
char *msg; |
||
1050 |
20 |
||
1051 |
file->errors++; |
||
1052 |
va_start(ap, fmt); |
||
1053 |
if (vasprintf(&msg, fmt, ap) == -1) |
||
1054 |
fatalx("yyerror vasprintf"); |
||
1055 |
va_end(ap); |
||
1056 |
logit(LOG_CRIT, "%s:%d: %s", file->name, yylval.lineno, msg); |
||
1057 |
free(msg); |
||
1058 |
return (0); |
||
1059 |
} |
||
1060 |
|||
1061 |
int |
||
1062 |
✗✓ | 48 |
kw_cmp(const void *k, const void *e) |
1063 |
24 |
{ |
|
1064 |
return (strcmp(k, ((const struct keywords *)e)->k_name)); |
||
1065 |
} |
||
1066 |
|||
1067 |
int |
||
1068 |
lookup(char *s) |
||
1069 |
{ |
||
1070 |
24 |
/* this has to be sorted always */ |
|
1071 |
static const struct keywords keywords[] = { |
||
1072 |
24 |
{ "AS", AS}, |
|
1073 |
20 |
{ "IPv4", IPV4}, |
|
1074 |
{ "IPv6", IPV6}, |
||
1075 |
{ "ah", AH}, |
||
1076 |
20 |
{ "allow", ALLOW}, |
|
1077 |
✓✗✗✓ |
8 |
{ "announce", ANNOUNCE}, |
1078 |
{ "any", ANY}, |
||
1079 |
{ "as-4byte", AS4BYTE }, |
||
1080 |
{ "blackhole", BLACKHOLE}, |
||
1081 |
4 |
{ "capabilities", CAPABILITIES}, |
|
1082 |
{ "community", COMMUNITY}, |
||
1083 |
4 |
{ "compare", COMPARE}, |
|
1084 |
4 |
{ "connect-retry", CONNECTRETRY}, |
|
1085 |
{ "connected", CONNECTED}, |
||
1086 |
4 |
{ "delete", DELETE}, |
|
1087 |
{ "demote", DEMOTE}, |
||
1088 |
{ "deny", DENY}, |
||
1089 |
{ "depend", DEPEND}, |
||
1090 |
{ "descr", DESCR}, |
||
1091 |
{ "down", DOWN}, |
||
1092 |
{ "dump", DUMP}, |
||
1093 |
{ "ebgp", EBGP}, |
||
1094 |
{ "enforce", ENFORCE}, |
||
1095 |
{ "esp", ESP}, |
||
1096 |
{ "evaluate", EVALUATE}, |
||
1097 |
{ "export-target", EXPORTTRGT}, |
||
1098 |
{ "ext-community", EXTCOMMUNITY}, |
||
1099 |
{ "fib-priority", FIBPRIORITY}, |
||
1100 |
{ "fib-update", FIBUPDATE}, |
||
1101 |
{ "from", FROM}, |
||
1102 |
{ "group", GROUP}, |
||
1103 |
{ "holdtime", HOLDTIME}, |
||
1104 |
{ "ibgp", IBGP}, |
||
1105 |
{ "ignore", IGNORE}, |
||
1106 |
{ "ike", IKE}, |
||
1107 |
{ "import-target", IMPORTTRGT}, |
||
1108 |
{ "in", IN}, |
||
1109 |
{ "include", INCLUDE}, |
||
1110 |
{ "inet", IPV4}, |
||
1111 |
{ "inet6", IPV6}, |
||
1112 |
{ "ipsec", IPSEC}, |
||
1113 |
{ "key", KEY}, |
||
1114 |
{ "large-community", LARGECOMMUNITY}, |
||
1115 |
{ "listen", LISTEN}, |
||
1116 |
{ "local-address", LOCALADDR}, |
||
1117 |
✓✗✗✓ |
8 |
{ "local-as", LOCALAS}, |
1118 |
{ "localpref", LOCALPREF}, |
||
1119 |
{ "log", LOG}, |
||
1120 |
{ "match", MATCH}, |
||
1121 |
{ "max-as-len", MAXASLEN}, |
||
1122 |
4 |
{ "max-as-seq", MAXASSEQ}, |
|
1123 |
{ "max-prefix", MAXPREFIX}, |
||
1124 |
4 |
{ "md5sig", MD5SIG}, |
|
1125 |
✓✗✗✓ |
8 |
{ "med", MED}, |
1126 |
{ "metric", METRIC}, |
||
1127 |
{ "min", YMIN}, |
||
1128 |
{ "multihop", MULTIHOP}, |
||
1129 |
{ "neighbor", NEIGHBOR}, |
||
1130 |
4 |
{ "neighbor-as", NEIGHBORAS}, |
|
1131 |
{ "network", NETWORK}, |
||
1132 |
4 |
{ "nexthop", NEXTHOP}, |
|
1133 |
{ "no-modify", NOMODIFY}, |
||
1134 |
{ "on", ON}, |
||
1135 |
{ "or-longer", LONGER}, |
||
1136 |
{ "origin", ORIGIN}, |
||
1137 |
{ "out", OUT}, |
||
1138 |
{ "passive", PASSIVE}, |
||
1139 |
{ "password", PASSWORD}, |
||
1140 |
{ "peer-as", PEERAS}, |
||
1141 |
{ "pftable", PFTABLE}, |
||
1142 |
{ "prefix", PREFIX}, |
||
1143 |
{ "prefixlen", PREFIXLEN}, |
||
1144 |
{ "prepend-neighbor", PREPEND_PEER}, |
||
1145 |
{ "prepend-self", PREPEND_SELF}, |
||
1146 |
{ "qualify", QUALIFY}, |
||
1147 |
{ "quick", QUICK}, |
||
1148 |
{ "rd", RD}, |
||
1149 |
{ "rde", RDE}, |
||
1150 |
{ "rdomain", RDOMAIN}, |
||
1151 |
{ "refresh", REFRESH }, |
||
1152 |
{ "reject", REJECT}, |
||
1153 |
{ "remote-as", REMOTEAS}, |
||
1154 |
{ "restart", RESTART}, |
||
1155 |
{ "restricted", RESTRICTED}, |
||
1156 |
{ "rib", RIB}, |
||
1157 |
{ "route-collector", ROUTECOLL}, |
||
1158 |
{ "route-reflector", REFLECTOR}, |
||
1159 |
{ "router-id", ROUTERID}, |
||
1160 |
{ "rtable", RTABLE}, |
||
1161 |
{ "rtlabel", RTLABEL}, |
||
1162 |
{ "self", SELF}, |
||
1163 |
{ "set", SET}, |
||
1164 |
{ "socket", SOCKET }, |
||
1165 |
{ "source-as", SOURCEAS}, |
||
1166 |
{ "spi", SPI}, |
||
1167 |
{ "static", STATIC}, |
||
1168 |
{ "tcp", TCP}, |
||
1169 |
{ "to", TO}, |
||
1170 |
4 |
{ "transit-as", TRANSITAS}, |
|
1171 |
{ "transparent-as", TRANSPARENT}, |
||
1172 |
4 |
{ "ttl-security", TTLSECURITY}, |
|
1173 |
✓✗ | 8 |
{ "via", VIA}, |
1174 |
{ "weight", WEIGHT} |
||
1175 |
✓✓ | 8 |
}; |
1176 |
const struct keywords *p; |
||
1177 |
✗✓ | 4 |
|
1178 |
p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]), |
||
1179 |
sizeof(keywords[0]), kw_cmp); |
||
1180 |
|||
1181 |
if (p) |
||
1182 |
return (p->k_val); |
||
1183 |
else |
||
1184 |
return (STRING); |
||
1185 |
} |
||
1186 |
|||
1187 |
8 |
#define MAXPUSHBACK 128 |
|
1188 |
|||
1189 |
8 |
u_char *parsebuf; |
|
1190 |
4 |
int parseindex; |
|
1191 |
u_char pushback_buffer[MAXPUSHBACK]; |
||
1192 |
int pushback_index = 0; |
||
1193 |
|||
1194 |
int |
||
1195 |
4 |
lgetc(int quotec) |
|
1196 |
{ |
||
1197 |
int c, next; |
||
1198 |
|||
1199 |
if (parsebuf) { |
||
1200 |
/* Read character from the parsebuffer instead of input. */ |
||
1201 |
if (parseindex >= 0) { |
||
1202 |
c = parsebuf[parseindex++]; |
||
1203 |
if (c != '\0') |
||
1204 |
return (c); |
||
1205 |
parsebuf = NULL; |
||
1206 |
} else |
||
1207 |
parseindex++; |
||
1208 |
} |
||
1209 |
|||
1210 |
✗✓ | 4 |
if (pushback_index) |
1211 |
return (pushback_buffer[--pushback_index]); |
||
1212 |
|||
1213 |
if (quotec) { |
||
1214 |
if ((c = getc(file->stream)) == EOF) { |
||
1215 |
✗✓ | 8 |
yyerror("reached end of file while parsing " |
1216 |
4 |
"quoted string"); |
|
1217 |
if (file == topfile || popfile() == EOF) |
||
1218 |
return (EOF); |
||
1219 |
return (quotec); |
||
1220 |
} |
||
1221 |
return (c); |
||
1222 |
} |
||
1223 |
4 |
||
1224 |
4 |
while ((c = getc(file->stream)) == '\\') { |
|
1225 |
4 |
next = getc(file->stream); |
|
1226 |
if (next != '\n') { |
||
1227 |
4 |
c = next; |
|
1228 |
✗✓ | 4 |
break; |
1229 |
} |
||
1230 |
yylval.lineno = file->lineno; |
||
1231 |
file->lineno++; |
||
1232 |
} |
||
1233 |
|||
1234 |
✗✓ | 8 |
while (c == EOF) { |
1235 |
4 |
if (file == topfile || popfile() == EOF) |
|
1236 |
return (EOF); |
||
1237 |
c = getc(file->stream); |
||
1238 |
} |
||
1239 |
4 |
return (c); |
|
1240 |
4 |
} |
|
1241 |
4 |
||
1242 |
int |
||
1243 |
4 |
lungetc(int c) |
|
1244 |
✗✓ | 12 |
{ |
1245 |
if (c == EOF) |
||
1246 |
return (EOF); |
||
1247 |
if (parsebuf) { |
||
1248 |
12 |
parseindex--; |
|
1249 |
if (parseindex >= 0) |
||
1250 |
return (c); |
||
1251 |
} |
||
1252 |
if (pushback_index < MAXPUSHBACK-1) |
||
1253 |
12 |
return (pushback_buffer[pushback_index++] = c); |
|
1254 |
else |
||
1255 |
return (EOF); |
||
1256 |
} |
||
1257 |
✓✓✗✗ |
8 |
|
1258 |
✓✗✓✗ |
8 |
int |
1259 |
✗✓✗✗ |
4 |
findeol(void) |
1260 |
✓✗ | 8 |
{ |
1261 |
✓✗ | 4 |
int c; |
1262 |
✗✓ | 4 |
|
1263 |
parsebuf = NULL; |
||
1264 |
|||
1265 |
/* skip to either EOF or the first real EOL */ |
||
1266 |
while (1) { |
||
1267 |
if (pushback_index) |
||
1268 |
c = pushback_buffer[--pushback_index]; |
||
1269 |
else |
||
1270 |
✓✗ | 8 |
c = lgetc(0); |
1271 |
if (c == '\n') { |
||
1272 |
file->lineno++; |
||
1273 |
✗✗ | 8 |
break; |
1274 |
} |
||
1275 |
if (c == EOF) |
||
1276 |
break; |
||
1277 |
} |
||
1278 |
return (ERROR); |
||
1279 |
} |
||
1280 |
|||
1281 |
int |
||
1282 |
8 |
yylex(void) |
|
1283 |
{ |
||
1284 |
✗✓ | 8 |
u_char buf[8096]; |
1285 |
u_char *p, *val; |
||
1286 |
int quotec, next, c; |
||
1287 |
int token; |
||
1288 |
|||
1289 |
top: |
||
1290 |
p = buf; |
||
1291 |
✗✓ | 8 |
while ((c = lgetc(0)) == ' ' || c == '\t') |
1292 |
; /* nothing */ |
||
1293 |
|||
1294 |
yylval.lineno = file->lineno; |
||
1295 |
if (c == '#') |
||
1296 |
while ((c = lgetc(0)) != '\n' && c != EOF) |
||
1297 |
; /* nothing */ |
||
1298 |
if (c == '$' && parsebuf == NULL) { |
||
1299 |
while (1) { |
||
1300 |
if ((c = lgetc(0)) == EOF) |
||
1301 |
return (0); |
||
1302 |
|||
1303 |
if (p + 1 >= buf + sizeof(buf) - 1) { |
||
1304 |
yyerror("string too long"); |
||
1305 |
✓✗✗✓ |
16 |
return (findeol()); |
1306 |
} |
||
1307 |
if (isalnum(c) || c == '_') { |
||
1308 |
*p++ = c; |
||
1309 |
continue; |
||
1310 |
} |
||
1311 |
✓✓ | 8 |
*p = '\0'; |
1312 |
✗✓ | 8 |
lungetc(c); |
1313 |
4 |
break; |
|
1314 |
} |
||
1315 |
val = symget(buf); |
||
1316 |
if (val == NULL) { |
||
1317 |
yyerror("macro '%s' not defined", buf); |
||
1318 |
4 |
return (findeol()); |
|
1319 |
4 |
} |
|
1320 |
4 |
parsebuf = val; |
|
1321 |
8 |
parseindex = 0; |
|
1322 |
4 |
goto top; |
|
1323 |
} |
||
1324 |
4 |
||
1325 |
4 |
switch (c) { |
|
1326 |
4 |
case '\'': |
|
1327 |
4 |
case '"': |
|
1328 |
✗✓ | 8 |
quotec = c; |
1329 |
4 |
while (1) { |
|
1330 |
if ((c = lgetc(quotec)) == EOF) |
||
1331 |
return (0); |
||
1332 |
if (c == '\n') { |
||
1333 |
file->lineno++; |
||
1334 |
4 |
continue; |
|
1335 |
4 |
} else if (c == '\\') { |
|
1336 |
4 |
if ((next = lgetc(quotec)) == EOF) |
|
1337 |
8 |
return (0); |
|
1338 |
4 |
if (next == quotec || c == ' ' || c == '\t') |
|
1339 |
c = next; |
||
1340 |
4 |
else if (next == '\n') { |
|
1341 |
4 |
file->lineno++; |
|
1342 |
4 |
continue; |
|
1343 |
} else |
||
1344 |
8 |
lungetc(next); |
|
1345 |
✗✓ | 8 |
} else if (c == quotec) { |
1346 |
*p = '\0'; |
||
1347 |
break; |
||
1348 |
} else if (c == '\0') { |
||
1349 |
yyerror("syntax error"); |
||
1350 |
return (findeol()); |
||
1351 |
} |
||
1352 |
if (p + 1 >= buf + sizeof(buf) - 1) { |
||
1353 |
yyerror("string too long"); |
||
1354 |
return (findeol()); |
||
1355 |
} |
||
1356 |
*p++ = c; |
||
1357 |
} |
||
1358 |
yylval.v.string = strdup(buf); |
||
1359 |
if (yylval.v.string == NULL) |
||
1360 |
fatal("yylex: strdup"); |
||
1361 |
return (STRING); |
||
1362 |
case '!': |
||
1363 |
next = lgetc(0); |
||
1364 |
if (next == '=') |
||
1365 |
return (NE); |
||
1366 |
lungetc(next); |
||
1367 |
break; |
||
1368 |
case '<': |
||
1369 |
next = lgetc(0); |
||
1370 |
if (next == '=') |
||
1371 |
return (LE); |
||
1372 |
lungetc(next); |
||
1373 |
break; |
||
1374 |
case '>': |
||
1375 |
next = lgetc(0); |
||
1376 |
if (next == '<') |
||
1377 |
return (XRANGE); |
||
1378 |
else if (next == '=') |
||
1379 |
return (GE); |
||
1380 |
lungetc(next); |
||
1381 |
break; |
||
1382 |
} |
||
1383 |
|||
1384 |
#define allowed_to_end_number(x) \ |
||
1385 |
(isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' || x == '=') |
||
1386 |
|||
1387 |
if (c == '-' || isdigit(c)) { |
||
1388 |
do { |
||
1389 |
*p++ = c; |
||
1390 |
if ((unsigned)(p-buf) >= sizeof(buf)) { |
||
1391 |
yyerror("string too long"); |
||
1392 |
return (findeol()); |
||
1393 |
} |
||
1394 |
} while ((c = lgetc(0)) != EOF && isdigit(c)); |
||
1395 |
lungetc(c); |
||
1396 |
if (p == buf + 1 && buf[0] == '-') |
||
1397 |
goto nodigits; |
||
1398 |
if (c == EOF || allowed_to_end_number(c)) { |
||
1399 |
const char *errstr = NULL; |
||
1400 |
|||
1401 |
*p = '\0'; |
||
1402 |
yylval.v.number = strtonum(buf, LLONG_MIN, |
||
1403 |
LLONG_MAX, &errstr); |
||
1404 |
if (errstr) { |
||
1405 |
yyerror("\"%s\" invalid number: %s", |
||
1406 |
buf, errstr); |
||
1407 |
return (findeol()); |
||
1408 |
} |
||
1409 |
return (NUMBER); |
||
1410 |
} else { |
||
1411 |
nodigits: |
||
1412 |
while (p > buf + 1) |
||
1413 |
lungetc(*--p); |
||
1414 |
c = *--p; |
||
1415 |
if (c == '-') |
||
1416 |
return (c); |
||
1417 |
} |
||
1418 |
} |
||
1419 |
|||
1420 |
#define allowed_in_string(x) \ |
||
1421 |
(isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \ |
||
1422 |
x != '{' && x != '}' && x != '<' && x != '>' && \ |
||
1423 |
x != '!' && x != '=' && x != '/' && x != '#' && \ |
||
1424 |
x != ',')) |
||
1425 |
|||
1426 |
if (isalnum(c) || c == ':' || c == '_' || c == '*') { |
||
1427 |
do { |
||
1428 |
*p++ = c; |
||
1429 |
if ((unsigned)(p-buf) >= sizeof(buf)) { |
||
1430 |
yyerror("string too long"); |
||
1431 |
return (findeol()); |
||
1432 |
} |
||
1433 |
} while ((c = lgetc(0)) != EOF && (allowed_in_string(c))); |
||
1434 |
lungetc(c); |
||
1435 |
*p = '\0'; |
||
1436 |
if ((token = lookup(buf)) == STRING) |
||
1437 |
if ((yylval.v.string = strdup(buf)) == NULL) |
||
1438 |
fatal("yylex: strdup"); |
||
1439 |
return (token); |
||
1440 |
} |
||
1441 |
if (c == '\n') { |
||
1442 |
yylval.lineno = file->lineno; |
||
1443 |
file->lineno++; |
||
1444 |
} |
||
1445 |
if (c == EOF) |
||
1446 |
return (0); |
||
1447 |
return (c); |
||
1448 |
} |
||
1449 |
|||
1450 |
int |
||
1451 |
check_file_secrecy(int fd, const char *fname) |
||
1452 |
{ |
||
1453 |
struct stat st; |
||
1454 |
|||
1455 |
if (fstat(fd, &st)) { |
||
1456 |
log_warn("cannot stat %s", fname); |
||
1457 |
return (-1); |
||
1458 |
} |
||
1459 |
return (0); |
||
1460 |
} |
||
1461 |
|||
1462 |
struct file * |
||
1463 |
12 |
pushfile(const char *name, int secret) |
|
1464 |
20 |
{ |
|
1465 |
8 |
struct file *nfile; |
|
1466 |
|||
1467 |
if ((nfile = calloc(1, sizeof(struct file))) == NULL) { |
||
1468 |
log_warn("malloc"); |
||
1469 |
return (NULL); |
||
1470 |
} |
||
1471 |
8 |
if ((nfile->name = strdup(name)) == NULL) { |
|
1472 |
✓✗✓✗ |
16 |
log_warn("malloc"); |
1473 |
free(nfile); |
||
1474 |
return (NULL); |
||
1475 |
✗✓✗✗ |
8 |
} |
1476 |
if ((nfile->stream = fopen(nfile->name, "r")) == NULL) { |
||
1477 |
log_warn("%s", nfile->name); |
||
1478 |
free(nfile->name); |
||
1479 |
free(nfile); |
||
1480 |
return (NULL); |
||
1481 |
} |
||
1482 |
if (secret && |
||
1483 |
check_file_secrecy(fileno(nfile->stream), nfile->name)) { |
||
1484 |
fclose(nfile->stream); |
||
1485 |
8 |
free(nfile->name); |
|
1486 |
free(nfile); |
||
1487 |
✗✓ | 8 |
return (NULL); |
1488 |
} |
||
1489 |
nfile->lineno = 1; |
||
1490 |
TAILQ_INSERT_TAIL(&files, nfile, entry); |
||
1491 |
return (nfile); |
||
1492 |
} |
||
1493 |
|||
1494 |
int |
||
1495 |
✗✓ | 16 |
popfile(void) |
1496 |
8 |
{ |
|
1497 |
struct file *prev; |
||
1498 |
|||
1499 |
if ((prev = TAILQ_PREV(file, files, entry)) != NULL) |
||
1500 |
prev->errors += file->errors; |
||
1501 |
|||
1502 |
TAILQ_REMOVE(&files, file, entry); |
||
1503 |
fclose(file->stream); |
||
1504 |
free(file->name); |
||
1505 |
184 |
free(file); |
|
1506 |
file = prev; |
||
1507 |
return (file ? 0 : EOF); |
||
1508 |
184 |
} |
|
1509 |
184 |
||
1510 |
184 |
int |
|
1511 |
184 |
parse_config(char *filename, struct bgpd_config *xconf, struct peer **xpeers) |
|
1512 |
✗✓ | 184 |
{ |
1513 |
struct sym *sym, *next; |
||
1514 |
struct peer *p, *pnext; |
||
1515 |
struct rde_rib *rr; |
||
1516 |
int errors = 0; |
||
1517 |
|||
1518 |
conf = new_config(); |
||
1519 |
|||
1520 |
if ((filter_l = calloc(1, sizeof(struct filter_head))) == NULL) |
||
1521 |
fatal(NULL); |
||
1522 |
if ((peerfilter_l = calloc(1, sizeof(struct filter_head))) == NULL) |
||
1523 |
fatal(NULL); |
||
1524 |
✗✓ | 184 |
if ((groupfilter_l = calloc(1, sizeof(struct filter_head))) == NULL) |
1525 |
fatal(NULL); |
||
1526 |
✗✓ | 368 |
TAILQ_INIT(filter_l); |
1527 |
TAILQ_INIT(peerfilter_l); |
||
1528 |
TAILQ_INIT(groupfilter_l); |
||
1529 |
48 |
||
1530 |
180 |
peer_l = NULL; |
|
1531 |
136 |
peer_l_old = *xpeers; |
|
1532 |
4 |
curpeer = NULL; |
|
1533 |
curgroup = NULL; |
||
1534 |
184 |
id = 1; |
|
1535 |
184 |
||
1536 |
netconf = &conf->networks; |
||
1537 |
|||
1538 |
176 |
add_rib("Adj-RIB-In", conf->default_tableid, |
|
1539 |
184 |
F_RIB_NOFIB | F_RIB_NOEVALUATE); |
|
1540 |
8 |
add_rib("Loc-RIB", conf->default_tableid, F_RIB_LOCAL); |
|
1541 |
|||
1542 |
184 |
if ((file = pushfile(filename, 1)) == NULL) { |
|
1543 |
184 |
free(conf); |
|
1544 |
return (-1); |
||
1545 |
} |
||
1546 |
topfile = file; |
||
1547 |
|||
1548 |
yyparse(); |
||
1549 |
errors = file->errors; |
||
1550 |
popfile(); |
||
1551 |
|||
1552 |
/* Free macros and check which have not been used. */ |
||
1553 |
TAILQ_FOREACH_SAFE(sym, &symhead, entry, next) { |
||
1554 |
if ((cmd_opts & BGPD_OPT_VERBOSE2) && !sym->used) |
||
1555 |
fprintf(stderr, "warning: macro \"%s\" not " |
||
1556 |
"used\n", sym->nam); |
||
1557 |
if (!sym->persist) { |
||
1558 |
free(sym->nam); |
||
1559 |
free(sym->val); |
||
1560 |
TAILQ_REMOVE(&symhead, sym, entry); |
||
1561 |
free(sym); |
||
1562 |
} |
||
1563 |
} |
||
1564 |
|||
1565 |
if (errors) { |
||
1566 |
for (p = peer_l; p != NULL; p = pnext) { |
||
1567 |
pnext = p->next; |
||
1568 |
free(p); |
||
1569 |
} |
||
1570 |
|||
1571 |
while ((rr = SIMPLEQ_FIRST(&ribnames)) != NULL) { |
||
1572 |
SIMPLEQ_REMOVE_HEAD(&ribnames, entry); |
||
1573 |
free(rr); |
||
1574 |
} |
||
1575 |
|||
1576 |
filterlist_free(filter_l); |
||
1577 |
filterlist_free(peerfilter_l); |
||
1578 |
filterlist_free(groupfilter_l); |
||
1579 |
|||
1580 |
free_config(conf); |
||
1581 |
} else { |
||
1582 |
/* |
||
1583 |
* Move filter list and static group and peer filtersets |
||
1584 |
* together. Static group sets come first then peer sets |
||
1585 |
* last normal filter rules. |
||
1586 |
*/ |
||
1587 |
✗✓ | 168 |
merge_filter_lists(conf->filters, groupfilter_l); |
1588 |
merge_filter_lists(conf->filters, peerfilter_l); |
||
1589 |
merge_filter_lists(conf->filters, filter_l); |
||
1590 |
168 |
||
1591 |
168 |
errors += mrt_mergeconfig(xconf->mrt, conf->mrt); |
|
1592 |
errors += merge_config(xconf, conf, peer_l); |
||
1593 |
168 |
*xpeers = peer_l; |
|
1594 |
|||
1595 |
for (p = peer_l_old; p != NULL; p = pnext) { |
||
1596 |
pnext = p->next; |
||
1597 |
free(p); |
||
1598 |
} |
||
1599 |
|||
1600 |
free(filter_l); |
||
1601 |
free(peerfilter_l); |
||
1602 |
free(groupfilter_l); |
||
1603 |
} |
||
1604 |
|||
1605 |
return (errors ? -1 : 0); |
||
1606 |
} |
||
1607 |
|||
1608 |
int |
||
1609 |
symset(const char *nam, const char *val, int persist) |
||
1610 |
{ |
||
1611 |
struct sym *sym; |
||
1612 |
|||
1613 |
TAILQ_FOREACH(sym, &symhead, entry) { |
||
1614 |
if (strcmp(nam, sym->nam) == 0) |
||
1615 |
break; |
||
1616 |
} |
||
1617 |
|||
1618 |
if (sym != NULL) { |
||
1619 |
if (sym->persist == 1) |
||
1620 |
return (0); |
||
1621 |
else { |
||
1622 |
free(sym->nam); |
||
1623 |
free(sym->val); |
||
1624 |
TAILQ_REMOVE(&symhead, sym, entry); |
||
1625 |
free(sym); |
||
1626 |
} |
||
1627 |
} |
||
1628 |
if ((sym = calloc(1, sizeof(*sym))) == NULL) |
||
1629 |
return (-1); |
||
1630 |
|||
1631 |
sym->nam = strdup(nam); |
||
1632 |
if (sym->nam == NULL) { |
||
1633 |
free(sym); |
||
1634 |
return (-1); |
||
1635 |
} |
||
1636 |
sym->val = strdup(val); |
||
1637 |
if (sym->val == NULL) { |
||
1638 |
free(sym->nam); |
||
1639 |
free(sym); |
||
1640 |
return (-1); |
||
1641 |
} |
||
1642 |
✗✓ | 8 |
sym->used = 0; |
1643 |
sym->persist = persist; |
||
1644 |
TAILQ_INSERT_TAIL(&symhead, sym, entry); |
||
1645 |
8 |
return (0); |
|
1646 |
} |
||
1647 |
8 |
||
1648 |
✗✓ | 8 |
int |
1649 |
cmdline_symset(char *s) |
||
1650 |
{ |
||
1651 |
8 |
char *sym, *val; |
|
1652 |
int ret; |
||
1653 |
8 |
size_t len; |
|
1654 |
|||
1655 |
if ((val = strrchr(s, '=')) == NULL) |
||
1656 |
✗✓ | 4 |
return (-1); |
1657 |
|||
1658 |
✗✓ | 4 |
len = strlen(s) - strlen(val) + 1; |
1659 |
if ((sym = malloc(len)) == NULL) |
||
1660 |
fatal("cmdline_symset: malloc"); |
||
1661 |
4 |
||
1662 |
✗✓ | 4 |
strlcpy(sym, s, len); |
1663 |
|||
1664 |
ret = symset(sym, val + 1, 1); |
||
1665 |
free(sym); |
||
1666 |
|||
1667 |
return (ret); |
||
1668 |
✗✓ | 4 |
} |
1669 |
|||
1670 |
✗✓ | 4 |
char * |
1671 |
symget(const char *nam) |
||
1672 |
{ |
||
1673 |
4 |
struct sym *sym; |
|
1674 |
✗✓ | 4 |
|
1675 |
TAILQ_FOREACH(sym, &symhead, entry) { |
||
1676 |
if (strcmp(nam, sym->nam) == 0) { |
||
1677 |
sym->used = 1; |
||
1678 |
return (sym->val); |
||
1679 |
96 |
} |
|
1680 |
96 |
} |
|
1681 |
return (NULL); |
||
1682 |
} |
||
1683 |
|||
1684 |
int |
||
1685 |
getcommunity(char *s) |
||
1686 |
{ |
||
1687 |
int val; |
||
1688 |
const char *errstr; |
||
1689 |
|||
1690 |
if (strcmp(s, "*") == 0) |
||
1691 |
return (COMMUNITY_ANY); |
||
1692 |
if (strcmp(s, "neighbor-as") == 0) |
||
1693 |
return (COMMUNITY_NEIGHBOR_AS); |
||
1694 |
if (strcmp(s, "local-as") == 0) |
||
1695 |
return (COMMUNITY_LOCAL_AS); |
||
1696 |
val = strtonum(s, 0, USHRT_MAX, &errstr); |
||
1697 |
if (errstr) { |
||
1698 |
yyerror("Community %s is %s (max: %u)", s, errstr, USHRT_MAX); |
||
1699 |
return (COMMUNITY_ERROR); |
||
1700 |
} |
||
1701 |
return (val); |
||
1702 |
} |
||
1703 |
|||
1704 |
int |
||
1705 |
✗✓ | 96 |
parsecommunity(struct filter_community *c, char *s) |
1706 |
{ |
||
1707 |
char *p; |
||
1708 |
96 |
int i, as; |
|
1709 |
|||
1710 |
96 |
/* Well-known communities */ |
|
1711 |
if (strcasecmp(s, "GRACEFUL_SHUTDOWN") == 0) { |
||
1712 |
✗✓ | 96 |
c->as = COMMUNITY_WELLKNOWN; |
1713 |
c->type = COMMUNITY_GRACEFUL_SHUTDOWN; |
||
1714 |
return (0); |
||
1715 |
} else if (strcasecmp(s, "NO_EXPORT") == 0) { |
||
1716 |
c->as = COMMUNITY_WELLKNOWN; |
||
1717 |
c->type = COMMUNITY_NO_EXPORT; |
||
1718 |
return (0); |
||
1719 |
} else if (strcasecmp(s, "NO_ADVERTISE") == 0) { |
||
1720 |
c->as = COMMUNITY_WELLKNOWN; |
||
1721 |
c->type = COMMUNITY_NO_ADVERTISE; |
||
1722 |
return (0); |
||
1723 |
} else if (strcasecmp(s, "NO_EXPORT_SUBCONFED") == 0) { |
||
1724 |
c->as = COMMUNITY_WELLKNOWN; |
||
1725 |
c->type = COMMUNITY_NO_EXPSUBCONFED; |
||
1726 |
return (0); |
||
1727 |
} else if (strcasecmp(s, "NO_PEER") == 0) { |
||
1728 |
c->as = COMMUNITY_WELLKNOWN; |
||
1729 |
c->type = COMMUNITY_NO_PEER; |
||
1730 |
return (0); |
||
1731 |
} else if (strcasecmp(s, "BLACKHOLE") == 0) { |
||
1732 |
c->as = COMMUNITY_WELLKNOWN; |
||
1733 |
c->type = COMMUNITY_BLACKHOLE; |
||
1734 |
return (0); |
||
1735 |
} |
||
1736 |
|||
1737 |
32 |
if ((p = strchr(s, ':')) == NULL) { |
|
1738 |
32 |
yyerror("Bad community syntax"); |
|
1739 |
return (-1); |
||
1740 |
32 |
} |
|
1741 |
*p++ = 0; |
||
1742 |
|||
1743 |
if ((i = getcommunity(s)) == COMMUNITY_ERROR) |
||
1744 |
return (-1); |
||
1745 |
as = i; |
||
1746 |
|||
1747 |
if ((i = getcommunity(p)) == COMMUNITY_ERROR) |
||
1748 |
return (-1); |
||
1749 |
c->as = as; |
||
1750 |
c->type = i; |
||
1751 |
|||
1752 |
return (0); |
||
1753 |
} |
||
1754 |
|||
1755 |
int64_t |
||
1756 |
getlargecommunity(char *s) |
||
1757 |
{ |
||
1758 |
u_int val; |
||
1759 |
const char *errstr; |
||
1760 |
|||
1761 |
if (strcmp(s, "*") == 0) |
||
1762 |
return (COMMUNITY_ANY); |
||
1763 |
if (strcmp(s, "neighbor-as") == 0) |
||
1764 |
return (COMMUNITY_NEIGHBOR_AS); |
||
1765 |
if (strcmp(s, "local-as") == 0) |
||
1766 |
return (COMMUNITY_LOCAL_AS); |
||
1767 |
val = strtonum(s, 0, UINT_MAX, &errstr); |
||
1768 |
if (errstr) { |
||
1769 |
yyerror("Large Community %s is %s (max: %u)", |
||
1770 |
s, errstr, UINT_MAX); |
||
1771 |
return (COMMUNITY_ERROR); |
||
1772 |
✗✓ | 12 |
} |
1773 |
return (val); |
||
1774 |
} |
||
1775 |
12 |
||
1776 |
12 |
int |
|
1777 |
parselargecommunity(struct filter_largecommunity *c, char *s) |
||
1778 |
12 |
{ |
|
1779 |
char *p, *q; |
||
1780 |
int64_t as, ld1, ld2; |
||
1781 |
|||
1782 |
if ((p = strchr(s, ':')) == NULL) { |
||
1783 |
yyerror("Bad community syntax"); |
||
1784 |
return (-1); |
||
1785 |
} |
||
1786 |
*p++ = 0; |
||
1787 |
|||
1788 |
if ((q = strchr(p, ':')) == NULL) { |
||
1789 |
yyerror("Bad community syntax"); |
||
1790 |
return (-1); |
||
1791 |
} |
||
1792 |
✗✓ | 20 |
*q++ = 0; |
1793 |
|||
1794 |
if ((as = getlargecommunity(s)) == COMMUNITY_ERROR) |
||
1795 |
✗✓ | 20 |
return (-1); |
1796 |
|||
1797 |
if ((ld1 = getlargecommunity(p)) == COMMUNITY_ERROR) |
||
1798 |
return (-1); |
||
1799 |
20 |
||
1800 |
20 |
if ((ld2 = getlargecommunity(q)) == COMMUNITY_ERROR) |
|
1801 |
20 |
return (-1); |
|
1802 |
|||
1803 |
20 |
c->as = as; |
|
1804 |
c->ld1 = ld1; |
||
1805 |
c->ld2 = ld2; |
||
1806 |
16 |
||
1807 |
16 |
return (0); |
|
1808 |
16 |
} |
|
1809 |
|||
1810 |
16 |
int |
|
1811 |
168 |
parsesubtype(char *name, int *type, int *subtype) |
|
1812 |
168 |
{ |
|
1813 |
168 |
const struct ext_comm_pairs *cp; |
|
1814 |
int found = 0; |
||
1815 |
168 |
||
1816 |
168 |
for (cp = iana_ext_comms; cp->subname != NULL; cp++) { |
|
1817 |
if (strcmp(name, cp->subname) == 0) { |
||
1818 |
168 |
if (found == 0) { |
|
1819 |
*type = cp->type; |
||
1820 |
*subtype = cp->subtype; |
||
1821 |
} |
||
1822 |
found++; |
||
1823 |
} |
||
1824 |
} |
||
1825 |
✗✓ | 104 |
if (found > 1) |
1826 |
*type = -1; |
||
1827 |
return (found); |
||
1828 |
} |
||
1829 |
104 |
||
1830 |
int |
||
1831 |
104 |
parseextvalue(char *s, u_int32_t *v) |
|
1832 |
✗✓ | 32 |
{ |
1833 |
const char *errstr; |
||
1834 |
char *p; |
||
1835 |
struct in_addr ip; |
||
1836 |
32 |
u_int32_t uvalh = 0, uval; |
|
1837 |
|||
1838 |
32 |
if ((p = strchr(s, '.')) == NULL) { |
|
1839 |
/* AS_PLAIN number (4 or 2 byte) */ |
||
1840 |
uval = strtonum(s, 0, UINT_MAX, &errstr); |
||
1841 |
if (errstr) { |
||
1842 |
yyerror("Bad ext-community %s is %s", s, errstr); |
||
1843 |
return (-1); |
||
1844 |
} |
||
1845 |
*v = uval; |
||
1846 |
if (uval <= USHRT_MAX) |
||
1847 |
return (EXT_COMMUNITY_TRANS_TWO_AS); |
||
1848 |
else |
||
1849 |
return (EXT_COMMUNITY_TRANS_FOUR_AS); |
||
1850 |
} else if (strchr(p + 1, '.') == NULL) { |
||
1851 |
/* AS_DOT number (4-byte) */ |
||
1852 |
*p++ = '\0'; |
||
1853 |
uvalh = strtonum(s, 0, USHRT_MAX, &errstr); |
||
1854 |
if (errstr) { |
||
1855 |
yyerror("Bad ext-community %s is %s", s, errstr); |
||
1856 |
return (-1); |
||
1857 |
} |
||
1858 |
uval = strtonum(p, 0, USHRT_MAX, &errstr); |
||
1859 |
if (errstr) { |
||
1860 |
yyerror("Bad ext-community %s is %s", p, errstr); |
||
1861 |
return (-1); |
||
1862 |
} |
||
1863 |
✗✓ | 8 |
*v = uval | (uvalh << 16); |
1864 |
return (EXT_COMMUNITY_TRANS_FOUR_AS); |
||
1865 |
} else { |
||
1866 |
/* more than one dot -> IP address */ |
||
1867 |
if (inet_aton(s, &ip) == 0) { |
||
1868 |
✗✓ | 16 |
yyerror("Bad ext-community %s not parseable", s); |
1869 |
8 |
return (-1); |
|
1870 |
} |
||
1871 |
*v = ip.s_addr; |
||
1872 |
return (EXT_COMMUNITY_TRANS_IPV4); |
||
1873 |
} |
||
1874 |
return (-1); |
||
1875 |
✗✓ | 4 |
} |
1876 |
|||
1877 |
int |
||
1878 |
parseextcommunity(struct filter_extcommunity *c, char *t, char *s) |
||
1879 |
{ |
||
1880 |
✗✓ | 8 |
const struct ext_comm_pairs *cp; |
1881 |
4 |
const char *errstr; |
|
1882 |
u_int64_t ullval; |
||
1883 |
u_int32_t uval; |
||
1884 |
char *p, *ep; |
||
1885 |
int type, subtype; |
||
1886 |
|||
1887 |
✗✓ | 20 |
if (parsesubtype(t, &type, &subtype) == 0) { |
1888 |
yyerror("Bad ext-community unknown type"); |
||
1889 |
return (-1); |
||
1890 |
} |
||
1891 |
|||
1892 |
switch (type) { |
||
1893 |
case -1: |
||
1894 |
if ((p = strchr(s, ':')) == NULL) { |
||
1895 |
✗✓ | 40 |
yyerror("Bad ext-community %s", s); |
1896 |
40 |
return (-1); |
|
1897 |
20 |
} |
|
1898 |
20 |
*p++ = '\0'; |
|
1899 |
if ((type = parseextvalue(s, &uval)) == -1) |
||
1900 |
return (-1); |
||
1901 |
switch (type) { |
||
1902 |
case EXT_COMMUNITY_TRANS_TWO_AS: |
||
1903 |
ullval = strtonum(p, 0, UINT_MAX, &errstr); |
||
1904 |
break; |
||
1905 |
case EXT_COMMUNITY_TRANS_IPV4: |
||
1906 |
case EXT_COMMUNITY_TRANS_FOUR_AS: |
||
1907 |
ullval = strtonum(p, 0, USHRT_MAX, &errstr); |
||
1908 |
break; |
||
1909 |
default: |
||
1910 |
fatalx("parseextcommunity: unexpected result"); |
||
1911 |
} |
||
1912 |
if (errstr) { |
||
1913 |
yyerror("Bad ext-community %s is %s", p, errstr); |
||
1914 |
return (-1); |
||
1915 |
} |
||
1916 |
switch (type) { |
||
1917 |
case EXT_COMMUNITY_TRANS_TWO_AS: |
||
1918 |
c->data.ext_as.as = uval; |
||
1919 |
c->data.ext_as.val = ullval; |
||
1920 |
break; |
||
1921 |
case EXT_COMMUNITY_TRANS_IPV4: |
||
1922 |
c->data.ext_ip.addr.s_addr = uval; |
||
1923 |
c->data.ext_ip.val = ullval; |
||
1924 |
break; |
||
1925 |
case EXT_COMMUNITY_TRANS_FOUR_AS: |
||
1926 |
c->data.ext_as4.as4 = uval; |
||
1927 |
c->data.ext_as4.val = ullval; |
||
1928 |
92 |
break; |
|
1929 |
✓✗✗✓ |
184 |
} |
1930 |
break; |
||
1931 |
case EXT_COMMUNITY_TRANS_OPAQUE: |
||
1932 |
case EXT_COMMUNITY_TRANS_EVPN: |
||
1933 |
✗✓✗✗ |
92 |
errno = 0; |
1934 |
ullval = strtoull(s, &ep, 0); |
||
1935 |
if (s[0] == '\0' || *ep != '\0') { |
||
1936 |
yyerror("Bad ext-community bad value"); |
||
1937 |
92 |
return (-1); |
|
1938 |
92 |
} |
|
1939 |
if (errno == ERANGE && ullval > EXT_COMMUNITY_OPAQUE_MAX) { |
||
1940 |
92 |
yyerror("Bad ext-community value too big"); |
|
1941 |
12 |
return (-1); |
|
1942 |
✓✗✓✗ ✓✗✗✓ |
48 |
} |
1943 |
c->data.ext_opaq = ullval; |
||
1944 |
break; |
||
1945 |
case EXT_COMMUNITY_NON_TRANS_OPAQUE: |
||
1946 |
✗✓ | 12 |
if (strcmp(s, "valid") == 0) |
1947 |
c->data.ext_opaq = EXT_COMMUNITY_OVS_VALID; |
||
1948 |
else if (strcmp(s, "invalid") == 0) |
||
1949 |
c->data.ext_opaq = EXT_COMMUNITY_OVS_INVALID; |
||
1950 |
12 |
else if (strcmp(s, "not-found") == 0) |
|
1951 |
12 |
c->data.ext_opaq = EXT_COMMUNITY_OVS_NOTFOUND; |
|
1952 |
12 |
else { |
|
1953 |
yyerror("Bad ext-community %s", s); |
||
1954 |
12 |
return (-1); |
|
1955 |
} |
||
1956 |
32 |
break; |
|
1957 |
32 |
} |
|
1958 |
c->type = type; |
||
1959 |
c->subtype = subtype; |
||
1960 |
|||
1961 |
/* verify type/subtype combo */ |
||
1962 |
180 |
for (cp = iana_ext_comms; cp->subname != NULL; cp++) { |
|
1963 |
180 |
if (cp->type == type && cp->subtype == subtype) { |
|
1964 |
c->flags |= EXT_COMMUNITY_FLAG_VALID; |
||
1965 |
return (0); |
||
1966 |
} |
||
1967 |
} |
||
1968 |
|||
1969 |
yyerror("Bad ext-community bad format for type"); |
||
1970 |
4 |
return (-1); |
|
1971 |
4 |
} |
|
1972 |
|||
1973 |
struct peer * |
||
1974 |
alloc_peer(void) |
||
1975 |
{ |
||
1976 |
struct peer *p; |
||
1977 |
u_int8_t i; |
||
1978 |
|||
1979 |
✗✓ | 4 |
if ((p = calloc(1, sizeof(struct peer))) == NULL) |
1980 |
fatal("new_peer"); |
||
1981 |
|||
1982 |
4 |
/* some sane defaults */ |
|
1983 |
4 |
p->state = STATE_NONE; |
|
1984 |
p->next = NULL; |
||
1985 |
4 |
p->conf.distance = 1; |
|
1986 |
p->conf.announce_type = ANNOUNCE_UNDEF; |
||
1987 |
p->conf.announce_capa = 1; |
||
1988 |
for (i = 0; i < AID_MAX; i++) |
||
1989 |
p->conf.capabilities.mp[i] = -1; |
||
1990 |
p->conf.capabilities.refresh = 1; |
||
1991 |
p->conf.capabilities.grestart.restart = 1; |
||
1992 |
✓✗✗✓ |
8 |
p->conf.capabilities.as4byte = 1; |
1993 |
p->conf.local_as = conf->as; |
||
1994 |
p->conf.local_short_as = conf->short_as; |
||
1995 |
|||
1996 |
✗✓ | 4 |
return (p); |
1997 |
} |
||
1998 |
4 |
||
1999 |
struct peer * |
||
2000 |
new_peer(void) |
||
2001 |
{ |
||
2002 |
struct peer *p; |
||
2003 |
|||
2004 |
p = alloc_peer(); |
||
2005 |
|||
2006 |
4 |
if (curgroup != NULL) { |
|
2007 |
memcpy(p, curgroup, sizeof(struct peer)); |
||
2008 |
if (strlcpy(p->conf.group, curgroup->conf.group, |
||
2009 |
sizeof(p->conf.group)) >= sizeof(p->conf.group)) |
||
2010 |
fatalx("new_peer group strlcpy"); |
||
2011 |
if (strlcpy(p->conf.descr, curgroup->conf.descr, |
||
2012 |
sizeof(p->conf.descr)) >= sizeof(p->conf.descr)) |
||
2013 |
fatalx("new_peer descr strlcpy"); |
||
2014 |
p->conf.groupid = curgroup->conf.id; |
||
2015 |
p->conf.local_as = curgroup->conf.local_as; |
||
2016 |
p->conf.local_short_as = curgroup->conf.local_short_as; |
||
2017 |
} |
||
2018 |
p->next = NULL; |
||
2019 |
if (conf->flags & BGPD_FLAG_DECISION_TRANS_AS) |
||
2020 |
p->conf.flags |= PEERFLAG_TRANS_AS; |
||
2021 |
return (p); |
||
2022 |
} |
||
2023 |
|||
2024 |
struct peer * |
||
2025 |
new_group(void) |
||
2026 |
{ |
||
2027 |
return (alloc_peer()); |
||
2028 |
} |
||
2029 |
|||
2030 |
int |
||
2031 |
add_mrtconfig(enum mrt_type type, char *name, int timeout, struct peer *p, |
||
2032 |
char *rib) |
||
2033 |
{ |
||
2034 |
struct mrt *m, *n; |
||
2035 |
|||
2036 |
LIST_FOREACH(m, conf->mrt, entry) { |
||
2037 |
if ((rib && strcmp(rib, m->rib)) || |
||
2038 |
(!rib && *m->rib)) |
||
2039 |
continue; |
||
2040 |
if (p == NULL) { |
||
2041 |
if (m->peer_id != 0 || m->group_id != 0) |
||
2042 |
continue; |
||
2043 |
} else { |
||
2044 |
if (m->peer_id != p->conf.id || |
||
2045 |
m->group_id != p->conf.groupid) |
||
2046 |
continue; |
||
2047 |
} |
||
2048 |
if (m->type == type) { |
||
2049 |
yyerror("only one mrtdump per type allowed."); |
||
2050 |
return (-1); |
||
2051 |
} |
||
2052 |
} |
||
2053 |
|||
2054 |
if ((n = calloc(1, sizeof(struct mrt_config))) == NULL) |
||
2055 |
fatal("add_mrtconfig"); |
||
2056 |
|||
2057 |
n->type = type; |
||
2058 |
if (strlcpy(MRT2MC(n)->name, name, sizeof(MRT2MC(n)->name)) >= |
||
2059 |
sizeof(MRT2MC(n)->name)) { |
||
2060 |
yyerror("filename \"%s\" too long: max %zu", |
||
2061 |
name, sizeof(MRT2MC(n)->name) - 1); |
||
2062 |
free(n); |
||
2063 |
return (-1); |
||
2064 |
} |
||
2065 |
MRT2MC(n)->ReopenTimerInterval = timeout; |
||
2066 |
if (p != NULL) { |
||
2067 |
if (curgroup == p) { |
||
2068 |
n->peer_id = 0; |
||
2069 |
n->group_id = p->conf.id; |
||
2070 |
} else { |
||
2071 |
n->peer_id = p->conf.id; |
||
2072 |
n->group_id = 0; |
||
2073 |
} |
||
2074 |
} |
||
2075 |
if (rib) { |
||
2076 |
if (!find_rib(rib)) { |
||
2077 |
yyerror("rib \"%s\" does not exist.", rib); |
||
2078 |
free(n); |
||
2079 |
return (-1); |
||
2080 |
} |
||
2081 |
if (strlcpy(n->rib, rib, sizeof(n->rib)) >= |
||
2082 |
sizeof(n->rib)) { |
||
2083 |
yyerror("rib name \"%s\" too long: max %zu", |
||
2084 |
name, sizeof(n->rib) - 1); |
||
2085 |
free(n); |
||
2086 |
return (-1); |
||
2087 |
} |
||
2088 |
} |
||
2089 |
|||
2090 |
LIST_INSERT_HEAD(conf->mrt, n, entry); |
||
2091 |
|||
2092 |
return (0); |
||
2093 |
} |
||
2094 |
|||
2095 |
int |
||
2096 |
add_rib(char *name, u_int rtableid, u_int16_t flags) |
||
2097 |
{ |
||
2098 |
struct rde_rib *rr; |
||
2099 |
u_int rdom, default_rdom; |
||
2100 |
|||
2101 |
if ((rr = find_rib(name)) == NULL) { |
||
2102 |
if ((rr = calloc(1, sizeof(*rr))) == NULL) { |
||
2103 |
log_warn("add_rib"); |
||
2104 |
return (-1); |
||
2105 |
} |
||
2106 |
} |
||
2107 |
if (strlcpy(rr->name, name, sizeof(rr->name)) >= sizeof(rr->name)) { |
||
2108 |
yyerror("rib name \"%s\" too long: max %zu", |
||
2109 |
name, sizeof(rr->name) - 1); |
||
2110 |
free(rr); |
||
2111 |
return (-1); |
||
2112 |
} |
||
2113 |
rr->flags |= flags; |
||
2114 |
if ((rr->flags & F_RIB_HASNOFIB) == 0) { |
||
2115 |
if (ktable_exists(rtableid, &rdom) != 1) { |
||
2116 |
yyerror("rtable id %u does not exist", rtableid); |
||
2117 |
free(rr); |
||
2118 |
return (-1); |
||
2119 |
} |
||
2120 |
if (ktable_exists(conf->default_tableid, &default_rdom) != 1) |
||
2121 |
fatal("default rtable %u does not exist", |
||
2122 |
conf->default_tableid); |
||
2123 |
if (rdom != default_rdom) { |
||
2124 |
log_warnx("rtable %u does not belong to rdomain %u", |
||
2125 |
rtableid, default_rdom); |
||
2126 |
free(rr); |
||
2127 |
return (-1); |
||
2128 |
} |
||
2129 |
rr->rtableid = rtableid; |
||
2130 |
} |
||
2131 |
SIMPLEQ_INSERT_TAIL(&ribnames, rr, entry); |
||
2132 |
return (0); |
||
2133 |
} |
||
2134 |
|||
2135 |
struct rde_rib * |
||
2136 |
find_rib(char *name) |
||
2137 |
{ |
||
2138 |
struct rde_rib *rr; |
||
2139 |
|||
2140 |
SIMPLEQ_FOREACH(rr, &ribnames, entry) { |
||
2141 |
if (!strcmp(rr->name, name)) |
||
2142 |
return (rr); |
||
2143 |
} |
||
2144 |
return (NULL); |
||
2145 |
} |
||
2146 |
|||
2147 |
int |
||
2148 |
get_id(struct peer *newpeer) |
||
2149 |
{ |
||
2150 |
struct peer *p; |
||
2151 |
|||
2152 |
for (p = peer_l_old; p != NULL; p = p->next) |
||
2153 |
if (newpeer->conf.remote_addr.aid) { |
||
2154 |
if (!memcmp(&p->conf.remote_addr, |
||
2155 |
&newpeer->conf.remote_addr, |
||
2156 |
sizeof(p->conf.remote_addr))) { |
||
2157 |
newpeer->conf.id = p->conf.id; |
||
2158 |
return (0); |
||
2159 |
} |
||
2160 |
} else { /* newpeer is a group */ |
||
2161 |
if (strcmp(newpeer->conf.group, p->conf.group) == 0) { |
||
2162 |
newpeer->conf.id = p->conf.groupid; |
||
2163 |
return (0); |
||
2164 |
} |
||
2165 |
} |
||
2166 |
|||
2167 |
/* new one */ |
||
2168 |
for (; id < UINT_MAX / 2; id++) { |
||
2169 |
for (p = peer_l_old; p != NULL && |
||
2170 |
p->conf.id != id && p->conf.groupid != id; p = p->next) |
||
2171 |
; /* nothing */ |
||
2172 |
if (p == NULL) { /* we found a free id */ |
||
2173 |
newpeer->conf.id = id++; |
||
2174 |
return (0); |
||
2175 |
} |
||
2176 |
} |
||
2177 |
|||
2178 |
return (-1); |
||
2179 |
} |
||
2180 |
|||
2181 |
int |
||
2182 |
merge_prefixspec(struct filter_prefix_l *p, struct filter_prefixlen *pl) |
||
2183 |
{ |
||
2184 |
u_int8_t max_len = 0; |
||
2185 |
|||
2186 |
switch (p->p.addr.aid) { |
||
2187 |
case AID_INET: |
||
2188 |
case AID_VPN_IPv4: |
||
2189 |
max_len = 32; |
||
2190 |
break; |
||
2191 |
case AID_INET6: |
||
2192 |
max_len = 128; |
||
2193 |
break; |
||
2194 |
} |
||
2195 |
|||
2196 |
switch (pl->op) { |
||
2197 |
case OP_NONE: |
||
2198 |
return (0); |
||
2199 |
case OP_RANGE: |
||
2200 |
case OP_XRANGE: |
||
2201 |
if (pl->len_min > max_len || pl->len_max > max_len) { |
||
2202 |
yyerror("prefixlen %d too big for AF, limit %d", |
||
2203 |
pl->len_min > max_len ? pl->len_min : pl->len_max, |
||
2204 |
max_len); |
||
2205 |
return (-1); |
||
2206 |
} |
||
2207 |
if (pl->len_min < p->p.len) { |
||
2208 |
yyerror("prefixlen %d smaller than prefix, limit %d", |
||
2209 |
pl->len_min, p->p.len); |
||
2210 |
return (-1); |
||
2211 |
} |
||
2212 |
p->p.len_max = pl->len_max; |
||
2213 |
break; |
||
2214 |
case OP_GE: |
||
2215 |
/* fix up the "or-longer" case */ |
||
2216 |
if (pl->len_min == -1) |
||
2217 |
pl->len_min = p->p.len; |
||
2218 |
/* FALLTHROUGH */ |
||
2219 |
case OP_EQ: |
||
2220 |
case OP_NE: |
||
2221 |
case OP_LE: |
||
2222 |
case OP_GT: |
||
2223 |
if (pl->len_min > max_len) { |
||
2224 |
yyerror("prefixlen %d too big for AF, limit %d", |
||
2225 |
pl->len_min, max_len); |
||
2226 |
return (-1); |
||
2227 |
} |
||
2228 |
if (pl->len_min < p->p.len) { |
||
2229 |
yyerror("prefixlen %d smaller than prefix, limit %d", |
||
2230 |
pl->len_min, p->p.len); |
||
2231 |
return (-1); |
||
2232 |
} |
||
2233 |
break; |
||
2234 |
case OP_LT: |
||
2235 |
if (pl->len_min > max_len - 1) { |
||
2236 |
yyerror("prefixlen %d too big for AF, limit %d", |
||
2237 |
pl->len_min, max_len - 1); |
||
2238 |
return (-1); |
||
2239 |
} |
||
2240 |
if (pl->len_min < p->p.len + 1) { |
||
2241 |
yyerror("prefixlen %d too small for prefix, limit %d", |
||
2242 |
pl->len_min, p->p.len + 1); |
||
2243 |
return (-1); |
||
2244 |
} |
||
2245 |
break; |
||
2246 |
} |
||
2247 |
|||
2248 |
p->p.op = pl->op; |
||
2249 |
p->p.len_min = pl->len_min; |
||
2250 |
return (0); |
||
2251 |
} |
||
2252 |
|||
2253 |
int |
||
2254 |
expand_rule(struct filter_rule *rule, struct filter_rib_l *rib, |
||
2255 |
struct filter_peers_l *peer, struct filter_match_l *match, |
||
2256 |
struct filter_set_head *set) |
||
2257 |
{ |
||
2258 |
struct filter_rule *r; |
||
2259 |
struct filter_rib_l *rb, *rbnext; |
||
2260 |
struct filter_peers_l *p, *pnext; |
||
2261 |
struct filter_prefix_l *prefix, *prefix_next; |
||
2262 |
struct filter_as_l *a, *anext; |
||
2263 |
struct filter_set *s; |
||
2264 |
|||
2265 |
rb = rib; |
||
2266 |
do { |
||
2267 |
p = peer; |
||
2268 |
do { |
||
2269 |
a = match->as_l; |
||
2270 |
do { |
||
2271 |
prefix = match->prefix_l; |
||
2272 |
do { |
||
2273 |
if ((r = calloc(1, |
||
2274 |
sizeof(struct filter_rule))) == |
||
2275 |
NULL) { |
||
2276 |
log_warn("expand_rule"); |
||
2277 |
return (-1); |
||
2278 |
} |
||
2279 |
|||
2280 |
memcpy(r, rule, sizeof(struct filter_rule)); |
||
2281 |
memcpy(&r->match, match, |
||
2282 |
sizeof(struct filter_match)); |
||
2283 |
TAILQ_INIT(&r->set); |
||
2284 |
copy_filterset(set, &r->set); |
||
2285 |
|||
2286 |
if (rb != NULL) |
||
2287 |
strlcpy(r->rib, rb->name, |
||
2288 |
sizeof(r->rib)); |
||
2289 |
|||
2290 |
if (p != NULL) |
||
2291 |
memcpy(&r->peer, &p->p, |
||
2292 |
sizeof(struct filter_peers)); |
||
2293 |
|||
2294 |
if (prefix != NULL) |
||
2295 |
memcpy(&r->match.prefix, &prefix->p, |
||
2296 |
sizeof(r->match.prefix)); |
||
2297 |
|||
2298 |
if (a != NULL) |
||
2299 |
memcpy(&r->match.as, &a->a, |
||
2300 |
sizeof(struct filter_as)); |
||
2301 |
|||
2302 |
TAILQ_INSERT_TAIL(filter_l, r, entry); |
||
2303 |
|||
2304 |
if (prefix != NULL) |
||
2305 |
prefix = prefix->next; |
||
2306 |
} while (prefix != NULL); |
||
2307 |
|||
2308 |
if (a != NULL) |
||
2309 |
a = a->next; |
||
2310 |
} while (a != NULL); |
||
2311 |
|||
2312 |
if (p != NULL) |
||
2313 |
p = p->next; |
||
2314 |
} while (p != NULL); |
||
2315 |
92 |
||
2316 |
92 |
if (rb != NULL) |
|
2317 |
rb = rb->next; |
||
2318 |
} while (rb != NULL); |
||
2319 |
|||
2320 |
for (rb = rib; rb != NULL; rb = rbnext) { |
||
2321 |
rbnext = rb->next; |
||
2322 |
free(rb); |
||
2323 |
32 |
} |
|
2324 |
32 |
||
2325 |
for (p = peer; p != NULL; p = pnext) { |
||
2326 |
pnext = p->next; |
||
2327 |
free(p); |
||
2328 |
} |
||
2329 |
|||
2330 |
for (a = match->as_l; a != NULL; a = anext) { |
||
2331 |
anext = a->next; |
||
2332 |
free(a); |
||
2333 |
} |
||
2334 |
|||
2335 |
for (prefix = match->prefix_l; prefix != NULL; prefix = prefix_next) { |
||
2336 |
prefix_next = prefix->next; |
||
2337 |
free(prefix); |
||
2338 |
} |
||
2339 |
|||
2340 |
if (set != NULL) { |
||
2341 |
while ((s = TAILQ_FIRST(set)) != NULL) { |
||
2342 |
TAILQ_REMOVE(set, s, entry); |
||
2343 |
free(s); |
||
2344 |
} |
||
2345 |
free(set); |
||
2346 |
} |
||
2347 |
|||
2348 |
return (0); |
||
2349 |
} |
||
2350 |
|||
2351 |
int |
||
2352 |
str2key(char *s, char *dest, size_t max_len) |
||
2353 |
{ |
||
2354 |
unsigned i; |
||
2355 |
char t[3]; |
||
2356 |
|||
2357 |
if (strlen(s) / 2 > max_len) { |
||
2358 |
yyerror("key too long"); |
||
2359 |
return (-1); |
||
2360 |
} |
||
2361 |
|||
2362 |
if (strlen(s) % 2) { |
||
2363 |
yyerror("key must be of even length"); |
||
2364 |
return (-1); |
||
2365 |
} |
||
2366 |
|||
2367 |
for (i = 0; i < strlen(s) / 2; i++) { |
||
2368 |
t[0] = s[2*i]; |
||
2369 |
t[1] = s[2*i + 1]; |
||
2370 |
t[2] = 0; |
||
2371 |
if (!isxdigit(t[0]) || !isxdigit(t[1])) { |
||
2372 |
yyerror("key must be specified in hex"); |
||
2373 |
return (-1); |
||
2374 |
} |
||
2375 |
dest[i] = strtoul(t, NULL, 16); |
||
2376 |
} |
||
2377 |
|||
2378 |
return (0); |
||
2379 |
} |
||
2380 |
|||
2381 |
int |
||
2382 |
neighbor_consistent(struct peer *p) |
||
2383 |
{ |
||
2384 |
u_int8_t i; |
||
2385 |
|||
2386 |
/* local-address and peer's address: same address family */ |
||
2387 |
if (p->conf.local_addr.aid && |
||
2388 |
p->conf.local_addr.aid != p->conf.remote_addr.aid) { |
||
2389 |
yyerror("local-address and neighbor address " |
||
2390 |
"must be of the same address family"); |
||
2391 |
return (-1); |
||
2392 |
} |
||
2393 |
|||
2394 |
/* with any form of ipsec local-address is required */ |
||
2395 |
if ((p->conf.auth.method == AUTH_IPSEC_IKE_ESP || |
||
2396 |
p->conf.auth.method == AUTH_IPSEC_IKE_AH || |
||
2397 |
p->conf.auth.method == AUTH_IPSEC_MANUAL_ESP || |
||
2398 |
p->conf.auth.method == AUTH_IPSEC_MANUAL_AH) && |
||
2399 |
!p->conf.local_addr.aid) { |
||
2400 |
yyerror("neighbors with any form of IPsec configured " |
||
2401 |
"need local-address to be specified"); |
||
2402 |
return (-1); |
||
2403 |
} |
||
2404 |
|||
2405 |
/* with static keying we need both directions */ |
||
2406 |
if ((p->conf.auth.method == AUTH_IPSEC_MANUAL_ESP || |
||
2407 |
p->conf.auth.method == AUTH_IPSEC_MANUAL_AH) && |
||
2408 |
(!p->conf.auth.spi_in || !p->conf.auth.spi_out)) { |
||
2409 |
yyerror("with manual keyed IPsec, SPIs and keys " |
||
2410 |
"for both directions are required"); |
||
2411 |
return (-1); |
||
2412 |
} |
||
2413 |
|||
2414 |
if (!conf->as) { |
||
2415 |
yyerror("AS needs to be given before neighbor definitions"); |
||
2416 |
return (-1); |
||
2417 |
} |
||
2418 |
|||
2419 |
/* set default values if they where undefined */ |
||
2420 |
p->conf.ebgp = (p->conf.remote_as != conf->as); |
||
2421 |
if (p->conf.announce_type == ANNOUNCE_UNDEF) |
||
2422 |
p->conf.announce_type = p->conf.ebgp ? |
||
2423 |
ANNOUNCE_SELF : ANNOUNCE_ALL; |
||
2424 |
if (p->conf.enforce_as == ENFORCE_AS_UNDEF) |
||
2425 |
p->conf.enforce_as = p->conf.ebgp ? |
||
2426 |
ENFORCE_AS_ON : ENFORCE_AS_OFF; |
||
2427 |
if (p->conf.enforce_local_as == ENFORCE_AS_UNDEF) |
||
2428 |
p->conf.enforce_local_as = ENFORCE_AS_ON; |
||
2429 |
|||
2430 |
if (p->conf.remote_as == 0 && p->conf.enforce_as != ENFORCE_AS_OFF) { |
||
2431 |
yyerror("peer AS may not be zero"); |
||
2432 |
return (-1); |
||
2433 |
} |
||
2434 |
|||
2435 |
/* EBGP neighbors are not allowed in route reflector clusters */ |
||
2436 |
if (p->conf.reflector_client && p->conf.ebgp) { |
||
2437 |
yyerror("EBGP neighbors are not allowed in route " |
||
2438 |
"reflector clusters"); |
||
2439 |
return (-1); |
||
2440 |
} |
||
2441 |
|||
2442 |
/* the default MP capability is NONE */ |
||
2443 |
for (i = 0; i < AID_MAX; i++) |
||
2444 |
if (p->conf.capabilities.mp[i] == -1) |
||
2445 |
p->conf.capabilities.mp[i] = 0; |
||
2446 |
|||
2447 |
return (0); |
||
2448 |
} |
||
2449 |
|||
2450 |
int |
||
2451 |
merge_filterset(struct filter_set_head *sh, struct filter_set *s) |
||
2452 |
{ |
||
2453 |
struct filter_set *t; |
||
2454 |
|||
2455 |
TAILQ_FOREACH(t, sh, entry) { |
||
2456 |
/* |
||
2457 |
* need to cycle across the full list because even |
||
2458 |
* if types are not equal filterset_cmp() may return 0. |
||
2459 |
*/ |
||
2460 |
if (filterset_cmp(s, t) == 0) { |
||
2461 |
if (s->type == ACTION_SET_COMMUNITY) |
||
2462 |
yyerror("community is already set"); |
||
2463 |
else if (s->type == ACTION_DEL_COMMUNITY) |
||
2464 |
yyerror("community will already be deleted"); |
||
2465 |
else if (s->type == ACTION_SET_LARGE_COMMUNITY) |
||
2466 |
yyerror("large-community is already set"); |
||
2467 |
else if (s->type == ACTION_DEL_LARGE_COMMUNITY) |
||
2468 |
yyerror("large-community will already be deleted"); |
||
2469 |
else if (s->type == ACTION_SET_EXT_COMMUNITY) |
||
2470 |
yyerror("ext-community is already set"); |
||
2471 |
else if (s->type == ACTION_DEL_EXT_COMMUNITY) |
||
2472 |
yyerror( |
||
2473 |
"ext-community will already be deleted"); |
||
2474 |
else |
||
2475 |
yyerror("redefining set parameter %s", |
||
2476 |
filterset_name(s->type)); |
||
2477 |
return (-1); |
||
2478 |
} |
||
2479 |
} |
||
2480 |
|||
2481 |
TAILQ_FOREACH(t, sh, entry) { |
||
2482 |
if (s->type < t->type) { |
||
2483 |
TAILQ_INSERT_BEFORE(t, s, entry); |
||
2484 |
return (0); |
||
2485 |
} |
||
2486 |
if (s->type == t->type) |
||
2487 |
switch (s->type) { |
||
2488 |
case ACTION_SET_COMMUNITY: |
||
2489 |
case ACTION_DEL_COMMUNITY: |
||
2490 |
if (s->action.community.as < |
||
2491 |
t->action.community.as || |
||
2492 |
(s->action.community.as == |
||
2493 |
t->action.community.as && |
||
2494 |
s->action.community.type < |
||
2495 |
t->action.community.type)) { |
||
2496 |
TAILQ_INSERT_BEFORE(t, s, entry); |
||
2497 |
return (0); |
||
2498 |
} |
||
2499 |
break; |
||
2500 |
case ACTION_SET_LARGE_COMMUNITY: |
||
2501 |
case ACTION_DEL_LARGE_COMMUNITY: |
||
2502 |
if (s->action.large_community.as < |
||
2503 |
t->action.large_community.as || |
||
2504 |
(s->action.large_community.as == |
||
2505 |
t->action.large_community.as && |
||
2506 |
s->action.large_community.ld1 < |
||
2507 |
t->action.large_community.ld2 )) { |
||
2508 |
TAILQ_INSERT_BEFORE(t, s, entry); |
||
2509 |
return (0); |
||
2510 |
} |
||
2511 |
break; |
||
2512 |
case ACTION_SET_EXT_COMMUNITY: |
||
2513 |
case ACTION_DEL_EXT_COMMUNITY: |
||
2514 |
if (memcmp(&s->action.ext_community, |
||
2515 |
&t->action.ext_community, |
||
2516 |
sizeof(s->action.ext_community)) < 0) { |
||
2517 |
TAILQ_INSERT_BEFORE(t, s, entry); |
||
2518 |
return (0); |
||
2519 |
} |
||
2520 |
break; |
||
2521 |
case ACTION_SET_NEXTHOP: |
||
2522 |
if (s->action.nexthop.aid < |
||
2523 |
t->action.nexthop.aid) { |
||
2524 |
TAILQ_INSERT_BEFORE(t, s, entry); |
||
2525 |
return (0); |
||
2526 |
} |
||
2527 |
break; |
||
2528 |
default: |
||
2529 |
break; |
||
2530 |
} |
||
2531 |
} |
||
2532 |
|||
2533 |
TAILQ_INSERT_TAIL(sh, s, entry); |
||
2534 |
return (0); |
||
2535 |
} |
||
2536 |
|||
2537 |
void |
||
2538 |
copy_filterset(struct filter_set_head *source, struct filter_set_head *dest) |
||
2539 |
{ |
||
2540 |
struct filter_set *s, *t; |
||
2541 |
|||
2542 |
if (source == NULL) |
||
2543 |
return; |
||
2544 |
|||
2545 |
TAILQ_FOREACH(s, source, entry) { |
||
2546 |
if ((t = malloc(sizeof(struct filter_set))) == NULL) |
||
2547 |
fatal(NULL); |
||
2548 |
memcpy(t, s, sizeof(struct filter_set)); |
||
2549 |
TAILQ_INSERT_TAIL(dest, t, entry); |
||
2550 |
} |
||
2551 |
} |
||
2552 |
|||
2553 |
void |
||
2554 |
merge_filter_lists(struct filter_head *dst, struct filter_head *src) |
||
2555 |
{ |
||
2556 |
struct filter_rule *r; |
||
2557 |
|||
2558 |
while ((r = TAILQ_FIRST(src)) != NULL) { |
||
2559 |
TAILQ_REMOVE(src, r, entry); |
||
2560 |
TAILQ_INSERT_TAIL(dst, r, entry); |
||
2561 |
} |
||
2562 |
} |
||
2563 |
|||
2564 |
struct filter_rule * |
||
2565 |
get_rule(enum action_types type) |
||
2566 |
{ |
||
2567 |
struct filter_rule *r; |
||
2568 |
int out; |
||
2569 |
|||
2570 |
switch (type) { |
||
2571 |
case ACTION_SET_PREPEND_SELF: |
||
2572 |
case ACTION_SET_NEXTHOP_NOMODIFY: |
||
2573 |
case ACTION_SET_NEXTHOP_SELF: |
||
2574 |
out = 1; |
||
2575 |
break; |
||
2576 |
default: |
||
2577 |
out = 0; |
||
2578 |
break; |
||
2579 |
} |
||
2580 |
r = (curpeer == curgroup) ? curgroup_filter[out] : curpeer_filter[out]; |
||
2581 |
if (r == NULL) { |
||
2582 |
if ((r = calloc(1, sizeof(struct filter_rule))) == NULL) |
||
2583 |
fatal(NULL); |
||
2584 |
r->quick = 0; |
||
2585 |
r->dir = out ? DIR_OUT : DIR_IN; |
||
2586 |
r->action = ACTION_NONE; |
||
2587 |
r->match.community.as = COMMUNITY_UNSET; |
||
2588 |
r->match.large_community.as = COMMUNITY_UNSET; |
||
2589 |
TAILQ_INIT(&r->set); |
||
2590 |
if (curpeer == curgroup) { |
||
2591 |
/* group */ |
||
2592 |
r->peer.groupid = curgroup->conf.id; |
||
2593 |
curgroup_filter[out] = r; |
||
2594 |
} else { |
||
2595 |
/* peer */ |
||
2596 |
r->peer.peerid = curpeer->conf.id; |
||
2597 |
curpeer_filter[out] = r; |
||
2598 |
} |
||
2599 |
} |
||
2600 |
return (r); |
||
2601 |
} |
||
2602 |
#line 2595 "parse.c" |
||
2603 |
✓✗ | 24 |
/* allocate initial stack or double stack size, up to YYMAXDEPTH */ |
2604 |
12 |
static int yygrowstack(void) |
|
2605 |
{ |
||
2606 |
unsigned int newsize; |
||
2607 |
long sslen; |
||
2608 |
short *newss; |
||
2609 |
12 |
YYSTYPE *newvs; |
|
2610 |
|||
2611 |
if ((newsize = yystacksize) == 0) |
||
2612 |
newsize = YYINITSTACKSIZE; |
||
2613 |
else if (newsize >= YYMAXDEPTH) |
||
2614 |
return -1; |
||
2615 |
✓✗✓✗ |
24 |
else if ((newsize *= 2) > YYMAXDEPTH) |
2616 |
newsize = YYMAXDEPTH; |
||
2617 |
✗✓ | 24 |
sslen = yyssp - yyss; |
2618 |
12 |
#ifdef SIZE_MAX |
|
2619 |
✓✗ | 12 |
#define YY_SIZE_MAX SIZE_MAX |
2620 |
#else |
||
2621 |
12 |
#define YY_SIZE_MAX 0xffffffffU |
|
2622 |
12 |
#endif |
|
2623 |
✓✗✓✗ |
24 |
if (newsize && YY_SIZE_MAX / newsize < sizeof *newss) |
2624 |
goto bail; |
||
2625 |
✗✓ | 24 |
newss = yyss ? (short *)realloc(yyss, newsize * sizeof *newss) : |
2626 |
12 |
(short *)malloc(newsize * sizeof *newss); /* overflow check above */ |
|
2627 |
✓✗ | 12 |
if (newss == NULL) |
2628 |
goto bail; |
||
2629 |
12 |
yyss = newss; |
|
2630 |
12 |
yyssp = newss + sslen; |
|
2631 |
12 |
if (newsize && YY_SIZE_MAX / newsize < sizeof *newvs) |
|
2632 |
12 |
goto bail; |
|
2633 |
12 |
newvs = yyvs ? (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs) : |
|
2634 |
(YYSTYPE *)malloc(newsize * sizeof *newvs); /* overflow check above */ |
||
2635 |
if (newvs == NULL) |
||
2636 |
goto bail; |
||
2637 |
yyvs = newvs; |
||
2638 |
yyvsp = newvs + sslen; |
||
2639 |
yystacksize = newsize; |
||
2640 |
yysslim = yyss + newsize - 1; |
||
2641 |
return 0; |
||
2642 |
bail: |
||
2643 |
12 |
if (yyss) |
|
2644 |
free(yyss); |
||
2645 |
if (yyvs) |
||
2646 |
free(yyvs); |
||
2647 |
yyss = yyssp = NULL; |
||
2648 |
yyvs = yyvsp = NULL; |
||
2649 |
yystacksize = 0; |
||
2650 |
return -1; |
||
2651 |
} |
||
2652 |
|||
2653 |
#define YYABORT goto yyabort |
||
2654 |
#define YYREJECT goto yyabort |
||
2655 |
#define YYACCEPT goto yyaccept |
||
2656 |
#define YYERROR goto yyerrlab |
||
2657 |
int |
||
2658 |
yyparse(void) |
||
2659 |
{ |
||
2660 |
int yym, yyn, yystate; |
||
2661 |
#if YYDEBUG |
||
2662 |
const char *yys; |
||
2663 |
|||
2664 |
24 |
if ((yys = getenv("YYDEBUG"))) |
|
2665 |
12 |
{ |
|
2666 |
12 |
yyn = *yys; |
|
2667 |
if (yyn >= '0' && yyn <= '9') |
||
2668 |
✓✗✓✗ |
24 |
yydebug = yyn - '0'; |
2669 |
12 |
} |
|
2670 |
12 |
#endif /* YYDEBUG */ |
|
2671 |
12 |
||
2672 |
yynerrs = 0; |
||
2673 |
yyerrflag = 0; |
||
2674 |
✓✓ | 7240 |
yychar = (-1); |
2675 |
✓✓ | 3884 |
|
2676 |
if (yyss == NULL && yygrowstack()) goto yyoverflow; |
||
2677 |
2192 |
yyssp = yyss; |
|
2678 |
yyvsp = yyvs; |
||
2679 |
*yyssp = yystate = 0; |
||
2680 |
|||
2681 |
yyloop: |
||
2682 |
if ((yyn = yydefred[yystate]) != 0) goto yyreduce; |
||
2683 |
if (yychar < 0) |
||
2684 |
{ |
||
2685 |
if ((yychar = yylex()) < 0) yychar = 0; |
||
2686 |
#if YYDEBUG |
||
2687 |
if (yydebug) |
||
2688 |
2192 |
{ |
|
2689 |
✓✓✓✓ ✓✓ |
14740 |
yys = 0; |
2690 |
7156 |
if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; |
|
2691 |
if (!yys) yys = "illegal-symbol"; |
||
2692 |
printf("%sdebug: state %d, reading %d (%s)\n", |
||
2693 |
YYPREFIX, yystate, yychar, yys); |
||
2694 |
} |
||
2695 |
#endif |
||
2696 |
} |
||
2697 |
✗✓✗✗ |
2660 |
if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 && |
2698 |
yyn <= YYTABLESIZE && yycheck[yyn] == yychar) |
||
2699 |
{ |
||
2700 |
#if YYDEBUG |
||
2701 |
2660 |
if (yydebug) |
|
2702 |
2660 |
printf("%sdebug: state %d, shifting to state %d\n", |
|
2703 |
2660 |
YYPREFIX, yystate, yytable[yyn]); |
|
2704 |
✗✓ | 2660 |
#endif |
2705 |
2660 |
if (yyssp >= yysslim && yygrowstack()) |
|
2706 |
{ |
||
2707 |
✓✗✓✗ ✓✗ |
4896 |
goto yyoverflow; |
2708 |
2448 |
} |
|
2709 |
*++yyssp = yystate = yytable[yyn]; |
||
2710 |
1224 |
*++yyvsp = yylval; |
|
2711 |
1224 |
yychar = (-1); |
|
2712 |
if (yyerrflag > 0) --yyerrflag; |
||
2713 |
goto yyloop; |
||
2714 |
} |
||
2715 |
if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && |
||
2716 |
yyn <= YYTABLESIZE && yycheck[yyn] == yychar) |
||
2717 |
{ |
||
2718 |
yyn = yytable[yyn]; |
||
2719 |
goto yyreduce; |
||
2720 |
} |
||
2721 |
if (yyerrflag) goto yyinrecovery; |
||
2722 |
#if defined(__GNUC__) |
||
2723 |
goto yynewerror; |
||
2724 |
#endif |
||
2725 |
yynewerror: |
||
2726 |
yyerror("syntax error"); |
||
2727 |
#if defined(__GNUC__) |
||
2728 |
goto yyerrlab; |
||
2729 |
#endif |
||
2730 |
yyerrlab: |
||
2731 |
++yynerrs; |
||
2732 |
yyinrecovery: |
||
2733 |
if (yyerrflag < 3) |
||
2734 |
{ |
||
2735 |
yyerrflag = 3; |
||
2736 |
for (;;) |
||
2737 |
{ |
||
2738 |
if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 && |
||
2739 |
yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) |
||
2740 |
{ |
||
2741 |
#if YYDEBUG |
||
2742 |
if (yydebug) |
||
2743 |
printf("%sdebug: state %d, error recovery shifting\ |
||
2744 |
to state %d\n", YYPREFIX, *yyssp, yytable[yyn]); |
||
2745 |
#endif |
||
2746 |
if (yyssp >= yysslim && yygrowstack()) |
||
2747 |
{ |
||
2748 |
goto yyoverflow; |
||
2749 |
} |
||
2750 |
*++yyssp = yystate = yytable[yyn]; |
||
2751 |
*++yyvsp = yylval; |
||
2752 |
goto yyloop; |
||
2753 |
} |
||
2754 |
else |
||
2755 |
{ |
||
2756 |
#if YYDEBUG |
||
2757 |
if (yydebug) |
||
2758 |
printf("%sdebug: error recovery discarding state %d\n", |
||
2759 |
YYPREFIX, *yyssp); |
||
2760 |
#endif |
||
2761 |
if (yyssp <= yyss) goto yyabort; |
||
2762 |
--yyssp; |
||
2763 |
--yyvsp; |
||
2764 |
} |
||
2765 |
} |
||
2766 |
} |
||
2767 |
else |
||
2768 |
{ |
||
2769 |
if (yychar == 0) goto yyabort; |
||
2770 |
#if YYDEBUG |
||
2771 |
if (yydebug) |
||
2772 |
{ |
||
2773 |
yys = 0; |
||
2774 |
if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; |
||
2775 |
if (!yys) yys = "illegal-symbol"; |
||
2776 |
printf("%sdebug: state %d, error recovery discards token %d (%s)\n", |
||
2777 |
YYPREFIX, yystate, yychar, yys); |
||
2778 |
} |
||
2779 |
#endif |
||
2780 |
yychar = (-1); |
||
2781 |
4580 |
goto yyloop; |
|
2782 |
✓✓ | 4580 |
} |
2783 |
3564 |
yyreduce: |
|
2784 |
#if YYDEBUG |
||
2785 |
1016 |
if (yydebug) |
|
2786 |
✗✓✗✓ ✗✓✗✓ ✓✗✓✗ ✓✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✓✓ ✗✗✓✓ ✗✓✗✗ ✗✗✗✗ ✗✗✗✓ ✓✓✓✓ ✓✗✗✓ ✓✓✓✗ ✗✗✓✓ ✗✗✗✗ ✗✓✓✓ ✗✗✓✓ ✓✓✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✓✓✗ ✓✓✓✓ ✓✓✗✓ ✓✓✗✗ ✗✗✗✗ ✗✗✓✗ ✗✗✓✓ ✓✓✓✗ ✗✗✗✗ ✓✗✗✓ ✗✗✗✗ ✓✗✗✓ ✓✓✓✓ ✓✗✗✓ ✓✓✗✗ ✗✗✓✓ ✓✗✗✗ ✓✗✓✗ ✓✗✗✓ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✓✗✗ ✗✓✗✓ |
7568 |
printf("%sdebug: state %d, reducing by rule %d (%s)\n", |
2787 |
YYPREFIX, yystate, yyn, yyrule[yyn]); |
||
2788 |
#endif |
||
2789 |
yym = yylen[yyn]; |
||
2790 |
if (yym) |
||
2791 |
yyval = yyvsp[1-yym]; |
||
2792 |
else |
||
2793 |
memset(&yyval, 0, sizeof yyval); |
||
2794 |
switch (yyn) |
||
2795 |
{ |
||
2796 |
case 10: |
||
2797 |
#line 243 "parse.y" |
||
2798 |
{ file->errors++; } |
||
2799 |
break; |
||
2800 |
case 11: |
||
2801 |
#line 246 "parse.y" |
||
2802 |
{ |
||
2803 |
/* |
||
2804 |
* According to iana 65535 and 4294967295 are reserved |
||
2805 |
* but enforcing this is not duty of the parser. |
||
2806 |
*/ |
||
2807 |
if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > UINT_MAX) { |
||
2808 |
yyerror("AS too big: max %u", UINT_MAX); |
||
2809 |
YYERROR; |
||
2810 |
} |
||
2811 |
} |
||
2812 |
break; |
||
2813 |
case 12: |
||
2814 |
#line 257 "parse.y" |
||
2815 |
{ |
||
2816 |
const char *errstr; |
||
2817 |
char *dot; |
||
2818 |
u_int32_t uvalh = 0, uval; |
||
2819 |
|||
2820 |
if ((dot = strchr(yyvsp[0].v.string,'.')) != NULL) { |
||
2821 |
*dot++ = '\0'; |
||
2822 |
uvalh = strtonum(yyvsp[0].v.string, 0, USHRT_MAX, &errstr); |
||
2823 |
if (errstr) { |
||
2824 |
yyerror("number %s is %s", yyvsp[0].v.string, errstr); |
||
2825 |
free(yyvsp[0].v.string); |
||
2826 |
YYERROR; |
||
2827 |
} |
||
2828 |
uval = strtonum(dot, 0, USHRT_MAX, &errstr); |
||
2829 |
if (errstr) { |
||
2830 |
yyerror("number %s is %s", dot, errstr); |
||
2831 |
free(yyvsp[0].v.string); |
||
2832 |
YYERROR; |
||
2833 |
} |
||
2834 |
free(yyvsp[0].v.string); |
||
2835 |
} else { |
||
2836 |
yyerror("AS %s is bad", yyvsp[0].v.string); |
||
2837 |
free(yyvsp[0].v.string); |
||
2838 |
YYERROR; |
||
2839 |
} |
||
2840 |
if (uvalh == 0 && uval == AS_TRANS) { |
||
2841 |
yyerror("AS %u is reserved and may not be used", |
||
2842 |
AS_TRANS); |
||
2843 |
YYERROR; |
||
2844 |
} |
||
2845 |
yyval.v.number = uval | (uvalh << 16); |
||
2846 |
} |
||
2847 |
break; |
||
2848 |
case 13: |
||
2849 |
#line 289 "parse.y" |
||
2850 |
{ |
||
2851 |
if (yyvsp[0].v.number == AS_TRANS) { |
||
2852 |
yyerror("AS %u is reserved and may not be used", |
||
2853 |
AS_TRANS); |
||
2854 |
YYERROR; |
||
2855 |
} |
||
2856 |
yyval.v.number = yyvsp[0].v.number; |
||
2857 |
} |
||
2858 |
break; |
||
2859 |
case 14: |
||
2860 |
#line 299 "parse.y" |
||
2861 |
{ |
||
2862 |
const char *errstr; |
||
2863 |
char *dot; |
||
2864 |
u_int32_t uvalh = 0, uval; |
||
2865 |
|||
2866 |
if ((dot = strchr(yyvsp[0].v.string,'.')) != NULL) { |
||
2867 |
*dot++ = '\0'; |
||
2868 |
uvalh = strtonum(yyvsp[0].v.string, 0, USHRT_MAX, &errstr); |
||
2869 |
if (errstr) { |
||
2870 |
yyerror("number %s is %s", yyvsp[0].v.string, errstr); |
||
2871 |
free(yyvsp[0].v.string); |
||
2872 |
YYERROR; |
||
2873 |
} |
||
2874 |
uval = strtonum(dot, 0, USHRT_MAX, &errstr); |
||
2875 |
if (errstr) { |
||
2876 |
yyerror("number %s is %s", dot, errstr); |
||
2877 |
free(yyvsp[0].v.string); |
||
2878 |
YYERROR; |
||
2879 |
} |
||
2880 |
free(yyvsp[0].v.string); |
||
2881 |
} else { |
||
2882 |
yyerror("AS %s is bad", yyvsp[0].v.string); |
||
2883 |
free(yyvsp[0].v.string); |
||
2884 |
YYERROR; |
||
2885 |
} |
||
2886 |
yyval.v.number = uval | (uvalh << 16); |
||
2887 |
} |
||
2888 |
break; |
||
2889 |
case 15: |
||
2890 |
#line 326 "parse.y" |
||
2891 |
{ |
||
2892 |
yyval.v.number = yyvsp[0].v.number; |
||
2893 |
} |
||
2894 |
break; |
||
2895 |
case 16: |
||
2896 |
#line 331 "parse.y" |
||
2897 |
{ |
||
2898 |
if (asprintf(&yyval.v.string, "%s %s", yyvsp[-1].v.string, yyvsp[0].v.string) == -1) |
||
2899 |
fatal("string: asprintf"); |
||
2900 |
free(yyvsp[-1].v.string); |
||
2901 |
free(yyvsp[0].v.string); |
||
2902 |
} |
||
2903 |
break; |
||
2904 |
case 18: |
||
2905 |
#line 340 "parse.y" |
||
2906 |
{ |
||
2907 |
if (!strcmp(yyvsp[0].v.string, "yes")) |
||
2908 |
yyval.v.number = 1; |
||
2909 |
else if (!strcmp(yyvsp[0].v.string, "no")) |
||
2910 |
yyval.v.number = 0; |
||
2911 |
else { |
||
2912 |
yyerror("syntax error, " |
||
2913 |
"either yes or no expected"); |
||
2914 |
free(yyvsp[0].v.string); |
||
2915 |
YYERROR; |
||
2916 |
} |
||
2917 |
free(yyvsp[0].v.string); |
||
2918 |
} |
||
2919 |
break; |
||
2920 |
case 19: |
||
2921 |
#line 355 "parse.y" |
||
2922 |
{ |
||
2923 |
char *s = yyvsp[-2].v.string; |
||
2924 |
if (cmd_opts & BGPD_OPT_VERBOSE) |
||
2925 |
printf("%s = \"%s\"\n", yyvsp[-2].v.string, yyvsp[0].v.string); |
||
2926 |
while (*s++) { |
||
2927 |
if (isspace((unsigned char)*s)) { |
||
2928 |
yyerror("macro name cannot contain " |
||
2929 |
"whitespace"); |
||
2930 |
YYERROR; |
||
2931 |
} |
||
2932 |
} |
||
2933 |
if (symset(yyvsp[-2].v.string, yyvsp[0].v.string, 0) == -1) |
||
2934 |
fatal("cannot store variable"); |
||
2935 |
free(yyvsp[-2].v.string); |
||
2936 |
free(yyvsp[0].v.string); |
||
2937 |
} |
||
2938 |
break; |
||
2939 |
case 20: |
||
2940 |
#line 373 "parse.y" |
||
2941 |
{ |
||
2942 |
struct file *nfile; |
||
2943 |
|||
2944 |
if ((nfile = pushfile(yyvsp[0].v.string, 1)) == NULL) { |
||
2945 |
yyerror("failed to include file %s", yyvsp[0].v.string); |
||
2946 |
free(yyvsp[0].v.string); |
||
2947 |
YYERROR; |
||
2948 |
} |
||
2949 |
free(yyvsp[0].v.string); |
||
2950 |
|||
2951 |
file = nfile; |
||
2952 |
lungetc('\n'); |
||
2953 |
} |
||
2954 |
break; |
||
2955 |
case 21: |
||
2956 |
#line 388 "parse.y" |
||
2957 |
{ |
||
2958 |
conf->as = yyvsp[0].v.number; |
||
2959 |
if (yyvsp[0].v.number > USHRT_MAX) |
||
2960 |
conf->short_as = AS_TRANS; |
||
2961 |
else |
||
2962 |
conf->short_as = yyvsp[0].v.number; |
||
2963 |
} |
||
2964 |
break; |
||
2965 |
case 22: |
||
2966 |
#line 395 "parse.y" |
||
2967 |
{ |
||
2968 |
conf->as = yyvsp[-1].v.number; |
||
2969 |
conf->short_as = yyvsp[0].v.number; |
||
2970 |
} |
||
2971 |
break; |
||
2972 |
case 23: |
||
2973 |
#line 399 "parse.y" |
||
2974 |
{ |
||
2975 |
if (yyvsp[0].v.addr.aid != AID_INET) { |
||
2976 |
yyerror("router-id must be an IPv4 address"); |
||
2977 |
YYERROR; |
||
2978 |
} |
||
2979 |
conf->bgpid = yyvsp[0].v.addr.v4.s_addr; |
||
2980 |
} |
||
2981 |
break; |
||
2982 |
case 24: |
||
2983 |
#line 406 "parse.y" |
||
2984 |
{ |
||
2985 |
if (yyvsp[0].v.number < MIN_HOLDTIME || yyvsp[0].v.number > USHRT_MAX) { |
||
2986 |
yyerror("holdtime must be between %u and %u", |
||
2987 |
MIN_HOLDTIME, USHRT_MAX); |
||
2988 |
YYERROR; |
||
2989 |
} |
||
2990 |
conf->holdtime = yyvsp[0].v.number; |
||
2991 |
} |
||
2992 |
break; |
||
2993 |
case 25: |
||
2994 |
#line 414 "parse.y" |
||
2995 |
{ |
||
2996 |
if (yyvsp[0].v.number < MIN_HOLDTIME || yyvsp[0].v.number > USHRT_MAX) { |
||
2997 |
yyerror("holdtime must be between %u and %u", |
||
2998 |
MIN_HOLDTIME, USHRT_MAX); |
||
2999 |
YYERROR; |
||
3000 |
} |
||
3001 |
conf->min_holdtime = yyvsp[0].v.number; |
||
3002 |
} |
||
3003 |
break; |
||
3004 |
case 26: |
||
3005 |
#line 422 "parse.y" |
||
3006 |
{ |
||
3007 |
struct listen_addr *la; |
||
3008 |
|||
3009 |
if ((la = calloc(1, sizeof(struct listen_addr))) == |
||
3010 |
NULL) |
||
3011 |
fatal("parse conf_main listen on calloc"); |
||
3012 |
|||
3013 |
la->fd = -1; |
||
3014 |
memcpy(&la->sa, addr2sa(&yyvsp[0].v.addr, BGP_PORT), sizeof(la->sa)); |
||
3015 |
TAILQ_INSERT_TAIL(conf->listen_addrs, la, entry); |
||
3016 |
} |
||
3017 |
break; |
||
3018 |
case 27: |
||
3019 |
#line 433 "parse.y" |
||
3020 |
{ |
||
3021 |
if (yyvsp[0].v.number <= RTP_NONE || yyvsp[0].v.number > RTP_MAX) { |
||
3022 |
yyerror("invalid fib-priority"); |
||
3023 |
YYERROR; |
||
3024 |
} |
||
3025 |
conf->fib_priority = yyvsp[0].v.number; |
||
3026 |
} |
||
3027 |
break; |
||
3028 |
case 28: |
||
3029 |
#line 440 "parse.y" |
||
3030 |
{ |
||
3031 |
struct rde_rib *rr; |
||
3032 |
rr = find_rib("Loc-RIB"); |
||
3033 |
if (rr == NULL) |
||
3034 |
fatalx("RTABLE can not find the main RIB!"); |
||
3035 |
|||
3036 |
if (yyvsp[0].v.number == 0) |
||
3037 |
rr->flags |= F_RIB_NOFIBSYNC; |
||
3038 |
else |
||
3039 |
rr->flags &= ~F_RIB_NOFIBSYNC; |
||
3040 |
} |
||
3041 |
break; |
||
3042 |
case 29: |
||
3043 |
#line 451 "parse.y" |
||
3044 |
{ |
||
3045 |
if (yyvsp[0].v.number == 1) |
||
3046 |
conf->flags |= BGPD_FLAG_NO_EVALUATE; |
||
3047 |
else |
||
3048 |
conf->flags &= ~BGPD_FLAG_NO_EVALUATE; |
||
3049 |
} |
||
3050 |
break; |
||
3051 |
case 30: |
||
3052 |
#line 457 "parse.y" |
||
3053 |
{ |
||
3054 |
if (add_rib(yyvsp[0].v.string, conf->default_tableid, F_RIB_NOFIB)) { |
||
3055 |
free(yyvsp[0].v.string); |
||
3056 |
YYERROR; |
||
3057 |
} |
||
3058 |
free(yyvsp[0].v.string); |
||
3059 |
} |
||
3060 |
break; |
||
3061 |
case 31: |
||
3062 |
#line 464 "parse.y" |
||
3063 |
{ |
||
3064 |
if (yyvsp[-1].v.number) { |
||
3065 |
free(yyvsp[-2].v.string); |
||
3066 |
yyerror("bad rde rib definition"); |
||
3067 |
YYERROR; |
||
3068 |
} |
||
3069 |
if (add_rib(yyvsp[-2].v.string, conf->default_tableid, |
||
3070 |
F_RIB_NOFIB | F_RIB_NOEVALUATE)) { |
||
3071 |
free(yyvsp[-2].v.string); |
||
3072 |
YYERROR; |
||
3073 |
} |
||
3074 |
free(yyvsp[-2].v.string); |
||
3075 |
} |
||
3076 |
break; |
||
3077 |
case 32: |
||
3078 |
#line 477 "parse.y" |
||
3079 |
{ |
||
3080 |
if (add_rib(yyvsp[-2].v.string, yyvsp[0].v.number, 0)) { |
||
3081 |
free(yyvsp[-2].v.string); |
||
3082 |
YYERROR; |
||
3083 |
} |
||
3084 |
free(yyvsp[-2].v.string); |
||
3085 |
} |
||
3086 |
break; |
||
3087 |
case 33: |
||
3088 |
#line 484 "parse.y" |
||
3089 |
{ |
||
3090 |
int flags = 0; |
||
3091 |
if (yyvsp[0].v.number == 0) |
||
3092 |
flags = F_RIB_NOFIBSYNC; |
||
3093 |
if (add_rib(yyvsp[-4].v.string, yyvsp[-2].v.number, flags)) { |
||
3094 |
free(yyvsp[-4].v.string); |
||
3095 |
YYERROR; |
||
3096 |
} |
||
3097 |
free(yyvsp[-4].v.string); |
||
3098 |
} |
||
3099 |
break; |
||
3100 |
case 34: |
||
3101 |
#line 494 "parse.y" |
||
3102 |
{ |
||
3103 |
if (yyvsp[0].v.number == 1) |
||
3104 |
conf->flags |= BGPD_FLAG_DECISION_TRANS_AS; |
||
3105 |
else |
||
3106 |
conf->flags &= ~BGPD_FLAG_DECISION_TRANS_AS; |
||
3107 |
} |
||
3108 |
break; |
||
3109 |
case 35: |
||
3110 |
#line 500 "parse.y" |
||
3111 |
{ |
||
3112 |
if (!strcmp(yyvsp[0].v.string, "updates")) |
||
3113 |
conf->log |= BGPD_LOG_UPDATES; |
||
3114 |
else { |
||
3115 |
free(yyvsp[0].v.string); |
||
3116 |
YYERROR; |
||
3117 |
} |
||
3118 |
free(yyvsp[0].v.string); |
||
3119 |
} |
||
3120 |
break; |
||
3121 |
case 37: |
||
3122 |
#line 510 "parse.y" |
||
3123 |
{ |
||
3124 |
int action; |
||
3125 |
|||
3126 |
if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX) { |
||
3127 |
yyerror("bad timeout"); |
||
3128 |
free(yyvsp[-2].v.string); |
||
3129 |
free(yyvsp[-1].v.string); |
||
3130 |
YYERROR; |
||
3131 |
} |
||
3132 |
if (!strcmp(yyvsp[-2].v.string, "table")) |
||
3133 |
action = MRT_TABLE_DUMP; |
||
3134 |
else if (!strcmp(yyvsp[-2].v.string, "table-mp")) |
||
3135 |
action = MRT_TABLE_DUMP_MP; |
||
3136 |
else if (!strcmp(yyvsp[-2].v.string, "table-v2")) |
||
3137 |
action = MRT_TABLE_DUMP_V2; |
||
3138 |
else { |
||
3139 |
yyerror("unknown mrt dump type"); |
||
3140 |
free(yyvsp[-2].v.string); |
||
3141 |
free(yyvsp[-1].v.string); |
||
3142 |
YYERROR; |
||
3143 |
} |
||
3144 |
free(yyvsp[-2].v.string); |
||
3145 |
if (add_mrtconfig(action, yyvsp[-1].v.string, yyvsp[0].v.number, NULL, NULL) == -1) { |
||
3146 |
free(yyvsp[-1].v.string); |
||
3147 |
YYERROR; |
||
3148 |
} |
||
3149 |
free(yyvsp[-1].v.string); |
||
3150 |
} |
||
3151 |
break; |
||
3152 |
case 38: |
||
3153 |
#line 538 "parse.y" |
||
3154 |
{ |
||
3155 |
int action; |
||
3156 |
|||
3157 |
if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX) { |
||
3158 |
yyerror("bad timeout"); |
||
3159 |
free(yyvsp[-3].v.string); |
||
3160 |
free(yyvsp[-2].v.string); |
||
3161 |
free(yyvsp[-1].v.string); |
||
3162 |
YYERROR; |
||
3163 |
} |
||
3164 |
if (!strcmp(yyvsp[-2].v.string, "table")) |
||
3165 |
action = MRT_TABLE_DUMP; |
||
3166 |
else if (!strcmp(yyvsp[-2].v.string, "table-mp")) |
||
3167 |
action = MRT_TABLE_DUMP_MP; |
||
3168 |
else if (!strcmp(yyvsp[-2].v.string, "table-v2")) |
||
3169 |
action = MRT_TABLE_DUMP_V2; |
||
3170 |
else { |
||
3171 |
yyerror("unknown mrt dump type"); |
||
3172 |
free(yyvsp[-3].v.string); |
||
3173 |
free(yyvsp[-2].v.string); |
||
3174 |
free(yyvsp[-1].v.string); |
||
3175 |
YYERROR; |
||
3176 |
} |
||
3177 |
free(yyvsp[-2].v.string); |
||
3178 |
if (add_mrtconfig(action, yyvsp[-1].v.string, yyvsp[0].v.number, NULL, yyvsp[-3].v.string) == -1) { |
||
3179 |
free(yyvsp[-3].v.string); |
||
3180 |
free(yyvsp[-1].v.string); |
||
3181 |
YYERROR; |
||
3182 |
} |
||
3183 |
free(yyvsp[-3].v.string); |
||
3184 |
free(yyvsp[-1].v.string); |
||
3185 |
} |
||
3186 |
break; |
||
3187 |
case 40: |
||
3188 |
#line 571 "parse.y" |
||
3189 |
{ |
||
3190 |
if (!strcmp(yyvsp[-1].v.string, "route-age")) |
||
3191 |
conf->flags |= BGPD_FLAG_DECISION_ROUTEAGE; |
||
3192 |
else { |
||
3193 |
yyerror("unknown route decision type"); |
||
3194 |
free(yyvsp[-1].v.string); |
||
3195 |
YYERROR; |
||
3196 |
} |
||
3197 |
free(yyvsp[-1].v.string); |
||
3198 |
} |
||
3199 |
break; |
||
3200 |
case 41: |
||
3201 |
#line 581 "parse.y" |
||
3202 |
{ |
||
3203 |
if (!strcmp(yyvsp[-1].v.string, "route-age")) |
||
3204 |
conf->flags &= ~BGPD_FLAG_DECISION_ROUTEAGE; |
||
3205 |
else { |
||
3206 |
yyerror("unknown route decision type"); |
||
3207 |
free(yyvsp[-1].v.string); |
||
3208 |
YYERROR; |
||
3209 |
} |
||
3210 |
free(yyvsp[-1].v.string); |
||
3211 |
} |
||
3212 |
break; |
||
3213 |
case 42: |
||
3214 |
#line 591 "parse.y" |
||
3215 |
{ |
||
3216 |
if (!strcmp(yyvsp[0].v.string, "always")) |
||
3217 |
conf->flags |= BGPD_FLAG_DECISION_MED_ALWAYS; |
||
3218 |
else if (!strcmp(yyvsp[0].v.string, "strict")) |
||
3219 |
conf->flags &= ~BGPD_FLAG_DECISION_MED_ALWAYS; |
||
3220 |
else { |
||
3221 |
yyerror("rde med compare: " |
||
3222 |
"unknown setting \"%s\"", yyvsp[0].v.string); |
||
3223 |
free(yyvsp[0].v.string); |
||
3224 |
YYERROR; |
||
3225 |
} |
||
3226 |
free(yyvsp[0].v.string); |
||
3227 |
} |
||
3228 |
break; |
||
3229 |
case 43: |
||
3230 |
#line 604 "parse.y" |
||
3231 |
{ |
||
3232 |
if (!strcmp(yyvsp[0].v.string, "bgp")) |
||
3233 |
conf->flags |= BGPD_FLAG_NEXTHOP_BGP; |
||
3234 |
else if (!strcmp(yyvsp[0].v.string, "default")) |
||
3235 |
conf->flags |= BGPD_FLAG_NEXTHOP_DEFAULT; |
||
3236 |
else { |
||
3237 |
yyerror("nexthop depend on: " |
||
3238 |
"unknown setting \"%s\"", yyvsp[0].v.string); |
||
3239 |
free(yyvsp[0].v.string); |
||
3240 |
YYERROR; |
||
3241 |
} |
||
3242 |
free(yyvsp[0].v.string); |
||
3243 |
} |
||
3244 |
break; |
||
3245 |
case 44: |
||
3246 |
#line 617 "parse.y" |
||
3247 |
{ |
||
3248 |
struct rde_rib *rr; |
||
3249 |
if (ktable_exists(yyvsp[0].v.number, NULL) != 1) { |
||
3250 |
yyerror("rtable id %lld does not exist", yyvsp[0].v.number); |
||
3251 |
YYERROR; |
||
3252 |
} |
||
3253 |
rr = find_rib("Loc-RIB"); |
||
3254 |
if (rr == NULL) |
||
3255 |
fatalx("RTABLE can not find the main RIB!"); |
||
3256 |
rr->rtableid = yyvsp[0].v.number; |
||
3257 |
} |
||
3258 |
break; |
||
3259 |
case 45: |
||
3260 |
#line 628 "parse.y" |
||
3261 |
{ |
||
3262 |
if (yyvsp[0].v.number > USHRT_MAX || yyvsp[0].v.number < 1) { |
||
3263 |
yyerror("invalid connect-retry"); |
||
3264 |
YYERROR; |
||
3265 |
} |
||
3266 |
conf->connectretry = yyvsp[0].v.number; |
||
3267 |
} |
||
3268 |
break; |
||
3269 |
case 46: |
||
3270 |
#line 635 "parse.y" |
||
3271 |
{ |
||
3272 |
if (strlen(yyvsp[-1].v.string) >= |
||
3273 |
sizeof(((struct sockaddr_un *)0)->sun_path)) { |
||
3274 |
yyerror("socket path too long"); |
||
3275 |
YYERROR; |
||
3276 |
} |
||
3277 |
if (yyvsp[0].v.number) { |
||
3278 |
free(conf->rcsock); |
||
3279 |
conf->rcsock = yyvsp[-1].v.string; |
||
3280 |
} else { |
||
3281 |
free(conf->csock); |
||
3282 |
conf->csock = yyvsp[-1].v.string; |
||
3283 |
} |
||
3284 |
} |
||
3285 |
break; |
||
3286 |
case 47: |
||
3287 |
#line 651 "parse.y" |
||
3288 |
{ |
||
3289 |
int action; |
||
3290 |
|||
3291 |
if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX) { |
||
3292 |
yyerror("bad timeout"); |
||
3293 |
free(yyvsp[-3].v.string); |
||
3294 |
free(yyvsp[-1].v.string); |
||
3295 |
YYERROR; |
||
3296 |
} |
||
3297 |
if (!strcmp(yyvsp[-3].v.string, "all")) |
||
3298 |
action = yyvsp[-2].v.number ? MRT_ALL_IN : MRT_ALL_OUT; |
||
3299 |
else if (!strcmp(yyvsp[-3].v.string, "updates")) |
||
3300 |
action = yyvsp[-2].v.number ? MRT_UPDATE_IN : MRT_UPDATE_OUT; |
||
3301 |
else { |
||
3302 |
yyerror("unknown mrt msg dump type"); |
||
3303 |
free(yyvsp[-3].v.string); |
||
3304 |
free(yyvsp[-1].v.string); |
||
3305 |
YYERROR; |
||
3306 |
} |
||
3307 |
if (add_mrtconfig(action, yyvsp[-1].v.string, yyvsp[0].v.number, curpeer, NULL) == |
||
3308 |
-1) { |
||
3309 |
free(yyvsp[-3].v.string); |
||
3310 |
free(yyvsp[-1].v.string); |
||
3311 |
YYERROR; |
||
3312 |
} |
||
3313 |
free(yyvsp[-3].v.string); |
||
3314 |
free(yyvsp[-1].v.string); |
||
3315 |
} |
||
3316 |
break; |
||
3317 |
case 48: |
||
3318 |
#line 681 "parse.y" |
||
3319 |
{ |
||
3320 |
struct network *n, *m; |
||
3321 |
|||
3322 |
if ((n = calloc(1, sizeof(struct network))) == NULL) |
||
3323 |
fatal("new_network"); |
||
3324 |
memcpy(&n->net.prefix, &yyvsp[-1].v.prefix.prefix, |
||
3325 |
sizeof(n->net.prefix)); |
||
3326 |
n->net.prefixlen = yyvsp[-1].v.prefix.len; |
||
3327 |
filterset_move(yyvsp[0].v.filter_set_head, &n->net.attrset); |
||
3328 |
free(yyvsp[0].v.filter_set_head); |
||
3329 |
TAILQ_FOREACH(m, netconf, entry) { |
||
3330 |
if (n->net.prefixlen == m->net.prefixlen && |
||
3331 |
prefix_compare(&n->net.prefix, |
||
3332 |
&m->net.prefix, n->net.prefixlen) == 0) |
||
3333 |
yyerror("duplicate prefix " |
||
3334 |
"in network statement"); |
||
3335 |
} |
||
3336 |
|||
3337 |
TAILQ_INSERT_TAIL(netconf, n, entry); |
||
3338 |
} |
||
3339 |
break; |
||
3340 |
case 49: |
||
3341 |
#line 701 "parse.y" |
||
3342 |
{ |
||
3343 |
struct network *n; |
||
3344 |
|||
3345 |
if ((n = calloc(1, sizeof(struct network))) == NULL) |
||
3346 |
fatal("new_network"); |
||
3347 |
if (afi2aid(yyvsp[-3].v.number, SAFI_UNICAST, &n->net.prefix.aid) == |
||
3348 |
-1) { |
||
3349 |
yyerror("unknown family"); |
||
3350 |
filterset_free(yyvsp[0].v.filter_set_head); |
||
3351 |
free(yyvsp[0].v.filter_set_head); |
||
3352 |
YYERROR; |
||
3353 |
} |
||
3354 |
n->net.type = NETWORK_RTLABEL; |
||
3355 |
n->net.rtlabel = rtlabel_name2id(yyvsp[-1].v.string); |
||
3356 |
filterset_move(yyvsp[0].v.filter_set_head, &n->net.attrset); |
||
3357 |
free(yyvsp[0].v.filter_set_head); |
||
3358 |
|||
3359 |
TAILQ_INSERT_TAIL(netconf, n, entry); |
||
3360 |
} |
||
3361 |
break; |
||
3362 |
case 50: |
||
3363 |
#line 720 "parse.y" |
||
3364 |
{ |
||
3365 |
struct network *n; |
||
3366 |
|||
3367 |
if ((n = calloc(1, sizeof(struct network))) == NULL) |
||
3368 |
fatal("new_network"); |
||
3369 |
if (afi2aid(yyvsp[-2].v.number, SAFI_UNICAST, &n->net.prefix.aid) == |
||
3370 |
-1) { |
||
3371 |
yyerror("unknown family"); |
||
3372 |
filterset_free(yyvsp[0].v.filter_set_head); |
||
3373 |
free(yyvsp[0].v.filter_set_head); |
||
3374 |
YYERROR; |
||
3375 |
} |
||
3376 |
n->net.type = yyvsp[-1].v.number ? NETWORK_STATIC : NETWORK_CONNECTED; |
||
3377 |
filterset_move(yyvsp[0].v.filter_set_head, &n->net.attrset); |
||
3378 |
free(yyvsp[0].v.filter_set_head); |
||
3379 |
|||
3380 |
TAILQ_INSERT_TAIL(netconf, n, entry); |
||
3381 |
} |
||
3382 |
break; |
||
3383 |
case 51: |
||
3384 |
#line 740 "parse.y" |
||
3385 |
{ yyval.v.number = 1; } |
||
3386 |
break; |
||
3387 |
case 52: |
||
3388 |
#line 741 "parse.y" |
||
3389 |
{ yyval.v.number = 0; } |
||
3390 |
break; |
||
3391 |
case 53: |
||
3392 |
#line 744 "parse.y" |
||
3393 |
{ yyval.v.number = 1; } |
||
3394 |
break; |
||
3395 |
case 54: |
||
3396 |
#line 745 "parse.y" |
||
3397 |
{ yyval.v.number = 0; } |
||
3398 |
break; |
||
3399 |
case 55: |
||
3400 |
#line 748 "parse.y" |
||
3401 |
{ |
||
3402 |
u_int8_t len; |
||
3403 |
|||
3404 |
if (!host(yyvsp[0].v.string, &yyval.v.addr, &len)) { |
||
3405 |
yyerror("could not parse address spec \"%s\"", |
||
3406 |
yyvsp[0].v.string); |
||
3407 |
free(yyvsp[0].v.string); |
||
3408 |
YYERROR; |
||
3409 |
} |
||
3410 |
free(yyvsp[0].v.string); |
||
3411 |
|||
3412 |
if ((yyval.v.addr.aid == AID_INET && len != 32) || |
||
3413 |
(yyval.v.addr.aid == AID_INET6 && len != 128)) { |
||
3414 |
/* unreachable */ |
||
3415 |
yyerror("got prefixlen %u, expected %u", |
||
3416 |
len, yyval.v.addr.aid == AID_INET ? 32 : 128); |
||
3417 |
YYERROR; |
||
3418 |
} |
||
3419 |
} |
||
3420 |
break; |
||
3421 |
case 56: |
||
3422 |
#line 769 "parse.y" |
||
3423 |
{ |
||
3424 |
char *s; |
||
3425 |
|||
3426 |
if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > 128) { |
||
3427 |
yyerror("bad prefixlen %lld", yyvsp[0].v.number); |
||
3428 |
free(yyvsp[-2].v.string); |
||
3429 |
YYERROR; |
||
3430 |
} |
||
3431 |
if (asprintf(&s, "%s/%lld", yyvsp[-2].v.string, yyvsp[0].v.number) == -1) |
||
3432 |
fatal(NULL); |
||
3433 |
free(yyvsp[-2].v.string); |
||
3434 |
|||
3435 |
if (!host(s, &yyval.v.prefix.prefix, &yyval.v.prefix.len)) { |
||
3436 |
yyerror("could not parse address \"%s\"", s); |
||
3437 |
free(s); |
||
3438 |
YYERROR; |
||
3439 |
} |
||
3440 |
free(s); |
||
3441 |
} |
||
3442 |
break; |
||
3443 |
case 57: |
||
3444 |
#line 788 "parse.y" |
||
3445 |
{ |
||
3446 |
char *s; |
||
3447 |
|||
3448 |
/* does not match IPv6 */ |
||
3449 |
if (yyvsp[-2].v.number < 0 || yyvsp[-2].v.number > 255 || yyvsp[0].v.number < 0 || yyvsp[0].v.number > 32) { |
||
3450 |
yyerror("bad prefix %lld/%lld", yyvsp[-2].v.number, yyvsp[0].v.number); |
||
3451 |
YYERROR; |
||
3452 |
} |
||
3453 |
if (asprintf(&s, "%lld/%lld", yyvsp[-2].v.number, yyvsp[0].v.number) == -1) |
||
3454 |
fatal(NULL); |
||
3455 |
|||
3456 |
if (!host(s, &yyval.v.prefix.prefix, &yyval.v.prefix.len)) { |
||
3457 |
yyerror("could not parse address \"%s\"", s); |
||
3458 |
free(s); |
||
3459 |
YYERROR; |
||
3460 |
} |
||
3461 |
free(s); |
||
3462 |
} |
||
3463 |
break; |
||
3464 |
case 58: |
||
3465 |
#line 808 "parse.y" |
||
3466 |
{ |
||
3467 |
memcpy(&yyval.v.prefix.prefix, &yyvsp[0].v.addr, sizeof(struct bgpd_addr)); |
||
3468 |
if (yyval.v.prefix.prefix.aid == AID_INET) |
||
3469 |
yyval.v.prefix.len = 32; |
||
3470 |
else |
||
3471 |
yyval.v.prefix.len = 128; |
||
3472 |
} |
||
3473 |
break; |
||
3474 |
case 63: |
||
3475 |
#line 825 "parse.y" |
||
3476 |
{ yyval.v.number = 0; } |
||
3477 |
break; |
||
3478 |
case 65: |
||
3479 |
#line 829 "parse.y" |
||
3480 |
{ |
||
3481 |
if (ktable_exists(yyvsp[-3].v.number, NULL) != 1) { |
||
3482 |
yyerror("rdomain %lld does not exist", yyvsp[-3].v.number); |
||
3483 |
YYERROR; |
||
3484 |
} |
||
3485 |
if (!(currdom = calloc(1, sizeof(struct rdomain)))) |
||
3486 |
fatal(NULL); |
||
3487 |
currdom->rtableid = yyvsp[-3].v.number; |
||
3488 |
TAILQ_INIT(&currdom->import); |
||
3489 |
TAILQ_INIT(&currdom->export); |
||
3490 |
TAILQ_INIT(&currdom->net_l); |
||
3491 |
netconf = &currdom->net_l; |
||
3492 |
} |
||
3493 |
break; |
||
3494 |
case 66: |
||
3495 |
#line 842 "parse.y" |
||
3496 |
{ |
||
3497 |
/* insert into list */ |
||
3498 |
SIMPLEQ_INSERT_TAIL(&conf->rdomains, currdom, entry); |
||
3499 |
currdom = NULL; |
||
3500 |
netconf = &conf->networks; |
||
3501 |
} |
||
3502 |
break; |
||
3503 |
case 70: |
||
3504 |
#line 856 "parse.y" |
||
3505 |
{ |
||
3506 |
struct filter_extcommunity ext; |
||
3507 |
u_int64_t rd; |
||
3508 |
|||
3509 |
if (parseextcommunity(&ext, "rt", yyvsp[0].v.string) == -1) { |
||
3510 |
free(yyvsp[0].v.string); |
||
3511 |
YYERROR; |
||
3512 |
} |
||
3513 |
free(yyvsp[0].v.string); |
||
3514 |
/* |
||
3515 |
* RD is almost encode like an ext-community, |
||
3516 |
* but only almost so convert here. |
||
3517 |
*/ |
||
3518 |
if (community_ext_conv(&ext, 0, &rd)) { |
||
3519 |
yyerror("bad encoding of rd"); |
||
3520 |
YYERROR; |
||
3521 |
} |
||
3522 |
rd = betoh64(rd) & 0xffffffffffffULL; |
||
3523 |
switch (ext.type) { |
||
3524 |
case EXT_COMMUNITY_TRANS_TWO_AS: |
||
3525 |
rd |= (0ULL << 48); |
||
3526 |
break; |
||
3527 |
case EXT_COMMUNITY_TRANS_IPV4: |
||
3528 |
rd |= (1ULL << 48); |
||
3529 |
break; |
||
3530 |
case EXT_COMMUNITY_TRANS_FOUR_AS: |
||
3531 |
rd |= (2ULL << 48); |
||
3532 |
break; |
||
3533 |
default: |
||
3534 |
yyerror("bad encoding of rd"); |
||
3535 |
YYERROR; |
||
3536 |
} |
||
3537 |
currdom->rd = htobe64(rd); |
||
3538 |
} |
||
3539 |
break; |
||
3540 |
case 71: |
||
3541 |
#line 890 "parse.y" |
||
3542 |
{ |
||
3543 |
struct filter_set *set; |
||
3544 |
|||
3545 |
if ((set = calloc(1, sizeof(struct filter_set))) == |
||
3546 |
NULL) |
||
3547 |
fatal(NULL); |
||
3548 |
set->type = ACTION_SET_EXT_COMMUNITY; |
||
3549 |
if (parseextcommunity(&set->action.ext_community, |
||
3550 |
yyvsp[-1].v.string, yyvsp[0].v.string) == -1) { |
||
3551 |
free(yyvsp[0].v.string); |
||
3552 |
free(yyvsp[-1].v.string); |
||
3553 |
free(set); |
||
3554 |
YYERROR; |
||
3555 |
} |
||
3556 |
free(yyvsp[0].v.string); |
||
3557 |
free(yyvsp[-1].v.string); |
||
3558 |
TAILQ_INSERT_TAIL(&currdom->export, set, entry); |
||
3559 |
} |
||
3560 |
break; |
||
3561 |
case 72: |
||
3562 |
#line 908 "parse.y" |
||
3563 |
{ |
||
3564 |
struct filter_set *set; |
||
3565 |
|||
3566 |
if ((set = calloc(1, sizeof(struct filter_set))) == |
||
3567 |
NULL) |
||
3568 |
fatal(NULL); |
||
3569 |
set->type = ACTION_SET_EXT_COMMUNITY; |
||
3570 |
if (parseextcommunity(&set->action.ext_community, |
||
3571 |
yyvsp[-1].v.string, yyvsp[0].v.string) == -1) { |
||
3572 |
free(yyvsp[0].v.string); |
||
3573 |
free(yyvsp[-1].v.string); |
||
3574 |
free(set); |
||
3575 |
YYERROR; |
||
3576 |
} |
||
3577 |
free(yyvsp[0].v.string); |
||
3578 |
free(yyvsp[-1].v.string); |
||
3579 |
TAILQ_INSERT_TAIL(&currdom->import, set, entry); |
||
3580 |
} |
||
3581 |
break; |
||
3582 |
case 73: |
||
3583 |
#line 926 "parse.y" |
||
3584 |
{ |
||
3585 |
if (strlcpy(currdom->descr, yyvsp[0].v.string, |
||
3586 |
sizeof(currdom->descr)) >= |
||
3587 |
sizeof(currdom->descr)) { |
||
3588 |
yyerror("descr \"%s\" too long: max %zu", |
||
3589 |
yyvsp[0].v.string, sizeof(currdom->descr) - 1); |
||
3590 |
free(yyvsp[0].v.string); |
||
3591 |
YYERROR; |
||
3592 |
} |
||
3593 |
free(yyvsp[0].v.string); |
||
3594 |
} |
||
3595 |
break; |
||
3596 |
case 74: |
||
3597 |
#line 937 "parse.y" |
||
3598 |
{ |
||
3599 |
if (yyvsp[0].v.number == 0) |
||
3600 |
currdom->flags |= F_RIB_NOFIBSYNC; |
||
3601 |
else |
||
3602 |
currdom->flags &= ~F_RIB_NOFIBSYNC; |
||
3603 |
} |
||
3604 |
break; |
||
3605 |
case 76: |
||
3606 |
#line 944 "parse.y" |
||
3607 |
{ |
||
3608 |
/* XXX this is a hack */ |
||
3609 |
if (if_nametoindex(yyvsp[0].v.string) == 0) { |
||
3610 |
yyerror("interface %s does not exist", yyvsp[0].v.string); |
||
3611 |
free(yyvsp[0].v.string); |
||
3612 |
YYERROR; |
||
3613 |
} |
||
3614 |
strlcpy(currdom->ifmpe, yyvsp[0].v.string, IFNAMSIZ); |
||
3615 |
free(yyvsp[0].v.string); |
||
3616 |
if (get_mpe_label(currdom)) { |
||
3617 |
yyerror("failed to get mpls label from %s", |
||
3618 |
currdom->ifmpe); |
||
3619 |
YYERROR; |
||
3620 |
} |
||
3621 |
} |
||
3622 |
break; |
||
3623 |
case 77: |
||
3624 |
#line 961 "parse.y" |
||
3625 |
{ curpeer = new_peer(); } |
||
3626 |
break; |
||
3627 |
case 78: |
||
3628 |
#line 962 "parse.y" |
||
3629 |
{ |
||
3630 |
memcpy(&curpeer->conf.remote_addr, &yyvsp[0].v.prefix.prefix, |
||
3631 |
sizeof(curpeer->conf.remote_addr)); |
||
3632 |
curpeer->conf.remote_masklen = yyvsp[0].v.prefix.len; |
||
3633 |
if ((yyvsp[0].v.prefix.prefix.aid == AID_INET && yyvsp[0].v.prefix.len != 32) || |
||
3634 |
(yyvsp[0].v.prefix.prefix.aid == AID_INET6 && yyvsp[0].v.prefix.len != 128)) |
||
3635 |
curpeer->conf.template = 1; |
||
3636 |
if (curpeer->conf.capabilities.mp[ |
||
3637 |
curpeer->conf.remote_addr.aid] == -1) |
||
3638 |
curpeer->conf.capabilities.mp[ |
||
3639 |
curpeer->conf.remote_addr.aid] = 1; |
||
3640 |
if (get_id(curpeer)) { |
||
3641 |
yyerror("get_id failed"); |
||
3642 |
YYERROR; |
||
3643 |
} |
||
3644 |
} |
||
3645 |
break; |
||
3646 |
case 79: |
||
3647 |
#line 978 "parse.y" |
||
3648 |
{ |
||
3649 |
if (curpeer_filter[0] != NULL) |
||
3650 |
TAILQ_INSERT_TAIL(peerfilter_l, |
||
3651 |
curpeer_filter[0], entry); |
||
3652 |
if (curpeer_filter[1] != NULL) |
||
3653 |
TAILQ_INSERT_TAIL(peerfilter_l, |
||
3654 |
curpeer_filter[1], entry); |
||
3655 |
curpeer_filter[0] = NULL; |
||
3656 |
curpeer_filter[1] = NULL; |
||
3657 |
|||
3658 |
if (neighbor_consistent(curpeer) == -1) |
||
3659 |
YYERROR; |
||
3660 |
curpeer->next = peer_l; |
||
3661 |
peer_l = curpeer; |
||
3662 |
curpeer = curgroup; |
||
3663 |
} |
||
3664 |
break; |
||
3665 |
case 80: |
||
3666 |
#line 996 "parse.y" |
||
3667 |
{ |
||
3668 |
curgroup = curpeer = new_group(); |
||
3669 |
if (strlcpy(curgroup->conf.group, yyvsp[-3].v.string, |
||
3670 |
sizeof(curgroup->conf.group)) >= |
||
3671 |
sizeof(curgroup->conf.group)) { |
||
3672 |
yyerror("group name \"%s\" too long: max %zu", |
||
3673 |
yyvsp[-3].v.string, sizeof(curgroup->conf.group) - 1); |
||
3674 |
free(yyvsp[-3].v.string); |
||
3675 |
YYERROR; |
||
3676 |
} |
||
3677 |
free(yyvsp[-3].v.string); |
||
3678 |
if (get_id(curgroup)) { |
||
3679 |
yyerror("get_id failed"); |
||
3680 |
YYERROR; |
||
3681 |
} |
||
3682 |
} |
||
3683 |
break; |
||
3684 |
case 81: |
||
3685 |
#line 1012 "parse.y" |
||
3686 |
{ |
||
3687 |
if (curgroup_filter[0] != NULL) |
||
3688 |
TAILQ_INSERT_TAIL(groupfilter_l, |
||
3689 |
curgroup_filter[0], entry); |
||
3690 |
if (curgroup_filter[1] != NULL) |
||
3691 |
TAILQ_INSERT_TAIL(groupfilter_l, |
||
3692 |
curgroup_filter[1], entry); |
||
3693 |
curgroup_filter[0] = NULL; |
||
3694 |
curgroup_filter[1] = NULL; |
||
3695 |
|||
3696 |
free(curgroup); |
||
3697 |
curgroup = NULL; |
||
3698 |
} |
||
3699 |
break; |
||
3700 |
case 92: |
||
3701 |
#line 1047 "parse.y" |
||
3702 |
{ |
||
3703 |
curpeer->conf.remote_as = yyvsp[0].v.number; |
||
3704 |
} |
||
3705 |
break; |
||
3706 |
case 93: |
||
3707 |
#line 1050 "parse.y" |
||
3708 |
{ |
||
3709 |
curpeer->conf.local_as = yyvsp[0].v.number; |
||
3710 |
if (yyvsp[0].v.number > USHRT_MAX) |
||
3711 |
curpeer->conf.local_short_as = AS_TRANS; |
||
3712 |
else |
||
3713 |
curpeer->conf.local_short_as = yyvsp[0].v.number; |
||
3714 |
} |
||
3715 |
break; |
||
3716 |
case 94: |
||
3717 |
#line 1057 "parse.y" |
||
3718 |
{ |
||
3719 |
curpeer->conf.local_as = yyvsp[-1].v.number; |
||
3720 |
curpeer->conf.local_short_as = yyvsp[0].v.number; |
||
3721 |
} |
||
3722 |
break; |
||
3723 |
case 95: |
||
3724 |
#line 1061 "parse.y" |
||
3725 |
{ |
||
3726 |
if (strlcpy(curpeer->conf.descr, yyvsp[0].v.string, |
||
3727 |
sizeof(curpeer->conf.descr)) >= |
||
3728 |
sizeof(curpeer->conf.descr)) { |
||
3729 |
yyerror("descr \"%s\" too long: max %zu", |
||
3730 |
yyvsp[0].v.string, sizeof(curpeer->conf.descr) - 1); |
||
3731 |
free(yyvsp[0].v.string); |
||
3732 |
YYERROR; |
||
3733 |
} |
||
3734 |
free(yyvsp[0].v.string); |
||
3735 |
} |
||
3736 |
break; |
||
3737 |
case 96: |
||
3738 |
#line 1072 "parse.y" |
||
3739 |
{ |
||
3740 |
memcpy(&curpeer->conf.local_addr, &yyvsp[0].v.addr, |
||
3741 |
sizeof(curpeer->conf.local_addr)); |
||
3742 |
} |
||
3743 |
break; |
||
3744 |
case 97: |
||
3745 |
#line 1076 "parse.y" |
||
3746 |
{ |
||
3747 |
if (yyvsp[0].v.number < 2 || yyvsp[0].v.number > 255) { |
||
3748 |
yyerror("invalid multihop distance %lld", yyvsp[0].v.number); |
||
3749 |
YYERROR; |
||
3750 |
} |
||
3751 |
curpeer->conf.distance = yyvsp[0].v.number; |
||
3752 |
} |
||
3753 |
break; |
||
3754 |
case 98: |
||
3755 |
#line 1083 "parse.y" |
||
3756 |
{ |
||
3757 |
curpeer->conf.passive = 1; |
||
3758 |
} |
||
3759 |
break; |
||
3760 |
case 99: |
||
3761 |
#line 1086 "parse.y" |
||
3762 |
{ |
||
3763 |
curpeer->conf.down = 1; |
||
3764 |
} |
||
3765 |
break; |
||
3766 |
case 100: |
||
3767 |
#line 1089 "parse.y" |
||
3768 |
{ |
||
3769 |
curpeer->conf.down = 1; |
||
3770 |
if (strlcpy(curpeer->conf.shutcomm, yyvsp[0].v.string, |
||
3771 |
sizeof(curpeer->conf.shutcomm)) >= |
||
3772 |
sizeof(curpeer->conf.shutcomm)) { |
||
3773 |
yyerror("shutdown reason too long"); |
||
3774 |
free(yyvsp[0].v.string); |
||
3775 |
YYERROR; |
||
3776 |
} |
||
3777 |
free(yyvsp[0].v.string); |
||
3778 |
} |
||
3779 |
break; |
||
3780 |
case 101: |
||
3781 |
#line 1100 "parse.y" |
||
3782 |
{ |
||
3783 |
if (!find_rib(yyvsp[0].v.string)) { |
||
3784 |
yyerror("rib \"%s\" does not exist.", yyvsp[0].v.string); |
||
3785 |
free(yyvsp[0].v.string); |
||
3786 |
YYERROR; |
||
3787 |
} |
||
3788 |
if (strlcpy(curpeer->conf.rib, yyvsp[0].v.string, |
||
3789 |
sizeof(curpeer->conf.rib)) >= |
||
3790 |
sizeof(curpeer->conf.rib)) { |
||
3791 |
yyerror("rib name \"%s\" too long: max %zu", |
||
3792 |
yyvsp[0].v.string, sizeof(curpeer->conf.rib) - 1); |
||
3793 |
free(yyvsp[0].v.string); |
||
3794 |
YYERROR; |
||
3795 |
} |
||
3796 |
free(yyvsp[0].v.string); |
||
3797 |
} |
||
3798 |
break; |
||
3799 |
case 102: |
||
3800 |
#line 1116 "parse.y" |
||
3801 |
{ |
||
3802 |
if (yyvsp[0].v.number < MIN_HOLDTIME || yyvsp[0].v.number > USHRT_MAX) { |
||
3803 |
yyerror("holdtime must be between %u and %u", |
||
3804 |
MIN_HOLDTIME, USHRT_MAX); |
||
3805 |
YYERROR; |
||
3806 |
} |
||
3807 |
curpeer->conf.holdtime = yyvsp[0].v.number; |
||
3808 |
} |
||
3809 |
break; |
||
3810 |
case 103: |
||
3811 |
#line 1124 "parse.y" |
||
3812 |
{ |
||
3813 |
if (yyvsp[0].v.number < MIN_HOLDTIME || yyvsp[0].v.number > USHRT_MAX) { |
||
3814 |
yyerror("holdtime must be between %u and %u", |
||
3815 |
MIN_HOLDTIME, USHRT_MAX); |
||
3816 |
YYERROR; |
||
3817 |
} |
||
3818 |
curpeer->conf.min_holdtime = yyvsp[0].v.number; |
||
3819 |
} |
||
3820 |
break; |
||
3821 |
case 104: |
||
3822 |
#line 1132 "parse.y" |
||
3823 |
{ |
||
3824 |
u_int8_t aid, safi; |
||
3825 |
int8_t val = 1; |
||
3826 |
|||
3827 |
if (!strcmp(yyvsp[0].v.string, "none")) { |
||
3828 |
safi = SAFI_UNICAST; |
||
3829 |
val = 0; |
||
3830 |
} else if (!strcmp(yyvsp[0].v.string, "unicast")) { |
||
3831 |
safi = SAFI_UNICAST; |
||
3832 |
} else if (!strcmp(yyvsp[0].v.string, "vpn")) { |
||
3833 |
safi = SAFI_MPLSVPN; |
||
3834 |
} else { |
||
3835 |
yyerror("unknown/unsupported SAFI \"%s\"", |
||
3836 |
yyvsp[0].v.string); |
||
3837 |
free(yyvsp[0].v.string); |
||
3838 |
YYERROR; |
||
3839 |
} |
||
3840 |
free(yyvsp[0].v.string); |
||
3841 |
|||
3842 |
if (afi2aid(yyvsp[-1].v.number, safi, &aid) == -1) { |
||
3843 |
yyerror("unknown AFI/SAFI pair"); |
||
3844 |
YYERROR; |
||
3845 |
} |
||
3846 |
curpeer->conf.capabilities.mp[aid] = val; |
||
3847 |
} |
||
3848 |
break; |
||
3849 |
case 105: |
||
3850 |
#line 1157 "parse.y" |
||
3851 |
{ |
||
3852 |
curpeer->conf.announce_capa = yyvsp[0].v.number; |
||
3853 |
} |
||
3854 |
break; |
||
3855 |
case 106: |
||
3856 |
#line 1160 "parse.y" |
||
3857 |
{ |
||
3858 |
curpeer->conf.capabilities.refresh = yyvsp[0].v.number; |
||
3859 |
} |
||
3860 |
break; |
||
3861 |
case 107: |
||
3862 |
#line 1163 "parse.y" |
||
3863 |
{ |
||
3864 |
curpeer->conf.capabilities.grestart.restart = yyvsp[0].v.number; |
||
3865 |
} |
||
3866 |
break; |
||
3867 |
case 108: |
||
3868 |
#line 1166 "parse.y" |
||
3869 |
{ |
||
3870 |
curpeer->conf.capabilities.as4byte = yyvsp[0].v.number; |
||
3871 |
} |
||
3872 |
break; |
||
3873 |
case 109: |
||
3874 |
#line 1169 "parse.y" |
||
3875 |
{ |
||
3876 |
curpeer->conf.announce_type = ANNOUNCE_SELF; |
||
3877 |
} |
||
3878 |
break; |
||
3879 |
case 110: |
||
3880 |
#line 1172 "parse.y" |
||
3881 |
{ |
||
3882 |
if (!strcmp(yyvsp[0].v.string, "self")) |
||
3883 |
curpeer->conf.announce_type = ANNOUNCE_SELF; |
||
3884 |
else if (!strcmp(yyvsp[0].v.string, "none")) |
||
3885 |
curpeer->conf.announce_type = ANNOUNCE_NONE; |
||
3886 |
else if (!strcmp(yyvsp[0].v.string, "all")) |
||
3887 |
curpeer->conf.announce_type = ANNOUNCE_ALL; |
||
3888 |
else if (!strcmp(yyvsp[0].v.string, "default-route")) |
||
3889 |
curpeer->conf.announce_type = |
||
3890 |
ANNOUNCE_DEFAULT_ROUTE; |
||
3891 |
else { |
||
3892 |
yyerror("invalid announce type"); |
||
3893 |
free(yyvsp[0].v.string); |
||
3894 |
YYERROR; |
||
3895 |
} |
||
3896 |
free(yyvsp[0].v.string); |
||
3897 |
} |
||
3898 |
break; |
||
3899 |
case 111: |
||
3900 |
#line 1189 "parse.y" |
||
3901 |
{ |
||
3902 |
if (yyvsp[0].v.number) |
||
3903 |
curpeer->conf.enforce_as = ENFORCE_AS_ON; |
||
3904 |
else |
||
3905 |
curpeer->conf.enforce_as = ENFORCE_AS_OFF; |
||
3906 |
} |
||
3907 |
break; |
||
3908 |
case 112: |
||
3909 |
#line 1195 "parse.y" |
||
3910 |
{ |
||
3911 |
if (yyvsp[0].v.number) |
||
3912 |
curpeer->conf.enforce_local_as = ENFORCE_AS_ON; |
||
3913 |
else |
||
3914 |
curpeer->conf.enforce_local_as = ENFORCE_AS_OFF; |
||
3915 |
} |
||
3916 |
break; |
||
3917 |
case 113: |
||
3918 |
#line 1201 "parse.y" |
||
3919 |
{ |
||
3920 |
if (yyvsp[-1].v.number < 0 || yyvsp[-1].v.number > UINT_MAX) { |
||
3921 |
yyerror("bad maximum number of prefixes"); |
||
3922 |
YYERROR; |
||
3923 |
} |
||
3924 |
curpeer->conf.max_prefix = yyvsp[-1].v.number; |
||
3925 |
curpeer->conf.max_prefix_restart = yyvsp[0].v.number; |
||
3926 |
} |
||
3927 |
break; |
||
3928 |
case 114: |
||
3929 |
#line 1209 "parse.y" |
||
3930 |
{ |
||
3931 |
if (curpeer->conf.auth.method) { |
||
3932 |
yyerror("auth method cannot be redefined"); |
||
3933 |
free(yyvsp[0].v.string); |
||
3934 |
YYERROR; |
||
3935 |
} |
||
3936 |
if (strlcpy(curpeer->conf.auth.md5key, yyvsp[0].v.string, |
||
3937 |
sizeof(curpeer->conf.auth.md5key)) >= |
||
3938 |
sizeof(curpeer->conf.auth.md5key)) { |
||
3939 |
yyerror("tcp md5sig password too long: max %zu", |
||
3940 |
sizeof(curpeer->conf.auth.md5key) - 1); |
||
3941 |
free(yyvsp[0].v.string); |
||
3942 |
YYERROR; |
||
3943 |
} |
||
3944 |
curpeer->conf.auth.method = AUTH_MD5SIG; |
||
3945 |
curpeer->conf.auth.md5key_len = strlen(yyvsp[0].v.string); |
||
3946 |
free(yyvsp[0].v.string); |
||
3947 |
} |
||
3948 |
break; |
||
3949 |
case 115: |
||
3950 |
#line 1227 "parse.y" |
||
3951 |
{ |
||
3952 |
if (curpeer->conf.auth.method) { |
||
3953 |
yyerror("auth method cannot be redefined"); |
||
3954 |
free(yyvsp[0].v.string); |
||
3955 |
YYERROR; |
||
3956 |
} |
||
3957 |
|||
3958 |
if (str2key(yyvsp[0].v.string, curpeer->conf.auth.md5key, |
||
3959 |
sizeof(curpeer->conf.auth.md5key)) == -1) { |
||
3960 |
free(yyvsp[0].v.string); |
||
3961 |
YYERROR; |
||
3962 |
} |
||
3963 |
curpeer->conf.auth.method = AUTH_MD5SIG; |
||
3964 |
curpeer->conf.auth.md5key_len = strlen(yyvsp[0].v.string) / 2; |
||
3965 |
free(yyvsp[0].v.string); |
||
3966 |
} |
||
3967 |
break; |
||
3968 |
case 116: |
||
3969 |
#line 1243 "parse.y" |
||
3970 |
{ |
||
3971 |
if (curpeer->conf.auth.method) { |
||
3972 |
yyerror("auth method cannot be redefined"); |
||
3973 |
YYERROR; |
||
3974 |
} |
||
3975 |
if (yyvsp[-1].v.number) |
||
3976 |
curpeer->conf.auth.method = AUTH_IPSEC_IKE_ESP; |
||
3977 |
else |
||
3978 |
curpeer->conf.auth.method = AUTH_IPSEC_IKE_AH; |
||
3979 |
} |
||
3980 |
break; |
||
3981 |
case 117: |
||
3982 |
#line 1253 "parse.y" |
||
3983 |
{ |
||
3984 |
u_int32_t auth_alg; |
||
3985 |
u_int8_t keylen; |
||
3986 |
|||
3987 |
if (curpeer->conf.auth.method && |
||
3988 |
(((curpeer->conf.auth.spi_in && yyvsp[-5].v.number == 1) || |
||
3989 |
(curpeer->conf.auth.spi_out && yyvsp[-5].v.number == 0)) || |
||
3990 |
(yyvsp[-6].v.number == 1 && curpeer->conf.auth.method != |
||
3991 |
AUTH_IPSEC_MANUAL_ESP) || |
||
3992 |
(yyvsp[-6].v.number == 0 && curpeer->conf.auth.method != |
||
3993 |
AUTH_IPSEC_MANUAL_AH))) { |
||
3994 |
yyerror("auth method cannot be redefined"); |
||
3995 |
free(yyvsp[-2].v.string); |
||
3996 |
free(yyvsp[-1].v.string); |
||
3997 |
YYERROR; |
||
3998 |
} |
||
3999 |
|||
4000 |
if (!strcmp(yyvsp[-2].v.string, "sha1")) { |
||
4001 |
auth_alg = SADB_AALG_SHA1HMAC; |
||
4002 |
keylen = 20; |
||
4003 |
} else if (!strcmp(yyvsp[-2].v.string, "md5")) { |
||
4004 |
auth_alg = SADB_AALG_MD5HMAC; |
||
4005 |
keylen = 16; |
||
4006 |
} else { |
||
4007 |
yyerror("unknown auth algorithm \"%s\"", yyvsp[-2].v.string); |
||
4008 |
free(yyvsp[-2].v.string); |
||
4009 |
free(yyvsp[-1].v.string); |
||
4010 |
YYERROR; |
||
4011 |
} |
||
4012 |
free(yyvsp[-2].v.string); |
||
4013 |
|||
4014 |
if (strlen(yyvsp[-1].v.string) / 2 != keylen) { |
||
4015 |
yyerror("auth key len: must be %u bytes, " |
||
4016 |
"is %zu bytes", keylen, strlen(yyvsp[-1].v.string) / 2); |
||
4017 |
free(yyvsp[-1].v.string); |
||
4018 |
YYERROR; |
||
4019 |
} |
||
4020 |
|||
4021 |
if (yyvsp[-6].v.number) |
||
4022 |
curpeer->conf.auth.method = |
||
4023 |
AUTH_IPSEC_MANUAL_ESP; |
||
4024 |
else { |
||
4025 |
if (yyvsp[0].v.encspec.enc_alg) { |
||
4026 |
yyerror("\"ipsec ah\" doesn't take " |
||
4027 |
"encryption keys"); |
||
4028 |
free(yyvsp[-1].v.string); |
||
4029 |
YYERROR; |
||
4030 |
} |
||
4031 |
curpeer->conf.auth.method = |
||
4032 |
AUTH_IPSEC_MANUAL_AH; |
||
4033 |
} |
||
4034 |
|||
4035 |
if (yyvsp[-3].v.number <= SPI_RESERVED_MAX || yyvsp[-3].v.number > UINT_MAX) { |
||
4036 |
yyerror("bad spi number %lld", yyvsp[-3].v.number); |
||
4037 |
free(yyvsp[-1].v.string); |
||
4038 |
YYERROR; |
||
4039 |
} |
||
4040 |
|||
4041 |
if (yyvsp[-5].v.number == 1) { |
||
4042 |
if (str2key(yyvsp[-1].v.string, curpeer->conf.auth.auth_key_in, |
||
4043 |
sizeof(curpeer->conf.auth.auth_key_in)) == |
||
4044 |
-1) { |
||
4045 |
free(yyvsp[-1].v.string); |
||
4046 |
YYERROR; |
||
4047 |
} |
||
4048 |
curpeer->conf.auth.spi_in = yyvsp[-3].v.number; |
||
4049 |
curpeer->conf.auth.auth_alg_in = auth_alg; |
||
4050 |
curpeer->conf.auth.enc_alg_in = yyvsp[0].v.encspec.enc_alg; |
||
4051 |
memcpy(&curpeer->conf.auth.enc_key_in, |
||
4052 |
&yyvsp[0].v.encspec.enc_key, |
||
4053 |
sizeof(curpeer->conf.auth.enc_key_in)); |
||
4054 |
curpeer->conf.auth.enc_keylen_in = |
||
4055 |
yyvsp[0].v.encspec.enc_key_len; |
||
4056 |
curpeer->conf.auth.auth_keylen_in = keylen; |
||
4057 |
} else { |
||
4058 |
if (str2key(yyvsp[-1].v.string, curpeer->conf.auth.auth_key_out, |
||
4059 |
sizeof(curpeer->conf.auth.auth_key_out)) == |
||
4060 |
-1) { |
||
4061 |
free(yyvsp[-1].v.string); |
||
4062 |
YYERROR; |
||
4063 |
} |
||
4064 |
curpeer->conf.auth.spi_out = yyvsp[-3].v.number; |
||
4065 |
curpeer->conf.auth.auth_alg_out = auth_alg; |
||
4066 |
curpeer->conf.auth.enc_alg_out = yyvsp[0].v.encspec.enc_alg; |
||
4067 |
memcpy(&curpeer->conf.auth.enc_key_out, |
||
4068 |
&yyvsp[0].v.encspec.enc_key, |
||
4069 |
sizeof(curpeer->conf.auth.enc_key_out)); |
||
4070 |
curpeer->conf.auth.enc_keylen_out = |
||
4071 |
yyvsp[0].v.encspec.enc_key_len; |
||
4072 |
curpeer->conf.auth.auth_keylen_out = keylen; |
||
4073 |
} |
||
4074 |
free(yyvsp[-1].v.string); |
||
4075 |
} |
||
4076 |
break; |
||
4077 |
case 118: |
||
4078 |
#line 1346 "parse.y" |
||
4079 |
{ |
||
4080 |
curpeer->conf.ttlsec = yyvsp[0].v.number; |
||
4081 |
} |
||
4082 |
break; |
||
4083 |
case 119: |
||
4084 |
#line 1349 "parse.y" |
||
4085 |
{ |
||
4086 |
struct filter_rule *r; |
||
4087 |
|||
4088 |
r = get_rule(yyvsp[0].v.filter_set->type); |
||
4089 |
if (merge_filterset(&r->set, yyvsp[0].v.filter_set) == -1) |
||
4090 |
YYERROR; |
||
4091 |
} |
||
4092 |
break; |
||
4093 |
case 120: |
||
4094 |
#line 1356 "parse.y" |
||
4095 |
{ |
||
4096 |
struct filter_rule *r; |
||
4097 |
struct filter_set *s; |
||
4098 |
|||
4099 |
while ((s = TAILQ_FIRST(yyvsp[-2].v.filter_set_head)) != NULL) { |
||
4100 |
TAILQ_REMOVE(yyvsp[-2].v.filter_set_head, s, entry); |
||
4101 |
r = get_rule(s->type); |
||
4102 |
if (merge_filterset(&r->set, s) == -1) |
||
4103 |
YYERROR; |
||
4104 |
} |
||
4105 |
free(yyvsp[-2].v.filter_set_head); |
||
4106 |
} |
||
4107 |
break; |
||
4108 |
case 122: |
||
4109 |
#line 1369 "parse.y" |
||
4110 |
{ |
||
4111 |
if ((conf->flags & BGPD_FLAG_REFLECTOR) && |
||
4112 |
conf->clusterid != 0) { |
||
4113 |
yyerror("only one route reflector " |
||
4114 |
"cluster allowed"); |
||
4115 |
YYERROR; |
||
4116 |
} |
||
4117 |
conf->flags |= BGPD_FLAG_REFLECTOR; |
||
4118 |
curpeer->conf.reflector_client = 1; |
||
4119 |
} |
||
4120 |
break; |
||
4121 |
case 123: |
||
4122 |
#line 1379 "parse.y" |
||
4123 |
{ |
||
4124 |
if (yyvsp[0].v.addr.aid != AID_INET) { |
||
4125 |
yyerror("route reflector cluster-id must be " |
||
4126 |
"an IPv4 address"); |
||
4127 |
YYERROR; |
||
4128 |
} |
||
4129 |
if ((conf->flags & BGPD_FLAG_REFLECTOR) && |
||
4130 |
conf->clusterid != yyvsp[0].v.addr.v4.s_addr) { |
||
4131 |
yyerror("only one route reflector " |
||
4132 |
"cluster allowed"); |
||
4133 |
YYERROR; |
||
4134 |
} |
||
4135 |
conf->flags |= BGPD_FLAG_REFLECTOR; |
||
4136 |
curpeer->conf.reflector_client = 1; |
||
4137 |
conf->clusterid = yyvsp[0].v.addr.v4.s_addr; |
||
4138 |
} |
||
4139 |
break; |
||
4140 |
case 124: |
||
4141 |
#line 1395 "parse.y" |
||
4142 |
{ |
||
4143 |
if (strlcpy(curpeer->conf.if_depend, yyvsp[0].v.string, |
||
4144 |
sizeof(curpeer->conf.if_depend)) >= |
||
4145 |
sizeof(curpeer->conf.if_depend)) { |
||
4146 |
yyerror("interface name \"%s\" too long: " |
||
4147 |
"max %zu", yyvsp[0].v.string, |
||
4148 |
sizeof(curpeer->conf.if_depend) - 1); |
||
4149 |
free(yyvsp[0].v.string); |
||
4150 |
YYERROR; |
||
4151 |
} |
||
4152 |
free(yyvsp[0].v.string); |
||
4153 |
} |
||
4154 |
break; |
||
4155 |
case 125: |
||
4156 |
#line 1407 "parse.y" |
||
4157 |
{ |
||
4158 |
if (strlcpy(curpeer->conf.demote_group, yyvsp[0].v.string, |
||
4159 |
sizeof(curpeer->conf.demote_group)) >= |
||
4160 |
sizeof(curpeer->conf.demote_group)) { |
||
4161 |
yyerror("demote group name \"%s\" too long: " |
||
4162 |
"max %zu", yyvsp[0].v.string, |
||
4163 |
sizeof(curpeer->conf.demote_group) - 1); |
||
4164 |
free(yyvsp[0].v.string); |
||
4165 |
YYERROR; |
||
4166 |
} |
||
4167 |
free(yyvsp[0].v.string); |
||
4168 |
if (carp_demote_init(curpeer->conf.demote_group, |
||
4169 |
cmd_opts & BGPD_OPT_FORCE_DEMOTE) == -1) { |
||
4170 |
yyerror("error initializing group \"%s\"", |
||
4171 |
curpeer->conf.demote_group); |
||
4172 |
YYERROR; |
||
4173 |
} |
||
4174 |
} |
||
4175 |
break; |
||
4176 |
case 126: |
||
4177 |
#line 1425 "parse.y" |
||
4178 |
{ |
||
4179 |
if (yyvsp[0].v.number == 1) |
||
4180 |
curpeer->conf.flags |= PEERFLAG_TRANS_AS; |
||
4181 |
else |
||
4182 |
curpeer->conf.flags &= ~PEERFLAG_TRANS_AS; |
||
4183 |
} |
||
4184 |
break; |
||
4185 |
case 127: |
||
4186 |
#line 1431 "parse.y" |
||
4187 |
{ |
||
4188 |
if (!strcmp(yyvsp[0].v.string, "updates")) |
||
4189 |
curpeer->conf.flags |= PEERFLAG_LOG_UPDATES; |
||
4190 |
else if (!strcmp(yyvsp[0].v.string, "no")) |
||
4191 |
curpeer->conf.flags &= ~PEERFLAG_LOG_UPDATES; |
||
4192 |
else { |
||
4193 |
free(yyvsp[0].v.string); |
||
4194 |
YYERROR; |
||
4195 |
} |
||
4196 |
free(yyvsp[0].v.string); |
||
4197 |
} |
||
4198 |
break; |
||
4199 |
case 128: |
||
4200 |
#line 1444 "parse.y" |
||
4201 |
{ yyval.v.number = 0; } |
||
4202 |
break; |
||
4203 |
case 129: |
||
4204 |
#line 1445 "parse.y" |
||
4205 |
{ |
||
4206 |
if (yyvsp[0].v.number < 1 || yyvsp[0].v.number > USHRT_MAX) { |
||
4207 |
yyerror("restart out of range. 1 to %u minutes", |
||
4208 |
USHRT_MAX); |
||
4209 |
YYERROR; |
||
4210 |
} |
||
4211 |
yyval.v.number = yyvsp[0].v.number; |
||
4212 |
} |
||
4213 |
break; |
||
4214 |
case 130: |
||
4215 |
#line 1455 "parse.y" |
||
4216 |
{ yyval.v.number = AFI_IPv4; } |
||
4217 |
break; |
||
4218 |
case 131: |
||
4219 |
#line 1456 "parse.y" |
||
4220 |
{ yyval.v.number = AFI_IPv6; } |
||
4221 |
break; |
||
4222 |
case 132: |
||
4223 |
#line 1459 "parse.y" |
||
4224 |
{ yyval.v.number = 1; } |
||
4225 |
break; |
||
4226 |
case 133: |
||
4227 |
#line 1460 "parse.y" |
||
4228 |
{ yyval.v.number = 0; } |
||
4229 |
break; |
||
4230 |
case 134: |
||
4231 |
#line 1463 "parse.y" |
||
4232 |
{ yyval.v.number = 1; } |
||
4233 |
break; |
||
4234 |
case 135: |
||
4235 |
#line 1464 "parse.y" |
||
4236 |
{ yyval.v.number = 0; } |
||
4237 |
break; |
||
4238 |
case 136: |
||
4239 |
#line 1467 "parse.y" |
||
4240 |
{ |
||
4241 |
bzero(&yyval.v.encspec, sizeof(yyval.v.encspec)); |
||
4242 |
} |
||
4243 |
break; |
||
4244 |
case 137: |
||
4245 |
#line 1470 "parse.y" |
||
4246 |
{ |
||
4247 |
bzero(&yyval.v.encspec, sizeof(yyval.v.encspec)); |
||
4248 |
if (!strcmp(yyvsp[-1].v.string, "3des") || !strcmp(yyvsp[-1].v.string, "3des-cbc")) { |
||
4249 |
yyval.v.encspec.enc_alg = SADB_EALG_3DESCBC; |
||
4250 |
yyval.v.encspec.enc_key_len = 21; /* XXX verify */ |
||
4251 |
} else if (!strcmp(yyvsp[-1].v.string, "aes") || |
||
4252 |
!strcmp(yyvsp[-1].v.string, "aes-128-cbc")) { |
||
4253 |
yyval.v.encspec.enc_alg = SADB_X_EALG_AES; |
||
4254 |
yyval.v.encspec.enc_key_len = 16; |
||
4255 |
} else { |
||
4256 |
yyerror("unknown enc algorithm \"%s\"", yyvsp[-1].v.string); |
||
4257 |
free(yyvsp[-1].v.string); |
||
4258 |
free(yyvsp[0].v.string); |
||
4259 |
YYERROR; |
||
4260 |
} |
||
4261 |
free(yyvsp[-1].v.string); |
||
4262 |
|||
4263 |
if (strlen(yyvsp[0].v.string) / 2 != yyval.v.encspec.enc_key_len) { |
||
4264 |
yyerror("enc key length wrong: should be %u " |
||
4265 |
"bytes, is %zu bytes", |
||
4266 |
yyval.v.encspec.enc_key_len * 2, strlen(yyvsp[0].v.string)); |
||
4267 |
free(yyvsp[0].v.string); |
||
4268 |
YYERROR; |
||
4269 |
} |
||
4270 |
|||
4271 |
if (str2key(yyvsp[0].v.string, yyval.v.encspec.enc_key, sizeof(yyval.v.encspec.enc_key)) == -1) { |
||
4272 |
free(yyvsp[0].v.string); |
||
4273 |
YYERROR; |
||
4274 |
} |
||
4275 |
free(yyvsp[0].v.string); |
||
4276 |
} |
||
4277 |
break; |
||
4278 |
case 138: |
||
4279 |
#line 1504 "parse.y" |
||
4280 |
{ |
||
4281 |
struct filter_rule r; |
||
4282 |
struct filter_rib_l *rb, *rbnext; |
||
4283 |
|||
4284 |
bzero(&r, sizeof(r)); |
||
4285 |
r.action = yyvsp[-6].v.u8; |
||
4286 |
r.quick = yyvsp[-5].v.u8; |
||
4287 |
r.dir = yyvsp[-3].v.u8; |
||
4288 |
if (yyvsp[-4].v.filter_rib) { |
||
4289 |
if (r.dir != DIR_IN) { |
||
4290 |
yyerror("rib only allowed on \"from\" " |
||
4291 |
"rules."); |
||
4292 |
|||
4293 |
for (rb = yyvsp[-4].v.filter_rib; rb != NULL; rb = rbnext) { |
||
4294 |
rbnext = rb->next; |
||
4295 |
free(rb); |
||
4296 |
} |
||
4297 |
YYERROR; |
||
4298 |
} |
||
4299 |
} |
||
4300 |
if (expand_rule(&r, yyvsp[-4].v.filter_rib, yyvsp[-2].v.filter_peers, &yyvsp[-1].v.filter_match, yyvsp[0].v.filter_set_head) == -1) |
||
4301 |
YYERROR; |
||
4302 |
} |
||
4303 |
break; |
||
4304 |
case 139: |
||
4305 |
#line 1529 "parse.y" |
||
4306 |
{ yyval.v.u8 = ACTION_ALLOW; } |
||
4307 |
break; |
||
4308 |
case 140: |
||
4309 |
#line 1530 "parse.y" |
||
4310 |
{ yyval.v.u8 = ACTION_DENY; } |
||
4311 |
break; |
||
4312 |
case 141: |
||
4313 |
#line 1531 "parse.y" |
||
4314 |
{ yyval.v.u8 = ACTION_NONE; } |
||
4315 |
break; |
||
4316 |
case 142: |
||
4317 |
#line 1534 "parse.y" |
||
4318 |
{ yyval.v.u8 = 0; } |
||
4319 |
break; |
||
4320 |
case 143: |
||
4321 |
#line 1535 "parse.y" |
||
4322 |
{ yyval.v.u8 = 1; } |
||
4323 |
break; |
||
4324 |
case 144: |
||
4325 |
#line 1538 "parse.y" |
||
4326 |
{ yyval.v.u8 = DIR_IN; } |
||
4327 |
break; |
||
4328 |
case 145: |
||
4329 |
#line 1539 "parse.y" |
||
4330 |
{ yyval.v.u8 = DIR_OUT; } |
||
4331 |
break; |
||
4332 |
case 146: |
||
4333 |
#line 1542 "parse.y" |
||
4334 |
{ yyval.v.filter_rib = NULL; } |
||
4335 |
break; |
||
4336 |
case 147: |
||
4337 |
#line 1543 "parse.y" |
||
4338 |
{ yyval.v.filter_rib = yyvsp[0].v.filter_rib; } |
||
4339 |
break; |
||
4340 |
case 148: |
||
4341 |
#line 1544 "parse.y" |
||
4342 |
{ yyval.v.filter_rib = yyvsp[-1].v.filter_rib; } |
||
4343 |
break; |
||
4344 |
case 149: |
||
4345 |
#line 1546 "parse.y" |
||
4346 |
{ yyval.v.filter_rib = yyvsp[0].v.filter_rib; } |
||
4347 |
break; |
||
4348 |
case 150: |
||
4349 |
#line 1547 "parse.y" |
||
4350 |
{ |
||
4351 |
yyvsp[0].v.filter_rib->next = yyvsp[-2].v.filter_rib; |
||
4352 |
yyval.v.filter_rib = yyvsp[0].v.filter_rib; |
||
4353 |
} |
||
4354 |
break; |
||
4355 |
case 151: |
||
4356 |
#line 1553 "parse.y" |
||
4357 |
{ |
||
4358 |
if (!find_rib(yyvsp[0].v.string)) { |
||
4359 |
yyerror("rib \"%s\" does not exist.", yyvsp[0].v.string); |
||
4360 |
free(yyvsp[0].v.string); |
||
4361 |
YYERROR; |
||
4362 |
} |
||
4363 |
if ((yyval.v.filter_rib = calloc(1, sizeof(struct filter_rib_l))) == |
||
4364 |
NULL) |
||
4365 |
fatal(NULL); |
||
4366 |
yyval.v.filter_rib->next = NULL; |
||
4367 |
if (strlcpy(yyval.v.filter_rib->name, yyvsp[0].v.string, sizeof(yyval.v.filter_rib->name)) >= |
||
4368 |
sizeof(yyval.v.filter_rib->name)) { |
||
4369 |
yyerror("rib name \"%s\" too long: " |
||
4370 |
"max %zu", yyvsp[0].v.string, sizeof(yyval.v.filter_rib->name) - 1); |
||
4371 |
free(yyvsp[0].v.string); |
||
4372 |
free(yyval.v.filter_rib); |
||
4373 |
YYERROR; |
||
4374 |
} |
||
4375 |
free(yyvsp[0].v.string); |
||
4376 |
} |
||
4377 |
break; |
||
4378 |
case 153: |
||
4379 |
#line 1576 "parse.y" |
||
4380 |
{ yyval.v.filter_peers = yyvsp[-1].v.filter_peers; } |
||
4381 |
break; |
||
4382 |
case 154: |
||
4383 |
#line 1579 "parse.y" |
||
4384 |
{ yyval.v.filter_peers = yyvsp[0].v.filter_peers; } |
||
4385 |
break; |
||
4386 |
case 155: |
||
4387 |
#line 1580 "parse.y" |
||
4388 |
{ |
||
4389 |
yyvsp[0].v.filter_peers->next = yyvsp[-2].v.filter_peers; |
||
4390 |
yyval.v.filter_peers = yyvsp[0].v.filter_peers; |
||
4391 |
} |
||
4392 |
break; |
||
4393 |
case 156: |
||
4394 |
#line 1586 "parse.y" |
||
4395 |
{ |
||
4396 |
if ((yyval.v.filter_peers = calloc(1, sizeof(struct filter_peers_l))) == |
||
4397 |
NULL) |
||
4398 |
fatal(NULL); |
||
4399 |
yyval.v.filter_peers->p.peerid = yyval.v.filter_peers->p.groupid = 0; |
||
4400 |
yyval.v.filter_peers->next = NULL; |
||
4401 |
} |
||
4402 |
break; |
||
4403 |
case 157: |
||
4404 |
#line 1593 "parse.y" |
||
4405 |
{ |
||
4406 |
struct peer *p; |
||
4407 |
|||
4408 |
if ((yyval.v.filter_peers = calloc(1, sizeof(struct filter_peers_l))) == |
||
4409 |
NULL) |
||
4410 |
fatal(NULL); |
||
4411 |
yyval.v.filter_peers->p.remote_as = yyval.v.filter_peers->p.groupid = yyval.v.filter_peers->p.peerid = 0; |
||
4412 |
yyval.v.filter_peers->next = NULL; |
||
4413 |
for (p = peer_l; p != NULL; p = p->next) |
||
4414 |
if (!memcmp(&p->conf.remote_addr, |
||
4415 |
&yyvsp[0].v.addr, sizeof(p->conf.remote_addr))) { |
||
4416 |
yyval.v.filter_peers->p.peerid = p->conf.id; |
||
4417 |
break; |
||
4418 |
} |
||
4419 |
if (yyval.v.filter_peers->p.peerid == 0) { |
||
4420 |
yyerror("no such peer: %s", log_addr(&yyvsp[0].v.addr)); |
||
4421 |
free(yyval.v.filter_peers); |
||
4422 |
YYERROR; |
||
4423 |
} |
||
4424 |
} |
||
4425 |
break; |
||
4426 |
case 158: |
||
4427 |
#line 1613 "parse.y" |
||
4428 |
{ |
||
4429 |
if ((yyval.v.filter_peers = calloc(1, sizeof(struct filter_peers_l))) == |
||
4430 |
NULL) |
||
4431 |
fatal(NULL); |
||
4432 |
yyval.v.filter_peers->p.groupid = yyval.v.filter_peers->p.peerid = 0; |
||
4433 |
yyval.v.filter_peers->p.remote_as = yyvsp[0].v.number; |
||
4434 |
} |
||
4435 |
break; |
||
4436 |
case 159: |
||
4437 |
#line 1620 "parse.y" |
||
4438 |
{ |
||
4439 |
struct peer *p; |
||
4440 |
|||
4441 |
if ((yyval.v.filter_peers = calloc(1, sizeof(struct filter_peers_l))) == |
||
4442 |
NULL) |
||
4443 |
fatal(NULL); |
||
4444 |
yyval.v.filter_peers->p.remote_as = yyval.v.filter_peers->p.peerid = 0; |
||
4445 |
yyval.v.filter_peers->next = NULL; |
||
4446 |
for (p = peer_l; p != NULL; p = p->next) |
||
4447 |
if (!strcmp(p->conf.group, yyvsp[0].v.string)) { |
||
4448 |
yyval.v.filter_peers->p.groupid = p->conf.groupid; |
||
4449 |
break; |
||
4450 |
} |
||
4451 |
if (yyval.v.filter_peers->p.groupid == 0) { |
||
4452 |
yyerror("no such group: \"%s\"", yyvsp[0].v.string); |
||
4453 |
free(yyvsp[0].v.string); |
||
4454 |
free(yyval.v.filter_peers); |
||
4455 |
YYERROR; |
||
4456 |
} |
||
4457 |
free(yyvsp[0].v.string); |
||
4458 |
} |
||
4459 |
break; |
||
4460 |
case 160: |
||
4461 |
#line 1641 "parse.y" |
||
4462 |
{ |
||
4463 |
if ((yyval.v.filter_peers = calloc(1, sizeof(struct filter_peers_l))) == |
||
4464 |
NULL) |
||
4465 |
fatal(NULL); |
||
4466 |
yyval.v.filter_peers->p.ebgp = 1; |
||
4467 |
} |
||
4468 |
break; |
||
4469 |
case 161: |
||
4470 |
#line 1647 "parse.y" |
||
4471 |
{ |
||
4472 |
if ((yyval.v.filter_peers = calloc(1, sizeof(struct filter_peers_l))) == |
||
4473 |
NULL) |
||
4474 |
fatal(NULL); |
||
4475 |
yyval.v.filter_peers->p.ibgp = 1; |
||
4476 |
} |
||
4477 |
break; |
||
4478 |
case 162: |
||
4479 |
#line 1655 "parse.y" |
||
4480 |
{ |
||
4481 |
if (yyvsp[0].v.prefixlen.op == OP_NONE) |
||
4482 |
yyvsp[0].v.prefixlen.op = OP_GE; |
||
4483 |
if ((yyval.v.filter_prefix = calloc(1, sizeof(struct filter_prefix_l))) == |
||
4484 |
NULL) |
||
4485 |
fatal(NULL); |
||
4486 |
yyval.v.filter_prefix->p.addr.aid = AID_INET; |
||
4487 |
if (merge_prefixspec(yyval.v.filter_prefix, &yyvsp[0].v.prefixlen) == -1) { |
||
4488 |
free(yyval.v.filter_prefix); |
||
4489 |
YYERROR; |
||
4490 |
} |
||
4491 |
} |
||
4492 |
break; |
||
4493 |
case 163: |
||
4494 |
#line 1667 "parse.y" |
||
4495 |
{ |
||
4496 |
if (yyvsp[0].v.prefixlen.op == OP_NONE) |
||
4497 |
yyvsp[0].v.prefixlen.op = OP_GE; |
||
4498 |
if ((yyval.v.filter_prefix = calloc(1, sizeof(struct filter_prefix_l))) == |
||
4499 |
NULL) |
||
4500 |
fatal(NULL); |
||
4501 |
yyval.v.filter_prefix->p.addr.aid = AID_INET6; |
||
4502 |
if (merge_prefixspec(yyval.v.filter_prefix, &yyvsp[0].v.prefixlen) == -1) { |
||
4503 |
free(yyval.v.filter_prefix); |
||
4504 |
YYERROR; |
||
4505 |
} |
||
4506 |
} |
||
4507 |
break; |
||
4508 |
case 164: |
||
4509 |
#line 1679 "parse.y" |
||
4510 |
{ yyval.v.filter_prefix = yyvsp[0].v.filter_prefix; } |
||
4511 |
break; |
||
4512 |
case 165: |
||
4513 |
#line 1680 "parse.y" |
||
4514 |
{ yyval.v.filter_prefix = yyvsp[-1].v.filter_prefix; } |
||
4515 |
break; |
||
4516 |
case 167: |
||
4517 |
#line 1684 "parse.y" |
||
4518 |
{ yyval.v.filter_prefix = yyvsp[-1].v.filter_prefix; } |
||
4519 |
break; |
||
4520 |
case 168: |
||
4521 |
#line 1686 "parse.y" |
||
4522 |
{ |
||
4523 |
struct filter_prefix_l *p; |
||
4524 |
|||
4525 |
/* merge, both can be lists */ |
||
4526 |
for (p = yyvsp[-2].v.filter_prefix; p != NULL && p->next != NULL; p = p->next) |
||
4527 |
; /* nothing */ |
||
4528 |
if (p != NULL) |
||
4529 |
p->next = yyvsp[0].v.filter_prefix; |
||
4530 |
yyval.v.filter_prefix = yyvsp[-2].v.filter_prefix; |
||
4531 |
} |
||
4532 |
break; |
||
4533 |
case 169: |
||
4534 |
#line 1697 "parse.y" |
||
4535 |
{ yyval.v.filter_prefix = yyvsp[0].v.filter_prefix; } |
||
4536 |
break; |
||
4537 |
case 170: |
||
4538 |
#line 1698 "parse.y" |
||
4539 |
{ |
||
4540 |
yyvsp[0].v.filter_prefix->next = yyvsp[-2].v.filter_prefix; |
||
4541 |
yyval.v.filter_prefix = yyvsp[0].v.filter_prefix; |
||
4542 |
} |
||
4543 |
break; |
||
4544 |
case 171: |
||
4545 |
#line 1704 "parse.y" |
||
4546 |
{ |
||
4547 |
if ((yyval.v.filter_prefix = calloc(1, sizeof(struct filter_prefix_l))) == |
||
4548 |
NULL) |
||
4549 |
fatal(NULL); |
||
4550 |
memcpy(&yyval.v.filter_prefix->p.addr, &yyvsp[-1].v.prefix.prefix, |
||
4551 |
sizeof(yyval.v.filter_prefix->p.addr)); |
||
4552 |
yyval.v.filter_prefix->p.len = yyvsp[-1].v.prefix.len; |
||
4553 |
|||
4554 |
if (merge_prefixspec(yyval.v.filter_prefix, &yyvsp[0].v.prefixlen) == -1) { |
||
4555 |
free(yyval.v.filter_prefix); |
||
4556 |
YYERROR; |
||
4557 |
} |
||
4558 |
} |
||
4559 |
break; |
||
4560 |
case 173: |
||
4561 |
#line 1720 "parse.y" |
||
4562 |
{ yyval.v.filter_as = yyvsp[-1].v.filter_as; } |
||
4563 |
break; |
||
4564 |
case 175: |
||
4565 |
#line 1724 "parse.y" |
||
4566 |
{ |
||
4567 |
struct filter_as_l *a; |
||
4568 |
|||
4569 |
/* merge, both can be lists */ |
||
4570 |
for (a = yyvsp[-2].v.filter_as; a != NULL && a->next != NULL; a = a->next) |
||
4571 |
; /* nothing */ |
||
4572 |
if (a != NULL) |
||
4573 |
a->next = yyvsp[0].v.filter_as; |
||
4574 |
yyval.v.filter_as = yyvsp[-2].v.filter_as; |
||
4575 |
} |
||
4576 |
break; |
||
4577 |
case 176: |
||
4578 |
#line 1736 "parse.y" |
||
4579 |
{ |
||
4580 |
yyval.v.filter_as = yyvsp[0].v.filter_as; |
||
4581 |
yyval.v.filter_as->a.type = yyvsp[-1].v.u8; |
||
4582 |
} |
||
4583 |
break; |
||
4584 |
case 177: |
||
4585 |
#line 1740 "parse.y" |
||
4586 |
{ |
||
4587 |
struct filter_as_l *a; |
||
4588 |
|||
4589 |
yyval.v.filter_as = yyvsp[-1].v.filter_as; |
||
4590 |
for (a = yyval.v.filter_as; a != NULL; a = a->next) |
||
4591 |
a->a.type = yyvsp[-3].v.u8; |
||
4592 |
} |
||
4593 |
break; |
||
4594 |
case 179: |
||
4595 |
#line 1750 "parse.y" |
||
4596 |
{ yyval.v.filter_as = yyvsp[-1].v.filter_as; } |
||
4597 |
break; |
||
4598 |
case 180: |
||
4599 |
#line 1752 "parse.y" |
||
4600 |
{ |
||
4601 |
struct filter_as_l *a; |
||
4602 |
|||
4603 |
/* merge, both can be lists */ |
||
4604 |
for (a = yyvsp[-2].v.filter_as; a != NULL && a->next != NULL; a = a->next) |
||
4605 |
; /* nothing */ |
||
4606 |
if (a != NULL) |
||
4607 |
a->next = yyvsp[0].v.filter_as; |
||
4608 |
yyval.v.filter_as = yyvsp[-2].v.filter_as; |
||
4609 |
} |
||
4610 |
break; |
||
4611 |
case 182: |
||
4612 |
#line 1765 "parse.y" |
||
4613 |
{ |
||
4614 |
yyvsp[0].v.filter_as->next = yyvsp[-2].v.filter_as; |
||
4615 |
yyval.v.filter_as = yyvsp[0].v.filter_as; |
||
4616 |
} |
||
4617 |
break; |
||
4618 |
case 183: |
||
4619 |
#line 1771 "parse.y" |
||
4620 |
{ |
||
4621 |
if ((yyval.v.filter_as = calloc(1, sizeof(struct filter_as_l))) == |
||
4622 |
NULL) |
||
4623 |
fatal(NULL); |
||
4624 |
yyval.v.filter_as->a.as = yyvsp[0].v.number; |
||
4625 |
yyval.v.filter_as->a.op = OP_EQ; |
||
4626 |
} |
||
4627 |
break; |
||
4628 |
case 184: |
||
4629 |
#line 1778 "parse.y" |
||
4630 |
{ |
||
4631 |
if ((yyval.v.filter_as = calloc(1, sizeof(struct filter_as_l))) == |
||
4632 |
NULL) |
||
4633 |
fatal(NULL); |
||
4634 |
yyval.v.filter_as->a.flags = AS_FLAG_NEIGHBORAS; |
||
4635 |
} |
||
4636 |
break; |
||
4637 |
case 185: |
||
4638 |
#line 1784 "parse.y" |
||
4639 |
{ |
||
4640 |
if ((yyval.v.filter_as = calloc(1, sizeof(struct filter_as_l))) == |
||
4641 |
NULL) |
||
4642 |
fatal(NULL); |
||
4643 |
yyval.v.filter_as->a.op = yyvsp[-1].v.u8; |
||
4644 |
yyval.v.filter_as->a.as = yyvsp[0].v.number; |
||
4645 |
} |
||
4646 |
break; |
||
4647 |
case 186: |
||
4648 |
#line 1791 "parse.y" |
||
4649 |
{ |
||
4650 |
if ((yyval.v.filter_as = calloc(1, sizeof(struct filter_as_l))) == |
||
4651 |
NULL) |
||
4652 |
fatal(NULL); |
||
4653 |
if (yyvsp[-2].v.number >= yyvsp[0].v.number) { |
||
4654 |
yyerror("start AS is bigger than end"); |
||
4655 |
YYERROR; |
||
4656 |
} |
||
4657 |
yyval.v.filter_as->a.op = yyvsp[-1].v.u8; |
||
4658 |
yyval.v.filter_as->a.as_min = yyvsp[-2].v.number; |
||
4659 |
yyval.v.filter_as->a.as_max = yyvsp[0].v.number; |
||
4660 |
} |
||
4661 |
break; |
||
4662 |
case 187: |
||
4663 |
#line 1805 "parse.y" |
||
4664 |
{ |
||
4665 |
bzero(&yyval.v.filter_match, sizeof(yyval.v.filter_match)); |
||
4666 |
yyval.v.filter_match.m.community.as = COMMUNITY_UNSET; |
||
4667 |
yyval.v.filter_match.m.large_community.as = COMMUNITY_UNSET; |
||
4668 |
} |
||
4669 |
break; |
||
4670 |
case 188: |
||
4671 |
#line 1810 "parse.y" |
||
4672 |
{ |
||
4673 |
bzero(&fmopts, sizeof(fmopts)); |
||
4674 |
fmopts.m.community.as = COMMUNITY_UNSET; |
||
4675 |
fmopts.m.large_community.as = COMMUNITY_UNSET; |
||
4676 |
} |
||
4677 |
break; |
||
4678 |
case 189: |
||
4679 |
#line 1815 "parse.y" |
||
4680 |
{ |
||
4681 |
memcpy(&yyval.v.filter_match, &fmopts, sizeof(yyval.v.filter_match)); |
||
4682 |
} |
||
4683 |
break; |
||
4684 |
case 192: |
||
4685 |
#line 1824 "parse.y" |
||
4686 |
{ |
||
4687 |
if (fmopts.prefix_l != NULL) { |
||
4688 |
yyerror("\"prefix\" already specified"); |
||
4689 |
YYERROR; |
||
4690 |
} |
||
4691 |
fmopts.prefix_l = yyvsp[0].v.filter_prefix; |
||
4692 |
} |
||
4693 |
break; |
||
4694 |
case 193: |
||
4695 |
#line 1831 "parse.y" |
||
4696 |
{ |
||
4697 |
if (fmopts.as_l != NULL) { |
||
4698 |
yyerror("AS filters already specified"); |
||
4699 |
YYERROR; |
||
4700 |
} |
||
4701 |
fmopts.as_l = yyvsp[0].v.filter_as; |
||
4702 |
} |
||
4703 |
break; |
||
4704 |
case 194: |
||
4705 |
#line 1838 "parse.y" |
||
4706 |
{ |
||
4707 |
if (fmopts.m.aslen.type != ASLEN_NONE) { |
||
4708 |
yyerror("AS length filters already specified"); |
||
4709 |
YYERROR; |
||
4710 |
} |
||
4711 |
if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > UINT_MAX) { |
||
4712 |
yyerror("bad max-as-len %lld", yyvsp[0].v.number); |
||
4713 |
YYERROR; |
||
4714 |
} |
||
4715 |
fmopts.m.aslen.type = ASLEN_MAX; |
||
4716 |
fmopts.m.aslen.aslen = yyvsp[0].v.number; |
||
4717 |
} |
||
4718 |
break; |
||
4719 |
case 195: |
||
4720 |
#line 1850 "parse.y" |
||
4721 |
{ |
||
4722 |
if (fmopts.m.aslen.type != ASLEN_NONE) { |
||
4723 |
yyerror("AS length filters already specified"); |
||
4724 |
YYERROR; |
||
4725 |
} |
||
4726 |
if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > UINT_MAX) { |
||
4727 |
yyerror("bad max-as-seq %lld", yyvsp[0].v.number); |
||
4728 |
YYERROR; |
||
4729 |
} |
||
4730 |
fmopts.m.aslen.type = ASLEN_SEQ; |
||
4731 |
fmopts.m.aslen.aslen = yyvsp[0].v.number; |
||
4732 |
} |
||
4733 |
break; |
||
4734 |
case 196: |
||
4735 |
#line 1862 "parse.y" |
||
4736 |
{ |
||
4737 |
if (fmopts.m.community.as != COMMUNITY_UNSET) { |
||
4738 |
yyerror("\"community\" already specified"); |
||
4739 |
free(yyvsp[0].v.string); |
||
4740 |
YYERROR; |
||
4741 |
} |
||
4742 |
if (parsecommunity(&fmopts.m.community, yyvsp[0].v.string) == -1) { |
||
4743 |
free(yyvsp[0].v.string); |
||
4744 |
YYERROR; |
||
4745 |
} |
||
4746 |
free(yyvsp[0].v.string); |
||
4747 |
} |
||
4748 |
break; |
||
4749 |
case 197: |
||
4750 |
#line 1874 "parse.y" |
||
4751 |
{ |
||
4752 |
if (fmopts.m.large_community.as != COMMUNITY_UNSET) { |
||
4753 |
yyerror("\"large-community\" already specified"); |
||
4754 |
free(yyvsp[0].v.string); |
||
4755 |
YYERROR; |
||
4756 |
} |
||
4757 |
if (parselargecommunity(&fmopts.m.large_community, yyvsp[0].v.string) == -1) { |
||
4758 |
free(yyvsp[0].v.string); |
||
4759 |
YYERROR; |
||
4760 |
} |
||
4761 |
free(yyvsp[0].v.string); |
||
4762 |
} |
||
4763 |
break; |
||
4764 |
case 198: |
||
4765 |
#line 1886 "parse.y" |
||
4766 |
{ |
||
4767 |
if (fmopts.m.ext_community.flags & |
||
4768 |
EXT_COMMUNITY_FLAG_VALID) { |
||
4769 |
yyerror("\"ext-community\" already specified"); |
||
4770 |
free(yyvsp[-1].v.string); |
||
4771 |
free(yyvsp[0].v.string); |
||
4772 |
YYERROR; |
||
4773 |
} |
||
4774 |
|||
4775 |
if (parseextcommunity(&fmopts.m.ext_community, |
||
4776 |
yyvsp[-1].v.string, yyvsp[0].v.string) == -1) { |
||
4777 |
free(yyvsp[-1].v.string); |
||
4778 |
free(yyvsp[0].v.string); |
||
4779 |
YYERROR; |
||
4780 |
} |
||
4781 |
free(yyvsp[-1].v.string); |
||
4782 |
free(yyvsp[0].v.string); |
||
4783 |
} |
||
4784 |
break; |
||
4785 |
case 199: |
||
4786 |
#line 1904 "parse.y" |
||
4787 |
{ |
||
4788 |
if (fmopts.m.nexthop.flags) { |
||
4789 |
yyerror("nexthop already specified"); |
||
4790 |
YYERROR; |
||
4791 |
} |
||
4792 |
fmopts.m.nexthop.addr = yyvsp[0].v.addr; |
||
4793 |
fmopts.m.nexthop.flags = FILTER_NEXTHOP_ADDR; |
||
4794 |
} |
||
4795 |
break; |
||
4796 |
case 200: |
||
4797 |
#line 1912 "parse.y" |
||
4798 |
{ |
||
4799 |
if (fmopts.m.nexthop.flags) { |
||
4800 |
yyerror("nexthop already specified"); |
||
4801 |
YYERROR; |
||
4802 |
} |
||
4803 |
fmopts.m.nexthop.flags = FILTER_NEXTHOP_NEIGHBOR; |
||
4804 |
} |
||
4805 |
break; |
||
4806 |
case 201: |
||
4807 |
#line 1921 "parse.y" |
||
4808 |
{ bzero(&yyval.v.prefixlen, sizeof(yyval.v.prefixlen)); } |
||
4809 |
break; |
||
4810 |
case 202: |
||
4811 |
#line 1922 "parse.y" |
||
4812 |
{ |
||
4813 |
bzero(&yyval.v.prefixlen, sizeof(yyval.v.prefixlen)); |
||
4814 |
yyval.v.prefixlen.op = OP_GE; |
||
4815 |
yyval.v.prefixlen.len_min = -1; |
||
4816 |
} |
||
4817 |
break; |
||
4818 |
case 203: |
||
4819 |
#line 1927 "parse.y" |
||
4820 |
{ |
||
4821 |
bzero(&yyval.v.prefixlen, sizeof(yyval.v.prefixlen)); |
||
4822 |
if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > 128) { |
||
4823 |
yyerror("prefixlen must be >= 0 and <= 128"); |
||
4824 |
YYERROR; |
||
4825 |
} |
||
4826 |
if (yyvsp[-1].v.u8 == OP_GT && yyvsp[0].v.number == 0) { |
||
4827 |
yyerror("prefixlen must be > 0"); |
||
4828 |
YYERROR; |
||
4829 |
} |
||
4830 |
yyval.v.prefixlen.op = yyvsp[-1].v.u8; |
||
4831 |
yyval.v.prefixlen.len_min = yyvsp[0].v.number; |
||
4832 |
} |
||
4833 |
break; |
||
4834 |
case 204: |
||
4835 |
#line 1940 "parse.y" |
||
4836 |
{ |
||
4837 |
bzero(&yyval.v.prefixlen, sizeof(yyval.v.prefixlen)); |
||
4838 |
if (yyvsp[-2].v.number < 0 || yyvsp[-2].v.number > 128 || yyvsp[0].v.number < 0 || yyvsp[0].v.number > 128) { |
||
4839 |
yyerror("prefixlen must be < 128"); |
||
4840 |
YYERROR; |
||
4841 |
} |
||
4842 |
if (yyvsp[-2].v.number >= yyvsp[0].v.number) { |
||
4843 |
yyerror("start prefixlen is bigger than end"); |
||
4844 |
YYERROR; |
||
4845 |
} |
||
4846 |
yyval.v.prefixlen.op = yyvsp[-1].v.u8; |
||
4847 |
yyval.v.prefixlen.len_min = yyvsp[-2].v.number; |
||
4848 |
yyval.v.prefixlen.len_max = yyvsp[0].v.number; |
||
4849 |
} |
||
4850 |
break; |
||
4851 |
case 205: |
||
4852 |
#line 1956 "parse.y" |
||
4853 |
{ yyval.v.u8 = AS_ALL; } |
||
4854 |
break; |
||
4855 |
case 206: |
||
4856 |
#line 1957 "parse.y" |
||
4857 |
{ yyval.v.u8 = AS_SOURCE; } |
||
4858 |
break; |
||
4859 |
case 207: |
||
4860 |
#line 1958 "parse.y" |
||
4861 |
{ yyval.v.u8 = AS_TRANSIT; } |
||
4862 |
break; |
||
4863 |
case 208: |
||
4864 |
#line 1959 "parse.y" |
||
4865 |
{ yyval.v.u8 = AS_PEER; } |
||
4866 |
break; |
||
4867 |
case 209: |
||
4868 |
#line 1962 "parse.y" |
||
4869 |
{ yyval.v.filter_set_head = NULL; } |
||
4870 |
break; |
||
4871 |
case 210: |
||
4872 |
#line 1963 "parse.y" |
||
4873 |
{ |
||
4874 |
if ((yyval.v.filter_set_head = calloc(1, sizeof(struct filter_set_head))) == |
||
4875 |
NULL) |
||
4876 |
fatal(NULL); |
||
4877 |
TAILQ_INIT(yyval.v.filter_set_head); |
||
4878 |
TAILQ_INSERT_TAIL(yyval.v.filter_set_head, yyvsp[0].v.filter_set, entry); |
||
4879 |
} |
||
4880 |
break; |
||
4881 |
case 211: |
||
4882 |
#line 1970 "parse.y" |
||
4883 |
{ yyval.v.filter_set_head = yyvsp[-2].v.filter_set_head; } |
||
4884 |
break; |
||
4885 |
case 212: |
||
4886 |
#line 1973 "parse.y" |
||
4887 |
{ |
||
4888 |
yyval.v.filter_set_head = yyvsp[-2].v.filter_set_head; |
||
4889 |
if (merge_filterset(yyval.v.filter_set_head, yyvsp[0].v.filter_set) == 1) |
||
4890 |
YYERROR; |
||
4891 |
} |
||
4892 |
break; |
||
4893 |
case 213: |
||
4894 |
#line 1978 "parse.y" |
||
4895 |
{ |
||
4896 |
if ((yyval.v.filter_set_head = calloc(1, sizeof(struct filter_set_head))) == |
||
4897 |
NULL) |
||
4898 |
fatal(NULL); |
||
4899 |
TAILQ_INIT(yyval.v.filter_set_head); |
||
4900 |
TAILQ_INSERT_TAIL(yyval.v.filter_set_head, yyvsp[0].v.filter_set, entry); |
||
4901 |
} |
||
4902 |
break; |
||
4903 |
case 214: |
||
4904 |
#line 1987 "parse.y" |
||
4905 |
{ yyval.v.u8 = 0; } |
||
4906 |
break; |
||
4907 |
case 215: |
||
4908 |
#line 1988 "parse.y" |
||
4909 |
{ yyval.v.u8 = 1; } |
||
4910 |
break; |
||
4911 |
case 216: |
||
4912 |
#line 1991 "parse.y" |
||
4913 |
{ |
||
4914 |
if (yyvsp[0].v.number < -INT_MAX || yyvsp[0].v.number > UINT_MAX) { |
||
4915 |
yyerror("bad localpref %lld", yyvsp[0].v.number); |
||
4916 |
YYERROR; |
||
4917 |
} |
||
4918 |
if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL) |
||
4919 |
fatal(NULL); |
||
4920 |
if (yyvsp[0].v.number >= 0) { |
||
4921 |
yyval.v.filter_set->type = ACTION_SET_LOCALPREF; |
||
4922 |
yyval.v.filter_set->action.metric = yyvsp[0].v.number; |
||
4923 |
} else { |
||
4924 |
yyval.v.filter_set->type = ACTION_SET_RELATIVE_LOCALPREF; |
||
4925 |
yyval.v.filter_set->action.relative = yyvsp[0].v.number; |
||
4926 |
} |
||
4927 |
} |
||
4928 |
break; |
||
4929 |
case 217: |
||
4930 |
#line 2006 "parse.y" |
||
4931 |
{ |
||
4932 |
if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX) { |
||
4933 |
yyerror("bad localpref +%lld", yyvsp[0].v.number); |
||
4934 |
YYERROR; |
||
4935 |
} |
||
4936 |
if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL) |
||
4937 |
fatal(NULL); |
||
4938 |
yyval.v.filter_set->type = ACTION_SET_RELATIVE_LOCALPREF; |
||
4939 |
yyval.v.filter_set->action.relative = yyvsp[0].v.number; |
||
4940 |
} |
||
4941 |
break; |
||
4942 |
case 218: |
||
4943 |
#line 2016 "parse.y" |
||
4944 |
{ |
||
4945 |
if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX) { |
||
4946 |
yyerror("bad localpref -%lld", yyvsp[0].v.number); |
||
4947 |
YYERROR; |
||
4948 |
} |
||
4949 |
if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL) |
||
4950 |
fatal(NULL); |
||
4951 |
yyval.v.filter_set->type = ACTION_SET_RELATIVE_LOCALPREF; |
||
4952 |
yyval.v.filter_set->action.relative = -yyvsp[0].v.number; |
||
4953 |
} |
||
4954 |
break; |
||
4955 |
case 219: |
||
4956 |
#line 2026 "parse.y" |
||
4957 |
{ |
||
4958 |
if (yyvsp[0].v.number < -INT_MAX || yyvsp[0].v.number > UINT_MAX) { |
||
4959 |
yyerror("bad metric %lld", yyvsp[0].v.number); |
||
4960 |
YYERROR; |
||
4961 |
} |
||
4962 |
if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL) |
||
4963 |
fatal(NULL); |
||
4964 |
if (yyvsp[0].v.number >= 0) { |
||
4965 |
yyval.v.filter_set->type = ACTION_SET_MED; |
||
4966 |
yyval.v.filter_set->action.metric = yyvsp[0].v.number; |
||
4967 |
} else { |
||
4968 |
yyval.v.filter_set->type = ACTION_SET_RELATIVE_MED; |
||
4969 |
yyval.v.filter_set->action.relative = yyvsp[0].v.number; |
||
4970 |
} |
||
4971 |
} |
||
4972 |
break; |
||
4973 |
case 220: |
||
4974 |
#line 2041 "parse.y" |
||
4975 |
{ |
||
4976 |
if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX) { |
||
4977 |
yyerror("bad metric +%lld", yyvsp[0].v.number); |
||
4978 |
YYERROR; |
||
4979 |
} |
||
4980 |
if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL) |
||
4981 |
fatal(NULL); |
||
4982 |
yyval.v.filter_set->type = ACTION_SET_RELATIVE_MED; |
||
4983 |
yyval.v.filter_set->action.relative = yyvsp[0].v.number; |
||
4984 |
} |
||
4985 |
break; |
||
4986 |
case 221: |
||
4987 |
#line 2051 "parse.y" |
||
4988 |
{ |
||
4989 |
if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX) { |
||
4990 |
yyerror("bad metric -%lld", yyvsp[0].v.number); |
||
4991 |
YYERROR; |
||
4992 |
} |
||
4993 |
if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL) |
||
4994 |
fatal(NULL); |
||
4995 |
yyval.v.filter_set->type = ACTION_SET_RELATIVE_MED; |
||
4996 |
yyval.v.filter_set->action.relative = -yyvsp[0].v.number; |
||
4997 |
} |
||
4998 |
break; |
||
4999 |
case 222: |
||
5000 |
#line 2061 "parse.y" |
||
5001 |
{ /* alias for MED */ |
||
5002 |
if (yyvsp[0].v.number < -INT_MAX || yyvsp[0].v.number > UINT_MAX) { |
||
5003 |
yyerror("bad metric %lld", yyvsp[0].v.number); |
||
5004 |
YYERROR; |
||
5005 |
} |
||
5006 |
if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL) |
||
5007 |
fatal(NULL); |
||
5008 |
if (yyvsp[0].v.number >= 0) { |
||
5009 |
yyval.v.filter_set->type = ACTION_SET_MED; |
||
5010 |
yyval.v.filter_set->action.metric = yyvsp[0].v.number; |
||
5011 |
} else { |
||
5012 |
yyval.v.filter_set->type = ACTION_SET_RELATIVE_MED; |
||
5013 |
yyval.v.filter_set->action.relative = yyvsp[0].v.number; |
||
5014 |
} |
||
5015 |
} |
||
5016 |
break; |
||
5017 |
case 223: |
||
5018 |
#line 2076 "parse.y" |
||
5019 |
{ |
||
5020 |
if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX) { |
||
5021 |
yyerror("bad metric +%lld", yyvsp[0].v.number); |
||
5022 |
YYERROR; |
||
5023 |
} |
||
5024 |
if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL) |
||
5025 |
fatal(NULL); |
||
5026 |
yyval.v.filter_set->type = ACTION_SET_RELATIVE_MED; |
||
5027 |
yyval.v.filter_set->action.metric = yyvsp[0].v.number; |
||
5028 |
} |
||
5029 |
break; |
||
5030 |
case 224: |
||
5031 |
#line 2086 "parse.y" |
||
5032 |
{ |
||
5033 |
if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX) { |
||
5034 |
yyerror("bad metric -%lld", yyvsp[0].v.number); |
||
5035 |
YYERROR; |
||
5036 |
} |
||
5037 |
if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL) |
||
5038 |
fatal(NULL); |
||
5039 |
yyval.v.filter_set->type = ACTION_SET_RELATIVE_MED; |
||
5040 |
yyval.v.filter_set->action.relative = -yyvsp[0].v.number; |
||
5041 |
} |
||
5042 |
break; |
||
5043 |
case 225: |
||
5044 |
#line 2096 "parse.y" |
||
5045 |
{ |
||
5046 |
if (yyvsp[0].v.number < -INT_MAX || yyvsp[0].v.number > UINT_MAX) { |
||
5047 |
yyerror("bad weight %lld", yyvsp[0].v.number); |
||
5048 |
YYERROR; |
||
5049 |
} |
||
5050 |
if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL) |
||
5051 |
fatal(NULL); |
||
5052 |
if (yyvsp[0].v.number > 0) { |
||
5053 |
yyval.v.filter_set->type = ACTION_SET_WEIGHT; |
||
5054 |
yyval.v.filter_set->action.metric = yyvsp[0].v.number; |
||
5055 |
} else { |
||
5056 |
yyval.v.filter_set->type = ACTION_SET_RELATIVE_WEIGHT; |
||
5057 |
yyval.v.filter_set->action.relative = yyvsp[0].v.number; |
||
5058 |
} |
||
5059 |
} |
||
5060 |
break; |
||
5061 |
case 226: |
||
5062 |
#line 2111 "parse.y" |
||
5063 |
{ |
||
5064 |
if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX) { |
||
5065 |
yyerror("bad weight +%lld", yyvsp[0].v.number); |
||
5066 |
YYERROR; |
||
5067 |
} |
||
5068 |
if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL) |
||
5069 |
fatal(NULL); |
||
5070 |
yyval.v.filter_set->type = ACTION_SET_RELATIVE_WEIGHT; |
||
5071 |
yyval.v.filter_set->action.relative = yyvsp[0].v.number; |
||
5072 |
} |
||
5073 |
break; |
||
5074 |
case 227: |
||
5075 |
#line 2121 "parse.y" |
||
5076 |
{ |
||
5077 |
if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX) { |
||
5078 |
yyerror("bad weight -%lld", yyvsp[0].v.number); |
||
5079 |
YYERROR; |
||
5080 |
} |
||
5081 |
if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL) |
||
5082 |
fatal(NULL); |
||
5083 |
yyval.v.filter_set->type = ACTION_SET_RELATIVE_WEIGHT; |
||
5084 |
yyval.v.filter_set->action.relative = -yyvsp[0].v.number; |
||
5085 |
} |
||
5086 |
break; |
||
5087 |
case 228: |
||
5088 |
#line 2131 "parse.y" |
||
5089 |
{ |
||
5090 |
if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL) |
||
5091 |
fatal(NULL); |
||
5092 |
yyval.v.filter_set->type = ACTION_SET_NEXTHOP; |
||
5093 |
memcpy(&yyval.v.filter_set->action.nexthop, &yyvsp[0].v.addr, |
||
5094 |
sizeof(yyval.v.filter_set->action.nexthop)); |
||
5095 |
} |
||
5096 |
break; |
||
5097 |
case 229: |
||
5098 |
#line 2138 "parse.y" |
||
5099 |
{ |
||
5100 |
if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL) |
||
5101 |
fatal(NULL); |
||
5102 |
yyval.v.filter_set->type = ACTION_SET_NEXTHOP_BLACKHOLE; |
||
5103 |
} |
||
5104 |
break; |
||
5105 |
case 230: |
||
5106 |
#line 2143 "parse.y" |
||
5107 |
{ |
||
5108 |
if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL) |
||
5109 |
fatal(NULL); |
||
5110 |
yyval.v.filter_set->type = ACTION_SET_NEXTHOP_REJECT; |
||
5111 |
} |
||
5112 |
break; |
||
5113 |
case 231: |
||
5114 |
#line 2148 "parse.y" |
||
5115 |
{ |
||
5116 |
if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL) |
||
5117 |
fatal(NULL); |
||
5118 |
yyval.v.filter_set->type = ACTION_SET_NEXTHOP_NOMODIFY; |
||
5119 |
} |
||
5120 |
break; |
||
5121 |
case 232: |
||
5122 |
#line 2153 "parse.y" |
||
5123 |
{ |
||
5124 |
if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL) |
||
5125 |
fatal(NULL); |
||
5126 |
yyval.v.filter_set->type = ACTION_SET_NEXTHOP_SELF; |
||
5127 |
} |
||
5128 |
break; |
||
5129 |
case 233: |
||
5130 |
#line 2158 "parse.y" |
||
5131 |
{ |
||
5132 |
if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > 128) { |
||
5133 |
yyerror("bad number of prepends"); |
||
5134 |
YYERROR; |
||
5135 |
} |
||
5136 |
if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL) |
||
5137 |
fatal(NULL); |
||
5138 |
yyval.v.filter_set->type = ACTION_SET_PREPEND_SELF; |
||
5139 |
yyval.v.filter_set->action.prepend = yyvsp[0].v.number; |
||
5140 |
} |
||
5141 |
break; |
||
5142 |
case 234: |
||
5143 |
#line 2168 "parse.y" |
||
5144 |
{ |
||
5145 |
if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > 128) { |
||
5146 |
yyerror("bad number of prepends"); |
||
5147 |
YYERROR; |
||
5148 |
} |
||
5149 |
if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL) |
||
5150 |
fatal(NULL); |
||
5151 |
yyval.v.filter_set->type = ACTION_SET_PREPEND_PEER; |
||
5152 |
yyval.v.filter_set->action.prepend = yyvsp[0].v.number; |
||
5153 |
} |
||
5154 |
break; |
||
5155 |
case 235: |
||
5156 |
#line 2178 "parse.y" |
||
5157 |
{ |
||
5158 |
if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL) |
||
5159 |
fatal(NULL); |
||
5160 |
yyval.v.filter_set->type = ACTION_PFTABLE; |
||
5161 |
if (!(cmd_opts & BGPD_OPT_NOACTION) && |
||
5162 |
pftable_exists(yyvsp[0].v.string) != 0) { |
||
5163 |
yyerror("pftable name does not exist"); |
||
5164 |
free(yyvsp[0].v.string); |
||
5165 |
free(yyval.v.filter_set); |
||
5166 |
YYERROR; |
||
5167 |
} |
||
5168 |
if (strlcpy(yyval.v.filter_set->action.pftable, yyvsp[0].v.string, |
||
5169 |
sizeof(yyval.v.filter_set->action.pftable)) >= |
||
5170 |
sizeof(yyval.v.filter_set->action.pftable)) { |
||
5171 |
yyerror("pftable name too long"); |
||
5172 |
free(yyvsp[0].v.string); |
||
5173 |
free(yyval.v.filter_set); |
||
5174 |
YYERROR; |
||
5175 |
} |
||
5176 |
if (pftable_add(yyvsp[0].v.string) != 0) { |
||
5177 |
yyerror("Couldn't register table"); |
||
5178 |
free(yyvsp[0].v.string); |
||
5179 |
free(yyval.v.filter_set); |
||
5180 |
YYERROR; |
||
5181 |
} |
||
5182 |
free(yyvsp[0].v.string); |
||
5183 |
} |
||
5184 |
break; |
||
5185 |
case 236: |
||
5186 |
#line 2205 "parse.y" |
||
5187 |
{ |
||
5188 |
if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL) |
||
5189 |
fatal(NULL); |
||
5190 |
yyval.v.filter_set->type = ACTION_RTLABEL; |
||
5191 |
if (strlcpy(yyval.v.filter_set->action.rtlabel, yyvsp[0].v.string, |
||
5192 |
sizeof(yyval.v.filter_set->action.rtlabel)) >= |
||
5193 |
sizeof(yyval.v.filter_set->action.rtlabel)) { |
||
5194 |
yyerror("rtlabel name too long"); |
||
5195 |
free(yyvsp[0].v.string); |
||
5196 |
free(yyval.v.filter_set); |
||
5197 |
YYERROR; |
||
5198 |
} |
||
5199 |
free(yyvsp[0].v.string); |
||
5200 |
} |
||
5201 |
break; |
||
5202 |
case 237: |
||
5203 |
#line 2219 "parse.y" |
||
5204 |
{ |
||
5205 |
if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL) |
||
5206 |
fatal(NULL); |
||
5207 |
if (yyvsp[-1].v.u8) |
||
5208 |
yyval.v.filter_set->type = ACTION_DEL_COMMUNITY; |
||
5209 |
else |
||
5210 |
yyval.v.filter_set->type = ACTION_SET_COMMUNITY; |
||
5211 |
|||
5212 |
if (parsecommunity(&yyval.v.filter_set->action.community, yyvsp[0].v.string) == -1) { |
||
5213 |
free(yyvsp[0].v.string); |
||
5214 |
free(yyval.v.filter_set); |
||
5215 |
YYERROR; |
||
5216 |
} |
||
5217 |
free(yyvsp[0].v.string); |
||
5218 |
/* Don't allow setting of any match */ |
||
5219 |
if (!yyvsp[-1].v.u8 && (yyval.v.filter_set->action.community.as == COMMUNITY_ANY || |
||
5220 |
yyval.v.filter_set->action.community.type == COMMUNITY_ANY)) { |
||
5221 |
yyerror("'*' is not allowed in set community"); |
||
5222 |
free(yyval.v.filter_set); |
||
5223 |
YYERROR; |
||
5224 |
} |
||
5225 |
} |
||
5226 |
break; |
||
5227 |
case 238: |
||
5228 |
#line 2241 "parse.y" |
||
5229 |
{ |
||
5230 |
if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL) |
||
5231 |
fatal(NULL); |
||
5232 |
if (yyvsp[-1].v.u8) |
||
5233 |
yyval.v.filter_set->type = ACTION_DEL_LARGE_COMMUNITY; |
||
5234 |
else |
||
5235 |
yyval.v.filter_set->type = ACTION_SET_LARGE_COMMUNITY; |
||
5236 |
|||
5237 |
if (parselargecommunity(&yyval.v.filter_set->action.large_community, |
||
5238 |
yyvsp[0].v.string) == -1) { |
||
5239 |
free(yyvsp[0].v.string); |
||
5240 |
free(yyval.v.filter_set); |
||
5241 |
YYERROR; |
||
5242 |
} |
||
5243 |
free(yyvsp[0].v.string); |
||
5244 |
/* Don't allow setting of any match */ |
||
5245 |
if (!yyvsp[-1].v.u8 && |
||
5246 |
(yyval.v.filter_set->action.large_community.as == COMMUNITY_ANY || |
||
5247 |
yyval.v.filter_set->action.large_community.ld1 == COMMUNITY_ANY || |
||
5248 |
yyval.v.filter_set->action.large_community.ld2 == COMMUNITY_ANY)) { |
||
5249 |
yyerror("'*' is not allowed in set community"); |
||
5250 |
free(yyval.v.filter_set); |
||
5251 |
YYERROR; |
||
5252 |
} |
||
5253 |
} |
||
5254 |
break; |
||
5255 |
case 239: |
||
5256 |
#line 2266 "parse.y" |
||
5257 |
{ |
||
5258 |
if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL) |
||
5259 |
fatal(NULL); |
||
5260 |
if (yyvsp[-2].v.u8) |
||
5261 |
yyval.v.filter_set->type = ACTION_DEL_EXT_COMMUNITY; |
||
5262 |
else |
||
5263 |
yyval.v.filter_set->type = ACTION_SET_EXT_COMMUNITY; |
||
5264 |
|||
5265 |
if (parseextcommunity(&yyval.v.filter_set->action.ext_community, |
||
5266 |
yyvsp[-1].v.string, yyvsp[0].v.string) == -1) { |
||
5267 |
free(yyvsp[-1].v.string); |
||
5268 |
free(yyvsp[0].v.string); |
||
5269 |
free(yyval.v.filter_set); |
||
5270 |
YYERROR; |
||
5271 |
} |
||
5272 |
free(yyvsp[-1].v.string); |
||
5273 |
free(yyvsp[0].v.string); |
||
5274 |
} |
||
5275 |
break; |
||
5276 |
case 240: |
||
5277 |
#line 2284 "parse.y" |
||
5278 |
{ |
||
5279 |
if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL) |
||
5280 |
fatal(NULL); |
||
5281 |
yyval.v.filter_set->type = ACTION_SET_ORIGIN; |
||
5282 |
yyval.v.filter_set->action.origin = yyvsp[0].v.number; |
||
5283 |
} |
||
5284 |
break; |
||
5285 |
case 241: |
||
5286 |
#line 2292 "parse.y" |
||
5287 |
{ |
||
5288 |
if (!strcmp(yyvsp[0].v.string, "egp")) |
||
5289 |
yyval.v.number = ORIGIN_EGP; |
||
5290 |
else if (!strcmp(yyvsp[0].v.string, "igp")) |
||
5291 |
yyval.v.number = ORIGIN_IGP; |
||
5292 |
else if (!strcmp(yyvsp[0].v.string, "incomplete")) |
||
5293 |
yyval.v.number = ORIGIN_INCOMPLETE; |
||
5294 |
else { |
||
5295 |
yyerror("unknown origin \"%s\"", yyvsp[0].v.string); |
||
5296 |
free(yyvsp[0].v.string); |
||
5297 |
YYERROR; |
||
5298 |
} |
||
5299 |
free(yyvsp[0].v.string); |
||
5300 |
} |
||
5301 |
break; |
||
5302 |
case 244: |
||
5303 |
#line 2311 "parse.y" |
||
5304 |
{ yyval.v.u8 = OP_EQ; } |
||
5305 |
break; |
||
5306 |
case 245: |
||
5307 |
#line 2312 "parse.y" |
||
5308 |
{ yyval.v.u8 = OP_NE; } |
||
5309 |
break; |
||
5310 |
case 246: |
||
5311 |
#line 2313 "parse.y" |
||
5312 |
{ yyval.v.u8 = OP_LE; } |
||
5313 |
break; |
||
5314 |
case 247: |
||
5315 |
#line 2314 "parse.y" |
||
5316 |
{ yyval.v.u8 = OP_LT; } |
||
5317 |
break; |
||
5318 |
case 248: |
||
5319 |
#line 2315 "parse.y" |
||
5320 |
{ yyval.v.u8 = OP_GE; } |
||
5321 |
break; |
||
5322 |
case 249: |
||
5323 |
#line 2316 "parse.y" |
||
5324 |
{ yyval.v.u8 = OP_GT; } |
||
5325 |
break; |
||
5326 |
case 250: |
||
5327 |
#line 2319 "parse.y" |
||
5328 |
{ yyval.v.u8 = OP_EQ; } |
||
5329 |
break; |
||
5330 |
case 251: |
||
5331 |
#line 2320 "parse.y" |
||
5332 |
{ yyval.v.u8 = OP_NE; } |
||
5333 |
break; |
||
5334 |
case 252: |
||
5335 |
#line 2323 "parse.y" |
||
5336 |
4580 |
{ yyval.v.u8 = OP_RANGE; } |
|
5337 |
4580 |
break; |
|
5338 |
4580 |
case 253: |
|
5339 |
4580 |
#line 2324 "parse.y" |
|
5340 |
✓✓ | 4580 |
{ yyval.v.u8 = OP_XRANGE; } |
5341 |
break; |
||
5342 |
#line 5335 "parse.c" |
||
5343 |
} |
||
5344 |
yyssp -= yym; |
||
5345 |
yystate = *yyssp; |
||
5346 |
yyvsp -= yym; |
||
5347 |
yym = yylhs[yyn]; |
||
5348 |
480 |
if (yystate == 0 && yym == 0) |
|
5349 |
480 |
{ |
|
5350 |
✓✗ | 480 |
#if YYDEBUG |
5351 |
if (yydebug) |
||
5352 |
480 |
printf("%sdebug: after reduction, shifting from state 0 to\ |
|
5353 |
state %d\n", YYPREFIX, YYFINAL); |
||
5354 |
#endif |
||
5355 |
yystate = YYFINAL; |
||
5356 |
*++yyssp = YYFINAL; |
||
5357 |
*++yyvsp = yyval; |
||
5358 |
if (yychar < 0) |
||
5359 |
{ |
||
5360 |
if ((yychar = yylex()) < 0) yychar = 0; |
||
5361 |
#if YYDEBUG |
||
5362 |
if (yydebug) |
||
5363 |
480 |
{ |
|
5364 |
✓✓ | 480 |
yys = 0; |
5365 |
468 |
if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; |
|
5366 |
if (!yys) yys = "illegal-symbol"; |
||
5367 |
✓✓✓✓ ✓✓ |
9472 |
printf("%sdebug: state %d, reading %d (%s)\n", |
5368 |
3492 |
YYPREFIX, YYFINAL, yychar, yys); |
|
5369 |
1196 |
} |
|
5370 |
#endif |
||
5371 |
2904 |
} |
|
5372 |
if (yychar == 0) goto yyaccept; |
||
5373 |
goto yyloop; |
||
5374 |
} |
||
5375 |
if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && |
||
5376 |
yyn <= YYTABLESIZE && yycheck[yyn] == yystate) |
||
5377 |
✗✓✗✗ |
4100 |
yystate = yytable[yyn]; |
5378 |
else |
||
5379 |
yystate = yydgoto[yym]; |
||
5380 |
#if YYDEBUG |
||
5381 |
4100 |
if (yydebug) |
|
5382 |
4100 |
printf("%sdebug: after reduction, shifting from state %d \ |
|
5383 |
4100 |
to state %d\n", YYPREFIX, *yyssp, yystate); |
|
5384 |
#endif |
||
5385 |
if (yyssp >= yysslim && yygrowstack()) |
||
5386 |
{ |
||
5387 |
goto yyoverflow; |
||
5388 |
} |
||
5389 |
*++yyssp = yystate; |
||
5390 |
*++yyvsp = yyval; |
||
5391 |
goto yyloop; |
||
5392 |
yyoverflow: |
||
5393 |
yyerror("yacc stack overflow"); |
||
5394 |
yyabort: |
||
5395 |
if (yyss) |
||
5396 |
✓✗ | 12 |
free(yyss); |
5397 |
12 |
if (yyvs) |
|
5398 |
✓✗ | 12 |
free(yyvs); |
5399 |
12 |
yyss = yyssp = NULL; |
|
5400 |
12 |
yyvs = yyvsp = NULL; |
|
5401 |
12 |
yystacksize = 0; |
|
5402 |
12 |
return (1); |
|
5403 |
12 |
yyaccept: |
|
5404 |
12 |
if (yyss) |
|
5405 |
free(yyss); |
||
5406 |
if (yyvs) |
||
5407 |
free(yyvs); |
||
5408 |
yyss = yyssp = NULL; |
||
5409 |
yyvs = yyvsp = NULL; |
||
5410 |
yystacksize = 0; |
||
5411 |
return (0); |
||
5412 |
} |
Generated by: GCOVR (Version 3.3) |