GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/bgpd/parse.c Lines: 359 1252 28.7 %
Date: 2017-11-13 Branches: 224 994 22.5 %

Line Branch Exec Source
1
#include <stdlib.h>
2
#include <string.h>
3
#define YYBYACC 1
4
#define YYMAJOR 1
5
#define YYMINOR 9
6
#define YYLEX yylex()
7
#define YYEMPTY -1
8
#define yyclearin (yychar=(YYEMPTY))
9
#define yyerrok (yyerrflag=0)
10
#define YYRECOVERING() (yyerrflag!=0)
11
#define YYPREFIX "yy"
12
#line 25 "parse.y"
13
#include <sys/types.h>
14
#include <sys/socket.h>
15
#include <sys/stat.h>
16
#include <sys/un.h>
17
#include <netinet/in.h>
18
#include <netinet/ip_ipsp.h>
19
#include <arpa/inet.h>
20
#include <netmpls/mpls.h>
21
22
#include <ctype.h>
23
#include <err.h>
24
#include <unistd.h>
25
#include <errno.h>
26
#include <limits.h>
27
#include <stdarg.h>
28
#include <stdio.h>
29
#include <string.h>
30
#include <syslog.h>
31
32
#include "bgpd.h"
33
#include "mrt.h"
34
#include "session.h"
35
#include "rde.h"
36
#include "log.h"
37
38
TAILQ_HEAD(files, file)		 files = TAILQ_HEAD_INITIALIZER(files);
39
static struct file {
40
	TAILQ_ENTRY(file)	 entry;
41
	FILE			*stream;
42
	char			*name;
43
	int			 lineno;
44
	int			 errors;
45
} *file, *topfile;
46
struct file	*pushfile(const char *, int);
47
int		 popfile(void);
48
int		 check_file_secrecy(int, const char *);
49
int		 yyparse(void);
50
int		 yylex(void);
51
int		 yyerror(const char *, ...)
52
    __attribute__((__format__ (printf, 1, 2)))
53
    __attribute__((__nonnull__ (1)));
54
int		 kw_cmp(const void *, const void *);
55
int		 lookup(char *);
56
int		 lgetc(int);
57
int		 lungetc(int);
58
int		 findeol(void);
59
60
TAILQ_HEAD(symhead, sym)	 symhead = TAILQ_HEAD_INITIALIZER(symhead);
61
struct sym {
62
	TAILQ_ENTRY(sym)	 entry;
63
	int			 used;
64
	int			 persist;
65
	char			*nam;
66
	char			*val;
67
};
68
int		 symset(const char *, const char *, int);
69
char		*symget(const char *);
70
71
static struct bgpd_config	*conf;
72
static struct network_head	*netconf;
73
static struct peer		*peer_l, *peer_l_old;
74
static struct peer		*curpeer;
75
static struct peer		*curgroup;
76
static struct rdomain		*currdom;
77
static struct filter_head	*filter_l;
78
static struct filter_head	*peerfilter_l;
79
static struct filter_head	*groupfilter_l;
80
static struct filter_rule	*curpeer_filter[2];
81
static struct filter_rule	*curgroup_filter[2];
82
static u_int32_t		 id;
83
84
struct filter_rib_l {
85
	struct filter_rib_l	*next;
86
	char			 name[PEER_DESCR_LEN];
87
};
88
89
struct filter_peers_l {
90
	struct filter_peers_l	*next;
91
	struct filter_peers	 p;
92
};
93
94
struct filter_prefix_l {
95
	struct filter_prefix_l	*next;
96
	struct filter_prefix	 p;
97
};
98
99
struct filter_prefixlen {
100
	enum comp_ops		op;
101
	int			len_min;
102
	int			len_max;
103
};
104
105
struct filter_as_l {
106
	struct filter_as_l	*next;
107
	struct filter_as	 a;
108
};
109
110
struct filter_match_l {
111
	struct filter_match	 m;
112
	struct filter_prefix_l	*prefix_l;
113
	struct filter_as_l	*as_l;
114
} fmopts;
115
116
struct peer	*alloc_peer(void);
117
struct peer	*new_peer(void);
118
struct peer	*new_group(void);
119
int		 add_mrtconfig(enum mrt_type, char *, int, struct peer *,
120
		    char *);
121
int		 add_rib(char *, u_int, u_int16_t);
122
struct rde_rib	*find_rib(char *);
123
int		 get_id(struct peer *);
124
int		 merge_prefixspec(struct filter_prefix_l *,
125
		    struct filter_prefixlen *);
126
int		 expand_rule(struct filter_rule *, struct filter_rib_l *,
127
		    struct filter_peers_l *, struct filter_match_l *,
128
		    struct filter_set_head *);
129
int		 str2key(char *, char *, size_t);
130
int		 neighbor_consistent(struct peer *);
131
int		 merge_filterset(struct filter_set_head *, struct filter_set *);
132
void		 copy_filterset(struct filter_set_head *,
133
		    struct filter_set_head *);
134
void		 merge_filter_lists(struct filter_head *, struct filter_head *);
135
struct filter_rule	*get_rule(enum action_types);
136
137
int		 getcommunity(char *);
138
int		 parsecommunity(struct filter_community *, char *);
139
int64_t 	 getlargecommunity(char *);
140
int		 parselargecommunity(struct filter_largecommunity *, char *);
141
int		 parsesubtype(char *, int *, int *);
142
int		 parseextvalue(char *, u_int32_t *);
143
int		 parseextcommunity(struct filter_extcommunity *, char *,
144
		    char *);
145
146
typedef struct {
147
	union {
148
		int64_t			 number;
149
		char			*string;
150
		struct bgpd_addr	 addr;
151
		u_int8_t		 u8;
152
		struct filter_rib_l	*filter_rib;
153
		struct filter_peers_l	*filter_peers;
154
		struct filter_match_l	 filter_match;
155
		struct filter_prefix_l	*filter_prefix;
156
		struct filter_as_l	*filter_as;
157
		struct filter_set	*filter_set;
158
		struct filter_set_head	*filter_set_head;
159
		struct {
160
			struct bgpd_addr	prefix;
161
			u_int8_t		len;
162
		}			prefix;
163
		struct filter_prefixlen	prefixlen;
164
		struct {
165
			u_int8_t		enc_alg;
166
			char			enc_key[IPSEC_ENC_KEY_LEN];
167
			u_int8_t		enc_key_len;
168
		}			encspec;
169
	} v;
170
	int lineno;
171
} YYSTYPE;
172
173
#line 174 "parse.c"
174
#define AS 257
175
#define ROUTERID 258
176
#define HOLDTIME 259
177
#define YMIN 260
178
#define LISTEN 261
179
#define ON 262
180
#define FIBUPDATE 263
181
#define FIBPRIORITY 264
182
#define RTABLE 265
183
#define RDOMAIN 266
184
#define RD 267
185
#define EXPORTTRGT 268
186
#define IMPORTTRGT 269
187
#define RDE 270
188
#define RIB 271
189
#define EVALUATE 272
190
#define IGNORE 273
191
#define COMPARE 274
192
#define GROUP 275
193
#define NEIGHBOR 276
194
#define NETWORK 277
195
#define EBGP 278
196
#define IBGP 279
197
#define LOCALAS 280
198
#define REMOTEAS 281
199
#define DESCR 282
200
#define LOCALADDR 283
201
#define MULTIHOP 284
202
#define PASSIVE 285
203
#define MAXPREFIX 286
204
#define RESTART 287
205
#define ANNOUNCE 288
206
#define CAPABILITIES 289
207
#define REFRESH 290
208
#define AS4BYTE 291
209
#define CONNECTRETRY 292
210
#define DEMOTE 293
211
#define ENFORCE 294
212
#define NEIGHBORAS 295
213
#define REFLECTOR 296
214
#define DEPEND 297
215
#define DOWN 298
216
#define DUMP 299
217
#define IN 300
218
#define OUT 301
219
#define SOCKET 302
220
#define RESTRICTED 303
221
#define LOG 304
222
#define ROUTECOLL 305
223
#define TRANSPARENT 306
224
#define TCP 307
225
#define MD5SIG 308
226
#define PASSWORD 309
227
#define KEY 310
228
#define TTLSECURITY 311
229
#define ALLOW 312
230
#define DENY 313
231
#define MATCH 314
232
#define QUICK 315
233
#define FROM 316
234
#define TO 317
235
#define ANY 318
236
#define CONNECTED 319
237
#define STATIC 320
238
#define COMMUNITY 321
239
#define EXTCOMMUNITY 322
240
#define LARGECOMMUNITY 323
241
#define PREFIX 324
242
#define PREFIXLEN 325
243
#define SOURCEAS 326
244
#define TRANSITAS 327
245
#define PEERAS 328
246
#define DELETE 329
247
#define MAXASLEN 330
248
#define MAXASSEQ 331
249
#define SET 332
250
#define LOCALPREF 333
251

168
#define MED 334
252
#define METRIC 335
253
#define NEXTHOP 336
254
#define REJECT 337
255
#define BLACKHOLE 338
256
#define NOMODIFY 339
257
#define SELF 340
258
#define PREPEND_SELF 341
259
#define PREPEND_PEER 342
260
#define PFTABLE 343
261
#define WEIGHT 344
262
#define RTLABEL 345
263
#define ORIGIN 346
264
#define ERROR 347
265
#define INCLUDE 348
266
#define IPSEC 349
267
#define ESP 350
268
#define AH 351
269
#define SPI 352
270
#define IKE 353
271
#define IPV4 354
272
#define IPV6 355
273
#define QUALIFY 356
274
#define VIA 357
275
#define NE 358
276
#define LE 359
277
#define GE 360
278
#define XRANGE 361
279
#define LONGER 362
280
#define STRING 363
281
#define NUMBER 364
282
#define YYERRCODE 256
283
const short yylhs[] =
284
	{                                        -1,
285
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
286
    1,    2,    2,    3,    3,   13,   13,   10,   51,   49,
287
   50,   50,   50,   50,   50,   50,   50,   50,   50,   50,
288
   50,   50,   50,   50,   50,   50,   50,   50,   50,   50,
289
   50,   50,   50,   50,   50,   50,   57,   56,   56,   56,
290
32
   11,   11,   12,   12,   14,   15,   15,   16,   16,   58,
291
   58,   59,    4,    4,   61,   52,   60,   60,   62,   63,
292
   63,   63,   63,   63,   63,   63,   64,   66,   53,   68,
293
   54,   67,   67,   69,   69,   69,   65,   65,   71,   71,
294
   72,   70,   70,   70,   70,   70,   70,   70,   70,   70,
295
32
   70,   70,   70,   70,   70,   70,   70,   70,   70,   70,
296
   70,   70,   70,   70,   70,   70,   70,   70,   70,   70,
297
32
   70,   70,   70,   70,   70,   70,   70,    7,    7,    6,
298
    6,    9,    9,    5,    5,   48,   48,   55,   17,   17,
299
   17,   18,   18,   19,   19,   21,   21,   21,   22,   22,
300
   23,   26,   26,   25,   25,   24,   24,   24,   24,   24,
301
   24,   42,   42,   42,   42,   43,   43,   43,   41,   41,
302
   40,   32,   32,   34,   34,   33,   33,   35,   35,   35,
303
   31,   31,   30,   30,   30,   30,   29,   74,   29,   27,
304
   27,   28,   28,   28,   28,   28,   28,   28,   28,   28,
305
   36,   36,   36,   36,   47,   47,   47,   47,   38,   38,
306
   38,   39,   39,   20,   20,   37,   37,   37,   37,   37,
307
   37,   37,   37,   37,   37,   37,   37,   37,   37,   37,
308
   37,   37,   37,   37,   37,   37,   37,   37,   37,   37,
309
    8,   73,   73,   44,   44,   44,   44,   44,   44,   45,
310
   45,   46,   46,
311
};
312
const short yylen[] =
313
	{                                         2,
314
    0,    2,    3,    3,    3,    3,    3,    3,    3,    3,
315
    1,    1,    1,    1,    1,    2,    1,    1,    3,    2,
316
    2,    3,    2,    2,    3,    3,    2,    2,    2,    3,
317
    5,    5,    7,    2,    2,    1,    4,    6,    1,    3,
318
    3,    4,    4,    2,    2,    3,    5,    3,    5,    4,
319
    1,    1,    1,    0,    1,    3,    3,    1,    1,    2,
320
    0,    2,    0,    1,    0,    8,    2,    1,    2,    2,
321
    3,    3,    2,    2,    1,    3,    0,    0,    5,    0,
322
    8,    2,    1,    2,    2,    2,    4,    0,    2,    1,
323
    2,    2,    2,    3,    2,    2,    2,    1,    1,    2,
324
    2,    2,    3,    3,    3,    3,    3,    3,    2,    2,
325
    3,    3,    3,    4,    4,    3,    8,    2,    2,    7,
326
    1,    1,    2,    3,    2,    2,    2,    0,    2,    1,
327
52
    1,    1,    1,    1,    1,    0,    2,    7,    1,    1,
328
    1,    0,    1,    1,    1,    0,    2,    4,    1,    3,
329
52
    1,    1,    3,    1,    3,    1,    1,    2,    2,    1,
330
    1,    2,    2,    2,    4,    1,    3,    4,    1,    3,
331
    2,    1,    3,    1,    3,    2,    4,    1,    3,    4,
332
    1,    3,    1,    1,    2,    3,    0,    0,    2,    1,
333
    2,    1,    1,    2,    2,    2,    2,    3,    2,    2,
334
    0,    1,    3,    4,    1,    1,    1,    1,    0,    2,
335
    7,    3,    1,    0,    1,    2,    3,    3,    2,    3,
336
    3,    2,    3,    3,    2,    3,    3,    2,    2,    2,
337
    2,    2,    2,    2,    2,    2,    3,    3,    4,    2,
338
    1,    1,    0,    1,    1,    1,    1,    1,    1,    1,
339
    1,    1,    1,
340
};
341
4
const short yydefred[] =
342
	{                                      1,
343
4
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
344
    0,    0,    0,    0,    0,    0,    0,    0,    0,  139,
345
  140,  141,    0,    0,    0,    2,    0,    0,    0,    0,
346
    0,    0,    0,    0,   36,   39,    0,   10,   12,   11,
347
   13,    0,   55,   23,    0,   24,    0,   18,   28,   27,
348
   44,    0,    0,    0,    0,   17,    0,  130,  131,    0,
349
    0,    0,    0,   45,    0,    0,    0,   35,   29,   34,
350
    0,   20,    0,  143,    0,    3,    4,    5,    6,    7,
351
4
    8,    9,    0,   22,   25,   26,    0,    0,    0,    0,
352
   40,   41,   16,    0,    0,    0,  133,  132,    0,    0,
353
4
    0,   48,    0,   51,   52,    0,    0,   53,   46,    0,
354
    0,    0,    0,    0,   58,   59,   78,   60,    0,    0,
355
    0,   42,    0,   56,   57,    0,   50,    0,    0,    0,
356
8
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
357
8
  210,    0,    0,   64,   37,    0,   43,  151,    0,  147,
358
8
  144,  145,    0,    0,   65,    0,   31,   80,   49,  215,
359
96
    0,    0,    0,  216,    0,    0,  219,    0,    0,  222,
360
40
    0,    0,  230,  229,  231,  232,  228,  233,  234,  235,
361
  225,    0,    0,  236,  240,    0,    0,    0,   47,    0,
362
  149,    0,    0,  160,  161,  156,    0,  157,  152,    0,
363
    0,   79,    0,    0,    0,  237,    0,  238,  217,  218,
364
  220,  221,  223,  224,  226,  227,    0,   38,  148,  242,
365
    0,  158,  159,  154,    0,    0,    0,    0,    0,    0,
366
8
    0,    0,    0,    0,   75,    0,   68,    0,   33,    0,
367
    0,    0,    0,    0,    0,    0,    0,   98,    0,    0,
368
8
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
369
8
    0,    0,    0,  121,    0,   83,    0,  239,  213,    0,
370
8
  150,  153,    0,  138,  205,    0,    0,    0,    0,  206,
371
  207,  208,    0,    0,    0,    0,    0,    0,    0,  190,
372
  193,  172,  192,    0,    0,    0,   90,   74,   70,    0,
373
    0,    0,    0,   66,   67,    0,   69,   86,    0,  102,
374
  101,    0,   92,    0,   96,   97,    0,    0,    0,    0,
375
    0,  109,  110,    0,  125,    0,    0,  123,    0,  100,
376
    0,  127,  126,    0,  118,  119,    0,  134,  135,    0,
377
   85,   81,   82,   84,    0,    0,  155,  196,    0,  197,
378
    0,    0,  164,  194,  195,  200,  199,    0,  202,  162,
379
  163,  174,    0,  191,  184,  251,   14,  250,    0,   15,
380
    0,  176,    0,   91,   87,   89,   71,   72,   76,   62,
381
  103,   94,    0,  113,  107,  105,  106,  108,  104,  112,
382
  111,  124,    0,    0,    0,  116,    0,  211,  212,  198,
383
    0,  169,    0,    0,  171,  245,  246,  248,    0,  244,
384
  247,  249,    0,  173,    0,    0,  181,    0,    0,  253,
385
  252,    0,  185,  129,    0,    0,    0,    0,    0,    0,
386
  165,    0,  203,  175,    0,    0,  177,  186,    0,    0,
387
    0,  170,  204,    0,  182,    0,    0,  168,  180,  120,
388
    0,    0,  117,  137,
389
12
};
390
12
const short yydgoto[] =
391
	{                                       1,
392
  370,   42,  371,  145,  340,   62,  384,  185,  100,   49,
393
12
  107,  109,   57,  198,  352,  117,   27,   75,  153,  161,
394
  113,  190,  150,  199,  225,  200,  289,  290,  226,  417,
395
12
  418,  291,  292,  363,  419,  360,  269,  102,  270,  402,
396
  403,  293,  404,  413,  373,  422,  294,  453,   28,   29,
397
   30,   31,  263,   33,   34,  235,  264,   88,  307,  236,
398
  203,  237,  238,   37,  202,  154,  265,  205,  266,  267,
399
  296,  297,  346,  227,
400
4
};
401
const short yysindex[] =
402
	{                                      0,
403
  144,   59, -251, -290, -229, -182, -274, -271, -268, -227,
404
4
 -237, -236, -264, -225, -235, -234, -212, -274, -274,    0,
405
    0,    0, -192, -210,   98,    0, -146,  157,  169,  171,
406
4
  176,  184,  186,  202,    0,    0,  -50,    0,    0,    0,
407
    0, -136,    0,    0, -129,    0, -290,    0,    0,    0,
408
    0,  208, -127,  -36, -111,    0,   -3,    0,    0,  193,
409
  194, -163,  -85,    0, -112, -217,  -51,    0,    0,    0,
410
 -101,    0, -236,    0,  -17,    0,    0,    0,    0,    0,
411
    0,    0, -180,    0,    0,    0,  208,  132, -238,  -92,
412
    0,    0,    0,  149,  -91,  -90,    0,    0,  -81,  -85,
413
  195,    0,  -80,    0,    0,  -89,  -76,    0,    0,  -75,
414
  -74,  -97, -126,  193,    0,    0,    0,    0,  208,  -84,
415
    4,    0,  208,    0,    0,  -85,    0,  -38,  -38,  -38,
416
  -39,  -34,  -33,  -94,  -69,  -66,  -73,  -30,  -67, -236,
417
    0,  188,  -64,    0,    0,  -89,    0,    0,  -62,    0,
418
    0,    0,  -86,  197,    0,   31,    0,    0,    0,    0,
419
  -54,  -47,  -28,    0,  -31,  -27,    0,  -21,  -20,    0,
420
  -13,  -12,    0,    0,    0,    0,    0,    0,    0,    0,
421
    0,  -11,   11,    0,    0,  -74,  208,  -89,    0,   -6,
422
    0, -251,    1,    0,    0,    0, -232,    0,    0,    0,
423
  208,    0,  605, -274,  610,    0,   17,    0,    0,    0,
424
    0,    0,    0,    0,    0,    0,  675,    0,    0,    0,
425
  -62,    0,    0,    0,   -2,  -85,  227,  642, -274,   22,
426
   23,   24, -236,  115,    0,  -68,    0,  371,    0,  371,
427
 -228,   25, -251, -251, -236, -290,   19,    0,   27,  -70,
428
   29, -203, -290,  122,   32,   34,   43, -274,   85, -274,
429
  195, -153,  371,    0,  470,    0,  371,    0,    0,   58,
430
    0,    0, -232,    0,    0,   48,   50,   52, -103,    0,
431
    0,    0,   40,   53, -243, -240, -240, -154,  227,    0,
432
    0,    0,    0,  -58,  371,  502,    0,    0,    0,   55,
433
   57,  -74,   60,    0,    0,  208,    0,    0,   61,    0,
434
    0, -136,    0,  -74,    0,    0,  107, -274, -274, -274,
435
 -274,    0,    0,   64,    0, -274, -274,    0,   66,    0,
436
  -98,    0,    0, -102,    0,    0,  293,    0,    0, -206,
437
    0,    0,    0,    0,  297,  675,    0,    0,   67,    0,
438
  -99, -240,    0,    0,    0,    0,    0,   10,    0,    0,
439
    0,    0,    7,    0,    0,    0,    0,    0,  -56,    0,
440
  -29,    0, -148,    0,    0,    0,    0,    0,    0,    0,
441
    0,    0,   68,    0,    0,    0,    0,    0,    0,    0,
442
    0,    0, -236, -236,  208,    0,   72,    0,    0,    0,
443
 -140,    0,  387,  308,    0,    0,    0,    0,  -29,    0,
444
    0,    0,   70,    0, -154,   77,    0,  387,  312,    0,
445
    0, -148,    0,    0,  -74,  -74,  675,   74,   20, -140,
446
    0,   78,    0,    0,   30,   77,    0,    0,   58,   84,
447
  -99,    0,    0,  -56,    0,  326,   89,    0,    0,    0,
448
   90,   91,    0,    0,};
449
const short yyrindex[] =
450
	{                                      0,
451
  179,    0,    0,    0,    0,    0,    0,    0,    0,    0,
452
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
453
    0,    0,    0,    0,    0,    0, -208,    0,    0,    0,
454
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
455
    0,  449,    0,    0,    0,    0,    0,    0,    0,    0,
456
    0,  341,    0,    0,    0,    0,  341,    0,    0,    0,
457
    0,    0,  458,    0,    0,    0,  462,    0,    0,    0,
458
    0,    0,    0,    0, -106,    0,    0,    0,    0,    0,
459
    0,    0,    0,    0,    0,    0,  303,    0,  463,    0,
460
    0,    0,    0,    0,    0,    0,    0,    0,    0,  458,
461
  341,    0,    0,    0,    0,  464,    0,    0,    0,    0,
462
  478,    0,    0,   18,    0,    0,    0,    0,  689,    0,
463
    0,    0,  556,    0,    0,  458,    0,  126,  126,  126,
464
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
465
    0,    0,    0,    0,    0,  464,    0,    0,    0,    0,
466
    0,    0,    0,  480,    0,  485,    0,    0,    0,    0,
467
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
468
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
469
    0,    0,    0,    0,    0,  178,  691,  464,    0,  133,
470
    0,    0,    0,    0,    0,    0,    0,    0,    0,  139,
471
  696,    0,    0,    0,  179,    0,    0,    0,    0,    0,
472
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
473
    0,    0,    0,    0, -197,  458,    0,    0,    0,    0,
474
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
475
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
476
    0,    0,  487,    0,  488,    0,    0,    0,    0,    0,
477
  341,    0,    0,    0,  179,    0,    0,    0,    0,  379,
478
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
479
    0,    0,    0,    0,    0,  155,  155,    0,   -8,    0,
480
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
481
    0,  492,    0,    0,    0,  400,    0,    0,    0,    0,
482
    0,  493,    0,  495,    0,    0,  496,    0,    0,    0,
483
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
484
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
485
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
486
    0,   35,    0,    0,    0,    0,    0,    0,    0,    0,
487
    0,    0, -151,    0,    0,    0,    0,    0,    0,    0,
488
   -9,    0,    0,    0,    0,    0,    0,    0,    0,    0,
489
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
490
    0,    0,    0,    0,  691,    0,    0,    0,    0,    0,
491
    0,    0,  -96,    0,    0,    0,    0,    0,    0,    0,
492
    0,    0,    0,    0,    0,    0,    0,   15,    0,    0,
493
    0,    0,    0,    0,  498,  505,    0,    0, -133,    0,
494
    0,    0,    0,    0,   81,    0,    0,    0,  379,    0,
495
  401,    0,    0,  402,    0,    0,    0,    0,    0,    0,
496
  522,    0,    0,    0,};
