iscsiadm: add netconfig support
commitdeef9e20c2f1b107760b5b4c29289de77fcdc39f
authorLalit Chandivade <lalit.chandivade@qlogic.com>
Sun, 14 Aug 2011 06:50:13 +0000 (14 01:50 -0500)
committerMike Christie <michaelc@cs.wisc.edu>
Mon, 15 Aug 2011 03:12:57 +0000 (14 22:12 -0500)
treea9c0bbf18b915511694135a72116c4fd252f7aa8
parent42a5950919038cac331c7fa69304478bd62bec15
iscsiadm: add netconfig support

1. Current status:
Using iscsiadm one cannot do any network configuration for qla4xxx
adapters.
However an iface is created for the qla4xxx ports using the hwaddress.

\# ls /etc/iscsi/ifaces/
iface.example  iface0  qla4xxx.00:0e:1e:04:8b:2a
qla4xxx.00:0e:1e:04:8b:2e

This allows user to issue sendtargets via the qla4xxx iscsi offload.

2. Current Proposal:
Current proposal is to allow iscsiadm to configure the network settings
for qla4xxx ports.

This implementation is based on discussions at
 - http://marc.info/?l=linux-scsi&m=127066184916180&w=2
 - http://groups.google.com/group/open-iscsi/browse_thread/thread/d8e8c2df71c95d69/8f731d95d46141a0?lnk=gst&q=iscsi+hba#

2.1 Changes in iscsiadm/iscsid

2.1.1 Add a new event: ISCSI_UEVENT_SET_IFACE_PARAMS

2.1.2 New structure/enum to represent a single network parameter
 - enum iscsi_net_param;
 - struct iscsi_iface_param_info;

2.1.3 Added new parameters in iface

2.1.4 Change in operations
Add two new operations to iscsiadm
apply: Apply the single iface settings
applyall: Apply the iface settings of all iface having the same MAC
address

2.2 Changes in sysfs network representation
The new sysfs directory would look like this:-
/sys/class/iscsi_iface/-|
 _______________________|
|
|- ipv4-iface-<host_no>-<iface_no>/                             <-- for ipv4
                                |- bootproto
                                |- enabled
                                |- ipaddress
                                |- subnet
                                |- gateway
                                |- mtu
                                |- port
                                |- vlan
                                |- vlan_enabled
                                |- vlan_priority
|- ipv6-iface-<host_no>-<iface_no>/                             <-- for ipv6

                                |- enabled
                                |- ipaddr_autocfg
                                |- ipaddress
                                |- link_local_addr
                                |- linklocal_autocfg
                                |- mtu
                                |- port
                                |- router_addr
                                |- vlan
                                |- vlan_enabled
                                |- vlan_priority

