summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/fw_context.h1
-rw-r--r--usr/iscsistart.c153
-rw-r--r--utils/fwparam_ibft/fw_entry.c163
3 files changed, 168 insertions, 149 deletions
diff --git a/include/fw_context.h b/include/fw_context.h
index d3971c4..abdff42 100644
--- a/include/fw_context.h
+++ b/include/fw_context.h
@@ -60,5 +60,6 @@ extern int fw_get_entry(struct boot_context *context);
extern void fw_print_entry(struct boot_context *context);
extern int fw_get_targets(struct list_head *list);
extern void fw_free_targets(struct list_head *list);
+extern int fw_setup_nics(void);
#endif /* FWPARAM_CONTEXT_H_ */
diff --git a/usr/iscsistart.c b/usr/iscsistart.c
index 2ee2674..01f4b85 100644
--- a/usr/iscsistart.c
+++ b/usr/iscsistart.c
@@ -24,7 +24,6 @@
#include <getopt.h>
#include <stdlib.h>
#include <stdio.h>
-#include <stddef.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
@@ -33,11 +32,6 @@
#include <sys/signal.h>
#include <sys/types.h>
#include <sys/wait.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <net/route.h>
#include "initiator.h"
#include "iscsi_ipc.h"
@@ -106,7 +100,7 @@ Open-iSCSI initiator.\n\
-W, --password_in=N set incoming password to N (optional\n\
-d, --debug debuglevel print debugging information \n\
-b, --fwparam_connect create a session to the target\n\
- -n, --fwparam_network bring up the network as specified by iBFT\n\
+ -N, --fwparam_network bring up the network as specified by iBFT\n\
-f, --fwparam_print print the iBFT to STDOUT \n\
-h, --help display this help and exit\n\
-v, --version display version and exit\n\
@@ -207,140 +201,6 @@ static int setup_session(void)
return rc;
}
-static int setup_nics(void)
-{
- struct boot_context *context;
- char *iface_prev = NULL;
- int sock;
- int ret;
-
- /* Create socket for making networking changes */
- if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
- perror("socket(AF_INET, SOCK_DGRAM, 0)");
- exit(1);
- }
-
- /*
- * 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) {
-
- /* 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 = -1;
- continue;
- }
- if (!inet_aton(context->ipaddr, &ipaddr.sin_addr)) {
- printf("Invalid or no ipaddr in fw entry\n");
- ret = -1;
- continue;
- }
-
- if (!inet_aton(context->mask, &netmask.sin_addr)) {
- printf("Invalid or no netmask in fw entry\n");
- ret = -1;
- 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 = -1;
- 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 = -1;
- 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 = -1;
- 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 = -1;
- continue;
- }
- }
-
- /* 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 = -1;
- 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 = -1;
- continue;
- }
- memcpy(&rt.rt_gateway, &gateway, sizeof(gateway));
- if (ioctl(sock, SIOCADDRT, &rt) < 0) {
- if (errno != EEXIST) {
- perror("ioctl(SIOCADDRT)");
- ret = -1;
- continue;
- }
- }
- }
- /* This target handled */
- }
-
- close(sock);
- fw_free_targets(&targets);
- return ret;
-}
-
-
static void catch_signal(int signo)
{
log_warning("pid %d caught signal -%d", getpid(), signo);
@@ -410,7 +270,7 @@ int main(int argc, char *argv[])
if (iscsi_sysfs_check_class_version())
exit(1);
- while ((ch = getopt_long(argc, argv, "i:t:g:a:p:d:u:w:U:W:bnfvh",
+ while ((ch = getopt_long(argc, argv, "i:t:g:a:p:d:u:w:U:W:bNfvh",
long_options, &longindex)) >= 0) {
switch (ch) {
case 'i':
@@ -474,13 +334,8 @@ int main(int argc, char *argv[])
exit(1);
}
break;
- case 'n':
- ret = fw_get_targets(&targets);
- if (ret || list_empty(&targets)) {
- printf("Could not setup fw entries.\n");
- exit(1);
- }
- ret = setup_nics();
+ case 'N':
+ ret = fw_setup_nics();
exit(ret);
case 'f':
ret = fw_get_targets(&targets);
diff --git a/utils/fwparam_ibft/fw_entry.c b/utils/fwparam_ibft/fw_entry.c
index b4f003c..479473c 100644
--- a/utils/fwparam_ibft/fw_entry.c
+++ b/utils/fwparam_ibft/fw_entry.c
@@ -21,12 +21,175 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
+#include <unistd.h>
+#include <stddef.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <net/route.h>
#include "fw_context.h"
#include "fwparam.h"
#include "idbm_fields.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.
+ */
+int fw_setup_nics(void)
+{
+ struct boot_context *context;
+ struct list_head targets;
+ char *iface_prev = NULL;
+ int sock;
+ int ret;
+
+ INIT_LIST_HEAD(&targets);
+
+ ret = fw_get_targets(&targets);
+ if (ret || list_empty(&targets)) {
+ printf("Could not setup fw entries.\n");
+ 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) {
+ /* 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;
+ 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;
+ }
+ }
+
+ /* 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 */
+ }
+
+ 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
*