497
const short yygindex[] =
498
	{                                      0,
499
   14, -139, -315,  -87,    0,  283,    0,    0,    0,   21,
500
  203,    0,  -65,   51,   41,    0,    0,    0,    0,  104,
501
    0,    0,  -88, -156,    0,    0,    0,  245,    0, -273,
502
  119,    0, -265,    0,  100, -200,  -83,  -78,  118, -260,
503
  141,    0,  105,    0,    0,  138,    0,    0,    0,    0,
504
    0,    0,  551,    0,    0,  555,  559,  -57, -152,    0,
505
    0,  325,    0,    0,    0,    0,    0,    0,  299, -178,
506
    0,  269, -176,    0,
507
};
508
#define YYTABLESIZE 1045
509
const short yytable[] =
510
	{                                      94,
511
  183,  189,  368,  165,  368,  166,   87,  111,  168,  171,
512
  169,  172,  182,  221,  183,  421,   41,  141,  353,  351,
513
  372,  127,  362,  401,  192,  149,  120,   55,  166,  118,
514
   45,  309,  356,   53,  183,   65,  197,  220,   69,   70,
515
  224,  220,  193,  142,  201,  194,  195,  159,  273,  295,
516
  220,  183,  222,   63,   44,   84,  304,  423,  189,  243,
517
  191,  155,  142,  220,  369,  158,  416,   87,   38,  411,
518
  410,  412,   43,  220,  186,  243,  326,  243,  201,   47,
519
  243,  243,  104,  105,  358,  196,  361,  308,   48,   58,
520
   59,  327,   50,  104,  105,   51,   54,   86,   60,   61,
521
  218,  220,  275,  312,  313,  243,  438,  142,  142,  121,
522
  341,   39,   40,  183,  344,  183,  347,  295,  219,   43,
523
  243,  359,  272,  116,   48,   55,   56,   66,   67,  217,
524
   43,  414,  271,  115,   46,  310,   52,  368,   64,  178,
525
   55,  243,  374,  228,  441,  106,  396,  274,  187,  434,
526
   68,  405,   72,   26,  444,   97,   98,  201,   73,  201,
527
   91,   92,  445,   71,  201,  243,   76,  302,   74,  442,
528
  192,  280,  281,  282,  243,  243,  243,  336,   77,  314,
529
   78,   99,  114,   61,  177,   79,  415,  241,  193,  151,
530
  152,  194,  195,   80,  229,   81,  338,  339,  230,  231,
531
  232,  104,  105,  337,   87,   41,  393,  394,   13,  146,
532
  146,   82,  345,  233,  367,   40,  318,   87,  319,  320,
533
  321,  241,   60,   61,  239,   83,  430,   40,  234,  243,
534
  243,  196,  162,  163,   85,   89,  365,   90,  365,   95,
535
   96,  436,  173,  174,  175,  176,  101,  183,  380,  298,
536
  103,  108,  430,  112,  119,  110,   41,   41,  436,   60,
537
   61,  188,  399,   60,   61,  148,  243,  243,   43,  322,
538
  122,  123,  124,  125,  144,  157,   43,  201,  333,  156,
539
  335,  126,  143,   58,   59,  183,  146,  147,   93,  180,
540
  160,  201,  323,  204,  178,  184,  315,  179,  188,  366,
541
  148,  366,  241,  328,  367,   40,  367,   40,  206,  243,
542
  187,  183,  183,  183,  183,  207,  183,  183,  183,  201,
543
  183,  183,  183,  189,  164,  382,  183,  425,  426,  167,
544
  170,  420,  209,  181,  208,  357,  210,  427,  385,  386,
545
  387,  388,  211,  212,  183,  183,  390,  391,  183,  288,
546
  213,  214,  215,  183,  183,  201,  201,  201,  201,   93,
547
  201,  201,  201,  223,  201,  201,  201,  406,  407,  408,
548
  201,  365,  243,  409,  216,  243,  303,  243,  243,  268,
549
  306,  446,  316,  329,  299,  300,  301,  311,  201,  201,
550
  317,  325,  334,  383,  330,  188,  331,  201,  201,    2,
551
    3,    4,    5,  354,    6,  332,    7,    8,    9,   10,
552
  348,  201,  349,   11,  350,  395,  355,  377,   12,  378,
553
   13,  398,  379,  428,  381,   61,  389,   61,  392,  400,
554
  220,  424,  431,  433,  366,   14,  437,  440,  243,  367,
555
   40,  443,   15,  243,  243,   16,  447,   17,   18,   19,
556
  450,  451,  452,  454,   77,   20,   21,   22,   21,  188,
557
  188,  188,  188,   61,  188,  188,  188,  209,  188,  188,
558
  187,   54,   30,   63,  188,  201,  201,  201,  201,   23,
559
  201,  201,  201,  275,  201,  201,  201,   19,  214,   88,
560
  201,   24,  188,  188,   32,  243,  122,   99,  241,  241,
561
  241,   73,   93,   61,   95,  128,   25,  114,  201,  201,
562
  241,  241,  241,  241,  115,  128,  129,  130,  241,  241,
563
  241,  241,  241,  241,   61,  167,  179,  131,  132,  133,
564
  134,  136,  324,  364,  435,  135,  136,  137,  138,  139,
565
  140,  429,  397,  449,  439,  448,  432,  276,  277,  278,
566
  279,   32,  280,  281,  282,   35,  283,  284,   61,   36,
567
  305,   61,  285,  343,  376,   61,    0,    0,    0,   61,
568
   61,   61,    0,   61,    0,    0,    0,    0,   61,   61,
569
  286,  287,   61,   61,   61,   61,   61,   61,   61,    0,
570
   61,    0,    0,    0,  342,   61,   61,    0,   61,   61,
571
   61,   61,    0,    0,    0,    0,   61,    0,   61,   61,
572
    0,    0,    0,   61,    0,    0,    0,    0,    0,    0,
573
    0,    0,    0,   61,   61,   61,  375,    0,    0,    0,
574
    0,    0,    0,    0,   61,   61,   61,   61,   61,    0,
575
    0,    0,    0,   61,   61,   61,   61,   61,   61,    0,
576
    0,   61,    0,    0,    0,   61,    0,    0,   61,    0,
577
    0,    0,   61,    0,    0,    0,   61,   61,   61,    0,
578
   61,    0,    0,    0,    0,   61,   61,    0,    0,   61,
579
   61,   61,   61,   61,   61,   61,    0,   61,    0,    0,
580
    0,    0,   61,   61,    0,   61,   61,   61,   61,  243,
581
  243,  243,    0,   61,    0,   61,   61,    0,    0,    0,
582
   61,  243,  243,  243,  243,    0,    0,    0,    0,  243,
583
  243,  243,  243,  243,  243,  240,    0,    0,  241,    0,
584
    0,   61,    0,    0,    0,    0,    0,    0,    0,    0,
585
  242,    0,    0,    0,    0,    0,    0,    0,   61,  243,
586
  244,  245,  246,  247,  248,  249,    0,  250,    0,    0,
587
  241,    0,  251,  252,    0,  253,  254,  255,  256,    0,
588
    0,    0,  242,  257,    0,  258,  259,    0,    0,    0,
589
  260,  243,  244,  245,  246,  247,  248,  249,    0,  250,
590
    0,    0,    0,    0,  251,  252,    0,  253,  254,  255,
591
  256,  261,    0,    0,    0,  257,    0,  258,  259,    0,
592
    0,   61,  260,    0,   61,    0,    0,    0,  262,    0,
593
    0,    0,    0,    0,    0,    0,   61,    0,    0,    0,
594
    0,   61,    0,  261,    0,   61,   61,   61,   61,   61,
595
   61,   61,    0,   61,    0,    0,    0,    0,   61,   61,
596
  262,   61,   61,   61,   61,    0,    0,    0,    0,   61,
597
    0,   61,   61,    0,    0,  240,   61,  229,  241,    0,
598
    0,  230,  231,  232,    0,    0,    0,    0,    0,    0,
599
  242,   13,    0,    0,    0,    0,  233,   61,    0,  243,
600
  244,  245,  246,  247,  248,  249,    0,  250,    0,    0,
601
  241,  234,  251,  252,   61,  253,  254,  255,  256,    0,
602
    0,    0,  242,  257,    0,  258,  259,    0,    0,    0,
603
  260,  243,  244,  245,  246,  247,  248,  249,    0,  250,
604
    0,    0,    0,    0,  251,  252,    0,  253,  254,  255,
605
  256,  261,    0,    0,    0,  257,    0,  258,  259,    0,
606
    0,   61,  260,    0,   61,   61,   61,   61,  262,    0,
607
    0,    0,    0,    0,    0,   61,   61,    0,    0,    0,
608
   61,    0,    0,  261,    0,   61,   61,   61,   61,   61,
609
   61,   61,    0,   61,    0,   61,    0,    0,   61,   61,
610
  262,   61,   61,   61,   61,  128,  129,  130,    0,   61,
611
    0,   61,   61,    0,    0,    0,   61,  131,  132,  133,
612
  134,   61,   61,   61,    0,  135,  136,  137,  138,  139,
613
  140,    0,    0,   61,   61,   61,   61,   61,    0,    0,
614
    0,   61,   61,   61,   61,   61,   61,    0,    0,    0,
615
    0,    0,    0,    0,   61,
616
};
617
const short yycheck[] =
618
	{                                      57,
619
   10,   10,   61,   43,   61,   45,   10,   73,   43,   43,
620
   45,   45,   43,  190,   45,   45,    3,  101,  279,  123,
621
  294,  100,  288,  123,  257,  123,  265,   10,  125,   87,
622
  260,  260,  276,  271,   44,  271,  123,   44,   18,   19,
623
  197,   44,  275,  101,   10,  278,  279,  126,  225,  228,
624
   44,   61,  192,   13,    4,   42,  125,  373,  146,  257,
625
  149,  119,  271,   44,  123,  123,  123,   10,   10,   60,
626
   61,   62,  363,   44,  140,   61,  280,  275,   44,  262,
627
  278,  279,  300,  301,  325,  318,  287,  240,  363,  354,
628
  355,  295,  364,  300,  301,  364,  334,   47,  363,  364,
629
  188,   44,  257,  243,  244,  257,  422,  316,  317,   89,
630
  263,  363,  364,  123,  267,  125,  273,  296,  125,  363,
631
  318,  362,  125,   83,  363,  363,  363,  363,  363,  187,
632
  363,  125,  221,   83,  364,  364,  364,   61,  364,  125,
633
  123,   61,  295,  201,  125,  363,  353,  226,   10,  415,
634
  363,  352,  363,   10,  125,  319,  320,  123,   61,  125,
635
  272,  273,  436,  356,   10,  363,   10,  233,  315,  430,
636
  257,  326,  327,  328,  326,  327,  328,  261,   10,  245,
637
   10,  345,  363,  364,  134,   10,  363,   10,  275,  316,
638
  317,  278,  279,   10,  263,   10,  350,  351,  267,  268,
639
  269,  300,  301,  261,   10,  192,  309,  310,  277,  316,
640
  317,   10,  270,  282,  363,  364,  287,   10,  289,  290,
641
  291,   44,  363,  364,  204,  276,  403,  364,  297,  363,
642
  364,  318,  129,  130,  364,  363,  295,  274,  295,   47,
643
   47,  418,  337,  338,  339,  340,  332,  257,  306,  229,
644
  363,  303,  429,  271,  123,  357,  243,  244,  435,  363,
645
  364,  123,  346,  363,  364,  363,  363,  364,  363,  340,
646
  363,  123,  364,  364,  364,  272,  363,  123,  258,  364,
647
  260,  363,  363,  354,  355,  295,  363,  363,  363,  363,
648
  329,  257,  363,  263,  364,  363,  246,  364,  363,  358,
649
  363,  358,  125,  253,  363,  364,  363,  364,  363,  295,
650
  123,  321,  322,  323,  324,  363,  326,  327,  328,  123,
651
  330,  331,  332,  332,  364,  312,  336,  393,  394,  364,
652
  364,  361,  364,  364,  363,  285,  364,  395,  318,  319,
653
  320,  321,  364,  364,  354,  355,  326,  327,  358,  123,
654
  364,  364,  364,  363,  364,  321,  322,  323,  324,  363,
655
  326,  327,  328,  363,  330,  331,  332,  358,  359,  360,
656
  336,  295,  358,  364,  364,  295,  262,  363,  364,  363,
657
   10,  439,  364,  262,  363,  363,  363,  363,  354,  355,
658
  364,  363,  308,  287,  363,  257,  363,  363,  364,  256,
659
  257,  258,  259,  364,  261,  363,  263,  264,  265,  266,
660
  363,  257,  363,  270,  363,  123,  364,  363,  275,  363,
661
  277,  125,  363,  352,  364,  123,  363,  125,  363,  363,
662
   44,  364,  125,  364,  358,  292,  125,  364,  358,  363,
663
  364,  364,  299,  363,  364,  302,  363,  304,  305,  306,
664
  125,  363,  363,  363,  276,  312,  313,  314,   10,  321,
665
  322,  323,  324,  123,  326,  327,  328,   10,  330,  331,
666
  332,   10,   10,   10,  336,  321,  322,  323,  324,  336,
667
  326,  327,  328,  257,  330,  331,  332,   10,  363,   10,
668
  336,  348,  354,  355,   10,  363,   10,   10,  321,  322,
669
  323,   10,   10,  125,   10,   10,  363,   10,  354,  355,
670
  333,  334,  335,  336,   10,  321,  322,  323,  341,  342,
671
  343,  344,  345,  346,  125,  125,  125,  333,  334,  335,
672
  336,   10,  250,  289,  416,  341,  342,  343,  344,  345,
673
  346,  401,  340,  444,  427,  441,  409,  321,  322,  323,
674
  324,    1,  326,  327,  328,    1,  330,  331,  256,    1,
675
  236,  259,  336,  265,  296,  263,   -1,   -1,   -1,  267,
676
  268,  269,   -1,  271,   -1,   -1,   -1,   -1,  276,  277,
677
  354,  355,  280,  281,  282,  283,  284,  285,  286,   -1,
678
  288,   -1,   -1,   -1,  125,  293,  294,   -1,  296,  297,
679
  298,  299,   -1,   -1,   -1,   -1,  304,   -1,  306,  307,
680
   -1,   -1,   -1,  311,   -1,   -1,   -1,   -1,   -1,   -1,
681
   -1,   -1,   -1,  321,  322,  323,  125,   -1,   -1,   -1,
682
   -1,   -1,   -1,   -1,  332,  333,  334,  335,  336,   -1,
683
   -1,   -1,   -1,  341,  342,  343,  344,  345,  346,   -1,
684
   -1,  349,   -1,   -1,   -1,  256,   -1,   -1,  259,   -1,
685
   -1,   -1,  263,   -1,   -1,   -1,  267,  268,  269,   -1,
686
  271,   -1,   -1,   -1,   -1,  276,  277,   -1,   -1,  280,
687
  281,  282,  283,  284,  285,  286,   -1,  288,   -1,   -1,
688
   -1,   -1,  293,  294,   -1,  296,  297,  298,  299,  321,
689
  322,  323,   -1,  304,   -1,  306,  307,   -1,   -1,   -1,
690
  311,  333,  334,  335,  336,   -1,   -1,   -1,   -1,  341,
691
  342,  343,  344,  345,  346,  256,   -1,   -1,  259,   -1,
692
   -1,  332,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
693
  271,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  349,  280,
694
  281,  282,  283,  284,  285,  286,   -1,  288,   -1,   -1,
695
  259,   -1,  293,  294,   -1,  296,  297,  298,  299,   -1,
696
   -1,   -1,  271,  304,   -1,  306,  307,   -1,   -1,   -1,
697
  311,  280,  281,  282,  283,  284,  285,  286,   -1,  288,
698
   -1,   -1,   -1,   -1,  293,  294,   -1,  296,  297,  298,
699
  299,  332,   -1,   -1,   -1,  304,   -1,  306,  307,   -1,
700
   -1,  256,  311,   -1,  259,   -1,   -1,   -1,  349,   -1,
701
   -1,   -1,   -1,   -1,   -1,   -1,  271,   -1,   -1,   -1,
702
   -1,  276,   -1,  332,   -1,  280,  281,  282,  283,  284,
703
  285,  286,   -1,  288,   -1,   -1,   -1,   -1,  293,  294,
704
  349,  296,  297,  298,  299,   -1,   -1,   -1,   -1,  304,
705
   -1,  306,  307,   -1,   -1,  256,  311,  263,  259,   -1,
706
   -1,  267,  268,  269,   -1,   -1,   -1,   -1,   -1,   -1,
707
  271,  277,   -1,   -1,   -1,   -1,  282,  332,   -1,  280,
708
  281,  282,  283,  284,  285,  286,   -1,  288,   -1,   -1,
709
  259,  297,  293,  294,  349,  296,  297,  298,  299,   -1,
710
   -1,   -1,  271,  304,   -1,  306,  307,   -1,   -1,   -1,
711
  311,  280,  281,  282,  283,  284,  285,  286,   -1,  288,
712
   -1,   -1,   -1,   -1,  293,  294,   -1,  296,  297,  298,
713
  299,  332,   -1,   -1,   -1,  304,   -1,  306,  307,   -1,
714
   -1,  263,  311,   -1,  259,  267,  268,  269,  349,   -1,
715
   -1,   -1,   -1,   -1,   -1,  277,  271,   -1,   -1,   -1,
716
  282,   -1,   -1,  332,   -1,  280,  281,  282,  283,  284,
717
  285,  286,   -1,  288,   -1,  297,   -1,   -1,  293,  294,
718
  349,  296,  297,  298,  299,  321,  322,  323,   -1,  304,
719
   -1,  306,  307,   -1,   -1,   -1,  311,  333,  334,  335,
720
  336,  321,  322,  323,   -1,  341,  342,  343,  344,  345,
721
  346,   -1,   -1,  333,  334,  335,  336,  332,   -1,   -1,
722
   -1,  341,  342,  343,  344,  345,  346,   -1,   -1,   -1,
723
   -1,   -1,   -1,   -1,  349,
724
};
725
#define YYFINAL 1
726
#ifndef YYDEBUG
727
#define YYDEBUG 0
728
#endif
729
#define YYMAXTOKEN 364
730
#if YYDEBUG
731
const char * const yyname[] =
732
	{
733
"end-of-file",0,0,0,0,0,0,0,0,0,"'\\n'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
734
0,0,0,0,0,0,0,0,0,0,0,0,"'+'","','","'-'",0,"'/'",0,0,0,0,0,0,0,0,0,0,0,0,"'<'",
735
"'='","'>'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
736
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'{'",0,"'}'",0,0,0,0,0,0,0,
737
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
738
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
739
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
740
4
0,0,0,0,"AS","ROUTERID","HOLDTIME","YMIN","LISTEN","ON","FIBUPDATE",
741
8
"FIBPRIORITY","RTABLE","RDOMAIN","RD","EXPORTTRGT","IMPORTTRGT","RDE","RIB",
742
4
"EVALUATE","IGNORE","COMPARE","GROUP","NEIGHBOR","NETWORK","EBGP","IBGP",
743
"LOCALAS","REMOTEAS","DESCR","LOCALADDR","MULTIHOP","PASSIVE","MAXPREFIX",
744
"RESTART","ANNOUNCE","CAPABILITIES","REFRESH","AS4BYTE","CONNECTRETRY","DEMOTE",
745
"ENFORCE","NEIGHBORAS","REFLECTOR","DEPEND","DOWN","DUMP","IN","OUT","SOCKET",
746
"RESTRICTED","LOG","ROUTECOLL","TRANSPARENT","TCP","MD5SIG","PASSWORD","KEY",
747
"TTLSECURITY","ALLOW","DENY","MATCH","QUICK","FROM","TO","ANY","CONNECTED",
748
"STATIC","COMMUNITY","EXTCOMMUNITY","LARGECOMMUNITY","PREFIX","PREFIXLEN",
749
52
"SOURCEAS","TRANSITAS","PEERAS","DELETE","MAXASLEN","MAXASSEQ","SET",
750
"LOCALPREF","MED","METRIC","NEXTHOP","REJECT","BLACKHOLE","NOMODIFY","SELF",
751
52
"PREPEND_SELF","PREPEND_PEER","PFTABLE","WEIGHT","RTLABEL","ORIGIN","ERROR",
752
"INCLUDE","IPSEC","ESP","AH","SPI","IKE","IPV4","IPV6","QUALIFY","VIA","NE",
753
"LE","GE","XRANGE","LONGER","STRING","NUMBER",
754
};
755
const char * const yyrule[] =
756
	{"$accept : grammar",
757
52
"grammar :",
758
"grammar : grammar '\\n'",
759

104
"grammar : grammar include '\\n'",
760
52
"grammar : grammar conf_main '\\n'",
761
"grammar : grammar varset '\\n'",
762
"grammar : grammar rdomain '\\n'",
763
"grammar : grammar neighbor '\\n'",
764
"grammar : grammar group '\\n'",
765
"grammar : grammar filterrule '\\n'",
766
104
"grammar : grammar error '\\n'",
767
"asnumber : NUMBER",
768
"as4number : STRING",
769
"as4number : asnumber",
770
100
"as4number_any : STRING",
771
"as4number_any : asnumber",
772

200
"string : string STRING",
773
"string : STRING",
774
"yesno : STRING",
775
"varset : STRING '=' string",
776
"include : INCLUDE STRING",
777
100
"conf_main : AS as4number",
778
"conf_main : AS as4number asnumber",
779
100
"conf_main : ROUTERID address",
780
"conf_main : HOLDTIME NUMBER",
781
100
"conf_main : HOLDTIME YMIN NUMBER",
782
"conf_main : LISTEN ON address",
783
"conf_main : FIBPRIORITY NUMBER",
784
"conf_main : FIBUPDATE yesno",
785
"conf_main : ROUTECOLL yesno",
786
100
"conf_main : RDE RIB STRING",
787
200
"conf_main : RDE RIB STRING yesno EVALUATE",
788
"conf_main : RDE RIB STRING RTABLE NUMBER",
789
"conf_main : RDE RIB STRING RTABLE NUMBER FIBUPDATE yesno",
790
"conf_main : TRANSPARENT yesno",
791
"conf_main : LOG STRING",
792
"conf_main : network",
793
"conf_main : DUMP STRING STRING optnumber",
794
"conf_main : DUMP RIB STRING STRING STRING optnumber",
795
"conf_main : mrtdump",
796
"conf_main : RDE STRING EVALUATE",
797
"conf_main : RDE STRING IGNORE",
798
"conf_main : RDE MED COMPARE STRING",
799
"conf_main : NEXTHOP QUALIFY VIA STRING",
800
"conf_main : RTABLE NUMBER",
801
"conf_main : CONNECTRETRY NUMBER",
802
"conf_main : SOCKET STRING restricted",
803
"mrtdump : DUMP STRING inout STRING optnumber",
804
"network : NETWORK prefix filter_set",
805
"network : NETWORK family RTLABEL STRING filter_set",
806
"network : NETWORK family nettype filter_set",
807
"inout : IN",
808
"inout : OUT",
809
28
"restricted : RESTRICTED",
810
28
"restricted :",
811
"address : STRING",
812
"prefix : STRING '/' NUMBER",
813
"prefix : NUMBER '/' NUMBER",
814
"addrspec : address",
815
28
"addrspec : prefix",
816
"optnl : '\\n' optnl",
817
"optnl :",
818
"nl : '\\n' optnl",
819
"optnumber :",
820
"optnumber : NUMBER",
821
"$$1 :",
822
"rdomain : RDOMAIN NUMBER optnl '{' optnl $$1 rdomainopts_l '}'",
823
"rdomainopts_l : rdomainopts_l rdomainoptsl",
824
"rdomainopts_l : rdomainoptsl",
825
"rdomainoptsl : rdomainopts nl",
826
"rdomainopts : RD STRING",
827
"rdomainopts : EXPORTTRGT STRING STRING",
828
"rdomainopts : IMPORTTRGT STRING STRING",
829
"rdomainopts : DESCR string",
830
"rdomainopts : FIBUPDATE yesno",
831
"rdomainopts : network",
832
"rdomainopts : DEPEND ON STRING",
833
"$$2 :",
834
"$$3 :",
835
"neighbor : $$2 NEIGHBOR addrspec $$3 peeropts_h",
836
"$$4 :",
837
"group : GROUP string optnl '{' optnl $$4 groupopts_l '}'",
838
"groupopts_l : groupopts_l groupoptsl",
839
"groupopts_l : groupoptsl",
840
"groupoptsl : peeropts nl",
841
"groupoptsl : neighbor nl",
842
"groupoptsl : error nl",
843
"peeropts_h : '{' optnl peeropts_l '}'",
844
"peeropts_h :",
845
"peeropts_l : peeropts_l peeroptsl",
846
"peeropts_l : peeroptsl",
847
"peeroptsl : peeropts nl",
848
"peeropts : REMOTEAS as4number",
849
"peeropts : LOCALAS as4number",
850
"peeropts : LOCALAS as4number asnumber",
851
"peeropts : DESCR string",
852
"peeropts : LOCALADDR address",
853
"peeropts : MULTIHOP NUMBER",
854
"peeropts : PASSIVE",
855
"peeropts : DOWN",
856
"peeropts : DOWN STRING",
857
"peeropts : RIB STRING",
858
"peeropts : HOLDTIME NUMBER",
859
"peeropts : HOLDTIME YMIN NUMBER",
860
"peeropts : ANNOUNCE family STRING",
861
"peeropts : ANNOUNCE CAPABILITIES yesno",
862
"peeropts : ANNOUNCE REFRESH yesno",
863
"peeropts : ANNOUNCE RESTART yesno",
864
"peeropts : ANNOUNCE AS4BYTE yesno",
865
"peeropts : ANNOUNCE SELF",
866
"peeropts : ANNOUNCE STRING",
867
"peeropts : ENFORCE NEIGHBORAS yesno",
868
"peeropts : ENFORCE LOCALAS yesno",
869
"peeropts : MAXPREFIX NUMBER restart",
870
"peeropts : TCP MD5SIG PASSWORD string",
871
"peeropts : TCP MD5SIG KEY string",
872
"peeropts : IPSEC espah IKE",
873
"peeropts : IPSEC espah inout SPI NUMBER STRING STRING encspec",
874
"peeropts : TTLSECURITY yesno",
875
"peeropts : SET filter_set_opt",
876
"peeropts : SET optnl '{' optnl filter_set_l optnl '}'",
877
"peeropts : mrtdump",
878
"peeropts : REFLECTOR",
879
"peeropts : REFLECTOR address",
880
"peeropts : DEPEND ON STRING",
881
"peeropts : DEMOTE STRING",
882
"peeropts : TRANSPARENT yesno",
883
"peeropts : LOG STRING",
884
"restart :",
885
"restart : RESTART NUMBER",
886
"family : IPV4",
887
"family : IPV6",
888
"nettype : STATIC",
889
"nettype : CONNECTED",
890
"espah : ESP",
891
"espah : AH",
892
"encspec :",
893
"encspec : STRING STRING",
894
"filterrule : action quick filter_rib_h direction filter_peer_h filter_match_h filter_set",
895
"action : ALLOW",
896
"action : DENY",
897
"action : MATCH",
898
"quick :",
899
"quick : QUICK",
900
"direction : FROM",
901
"direction : TO",
902
"filter_rib_h :",
903
"filter_rib_h : RIB filter_rib",
904
"filter_rib_h : RIB '{' filter_rib_l '}'",
905
"filter_rib_l : filter_rib",
906
"filter_rib_l : filter_rib_l comma filter_rib",
907
"filter_rib : STRING",
908
"filter_peer_h : filter_peer",
909
"filter_peer_h : '{' filter_peer_l '}'",
910
"filter_peer_l : filter_peer",
911
"filter_peer_l : filter_peer_l comma filter_peer",
912
"filter_peer : ANY",
913
"filter_peer : address",
914
"filter_peer : AS as4number",
915
"filter_peer : GROUP STRING",
916
"filter_peer : EBGP",
917
"filter_peer : IBGP",
918
"filter_prefix_h : IPV4 prefixlenop",
919
"filter_prefix_h : IPV6 prefixlenop",
920
"filter_prefix_h : PREFIX filter_prefix",
921
"filter_prefix_h : PREFIX '{' filter_prefix_m '}'",
922
"filter_prefix_m : filter_prefix_l",
923
"filter_prefix_m : '{' filter_prefix_l '}'",
924
"filter_prefix_m : '{' filter_prefix_l '}' filter_prefix_m",
925
"filter_prefix_l : filter_prefix",
926
"filter_prefix_l : filter_prefix_l comma filter_prefix",
927
"filter_prefix : prefix prefixlenop",
928
"filter_as_h : filter_as_t",
929
"filter_as_h : '{' filter_as_t_l '}'",
930
"filter_as_t_l : filter_as_t",
931
"filter_as_t_l : filter_as_t_l comma filter_as_t",
932
"filter_as_t : filter_as_type filter_as",
933
"filter_as_t : filter_as_type '{' filter_as_l_h '}'",
934
"filter_as_l_h : filter_as_l",
935
"filter_as_l_h : '{' filter_as_l '}'",
936
"filter_as_l_h : '{' filter_as_l '}' filter_as_l_h",
937
"filter_as_l : filter_as",
938
"filter_as_l : filter_as_l comma filter_as",
939
"filter_as : as4number_any",
940
"filter_as : NEIGHBORAS",
941
"filter_as : equalityop as4number_any",
942
"filter_as : as4number_any binaryop as4number_any",
943
"filter_match_h :",
944
"$$5 :",
945
"filter_match_h : $$5 filter_match",
946
"filter_match : filter_elm",
947
"filter_match : filter_match filter_elm",
948
"filter_elm : filter_prefix_h",
949
"filter_elm : filter_as_h",
950
"filter_elm : MAXASLEN NUMBER",
951
"filter_elm : MAXASSEQ NUMBER",
952
"filter_elm : COMMUNITY STRING",
953
"filter_elm : LARGECOMMUNITY STRING",
954
"filter_elm : EXTCOMMUNITY STRING STRING",
955
"filter_elm : NEXTHOP address",
956
"filter_elm : NEXTHOP NEIGHBOR",
957
"prefixlenop :",
958
"prefixlenop : LONGER",
959
"prefixlenop : PREFIXLEN unaryop NUMBER",
960
"prefixlenop : PREFIXLEN NUMBER binaryop NUMBER",
961
32
"filter_as_type : AS",
962
32
"filter_as_type : SOURCEAS",
963
32
"filter_as_type : TRANSITAS",
964
"filter_as_type : PEERAS",
965
32
"filter_set :",
966

64
"filter_set : SET filter_set_opt",
967
28
"filter_set : SET optnl '{' optnl filter_set_l optnl '}'",
968
4
"filter_set_l : filter_set_l comma filter_set_opt",
969
96
"filter_set_l : filter_set_opt",
970
64
"delete :",
971
32
"delete : DELETE",
972
32
"filter_set_opt : LOCALPREF NUMBER",
973
32
"filter_set_opt : LOCALPREF '+' NUMBER",
974
"filter_set_opt : LOCALPREF '-' NUMBER",
975
"filter_set_opt : MED NUMBER",
976
"filter_set_opt : MED '+' NUMBER",
977
"filter_set_opt : MED '-' NUMBER",
978
"filter_set_opt : METRIC NUMBER",
979
32
"filter_set_opt : METRIC '+' NUMBER",
980
"filter_set_opt : METRIC '-' NUMBER",
981
"filter_set_opt : WEIGHT NUMBER",
982
32
"filter_set_opt : WEIGHT '+' NUMBER",
983
"filter_set_opt : WEIGHT '-' NUMBER",
984
"filter_set_opt : NEXTHOP address",
985
32
"filter_set_opt : NEXTHOP BLACKHOLE",
986
32
"filter_set_opt : NEXTHOP REJECT",
987
"filter_set_opt : NEXTHOP NOMODIFY",
988
32
"filter_set_opt : NEXTHOP SELF",
989
"filter_set_opt : PREPEND_SELF NUMBER",
990
32
"filter_set_opt : PREPEND_PEER NUMBER",
991
32
"filter_set_opt : PFTABLE STRING",
992
32
"filter_set_opt : RTLABEL STRING",
993
"filter_set_opt : COMMUNITY delete STRING",
994
32
"filter_set_opt : LARGECOMMUNITY delete STRING",
995
"filter_set_opt : EXTCOMMUNITY delete STRING STRING",
996
"filter_set_opt : ORIGIN origincode",
997
8
"origincode : string",
998
16
"comma : ','",
999
8
"comma :",
1000
"unaryop : '='",
1001
"unaryop : NE",
1002
"unaryop : LE",
1003
"unaryop : '<'",
1004
"unaryop : GE",
1005
"unaryop : '>'",
1006
8
"equalityop : '='",
1007
8
"equalityop : NE",
1008
"binaryop : '-'",
1009
"binaryop : XRANGE",
1010
};
1011
#endif
1012
#ifdef YYSTACKSIZE
1013
8
#undef YYMAXDEPTH
1014
#define YYMAXDEPTH YYSTACKSIZE
1015
#else
1016
8
#ifdef YYMAXDEPTH
1017
#define YYSTACKSIZE YYMAXDEPTH
1018
#else
1019
8
#define YYSTACKSIZE 10000
1020
8
#define YYMAXDEPTH 10000
1021
#endif
1022
8
#endif
1023
8
#define YYINITSTACKSIZE 200
1024
/* LINTUSED */
1025
8
int yydebug;
1026
int yynerrs;
1027
int yyerrflag;
1028
int yychar;
1029
short *yyssp;
1030
YYSTYPE *yyvsp;
1031
YYSTYPE yyval;
1032
YYSTYPE yylval;
1033
short *yyss;
1034
short *yysslim;
1035
YYSTYPE *yyvs;
1036
unsigned int yystacksize;
1037
int yyparse(void);
1038
#line 2328 "parse.y"
1039
1040
struct keywords {
1041
	const char	*k_name;
1042
	int		 k_val;
1043
};
1044
1045
int
1046
yyerror(const char *fmt, ...)
1047
{
1048
20
	va_list		 ap;
1049
	char		*msg;
1050
20
1051
	file->errors++;
1052
	va_start(ap, fmt);
1053
	if (vasprintf(&msg, fmt, ap) == -1)
1054
		fatalx("yyerror vasprintf");
1055
	va_end(ap);
1056
	logit(LOG_CRIT, "%s:%d: %s", file->name, yylval.lineno, msg);
1057
	free(msg);
1058
	return (0);
1059
}
1060
1061
int
1062
48
kw_cmp(const void *k, const void *e)
1063
24
{
1064
	return (strcmp(k, ((const struct keywords *)e)->k_name));
1065
}
1066
1067
int
1068
lookup(char *s)
1069
{
1070
24
	/* this has to be sorted always */
1071
	static const struct keywords keywords[] = {
1072
24
		{ "AS",			AS},
1073
20
		{ "IPv4",		IPV4},
1074
		{ "IPv6",		IPV6},
1075
		{ "ah",			AH},
1076
20
		{ "allow",		ALLOW},
1077

8
		{ "announce",		ANNOUNCE},
1078
		{ "any",		ANY},
1079
		{ "as-4byte",		AS4BYTE },
1080
		{ "blackhole",		BLACKHOLE},
1081
4
		{ "capabilities",	CAPABILITIES},
1082
		{ "community",		COMMUNITY},
1083
4
		{ "compare",		COMPARE},
1084
4
		{ "connect-retry",	CONNECTRETRY},
1085
		{ "connected",		CONNECTED},
1086
4
		{ "delete",		DELETE},
1087
		{ "demote",		DEMOTE},
1088
		{ "deny",		DENY},
1089
		{ "depend",		DEPEND},
1090
		{ "descr",		DESCR},
1091
		{ "down",		DOWN},
1092
		{ "dump",		DUMP},
1093
		{ "ebgp",		EBGP},
1094
		{ "enforce",		ENFORCE},
1095
		{ "esp",		ESP},
1096
		{ "evaluate",		EVALUATE},
1097
		{ "export-target",	EXPORTTRGT},
1098
		{ "ext-community",	EXTCOMMUNITY},
1099
		{ "fib-priority",	FIBPRIORITY},
1100
		{ "fib-update",		FIBUPDATE},
1101
		{ "from",		FROM},
1102
		{ "group",		GROUP},
1103
		{ "holdtime",		HOLDTIME},
1104
		{ "ibgp",		IBGP},
1105
		{ "ignore",		IGNORE},
1106
		{ "ike",		IKE},
1107
		{ "import-target",	IMPORTTRGT},
1108
		{ "in",			IN},
1109
		{ "include",		INCLUDE},
1110
		{ "inet",		IPV4},
1111
		{ "inet6",		IPV6},
1112
		{ "ipsec",		IPSEC},
1113
		{ "key",		KEY},
1114
		{ "large-community",	LARGECOMMUNITY},
1115
		{ "listen",		LISTEN},
1116
		{ "local-address",	LOCALADDR},
1117

8
		{ "local-as",		LOCALAS},
1118
		{ "localpref",		LOCALPREF},
1119
		{ "log",		LOG},
1120
		{ "match",		MATCH},
1121
		{ "max-as-len",		MAXASLEN},
1122
4
		{ "max-as-seq",		MAXASSEQ},
1123
		{ "max-prefix",		MAXPREFIX},
1124
4
		{ "md5sig",		MD5SIG},
1125

8
		{ "med",		MED},
1126
		{ "metric",		METRIC},
1127
		{ "min",		YMIN},
1128
		{ "multihop",		MULTIHOP},
1129
		{ "neighbor",		NEIGHBOR},
1130
4
		{ "neighbor-as",	NEIGHBORAS},
1131
		{ "network",		NETWORK},
1132
4
		{ "nexthop",		NEXTHOP},
1133
		{ "no-modify",		NOMODIFY},
1134
		{ "on",			ON},
1135
		{ "or-longer",		LONGER},
1136
		{ "origin",		ORIGIN},
1137
		{ "out",		OUT},
1138
		{ "passive",		PASSIVE},
1139
		{ "password",		PASSWORD},
1140
		{ "peer-as",		PEERAS},
1141
		{ "pftable",		PFTABLE},
1142
		{ "prefix",		PREFIX},
1143
		{ "prefixlen",		PREFIXLEN},
1144
		{ "prepend-neighbor",	PREPEND_PEER},
1145
		{ "prepend-self",	PREPEND_SELF},
1146
		{ "qualify",		QUALIFY},
1147
		{ "quick",		QUICK},
1148
		{ "rd",			RD},
1149
		{ "rde",		RDE},
1150
		{ "rdomain",		RDOMAIN},
1151
		{ "refresh",		REFRESH },
1152
		{ "reject",		REJECT},
1153
		{ "remote-as",		REMOTEAS},
1154
		{ "restart",		RESTART},
1155
		{ "restricted",		RESTRICTED},
1156
		{ "rib",		RIB},
1157
		{ "route-collector",	ROUTECOLL},
1158
		{ "route-reflector",	REFLECTOR},
1159
		{ "router-id",		ROUTERID},
1160
		{ "rtable",		RTABLE},
1161
		{ "rtlabel",		RTLABEL},
1162
		{ "self",		SELF},
1163
		{ "set",		SET},
1164
		{ "socket",		SOCKET },
1165
		{ "source-as",		SOURCEAS},
1166
		{ "spi",		SPI},
1167
		{ "static",		STATIC},
1168
		{ "tcp",		TCP},
1169
		{ "to",			TO},
1170
4
		{ "transit-as",		TRANSITAS},
1171
		{ "transparent-as",	TRANSPARENT},
1172
4
		{ "ttl-security",	TTLSECURITY},
1173
8
		{ "via",		VIA},
1174
		{ "weight",		WEIGHT}
1175
8
	};
1176
	const struct keywords	*p;
1177
4
1178
	p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]),
