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