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