1179
	    sizeof(keywords[0]), kw_cmp);
1180
1181
	if (p)
1182
		return (p->k_val);
1183
	else
1184
		return (STRING);
1185
}
1186
1187
8
#define MAXPUSHBACK	128
1188
1189
8
u_char	*parsebuf;
1190
4
int	 parseindex;
1191
u_char	 pushback_buffer[MAXPUSHBACK];
1192
int	 pushback_index = 0;
1193
1194
int
1195
4
lgetc(int quotec)
1196
{
1197
	int		c, next;
1198
1199
	if (parsebuf) {
1200
		/* Read character from the parsebuffer instead of input. */
1201
		if (parseindex >= 0) {
1202
			c = parsebuf[parseindex++];
1203
			if (c != '\0')
1204
				return (c);
1205
			parsebuf = NULL;
1206
		} else
1207
			parseindex++;
1208
	}
1209
1210
4
	if (pushback_index)
1211
		return (pushback_buffer[--pushback_index]);
1212
1213
	if (quotec) {
1214
		if ((c = getc(file->stream)) == EOF) {
1215
8
			yyerror("reached end of file while parsing "
1216
4
			    "quoted string");
1217
			if (file == topfile || popfile() == EOF)
1218
				return (EOF);
1219
			return (quotec);
1220
		}
1221
		return (c);
1222
	}
1223
4
1224
4
	while ((c = getc(file->stream)) == '\\') {
1225
4
		next = getc(file->stream);
1226
		if (next != '\n') {
1227
4
			c = next;
1228
4
			break;
1229
		}
1230
		yylval.lineno = file->lineno;
1231
		file->lineno++;
1232
	}
1233
1234
8
	while (c == EOF) {
1235
4
		if (file == topfile || popfile() == EOF)
1236
			return (EOF);
1237
		c = getc(file->stream);
1238
	}
1239
4
	return (c);
1240
4
}
1241
4
1242
int
1243
4
lungetc(int c)
1244
12
{
1245
	if (c == EOF)
1246
		return (EOF);
1247
	if (parsebuf) {
1248
12
		parseindex--;
1249
		if (parseindex >= 0)
1250
			return (c);
1251
	}
1252
	if (pushback_index < MAXPUSHBACK-1)
1253
12
		return (pushback_buffer[pushback_index++] = c);
1254
	else
1255
		return (EOF);
1256
}
1257

8
1258

8
int
1259

4
findeol(void)
1260
8
{
1261
4
	int	c;
1262
4
1263
	parsebuf = NULL;
1264
1265
	/* skip to either EOF or the first real EOL */
1266
	while (1) {
1267
		if (pushback_index)
1268
			c = pushback_buffer[--pushback_index];
1269
		else
1270
8
			c = lgetc(0);
1271
		if (c == '\n') {
1272
			file->lineno++;
1273
8
			break;
1274
		}
1275
		if (c == EOF)
1276
			break;
1277
	}
1278
	return (ERROR);
1279
}
1280
1281
int
1282
8
yylex(void)
1283
{
1284
8
	u_char	 buf[8096];
1285
	u_char	*p, *val;
1286
	int	 quotec, next, c;
1287
	int	 token;
1288
1289
top:
1290
	p = buf;
1291
8
	while ((c = lgetc(0)) == ' ' || c == '\t')
1292
		; /* nothing */
1293
1294
	yylval.lineno = file->lineno;
1295
	if (c == '#')
1296
		while ((c = lgetc(0)) != '\n' && c != EOF)
1297
			; /* nothing */
1298
	if (c == '$' && parsebuf == NULL) {
1299
		while (1) {
1300
			if ((c = lgetc(0)) == EOF)
1301
				return (0);
1302
1303
			if (p + 1 >= buf + sizeof(buf) - 1) {
1304
				yyerror("string too long");
1305

16
				return (findeol());
1306
			}
1307
			if (isalnum(c) || c == '_') {
1308
				*p++ = c;
1309
				continue;
1310
			}
1311
8
			*p = '\0';
1312
8
			lungetc(c);
1313
4
			break;
1314
		}
1315
		val = symget(buf);
1316
		if (val == NULL) {
1317
			yyerror("macro '%s' not defined", buf);
1318
4
			return (findeol());
1319
4
		}
1320
4
		parsebuf = val;
1321
8
		parseindex = 0;
1322
4
		goto top;
1323
	}
1324
4
1325
4
	switch (c) {
1326
4
	case '\'':
1327
4
	case '"':
1328
8
		quotec = c;
1329
4
		while (1) {
1330
			if ((c = lgetc(quotec)) == EOF)
1331
				return (0);
1332
			if (c == '\n') {
1333
				file->lineno++;
1334
4
				continue;
1335
4
			} else if (c == '\\') {
1336
4
				if ((next = lgetc(quotec)) == EOF)
1337
8
					return (0);
1338
4
				if (next == quotec || c == ' ' || c == '\t')
1339
					c = next;
1340
4
				else if (next == '\n') {
1341
4
					file->lineno++;
1342
4
					continue;
1343
				} else
1344
8
					lungetc(next);
1345
8
			} else if (c == quotec) {
1346
				*p = '\0';
1347
				break;
1348
			} else if (c == '\0') {
1349
				yyerror("syntax error");
1350
				return (findeol());
1351
			}
1352
			if (p + 1 >= buf + sizeof(buf) - 1) {
1353
				yyerror("string too long");
1354
				return (findeol());
1355
			}
1356
			*p++ = c;
1357
		}
1358
		yylval.v.string = strdup(buf);
1359
		if (yylval.v.string == NULL)
1360
			fatal("yylex: strdup");
1361
		return (STRING);
1362
	case '!':
1363
		next = lgetc(0);
1364
		if (next == '=')
1365
			return (NE);
1366
		lungetc(next);
1367
		break;
1368
	case '<':
1369
		next = lgetc(0);
1370
		if (next == '=')
1371
			return (LE);
1372
		lungetc(next);
1373
		break;
1374
	case '>':
1375
		next = lgetc(0);
1376
		if (next == '<')
1377
			return (XRANGE);
1378
		else if (next == '=')
1379
			return (GE);
1380
		lungetc(next);
1381
		break;
1382
	}
1383
1384
#define allowed_to_end_number(x) \
1385
	(isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' || x == '=')
1386
1387
	if (c == '-' || isdigit(c)) {
1388
		do {
1389
			*p++ = c;
1390
			if ((unsigned)(p-buf) >= sizeof(buf)) {
1391
				yyerror("string too long");
1392
				return (findeol());
1393
			}
1394
		} while ((c = lgetc(0)) != EOF && isdigit(c));
1395
		lungetc(c);
1396
		if (p == buf + 1 && buf[0] == '-')
1397
			goto nodigits;
1398
		if (c == EOF || allowed_to_end_number(c)) {
1399
			const char *errstr = NULL;
1400
1401
			*p = '\0';
1402
			yylval.v.number = strtonum(buf, LLONG_MIN,
1403
			    LLONG_MAX, &errstr);
1404
			if (errstr) {
1405
				yyerror("\"%s\" invalid number: %s",
1406
				    buf, errstr);
1407
				return (findeol());
1408
			}
1409
			return (NUMBER);
1410
		} else {
1411
nodigits:
1412
			while (p > buf + 1)
1413
				lungetc(*--p);
1414
			c = *--p;
1415
			if (c == '-')
1416
				return (c);
1417
		}
1418
	}
1419
1420
#define allowed_in_string(x) \
1421
	(isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \
1422
	x != '{' && x != '}' && x != '<' && x != '>' && \
1423
	x != '!' && x != '=' && x != '/' && x != '#' && \
1424
	x != ','))
1425
1426
	if (isalnum(c) || c == ':' || c == '_' || c == '*') {
1427
		do {
1428
			*p++ = c;
1429
			if ((unsigned)(p-buf) >= sizeof(buf)) {
1430
				yyerror("string too long");
1431
				return (findeol());
1432
			}
1433
		} while ((c = lgetc(0)) != EOF && (allowed_in_string(c)));
1434
		lungetc(c);
1435
		*p = '\0';
1436
		if ((token = lookup(buf)) == STRING)
1437
			if ((yylval.v.string = strdup(buf)) == NULL)
1438
				fatal("yylex: strdup");
1439
		return (token);
1440
	}
1441
	if (c == '\n') {
1442
		yylval.lineno = file->lineno;
1443
		file->lineno++;
1444
	}
1445
	if (c == EOF)
1446
		return (0);
1447
	return (c);
1448
}
1449
1450
int
1451
check_file_secrecy(int fd, const char *fname)
1452
{
1453
	struct stat	st;
1454
1455
	if (fstat(fd, &st)) {
1456
		log_warn("cannot stat %s", fname);
1457
		return (-1);
1458
	}
1459
	return (0);
1460
}
1461
1462
struct file *
1463
12
pushfile(const char *name, int secret)
1464
20
{
1465
8
	struct file	*nfile;
1466
1467
	if ((nfile = calloc(1, sizeof(struct file))) == NULL) {
1468
		log_warn("malloc");
1469
		return (NULL);
1470
	}
1471
8
	if ((nfile->name = strdup(name)) == NULL) {
1472

16
		log_warn("malloc");
1473
		free(nfile);
1474
		return (NULL);
1475

8
	}
1476
	if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
1477
		log_warn("%s", nfile->name);
1478
		free(nfile->name);
1479
		free(nfile);
1480
		return (NULL);
1481
	}
1482
	if (secret &&
1483
	    check_file_secrecy(fileno(nfile->stream), nfile->name)) {
1484
		fclose(nfile->stream);
1485
8
		free(nfile->name);
1486
		free(nfile);
1487
8
		return (NULL);
1488
	}
1489
	nfile->lineno = 1;
1490
	TAILQ_INSERT_TAIL(&files, nfile, entry);
1491
	return (nfile);
1492
}
1493
1494
int
1495
16
popfile(void)
1496
8
{
1497
	struct file	*prev;
1498
1499
	if ((prev = TAILQ_PREV(file, files, entry)) != NULL)
1500
		prev->errors += file->errors;
1501
1502
	TAILQ_REMOVE(&files, file, entry);
1503
	fclose(file->stream);
1504
	free(file->name);
1505
184
	free(file);
1506
	file = prev;
1507
	return (file ? 0 : EOF);
1508
184
}
1509
184
1510
184
int
1511
184
parse_config(char *filename, struct bgpd_config *xconf, struct peer **xpeers)
1512
184
{
1513
	struct sym		*sym, *next;
1514
	struct peer		*p, *pnext;
1515
	struct rde_rib		*rr;
1516
	int			 errors = 0;
1517
1518
	conf = new_config();
1519
1520
	if ((filter_l = calloc(1, sizeof(struct filter_head))) == NULL)
1521
		fatal(NULL);
1522
	if ((peerfilter_l = calloc(1, sizeof(struct filter_head))) == NULL)
1523
		fatal(NULL);
1524
184
	if ((groupfilter_l = calloc(1, sizeof(struct filter_head))) == NULL)
1525
		fatal(NULL);
1526
368
	TAILQ_INIT(filter_l);
1527
	TAILQ_INIT(peerfilter_l);
1528
	TAILQ_INIT(groupfilter_l);
1529
48
1530
180
	peer_l = NULL;
1531
136
	peer_l_old = *xpeers;
1532
4
	curpeer = NULL;
1533
	curgroup = NULL;
1534
184
	id = 1;
1535
184
1536
	netconf = &conf->networks;
1537
1538
176
	add_rib("Adj-RIB-In", conf->default_tableid,
1539
184
	    F_RIB_NOFIB | F_RIB_NOEVALUATE);
1540
8
	add_rib("Loc-RIB", conf->default_tableid, F_RIB_LOCAL);
1541
1542
184
	if ((file = pushfile(filename, 1)) == NULL) {
1543
184
		free(conf);
1544
		return (-1);
1545
	}
1546
	topfile = file;
1547
1548
	yyparse();
1549
	errors = file->errors;
1550
	popfile();
1551
1552
	/* Free macros and check which have not been used. */
1553
	TAILQ_FOREACH_SAFE(sym, &symhead, entry, next) {
1554
		if ((cmd_opts & BGPD_OPT_VERBOSE2) && !sym->used)
1555
			fprintf(stderr, "warning: macro \"%s\" not "
1556
			    "used\n", sym->nam);
1557
		if (!sym->persist) {
1558
			free(sym->nam);
1559
			free(sym->val);
1560
			TAILQ_REMOVE(&symhead, sym, entry);
1561
			free(sym);
1562
		}
1563
	}
1564
1565
	if (errors) {
1566
		for (p = peer_l; p != NULL; p = pnext) {
1567
			pnext = p->next;
1568
			free(p);
1569
		}
1570
1571
		while ((rr = SIMPLEQ_FIRST(&ribnames)) != NULL) {
1572
			SIMPLEQ_REMOVE_HEAD(&ribnames, entry);
1573
			free(rr);
1574
		}
1575
1576
		filterlist_free(filter_l);
1577
		filterlist_free(peerfilter_l);
1578
		filterlist_free(groupfilter_l);
1579
1580
		free_config(conf);
1581
	} else {
1582
		/*
1583
		 * Move filter list and static group and peer filtersets
1584
		 * together. Static group sets come first then peer sets
1585
		 * last normal filter rules.
1586
		 */
1587
168
		merge_filter_lists(conf->filters, groupfilter_l);
1588
		merge_filter_lists(conf->filters, peerfilter_l);
1589
		merge_filter_lists(conf->filters, filter_l);
1590
168
1591
168
		errors += mrt_mergeconfig(xconf->mrt, conf->mrt);
1592
		errors += merge_config(xconf, conf, peer_l);
1593
168
		*xpeers = peer_l;
1594
1595
		for (p = peer_l_old; p != NULL; p = pnext) {
1596
			pnext = p->next;
1597
			free(p);
1598
		}
1599
1600
		free(filter_l);
1601
		free(peerfilter_l);
1602
		free(groupfilter_l);
1603
	}
1604
1605
	return (errors ? -1 : 0);
1606
}
1607
1608
int
1609
symset(const char *nam, const char *val, int persist)
1610
{
1611
	struct sym	*sym;
1612
1613
	TAILQ_FOREACH(sym, &symhead, entry) {
1614
		if (strcmp(nam, sym->nam) == 0)
1615
			break;
1616
	}
1617
1618
	if (sym != NULL) {
1619
		if (sym->persist == 1)
1620
			return (0);
1621
		else {
1622
			free(sym->nam);
1623
			free(sym->val);
1624
			TAILQ_REMOVE(&symhead, sym, entry);
1625
			free(sym);
1626
		}
1627
	}
1628
	if ((sym = calloc(1, sizeof(*sym))) == NULL)
1629
		return (-1);
1630
1631
	sym->nam = strdup(nam);
1632
	if (sym->nam == NULL) {
1633
		free(sym);
1634
		return (-1);
1635
	}
1636
	sym->val = strdup(val);
1637
	if (sym->val == NULL) {
1638
		free(sym->nam);
1639
		free(sym);
1640
		return (-1);
1641
	}
1642
8
	sym->used = 0;
1643
	sym->persist = persist;
1644
	TAILQ_INSERT_TAIL(&symhead, sym, entry);
1645
8
	return (0);
1646
}
1647
8
1648
8
int
1649
cmdline_symset(char *s)
1650
{
1651
8
	char	*sym, *val;
1652
	int	ret;
1653
8
	size_t	len;
1654
1655
	if ((val = strrchr(s, '=')) == NULL)
1656
4
		return (-1);
1657
1658
4
	len = strlen(s) - strlen(val) + 1;
1659
	if ((sym = malloc(len)) == NULL)
1660
		fatal("cmdline_symset: malloc");
1661
4
1662
4
	strlcpy(sym, s, len);
1663
1664
	ret = symset(sym, val + 1, 1);
1665
	free(sym);
1666
1667
	return (ret);
1668
4
}
1669
1670
4
char *
1671
symget(const char *nam)
1672
{
1673
4
	struct sym	*sym;
1674
4
1675
	TAILQ_FOREACH(sym, &symhead, entry) {
1676
		if (strcmp(nam, sym->nam) == 0) {
1677
			sym->used = 1;
1678
			return (sym->val);
1679
96
		}
1680
96
	}
1681
	return (NULL);
1682
}
1683
1684
int
1685
getcommunity(char *s)
1686
{
1687
	int		 val;
1688
	const char	*errstr;
1689
1690
	if (strcmp(s, "*") == 0)
1691
		return (COMMUNITY_ANY);
1692
	if (strcmp(s, "neighbor-as") == 0)
1693
		return (COMMUNITY_NEIGHBOR_AS);
1694
	if (strcmp(s, "local-as") == 0)
1695
		return (COMMUNITY_LOCAL_AS);
1696
	val = strtonum(s, 0, USHRT_MAX, &errstr);
1697
	if (errstr) {
1698
		yyerror("Community %s is %s (max: %u)", s, errstr, USHRT_MAX);
1699
		return (COMMUNITY_ERROR);
1700
	}
1701
	return (val);
1702
}
1703
1704
int
1705
96
parsecommunity(struct filter_community *c, char *s)
1706
{
1707
	char *p;
1708
96
	int i, as;
1709
1710
96
	/* Well-known communities */
1711
	if (strcasecmp(s, "GRACEFUL_SHUTDOWN") == 0) {
1712
96
		c->as = COMMUNITY_WELLKNOWN;
1713
		c->type = COMMUNITY_GRACEFUL_SHUTDOWN;
1714
		return (0);
1715
	} else if (strcasecmp(s, "NO_EXPORT") == 0) {
1716
		c->as = COMMUNITY_WELLKNOWN;
1717
		c->type = COMMUNITY_NO_EXPORT;
1718
		return (0);
1719
	} else if (strcasecmp(s, "NO_ADVERTISE") == 0) {
1720
		c->as = COMMUNITY_WELLKNOWN;
1721
		c->type = COMMUNITY_NO_ADVERTISE;
1722
		return (0);
1723
	} else if (strcasecmp(s, "NO_EXPORT_SUBCONFED") == 0) {
1724
		c->as = COMMUNITY_WELLKNOWN;
1725
		c->type = COMMUNITY_NO_EXPSUBCONFED;
1726
		return (0);
1727
	} else if (strcasecmp(s, "NO_PEER") == 0) {
1728
		c->as = COMMUNITY_WELLKNOWN;
1729
		c->type = COMMUNITY_NO_PEER;
1730
		return (0);
1731
	} else if (strcasecmp(s, "BLACKHOLE") == 0) {
1732
		c->as = COMMUNITY_WELLKNOWN;
1733
		c->type = COMMUNITY_BLACKHOLE;
1734
		return (0);
1735
	}
1736
1737
32
	if ((p = strchr(s, ':')) == NULL) {
1738
32
		yyerror("Bad community syntax");
1739
		return (-1);
1740
32
	}
1741
	*p++ = 0;
1742
1743
	if ((i = getcommunity(s)) == COMMUNITY_ERROR)
1744
		return (-1);
1745
	as = i;
1746
1747
	if ((i = getcommunity(p)) == COMMUNITY_ERROR)
1748
		return (-1);
1749
	c->as = as;
1750
	c->type = i;
1751
1752
	return (0);
1753
}
1754
1755
int64_t
1756
getlargecommunity(char *s)
1757
{
1758
	u_int		 val;
1759
	const char	*errstr;
1760
1761
	if (strcmp(s, "*") == 0)
1762
		return (COMMUNITY_ANY);
1763
	if (strcmp(s, "neighbor-as") == 0)
1764
		return (COMMUNITY_NEIGHBOR_AS);
1765
	if (strcmp(s, "local-as") == 0)
1766
		return (COMMUNITY_LOCAL_AS);
1767
	val = strtonum(s, 0, UINT_MAX, &errstr);
1768
	if (errstr) {
1769
		yyerror("Large Community %s is %s (max: %u)",
1770
		    s, errstr, UINT_MAX);
1771
		return (COMMUNITY_ERROR);
1772
12
	}
1773
	return (val);
1774
}
1775
12
1776
12
int
1777
parselargecommunity(struct filter_largecommunity *c, char *s)
1778
12
{
1779
	char *p, *q;
1780
	int64_t as, ld1, ld2;
1781
1782
	if ((p = strchr(s, ':')) == NULL) {
1783
		yyerror("Bad community syntax");
1784
		return (-1);
1785
	}
1786
	*p++ = 0;
1787
1788
	if ((q = strchr(p, ':')) == NULL) {
1789
		yyerror("Bad community syntax");
1790
		return (-1);
1791
	}
1792
20
	*q++ = 0;
1793
1794
	if ((as = getlargecommunity(s)) == COMMUNITY_ERROR)
1795
20
		return (-1);
1796
1797
	if ((ld1 = getlargecommunity(p)) == COMMUNITY_ERROR)
1798
		return (-1);
1799
20
1800
20
	if ((ld2 = getlargecommunity(q)) == COMMUNITY_ERROR)
1801
20
		return (-1);
1802
1803
20
	c->as = as;
1804
	c->ld1 = ld1;
1805
	c->ld2 = ld2;
1806
16
1807
16
	return (0);
1808
16
}
1809
1810
16
int
1811
168
parsesubtype(char *name, int *type, int *subtype)
1812
168
{
1813
168
	const struct ext_comm_pairs *cp;
1814
	int found = 0;
1815
168
1816
168
	for (cp = iana_ext_comms; cp->subname != NULL; cp++) {
1817
		if (strcmp(name, cp->subname) == 0) {
1818
168
			if (found == 0) {
1819
				*type = cp->type;
1820
				*subtype = cp->subtype;
1821
			}
1822
			found++;
1823
		}
1824
	}
1825
104
	if (found > 1)
1826
		*type = -1;
1827
	return (found);
1828
}
1829
104
1830
int
1831
104
parseextvalue(char *s, u_int32_t *v)
1832
32
{
1833
	const char 	*errstr;
1834
	char		*p;
1835
	struct in_addr	 ip;
1836
32
	u_int32_t	 uvalh = 0, uval;
1837
1838
32
	if ((p = strchr(s, '.')) == NULL) {
1839
		/* AS_PLAIN number (4 or 2 byte) */
1840
		uval = strtonum(s, 0, UINT_MAX, &errstr);
1841
		if (errstr) {
1842
			yyerror("Bad ext-community %s is %s", s, errstr);
1843
			return (-1);
1844
		}
1845
		*v = uval;
1846
		if (uval <= USHRT_MAX)
1847
			return (EXT_COMMUNITY_TRANS_TWO_AS);
1848
		else
1849
			return (EXT_COMMUNITY_TRANS_FOUR_AS);
1850
	} else if (strchr(p + 1, '.') == NULL) {
1851
		/* AS_DOT number (4-byte) */
1852
		*p++ = '\0';
1853
		uvalh = strtonum(s, 0, USHRT_MAX, &errstr);
1854
		if (errstr) {
1855
			yyerror("Bad ext-community %s is %s", s, errstr);
1856
			return (-1);
1857
		}
1858
		uval = strtonum(p, 0, USHRT_MAX, &errstr);
1859
		if (errstr) {
1860
			yyerror("Bad ext-community %s is %s", p, errstr);
1861
			return (-1);
1862
		}
1863
8
		*v = uval | (uvalh << 16);
1864
		return (EXT_COMMUNITY_TRANS_FOUR_AS);
1865
	} else {
1866
		/* more than one dot -> IP address */
1867
		if (inet_aton(s, &ip) == 0) {
1868
16
			yyerror("Bad ext-community %s not parseable", s);
1869
8
			return (-1);
1870
		}
1871
		*v = ip.s_addr;
1872
		return (EXT_COMMUNITY_TRANS_IPV4);
1873
	}
1874
	return (-1);
1875
4
}
1876
1877
int
1878
parseextcommunity(struct filter_extcommunity *c, char *t, char *s)
1879
{
1880
8
	const struct ext_comm_pairs *cp;
1881
4
	const char 	*errstr;
1882
	u_int64_t	 ullval;
1883
	u_int32_t	 uval;
1884
	char		*p, *ep;
1885
	int		 type, subtype;
1886
1887
20
	if (parsesubtype(t, &type, &subtype) == 0) {
1888
		yyerror("Bad ext-community unknown type");
1889
		return (-1);
1890
	}
1891
1892
	switch (type) {
1893
	case -1:
1894
		if ((p = strchr(s, ':')) == NULL) {
1895
40
			yyerror("Bad ext-community %s", s);
1896
40
			return (-1);
1897
20
		}
1898
20
		*p++ = '\0';
1899
		if ((type = parseextvalue(s, &uval)) == -1)
1900
			return (-1);
1901
		switch (type) {
1902
		case EXT_COMMUNITY_TRANS_TWO_AS:
1903
			ullval = strtonum(p, 0, UINT_MAX, &errstr);
1904
			break;
1905
		case EXT_COMMUNITY_TRANS_IPV4:
1906
		case EXT_COMMUNITY_TRANS_FOUR_AS:
1907
			ullval = strtonum(p, 0, USHRT_MAX, &errstr);
1908
			break;
1909
		default:
1910
			fatalx("parseextcommunity: unexpected result");
1911
		}
1912
		if (errstr) {
1913
			yyerror("Bad ext-community %s is %s", p, errstr);
1914
			return (-1);
1915
		}
1916
		switch (type) {
1917
		case EXT_COMMUNITY_TRANS_TWO_AS:
1918
			c->data.ext_as.as = uval;
1919
			c->data.ext_as.val = ullval;
1920
			break;
1921
		case EXT_COMMUNITY_TRANS_IPV4:
1922
			c->data.ext_ip.addr.s_addr = uval;
1923
			c->data.ext_ip.val = ullval;
1924
			break;
1925
		case EXT_COMMUNITY_TRANS_FOUR_AS:
1926
			c->data.ext_as4.as4 = uval;
1927
			c->data.ext_as4.val = ullval;
1928
92
			break;
1929

184
		}
1930
		break;
1931
	case EXT_COMMUNITY_TRANS_OPAQUE:
1932
	case EXT_COMMUNITY_TRANS_EVPN:
1933

92
		errno = 0;
1934
		ullval = strtoull(s, &ep, 0);
1935
		if (s[0] == '\0' || *ep != '\0') {
1936
			yyerror("Bad ext-community bad value");
1937
92
			return (-1);
1938
92
		}
1939
		if (errno == ERANGE && ullval > EXT_COMMUNITY_OPAQUE_MAX) {
1940
92
			yyerror("Bad ext-community value too big");
1941
12
			return (-1);
1942


48
		}
1943
		c->data.ext_opaq = ullval;
1944
		break;
1945
	case EXT_COMMUNITY_NON_TRANS_OPAQUE:
1946
12
		if (strcmp(s, "valid") == 0)
1947
			c->data.ext_opaq = EXT_COMMUNITY_OVS_VALID;
1948
		else if (strcmp(s, "invalid") == 0)
1949
			c->data.ext_opaq = EXT_COMMUNITY_OVS_INVALID;
1950
12
		else if (strcmp(s, "not-found") == 0)
1951
12
			c->data.ext_opaq = EXT_COMMUNITY_OVS_NOTFOUND;
1952
12
		else {
1953
			yyerror("Bad ext-community %s", s);
1954
12
			return (-1);
1955
		}
1956
32
		break;
1957
32
	}
1958
	c->type = type;
1959
	c->subtype = subtype;
1960
1961
	/* verify type/subtype combo */
1962
180
	for (cp = iana_ext_comms; cp->subname != NULL; cp++) {
1963
180
		if (cp->type == type && cp->subtype == subtype) {
1964
			c->flags |= EXT_COMMUNITY_FLAG_VALID;
1965
			return (0);
1966
		}
1967
	}
1968
1969
	yyerror("Bad ext-community bad format for type");
1970
4
	return (-1);
1971
4
}
1972
1973
struct peer *
1974
alloc_peer(void)
1975
{
1976
	struct peer	*p;
1977
	u_int8_t	 i;
1978
1979
4
	if ((p = calloc(1, sizeof(struct peer))) == NULL)
1980
		fatal("new_peer");
1981
1982
4
	/* some sane defaults */
1983
4
	p->state = STATE_NONE;
1984
	p->next = NULL;
1985
4
	p->conf.distance = 1;
1986
	p->conf.announce_type = ANNOUNCE_UNDEF;
1987
	p->conf.announce_capa = 1;
1988
	for (i = 0; i < AID_MAX; i++)
1989
		p->conf.capabilities.mp[i] = -1;
1990
	p->conf.capabilities.refresh = 1;
1991
	p->conf.capabilities.grestart.restart = 1;
1992

8
	p->conf.capabilities.as4byte = 1;
1993
	p->conf.local_as = conf->as;
1994
	p->conf.local_short_as = conf->short_as;
1995
1996
4
	return (p);
1997
}
1998
4
1999
struct peer *
2000
new_peer(void)
2001
{
2002
	struct peer		*p;
2003
2004
	p = alloc_peer();
2005
2006
4
	if (curgroup != NULL) {
2007
		memcpy(p, curgroup, sizeof(struct peer));
2008
		if (strlcpy(p->conf.group, curgroup->conf.group,
2009
		    sizeof(p->conf.group)) >= sizeof(p->conf.group))
2010
			fatalx("new_peer group strlcpy");
2011
		if (strlcpy(p->conf.descr, curgroup->conf.descr,
2012
		    sizeof(p->conf.descr)) >= sizeof(p->conf.descr))
2013
			fatalx("new_peer descr strlcpy");
2014
		p->conf.groupid = curgroup->conf.id;
2015
		p->conf.local_as = curgroup->conf.local_as;
2016
		p->conf.local_short_as = curgroup->conf.local_short_as;
2017
	}
2018
	p->next = NULL;
2019
	if (conf->flags & BGPD_FLAG_DECISION_TRANS_AS)
2020
		p->conf.flags |= PEERFLAG_TRANS_AS;
2021
	return (p);
2022
}
2023
2024
struct peer *
2025
new_group(void)
2026
{
2027
	return (alloc_peer());
2028
}
2029
2030
int
2031
add_mrtconfig(enum mrt_type type, char *name, int timeout, struct peer *p,
2032
    char *rib)
