xref: /openbsd/usr.sbin/ldpd/parse.y (revision 4cfece93)
1 /*	$OpenBSD: parse.y,v 1.71 2019/02/13 22:57:08 deraadt Exp $ */
2 
3 /*
4  * Copyright (c) 2013, 2015, 2016 Renato Westphal <renato@openbsd.org>
5  * Copyright (c) 2004, 2005, 2008 Esben Norby <norby@openbsd.org>
6  * Copyright (c) 2004 Ryan McBride <mcbride@openbsd.org>
7  * Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
8  * Copyright (c) 2001 Markus Friedl.  All rights reserved.
9  * Copyright (c) 2001 Daniel Hartmeier.  All rights reserved.
10  * Copyright (c) 2001 Theo de Raadt.  All rights reserved.
11  *
12  * Permission to use, copy, modify, and distribute this software for any
13  * purpose with or without fee is hereby granted, provided that the above
14  * copyright notice and this permission notice appear in all copies.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
17  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
18  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
19  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
21  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
22  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23  */
24 
25 %{
26 #include <sys/stat.h>
27 #include <sys/types.h>
28 #include <sys/socket.h>
29 #include <arpa/inet.h>
30 #include <ctype.h>
31 #include <err.h>
32 #include <unistd.h>
33 #include <ifaddrs.h>
34 #include <net/if_types.h>
35 #include <limits.h>
36 #include <stdio.h>
37 #include <syslog.h>
38 #include <errno.h>
39 #include <netdb.h>
40 
41 #include "ldpd.h"
42 #include "ldpe.h"
43 #include "lde.h"
44 #include "log.h"
45 
46 struct file {
47 	TAILQ_ENTRY(file)	 entry;
48 	FILE			*stream;
49 	char			*name;
50 	size_t			 ungetpos;
51 	size_t			 ungetsize;
52 	u_char			*ungetbuf;
53 	int			 eof_reached;
54 	int			 lineno;
55 	int			 errors;
56 };
57 TAILQ_HEAD(files, file);
58 
59 struct sym {
60 	TAILQ_ENTRY(sym)	 entry;
61 	int			 used;
62 	int			 persist;
63 	char			*nam;
64 	char			*val;
65 };
66 TAILQ_HEAD(symhead, sym);
67 
68 struct config_defaults {
69 	uint16_t	keepalive;
70 	uint16_t	lhello_holdtime;
71 	uint16_t	lhello_interval;
72 	uint16_t	thello_holdtime;
73 	uint16_t	thello_interval;
74 	union ldpd_addr	trans_addr;
75 	int		afflags;
76 	uint8_t		pwflags;
77 };
78 
79 typedef struct {
80 	union {
81 		int64_t		 number;
82 		char		*string;
83 		struct in_addr	 routerid;
84 		struct ldp_auth	*auth;
85 	} v;
86 	int lineno;
87 } YYSTYPE;
88 
89 static int		 yyerror(const char *, ...)
90     __attribute__((__format__ (printf, 1, 2)))
91     __attribute__((__nonnull__ (1)));
92 static int		 kw_cmp(const void *, const void *);
93 static int		 lookup(char *);
94 static int		 igetc(void);
95 static int		 lgetc(int);
96 void			 lungetc(int);
97 static int		 findeol(void);
98 static int		 yylex(void);
99 static int		 check_file_secrecy(int, const char *);
100 static struct file	*pushfile(const char *, int);
101 static int		 popfile(void);
102 static int		 yyparse(void);
103 static int		 symset(const char *, const char *, int);
104 static char		*symget(const char *);
105 static struct iface	*conf_get_if(struct kif *);
106 static struct tnbr	*conf_get_tnbr(union ldpd_addr *);
107 static struct nbr_params *conf_get_nbrp(struct in_addr);
108 static struct l2vpn	*conf_get_l2vpn(char *);
109 static struct l2vpn_if	*conf_get_l2vpn_if(struct l2vpn *, struct kif *);
110 static struct l2vpn_pw	*conf_get_l2vpn_pw(struct l2vpn *, struct kif *);
111 int			 conf_check_rdomain(unsigned int);
112 static void		 clear_config(struct ldpd_conf *xconf);
113 static uint32_t		 get_rtr_id(void);
114 static int		 get_address(const char *, union ldpd_addr *);
115 static int		 get_af_address(const char *, int *, union ldpd_addr *);
116 static int		 str2key(char *, const char *, int);
117 
118 static struct file		*file, *topfile;
119 static struct files		 files = TAILQ_HEAD_INITIALIZER(files);
120 static struct symhead		 symhead = TAILQ_HEAD_INITIALIZER(symhead);
121 static struct ldpd_conf		*conf;
122 static int			 errors;
123 
124 static int			 af;
125 static struct ldpd_af_conf	*af_conf;
126 static struct iface		*iface;
127 static struct iface_af		*ia;
128 static struct tnbr		*tnbr;
129 static struct nbr_params	*nbrp;
130 static struct l2vpn		*l2vpn;
131 static struct l2vpn_pw		*pw;
132 
133 static struct config_defaults	 globaldefs;
134 static struct config_defaults	 afdefs;
135 static struct config_defaults	 ifacedefs;
136 static struct config_defaults	 tnbrdefs;
137 static struct config_defaults	 pwdefs;
138 static struct config_defaults	*defs;
139 
140 %}
141 
142 %token	INTERFACE TNEIGHBOR ROUTERID FIBUPDATE RDOMAIN EXPNULL
143 %token	LHELLOHOLDTIME LHELLOINTERVAL
144 %token	THELLOHOLDTIME THELLOINTERVAL
145 %token	THELLOACCEPT AF IPV4 IPV6 INET INET6 GTSMENABLE GTSMHOPS
146 %token	KEEPALIVE TRANSADDRESS TRANSPREFERENCE DSCISCOINTEROP
147 %token	NEIGHBOR
148 %token	TCP MD5SIG PASSWORD KEY
149 %token	L2VPN TYPE VPLS PWTYPE MTU BRIDGE
150 %token	ETHERNET ETHERNETTAGGED STATUSTLV CONTROLWORD
151 %token	PSEUDOWIRE NEIGHBORID NEIGHBORADDR PWID
152 %token	EXTTAG
153 %token	YES NO
154 %token	INCLUDE
155 %token	ERROR
156 %token	<v.string>	STRING
157 %token	<v.number>	NUMBER
158 %type	<v.number>	yesno ldp_af l2vpn_type pw_type
159 %type	<v.string>	string
160 %type	<v.routerid>	routerid
161 %type	<v.auth>	auth tcpmd5 optnbrprefix
162 
163 %%
164 
165 grammar		: /* empty */
166 		| grammar include '\n'
167 		| grammar '\n'
168 		| grammar conf_main '\n'
169 		| grammar varset '\n'
170 		| grammar af '\n'
171 		| grammar neighbor '\n'
172 		| grammar l2vpn '\n'
173 		| grammar error '\n'		{ file->errors++; }
174 		;
175 
176 include		: INCLUDE STRING		{
177 			struct file	*nfile;
178 
179 			if ((nfile = pushfile($2,
180 			    !(global.cmd_opts & LDPD_OPT_NOACTION))) == NULL) {
181 				yyerror("failed to include file %s", $2);
182 				free($2);
183 				YYERROR;
184 			}
185 			free($2);
186 
187 			file = nfile;
188 			lungetc('\n');
189 		}
190 		;
191 
192 string		: string STRING	{
193 			if (asprintf(&$$, "%s %s", $1, $2) == -1) {
194 				free($1);
195 				free($2);
196 				yyerror("string: asprintf");
197 				YYERROR;
198 			}
199 			free($1);
200 			free($2);
201 		}
202 		| STRING
203 		;
204 
205 routerid	: STRING {
206 			if (!inet_aton($1, &$$)) {
207 				yyerror("%s: error parsing router id", $1);
208 				free($1);
209 				YYERROR;
210 			}
211 			if (bad_addr_v4($$)) {
212 				yyerror("%s: invalid router id", $1);
213 				free($1);
214 				YYERROR;
215 			}
216 			free($1);
217 
218 			break;
219 		}
220 		;
221 
222 yesno		: YES	{ $$ = 1; }
223 		| NO	{ $$ = 0; }
224 		;
225 
226 ldp_af		: IPV4	{ $$ = AF_INET; }
227 		| IPV6	{ $$ = AF_INET6; }
228 		;
229 
230 l2vpn_type	: VPLS	{ $$ = L2VPN_TYPE_VPLS; }
231 		;
232 
233 pw_type		: ETHERNET		{ $$ = PW_TYPE_ETHERNET; }
234 		| ETHERNETTAGGED	{ $$ = PW_TYPE_ETHERNET_TAGGED; }
235 		;
236 
237 varset		: STRING '=' string {
238 			char *s = $1;
239 			if (global.cmd_opts & LDPD_OPT_VERBOSE)
240 				printf("%s = \"%s\"\n", $1, $3);
241 			while (*s++) {
242 				if (isspace((unsigned char)*s)) {
243 					yyerror("macro name cannot contain "
244 					    "whitespace");
245 					free($1);
246 					free($3);
247 					YYERROR;
248 				}
249 			}
250 			if (symset($1, $3, 0) == -1)
251 				fatal("cannot store variable");
252 			free($1);
253 			free($3);
254 		}
255 		;
256 
257 conf_main	: ROUTERID routerid {
258 			conf->rtr_id = $2;
259 		}
260 		| FIBUPDATE yesno {
261 			if ($2 == 0)
262 				conf->flags |= F_LDPD_NO_FIB_UPDATE;
263 			else
264 				conf->flags &= ~F_LDPD_NO_FIB_UPDATE;
265 		}
266 		| RDOMAIN NUMBER {
267 			if ($2 < 0 || $2 > RT_TABLEID_MAX) {
268 				yyerror("invalid rdomain");
269 				YYERROR;
270 			}
271 			conf->rdomain = $2;
272 		}
273 		| TRANSPREFERENCE ldp_af {
274 			conf->trans_pref = $2;
275 
276 			switch (conf->trans_pref) {
277 			case AF_INET:
278 				conf->trans_pref = DUAL_STACK_LDPOV4;
279 				break;
280 			case AF_INET6:
281 				conf->trans_pref = DUAL_STACK_LDPOV6;
282 				break;
283 			default:
284 				yyerror("invalid address-family");
285 				YYERROR;
286 			}
287 		}
288 		| DSCISCOINTEROP yesno {
289 			if ($2 == 1)
290 				conf->flags |= F_LDPD_DS_CISCO_INTEROP;
291 			else
292 				conf->flags &= ~F_LDPD_DS_CISCO_INTEROP;
293 		}
294 		| auth {
295 			LIST_INSERT_HEAD(&conf->auth_list, $1, entry);
296 		}
297 		| af_defaults
298 		| iface_defaults
299 		| tnbr_defaults
300 		;
301 
302 af		: AF ldp_af {
303 			af = $2;
304 			switch (af) {
305 			case AF_INET:
306 				af_conf = &conf->ipv4;
307 				break;
308 			case AF_INET6:
309 				af_conf = &conf->ipv6;
310 				break;
311 			default:
312 				yyerror("invalid address-family");
313 				YYERROR;
314 			}
315 
316 			afdefs = *defs;
317 			defs = &afdefs;
318 		} af_block {
319 			af_conf->keepalive = defs->keepalive;
320 			af_conf->thello_holdtime = defs->thello_holdtime;
321 			af_conf->thello_interval = defs->thello_interval;
322 			af_conf->flags = defs->afflags;
323 			af_conf->flags |= F_LDPD_AF_ENABLED;
324 			af_conf = NULL;
325 			af = AF_UNSPEC;
326 			defs = &globaldefs;
327 		}
328 		;
329 
330 af_block	: '{' optnl afopts_l '}'
331 		| '{' optnl '}'
332 		|
333 		;
334 
335 afopts_l	: afopts_l afoptsl nl
336 		| afoptsl optnl
337 		;
338 
339 afoptsl		:  TRANSADDRESS STRING {
340 			if (get_address($2, &af_conf->trans_addr) == -1) {
341 				yyerror("error parsing transport-address");
342 				free($2);
343 				YYERROR;
344 			}
345 			free($2);
346 			if (bad_addr(af, &af_conf->trans_addr)) {
347 				yyerror("invalid transport-address");
348 				YYERROR;
349 			}
350 			if (af == AF_INET6 &&
351 			   IN6_IS_SCOPE_EMBED(&af_conf->trans_addr.v6)) {
352 				yyerror("ipv6 transport-address can not be "
353 				    "link-local");
354 				YYERROR;
355 			}
356 		}
357 		| GTSMENABLE yesno {
358 			if ($2 == 0)
359 				defs->afflags |= F_LDPD_AF_NO_GTSM;
360 		}
361 		| af_defaults
362 		| iface_defaults
363 		| tnbr_defaults
364 		| interface
365 		| tneighbor
366 		;
367 
368 af_defaults	: THELLOACCEPT yesno {
369 			if ($2 == 0)
370 				defs->afflags &= ~F_LDPD_AF_THELLO_ACCEPT;
371 			else
372 				defs->afflags |= F_LDPD_AF_THELLO_ACCEPT;
373 		}
374 		| EXPNULL yesno {
375 			if ($2 == 0)
376 				defs->afflags &= ~F_LDPD_AF_EXPNULL;
377 			else
378 				defs->afflags |= F_LDPD_AF_EXPNULL;
379 		}
380 		| KEEPALIVE NUMBER {
381 			if ($2 < MIN_KEEPALIVE || $2 > MAX_KEEPALIVE) {
382 				yyerror("keepalive out of range (%d-%d)",
383 				    MIN_KEEPALIVE, MAX_KEEPALIVE);
384 				YYERROR;
385 			}
386 			defs->keepalive = $2;
387 		}
388 		;
389 
390 iface_defaults	: LHELLOHOLDTIME NUMBER {
391 			if ($2 < MIN_HOLDTIME || $2 > MAX_HOLDTIME) {
392 				yyerror("hello-holdtime out of range (%d-%d)",
393 				    MIN_HOLDTIME, MAX_HOLDTIME);
394 				YYERROR;
395 			}
396 			defs->lhello_holdtime = $2;
397 		}
398 		| LHELLOINTERVAL NUMBER {
399 			if ($2 < MIN_HELLO_INTERVAL ||
400 			    $2 > MAX_HELLO_INTERVAL) {
401 				yyerror("hello-interval out of range (%d-%d)",
402 				    MIN_HELLO_INTERVAL, MAX_HELLO_INTERVAL);
403 				YYERROR;
404 			}
405 			defs->lhello_interval = $2;
406 		}
407 		;
408 
409 tnbr_defaults	: THELLOHOLDTIME NUMBER {
410 			if ($2 < MIN_HOLDTIME || $2 > MAX_HOLDTIME) {
411 				yyerror("hello-holdtime out of range (%d-%d)",
412 				    MIN_HOLDTIME, MAX_HOLDTIME);
413 				YYERROR;
414 			}
415 			defs->thello_holdtime = $2;
416 		}
417 		| THELLOINTERVAL NUMBER {
418 			if ($2 < MIN_HELLO_INTERVAL ||
419 			    $2 > MAX_HELLO_INTERVAL) {
420 				yyerror("hello-interval out of range (%d-%d)",
421 				    MIN_HELLO_INTERVAL, MAX_HELLO_INTERVAL);
422 				YYERROR;
423 			}
424 			defs->thello_interval = $2;
425 		}
426 		;
427 
428 tcpmd5		: TCP MD5SIG PASSWORD STRING {
429 			size_t len;
430 
431 			$$ = calloc(1, sizeof(*$$));
432 			if ($$ == NULL) {
433 				free($4);
434 				yyerror("unable to allocate md5 key");
435 				YYERROR;
436 			}
437 
438 			len = strlen($4);
439 			if (len > sizeof($$->md5key)) {
440 				free($$);
441 				free($4);
442 				yyerror("tcp md5sig password too long: "
443 				    "max %zu", sizeof($$->md5key));
444 				YYERROR;
445 			}
446 
447 			memcpy($$->md5key, $4, len);
448 			$$->md5key_len = len;
449 
450 			free($4);
451 		}
452 		| TCP MD5SIG KEY STRING {
453 			int len;
454 
455 			$$ = calloc(1, sizeof(*$$));
456 			if ($$ == NULL) {
457 				free($4);
458 				yyerror("unable to allocate md5 key");
459 				YYERROR;
460 			}
461 
462 			len = str2key($$->md5key, $4, sizeof($$->md5key));
463 			if (len == -1) {
464 				free($$);
465 				free($4);
466 				yyerror("invalid hex string");
467 				YYERROR;
468 			}
469 			if ((size_t)len > sizeof($$->md5key_len)) {
470 				free($$);
471 				free($4);
472 				yyerror("tcp md5sig key too long: %d "
473 				    "max %zu", len, sizeof($$->md5key));
474 				YYERROR;
475 			}
476 
477 			$$->md5key_len = len;
478 
479 			free($4);
480 		}
481 		| NO TCP MD5SIG {
482 			$$ = calloc(1, sizeof(*$$));
483 			if ($$ == NULL) {
484 				yyerror("unable to allocate no md5 key");
485 				YYERROR;
486 			}
487 			$$->md5key_len = 0;
488 		}
489 		;
490 
491 optnbrprefix	: STRING {
492 			$$ = calloc(1, sizeof(*$$));
493 			if ($$ == NULL) {
494 				yyerror("unable to allocate auth");
495 				free($1);
496 				YYERROR;
497 			}
498 
499 			$$->idlen = inet_net_pton(AF_INET, $1,
500 			    &$$->id, sizeof($$->id));
501 			if ($$->idlen == -1) {
502 				yyerror("%s: %s", $1, strerror(errno));
503 				free($1);
504 				YYERROR;
505 			}
506 		}
507 		| /* empty */ {
508 			$$ = NULL;
509 		}
510 		;
511 
512 auth		: tcpmd5 optnbrprefix {
513 			$$ = $1;
514 			if ($2 != NULL) {
515 				$$->id = $2->id;
516 				$$->idlen = $2->idlen;
517 				free($2);
518 			} else {
519 				$$->id.s_addr = 0;
520 				$$->idlen = 0;
521 			}
522 		}
523 		;
524 
525 nbr_opts	: KEEPALIVE NUMBER {
526 			if ($2 < MIN_KEEPALIVE || $2 > MAX_KEEPALIVE) {
527 				yyerror("keepalive out of range (%d-%d)",
528 				    MIN_KEEPALIVE, MAX_KEEPALIVE);
529 				YYERROR;
530 			}
531 			nbrp->keepalive = $2;
532 			nbrp->flags |= F_NBRP_KEEPALIVE;
533 		}
534 		| tcpmd5 {
535 			/* this is syntactic sugar... */
536 			$1->id = nbrp->lsr_id;
537 			$1->idlen = 32;
538 			LIST_INSERT_HEAD(&conf->auth_list, $1, entry);
539 		}
540 		| GTSMENABLE yesno {
541 			nbrp->flags |= F_NBRP_GTSM;
542 			nbrp->gtsm_enabled = $2;
543 		}
544 		| GTSMHOPS NUMBER {
545 			if ($2 < 1 || $2 > 255) {
546 				yyerror("invalid number of hops %lld", $2);
547 				YYERROR;
548 			}
549 			nbrp->gtsm_hops = $2;
550 			nbrp->flags |= F_NBRP_GTSM_HOPS;
551 		}
552 		;
553 
554 pw_defaults	: STATUSTLV yesno {
555 			if ($2 == 1)
556 				defs->pwflags |= F_PW_STATUSTLV_CONF;
557 			else
558 				defs->pwflags &= ~F_PW_STATUSTLV_CONF;
559 		}
560 		| CONTROLWORD yesno {
561 			if ($2 == 1)
562 				defs->pwflags |= F_PW_CWORD_CONF;
563 			else
564 				defs->pwflags &= ~F_PW_CWORD_CONF;
565 		}
566 		;
567 
568 pwopts		: PWID NUMBER {
569 			if ($2 < MIN_PWID_ID ||
570 			    $2 > MAX_PWID_ID) {
571 				yyerror("pw-id out of range (%d-%d)",
572 				    MIN_PWID_ID, MAX_PWID_ID);
573 				YYERROR;
574 			}
575 
576 			pw->pwid = $2;
577 		}
578 		| NEIGHBORID routerid {
579 			pw->lsr_id = $2;
580 		}
581 		| NEIGHBORADDR STRING {
582 			int		 family;
583 			union ldpd_addr	 addr;
584 
585 			if (get_af_address($2, &family, &addr) == -1) {
586 				yyerror("error parsing neighbor address");
587 				free($2);
588 				YYERROR;
589 			}
590 			free($2);
591 			if (bad_addr(family, &addr)) {
592 				yyerror("invalid neighbor address");
593 				YYERROR;
594 			}
595 			if (family == AF_INET6 &&
596 			    IN6_IS_SCOPE_EMBED(&addr.v6)) {
597 				yyerror("neighbor address can not be "
598 				    "link-local");
599 				YYERROR;
600 			}
601 
602 			pw->af = family;
603 			pw->addr = addr;
604 		}
605 		| pw_defaults
606 		;
607 
608 pseudowire	: PSEUDOWIRE STRING {
609 			struct kif	*kif;
610 
611 			if ((kif = kif_findname($2)) == NULL) {
612 				yyerror("unknown interface %s", $2);
613 				free($2);
614 				YYERROR;
615 			}
616 			free($2);
617 
618 			if (kif->if_type != IFT_MPLSTUNNEL &&
619 			    kmpw_find(kif->ifname) == -1) {
620 				yyerror("unsupported interface type on "
621 				    "interface %s", kif->ifname);
622 				YYERROR;
623 			}
624 
625 			pw = conf_get_l2vpn_pw(l2vpn, kif);
626 			if (pw == NULL)
627 				YYERROR;
628 
629 			pwdefs = *defs;
630 			defs = &pwdefs;
631 		} pw_block {
632 			struct l2vpn	*l;
633 			struct l2vpn_pw *p;
634 
635 			/* check for errors */
636 			if (pw->pwid == 0) {
637 				yyerror("missing pseudowire id");
638 				YYERROR;
639 			}
640 			if (pw->lsr_id.s_addr == INADDR_ANY) {
641 				yyerror("missing pseudowire neighbor-id");
642 				YYERROR;
643 			}
644 			LIST_FOREACH(l, &conf->l2vpn_list, entry) {
645 				LIST_FOREACH(p, &l->pw_list, entry) {
646 					if (pw != p &&
647 					    pw->pwid == p->pwid &&
648 					    pw->af == p->af &&
649 					    pw->lsr_id.s_addr ==
650 					    p->lsr_id.s_addr) {
651 						yyerror("pseudowire already "
652 						    "configured");
653 						YYERROR;
654 					}
655 				}
656 			}
657 
658 			/*
659 			 * If the neighbor address is not specified, use the
660 			 * neighbor id.
661 			 */
662 			if (pw->af == AF_UNSPEC) {
663 				pw->af = AF_INET;
664 				pw->addr.v4 = pw->lsr_id;
665 			}
666 
667 			pw->flags = defs->pwflags;
668 			pw = NULL;
669 			defs = &globaldefs;
670 		}
671 		;
672 
673 pw_block	: '{' optnl pwopts_l '}'
674 		| '{' optnl '}'
675 		| /* nothing */
676 		;
677 
678 pwopts_l	: pwopts_l pwopts nl
679 		| pwopts optnl
680 		;
681 
682 l2vpnopts	: PWTYPE pw_type {
683 			l2vpn->pw_type = $2;
684 		}
685 		| MTU NUMBER {
686 			if ($2 < MIN_L2VPN_MTU ||
687 			    $2 > MAX_L2VPN_MTU) {
688 				yyerror("l2vpn mtu out of range (%d-%d)",
689 				    MIN_L2VPN_MTU, MAX_L2VPN_MTU);
690 				YYERROR;
691 			}
692 			l2vpn->mtu = $2;
693 		}
694 		| pw_defaults
695 		| BRIDGE STRING {
696 			struct l2vpn	 *l;
697 			struct kif	 *kif;
698 
699 			if ((kif = kif_findname($2)) == NULL) {
700 				yyerror("unknown interface %s", $2);
701 				free($2);
702 				YYERROR;
703 			}
704 			free($2);
705 
706 			if (l2vpn->br_ifindex != 0) {
707 				yyerror("bridge interface cannot be "
708 				    "redefined on l2vpn %s", l2vpn->name);
709 				YYERROR;
710 			}
711 
712 			if (kif->if_type != IFT_BRIDGE) {
713 				yyerror("unsupported interface type on "
714 				    "interface %s", kif->ifname);
715 				YYERROR;
716 			}
717 
718 			LIST_FOREACH(l, &conf->l2vpn_list, entry) {
719 				if (l->br_ifindex == kif->ifindex) {
720 					yyerror("bridge %s is already being "
721 					    "used by l2vpn %s", kif->ifname,
722 					    l->name);
723 					YYERROR;
724 				}
725 			}
726 
727 			l2vpn->br_ifindex = kif->ifindex;
728 			strlcpy(l2vpn->br_ifname, kif->ifname,
729 			    sizeof(l2vpn->br_ifname));
730 		}
731 		| INTERFACE STRING {
732 			struct kif	*kif;
733 			struct l2vpn_if	*lif;
734 
735 			if ((kif = kif_findname($2)) == NULL) {
736 				yyerror("unknown interface %s", $2);
737 				free($2);
738 				YYERROR;
739 			}
740 			free($2);
741 
742 			lif = conf_get_l2vpn_if(l2vpn, kif);
743 			if (lif == NULL)
744 				YYERROR;
745 		}
746 		| pseudowire
747 		;
748 
749 optnl		: '\n' optnl
750 		|
751 		;
752 
753 nl		: '\n' optnl		/* one newline or more */
754 		;
755 
756 interface	: INTERFACE STRING	{
757 			struct kif	*kif;
758 
759 			if ((kif = kif_findname($2)) == NULL) {
760 				yyerror("unknown interface %s", $2);
761 				free($2);
762 				YYERROR;
763 			}
764 			free($2);
765 
766 			iface = conf_get_if(kif);
767 			if (iface == NULL)
768 				YYERROR;
769 
770 			ia = iface_af_get(iface, af);
771 			if (ia->enabled) {
772 				yyerror("interface %s already configured for "
773 				    "address-family %s", kif->ifname,
774 				    af_name(af));
775 				YYERROR;
776 			}
777 			ia->enabled = 1;
778 
779 			ifacedefs = *defs;
780 			defs = &ifacedefs;
781 		} interface_block {
782 			ia->hello_holdtime = defs->lhello_holdtime;
783 			ia->hello_interval = defs->lhello_interval;
784 			iface = NULL;
785 			defs = &afdefs;
786 		}
787 		;
788 
789 interface_block	: '{' optnl interfaceopts_l '}'
790 		| '{' optnl '}'
791 		| /* nothing */
792 		;
793 
794 interfaceopts_l	: interfaceopts_l iface_defaults nl
795 		| iface_defaults optnl
796 		;
797 
798 tneighbor	: TNEIGHBOR STRING	{
799 			union ldpd_addr	 addr;
800 
801 			if (get_address($2, &addr) == -1) {
802 				yyerror("error parsing targeted-neighbor "
803 				    "address");
804 				free($2);
805 				YYERROR;
806 			}
807 			free($2);
808 			if (bad_addr(af, &addr)) {
809 				yyerror("invalid targeted-neighbor address");
810 				YYERROR;
811 			}
812 			if (af == AF_INET6 &&
813 			   IN6_IS_SCOPE_EMBED(&addr.v6)) {
814 				yyerror("targeted-neighbor address can not be "
815 				    "link-local");
816 				YYERROR;
817 			}
818 
819 			tnbr = conf_get_tnbr(&addr);
820 			if (tnbr == NULL)
821 				YYERROR;
822 
823 			tnbrdefs = *defs;
824 			defs = &tnbrdefs;
825 		} tneighbor_block {
826 			tnbr->hello_holdtime = defs->thello_holdtime;
827 			tnbr->hello_interval = defs->thello_interval;
828 			tnbr = NULL;
829 			defs = &afdefs;
830 		}
831 		;
832 
833 tneighbor_block	: '{' optnl tneighboropts_l '}'
834 		| '{' optnl '}'
835 		| /* nothing */
836 		;
837 
838 tneighboropts_l	: tneighboropts_l tnbr_defaults nl
839 		| tnbr_defaults optnl
840 		;
841 
842 neighbor	: NEIGHBOR routerid	{
843 			nbrp = conf_get_nbrp($2);
844 			if (nbrp == NULL)
845 				YYERROR;
846 		} neighbor_block {
847 			nbrp = NULL;
848 		}
849 		;
850 
851 neighbor_block	: '{' optnl neighboropts_l '}'
852 		| '{' optnl '}'
853 		| /* nothing */
854 		;
855 
856 neighboropts_l	: neighboropts_l nbr_opts nl
857 		| nbr_opts optnl
858 		;
859 
860 l2vpn		: L2VPN STRING TYPE l2vpn_type {
861 			l2vpn = conf_get_l2vpn($2);
862 			if (l2vpn == NULL)
863 				YYERROR;
864 			l2vpn->type = $4;
865 		} l2vpn_block {
866 			l2vpn = NULL;
867 		}
868 		;
869 
870 l2vpn_block	: '{' optnl l2vpnopts_l '}'
871 		| '{' optnl '}'
872 		| /* nothing */
873 		;
874 
875 l2vpnopts_l	: l2vpnopts_l l2vpnopts nl
876 		| l2vpnopts optnl
877 		;
878 
879 %%
880 
881 struct keywords {
882 	const char	*k_name;
883 	int		 k_val;
884 };
885 
886 static int
887 yyerror(const char *fmt, ...)
888 {
889 	va_list		 ap;
890 	char		*msg;
891 
892 	file->errors++;
893 	va_start(ap, fmt);
894 	if (vasprintf(&msg, fmt, ap) == -1)
895 		fatalx("yyerror vasprintf");
896 	va_end(ap);
897 	logit(LOG_CRIT, "%s:%d: %s", file->name, yylval.lineno, msg);
898 	free(msg);
899 	return (0);
900 }
901 
902 static int
903 kw_cmp(const void *k, const void *e)
904 {
905 	return (strcmp(k, ((const struct keywords *)e)->k_name));
906 }
907 
908 static int
909 lookup(char *s)
910 {
911 	/* this has to be sorted always */
912 	static const struct keywords keywords[] = {
913 		{"address-family",		AF},
914 		{"bridge",			BRIDGE},
915 		{"control-word",		CONTROLWORD},
916 		{"ds-cisco-interop",		DSCISCOINTEROP},
917 		{"ethernet",			ETHERNET},
918 		{"ethernet-tagged",		ETHERNETTAGGED},
919 		{"explicit-null",		EXPNULL},
920 		{"fib-update",			FIBUPDATE},
921 		{"gtsm-enable",			GTSMENABLE},
922 		{"gtsm-hops",			GTSMHOPS},
923 		{"include",			INCLUDE},
924 		{"inet",			INET},
925 		{"inet6",			INET6},
926 		{"interface",			INTERFACE},
927 		{"ipv4",			IPV4},
928 		{"ipv6",			IPV6},
929 		{"keepalive",			KEEPALIVE},
930 		{"key",				KEY},
931 		{"l2vpn",			L2VPN},
932 		{"link-hello-holdtime",		LHELLOHOLDTIME},
933 		{"link-hello-interval",		LHELLOINTERVAL},
934 		{"md5sig",			MD5SIG},
935 		{"mtu",				MTU},
936 		{"neighbor",			NEIGHBOR},
937 		{"neighbor-addr",		NEIGHBORADDR},
938 		{"neighbor-id",			NEIGHBORID},
939 		{"no",				NO},
940 		{"password",			PASSWORD},
941 		{"pseudowire",			PSEUDOWIRE},
942 		{"pw-id",			PWID},
943 		{"pw-type",			PWTYPE},
944 		{"rdomain",			RDOMAIN},
945 		{"router-id",			ROUTERID},
946 		{"status-tlv",			STATUSTLV},
947 		{"targeted-hello-accept",	THELLOACCEPT},
948 		{"targeted-hello-holdtime",	THELLOHOLDTIME},
949 		{"targeted-hello-interval",	THELLOINTERVAL},
950 		{"targeted-neighbor",		TNEIGHBOR},
951 		{"tcp",				TCP},
952 		{"transport-address",		TRANSADDRESS},
953 		{"transport-preference",	TRANSPREFERENCE},
954 		{"type",			TYPE},
955 		{"vpls",			VPLS},
956 		{"yes",				YES}
957 	};
958 	const struct keywords	*p;
959 
960 	p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]),
961 	    sizeof(keywords[0]), kw_cmp);
962 
963 	if (p)
964 		return (p->k_val);
965 	else
966 		return (STRING);
967 }
968 
969 #define START_EXPAND	1
970 #define DONE_EXPAND	2
971 
972 static int	expanding;
973 
974 int
975 igetc(void)
976 {
977 	int	c;
978 
979 	while (1) {
980 		if (file->ungetpos > 0)
981 			c = file->ungetbuf[--file->ungetpos];
982 		else
983 			c = getc(file->stream);
984 
985 		if (c == START_EXPAND)
986 			expanding = 1;
987 		else if (c == DONE_EXPAND)
988 			expanding = 0;
989 		else
990 			break;
991 	}
992 	return (c);
993 }
994 
995 static int
996 lgetc(int quotec)
997 {
998 	int		c, next;
999 
1000 	if (quotec) {
1001 		if ((c = igetc()) == EOF) {
1002 			yyerror("reached end of file while parsing "
1003 			    "quoted string");
1004 			if (file == topfile || popfile() == EOF)
1005 				return (EOF);
1006 			return (quotec);
1007 		}
1008 		return (c);
1009 	}
1010 
1011 	while ((c = igetc()) == '\\') {
1012 		next = igetc();
1013 		if (next != '\n') {
1014 			c = next;
1015 			break;
1016 		}
1017 		yylval.lineno = file->lineno;
1018 		file->lineno++;
1019 	}
1020 
1021 	if (c == EOF) {
1022 		/*
1023 		 * Fake EOL when hit EOF for the first time. This gets line
1024 		 * count right if last line in included file is syntactically
1025 		 * invalid and has no newline.
1026 		 */
1027 		if (file->eof_reached == 0) {
1028 			file->eof_reached = 1;
1029 			return ('\n');
1030 		}
1031 		while (c == EOF) {
1032 			if (file == topfile || popfile() == EOF)
1033 				return (EOF);
1034 			c = igetc();
1035 		}
1036 	}
1037 	return (c);
1038 }
1039 
1040 void
1041 lungetc(int c)
1042 {
1043 	if (c == EOF)
1044 		return;
1045 
1046 	if (file->ungetpos >= file->ungetsize) {
1047 		void *p = reallocarray(file->ungetbuf, file->ungetsize, 2);
1048 		if (p == NULL)
1049 			err(1, "%s", __func__);
1050 		file->ungetbuf = p;
1051 		file->ungetsize *= 2;
1052 	}
1053 	file->ungetbuf[file->ungetpos++] = c;
1054 }
1055 
1056 static int
1057 findeol(void)
1058 {
1059 	int	c;
1060 
1061 	/* skip to either EOF or the first real EOL */
1062 	while (1) {
1063 		c = lgetc(0);
1064 		if (c == '\n') {
1065 			file->lineno++;
1066 			break;
1067 		}
1068 		if (c == EOF)
1069 			break;
1070 	}
1071 	return (ERROR);
1072 }
1073 
1074 static int
1075 yylex(void)
1076 {
1077 	unsigned char	 buf[8096];
1078 	unsigned char	*p, *val;
1079 	int		 quotec, next, c;
1080 	int		 token;
1081 
1082  top:
1083 	p = buf;
1084 	while ((c = lgetc(0)) == ' ' || c == '\t')
1085 		; /* nothing */
1086 
1087 	yylval.lineno = file->lineno;
1088 	if (c == '#')
1089 		while ((c = lgetc(0)) != '\n' && c != EOF)
1090 			; /* nothing */
1091 	if (c == '$' && !expanding) {
1092 		while (1) {
1093 			if ((c = lgetc(0)) == EOF)
1094 				return (0);
1095 
1096 			if (p + 1 >= buf + sizeof(buf) - 1) {
1097 				yyerror("string too long");
1098 				return (findeol());
1099 			}
1100 			if (isalnum(c) || c == '_') {
1101 				*p++ = c;
1102 				continue;
1103 			}
1104 			*p = '\0';
1105 			lungetc(c);
1106 			break;
1107 		}
1108 		val = symget(buf);
1109 		if (val == NULL) {
1110 			yyerror("macro '%s' not defined", buf);
1111 			return (findeol());
1112 		}
1113 		p = val + strlen(val) - 1;
1114 		lungetc(DONE_EXPAND);
1115 		while (p >= val) {
1116 			lungetc(*p);
1117 			p--;
1118 		}
1119 		lungetc(START_EXPAND);
1120 		goto top;
1121 	}
1122 
1123 	switch (c) {
1124 	case '\'':
1125 	case '"':
1126 		quotec = c;
1127 		while (1) {
1128 			if ((c = lgetc(quotec)) == EOF)
1129 				return (0);
1130 			if (c == '\n') {
1131 				file->lineno++;
1132 				continue;
1133 			} else if (c == '\\') {
1134 				if ((next = lgetc(quotec)) == EOF)
1135 					return (0);
1136 				if (next == quotec || next == ' ' ||
1137 				    next == '\t')
1138 					c = next;
1139 				else if (next == '\n') {
1140 					file->lineno++;
1141 					continue;
1142 				} else
1143 					lungetc(next);
1144 			} else if (c == quotec) {
1145 				*p = '\0';
1146 				break;
1147 			} else if (c == '\0') {
1148 				yyerror("syntax error");
1149 				return (findeol());
1150 			}
1151 			if (p + 1 >= buf + sizeof(buf) - 1) {
1152 				yyerror("string too long");
1153 				return (findeol());
1154 			}
1155 			*p++ = c;
1156 		}
1157 		yylval.v.string = strdup(buf);
1158 		if (yylval.v.string == NULL)
1159 			err(1, "%s", __func__);
1160 		return (STRING);
1161 	}
1162 
1163 #define allowed_to_end_number(x) \
1164 	(isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' || x == '=')
1165 
1166 	if (c == '-' || isdigit(c)) {
1167 		do {
1168 			*p++ = c;
1169 			if ((size_t)(p-buf) >= sizeof(buf)) {
1170 				yyerror("string too long");
1171 				return (findeol());
1172 			}
1173 		} while ((c = lgetc(0)) != EOF && isdigit(c));
1174 		lungetc(c);
1175 		if (p == buf + 1 && buf[0] == '-')
1176 			goto nodigits;
1177 		if (c == EOF || allowed_to_end_number(c)) {
1178 			const char *errstr = NULL;
1179 
1180 			*p = '\0';
1181 			yylval.v.number = strtonum(buf, LLONG_MIN,
1182 			    LLONG_MAX, &errstr);
1183 			if (errstr) {
1184 				yyerror("\"%s\" invalid number: %s",
1185 				    buf, errstr);
1186 				return (findeol());
1187 			}
1188 			return (NUMBER);
1189 		} else {
1190  nodigits:
1191 			while (p > buf + 1)
1192 				lungetc(*--p);
1193 			c = *--p;
1194 			if (c == '-')
1195 				return (c);
1196 		}
1197 	}
1198 
1199 #define allowed_in_string(x) \
1200 	(isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \
1201 	x != '{' && x != '}' && \
1202 	x != '!' && x != '=' && x != '#' && \
1203 	x != ','))
1204 
1205 	if (isalnum(c) || c == ':' || c == '_') {
1206 		do {
1207 			*p++ = c;
1208 			if ((size_t)(p-buf) >= sizeof(buf)) {
1209 				yyerror("string too long");
1210 				return (findeol());
1211 			}
1212 		} while ((c = lgetc(0)) != EOF && (allowed_in_string(c)));
1213 		lungetc(c);
1214 		*p = '\0';
1215 		if ((token = lookup(buf)) == STRING)
1216 			if ((yylval.v.string = strdup(buf)) == NULL)
1217 				err(1, "%s", __func__);
1218 		return (token);
1219 	}
1220 	if (c == '\n') {
1221 		yylval.lineno = file->lineno;
1222 		file->lineno++;
1223 	}
1224 	if (c == EOF)
1225 		return (0);
1226 	return (c);
1227 }
1228 
1229 static int
1230 check_file_secrecy(int fd, const char *fname)
1231 {
1232 	struct stat	st;
1233 
1234 	if (fstat(fd, &st)) {
1235 		log_warn("cannot stat %s", fname);
1236 		return (-1);
1237 	}
1238 	if (st.st_uid != 0 && st.st_uid != getuid()) {
1239 		log_warnx("%s: owner not root or current user", fname);
1240 		return (-1);
1241 	}
1242 	if (st.st_mode & (S_IWGRP | S_IXGRP | S_IRWXO)) {
1243 		log_warnx("%s: group writable or world read/writable", fname);
1244 		return (-1);
1245 	}
1246 	return (0);
1247 }
1248 
1249 static struct file *
1250 pushfile(const char *name, int secret)
1251 {
1252 	struct file	*nfile;
1253 
1254 	if ((nfile = calloc(1, sizeof(struct file))) == NULL) {
1255 		log_warn("%s", __func__);
1256 		return (NULL);
1257 	}
1258 	if ((nfile->name = strdup(name)) == NULL) {
1259 		log_warn("%s", __func__);
1260 		free(nfile);
1261 		return (NULL);
1262 	}
1263 	if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
1264 		log_warn("%s: %s", __func__, nfile->name);
1265 		free(nfile->name);
1266 		free(nfile);
1267 		return (NULL);
1268 	} else if (secret &&
1269 	    check_file_secrecy(fileno(nfile->stream), nfile->name)) {
1270 		fclose(nfile->stream);
1271 		free(nfile->name);
1272 		free(nfile);
1273 		return (NULL);
1274 	}
1275 	nfile->lineno = TAILQ_EMPTY(&files) ? 1 : 0;
1276 	nfile->ungetsize = 16;
1277 	nfile->ungetbuf = malloc(nfile->ungetsize);
1278 	if (nfile->ungetbuf == NULL) {
1279 		log_warn("%s", __func__);
1280 		fclose(nfile->stream);
1281 		free(nfile->name);
1282 		free(nfile);
1283 		return (NULL);
1284 	}
1285 	TAILQ_INSERT_TAIL(&files, nfile, entry);
1286 	return (nfile);
1287 }
1288 
1289 static int
1290 popfile(void)
1291 {
1292 	struct file	*prev;
1293 
1294 	if ((prev = TAILQ_PREV(file, files, entry)) != NULL)
1295 		prev->errors += file->errors;
1296 
1297 	TAILQ_REMOVE(&files, file, entry);
1298 	fclose(file->stream);
1299 	free(file->name);
1300 	free(file->ungetbuf);
1301 	free(file);
1302 	file = prev;
1303 	return (file ? 0 : EOF);
1304 }
1305 
1306 struct ldpd_conf *
1307 parse_config(char *filename)
1308 {
1309 	struct sym	*sym, *next;
1310 
1311 	conf = config_new_empty();
1312 	conf->rdomain = 0;
1313 	conf->trans_pref = DUAL_STACK_LDPOV6;
1314 
1315 	defs = &globaldefs;
1316 	defs->keepalive = DEFAULT_KEEPALIVE;
1317 	defs->lhello_holdtime = LINK_DFLT_HOLDTIME;
1318 	defs->lhello_interval = DEFAULT_HELLO_INTERVAL;
1319 	defs->thello_holdtime = TARGETED_DFLT_HOLDTIME;
1320 	defs->thello_interval = DEFAULT_HELLO_INTERVAL;
1321 	defs->pwflags = F_PW_STATUSTLV_CONF|F_PW_CWORD_CONF;
1322 
1323 	if ((file = pushfile(filename,
1324 	    !(global.cmd_opts & LDPD_OPT_NOACTION))) == NULL) {
1325 		free(conf);
1326 		return (NULL);
1327 	}
1328 	topfile = file;
1329 
1330 	yyparse();
1331 	errors = file->errors;
1332 	popfile();
1333 
1334 	/* Free macros and check which have not been used. */
1335 	TAILQ_FOREACH_SAFE(sym, &symhead, entry, next) {
1336 		if ((global.cmd_opts & LDPD_OPT_VERBOSE2) && !sym->used)
1337 			fprintf(stderr, "warning: macro '%s' not "
1338 			    "used\n", sym->nam);
1339 		if (!sym->persist) {
1340 			free(sym->nam);
1341 			free(sym->val);
1342 			TAILQ_REMOVE(&symhead, sym, entry);
1343 			free(sym);
1344 		}
1345 	}
1346 
1347 	/* check that all interfaces belong to the configured rdomain */
1348 	errors += conf_check_rdomain(conf->rdomain);
1349 
1350 	/* free global config defaults */
1351 	if (errors) {
1352 		clear_config(conf);
1353 		return (NULL);
1354 	}
1355 
1356 	if (conf->rtr_id.s_addr == INADDR_ANY)
1357 		conf->rtr_id.s_addr = get_rtr_id();
1358 
1359 	/* if the ipv4 transport-address is not set, use the router-id */
1360 	if ((conf->ipv4.flags & F_LDPD_AF_ENABLED) &&
1361 	    conf->ipv4.trans_addr.v4.s_addr == INADDR_ANY)
1362 		conf->ipv4.trans_addr.v4 = conf->rtr_id;
1363 
1364 	return (conf);
1365 }
1366 
1367 static int
1368 symset(const char *nam, const char *val, int persist)
1369 {
1370 	struct sym	*sym;
1371 
1372 	TAILQ_FOREACH(sym, &symhead, entry) {
1373 		if (strcmp(nam, sym->nam) == 0)
1374 			break;
1375 	}
1376 
1377 	if (sym != NULL) {
1378 		if (sym->persist == 1)
1379 			return (0);
1380 		else {
1381 			free(sym->nam);
1382 			free(sym->val);
1383 			TAILQ_REMOVE(&symhead, sym, entry);
1384 			free(sym);
1385 		}
1386 	}
1387 	if ((sym = calloc(1, sizeof(*sym))) == NULL)
1388 		return (-1);
1389 
1390 	sym->nam = strdup(nam);
1391 	if (sym->nam == NULL) {
1392 		free(sym);
1393 		return (-1);
1394 	}
1395 	sym->val = strdup(val);
1396 	if (sym->val == NULL) {
1397 		free(sym->nam);
1398 		free(sym);
1399 		return (-1);
1400 	}
1401 	sym->used = 0;
1402 	sym->persist = persist;
1403 	TAILQ_INSERT_TAIL(&symhead, sym, entry);
1404 	return (0);
1405 }
1406 
1407 int
1408 cmdline_symset(char *s)
1409 {
1410 	char	*sym, *val;
1411 	int	ret;
1412 
1413 	if ((val = strrchr(s, '=')) == NULL)
1414 		return (-1);
1415 	sym = strndup(s, val - s);
1416 	if (sym == NULL)
1417 		errx(1, "%s: strndup", __func__);
1418 	ret = symset(sym, val + 1, 1);
1419 	free(sym);
1420 
1421 	return (ret);
1422 }
1423 
1424 static char *
1425 symget(const char *nam)
1426 {
1427 	struct sym	*sym;
1428 
1429 	TAILQ_FOREACH(sym, &symhead, entry) {
1430 		if (strcmp(nam, sym->nam) == 0) {
1431 			sym->used = 1;
1432 			return (sym->val);
1433 		}
1434 	}
1435 	return (NULL);
1436 }
1437 
1438 static struct iface *
1439 conf_get_if(struct kif *kif)
1440 {
1441 	struct iface	*i;
1442 	struct l2vpn	*l;
1443 
1444 	if (kif->if_type == IFT_LOOP ||
1445 	    kif->if_type == IFT_CARP ||
1446 	    kif->if_type == IFT_BRIDGE ||
1447 	    kif->if_type == IFT_MPLSTUNNEL) {
1448 		yyerror("unsupported interface type on interface %s",
1449 		    kif->ifname);
1450 		return (NULL);
1451 	}
1452 
1453 	LIST_FOREACH(l, &conf->l2vpn_list, entry)
1454 		if (l2vpn_if_find(l, kif->ifindex)) {
1455 			yyerror("interface %s already configured under "
1456 			    "l2vpn %s", kif->ifname, l->name);
1457 			return (NULL);
1458 		}
1459 
1460 	LIST_FOREACH(i, &conf->iface_list, entry)
1461 		if (i->ifindex == kif->ifindex)
1462 			return (i);
1463 
1464 	i = if_new(kif);
1465 	LIST_INSERT_HEAD(&conf->iface_list, i, entry);
1466 	return (i);
1467 }
1468 
1469 static struct tnbr *
1470 conf_get_tnbr(union ldpd_addr *addr)
1471 {
1472 	struct tnbr	*t;
1473 
1474 	t = tnbr_find(conf, af, addr);
1475 	if (t) {
1476 		yyerror("targeted neighbor %s already configured",
1477 		    log_addr(af, addr));
1478 		return (NULL);
1479 	}
1480 
1481 	t = tnbr_new(conf, af, addr);
1482 	t->flags |= F_TNBR_CONFIGURED;
1483 	LIST_INSERT_HEAD(&conf->tnbr_list, t, entry);
1484 	return (t);
1485 }
1486 
1487 static struct nbr_params *
1488 conf_get_nbrp(struct in_addr lsr_id)
1489 {
1490 	struct nbr_params	*n;
1491 
1492 	LIST_FOREACH(n, &conf->nbrp_list, entry) {
1493 		if (n->lsr_id.s_addr == lsr_id.s_addr) {
1494 			yyerror("neighbor %s already configured",
1495 			    inet_ntoa(lsr_id));
1496 			return (NULL);
1497 		}
1498 	}
1499 
1500 	n = nbr_params_new(lsr_id);
1501 	LIST_INSERT_HEAD(&conf->nbrp_list, n, entry);
1502 	return (n);
1503 }
1504 
1505 static struct l2vpn *
1506 conf_get_l2vpn(char *name)
1507 {
1508 	struct l2vpn	 *l;
1509 
1510 	if (l2vpn_find(conf, name)) {
1511 		yyerror("l2vpn %s already configured", name);
1512 		return (NULL);
1513 	}
1514 
1515 	l = l2vpn_new(name);
1516 	LIST_INSERT_HEAD(&conf->l2vpn_list, l, entry);
1517 	return (l);
1518 }
1519 
1520 static struct l2vpn_if *
1521 conf_get_l2vpn_if(struct l2vpn *l, struct kif *kif)
1522 {
1523 	struct iface	*i;
1524 	struct l2vpn	*ltmp;
1525 	struct l2vpn_if	*f;
1526 
1527 	if (kif->if_type == IFT_LOOP ||
1528 	    kif->if_type == IFT_CARP ||
1529 	    kif->if_type == IFT_BRIDGE ||
1530 	    kif->if_type == IFT_MPLSTUNNEL) {
1531 		yyerror("unsupported interface type on interface %s",
1532 		    kif->ifname);
1533 		return (NULL);
1534 	}
1535 
1536 	LIST_FOREACH(ltmp, &conf->l2vpn_list, entry)
1537 		if (l2vpn_if_find(ltmp, kif->ifindex)) {
1538 			yyerror("interface %s already configured under "
1539 			    "l2vpn %s", kif->ifname, ltmp->name);
1540 			return (NULL);
1541 		}
1542 
1543 	LIST_FOREACH(i, &conf->iface_list, entry) {
1544 		if (i->ifindex == kif->ifindex) {
1545 			yyerror("interface %s already configured",
1546 			    kif->ifname);
1547 			return (NULL);
1548 		}
1549 	}
1550 
1551 	f = l2vpn_if_new(l, kif);
1552 	LIST_INSERT_HEAD(&l2vpn->if_list, f, entry);
1553 	return (f);
1554 }
1555 
1556 static struct l2vpn_pw *
1557 conf_get_l2vpn_pw(struct l2vpn *l, struct kif *kif)
1558 {
1559 	struct l2vpn	*ltmp;
1560 	struct l2vpn_pw	*p;
1561 
1562 	LIST_FOREACH(ltmp, &conf->l2vpn_list, entry) {
1563 		if (l2vpn_pw_find(ltmp, kif->ifindex)) {
1564 			yyerror("pseudowire %s is already being "
1565 			    "used by l2vpn %s", kif->ifname, ltmp->name);
1566 			return (NULL);
1567 		}
1568 	}
1569 
1570 	p = l2vpn_pw_new(l, kif);
1571 	LIST_INSERT_HEAD(&l2vpn->pw_list, p, entry);
1572 	return (p);
1573 }
1574 
1575 int
1576 conf_check_rdomain(unsigned int rdomain)
1577 {
1578 	struct iface	*i;
1579 	int		 errs = 0;
1580 
1581 	LIST_FOREACH(i, &conf->iface_list, entry) {
1582 		if (i->rdomain != rdomain) {
1583 			logit(LOG_CRIT, "interface %s not in rdomain %u",
1584 			    i->name, rdomain);
1585 			errs++;
1586 		}
1587 	}
1588 
1589 	return (errs);
1590 }
1591 
1592 static void
1593 clear_config(struct ldpd_conf *xconf)
1594 {
1595 	struct iface		*i;
1596 	struct tnbr		*t;
1597 	struct nbr_params	*n;
1598 	struct l2vpn		*l;
1599 	struct l2vpn_if		*f;
1600 	struct l2vpn_pw		*p;
1601 
1602 	while ((i = LIST_FIRST(&xconf->iface_list)) != NULL) {
1603 		LIST_REMOVE(i, entry);
1604 		free(i);
1605 	}
1606 
1607 	while ((t = LIST_FIRST(&xconf->tnbr_list)) != NULL) {
1608 		LIST_REMOVE(t, entry);
1609 		free(t);
1610 	}
1611 
1612 	while ((n = LIST_FIRST(&xconf->nbrp_list)) != NULL) {
1613 		LIST_REMOVE(n, entry);
1614 		free(n);
1615 	}
1616 
1617 	while ((l = LIST_FIRST(&xconf->l2vpn_list)) != NULL) {
1618 		while ((f = LIST_FIRST(&l->if_list)) != NULL) {
1619 			LIST_REMOVE(f, entry);
1620 			free(f);
1621 		}
1622 		while ((p = LIST_FIRST(&l->pw_list)) != NULL) {
1623 			LIST_REMOVE(p, entry);
1624 			free(p);
1625 		}
1626 		LIST_REMOVE(l, entry);
1627 		free(l);
1628 	}
1629 
1630 	free(xconf);
1631 }
1632 
1633 static uint32_t
1634 get_rtr_id(void)
1635 {
1636 	struct ifaddrs		*ifap, *ifa;
1637 	uint32_t		 ip = 0, cur, localnet;
1638 
1639 	localnet = htonl(INADDR_LOOPBACK & IN_CLASSA_NET);
1640 
1641 	if (getifaddrs(&ifap) == -1) {
1642 		log_warn("getifaddrs");
1643 		return (0);
1644 	}
1645 
1646 	for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
1647 		if (strncmp(ifa->ifa_name, "carp", 4) == 0)
1648 			continue;
1649 		if (ifa->ifa_addr->sa_family != AF_INET)
1650 			continue;
1651 		cur = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr;
1652 		if ((cur & localnet) == localnet)	/* skip 127/8 */
1653 			continue;
1654 		if (ntohl(cur) < ntohl(ip) || ip == 0)
1655 			ip = cur;
1656 	}
1657 	freeifaddrs(ifap);
1658 
1659 	return (ip);
1660 }
1661 
1662 static int
1663 get_address(const char *s, union ldpd_addr *addr)
1664 {
1665 	switch (af) {
1666 	case AF_INET:
1667 		if (inet_pton(AF_INET, s, &addr->v4) != 1)
1668 			return (-1);
1669 		break;
1670 	case AF_INET6:
1671 		if (inet_pton(AF_INET6, s, &addr->v6) != 1)
1672 			return (-1);
1673 		break;
1674 	default:
1675 		return (-1);
1676 	}
1677 
1678 	return (0);
1679 }
1680 
1681 static int
1682 get_af_address(const char *s, int *family, union ldpd_addr *addr)
1683 {
1684 	if (inet_pton(AF_INET, s, &addr->v4) == 1) {
1685 		*family = AF_INET;
1686 		return (0);
1687 	}
1688 
1689 	if (inet_pton(AF_INET6, s, &addr->v6) == 1) {
1690 		*family = AF_INET6;
1691 		return (0);
1692 	}
1693 
1694 	return (-1);
1695 }
1696 
1697 static int
1698 hexchar(int ch)
1699 {
1700 	if (ch >= '0' && ch <= '9')
1701 		return (ch - '0');
1702 	if (ch >= 'a' && ch <= 'f')
1703 		return (ch - 'a');
1704 	if (ch >= 'A' && ch <= 'F')
1705 		return (ch - 'A');
1706 
1707 	return (-1);
1708 }
1709 
1710 static int
1711 str2key(char *dst, const char *src, int dstlen)
1712 {
1713 	int		i = 0;
1714 	int		digit;
1715 
1716 	while (*src != '\0') {
1717 		digit = hexchar(*src);
1718 		if (digit == -1)
1719 			return (-1);
1720 
1721 		if (i < dstlen)
1722 			*dst = digit << 4;
1723 
1724 		src++;
1725 		if (*src == '\0')
1726 			return (-1);
1727 		digit = hexchar(*src);
1728 		if (digit == -1)
1729 			return (-1);
1730 
1731 		if (i < dstlen)
1732 			*dst |= digit;
1733 
1734 		src++;
1735 		i++;
1736 	}
1737 
1738 	return (i);
1739 }
1740