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 CONTROLLER CTL_LUN DEBUG DEVICE_ID DEVICE_TYPE
58 %token DISCOVERY_AUTH_GROUP DISCOVERY_FILTER DISCOVERY_TCP DSCP FOREIGN
59 %token HOST_ADDRESS HOST_NQN
60 %token INITIATOR_NAME INITIATOR_PORTAL ISNS_SERVER ISNS_PERIOD ISNS_TIMEOUT
61 %token LISTEN LISTEN_ISER LUN MAXPROC NAMESPACE
62 %token OFFLOAD OPENING_BRACKET OPTION
63 %token PATH PCP PIDFILE PORT PORTAL_GROUP REDIRECT SEMICOLON SERIAL
64 %token SIZE STR TAG TARGET TCP TIMEOUT TRANSPORT_GROUP
65 %token AF11 AF12 AF13 AF21 AF22 AF23 AF31 AF32 AF33 AF41 AF42 AF43
66 %token BE EF CS0 CS1 CS2 CS3 CS4 CS5 CS6 CS7
67
68 %union
69 {
70 char *str;
71 }
72
73 %token <str> STR
74
75 %%
76
77 statements:
78 |
79 statements statement
80 |
81 statements statement SEMICOLON
82 ;
83
84 statement:
85 debug
86 |
87 timeout
88 |
89 maxproc
90 |
91 pidfile
92 |
93 isns_server
94 |
95 isns_period
96 |
97 isns_timeout
98 |
99 auth_group
100 |
101 portal_group
102 |
103 transport_group
104 |
105 lun
106 |
107 target
108 |
109 controller
110 ;
111
112 debug: DEBUG STR
113 {
114 int64_t tmp;
115
116 if (expand_number($2, &tmp) != 0) {
117 yyerror("invalid numeric value");
118 free($2);
119 return (1);
120 }
121 free($2);
122
123 conf_set_debug(tmp);
124 }
125 ;
126
127 timeout: TIMEOUT STR
128 {
129 int64_t tmp;
130
131 if (expand_number($2, &tmp) != 0) {
132 yyerror("invalid numeric value");
133 free($2);
134 return (1);
135 }
136 free($2);
137
138 conf_set_timeout(tmp);
139 }
140 ;
141
142 maxproc: MAXPROC STR
143 {
144 int64_t tmp;
145
146 if (expand_number($2, &tmp) != 0) {
147 yyerror("invalid numeric value");
148 free($2);
149 return (1);
150 }
151 free($2);
152
153 conf_set_maxproc(tmp);
154 }
155 ;
156
157 pidfile: PIDFILE STR
158 {
159 bool ok;
160
161 ok = conf_set_pidfile_path($2);
162 free($2);
163 if (!ok)
164 return (1);
165 }
166 ;
167
168 isns_server: ISNS_SERVER STR
169 {
170 bool ok;
171
172 ok = isns_add_server($2);
173 free($2);
174 if (!ok)
175 return (1);
176 }
177 ;
178
179 isns_period: ISNS_PERIOD STR
180 {
181 int64_t tmp;
182
183 if (expand_number($2, &tmp) != 0) {
184 yyerror("invalid numeric value");
185 free($2);
186 return (1);
187 }
188 free($2);
189
190 conf_set_isns_period(tmp);
191 }
192 ;
193
194 isns_timeout: ISNS_TIMEOUT STR
195 {
196 int64_t tmp;
197
198 if (expand_number($2, &tmp) != 0) {
199 yyerror("invalid numeric value");
200 free($2);
201 return (1);
202 }
203 free($2);
204
205 conf_set_isns_timeout(tmp);
206 }
207 ;
208
209 auth_group: AUTH_GROUP auth_group_name
210 OPENING_BRACKET auth_group_entries CLOSING_BRACKET
211 {
212 auth_group_finish();
213 }
214 ;
215
216 auth_group_name: STR
217 {
218 bool ok;
219
220 ok = auth_group_start($1);
221 free($1);
222 if (!ok)
223 return (1);
224 }
225 ;
226
227 auth_group_entries:
228 |
229 auth_group_entries auth_group_entry
230 |
231 auth_group_entries auth_group_entry SEMICOLON
232 ;
233
234 auth_group_entry:
235 auth_group_auth_type
236 |
237 auth_group_chap
238 |
239 auth_group_chap_mutual
240 |
241 auth_group_host_address
242 |
243 auth_group_host_nqn
244 |
245 auth_group_initiator_name
246 |
247 auth_group_initiator_portal
248 ;
249
250 auth_group_auth_type: AUTH_TYPE STR
251 {
252 bool ok;
253
254 ok = auth_group_set_type($2);
255 free($2);
256 if (!ok)
257 return (1);
258 }
259 ;
260
261 auth_group_chap: CHAP STR STR
262 {
263 bool ok;
264
265 ok = auth_group_add_chap($2, $3);
266 free($2);
267 free($3);
268 if (!ok)
269 return (1);
270 }
271 ;
272
273 auth_group_chap_mutual: CHAP_MUTUAL STR STR STR STR
274 {
275 bool ok;
276
277 ok = auth_group_add_chap_mutual($2, $3, $4, $5);
278 free($2);
279 free($3);
280 free($4);
281 free($5);
282 if (!ok)
283 return (1);
284 }
285 ;
286
287 auth_group_host_address: HOST_ADDRESS STR
288 {
289 bool ok;
290
291 ok = auth_group_add_host_address($2);
292 free($2);
293 if (!ok)
294 return (1);
295 }
296 ;
297
298 auth_group_host_nqn: HOST_NQN STR
299 {
300 bool ok;
301
302 ok = auth_group_add_host_nqn($2);
303 free($2);
304 if (!ok)
305 return (1);
306 }
307 ;
308
309 auth_group_initiator_name: INITIATOR_NAME STR
310 {
311 bool ok;
312
313 ok = auth_group_add_initiator_name($2);
314 free($2);
315 if (!ok)
316 return (1);
317 }
318 ;
319
320 auth_group_initiator_portal: INITIATOR_PORTAL STR
321 {
322 bool ok;
323
324 ok = auth_group_add_initiator_portal($2);
325 free($2);
326 if (!ok)
327 return (1);
328 }
329 ;
330
331 portal_group: PORTAL_GROUP portal_group_name
332 OPENING_BRACKET portal_group_entries CLOSING_BRACKET
333 {
334 portal_group_finish();
335 }
336 ;
337
338 portal_group_name: STR
339 {
340 bool ok;
341
342 ok = portal_group_start($1);
343 free($1);
344 if (!ok)
345 return (1);
346 }
347 ;
348
349 portal_group_entries:
350 |
351 portal_group_entries portal_group_entry
352 |
353 portal_group_entries portal_group_entry SEMICOLON
354 ;
355
356 portal_group_entry:
357 portal_group_discovery_auth_group
358 |
359 portal_group_discovery_filter
360 |
361 portal_group_foreign
362 |
363 portal_group_listen
364 |
365 portal_group_listen_iser
366 |
367 portal_group_offload
368 |
369 portal_group_option
370 |
371 portal_group_redirect
372 |
373 portal_group_tag
374 |
375 portal_group_dscp
376 |
377 portal_group_pcp
378 ;
379
380 portal_group_discovery_auth_group: DISCOVERY_AUTH_GROUP STR
381 {
382 bool ok;
383
384 ok = portal_group_set_discovery_auth_group($2);
385 free($2);
386 if (!ok)
387 return (1);
388 }
389 ;
390
391 portal_group_discovery_filter: DISCOVERY_FILTER STR
392 {
393 bool ok;
394
395 ok = portal_group_set_filter($2);
396 free($2);
397 if (!ok)
398 return (1);
399 }
400 ;
401
402 portal_group_foreign: FOREIGN
403 {
404
405 portal_group_set_foreign();
406 }
407 ;
408
409 portal_group_listen: LISTEN STR
410 {
411 bool ok;
412
413 ok = portal_group_add_listen($2, false);
414 free($2);
415 if (!ok)
416 return (1);
417 }
418 ;
419
420 portal_group_listen_iser: LISTEN_ISER STR
421 {
422 bool ok;
423
424 ok = portal_group_add_listen($2, true);
425 free($2);
426 if (!ok)
427 return (1);
428 }
429 ;
430
431 portal_group_offload: OFFLOAD STR
432 {
433 bool ok;
434
435 ok = portal_group_set_offload($2);
436 free($2);
437 if (!ok)
438 return (1);
439 }
440 ;
441
442 portal_group_option: OPTION STR STR
443 {
444 bool ok;
445
446 ok = portal_group_add_option($2, $3);
447 free($2);
448 free($3);
449 if (!ok)
450 return (1);
451 }
452 ;
453
454 portal_group_redirect: REDIRECT STR
455 {
456 bool ok;
457
458 ok = portal_group_set_redirection($2);
459 free($2);
460 if (!ok)
461 return (1);
462 }
463 ;
464
465 portal_group_tag: TAG STR
466 {
467 int64_t tmp;
468
469 if (expand_number($2, &tmp) != 0) {
470 yyerror("invalid numeric value");
471 free($2);
472 return (1);
473 }
474 free($2);
475
476 portal_group_set_tag(tmp);
477 }
478 ;
479
480 portal_group_dscp
481 : DSCP STR
482 {
483 int64_t tmp;
484
485 if (strcmp($2, "0x") == 0) {
486 tmp = strtol($2 + 2, NULL, 16);
487 } else if (expand_number($2, &tmp) != 0) {
488 yyerror("invalid numeric value");
489 free($2);
490 return (1);
491 }
492 free($2);
493
494 if (!portal_group_set_dscp(tmp))
495 return (1);
496 }
497 | DSCP BE { portal_group_set_dscp(IPTOS_DSCP_CS0 >> 2); }
498 | DSCP EF { portal_group_set_dscp(IPTOS_DSCP_EF >> 2); }
499 | DSCP CS0 { portal_group_set_dscp(IPTOS_DSCP_CS0 >> 2); }
500 | DSCP CS1 { portal_group_set_dscp(IPTOS_DSCP_CS1 >> 2); }
501 | DSCP CS2 { portal_group_set_dscp(IPTOS_DSCP_CS2 >> 2); }
502 | DSCP CS3 { portal_group_set_dscp(IPTOS_DSCP_CS3 >> 2); }
503 | DSCP CS4 { portal_group_set_dscp(IPTOS_DSCP_CS4 >> 2); }
504 | DSCP CS5 { portal_group_set_dscp(IPTOS_DSCP_CS5 >> 2); }
505 | DSCP CS6 { portal_group_set_dscp(IPTOS_DSCP_CS6 >> 2); }
506 | DSCP CS7 { portal_group_set_dscp(IPTOS_DSCP_CS7 >> 2); }
507 | DSCP AF11 { portal_group_set_dscp(IPTOS_DSCP_AF11 >> 2); }
508 | DSCP AF12 { portal_group_set_dscp(IPTOS_DSCP_AF12 >> 2); }
509 | DSCP AF13 { portal_group_set_dscp(IPTOS_DSCP_AF13 >> 2); }
510 | DSCP AF21 { portal_group_set_dscp(IPTOS_DSCP_AF21 >> 2); }
511 | DSCP AF22 { portal_group_set_dscp(IPTOS_DSCP_AF22 >> 2); }
512 | DSCP AF23 { portal_group_set_dscp(IPTOS_DSCP_AF23 >> 2); }
513 | DSCP AF31 { portal_group_set_dscp(IPTOS_DSCP_AF31 >> 2); }
514 | DSCP AF32 { portal_group_set_dscp(IPTOS_DSCP_AF32 >> 2); }
515 | DSCP AF33 { portal_group_set_dscp(IPTOS_DSCP_AF33 >> 2); }
516 | DSCP AF41 { portal_group_set_dscp(IPTOS_DSCP_AF41 >> 2); }
517 | DSCP AF42 { portal_group_set_dscp(IPTOS_DSCP_AF42 >> 2); }
518 | DSCP AF43 { portal_group_set_dscp(IPTOS_DSCP_AF43 >> 2); }
519 ;
520
521 portal_group_pcp: PCP STR
522 {
523 int64_t tmp;
524
525 if (expand_number($2, &tmp) != 0) {
526 yyerror("invalid numeric value");
527 free($2);
528 return (1);
529 }
530 free($2);
531
532 if (!portal_group_set_pcp(tmp))
533 return (1);
534 }
535 ;
536
537 transport_group: TRANSPORT_GROUP transport_group_name
538 OPENING_BRACKET transport_group_entries CLOSING_BRACKET
539 {
540 portal_group_finish();
541 }
542 ;
543
544 transport_group_name: STR
545 {
546 bool ok;
547
548 ok = transport_group_start($1);
549 free($1);
550 if (!ok)
551 return (1);
552 }
553 ;
554
555 transport_group_entries:
556 |
557 transport_group_entries transport_group_entry
558 |
559 transport_group_entries transport_group_entry SEMICOLON
560 ;
561
562 transport_group_entry:
563 portal_group_discovery_auth_group
564 |
565 portal_group_discovery_filter
566 |
567 transport_group_listen_discovery_tcp
568 |
569 transport_group_listen_tcp
570 |
571 portal_group_option
572 |
573 portal_group_tag
574 |
575 portal_group_dscp
576 |
577 portal_group_pcp
578 ;
579
580 transport_group_listen_discovery_tcp: LISTEN DISCOVERY_TCP STR
581 {
582 bool ok;
583
584 ok = transport_group_add_listen_discovery_tcp($3);
585 free($3);
586 if (!ok)
587 return (1);
588 }
589 ;
590
591 transport_group_listen_tcp: LISTEN TCP STR
592 {
593 bool ok;
594
595 ok = transport_group_add_listen_tcp($3);
596 free($3);
597 if (!ok)
598 return (1);
599 }
600 ;
601
602 lun: LUN lun_name
603 OPENING_BRACKET lun_entries CLOSING_BRACKET
604 {
605 lun_finish();
606 }
607 ;
608
609 lun_name: STR
610 {
611 bool ok;
612
613 ok = lun_start($1);
614 free($1);
615 if (!ok)
616 return (1);
617 }
618 ;
619
620 target: TARGET target_name
621 OPENING_BRACKET target_entries CLOSING_BRACKET
622 {
623 target_finish();
624 }
625 ;
626
627 target_name: STR
628 {
629 bool ok;
630
631 ok = target_start($1);
632 free($1);
633 if (!ok)
634 return (1);
635 }
636 ;
637
638 target_entries:
639 |
640 target_entries target_entry
641 |
642 target_entries target_entry SEMICOLON
643 ;
644
645 target_entry:
646 target_alias
647 |
648 target_auth_group
649 |
650 target_auth_type
651 |
652 target_chap
653 |
654 target_chap_mutual
655 |
656 target_initiator_name
657 |
658 target_initiator_portal
659 |
660 target_portal_group
661 |
662 target_port
663 |
664 target_redirect
665 |
666 target_lun
667 |
668 target_lun_ref
669 ;
670
671 target_alias: ALIAS STR
672 {
673 bool ok;
674
675 ok = target_set_alias($2);
676 free($2);
677 if (!ok)
678 return (1);
679 }
680 ;
681
682 target_auth_group: AUTH_GROUP STR
683 {
684 bool ok;
685
686 ok = target_set_auth_group($2);
687 free($2);
688 if (!ok)
689 return (1);
690 }
691 ;
692
693 target_auth_type: AUTH_TYPE STR
694 {
695 bool ok;
696
697 ok = target_set_auth_type($2);
698 free($2);
699 if (!ok)
700 return (1);
701 }
702 ;
703
704 target_chap: CHAP STR STR
705 {
706 bool ok;
707
708 ok = target_add_chap($2, $3);
709 free($2);
710 free($3);
711 if (!ok)
712 return (1);
713 }
714 ;
715
716 target_chap_mutual: CHAP_MUTUAL STR STR STR STR
717 {
718 bool ok;
719
720 ok = target_add_chap_mutual($2, $3, $4, $5);
721 free($2);
722 free($3);
723 free($4);
724 free($5);
725 if (!ok)
726 return (1);
727 }
728 ;
729
730 target_initiator_name: INITIATOR_NAME STR
731 {
732 bool ok;
733
734 ok = target_add_initiator_name($2);
735 free($2);
736 if (!ok)
737 return (1);
738 }
739 ;
740
741 target_initiator_portal: INITIATOR_PORTAL STR
742 {
743 bool ok;
744
745 ok = target_add_initiator_portal($2);
746 free($2);
747 if (!ok)
748 return (1);
749 }
750 ;
751
752 target_portal_group: PORTAL_GROUP STR STR
753 {
754 bool ok;
755
756 ok = target_add_portal_group($2, $3);
757 free($2);
758 free($3);
759 if (!ok)
760 return (1);
761 }
762 | PORTAL_GROUP STR
763 {
764 bool ok;
765
766 ok = target_add_portal_group($2, NULL);
767 free($2);
768 if (!ok)
769 return (1);
770 }
771 ;
772
773 target_port: PORT STR
774 {
775 bool ok;
776
777 ok = target_set_physical_port($2);
778 free($2);
779 if (!ok)
780 return (1);
781 }
782 ;
783
784 target_redirect: REDIRECT STR
785 {
786 bool ok;
787
788 ok = target_set_redirection($2);
789 free($2);
790 if (!ok)
791 return (1);
792 }
793 ;
794
795 target_lun: LUN lun_number
796 OPENING_BRACKET lun_entries CLOSING_BRACKET
797 {
798 lun_finish();
799 }
800 ;
801
802 lun_number: STR
803 {
804 int64_t tmp;
805
806 if (expand_number($1, &tmp) != 0) {
807 yyerror("invalid numeric value");
808 free($1);
809 return (1);
810 }
811 free($1);
812
813 if (!target_start_lun(tmp))
814 return (1);
815 }
816 ;
817
818 target_lun_ref: LUN STR STR
819 {
820 int64_t tmp;
821 bool ok;
822
823 if (expand_number($2, &tmp) != 0) {
824 yyerror("invalid numeric value");
825 free($2);
826 free($3);
827 return (1);
828 }
829 free($2);
830
831 ok = target_add_lun(tmp, $3);
832 free($3);
833 if (!ok)
834 return (1);
835 }
836 ;
837
838 controller: CONTROLLER controller_name
839 OPENING_BRACKET controller_entries CLOSING_BRACKET
840 {
841 target_finish();
842 }
843 ;
844
845 controller_name: STR
846 {
847 bool ok;
848
849 ok = controller_start($1);
850 free($1);
851 if (!ok)
852 return (1);
853 }
854 ;
855
856 controller_entries:
857 |
858 controller_entries controller_entry
859 |
860 controller_entries controller_entry SEMICOLON
861 ;
862
863 controller_entry:
864 target_auth_group
865 |
866 target_auth_type
867 |
868 controller_host_address
869 |
870 controller_host_nqn
871 |
872 controller_transport_group
873 |
874 controller_namespace
875 |
876 controller_namespace_ref
877 ;
878
879 controller_host_address: HOST_ADDRESS STR
880 {
881 bool ok;
882
883 ok = controller_add_host_address($2);
884 free($2);
885 if (!ok)
886 return (1);
887 }
888 ;
889
890 controller_host_nqn: HOST_NQN STR
891 {
892 bool ok;
893
894 ok = controller_add_host_nqn($2);
895 free($2);
896 if (!ok)
897 return (1);
898 }
899 ;
900
901 controller_transport_group: TRANSPORT_GROUP STR STR
902 {
903 bool ok;
904
905 ok = target_add_portal_group($2, $3);
906 free($2);
907 free($3);
908 if (!ok)
909 return (1);
910 }
911 | TRANSPORT_GROUP STR
912 {
913 bool ok;
914
915 ok = target_add_portal_group($2, NULL);
916 free($2);
917 if (!ok)
918 return (1);
919 }
920 ;
921
922 controller_namespace: NAMESPACE ns_number
923 OPENING_BRACKET lun_entries CLOSING_BRACKET
924 {
925 lun_finish();
926 }
927 ;
928
929 ns_number: STR
930 {
931 uint64_t tmp;
932
933 if (expand_number($1, &tmp) != 0) {
934 yyerror("invalid numeric value");
935 free($1);
936 return (1);
937 }
938 free($1);
939
940 if (!controller_start_namespace(tmp))
941 return (1);
942 }
943 ;
944
945 controller_namespace_ref: NAMESPACE STR STR
946 {
947 uint64_t tmp;
948 bool ok;
949
950 if (expand_number($2, &tmp) != 0) {
951 yyerror("invalid numeric value");
952 free($2);
953 free($3);
954 return (1);
955 }
956 free($2);
957
958 ok = controller_add_namespace(tmp, $3);
959 free($3);
960 if (!ok)
961 return (1);
962 }
963 ;
964
965 lun_entries:
966 |
967 lun_entries lun_entry
968 |
969 lun_entries lun_entry SEMICOLON
970 ;
971
972 lun_entry:
973 lun_backend
974 |
975 lun_blocksize
976 |
977 lun_device_id
978 |
979 lun_device_type
980 |
981 lun_ctl_lun
982 |
983 lun_option
984 |
985 lun_path
986 |
987 lun_serial
988 |
989 lun_size
990 ;
991
992 lun_backend: BACKEND STR
993 {
994 bool ok;
995
996 ok = lun_set_backend($2);
997 free($2);
998 if (!ok)
999 return (1);
1000 }
1001 ;
1002
1003 lun_blocksize: BLOCKSIZE STR
1004 {
1005 int64_t tmp;
1006
1007 if (expand_number($2, &tmp) != 0) {
1008 yyerror("invalid numeric value");
1009 free($2);
1010 return (1);
1011 }
1012 free($2);
1013
1014 if (!lun_set_blocksize(tmp))
1015 return (1);
1016 }
1017 ;
1018
1019 lun_device_id: DEVICE_ID STR
1020 {
1021 bool ok;
1022
1023 ok = lun_set_device_id($2);
1024 free($2);
1025 if (!ok)
1026 return (1);
1027 }
1028 ;
1029
1030 lun_device_type: DEVICE_TYPE STR
1031 {
1032 bool ok;
1033
1034 ok = lun_set_device_type($2);
1035 free($2);
1036 if (!ok)
1037 return (1);
1038 }
1039 ;
1040
1041 lun_ctl_lun: CTL_LUN STR
1042 {
1043 int64_t tmp;
1044
1045 if (expand_number($2, &tmp) != 0) {
1046 yyerror("invalid numeric value");
1047 free($2);
1048 return (1);
1049 }
1050 free($2);
1051
1052 if (!lun_set_ctl_lun(tmp))
1053 return (1);
1054 }
1055 ;
1056
1057 lun_option: OPTION STR STR
1058 {
1059 bool ok;
1060
1061 ok = lun_add_option($2, $3);
1062 free($2);
1063 free($3);
1064 if (!ok)
1065 return (1);
1066 }
1067 ;
1068
1069 lun_path: PATH STR
1070 {
1071 bool ok;
1072
1073 ok = lun_set_path($2);
1074 free($2);
1075 if (!ok)
1076 return (1);
1077 }
1078 ;
1079
1080 lun_serial: SERIAL STR
1081 {
1082 bool ok;
1083
1084 ok = lun_set_serial($2);
1085 free($2);
1086 if (!ok)
1087 return (1);
1088 }
1089 ;
1090
1091 lun_size: SIZE STR
1092 {
1093 int64_t tmp;
1094
1095 if (expand_number($2, &tmp) != 0) {
1096 yyerror("invalid numeric value");
1097 free($2);
1098 return (1);
1099 }
1100 free($2);
1101
1102 if (!lun_set_size(tmp))
1103 return (1);
1104 }
1105 ;
1106 %%
1107
1108 void
1109 yyerror(const char *str)
1110 {
1111
1112 log_warnx("error in configuration file at line %d near '%s': %s",
1113 lineno, yytext, str);
1114 }
1115
1116 bool
yyparse_conf(FILE * fp)1117 yyparse_conf(FILE *fp)
1118 {
1119 int error;
1120
1121 yyin = fp;
1122 lineno = 1;
1123 yyrestart(yyin);
1124 error = yyparse();
1125
1126 return (error == 0);
1127 }
1128