2033
{
2034
	struct mrt	*m, *n;
2035
2036
	LIST_FOREACH(m, conf->mrt, entry) {
2037
		if ((rib && strcmp(rib, m->rib)) ||
2038
		    (!rib && *m->rib))
2039
			continue;
2040
		if (p == NULL) {
2041
			if (m->peer_id != 0 || m->group_id != 0)
2042
				continue;
2043
		} else {
2044
			if (m->peer_id != p->conf.id ||
2045
			    m->group_id != p->conf.groupid)
2046
				continue;
2047
		}
2048
		if (m->type == type) {
2049
			yyerror("only one mrtdump per type allowed.");
2050
			return (-1);
2051
		}
2052
	}
2053
2054
	if ((n = calloc(1, sizeof(struct mrt_config))) == NULL)
2055
		fatal("add_mrtconfig");
2056
2057
	n->type = type;
2058
	if (strlcpy(MRT2MC(n)->name, name, sizeof(MRT2MC(n)->name)) >=
2059
	    sizeof(MRT2MC(n)->name)) {
2060
		yyerror("filename \"%s\" too long: max %zu",
2061
		    name, sizeof(MRT2MC(n)->name) - 1);
2062
		free(n);
2063
		return (-1);
2064
	}
2065
	MRT2MC(n)->ReopenTimerInterval = timeout;
2066
	if (p != NULL) {
2067
		if (curgroup == p) {
2068
			n->peer_id = 0;
2069
			n->group_id = p->conf.id;
2070
		} else {
2071
			n->peer_id = p->conf.id;
2072
			n->group_id = 0;
2073
		}
2074
	}
2075
	if (rib) {
2076
		if (!find_rib(rib)) {
2077
			yyerror("rib \"%s\" does not exist.", rib);
2078
			free(n);
2079
			return (-1);
2080
		}
2081
		if (strlcpy(n->rib, rib, sizeof(n->rib)) >=
2082
		    sizeof(n->rib)) {
2083
			yyerror("rib name \"%s\" too long: max %zu",
2084
			    name, sizeof(n->rib) - 1);
2085
			free(n);
2086
			return (-1);
2087
		}
2088
	}
2089
2090
	LIST_INSERT_HEAD(conf->mrt, n, entry);
2091
2092
	return (0);
2093
}
2094
2095
int
2096
add_rib(char *name, u_int rtableid, u_int16_t flags)
2097
{
2098
	struct rde_rib	*rr;
2099
	u_int		 rdom, default_rdom;
2100
2101
	if ((rr = find_rib(name)) == NULL) {
2102
		if ((rr = calloc(1, sizeof(*rr))) == NULL) {
2103
			log_warn("add_rib");
2104
			return (-1);
2105
		}
2106
	}
2107
	if (strlcpy(rr->name, name, sizeof(rr->name)) >= sizeof(rr->name)) {
2108
		yyerror("rib name \"%s\" too long: max %zu",
2109
		   name, sizeof(rr->name) - 1);
2110
		free(rr);
2111
		return (-1);
2112
	}
2113
	rr->flags |= flags;
2114
	if ((rr->flags & F_RIB_HASNOFIB) == 0) {
2115
		if (ktable_exists(rtableid, &rdom) != 1) {
2116
			yyerror("rtable id %u does not exist", rtableid);
2117
			free(rr);
2118
			return (-1);
2119
		}
2120
		if (ktable_exists(conf->default_tableid, &default_rdom) != 1)
2121
			fatal("default rtable %u does not exist",
2122
			    conf->default_tableid);
2123
		if (rdom != default_rdom) {
2124
			log_warnx("rtable %u does not belong to rdomain %u",
2125
			    rtableid, default_rdom);
2126
			free(rr);
2127
			return (-1);
2128
		}
2129
		rr->rtableid = rtableid;
2130
	}
2131
	SIMPLEQ_INSERT_TAIL(&ribnames, rr, entry);
2132
	return (0);
2133
}
2134
2135
struct rde_rib *
2136
find_rib(char *name)
2137
{
2138
	struct rde_rib	*rr;
2139
2140
	SIMPLEQ_FOREACH(rr, &ribnames, entry) {
2141
		if (!strcmp(rr->name, name))
2142
			return (rr);
2143
	}
2144
	return (NULL);
2145
}
2146
2147
int
2148
get_id(struct peer *newpeer)
2149
{
2150
	struct peer	*p;
2151
2152
	for (p = peer_l_old; p != NULL; p = p->next)
2153
		if (newpeer->conf.remote_addr.aid) {
2154
			if (!memcmp(&p->conf.remote_addr,
2155
			    &newpeer->conf.remote_addr,
2156
			    sizeof(p->conf.remote_addr))) {
2157
				newpeer->conf.id = p->conf.id;
2158
				return (0);
2159
			}
2160
		} else {	/* newpeer is a group */
2161
			if (strcmp(newpeer->conf.group, p->conf.group) == 0) {
2162
				newpeer->conf.id = p->conf.groupid;
2163
				return (0);
2164
			}
2165
		}
2166
2167
	/* new one */
2168
	for (; id < UINT_MAX / 2; id++) {
2169
		for (p = peer_l_old; p != NULL &&
2170
		    p->conf.id != id && p->conf.groupid != id; p = p->next)
2171
			;	/* nothing */
2172
		if (p == NULL) {	/* we found a free id */
2173
			newpeer->conf.id = id++;
2174
			return (0);
2175
		}
2176
	}
2177
2178
	return (-1);
2179
}
2180
2181
int
2182
merge_prefixspec(struct filter_prefix_l *p, struct filter_prefixlen *pl)
2183
{
2184
	u_int8_t max_len = 0;
2185
2186
	switch (p->p.addr.aid) {
2187
	case AID_INET:
2188
	case AID_VPN_IPv4:
2189
		max_len = 32;
2190
		break;
2191
	case AID_INET6:
2192
		max_len = 128;
2193
		break;
2194
	}
2195
2196
	switch (pl->op) {
2197
	case OP_NONE:
2198
		return (0);
2199
	case OP_RANGE:
2200
	case OP_XRANGE:
2201
		if (pl->len_min > max_len || pl->len_max > max_len) {
2202
			yyerror("prefixlen %d too big for AF, limit %d",
2203
			    pl->len_min > max_len ? pl->len_min : pl->len_max,
2204
			    max_len);
2205
			return (-1);
2206
		}
2207
		if (pl->len_min < p->p.len) {
2208
			yyerror("prefixlen %d smaller than prefix, limit %d",
2209
			    pl->len_min, p->p.len);
2210
			return (-1);
2211
		}
2212
		p->p.len_max = pl->len_max;
2213
		break;
2214
	case OP_GE:
2215
		/* fix up the "or-longer" case */
2216
		if (pl->len_min == -1)
2217
			pl->len_min = p->p.len;
2218
		/* FALLTHROUGH */
2219
	case OP_EQ:
2220
	case OP_NE:
2221
	case OP_LE:
2222
	case OP_GT:
2223
		if (pl->len_min > max_len) {
2224
			yyerror("prefixlen %d too big for AF, limit %d",
2225
			    pl->len_min, max_len);
2226
			return (-1);
2227
		}
2228
		if (pl->len_min < p->p.len) {
2229
			yyerror("prefixlen %d smaller than prefix, limit %d",
2230
			    pl->len_min, p->p.len);
2231
			return (-1);
2232
		}
2233
		break;
2234
	case OP_LT:
2235
		if (pl->len_min > max_len - 1) {
2236
			yyerror("prefixlen %d too big for AF, limit %d",
2237
			    pl->len_min, max_len - 1);
2238
			return (-1);
2239
		}
2240
		if (pl->len_min < p->p.len + 1) {
2241
			yyerror("prefixlen %d too small for prefix, limit %d",
2242
			    pl->len_min, p->p.len + 1);
2243
			return (-1);
2244
		}
2245
		break;
2246
	}
2247
2248
	p->p.op = pl->op;
2249
	p->p.len_min = pl->len_min;
2250
	return (0);
2251
}
2252
2253
int
2254
expand_rule(struct filter_rule *rule, struct filter_rib_l *rib,
2255
    struct filter_peers_l *peer, struct filter_match_l *match,
2256
    struct filter_set_head *set)
