diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/libiscsi/Makefile open-iscsi-2.0-872-rc4-bnx2i.work/libiscsi/Makefile --- open-iscsi-2.0-872-rc4-bnx2i/libiscsi/Makefile 2011-02-03 23:56:36.000000000 -0600 +++ open-iscsi-2.0-872-rc4-bnx2i.work/libiscsi/Makefile 2011-02-03 23:57:29.000000000 -0600 @@ -13,7 +13,7 @@ TESTS += tests/test_set_auth tests/test_ COMMON_SRCS = sysdeps.o # sources shared between iscsid, iscsiadm and iscsistart -ISCSI_LIB_SRCS = netlink.o uip_mgmt_ipc.o transport.o cxgbi.o be2iscsi.o iscsi_timer.o initiator_common.o iscsi_err.o session_info.o iscsi_util.o io.o auth.o discovery.o login.o log.o md5.o sha1.o iface.o idbm.o sysfs.o iscsi_sysfs.o iscsi_net_util.o iscsid_req.o +ISCSI_LIB_SRCS = dcb_app.o netlink.o uip_mgmt_ipc.o transport.o cxgbi.o be2iscsi.o iscsi_timer.o initiator_common.o iscsi_err.o session_info.o iscsi_util.o io.o auth.o discovery.o login.o log.o md5.o sha1.o iface.o idbm.o sysfs.o iscsi_sysfs.o iscsi_net_util.o iscsid_req.o FW_PARAM_SRCS = fw_entry.o prom_lex.o prom_parse.tab.o fwparam_ppc.o fwparam_sysfs.o # sources shared with the userspace utils, note we build these separately diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/dcb_app.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/dcb_app.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/dcb_app.c 1969-12-31 18:00:00.000000000 -0600 +++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/dcb_app.c 2011-02-03 23:54:11.000000000 -0600 @@ -0,0 +1,246 @@ +/******************************************************************************* + + DCB application support + Copyright(c) 2007-2010 Intel Corporation. + + This program is free software; you can redistribute it and/or modify it + under the terms and conditions of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + This program is distributed in the hope 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. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + + The full GNU General Public License is included in this distribution in + the file called "COPYING". + + Contact Information: + e1000-eedc Mailing List + Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + +*******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "dcb_app.h" +#include "sysfs.h" + +#define NLA_DATA(nla) ((void *)((char*)(nla) + NLA_HDRLEN)) + +/* Maximum size of response requested or message sent */ +#define MAX_MSG_SIZE 1024 + +static struct nlmsghdr *start_dcbmsg(__u16 msg_type, __u8 arg) +{ + struct nlmsghdr *nlh; + struct dcbmsg *d; + + nlh = malloc(MAX_MSG_SIZE); + if (!nlh) + return NULL; + memset(nlh, 0, MAX_MSG_SIZE); + nlh->nlmsg_type = msg_type; + nlh->nlmsg_flags = NLM_F_REQUEST; + nlh->nlmsg_seq = 0; + nlh->nlmsg_pid = getpid(); + if (msg_type != RTM_GETDCB) { + free(nlh); + return NULL; + } + + nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct dcbmsg)); + d = NLMSG_DATA(nlh); + d->cmd = arg; + d->dcb_family = AF_UNSPEC; + d->dcb_pad = 0; + + return nlh; +} + +static struct rtattr *add_rta(struct nlmsghdr *nlh, __u16 rta_type, + void *attr, __u16 rta_len) +{ + struct rtattr *rta; + + rta = (struct rtattr *)((char *)nlh + nlh->nlmsg_len); + rta->rta_type = rta_type; + rta->rta_len = rta_len + NLA_HDRLEN; + if (attr) + memcpy(NLA_DATA(rta), attr, rta_len); + nlh->nlmsg_len += NLMSG_ALIGN(rta->rta_len); + + return rta; +} + +static int dcbnl_send_msg(int nl_sd, struct nlmsghdr *nlh) +{ + struct sockaddr_nl nladdr; + void *buf = nlh; + int r, len = nlh->nlmsg_len; + + memset(&nladdr, 0, sizeof(nladdr)); + nladdr.nl_family = AF_NETLINK; + + do { + r = sendto(nl_sd, buf, len, 0, (struct sockaddr *)&nladdr, + sizeof(nladdr)); + } while (r < 0 && errno == EINTR); + + if (r < 0) + return 1; + + return 0; +} + +static struct nlmsghdr *dcbnl_get_msg(int nl_sd) +{ + struct nlmsghdr *nlh; + int len; + + nlh = malloc(MAX_MSG_SIZE); + if (!nlh) + return NULL; + memset(nlh, 0, MAX_MSG_SIZE); + + len = recv(nl_sd, (void *)nlh, MAX_MSG_SIZE, 0); + + if (len < 0 || nlh->nlmsg_type == NLMSG_ERROR || + !NLMSG_OK(nlh, (unsigned int)len)) { + free(nlh); + return NULL; + } + + return nlh; +} + +static int get_app_cfg(const char *ifname, __u8 req_idtype, __u16 req_id) +{ + struct nlmsghdr *nlh; + struct dcbmsg *d; + struct rtattr *rta_parent, *rta_child; + int rval = 0; + int nl_sd; + unsigned int seq; + __u8 idtype; + __u16 id; + + nlh = start_dcbmsg(RTM_GETDCB, DCB_CMD_GAPP); + if (!nlh) + return -EIO; + + seq = nlh->nlmsg_seq; + add_rta(nlh, DCB_ATTR_IFNAME, (void *)ifname, strlen(ifname) + 1); + rta_parent = add_rta(nlh, DCB_ATTR_APP, NULL, 0); + + rta_child = add_rta(nlh, DCB_APP_ATTR_IDTYPE, + (void *)&req_idtype, sizeof(__u8)); + rta_parent->rta_len += NLA_ALIGN(rta_child->rta_len); + + rta_child = add_rta(nlh, DCB_APP_ATTR_ID, + (void *)&req_id, sizeof(__u16)); + rta_parent->rta_len += NLA_ALIGN(rta_child->rta_len); + + nl_sd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); + if (nl_sd < 0) + return nl_sd; + + rval = dcbnl_send_msg(nl_sd, nlh); + free(nlh); + if (rval) { + close(nl_sd); + return -EIO; + } + + nlh = dcbnl_get_msg(nl_sd); + close(nl_sd); + if (!nlh) + return -EIO; + + d = (struct dcbmsg *)NLMSG_DATA(nlh); + rta_parent = (struct rtattr *)(((char *)d) + + NLMSG_ALIGN(sizeof(struct dcbmsg))); + + if (d->cmd != DCB_CMD_GAPP) { + rval = -EIO; + goto get_error; + } + if (rta_parent->rta_type != DCB_ATTR_APP) { + rval = -EIO; + goto get_error; + } + + rta_child = NLA_DATA(rta_parent); + rta_parent = (struct rtattr *)((char *)rta_parent + + NLMSG_ALIGN(rta_parent->rta_len)); + + idtype = *(__u8 *)NLA_DATA(rta_child); + rta_child = (struct rtattr *)((char *)rta_child + + NLMSG_ALIGN(rta_child->rta_len)); + if (idtype != req_idtype) { + rval = -EIO; + goto get_error; + } + + id = *(__u16 *)NLA_DATA(rta_child); + rta_child = (struct rtattr *)((char *)rta_child + + NLMSG_ALIGN(rta_child->rta_len)); + if (id != req_id) { + rval = -EIO; + goto get_error; + } + + rval = *(__u8 *)NLA_DATA(rta_child); + rta_child = (struct rtattr *)((char *)rta_child + + NLMSG_ALIGN(rta_child->rta_len)); + +get_error: + free(nlh); + return rval; +} + +static int get_link_ifname(const char *ifname, char *link_ifname) +{ + int ifindex; + + if (sysfs_get_int(ifname, "net", "iflink", &ifindex)) + return -EIO; + + if (!if_indextoname(ifindex, link_ifname)) + return -ENODEV; + + return 0; +} + +int get_dcb_app_pri_by_port(const char *ifname, int port) +{ + char link_ifname[IFNAMSIZ]; + + if (get_link_ifname(ifname, link_ifname)) + return 0; + + return get_app_cfg(link_ifname, DCB_APP_IDTYPE_PORTNUM, port); +} + +int get_dcb_app_pri_by_ethtype(const char *ifname, int ethtype) +{ + char link_ifname[IFNAMSIZ]; + + if (get_link_ifname(ifname, link_ifname)) + return 0; + + return get_app_cfg(link_ifname, DCB_APP_IDTYPE_ETHTYPE, ethtype); +} diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/dcb_app.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/dcb_app.h --- open-iscsi-2.0-872-rc4-bnx2i/usr/dcb_app.h 1969-12-31 18:00:00.000000000 -0600 +++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/dcb_app.h 2011-02-03 23:54:07.000000000 -0600 @@ -0,0 +1,34 @@ +/******************************************************************************* + + DCB application support + Copyright(c) 2007-2010 Intel Corporation. + + This program is free software; you can redistribute it and/or modify it + under the terms and conditions of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + This program is distributed in the hope 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. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + + The full GNU General Public License is included in this distribution in + the file called "COPYING". + + Contact Information: + e1000-eedc Mailing List + Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + +*******************************************************************************/ + +#ifndef _DCB_APP_H_ +#define _DCB_APP_H_ + +int get_dcb_app_pri_by_port(const char *iface, int port); +int get_dcb_app_pri_by_ethtype(const char *iface, int ethtype); + +#endif /* _DCB_APP_H_ */ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/io.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/io.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/io.c 2011-02-04 00:02:19.000000000 -0600 +++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/io.c 2011-02-03 23:54:15.000000000 -0600 @@ -26,11 +26,14 @@ #include #include #include +#include +#include #include #include #include "types.h" #include "iscsi_proto.h" +#include "iscsi_settings.h" #include "initiator.h" #include "iscsi_ipc.h" #include "log.h" @@ -38,6 +41,7 @@ #include "idbm.h" #include "iface.h" #include "sysdeps.h" +#include "dcb_app.h" #define LOG_CONN_CLOSED(conn) \ do { \ @@ -53,6 +57,13 @@ do { \ log_error("Connection to Discovery Address %s failed", conn->host); \ } while (0) +union sockaddr_u { + struct sockaddr_storage ss; + struct sockaddr sa; + struct sockaddr_in si; + struct sockaddr_in6 si6; +}; + static int timedout; static void @@ -76,6 +87,90 @@ set_non_blocking(int fd) } +static int select_priority(struct iscsi_conn *conn, int pri_mask) +{ + int msk; + + if (!pri_mask) + return 0; + + /* + * TODO: Configure priority selection from the mask + * For now, just always take the highest + */ + + /* Find highest bit set */ + while ((msk = pri_mask & (pri_mask - 1))) + pri_mask = msk; + + return ffs(pri_mask) - 1; +} + +static int +inet_cmp_addr(const union sockaddr_u *s1, const union sockaddr_u *s2) +{ + const struct sockaddr_in *si1 = &s1->si; + const struct sockaddr_in *si2 = &s2->si; + + return si1->sin_addr.s_addr != si2->sin_addr.s_addr; +} + +static int +inet6_cmp_addr(const union sockaddr_u *s1, const union sockaddr_u *s2) +{ + const struct sockaddr_in6 *si1 = &s1->si6; + const struct sockaddr_in6 *si2 = &s2->si6; + + return memcmp(&si1->sin6_addr, &si2->sin6_addr, sizeof(si1->sin6_addr)); +} + +static char * +find_ifname(const struct ifaddrs *ifa, const union sockaddr_u *ss) +{ + for (; ifa; ifa = ifa->ifa_next) { + if (ss->ss.ss_family != ifa->ifa_addr->sa_family) + continue; + switch (ss->ss.ss_family) { + case AF_INET: + if (inet_cmp_addr(ss, (union sockaddr_u *)ifa->ifa_addr) == 0) + return ifa->ifa_name; + break; + case AF_INET6: + if (inet6_cmp_addr(ss, (union sockaddr_u *)ifa->ifa_addr) == 0) + return ifa->ifa_name; + break; + } + } + + return NULL; +} + +static void set_dcb_priority(struct iscsi_conn *conn, const char *devname) +{ + int pri_mask = 0; + + pri_mask = get_dcb_app_pri_by_port(devname, ISCSI_DEFAULT_PORT); + if (pri_mask < 0) + log_debug(2, "Getting priority for %s returned %d", + devname, pri_mask); + else if (pri_mask == 0) + log_debug(2, "No priority for %s", devname); + else { + int pri = select_priority(conn, pri_mask); + int rc; + + log_debug(1, "Setting socket %d priority to %d", + conn->socket_fd, pri); + rc = setsockopt(conn->socket_fd, SOL_SOCKET, + SO_PRIORITY, &pri, sizeof(pri)); + if (rc < 0) { + log_warning("Setting socket %d priority to %d failed " + "with errno %d", conn->socket_fd, + pri, errno); + } + } +} + #if 0 /* not used by anyone */ static int get_hwaddress_from_netdev(char *netdev, char *hwaddress) @@ -320,6 +415,10 @@ iscsi_io_tcp_connect(iscsi_conn_t *conn, log_debug(1, "connecting to %s:%s", conn->host, serv); if (non_blocking) set_non_blocking(conn->socket_fd); + + if (conn->session->netdev[0]) + set_dcb_priority(conn, conn->session->netdev); + rc = connect(conn->socket_fd, (struct sockaddr *) ss, sizeof (*ss)); return rc; } @@ -368,8 +467,9 @@ iscsi_io_tcp_poll(iscsi_conn_t *conn, in } len = sizeof(ss); - if (log_level > 0 && - getsockname(conn->socket_fd, (struct sockaddr *) &ss, &len) >= 0) { + if (log_level > 0 || !conn->session->netdev) + rc = getsockname(conn->socket_fd, (struct sockaddr *)&ss, &len); + if (log_level > 0 && rc >= 0) { getnameinfo((struct sockaddr *) &conn->saddr, sizeof(conn->saddr), conn->host, sizeof(conn->host), serv, sizeof(serv), @@ -381,6 +481,22 @@ iscsi_io_tcp_poll(iscsi_conn_t *conn, in log_debug(1, "connected local port %s to %s:%s", lserv, conn->host, serv); } + + if (!conn->session->netdev[0] && rc >= 0) { + struct ifaddrs *ifa; + char *ifname; + + rc = getifaddrs(&ifa); + if (rc < 0) + log_error("getifaddrs failed with %d\n", errno); + else { + ifname = find_ifname(ifa, (union sockaddr_u *)&ss); + if (ifname) + set_dcb_priority(conn, ifname); + freeifaddrs(ifa); + } + } + return 1; } diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/Makefile open-iscsi-2.0-872-rc4-bnx2i.work/usr/Makefile --- open-iscsi-2.0-872-rc4-bnx2i/usr/Makefile 2011-02-04 00:02:19.000000000 -0600 +++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/Makefile 2011-02-03 23:54:31.000000000 -0600 @@ -21,10 +21,12 @@ ifeq ($(OSNAME),Linux) endif endif IPC_OBJ=netlink.o +DCB_OBJ=dcb_app.o else ifeq ($(OSNAME),FreeBSD) IPC_CFLAGS= IPC_OBJ=ioctl.o +DCB_OBJ= endif endif @@ -40,7 +42,7 @@ SYSDEPS_SRCS = $(wildcard ../utils/sysde ISCSI_LIB_SRCS = iscsi_util.o io.o auth.o iscsi_timer.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 iscsid_req.o transport.o cxgbi.o be2iscsi.o \ - initiator_common.o iscsi_err.o uip_mgmt_ipc.o $(IPC_OBJ) $(SYSDEPS_SRCS) + initiator_common.o iscsi_err.o uip_mgmt_ipc.o $(DCB_OBJ) $(IPC_OBJ) $(SYSDEPS_SRCS) # core initiator files INITIATOR_SRCS = initiator.o scsi.o actor.o event_poll.o mgmt_ipc.o diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/Makefile.orig open-iscsi-2.0-872-rc4-bnx2i.work/usr/Makefile.orig --- open-iscsi-2.0-872-rc4-bnx2i/usr/Makefile.orig 1969-12-31 18:00:00.000000000 -0600 +++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/Makefile.orig 2011-02-03 23:53:53.000000000 -0600 @@ -0,0 +1,71 @@ +# This Makefile will work only with GNU make. + +OSNAME=$(shell uname -s) + +# allow users to override these +# eg to compile for a kernel that you aren't currently running +KERNELRELEASE ?= $(shell uname -r) +KSRC ?= /lib/modules/$(KERNELRELEASE)/build + +KSUBLEVEL=$(shell cat $(KSRC)/Makefile | awk -F= '/^SUBLEVEL =/ {print $$2}' | \ + sed 's/^[ \t]*//;s/[ \t]*$$//') + +ifeq ($(OSNAME),Linux) + ifeq ($(KSUBLEVEL),11) + IPC_CFLAGS=-DNETLINK_ISCSI=12 -D_GNU_SOURCE + else + ifeq ($(KSUBLEVEL),12) + IPC_CFLAGS=-DNETLINK_ISCSI=12 -D_GNU_SOURCE + else + IPC_CFLAGS=-DNETLINK_ISCSI=8 -D_GNU_SOURCE + endif + endif +IPC_OBJ=netlink.o +else +ifeq ($(OSNAME),FreeBSD) +IPC_CFLAGS= +IPC_OBJ=ioctl.o +endif +endif + +OPTFLAGS ?= -O2 -g +WARNFLAGS ?= -Wall -Wstrict-prototypes +CFLAGS += $(OPTFLAGS) $(WARNFLAGS) -I../include -I. -I../utils/open-isns \ + -D$(OSNAME) $(IPC_CFLAGS) -DISNS_ENABLE +PROGRAMS = iscsid iscsiadm iscsistart + +# libc compat files +SYSDEPS_SRCS = $(wildcard ../utils/sysdeps/*.o) +# sources shared between iscsid, iscsiadm and iscsistart +ISCSI_LIB_SRCS = iscsi_util.o io.o auth.o iscsi_timer.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 iscsid_req.o transport.o cxgbi.o be2iscsi.o \ + initiator_common.o iscsi_err.o uip_mgmt_ipc.o $(IPC_OBJ) $(SYSDEPS_SRCS) +# core initiator files +INITIATOR_SRCS = initiator.o scsi.o actor.o event_poll.o mgmt_ipc.o + +# fw boot files +FW_BOOT_SRCS = $(wildcard ../utils/fwparam_ibft/*.o) + +# core discovery files +DISCOVERY_SRCS = $(FW_BOOT_SRCS) strings.o discovery.o + +all: $(PROGRAMS) + +iscsid: $(ISCSI_LIB_SRCS) $(INITIATOR_SRCS) $(DISCOVERY_SRCS) \ + iscsid.o session_mgmt.o discoveryd.o + $(CC) $(CFLAGS) $^ -o $@ -L../utils/open-isns -lisns + +iscsiadm: $(ISCSI_LIB_SRCS) $(DISCOVERY_SRCS) iscsiadm.o session_mgmt.o + $(CC) $(CFLAGS) $^ -o $@ -L../utils/open-isns -lisns + +iscsistart: $(ISCSI_LIB_SRCS) $(INITIATOR_SRCS) $(FW_BOOT_SRCS) \ + iscsistart.o statics.o + $(CC) $(CFLAGS) $^ -o $@ +clean: + rm -f *.o $(PROGRAMS) .depend $(LIBSYS) + +depend: + gcc $(CFLAGS) -M `ls *.c` > .depend + +-include .depend diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/sysfs.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/sysfs.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/sysfs.c 2011-02-04 00:02:19.000000000 -0600 +++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/sysfs.c 2011-02-03 23:54:03.000000000 -0600 @@ -547,7 +547,7 @@ found: } -char *sysfs_get_value(char *id, char *subsys, char *param) +char *sysfs_get_value(const char *id, char *subsys, char *param) { char devpath[PATH_SIZE]; char *sysfs_value; @@ -590,7 +590,7 @@ int sysfs_get_uint(char *id, char *subsy return 0; } -int sysfs_get_int(char *id, char *subsys, char *param, int *value) +int sysfs_get_int(const char *id, char *subsys, char *param, int *value) { char *sysfs_value; diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/sysfs.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/sysfs.h --- open-iscsi-2.0-872-rc4-bnx2i/usr/sysfs.h 2011-02-04 00:02:19.000000000 -0600 +++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/sysfs.h 2011-02-03 23:54:03.000000000 -0600 @@ -51,10 +51,10 @@ extern char *sysfs_attr_get_value(const extern int sysfs_resolve_link(char *path, size_t size); extern int sysfs_lookup_devpath_by_subsys_id(char *devpath, size_t len, const char *subsystem, const char *id); -extern char *sysfs_get_value(char *id, char *subsys, char *param); +extern char *sysfs_get_value(const char *id, char *subsys, char *param); extern int sysfs_get_uint(char *id, char *subsys, char *param, unsigned int *value); -extern int sysfs_get_int(char *id, char *subsys, char *param, int *value); +extern int sysfs_get_int(const char *id, char *subsys, char *param, int *value); extern int sysfs_get_str(char *id, char *subsys, char *param, char *value, int value_size); extern int sysfs_get_uint64(char *id, char *subsys, char *param,