diff options
author | Mike Christie <michaelc@cs.wisc.edu> | 2010-01-15 11:50:16 -0600 |
---|---|---|
committer | Mike Christie <michaelc@cs.wisc.edu> | 2010-01-15 11:50:16 -0600 |
commit | 65a224afcd13198ce4d881be0ad3647143edb144 (patch) | |
tree | c93cfec8b924061b363e05ddd3273dc708307626 | |
parent | 0c74f070052002cb984cd39146e0090ec930714e (diff) | |
download | open-iscsi-65a224afcd13198ce4d881be0ad3647143edb144.tar.gz |
iscsi tools: nic setup cleanup
This just breaks up the network part of the nic setup code
to a new function that lives in the net utils code, so it
can be used by other callers one day.
-rw-r--r-- | include/iscsi_net_util.h | 6 | ||||
-rw-r--r-- | usr/iface.c | 6 | ||||
-rw-r--r-- | usr/io.c | 2 | ||||
-rw-r--r-- | usr/iscsi_net_util.c | 162 | ||||
-rw-r--r-- | utils/fwparam_ibft/fw_entry.c | 126 | ||||
-rw-r--r-- | utils/fwparam_ibft/fwparam_ibft_sysfs.c | 3 |
6 files changed, 176 insertions, 129 deletions
diff --git a/include/iscsi_net_util.h b/include/iscsi_net_util.h index 8d06bd5..222634d 100644 --- a/include/iscsi_net_util.h +++ b/include/iscsi_net_util.h @@ -3,7 +3,9 @@ #define ISCSI_HWADDRESS_BUF_SIZE 18 -extern int net_get_transport_name_from_iface(char *iface, char *transport); -extern int net_get_dev_from_hwaddress(char *hwaddress, char *netdev); +extern int net_get_transport_name_from_netdev(char *netdev, char *transport); +extern int net_get_netdev_from_hwaddress(char *hwaddress, char *netdev); +extern int net_setup_netdev(char *netdev, char *local_ip, char *mask, + char *gateway, char *remote_ip, int needs_bringup); #endif diff --git a/usr/iface.c b/usr/iface.c index adb7856..e08946b 100644 --- a/usr/iface.c +++ b/usr/iface.c @@ -775,8 +775,8 @@ void iface_setup_from_boot_context(struct iface_rec *iface, sizeof(iface->iname)); if (strlen(context->iface)) { - if (!net_get_transport_name_from_iface(context->iface, - iface->transport_name)) { + if (!net_get_transport_name_from_netdev(context->iface, + iface->transport_name)) { /* set up for access through offload card */ memset(iface->name, 0, sizeof(iface->name)); snprintf(iface->name, sizeof(iface->name), @@ -815,7 +815,7 @@ int iface_create_ifaces_from_boot_contexts(struct list_head *ifaces, list_for_each_entry(context, targets, list) { memset(transport_name, 0, ISCSI_TRANSPORT_NAME_MAXLEN); - if (net_get_transport_name_from_iface(context->iface, + if (net_get_transport_name_from_netdev(context->iface, transport_name)) continue; @@ -203,7 +203,7 @@ static int bind_conn_to_iface(iscsi_conn_t *conn, struct iface_rec *iface) memset(session->netdev, 0, IFNAMSIZ); if (iface_is_bound_by_hwaddr(iface) && - net_get_dev_from_hwaddress(iface->hwaddress, session->netdev)) { + net_get_netdev_from_hwaddress(iface->hwaddress, session->netdev)) { log_error("Cannot match %s to net/scsi interface.", iface->hwaddress); return -1; diff --git a/usr/iscsi_net_util.c b/usr/iscsi_net_util.c index 3bf763c..cbe6f56 100644 --- a/usr/iscsi_net_util.c +++ b/usr/iscsi_net_util.c @@ -19,9 +19,13 @@ #include <errno.h> #include <net/if.h> #include <unistd.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <net/route.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/ioctl.h> +#include <sys/socket.h> #include <linux/sockios.h> #include "sysdeps.h" @@ -44,20 +48,20 @@ static struct iscsi_net_driver net_drivers[] = { }; /** - * net_get_transport_name_from_iface - get name of transport to use for iface - * @iface: net iface name + * net_get_transport_name_from_netdev - get name of transport to use for iface + * @netdev: netdev iface name * @transport: buffer to hold transport name * * transport buffer should be ISCSI_TRANSPORT_NAME_MAXLEN bytes */ -int net_get_transport_name_from_iface(char *iface, char *transport) +int net_get_transport_name_from_netdev(char *netdev, char *transport) { struct ethtool_drvinfo drvinfo; struct ifreq ifr; int err, fd, i; memset(&ifr, 0, sizeof(ifr)); - strcpy(ifr.ifr_name, iface); + strcpy(ifr.ifr_name, netdev); fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd < 0) { @@ -91,14 +95,14 @@ close_sock: } /** - * net_get_dev_from_hwaddress - given a hwaddress return the ethX + * net_get_netdev_from_hwaddress - given a hwaddress return the ethX * @hwaddress: hw address no larger than ISCSI_HWADDRESS_BUF_SIZE * @netdev: buffer of IFNAMSIZ size that will hold the ethX * * Does not support interfaces like a bond or alias because * multiple interfaces will have the same hwaddress. */ -int net_get_dev_from_hwaddress(char *hwaddress, char *netdev) +int net_get_netdev_from_hwaddress(char *hwaddress, char *netdev) { struct if_nameindex *ifni; struct ifreq if_hwaddr; @@ -158,3 +162,149 @@ free_ifni: return ENODEV; return 0; } + +/** + * net_setup_netdev - bring up NIC + * @netdev: network device name + * @local: ip address for netdev + * @mask: net mask + * @gateway: gateway + * @remote_ip: target portal ip + * @needs_bringup: bool indicating if the netdev needs to be started + * + * Bring up required NIC and use routing + * to force iSCSI traffic through correct NIC. + */ +int net_setup_netdev(char *netdev, char *local_ip, char *mask, char *gateway, + char *remote_ip, int needs_bringup) +{ + struct sockaddr_in sk_ipaddr = { .sin_family = AF_INET }; + struct sockaddr_in sk_netmask = { .sin_family = AF_INET }; + struct sockaddr_in sk_hostmask = { .sin_family = AF_INET }; + struct sockaddr_in sk_gateway = { .sin_family = AF_INET }; + struct sockaddr_in sk_tgt_ipaddr = { .sin_family = AF_INET }; + struct rtentry rt; + struct ifreq ifr; + int sock; + int ret; + + if (!strlen(netdev)) { + log_error("No netdev name in fw entry.\n"); + return EINVAL; + } + + /* Create socket for making networking changes */ + if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { + log_error("Could not open socket to manage network " + "(err %d - %s)", errno, strerror(errno)); + return errno; + } + + /* Bring up NIC with correct address - unless it + * has already been handled (2 targets in IBFT may share one NIC) + */ + if (!inet_aton(local_ip, &sk_ipaddr.sin_addr)) { + log_error("Invalid or missing ipaddr in fw entry\n"); + ret = EINVAL; + goto done; + } + + if (!inet_aton(mask, &sk_netmask.sin_addr)) { + log_error("Invalid or missing netmask in fw entry\n"); + ret = EINVAL; + goto done; + } + + inet_aton("255.255.255.255", &sk_hostmask.sin_addr); + + if (!inet_aton(remote_ip, &sk_tgt_ipaddr.sin_addr)) { + log_error("Invalid or missing target ipaddr in fw entry\n"); + ret = EINVAL; + goto done; + } + + /* Only set IP/NM if this is a new interface */ + if (needs_bringup) { + /* TODO: create vlan if strlen(vlan) */ + + /* Bring up interface */ + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, netdev, IFNAMSIZ); + ifr.ifr_flags = IFF_UP | IFF_RUNNING; + if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0) { + log_error("Could not bring up netdev %s (err %d - %s)", + netdev, errno, strerror(errno)); + ret = errno; + goto done; + } + /* Set IP address */ + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, netdev, IFNAMSIZ); + memcpy(&ifr.ifr_addr, &sk_ipaddr, sizeof(struct sockaddr)); + if (ioctl(sock, SIOCSIFADDR, &ifr) < 0) { + log_error("Could not set ip for %s (err %d - %s)", + netdev, errno, strerror(errno)); + ret = errno; + goto done; + } + + /* Set netmask */ + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, netdev, IFNAMSIZ); + memcpy(&ifr.ifr_addr, &sk_netmask, sizeof(struct sockaddr)); + if (ioctl(sock, SIOCSIFNETMASK, &ifr) < 0) { + log_error("Could not set ip for %s (err %d - %s)", + netdev, errno, strerror(errno)); + ret = errno; + goto done; + } + } + + /* Set static route to target via this interface */ + memset((char *) &rt, 0, sizeof(rt)); + memcpy(&rt.rt_dst, &sk_tgt_ipaddr, sizeof(sk_tgt_ipaddr)); + memcpy(&rt.rt_genmask, &sk_hostmask, sizeof(sk_hostmask)); + rt.rt_flags = RTF_UP | RTF_HOST; + rt.rt_dev = netdev; + + if ((sk_tgt_ipaddr.sin_addr.s_addr & sk_netmask.sin_addr.s_addr) == + (sk_ipaddr.sin_addr.s_addr & sk_netmask.sin_addr.s_addr)) { + /* Same subnet */ + if (ioctl(sock, SIOCADDRT, &rt) < 0) { + if (errno != EEXIST) { + log_error("Could not set ip for %s " + "(err %d - %s)", netdev, + errno, strerror(errno)); + ret = errno; + goto done; + } + } + } else { + /* Different subnet. Use gateway */ + rt.rt_flags |= RTF_GATEWAY; + if (!inet_aton(gateway, &sk_gateway.sin_addr)) { + log_error("Invalid or missing gateway for %s " + "(err %d - %s)", + netdev, errno, strerror(errno)); + ret = errno; + goto done; + } + memcpy(&rt.rt_gateway, &sk_gateway, sizeof(sk_gateway)); + if (ioctl(sock, SIOCADDRT, &rt) < 0) { + if (errno != EEXIST) { + log_error("Could not set gateway for %s " + "(err %d - %s)", netdev, + errno, strerror(errno)); + ret = errno; + goto done; + } + } + } + ret = 0; + +done: + close(sock); + return ret; +} + + diff --git a/utils/fwparam_ibft/fw_entry.c b/utils/fwparam_ibft/fw_entry.c index 9dbaf59..ae5d34a 100644 --- a/utils/fwparam_ibft/fw_entry.c +++ b/utils/fwparam_ibft/fw_entry.c @@ -49,8 +49,7 @@ int fw_setup_nics(void) struct boot_context *context; struct list_head targets; char *iface_prev = NULL, transport[16]; - int sock; - int ret; + int needs_bringup = 0, ret = 0, err; INIT_LIST_HEAD(&targets); @@ -60,140 +59,35 @@ int fw_setup_nics(void) return ENODEV; } - /* Create socket for making networking changes */ - if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { - perror("socket(AF_INET, SOCK_DGRAM, 0)"); - ret = errno; - goto free_targets; - } - /* * For each target in iBFT bring up required NIC and use routing * to force iSCSI traffic through correct NIC */ list_for_each_entry(context, &targets, list) { - if (!net_get_transport_name_from_iface(context->iface, - transport)) - continue; - - /* Bring up NIC with correct address - unless it - * has already been handled (2 targets in IBFT may share - * one NIC) - */ - struct sockaddr_in ipaddr = { .sin_family = AF_INET }; - struct sockaddr_in netmask = { .sin_family = AF_INET }; - struct sockaddr_in hostmask = { .sin_family = AF_INET }; - struct sockaddr_in gateway = { .sin_family = AF_INET }; - struct sockaddr_in tgt_ipaddr = { .sin_family = AF_INET }; - struct rtentry rt; - struct ifreq ifr; - - if (!strlen(context->iface)) { - printf("No iface in fw entry\n"); - ret = EINVAL; - continue; - } - if (!inet_aton(context->ipaddr, &ipaddr.sin_addr)) { - printf("Invalid or no ipaddr in fw entry\n"); - ret = EINVAL; - continue; - } - - if (!inet_aton(context->mask, &netmask.sin_addr)) { - printf("Invalid or no netmask in fw entry\n"); - ret = EINVAL; + /* if it is a offload nic ignore it */ + if (!net_get_transport_name_from_netdev(context->iface, + transport)) continue; - } - inet_aton("255.255.255.255", &hostmask.sin_addr); - - if (!inet_aton(context->target_ipaddr, &tgt_ipaddr.sin_addr)) { - printf("Invalid or no target ipaddr in fw entry\n"); - ret = EINVAL; - continue; - } - /* Only set IP/NM if this is a new interface */ if (iface_prev == NULL || strcmp(context->iface, iface_prev)) { /* Note: test above works because there is a * maximum of two targets in the iBFT */ iface_prev = context->iface; - - /* TODO: create vlan if strlen(context->vlan) */ - - /* Bring up interface */ - memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, context->iface, IFNAMSIZ); - ifr.ifr_flags = IFF_UP | IFF_RUNNING; - if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0) { - perror("ioctl(SIOCSIFFLAGS)"); - ret = errno; - continue; - } - /* Set IP address */ - memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, context->iface, IFNAMSIZ); - memcpy(&ifr.ifr_addr, &ipaddr, sizeof(struct sockaddr)); - if (ioctl(sock, SIOCSIFADDR, &ifr) < 0) { - perror("ioctl(SIOCSIFADDR)"); - ret = errno; - continue; - } - /* Set netmask */ - memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, context->iface, IFNAMSIZ); - memcpy(&ifr.ifr_addr, &netmask, sizeof(struct sockaddr)); - if (ioctl(sock, SIOCSIFNETMASK, &ifr) < 0) { - perror("ioctl(SIOCSIFNETMASK)"); - ret = errno; - continue; - } + needs_bringup = 1; } - /* Set static route to target via this interface */ - memset((char *) &rt, 0, sizeof(rt)); - memcpy(&rt.rt_dst, &tgt_ipaddr, sizeof(tgt_ipaddr)); - memcpy(&rt.rt_genmask, &hostmask, sizeof(hostmask)); - rt.rt_flags = RTF_UP | RTF_HOST; - rt.rt_dev = context->iface; - - if ((tgt_ipaddr.sin_addr.s_addr & netmask.sin_addr.s_addr) == - (ipaddr.sin_addr.s_addr & netmask.sin_addr.s_addr)) { - /* Same subnet */ - if (ioctl(sock, SIOCADDRT, &rt) < 0) { - if (errno != EEXIST) { - perror("ioctl(SIOCADDRT)"); - ret = errno; - continue; - } - } - } else { - /* Different subnet. Use gateway */ - rt.rt_flags |= RTF_GATEWAY; - if (!inet_aton(context->gateway, &gateway.sin_addr)) { - printf("Invalid or no gateway in fw entry\n"); - ret = errno; - continue; - } - memcpy(&rt.rt_gateway, &gateway, sizeof(gateway)); - if (ioctl(sock, SIOCADDRT, &rt) < 0) { - if (errno != EEXIST) { - perror("ioctl(SIOCADDRT)"); - ret = errno; - continue; - } - } - } - /* This target handled */ + err = net_setup_netdev(context->iface, context->ipaddr, + context->mask, context->gateway, + context->target_ipaddr, needs_bringup); + if (err) + ret = err; } - close(sock); -free_targets: fw_free_targets(&targets); return ret; } - /** * fw_get_entry - return boot context of portal used for boot * @context: firmware info of portal diff --git a/utils/fwparam_ibft/fwparam_ibft_sysfs.c b/utils/fwparam_ibft/fwparam_ibft_sysfs.c index 9a2cb7d..9185c85 100644 --- a/utils/fwparam_ibft/fwparam_ibft_sysfs.c +++ b/utils/fwparam_ibft/fwparam_ibft_sysfs.c @@ -181,7 +181,8 @@ static int fill_nic_context(char *id, struct boot_context *context) */ rc = get_iface_from_device(id, context); if (rc) { - rc = net_get_dev_from_hwaddress(context->mac, context->iface); + rc = net_get_netdev_from_hwaddress(context->mac, + context->iface); if (rc) return rc; } |