2257
{
2258
	struct filter_rule	*r;
2259
	struct filter_rib_l	*rb, *rbnext;
2260
	struct filter_peers_l	*p, *pnext;
2261
	struct filter_prefix_l	*prefix, *prefix_next;
2262
	struct filter_as_l	*a, *anext;
2263
	struct filter_set	*s;
2264
2265
	rb = rib;
2266
	do {
2267
		p = peer;
2268
		do {
2269
			a = match->as_l;
2270
			do {
2271
				prefix = match->prefix_l;
2272
				do {
2273
					if ((r = calloc(1,
2274
					    sizeof(struct filter_rule))) ==
2275
						 NULL) {
2276
						log_warn("expand_rule");
2277
						return (-1);
2278
					}
2279
2280
					memcpy(r, rule, sizeof(struct filter_rule));
2281
					memcpy(&r->match, match,
2282
					    sizeof(struct filter_match));
2283
					TAILQ_INIT(&r->set);
2284
					copy_filterset(set, &r->set);
2285
2286
					if (rb != NULL)
2287
						strlcpy(r->rib, rb->name,
2288
						     sizeof(r->rib));
2289
2290
					if (p != NULL)
2291
						memcpy(&r->peer, &p->p,
2292
						    sizeof(struct filter_peers));
2293
2294
					if (prefix != NULL)
2295
						memcpy(&r->match.prefix, &prefix->p,
2296
						    sizeof(r->match.prefix));
2297
2298
					if (a != NULL)
2299
						memcpy(&r->match.as, &a->a,
2300
						    sizeof(struct filter_as));
2301
2302
					TAILQ_INSERT_TAIL(filter_l, r, entry);
2303
2304
					if (prefix != NULL)
2305
						prefix = prefix->next;
2306
				} while (prefix != NULL);
2307
2308
				if (a != NULL)
2309
					a = a->next;
2310
			} while (a != NULL);
2311
2312
			if (p != NULL)
2313
				p = p->next;
2314
		} while (p != NULL);
2315
92
2316
92
		if (rb != NULL)
2317
			rb = rb->next;
2318
	} while (rb != NULL);
2319
2320
	for (rb = rib; rb != NULL; rb = rbnext) {
2321
		rbnext = rb->next;
2322
		free(rb);
2323
32
	}
2324
32
2325
	for (p = peer; p != NULL; p = pnext) {
2326
		pnext = p->next;
2327
		free(p);
2328
	}
2329
2330
	for (a = match->as_l; a != NULL; a = anext) {
2331
		anext = a->next;
2332
		free(a);
2333
	}
2334
2335
	for (prefix = match->prefix_l; prefix != NULL; prefix = prefix_next) {
2336
		prefix_next = prefix->next;
2337
		free(prefix);
2338
	}
2339
2340
	if (set != NULL) {
2341
		while ((s = TAILQ_FIRST(set)) != NULL) {
2342
			TAILQ_REMOVE(set, s, entry);
2343
			free(s);
2344
		}
2345
		free(set);
2346
	}
2347
2348
	return (0);
2349
}
2350
2351
int
2352
str2key(char *s, char *dest, size_t max_len)
2353
{
2354
	unsigned	i;
2355
	char		t[3];
2356
2357
	if (strlen(s) / 2 > max_len) {
2358
		yyerror("key too long");
2359
		return (-1);
2360
	}
2361
2362
	if (strlen(s) % 2) {
2363
		yyerror("key must be of even length");
2364
		return (-1);
2365
	}
2366
2367
	for (i = 0; i < strlen(s) / 2; i++) {
2368
		t[0] = s[2*i];
2369
		t[1] = s[2*i + 1];
2370
		t[2] = 0;
2371
		if (!isxdigit(t[0]) || !isxdigit(t[1])) {
2372
			yyerror("key must be specified in hex");
2373
			return (-1);
2374
		}
2375
		dest[i] = strtoul(t, NULL, 16);
2376
	}
2377
2378
	return (0);
2379
}
2380
2381
int
2382
neighbor_consistent(struct peer *p)
2383
{
2384
	u_int8_t	i;
2385
2386
	/* local-address and peer's address: same address family */
2387
	if (p->conf.local_addr.aid &&
2388
	    p->conf.local_addr.aid != p->conf.remote_addr.aid) {
2389
		yyerror("local-address and neighbor address "
2390
		    "must be of the same address family");
2391
		return (-1);
2392
	}
2393
2394
	/* with any form of ipsec local-address is required */
2395
	if ((p->conf.auth.method == AUTH_IPSEC_IKE_ESP ||
2396
	    p->conf.auth.method == AUTH_IPSEC_IKE_AH ||
2397
	    p->conf.auth.method == AUTH_IPSEC_MANUAL_ESP ||
2398
	    p->conf.auth.method == AUTH_IPSEC_MANUAL_AH) &&
2399
	    !p->conf.local_addr.aid) {
2400
		yyerror("neighbors with any form of IPsec configured "
2401
		    "need local-address to be specified");
2402
		return (-1);
2403
	}
2404
2405
	/* with static keying we need both directions */
2406
	if ((p->conf.auth.method == AUTH_IPSEC_MANUAL_ESP ||
2407
	    p->conf.auth.method == AUTH_IPSEC_MANUAL_AH) &&
2408
	    (!p->conf.auth.spi_in || !p->conf.auth.spi_out)) {
2409
		yyerror("with manual keyed IPsec, SPIs and keys "
2410
		    "for both directions are required");
2411
		return (-1);
2412
	}
2413
2414
	if (!conf->as) {
2415
		yyerror("AS needs to be given before neighbor definitions");
2416
		return (-1);
2417
	}
2418
2419
	/* set default values if they where undefined */
2420
	p->conf.ebgp = (p->conf.remote_as != conf->as);
2421
	if (p->conf.announce_type == ANNOUNCE_UNDEF)
2422
		p->conf.announce_type = p->conf.ebgp ?
2423
		    ANNOUNCE_SELF : ANNOUNCE_ALL;
2424
	if (p->conf.enforce_as == ENFORCE_AS_UNDEF)
2425
		p->conf.enforce_as = p->conf.ebgp ?
2426
		    ENFORCE_AS_ON : ENFORCE_AS_OFF;
2427
	if (p->conf.enforce_local_as == ENFORCE_AS_UNDEF)
2428
		p->conf.enforce_local_as = ENFORCE_AS_ON;
2429
2430
	if (p->conf.remote_as == 0 && p->conf.enforce_as != ENFORCE_AS_OFF) {
2431
		yyerror("peer AS may not be zero");
2432
		return (-1);
2433
	}
2434
2435
	/* EBGP neighbors are not allowed in route reflector clusters */
2436
	if (p->conf.reflector_client && p->conf.ebgp) {
2437
		yyerror("EBGP neighbors are not allowed in route "
2438
		    "reflector clusters");
2439
		return (-1);
2440
	}
2441
2442
	/* the default MP capability is NONE */
2443
	for (i = 0; i < AID_MAX; i++)
2444
		if (p->conf.capabilities.mp[i] == -1)
2445
			p->conf.capabilities.mp[i] = 0;
2446
2447
	return (0);
2448
}
2449
2450
int
2451
merge_filterset(struct filter_set_head *sh, struct filter_set *s)
2452
{
2453
	struct filter_set	*t;
2454
2455
	TAILQ_FOREACH(t, sh, entry) {
2456
		/*
2457
		 * need to cycle across the full list because even
2458
		 * if types are not equal filterset_cmp() may return 0.
2459
		 */
2460
		if (filterset_cmp(s, t) == 0) {
2461
			if (s->type == ACTION_SET_COMMUNITY)
2462
				yyerror("community is already set");
2463
			else if (s->type == ACTION_DEL_COMMUNITY)
2464
				yyerror("community will already be deleted");
2465
			else if (s->type == ACTION_SET_LARGE_COMMUNITY)
2466
				yyerror("large-community is already set");
2467
			else if (s->type == ACTION_DEL_LARGE_COMMUNITY)
2468
				yyerror("large-community will already be deleted");
2469
			else if (s->type == ACTION_SET_EXT_COMMUNITY)
2470
				yyerror("ext-community is already set");
2471
			else if (s->type == ACTION_DEL_EXT_COMMUNITY)
2472
				yyerror(
2473
				    "ext-community will already be deleted");
2474
			else
2475
				yyerror("redefining set parameter %s",
2476
				    filterset_name(s->type));
2477
			return (-1);
2478
		}
2479
	}
2480
2481
	TAILQ_FOREACH(t, sh, entry) {
2482
		if (s->type < t->type) {
2483
			TAILQ_INSERT_BEFORE(t, s, entry);
2484
			return (0);
2485
		}
2486
		if (s->type == t->type)
2487
			switch (s->type) {
2488
			case ACTION_SET_COMMUNITY:
2489
			case ACTION_DEL_COMMUNITY:
2490
				if (s->action.community.as <
2491
				    t->action.community.as ||
2492
				    (s->action.community.as ==
2493
				    t->action.community.as &&
2494
				    s->action.community.type <
2495
				    t->action.community.type)) {
2496
					TAILQ_INSERT_BEFORE(t, s, entry);
2497
					return (0);
2498
				}
2499
				break;
2500
			case ACTION_SET_LARGE_COMMUNITY:
2501
			case ACTION_DEL_LARGE_COMMUNITY:
2502
				if (s->action.large_community.as <
2503
				    t->action.large_community.as ||
2504
				    (s->action.large_community.as ==
2505
				    t->action.large_community.as &&
2506
				    s->action.large_community.ld1 <
2507
				    t->action.large_community.ld2 )) {
2508
					TAILQ_INSERT_BEFORE(t, s, entry);
2509
					return (0);
2510
				}
2511
				break;
2512
			case ACTION_SET_EXT_COMMUNITY:
2513
			case ACTION_DEL_EXT_COMMUNITY:
2514
				if (memcmp(&s->action.ext_community,
2515
				    &t->action.ext_community,
2516
				    sizeof(s->action.ext_community)) < 0) {
2517
					TAILQ_INSERT_BEFORE(t, s, entry);
2518
					return (0);
2519
				}
2520
				break;
2521
			case ACTION_SET_NEXTHOP:
2522
				if (s->action.nexthop.aid <
2523
				    t->action.nexthop.aid) {
2524
					TAILQ_INSERT_BEFORE(t, s, entry);
2525
					return (0);
2526
				}
2527
				break;
2528
			default:
2529
				break;
2530
			}
2531
	}
2532
2533
	TAILQ_INSERT_TAIL(sh, s, entry);
2534
	return (0);
2535
}
2536
2537
void
2538
copy_filterset(struct filter_set_head *source, struct filter_set_head *dest)
2539
{
2540
	struct filter_set	*s, *t;
2541
2542
	if (source == NULL)
2543
		return;
2544
2545
	TAILQ_FOREACH(s, source, entry) {
2546
		if ((t = malloc(sizeof(struct filter_set))) == NULL)
2547
			fatal(NULL);
2548
		memcpy(t, s, sizeof(struct filter_set));
2549
		TAILQ_INSERT_TAIL(dest, t, entry);
2550
	}
2551
}
2552
2553
void
2554
merge_filter_lists(struct filter_head *dst, struct filter_head *src)
2555
{
2556
	struct filter_rule *r;
2557
2558
	while ((r = TAILQ_FIRST(src)) != NULL) {
2559
		TAILQ_REMOVE(src, r, entry);
2560
		TAILQ_INSERT_TAIL(dst, r, entry);
2561
	}
2562
}
2563
2564
struct filter_rule *
2565
get_rule(enum action_types type)
2566
{
2567
	struct filter_rule	*r;
2568
	int			 out;
2569
2570
	switch (type) {
2571
	case ACTION_SET_PREPEND_SELF:
2572
	case ACTION_SET_NEXTHOP_NOMODIFY:
2573
	case ACTION_SET_NEXTHOP_SELF:
2574
		out = 1;
2575
		break;
2576
	default:
2577
		out = 0;
2578
		break;
2579
	}
2580
	r = (curpeer == curgroup) ? curgroup_filter[out] : curpeer_filter[out];
2581
	if (r == NULL) {
2582
		if ((r = calloc(1, sizeof(struct filter_rule))) == NULL)
2583
			fatal(NULL);
2584
		r->quick = 0;
2585
		r->dir = out ? DIR_OUT : DIR_IN;
2586
		r->action = ACTION_NONE;
2587
		r->match.community.as = COMMUNITY_UNSET;
2588
		r->match.large_community.as = COMMUNITY_UNSET;
2589
		TAILQ_INIT(&r->set);
2590
		if (curpeer == curgroup) {
2591
			/* group */
2592
			r->peer.groupid = curgroup->conf.id;
2593
			curgroup_filter[out] = r;
2594
		} else {
2595
			/* peer */
2596
			r->peer.peerid = curpeer->conf.id;
2597
			curpeer_filter[out] = r;
2598
		}
2599
	}
2600
	return (r);
2601
}
2602
#line 2595 "parse.c"
2603
24
/* allocate initial stack or double stack size, up to YYMAXDEPTH */
2604
12
static int yygrowstack(void)
2605
{
2606
    unsigned int newsize;
2607
    long sslen;
2608
    short *newss;
2609
12
    YYSTYPE *newvs;
2610
2611
    if ((newsize = yystacksize) == 0)
2612
        newsize = YYINITSTACKSIZE;
2613
    else if (newsize >= YYMAXDEPTH)
2614
        return -1;
2615

24
    else if ((newsize *= 2) > YYMAXDEPTH)
2616
        newsize = YYMAXDEPTH;
2617
24
    sslen = yyssp - yyss;
2618
12
#ifdef SIZE_MAX
2619
12
#define YY_SIZE_MAX SIZE_MAX
2620
#else
2621
12
#define YY_SIZE_MAX 0xffffffffU
2622
12
#endif
2623

24
    if (newsize && YY_SIZE_MAX / newsize < sizeof *newss)
2624
        goto bail;
2625
24
    newss = yyss ? (short *)realloc(yyss, newsize * sizeof *newss) :
2626
12
      (short *)malloc(newsize * sizeof *newss); /* overflow check above */
2627
12
    if (newss == NULL)
2628
        goto bail;
2629
12
    yyss = newss;
2630
12
    yyssp = newss + sslen;
2631
12
    if (newsize && YY_SIZE_MAX / newsize < sizeof *newvs)
2632
12
        goto bail;
2633
12
    newvs = yyvs ? (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs) :
2634
      (YYSTYPE *)malloc(newsize * sizeof *newvs); /* overflow check above */
2635
    if (newvs == NULL)
2636
        goto bail;
2637
    yyvs = newvs;
2638
    yyvsp = newvs + sslen;
2639
    yystacksize = newsize;
2640
    yysslim = yyss + newsize - 1;
2641
    return 0;
2642
bail:
2643
12
    if (yyss)
2644
            free(yyss);
2645
    if (yyvs)
2646
            free(yyvs);
2647
    yyss = yyssp = NULL;
2648
    yyvs = yyvsp = NULL;
2649
    yystacksize = 0;
2650
    return -1;
2651
}
2652
2653
#define YYABORT goto yyabort
2654
#define YYREJECT goto yyabort
2655
#define YYACCEPT goto yyaccept
2656
#define YYERROR goto yyerrlab
2657
int
2658
yyparse(void)
2659
{
2660
    int yym, yyn, yystate;
2661
#if YYDEBUG
2662
    const char *yys;
2663
2664
24
    if ((yys = getenv("YYDEBUG")))
2665
12
    {
2666
12
        yyn = *yys;
2667
        if (yyn >= '0' && yyn <= '9')
2668

24
            yydebug = yyn - '0';
2669
12
    }
2670
12
#endif /* YYDEBUG */
2671
12
2672
    yynerrs = 0;
2673
    yyerrflag = 0;
2674
7240
    yychar = (-1);
2675
3884
2676
    if (yyss == NULL && yygrowstack()) goto yyoverflow;
2677
2192
    yyssp = yyss;
2678
    yyvsp = yyvs;
2679
    *yyssp = yystate = 0;
2680
2681
yyloop:
2682
    if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
2683
    if (yychar < 0)
2684
    {
2685
        if ((yychar = yylex()) < 0) yychar = 0;
2686
#if YYDEBUG
2687
        if (yydebug)
2688
2192
        {
2689

14740
            yys = 0;
2690
7156
            if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
2691
            if (!yys) yys = "illegal-symbol";
2692
            printf("%sdebug: state %d, reading %d (%s)\n",
2693
                    YYPREFIX, yystate, yychar, yys);
2694
        }
2695
#endif
2696
    }
2697

2660
    if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
2698
            yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
2699
    {
2700
#if YYDEBUG
2701
2660
        if (yydebug)
2702
2660
            printf("%sdebug: state %d, shifting to state %d\n",
2703
2660
                    YYPREFIX, yystate, yytable[yyn]);
2704
2660
#endif
2705
2660
        if (yyssp >= yysslim && yygrowstack())
2706
        {
2707

4896
            goto yyoverflow;
2708
2448
        }
2709
        *++yyssp = yystate = yytable[yyn];
2710
1224
        *++yyvsp = yylval;
2711
1224
        yychar = (-1);
2712
        if (yyerrflag > 0)  --yyerrflag;
2713
        goto yyloop;
2714
    }
2715
    if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
2716
            yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
2717
    {
2718
        yyn = yytable[yyn];
2719
        goto yyreduce;
2720
    }
2721
    if (yyerrflag) goto yyinrecovery;
2722
#if defined(__GNUC__)
2723
    goto yynewerror;
2724
#endif
2725
yynewerror:
2726
    yyerror("syntax error");
2727
#if defined(__GNUC__)
2728
    goto yyerrlab;
2729
#endif
2730
yyerrlab:
2731
    ++yynerrs;
2732
yyinrecovery:
2733
    if (yyerrflag < 3)
2734
    {
2735
        yyerrflag = 3;
2736
        for (;;)
2737
        {
2738
            if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
2739
                    yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
2740
            {
2741
#if YYDEBUG
2742
                if (yydebug)
2743
                    printf("%sdebug: state %d, error recovery shifting\
2744
 to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
2745
#endif
2746
                if (yyssp >= yysslim && yygrowstack())
2747
                {
2748
                    goto yyoverflow;
2749
                }
2750
                *++yyssp = yystate = yytable[yyn];
2751
                *++yyvsp = yylval;
2752
                goto yyloop;
2753
            }
2754
            else
2755
            {
2756
#if YYDEBUG
2757
                if (yydebug)
2758
                    printf("%sdebug: error recovery discarding state %d\n",
2759
                            YYPREFIX, *yyssp);
2760
#endif
2761
                if (yyssp <= yyss) goto yyabort;
2762
                --yyssp;
2763
                --yyvsp;
2764
            }
2765
        }
2766
    }
2767
    else
2768
    {
2769
        if (yychar == 0) goto yyabort;
2770
#if YYDEBUG
2771
        if (yydebug)
2772
        {
2773
            yys = 0;
2774
            if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
2775
            if (!yys) yys = "illegal-symbol";
2776
            printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
2777
                    YYPREFIX, yystate, yychar, yys);
2778
        }
2779
#endif
2780
        yychar = (-1);
2781
4580
        goto yyloop;
2782
4580
    }
2783
3564
yyreduce:
2784
#if YYDEBUG
2785
1016
    if (yydebug)
2786





















































7568
        printf("%sdebug: state %d, reducing by rule %d (%s)\n",
2787
                YYPREFIX, yystate, yyn, yyrule[yyn]);
2788
#endif
2789
    yym = yylen[yyn];
2790
    if (yym)
2791
        yyval = yyvsp[1-yym];
2792
    else
2793
        memset(&yyval, 0, sizeof yyval);
2794
    switch (yyn)
2795
    {
2796
case 10:
2797
#line 243 "parse.y"
2798
{ file->errors++; }
2799
break;
2800
case 11:
2801
#line 246 "parse.y"
2802
{
2803
			/*
2804
			 * According to iana 65535 and 4294967295 are reserved
2805
			 * but enforcing this is not duty of the parser.
2806
			 */
2807
			if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > UINT_MAX) {
2808
				yyerror("AS too big: max %u", UINT_MAX);
2809
				YYERROR;
2810
			}
2811
		}
2812
break;
2813
case 12:
2814
#line 257 "parse.y"
2815
{
2816
			const char	*errstr;
2817
			char		*dot;
2818
			u_int32_t	 uvalh = 0, uval;
2819
2820
			if ((dot = strchr(yyvsp[0].v.string,'.')) != NULL) {
2821
				*dot++ = '\0';
2822
				uvalh = strtonum(yyvsp[0].v.string, 0, USHRT_MAX, &errstr);
2823
				if (errstr) {
2824
					yyerror("number %s is %s", yyvsp[0].v.string, errstr);
2825
					free(yyvsp[0].v.string);
2826
					YYERROR;
2827
				}
2828
				uval = strtonum(dot, 0, USHRT_MAX, &errstr);
2829
				if (errstr) {
2830
					yyerror("number %s is %s", dot, errstr);
2831
					free(yyvsp[0].v.string);
2832
					YYERROR;
2833
				}
2834
				free(yyvsp[0].v.string);
2835
			} else {
2836
				yyerror("AS %s is bad", yyvsp[0].v.string);
2837
				free(yyvsp[0].v.string);
2838
				YYERROR;
2839
			}
2840
			if (uvalh == 0 && uval == AS_TRANS) {
2841
				yyerror("AS %u is reserved and may not be used",
2842
				    AS_TRANS);
2843
				YYERROR;
2844
			}
2845
			yyval.v.number = uval | (uvalh << 16);
2846
		}
2847
break;
2848
case 13:
2849
#line 289 "parse.y"
2850
{
2851
			if (yyvsp[0].v.number == AS_TRANS) {
2852
				yyerror("AS %u is reserved and may not be used",
2853
				    AS_TRANS);
2854
				YYERROR;
2855
			}
2856
			yyval.v.number = yyvsp[0].v.number;
2857
		}
2858
break;
2859
case 14:
2860
#line 299 "parse.y"
2861
{
2862
			const char	*errstr;
2863
			char		*dot;
2864
			u_int32_t	 uvalh = 0, uval;
2865
2866
			if ((dot = strchr(yyvsp[0].v.string,'.')) != NULL) {
2867
				*dot++ = '\0';
2868
				uvalh = strtonum(yyvsp[0].v.string, 0, USHRT_MAX, &errstr);
2869
				if (errstr) {
2870
					yyerror("number %s is %s", yyvsp[0].v.string, errstr);
2871
					free(yyvsp[0].v.string);
2872
					YYERROR;
2873
				}
2874
				uval = strtonum(dot, 0, USHRT_MAX, &errstr);
2875
				if (errstr) {
2876
					yyerror("number %s is %s", dot, errstr);
2877
					free(yyvsp[0].v.string);
2878
					YYERROR;
2879
				}
2880
				free(yyvsp[0].v.string);
2881
			} else {
2882
				yyerror("AS %s is bad", yyvsp[0].v.string);
2883
				free(yyvsp[0].v.string);
2884
				YYERROR;
2885
			}
2886
			yyval.v.number = uval | (uvalh << 16);
2887
		}
2888
break;
2889
case 15:
2890
#line 326 "parse.y"
2891
{
2892
			yyval.v.number = yyvsp[0].v.number;
2893
		}
2894
break;
2895
case 16:
2896
#line 331 "parse.y"
2897
{
2898
			if (asprintf(&yyval.v.string, "%s %s", yyvsp[-1].v.string, yyvsp[0].v.string) == -1)
2899
				fatal("string: asprintf");
2900
			free(yyvsp[-1].v.string);
2901
			free(yyvsp[0].v.string);
2902
		}
2903
break;
2904
case 18:
2905
#line 340 "parse.y"
2906
{
2907
			if (!strcmp(yyvsp[0].v.string, "yes"))
2908
				yyval.v.number = 1;
2909
			else if (!strcmp(yyvsp[0].v.string, "no"))
2910
				yyval.v.number = 0;
2911
			else {
2912
				yyerror("syntax error, "
2913
				    "either yes or no expected");
2914
				free(yyvsp[0].v.string);
2915
				YYERROR;
2916
			}
2917
			free(yyvsp[0].v.string);
2918
		}
2919
break;
2920
case 19:
2921
#line 355 "parse.y"
2922
{
2923
			char *s = yyvsp[-2].v.string;
2924
			if (cmd_opts & BGPD_OPT_VERBOSE)
2925
				printf("%s = \"%s\"\n", yyvsp[-2].v.string, yyvsp[0].v.string);
2926
			while (*s++) {
2927
				if (isspace((unsigned char)*s)) {
2928
					yyerror("macro name cannot contain "
2929
					    "whitespace");
2930
					YYERROR;
2931
				}
2932
			}
2933
			if (symset(yyvsp[-2].v.string, yyvsp[0].v.string, 0) == -1)
2934
				fatal("cannot store variable");
2935
			free(yyvsp[-2].v.string);
2936
			free(yyvsp[0].v.string);
2937
		}
2938
break;
2939
case 20:
2940
#line 373 "parse.y"
2941
{
2942
			struct file	*nfile;
2943
2944
			if ((nfile = pushfile(yyvsp[0].v.string, 1)) == NULL) {
2945
				yyerror("failed to include file %s", yyvsp[0].v.string);
2946
				free(yyvsp[0].v.string);
2947
				YYERROR;
2948
			}
2949
			free(yyvsp[0].v.string);
2950
2951
			file = nfile;
2952
			lungetc('\n');
2953
		}
2954
break;
2955
case 21:
2956
#line 388 "parse.y"
2957
{
2958
			conf->as = yyvsp[0].v.number;
2959
			if (yyvsp[0].v.number > USHRT_MAX)
2960
				conf->short_as = AS_TRANS;
2961
			else
2962
				conf->short_as = yyvsp[0].v.number;
2963
		}
2964
break;
2965
case 22:
2966
#line 395 "parse.y"
2967
{
2968
			conf->as = yyvsp[-1].v.number;
2969
			conf->short_as = yyvsp[0].v.number;
2970
		}
2971
break;
2972
case 23:
2973
#line 399 "parse.y"
2974
{
2975
			if (yyvsp[0].v.addr.aid != AID_INET) {
2976
				yyerror("router-id must be an IPv4 address");
2977
				YYERROR;
2978
			}
2979
			conf->bgpid = yyvsp[0].v.addr.v4.s_addr;
2980
		}
2981
break;
2982
case 24:
2983
#line 406 "parse.y"
2984
{
2985
			if (yyvsp[0].v.number < MIN_HOLDTIME || yyvsp[0].v.number > USHRT_MAX) {
2986
				yyerror("holdtime must be between %u and %u",
2987
				    MIN_HOLDTIME, USHRT_MAX);
2988
				YYERROR;
2989
			}
2990
			conf->holdtime = yyvsp[0].v.number;
2991
		}
2992
break;
2993
case 25:
2994
#line 414 "parse.y"
2995
{
2996
			if (yyvsp[0].v.number < MIN_HOLDTIME || yyvsp[0].v.number > USHRT_MAX) {
2997
				yyerror("holdtime must be between %u and %u",
2998
				    MIN_HOLDTIME, USHRT_MAX);
2999
				YYERROR;
3000
			}
3001
			conf->min_holdtime = yyvsp[0].v.number;
3002
		}
3003
break;
3004
case 26:
3005
#line 422 "parse.y"
3006
{
3007
			struct listen_addr	*la;
3008
3009
			if ((la = calloc(1, sizeof(struct listen_addr))) ==
3010
			    NULL)
3011
				fatal("parse conf_main listen on calloc");
3012
3013
			la->fd = -1;
3014
			memcpy(&la->sa, addr2sa(&yyvsp[0].v.addr, BGP_PORT), sizeof(la->sa));
3015
			TAILQ_INSERT_TAIL(conf->listen_addrs, la, entry);
3016
		}
3017
break;
3018
case 27:
3019
#line 433 "parse.y"
3020
{
3021
			if (yyvsp[0].v.number <= RTP_NONE || yyvsp[0].v.number > RTP_MAX) {
3022
				yyerror("invalid fib-priority");
3023
				YYERROR;
3024
			}
3025
			conf->fib_priority = yyvsp[0].v.number;
3026
		}
3027
break;
3028
case 28:
3029
#line 440 "parse.y"
3030
{
3031
			struct rde_rib *rr;
3032
			rr = find_rib("Loc-RIB");
3033
			if (rr == NULL)
3034
				fatalx("RTABLE can not find the main RIB!");
3035
3036
			if (yyvsp[0].v.number == 0)
3037
				rr->flags |= F_RIB_NOFIBSYNC;
3038
			else
3039
				rr->flags &= ~F_RIB_NOFIBSYNC;
3040
		}
3041
break;
3042
case 29:
3043
#line 451 "parse.y"
3044
{
3045
			if (yyvsp[0].v.number == 1)
3046
				conf->flags |= BGPD_FLAG_NO_EVALUATE;
3047
			else
3048
				conf->flags &= ~BGPD_FLAG_NO_EVALUATE;
3049
		}
3050
break;
3051
case 30:
3052
#line 457 "parse.y"
3053
{
3054
			if (add_rib(yyvsp[0].v.string, conf->default_tableid, F_RIB_NOFIB)) {
3055
				free(yyvsp[0].v.string);
3056
				YYERROR;
3057
			}
3058
			free(yyvsp[0].v.string);
3059
		}
3060
break;
3061
case 31:
3062
#line 464 "parse.y"
3063
{
3064
			if (yyvsp[-1].v.number) {
3065
				free(yyvsp[-2].v.string);
3066
				yyerror("bad rde rib definition");
3067
				YYERROR;
3068
			}
3069
			if (add_rib(yyvsp[-2].v.string, conf->default_tableid,
3070
			    F_RIB_NOFIB | F_RIB_NOEVALUATE)) {
3071
				free(yyvsp[-2].v.string);
3072
				YYERROR;
3073
			}
3074
			free(yyvsp[-2].v.string);
3075
		}
3076
break;
3077
case 32:
3078
#line 477 "parse.y"
3079
{
3080
			if (add_rib(yyvsp[-2].v.string, yyvsp[0].v.number, 0)) {
3081
				free(yyvsp[-2].v.string);
3082
				YYERROR;
3083
			}
3084
			free(yyvsp[-2].v.string);
3085
		}
3086
break;
3087
case 33:
3088
#line 484 "parse.y"
3089
{
3090
			int	flags = 0;
3091
			if (yyvsp[0].v.number == 0)
3092
				flags = F_RIB_NOFIBSYNC;
3093
			if (add_rib(yyvsp[-4].v.string, yyvsp[-2].v.number, flags)) {
3094
				free(yyvsp[-4].v.string);
3095
				YYERROR;
3096
			}
3097
			free(yyvsp[-4].v.string);
3098
		}
3099
break;
3100
case 34:
3101
#line 494 "parse.y"
3102
{
3103
			if (yyvsp[0].v.number == 1)
3104
				conf->flags |= BGPD_FLAG_DECISION_TRANS_AS;
3105
			else
3106
				conf->flags &= ~BGPD_FLAG_DECISION_TRANS_AS;
3107
		}
3108
break;
3109
case 35:
3110
#line 500 "parse.y"
3111
{
3112
			if (!strcmp(yyvsp[0].v.string, "updates"))
3113
				conf->log |= BGPD_LOG_UPDATES;
3114
			else {
3115
				free(yyvsp[0].v.string);
3116
				YYERROR;
3117
			}
3118
			free(yyvsp[0].v.string);
3119
		}
3120
break;
3121
case 37:
3122
#line 510 "parse.y"
3123
{
3124
			int action;
3125
3126
			if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX) {
3127
				yyerror("bad timeout");
3128
				free(yyvsp[-2].v.string);
3129
				free(yyvsp[-1].v.string);
3130
				YYERROR;
3131
			}
3132
			if (!strcmp(yyvsp[-2].v.string, "table"))
3133
				action = MRT_TABLE_DUMP;
3134
			else if (!strcmp(yyvsp[-2].v.string, "table-mp"))
3135
				action = MRT_TABLE_DUMP_MP;
3136
			else if (!strcmp(yyvsp[-2].v.string, "table-v2"))
3137
				action = MRT_TABLE_DUMP_V2;
3138
			else {
3139
				yyerror("unknown mrt dump type");
3140
				free(yyvsp[-2].v.string);
3141
				free(yyvsp[-1].v.string);
3142
				YYERROR;
3143
			}
3144
			free(yyvsp[-2].v.string);
3145
			if (add_mrtconfig(action, yyvsp[-1].v.string, yyvsp[0].v.number, NULL, NULL) == -1) {
3146
				free(yyvsp[-1].v.string);
3147
				YYERROR;
3148
			}
3149
			free(yyvsp[-1].v.string);
3150
		}
3151
break;
3152
case 38:
3153
#line 538 "parse.y"
3154
{
3155
			int action;
3156
3157
			if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX) {
3158
				yyerror("bad timeout");
3159
				free(yyvsp[-3].v.string);
3160
				free(yyvsp[-2].v.string);
3161
				free(yyvsp[-1].v.string);
3162
				YYERROR;
3163
			}
3164
			if (!strcmp(yyvsp[-2].v.string, "table"))
3165
				action = MRT_TABLE_DUMP;
3166
			else if (!strcmp(yyvsp[-2].v.string, "table-mp"))
3167
				action = MRT_TABLE_DUMP_MP;
3168
			else if (!strcmp(yyvsp[-2].v.string, "table-v2"))
3169
				action = MRT_TABLE_DUMP_V2;
3170
			else {
3171
				yyerror("unknown mrt dump type");
3172
				free(yyvsp[-3].v.string);
3173
				free(yyvsp[-2].v.string);
3174
				free(yyvsp[-1].v.string);
3175
				YYERROR;
3176
			}
3177
			free(yyvsp[-2].v.string);
3178
			if (add_mrtconfig(action, yyvsp[-1].v.string, yyvsp[0].v.number, NULL, yyvsp[-3].v.string) == -1) {
3179
				free(yyvsp[-3].v.string);
3180
				free(yyvsp[-1].v.string);
3181
				YYERROR;
3182
			}
3183
			free(yyvsp[-3].v.string);
3184
			free(yyvsp[-1].v.string);
3185
		}
3186
break;
3187
case 40:
3188
#line 571 "parse.y"
3189
{
3190
			if (!strcmp(yyvsp[-1].v.string, "route-age"))
3191
				conf->flags |= BGPD_FLAG_DECISION_ROUTEAGE;
3192
			else {
3193
				yyerror("unknown route decision type");
3194
				free(yyvsp[-1].v.string);
3195
				YYERROR;
3196
			}
3197
			free(yyvsp[-1].v.string);
3198
		}
3199
break;
3200
case 41:
3201
#line 581 "parse.y"
3202
{
3203
			if (!strcmp(yyvsp[-1].v.string, "route-age"))
3204
				conf->flags &= ~BGPD_FLAG_DECISION_ROUTEAGE;
3205
			else {
3206
				yyerror("unknown route decision type");
3207
				free(yyvsp[-1].v.string);
3208
				YYERROR;
3209
			}
3210
			free(yyvsp[-1].v.string);
3211
		}
3212
break;
3213
case 42:
3214
#line 591 "parse.y"
3215
{
3216
			if (!strcmp(yyvsp[0].v.string, "always"))
3217
				conf->flags |= BGPD_FLAG_DECISION_MED_ALWAYS;
3218
			else if (!strcmp(yyvsp[0].v.string, "strict"))
3219
				conf->flags &= ~BGPD_FLAG_DECISION_MED_ALWAYS;
3220
			else {
3221
				yyerror("rde med compare: "
3222
				    "unknown setting \"%s\"", yyvsp[0].v.string);
3223
				free(yyvsp[0].v.string);
3224
				YYERROR;
3225
			}
3226
			free(yyvsp[0].v.string);
3227
		}
3228
break;
3229
case 43:
3230
#line 604 "parse.y"
3231
{
3232
			if (!strcmp(yyvsp[0].v.string, "bgp"))
3233
				conf->flags |= BGPD_FLAG_NEXTHOP_BGP;
3234
			else if (!strcmp(yyvsp[0].v.string, "default"))
3235
				conf->flags |= BGPD_FLAG_NEXTHOP_DEFAULT;
3236
			else {
3237
				yyerror("nexthop depend on: "
3238
				    "unknown setting \"%s\"", yyvsp[0].v.string);
3239
				free(yyvsp[0].v.string);
3240
				YYERROR;
3241
			}
3242
			free(yyvsp[0].v.string);
3243
		}
3244
break;
3245
case 44:
3246
#line 617 "parse.y"
3247
{
3248
			struct rde_rib *rr;
3249
			if (ktable_exists(yyvsp[0].v.number, NULL) != 1) {
3250
				yyerror("rtable id %lld does not exist", yyvsp[0].v.number);
3251
				YYERROR;
3252
			}
3253
			rr = find_rib("Loc-RIB");
3254
			if (rr == NULL)
3255
				fatalx("RTABLE can not find the main RIB!");
3256
			rr->rtableid = yyvsp[0].v.number;
3257
		}
3258
break;
3259
case 45:
3260
#line 628 "parse.y"
3261
{
3262
			if (yyvsp[0].v.number > USHRT_MAX || yyvsp[0].v.number < 1) {
3263
				yyerror("invalid connect-retry");
3264
				YYERROR;
3265
			}
3266
			conf->connectretry = yyvsp[0].v.number;
3267
		}
3268
break;
3269
case 46:
3270
#line 635 "parse.y"
3271
{
3272
			if (strlen(yyvsp[-1].v.string) >=
3273
			    sizeof(((struct sockaddr_un *)0)->sun_path)) {
3274
				yyerror("socket path too long");
3275
				YYERROR;
3276
			}
3277
			if (yyvsp[0].v.number) {
3278
				free(conf->rcsock);
3279
				conf->rcsock = yyvsp[-1].v.string;
3280
			} else {
3281
				free(conf->csock);
3282
				conf->csock = yyvsp[-1].v.string;
3283
			}
3284
		}
3285
break;
3286
case 47:
3287
#line 651 "parse.y"
3288
{
3289
			int action;
3290
3291
			if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX) {
3292
				yyerror("bad timeout");
3293
				free(yyvsp[-3].v.string);
3294
				free(yyvsp[-1].v.string);
3295
				YYERROR;
3296
			}
3297
			if (!strcmp(yyvsp[-3].v.string, "all"))
3298
				action = yyvsp[-2].v.number ? MRT_ALL_IN : MRT_ALL_OUT;
3299
			else if (!strcmp(yyvsp[-3].v.string, "updates"))
3300
				action = yyvsp[-2].v.number ? MRT_UPDATE_IN : MRT_UPDATE_OUT;
3301
			else {
3302
				yyerror("unknown mrt msg dump type");
3303
				free(yyvsp[-3].v.string);
3304
				free(yyvsp[-1].v.string);
3305
				YYERROR;
3306
			}
