ctld: Add a dedicated API between parse.y and the rest of the program

The primary purpose of this is to permit the rest of ctld to use C++.
However, this also has the nice side effect of reducing code
duplication with the UCL parser.

As a general rule, setting of options including error handling for
invalid values, etc. is moved out of parse.y and into conf.c.  The
globals for the current configuration, auth group, portal group, lun,
and target are also moved into conf.c hiding the types from parse.y.
The intention is that all of the functions declared in conf.h will be
extern "C" for use by parse.y and that the backing data structures can
be reimplemented as C++ classes instead of C structures if desired.

A few other small changes are included with this refactoring:

- Warn and fail a configuration that specifies the same LUN multiple
  times for a target.

- Use T_* constants for SCSI device types instead of magic numbers.

- Warn and fail for a few UCL properties that aren't the required type
  including "discovery-auth-group" in a portal group context,
  "auth-type" and "port" in a target context.

- Fix a bug where chap-mutual in a target in UCL would not auto-create
  a new auth-group.

Sponsored by:	Chelsio Communications
Differential Revision:	https://reviews.freebsd.org/D48934
This commit is contained in:
John Baldwin
2025-02-26 10:10:33 -05:00
parent 8c108dccd7
commit d42a73fb6a
8 changed files with 1391 additions and 1018 deletions
+1 -1
View File
@@ -5,7 +5,7 @@ CFLAGS+=-I${SRCTOP}/contrib/libucl/include
PACKAGE= iscsi
PROG= ctld
SRCS= ctld.c discovery.c isns.c kernel.c
SRCS= ctld.c conf.c discovery.c isns.c kernel.c
SRCS+= login.c parse.y token.l y.tab.h uclparse.c
CFLAGS+= -I${.CURDIR}
CFLAGS+= -I${SRCTOP}/sys
+772
View File
@@ -0,0 +1,772 @@
/*-
* 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 <sys/types.h>
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <cam/scsi/scsi_all.h>
#include "conf.h"
#include "ctld.h"
static struct conf *conf = NULL;
static struct auth_group *auth_group = NULL;
static struct portal_group *portal_group = NULL;
static struct target *target = NULL;
static struct lun *lun = NULL;
void
conf_start(struct conf *new_conf)
{
assert(conf == NULL);
conf = new_conf;
}
void
conf_finish(void)
{
auth_group = NULL;
portal_group = NULL;
target = NULL;
lun = NULL;
conf = NULL;
}
bool
isns_add_server(const char *addr)
{
return (isns_new(conf, addr));
}
void
conf_set_debug(int debug)
{
conf->conf_debug = debug;
}
void
conf_set_isns_period(int period)
{
conf->conf_isns_period = period;
}
void
conf_set_isns_timeout(int timeout)
{
conf->conf_isns_timeout = timeout;
}
void
conf_set_maxproc(int maxproc)
{
conf->conf_maxproc = maxproc;
}
bool
conf_set_pidfile_path(const char *path)
{
if (conf->conf_pidfile_path != NULL) {
log_warnx("pidfile specified more than once");
return (false);
}
conf->conf_pidfile_path = checked_strdup(path);
return (true);
}
void
conf_set_timeout(int timeout)
{
conf->conf_timeout = timeout;
}
static bool
_auth_group_set_type(struct auth_group *ag, const char *str)
{
int type;
if (strcmp(str, "none") == 0) {
type = AG_TYPE_NO_AUTHENTICATION;
} else if (strcmp(str, "deny") == 0) {
type = AG_TYPE_DENY;
} else if (strcmp(str, "chap") == 0) {
type = AG_TYPE_CHAP;
} else if (strcmp(str, "chap-mutual") == 0) {
type = AG_TYPE_CHAP_MUTUAL;
} else {
if (ag->ag_name != NULL)
log_warnx("invalid auth-type \"%s\" for auth-group "
"\"%s\"", str, ag->ag_name);
else
log_warnx("invalid auth-type \"%s\" for target "
"\"%s\"", str, ag->ag_target->t_name);
return (false);
}
if (ag->ag_type != AG_TYPE_UNKNOWN && ag->ag_type != type) {
if (ag->ag_name != NULL) {
log_warnx("cannot set auth-type to \"%s\" for "
"auth-group \"%s\"; already has a different "
"type", str, ag->ag_name);
} else {
log_warnx("cannot set auth-type to \"%s\" for target "
"\"%s\"; already has a different type",
str, ag->ag_target->t_name);
}
return (false);
}
ag->ag_type = type;
return (true);
}
bool
auth_group_add_chap(const char *user, const char *secret)
{
return (auth_new_chap(auth_group, user, secret));
}
bool
auth_group_add_chap_mutual(const char *user, const char *secret,
const char *user2, const char *secret2)
{
return (auth_new_chap_mutual(auth_group, user, secret, user2, secret2));
}
bool
auth_group_add_initiator_name(const char *name)
{
return (auth_name_new(auth_group, name));
}
bool
auth_group_add_initiator_portal(const char *portal)
{
return (auth_portal_new(auth_group, portal));
}
bool
auth_group_set_type(const char *type)
{
return (_auth_group_set_type(auth_group, type));
}
bool
auth_group_start(const char *name)
{
/*
* Make it possible to redefine the default auth-group. but
* only once.
*/
if (strcmp(name, "default") == 0) {
if (conf->conf_default_ag_defined) {
log_warnx("duplicated auth-group \"default\"");
return (false);
}
conf->conf_default_ag_defined = true;
auth_group = auth_group_find(conf, "default");
return (true);
}
auth_group = auth_group_new(conf, name);
return (auth_group != NULL);
}
void
auth_group_finish(void)
{
auth_group = NULL;
}
bool
portal_group_start(const char *name)
{
/*
* Make it possible to redefine the default portal-group. but
* only once.
*/
if (strcmp(name, "default") == 0) {
if (conf->conf_default_pg_defined) {
log_warnx("duplicated portal-group \"default\"");
return (false);
}
conf->conf_default_pg_defined = true;
portal_group = portal_group_find(conf, "default");
return (true);
}
portal_group = portal_group_new(conf, name);
return (portal_group != NULL);
}
void
portal_group_finish(void)
{
portal_group = NULL;
}
bool
portal_group_add_listen(const char *listen, bool iser)
{
return (portal_group_add_portal(portal_group, listen, iser));
}
bool
portal_group_add_option(const char *name, const char *value)
{
return (option_new(portal_group->pg_options, name, value));
}
bool
portal_group_set_discovery_auth_group(const char *name)
{
if (portal_group->pg_discovery_auth_group != NULL) {
log_warnx("discovery-auth-group for portal-group "
"\"%s\" specified more than once",
portal_group->pg_name);
return (false);
}
portal_group->pg_discovery_auth_group = auth_group_find(conf, name);
if (portal_group->pg_discovery_auth_group == NULL) {
log_warnx("unknown discovery-auth-group \"%s\" "
"for portal-group \"%s\"", name, portal_group->pg_name);
return (false);
}
return (true);
}
bool
portal_group_set_dscp(u_int dscp)
{
if (dscp >= 0x40) {
log_warnx("invalid DSCP value %u for portal-group \"%s\"",
dscp, portal_group->pg_name);
return (false);
}
portal_group->pg_dscp = dscp;
return (true);
}
bool
portal_group_set_filter(const char *str)
{
int filter;
if (strcmp(str, "none") == 0) {
filter = PG_FILTER_NONE;
} else if (strcmp(str, "portal") == 0) {
filter = PG_FILTER_PORTAL;
} else if (strcmp(str, "portal-name") == 0) {
filter = PG_FILTER_PORTAL_NAME;
} else if (strcmp(str, "portal-name-auth") == 0) {
filter = PG_FILTER_PORTAL_NAME_AUTH;
} else {
log_warnx("invalid discovery-filter \"%s\" for portal-group "
"\"%s\"; valid values are \"none\", \"portal\", "
"\"portal-name\", and \"portal-name-auth\"",
str, portal_group->pg_name);
return (false);
}
if (portal_group->pg_discovery_filter != PG_FILTER_UNKNOWN &&
portal_group->pg_discovery_filter != filter) {
log_warnx("cannot set discovery-filter to \"%s\" for "
"portal-group \"%s\"; already has a different "
"value", str, portal_group->pg_name);
return (false);
}
portal_group->pg_discovery_filter = filter;
return (true);
}
void
portal_group_set_foreign(void)
{
portal_group->pg_foreign = true;
}
bool
portal_group_set_offload(const char *offload)
{
if (portal_group->pg_offload != NULL) {
log_warnx("cannot set offload to \"%s\" for "
"portal-group \"%s\"; already defined",
offload, portal_group->pg_name);
return (false);
}
portal_group->pg_offload = checked_strdup(offload);
return (true);
}
bool
portal_group_set_pcp(u_int pcp)
{
if (pcp > 7) {
log_warnx("invalid PCP value %u for portal-group \"%s\"",
pcp, portal_group->pg_name);
return (false);
}
portal_group->pg_pcp = pcp;
return (true);
}
bool
portal_group_set_redirection(const char *addr)
{
if (portal_group->pg_redirection != NULL) {
log_warnx("cannot set redirection to \"%s\" for "
"portal-group \"%s\"; already defined",
addr, portal_group->pg_name);
return (false);
}
portal_group->pg_redirection = checked_strdup(addr);
return (true);
}
void
portal_group_set_tag(uint16_t tag)
{
portal_group->pg_tag = tag;
}
bool
lun_start(const char *name)
{
lun = lun_new(conf, name);
return (lun != NULL);
}
void
lun_finish(void)
{
lun = NULL;
}
bool
lun_add_option(const char *name, const char *value)
{
return (option_new(lun->l_options, name, value));
}
bool
lun_set_backend(const char *value)
{
if (lun->l_backend != NULL) {
log_warnx("backend for lun \"%s\" specified more than once",
lun->l_name);
return (false);
}
lun->l_backend = checked_strdup(value);
return (true);
}
bool
lun_set_blocksize(size_t value)
{
if (lun->l_blocksize != 0) {
log_warnx("blocksize for lun \"%s\" specified more than once",
lun->l_name);
return (false);
}
lun->l_blocksize = value;
return (true);
}
bool
lun_set_device_type(const char *value)
{
uint64_t device_type;
if (strcasecmp(value, "disk") == 0 ||
strcasecmp(value, "direct") == 0)
device_type = T_DIRECT;
else if (strcasecmp(value, "processor") == 0)
device_type = T_PROCESSOR;
else if (strcasecmp(value, "cd") == 0 ||
strcasecmp(value, "cdrom") == 0 ||
strcasecmp(value, "dvd") == 0 ||
strcasecmp(value, "dvdrom") == 0)
device_type = T_CDROM;
else if (expand_number(value, &device_type) != 0 || device_type > 15) {
log_warnx("invalid device-type \"%s\" for lun \"%s\"", value,
lun->l_name);
return (false);
}
lun->l_device_type = device_type;
return (true);
}
bool
lun_set_device_id(const char *value)
{
if (lun->l_device_id != NULL) {
log_warnx("device_id for lun \"%s\" specified more than once",
lun->l_name);
return (false);
}
lun->l_device_id = checked_strdup(value);
return (true);
}
bool
lun_set_path(const char *value)
{
if (lun->l_path != NULL) {
log_warnx("path for lun \"%s\" specified more than once",
lun->l_name);
return (false);
}
lun->l_path = checked_strdup(value);
return (true);
}
bool
lun_set_serial(const char *value)
{
if (lun->l_serial != NULL) {
log_warnx("serial for lun \"%s\" specified more than once",
lun->l_name);
return (false);
}
lun->l_serial = checked_strdup(value);
return (true);
}
bool
lun_set_size(uint64_t value)
{
if (lun->l_size != 0) {
log_warnx("size for lun \"%s\" specified more than once",
lun->l_name);
return (false);
}
lun->l_size = value;
return (true);
}
bool
lun_set_ctl_lun(uint32_t value)
{
if (lun->l_ctl_lun >= 0) {
log_warnx("ctl_lun for lun \"%s\" specified more than once",
lun->l_name);
return (false);
}
lun->l_ctl_lun = value;
return (true);
}
bool
target_start(const char *name)
{
target = target_new(conf, name);
return (target != NULL);
}
void
target_finish(void)
{
target = NULL;
}
bool
target_add_chap(const char *user, const char *secret)
{
if (target->t_auth_group != NULL) {
if (target->t_auth_group->ag_name != NULL) {
log_warnx("cannot use both auth-group and "
"chap for target \"%s\"", target->t_name);
return (false);
}
} else {
target->t_auth_group = auth_group_new(conf, NULL);
if (target->t_auth_group == NULL)
return (false);
target->t_auth_group->ag_target = target;
}
return (auth_new_chap(target->t_auth_group, user, secret));
}
bool
target_add_chap_mutual(const char *user, const char *secret,
const char *user2, const char *secret2)
{
if (target->t_auth_group != NULL) {
if (target->t_auth_group->ag_name != NULL) {
log_warnx("cannot use both auth-group and "
"chap-mutual for target \"%s\"", target->t_name);
return (false);
}
} else {
target->t_auth_group = auth_group_new(conf, NULL);
if (target->t_auth_group == NULL)
return (false);
target->t_auth_group->ag_target = target;
}
return (auth_new_chap_mutual(target->t_auth_group, user, secret, user2,
secret2));
}
bool
target_add_initiator_name(const char *name)
{
if (target->t_auth_group != NULL) {
if (target->t_auth_group->ag_name != NULL) {
log_warnx("cannot use both auth-group and "
"initiator-name for target \"%s\"", target->t_name);
return (false);
}
} else {
target->t_auth_group = auth_group_new(conf, NULL);
if (target->t_auth_group == NULL)
return (false);
target->t_auth_group->ag_target = target;
}
return (auth_name_new(target->t_auth_group, name));
}
bool
target_add_initiator_portal(const char *addr)
{
if (target->t_auth_group != NULL) {
if (target->t_auth_group->ag_name != NULL) {
log_warnx("cannot use both auth-group and "
"initiator-portal for target \"%s\"",
target->t_name);
return (false);
}
} else {
target->t_auth_group = auth_group_new(conf, NULL);
if (target->t_auth_group == NULL)
return (false);
target->t_auth_group->ag_target = target;
}
return (auth_portal_new(target->t_auth_group, addr));
}
bool
target_add_lun(u_int id, const char *name)
{
struct lun *t_lun;
if (id >= MAX_LUNS) {
log_warnx("LUN %u too big for target \"%s\"", id,
target->t_name);
return (false);
}
if (target->t_luns[id] != NULL) {
log_warnx("duplicate LUN %u for target \"%s\"", id,
target->t_name);
return (false);
}
t_lun = lun_find(conf, name);
if (t_lun == NULL) {
log_warnx("unknown LUN named %s used for target \"%s\"",
name, target->t_name);
return (false);
}
target->t_luns[id] = t_lun;
return (true);
}
bool
target_add_portal_group(const char *pg_name, const char *ag_name)
{
struct portal_group *pg;
struct auth_group *ag;
struct port *p;
pg = portal_group_find(conf, pg_name);
if (pg == NULL) {
log_warnx("unknown portal-group \"%s\" for target \"%s\"",
pg_name, target->t_name);
return (false);
}
if (ag_name != NULL) {
ag = auth_group_find(conf, ag_name);
if (ag == NULL) {
log_warnx("unknown auth-group \"%s\" for target \"%s\"",
ag_name, target->t_name);
return (false);
}
} else
ag = NULL;
p = port_new(conf, target, pg);
if (p == NULL) {
log_warnx("can't link portal-group \"%s\" to target \"%s\"",
pg_name, target->t_name);
return (false);
}
p->p_auth_group = ag;
return (true);
}
bool
target_set_alias(const char *alias)
{
if (target->t_alias != NULL) {
log_warnx("alias for target \"%s\" specified more than once",
target->t_name);
return (false);
}
target->t_alias = checked_strdup(alias);
return (true);
}
bool
target_set_auth_group(const char *name)
{
if (target->t_auth_group != NULL) {
if (target->t_auth_group->ag_name != NULL)
log_warnx("auth-group for target \"%s\" "
"specified more than once", target->t_name);
else
log_warnx("cannot use both auth-group and explicit "
"authorisations for target \"%s\"", target->t_name);
return (false);
}
target->t_auth_group = auth_group_find(conf, name);
if (target->t_auth_group == NULL) {
log_warnx("unknown auth-group \"%s\" for target \"%s\"", name,
target->t_name);
return (false);
}
return (true);
}
bool
target_set_auth_type(const char *type)
{
if (target->t_auth_group != NULL) {
if (target->t_auth_group->ag_name != NULL) {
log_warnx("cannot use both auth-group and "
"auth-type for target \"%s\"", target->t_name);
return (false);
}
} else {
target->t_auth_group = auth_group_new(conf, NULL);
if (target->t_auth_group == NULL)
return (false);
target->t_auth_group->ag_target = target;
}
return (_auth_group_set_type(target->t_auth_group, type));
}
bool
target_set_physical_port(const char *pport)
{
if (target->t_pport != NULL) {
log_warnx("cannot set multiple physical ports for target "
"\"%s\"", target->t_name);
return (false);
}
target->t_pport = checked_strdup(pport);
return (true);
}
bool
target_set_redirection(const char *addr)
{
if (target->t_redirection != NULL) {
log_warnx("cannot set redirection to \"%s\" for "
"target \"%s\"; already defined",
addr, target->t_name);
return (false);
}
target->t_redirection = checked_strdup(addr);
return (true);
}
bool
target_start_lun(u_int id)
{
struct lun *new_lun;
char *name;
if (id >= MAX_LUNS) {
log_warnx("LUN %u too big for target \"%s\"", id,
target->t_name);
return (false);
}
if (target->t_luns[id] != NULL) {
log_warnx("duplicate LUN %u for target \"%s\"", id,
target->t_name);
return (false);
}
if (asprintf(&name, "%s,lun,%u", target->t_name, id) <= 0)
log_err(1, "asprintf");
new_lun = lun_new(conf, name);
if (new_lun == NULL)
return (false);
lun_set_scsiname(new_lun, name);
free(name);
target->t_luns[id] = new_lun;
lun = new_lun;
return (true);
}
+100
View File
@@ -0,0 +1,100 @@
/*-
* 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.
*/
#ifndef __CONF_H__
#define __CONF_H__
/*
* This file defines the interface between parse.y and the rest of
* ctld.
*/
bool auth_group_start(const char *name);
void auth_group_finish(void);
bool auth_group_add_chap(const char *user, const char *secret);
bool auth_group_add_chap_mutual(const char *user, const char *secret,
const char *user2, const char *secret2);
bool auth_group_add_initiator_name(const char *name);
bool auth_group_add_initiator_portal(const char *portal);
bool auth_group_set_type(const char *type);
void conf_set_debug(int debug);
void conf_set_isns_period(int period);
void conf_set_isns_timeout(int timeout);
void conf_set_maxproc(int maxproc);
bool conf_set_pidfile_path(const char *path);
void conf_set_timeout(int timeout);
bool isns_add_server(const char *addr);
bool portal_group_start(const char *name);
void portal_group_finish(void);
bool portal_group_add_listen(const char *listen, bool iser);
bool portal_group_add_option(const char *name, const char *value);
bool portal_group_set_discovery_auth_group(const char *name);
bool portal_group_set_dscp(u_int dscp);
bool portal_group_set_filter(const char *filter);
void portal_group_set_foreign(void);
bool portal_group_set_offload(const char *offload);
bool portal_group_set_pcp(u_int pcp);
bool portal_group_set_redirection(const char *addr);
void portal_group_set_tag(uint16_t tag);
bool target_start(const char *name);
void target_finish(void);
bool target_add_chap(const char *user, const char *secret);
bool target_add_chap_mutual(const char *user, const char *secret,
const char *user2, const char *secret2);
bool target_add_initiator_name(const char *name);
bool target_add_initiator_portal(const char *addr);
bool target_add_lun(u_int id, const char *name);
bool target_add_portal_group(const char *pg_name, const char *ag_name);
bool target_set_alias(const char *alias);
bool target_set_auth_group(const char *name);
bool target_set_auth_type(const char *type);
bool target_set_physical_port(const char *pport);
bool target_set_redirection(const char *addr);
bool target_start_lun(u_int id);
bool lun_start(const char *name);
void lun_finish(void);
bool lun_add_option(const char *name, const char *value);
bool lun_set_backend(const char *value);
bool lun_set_blocksize(size_t value);
bool lun_set_ctl_lun(uint32_t value);
bool lun_set_device_id(const char *value);
bool lun_set_device_type(const char *value);
bool lun_set_path(const char *value);
bool lun_set_serial(const char *value);
bool lun_set_size(uint64_t value);
bool parse_conf(const char *path);
#endif /* !__CONF_H__ */
+25 -200
View File
@@ -49,7 +49,9 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <cam/scsi/scsi_all.h>
#include "conf.h"
#include "ctld.h"
#include "isns.h"
@@ -237,7 +239,7 @@ auth_check_secret_length(struct auth *auth)
}
}
const struct auth *
bool
auth_new_chap(struct auth_group *ag, const char *user,
const char *secret)
{
@@ -253,7 +255,7 @@ auth_new_chap(struct auth_group *ag, const char *user,
log_warnx("cannot mix \"chap\" authentication with "
"other types for target \"%s\"",
ag->ag_target->t_name);
return (NULL);
return (false);
}
auth = auth_new(ag);
@@ -262,10 +264,10 @@ auth_new_chap(struct auth_group *ag, const char *user,
auth_check_secret_length(auth);
return (auth);
return (true);
}
const struct auth *
bool
auth_new_chap_mutual(struct auth_group *ag, const char *user,
const char *secret, const char *user2, const char *secret2)
{
@@ -282,7 +284,7 @@ auth_new_chap_mutual(struct auth_group *ag, const char *user,
log_warnx("cannot mix \"chap-mutual\" authentication "
"with other types for target \"%s\"",
ag->ag_target->t_name);
return (NULL);
return (false);
}
auth = auth_new(ag);
@@ -293,10 +295,10 @@ auth_new_chap_mutual(struct auth_group *ag, const char *user,
auth_check_secret_length(auth);
return (auth);
return (true);
}
const struct auth_name *
bool
auth_name_new(struct auth_group *ag, const char *name)
{
struct auth_name *an;
@@ -307,7 +309,7 @@ auth_name_new(struct auth_group *ag, const char *name)
an->an_auth_group = ag;
an->an_initiator_name = checked_strdup(name);
TAILQ_INSERT_TAIL(&ag->ag_names, an, an_next);
return (an);
return (true);
}
static void
@@ -352,7 +354,7 @@ auth_name_check(const struct auth_group *ag, const char *initiator_name)
return (true);
}
const struct auth_portal *
bool
auth_portal_new(struct auth_group *ag, const char *portal)
{
struct auth_portal *ap;
@@ -401,13 +403,13 @@ auth_portal_new(struct auth_group *ag, const char *portal)
ap->ap_mask = m;
free(str);
TAILQ_INSERT_TAIL(&ag->ag_portals, ap, ap_next);
return (ap);
return (true);
error:
free(str);
free(ap);
log_warnx("incorrect initiator portal \"%s\"", portal);
return (NULL);
return (false);
}
static void
@@ -540,47 +542,6 @@ auth_group_find(const struct conf *conf, const char *name)
return (NULL);
}
bool
auth_group_set_type(struct auth_group *ag, const char *str)
{
int type;
if (strcmp(str, "none") == 0) {
type = AG_TYPE_NO_AUTHENTICATION;
} else if (strcmp(str, "deny") == 0) {
type = AG_TYPE_DENY;
} else if (strcmp(str, "chap") == 0) {
type = AG_TYPE_CHAP;
} else if (strcmp(str, "chap-mutual") == 0) {
type = AG_TYPE_CHAP_MUTUAL;
} else {
if (ag->ag_name != NULL)
log_warnx("invalid auth-type \"%s\" for auth-group "
"\"%s\"", str, ag->ag_name);
else
log_warnx("invalid auth-type \"%s\" for target "
"\"%s\"", str, ag->ag_target->t_name);
return (false);
}
if (ag->ag_type != AG_TYPE_UNKNOWN && ag->ag_type != type) {
if (ag->ag_name != NULL) {
log_warnx("cannot set auth-type to \"%s\" for "
"auth-group \"%s\"; already has a different "
"type", str, ag->ag_name);
} else {
log_warnx("cannot set auth-type to \"%s\" for target "
"\"%s\"; already has a different type",
str, ag->ag_target->t_name);
}
return (false);
}
ag->ag_type = type;
return (true);
}
static struct portal *
portal_new(struct portal_group *pg)
{
@@ -723,7 +684,7 @@ parse_addr_port(char *arg, const char *def_port, struct addrinfo **ai)
}
bool
portal_group_add_listen(struct portal_group *pg, const char *value, bool iser)
portal_group_add_portal(struct portal_group *pg, const char *value, bool iser)
{
struct portal *portal;
@@ -1007,72 +968,6 @@ isns_deregister(struct isns *isns)
set_timeout(0, false);
}
bool
portal_group_set_filter(struct portal_group *pg, const char *str)
{
int filter;
if (strcmp(str, "none") == 0) {
filter = PG_FILTER_NONE;
} else if (strcmp(str, "portal") == 0) {
filter = PG_FILTER_PORTAL;
} else if (strcmp(str, "portal-name") == 0) {
filter = PG_FILTER_PORTAL_NAME;
} else if (strcmp(str, "portal-name-auth") == 0) {
filter = PG_FILTER_PORTAL_NAME_AUTH;
} else {
log_warnx("invalid discovery-filter \"%s\" for portal-group "
"\"%s\"; valid values are \"none\", \"portal\", "
"\"portal-name\", and \"portal-name-auth\"",
str, pg->pg_name);
return (false);
}
if (pg->pg_discovery_filter != PG_FILTER_UNKNOWN &&
pg->pg_discovery_filter != filter) {
log_warnx("cannot set discovery-filter to \"%s\" for "
"portal-group \"%s\"; already has a different "
"value", str, pg->pg_name);
return (false);
}
pg->pg_discovery_filter = filter;
return (true);
}
bool
portal_group_set_offload(struct portal_group *pg, const char *offload)
{
if (pg->pg_offload != NULL) {
log_warnx("cannot set offload to \"%s\" for "
"portal-group \"%s\"; already defined",
offload, pg->pg_name);
return (false);
}
pg->pg_offload = checked_strdup(offload);
return (true);
}
bool
portal_group_set_redirection(struct portal_group *pg, const char *addr)
{
if (pg->pg_redirection != NULL) {
log_warnx("cannot set redirection to \"%s\" for "
"portal-group \"%s\"; already defined",
addr, pg->pg_name);
return (false);
}
pg->pg_redirection = checked_strdup(addr);
return (true);
}
struct pport *
pport_new(struct kports *kports, const char *name, uint32_t ctl_port)
{
@@ -1339,22 +1234,6 @@ target_find(struct conf *conf, const char *name)
return (NULL);
}
bool
target_set_redirection(struct target *target, const char *addr)
{
if (target->t_redirection != NULL) {
log_warnx("cannot set redirection to \"%s\" for "
"target \"%s\"; already defined",
addr, target->t_name);
return (false);
}
target->t_redirection = checked_strdup(addr);
return (true);
}
struct lun *
lun_new(struct conf *conf, const char *name)
{
@@ -1415,41 +1294,6 @@ lun_find(const struct conf *conf, const char *name)
return (NULL);
}
void
lun_set_backend(struct lun *lun, const char *value)
{
free(lun->l_backend);
lun->l_backend = checked_strdup(value);
}
void
lun_set_blocksize(struct lun *lun, size_t value)
{
lun->l_blocksize = value;
}
void
lun_set_device_type(struct lun *lun, uint8_t value)
{
lun->l_device_type = value;
}
void
lun_set_device_id(struct lun *lun, const char *value)
{
free(lun->l_device_id);
lun->l_device_id = checked_strdup(value);
}
void
lun_set_path(struct lun *lun, const char *value)
{
free(lun->l_path);
lun->l_path = checked_strdup(value);
}
void
lun_set_scsiname(struct lun *lun, const char *value)
{
@@ -1457,27 +1301,6 @@ lun_set_scsiname(struct lun *lun, const char *value)
lun->l_scsiname = checked_strdup(value);
}
void
lun_set_serial(struct lun *lun, const char *value)
{
free(lun->l_serial);
lun->l_serial = checked_strdup(value);
}
void
lun_set_size(struct lun *lun, int64_t value)
{
lun->l_size = value;
}
void
lun_set_ctl_lun(struct lun *lun, uint32_t value)
{
lun->l_ctl_lun = value;
}
bool
option_new(nvlist_t *nvl, const char *name, const char *value)
{
@@ -1622,7 +1445,7 @@ conf_verify_lun(struct lun *lun)
const struct lun *lun2;
if (lun->l_backend == NULL)
lun_set_backend(lun, "block");
lun->l_backend = checked_strdup("block");
if (strcmp(lun->l_backend, "block") == 0) {
if (lun->l_path == NULL) {
log_warnx("missing path for lun \"%s\"",
@@ -1643,10 +1466,10 @@ conf_verify_lun(struct lun *lun)
}
}
if (lun->l_blocksize == 0) {
if (lun->l_device_type == 5)
lun_set_blocksize(lun, DEFAULT_CD_BLOCKSIZE);
if (lun->l_device_type == T_CDROM)
lun->l_blocksize = DEFAULT_CD_BLOCKSIZE;
else
lun_set_blocksize(lun, DEFAULT_BLOCKSIZE);
lun->l_blocksize = DEFAULT_BLOCKSIZE;
} else if (lun->l_blocksize < 0) {
log_warnx("invalid blocksize for lun \"%s\"; "
"must be larger than 0", lun->l_name);
@@ -2066,7 +1889,7 @@ conf_apply(struct conf *oldconf, struct conf *newconf)
continue;
}
lun_set_ctl_lun(newlun, oldlun->l_ctl_lun);
newlun->l_ctl_lun = oldlun->l_ctl_lun;
}
TAILQ_FOREACH_SAFE(newlun, &newconf->conf_luns, l_next, tmplun) {
@@ -2565,10 +2388,12 @@ conf_new_from_file(const char *path, bool ucl)
pg = portal_group_new(conf, "default");
assert(pg != NULL);
conf_start(conf);
if (ucl)
valid = uclparse_conf(conf, path);
valid = uclparse_conf(path);
else
valid = parse_conf(conf, path);
valid = parse_conf(path);
conf_finish();
if (!valid) {
conf_delete(conf);
@@ -2590,8 +2415,8 @@ conf_new_from_file(const char *path, bool ucl)
"going with defaults");
pg = portal_group_find(conf, "default");
assert(pg != NULL);
portal_group_add_listen(pg, "0.0.0.0", false);
portal_group_add_listen(pg, "[::]", false);
portal_group_add_portal(pg, "0.0.0.0", false);
portal_group_add_portal(pg, "[::]", false);
}
conf->conf_kernel_port_on = true;
+11 -28
View File
@@ -168,7 +168,7 @@ struct lun {
char *l_path;
char *l_scsiname;
char *l_serial;
int64_t l_size;
uint64_t l_size;
int l_ctl_lun;
};
@@ -247,30 +247,29 @@ struct ctld_connection {
extern int ctl_fd;
bool parse_conf(struct conf *newconf, const char *path);
bool uclparse_conf(struct conf *conf, const char *path);
bool uclparse_conf(const char *path);
struct conf *conf_new(void);
struct conf *conf_new_from_kernel(struct kports *kports);
void conf_delete(struct conf *conf);
void conf_finish(void);
void conf_start(struct conf *new_conf);
bool conf_verify(struct conf *conf);
struct auth_group *auth_group_new(struct conf *conf, const char *name);
void auth_group_delete(struct auth_group *ag);
struct auth_group *auth_group_find(const struct conf *conf,
const char *name);
bool auth_group_set_type(struct auth_group *ag,
const char *type);
const struct auth *auth_new_chap(struct auth_group *ag,
const char *user, const char *secret);
const struct auth *auth_new_chap_mutual(struct auth_group *ag,
bool auth_new_chap(struct auth_group *ag, const char *user,
const char *secret);
bool auth_new_chap_mutual(struct auth_group *ag,
const char *user, const char *secret,
const char *user2, const char *secret2);
const struct auth *auth_find(const struct auth_group *ag,
const char *user);
const struct auth_name *auth_name_new(struct auth_group *ag,
bool auth_name_new(struct auth_group *ag,
const char *initiator_name);
bool auth_name_defined(const struct auth_group *ag);
const struct auth_name *auth_name_find(const struct auth_group *ag,
@@ -278,7 +277,7 @@ const struct auth_name *auth_name_find(const struct auth_group *ag,
bool auth_name_check(const struct auth_group *ag,
const char *initiator_name);
const struct auth_portal *auth_portal_new(struct auth_group *ag,
bool auth_portal_new(struct auth_group *ag,
const char *initiator_portal);
bool auth_portal_defined(const struct auth_group *ag);
const struct auth_portal *auth_portal_find(const struct auth_group *ag,
@@ -290,14 +289,8 @@ struct portal_group *portal_group_new(struct conf *conf, const char *name);
void portal_group_delete(struct portal_group *pg);
struct portal_group *portal_group_find(const struct conf *conf,
const char *name);
bool portal_group_add_listen(struct portal_group *pg,
const char *listen, bool iser);
bool portal_group_set_filter(struct portal_group *pg,
const char *filter);
bool portal_group_set_offload(struct portal_group *pg,
const char *offload);
bool portal_group_set_redirection(struct portal_group *pg,
const char *addr);
bool portal_group_add_portal(struct portal_group *pg,
const char *value, bool iser);
bool isns_new(struct conf *conf, const char *addr);
void isns_delete(struct isns *is);
@@ -329,21 +322,11 @@ struct target *target_new(struct conf *conf, const char *name);
void target_delete(struct target *target);
struct target *target_find(struct conf *conf,
const char *name);
bool target_set_redirection(struct target *target,
const char *addr);
struct lun *lun_new(struct conf *conf, const char *name);
void lun_delete(struct lun *lun);
struct lun *lun_find(const struct conf *conf, const char *name);
void lun_set_backend(struct lun *lun, const char *value);
void lun_set_device_type(struct lun *lun, uint8_t value);
void lun_set_blocksize(struct lun *lun, size_t value);
void lun_set_device_id(struct lun *lun, const char *value);
void lun_set_path(struct lun *lun, const char *value);
void lun_set_scsiname(struct lun *lun, const char *value);
void lun_set_serial(struct lun *lun, const char *value);
void lun_set_size(struct lun *lun, int64_t value);
void lun_set_ctl_lun(struct lun *lun, uint32_t value);
bool option_new(nvlist_t *nvl,
const char *name, const char *value);
+13 -10
View File
@@ -619,21 +619,24 @@ conf_new_from_kernel(struct kports *kports)
log_warnx("lun_new failed");
continue;
}
lun_set_backend(cl, lun->backend_type);
lun_set_device_type(cl, lun->device_type);
lun_set_blocksize(cl, lun->blocksize);
lun_set_device_id(cl, lun->device_id);
lun_set_serial(cl, lun->serial_number);
lun_set_size(cl, lun->size_blocks * cl->l_blocksize);
lun_set_ctl_lun(cl, lun->lun_id);
cl->l_backend = lun->backend_type;
lun->backend_type = NULL;
cl->l_device_type = lun->device_type;
cl->l_blocksize = lun->blocksize;
cl->l_device_id = lun->device_id;
lun->device_id = NULL;
cl->l_serial = lun->serial_number;
lun->serial_number = NULL;
cl->l_size = lun->size_blocks * cl->l_blocksize;
cl->l_ctl_lun = lun->lun_id;
cookie = NULL;
while ((key = nvlist_next(lun->attr_list, NULL, &cookie)) !=
NULL) {
if (strcmp(key, "file") == 0 ||
strcmp(key, "dev") == 0) {
lun_set_path(cl,
nvlist_get_string(lun->attr_list, key));
cl->l_path = nvlist_take_string(lun->attr_list,
key);
continue;
}
nvlist_add_string(cl->l_options, key,
@@ -739,7 +742,7 @@ kernel_lun_add(struct lun *lun)
return (1);
}
lun_set_ctl_lun(lun, req.reqdata.create.req_lun_id);
lun->l_ctl_lun = req.reqdata.create.req_lun_id;
return (0);
}
+156 -387
View File
@@ -34,24 +34,20 @@
#include <sys/queue.h>
#include <sys/stat.h>
#include <assert.h>
#include <libiscsiutil.h>
#include <libutil.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ctld.h"
#include <netinet/in.h>
#include <netinet/ip.h>
#include "conf.h"
extern FILE *yyin;
extern char *yytext;
extern int lineno;
static struct conf *conf = NULL;
static struct auth_group *auth_group = NULL;
static struct portal_group *portal_group = NULL;
static struct target *target = NULL;
static struct lun *lun = NULL;
extern void yyerror(const char *);
extern void yyrestart(FILE *);
@@ -118,7 +114,7 @@ debug: DEBUG STR
}
free($2);
conf->conf_debug = tmp;
conf_set_debug(tmp);
}
;
@@ -133,7 +129,7 @@ timeout: TIMEOUT STR
}
free($2);
conf->conf_timeout = tmp;
conf_set_timeout(tmp);
}
;
@@ -148,18 +144,18 @@ maxproc: MAXPROC STR
}
free($2);
conf->conf_maxproc = tmp;
conf_set_maxproc(tmp);
}
;
pidfile: PIDFILE STR
{
if (conf->conf_pidfile_path != NULL) {
log_warnx("pidfile specified more than once");
free($2);
bool ok;
ok = conf_set_pidfile_path($2);
free($2);
if (!ok)
return (1);
}
conf->conf_pidfile_path = $2;
}
;
@@ -167,7 +163,7 @@ isns_server: ISNS_SERVER STR
{
bool ok;
ok = isns_new(conf, $2);
ok = isns_add_server($2);
free($2);
if (!ok)
return (1);
@@ -185,7 +181,7 @@ isns_period: ISNS_PERIOD STR
}
free($2);
conf->conf_isns_period = tmp;
conf_set_isns_period(tmp);
}
;
@@ -200,32 +196,24 @@ isns_timeout: ISNS_TIMEOUT STR
}
free($2);
conf->conf_isns_timeout = tmp;
conf_set_isns_timeout(tmp);
}
;
auth_group: AUTH_GROUP auth_group_name
OPENING_BRACKET auth_group_entries CLOSING_BRACKET
{
auth_group = NULL;
auth_group_finish();
}
;
auth_group_name: STR
{
/*
* Make it possible to redefine default
* auth-group. but only once.
*/
if (strcmp($1, "default") == 0 &&
conf->conf_default_ag_defined == false) {
auth_group = auth_group_find(conf, $1);
conf->conf_default_ag_defined = true;
} else {
auth_group = auth_group_new(conf, $1);
}
bool ok;
ok = auth_group_start($1);
free($1);
if (auth_group == NULL)
if (!ok)
return (1);
}
;
@@ -253,7 +241,7 @@ auth_group_auth_type: AUTH_TYPE STR
{
bool ok;
ok = auth_group_set_type(auth_group, $2);
ok = auth_group_set_type($2);
free($2);
if (!ok)
return (1);
@@ -262,48 +250,48 @@ auth_group_auth_type: AUTH_TYPE STR
auth_group_chap: CHAP STR STR
{
const struct auth *ca;
bool ok;
ca = auth_new_chap(auth_group, $2, $3);
ok = auth_group_add_chap($2, $3);
free($2);
free($3);
if (ca == NULL)
if (!ok)
return (1);
}
;
auth_group_chap_mutual: CHAP_MUTUAL STR STR STR STR
{
const struct auth *ca;
bool ok;
ca = auth_new_chap_mutual(auth_group, $2, $3, $4, $5);
ok = auth_group_add_chap_mutual($2, $3, $4, $5);
free($2);
free($3);
free($4);
free($5);
if (ca == NULL)
if (!ok)
return (1);
}
;
auth_group_initiator_name: INITIATOR_NAME STR
{
const struct auth_name *an;
bool ok;
an = auth_name_new(auth_group, $2);
ok = auth_group_add_initiator_name($2);
free($2);
if (an == NULL)
if (!ok)
return (1);
}
;
auth_group_initiator_portal: INITIATOR_PORTAL STR
{
const struct auth_portal *ap;
bool ok;
ap = auth_portal_new(auth_group, $2);
ok = auth_group_add_initiator_portal($2);
free($2);
if (ap == NULL)
if (!ok)
return (1);
}
;
@@ -311,25 +299,17 @@ auth_group_initiator_portal: INITIATOR_PORTAL STR
portal_group: PORTAL_GROUP portal_group_name
OPENING_BRACKET portal_group_entries CLOSING_BRACKET
{
portal_group = NULL;
portal_group_finish();
}
;
portal_group_name: STR
{
/*
* Make it possible to redefine default
* portal-group. but only once.
*/
if (strcmp($1, "default") == 0 &&
conf->conf_default_pg_defined == false) {
portal_group = portal_group_find(conf, $1);
conf->conf_default_pg_defined = true;
} else {
portal_group = portal_group_new(conf, $1);
}
bool ok;
ok = portal_group_start($1);
free($1);
if (portal_group == NULL)
if (!ok)
return (1);
}
;
@@ -367,23 +347,12 @@ portal_group_entry:
portal_group_discovery_auth_group: DISCOVERY_AUTH_GROUP STR
{
if (portal_group->pg_discovery_auth_group != NULL) {
log_warnx("discovery-auth-group for portal-group "
"\"%s\" specified more than once",
portal_group->pg_name);
free($2);
return (1);
}
portal_group->pg_discovery_auth_group =
auth_group_find(conf, $2);
if (portal_group->pg_discovery_auth_group == NULL) {
log_warnx("unknown discovery-auth-group \"%s\" "
"for portal-group \"%s\"",
$2, portal_group->pg_name);
free($2);
return (1);
}
bool ok;
ok = portal_group_set_discovery_auth_group($2);
free($2);
if (!ok)
return (1);
}
;
@@ -391,7 +360,7 @@ portal_group_discovery_filter: DISCOVERY_FILTER STR
{
bool ok;
ok = portal_group_set_filter(portal_group, $2);
ok = portal_group_set_filter($2);
free($2);
if (!ok)
return (1);
@@ -401,7 +370,7 @@ portal_group_discovery_filter: DISCOVERY_FILTER STR
portal_group_foreign: FOREIGN
{
portal_group->pg_foreign = true;
portal_group_set_foreign();
}
;
@@ -409,7 +378,7 @@ portal_group_listen: LISTEN STR
{
bool ok;
ok = portal_group_add_listen(portal_group, $2, false);
ok = portal_group_add_listen($2, false);
free($2);
if (!ok)
return (1);
@@ -420,7 +389,7 @@ portal_group_listen_iser: LISTEN_ISER STR
{
bool ok;
ok = portal_group_add_listen(portal_group, $2, true);
ok = portal_group_add_listen($2, true);
free($2);
if (!ok)
return (1);
@@ -431,7 +400,7 @@ portal_group_offload: OFFLOAD STR
{
bool ok;
ok = portal_group_set_offload(portal_group, $2);
ok = portal_group_set_offload($2);
free($2);
if (!ok)
return (1);
@@ -442,7 +411,7 @@ portal_group_option: OPTION STR STR
{
bool ok;
ok = option_new(portal_group->pg_options, $2, $3);
ok = portal_group_add_option($2, $3);
free($2);
free($3);
if (!ok)
@@ -454,7 +423,7 @@ portal_group_redirect: REDIRECT STR
{
bool ok;
ok = portal_group_set_redirection(portal_group, $2);
ok = portal_group_set_redirection($2);
free($2);
if (!ok)
return (1);
@@ -472,7 +441,7 @@ portal_group_tag: TAG STR
}
free($2);
portal_group->pg_tag = tmp;
portal_group_set_tag(tmp);
}
;
@@ -486,38 +455,35 @@ portal_group_dscp
} else if (expand_number($2, &tmp) != 0) {
yyerror("invalid numeric value");
free($2);
return(1);
return (1);
}
free($2);
if (tmp >= 0x40) {
yyerror("invalid dscp value");
return(1);
}
portal_group->pg_dscp = tmp;
if (!portal_group_set_dscp(tmp))
return (1);
}
| DSCP BE { portal_group->pg_dscp = IPTOS_DSCP_CS0 >> 2 ; }
| DSCP EF { portal_group->pg_dscp = IPTOS_DSCP_EF >> 2 ; }
| DSCP CS0 { portal_group->pg_dscp = IPTOS_DSCP_CS0 >> 2 ; }
| DSCP CS1 { portal_group->pg_dscp = IPTOS_DSCP_CS1 >> 2 ; }
| DSCP CS2 { portal_group->pg_dscp = IPTOS_DSCP_CS2 >> 2 ; }
| DSCP CS3 { portal_group->pg_dscp = IPTOS_DSCP_CS3 >> 2 ; }
| DSCP CS4 { portal_group->pg_dscp = IPTOS_DSCP_CS4 >> 2 ; }
| DSCP CS5 { portal_group->pg_dscp = IPTOS_DSCP_CS5 >> 2 ; }
| DSCP CS6 { portal_group->pg_dscp = IPTOS_DSCP_CS6 >> 2 ; }
| DSCP CS7 { portal_group->pg_dscp = IPTOS_DSCP_CS7 >> 2 ; }
| DSCP AF11 { portal_group->pg_dscp = IPTOS_DSCP_AF11 >> 2 ; }
| DSCP AF12 { portal_group->pg_dscp = IPTOS_DSCP_AF12 >> 2 ; }
| DSCP AF13 { portal_group->pg_dscp = IPTOS_DSCP_AF13 >> 2 ; }
| DSCP AF21 { portal_group->pg_dscp = IPTOS_DSCP_AF21 >> 2 ; }
| DSCP AF22 { portal_group->pg_dscp = IPTOS_DSCP_AF22 >> 2 ; }
| DSCP AF23 { portal_group->pg_dscp = IPTOS_DSCP_AF23 >> 2 ; }
| DSCP AF31 { portal_group->pg_dscp = IPTOS_DSCP_AF31 >> 2 ; }
| DSCP AF32 { portal_group->pg_dscp = IPTOS_DSCP_AF32 >> 2 ; }
| DSCP AF33 { portal_group->pg_dscp = IPTOS_DSCP_AF33 >> 2 ; }
| DSCP AF41 { portal_group->pg_dscp = IPTOS_DSCP_AF41 >> 2 ; }
| DSCP AF42 { portal_group->pg_dscp = IPTOS_DSCP_AF42 >> 2 ; }
| DSCP AF43 { portal_group->pg_dscp = IPTOS_DSCP_AF43 >> 2 ; }
| 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
@@ -530,27 +496,26 @@ portal_group_pcp: PCP STR
return (1);
}
free($2);
if (tmp > 7) {
yyerror("invalid pcp value");
return (1);
}
portal_group->pg_pcp = tmp;
if (!portal_group_set_pcp(tmp))
return (1);
}
;
lun: LUN lun_name
OPENING_BRACKET lun_entries CLOSING_BRACKET
{
lun = NULL;
lun_finish();
}
;
lun_name: STR
{
lun = lun_new(conf, $1);
bool ok;
ok = lun_start($1);
free($1);
if (lun == NULL)
if (!ok)
return (1);
}
;
@@ -558,15 +523,17 @@ lun_name: STR
target: TARGET target_name
OPENING_BRACKET target_entries CLOSING_BRACKET
{
target = NULL;
target_finish();
}
;
target_name: STR
{
target = target_new(conf, $1);
bool ok;
ok = target_start($1);
free($1);
if (target == NULL)
if (!ok)
return (1);
}
;
@@ -606,37 +573,23 @@ target_entry:
target_alias: ALIAS STR
{
if (target->t_alias != NULL) {
log_warnx("alias for target \"%s\" "
"specified more than once", target->t_name);
free($2);
bool ok;
ok = target_set_alias($2);
free($2);
if (!ok)
return (1);
}
target->t_alias = $2;
}
;
target_auth_group: AUTH_GROUP STR
{
if (target->t_auth_group != NULL) {
if (target->t_auth_group->ag_name != NULL)
log_warnx("auth-group for target \"%s\" "
"specified more than once", target->t_name);
else
log_warnx("cannot use both auth-group and explicit "
"authorisations for target \"%s\"",
target->t_name);
free($2);
return (1);
}
target->t_auth_group = auth_group_find(conf, $2);
if (target->t_auth_group == NULL) {
log_warnx("unknown auth-group \"%s\" for target "
"\"%s\"", $2, target->t_name);
free($2);
return (1);
}
bool ok;
ok = target_set_auth_group($2);
free($2);
if (!ok)
return (1);
}
;
@@ -644,23 +597,7 @@ target_auth_type: AUTH_TYPE STR
{
bool ok;
if (target->t_auth_group != NULL) {
if (target->t_auth_group->ag_name != NULL) {
log_warnx("cannot use both auth-group and "
"auth-type for target \"%s\"",
target->t_name);
free($2);
return (1);
}
} else {
target->t_auth_group = auth_group_new(conf, NULL);
if (target->t_auth_group == NULL) {
free($2);
return (1);
}
target->t_auth_group->ag_target = target;
}
ok = auth_group_set_type(target->t_auth_group, $2);
ok = target_set_auth_type($2);
free($2);
if (!ok)
return (1);
@@ -669,183 +606,81 @@ target_auth_type: AUTH_TYPE STR
target_chap: CHAP STR STR
{
const struct auth *ca;
bool ok;
if (target->t_auth_group != NULL) {
if (target->t_auth_group->ag_name != NULL) {
log_warnx("cannot use both auth-group and "
"chap for target \"%s\"",
target->t_name);
free($2);
free($3);
return (1);
}
} else {
target->t_auth_group = auth_group_new(conf, NULL);
if (target->t_auth_group == NULL) {
free($2);
free($3);
return (1);
}
target->t_auth_group->ag_target = target;
}
ca = auth_new_chap(target->t_auth_group, $2, $3);
ok = target_add_chap($2, $3);
free($2);
free($3);
if (ca == NULL)
if (!ok)
return (1);
}
;
target_chap_mutual: CHAP_MUTUAL STR STR STR STR
{
const struct auth *ca;
bool ok;
if (target->t_auth_group != NULL) {
if (target->t_auth_group->ag_name != NULL) {
log_warnx("cannot use both auth-group and "
"chap-mutual for target \"%s\"",
target->t_name);
free($2);
free($3);
free($4);
free($5);
return (1);
}
} else {
target->t_auth_group = auth_group_new(conf, NULL);
if (target->t_auth_group == NULL) {
free($2);
free($3);
free($4);
free($5);
return (1);
}
target->t_auth_group->ag_target = target;
}
ca = auth_new_chap_mutual(target->t_auth_group,
$2, $3, $4, $5);
ok = target_add_chap_mutual($2, $3, $4, $5);
free($2);
free($3);
free($4);
free($5);
if (ca == NULL)
if (!ok)
return (1);
}
;
target_initiator_name: INITIATOR_NAME STR
{
const struct auth_name *an;
bool ok;
if (target->t_auth_group != NULL) {
if (target->t_auth_group->ag_name != NULL) {
log_warnx("cannot use both auth-group and "
"initiator-name for target \"%s\"",
target->t_name);
free($2);
return (1);
}
} else {
target->t_auth_group = auth_group_new(conf, NULL);
if (target->t_auth_group == NULL) {
free($2);
return (1);
}
target->t_auth_group->ag_target = target;
}
an = auth_name_new(target->t_auth_group, $2);
ok = target_add_initiator_name($2);
free($2);
if (an == NULL)
if (!ok)
return (1);
}
;
target_initiator_portal: INITIATOR_PORTAL STR
{
const struct auth_portal *ap;
bool ok;
if (target->t_auth_group != NULL) {
if (target->t_auth_group->ag_name != NULL) {
log_warnx("cannot use both auth-group and "
"initiator-portal for target \"%s\"",
target->t_name);
free($2);
return (1);
}
} else {
target->t_auth_group = auth_group_new(conf, NULL);
if (target->t_auth_group == NULL) {
free($2);
return (1);
}
target->t_auth_group->ag_target = target;
}
ap = auth_portal_new(target->t_auth_group, $2);
ok = target_add_initiator_portal($2);
free($2);
if (ap == NULL)
if (!ok)
return (1);
}
;
target_portal_group: PORTAL_GROUP STR STR
{
struct portal_group *tpg;
struct auth_group *tag;
struct port *tp;
bool ok;
tpg = portal_group_find(conf, $2);
if (tpg == NULL) {
log_warnx("unknown portal-group \"%s\" for target "
"\"%s\"", $2, target->t_name);
free($2);
free($3);
return (1);
}
ok = target_add_portal_group($2, $3);
free($2);
tag = auth_group_find(conf, $3);
if (tag == NULL) {
log_warnx("unknown auth-group \"%s\" for target "
"\"%s\"", $3, target->t_name);
free($3);
return (1);
}
free($3);
tp = port_new(conf, target, tpg);
if (tp == NULL) {
log_warnx("can't link portal-group \"%s\" to target "
"\"%s\"", tpg->pg_name, target->t_name);
if (!ok)
return (1);
}
tp->p_auth_group = tag;
}
| PORTAL_GROUP STR
{
struct portal_group *tpg;
struct port *tp;
bool ok;
tpg = portal_group_find(conf, $2);
if (tpg == NULL) {
log_warnx("unknown portal-group \"%s\" for target "
"\"%s\"", $2, target->t_name);
free($2);
return (1);
}
ok = target_add_portal_group($2, NULL);
free($2);
tp = port_new(conf, target, tpg);
if (tp == NULL) {
log_warnx("can't link portal-group \"%s\" to target "
"\"%s\"", tpg->pg_name, target->t_name);
if (!ok)
return (1);
}
}
;
target_port: PORT STR
{
target->t_pport = strdup($2);
bool ok;
ok = target_set_physical_port($2);
free($2);
if (!ok)
return (1);
}
;
@@ -853,7 +688,7 @@ target_redirect: REDIRECT STR
{
bool ok;
ok = target_set_redirection(target, $2);
ok = target_set_redirection($2);
free($2);
if (!ok)
return (1);
@@ -863,15 +698,13 @@ target_redirect: REDIRECT STR
target_lun: LUN lun_number
OPENING_BRACKET lun_entries CLOSING_BRACKET
{
lun = NULL;
lun_finish();
}
;
lun_number: STR
{
uint64_t tmp;
int ret;
char *name;
if (expand_number($1, &tmp) != 0) {
yyerror("invalid numeric value");
@@ -879,26 +712,16 @@ lun_number: STR
return (1);
}
free($1);
if (tmp >= MAX_LUNS) {
yyerror("LU number is too big");
return (1);
}
ret = asprintf(&name, "%s,lun,%ju", target->t_name, tmp);
if (ret <= 0)
log_err(1, "asprintf");
lun = lun_new(conf, name);
if (lun == NULL)
if (!target_start_lun(tmp))
return (1);
lun_set_scsiname(lun, name);
target->t_luns[tmp] = lun;
}
;
target_lun_ref: LUN STR STR
{
uint64_t tmp;
bool ok;
if (expand_number($2, &tmp) != 0) {
yyerror("invalid numeric value");
@@ -907,18 +730,11 @@ target_lun_ref: LUN STR STR
return (1);
}
free($2);
if (tmp >= MAX_LUNS) {
yyerror("LU number is too big");
free($3);
return (1);
}
lun = lun_find(conf, $3);
ok = target_add_lun(tmp, $3);
free($3);
if (lun == NULL)
if (!ok)
return (1);
target->t_luns[tmp] = lun;
}
;
@@ -951,15 +767,12 @@ lun_entry:
lun_backend: BACKEND STR
{
if (lun->l_backend != NULL) {
log_warnx("backend for lun \"%s\" "
"specified more than once",
lun->l_name);
free($2);
return (1);
}
lun_set_backend(lun, $2);
bool ok;
ok = lun_set_backend($2);
free($2);
if (!ok)
return (1);
}
;
@@ -974,53 +787,30 @@ lun_blocksize: BLOCKSIZE STR
}
free($2);
if (lun->l_blocksize != 0) {
log_warnx("blocksize for lun \"%s\" "
"specified more than once",
lun->l_name);
if (!lun_set_blocksize(tmp))
return (1);
}
lun_set_blocksize(lun, tmp);
}
;
lun_device_id: DEVICE_ID STR
{
if (lun->l_device_id != NULL) {
log_warnx("device_id for lun \"%s\" "
"specified more than once",
lun->l_name);
free($2);
return (1);
}
lun_set_device_id(lun, $2);
bool ok;
ok = lun_set_device_id($2);
free($2);
if (!ok)
return (1);
}
;
lun_device_type: DEVICE_TYPE STR
{
uint64_t tmp;
bool ok;
if (strcasecmp($2, "disk") == 0 ||
strcasecmp($2, "direct") == 0)
tmp = 0;
else if (strcasecmp($2, "processor") == 0)
tmp = 3;
else if (strcasecmp($2, "cd") == 0 ||
strcasecmp($2, "cdrom") == 0 ||
strcasecmp($2, "dvd") == 0 ||
strcasecmp($2, "dvdrom") == 0)
tmp = 5;
else if (expand_number($2, &tmp) != 0 ||
tmp > 15) {
yyerror("invalid numeric value");
free($2);
return (1);
}
ok = lun_set_device_type($2);
free($2);
lun_set_device_type(lun, tmp);
if (!ok)
return (1);
}
;
@@ -1035,13 +825,8 @@ lun_ctl_lun: CTL_LUN STR
}
free($2);
if (lun->l_ctl_lun >= 0) {
log_warnx("ctl_lun for lun \"%s\" "
"specified more than once",
lun->l_name);
if (!lun_set_ctl_lun(tmp))
return (1);
}
lun_set_ctl_lun(lun, tmp);
}
;
@@ -1049,7 +834,7 @@ lun_option: OPTION STR STR
{
bool ok;
ok = option_new(lun->l_options, $2, $3);
ok = lun_add_option($2, $3);
free($2);
free($3);
if (!ok)
@@ -1059,29 +844,23 @@ lun_option: OPTION STR STR
lun_path: PATH STR
{
if (lun->l_path != NULL) {
log_warnx("path for lun \"%s\" "
"specified more than once",
lun->l_name);
free($2);
return (1);
}
lun_set_path(lun, $2);
bool ok;
ok = lun_set_path($2);
free($2);
if (!ok)
return (1);
}
;
lun_serial: SERIAL STR
{
if (lun->l_serial != NULL) {
log_warnx("serial for lun \"%s\" "
"specified more than once",
lun->l_name);
free($2);
return (1);
}
lun_set_serial(lun, $2);
bool ok;
ok = lun_set_serial($2);
free($2);
if (!ok)
return (1);
}
;
@@ -1096,13 +875,8 @@ lun_size: SIZE STR
}
free($2);
if (lun->l_size != 0) {
log_warnx("size for lun \"%s\" "
"specified more than once",
lun->l_name);
if (!lun_set_size(tmp))
return (1);
}
lun_set_size(lun, tmp);
}
;
%%
@@ -1116,11 +890,10 @@ yyerror(const char *str)
}
bool
parse_conf(struct conf *newconf, const char *path)
parse_conf(const char *path)
{
int error;
conf = newconf;
yyin = fopen(path, "r");
if (yyin == NULL) {
log_warn("unable to open configuration file %s", path);
@@ -1130,10 +903,6 @@ parse_conf(struct conf *newconf, const char *path)
lineno = 1;
yyrestart(yyin);
error = yyparse();
auth_group = NULL;
portal_group = NULL;
target = NULL;
lun = NULL;
fclose(yyin);
return (error == 0);
+313 -392
View File
File diff suppressed because it is too large Load Diff