3 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
5 * Copyright (c) 2012 The FreeBSD Foundation
8 * This software was developed by Edward Tomasz Napierala under sponsorship
9 * from the FreeBSD Foundation.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 #include <sys/queue.h>
36 #include <sys/types.h>
49 static struct conf *conf = NULL;
50 static struct auth_group *auth_group = NULL;
51 static struct portal_group *portal_group = NULL;
52 static struct target *target = NULL;
53 static struct lun *lun = NULL;
55 extern void yyerror(const char *);
56 extern int yylex(void);
57 extern void yyrestart(FILE *);
61 %token ALIAS AUTH_GROUP AUTH_TYPE BACKEND BLOCKSIZE CHAP CHAP_MUTUAL
62 %token CLOSING_BRACKET CTL_LUN DEBUG DEVICE_ID DEVICE_TYPE
63 %token DISCOVERY_AUTH_GROUP DISCOVERY_FILTER FOREIGN
64 %token INITIATOR_NAME INITIATOR_PORTAL ISNS_SERVER ISNS_PERIOD ISNS_TIMEOUT
65 %token LISTEN LISTEN_ISER LUN MAXPROC OFFLOAD OPENING_BRACKET OPTION
66 %token PATH PIDFILE PORT PORTAL_GROUP REDIRECT SEMICOLON SERIAL SIZE STR
67 %token TAG TARGET TIMEOUT
82 statements statement SEMICOLON
113 if (expand_number($2, &tmp) != 0) {
114 yyerror("invalid numeric value");
119 conf->conf_debug = tmp;
127 if (expand_number($2, &tmp) != 0) {
128 yyerror("invalid numeric value");
133 conf->conf_timeout = tmp;
141 if (expand_number($2, &tmp) != 0) {
142 yyerror("invalid numeric value");
147 conf->conf_maxproc = tmp;
153 if (conf->conf_pidfile_path != NULL) {
154 log_warnx("pidfile specified more than once");
158 conf->conf_pidfile_path = $2;
162 isns_server: ISNS_SERVER STR
166 error = isns_new(conf, $2);
173 isns_period: ISNS_PERIOD STR
177 if (expand_number($2, &tmp) != 0) {
178 yyerror("invalid numeric value");
183 conf->conf_isns_period = tmp;
187 isns_timeout: ISNS_TIMEOUT STR
191 if (expand_number($2, &tmp) != 0) {
192 yyerror("invalid numeric value");
197 conf->conf_isns_timeout = tmp;
201 auth_group: AUTH_GROUP auth_group_name
202 OPENING_BRACKET auth_group_entries CLOSING_BRACKET
211 * Make it possible to redefine default
212 * auth-group. but only once.
214 if (strcmp($1, "default") == 0 &&
215 conf->conf_default_ag_defined == false) {
216 auth_group = auth_group_find(conf, $1);
217 conf->conf_default_ag_defined = true;
219 auth_group = auth_group_new(conf, $1);
222 if (auth_group == NULL)
229 auth_group_entries auth_group_entry
231 auth_group_entries auth_group_entry SEMICOLON
239 auth_group_chap_mutual
241 auth_group_initiator_name
243 auth_group_initiator_portal
246 auth_group_auth_type: AUTH_TYPE STR
250 error = auth_group_set_type(auth_group, $2);
257 auth_group_chap: CHAP STR STR
259 const struct auth *ca;
261 ca = auth_new_chap(auth_group, $2, $3);
269 auth_group_chap_mutual: CHAP_MUTUAL STR STR STR STR
271 const struct auth *ca;
273 ca = auth_new_chap_mutual(auth_group, $2, $3, $4, $5);
283 auth_group_initiator_name: INITIATOR_NAME STR
285 const struct auth_name *an;
287 an = auth_name_new(auth_group, $2);
294 auth_group_initiator_portal: INITIATOR_PORTAL STR
296 const struct auth_portal *ap;
298 ap = auth_portal_new(auth_group, $2);
305 portal_group: PORTAL_GROUP portal_group_name
306 OPENING_BRACKET portal_group_entries CLOSING_BRACKET
312 portal_group_name: STR
315 * Make it possible to redefine default
316 * portal-group. but only once.
318 if (strcmp($1, "default") == 0 &&
319 conf->conf_default_pg_defined == false) {
320 portal_group = portal_group_find(conf, $1);
321 conf->conf_default_pg_defined = true;
323 portal_group = portal_group_new(conf, $1);
326 if (portal_group == NULL)
331 portal_group_entries:
333 portal_group_entries portal_group_entry
335 portal_group_entries portal_group_entry SEMICOLON
339 portal_group_discovery_auth_group
341 portal_group_discovery_filter
347 portal_group_listen_iser
353 portal_group_redirect
358 portal_group_discovery_auth_group: DISCOVERY_AUTH_GROUP STR
360 if (portal_group->pg_discovery_auth_group != NULL) {
361 log_warnx("discovery-auth-group for portal-group "
362 "\"%s\" specified more than once",
363 portal_group->pg_name);
366 portal_group->pg_discovery_auth_group =
367 auth_group_find(conf, $2);
368 if (portal_group->pg_discovery_auth_group == NULL) {
369 log_warnx("unknown discovery-auth-group \"%s\" "
370 "for portal-group \"%s\"",
371 $2, portal_group->pg_name);
378 portal_group_discovery_filter: DISCOVERY_FILTER STR
382 error = portal_group_set_filter(portal_group, $2);
389 portal_group_foreign: FOREIGN
392 portal_group->pg_foreign = 1;
396 portal_group_listen: LISTEN STR
400 error = portal_group_add_listen(portal_group, $2, false);
407 portal_group_listen_iser: LISTEN_ISER STR
411 error = portal_group_add_listen(portal_group, $2, true);
418 portal_group_offload: OFFLOAD STR
422 error = portal_group_set_offload(portal_group, $2);
429 portal_group_option: OPTION STR STR
433 o = option_new(&portal_group->pg_options, $2, $3);
441 portal_group_redirect: REDIRECT STR
445 error = portal_group_set_redirection(portal_group, $2);
452 portal_group_tag: TAG STR
456 if (expand_number($2, &tmp) != 0) {
457 yyerror("invalid numeric value");
462 portal_group->pg_tag = tmp;
467 OPENING_BRACKET lun_entries CLOSING_BRACKET
475 lun = lun_new(conf, $1);
482 target: TARGET target_name
483 OPENING_BRACKET target_entries CLOSING_BRACKET
491 target = target_new(conf, $1);
500 target_entries target_entry
502 target_entries target_entry SEMICOLON
516 target_initiator_name
518 target_initiator_portal
531 target_alias: ALIAS STR
533 if (target->t_alias != NULL) {
534 log_warnx("alias for target \"%s\" "
535 "specified more than once", target->t_name);
538 target->t_alias = $2;
542 target_auth_group: AUTH_GROUP STR
544 if (target->t_auth_group != NULL) {
545 if (target->t_auth_group->ag_name != NULL)
546 log_warnx("auth-group for target \"%s\" "
547 "specified more than once", target->t_name);
549 log_warnx("cannot use both auth-group and explicit "
550 "authorisations for target \"%s\"",
554 target->t_auth_group = auth_group_find(conf, $2);
555 if (target->t_auth_group == NULL) {
556 log_warnx("unknown auth-group \"%s\" for target "
557 "\"%s\"", $2, target->t_name);
564 target_auth_type: AUTH_TYPE STR
568 if (target->t_auth_group != NULL) {
569 if (target->t_auth_group->ag_name != NULL) {
570 log_warnx("cannot use both auth-group and "
571 "auth-type for target \"%s\"",
576 target->t_auth_group = auth_group_new(conf, NULL);
577 if (target->t_auth_group == NULL) {
581 target->t_auth_group->ag_target = target;
583 error = auth_group_set_type(target->t_auth_group, $2);
590 target_chap: CHAP STR STR
592 const struct auth *ca;
594 if (target->t_auth_group != NULL) {
595 if (target->t_auth_group->ag_name != NULL) {
596 log_warnx("cannot use both auth-group and "
597 "chap for target \"%s\"",
604 target->t_auth_group = auth_group_new(conf, NULL);
605 if (target->t_auth_group == NULL) {
610 target->t_auth_group->ag_target = target;
612 ca = auth_new_chap(target->t_auth_group, $2, $3);
620 target_chap_mutual: CHAP_MUTUAL STR STR STR STR
622 const struct auth *ca;
624 if (target->t_auth_group != NULL) {
625 if (target->t_auth_group->ag_name != NULL) {
626 log_warnx("cannot use both auth-group and "
627 "chap-mutual for target \"%s\"",
636 target->t_auth_group = auth_group_new(conf, NULL);
637 if (target->t_auth_group == NULL) {
644 target->t_auth_group->ag_target = target;
646 ca = auth_new_chap_mutual(target->t_auth_group,
657 target_initiator_name: INITIATOR_NAME STR
659 const struct auth_name *an;
661 if (target->t_auth_group != NULL) {
662 if (target->t_auth_group->ag_name != NULL) {
663 log_warnx("cannot use both auth-group and "
664 "initiator-name for target \"%s\"",
670 target->t_auth_group = auth_group_new(conf, NULL);
671 if (target->t_auth_group == NULL) {
675 target->t_auth_group->ag_target = target;
677 an = auth_name_new(target->t_auth_group, $2);
684 target_initiator_portal: INITIATOR_PORTAL STR
686 const struct auth_portal *ap;
688 if (target->t_auth_group != NULL) {
689 if (target->t_auth_group->ag_name != NULL) {
690 log_warnx("cannot use both auth-group and "
691 "initiator-portal for target \"%s\"",
697 target->t_auth_group = auth_group_new(conf, NULL);
698 if (target->t_auth_group == NULL) {
702 target->t_auth_group->ag_target = target;
704 ap = auth_portal_new(target->t_auth_group, $2);
711 target_portal_group: PORTAL_GROUP STR STR
713 struct portal_group *tpg;
714 struct auth_group *tag;
717 tpg = portal_group_find(conf, $2);
719 log_warnx("unknown portal-group \"%s\" for target "
720 "\"%s\"", $2, target->t_name);
725 tag = auth_group_find(conf, $3);
727 log_warnx("unknown auth-group \"%s\" for target "
728 "\"%s\"", $3, target->t_name);
733 tp = port_new(conf, target, tpg);
735 log_warnx("can't link portal-group \"%s\" to target "
736 "\"%s\"", $2, target->t_name);
740 tp->p_auth_group = tag;
746 struct portal_group *tpg;
749 tpg = portal_group_find(conf, $2);
751 log_warnx("unknown portal-group \"%s\" for target "
752 "\"%s\"", $2, target->t_name);
756 tp = port_new(conf, target, tpg);
758 log_warnx("can't link portal-group \"%s\" to target "
759 "\"%s\"", $2, target->t_name);
767 target_port: PORT STR
771 int ret, i_pp, i_vp = 0;
773 ret = sscanf($2, "ioctl/%d/%d", &i_pp, &i_vp);
775 tp = port_new_ioctl(conf, target, i_pp, i_vp);
777 log_warnx("can't create new ioctl port for "
778 "target \"%s\"", target->t_name);
783 pp = pport_find(conf, $2);
785 log_warnx("unknown port \"%s\" for target \"%s\"",
790 if (!TAILQ_EMPTY(&pp->pp_ports)) {
791 log_warnx("can't link port \"%s\" to target \"%s\", "
792 "port already linked to some target",
797 tp = port_new_pp(conf, target, pp);
799 log_warnx("can't link port \"%s\" to target \"%s\"",
810 target_redirect: REDIRECT STR
814 error = target_set_redirection(target, $2);
821 target_lun: LUN lun_number
822 OPENING_BRACKET lun_entries CLOSING_BRACKET
834 if (expand_number($1, &tmp) != 0) {
835 yyerror("invalid numeric value");
839 if (tmp >= MAX_LUNS) {
840 yyerror("LU number is too big");
845 ret = asprintf(&name, "%s,lun,%ju", target->t_name, tmp);
847 log_err(1, "asprintf");
848 lun = lun_new(conf, name);
852 lun_set_scsiname(lun, name);
853 target->t_luns[tmp] = lun;
857 target_lun_ref: LUN STR STR
861 if (expand_number($2, &tmp) != 0) {
862 yyerror("invalid numeric value");
868 if (tmp >= MAX_LUNS) {
869 yyerror("LU number is too big");
874 lun = lun_find(conf, $3);
879 target->t_luns[tmp] = lun;
885 lun_entries lun_entry
887 lun_entries lun_entry SEMICOLON
910 lun_backend: BACKEND STR
912 if (lun->l_backend != NULL) {
913 log_warnx("backend for lun \"%s\" "
914 "specified more than once",
919 lun_set_backend(lun, $2);
924 lun_blocksize: BLOCKSIZE STR
928 if (expand_number($2, &tmp) != 0) {
929 yyerror("invalid numeric value");
934 if (lun->l_blocksize != 0) {
935 log_warnx("blocksize for lun \"%s\" "
936 "specified more than once",
940 lun_set_blocksize(lun, tmp);
944 lun_device_id: DEVICE_ID STR
946 if (lun->l_device_id != NULL) {
947 log_warnx("device_id for lun \"%s\" "
948 "specified more than once",
953 lun_set_device_id(lun, $2);
958 lun_device_type: DEVICE_TYPE STR
962 if (strcasecmp($2, "disk") == 0 ||
963 strcasecmp($2, "direct") == 0)
965 else if (strcasecmp($2, "processor") == 0)
967 else if (strcasecmp($2, "cd") == 0 ||
968 strcasecmp($2, "cdrom") == 0 ||
969 strcasecmp($2, "dvd") == 0 ||
970 strcasecmp($2, "dvdrom") == 0)
972 else if (expand_number($2, &tmp) != 0 ||
974 yyerror("invalid numeric value");
979 lun_set_device_type(lun, tmp);
983 lun_ctl_lun: CTL_LUN STR
987 if (expand_number($2, &tmp) != 0) {
988 yyerror("invalid numeric value");
993 if (lun->l_ctl_lun >= 0) {
994 log_warnx("ctl_lun for lun \"%s\" "
995 "specified more than once",
999 lun_set_ctl_lun(lun, tmp);
1003 lun_option: OPTION STR STR
1007 o = option_new(&lun->l_options, $2, $3);
1017 if (lun->l_path != NULL) {
1018 log_warnx("path for lun \"%s\" "
1019 "specified more than once",
1024 lun_set_path(lun, $2);
1029 lun_serial: SERIAL STR
1031 if (lun->l_serial != NULL) {
1032 log_warnx("serial for lun \"%s\" "
1033 "specified more than once",
1038 lun_set_serial(lun, $2);
1047 if (expand_number($2, &tmp) != 0) {
1048 yyerror("invalid numeric value");
1053 if (lun->l_size != 0) {
1054 log_warnx("size for lun \"%s\" "
1055 "specified more than once",
1059 lun_set_size(lun, tmp);
1065 yyerror(const char *str)
1068 log_warnx("error in configuration file at line %d near '%s': %s",
1069 lineno, yytext, str);
1073 parse_conf(struct conf *newconf, const char *path)
1078 yyin = fopen(path, "r");
1080 log_warn("unable to open configuration file %s", path);
1088 portal_group = NULL;