3307
			if (add_mrtconfig(action, yyvsp[-1].v.string, yyvsp[0].v.number, curpeer, NULL) ==
3308
			    -1) {
3309
				free(yyvsp[-3].v.string);
3310
				free(yyvsp[-1].v.string);
3311
				YYERROR;
3312
			}
3313
			free(yyvsp[-3].v.string);
3314
			free(yyvsp[-1].v.string);
3315
		}
3316
break;
3317
case 48:
3318
#line 681 "parse.y"
3319
{
3320
			struct network	*n, *m;
3321
3322
			if ((n = calloc(1, sizeof(struct network))) == NULL)
3323
				fatal("new_network");
3324
			memcpy(&n->net.prefix, &yyvsp[-1].v.prefix.prefix,
3325
			    sizeof(n->net.prefix));
3326
			n->net.prefixlen = yyvsp[-1].v.prefix.len;
3327
			filterset_move(yyvsp[0].v.filter_set_head, &n->net.attrset);
3328
			free(yyvsp[0].v.filter_set_head);
3329
			TAILQ_FOREACH(m, netconf, entry) {
3330
				if (n->net.prefixlen == m->net.prefixlen &&
3331
				    prefix_compare(&n->net.prefix,
3332
				    &m->net.prefix, n->net.prefixlen) == 0)
3333
					yyerror("duplicate prefix "
3334
					    "in network statement");
3335
			}
3336
3337
			TAILQ_INSERT_TAIL(netconf, n, entry);
3338
		}
3339
break;
3340
case 49:
3341
#line 701 "parse.y"
3342
{
3343
			struct network	*n;
3344
3345
			if ((n = calloc(1, sizeof(struct network))) == NULL)
3346
				fatal("new_network");
3347
			if (afi2aid(yyvsp[-3].v.number, SAFI_UNICAST, &n->net.prefix.aid) ==
3348
			    -1) {
3349
				yyerror("unknown family");
3350
				filterset_free(yyvsp[0].v.filter_set_head);
3351
				free(yyvsp[0].v.filter_set_head);
3352
				YYERROR;
3353
			}
3354
			n->net.type = NETWORK_RTLABEL;
3355
			n->net.rtlabel = rtlabel_name2id(yyvsp[-1].v.string);
3356
			filterset_move(yyvsp[0].v.filter_set_head, &n->net.attrset);
3357
			free(yyvsp[0].v.filter_set_head);
3358
3359
			TAILQ_INSERT_TAIL(netconf, n, entry);
3360
		}
3361
break;
3362
case 50:
3363
#line 720 "parse.y"
3364
{
3365
			struct network	*n;
3366
3367
			if ((n = calloc(1, sizeof(struct network))) == NULL)
3368
				fatal("new_network");
3369
			if (afi2aid(yyvsp[-2].v.number, SAFI_UNICAST, &n->net.prefix.aid) ==
3370
			    -1) {
3371
				yyerror("unknown family");
3372
				filterset_free(yyvsp[0].v.filter_set_head);
3373
				free(yyvsp[0].v.filter_set_head);
3374
				YYERROR;
3375
			}
3376
			n->net.type = yyvsp[-1].v.number ? NETWORK_STATIC : NETWORK_CONNECTED;
3377
			filterset_move(yyvsp[0].v.filter_set_head, &n->net.attrset);
3378
			free(yyvsp[0].v.filter_set_head);
3379
3380
			TAILQ_INSERT_TAIL(netconf, n, entry);
3381
		}
3382
break;
3383
case 51:
3384
#line 740 "parse.y"
3385
{ yyval.v.number = 1; }
3386
break;
3387
case 52:
3388
#line 741 "parse.y"
3389
{ yyval.v.number = 0; }
3390
break;
3391
case 53:
3392
#line 744 "parse.y"
3393
{ yyval.v.number = 1; }
3394
break;
3395
case 54:
3396
#line 745 "parse.y"
3397
{ yyval.v.number = 0; }
3398
break;
3399
case 55:
3400
#line 748 "parse.y"
3401
{
3402
			u_int8_t	len;
3403
3404
			if (!host(yyvsp[0].v.string, &yyval.v.addr, &len)) {
3405
				yyerror("could not parse address spec \"%s\"",
3406
				    yyvsp[0].v.string);
3407
				free(yyvsp[0].v.string);
3408
				YYERROR;
3409
			}
3410
			free(yyvsp[0].v.string);
3411
3412
			if ((yyval.v.addr.aid == AID_INET && len != 32) ||
3413
			    (yyval.v.addr.aid == AID_INET6 && len != 128)) {
3414
				/* unreachable */
3415
				yyerror("got prefixlen %u, expected %u",
3416
				    len, yyval.v.addr.aid == AID_INET ? 32 : 128);
3417
				YYERROR;
3418
			}
3419
		}
3420
break;
3421
case 56:
3422
#line 769 "parse.y"
3423
{
3424
			char	*s;
3425
3426
			if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > 128) {
3427
				yyerror("bad prefixlen %lld", yyvsp[0].v.number);
3428
				free(yyvsp[-2].v.string);
3429
				YYERROR;
3430
			}
3431
			if (asprintf(&s, "%s/%lld", yyvsp[-2].v.string, yyvsp[0].v.number) == -1)
3432
				fatal(NULL);
3433
			free(yyvsp[-2].v.string);
3434
3435
			if (!host(s, &yyval.v.prefix.prefix, &yyval.v.prefix.len)) {
3436
				yyerror("could not parse address \"%s\"", s);
3437
				free(s);
3438
				YYERROR;
3439
			}
3440
			free(s);
3441
		}
3442
break;
3443
case 57:
3444
#line 788 "parse.y"
3445
{
3446
			char	*s;
3447
3448
			/* does not match IPv6 */
3449
			if (yyvsp[-2].v.number < 0 || yyvsp[-2].v.number > 255 || yyvsp[0].v.number < 0 || yyvsp[0].v.number > 32) {
3450
				yyerror("bad prefix %lld/%lld", yyvsp[-2].v.number, yyvsp[0].v.number);
3451
				YYERROR;
3452
			}
3453
			if (asprintf(&s, "%lld/%lld", yyvsp[-2].v.number, yyvsp[0].v.number) == -1)
3454
				fatal(NULL);
3455
3456
			if (!host(s, &yyval.v.prefix.prefix, &yyval.v.prefix.len)) {
3457
				yyerror("could not parse address \"%s\"", s);
3458
				free(s);
3459
				YYERROR;
3460
			}
3461
			free(s);
3462
		}
3463
break;
3464
case 58:
3465
#line 808 "parse.y"
3466
{
3467
			memcpy(&yyval.v.prefix.prefix, &yyvsp[0].v.addr, sizeof(struct bgpd_addr));
3468
			if (yyval.v.prefix.prefix.aid == AID_INET)
3469
				yyval.v.prefix.len = 32;
3470
			else
3471
				yyval.v.prefix.len = 128;
3472
		}
3473
break;
3474
case 63:
3475
#line 825 "parse.y"
3476
{ yyval.v.number = 0; }
3477
break;
3478
case 65:
3479
#line 829 "parse.y"
3480
{
3481
			if (ktable_exists(yyvsp[-3].v.number, NULL) != 1) {
3482
				yyerror("rdomain %lld does not exist", yyvsp[-3].v.number);
3483
				YYERROR;
3484
			}
3485
			if (!(currdom = calloc(1, sizeof(struct rdomain))))
3486
				fatal(NULL);
3487
			currdom->rtableid = yyvsp[-3].v.number;
3488
			TAILQ_INIT(&currdom->import);
3489
			TAILQ_INIT(&currdom->export);
3490
			TAILQ_INIT(&currdom->net_l);
3491
			netconf = &currdom->net_l;
3492
		}
3493
break;
3494
case 66:
3495
#line 842 "parse.y"
3496
{
3497
			/* insert into list */
3498
			SIMPLEQ_INSERT_TAIL(&conf->rdomains, currdom, entry);
3499
			currdom = NULL;
3500
			netconf = &conf->networks;
3501
		}
3502
break;
3503
case 70:
3504
#line 856 "parse.y"
3505
{
3506
			struct filter_extcommunity	ext;
3507
			u_int64_t			rd;
3508
3509
			if (parseextcommunity(&ext, "rt", yyvsp[0].v.string) == -1) {
3510
				free(yyvsp[0].v.string);
3511
				YYERROR;
3512
			}
3513
			free(yyvsp[0].v.string);
3514
			/*
3515
			 * RD is almost encode like an ext-community,
3516
			 * but only almost so convert here.
3517
			 */
3518
			if (community_ext_conv(&ext, 0, &rd)) {
3519
				yyerror("bad encoding of rd");
3520
				YYERROR;
3521
			}
3522
			rd = betoh64(rd) & 0xffffffffffffULL;
3523
			switch (ext.type) {
3524
			case EXT_COMMUNITY_TRANS_TWO_AS:
3525
				rd |= (0ULL << 48);
3526
				break;
3527
			case EXT_COMMUNITY_TRANS_IPV4:
3528
				rd |= (1ULL << 48);
3529
				break;
3530
			case EXT_COMMUNITY_TRANS_FOUR_AS:
3531
				rd |= (2ULL << 48);
3532
				break;
3533
			default:
3534
				yyerror("bad encoding of rd");
3535
				YYERROR;
3536
			}
3537
			currdom->rd = htobe64(rd);
3538
		}
3539
break;
3540
case 71:
3541
#line 890 "parse.y"
3542
{
3543
			struct filter_set	*set;
3544
3545
			if ((set = calloc(1, sizeof(struct filter_set))) ==
3546
			    NULL)
3547
				fatal(NULL);
3548
			set->type = ACTION_SET_EXT_COMMUNITY;
3549
			if (parseextcommunity(&set->action.ext_community,
3550
			    yyvsp[-1].v.string, yyvsp[0].v.string) == -1) {
3551
				free(yyvsp[0].v.string);
3552
				free(yyvsp[-1].v.string);
3553
				free(set);
3554
				YYERROR;
3555
			}
3556
			free(yyvsp[0].v.string);
3557
			free(yyvsp[-1].v.string);
3558
			TAILQ_INSERT_TAIL(&currdom->export, set, entry);
3559
		}
3560
break;
3561
case 72:
3562
#line 908 "parse.y"
3563
{
3564
			struct filter_set	*set;
3565
3566
			if ((set = calloc(1, sizeof(struct filter_set))) ==
3567
			    NULL)
3568
				fatal(NULL);
3569
			set->type = ACTION_SET_EXT_COMMUNITY;
3570
			if (parseextcommunity(&set->action.ext_community,
3571
			    yyvsp[-1].v.string, yyvsp[0].v.string) == -1) {
3572
				free(yyvsp[0].v.string);
3573
				free(yyvsp[-1].v.string);
3574
				free(set);
3575
				YYERROR;
3576
			}
3577
			free(yyvsp[0].v.string);
3578
			free(yyvsp[-1].v.string);
3579
			TAILQ_INSERT_TAIL(&currdom->import, set, entry);
3580
		}
3581
break;
3582
case 73:
3583
#line 926 "parse.y"
3584
{
3585
			if (strlcpy(currdom->descr, yyvsp[0].v.string,
3586
			    sizeof(currdom->descr)) >=
3587
			    sizeof(currdom->descr)) {
3588
				yyerror("descr \"%s\" too long: max %zu",
3589
				    yyvsp[0].v.string, sizeof(currdom->descr) - 1);
3590
				free(yyvsp[0].v.string);
3591
				YYERROR;
3592
			}
3593
			free(yyvsp[0].v.string);
3594
		}
3595
break;
3596
case 74:
3597
#line 937 "parse.y"
3598
{
3599
			if (yyvsp[0].v.number == 0)
3600
				currdom->flags |= F_RIB_NOFIBSYNC;
3601
			else
3602
				currdom->flags &= ~F_RIB_NOFIBSYNC;
3603
		}
3604
break;
3605
case 76:
3606
#line 944 "parse.y"
3607
{
3608
			/* XXX this is a hack */
3609
			if (if_nametoindex(yyvsp[0].v.string) == 0) {
3610
				yyerror("interface %s does not exist", yyvsp[0].v.string);
3611
				free(yyvsp[0].v.string);
3612
				YYERROR;
3613
			}
3614
			strlcpy(currdom->ifmpe, yyvsp[0].v.string, IFNAMSIZ);
3615
			free(yyvsp[0].v.string);
3616
			if (get_mpe_label(currdom)) {
3617
				yyerror("failed to get mpls label from %s",
3618
				    currdom->ifmpe);
3619
				YYERROR;
3620
			}
3621
		}
3622
break;
3623
case 77:
3624
#line 961 "parse.y"
3625
{	curpeer = new_peer(); }
3626
break;
3627
case 78:
3628
#line 962 "parse.y"
3629
{
3630
			memcpy(&curpeer->conf.remote_addr, &yyvsp[0].v.prefix.prefix,
3631
			    sizeof(curpeer->conf.remote_addr));
3632
			curpeer->conf.remote_masklen = yyvsp[0].v.prefix.len;
3633
			if ((yyvsp[0].v.prefix.prefix.aid == AID_INET && yyvsp[0].v.prefix.len != 32) ||
3634
			    (yyvsp[0].v.prefix.prefix.aid == AID_INET6 && yyvsp[0].v.prefix.len != 128))
3635
				curpeer->conf.template = 1;
3636
			if (curpeer->conf.capabilities.mp[
3637
			    curpeer->conf.remote_addr.aid] == -1)
3638
				curpeer->conf.capabilities.mp[
3639
				    curpeer->conf.remote_addr.aid] = 1;
3640
			if (get_id(curpeer)) {
3641
				yyerror("get_id failed");
3642
				YYERROR;
3643
			}
3644
		}
3645
break;
3646
case 79:
3647
#line 978 "parse.y"
3648
{
3649
			if (curpeer_filter[0] != NULL)
3650
				TAILQ_INSERT_TAIL(peerfilter_l,
3651
				    curpeer_filter[0], entry);
3652
			if (curpeer_filter[1] != NULL)
3653
				TAILQ_INSERT_TAIL(peerfilter_l,
3654
				    curpeer_filter[1], entry);
3655
			curpeer_filter[0] = NULL;
3656
			curpeer_filter[1] = NULL;
3657
3658
			if (neighbor_consistent(curpeer) == -1)
3659
				YYERROR;
3660
			curpeer->next = peer_l;
3661
			peer_l = curpeer;
3662
			curpeer = curgroup;
3663
		}
3664
break;
3665
case 80:
3666
#line 996 "parse.y"
3667
{
3668
			curgroup = curpeer = new_group();
3669
			if (strlcpy(curgroup->conf.group, yyvsp[-3].v.string,
3670
			    sizeof(curgroup->conf.group)) >=
3671
			    sizeof(curgroup->conf.group)) {
3672
				yyerror("group name \"%s\" too long: max %zu",
3673
				    yyvsp[-3].v.string, sizeof(curgroup->conf.group) - 1);
3674
				free(yyvsp[-3].v.string);
3675
				YYERROR;
3676
			}
3677
			free(yyvsp[-3].v.string);
3678
			if (get_id(curgroup)) {
3679
				yyerror("get_id failed");
3680
				YYERROR;
3681
			}
3682
		}
3683
break;
3684
case 81:
3685
#line 1012 "parse.y"
3686
{
3687
			if (curgroup_filter[0] != NULL)
3688
				TAILQ_INSERT_TAIL(groupfilter_l,
3689
				    curgroup_filter[0], entry);
3690
			if (curgroup_filter[1] != NULL)
3691
				TAILQ_INSERT_TAIL(groupfilter_l,
3692
				    curgroup_filter[1], entry);
3693
			curgroup_filter[0] = NULL;
3694
			curgroup_filter[1] = NULL;
3695
3696
			free(curgroup);
3697
			curgroup = NULL;
3698
		}
3699
break;
3700
case 92:
3701
#line 1047 "parse.y"
3702
{
3703
			curpeer->conf.remote_as = yyvsp[0].v.number;
3704
		}
3705
break;
3706
case 93:
3707
#line 1050 "parse.y"
3708
{
3709
			curpeer->conf.local_as = yyvsp[0].v.number;
3710
			if (yyvsp[0].v.number > USHRT_MAX)
3711
				curpeer->conf.local_short_as = AS_TRANS;
3712
			else
3713
				curpeer->conf.local_short_as = yyvsp[0].v.number;
3714
		}
3715
break;
3716
case 94:
3717
#line 1057 "parse.y"
3718
{
3719
			curpeer->conf.local_as = yyvsp[-1].v.number;
3720
			curpeer->conf.local_short_as = yyvsp[0].v.number;
3721
		}
3722
break;
3723
case 95:
3724
#line 1061 "parse.y"
3725
{
3726
			if (strlcpy(curpeer->conf.descr, yyvsp[0].v.string,
3727
			    sizeof(curpeer->conf.descr)) >=
3728
			    sizeof(curpeer->conf.descr)) {
3729
				yyerror("descr \"%s\" too long: max %zu",
3730
				    yyvsp[0].v.string, sizeof(curpeer->conf.descr) - 1);
3731
				free(yyvsp[0].v.string);
3732
				YYERROR;
3733
			}
3734
			free(yyvsp[0].v.string);
3735
		}
3736
break;
3737
case 96:
3738
#line 1072 "parse.y"
3739
{
3740
			memcpy(&curpeer->conf.local_addr, &yyvsp[0].v.addr,
3741
			    sizeof(curpeer->conf.local_addr));
3742
		}
3743
break;
3744
case 97:
3745
#line 1076 "parse.y"
3746
{
3747
			if (yyvsp[0].v.number < 2 || yyvsp[0].v.number > 255) {
3748
				yyerror("invalid multihop distance %lld", yyvsp[0].v.number);
3749
				YYERROR;
3750
			}
3751
			curpeer->conf.distance = yyvsp[0].v.number;
3752
		}
3753
break;
3754
case 98:
3755
#line 1083 "parse.y"
3756
{
3757
			curpeer->conf.passive = 1;
3758
		}
3759
break;
3760
case 99:
3761
#line 1086 "parse.y"
3762
{
3763
			curpeer->conf.down = 1;
3764
		}
3765
break;
3766
case 100:
3767
#line 1089 "parse.y"
3768
{
3769
			curpeer->conf.down = 1;
3770
			if (strlcpy(curpeer->conf.shutcomm, yyvsp[0].v.string,
3771
				sizeof(curpeer->conf.shutcomm)) >=
3772
				sizeof(curpeer->conf.shutcomm)) {
3773
				    yyerror("shutdown reason too long");
3774
				    free(yyvsp[0].v.string);
3775
				    YYERROR;
3776
			}
3777
			free(yyvsp[0].v.string);
3778
		}
3779
break;
3780
case 101:
3781
#line 1100 "parse.y"
3782
{
3783
			if (!find_rib(yyvsp[0].v.string)) {
3784
				yyerror("rib \"%s\" does not exist.", yyvsp[0].v.string);
3785
				free(yyvsp[0].v.string);
3786
				YYERROR;
3787
			}
3788
			if (strlcpy(curpeer->conf.rib, yyvsp[0].v.string,
3789
			    sizeof(curpeer->conf.rib)) >=
3790
			    sizeof(curpeer->conf.rib)) {
3791
				yyerror("rib name \"%s\" too long: max %zu",
3792
				   yyvsp[0].v.string, sizeof(curpeer->conf.rib) - 1);
3793
				free(yyvsp[0].v.string);
3794
				YYERROR;
3795
			}
3796
			free(yyvsp[0].v.string);
3797
		}
3798
break;
3799
case 102:
3800
#line 1116 "parse.y"
3801
{
3802
			if (yyvsp[0].v.number < MIN_HOLDTIME || yyvsp[0].v.number > USHRT_MAX) {
3803
				yyerror("holdtime must be between %u and %u",
3804
				    MIN_HOLDTIME, USHRT_MAX);
3805
				YYERROR;
3806
			}
3807
			curpeer->conf.holdtime = yyvsp[0].v.number;
3808
		}
3809
break;
3810
case 103:
3811
#line 1124 "parse.y"
3812
{
3813
			if (yyvsp[0].v.number < MIN_HOLDTIME || yyvsp[0].v.number > USHRT_MAX) {
3814
				yyerror("holdtime must be between %u and %u",
3815
				    MIN_HOLDTIME, USHRT_MAX);
3816
				YYERROR;
3817
			}
3818
			curpeer->conf.min_holdtime = yyvsp[0].v.number;
3819
		}
3820
break;
3821
case 104:
3822
#line 1132 "parse.y"
3823
{
3824
			u_int8_t	aid, safi;
3825
			int8_t		val = 1;
3826
3827
			if (!strcmp(yyvsp[0].v.string, "none")) {
3828
				safi = SAFI_UNICAST;
3829
				val = 0;
3830
			} else if (!strcmp(yyvsp[0].v.string, "unicast")) {
3831
				safi = SAFI_UNICAST;
3832
			} else if (!strcmp(yyvsp[0].v.string, "vpn")) {
3833
				safi = SAFI_MPLSVPN;
3834
			} else {
3835
				yyerror("unknown/unsupported SAFI \"%s\"",
3836
				    yyvsp[0].v.string);
3837
				free(yyvsp[0].v.string);
3838
				YYERROR;
3839
			}
3840
			free(yyvsp[0].v.string);
3841
3842
			if (afi2aid(yyvsp[-1].v.number, safi, &aid) == -1) {
3843
				yyerror("unknown AFI/SAFI pair");
3844
				YYERROR;
3845
			}
3846
			curpeer->conf.capabilities.mp[aid] = val;
3847
		}
3848
break;
3849
case 105:
3850
#line 1157 "parse.y"
3851
{
3852
			curpeer->conf.announce_capa = yyvsp[0].v.number;
3853
		}
3854
break;
3855
case 106:
3856
#line 1160 "parse.y"
3857
{
3858
			curpeer->conf.capabilities.refresh = yyvsp[0].v.number;
3859
		}
3860
break;
3861
case 107:
3862
#line 1163 "parse.y"
3863
{
3864
			curpeer->conf.capabilities.grestart.restart = yyvsp[0].v.number;
3865
		}
3866
break;
3867
case 108:
3868
#line 1166 "parse.y"
3869
{
3870
			curpeer->conf.capabilities.as4byte = yyvsp[0].v.number;
3871
		}
3872
break;
3873
case 109:
3874
#line 1169 "parse.y"
3875
{
3876
			curpeer->conf.announce_type = ANNOUNCE_SELF;
3877
		}
3878
break;
3879
case 110:
3880
#line 1172 "parse.y"
3881
{
3882
			if (!strcmp(yyvsp[0].v.string, "self"))
3883
				curpeer->conf.announce_type = ANNOUNCE_SELF;
3884
			else if (!strcmp(yyvsp[0].v.string, "none"))
3885
				curpeer->conf.announce_type = ANNOUNCE_NONE;
3886
			else if (!strcmp(yyvsp[0].v.string, "all"))
3887
				curpeer->conf.announce_type = ANNOUNCE_ALL;
3888
			else if (!strcmp(yyvsp[0].v.string, "default-route"))
3889
				curpeer->conf.announce_type =
3890
				    ANNOUNCE_DEFAULT_ROUTE;
3891
			else {
3892
				yyerror("invalid announce type");
3893
				free(yyvsp[0].v.string);
3894
				YYERROR;
3895
			}
3896
			free(yyvsp[0].v.string);
3897
		}
3898
break;
3899
case 111:
3900
#line 1189 "parse.y"
3901
{
3902
			if (yyvsp[0].v.number)
3903
				curpeer->conf.enforce_as = ENFORCE_AS_ON;
3904
			else
3905
				curpeer->conf.enforce_as = ENFORCE_AS_OFF;
3906
		}
3907
break;
3908
case 112:
3909
#line 1195 "parse.y"
3910
{
3911
			if (yyvsp[0].v.number)
3912
				curpeer->conf.enforce_local_as = ENFORCE_AS_ON;
3913
			else
3914
				curpeer->conf.enforce_local_as = ENFORCE_AS_OFF;
3915
		}
3916
break;
3917
case 113:
3918
#line 1201 "parse.y"
3919
{
3920
			if (yyvsp[-1].v.number < 0 || yyvsp[-1].v.number > UINT_MAX) {
3921
				yyerror("bad maximum number of prefixes");
3922
				YYERROR;
3923
			}
3924
			curpeer->conf.max_prefix = yyvsp[-1].v.number;
3925
			curpeer->conf.max_prefix_restart = yyvsp[0].v.number;
3926
		}
3927
break;
3928
case 114:
3929
#line 1209 "parse.y"
3930
{
3931
			if (curpeer->conf.auth.method) {
3932
				yyerror("auth method cannot be redefined");
3933
				free(yyvsp[0].v.string);
3934
				YYERROR;
3935
			}
3936
			if (strlcpy(curpeer->conf.auth.md5key, yyvsp[0].v.string,
3937
			    sizeof(curpeer->conf.auth.md5key)) >=
3938
			    sizeof(curpeer->conf.auth.md5key)) {
3939
				yyerror("tcp md5sig password too long: max %zu",
3940
				    sizeof(curpeer->conf.auth.md5key) - 1);
3941
				free(yyvsp[0].v.string);
3942
				YYERROR;
3943
			}
3944
			curpeer->conf.auth.method = AUTH_MD5SIG;
3945
			curpeer->conf.auth.md5key_len = strlen(yyvsp[0].v.string);
3946
			free(yyvsp[0].v.string);
3947
		}
3948
break;
3949
case 115:
3950
#line 1227 "parse.y"
3951
{
3952
			if (curpeer->conf.auth.method) {
3953
				yyerror("auth method cannot be redefined");
3954
				free(yyvsp[0].v.string);
3955
				YYERROR;
3956
			}
3957
3958
			if (str2key(yyvsp[0].v.string, curpeer->conf.auth.md5key,
3959
			    sizeof(curpeer->conf.auth.md5key)) == -1) {
3960
				free(yyvsp[0].v.string);
3961
				YYERROR;
3962
			}
3963
			curpeer->conf.auth.method = AUTH_MD5SIG;
3964
			curpeer->conf.auth.md5key_len = strlen(yyvsp[0].v.string) / 2;
3965
			free(yyvsp[0].v.string);
3966
		}
3967
break;
3968
case 116:
3969
#line 1243 "parse.y"
3970
{
3971
			if (curpeer->conf.auth.method) {
3972
				yyerror("auth method cannot be redefined");
3973
				YYERROR;
3974
			}
3975
			if (yyvsp[-1].v.number)
3976
				curpeer->conf.auth.method = AUTH_IPSEC_IKE_ESP;
3977
			else
3978
				curpeer->conf.auth.method = AUTH_IPSEC_IKE_AH;
3979
		}