3. Flow:
3.1 User space code:
            - If user specify --op=update, then just update the iface
              config file
            - If use specify --op=applyall then ifaces for the host
      passed in.
              and build up the net config buffer.
            - Note: If --op is "apply" then only settings for single
              iface is read,
              the iface provided with -I option is only read.
            - The net config buffer will look like this.

        ----------------------------------------------------------------|
        | iscsi_net_param { |
        |  iface_num = 0; |
        |  len = 4; |
        |  param = ISCSI_NET_PARAM_IPV4_ADDR; |
        |  iface_type = ISCSI_IFACE_TYPE_IPV4; |
        |  param_type = ISCSI_NET_PARAM; |
        |  value[0] = ipaddress[0]; |
        |  value[1] = ipaddress[1]; |
        |  value[2] = ipaddress[2]; |
        |  value[3] = ipaddress[3]; |
        | } |
        ----------------------------------------------------------------|
        |  iscsi_net_param { |
        |  iface_num = 0; |
        |  len = 4; |
        |  param = ISCSI_NET_PARAM_IPV4_GW; |
        |  iface_type = ISCSI_IFACE_TYPE_IPV4; |
        |  param_type = ISCSI_NET_PARAM; |
        |  value[0] = ipgateway[0]; |
        |  value[1] = ipgateway[1]; |
        |  value[2] = ipgateway[2]; |
        |  value[3] = ipgateway[3]; |
        | } |
        -----------------------------------------------------------------
        | |
        | iscsi_net_param { |
        |  iface_num = 1; |
        |  len = 4; |
        |  param = ISCSI_NET_PARAM_IPV4_ADDR; |
        |  iface_type = ISCSI_IFACE_TYPE_IPV4; |
        |  param_type = ISCSI_NET_PARAM; |
        |  value[0] = ipaddress[0]; |
        |  value[1] = ipaddress[1]; |
        |  value[2] = ipaddress[2]; |
        |  value[3] = ipaddress[3]; |
        | } |
        -----------------------------------------------------------------
        -----------------------------------------------------------------
        | iscsi_net_param { |
        |  iface_num = 0; |
        |  len = 4; |
        |  param = ISCSI_NET_PARAM_IPV4_GW; |
        |  iface_type = ISCSI_IFACE_TYPE_IPV4; |
        |  param_type = ISCSI_NET_PARAM; |
        |  value[0] = ipgateway[0]; |
        |  value[1] = ipgateway[1]; |
        |  value[2] = ipgateway[2]; |
        |  value[3] = ipgateway[3]; |
        | } |
        -----------------------------------------------------------------
        | iscsi_net_param { |
        |  iface_num = 1; |
        |  len = 1; |
        |  param = ISCSI_NET_PARAM_IFACE_ENABLED; |
        |  iface_type = ISCSI_IFACE_TYPE_IPV4; |
        |  param_type = ISCSI_NET_PARAM; |
        |  offset = 0; |
        |  value[0] = 0; /* 0 = disable, default = 1 = enable */ |
        | } |
        -----------------------------------------------------------------

Each netconfig parameter has different size requirement for value field.

e.g.: IPv4 address requires 4 bytes, IPv6 address requires 16 bytes etc.

        The memory allocated for each netconfig parameter is size of
        iscsi_net_param + length required for that parameter.

        The multiple IO Vector mechanism is used to send netconfig
        parameter from user space to kernel using Netlink interface.

        IO Vector 0 is used for Netlink message header.

        IO Vector 1 is used for iSCSI User Event (ev).
        - The ev will be sent down with event type =
          ISCSI_UEVENT_SET_NET_CONFIG

        IO Vector 2 onwards, each vector consists of the struct
iscsi_net_param
        with parameter name followed by its value.

        The total size will be addition of all the IO vector sizes.

3.2 Kernel space code:
        - Once event is received, the buffer will look like struct
          iscsi_net_param
          with parameter name followed by its value, then next parameter
and
          its value and so on.
        - the scsi_transport_iscsi would call the adapter's
          transport->set_net_config        - In set_net_config each
individual param can be decoded and set into the
          hardware.
4. qla4xxx configuration:
        iscsid, creates the iface for qla4xxx, based on the hwaddress.
To display
        the iface related to qla4xxx execute following
           \# iscsiadm -m iface
               qla4xxx.00:0e:1e:04:8b:2e
qla4xxx,00:0e:1e:04:8b:2e,<empty>,<empty>,<empty>
               qla4xxx.00:0e:1e:04:8b:2e.ipv6
qla4xxx,00:0e:1e:04:8b:2e,<empty>,<empty>,<e
mpty>
               qla4xxx.00:0e:1e:04:8b:2a
qla4xxx,00:0e:1e:04:8b:2a,20.15.0.66,<empty>,<emp
ty>
               qla4xxx.00:0e:1e:04:8b:2a.ipv6
               qla4xxx,00:0e:1e:04:8b:2a,2001:DB8:1111:2222::8888,<empty>,<empty>
               qla4xxx.00:0e:1e:04:8b:2a.ipv6.1
               qla4xxx,00:0e:1e:04:8b:2a,2001:DB8:4444:5555::9999,<empty>,<empty>
