diff options
author | Mike Christie <michaelc@cs.wisc.edu> | 2010-01-14 04:33:51 -0600 |
---|---|---|
committer | Mike Christie <michaelc@cs.wisc.edu> | 2010-01-15 02:24:01 -0600 |
commit | 2e39c68d905380efad58cd19ba982c06147161e3 (patch) | |
tree | 18bb63ae514ee6b0bc1b6a17edcc02ba1fbd51b2 | |
parent | 29a1a1d624c12d2db0645c69cd672d54a5bdc549 (diff) | |
download | open-iscsi-2e39c68d905380efad58cd19ba982c06147161e3.tar.gz |
iscsi tools: merge functions to get net iface name from mac address
There are 3 functions to get the net iface name
from the mac address. This merges them into
one function and moves it to a new file.
-rw-r--r-- | include/iscsi_net_util.h | 8 | ||||
-rw-r--r-- | usr/Makefile | 12 | ||||
-rw-r--r-- | usr/config.h | 4 | ||||
-rw-r--r-- | usr/io.c | 64 | ||||
-rw-r--r-- | usr/iscsi_net_util.c | 100 | ||||
-rw-r--r-- | usr/log.h | 2 | ||||
-rw-r--r-- | utils/fwparam_ibft/Makefile | 2 | ||||
-rw-r--r-- | utils/fwparam_ibft/fw_entry.c | 7 | ||||
-rw-r--r-- | utils/fwparam_ibft/fwparam_ibft_sysfs.c | 146 |
9 files changed, 125 insertions, 220 deletions
diff --git a/include/iscsi_net_util.h b/include/iscsi_net_util.h new file mode 100644 index 0000000..304214d --- /dev/null +++ b/include/iscsi_net_util.h @@ -0,0 +1,8 @@ +#ifndef __ISCSI_NET_UTIL_h__ +#define __ISCSI_NET_UTIL_h__ + +#define ISCSI_HWADDRESS_BUF_SIZE 18 + +extern int net_get_dev_from_hwaddress(char *hwaddress, char *netdev); + +#endif diff --git a/usr/Makefile b/usr/Makefile index 4d3c71f..1caf4f1 100644 --- a/usr/Makefile +++ b/usr/Makefile @@ -36,21 +36,21 @@ PROGRAMS = iscsid iscsiadm iscsistart # libc compat files SYSDEPS_SRCS = $(wildcard ../utils/sysdeps/*.o) # sources shared between iscsid, iscsiadm and iscsistart -ISCSI_LIB_SRCS = util.o io.o auth.o login.o log.o md5.o sha1.o iface.o idbm.o sysfs.o host.o session_info.o iscsi_sysfs.o $(SYSDEPS_SRCS) -# sources shared between iscsid and iscsiadm -COMMON_SRCS = $(ISCSI_LIB_SRCS) +ISCSI_LIB_SRCS = util.o io.o auth.o login.o log.o md5.o sha1.o iface.o idbm.o \ + sysfs.o host.o session_info.o iscsi_sysfs.o iscsi_net_util.o \ + $(SYSDEPS_SRCS) # core initiator files INITIATOR_SRCS = initiator.o scsi.o actor.o event_poll.o mgmt_ipc.o isns.o \ - cxgb3i.o be2iscsi.o transport.o + transport.o cxgb3i.o be2iscsi.o # fw boot files FW_BOOT_SRCS = $(wildcard ../utils/fwparam_ibft/*.o) all: $(PROGRAMS) -iscsid: $(COMMON_SRCS) $(IPC_OBJ) $(INITIATOR_SRCS) iscsid.o +iscsid: $(ISCSI_LIB_SRCS) $(IPC_OBJ) $(INITIATOR_SRCS) iscsid.o $(CC) $(CFLAGS) $^ -o $@ -iscsiadm: $(COMMON_SRCS) $(FW_BOOT_SRCS) strings.o discovery.o iscsiadm.o +iscsiadm: $(ISCSI_LIB_SRCS) $(FW_BOOT_SRCS) strings.o discovery.o iscsiadm.o $(CC) $(CFLAGS) $^ -o $@ iscsistart: $(IPC_OBJ) $(ISCSI_LIB_SRCS) $(INITIATOR_SRCS) $(FW_BOOT_SRCS) \ diff --git a/usr/config.h b/usr/config.h index 47b8d9b..8fd1f77 100644 --- a/usr/config.h +++ b/usr/config.h @@ -22,9 +22,11 @@ #include <netdb.h> #include <net/if.h> + #include "types.h" #include "auth.h" /* for the username and password sizes */ #include "list.h" +#include "iscsi_net_util.h" /* ISIDs now have a typed naming authority in them. We use an OUI */ #define DRIVER_ISID_0 0x00 @@ -197,7 +199,7 @@ typedef struct iface_rec { * TODO: we may have to make this bigger and interconnect * specific for infinniband */ - char hwaddress[ISCSI_MAX_IFACE_LEN]; + char hwaddress[ISCSI_HWADDRESS_BUF_SIZE]; char transport_name[ISCSI_TRANSPORT_NAME_MAXLEN]; /* * This is only used for boot now, but the iser guys @@ -157,68 +157,6 @@ free_ifap: } #endif -/* - * In this mode we do not support interfaces like a bond or alias because - * multiple interfaces will have the same hwaddress. - */ -static int get_netdev_from_hwaddress(char *hwaddress, char *netdev) -{ - struct if_nameindex *ifni; - struct ifreq if_hwaddr; - int found = 0, sockfd, i = 0; - unsigned char *hwaddr; - char tmp_hwaddress[ISCSI_MAX_IFACE_LEN]; - - ifni = if_nameindex(); - if (ifni == NULL) { - log_error("Could not match hwaddress %s to netdev. " - "getifaddrs failed %d", hwaddress, errno); - return 0; - } - - /* Open a basic socket. */ - sockfd = socket(AF_INET, SOCK_DGRAM, 0); - if (sockfd < 0) { - log_error("Could not open socket for ioctl."); - goto free_ifni; - } - - for (i = 0; ifni[i].if_index && ifni[i].if_name; i++) { - struct if_nameindex *n = &ifni[i]; - - strlcpy(if_hwaddr.ifr_name, n->if_name, IFNAMSIZ); - if (ioctl(sockfd, SIOCGIFHWADDR, &if_hwaddr) < 0) { - log_error("Could not match %s to netdevice.", - hwaddress); - continue; - } - - /* check for ARPHRD_ETHER (ethernet) */ - if (if_hwaddr.ifr_hwaddr.sa_family != 1) - continue; - hwaddr = (unsigned char *)if_hwaddr.ifr_hwaddr.sa_data; - - memset(tmp_hwaddress, 0, ISCSI_MAX_IFACE_LEN); - /* TODO should look and covert so we do not need tmp buf */ - sprintf(tmp_hwaddress, "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x", - hwaddr[0], hwaddr[1], hwaddr[2], hwaddr[3], - hwaddr[4], hwaddr[5]); - log_debug(4, "Found hardware address %s", tmp_hwaddress); - if (!strcasecmp(tmp_hwaddress, hwaddress)) { - log_debug(4, "Matches %s to %s", hwaddress, - n->if_name); - memset(netdev, 0, IFNAMSIZ); - strlcpy(netdev, n->if_name, IFNAMSIZ); - found = 1; - break; - } - } - - close(sockfd); -free_ifni: - if_freenameindex(ifni); - return found; -} #if 0 @@ -265,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) && - !get_netdev_from_hwaddress(iface->hwaddress, session->netdev)) { + net_get_dev_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 new file mode 100644 index 0000000..e52be82 --- /dev/null +++ b/usr/iscsi_net_util.c @@ -0,0 +1,100 @@ +/* + * net helpers + * + * Copyright (C) 2010 Mike Christie + * Copyright (C) 2010 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <net/if.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/ioctl.h> + +#include "sysdeps.h" +#include "ethtool-copy.h" +#include "iscsi_net_util.h" +#include "log.h" + +/** + * net_get_dev_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) +{ + struct if_nameindex *ifni; + struct ifreq if_hwaddr; + int found = 0, sockfd, i = 0; + unsigned char *hwaddr; + char tmp_hwaddress[ISCSI_HWADDRESS_BUF_SIZE]; + + ifni = if_nameindex(); + if (ifni == NULL) { + log_error("Could not match hwaddress %s to netdev. " + "getifaddrs failed %d", hwaddress, errno); + return errno; + } + + /* Open a basic socket. */ + sockfd = socket(AF_INET, SOCK_DGRAM, 0); + if (sockfd < 0) { + log_error("Could not open socket for ioctl."); + goto free_ifni; + } + + for (i = 0; ifni[i].if_index && ifni[i].if_name; i++) { + struct if_nameindex *n = &ifni[i]; + + strlcpy(if_hwaddr.ifr_name, n->if_name, IFNAMSIZ); + if (ioctl(sockfd, SIOCGIFHWADDR, &if_hwaddr) < 0) { + log_error("Could not match %s to netdevice.", + hwaddress); + continue; + } + + /* check for ARPHRD_ETHER (ethernet) */ + if (if_hwaddr.ifr_hwaddr.sa_family != 1) + continue; + hwaddr = (unsigned char *)if_hwaddr.ifr_hwaddr.sa_data; + + memset(tmp_hwaddress, 0, ISCSI_HWADDRESS_BUF_SIZE); + /* TODO should look and covert so we do not need tmp buf */ + sprintf(tmp_hwaddress, "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x", + hwaddr[0], hwaddr[1], hwaddr[2], hwaddr[3], + hwaddr[4], hwaddr[5]); + log_debug(4, "Found hardware address %s", tmp_hwaddress); + if (!strcasecmp(tmp_hwaddress, hwaddress)) { + log_debug(4, "Matches %s to %s", hwaddress, + n->if_name); + memset(netdev, 0, IFNAMSIZ); + strlcpy(netdev, n->if_name, IFNAMSIZ); + found = 1; + break; + } + } + + close(sockfd); +free_ifni: + if_freenameindex(ifni); + if (!found) + return ENODEV; + return 0; +} + + @@ -28,14 +28,12 @@ #include "iscsid.h" -#if defined(Linux) union semun { int val; struct semid_ds *buf; unsigned short int *array; struct seminfo *__buf; }; -#endif #include <sys/sem.h> #define DEFAULT_AREA_SIZE 16384 diff --git a/utils/fwparam_ibft/Makefile b/utils/fwparam_ibft/Makefile index c160e0b..b9e7988 100644 --- a/utils/fwparam_ibft/Makefile +++ b/utils/fwparam_ibft/Makefile @@ -22,7 +22,7 @@ # SYSDEPS_OBJS = $(wildcard ../sysdeps/*.o) -OBJS := fw_entry.o fwparam_ibft_sysfs.o $(SYSDEPS_OBJS) +OBJS := fw_entry.o fwparam_ibft_sysfs.o $(SYSDEPS_OBJS) ../../usr/iscsi_net_util.o OBJS += prom_lex.o prom_parse.tab.o fwparam_ppc.o CLEANFILES = $(OBJS) *.output *~ diff --git a/utils/fwparam_ibft/fw_entry.c b/utils/fwparam_ibft/fw_entry.c index 479473c..894bd64 100644 --- a/utils/fwparam_ibft/fw_entry.c +++ b/utils/fwparam_ibft/fw_entry.c @@ -33,15 +33,16 @@ #include "fw_context.h" #include "fwparam.h" #include "idbm_fields.h" +#include "ethtool-copy.h" /** * fw_setup_nics - setup nics (ethXs) based on ibft net info * * Currently does not support vlans. * - * TODO: - * For offload cards, this will setup the ethX with the net info. - * It will not yet setup the offload card with it, but this is planned. + * If this is a offload card, this function does nothing. The + * net info is used by the iscsi iface settings for the iscsi + * function. */ int fw_setup_nics(void) { diff --git a/utils/fwparam_ibft/fwparam_ibft_sysfs.c b/utils/fwparam_ibft/fwparam_ibft_sysfs.c index 1527485..b782f5a 100644 --- a/utils/fwparam_ibft/fwparam_ibft_sysfs.c +++ b/utils/fwparam_ibft/fwparam_ibft_sysfs.c @@ -35,6 +35,7 @@ #include "fw_context.h" #include "fwparam.h" #include "sysdeps.h" +#include "iscsi_net_util.h" #define IBFT_MAX 255 #define IBFT_SYSFS_ROOT "/sys/firmware/ibft/" @@ -80,146 +81,6 @@ static int find_sysfs_dirs(const char *fpath, const struct stat *sb, return 0; } -static int get_iface_from_device(char *id, struct boot_context *context) -{ - char dev_dir[FILENAMESZ]; - int rc = ENODEV; - DIR *dirfd; - struct dirent *dent; - - memset(dev_dir, 0, FILENAMESZ); - snprintf(dev_dir, FILENAMESZ, IBFT_SYSFS_ROOT"/%s/device", id); - - if (!file_exist(dev_dir)) - return 0; - - dirfd = opendir(dev_dir); - if (!dirfd) - return errno; - - while ((dent = readdir(dirfd))) { - if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, "..") || - strncmp(dent->d_name, "net:", 4)) - continue; - - if (!strncmp(dent->d_name, "net:", 4)) { - if ((strlen(dent->d_name) - 4) > - (sizeof(context->iface) - 1)) { - rc = EINVAL; - printf("Net device %s too big for iface " - "buffer.\n", dent->d_name); - break; - } - - if (sscanf(dent->d_name, "net:%s", context->iface) != 1) - rc = EINVAL; - rc = 0; - break; - } else { - printf("Could not read ethernet to net link.\n"); - rc = EOPNOTSUPP; - break; - } - } - - closedir(dirfd); - - if (rc != ENODEV) - return rc; - - /* If not found try again with newer kernel networkdev sysfs layout */ - strlcat(dev_dir, "/net", FILENAMESZ); - - if (!file_exist(dev_dir)) - return rc; - - dirfd = opendir(dev_dir); - if (!dirfd) - return errno; - - while ((dent = readdir(dirfd))) { - if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, "..")) - continue; - - /* Take the first "regular" directory entry */ - if (strlen(dent->d_name) > (sizeof(context->iface) - 1)) { - rc = EINVAL; - printf("Net device %s too big for iface buffer.\n", - dent->d_name); - break; - } - - strcpy(context->iface, dent->d_name); - rc = 0; - break; - } - - closedir(dirfd); - - return rc; -} - -static int get_iface_from_mac(char *id, struct boot_context *context) -{ - char mac_fname[FILENAMESZ]; - char mac[18] = {0}; - int rc = ENODEV; - int fd; - int retval; - struct dirent **namelist; - int n, i; - - memset(mac_fname, 0, FILENAMESZ); - snprintf(mac_fname, FILENAMESZ, IBFT_SYSFS_ROOT"/%s/mac", id); - - if (!file_exist(mac_fname)) - return 0; - - fd = open(mac_fname, O_RDONLY); - if (fd == -1) - return errno; - - retval = read(fd, mac, 17); - if (retval == -1) - return errno; - if (retval != 17) { - printf("Couldn't read whole mac address from %s\n", mac_fname); - return EINVAL; - } - close(fd); - - n = scandir(NET_SYSFS_ROOT, &namelist, NULL, alphasort); - if (n <= 0) - return -n; - - for (i = 0; i < n; i++) { - char name[256]; - char *dir = namelist[i]->d_name; - char buf[18] = {0}; - if (!strcmp(name, ".") || !strcmp(name, "..")) - continue; - - snprintf(name, sizeof(name), "%s%s/address", NET_SYSFS_ROOT, dir); - fd = open(name, O_RDONLY); - if (fd == -1) - continue; - retval = read(fd, buf, 17); - close(fd); - - if (strncasecmp(buf, mac, 17) == 0) { - strlcpy(context->iface, dir, sizeof(context->iface)); - rc = 0; - break; - } - } - - for (i = 0; i < n; i++) - free(namelist[i]); - free(namelist); - - return rc; -} - /* * Routines to fill in the context values. */ @@ -232,10 +93,7 @@ static int fill_nic_context(char *id, struct boot_context *context) if (rc) return rc; - rc = get_iface_from_device(id, context); - if (rc) - rc = get_iface_from_mac(id, context); - + rc = net_get_dev_from_hwaddress(context->mac, context->iface); if (rc) return rc; |