3980
break;
3981
case 117:
3982
#line 1253 "parse.y"
3983
{
3984
			u_int32_t	auth_alg;
3985
			u_int8_t	keylen;
3986
3987
			if (curpeer->conf.auth.method &&
3988
			    (((curpeer->conf.auth.spi_in && yyvsp[-5].v.number == 1) ||
3989
			    (curpeer->conf.auth.spi_out && yyvsp[-5].v.number == 0)) ||
3990
			    (yyvsp[-6].v.number == 1 && curpeer->conf.auth.method !=
3991
			    AUTH_IPSEC_MANUAL_ESP) ||
3992
			    (yyvsp[-6].v.number == 0 && curpeer->conf.auth.method !=
3993
			    AUTH_IPSEC_MANUAL_AH))) {
3994
				yyerror("auth method cannot be redefined");
3995
				free(yyvsp[-2].v.string);
3996
				free(yyvsp[-1].v.string);
3997
				YYERROR;
3998
			}
3999
4000
			if (!strcmp(yyvsp[-2].v.string, "sha1")) {
4001
				auth_alg = SADB_AALG_SHA1HMAC;
4002
				keylen = 20;
4003
			} else if (!strcmp(yyvsp[-2].v.string, "md5")) {
4004
				auth_alg = SADB_AALG_MD5HMAC;
4005
				keylen = 16;
4006
			} else {
4007
				yyerror("unknown auth algorithm \"%s\"", yyvsp[-2].v.string);
4008
				free(yyvsp[-2].v.string);
4009
				free(yyvsp[-1].v.string);
4010
				YYERROR;
4011
			}
4012
			free(yyvsp[-2].v.string);
4013
4014
			if (strlen(yyvsp[-1].v.string) / 2 != keylen) {
4015
				yyerror("auth key len: must be %u bytes, "
4016
				    "is %zu bytes", keylen, strlen(yyvsp[-1].v.string) / 2);
4017
				free(yyvsp[-1].v.string);
4018
				YYERROR;
4019
			}
4020
4021
			if (yyvsp[-6].v.number)
4022
				curpeer->conf.auth.method =
4023
				    AUTH_IPSEC_MANUAL_ESP;
4024
			else {
4025
				if (yyvsp[0].v.encspec.enc_alg) {
4026
					yyerror("\"ipsec ah\" doesn't take "
4027
					    "encryption keys");
4028
					free(yyvsp[-1].v.string);
4029
					YYERROR;
4030
				}
4031
				curpeer->conf.auth.method =
4032
				    AUTH_IPSEC_MANUAL_AH;
4033
			}
4034
4035
			if (yyvsp[-3].v.number <= SPI_RESERVED_MAX || yyvsp[-3].v.number > UINT_MAX) {
4036
				yyerror("bad spi number %lld", yyvsp[-3].v.number);
4037
				free(yyvsp[-1].v.string);
4038
				YYERROR;
4039
			}
4040
4041
			if (yyvsp[-5].v.number == 1) {
4042
				if (str2key(yyvsp[-1].v.string, curpeer->conf.auth.auth_key_in,
4043
				    sizeof(curpeer->conf.auth.auth_key_in)) ==
4044
				    -1) {
4045
					free(yyvsp[-1].v.string);
4046
					YYERROR;
4047
				}
4048
				curpeer->conf.auth.spi_in = yyvsp[-3].v.number;
4049
				curpeer->conf.auth.auth_alg_in = auth_alg;
4050
				curpeer->conf.auth.enc_alg_in = yyvsp[0].v.encspec.enc_alg;
4051
				memcpy(&curpeer->conf.auth.enc_key_in,
4052
				    &yyvsp[0].v.encspec.enc_key,
4053
				    sizeof(curpeer->conf.auth.enc_key_in));
4054
				curpeer->conf.auth.enc_keylen_in =
4055
				    yyvsp[0].v.encspec.enc_key_len;
4056
				curpeer->conf.auth.auth_keylen_in = keylen;
4057
			} else {
4058
				if (str2key(yyvsp[-1].v.string, curpeer->conf.auth.auth_key_out,
4059
				    sizeof(curpeer->conf.auth.auth_key_out)) ==
4060
				    -1) {
4061
					free(yyvsp[-1].v.string);
4062
					YYERROR;
4063
				}
4064
				curpeer->conf.auth.spi_out = yyvsp[-3].v.number;
4065
				curpeer->conf.auth.auth_alg_out = auth_alg;
4066
				curpeer->conf.auth.enc_alg_out = yyvsp[0].v.encspec.enc_alg;
4067
				memcpy(&curpeer->conf.auth.enc_key_out,
4068
				    &yyvsp[0].v.encspec.enc_key,
4069
				    sizeof(curpeer->conf.auth.enc_key_out));
4070
				curpeer->conf.auth.enc_keylen_out =
4071
				    yyvsp[0].v.encspec.enc_key_len;
4072
				curpeer->conf.auth.auth_keylen_out = keylen;
4073
			}
4074
			free(yyvsp[-1].v.string);
4075
		}
4076
break;
4077
case 118:
4078
#line 1346 "parse.y"
4079
{
4080
			curpeer->conf.ttlsec = yyvsp[0].v.number;
4081
		}
4082
break;
4083
case 119:
4084
#line 1349 "parse.y"
4085
{
4086
			struct filter_rule	*r;
4087
4088
			r = get_rule(yyvsp[0].v.filter_set->type);
4089
			if (merge_filterset(&r->set, yyvsp[0].v.filter_set) == -1)
4090
				YYERROR;
4091
		}
4092
break;
4093
case 120:
4094
#line 1356 "parse.y"
4095
{
4096
			struct filter_rule	*r;
4097
			struct filter_set	*s;
4098
4099
			while ((s = TAILQ_FIRST(yyvsp[-2].v.filter_set_head)) != NULL) {
4100
				TAILQ_REMOVE(yyvsp[-2].v.filter_set_head, s, entry);
4101
				r = get_rule(s->type);
4102
				if (merge_filterset(&r->set, s) == -1)
4103
					YYERROR;
4104
			}
4105
			free(yyvsp[-2].v.filter_set_head);
4106
		}
4107
break;
4108
case 122:
4109
#line 1369 "parse.y"
4110
{
4111
			if ((conf->flags & BGPD_FLAG_REFLECTOR) &&
4112
			    conf->clusterid != 0) {
4113
				yyerror("only one route reflector "
4114
				    "cluster allowed");
4115
				YYERROR;
4116
			}
4117
			conf->flags |= BGPD_FLAG_REFLECTOR;
4118
			curpeer->conf.reflector_client = 1;
4119
		}
4120
break;
4121
case 123:
4122
#line 1379 "parse.y"
4123
{
4124
			if (yyvsp[0].v.addr.aid != AID_INET) {
4125
				yyerror("route reflector cluster-id must be "
4126
				    "an IPv4 address");
4127
				YYERROR;
4128
			}
4129
			if ((conf->flags & BGPD_FLAG_REFLECTOR) &&
4130
			    conf->clusterid != yyvsp[0].v.addr.v4.s_addr) {
4131
				yyerror("only one route reflector "
4132
				    "cluster allowed");
4133
				YYERROR;
4134
			}
4135
			conf->flags |= BGPD_FLAG_REFLECTOR;
4136
			curpeer->conf.reflector_client = 1;
4137
			conf->clusterid = yyvsp[0].v.addr.v4.s_addr;
4138
		}
4139
break;
4140
case 124:
4141
#line 1395 "parse.y"
4142
{
4143
			if (strlcpy(curpeer->conf.if_depend, yyvsp[0].v.string,
4144
			    sizeof(curpeer->conf.if_depend)) >=
4145
			    sizeof(curpeer->conf.if_depend)) {
4146
				yyerror("interface name \"%s\" too long: "
4147
				    "max %zu", yyvsp[0].v.string,
4148
				    sizeof(curpeer->conf.if_depend) - 1);
4149
				free(yyvsp[0].v.string);
4150
				YYERROR;
4151
			}
4152
			free(yyvsp[0].v.string);
4153
		}
4154
break;
4155
case 125:
4156
#line 1407 "parse.y"
4157
{
4158
			if (strlcpy(curpeer->conf.demote_group, yyvsp[0].v.string,
4159
			    sizeof(curpeer->conf.demote_group)) >=
4160
			    sizeof(curpeer->conf.demote_group)) {
4161
				yyerror("demote group name \"%s\" too long: "
4162
				    "max %zu", yyvsp[0].v.string,
4163
				    sizeof(curpeer->conf.demote_group) - 1);
4164
				free(yyvsp[0].v.string);
4165
				YYERROR;
4166
			}
4167
			free(yyvsp[0].v.string);
4168
			if (carp_demote_init(curpeer->conf.demote_group,
4169
			    cmd_opts & BGPD_OPT_FORCE_DEMOTE) == -1) {
4170
				yyerror("error initializing group \"%s\"",
4171
				    curpeer->conf.demote_group);
4172
				YYERROR;
4173
			}
4174
		}
4175
break;
4176
case 126:
4177
#line 1425 "parse.y"
4178
{
4179
			if (yyvsp[0].v.number == 1)
4180
				curpeer->conf.flags |= PEERFLAG_TRANS_AS;
4181
			else
4182
				curpeer->conf.flags &= ~PEERFLAG_TRANS_AS;
4183
		}
4184
break;
4185
case 127:
4186
#line 1431 "parse.y"
4187
{
4188
			if (!strcmp(yyvsp[0].v.string, "updates"))
4189
				curpeer->conf.flags |= PEERFLAG_LOG_UPDATES;
4190
			else if (!strcmp(yyvsp[0].v.string, "no"))
4191
				curpeer->conf.flags &= ~PEERFLAG_LOG_UPDATES;
4192
			else {
4193
				free(yyvsp[0].v.string);
4194
				YYERROR;
4195
			}
4196
			free(yyvsp[0].v.string);
4197
		}
4198
break;
4199
case 128:
4200
#line 1444 "parse.y"
4201
{ yyval.v.number = 0; }
4202
break;
4203
case 129:
4204
#line 1445 "parse.y"
4205
{
4206
			if (yyvsp[0].v.number < 1 || yyvsp[0].v.number > USHRT_MAX) {
4207
				yyerror("restart out of range. 1 to %u minutes",
4208
				    USHRT_MAX);
4209
				YYERROR;
4210
			}
4211
			yyval.v.number = yyvsp[0].v.number;
4212
		}
4213
break;
4214
case 130:
4215
#line 1455 "parse.y"
4216
{ yyval.v.number = AFI_IPv4; }
4217
break;
4218
case 131:
4219
#line 1456 "parse.y"
4220
{ yyval.v.number = AFI_IPv6; }
4221
break;
4222
case 132:
4223
#line 1459 "parse.y"
4224
{ yyval.v.number = 1; }
4225
break;
4226
case 133:
4227
#line 1460 "parse.y"
4228
{ yyval.v.number = 0; }
4229
break;
4230
case 134:
4231
#line 1463 "parse.y"
4232
{ yyval.v.number = 1; }
4233
break;
4234
case 135:
4235
#line 1464 "parse.y"
4236
{ yyval.v.number = 0; }
4237
break;
4238
case 136:
4239
#line 1467 "parse.y"
4240
{
4241
			bzero(&yyval.v.encspec, sizeof(yyval.v.encspec));
4242
		}
4243
break;
4244
case 137:
4245
#line 1470 "parse.y"
4246
{
4247
			bzero(&yyval.v.encspec, sizeof(yyval.v.encspec));
4248
			if (!strcmp(yyvsp[-1].v.string, "3des") || !strcmp(yyvsp[-1].v.string, "3des-cbc")) {
4249
				yyval.v.encspec.enc_alg = SADB_EALG_3DESCBC;
4250
				yyval.v.encspec.enc_key_len = 21; /* XXX verify */
4251
			} else if (!strcmp(yyvsp[-1].v.string, "aes") ||
4252
			    !strcmp(yyvsp[-1].v.string, "aes-128-cbc")) {
4253
				yyval.v.encspec.enc_alg = SADB_X_EALG_AES;
4254
				yyval.v.encspec.enc_key_len = 16;
4255
			} else {
4256
				yyerror("unknown enc algorithm \"%s\"", yyvsp[-1].v.string);
4257
				free(yyvsp[-1].v.string);
4258
				free(yyvsp[0].v.string);
4259
				YYERROR;
4260
			}
4261
			free(yyvsp[-1].v.string);
4262
4263
			if (strlen(yyvsp[0].v.string) / 2 != yyval.v.encspec.enc_key_len) {
4264
				yyerror("enc key length wrong: should be %u "
4265
				    "bytes, is %zu bytes",
4266
				    yyval.v.encspec.enc_key_len * 2, strlen(yyvsp[0].v.string));
4267
				free(yyvsp[0].v.string);
4268
				YYERROR;
4269
			}
4270
4271
			if (str2key(yyvsp[0].v.string, yyval.v.encspec.enc_key, sizeof(yyval.v.encspec.enc_key)) == -1) {
4272
				free(yyvsp[0].v.string);
4273
				YYERROR;
4274
			}
4275
			free(yyvsp[0].v.string);
4276
		}
4277
break;
4278
case 138:
4279
#line 1504 "parse.y"
4280
{
4281
			struct filter_rule	 r;
4282
			struct filter_rib_l	 *rb, *rbnext;
4283
4284
			bzero(&r, sizeof(r));
4285
			r.action = yyvsp[-6].v.u8;
4286
			r.quick = yyvsp[-5].v.u8;
4287
			r.dir = yyvsp[-3].v.u8;
4288
			if (yyvsp[-4].v.filter_rib) {
4289
				if (r.dir != DIR_IN) {
4290
					yyerror("rib only allowed on \"from\" "
4291
					    "rules.");
4292
4293
					for (rb = yyvsp[-4].v.filter_rib; rb != NULL; rb = rbnext) {
4294
						rbnext = rb->next;
4295
						free(rb);
4296
					}
4297
					YYERROR;
4298
				}
4299
			}
4300
			if (expand_rule(&r, yyvsp[-4].v.filter_rib, yyvsp[-2].v.filter_peers, &yyvsp[-1].v.filter_match, yyvsp[0].v.filter_set_head) == -1)
4301
				YYERROR;
4302
		}
4303
break;
4304
case 139:
4305
#line 1529 "parse.y"
4306
{ yyval.v.u8 = ACTION_ALLOW; }
4307
break;
4308
case 140:
4309
#line 1530 "parse.y"
4310
{ yyval.v.u8 = ACTION_DENY; }
4311
break;
4312
case 141:
4313
#line 1531 "parse.y"
4314
{ yyval.v.u8 = ACTION_NONE; }
4315
break;
4316
case 142:
4317
#line 1534 "parse.y"
4318
{ yyval.v.u8 = 0; }
4319
break;
4320
case 143:
4321
#line 1535 "parse.y"
4322
{ yyval.v.u8 = 1; }
4323
break;
4324
case 144:
4325
#line 1538 "parse.y"
4326
{ yyval.v.u8 = DIR_IN; }
4327
break;
4328
case 145:
4329
#line 1539 "parse.y"
4330
{ yyval.v.u8 = DIR_OUT; }
4331
break;
4332
case 146:
4333
#line 1542 "parse.y"
4334
{ yyval.v.filter_rib = NULL; }
4335
break;
4336
case 147:
4337
#line 1543 "parse.y"
4338
{ yyval.v.filter_rib = yyvsp[0].v.filter_rib; }
4339
break;
4340
case 148:
4341
#line 1544 "parse.y"
4342
{ yyval.v.filter_rib = yyvsp[-1].v.filter_rib; }
4343
break;
4344
case 149:
4345
#line 1546 "parse.y"
4346
{ yyval.v.filter_rib = yyvsp[0].v.filter_rib; }
4347
break;
4348
case 150:
4349
#line 1547 "parse.y"
4350
{
4351
			yyvsp[0].v.filter_rib->next = yyvsp[-2].v.filter_rib;
4352
			yyval.v.filter_rib = yyvsp[0].v.filter_rib;
4353
		}
4354
break;
4355
case 151:
4356
#line 1553 "parse.y"
4357
{
4358
			if (!find_rib(yyvsp[0].v.string)) {
4359
				yyerror("rib \"%s\" does not exist.", yyvsp[0].v.string);
4360
				free(yyvsp[0].v.string);
4361
				YYERROR;
4362
			}
4363
			if ((yyval.v.filter_rib = calloc(1, sizeof(struct filter_rib_l))) ==
4364
			    NULL)
4365
				fatal(NULL);
4366
			yyval.v.filter_rib->next = NULL;
4367
			if (strlcpy(yyval.v.filter_rib->name, yyvsp[0].v.string, sizeof(yyval.v.filter_rib->name)) >=
4368
			    sizeof(yyval.v.filter_rib->name)) {
4369
				yyerror("rib name \"%s\" too long: "
4370
				    "max %zu", yyvsp[0].v.string, sizeof(yyval.v.filter_rib->name) - 1);
4371
				free(yyvsp[0].v.string);
4372
				free(yyval.v.filter_rib);
4373
				YYERROR;
4374
			}
4375
			free(yyvsp[0].v.string);
4376
		}
4377
break;
4378
case 153:
4379
#line 1576 "parse.y"
4380
{ yyval.v.filter_peers = yyvsp[-1].v.filter_peers; }
4381
break;
4382
case 154:
4383
#line 1579 "parse.y"
4384
{ yyval.v.filter_peers = yyvsp[0].v.filter_peers; }
4385
break;
4386
case 155:
4387
#line 1580 "parse.y"
4388
{
4389
			yyvsp[0].v.filter_peers->next = yyvsp[-2].v.filter_peers;
4390
			yyval.v.filter_peers = yyvsp[0].v.filter_peers;
4391
		}
4392
break;
4393
case 156:
4394
#line 1586 "parse.y"
4395
{
4396
			if ((yyval.v.filter_peers = calloc(1, sizeof(struct filter_peers_l))) ==
4397
			    NULL)
4398
				fatal(NULL);
4399
			yyval.v.filter_peers->p.peerid = yyval.v.filter_peers->p.groupid = 0;
4400
			yyval.v.filter_peers->next = NULL;
4401
		}
4402
break;
4403
case 157:
4404
#line 1593 "parse.y"
4405
{
4406
			struct peer *p;
4407
4408
			if ((yyval.v.filter_peers = calloc(1, sizeof(struct filter_peers_l))) ==
4409
			    NULL)
4410
				fatal(NULL);
4411
			yyval.v.filter_peers->p.remote_as = yyval.v.filter_peers->p.groupid = yyval.v.filter_peers->p.peerid = 0;
4412
			yyval.v.filter_peers->next = NULL;
4413
			for (p = peer_l; p != NULL; p = p->next)
4414
				if (!memcmp(&p->conf.remote_addr,
4415
				    &yyvsp[0].v.addr, sizeof(p->conf.remote_addr))) {
4416
					yyval.v.filter_peers->p.peerid = p->conf.id;
4417
					break;
4418
				}
4419
			if (yyval.v.filter_peers->p.peerid == 0) {
4420
				yyerror("no such peer: %s", log_addr(&yyvsp[0].v.addr));
4421
				free(yyval.v.filter_peers);
4422
				YYERROR;
4423
			}
4424
		}
4425
break;
4426
case 158:
4427
#line 1613 "parse.y"
4428
{
4429
			if ((yyval.v.filter_peers = calloc(1, sizeof(struct filter_peers_l))) ==
4430
			    NULL)
4431
				fatal(NULL);
4432
			yyval.v.filter_peers->p.groupid = yyval.v.filter_peers->p.peerid = 0;
4433
			yyval.v.filter_peers->p.remote_as = yyvsp[0].v.number;
4434
		}
4435
break;
4436
case 159:
4437
#line 1620 "parse.y"
4438
{
4439
			struct peer *p;
4440
4441
			if ((yyval.v.filter_peers = calloc(1, sizeof(struct filter_peers_l))) ==
4442
			    NULL)
4443
				fatal(NULL);
4444
			yyval.v.filter_peers->p.remote_as = yyval.v.filter_peers->p.peerid = 0;
4445
			yyval.v.filter_peers->next = NULL;
4446
			for (p = peer_l; p != NULL; p = p->next)
4447
				if (!strcmp(p->conf.group, yyvsp[0].v.string)) {
4448
					yyval.v.filter_peers->p.groupid = p->conf.groupid;
4449
					break;
4450
				}
4451
			if (yyval.v.filter_peers->p.groupid == 0) {
4452
				yyerror("no such group: \"%s\"", yyvsp[0].v.string);
4453
				free(yyvsp[0].v.string);
4454
				free(yyval.v.filter_peers);
4455
				YYERROR;
4456
			}
4457
			free(yyvsp[0].v.string);
4458
		}
4459
break;
4460
case 160:
4461
#line 1641 "parse.y"
4462
{
4463
			if ((yyval.v.filter_peers = calloc(1, sizeof(struct filter_peers_l))) ==
4464
			    NULL)
4465
				fatal(NULL);
4466
			yyval.v.filter_peers->p.ebgp = 1;
4467
		}
4468
break;
4469
case 161:
4470
#line 1647 "parse.y"
4471
{
4472
			if ((yyval.v.filter_peers = calloc(1, sizeof(struct filter_peers_l))) ==
4473
			    NULL)
4474
				fatal(NULL);
4475
			yyval.v.filter_peers->p.ibgp = 1;
4476
		}
4477
break;
4478
case 162:
4479
#line 1655 "parse.y"
4480
{
4481
			if (yyvsp[0].v.prefixlen.op == OP_NONE)
4482
				yyvsp[0].v.prefixlen.op = OP_GE;
4483
			if ((yyval.v.filter_prefix = calloc(1, sizeof(struct filter_prefix_l))) ==
4484
			    NULL)
4485
				fatal(NULL);
4486
			yyval.v.filter_prefix->p.addr.aid = AID_INET;
4487
			if (merge_prefixspec(yyval.v.filter_prefix, &yyvsp[0].v.prefixlen) == -1) {
4488
				free(yyval.v.filter_prefix);
4489
				YYERROR;
4490
			}
4491
		}
4492
break;
4493
case 163:
4494
#line 1667 "parse.y"
4495
{
4496
			if (yyvsp[0].v.prefixlen.op == OP_NONE)
4497
				yyvsp[0].v.prefixlen.op = OP_GE;
4498
			if ((yyval.v.filter_prefix = calloc(1, sizeof(struct filter_prefix_l))) ==
4499
			    NULL)
4500
				fatal(NULL);
4501
			yyval.v.filter_prefix->p.addr.aid = AID_INET6;
4502
			if (merge_prefixspec(yyval.v.filter_prefix, &yyvsp[0].v.prefixlen) == -1) {
4503
				free(yyval.v.filter_prefix);
4504
				YYERROR;
4505
			}
4506
		}
4507
break;
4508
case 164:
4509
#line 1679 "parse.y"
4510
{ yyval.v.filter_prefix = yyvsp[0].v.filter_prefix; }
4511
break;
4512
case 165:
4513
#line 1680 "parse.y"
4514
{ yyval.v.filter_prefix = yyvsp[-1].v.filter_prefix; }
4515
break;
4516
case 167:
4517
#line 1684 "parse.y"
4518
{ yyval.v.filter_prefix = yyvsp[-1].v.filter_prefix; }
4519
break;
4520
case 168:
4521
#line 1686 "parse.y"
4522
{
4523
			struct filter_prefix_l  *p;
4524
4525
			/* merge, both can be lists */
4526
			for (p = yyvsp[-2].v.filter_prefix; p != NULL && p->next != NULL; p = p->next)
4527
				;       /* nothing */
4528
			if (p != NULL)
4529
				p->next = yyvsp[0].v.filter_prefix;
4530
			yyval.v.filter_prefix = yyvsp[-2].v.filter_prefix;
4531
		}
4532
break;
4533
case 169:
4534
#line 1697 "parse.y"
4535
{ yyval.v.filter_prefix = yyvsp[0].v.filter_prefix; }
4536
break;
4537
case 170:
4538
#line 1698 "parse.y"
4539
{
4540
			yyvsp[0].v.filter_prefix->next = yyvsp[-2].v.filter_prefix;
4541
			yyval.v.filter_prefix = yyvsp[0].v.filter_prefix;
4542
		}
4543
break;
4544
case 171:
4545
#line 1704 "parse.y"
4546
{
4547
			if ((yyval.v.filter_prefix = calloc(1, sizeof(struct filter_prefix_l))) ==
4548
			    NULL)
4549
				fatal(NULL);
4550
			memcpy(&yyval.v.filter_prefix->p.addr, &yyvsp[-1].v.prefix.prefix,
4551
			    sizeof(yyval.v.filter_prefix->p.addr));
4552
			yyval.v.filter_prefix->p.len = yyvsp[-1].v.prefix.len;
4553
4554
			if (merge_prefixspec(yyval.v.filter_prefix, &yyvsp[0].v.prefixlen) == -1) {
4555
				free(yyval.v.filter_prefix);
4556
				YYERROR;
4557
			}
4558
		}
4559
break;
4560
case 173:
4561
#line 1720 "parse.y"
4562
{ yyval.v.filter_as = yyvsp[-1].v.filter_as; }
4563
break;
4564
case 175:
4565
#line 1724 "parse.y"
4566
{
4567
			struct filter_as_l	*a;
4568
4569
			/* merge, both can be lists */
4570
			for (a = yyvsp[-2].v.filter_as; a != NULL && a->next != NULL; a = a->next)
4571
				;	/* nothing */
4572
			if (a != NULL)
4573
				a->next = yyvsp[0].v.filter_as;
4574
			yyval.v.filter_as = yyvsp[-2].v.filter_as;
4575
		}
4576
break;
4577
case 176:
4578
#line 1736 "parse.y"
4579
{
4580
			yyval.v.filter_as = yyvsp[0].v.filter_as;
4581
			yyval.v.filter_as->a.type = yyvsp[-1].v.u8;
4582
		}
4583
break;
4584
case 177:
4585
#line 1740 "parse.y"
4586
{
4587
			struct filter_as_l	*a;
4588
4589
			yyval.v.filter_as = yyvsp[-1].v.filter_as;
4590
			for (a = yyval.v.filter_as; a != NULL; a = a->next)
4591
				a->a.type = yyvsp[-3].v.u8;
4592
		}
4593
break;
4594
case 179:
4595
#line 1750 "parse.y"
4596
{ yyval.v.filter_as = yyvsp[-1].v.filter_as; }
4597
break;
4598
case 180:
4599
#line 1752 "parse.y"
4600
{
4601
			struct filter_as_l	*a;
4602
4603
			/* merge, both can be lists */
4604
			for (a = yyvsp[-2].v.filter_as; a != NULL && a->next != NULL; a = a->next)
4605
				;	/* nothing */
4606
			if (a != NULL)
4607
				a->next = yyvsp[0].v.filter_as;
4608
			yyval.v.filter_as = yyvsp[-2].v.filter_as;
4609
		}
4610
break;
4611
case 182:
4612
#line 1765 "parse.y"
4613
{
4614
			yyvsp[0].v.filter_as->next = yyvsp[-2].v.filter_as;
4615
			yyval.v.filter_as = yyvsp[0].v.filter_as;
4616
		}
4617
break;
4618
case 183:
4619
#line 1771 "parse.y"
4620
{
4621
			if ((yyval.v.filter_as = calloc(1, sizeof(struct filter_as_l))) ==
4622
			    NULL)
4623
				fatal(NULL);
4624
			yyval.v.filter_as->a.as = yyvsp[0].v.number;
4625
			yyval.v.filter_as->a.op = OP_EQ;
4626
		}
4627
break;
4628
case 184:
4629
#line 1778 "parse.y"
4630
{
4631
			if ((yyval.v.filter_as = calloc(1, sizeof(struct filter_as_l))) ==
4632
			    NULL)
4633
				fatal(NULL);
4634
			yyval.v.filter_as->a.flags = AS_FLAG_NEIGHBORAS;
4635
		}
4636
break;
4637
case 185:
4638
#line 1784 "parse.y"
4639
{
4640
			if ((yyval.v.filter_as = calloc(1, sizeof(struct filter_as_l))) ==
4641
			    NULL)
4642
				fatal(NULL);
4643
			yyval.v.filter_as->a.op = yyvsp[-1].v.u8;
4644
			yyval.v.filter_as->a.as = yyvsp[0].v.number;
4645
		}
4646
break;
4647
case 186:
4648
#line 1791 "parse.y"
4649
{
4650
			if ((yyval.v.filter_as = calloc(1, sizeof(struct filter_as_l))) ==
4651
			    NULL)
4652
				fatal(NULL);
4653
			if (yyvsp[-2].v.number >= yyvsp[0].v.number) {
4654
				yyerror("start AS is bigger than end");
4655
				YYERROR;
4656
			}
4657
			yyval.v.filter_as->a.op = yyvsp[-1].v.u8;
4658
			yyval.v.filter_as->a.as_min = yyvsp[-2].v.number;
4659
			yyval.v.filter_as->a.as_max = yyvsp[0].v.number;
4660
		}
4661
break;
4662
case 187:
4663
#line 1805 "parse.y"
4664
{
4665
			bzero(&yyval.v.filter_match, sizeof(yyval.v.filter_match));
4666
			yyval.v.filter_match.m.community.as = COMMUNITY_UNSET;
4667
			yyval.v.filter_match.m.large_community.as = COMMUNITY_UNSET;
4668
		}
4669
break;
4670
case 188:
4671
#line 1810 "parse.y"
4672
{
4673
			bzero(&fmopts, sizeof(fmopts));
4674
			fmopts.m.community.as = COMMUNITY_UNSET;
4675
			fmopts.m.large_community.as = COMMUNITY_UNSET;
4676
		}
4677
break;
4678
case 189:
4679
#line 1815 "parse.y"
4680
{
4681
			memcpy(&yyval.v.filter_match, &fmopts, sizeof(yyval.v.filter_match));
4682
		}
