aboutsummaryrefslogtreecommitdiff
path: root/usr.sbin/ctld/ctld.hh
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/ctld/ctld.hh')
-rw-r--r--usr.sbin/ctld/ctld.hh181
1 files changed, 108 insertions, 73 deletions
diff --git a/usr.sbin/ctld/ctld.hh b/usr.sbin/ctld/ctld.hh
index 059f719668f9..3bf18f6a32c0 100644
--- a/usr.sbin/ctld/ctld.hh
+++ b/usr.sbin/ctld/ctld.hh
@@ -56,7 +56,6 @@
#define DEFAULT_CD_BLOCKSIZE 2048
#define MAX_LUNS 1024
-#define SOCKBUF_SIZE 1048576
struct isns_req;
struct port;
@@ -111,6 +110,12 @@ struct auth_group {
const char *user2, const char *secret2);
const struct auth *find_auth(std::string_view user) const;
+ bool add_host_nqn(std::string_view nqn);
+ bool host_permitted(std::string_view nqn) const;
+
+ bool add_host_address(const char *address);
+ bool host_permitted(const struct sockaddr *sa) const;
+
bool add_initiator_name(std::string_view initiator_name);
bool initiator_permitted(std::string_view initiator_name) const;
@@ -124,24 +129,39 @@ private:
std::string ag_label;
auth_type ag_type = auth_type::UNKNOWN;
std::unordered_map<std::string, auth> ag_auths;
- std::unordered_set<std::string> ag_names;
- std::list<auth_portal> ag_portals;
+ std::unordered_set<std::string> ag_host_names;
+ std::list<auth_portal> ag_host_addresses;
+ std::unordered_set<std::string> ag_initiator_names;
+ std::list<auth_portal> ag_initiator_portals;
};
using auth_group_sp = std::shared_ptr<auth_group>;
+enum class portal_protocol {
+ ISCSI,
+ ISER,
+ NVME_TCP,
+ NVME_DISCOVERY_TCP,
+};
+
struct portal {
- portal(struct portal_group *pg, std::string_view listen, bool iser,
- freebsd::addrinfo_up ai) :
+ portal(struct portal_group *pg, std::string_view listen,
+ portal_protocol protocol, freebsd::addrinfo_up ai) :
p_portal_group(pg), p_listen(listen), p_ai(std::move(ai)),
- p_iser(iser) {}
+ p_protocol(protocol) {}
+ virtual ~portal() = default;
+ virtual bool prepare() { return true; }
bool reuse_socket(portal &oldp);
bool init_socket();
+ virtual bool init_socket_options(int s __unused) { return true; }
+ virtual void handle_connection(freebsd::fd_up fd, const char *host,
+ const struct sockaddr *client_sa) = 0;
- portal_group *portal_group() { return p_portal_group; }
+ struct portal_group *portal_group() const { return p_portal_group; }
const char *listen() const { return p_listen.c_str(); }
const addrinfo *ai() const { return p_ai.get(); }
+ portal_protocol protocol() const { return p_protocol; }
int socket() const { return p_socket; }
void close() { p_socket.reset(); }
@@ -149,12 +169,13 @@ private:
struct portal_group *p_portal_group;
std::string p_listen;
freebsd::addrinfo_up p_ai;
- bool p_iser;
+ portal_protocol p_protocol;
freebsd::fd_up p_socket;
};
using portal_up = std::unique_ptr<portal>;
+using port_up = std::unique_ptr<port>;
enum class discovery_filter {
UNKNOWN,
@@ -166,15 +187,17 @@ enum class discovery_filter {
struct portal_group {
portal_group(struct conf *conf, std::string_view name);
+ virtual ~portal_group() = default;
struct conf *conf() const { return pg_conf; }
+ virtual const char *keyword() const = 0;
const char *name() const { return pg_name.c_str(); }
bool assigned() const { return pg_assigned; }
bool is_dummy() const;
bool is_redirecting() const { return !pg_redirection.empty(); }
struct auth_group *discovery_auth_group() const
{ return pg_discovery_auth_group.get(); }
- discovery_filter discovery_filter() const
+ enum discovery_filter discovery_filter() const
{ return pg_discovery_filter; }
int dscp() const { return pg_dscp; }
const char *offload() const { return pg_offload.c_str(); }
@@ -188,17 +211,25 @@ struct portal_group {
const std::unordered_map<std::string, port *> &ports() const
{ return pg_ports; }
- bool add_portal(const char *value, bool iser);
+ virtual void allocate_tag() = 0;
+ virtual bool add_portal(const char *value,
+ portal_protocol protocol) = 0;
+ virtual void add_default_portals() = 0;
bool add_option(const char *name, const char *value);
bool set_discovery_auth_group(const char *name);
bool set_dscp(u_int dscp);
- bool set_filter(const char *str);
+ virtual bool set_filter(const char *str) = 0;
void set_foreign();
bool set_offload(const char *offload);
bool set_pcp(u_int pcp);
bool set_redirection(const char *addr);
void set_tag(uint16_t tag);
+ virtual port_up create_port(struct target *target, auth_group_sp ag) =
+ 0;
+ virtual port_up create_port(struct target *target, uint32_t ctl_port) =
+ 0;
+
void add_port(struct portal_group_port *port);
const struct port *find_port(std::string_view target) const;
void remove_port(struct portal_group_port *port);
@@ -208,9 +239,10 @@ struct portal_group {
int open_sockets(struct conf &oldconf);
void close_sockets();
-private:
+protected:
struct conf *pg_conf;
freebsd::nvlist_up pg_options;
+ const char *pg_keyword;
std::string pg_name;
auth_group_sp pg_discovery_auth_group;
enum discovery_filter pg_discovery_filter =
@@ -254,7 +286,7 @@ protected:
uint32_t p_ctl_port = 0;
};
-struct portal_group_port final : public port {
+struct portal_group_port : public port {
portal_group_port(struct target *target, struct portal_group *pg,
auth_group_sp ag);
portal_group_port(struct target *target, struct portal_group *pg,
@@ -270,10 +302,7 @@ struct portal_group_port final : public port {
void clear_references() override;
- bool kernel_create_port() override;
- bool kernel_remove_port() override;
-
-private:
+protected:
auth_group_sp p_auth_group;
struct portal_group *p_portal_group;
};
@@ -348,14 +377,15 @@ private:
};
struct target {
- target(struct conf *conf, std::string_view name) :
- t_conf(conf), t_name(name) {}
+ target(struct conf *conf, const char *keyword, std::string_view name);
+ virtual ~target() = default;
bool has_alias() const { return !t_alias.empty(); }
bool has_pport() const { return !t_pport.empty(); }
bool has_redirection() const { return !t_redirection.empty(); }
const char *alias() const { return t_alias.c_str(); }
const char *name() const { return t_name.c_str(); }
+ const char *label() const { return t_label.c_str(); }
const char *pport() const { return t_pport.c_str(); }
bool private_auth() const { return t_private_auth; }
const char *redirection() const { return t_redirection.c_str(); }
@@ -367,37 +397,49 @@ struct target {
bool add_chap(const char *user, const char *secret);
bool add_chap_mutual(const char *user, const char *secret,
const char *user2, const char *secret2);
- bool add_initiator_name(std::string_view name);
- bool add_initiator_portal(const char *addr);
- bool add_lun(u_int id, const char *lun_name);
- bool add_portal_group(const char *pg_name, const char *ag_name);
+ virtual bool add_host_address(const char *) { return false; }
+ virtual bool add_host_nqn(std::string_view) { return false; }
+ virtual bool add_initiator_name(std::string_view) { return false; }
+ virtual bool add_initiator_portal(const char *) { return false; }
+ virtual bool add_lun(u_int, const char *) { return false; }
+ virtual bool add_namespace(u_int, const char *) { return false; }
+ virtual bool add_portal_group(const char *pg_name,
+ const char *ag_name) = 0;
bool set_alias(std::string_view alias);
bool set_auth_group(const char *ag_name);
bool set_auth_type(const char *type);
bool set_physical_port(std::string_view pport);
bool set_redirection(const char *addr);
- struct lun *start_lun(u_int id);
+ virtual struct lun *start_lun(u_int) { return nullptr; }
+ virtual struct lun *start_namespace(u_int) { return nullptr; }
void add_port(struct port *port);
void remove_lun(struct lun *lun);
void remove_port(struct port *port);
void verify();
-private:
+protected:
bool use_private_auth(const char *keyword);
+ bool add_lun(u_int id, const char *lun_label, const char *lun_name);
+ struct lun *start_lun(u_int id, const char *lun_label,
+ const char *lun_name);
+ virtual struct portal_group *default_portal_group() = 0;
struct conf *t_conf;
- std::array<struct lun *, MAX_LUNS> t_luns;
+ std::array<struct lun *, MAX_LUNS> t_luns = {};
auth_group_sp t_auth_group;
std::list<port *> t_ports;
std::string t_name;
+ std::string t_label;
std::string t_alias;
std::string t_redirection;
/* Name of this target's physical port, if any, i.e. "isp0" */
std::string t_pport;
- bool t_private_auth;
+ bool t_private_auth = false;
};
+using target_up = std::unique_ptr<target>;
+
struct isns {
isns(std::string_view addr, freebsd::addrinfo_up ai) :
i_addr(addr), i_ai(std::move(ai)) {}
@@ -413,13 +455,18 @@ private:
};
struct conf {
+ conf();
+
int maxproc() const { return conf_maxproc; }
int timeout() const { return conf_timeout; }
+ uint32_t genctr() const { return conf_genctr; }
bool default_auth_group_defined() const
{ return conf_default_ag_defined; }
bool default_portal_group_defined() const
{ return conf_default_pg_defined; }
+ bool default_transport_group_defined() const
+ { return conf_default_tg_defined; }
struct auth_group *add_auth_group(const char *ag_name);
struct auth_group *define_default_auth_group();
@@ -429,6 +476,10 @@ struct conf {
struct portal_group *define_default_portal_group();
struct portal_group *find_portal_group(std::string_view name);
+ struct portal_group *add_transport_group(const char *name);
+ struct portal_group *define_default_transport_group();
+ struct portal_group *find_transport_group(std::string_view name);
+
bool add_port(struct target *target, struct portal_group *pg,
auth_group_sp ag);
bool add_port(struct target *target, struct portal_group *pg,
@@ -438,6 +489,9 @@ struct conf {
int vp);
bool add_pports(struct kports &kports);
+ struct target *add_controller(const char *name);
+ struct target *find_controller(std::string_view name);
+
struct target *add_target(const char *name);
struct target *find_target(std::string_view name);
@@ -474,10 +528,12 @@ private:
std::string conf_pidfile_path;
std::unordered_map<std::string, std::unique_ptr<lun>> conf_luns;
- std::unordered_map<std::string, std::unique_ptr<target>> conf_targets;
+ std::unordered_map<std::string, target_up> conf_targets;
+ std::unordered_map<std::string, target_up> conf_controllers;
std::unordered_map<std::string, auth_group_sp> conf_auth_groups;
std::unordered_map<std::string, std::unique_ptr<port>> conf_ports;
std::unordered_map<std::string, portal_group_up> conf_portal_groups;
+ std::unordered_map<std::string, portal_group_up> conf_transport_groups;
std::unordered_map<std::string, isns> conf_isns;
struct target *conf_first_target = nullptr;
int conf_isns_period = 900;
@@ -485,12 +541,16 @@ private:
int conf_debug = 0;
int conf_timeout = 60;
int conf_maxproc = 30;
+ uint32_t conf_genctr = 0;
freebsd::pidfile conf_pidfile;
bool conf_default_pg_defined = false;
+ bool conf_default_tg_defined = false;
bool conf_default_ag_defined = false;
+ static uint32_t global_genctr;
+
#ifdef ICL_KERNEL_PROXY
public:
int add_proxy_portal(portal *);
@@ -516,7 +576,7 @@ struct pport {
private:
std::string pp_name;
uint32_t pp_ctl_port;
- bool pp_linked;
+ bool pp_linked = false;
};
struct kports {
@@ -528,50 +588,7 @@ private:
std::unordered_map<std::string, struct pport> pports;
};
-#define CONN_SESSION_TYPE_NONE 0
-#define CONN_SESSION_TYPE_DISCOVERY 1
-#define CONN_SESSION_TYPE_NORMAL 2
-
-struct ctld_connection {
- ctld_connection(struct portal *portal, int fd, const char *host,
- const struct sockaddr *client_sa);
- ~ctld_connection();
-
- int session_type() const { return conn_session_type; }
-
- void login();
- void discovery();
- void kernel_handoff();
-private:
- void login_chap(struct auth_group *ag);
- void login_negotiate_key(struct pdu *request, const char *name,
- const char *value, bool skipped_security,
- struct keys *response_keys);
- bool login_portal_redirect(struct pdu *request);
- bool login_target_redirect(struct pdu *request);
- void login_negotiate(struct pdu *request);
- void login_wait_transition();
-
- bool discovery_target_filtered_out(const struct port *port) const;
-
- struct connection conn;
- struct portal *conn_portal = nullptr;
- const struct port *conn_port = nullptr;
- struct target *conn_target = nullptr;
- int conn_session_type = CONN_SESSION_TYPE_NONE;
- std::string conn_initiator_name;
- std::string conn_initiator_addr;
- std::string conn_initiator_alias;
- uint8_t conn_initiator_isid[6];
- const struct sockaddr *conn_initiator_sa = nullptr;
- int conn_max_recv_data_segment_limit = 0;
- int conn_max_send_data_segment_limit = 0;
- int conn_max_burst_limit = 0;
- int conn_first_burst_limit = 0;
- std::string conn_user;
- struct chap *conn_chap = nullptr;
-};
-
+extern bool proxy_mode;
extern int ctl_fd;
bool parse_conf(const char *path);
@@ -584,6 +601,9 @@ void conf_start(struct conf *new_conf);
bool option_new(nvlist_t *nvl,
const char *name, const char *value);
+freebsd::addrinfo_up parse_addr_port(const char *address,
+ const char *def_port);
+
void kernel_init(void);
void kernel_capsicate(void);
@@ -597,7 +617,22 @@ void kernel_send(struct pdu *pdu);
void kernel_receive(struct pdu *pdu);
#endif
+bool ctl_create_port(const char *driver,
+ const nvlist_t *nvl, uint32_t *ctl_port);
+bool ctl_remove_port(const char *driver, nvlist_t *nvl);
+
+portal_group_up iscsi_make_portal_group(struct conf *conf,
+ std::string_view name);
+target_up iscsi_make_target(struct conf *conf,
+ std::string_view name);
+
+portal_group_up nvmf_make_transport_group(struct conf *conf,
+ std::string_view name);
+target_up nvmf_make_controller(struct conf *conf,
+ std::string_view name);
+
void start_timer(int timeout, bool fatal = false);
void stop_timer();
+bool timed_out();
#endif /* !__CTLD_HH__ */