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