1 %{ 2 /*- 3 * SPDX-License-Identifier: BSD-2-Clause 4 * 5 * Copyright (c) 2012 The FreeBSD Foundation 6 * 7 * This software was developed by Edward Tomasz Napierala under sponsorship 8 * from the FreeBSD Foundation. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 #include <sys/types.h> 33 #include <sys/nv.h> 34 #include <sys/queue.h> 35 #include <sys/stat.h> 36 #include <assert.h> 37 #include <libiscsiutil.h> 38 #include <libutil.h> 39 #include <stdio.h> 40 #include <stdlib.h> 41 #include <string.h> 42 #include <netinet/in.h> 43 #include <netinet/ip.h> 44 45 #include "conf.h" 46 47 extern FILE *yyin; 48 extern char *yytext; 49 extern int lineno; 50 51 extern void yyerror(const char *); 52 extern void yyrestart(FILE *); 53 54 %} 55 56 %token ALIAS AUTH_GROUP AUTH_TYPE BACKEND BLOCKSIZE CHAP CHAP_MUTUAL 57 %token CLOSING_BRACKET CTL_LUN DEBUG DEVICE_ID DEVICE_TYPE 58 %token DISCOVERY_AUTH_GROUP DISCOVERY_FILTER DSCP FOREIGN 59 %token INITIATOR_NAME INITIATOR_PORTAL ISNS_SERVER ISNS_PERIOD ISNS_TIMEOUT 60 %token LISTEN LISTEN_ISER LUN MAXPROC OFFLOAD OPENING_BRACKET OPTION 61 %token PATH PCP PIDFILE PORT PORTAL_GROUP REDIRECT SEMICOLON SERIAL 62 %token SIZE STR TAG TARGET TIMEOUT 63 %token AF11 AF12 AF13 AF21 AF22 AF23 AF31 AF32 AF33 AF41 AF42 AF43 64 %token BE EF CS0 CS1 CS2 CS3 CS4 CS5 CS6 CS7 65 66 %union 67 { 68 char *str; 69 } 70 71 %token <str> STR 72 73 %% 74 75 statements: 76 | 77 statements statement 78 | 79 statements statement SEMICOLON 80 ; 81 82 statement: 83 debug 84 | 85 timeout 86 | 87 maxproc 88 | 89 pidfile 90 | 91 isns_server 92 | 93 isns_period 94 | 95 isns_timeout 96 | 97 auth_group 98 | 99 portal_group 100 | 101 lun 102 | 103 target 104 ; 105 106 debug: DEBUG STR 107 { 108 uint64_t tmp; 109 110 if (expand_number($2, &tmp) != 0) { 111 yyerror("invalid numeric value"); 112 free($2); 113 return (1); 114 } 115 free($2); 116 117 conf_set_debug(tmp); 118 } 119 ; 120 121 timeout: TIMEOUT STR 122 { 123 uint64_t tmp; 124 125 if (expand_number($2, &tmp) != 0) { 126 yyerror("invalid numeric value"); 127 free($2); 128 return (1); 129 } 130 free($2); 131 132 conf_set_timeout(tmp); 133 } 134 ; 135 136 maxproc: MAXPROC STR 137 { 138 uint64_t tmp; 139 140 if (expand_number($2, &tmp) != 0) { 141 yyerror("invalid numeric value"); 142 free($2); 143 return (1); 144 } 145 free($2); 146 147 conf_set_maxproc(tmp); 148 } 149 ; 150 151 pidfile: PIDFILE STR 152 { 153 bool ok; 154 155 ok = conf_set_pidfile_path($2); 156 free($2); 157 if (!ok) 158 return (1); 159 } 160 ; 161 162 isns_server: ISNS_SERVER STR 163 { 164 bool ok; 165 166 ok = isns_add_server($2); 167 free($2); 168 if (!ok) 169 return (1); 170 } 171 ; 172 173 isns_period: ISNS_PERIOD STR 174 { 175 uint64_t tmp; 176 177 if (expand_number($2, &tmp) != 0) { 178 yyerror("invalid numeric value"); 179 free($2); 180 return (1); 181 } 182 free($2); 183 184 conf_set_isns_period(tmp); 185 } 186 ; 187 188 isns_timeout: ISNS_TIMEOUT STR 189 { 190 uint64_t tmp; 191 192 if (expand_number($2, &tmp) != 0) { 193 yyerror("invalid numeric value"); 194 free($2); 195 return (1); 196 } 197 free($2); 198 199 conf_set_isns_timeout(tmp); 200 } 201 ; 202 203 auth_group: AUTH_GROUP auth_group_name 204 OPENING_BRACKET auth_group_entries CLOSING_BRACKET 205 { 206 auth_group_finish(); 207 } 208 ; 209 210 auth_group_name: STR 211 { 212 bool ok; 213 214 ok = auth_group_start($1); 215 free($1); 216 if (!ok) 217 return (1); 218 } 219 ; 220 221 auth_group_entries: 222 | 223 auth_group_entries auth_group_entry 224 | 225 auth_group_entries auth_group_entry SEMICOLON 226 ; 227 228 auth_group_entry: 229 auth_group_auth_type 230 | 231 auth_group_chap 232 | 233 auth_group_chap_mutual 234 | 235 auth_group_initiator_name 236 | 237 auth_group_initiator_portal 238 ; 239 240 auth_group_auth_type: AUTH_TYPE STR 241 { 242 bool ok; 243 244 ok = auth_group_set_type($2); 245 free($2); 246 if (!ok) 247 return (1); 248 } 249 ; 250 251 auth_group_chap: CHAP STR STR 252 { 253 bool ok; 254 255 ok = auth_group_add_chap($2, $3); 256 free($2); 257 free($3); 258 if (!ok) 259 return (1); 260 } 261 ; 262 263 auth_group_chap_mutual: CHAP_MUTUAL STR STR STR STR 264 { 265 bool ok; 266 267 ok = auth_group_add_chap_mutual($2, $3, $4, $5); 268 free($2); 269 free($3); 270 free($4); 271 free($5); 272 if (!ok) 273 return (1); 274 } 275 ; 276 277 auth_group_initiator_name: INITIATOR_NAME STR 278 { 279 bool ok; 280 281 ok = auth_group_add_initiator_name($2); 282 free($2); 283 if (!ok) 284 return (1); 285 } 286 ; 287 288 auth_group_initiator_portal: INITIATOR_PORTAL STR 289 { 290 bool ok; 291 292 ok = auth_group_add_initiator_portal($2); 293 free($2); 294 if (!ok) 295 return (1); 296 } 297 ; 298 299 portal_group: PORTAL_GROUP portal_group_name 300 OPENING_BRACKET portal_group_entries CLOSING_BRACKET 301 { 302 portal_group_finish(); 303 } 304 ; 305 306 portal_group_name: STR 307 { 308 bool ok; 309 310 ok = portal_group_start($1); 311 free($1); 312 if (!ok) 313 return (1); 314 } 315 ; 316 317 portal_group_entries: 318 | 319 portal_group_entries portal_group_entry 320 | 321 portal_group_entries portal_group_entry SEMICOLON 322 ; 323 324 portal_group_entry: 325 portal_group_discovery_auth_group 326 | 327 portal_group_discovery_filter 328 | 329 portal_group_foreign 330 | 331 portal_group_listen 332 | 333 portal_group_listen_iser 334 | 335 portal_group_offload 336 | 337 portal_group_option 338 | 339 portal_group_redirect 340 | 341 portal_group_tag 342 | 343 portal_group_dscp 344 | 345 portal_group_pcp 346 ; 347 348 portal_group_discovery_auth_group: DISCOVERY_AUTH_GROUP STR 349 { 350 bool ok; 351 352 ok = portal_group_set_discovery_auth_group($2); 353 free($2); 354 if (!ok) 355 return (1); 356 } 357 ; 358 359 portal_group_discovery_filter: DISCOVERY_FILTER STR 360 { 361 bool ok; 362 363 ok = portal_group_set_filter($2); 364 free($2); 365 if (!ok) 366 return (1); 367 } 368 ; 369 370 portal_group_foreign: FOREIGN 371 { 372 373 portal_group_set_foreign(); 374 } 375 ; 376 377 portal_group_listen: LISTEN STR 378 { 379 bool ok; 380 381 ok = portal_group_add_listen($2, false); 382 free($2); 383 if (!ok) 384 return (1); 385 } 386 ; 387 388 portal_group_listen_iser: LISTEN_ISER STR 389 { 390 bool ok; 391 392 ok = portal_group_add_listen($2, true); 393 free($2); 394 if (!ok) 395 return (1); 396 } 397 ; 398 399 portal_group_offload: OFFLOAD STR 400 { 401 bool ok; 402 403 ok = portal_group_set_offload($2); 404 free($2); 405 if (!ok) 406 return (1); 407 } 408 ; 409 410 portal_group_option: OPTION STR STR 411 { 412 bool ok; 413 414 ok = portal_group_add_option($2, $3); 415 free($2); 416 free($3); 417 if (!ok) 418 return (1); 419 } 420 ; 421 422 portal_group_redirect: REDIRECT STR 423 { 424 bool ok; 425 426 ok = portal_group_set_redirection($2); 427 free($2); 428 if (!ok) 429 return (1); 430 } 431 ; 432 433 portal_group_tag: TAG STR 434 { 435 uint64_t tmp; 436 437 if (expand_number($2, &tmp) != 0) { 438 yyerror("invalid numeric value"); 439 free($2); 440 return (1); 441 } 442 free($2); 443 444 portal_group_set_tag(tmp); 445 } 446 ; 447 448 portal_group_dscp 449 : DSCP STR 450 { 451 uint64_t tmp; 452 453 if (strcmp($2, "0x") == 0) { 454 tmp = strtol($2 + 2, NULL, 16); 455 } else if (expand_number($2, &tmp) != 0) { 456 yyerror("invalid numeric value"); 457 free($2); 458 return (1); 459 } 460 free($2); 461 462 if (!portal_group_set_dscp(tmp)) 463 return (1); 464 } 465 | DSCP BE { portal_group_set_dscp(IPTOS_DSCP_CS0 >> 2); } 466 | DSCP EF { portal_group_set_dscp(IPTOS_DSCP_EF >> 2); } 467 | DSCP CS0 { portal_group_set_dscp(IPTOS_DSCP_CS0 >> 2); } 468 | DSCP CS1 { portal_group_set_dscp(IPTOS_DSCP_CS1 >> 2); } 469 | DSCP CS2 { portal_group_set_dscp(IPTOS_DSCP_CS2 >> 2); } 470 | DSCP CS3 { portal_group_set_dscp(IPTOS_DSCP_CS3 >> 2); } 471 | DSCP CS4 { portal_group_set_dscp(IPTOS_DSCP_CS4 >> 2); } 472 | DSCP CS5 { portal_group_set_dscp(IPTOS_DSCP_CS5 >> 2); } 473 | DSCP CS6 { portal_group_set_dscp(IPTOS_DSCP_CS6 >> 2); } 474 | DSCP CS7 { portal_group_set_dscp(IPTOS_DSCP_CS7 >> 2); } 475 | DSCP AF11 { portal_group_set_dscp(IPTOS_DSCP_AF11 >> 2); } 476 | DSCP AF12 { portal_group_set_dscp(IPTOS_DSCP_AF12 >> 2); } 477 | DSCP AF13 { portal_group_set_dscp(IPTOS_DSCP_AF13 >> 2); } 478 | DSCP AF21 { portal_group_set_dscp(IPTOS_DSCP_AF21 >> 2); } 479 | DSCP AF22 { portal_group_set_dscp(IPTOS_DSCP_AF22 >> 2); } 480 | DSCP AF23 { portal_group_set_dscp(IPTOS_DSCP_AF23 >> 2); } 481 | DSCP AF31 { portal_group_set_dscp(IPTOS_DSCP_AF31 >> 2); } 482 | DSCP AF32 { portal_group_set_dscp(IPTOS_DSCP_AF32 >> 2); } 483 | DSCP AF33 { portal_group_set_dscp(IPTOS_DSCP_AF33 >> 2); } 484 | DSCP AF41 { portal_group_set_dscp(IPTOS_DSCP_AF41 >> 2); } 485 | DSCP AF42 { portal_group_set_dscp(IPTOS_DSCP_AF42 >> 2); } 486 | DSCP AF43 { portal_group_set_dscp(IPTOS_DSCP_AF43 >> 2); } 487 ; 488 489 portal_group_pcp: PCP STR 490 { 491 uint64_t tmp; 492 493 if (expand_number($2, &tmp) != 0) { 494 yyerror("invalid numeric value"); 495 free($2); 496 return (1); 497 } 498 free($2); 499 500 if (!portal_group_set_pcp(tmp)) 501 return (1); 502 } 503 ; 504 505 lun: LUN lun_name 506 OPENING_BRACKET lun_entries CLOSING_BRACKET 507 { 508 lun_finish(); 509 } 510 ; 511 512 lun_name: STR 513 { 514 bool ok; 515 516 ok = lun_start($1); 517 free($1); 518 if (!ok) 519 return (1); 520 } 521 ; 522 523 target: TARGET target_name 524 OPENING_BRACKET target_entries CLOSING_BRACKET 525 { 526 target_finish(); 527 } 528 ; 529 530 target_name: STR 531 { 532 bool ok; 533 534 ok = target_start($1); 535 free($1); 536 if (!ok) 537 return (1); 538 } 539 ; 540 541 target_entries: 542 | 543 target_entries target_entry 544 | 545 target_entries target_entry SEMICOLON 546 ; 547 548 target_entry: 549 target_alias 550 | 551 target_auth_group 552 | 553 target_auth_type 554 | 555 target_chap 556 | 557 target_chap_mutual 558 | 559 target_initiator_name 560 | 561 target_initiator_portal 562 | 563 target_portal_group 564 | 565 target_port 566 | 567 target_redirect 568 | 569 target_lun 570 | 571 target_lun_ref 572 ; 573 574 target_alias: ALIAS STR 575 { 576 bool ok; 577 578 ok = target_set_alias($2); 579 free($2); 580 if (!ok) 581 return (1); 582 } 583 ; 584 585 target_auth_group: AUTH_GROUP STR 586 { 587 bool ok; 588 589 ok = target_set_auth_group($2); 590 free($2); 591 if (!ok) 592 return (1); 593 } 594 ; 595 596 target_auth_type: AUTH_TYPE STR 597 { 598 bool ok; 599 600 ok = target_set_auth_type($2); 601 free($2); 602 if (!ok) 603 return (1); 604 } 605 ; 606 607 target_chap: CHAP STR STR 608 { 609 bool ok; 610 611 ok = target_add_chap($2, $3); 612 free($2); 613 free($3); 614 if (!ok) 615 return (1); 616 } 617 ; 618 619 target_chap_mutual: CHAP_MUTUAL STR STR STR STR 620 { 621 bool ok; 622 623 ok = target_add_chap_mutual($2, $3, $4, $5); 624 free($2); 625 free($3); 626 free($4); 627 free($5); 628 if (!ok) 629 return (1); 630 } 631 ; 632 633 target_initiator_name: INITIATOR_NAME STR 634 { 635 bool ok; 636 637 ok = target_add_initiator_name($2); 638 free($2); 639 if (!ok) 640 return (1); 641 } 642 ; 643 644 target_initiator_portal: INITIATOR_PORTAL STR 645 { 646 bool ok; 647 648 ok = target_add_initiator_portal($2); 649 free($2); 650 if (!ok) 651 return (1); 652 } 653 ; 654 655 target_portal_group: PORTAL_GROUP STR STR 656 { 657 bool ok; 658 659 ok = target_add_portal_group($2, $3); 660 free($2); 661 free($3); 662 if (!ok) 663 return (1); 664 } 665 | PORTAL_GROUP STR 666 { 667 bool ok; 668 669 ok = target_add_portal_group($2, NULL); 670 free($2); 671 if (!ok) 672 return (1); 673 } 674 ; 675 676 target_port: PORT STR 677 { 678 bool ok; 679 680 ok = target_set_physical_port($2); 681 free($2); 682 if (!ok) 683 return (1); 684 } 685 ; 686 687 target_redirect: REDIRECT STR 688 { 689 bool ok; 690 691 ok = target_set_redirection($2); 692 free($2); 693 if (!ok) 694 return (1); 695 } 696 ; 697 698 target_lun: LUN lun_number 699 OPENING_BRACKET lun_entries CLOSING_BRACKET 700 { 701 lun_finish(); 702 } 703 ; 704 705 lun_number: STR 706 { 707 uint64_t tmp; 708 709 if (expand_number($1, &tmp) != 0) { 710 yyerror("invalid numeric value"); 711 free($1); 712 return (1); 713 } 714 free($1); 715 716 if (!target_start_lun(tmp)) 717 return (1); 718 } 719 ; 720 721 target_lun_ref: LUN STR STR 722 { 723 uint64_t tmp; 724 bool ok; 725 726 if (expand_number($2, &tmp) != 0) { 727 yyerror("invalid numeric value"); 728 free($2); 729 free($3); 730 return (1); 731 } 732 free($2); 733 734 ok = target_add_lun(tmp, $3); 735 free($3); 736 if (!ok) 737 return (1); 738 } 739 ; 740 741 lun_entries: 742 | 743 lun_entries lun_entry 744 | 745 lun_entries lun_entry SEMICOLON 746 ; 747 748 lun_entry: 749 lun_backend 750 | 751 lun_blocksize 752 | 753 lun_device_id 754 | 755 lun_device_type 756 | 757 lun_ctl_lun 758 | 759 lun_option 760 | 761 lun_path 762 | 763 lun_serial 764 | 765 lun_size 766 ; 767 768 lun_backend: BACKEND STR 769 { 770 bool ok; 771 772 ok = lun_set_backend($2); 773 free($2); 774 if (!ok) 775 return (1); 776 } 777 ; 778 779 lun_blocksize: BLOCKSIZE STR 780 { 781 uint64_t tmp; 782 783 if (expand_number($2, &tmp) != 0) { 784 yyerror("invalid numeric value"); 785 free($2); 786 return (1); 787 } 788 free($2); 789 790 if (!lun_set_blocksize(tmp)) 791 return (1); 792 } 793 ; 794 795 lun_device_id: DEVICE_ID STR 796 { 797 bool ok; 798 799 ok = lun_set_device_id($2); 800 free($2); 801 if (!ok) 802 return (1); 803 } 804 ; 805 806 lun_device_type: DEVICE_TYPE STR 807 { 808 bool ok; 809 810 ok = lun_set_device_type($2); 811 free($2); 812 if (!ok) 813 return (1); 814 } 815 ; 816 817 lun_ctl_lun: CTL_LUN STR 818 { 819 uint64_t tmp; 820 821 if (expand_number($2, &tmp) != 0) { 822 yyerror("invalid numeric value"); 823 free($2); 824 return (1); 825 } 826 free($2); 827 828 if (!lun_set_ctl_lun(tmp)) 829 return (1); 830 } 831 ; 832 833 lun_option: OPTION STR STR 834 { 835 bool ok; 836 837 ok = lun_add_option($2, $3); 838 free($2); 839 free($3); 840 if (!ok) 841 return (1); 842 } 843 ; 844 845 lun_path: PATH STR 846 { 847 bool ok; 848 849 ok = lun_set_path($2); 850 free($2); 851 if (!ok) 852 return (1); 853 } 854 ; 855 856 lun_serial: SERIAL STR 857 { 858 bool ok; 859 860 ok = lun_set_serial($2); 861 free($2); 862 if (!ok) 863 return (1); 864 } 865 ; 866 867 lun_size: SIZE STR 868 { 869 uint64_t tmp; 870 871 if (expand_number($2, &tmp) != 0) { 872 yyerror("invalid numeric value"); 873 free($2); 874 return (1); 875 } 876 free($2); 877 878 if (!lun_set_size(tmp)) 879 return (1); 880 } 881 ; 882 %% 883 884 void 885 yyerror(const char *str) 886 { 887 888 log_warnx("error in configuration file at line %d near '%s': %s", 889 lineno, yytext, str); 890 } 891 892 bool 893 parse_conf(const char *path) 894 { 895 int error; 896 897 yyin = fopen(path, "r"); 898 if (yyin == NULL) { 899 log_warn("unable to open configuration file %s", path); 900 return (false); 901 } 902 903 lineno = 1; 904 yyrestart(yyin); 905 error = yyparse(); 906 fclose(yyin); 907 908 return (error == 0); 909 } 910