summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/iscsi_net_util.h6
-rw-r--r--usr/iface.c6
-rw-r--r--usr/io.c2
-rw-r--r--usr/iscsi_net_util.c162
-rw-r--r--utils/fwparam_ibft/fw_entry.c126
-rw-r--r--utils/fwparam_ibft/fwparam_ibft_sysfs.c3
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;
diff --git a/usr/io.c b/usr/io.c
index 0b9b179..8fb806d 100644
--- a/usr/io.c
+++ b/usr/io.c
@@ -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;
}