4683
break;
4684
case 192:
4685
#line 1824 "parse.y"
4686
{
4687
			if (fmopts.prefix_l != NULL) {
4688
				yyerror("\"prefix\" already specified");
4689
				YYERROR;
4690
			}
4691
			fmopts.prefix_l = yyvsp[0].v.filter_prefix;
4692
		}
4693
break;
4694
case 193:
4695
#line 1831 "parse.y"
4696
{
4697
			if (fmopts.as_l != NULL) {
4698
				yyerror("AS filters already specified");
4699
				YYERROR;
4700
			}
4701
			fmopts.as_l = yyvsp[0].v.filter_as;
4702
		}
4703
break;
4704
case 194:
4705
#line 1838 "parse.y"
4706
{
4707
			if (fmopts.m.aslen.type != ASLEN_NONE) {
4708
				yyerror("AS length filters already specified");
4709
				YYERROR;
4710
			}
4711
			if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > UINT_MAX) {
4712
				yyerror("bad max-as-len %lld", yyvsp[0].v.number);
4713
				YYERROR;
4714
			}
4715
			fmopts.m.aslen.type = ASLEN_MAX;
4716
			fmopts.m.aslen.aslen = yyvsp[0].v.number;
4717
		}
4718
break;
4719
case 195:
4720
#line 1850 "parse.y"
4721
{
4722
			if (fmopts.m.aslen.type != ASLEN_NONE) {
4723
				yyerror("AS length filters already specified");
4724
				YYERROR;
4725
			}
4726
			if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > UINT_MAX) {
4727
				yyerror("bad max-as-seq %lld", yyvsp[0].v.number);
4728
				YYERROR;
4729
			}
4730
			fmopts.m.aslen.type = ASLEN_SEQ;
4731
			fmopts.m.aslen.aslen = yyvsp[0].v.number;
4732
		}
4733
break;
4734
case 196:
4735
#line 1862 "parse.y"
4736
{
4737
			if (fmopts.m.community.as != COMMUNITY_UNSET) {
4738
				yyerror("\"community\" already specified");
4739
				free(yyvsp[0].v.string);
4740
				YYERROR;
4741
			}
4742
			if (parsecommunity(&fmopts.m.community, yyvsp[0].v.string) == -1) {
4743
				free(yyvsp[0].v.string);
4744
				YYERROR;
4745
			}
4746
			free(yyvsp[0].v.string);
4747
		}
4748
break;
4749
case 197:
4750
#line 1874 "parse.y"
4751
{
4752
			if (fmopts.m.large_community.as != COMMUNITY_UNSET) {
4753
				yyerror("\"large-community\" already specified");
4754
				free(yyvsp[0].v.string);
4755
				YYERROR;
4756
			}
4757
			if (parselargecommunity(&fmopts.m.large_community, yyvsp[0].v.string) == -1) {
4758
				free(yyvsp[0].v.string);
4759
				YYERROR;
4760
			}
4761
			free(yyvsp[0].v.string);
4762
		}
4763
break;
4764
case 198:
4765
#line 1886 "parse.y"
4766
{
4767
			if (fmopts.m.ext_community.flags &
4768
			    EXT_COMMUNITY_FLAG_VALID) {
4769
				yyerror("\"ext-community\" already specified");
4770
				free(yyvsp[-1].v.string);
4771
				free(yyvsp[0].v.string);
4772
				YYERROR;
4773
			}
4774
4775
			if (parseextcommunity(&fmopts.m.ext_community,
4776
			    yyvsp[-1].v.string, yyvsp[0].v.string) == -1) {
4777
				free(yyvsp[-1].v.string);
4778
				free(yyvsp[0].v.string);
4779
				YYERROR;
4780
			}
4781
			free(yyvsp[-1].v.string);
4782
			free(yyvsp[0].v.string);
4783
		}
4784
break;
4785
case 199:
4786
#line 1904 "parse.y"
4787
{
4788
			if (fmopts.m.nexthop.flags) {
4789
				yyerror("nexthop already specified");
4790
				YYERROR;
4791
			}
4792
			fmopts.m.nexthop.addr = yyvsp[0].v.addr;
4793
			fmopts.m.nexthop.flags = FILTER_NEXTHOP_ADDR;
4794
		}
4795
break;
4796
case 200:
4797
#line 1912 "parse.y"
4798
{
4799
			if (fmopts.m.nexthop.flags) {
4800
				yyerror("nexthop already specified");
4801
				YYERROR;
4802
			}
4803
			fmopts.m.nexthop.flags = FILTER_NEXTHOP_NEIGHBOR;
4804
		}
4805
break;
4806
case 201:
4807
#line 1921 "parse.y"
4808
{ bzero(&yyval.v.prefixlen, sizeof(yyval.v.prefixlen)); }
4809
break;
4810
case 202:
4811
#line 1922 "parse.y"
4812
{
4813
			bzero(&yyval.v.prefixlen, sizeof(yyval.v.prefixlen));
4814
			yyval.v.prefixlen.op = OP_GE;
4815
			yyval.v.prefixlen.len_min = -1;
4816
		}
4817
break;
4818
case 203:
4819
#line 1927 "parse.y"
4820
{
4821
			bzero(&yyval.v.prefixlen, sizeof(yyval.v.prefixlen));
4822
			if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > 128) {
4823
				yyerror("prefixlen must be >= 0 and <= 128");
4824
				YYERROR;
4825
			}
4826
			if (yyvsp[-1].v.u8 == OP_GT && yyvsp[0].v.number == 0) {
4827
				yyerror("prefixlen must be > 0");
4828
				YYERROR;
4829
			}
4830
			yyval.v.prefixlen.op = yyvsp[-1].v.u8;
4831
			yyval.v.prefixlen.len_min = yyvsp[0].v.number;
4832
		}
4833
break;
4834
case 204:
4835
#line 1940 "parse.y"
4836
{
4837
			bzero(&yyval.v.prefixlen, sizeof(yyval.v.prefixlen));
4838
			if (yyvsp[-2].v.number < 0 || yyvsp[-2].v.number > 128 || yyvsp[0].v.number < 0 || yyvsp[0].v.number > 128) {
4839
				yyerror("prefixlen must be < 128");
4840
				YYERROR;
4841
			}
4842
			if (yyvsp[-2].v.number >= yyvsp[0].v.number) {
4843
				yyerror("start prefixlen is bigger than end");
4844
				YYERROR;
4845
			}
4846
			yyval.v.prefixlen.op = yyvsp[-1].v.u8;
4847
			yyval.v.prefixlen.len_min = yyvsp[-2].v.number;
4848
			yyval.v.prefixlen.len_max = yyvsp[0].v.number;
4849
		}
4850
break;
4851
case 205:
4852
#line 1956 "parse.y"
4853
{ yyval.v.u8 = AS_ALL; }
4854
break;
4855
case 206:
4856
#line 1957 "parse.y"
4857
{ yyval.v.u8 = AS_SOURCE; }
4858
break;
4859
case 207:
4860
#line 1958 "parse.y"
4861
{ yyval.v.u8 = AS_TRANSIT; }
4862
break;
4863
case 208:
4864
#line 1959 "parse.y"
4865
{ yyval.v.u8 = AS_PEER; }
4866
break;
4867
case 209:
4868
#line 1962 "parse.y"
4869
{ yyval.v.filter_set_head = NULL; }
4870
break;
4871
case 210:
4872
#line 1963 "parse.y"
4873
{
4874
			if ((yyval.v.filter_set_head = calloc(1, sizeof(struct filter_set_head))) ==
4875
			    NULL)
4876
				fatal(NULL);
4877
			TAILQ_INIT(yyval.v.filter_set_head);
4878
			TAILQ_INSERT_TAIL(yyval.v.filter_set_head, yyvsp[0].v.filter_set, entry);
4879
		}
4880
break;
4881
case 211:
4882
#line 1970 "parse.y"
4883
{ yyval.v.filter_set_head = yyvsp[-2].v.filter_set_head; }
4884
break;
4885
case 212:
4886
#line 1973 "parse.y"
4887
{
4888
			yyval.v.filter_set_head = yyvsp[-2].v.filter_set_head;
4889
			if (merge_filterset(yyval.v.filter_set_head, yyvsp[0].v.filter_set) == 1)
4890
				YYERROR;
4891
		}
4892
break;
4893
case 213:
4894
#line 1978 "parse.y"
4895
{
4896
			if ((yyval.v.filter_set_head = calloc(1, sizeof(struct filter_set_head))) ==
4897
			    NULL)
4898
				fatal(NULL);
4899
			TAILQ_INIT(yyval.v.filter_set_head);
4900
			TAILQ_INSERT_TAIL(yyval.v.filter_set_head, yyvsp[0].v.filter_set, entry);
4901
		}
4902
break;
4903
case 214:
4904
#line 1987 "parse.y"
4905
{ yyval.v.u8 = 0; }
4906
break;
4907
case 215:
4908
#line 1988 "parse.y"
4909
{ yyval.v.u8 = 1; }
4910
break;
4911
case 216:
4912
#line 1991 "parse.y"
4913
{
4914
			if (yyvsp[0].v.number < -INT_MAX || yyvsp[0].v.number > UINT_MAX) {
4915
				yyerror("bad localpref %lld", yyvsp[0].v.number);
4916
				YYERROR;
4917
			}
4918
			if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL)
4919
				fatal(NULL);
4920
			if (yyvsp[0].v.number >= 0) {
4921
				yyval.v.filter_set->type = ACTION_SET_LOCALPREF;
4922
				yyval.v.filter_set->action.metric = yyvsp[0].v.number;
4923
			} else {
4924
				yyval.v.filter_set->type = ACTION_SET_RELATIVE_LOCALPREF;
4925
				yyval.v.filter_set->action.relative = yyvsp[0].v.number;
4926
			}
4927
		}
4928
break;
4929
case 217:
4930
#line 2006 "parse.y"
4931
{
4932
			if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX) {
4933
				yyerror("bad localpref +%lld", yyvsp[0].v.number);
4934
				YYERROR;
4935
			}
4936
			if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL)
4937
				fatal(NULL);
4938
			yyval.v.filter_set->type = ACTION_SET_RELATIVE_LOCALPREF;
4939
			yyval.v.filter_set->action.relative = yyvsp[0].v.number;
4940
		}
4941
break;
4942
case 218:
4943
#line 2016 "parse.y"
4944
{
4945
			if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX) {
4946
				yyerror("bad localpref -%lld", yyvsp[0].v.number);
4947
				YYERROR;
4948
			}
4949
			if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL)
4950
				fatal(NULL);
4951
			yyval.v.filter_set->type = ACTION_SET_RELATIVE_LOCALPREF;
4952
			yyval.v.filter_set->action.relative = -yyvsp[0].v.number;
4953
		}
4954
break;
4955
case 219:
4956
#line 2026 "parse.y"
4957
{
4958
			if (yyvsp[0].v.number < -INT_MAX || yyvsp[0].v.number > UINT_MAX) {
4959
				yyerror("bad metric %lld", yyvsp[0].v.number);
4960
				YYERROR;
4961
			}
4962
			if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL)
4963
				fatal(NULL);
4964
			if (yyvsp[0].v.number >= 0) {
4965
				yyval.v.filter_set->type = ACTION_SET_MED;
4966
				yyval.v.filter_set->action.metric = yyvsp[0].v.number;
4967
			} else {
4968
				yyval.v.filter_set->type = ACTION_SET_RELATIVE_MED;
4969
				yyval.v.filter_set->action.relative = yyvsp[0].v.number;
4970
			}
4971
		}
4972
break;
4973
case 220:
4974
#line 2041 "parse.y"
4975
{
4976
			if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX) {
4977
				yyerror("bad metric +%lld", yyvsp[0].v.number);
4978
				YYERROR;
4979
			}
4980
			if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL)
4981
				fatal(NULL);
4982
			yyval.v.filter_set->type = ACTION_SET_RELATIVE_MED;
4983
			yyval.v.filter_set->action.relative = yyvsp[0].v.number;
4984
		}
4985
break;
4986
case 221:
4987
#line 2051 "parse.y"
4988
{
4989
			if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX) {
4990
				yyerror("bad metric -%lld", yyvsp[0].v.number);
4991
				YYERROR;
4992
			}
4993
			if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL)
4994
				fatal(NULL);
4995
			yyval.v.filter_set->type = ACTION_SET_RELATIVE_MED;
4996
			yyval.v.filter_set->action.relative = -yyvsp[0].v.number;
4997
		}
4998
break;
4999
case 222:
5000
#line 2061 "parse.y"
5001
{	/* alias for MED */
5002
			if (yyvsp[0].v.number < -INT_MAX || yyvsp[0].v.number > UINT_MAX) {
5003
				yyerror("bad metric %lld", yyvsp[0].v.number);
5004
				YYERROR;
5005
			}
5006
			if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL)
5007
				fatal(NULL);
5008
			if (yyvsp[0].v.number >= 0) {
5009
				yyval.v.filter_set->type = ACTION_SET_MED;
5010
				yyval.v.filter_set->action.metric = yyvsp[0].v.number;
5011
			} else {
5012
				yyval.v.filter_set->type = ACTION_SET_RELATIVE_MED;
5013
				yyval.v.filter_set->action.relative = yyvsp[0].v.number;
5014
			}
5015
		}
5016
break;
5017
case 223:
5018
#line 2076 "parse.y"
5019
{
5020
			if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX) {
5021
				yyerror("bad metric +%lld", yyvsp[0].v.number);
5022
				YYERROR;
5023
			}
5024
			if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL)
5025
				fatal(NULL);
5026
			yyval.v.filter_set->type = ACTION_SET_RELATIVE_MED;
5027
			yyval.v.filter_set->action.metric = yyvsp[0].v.number;
5028
		}
5029
break;
5030
case 224:
5031
#line 2086 "parse.y"
5032
{
5033
			if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX) {
5034
				yyerror("bad metric -%lld", yyvsp[0].v.number);
5035
				YYERROR;
5036
			}
5037
			if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL)
5038
				fatal(NULL);
5039
			yyval.v.filter_set->type = ACTION_SET_RELATIVE_MED;
5040
			yyval.v.filter_set->action.relative = -yyvsp[0].v.number;
5041
		}
5042
break;
5043
case 225:
5044
#line 2096 "parse.y"
5045
{
5046
			if (yyvsp[0].v.number < -INT_MAX || yyvsp[0].v.number > UINT_MAX) {
5047
				yyerror("bad weight %lld", yyvsp[0].v.number);
5048
				YYERROR;
5049
			}
5050
			if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL)
5051
				fatal(NULL);
5052
			if (yyvsp[0].v.number > 0) {
5053
				yyval.v.filter_set->type = ACTION_SET_WEIGHT;
5054
				yyval.v.filter_set->action.metric = yyvsp[0].v.number;
5055
			} else {
5056
				yyval.v.filter_set->type = ACTION_SET_RELATIVE_WEIGHT;
5057
				yyval.v.filter_set->action.relative = yyvsp[0].v.number;
5058
			}
5059
		}
5060
break;
5061
case 226:
5062
#line 2111 "parse.y"
5063
{
5064
			if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX) {
5065
				yyerror("bad weight +%lld", yyvsp[0].v.number);
5066
				YYERROR;
5067
			}
5068
			if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL)
5069
				fatal(NULL);
5070
			yyval.v.filter_set->type = ACTION_SET_RELATIVE_WEIGHT;
5071
			yyval.v.filter_set->action.relative = yyvsp[0].v.number;
5072
		}
5073
break;
5074
case 227:
5075
#line 2121 "parse.y"
5076
{
5077
			if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > INT_MAX) {
5078
				yyerror("bad weight -%lld", yyvsp[0].v.number);
5079
				YYERROR;
5080
			}
5081
			if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL)
5082
				fatal(NULL);
5083
			yyval.v.filter_set->type = ACTION_SET_RELATIVE_WEIGHT;
5084
			yyval.v.filter_set->action.relative = -yyvsp[0].v.number;
5085
		}
5086
break;
5087
case 228:
5088
#line 2131 "parse.y"
5089
{
5090
			if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL)
5091
				fatal(NULL);
5092
			yyval.v.filter_set->type = ACTION_SET_NEXTHOP;
5093
			memcpy(&yyval.v.filter_set->action.nexthop, &yyvsp[0].v.addr,
5094
			    sizeof(yyval.v.filter_set->action.nexthop));
5095
		}
5096
break;
5097
case 229:
5098
#line 2138 "parse.y"
5099
{
5100
			if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL)
5101
				fatal(NULL);
5102
			yyval.v.filter_set->type = ACTION_SET_NEXTHOP_BLACKHOLE;
5103
		}
5104
break;
5105
case 230:
5106
#line 2143 "parse.y"
5107
{
5108
			if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL)
5109
				fatal(NULL);
5110
			yyval.v.filter_set->type = ACTION_SET_NEXTHOP_REJECT;
5111
		}
5112
break;
5113
case 231:
5114
#line 2148 "parse.y"
5115
{
5116
			if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL)
5117
				fatal(NULL);
5118
			yyval.v.filter_set->type = ACTION_SET_NEXTHOP_NOMODIFY;
5119
		}
5120
break;
5121
case 232:
5122
#line 2153 "parse.y"
5123
{
5124
			if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL)
5125
				fatal(NULL);
5126
			yyval.v.filter_set->type = ACTION_SET_NEXTHOP_SELF;
5127
		}
5128
break;
5129
case 233:
5130
#line 2158 "parse.y"
5131
{
5132
			if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > 128) {
5133
				yyerror("bad number of prepends");
5134
				YYERROR;
5135
			}
5136
			if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL)
5137
				fatal(NULL);
5138
			yyval.v.filter_set->type = ACTION_SET_PREPEND_SELF;
5139
			yyval.v.filter_set->action.prepend = yyvsp[0].v.number;
5140
		}
5141
break;
5142
case 234:
5143
#line 2168 "parse.y"
5144
{
5145
			if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > 128) {
5146
				yyerror("bad number of prepends");
5147
				YYERROR;
5148
			}
5149
			if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL)
5150
				fatal(NULL);
5151
			yyval.v.filter_set->type = ACTION_SET_PREPEND_PEER;
5152
			yyval.v.filter_set->action.prepend = yyvsp[0].v.number;
5153
		}
5154
break;
5155
case 235:
5156
#line 2178 "parse.y"
5157
{
5158
			if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL)
5159
				fatal(NULL);
5160
			yyval.v.filter_set->type = ACTION_PFTABLE;
5161
			if (!(cmd_opts & BGPD_OPT_NOACTION) &&
5162
			    pftable_exists(yyvsp[0].v.string) != 0) {
5163
				yyerror("pftable name does not exist");
5164
				free(yyvsp[0].v.string);
5165
				free(yyval.v.filter_set);
5166
				YYERROR;
5167
			}
5168
			if (strlcpy(yyval.v.filter_set->action.pftable, yyvsp[0].v.string,
5169
			    sizeof(yyval.v.filter_set->action.pftable)) >=
5170
			    sizeof(yyval.v.filter_set->action.pftable)) {
5171
				yyerror("pftable name too long");
5172
				free(yyvsp[0].v.string);
5173
				free(yyval.v.filter_set);
5174
				YYERROR;
5175
			}
5176
			if (pftable_add(yyvsp[0].v.string) != 0) {
5177
				yyerror("Couldn't register table");
5178
				free(yyvsp[0].v.string);
5179
				free(yyval.v.filter_set);
5180
				YYERROR;
5181
			}
5182
			free(yyvsp[0].v.string);
5183
		}
5184
break;
5185
case 236:
5186
#line 2205 "parse.y"
5187
{
5188
			if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL)
5189
				fatal(NULL);
5190
			yyval.v.filter_set->type = ACTION_RTLABEL;
5191
			if (strlcpy(yyval.v.filter_set->action.rtlabel, yyvsp[0].v.string,
5192
			    sizeof(yyval.v.filter_set->action.rtlabel)) >=
5193
			    sizeof(yyval.v.filter_set->action.rtlabel)) {
5194
				yyerror("rtlabel name too long");
5195
				free(yyvsp[0].v.string);
5196
				free(yyval.v.filter_set);
5197
				YYERROR;
5198
			}
5199
			free(yyvsp[0].v.string);
5200
		}
5201
break;
5202
case 237:
5203
#line 2219 "parse.y"
5204
{
5205
			if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL)
5206
				fatal(NULL);
5207
			if (yyvsp[-1].v.u8)
5208
				yyval.v.filter_set->type = ACTION_DEL_COMMUNITY;
5209
			else
5210
				yyval.v.filter_set->type = ACTION_SET_COMMUNITY;
5211
5212
			if (parsecommunity(&yyval.v.filter_set->action.community, yyvsp[0].v.string) == -1) {
5213
				free(yyvsp[0].v.string);
5214
				free(yyval.v.filter_set);
5215
				YYERROR;
5216
			}
5217
			free(yyvsp[0].v.string);
5218
			/* Don't allow setting of any match */
5219
			if (!yyvsp[-1].v.u8 && (yyval.v.filter_set->action.community.as == COMMUNITY_ANY ||
5220
			    yyval.v.filter_set->action.community.type == COMMUNITY_ANY)) {
5221
				yyerror("'*' is not allowed in set community");
5222
				free(yyval.v.filter_set);
5223
				YYERROR;
5224
			}
5225
		}
5226
break;
5227
case 238:
5228
#line 2241 "parse.y"
5229
{
5230
			if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL)
5231
				fatal(NULL);
5232
			if (yyvsp[-1].v.u8)
5233
				yyval.v.filter_set->type = ACTION_DEL_LARGE_COMMUNITY;
5234
			else
5235
				yyval.v.filter_set->type = ACTION_SET_LARGE_COMMUNITY;
5236
5237
			if (parselargecommunity(&yyval.v.filter_set->action.large_community,
5238
			    yyvsp[0].v.string) == -1) {
5239
				free(yyvsp[0].v.string);
5240
				free(yyval.v.filter_set);
5241
				YYERROR;
5242
			}
5243
			free(yyvsp[0].v.string);
5244
			/* Don't allow setting of any match */
5245
			if (!yyvsp[-1].v.u8 &&
5246
			    (yyval.v.filter_set->action.large_community.as == COMMUNITY_ANY ||
5247
			    yyval.v.filter_set->action.large_community.ld1 == COMMUNITY_ANY ||
5248
			    yyval.v.filter_set->action.large_community.ld2 == COMMUNITY_ANY)) {
5249
				yyerror("'*' is not allowed in set community");
5250
				free(yyval.v.filter_set);
5251
				YYERROR;
5252
			}
5253
		}
5254
break;
5255
case 239:
5256
#line 2266 "parse.y"
5257
{
5258
			if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL)
5259
				fatal(NULL);
5260
			if (yyvsp[-2].v.u8)
5261
				yyval.v.filter_set->type = ACTION_DEL_EXT_COMMUNITY;
5262
			else
5263
				yyval.v.filter_set->type = ACTION_SET_EXT_COMMUNITY;
5264
5265
			if (parseextcommunity(&yyval.v.filter_set->action.ext_community,
5266
			    yyvsp[-1].v.string, yyvsp[0].v.string) == -1) {
5267
				free(yyvsp[-1].v.string);
5268
				free(yyvsp[0].v.string);
5269
				free(yyval.v.filter_set);
5270
				YYERROR;
5271
			}
5272
			free(yyvsp[-1].v.string);
5273
			free(yyvsp[0].v.string);
5274
		}
5275
break;
5276
case 240:
5277
#line 2284 "parse.y"
5278
{
5279
			if ((yyval.v.filter_set = calloc(1, sizeof(struct filter_set))) == NULL)
5280
				fatal(NULL);
5281
			yyval.v.filter_set->type = ACTION_SET_ORIGIN;
5282
			yyval.v.filter_set->action.origin = yyvsp[0].v.number;
5283
		}
5284
break;
5285
case 241:
5286
#line 2292 "parse.y"
5287
{
5288
			if (!strcmp(yyvsp[0].v.string, "egp"))
5289
				yyval.v.number = ORIGIN_EGP;
5290
			else if (!strcmp(yyvsp[0].v.string, "igp"))
5291
				yyval.v.number = ORIGIN_IGP;
5292
			else if (!strcmp(yyvsp[0].v.string, "incomplete"))
5293
				yyval.v.number = ORIGIN_INCOMPLETE;
5294
			else {
5295
				yyerror("unknown origin \"%s\"", yyvsp[0].v.string);
5296
				free(yyvsp[0].v.string);
5297
				YYERROR;
5298
			}
5299
			free(yyvsp[0].v.string);
5300
		}
5301
break;
5302
case 244:
5303
#line 2311 "parse.y"
5304
{ yyval.v.u8 = OP_EQ; }
5305
break;
5306
case 245:
5307
#line 2312 "parse.y"
5308
{ yyval.v.u8 = OP_NE; }
5309
break;
5310
case 246:
5311
#line 2313 "parse.y"
5312
{ yyval.v.u8 = OP_LE; }
5313
break;
5314
case 247:
5315
#line 2314 "parse.y"
5316
{ yyval.v.u8 = OP_LT; }
5317
break;
5318
case 248:
5319
#line 2315 "parse.y"
5320
{ yyval.v.u8 = OP_GE; }
5321
break;
5322
case 249:
5323
#line 2316 "parse.y"
5324
{ yyval.v.u8 = OP_GT; }
5325
break;
5326
case 250:
5327
#line 2319 "parse.y"
5328
{ yyval.v.u8 = OP_EQ; }
5329
break;
5330
case 251:
5331
#line 2320 "parse.y"
5332
{ yyval.v.u8 = OP_NE; }
5333
break;
5334
case 252:
5335
#line 2323 "parse.y"
5336
4580
{ yyval.v.u8 = OP_RANGE; }
5337
4580
break;
5338
4580
case 253:
5339
4580
#line 2324 "parse.y"
5340
4580
{ yyval.v.u8 = OP_XRANGE; }
5341
break;
5342
#line 5335 "parse.c"
5343
    }
5344
    yyssp -= yym;
5345
    yystate = *yyssp;
5346
    yyvsp -= yym;
5347
    yym = yylhs[yyn];
5348
480
    if (yystate == 0 && yym == 0)
5349
480
    {
5350
480
#if YYDEBUG
5351
        if (yydebug)
5352
480
            printf("%sdebug: after reduction, shifting from state 0 to\
5353
 state %d\n", YYPREFIX, YYFINAL);
5354
#endif
5355
        yystate = YYFINAL;
5356
        *++yyssp = YYFINAL;
5357
        *++yyvsp = yyval;
5358
        if (yychar < 0)
5359
        {
5360
            if ((yychar = yylex()) < 0) yychar = 0;
5361
#if YYDEBUG
5362
            if (yydebug)
5363
480
            {
5364
480
                yys = 0;
5365
468
                if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
5366
                if (!yys) yys = "illegal-symbol";
5367

9472
                printf("%sdebug: state %d, reading %d (%s)\n",
5368
3492
                        YYPREFIX, YYFINAL, yychar, yys);
5369
1196
            }
5370
#endif
5371
2904
        }
5372
        if (yychar == 0) goto yyaccept;
5373
        goto yyloop;
5374
    }
5375
    if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
5376
            yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
5377

4100
        yystate = yytable[yyn];
5378
    else
5379
        yystate = yydgoto[yym];
5380
#if YYDEBUG
5381
4100
    if (yydebug)
5382
4100
        printf("%sdebug: after reduction, shifting from state %d \
5383
4100
to state %d\n", YYPREFIX, *yyssp, yystate);
5384
#endif
5385
    if (yyssp >= yysslim && yygrowstack())
5386
    {
5387
        goto yyoverflow;
5388
    }
5389
    *++yyssp = yystate;
5390
    *++yyvsp = yyval;
5391
    goto yyloop;
5392
yyoverflow:
5393
    yyerror("yacc stack overflow");
5394
yyabort:
5395
    if (yyss)
5396
12
            free(yyss);
5397
12
    if (yyvs)
5398
12
            free(yyvs);
5399
12
    yyss = yyssp = NULL;
5400
12
    yyvs = yyvsp = NULL;
5401
12
    yystacksize = 0;
5402
12
    return (1);
5403
12
yyaccept:
5404
12
    if (yyss)
5405
            free(yyss);
5406
    if (yyvs)
5407
            free(yyvs);
5408
    yyss = yyssp = NULL;
5409
    yyvs = yyvsp = NULL;
5410
    yystacksize = 0;
5411
    return (0);
5412
}