From deef9e20c2f1b107760b5b4c29289de77fcdc39f Mon Sep 17 00:00:00 2001 From: Lalit Chandivade Date: Sun, 14 Aug 2011 01:50:13 -0500 Subject: 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--/ <-- for ipv4 |- bootproto |- enabled |- ipaddress |- subnet |- gateway |- mtu |- port |- vlan |- vlan_enabled |- vlan_priority |- ipv6-iface--/ <-- 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,,, qla4xxx.00:0e:1e:04:8b:2e.ipv6 qla4xxx,00:0e:1e:04:8b:2e,,, qla4xxx.00:0e:1e:04:8b:2a qla4xxx,00:0e:1e:04:8b:2a,20.15.0.66,, qla4xxx.00:0e:1e:04:8b:2a.ipv6 qla4xxx,00:0e:1e:04:8b:2a,2001:DB8:1111:2222::8888,, qla4xxx.00:0e:1e:04:8b:2a.ipv6.1 qla4xxx,00:0e:1e:04:8b:2a,2001:DB8:4444:5555::9999,, 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 Signed-off-by: Harish Zunjarrao [formatting fixes and addition of host param for applyall] Signed-off-by: Mike Christie Signed-off-by: Vikas Chaudhary --- etc/iface.example | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) (limited to 'etc') diff --git a/etc/iface.example b/etc/iface.example index 3c7354f..7af784b 100644 --- a/etc/iface.example +++ b/etc/iface.example @@ -60,3 +60,138 @@ # the same subnet. # iface.net_ifacename = eth0 # iface.ipaddress = 102.50.50.101 + +# OPTIONAL: iface.bootproto +# +# Valid values are: +# "dhcp" and "static" +# +# REQUIRED when IPv4 address need to be obtained dynamically using DHCP +# example: +# iface.bootproto = dhcp +# +# OPTIONAL when the IPv4 address is set statically +# example: +# iface.ipaddress = 102.50.50.101 +# iface.bootproto = static +# + +# OPTIONAL: iface.vlan_id +# Used to set the VLAN ID for the iSCSI interfae. +# example +# iface.vlan_id = 1022 + +# OPTIONAL: iface.vlan_priority +# Used to set the VLAN priority for the iSCSI interfae. +# example +# iface.vlan_priority = 1 + +# OPTIONAL: iface.vlan_state +# Used to enable or disable the VLAN on the iSCSI interface +# example +# iface.vlan_state = enable + +# OPTIONAL: iface.ipv6_linklocal +# Specify the IPV6 Link Local Address with the +# link local prefix of FE80::0/64 +# example: +# iface.ipv6_linklocal = fe80:0000:0000:0000:020e:1eff:1111:2221 + +# OPTIONAL: iface.ipv6_router +# Used to set a default IPV6 router +# example: +# iface.ipv6_router = fe80:0000:0000:0000:7ae7:d1ff:fe72:4048 + +# OPTIONAL: iface.ipv6_autocfg +# Used to set the discovery protocol to obtain IPV6 address +# For example qla4xxx support neighbor discovery +# example: +# iface.ipv6_autocfg = nd + +# OPTIONAL: iface.linklocal_autocfg +# For transport like qla4xxx this allows to auto configure the +# IPV6 link local address based on the MAC address of the iSCSI +# interface + +# OPTIONAL: iface.router_autocfg +# Required to set the IPv6 router discovery protocol +# To set the router discovery protocol to Neighbor Discovery specify "nd" +# example: +# iface.router_autocfg = nd + +# OPTIONAL: iface.state +# By default the iface is enabled +# iface.state = enable +# To disable the iface set the state to "disable" +# iface.state = disable + +# iface.iface_num +# REQUIRED: When there are more than 1 interface to be configured. +# For transports like qla4xxx, one can specify two IPV6 interfaces +# in such case the iface_num must be set correctly +# example: +# iface settings for first IPV6 interface +# iface.iscsi_ifacename = iface-qla4xxx-ipv6-1 +# iface.iface_num = 0 +# +# iface settings for second IPV6 interface +# iface.iscsi_ifacename = iface-qla4xxx-ipv6-2 +# iface.iface_num = 1 + +# Here are some example iface files +# IPV4 sample config file with static IP address: +# BEGIN RECORD 2.0-872 +# iface.iscsi_ifacename = qla4xxx-3 +# iface.ipaddress = 192.168.1.75 +# iface.hwaddress = 00:0e:1e:04:93:92 +# iface.transport_name = qla4xxx +# iface.bootproto = static +# iface.subnet_mask = 255.255.255.0 +# iface.gateway = 192.168.1.1 +# iface.state = enable +# iface.vlan = +# iface.iface_num = 0 +# END RECORD +# +# IPV6 sample config file with neighbor discovery: +# BEGIN RECORD 2.0-872 +# iface.iscsi_ifacename = qla4xxx-3-1 +# iface.ipaddress = +# iface.hwaddress = 00:0e:1e:04:93:92 +# iface.transport_name = qla4xxx +# iface.ipv6_autocfg = nd +# iface.linklocal_autocfg = auto +# iface.router_autocfg = nd +# iface.ipv6_linklocal = fe80:0000:0000:0000:020e:1eff:1111:2221 +# iface.ipv6_router = auto +# iface.state = enable +# iface.vlan = +# iface.iface_num = 0 +# END RECORD + +# Ipv4 sample config file (DHCP configuration): +# BEGIN RECORD 2.0-872 +# iface.iscsi_ifacename = qla4xxx-3 +# iface.hwaddress = 00:0e:1e:04:93:92 +# iface.transport_name = qla4xxx +# iface.bootproto = dhcp +# iface.state = enable +# iface.vlan = +# iface.iface_num = 0 +# END RECORD + +# Sample ipv6 config file(manual configured IPs): +# BEGIN RECORD 2.0-872 +# iface.iscsi_ifacename = iface-new-file +# iface.ipaddress = fec0:ce00:7014:0041:1111:2222:1e04:9392 +# iface.hwaddress = 00:0e:1e:04:93:92 +# iface.transport_name = qla4xxx +# iface.ipv6_autocfg = +# iface.linklocal_autocfg = +# iface.router_autocfg = +# iface.ipv6_linklocal = fe80:0000:0000:0000:0000:0000:1e04:9392 +# iface.ipv6_router = fe80:0000:0000:0000:7ae7:d1ff:fe72:4048 +# iface.state = enable +# iface.vlan = +# iface.iface_num = 0 +# END RECORD -- cgit v1.2.1