%{ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2012 The FreeBSD Foundation * * This software was developed by Edward Tomasz Napierala under sponsorship * from the FreeBSD Foundation. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include #include #include #include #include "conf.h" extern FILE *yyin; extern char *yytext; extern int lineno; extern void yyerror(const char *); extern void yyrestart(FILE *); %} %token ALIAS AUTH_GROUP AUTH_TYPE BACKEND BLOCKSIZE CHAP CHAP_MUTUAL %token CLOSING_BRACKET CTL_LUN DEBUG DEVICE_ID DEVICE_TYPE %token DISCOVERY_AUTH_GROUP DISCOVERY_FILTER DSCP FOREIGN %token INITIATOR_NAME INITIATOR_PORTAL ISNS_SERVER ISNS_PERIOD ISNS_TIMEOUT %token LISTEN LISTEN_ISER LUN MAXPROC OFFLOAD OPENING_BRACKET OPTION %token PATH PCP PIDFILE PORT PORTAL_GROUP REDIRECT SEMICOLON SERIAL %token SIZE STR TAG TARGET TIMEOUT %token AF11 AF12 AF13 AF21 AF22 AF23 AF31 AF32 AF33 AF41 AF42 AF43 %token BE EF CS0 CS1 CS2 CS3 CS4 CS5 CS6 CS7 %union { char *str; } %token STR %% statements: | statements statement | statements statement SEMICOLON ; statement: debug | timeout | maxproc | pidfile | isns_server | isns_period | isns_timeout | auth_group | portal_group | lun | target ; debug: DEBUG STR { uint64_t tmp; if (expand_number($2, &tmp) != 0) { yyerror("invalid numeric value"); free($2); return (1); } free($2); conf_set_debug(tmp); } ; timeout: TIMEOUT STR { uint64_t tmp; if (expand_number($2, &tmp) != 0) { yyerror("invalid numeric value"); free($2); return (1); } free($2); conf_set_timeout(tmp); } ; maxproc: MAXPROC STR { uint64_t tmp; if (expand_number($2, &tmp) != 0) { yyerror("invalid numeric value"); free($2); return (1); } free($2); conf_set_maxproc(tmp); } ; pidfile: PIDFILE STR { bool ok; ok = conf_set_pidfile_path($2); free($2); if (!ok) return (1); } ; isns_server: ISNS_SERVER STR { bool ok; ok = isns_add_server($2); free($2); if (!ok) return (1); } ; isns_period: ISNS_PERIOD STR { uint64_t tmp; if (expand_number($2, &tmp) != 0) { yyerror("invalid numeric value"); free($2); return (1); } free($2); conf_set_isns_period(tmp); } ; isns_timeout: ISNS_TIMEOUT STR { uint64_t tmp; if (expand_number($2, &tmp) != 0) { yyerror("invalid numeric value"); free($2); return (1); } free($2); conf_set_isns_timeout(tmp); } ; auth_group: AUTH_GROUP auth_group_name OPENING_BRACKET auth_group_entries CLOSING_BRACKET { auth_group_finish(); } ; auth_group_name: STR { bool ok; ok = auth_group_start($1); free($1); if (!ok) return (1); } ; auth_group_entries: | auth_group_entries auth_group_entry | auth_group_entries auth_group_entry SEMICOLON ; auth_group_entry: auth_group_auth_type | auth_group_chap | auth_group_chap_mutual | auth_group_initiator_name | auth_group_initiator_portal ; auth_group_auth_type: AUTH_TYPE STR { bool ok; ok = auth_group_set_type($2); free($2); if (!ok) return (1); } ; auth_group_chap: CHAP STR STR { bool ok; ok = auth_group_add_chap($2, $3); free($2); free($3); if (!ok) return (1); } ; auth_group_chap_mutual: CHAP_MUTUAL STR STR STR STR { bool ok; ok = auth_group_add_chap_mutual($2, $3, $4, $5); free($2); free($3); free($4); free($5); if (!ok) return (1); } ; auth_group_initiator_name: INITIATOR_NAME STR { bool ok; ok = auth_group_add_initiator_name($2); free($2); if (!ok) return (1); } ; auth_group_initiator_portal: INITIATOR_PORTAL STR { bool ok; ok = auth_group_add_initiator_portal($2); free($2); if (!ok) return (1); } ; portal_group: PORTAL_GROUP portal_group_name OPENING_BRACKET portal_group_entries CLOSING_BRACKET { portal_group_finish(); } ; portal_group_name: STR { bool ok; ok = portal_group_start($1); free($1); if (!ok) return (1); } ; portal_group_entries: | portal_group_entries portal_group_entry | portal_group_entries portal_group_entry SEMICOLON ; portal_group_entry: portal_group_discovery_auth_group | portal_group_discovery_filter | portal_group_foreign | portal_group_listen | portal_group_listen_iser | portal_group_offload | portal_group_option | portal_group_redirect | portal_group_tag | portal_group_dscp | portal_group_pcp ; portal_group_discovery_auth_group: DISCOVERY_AUTH_GROUP STR { bool ok; ok = portal_group_set_discovery_auth_group($2); free($2); if (!ok) return (1); } ; portal_group_discovery_filter: DISCOVERY_FILTER STR { bool ok; ok = portal_group_set_filter($2); free($2); if (!ok) return (1); } ; portal_group_foreign: FOREIGN { portal_group_set_foreign(); } ; portal_group_listen: LISTEN STR { bool ok; ok = portal_group_add_listen($2, false); free($2); if (!ok) return (1); } ; portal_group_listen_iser: LISTEN_ISER STR { bool ok; ok = portal_group_add_listen($2, true); free($2); if (!ok) return (1); } ; portal_group_offload: OFFLOAD STR { bool ok; ok = portal_group_set_offload($2); free($2); if (!ok) return (1); } ; portal_group_option: OPTION STR STR { bool ok; ok = portal_group_add_option($2, $3); free($2); free($3); if (!ok) return (1); } ; portal_group_redirect: REDIRECT STR { bool ok; ok = portal_group_set_redirection($2); free($2); if (!ok) return (1); } ; portal_group_tag: TAG STR { uint64_t tmp; if (expand_number($2, &tmp) != 0) { yyerror("invalid numeric value"); free($2); return (1); } free($2); portal_group_set_tag(tmp); } ; portal_group_dscp : DSCP STR { uint64_t tmp; if (strcmp($2, "0x") == 0) { tmp = strtol($2 + 2, NULL, 16); } else if (expand_number($2, &tmp) != 0) { yyerror("invalid numeric value"); free($2); return (1); } free($2); if (!portal_group_set_dscp(tmp)) return (1); } | DSCP BE { portal_group_set_dscp(IPTOS_DSCP_CS0 >> 2); } | DSCP EF { portal_group_set_dscp(IPTOS_DSCP_EF >> 2); } | DSCP CS0 { portal_group_set_dscp(IPTOS_DSCP_CS0 >> 2); } | DSCP CS1 { portal_group_set_dscp(IPTOS_DSCP_CS1 >> 2); } | DSCP CS2 { portal_group_set_dscp(IPTOS_DSCP_CS2 >> 2); } | DSCP CS3 { portal_group_set_dscp(IPTOS_DSCP_CS3 >> 2); } | DSCP CS4 { portal_group_set_dscp(IPTOS_DSCP_CS4 >> 2); } | DSCP CS5 { portal_group_set_dscp(IPTOS_DSCP_CS5 >> 2); } | DSCP CS6 { portal_group_set_dscp(IPTOS_DSCP_CS6 >> 2); } | DSCP CS7 { portal_group_set_dscp(IPTOS_DSCP_CS7 >> 2); } | DSCP AF11 { portal_group_set_dscp(IPTOS_DSCP_AF11 >> 2); } | DSCP AF12 { portal_group_set_dscp(IPTOS_DSCP_AF12 >> 2); } | DSCP AF13 { portal_group_set_dscp(IPTOS_DSCP_AF13 >> 2); } | DSCP AF21 { portal_group_set_dscp(IPTOS_DSCP_AF21 >> 2); } | DSCP AF22 { portal_group_set_dscp(IPTOS_DSCP_AF22 >> 2); } | DSCP AF23 { portal_group_set_dscp(IPTOS_DSCP_AF23 >> 2); } | DSCP AF31 { portal_group_set_dscp(IPTOS_DSCP_AF31 >> 2); } | DSCP AF32 { portal_group_set_dscp(IPTOS_DSCP_AF32 >> 2); } | DSCP AF33 { portal_group_set_dscp(IPTOS_DSCP_AF33 >> 2); } | DSCP AF41 { portal_group_set_dscp(IPTOS_DSCP_AF41 >> 2); } | DSCP AF42 { portal_group_set_dscp(IPTOS_DSCP_AF42 >> 2); } | DSCP AF43 { portal_group_set_dscp(IPTOS_DSCP_AF43 >> 2); } ; portal_group_pcp: PCP STR { uint64_t tmp; if (expand_number($2, &tmp) != 0) { yyerror("invalid numeric value"); free($2); return (1); } free($2); if (!portal_group_set_pcp(tmp)) return (1); } ; lun: LUN lun_name OPENING_BRACKET lun_entries CLOSING_BRACKET { lun_finish(); } ; lun_name: STR { bool ok; ok = lun_start($1); free($1); if (!ok) return (1); } ; target: TARGET target_name OPENING_BRACKET target_entries CLOSING_BRACKET { target_finish(); } ; target_name: STR { bool ok; ok = target_start($1); free($1); if (!ok) return (1); } ; target_entries: | target_entries target_entry | target_entries target_entry SEMICOLON ; target_entry: target_alias | target_auth_group | target_auth_type | target_chap | target_chap_mutual | target_initiator_name | target_initiator_portal | target_portal_group | target_port | target_redirect | target_lun | target_lun_ref ; target_alias: ALIAS STR { bool ok; ok = target_set_alias($2); free($2); if (!ok) return (1); } ; target_auth_group: AUTH_GROUP STR { bool ok; ok = target_set_auth_group($2); free($2); if (!ok) return (1); } ; target_auth_type: AUTH_TYPE STR { bool ok; ok = target_set_auth_type($2); free($2); if (!ok) return (1); } ; target_chap: CHAP STR STR { bool ok; ok = target_add_chap($2, $3); free($2); free($3); if (!ok) return (1); } ; target_chap_mutual: CHAP_MUTUAL STR STR STR STR { bool ok; ok = target_add_chap_mutual($2, $3, $4, $5); free($2); free($3); free($4); free($5); if (!ok) return (1); } ; target_initiator_name: INITIATOR_NAME STR { bool ok; ok = target_add_initiator_name($2); free($2); if (!ok) return (1); } ; target_initiator_portal: INITIATOR_PORTAL STR { bool ok; ok = target_add_initiator_portal($2); free($2); if (!ok) return (1); } ; target_portal_group: PORTAL_GROUP STR STR { bool ok; ok = target_add_portal_group($2, $3); free($2); free($3); if (!ok) return (1); } | PORTAL_GROUP STR { bool ok; ok = target_add_portal_group($2, NULL); free($2); if (!ok) return (1); } ; target_port: PORT STR { bool ok; ok = target_set_physical_port($2); free($2); if (!ok) return (1); } ; target_redirect: REDIRECT STR { bool ok; ok = target_set_redirection($2); free($2); if (!ok) return (1); } ; target_lun: LUN lun_number OPENING_BRACKET lun_entries CLOSING_BRACKET { lun_finish(); } ; lun_number: STR { uint64_t tmp; if (expand_number($1, &tmp) != 0) { yyerror("invalid numeric value"); free($1); return (1); } free($1); if (!target_start_lun(tmp)) return (1); } ; target_lun_ref: LUN STR STR { uint64_t tmp; bool ok; if (expand_number($2, &tmp) != 0) { yyerror("invalid numeric value"); free($2); free($3); return (1); } free($2); ok = target_add_lun(tmp, $3); free($3); if (!ok) return (1); } ; lun_entries: | lun_entries lun_entry | lun_entries lun_entry SEMICOLON ; lun_entry: lun_backend | lun_blocksize | lun_device_id | lun_device_type | lun_ctl_lun | lun_option | lun_path | lun_serial | lun_size ; lun_backend: BACKEND STR { bool ok; ok = lun_set_backend($2); free($2); if (!ok) return (1); } ; lun_blocksize: BLOCKSIZE STR { uint64_t tmp; if (expand_number($2, &tmp) != 0) { yyerror("invalid numeric value"); free($2); return (1); } free($2); if (!lun_set_blocksize(tmp)) return (1); } ; lun_device_id: DEVICE_ID STR { bool ok; ok = lun_set_device_id($2); free($2); if (!ok) return (1); } ; lun_device_type: DEVICE_TYPE STR { bool ok; ok = lun_set_device_type($2); free($2); if (!ok) return (1); } ; lun_ctl_lun: CTL_LUN STR { uint64_t tmp; if (expand_number($2, &tmp) != 0) { yyerror("invalid numeric value"); free($2); return (1); } free($2); if (!lun_set_ctl_lun(tmp)) return (1); } ; lun_option: OPTION STR STR { bool ok; ok = lun_add_option($2, $3); free($2); free($3); if (!ok) return (1); } ; lun_path: PATH STR { bool ok; ok = lun_set_path($2); free($2); if (!ok) return (1); } ; lun_serial: SERIAL STR { bool ok; ok = lun_set_serial($2); free($2); if (!ok) return (1); } ; lun_size: SIZE STR { uint64_t tmp; if (expand_number($2, &tmp) != 0) { yyerror("invalid numeric value"); free($2); return (1); } free($2); if (!lun_set_size(tmp)) return (1); } ; %% void yyerror(const char *str) { log_warnx("error in configuration file at line %d near '%s': %s", lineno, yytext, str); } bool parse_conf(const char *path) { int error; yyin = fopen(path, "r"); if (yyin == NULL) { log_warn("unable to open configuration file %s", path); return (false); } lineno = 1; yyrestart(yyin); error = yyparse(); fclose(yyin); return (error == 0); }