To setup network configuration there can be two methods
4. 1. User can manually modify the iface file, and issue an "apply"
command.
---------------------------------------------------------------------------
 \#cat /etc/iscsi/ifaces/
  iface.example  iface0  qla4xxx.00:0e:1e:04:8b:2a
qla4xxx.00:0e:1e:04:8b:2e

            Example:
            \# cat qla4xxx.00:0e:1e:04:8b:2a
            iface.iscsi_ifacename = qla4xxx.00:0e:1e:04:8b:2a
            iface.transport_name = qla4xxx
            iface.hwaddress = 00:0e:1e:04:8b:2a
            iface.state = enable
            iface.iface_num = 0 (default)
            iface.bootproto = static
            iface.ipaddress = 192.168.2.2 (decimal)
            iface.subnetmask = 255.255.255.0 (decimal)
            \# vi qla4xxx.00:0e:1e:04:8b:2a.ipv6
               (If file does not exist, the one can create it)
            iface.iscsi_ifacename = qla4xxx.00:0e:1e:04:8b:2a.ipv6
            iface.transport_name = qla4xxx
            iface.hwaddress = 00:0e:1e:04:8b:2a
            iface.ipaddress =  1111:2222::7777:8888 (hex)
            iface.iface_num = 0

            \# iscsiadm -m iface -H 00:0e:1e:04:8b:2a --op=applyall
            This will find the ifaces on the host with MAC address
    00:0e:1e:04:8b:2a and apply the settings to the hardware..

            Note, this will read all the iface belonging to the same MAC
    address.

    Note2, Instead of a MAC address the host number can be
passed in.

4.2. User can use iscsiadm to specify the values and then apply
--------------------------------------------------------------
            \# ls /etc/iscsi/ifaces/
              iface.example  iface0  qla4xxx.00:0e:1e:04:8b:2a
qla4xxx.00:0e:1e:04:8b:2e
            \# iscsiadm -m iface -I qla4xxx.00:0e:1e:04:8b:2a -o update
\
               -n iface.ipaddress -v 192.168.1.2
            \# iscsiadm -m iface -I qla4xxx.00:0e:1e:04:8b:2a -o update
\
                           -n iface.gateway -v 192.168.1.1
            \# iscsiadm -m iface -I qla4xxx.00:0e:1e:04:8b:2a -o update
\
                           -n iface.subnet_mask -v 255.255.255.0
            \# iscsiadm -m iface -H 00:0e:1e:04:8b:2a -o applyall

            Setting up multiple IP:
            First interface (default, no need to set iface_num, it is 0
by default)
            \# iscsiadm -m iface -I qla4xxx.00:0e:1e:04:8b:2a -o update
\
                           -n iface.ipaddress -v 192.168.1.2
            Create the second one if it does not exist
            \# iscsiadm -m iface -I qla4xxx.00:0e:1e:04:8b:2a.1 -op=new
            \# iscsiadm -m iface -I qla4xxx.00:0e:1e:04:8b:2a -o update
\
                           -n iface.iface_num -v 1 (Mandatory)
            \# iscsiadm -m iface -I qla4xxx.00:0e:1e:04:8b:2a -o update
\
                           -n iface.ipaddress -v 192.168.1.3
            \# iscsiadm -m iface -H 00:0e:1e:04:8b:2a --op=applyall

            Note: If there are common settings for multiple interfaces
then the
            settings from 0th iface would be considered valid.

            Note: To apply settings for a single iface, just say
--op=apply

Signed-off-by: Lalit Chandivade <lalit.chandivade@qlogic.com>
Signed-off-by: Harish Zunjarrao <harish.zunjarrao@qlogic.com>
[formatting fixes and addition of host param for applyall]
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com>
15 files changed:
README
doc/iscsiadm.8
etc/iface.example
include/iscsi_if.h
usr/config.h
usr/idbm.c
usr/idbm.h
usr/idbm_fields.h
usr/iface.c
usr/iface.h
usr/iscsi_ipc.h
usr/iscsi_sysfs.c
usr/iscsiadm.c
usr/netlink.c
utils/fwparam_ibft/fw_entry.c