Bug Summary

File:src/usr.sbin/bgpd/obj/parse.c
Warning:line 3310, column 10
Use of memory after it is freed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name parse.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/usr.sbin/bgpd/obj -resource-dir /usr/local/llvm16/lib/clang/16 -I /usr/src/usr.sbin/bgpd -internal-isystem /usr/local/llvm16/lib/clang/16/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.sbin/bgpd/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fcf-protection=branch -fno-jump-tables -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/scan/2024-01-11-140451-98009-1 -x c parse.c
1#include <stdlib.h>
2#include <string.h>
3#define YYBYACC1 1
4#define YYMAJOR1 1
5#define YYMINOR9 9
6#define YYLEXyylex() yylex()
7#define YYEMPTY-1 -1
8#define yyclearin(yychar=(-1)) (yychar=(YYEMPTY-1))
9#define yyerrok(yyerrflag=0) (yyerrflag=0)
10#define YYRECOVERING()(yyerrflag!=0) (yyerrflag!=0)
11#define YYPREFIX"yy" "yy"
12#line 26 "/usr/src/usr.sbin/bgpd/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.h>
19#include <netinet/ip_icmp.h>
20#include <netinet/ip_ipsp.h>
21#include <netinet/icmp6.h>
22#include <arpa/inet.h>
23
24#include <ctype.h>
25#include <endian.h>
26#include <err.h>
27#include <unistd.h>
28#include <errno(*__errno()).h>
29#include <limits.h>
30#include <netdb.h>
31#include <stdarg.h>
32#include <stdio.h>
33#include <stdlib.h>
34#include <string.h>
35#include <syslog.h>
36
37#include "bgpd.h"
38#include "session.h"
39#include "rde.h"
40#include "log.h"
41
42#ifndef nitems
43#define nitems(_a)(sizeof((_a)) / sizeof((_a)[0])) (sizeof((_a)) / sizeof((_a)[0]))
44#endif
45
46#define MACRO_NAME_LEN128 128
47
48TAILQ_HEAD(files, file)struct files { struct file *tqh_first; struct file **tqh_last
; }
files = TAILQ_HEAD_INITIALIZER(files){ ((void *)0), &(files).tqh_first };
49static struct file {
50 TAILQ_ENTRY(file)struct { struct file *tqe_next; struct file **tqe_prev; } entry;
51 FILE *stream;
52 char *name;
53 size_t ungetpos;
54 size_t ungetsize;
55 u_char *ungetbuf;
56 int eof_reached;
57 int lineno;
58 int errors;
59} *file, *topfile;
60struct file *pushfile(const char *, int);
61int popfile(void);
62int check_file_secrecy(int, const char *);
63int yyparse(void);
64int yylex(void);
65int yyerror(const char *, ...)
66 __attribute__((__format__ (printf, 1, 2)))
67 __attribute__((__nonnull__ (1)));
68int kw_cmp(const void *, const void *);
69int lookup(char *);
70int igetc(void);
71int lgetc(int);
72void lungetc(int);
73int findeol(void);
74int expand_macro(void);
75
76TAILQ_HEAD(symhead, sym)struct symhead { struct sym *tqh_first; struct sym **tqh_last
; }
symhead = TAILQ_HEAD_INITIALIZER(symhead){ ((void *)0), &(symhead).tqh_first };
77struct sym {
78 TAILQ_ENTRY(sym)struct { struct sym *tqe_next; struct sym **tqe_prev; } entry;
79 int used;
80 int persist;
81 char *nam;
82 char *val;
83};
84int symset(const char *, const char *, int);
85char *symget(const char *);
86
87struct filter_rib_l {
88 struct filter_rib_l *next;
89 char name[PEER_DESCR_LEN32];
90};
91
92struct filter_peers_l {
93 struct filter_peers_l *next;
94 struct filter_peers p;
95};
96
97struct filter_prefix_l {
98 struct filter_prefix_l *next;
99 struct filter_prefix p;
100};
101
102struct filter_prefixlen {
103 enum comp_ops op;
104 int len_min;
105 int len_max;
106};
107
108struct filter_as_l {
109 struct filter_as_l *next;
110 struct filter_as a;
111};
112
113struct filter_match_l {
114 struct filter_match m;
115 struct filter_prefix_l *prefix_l;
116 struct filter_as_l *as_l;
117 struct filter_prefixset *prefixset;
118} fmopts;
119
120struct aspa_tas_l {
121 struct aspa_tas_l *next;
122 uint32_t as;
123 uint32_t num;
124};
125
126struct flowspec_context {
127 uint8_t *components[FLOWSPEC_TYPE_MAX14];
128 uint16_t complen[FLOWSPEC_TYPE_MAX14];
129 uint8_t aid;
130 uint8_t type;
131 uint8_t addr_type;
132};
133
134struct peer *alloc_peer(void);
135struct peer *new_peer(void);
136struct peer *new_group(void);
137int add_mrtconfig(enum mrt_type, char *, int, struct peer *,
138 char *);
139struct rde_rib *add_rib(char *);
140struct rde_rib *find_rib(char *);
141int rib_add_fib(struct rde_rib *, u_int);
142int get_id(struct peer *);
143int merge_prefixspec(struct filter_prefix *,
144 struct filter_prefixlen *);
145int expand_rule(struct filter_rule *, struct filter_rib_l *,
146 struct filter_peers_l *, struct filter_match_l *,
147 struct filter_set_head *);
148int str2key(char *, char *, size_t);
149int neighbor_consistent(struct peer *);
150int merge_filterset(struct filter_set_head *, struct filter_set *);
151void optimize_filters(struct filter_head *);
152struct filter_rule *get_rule(enum action_types);
153
154int parsecommunity(struct community *, int, char *);
155int parseextcommunity(struct community *, char *,
156 char *);
157static int new_as_set(char *);
158static void add_as_set(uint32_t);
159static void done_as_set(void);
160static struct prefixset *new_prefix_set(char *, int);
161static void add_roa_set(struct prefixset_item *, uint32_t, uint8_t,
162 time_t);
163static struct rtr_config *get_rtr(struct bgpd_addr *);
164static int insert_rtr(struct rtr_config *);
165static int merge_aspa_set(uint32_t, struct aspa_tas_l *, time_t);
166static int map_tos(char *, int *);
167static int getservice(char *);
168static int parse_flags(char *);
169static struct flowspec_config *flow_to_flowspec(struct flowspec_context *);
170static void flow_free(struct flowspec_context *);
171static int push_prefix(struct bgpd_addr *, uint8_t);
172static int push_binop(uint8_t, long long);
173static int push_unary_numop(enum comp_ops, long long);
174static int push_binary_numop(enum comp_ops, long long, long long);
175static int geticmptypebyname(char *, uint8_t);
176static int geticmpcodebyname(u_long, char *, uint8_t);
177
178static struct bgpd_config *conf;
179static struct network_head *netconf;
180static struct peer_head *new_peers, *cur_peers;
181static struct rtr_config_head *cur_rtrs;
182static struct peer *curpeer;
183static struct peer *curgroup;
184static struct rde_rib *currib;
185static struct l3vpn *curvpn;
186static struct prefixset *curpset, *curoset;
187static struct roa_tree *curroatree;
188static struct rtr_config *currtr;
189static struct filter_head *filter_l;
190static struct filter_head *peerfilter_l;
191static struct filter_head *groupfilter_l;
192static struct filter_rule *curpeer_filter[2];
193static struct filter_rule *curgroup_filter[2];
194static struct flowspec_context *curflow;
195static int noexpires;
196
197typedef struct {
198 union {
199 long long number;
200 char *string;
201 struct bgpd_addr addr;
202 uint8_t u8;
203 struct filter_rib_l *filter_rib;
204 struct filter_peers_l *filter_peers;
205 struct filter_match_l filter_match;
206 struct filter_prefixset *filter_prefixset;
207 struct filter_prefix_l *filter_prefix;
208 struct filter_as_l *filter_as;
209 struct filter_set *filter_set;
210 struct filter_set_head *filter_set_head;
211 struct aspa_tas_l *aspa_elm;
212 struct {
213 struct bgpd_addr prefix;
214 uint8_t len;
215 } prefix;
216 struct filter_prefixlen prefixlen;
217 struct prefixset_item *prefixset_item;
218 struct {
219 enum auth_enc_alg enc_alg;
220 uint8_t enc_key_len;
221 char enc_key[IPSEC_ENC_KEY_LEN32];
222 } encspec;
223 } v;
224 int lineno;
225} YYSTYPE;
226
227#line 228 "parse.c"
228#define AS257 257
229#define ROUTERID258 258
230#define HOLDTIME259 259
231#define YMIN260 260
232#define LISTEN261 261
233#define ON262 262
234#define FIBUPDATE263 263
235#define FIBPRIORITY264 264
236#define RTABLE265 265
237#define NONE266 266
238#define UNICAST267 267
239#define VPN268 268
240#define RD269 269
241#define EXPORT270 270
242#define EXPORTTRGT271 271
243#define IMPORTTRGT272 272
244#define DEFAULTROUTE273 273
245#define RDE274 274
246#define RIB275 275
247#define EVALUATE276 276
248#define IGNORE277 277
249#define COMPARE278 278
250#define RTR279 279
251#define PORT280 280
252#define GROUP281 281
253#define NEIGHBOR282 282
254#define NETWORK283 283
255#define EBGP284 284
256#define IBGP285 285
257#define FLOWSPEC286 286
258#define PROTO287 287
259#define FLAGS288 288
260#define FRAGMENT289 289
261#define TOS290 290
262#define LENGTH291 291
263#define ICMPTYPE292 292
264#define CODE293 293
265#define LOCALAS294 294
266#define REMOTEAS295 295
267#define DESCR296 296
268#define LOCALADDR297 297
269#define MULTIHOP298 298
270#define PASSIVE299 299
271#define MAXPREFIX300 300
272#define RESTART301 301
273#define ANNOUNCE302 302
274#define CAPABILITIES303 303
275#define REFRESH304 304
276#define AS4BYTE305 305
277#define CONNECTRETRY306 306
278#define ENHANCED307 307
279#define ADDPATH308 308
280#define SEND309 309
281#define RECV310 310
282#define PLUS311 311
283#define POLICY312 312
284#define ROLE313 313
285#define DEMOTE314 314
286#define ENFORCE315 315
287#define NEIGHBORAS316 316
288#define ASOVERRIDE317 317
289#define REFLECTOR318 318
290#define DEPEND319 319
291#define DOWN320 320
292#define DUMP321 321
293#define IN322 322
294#define OUT323 323
295#define SOCKET324 324
296#define RESTRICTED325 325
297#define LOG326 326
298#define TRANSPARENT327 327
299#define TCP328 328
300#define MD5SIG329 329
301#define PASSWORD330 330
302#define KEY331 331
303#define TTLSECURITY332 332
304#define ALLOW333 333
305#define DENY334 334
306#define MATCH335 335
307#define QUICK336 336
308#define FROM337 337
309#define TO338 338
310#define ANY339 339
311#define CONNECTED340 340
312#define STATIC341 341
313#define COMMUNITY342 342
314#define EXTCOMMUNITY343 343
315#define LARGECOMMUNITY344 344
316#define DELETE345 345
317#define MAXCOMMUNITIES346 346
318#define MAXEXTCOMMUNITIES347 347
319#define MAXLARGECOMMUNITIES348 348
320#define PREFIX349 349
321#define PREFIXLEN350 350
322#define PREFIXSET351 351
323#define ASPASET352 352
324#define ROASET353 353
325#define ORIGINSET354 354
326#define OVS355 355
327#define AVS356 356
328#define EXPIRES357 357
329#define ASSET358 358
330#define SOURCEAS359 359
331#define TRANSITAS360 360
332#define PEERAS361 361
333#define PROVIDERAS362 362
334#define CUSTOMERAS363 363
335#define MAXASLEN364 364
336#define MAXASSEQ365 365
337#define SET366 366
338#define LOCALPREF367 367
339#define MED368 368
340#define METRIC369 369
341#define NEXTHOP370 370
342#define REJECT371 371
343#define BLACKHOLE372 372
344#define NOMODIFY373 373
345#define SELF374 374
346#define PREPEND_SELF375 375
347#define PREPEND_PEER376 376
348#define PFTABLE377 377
349#define WEIGHT378 378
350#define RTLABEL379 379
351#define ORIGIN380 380
352#define PRIORITY381 381
353#define ERROR382 382
354#define INCLUDE383 383
355#define IPSEC384 384
356#define ESP385 385
357#define AH386 386
358#define SPI387 387
359#define IKE388 388
360#define IPV4389 389
361#define IPV6390 390
362#define QUALIFY391 391
363#define VIA392 392
364#define NE393 393
365#define LE394 394
366#define GE395 395
367#define XRANGE396 396
368#define LONGER397 397
369#define MAXLEN398 398
370#define MAX399 399
371#define STRING400 400
372#define NUMBER401 401
373#define YYERRCODE256 256
374const short yylhs[] =
375 { -1,
376 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
377 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
378 1, 2, 2, 3, 3, 26, 26, 11, 66, 67,
379 85, 68, 68, 84, 84, 88, 69, 69, 87, 87,
380 30, 90, 70, 70, 91, 72, 72, 14, 14, 89,
381 89, 71, 71, 92, 92, 93, 65, 65, 64, 64,
382 73, 94, 73, 95, 95, 96, 96, 96, 78, 78,
383 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
384 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
385 98, 74, 97, 97, 97, 99, 99, 77, 75, 75,
386 75, 75, 75, 101, 76, 102, 102, 103, 103, 21,
387 21, 106, 104, 108, 107, 105, 105, 105, 109, 109,
388 110, 110, 112, 112, 111, 111, 111, 20, 20, 100,
389 100, 113, 113, 114, 114, 116, 114, 117, 114, 114,
390 114, 114, 114, 115, 115, 115, 115, 24, 118, 118,
391 121, 121, 120, 120, 120, 25, 25, 22, 22, 119,
392 119, 123, 123, 122, 122, 122, 23, 12, 12, 13,
393 13, 27, 28, 28, 29, 29, 4, 4, 124, 79,
394 125, 125, 125, 125, 126, 126, 126, 126, 126, 127,
395 129, 80, 130, 81, 131, 131, 131, 131, 131, 18,
396 18, 19, 19, 128, 128, 128, 133, 133, 133, 133,
397 132, 132, 132, 132, 132, 132, 132, 132, 132, 132,
398 132, 132, 132, 132, 132, 132, 132, 132, 132, 132,
399 132, 132, 132, 132, 132, 132, 132, 132, 132, 132,
400 132, 132, 132, 132, 132, 132, 132, 132, 132, 132,
401 132, 132, 132, 132, 132, 132, 132, 132, 8, 8,
402 6, 6, 7, 7, 7, 7, 10, 10, 5, 5,
403 63, 63, 82, 31, 31, 31, 32, 32, 33, 33,
404 36, 36, 36, 37, 37, 38, 41, 41, 40, 40,
405 39, 39, 39, 39, 39, 39, 57, 57, 57, 57,
406 58, 58, 58, 56, 56, 55, 47, 47, 49, 49,
407 48, 48, 48, 50, 50, 50, 46, 46, 45, 45,
408 45, 45, 44, 134, 44, 42, 42, 43, 43, 43,
409 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
410 43, 43, 43, 51, 51, 51, 51, 51, 62, 62,
411 62, 62, 53, 53, 53, 54, 54, 35, 35, 34,
412 34, 15, 15, 52, 52, 52, 52, 52, 52, 52,
413 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
414 52, 52, 52, 52, 52, 52, 52, 52, 52, 9,
415 16, 17, 83, 83, 86, 86, 86, 86, 59, 59,
416 59, 59, 59, 59, 60, 60, 61, 61,
417};
418const short yylen[] =
419 { 2,
420 0, 2, 3, 3, 3, 3, 3, 3, 3, 3,
421 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
422 1, 1, 1, 1, 1, 2, 1, 1, 3, 2,
423 0, 8, 5, 1, 3, 0, 8, 5, 1, 3,
424 2, 0, 7, 4, 0, 8, 5, 0, 2, 4,
425 6, 6, 4, 1, 3, 9, 1, 3, 1, 2,
426 2, 0, 8, 1, 3, 2, 2, 2, 2, 3,
427 2, 2, 3, 3, 5, 2, 2, 2, 3, 2,
428 4, 6, 3, 3, 4, 3, 4, 2, 2, 3,
429 0, 5, 1, 3, 2, 0, 2, 5, 3, 4,
430 5, 5, 4, 0, 5, 2, 6, 1, 3, 1,
431 1, 0, 3, 0, 3, 1, 3, 2, 1, 1,
432 1, 5, 1, 3, 1, 2, 3, 1, 1, 0,
433 1, 1, 2, 1, 1, 0, 3, 0, 3, 1,
434 2, 1, 2, 3, 2, 1, 1, 1, 2, 6,
435 1, 3, 1, 3, 3, 1, 1, 1, 1, 1,
436 5, 1, 3, 1, 2, 3, 1, 1, 1, 0,
437 1, 1, 3, 3, 1, 1, 0, 1, 0, 8,
438 0, 2, 3, 3, 2, 3, 3, 2, 1, 0,
439 0, 5, 0, 6, 0, 2, 3, 3, 3, 0,
440 2, 0, 2, 4, 3, 0, 0, 2, 3, 3,
441 2, 2, 3, 2, 2, 2, 2, 1, 1, 2,
442 2, 2, 3, 3, 3, 3, 4, 3, 3, 4,
443 6, 3, 2, 2, 2, 2, 3, 3, 2, 3,
444 4, 4, 4, 3, 8, 2, 2, 6, 1, 1,
445 2, 3, 2, 2, 2, 3, 2, 3, 0, 2,
446 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
447 0, 2, 7, 1, 1, 1, 0, 1, 1, 1,
448 0, 2, 6, 1, 3, 1, 1, 5, 1, 3,
449 1, 1, 2, 2, 1, 1, 2, 2, 2, 4,
450 1, 3, 4, 1, 3, 2, 1, 3, 1, 3,
451 2, 4, 3, 1, 3, 4, 1, 3, 1, 1,
452 2, 3, 0, 0, 2, 1, 2, 1, 1, 2,
453 2, 2, 3, 3, 2, 2, 2, 2, 2, 3,
454 2, 2, 2, 0, 1, 2, 3, 4, 1, 1,
455 1, 1, 0, 2, 6, 3, 1, 1, 1, 0,
456 1, 1, 1, 2, 3, 3, 2, 3, 3, 2,
457 3, 3, 2, 3, 3, 2, 2, 2, 2, 2,
458 2, 2, 1, 2, 2, 3, 4, 4, 2, 1,
459 1, 1, 0, 2, 0, 1, 2, 3, 1, 1,
460 1, 1, 1, 1, 1, 1, 1, 1,
461};
462const short yydefred[] =
463 { 1,
464 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
465 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
466 274, 275, 276, 0, 0, 0, 0, 0, 0, 0,
467 0, 0, 2, 0, 0, 0, 0, 0, 0, 0,
468 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
469 0, 0, 20, 22, 21, 23, 0, 172, 71, 0,
470 72, 0, 28, 77, 76, 88, 0, 0, 0, 0,
471 0, 0, 27, 0, 0, 261, 262, 0, 0, 0,
472 0, 104, 89, 0, 0, 0, 80, 78, 0, 0,
473 0, 0, 0, 0, 0, 30, 0, 278, 0, 3,
474 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
475 14, 15, 16, 17, 18, 19, 0, 70, 73, 0,
476 0, 91, 86, 0, 83, 84, 0, 26, 0, 0,
477 0, 0, 268, 267, 0, 0, 0, 0, 99, 0,
478 0, 168, 169, 0, 0, 171, 90, 0, 0, 0,
479 0, 0, 0, 0, 79, 0, 0, 0, 0, 175,
480 176, 191, 0, 179, 0, 85, 0, 195, 100, 173,
481 174, 0, 0, 103, 383, 358, 0, 359, 0, 0,
482 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
483 354, 0, 136, 138, 0, 0, 0, 112, 114, 0,
484 142, 134, 135, 0, 132, 140, 0, 178, 81, 0,
485 0, 394, 0, 53, 0, 54, 44, 0, 0, 0,
486 87, 286, 0, 282, 279, 280, 0, 0, 129, 128,
487 75, 0, 0, 0, 0, 92, 93, 0, 0, 101,
488 102, 361, 0, 364, 0, 0, 367, 0, 0, 370,
489 0, 0, 378, 377, 379, 380, 376, 381, 382, 384,
490 373, 0, 0, 385, 390, 389, 0, 0, 110, 111,
491 0, 106, 0, 0, 158, 159, 143, 400, 401, 403,
492 167, 399, 0, 402, 404, 0, 0, 141, 160, 156,
493 157, 0, 0, 149, 0, 0, 105, 133, 0, 98,
494 38, 0, 0, 0, 0, 0, 0, 0, 0, 0,
495 47, 0, 33, 0, 0, 0, 0, 295, 296, 291,
496 0, 292, 287, 0, 0, 192, 181, 97, 0, 95,
497 0, 0, 0, 0, 64, 0, 0, 0, 0, 0,
498 0, 0, 0, 0, 0, 0, 218, 0, 0, 0,
499 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
500 0, 0, 0, 0, 196, 194, 0, 249, 0, 0,
501 0, 0, 365, 366, 368, 369, 371, 372, 374, 375,
502 357, 0, 386, 0, 147, 148, 0, 0, 137, 139,
503 0, 408, 407, 0, 165, 0, 0, 0, 119, 120,
504 113, 0, 115, 82, 39, 0, 0, 0, 0, 0,
505 52, 55, 0, 345, 0, 41, 0, 0, 0, 0,
506 24, 25, 34, 0, 0, 284, 293, 294, 0, 0,
507 0, 207, 0, 0, 94, 68, 66, 67, 0, 199,
508 0, 222, 235, 236, 0, 221, 257, 0, 211, 0,
509 215, 217, 0, 0, 0, 0, 0, 0, 0, 0,
510 0, 234, 233, 253, 0, 0, 239, 251, 0, 220,
511 0, 255, 254, 0, 246, 0, 247, 0, 269, 270,
512 0, 216, 198, 197, 388, 387, 0, 0, 108, 0,
513 145, 0, 162, 0, 166, 151, 0, 154, 155, 0,
514 0, 0, 118, 121, 0, 0, 0, 49, 0, 398,
515 0, 0, 346, 0, 43, 0, 0, 0, 0, 0,
516 0, 289, 0, 273, 349, 0, 0, 0, 0, 0,
517 0, 0, 0, 0, 350, 351, 352, 0, 0, 0,
518 0, 0, 0, 0, 0, 326, 329, 307, 328, 0,
519 0, 205, 0, 0, 0, 0, 0, 182, 180, 189,
520 0, 63, 65, 223, 258, 213, 0, 0, 240, 228,
521 225, 226, 229, 0, 0, 0, 363, 362, 232, 263,
522 264, 265, 266, 224, 238, 237, 252, 0, 0, 0,
523 256, 244, 0, 355, 356, 0, 0, 144, 0, 0,
524 0, 0, 0, 0, 126, 117, 37, 40, 0, 0,
525 347, 50, 0, 46, 32, 35, 283, 285, 0, 0,
526 0, 0, 335, 336, 337, 0, 0, 299, 0, 341,
527 391, 342, 392, 343, 330, 331, 339, 338, 297, 298,
528 309, 0, 332, 327, 320, 0, 406, 405, 0, 0,
529 311, 0, 0, 208, 204, 0, 184, 188, 185, 0,
530 0, 183, 260, 241, 227, 0, 230, 0, 0, 0,
531 0, 107, 109, 161, 163, 150, 152, 123, 0, 127,
532 0, 348, 0, 288, 290, 334, 333, 0, 304, 0,
533 0, 306, 340, 0, 308, 0, 313, 0, 317, 0,
534 0, 0, 321, 210, 209, 186, 187, 0, 0, 0,
535 0, 0, 0, 0, 57, 0, 51, 0, 0, 300,
536 397, 310, 0, 0, 312, 322, 201, 0, 231, 248,
537 0, 122, 124, 60, 0, 0, 0, 305, 0, 318,
538 203, 0, 56, 58, 303, 316, 0, 245, 272,
539};
540const short yydgoto[] =
541 { 1,
542 422, 57, 650, 209, 481, 80, 584, 569, 266, 137,
543 367, 145, 147, 408, 579, 632, 634, 709, 729, 501,
544 272, 277, 286, 388, 293, 74, 322, 308, 162, 309,
545 34, 99, 227, 243, 190, 158, 425, 224, 323, 523,
546 324, 545, 546, 430, 699, 700, 547, 548, 642, 701,
547 416, 381, 139, 382, 689, 690, 549, 691, 502, 652,
548 394, 550, 748, 715, 716, 35, 36, 37, 38, 39,
549 40, 41, 42, 43, 44, 45, 368, 47, 48, 49,
550 50, 51, 150, 424, 314, 419, 406, 302, 310, 218,
551 312, 215, 216, 127, 334, 335, 236, 165, 237, 200,
552 140, 201, 490, 202, 401, 295, 203, 296, 402, 503,
553 504, 679, 204, 205, 389, 273, 274, 206, 288, 294,
554 497, 289, 494, 232, 434, 561, 52, 326, 228, 129,
555 239, 370, 551, 431,
556};
557const short yysindex[] =
558 { 0,
559 532, 91, -242, -276, -209, -124, -256, -249, -239, -231,
560 -92, -276, -227, 352, -224, -223, -192, -150, -125, -256,
561 0, 0, 0, -107, 175, 179, -72, -67, -47, 24,
562 -52, 301, 0, 36, 365, 386, 401, 405, 409, 422,
563 426, 436, 450, 459, 483, 485, 495, 505, 508, 522,
564 533, 244, 0, 0, 0, 0, 150, 0, 0, 156,
565 0, -276, 0, 0, 0, 0, 303, 171, 176, 308,
566 14, 0, 0, 203, 210, 0, 0, 559, 566, 84,
567 259, 0, 0, 231, -1, 311, 0, 0, 530, 635,
568 635, 560, 564, 312, -256, 0, -227, 0, 414, 0,
569 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
570 0, 0, 0, 0, 0, 0, -59, 0, 0, 438,
571 321, 0, 0, 322, 0, 0, 597, 0, 604, 259,
572 327, 328, 0, 0, 334, 343, 259, 1147, 0, 542,
573 360, 0, 0, 361, 363, 0, 0, 635, 635, -115,
574 636, 635, 635, 364, 0, 203, -87, -28, 559, 0,
575 0, 0, -10, 0, -193, 0, 635, 0, 0, 0,
576 0, 259, 259, 0, 0, 0, 420, 0, -30, -25,
577 -24, 377, 367, 368, 366, -21, 370, 371, 635, 420,
578 0, -82, 0, 0, 81, 33, -77, 0, 0, 259,
579 0, 0, 0, 542, 0, 0, 378, 0, 0, 361,
580 656, 0, -242, 0, 107, 0, 0, 146, 657, 667,
581 0, 0, 635, 0, 0, 0, -27, 671, 0, 0,
582 0, 676, -256, 402, 526, 0, 0, -126, 642, 0,
583 0, 0, -263, 0, 403, 404, 0, 406, 407, 0,
584 408, 411, 0, 0, 0, 0, 0, 0, 0, 0,
585 0, 415, 424, 0, 0, 0, 551, 410, 0, 0,
586 635, 0, -22, -22, 0, 0, 0, 0, 0, 0,
587 0, 0, 635, 0, 0, -12, 425, 0, 0, 0,
588 0, 635, 529, 0, -190, -190, 0, 0, 361, 0,
589 0, 146, 470, 635, 825, 711, 474, 8, 480, 107,
590 0, 146, 0, 153, 440, -242, 444, 0, 0, 0,
591 635, 0, 0, 0, 264, 0, 0, 0, 584, 0,
592 -10, 451, -276, 635, 0, 838, -207, -154, 574, 452,
593 -10, -242, -242, -227, -276, 453, 0, 454, 516, -211,
594 457, -189, -256, -276, 598, 461, 463, 464, -256, 540,
595 -256, 1211, 512, 2, 0, 0, 575, 0, 861, 863,
596 475, 476, 0, 0, 0, 0, 0, 0, 0, 0,
597 0, 107, 0, 155, 0, 0, 477, 827, 0, 0,
598 223, 0, 0, 425, 0, 222, 228, 54, 0, 0,
599 0, 601, 0, 0, 0, 107, 481, 525, 0, 635,
600 0, 0, 226, 0, 487, 0, 153, 753, 146, 107,
601 0, 0, 0, 107, 107, 0, 0, 0, -200, 259,
602 848, 0, 764, 899, 0, 0, 0, 0, -64, 0,
603 490, 0, 0, 0, 492, 0, 0, 150, 0, 203,
604 0, 0, -173, -256, -256, -256, -256, 592, 202, -237,
605 489, 0, 0, 0, -256, -256, 0, 0, 497, 0,
606 86, 0, 0, 191, 0, 635, 0, -256, 0, 0,
607 47, 0, 0, 0, 0, 0, 774, 551, 0, 107,
608 0, 477, 0, 107, 0, 0, 107, 0, 0, 635,
609 -12, -10, 0, 0, 54, 775, 146, 0, 781, 0,
610 -12, 506, 0, 470, 0, 549, 785, 789, 153, 798,
611 440, 0, 107, 0, 0, -258, 523, 524, 534, -74,
612 513, 543, 545, 546, 0, 0, 0, 547, 548, -194,
613 8, 8, 140, 550, 848, 0, 0, 0, 0, 148,
614 720, 0, 923, -256, 552, 553, 554, 0, 0, 0,
615 924, 0, 0, 0, 0, 0, 557, 646, 0, 0,
616 0, 0, 0, -256, 567, -256, 0, 0, 0, 0,
617 0, 0, 0, 0, 0, 0, 0, -227, -227, 551,
618 0, 0, 585, 0, 0, 826, 155, 0, 850, 223,
619 852, 222, 174, -10, 0, 0, 0, 0, 635, 572,
620 0, 0, 153, 0, 0, 0, 0, 0, 853, -200,
621 581, 582, 0, 0, 0, -69, 8, 0, 8, 0,
622 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
623 0, 96, 0, 0, 0, 583, 0, 0, 37, -12,
624 0, 153, 974, 0, 0, 975, 0, 0, 0, 586,
625 587, 0, 0, 0, 0, 677, 0, 203, 203, 107,
626 588, 0, 0, 0, 0, 0, 0, 0, 107, 0,
627 153, 0, 470, 0, 0, 0, 0, 146, 0, 111,
628 866, 0, 0, 635, 0, 140, 0, 293, 0, 111,
629 867, 153, 0, 0, 0, 0, 0, 595, 594, 872,
630 599, 873, 174, -224, 0, 107, 0, 99, 146, 0,
631 0, 0, 101, 293, 0, 0, 0, 600, 0, 0,
632 602, 0, 0, 0, 878, 153, -69, 0, 37, 0,
633 0, 605, 0, 0, 0, 0, 606, 0, 0,};
634const short yyrindex[] =
635 { 0,
636 722, 0, 0, 0, 0, 0, 0, 0, 0, 0,
637 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
638 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
639 0, 0, 0, -100, 0, 0, 0, 0, 0, 0,
640 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
641 0, 0, 0, 0, 0, 0, 997, 0, 0, 0,
642 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
643 0, 63, 0, 886, 0, 0, 0, 0, 0, 0,
644 1000, 0, 0, 0, 0, 1001, 0, 0, 0, -86,
645 -97, 0, 0, 0, 0, 0, 0, 0, 320, 0,
646 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
647 0, 0, 0, 0, 0, 0, 0, 0, 0, 1002,
648 0, 0, 0, 0, 0, 0, 0, 0, 0, 1000,
649 0, 0, 0, 0, 0, 0, 1000, 0, 0, -5,
650 0, 0, 0, 1011, 0, 0, 0, -97, 904, 0,
651 262, -97, -97, 0, 0, 1013, 0, 0, 72, 0,
652 0, 0, 0, 0, 1015, 0, 206, 0, 0, 0,
653 0, 1000, 1000, 0, 0, 0, -253, 0, 0, 0,
654 0, 0, 0, 0, 0, 0, 0, 0, 1250, 627,
655 0, 0, 0, 0, 0, 0, 0, 0, 0, 1000,
656 0, 0, 0, 13, 0, 0, 0, 0, 0, 66,
657 272, 0, 0, 0, -83, 0, 0, 0, 281, 297,
658 0, 0, 628, 0, 0, 0, 0, 1026, 0, 0,
659 0, 0, 0, 0, 0, 0, 0, 0, 722, 0,
660 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
661 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
662 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
663 306, 0, 0, 0, 0, 0, 0, 0, 0, 0,
664 0, 0, 239, 0, 0, 448, 0, 0, 0, 0,
665 0, 306, 76, 0, 0, 0, 0, 0, 1011, 0,
666 0, 0, 681, 1103, 970, 0, 0, 1, 0, -54,
667 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
668 -149, 0, 0, 723, 0, 0, 0, 0, 1015, 0,
669 0, 0, 0, -2, 0, 0, 0, 0, 0, 0,
670 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
671 0, 0, 0, 79, 0, 90, 0, 0, 0, 0,
672 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
673 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
674 0, 1233, 0, 0, 0, 0, 0, 388, 0, 0,
675 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
676 0, 421, 0, 0, 0, -54, 0, 0, 1169, 1035,
677 0, 0, 0, 0, 0, 0, 0, 0, 0, -54,
678 0, 0, 0, -54, -85, 0, 0, 0, 0, 1000,
679 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
680 0, 0, 0, 0, 0, 0, 0, 103, 0, 120,
681 0, 0, 121, 0, 0, 0, 0, 0, 0, 0,
682 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
683 0, 0, 0, 0, 0, 1250, 0, 0, 0, 0,
684 0, 0, 0, 0, 0, 0, 0, 0, 0, -54,
685 0, 0, 0, 204, 0, 0, -54, 0, 0, 207,
686 379, 0, 0, 0, 0, 0, 0, 0, 0, 0,
687 0, 0, 0, 16, 0, 0, 0, 0, 0, 0,
688 0, 0, 462, 0, 0, 0, 0, 0, 0, 0,
689 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
690 788, 788, 0, 0, 17, 0, 0, 0, 0, 0,
691 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
692 0, 0, 0, 0, 0, 0, 0, 121, 0, 0,
693 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
694 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
695 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
696 0, 0, 0, 0, 0, 0, 0, 0, 306, 0,
697 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
698 0, 0, 0, 0, 0, 0, 124, 0, 788, 0,
699 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
700 0, 234, 0, 0, 0, 0, 0, 0, 0, 295,
701 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
702 0, 0, 0, 0, 0, 4, 0, 138, 147, 1233,
703 0, 0, 0, 0, 0, 0, 0, 0, 136, 0,
704 0, 0, 16, 0, 0, 0, 0, 0, 0, -7,
705 0, 0, 0, 331, 0, 0, 0, 0, 0, 127,
706 0, 0, 0, 0, 0, 0, 0, 0, 154, 0,
707 0, 0, 0, 21, 0, -54, 0, 314, 0, 0,
708 0, 0, 383, 0, 0, 0, 0, 0, 0, 0,
709 0, 0, 0, 0, 0, 0, 919, 0, 925, 0,
710 0, 164, 0, 0, 0, 0, 0, 0, 0,};
711const short yygindex[] =
712 { 0,
713 9, -46, -307, -123, 0, -13, 0, 486, 0, 0,
714 -4, 568, 0, -464, 0, 0, 0, 0, 0, -159,
715 -354, 0, -134, -312, 0, -91, 5, -14, 0, -234,
716 0, 0, 0, 865, -327, 0, 0, -281, -381, 0,
717 0, 0, 511, 0, -507, 353, 0, -491, 0, 318,
718 73, -103, -93, 468, -492, 372, 0, 316, -188, 0,
719 -437, 0, 0, 323, 0, 0, 0, 0, 0, 0,
720 0, 0, 0, 0, 629, 0, 1060, 0, 0, 823,
721 0, 0, -90, 0, 0, -183, 0, 0, 752, 0,
722 0, 0, 761, 0, 0, 634, 0, 0, 746, 0,
723 0, 0, 0, 0, 780, 0, 0, 0, 0, 576,
724 -534, 0, 0, 876, 811, 0, 0, 0, 0, -340,
725 0, -344, 0, 0, 0, 0, 0, 0, 0, 0,
726 0, -296, 0, 0,
727};
728#define YYTABLESIZE1630 1630
729const short yytable[] =
730 { 81,
731 151, 82, 64, 231, 130, 156, 423, 287, 59, 214,
732 344, 56, 245, 200, 246, 88, 72, 248, 251, 249,
733 252, 262, 131, 263, 387, 48, 325, 393, 433, 489,
734 59, 307, 393, 426, 191, 223, 169, 628, 393, 393,
735 271, 393, 651, 174, 344, 292, 493, 522, 626, 612,
736 60, 641, 441, 688, 462, 496, 316, 211, 212, 48,
737 562, 219, 220, 604, 59, 118, 120, 405, 678, 233,
738 393, 234, 61, 610, 491, 177, 238, 577, 240, 241,
739 317, 172, 84, 318, 319, 153, 300, 637, 250, 398,
740 155, 371, 284, 282, 285, 321, 621, 648, 267, 219,
741 53, 360, 161, 544, 465, 694, 297, 393, 694, 514,
742 694, 443, 212, 284, 282, 285, 304, 301, 444, 153,
743 694, 160, 393, 58, 306, 344, 466, 567, 200, 214,
744 259, 393, 315, 344, 393, 393, 372, 62, 320, 305,
745 48, 622, 305, 63, 305, 59, 360, 242, 399, 568,
746 305, 65, 395, 331, 305, 283, 243, 54, 55, 698,
747 235, 66, 63, 202, 76, 77, 303, 344, 67, 332,
748 333, 436, 73, 271, 277, 404, 500, 83, 733, 598,
749 384, 447, 68, 69, 516, 62, 257, 395, 463, 393,
750 177, 61, 391, 442, 172, 395, 395, 395, 488, 58,
751 153, 396, 287, 250, 722, 58, 63, 85, 648, 78,
752 79, 616, 702, 409, 219, 331, 740, 544, 717, 418,
753 695, 56, 507, 737, 512, 739, 738, 212, 328, 316,
754 429, 332, 333, 284, 282, 285, 277, 277, 685, 618,
755 519, 521, 673, 439, 214, 259, 344, 213, 344, 86,
756 393, 314, 450, 317, 656, 675, 318, 319, 477, 495,
757 393, 677, 242, 395, 395, 395, 393, 393, 393, 427,
758 649, 243, 608, 432, 87, 70, 393, 393, 202, 395,
759 400, 400, 284, 282, 285, 284, 282, 285, 271, 125,
760 126, 487, 89, 393, 393, 448, 449, 90, 393, 393,
761 393, 91, 393, 393, 319, 683, 597, 71, 225, 226,
762 600, 320, 222, 602, 395, 506, 385, 269, 270, 510,
763 142, 143, 290, 291, 56, 78, 79, 92, 393, 517,
764 78, 79, 93, 518, 520, 461, 524, 438, 319, 620,
765 159, 79, 605, 94, 703, 395, 395, 96, 467, 451,
766 56, 56, 645, 648, 473, 319, 475, 413, 468, 344,
767 130, 97, 153, 153, 153, 153, 153, 153, 142, 143,
768 244, 98, 58, 714, 100, 247, 250, 386, 131, 261,
769 344, 95, 325, 392, 595, 590, 479, 480, 125, 229,
770 230, 393, 395, 395, 726, 101, 525, 146, 144, 596,
771 344, 344, 200, 599, 414, 415, 601, 142, 143, 603,
772 102, 287, 153, 153, 103, 48, 48, 319, 104, 319,
773 59, 59, 125, 133, 134, 278, 279, 280, 714, 647,
774 116, 105, 619, 281, 592, 106, 421, 55, 125, 125,
775 125, 153, 395, 395, 680, 107, 278, 279, 280, 570,
776 571, 572, 573, 229, 230, 578, 566, 164, 696, 108,
777 585, 586, 135, 645, 136, 344, 344, 344, 109, 344,
778 344, 344, 344, 591, 344, 153, 153, 344, 344, 344,
779 275, 276, 344, 344, 344, 393, 488, 344, 344, 344,
780 395, 164, 110, 344, 111, 713, 668, 669, 535, 536,
781 537, 393, 393, 125, 112, 646, 719, 164, 164, 164,
782 575, 576, 344, 344, 113, 627, 724, 114, 681, 395,
783 588, 589, 337, 344, 344, 117, 395, 395, 395, 395,
784 395, 115, 736, 338, 719, 395, 395, 339, 340, 724,
785 647, 33, 116, 341, 638, 78, 79, 421, 55, 658,
786 55, 319, 421, 55, 269, 270, 119, 342, 343, 344,
787 345, 346, 347, 348, 121, 349, 278, 279, 280, 665,
788 122, 667, 164, 229, 230, 123, 350, 351, 352, 710,
789 353, 354, 355, 356, 357, 124, 393, 393, 712, 358,
790 359, 360, 395, 395, 395, 361, 395, 395, 395, 393,
791 393, 393, 128, 721, 395, 131, 393, 393, 645, 130,
792 319, 627, 132, 639, 640, 278, 279, 280, 278, 279,
793 280, 290, 291, 281, 138, 735, 511, 498, 499, 362,
794 141, 393, 393, 393, 363, 146, 319, 319, 319, 393,
795 319, 319, 319, 319, 149, 319, 393, 364, 319, 319,
796 319, 365, 148, 319, 319, 319, 281, 281, 319, 319,
797 319, 42, 42, 63, 319, 125, 125, 125, 125, 125,
798 125, 36, 36, 627, 146, 146, 146, 146, 146, 146,
799 45, 45, 152, 319, 319, 647, 153, 319, 157, 393,
800 393, 393, 421, 55, 319, 319, 31, 31, 395, 692,
801 734, 693, 75, 154, 627, 393, 393, 116, 116, 116,
802 116, 116, 116, 395, 395, 125, 125, 163, 395, 167,
803 164, 166, 627, 393, 146, 146, 168, 170, 171, 654,
804 393, 393, 323, 172, 164, 164, 164, 164, 164, 164,
805 76, 77, 395, 173, 125, 395, 395, 253, 254, 255,
806 256, 78, 79, 146, 580, 581, 582, 116, 116, 207,
807 217, 208, 210, 221, 242, 260, 366, 258, 259, 264,
808 265, 125, 125, 125, 583, 395, 58, 299, 125, 125,
809 301, 311, 395, 395, 164, 164, 116, 2, 3, 4,
810 5, 313, 6, 325, 7, 8, 9, 344, 327, 10,
811 395, 330, 329, 373, 374, 11, 375, 376, 377, 383,
812 12, 378, 13, 164, 14, 379, 454, 15, 455, 456,
813 457, 397, 458, 459, 380, 281, 407, 460, 192, 193,
814 194, 195, 196, 197, 410, 411, 213, 16, 417, 222,
815 164, 164, 164, 428, 655, 324, 233, 440, 164, 445,
816 437, 446, 17, 452, 453, 18, 464, 19, 20, 469,
817 470, 395, 471, 472, 21, 22, 23, 175, 474, 478,
818 483, 482, 484, 492, 485, 486, 386, 515, 198, 199,
819 505, 508, 24, 25, 26, 27, 509, 513, 552, 28,
820 564, 565, 176, 177, 178, 574, 587, 336, 594, 607,
821 337, 29, 30, 609, 76, 77, 611, 613, 558, 614,
822 344, 338, 629, 615, 31, 339, 340, 179, 180, 181,
823 182, 341, 617, 623, 624, 183, 184, 185, 186, 187,
824 188, 32, 657, 662, 625, 342, 343, 344, 345, 346,
825 347, 348, 630, 349, 631, 633, 567, 635, 636, 643,
826 672, 659, 660, 661, 350, 351, 352, 663, 353, 354,
827 355, 356, 357, 393, 393, 393, 666, 358, 359, 360,
828 543, 671, 682, 361, 674, 653, 676, 684, 337, 324,
829 686, 687, 697, 704, 705, 706, 707, 708, 711, 338,
830 720, 725, 728, 339, 340, 727, 730, 732, 731, 341,
831 741, 742, 743, 190, 747, 749, 69, 362, 193, 353,
832 170, 74, 363, 342, 343, 344, 345, 346, 347, 348,
833 177, 349, 29, 559, 96, 364, 360, 393, 393, 396,
834 396, 396, 350, 351, 352, 206, 353, 354, 355, 356,
835 357, 63, 48, 302, 344, 358, 359, 360, 593, 315,
836 723, 361, 745, 664, 268, 644, 746, 670, 744, 718,
837 46, 369, 560, 420, 324, 324, 324, 412, 324, 324,
838 324, 324, 563, 324, 435, 403, 324, 324, 324, 298,
839 606, 324, 324, 324, 390, 362, 324, 324, 323, 0,
840 363, 0, 324, 0, 393, 393, 393, 0, 0, 0,
841 0, 0, 0, 364, 525, 0, 0, 0, 0, 0,
842 0, 324, 324, 0, 0, 0, 0, 0, 0, 63,
843 0, 0, 0, 0, 0, 0, 0, 0, 0, 344,
844 344, 344, 0, 344, 344, 344, 344, 0, 344, 0,
845 0, 344, 344, 344, 0, 0, 344, 344, 344, 0,
846 0, 344, 344, 344, 553, 0, 0, 344, 0, 0,
847 393, 554, 393, 393, 393, 0, 0, 555, 0, 556,
848 557, 0, 0, 0, 0, 0, 344, 344, 0, 0,
849 0, 14, 0, 393, 393, 0, 0, 393, 393, 176,
850 526, 178, 0, 527, 528, 529, 530, 0, 531, 393,
851 393, 532, 533, 534, 0, 0, 535, 536, 537, 0,
852 0, 538, 539, 0, 0, 0, 0, 540, 0, 393,
853 393, 0, 0, 0, 0, 0, 396, 393, 397, 397,
854 397, 0, 0, 0, 0, 0, 541, 542, 0, 0,
855 0, 0, 393, 0, 0, 393, 393, 393, 0, 0,
856 396, 0, 0, 396, 396, 0, 0, 0, 0, 0,
857 0, 0, 393, 393, 393, 0, 393, 0, 0, 189,
858 393, 393, 393, 393, 0, 0, 0, 0, 393, 393,
859 393, 393, 393, 393, 0, 396, 396, 0, 0, 0,
860 0, 393, 0, 394, 0, 0, 393, 393, 393, 0,
861 0, 0, 0, 393, 393, 0, 0, 0, 396, 0,
862 0, 396, 396, 396, 0, 393, 0, 0, 393, 393,
863 0, 0, 0, 0, 0, 0, 0, 0, 396, 396,
864 396, 0, 396, 476, 0, 0, 396, 396, 396, 396,
865 0, 0, 0, 0, 396, 396, 396, 396, 396, 396,
866 393, 393, 0, 0, 0, 0, 0, 393, 0, 393,
867 0, 0, 396, 396, 396, 0, 0, 0, 0, 396,
868 396, 0, 0, 393, 0, 0, 393, 393, 393, 0,
869 0, 0, 0, 393, 0, 0, 393, 393, 0, 0,
870 0, 0, 0, 393, 393, 393, 0, 393, 0, 0,
871 0, 393, 393, 393, 393, 0, 0, 0, 0, 393,
872 393, 393, 393, 393, 393, 0, 0, 0, 0, 393,
873 0, 0, 0, 0, 0, 397, 0, 393, 393, 393,
874 0, 0, 0, 0, 393, 393, 0, 0, 0, 0,
875 0, 393, 0, 0, 393, 393, 393, 0, 0, 397,
876 0, 0, 397, 397, 0, 0, 0, 0, 0, 0,
877 0, 0, 0, 175, 0, 393, 0, 0, 0, 393,
878 393, 393, 393, 0, 0, 0, 0, 393, 393, 393,
879 393, 393, 393, 0, 0, 397, 0, 0, 176, 177,
880 178, 0, 0, 0, 0, 393, 393, 393, 0, 0,
881 0, 0, 393, 393, 0, 0, 0, 397, 0, 0,
882 397, 397, 397, 179, 180, 181, 182, 0, 0, 0,
883 0, 183, 184, 185, 186, 187, 188, 175, 0, 0,
884 0, 397, 0, 0, 0, 397, 397, 397, 397, 0,
885 0, 0, 0, 397, 397, 397, 397, 397, 397, 395,
886 0, 0, 176, 177, 178, 0, 0, 0, 0, 0,
887 0, 397, 397, 397, 0, 0, 393, 0, 397, 397,
888 0, 0, 0, 0, 395, 395, 395, 179, 180, 181,
889 182, 0, 0, 0, 0, 183, 184, 185, 186, 187,
890 188, 393, 393, 393, 0, 0, 0, 0, 0, 395,
891 395, 395, 395, 0, 0, 0, 0, 395, 395, 395,
892 395, 395, 395, 0, 0, 0, 393, 393, 393, 393,
893 0, 0, 0, 0, 393, 393, 393, 393, 393, 393,
894};
895const short yycheck[] =
896 { 14,
897 91, 15, 7, 163, 10, 97, 314, 196, 4, 125,
898 10, 3, 43, 10, 45, 20, 12, 43, 43, 45,
899 45, 43, 10, 45, 47, 10, 10, 125, 325, 384,
900 10, 215, 45, 315, 138, 123, 130, 530, 125, 125,
901 123, 125, 550, 137, 44, 123, 391, 429, 123, 514,
902 260, 543, 260, 123, 266, 396, 257, 148, 149, 44,
903 125, 152, 153, 501, 44, 57, 62, 302, 603, 263,
904 125, 265, 10, 511, 387, 10, 167, 315, 172, 173,
905 281, 10, 275, 284, 285, 10, 210, 282, 10, 280,
906 95, 355, 60, 61, 62, 123, 355, 61, 189, 10,
907 10, 355, 117, 431, 294, 10, 200, 257, 10, 417,
908 10, 266, 10, 60, 61, 62, 10, 125, 273, 44,
909 10, 117, 125, 400, 215, 125, 316, 301, 125, 10,
910 10, 281, 223, 10, 284, 285, 400, 262, 339, 44,
911 125, 400, 44, 400, 44, 125, 400, 10, 339, 323,
912 44, 401, 287, 280, 44, 123, 10, 400, 401, 123,
913 165, 401, 400, 10, 389, 390, 213, 44, 400, 296,
914 297, 331, 400, 10, 275, 299, 123, 401, 713, 492,
915 271, 341, 275, 276, 419, 123, 182, 61, 400, 339,
916 125, 401, 283, 401, 123, 60, 61, 62, 382, 400,
917 125, 292, 391, 125, 696, 400, 400, 400, 61, 400,
918 401, 519, 650, 304, 125, 280, 724, 545, 683, 310,
919 125, 213, 406, 125, 413, 125, 719, 125, 233, 257,
920 321, 296, 297, 60, 61, 62, 337, 338, 620, 521,
921 424, 425, 597, 334, 125, 125, 123, 363, 125, 400,
922 400, 125, 344, 281, 551, 600, 284, 285, 362, 394,
923 125, 602, 125, 60, 61, 62, 60, 61, 62, 316,
924 123, 125, 507, 10, 400, 368, 363, 280, 125, 363,
925 295, 296, 60, 61, 62, 60, 61, 62, 125, 276,
926 277, 382, 400, 296, 297, 342, 343, 123, 60, 61,
927 62, 123, 400, 401, 10, 613, 490, 400, 337, 338,
928 494, 339, 400, 497, 400, 406, 339, 400, 401, 410,
929 322, 323, 400, 401, 316, 400, 401, 400, 125, 420,
930 400, 401, 400, 424, 425, 349, 430, 333, 44, 523,
931 400, 401, 502, 391, 652, 400, 401, 400, 353, 345,
932 342, 343, 316, 61, 359, 61, 361, 350, 354, 359,
933 366, 61, 287, 288, 289, 290, 291, 292, 322, 323,
934 401, 336, 400, 681, 10, 401, 401, 400, 366, 401,
935 257, 358, 366, 396, 488, 476, 385, 386, 10, 400,
936 401, 61, 400, 401, 702, 10, 257, 10, 400, 490,
937 400, 401, 399, 494, 397, 398, 497, 322, 323, 500,
938 10, 600, 337, 338, 10, 400, 401, 123, 10, 125,
939 400, 401, 44, 340, 341, 393, 394, 395, 736, 393,
940 10, 10, 523, 401, 388, 10, 400, 401, 60, 61,
941 62, 366, 316, 61, 604, 10, 393, 394, 395, 454,
942 455, 456, 457, 400, 401, 460, 448, 10, 642, 10,
943 465, 466, 379, 316, 381, 342, 343, 344, 10, 346,
944 347, 348, 349, 478, 351, 400, 401, 354, 355, 356,
945 400, 401, 359, 360, 361, 280, 670, 364, 365, 366,
946 257, 44, 10, 370, 10, 679, 588, 589, 359, 360,
947 361, 296, 297, 125, 10, 358, 690, 60, 61, 62,
948 309, 310, 389, 390, 10, 530, 700, 10, 609, 393,
949 330, 331, 259, 400, 401, 282, 400, 401, 393, 394,
950 395, 10, 716, 270, 718, 400, 401, 274, 275, 723,
951 393, 10, 10, 280, 540, 400, 401, 400, 401, 554,
952 401, 257, 400, 401, 400, 401, 401, 294, 295, 296,
953 297, 298, 299, 300, 262, 302, 393, 394, 395, 574,
954 400, 576, 125, 400, 401, 400, 313, 314, 315, 670,
955 317, 318, 319, 320, 321, 278, 125, 257, 679, 326,
956 327, 328, 359, 360, 361, 332, 393, 394, 395, 393,
957 394, 395, 400, 694, 401, 47, 400, 401, 316, 400,
958 316, 626, 47, 541, 542, 393, 394, 395, 393, 394,
959 395, 400, 401, 401, 366, 716, 401, 400, 401, 366,
960 400, 393, 394, 395, 371, 325, 342, 343, 344, 401,
961 346, 347, 348, 349, 10, 351, 316, 384, 354, 355,
962 356, 10, 123, 359, 360, 361, 337, 338, 364, 365,
963 366, 400, 401, 400, 370, 287, 288, 289, 290, 291,
964 292, 400, 401, 688, 287, 288, 289, 290, 291, 292,
965 400, 401, 123, 389, 390, 393, 123, 393, 275, 359,
966 360, 361, 400, 401, 400, 401, 400, 401, 316, 627,
967 714, 629, 351, 392, 719, 400, 401, 287, 288, 289,
968 290, 291, 292, 400, 401, 337, 338, 280, 257, 123,
969 400, 400, 737, 393, 337, 338, 123, 401, 401, 10,
970 400, 401, 10, 400, 287, 288, 289, 290, 291, 292,
971 389, 390, 281, 401, 366, 284, 285, 371, 372, 373,
972 374, 400, 401, 366, 266, 267, 268, 337, 338, 400,
973 125, 401, 400, 400, 345, 400, 125, 401, 401, 400,
974 400, 393, 394, 395, 286, 393, 400, 400, 400, 401,
975 125, 125, 400, 401, 337, 338, 366, 256, 257, 258,
976 259, 125, 261, 123, 263, 264, 265, 10, 123, 268,
977 339, 276, 401, 401, 401, 274, 401, 401, 401, 400,
978 279, 401, 281, 366, 283, 401, 301, 286, 303, 304,
979 305, 293, 307, 308, 401, 401, 357, 312, 287, 288,
980 289, 290, 291, 292, 10, 125, 363, 306, 359, 400,
981 393, 394, 395, 400, 125, 123, 263, 10, 401, 276,
982 400, 400, 321, 401, 401, 324, 400, 326, 327, 262,
983 400, 400, 400, 400, 333, 334, 335, 317, 329, 358,
984 10, 297, 10, 47, 400, 400, 400, 125, 337, 338,
985 280, 401, 351, 352, 353, 354, 362, 401, 125, 358,
986 401, 400, 342, 343, 344, 304, 400, 256, 125, 125,
987 259, 370, 371, 123, 389, 390, 401, 359, 10, 125,
988 123, 270, 400, 125, 383, 274, 275, 367, 368, 369,
989 370, 280, 125, 401, 401, 375, 376, 377, 378, 379,
990 380, 400, 10, 10, 401, 294, 295, 296, 297, 298,
991 299, 300, 400, 302, 400, 400, 301, 401, 401, 400,
992 125, 400, 400, 400, 313, 314, 315, 401, 317, 318,
993 319, 320, 321, 60, 61, 62, 400, 326, 327, 328,
994 123, 387, 401, 332, 125, 256, 125, 125, 259, 257,
995 400, 400, 400, 10, 10, 400, 400, 311, 401, 270,
996 125, 125, 399, 274, 275, 401, 125, 125, 400, 280,
997 401, 400, 125, 282, 400, 400, 10, 366, 123, 10,
998 10, 10, 371, 294, 295, 296, 297, 298, 299, 300,
999 10, 302, 10, 125, 10, 384, 400, 400, 125, 60,
1000 61, 62, 313, 314, 315, 10, 317, 318, 319, 320,
1001 321, 400, 362, 125, 257, 326, 327, 328, 481, 125,
1002 698, 332, 737, 568, 190, 545, 739, 590, 736, 688,
1003 1, 239, 434, 312, 342, 343, 344, 307, 346, 347,
1004 348, 349, 439, 351, 329, 296, 354, 355, 356, 204,
1005 505, 359, 360, 361, 274, 366, 364, 365, 366, -1,
1006 371, -1, 370, -1, 60, 61, 62, -1, -1, -1,
1007 -1, -1, -1, 384, 257, -1, -1, -1, -1, -1,
1008 -1, 389, 390, -1, -1, -1, -1, -1, -1, 400,
1009 -1, -1, -1, -1, -1, -1, -1, -1, -1, 342,
1010 343, 344, -1, 346, 347, 348, 349, -1, 351, -1,
1011 -1, 354, 355, 356, -1, -1, 359, 360, 361, -1,
1012 -1, 364, 365, 366, 256, -1, -1, 370, -1, -1,
1013 257, 263, 60, 61, 62, -1, -1, 269, -1, 271,
1014 272, -1, -1, -1, -1, -1, 389, 390, -1, -1,
1015 -1, 283, -1, 280, 281, -1, -1, 284, 285, 342,
1016 343, 344, -1, 346, 347, 348, 349, -1, 351, 296,
1017 297, 354, 355, 356, -1, -1, 359, 360, 361, -1,
1018 -1, 364, 365, -1, -1, -1, -1, 370, -1, 316,
1019 317, -1, -1, -1, -1, -1, 257, 125, 60, 61,
1020 62, -1, -1, -1, -1, -1, 389, 390, -1, -1,
1021 -1, -1, 339, -1, -1, 342, 343, 344, -1, -1,
1022 281, -1, -1, 284, 285, -1, -1, -1, -1, -1,
1023 -1, -1, 359, 360, 361, -1, 363, -1, -1, 123,
1024 367, 368, 369, 370, -1, -1, -1, -1, 375, 376,
1025 377, 378, 379, 380, -1, 316, 317, -1, -1, -1,
1026 -1, 257, -1, 125, -1, -1, 393, 394, 395, -1,
1027 -1, -1, -1, 400, 401, -1, -1, -1, 339, -1,
1028 -1, 342, 343, 344, -1, 281, -1, -1, 284, 285,
1029 -1, -1, -1, -1, -1, -1, -1, -1, 359, 360,
1030 361, -1, 363, 123, -1, -1, 367, 368, 369, 370,
1031 -1, -1, -1, -1, 375, 376, 377, 378, 379, 380,
1032 316, 317, -1, -1, -1, -1, -1, 125, -1, 257,
1033 -1, -1, 393, 394, 395, -1, -1, -1, -1, 400,
1034 401, -1, -1, 339, -1, -1, 342, 343, 344, -1,
1035 -1, -1, -1, 281, -1, -1, 284, 285, -1, -1,
1036 -1, -1, -1, 359, 360, 361, -1, 363, -1, -1,
1037 -1, 367, 368, 369, 370, -1, -1, -1, -1, 375,
1038 376, 377, 378, 379, 380, -1, -1, -1, -1, 317,
1039 -1, -1, -1, -1, -1, 257, -1, 393, 394, 395,
1040 -1, -1, -1, -1, 400, 401, -1, -1, -1, -1,
1041 -1, 339, -1, -1, 342, 343, 344, -1, -1, 281,
1042 -1, -1, 284, 285, -1, -1, -1, -1, -1, -1,
1043 -1, -1, -1, 317, -1, 363, -1, -1, -1, 367,
1044 368, 369, 370, -1, -1, -1, -1, 375, 376, 377,
1045 378, 379, 380, -1, -1, 317, -1, -1, 342, 343,
1046 344, -1, -1, -1, -1, 393, 394, 395, -1, -1,
1047 -1, -1, 400, 401, -1, -1, -1, 339, -1, -1,
1048 342, 343, 344, 367, 368, 369, 370, -1, -1, -1,
1049 -1, 375, 376, 377, 378, 379, 380, 317, -1, -1,
1050 -1, 363, -1, -1, -1, 367, 368, 369, 370, -1,
1051 -1, -1, -1, 375, 376, 377, 378, 379, 380, 317,
1052 -1, -1, 342, 343, 344, -1, -1, -1, -1, -1,
1053 -1, 393, 394, 395, -1, -1, 317, -1, 400, 401,
1054 -1, -1, -1, -1, 342, 343, 344, 367, 368, 369,
1055 370, -1, -1, -1, -1, 375, 376, 377, 378, 379,
1056 380, 342, 343, 344, -1, -1, -1, -1, -1, 367,
1057 368, 369, 370, -1, -1, -1, -1, 375, 376, 377,
1058 378, 379, 380, -1, -1, -1, 367, 368, 369, 370,
1059 -1, -1, -1, -1, 375, 376, 377, 378, 379, 380,
1060};
1061#define YYFINAL1 1
1062#ifndef YYDEBUG0
1063#define YYDEBUG0 0
1064#endif
1065#define YYMAXTOKEN401 401
1066#if YYDEBUG0
1067const char * const yyname[] =
1068 {
1069"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,
10700,0,0,0,0,0,0,0,0,0,0,0,"'+'","','","'-'",0,"'/'",0,0,0,0,0,0,0,0,0,0,0,0,"'<'",
1071"'='","'>'",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,
10720,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,
10730,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,
10740,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,
10750,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,
10760,0,0,0,"AS","ROUTERID","HOLDTIME","YMIN","LISTEN","ON","FIBUPDATE",
1077"FIBPRIORITY","RTABLE","NONE","UNICAST","VPN","RD","EXPORT","EXPORTTRGT",
1078"IMPORTTRGT","DEFAULTROUTE","RDE","RIB","EVALUATE","IGNORE","COMPARE","RTR",
1079"PORT","GROUP","NEIGHBOR","NETWORK","EBGP","IBGP","FLOWSPEC","PROTO","FLAGS",
1080"FRAGMENT","TOS","LENGTH","ICMPTYPE","CODE","LOCALAS","REMOTEAS","DESCR",
1081"LOCALADDR","MULTIHOP","PASSIVE","MAXPREFIX","RESTART","ANNOUNCE",
1082"CAPABILITIES","REFRESH","AS4BYTE","CONNECTRETRY","ENHANCED","ADDPATH","SEND",
1083"RECV","PLUS","POLICY","ROLE","DEMOTE","ENFORCE","NEIGHBORAS","ASOVERRIDE",
1084"REFLECTOR","DEPEND","DOWN","DUMP","IN","OUT","SOCKET","RESTRICTED","LOG",
1085"TRANSPARENT","TCP","MD5SIG","PASSWORD","KEY","TTLSECURITY","ALLOW","DENY",
1086"MATCH","QUICK","FROM","TO","ANY","CONNECTED","STATIC","COMMUNITY",
1087"EXTCOMMUNITY","LARGECOMMUNITY","DELETE","MAXCOMMUNITIES","MAXEXTCOMMUNITIES",
1088"MAXLARGECOMMUNITIES","PREFIX","PREFIXLEN","PREFIXSET","ASPASET","ROASET",
1089"ORIGINSET","OVS","AVS","EXPIRES","ASSET","SOURCEAS","TRANSITAS","PEERAS",
1090"PROVIDERAS","CUSTOMERAS","MAXASLEN","MAXASSEQ","SET","LOCALPREF","MED",
1091"METRIC","NEXTHOP","REJECT","BLACKHOLE","NOMODIFY","SELF","PREPEND_SELF",
1092"PREPEND_PEER","PFTABLE","WEIGHT","RTLABEL","ORIGIN","PRIORITY","ERROR",
1093"INCLUDE","IPSEC","ESP","AH","SPI","IKE","IPV4","IPV6","QUALIFY","VIA","NE",
1094"LE","GE","XRANGE","LONGER","MAXLEN","MAX","STRING","NUMBER",
1095};
1096const char * const yyrule[] =
1097 {"$accept : grammar",
1098"grammar :",
1099"grammar : grammar '\\n'",
1100"grammar : grammar varset '\\n'",
1101"grammar : grammar include '\\n'",
1102"grammar : grammar as_set '\\n'",
1103"grammar : grammar prefixset '\\n'",
1104"grammar : grammar roa_set '\\n'",
1105"grammar : grammar aspa_set '\\n'",
1106"grammar : grammar origin_set '\\n'",
1107"grammar : grammar rtr '\\n'",
1108"grammar : grammar rib '\\n'",
1109"grammar : grammar network '\\n'",
1110"grammar : grammar flowspec '\\n'",
1111"grammar : grammar mrtdump '\\n'",
1112"grammar : grammar conf_main '\\n'",
1113"grammar : grammar l3vpn '\\n'",
1114"grammar : grammar neighbor '\\n'",
1115"grammar : grammar group '\\n'",
1116"grammar : grammar filterrule '\\n'",
1117"grammar : grammar error '\\n'",
1118"asnumber : NUMBER",
1119"as4number : STRING",
1120"as4number : asnumber",
1121"as4number_any : STRING",
1122"as4number_any : asnumber",
1123"string : string STRING",
1124"string : STRING",
1125"yesno : STRING",
1126"varset : STRING '=' string",
1127"include : INCLUDE STRING",
1128"$$1 :",
1129"as_set : ASSET STRING '{' optnl $$1 as_set_l optnl '}'",
1130"as_set : ASSET STRING '{' optnl '}'",
1131"as_set_l : as4number_any",
1132"as_set_l : as_set_l comma as4number_any",
1133"$$2 :",
1134"prefixset : PREFIXSET STRING '{' optnl $$2 prefixset_l optnl '}'",
1135"prefixset : PREFIXSET STRING '{' optnl '}'",
1136"prefixset_l : prefixset_item",
1137"prefixset_l : prefixset_l comma prefixset_item",
1138"prefixset_item : prefix prefixlenop",
1139"$$3 :",
1140"roa_set : ROASET '{' optnl $$3 roa_set_l optnl '}'",
1141"roa_set : ROASET '{' optnl '}'",
1142"$$4 :",
1143"origin_set : ORIGINSET STRING '{' optnl $$4 roa_set_l optnl '}'",
1144"origin_set : ORIGINSET STRING '{' optnl '}'",
1145"expires :",
1146"expires : EXPIRES NUMBER",
1147"roa_set_l : prefixset_item SOURCEAS as4number_any expires",
1148"roa_set_l : roa_set_l comma prefixset_item SOURCEAS as4number_any expires",
1149"aspa_set : ASPASET '{' optnl aspa_set_l optnl '}'",
1150"aspa_set : ASPASET '{' optnl '}'",
1151"aspa_set_l : aspa_elm",
1152"aspa_set_l : aspa_set_l comma aspa_elm",
1153"aspa_elm : CUSTOMERAS as4number expires PROVIDERAS '{' optnl aspa_tas_l optnl '}'",
1154"aspa_tas_l : aspa_tas",
1155"aspa_tas_l : aspa_tas_l comma aspa_tas",
1156"aspa_tas : as4number_any",
1157"aspa_tas : as4number_any af",
1158"rtr : RTR address",
1159"$$5 :",
1160"rtr : RTR address $$5 '{' optnl rtropt_l optnl '}'",
1161"rtropt_l : rtropt",
1162"rtropt_l : rtropt_l optnl rtropt",
1163"rtropt : DESCR STRING",
1164"rtropt : LOCALADDR address",
1165"rtropt : PORT port",
1166"conf_main : AS as4number",
1167"conf_main : AS as4number asnumber",
1168"conf_main : ROUTERID address",
1169"conf_main : HOLDTIME NUMBER",
1170"conf_main : HOLDTIME YMIN NUMBER",
1171"conf_main : LISTEN ON address",
1172"conf_main : LISTEN ON address PORT port",
1173"conf_main : FIBPRIORITY NUMBER",
1174"conf_main : FIBUPDATE yesno",
1175"conf_main : TRANSPARENT yesno",
1176"conf_main : REJECT ASSET yesno",
1177"conf_main : LOG STRING",
1178"conf_main : DUMP STRING STRING optnumber",
1179"conf_main : DUMP RIB STRING STRING STRING optnumber",
1180"conf_main : RDE STRING EVALUATE",
1181"conf_main : RDE STRING IGNORE",
1182"conf_main : RDE MED COMPARE STRING",
1183"conf_main : RDE EVALUATE STRING",
1184"conf_main : NEXTHOP QUALIFY VIA STRING",
1185"conf_main : RTABLE NUMBER",
1186"conf_main : CONNECTRETRY NUMBER",
1187"conf_main : SOCKET STRING restricted",
1188"$$6 :",
1189"rib : RDE RIB STRING $$6 ribopts",
1190"ribopts : fibupdate",
1191"ribopts : RTABLE NUMBER fibupdate",
1192"ribopts : yesno EVALUATE",
1193"fibupdate :",
1194"fibupdate : FIBUPDATE yesno",
1195"mrtdump : DUMP STRING inout STRING optnumber",
1196"network : NETWORK prefix filter_set",
1197"network : NETWORK PREFIXSET STRING filter_set",
1198"network : NETWORK af RTLABEL STRING filter_set",
1199"network : NETWORK af PRIORITY NUMBER filter_set",
1200"network : NETWORK af nettype filter_set",
1201"$$7 :",
1202"flowspec : FLOWSPEC af $$7 flow_rules filter_set",
1203"proto : PROTO proto_item",
1204"proto : PROTO '{' optnl proto_list optnl '}'",
1205"proto_list : proto_item",
1206"proto_list : proto_list comma proto_item",
1207"proto_item : STRING",
1208"proto_item : NUMBER",
1209"$$8 :",
1210"from : FROM $$8 ipportspec",
1211"$$9 :",
1212"to : TO $$9 ipportspec",
1213"ipportspec : ipspec",
1214"ipportspec : ipspec PORT portspec",
1215"ipportspec : PORT portspec",
1216"ipspec : ANY",
1217"ipspec : prefix",
1218"portspec : port_item",
1219"portspec : '{' optnl port_list optnl '}'",
1220"port_list : port_item",
1221"port_list : port_list comma port_item",
1222"port_item : port",
1223"port_item : unaryop port",
1224"port_item : port binaryop port",
1225"port : NUMBER",
1226"port : STRING",
1227"flow_rules :",
1228"flow_rules : flow_rules_l",
1229"flow_rules_l : flowrule",
1230"flow_rules_l : flow_rules_l flowrule",
1231"flowrule : from",
1232"flowrule : to",
1233"$$10 :",
1234"flowrule : FLAGS $$10 flags",
1235"$$11 :",
1236"flowrule : FRAGMENT $$11 flags",
1237"flowrule : icmpspec",
1238"flowrule : LENGTH lengthspec",
1239"flowrule : proto",
1240"flowrule : TOS tos",
1241"flags : flag '/' flag",
1242"flags : '/' flag",
1243"flags : flag",
1244"flags : ANY",
1245"flag : STRING",
1246"icmpspec : ICMPTYPE icmp_item",
1247"icmpspec : ICMPTYPE '{' optnl icmp_list optnl '}'",
1248"icmp_list : icmp_item",
1249"icmp_list : icmp_list comma icmp_item",
1250"icmp_item : icmptype",
1251"icmp_item : icmptype CODE STRING",
1252"icmp_item : icmptype CODE NUMBER",
1253"icmptype : STRING",
1254"icmptype : NUMBER",
1255"tos : STRING",
1256"tos : NUMBER",
1257"lengthspec : length_item",
1258"lengthspec : '{' optnl length_list optnl '}'",
1259"length_list : length_item",
1260"length_list : length_list comma length_item",
1261"length_item : length",
1262"length_item : unaryop length",
1263"length_item : length binaryop length",
1264"length : NUMBER",
1265"inout : IN",
1266"inout : OUT",
1267"restricted :",
1268"restricted : RESTRICTED",
1269"address : STRING",
1270"prefix : STRING '/' NUMBER",
1271"prefix : NUMBER '/' NUMBER",
1272"addrspec : address",
1273"addrspec : prefix",
1274"optnumber :",
1275"optnumber : NUMBER",
1276"$$12 :",
1277"l3vpn : VPN STRING ON STRING $$12 '{' l3vpnopts_l '}'",
1278"l3vpnopts_l :",
1279"l3vpnopts_l : l3vpnopts_l '\\n'",
1280"l3vpnopts_l : l3vpnopts_l l3vpnopts '\\n'",
1281"l3vpnopts_l : l3vpnopts_l error '\\n'",
1282"l3vpnopts : RD STRING",
1283"l3vpnopts : EXPORTTRGT STRING STRING",
1284"l3vpnopts : IMPORTTRGT STRING STRING",
1285"l3vpnopts : FIBUPDATE yesno",
1286"l3vpnopts : network",
1287"$$13 :",
1288"$$14 :",
1289"neighbor : $$13 NEIGHBOR addrspec $$14 peeropts_h",
1290"$$15 :",
1291"group : GROUP string $$15 '{' groupopts_l '}'",
1292"groupopts_l :",
1293"groupopts_l : groupopts_l '\\n'",
1294"groupopts_l : groupopts_l peeropts '\\n'",
1295"groupopts_l : groupopts_l neighbor '\\n'",
1296"groupopts_l : groupopts_l error '\\n'",
1297"addpathextra :",
1298"addpathextra : PLUS NUMBER",
1299"addpathmax :",
1300"addpathmax : MAX NUMBER",
1301"peeropts_h : '{' '\\n' peeropts_l '}'",
1302"peeropts_h : '{' peeropts '}'",
1303"peeropts_h :",
1304"peeropts_l :",
1305"peeropts_l : peeropts_l '\\n'",
1306"peeropts_l : peeropts_l peeropts '\\n'",
1307"peeropts_l : peeropts_l error '\\n'",
1308"peeropts : REMOTEAS as4number",
1309"peeropts : LOCALAS as4number",
1310"peeropts : LOCALAS as4number asnumber",
1311"peeropts : DESCR string",
1312"peeropts : LOCALADDR address",
1313"peeropts : yesno LOCALADDR",
1314"peeropts : MULTIHOP NUMBER",
1315"peeropts : PASSIVE",
1316"peeropts : DOWN",
1317"peeropts : DOWN STRING",
1318"peeropts : RIB STRING",
1319"peeropts : HOLDTIME NUMBER",
1320"peeropts : HOLDTIME YMIN NUMBER",
1321"peeropts : ANNOUNCE af safi",
1322"peeropts : ANNOUNCE CAPABILITIES yesno",
1323"peeropts : ANNOUNCE REFRESH yesno",
1324"peeropts : ANNOUNCE ENHANCED REFRESH yesno",
1325"peeropts : ANNOUNCE RESTART yesno",
1326"peeropts : ANNOUNCE AS4BYTE yesno",
1327"peeropts : ANNOUNCE ADDPATH RECV yesno",
1328"peeropts : ANNOUNCE ADDPATH SEND STRING addpathextra addpathmax",
1329"peeropts : ANNOUNCE POLICY enforce",
1330"peeropts : ROLE STRING",
1331"peeropts : ROLE NONE",
1332"peeropts : EXPORT NONE",
1333"peeropts : EXPORT DEFAULTROUTE",
1334"peeropts : ENFORCE NEIGHBORAS yesno",
1335"peeropts : ENFORCE LOCALAS yesno",
1336"peeropts : ASOVERRIDE yesno",
1337"peeropts : MAXPREFIX NUMBER restart",
1338"peeropts : MAXPREFIX NUMBER OUT restart",
1339"peeropts : TCP MD5SIG PASSWORD string",
1340"peeropts : TCP MD5SIG KEY string",
1341"peeropts : IPSEC espah IKE",
1342"peeropts : IPSEC espah inout SPI NUMBER STRING STRING encspec",
1343"peeropts : TTLSECURITY yesno",
1344"peeropts : SET filter_set_opt",
1345"peeropts : SET '{' optnl filter_set_l optnl '}'",
1346"peeropts : mrtdump",
1347"peeropts : REFLECTOR",
1348"peeropts : REFLECTOR address",
1349"peeropts : DEPEND ON STRING",
1350"peeropts : DEMOTE STRING",
1351"peeropts : TRANSPARENT yesno",
1352"peeropts : LOG STRING",
1353"peeropts : REJECT ASSET yesno",
1354"peeropts : PORT port",
1355"peeropts : RDE EVALUATE STRING",
1356"restart :",
1357"restart : RESTART NUMBER",
1358"af : IPV4",
1359"af : IPV6",
1360"safi : NONE",
1361"safi : UNICAST",
1362"safi : VPN",
1363"safi : FLOWSPEC",
1364"nettype : STATIC",
1365"nettype : CONNECTED",
1366"espah : ESP",
1367"espah : AH",
1368"encspec :",
1369"encspec : STRING STRING",
1370"filterrule : action quick filter_rib_h direction filter_peer_h filter_match_h filter_set",
1371"action : ALLOW",
1372"action : DENY",
1373"action : MATCH",
1374"quick :",
1375"quick : QUICK",
1376"direction : FROM",
1377"direction : TO",
1378"filter_rib_h :",
1379"filter_rib_h : RIB filter_rib",
1380"filter_rib_h : RIB '{' optnl filter_rib_l optnl '}'",
1381"filter_rib_l : filter_rib",
1382"filter_rib_l : filter_rib_l comma filter_rib",
1383"filter_rib : STRING",
1384"filter_peer_h : filter_peer",
1385"filter_peer_h : '{' optnl filter_peer_l optnl '}'",
1386"filter_peer_l : filter_peer",
1387"filter_peer_l : filter_peer_l comma filter_peer",
1388"filter_peer : ANY",
1389"filter_peer : address",
1390"filter_peer : AS as4number",
1391"filter_peer : GROUP STRING",
1392"filter_peer : EBGP",
1393"filter_peer : IBGP",
1394"filter_prefix_h : IPV4 prefixlenop",
1395"filter_prefix_h : IPV6 prefixlenop",
1396"filter_prefix_h : PREFIX filter_prefix",
1397"filter_prefix_h : PREFIX '{' filter_prefix_m '}'",
1398"filter_prefix_m : filter_prefix_l",
1399"filter_prefix_m : '{' filter_prefix_l '}'",
1400"filter_prefix_m : '{' filter_prefix_l '}' filter_prefix_m",
1401"filter_prefix_l : filter_prefix",
1402"filter_prefix_l : filter_prefix_l comma filter_prefix",
1403"filter_prefix : prefix prefixlenop",
1404"filter_as_h : filter_as_t",
1405"filter_as_h : '{' filter_as_t_l '}'",
1406"filter_as_t_l : filter_as_t",
1407"filter_as_t_l : filter_as_t_l comma filter_as_t",
1408"filter_as_t : filter_as_type filter_as",
1409"filter_as_t : filter_as_type '{' filter_as_l_h '}'",
1410"filter_as_t : filter_as_type ASSET STRING",
1411"filter_as_l_h : filter_as_l",
1412"filter_as_l_h : '{' filter_as_l '}'",
1413"filter_as_l_h : '{' filter_as_l '}' filter_as_l_h",
1414"filter_as_l : filter_as",
1415"filter_as_l : filter_as_l comma filter_as",
1416"filter_as : as4number_any",
1417"filter_as : NEIGHBORAS",
1418"filter_as : equalityop as4number_any",
1419"filter_as : as4number_any binaryop as4number_any",
1420"filter_match_h :",
1421"$$16 :",
1422"filter_match_h : $$16 filter_match",
1423"filter_match : filter_elm",
1424"filter_match : filter_match filter_elm",
1425"filter_elm : filter_prefix_h",
1426"filter_elm : filter_as_h",
1427"filter_elm : MAXASLEN NUMBER",
1428"filter_elm : MAXASSEQ NUMBER",
1429"filter_elm : community STRING",
1430"filter_elm : EXTCOMMUNITY STRING STRING",
1431"filter_elm : EXTCOMMUNITY OVS STRING",
1432"filter_elm : MAXCOMMUNITIES NUMBER",
1433"filter_elm : MAXEXTCOMMUNITIES NUMBER",
1434"filter_elm : MAXLARGECOMMUNITIES NUMBER",
1435"filter_elm : NEXTHOP address",
1436"filter_elm : NEXTHOP NEIGHBOR",
1437"filter_elm : PREFIXSET STRING prefixlenop",
1438"filter_elm : ORIGINSET STRING",
1439"filter_elm : OVS validity",
1440"filter_elm : AVS aspa_validity",
1441"prefixlenop :",
1442"prefixlenop : LONGER",
1443"prefixlenop : MAXLEN NUMBER",
1444"prefixlenop : PREFIXLEN unaryop NUMBER",
1445"prefixlenop : PREFIXLEN NUMBER binaryop NUMBER",
1446"filter_as_type : AS",
1447"filter_as_type : SOURCEAS",
1448"filter_as_type : TRANSITAS",
1449"filter_as_type : PEERAS",
1450"filter_set :",
1451"filter_set : SET filter_set_opt",
1452"filter_set : SET '{' optnl filter_set_l optnl '}'",
1453"filter_set_l : filter_set_l comma filter_set_opt",
1454"filter_set_l : filter_set_opt",
1455"community : COMMUNITY",
1456"community : LARGECOMMUNITY",
1457"delete :",
1458"delete : DELETE",
1459"enforce : yesno",
1460"enforce : ENFORCE",
1461"filter_set_opt : LOCALPREF NUMBER",
1462"filter_set_opt : LOCALPREF '+' NUMBER",
1463"filter_set_opt : LOCALPREF '-' NUMBER",
1464"filter_set_opt : MED NUMBER",
1465"filter_set_opt : MED '+' NUMBER",
1466"filter_set_opt : MED '-' NUMBER",
1467"filter_set_opt : METRIC NUMBER",
1468"filter_set_opt : METRIC '+' NUMBER",
1469"filter_set_opt : METRIC '-' NUMBER",
1470"filter_set_opt : WEIGHT NUMBER",
1471"filter_set_opt : WEIGHT '+' NUMBER",
1472"filter_set_opt : WEIGHT '-' NUMBER",
1473"filter_set_opt : NEXTHOP address",
1474"filter_set_opt : NEXTHOP BLACKHOLE",
1475"filter_set_opt : NEXTHOP REJECT",
1476"filter_set_opt : NEXTHOP NOMODIFY",
1477"filter_set_opt : NEXTHOP SELF",
1478"filter_set_opt : PREPEND_SELF NUMBER",
1479"filter_set_opt : PREPEND_PEER NUMBER",
1480"filter_set_opt : ASOVERRIDE",
1481"filter_set_opt : PFTABLE STRING",
1482"filter_set_opt : RTLABEL STRING",
1483"filter_set_opt : community delete STRING",
1484"filter_set_opt : EXTCOMMUNITY delete STRING STRING",
1485"filter_set_opt : EXTCOMMUNITY delete OVS STRING",
1486"filter_set_opt : ORIGIN origincode",
1487"origincode : STRING",
1488"validity : STRING",
1489"aspa_validity : STRING",
1490"optnl :",
1491"optnl : '\\n' optnl",
1492"comma :",
1493"comma : ','",
1494"comma : '\\n' optnl",
1495"comma : ',' '\\n' optnl",
1496"unaryop : '='",
1497"unaryop : NE",
1498"unaryop : LE",
1499"unaryop : '<'",
1500"unaryop : GE",
1501"unaryop : '>'",
1502"equalityop : '='",
1503"equalityop : NE",
1504"binaryop : '-'",
1505"binaryop : XRANGE",
1506};
1507#endif
1508#ifdef YYSTACKSIZE10000
1509#undef YYMAXDEPTH10000
1510#define YYMAXDEPTH10000 YYSTACKSIZE10000
1511#else
1512#ifdef YYMAXDEPTH10000
1513#define YYSTACKSIZE10000 YYMAXDEPTH10000
1514#else
1515#define YYSTACKSIZE10000 10000
1516#define YYMAXDEPTH10000 10000
1517#endif
1518#endif
1519#define YYINITSTACKSIZE200 200
1520/* LINTUSED */
1521int yydebug;
1522int yynerrs;
1523int yyerrflag;
1524int yychar;
1525short *yyssp;
1526YYSTYPE *yyvsp;
1527YYSTYPE yyval;
1528YYSTYPE yylval;
1529short *yyss;
1530short *yysslim;
1531YYSTYPE *yyvs;
1532unsigned int yystacksize;
1533int yyparse(void);
1534#line 3463 "/usr/src/usr.sbin/bgpd/parse.y"
1535
1536struct keywords {
1537 const char *k_name;
1538 int k_val;
1539};
1540
1541int
1542yyerror(const char *fmt, ...)
1543{
1544 va_list ap;
1545 char *msg;
1546
1547 file->errors++;
1548 va_start(ap, fmt)__builtin_va_start((ap), fmt);
1549 if (vasprintf(&msg, fmt, ap) == -1)
1550 fatalx("yyerror vasprintf");
1551 va_end(ap)__builtin_va_end((ap));
1552 logit(LOG_CRIT2, "%s:%d: %s", file->name, yylval.lineno, msg);
1553 free(msg);
1554 return (0);
1555}
1556
1557int
1558kw_cmp(const void *k, const void *e)
1559{
1560 return (strcmp(k, ((const struct keywords *)e)->k_name));
1561}
1562
1563int
1564lookup(char *s)
1565{
1566 /* this has to be sorted always */
1567 static const struct keywords keywords[] = {
1568 { "AS", AS257},
1569 { "IPv4", IPV4389},
1570 { "IPv6", IPV6390},
1571 { "add-path", ADDPATH308},
1572 { "ah", AH386},
1573 { "allow", ALLOW333},
1574 { "announce", ANNOUNCE302},
1575 { "any", ANY339},
1576 { "as-4byte", AS4BYTE305 },
1577 { "as-override", ASOVERRIDE317},
1578 { "as-set", ASSET358 },
1579 { "aspa-set", ASPASET352},
1580 { "avs", AVS356},
1581 { "blackhole", BLACKHOLE372},
1582 { "capabilities", CAPABILITIES303},
1583 { "community", COMMUNITY342},
1584 { "compare", COMPARE278},
1585 { "connect-retry", CONNECTRETRY306},
1586 { "connected", CONNECTED340},
1587 { "customer-as", CUSTOMERAS363},
1588 { "default-route", DEFAULTROUTE273},
1589 { "delete", DELETE345},
1590 { "demote", DEMOTE314},
1591 { "deny", DENY334},
1592 { "depend", DEPEND319},
1593 { "descr", DESCR296},
1594 { "down", DOWN320},
1595 { "dump", DUMP321},
1596 { "ebgp", EBGP284},
1597 { "enforce", ENFORCE315},
1598 { "enhanced", ENHANCED307 },
1599 { "esp", ESP385},
1600 { "evaluate", EVALUATE276},
1601 { "expires", EXPIRES357},
1602 { "export", EXPORT270},
1603 { "export-target", EXPORTTRGT271},
1604 { "ext-community", EXTCOMMUNITY343},
1605 { "fib-priority", FIBPRIORITY264},
1606 { "fib-update", FIBUPDATE263},
1607 { "flags", FLAGS288},
1608 { "flowspec", FLOWSPEC286},
1609 { "fragment", FRAGMENT289},
1610 { "from", FROM337},
1611 { "group", GROUP281},
1612 { "holdtime", HOLDTIME259},
1613 { "ibgp", IBGP285},
1614 { "ignore", IGNORE277},
1615 { "ike", IKE388},
1616 { "import-target", IMPORTTRGT272},
1617 { "in", IN322},
1618 { "include", INCLUDE383},
1619 { "inet", IPV4389},
1620 { "inet6", IPV6390},
1621 { "ipsec", IPSEC384},
1622 { "key", KEY331},
1623 { "large-community", LARGECOMMUNITY344},
1624 { "listen", LISTEN261},
1625 { "local-address", LOCALADDR297},
1626 { "local-as", LOCALAS294},
1627 { "localpref", LOCALPREF367},
1628 { "log", LOG326},
1629 { "match", MATCH335},
1630 { "max", MAX399},
1631 { "max-as-len", MAXASLEN364},
1632 { "max-as-seq", MAXASSEQ365},
1633 { "max-communities", MAXCOMMUNITIES346},
1634 { "max-ext-communities", MAXEXTCOMMUNITIES347},
1635 { "max-large-communities", MAXLARGECOMMUNITIES348},
1636 { "max-prefix", MAXPREFIX300},
1637 { "maxlen", MAXLEN398},
1638 { "md5sig", MD5SIG329},
1639 { "med", MED368},
1640 { "metric", METRIC369},
1641 { "min", YMIN260},
1642 { "multihop", MULTIHOP298},
1643 { "neighbor", NEIGHBOR282},
1644 { "neighbor-as", NEIGHBORAS316},
1645 { "network", NETWORK283},
1646 { "nexthop", NEXTHOP370},
1647 { "no-modify", NOMODIFY373},
1648 { "none", NONE266},
1649 { "on", ON262},
1650 { "or-longer", LONGER397},
1651 { "origin", ORIGIN380},
1652 { "origin-set", ORIGINSET354},
1653 { "out", OUT323},
1654 { "ovs", OVS355},
1655 { "passive", PASSIVE299},
1656 { "password", PASSWORD330},
1657 { "peer-as", PEERAS361},
1658 { "pftable", PFTABLE377},
1659 { "plus", PLUS311},
1660 { "policy", POLICY312},
1661 { "port", PORT280},
1662 { "prefix", PREFIX349},
1663 { "prefix-set", PREFIXSET351},
1664 { "prefixlen", PREFIXLEN350},
1665 { "prepend-neighbor", PREPEND_PEER376},
1666 { "prepend-self", PREPEND_SELF375},
1667 { "priority", PRIORITY381},
1668 { "proto", PROTO287},
1669 { "provider-as", PROVIDERAS362},
1670 { "qualify", QUALIFY391},
1671 { "quick", QUICK336},
1672 { "rd", RD269},
1673 { "rde", RDE274},
1674 { "recv", RECV310},
1675 { "refresh", REFRESH304 },
1676 { "reject", REJECT371},
1677 { "remote-as", REMOTEAS295},
1678 { "restart", RESTART301},
1679 { "restricted", RESTRICTED325},
1680 { "rib", RIB275},
1681 { "roa-set", ROASET353 },
1682 { "role", ROLE313},
1683 { "route-reflector", REFLECTOR318},
1684 { "router-id", ROUTERID258},
1685 { "rtable", RTABLE265},
1686 { "rtlabel", RTLABEL379},
1687 { "rtr", RTR279},
1688 { "self", SELF374},
1689 { "send", SEND309},
1690 { "set", SET366},
1691 { "socket", SOCKET324 },
1692 { "source-as", SOURCEAS359},
1693 { "spi", SPI387},
1694 { "static", STATIC341},
1695 { "tcp", TCP328},
1696 { "to", TO338},
1697 { "tos", TOS290},
1698 { "transit-as", TRANSITAS360},
1699 { "transparent-as", TRANSPARENT327},
1700 { "ttl-security", TTLSECURITY332},
1701 { "unicast", UNICAST267},
1702 { "via", VIA392},
1703 { "vpn", VPN268},
1704 { "weight", WEIGHT378}
1705 };
1706 const struct keywords *p;
1707
1708 p = bsearch(s, keywords, nitems(keywords)(sizeof((keywords)) / sizeof((keywords)[0])), sizeof(keywords[0]), kw_cmp);
1709
1710 if (p)
1711 return (p->k_val);
1712 else
1713 return (STRING400);
1714}
1715
1716#define START_EXPAND1 1
1717#define DONE_EXPAND2 2
1718
1719static int expanding;
1720
1721int
1722igetc(void)
1723{
1724 int c;
1725
1726 while (1) {
1727 if (file->ungetpos > 0)
1728 c = file->ungetbuf[--file->ungetpos];
1729 else
1730 c = getc(file->stream)(!__isthreaded ? (--(file->stream)->_r < 0 ? __srget
(file->stream) : (int)(*(file->stream)->_p++)) : (getc
)(file->stream))
;
1731
1732 if (c == START_EXPAND1)
1733 expanding = 1;
1734 else if (c == DONE_EXPAND2)
1735 expanding = 0;
1736 else
1737 break;
1738 }
1739 return (c);
1740}
1741
1742int
1743lgetc(int quotec)
1744{
1745 int c, next;
1746
1747 if (quotec) {
1748 if ((c = igetc()) == EOF(-1)) {
1749 yyerror("reached end of file while parsing "
1750 "quoted string");
1751 if (file == topfile || popfile() == EOF(-1))
1752 return (EOF(-1));
1753 return (quotec);
1754 }
1755 return (c);
1756 }
1757
1758 while ((c = igetc()) == '\\') {
1759 next = igetc();
1760 if (next != '\n') {
1761 c = next;
1762 break;
1763 }
1764 yylval.lineno = file->lineno;
1765 file->lineno++;
1766 }
1767
1768 if (c == EOF(-1)) {
1769 /*
1770 * Fake EOL when hit EOF for the first time. This gets line
1771 * count right if last line in included file is syntactically
1772 * invalid and has no newline.
1773 */
1774 if (file->eof_reached == 0) {
1775 file->eof_reached = 1;
1776 return ('\n');
1777 }
1778 while (c == EOF(-1)) {
1779 if (file == topfile || popfile() == EOF(-1))
1780 return (EOF(-1));
1781 c = igetc();
1782 }
1783 }
1784 return (c);
1785}
1786
1787void
1788lungetc(int c)
1789{
1790 if (c == EOF(-1))
1791 return;
1792
1793 if (file->ungetpos >= file->ungetsize) {
1794 void *p = reallocarray(file->ungetbuf, file->ungetsize, 2);
1795 if (p == NULL((void *)0))
1796 err(1, "lungetc");
1797 file->ungetbuf = p;
1798 file->ungetsize *= 2;
1799 }
1800 file->ungetbuf[file->ungetpos++] = c;
1801}
1802
1803int
1804findeol(void)
1805{
1806 int c;
1807
1808 /* skip to either EOF or the first real EOL */
1809 while (1) {
1810 c = lgetc(0);
1811 if (c == '\n') {
1812 file->lineno++;
1813 break;
1814 }
1815 if (c == EOF(-1))
1816 break;
1817 }
1818 return (ERROR382);
1819}
1820
1821int
1822expand_macro(void)
1823{
1824 char buf[MACRO_NAME_LEN128];
1825 char *p, *val;
1826 int c;
1827
1828 p = buf;
1829 while (1) {
1830 if ((c = lgetc('$')) == EOF(-1))
1831 return (ERROR382);
1832 if (p + 1 >= buf + sizeof(buf) - 1) {
1833 yyerror("macro name too long");
1834 return (ERROR382);
1835 }
1836 if (isalnum(c) || c == '_') {
1837 *p++ = c;
1838 continue;
1839 }
1840 *p = '\0';
1841 lungetc(c);
1842 break;
1843 }
1844 val = symget(buf);
1845 if (val == NULL((void *)0)) {
1846 yyerror("macro '%s' not defined", buf);
1847 return (ERROR382);
1848 }
1849 p = val + strlen(val) - 1;
1850 lungetc(DONE_EXPAND2);
1851 while (p >= val) {
1852 lungetc((unsigned char)*p);
1853 p--;
1854 }
1855 lungetc(START_EXPAND1);
1856 return (0);
1857}
1858
1859int
1860yylex(void)
1861{
1862 char buf[8096];
1863 char *p;
1864 int quotec, next, c;
1865 int token;
1866
1867top:
1868 p = buf;
1869 while ((c = lgetc(0)) == ' ' || c == '\t')
1870 ; /* nothing */
1871
1872 yylval.lineno = file->lineno;
1873 if (c == '#')
1874 while ((c = lgetc(0)) != '\n' && c != EOF(-1))
1875 ; /* nothing */
1876 if (c == '$' && !expanding) {
1877 c = expand_macro();
1878 if (c != 0)
1879 return (c);
1880 goto top;
1881 }
1882
1883 switch (c) {
1884 case '\'':
1885 case '"':
1886 quotec = c;
1887 while (1) {
1888 if ((c = lgetc(quotec)) == EOF(-1))
1889 return (0);
1890 if (c == '\n') {
1891 file->lineno++;
1892 continue;
1893 } else if (c == '\\') {
1894 if ((next = lgetc(quotec)) == EOF(-1))
1895 return (0);
1896 if (next == quotec || next == ' ' ||
1897 next == '\t')
1898 c = next;
1899 else if (next == '\n') {
1900 file->lineno++;
1901 continue;
1902 } else
1903 lungetc(next);
1904 } else if (c == quotec) {
1905 *p = '\0';
1906 break;
1907 } else if (c == '\0') {
1908 yyerror("syntax error: unterminated quote");
1909 return (findeol());
1910 }
1911 if (p + 1 >= buf + sizeof(buf) - 1) {
1912 yyerror("string too long");
1913 return (findeol());
1914 }
1915 *p++ = c;
1916 }
1917 yylval.v.string = strdup(buf);
1918 if (yylval.v.string == NULL((void *)0))
1919 fatal("yylex: strdup");
1920 return (STRING400);
1921 case '!':
1922 next = lgetc(0);
1923 if (next == '=')
1924 return (NE393);
1925 lungetc(next);
1926 break;
1927 case '<':
1928 next = lgetc(0);
1929 if (next == '=')
1930 return (LE394);
1931 lungetc(next);
1932 break;
1933 case '>':
1934 next = lgetc(0);
1935 if (next == '<')
1936 return (XRANGE396);
1937 else if (next == '=')
1938 return (GE395);
1939 lungetc(next);
1940 break;
1941 }
1942
1943#define allowed_to_end_number(x)(isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' ||
x == '=')
\
1944 (isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' || x == '=')
1945
1946 if (c == '-' || isdigit(c)) {
1947 do {
1948 *p++ = c;
1949 if ((size_t)(p-buf) >= sizeof(buf)) {
1950 yyerror("string too long");
1951 return (findeol());
1952 }
1953 } while ((c = lgetc(0)) != EOF(-1) && isdigit(c));
1954 lungetc(c);
1955 if (p == buf + 1 && buf[0] == '-')
1956 goto nodigits;
1957 if (c == EOF(-1) || allowed_to_end_number(c)(isspace(c) || c == ')' || c ==',' || c == '/' || c == '}' ||
c == '=')
) {
1958 const char *errstr = NULL((void *)0);
1959
1960 *p = '\0';
1961 yylval.v.number = strtonum(buf, LLONG_MIN(-0x7fffffffffffffffLL-1),
1962 LLONG_MAX0x7fffffffffffffffLL, &errstr);
1963 if (errstr) {
1964 yyerror("\"%s\" invalid number: %s",
1965 buf, errstr);
1966 return (findeol());
1967 }
1968 return (NUMBER401);
1969 } else {
1970nodigits:
1971 while (p > buf + 1)
1972 lungetc((unsigned char)*--p);
1973 c = (unsigned char)*--p;
1974 if (c == '-')
1975 return (c);
1976 }
1977 }
1978
1979#define allowed_in_string(x)(isalnum(x) || (ispunct(x) && x != '(' && x !=
')' && x != '{' && x != '}' && x != '<'
&& x != '>' && x != '!' && x != '='
&& x != '/' && x != '#' && x != ',')
)
\
1980 (isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \
1981 x != '{' && x != '}' && x != '<' && x != '>' && \
1982 x != '!' && x != '=' && x != '/' && x != '#' && \
1983 x != ','))
1984
1985 if (isalnum(c) || c == ':' || c == '_' || c == '*') {
1986 do {
1987 if (c == '$' && !expanding) {
1988 c = expand_macro();
1989 if (c != 0)
1990 return (c);
1991 } else
1992 *p++ = c;
1993
1994 if ((size_t)(p-buf) >= sizeof(buf)) {
1995 yyerror("string too long");
1996 return (findeol());
1997 }
1998 } while ((c = lgetc(0)) != EOF(-1) && (allowed_in_string(c)(isalnum(c) || (ispunct(c) && c != '(' && c !=
')' && c != '{' && c != '}' && c != '<'
&& c != '>' && c != '!' && c != '='
&& c != '/' && c != '#' && c != ',')
)
));
1999 lungetc(c);
2000 *p = '\0';
2001 if ((token = lookup(buf)) == STRING400)
2002 if ((yylval.v.string = strdup(buf)) == NULL((void *)0))
2003 fatal("yylex: strdup");
2004 return (token);
2005 }
2006 if (c == '\n') {
2007 yylval.lineno = file->lineno;
2008 file->lineno++;
2009 }
2010 if (c == EOF(-1))
2011 return (0);
2012 return (c);
2013}
2014
2015int
2016check_file_secrecy(int fd, const char *fname)
2017{
2018 struct stat st;
2019
2020 if (fstat(fd, &st)) {
2021 log_warn("cannot stat %s", fname);
2022 return (-1);
2023 }
2024 return (0);
2025}
2026
2027struct file *
2028pushfile(const char *name, int secret)
2029{
2030 struct file *nfile;
2031
2032 if ((nfile = calloc(1, sizeof(struct file))) == NULL((void *)0)) {
2033 log_warn("%s", __func__);
2034 return (NULL((void *)0));
2035 }
2036 if ((nfile->name = strdup(name)) == NULL((void *)0)) {
2037 log_warn("%s", __func__);
2038 free(nfile);
2039 return (NULL((void *)0));
2040 }
2041 if ((nfile->stream = fopen(nfile->name, "r")) == NULL((void *)0)) {
2042 log_warn("%s: %s", __func__, nfile->name);
2043 free(nfile->name);
2044 free(nfile);
2045 return (NULL((void *)0));
2046 }
2047 if (secret &&
2048 check_file_secrecy(fileno(nfile->stream)(!__isthreaded ? ((nfile->stream)->_file) : (fileno)(nfile
->stream))
, nfile->name)) {
2049 fclose(nfile->stream);
2050 free(nfile->name);
2051 free(nfile);
2052 return (NULL((void *)0));
2053 }
2054 nfile->lineno = TAILQ_EMPTY(&files)(((&files)->tqh_first) == ((void *)0)) ? 1 : 0;
2055 nfile->ungetsize = 16;
2056 nfile->ungetbuf = malloc(nfile->ungetsize);
2057 if (nfile->ungetbuf == NULL((void *)0)) {
2058 log_warn("%s", __func__);
2059 fclose(nfile->stream);
2060 free(nfile->name);
2061 free(nfile);
2062 return (NULL((void *)0));
2063 }
2064 TAILQ_INSERT_TAIL(&files, nfile, entry)do { (nfile)->entry.tqe_next = ((void *)0); (nfile)->entry
.tqe_prev = (&files)->tqh_last; *(&files)->tqh_last
= (nfile); (&files)->tqh_last = &(nfile)->entry
.tqe_next; } while (0)
;
2065 return (nfile);
2066}
2067
2068int
2069popfile(void)
2070{
2071 struct file *prev;
2072
2073 if ((prev = TAILQ_PREV(file, files, entry)(*(((struct files *)((file)->entry.tqe_prev))->tqh_last
))
) != NULL((void *)0))
2074 prev->errors += file->errors;
2075
2076 TAILQ_REMOVE(&files, file, entry)do { if (((file)->entry.tqe_next) != ((void *)0)) (file)->
entry.tqe_next->entry.tqe_prev = (file)->entry.tqe_prev
; else (&files)->tqh_last = (file)->entry.tqe_prev;
*(file)->entry.tqe_prev = (file)->entry.tqe_next; ; ; }
while (0)
;
2077 fclose(file->stream);
2078 free(file->name);
2079 free(file->ungetbuf);
2080 free(file);
2081 file = prev;
2082 return (file ? 0 : EOF(-1));
2083}
2084
2085static void
2086init_config(struct bgpd_config *c)
2087{
2088 u_int rdomid;
2089
2090 c->min_holdtime = MIN_HOLDTIME3;
2091 c->holdtime = INTERVAL_HOLD90;
2092 c->connectretry = INTERVAL_CONNECTRETRY120;
2093 c->bgpid = get_bgpid();
2094 c->fib_priority = kr_default_prio();
2095 c->default_tableid = getrtable();
2096 if (!ktable_exists(c->default_tableid, &rdomid))
2097 fatalx("current routing table %u does not exist",
2098 c->default_tableid);
2099 if (rdomid != c->default_tableid)
2100 fatalx("current routing table %u is not a routing domain",
2101 c->default_tableid);
2102
2103 if (asprintf(&c->csock, "%s.%d", SOCKET_NAME"/var/run/bgpd.sock", c->default_tableid) == -1)
2104 fatal(NULL((void *)0));
2105}
2106
2107struct bgpd_config *
2108parse_config(char *filename, struct peer_head *ph, struct rtr_config_head *rh)
2109{
2110 struct sym *sym, *next;
2111 struct rde_rib *rr;
2112 struct network *n;
2113 int errors = 0;
2114
2115 conf = new_config();
2116 init_config(conf);
2117
2118 if ((filter_l = calloc(1, sizeof(struct filter_head))) == NULL((void *)0))
1
Assuming the condition is false
2
Taking false branch
2119 fatal(NULL((void *)0));
2120 if ((peerfilter_l = calloc(1, sizeof(struct filter_head))) == NULL((void *)0))
3
Assuming the condition is false
4
Taking false branch
2121 fatal(NULL((void *)0));
2122 if ((groupfilter_l = calloc(1, sizeof(struct filter_head))) == NULL((void *)0))
5
Assuming the condition is false
6
Taking false branch
2123 fatal(NULL((void *)0));
2124 TAILQ_INIT(filter_l)do { (filter_l)->tqh_first = ((void *)0); (filter_l)->tqh_last
= &(filter_l)->tqh_first; } while (0)
;
7
Loop condition is false. Exiting loop
2125 TAILQ_INIT(peerfilter_l)do { (peerfilter_l)->tqh_first = ((void *)0); (peerfilter_l
)->tqh_last = &(peerfilter_l)->tqh_first; } while (
0)
;
8
Loop condition is false. Exiting loop
2126 TAILQ_INIT(groupfilter_l)do { (groupfilter_l)->tqh_first = ((void *)0); (groupfilter_l
)->tqh_last = &(groupfilter_l)->tqh_first; } while (
0)
;
9
Loop condition is false. Exiting loop
2127
2128 curpeer = NULL((void *)0);
2129 curgroup = NULL((void *)0);
2130
2131 cur_peers = ph;
2132 cur_rtrs = rh;
2133 new_peers = &conf->peers;
2134 netconf = &conf->networks;
2135
2136 if ((rr = add_rib("Adj-RIB-In")) == NULL((void *)0))
10
Taking false branch
2137 fatal("add_rib failed");
2138 rr->flags = F_RIB_NOFIB0x0004 | F_RIB_NOEVALUATE0x0002;
2139 if ((rr = add_rib("Loc-RIB")) == NULL((void *)0))
11
Taking false branch
2140 fatal("add_rib failed");
2141 rib_add_fib(rr, conf->default_tableid);
2142 rr->flags = F_RIB_LOCAL0x0001;
2143
2144 if ((file = pushfile(filename, 1)) == NULL((void *)0))
12
Taking false branch
2145 goto errors;
2146 topfile = file;
2147
2148 yyparse();
2149 errors = file->errors;
2150 popfile();
2151
2152 /* check that we dont try to announce our own routes */
2153 TAILQ_FOREACH(n, netconf, entry)for((n) = ((netconf)->tqh_first); (n) != ((void *)0); (n) =
((n)->entry.tqe_next))
13
Assuming 'n' is equal to null
14
Loop condition is false. Execution continues on line 2162
2154 if (n->net.priority == conf->fib_priority) {
2155 errors++;
2156 logit(LOG_CRIT2, "network priority %d == fib-priority "
2157 "%d is not allowed.",
2158 n->net.priority, conf->fib_priority);
2159 }
2160
2161 /* Free macros and check which have not been used. */
2162 TAILQ_FOREACH_SAFE(sym, &symhead, entry, next)for ((sym) = ((&symhead)->tqh_first); (sym) != ((void *
)0) && ((next) = ((sym)->entry.tqe_next), 1); (sym
) = (next))
{
15
Assuming 'sym' is equal to null
2163 if ((cmd_opts & BGPD_OPT_VERBOSE20x0002) && !sym->used)
2164 fprintf(stderr(&__sF[2]), "warning: macro \"%s\" not "
2165 "used\n", sym->nam);
2166 if (!sym->persist) {
2167 free(sym->nam);
2168 free(sym->val);
2169 TAILQ_REMOVE(&symhead, sym, entry)do { if (((sym)->entry.tqe_next) != ((void *)0)) (sym)->
entry.tqe_next->entry.tqe_prev = (sym)->entry.tqe_prev;
else (&symhead)->tqh_last = (sym)->entry.tqe_prev;
*(sym)->entry.tqe_prev = (sym)->entry.tqe_next; ; ; } while
(0)
;
2170 free(sym);
2171 }
2172 }
2173
2174 if (!conf->as) {
16
Assuming field 'as' is not equal to 0
17
Taking false branch
2175 log_warnx("configuration error: AS not given");
2176 errors++;
2177 }
2178
2179 /* clear the globals */
2180 curpeer = NULL((void *)0);
2181 curgroup = NULL((void *)0);
2182 cur_peers = NULL((void *)0);
2183 new_peers = NULL((void *)0);
2184 netconf = NULL((void *)0);
2185 curflow = NULL((void *)0);
2186
2187 if (errors) {
18
Assuming 'errors' is 0
19
Taking false branch
2188errors:
2189 while ((rr = SIMPLEQ_FIRST(&ribnames)((&ribnames)->sqh_first)) != NULL((void *)0)) {
2190 SIMPLEQ_REMOVE_HEAD(&ribnames, entry)do { if (((&ribnames)->sqh_first = (&ribnames)->
sqh_first->entry.sqe_next) == ((void *)0)) (&ribnames)
->sqh_last = &(&ribnames)->sqh_first; } while (
0)
;
2191 free(rr);
2192 }
2193
2194 filterlist_free(filter_l);
2195 filterlist_free(peerfilter_l);
2196 filterlist_free(groupfilter_l);
2197
2198 free_config(conf);
2199 return (NULL((void *)0));
2200 }
2201
2202 /* Create default listeners if none where specified. */
2203 if (TAILQ_EMPTY(conf->listen_addrs)(((conf->listen_addrs)->tqh_first) == ((void *)0))) {
20
Assuming field 'tqh_first' is not equal to null
2204 struct listen_addr *la;
2205
2206 if ((la = calloc(1, sizeof(struct listen_addr))) == NULL((void *)0))
2207 fatal("setup_listeners calloc");
2208 la->fd = -1;
2209 la->flags = DEFAULT_LISTENER0x01;
2210 la->reconf = RECONF_REINIT;
2211 la->sa_len = sizeof(struct sockaddr_in);
2212 ((struct sockaddr_in *)&la->sa)->sin_family = AF_INET2;
2213 ((struct sockaddr_in *)&la->sa)->sin_addr.s_addr =
2214 htonl(INADDR_ANY)(__uint32_t)(__builtin_constant_p(((u_int32_t)(0x00000000))) ?
(__uint32_t)(((__uint32_t)(((u_int32_t)(0x00000000))) & 0xff
) << 24 | ((__uint32_t)(((u_int32_t)(0x00000000))) &
0xff00) << 8 | ((__uint32_t)(((u_int32_t)(0x00000000))
) & 0xff0000) >> 8 | ((__uint32_t)(((u_int32_t)(0x00000000
))) & 0xff000000) >> 24) : __swap32md(((u_int32_t)(
0x00000000))))
;
2215 ((struct sockaddr_in *)&la->sa)->sin_port = htons(BGP_PORT)(__uint16_t)(__builtin_constant_p(179) ? (__uint16_t)(((__uint16_t
)(179) & 0xffU) << 8 | ((__uint16_t)(179) & 0xff00U
) >> 8) : __swap16md(179))
;
2216 TAILQ_INSERT_TAIL(conf->listen_addrs, la, entry)do { (la)->entry.tqe_next = ((void *)0); (la)->entry.tqe_prev
= (conf->listen_addrs)->tqh_last; *(conf->listen_addrs
)->tqh_last = (la); (conf->listen_addrs)->tqh_last =
&(la)->entry.tqe_next; } while (0)
;
2217
2218 if ((la = calloc(1, sizeof(struct listen_addr))) == NULL((void *)0))
2219 fatal("setup_listeners calloc");
2220 la->fd = -1;
2221 la->flags = DEFAULT_LISTENER0x01;
2222 la->reconf = RECONF_REINIT;
2223 la->sa_len = sizeof(struct sockaddr_in6);
2224 ((struct sockaddr_in6 *)&la->sa)->sin6_family = AF_INET624;
2225 ((struct sockaddr_in6 *)&la->sa)->sin6_port = htons(BGP_PORT)(__uint16_t)(__builtin_constant_p(179) ? (__uint16_t)(((__uint16_t
)(179) & 0xffU) << 8 | ((__uint16_t)(179) & 0xff00U
) >> 8) : __swap16md(179))
;
2226 TAILQ_INSERT_TAIL(conf->listen_addrs, la, entry)do { (la)->entry.tqe_next = ((void *)0); (la)->entry.tqe_prev
= (conf->listen_addrs)->tqh_last; *(conf->listen_addrs
)->tqh_last = (la); (conf->listen_addrs)->tqh_last =
&(la)->entry.tqe_next; } while (0)
;
2227 }
2228
2229 /* update clusterid in case it was not set explicitly */
2230 if ((conf->flags & BGPD_FLAG_REFLECTOR0x0004) && conf->clusterid == 0)
21
Assuming the condition is false
2231 conf->clusterid = conf->bgpid;
2232
2233 /*
2234 * Concatenate filter list and static group and peer filtersets
2235 * together. Static group sets come first then peer sets
2236 * last normal filter rules.
2237 */
2238 TAILQ_CONCAT(conf->filters, groupfilter_l, entry)do { if (!(((groupfilter_l)->tqh_first) == ((void *)0))) {
*(conf->filters)->tqh_last = (groupfilter_l)->tqh_first
; (groupfilter_l)->tqh_first->entry.tqe_prev = (conf->
filters)->tqh_last; (conf->filters)->tqh_last = (groupfilter_l
)->tqh_last; do { ((groupfilter_l))->tqh_first = ((void
*)0); ((groupfilter_l))->tqh_last = &((groupfilter_l)
)->tqh_first; } while (0); } } while (0)
;
22
Assuming field 'tqh_first' is equal to null
23
Taking false branch
24
Loop condition is false. Exiting loop
2239 TAILQ_CONCAT(conf->filters, peerfilter_l, entry)do { if (!(((peerfilter_l)->tqh_first) == ((void *)0))) { *
(conf->filters)->tqh_last = (peerfilter_l)->tqh_first
; (peerfilter_l)->tqh_first->entry.tqe_prev = (conf->
filters)->tqh_last; (conf->filters)->tqh_last = (peerfilter_l
)->tqh_last; do { ((peerfilter_l))->tqh_first = ((void *
)0); ((peerfilter_l))->tqh_last = &((peerfilter_l))->
tqh_first; } while (0); } } while (0)
;
25
Assuming field 'tqh_first' is equal to null
26
Taking false branch
27
Loop condition is false. Exiting loop
2240 TAILQ_CONCAT(conf->filters, filter_l, entry)do { if (!(((filter_l)->tqh_first) == ((void *)0))) { *(conf
->filters)->tqh_last = (filter_l)->tqh_first; (filter_l
)->tqh_first->entry.tqe_prev = (conf->filters)->tqh_last
; (conf->filters)->tqh_last = (filter_l)->tqh_last; do
{ ((filter_l))->tqh_first = ((void *)0); ((filter_l))->
tqh_last = &((filter_l))->tqh_first; } while (0); } } while
(0)
;
28
Assuming field 'tqh_first' is equal to null
29
Taking false branch
30
Loop condition is false. Exiting loop
2241
2242 optimize_filters(conf->filters);
31
Calling 'optimize_filters'
2243
2244 free(filter_l);
2245 free(peerfilter_l);
2246 free(groupfilter_l);
2247
2248 return (conf);
2249}
2250
2251int
2252symset(const char *nam, const char *val, int persist)
2253{
2254 struct sym *sym;
2255
2256 TAILQ_FOREACH(sym, &symhead, entry)for((sym) = ((&symhead)->tqh_first); (sym) != ((void *
)0); (sym) = ((sym)->entry.tqe_next))
{
2257 if (strcmp(nam, sym->nam) == 0)
2258 break;
2259 }
2260
2261 if (sym != NULL((void *)0)) {
2262 if (sym->persist == 1)
2263 return (0);
2264 else {
2265 free(sym->nam);
2266 free(sym->val);
2267 TAILQ_REMOVE(&symhead, sym, entry)do { if (((sym)->entry.tqe_next) != ((void *)0)) (sym)->
entry.tqe_next->entry.tqe_prev = (sym)->entry.tqe_prev;
else (&symhead)->tqh_last = (sym)->entry.tqe_prev;
*(sym)->entry.tqe_prev = (sym)->entry.tqe_next; ; ; } while
(0)
;
2268 free(sym);
2269 }
2270 }
2271 if ((sym = calloc(1, sizeof(*sym))) == NULL((void *)0))
2272 return (-1);
2273
2274 sym->nam = strdup(nam);
2275 if (sym->nam == NULL((void *)0)) {
2276 free(sym);
2277 return (-1);
2278 }
2279 sym->val = strdup(val);
2280 if (sym->val == NULL((void *)0)) {
2281 free(sym->nam);
2282 free(sym);
2283 return (-1);
2284 }
2285 sym->used = 0;
2286 sym->persist = persist;
2287 TAILQ_INSERT_TAIL(&symhead, sym, entry)do { (sym)->entry.tqe_next = ((void *)0); (sym)->entry.
tqe_prev = (&symhead)->tqh_last; *(&symhead)->tqh_last
= (sym); (&symhead)->tqh_last = &(sym)->entry.
tqe_next; } while (0)
;
2288 return (0);
2289}
2290
2291int
2292cmdline_symset(char *s)
2293{
2294 char *sym, *val;
2295 int ret;
2296
2297 if ((val = strrchr(s, '=')) == NULL((void *)0))
2298 return (-1);
2299 sym = strndup(s, val - s);
2300 if (sym == NULL((void *)0))
2301 fatal("%s: strndup", __func__);
2302 ret = symset(sym, val + 1, 1);
2303 free(sym);
2304
2305 return (ret);
2306}
2307
2308char *
2309symget(const char *nam)
2310{
2311 struct sym *sym;
2312
2313 TAILQ_FOREACH(sym, &symhead, entry)for((sym) = ((&symhead)->tqh_first); (sym) != ((void *
)0); (sym) = ((sym)->entry.tqe_next))
{
2314 if (strcmp(nam, sym->nam) == 0) {
2315 sym->used = 1;
2316 return (sym->val);
2317 }
2318 }
2319 return (NULL((void *)0));
2320}
2321
2322static int
2323cmpcommunity(struct community *a, struct community *b)
2324{
2325 if (a->flags > b->flags)
2326 return 1;
2327 if (a->flags < b->flags)
2328 return -1;
2329 if (a->data1 > b->data1)
2330 return 1;
2331 if (a->data1 < b->data1)
2332 return -1;
2333 if (a->data2 > b->data2)
2334 return 1;
2335 if (a->data2 < b->data2)
2336 return -1;
2337 if (a->data3 > b->data3)
2338 return 1;
2339 if (a->data3 < b->data3)
2340 return -1;
2341 return 0;
2342}
2343
2344static int
2345getcommunity(char *s, int large, uint32_t *val, uint32_t *flag)
2346{
2347 long long max = USHRT_MAX0xffff;
2348 const char *errstr;
2349
2350 *flag = 0;
2351 *val = 0;
2352 if (strcmp(s, "*") == 0) {
2353 *flag = COMMUNITY_ANY1;
2354 return 0;
2355 } else if (strcmp(s, "neighbor-as") == 0) {
2356 *flag = COMMUNITY_NEIGHBOR_AS2;
2357 return 0;
2358 } else if (strcmp(s, "local-as") == 0) {
2359 *flag = COMMUNITY_LOCAL_AS3;
2360 return 0;
2361 }
2362 if (large)
2363 max = UINT_MAX0xffffffffU;
2364 *val = strtonum(s, 0, max, &errstr);
2365 if (errstr) {
2366 yyerror("Community %s is %s (max: %lld)", s, errstr, max);
2367 return -1;
2368 }
2369 return 0;
2370}
2371
2372static void
2373setcommunity(struct community *c, uint32_t as, uint32_t data,
2374 uint32_t asflag, uint32_t dataflag)
2375{
2376 c->flags = COMMUNITY_TYPE_BASIC8;
2377 c->flags |= asflag << 8;
2378 c->flags |= dataflag << 16;
2379 c->data1 = as;
2380 c->data2 = data;
2381 c->data3 = 0;
2382}
2383
2384static int
2385parselargecommunity(struct community *c, char *s)
2386{
2387 char *p, *q;
2388 uint32_t dflag1, dflag2, dflag3;
2389
2390 if ((p = strchr(s, ':')) == NULL((void *)0)) {
2391 yyerror("Bad community syntax");
2392 return (-1);
2393 }
2394 *p++ = 0;
2395
2396 if ((q = strchr(p, ':')) == NULL((void *)0)) {
2397 yyerror("Bad community syntax");
2398 return (-1);
2399 }
2400 *q++ = 0;
2401
2402 if (getcommunity(s, 1, &c->data1, &dflag1) == -1 ||
2403 getcommunity(p, 1, &c->data2, &dflag2) == -1 ||
2404 getcommunity(q, 1, &c->data3, &dflag3) == -1)
2405 return (-1);
2406 c->flags = COMMUNITY_TYPE_LARGE32;
2407 c->flags |= dflag1 << 8;;
2408 c->flags |= dflag2 << 16;;
2409 c->flags |= dflag3 << 24;;
2410 return (0);
2411}
2412
2413int
2414parsecommunity(struct community *c, int type, char *s)
2415{
2416 char *p;
2417 uint32_t as, data, asflag, dataflag;
2418
2419 if (type == COMMUNITY_TYPE_LARGE32)
2420 return parselargecommunity(c, s);
2421
2422 /* Well-known communities */
2423 if (strcasecmp(s, "GRACEFUL_SHUTDOWN") == 0) {
2424 setcommunity(c, COMMUNITY_WELLKNOWN0xffff,
2425 COMMUNITY_GRACEFUL_SHUTDOWN0x0000, 0, 0);
2426 return (0);
2427 } else if (strcasecmp(s, "NO_EXPORT") == 0) {
2428 setcommunity(c, COMMUNITY_WELLKNOWN0xffff,
2429 COMMUNITY_NO_EXPORT0xff01, 0, 0);
2430 return (0);
2431 } else if (strcasecmp(s, "NO_ADVERTISE") == 0) {
2432 setcommunity(c, COMMUNITY_WELLKNOWN0xffff,
2433 COMMUNITY_NO_ADVERTISE0xff02, 0, 0);
2434 return (0);
2435 } else if (strcasecmp(s, "NO_EXPORT_SUBCONFED") == 0) {
2436 setcommunity(c, COMMUNITY_WELLKNOWN0xffff,
2437 COMMUNITY_NO_EXPSUBCONFED0xff03, 0, 0);
2438 return (0);
2439 } else if (strcasecmp(s, "NO_PEER") == 0) {
2440 setcommunity(c, COMMUNITY_WELLKNOWN0xffff,
2441 COMMUNITY_NO_PEER0xff04, 0, 0);
2442 return (0);
2443 } else if (strcasecmp(s, "BLACKHOLE") == 0) {
2444 setcommunity(c, COMMUNITY_WELLKNOWN0xffff,
2445 COMMUNITY_BLACKHOLE0x029A, 0, 0);
2446 return (0);
2447 }
2448
2449 if ((p = strchr(s, ':')) == NULL((void *)0)) {
2450 yyerror("Bad community syntax");
2451 return (-1);
2452 }
2453 *p++ = 0;
2454
2455 if (getcommunity(s, 0, &as, &asflag) == -1 ||
2456 getcommunity(p, 0, &data, &dataflag) == -1)
2457 return (-1);
2458 setcommunity(c, as, data, asflag, dataflag);
2459 return (0);
2460}
2461
2462static int
2463parsesubtype(char *name, int *type, int *subtype)
2464{
2465 const struct ext_comm_pairs *cp;
2466 int found = 0;
2467
2468 for (cp = iana_ext_comms; cp->subname != NULL((void *)0); cp++) {
2469 if (strcmp(name, cp->subname) == 0) {
2470 if (found == 0) {
2471 *type = cp->type;
2472 *subtype = cp->subtype;
2473 }
2474 found++;
2475 }
2476 }
2477 if (found > 1)
2478 *type = -1;
2479 return (found);
2480}
2481
2482static int
2483parseextvalue(int type, char *s, uint32_t *v, uint32_t *flag)
2484{
2485 const char *errstr;
2486 char *p;
2487 struct in_addr ip;
2488 uint32_t uvalh, uval;
2489
2490 if (type != -1) {
2491 /* nothing */
2492 } else if (strcmp(s, "neighbor-as") == 0) {
2493 *flag = COMMUNITY_NEIGHBOR_AS2;
2494 *v = 0;
2495 return EXT_COMMUNITY_TRANS_TWO_AS0x00;
2496 } else if (strcmp(s, "local-as") == 0) {
2497 *flag = COMMUNITY_LOCAL_AS3;
2498 *v = 0;
2499 return EXT_COMMUNITY_TRANS_TWO_AS0x00;
2500 } else if ((p = strchr(s, '.')) == NULL((void *)0)) {
2501 /* AS_PLAIN number (4 or 2 byte) */
2502 strtonum(s, 0, USHRT_MAX0xffff, &errstr);
2503 if (errstr == NULL((void *)0))
2504 type = EXT_COMMUNITY_TRANS_TWO_AS0x00;
2505 else
2506 type = EXT_COMMUNITY_TRANS_FOUR_AS0x02;
2507 } else if (strchr(p + 1, '.') == NULL((void *)0)) {
2508 /* AS_DOT number (4-byte) */
2509 type = EXT_COMMUNITY_TRANS_FOUR_AS0x02;
2510 } else {
2511 /* more than one dot -> IP address */
2512 type = EXT_COMMUNITY_TRANS_IPV40x01;
2513 }
2514
2515 switch (type & EXT_COMMUNITY_VALUE0x3f) {
2516 case EXT_COMMUNITY_TRANS_TWO_AS0x00:
2517 uval = strtonum(s, 0, USHRT_MAX0xffff, &errstr);
2518 if (errstr) {
2519 yyerror("Bad ext-community %s is %s", s, errstr);
2520 return (-1);
2521 }
2522 *v = uval;
2523 break;
2524 case EXT_COMMUNITY_TRANS_FOUR_AS0x02:
2525 if ((p = strchr(s, '.')) == NULL((void *)0)) {
2526 uval = strtonum(s, 0, UINT_MAX0xffffffffU, &errstr);
2527 if (errstr) {
2528 yyerror("Bad ext-community %s is %s", s,
2529 errstr);
2530 return (-1);
2531 }
2532 *v = uval;
2533 break;
2534 }
2535 *p++ = '\0';
2536 uvalh = strtonum(s, 0, USHRT_MAX0xffff, &errstr);
2537 if (errstr) {
2538 yyerror("Bad ext-community %s is %s", s, errstr);
2539 return (-1);
2540 }
2541 uval = strtonum(p, 0, USHRT_MAX0xffff, &errstr);
2542 if (errstr) {
2543 yyerror("Bad ext-community %s is %s", p, errstr);
2544 return (-1);
2545 }
2546 *v = uval | (uvalh << 16);
2547 break;
2548 case EXT_COMMUNITY_TRANS_IPV40x01:
2549 if (inet_aton(s, &ip) == 0) {
2550 yyerror("Bad ext-community %s not parseable", s);
2551 return (-1);
2552 }
2553 *v = ntohl(ip.s_addr)(__uint32_t)(__builtin_constant_p(ip.s_addr) ? (__uint32_t)((
(__uint32_t)(ip.s_addr) & 0xff) << 24 | ((__uint32_t
)(ip.s_addr) & 0xff00) << 8 | ((__uint32_t)(ip.s_addr
) & 0xff0000) >> 8 | ((__uint32_t)(ip.s_addr) &
0xff000000) >> 24) : __swap32md(ip.s_addr))
;
2554 break;
2555 default:
2556 fatalx("%s: unexpected type %d", __func__, type);
2557 }
2558 return (type);
2559}
2560
2561int
2562parseextcommunity(struct community *c, char *t, char *s)
2563{
2564 const struct ext_comm_pairs *cp;
2565 char *p, *ep;
2566 uint64_t ullval;
2567 uint32_t uval, uval2, dflag1 = 0, dflag2 = 0;
2568 int type = 0, subtype = 0;
2569
2570 if (strcmp(t, "*") == 0 && strcmp(s, "*") == 0) {
2571 c->flags = COMMUNITY_TYPE_EXT16;
2572 c->flags |= COMMUNITY_ANY1 << 24;
2573 return (0);
2574 }
2575 if (parsesubtype(t, &type, &subtype) == 0) {
2576 yyerror("Bad ext-community unknown type");
2577 return (-1);
2578 }
2579
2580 switch (type) {
2581 case EXT_COMMUNITY_TRANS_TWO_AS0x00:
2582 case EXT_COMMUNITY_TRANS_FOUR_AS0x02:
2583 case EXT_COMMUNITY_TRANS_IPV40x01:
2584 case EXT_COMMUNITY_GEN_TWO_AS0x80:
2585 case EXT_COMMUNITY_GEN_FOUR_AS0x82:
2586 case EXT_COMMUNITY_GEN_IPV40x81:
2587 case -1:
2588 if (strcmp(s, "*") == 0) {
2589 dflag1 = COMMUNITY_ANY1;
2590 break;
2591 }
2592 if ((p = strchr(s, ':')) == NULL((void *)0)) {
2593 yyerror("Bad ext-community %s", s);
2594 return (-1);
2595 }
2596 *p++ = '\0';
2597 if ((type = parseextvalue(type, s, &uval, &dflag1)) == -1)
2598 return (-1);
2599
2600 switch (type) {
2601 case EXT_COMMUNITY_TRANS_TWO_AS0x00:
2602 case EXT_COMMUNITY_GEN_TWO_AS0x80:
2603 if (getcommunity(p, 1, &uval2, &dflag2) == -1)
2604 return (-1);
2605 break;
2606 case EXT_COMMUNITY_TRANS_IPV40x01:
2607 case EXT_COMMUNITY_TRANS_FOUR_AS0x02:
2608 case EXT_COMMUNITY_GEN_IPV40x81:
2609 case EXT_COMMUNITY_GEN_FOUR_AS0x82:
2610 if (getcommunity(p, 0, &uval2, &dflag2) == -1)
2611 return (-1);
2612 break;
2613 default:
2614 fatalx("parseextcommunity: unexpected result");
2615 }
2616
2617 c->data1 = uval;
2618 c->data2 = uval2;
2619 break;
2620 case EXT_COMMUNITY_TRANS_OPAQUE0x03:
2621 case EXT_COMMUNITY_TRANS_EVPN0x06:
2622 if (strcmp(s, "*") == 0) {
2623 dflag1 = COMMUNITY_ANY1;
2624 break;
2625 }
2626 errno(*__errno()) = 0;
2627 ullval = strtoull(s, &ep, 0);
2628 if (s[0] == '\0' || *ep != '\0') {
2629 yyerror("Bad ext-community bad value");
2630 return (-1);
2631 }
2632 if (errno(*__errno()) == ERANGE34 && ullval > EXT_COMMUNITY_OPAQUE_MAX0xffffffffffffULL) {
2633 yyerror("Bad ext-community value too big");
2634 return (-1);
2635 }
2636 c->data1 = ullval >> 32;
2637 c->data2 = ullval;
2638 break;
2639 case EXT_COMMUNITY_NON_TRANS_OPAQUE0x43:
2640 if (subtype == EXT_COMMUNITY_SUBTYPE_OVS0) {
2641 if (strcmp(s, "valid") == 0) {
2642 c->data2 = EXT_COMMUNITY_OVS_VALID0;
2643 break;
2644 } else if (strcmp(s, "invalid") == 0) {
2645 c->data2 = EXT_COMMUNITY_OVS_INVALID2;
2646 break;
2647 } else if (strcmp(s, "not-found") == 0) {
2648 c->data2 = EXT_COMMUNITY_OVS_NOTFOUND1;
2649 break;
2650 } else if (strcmp(s, "*") == 0) {
2651 dflag1 = COMMUNITY_ANY1;
2652 break;
2653 }
2654 }
2655 yyerror("Bad ext-community %s", s);
2656 return (-1);
2657 }
2658
2659 c->data3 = type << 8 | subtype;
2660
2661 /* special handling of ext-community rt * since type is not known */
2662 if (dflag1 == COMMUNITY_ANY1 && type == -1) {
2663 c->flags = COMMUNITY_TYPE_EXT16;
2664 c->flags |= dflag1 << 8;
2665 return (0);
2666 }
2667
2668 /* verify type/subtype combo */
2669 for (cp = iana_ext_comms; cp->subname != NULL((void *)0); cp++) {
2670 if (cp->type == type && cp->subtype == subtype) {
2671 c->flags = COMMUNITY_TYPE_EXT16;
2672 c->flags |= dflag1 << 8;
2673 c->flags |= dflag2 << 16;
2674 return (0);
2675 }
2676 }
2677
2678 yyerror("Bad ext-community bad format for type");
2679 return (-1);
2680}
2681
2682struct peer *
2683alloc_peer(void)
2684{
2685 struct peer *p;
2686 uint8_t i;
2687
2688 if ((p = calloc(1, sizeof(struct peer))) == NULL((void *)0))
2689 fatal("new_peer");
2690
2691 /* some sane defaults */
2692 p->state = STATE_NONE;
2693 p->reconf_action = RECONF_REINIT;
2694 p->conf.distance = 1;
2695 p->conf.export_type = EXPORT_UNSET;
2696 p->conf.announce_capa = 1;
2697 for (i = 0; i < AID_MAX7; i++)
2698 p->conf.capabilities.mp[i] = 0;
2699 p->conf.capabilities.refresh = 1;
2700 p->conf.capabilities.grestart.restart = 1;
2701 p->conf.capabilities.as4byte = 1;
2702 p->conf.capabilities.policy = 1;
2703 p->conf.local_as = conf->as;
2704 p->conf.local_short_as = conf->short_as;
2705 p->conf.remote_port = BGP_PORT179;
2706
2707 if (conf->flags & BGPD_FLAG_DECISION_TRANS_AS0x0200)
2708 p->conf.flags |= PEERFLAG_TRANS_AS0x01;
2709 if (conf->flags & BGPD_FLAG_DECISION_ALL_PATHS0x0800)
2710 p->conf.flags |= PEERFLAG_EVALUATE_ALL0x04;
2711 if (conf->flags & BGPD_FLAG_NO_AS_SET0x1000)
2712 p->conf.flags |= PEERFLAG_NO_AS_SET0x08;
2713
2714 return (p);
2715}
2716
2717struct peer *
2718new_peer(void)
2719{
2720 struct peer *p;
2721
2722 p = alloc_peer();
2723
2724 if (curgroup != NULL((void *)0)) {
2725 memcpy(p, curgroup, sizeof(struct peer));
2726 p->conf.groupid = curgroup->conf.id;
2727 }
2728 return (p);
2729}
2730
2731struct peer *
2732new_group(void)
2733{
2734 return (alloc_peer());
2735}
2736
2737int
2738add_mrtconfig(enum mrt_type type, char *name, int timeout, struct peer *p,
2739 char *rib)
2740{
2741 struct mrt *m, *n;
2742
2743 LIST_FOREACH(m, conf->mrt, entry)for((m) = ((conf->mrt)->lh_first); (m)!= ((void *)0); (
m) = ((m)->entry.le_next))
{
2744 if ((rib && strcmp(rib, m->rib)) ||
2745 (!rib && *m->rib))
2746 continue;
2747 if (p == NULL((void *)0)) {
2748 if (m->peer_id != 0 || m->group_id != 0)
2749 continue;
2750 } else {
2751 if (m->peer_id != p->conf.id ||
2752 m->group_id != p->conf.groupid)
2753 continue;
2754 }
2755 if (m->type == type) {
2756 yyerror("only one mrtdump per type allowed.");
2757 return (-1);
2758 }
2759 }
2760
2761 if ((n = calloc(1, sizeof(struct mrt_config))) == NULL((void *)0))
2762 fatal("add_mrtconfig");
2763
2764 n->type = type;
2765 n->state = MRT_STATE_OPEN;
2766 if (strlcpy(MRT2MC(n)((struct mrt_config *)(n))->name, name, sizeof(MRT2MC(n)((struct mrt_config *)(n))->name)) >=
2767 sizeof(MRT2MC(n)((struct mrt_config *)(n))->name)) {
2768 yyerror("filename \"%s\" too long: max %zu",
2769 name, sizeof(MRT2MC(n)((struct mrt_config *)(n))->name) - 1);
2770 free(n);
2771 return (-1);
2772 }
2773 MRT2MC(n)((struct mrt_config *)(n))->ReopenTimerInterval = timeout;
2774 if (p != NULL((void *)0)) {
2775 if (curgroup == p) {
2776 n->peer_id = 0;
2777 n->group_id = p->conf.id;
2778 } else {
2779 n->peer_id = p->conf.id;
2780 n->group_id = p->conf.groupid;
2781 }
2782 }
2783 if (rib) {
2784 if (!find_rib(rib)) {
2785 yyerror("rib \"%s\" does not exist.", rib);
2786 free(n);
2787 return (-1);
2788 }
2789 if (strlcpy(n->rib, rib, sizeof(n->rib)) >=
2790 sizeof(n->rib)) {
2791 yyerror("rib name \"%s\" too long: max %zu",
2792 name, sizeof(n->rib) - 1);
2793 free(n);
2794 return (-1);
2795 }
2796 }
2797
2798 LIST_INSERT_HEAD(conf->mrt, n, entry)do { if (((n)->entry.le_next = (conf->mrt)->lh_first
) != ((void *)0)) (conf->mrt)->lh_first->entry.le_prev
= &(n)->entry.le_next; (conf->mrt)->lh_first = (
n); (n)->entry.le_prev = &(conf->mrt)->lh_first;
} while (0)
;
2799
2800 return (0);
2801}
2802
2803struct rde_rib *
2804add_rib(char *name)
2805{
2806 struct rde_rib *rr;
2807
2808 if ((rr = find_rib(name)) == NULL((void *)0)) {
2809 if ((rr = calloc(1, sizeof(*rr))) == NULL((void *)0)) {
2810 log_warn("add_rib");
2811 return (NULL((void *)0));
2812 }
2813 if (strlcpy(rr->name, name, sizeof(rr->name)) >=
2814 sizeof(rr->name)) {
2815 yyerror("rib name \"%s\" too long: max %zu",
2816 name, sizeof(rr->name) - 1);
2817 free(rr);
2818 return (NULL((void *)0));
2819 }
2820 rr->flags = F_RIB_NOFIB0x0004;
2821 SIMPLEQ_INSERT_TAIL(&ribnames, rr, entry)do { (rr)->entry.sqe_next = ((void *)0); *(&ribnames)->
sqh_last = (rr); (&ribnames)->sqh_last = &(rr)->
entry.sqe_next; } while (0)
;
2822 }
2823 return (rr);
2824}
2825
2826struct rde_rib *
2827find_rib(char *name)
2828{
2829 struct rde_rib *rr;
2830
2831 SIMPLEQ_FOREACH(rr, &ribnames, entry)for((rr) = ((&ribnames)->sqh_first); (rr) != ((void *)
0); (rr) = ((rr)->entry.sqe_next))
{
2832 if (!strcmp(rr->name, name))
2833 return (rr);
2834 }
2835 return (NULL((void *)0));
2836}
2837
2838int
2839rib_add_fib(struct rde_rib *rr, u_int rtableid)
2840{
2841 u_int rdom;
2842
2843 if (!ktable_exists(rtableid, &rdom)) {
2844 yyerror("rtable id %u does not exist", rtableid);
2845 return (-1);
2846 }
2847 /*
2848 * conf->default_tableid is also a rdomain because that is checked
2849 * in init_config()
2850 */
2851 if (rdom != conf->default_tableid) {
2852 log_warnx("rtable %u does not belong to rdomain %u",
2853 rtableid, conf->default_tableid);
2854 return (-1);
2855 }
2856 rr->rtableid = rtableid;
2857 rr->flags &= ~F_RIB_NOFIB0x0004;
2858 return (0);
2859}
2860
2861struct prefixset *
2862find_prefixset(char *name, struct prefixset_head *p)
2863{
2864 struct prefixset *ps;
2865
2866 SIMPLEQ_FOREACH(ps, p, entry)for((ps) = ((p)->sqh_first); (ps) != ((void *)0); (ps) = (
(ps)->entry.sqe_next))
{
2867 if (!strcmp(ps->name, name))
2868 return (ps);
2869 }
2870 return (NULL((void *)0));
2871}
2872
2873int
2874get_id(struct peer *newpeer)
2875{
2876 static uint32_t id = PEER_ID_STATIC_MIN2;
2877 struct peer *p = NULL((void *)0);
2878
2879 /* check if the peer already existed before */
2880 if (newpeer->conf.remote_addr.aid) {
2881 /* neighbor */
2882 if (cur_peers)
2883 RB_FOREACH(p, peer_head, cur_peers)for ((p) = peer_head_RB_MINMAX(cur_peers, -1); (p) != ((void *
)0); (p) = peer_head_RB_NEXT(p))
2884 if (p->conf.remote_masklen ==
2885 newpeer->conf.remote_masklen &&
2886 memcmp(&p->conf.remote_addr,
2887 &newpeer->conf.remote_addr,
2888 sizeof(p->conf.remote_addr)) == 0)
2889 break;
2890 if (p) {
2891 newpeer->conf.id = p->conf.id;
2892 return (0);
2893 }
2894 } else {
2895 /* group */
2896 if (cur_peers)
2897 RB_FOREACH(p, peer_head, cur_peers)for ((p) = peer_head_RB_MINMAX(cur_peers, -1); (p) != ((void *
)0); (p) = peer_head_RB_NEXT(p))
2898 if (strcmp(p->conf.group,
2899 newpeer->conf.group) == 0)
2900 break;
2901 if (p) {
2902 newpeer->conf.id = p->conf.groupid;
2903 return (0);
2904 }
2905 }
2906
2907 /* else new one */
2908 if (id < PEER_ID_STATIC_MAX(0xffffffffU / 2)) {
2909 newpeer->conf.id = id++;
2910 return (0);
2911 }
2912
2913 return (-1);
2914}
2915
2916int
2917merge_prefixspec(struct filter_prefix *p, struct filter_prefixlen *pl)
2918{
2919 uint8_t max_len = 0;
2920
2921 switch (p->addr.aid) {
2922 case AID_INET1:
2923 case AID_VPN_IPv43:
2924 max_len = 32;
2925 break;
2926 case AID_INET62:
2927 case AID_VPN_IPv64:
2928 max_len = 128;
2929 break;
2930 }
2931
2932 if (pl->op == OP_NONE) {
2933 p->len_min = p->len_max = p->len;
2934 return (0);
2935 }
2936
2937 if (pl->len_min == -1)
2938 pl->len_min = p->len;
2939 if (pl->len_max == -1)
2940 pl->len_max = max_len;
2941
2942 if (pl->len_max > max_len) {
2943 yyerror("prefixlen %d too big, limit %d",
2944 pl->len_max, max_len);
2945 return (-1);
2946 }
2947 if (pl->len_min > pl->len_max) {
2948 yyerror("prefixlen %d too big, limit %d",
2949 pl->len_min, pl->len_max);
2950 return (-1);
2951 }
2952 if (pl->len_min < p->len) {
2953 yyerror("prefixlen %d smaller than prefix, limit %d",
2954 pl->len_min, p->len);
2955 return (-1);
2956 }
2957
2958 p->op = pl->op;
2959 p->len_min = pl->len_min;
2960 p->len_max = pl->len_max;
2961 return (0);
2962}
2963
2964int
2965expand_rule(struct filter_rule *rule, struct filter_rib_l *rib,
2966 struct filter_peers_l *peer, struct filter_match_l *match,
2967 struct filter_set_head *set)
2968{
2969 struct filter_rule *r;
2970 struct filter_rib_l *rb, *rbnext;
2971 struct filter_peers_l *p, *pnext;
2972 struct filter_prefix_l *prefix, *prefix_next;
2973 struct filter_as_l *a, *anext;
2974 struct filter_set *s;
2975
2976 rb = rib;
2977 do {
2978 p = peer;
2979 do {
2980 a = match->as_l;
2981 do {
2982 prefix = match->prefix_l;
2983 do {
2984 if ((r = calloc(1,
2985 sizeof(struct filter_rule))) ==
2986 NULL((void *)0)) {
2987 log_warn("expand_rule");
2988 return (-1);
2989 }
2990
2991 memcpy(r, rule, sizeof(struct filter_rule));
2992 memcpy(&r->match, match,
2993 sizeof(struct filter_match));
2994 filterset_copy(set, &r->set);
2995
2996 if (rb != NULL((void *)0))
2997 strlcpy(r->rib, rb->name,
2998 sizeof(r->rib));
2999
3000 if (p != NULL((void *)0))
3001 memcpy(&r->peer, &p->p,
3002 sizeof(struct filter_peers));
3003
3004 if (prefix != NULL((void *)0))
3005 memcpy(&r->match.prefix, &prefix->p,
3006 sizeof(r->match.prefix));
3007
3008 if (a != NULL((void *)0))
3009 memcpy(&r->match.as, &a->a,
3010 sizeof(struct filter_as));
3011
3012 TAILQ_INSERT_TAIL(filter_l, r, entry)do { (r)->entry.tqe_next = ((void *)0); (r)->entry.tqe_prev
= (filter_l)->tqh_last; *(filter_l)->tqh_last = (r); (
filter_l)->tqh_last = &(r)->entry.tqe_next; } while
(0)
;
3013
3014 if (prefix != NULL((void *)0))
3015 prefix = prefix->next;
3016 } while (prefix != NULL((void *)0));
3017
3018 if (a != NULL((void *)0))
3019 a = a->next;
3020 } while (a != NULL((void *)0));
3021
3022 if (p != NULL((void *)0))
3023 p = p->next;
3024 } while (p != NULL((void *)0));
3025
3026 if (rb != NULL((void *)0))
3027 rb = rb->next;
3028 } while (rb != NULL((void *)0));
3029
3030 for (rb = rib; rb != NULL((void *)0); rb = rbnext) {
3031 rbnext = rb->next;
3032 free(rb);
3033 }
3034
3035 for (p = peer; p != NULL((void *)0); p = pnext) {
3036 pnext = p->next;
3037 free(p);
3038 }
3039
3040 for (a = match->as_l; a != NULL((void *)0); a = anext) {
3041 anext = a->next;
3042 free(a);
3043 }
3044
3045 for (prefix = match->prefix_l; prefix != NULL((void *)0); prefix = prefix_next) {
3046 prefix_next = prefix->next;
3047 free(prefix);
3048 }
3049
3050 if (set != NULL((void *)0)) {
3051 while ((s = TAILQ_FIRST(set)((set)->tqh_first)) != NULL((void *)0)) {
3052 TAILQ_REMOVE(set, s, entry)do { if (((s)->entry.tqe_next) != ((void *)0)) (s)->entry
.tqe_next->entry.tqe_prev = (s)->entry.tqe_prev; else (
set)->tqh_last = (s)->entry.tqe_prev; *(s)->entry.tqe_prev
= (s)->entry.tqe_next; ; ; } while (0)
;
3053 free(s);
3054 }
3055 free(set);
3056 }
3057
3058 return (0);
3059}
3060
3061int
3062str2key(char *s, char *dest, size_t max_len)
3063{
3064 unsigned i;
3065 char t[3];
3066
3067 if (strlen(s) / 2 > max_len) {
3068 yyerror("key too long");
3069 return (-1);
3070 }
3071
3072 if (strlen(s) % 2) {
3073 yyerror("key must be of even length");
3074 return (-1);
3075 }
3076
3077 for (i = 0; i < strlen(s) / 2; i++) {
3078 t[0] = s[2*i];
3079 t[1] = s[2*i + 1];
3080 t[2] = 0;
3081 if (!isxdigit(t[0]) || !isxdigit(t[1])) {
3082 yyerror("key must be specified in hex");
3083 return (-1);
3084 }
3085 dest[i] = strtoul(t, NULL((void *)0), 16);
3086 }
3087
3088 return (0);
3089}
3090
3091int
3092neighbor_consistent(struct peer *p)
3093{
3094 struct bgpd_addr *local_addr;
3095 struct peer *xp;
3096
3097 switch (p->conf.remote_addr.aid) {
3098 case AID_INET1:
3099 local_addr = &p->conf.local_addr_v4;
3100 break;
3101 case AID_INET62:
3102 local_addr = &p->conf.local_addr_v6;
3103 break;
3104 default:
3105 yyerror("Bad address family for remote-addr");
3106 return (-1);
3107 }
3108
3109 /* with any form of ipsec local-address is required */
3110 if ((p->conf.auth.method == AUTH_IPSEC_IKE_ESP ||
3111 p->conf.auth.method == AUTH_IPSEC_IKE_AH ||
3112 p->conf.auth.method == AUTH_IPSEC_MANUAL_ESP ||
3113 p->conf.auth.method == AUTH_IPSEC_MANUAL_AH) &&
3114 local_addr->aid == AID_UNSPEC0) {
3115 yyerror("neighbors with any form of IPsec configured "
3116 "need local-address to be specified");
3117 return (-1);
3118 }
3119
3120 /* with static keying we need both directions */
3121 if ((p->conf.auth.method == AUTH_IPSEC_MANUAL_ESP ||
3122 p->conf.auth.method == AUTH_IPSEC_MANUAL_AH) &&
3123 (!p->conf.auth.spi_in || !p->conf.auth.spi_out)) {
3124 yyerror("with manual keyed IPsec, SPIs and keys "
3125 "for both directions are required");
3126 return (-1);
3127 }
3128
3129 if (!conf->as) {
3130 yyerror("AS needs to be given before neighbor definitions");
3131 return (-1);
3132 }
3133
3134 /* set default values if they where undefined */
3135 p->conf.ebgp = (p->conf.remote_as != conf->as);
3136 if (p->conf.enforce_as == ENFORCE_AS_UNDEF)
3137 p->conf.enforce_as = p->conf.ebgp ?
3138 ENFORCE_AS_ON : ENFORCE_AS_OFF;
3139 if (p->conf.enforce_local_as == ENFORCE_AS_UNDEF)
3140 p->conf.enforce_local_as = ENFORCE_AS_ON;
3141
3142 if (p->conf.remote_as == 0 && !p->conf.template) {
3143 yyerror("peer AS may not be zero");
3144 return (-1);
3145 }
3146
3147 /* EBGP neighbors are not allowed in route reflector clusters */
3148 if (p->conf.reflector_client && p->conf.ebgp) {
3149 yyerror("EBGP neighbors are not allowed in route "
3150 "reflector clusters");
3151 return (-1);
3152 }
3153
3154 /* BGP role and RFC 9234 role are only valid for EBGP neighbors */
3155 if (!p->conf.ebgp) {
3156 p->conf.role = ROLE_NONE;
3157 p->conf.capabilities.policy = 0;
3158 } else if (p->conf.role == ROLE_NONE) {
3159 /* no role, no policy capability */
3160 p->conf.capabilities.policy = 0;
3161 }
3162
3163 /* check for duplicate peer definitions */
3164 RB_FOREACH(xp, peer_head, new_peers)for ((xp) = peer_head_RB_MINMAX(new_peers, -1); (xp) != ((void
*)0); (xp) = peer_head_RB_NEXT(xp))
3165 if (xp->conf.remote_masklen ==
3166 p->conf.remote_masklen &&
3167 memcmp(&xp->conf.remote_addr,
3168 &p->conf.remote_addr,
3169 sizeof(p->conf.remote_addr)) == 0)
3170 break;
3171 if (xp != NULL((void *)0)) {
3172 char *descr = log_fmt_peer(&p->conf);
3173 yyerror("duplicate %s", descr);
3174 free(descr);
3175 return (-1);
3176 }
3177
3178 return (0);
3179}
3180
3181static void
3182filterset_add(struct filter_set_head *sh, struct filter_set *s)
3183{
3184 struct filter_set *t;
3185
3186 TAILQ_FOREACH(t, sh, entry)for((t) = ((sh)->tqh_first); (t) != ((void *)0); (t) = ((t
)->entry.tqe_next))
{
3187 if (s->type < t->type) {
3188 TAILQ_INSERT_BEFORE(t, s, entry)do { (s)->entry.tqe_prev = (t)->entry.tqe_prev; (s)->
entry.tqe_next = (t); *(t)->entry.tqe_prev = (s); (t)->
entry.tqe_prev = &(s)->entry.tqe_next; } while (0)
;
3189 return;
3190 }
3191 if (s->type == t->type) {
3192 switch (s->type) {
3193 case ACTION_SET_COMMUNITY:
3194 case ACTION_DEL_COMMUNITY:
3195 switch (cmpcommunity(&s->action.community,
3196 &t->action.community)) {
3197 case -1:
3198 TAILQ_INSERT_BEFORE(t, s, entry)do { (s)->entry.tqe_prev = (t)->entry.tqe_prev; (s)->
entry.tqe_next = (t); *(t)->entry.tqe_prev = (s); (t)->
entry.tqe_prev = &(s)->entry.tqe_next; } while (0)
;
3199 return;
3200 case 0:
3201 break;
3202 case 1:
3203 continue;
3204 }
3205 break;
3206 case ACTION_SET_NEXTHOP:
3207 /* only last nexthop per AF matters */
3208 if (s->action.nexthop.aid <
3209 t->action.nexthop.aid) {
3210 TAILQ_INSERT_BEFORE(t, s, entry)do { (s)->entry.tqe_prev = (t)->entry.tqe_prev; (s)->
entry.tqe_next = (t); *(t)->entry.tqe_prev = (s); (t)->
entry.tqe_prev = &(s)->entry.tqe_next; } while (0)
;
3211 return;
3212 } else if (s->action.nexthop.aid ==
3213 t->action.nexthop.aid) {
3214 t->action.nexthop = s->action.nexthop;
3215 break;
3216 }
3217 continue;
3218 case ACTION_SET_NEXTHOP_BLACKHOLE:
3219 case ACTION_SET_NEXTHOP_REJECT:
3220 case ACTION_SET_NEXTHOP_NOMODIFY:
3221 case ACTION_SET_NEXTHOP_SELF:
3222 /* set it only once */
3223 break;
3224 case ACTION_SET_LOCALPREF:
3225 case ACTION_SET_MED:
3226 case ACTION_SET_WEIGHT:
3227 /* only last set matters */
3228 t->action.metric = s->action.metric;
3229 break;
3230 case ACTION_SET_RELATIVE_LOCALPREF:
3231 case ACTION_SET_RELATIVE_MED:
3232 case ACTION_SET_RELATIVE_WEIGHT:
3233 /* sum all relative numbers */
3234 t->action.relative += s->action.relative;
3235 break;
3236 case ACTION_SET_ORIGIN:
3237 /* only last set matters */
3238 t->action.origin = s->action.origin;
3239 break;
3240 case ACTION_PFTABLE:
3241 /* only last set matters */
3242 strlcpy(t->action.pftable, s->action.pftable,
3243 sizeof(t->action.pftable));
3244 break;
3245 case ACTION_RTLABEL:
3246 /* only last set matters */
3247 strlcpy(t->action.rtlabel, s->action.rtlabel,
3248 sizeof(t->action.rtlabel));
3249 break;
3250 default:
3251 break;
3252 }
3253 free(s);
3254 return;
3255 }
3256 }
3257
3258 TAILQ_INSERT_TAIL(sh, s, entry)do { (s)->entry.tqe_next = ((void *)0); (s)->entry.tqe_prev
= (sh)->tqh_last; *(sh)->tqh_last = (s); (sh)->tqh_last
= &(s)->entry.tqe_next; } while (0)
;
3259}
3260
3261int
3262merge_filterset(struct filter_set_head *sh, struct filter_set *s)
3263{
3264 struct filter_set *t;
3265
3266 TAILQ_FOREACH(t, sh, entry)for((t) = ((sh)->tqh_first); (t) != ((void *)0); (t) = ((t
)->entry.tqe_next))
{
3267 /*
3268 * need to cycle across the full list because even
3269 * if types are not equal filterset_cmp() may return 0.
3270 */
3271 if (filterset_cmp(s, t) == 0) {
3272 if (s->type == ACTION_SET_COMMUNITY)
3273 yyerror("community is already set");
3274 else if (s->type == ACTION_DEL_COMMUNITY)
3275 yyerror("community will already be deleted");
3276 else
3277 yyerror("redefining set parameter %s",
3278 filterset_name(s->type));
3279 return (-1);
3280 }
3281 }
3282
3283 filterset_add(sh, s);
3284 return (0);
3285}
3286
3287static int
3288filter_equal(struct filter_rule *fa, struct filter_rule *fb)
3289{
3290 if (fa
34.1
'fa' is not equal to NULL
== NULL((void *)0) || fb == NULL((void *)0))
35
Assuming 'fb' is not equal to NULL
3291 return 0;
3292 if (fa->action != fb->action || fa->quick != fb->quick ||
36
Assuming 'fa->action' is equal to 'fb->action'
37
Assuming 'fa->quick' is equal to 'fb->quick'
39
Taking false branch
3293 fa->dir != fb->dir)
38
Assuming 'fa->dir' is equal to 'fb->dir'
3294 return 0;
3295 if (memcmp(&fa->peer, &fb->peer, sizeof(fa->peer)))
40
Assuming the condition is false
41
Taking false branch
3296 return 0;
3297 if (memcmp(&fa->match, &fb->match, sizeof(fa->match)))
42
Assuming the condition is false
43
Taking false branch
3298 return 0;
3299
3300 return 1;
3301}
3302
3303/* do a basic optimization by folding equal rules together */
3304void
3305optimize_filters(struct filter_head *fh)
3306{
3307 struct filter_rule *r, *nr;
3308
3309 TAILQ_FOREACH_SAFE(r, fh, entry, nr)for ((r) = ((fh)->tqh_first); (r) != ((void *)0) &&
((nr) = ((r)->entry.tqe_next), 1); (r) = (nr))
{
32
Assuming 'r' is not equal to null
33
Loop condition is true. Entering loop body
3310 while (filter_equal(r, nr)) {
34
Calling 'filter_equal'
44
Returning from 'filter_equal'
45
Loop condition is true. Entering loop body
52
Use of memory after it is freed
3311 struct filter_set *t;
3312
3313 while ((t = TAILQ_FIRST(&nr->set)((&nr->set)->tqh_first)) != NULL((void *)0)) {
46
Assuming the condition is false
47
Loop condition is false. Execution continues on line 3318
3314 TAILQ_REMOVE(&nr->set, t, entry)do { if (((t)->entry.tqe_next) != ((void *)0)) (t)->entry
.tqe_next->entry.tqe_prev = (t)->entry.tqe_prev; else (
&nr->set)->tqh_last = (t)->entry.tqe_prev; *(t)->
entry.tqe_prev = (t)->entry.tqe_next; ; ; } while (0)
;
3315 filterset_add(&r->set, t);
3316 }
3317
3318 TAILQ_REMOVE(fh, nr, entry)do { if (((nr)->entry.tqe_next) != ((void *)0)) (nr)->entry
.tqe_next->entry.tqe_prev = (nr)->entry.tqe_prev; else (
fh)->tqh_last = (nr)->entry.tqe_prev; *(nr)->entry.tqe_prev
= (nr)->entry.tqe_next; ; ; } while (0)
;
48
Assuming field 'tqe_next' is equal to null
49
Taking false branch
50
Loop condition is false. Exiting loop
3319 free(nr);
51
Memory is released
3320 nr = TAILQ_NEXT(r, entry)((r)->entry.tqe_next);
3321 }
3322 }
3323}
3324
3325struct filter_rule *
3326get_rule(enum action_types type)
3327{
3328 struct filter_rule *r;
3329 int out;
3330
3331 switch (type) {
3332 case ACTION_SET_PREPEND_SELF:
3333 case ACTION_SET_NEXTHOP_NOMODIFY:
3334 case ACTION_SET_NEXTHOP_SELF:
3335 out = 1;
3336 break;
3337 default:
3338 out = 0;
3339 break;
3340 }
3341 r = (curpeer == curgroup) ? curgroup_filter[out] : curpeer_filter[out];
3342 if (r == NULL((void *)0)) {
3343 if ((r = calloc(1, sizeof(struct filter_rule))) == NULL((void *)0))
3344 fatal(NULL((void *)0));
3345 r->quick = 0;
3346 r->dir = out ? DIR_OUT : DIR_IN;
3347 r->action = ACTION_NONE;
3348 TAILQ_INIT(&r->set)do { (&r->set)->tqh_first = ((void *)0); (&r->
set)->tqh_last = &(&r->set)->tqh_first; } while
(0)
;
3349 if (curpeer == curgroup) {
3350 /* group */
3351 r->peer.groupid = curgroup->conf.id;
3352 curgroup_filter[out] = r;
3353 } else {
3354 /* peer */
3355 r->peer.peerid = curpeer->conf.id;
3356 curpeer_filter[out] = r;
3357 }
3358 }
3359 return (r);
3360}
3361
3362struct set_table *curset;
3363static int
3364new_as_set(char *name)
3365{
3366 struct as_set *aset;
3367
3368 if (as_sets_lookup(&conf->as_sets, name) != NULL((void *)0)) {
3369 yyerror("as-set \"%s\" already exists", name);
3370 return -1;
3371 }
3372
3373 aset = as_sets_new(&conf->as_sets, name, 0, sizeof(uint32_t));
3374 if (aset == NULL((void *)0))
3375 fatal(NULL((void *)0));
3376
3377 curset = aset->set;
3378 return 0;
3379}
3380
3381static void
3382add_as_set(uint32_t as)
3383{
3384 if (curset == NULL((void *)0))
3385 fatalx("%s: bad mojo jojo", __func__);
3386
3387 if (set_add(curset, &as, 1) != 0)
3388 fatal(NULL((void *)0));
3389}
3390
3391static void
3392done_as_set(void)
3393{
3394 curset = NULL((void *)0);
3395}
3396
3397static struct prefixset *
3398new_prefix_set(char *name, int is_roa)
3399{
3400 const char *type = "prefix-set";
3401 struct prefixset_head *sets = &conf->prefixsets;
3402 struct prefixset *pset;
3403
3404 if (is_roa) {
3405 type = "origin-set";
3406 sets = &conf->originsets;
3407 }
3408
3409 if (find_prefixset(name, sets) != NULL((void *)0)) {
3410 yyerror("%s \"%s\" already exists", type, name);
3411 return NULL((void *)0);
3412 }
3413 if ((pset = calloc(1, sizeof(*pset))) == NULL((void *)0))
3414 fatal("prefixset");
3415 if (strlcpy(pset->name, name, sizeof(pset->name)) >=
3416 sizeof(pset->name)) {
3417 yyerror("%s \"%s\" too long: max %zu", type,
3418 name, sizeof(pset->name) - 1);
3419 free(pset);
3420 return NULL((void *)0);
3421 }
3422 RB_INIT(&pset->psitems)do { (&pset->psitems)->rbh_root = ((void *)0); } while
(0)
;
3423 RB_INIT(&pset->roaitems)do { (&pset->roaitems)->rbh_root = ((void *)0); } while
(0)
;
3424 return pset;
3425}
3426
3427static void
3428add_roa_set(struct prefixset_item *npsi, uint32_t as, uint8_t max,
3429 time_t expires)
3430{
3431 struct roa *roa, *r;
3432
3433 if ((roa = calloc(1, sizeof(*roa))) == NULL((void *)0))
3434 fatal("add_roa_set");
3435
3436 roa->aid = npsi->p.addr.aid;
3437 roa->prefixlen = npsi->p.len;
3438 roa->maxlen = max;
3439 roa->asnum = as;
3440 roa->expires = expires;
3441 switch (roa->aid) {
3442 case AID_INET1:
3443 roa->prefix.inet = npsi->p.addr.v4ba.v4;
3444 break;
3445 case AID_INET62:
3446 roa->prefix.inet6 = npsi->p.addr.v6ba.v6;
3447 break;
3448 default:
3449 fatalx("Bad address family for roa_set address");
3450 }
3451
3452 r = RB_INSERT(roa_tree, curroatree, roa)roa_tree_RB_INSERT(curroatree, roa);
3453 if (r != NULL((void *)0)) {
3454 /* just ignore duplicates */
3455 if (r->expires != 0 && expires != 0 && expires > r->expires)
3456 r->expires = expires;
3457 free(roa);
3458 }
3459}
3460
3461static struct rtr_config *
3462get_rtr(struct bgpd_addr *addr)
3463{
3464 struct rtr_config *n;
3465
3466 n = calloc(1, sizeof(*n));
3467 if (n == NULL((void *)0)) {
3468 yyerror("out of memory");
3469 return NULL((void *)0);
3470 }
3471
3472 n->remote_addr = *addr;
3473 strlcpy(n->descr, log_addr(addr), sizeof(currtr->descr));
3474
3475 return n;
3476}
3477
3478static int
3479insert_rtr(struct rtr_config *new)
3480{
3481 static uint32_t id;
3482 struct rtr_config *r;
3483
3484 if (id == UINT32_MAX0xffffffffU) {
3485 yyerror("out of rtr session IDs");
3486 return -1;
3487 }
3488
3489 SIMPLEQ_FOREACH(r, &conf->rtrs, entry)for((r) = ((&conf->rtrs)->sqh_first); (r) != ((void
*)0); (r) = ((r)->entry.sqe_next))
3490 if (memcmp(&r->remote_addr, &new->remote_addr,
3491 sizeof(r->remote_addr)) == 0 &&
3492 r->remote_port == new->remote_port) {
3493 yyerror("duplicate rtr session to %s:%u",
3494 log_addr(&new->remote_addr), new->remote_port);
3495 return -1;
3496 }
3497
3498 if (cur_rtrs)
3499 SIMPLEQ_FOREACH(r, cur_rtrs, entry)for((r) = ((cur_rtrs)->sqh_first); (r) != ((void *)0); (r)
= ((r)->entry.sqe_next))
3500 if (memcmp(&r->remote_addr, &new->remote_addr,
3501 sizeof(r->remote_addr)) == 0 &&
3502 r->remote_port == new->remote_port) {
3503 new->id = r->id;
3504 break;
3505 }
3506
3507 if (new->id == 0)
3508 new->id = ++id;
3509
3510 SIMPLEQ_INSERT_TAIL(&conf->rtrs, currtr, entry)do { (currtr)->entry.sqe_next = ((void *)0); *(&conf->
rtrs)->sqh_last = (currtr); (&conf->rtrs)->sqh_last
= &(currtr)->entry.sqe_next; } while (0)
;
3511
3512 return 0;
3513}
3514
3515static int
3516merge_aspa_set(uint32_t as, struct aspa_tas_l *tas, time_t expires)
3517{
3518 struct aspa_set *aspa, needle = { .as = as };
3519 uint32_t i, num, *newtas;
3520
3521 aspa = RB_FIND(aspa_tree, &conf->aspa, &needle)aspa_tree_RB_FIND(&conf->aspa, &needle);
3522 if (aspa == NULL((void *)0)) {
3523 if ((aspa = calloc(1, sizeof(*aspa))) == NULL((void *)0)) {
3524 yyerror("out of memory");
3525 return -1;
3526 }
3527 aspa->as = as;
3528 aspa->expires = expires;
3529 RB_INSERT(aspa_tree, &conf->aspa, aspa)aspa_tree_RB_INSERT(&conf->aspa, aspa);
3530 }
3531
3532 if (UINT32_MAX0xffffffffU - aspa->num <= tas->num) {
3533 yyerror("aspa_set overflow");
3534 return -1;
3535 }
3536 num = aspa->num + tas->num;
3537 newtas = recallocarray(aspa->tas, aspa->num, num, sizeof(uint32_t));
3538 if (newtas == NULL((void *)0)) {
3539 yyerror("out of memory");
3540 return -1;
3541 }
3542 /* fill starting at the end since the tas list is reversed */
3543 if (num > 0) {
3544 for (i = num - 1; tas; tas = tas->next, i--)
3545 newtas[i] = tas->as;
3546 }
3547
3548 aspa->num = num;
3549 aspa->tas = newtas;
3550 /* take the longest expiry time, same logic as for ROA entries */
3551 if (aspa->expires != 0 && expires != 0 && expires > aspa->expires)
3552 aspa->expires = expires;
3553
3554 return 0;
3555}
3556
3557static int
3558kw_casecmp(const void *k, const void *e)
3559{
3560 return (strcasecmp(k, ((const struct keywords *)e)->k_name));
3561}
3562
3563static int
3564map_tos(char *s, int *val)
3565{
3566 /* DiffServ Codepoints and other TOS mappings */
3567 const struct keywords toswords[] = {
3568 { "af11", IPTOS_DSCP_AF110x28 },
3569 { "af12", IPTOS_DSCP_AF120x30 },
3570 { "af13", IPTOS_DSCP_AF130x38 },
3571 { "af21", IPTOS_DSCP_AF210x48 },
3572 { "af22", IPTOS_DSCP_AF220x50 },
3573 { "af23", IPTOS_DSCP_AF230x58 },
3574 { "af31", IPTOS_DSCP_AF310x68 },
3575 { "af32", IPTOS_DSCP_AF320x70 },
3576 { "af33", IPTOS_DSCP_AF330x78 },
3577 { "af41", IPTOS_DSCP_AF410x88 },
3578 { "af42", IPTOS_DSCP_AF420x90 },
3579 { "af43", IPTOS_DSCP_AF430x98 },
3580 { "critical", IPTOS_PREC_CRITIC_ECP0xa0 },
3581 { "cs0", IPTOS_DSCP_CS00x00 },
3582 { "cs1", IPTOS_DSCP_CS10x20 },
3583 { "cs2", IPTOS_DSCP_CS20x40 },
3584 { "cs3", IPTOS_DSCP_CS30x60 },
3585 { "cs4", IPTOS_DSCP_CS40x80 },
3586 { "cs5", IPTOS_DSCP_CS50xa0 },
3587 { "cs6", IPTOS_DSCP_CS60xc0 },
3588 { "cs7", IPTOS_DSCP_CS70xe0 },
3589 { "ef", IPTOS_DSCP_EF0xb8 },
3590 { "inetcontrol", IPTOS_PREC_INTERNETCONTROL0xc0 },
3591 { "lowdelay", IPTOS_LOWDELAY0x10 },
3592 { "netcontrol", IPTOS_PREC_NETCONTROL0xe0 },
3593 { "reliability", IPTOS_RELIABILITY0x04 },
3594 { "throughput", IPTOS_THROUGHPUT0x08 }
3595 };
3596 const struct keywords *p;
3597
3598 p = bsearch(s, toswords, nitems(toswords)(sizeof((toswords)) / sizeof((toswords)[0])), sizeof(toswords[0]),
3599 kw_casecmp);
3600
3601 if (p) {
3602 *val = p->k_val;
3603 return (1);
3604 }
3605 return (0);
3606}
3607
3608static int
3609getservice(char *n)
3610{
3611 struct servent *s;
3612
3613 s = getservbyname(n, "tcp");
3614 if (s == NULL((void *)0))
3615 s = getservbyname(n, "udp");
3616 if (s == NULL((void *)0))
3617 return -1;
3618 return s->s_port;
3619}
3620
3621static int
3622parse_flags(char *s)
3623{
3624 const char *flags = FLOWSPEC_TCP_FLAG_STRING"FSRPAUEW";
3625 char *p, *q;
3626 uint8_t f = 0;
3627
3628 if (curflow->type == FLOWSPEC_TYPE_FRAG12) {
3629 if (curflow->aid == AID_INET1)
3630 flags = FLOWSPEC_FRAG_STRING4"DIFL";
3631 else
3632 flags = FLOWSPEC_FRAG_STRING6" IFL";
3633 }
3634
3635 for (p = s; *p; p++) {
3636 if ((q = strchr(flags, *p)) == NULL((void *)0))
3637 return -1;
3638 f |= 1 << (q - flags);
3639 }
3640 return (f ? f : 0xff);
3641}
3642
3643static void
3644component_finish(int type, uint8_t *data, int len)
3645{
3646 uint8_t *last;
3647 int i;
3648
3649 switch (type) {
3650 case FLOWSPEC_TYPE_DEST1:
3651 case FLOWSPEC_TYPE_SOURCE2:
3652 /* nothing to do */
3653 return;
3654 default:
3655 break;
3656 }
3657
3658 i = 0;
3659 do {
3660 last = data + i;
3661 i += FLOWSPEC_OP_LEN(*last)(1 << (((*last) & 0x30) >> 4)) + 1;
3662 } while (i < len);
3663 *last |= FLOWSPEC_OP_EOL0x80;
3664}
3665
3666static struct flowspec_config *
3667flow_to_flowspec(struct flowspec_context *ctx)
3668{
3669 struct flowspec_config *f;
3670 int i, len = 0;
3671 uint8_t aid;
3672
3673 switch (ctx->aid) {
3674 case AID_INET1:
3675 aid = AID_FLOWSPECv45;
3676 break;
3677 case AID_INET62:
3678 aid = AID_FLOWSPECv66;
3679 break;
3680 default:
3681 return NULL((void *)0);
3682 }
3683
3684 for (i = FLOWSPEC_TYPE_MIN1; i < FLOWSPEC_TYPE_MAX14; i++)
3685 if (ctx->components[i] != NULL((void *)0))
3686 len += ctx->complen[i] + 1;
3687
3688 f = flowspec_alloc(aid, len);
3689 if (f == NULL((void *)0))
3690 return NULL((void *)0);
3691
3692 len = 0;
3693 for (i = FLOWSPEC_TYPE_MIN1; i < FLOWSPEC_TYPE_MAX14; i++)
3694 if (ctx->components[i] != NULL((void *)0)) {
3695 f->flow->data[len++] = i;
3696 component_finish(i, ctx->components[i],
3697 ctx->complen[i]);
3698 memcpy(f->flow->data + len, ctx->components[i],
3699 ctx->complen[i]);
3700 len += ctx->complen[i];
3701 }
3702
3703 return f;
3704}
3705
3706static void
3707flow_free(struct flowspec_context *ctx)
3708{
3709 int i;
3710
3711 for (i = 0; i < FLOWSPEC_TYPE_MAX14; i++)
3712 free(ctx->components[i]);
3713 free(ctx);
3714}
3715
3716static int
3717push_prefix(struct bgpd_addr *addr, uint8_t len)
3718{
3719 void *data;
3720 uint8_t *comp;
3721 int complen, l;
3722
3723 if (curflow->components[curflow->addr_type] != NULL((void *)0)) {
3724 yyerror("flowspec address already set");
3725 return -1;
3726 }
3727
3728 if (curflow->aid != addr->aid) {
3729 yyerror("wrong address family for flowspec address");
3730 return -1;
3731 }
3732
3733 switch (curflow->aid) {
3734 case AID_INET1:
3735 complen = PREFIX_SIZE(len)(((len) + 7) / 8 + 1);
3736 data = &addr->v4ba.v4;
3737 break;
3738 case AID_INET62:
3739 /* IPv6 includes an offset byte */
3740 complen = PREFIX_SIZE(len)(((len) + 7) / 8 + 1) + 1;
3741 data = &addr->v6ba.v6;
3742 break;
3743 default:
3744 yyerror("unsupported address family for flowspec address");
3745 return -1;
3746 }
3747 comp = malloc(complen);
3748 if (comp == NULL((void *)0)) {
3749 yyerror("out of memory");
3750 return -1;
3751 }
3752
3753 l = 0;
3754 comp[l++] = len;
3755 if (curflow->aid == AID_INET62)
3756 comp[l++] = 0;
3757 memcpy(comp + l, data, complen - l);
3758
3759 curflow->complen[curflow->addr_type] = complen;
3760 curflow->components[curflow->addr_type] = comp;
3761
3762 return 0;
3763}
3764
3765static int
3766push_binop(uint8_t binop, long long val)
3767{
3768 uint8_t *comp;
3769 int complen;
3770 uint8_t u8;
3771
3772 if (val < 0 || val > 0xff) {
3773 yyerror("unsupported value for flowspec bin_op");
3774 return -1;
3775 }
3776 u8 = val;
3777
3778 complen = curflow->complen[curflow->type];
3779 comp = realloc(curflow->components[curflow->type],
3780 complen + 2);
3781 if (comp == NULL((void *)0)) {
3782 yyerror("out of memory");
3783 return -1;
3784 }
3785
3786 comp[complen++] = binop;
3787 comp[complen++] = u8;
3788 curflow->complen[curflow->type] = complen;
3789 curflow->components[curflow->type] = comp;
3790
3791 return 0;
3792}
3793
3794static uint8_t
3795component_numop(enum comp_ops op, int and, int len)
3796{
3797 uint8_t flag = 0;
3798
3799 switch (op) {
3800 case OP_EQ:
3801 flag |= FLOWSPEC_OP_NUM_EQ0x01;
3802 break;
3803 case OP_NE:
3804 flag |= FLOWSPEC_OP_NUM_NOT(0x02 | 0x04);
3805 break;
3806 case OP_LE:
3807 flag |= FLOWSPEC_OP_NUM_LE(0x04 | 0x01);
3808 break;
3809 case OP_LT:
3810 flag |= FLOWSPEC_OP_NUM_LT0x04;
3811 break;
3812 case OP_GE:
3813 flag |= FLOWSPEC_OP_NUM_GE(0x02 | 0x01);
3814 break;
3815 case OP_GT:
3816 flag |= FLOWSPEC_OP_NUM_GT0x02;
3817 break;
3818 default:
3819 fatalx("unsupported op");
3820 }
3821
3822 switch (len) {
3823 case 2:
3824 flag |= 1 << FLOWSPEC_OP_LEN_SHIFT4;
3825 break;
3826 case 4:
3827 flag |= 2 << FLOWSPEC_OP_LEN_SHIFT4;
3828 break;
3829 case 8:
3830 flag |= 3 << FLOWSPEC_OP_LEN_SHIFT4;
3831 break;
3832 }
3833
3834 if (and)
3835 flag |= FLOWSPEC_OP_AND0x40;
3836
3837 return flag;
3838}
3839
3840static int
3841push_numop(enum comp_ops op, int and, long long val)
3842{
3843 uint8_t *comp;
3844 void *data;
3845 uint32_t u32;
3846 uint16_t u16;
3847 uint8_t u8;
3848 int len, complen;
3849
3850 if (val < 0 || val > 0xffffffff) {
3851 yyerror("unsupported value for flowspec num_op");
3852 return -1;
3853 } else if (val <= 255) {
3854 len = 1;
3855 u8 = val;
3856 data = &u8;
3857 } else if (val <= 0xffff) {
3858 len = 2;
3859 u16 = htons(val)(__uint16_t)(__builtin_constant_p(val) ? (__uint16_t)(((__uint16_t
)(val) & 0xffU) << 8 | ((__uint16_t)(val) & 0xff00U
) >> 8) : __swap16md(val))
;
3860 data = &u16;
3861 } else {
3862 len = 4;
3863 u32 = htonl(val)(__uint32_t)(__builtin_constant_p(val) ? (__uint32_t)(((__uint32_t
)(val) & 0xff) << 24 | ((__uint32_t)(val) & 0xff00
) << 8 | ((__uint32_t)(val) & 0xff0000) >> 8 |
((__uint32_t)(val) & 0xff000000) >> 24) : __swap32md
(val))
;
3864 data = &u32;
3865 }
3866
3867 complen = curflow->complen[curflow->type];
3868 comp = realloc(curflow->components[curflow->type],
3869 complen + len + 1);
3870 if (comp == NULL((void *)0)) {
3871 yyerror("out of memory");
3872 return -1;
3873 }
3874
3875 comp[complen++] = component_numop(op, and, len);
3876 memcpy(comp + complen, data, len);
3877 complen += len;
3878 curflow->complen[curflow->type] = complen;
3879 curflow->components[curflow->type] = comp;
3880
3881 return 0;
3882}
3883
3884static int
3885push_unary_numop(enum comp_ops op, long long val)
3886{
3887 return push_numop(op, 0, val);
3888}
3889
3890static int
3891push_binary_numop(enum comp_ops op, long long min, long long max)
3892{
3893 switch (op) {
3894 case OP_RANGE:
3895 if (push_numop(OP_GE, 0, min) == -1)
3896 return -1;
3897 return push_numop(OP_LE, 1, max);
3898 case OP_XRANGE:
3899 if (push_numop(OP_LT, 0, min) == -1)
3900 return -1;
3901 return push_numop(OP_GT, 0, max);
3902 default:
3903 yyerror("unsupported binary flowspec num_op");
3904 return -1;
3905 }
3906}
3907
3908struct icmptypeent {
3909 const char *name;
3910 u_int8_t type;
3911};
3912
3913struct icmpcodeent {
3914 const char *name;
3915 u_int8_t type;
3916 u_int8_t code;
3917};
3918
3919static const struct icmptypeent icmp_type[] = {
3920 { "echoreq", ICMP_ECHO8 },
3921 { "echorep", ICMP_ECHOREPLY0 },
3922 { "unreach", ICMP_UNREACH3 },
3923 { "squench", ICMP_SOURCEQUENCH4 },
3924 { "redir", ICMP_REDIRECT5 },
3925 { "althost", ICMP_ALTHOSTADDR6 },
3926 { "routeradv", ICMP_ROUTERADVERT9 },
3927 { "routersol", ICMP_ROUTERSOLICIT10 },
3928 { "timex", ICMP_TIMXCEED11 },
3929 { "paramprob", ICMP_PARAMPROB12 },
3930 { "timereq", ICMP_TSTAMP13 },
3931 { "timerep", ICMP_TSTAMPREPLY14 },
3932 { "inforeq", ICMP_IREQ15 },
3933 { "inforep", ICMP_IREQREPLY16 },
3934 { "maskreq", ICMP_MASKREQ17 },
3935 { "maskrep", ICMP_MASKREPLY18 },
3936 { "trace", ICMP_TRACEROUTE30 },
3937 { "dataconv", ICMP_DATACONVERR31 },
3938 { "mobredir", ICMP_MOBILE_REDIRECT32 },
3939 { "ipv6-where", ICMP_IPV6_WHEREAREYOU33 },
3940 { "ipv6-here", ICMP_IPV6_IAMHERE34 },
3941 { "mobregreq", ICMP_MOBILE_REGREQUEST35 },
3942 { "mobregrep", ICMP_MOBILE_REGREPLY36 },
3943 { "skip", ICMP_SKIP39 },
3944 { "photuris", ICMP_PHOTURIS40 }
3945};
3946
3947static const struct icmptypeent icmp6_type[] = {
3948 { "unreach", ICMP6_DST_UNREACH1 },
3949 { "toobig", ICMP6_PACKET_TOO_BIG2 },
3950 { "timex", ICMP6_TIME_EXCEEDED3 },
3951 { "paramprob", ICMP6_PARAM_PROB4 },
3952 { "echoreq", ICMP6_ECHO_REQUEST128 },
3953 { "echorep", ICMP6_ECHO_REPLY129 },
3954 { "groupqry", ICMP6_MEMBERSHIP_QUERY130 },
3955 { "listqry", MLD_LISTENER_QUERY130 },
3956 { "grouprep", ICMP6_MEMBERSHIP_REPORT131 },
3957 { "listenrep", MLD_LISTENER_REPORT131 },
3958 { "groupterm", ICMP6_MEMBERSHIP_REDUCTION132 },
3959 { "listendone", MLD_LISTENER_DONE132 },
3960 { "routersol", ND_ROUTER_SOLICIT133 },
3961 { "routeradv", ND_ROUTER_ADVERT134 },
3962 { "neighbrsol", ND_NEIGHBOR_SOLICIT135 },
3963 { "neighbradv", ND_NEIGHBOR_ADVERT136 },
3964 { "redir", ND_REDIRECT137 },
3965 { "routrrenum", ICMP6_ROUTER_RENUMBERING138 },
3966 { "wrureq", ICMP6_WRUREQUEST139 },
3967 { "wrurep", ICMP6_WRUREPLY140 },
3968 { "fqdnreq", ICMP6_FQDN_QUERY139 },
3969 { "fqdnrep", ICMP6_FQDN_REPLY140 },
3970 { "niqry", ICMP6_NI_QUERY139 },
3971 { "nirep", ICMP6_NI_REPLY140 },
3972 { "mtraceresp", MLD_MTRACE_RESP200 },
3973 { "mtrace", MLD_MTRACE201 },
3974 { "listenrepv2", MLDV2_LISTENER_REPORT143 },
3975};
3976
3977static const struct icmpcodeent icmp_code[] = {
3978 { "net-unr", ICMP_UNREACH3, ICMP_UNREACH_NET0 },
3979 { "host-unr", ICMP_UNREACH3, ICMP_UNREACH_HOST1 },
3980 { "proto-unr", ICMP_UNREACH3, ICMP_UNREACH_PROTOCOL2 },
3981 { "port-unr", ICMP_UNREACH3, ICMP_UNREACH_PORT3 },
3982 { "needfrag", ICMP_UNREACH3, ICMP_UNREACH_NEEDFRAG4 },
3983 { "srcfail", ICMP_UNREACH3, ICMP_UNREACH_SRCFAIL5 },
3984 { "net-unk", ICMP_UNREACH3, ICMP_UNREACH_NET_UNKNOWN6 },
3985 { "host-unk", ICMP_UNREACH3, ICMP_UNREACH_HOST_UNKNOWN7 },
3986 { "isolate", ICMP_UNREACH3, ICMP_UNREACH_ISOLATED8 },
3987 { "net-prohib", ICMP_UNREACH3, ICMP_UNREACH_NET_PROHIB9 },
3988 { "host-prohib", ICMP_UNREACH3, ICMP_UNREACH_HOST_PROHIB10 },
3989 { "net-tos", ICMP_UNREACH3, ICMP_UNREACH_TOSNET11 },
3990 { "host-tos", ICMP_UNREACH3, ICMP_UNREACH_TOSHOST12 },
3991 { "filter-prohib", ICMP_UNREACH3, ICMP_UNREACH_FILTER_PROHIB13 },
3992 { "host-preced", ICMP_UNREACH3, ICMP_UNREACH_HOST_PRECEDENCE14 },
3993 { "cutoff-preced", ICMP_UNREACH3, ICMP_UNREACH_PRECEDENCE_CUTOFF15 },
3994 { "redir-net", ICMP_REDIRECT5, ICMP_REDIRECT_NET0 },
3995 { "redir-host", ICMP_REDIRECT5, ICMP_REDIRECT_HOST1 },
3996 { "redir-tos-net", ICMP_REDIRECT5, ICMP_REDIRECT_TOSNET2 },
3997 { "redir-tos-host", ICMP_REDIRECT5, ICMP_REDIRECT_TOSHOST3 },
3998 { "normal-adv", ICMP_ROUTERADVERT9, ICMP_ROUTERADVERT_NORMAL0 },
3999 { "common-adv", ICMP_ROUTERADVERT9, ICMP_ROUTERADVERT_NOROUTE_COMMON16 },
4000 { "transit", ICMP_TIMXCEED11, ICMP_TIMXCEED_INTRANS0 },
4001 { "reassemb", ICMP_TIMXCEED11, ICMP_TIMXCEED_REASS1 },
4002 { "badhead", ICMP_PARAMPROB12, ICMP_PARAMPROB_ERRATPTR0 },
4003 { "optmiss", ICMP_PARAMPROB12, ICMP_PARAMPROB_OPTABSENT1 },
4004 { "badlen", ICMP_PARAMPROB12, ICMP_PARAMPROB_LENGTH2 },
4005 { "unknown-ind", ICMP_PHOTURIS40, ICMP_PHOTURIS_UNKNOWN_INDEX1 },
4006 { "auth-fail", ICMP_PHOTURIS40, ICMP_PHOTURIS_AUTH_FAILED2 },
4007 { "decrypt-fail", ICMP_PHOTURIS40, ICMP_PHOTURIS_DECRYPT_FAILED3 }
4008};
4009
4010static const struct icmpcodeent icmp6_code[] = {
4011 { "admin-unr", ICMP6_DST_UNREACH1, ICMP6_DST_UNREACH_ADMIN1 },
4012 { "noroute-unr", ICMP6_DST_UNREACH1, ICMP6_DST_UNREACH_NOROUTE0 },
4013 { "beyond-unr", ICMP6_DST_UNREACH1, ICMP6_DST_UNREACH_BEYONDSCOPE2 },
4014 { "addr-unr", ICMP6_DST_UNREACH1, ICMP6_DST_UNREACH_ADDR3 },
4015 { "port-unr", ICMP6_DST_UNREACH1, ICMP6_DST_UNREACH_NOPORT4 },
4016 { "transit", ICMP6_TIME_EXCEEDED3, ICMP6_TIME_EXCEED_TRANSIT0 },
4017 { "reassemb", ICMP6_TIME_EXCEEDED3, ICMP6_TIME_EXCEED_REASSEMBLY1 },
4018 { "badhead", ICMP6_PARAM_PROB4, ICMP6_PARAMPROB_HEADER0 },
4019 { "nxthdr", ICMP6_PARAM_PROB4, ICMP6_PARAMPROB_NEXTHEADER1 },
4020 { "redironlink", ND_REDIRECT137, ND_REDIRECT_ONLINK0 },
4021 { "redirrouter", ND_REDIRECT137, ND_REDIRECT_ROUTER1 }
4022};
4023
4024static int
4025geticmptypebyname(char *w, uint8_t aid)
4026{
4027 size_t i;
4028
4029 switch (aid) {
4030 case AID_INET1:
4031 for (i = 0; i < nitems(icmp_type)(sizeof((icmp_type)) / sizeof((icmp_type)[0])); i++) {
4032 if (!strcmp(w, icmp_type[i].name))
4033 return (icmp_type[i].type);
4034 }
4035 break;
4036 case AID_INET62:
4037 for (i = 0; i < nitems(icmp6_type)(sizeof((icmp6_type)) / sizeof((icmp6_type)[0])); i++) {
4038 if (!strcmp(w, icmp6_type[i].name))
4039 return (icmp6_type[i].type);
4040 }
4041 break;
4042 }
4043 return -1;
4044}
4045
4046static int
4047geticmpcodebyname(u_long type, char *w, uint8_t aid)
4048{
4049 size_t i;
4050
4051 switch (aid) {
4052 case AID_INET1:
4053 for (i = 0; i < nitems(icmp_code)(sizeof((icmp_code)) / sizeof((icmp_code)[0])); i++) {
4054 if (type == icmp_code[i].type &&
4055 !strcmp(w, icmp_code[i].name))
4056 return (icmp_code[i].code);
4057 }
4058 break;
4059 case AID_INET62:
4060 for (i = 0; i < nitems(icmp6_code)(sizeof((icmp6_code)) / sizeof((icmp6_code)[0])); i++) {
4061 if (type == icmp6_code[i].type &&
4062 !strcmp(w, icmp6_code[i].name))
4063 return (icmp6_code[i].code);
4064 }
4065 break;
4066 }
4067 return -1;
4068}
4069#line 4062 "parse.c"
4070/* allocate initial stack or double stack size, up to YYMAXDEPTH */
4071static int yygrowstack(void)
4072{
4073 unsigned int newsize;
4074 long sslen;
4075 short *newss;
4076 YYSTYPE *newvs;
4077
4078 if ((newsize = yystacksize) == 0)
4079 newsize = YYINITSTACKSIZE200;
4080 else if (newsize >= YYMAXDEPTH10000)
4081 return -1;
4082 else if ((newsize *= 2) > YYMAXDEPTH10000)
4083 newsize = YYMAXDEPTH10000;
4084 sslen = yyssp - yyss;
4085#ifdef SIZE_MAX0xffffffffffffffffUL
4086#define YY_SIZE_MAX0xffffffffffffffffUL SIZE_MAX0xffffffffffffffffUL
4087#else
4088#define YY_SIZE_MAX0xffffffffffffffffUL 0xffffffffU
4089#endif
4090 if (newsize && YY_SIZE_MAX0xffffffffffffffffUL / newsize < sizeof *newss)
4091 goto bail;
4092 newss = (short *)realloc(yyss, newsize * sizeof *newss);
4093 if (newss == NULL((void *)0))
4094 goto bail;
4095 yyss = newss;
4096 yyssp = newss + sslen;
4097 if (newsize && YY_SIZE_MAX0xffffffffffffffffUL / newsize < sizeof *newvs)
4098 goto bail;
4099 newvs = (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs);
4100 if (newvs == NULL((void *)0))
4101 goto bail;
4102 yyvs = newvs;
4103 yyvsp = newvs + sslen;
4104 yystacksize = newsize;
4105 yysslim = yyss + newsize - 1;
4106 return 0;
4107bail:
4108 if (yyss)
4109 free(yyss);
4110 if (yyvs)
4111 free(yyvs);
4112 yyss = yyssp = NULL((void *)0);
4113 yyvs = yyvsp = NULL((void *)0);
4114 yystacksize = 0;
4115 return -1;
4116}
4117
4118#define YYABORTgoto yyabort goto yyabort
4119#define YYREJECTgoto yyabort goto yyabort
4120#define YYACCEPTgoto yyaccept goto yyaccept
4121#define YYERRORgoto yyerrlab goto yyerrlab
4122int
4123yyparse(void)
4124{
4125 int yym, yyn, yystate;
4126#if YYDEBUG0
4127 const char *yys;
4128
4129 if ((yys = getenv("YYDEBUG")))
4130 {
4131 yyn = *yys;
4132 if (yyn >= '0' && yyn <= '9')
4133 yydebug = yyn - '0';
4134 }
4135#endif /* YYDEBUG */
4136
4137 yynerrs = 0;
4138 yyerrflag = 0;
4139 yychar = (-1);
4140
4141 if (yyss == NULL((void *)0) && yygrowstack()) goto yyoverflow;
4142 yyssp = yyss;
4143 yyvsp = yyvs;
4144 *yyssp = yystate = 0;
4145
4146yyloop:
4147 if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
4148 if (yychar < 0)
4149 {
4150 if ((yychar = yylex()) < 0) yychar = 0;
4151#if YYDEBUG0
4152 if (yydebug)
4153 {
4154 yys = 0;
4155 if (yychar <= YYMAXTOKEN401) yys = yyname[yychar];
4156 if (!yys) yys = "illegal-symbol";
4157 printf("%sdebug: state %d, reading %d (%s)\n",
4158 YYPREFIX"yy", yystate, yychar, yys);
4159 }
4160#endif
4161 }
4162 if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
4163 yyn <= YYTABLESIZE1630 && yycheck[yyn] == yychar)
4164 {
4165#if YYDEBUG0
4166 if (yydebug)
4167 printf("%sdebug: state %d, shifting to state %d\n",
4168 YYPREFIX"yy", yystate, yytable[yyn]);
4169#endif
4170 if (yyssp >= yysslim && yygrowstack())
4171 {
4172 goto yyoverflow;
4173 }
4174 *++yyssp = yystate = yytable[yyn];
4175 *++yyvsp = yylval;
4176 yychar = (-1);
4177 if (yyerrflag > 0) --yyerrflag;
4178 goto yyloop;
4179 }
4180 if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
4181 yyn <= YYTABLESIZE1630 && yycheck[yyn] == yychar)
4182 {
4183 yyn = yytable[yyn];
4184 goto yyreduce;
4185 }
4186 if (yyerrflag) goto yyinrecovery;
4187#if defined(__GNUC__4)
4188 goto yynewerror;
4189#endif
4190yynewerror:
4191 yyerror("syntax error");
4192#if defined(__GNUC__4)
4193 goto yyerrlab;
4194#endif
4195yyerrlab:
4196 ++yynerrs;
4197yyinrecovery:
4198 if (yyerrflag < 3)
4199 {
4200 yyerrflag = 3;
4201 for (;;)
4202 {
4203 if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE256) >= 0 &&
4204 yyn <= YYTABLESIZE1630 && yycheck[yyn] == YYERRCODE256)
4205 {
4206#if YYDEBUG0
4207 if (yydebug)
4208 printf("%sdebug: state %d, error recovery shifting\
4209 to state %d\n", YYPREFIX"yy", *yyssp, yytable[yyn]);
4210#endif
4211 if (yyssp >= yysslim && yygrowstack())
4212 {
4213 goto yyoverflow;
4214 }
4215 *++yyssp = yystate = yytable[yyn];
4216 *++yyvsp = yylval;
4217 goto yyloop;
4218 }
4219 else
4220 {
4221#if YYDEBUG0
4222 if (yydebug)
4223 printf("%sdebug: error recovery discarding state %d\n",
4224 YYPREFIX"yy", *yyssp);
4225#endif
4226 if (yyssp <= yyss) goto yyabort;
4227 --yyssp;
4228 --yyvsp;
4229 }
4230 }
4231 }
4232 else
4233 {
4234 if (yychar == 0) goto yyabort;
4235#if YYDEBUG0
4236 if (yydebug)
4237 {
4238 yys = 0;
4239 if (yychar <= YYMAXTOKEN401) yys = yyname[yychar];
4240 if (!yys) yys = "illegal-symbol";
4241 printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
4242 YYPREFIX"yy", yystate, yychar, yys);
4243 }
4244#endif
4245 yychar = (-1);
4246 goto yyloop;
4247 }
4248yyreduce:
4249#if YYDEBUG0
4250 if (yydebug)
4251 printf("%sdebug: state %d, reducing by rule %d (%s)\n",
4252 YYPREFIX"yy", yystate, yyn, yyrule[yyn]);
4253#endif
4254 yym = yylen[yyn];
4255 if (yym)
4256 yyval = yyvsp[1-yym];
4257 else
4258 memset(&yyval, 0, sizeof yyval);
4259 switch (yyn)
4260 {
4261case 20:
4262#line 318 "/usr/src/usr.sbin/bgpd/parse.y"
4263{ file->errors++; }
4264break;
4265case 21:
4266#line 321 "/usr/src/usr.sbin/bgpd/parse.y"
4267{
4268 /*
4269 * According to iana 65535 and 4294967295 are reserved
4270 * but enforcing this is not duty of the parser.
4271 */
4272 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > UINT_MAX0xffffffffU) {
4273 yyerror("AS too big: max %u", UINT_MAX0xffffffffU);
4274 YYERRORgoto yyerrlab;
4275 }
4276 }
4277break;
4278case 22:
4279#line 332 "/usr/src/usr.sbin/bgpd/parse.y"
4280{
4281 const char *errstr;
4282 char *dot;
4283 uint32_t uvalh = 0, uval;
4284
4285 if ((dot = strchr(yyvsp[0].v.string,'.')) != NULL((void *)0)) {
4286 *dot++ = '\0';
4287 uvalh = strtonum(yyvsp[0].v.string, 0, USHRT_MAX0xffff, &errstr);
4288 if (errstr) {
4289 yyerror("number %s is %s", yyvsp[0].v.string, errstr);
4290 free(yyvsp[0].v.string);
4291 YYERRORgoto yyerrlab;
4292 }
4293 uval = strtonum(dot, 0, USHRT_MAX0xffff, &errstr);
4294 if (errstr) {
4295 yyerror("number %s is %s", dot, errstr);
4296 free(yyvsp[0].v.string);
4297 YYERRORgoto yyerrlab;
4298 }
4299 free(yyvsp[0].v.string);
4300 } else {
4301 yyerror("AS %s is bad", yyvsp[0].v.string);
4302 free(yyvsp[0].v.string);
4303 YYERRORgoto yyerrlab;
4304 }
4305 if (uvalh == 0 && (uval == AS_TRANS23456 || uval == 0)) {
4306 yyerror("AS %u is reserved and may not be used",
4307 uval);
4308 YYERRORgoto yyerrlab;
4309 }
4310 yyval.v.number = uval | (uvalh << 16);
4311 }
4312break;
4313case 23:
4314#line 364 "/usr/src/usr.sbin/bgpd/parse.y"
4315{
4316 if (yyvsp[0].v.number == AS_TRANS23456 || yyvsp[0].v.number == 0) {
4317 yyerror("AS %u is reserved and may not be used",
4318 (uint32_t)yyvsp[0].v.number);
4319 YYERRORgoto yyerrlab;
4320 }
4321 yyval.v.number = yyvsp[0].v.number;
4322 }
4323break;
4324case 24:
4325#line 374 "/usr/src/usr.sbin/bgpd/parse.y"
4326{
4327 const char *errstr;
4328 char *dot;
4329 uint32_t uvalh = 0, uval;
4330
4331 if ((dot = strchr(yyvsp[0].v.string,'.')) != NULL((void *)0)) {
4332 *dot++ = '\0';
4333 uvalh = strtonum(yyvsp[0].v.string, 0, USHRT_MAX0xffff, &errstr);
4334 if (errstr) {
4335 yyerror("number %s is %s", yyvsp[0].v.string, errstr);
4336 free(yyvsp[0].v.string);
4337 YYERRORgoto yyerrlab;
4338 }
4339 uval = strtonum(dot, 0, USHRT_MAX0xffff, &errstr);
4340 if (errstr) {
4341 yyerror("number %s is %s", dot, errstr);
4342 free(yyvsp[0].v.string);
4343 YYERRORgoto yyerrlab;
4344 }
4345 free(yyvsp[0].v.string);
4346 } else {
4347 yyerror("AS %s is bad", yyvsp[0].v.string);
4348 free(yyvsp[0].v.string);
4349 YYERRORgoto yyerrlab;
4350 }
4351 yyval.v.number = uval | (uvalh << 16);
4352 }
4353break;
4354case 25:
4355#line 401 "/usr/src/usr.sbin/bgpd/parse.y"
4356{
4357 yyval.v.number = yyvsp[0].v.number;
4358 }
4359break;
4360case 26:
4361#line 406 "/usr/src/usr.sbin/bgpd/parse.y"
4362{
4363 if (asprintf(&yyval.v.string, "%s %s", yyvsp[-1].v.string, yyvsp[0].v.string) == -1)
4364 fatal("string: asprintf");
4365 free(yyvsp[-1].v.string);
4366 free(yyvsp[0].v.string);
4367 }
4368break;
4369case 28:
4370#line 415 "/usr/src/usr.sbin/bgpd/parse.y"
4371{
4372 if (!strcmp(yyvsp[0].v.string, "yes"))
4373 yyval.v.number = 1;
4374 else if (!strcmp(yyvsp[0].v.string, "no"))
4375 yyval.v.number = 0;
4376 else {
4377 yyerror("syntax error, "
4378 "either yes or no expected");
4379 free(yyvsp[0].v.string);
4380 YYERRORgoto yyerrlab;
4381 }
4382 free(yyvsp[0].v.string);
4383 }
4384break;
4385case 29:
4386#line 430 "/usr/src/usr.sbin/bgpd/parse.y"
4387{
4388 char *s = yyvsp[-2].v.string;
4389 if (strlen(yyvsp[-2].v.string) >= MACRO_NAME_LEN128) {
4390 yyerror("macro name to long, max %d characters",
4391 MACRO_NAME_LEN128 - 1);
4392 free(yyvsp[-2].v.string);
4393 free(yyvsp[0].v.string);
4394 YYERRORgoto yyerrlab;
4395 }
4396 do {
4397 if (isalnum((unsigned char)*s) || *s == '_')
4398 continue;
4399 yyerror("macro name can only contain "
4400 "alphanumerics and '_'");
4401 free(yyvsp[-2].v.string);
4402 free(yyvsp[0].v.string);
4403 YYERRORgoto yyerrlab;
4404 } while (*++s);
4405
4406 if (cmd_opts & BGPD_OPT_VERBOSE0x0001)
4407 printf("%s = \"%s\"\n", yyvsp[-2].v.string, yyvsp[0].v.string);
4408 if (symset(yyvsp[-2].v.string, yyvsp[0].v.string, 0) == -1)
4409 fatal("cannot store variable");
4410 free(yyvsp[-2].v.string);
4411 free(yyvsp[0].v.string);
4412 }
4413break;
4414case 30:
4415#line 458 "/usr/src/usr.sbin/bgpd/parse.y"
4416{
4417 struct file *nfile;
4418
4419 if ((nfile = pushfile(yyvsp[0].v.string, 1)) == NULL((void *)0)) {
4420 yyerror("failed to include file %s", yyvsp[0].v.string);
4421 free(yyvsp[0].v.string);
4422 YYERRORgoto yyerrlab;
4423 }
4424 free(yyvsp[0].v.string);
4425
4426 file = nfile;
4427 lungetc('\n');
4428 }
4429break;
4430case 31:
4431#line 473 "/usr/src/usr.sbin/bgpd/parse.y"
4432{
4433 if (strlen(yyvsp[-2].v.string) >= SET_NAME_LEN128) {
4434 yyerror("as-set name %s too long", yyvsp[-2].v.string);
4435 free(yyvsp[-2].v.string);
4436 YYERRORgoto yyerrlab;
4437 }
4438 if (new_as_set(yyvsp[-2].v.string) != 0) {
4439 free(yyvsp[-2].v.string);
4440 YYERRORgoto yyerrlab;
4441 }
4442 free(yyvsp[-2].v.string);
4443 }
4444break;
4445case 32:
4446#line 484 "/usr/src/usr.sbin/bgpd/parse.y"
4447{
4448 done_as_set();
4449 }
4450break;
4451case 33:
4452#line 487 "/usr/src/usr.sbin/bgpd/parse.y"
4453{
4454 if (new_as_set(yyvsp[-3].v.string) != 0) {
4455 free(yyvsp[-3].v.string);
4456 YYERRORgoto yyerrlab;
4457 }
4458 free(yyvsp[-3].v.string);
4459 }
4460break;
4461case 34:
4462#line 495 "/usr/src/usr.sbin/bgpd/parse.y"
4463{ add_as_set(yyvsp[0].v.number); }
4464break;
4465case 35:
4466#line 496 "/usr/src/usr.sbin/bgpd/parse.y"
4467{ add_as_set(yyvsp[0].v.number); }
4468break;
4469case 36:
4470#line 498 "/usr/src/usr.sbin/bgpd/parse.y"
4471{
4472 if ((curpset = new_prefix_set(yyvsp[-2].v.string, 0)) == NULL((void *)0)) {
4473 free(yyvsp[-2].v.string);
4474 YYERRORgoto yyerrlab;
4475 }
4476 free(yyvsp[-2].v.string);
4477 }
4478break;
4479case 37:
4480#line 504 "/usr/src/usr.sbin/bgpd/parse.y"
4481{
4482 SIMPLEQ_INSERT_TAIL(&conf->prefixsets, curpset, entry)do { (curpset)->entry.sqe_next = ((void *)0); *(&conf->
prefixsets)->sqh_last = (curpset); (&conf->prefixsets
)->sqh_last = &(curpset)->entry.sqe_next; } while (
0)
;
4483 curpset = NULL((void *)0);
4484 }
4485break;
4486case 38:
4487#line 508 "/usr/src/usr.sbin/bgpd/parse.y"
4488{
4489 if ((curpset = new_prefix_set(yyvsp[-3].v.string, 0)) == NULL((void *)0)) {
4490 free(yyvsp[-3].v.string);
4491 YYERRORgoto yyerrlab;
4492 }
4493 free(yyvsp[-3].v.string);
4494 SIMPLEQ_INSERT_TAIL(&conf->prefixsets, curpset, entry)do { (curpset)->entry.sqe_next = ((void *)0); *(&conf->
prefixsets)->sqh_last = (curpset); (&conf->prefixsets
)->sqh_last = &(curpset)->entry.sqe_next; } while (
0)
;
4495 curpset = NULL((void *)0);
4496 }
4497break;
4498case 39:
4499#line 518 "/usr/src/usr.sbin/bgpd/parse.y"
4500{
4501 struct prefixset_item *psi;
4502 if (yyvsp[0].v.prefixset_item->p.op != OP_NONE)
4503 curpset->sflags |= PREFIXSET_FLAG_OPS0x04;
4504 psi = RB_INSERT(prefixset_tree, &curpset->psitems, yyvsp[0].v.prefixset_item)prefixset_tree_RB_INSERT(&curpset->psitems, yyvsp[0].v
.prefixset_item)
;
4505 if (psi != NULL((void *)0)) {
4506 if (cmd_opts & BGPD_OPT_VERBOSE20x0002)
4507 log_warnx("warning: duplicate entry in "
4508 "prefixset \"%s\" for %s/%u",
4509 curpset->name,
4510 log_addr(&yyvsp[0].v.prefixset_item->p.addr), yyvsp[0].v.prefixset_item->p.len);
4511 free(yyvsp[0].v.prefixset_item);
4512 }
4513 }
4514break;
4515case 40:
4516#line 532 "/usr/src/usr.sbin/bgpd/parse.y"
4517{
4518 struct prefixset_item *psi;
4519 if (yyvsp[0].v.prefixset_item->p.op != OP_NONE)
4520 curpset->sflags |= PREFIXSET_FLAG_OPS0x04;
4521 psi = RB_INSERT(prefixset_tree, &curpset->psitems, yyvsp[0].v.prefixset_item)prefixset_tree_RB_INSERT(&curpset->psitems, yyvsp[0].v
.prefixset_item)
;
4522 if (psi != NULL((void *)0)) {
4523 if (cmd_opts & BGPD_OPT_VERBOSE20x0002)
4524 log_warnx("warning: duplicate entry in "
4525 "prefixset \"%s\" for %s/%u",
4526 curpset->name,
4527 log_addr(&yyvsp[0].v.prefixset_item->p.addr), yyvsp[0].v.prefixset_item->p.len);
4528 free(yyvsp[0].v.prefixset_item);
4529 }
4530 }
4531break;
4532case 41:
4533#line 548 "/usr/src/usr.sbin/bgpd/parse.y"
4534{
4535 if (yyvsp[0].v.prefixlen.op != OP_NONE && yyvsp[0].v.prefixlen.op != OP_RANGE) {
4536 yyerror("unsupported prefixlen operation in "
4537 "prefix-set");
4538 YYERRORgoto yyerrlab;
4539 }
4540 if ((yyval.v.prefixset_item = calloc(1, sizeof(*yyval.v.prefixset_item))) == NULL((void *)0))
4541 fatal(NULL((void *)0));
4542 memcpy(&yyval.v.prefixset_item->p.addr, &yyvsp[-1].v.prefix.prefix, sizeof(yyval.v.prefixset_item->p.addr));
4543 yyval.v.prefixset_item->p.len = yyvsp[-1].v.prefix.len;
4544 if (merge_prefixspec(&yyval.v.prefixset_item->p, &yyvsp[0].v.prefixlen) == -1) {
4545 free(yyval.v.prefixset_item);
4546 YYERRORgoto yyerrlab;
4547 }
4548 }
4549break;
4550case 42:
4551#line 565 "/usr/src/usr.sbin/bgpd/parse.y"
4552{
4553 curroatree = &conf->roa;
4554 }
4555break;
4556case 43:
4557#line 567 "/usr/src/usr.sbin/bgpd/parse.y"
4558{
4559 curroatree = NULL((void *)0);
4560 }
4561break;
4562case 45:
4563#line 573 "/usr/src/usr.sbin/bgpd/parse.y"
4564{
4565 if ((curoset = new_prefix_set(yyvsp[-2].v.string, 1)) == NULL((void *)0)) {
4566 free(yyvsp[-2].v.string);
4567 YYERRORgoto yyerrlab;
4568 }
4569 curroatree = &curoset->roaitems;
4570 noexpires = 1;
4571 free(yyvsp[-2].v.string);
4572 }
4573break;
4574case 46:
4575#line 581 "/usr/src/usr.sbin/bgpd/parse.y"
4576{
4577 SIMPLEQ_INSERT_TAIL(&conf->originsets, curoset, entry)do { (curoset)->entry.sqe_next = ((void *)0); *(&conf->
originsets)->sqh_last = (curoset); (&conf->originsets
)->sqh_last = &(curoset)->entry.sqe_next; } while (
0)
;
4578 curoset = NULL((void *)0);
4579 curroatree = NULL((void *)0);
4580 noexpires = 0;
4581 }
4582break;
4583case 47:
4584#line 587 "/usr/src/usr.sbin/bgpd/parse.y"
4585{
4586 if ((curoset = new_prefix_set(yyvsp[-3].v.string, 1)) == NULL((void *)0)) {
4587 free(yyvsp[-3].v.string);
4588 YYERRORgoto yyerrlab;
4589 }
4590 free(yyvsp[-3].v.string);
4591 SIMPLEQ_INSERT_TAIL(&conf->originsets, curoset, entry)do { (curoset)->entry.sqe_next = ((void *)0); *(&conf->
originsets)->sqh_last = (curoset); (&conf->originsets
)->sqh_last = &(curoset)->entry.sqe_next; } while (
0)
;
4592 curoset = NULL((void *)0);
4593 curroatree = NULL((void *)0);
4594 }
4595break;
4596case 48:
4597#line 599 "/usr/src/usr.sbin/bgpd/parse.y"
4598{
4599 yyval.v.number = 0;
4600 }
4601break;
4602case 49:
4603#line 602 "/usr/src/usr.sbin/bgpd/parse.y"
4604{
4605 if (noexpires) {
4606 yyerror("syntax error, expires not allowed");
4607 YYERRORgoto yyerrlab;
4608 }
4609 yyval.v.number = yyvsp[0].v.number;
4610 }
4611break;
4612case 50:
4613#line 610 "/usr/src/usr.sbin/bgpd/parse.y"
4614{
4615 if (yyvsp[-3].v.prefixset_item->p.len_min != yyvsp[-3].v.prefixset_item->p.len) {
4616 yyerror("unsupported prefixlen operation in "
4617 "roa-set");
4618 free(yyvsp[-3].v.prefixset_item);
4619 YYERRORgoto yyerrlab;
4620 }
4621 add_roa_set(yyvsp[-3].v.prefixset_item, yyvsp[-1].v.number, yyvsp[-3].v.prefixset_item->p.len_max, yyvsp[0].v.number);
4622 free(yyvsp[-3].v.prefixset_item);
4623 }
4624break;
4625case 51:
4626#line 620 "/usr/src/usr.sbin/bgpd/parse.y"
4627{
4628 if (yyvsp[-3].v.prefixset_item->p.len_min != yyvsp[-3].v.prefixset_item->p.len) {
4629 yyerror("unsupported prefixlen operation in "
4630 "roa-set");
4631 free(yyvsp[-3].v.prefixset_item);
4632 YYERRORgoto yyerrlab;
4633 }
4634 add_roa_set(yyvsp[-3].v.prefixset_item, yyvsp[-1].v.number, yyvsp[-3].v.prefixset_item->p.len_max, yyvsp[0].v.number);
4635 free(yyvsp[-3].v.prefixset_item);
4636 }
4637break;
4638case 56:
4639#line 641 "/usr/src/usr.sbin/bgpd/parse.y"
4640{
4641 int rv;
4642 struct aspa_tas_l *a, *n;
4643
4644 rv = merge_aspa_set(yyvsp[-7].v.number, yyvsp[-2].v.aspa_elm, yyvsp[-6].v.number);
4645
4646 for (a = yyvsp[-2].v.aspa_elm; a != NULL((void *)0); a = n) {
4647 n = a->next;
4648 free(a);
4649 }
4650
4651 if (rv == -1)
4652 YYERRORgoto yyerrlab;
4653 }
4654break;
4655case 57:
4656#line 657 "/usr/src/usr.sbin/bgpd/parse.y"
4657{ yyval.v.aspa_elm = yyvsp[0].v.aspa_elm; }
4658break;
4659case 58:
4660#line 658 "/usr/src/usr.sbin/bgpd/parse.y"
4661{
4662 yyvsp[0].v.aspa_elm->next = yyvsp[-2].v.aspa_elm;
4663 yyvsp[0].v.aspa_elm->num = yyvsp[-2].v.aspa_elm->num + 1;
4664 yyval.v.aspa_elm = yyvsp[0].v.aspa_elm;
4665 }
4666break;
4667case 59:
4668#line 665 "/usr/src/usr.sbin/bgpd/parse.y"
4669{
4670 if ((yyval.v.aspa_elm = calloc(1, sizeof(*yyval.v.aspa_elm))) == NULL((void *)0))
4671 fatal(NULL((void *)0));
4672 yyval.v.aspa_elm->as = yyvsp[0].v.number;
4673 yyval.v.aspa_elm->num = 1;
4674 }
4675break;
4676case 60:
4677#line 671 "/usr/src/usr.sbin/bgpd/parse.y"
4678{
4679 if ((yyval.v.aspa_elm = calloc(1, sizeof(*yyval.v.aspa_elm))) == NULL((void *)0))
4680 fatal(NULL((void *)0));
4681 yyval.v.aspa_elm->as = yyvsp[-1].v.number;
4682 yyval.v.aspa_elm->num = 1;
4683 }
4684break;
4685case 61:
4686#line 679 "/usr/src/usr.sbin/bgpd/parse.y"
4687{
4688 currtr = get_rtr(&yyvsp[0].v.addr);
4689 currtr->remote_port = RTR_PORT323;
4690 if (insert_rtr(currtr) == -1) {
4691 free(currtr);
4692 YYERRORgoto yyerrlab;
4693 }
4694 currtr = NULL((void *)0);
4695 }
4696break;
4697case 62:
4698#line 688 "/usr/src/usr.sbin/bgpd/parse.y"
4699{
4700 currtr = get_rtr(&yyvsp[0].v.addr);
4701 currtr->remote_port = RTR_PORT323;
4702 }
4703break;
4704case 63:
4705#line 691 "/usr/src/usr.sbin/bgpd/parse.y"
4706{
4707 if (insert_rtr(currtr) == -1) {
4708 free(currtr);
4709 YYERRORgoto yyerrlab;
4710 }
4711 currtr = NULL((void *)0);
4712 }
4713break;
4714case 66:
4715#line 704 "/usr/src/usr.sbin/bgpd/parse.y"
4716{
4717 if (strlcpy(currtr->descr, yyvsp[0].v.string,
4718 sizeof(currtr->descr)) >=
4719 sizeof(currtr->descr)) {
4720 yyerror("descr \"%s\" too long: max %zu",
4721 yyvsp[0].v.string, sizeof(currtr->descr) - 1);
4722 free(yyvsp[0].v.string);
4723 YYERRORgoto yyerrlab;
4724 }
4725 free(yyvsp[0].v.string);
4726 }
4727break;
4728case 67:
4729#line 715 "/usr/src/usr.sbin/bgpd/parse.y"
4730{
4731 if (yyvsp[0].v.addr.aid != currtr->remote_addr.aid) {
4732 yyerror("Bad address family %s for "
4733 "local-addr", aid2str(yyvsp[0].v.addr.aid));
4734 YYERRORgoto yyerrlab;
4735 }
4736 currtr->local_addr = yyvsp[0].v.addr;
4737 }
4738break;
4739case 68:
4740#line 723 "/usr/src/usr.sbin/bgpd/parse.y"
4741{
4742 currtr->remote_port = yyvsp[0].v.number;
4743 }
4744break;
4745case 69:
4746#line 728 "/usr/src/usr.sbin/bgpd/parse.y"
4747{
4748 conf->as = yyvsp[0].v.number;
4749 if (yyvsp[0].v.number > USHRT_MAX0xffff)
4750 conf->short_as = AS_TRANS23456;
4751 else
4752 conf->short_as = yyvsp[0].v.number;
4753 }
4754break;
4755case 70:
4756#line 735 "/usr/src/usr.sbin/bgpd/parse.y"
4757{
4758 conf->as = yyvsp[-1].v.number;
4759 conf->short_as = yyvsp[0].v.number;
4760 }
4761break;
4762case 71:
4763#line 739 "/usr/src/usr.sbin/bgpd/parse.y"
4764{
4765 if (yyvsp[0].v.addr.aid != AID_INET1) {
4766 yyerror("router-id must be an IPv4 address");
4767 YYERRORgoto yyerrlab;
4768 }
4769 conf->bgpid = yyvsp[0].v.addr.v4ba.v4.s_addr;
4770 }
4771break;
4772case 72:
4773#line 746 "/usr/src/usr.sbin/bgpd/parse.y"
4774{
4775 if (yyvsp[0].v.number < MIN_HOLDTIME3 || yyvsp[0].v.number > USHRT_MAX0xffff) {
4776 yyerror("holdtime must be between %u and %u",
4777 MIN_HOLDTIME3, USHRT_MAX0xffff);
4778 YYERRORgoto yyerrlab;
4779 }
4780 conf->holdtime = yyvsp[0].v.number;
4781 }
4782break;
4783case 73:
4784#line 754 "/usr/src/usr.sbin/bgpd/parse.y"
4785{
4786 if (yyvsp[0].v.number < MIN_HOLDTIME3 || yyvsp[0].v.number > USHRT_MAX0xffff) {
4787 yyerror("holdtime must be between %u and %u",
4788 MIN_HOLDTIME3, USHRT_MAX0xffff);
4789 YYERRORgoto yyerrlab;
4790 }
4791 conf->min_holdtime = yyvsp[0].v.number;
4792 }
4793break;
4794case 74:
4795#line 762 "/usr/src/usr.sbin/bgpd/parse.y"
4796{
4797 struct listen_addr *la;
4798 struct sockaddr *sa;
4799
4800 if ((la = calloc(1, sizeof(struct listen_addr))) ==
4801 NULL((void *)0))
4802 fatal("parse conf_main listen on calloc");
4803
4804 la->fd = -1;
4805 la->reconf = RECONF_REINIT;
4806 sa = addr2sa(&yyvsp[0].v.addr, BGP_PORT179, &la->sa_len);
4807 memcpy(&la->sa, sa, la->sa_len);
4808 TAILQ_INSERT_TAIL(conf->listen_addrs, la, entry)do { (la)->entry.tqe_next = ((void *)0); (la)->entry.tqe_prev
= (conf->listen_addrs)->tqh_last; *(conf->listen_addrs
)->tqh_last = (la); (conf->listen_addrs)->tqh_last =
&(la)->entry.tqe_next; } while (0)
;
4809 }
4810break;
4811case 75:
4812#line 776 "/usr/src/usr.sbin/bgpd/parse.y"
4813{
4814 struct listen_addr *la;
4815 struct sockaddr *sa;
4816
4817 if ((la = calloc(1, sizeof(struct listen_addr))) ==
4818 NULL((void *)0))
4819 fatal("parse conf_main listen on calloc");
4820
4821 la->fd = -1;
4822 la->reconf = RECONF_REINIT;
4823 sa = addr2sa(&yyvsp[-2].v.addr, yyvsp[0].v.number, &la->sa_len);
4824 memcpy(&la->sa, sa, la->sa_len);
4825 TAILQ_INSERT_TAIL(conf->listen_addrs, la, entry)do { (la)->entry.tqe_next = ((void *)0); (la)->entry.tqe_prev
= (conf->listen_addrs)->tqh_last; *(conf->listen_addrs
)->tqh_last = (la); (conf->listen_addrs)->tqh_last =
&(la)->entry.tqe_next; } while (0)
;
4826 }
4827break;
4828case 76:
4829#line 790 "/usr/src/usr.sbin/bgpd/parse.y"
4830{
4831 if (!kr_check_prio(yyvsp[0].v.number)) {
4832 yyerror("fib-priority %lld out of range", yyvsp[0].v.number);
4833 YYERRORgoto yyerrlab;
4834 }
4835 conf->fib_priority = yyvsp[0].v.number;
4836 }
4837break;
4838case 77:
4839#line 797 "/usr/src/usr.sbin/bgpd/parse.y"
4840{
4841 struct rde_rib *rr;
4842 rr = find_rib("Loc-RIB");
4843 if (rr == NULL((void *)0))
4844 fatalx("RTABLE cannot find the main RIB!");
4845
4846 if (yyvsp[0].v.number == 0)
4847 rr->flags |= F_RIB_NOFIBSYNC0x0008;
4848 else
4849 rr->flags &= ~F_RIB_NOFIBSYNC0x0008;
4850 }
4851break;
4852case 78:
4853#line 808 "/usr/src/usr.sbin/bgpd/parse.y"
4854{
4855 if (yyvsp[0].v.number == 1)
4856 conf->flags |= BGPD_FLAG_DECISION_TRANS_AS0x0200;
4857 else
4858 conf->flags &= ~BGPD_FLAG_DECISION_TRANS_AS0x0200;
4859 }
4860break;
4861case 79:
4862#line 814 "/usr/src/usr.sbin/bgpd/parse.y"
4863{
4864 if (yyvsp[0].v.number == 1)
4865 conf->flags |= BGPD_FLAG_NO_AS_SET0x1000;
4866 else
4867 conf->flags &= ~BGPD_FLAG_NO_AS_SET0x1000;
4868 }
4869break;
4870case 80:
4871#line 820 "/usr/src/usr.sbin/bgpd/parse.y"
4872{
4873 if (!strcmp(yyvsp[0].v.string, "updates"))
4874 conf->log |= BGPD_LOG_UPDATES0x0001;
4875 else {
4876 free(yyvsp[0].v.string);
4877 YYERRORgoto yyerrlab;
4878 }
4879 free(yyvsp[0].v.string);
4880 }
4881break;
4882case 81:
4883#line 829 "/usr/src/usr.sbin/bgpd/parse.y"
4884{
4885 int action;
4886
4887 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX0x7fffffff) {
4888 yyerror("bad timeout");
4889 free(yyvsp[-2].v.string);
4890 free(yyvsp[-1].v.string);
4891 YYERRORgoto yyerrlab;
4892 }
4893 if (!strcmp(yyvsp[-2].v.string, "table"))
4894 action = MRT_TABLE_DUMP;
4895 else if (!strcmp(yyvsp[-2].v.string, "table-mp"))
4896 action = MRT_TABLE_DUMP_MP;
4897 else if (!strcmp(yyvsp[-2].v.string, "table-v2"))
4898 action = MRT_TABLE_DUMP_V2;
4899 else {
4900 yyerror("unknown mrt dump type");
4901 free(yyvsp[-2].v.string);
4902 free(yyvsp[-1].v.string);
4903 YYERRORgoto yyerrlab;
4904 }
4905 free(yyvsp[-2].v.string);
4906 if (add_mrtconfig(action, yyvsp[-1].v.string, yyvsp[0].v.number, NULL((void *)0), NULL((void *)0)) == -1) {
4907 free(yyvsp[-1].v.string);
4908 YYERRORgoto yyerrlab;
4909 }
4910 free(yyvsp[-1].v.string);
4911 }
4912break;
4913case 82:
4914#line 857 "/usr/src/usr.sbin/bgpd/parse.y"
4915{
4916 int action;
4917
4918 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX0x7fffffff) {
4919 yyerror("bad timeout");
4920 free(yyvsp[-3].v.string);
4921 free(yyvsp[-2].v.string);
4922 free(yyvsp[-1].v.string);
4923 YYERRORgoto yyerrlab;
4924 }
4925 if (!strcmp(yyvsp[-2].v.string, "table"))
4926 action = MRT_TABLE_DUMP;
4927 else if (!strcmp(yyvsp[-2].v.string, "table-mp"))
4928 action = MRT_TABLE_DUMP_MP;
4929 else if (!strcmp(yyvsp[-2].v.string, "table-v2"))
4930 action = MRT_TABLE_DUMP_V2;
4931 else {
4932 yyerror("unknown mrt dump type");
4933 free(yyvsp[-3].v.string);
4934 free(yyvsp[-2].v.string);
4935 free(yyvsp[-1].v.string);
4936 YYERRORgoto yyerrlab;
4937 }
4938 free(yyvsp[-2].v.string);
4939 if (add_mrtconfig(action, yyvsp[-1].v.string, yyvsp[0].v.number, NULL((void *)0), yyvsp[-3].v.string) == -1) {
4940 free(yyvsp[-3].v.string);
4941 free(yyvsp[-1].v.string);
4942 YYERRORgoto yyerrlab;
4943 }
4944 free(yyvsp[-3].v.string);
4945 free(yyvsp[-1].v.string);
4946 }
4947break;
4948case 83:
4949#line 889 "/usr/src/usr.sbin/bgpd/parse.y"
4950{
4951 if (!strcmp(yyvsp[-1].v.string, "route-age"))
4952 conf->flags |= BGPD_FLAG_DECISION_ROUTEAGE0x0100;
4953 else {
4954 yyerror("unknown route decision type");
4955 free(yyvsp[-1].v.string);
4956 YYERRORgoto yyerrlab;
4957 }
4958 free(yyvsp[-1].v.string);
4959 }
4960break;
4961case 84:
4962#line 899 "/usr/src/usr.sbin/bgpd/parse.y"
4963{
4964 if (!strcmp(yyvsp[-1].v.string, "route-age"))
4965 conf->flags &= ~BGPD_FLAG_DECISION_ROUTEAGE0x0100;
4966 else {
4967 yyerror("unknown route decision type");
4968 free(yyvsp[-1].v.string);
4969 YYERRORgoto yyerrlab;
4970 }
4971 free(yyvsp[-1].v.string);
4972 }
4973break;
4974case 85:
4975#line 909 "/usr/src/usr.sbin/bgpd/parse.y"
4976{
4977 if (!strcmp(yyvsp[0].v.string, "always"))
4978 conf->flags |= BGPD_FLAG_DECISION_MED_ALWAYS0x0400;
4979 else if (!strcmp(yyvsp[0].v.string, "strict"))
4980 conf->flags &= ~BGPD_FLAG_DECISION_MED_ALWAYS0x0400;
4981 else {
4982 yyerror("rde med compare: "
4983 "unknown setting \"%s\"", yyvsp[0].v.string);
4984 free(yyvsp[0].v.string);
4985 YYERRORgoto yyerrlab;
4986 }
4987 free(yyvsp[0].v.string);
4988 }
4989break;
4990case 86:
4991#line 922 "/usr/src/usr.sbin/bgpd/parse.y"
4992{
4993 if (!strcmp(yyvsp[0].v.string, "all"))
4994 conf->flags |= BGPD_FLAG_DECISION_ALL_PATHS0x0800;
4995 else if (!strcmp(yyvsp[0].v.string, "default"))
4996 conf->flags &= ~BGPD_FLAG_DECISION_ALL_PATHS0x0800;
4997 else {
4998 yyerror("rde evaluate: "
4999 "unknown setting \"%s\"", yyvsp[0].v.string);
5000 free(yyvsp[0].v.string);
5001 YYERRORgoto yyerrlab;
5002 }
5003 free(yyvsp[0].v.string);
5004 }
5005break;
5006case 87:
5007#line 935 "/usr/src/usr.sbin/bgpd/parse.y"
5008{
5009 if (!strcmp(yyvsp[0].v.string, "bgp"))
5010 conf->flags |= BGPD_FLAG_NEXTHOP_BGP0x0010;
5011 else if (!strcmp(yyvsp[0].v.string, "default"))
5012 conf->flags |= BGPD_FLAG_NEXTHOP_DEFAULT0x0020;
5013 else {
5014 yyerror("nexthop depend on: "
5015 "unknown setting \"%s\"", yyvsp[0].v.string);
5016 free(yyvsp[0].v.string);
5017 YYERRORgoto yyerrlab;
5018 }
5019 free(yyvsp[0].v.string);
5020 }
5021break;
5022case 88:
5023#line 948 "/usr/src/usr.sbin/bgpd/parse.y"
5024{
5025 struct rde_rib *rr;
5026 if (yyvsp[0].v.number > RT_TABLEID_MAX255) {
5027 yyerror("rtable %llu too big: max %u", yyvsp[0].v.number,
5028 RT_TABLEID_MAX255);
5029 YYERRORgoto yyerrlab;
5030 }
5031 if (!ktable_exists(yyvsp[0].v.number, NULL((void *)0))) {
5032 yyerror("rtable id %lld does not exist", yyvsp[0].v.number);
5033 YYERRORgoto yyerrlab;
5034 }
5035 rr = find_rib("Loc-RIB");
5036 if (rr == NULL((void *)0))
5037 fatalx("RTABLE cannot find the main RIB!");
5038 rr->rtableid = yyvsp[0].v.number;
5039 }
5040break;
5041case 89:
5042#line 964 "/usr/src/usr.sbin/bgpd/parse.y"
5043{
5044 if (yyvsp[0].v.number > USHRT_MAX0xffff || yyvsp[0].v.number < 1) {
5045 yyerror("invalid connect-retry");
5046 YYERRORgoto yyerrlab;
5047 }
5048 conf->connectretry = yyvsp[0].v.number;
5049 }
5050break;
5051case 90:
5052#line 971 "/usr/src/usr.sbin/bgpd/parse.y"
5053{
5054 if (strlen(yyvsp[-1].v.string) >=
5055 sizeof(((struct sockaddr_un *)0)->sun_path)) {
5056 yyerror("socket path too long");
5057 YYERRORgoto yyerrlab;
5058 }
5059 if (yyvsp[0].v.number) {
5060 free(conf->rcsock);
5061 conf->rcsock = yyvsp[-1].v.string;
5062 } else {
5063 free(conf->csock);
5064 conf->csock = yyvsp[-1].v.string;
5065 }
5066 }
5067break;
5068case 91:
5069#line 987 "/usr/src/usr.sbin/bgpd/parse.y"
5070{
5071 if ((currib = add_rib(yyvsp[0].v.string)) == NULL((void *)0)) {
5072 free(yyvsp[0].v.string);
5073 YYERRORgoto yyerrlab;
5074 }
5075 free(yyvsp[0].v.string);
5076 }
5077break;
5078case 92:
5079#line 993 "/usr/src/usr.sbin/bgpd/parse.y"
5080{
5081 currib = NULL((void *)0);
5082 }
5083break;
5084case 94:
5085#line 998 "/usr/src/usr.sbin/bgpd/parse.y"
5086{
5087 if (yyvsp[-1].v.number > RT_TABLEID_MAX255) {
5088 yyerror("rtable %llu too big: max %u", yyvsp[-1].v.number,
5089 RT_TABLEID_MAX255);
5090 YYERRORgoto yyerrlab;
5091 }
5092 if (rib_add_fib(currib, yyvsp[-1].v.number) == -1)
5093 YYERRORgoto yyerrlab;
5094 }
5095break;
5096case 95:
5097#line 1007 "/usr/src/usr.sbin/bgpd/parse.y"
5098{
5099 if (yyvsp[-1].v.number) {
5100 yyerror("bad rde rib definition");
5101 YYERRORgoto yyerrlab;
5102 }
5103 currib->flags |= F_RIB_NOEVALUATE0x0002;
5104 }
5105break;
5106case 97:
5107#line 1017 "/usr/src/usr.sbin/bgpd/parse.y"
5108{
5109 if (yyvsp[0].v.number == 0)
5110 currib->flags |= F_RIB_NOFIBSYNC0x0008;
5111 else
5112 currib->flags &= ~F_RIB_NOFIBSYNC0x0008;
5113 }
5114break;
5115case 98:
5116#line 1025 "/usr/src/usr.sbin/bgpd/parse.y"
5117{
5118 int action;
5119
5120 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX0x7fffffff) {
5121 yyerror("bad timeout");
5122 free(yyvsp[-3].v.string);
5123 free(yyvsp[-1].v.string);
5124 YYERRORgoto yyerrlab;
5125 }
5126 if (!strcmp(yyvsp[-3].v.string, "all"))
5127 action = yyvsp[-2].v.number ? MRT_ALL_IN : MRT_ALL_OUT;
5128 else if (!strcmp(yyvsp[-3].v.string, "updates"))
5129 action = yyvsp[-2].v.number ? MRT_UPDATE_IN : MRT_UPDATE_OUT;
5130 else {
5131 yyerror("unknown mrt msg dump type");
5132 free(yyvsp[-3].v.string);
5133 free(yyvsp[-1].v.string);
5134 YYERRORgoto yyerrlab;
5135 }
5136 if (add_mrtconfig(action, yyvsp[-1].v.string, yyvsp[0].v.number, curpeer, NULL((void *)0)) ==
5137 -1) {
5138 free(yyvsp[-3].v.string);
5139 free(yyvsp[-1].v.string);
5140 YYERRORgoto yyerrlab;
5141 }
5142 free(yyvsp[-3].v.string);
5143 free(yyvsp[-1].v.string);
5144 }
5145break;
5146case 99:
5147#line 1055 "/usr/src/usr.sbin/bgpd/parse.y"
5148{
5149 struct network *n, *m;
5150
5151 if ((n = calloc(1, sizeof(struct network))) == NULL((void *)0))
5152 fatal("new_network");
5153 memcpy(&n->net.prefix, &yyvsp[-1].v.prefix.prefix,
5154 sizeof(n->net.prefix));
5155 n->net.prefixlen = yyvsp[-1].v.prefix.len;
5156 filterset_move(yyvsp[0].v.filter_set_head, &n->net.attrset);
5157 free(yyvsp[0].v.filter_set_head);
5158 TAILQ_FOREACH(m, netconf, entry)for((m) = ((netconf)->tqh_first); (m) != ((void *)0); (m) =
((m)->entry.tqe_next))
{
5159 if (n->net.type == m->net.type &&
5160 n->net.prefixlen == m->net.prefixlen &&
5161 prefix_compare(&n->net.prefix,
5162 &m->net.prefix, n->net.prefixlen) == 0)
5163 yyerror("duplicate prefix "
5164 "in network statement");
5165 }
5166
5167 TAILQ_INSERT_TAIL(netconf, n, entry)do { (n)->entry.tqe_next = ((void *)0); (n)->entry.tqe_prev
= (netconf)->tqh_last; *(netconf)->tqh_last = (n); (netconf
)->tqh_last = &(n)->entry.tqe_next; } while (0)
;
5168 }
5169break;
5170case 100:
5171#line 1076 "/usr/src/usr.sbin/bgpd/parse.y"
5172{
5173 struct prefixset *ps;
5174 struct network *n;
5175 if ((ps = find_prefixset(yyvsp[-1].v.string, &conf->prefixsets))
5176 == NULL((void *)0)) {
5177 yyerror("prefix-set '%s' not defined", yyvsp[-1].v.string);
5178 free(yyvsp[-1].v.string);
5179 filterset_free(yyvsp[0].v.filter_set_head);
5180 free(yyvsp[0].v.filter_set_head);
5181 YYERRORgoto yyerrlab;
5182 }
5183 if (ps->sflags & PREFIXSET_FLAG_OPS0x04) {
5184 yyerror("prefix-set %s has prefixlen operators "
5185 "and cannot be used in network statements.",
5186 ps->name);
5187 free(yyvsp[-1].v.string);
5188 filterset_free(yyvsp[0].v.filter_set_head);
5189 free(yyvsp[0].v.filter_set_head);
5190 YYERRORgoto yyerrlab;
5191 }
5192 if ((n = calloc(1, sizeof(struct network))) == NULL((void *)0))
5193 fatal("new_network");
5194 strlcpy(n->net.psname, ps->name, sizeof(n->net.psname));
5195 filterset_move(yyvsp[0].v.filter_set_head, &n->net.attrset);
5196 n->net.type = NETWORK_PREFIXSET;
5197 TAILQ_INSERT_TAIL(netconf, n, entry)do { (n)->entry.tqe_next = ((void *)0); (n)->entry.tqe_prev
= (netconf)->tqh_last; *(netconf)->tqh_last = (n); (netconf
)->tqh_last = &(n)->entry.tqe_next; } while (0)
;
5198 free(yyvsp[-1].v.string);
5199 free(yyvsp[0].v.filter_set_head);
5200 }
5201break;
5202case 101:
5203#line 1105 "/usr/src/usr.sbin/bgpd/parse.y"
5204{
5205 struct network *n;
5206
5207 if ((n = calloc(1, sizeof(struct network))) == NULL((void *)0))
5208 fatal("new_network");
5209 if (afi2aid(yyvsp[-3].v.number, SAFI_UNICAST1, &n->net.prefix.aid) ==
5210 -1) {
5211 yyerror("unknown address family");
5212 filterset_free(yyvsp[0].v.filter_set_head);
5213 free(yyvsp[0].v.filter_set_head);
5214 YYERRORgoto yyerrlab;
5215 }
5216 n->net.type = NETWORK_RTLABEL;
5217 n->net.rtlabel = rtlabel_name2id(yyvsp[-1].v.string);
5218 filterset_move(yyvsp[0].v.filter_set_head, &n->net.attrset);
5219 free(yyvsp[0].v.filter_set_head);
5220
5221 TAILQ_INSERT_TAIL(netconf, n, entry)do { (n)->entry.tqe_next = ((void *)0); (n)->entry.tqe_prev
= (netconf)->tqh_last; *(netconf)->tqh_last = (n); (netconf
)->tqh_last = &(n)->entry.tqe_next; } while (0)
;
5222 }
5223break;
5224case 102:
5225#line 1124 "/usr/src/usr.sbin/bgpd/parse.y"
5226{
5227 struct network *n;
5228 if (!kr_check_prio(yyvsp[-1].v.number)) {
5229 yyerror("priority %lld out of range", yyvsp[-1].v.number);
5230 YYERRORgoto yyerrlab;
5231 }
5232
5233 if ((n = calloc(1, sizeof(struct network))) == NULL((void *)0))
5234 fatal("new_network");
5235 if (afi2aid(yyvsp[-3].v.number, SAFI_UNICAST1, &n->net.prefix.aid) ==
5236 -1) {
5237 yyerror("unknown address family");
5238 filterset_free(yyvsp[0].v.filter_set_head);
5239 free(yyvsp[0].v.filter_set_head);
5240 YYERRORgoto yyerrlab;
5241 }
5242 n->net.type = NETWORK_PRIORITY;
5243 n->net.priority = yyvsp[-1].v.number;
5244 filterset_move(yyvsp[0].v.filter_set_head, &n->net.attrset);
5245 free(yyvsp[0].v.filter_set_head);
5246
5247 TAILQ_INSERT_TAIL(netconf, n, entry)do { (n)->entry.tqe_next = ((void *)0); (n)->entry.tqe_prev
= (netconf)->tqh_last; *(netconf)->tqh_last = (n); (netconf
)->tqh_last = &(n)->entry.tqe_next; } while (0)
;
5248 }
5249break;
5250case 103:
5251#line 1147 "/usr/src/usr.sbin/bgpd/parse.y"
5252{
5253 struct network *n;
5254
5255 if ((n = calloc(1, sizeof(struct network))) == NULL((void *)0))
5256 fatal("new_network");
5257 if (afi2aid(yyvsp[-2].v.number, SAFI_UNICAST1, &n->net.prefix.aid) ==
5258 -1) {
5259 yyerror("unknown address family");
5260 filterset_free(yyvsp[0].v.filter_set_head);
5261 free(yyvsp[0].v.filter_set_head);
5262 YYERRORgoto yyerrlab;
5263 }
5264 n->net.type = yyvsp[-1].v.number ? NETWORK_STATIC : NETWORK_CONNECTED;
5265 filterset_move(yyvsp[0].v.filter_set_head, &n->net.attrset);
5266 free(yyvsp[0].v.filter_set_head);
5267
5268 TAILQ_INSERT_TAIL(netconf, n, entry)do { (n)->entry.tqe_next = ((void *)0); (n)->entry.tqe_prev
= (netconf)->tqh_last; *(netconf)->tqh_last = (n); (netconf
)->tqh_last = &(n)->entry.tqe_next; } while (0)
;
5269 }
5270break;
5271case 104:
5272#line 1167 "/usr/src/usr.sbin/bgpd/parse.y"
5273{
5274 if ((curflow = calloc(1, sizeof(*curflow))) == NULL((void *)0))
5275 fatal("new_flowspec");
5276 curflow->aid = yyvsp[0].v.number;
5277 }
5278break;
5279case 105:
5280#line 1171 "/usr/src/usr.sbin/bgpd/parse.y"
5281{
5282 struct flowspec_config *f;
5283
5284 f = flow_to_flowspec(curflow);
5285 if (f == NULL((void *)0)) {
5286 yyerror("out of memory");
5287 free(yyvsp[0].v.filter_set_head);
5288 flow_free(curflow);
5289 curflow = NULL((void *)0);
5290 YYERRORgoto yyerrlab;
5291 }
5292 filterset_move(yyvsp[0].v.filter_set_head, &f->attrset);
5293 free(yyvsp[0].v.filter_set_head);
5294 flow_free(curflow);
5295 curflow = NULL((void *)0);
5296
5297 if (RB_INSERT(flowspec_tree, &conf->flowspecs, f)flowspec_tree_RB_INSERT(&conf->flowspecs, f) !=
5298 NULL((void *)0)) {
5299 yyerror("duplicate flowspec definition");
5300 flowspec_free(f);
5301 YYERRORgoto yyerrlab;
5302 }
5303 }
5304break;
5305case 108:
5306#line 1200 "/usr/src/usr.sbin/bgpd/parse.y"
5307{
5308 curflow->type = FLOWSPEC_TYPE_PROTO3;
5309 if (push_unary_numop(OP_EQ, yyvsp[0].v.number) == -1)
5310 YYERRORgoto yyerrlab;
5311 }
5312break;
5313case 109:
5314#line 1205 "/usr/src/usr.sbin/bgpd/parse.y"
5315{
5316 curflow->type = FLOWSPEC_TYPE_PROTO3;
5317 if (push_unary_numop(OP_EQ, yyvsp[0].v.number) == -1)
5318 YYERRORgoto yyerrlab;
5319 }
5320break;
5321case 110:
5322#line 1212 "/usr/src/usr.sbin/bgpd/parse.y"
5323{
5324 struct protoent *p;
5325
5326 p = getprotobyname(yyvsp[0].v.string);
5327 if (p == NULL((void *)0)) {
5328 yyerror("unknown protocol %s", yyvsp[0].v.string);
5329 free(yyvsp[0].v.string);
5330 YYERRORgoto yyerrlab;
5331 }
5332 yyval.v.number = p->p_proto;
5333 free(yyvsp[0].v.string);
5334 }
5335break;
5336case 111:
5337#line 1224 "/usr/src/usr.sbin/bgpd/parse.y"
5338{
5339 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > 255) {
5340 yyerror("protocol outside range");
5341 YYERRORgoto yyerrlab;
5342 }
5343 yyval.v.number = yyvsp[0].v.number;
5344 }
5345break;
5346case 112:
5347#line 1233 "/usr/src/usr.sbin/bgpd/parse.y"
5348{
5349 curflow->type = FLOWSPEC_TYPE_SRC_PORT6;
5350 curflow->addr_type = FLOWSPEC_TYPE_SOURCE2;
5351 }
5352break;
5353case 114:
5354#line 1239 "/usr/src/usr.sbin/bgpd/parse.y"
5355{
5356 curflow->type = FLOWSPEC_TYPE_DST_PORT5;
5357 curflow->addr_type = FLOWSPEC_TYPE_DEST1;
5358 }
5359break;
5360case 120:
5361#line 1251 "/usr/src/usr.sbin/bgpd/parse.y"
5362{
5363 if (push_prefix(&yyvsp[0].v.prefix.prefix, yyvsp[0].v.prefix.len) == -1)
5364 YYERRORgoto yyerrlab;
5365 }
5366break;
5367case 125:
5368#line 1265 "/usr/src/usr.sbin/bgpd/parse.y"
5369{
5370 if (push_unary_numop(OP_EQ, yyvsp[0].v.number) == -1)
5371 YYERRORgoto yyerrlab;
5372 }
5373break;
5374case 126:
5375#line 1269 "/usr/src/usr.sbin/bgpd/parse.y"
5376{
5377 if (push_unary_numop(yyvsp[-1].v.u8, yyvsp[0].v.number) == -1)
5378 YYERRORgoto yyerrlab;
5379 }
5380break;
5381case 127:
5382#line 1273 "/usr/src/usr.sbin/bgpd/parse.y"
5383{
5384 if (push_binary_numop(yyvsp[-1].v.u8, yyvsp[-2].v.number, yyvsp[0].v.number))
5385 YYERRORgoto yyerrlab;
5386 }
5387break;
5388case 128:
5389#line 1279 "/usr/src/usr.sbin/bgpd/parse.y"
5390{
5391 if (yyvsp[0].v.number < 1 || yyvsp[0].v.number > USHRT_MAX0xffff) {
5392 yyerror("port must be between %u and %u",
5393 1, USHRT_MAX0xffff);
5394 YYERRORgoto yyerrlab;
5395 }
5396 yyval.v.number = yyvsp[0].v.number;
5397 }
5398break;
5399case 129:
5400#line 1287 "/usr/src/usr.sbin/bgpd/parse.y"
5401{
5402 if ((yyval.v.number = getservice(yyvsp[0].v.string)) == -1) {
5403 yyerror("unknown port '%s'", yyvsp[0].v.string);
5404 free(yyvsp[0].v.string);
5405 YYERRORgoto yyerrlab;
5406 }
5407 free(yyvsp[0].v.string);
5408 }
5409break;
5410case 136:
5411#line 1307 "/usr/src/usr.sbin/bgpd/parse.y"
5412{
5413 curflow->type = FLOWSPEC_TYPE_TCP_FLAGS9;
5414 }
5415break;
5416case 138:
5417#line 1310 "/usr/src/usr.sbin/bgpd/parse.y"
5418{
5419 curflow->type = FLOWSPEC_TYPE_FRAG12;
5420 }
5421break;
5422case 141:
5423#line 1314 "/usr/src/usr.sbin/bgpd/parse.y"
5424{
5425 curflow->type = FLOWSPEC_TYPE_PKT_LEN10;
5426 }
5427break;
5428case 143:
5429#line 1318 "/usr/src/usr.sbin/bgpd/parse.y"
5430{
5431 curflow->type = FLOWSPEC_TYPE_DSCP11;
5432 if (push_unary_numop(OP_EQ, yyvsp[0].v.number >> 2) == -1)
5433 YYERRORgoto yyerrlab;
5434 }
5435break;
5436case 144:
5437#line 1325 "/usr/src/usr.sbin/bgpd/parse.y"
5438{
5439 if ((yyvsp[-2].v.number & yyvsp[0].v.number) != yyvsp[-2].v.number) {
5440 yyerror("bad flag combination, "
5441 "check bit not in mask");
5442 YYERRORgoto yyerrlab;
5443 }
5444 if (push_binop(FLOWSPEC_OP_BIT_MATCH0x01, yyvsp[-2].v.number) == -1)
5445 YYERRORgoto yyerrlab;
5446 /* check if extra mask op is needed */
5447 if (yyvsp[0].v.number & ~yyvsp[-2].v.number) {
5448 if (push_binop(FLOWSPEC_OP_BIT_NOT0x02 |
5449 FLOWSPEC_OP_AND0x40, yyvsp[0].v.number & ~yyvsp[-2].v.number) == -1)
5450 YYERRORgoto yyerrlab;
5451 }
5452 }
5453break;
5454case 145:
5455#line 1340 "/usr/src/usr.sbin/bgpd/parse.y"
5456{
5457 if (push_binop(FLOWSPEC_OP_BIT_NOT0x02, yyvsp[0].v.number) == -1)
5458 YYERRORgoto yyerrlab;
5459 }
5460break;
5461case 146:
5462#line 1344 "/usr/src/usr.sbin/bgpd/parse.y"
5463{
5464 if (push_binop(0, yyvsp[0].v.number) == -1)
5465 YYERRORgoto yyerrlab;
5466 }
5467break;
5468case 148:
5469#line 1351 "/usr/src/usr.sbin/bgpd/parse.y"
5470{
5471 if ((yyval.v.number = parse_flags(yyvsp[0].v.string)) < 0) {
5472 yyerror("bad flags %s", yyvsp[0].v.string);
5473 free(yyvsp[0].v.string);
5474 YYERRORgoto yyerrlab;
5475 }
5476 free(yyvsp[0].v.string);
5477 }
5478break;
5479case 153:
5480#line 1369 "/usr/src/usr.sbin/bgpd/parse.y"
5481{
5482 curflow->type = FLOWSPEC_TYPE_ICMP_TYPE7;
5483 if (push_unary_numop(OP_EQ, yyvsp[0].v.number) == -1)
5484 YYERRORgoto yyerrlab;
5485 }
5486break;
5487case 154:
5488#line 1374 "/usr/src/usr.sbin/bgpd/parse.y"
5489{
5490 int code;
5491
5492 if ((code = geticmpcodebyname(yyvsp[-2].v.number, yyvsp[0].v.string, curflow->aid)) ==
5493 -1) {
5494 yyerror("unknown icmp-code %s", yyvsp[0].v.string);
5495 free(yyvsp[0].v.string);
5496 YYERRORgoto yyerrlab;
5497 }
5498 free(yyvsp[0].v.string);
5499
5500 curflow->type = FLOWSPEC_TYPE_ICMP_TYPE7;
5501 if (push_unary_numop(OP_EQ, yyvsp[-2].v.number) == -1)
5502 YYERRORgoto yyerrlab;
5503 curflow->type = FLOWSPEC_TYPE_ICMP_CODE8;
5504 if (push_unary_numop(OP_EQ, code) == -1)
5505 YYERRORgoto yyerrlab;
5506 }
5507break;
5508case 155:
5509#line 1392 "/usr/src/usr.sbin/bgpd/parse.y"
5510{
5511 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > 255) {
5512 yyerror("illegal icmp-code %lld", yyvsp[0].v.number);
5513 YYERRORgoto yyerrlab;
5514 }
5515 curflow->type = FLOWSPEC_TYPE_ICMP_TYPE7;
5516 if (push_unary_numop(OP_EQ, yyvsp[-2].v.number) == -1)
5517 YYERRORgoto yyerrlab;
5518 curflow->type = FLOWSPEC_TYPE_ICMP_CODE8;
5519 if (push_unary_numop(OP_EQ, yyvsp[0].v.number) == -1)
5520 YYERRORgoto yyerrlab;
5521 }
5522break;
5523case 156:
5524#line 1406 "/usr/src/usr.sbin/bgpd/parse.y"
5525{
5526 int type;
5527
5528 if ((type = geticmptypebyname(yyvsp[0].v.string, curflow->aid)) ==
5529 -1) {
5530 yyerror("unknown icmp-type %s", yyvsp[0].v.string);
5531 free(yyvsp[0].v.string);
5532 YYERRORgoto yyerrlab;
5533 }
5534 yyval.v.number = type;
5535 free(yyvsp[0].v.string);
5536 }
5537break;
5538case 157:
5539#line 1418 "/usr/src/usr.sbin/bgpd/parse.y"
5540{
5541 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > 255) {
5542 yyerror("illegal icmp-type %lld", yyvsp[0].v.number);
5543 YYERRORgoto yyerrlab;
5544 }
5545 yyval.v.number = yyvsp[0].v.number;
5546 }
5547break;
5548case 158:
5549#line 1427 "/usr/src/usr.sbin/bgpd/parse.y"
5550{
5551 int val;
5552 char *end;
5553
5554 if (map_tos(yyvsp[0].v.string, &val))
5555 yyval.v.number = val;
5556 else if (yyvsp[0].v.string[0] == '0' && yyvsp[0].v.string[1] == 'x') {
5557 errno(*__errno()) = 0;
5558 yyval.v.number = strtoul(yyvsp[0].v.string, &end, 16);
5559 if (errno(*__errno()) || *end != '\0')
5560 yyval.v.number = 256;
5561 } else
5562 yyval.v.number = 256;
5563 if (yyval.v.number < 0 || yyval.v.number > 255) {
5564 yyerror("illegal tos value %s", yyvsp[0].v.string);
5565 free(yyvsp[0].v.string);
5566 YYERRORgoto yyerrlab;
5567 }
5568 free(yyvsp[0].v.string);
5569 }
5570break;
5571case 159:
5572#line 1447 "/usr/src/usr.sbin/bgpd/parse.y"
5573{
5574 if (yyval.v.number < 0 || yyval.v.number > 255) {
5575 yyerror("illegal tos value %lld", yyvsp[0].v.number);
5576 YYERRORgoto yyerrlab;
5577 }
5578 yyval.v.number = yyvsp[0].v.number;
5579 }
5580break;
5581case 164:
5582#line 1464 "/usr/src/usr.sbin/bgpd/parse.y"
5583{
5584 if (push_unary_numop(OP_EQ, yyvsp[0].v.number) == -1)
5585 YYERRORgoto yyerrlab;
5586 }
5587break;
5588case 165:
5589#line 1468 "/usr/src/usr.sbin/bgpd/parse.y"
5590{
5591 if (push_unary_numop(yyvsp[-1].v.u8, yyvsp[0].v.number) == -1)
5592 YYERRORgoto yyerrlab;
5593 }
5594break;
5595case 166:
5596#line 1472 "/usr/src/usr.sbin/bgpd/parse.y"
5597{
5598 if (push_binary_numop(yyvsp[-1].v.u8, yyvsp[-2].v.number, yyvsp[0].v.number) == -1)
5599 YYERRORgoto yyerrlab;
5600 }
5601break;
5602case 167:
5603#line 1478 "/usr/src/usr.sbin/bgpd/parse.y"
5604{
5605 if (yyval.v.number < 0 || yyval.v.number > USHRT_MAX0xffff) {
5606 yyerror("illegal ptk length value %lld", yyvsp[0].v.number);
5607 YYERRORgoto yyerrlab;
5608 }
5609 yyval.v.number = yyvsp[0].v.number;
5610 }
5611break;
5612case 168:
5613#line 1486 "/usr/src/usr.sbin/bgpd/parse.y"
5614{ yyval.v.number = 1; }
5615break;
5616case 169:
5617#line 1487 "/usr/src/usr.sbin/bgpd/parse.y"
5618{ yyval.v.number = 0; }
5619break;
5620case 170:
5621#line 1490 "/usr/src/usr.sbin/bgpd/parse.y"
5622{ yyval.v.number = 0; }
5623break;
5624case 171:
5625#line 1491 "/usr/src/usr.sbin/bgpd/parse.y"
5626{ yyval.v.number = 1; }
5627break;
5628case 172:
5629#line 1494 "/usr/src/usr.sbin/bgpd/parse.y"
5630{
5631 uint8_t len;
5632
5633 if (!host(yyvsp[0].v.string, &yyval.v.addr, &len)) {
5634 yyerror("could not parse address spec \"%s\"",
5635 yyvsp[0].v.string);
5636 free(yyvsp[0].v.string);
5637 YYERRORgoto yyerrlab;
5638 }
5639 free(yyvsp[0].v.string);
5640
5641 if ((yyval.v.addr.aid == AID_INET1 && len != 32) ||
5642 (yyval.v.addr.aid == AID_INET62 && len != 128)) {
5643 /* unreachable */
5644 yyerror("got prefixlen %u, expected %u",
5645 len, yyval.v.addr.aid == AID_INET1 ? 32 : 128);
5646 YYERRORgoto yyerrlab;
5647 }
5648 }
5649break;
5650case 173:
5651#line 1515 "/usr/src/usr.sbin/bgpd/parse.y"
5652{
5653 char *s;
5654 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > 128) {
5655 yyerror("bad prefixlen %lld", yyvsp[0].v.number);
5656 free(yyvsp[-2].v.string);
5657 YYERRORgoto yyerrlab;
5658 }
5659 if (asprintf(&s, "%s/%lld", yyvsp[-2].v.string, yyvsp[0].v.number) == -1)
5660 fatal(NULL((void *)0));
5661 free(yyvsp[-2].v.string);
5662
5663 if (!host(s, &yyval.v.prefix.prefix, &yyval.v.prefix.len)) {
5664 yyerror("could not parse address \"%s\"", s);
5665 free(s);
5666 YYERRORgoto yyerrlab;
5667 }
5668 free(s);
5669 }
5670break;
5671case 174:
5672#line 1533 "/usr/src/usr.sbin/bgpd/parse.y"
5673{
5674 char *s;
5675
5676 /* does not match IPv6 */
5677 if (yyvsp[-2].v.number < 0 || yyvsp[-2].v.number > 255 || yyvsp[0].v.number < 0 || yyvsp[0].v.number > 32) {
5678 yyerror("bad prefix %lld/%lld", yyvsp[-2].v.number, yyvsp[0].v.number);
5679 YYERRORgoto yyerrlab;
5680 }
5681 if (asprintf(&s, "%lld/%lld", yyvsp[-2].v.number, yyvsp[0].v.number) == -1)
5682 fatal(NULL((void *)0));
5683
5684 if (!host(s, &yyval.v.prefix.prefix, &yyval.v.prefix.len)) {
5685 yyerror("could not parse address \"%s\"", s);
5686 free(s);
5687 YYERRORgoto yyerrlab;
5688 }
5689 free(s);
5690 }
5691break;
5692case 175:
5693#line 1553 "/usr/src/usr.sbin/bgpd/parse.y"
5694{
5695 memcpy(&yyval.v.prefix.prefix, &yyvsp[0].v.addr, sizeof(struct bgpd_addr));
5696 if (yyval.v.prefix.prefix.aid == AID_INET1)
5697 yyval.v.prefix.len = 32;
5698 else
5699 yyval.v.prefix.len = 128;
5700 }
5701break;
5702case 177:
5703#line 1563 "/usr/src/usr.sbin/bgpd/parse.y"
5704{ yyval.v.number = 0; }
5705break;
5706case 179:
5707#line 1567 "/usr/src/usr.sbin/bgpd/parse.y"
5708{
5709 u_int rdomain, label;
5710
5711 if (get_mpe_config(yyvsp[0].v.string, &rdomain, &label) == -1) {
5712 if ((cmd_opts & BGPD_OPT_NOACTION0x0004) == 0) {
5713 yyerror("troubles getting config of %s",
5714 yyvsp[0].v.string);
5715 free(yyvsp[0].v.string);
5716 free(yyvsp[-2].v.string);
5717 YYERRORgoto yyerrlab;
5718 }
5719 }
5720
5721 if (!(curvpn = calloc(1, sizeof(struct l3vpn))))
5722 fatal(NULL((void *)0));
5723 strlcpy(curvpn->ifmpe, yyvsp[0].v.string, IFNAMSIZ16);
5724
5725 if (strlcpy(curvpn->descr, yyvsp[-2].v.string,
5726 sizeof(curvpn->descr)) >=
5727 sizeof(curvpn->descr)) {
5728 yyerror("descr \"%s\" too long: max %zu",
5729 yyvsp[-2].v.string, sizeof(curvpn->descr) - 1);
5730 free(yyvsp[-2].v.string);
5731 free(yyvsp[0].v.string);
5732 free(curvpn);
5733 curvpn = NULL((void *)0);
5734 YYERRORgoto yyerrlab;
5735 }
5736 free(yyvsp[-2].v.string);
5737 free(yyvsp[0].v.string);
5738
5739 TAILQ_INIT(&curvpn->import)do { (&curvpn->import)->tqh_first = ((void *)0); (&
curvpn->import)->tqh_last = &(&curvpn->import
)->tqh_first; } while (0)
;
5740 TAILQ_INIT(&curvpn->export)do { (&curvpn->export)->tqh_first = ((void *)0); (&
curvpn->export)->tqh_last = &(&curvpn->export
)->tqh_first; } while (0)
;
5741 TAILQ_INIT(&curvpn->net_l)do { (&curvpn->net_l)->tqh_first = ((void *)0); (&
curvpn->net_l)->tqh_last = &(&curvpn->net_l)
->tqh_first; } while (0)
;
5742 curvpn->label = label;
5743 curvpn->rtableid = rdomain;
5744 netconf = &curvpn->net_l;
5745 }
5746break;
5747case 180:
5748#line 1604 "/usr/src/usr.sbin/bgpd/parse.y"
5749{
5750 /* insert into list */
5751 SIMPLEQ_INSERT_TAIL(&conf->l3vpns, curvpn, entry)do { (curvpn)->entry.sqe_next = ((void *)0); *(&conf->
l3vpns)->sqh_last = (curvpn); (&conf->l3vpns)->sqh_last
= &(curvpn)->entry.sqe_next; } while (0)
;
5752 curvpn = NULL((void *)0);
5753 netconf = &conf->networks;
5754 }
5755break;
5756case 185:
5757#line 1618 "/usr/src/usr.sbin/bgpd/parse.y"
5758{
5759 struct community ext;
5760
5761 memset(&ext, 0, sizeof(ext));
5762 if (parseextcommunity(&ext, "rt", yyvsp[0].v.string) == -1) {
5763 free(yyvsp[0].v.string);
5764 YYERRORgoto yyerrlab;
5765 }
5766 free(yyvsp[0].v.string);
5767 /*
5768 * RD is almost encoded like an ext-community,
5769 * but only almost so convert here.
5770 */
5771 if (community_to_rd(&ext, &curvpn->rd) == -1) {
5772 yyerror("bad encoding of rd");
5773 YYERRORgoto yyerrlab;
5774 }
5775 }
5776break;
5777case 186:
5778#line 1636 "/usr/src/usr.sbin/bgpd/parse.y"
5779{
5780 struct filter_set *set;
5781
5782 if ((set = calloc(1, sizeof(struct filter_set))) ==
5783 NULL((void *)0))
5784 fatal(NULL((void *)0));
5785 set->type = ACTION_SET_COMMUNITY;
5786 if (parseextcommunity(&set->action.community,
5787 yyvsp[-1].v.string, yyvsp[0].v.string) == -1) {
5788 free(yyvsp[0].v.string);
5789 free(yyvsp[-1].v.string);
5790 free(set);
5791 YYERRORgoto yyerrlab;
5792 }
5793 free(yyvsp[0].v.string);
5794 free(yyvsp[-1].v.string);
5795 TAILQ_INSERT_TAIL(&curvpn->export, set, entry)do { (set)->entry.tqe_next = ((void *)0); (set)->entry.
tqe_prev = (&curvpn->export)->tqh_last; *(&curvpn
->export)->tqh_last = (set); (&curvpn->export)->
tqh_last = &(set)->entry.tqe_next; } while (0)
;
5796 }
5797break;
5798case 187:
5799#line 1654 "/usr/src/usr.sbin/bgpd/parse.y"
5800{
5801 struct filter_set *set;
5802
5803 if ((set = calloc(1, sizeof(struct filter_set))) ==
5804 NULL((void *)0))
5805 fatal(NULL((void *)0));
5806 set->type = ACTION_SET_COMMUNITY;
5807 if (parseextcommunity(&set->action.community,
5808 yyvsp[-1].v.string, yyvsp[0].v.string) == -1) {
5809 free(yyvsp[0].v.string);
5810 free(yyvsp[-1].v.string);
5811 free(set);
5812 YYERRORgoto yyerrlab;
5813 }
5814 free(yyvsp[0].v.string);
5815 free(yyvsp[-1].v.string);
5816 TAILQ_INSERT_TAIL(&curvpn->import, set, entry)do { (set)->entry.tqe_next = ((void *)0); (set)->entry.
tqe_prev = (&curvpn->import)->tqh_last; *(&curvpn
->import)->tqh_last = (set); (&curvpn->import)->
tqh_last = &(set)->entry.tqe_next; } while (0)
;
5817 }
5818break;
5819case 188:
5820#line 1672 "/usr/src/usr.sbin/bgpd/parse.y"
5821{
5822 if (yyvsp[0].v.number == 0)
5823 curvpn->flags |= F_RIB_NOFIBSYNC0x0008;
5824 else
5825 curvpn->flags &= ~F_RIB_NOFIBSYNC0x0008;
5826 }
5827break;
5828case 190:
5829#line 1681 "/usr/src/usr.sbin/bgpd/parse.y"
5830{ curpeer = new_peer(); }
5831break;
5832case 191:
5833#line 1682 "/usr/src/usr.sbin/bgpd/parse.y"
5834{
5835 memcpy(&curpeer->conf.remote_addr, &yyvsp[0].v.prefix.prefix,
5836 sizeof(curpeer->conf.remote_addr));
5837 curpeer->conf.remote_masklen = yyvsp[0].v.prefix.len;
5838 if ((yyvsp[0].v.prefix.prefix.aid == AID_INET1 && yyvsp[0].v.prefix.len != 32) ||
5839 (yyvsp[0].v.prefix.prefix.aid == AID_INET62 && yyvsp[0].v.prefix.len != 128))
5840 curpeer->conf.template = 1;
5841 curpeer->conf.capabilities.mp[
5842 curpeer->conf.remote_addr.aid] = 1;
5843 if (get_id(curpeer)) {
5844 yyerror("get_id failed");
5845 YYERRORgoto yyerrlab;
5846 }
5847 }
5848break;
5849case 192:
5850#line 1696 "/usr/src/usr.sbin/bgpd/parse.y"
5851{
5852 if (curpeer_filter[0] != NULL((void *)0))
5853 TAILQ_INSERT_TAIL(peerfilter_l,do { (curpeer_filter[0])->entry.tqe_next = ((void *)0); (curpeer_filter
[0])->entry.tqe_prev = (peerfilter_l)->tqh_last; *(peerfilter_l
)->tqh_last = (curpeer_filter[0]); (peerfilter_l)->tqh_last
= &(curpeer_filter[0])->entry.tqe_next; } while (0)
5854 curpeer_filter[0], entry)do { (curpeer_filter[0])->entry.tqe_next = ((void *)0); (curpeer_filter
[0])->entry.tqe_prev = (peerfilter_l)->tqh_last; *(peerfilter_l
)->tqh_last = (curpeer_filter[0]); (peerfilter_l)->tqh_last
= &(curpeer_filter[0])->entry.tqe_next; } while (0)
;
5855 if (curpeer_filter[1] != NULL((void *)0))
5856 TAILQ_INSERT_TAIL(peerfilter_l,do { (curpeer_filter[1])->entry.tqe_next = ((void *)0); (curpeer_filter
[1])->entry.tqe_prev = (peerfilter_l)->tqh_last; *(peerfilter_l
)->tqh_last = (curpeer_filter[1]); (peerfilter_l)->tqh_last
= &(curpeer_filter[1])->entry.tqe_next; } while (0)
5857 curpeer_filter[1], entry)do { (curpeer_filter[1])->entry.tqe_next = ((void *)0); (curpeer_filter
[1])->entry.tqe_prev = (peerfilter_l)->tqh_last; *(peerfilter_l
)->tqh_last = (curpeer_filter[1]); (peerfilter_l)->tqh_last
= &(curpeer_filter[1])->entry.tqe_next; } while (0)
;
5858 curpeer_filter[0] = NULL((void *)0);
5859 curpeer_filter[1] = NULL((void *)0);
5860
5861 if (neighbor_consistent(curpeer) == -1) {
5862 free(curpeer);
5863 YYERRORgoto yyerrlab;
5864 }
5865 if (RB_INSERT(peer_head, new_peers, curpeer)peer_head_RB_INSERT(new_peers, curpeer) != NULL((void *)0))
5866 fatalx("%s: peer tree is corrupt", __func__);
5867 curpeer = curgroup;
5868 }
5869break;
5870case 193:
5871#line 1716 "/usr/src/usr.sbin/bgpd/parse.y"
5872{
5873 curgroup = curpeer = new_group();
5874 if (strlcpy(curgroup->conf.group, yyvsp[0].v.string,
5875 sizeof(curgroup->conf.group)) >=
5876 sizeof(curgroup->conf.group)) {
5877 yyerror("group name \"%s\" too long: max %zu",
5878 yyvsp[0].v.string, sizeof(curgroup->conf.group) - 1);
5879 free(yyvsp[0].v.string);
5880 free(curgroup);
5881 YYERRORgoto yyerrlab;
5882 }
5883 free(yyvsp[0].v.string);
5884 if (get_id(curgroup)) {
5885 yyerror("get_id failed");
5886 free(curgroup);
5887 YYERRORgoto yyerrlab;
5888 }
5889 }
5890break;
5891case 194:
5892#line 1733 "/usr/src/usr.sbin/bgpd/parse.y"
5893{
5894 if (curgroup_filter[0] != NULL((void *)0))
5895 TAILQ_INSERT_TAIL(groupfilter_l,do { (curgroup_filter[0])->entry.tqe_next = ((void *)0); (
curgroup_filter[0])->entry.tqe_prev = (groupfilter_l)->
tqh_last; *(groupfilter_l)->tqh_last = (curgroup_filter[0]
); (groupfilter_l)->tqh_last = &(curgroup_filter[0])->
entry.tqe_next; } while (0)
5896 curgroup_filter[0], entry)do { (curgroup_filter[0])->entry.tqe_next = ((void *)0); (
curgroup_filter[0])->entry.tqe_prev = (groupfilter_l)->
tqh_last; *(groupfilter_l)->tqh_last = (curgroup_filter[0]
); (groupfilter_l)->tqh_last = &(curgroup_filter[0])->
entry.tqe_next; } while (0)
;
5897 if (curgroup_filter[1] != NULL((void *)0))
5898 TAILQ_INSERT_TAIL(groupfilter_l,do { (curgroup_filter[1])->entry.tqe_next = ((void *)0); (
curgroup_filter[1])->entry.tqe_prev = (groupfilter_l)->
tqh_last; *(groupfilter_l)->tqh_last = (curgroup_filter[1]
); (groupfilter_l)->tqh_last = &(curgroup_filter[1])->
entry.tqe_next; } while (0)
5899 curgroup_filter[1], entry)do { (curgroup_filter[1])->entry.tqe_next = ((void *)0); (
curgroup_filter[1])->entry.tqe_prev = (groupfilter_l)->
tqh_last; *(groupfilter_l)->tqh_last = (curgroup_filter[1]
); (groupfilter_l)->tqh_last = &(curgroup_filter[1])->
entry.tqe_next; } while (0)
;
5900 curgroup_filter[0] = NULL((void *)0);
5901 curgroup_filter[1] = NULL((void *)0);
5902
5903 free(curgroup);
5904 curgroup = NULL((void *)0);
5905 }
5906break;
5907case 200:
5908#line 1755 "/usr/src/usr.sbin/bgpd/parse.y"
5909{ yyval.v.number = 0; }
5910break;
5911case 201:
5912#line 1756 "/usr/src/usr.sbin/bgpd/parse.y"
5913{
5914 if (yyvsp[0].v.number < 1 || yyvsp[0].v.number > USHRT_MAX0xffff) {
5915 yyerror("additional paths must be between "
5916 "%u and %u", 1, USHRT_MAX0xffff);
5917 YYERRORgoto yyerrlab;
5918 }
5919 yyval.v.number = yyvsp[0].v.number;
5920 }
5921break;
5922case 202:
5923#line 1766 "/usr/src/usr.sbin/bgpd/parse.y"
5924{ yyval.v.number = 0; }
5925break;
5926case 203:
5927#line 1767 "/usr/src/usr.sbin/bgpd/parse.y"
5928{
5929 if (yyvsp[0].v.number < 1 || yyvsp[0].v.number > USHRT_MAX0xffff) {
5930 yyerror("maximum additional paths must be "
5931 "between %u and %u", 1, USHRT_MAX0xffff);
5932 YYERRORgoto yyerrlab;
5933 }
5934 yyval.v.number = yyvsp[0].v.number;
5935 }
5936break;
5937case 211:
5938#line 1788 "/usr/src/usr.sbin/bgpd/parse.y"
5939{
5940 curpeer->conf.remote_as = yyvsp[0].v.number;
5941 }
5942break;
5943case 212:
5944#line 1791 "/usr/src/usr.sbin/bgpd/parse.y"
5945{
5946 curpeer->conf.local_as = yyvsp[0].v.number;
5947 if (yyvsp[0].v.number > USHRT_MAX0xffff)
5948 curpeer->conf.local_short_as = AS_TRANS23456;
5949 else
5950 curpeer->conf.local_short_as = yyvsp[0].v.number;
5951 }
5952break;
5953case 213:
5954#line 1798 "/usr/src/usr.sbin/bgpd/parse.y"
5955{
5956 curpeer->conf.local_as = yyvsp[-1].v.number;
5957 curpeer->conf.local_short_as = yyvsp[0].v.number;
5958 }
5959break;
5960case 214:
5961#line 1802 "/usr/src/usr.sbin/bgpd/parse.y"
5962{
5963 if (strlcpy(curpeer->conf.descr, yyvsp[0].v.string,
5964 sizeof(curpeer->conf.descr)) >=
5965 sizeof(curpeer->conf.descr)) {
5966 yyerror("descr \"%s\" too long: max %zu",
5967 yyvsp[0].v.string, sizeof(curpeer->conf.descr) - 1);
5968 free(yyvsp[0].v.string);
5969 YYERRORgoto yyerrlab;
5970 }
5971 free(yyvsp[0].v.string);
5972 }
5973break;
5974case 215:
5975#line 1813 "/usr/src/usr.sbin/bgpd/parse.y"
5976{
5977 if (yyvsp[0].v.addr.aid == AID_INET1)
5978 memcpy(&curpeer->conf.local_addr_v4, &yyvsp[0].v.addr,
5979 sizeof(curpeer->conf.local_addr_v4));
5980 else if (yyvsp[0].v.addr.aid == AID_INET62)
5981 memcpy(&curpeer->conf.local_addr_v6, &yyvsp[0].v.addr,
5982 sizeof(curpeer->conf.local_addr_v6));
5983 else {
5984 yyerror("Unsupported address family %s for "
5985 "local-addr", aid2str(yyvsp[0].v.addr.aid));
5986 YYERRORgoto yyerrlab;
5987 }
5988 }
5989break;
5990case 216:
5991#line 1826 "/usr/src/usr.sbin/bgpd/parse.y"
5992{
5993 if (yyvsp[-1].v.number) {
5994 yyerror("bad local-address definition");
5995 YYERRORgoto yyerrlab;
5996 }
5997 memset(&curpeer->conf.local_addr_v4, 0,
5998 sizeof(curpeer->conf.local_addr_v4));
5999 memset(&curpeer->conf.local_addr_v6, 0,
6000 sizeof(curpeer->conf.local_addr_v6));
6001 }
6002break;
6003case 217:
6004#line 1836 "/usr/src/usr.sbin/bgpd/parse.y"
6005{
6006 if (yyvsp[0].v.number < 2 || yyvsp[0].v.number > 255) {
6007 yyerror("invalid multihop distance %lld", yyvsp[0].v.number);
6008 YYERRORgoto yyerrlab;
6009 }
6010 curpeer->conf.distance = yyvsp[0].v.number;
6011 }
6012break;
6013case 218:
6014#line 1843 "/usr/src/usr.sbin/bgpd/parse.y"
6015{
6016 curpeer->conf.passive = 1;
6017 }
6018break;
6019case 219:
6020#line 1846 "/usr/src/usr.sbin/bgpd/parse.y"
6021{
6022 curpeer->conf.down = 1;
6023 }
6024break;
6025case 220:
6026#line 1849 "/usr/src/usr.sbin/bgpd/parse.y"
6027{
6028 curpeer->conf.down = 1;
6029 if (strlcpy(curpeer->conf.reason, yyvsp[0].v.string,
6030 sizeof(curpeer->conf.reason)) >=
6031 sizeof(curpeer->conf.reason)) {
6032 yyerror("shutdown reason too long");
6033 free(yyvsp[0].v.string);
6034 YYERRORgoto yyerrlab;
6035 }
6036 free(yyvsp[0].v.string);
6037 }
6038break;
6039case 221:
6040#line 1860 "/usr/src/usr.sbin/bgpd/parse.y"
6041{
6042 if (!find_rib(yyvsp[0].v.string)) {
6043 yyerror("rib \"%s\" does not exist.", yyvsp[0].v.string);
6044 free(yyvsp[0].v.string);
6045 YYERRORgoto yyerrlab;
6046 }
6047 if (strlcpy(curpeer->conf.rib, yyvsp[0].v.string,
6048 sizeof(curpeer->conf.rib)) >=
6049 sizeof(curpeer->conf.rib)) {
6050 yyerror("rib name \"%s\" too long: max %zu",
6051 yyvsp[0].v.string, sizeof(curpeer->conf.rib) - 1);
6052 free(yyvsp[0].v.string);
6053 YYERRORgoto yyerrlab;
6054 }
6055 free(yyvsp[0].v.string);
6056 }
6057break;
6058case 222:
6059#line 1876 "/usr/src/usr.sbin/bgpd/parse.y"
6060{
6061 if (yyvsp[0].v.number < MIN_HOLDTIME3 || yyvsp[0].v.number > USHRT_MAX0xffff) {
6062 yyerror("holdtime must be between %u and %u",
6063 MIN_HOLDTIME3, USHRT_MAX0xffff);
6064 YYERRORgoto yyerrlab;
6065 }
6066 curpeer->conf.holdtime = yyvsp[0].v.number;
6067 }
6068break;
6069case 223:
6070#line 1884 "/usr/src/usr.sbin/bgpd/parse.y"
6071{
6072 if (yyvsp[0].v.number < MIN_HOLDTIME3 || yyvsp[0].v.number > USHRT_MAX0xffff) {
6073 yyerror("holdtime must be between %u and %u",
6074 MIN_HOLDTIME3, USHRT_MAX0xffff);
6075 YYERRORgoto yyerrlab;
6076 }
6077 curpeer->conf.min_holdtime = yyvsp[0].v.number;
6078 }
6079break;
6080case 224:
6081#line 1892 "/usr/src/usr.sbin/bgpd/parse.y"
6082{
6083 uint8_t aid, safi;
6084 uint16_t afi;
6085
6086 if (yyvsp[0].v.number == SAFI_NONE0) {
6087 for (aid = 0; aid < AID_MAX7; aid++) {
6088 if (aid2afi(aid, &afi, &safi) == -1 ||
6089 afi != yyvsp[-1].v.number)
6090 continue;
6091 curpeer->conf.capabilities.mp[aid] = 0;
6092 }
6093 } else {
6094 if (afi2aid(yyvsp[-1].v.number, yyvsp[0].v.number, &aid) == -1) {
6095 yyerror("unknown AFI/SAFI pair");
6096 YYERRORgoto yyerrlab;
6097 }
6098 curpeer->conf.capabilities.mp[aid] = 1;
6099 }
6100 }
6101break;
6102case 225:
6103#line 1911 "/usr/src/usr.sbin/bgpd/parse.y"
6104{
6105 curpeer->conf.announce_capa = yyvsp[0].v.number;
6106 }
6107break;
6108case 226:
6109#line 1914 "/usr/src/usr.sbin/bgpd/parse.y"
6110{
6111 curpeer->conf.capabilities.refresh = yyvsp[0].v.number;
6112 }
6113break;
6114case 227:
6115#line 1917 "/usr/src/usr.sbin/bgpd/parse.y"
6116{
6117 curpeer->conf.capabilities.enhanced_rr = yyvsp[0].v.number;
6118 }
6119break;
6120case 228:
6121#line 1920 "/usr/src/usr.sbin/bgpd/parse.y"
6122{
6123 curpeer->conf.capabilities.grestart.restart = yyvsp[0].v.number;
6124 }
6125break;
6126case 229:
6127#line 1923 "/usr/src/usr.sbin/bgpd/parse.y"
6128{
6129 curpeer->conf.capabilities.as4byte = yyvsp[0].v.number;
6130 }
6131break;
6132case 230:
6133#line 1926 "/usr/src/usr.sbin/bgpd/parse.y"
6134{
6135 int8_t *ap = curpeer->conf.capabilities.add_path;
6136 uint8_t i;
6137
6138 for (i = 0; i < AID_MAX7; i++)
6139 if (yyvsp[0].v.number)
6140 *ap++ |= CAPA_AP_RECV0x01;
6141 else
6142 *ap++ &= ~CAPA_AP_RECV0x01;
6143 }
6144break;
6145case 231:
6146#line 1936 "/usr/src/usr.sbin/bgpd/parse.y"
6147{
6148 int8_t *ap = curpeer->conf.capabilities.add_path;
6149 enum addpath_mode mode;
6150 u_int8_t i;
6151
6152 if (!strcmp(yyvsp[-2].v.string, "no")) {
6153 free(yyvsp[-2].v.string);
6154 if (yyvsp[-1].v.number != 0 || yyvsp[0].v.number != 0) {
6155 yyerror("no additional option allowed "
6156 "for 'add-path send no'");
6157 YYERRORgoto yyerrlab;
6158 }
6159 for (i = 0; i < AID_MAX7; i++)
6160 *ap++ &= ~CAPA_AP_SEND0x02;
6161 break;
6162 } else if (!strcmp(yyvsp[-2].v.string, "all")) {
6163 free(yyvsp[-2].v.string);
6164 if (yyvsp[-1].v.number != 0 || yyvsp[0].v.number != 0) {
6165 yyerror("no additional option allowed "
6166 "for 'add-path send all'");
6167 YYERRORgoto yyerrlab;
6168 }
6169 mode = ADDPATH_EVAL_ALL;
6170 } else if (!strcmp(yyvsp[-2].v.string, "best")) {
6171 free(yyvsp[-2].v.string);
6172 mode = ADDPATH_EVAL_BEST;
6173 } else if (!strcmp(yyvsp[-2].v.string, "ecmp")) {
6174 free(yyvsp[-2].v.string);
6175 mode = ADDPATH_EVAL_ECMP;
6176 } else if (!strcmp(yyvsp[-2].v.string, "as-wide-best")) {
6177 free(yyvsp[-2].v.string);
6178 mode = ADDPATH_EVAL_AS_WIDE;
6179 } else {
6180 yyerror("announce add-path send: "
6181 "unknown mode \"%s\"", yyvsp[-2].v.string);
6182 free(yyvsp[-2].v.string);
6183 YYERRORgoto yyerrlab;
6184 }
6185 for (i = 0; i < AID_MAX7; i++)
6186 *ap++ |= CAPA_AP_SEND0x02;
6187 curpeer->conf.eval.mode = mode;
6188 curpeer->conf.eval.extrapaths = yyvsp[-1].v.number;
6189 curpeer->conf.eval.maxpaths = yyvsp[0].v.number;
6190 }
6191break;
6192case 232:
6193#line 1980 "/usr/src/usr.sbin/bgpd/parse.y"
6194{
6195 curpeer->conf.capabilities.policy = yyvsp[0].v.number;
6196 }
6197break;
6198case 233:
6199#line 1983 "/usr/src/usr.sbin/bgpd/parse.y"
6200{
6201 if (strcmp(yyvsp[0].v.string, "provider") == 0) {
6202 curpeer->conf.role = ROLE_PROVIDER;
6203 } else if (strcmp(yyvsp[0].v.string, "rs") == 0) {
6204 curpeer->conf.role = ROLE_RS;
6205 } else if (strcmp(yyvsp[0].v.string, "rs-client") == 0) {
6206 curpeer->conf.role = ROLE_RS_CLIENT;
6207 } else if (strcmp(yyvsp[0].v.string, "customer") == 0) {
6208 curpeer->conf.role = ROLE_CUSTOMER;
6209 } else if (strcmp(yyvsp[0].v.string, "peer") == 0) {
6210 curpeer->conf.role = ROLE_PEER;
6211 } else {
6212 yyerror("syntax error, one of none, provider, "
6213 "rs, rs-client, customer, peer expected");
6214 free(yyvsp[0].v.string);
6215 YYERRORgoto yyerrlab;
6216 }
6217 free(yyvsp[0].v.string);
6218 }
6219break;
6220case 234:
6221#line 2002 "/usr/src/usr.sbin/bgpd/parse.y"
6222{
6223 curpeer->conf.role = ROLE_NONE;
6224 }
6225break;
6226case 235:
6227#line 2005 "/usr/src/usr.sbin/bgpd/parse.y"
6228{
6229 curpeer->conf.export_type = EXPORT_NONE;
6230 }
6231break;
6232case 236:
6233#line 2008 "/usr/src/usr.sbin/bgpd/parse.y"
6234{
6235 curpeer->conf.export_type = EXPORT_DEFAULT_ROUTE;
6236 }
6237break;
6238case 237:
6239#line 2011 "/usr/src/usr.sbin/bgpd/parse.y"
6240{
6241 if (yyvsp[0].v.number)
6242 curpeer->conf.enforce_as = ENFORCE_AS_ON;
6243 else
6244 curpeer->conf.enforce_as = ENFORCE_AS_OFF;
6245 }
6246break;
6247case 238:
6248#line 2017 "/usr/src/usr.sbin/bgpd/parse.y"
6249{
6250 if (yyvsp[0].v.number)
6251 curpeer->conf.enforce_local_as = ENFORCE_AS_ON;
6252 else
6253 curpeer->conf.enforce_local_as = ENFORCE_AS_OFF;
6254 }
6255break;
6256case 239:
6257#line 2023 "/usr/src/usr.sbin/bgpd/parse.y"
6258{
6259 if (yyvsp[0].v.number) {
6260 struct filter_rule *r;
6261 struct filter_set *s;
6262
6263 if ((s = calloc(1, sizeof(struct filter_set)))
6264 == NULL((void *)0))
6265 fatal(NULL((void *)0));
6266 s->type = ACTION_SET_AS_OVERRIDE;
6267
6268 r = get_rule(s->type);
6269 if (merge_filterset(&r->set, s) == -1)
6270 YYERRORgoto yyerrlab;
6271 }
6272 }
6273break;
6274case 240:
6275#line 2038 "/usr/src/usr.sbin/bgpd/parse.y"
6276{
6277 if (yyvsp[-1].v.number < 0 || yyvsp[-1].v.number > UINT_MAX0xffffffffU) {
6278 yyerror("bad maximum number of prefixes");
6279 YYERRORgoto yyerrlab;
6280 }
6281 curpeer->conf.max_prefix = yyvsp[-1].v.number;
6282 curpeer->conf.max_prefix_restart = yyvsp[0].v.number;
6283 }
6284break;
6285case 241:
6286#line 2046 "/usr/src/usr.sbin/bgpd/parse.y"
6287{
6288 if (yyvsp[-2].v.number < 0 || yyvsp[-2].v.number > UINT_MAX0xffffffffU) {
6289 yyerror("bad maximum number of prefixes");
6290 YYERRORgoto yyerrlab;
6291 }
6292 curpeer->conf.max_out_prefix = yyvsp[-2].v.number;
6293 curpeer->conf.max_out_prefix_restart = yyvsp[0].v.number;
6294 }
6295break;
6296case 242:
6297#line 2054 "/usr/src/usr.sbin/bgpd/parse.y"
6298{
6299 if (curpeer->conf.auth.method) {
6300 yyerror("auth method cannot be redefined");
6301 free(yyvsp[0].v.string);
6302 YYERRORgoto yyerrlab;
6303 }
6304 if (strlcpy(curpeer->conf.auth.md5key, yyvsp[0].v.string,
6305 sizeof(curpeer->conf.auth.md5key)) >=
6306 sizeof(curpeer->conf.auth.md5key)) {
6307 yyerror("tcp md5sig password too long: max %zu",
6308 sizeof(curpeer->conf.auth.md5key) - 1);
6309 free(yyvsp[0].v.string);
6310 YYERRORgoto yyerrlab;
6311 }
6312 curpeer->conf.auth.method = AUTH_MD5SIG;
6313 curpeer->conf.auth.md5key_len = strlen(yyvsp[0].v.string);
6314 free(yyvsp[0].v.string);
6315 }
6316break;
6317case 243:
6318#line 2072 "/usr/src/usr.sbin/bgpd/parse.y"
6319{
6320 if (curpeer->conf.auth.method) {
6321 yyerror("auth method cannot be redefined");
6322 free(yyvsp[0].v.string);
6323 YYERRORgoto yyerrlab;
6324 }
6325
6326 if (str2key(yyvsp[0].v.string, curpeer->conf.auth.md5key,
6327 sizeof(curpeer->conf.auth.md5key)) == -1) {
6328 free(yyvsp[0].v.string);
6329 YYERRORgoto yyerrlab;
6330 }
6331 curpeer->conf.auth.method = AUTH_MD5SIG;
6332 curpeer->conf.auth.md5key_len = strlen(yyvsp[0].v.string) / 2;
6333 free(yyvsp[0].v.string);
6334 }
6335break;
6336case 244:
6337#line 2088 "/usr/src/usr.sbin/bgpd/parse.y"
6338{
6339 if (curpeer->conf.auth.method) {
6340 yyerror("auth method cannot be redefined");
6341 YYERRORgoto yyerrlab;
6342 }
6343 if (yyvsp[-1].v.number)
6344 curpeer->conf.auth.method = AUTH_IPSEC_IKE_ESP;
6345 else
6346 curpeer->conf.auth.method = AUTH_IPSEC_IKE_AH;
6347 }
6348break;
6349case 245:
6350#line 2098 "/usr/src/usr.sbin/bgpd/parse.y"
6351{
6352 enum auth_alg auth_alg;
6353 uint8_t keylen;
6354
6355 if (curpeer->conf.auth.method &&
6356 (((curpeer->conf.auth.spi_in && yyvsp[-5].v.number == 1) ||
6357 (curpeer->conf.auth.spi_out && yyvsp[-5].v.number == 0)) ||
6358 (yyvsp[-6].v.number == 1 && curpeer->conf.auth.method !=
6359 AUTH_IPSEC_MANUAL_ESP) ||
6360 (yyvsp[-6].v.number == 0 && curpeer->conf.auth.method !=
6361 AUTH_IPSEC_MANUAL_AH))) {
6362 yyerror("auth method cannot be redefined");
6363 free(yyvsp[-2].v.string);
6364 free(yyvsp[-1].v.string);
6365 YYERRORgoto yyerrlab;
6366 }
6367
6368 if (!strcmp(yyvsp[-2].v.string, "sha1")) {
6369 auth_alg = AUTH_AALG_SHA1HMAC;
6370 keylen = 20;
6371 } else if (!strcmp(yyvsp[-2].v.string, "md5")) {
6372 auth_alg = AUTH_AALG_MD5HMAC;
6373 keylen = 16;
6374 } else {
6375 yyerror("unknown auth algorithm \"%s\"", yyvsp[-2].v.string);
6376 free(yyvsp[-2].v.string);
6377 free(yyvsp[-1].v.string);
6378 YYERRORgoto yyerrlab;
6379 }
6380 free(yyvsp[-2].v.string);
6381
6382 if (strlen(yyvsp[-1].v.string) / 2 != keylen) {
6383 yyerror("auth key len: must be %u bytes, "
6384 "is %zu bytes", keylen, strlen(yyvsp[-1].v.string) / 2);
6385 free(yyvsp[-1].v.string);
6386 YYERRORgoto yyerrlab;
6387 }
6388
6389 if (yyvsp[-6].v.number)
6390 curpeer->conf.auth.method =
6391 AUTH_IPSEC_MANUAL_ESP;
6392 else {
6393 if (yyvsp[0].v.encspec.enc_alg) {
6394 yyerror("\"ipsec ah\" doesn't take "
6395 "encryption keys");
6396 free(yyvsp[-1].v.string);
6397 YYERRORgoto yyerrlab;
6398 }
6399 curpeer->conf.auth.method =
6400 AUTH_IPSEC_MANUAL_AH;
6401 }
6402
6403 if (yyvsp[-3].v.number <= SPI_RESERVED_MAX255 || yyvsp[-3].v.number > UINT_MAX0xffffffffU) {
6404 yyerror("bad spi number %lld", yyvsp[-3].v.number);
6405 free(yyvsp[-1].v.string);
6406 YYERRORgoto yyerrlab;
6407 }
6408
6409 if (yyvsp[-5].v.number == 1) {
6410 if (str2key(yyvsp[-1].v.string, curpeer->conf.auth.auth_key_in,
6411 sizeof(curpeer->conf.auth.auth_key_in)) ==
6412 -1) {
6413 free(yyvsp[-1].v.string);
6414 YYERRORgoto yyerrlab;
6415 }
6416 curpeer->conf.auth.spi_in = yyvsp[-3].v.number;
6417 curpeer->conf.auth.auth_alg_in = auth_alg;
6418 curpeer->conf.auth.enc_alg_in = yyvsp[0].v.encspec.enc_alg;
6419 memcpy(&curpeer->conf.auth.enc_key_in,
6420 &yyvsp[0].v.encspec.enc_key,
6421 sizeof(curpeer->conf.auth.enc_key_in));
6422 curpeer->conf.auth.enc_keylen_in =
6423 yyvsp[0].v.encspec.enc_key_len;
6424 curpeer->conf.auth.auth_keylen_in = keylen;
6425 } else {
6426 if (str2key(yyvsp[-1].v.string, curpeer->conf.auth.auth_key_out,
6427 sizeof(curpeer->conf.auth.auth_key_out)) ==
6428 -1) {
6429 free(yyvsp[-1].v.string);
6430 YYERRORgoto yyerrlab;
6431 }
6432 curpeer->conf.auth.spi_out = yyvsp[-3].v.number;
6433 curpeer->conf.auth.auth_alg_out = auth_alg;
6434 curpeer->conf.auth.enc_alg_out = yyvsp[0].v.encspec.enc_alg;
6435 memcpy(&curpeer->conf.auth.enc_key_out,
6436 &yyvsp[0].v.encspec.enc_key,
6437 sizeof(curpeer->conf.auth.enc_key_out));
6438 curpeer->conf.auth.enc_keylen_out =
6439 yyvsp[0].v.encspec.enc_key_len;
6440 curpeer->conf.auth.auth_keylen_out = keylen;
6441 }
6442 free(yyvsp[-1].v.string);
6443 }
6444break;
6445case 246:
6446#line 2191 "/usr/src/usr.sbin/bgpd/parse.y"
6447{
6448 curpeer->conf.ttlsec = yyvsp[0].v.number;
6449 }
6450break;
6451case 247:
6452#line 2194 "/usr/src/usr.sbin/bgpd/parse.y"
6453{
6454 struct filter_rule *r;
6455
6456 r = get_rule(yyvsp[0].v.filter_set->type);
6457 if (merge_filterset(&r->set, yyvsp[0].v.filter_set) == -1)
6458 YYERRORgoto yyerrlab;
6459 }
6460break;
6461case 248:
6462#line 2201 "/usr/src/usr.sbin/bgpd/parse.y"
6463{
6464 struct filter_rule *r;
6465 struct filter_set *s;
6466
6467 while ((s = TAILQ_FIRST(yyvsp[-2].v.filter_set_head)((yyvsp[-2].v.filter_set_head)->tqh_first)) != NULL((void *)0)) {
6468 TAILQ_REMOVE(yyvsp[-2].v.filter_set_head, s, entry)do { if (((s)->entry.tqe_next) != ((void *)0)) (s)->entry
.tqe_next->entry.tqe_prev = (s)->entry.tqe_prev; else (
yyvsp[-2].v.filter_set_head)->tqh_last = (s)->entry.tqe_prev
; *(s)->entry.tqe_prev = (s)->entry.tqe_next; ; ; } while
(0)
;
6469 r = get_rule(s->type);
6470 if (merge_filterset(&r->set, s) == -1)
6471 YYERRORgoto yyerrlab;
6472 }
6473 free(yyvsp[-2].v.filter_set_head);
6474 }
6475break;
6476case 250:
6477#line 2214 "/usr/src/usr.sbin/bgpd/parse.y"
6478{
6479 if ((conf->flags & BGPD_FLAG_REFLECTOR0x0004) &&
6480 conf->clusterid != 0) {
6481 yyerror("only one route reflector "
6482 "cluster allowed");
6483 YYERRORgoto yyerrlab;
6484 }
6485 conf->flags |= BGPD_FLAG_REFLECTOR0x0004;
6486 curpeer->conf.reflector_client = 1;
6487 }
6488break;
6489case 251:
6490#line 2224 "/usr/src/usr.sbin/bgpd/parse.y"
6491{
6492 if (yyvsp[0].v.addr.aid != AID_INET1) {
6493 yyerror("route reflector cluster-id must be "
6494 "an IPv4 address");
6495 YYERRORgoto yyerrlab;
6496 }
6497 if ((conf->flags & BGPD_FLAG_REFLECTOR0x0004) &&
6498 conf->clusterid != yyvsp[0].v.addr.v4ba.v4.s_addr) {
6499 yyerror("only one route reflector "
6500 "cluster allowed");
6501 YYERRORgoto yyerrlab;
6502 }
6503 conf->flags |= BGPD_FLAG_REFLECTOR0x0004;
6504 curpeer->conf.reflector_client = 1;
6505 conf->clusterid = yyvsp[0].v.addr.v4ba.v4.s_addr;
6506 }
6507break;
6508case 252:
6509#line 2240 "/usr/src/usr.sbin/bgpd/parse.y"
6510{
6511 if (strlcpy(curpeer->conf.if_depend, yyvsp[0].v.string,
6512 sizeof(curpeer->conf.if_depend)) >=
6513 sizeof(curpeer->conf.if_depend)) {
6514 yyerror("interface name \"%s\" too long: "
6515 "max %zu", yyvsp[0].v.string,
6516 sizeof(curpeer->conf.if_depend) - 1);
6517 free(yyvsp[0].v.string);
6518 YYERRORgoto yyerrlab;
6519 }
6520 free(yyvsp[0].v.string);
6521 }
6522break;
6523case 253:
6524#line 2252 "/usr/src/usr.sbin/bgpd/parse.y"
6525{
6526 if (strlcpy(curpeer->conf.demote_group, yyvsp[0].v.string,
6527 sizeof(curpeer->conf.demote_group)) >=
6528 sizeof(curpeer->conf.demote_group)) {
6529 yyerror("demote group name \"%s\" too long: "
6530 "max %zu", yyvsp[0].v.string,
6531 sizeof(curpeer->conf.demote_group) - 1);
6532 free(yyvsp[0].v.string);
6533 YYERRORgoto yyerrlab;
6534 }
6535 free(yyvsp[0].v.string);
6536 if (carp_demote_init(curpeer->conf.demote_group,
6537 cmd_opts & BGPD_OPT_FORCE_DEMOTE0x0008) == -1) {
6538 yyerror("error initializing group \"%s\"",
6539 curpeer->conf.demote_group);
6540 YYERRORgoto yyerrlab;
6541 }
6542 }
6543break;
6544case 254:
6545#line 2270 "/usr/src/usr.sbin/bgpd/parse.y"
6546{
6547 if (yyvsp[0].v.number == 1)
6548 curpeer->conf.flags |= PEERFLAG_TRANS_AS0x01;
6549 else
6550 curpeer->conf.flags &= ~PEERFLAG_TRANS_AS0x01;
6551 }
6552break;
6553case 255:
6554#line 2276 "/usr/src/usr.sbin/bgpd/parse.y"
6555{
6556 if (!strcmp(yyvsp[0].v.string, "updates"))
6557 curpeer->conf.flags |= PEERFLAG_LOG_UPDATES0x02;
6558 else if (!strcmp(yyvsp[0].v.string, "no"))
6559 curpeer->conf.flags &= ~PEERFLAG_LOG_UPDATES0x02;
6560 else {
6561 free(yyvsp[0].v.string);
6562 YYERRORgoto yyerrlab;
6563 }
6564 free(yyvsp[0].v.string);
6565 }
6566break;
6567case 256:
6568#line 2287 "/usr/src/usr.sbin/bgpd/parse.y"
6569{
6570 if (yyvsp[0].v.number == 1)
6571 curpeer->conf.flags |= PEERFLAG_NO_AS_SET0x08;
6572 else
6573 curpeer->conf.flags &= ~PEERFLAG_NO_AS_SET0x08;
6574 }
6575break;
6576case 257:
6577#line 2293 "/usr/src/usr.sbin/bgpd/parse.y"
6578{
6579 curpeer->conf.remote_port = yyvsp[0].v.number;
6580 }
6581break;
6582case 258:
6583#line 2296 "/usr/src/usr.sbin/bgpd/parse.y"
6584{
6585 if (!strcmp(yyvsp[0].v.string, "all"))
6586 curpeer->conf.flags |= PEERFLAG_EVALUATE_ALL0x04;
6587 else if (!strcmp(yyvsp[0].v.string, "default"))
6588 curpeer->conf.flags &= ~PEERFLAG_EVALUATE_ALL0x04;
6589 else {
6590 yyerror("rde evaluate: "
6591 "unknown setting \"%s\"", yyvsp[0].v.string);
6592 free(yyvsp[0].v.string);
6593 YYERRORgoto yyerrlab;
6594 }
6595 free(yyvsp[0].v.string);
6596 }
6597break;
6598case 259:
6599#line 2311 "/usr/src/usr.sbin/bgpd/parse.y"
6600{ yyval.v.number = 0; }
6601break;
6602case 260:
6603#line 2312 "/usr/src/usr.sbin/bgpd/parse.y"
6604{
6605 if (yyvsp[0].v.number < 1 || yyvsp[0].v.number > USHRT_MAX0xffff) {
6606 yyerror("restart out of range. 1 to %u minutes",
6607 USHRT_MAX0xffff);
6608 YYERRORgoto yyerrlab;
6609 }
6610 yyval.v.number = yyvsp[0].v.number;
6611 }
6612break;
6613case 261:
6614#line 2322 "/usr/src/usr.sbin/bgpd/parse.y"
6615{ yyval.v.number = AFI_IPv41; }
6616break;
6617case 262:
6618#line 2323 "/usr/src/usr.sbin/bgpd/parse.y"
6619{ yyval.v.number = AFI_IPv62; }
6620break;
6621case 263:
6622#line 2326 "/usr/src/usr.sbin/bgpd/parse.y"
6623{ yyval.v.number = SAFI_NONE0; }
6624break;
6625case 264:
6626#line 2327 "/usr/src/usr.sbin/bgpd/parse.y"
6627{ yyval.v.number = SAFI_UNICAST1; }
6628break;
6629case 265:
6630#line 2328 "/usr/src/usr.sbin/bgpd/parse.y"
6631{ yyval.v.number = SAFI_MPLSVPN128; }
6632break;
6633case 266:
6634#line 2329 "/usr/src/usr.sbin/bgpd/parse.y"
6635{ yyval.v.number = SAFI_FLOWSPEC133; }
6636break;
6637case 267:
6638#line 2332 "/usr/src/usr.sbin/bgpd/parse.y"
6639{ yyval.v.number = 1; }
6640break;
6641case 268:
6642#line 2333 "/usr/src/usr.sbin/bgpd/parse.y"
6643{ yyval.v.number = 0; }
6644break;
6645case 269:
6646#line 2336 "/usr/src/usr.sbin/bgpd/parse.y"
6647{ yyval.v.number = 1; }
6648break;
6649case 270:
6650#line 2337 "/usr/src/usr.sbin/bgpd/parse.y"
6651{ yyval.v.number = 0; }
6652break;
6653case 271:
6654#line 2340 "/usr/src/usr.sbin/bgpd/parse.y"
6655{
6656 memset(&yyval.v.encspec, 0, sizeof(yyval.v.encspec));
6657 }
6658break;
6659case 272:
6660#line 2343 "/usr/src/usr.sbin/bgpd/parse.y"
6661{
6662 memset(&yyval.v.encspec, 0, sizeof(yyval.v.encspec));
6663 if (!strcmp(yyvsp[-1].v.string, "3des") || !strcmp(yyvsp[-1].v.string, "3des-cbc")) {
6664 yyval.v.encspec.enc_alg = AUTH_EALG_3DESCBC;
6665 yyval.v.encspec.enc_key_len = 21; /* XXX verify */
6666 } else if (!strcmp(yyvsp[-1].v.string, "aes") ||
6667 !strcmp(yyvsp[-1].v.string, "aes-128-cbc")) {
6668 yyval.v.encspec.enc_alg = AUTH_EALG_AES;
6669 yyval.v.encspec.enc_key_len = 16;
6670 } else {
6671 yyerror("unknown enc algorithm \"%s\"", yyvsp[-1].v.string);
6672 free(yyvsp[-1].v.string);
6673 free(yyvsp[0].v.string);
6674 YYERRORgoto yyerrlab;
6675 }
6676 free(yyvsp[-1].v.string);
6677
6678 if (strlen(yyvsp[0].v.string) / 2 != yyval.v.encspec.enc_key_len) {
6679 yyerror("enc key length wrong: should be %u "
6680 "bytes, is %zu bytes",
6681 yyval.v.encspec.enc_key_len * 2, strlen(yyvsp[0].v.string));
6682 free(yyvsp[0].v.string);
6683 YYERRORgoto yyerrlab;
6684 }
6685
6686 if (str2key(yyvsp[0].v.string, yyval.v.encspec.enc_key, sizeof(yyval.v.encspec.enc_key)) == -1) {
6687 free(yyvsp[0].v.string);
6688 YYERRORgoto yyerrlab;
6689 }
6690 free(yyvsp[0].v.string);
6691 }
6692break;
6693case 273:
6694#line 2378 "/usr/src/usr.sbin/bgpd/parse.y"
6695{
6696 struct filter_rule r;
6697 struct filter_rib_l *rb, *rbnext;
6698
6699 memset(&r, 0, sizeof(r));
6700 r.action = yyvsp[-6].v.u8;
6701 r.quick = yyvsp[-5].v.u8;
6702 r.dir = yyvsp[-3].v.u8;
6703 if (yyvsp[-4].v.filter_rib) {
6704 if (r.dir != DIR_IN) {
6705 yyerror("rib only allowed on \"from\" "
6706 "rules.");
6707
6708 for (rb = yyvsp[-4].v.filter_rib; rb != NULL((void *)0); rb = rbnext) {
6709 rbnext = rb->next;
6710 free(rb);
6711 }
6712 YYERRORgoto yyerrlab;
6713 }
6714 }
6715 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)
6716 YYERRORgoto yyerrlab;
6717 }
6718break;
6719case 274:
6720#line 2403 "/usr/src/usr.sbin/bgpd/parse.y"
6721{ yyval.v.u8 = ACTION_ALLOW; }
6722break;
6723case 275:
6724#line 2404 "/usr/src/usr.sbin/bgpd/parse.y"
6725{ yyval.v.u8 = ACTION_DENY; }
6726break;
6727case 276:
6728#line 2405 "/usr/src/usr.sbin/bgpd/parse.y"
6729{ yyval.v.u8 = ACTION_NONE; }
6730break;
6731case 277:
6732#line 2408 "/usr/src/usr.sbin/bgpd/parse.y"
6733{ yyval.v.u8 = 0; }
6734break;
6735case 278:
6736#line 2409 "/usr/src/usr.sbin/bgpd/parse.y"
6737{ yyval.v.u8 = 1; }
6738break;
6739case 279:
6740#line 2412 "/usr/src/usr.sbin/bgpd/parse.y"
6741{ yyval.v.u8 = DIR_IN; }
6742break;
6743case 280:
6744#line 2413 "/usr/src/usr.sbin/bgpd/parse.y"
6745{ yyval.v.u8 = DIR_OUT; }
6746break;
6747case 281:
6748#line 2416 "/usr/src/usr.sbin/bgpd/parse.y"
6749{ yyval.v.filter_rib = NULL((void *)0); }
6750break;
6751case 282:
6752#line 2417 "/usr/src/usr.sbin/bgpd/parse.y"
6753{ yyval.v.filter_rib = yyvsp[0].v.filter_rib; }
6754break;
6755case 283:
6756#line 2418 "/usr/src/usr.sbin/bgpd/parse.y"
6757{ yyval.v.filter_rib = yyvsp[-2].v.filter_rib; }
6758break;
6759case 284:
6760#line 2420 "/usr/src/usr.sbin/bgpd/parse.y"
6761{ yyval.v.filter_rib = yyvsp[0].v.filter_rib; }
6762break;
6763case 285:
6764#line 2421 "/usr/src/usr.sbin/bgpd/parse.y"
6765{
6766 yyvsp[0].v.filter_rib->next = yyvsp[-2].v.filter_rib;
6767 yyval.v.filter_rib = yyvsp[0].v.filter_rib;
6768 }
6769break;
6770case 286:
6771#line 2427 "/usr/src/usr.sbin/bgpd/parse.y"
6772{
6773 if (!find_rib(yyvsp[0].v.string)) {
6774 yyerror("rib \"%s\" does not exist.", yyvsp[0].v.string);
6775 free(yyvsp[0].v.string);
6776 YYERRORgoto yyerrlab;
6777 }
6778 if ((yyval.v.filter_rib = calloc(1, sizeof(struct filter_rib_l))) ==
6779 NULL((void *)0))
6780 fatal(NULL((void *)0));
6781 yyval.v.filter_rib->next = NULL((void *)0);
6782 if (strlcpy(yyval.v.filter_rib->name, yyvsp[0].v.string, sizeof(yyval.v.filter_rib->name)) >=
6783 sizeof(yyval.v.filter_rib->name)) {
6784 yyerror("rib name \"%s\" too long: "
6785 "max %zu", yyvsp[0].v.string, sizeof(yyval.v.filter_rib->name) - 1);
6786 free(yyvsp[0].v.string);
6787 free(yyval.v.filter_rib);
6788 YYERRORgoto yyerrlab;
6789 }
6790 free(yyvsp[0].v.string);
6791 }
6792break;
6793case 288:
6794#line 2450 "/usr/src/usr.sbin/bgpd/parse.y"
6795{ yyval.v.filter_peers = yyvsp[-2].v.filter_peers; }
6796break;
6797case 289:
6798#line 2453 "/usr/src/usr.sbin/bgpd/parse.y"
6799{ yyval.v.filter_peers = yyvsp[0].v.filter_peers; }
6800break;
6801case 290:
6802#line 2454 "/usr/src/usr.sbin/bgpd/parse.y"
6803{
6804 yyvsp[0].v.filter_peers->next = yyvsp[-2].v.filter_peers;
6805 yyval.v.filter_peers = yyvsp[0].v.filter_peers;
6806 }
6807break;
6808case 291:
6809#line 2460 "/usr/src/usr.sbin/bgpd/parse.y"
6810{
6811 if ((yyval.v.filter_peers = calloc(1, sizeof(struct filter_peers_l))) ==
6812 NULL((void *)0))
6813 fatal(NULL((void *)0));
6814 yyval.v.filter_peers->p.peerid = yyval.v.filter_peers->p.groupid = 0;
6815 yyval.v.filter_peers->next = NULL((void *)0);
6816 }
6817break;
6818case 292:
6819#line 2467 "/usr/src/usr.sbin/bgpd/parse.y"
6820{
6821 struct peer *p;
6822
6823 if ((yyval.v.filter_peers = calloc(1, sizeof(struct filter_peers_l))) ==
6824 NULL((void *)0))
6825 fatal(NULL((void *)0));
6826 yyval.v.filter_peers->p.remote_as = yyval.v.filter_peers->p.groupid = yyval.v.filter_peers->p.peerid = 0;
6827 yyval.v.filter_peers->next = NULL((void *)0);
6828 RB_FOREACH(p, peer_head, new_peers)for ((p) = peer_head_RB_MINMAX(new_peers, -1); (p) != ((void *
)0); (p) = peer_head_RB_NEXT(p))
6829 if (!memcmp(&p->conf.remote_addr,
6830 &yyvsp[0].v.addr, sizeof(p->conf.remote_addr))) {
6831 yyval.v.filter_peers->p.peerid = p->conf.id;
6832 break;
6833 }
6834 if (yyval.v.filter_peers->p.peerid == 0) {
6835 yyerror("no such peer: %s", log_addr(&yyvsp[0].v.addr));
6836 free(yyval.v.filter_peers);
6837 YYERRORgoto yyerrlab;
6838 }
6839 }
6840break;
6841case 293:
6842#line 2487 "/usr/src/usr.sbin/bgpd/parse.y"
6843{
6844 if ((yyval.v.filter_peers = calloc(1, sizeof(struct filter_peers_l))) ==
6845 NULL((void *)0))
6846 fatal(NULL((void *)0));
6847 yyval.v.filter_peers->p.groupid = yyval.v.filter_peers->p.peerid = 0;
6848 yyval.v.filter_peers->p.remote_as = yyvsp[0].v.number;
6849 }
6850break;
6851case 294:
6852#line 2494 "/usr/src/usr.sbin/bgpd/parse.y"
6853{
6854 struct peer *p;
6855
6856 if ((yyval.v.filter_peers = calloc(1, sizeof(struct filter_peers_l))) ==
6857 NULL((void *)0))
6858 fatal(NULL((void *)0));
6859 yyval.v.filter_peers->p.remote_as = yyval.v.filter_peers->p.peerid = 0;
6860 yyval.v.filter_peers->next = NULL((void *)0);
6861 RB_FOREACH(p, peer_head, new_peers)for ((p) = peer_head_RB_MINMAX(new_peers, -1); (p) != ((void *
)0); (p) = peer_head_RB_NEXT(p))
6862 if (!strcmp(p->conf.group, yyvsp[0].v.string)) {
6863 yyval.v.filter_peers->p.groupid = p->conf.groupid;
6864 break;
6865 }
6866 if (yyval.v.filter_peers->p.groupid == 0) {
6867 yyerror("no such group: \"%s\"", yyvsp[0].v.string);
6868 free(yyvsp[0].v.string);
6869 free(yyval.v.filter_peers);
6870 YYERRORgoto yyerrlab;
6871 }
6872 free(yyvsp[0].v.string);
6873 }
6874break;
6875case 295:
6876#line 2515 "/usr/src/usr.sbin/bgpd/parse.y"
6877{
6878 if ((yyval.v.filter_peers = calloc(1, sizeof(struct filter_peers_l))) ==
6879 NULL((void *)0))
6880 fatal(NULL((void *)0));
6881 yyval.v.filter_peers->p.ebgp = 1;
6882 }
6883break;
6884case 296:
6885#line 2521 "/usr/src/usr.sbin/bgpd/parse.y"
6886{
6887 if ((yyval.v.filter_peers = calloc(1, sizeof(struct filter_peers_l))) ==
6888 NULL((void *)0))
6889 fatal(NULL((void *)0));
6890 yyval.v.filter_peers->p.ibgp = 1;
6891 }
6892break;
6893case 297:
6894#line 2529 "/usr/src/usr.sbin/bgpd/parse.y"
6895{
6896 if (yyvsp[0].v.prefixlen.op == OP_NONE) {
6897 yyvsp[0].v.prefixlen.op = OP_RANGE;
6898 yyvsp[0].v.prefixlen.len_min = 0;
6899 yyvsp[0].v.prefixlen.len_max = -1;
6900 }
6901 if ((yyval.v.filter_prefix = calloc(1, sizeof(struct filter_prefix_l))) ==
6902 NULL((void *)0))
6903 fatal(NULL((void *)0));
6904 yyval.v.filter_prefix->p.addr.aid = AID_INET1;
6905 if (merge_prefixspec(&yyval.v.filter_prefix->p, &yyvsp[0].v.prefixlen) == -1) {
6906 free(yyval.v.filter_prefix);
6907 YYERRORgoto yyerrlab;
6908 }
6909 }
6910break;
6911case 298:
6912#line 2544 "/usr/src/usr.sbin/bgpd/parse.y"
6913{
6914 if (yyvsp[0].v.prefixlen.op == OP_NONE) {
6915 yyvsp[0].v.prefixlen.op = OP_RANGE;
6916 yyvsp[0].v.prefixlen.len_min = 0;
6917 yyvsp[0].v.prefixlen.len_max = -1;
6918 }
6919 if ((yyval.v.filter_prefix = calloc(1, sizeof(struct filter_prefix_l))) ==
6920 NULL((void *)0))
6921 fatal(NULL((void *)0));
6922 yyval.v.filter_prefix->p.addr.aid = AID_INET62;
6923 if (merge_prefixspec(&yyval.v.filter_prefix->p, &yyvsp[0].v.prefixlen) == -1) {
6924 free(yyval.v.filter_prefix);
6925 YYERRORgoto yyerrlab;
6926 }
6927 }
6928break;
6929case 299:
6930#line 2559 "/usr/src/usr.sbin/bgpd/parse.y"
6931{ yyval.v.filter_prefix = yyvsp[0].v.filter_prefix; }
6932break;
6933case 300:
6934#line 2560 "/usr/src/usr.sbin/bgpd/parse.y"
6935{ yyval.v.filter_prefix = yyvsp[-1].v.filter_prefix; }
6936break;
6937case 302:
6938#line 2564 "/usr/src/usr.sbin/bgpd/parse.y"
6939{ yyval.v.filter_prefix = yyvsp[-1].v.filter_prefix; }
6940break;
6941case 303:
6942#line 2566 "/usr/src/usr.sbin/bgpd/parse.y"
6943{
6944 struct filter_prefix_l *p;
6945
6946 /* merge, both can be lists */
6947 for (p = yyvsp[-2].v.filter_prefix; p != NULL((void *)0) && p->next != NULL((void *)0); p = p->next)
6948 ; /* nothing */
6949 if (p != NULL((void *)0))
6950 p->next = yyvsp[0].v.filter_prefix;
6951 yyval.v.filter_prefix = yyvsp[-2].v.filter_prefix;
6952 }
6953break;
6954case 304:
6955#line 2577 "/usr/src/usr.sbin/bgpd/parse.y"
6956{ yyval.v.filter_prefix = yyvsp[0].v.filter_prefix; }
6957break;
6958case 305:
6959#line 2578 "/usr/src/usr.sbin/bgpd/parse.y"
6960{
6961 yyvsp[0].v.filter_prefix->next = yyvsp[-2].v.filter_prefix;
6962 yyval.v.filter_prefix = yyvsp[0].v.filter_prefix;
6963 }
6964break;
6965case 306:
6966#line 2584 "/usr/src/usr.sbin/bgpd/parse.y"
6967{
6968 if ((yyval.v.filter_prefix = calloc(1, sizeof(struct filter_prefix_l))) ==
6969 NULL((void *)0))
6970 fatal(NULL((void *)0));
6971 memcpy(&yyval.v.filter_prefix->p.addr, &yyvsp[-1].v.prefix.prefix,
6972 sizeof(yyval.v.filter_prefix->p.addr));
6973 yyval.v.filter_prefix->p.len = yyvsp[-1].v.prefix.len;
6974
6975 if (merge_prefixspec(&yyval.v.filter_prefix->p, &yyvsp[0].v.prefixlen) == -1) {
6976 free(yyval.v.filter_prefix);
6977 YYERRORgoto yyerrlab;
6978 }
6979 }
6980break;
6981case 308:
6982#line 2600 "/usr/src/usr.sbin/bgpd/parse.y"
6983{ yyval.v.filter_as = yyvsp[-1].v.filter_as; }
6984break;
6985case 310:
6986#line 2604 "/usr/src/usr.sbin/bgpd/parse.y"
6987{
6988 struct filter_as_l *a;
6989
6990 /* merge, both can be lists */
6991 for (a = yyvsp[-2].v.filter_as; a != NULL((void *)0) && a->next != NULL((void *)0); a = a->next)
6992 ; /* nothing */
6993 if (a != NULL((void *)0))
6994 a->next = yyvsp[0].v.filter_as;
6995 yyval.v.filter_as = yyvsp[-2].v.filter_as;
6996 }
6997break;
6998case 311:
6999#line 2616 "/usr/src/usr.sbin/bgpd/parse.y"
7000{
7001 yyval.v.filter_as = yyvsp[0].v.filter_as;
7002 yyval.v.filter_as->a.type = yyvsp[-1].v.u8;
7003 }
7004break;
7005case 312:
7006#line 2620 "/usr/src/usr.sbin/bgpd/parse.y"
7007{
7008 struct filter_as_l *a;
7009
7010 yyval.v.filter_as = yyvsp[-1].v.filter_as;
7011 for (a = yyval.v.filter_as; a != NULL((void *)0); a = a->next)
7012 a->a.type = yyvsp[-3].v.u8;
7013 }
7014break;
7015case 313:
7016#line 2627 "/usr/src/usr.sbin/bgpd/parse.y"
7017{
7018 if (as_sets_lookup(&conf->as_sets, yyvsp[0].v.string) == NULL((void *)0)) {
7019 yyerror("as-set \"%s\" not defined", yyvsp[0].v.string);
7020 free(yyvsp[0].v.string);
7021 YYERRORgoto yyerrlab;
7022 }
7023 if ((yyval.v.filter_as = calloc(1, sizeof(struct filter_as_l))) ==
7024 NULL((void *)0))
7025 fatal(NULL((void *)0));
7026 yyval.v.filter_as->a.type = yyvsp[-2].v.u8;
7027 yyval.v.filter_as->a.flags = AS_FLAG_AS_SET_NAME0x02;
7028 if (strlcpy(yyval.v.filter_as->a.name, yyvsp[0].v.string, sizeof(yyval.v.filter_as->a.name)) >=
7029 sizeof(yyval.v.filter_as->a.name)) {
7030 yyerror("as-set name \"%s\" too long: "
7031 "max %zu", yyvsp[0].v.string, sizeof(yyval.v.filter_as->a.name) - 1);
7032 free(yyvsp[0].v.string);
7033 free(yyval.v.filter_as);
7034 YYERRORgoto yyerrlab;
7035 }
7036 free(yyvsp[0].v.string);
7037 }
7038break;
7039case 315:
7040#line 2651 "/usr/src/usr.sbin/bgpd/parse.y"
7041{ yyval.v.filter_as = yyvsp[-1].v.filter_as; }
7042break;
7043case 316:
7044#line 2653 "/usr/src/usr.sbin/bgpd/parse.y"
7045{
7046 struct filter_as_l *a;
7047
7048 /* merge, both can be lists */
7049 for (a = yyvsp[-2].v.filter_as; a != NULL((void *)0) && a->next != NULL((void *)0); a = a->next)
7050 ; /* nothing */
7051 if (a != NULL((void *)0))
7052 a->next = yyvsp[0].v.filter_as;
7053 yyval.v.filter_as = yyvsp[-2].v.filter_as;
7054 }
7055break;
7056case 318:
7057#line 2666 "/usr/src/usr.sbin/bgpd/parse.y"
7058{
7059 yyvsp[0].v.filter_as->next = yyvsp[-2].v.filter_as;
7060 yyval.v.filter_as = yyvsp[0].v.filter_as;
7061 }
7062break;
7063case 319:
7064#line 2672 "/usr/src/usr.sbin/bgpd/parse.y"
7065{
7066 if ((yyval.v.filter_as = calloc(1, sizeof(struct filter_as_l))) ==
7067 NULL((void *)0))
7068 fatal(NULL((void *)0));
7069 yyval.v.filter_as->a.as_min = yyvsp[0].v.number;
7070 yyval.v.filter_as->a.as_max = yyvsp[0].v.number;
7071 yyval.v.filter_as->a.op = OP_EQ;
7072 }
7073break;
7074case 320:
7075#line 2680 "/usr/src/usr.sbin/bgpd/parse.y"
7076{
7077 if ((yyval.v.filter_as = calloc(1, sizeof(struct filter_as_l))) ==
7078 NULL((void *)0))
7079 fatal(NULL((void *)0));
7080 yyval.v.filter_as->a.flags = AS_FLAG_NEIGHBORAS0x01;
7081 }
7082break;
7083case 321:
7084#line 2686 "/usr/src/usr.sbin/bgpd/parse.y"
7085{
7086 if ((yyval.v.filter_as = calloc(1, sizeof(struct filter_as_l))) ==
7087 NULL((void *)0))
7088 fatal(NULL((void *)0));
7089 yyval.v.filter_as->a.op = yyvsp[-1].v.u8;
7090 yyval.v.filter_as->a.as_min = yyvsp[0].v.number;
7091 yyval.v.filter_as->a.as_max = yyvsp[0].v.number;
7092 }
7093break;
7094case 322:
7095#line 2694 "/usr/src/usr.sbin/bgpd/parse.y"
7096{
7097 if ((yyval.v.filter_as = calloc(1, sizeof(struct filter_as_l))) ==
7098 NULL((void *)0))
7099 fatal(NULL((void *)0));
7100 if (yyvsp[-2].v.number >= yyvsp[0].v.number) {
7101 yyerror("start AS is bigger than end");
7102 YYERRORgoto yyerrlab;
7103 }
7104 yyval.v.filter_as->a.op = yyvsp[-1].v.u8;
7105 yyval.v.filter_as->a.as_min = yyvsp[-2].v.number;
7106 yyval.v.filter_as->a.as_max = yyvsp[0].v.number;
7107 }
7108break;
7109case 323:
7110#line 2708 "/usr/src/usr.sbin/bgpd/parse.y"
7111{
7112 memset(&yyval.v.filter_match, 0, sizeof(yyval.v.filter_match));
7113 }
7114break;
7115case 324:
7116#line 2711 "/usr/src/usr.sbin/bgpd/parse.y"
7117{
7118 memset(&fmopts, 0, sizeof(fmopts));
7119 }
7120break;
7121case 325:
7122#line 2714 "/usr/src/usr.sbin/bgpd/parse.y"
7123{
7124 memcpy(&yyval.v.filter_match, &fmopts, sizeof(yyval.v.filter_match));
7125 }
7126break;
7127case 328:
7128#line 2723 "/usr/src/usr.sbin/bgpd/parse.y"
7129{
7130 if (fmopts.prefix_l != NULL((void *)0)) {
7131 yyerror("\"prefix\" already specified");
7132 YYERRORgoto yyerrlab;
7133 }
7134 if (fmopts.m.prefixset.name[0] != '\0') {
7135 yyerror("\"prefix-set\" already specified, "
7136 "cannot be used with \"prefix\" in the "
7137 "same filter rule");
7138 YYERRORgoto yyerrlab;
7139 }
7140 fmopts.prefix_l = yyvsp[0].v.filter_prefix;
7141 }
7142break;
7143case 329:
7144#line 2736 "/usr/src/usr.sbin/bgpd/parse.y"
7145{
7146 if (fmopts.as_l != NULL((void *)0)) {
7147 yyerror("AS filters already specified");
7148 YYERRORgoto yyerrlab;
7149 }
7150 fmopts.as_l = yyvsp[0].v.filter_as;
7151 }
7152break;
7153case 330:
7154#line 2743 "/usr/src/usr.sbin/bgpd/parse.y"
7155{
7156 if (fmopts.m.aslen.type != ASLEN_NONE) {
7157 yyerror("AS length filters already specified");
7158 YYERRORgoto yyerrlab;
7159 }
7160 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > UINT_MAX0xffffffffU) {
7161 yyerror("bad max-as-len %lld", yyvsp[0].v.number);
7162 YYERRORgoto yyerrlab;
7163 }
7164 fmopts.m.aslen.type = ASLEN_MAX;
7165 fmopts.m.aslen.aslen = yyvsp[0].v.number;
7166 }
7167break;
7168case 331:
7169#line 2755 "/usr/src/usr.sbin/bgpd/parse.y"
7170{
7171 if (fmopts.m.aslen.type != ASLEN_NONE) {
7172 yyerror("AS length filters already specified");
7173 YYERRORgoto yyerrlab;
7174 }
7175 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > UINT_MAX0xffffffffU) {
7176 yyerror("bad max-as-seq %lld", yyvsp[0].v.number);
7177 YYERRORgoto yyerrlab;
7178 }
7179 fmopts.m.aslen.type = ASLEN_SEQ;
7180 fmopts.m.aslen.aslen = yyvsp[0].v.number;
7181 }
7182break;
7183case 332:
7184#line 2767 "/usr/src/usr.sbin/bgpd/parse.y"
7185{
7186 int i;
7187 for (i = 0; i < MAX_COMM_MATCH3; i++) {
7188 if (fmopts.m.community[i].flags == 0)
7189 break;
7190 }
7191 if (i >= MAX_COMM_MATCH3) {
7192 yyerror("too many \"community\" filters "
7193 "specified");
7194 free(yyvsp[0].v.string);
7195 YYERRORgoto yyerrlab;
7196 }
7197 if (parsecommunity(&fmopts.m.community[i], yyvsp[-1].v.u8, yyvsp[0].v.string) == -1) {
7198 free(yyvsp[0].v.string);
7199 YYERRORgoto yyerrlab;
7200 }
7201 free(yyvsp[0].v.string);
7202 }
7203break;
7204case 333:
7205#line 2785 "/usr/src/usr.sbin/bgpd/parse.y"
7206{
7207 int i;
7208 for (i = 0; i < MAX_COMM_MATCH3; i++) {
7209 if (fmopts.m.community[i].flags == 0)
7210 break;
7211 }
7212 if (i >= MAX_COMM_MATCH3) {
7213 yyerror("too many \"community\" filters "
7214 "specified");
7215 free(yyvsp[-1].v.string);
7216 free(yyvsp[0].v.string);
7217 YYERRORgoto yyerrlab;
7218 }
7219 if (parseextcommunity(&fmopts.m.community[i],
7220 yyvsp[-1].v.string, yyvsp[0].v.string) == -1) {
7221 free(yyvsp[-1].v.string);
7222 free(yyvsp[0].v.string);
7223 YYERRORgoto yyerrlab;
7224 }
7225 free(yyvsp[-1].v.string);
7226 free(yyvsp[0].v.string);
7227 }
7228break;
7229case 334:
7230#line 2807 "/usr/src/usr.sbin/bgpd/parse.y"
7231{
7232 int i;
7233 for (i = 0; i < MAX_COMM_MATCH3; i++) {
7234 if (fmopts.m.community[i].flags == 0)
7235 break;
7236 }
7237 if (i >= MAX_COMM_MATCH3) {
7238 yyerror("too many \"community\" filters "
7239 "specified");
7240 free(yyvsp[0].v.string);
7241 YYERRORgoto yyerrlab;
7242 }
7243 if (parseextcommunity(&fmopts.m.community[i],
7244 "ovs", yyvsp[0].v.string) == -1) {
7245 free(yyvsp[0].v.string);
7246 YYERRORgoto yyerrlab;
7247 }
7248 free(yyvsp[0].v.string);
7249 }
7250break;
7251case 335:
7252#line 2826 "/usr/src/usr.sbin/bgpd/parse.y"
7253{
7254 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT16_MAX0x7fff) {
7255 yyerror("bad max-comunities %lld", yyvsp[0].v.number);
7256 YYERRORgoto yyerrlab;
7257 }
7258 if (fmopts.m.maxcomm != 0) {
7259 yyerror("%s already specified",
7260 "max-communities");
7261 YYERRORgoto yyerrlab;
7262 }
7263 /*
7264 * Offset by 1 since 0 means not used.
7265 * The match function then uses >= to compensate.
7266 */
7267 fmopts.m.maxcomm = yyvsp[0].v.number + 1;
7268 }
7269break;
7270case 336:
7271#line 2842 "/usr/src/usr.sbin/bgpd/parse.y"
7272{
7273 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT16_MAX0x7fff) {
7274 yyerror("bad max-ext-communities %lld", yyvsp[0].v.number);
7275 YYERRORgoto yyerrlab;
7276 }
7277 if (fmopts.m.maxextcomm != 0) {
7278 yyerror("%s already specified",
7279 "max-ext-communities");
7280 YYERRORgoto yyerrlab;
7281 }
7282 fmopts.m.maxextcomm = yyvsp[0].v.number + 1;
7283 }
7284break;
7285case 337:
7286#line 2854 "/usr/src/usr.sbin/bgpd/parse.y"
7287{
7288 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT16_MAX0x7fff) {
7289 yyerror("bad max-large-communities %lld", yyvsp[0].v.number);
7290 YYERRORgoto yyerrlab;
7291 }
7292 if (fmopts.m.maxlargecomm != 0) {
7293 yyerror("%s already specified",
7294 "max-large-communities");
7295 YYERRORgoto yyerrlab;
7296 }
7297 fmopts.m.maxlargecomm = yyvsp[0].v.number + 1;
7298 }
7299break;
7300case 338:
7301#line 2866 "/usr/src/usr.sbin/bgpd/parse.y"
7302{
7303 if (fmopts.m.nexthop.flags) {
7304 yyerror("nexthop already specified");
7305 YYERRORgoto yyerrlab;
7306 }
7307 fmopts.m.nexthop.addr = yyvsp[0].v.addr;
7308 fmopts.m.nexthop.flags = FILTER_NEXTHOP_ADDR1;
7309 }
7310break;
7311case 339:
7312#line 2874 "/usr/src/usr.sbin/bgpd/parse.y"
7313{
7314 if (fmopts.m.nexthop.flags) {
7315 yyerror("nexthop already specified");
7316 YYERRORgoto yyerrlab;
7317 }
7318 fmopts.m.nexthop.flags = FILTER_NEXTHOP_NEIGHBOR2;
7319 }
7320break;
7321case 340:
7322#line 2881 "/usr/src/usr.sbin/bgpd/parse.y"
7323{
7324 struct prefixset *ps;
7325 if (fmopts.prefix_l != NULL((void *)0)) {
7326 yyerror("\"prefix\" already specified, cannot "
7327 "be used with \"prefix-set\" in the same "
7328 "filter rule");
7329 free(yyvsp[-1].v.string);
7330 YYERRORgoto yyerrlab;
7331 }
7332 if (fmopts.m.prefixset.name[0] != '\0') {
7333 yyerror("prefix-set filter already specified");
7334 free(yyvsp[-1].v.string);
7335 YYERRORgoto yyerrlab;
7336 }
7337 if ((ps = find_prefixset(yyvsp[-1].v.string, &conf->prefixsets))
7338 == NULL((void *)0)) {
7339 yyerror("prefix-set '%s' not defined", yyvsp[-1].v.string);
7340 free(yyvsp[-1].v.string);
7341 YYERRORgoto yyerrlab;
7342 }
7343 if (strlcpy(fmopts.m.prefixset.name, yyvsp[-1].v.string,
7344 sizeof(fmopts.m.prefixset.name)) >=
7345 sizeof(fmopts.m.prefixset.name)) {
7346 yyerror("prefix-set name too long");
7347 free(yyvsp[-1].v.string);
7348 YYERRORgoto yyerrlab;
7349 }
7350 if (!(yyvsp[0].v.prefixlen.op == OP_NONE ||
7351 (yyvsp[0].v.prefixlen.op == OP_RANGE &&
7352 yyvsp[0].v.prefixlen.len_min == -1 && yyvsp[0].v.prefixlen.len_max == -1))) {
7353 yyerror("prefix-sets can only use option "
7354 "or-longer");
7355 free(yyvsp[-1].v.string);
7356 YYERRORgoto yyerrlab;
7357 }
7358 if (yyvsp[0].v.prefixlen.op == OP_RANGE && ps->sflags & PREFIXSET_FLAG_OPS0x04) {
7359 yyerror("prefix-set %s contains prefixlen "
7360 "operators and cannot be used with an "
7361 "or-longer filter", yyvsp[-1].v.string);
7362 free(yyvsp[-1].v.string);
7363 YYERRORgoto yyerrlab;
7364 }
7365 if (yyvsp[0].v.prefixlen.op == OP_RANGE && yyvsp[0].v.prefixlen.len_min == -1 &&
7366 yyvsp[0].v.prefixlen.len_min == -1)
7367 fmopts.m.prefixset.flags |=
7368 PREFIXSET_FLAG_LONGER0x08;
7369 fmopts.m.prefixset.flags |= PREFIXSET_FLAG_FILTER0x01;
7370 free(yyvsp[-1].v.string);
7371 }
7372break;
7373case 341:
7374#line 2930 "/usr/src/usr.sbin/bgpd/parse.y"
7375{
7376 if (fmopts.m.originset.name[0] != '\0') {
7377 yyerror("origin-set filter already specified");
7378 free(yyvsp[0].v.string);
7379 YYERRORgoto yyerrlab;
7380 }
7381 if (find_prefixset(yyvsp[0].v.string, &conf->originsets) == NULL((void *)0)) {
7382 yyerror("origin-set '%s' not defined", yyvsp[0].v.string);
7383 free(yyvsp[0].v.string);
7384 YYERRORgoto yyerrlab;
7385 }
7386 if (strlcpy(fmopts.m.originset.name, yyvsp[0].v.string,
7387 sizeof(fmopts.m.originset.name)) >=
7388 sizeof(fmopts.m.originset.name)) {
7389 yyerror("origin-set name too long");
7390 free(yyvsp[0].v.string);
7391 YYERRORgoto yyerrlab;
7392 }
7393 free(yyvsp[0].v.string);
7394 }
7395break;
7396case 342:
7397#line 2950 "/usr/src/usr.sbin/bgpd/parse.y"
7398{
7399 if (fmopts.m.ovs.is_set) {
7400 yyerror("ovs filter already specified");
7401 YYERRORgoto yyerrlab;
7402 }
7403 fmopts.m.ovs.validity = yyvsp[0].v.number;
7404 fmopts.m.ovs.is_set = 1;
7405 }
7406break;
7407case 343:
7408#line 2958 "/usr/src/usr.sbin/bgpd/parse.y"
7409{
7410 if (fmopts.m.avs.is_set) {
7411 yyerror("avs filter already specified");
7412 YYERRORgoto yyerrlab;
7413 }
7414 fmopts.m.avs.validity = yyvsp[0].v.number;
7415 fmopts.m.avs.is_set = 1;
7416 }
7417break;
7418case 344:
7419#line 2968 "/usr/src/usr.sbin/bgpd/parse.y"
7420{ memset(&yyval.v.prefixlen, 0, sizeof(yyval.v.prefixlen)); }
7421break;
7422case 345:
7423#line 2969 "/usr/src/usr.sbin/bgpd/parse.y"
7424{
7425 memset(&yyval.v.prefixlen, 0, sizeof(yyval.v.prefixlen));
7426 yyval.v.prefixlen.op = OP_RANGE;
7427 yyval.v.prefixlen.len_min = -1;
7428 yyval.v.prefixlen.len_max = -1;
7429 }
7430break;
7431case 346:
7432#line 2975 "/usr/src/usr.sbin/bgpd/parse.y"
7433{
7434 memset(&yyval.v.prefixlen, 0, sizeof(yyval.v.prefixlen));
7435 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > 128) {
7436 yyerror("prefixlen must be >= 0 and <= 128");
7437 YYERRORgoto yyerrlab;
7438 }
7439
7440 yyval.v.prefixlen.op = OP_RANGE;
7441 yyval.v.prefixlen.len_min = -1;
7442 yyval.v.prefixlen.len_max = yyvsp[0].v.number;
7443 }
7444break;
7445case 347:
7446#line 2986 "/usr/src/usr.sbin/bgpd/parse.y"
7447{
7448 int min, max;
7449
7450 memset(&yyval.v.prefixlen, 0, sizeof(yyval.v.prefixlen));
7451 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > 128) {
7452 yyerror("prefixlen must be >= 0 and <= 128");
7453 YYERRORgoto yyerrlab;
7454 }
7455 /*
7456 * convert the unary operation into the equivalent
7457 * range check
7458 */
7459 yyval.v.prefixlen.op = OP_RANGE;
7460
7461 switch (yyvsp[-1].v.u8) {
7462 case OP_NE:
7463 yyval.v.prefixlen.op = yyvsp[-1].v.u8;
7464 case OP_EQ:
7465 min = max = yyvsp[0].v.number;
7466 break;
7467 case OP_LT:
7468 if (yyvsp[0].v.number == 0) {
7469 yyerror("prefixlen must be > 0");
7470 YYERRORgoto yyerrlab;
7471 }
7472 yyvsp[0].v.number -= 1;
7473 case OP_LE:
7474 min = -1;
7475 max = yyvsp[0].v.number;
7476 break;
7477 case OP_GT:
7478 yyvsp[0].v.number += 1;
7479 case OP_GE:
7480 min = yyvsp[0].v.number;
7481 max = -1;
7482 break;
7483 default:
7484 yyerror("unknown prefixlen operation");
7485 YYERRORgoto yyerrlab;
7486 }
7487 yyval.v.prefixlen.len_min = min;
7488 yyval.v.prefixlen.len_max = max;
7489 }
7490break;
7491case 348:
7492#line 3029 "/usr/src/usr.sbin/bgpd/parse.y"
7493{
7494 memset(&yyval.v.prefixlen, 0, sizeof(yyval.v.prefixlen));
7495 if (yyvsp[-2].v.number < 0 || yyvsp[-2].v.number > 128 || yyvsp[0].v.number < 0 || yyvsp[0].v.number > 128) {
7496 yyerror("prefixlen must be < 128");
7497 YYERRORgoto yyerrlab;
7498 }
7499 if (yyvsp[-2].v.number > yyvsp[0].v.number) {
7500 yyerror("start prefixlen is bigger than end");
7501 YYERRORgoto yyerrlab;
7502 }
7503 yyval.v.prefixlen.op = yyvsp[-1].v.u8;
7504 yyval.v.prefixlen.len_min = yyvsp[-2].v.number;
7505 yyval.v.prefixlen.len_max = yyvsp[0].v.number;
7506 }
7507break;
7508case 349:
7509#line 3045 "/usr/src/usr.sbin/bgpd/parse.y"
7510{ yyval.v.u8 = AS_ALL; }
7511break;
7512case 350:
7513#line 3046 "/usr/src/usr.sbin/bgpd/parse.y"
7514{ yyval.v.u8 = AS_SOURCE; }
7515break;
7516case 351:
7517#line 3047 "/usr/src/usr.sbin/bgpd/parse.y"
7518{ yyval.v.u8 = AS_TRANSIT; }
7519break;
7520case 352:
7521#line 3048 "/usr/src/usr.sbin/bgpd/parse.y"
7522{ yyval.v.u8 = AS_PEER; }
7523break;
7524case 353:
7525#line 3051 "/usr/src/usr.sbin/bgpd/parse.y"
7526{ yyval.v.filter_set_head = NULL((void *)0); }
7527break;
7528case 354:
7529#line 3052 "/usr/src/usr.sbin/bgpd/parse.y"
7530{
7531 if ((yyval.v.filter_set_head = calloc(1, sizeof(struct filter_set_head))) ==
7532 NULL((void *)0))
7533 fatal(NULL((void *)0));
7534 TAILQ_INIT(yyval.v.filter_set_head)do { (yyval.v.filter_set_head)->tqh_first = ((void *)0); (
yyval.v.filter_set_head)->tqh_last = &(yyval.v.filter_set_head
)->tqh_first; } while (0)
;
7535 TAILQ_INSERT_TAIL(yyval.v.filter_set_head, yyvsp[0].v.filter_set, entry)do { (yyvsp[0].v.filter_set)->entry.tqe_next = ((void *)0)
; (yyvsp[0].v.filter_set)->entry.tqe_prev = (yyval.v.filter_set_head
)->tqh_last; *(yyval.v.filter_set_head)->tqh_last = (yyvsp
[0].v.filter_set); (yyval.v.filter_set_head)->tqh_last = &
(yyvsp[0].v.filter_set)->entry.tqe_next; } while (0)
;
7536 }
7537break;
7538case 355:
7539#line 3059 "/usr/src/usr.sbin/bgpd/parse.y"
7540{ yyval.v.filter_set_head = yyvsp[-2].v.filter_set_head; }
7541break;
7542case 356:
7543#line 3062 "/usr/src/usr.sbin/bgpd/parse.y"
7544{
7545 yyval.v.filter_set_head = yyvsp[-2].v.filter_set_head;
7546 if (merge_filterset(yyval.v.filter_set_head, yyvsp[0].v.filter_set) == 1)
7547 YYERRORgoto yyerrlab;
7548 }
7549break;
7550case 357:
7551#line 3067 "/usr/src/usr.sbin/bgpd/parse.y"
7552{
7553 if ((yyval.v.filter_set_head = calloc(1, sizeof(struct filter_set_head))) ==
7554 NULL((void *)0))
7555 fatal(NULL((void *)0));
7556 TAILQ_INIT(yyval.v.filter_set_head)do { (yyval.v.filter_set_head)->tqh_first = ((void *)0); (
yyval.v.filter_set_head)->tqh_last = &(yyval.v.filter_set_head
)->tqh_first; } while (0)
;
7557 TAILQ_INSERT_TAIL(yyval.v.filter_set_head, yyvsp[0].v.filter_set, entry)do { (yyvsp[0].v.filter_set)->entry.tqe_next = ((void *)0)
; (yyvsp[0].v.filter_set)->entry.tqe_prev = (yyval.v.filter_set_head
)->tqh_last; *(yyval.v.filter_set_head)->tqh_last = (yyvsp
[0].v.filter_set); (yyval.v.filter_set_head)->tqh_last = &
(yyvsp[0].v.filter_set)->entry.tqe_next; } while (0)
;
7558 }
7559break;
7560case 358:
7561#line 3076 "/usr/src/usr.sbin/bgpd/parse.y"
7562{ yyval.v.u8 = COMMUNITY_TYPE_BASIC8; }
7563break;
7564case 359:
7565#line 3077 "/usr/src/usr.sbin/bgpd/parse.y"
7566{ yyval.v.u8 = COMMUNITY_TYPE_LARGE32; }
7567break;
7568case 360:
7569#line 3080 "/usr/src/usr.sbin/bgpd/parse.y"
7570{ yyval.v.u8 = 0; }
7571break;
7572case 361:
7573#line 3081 "/usr/src/usr.sbin/bgpd/parse.y"
7574{ yyval.v.u8 = 1; }
7575break;
7576case 362:
7577#line 3084 "/usr/src/usr.sbin/bgpd/parse.y"
7578{ yyval.v.number = yyvsp[0].v.number; }
7579break;
7580case 363:
7581#line 3085 "/usr/src/usr.sbin/bgpd/parse.y"
7582{ yyval.v.number = 2; }
7583break;
7584case 364:
7585#line 3088 "/usr/src/usr.sbin/bgpd/parse.y"
7586{
7587 if (yyvsp[0].v.number < -INT_MAX0x7fffffff || yyvsp[0].v.number > UINT_MAX0xffffffffU) {
7588 yyerror("bad localpref %lld", yyvsp[0].v.number);
7589 YYERRORgoto yyerrlab;
7590 }
7591 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void *)0))
7592 fatal(NULL((void *)0));
7593 if (yyvsp[0].v.number >= 0) {
7594 yyval.v.filter_set->type = ACTION_SET_LOCALPREF;
7595 yyval.v.filter_set->action.metric = yyvsp[0].v.number;
7596 } else {
7597 yyval.v.filter_set->type = ACTION_SET_RELATIVE_LOCALPREF;
7598 yyval.v.filter_set->action.relative = yyvsp[0].v.number;
7599 }
7600 }
7601break;
7602case 365:
7603#line 3103 "/usr/src/usr.sbin/bgpd/parse.y"
7604{
7605 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX0x7fffffff) {
7606 yyerror("bad localpref +%lld", yyvsp[0].v.number);
7607 YYERRORgoto yyerrlab;
7608 }
7609 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void *)0))
7610 fatal(NULL((void *)0));
7611 yyval.v.filter_set->type = ACTION_SET_RELATIVE_LOCALPREF;
7612 yyval.v.filter_set->action.relative = yyvsp[0].v.number;
7613 }
7614break;
7615case 366:
7616#line 3113 "/usr/src/usr.sbin/bgpd/parse.y"
7617{
7618 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX0x7fffffff) {
7619 yyerror("bad localpref -%lld", yyvsp[0].v.number);
7620 YYERRORgoto yyerrlab;
7621 }
7622 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void *)0))
7623 fatal(NULL((void *)0));
7624 yyval.v.filter_set->type = ACTION_SET_RELATIVE_LOCALPREF;
7625 yyval.v.filter_set->action.relative = -yyvsp[0].v.number;
7626 }
7627break;
7628case 367:
7629#line 3123 "/usr/src/usr.sbin/bgpd/parse.y"
7630{
7631 if (yyvsp[0].v.number < -INT_MAX0x7fffffff || yyvsp[0].v.number > UINT_MAX0xffffffffU) {
7632 yyerror("bad metric %lld", yyvsp[0].v.number);
7633 YYERRORgoto yyerrlab;
7634 }
7635 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void *)0))
7636 fatal(NULL((void *)0));
7637 if (yyvsp[0].v.number >= 0) {
7638 yyval.v.filter_set->type = ACTION_SET_MED;
7639 yyval.v.filter_set->action.metric = yyvsp[0].v.number;
7640 } else {
7641 yyval.v.filter_set->type = ACTION_SET_RELATIVE_MED;
7642 yyval.v.filter_set->action.relative = yyvsp[0].v.number;
7643 }
7644 }
7645break;
7646case 368:
7647#line 3138 "/usr/src/usr.sbin/bgpd/parse.y"
7648{
7649 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX0x7fffffff) {
7650 yyerror("bad metric +%lld", yyvsp[0].v.number);
7651 YYERRORgoto yyerrlab;
7652 }
7653 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void *)0))
7654 fatal(NULL((void *)0));
7655 yyval.v.filter_set->type = ACTION_SET_RELATIVE_MED;
7656 yyval.v.filter_set->action.relative = yyvsp[0].v.number;
7657 }
7658break;
7659case 369:
7660#line 3148 "/usr/src/usr.sbin/bgpd/parse.y"
7661{
7662 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX0x7fffffff) {
7663 yyerror("bad metric -%lld", yyvsp[0].v.number);
7664 YYERRORgoto yyerrlab;
7665 }
7666 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void *)0))
7667 fatal(NULL((void *)0));
7668 yyval.v.filter_set->type = ACTION_SET_RELATIVE_MED;
7669 yyval.v.filter_set->action.relative = -yyvsp[0].v.number;
7670 }
7671break;
7672case 370:
7673#line 3158 "/usr/src/usr.sbin/bgpd/parse.y"
7674{ /* alias for MED */
7675 if (yyvsp[0].v.number < -INT_MAX0x7fffffff || yyvsp[0].v.number > UINT_MAX0xffffffffU) {
7676 yyerror("bad metric %lld", yyvsp[0].v.number);
7677 YYERRORgoto yyerrlab;
7678 }
7679 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void *)0))
7680 fatal(NULL((void *)0));
7681 if (yyvsp[0].v.number >= 0) {
7682 yyval.v.filter_set->type = ACTION_SET_MED;
7683 yyval.v.filter_set->action.metric = yyvsp[0].v.number;
7684 } else {
7685 yyval.v.filter_set->type = ACTION_SET_RELATIVE_MED;
7686 yyval.v.filter_set->action.relative = yyvsp[0].v.number;
7687 }
7688 }
7689break;
7690case 371:
7691#line 3173 "/usr/src/usr.sbin/bgpd/parse.y"
7692{
7693 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX0x7fffffff) {
7694 yyerror("bad metric +%lld", yyvsp[0].v.number);
7695 YYERRORgoto yyerrlab;
7696 }
7697 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void *)0))
7698 fatal(NULL((void *)0));
7699 yyval.v.filter_set->type = ACTION_SET_RELATIVE_MED;
7700 yyval.v.filter_set->action.metric = yyvsp[0].v.number;
7701 }
7702break;
7703case 372:
7704#line 3183 "/usr/src/usr.sbin/bgpd/parse.y"
7705{
7706 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX0x7fffffff) {
7707 yyerror("bad metric -%lld", yyvsp[0].v.number);
7708 YYERRORgoto yyerrlab;
7709 }
7710 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void *)0))
7711 fatal(NULL((void *)0));
7712 yyval.v.filter_set->type = ACTION_SET_RELATIVE_MED;
7713 yyval.v.filter_set->action.relative = -yyvsp[0].v.number;
7714 }
7715break;
7716case 373:
7717#line 3193 "/usr/src/usr.sbin/bgpd/parse.y"
7718{
7719 if (yyvsp[0].v.number < -INT_MAX0x7fffffff || yyvsp[0].v.number > UINT_MAX0xffffffffU) {
7720 yyerror("bad weight %lld", yyvsp[0].v.number);
7721 YYERRORgoto yyerrlab;
7722 }
7723 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void *)0))
7724 fatal(NULL((void *)0));
7725 if (yyvsp[0].v.number > 0) {
7726 yyval.v.filter_set->type = ACTION_SET_WEIGHT;
7727 yyval.v.filter_set->action.metric = yyvsp[0].v.number;
7728 } else {
7729 yyval.v.filter_set->type = ACTION_SET_RELATIVE_WEIGHT;
7730 yyval.v.filter_set->action.relative = yyvsp[0].v.number;
7731 }
7732 }
7733break;
7734case 374:
7735#line 3208 "/usr/src/usr.sbin/bgpd/parse.y"
7736{
7737 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX0x7fffffff) {
7738 yyerror("bad weight +%lld", yyvsp[0].v.number);
7739 YYERRORgoto yyerrlab;
7740 }
7741 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void *)0))
7742 fatal(NULL((void *)0));
7743 yyval.v.filter_set->type = ACTION_SET_RELATIVE_WEIGHT;
7744 yyval.v.filter_set->action.relative = yyvsp[0].v.number;
7745 }
7746break;
7747case 375:
7748#line 3218 "/usr/src/usr.sbin/bgpd/parse.y"
7749{
7750 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX0x7fffffff) {
7751 yyerror("bad weight -%lld", yyvsp[0].v.number);
7752 YYERRORgoto yyerrlab;
7753 }
7754 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void *)0))
7755 fatal(NULL((void *)0));
7756 yyval.v.filter_set->type = ACTION_SET_RELATIVE_WEIGHT;
7757 yyval.v.filter_set->action.relative = -yyvsp[0].v.number;
7758 }
7759break;
7760case 376:
7761#line 3228 "/usr/src/usr.sbin/bgpd/parse.y"
7762{
7763 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void *)0))
7764 fatal(NULL((void *)0));
7765 yyval.v.filter_set->type = ACTION_SET_NEXTHOP;
7766 memcpy(&yyval.v.filter_set->action.nexthop, &yyvsp[0].v.addr,
7767 sizeof(yyval.v.filter_set->action.nexthop));
7768 }
7769break;
7770case 377:
7771#line 3235 "/usr/src/usr.sbin/bgpd/parse.y"
7772{
7773 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void *)0))
7774 fatal(NULL((void *)0));
7775 yyval.v.filter_set->type = ACTION_SET_NEXTHOP_BLACKHOLE;
7776 }
7777break;
7778case 378:
7779#line 3240 "/usr/src/usr.sbin/bgpd/parse.y"
7780{
7781 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void *)0))
7782 fatal(NULL((void *)0));
7783 yyval.v.filter_set->type = ACTION_SET_NEXTHOP_REJECT;
7784 }
7785break;
7786case 379:
7787#line 3245 "/usr/src/usr.sbin/bgpd/parse.y"
7788{
7789 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void *)0))
7790 fatal(NULL((void *)0));
7791 yyval.v.filter_set->type = ACTION_SET_NEXTHOP_NOMODIFY;
7792 }
7793break;
7794case 380:
7795#line 3250 "/usr/src/usr.sbin/bgpd/parse.y"
7796{
7797 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void *)0))
7798 fatal(NULL((void *)0));
7799 yyval.v.filter_set->type = ACTION_SET_NEXTHOP_SELF;
7800 }
7801break;
7802case 381:
7803#line 3255 "/usr/src/usr.sbin/bgpd/parse.y"
7804{
7805 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > 128) {
7806 yyerror("bad number of prepends");
7807 YYERRORgoto yyerrlab;
7808 }
7809 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void *)0))
7810 fatal(NULL((void *)0));
7811 yyval.v.filter_set->type = ACTION_SET_PREPEND_SELF;
7812 yyval.v.filter_set->action.prepend = yyvsp[0].v.number;
7813 }
7814break;
7815case 382:
7816#line 3265 "/usr/src/usr.sbin/bgpd/parse.y"
7817{
7818 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > 128) {
7819 yyerror("bad number of prepends");
7820 YYERRORgoto yyerrlab;
7821 }
7822 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void *)0))
7823 fatal(NULL((void *)0));
7824 yyval.v.filter_set->type = ACTION_SET_PREPEND_PEER;
7825 yyval.v.filter_set->action.prepend = yyvsp[0].v.number;
7826 }
7827break;
7828case 383:
7829#line 3275 "/usr/src/usr.sbin/bgpd/parse.y"
7830{
7831 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void *)0))
7832 fatal(NULL((void *)0));
7833 yyval.v.filter_set->type = ACTION_SET_AS_OVERRIDE;
7834 }
7835break;
7836case 384:
7837#line 3280 "/usr/src/usr.sbin/bgpd/parse.y"
7838{
7839 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void *)0))
7840 fatal(NULL((void *)0));
7841 yyval.v.filter_set->type = ACTION_PFTABLE;
7842 if (!(cmd_opts & BGPD_OPT_NOACTION0x0004) &&
7843 pftable_exists(yyvsp[0].v.string) != 0) {
7844 yyerror("pftable name does not exist");
7845 free(yyvsp[0].v.string);
7846 free(yyval.v.filter_set);
7847 YYERRORgoto yyerrlab;
7848 }
7849 if (strlcpy(yyval.v.filter_set->action.pftable, yyvsp[0].v.string,
7850 sizeof(yyval.v.filter_set->action.pftable)) >=
7851 sizeof(yyval.v.filter_set->action.pftable)) {
7852 yyerror("pftable name too long");
7853 free(yyvsp[0].v.string);
7854 free(yyval.v.filter_set);
7855 YYERRORgoto yyerrlab;
7856 }
7857 if (pftable_add(yyvsp[0].v.string) != 0) {
7858 yyerror("Couldn't register table");
7859 free(yyvsp[0].v.string);
7860 free(yyval.v.filter_set);
7861 YYERRORgoto yyerrlab;
7862 }
7863 free(yyvsp[0].v.string);
7864 }
7865break;
7866case 385:
7867#line 3307 "/usr/src/usr.sbin/bgpd/parse.y"
7868{
7869 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void *)0))
7870 fatal(NULL((void *)0));
7871 yyval.v.filter_set->type = ACTION_RTLABEL;
7872 if (strlcpy(yyval.v.filter_set->action.rtlabel, yyvsp[0].v.string,
7873 sizeof(yyval.v.filter_set->action.rtlabel)) >=
7874 sizeof(yyval.v.filter_set->action.rtlabel)) {
7875 yyerror("rtlabel name too long");
7876 free(yyvsp[0].v.string);
7877 free(yyval.v.filter_set);
7878 YYERRORgoto yyerrlab;
7879 }
7880 free(yyvsp[0].v.string);
7881 }
7882break;
7883case 386:
7884#line 3321 "/usr/src/usr.sbin/bgpd/parse.y"
7885{
7886 uint8_t f1, f2, f3;
7887
7888 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void *)0))
7889 fatal(NULL((void *)0));
7890 if (yyvsp[-1].v.u8)
7891 yyval.v.filter_set->type = ACTION_DEL_COMMUNITY;
7892 else
7893 yyval.v.filter_set->type = ACTION_SET_COMMUNITY;
7894
7895 if (parsecommunity(&yyval.v.filter_set->action.community, yyvsp[-2].v.u8, yyvsp[0].v.string) ==
7896 -1) {
7897 free(yyvsp[0].v.string);
7898 free(yyval.v.filter_set);
7899 YYERRORgoto yyerrlab;
7900 }
7901 free(yyvsp[0].v.string);
7902 /* Don't allow setting of any match */
7903 f1 = yyval.v.filter_set->action.community.flags >> 8;
7904 f2 = yyval.v.filter_set->action.community.flags >> 16;
7905 f3 = yyval.v.filter_set->action.community.flags >> 24;
7906 if (!yyvsp[-1].v.u8 && (f1 == COMMUNITY_ANY1 ||
7907 f2 == COMMUNITY_ANY1 || f3 == COMMUNITY_ANY1)) {
7908 yyerror("'*' is not allowed in set community");
7909 free(yyval.v.filter_set);
7910 YYERRORgoto yyerrlab;
7911 }
7912 }
7913break;
7914case 387:
7915#line 3349 "/usr/src/usr.sbin/bgpd/parse.y"
7916{
7917 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void *)0))
7918 fatal(NULL((void *)0));
7919 if (yyvsp[-2].v.u8)
7920 yyval.v.filter_set->type = ACTION_DEL_COMMUNITY;
7921 else
7922 yyval.v.filter_set->type = ACTION_SET_COMMUNITY;
7923
7924 if (parseextcommunity(&yyval.v.filter_set->action.community,
7925 yyvsp[-1].v.string, yyvsp[0].v.string) == -1) {
7926 free(yyvsp[-1].v.string);
7927 free(yyvsp[0].v.string);
7928 free(yyval.v.filter_set);
7929 YYERRORgoto yyerrlab;
7930 }
7931 free(yyvsp[-1].v.string);
7932 free(yyvsp[0].v.string);
7933 }
7934break;
7935case 388:
7936#line 3367 "/usr/src/usr.sbin/bgpd/parse.y"
7937{
7938 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void *)0))
7939 fatal(NULL((void *)0));
7940 if (yyvsp[-2].v.u8)
7941 yyval.v.filter_set->type = ACTION_DEL_COMMUNITY;
7942 else
7943 yyval.v.filter_set->type = ACTION_SET_COMMUNITY;
7944
7945 if (parseextcommunity(&yyval.v.filter_set->action.community,
7946 "ovs", yyvsp[0].v.string) == -1) {
7947 free(yyvsp[0].v.string);
7948 free(yyval.v.filter_set);
7949 YYERRORgoto yyerrlab;
7950 }
7951 free(yyvsp[0].v.string);
7952 }
7953break;
7954case 389:
7955#line 3383 "/usr/src/usr.sbin/bgpd/parse.y"
7956{
7957 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void *)0))
7958 fatal(NULL((void *)0));
7959 yyval.v.filter_set->type = ACTION_SET_ORIGIN;
7960 yyval.v.filter_set->action.origin = yyvsp[0].v.number;
7961 }
7962break;
7963case 390:
7964#line 3391 "/usr/src/usr.sbin/bgpd/parse.y"
7965{
7966 if (!strcmp(yyvsp[0].v.string, "egp"))
7967 yyval.v.number = ORIGIN_EGP1;
7968 else if (!strcmp(yyvsp[0].v.string, "igp"))
7969 yyval.v.number = ORIGIN_IGP0;
7970 else if (!strcmp(yyvsp[0].v.string, "incomplete"))
7971 yyval.v.number = ORIGIN_INCOMPLETE2;
7972 else {
7973 yyerror("unknown origin \"%s\"", yyvsp[0].v.string);
7974 free(yyvsp[0].v.string);
7975 YYERRORgoto yyerrlab;
7976 }
7977 free(yyvsp[0].v.string);
7978 }
7979break;
7980case 391:
7981#line 3406 "/usr/src/usr.sbin/bgpd/parse.y"
7982{
7983 if (!strcmp(yyvsp[0].v.string, "not-found"))
7984 yyval.v.number = ROA_NOTFOUND0x0;
7985 else if (!strcmp(yyvsp[0].v.string, "invalid"))
7986 yyval.v.number = ROA_INVALID0x1;
7987 else if (!strcmp(yyvsp[0].v.string, "valid"))
7988 yyval.v.number = ROA_VALID0x2;
7989 else {
7990 yyerror("unknown roa validity \"%s\"", yyvsp[0].v.string);
7991 free(yyvsp[0].v.string);
7992 YYERRORgoto yyerrlab;
7993 }
7994 free(yyvsp[0].v.string);
7995 }
7996break;
7997case 392:
7998#line 3421 "/usr/src/usr.sbin/bgpd/parse.y"
7999{
8000 if (!strcmp(yyvsp[0].v.string, "unknown"))
8001 yyval.v.number = ASPA_UNKNOWN0x00;
8002 else if (!strcmp(yyvsp[0].v.string, "invalid"))
8003 yyval.v.number = ASPA_INVALID0x01;
8004 else if (!strcmp(yyvsp[0].v.string, "valid"))
8005 yyval.v.number = ASPA_VALID0x02;
8006 else {
8007 yyerror("unknown aspa validity \"%s\"", yyvsp[0].v.string);
8008 free(yyvsp[0].v.string);
8009 YYERRORgoto yyerrlab;
8010 }
8011 free(yyvsp[0].v.string);
8012 }
8013break;
8014case 399:
8015#line 3446 "/usr/src/usr.sbin/bgpd/parse.y"
8016{ yyval.v.u8 = OP_EQ; }
8017break;
8018case 400:
8019#line 3447 "/usr/src/usr.sbin/bgpd/parse.y"
8020{ yyval.v.u8 = OP_NE; }
8021break;
8022case 401:
8023#line 3448 "/usr/src/usr.sbin/bgpd/parse.y"
8024{ yyval.v.u8 = OP_LE; }
8025break;
8026case 402:
8027#line 3449 "/usr/src/usr.sbin/bgpd/parse.y"
8028{ yyval.v.u8 = OP_LT; }
8029break;
8030case 403:
8031#line 3450 "/usr/src/usr.sbin/bgpd/parse.y"
8032{ yyval.v.u8 = OP_GE; }
8033break;
8034case 404:
8035#line 3451 "/usr/src/usr.sbin/bgpd/parse.y"
8036{ yyval.v.u8 = OP_GT; }
8037break;
8038case 405:
8039#line 3454 "/usr/src/usr.sbin/bgpd/parse.y"
8040{ yyval.v.u8 = OP_EQ; }
8041break;
8042case 406:
8043#line 3455 "/usr/src/usr.sbin/bgpd/parse.y"
8044{ yyval.v.u8 = OP_NE; }
8045break;
8046case 407:
8047#line 3458 "/usr/src/usr.sbin/bgpd/parse.y"
8048{ yyval.v.u8 = OP_RANGE; }
8049break;
8050case 408:
8051#line 3459 "/usr/src/usr.sbin/bgpd/parse.y"
8052{ yyval.v.u8 = OP_XRANGE; }
8053break;
8054#line 8047 "parse.c"
8055 }
8056 yyssp -= yym;
8057 yystate = *yyssp;
8058 yyvsp -= yym;
8059 yym = yylhs[yyn];
8060 if (yystate == 0 && yym == 0)
8061 {
8062#if YYDEBUG0
8063 if (yydebug)
8064 printf("%sdebug: after reduction, shifting from state 0 to\
8065 state %d\n", YYPREFIX"yy", YYFINAL1);
8066#endif
8067 yystate = YYFINAL1;
8068 *++yyssp = YYFINAL1;
8069 *++yyvsp = yyval;
8070 if (yychar < 0)
8071 {
8072 if ((yychar = yylex()) < 0) yychar = 0;
8073#if YYDEBUG0
8074 if (yydebug)
8075 {
8076 yys = 0;
8077 if (yychar <= YYMAXTOKEN401) yys = yyname[yychar];
8078 if (!yys) yys = "illegal-symbol";
8079 printf("%sdebug: state %d, reading %d (%s)\n",
8080 YYPREFIX"yy", YYFINAL1, yychar, yys);
8081 }
8082#endif
8083 }
8084 if (yychar == 0) goto yyaccept;
8085 goto yyloop;
8086 }
8087 if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
8088 yyn <= YYTABLESIZE1630 && yycheck[yyn] == yystate)
8089 yystate = yytable[yyn];
8090 else
8091 yystate = yydgoto[yym];
8092#if YYDEBUG0
8093 if (yydebug)
8094 printf("%sdebug: after reduction, shifting from state %d \
8095to state %d\n", YYPREFIX"yy", *yyssp, yystate);
8096#endif
8097 if (yyssp >= yysslim && yygrowstack())
8098 {
8099 goto yyoverflow;
8100 }
8101 *++yyssp = yystate;
8102 *++yyvsp = yyval;
8103 goto yyloop;
8104yyoverflow:
8105 yyerror("yacc stack overflow");
8106yyabort:
8107 if (yyss)
8108 free(yyss);
8109 if (yyvs)
8110 free(yyvs);
8111 yyss = yyssp = NULL((void *)0);
8112 yyvs = yyvsp = NULL((void *)0);
8113 yystacksize = 0;
8114 return (1);
8115yyaccept:
8116 if (yyss)
8117 free(yyss);
8118 if (yyvs)
8119 free(yyvs);
8120 yyss = yyssp = NULL((void *)0);
8121 yyvs = yyvsp = NULL((void *)0);
8122 yystacksize = 0;
8123 return (0);
8124}