diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/RELEASE.TXT open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/RELEASE.TXT --- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/RELEASE.TXT 2011-10-26 07:21:46.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/RELEASE.TXT 2011-10-26 17:55:59.000000000 -0500 @@ -1,7 +1,7 @@ Release Notes Broadcom uIP Linux Driver Version 0.7.0.14 - 08/23/2011 + 10/25/2011 Broadcom Corporation 5300 California Avenue, @@ -10,7 +10,7 @@ Copyright (c) 2004 - 2011 Broadcom Corporation All rights reserved -uIP v0.7.0.14 (Aug 23, 2011) +uIP v0.7.0.14 (Oct 25, 2011) ======================================================= Fixes ----- @@ -23,11 +23,56 @@ uIP v0.7.0.14 (Aug 23, 2011) Change: Adjusted the routine which seeks the device->net entry to include more logic instead of hard waiting for 5s. + 2. Problem: Cont00058256 - Sessions fail after loginstress to via + simultaneous ipv4 and ipv6 dhcp + Cause: Switching between DHCPv4/v6 coupled with VLAN exposed + a drawback in our nic_iface architecture design where + VLAN is not specified by iscsid. + Change: The code was optimized and improved the performance when + switching between DHCPv4/v6+VLAN. However, the ultimate + fix is to make use of the net config parameters introduced + in the newer open-iscsi util which will identify the + specific VLAN nic_iface to use. + + 3. Problem: Cont00058602 - Can't iboot using IPv6 offload path + Cause: The bug was exposed by a fix in 0.7.0.14c where the + IPv6 router solicitation timeout exceeded the nic + enable thread timeout. + Change: The IPv6 router solicitation timeout has been adjusted + + 4. Problem: Cont00058678 - Can not iboot target from ipv6 path + using VLAN + Cause: A bug was found in the path request path where the vlan + iface's protocol family was not used correctly in the + iface search + Change: This has been corrected + + 5. Problem: Cont00058994 - DOS vulnerability in uip during UDP flood + Cause: The warning messages from the UDP handler was logging + at a rate faster than the log file logrotate rate + Therefore, the system's OOM eventually got kicked in to + start terminating running processes which includes iscsiuio + Change: Moved several UDP warning messages from the default log + level to the debug log level + Impact: All (minor) + + 6. Problem: Cont00059288 - Show segfault w/ Xen kernel + Cause: The bnx2x chip_id was not read correctly from the PCIe BAR1 + under the Xen kernel. The error was in the mmap area. + Change: Corrected the mmapping of the PCI MMIO space. + Impact: Xen kernels + Enhancements ------------ 1. Change: Added support for RHEL6.2 for out-of-box release 2. Change: Updated the man page with -h and -p info 3. Change: Updated the -h info + 4. Change: Added support for bnx2x-1.71.00 + 5. Change: Changed the log file open error to a warning and let + the daemon progress + 6. Change: Added oom_adjust call to prevent OOM Killer from killing + iscsiuio when memory is low + 7. Change: Added mlockall setting to prevent page swap uIP v0.7.0.13 (Aug 10, 2011) diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/uip.c open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/uip.c --- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/uip.c 2011-10-26 07:21:27.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/uip.c 2011-10-26 17:55:59.000000000 -0500 @@ -1300,7 +1300,7 @@ void uip_process(struct uip_stack *ustac u16_t len = ntohs(ipv6_hdr->ip6_plen); if (len <= ustack->uip_len) { } else { - LOG_WARN(PFX + LOG_DEBUG(PFX "ip: packet shorter than reported in IP header" ":IPv6_BUF(ustack)->len: %d ustack->uip_len: " "%d", len, ustack->uip_len); @@ -1312,7 +1312,7 @@ void uip_process(struct uip_stack *ustac ustack->uip_len = (tcp_ipv4_hdr->len[0] << 8) + tcp_ipv4_hdr->len[1]; } else { - LOG_WARN(PFX + LOG_DEBUG(PFX "ip: packet shorter than reported in IP header" ":tcp_ipv4_hdr->len: %d ustack->uip_len:%d.", (tcp_ipv4_hdr->len[0] << 8) + @@ -1505,7 +1505,7 @@ icmp_input: if (UDPBUF(ustack)->udpchksum != 0 && uip_udpchksum(ustack) != 0xffff) { ++ustack->stats.udp.drop; ++ustack->stats.udp.chkerr; - LOG_WARN(PFX "udp: bad checksum."); + LOG_DEBUG(PFX "udp: bad checksum."); goto drop; } #else /* UIP_UDP_CHECKSUMS */ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/iscsid_ipc.c open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/iscsid_ipc.c --- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/iscsid_ipc.c 2011-10-26 07:21:46.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/iscsid_ipc.c 2011-10-26 17:55:59.000000000 -0500 @@ -111,8 +111,8 @@ static void *enable_nic_thread(void *dat LOG_INFO(PFX "%s: started NIC enable thread state: 0x%x", nic->log_name, nic->state) - /* Enable the NIC */ - nic_enable(nic); + /* Enable the NIC */ + nic_enable(nic); pthread_exit(NULL); } @@ -206,7 +206,7 @@ static int parse_iface(void *arg) { int rc; nic_t *nic = NULL; - nic_interface_t *nic_iface, *next_nic_iface; + nic_interface_t *nic_iface, *vlan_iface, *base_nic_iface; char *transport_name; size_t transport_name_size; nic_lib_handle_t *handle; @@ -356,24 +356,22 @@ static int parse_iface(void *arg) LOG_INFO(PFX "%s library set using transport_name %s", nic->log_name, transport_name); - /* Create the network interface if it doesn't exist */ - nic_iface = nic_find_nic_iface_protocol(nic, vlan, ipam.ip_type); + /* Create the base network interface if it doesn't exist */ + nic_iface = nic_find_nic_iface_protocol(nic, 0, ipam.ip_type); if (nic_iface == NULL) { - LOG_INFO(PFX "%s couldn't find VLAN %d interface with " + LOG_INFO(PFX "%s couldn't find interface with " "ip_type: 0x%x creating it", - nic->log_name, vlan, ipam.ip_type); + nic->log_name, ipam.ip_type); - /* Create the vlan interface */ + /* Create the nic interface */ nic_iface = nic_iface_init(); if (nic_iface == NULL) { - LOG_ERR(PFX "Couldn't allocate nic_iface for VLAN: %d", - nic_iface, vlan); + LOG_ERR(PFX "Couldn't allocate nic_iface", nic_iface); goto done; } nic_iface->protocol = ipam.ip_type; - nic_iface->vlan_id = vlan; nic_add_nic_iface(nic, nic_iface); persist_all_nic_iface(nic); @@ -384,6 +382,37 @@ static int parse_iface(void *arg) nic->log_name); } + set_nic_iface(nic, nic_iface); + + /* Find the vlan nic_interface */ + if (vlan) { + vlan_iface = nic_find_vlan_iface_protocol(nic, nic_iface, vlan, + ipam.ip_type); + if (vlan_iface == NULL) { + LOG_INFO(PFX "%s couldn't find interface with VLAN = %d" + "ip_type: 0x%x creating it", + nic->log_name, vlan, ipam.ip_type); + + /* Create the nic interface */ + vlan_iface = nic_iface_init(); + + if (vlan_iface == NULL) { + LOG_ERR(PFX "Couldn't allocate nic_iface for " + "VLAN: %d", vlan_iface, vlan); + goto done; + } + + vlan_iface->protocol = ipam.ip_type; + vlan_iface->vlan_id = vlan; + nic_add_vlan_iface(nic, nic_iface, vlan_iface); + } else { + LOG_INFO(PFX "%s: using existing vlan interface", + nic->log_name); + } + base_nic_iface = nic_iface; + nic_iface = vlan_iface; + } + /* Determine how to configure the IP address */ if (ipam.ip_type == AF_INET) { if (memcmp(&ipam.addr4, @@ -509,24 +538,27 @@ diff: } /* Configuration changed, do VLAN WA */ - next_nic_iface = nic_iface->next; - while (next_nic_iface) { - if (next_nic_iface->vlan_id) { - /* TODO: When VLAN support is placed in the iface file - * revisit this code */ - next_nic_iface->ustack.ip_config = + vlan_iface = nic_iface->vlan_next; + while (vlan_iface) { + /* TODO: When VLAN support is placed in the iface file + * revisit this code */ + if (vlan_iface->ustack.ip_config) { + vlan_iface->ustack.ip_config = nic_iface->ustack.ip_config; - memcpy(next_nic_iface->ustack.hostaddr, + memcpy(vlan_iface->ustack.hostaddr, nic_iface->ustack.hostaddr, sizeof(nic_iface->ustack.hostaddr)); - memcpy(next_nic_iface->ustack.netmask, + memcpy(vlan_iface->ustack.netmask, nic_iface->ustack.netmask, sizeof(nic_iface->ustack.netmask)); - memcpy(next_nic_iface->ustack.hostaddr6, + memcpy(vlan_iface->ustack.hostaddr6, nic_iface->ustack.hostaddr6, sizeof(nic_iface->ustack.hostaddr6)); + memcpy(vlan_iface->ustack.netmask6, + nic_iface->ustack.netmask6, + sizeof(nic_iface->ustack.netmask6)); } - next_nic_iface = next_nic_iface->next; + vlan_iface = vlan_iface->vlan_next; } enable_nic: diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/libs/bnx2.c open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/libs/bnx2.c --- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/libs/bnx2.c 2011-10-26 07:21:27.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/libs/bnx2.c 2011-10-26 17:55:59.000000000 -0500 @@ -396,6 +396,7 @@ static bnx2_t *bnx2_alloc(nic_t * nic) /* Clear out the bnx2 contents */ memset(bp, 0, sizeof(*bp)); + bp->bar0_fd = INVALID_FD; bp->flags = BNX2_UIO_TX_HAS_SENT; bp->parent = nic; @@ -417,6 +418,7 @@ static int bnx2_open(nic_t * nic) __u32 val; uint32_t tx_cid; __u32 msix_vector = 0; + char sysfs_resc_path[80]; /* Sanity Check: validate the parameters */ if (nic == NULL) { @@ -465,6 +467,14 @@ static int bnx2_open(nic_t * nic) } nic->uio_minor = minor(uio_stat.st_rdev); + cnic_get_sysfs_pci_resource_path(nic, 0, sysfs_resc_path, 80); + bp->bar0_fd = open(sysfs_resc_path, O_RDWR | O_SYNC); + if (bp->bar0_fd < 0) { + LOG_ERR(PFX "%s: Could not open %s", nic->log_name, + sysfs_resc_path); + return -ENODEV; + } + /* TODO: hardcoded with the cnic driver */ bp->rx_ring_size = 3; bp->rx_buffer_size = 0x400; @@ -498,7 +508,7 @@ static int bnx2_open(nic_t * nic) mlock(bp->rx_pkt_ring, sizeof(void *) * bp->rx_ring_size); bp->reg = mmap(NULL, 0x12800, PROT_READ | PROT_WRITE, MAP_SHARED, - nic->fd, (off_t) 0); + bp->bar0_fd, (off_t) 0); if (bp->reg == MAP_FAILED) { LOG_INFO(PFX "%s: Couldn't mmap registers: %s", nic->log_name, strerror(errno)); @@ -758,6 +768,11 @@ static int bnx2_uio_close_resources(nic_ bp->reg = NULL; } + if (bp->bar0_fd != INVALID_FD) { + close(bp->bar0_fd); + bp->bar0_fd = INVALID_FD; + } + if (nic->fd != INVALID_FD) { rc = close(nic->fd); if (rc != 0) { diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/libs/bnx2.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/libs/bnx2.h --- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/libs/bnx2.h 2011-10-26 07:21:27.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/libs/bnx2.h 2011-10-26 17:55:59.000000000 -0500 @@ -250,6 +250,7 @@ typedef struct bnx2 { #define BNX2_UIO_TX_HAS_SENT 0x0002 #define BNX2_OPENED 0x0004 + int bar0_fd; void *reg; /* Pointer to the mapped registers */ __u32 tx_bidx_io; diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/libs/bnx2x.c open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/libs/bnx2x.c --- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/libs/bnx2x.c 2011-10-26 07:21:46.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/libs/bnx2x.c 2011-10-26 17:55:59.000000000 -0500 @@ -77,9 +77,6 @@ static const char library_uio_name[] = " static const char cnic_uio_sysfs_name_tempate[] = "/sys/class/uio/uio%i/name"; static const char bnx2x_uio_sysfs_name[] = "bnx2x_cnic"; -static const char cnic_uio_sysfs_resc_tempate[] = - "/sys/class/uio/uio%i/device/resource"; - /******************************************************************************* * String constants used to display human readable adapter name ******************************************************************************/ @@ -377,7 +374,7 @@ error: static inline int bnx2x_is_ver70(bnx2x_t *bp) { - return (bp->version.major == 1 && bp->version.minor == 70); + return (bp->version.major == 1 && bp->version.minor >= 70); } static inline int bnx2x_is_ver60(bnx2x_t * bp) @@ -506,44 +503,10 @@ static int bnx2x_uio_verify(nic_t * nic) LOG_INFO(PFX "%s: Verified is a cnic_uio device", nic->log_name); - error: +error: return rc; } -static unsigned long cnic_get_bar2(nic_t * nic) -{ - char *raw = NULL, *raw_tmp; - uint32_t raw_size = 0; - char temp_path[sizeof(cnic_uio_sysfs_resc_tempate) + 8]; - int rc = 0, i, new_line; - unsigned long bar = 0; - - /* Build the path to determine uio name */ - snprintf(temp_path, sizeof(temp_path), - cnic_uio_sysfs_resc_tempate, nic->uio_minor); - - rc = capture_file(&raw, &raw_size, temp_path); - if (rc != 0) - return 0; - - /* Skip 2 lines to get to BAR2 */ - raw_tmp = raw; - i = 0; - new_line = 0; - while (i++ < raw_size && new_line < 2) { - if (*raw_tmp == '\n') - new_line++; - raw_tmp++; - } - - if (new_line == 2) - sscanf(raw_tmp, "%lx ", &bar); - - free(raw); - - return bar; -} - /******************************************************************************* * bnx2x Utility Functions to get to the hardware consumer indexes ******************************************************************************/ @@ -635,7 +598,8 @@ static bnx2x_t *bnx2x_alloc(nic_t * nic) /* Clear out the CNIC contents */ memset(bp, 0, sizeof(*bp)); - bp->mem_fd = INVALID_FD; + bp->bar0_fd = INVALID_FD; + bp->bar2_fd = INVALID_FD; bp->parent = nic; nic->priv = (void *)bp; @@ -657,9 +621,8 @@ static int bnx2x_open(nic_t * nic) struct stat uio_stat; int i, rc; __u32 val; - unsigned long bar2; int count; - + char sysfs_resc_path[80]; uint32_t bus; uint32_t slot; uint32_t func; @@ -722,20 +685,37 @@ static int bnx2x_open(nic_t * nic) } nic->uio_minor = minor(uio_stat.st_rdev); - bar2 = cnic_get_bar2(nic); - if (bar2 == 0) { - LOG_ERR(PFX "%s: Could not read BAR2", nic->log_name); + cnic_get_sysfs_pci_resource_path(nic, 0, sysfs_resc_path, 80); + bp->bar0_fd = open(sysfs_resc_path, O_RDWR | O_SYNC); + if (bp->bar0_fd < 0) { + LOG_ERR(PFX "%s: Could not open %s", nic->log_name, + sysfs_resc_path); return -ENODEV; } - bp->mem_fd = open("/dev/mem", O_RDWR | O_SYNC); - if (bp->mem_fd < 0) { - LOG_ERR(PFX "%s: Could not open /dev/mem", nic->log_name); + bp->reg = mmap(NULL, BNX2X_BAR_SIZE, PROT_READ | PROT_WRITE, + MAP_SHARED, bp->bar0_fd, (off_t) 0); + + if (bp->reg == MAP_FAILED) { + LOG_INFO(PFX "%s: Couldn't mmap BAR registers: %s", + nic->log_name, strerror(errno)); + bp->reg = NULL; + rc = errno; + goto open_error; + } + + msync(bp->reg, BNX2X_BAR_SIZE, MS_SYNC); + + cnic_get_sysfs_pci_resource_path(nic, 2, sysfs_resc_path, 80); + bp->bar2_fd = open(sysfs_resc_path, O_RDWR | O_SYNC); + if (bp->bar2_fd < 0) { + LOG_ERR(PFX "%s: Could not open %s", nic->log_name, + sysfs_resc_path); return -ENODEV; } bp->reg2 = mmap(NULL, BNX2X_BAR2_SIZE, PROT_READ | PROT_WRITE, - MAP_SHARED, bp->mem_fd, (off_t) bar2); + MAP_SHARED, bp->bar2_fd, (off_t) 0); if (bp->reg2 == MAP_FAILED) { LOG_INFO(PFX "%s: Couldn't mmap BAR2 registers: %s", @@ -768,18 +748,6 @@ static int bnx2x_open(nic_t * nic) goto open_error; } - bp->reg = mmap(NULL, BNX2X_BAR_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, - nic->fd, (off_t) 0); - if (bp->reg == MAP_FAILED) { - LOG_INFO(PFX "%s: Couldn't mmap registers: %s", - nic->log_name, strerror(errno)); - bp->reg = NULL; - rc = errno; - goto open_error; - } - - msync(bp->reg, BNX2X_BAR_SIZE, MS_SYNC); - if (bnx2x_is_ver60_plus(bp)) bp->status_blk_size = sizeof(struct host_sp_status_block); else if (bnx2x_is_ver52(bp)) @@ -1036,9 +1004,14 @@ open_error: bp->rx_pkt_ring = NULL; } - if (bp->mem_fd != INVALID_FD) { - close(bp->mem_fd); - bp->mem_fd = INVALID_FD; + if (bp->bar2_fd != INVALID_FD) { + close(bp->bar2_fd); + bp->bar2_fd = INVALID_FD; + } + + if (bp->bar0_fd != INVALID_FD) { + close(bp->bar0_fd); + bp->bar0_fd = INVALID_FD; } return rc; @@ -1108,9 +1081,14 @@ static int bnx2x_uio_close_resources(nic bp->reg2 = NULL; } - if (bp->mem_fd != INVALID_FD) { - close(bp->mem_fd); - bp->mem_fd = INVALID_FD; + if (bp->bar2_fd != INVALID_FD) { + close(bp->bar2_fd); + bp->bar2_fd = INVALID_FD; + } + + if (bp->bar0_fd != INVALID_FD) { + close(bp->bar0_fd); + bp->bar0_fd = INVALID_FD; } if (nic->fd != INVALID_FD) { diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/libs/bnx2x.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/libs/bnx2x.h --- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/libs/bnx2x.h 2011-10-26 07:21:27.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/libs/bnx2x.h 2011-10-26 17:55:59.000000000 -0500 @@ -574,7 +574,8 @@ typedef struct bnx2x { void *reg; /* Pointer to the BAR1 mapped registers */ void *reg2; /* Pointer to the BAR2 mapped registers */ - int mem_fd; + int bar0_fd; + int bar2_fd; __u32 chip_id; __u32 shmem_base; diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/libs/cnic.c open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/libs/cnic.c --- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/libs/cnic.c 2011-10-26 07:21:46.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/libs/cnic.c 2011-10-26 17:55:59.000000000 -0500 @@ -325,7 +325,7 @@ int cnic_handle_ipv4_iscsi_path_req(nic_ struct iscsi_uevent *ev, struct iscsi_path *path) { - nic_interface_t *nic_iface; + nic_interface_t *nic_iface, *vlan_iface; struct in_addr src_addr, dst_addr, src_matching_addr, dst_matching_addr, netmask; __u8 mac_addr[6]; @@ -338,18 +338,50 @@ int cnic_handle_ipv4_iscsi_path_req(nic_ pthread_mutex_lock(&nic_list_mutex); /* Find the proper interface via VLAN id */ - nic_iface = nic_find_nic_iface_protocol(nic, path->vlan_id, AF_INET); + nic_iface = nic_find_nic_iface_protocol(nic, 0, AF_INET); if (nic_iface == NULL) { - nic_iface = nic_find_nic_iface_protocol(nic, 0, AF_INET); - if (nic_iface == NULL) { - pthread_mutex_unlock(&nic_list_mutex); - LOG_ERR(PFX "%s: Couldn't find net_iface vlan_id: %d", - nic->log_name, path->vlan_id); - return -EINVAL; - } + pthread_mutex_unlock(&nic_list_mutex); + LOG_ERR(PFX "%s: Couldn't find net_iface vlan_id: %d", + nic->log_name, path->vlan_id); + return -EINVAL; + } + if (path->vlan_id) { + vlan_iface = nic_find_vlan_iface_protocol(nic, nic_iface, + path->vlan_id, + AF_INET); + if (vlan_iface == NULL) { + LOG_INFO(PFX "%s couldn't find interface with VLAN = %d" + "ip_type: 0x%x creating it", + nic->log_name, path->vlan_id, AF_INET); + + /* Create the nic interface */ + vlan_iface = nic_iface_init(); + + if (vlan_iface == NULL) { + LOG_ERR(PFX "Couldn't allocate nic_iface for " + "VLAN: %d", vlan_iface, + path->vlan_id); + return -EINVAL; + } - nic_iface->vlan_id = path->vlan_id; + vlan_iface->protocol = nic_iface->protocol; + vlan_iface->vlan_id = path->vlan_id; + vlan_iface->ustack.ip_config = + nic_iface->ustack.ip_config; + memcpy(vlan_iface->ustack.hostaddr, + nic_iface->ustack.hostaddr, + sizeof(nic_iface->ustack.hostaddr)); + memcpy(vlan_iface->ustack.netmask, + nic_iface->ustack.netmask, + sizeof(nic_iface->ustack.netmask)); + nic_add_vlan_iface(nic, nic_iface, vlan_iface); + } else { + LOG_INFO(PFX "%s: using existing vlan interface", + nic->log_name); + } + nic_iface = vlan_iface; } + #define MAX_ARP_RETRY 4 memcpy(&dst_addr, &path->dst.v4_addr, sizeof(dst_addr)); @@ -364,6 +396,9 @@ int cnic_handle_ipv4_iscsi_path_req(nic_ src_matching_addr.s_addr = src_addr.s_addr & netmask.s_addr; dst_matching_addr.s_addr = dst_addr.s_addr & netmask.s_addr; + LOG_DEBUG(PFX "%s: src=%s", nic->log_name, inet_ntoa(src_addr)); + LOG_DEBUG(PFX "%s: dst=%s", nic->log_name, inet_ntoa(dst_addr)); + LOG_DEBUG(PFX "%s: nm=%s", nic->log_name, inet_ntoa(netmask)); if (src_matching_addr.s_addr != dst_matching_addr.s_addr) { /* If there is an assigned gateway address then use it * if the source address doesn't match */ @@ -374,6 +409,7 @@ int cnic_handle_ipv4_iscsi_path_req(nic_ sizeof(dst_addr)); } else { arp_retry = MAX_ARP_RETRY; + LOG_DEBUG(PFX "%s: no default", nic->log_name); goto done; } } @@ -473,7 +509,7 @@ int cnic_handle_ipv6_iscsi_path_req(nic_ struct iscsi_uevent *ev, struct iscsi_path *path) { - nic_interface_t *nic_iface; + nic_interface_t *nic_iface, *vlan_iface; __u8 mac_addr[6]; int rc, i; uint16_t neighbor_retry; @@ -492,18 +528,49 @@ int cnic_handle_ipv6_iscsi_path_req(nic_ pthread_mutex_lock(&nic_list_mutex); /* Find the proper interface via VLAN id */ - nic_iface = nic_find_nic_iface_protocol(nic, path->vlan_id, AF_INET6); + nic_iface = nic_find_nic_iface_protocol(nic, 0, AF_INET6); if (nic_iface == NULL) { - nic_iface = nic_find_nic_iface_protocol(nic, 0, AF_INET6); - if (nic_iface == NULL) { - pthread_mutex_unlock(&nic_list_mutex); - LOG_ERR(PFX "%s: Couldn't find net_iface vlan_id: %d", - nic->log_name, path->vlan_id); - return -EINVAL; + pthread_mutex_unlock(&nic_list_mutex); + LOG_ERR(PFX "%s: Couldn't find net_iface vlan_id: %d", + nic->log_name, path->vlan_id); + return -EINVAL; + } + if (path->vlan_id) { + vlan_iface = nic_find_vlan_iface_protocol(nic, nic_iface, + path->vlan_id, + AF_INET6); + if (vlan_iface == NULL) { + LOG_INFO(PFX "%s couldn't find interface with VLAN = %d" + "ip_type: 0x%x creating it", + nic->log_name, path->vlan_id, AF_INET6); + + /* Create the nic interface */ + vlan_iface = nic_iface_init(); + + if (vlan_iface == NULL) { + LOG_ERR(PFX "Couldn't allocate nic_iface for " + "VLAN: %d", vlan_iface, + path->vlan_id); + return -EINVAL; + } + vlan_iface->protocol = nic_iface->protocol; + vlan_iface->vlan_id = path->vlan_id; + vlan_iface->ustack.ip_config = + nic_iface->ustack.ip_config; + memcpy(vlan_iface->ustack.hostaddr6, + nic_iface->ustack.hostaddr6, + sizeof(nic_iface->ustack.hostaddr6)); + memcpy(vlan_iface->ustack.netmask6, + nic_iface->ustack.netmask6, + sizeof(nic_iface->ustack.netmask6)); + nic_add_vlan_iface(nic, nic_iface, vlan_iface); + } else { + LOG_INFO(PFX "%s: using existing vlan interface", + nic->log_name); } - - nic_iface->vlan_id = path->vlan_id; + nic_iface = vlan_iface; } + /* Depending on the IPv6 address of the target we will need to * determine whether we use the assigned IPv6 address or the * link local IPv6 address */ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/logger.c open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/logger.c --- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/logger.c 2011-10-26 07:21:46.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/logger.c 2011-10-26 17:55:59.000000000 -0500 @@ -109,7 +109,7 @@ void log_uip(char *level_str, char *fmt, fflush(stdout); } - end: +end: va_end(ap2); va_end(ap); pthread_mutex_unlock(&main_log.lock); @@ -129,17 +129,26 @@ int init_logger(char *filename) pthread_mutex_lock(&main_log.lock); + if (opt.debug != DEBUG_ON) { + rc = -EIO; + goto disable; + } main_log.fp = fopen(filename, "a"); if (main_log.fp == NULL) { printf("Could not create log file: %s <%s>\n", filename, strerror(errno)); rc = -EIO; } - main_log.enabled = LOGGER_ENABLED; +disable: + if (rc) + main_log.enabled = LOGGER_DISABLED; + else + main_log.enabled = LOGGER_ENABLED; pthread_mutex_unlock(&main_log.lock); - LOG_INFO("Initialize logger using log file: %s", filename); + if (!rc) + LOG_INFO("Initialize logger using log file: %s", filename); return rc; } diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/main.c open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/main.c --- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/main.c 2011-10-26 07:21:46.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/main.c 2011-10-26 17:55:59.000000000 -0500 @@ -48,6 +48,7 @@ #include #include #include +#include #include "uip.h" #include "uip_arp.h" @@ -143,11 +144,9 @@ signal_wait: retry: fini_logger(SHUTDOWN_LOGGER); rc = init_logger(main_log.log_file); - if (rc != 0) { + if (rc != 0) printf("Could not initialize the logger in " "signal!\n"); - goto retry; - } goto signal_wait; default: break; @@ -198,6 +197,38 @@ static void daemon_init() rc = chdir("/"); } +#define ISCSI_OOM_PATH_LEN 48 + +int oom_adjust(void) +{ + int fd; + char path[ISCSI_OOM_PATH_LEN]; + struct stat statb; + + if (nice(-10) < 0) + LOG_DEBUG("Could not increase process priority: %s", + strerror(errno)); + + snprintf(path, ISCSI_OOM_PATH_LEN, "/proc/%d/oom_score_adj", getpid()); + if (stat(path, &statb)) { + /* older kernel so use old oom_adj file */ + snprintf(path, ISCSI_OOM_PATH_LEN, "/proc/%d/oom_adj", + getpid()); + } + fd = open(path, O_WRONLY); + if (fd < 0) + return -1; + if (write(fd, "-16", 3) < 0) /* for 2.6.11 */ + LOG_DEBUG("Could not set oom score to -16: %s", + strerror(errno)); + if (write(fd, "-17", 3) < 0) /* for Andrea's patch */ + LOG_DEBUG("Could not set oom score to -17: %s", + strerror(errno)); + close(fd); + return 0; +} + + /******************************************************************************* * Main routine ******************************************************************************/ @@ -250,10 +281,8 @@ int main(int argc, char *argv[]) if (main_log.enabled == LOGGER_ENABLED) { /* initialize the logger */ rc = init_logger(main_log.log_file); - if (rc != 0) { - printf("Could not initialize the logger\n"); - goto error; - } + if (rc != 0 && opt.debug == DEBUG_ON) + printf("WARN: Could not initialize the logger\n"); } LOG_INFO("Started iSCSI uio stack: Ver " PACKAGE_VERSION); @@ -348,6 +377,16 @@ int main(int argc, char *argv[]) /* Using sysfs to discover iSCSI hosts */ nic_discover_iscsi_hosts(); + /* oom-killer will not kill us at the night... */ + if (oom_adjust()) + LOG_DEBUG("Can not adjust oom-killer's pardon"); + + /* we don't want our active sessions to be paged out... */ + if (mlockall(MCL_CURRENT | MCL_FUTURE)) { + LOG_ERR("failed to mlockall, exiting..."); + goto error; + } + /* Start the iscsid listener */ rc = iscsid_start(); if (rc != 0) { diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/nic.c open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/nic.c --- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/nic.c 2011-10-26 07:21:46.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/nic.c 2011-10-26 17:55:59.000000000 -0500 @@ -440,7 +440,7 @@ int nic_remove(nic_t * nic) nic_t *prev, *current; struct stat file_stat; void *res; - nic_interface_t *nic_iface, *next_nic_iface; + nic_interface_t *nic_iface, *next_nic_iface, *vlan_iface; pthread_mutex_lock(&nic->nic_mutex); @@ -505,6 +505,12 @@ int nic_remove(nic_t * nic) nic_iface */ nic_iface = nic->nic_iface; while (nic_iface != NULL) { + vlan_iface = nic_iface->vlan_next; + while (vlan_iface != NULL) { + next_nic_iface = vlan_iface->vlan_next; + free(vlan_iface); + vlan_iface = next_nic_iface; + } next_nic_iface = nic_iface->next; free(nic_iface); nic_iface = next_nic_iface; @@ -532,7 +538,7 @@ int nic_remove(nic_t * nic) void nic_close(nic_t * nic, NIC_SHUTDOWN_T graceful, int clean) { int rc; - nic_interface_t *nic_iface; + nic_interface_t *nic_iface, *vlan_iface; struct stat file_stat; /* The NIC could be configured by the uIP config file @@ -559,8 +565,14 @@ void nic_close(nic_t * nic, NIC_SHUTDOWN nic_iface = nic->nic_iface; while (nic_iface != NULL) { if (!((nic_iface->flags & NIC_IFACE_PERSIST) == - NIC_IFACE_PERSIST)) + NIC_IFACE_PERSIST)) { uip_reset(&nic_iface->ustack); + vlan_iface = nic_iface->vlan_next; + while (vlan_iface != NULL) { + uip_reset(&vlan_iface->ustack); + vlan_iface = vlan_iface->vlan_next; + } + } nic_iface = nic_iface->next; } @@ -608,12 +620,13 @@ nic_interface_t *nic_iface_init() memset(nic_iface, 0, sizeof(*nic_iface)); nic_iface->next = NULL; + nic_iface->vlan_next = NULL; return nic_iface; } /** - * nic_add_net_iface() - This function is used to add an interface to the + * nic_add_nic_iface() - This function is used to add an interface to the * nic structure * @param nic - struct nic device to add the interface to * @param nic_iface - network interface used to add to the nic @@ -632,7 +645,7 @@ int nic_add_nic_iface(nic_t * nic, nic_i /* Check to see if this interface already exists via 2 * conditions: 1) VLAN 2) protocol */ - while (current->next != NULL) { + while (current != NULL) { if ((current->protocol == nic_iface->protocol) && (current->vlan_id == nic_iface->vlan_id)) { LOG_WARN(PFX "%s: nic interface alread exists" @@ -641,7 +654,6 @@ int nic_add_nic_iface(nic_t * nic, nic_i current->protocol); goto error; } - current = current->next; } @@ -668,6 +680,60 @@ error: return 0; } +/** + * nic_add_vlan_iface() - This function is used to add a vlan interface to the + * nic structure + * @param nic - struct nic device to add the interface to + * @param nic_iface - network interface to be added to + * @param vlan_iface - vlan interface used to add to the nic_iface + * @return 0 on success, <0 on failure + */ +int nic_add_vlan_iface(nic_t *nic, nic_interface_t *nic_iface, + nic_interface_t *vlan_iface) +{ + pthread_mutex_lock(&nic->nic_mutex); + + /* Add the nic_interface */ + if (nic_iface == NULL) + goto error; + else { + nic_interface_t *current = nic_iface->vlan_next; + + /* Check to see if this interface already exists via 2 + * conditions: 1) VLAN 2) protocol */ + while (current != NULL) { + if ((current->protocol == vlan_iface->protocol) && + (current->vlan_id == vlan_iface->vlan_id)) { + LOG_WARN(PFX "%s: vlan interface already exists" + "for VLAN: %d, protocol: %d", + nic->log_name, current->vlan_id, + current->protocol); + goto error; + } + current = current->vlan_next; + } + + /* This interface doesn't exists, we can safely add + * this nic interface */ + current = nic_iface; + while (current->vlan_next != NULL) + current = current->vlan_next; + + current->vlan_next = vlan_iface; + } + + /* Set nic_interface common fields */ + vlan_iface->parent = nic; + nic->num_of_nic_iface++; + + LOG_INFO(PFX "%s: Added vlan interface for VLAN: %d, protocol: %d", + nic->log_name, vlan_iface->vlan_id, vlan_iface->protocol); + +error: + pthread_mutex_unlock(&nic->nic_mutex); + + return 0; +} /****************************************************************************** * Routine to process interrupts from the NIC device ******************************************************************************/ @@ -944,6 +1010,7 @@ int process_packets(nic_t * nic, uint16_t type = 0; int af_type = 0; struct uip_stack *ustack; + nic_interface_t *vlan_iface; if ((pkt->vlan_tag == 0) || (NIC_VLAN_STRIP_ENABLED & nic->flags)) { @@ -970,8 +1037,7 @@ int process_packets(nic_t * nic, /* check if we have the given VLAN interface */ if (nic_iface == NULL) { - nic_iface = nic_find_nic_iface_protocol(nic, - pkt->vlan_tag, + nic_iface = nic_find_nic_iface_protocol(nic, 0, af_type); if (nic_iface == NULL) { LOG_INFO(PFX "%s: Couldn't find interface for " @@ -993,11 +1059,58 @@ int process_packets(nic_t * nic, } nic_iface->protocol = af_type; - nic_iface->vlan_id = pkt->vlan_tag; + nic_iface->vlan_id = 0; nic_add_nic_iface(nic, nic_iface); persist_all_nic_iface(nic); } + if (pkt->vlan_tag) { + vlan_iface = nic_find_vlan_iface_protocol(nic, + nic_iface, pkt->vlan_tag, + af_type); + if (vlan_iface == NULL) { + LOG_INFO(PFX "%s couldn't find " + "interface with VLAN =" + " %d ip_type: 0x%x " + "creating it", + nic->log_name, pkt->vlan_tag, + af_type); + + /* Create the nic interface */ + vlan_iface = nic_iface_init(); + + if (vlan_iface == NULL) { + LOG_ERR(PFX "Couldn't allocate " + "nic_iface for VLAN: %d", + vlan_iface, + pkt->vlan_tag); + rc = 0; + goto done; + } + vlan_iface->protocol = af_type; + vlan_iface->vlan_id = pkt->vlan_tag; + nic_add_vlan_iface(nic, nic_iface, + vlan_iface); + /* TODO: When VLAN support is placed */ + /* in the iface file revisit this */ + /* code */ + memcpy(vlan_iface->ustack.hostaddr, + nic_iface->ustack.hostaddr, + sizeof(nic_iface->ustack.hostaddr)); + memcpy(vlan_iface->ustack.netmask, + nic_iface->ustack.netmask, + sizeof(nic_iface->ustack.netmask)); + memcpy(vlan_iface->ustack.netmask6, + nic_iface->ustack.netmask6, + sizeof(nic_iface->ustack.netmask6)); + memcpy(vlan_iface->ustack.hostaddr6, + nic_iface->ustack.hostaddr6, + sizeof(nic_iface->ustack.hostaddr6)); + + persist_all_nic_iface(nic); + } + nic_iface = vlan_iface; + } } pkt->nic_iface = nic_iface; @@ -1095,10 +1208,19 @@ static int process_dhcp_loop(nic_t * nic struct timeval total_time; /* 10s loop time to wait for DHCP */ - if (nic_iface->ustack.ip_config == IPV4_CONFIG_DHCP) + switch (nic_iface->ustack.ip_config) { + case IPV4_CONFIG_DHCP: wait_time.tv_sec = 10; - else + break; + case IPV6_CONFIG_DHCP: wait_time.tv_sec = 15; + break; + case IPV6_CONFIG_STATIC: + wait_time.tv_sec = 4; + break; + default: + wait_time.tv_sec = 2; + } wait_time.tv_usec = 0; s = nic_iface->ustack.dhcpc; @@ -1177,7 +1299,6 @@ void *nic_loop(void *arg) /* Signal the device to enable itself */ pthread_mutex_lock(&nic->nic_mutex); pthread_cond_signal(&nic->nic_loop_started_cond); - pthread_mutex_unlock(&nic->nic_mutex); while ((event_loop_stop == 0) && !(nic->flags & NIC_EXIT_MAIN_LOOP) && @@ -1189,16 +1310,17 @@ void *nic_loop(void *arg) nic->log_name); /* Wait for the device to be enabled */ - pthread_mutex_lock(&nic->nic_mutex); + /* nic_mutex is already locked */ pthread_cond_wait(&nic->enable_wait_cond, &nic->nic_mutex); - pthread_mutex_unlock(&nic->nic_mutex); - if (nic->state == NIC_EXIT) + if (nic->state == NIC_EXIT) { + pthread_mutex_unlock(&nic->nic_mutex); pthread_exit(NULL); - + } LOG_DEBUG(PFX "%s: is now enabled", nic->log_name); } + pthread_mutex_unlock(&nic->nic_mutex); /* initialize the device to send/rec data */ rc = (*nic->ops->open) (nic); @@ -1407,7 +1529,7 @@ skip: nic->log_name, nic_iface->vlan_id, nic_iface->protocol); - nic_iface = nic_iface->next; + nic_iface = nic_iface->vlan_next; } if (nic->flags & NIC_DISABLED) { @@ -1458,20 +1580,27 @@ dev_close: nic->flags &= ~NIC_GOING_DOWN; } else { - pthread_mutex_destroy(&nic->xmit_mutex); pthread_mutex_init(&nic->xmit_mutex, NULL); if (nic->flags & NIC_RESET_UIP) { nic_interface_t *nic_iface = nic->nic_iface; + nic_interface_t *vlan_iface; while (nic_iface != NULL) { LOG_INFO(PFX "%s: resetting uIP stack", nic->log_name); uip_reset(&nic_iface->ustack); - + vlan_iface = nic_iface->vlan_next; + while (vlan_iface != NULL) { + LOG_INFO(PFX "%s: resetting " + "vlan uIP stack", + nic->log_name); + uip_reset(&vlan_iface->ustack); + vlan_iface = + vlan_iface->vlan_next; + } nic_iface = nic_iface->next; } - nic->flags &= ~NIC_RESET_UIP; } } @@ -1486,8 +1615,8 @@ dev_close: /* Signal we are done closing CNIC/UIO device */ pthread_cond_broadcast(&nic->disable_wait_cond); } - pthread_mutex_unlock(&nic->nic_mutex); } + pthread_mutex_unlock(&nic->nic_mutex); LOG_INFO(PFX "%s: nic loop thread exited", nic->log_name); diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/nic.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/nic.h --- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/nic.h 2011-10-26 07:21:46.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/nic.h 2011-10-26 17:55:59.000000000 -0500 @@ -130,6 +130,7 @@ typedef struct nic_interface { time_t start_time; struct uip_stack ustack; + struct nic_interface *vlan_next; } nic_interface_t; /****************************************************************************** @@ -302,11 +303,13 @@ typedef struct nic { int load_all_nic_libraries(); nic_t *nic_init(); -void nic_add(nic_t * nic); -int nic_remove(nic_t * nic); +void nic_add(nic_t *nic); +int nic_remove(nic_t *nic); -int nic_add_nic_iface(nic_t * nic, nic_interface_t * nic_iface); -int nic_process_intr(nic_t * nic, int discard_check); +int nic_add_nic_iface(nic_t *nic, nic_interface_t *nic_iface); +int nic_add_vlan_iface(nic_t *nic, nic_interface_t *nic_iface, + nic_interface_t *vlan_iface); +int nic_process_intr(nic_t *nic, int discard_check); nic_interface_t *nic_iface_init(); @@ -340,6 +343,10 @@ struct nic_interface *nic_find_nic_iface struct nic_interface *nic_find_nic_iface_protocol(nic_t * nic, uint16_t vlan_id, uint16_t protocol); +struct nic_interface *nic_find_vlan_iface_protocol(nic_t *nic, + nic_interface_t *nic_iface, + uint16_t vlan_id, + uint16_t protocol); int find_nic_lib_using_pci_id(uint32_t vendor, uint32_t device, uint32_t subvendor, uint32_t subdevice, nic_lib_handle_t ** handle, diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/nic_nl.c open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/nic_nl.c --- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/nic_nl.c 2011-10-26 07:21:46.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/nic_nl.c 2011-10-26 17:55:59.000000000 -0500 @@ -329,7 +329,7 @@ static int ctldev_handle(char *data) if (ev->type == ISCSI_KEVENT_PATH_REQ) { struct timespec sleep_rem; - nic_interface_t *nic_iface; + nic_interface_t *nic_iface, *vlan_iface; uint16_t ip_type; if (path->ip_addr_len == 4) @@ -339,52 +339,56 @@ static int ctldev_handle(char *data) else ip_type = 0; - nic_iface = nic_find_nic_iface_protocol(nic, path->vlan_id, - ip_type); + /* Find the parent nic_iface */ + nic_iface = nic_find_nic_iface_protocol(nic, 0, ip_type); if (nic_iface == NULL) { - nic_interface_t *default_iface; - default_iface = nic_find_nic_iface_protocol(nic, - 0, ip_type); - if (default_iface == NULL) { - LOG_ERR(PFX "%s: Couldn't find default iface " - "vlan: %d ip_type: %d " - "ip_addr_len: %d to clone", - nic->log_name, path->vlan_id, ip_type, - path->ip_addr_len); - goto error; - } - - nic_iface = nic_iface_init(); - if (nic_iface == NULL) { - LOG_ERR(PFX "%s: Couldn't allocate space for " - "vlan: %d ip_type: %d " - "ip_addr_len: %d", - nic->log_name, path->vlan_id, ip_type, - path->ip_addr_len); - - goto error; + LOG_ERR(PFX "%s: Couldn't find nic iface " + "vlan: %d ip_type: %d " + "ip_addr_len: %d to clone", + nic->log_name, path->vlan_id, ip_type, + path->ip_addr_len); + goto error; + } + if (path->vlan_id) { + vlan_iface = nic_find_vlan_iface_protocol(nic, + nic_iface, path->vlan_id, ip_type); + if (vlan_iface == NULL) { + /* Create a vlan_iface */ + vlan_iface = nic_iface_init(); + if (vlan_iface == NULL) { + LOG_ERR(PFX "%s: Couldn't allocate " + "space for vlan: %d ip_type: " + "%d ip_addr_len: %d", + nic->log_name, path->vlan_id, + ip_type, path->ip_addr_len); + goto error; + } + + vlan_iface->protocol = ip_type; + vlan_iface->vlan_id = path->vlan_id; + nic_add_vlan_iface(nic, nic_iface, vlan_iface); + + /* TODO: When VLAN support is placed in */ + /* the iface file revisit this code */ + vlan_iface->ustack.ip_config = + nic_iface->ustack.ip_config; + memcpy(vlan_iface->ustack.hostaddr, + nic_iface->ustack.hostaddr, + sizeof(nic_iface->ustack.hostaddr)); + memcpy(vlan_iface->ustack.netmask, + nic_iface->ustack.netmask, + sizeof(nic_iface->ustack.netmask)); + memcpy(vlan_iface->ustack.netmask6, + nic_iface->ustack.netmask6, + sizeof(nic_iface->ustack.netmask6)); + memcpy(vlan_iface->ustack.hostaddr6, + nic_iface->ustack.hostaddr6, + sizeof(nic_iface->ustack.hostaddr6)); + + persist_all_nic_iface(nic); + nic_disable(nic, 0); + nic_iface = vlan_iface; } - - nic_iface->protocol = ip_type; - nic_iface->vlan_id = path->vlan_id; - nic_add_nic_iface(nic, nic_iface); - - /* TODO: When VLAN support is placed in the iface file - * revisit this code */ - nic_iface->ustack.ip_config = - default_iface->ustack.ip_config; - memcpy(nic_iface->ustack.hostaddr, - default_iface->ustack.hostaddr, - sizeof(nic_iface->ustack.hostaddr)); - memcpy(nic_iface->ustack.netmask, - default_iface->ustack.netmask, - sizeof(nic_iface->ustack.netmask)); - memcpy(nic_iface->ustack.hostaddr6, - default_iface->ustack.hostaddr6, - sizeof(nic_iface->ustack.hostaddr6)); - - persist_all_nic_iface(nic); - nic_disable(nic, 0); } /* Force enable the NIC */ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/nic_utils.c open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/nic_utils.c --- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/nic_utils.c 2011-10-26 07:21:46.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/nic_utils.c 2011-10-26 17:55:59.000000000 -0500 @@ -78,6 +78,8 @@ static const char host_template[] = "hos static const char iscsi_host_path_template[] = "/sys/class/iscsi_host/host%d"; static const char iscsi_host_path_netdev_template[] = "/sys/class/iscsi_host/host%d/netdev"; +static const char cnic_uio_sysfs_resc_template[] = + "/sys/class/uio/uio%i/device/resource%i"; /** * manually_trigger_uio_event() - If the uio file node doesn't exist then @@ -824,6 +826,15 @@ int nic_fill_name(nic_t * nic) return 0; } +void cnic_get_sysfs_pci_resource_path(nic_t *nic, int resc_no, + char *sys_path, size_t size) +{ + /* Build the path to sysfs pci resource */ + snprintf(sys_path, size, + cnic_uio_sysfs_resc_template, nic->uio_minor, resc_no); + +} + void prepare_library(nic_t * nic) { int rc; @@ -925,13 +936,23 @@ int nic_enable(nic_t * nic) rc = gettimeofday(&tp, NULL); ts.tv_sec = tp.tv_sec; ts.tv_nsec = tp.tv_usec * 1000; - /* Changed the timeout to 10s to accommodate for DHCP - timeout */ ts.tv_sec += 10; - /* Wait for the device to be disabled */ + /* Wait for the device to be enabled */ rc = pthread_cond_timedwait(&nic->enable_done_cond, &nic->nic_mutex, &ts); +#if 0 + if (rc || !nic->flags & NIC_ENABLED) { + /* Give it one more shout */ + pthread_cond_broadcast(&nic->enable_wait_cond); + rc = gettimeofday(&tp, NULL); + ts.tv_sec = tp.tv_sec; + ts.tv_nsec = tp.tv_usec * 1000; + ts.tv_sec += 5; + rc = pthread_cond_timedwait(&nic->enable_done_cond, + &nic->nic_mutex, &ts); + } +#endif nic->flags &= ~NIC_ENABLED_PENDING; pthread_mutex_unlock(&nic->nic_mutex); @@ -940,6 +961,24 @@ int nic_enable(nic_t * nic) } else { LOG_ERR(PFX "%s: waiting to finish nic_enable err:%s", nic->log_name, strerror(rc)); + /* Must clean up the ustack */ + nic_interface_t *nic_iface = nic->nic_iface; + nic_interface_t *vlan_iface; + while (nic_iface != NULL) { + LOG_INFO(PFX "%s: resetting uIP stack", + nic->log_name); + uip_reset(&nic_iface->ustack); + vlan_iface = nic_iface->vlan_next; + while (vlan_iface != NULL) { + LOG_INFO(PFX "%s: resetting " + "vlan uIP stack", + nic->log_name); + uip_reset(&vlan_iface->ustack); + vlan_iface = + vlan_iface->vlan_next; + } + nic_iface = nic_iface->next; + } } return rc; @@ -979,7 +1018,7 @@ int nic_disable(nic_t * nic, int going_d rc = gettimeofday(&tp, NULL); ts.tv_sec = tp.tv_sec; ts.tv_nsec = tp.tv_usec * 1000; - ts.tv_sec += 5; /* TODO: hardcoded wait for 2 seconds */ + ts.tv_sec += 5; /* TODO: hardcoded wait for 5 seconds */ /* Wait for the device to be disabled */ rc = pthread_cond_timedwait(&nic->disable_wait_cond, @@ -1087,7 +1126,7 @@ error: */ void nic_set_all_nic_iface_mac_to_parent(nic_t * nic) { - nic_interface_t *current; + nic_interface_t *current, *vlan_current; pthread_mutex_lock(&nic->nic_mutex); @@ -1097,6 +1136,11 @@ void nic_set_all_nic_iface_mac_to_parent * adapter */ memcpy(current->mac_addr, nic->mac_addr, 6); + vlan_current = current->vlan_next; + while (vlan_current != NULL) { + memcpy(vlan_current->mac_addr, nic->mac_addr, 6); + vlan_current = vlan_current->vlan_next; + } current = current->next; } @@ -1286,20 +1330,80 @@ nic_interface_t *nic_find_nic_iface_prot void persist_all_nic_iface(nic_t * nic) { - nic_interface_t *current; + nic_interface_t *current, *vlan_iface; pthread_mutex_lock(&nic->nic_mutex); current = nic->nic_iface; while (current != NULL) { current->flags |= NIC_IFACE_PERSIST; - + vlan_iface = current->vlan_next; + while (vlan_iface != NULL) { + vlan_iface->flags |= NIC_IFACE_PERSIST; + vlan_iface = vlan_iface->vlan_next; + } current = current->next; } pthread_mutex_unlock(&nic->nic_mutex); } +/** + * nic_find_vlan_iface_protocol() - This function is used to find an interface + * from the NIC + * @param nic_iface - Base NIC to look for the vlan interfaces + * @param vlan_id - VLAN id to look for + * @param protocol - either AF_INET or AF_INET6 + * @return nic_iface - if found network interface with the given VLAN ID + * if not found a NULL is returned + */ +nic_interface_t *nic_find_vlan_iface_protocol(nic_t *nic, + nic_interface_t *nic_iface, + uint16_t vlan_id, + uint16_t protocol) +{ + nic_interface_t *current; + + pthread_mutex_lock(&nic->nic_mutex); + + current = nic_iface->vlan_next; + while (current != NULL) { + if ((current->vlan_id == vlan_id) && + (current->protocol == protocol)) { + pthread_mutex_unlock(&nic->nic_mutex); + return current; + } + current = current->vlan_next; + } + + pthread_mutex_unlock(&nic->nic_mutex); + return NULL; +} + +void set_nic_iface(nic_t *nic, nic_interface_t *nic_iface) +{ + nic_interface_t *current, *prev; + + pthread_mutex_lock(&nic->nic_mutex); + + if (nic->nic_iface == nic_iface) + goto done; + + prev = nic->nic_iface; + current = nic->nic_iface->next; + while (current != NULL) { + if (current == nic_iface) { + prev->next = current->next; + current->next = nic->nic_iface; + nic->nic_iface = current; + goto done; + } + prev = current; + current = current->next; + } +done: + pthread_mutex_unlock(&nic->nic_mutex); +} /******************************************************************************* * Packet management utility functions ******************************************************************************/ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/nic_utils.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/nic_utils.h --- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/nic_utils.h 2011-10-26 07:21:46.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/nic_utils.h 2011-10-26 17:55:59.000000000 -0500 @@ -68,12 +68,15 @@ void nic_fill_ethernet_header(nic_interf uint16_t ether_type); nic_interface_t *nic_find_nic_iface(nic_t * nic, uint16_t vlan_id); +void set_nic_iface(nic_t *nic, nic_interface_t *nic_iface); void persist_all_nic_iface(nic_t * nic); int add_vlan_interfaces(nic_t * nic); int nic_verify_uio_sysfs_name(nic_t * nic); +void cnic_get_sysfs_pci_resource_path(nic_t *nic, int resc_no, + char *sys_path, size_t size); void nic_close_all(); void nic_remove_all();