1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 /*
  26  * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
  27  */
  28 
  29 #ifndef _LIBISCSIT_H
  30 #define _LIBISCSIT_H
  31 
  32 #ifndef _KERNEL
  33 #include <libnvpair.h>
  34 #include <sys/socket.h>
  35 #endif
  36 
  37 #include <sys/iscsit/iscsit_common.h>
  38 
  39 #ifdef  __cplusplus
  40 extern "C" {
  41 #endif
  42 
  43 #define MAX_TARGETS     4095 /* maximum targets that may be created */
  44 #define MAX_TPGT        256
  45 #define CFG_TPGTLIST    "tpgt-list"
  46 
  47 #define IS_IQN_NAME(s) (strncmp((s), "iqn.", 4) == 0)
  48 #define IS_EUI_NAME(s) (strncmp((s), "eui.", 4) == 0)
  49 
  50 /*
  51  * We change the default IQN here to org.illumos.
  52  * Other distros using it need to change accordingly.
  53  */
  54 
  55 #define DEFAULT_IQN     "iqn.2005-07.com.nexenta:"
  56 
  57 /*
  58  * Object Hierarchy
  59  *
  60  *  _______________________
  61  * |                       |
  62  * |  iSCSI Target Config  |
  63  * |      it_config_t      |
  64  * |_______________________|
  65  *    |     |
  66  *    |     |
  67  *    |     |      ________     ________              ________
  68  *    |     |     |        |   |        |            |        |
  69  *    |     |     | Target |-->| Target |--  - -  -->| Target |
  70  *    |     |     |________|   |________|            |________|
  71  *    |     |           |
  72  *    |     |           |
  73  *    |     |           |
  74  *    |     |           |       ______              ______
  75  *    |     |           |      |      |            |      |
  76  *    |     |           +----->| TPGT |--  - -  -->| TPGT |
  77  *    |     |                  |______|            |______|
  78  *    |     |                       |                   |
  79  *    |  +--+                       |                   |
  80  *    |  |   _______     _______    |         ______    |
  81  *    |  |  |       |   |       |<--+        |      |<--+
  82  *    |  +->|  TPG  |-->|  TPG  |--  - -  -->| TPG  |
  83  *    |     |_______|   |_______|            |______|
  84  *    |
  85  *    |      ___________     ___________              ___________
  86  *    |     |           |   |           |            |           |
  87  *    +---->| Initiator |-->| Initiator |--  - -  -->| Initiator |
  88  *          |  Context  |   |  Context  |            |  Context  |
  89  *          |___________|   |___________|            |___________|
  90  *
  91  *
  92  * it_config_t includes a list of global properties
  93  *
  94  * Targets include a list of properties which override the global properties
  95  * if set
  96  *
  97  * Initiators also include a list of properties but never inherit properties
  98  * from the global config.
  99  */
 100 
 101 /*
 102  * Function:  it_config_load()
 103  *
 104  * Allocate and create an it_config_t structure representing the
 105  * current iSCSI configuration.  This structure is compiled using
 106  * the 'provider' data returned by stmfGetProviderData().  If there
 107  * is no provider data associated with iscsit, the it_config_t
 108  * structure will be set to a default configuration.
 109  *
 110  * Parameters:
 111  *    cfg               A C representation of the current iSCSI configuration
 112  *
 113  * Return Values:
 114  *    0                 Success
 115  *    ENOMEM            Could not allocate resources
 116  *    EINVAL            Invalid parameter
 117  */
 118 int
 119 it_config_load(it_config_t **cfg);
 120 
 121 /*
 122  * Function:  it_config_commit()
 123  *
 124  * Informs the iscsit service that the configuration has changed and
 125  * commits the new configuration to persistent store by calling
 126  * stmfSetProviderData.  This function can be called multiple times
 127  * during a configuration sequence if necessary.
 128  *
 129  * Parameters:
 130  *    cfg               A C representation of the current iSCSI configuration
 131  *
 132  * Return Values:
 133  *    0                 Success
 134  *    ENOMEM            Could not allocate resources
 135  *    EINVAL            Invalid it_config_t structure
 136  *    STMF_ERROR_SERVICE_DATA_VERSION   Configuration was updated by another
 137  *                      client.  See stmfSetProviderDataProt().
 138  */
 139 int
 140 it_config_commit(it_config_t *cfg);
 141 
 142 /*
 143  * Function:  it_config_setprop()
 144  *
 145  * Validate the provided property list and set the global properties
 146  * for iSCSI Target.  If errlist is not NULL, returns detailed
 147  * errors for each property that failed.  The format for errorlist
 148  * is key = property, value = error string.
 149  *
 150  * Parameters:
 151  *
 152  *    cfg               The current iSCSI configuration obtained from
 153  *                      it_config_load()
 154  *    proplist          nvlist_t containing properties for this target.
 155  *    errlist           (optional)  nvlist_t of errors encountered when
 156  *                      validating the properties.
 157  *
 158  * Return Values:
 159  *    0                 Success
 160  *    ENOMEM            Could not allocate resources
 161  *    EINVAL            Invalid property
 162  *
 163  */
 164 int
 165 it_config_setprop(it_config_t *cfg, nvlist_t *proplist, nvlist_t **errlist);
 166 
 167 /*
 168  * Function:  it_config_free()
 169  *
 170  * Free any resources associated with the it_config_t structure.
 171  *
 172  * Parameters:
 173  *    cfg               A C representation of the current iSCSI configuration
 174  */
 175 void
 176 it_config_free(it_config_t *cfg);
 177 
 178 /*
 179  * Function:  it_tgt_create()
 180  *
 181  * Allocate and create an it_tgt_t structure representing a new iSCSI
 182  * target node.  If tgt_name is NULL, then a unique target node name will
 183  * be generated automatically.  Otherwise, the value of tgt_name will be
 184  * used as the target node name.  The new it_tgt_t structure is added to
 185  * the target list (cfg_tgt_list) in the configuration structure, and the
 186  * new target will not be instantiated until the modified configuration
 187  * is committed by calling it_config_commit().
 188  *
 189  * Parameters:
 190  *    cfg               The current iSCSI configuration obtained from
 191  *                      it_config_load()
 192  *    tgt               Pointer to an iSCSI target structure
 193  *    tgt_name          The target node name for the target to be created.
 194  *                      The name must be in either IQN or EUI format.  If
 195  *                      this value is NULL, a node name will be generated
 196  *                      automatically in IQN format.
 197  *
 198  * Return Values:
 199  *    0                 Success
 200  *    ENOMEM            Could not allocate resources
 201  *    EINVAL            Invalid parameter or creating would create too many
 202  *                      targets.
 203  *    EEXIST            The requested target node name is already configured
 204  *    EFAULT            Invalid iSCSI target name
 205  */
 206 int
 207 it_tgt_create(it_config_t *cfg, it_tgt_t **tgt, char *tgt_name);
 208 
 209 /*
 210  * Function:  it_tgt_setprop()
 211  *
 212  * Validate the provided property list and set the properties for
 213  * the specified target.  If errlist is not NULL, returns detailed
 214  * errors for each property that failed.  The format for errorlist
 215  * is key = property, value = error string.
 216  *
 217  * Parameters:
 218  *
 219  *    cfg               The current iSCSI configuration obtained from
 220  *                      it_config_load()
 221  *    tgt               Pointer to an iSCSI target structure
 222  *    proplist          nvlist_t containing properties for this target.
 223  *    errlist           (optional)  nvlist_t of errors encountered when
 224  *                      validating the properties.
 225  *
 226  * Return Values:
 227  *    0                 Success
 228  *    ENOMEM            Could not allocate resources
 229  *    EINVAL            Invalid property
 230  *
 231  */
 232 int
 233 it_tgt_setprop(it_config_t *cfg, it_tgt_t *tgt, nvlist_t *proplist,
 234     nvlist_t **errlist);
 235 
 236 
 237 /*
 238  * Function:  it_tgt_delete()
 239  *
 240  * Delete target represented by 'tgt', where 'tgt' is an existing
 241  * it_tgt_t structure within the configuration 'cfg'.  The target removal
 242  * will not take effect until the modified configuration is committed
 243  * by calling it_config_commit().
 244  *
 245  * Parameters:
 246  *    cfg               The current iSCSI configuration obtained from
 247  *                      it_config_load()
 248  *    tgt               Pointer to an iSCSI target structure
 249  *    force             Set the target to offline before removing it from
 250  *                      the config.  If not specified, the operation will
 251  *                      fail if the target is determined to be online.
 252  *
 253  * Return Values:
 254  *    0                 Success
 255  *    EBUSY             Target is online
 256  */
 257 int
 258 it_tgt_delete(it_config_t *cfg, it_tgt_t *tgt, boolean_t force);
 259 
 260 /*
 261  * Function:  it_tpgt_create()
 262  *
 263  * Allocate and create an it_tpgt_t structure representing a new iSCSI
 264  * target portal group tag.  The new it_tpgt_t structure is added to the
 265  * target tpgt list (tgt_tpgt_list) in the it_tgt_t structure.  The new
 266  * target portal group tag will not be instantiated until the modified
 267  * configuration is committed by calling it_config_commit().
 268  *
 269  * Parameters:
 270  *    cfg               The current iSCSI configuration obtained from
 271  *                      it_config_load()
 272  *    tgt               Pointer to the iSCSI target structure associated
 273  *                      with the target portal group tag
 274  *    tpgt              Pointer to a target portal group tag structure
 275  *    tpg_name          The name of the TPG to be associated with this TPGT
 276  *    tpgt_tag          16-bit numerical identifier for this TPGT.  Valid
 277  *                      values are 2 through 65535.  If tpgt_tag is '0',
 278  *                      this function will assign an appropriate tag number.
 279  *                      If tpgt_tag is != 0, and the requested number is
 280  *                      unavailable, another value will be chosen.
 281  *
 282  * Return Values:
 283  *    0                 Success
 284  *    ENOMEM            Could not allocate resources
 285  *    EINVAL            Invalid parameter
 286  *    EEXIST            Specified TPG is already associated with the target
 287  *    E2BIG             All tag numbers already in use
 288  */
 289 int
 290 it_tpgt_create(it_config_t *cfg, it_tgt_t *tgt, it_tpgt_t **tpgt,
 291     char *tpg_name, uint16_t tpgt_tag);
 292 
 293 /*
 294  * Function:  it_tpgt_delete()
 295  *
 296  * Delete the target portal group tag represented by 'tpgt', where
 297  * 'tpgt' is an existing is_tpgt_t structure within the target 'tgt'.
 298  * The target portal group tag removal will not take effect until the
 299  * modified configuation is committed by calling it_config_commit().
 300  *
 301  * Parameters:
 302  *    cfg               The current iSCSI configuration obtained from
 303  *                      it_config_load()
 304  *    tgt               Pointer to the iSCSI target structure associated
 305  *                      with the target portal group tag
 306  *    tpgt              Pointer to a target portal group tag structure
 307  */
 308 void
 309 it_tpgt_delete(it_config_t *cfg, it_tgt_t *tgt, it_tpgt_t *tpgt);
 310 
 311 /*
 312  * Function:  it_tpg_create()
 313  *
 314  * Allocate and create an it_tpg_t structure representing a new iSCSI
 315  * target portal group.  The new it_tpg_t structure is added to the global
 316  * tpg list (cfg_tgt_list) in the it_config_t structure.  The new target
 317  * portal group will not be instantiated until the modified configuration
 318  * is committed by calling it_config_commit().
 319  *
 320  * Parameters:
 321  *    cfg               The current iSCSI configuration obtained from
 322  *                      it_config_load()
 323  *    tpg               Pointer to the it_tpg_t structure representing
 324  *                      the target portal group
 325  *    tpg_name          Identifier for the target portal group
 326  *    portal_ip_port    A string containing an appropriatedly formatted
 327  *                      IP address:port.  Both IPv4 and IPv6 addresses are
 328  *                      permitted.  This value becomes the first portal in
 329  *                      the TPG -- applications can add additional values
 330  *                      using it_portal_create() before committing the TPG.
 331  * Return Values:
 332  *    0                 Success
 333  *    ENOMEM            Cannot allocate resources
 334  *    EINVAL            Invalid parameter
 335  *    EEXIST            Portal already configured for another portal group
 336  *                      associated with this target.
 337  */
 338 int
 339 it_tpg_create(it_config_t *cfg, it_tpg_t **tpg, char *tpg_name,
 340     char *portal_ip_port);
 341 
 342 /*
 343  * Function:  it_tpg_delete()
 344  *
 345  * Delete target portal group represented by 'tpg', where 'tpg' is an
 346  * existing it_tpg_t structure within the global configuration 'cfg'.
 347  * The target portal group removal will not take effect until the
 348  * modified configuration is committed by calling it_config_commit().
 349  *
 350  * Parameters:
 351  *    cfg               The current iSCSI configuration obtained from
 352  *                      it_config_load()
 353  *    tpg               Pointer to the it_tpg_t structure representing
 354  *                      the target portal group
 355  *    force             Remove this target portal group even if it's
 356  *                      associated with one or more targets.
 357  *
 358  * Return Values:
 359  *    0                 Success
 360  *    EINVAL            Invalid parameter
 361  *    EBUSY             Portal group associated with one or more targets.
 362  */
 363 int
 364 it_tpg_delete(it_config_t *cfg, it_tpg_t *tpg, boolean_t force);
 365 
 366 /*
 367  * Function:  it_portal_create()
 368  *
 369  * Add an it_portal_t structure representing a new portal to the specified
 370  * target portal group.  The change to the target portal group will not take
 371  * effect until the modified configuration is committed by calling
 372  * it_config_commit().
 373  *
 374  * Parameters:
 375  *    cfg               The current iSCSI configration obtained from
 376  *                      it_config_load()
 377  *    tpg               Pointer to the it_tpg_t structure representing the
 378  *                      target portal group or "none" to remove
 379  *    portal            Pointer to the it_portal_t structure representing
 380  *                      the portal
 381  *    portal_ip_port    A string containing an appropriately formatted
 382  *                      IP address or IP address:port in either IPv4 or
 383  *                      IPv6 format.
 384  * Return Values:
 385  *    0                 Success
 386  *    ENOMEM            Could not allocate resources
 387  *    EINVAL            Invalid parameter
 388  *    EEXIST            Portal already configured for another portal group
 389  */
 390 int
 391 it_portal_create(it_config_t *cfg, it_tpg_t *tpg, it_portal_t **portal,
 392     char *portal_ip_port);
 393 
 394 /*
 395  * Function:  it_portal_delete()
 396  *
 397  * Remove the specified portal from the specified target portal group.
 398  * The portal removal will not take effect until the modified configuration
 399  * is committed by calling it_config_commit().
 400  *
 401  * Parameters:
 402  *    cfg               The current iSCSI configration obtained from
 403  *                      it_config_load()
 404  *    tpg               Pointer to the it_tpg_t structure representing the
 405  *                      target portal group
 406  *    portal            Pointer to the it_portal_t structure representing
 407  *                      the portal
 408  */
 409 void
 410 it_portal_delete(it_config_t *cfg, it_tpg_t *tpg, it_portal_t *portal);
 411 
 412 /*
 413  * Function:  it_ini_create()
 414  *
 415  * Add an initiator context to the global configuration. The new
 416  * initiator context will not be instantiated until the modified
 417  * configuration is committed by calling it_config_commit().
 418  *
 419  * Parameters:
 420  *    cfg               The current iSCSI configration obtained from
 421  *                      it_config_load()
 422  *    ini               Pointer to the it_ini_t structure representing
 423  *                      the initiator context.
 424  *    ini_node_name     The iSCSI node name of the remote initiator.
 425  *
 426  * Return Values:
 427  *    0                 Success
 428  *    ENOMEM            Could not allocate resources
 429  *    EINVAL            Invalid parameter.
 430  *    EEXIST            Initiator already configured
 431  *    EFAULT            Invalid initiator name
 432  */
 433 int
 434 it_ini_create(it_config_t *cfg, it_ini_t **ini, char *ini_node_name);
 435 
 436 /*
 437  * Function:  it_ini_setprop()
 438  *
 439  * Validate the provided property list and set the initiator properties.
 440  * If errlist is not NULL, returns detailed errors for each property
 441  * that failed.  The format for errorlist is
 442  *               key = property, value = error string.
 443  *
 444  * Parameters:
 445  *
 446  *    ini               The initiator being updated.
 447  *    proplist          nvlist_t containing properties for this target.
 448  *    errlist           (optional)  nvlist_t of errors encountered when
 449  *                      validating the properties.
 450  *
 451  * Return Values:
 452  *    0                 Success
 453  *    ENOMEM            Could not allocate resources
 454  *    EINVAL            Invalid property
 455  *
 456  */
 457 int
 458 it_ini_setprop(it_ini_t *ini, nvlist_t *proplist, nvlist_t **errlist);
 459 
 460 /*
 461  * Function:  it_ini_delete()
 462  *
 463  * Remove the specified initiator context from the global configuration.
 464  * The removal will not take effect until the modified configuration is
 465  * committed by calling it_config_commit().
 466  *
 467  * Parameters:
 468  *    cfg               The current iSCSI configration obtained from
 469  *                      it_config_load()
 470  *    ini               Pointer to the it_ini_t structure representing
 471  *                      the initiator context.
 472  */
 473 void
 474 it_ini_delete(it_config_t *cfg, it_ini_t *ini);
 475 
 476 /*
 477  * Function:  it_config_free()
 478  *
 479  * Free any resources associated with the it_config_t structure.
 480  *
 481  * Parameters:
 482  *    cfg       A C representation of the current iSCSI configuration
 483  */
 484 void
 485 it_config_free(it_config_t *cfg);
 486 
 487 /*
 488  * Function:  it_tgt_free()
 489  *
 490  * Frees an it_tgt_t structure.  If tgt_next is not NULL, frees
 491  * all structures in the list.
 492  */
 493 void
 494 it_tgt_free(it_tgt_t *tgt);
 495 
 496 /*
 497  * Function:  it_tpgt_free()
 498  *
 499  * Deallocates resources of an it_tpgt_t structure.  If tpgt->next
 500  * is not NULL, frees all members of the list.
 501  */
 502 void
 503 it_tpgt_free(it_tpgt_t *tpgt);
 504 
 505 /*
 506  * Function:  it_tpg_free()
 507  *
 508  * Deallocates resources associated with an it_tpg_t structure.
 509  * If tpg->next is not NULL, frees all members of the list.
 510  */
 511 void
 512 it_tpg_free(it_tpg_t *tpg);
 513 
 514 /*
 515  * Function:  it_ini_free()
 516  *
 517  * Deallocates resources of an it_ini_t structure. If ini->next is
 518  * not NULL, frees all members of the list.
 519  */
 520 void
 521 it_ini_free(it_ini_t *ini);
 522 
 523 /*
 524  * Function:  validate_iscsi_name()
 525  *
 526  * Ensures the passed-in string is a valid IQN or EUI iSCSI name
 527  */
 528 boolean_t
 529 validate_iscsi_name(char *in_name);
 530 
 531 /*
 532  * Function:  canonical_iscsi_name()
 533  *
 534  * Fold the iqn iscsi name to lower-case and the EUI-64 identifier of
 535  * the eui iscsi name to upper-case.
 536  * Ensures the passed-in string is a valid IQN or EUI iSCSI name
 537  */
 538 void
 539 canonical_iscsi_name(char *tgt);
 540 
 541 #ifdef  __cplusplus
 542 }
 543 #endif
 544 
 545 #endif  /* _LIBISCSIT_H */