Bug Summary

File:src/usr.sbin/bgpd/obj/parse.c
Warning:line 2393, column 11
Result of 'calloc' is converted to a pointer of type 'struct mrt', which is incompatible with sizeof operand type 'struct mrt_config'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name parse.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -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 -fno-rounding-math -mconstructor-aliases -munwind-tables -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/lib/clang/13.0.0 -I /usr/src/usr.sbin/bgpd -internal-isystem /usr/local/lib/clang/13.0.0/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 -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/vmm/scan-build/2022-01-12-194120-40624-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_ipsp.h>
19#include <arpa/inet.h>
20
21#include <ctype.h>
22#include <endian.h>
23#include <err.h>
24#include <unistd.h>
25#include <errno(*__errno()).h>
26#include <limits.h>
27#include <stdarg.h>
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
31#include <syslog.h>
32
33#include "bgpd.h"
34#include "session.h"
35#include "rde.h"
36#include "log.h"
37
38TAILQ_HEAD(files, file)struct files { struct file *tqh_first; struct file **tqh_last
; }
files = TAILQ_HEAD_INITIALIZER(files){ ((void*)0), &(files).tqh_first };
39static struct file {
40 TAILQ_ENTRY(file)struct { struct file *tqe_next; struct file **tqe_prev; } entry;
41 FILE *stream;
42 char *name;
43 size_t ungetpos;
44 size_t ungetsize;
45 u_char *ungetbuf;
46 int eof_reached;
47 int lineno;
48 int errors;
49} *file, *topfile;
50struct file *pushfile(const char *, int);
51int popfile(void);
52int check_file_secrecy(int, const char *);
53int yyparse(void);
54int yylex(void);
55int yyerror(const char *, ...)
56 __attribute__((__format__ (printf, 1, 2)))
57 __attribute__((__nonnull__ (1)));
58int kw_cmp(const void *, const void *);
59int lookup(char *);
60int igetc(void);
61int lgetc(int);
62void lungetc(int);
63int findeol(void);
64
65TAILQ_HEAD(symhead, sym)struct symhead { struct sym *tqh_first; struct sym **tqh_last
; }
symhead = TAILQ_HEAD_INITIALIZER(symhead){ ((void*)0), &(symhead).tqh_first };
66struct sym {
67 TAILQ_ENTRY(sym)struct { struct sym *tqe_next; struct sym **tqe_prev; } entry;
68 int used;
69 int persist;
70 char *nam;
71 char *val;
72};
73int symset(const char *, const char *, int);
74char *symget(const char *);
75
76static struct bgpd_config *conf;
77static struct network_head *netconf;
78static struct peer_head *new_peers, *cur_peers;
79static struct rtr_config_head *cur_rtrs;
80static struct peer *curpeer;
81static struct peer *curgroup;
82static struct rde_rib *currib;
83static struct l3vpn *curvpn;
84static struct prefixset *curpset, *curoset;
85static struct roa_tree *curroatree;
86static struct rtr_config *currtr;
87static struct filter_head *filter_l;
88static struct filter_head *peerfilter_l;
89static struct filter_head *groupfilter_l;
90static struct filter_rule *curpeer_filter[2];
91static struct filter_rule *curgroup_filter[2];
92static int noexpires;
93
94struct filter_rib_l {
95 struct filter_rib_l *next;
96 char name[PEER_DESCR_LEN32];
97};
98
99struct filter_peers_l {
100 struct filter_peers_l *next;
101 struct filter_peers p;
102};
103
104struct filter_prefix_l {
105 struct filter_prefix_l *next;
106 struct filter_prefix p;
107};
108
109struct filter_prefixlen {
110 enum comp_ops op;
111 int len_min;
112 int len_max;
113};
114
115struct filter_as_l {
116 struct filter_as_l *next;
117 struct filter_as a;
118};
119
120struct filter_match_l {
121 struct filter_match m;
122 struct filter_prefix_l *prefix_l;
123 struct filter_as_l *as_l;
124 struct filter_prefixset *prefixset;
125} fmopts;
126
127struct peer *alloc_peer(void);
128struct peer *new_peer(void);
129struct peer *new_group(void);
130int add_mrtconfig(enum mrt_type, char *, int, struct peer *,
131 char *);
132struct rde_rib *add_rib(char *);
133struct rde_rib *find_rib(char *);
134int rib_add_fib(struct rde_rib *, u_int);
135int get_id(struct peer *);
136int merge_prefixspec(struct filter_prefix *,
137 struct filter_prefixlen *);
138int expand_rule(struct filter_rule *, struct filter_rib_l *,
139 struct filter_peers_l *, struct filter_match_l *,
140 struct filter_set_head *);
141int str2key(char *, char *, size_t);
142int neighbor_consistent(struct peer *);
143int merge_filterset(struct filter_set_head *, struct filter_set *);
144void optimize_filters(struct filter_head *);
145struct filter_rule *get_rule(enum action_types);
146
147int parsecommunity(struct community *, int, char *);
148int parseextcommunity(struct community *, char *,
149 char *);
150static int new_as_set(char *);
151static void add_as_set(u_int32_t);
152static void done_as_set(void);
153static struct prefixset *new_prefix_set(char *, int);
154static void add_roa_set(struct prefixset_item *, u_int32_t, u_int8_t,
155 time_t);
156static struct rtr_config *get_rtr(struct bgpd_addr *);
157static int insert_rtr(struct rtr_config *);
158
159typedef struct {
160 union {
161 long long number;
162 char *string;
163 struct bgpd_addr addr;
164 u_int8_t u8;
165 struct filter_rib_l *filter_rib;
166 struct filter_peers_l *filter_peers;
167 struct filter_match_l filter_match;
168 struct filter_prefixset *filter_prefixset;
169 struct filter_prefix_l *filter_prefix;
170 struct filter_as_l *filter_as;
171 struct filter_set *filter_set;
172 struct filter_set_head *filter_set_head;
173 struct {
174 struct bgpd_addr prefix;
175 u_int8_t len;
176 } prefix;
177 struct filter_prefixlen prefixlen;
178 struct prefixset_item *prefixset_item;
179 struct {
180 u_int8_t enc_alg;
181 char enc_key[IPSEC_ENC_KEY_LEN32];
182 u_int8_t enc_key_len;
183 } encspec;
184 } v;
185 int lineno;
186} YYSTYPE;
187
188#line 189 "parse.c"
189#define AS257 257
190#define ROUTERID258 258
191#define HOLDTIME259 259
192#define YMIN260 260
193#define LISTEN261 261
194#define ON262 262
195#define FIBUPDATE263 263
196#define FIBPRIORITY264 264
197#define RTABLE265 265
198#define NONE266 266
199#define UNICAST267 267
200#define VPN268 268
201#define RD269 269
202#define EXPORT270 270
203#define EXPORTTRGT271 271
204#define IMPORTTRGT272 272
205#define DEFAULTROUTE273 273
206#define RDE274 274
207#define RIB275 275
208#define EVALUATE276 276
209#define IGNORE277 277
210#define COMPARE278 278
211#define RTR279 279
212#define PORT280 280
213#define GROUP281 281
214#define NEIGHBOR282 282
215#define NETWORK283 283
216#define EBGP284 284
217#define IBGP285 285
218#define LOCALAS286 286
219#define REMOTEAS287 287
220#define DESCR288 288
221#define LOCALADDR289 289
222#define MULTIHOP290 290
223#define PASSIVE291 291
224#define MAXPREFIX292 292
225#define RESTART293 293
226#define ANNOUNCE294 294
227#define CAPABILITIES295 295
228#define REFRESH296 296
229#define AS4BYTE297 297
230#define CONNECTRETRY298 298
231#define ENHANCED299 299
232#define ADDPATH300 300
233#define SEND301 301
234#define RECV302 302
235#define DEMOTE303 303
236#define ENFORCE304 304
237#define NEIGHBORAS305 305
238#define ASOVERRIDE306 306
239#define REFLECTOR307 307
240#define DEPEND308 308
241#define DOWN309 309
242#define DUMP310 310
243#define IN311 311
244#define OUT312 312
245#define SOCKET313 313
246#define RESTRICTED314 314
247#define LOG315 315
248#define TRANSPARENT316 316
249#define TCP317 317
250#define MD5SIG318 318
251#define PASSWORD319 319
252#define KEY320 320
253#define TTLSECURITY321 321
254#define ALLOW322 322
255#define DENY323 323
256#define MATCH324 324
257#define QUICK325 325
258#define FROM326 326
259#define TO327 327
260#define ANY328 328
261#define CONNECTED329 329
262#define STATIC330 330
263#define COMMUNITY331 331
264#define EXTCOMMUNITY332 332
265#define LARGECOMMUNITY333 333
266#define DELETE334 334
267#define PREFIX335 335
268#define PREFIXLEN336 336
269#define PREFIXSET337 337
270#define ROASET338 338
271#define ORIGINSET339 339
272#define OVS340 340
273#define EXPIRES341 341
274#define ASSET342 342
275#define SOURCEAS343 343
276#define TRANSITAS344 344
277#define PEERAS345 345
278#define MAXASLEN346 346
279#define MAXASSEQ347 347
280#define SET348 348
281#define LOCALPREF349 349
282#define MED350 350
283#define METRIC351 351
284#define NEXTHOP352 352
285#define REJECT353 353
286#define BLACKHOLE354 354
287#define NOMODIFY355 355
288#define SELF356 356
289#define PREPEND_SELF357 357
290#define PREPEND_PEER358 358
291#define PFTABLE359 359
292#define WEIGHT360 360
293#define RTLABEL361 361
294#define ORIGIN362 362
295#define PRIORITY363 363
296#define ERROR364 364
297#define INCLUDE365 365
298#define IPSEC366 366
299#define ESP367 367
300#define AH368 368
301#define SPI369 369
302#define IKE370 370
303#define IPV4371 371
304#define IPV6372 372
305#define QUALIFY373 373
306#define VIA374 374
307#define NE375 375
308#define LE376 376
309#define GE377 377
310#define XRANGE378 378
311#define LONGER379 379
312#define MAXLEN380 380
313#define STRING381 381
314#define NUMBER382 382
315#define YYERRCODE256 256
316const short yylhs[] =
317 { -1,
318 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
319 0, 0, 0, 0, 0, 0, 1, 2, 2, 3,
320 3, 16, 16, 11, 54, 55, 69, 56, 56, 68,
321 68, 72, 57, 57, 71, 71, 20, 74, 58, 58,
322 75, 59, 59, 15, 15, 73, 73, 60, 76, 60,
323 77, 77, 78, 78, 78, 62, 62, 62, 62, 62,
324 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
325 62, 62, 62, 62, 62, 62, 62, 62, 82, 61,
326 81, 81, 81, 83, 83, 80, 79, 79, 79, 79,
327 79, 12, 12, 13, 13, 17, 18, 18, 19, 19,
328 4, 4, 84, 63, 85, 85, 85, 85, 86, 86,
329 86, 86, 86, 87, 89, 64, 90, 65, 91, 91,
330 91, 91, 91, 88, 88, 88, 93, 93, 93, 93,
331 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
332 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
333 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
334 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
335 92, 92, 92, 8, 8, 6, 6, 7, 7, 7,
336 10, 10, 5, 5, 53, 53, 66, 21, 21, 21,
337 22, 22, 23, 23, 26, 26, 26, 27, 27, 28,
338 31, 31, 30, 30, 29, 29, 29, 29, 29, 29,
339 47, 47, 47, 47, 48, 48, 48, 46, 46, 45,
340 37, 37, 39, 39, 38, 38, 38, 40, 40, 40,
341 36, 36, 35, 35, 35, 35, 34, 94, 34, 32,
342 32, 33, 33, 33, 33, 33, 33, 33, 33, 33,
343 33, 33, 33, 41, 41, 41, 41, 41, 52, 52,
344 52, 52, 43, 43, 43, 44, 44, 25, 25, 24,
345 24, 42, 42, 42, 42, 42, 42, 42, 42, 42,
346 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
347 42, 42, 42, 42, 42, 42, 42, 9, 14, 67,
348 67, 70, 70, 70, 70, 49, 49, 49, 49, 49,
349 49, 50, 50, 51, 51,
350};
351const short yylen[] =
352 { 2,
353 0, 2, 3, 3, 3, 3, 3, 3, 3, 3,
354 3, 3, 3, 3, 3, 3, 1, 1, 1, 1,
355 1, 2, 1, 1, 3, 2, 0, 8, 5, 1,
356 3, 0, 8, 5, 1, 3, 2, 0, 7, 4,
357 0, 8, 5, 0, 2, 4, 6, 2, 0, 8,
358 1, 3, 2, 2, 2, 2, 3, 2, 2, 3,
359 3, 2, 2, 2, 3, 2, 1, 4, 6, 1,
360 3, 3, 4, 3, 4, 2, 2, 3, 0, 5,
361 1, 3, 2, 0, 2, 5, 3, 4, 5, 5,
362 4, 1, 1, 1, 0, 1, 3, 3, 1, 1,
363 0, 1, 0, 8, 0, 2, 3, 3, 2, 3,
364 3, 2, 1, 0, 0, 5, 0, 6, 0, 2,
365 3, 3, 3, 4, 3, 0, 0, 2, 3, 3,
366 2, 2, 3, 2, 2, 2, 2, 1, 1, 2,
367 2, 2, 3, 3, 3, 3, 4, 3, 3, 4,
368 2, 2, 3, 3, 2, 3, 4, 4, 4, 3,
369 8, 2, 2, 6, 1, 1, 2, 3, 2, 2,
370 2, 3, 3, 0, 2, 1, 1, 1, 1, 1,
371 1, 1, 1, 1, 0, 2, 7, 1, 1, 1,
372 0, 1, 1, 1, 0, 2, 6, 1, 3, 1,
373 1, 5, 1, 3, 1, 1, 2, 2, 1, 1,
374 2, 2, 2, 4, 1, 3, 4, 1, 3, 2,
375 1, 3, 1, 3, 2, 4, 3, 1, 3, 4,
376 1, 3, 1, 1, 2, 3, 0, 0, 2, 1,
377 2, 1, 1, 2, 2, 2, 3, 3, 2, 2,
378 3, 2, 2, 0, 1, 2, 3, 4, 1, 1,
379 1, 1, 0, 2, 6, 3, 1, 1, 1, 0,
380 1, 2, 3, 3, 2, 3, 3, 2, 3, 3,
381 2, 3, 3, 2, 2, 2, 2, 2, 2, 2,
382 1, 2, 2, 3, 4, 4, 2, 1, 1, 0,
383 2, 0, 1, 2, 3, 1, 1, 1, 1, 1,
384 1, 1, 1, 1, 1,
385};
386const short yydefred[] =
387 { 1,
388 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
389 0, 0, 0, 0, 0, 0, 0, 0, 0, 188,
390 189, 190, 0, 0, 0, 0, 0, 0, 0, 0,
391 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,
392 0, 0, 0, 0, 0, 67, 70, 0, 16, 18,
393 17, 19, 0, 96, 58, 0, 59, 0, 24, 63,
394 62, 76, 0, 0, 0, 0, 0, 0, 23, 0,
395 0, 176, 177, 0, 0, 0, 0, 77, 0, 0,
396 0, 66, 64, 0, 0, 0, 0, 0, 0, 26,
397 0, 192, 0, 3, 4, 5, 6, 7, 8, 9,
398 10, 11, 12, 13, 14, 15, 0, 57, 60, 61,
399 0, 79, 74, 0, 71, 72, 0, 22, 0, 0,
400 0, 0, 182, 181, 0, 0, 0, 0, 87, 0,
401 92, 93, 0, 0, 94, 78, 0, 0, 0, 0,
402 0, 0, 65, 0, 0, 0, 0, 99, 100, 115,
403 103, 0, 73, 0, 119, 88, 97, 98, 0, 0,
404 91, 291, 268, 0, 269, 0, 0, 0, 0, 0,
405 0, 0, 0, 0, 0, 0, 0, 264, 0, 102,
406 68, 0, 0, 301, 40, 0, 0, 0, 75, 200,
407 0, 196, 193, 194, 0, 0, 0, 0, 0, 0,
408 80, 81, 0, 0, 89, 90, 271, 0, 272, 0,
409 0, 275, 0, 0, 278, 0, 0, 286, 285, 287,
410 288, 284, 289, 290, 292, 281, 0, 0, 293, 298,
411 297, 0, 0, 0, 86, 34, 0, 0, 0, 0,
412 43, 0, 29, 0, 0, 0, 0, 209, 210, 205,
413 0, 206, 201, 0, 0, 116, 105, 85, 0, 83,
414 0, 0, 0, 0, 51, 0, 0, 0, 0, 0,
415 0, 0, 0, 0, 0, 138, 0, 0, 0, 0,
416 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
417 0, 0, 120, 118, 0, 0, 165, 0, 0, 0,
418 273, 274, 276, 277, 279, 280, 282, 283, 267, 0,
419 294, 69, 35, 0, 0, 255, 0, 37, 0, 0,
420 0, 0, 0, 0, 20, 21, 30, 0, 0, 198,
421 207, 208, 0, 0, 0, 127, 0, 0, 82, 55,
422 53, 54, 0, 123, 0, 142, 151, 152, 0, 141,
423 0, 131, 0, 135, 137, 0, 0, 0, 0, 0,
424 0, 0, 0, 169, 0, 0, 155, 167, 0, 140,
425 0, 171, 170, 0, 162, 0, 163, 0, 183, 184,
426 0, 136, 122, 121, 296, 295, 0, 0, 0, 0,
427 307, 308, 310, 0, 306, 309, 311, 0, 256, 0,
428 0, 0, 39, 0, 0, 0, 0, 0, 0, 203,
429 0, 187, 259, 0, 0, 0, 0, 0, 260, 261,
430 262, 0, 0, 0, 0, 0, 0, 0, 0, 240,
431 243, 221, 242, 0, 0, 125, 0, 0, 0, 0,
432 0, 106, 104, 113, 0, 50, 52, 143, 173, 133,
433 0, 0, 156, 148, 145, 146, 149, 0, 0, 178,
434 179, 180, 144, 154, 153, 168, 0, 0, 0, 172,
435 160, 0, 265, 266, 33, 36, 315, 314, 0, 257,
436 0, 46, 305, 0, 42, 28, 31, 197, 199, 0,
437 0, 0, 0, 0, 0, 213, 0, 252, 299, 253,
438 244, 245, 250, 249, 211, 212, 223, 0, 246, 241,
439 234, 0, 313, 312, 0, 0, 225, 0, 0, 128,
440 124, 0, 108, 112, 109, 0, 0, 107, 175, 157,
441 147, 150, 0, 0, 0, 0, 258, 45, 0, 202,
442 204, 248, 247, 0, 218, 0, 0, 220, 251, 0,
443 222, 0, 227, 0, 231, 0, 0, 0, 235, 130,
444 129, 110, 111, 0, 0, 47, 0, 0, 214, 304,
445 224, 0, 0, 226, 236, 164, 0, 0, 219, 0,
446 232, 0, 217, 230, 0, 161, 186,
447};
448const short yydgoto[] =
449 { 1,
450 326, 53, 516, 181, 381, 76, 463, 453, 231, 127,
451 295, 134, 136, 500, 482, 70, 252, 238, 150, 239,
452 32, 93, 195, 208, 177, 146, 329, 192, 253, 411,
453 254, 429, 430, 334, 555, 556, 431, 432, 508, 557,
454 318, 309, 129, 310, 545, 546, 433, 547, 398, 518,
455 479, 434, 586, 33, 34, 35, 36, 37, 38, 39,
456 40, 41, 42, 43, 44, 45, 139, 328, 244, 323,
457 314, 237, 240, 186, 242, 117, 264, 265, 46, 297,
458 201, 152, 202, 197, 338, 445, 48, 256, 196, 119,
459 204, 298, 435, 335,
460};
461const short yysindex[] =
462 { 0,
463 229, 75, -160, -282, -219, -159, -256, -247, -232, -226,
464 -35, -282, -224, -229, -185, -212, -209, -182, -256, 0,
465 0, 0, -177, 105, -135, -129, -125, -84, -127, 199,
466 0, -63, 255, 260, 279, 292, 295, 297, 311, 314,
467 316, 320, 322, 324, 327, 0, 0, 67, 0, 0,
468 0, 0, -27, 0, 0, -9, 0, -282, 0, 0,
469 0, 0, 114, 1, 16, 122, 40, 0, 0, 22,
470 26, 0, 0, 348, 365, -95, 68, 0, 42, -220,
471 107, 0, 0, 302, 421, 310, 331, 73, -256, 0,
472 -224, 0, 170, 0, 0, 0, 0, 0, 0, 0,
473 0, 0, 0, 0, 0, 0, -62, 0, 0, 0,
474 79, 0, 0, 84, 0, 0, 335, 0, 339, 68,
475 93, 97, 0, 0, 103, 109, 68, 777, 0, 108,
476 0, 0, 120, 123, 0, 0, 421, 421, 358, 421,
477 421, 126, 0, 22, -94, 43, 348, 0, 0, 0,
478 0, -181, 0, 421, 0, 0, 0, 0, 68, 68,
479 0, 0, 0, 177, 0, -26, -25, -21, 85, 136,
480 140, 148, -20, 150, 151, 421, 177, 0, 152, 0,
481 0, 120, 403, 0, 0, 6, 409, 410, 0, 0,
482 421, 0, 0, 0, -91, 413, 414, -256, 156, 264,
483 0, 0, -44, 299, 0, 0, 0, -243, 0, 159,
484 161, 0, 164, 166, 0, 167, 174, 0, 0, 0,
485 0, 0, 0, 0, 0, 0, 175, 178, 0, 0,
486 0, 878, 180, 120, 0, 0, 6, -116, 216, 71,
487 0, 6, 0, 48, 181, -160, 182, 0, 0, 0,
488 421, 0, 0, 0, 436, 0, 0, 0, 307, 0,
489 183, 191, -282, 421, 0, 565, -199, -196, 300, 196,
490 -160, -160, -224, -282, 197, 0, 198, 224, 202, -158,
491 -256, -282, 330, 217, 218, 219, -256, 283, -256, 842,
492 236, 81, 0, 0, 308, 594, 0, 601, 231, 232,
493 0, 0, 0, 0, 0, 0, 0, 0, 0, 71,
494 0, 0, 0, 71, 14, 0, 235, 0, 48, 421,
495 608, 499, 6, 71, 0, 0, 0, 71, 71, 0,
496 0, 0, -168, 68, 814, 0, 501, 23, 0, 0,
497 0, 0, -70, 0, 246, 0, 0, 0, 250, 0,
498 -27, 0, 22, 0, 0, -55, -256, -256, -256, -256,
499 336, 337, 46, 0, -256, -256, 0, 0, 263, 0,
500 162, 0, 0, 158, 0, 421, 0, -256, 0, 0,
501 -216, 0, 0, 0, 0, 0, 516, 878, 520, 6,
502 0, 0, 0, -15, 0, 0, 0, 267, 0, 305,
503 0, 421, 0, 312, 525, 526, 48, 528, 181, 0,
504 71, 0, 0, -240, -108, 275, 276, 282, 0, 0,
505 0, 278, 284, -210, -116, -116, -113, 286, 814, 0,
506 0, 0, 0, 33, 384, 0, 654, -256, 287, 288,
507 296, 0, 0, 0, 669, 0, 0, 0, 0, 0,
508 301, 388, 0, 0, 0, 0, 0, -256, -256, 0,
509 0, 0, 0, 0, 0, 0, -224, -224, 878, 0,
510 0, 313, 0, 0, 0, 0, 0, 0, 303, 0,
511 304, 0, 0, 48, 0, 0, 0, 0, 0, 564,
512 -168, 315, 317, -85, -116, 0, -116, 0, 0, 0,
513 0, 0, 0, 0, 0, 0, 0, 54, 0, 0,
514 0, 321, 0, 0, 17, -15, 0, 48, 687, 0,
515 0, 694, 0, 0, 0, 326, 328, 0, 0, 0,
516 0, 0, 22, 22, 71, 332, 0, 0, 305, 0,
517 0, 0, 0, 6, 0, 165, 583, 0, 0, 421,
518 0, -113, 0, 53, 0, 165, 587, 48, 0, 0,
519 0, 0, 0, 588, 334, 0, 76, 6, 0, 0,
520 0, 80, 53, 0, 0, 0, 338, -85, 0, 17,
521 0, 340, 0, 0, 350, 0, 0,};
522const short yyrindex[] =
523 { 0,
524 434, 0, 0, 0, 0, 0, 0, 0, 0, 0,
525 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
526 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
527 0, -110, 0, 0, 0, 0, 0, 0, 0, 0,
528 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
529 0, 0, 707, 0, 0, 0, 0, 0, 0, 0,
530 0, 0, 0, 0, 0, 0, 0, 35, 0, 595,
531 0, 0, 0, 0, 0, 0, 710, 0, 0, 0,
532 260, 0, 0, 0, -83, 0, 0, 0, 0, 0,
533 0, 0, 155, 0, 0, 0, 0, 0, 0, 0,
534 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
535 0, 0, 0, 0, 0, 0, 0, 0, 0, 710,
536 0, 0, 0, 0, 0, 0, 710, 0, 0, 0,
537 0, 0, 314, 0, 0, 0, -83, 523, 117, -83,
538 -83, 0, 0, 719, 0, 0, 55, 0, 0, 0,
539 0, 723, 0, -38, 0, 0, 0, 0, 710, 710,
540 0, 0, 0, -236, 0, 0, 0, 0, 0, 0,
541 0, 0, 0, 0, 0, 892, 353, 0, 0, 0,
542 0, 34, 119, 0, 0, 0, 132, 134, 0, 0,
543 354, 0, 0, 0, 0, 726, 0, 0, 0, 0,
544 0, 0, 0, 434, 0, 0, 0, 0, 0, 0,
545 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
546 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
547 0, 0, 0, 314, 0, 0, 0, 2, 0, -78,
548 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
549 -148, 0, 0, 290, 0, 0, 0, 0, 723, 0,
550 0, 0, 0, -65, 0, 0, 0, 0, 0, 0,
551 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
552 0, 49, 0, 57, 0, 0, 0, 0, 0, 0,
553 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
554 0, 0, 0, 0, 0, 0, 0, 0, 0, 856,
555 0, 0, 0, -78, 0, 0, 0, 0, 0, 699,
556 558, 0, 0, -78, 0, 0, 0, -78, -99, 0,
557 0, 0, 0, 710, 0, 0, 0, 0, 0, 0,
558 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
559 63, 0, 77, 0, 0, 78, 0, 0, 0, 0,
560 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
561 0, 0, 0, 0, 0, 892, 0, 0, 0, 0,
562 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
563 0, 0, 0, 0, 0, 0, 0, 0, 0, 4,
564 762, 642, 0, 0, 0, 0, 0, 0, 0, 0,
565 -73, 0, 0, 0, 0, 0, 0, 0, 0, 0,
566 0, 0, 0, 0, 427, 427, 0, 0, -1, 0,
567 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
568 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
569 0, 78, 0, 0, 0, 0, 0, 0, 0, 0,
570 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
571 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
572 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
573 0, 0, 0, 0, 124, 0, 427, 0, 0, 0,
574 0, 0, 0, 0, 0, 0, 0, 66, 0, 0,
575 0, 0, 0, 0, 0, -4, 0, 0, 0, 0,
576 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
577 0, 0, 100, 101, 856, 0, 0, 0, 4, 0,
578 0, 0, 0, 0, 0, -71, 0, 0, 0, 61,
579 0, 0, 0, 0, 0, 45, 0, 0, 0, 0,
580 0, 0, 0, 0, 0, 0, 144, 0, 0, 0,
581 0, 69, 0, 0, 0, 0, 0, 613, 0, 616,
582 0, 102, 0, 0, 0, 0, 0,};
583const short yygindex[] =
584 { 0,
585 13, 147, -193, -111, 0, 469, 0, 309, 0, 0,
586 -6, 367, 0, 0, 210, -88, -2, -14, 0, -184,
587 0, 0, 0, 577, -267, 0, 0, -211, -305, 0,
588 0, 0, 347, 0, -397, 201, 0, -388, 0, 176,
589 -346, -117, -58, 294, -379, 225, 0, 190, 0, 0,
590 261, 0, 0, 0, 0, 0, 0, 0, 0, 0,
591 0, 0, 0, 574, 0, 0, -133, 0, 0, -279,
592 0, 0, 539, 0, 0, 0, 0, 439, 445, 784,
593 0, 0, 527, 0, 0, 0, 0, 0, 0, 0,
594 0, -228, 0, 0,
595};
596#define YYTABLESIZE1254 1254
597const short yytable[] =
598 { 77,
599 60, 55, 144, 183, 184, 233, 187, 188, 239, 68,
600 178, 254, 83, 44, 494, 52, 210, 213, 211, 214,
601 203, 216, 227, 217, 228, 300, 337, 410, 191, 478,
602 388, 251, 442, 330, 390, 496, 517, 544, 507, 233,
603 56, 300, 232, 101, 48, 254, 300, 44, 407, 409,
604 327, 300, 313, 215, 446, 110, 233, 245, 166, 300,
605 345, 156, 79, 550, 96, 108, 139, 428, 161, 347,
606 235, 503, 132, 396, 395, 397, 348, 514, 505, 506,
607 320, 198, 143, 199, 49, 550, 134, 174, 246, 550,
608 131, 132, 149, 514, 131, 132, 299, 321, 54, 492,
609 205, 206, 58, 270, 148, 302, 322, 71, 300, 158,
610 159, 185, 247, 514, 321, 248, 249, 333, 233, 321,
611 233, 300, 312, 321, 59, 400, 254, 365, 44, 302,
612 343, 491, 300, 254, 61, 300, 300, 300, 404, 554,
613 493, 72, 73, 413, 270, 200, 366, 443, 548, 62,
614 549, 74, 75, 471, 63, 515, 69, 49, 101, 250,
615 133, 428, 57, 571, 191, 246, 222, 254, 80, 228,
616 54, 81, 377, 166, 550, 581, 387, 96, 551, 300,
617 389, 139, 346, 302, 353, 541, 401, 132, 579, 247,
618 405, 258, 248, 249, 406, 408, 78, 489, 82, 59,
619 578, 134, 174, 84, 580, 476, 522, 302, 321, 261,
620 302, 302, 54, 487, 300, 191, 191, 262, 263, 315,
621 50, 51, 300, 300, 158, 159, 185, 85, 552, 419,
622 420, 421, 300, 123, 124, 261, 250, 451, 31, 64,
623 65, 300, 469, 262, 263, 86, 254, 88, 254, 300,
624 300, 87, 233, 90, 302, 388, 452, 89, 52, 91,
625 342, 92, 316, 317, 94, 125, 568, 126, 483, 95,
626 474, 354, 74, 75, 367, 412, 573, 490, 437, 368,
627 373, 302, 375, 52, 52, 438, 190, 568, 96, 54,
628 539, 439, 573, 440, 441, 74, 75, 300, 300, 237,
629 233, 97, 302, 302, 98, 14, 99, 302, 293, 302,
630 302, 460, 461, 462, 66, 115, 116, 300, 147, 75,
631 100, 511, 302, 101, 559, 102, 233, 233, 233, 103,
632 233, 104, 233, 105, 233, 233, 106, 511, 233, 233,
633 233, 233, 233, 233, 254, 67, 239, 233, 107, 302,
634 454, 455, 456, 457, 51, 209, 212, 511, 464, 465,
635 215, 226, 477, 450, 575, 300, 233, 233, 193, 194,
636 233, 470, 109, 302, 512, 111, 233, 233, 533, 534,
637 254, 112, 254, 254, 44, 44, 74, 75, 391, 392,
638 393, 513, 331, 520, 121, 394, 113, 325, 51, 114,
639 495, 564, 118, 300, 300, 300, 120, 513, 302, 302,
640 302, 122, 238, 325, 51, 128, 570, 351, 352, 302,
641 135, 504, 130, 294, 137, 302, 302, 513, 325, 51,
642 138, 524, 140, 325, 51, 300, 254, 218, 219, 220,
643 221, 300, 300, 302, 145, 336, 142, 379, 380, 302,
644 302, 531, 532, 141, 254, 254, 254, 154, 254, 151,
645 254, 155, 254, 254, 153, 54, 254, 254, 254, 254,
646 254, 254, 131, 132, 157, 254, 467, 468, 158, 495,
647 195, 195, 185, 159, 2, 3, 4, 5, 179, 6,
648 160, 7, 8, 9, 254, 254, 10, 38, 38, 32,
649 32, 180, 11, 182, 254, 254, 189, 12, 521, 13,
650 207, 14, 41, 41, 27, 27, 357, 223, 358, 359,
651 360, 224, 361, 362, 302, 302, 15, 236, 225, 495,
652 229, 230, 234, 241, 243, 255, 257, 259, 16, 260,
653 301, 17, 302, 18, 19, 303, 238, 304, 305, 254,
654 20, 21, 22, 495, 266, 306, 307, 267, 319, 308,
655 311, 190, 332, 495, 340, 23, 24, 25, 268, 198,
656 26, 341, 269, 270, 344, 349, 350, 378, 355, 356,
657 27, 28, 364, 300, 271, 272, 273, 274, 275, 276,
658 277, 369, 278, 29, 72, 73, 382, 370, 371, 372,
659 374, 279, 280, 383, 281, 282, 283, 284, 285, 30,
660 384, 385, 386, 286, 287, 288, 399, 402, 303, 289,
661 238, 238, 238, 403, 238, 436, 238, 448, 238, 238,
662 449, 458, 238, 238, 238, 238, 238, 237, 459, 519,
663 473, 238, 267, 466, 475, 481, 290, 300, 480, 485,
664 486, 291, 488, 268, 484, 497, 498, 269, 270, 501,
665 238, 238, 499, 523, 292, 502, 509, 525, 526, 271,
666 272, 273, 274, 275, 276, 277, 527, 278, 528, 59,
667 451, 536, 529, 254, 537, 538, 279, 280, 540, 281,
668 282, 283, 284, 285, 267, 542, 560, 543, 286, 287,
669 288, 553, 300, 561, 289, 268, 562, 569, 563, 269,
670 270, 574, 576, 565, 577, 114, 56, 117, 582, 263,
671 585, 271, 272, 273, 274, 275, 276, 277, 25, 278,
672 587, 290, 84, 270, 300, 126, 291, 216, 279, 280,
673 229, 281, 282, 283, 284, 285, 363, 472, 566, 292,
674 286, 287, 288, 233, 572, 584, 289, 254, 254, 254,
675 530, 254, 535, 254, 59, 254, 254, 583, 567, 254,
676 254, 254, 254, 254, 254, 510, 558, 296, 254, 300,
677 324, 447, 444, 290, 47, 339, 0, 0, 291, 0,
678 0, 0, 0, 0, 0, 0, 0, 254, 254, 0,
679 0, 292, 300, 300, 0, 0, 300, 300, 0, 0,
680 300, 300, 0, 0, 303, 0, 59, 0, 0, 0,
681 0, 0, 0, 300, 0, 0, 0, 300, 300, 0,
682 0, 0, 0, 0, 0, 0, 0, 0, 303, 0,
683 0, 303, 303, 0, 0, 0, 0, 0, 0, 0,
684 300, 0, 0, 300, 300, 300, 0, 0, 0, 0,
685 0, 0, 303, 303, 0, 300, 300, 300, 0, 0,
686 0, 300, 300, 300, 300, 0, 0, 0, 0, 300,
687 300, 300, 300, 300, 300, 303, 301, 0, 303, 303,
688 303, 0, 0, 0, 0, 0, 0, 300, 300, 176,
689 303, 303, 303, 300, 300, 0, 303, 303, 303, 303,
690 0, 0, 0, 0, 303, 303, 303, 303, 303, 303,
691 0, 0, 300, 0, 0, 300, 300, 0, 0, 0,
692 0, 0, 303, 0, 0, 0, 427, 0, 303, 303,
693 0, 0, 0, 0, 0, 0, 300, 300, 0, 0,
694 0, 0, 0, 0, 0, 300, 0, 0, 0, 0,
695 0, 0, 0, 0, 376, 0, 0, 0, 0, 300,
696 0, 0, 300, 300, 300, 0, 0, 0, 0, 300,
697 300, 0, 300, 300, 300, 300, 300, 0, 0, 0,
698 300, 300, 300, 300, 0, 0, 0, 0, 300, 300,
699 300, 300, 300, 300, 300, 0, 0, 0, 0, 0,
700 0, 0, 0, 0, 0, 0, 300, 0, 304, 0,
701 0, 0, 300, 300, 0, 0, 300, 0, 0, 300,
702 300, 300, 0, 0, 0, 0, 0, 0, 0, 0,
703 0, 0, 304, 0, 0, 304, 304, 300, 300, 300,
704 300, 0, 0, 0, 0, 300, 300, 300, 300, 300,
705 300, 0, 0, 0, 0, 0, 0, 304, 0, 0,
706 413, 0, 0, 0, 0, 0, 0, 0, 0, 300,
707 300, 0, 162, 0, 0, 0, 0, 0, 0, 304,
708 0, 0, 304, 304, 304, 0, 0, 0, 0, 0,
709 0, 0, 0, 0, 0, 0, 0, 163, 164, 165,
710 304, 304, 304, 304, 0, 0, 0, 0, 304, 304,
711 304, 304, 304, 304, 0, 166, 167, 168, 169, 0,
712 0, 0, 0, 170, 171, 172, 173, 174, 175, 0,
713 0, 0, 304, 304, 163, 414, 165, 162, 415, 0,
714 416, 0, 417, 418, 0, 0, 419, 420, 421, 422,
715 423, 302, 0, 0, 0, 424, 0, 0, 0, 0,
716 0, 0, 163, 164, 165, 0, 0, 0, 0, 0,
717 0, 0, 0, 162, 425, 426, 302, 302, 302, 0,
718 166, 167, 168, 169, 0, 0, 0, 300, 170, 171,
719 172, 173, 174, 175, 302, 302, 302, 302, 163, 164,
720 165, 0, 302, 302, 302, 302, 302, 302, 0, 0,
721 0, 0, 300, 300, 300, 0, 166, 167, 168, 169,
722 0, 0, 0, 0, 170, 171, 172, 173, 174, 175,
723 300, 300, 300, 300, 0, 0, 0, 0, 300, 300,
724 300, 300, 300, 300,
725};
726const short yycheck[] =
727 { 14,
728 7, 4, 91, 137, 138, 10, 140, 141, 10, 12,
729 128, 10, 19, 10, 123, 3, 43, 43, 45, 45,
730 154, 43, 43, 45, 45, 125, 255, 333, 123, 45,
731 310, 123, 10, 245, 314, 415, 434, 123, 427, 44,
732 260, 125, 176, 10, 10, 44, 125, 44, 328, 329,
733 244, 125, 237, 125, 125, 58, 61, 191, 10, 125,
734 260, 120, 275, 10, 10, 53, 10, 335, 127, 266,
735 182, 282, 10, 60, 61, 62, 273, 61, 425, 426,
736 10, 263, 89, 265, 10, 10, 10, 10, 257, 10,
737 311, 312, 107, 61, 311, 312, 340, 44, 381, 340,
738 159, 160, 262, 340, 107, 61, 240, 337, 257, 10,
739 10, 10, 281, 61, 44, 284, 285, 251, 123, 44,
740 125, 61, 234, 44, 381, 319, 125, 286, 125, 61,
741 264, 411, 281, 10, 382, 284, 285, 381, 323, 123,
742 381, 371, 372, 257, 381, 152, 305, 125, 495, 382,
743 497, 381, 382, 370, 381, 123, 381, 123, 125, 328,
744 381, 429, 382, 552, 275, 257, 169, 44, 381, 125,
745 381, 381, 290, 125, 10, 573, 310, 123, 125, 328,
746 314, 125, 382, 257, 273, 491, 320, 125, 568, 281,
747 324, 198, 284, 285, 328, 329, 382, 409, 381, 381,
748 125, 125, 125, 381, 125, 390, 435, 281, 44, 280,
749 284, 285, 381, 407, 280, 326, 327, 288, 289, 336,
750 381, 382, 288, 289, 125, 125, 125, 123, 508, 343,
751 344, 345, 381, 329, 330, 280, 328, 293, 10, 275,
752 276, 280, 376, 288, 289, 381, 123, 373, 125, 288,
753 289, 381, 257, 381, 328, 535, 312, 342, 246, 61,
754 263, 325, 379, 380, 10, 361, 546, 363, 402, 10,
755 388, 274, 381, 382, 281, 334, 556, 411, 256, 282,
756 287, 381, 289, 271, 272, 263, 381, 567, 10, 381,
757 484, 269, 572, 271, 272, 381, 382, 381, 382, 10,
758 305, 10, 381, 382, 10, 283, 10, 381, 10, 381,
759 382, 266, 267, 268, 350, 276, 277, 257, 381, 382,
760 10, 305, 257, 10, 518, 10, 331, 332, 333, 10,
761 335, 10, 337, 10, 339, 340, 10, 305, 343, 344,
762 345, 346, 347, 348, 343, 381, 348, 352, 282, 305,
763 357, 358, 359, 360, 382, 382, 382, 305, 365, 366,
764 382, 382, 378, 351, 558, 305, 371, 372, 326, 327,
765 375, 378, 382, 305, 342, 262, 381, 382, 467, 468,
766 257, 381, 381, 382, 381, 382, 381, 382, 375, 376,
767 377, 375, 246, 10, 47, 382, 381, 381, 382, 278,
768 415, 535, 381, 343, 344, 345, 381, 375, 343, 344,
769 345, 47, 123, 381, 382, 348, 550, 271, 272, 375,
770 314, 424, 381, 125, 123, 381, 382, 375, 381, 382,
771 10, 438, 123, 381, 382, 375, 10, 353, 354, 355,
772 356, 381, 382, 375, 275, 10, 374, 367, 368, 381,
773 382, 458, 459, 123, 331, 332, 333, 123, 335, 381,
774 337, 123, 339, 340, 381, 381, 343, 344, 345, 346,
775 347, 348, 311, 312, 382, 352, 319, 320, 382, 494,
776 326, 327, 125, 381, 256, 257, 258, 259, 381, 261,
777 382, 263, 264, 265, 371, 372, 268, 381, 382, 381,
778 382, 382, 274, 381, 381, 382, 381, 279, 125, 281,
779 334, 283, 381, 382, 381, 382, 293, 382, 295, 296,
780 297, 382, 299, 300, 381, 382, 298, 125, 381, 544,
781 381, 381, 381, 125, 125, 123, 123, 382, 310, 276,
782 382, 313, 382, 315, 316, 382, 257, 382, 382, 123,
783 322, 323, 324, 568, 256, 382, 382, 259, 343, 382,
784 381, 381, 381, 578, 382, 337, 338, 339, 270, 263,
785 342, 381, 274, 275, 10, 276, 381, 342, 382, 382,
786 352, 353, 381, 61, 286, 287, 288, 289, 290, 291,
787 292, 262, 294, 365, 371, 372, 289, 381, 381, 381,
788 318, 303, 304, 10, 306, 307, 308, 309, 310, 381,
789 10, 381, 381, 315, 316, 317, 382, 10, 61, 321,
790 331, 332, 333, 125, 335, 125, 337, 382, 339, 340,
791 381, 296, 343, 344, 345, 346, 347, 348, 302, 256,
792 125, 352, 259, 381, 125, 341, 348, 125, 382, 125,
793 125, 353, 125, 270, 343, 381, 381, 274, 275, 382,
794 371, 372, 381, 10, 366, 382, 381, 381, 381, 286,
795 287, 288, 289, 290, 291, 292, 381, 294, 10, 381,
796 293, 369, 382, 257, 382, 382, 303, 304, 125, 306,
797 307, 308, 309, 310, 259, 381, 10, 381, 315, 316,
798 317, 381, 61, 10, 321, 270, 381, 125, 381, 274,
799 275, 125, 125, 382, 381, 282, 10, 123, 381, 10,
800 381, 286, 287, 288, 289, 290, 291, 292, 10, 294,
801 381, 348, 10, 381, 381, 10, 353, 125, 303, 304,
802 125, 306, 307, 308, 309, 310, 278, 381, 539, 366,
803 315, 316, 317, 177, 554, 580, 321, 331, 332, 333,
804 452, 335, 469, 337, 381, 339, 340, 578, 544, 343,
805 344, 345, 346, 347, 348, 429, 516, 204, 352, 257,
806 242, 343, 338, 348, 1, 259, -1, -1, 353, -1,
807 -1, -1, -1, -1, -1, -1, -1, 371, 372, -1,
808 -1, 366, 280, 281, -1, -1, 284, 285, -1, -1,
809 288, 289, -1, -1, 257, -1, 381, -1, -1, -1,
810 -1, -1, -1, 125, -1, -1, -1, 305, 306, -1,
811 -1, -1, -1, -1, -1, -1, -1, -1, 281, -1,
812 -1, 284, 285, -1, -1, -1, -1, -1, -1, -1,
813 328, -1, -1, 331, 332, 333, -1, -1, -1, -1,
814 -1, -1, 305, 306, -1, 343, 344, 345, -1, -1,
815 -1, 349, 350, 351, 352, -1, -1, -1, -1, 357,
816 358, 359, 360, 361, 362, 328, 125, -1, 331, 332,
817 333, -1, -1, -1, -1, -1, -1, 375, 257, 123,
818 343, 344, 345, 381, 382, -1, 349, 350, 351, 352,
819 -1, -1, -1, -1, 357, 358, 359, 360, 361, 362,
820 -1, -1, 281, -1, -1, 284, 285, -1, -1, -1,
821 -1, -1, 375, -1, -1, -1, 123, -1, 381, 382,
822 -1, -1, -1, -1, -1, -1, 305, 306, -1, -1,
823 -1, -1, -1, -1, -1, 257, -1, -1, -1, -1,
824 -1, -1, -1, -1, 123, -1, -1, -1, -1, 328,
825 -1, -1, 331, 332, 333, -1, -1, -1, -1, 281,
826 125, -1, 284, 285, 343, 344, 345, -1, -1, -1,
827 349, 350, 351, 352, -1, -1, -1, -1, 357, 358,
828 359, 360, 361, 362, 306, -1, -1, -1, -1, -1,
829 -1, -1, -1, -1, -1, -1, 375, -1, 257, -1,
830 -1, -1, 381, 382, -1, -1, 328, -1, -1, 331,
831 332, 333, -1, -1, -1, -1, -1, -1, -1, -1,
832 -1, -1, 281, -1, -1, 284, 285, 349, 350, 351,
833 352, -1, -1, -1, -1, 357, 358, 359, 360, 361,
834 362, -1, -1, -1, -1, -1, -1, 306, -1, -1,
835 257, -1, -1, -1, -1, -1, -1, -1, -1, 381,
836 382, -1, 306, -1, -1, -1, -1, -1, -1, 328,
837 -1, -1, 331, 332, 333, -1, -1, -1, -1, -1,
838 -1, -1, -1, -1, -1, -1, -1, 331, 332, 333,
839 349, 350, 351, 352, -1, -1, -1, -1, 357, 358,
840 359, 360, 361, 362, -1, 349, 350, 351, 352, -1,
841 -1, -1, -1, 357, 358, 359, 360, 361, 362, -1,
842 -1, -1, 381, 382, 331, 332, 333, 306, 335, -1,
843 337, -1, 339, 340, -1, -1, 343, 344, 345, 346,
844 347, 306, -1, -1, -1, 352, -1, -1, -1, -1,
845 -1, -1, 331, 332, 333, -1, -1, -1, -1, -1,
846 -1, -1, -1, 306, 371, 372, 331, 332, 333, -1,
847 349, 350, 351, 352, -1, -1, -1, 306, 357, 358,
848 359, 360, 361, 362, 349, 350, 351, 352, 331, 332,
849 333, -1, 357, 358, 359, 360, 361, 362, -1, -1,
850 -1, -1, 331, 332, 333, -1, 349, 350, 351, 352,
851 -1, -1, -1, -1, 357, 358, 359, 360, 361, 362,
852 349, 350, 351, 352, -1, -1, -1, -1, 357, 358,
853 359, 360, 361, 362,
854};
855#define YYFINAL1 1
856#ifndef YYDEBUG0
857#define YYDEBUG0 0
858#endif
859#define YYMAXTOKEN382 382
860#if YYDEBUG0
861const char * const yyname[] =
862 {
863"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,
8640,0,0,0,0,0,0,0,0,0,0,0,"'+'","','","'-'",0,"'/'",0,0,0,0,0,0,0,0,0,0,0,0,"'<'",
865"'='","'>'",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,
8660,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,
8670,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,
8680,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,
8690,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,
8700,0,0,0,"AS","ROUTERID","HOLDTIME","YMIN","LISTEN","ON","FIBUPDATE",
871"FIBPRIORITY","RTABLE","NONE","UNICAST","VPN","RD","EXPORT","EXPORTTRGT",
872"IMPORTTRGT","DEFAULTROUTE","RDE","RIB","EVALUATE","IGNORE","COMPARE","RTR",
873"PORT","GROUP","NEIGHBOR","NETWORK","EBGP","IBGP","LOCALAS","REMOTEAS","DESCR",
874"LOCALADDR","MULTIHOP","PASSIVE","MAXPREFIX","RESTART","ANNOUNCE",
875"CAPABILITIES","REFRESH","AS4BYTE","CONNECTRETRY","ENHANCED","ADDPATH","SEND",
876"RECV","DEMOTE","ENFORCE","NEIGHBORAS","ASOVERRIDE","REFLECTOR","DEPEND","DOWN",
877"DUMP","IN","OUT","SOCKET","RESTRICTED","LOG","TRANSPARENT","TCP","MD5SIG",
878"PASSWORD","KEY","TTLSECURITY","ALLOW","DENY","MATCH","QUICK","FROM","TO","ANY",
879"CONNECTED","STATIC","COMMUNITY","EXTCOMMUNITY","LARGECOMMUNITY","DELETE",
880"PREFIX","PREFIXLEN","PREFIXSET","ROASET","ORIGINSET","OVS","EXPIRES","ASSET",
881"SOURCEAS","TRANSITAS","PEERAS","MAXASLEN","MAXASSEQ","SET","LOCALPREF","MED",
882"METRIC","NEXTHOP","REJECT","BLACKHOLE","NOMODIFY","SELF","PREPEND_SELF",
883"PREPEND_PEER","PFTABLE","WEIGHT","RTLABEL","ORIGIN","PRIORITY","ERROR",
884"INCLUDE","IPSEC","ESP","AH","SPI","IKE","IPV4","IPV6","QUALIFY","VIA","NE",
885"LE","GE","XRANGE","LONGER","MAXLEN","STRING","NUMBER",
886};
887const char * const yyrule[] =
888 {"$accept : grammar",
889"grammar :",
890"grammar : grammar '\\n'",
891"grammar : grammar varset '\\n'",
892"grammar : grammar include '\\n'",
893"grammar : grammar as_set '\\n'",
894"grammar : grammar prefixset '\\n'",
895"grammar : grammar roa_set '\\n'",
896"grammar : grammar origin_set '\\n'",
897"grammar : grammar rtr '\\n'",
898"grammar : grammar rib '\\n'",
899"grammar : grammar conf_main '\\n'",
900"grammar : grammar l3vpn '\\n'",
901"grammar : grammar neighbor '\\n'",
902"grammar : grammar group '\\n'",
903"grammar : grammar filterrule '\\n'",
904"grammar : grammar error '\\n'",
905"asnumber : NUMBER",
906"as4number : STRING",
907"as4number : asnumber",
908"as4number_any : STRING",
909"as4number_any : asnumber",
910"string : string STRING",
911"string : STRING",
912"yesno : STRING",
913"varset : STRING '=' string",
914"include : INCLUDE STRING",
915"$$1 :",
916"as_set : ASSET STRING '{' optnl $$1 as_set_l optnl '}'",
917"as_set : ASSET STRING '{' optnl '}'",
918"as_set_l : as4number_any",
919"as_set_l : as_set_l comma as4number_any",
920"$$2 :",
921"prefixset : PREFIXSET STRING '{' optnl $$2 prefixset_l optnl '}'",
922"prefixset : PREFIXSET STRING '{' optnl '}'",
923"prefixset_l : prefixset_item",
924"prefixset_l : prefixset_l comma prefixset_item",
925"prefixset_item : prefix prefixlenop",
926"$$3 :",
927"roa_set : ROASET '{' optnl $$3 roa_set_l optnl '}'",
928"roa_set : ROASET '{' optnl '}'",
929"$$4 :",
930"origin_set : ORIGINSET STRING '{' optnl $$4 roa_set_l optnl '}'",
931"origin_set : ORIGINSET STRING '{' optnl '}'",
932"expires :",
933"expires : EXPIRES NUMBER",
934"roa_set_l : prefixset_item SOURCEAS as4number_any expires",
935"roa_set_l : roa_set_l comma prefixset_item SOURCEAS as4number_any expires",
936"rtr : RTR address",
937"$$5 :",
938"rtr : RTR address $$5 '{' optnl rtropt_l optnl '}'",
939"rtropt_l : rtropt",
940"rtropt_l : rtropt_l optnl rtropt",
941"rtropt : DESCR STRING",
942"rtropt : LOCALADDR address",
943"rtropt : PORT NUMBER",
944"conf_main : AS as4number",
945"conf_main : AS as4number asnumber",
946"conf_main : ROUTERID address",
947"conf_main : HOLDTIME NUMBER",
948"conf_main : HOLDTIME YMIN NUMBER",
949"conf_main : LISTEN ON address",
950"conf_main : FIBPRIORITY NUMBER",
951"conf_main : FIBUPDATE yesno",
952"conf_main : TRANSPARENT yesno",
953"conf_main : REJECT ASSET yesno",
954"conf_main : LOG STRING",
955"conf_main : network",
956"conf_main : DUMP STRING STRING optnumber",
957"conf_main : DUMP RIB STRING STRING STRING optnumber",
958"conf_main : mrtdump",
959"conf_main : RDE STRING EVALUATE",
960"conf_main : RDE STRING IGNORE",
961"conf_main : RDE MED COMPARE STRING",
962"conf_main : RDE EVALUATE STRING",
963"conf_main : NEXTHOP QUALIFY VIA STRING",
964"conf_main : RTABLE NUMBER",
965"conf_main : CONNECTRETRY NUMBER",
966"conf_main : SOCKET STRING restricted",
967"$$6 :",
968"rib : RDE RIB STRING $$6 ribopts",
969"ribopts : fibupdate",
970"ribopts : RTABLE NUMBER fibupdate",
971"ribopts : yesno EVALUATE",
972"fibupdate :",
973"fibupdate : FIBUPDATE yesno",
974"mrtdump : DUMP STRING inout STRING optnumber",
975"network : NETWORK prefix filter_set",
976"network : NETWORK PREFIXSET STRING filter_set",
977"network : NETWORK family RTLABEL STRING filter_set",
978"network : NETWORK family PRIORITY NUMBER filter_set",
979"network : NETWORK family nettype filter_set",
980"inout : IN",
981"inout : OUT",
982"restricted : RESTRICTED",
983"restricted :",
984"address : STRING",
985"prefix : STRING '/' NUMBER",
986"prefix : NUMBER '/' NUMBER",
987"addrspec : address",
988"addrspec : prefix",
989"optnumber :",
990"optnumber : NUMBER",
991"$$7 :",
992"l3vpn : VPN STRING ON STRING $$7 '{' l3vpnopts_l '}'",
993"l3vpnopts_l :",
994"l3vpnopts_l : l3vpnopts_l '\\n'",
995"l3vpnopts_l : l3vpnopts_l l3vpnopts '\\n'",
996"l3vpnopts_l : l3vpnopts_l error '\\n'",
997"l3vpnopts : RD STRING",
998"l3vpnopts : EXPORTTRGT STRING STRING",
999"l3vpnopts : IMPORTTRGT STRING STRING",
1000"l3vpnopts : FIBUPDATE yesno",
1001"l3vpnopts : network",
1002"$$8 :",
1003"$$9 :",
1004"neighbor : $$8 NEIGHBOR addrspec $$9 peeropts_h",
1005"$$10 :",
1006"group : GROUP string $$10 '{' groupopts_l '}'",
1007"groupopts_l :",
1008"groupopts_l : groupopts_l '\\n'",
1009"groupopts_l : groupopts_l peeropts '\\n'",
1010"groupopts_l : groupopts_l neighbor '\\n'",
1011"groupopts_l : groupopts_l error '\\n'",
1012"peeropts_h : '{' '\\n' peeropts_l '}'",
1013"peeropts_h : '{' peeropts '}'",
1014"peeropts_h :",
1015"peeropts_l :",
1016"peeropts_l : peeropts_l '\\n'",
1017"peeropts_l : peeropts_l peeropts '\\n'",
1018"peeropts_l : peeropts_l error '\\n'",
1019"peeropts : REMOTEAS as4number",
1020"peeropts : LOCALAS as4number",
1021"peeropts : LOCALAS as4number asnumber",
1022"peeropts : DESCR string",
1023"peeropts : LOCALADDR address",
1024"peeropts : yesno LOCALADDR",
1025"peeropts : MULTIHOP NUMBER",
1026"peeropts : PASSIVE",
1027"peeropts : DOWN",
1028"peeropts : DOWN STRING",
1029"peeropts : RIB STRING",
1030"peeropts : HOLDTIME NUMBER",
1031"peeropts : HOLDTIME YMIN NUMBER",
1032"peeropts : ANNOUNCE family safi",
1033"peeropts : ANNOUNCE CAPABILITIES yesno",
1034"peeropts : ANNOUNCE REFRESH yesno",
1035"peeropts : ANNOUNCE ENHANCED REFRESH yesno",
1036"peeropts : ANNOUNCE RESTART yesno",
1037"peeropts : ANNOUNCE AS4BYTE yesno",
1038"peeropts : ANNOUNCE ADDPATH RECV yesno",
1039"peeropts : EXPORT NONE",
1040"peeropts : EXPORT DEFAULTROUTE",
1041"peeropts : ENFORCE NEIGHBORAS yesno",
1042"peeropts : ENFORCE LOCALAS yesno",
1043"peeropts : ASOVERRIDE yesno",
1044"peeropts : MAXPREFIX NUMBER restart",
1045"peeropts : MAXPREFIX NUMBER OUT restart",
1046"peeropts : TCP MD5SIG PASSWORD string",
1047"peeropts : TCP MD5SIG KEY string",
1048"peeropts : IPSEC espah IKE",
1049"peeropts : IPSEC espah inout SPI NUMBER STRING STRING encspec",
1050"peeropts : TTLSECURITY yesno",
1051"peeropts : SET filter_set_opt",
1052"peeropts : SET '{' optnl filter_set_l optnl '}'",
1053"peeropts : mrtdump",
1054"peeropts : REFLECTOR",
1055"peeropts : REFLECTOR address",
1056"peeropts : DEPEND ON STRING",
1057"peeropts : DEMOTE STRING",
1058"peeropts : TRANSPARENT yesno",
1059"peeropts : LOG STRING",
1060"peeropts : REJECT ASSET yesno",
1061"peeropts : RDE EVALUATE STRING",
1062"restart :",
1063"restart : RESTART NUMBER",
1064"family : IPV4",
1065"family : IPV6",
1066"safi : NONE",
1067"safi : UNICAST",
1068"safi : VPN",
1069"nettype : STATIC",
1070"nettype : CONNECTED",
1071"espah : ESP",
1072"espah : AH",
1073"encspec :",
1074"encspec : STRING STRING",
1075"filterrule : action quick filter_rib_h direction filter_peer_h filter_match_h filter_set",
1076"action : ALLOW",
1077"action : DENY",
1078"action : MATCH",
1079"quick :",
1080"quick : QUICK",
1081"direction : FROM",
1082"direction : TO",
1083"filter_rib_h :",
1084"filter_rib_h : RIB filter_rib",
1085"filter_rib_h : RIB '{' optnl filter_rib_l optnl '}'",
1086"filter_rib_l : filter_rib",
1087"filter_rib_l : filter_rib_l comma filter_rib",
1088"filter_rib : STRING",
1089"filter_peer_h : filter_peer",
1090"filter_peer_h : '{' optnl filter_peer_l optnl '}'",
1091"filter_peer_l : filter_peer",
1092"filter_peer_l : filter_peer_l comma filter_peer",
1093"filter_peer : ANY",
1094"filter_peer : address",
1095"filter_peer : AS as4number",
1096"filter_peer : GROUP STRING",
1097"filter_peer : EBGP",
1098"filter_peer : IBGP",
1099"filter_prefix_h : IPV4 prefixlenop",
1100"filter_prefix_h : IPV6 prefixlenop",
1101"filter_prefix_h : PREFIX filter_prefix",
1102"filter_prefix_h : PREFIX '{' filter_prefix_m '}'",
1103"filter_prefix_m : filter_prefix_l",
1104"filter_prefix_m : '{' filter_prefix_l '}'",
1105"filter_prefix_m : '{' filter_prefix_l '}' filter_prefix_m",
1106"filter_prefix_l : filter_prefix",
1107"filter_prefix_l : filter_prefix_l comma filter_prefix",
1108"filter_prefix : prefix prefixlenop",
1109"filter_as_h : filter_as_t",
1110"filter_as_h : '{' filter_as_t_l '}'",
1111"filter_as_t_l : filter_as_t",
1112"filter_as_t_l : filter_as_t_l comma filter_as_t",
1113"filter_as_t : filter_as_type filter_as",
1114"filter_as_t : filter_as_type '{' filter_as_l_h '}'",
1115"filter_as_t : filter_as_type ASSET STRING",
1116"filter_as_l_h : filter_as_l",
1117"filter_as_l_h : '{' filter_as_l '}'",
1118"filter_as_l_h : '{' filter_as_l '}' filter_as_l_h",
1119"filter_as_l : filter_as",
1120"filter_as_l : filter_as_l comma filter_as",
1121"filter_as : as4number_any",
1122"filter_as : NEIGHBORAS",
1123"filter_as : equalityop as4number_any",
1124"filter_as : as4number_any binaryop as4number_any",
1125"filter_match_h :",
1126"$$11 :",
1127"filter_match_h : $$11 filter_match",
1128"filter_match : filter_elm",
1129"filter_match : filter_match filter_elm",
1130"filter_elm : filter_prefix_h",
1131"filter_elm : filter_as_h",
1132"filter_elm : MAXASLEN NUMBER",
1133"filter_elm : MAXASSEQ NUMBER",
1134"filter_elm : community STRING",
1135"filter_elm : EXTCOMMUNITY STRING STRING",
1136"filter_elm : EXTCOMMUNITY OVS STRING",
1137"filter_elm : NEXTHOP address",
1138"filter_elm : NEXTHOP NEIGHBOR",
1139"filter_elm : PREFIXSET STRING prefixlenop",
1140"filter_elm : ORIGINSET STRING",
1141"filter_elm : OVS validity",
1142"prefixlenop :",
1143"prefixlenop : LONGER",
1144"prefixlenop : MAXLEN NUMBER",
1145"prefixlenop : PREFIXLEN unaryop NUMBER",
1146"prefixlenop : PREFIXLEN NUMBER binaryop NUMBER",
1147"filter_as_type : AS",
1148"filter_as_type : SOURCEAS",
1149"filter_as_type : TRANSITAS",
1150"filter_as_type : PEERAS",
1151"filter_set :",
1152"filter_set : SET filter_set_opt",
1153"filter_set : SET '{' optnl filter_set_l optnl '}'",
1154"filter_set_l : filter_set_l comma filter_set_opt",
1155"filter_set_l : filter_set_opt",
1156"community : COMMUNITY",
1157"community : LARGECOMMUNITY",
1158"delete :",
1159"delete : DELETE",
1160"filter_set_opt : LOCALPREF NUMBER",
1161"filter_set_opt : LOCALPREF '+' NUMBER",
1162"filter_set_opt : LOCALPREF '-' NUMBER",
1163"filter_set_opt : MED NUMBER",
1164"filter_set_opt : MED '+' NUMBER",
1165"filter_set_opt : MED '-' NUMBER",
1166"filter_set_opt : METRIC NUMBER",
1167"filter_set_opt : METRIC '+' NUMBER",
1168"filter_set_opt : METRIC '-' NUMBER",
1169"filter_set_opt : WEIGHT NUMBER",
1170"filter_set_opt : WEIGHT '+' NUMBER",
1171"filter_set_opt : WEIGHT '-' NUMBER",
1172"filter_set_opt : NEXTHOP address",
1173"filter_set_opt : NEXTHOP BLACKHOLE",
1174"filter_set_opt : NEXTHOP REJECT",
1175"filter_set_opt : NEXTHOP NOMODIFY",
1176"filter_set_opt : NEXTHOP SELF",
1177"filter_set_opt : PREPEND_SELF NUMBER",
1178"filter_set_opt : PREPEND_PEER NUMBER",
1179"filter_set_opt : ASOVERRIDE",
1180"filter_set_opt : PFTABLE STRING",
1181"filter_set_opt : RTLABEL STRING",
1182"filter_set_opt : community delete STRING",
1183"filter_set_opt : EXTCOMMUNITY delete STRING STRING",
1184"filter_set_opt : EXTCOMMUNITY delete OVS STRING",
1185"filter_set_opt : ORIGIN origincode",
1186"origincode : STRING",
1187"validity : STRING",
1188"optnl :",
1189"optnl : '\\n' optnl",
1190"comma :",
1191"comma : ','",
1192"comma : '\\n' optnl",
1193"comma : ',' '\\n' optnl",
1194"unaryop : '='",
1195"unaryop : NE",
1196"unaryop : LE",
1197"unaryop : '<'",
1198"unaryop : GE",
1199"unaryop : '>'",
1200"equalityop : '='",
1201"equalityop : NE",
1202"binaryop : '-'",
1203"binaryop : XRANGE",
1204};
1205#endif
1206#ifdef YYSTACKSIZE10000
1207#undef YYMAXDEPTH10000
1208#define YYMAXDEPTH10000 YYSTACKSIZE10000
1209#else
1210#ifdef YYMAXDEPTH10000
1211#define YYSTACKSIZE10000 YYMAXDEPTH10000
1212#else
1213#define YYSTACKSIZE10000 10000
1214#define YYMAXDEPTH10000 10000
1215#endif
1216#endif
1217#define YYINITSTACKSIZE200 200
1218/* LINTUSED */
1219int yydebug;
1220int yynerrs;
1221int yyerrflag;
1222int yychar;
1223short *yyssp;
1224YYSTYPE *yyvsp;
1225YYSTYPE yyval;
1226YYSTYPE yylval;
1227short *yyss;
1228short *yysslim;
1229YYSTYPE *yyvs;
1230unsigned int yystacksize;
1231int yyparse(void);
1232#line 2872 "/usr/src/usr.sbin/bgpd/parse.y"
1233
1234struct keywords {
1235 const char *k_name;
1236 int k_val;
1237};
1238
1239int
1240yyerror(const char *fmt, ...)
1241{
1242 va_list ap;
1243 char *msg;
1244
1245 file->errors++;
1246 va_start(ap, fmt)__builtin_va_start(ap, fmt);
1247 if (vasprintf(&msg, fmt, ap) == -1)
1248 fatalx("yyerror vasprintf");
1249 va_end(ap)__builtin_va_end(ap);
1250 logit(LOG_CRIT2, "%s:%d: %s", file->name, yylval.lineno, msg);
1251 free(msg);
1252 return (0);
1253}
1254
1255int
1256kw_cmp(const void *k, const void *e)
1257{
1258 return (strcmp(k, ((const struct keywords *)e)->k_name));
1259}
1260
1261int
1262lookup(char *s)
1263{
1264 /* this has to be sorted always */
1265 static const struct keywords keywords[] = {
1266 { "AS", AS257},
1267 { "IPv4", IPV4371},
1268 { "IPv6", IPV6372},
1269 { "add-path", ADDPATH300},
1270 { "ah", AH368},
1271 { "allow", ALLOW322},
1272 { "announce", ANNOUNCE294},
1273 { "any", ANY328},
1274 { "as-4byte", AS4BYTE297 },
1275 { "as-override", ASOVERRIDE306},
1276 { "as-set", ASSET342 },
1277 { "blackhole", BLACKHOLE354},
1278 { "capabilities", CAPABILITIES295},
1279 { "community", COMMUNITY331},
1280 { "compare", COMPARE278},
1281 { "connect-retry", CONNECTRETRY298},
1282 { "connected", CONNECTED329},
1283 { "default-route", DEFAULTROUTE273},
1284 { "delete", DELETE334},
1285 { "demote", DEMOTE303},
1286 { "deny", DENY323},
1287 { "depend", DEPEND308},
1288 { "descr", DESCR288},
1289 { "down", DOWN309},
1290 { "dump", DUMP310},
1291 { "ebgp", EBGP284},
1292 { "enforce", ENFORCE304},
1293 { "enhanced", ENHANCED299 },
1294 { "esp", ESP367},
1295 { "evaluate", EVALUATE276},
1296 { "expires", EXPIRES341},
1297 { "export", EXPORT270},
1298 { "export-target", EXPORTTRGT271},
1299 { "ext-community", EXTCOMMUNITY332},
1300 { "fib-priority", FIBPRIORITY264},
1301 { "fib-update", FIBUPDATE263},
1302 { "from", FROM326},
1303 { "group", GROUP281},
1304 { "holdtime", HOLDTIME259},
1305 { "ibgp", IBGP285},
1306 { "ignore", IGNORE277},
1307 { "ike", IKE370},
1308 { "import-target", IMPORTTRGT272},
1309 { "in", IN311},
1310 { "include", INCLUDE365},
1311 { "inet", IPV4371},
1312 { "inet6", IPV6372},
1313 { "ipsec", IPSEC366},
1314 { "key", KEY320},
1315 { "large-community", LARGECOMMUNITY333},
1316 { "listen", LISTEN261},
1317 { "local-address", LOCALADDR289},
1318 { "local-as", LOCALAS286},
1319 { "localpref", LOCALPREF349},
1320 { "log", LOG315},
1321 { "match", MATCH324},
1322 { "max-as-len", MAXASLEN346},
1323 { "max-as-seq", MAXASSEQ347},
1324 { "max-prefix", MAXPREFIX292},
1325 { "maxlen", MAXLEN380},
1326 { "md5sig", MD5SIG318},
1327 { "med", MED350},
1328 { "metric", METRIC351},
1329 { "min", YMIN260},
1330 { "multihop", MULTIHOP290},
1331 { "neighbor", NEIGHBOR282},
1332 { "neighbor-as", NEIGHBORAS305},
1333 { "network", NETWORK283},
1334 { "nexthop", NEXTHOP352},
1335 { "no-modify", NOMODIFY355},
1336 { "none", NONE266},
1337 { "on", ON262},
1338 { "or-longer", LONGER379},
1339 { "origin", ORIGIN362},
1340 { "origin-set", ORIGINSET339},
1341 { "out", OUT312},
1342 { "ovs", OVS340},
1343 { "passive", PASSIVE291},
1344 { "password", PASSWORD319},
1345 { "peer-as", PEERAS345},
1346 { "pftable", PFTABLE359},
1347 { "port", PORT280},
1348 { "prefix", PREFIX335},
1349 { "prefix-set", PREFIXSET337},
1350 { "prefixlen", PREFIXLEN336},
1351 { "prepend-neighbor", PREPEND_PEER358},
1352 { "prepend-self", PREPEND_SELF357},
1353 { "priority", PRIORITY363},
1354 { "qualify", QUALIFY373},
1355 { "quick", QUICK325},
1356 { "rd", RD269},
1357 { "rde", RDE274},
1358 { "recv", RECV302},
1359 { "refresh", REFRESH296 },
1360 { "reject", REJECT353},
1361 { "remote-as", REMOTEAS287},
1362 { "restart", RESTART293},
1363 { "restricted", RESTRICTED314},
1364 { "rib", RIB275},
1365 { "roa-set", ROASET338 },
1366 { "route-reflector", REFLECTOR307},
1367 { "router-id", ROUTERID258},
1368 { "rtable", RTABLE265},
1369 { "rtlabel", RTLABEL361},
1370 { "rtr", RTR279},
1371 { "self", SELF356},
1372 { "send", SEND301},
1373 { "set", SET348},
1374 { "socket", SOCKET313 },
1375 { "source-as", SOURCEAS343},
1376 { "spi", SPI369},
1377 { "static", STATIC330},
1378 { "tcp", TCP317},
1379 { "to", TO327},
1380 { "transit-as", TRANSITAS344},
1381 { "transparent-as", TRANSPARENT316},
1382 { "ttl-security", TTLSECURITY321},
1383 { "unicast", UNICAST267},
1384 { "via", VIA374},
1385 { "vpn", VPN268},
1386 { "weight", WEIGHT360}
1387 };
1388 const struct keywords *p;
1389
1390 p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]),
1391 sizeof(keywords[0]), kw_cmp);
1392
1393 if (p)
1394 return (p->k_val);
1395 else
1396 return (STRING381);
1397}
1398
1399#define START_EXPAND1 1
1400#define DONE_EXPAND2 2
1401
1402static int expanding;
1403
1404int
1405igetc(void)
1406{
1407 int c;
1408
1409 while (1) {
1410 if (file->ungetpos > 0)
1411 c = file->ungetbuf[--file->ungetpos];
1412 else
1413 c = getc(file->stream)(!__isthreaded ? (--(file->stream)->_r < 0 ? __srget
(file->stream) : (int)(*(file->stream)->_p++)) : (getc
)(file->stream))
;
1414
1415 if (c == START_EXPAND1)
1416 expanding = 1;
1417 else if (c == DONE_EXPAND2)
1418 expanding = 0;
1419 else
1420 break;
1421 }
1422 return (c);
1423}
1424
1425int
1426lgetc(int quotec)
1427{
1428 int c, next;
1429
1430 if (quotec) {
1431 if ((c = igetc()) == EOF(-1)) {
1432 yyerror("reached end of file while parsing "
1433 "quoted string");
1434 if (file == topfile || popfile() == EOF(-1))
1435 return (EOF(-1));
1436 return (quotec);
1437 }
1438 return (c);
1439 }
1440
1441 while ((c = igetc()) == '\\') {
1442 next = igetc();
1443 if (next != '\n') {
1444 c = next;
1445 break;
1446 }
1447 yylval.lineno = file->lineno;
1448 file->lineno++;
1449 }
1450
1451 if (c == EOF(-1)) {
1452 /*
1453 * Fake EOL when hit EOF for the first time. This gets line
1454 * count right if last line in included file is syntactically
1455 * invalid and has no newline.
1456 */
1457 if (file->eof_reached == 0) {
1458 file->eof_reached = 1;
1459 return ('\n');
1460 }
1461 while (c == EOF(-1)) {
1462 if (file == topfile || popfile() == EOF(-1))
1463 return (EOF(-1));
1464 c = igetc();
1465 }
1466 }
1467 return (c);
1468}
1469
1470void
1471lungetc(int c)
1472{
1473 if (c == EOF(-1))
1474 return;
1475
1476 if (file->ungetpos >= file->ungetsize) {
1477 void *p = reallocarray(file->ungetbuf, file->ungetsize, 2);
1478 if (p == NULL((void*)0))
1479 err(1, "lungetc");
1480 file->ungetbuf = p;
1481 file->ungetsize *= 2;
1482 }
1483 file->ungetbuf[file->ungetpos++] = c;
1484}
1485
1486int
1487findeol(void)
1488{
1489 int c;
1490
1491 /* skip to either EOF or the first real EOL */
1492 while (1) {
1493 c = lgetc(0);
1494 if (c == '\n') {
1495 file->lineno++;
1496 break;
1497 }
1498 if (c == EOF(-1))
1499 break;
1500 }
1501 return (ERROR364);
1502}
1503
1504int
1505yylex(void)
1506{
1507 char buf[8096];
1508 char *p, *val;
1509 int quotec, next, c;
1510 int token;
1511
1512top:
1513 p = buf;
1514 while ((c = lgetc(0)) == ' ' || c == '\t')
1515 ; /* nothing */
1516
1517 yylval.lineno = file->lineno;
1518 if (c == '#')
1519 while ((c = lgetc(0)) != '\n' && c != EOF(-1))
1520 ; /* nothing */
1521 if (c == '$' && !expanding) {
1522 while (1) {
1523 if ((c = lgetc(0)) == EOF(-1))
1524 return (0);
1525
1526 if (p + 1 >= buf + sizeof(buf) - 1) {
1527 yyerror("string too long");
1528 return (findeol());
1529 }
1530 if (isalnum(c) || c == '_') {
1531 *p++ = c;
1532 continue;
1533 }
1534 *p = '\0';
1535 lungetc(c);
1536 break;
1537 }
1538 val = symget(buf);
1539 if (val == NULL((void*)0)) {
1540 yyerror("macro '%s' not defined", buf);
1541 return (findeol());
1542 }
1543 p = val + strlen(val) - 1;
1544 lungetc(DONE_EXPAND2);
1545 while (p >= val) {
1546 lungetc((unsigned char)*p);
1547 p--;
1548 }
1549 lungetc(START_EXPAND1);
1550 goto top;
1551 }
1552
1553 switch (c) {
1554 case '\'':
1555 case '"':
1556 quotec = c;
1557 while (1) {
1558 if ((c = lgetc(quotec)) == EOF(-1))
1559 return (0);
1560 if (c == '\n') {
1561 file->lineno++;
1562 continue;
1563 } else if (c == '\\') {
1564 if ((next = lgetc(quotec)) == EOF(-1))
1565 return (0);
1566 if (next == quotec || next == ' ' ||
1567 next == '\t')
1568 c = next;
1569 else if (next == '\n') {
1570 file->lineno++;
1571 continue;
1572 } else
1573 lungetc(next);
1574 } else if (c == quotec) {
1575 *p = '\0';
1576 break;
1577 } else if (c == '\0') {
1578 yyerror("syntax error: unterminated quote");
1579 return (findeol());
1580 }
1581 if (p + 1 >= buf + sizeof(buf) - 1) {
1582 yyerror("string too long");
1583 return (findeol());
1584 }
1585 *p++ = c;
1586 }
1587 yylval.v.string = strdup(buf);
1588 if (yylval.v.string == NULL((void*)0))
1589 fatal("yylex: strdup");
1590 return (STRING381);
1591 case '!':
1592 next = lgetc(0);
1593 if (next == '=')
1594 return (NE375);
1595 lungetc(next);
1596 break;
1597 case '<':
1598 next = lgetc(0);
1599 if (next == '=')
1600 return (LE376);
1601 lungetc(next);
1602 break;
1603 case '>':
1604 next = lgetc(0);
1605 if (next == '<')
1606 return (XRANGE378);
1607 else if (next == '=')
1608 return (GE377);
1609 lungetc(next);
1610 break;
1611 }
1612
1613#define allowed_to_end_number(x)(isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' ||
x == '=')
\
1614 (isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' || x == '=')
1615
1616 if (c == '-' || isdigit(c)) {
1617 do {
1618 *p++ = c;
1619 if ((size_t)(p-buf) >= sizeof(buf)) {
1620 yyerror("string too long");
1621 return (findeol());
1622 }
1623 } while ((c = lgetc(0)) != EOF(-1) && isdigit(c));
1624 lungetc(c);
1625 if (p == buf + 1 && buf[0] == '-')
1626 goto nodigits;
1627 if (c == EOF(-1) || allowed_to_end_number(c)(isspace(c) || c == ')' || c ==',' || c == '/' || c == '}' ||
c == '=')
) {
1628 const char *errstr = NULL((void*)0);
1629
1630 *p = '\0';
1631 yylval.v.number = strtonum(buf, LLONG_MIN(-9223372036854775807LL -1LL),
1632 LLONG_MAX9223372036854775807LL, &errstr);
1633 if (errstr) {
1634 yyerror("\"%s\" invalid number: %s",
1635 buf, errstr);
1636 return (findeol());
1637 }
1638 return (NUMBER382);
1639 } else {
1640nodigits:
1641 while (p > buf + 1)
1642 lungetc((unsigned char)*--p);
1643 c = (unsigned char)*--p;
1644 if (c == '-')
1645 return (c);
1646 }
1647 }
1648
1649#define allowed_in_string(x)(isalnum(x) || (ispunct(x) && x != '(' && x !=
')' && x != '{' && x != '}' && x != '<'
&& x != '>' && x != '!' && x != '='
&& x != '/' && x != '#' && x != ',')
)
\
1650 (isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \
1651 x != '{' && x != '}' && x != '<' && x != '>' && \
1652 x != '!' && x != '=' && x != '/' && x != '#' && \
1653 x != ','))
1654
1655 if (isalnum(c) || c == ':' || c == '_' || c == '*') {
1656 do {
1657 *p++ = c;
1658 if ((size_t)(p-buf) >= sizeof(buf)) {
1659 yyerror("string too long");
1660 return (findeol());
1661 }
1662 } 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 != ',')
)
));
1663 lungetc(c);
1664 *p = '\0';
1665 if ((token = lookup(buf)) == STRING381)
1666 if ((yylval.v.string = strdup(buf)) == NULL((void*)0))
1667 fatal("yylex: strdup");
1668 return (token);
1669 }
1670 if (c == '\n') {
1671 yylval.lineno = file->lineno;
1672 file->lineno++;
1673 }
1674 if (c == EOF(-1))
1675 return (0);
1676 return (c);
1677}
1678
1679int
1680check_file_secrecy(int fd, const char *fname)
1681{
1682 struct stat st;
1683
1684 if (fstat(fd, &st)) {
1685 log_warn("cannot stat %s", fname);
1686 return (-1);
1687 }
1688 return (0);
1689}
1690
1691struct file *
1692pushfile(const char *name, int secret)
1693{
1694 struct file *nfile;
1695
1696 if ((nfile = calloc(1, sizeof(struct file))) == NULL((void*)0)) {
1697 log_warn("%s", __func__);
1698 return (NULL((void*)0));
1699 }
1700 if ((nfile->name = strdup(name)) == NULL((void*)0)) {
1701 log_warn("%s", __func__);
1702 free(nfile);
1703 return (NULL((void*)0));
1704 }
1705 if ((nfile->stream = fopen(nfile->name, "r")) == NULL((void*)0)) {
1706 log_warn("%s: %s", __func__, nfile->name);
1707 free(nfile->name);
1708 free(nfile);
1709 return (NULL((void*)0));
1710 }
1711 if (secret &&
1712 check_file_secrecy(fileno(nfile->stream)(!__isthreaded ? ((nfile->stream)->_file) : (fileno)(nfile
->stream))
, nfile->name)) {
1713 fclose(nfile->stream);
1714 free(nfile->name);
1715 free(nfile);
1716 return (NULL((void*)0));
1717 }
1718 nfile->lineno = TAILQ_EMPTY(&files)(((&files)->tqh_first) == ((void*)0)) ? 1 : 0;
1719 nfile->ungetsize = 16;
1720 nfile->ungetbuf = malloc(nfile->ungetsize);
1721 if (nfile->ungetbuf == NULL((void*)0)) {
1722 log_warn("%s", __func__);
1723 fclose(nfile->stream);
1724 free(nfile->name);
1725 free(nfile);
1726 return (NULL((void*)0));
1727 }
1728 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)
;
1729 return (nfile);
1730}
1731
1732int
1733popfile(void)
1734{
1735 struct file *prev;
1736
1737 if ((prev = TAILQ_PREV(file, files, entry)(*(((struct files *)((file)->entry.tqe_prev))->tqh_last
))
) != NULL((void*)0))
1738 prev->errors += file->errors;
1739
1740 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)
;
1741 fclose(file->stream);
1742 free(file->name);
1743 free(file->ungetbuf);
1744 free(file);
1745 file = prev;
1746 return (file ? 0 : EOF(-1));
1747}
1748
1749static void
1750init_config(struct bgpd_config *c)
1751{
1752 u_int rdomid;
1753
1754 c->min_holdtime = MIN_HOLDTIME3;
1755 c->holdtime = INTERVAL_HOLD90;
1756 c->connectretry = INTERVAL_CONNECTRETRY120;
1757 c->bgpid = get_bgpid();
1758 c->fib_priority = RTP_BGP48;
1759 c->default_tableid = getrtable();
1760 ktable_exists(c->default_tableid, &rdomid);
1761 if (rdomid != c->default_tableid)
1762 fatalx("current routing table %u is not a routing domain",
1763 c->default_tableid);
1764
1765 if (asprintf(&c->csock, "%s.%d", SOCKET_NAME"/var/run/bgpd.sock", c->default_tableid) == -1)
1766 fatal(NULL((void*)0));
1767}
1768
1769struct bgpd_config *
1770parse_config(char *filename, struct peer_head *ph, struct rtr_config_head *rh)
1771{
1772 struct sym *sym, *next;
1773 struct rde_rib *rr;
1774 struct network *n;
1775 int errors = 0;
1776
1777 conf = new_config();
1778 init_config(conf);
1779
1780 if ((filter_l = calloc(1, sizeof(struct filter_head))) == NULL((void*)0))
1781 fatal(NULL((void*)0));
1782 if ((peerfilter_l = calloc(1, sizeof(struct filter_head))) == NULL((void*)0))
1783 fatal(NULL((void*)0));
1784 if ((groupfilter_l = calloc(1, sizeof(struct filter_head))) == NULL((void*)0))
1785 fatal(NULL((void*)0));
1786 TAILQ_INIT(filter_l)do { (filter_l)->tqh_first = ((void*)0); (filter_l)->tqh_last
= &(filter_l)->tqh_first; } while (0)
;
1787 TAILQ_INIT(peerfilter_l)do { (peerfilter_l)->tqh_first = ((void*)0); (peerfilter_l
)->tqh_last = &(peerfilter_l)->tqh_first; } while (
0)
;
1788 TAILQ_INIT(groupfilter_l)do { (groupfilter_l)->tqh_first = ((void*)0); (groupfilter_l
)->tqh_last = &(groupfilter_l)->tqh_first; } while (
0)
;
1789
1790 curpeer = NULL((void*)0);
1791 curgroup = NULL((void*)0);
1792
1793 cur_peers = ph;
1794 cur_rtrs = rh;
1795 new_peers = &conf->peers;
1796 netconf = &conf->networks;
1797
1798 if ((rr = add_rib("Adj-RIB-In")) == NULL((void*)0))
1799 fatal("add_rib failed");
1800 rr->flags = F_RIB_NOFIB0x0004 | F_RIB_NOEVALUATE0x0002;
1801 if ((rr = add_rib("Loc-RIB")) == NULL((void*)0))
1802 fatal("add_rib failed");
1803 rib_add_fib(rr, conf->default_tableid);
1804 rr->flags = F_RIB_LOCAL0x0001;
1805
1806 if ((file = pushfile(filename, 1)) == NULL((void*)0))
1807 goto errors;
1808 topfile = file;
1809
1810 yyparse();
1811 errors = file->errors;
1812 popfile();
1813
1814 /* check that we dont try to announce our own routes */
1815 TAILQ_FOREACH(n, netconf, entry)for((n) = ((netconf)->tqh_first); (n) != ((void*)0); (n) =
((n)->entry.tqe_next))
1816 if (n->net.priority == conf->fib_priority) {
1817 errors++;
1818 logit(LOG_CRIT2, "network priority %d == fib-priority "
1819 "%d is not allowed.",
1820 n->net.priority, conf->fib_priority);
1821 }
1822
1823 /* Free macros and check which have not been used. */
1824 TAILQ_FOREACH_SAFE(sym, &symhead, entry, next)for ((sym) = ((&symhead)->tqh_first); (sym) != ((void*
)0) && ((next) = ((sym)->entry.tqe_next), 1); (sym
) = (next))
{
1825 if ((cmd_opts & BGPD_OPT_VERBOSE20x0002) && !sym->used)
1826 fprintf(stderr(&__sF[2]), "warning: macro \"%s\" not "
1827 "used\n", sym->nam);
1828 if (!sym->persist) {
1829 free(sym->nam);
1830 free(sym->val);
1831 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)
;
1832 free(sym);
1833 }
1834 }
1835
1836 if (!conf->as) {
1837 log_warnx("configuration error: AS not given");
1838 errors++;
1839 }
1840
1841 /* clear the globals */
1842 curpeer = NULL((void*)0);
1843 curgroup = NULL((void*)0);
1844 cur_peers = NULL((void*)0);
1845 new_peers = NULL((void*)0);
1846 netconf = NULL((void*)0);
1847
1848 if (errors) {
1849errors:
1850 while ((rr = SIMPLEQ_FIRST(&ribnames)((&ribnames)->sqh_first)) != NULL((void*)0)) {
1851 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)
;
1852 free(rr);
1853 }
1854
1855 filterlist_free(filter_l);
1856 filterlist_free(peerfilter_l);
1857 filterlist_free(groupfilter_l);
1858
1859 free_config(conf);
1860 return (NULL((void*)0));
1861 } else {
1862 /* update clusterid in case it was not set explicitly */
1863 if ((conf->flags & BGPD_FLAG_REFLECTOR0x0004) && conf->clusterid == 0)
1864 conf->clusterid = conf->bgpid;
1865
1866 /*
1867 * Concatenate filter list and static group and peer filtersets
1868 * together. Static group sets come first then peer sets
1869 * last normal filter rules.
1870 */
1871 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)
;
1872 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)
;
1873 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)
;
1874
1875 optimize_filters(conf->filters);
1876
1877 free(filter_l);
1878 free(peerfilter_l);
1879 free(groupfilter_l);
1880
1881 return (conf);
1882 }
1883}
1884
1885int
1886symset(const char *nam, const char *val, int persist)
1887{
1888 struct sym *sym;
1889
1890 TAILQ_FOREACH(sym, &symhead, entry)for((sym) = ((&symhead)->tqh_first); (sym) != ((void*)
0); (sym) = ((sym)->entry.tqe_next))
{
1891 if (strcmp(nam, sym->nam) == 0)
1892 break;
1893 }
1894
1895 if (sym != NULL((void*)0)) {
1896 if (sym->persist == 1)
1897 return (0);
1898 else {
1899 free(sym->nam);
1900 free(sym->val);
1901 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)
;
1902 free(sym);
1903 }
1904 }
1905 if ((sym = calloc(1, sizeof(*sym))) == NULL((void*)0))
1906 return (-1);
1907
1908 sym->nam = strdup(nam);
1909 if (sym->nam == NULL((void*)0)) {
1910 free(sym);
1911 return (-1);
1912 }
1913 sym->val = strdup(val);
1914 if (sym->val == NULL((void*)0)) {
1915 free(sym->nam);
1916 free(sym);
1917 return (-1);
1918 }
1919 sym->used = 0;
1920 sym->persist = persist;
1921 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)
;
1922 return (0);
1923}
1924
1925int
1926cmdline_symset(char *s)
1927{
1928 char *sym, *val;
1929 int ret;
1930
1931 if ((val = strrchr(s, '=')) == NULL((void*)0))
1932 return (-1);
1933 sym = strndup(s, val - s);
1934 if (sym == NULL((void*)0))
1935 fatal("%s: strndup", __func__);
1936 ret = symset(sym, val + 1, 1);
1937 free(sym);
1938
1939 return (ret);
1940}
1941
1942char *
1943symget(const char *nam)
1944{
1945 struct sym *sym;
1946
1947 TAILQ_FOREACH(sym, &symhead, entry)for((sym) = ((&symhead)->tqh_first); (sym) != ((void*)
0); (sym) = ((sym)->entry.tqe_next))
{
1948 if (strcmp(nam, sym->nam) == 0) {
1949 sym->used = 1;
1950 return (sym->val);
1951 }
1952 }
1953 return (NULL((void*)0));
1954}
1955
1956static int
1957cmpcommunity(struct community *a, struct community *b)
1958{
1959 if (a->flags > b->flags)
1960 return 1;
1961 if (a->flags < b->flags)
1962 return -1;
1963 if (a->data1 > b->data1)
1964 return 1;
1965 if (a->data1 < b->data1)
1966 return -1;
1967 if (a->data2 > b->data2)
1968 return 1;
1969 if (a->data2 < b->data2)
1970 return -1;
1971 if (a->data3 > b->data3)
1972 return 1;
1973 if (a->data3 < b->data3)
1974 return -1;
1975 return 0;
1976}
1977
1978static int
1979getcommunity(char *s, int large, u_int32_t *val, u_int32_t *flag)
1980{
1981 long long max = USHRT_MAX(32767 *2 +1);
1982 const char *errstr;
1983
1984 *flag = 0;
1985 *val = 0;
1986 if (strcmp(s, "*") == 0) {
1987 *flag = COMMUNITY_ANY1;
1988 return 0;
1989 } else if (strcmp(s, "neighbor-as") == 0) {
1990 *flag = COMMUNITY_NEIGHBOR_AS2;
1991 return 0;
1992 } else if (strcmp(s, "local-as") == 0) {
1993 *flag = COMMUNITY_LOCAL_AS3;
1994 return 0;
1995 }
1996 if (large)
1997 max = UINT_MAX(2147483647 *2U +1U);
1998 *val = strtonum(s, 0, max, &errstr);
1999 if (errstr) {
2000 yyerror("Community %s is %s (max: %lld)", s, errstr, max);
2001 return -1;
2002 }
2003 return 0;
2004}
2005
2006static void
2007setcommunity(struct community *c, u_int32_t as, u_int32_t data,
2008 u_int32_t asflag, u_int32_t dataflag)
2009{
2010 c->flags = COMMUNITY_TYPE_BASIC8;
2011 c->flags |= asflag << 8;
2012 c->flags |= dataflag << 16;
2013 c->data1 = as;
2014 c->data2 = data;
2015 c->data3 = 0;
2016}
2017
2018static int
2019parselargecommunity(struct community *c, char *s)
2020{
2021 char *p, *q;
2022 u_int32_t dflag1, dflag2, dflag3;
2023
2024 if ((p = strchr(s, ':')) == NULL((void*)0)) {
2025 yyerror("Bad community syntax");
2026 return (-1);
2027 }
2028 *p++ = 0;
2029
2030 if ((q = strchr(p, ':')) == NULL((void*)0)) {
2031 yyerror("Bad community syntax");
2032 return (-1);
2033 }
2034 *q++ = 0;
2035
2036 if (getcommunity(s, 1, &c->data1, &dflag1) == -1 ||
2037 getcommunity(p, 1, &c->data2, &dflag2) == -1 ||
2038 getcommunity(q, 1, &c->data3, &dflag3) == -1)
2039 return (-1);
2040 c->flags = COMMUNITY_TYPE_LARGE32;
2041 c->flags |= dflag1 << 8;;
2042 c->flags |= dflag2 << 16;;
2043 c->flags |= dflag3 << 24;;
2044 return (0);
2045}
2046
2047int
2048parsecommunity(struct community *c, int type, char *s)
2049{
2050 char *p;
2051 u_int32_t as, data, asflag, dataflag;
2052
2053 if (type == COMMUNITY_TYPE_LARGE32)
2054 return parselargecommunity(c, s);
2055
2056 /* Well-known communities */
2057 if (strcasecmp(s, "GRACEFUL_SHUTDOWN") == 0) {
2058 setcommunity(c, COMMUNITY_WELLKNOWN0xffff,
2059 COMMUNITY_GRACEFUL_SHUTDOWN0x0000, 0, 0);
2060 return (0);
2061 } else if (strcasecmp(s, "NO_EXPORT") == 0) {
2062 setcommunity(c, COMMUNITY_WELLKNOWN0xffff,
2063 COMMUNITY_NO_EXPORT0xff01, 0, 0);
2064 return (0);
2065 } else if (strcasecmp(s, "NO_ADVERTISE") == 0) {
2066 setcommunity(c, COMMUNITY_WELLKNOWN0xffff,
2067 COMMUNITY_NO_ADVERTISE0xff02, 0, 0);
2068 return (0);
2069 } else if (strcasecmp(s, "NO_EXPORT_SUBCONFED") == 0) {
2070 setcommunity(c, COMMUNITY_WELLKNOWN0xffff,
2071 COMMUNITY_NO_EXPSUBCONFED0xff03, 0, 0);
2072 return (0);
2073 } else if (strcasecmp(s, "NO_PEER") == 0) {
2074 setcommunity(c, COMMUNITY_WELLKNOWN0xffff,
2075 COMMUNITY_NO_PEER0xff04, 0, 0);
2076 return (0);
2077 } else if (strcasecmp(s, "BLACKHOLE") == 0) {
2078 setcommunity(c, COMMUNITY_WELLKNOWN0xffff,
2079 COMMUNITY_BLACKHOLE0x029A, 0, 0);
2080 return (0);
2081 }
2082
2083 if ((p = strchr(s, ':')) == NULL((void*)0)) {
2084 yyerror("Bad community syntax");
2085 return (-1);
2086 }
2087 *p++ = 0;
2088
2089 if (getcommunity(s, 0, &as, &asflag) == -1 ||
2090 getcommunity(p, 0, &data, &dataflag) == -1)
2091 return (-1);
2092 setcommunity(c, as, data, asflag, dataflag);
2093 return (0);
2094}
2095
2096static int
2097parsesubtype(char *name, int *type, int *subtype)
2098{
2099 const struct ext_comm_pairs *cp;
2100 int found = 0;
2101
2102 for (cp = iana_ext_comms; cp->subname != NULL((void*)0); cp++) {
2103 if (strcmp(name, cp->subname) == 0) {
2104 if (found == 0) {
2105 *type = cp->type;
2106 *subtype = cp->subtype;
2107 }
2108 found++;
2109 }
2110 }
2111 if (found > 1)
2112 *type = -1;
2113 return (found);
2114}
2115
2116static int
2117parseextvalue(int type, char *s, u_int32_t *v, u_int32_t *flag)
2118{
2119 const char *errstr;
2120 char *p;
2121 struct in_addr ip;
2122 u_int32_t uvalh, uval;
2123
2124 if (type != -1) {
2125 /* nothing */
2126 } else if (strcmp(s, "neighbor-as") == 0) {
2127 *flag = COMMUNITY_NEIGHBOR_AS2;
2128 *v = 0;
2129 return EXT_COMMUNITY_TRANS_FOUR_AS0x02;
2130 } else if (strcmp(s, "local-as") == 0) {
2131 *flag = COMMUNITY_LOCAL_AS3;
2132 *v = 0;
2133 return EXT_COMMUNITY_TRANS_FOUR_AS0x02;
2134 } else if ((p = strchr(s, '.')) == NULL((void*)0)) {
2135 /* AS_PLAIN number (4 or 2 byte) */
2136 strtonum(s, 0, USHRT_MAX(32767 *2 +1), &errstr);
2137 if (errstr == NULL((void*)0))
2138 type = EXT_COMMUNITY_TRANS_TWO_AS0x00;
2139 else
2140 type = EXT_COMMUNITY_TRANS_FOUR_AS0x02;
2141 } else if (strchr(p + 1, '.') == NULL((void*)0)) {
2142 /* AS_DOT number (4-byte) */
2143 type = EXT_COMMUNITY_TRANS_FOUR_AS0x02;
2144 } else {
2145 /* more than one dot -> IP address */
2146 type = EXT_COMMUNITY_TRANS_IPV40x01;
2147 }
2148
2149 switch (type) {
2150 case EXT_COMMUNITY_TRANS_TWO_AS0x00:
2151 uval = strtonum(s, 0, USHRT_MAX(32767 *2 +1), &errstr);
2152 if (errstr) {
2153 yyerror("Bad ext-community %s is %s", s, errstr);
2154 return (-1);
2155 }
2156 *v = uval;
2157 break;
2158 case EXT_COMMUNITY_TRANS_FOUR_AS0x02:
2159 if ((p = strchr(s, '.')) == NULL((void*)0)) {
2160 uval = strtonum(s, 0, UINT_MAX(2147483647 *2U +1U), &errstr);
2161 if (errstr) {
2162 yyerror("Bad ext-community %s is %s", s,
2163 errstr);
2164 return (-1);
2165 }
2166 *v = uval;
2167 break;
2168 }
2169 *p++ = '\0';
2170 uvalh = strtonum(s, 0, USHRT_MAX(32767 *2 +1), &errstr);
2171 if (errstr) {
2172 yyerror("Bad ext-community %s is %s", s, errstr);
2173 return (-1);
2174 }
2175 uval = strtonum(p, 0, USHRT_MAX(32767 *2 +1), &errstr);
2176 if (errstr) {
2177 yyerror("Bad ext-community %s is %s", p, errstr);
2178 return (-1);
2179 }
2180 *v = uval | (uvalh << 16);
2181 break;
2182 case EXT_COMMUNITY_TRANS_IPV40x01:
2183 if (inet_aton(s, &ip) == 0) {
2184 yyerror("Bad ext-community %s not parseable", s);
2185 return (-1);
2186 }
2187 *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))
;
2188 break;
2189 default:
2190 fatalx("%s: unexpected type %d", __func__, type);
2191 }
2192 return (type);
2193}
2194
2195int
2196parseextcommunity(struct community *c, char *t, char *s)
2197{
2198 const struct ext_comm_pairs *cp;
2199 char *p, *ep;
2200 u_int64_t ullval;
2201 u_int32_t uval, uval2, dflag1 = 0, dflag2 = 0;
2202 int type = 0, subtype = 0;
2203
2204 if (strcmp(t, "*") == 0 && strcmp(s, "*") == 0) {
2205 c->flags = COMMUNITY_TYPE_EXT16;
2206 c->flags |= COMMUNITY_ANY1 << 24;
2207 return (0);
2208 }
2209 if (parsesubtype(t, &type, &subtype) == 0) {
2210 yyerror("Bad ext-community unknown type");
2211 return (-1);
2212 }
2213
2214 switch (type) {
2215 case EXT_COMMUNITY_TRANS_TWO_AS0x00:
2216 case EXT_COMMUNITY_TRANS_FOUR_AS0x02:
2217 case EXT_COMMUNITY_TRANS_IPV40x01:
2218 case -1:
2219 if (strcmp(s, "*") == 0) {
2220 dflag1 = COMMUNITY_ANY1;
2221 break;
2222 }
2223 if ((p = strchr(s, ':')) == NULL((void*)0)) {
2224 yyerror("Bad ext-community %s", s);
2225 return (-1);
2226 }
2227 *p++ = '\0';
2228 if ((type = parseextvalue(type, s, &uval, &dflag1)) == -1)
2229 return (-1);
2230
2231 switch (type) {
2232 case EXT_COMMUNITY_TRANS_TWO_AS0x00:
2233 if (getcommunity(p, 1, &uval2, &dflag2) == -1)
2234 return (-1);
2235 break;
2236 case EXT_COMMUNITY_TRANS_IPV40x01:
2237 case EXT_COMMUNITY_TRANS_FOUR_AS0x02:
2238 if (getcommunity(p, 0, &uval2, &dflag2) == -1)
2239 return (-1);
2240 break;
2241 default:
2242 fatalx("parseextcommunity: unexpected result");
2243 }
2244
2245 c->data1 = uval;
2246 c->data2 = uval2;
2247 break;
2248 case EXT_COMMUNITY_TRANS_OPAQUE0x03:
2249 case EXT_COMMUNITY_TRANS_EVPN0x06:
2250 if (strcmp(s, "*") == 0) {
2251 dflag1 = COMMUNITY_ANY1;
2252 break;
2253 }
2254 errno(*__errno()) = 0;
2255 ullval = strtoull(s, &ep, 0);
2256 if (s[0] == '\0' || *ep != '\0') {
2257 yyerror("Bad ext-community bad value");
2258 return (-1);
2259 }
2260 if (errno(*__errno()) == ERANGE34 && ullval > EXT_COMMUNITY_OPAQUE_MAX0xffffffffffffULL) {
2261 yyerror("Bad ext-community value too big");
2262 return (-1);
2263 }
2264 c->data1 = ullval >> 32;
2265 c->data2 = ullval;
2266 break;
2267 case EXT_COMMUNITY_NON_TRANS_OPAQUE0x43:
2268 if (subtype == EXT_COMMUNITY_SUBTYPE_OVS0) {
2269 if (strcmp(s, "valid") == 0) {
2270 c->data2 = EXT_COMMUNITY_OVS_VALID0;
2271 break;
2272 } else if (strcmp(s, "invalid") == 0) {
2273 c->data2 = EXT_COMMUNITY_OVS_INVALID2;
2274 break;
2275 } else if (strcmp(s, "not-found") == 0) {
2276 c->data2 = EXT_COMMUNITY_OVS_NOTFOUND1;
2277 break;
2278 } else if (strcmp(s, "*") == 0) {
2279 dflag1 = COMMUNITY_ANY1;
2280 break;
2281 }
2282 }
2283 yyerror("Bad ext-community %s", s);
2284 return (-1);
2285 }
2286
2287 c->data3 = type << 8 | subtype;
2288
2289 /* special handling of ext-community rt * since type is not known */
2290 if (dflag1 == COMMUNITY_ANY1 && type == -1) {
2291 c->flags = COMMUNITY_TYPE_EXT16;
2292 c->flags |= dflag1 << 8;
2293 return (0);
2294 }
2295
2296 /* verify type/subtype combo */
2297 for (cp = iana_ext_comms; cp->subname != NULL((void*)0); cp++) {
2298 if (cp->type == type && cp->subtype == subtype) {
2299 c->flags = COMMUNITY_TYPE_EXT16;
2300 c->flags |= dflag1 << 8;
2301 c->flags |= dflag2 << 16;
2302 return (0);
2303 }
2304 }
2305
2306 yyerror("Bad ext-community bad format for type");
2307 return (-1);
2308}
2309
2310struct peer *
2311alloc_peer(void)
2312{
2313 struct peer *p;
2314 u_int8_t i;
2315
2316 if ((p = calloc(1, sizeof(struct peer))) == NULL((void*)0))
2317 fatal("new_peer");
2318
2319 /* some sane defaults */
2320 p->state = STATE_NONE;
2321 p->reconf_action = RECONF_REINIT;
2322 p->conf.distance = 1;
2323 p->conf.export_type = EXPORT_UNSET;
2324 p->conf.announce_capa = 1;
2325 for (i = 0; i < AID_MAX5; i++)
2326 p->conf.capabilities.mp[i] = 0;
2327 p->conf.capabilities.refresh = 1;
2328 p->conf.capabilities.grestart.restart = 1;
2329 p->conf.capabilities.as4byte = 1;
2330 p->conf.local_as = conf->as;
2331 p->conf.local_short_as = conf->short_as;
2332
2333 if (conf->flags & BGPD_FLAG_DECISION_TRANS_AS0x0200)
2334 p->conf.flags |= PEERFLAG_TRANS_AS0x01;
2335 if (conf->flags & BGPD_FLAG_DECISION_ALL_PATHS0x0800)
2336 p->conf.flags |= PEERFLAG_EVALUATE_ALL0x04;
2337 if (conf->flags & BGPD_FLAG_NO_AS_SET0x1000)
2338 p->conf.flags |= PEERFLAG_NO_AS_SET0x08;
2339
2340 return (p);
2341}
2342
2343struct peer *
2344new_peer(void)
2345{
2346 struct peer *p;
2347
2348 p = alloc_peer();
2349
2350 if (curgroup != NULL((void*)0)) {
2351 memcpy(p, curgroup, sizeof(struct peer));
2352 if (strlcpy(p->conf.group, curgroup->conf.group,
2353 sizeof(p->conf.group)) >= sizeof(p->conf.group))
2354 fatalx("new_peer group strlcpy");
2355 if (strlcpy(p->conf.descr, curgroup->conf.descr,
2356 sizeof(p->conf.descr)) >= sizeof(p->conf.descr))
2357 fatalx("new_peer descr strlcpy");
2358 p->conf.groupid = curgroup->conf.id;
2359 }
2360 return (p);
2361}
2362
2363struct peer *
2364new_group(void)
2365{
2366 return (alloc_peer());
2367}
2368
2369int
2370add_mrtconfig(enum mrt_type type, char *name, int timeout, struct peer *p,
2371 char *rib)
2372{
2373 struct mrt *m, *n;
2374
2375 LIST_FOREACH(m, conf->mrt, entry)for((m) = ((conf->mrt)->lh_first); (m)!= ((void*)0); (m
) = ((m)->entry.le_next))
{
2376 if ((rib && strcmp(rib, m->rib)) ||
2377 (!rib && *m->rib))
2378 continue;
2379 if (p == NULL((void*)0)) {
2380 if (m->peer_id != 0 || m->group_id != 0)
2381 continue;
2382 } else {
2383 if (m->peer_id != p->conf.id ||
2384 m->group_id != p->conf.groupid)
2385 continue;
2386 }
2387 if (m->type == type) {
2388 yyerror("only one mrtdump per type allowed.");
2389 return (-1);
2390 }
2391 }
2392
2393 if ((n = calloc(1, sizeof(struct mrt_config))) == NULL((void*)0))
Result of 'calloc' is converted to a pointer of type 'struct mrt', which is incompatible with sizeof operand type 'struct mrt_config'
2394 fatal("add_mrtconfig");
2395
2396 n->type = type;
2397 n->state = MRT_STATE_OPEN;
2398 if (strlcpy(MRT2MC(n)((struct mrt_config *)(n))->name, name, sizeof(MRT2MC(n)((struct mrt_config *)(n))->name)) >=
2399 sizeof(MRT2MC(n)((struct mrt_config *)(n))->name)) {
2400 yyerror("filename \"%s\" too long: max %zu",
2401 name, sizeof(MRT2MC(n)((struct mrt_config *)(n))->name) - 1);
2402 free(n);
2403 return (-1);
2404 }
2405 MRT2MC(n)((struct mrt_config *)(n))->ReopenTimerInterval = timeout;
2406 if (p != NULL((void*)0)) {
2407 if (curgroup == p) {
2408 n->peer_id = 0;
2409 n->group_id = p->conf.id;
2410 } else {
2411 n->peer_id = p->conf.id;
2412 n->group_id = p->conf.groupid;
2413 }
2414 }
2415 if (rib) {
2416 if (!find_rib(rib)) {
2417 yyerror("rib \"%s\" does not exist.", rib);
2418 free(n);
2419 return (-1);
2420 }
2421 if (strlcpy(n->rib, rib, sizeof(n->rib)) >=
2422 sizeof(n->rib)) {
2423 yyerror("rib name \"%s\" too long: max %zu",
2424 name, sizeof(n->rib) - 1);
2425 free(n);
2426 return (-1);
2427 }
2428 }
2429
2430 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)
;
2431
2432 return (0);
2433}
2434
2435struct rde_rib *
2436add_rib(char *name)
2437{
2438 struct rde_rib *rr;
2439
2440 if ((rr = find_rib(name)) == NULL((void*)0)) {
2441 if ((rr = calloc(1, sizeof(*rr))) == NULL((void*)0)) {
2442 log_warn("add_rib");
2443 return (NULL((void*)0));
2444 }
2445 if (strlcpy(rr->name, name, sizeof(rr->name)) >=
2446 sizeof(rr->name)) {
2447 yyerror("rib name \"%s\" too long: max %zu",
2448 name, sizeof(rr->name) - 1);
2449 free(rr);
2450 return (NULL((void*)0));
2451 }
2452 rr->flags = F_RIB_NOFIB0x0004;
2453 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)
;
2454 }
2455 return (rr);
2456}
2457
2458struct rde_rib *
2459find_rib(char *name)
2460{
2461 struct rde_rib *rr;
2462
2463 SIMPLEQ_FOREACH(rr, &ribnames, entry)for((rr) = ((&ribnames)->sqh_first); (rr) != ((void*)0
); (rr) = ((rr)->entry.sqe_next))
{
2464 if (!strcmp(rr->name, name))
2465 return (rr);
2466 }
2467 return (NULL((void*)0));
2468}
2469
2470int
2471rib_add_fib(struct rde_rib *rr, u_int rtableid)
2472{
2473 u_int rdom;
2474
2475 if (ktable_exists(rtableid, &rdom) != 1) {
2476 yyerror("rtable id %u does not exist", rtableid);
2477 return (-1);
2478 }
2479 /*
2480 * conf->default_tableid is also a rdomain because that is checked
2481 * in init_config()
2482 */
2483 if (rdom != conf->default_tableid) {
2484 log_warnx("rtable %u does not belong to rdomain %u",
2485 rtableid, conf->default_tableid);
2486 return (-1);
2487 }
2488 rr->rtableid = rtableid;
2489 rr->flags &= ~F_RIB_NOFIB0x0004;
2490 return (0);
2491}
2492
2493struct prefixset *
2494find_prefixset(char *name, struct prefixset_head *p)
2495{
2496 struct prefixset *ps;
2497
2498 SIMPLEQ_FOREACH(ps, p, entry)for((ps) = ((p)->sqh_first); (ps) != ((void*)0); (ps) = ((
ps)->entry.sqe_next))
{
2499 if (!strcmp(ps->name, name))
2500 return (ps);
2501 }
2502 return (NULL((void*)0));
2503}
2504
2505int
2506get_id(struct peer *newpeer)
2507{
2508 static u_int32_t id = PEER_ID_STATIC_MIN2;
2509 struct peer *p = NULL((void*)0);
2510
2511 /* check if the peer already existed before */
2512 if (newpeer->conf.remote_addr.aid) {
2513 /* neighbor */
2514 if (cur_peers)
2515 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))
2516 if (p->conf.remote_masklen ==
2517 newpeer->conf.remote_masklen &&
2518 memcmp(&p->conf.remote_addr,
2519 &newpeer->conf.remote_addr,
2520 sizeof(p->conf.remote_addr)) == 0)
2521 break;
2522 if (p) {
2523 newpeer->conf.id = p->conf.id;
2524 return (0);
2525 }
2526 } else {
2527 /* group */
2528 if (cur_peers)
2529 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))
2530 if (strcmp(p->conf.group,
2531 newpeer->conf.group) == 0)
2532 break;
2533 if (p) {
2534 newpeer->conf.id = p->conf.groupid;
2535 return (0);
2536 }
2537 }
2538
2539 /* else new one */
2540 if (id < PEER_ID_STATIC_MAX((2147483647 *2U +1U) / 2)) {
2541 newpeer->conf.id = id++;
2542 return (0);
2543 }
2544
2545 return (-1);
2546}
2547
2548int
2549merge_prefixspec(struct filter_prefix *p, struct filter_prefixlen *pl)
2550{
2551 u_int8_t max_len = 0;
2552
2553 switch (p->addr.aid) {
2554 case AID_INET1:
2555 case AID_VPN_IPv43:
2556 max_len = 32;
2557 break;
2558 case AID_INET62:
2559 case AID_VPN_IPv64:
2560 max_len = 128;
2561 break;
2562 }
2563
2564 if (pl->op == OP_NONE) {
2565 p->len_min = p->len_max = p->len;
2566 return (0);
2567 }
2568
2569 if (pl->len_min == -1)
2570 pl->len_min = p->len;
2571 if (pl->len_max == -1)
2572 pl->len_max = max_len;
2573
2574 if (pl->len_max > max_len) {
2575 yyerror("prefixlen %d too big, limit %d",
2576 pl->len_max, max_len);
2577 return (-1);
2578 }
2579 if (pl->len_min > pl->len_max) {
2580 yyerror("prefixlen %d too big, limit %d",
2581 pl->len_min, pl->len_max);
2582 return (-1);
2583 }
2584 if (pl->len_min < p->len) {
2585 yyerror("prefixlen %d smaller than prefix, limit %d",
2586 pl->len_min, p->len);
2587 return (-1);
2588 }
2589
2590 p->op = pl->op;
2591 p->len_min = pl->len_min;
2592 p->len_max = pl->len_max;
2593 return (0);
2594}
2595
2596int
2597expand_rule(struct filter_rule *rule, struct filter_rib_l *rib,
2598 struct filter_peers_l *peer, struct filter_match_l *match,
2599 struct filter_set_head *set)
2600{
2601 struct filter_rule *r;
2602 struct filter_rib_l *rb, *rbnext;
2603 struct filter_peers_l *p, *pnext;
2604 struct filter_prefix_l *prefix, *prefix_next;
2605 struct filter_as_l *a, *anext;
2606 struct filter_set *s;
2607
2608 rb = rib;
2609 do {
2610 p = peer;
2611 do {
2612 a = match->as_l;
2613 do {
2614 prefix = match->prefix_l;
2615 do {
2616 if ((r = calloc(1,
2617 sizeof(struct filter_rule))) ==
2618 NULL((void*)0)) {
2619 log_warn("expand_rule");
2620 return (-1);
2621 }
2622
2623 memcpy(r, rule, sizeof(struct filter_rule));
2624 memcpy(&r->match, match,
2625 sizeof(struct filter_match));
2626 filterset_copy(set, &r->set);
2627
2628 if (rb != NULL((void*)0))
2629 strlcpy(r->rib, rb->name,
2630 sizeof(r->rib));
2631
2632 if (p != NULL((void*)0))
2633 memcpy(&r->peer, &p->p,
2634 sizeof(struct filter_peers));
2635
2636 if (prefix != NULL((void*)0))
2637 memcpy(&r->match.prefix, &prefix->p,
2638 sizeof(r->match.prefix));
2639
2640 if (a != NULL((void*)0))
2641 memcpy(&r->match.as, &a->a,
2642 sizeof(struct filter_as));
2643
2644 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)
;
2645
2646 if (prefix != NULL((void*)0))
2647 prefix = prefix->next;
2648 } while (prefix != NULL((void*)0));
2649
2650 if (a != NULL((void*)0))
2651 a = a->next;
2652 } while (a != NULL((void*)0));
2653
2654 if (p != NULL((void*)0))
2655 p = p->next;
2656 } while (p != NULL((void*)0));
2657
2658 if (rb != NULL((void*)0))
2659 rb = rb->next;
2660 } while (rb != NULL((void*)0));
2661
2662 for (rb = rib; rb != NULL((void*)0); rb = rbnext) {
2663 rbnext = rb->next;
2664 free(rb);
2665 }
2666
2667 for (p = peer; p != NULL((void*)0); p = pnext) {
2668 pnext = p->next;
2669 free(p);
2670 }
2671
2672 for (a = match->as_l; a != NULL((void*)0); a = anext) {
2673 anext = a->next;
2674 free(a);
2675 }
2676
2677 for (prefix = match->prefix_l; prefix != NULL((void*)0); prefix = prefix_next) {
2678 prefix_next = prefix->next;
2679 free(prefix);
2680 }
2681
2682 if (set != NULL((void*)0)) {
2683 while ((s = TAILQ_FIRST(set)((set)->tqh_first)) != NULL((void*)0)) {
2684 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)
;
2685 free(s);
2686 }
2687 free(set);
2688 }
2689
2690 return (0);
2691}
2692
2693int
2694str2key(char *s, char *dest, size_t max_len)
2695{
2696 unsigned i;
2697 char t[3];
2698
2699 if (strlen(s) / 2 > max_len) {
2700 yyerror("key too long");
2701 return (-1);
2702 }
2703
2704 if (strlen(s) % 2) {
2705 yyerror("key must be of even length");
2706 return (-1);
2707 }
2708
2709 for (i = 0; i < strlen(s) / 2; i++) {
2710 t[0] = s[2*i];
2711 t[1] = s[2*i + 1];
2712 t[2] = 0;
2713 if (!isxdigit(t[0]) || !isxdigit(t[1])) {
2714 yyerror("key must be specified in hex");
2715 return (-1);
2716 }
2717 dest[i] = strtoul(t, NULL((void*)0), 16);
2718 }
2719
2720 return (0);
2721}
2722
2723int
2724neighbor_consistent(struct peer *p)
2725{
2726 struct bgpd_addr *local_addr;
2727 struct peer *xp;
2728
2729 switch (p->conf.remote_addr.aid) {
2730 case AID_INET1:
2731 local_addr = &p->conf.local_addr_v4;
2732 break;
2733 case AID_INET62:
2734 local_addr = &p->conf.local_addr_v6;
2735 break;
2736 default:
2737 yyerror("Bad address family for remote-addr");
2738 return (-1);
2739 }
2740
2741 /* with any form of ipsec local-address is required */
2742 if ((p->conf.auth.method == AUTH_IPSEC_IKE_ESP ||
2743 p->conf.auth.method == AUTH_IPSEC_IKE_AH ||
2744 p->conf.auth.method == AUTH_IPSEC_MANUAL_ESP ||
2745 p->conf.auth.method == AUTH_IPSEC_MANUAL_AH) &&
2746 local_addr->aid == AID_UNSPEC0) {
2747 yyerror("neighbors with any form of IPsec configured "
2748 "need local-address to be specified");
2749 return (-1);
2750 }
2751
2752 /* with static keying we need both directions */
2753 if ((p->conf.auth.method == AUTH_IPSEC_MANUAL_ESP ||
2754 p->conf.auth.method == AUTH_IPSEC_MANUAL_AH) &&
2755 (!p->conf.auth.spi_in || !p->conf.auth.spi_out)) {
2756 yyerror("with manual keyed IPsec, SPIs and keys "
2757 "for both directions are required");
2758 return (-1);
2759 }
2760
2761 if (!conf->as) {
2762 yyerror("AS needs to be given before neighbor definitions");
2763 return (-1);
2764 }
2765
2766 /* set default values if they where undefined */
2767 p->conf.ebgp = (p->conf.remote_as != conf->as);
2768 if (p->conf.enforce_as == ENFORCE_AS_UNDEF)
2769 p->conf.enforce_as = p->conf.ebgp ?
2770 ENFORCE_AS_ON : ENFORCE_AS_OFF;
2771 if (p->conf.enforce_local_as == ENFORCE_AS_UNDEF)
2772 p->conf.enforce_local_as = ENFORCE_AS_ON;
2773
2774 if (p->conf.remote_as == 0 && !p->conf.template) {
2775 yyerror("peer AS may not be zero");
2776 return (-1);
2777 }
2778
2779 /* EBGP neighbors are not allowed in route reflector clusters */
2780 if (p->conf.reflector_client && p->conf.ebgp) {
2781 yyerror("EBGP neighbors are not allowed in route "
2782 "reflector clusters");
2783 return (-1);
2784 }
2785
2786 /* check for duplicate peer definitions */
2787 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))
2788 if (xp->conf.remote_masklen ==
2789 p->conf.remote_masklen &&
2790 memcmp(&xp->conf.remote_addr,
2791 &p->conf.remote_addr,
2792 sizeof(p->conf.remote_addr)) == 0)
2793 break;
2794 if (xp != NULL((void*)0)) {
2795 char *descr = log_fmt_peer(&p->conf);
2796 yyerror("duplicate %s", descr);
2797 free(descr);
2798 return (-1);
2799 }
2800
2801 return (0);
2802}
2803
2804static void
2805filterset_add(struct filter_set_head *sh, struct filter_set *s)
2806{
2807 struct filter_set *t;
2808
2809 TAILQ_FOREACH(t, sh, entry)for((t) = ((sh)->tqh_first); (t) != ((void*)0); (t) = ((t)
->entry.tqe_next))
{
2810 if (s->type < t->type) {
2811 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)
;
2812 return;
2813 }
2814 if (s->type == t->type) {
2815 switch (s->type) {
2816 case ACTION_SET_COMMUNITY:
2817 case ACTION_DEL_COMMUNITY:
2818 switch (cmpcommunity(&s->action.community,
2819 &t->action.community)) {
2820 case -1:
2821 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)
;
2822 return;
2823 case 0:
2824 break;
2825 case 1:
2826 continue;
2827 }
2828 break;
2829 case ACTION_SET_NEXTHOP:
2830 /* only last nexthop per AF matters */
2831 if (s->action.nexthop.aid <
2832 t->action.nexthop.aid) {
2833 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)
;
2834 return;
2835 } else if (s->action.nexthop.aid ==
2836 t->action.nexthop.aid) {
2837 t->action.nexthop = s->action.nexthop;
2838 break;
2839 }
2840 continue;
2841 case ACTION_SET_NEXTHOP_BLACKHOLE:
2842 case ACTION_SET_NEXTHOP_REJECT:
2843 case ACTION_SET_NEXTHOP_NOMODIFY:
2844 case ACTION_SET_NEXTHOP_SELF:
2845 /* set it only once */
2846 break;
2847 case ACTION_SET_LOCALPREF:
2848 case ACTION_SET_MED:
2849 case ACTION_SET_WEIGHT:
2850 /* only last set matters */
2851 t->action.metric = s->action.metric;
2852 break;
2853 case ACTION_SET_RELATIVE_LOCALPREF:
2854 case ACTION_SET_RELATIVE_MED:
2855 case ACTION_SET_RELATIVE_WEIGHT:
2856 /* sum all relative numbers */
2857 t->action.relative += s->action.relative;
2858 break;
2859 case ACTION_SET_ORIGIN:
2860 /* only last set matters */
2861 t->action.origin = s->action.origin;
2862 break;
2863 case ACTION_PFTABLE:
2864 /* only last set matters */
2865 strlcpy(t->action.pftable, s->action.pftable,
2866 sizeof(t->action.pftable));
2867 break;
2868 case ACTION_RTLABEL:
2869 /* only last set matters */
2870 strlcpy(t->action.rtlabel, s->action.rtlabel,
2871 sizeof(t->action.rtlabel));
2872 break;
2873 default:
2874 break;
2875 }
2876 free(s);
2877 return;
2878 }
2879 }
2880
2881 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)
;
2882}
2883
2884int
2885merge_filterset(struct filter_set_head *sh, struct filter_set *s)
2886{
2887 struct filter_set *t;
2888
2889 TAILQ_FOREACH(t, sh, entry)for((t) = ((sh)->tqh_first); (t) != ((void*)0); (t) = ((t)
->entry.tqe_next))
{
2890 /*
2891 * need to cycle across the full list because even
2892 * if types are not equal filterset_cmp() may return 0.
2893 */
2894 if (filterset_cmp(s, t) == 0) {
2895 if (s->type == ACTION_SET_COMMUNITY)
2896 yyerror("community is already set");
2897 else if (s->type == ACTION_DEL_COMMUNITY)
2898 yyerror("community will already be deleted");
2899 else
2900 yyerror("redefining set parameter %s",
2901 filterset_name(s->type));
2902 return (-1);
2903 }
2904 }
2905
2906 filterset_add(sh, s);
2907 return (0);
2908}
2909
2910static int
2911filter_equal(struct filter_rule *fa, struct filter_rule *fb)
2912{
2913 if (fa == NULL((void*)0) || fb == NULL((void*)0))
2914 return 0;
2915 if (fa->action != fb->action || fa->quick != fb->quick ||
2916 fa->dir != fb->dir)
2917 return 0;
2918 if (memcmp(&fa->peer, &fb->peer, sizeof(fa->peer)))
2919 return 0;
2920 if (memcmp(&fa->match, &fb->match, sizeof(fa->match)))
2921 return 0;
2922
2923 return 1;
2924}
2925
2926/* do a basic optimization by folding equal rules together */
2927void
2928optimize_filters(struct filter_head *fh)
2929{
2930 struct filter_rule *r, *nr;
2931
2932 TAILQ_FOREACH_SAFE(r, fh, entry, nr)for ((r) = ((fh)->tqh_first); (r) != ((void*)0) &&
((nr) = ((r)->entry.tqe_next), 1); (r) = (nr))
{
2933 while (filter_equal(r, nr)) {
2934 struct filter_set *t;
2935
2936 while ((t = TAILQ_FIRST(&nr->set)((&nr->set)->tqh_first)) != NULL((void*)0)) {
2937 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)
;
2938 filterset_add(&r->set, t);
2939 }
2940
2941 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)
;
2942 free(nr);
2943 nr = TAILQ_NEXT(r, entry)((r)->entry.tqe_next);
2944 }
2945 }
2946}
2947
2948struct filter_rule *
2949get_rule(enum action_types type)
2950{
2951 struct filter_rule *r;
2952 int out;
2953
2954 switch (type) {
2955 case ACTION_SET_PREPEND_SELF:
2956 case ACTION_SET_NEXTHOP_NOMODIFY:
2957 case ACTION_SET_NEXTHOP_SELF:
2958 out = 1;
2959 break;
2960 default:
2961 out = 0;
2962 break;
2963 }
2964 r = (curpeer == curgroup) ? curgroup_filter[out] : curpeer_filter[out];
2965 if (r == NULL((void*)0)) {
2966 if ((r = calloc(1, sizeof(struct filter_rule))) == NULL((void*)0))
2967 fatal(NULL((void*)0));
2968 r->quick = 0;
2969 r->dir = out ? DIR_OUT : DIR_IN;
2970 r->action = ACTION_NONE;
2971 TAILQ_INIT(&r->set)do { (&r->set)->tqh_first = ((void*)0); (&r->
set)->tqh_last = &(&r->set)->tqh_first; } while
(0)
;
2972 if (curpeer == curgroup) {
2973 /* group */
2974 r->peer.groupid = curgroup->conf.id;
2975 curgroup_filter[out] = r;
2976 } else {
2977 /* peer */
2978 r->peer.peerid = curpeer->conf.id;
2979 curpeer_filter[out] = r;
2980 }
2981 }
2982 return (r);
2983}
2984
2985struct set_table *curset;
2986static int
2987new_as_set(char *name)
2988{
2989 struct as_set *aset;
2990
2991 if (as_sets_lookup(&conf->as_sets, name) != NULL((void*)0)) {
2992 yyerror("as-set \"%s\" already exists", name);
2993 return -1;
2994 }
2995
2996 aset = as_sets_new(&conf->as_sets, name, 0, sizeof(u_int32_t));
2997 if (aset == NULL((void*)0))
2998 fatal(NULL((void*)0));
2999
3000 curset = aset->set;
3001 return 0;
3002}
3003
3004static void
3005add_as_set(u_int32_t as)
3006{
3007 if (curset == NULL((void*)0))
3008 fatalx("%s: bad mojo jojo", __func__);
3009
3010 if (set_add(curset, &as, 1) != 0)
3011 fatal(NULL((void*)0));
3012}
3013
3014static void
3015done_as_set(void)
3016{
3017 curset = NULL((void*)0);
3018}
3019
3020static struct prefixset *
3021new_prefix_set(char *name, int is_roa)
3022{
3023 const char *type = "prefix-set";
3024 struct prefixset_head *sets = &conf->prefixsets;
3025 struct prefixset *pset;
3026
3027 if (is_roa) {
3028 type = "origin-set";
3029 sets = &conf->originsets;
3030 }
3031
3032 if (find_prefixset(name, sets) != NULL((void*)0)) {
3033 yyerror("%s \"%s\" already exists", type, name);
3034 return NULL((void*)0);
3035 }
3036 if ((pset = calloc(1, sizeof(*pset))) == NULL((void*)0))
3037 fatal("prefixset");
3038 if (strlcpy(pset->name, name, sizeof(pset->name)) >=
3039 sizeof(pset->name)) {
3040 yyerror("%s \"%s\" too long: max %zu", type,
3041 name, sizeof(pset->name) - 1);
3042 free(pset);
3043 return NULL((void*)0);
3044 }
3045 RB_INIT(&pset->psitems)do { (&pset->psitems)->rbh_root = ((void*)0); } while
(0)
;
3046 RB_INIT(&pset->roaitems)do { (&pset->roaitems)->rbh_root = ((void*)0); } while
(0)
;
3047 return pset;
3048}
3049
3050static void
3051add_roa_set(struct prefixset_item *npsi, u_int32_t as, u_int8_t max,
3052 time_t expires)
3053{
3054 struct roa *roa, *r;
3055
3056 if ((roa = calloc(1, sizeof(*roa))) == NULL((void*)0))
3057 fatal("add_roa_set");
3058
3059 roa->aid = npsi->p.addr.aid;
3060 roa->prefixlen = npsi->p.len;
3061 roa->maxlen = max;
3062 roa->asnum = as;
3063 roa->expires = expires;
3064 switch (roa->aid) {
3065 case AID_INET1:
3066 roa->prefix.inet = npsi->p.addr.v4ba.v4;
3067 break;
3068 case AID_INET62:
3069 roa->prefix.inet6 = npsi->p.addr.v6ba.v6;
3070 break;
3071 default:
3072 fatalx("Bad address family for roa_set address");
3073 }
3074
3075 r = RB_INSERT(roa_tree, curroatree, roa)roa_tree_RB_INSERT(curroatree, roa);
3076 if (r != NULL((void*)0)) {
3077 /* just ignore duplicates */
3078 if (r->expires != 0 && expires != 0 && expires > r->expires)
3079 r->expires = expires;
3080 free(roa);
3081 }
3082}
3083
3084static struct rtr_config *
3085get_rtr(struct bgpd_addr *addr)
3086{
3087 struct rtr_config *n;
3088
3089 n = calloc(1, sizeof(*n));
3090 if (n == NULL((void*)0)) {
3091 yyerror("out of memory");
3092 return NULL((void*)0);
3093 }
3094
3095 n->remote_addr = *addr;
3096 strlcpy(n->descr, log_addr(addr), sizeof(currtr->descr));
3097
3098 return n;
3099}
3100
3101static int
3102insert_rtr(struct rtr_config *new)
3103{
3104 static uint32_t id;
3105 struct rtr_config *r;
3106
3107 if (id == UINT32_MAX0xffffffffU) {
3108 yyerror("out of rtr session IDs");
3109 return -1;
3110 }
3111
3112 SIMPLEQ_FOREACH(r, &conf->rtrs, entry)for((r) = ((&conf->rtrs)->sqh_first); (r) != ((void
*)0); (r) = ((r)->entry.sqe_next))
3113 if (memcmp(&r->remote_addr, &new->remote_addr,
3114 sizeof(r->remote_addr)) == 0 &&
3115 r->remote_port == new->remote_port) {
3116 yyerror("duplicate rtr session to %s:%u",
3117 log_addr(&new->remote_addr), new->remote_port);
3118 return -1;
3119 }
3120
3121 if (cur_rtrs)
3122 SIMPLEQ_FOREACH(r, cur_rtrs, entry)for((r) = ((cur_rtrs)->sqh_first); (r) != ((void*)0); (r) =
((r)->entry.sqe_next))
3123 if (memcmp(&r->remote_addr, &new->remote_addr,
3124 sizeof(r->remote_addr)) == 0 &&
3125 r->remote_port == new->remote_port) {
3126 new->id = r->id;
3127 break;
3128 }
3129
3130 if (new->id == 0)
3131 new->id = ++id;
3132
3133 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)
;
3134
3135 return 0;
3136}
3137#line 3130 "parse.c"
3138/* allocate initial stack or double stack size, up to YYMAXDEPTH */
3139static int yygrowstack(void)
3140{
3141 unsigned int newsize;
3142 long sslen;
3143 short *newss;
3144 YYSTYPE *newvs;
3145
3146 if ((newsize = yystacksize) == 0)
3147 newsize = YYINITSTACKSIZE200;
3148 else if (newsize >= YYMAXDEPTH10000)
3149 return -1;
3150 else if ((newsize *= 2) > YYMAXDEPTH10000)
3151 newsize = YYMAXDEPTH10000;
3152 sslen = yyssp - yyss;
3153#ifdef SIZE_MAX0xffffffffffffffffUL
3154#define YY_SIZE_MAX0xffffffffffffffffUL SIZE_MAX0xffffffffffffffffUL
3155#else
3156#define YY_SIZE_MAX0xffffffffffffffffUL 0xffffffffU
3157#endif
3158 if (newsize && YY_SIZE_MAX0xffffffffffffffffUL / newsize < sizeof *newss)
3159 goto bail;
3160 newss = (short *)realloc(yyss, newsize * sizeof *newss);
3161 if (newss == NULL((void*)0))
3162 goto bail;
3163 yyss = newss;
3164 yyssp = newss + sslen;
3165 if (newsize && YY_SIZE_MAX0xffffffffffffffffUL / newsize < sizeof *newvs)
3166 goto bail;
3167 newvs = (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs);
3168 if (newvs == NULL((void*)0))
3169 goto bail;
3170 yyvs = newvs;
3171 yyvsp = newvs + sslen;
3172 yystacksize = newsize;
3173 yysslim = yyss + newsize - 1;
3174 return 0;
3175bail:
3176 if (yyss)
3177 free(yyss);
3178 if (yyvs)
3179 free(yyvs);
3180 yyss = yyssp = NULL((void*)0);
3181 yyvs = yyvsp = NULL((void*)0);
3182 yystacksize = 0;
3183 return -1;
3184}
3185
3186#define YYABORTgoto yyabort goto yyabort
3187#define YYREJECTgoto yyabort goto yyabort
3188#define YYACCEPTgoto yyaccept goto yyaccept
3189#define YYERRORgoto yyerrlab goto yyerrlab
3190int
3191yyparse(void)
3192{
3193 int yym, yyn, yystate;
3194#if YYDEBUG0
3195 const char *yys;
3196
3197 if ((yys = getenv("YYDEBUG")))
3198 {
3199 yyn = *yys;
3200 if (yyn >= '0' && yyn <= '9')
3201 yydebug = yyn - '0';
3202 }
3203#endif /* YYDEBUG */
3204
3205 yynerrs = 0;
3206 yyerrflag = 0;
3207 yychar = (-1);
3208
3209 if (yyss == NULL((void*)0) && yygrowstack()) goto yyoverflow;
3210 yyssp = yyss;
3211 yyvsp = yyvs;
3212 *yyssp = yystate = 0;
3213
3214yyloop:
3215 if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
3216 if (yychar < 0)
3217 {
3218 if ((yychar = yylex()) < 0) yychar = 0;
3219#if YYDEBUG0
3220 if (yydebug)
3221 {
3222 yys = 0;
3223 if (yychar <= YYMAXTOKEN382) yys = yyname[yychar];
3224 if (!yys) yys = "illegal-symbol";
3225 printf("%sdebug: state %d, reading %d (%s)\n",
3226 YYPREFIX"yy", yystate, yychar, yys);
3227 }
3228#endif
3229 }
3230 if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
3231 yyn <= YYTABLESIZE1254 && yycheck[yyn] == yychar)
3232 {
3233#if YYDEBUG0
3234 if (yydebug)
3235 printf("%sdebug: state %d, shifting to state %d\n",
3236 YYPREFIX"yy", yystate, yytable[yyn]);
3237#endif
3238 if (yyssp >= yysslim && yygrowstack())
3239 {
3240 goto yyoverflow;
3241 }
3242 *++yyssp = yystate = yytable[yyn];
3243 *++yyvsp = yylval;
3244 yychar = (-1);
3245 if (yyerrflag > 0) --yyerrflag;
3246 goto yyloop;
3247 }
3248 if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
3249 yyn <= YYTABLESIZE1254 && yycheck[yyn] == yychar)
3250 {
3251 yyn = yytable[yyn];
3252 goto yyreduce;
3253 }
3254 if (yyerrflag) goto yyinrecovery;
3255#if defined(__GNUC__4)
3256 goto yynewerror;
3257#endif
3258yynewerror:
3259 yyerror("syntax error");
3260#if defined(__GNUC__4)
3261 goto yyerrlab;
3262#endif
3263yyerrlab:
3264 ++yynerrs;
3265yyinrecovery:
3266 if (yyerrflag < 3)
3267 {
3268 yyerrflag = 3;
3269 for (;;)
3270 {
3271 if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE256) >= 0 &&
3272 yyn <= YYTABLESIZE1254 && yycheck[yyn] == YYERRCODE256)
3273 {
3274#if YYDEBUG0
3275 if (yydebug)
3276 printf("%sdebug: state %d, error recovery shifting\
3277 to state %d\n", YYPREFIX"yy", *yyssp, yytable[yyn]);
3278#endif
3279 if (yyssp >= yysslim && yygrowstack())
3280 {
3281 goto yyoverflow;
3282 }
3283 *++yyssp = yystate = yytable[yyn];
3284 *++yyvsp = yylval;
3285 goto yyloop;
3286 }
3287 else
3288 {
3289#if YYDEBUG0
3290 if (yydebug)
3291 printf("%sdebug: error recovery discarding state %d\n",
3292 YYPREFIX"yy", *yyssp);
3293#endif
3294 if (yyssp <= yyss) goto yyabort;
3295 --yyssp;
3296 --yyvsp;
3297 }
3298 }
3299 }
3300 else
3301 {
3302 if (yychar == 0) goto yyabort;
3303#if YYDEBUG0
3304 if (yydebug)
3305 {
3306 yys = 0;
3307 if (yychar <= YYMAXTOKEN382) yys = yyname[yychar];
3308 if (!yys) yys = "illegal-symbol";
3309 printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
3310 YYPREFIX"yy", yystate, yychar, yys);
3311 }
3312#endif
3313 yychar = (-1);
3314 goto yyloop;
3315 }
3316yyreduce:
3317#if YYDEBUG0
3318 if (yydebug)
3319 printf("%sdebug: state %d, reducing by rule %d (%s)\n",
3320 YYPREFIX"yy", yystate, yyn, yyrule[yyn]);
3321#endif
3322 yym = yylen[yyn];
3323 if (yym)
3324 yyval = yyvsp[1-yym];
3325 else
3326 memset(&yyval, 0, sizeof yyval);
3327 switch (yyn)
3328 {
3329case 16:
3330#line 269 "/usr/src/usr.sbin/bgpd/parse.y"
3331{ file->errors++; }
3332break;
3333case 17:
3334#line 272 "/usr/src/usr.sbin/bgpd/parse.y"
3335{
3336 /*
3337 * According to iana 65535 and 4294967295 are reserved
3338 * but enforcing this is not duty of the parser.
3339 */
3340 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > UINT_MAX(2147483647 *2U +1U)) {
3341 yyerror("AS too big: max %u", UINT_MAX(2147483647 *2U +1U));
3342 YYERRORgoto yyerrlab;
3343 }
3344 }
3345break;
3346case 18:
3347#line 283 "/usr/src/usr.sbin/bgpd/parse.y"
3348{
3349 const char *errstr;
3350 char *dot;
3351 u_int32_t uvalh = 0, uval;
3352
3353 if ((dot = strchr(yyvsp[0].v.string,'.')) != NULL((void*)0)) {
3354 *dot++ = '\0';
3355 uvalh = strtonum(yyvsp[0].v.string, 0, USHRT_MAX(32767 *2 +1), &errstr);
3356 if (errstr) {
3357 yyerror("number %s is %s", yyvsp[0].v.string, errstr);
3358 free(yyvsp[0].v.string);
3359 YYERRORgoto yyerrlab;
3360 }
3361 uval = strtonum(dot, 0, USHRT_MAX(32767 *2 +1), &errstr);
3362 if (errstr) {
3363 yyerror("number %s is %s", dot, errstr);
3364 free(yyvsp[0].v.string);
3365 YYERRORgoto yyerrlab;
3366 }
3367 free(yyvsp[0].v.string);
3368 } else {
3369 yyerror("AS %s is bad", yyvsp[0].v.string);
3370 free(yyvsp[0].v.string);
3371 YYERRORgoto yyerrlab;
3372 }
3373 if (uvalh == 0 && (uval == AS_TRANS23456 || uval == 0)) {
3374 yyerror("AS %u is reserved and may not be used",
3375 uval);
3376 YYERRORgoto yyerrlab;
3377 }
3378 yyval.v.number = uval | (uvalh << 16);
3379 }
3380break;
3381case 19:
3382#line 315 "/usr/src/usr.sbin/bgpd/parse.y"
3383{
3384 if (yyvsp[0].v.number == AS_TRANS23456 || yyvsp[0].v.number == 0) {
3385 yyerror("AS %u is reserved and may not be used",
3386 (u_int32_t)yyvsp[0].v.number);
3387 YYERRORgoto yyerrlab;
3388 }
3389 yyval.v.number = yyvsp[0].v.number;
3390 }
3391break;
3392case 20:
3393#line 325 "/usr/src/usr.sbin/bgpd/parse.y"
3394{
3395 const char *errstr;
3396 char *dot;
3397 u_int32_t uvalh = 0, uval;
3398
3399 if ((dot = strchr(yyvsp[0].v.string,'.')) != NULL((void*)0)) {
3400 *dot++ = '\0';
3401 uvalh = strtonum(yyvsp[0].v.string, 0, USHRT_MAX(32767 *2 +1), &errstr);
3402 if (errstr) {
3403 yyerror("number %s is %s", yyvsp[0].v.string, errstr);
3404 free(yyvsp[0].v.string);
3405 YYERRORgoto yyerrlab;
3406 }
3407 uval = strtonum(dot, 0, USHRT_MAX(32767 *2 +1), &errstr);
3408 if (errstr) {
3409 yyerror("number %s is %s", dot, errstr);
3410 free(yyvsp[0].v.string);
3411 YYERRORgoto yyerrlab;
3412 }
3413 free(yyvsp[0].v.string);
3414 } else {
3415 yyerror("AS %s is bad", yyvsp[0].v.string);
3416 free(yyvsp[0].v.string);
3417 YYERRORgoto yyerrlab;
3418 }
3419 yyval.v.number = uval | (uvalh << 16);
3420 }
3421break;
3422case 21:
3423#line 352 "/usr/src/usr.sbin/bgpd/parse.y"
3424{
3425 yyval.v.number = yyvsp[0].v.number;
3426 }
3427break;
3428case 22:
3429#line 357 "/usr/src/usr.sbin/bgpd/parse.y"
3430{
3431 if (asprintf(&yyval.v.string, "%s %s", yyvsp[-1].v.string, yyvsp[0].v.string) == -1)
3432 fatal("string: asprintf");
3433 free(yyvsp[-1].v.string);
3434 free(yyvsp[0].v.string);
3435 }
3436break;
3437case 24:
3438#line 366 "/usr/src/usr.sbin/bgpd/parse.y"
3439{
3440 if (!strcmp(yyvsp[0].v.string, "yes"))
3441 yyval.v.number = 1;
3442 else if (!strcmp(yyvsp[0].v.string, "no"))
3443 yyval.v.number = 0;
3444 else {
3445 yyerror("syntax error, "
3446 "either yes or no expected");
3447 free(yyvsp[0].v.string);
3448 YYERRORgoto yyerrlab;
3449 }
3450 free(yyvsp[0].v.string);
3451 }
3452break;
3453case 25:
3454#line 381 "/usr/src/usr.sbin/bgpd/parse.y"
3455{
3456 char *s = yyvsp[-2].v.string;
3457 if (cmd_opts & BGPD_OPT_VERBOSE0x0001)
3458 printf("%s = \"%s\"\n", yyvsp[-2].v.string, yyvsp[0].v.string);
3459 while (*s++) {
3460 if (isspace((unsigned char)*s)) {
3461 yyerror("macro name cannot contain "
3462 "whitespace");
3463 free(yyvsp[-2].v.string);
3464 free(yyvsp[0].v.string);
3465 YYERRORgoto yyerrlab;
3466 }
3467 }
3468 if (symset(yyvsp[-2].v.string, yyvsp[0].v.string, 0) == -1)
3469 fatal("cannot store variable");
3470 free(yyvsp[-2].v.string);
3471 free(yyvsp[0].v.string);
3472 }
3473break;
3474case 26:
3475#line 401 "/usr/src/usr.sbin/bgpd/parse.y"
3476{
3477 struct file *nfile;
3478
3479 if ((nfile = pushfile(yyvsp[0].v.string, 1)) == NULL((void*)0)) {
3480 yyerror("failed to include file %s", yyvsp[0].v.string);
3481 free(yyvsp[0].v.string);
3482 YYERRORgoto yyerrlab;
3483 }
3484 free(yyvsp[0].v.string);
3485
3486 file = nfile;
3487 lungetc('\n');
3488 }
3489break;
3490case 27:
3491#line 416 "/usr/src/usr.sbin/bgpd/parse.y"
3492{
3493 if (strlen(yyvsp[-2].v.string) >= SET_NAME_LEN128) {
3494 yyerror("as-set name %s too long", yyvsp[-2].v.string);
3495 free(yyvsp[-2].v.string);
3496 YYERRORgoto yyerrlab;
3497 }
3498 if (new_as_set(yyvsp[-2].v.string) != 0) {
3499 free(yyvsp[-2].v.string);
3500 YYERRORgoto yyerrlab;
3501 }
3502 free(yyvsp[-2].v.string);
3503 }
3504break;
3505case 28:
3506#line 427 "/usr/src/usr.sbin/bgpd/parse.y"
3507{
3508 done_as_set();
3509 }
3510break;
3511case 29:
3512#line 430 "/usr/src/usr.sbin/bgpd/parse.y"
3513{
3514 if (new_as_set(yyvsp[-3].v.string) != 0) {
3515 free(yyvsp[-3].v.string);
3516 YYERRORgoto yyerrlab;
3517 }
3518 free(yyvsp[-3].v.string);
3519 }
3520break;
3521case 30:
3522#line 438 "/usr/src/usr.sbin/bgpd/parse.y"
3523{ add_as_set(yyvsp[0].v.number); }
3524break;
3525case 31:
3526#line 439 "/usr/src/usr.sbin/bgpd/parse.y"
3527{ add_as_set(yyvsp[0].v.number); }
3528break;
3529case 32:
3530#line 441 "/usr/src/usr.sbin/bgpd/parse.y"
3531{
3532 if ((curpset = new_prefix_set(yyvsp[-2].v.string, 0)) == NULL((void*)0)) {
3533 free(yyvsp[-2].v.string);
3534 YYERRORgoto yyerrlab;
3535 }
3536 free(yyvsp[-2].v.string);
3537 }
3538break;
3539case 33:
3540#line 447 "/usr/src/usr.sbin/bgpd/parse.y"
3541{
3542 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)
;
3543 curpset = NULL((void*)0);
3544 }
3545break;
3546case 34:
3547#line 451 "/usr/src/usr.sbin/bgpd/parse.y"
3548{
3549 if ((curpset = new_prefix_set(yyvsp[-3].v.string, 0)) == NULL((void*)0)) {
3550 free(yyvsp[-3].v.string);
3551 YYERRORgoto yyerrlab;
3552 }
3553 free(yyvsp[-3].v.string);
3554 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)
;
3555 curpset = NULL((void*)0);
3556 }
3557break;
3558case 35:
3559#line 461 "/usr/src/usr.sbin/bgpd/parse.y"
3560{
3561 struct prefixset_item *psi;
3562 if (yyvsp[0].v.prefixset_item->p.op != OP_NONE)
3563 curpset->sflags |= PREFIXSET_FLAG_OPS0x04;
3564 psi = RB_INSERT(prefixset_tree, &curpset->psitems, yyvsp[0].v.prefixset_item)prefixset_tree_RB_INSERT(&curpset->psitems, yyvsp[0].v
.prefixset_item)
;
3565 if (psi != NULL((void*)0)) {
3566 if (cmd_opts & BGPD_OPT_VERBOSE20x0002)
3567 log_warnx("warning: duplicate entry in "
3568 "prefixset \"%s\" for %s/%u",
3569 curpset->name,
3570 log_addr(&yyvsp[0].v.prefixset_item->p.addr), yyvsp[0].v.prefixset_item->p.len);
3571 free(yyvsp[0].v.prefixset_item);
3572 }
3573 }
3574break;
3575case 36:
3576#line 475 "/usr/src/usr.sbin/bgpd/parse.y"
3577{
3578 struct prefixset_item *psi;
3579 if (yyvsp[0].v.prefixset_item->p.op != OP_NONE)
3580 curpset->sflags |= PREFIXSET_FLAG_OPS0x04;
3581 psi = RB_INSERT(prefixset_tree, &curpset->psitems, yyvsp[0].v.prefixset_item)prefixset_tree_RB_INSERT(&curpset->psitems, yyvsp[0].v
.prefixset_item)
;
3582 if (psi != NULL((void*)0)) {
3583 if (cmd_opts & BGPD_OPT_VERBOSE20x0002)
3584 log_warnx("warning: duplicate entry in "
3585 "prefixset \"%s\" for %s/%u",
3586 curpset->name,
3587 log_addr(&yyvsp[0].v.prefixset_item->p.addr), yyvsp[0].v.prefixset_item->p.len);
3588 free(yyvsp[0].v.prefixset_item);
3589 }
3590 }
3591break;
3592case 37:
3593#line 491 "/usr/src/usr.sbin/bgpd/parse.y"
3594{
3595 if (yyvsp[0].v.prefixlen.op != OP_NONE && yyvsp[0].v.prefixlen.op != OP_RANGE) {
3596 yyerror("unsupported prefixlen operation in "
3597 "prefix-set");
3598 YYERRORgoto yyerrlab;
3599 }
3600 if ((yyval.v.prefixset_item = calloc(1, sizeof(*yyval.v.prefixset_item))) == NULL((void*)0))
3601 fatal(NULL((void*)0));
3602 memcpy(&yyval.v.prefixset_item->p.addr, &yyvsp[-1].v.prefix.prefix, sizeof(yyval.v.prefixset_item->p.addr));
3603 yyval.v.prefixset_item->p.len = yyvsp[-1].v.prefix.len;
3604 if (merge_prefixspec(&yyval.v.prefixset_item->p, &yyvsp[0].v.prefixlen) == -1) {
3605 free(yyval.v.prefixset_item);
3606 YYERRORgoto yyerrlab;
3607 }
3608 }
3609break;
3610case 38:
3611#line 508 "/usr/src/usr.sbin/bgpd/parse.y"
3612{
3613 curroatree = &conf->roa;
3614 noexpires = 0;
3615 }
3616break;
3617case 39:
3618#line 511 "/usr/src/usr.sbin/bgpd/parse.y"
3619{
3620 curroatree = NULL((void*)0);
3621 noexpires = 1;
3622 }
3623break;
3624case 41:
3625#line 518 "/usr/src/usr.sbin/bgpd/parse.y"
3626{
3627 if ((curoset = new_prefix_set(yyvsp[-2].v.string, 1)) == NULL((void*)0)) {
3628 free(yyvsp[-2].v.string);
3629 YYERRORgoto yyerrlab;
3630 }
3631 curroatree = &curoset->roaitems;
3632 noexpires = 1;
3633 free(yyvsp[-2].v.string);
3634 }
3635break;
3636case 42:
3637#line 526 "/usr/src/usr.sbin/bgpd/parse.y"
3638{
3639 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)
;
3640 curoset = NULL((void*)0);
3641 curroatree = NULL((void*)0);
3642 }
3643break;
3644case 43:
3645#line 531 "/usr/src/usr.sbin/bgpd/parse.y"
3646{
3647 if ((curoset = new_prefix_set(yyvsp[-3].v.string, 1)) == NULL((void*)0)) {
3648 free(yyvsp[-3].v.string);
3649 YYERRORgoto yyerrlab;
3650 }
3651 free(yyvsp[-3].v.string);
3652 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)
;
3653 curoset = NULL((void*)0);
3654 curroatree = NULL((void*)0);
3655 }
3656break;
3657case 44:
3658#line 543 "/usr/src/usr.sbin/bgpd/parse.y"
3659{
3660 yyval.v.number = 0;
3661 }
3662break;
3663case 45:
3664#line 546 "/usr/src/usr.sbin/bgpd/parse.y"
3665{
3666 if (noexpires) {
3667 yyerror("syntax error, expires not allowed");
3668 YYERRORgoto yyerrlab;
3669 }
3670 yyval.v.number = yyvsp[0].v.number;
3671 }
3672break;
3673case 46:
3674#line 554 "/usr/src/usr.sbin/bgpd/parse.y"
3675{
3676 if (yyvsp[-3].v.prefixset_item->p.len_min != yyvsp[-3].v.prefixset_item->p.len) {
3677 yyerror("unsupported prefixlen operation in "
3678 "roa-set");
3679 free(yyvsp[-3].v.prefixset_item);
3680 YYERRORgoto yyerrlab;
3681 }
3682 add_roa_set(yyvsp[-3].v.prefixset_item, yyvsp[-1].v.number, yyvsp[-3].v.prefixset_item->p.len_max, yyvsp[0].v.number);
3683 free(yyvsp[-3].v.prefixset_item);
3684 }
3685break;
3686case 47:
3687#line 564 "/usr/src/usr.sbin/bgpd/parse.y"
3688{
3689 if (yyvsp[-3].v.prefixset_item->p.len_min != yyvsp[-3].v.prefixset_item->p.len) {
3690 yyerror("unsupported prefixlen operation in "
3691 "roa-set");
3692 free(yyvsp[-3].v.prefixset_item);
3693 YYERRORgoto yyerrlab;
3694 }
3695 add_roa_set(yyvsp[-3].v.prefixset_item, yyvsp[-1].v.number, yyvsp[-3].v.prefixset_item->p.len_max, yyvsp[0].v.number);
3696 free(yyvsp[-3].v.prefixset_item);
3697 }
3698break;
3699case 48:
3700#line 576 "/usr/src/usr.sbin/bgpd/parse.y"
3701{
3702 currtr = get_rtr(&yyvsp[0].v.addr);
3703 currtr->remote_port = 323;
3704 if (insert_rtr(currtr) == -1) {
3705 free(currtr);
3706 YYERRORgoto yyerrlab;
3707 }
3708 currtr = NULL((void*)0);
3709 }
3710break;
3711case 49:
3712#line 585 "/usr/src/usr.sbin/bgpd/parse.y"
3713{
3714 currtr = get_rtr(&yyvsp[0].v.addr);
3715 currtr->remote_port = 323;
3716 }
3717break;
3718case 50:
3719#line 588 "/usr/src/usr.sbin/bgpd/parse.y"
3720{
3721 if (insert_rtr(currtr) == -1) {
3722 free(currtr);
3723 YYERRORgoto yyerrlab;
3724 }
3725 currtr = NULL((void*)0);
3726 }
3727break;
3728case 53:
3729#line 600 "/usr/src/usr.sbin/bgpd/parse.y"
3730{
3731 if (strlcpy(currtr->descr, yyvsp[0].v.string,
3732 sizeof(currtr->descr)) >=
3733 sizeof(currtr->descr)) {
3734 yyerror("descr \"%s\" too long: max %zu",
3735 yyvsp[0].v.string, sizeof(currtr->descr) - 1);
3736 free(yyvsp[0].v.string);
3737 YYERRORgoto yyerrlab;
3738 }
3739 free(yyvsp[0].v.string);
3740 }
3741break;
3742case 54:
3743#line 611 "/usr/src/usr.sbin/bgpd/parse.y"
3744{
3745 if (yyvsp[0].v.addr.aid != currtr->remote_addr.aid) {
3746 yyerror("Bad address family %s for "
3747 "local-addr", aid2str(yyvsp[0].v.addr.aid));
3748 YYERRORgoto yyerrlab;
3749 }
3750 currtr->local_addr = yyvsp[0].v.addr;
3751 }
3752break;
3753case 55:
3754#line 619 "/usr/src/usr.sbin/bgpd/parse.y"
3755{
3756 if (yyvsp[0].v.number < 1 || yyvsp[0].v.number > USHRT_MAX(32767 *2 +1)) {
3757 yyerror("local-port must be between %u and %u",
3758 1, USHRT_MAX(32767 *2 +1));
3759 YYERRORgoto yyerrlab;
3760 }
3761 currtr->remote_port = yyvsp[0].v.number;
3762 }
3763break;
3764case 56:
3765#line 629 "/usr/src/usr.sbin/bgpd/parse.y"
3766{
3767 conf->as = yyvsp[0].v.number;
3768 if (yyvsp[0].v.number > USHRT_MAX(32767 *2 +1))
3769 conf->short_as = AS_TRANS23456;
3770 else
3771 conf->short_as = yyvsp[0].v.number;
3772 }
3773break;
3774case 57:
3775#line 636 "/usr/src/usr.sbin/bgpd/parse.y"
3776{
3777 conf->as = yyvsp[-1].v.number;
3778 conf->short_as = yyvsp[0].v.number;
3779 }
3780break;
3781case 58:
3782#line 640 "/usr/src/usr.sbin/bgpd/parse.y"
3783{
3784 if (yyvsp[0].v.addr.aid != AID_INET1) {
3785 yyerror("router-id must be an IPv4 address");
3786 YYERRORgoto yyerrlab;
3787 }
3788 conf->bgpid = yyvsp[0].v.addr.v4ba.v4.s_addr;
3789 }
3790break;
3791case 59:
3792#line 647 "/usr/src/usr.sbin/bgpd/parse.y"
3793{
3794 if (yyvsp[0].v.number < MIN_HOLDTIME3 || yyvsp[0].v.number > USHRT_MAX(32767 *2 +1)) {
3795 yyerror("holdtime must be between %u and %u",
3796 MIN_HOLDTIME3, USHRT_MAX(32767 *2 +1));
3797 YYERRORgoto yyerrlab;
3798 }
3799 conf->holdtime = yyvsp[0].v.number;
3800 }
3801break;
3802case 60:
3803#line 655 "/usr/src/usr.sbin/bgpd/parse.y"
3804{
3805 if (yyvsp[0].v.number < MIN_HOLDTIME3 || yyvsp[0].v.number > USHRT_MAX(32767 *2 +1)) {
3806 yyerror("holdtime must be between %u and %u",
3807 MIN_HOLDTIME3, USHRT_MAX(32767 *2 +1));
3808 YYERRORgoto yyerrlab;
3809 }
3810 conf->min_holdtime = yyvsp[0].v.number;
3811 }
3812break;
3813case 61:
3814#line 663 "/usr/src/usr.sbin/bgpd/parse.y"
3815{
3816 struct listen_addr *la;
3817 struct sockaddr *sa;
3818
3819 if ((la = calloc(1, sizeof(struct listen_addr))) ==
3820 NULL((void*)0))
3821 fatal("parse conf_main listen on calloc");
3822
3823 la->fd = -1;
3824 la->reconf = RECONF_REINIT;
3825 sa = addr2sa(&yyvsp[0].v.addr, BGP_PORT179, &la->sa_len);
3826 memcpy(&la->sa, sa, la->sa_len);
3827 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)
;
3828 }
3829break;
3830case 62:
3831#line 677 "/usr/src/usr.sbin/bgpd/parse.y"
3832{
3833 if (yyvsp[0].v.number <= RTP_NONE0 || yyvsp[0].v.number > RTP_MAX63) {
3834 yyerror("invalid fib-priority");
3835 YYERRORgoto yyerrlab;
3836 }
3837 conf->fib_priority = yyvsp[0].v.number;
3838 }
3839break;
3840case 63:
3841#line 684 "/usr/src/usr.sbin/bgpd/parse.y"
3842{
3843 struct rde_rib *rr;
3844 rr = find_rib("Loc-RIB");
3845 if (rr == NULL((void*)0))
3846 fatalx("RTABLE can not find the main RIB!");
3847
3848 if (yyvsp[0].v.number == 0)
3849 rr->flags |= F_RIB_NOFIBSYNC0x0008;
3850 else
3851 rr->flags &= ~F_RIB_NOFIBSYNC0x0008;
3852 }
3853break;
3854case 64:
3855#line 695 "/usr/src/usr.sbin/bgpd/parse.y"
3856{
3857 if (yyvsp[0].v.number == 1)
3858 conf->flags |= BGPD_FLAG_DECISION_TRANS_AS0x0200;
3859 else
3860 conf->flags &= ~BGPD_FLAG_DECISION_TRANS_AS0x0200;
3861 }
3862break;
3863case 65:
3864#line 701 "/usr/src/usr.sbin/bgpd/parse.y"
3865{
3866 if (yyvsp[0].v.number == 1)
3867 conf->flags |= BGPD_FLAG_NO_AS_SET0x1000;
3868 else
3869 conf->flags &= ~BGPD_FLAG_NO_AS_SET0x1000;
3870 }
3871break;
3872case 66:
3873#line 707 "/usr/src/usr.sbin/bgpd/parse.y"
3874{
3875 if (!strcmp(yyvsp[0].v.string, "updates"))
3876 conf->log |= BGPD_LOG_UPDATES0x0001;
3877 else {
3878 free(yyvsp[0].v.string);
3879 YYERRORgoto yyerrlab;
3880 }
3881 free(yyvsp[0].v.string);
3882 }
3883break;
3884case 68:
3885#line 717 "/usr/src/usr.sbin/bgpd/parse.y"
3886{
3887 int action;
3888
3889 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX2147483647) {
3890 yyerror("bad timeout");
3891 free(yyvsp[-2].v.string);
3892 free(yyvsp[-1].v.string);
3893 YYERRORgoto yyerrlab;
3894 }
3895 if (!strcmp(yyvsp[-2].v.string, "table"))
3896 action = MRT_TABLE_DUMP;
3897 else if (!strcmp(yyvsp[-2].v.string, "table-mp"))
3898 action = MRT_TABLE_DUMP_MP;
3899 else if (!strcmp(yyvsp[-2].v.string, "table-v2"))
3900 action = MRT_TABLE_DUMP_V2;
3901 else {
3902 yyerror("unknown mrt dump type");
3903 free(yyvsp[-2].v.string);
3904 free(yyvsp[-1].v.string);
3905 YYERRORgoto yyerrlab;
3906 }
3907 free(yyvsp[-2].v.string);
3908 if (add_mrtconfig(action, yyvsp[-1].v.string, yyvsp[0].v.number, NULL((void*)0), NULL((void*)0)) == -1) {
3909 free(yyvsp[-1].v.string);
3910 YYERRORgoto yyerrlab;
3911 }
3912 free(yyvsp[-1].v.string);
3913 }
3914break;
3915case 69:
3916#line 745 "/usr/src/usr.sbin/bgpd/parse.y"
3917{
3918 int action;
3919
3920 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX2147483647) {
3921 yyerror("bad timeout");
3922 free(yyvsp[-3].v.string);
3923 free(yyvsp[-2].v.string);
3924 free(yyvsp[-1].v.string);
3925 YYERRORgoto yyerrlab;
3926 }
3927 if (!strcmp(yyvsp[-2].v.string, "table"))
3928 action = MRT_TABLE_DUMP;
3929 else if (!strcmp(yyvsp[-2].v.string, "table-mp"))
3930 action = MRT_TABLE_DUMP_MP;
3931 else if (!strcmp(yyvsp[-2].v.string, "table-v2"))
3932 action = MRT_TABLE_DUMP_V2;
3933 else {
3934 yyerror("unknown mrt dump type");
3935 free(yyvsp[-3].v.string);
3936 free(yyvsp[-2].v.string);
3937 free(yyvsp[-1].v.string);
3938 YYERRORgoto yyerrlab;
3939 }
3940 free(yyvsp[-2].v.string);
3941 if (add_mrtconfig(action, yyvsp[-1].v.string, yyvsp[0].v.number, NULL((void*)0), yyvsp[-3].v.string) == -1) {
3942 free(yyvsp[-3].v.string);
3943 free(yyvsp[-1].v.string);
3944 YYERRORgoto yyerrlab;
3945 }
3946 free(yyvsp[-3].v.string);
3947 free(yyvsp[-1].v.string);
3948 }
3949break;
3950case 71:
3951#line 778 "/usr/src/usr.sbin/bgpd/parse.y"
3952{
3953 if (!strcmp(yyvsp[-1].v.string, "route-age"))
3954 conf->flags |= BGPD_FLAG_DECISION_ROUTEAGE0x0100;
3955 else {
3956 yyerror("unknown route decision type");
3957 free(yyvsp[-1].v.string);
3958 YYERRORgoto yyerrlab;
3959 }
3960 free(yyvsp[-1].v.string);
3961 }
3962break;
3963case 72:
3964#line 788 "/usr/src/usr.sbin/bgpd/parse.y"
3965{
3966 if (!strcmp(yyvsp[-1].v.string, "route-age"))
3967 conf->flags &= ~BGPD_FLAG_DECISION_ROUTEAGE0x0100;
3968 else {
3969 yyerror("unknown route decision type");
3970 free(yyvsp[-1].v.string);
3971 YYERRORgoto yyerrlab;
3972 }
3973 free(yyvsp[-1].v.string);
3974 }
3975break;
3976case 73:
3977#line 798 "/usr/src/usr.sbin/bgpd/parse.y"
3978{
3979 if (!strcmp(yyvsp[0].v.string, "always"))
3980 conf->flags |= BGPD_FLAG_DECISION_MED_ALWAYS0x0400;
3981 else if (!strcmp(yyvsp[0].v.string, "strict"))
3982 conf->flags &= ~BGPD_FLAG_DECISION_MED_ALWAYS0x0400;
3983 else {
3984 yyerror("rde med compare: "
3985 "unknown setting \"%s\"", yyvsp[0].v.string);
3986 free(yyvsp[0].v.string);
3987 YYERRORgoto yyerrlab;
3988 }
3989 free(yyvsp[0].v.string);
3990 }
3991break;
3992case 74:
3993#line 811 "/usr/src/usr.sbin/bgpd/parse.y"
3994{
3995 if (!strcmp(yyvsp[0].v.string, "all"))
3996 conf->flags |= BGPD_FLAG_DECISION_ALL_PATHS0x0800;
3997 else if (!strcmp(yyvsp[0].v.string, "default"))
3998 conf->flags &= ~BGPD_FLAG_DECISION_ALL_PATHS0x0800;
3999 else {
4000 yyerror("rde evaluate: "
4001 "unknown setting \"%s\"", yyvsp[0].v.string);
4002 free(yyvsp[0].v.string);
4003 YYERRORgoto yyerrlab;
4004 }
4005 free(yyvsp[0].v.string);
4006 }
4007break;
4008case 75:
4009#line 824 "/usr/src/usr.sbin/bgpd/parse.y"
4010{
4011 if (!strcmp(yyvsp[0].v.string, "bgp"))
4012 conf->flags |= BGPD_FLAG_NEXTHOP_BGP0x0010;
4013 else if (!strcmp(yyvsp[0].v.string, "default"))
4014 conf->flags |= BGPD_FLAG_NEXTHOP_DEFAULT0x0020;
4015 else {
4016 yyerror("nexthop depend on: "
4017 "unknown setting \"%s\"", yyvsp[0].v.string);
4018 free(yyvsp[0].v.string);
4019 YYERRORgoto yyerrlab;
4020 }
4021 free(yyvsp[0].v.string);
4022 }
4023break;
4024case 76:
4025#line 837 "/usr/src/usr.sbin/bgpd/parse.y"
4026{
4027 struct rde_rib *rr;
4028 if (yyvsp[0].v.number > RT_TABLEID_MAX255) {
4029 yyerror("rtable %llu too big: max %u", yyvsp[0].v.number,
4030 RT_TABLEID_MAX255);
4031 YYERRORgoto yyerrlab;
4032 }
4033 if (ktable_exists(yyvsp[0].v.number, NULL((void*)0)) != 1) {
4034 yyerror("rtable id %lld does not exist", yyvsp[0].v.number);
4035 YYERRORgoto yyerrlab;
4036 }
4037 rr = find_rib("Loc-RIB");
4038 if (rr == NULL((void*)0))
4039 fatalx("RTABLE can not find the main RIB!");
4040 rr->rtableid = yyvsp[0].v.number;
4041 }
4042break;
4043case 77:
4044#line 853 "/usr/src/usr.sbin/bgpd/parse.y"
4045{
4046 if (yyvsp[0].v.number > USHRT_MAX(32767 *2 +1) || yyvsp[0].v.number < 1) {
4047 yyerror("invalid connect-retry");
4048 YYERRORgoto yyerrlab;
4049 }
4050 conf->connectretry = yyvsp[0].v.number;
4051 }
4052break;
4053case 78:
4054#line 860 "/usr/src/usr.sbin/bgpd/parse.y"
4055{
4056 if (strlen(yyvsp[-1].v.string) >=
4057 sizeof(((struct sockaddr_un *)0)->sun_path)) {
4058 yyerror("socket path too long");
4059 YYERRORgoto yyerrlab;
4060 }
4061 if (yyvsp[0].v.number) {
4062 free(conf->rcsock);
4063 conf->rcsock = yyvsp[-1].v.string;
4064 } else {
4065 free(conf->csock);
4066 conf->csock = yyvsp[-1].v.string;
4067 }
4068 }
4069break;
4070case 79:
4071#line 876 "/usr/src/usr.sbin/bgpd/parse.y"
4072{
4073 if ((currib = add_rib(yyvsp[0].v.string)) == NULL((void*)0)) {
4074 free(yyvsp[0].v.string);
4075 YYERRORgoto yyerrlab;
4076 }
4077 free(yyvsp[0].v.string);
4078 }
4079break;
4080case 80:
4081#line 882 "/usr/src/usr.sbin/bgpd/parse.y"
4082{
4083 currib = NULL((void*)0);
4084 }
4085break;
4086case 82:
4087#line 887 "/usr/src/usr.sbin/bgpd/parse.y"
4088{
4089 if (yyvsp[-1].v.number > RT_TABLEID_MAX255) {
4090 yyerror("rtable %llu too big: max %u", yyvsp[-1].v.number,
4091 RT_TABLEID_MAX255);
4092 YYERRORgoto yyerrlab;
4093 }
4094 if (rib_add_fib(currib, yyvsp[-1].v.number) == -1)
4095 YYERRORgoto yyerrlab;
4096 }
4097break;
4098case 83:
4099#line 896 "/usr/src/usr.sbin/bgpd/parse.y"
4100{
4101 if (yyvsp[-1].v.number) {
4102 yyerror("bad rde rib definition");
4103 YYERRORgoto yyerrlab;
4104 }
4105 currib->flags |= F_RIB_NOEVALUATE0x0002;
4106 }
4107break;
4108case 85:
4109#line 906 "/usr/src/usr.sbin/bgpd/parse.y"
4110{
4111 if (yyvsp[0].v.number == 0)
4112 currib->flags |= F_RIB_NOFIBSYNC0x0008;
4113 else
4114 currib->flags &= ~F_RIB_NOFIBSYNC0x0008;
4115 }
4116break;
4117case 86:
4118#line 914 "/usr/src/usr.sbin/bgpd/parse.y"
4119{
4120 int action;
4121
4122 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX2147483647) {
4123 yyerror("bad timeout");
4124 free(yyvsp[-3].v.string);
4125 free(yyvsp[-1].v.string);
4126 YYERRORgoto yyerrlab;
4127 }
4128 if (!strcmp(yyvsp[-3].v.string, "all"))
4129 action = yyvsp[-2].v.number ? MRT_ALL_IN : MRT_ALL_OUT;
4130 else if (!strcmp(yyvsp[-3].v.string, "updates"))
4131 action = yyvsp[-2].v.number ? MRT_UPDATE_IN : MRT_UPDATE_OUT;
4132 else {
4133 yyerror("unknown mrt msg dump type");
4134 free(yyvsp[-3].v.string);
4135 free(yyvsp[-1].v.string);
4136 YYERRORgoto yyerrlab;
4137 }
4138 if (add_mrtconfig(action, yyvsp[-1].v.string, yyvsp[0].v.number, curpeer, NULL((void*)0)) ==
4139 -1) {
4140 free(yyvsp[-3].v.string);
4141 free(yyvsp[-1].v.string);
4142 YYERRORgoto yyerrlab;
4143 }
4144 free(yyvsp[-3].v.string);
4145 free(yyvsp[-1].v.string);
4146 }
4147break;
4148case 87:
4149#line 944 "/usr/src/usr.sbin/bgpd/parse.y"
4150{
4151 struct network *n, *m;
4152
4153 if ((n = calloc(1, sizeof(struct network))) == NULL((void*)0))
4154 fatal("new_network");
4155 memcpy(&n->net.prefix, &yyvsp[-1].v.prefix.prefix,
4156 sizeof(n->net.prefix));
4157 n->net.prefixlen = yyvsp[-1].v.prefix.len;
4158 filterset_move(yyvsp[0].v.filter_set_head, &n->net.attrset);
4159 free(yyvsp[0].v.filter_set_head);
4160 TAILQ_FOREACH(m, netconf, entry)for((m) = ((netconf)->tqh_first); (m) != ((void*)0); (m) =
((m)->entry.tqe_next))
{
4161 if (n->net.type == m->net.type &&
4162 n->net.prefixlen == m->net.prefixlen &&
4163 prefix_compare(&n->net.prefix,
4164 &m->net.prefix, n->net.prefixlen) == 0)
4165 yyerror("duplicate prefix "
4166 "in network statement");
4167 }
4168
4169 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)
;
4170 }
4171break;
4172case 88:
4173#line 965 "/usr/src/usr.sbin/bgpd/parse.y"
4174{
4175 struct prefixset *ps;
4176 struct network *n;
4177 if ((ps = find_prefixset(yyvsp[-1].v.string, &conf->prefixsets))
4178 == NULL((void*)0)) {
4179 yyerror("prefix-set '%s' not defined", yyvsp[-1].v.string);
4180 free(yyvsp[-1].v.string);
4181 filterset_free(yyvsp[0].v.filter_set_head);
4182 free(yyvsp[0].v.filter_set_head);
4183 YYERRORgoto yyerrlab;
4184 }
4185 if (ps->sflags & PREFIXSET_FLAG_OPS0x04) {
4186 yyerror("prefix-set %s has prefixlen operators "
4187 "and cannot be used in network statements.",
4188 ps->name);
4189 free(yyvsp[-1].v.string);
4190 filterset_free(yyvsp[0].v.filter_set_head);
4191 free(yyvsp[0].v.filter_set_head);
4192 YYERRORgoto yyerrlab;
4193 }
4194 if ((n = calloc(1, sizeof(struct network))) == NULL((void*)0))
4195 fatal("new_network");
4196 strlcpy(n->net.psname, ps->name, sizeof(n->net.psname));
4197 filterset_move(yyvsp[0].v.filter_set_head, &n->net.attrset);
4198 n->net.type = NETWORK_PREFIXSET;
4199 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)
;
4200 free(yyvsp[-1].v.string);
4201 free(yyvsp[0].v.filter_set_head);
4202 }
4203break;
4204case 89:
4205#line 994 "/usr/src/usr.sbin/bgpd/parse.y"
4206{
4207 struct network *n;
4208
4209 if ((n = calloc(1, sizeof(struct network))) == NULL((void*)0))
4210 fatal("new_network");
4211 if (afi2aid(yyvsp[-3].v.number, SAFI_UNICAST1, &n->net.prefix.aid) ==
4212 -1) {
4213 yyerror("unknown family");
4214 filterset_free(yyvsp[0].v.filter_set_head);
4215 free(yyvsp[0].v.filter_set_head);
4216 YYERRORgoto yyerrlab;
4217 }
4218 n->net.type = NETWORK_RTLABEL;
4219 n->net.rtlabel = rtlabel_name2id(yyvsp[-1].v.string);
4220 filterset_move(yyvsp[0].v.filter_set_head, &n->net.attrset);
4221 free(yyvsp[0].v.filter_set_head);
4222
4223 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)
;
4224 }
4225break;
4226case 90:
4227#line 1013 "/usr/src/usr.sbin/bgpd/parse.y"
4228{
4229 struct network *n;
4230 if (yyvsp[-1].v.number < RTP_LOCAL1 && yyvsp[-1].v.number > RTP_MAX63) {
4231 yyerror("priority %lld > max %d or < min %d", yyvsp[-1].v.number,
4232 RTP_MAX63, RTP_LOCAL1);
4233 YYERRORgoto yyerrlab;
4234 }
4235
4236 if ((n = calloc(1, sizeof(struct network))) == NULL((void*)0))
4237 fatal("new_network");
4238 if (afi2aid(yyvsp[-3].v.number, SAFI_UNICAST1, &n->net.prefix.aid) ==
4239 -1) {
4240 yyerror("unknown family");
4241 filterset_free(yyvsp[0].v.filter_set_head);
4242 free(yyvsp[0].v.filter_set_head);
4243 YYERRORgoto yyerrlab;
4244 }
4245 n->net.type = NETWORK_PRIORITY;
4246 n->net.priority = yyvsp[-1].v.number;
4247 filterset_move(yyvsp[0].v.filter_set_head, &n->net.attrset);
4248 free(yyvsp[0].v.filter_set_head);
4249
4250 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)
;
4251 }
4252break;
4253case 91:
4254#line 1037 "/usr/src/usr.sbin/bgpd/parse.y"
4255{
4256 struct network *n;
4257
4258 if ((n = calloc(1, sizeof(struct network))) == NULL((void*)0))
4259 fatal("new_network");
4260 if (afi2aid(yyvsp[-2].v.number, SAFI_UNICAST1, &n->net.prefix.aid) ==
4261 -1) {
4262 yyerror("unknown family");
4263 filterset_free(yyvsp[0].v.filter_set_head);
4264 free(yyvsp[0].v.filter_set_head);
4265 YYERRORgoto yyerrlab;
4266 }
4267 n->net.type = yyvsp[-1].v.number ? NETWORK_STATIC : NETWORK_CONNECTED;
4268 filterset_move(yyvsp[0].v.filter_set_head, &n->net.attrset);
4269 free(yyvsp[0].v.filter_set_head);
4270
4271 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)
;
4272 }
4273break;
4274case 92:
4275#line 1057 "/usr/src/usr.sbin/bgpd/parse.y"
4276{ yyval.v.number = 1; }
4277break;
4278case 93:
4279#line 1058 "/usr/src/usr.sbin/bgpd/parse.y"
4280{ yyval.v.number = 0; }
4281break;
4282case 94:
4283#line 1061 "/usr/src/usr.sbin/bgpd/parse.y"
4284{ yyval.v.number = 1; }
4285break;
4286case 95:
4287#line 1062 "/usr/src/usr.sbin/bgpd/parse.y"
4288{ yyval.v.number = 0; }
4289break;
4290case 96:
4291#line 1065 "/usr/src/usr.sbin/bgpd/parse.y"
4292{
4293 u_int8_t len;
4294
4295 if (!host(yyvsp[0].v.string, &yyval.v.addr, &len)) {
4296 yyerror("could not parse address spec \"%s\"",
4297 yyvsp[0].v.string);
4298 free(yyvsp[0].v.string);
4299 YYERRORgoto yyerrlab;
4300 }
4301 free(yyvsp[0].v.string);
4302
4303 if ((yyval.v.addr.aid == AID_INET1 && len != 32) ||
4304 (yyval.v.addr.aid == AID_INET62 && len != 128)) {
4305 /* unreachable */
4306 yyerror("got prefixlen %u, expected %u",
4307 len, yyval.v.addr.aid == AID_INET1 ? 32 : 128);
4308 YYERRORgoto yyerrlab;
4309 }
4310 }
4311break;
4312case 97:
4313#line 1086 "/usr/src/usr.sbin/bgpd/parse.y"
4314{
4315 char *s;
4316 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > 128) {
4317 yyerror("bad prefixlen %lld", yyvsp[0].v.number);
4318 free(yyvsp[-2].v.string);
4319 YYERRORgoto yyerrlab;
4320 }
4321 if (asprintf(&s, "%s/%lld", yyvsp[-2].v.string, yyvsp[0].v.number) == -1)
4322 fatal(NULL((void*)0));
4323 free(yyvsp[-2].v.string);
4324
4325 if (!host(s, &yyval.v.prefix.prefix, &yyval.v.prefix.len)) {
4326 yyerror("could not parse address \"%s\"", s);
4327 free(s);
4328 YYERRORgoto yyerrlab;
4329 }
4330 free(s);
4331 }
4332break;
4333case 98:
4334#line 1104 "/usr/src/usr.sbin/bgpd/parse.y"
4335{
4336 char *s;
4337
4338 /* does not match IPv6 */
4339 if (yyvsp[-2].v.number < 0 || yyvsp[-2].v.number > 255 || yyvsp[0].v.number < 0 || yyvsp[0].v.number > 32) {
4340 yyerror("bad prefix %lld/%lld", yyvsp[-2].v.number, yyvsp[0].v.number);
4341 YYERRORgoto yyerrlab;
4342 }
4343 if (asprintf(&s, "%lld/%lld", yyvsp[-2].v.number, yyvsp[0].v.number) == -1)
4344 fatal(NULL((void*)0));
4345
4346 if (!host(s, &yyval.v.prefix.prefix, &yyval.v.prefix.len)) {
4347 yyerror("could not parse address \"%s\"", s);
4348 free(s);
4349 YYERRORgoto yyerrlab;
4350 }
4351 free(s);
4352 }
4353break;
4354case 99:
4355#line 1124 "/usr/src/usr.sbin/bgpd/parse.y"
4356{
4357 memcpy(&yyval.v.prefix.prefix, &yyvsp[0].v.addr, sizeof(struct bgpd_addr));
4358 if (yyval.v.prefix.prefix.aid == AID_INET1)
4359 yyval.v.prefix.len = 32;
4360 else
4361 yyval.v.prefix.len = 128;
4362 }
4363break;
4364case 101:
4365#line 1134 "/usr/src/usr.sbin/bgpd/parse.y"
4366{ yyval.v.number = 0; }
4367break;
4368case 103:
4369#line 1138 "/usr/src/usr.sbin/bgpd/parse.y"
4370{
4371 u_int rdomain, label;
4372
4373 if (get_mpe_config(yyvsp[0].v.string, &rdomain, &label) == -1) {
4374 if ((cmd_opts & BGPD_OPT_NOACTION0x0004) == 0) {
4375 yyerror("troubles getting config of %s",
4376 yyvsp[0].v.string);
4377 free(yyvsp[0].v.string);
4378 free(yyvsp[-2].v.string);
4379 YYERRORgoto yyerrlab;
4380 }
4381 }
4382
4383 if (!(curvpn = calloc(1, sizeof(struct l3vpn))))
4384 fatal(NULL((void*)0));
4385 strlcpy(curvpn->ifmpe, yyvsp[0].v.string, IFNAMSIZ16);
4386
4387 if (strlcpy(curvpn->descr, yyvsp[-2].v.string,
4388 sizeof(curvpn->descr)) >=
4389 sizeof(curvpn->descr)) {
4390 yyerror("descr \"%s\" too long: max %zu",
4391 yyvsp[-2].v.string, sizeof(curvpn->descr) - 1);
4392 free(yyvsp[-2].v.string);
4393 free(yyvsp[0].v.string);
4394 free(curvpn);
4395 curvpn = NULL((void*)0);
4396 YYERRORgoto yyerrlab;
4397 }
4398 free(yyvsp[-2].v.string);
4399 free(yyvsp[0].v.string);
4400
4401 TAILQ_INIT(&curvpn->import)do { (&curvpn->import)->tqh_first = ((void*)0); (&
curvpn->import)->tqh_last = &(&curvpn->import
)->tqh_first; } while (0)
;
4402 TAILQ_INIT(&curvpn->export)do { (&curvpn->export)->tqh_first = ((void*)0); (&
curvpn->export)->tqh_last = &(&curvpn->export
)->tqh_first; } while (0)
;
4403 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)
;
4404 curvpn->label = label;
4405 curvpn->rtableid = rdomain;
4406 netconf = &curvpn->net_l;
4407 }
4408break;
4409case 104:
4410#line 1175 "/usr/src/usr.sbin/bgpd/parse.y"
4411{
4412 /* insert into list */
4413 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)
;
4414 curvpn = NULL((void*)0);
4415 netconf = &conf->networks;
4416 }
4417break;
4418case 109:
4419#line 1189 "/usr/src/usr.sbin/bgpd/parse.y"
4420{
4421 struct community ext;
4422
4423 memset(&ext, 0, sizeof(ext));
4424 if (parseextcommunity(&ext, "rt", yyvsp[0].v.string) == -1) {
4425 free(yyvsp[0].v.string);
4426 YYERRORgoto yyerrlab;
4427 }
4428 free(yyvsp[0].v.string);
4429 /*
4430 * RD is almost encoded like an ext-community,
4431 * but only almost so convert here.
4432 */
4433 if (community_to_rd(&ext, &curvpn->rd) == -1) {
4434 yyerror("bad encoding of rd");
4435 YYERRORgoto yyerrlab;
4436 }
4437 }
4438break;
4439case 110:
4440#line 1207 "/usr/src/usr.sbin/bgpd/parse.y"
4441{
4442 struct filter_set *set;
4443
4444 if ((set = calloc(1, sizeof(struct filter_set))) ==
4445 NULL((void*)0))
4446 fatal(NULL((void*)0));
4447 set->type = ACTION_SET_COMMUNITY;
4448 if (parseextcommunity(&set->action.community,
4449 yyvsp[-1].v.string, yyvsp[0].v.string) == -1) {
4450 free(yyvsp[0].v.string);
4451 free(yyvsp[-1].v.string);
4452 free(set);
4453 YYERRORgoto yyerrlab;
4454 }
4455 free(yyvsp[0].v.string);
4456 free(yyvsp[-1].v.string);
4457 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)
;
4458 }
4459break;
4460case 111:
4461#line 1225 "/usr/src/usr.sbin/bgpd/parse.y"
4462{
4463 struct filter_set *set;
4464
4465 if ((set = calloc(1, sizeof(struct filter_set))) ==
4466 NULL((void*)0))
4467 fatal(NULL((void*)0));
4468 set->type = ACTION_SET_COMMUNITY;
4469 if (parseextcommunity(&set->action.community,
4470 yyvsp[-1].v.string, yyvsp[0].v.string) == -1) {
4471 free(yyvsp[0].v.string);
4472 free(yyvsp[-1].v.string);
4473 free(set);
4474 YYERRORgoto yyerrlab;
4475 }
4476 free(yyvsp[0].v.string);
4477 free(yyvsp[-1].v.string);
4478 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)
;
4479 }
4480break;
4481case 112:
4482#line 1243 "/usr/src/usr.sbin/bgpd/parse.y"
4483{
4484 if (yyvsp[0].v.number == 0)
4485 curvpn->flags |= F_RIB_NOFIBSYNC0x0008;
4486 else
4487 curvpn->flags &= ~F_RIB_NOFIBSYNC0x0008;
4488 }
4489break;
4490case 114:
4491#line 1252 "/usr/src/usr.sbin/bgpd/parse.y"
4492{ curpeer = new_peer(); }
4493break;
4494case 115:
4495#line 1253 "/usr/src/usr.sbin/bgpd/parse.y"
4496{
4497 memcpy(&curpeer->conf.remote_addr, &yyvsp[0].v.prefix.prefix,
4498 sizeof(curpeer->conf.remote_addr));
4499 curpeer->conf.remote_masklen = yyvsp[0].v.prefix.len;
4500 if ((yyvsp[0].v.prefix.prefix.aid == AID_INET1 && yyvsp[0].v.prefix.len != 32) ||
4501 (yyvsp[0].v.prefix.prefix.aid == AID_INET62 && yyvsp[0].v.prefix.len != 128))
4502 curpeer->conf.template = 1;
4503 curpeer->conf.capabilities.mp[
4504 curpeer->conf.remote_addr.aid] = 1;
4505 if (get_id(curpeer)) {
4506 yyerror("get_id failed");
4507 YYERRORgoto yyerrlab;
4508 }
4509 }
4510break;
4511case 116:
4512#line 1267 "/usr/src/usr.sbin/bgpd/parse.y"
4513{
4514 if (curpeer_filter[0] != NULL((void*)0))
4515 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)
4516 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)
;
4517 if (curpeer_filter[1] != NULL((void*)0))
4518 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)
4519 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)
;
4520 curpeer_filter[0] = NULL((void*)0);
4521 curpeer_filter[1] = NULL((void*)0);
4522
4523 if (neighbor_consistent(curpeer) == -1) {
4524 free(curpeer);
4525 YYERRORgoto yyerrlab;
4526 }
4527 if (RB_INSERT(peer_head, new_peers, curpeer)peer_head_RB_INSERT(new_peers, curpeer) != NULL((void*)0))
4528 fatalx("%s: peer tree is corrupt", __func__);
4529 curpeer = curgroup;
4530 }
4531break;
4532case 117:
4533#line 1287 "/usr/src/usr.sbin/bgpd/parse.y"
4534{
4535 curgroup = curpeer = new_group();
4536 if (strlcpy(curgroup->conf.group, yyvsp[0].v.string,
4537 sizeof(curgroup->conf.group)) >=
4538 sizeof(curgroup->conf.group)) {
4539 yyerror("group name \"%s\" too long: max %zu",
4540 yyvsp[0].v.string, sizeof(curgroup->conf.group) - 1);
4541 free(yyvsp[0].v.string);
4542 free(curgroup);
4543 YYERRORgoto yyerrlab;
4544 }
4545 free(yyvsp[0].v.string);
4546 if (get_id(curgroup)) {
4547 yyerror("get_id failed");
4548 free(curgroup);
4549 YYERRORgoto yyerrlab;
4550 }
4551 }
4552break;
4553case 118:
4554#line 1304 "/usr/src/usr.sbin/bgpd/parse.y"
4555{
4556 if (curgroup_filter[0] != NULL((void*)0))
4557 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)
4558 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)
;
4559 if (curgroup_filter[1] != NULL((void*)0))
4560 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)
4561 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)
;
4562 curgroup_filter[0] = NULL((void*)0);
4563 curgroup_filter[1] = NULL((void*)0);
4564
4565 free(curgroup);
4566 curgroup = NULL((void*)0);
4567 }
4568break;
4569case 131:
4570#line 1337 "/usr/src/usr.sbin/bgpd/parse.y"
4571{
4572 curpeer->conf.remote_as = yyvsp[0].v.number;
4573 }
4574break;
4575case 132:
4576#line 1340 "/usr/src/usr.sbin/bgpd/parse.y"
4577{
4578 curpeer->conf.local_as = yyvsp[0].v.number;
4579 if (yyvsp[0].v.number > USHRT_MAX(32767 *2 +1))
4580 curpeer->conf.local_short_as = AS_TRANS23456;
4581 else
4582 curpeer->conf.local_short_as = yyvsp[0].v.number;
4583 }
4584break;
4585case 133:
4586#line 1347 "/usr/src/usr.sbin/bgpd/parse.y"
4587{
4588 curpeer->conf.local_as = yyvsp[-1].v.number;
4589 curpeer->conf.local_short_as = yyvsp[0].v.number;
4590 }
4591break;
4592case 134:
4593#line 1351 "/usr/src/usr.sbin/bgpd/parse.y"
4594{
4595 if (strlcpy(curpeer->conf.descr, yyvsp[0].v.string,
4596 sizeof(curpeer->conf.descr)) >=
4597 sizeof(curpeer->conf.descr)) {
4598 yyerror("descr \"%s\" too long: max %zu",
4599 yyvsp[0].v.string, sizeof(curpeer->conf.descr) - 1);
4600 free(yyvsp[0].v.string);
4601 YYERRORgoto yyerrlab;
4602 }
4603 free(yyvsp[0].v.string);
4604 }
4605break;
4606case 135:
4607#line 1362 "/usr/src/usr.sbin/bgpd/parse.y"
4608{
4609 if (yyvsp[0].v.addr.aid == AID_INET1)
4610 memcpy(&curpeer->conf.local_addr_v4, &yyvsp[0].v.addr,
4611 sizeof(curpeer->conf.local_addr_v4));
4612 else if (yyvsp[0].v.addr.aid == AID_INET62)
4613 memcpy(&curpeer->conf.local_addr_v6, &yyvsp[0].v.addr,
4614 sizeof(curpeer->conf.local_addr_v6));
4615 else {
4616 yyerror("Unsupported address family %s for "
4617 "local-addr", aid2str(yyvsp[0].v.addr.aid));
4618 YYERRORgoto yyerrlab;
4619 }
4620 }
4621break;
4622case 136:
4623#line 1375 "/usr/src/usr.sbin/bgpd/parse.y"
4624{
4625 if (yyvsp[-1].v.number) {
4626 yyerror("bad local-address definition");
4627 YYERRORgoto yyerrlab;
4628 }
4629 memset(&curpeer->conf.local_addr_v4, 0,
4630 sizeof(curpeer->conf.local_addr_v4));
4631 memset(&curpeer->conf.local_addr_v6, 0,
4632 sizeof(curpeer->conf.local_addr_v6));
4633 }
4634break;
4635case 137:
4636#line 1385 "/usr/src/usr.sbin/bgpd/parse.y"
4637{
4638 if (yyvsp[0].v.number < 2 || yyvsp[0].v.number > 255) {
4639 yyerror("invalid multihop distance %lld", yyvsp[0].v.number);
4640 YYERRORgoto yyerrlab;
4641 }
4642 curpeer->conf.distance = yyvsp[0].v.number;
4643 }
4644break;
4645case 138:
4646#line 1392 "/usr/src/usr.sbin/bgpd/parse.y"
4647{
4648 curpeer->conf.passive = 1;
4649 }
4650break;
4651case 139:
4652#line 1395 "/usr/src/usr.sbin/bgpd/parse.y"
4653{
4654 curpeer->conf.down = 1;
4655 }
4656break;
4657case 140:
4658#line 1398 "/usr/src/usr.sbin/bgpd/parse.y"
4659{
4660 curpeer->conf.down = 1;
4661 if (strlcpy(curpeer->conf.reason, yyvsp[0].v.string,
4662 sizeof(curpeer->conf.reason)) >=
4663 sizeof(curpeer->conf.reason)) {
4664 yyerror("shutdown reason too long");
4665 free(yyvsp[0].v.string);
4666 YYERRORgoto yyerrlab;
4667 }
4668 free(yyvsp[0].v.string);
4669 }
4670break;
4671case 141:
4672#line 1409 "/usr/src/usr.sbin/bgpd/parse.y"
4673{
4674 if (!find_rib(yyvsp[0].v.string)) {
4675 yyerror("rib \"%s\" does not exist.", yyvsp[0].v.string);
4676 free(yyvsp[0].v.string);
4677 YYERRORgoto yyerrlab;
4678 }
4679 if (strlcpy(curpeer->conf.rib, yyvsp[0].v.string,
4680 sizeof(curpeer->conf.rib)) >=
4681 sizeof(curpeer->conf.rib)) {
4682 yyerror("rib name \"%s\" too long: max %zu",
4683 yyvsp[0].v.string, sizeof(curpeer->conf.rib) - 1);
4684 free(yyvsp[0].v.string);
4685 YYERRORgoto yyerrlab;
4686 }
4687 free(yyvsp[0].v.string);
4688 }
4689break;
4690case 142:
4691#line 1425 "/usr/src/usr.sbin/bgpd/parse.y"
4692{
4693 if (yyvsp[0].v.number < MIN_HOLDTIME3 || yyvsp[0].v.number > USHRT_MAX(32767 *2 +1)) {
4694 yyerror("holdtime must be between %u and %u",
4695 MIN_HOLDTIME3, USHRT_MAX(32767 *2 +1));
4696 YYERRORgoto yyerrlab;
4697 }
4698 curpeer->conf.holdtime = yyvsp[0].v.number;
4699 }
4700break;
4701case 143:
4702#line 1433 "/usr/src/usr.sbin/bgpd/parse.y"
4703{
4704 if (yyvsp[0].v.number < MIN_HOLDTIME3 || yyvsp[0].v.number > USHRT_MAX(32767 *2 +1)) {
4705 yyerror("holdtime must be between %u and %u",
4706 MIN_HOLDTIME3, USHRT_MAX(32767 *2 +1));
4707 YYERRORgoto yyerrlab;
4708 }
4709 curpeer->conf.min_holdtime = yyvsp[0].v.number;
4710 }
4711break;
4712case 144:
4713#line 1441 "/usr/src/usr.sbin/bgpd/parse.y"
4714{
4715 u_int8_t aid, safi;
4716 u_int16_t afi;
4717
4718 if (yyvsp[0].v.number == SAFI_NONE0) {
4719 for (aid = 0; aid < AID_MAX5; aid++) {
4720 if (aid2afi(aid, &afi, &safi) == -1 ||
4721 afi != yyvsp[-1].v.number)
4722 continue;
4723 curpeer->conf.capabilities.mp[aid] = 0;
4724 }
4725 } else {
4726 if (afi2aid(yyvsp[-1].v.number, yyvsp[0].v.number, &aid) == -1) {
4727 yyerror("unknown AFI/SAFI pair");
4728 YYERRORgoto yyerrlab;
4729 }
4730 curpeer->conf.capabilities.mp[aid] = 1;
4731 }
4732 }
4733break;
4734case 145:
4735#line 1460 "/usr/src/usr.sbin/bgpd/parse.y"
4736{
4737 curpeer->conf.announce_capa = yyvsp[0].v.number;
4738 }
4739break;
4740case 146:
4741#line 1463 "/usr/src/usr.sbin/bgpd/parse.y"
4742{
4743 curpeer->conf.capabilities.refresh = yyvsp[0].v.number;
4744 }
4745break;
4746case 147:
4747#line 1466 "/usr/src/usr.sbin/bgpd/parse.y"
4748{
4749 curpeer->conf.capabilities.enhanced_rr = yyvsp[0].v.number;
4750 }
4751break;
4752case 148:
4753#line 1469 "/usr/src/usr.sbin/bgpd/parse.y"
4754{
4755 curpeer->conf.capabilities.grestart.restart = yyvsp[0].v.number;
4756 }
4757break;
4758case 149:
4759#line 1472 "/usr/src/usr.sbin/bgpd/parse.y"
4760{
4761 curpeer->conf.capabilities.as4byte = yyvsp[0].v.number;
4762 }
4763break;
4764case 150:
4765#line 1475 "/usr/src/usr.sbin/bgpd/parse.y"
4766{
4767 int8_t *ap = curpeer->conf.capabilities.add_path;
4768 u_int8_t i;
4769
4770 for (i = 0; i < AID_MAX5; i++)
4771 if (yyvsp[0].v.number)
4772 *ap++ |= CAPA_AP_RECV0x01;
4773 else
4774 *ap++ &= ~CAPA_AP_RECV0x01;
4775 }
4776break;
4777case 151:
4778#line 1485 "/usr/src/usr.sbin/bgpd/parse.y"
4779{
4780 curpeer->conf.export_type = EXPORT_NONE;
4781 }
4782break;
4783case 152:
4784#line 1488 "/usr/src/usr.sbin/bgpd/parse.y"
4785{
4786 curpeer->conf.export_type = EXPORT_DEFAULT_ROUTE;
4787 }
4788break;
4789case 153:
4790#line 1491 "/usr/src/usr.sbin/bgpd/parse.y"
4791{
4792 if (yyvsp[0].v.number)
4793 curpeer->conf.enforce_as = ENFORCE_AS_ON;
4794 else
4795 curpeer->conf.enforce_as = ENFORCE_AS_OFF;
4796 }
4797break;
4798case 154:
4799#line 1497 "/usr/src/usr.sbin/bgpd/parse.y"
4800{
4801 if (yyvsp[0].v.number)
4802 curpeer->conf.enforce_local_as = ENFORCE_AS_ON;
4803 else
4804 curpeer->conf.enforce_local_as = ENFORCE_AS_OFF;
4805 }
4806break;
4807case 155:
4808#line 1503 "/usr/src/usr.sbin/bgpd/parse.y"
4809{
4810 if (yyvsp[0].v.number) {
4811 struct filter_rule *r;
4812 struct filter_set *s;
4813
4814 if ((s = calloc(1, sizeof(struct filter_set)))
4815 == NULL((void*)0))
4816 fatal(NULL((void*)0));
4817 s->type = ACTION_SET_AS_OVERRIDE;
4818
4819 r = get_rule(s->type);
4820 if (merge_filterset(&r->set, s) == -1)
4821 YYERRORgoto yyerrlab;
4822 }
4823 }
4824break;
4825case 156:
4826#line 1518 "/usr/src/usr.sbin/bgpd/parse.y"
4827{
4828 if (yyvsp[-1].v.number < 0 || yyvsp[-1].v.number > UINT_MAX(2147483647 *2U +1U)) {
4829 yyerror("bad maximum number of prefixes");
4830 YYERRORgoto yyerrlab;
4831 }
4832 curpeer->conf.max_prefix = yyvsp[-1].v.number;
4833 curpeer->conf.max_prefix_restart = yyvsp[0].v.number;
4834 }
4835break;
4836case 157:
4837#line 1526 "/usr/src/usr.sbin/bgpd/parse.y"
4838{
4839 if (yyvsp[-2].v.number < 0 || yyvsp[-2].v.number > UINT_MAX(2147483647 *2U +1U)) {
4840 yyerror("bad maximum number of prefixes");
4841 YYERRORgoto yyerrlab;
4842 }
4843 curpeer->conf.max_out_prefix = yyvsp[-2].v.number;
4844 curpeer->conf.max_out_prefix_restart = yyvsp[0].v.number;
4845 }
4846break;
4847case 158:
4848#line 1534 "/usr/src/usr.sbin/bgpd/parse.y"
4849{
4850 if (curpeer->conf.auth.method) {
4851 yyerror("auth method cannot be redefined");
4852 free(yyvsp[0].v.string);
4853 YYERRORgoto yyerrlab;
4854 }
4855 if (strlcpy(curpeer->conf.auth.md5key, yyvsp[0].v.string,
4856 sizeof(curpeer->conf.auth.md5key)) >=
4857 sizeof(curpeer->conf.auth.md5key)) {
4858 yyerror("tcp md5sig password too long: max %zu",
4859 sizeof(curpeer->conf.auth.md5key) - 1);
4860 free(yyvsp[0].v.string);
4861 YYERRORgoto yyerrlab;
4862 }
4863 curpeer->conf.auth.method = AUTH_MD5SIG;
4864 curpeer->conf.auth.md5key_len = strlen(yyvsp[0].v.string);
4865 free(yyvsp[0].v.string);
4866 }
4867break;
4868case 159:
4869#line 1552 "/usr/src/usr.sbin/bgpd/parse.y"
4870{
4871 if (curpeer->conf.auth.method) {
4872 yyerror("auth method cannot be redefined");
4873 free(yyvsp[0].v.string);
4874 YYERRORgoto yyerrlab;
4875 }
4876
4877 if (str2key(yyvsp[0].v.string, curpeer->conf.auth.md5key,
4878 sizeof(curpeer->conf.auth.md5key)) == -1) {
4879 free(yyvsp[0].v.string);
4880 YYERRORgoto yyerrlab;
4881 }
4882 curpeer->conf.auth.method = AUTH_MD5SIG;
4883 curpeer->conf.auth.md5key_len = strlen(yyvsp[0].v.string) / 2;
4884 free(yyvsp[0].v.string);
4885 }
4886break;
4887case 160:
4888#line 1568 "/usr/src/usr.sbin/bgpd/parse.y"
4889{
4890 if (curpeer->conf.auth.method) {
4891 yyerror("auth method cannot be redefined");
4892 YYERRORgoto yyerrlab;
4893 }
4894 if (yyvsp[-1].v.number)
4895 curpeer->conf.auth.method = AUTH_IPSEC_IKE_ESP;
4896 else
4897 curpeer->conf.auth.method = AUTH_IPSEC_IKE_AH;
4898 }
4899break;
4900case 161:
4901#line 1578 "/usr/src/usr.sbin/bgpd/parse.y"
4902{
4903 u_int32_t auth_alg;
4904 u_int8_t keylen;
4905
4906 if (curpeer->conf.auth.method &&
4907 (((curpeer->conf.auth.spi_in && yyvsp[-5].v.number == 1) ||
4908 (curpeer->conf.auth.spi_out && yyvsp[-5].v.number == 0)) ||
4909 (yyvsp[-6].v.number == 1 && curpeer->conf.auth.method !=
4910 AUTH_IPSEC_MANUAL_ESP) ||
4911 (yyvsp[-6].v.number == 0 && curpeer->conf.auth.method !=
4912 AUTH_IPSEC_MANUAL_AH))) {
4913 yyerror("auth method cannot be redefined");
4914 free(yyvsp[-2].v.string);
4915 free(yyvsp[-1].v.string);
4916 YYERRORgoto yyerrlab;
4917 }
4918
4919 if (!strcmp(yyvsp[-2].v.string, "sha1")) {
4920 auth_alg = SADB_AALG_SHA1HMAC3;
4921 keylen = 20;
4922 } else if (!strcmp(yyvsp[-2].v.string, "md5")) {
4923 auth_alg = SADB_AALG_MD5HMAC2;
4924 keylen = 16;
4925 } else {
4926 yyerror("unknown auth algorithm \"%s\"", yyvsp[-2].v.string);
4927 free(yyvsp[-2].v.string);
4928 free(yyvsp[-1].v.string);
4929 YYERRORgoto yyerrlab;
4930 }
4931 free(yyvsp[-2].v.string);
4932
4933 if (strlen(yyvsp[-1].v.string) / 2 != keylen) {
4934 yyerror("auth key len: must be %u bytes, "
4935 "is %zu bytes", keylen, strlen(yyvsp[-1].v.string) / 2);
4936 free(yyvsp[-1].v.string);
4937 YYERRORgoto yyerrlab;
4938 }
4939
4940 if (yyvsp[-6].v.number)
4941 curpeer->conf.auth.method =
4942 AUTH_IPSEC_MANUAL_ESP;
4943 else {
4944 if (yyvsp[0].v.encspec.enc_alg) {
4945 yyerror("\"ipsec ah\" doesn't take "
4946 "encryption keys");
4947 free(yyvsp[-1].v.string);
4948 YYERRORgoto yyerrlab;
4949 }
4950 curpeer->conf.auth.method =
4951 AUTH_IPSEC_MANUAL_AH;
4952 }
4953
4954 if (yyvsp[-3].v.number <= SPI_RESERVED_MAX255 || yyvsp[-3].v.number > UINT_MAX(2147483647 *2U +1U)) {
4955 yyerror("bad spi number %lld", yyvsp[-3].v.number);
4956 free(yyvsp[-1].v.string);
4957 YYERRORgoto yyerrlab;
4958 }
4959
4960 if (yyvsp[-5].v.number == 1) {
4961 if (str2key(yyvsp[-1].v.string, curpeer->conf.auth.auth_key_in,
4962 sizeof(curpeer->conf.auth.auth_key_in)) ==
4963 -1) {
4964 free(yyvsp[-1].v.string);
4965 YYERRORgoto yyerrlab;
4966 }
4967 curpeer->conf.auth.spi_in = yyvsp[-3].v.number;
4968 curpeer->conf.auth.auth_alg_in = auth_alg;
4969 curpeer->conf.auth.enc_alg_in = yyvsp[0].v.encspec.enc_alg;
4970 memcpy(&curpeer->conf.auth.enc_key_in,
4971 &yyvsp[0].v.encspec.enc_key,
4972 sizeof(curpeer->conf.auth.enc_key_in));
4973 curpeer->conf.auth.enc_keylen_in =
4974 yyvsp[0].v.encspec.enc_key_len;
4975 curpeer->conf.auth.auth_keylen_in = keylen;
4976 } else {
4977 if (str2key(yyvsp[-1].v.string, curpeer->conf.auth.auth_key_out,
4978 sizeof(curpeer->conf.auth.auth_key_out)) ==
4979 -1) {
4980 free(yyvsp[-1].v.string);
4981 YYERRORgoto yyerrlab;
4982 }
4983 curpeer->conf.auth.spi_out = yyvsp[-3].v.number;
4984 curpeer->conf.auth.auth_alg_out = auth_alg;
4985 curpeer->conf.auth.enc_alg_out = yyvsp[0].v.encspec.enc_alg;
4986 memcpy(&curpeer->conf.auth.enc_key_out,
4987 &yyvsp[0].v.encspec.enc_key,
4988 sizeof(curpeer->conf.auth.enc_key_out));
4989 curpeer->conf.auth.enc_keylen_out =
4990 yyvsp[0].v.encspec.enc_key_len;
4991 curpeer->conf.auth.auth_keylen_out = keylen;
4992 }
4993 free(yyvsp[-1].v.string);
4994 }
4995break;
4996case 162:
4997#line 1671 "/usr/src/usr.sbin/bgpd/parse.y"
4998{
4999 curpeer->conf.ttlsec = yyvsp[0].v.number;
5000 }
5001break;
5002case 163:
5003#line 1674 "/usr/src/usr.sbin/bgpd/parse.y"
5004{
5005 struct filter_rule *r;
5006
5007 r = get_rule(yyvsp[0].v.filter_set->type);
5008 if (merge_filterset(&r->set, yyvsp[0].v.filter_set) == -1)
5009 YYERRORgoto yyerrlab;
5010 }
5011break;
5012case 164:
5013#line 1681 "/usr/src/usr.sbin/bgpd/parse.y"
5014{
5015 struct filter_rule *r;
5016 struct filter_set *s;
5017
5018 while ((s = TAILQ_FIRST(yyvsp[-2].v.filter_set_head)((yyvsp[-2].v.filter_set_head)->tqh_first)) != NULL((void*)0)) {
5019 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)
;
5020 r = get_rule(s->type);
5021 if (merge_filterset(&r->set, s) == -1)
5022 YYERRORgoto yyerrlab;
5023 }
5024 free(yyvsp[-2].v.filter_set_head);
5025 }
5026break;
5027case 166:
5028#line 1694 "/usr/src/usr.sbin/bgpd/parse.y"
5029{
5030 if ((conf->flags & BGPD_FLAG_REFLECTOR0x0004) &&
5031 conf->clusterid != 0) {
5032 yyerror("only one route reflector "
5033 "cluster allowed");
5034 YYERRORgoto yyerrlab;
5035 }
5036 conf->flags |= BGPD_FLAG_REFLECTOR0x0004;
5037 curpeer->conf.reflector_client = 1;
5038 }
5039break;
5040case 167:
5041#line 1704 "/usr/src/usr.sbin/bgpd/parse.y"
5042{
5043 if (yyvsp[0].v.addr.aid != AID_INET1) {
5044 yyerror("route reflector cluster-id must be "
5045 "an IPv4 address");
5046 YYERRORgoto yyerrlab;
5047 }
5048 if ((conf->flags & BGPD_FLAG_REFLECTOR0x0004) &&
5049 conf->clusterid != yyvsp[0].v.addr.v4ba.v4.s_addr) {
5050 yyerror("only one route reflector "
5051 "cluster allowed");
5052 YYERRORgoto yyerrlab;
5053 }
5054 conf->flags |= BGPD_FLAG_REFLECTOR0x0004;
5055 curpeer->conf.reflector_client = 1;
5056 conf->clusterid = yyvsp[0].v.addr.v4ba.v4.s_addr;
5057 }
5058break;
5059case 168:
5060#line 1720 "/usr/src/usr.sbin/bgpd/parse.y"
5061{
5062 if (strlcpy(curpeer->conf.if_depend, yyvsp[0].v.string,
5063 sizeof(curpeer->conf.if_depend)) >=
5064 sizeof(curpeer->conf.if_depend)) {
5065 yyerror("interface name \"%s\" too long: "
5066 "max %zu", yyvsp[0].v.string,
5067 sizeof(curpeer->conf.if_depend) - 1);
5068 free(yyvsp[0].v.string);
5069 YYERRORgoto yyerrlab;
5070 }
5071 free(yyvsp[0].v.string);
5072 }
5073break;
5074case 169:
5075#line 1732 "/usr/src/usr.sbin/bgpd/parse.y"
5076{
5077 if (strlcpy(curpeer->conf.demote_group, yyvsp[0].v.string,
5078 sizeof(curpeer->conf.demote_group)) >=
5079 sizeof(curpeer->conf.demote_group)) {
5080 yyerror("demote group name \"%s\" too long: "
5081 "max %zu", yyvsp[0].v.string,
5082 sizeof(curpeer->conf.demote_group) - 1);
5083 free(yyvsp[0].v.string);
5084 YYERRORgoto yyerrlab;
5085 }
5086 free(yyvsp[0].v.string);
5087 if (carp_demote_init(curpeer->conf.demote_group,
5088 cmd_opts & BGPD_OPT_FORCE_DEMOTE0x0008) == -1) {
5089 yyerror("error initializing group \"%s\"",
5090 curpeer->conf.demote_group);
5091 YYERRORgoto yyerrlab;
5092 }
5093 }
5094break;
5095case 170:
5096#line 1750 "/usr/src/usr.sbin/bgpd/parse.y"
5097{
5098 if (yyvsp[0].v.number == 1)
5099 curpeer->conf.flags |= PEERFLAG_TRANS_AS0x01;
5100 else
5101 curpeer->conf.flags &= ~PEERFLAG_TRANS_AS0x01;
5102 }
5103break;
5104case 171:
5105#line 1756 "/usr/src/usr.sbin/bgpd/parse.y"
5106{
5107 if (!strcmp(yyvsp[0].v.string, "updates"))
5108 curpeer->conf.flags |= PEERFLAG_LOG_UPDATES0x02;
5109 else if (!strcmp(yyvsp[0].v.string, "no"))
5110 curpeer->conf.flags &= ~PEERFLAG_LOG_UPDATES0x02;
5111 else {
5112 free(yyvsp[0].v.string);
5113 YYERRORgoto yyerrlab;
5114 }
5115 free(yyvsp[0].v.string);
5116 }
5117break;
5118case 172:
5119#line 1767 "/usr/src/usr.sbin/bgpd/parse.y"
5120{
5121 if (yyvsp[0].v.number == 1)
5122 curpeer->conf.flags |= PEERFLAG_NO_AS_SET0x08;
5123 else
5124 curpeer->conf.flags &= ~PEERFLAG_NO_AS_SET0x08;
5125 }
5126break;
5127case 173:
5128#line 1773 "/usr/src/usr.sbin/bgpd/parse.y"
5129{
5130 if (!strcmp(yyvsp[0].v.string, "all"))
5131 curpeer->conf.flags |= PEERFLAG_EVALUATE_ALL0x04;
5132 else if (!strcmp(yyvsp[0].v.string, "default"))
5133 curpeer->conf.flags &= ~PEERFLAG_EVALUATE_ALL0x04;
5134 else {
5135 yyerror("rde evaluate: "
5136 "unknown setting \"%s\"", yyvsp[0].v.string);
5137 free(yyvsp[0].v.string);
5138 YYERRORgoto yyerrlab;
5139 }
5140 free(yyvsp[0].v.string);
5141 }
5142break;
5143case 174:
5144#line 1788 "/usr/src/usr.sbin/bgpd/parse.y"
5145{ yyval.v.number = 0; }
5146break;
5147case 175:
5148#line 1789 "/usr/src/usr.sbin/bgpd/parse.y"
5149{
5150 if (yyvsp[0].v.number < 1 || yyvsp[0].v.number > USHRT_MAX(32767 *2 +1)) {
5151 yyerror("restart out of range. 1 to %u minutes",
5152 USHRT_MAX(32767 *2 +1));
5153 YYERRORgoto yyerrlab;
5154 }
5155 yyval.v.number = yyvsp[0].v.number;
5156 }
5157break;
5158case 176:
5159#line 1799 "/usr/src/usr.sbin/bgpd/parse.y"
5160{ yyval.v.number = AFI_IPv41; }
5161break;
5162case 177:
5163#line 1800 "/usr/src/usr.sbin/bgpd/parse.y"
5164{ yyval.v.number = AFI_IPv62; }
5165break;
5166case 178:
5167#line 1803 "/usr/src/usr.sbin/bgpd/parse.y"
5168{ yyval.v.number = SAFI_NONE0; }
5169break;
5170case 179:
5171#line 1804 "/usr/src/usr.sbin/bgpd/parse.y"
5172{ yyval.v.number = SAFI_UNICAST1; }
5173break;
5174case 180:
5175#line 1805 "/usr/src/usr.sbin/bgpd/parse.y"
5176{ yyval.v.number = SAFI_MPLSVPN128; }
5177break;
5178case 181:
5179#line 1808 "/usr/src/usr.sbin/bgpd/parse.y"
5180{ yyval.v.number = 1; }
5181break;
5182case 182:
5183#line 1809 "/usr/src/usr.sbin/bgpd/parse.y"
5184{ yyval.v.number = 0; }
5185break;
5186case 183:
5187#line 1812 "/usr/src/usr.sbin/bgpd/parse.y"
5188{ yyval.v.number = 1; }
5189break;
5190case 184:
5191#line 1813 "/usr/src/usr.sbin/bgpd/parse.y"
5192{ yyval.v.number = 0; }
5193break;
5194case 185:
5195#line 1816 "/usr/src/usr.sbin/bgpd/parse.y"
5196{
5197 bzero(&yyval.v.encspec, sizeof(yyval.v.encspec));
5198 }
5199break;
5200case 186:
5201#line 1819 "/usr/src/usr.sbin/bgpd/parse.y"
5202{
5203 bzero(&yyval.v.encspec, sizeof(yyval.v.encspec));
5204 if (!strcmp(yyvsp[-1].v.string, "3des") || !strcmp(yyvsp[-1].v.string, "3des-cbc")) {
5205 yyval.v.encspec.enc_alg = SADB_EALG_3DESCBC3;
5206 yyval.v.encspec.enc_key_len = 21; /* XXX verify */
5207 } else if (!strcmp(yyvsp[-1].v.string, "aes") ||
5208 !strcmp(yyvsp[-1].v.string, "aes-128-cbc")) {
5209 yyval.v.encspec.enc_alg = SADB_X_EALG_AES12;
5210 yyval.v.encspec.enc_key_len = 16;
5211 } else {
5212 yyerror("unknown enc algorithm \"%s\"", yyvsp[-1].v.string);
5213 free(yyvsp[-1].v.string);
5214 free(yyvsp[0].v.string);
5215 YYERRORgoto yyerrlab;
5216 }
5217 free(yyvsp[-1].v.string);
5218
5219 if (strlen(yyvsp[0].v.string) / 2 != yyval.v.encspec.enc_key_len) {
5220 yyerror("enc key length wrong: should be %u "
5221 "bytes, is %zu bytes",
5222 yyval.v.encspec.enc_key_len * 2, strlen(yyvsp[0].v.string));
5223 free(yyvsp[0].v.string);
5224 YYERRORgoto yyerrlab;
5225 }
5226
5227 if (str2key(yyvsp[0].v.string, yyval.v.encspec.enc_key, sizeof(yyval.v.encspec.enc_key)) == -1) {
5228 free(yyvsp[0].v.string);
5229 YYERRORgoto yyerrlab;
5230 }
5231 free(yyvsp[0].v.string);
5232 }
5233break;
5234case 187:
5235#line 1854 "/usr/src/usr.sbin/bgpd/parse.y"
5236{
5237 struct filter_rule r;
5238 struct filter_rib_l *rb, *rbnext;
5239
5240 bzero(&r, sizeof(r));
5241 r.action = yyvsp[-6].v.u8;
5242 r.quick = yyvsp[-5].v.u8;
5243 r.dir = yyvsp[-3].v.u8;
5244 if (yyvsp[-4].v.filter_rib) {
5245 if (r.dir != DIR_IN) {
5246 yyerror("rib only allowed on \"from\" "
5247 "rules.");
5248
5249 for (rb = yyvsp[-4].v.filter_rib; rb != NULL((void*)0); rb = rbnext) {
5250 rbnext = rb->next;
5251 free(rb);
5252 }
5253 YYERRORgoto yyerrlab;
5254 }
5255 }
5256 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)
5257 YYERRORgoto yyerrlab;
5258 }
5259break;
5260case 188:
5261#line 1879 "/usr/src/usr.sbin/bgpd/parse.y"
5262{ yyval.v.u8 = ACTION_ALLOW; }
5263break;
5264case 189:
5265#line 1880 "/usr/src/usr.sbin/bgpd/parse.y"
5266{ yyval.v.u8 = ACTION_DENY; }
5267break;
5268case 190:
5269#line 1881 "/usr/src/usr.sbin/bgpd/parse.y"
5270{ yyval.v.u8 = ACTION_NONE; }
5271break;
5272case 191:
5273#line 1884 "/usr/src/usr.sbin/bgpd/parse.y"
5274{ yyval.v.u8 = 0; }
5275break;
5276case 192:
5277#line 1885 "/usr/src/usr.sbin/bgpd/parse.y"
5278{ yyval.v.u8 = 1; }
5279break;
5280case 193:
5281#line 1888 "/usr/src/usr.sbin/bgpd/parse.y"
5282{ yyval.v.u8 = DIR_IN; }
5283break;
5284case 194:
5285#line 1889 "/usr/src/usr.sbin/bgpd/parse.y"
5286{ yyval.v.u8 = DIR_OUT; }
5287break;
5288case 195:
5289#line 1892 "/usr/src/usr.sbin/bgpd/parse.y"
5290{ yyval.v.filter_rib = NULL((void*)0); }
5291break;
5292case 196:
5293#line 1893 "/usr/src/usr.sbin/bgpd/parse.y"
5294{ yyval.v.filter_rib = yyvsp[0].v.filter_rib; }
5295break;
5296case 197:
5297#line 1894 "/usr/src/usr.sbin/bgpd/parse.y"
5298{ yyval.v.filter_rib = yyvsp[-2].v.filter_rib; }
5299break;
5300case 198:
5301#line 1896 "/usr/src/usr.sbin/bgpd/parse.y"
5302{ yyval.v.filter_rib = yyvsp[0].v.filter_rib; }
5303break;
5304case 199:
5305#line 1897 "/usr/src/usr.sbin/bgpd/parse.y"
5306{
5307 yyvsp[0].v.filter_rib->next = yyvsp[-2].v.filter_rib;
5308 yyval.v.filter_rib = yyvsp[0].v.filter_rib;
5309 }
5310break;
5311case 200:
5312#line 1903 "/usr/src/usr.sbin/bgpd/parse.y"
5313{
5314 if (!find_rib(yyvsp[0].v.string)) {
5315 yyerror("rib \"%s\" does not exist.", yyvsp[0].v.string);
5316 free(yyvsp[0].v.string);
5317 YYERRORgoto yyerrlab;
5318 }
5319 if ((yyval.v.filter_rib = calloc(1, sizeof(struct filter_rib_l))) ==
5320 NULL((void*)0))
5321 fatal(NULL((void*)0));
5322 yyval.v.filter_rib->next = NULL((void*)0);
5323 if (strlcpy(yyval.v.filter_rib->name, yyvsp[0].v.string, sizeof(yyval.v.filter_rib->name)) >=
5324 sizeof(yyval.v.filter_rib->name)) {
5325 yyerror("rib name \"%s\" too long: "
5326 "max %zu", yyvsp[0].v.string, sizeof(yyval.v.filter_rib->name) - 1);
5327 free(yyvsp[0].v.string);
5328 free(yyval.v.filter_rib);
5329 YYERRORgoto yyerrlab;
5330 }
5331 free(yyvsp[0].v.string);
5332 }
5333break;
5334case 202:
5335#line 1926 "/usr/src/usr.sbin/bgpd/parse.y"
5336{ yyval.v.filter_peers = yyvsp[-2].v.filter_peers; }
5337break;
5338case 203:
5339#line 1929 "/usr/src/usr.sbin/bgpd/parse.y"
5340{ yyval.v.filter_peers = yyvsp[0].v.filter_peers; }
5341break;
5342case 204:
5343#line 1930 "/usr/src/usr.sbin/bgpd/parse.y"
5344{
5345 yyvsp[0].v.filter_peers->next = yyvsp[-2].v.filter_peers;
5346 yyval.v.filter_peers = yyvsp[0].v.filter_peers;
5347 }
5348break;
5349case 205:
5350#line 1936 "/usr/src/usr.sbin/bgpd/parse.y"
5351{
5352 if ((yyval.v.filter_peers = calloc(1, sizeof(struct filter_peers_l))) ==
5353 NULL((void*)0))
5354 fatal(NULL((void*)0));
5355 yyval.v.filter_peers->p.peerid = yyval.v.filter_peers->p.groupid = 0;
5356 yyval.v.filter_peers->next = NULL((void*)0);
5357 }
5358break;
5359case 206:
5360#line 1943 "/usr/src/usr.sbin/bgpd/parse.y"
5361{
5362 struct peer *p;
5363
5364 if ((yyval.v.filter_peers = calloc(1, sizeof(struct filter_peers_l))) ==
5365 NULL((void*)0))
5366 fatal(NULL((void*)0));
5367 yyval.v.filter_peers->p.remote_as = yyval.v.filter_peers->p.groupid = yyval.v.filter_peers->p.peerid = 0;
5368 yyval.v.filter_peers->next = NULL((void*)0);
5369 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))
5370 if (!memcmp(&p->conf.remote_addr,
5371 &yyvsp[0].v.addr, sizeof(p->conf.remote_addr))) {
5372 yyval.v.filter_peers->p.peerid = p->conf.id;
5373 break;
5374 }
5375 if (yyval.v.filter_peers->p.peerid == 0) {
5376 yyerror("no such peer: %s", log_addr(&yyvsp[0].v.addr));
5377 free(yyval.v.filter_peers);
5378 YYERRORgoto yyerrlab;
5379 }
5380 }
5381break;
5382case 207:
5383#line 1963 "/usr/src/usr.sbin/bgpd/parse.y"
5384{
5385 if ((yyval.v.filter_peers = calloc(1, sizeof(struct filter_peers_l))) ==
5386 NULL((void*)0))
5387 fatal(NULL((void*)0));
5388 yyval.v.filter_peers->p.groupid = yyval.v.filter_peers->p.peerid = 0;
5389 yyval.v.filter_peers->p.remote_as = yyvsp[0].v.number;
5390 }
5391break;
5392case 208:
5393#line 1970 "/usr/src/usr.sbin/bgpd/parse.y"
5394{
5395 struct peer *p;
5396
5397 if ((yyval.v.filter_peers = calloc(1, sizeof(struct filter_peers_l))) ==
5398 NULL((void*)0))
5399 fatal(NULL((void*)0));
5400 yyval.v.filter_peers->p.remote_as = yyval.v.filter_peers->p.peerid = 0;
5401 yyval.v.filter_peers->next = NULL((void*)0);
5402 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))
5403 if (!strcmp(p->conf.group, yyvsp[0].v.string)) {
5404 yyval.v.filter_peers->p.groupid = p->conf.groupid;
5405 break;
5406 }
5407 if (yyval.v.filter_peers->p.groupid == 0) {
5408 yyerror("no such group: \"%s\"", yyvsp[0].v.string);
5409 free(yyvsp[0].v.string);
5410 free(yyval.v.filter_peers);
5411 YYERRORgoto yyerrlab;
5412 }
5413 free(yyvsp[0].v.string);
5414 }
5415break;
5416case 209:
5417#line 1991 "/usr/src/usr.sbin/bgpd/parse.y"
5418{
5419 if ((yyval.v.filter_peers = calloc(1, sizeof(struct filter_peers_l))) ==
5420 NULL((void*)0))
5421 fatal(NULL((void*)0));
5422 yyval.v.filter_peers->p.ebgp = 1;
5423 }
5424break;
5425case 210:
5426#line 1997 "/usr/src/usr.sbin/bgpd/parse.y"
5427{
5428 if ((yyval.v.filter_peers = calloc(1, sizeof(struct filter_peers_l))) ==
5429 NULL((void*)0))
5430 fatal(NULL((void*)0));
5431 yyval.v.filter_peers->p.ibgp = 1;
5432 }
5433break;
5434case 211:
5435#line 2005 "/usr/src/usr.sbin/bgpd/parse.y"
5436{
5437 if (yyvsp[0].v.prefixlen.op == OP_NONE) {
5438 yyvsp[0].v.prefixlen.op = OP_RANGE;
5439 yyvsp[0].v.prefixlen.len_min = 0;
5440 yyvsp[0].v.prefixlen.len_max = -1;
5441 }
5442 if ((yyval.v.filter_prefix = calloc(1, sizeof(struct filter_prefix_l))) ==
5443 NULL((void*)0))
5444 fatal(NULL((void*)0));
5445 yyval.v.filter_prefix->p.addr.aid = AID_INET1;
5446 if (merge_prefixspec(&yyval.v.filter_prefix->p, &yyvsp[0].v.prefixlen) == -1) {
5447 free(yyval.v.filter_prefix);
5448 YYERRORgoto yyerrlab;
5449 }
5450 }
5451break;
5452case 212:
5453#line 2020 "/usr/src/usr.sbin/bgpd/parse.y"
5454{
5455 if (yyvsp[0].v.prefixlen.op == OP_NONE) {
5456 yyvsp[0].v.prefixlen.op = OP_RANGE;
5457 yyvsp[0].v.prefixlen.len_min = 0;
5458 yyvsp[0].v.prefixlen.len_max = -1;
5459 }
5460 if ((yyval.v.filter_prefix = calloc(1, sizeof(struct filter_prefix_l))) ==
5461 NULL((void*)0))
5462 fatal(NULL((void*)0));
5463 yyval.v.filter_prefix->p.addr.aid = AID_INET62;
5464 if (merge_prefixspec(&yyval.v.filter_prefix->p, &yyvsp[0].v.prefixlen) == -1) {
5465 free(yyval.v.filter_prefix);
5466 YYERRORgoto yyerrlab;
5467 }
5468 }
5469break;
5470case 213:
5471#line 2035 "/usr/src/usr.sbin/bgpd/parse.y"
5472{ yyval.v.filter_prefix = yyvsp[0].v.filter_prefix; }
5473break;
5474case 214:
5475#line 2036 "/usr/src/usr.sbin/bgpd/parse.y"
5476{ yyval.v.filter_prefix = yyvsp[-1].v.filter_prefix; }
5477break;
5478case 216:
5479#line 2040 "/usr/src/usr.sbin/bgpd/parse.y"
5480{ yyval.v.filter_prefix = yyvsp[-1].v.filter_prefix; }
5481break;
5482case 217:
5483#line 2042 "/usr/src/usr.sbin/bgpd/parse.y"
5484{
5485 struct filter_prefix_l *p;
5486
5487 /* merge, both can be lists */
5488 for (p = yyvsp[-2].v.filter_prefix; p != NULL((void*)0) && p->next != NULL((void*)0); p = p->next)
5489 ; /* nothing */
5490 if (p != NULL((void*)0))
5491 p->next = yyvsp[0].v.filter_prefix;
5492 yyval.v.filter_prefix = yyvsp[-2].v.filter_prefix;
5493 }
5494break;
5495case 218:
5496#line 2053 "/usr/src/usr.sbin/bgpd/parse.y"
5497{ yyval.v.filter_prefix = yyvsp[0].v.filter_prefix; }
5498break;
5499case 219:
5500#line 2054 "/usr/src/usr.sbin/bgpd/parse.y"
5501{
5502 yyvsp[0].v.filter_prefix->next = yyvsp[-2].v.filter_prefix;
5503 yyval.v.filter_prefix = yyvsp[0].v.filter_prefix;
5504 }
5505break;
5506case 220:
5507#line 2060 "/usr/src/usr.sbin/bgpd/parse.y"
5508{
5509 if ((yyval.v.filter_prefix = calloc(1, sizeof(struct filter_prefix_l))) ==
5510 NULL((void*)0))
5511 fatal(NULL((void*)0));
5512 memcpy(&yyval.v.filter_prefix->p.addr, &yyvsp[-1].v.prefix.prefix,
5513 sizeof(yyval.v.filter_prefix->p.addr));
5514 yyval.v.filter_prefix->p.len = yyvsp[-1].v.prefix.len;
5515
5516 if (merge_prefixspec(&yyval.v.filter_prefix->p, &yyvsp[0].v.prefixlen) == -1) {
5517 free(yyval.v.filter_prefix);
5518 YYERRORgoto yyerrlab;
5519 }
5520 }
5521break;
5522case 222:
5523#line 2076 "/usr/src/usr.sbin/bgpd/parse.y"
5524{ yyval.v.filter_as = yyvsp[-1].v.filter_as; }
5525break;
5526case 224:
5527#line 2080 "/usr/src/usr.sbin/bgpd/parse.y"
5528{
5529 struct filter_as_l *a;
5530
5531 /* merge, both can be lists */
5532 for (a = yyvsp[-2].v.filter_as; a != NULL((void*)0) && a->next != NULL((void*)0); a = a->next)
5533 ; /* nothing */
5534 if (a != NULL((void*)0))
5535 a->next = yyvsp[0].v.filter_as;
5536 yyval.v.filter_as = yyvsp[-2].v.filter_as;
5537 }
5538break;
5539case 225:
5540#line 2092 "/usr/src/usr.sbin/bgpd/parse.y"
5541{
5542 yyval.v.filter_as = yyvsp[0].v.filter_as;
5543 yyval.v.filter_as->a.type = yyvsp[-1].v.u8;
5544 }
5545break;
5546case 226:
5547#line 2096 "/usr/src/usr.sbin/bgpd/parse.y"
5548{
5549 struct filter_as_l *a;
5550
5551 yyval.v.filter_as = yyvsp[-1].v.filter_as;
5552 for (a = yyval.v.filter_as; a != NULL((void*)0); a = a->next)
5553 a->a.type = yyvsp[-3].v.u8;
5554 }
5555break;
5556case 227:
5557#line 2103 "/usr/src/usr.sbin/bgpd/parse.y"
5558{
5559 if (as_sets_lookup(&conf->as_sets, yyvsp[0].v.string) == NULL((void*)0)) {
5560 yyerror("as-set \"%s\" not defined", yyvsp[0].v.string);
5561 free(yyvsp[0].v.string);
5562 YYERRORgoto yyerrlab;
5563 }
5564 if ((yyval.v.filter_as = calloc(1, sizeof(struct filter_as_l))) ==
5565 NULL((void*)0))
5566 fatal(NULL((void*)0));
5567 yyval.v.filter_as->a.type = yyvsp[-2].v.u8;
5568 yyval.v.filter_as->a.flags = AS_FLAG_AS_SET_NAME0x02;
5569 if (strlcpy(yyval.v.filter_as->a.name, yyvsp[0].v.string, sizeof(yyval.v.filter_as->a.name)) >=
5570 sizeof(yyval.v.filter_as->a.name)) {
5571 yyerror("as-set name \"%s\" too long: "
5572 "max %zu", yyvsp[0].v.string, sizeof(yyval.v.filter_as->a.name) - 1);
5573 free(yyvsp[0].v.string);
5574 free(yyval.v.filter_as);
5575 YYERRORgoto yyerrlab;
5576 }
5577 free(yyvsp[0].v.string);
5578 }
5579break;
5580case 229:
5581#line 2127 "/usr/src/usr.sbin/bgpd/parse.y"
5582{ yyval.v.filter_as = yyvsp[-1].v.filter_as; }
5583break;
5584case 230:
5585#line 2129 "/usr/src/usr.sbin/bgpd/parse.y"
5586{
5587 struct filter_as_l *a;
5588
5589 /* merge, both can be lists */
5590 for (a = yyvsp[-2].v.filter_as; a != NULL((void*)0) && a->next != NULL((void*)0); a = a->next)
5591 ; /* nothing */
5592 if (a != NULL((void*)0))
5593 a->next = yyvsp[0].v.filter_as;
5594 yyval.v.filter_as = yyvsp[-2].v.filter_as;
5595 }
5596break;
5597case 232:
5598#line 2142 "/usr/src/usr.sbin/bgpd/parse.y"
5599{
5600 yyvsp[0].v.filter_as->next = yyvsp[-2].v.filter_as;
5601 yyval.v.filter_as = yyvsp[0].v.filter_as;
5602 }
5603break;
5604case 233:
5605#line 2148 "/usr/src/usr.sbin/bgpd/parse.y"
5606{
5607 if ((yyval.v.filter_as = calloc(1, sizeof(struct filter_as_l))) ==
5608 NULL((void*)0))
5609 fatal(NULL((void*)0));
5610 yyval.v.filter_as->a.as_min = yyvsp[0].v.number;
5611 yyval.v.filter_as->a.as_max = yyvsp[0].v.number;
5612 yyval.v.filter_as->a.op = OP_EQ;
5613 }
5614break;
5615case 234:
5616#line 2156 "/usr/src/usr.sbin/bgpd/parse.y"
5617{
5618 if ((yyval.v.filter_as = calloc(1, sizeof(struct filter_as_l))) ==
5619 NULL((void*)0))
5620 fatal(NULL((void*)0));
5621 yyval.v.filter_as->a.flags = AS_FLAG_NEIGHBORAS0x01;
5622 }
5623break;
5624case 235:
5625#line 2162 "/usr/src/usr.sbin/bgpd/parse.y"
5626{
5627 if ((yyval.v.filter_as = calloc(1, sizeof(struct filter_as_l))) ==
5628 NULL((void*)0))
5629 fatal(NULL((void*)0));
5630 yyval.v.filter_as->a.op = yyvsp[-1].v.u8;
5631 yyval.v.filter_as->a.as_min = yyvsp[0].v.number;
5632 yyval.v.filter_as->a.as_max = yyvsp[0].v.number;
5633 }
5634break;
5635case 236:
5636#line 2170 "/usr/src/usr.sbin/bgpd/parse.y"
5637{
5638 if ((yyval.v.filter_as = calloc(1, sizeof(struct filter_as_l))) ==
5639 NULL((void*)0))
5640 fatal(NULL((void*)0));
5641 if (yyvsp[-2].v.number >= yyvsp[0].v.number) {
5642 yyerror("start AS is bigger than end");
5643 YYERRORgoto yyerrlab;
5644 }
5645 yyval.v.filter_as->a.op = yyvsp[-1].v.u8;
5646 yyval.v.filter_as->a.as_min = yyvsp[-2].v.number;
5647 yyval.v.filter_as->a.as_max = yyvsp[0].v.number;
5648 }
5649break;
5650case 237:
5651#line 2184 "/usr/src/usr.sbin/bgpd/parse.y"
5652{
5653 bzero(&yyval.v.filter_match, sizeof(yyval.v.filter_match));
5654 }
5655break;
5656case 238:
5657#line 2187 "/usr/src/usr.sbin/bgpd/parse.y"
5658{
5659 bzero(&fmopts, sizeof(fmopts));
5660 }
5661break;
5662case 239:
5663#line 2190 "/usr/src/usr.sbin/bgpd/parse.y"
5664{
5665 memcpy(&yyval.v.filter_match, &fmopts, sizeof(yyval.v.filter_match));
5666 }
5667break;
5668case 242:
5669#line 2199 "/usr/src/usr.sbin/bgpd/parse.y"
5670{
5671 if (fmopts.prefix_l != NULL((void*)0)) {
5672 yyerror("\"prefix\" already specified");
5673 YYERRORgoto yyerrlab;
5674 }
5675 if (fmopts.m.prefixset.name[0] != '\0') {
5676 yyerror("\"prefix-set\" already specified, "
5677 "cannot be used with \"prefix\" in the "
5678 "same filter rule");
5679 YYERRORgoto yyerrlab;
5680 }
5681 fmopts.prefix_l = yyvsp[0].v.filter_prefix;
5682 }
5683break;
5684case 243:
5685#line 2212 "/usr/src/usr.sbin/bgpd/parse.y"
5686{
5687 if (fmopts.as_l != NULL((void*)0)) {
5688 yyerror("AS filters already specified");
5689 YYERRORgoto yyerrlab;
5690 }
5691 fmopts.as_l = yyvsp[0].v.filter_as;
5692 }
5693break;
5694case 244:
5695#line 2219 "/usr/src/usr.sbin/bgpd/parse.y"
5696{
5697 if (fmopts.m.aslen.type != ASLEN_NONE) {
5698 yyerror("AS length filters already specified");
5699 YYERRORgoto yyerrlab;
5700 }
5701 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > UINT_MAX(2147483647 *2U +1U)) {
5702 yyerror("bad max-as-len %lld", yyvsp[0].v.number);
5703 YYERRORgoto yyerrlab;
5704 }
5705 fmopts.m.aslen.type = ASLEN_MAX;
5706 fmopts.m.aslen.aslen = yyvsp[0].v.number;
5707 }
5708break;
5709case 245:
5710#line 2231 "/usr/src/usr.sbin/bgpd/parse.y"
5711{
5712 if (fmopts.m.aslen.type != ASLEN_NONE) {
5713 yyerror("AS length filters already specified");
5714 YYERRORgoto yyerrlab;
5715 }
5716 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > UINT_MAX(2147483647 *2U +1U)) {
5717 yyerror("bad max-as-seq %lld", yyvsp[0].v.number);
5718 YYERRORgoto yyerrlab;
5719 }
5720 fmopts.m.aslen.type = ASLEN_SEQ;
5721 fmopts.m.aslen.aslen = yyvsp[0].v.number;
5722 }
5723break;
5724case 246:
5725#line 2243 "/usr/src/usr.sbin/bgpd/parse.y"
5726{
5727 int i;
5728 for (i = 0; i < MAX_COMM_MATCH3; i++) {
5729 if (fmopts.m.community[i].flags == 0)
5730 break;
5731 }
5732 if (i >= MAX_COMM_MATCH3) {
5733 yyerror("too many \"community\" filters "
5734 "specified");
5735 free(yyvsp[0].v.string);
5736 YYERRORgoto yyerrlab;
5737 }
5738 if (parsecommunity(&fmopts.m.community[i], yyvsp[-1].v.u8, yyvsp[0].v.string) == -1) {
5739 free(yyvsp[0].v.string);
5740 YYERRORgoto yyerrlab;
5741 }
5742 free(yyvsp[0].v.string);
5743 }
5744break;
5745case 247:
5746#line 2261 "/usr/src/usr.sbin/bgpd/parse.y"
5747{
5748 int i;
5749 for (i = 0; i < MAX_COMM_MATCH3; i++) {
5750 if (fmopts.m.community[i].flags == 0)
5751 break;
5752 }
5753 if (i >= MAX_COMM_MATCH3) {
5754 yyerror("too many \"community\" filters "
5755 "specified");
5756 free(yyvsp[-1].v.string);
5757 free(yyvsp[0].v.string);
5758 YYERRORgoto yyerrlab;
5759 }
5760 if (parseextcommunity(&fmopts.m.community[i],
5761 yyvsp[-1].v.string, yyvsp[0].v.string) == -1) {
5762 free(yyvsp[-1].v.string);
5763 free(yyvsp[0].v.string);
5764 YYERRORgoto yyerrlab;
5765 }
5766 free(yyvsp[-1].v.string);
5767 free(yyvsp[0].v.string);
5768 }
5769break;
5770case 248:
5771#line 2283 "/usr/src/usr.sbin/bgpd/parse.y"
5772{
5773 int i;
5774 for (i = 0; i < MAX_COMM_MATCH3; i++) {
5775 if (fmopts.m.community[i].flags == 0)
5776 break;
5777 }
5778 if (i >= MAX_COMM_MATCH3) {
5779 yyerror("too many \"community\" filters "
5780 "specified");
5781 free(yyvsp[0].v.string);
5782 YYERRORgoto yyerrlab;
5783 }
5784 if (parseextcommunity(&fmopts.m.community[i],
5785 "ovs", yyvsp[0].v.string) == -1) {
5786 free(yyvsp[0].v.string);
5787 YYERRORgoto yyerrlab;
5788 }
5789 free(yyvsp[0].v.string);
5790 }
5791break;
5792case 249:
5793#line 2302 "/usr/src/usr.sbin/bgpd/parse.y"
5794{
5795 if (fmopts.m.nexthop.flags) {
5796 yyerror("nexthop already specified");
5797 YYERRORgoto yyerrlab;
5798 }
5799 fmopts.m.nexthop.addr = yyvsp[0].v.addr;
5800 fmopts.m.nexthop.flags = FILTER_NEXTHOP_ADDR1;
5801 }
5802break;
5803case 250:
5804#line 2310 "/usr/src/usr.sbin/bgpd/parse.y"
5805{
5806 if (fmopts.m.nexthop.flags) {
5807 yyerror("nexthop already specified");
5808 YYERRORgoto yyerrlab;
5809 }
5810 fmopts.m.nexthop.flags = FILTER_NEXTHOP_NEIGHBOR2;
5811 }
5812break;
5813case 251:
5814#line 2317 "/usr/src/usr.sbin/bgpd/parse.y"
5815{
5816 struct prefixset *ps;
5817 if (fmopts.prefix_l != NULL((void*)0)) {
5818 yyerror("\"prefix\" already specified, cannot "
5819 "be used with \"prefix-set\" in the same "
5820 "filter rule");
5821 free(yyvsp[-1].v.string);
5822 YYERRORgoto yyerrlab;
5823 }
5824 if (fmopts.m.prefixset.name[0] != '\0') {
5825 yyerror("prefix-set filter already specified");
5826 free(yyvsp[-1].v.string);
5827 YYERRORgoto yyerrlab;
5828 }
5829 if ((ps = find_prefixset(yyvsp[-1].v.string, &conf->prefixsets))
5830 == NULL((void*)0)) {
5831 yyerror("prefix-set '%s' not defined", yyvsp[-1].v.string);
5832 free(yyvsp[-1].v.string);
5833 YYERRORgoto yyerrlab;
5834 }
5835 if (strlcpy(fmopts.m.prefixset.name, yyvsp[-1].v.string,
5836 sizeof(fmopts.m.prefixset.name)) >=
5837 sizeof(fmopts.m.prefixset.name)) {
5838 yyerror("prefix-set name too long");
5839 free(yyvsp[-1].v.string);
5840 YYERRORgoto yyerrlab;
5841 }
5842 if (!(yyvsp[0].v.prefixlen.op == OP_NONE ||
5843 (yyvsp[0].v.prefixlen.op == OP_RANGE &&
5844 yyvsp[0].v.prefixlen.len_min == -1 && yyvsp[0].v.prefixlen.len_max == -1))) {
5845 yyerror("prefix-sets can only use option "
5846 "or-longer");
5847 free(yyvsp[-1].v.string);
5848 YYERRORgoto yyerrlab;
5849 }
5850 if (yyvsp[0].v.prefixlen.op == OP_RANGE && ps->sflags & PREFIXSET_FLAG_OPS0x04) {
5851 yyerror("prefix-set %s contains prefixlen "
5852 "operators and cannot be used with an "
5853 "or-longer filter", yyvsp[-1].v.string);
5854 free(yyvsp[-1].v.string);
5855 YYERRORgoto yyerrlab;
5856 }
5857 if (yyvsp[0].v.prefixlen.op == OP_RANGE && yyvsp[0].v.prefixlen.len_min == -1 &&
5858 yyvsp[0].v.prefixlen.len_min == -1)
5859 fmopts.m.prefixset.flags |=
5860 PREFIXSET_FLAG_LONGER0x08;
5861 fmopts.m.prefixset.flags |= PREFIXSET_FLAG_FILTER0x01;
5862 free(yyvsp[-1].v.string);
5863 }
5864break;
5865case 252:
5866#line 2366 "/usr/src/usr.sbin/bgpd/parse.y"
5867{
5868 if (fmopts.m.originset.name[0] != '\0') {
5869 yyerror("origin-set filter already specified");
5870 free(yyvsp[0].v.string);
5871 YYERRORgoto yyerrlab;
5872 }
5873 if (find_prefixset(yyvsp[0].v.string, &conf->originsets) == NULL((void*)0)) {
5874 yyerror("origin-set '%s' not defined", yyvsp[0].v.string);
5875 free(yyvsp[0].v.string);
5876 YYERRORgoto yyerrlab;
5877 }
5878 if (strlcpy(fmopts.m.originset.name, yyvsp[0].v.string,
5879 sizeof(fmopts.m.originset.name)) >=
5880 sizeof(fmopts.m.originset.name)) {
5881 yyerror("origin-set name too long");
5882 free(yyvsp[0].v.string);
5883 YYERRORgoto yyerrlab;
5884 }
5885 free(yyvsp[0].v.string);
5886 }
5887break;
5888case 253:
5889#line 2386 "/usr/src/usr.sbin/bgpd/parse.y"
5890{
5891 if (fmopts.m.ovs.is_set) {
5892 yyerror("ovs filter already specified");
5893 YYERRORgoto yyerrlab;
5894 }
5895 fmopts.m.ovs.validity = yyvsp[0].v.number;
5896 fmopts.m.ovs.is_set = 1;
5897 }
5898break;
5899case 254:
5900#line 2396 "/usr/src/usr.sbin/bgpd/parse.y"
5901{ bzero(&yyval.v.prefixlen, sizeof(yyval.v.prefixlen)); }
5902break;
5903case 255:
5904#line 2397 "/usr/src/usr.sbin/bgpd/parse.y"
5905{
5906 bzero(&yyval.v.prefixlen, sizeof(yyval.v.prefixlen));
5907 yyval.v.prefixlen.op = OP_RANGE;
5908 yyval.v.prefixlen.len_min = -1;
5909 yyval.v.prefixlen.len_max = -1;
5910 }
5911break;
5912case 256:
5913#line 2403 "/usr/src/usr.sbin/bgpd/parse.y"
5914{
5915 bzero(&yyval.v.prefixlen, sizeof(yyval.v.prefixlen));
5916 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > 128) {
5917 yyerror("prefixlen must be >= 0 and <= 128");
5918 YYERRORgoto yyerrlab;
5919 }
5920
5921 yyval.v.prefixlen.op = OP_RANGE;
5922 yyval.v.prefixlen.len_min = -1;
5923 yyval.v.prefixlen.len_max = yyvsp[0].v.number;
5924 }
5925break;
5926case 257:
5927#line 2414 "/usr/src/usr.sbin/bgpd/parse.y"
5928{
5929 int min, max;
5930
5931 bzero(&yyval.v.prefixlen, sizeof(yyval.v.prefixlen));
5932 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > 128) {
5933 yyerror("prefixlen must be >= 0 and <= 128");
5934 YYERRORgoto yyerrlab;
5935 }
5936 /*
5937 * convert the unary operation into the equivalent
5938 * range check
5939 */
5940 yyval.v.prefixlen.op = OP_RANGE;
5941
5942 switch (yyvsp[-1].v.u8) {
5943 case OP_NE:
5944 yyval.v.prefixlen.op = yyvsp[-1].v.u8;
5945 case OP_EQ:
5946 min = max = yyvsp[0].v.number;
5947 break;
5948 case OP_LT:
5949 if (yyvsp[0].v.number == 0) {
5950 yyerror("prefixlen must be > 0");
5951 YYERRORgoto yyerrlab;
5952 }
5953 yyvsp[0].v.number -= 1;
5954 case OP_LE:
5955 min = -1;
5956 max = yyvsp[0].v.number;
5957 break;
5958 case OP_GT:
5959 yyvsp[0].v.number += 1;
5960 case OP_GE:
5961 min = yyvsp[0].v.number;
5962 max = -1;
5963 break;
5964 default:
5965 yyerror("unknown prefixlen operation");
5966 YYERRORgoto yyerrlab;
5967 }
5968 yyval.v.prefixlen.len_min = min;
5969 yyval.v.prefixlen.len_max = max;
5970 }
5971break;
5972case 258:
5973#line 2457 "/usr/src/usr.sbin/bgpd/parse.y"
5974{
5975 bzero(&yyval.v.prefixlen, sizeof(yyval.v.prefixlen));
5976 if (yyvsp[-2].v.number < 0 || yyvsp[-2].v.number > 128 || yyvsp[0].v.number < 0 || yyvsp[0].v.number > 128) {
5977 yyerror("prefixlen must be < 128");
5978 YYERRORgoto yyerrlab;
5979 }
5980 if (yyvsp[-2].v.number > yyvsp[0].v.number) {
5981 yyerror("start prefixlen is bigger than end");
5982 YYERRORgoto yyerrlab;
5983 }
5984 yyval.v.prefixlen.op = yyvsp[-1].v.u8;
5985 yyval.v.prefixlen.len_min = yyvsp[-2].v.number;
5986 yyval.v.prefixlen.len_max = yyvsp[0].v.number;
5987 }
5988break;
5989case 259:
5990#line 2473 "/usr/src/usr.sbin/bgpd/parse.y"
5991{ yyval.v.u8 = AS_ALL; }
5992break;
5993case 260:
5994#line 2474 "/usr/src/usr.sbin/bgpd/parse.y"
5995{ yyval.v.u8 = AS_SOURCE; }
5996break;
5997case 261:
5998#line 2475 "/usr/src/usr.sbin/bgpd/parse.y"
5999{ yyval.v.u8 = AS_TRANSIT; }
6000break;
6001case 262:
6002#line 2476 "/usr/src/usr.sbin/bgpd/parse.y"
6003{ yyval.v.u8 = AS_PEER; }
6004break;
6005case 263:
6006#line 2479 "/usr/src/usr.sbin/bgpd/parse.y"
6007{ yyval.v.filter_set_head = NULL((void*)0); }
6008break;
6009case 264:
6010#line 2480 "/usr/src/usr.sbin/bgpd/parse.y"
6011{
6012 if ((yyval.v.filter_set_head = calloc(1, sizeof(struct filter_set_head))) ==
6013 NULL((void*)0))
6014 fatal(NULL((void*)0));
6015 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)
;
6016 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)
;
6017 }
6018break;
6019case 265:
6020#line 2487 "/usr/src/usr.sbin/bgpd/parse.y"
6021{ yyval.v.filter_set_head = yyvsp[-2].v.filter_set_head; }
6022break;
6023case 266:
6024#line 2490 "/usr/src/usr.sbin/bgpd/parse.y"
6025{
6026 yyval.v.filter_set_head = yyvsp[-2].v.filter_set_head;
6027 if (merge_filterset(yyval.v.filter_set_head, yyvsp[0].v.filter_set) == 1)
6028 YYERRORgoto yyerrlab;
6029 }
6030break;
6031case 267:
6032#line 2495 "/usr/src/usr.sbin/bgpd/parse.y"
6033{
6034 if ((yyval.v.filter_set_head = calloc(1, sizeof(struct filter_set_head))) ==
6035 NULL((void*)0))
6036 fatal(NULL((void*)0));
6037 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)
;
6038 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)
;
6039 }
6040break;
6041case 268:
6042#line 2504 "/usr/src/usr.sbin/bgpd/parse.y"
6043{ yyval.v.u8 = COMMUNITY_TYPE_BASIC8; }
6044break;
6045case 269:
6046#line 2505 "/usr/src/usr.sbin/bgpd/parse.y"
6047{ yyval.v.u8 = COMMUNITY_TYPE_LARGE32; }
6048break;
6049case 270:
6050#line 2508 "/usr/src/usr.sbin/bgpd/parse.y"
6051{ yyval.v.u8 = 0; }
6052break;
6053case 271:
6054#line 2509 "/usr/src/usr.sbin/bgpd/parse.y"
6055{ yyval.v.u8 = 1; }
6056break;
6057case 272:
6058#line 2512 "/usr/src/usr.sbin/bgpd/parse.y"
6059{
6060 if (yyvsp[0].v.number < -INT_MAX2147483647 || yyvsp[0].v.number > UINT_MAX(2147483647 *2U +1U)) {
6061 yyerror("bad localpref %lld", yyvsp[0].v.number);
6062 YYERRORgoto yyerrlab;
6063 }
6064 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void*)0))
6065 fatal(NULL((void*)0));
6066 if (yyvsp[0].v.number >= 0) {
6067 yyval.v.filter_set->type = ACTION_SET_LOCALPREF;
6068 yyval.v.filter_set->action.metric = yyvsp[0].v.number;
6069 } else {
6070 yyval.v.filter_set->type = ACTION_SET_RELATIVE_LOCALPREF;
6071 yyval.v.filter_set->action.relative = yyvsp[0].v.number;
6072 }
6073 }
6074break;
6075case 273:
6076#line 2527 "/usr/src/usr.sbin/bgpd/parse.y"
6077{
6078 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX2147483647) {
6079 yyerror("bad localpref +%lld", yyvsp[0].v.number);
6080 YYERRORgoto yyerrlab;
6081 }
6082 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void*)0))
6083 fatal(NULL((void*)0));
6084 yyval.v.filter_set->type = ACTION_SET_RELATIVE_LOCALPREF;
6085 yyval.v.filter_set->action.relative = yyvsp[0].v.number;
6086 }
6087break;
6088case 274:
6089#line 2537 "/usr/src/usr.sbin/bgpd/parse.y"
6090{
6091 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX2147483647) {
6092 yyerror("bad localpref -%lld", yyvsp[0].v.number);
6093 YYERRORgoto yyerrlab;
6094 }
6095 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void*)0))
6096 fatal(NULL((void*)0));
6097 yyval.v.filter_set->type = ACTION_SET_RELATIVE_LOCALPREF;
6098 yyval.v.filter_set->action.relative = -yyvsp[0].v.number;
6099 }
6100break;
6101case 275:
6102#line 2547 "/usr/src/usr.sbin/bgpd/parse.y"
6103{
6104 if (yyvsp[0].v.number < -INT_MAX2147483647 || yyvsp[0].v.number > UINT_MAX(2147483647 *2U +1U)) {
6105 yyerror("bad metric %lld", yyvsp[0].v.number);
6106 YYERRORgoto yyerrlab;
6107 }
6108 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void*)0))
6109 fatal(NULL((void*)0));
6110 if (yyvsp[0].v.number >= 0) {
6111 yyval.v.filter_set->type = ACTION_SET_MED;
6112 yyval.v.filter_set->action.metric = yyvsp[0].v.number;
6113 } else {
6114 yyval.v.filter_set->type = ACTION_SET_RELATIVE_MED;
6115 yyval.v.filter_set->action.relative = yyvsp[0].v.number;
6116 }
6117 }
6118break;
6119case 276:
6120#line 2562 "/usr/src/usr.sbin/bgpd/parse.y"
6121{
6122 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX2147483647) {
6123 yyerror("bad metric +%lld", yyvsp[0].v.number);
6124 YYERRORgoto yyerrlab;
6125 }
6126 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void*)0))
6127 fatal(NULL((void*)0));
6128 yyval.v.filter_set->type = ACTION_SET_RELATIVE_MED;
6129 yyval.v.filter_set->action.relative = yyvsp[0].v.number;
6130 }
6131break;
6132case 277:
6133#line 2572 "/usr/src/usr.sbin/bgpd/parse.y"
6134{
6135 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX2147483647) {
6136 yyerror("bad metric -%lld", yyvsp[0].v.number);
6137 YYERRORgoto yyerrlab;
6138 }
6139 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void*)0))
6140 fatal(NULL((void*)0));
6141 yyval.v.filter_set->type = ACTION_SET_RELATIVE_MED;
6142 yyval.v.filter_set->action.relative = -yyvsp[0].v.number;
6143 }
6144break;
6145case 278:
6146#line 2582 "/usr/src/usr.sbin/bgpd/parse.y"
6147{ /* alias for MED */
6148 if (yyvsp[0].v.number < -INT_MAX2147483647 || yyvsp[0].v.number > UINT_MAX(2147483647 *2U +1U)) {
6149 yyerror("bad metric %lld", yyvsp[0].v.number);
6150 YYERRORgoto yyerrlab;
6151 }
6152 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void*)0))
6153 fatal(NULL((void*)0));
6154 if (yyvsp[0].v.number >= 0) {
6155 yyval.v.filter_set->type = ACTION_SET_MED;
6156 yyval.v.filter_set->action.metric = yyvsp[0].v.number;
6157 } else {
6158 yyval.v.filter_set->type = ACTION_SET_RELATIVE_MED;
6159 yyval.v.filter_set->action.relative = yyvsp[0].v.number;
6160 }
6161 }
6162break;
6163case 279:
6164#line 2597 "/usr/src/usr.sbin/bgpd/parse.y"
6165{
6166 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX2147483647) {
6167 yyerror("bad metric +%lld", yyvsp[0].v.number);
6168 YYERRORgoto yyerrlab;
6169 }
6170 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void*)0))
6171 fatal(NULL((void*)0));
6172 yyval.v.filter_set->type = ACTION_SET_RELATIVE_MED;
6173 yyval.v.filter_set->action.metric = yyvsp[0].v.number;
6174 }
6175break;
6176case 280:
6177#line 2607 "/usr/src/usr.sbin/bgpd/parse.y"
6178{
6179 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX2147483647) {
6180 yyerror("bad metric -%lld", yyvsp[0].v.number);
6181 YYERRORgoto yyerrlab;
6182 }
6183 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void*)0))
6184 fatal(NULL((void*)0));
6185 yyval.v.filter_set->type = ACTION_SET_RELATIVE_MED;
6186 yyval.v.filter_set->action.relative = -yyvsp[0].v.number;
6187 }
6188break;
6189case 281:
6190#line 2617 "/usr/src/usr.sbin/bgpd/parse.y"
6191{
6192 if (yyvsp[0].v.number < -INT_MAX2147483647 || yyvsp[0].v.number > UINT_MAX(2147483647 *2U +1U)) {
6193 yyerror("bad weight %lld", yyvsp[0].v.number);
6194 YYERRORgoto yyerrlab;
6195 }
6196 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void*)0))
6197 fatal(NULL((void*)0));
6198 if (yyvsp[0].v.number > 0) {
6199 yyval.v.filter_set->type = ACTION_SET_WEIGHT;
6200 yyval.v.filter_set->action.metric = yyvsp[0].v.number;
6201 } else {
6202 yyval.v.filter_set->type = ACTION_SET_RELATIVE_WEIGHT;
6203 yyval.v.filter_set->action.relative = yyvsp[0].v.number;
6204 }
6205 }
6206break;
6207case 282:
6208#line 2632 "/usr/src/usr.sbin/bgpd/parse.y"
6209{
6210 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX2147483647) {
6211 yyerror("bad weight +%lld", yyvsp[0].v.number);
6212 YYERRORgoto yyerrlab;
6213 }
6214 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void*)0))
6215 fatal(NULL((void*)0));
6216 yyval.v.filter_set->type = ACTION_SET_RELATIVE_WEIGHT;
6217 yyval.v.filter_set->action.relative = yyvsp[0].v.number;
6218 }
6219break;
6220case 283:
6221#line 2642 "/usr/src/usr.sbin/bgpd/parse.y"
6222{
6223 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX2147483647) {
6224 yyerror("bad weight -%lld", yyvsp[0].v.number);
6225 YYERRORgoto yyerrlab;
6226 }
6227 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void*)0))
6228 fatal(NULL((void*)0));
6229 yyval.v.filter_set->type = ACTION_SET_RELATIVE_WEIGHT;
6230 yyval.v.filter_set->action.relative = -yyvsp[0].v.number;
6231 }
6232break;
6233case 284:
6234#line 2652 "/usr/src/usr.sbin/bgpd/parse.y"
6235{
6236 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void*)0))
6237 fatal(NULL((void*)0));
6238 yyval.v.filter_set->type = ACTION_SET_NEXTHOP;
6239 memcpy(&yyval.v.filter_set->action.nexthop, &yyvsp[0].v.addr,
6240 sizeof(yyval.v.filter_set->action.nexthop));
6241 }
6242break;
6243case 285:
6244#line 2659 "/usr/src/usr.sbin/bgpd/parse.y"
6245{
6246 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void*)0))
6247 fatal(NULL((void*)0));
6248 yyval.v.filter_set->type = ACTION_SET_NEXTHOP_BLACKHOLE;
6249 }
6250break;
6251case 286:
6252#line 2664 "/usr/src/usr.sbin/bgpd/parse.y"
6253{
6254 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void*)0))
6255 fatal(NULL((void*)0));
6256 yyval.v.filter_set->type = ACTION_SET_NEXTHOP_REJECT;
6257 }
6258break;
6259case 287:
6260#line 2669 "/usr/src/usr.sbin/bgpd/parse.y"
6261{
6262 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void*)0))
6263 fatal(NULL((void*)0));
6264 yyval.v.filter_set->type = ACTION_SET_NEXTHOP_NOMODIFY;
6265 }
6266break;
6267case 288:
6268#line 2674 "/usr/src/usr.sbin/bgpd/parse.y"
6269{
6270 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void*)0))
6271 fatal(NULL((void*)0));
6272 yyval.v.filter_set->type = ACTION_SET_NEXTHOP_SELF;
6273 }
6274break;
6275case 289:
6276#line 2679 "/usr/src/usr.sbin/bgpd/parse.y"
6277{
6278 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > 128) {
6279 yyerror("bad number of prepends");
6280 YYERRORgoto yyerrlab;
6281 }
6282 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void*)0))
6283 fatal(NULL((void*)0));
6284 yyval.v.filter_set->type = ACTION_SET_PREPEND_SELF;
6285 yyval.v.filter_set->action.prepend = yyvsp[0].v.number;
6286 }
6287break;
6288case 290:
6289#line 2689 "/usr/src/usr.sbin/bgpd/parse.y"
6290{
6291 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > 128) {
6292 yyerror("bad number of prepends");
6293 YYERRORgoto yyerrlab;
6294 }
6295 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void*)0))
6296 fatal(NULL((void*)0));
6297 yyval.v.filter_set->type = ACTION_SET_PREPEND_PEER;
6298 yyval.v.filter_set->action.prepend = yyvsp[0].v.number;
6299 }
6300break;
6301case 291:
6302#line 2699 "/usr/src/usr.sbin/bgpd/parse.y"
6303{
6304 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void*)0))
6305 fatal(NULL((void*)0));
6306 yyval.v.filter_set->type = ACTION_SET_AS_OVERRIDE;
6307 }
6308break;
6309case 292:
6310#line 2704 "/usr/src/usr.sbin/bgpd/parse.y"
6311{
6312 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void*)0))
6313 fatal(NULL((void*)0));
6314 yyval.v.filter_set->type = ACTION_PFTABLE;
6315 if (!(cmd_opts & BGPD_OPT_NOACTION0x0004) &&
6316 pftable_exists(yyvsp[0].v.string) != 0) {
6317 yyerror("pftable name does not exist");
6318 free(yyvsp[0].v.string);
6319 free(yyval.v.filter_set);
6320 YYERRORgoto yyerrlab;
6321 }
6322 if (strlcpy(yyval.v.filter_set->action.pftable, yyvsp[0].v.string,
6323 sizeof(yyval.v.filter_set->action.pftable)) >=
6324 sizeof(yyval.v.filter_set->action.pftable)) {
6325 yyerror("pftable name too long");
6326 free(yyvsp[0].v.string);
6327 free(yyval.v.filter_set);
6328 YYERRORgoto yyerrlab;
6329 }
6330 if (pftable_add(yyvsp[0].v.string) != 0) {
6331 yyerror("Couldn't register table");
6332 free(yyvsp[0].v.string);
6333 free(yyval.v.filter_set);
6334 YYERRORgoto yyerrlab;
6335 }
6336 free(yyvsp[0].v.string);
6337 }
6338break;
6339case 293:
6340#line 2731 "/usr/src/usr.sbin/bgpd/parse.y"
6341{
6342 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void*)0))
6343 fatal(NULL((void*)0));
6344 yyval.v.filter_set->type = ACTION_RTLABEL;
6345 if (strlcpy(yyval.v.filter_set->action.rtlabel, yyvsp[0].v.string,
6346 sizeof(yyval.v.filter_set->action.rtlabel)) >=
6347 sizeof(yyval.v.filter_set->action.rtlabel)) {
6348 yyerror("rtlabel name too long");
6349 free(yyvsp[0].v.string);
6350 free(yyval.v.filter_set);
6351 YYERRORgoto yyerrlab;
6352 }
6353 free(yyvsp[0].v.string);
6354 }
6355break;
6356case 294:
6357#line 2745 "/usr/src/usr.sbin/bgpd/parse.y"
6358{
6359 u_int8_t f1, f2, f3;
6360
6361 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void*)0))
6362 fatal(NULL((void*)0));
6363 if (yyvsp[-1].v.u8)
6364 yyval.v.filter_set->type = ACTION_DEL_COMMUNITY;
6365 else
6366 yyval.v.filter_set->type = ACTION_SET_COMMUNITY;
6367
6368 if (parsecommunity(&yyval.v.filter_set->action.community, yyvsp[-2].v.u8, yyvsp[0].v.string) ==
6369 -1) {
6370 free(yyvsp[0].v.string);
6371 free(yyval.v.filter_set);
6372 YYERRORgoto yyerrlab;
6373 }
6374 free(yyvsp[0].v.string);
6375 /* Don't allow setting of any match */
6376 f1 = yyval.v.filter_set->action.community.flags >> 8;
6377 f2 = yyval.v.filter_set->action.community.flags >> 16;
6378 f3 = yyval.v.filter_set->action.community.flags >> 24;
6379 if (!yyvsp[-1].v.u8 && (f1 == COMMUNITY_ANY1 ||
6380 f2 == COMMUNITY_ANY1 || f3 == COMMUNITY_ANY1)) {
6381 yyerror("'*' is not allowed in set community");
6382 free(yyval.v.filter_set);
6383 YYERRORgoto yyerrlab;
6384 }
6385 }
6386break;
6387case 295:
6388#line 2773 "/usr/src/usr.sbin/bgpd/parse.y"
6389{
6390 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void*)0))
6391 fatal(NULL((void*)0));
6392 if (yyvsp[-2].v.u8)
6393 yyval.v.filter_set->type = ACTION_DEL_COMMUNITY;
6394 else
6395 yyval.v.filter_set->type = ACTION_SET_COMMUNITY;
6396
6397 if (parseextcommunity(&yyval.v.filter_set->action.community,
6398 yyvsp[-1].v.string, yyvsp[0].v.string) == -1) {
6399 free(yyvsp[-1].v.string);
6400 free(yyvsp[0].v.string);
6401 free(yyval.v.filter_set);
6402 YYERRORgoto yyerrlab;
6403 }
6404 free(yyvsp[-1].v.string);
6405 free(yyvsp[0].v.string);
6406 }
6407break;
6408case 296:
6409#line 2791 "/usr/src/usr.sbin/bgpd/parse.y"
6410{
6411 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void*)0))
6412 fatal(NULL((void*)0));
6413 if (yyvsp[-2].v.u8)
6414 yyval.v.filter_set->type = ACTION_DEL_COMMUNITY;
6415 else
6416 yyval.v.filter_set->type = ACTION_SET_COMMUNITY;
6417
6418 if (parseextcommunity(&yyval.v.filter_set->action.community,
6419 "ovs", yyvsp[0].v.string) == -1) {
6420 free(yyvsp[0].v.string);
6421 free(yyval.v.filter_set);
6422 YYERRORgoto yyerrlab;
6423 }
6424 free(yyvsp[0].v.string);
6425 }
6426break;
6427case 297:
6428#line 2807 "/usr/src/usr.sbin/bgpd/parse.y"
6429{
6430 if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL((void*)0))
6431 fatal(NULL((void*)0));
6432 yyval.v.filter_set->type = ACTION_SET_ORIGIN;
6433 yyval.v.filter_set->action.origin = yyvsp[0].v.number;
6434 }
6435break;
6436case 298:
6437#line 2815 "/usr/src/usr.sbin/bgpd/parse.y"
6438{
6439 if (!strcmp(yyvsp[0].v.string, "egp"))
6440 yyval.v.number = ORIGIN_EGP1;
6441 else if (!strcmp(yyvsp[0].v.string, "igp"))
6442 yyval.v.number = ORIGIN_IGP0;
6443 else if (!strcmp(yyvsp[0].v.string, "incomplete"))
6444 yyval.v.number = ORIGIN_INCOMPLETE2;
6445 else {
6446 yyerror("unknown origin \"%s\"", yyvsp[0].v.string);
6447 free(yyvsp[0].v.string);
6448 YYERRORgoto yyerrlab;
6449 }
6450 free(yyvsp[0].v.string);
6451 }
6452break;
6453case 299:
6454#line 2830 "/usr/src/usr.sbin/bgpd/parse.y"
6455{
6456 if (!strcmp(yyvsp[0].v.string, "not-found"))
6457 yyval.v.number = ROA_NOTFOUND0x0;
6458 else if (!strcmp(yyvsp[0].v.string, "invalid"))
6459 yyval.v.number = ROA_INVALID0x1;
6460 else if (!strcmp(yyvsp[0].v.string, "valid"))
6461 yyval.v.number = ROA_VALID0x2;
6462 else {
6463 yyerror("unknown validity \"%s\"", yyvsp[0].v.string);
6464 free(yyvsp[0].v.string);
6465 YYERRORgoto yyerrlab;
6466 }
6467 free(yyvsp[0].v.string);
6468 }
6469break;
6470case 306:
6471#line 2855 "/usr/src/usr.sbin/bgpd/parse.y"
6472{ yyval.v.u8 = OP_EQ; }
6473break;
6474case 307:
6475#line 2856 "/usr/src/usr.sbin/bgpd/parse.y"
6476{ yyval.v.u8 = OP_NE; }
6477break;
6478case 308:
6479#line 2857 "/usr/src/usr.sbin/bgpd/parse.y"
6480{ yyval.v.u8 = OP_LE; }
6481break;
6482case 309:
6483#line 2858 "/usr/src/usr.sbin/bgpd/parse.y"
6484{ yyval.v.u8 = OP_LT; }
6485break;
6486case 310:
6487#line 2859 "/usr/src/usr.sbin/bgpd/parse.y"
6488{ yyval.v.u8 = OP_GE; }
6489break;
6490case 311:
6491#line 2860 "/usr/src/usr.sbin/bgpd/parse.y"
6492{ yyval.v.u8 = OP_GT; }
6493break;
6494case 312:
6495#line 2863 "/usr/src/usr.sbin/bgpd/parse.y"
6496{ yyval.v.u8 = OP_EQ; }
6497break;
6498case 313:
6499#line 2864 "/usr/src/usr.sbin/bgpd/parse.y"
6500{ yyval.v.u8 = OP_NE; }
6501break;
6502case 314:
6503#line 2867 "/usr/src/usr.sbin/bgpd/parse.y"
6504{ yyval.v.u8 = OP_RANGE; }
6505break;
6506case 315:
6507#line 2868 "/usr/src/usr.sbin/bgpd/parse.y"
6508{ yyval.v.u8 = OP_XRANGE; }
6509break;
6510#line 6503 "parse.c"
6511 }
6512 yyssp -= yym;
6513 yystate = *yyssp;
6514 yyvsp -= yym;
6515 yym = yylhs[yyn];
6516 if (yystate == 0 && yym == 0)
6517 {
6518#if YYDEBUG0
6519 if (yydebug)
6520 printf("%sdebug: after reduction, shifting from state 0 to\
6521 state %d\n", YYPREFIX"yy", YYFINAL1);
6522#endif
6523 yystate = YYFINAL1;
6524 *++yyssp = YYFINAL1;
6525 *++yyvsp = yyval;
6526 if (yychar < 0)
6527 {
6528 if ((yychar = yylex()) < 0) yychar = 0;
6529#if YYDEBUG0
6530 if (yydebug)
6531 {
6532 yys = 0;
6533 if (yychar <= YYMAXTOKEN382) yys = yyname[yychar];
6534 if (!yys) yys = "illegal-symbol";
6535 printf("%sdebug: state %d, reading %d (%s)\n",
6536 YYPREFIX"yy", YYFINAL1, yychar, yys);
6537 }
6538#endif
6539 }
6540 if (yychar == 0) goto yyaccept;
6541 goto yyloop;
6542 }
6543 if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
6544 yyn <= YYTABLESIZE1254 && yycheck[yyn] == yystate)
6545 yystate = yytable[yyn];
6546 else
6547 yystate = yydgoto[yym];
6548#if YYDEBUG0
6549 if (yydebug)
6550 printf("%sdebug: after reduction, shifting from state %d \
6551to state %d\n", YYPREFIX"yy", *yyssp, yystate);
6552#endif
6553 if (yyssp >= yysslim && yygrowstack())
6554 {
6555 goto yyoverflow;
6556 }
6557 *++yyssp = yystate;
6558 *++yyvsp = yyval;
6559 goto yyloop;
6560yyoverflow:
6561 yyerror("yacc stack overflow");
6562yyabort:
6563 if (yyss)
6564 free(yyss);
6565 if (yyvs)
6566 free(yyvs);
6567 yyss = yyssp = NULL((void*)0);
6568 yyvs = yyvsp = NULL((void*)0);
6569 yystacksize = 0;
6570 return (1);
6571yyaccept:
6572 if (yyss)
6573 free(yyss);
6574 if (yyvs)
6575 free(yyvs);
6576 yyss = yyssp = NULL((void*)0);
6577 yyvs = yyvsp = NULL((void*)0);
6578 yystacksize = 0;
6579 return (0);
6580}