5691 lines
183 KiB
Diff
5691 lines
183 KiB
Diff
diff --git a/iscsiuio/README b/iscsiuio/README
|
|
index 5c36dec..a716263 100644
|
|
--- a/iscsiuio/README
|
|
+++ b/iscsiuio/README
|
|
@@ -1,6 +1,6 @@
|
|
-Iscsiuio Userspace Tool
|
|
-Version 0.7.2.1
|
|
-Mar 05, 2012
|
|
+iscsiuio Userspace Tool
|
|
+Version 0.7.4.3
|
|
+Aug 16, 2012
|
|
------------------------------------------------------
|
|
|
|
This tool is to be used in conjunction with the Broadcom NetXtreme II Linux
|
|
@@ -189,10 +189,11 @@ To run the daemon in debug mode please pass the parameter '-d <debug level>'
|
|
|
|
where the following debug levels are defined:
|
|
|
|
-DEBUG 4 - Print all messages
|
|
-INFO 3 - Print messages needed to follow the uIP code (default)
|
|
-WARN 2 - Print warning messages
|
|
-ERROR 1 - Only print critical errors
|
|
+PACKET 5 - Print all messages
|
|
+DEBUG 4 - Print debug messages
|
|
+INFO 3 - Print messages needed to follow the uIP code (default)
|
|
+WARN 2 - Print warning messages
|
|
+ERROR 1 - Only print critical errors
|
|
|
|
A sample banner message:
|
|
|
|
diff --git a/iscsiuio/RELEASE.TXT b/iscsiuio/RELEASE.TXT
|
|
index d4a00b6..cb1d470 100644
|
|
--- a/iscsiuio/RELEASE.TXT
|
|
+++ b/iscsiuio/RELEASE.TXT
|
|
@@ -1,7 +1,7 @@
|
|
Release Notes
|
|
Broadcom uIP Linux Driver
|
|
- Version 0.7.2.1
|
|
- 03/05/2012
|
|
+ Version 0.7.4.3
|
|
+ 08/16/2012
|
|
|
|
Broadcom Corporation
|
|
5300 California Avenue,
|
|
@@ -10,6 +10,228 @@
|
|
Copyright (c) 2004 - 2012 Broadcom Corporation
|
|
All rights reserved
|
|
|
|
+
|
|
+uIP v0.7.4.3 (Aug 16, 2012)
|
|
+=======================================================
|
|
+ Fixes
|
|
+ -----
|
|
+ 1. Problem: Cont00049383 - No mechanism in iface file to support
|
|
+ gateway/routing
|
|
+ Change: Added support for the additional network parameters
|
|
+ as passed from the newer iscsi-util.
|
|
+ These parameters include:
|
|
+ IPv4: subnet_mask, gateway
|
|
+ IPv6: ipv6_linklocal, ipv6_router,
|
|
+ ipv6_autocfg, linklocal_autocfg, router_autocfg
|
|
+ VLAN: vlan_id, vlan_priority, vlan_state
|
|
+ Other: mtu, port
|
|
+ Impact: All
|
|
+
|
|
+ 2. Problem: Cont00060806 - Unable to connect target using DHCP over
|
|
+ tagged VLAN
|
|
+ Change: DHCP+VLAN is a new feature enhancement that was added
|
|
+ alongside all other new iface parameters.
|
|
+ Impact: All
|
|
+
|
|
+ 3. Problem: Cont00061513 - Unable to connect to target over VLAN
|
|
+ interface
|
|
+ Cause: The VLAN id was not properly passed back to the CNIC
|
|
+ driver for the offload request
|
|
+ Change: Fixed the VLAN id being passed back to the CNIC driver
|
|
+ Impact: All
|
|
+
|
|
+ 4. Problem: Cont00061529 - Unable to connect to target after an
|
|
+ initial failed login attempt until iscsi service is
|
|
+ restarted
|
|
+ Cause: Upon a failed DHCPv4 acquisition due to the wrong VLAN
|
|
+ tag in the initial iface setup, any iscsid connect request
|
|
+ from the same NIC will get dropped due to a bug.
|
|
+ Change: Fixed the bug which prevented new iscsid connect requests
|
|
+ from getting honored
|
|
+ Impact: All
|
|
+
|
|
+ 5. Problem: Cont00061978 - Load/unload stress test fails
|
|
+ Cause: The bnx2x open request was failing due to the module
|
|
+ request procedure. However, the open failure was
|
|
+ not being handled correctly.
|
|
+ Change: Fixed the device open error handling
|
|
+ Impact: 5771X/578XX
|
|
+
|
|
+ 6. Problem: Cont00062170 - IPv6 login/logout stress fails
|
|
+ Cause: The packet buffer routine for IPv6 did not take
|
|
+ network order <-> host order into consideration
|
|
+ Change: Added a htons call to compensate for the ntohs pair
|
|
+ Impact: All
|
|
+
|
|
+ 7. Problem: Cont00061869 - Unable to setup an offload iSCSI
|
|
+ connection with FLR/NPAR under ESX5.0:PDA
|
|
+ Cause: The physical function ID was previously extracted
|
|
+ from the sysfs of the VM which might not be consistent
|
|
+ to the actual physical setup due to the function
|
|
+ remapping in the hypervisor
|
|
+ Change: Read the physical function ID directly from the BAR0
|
|
+ ME register
|
|
+ Impact: All
|
|
+
|
|
+ 8. Problem: Cont00062170 - IPv6 login/logout stress fails
|
|
+ Cause: The packet interrupt was lost after running the test
|
|
+ for a much longer period of time. A bug in the
|
|
+ packet processing routine was found to exit prematurely
|
|
+ Change: Fixed the packet processing routine to process all
|
|
+ packets before exiting
|
|
+ Impact: All
|
|
+
|
|
+ 9. Problem: Cont00062660 - Unable to login with VLAN iscsiuio
|
|
+ on RHEL6.2
|
|
+ Cause: The open-iscsi util in RHEL6.2 has a bug which
|
|
+ does not pass the correct iface_num to iscsiuio
|
|
+ Change: Added workaround to fall back to do the legacy
|
|
+ VLAN support if iface_num and vlan_id = 0
|
|
+ Impact: RHEL6.2
|
|
+
|
|
+ 10. Problem: Cont00062805 - Cannot login to iSCSI targets on RHEL6.3
|
|
+ Cause: The problem was caused by a change made to the iface_rec
|
|
+ structure in the RHEL6.3 inbox open-iscsi util
|
|
+ Change: The new changes is now incorporated
|
|
+ Impact: All
|
|
+
|
|
+ 11. Problem: Cont00062993 - IPv6 DHCP with VLAN specification in
|
|
+ iface file gets wrong address
|
|
+ Cause: The DHCPv6 request was using the same DUID as always
|
|
+ so the non-VLAN DHCP server responded to our broadcast
|
|
+ instead
|
|
+ Change: Changed the DHCPv6 request DUID to link address + time
|
|
+ instead of link address alone
|
|
+ Impact: DHCPv6 operation
|
|
+
|
|
+ 12. Problem: RHEL BZ 734010/804580 - issues found by the Coverity
|
|
+ scan
|
|
+ Cause: 10 code issues were flagged for revision
|
|
+ Change: Fixed all area of concern
|
|
+ Impact: All
|
|
+
|
|
+ 13. Problem: Cont00063177 - IPv4 DHCP with VLAN specification in
|
|
+ iface file gets wrong address
|
|
+ Cause: The DHCPv4 handler was not discriminating the VLAN tag
|
|
+ associated with the DHCP offers from multiple DHCP
|
|
+ servers
|
|
+ Change: Changed the DHCPv4 handler to drop DHCP offer packets
|
|
+ that doesn't match the VLAN tag of the intended DHCP
|
|
+ discovery packet
|
|
+ Impact: DHCPv4 operation
|
|
+
|
|
+ 14. Problem: Cont00063421 - Static IPv6 cannot connect via RA/LL
|
|
+ Cause: The router advertise and the linklocal address
|
|
+ were corrupted due to the override capabilities
|
|
+ added for the newer open-iscsi util
|
|
+ Change: Fixed the address override code
|
|
+ Impact: Static IPv6
|
|
+
|
|
+ 15. Problem: Cont00063443 - Compilation error on SLES11sp1
|
|
+ Cause: The iface_num field was not defined
|
|
+ Change: Fixed all references to iface_num
|
|
+ Impact: SLES11sp1
|
|
+
|
|
+ 16. Problem: Cont00063518 - HBA fails to connect across router
|
|
+ using iface.gateway address
|
|
+ Cause: The gateway override code did not populate the
|
|
+ address into the lower level engine
|
|
+ Change: Fixed the gateway override code
|
|
+ Impact: IPv4 Static IP operation
|
|
+
|
|
+ 17. Problem: Cont00063567 - IPv6 LL and RA override does not work
|
|
+ Cause: The IPv6 LL/RA override addresses were overwritten
|
|
+ by the NDP engine
|
|
+ Change: Fixed the LL/RA override code
|
|
+ Impact: IPv6 operation
|
|
+
|
|
+ 18. Problem: Cont00063626 - Static IPv6 does not connect when
|
|
+ the prefix len is not set explicitly
|
|
+ Cause: The IPv6 prefix length was not set correctly
|
|
+ for Static IPv6 operation when CIDR notation is
|
|
+ not specified
|
|
+ Change: Fixed the default prefix length
|
|
+ Impact: Static IPv6
|
|
+
|
|
+ 19. Problem: Cont00063651 - Cannot connect to iSCSI targets
|
|
+ HP PTM/SF
|
|
+ Cause: Switch-Dependent mode + invalid Outer VLAN was
|
|
+ not supported
|
|
+ Change: Allow SD+invalid OV to fallback to SF operation mode
|
|
+ Impact: 5771X/578XX
|
|
+
|
|
+ 20. Problem: Cont00063816 - The initiator is not able to connect
|
|
+ to the iSCSI targets over VLAN
|
|
+ Cause: The process packet routine did not consider the PCP
|
|
+ of the VLAN tag to be non-zero. This created a
|
|
+ mismatch when this VLAN tag was compared against the
|
|
+ nic_iface->vlan_id which doesn't include the PCP.
|
|
+ Change: Added the consideration of non-zero PCP
|
|
+ Impact: All
|
|
+
|
|
+ 21. Problem: Cont00063863 - can't boot into offload image
|
|
+ when VLAN is enabled
|
|
+ Cause: During the iSCSI login exchange, certain iSCSI targets
|
|
+ will send an ARP request even though the TCP connection
|
|
+ has been made. The bug was in this ARP reply where
|
|
+ the local MAC was corrupted when VLAN is enabled.
|
|
+ Change: Fixed the ARP reply packet
|
|
+ Impact: All
|
|
+
|
|
+ 22. Problem: Cont00063863 - can't boot into offload image
|
|
+ when VLAN is enabled
|
|
+ Cause: During the iSCSI login exchange, certain iSCSI targets
|
|
+ will send an ARP request even though the TCP connection
|
|
+ has been made. The bug was in this ARP reply where
|
|
+ the local MAC was corrupted when VLAN is enabled.
|
|
+ Change: Fixed the ARP reply packet
|
|
+ Impact: All
|
|
+
|
|
+ 23. Problem: Cont00064604 - Fails to connect to routed IPv6 target
|
|
+ via RA
|
|
+ Cause: The default router IPv6 address was not being retrieved
|
|
+ correctly.
|
|
+ Change: Fixed the default router IPv6 address read
|
|
+ Impact: All
|
|
+
|
|
+ 24. Problem: Cont00064665 - Linux iSCSI connects via gateway address
|
|
+ on the wrong subnet
|
|
+ Cause: The gateway address used was not checked against the
|
|
+ subnet mask specified before the ARP requests. Since
|
|
+ this behavior deters from how L2 operates, therefore,
|
|
+ a change was made to correct this.
|
|
+ Change: Added check of the gateway specified against the subnet
|
|
+ specified.
|
|
+ Impact: Static IPv4 operation
|
|
+
|
|
+ 25. Problem: Cont00064722 - Linux iSCSI unable to force IPv6 LL
|
|
+ override (advanced iface parameters)
|
|
+ Cause: The override LL address was not being populated to the
|
|
+ IPv6 address database correctly
|
|
+ Change: Added this correctly to the IPv6 initialization
|
|
+ Impact: Static/DHCP IPv6 LL address override only
|
|
+
|
|
+ Enhancements
|
|
+ ------------
|
|
+ 1. Lock iscsid's connect request with path_req so connect requests
|
|
+ with DHCP/Static will no longer override each other
|
|
+
|
|
+ 2. Fixed the if_down handler from global to nic specific
|
|
+
|
|
+ 3. Fixed various synchronization issues
|
|
+
|
|
+ 4. Updated README
|
|
+
|
|
+ 5. Added support for the new iface_num field in the iscsi_uevent
|
|
+ path
|
|
+
|
|
+ 6. Fixed bug in the nic_iface search engine based on iface_num
|
|
+
|
|
+ 7. Allow VLAN tag = 1 (router management) to connect offload
|
|
+
|
|
+ 8. Added support for jumbo MTU (independent from the L2 MTU)
|
|
+
|
|
+
|
|
uIP v0.7.2.1 (Mar 05, 2012)
|
|
=======================================================
|
|
Fixes
|
|
@@ -47,7 +269,7 @@ uIP v0.7.2.1 (Mar 05, 2012)
|
|
------------
|
|
1. Change: Default iscsiuio logging to off. Use the '-d'
|
|
option to enable
|
|
- 2. Change: Disable HP SD mode
|
|
+ 2. Change: Disable HP SD mode (NOT)
|
|
3. Change: Updated README
|
|
|
|
|
|
diff --git a/iscsiuio/configure b/iscsiuio/configure
|
|
index 4879fb9..6ff2e68 100644
|
|
--- a/iscsiuio/configure
|
|
+++ b/iscsiuio/configure
|
|
@@ -1,6 +1,6 @@
|
|
#! /bin/sh
|
|
# Guess values for system-dependent variables and create Makefiles.
|
|
-# Generated by GNU Autoconf 2.59 for iscsiuio 0.7.2.1.
|
|
+# Generated by GNU Autoconf 2.59 for iscsiuio 0.7.4.3.
|
|
#
|
|
# Report bugs to <eddie.wai@broadcom.com>.
|
|
#
|
|
@@ -423,8 +423,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
|
|
# Identity of this package.
|
|
PACKAGE_NAME='iscsiuio'
|
|
PACKAGE_TARNAME='iscsiuio'
|
|
-PACKAGE_VERSION='0.7.2.1'
|
|
-PACKAGE_STRING='iscsiuio 0.7.2.1'
|
|
+PACKAGE_VERSION='0.7.4.3'
|
|
+PACKAGE_STRING='iscsiuio 0.7.4.3'
|
|
PACKAGE_BUGREPORT='eddie.wai@broadcom.com'
|
|
|
|
# Factoring default headers for most tests.
|
|
@@ -954,7 +954,7 @@ if test "$ac_init_help" = "long"; then
|
|
# Omit some internal or obsolete options to make the list less imposing.
|
|
# This message is too long to be a string in the A/UX 3.1 sh.
|
|
cat <<_ACEOF
|
|
-\`configure' configures iscsiuio 0.7.2.1 to adapt to many kinds of systems.
|
|
+\`configure' configures iscsiuio 0.7.4.3 to adapt to many kinds of systems.
|
|
|
|
Usage: $0 [OPTION]... [VAR=VALUE]...
|
|
|
|
@@ -1020,7 +1020,7 @@ fi
|
|
|
|
if test -n "$ac_init_help"; then
|
|
case $ac_init_help in
|
|
- short | recursive ) echo "Configuration of iscsiuio 0.7.2.1:";;
|
|
+ short | recursive ) echo "Configuration of iscsiuio 0.7.4.3:";;
|
|
esac
|
|
cat <<\_ACEOF
|
|
|
|
@@ -1161,7 +1161,7 @@ fi
|
|
test -n "$ac_init_help" && exit 0
|
|
if $ac_init_version; then
|
|
cat <<\_ACEOF
|
|
-iscsiuio configure 0.7.2.1
|
|
+iscsiuio configure 0.7.4.3
|
|
generated by GNU Autoconf 2.59
|
|
|
|
Copyright (C) 2003 Free Software Foundation, Inc.
|
|
@@ -1175,7 +1175,7 @@ cat >&5 <<_ACEOF
|
|
This file contains any messages produced by compilers while
|
|
running configure, to aid debugging if configure makes a mistake.
|
|
|
|
-It was created by iscsiuio $as_me 0.7.2.1, which was
|
|
+It was created by iscsiuio $as_me 0.7.4.3, which was
|
|
generated by GNU Autoconf 2.59. Invocation command line was
|
|
|
|
$ $0 $@
|
|
@@ -21726,7 +21726,7 @@ _ASBOX
|
|
} >&5
|
|
cat >&5 <<_CSEOF
|
|
|
|
-This file was extended by iscsiuio $as_me 0.7.2.1, which was
|
|
+This file was extended by iscsiuio $as_me 0.7.4.3, which was
|
|
generated by GNU Autoconf 2.59. Invocation command line was
|
|
|
|
CONFIG_FILES = $CONFIG_FILES
|
|
@@ -21789,7 +21789,7 @@ _ACEOF
|
|
|
|
cat >>$CONFIG_STATUS <<_ACEOF
|
|
ac_cs_version="\\
|
|
-iscsiuio config.status 0.7.2.1
|
|
+iscsiuio config.status 0.7.4.3
|
|
configured by $0, generated by GNU Autoconf 2.59,
|
|
with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
|
|
|
|
diff --git a/iscsiuio/configure.ac b/iscsiuio/configure.ac
|
|
index 3b7a880..0b1e7f1 100644
|
|
--- a/iscsiuio/configure.ac
|
|
+++ b/iscsiuio/configure.ac
|
|
@@ -1,6 +1,6 @@
|
|
dnl iscsiuio uIP user space stack configure.ac file
|
|
dnl
|
|
-dnl Copyright (c) 2004-2011 Broadcom Corporation
|
|
+dnl Copyright (c) 2004-2012 Broadcom Corporation
|
|
dnl
|
|
dnl This program is free software; you can redistribute it and/or modify
|
|
dnl it under the terms of the GNU General Public License as published by
|
|
@@ -11,9 +11,9 @@ dnl Maintained by: Eddie Wai (eddie.wai@broadcom.com)
|
|
dnl
|
|
|
|
PACKAGE=iscsiuio
|
|
-VERSION=0.7.2.1
|
|
+VERSION=0.7.4.3
|
|
|
|
-AC_INIT(iscsiuio, 0.7.2.1, eddie.wai@broadcom.com)
|
|
+AC_INIT(iscsiuio, 0.7.4.3, eddie.wai@broadcom.com)
|
|
|
|
AM_INIT_AUTOMAKE($PACKAGE, $VERSION)
|
|
AC_CONFIG_HEADER(config.h)
|
|
diff --git a/iscsiuio/docs/iscsiuio.8 b/iscsiuio/docs/iscsiuio.8
|
|
index 3307b1e..4bf26df 100644
|
|
--- a/iscsiuio/docs/iscsiuio.8
|
|
+++ b/iscsiuio/docs/iscsiuio.8
|
|
@@ -3,9 +3,9 @@
|
|
.\" modify it under the terms of the GNU General Public License as
|
|
.\" published by the Free Software Foundation.
|
|
.\"
|
|
-.\" bnx2.4,v 0.7.2.1
|
|
+.\" bnx2.4,v 0.7.4.3
|
|
.\"
|
|
-.TH iscsiuio 8 "03/05/2012" "Broadcom Corporation"
|
|
+.TH iscsiuio 8 "08/16/2012" "Broadcom Corporation"
|
|
.\"
|
|
.\" NAME part
|
|
.\"
|
|
diff --git a/iscsiuio/include/iscsi_if.h b/iscsiuio/include/iscsi_if.h
|
|
index a9ac145..1944abd 100644
|
|
--- a/iscsiuio/include/iscsi_if.h
|
|
+++ b/iscsiuio/include/iscsi_if.h
|
|
@@ -207,6 +207,7 @@ struct iscsi_uevent {
|
|
} ep_connect_ret;
|
|
struct msg_req_path {
|
|
uint32_t host_no;
|
|
+ uint32_t iface_num;
|
|
} req_path;
|
|
struct msg_notify_if_down {
|
|
uint32_t host_no;
|
|
@@ -234,6 +235,8 @@ struct iscsi_path {
|
|
struct in6_addr v6_addr;
|
|
} dst;
|
|
uint16_t vlan_id;
|
|
+#define IFACE_NUM_PRESENT (1<<0)
|
|
+#define IFACE_NUM_INVALID -1
|
|
uint16_t pmtu;
|
|
} __attribute__ ((aligned (sizeof(uint64_t))));
|
|
|
|
diff --git a/iscsiuio/src/apps/dhcpc/dhcpc.c b/iscsiuio/src/apps/dhcpc/dhcpc.c
|
|
index 88d75c3..afec601 100644
|
|
--- a/iscsiuio/src/apps/dhcpc/dhcpc.c
|
|
+++ b/iscsiuio/src/apps/dhcpc/dhcpc.c
|
|
@@ -334,7 +334,7 @@ static PT_THREAD(handle_dhcp(struct uip_stack *ustack))
|
|
(uint8_t *) s->mac_addr);
|
|
|
|
/* Put the stack thread back into a long sleep */
|
|
- s->nic->state |= NIC_LONG_SLEEP;
|
|
+ s->nic->flags |= NIC_LONG_SLEEP;
|
|
|
|
/* timer_stop(&s.timer); */
|
|
|
|
@@ -343,7 +343,7 @@ static PT_THREAD(handle_dhcp(struct uip_stack *ustack))
|
|
timer_set(&s->timer, s->ticks);
|
|
PT_WAIT_UNTIL(&s->pt, timer_expired(&s->timer));
|
|
LOG_INFO("Lease expired, re-acquire IP address");
|
|
- s->nic->state &= ~NIC_LONG_SLEEP;
|
|
+ s->nic->flags &= ~NIC_LONG_SLEEP;
|
|
PT_RESTART(&s->pt);
|
|
|
|
/*
|
|
@@ -397,7 +397,7 @@ int dhcpc_init(nic_t * nic, struct uip_stack *ustack,
|
|
ustack->dhcpc = s;
|
|
|
|
/* Let the RX poll value take over */
|
|
- nic->state &= ~NIC_LONG_SLEEP;
|
|
+ nic->flags &= ~NIC_LONG_SLEEP;
|
|
|
|
PT_INIT(&s->pt);
|
|
|
|
diff --git a/iscsiuio/src/apps/dhcpc/dhcpv6.c b/iscsiuio/src/apps/dhcpc/dhcpv6.c
|
|
index b7ae631..273cce0 100644
|
|
--- a/iscsiuio/src/apps/dhcpc/dhcpv6.c
|
|
+++ b/iscsiuio/src/apps/dhcpc/dhcpv6.c
|
|
@@ -86,10 +86,6 @@ int dhcpv6_do_discovery(pDHCPV6_CONTEXT dhcpv6_context)
|
|
(pIPV6_HDR) dhcpv6_context->ipv6_context->ustack->network_layer;
|
|
dhcpv6_context->udp =
|
|
(pUDP_HDR) ((u8_t *) dhcpv6_context->ipv6 + sizeof(IPV6_HDR));
|
|
- LOG_INFO("dhcpv6: ipv6c=%p, ustack=%p eth=%p ipv6=%p udp=%p",
|
|
- dhcpv6_context->ipv6_context,
|
|
- dhcpv6_context->ipv6_context->ustack, dhcpv6_context->eth,
|
|
- dhcpv6_context->ipv6, dhcpv6_context->udp);
|
|
|
|
/* Send out DHCPv6 Solicit packet. */
|
|
dhcpv6_send_solicit_packet(dhcpv6_context);
|
|
@@ -176,8 +172,10 @@ STATIC u16_t dhcpv6_init_packet(pDHCPV6_CONTEXT dhcpv6_context, u8_t type)
|
|
opt->hdr.type = HOST_TO_NET16(DHCPV6_OPT_CLIENTID);
|
|
opt->hdr.length = HOST_TO_NET16(sizeof(DHCPV6_OPT_CLIENT_ID));
|
|
opt->type.client_id.duid_type =
|
|
- HOST_TO_NET16(DHCPV6_DUID_TYPE_LINK_LAYER);
|
|
+ HOST_TO_NET16(DHCPV6_DUID_TYPE_LINK_LAYER_AND_TIME);
|
|
opt->type.client_id.hw_type = HOST_TO_NET16(DHCPV6_HW_TYPE_ETHERNET);
|
|
+ opt->type.client_id.time = HOST_TO_NET32(clock_time()/1000 -
|
|
+ 0x3A4FC880);
|
|
memcpy((char __FAR__ *)&opt->type.client_id.link_layer_addr,
|
|
(char __FAR__ *)dhcpv6_context->our_mac_addr, sizeof(MAC_ADDR));
|
|
pkt_len += sizeof(DHCPV6_OPT_CLIENT_ID) + sizeof(DHCPV6_OPT_HDR);
|
|
diff --git a/iscsiuio/src/apps/dhcpc/dhcpv6.h b/iscsiuio/src/apps/dhcpc/dhcpv6.h
|
|
index 917cf35..d8e03e5 100644
|
|
--- a/iscsiuio/src/apps/dhcpc/dhcpv6.h
|
|
+++ b/iscsiuio/src/apps/dhcpc/dhcpv6.h
|
|
@@ -164,7 +164,7 @@ typedef struct DHCPV6_OPT_CLIENT_ID {
|
|
#define DHCPV6_DUID_TYPE_LINK_LAYER 3
|
|
u16_t hw_type;
|
|
#define DHCPV6_HW_TYPE_ETHERNET 1
|
|
-// u32_t time;
|
|
+ u32_t time;
|
|
MAC_ADDR link_layer_addr;
|
|
} DHCPV6_OPT_CLIENT_ID, *pDHCPV6_OPT_CLIENT_ID;
|
|
|
|
diff --git a/iscsiuio/src/uip/ipv6.c b/iscsiuio/src/uip/ipv6.c
|
|
index 594495a..a8eed71 100644
|
|
--- a/iscsiuio/src/uip/ipv6.c
|
|
+++ b/iscsiuio/src/uip/ipv6.c
|
|
@@ -38,6 +38,7 @@
|
|
*/
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
+#include <arpa/inet.h>
|
|
#include "logger.h"
|
|
#include "uip.h"
|
|
#include "ipv6.h"
|
|
@@ -78,7 +79,7 @@ STATIC void ipv6_udp_rx(pIPV6_CONTEXT ipv6_context);
|
|
|
|
int iscsiL2Send(pIPV6_CONTEXT ipv6_context, int pkt_len)
|
|
{
|
|
- LOG_DEBUG("IPV6: iscsiL2Send");
|
|
+ LOG_DEBUG("IPv6: iscsiL2Send");
|
|
uip_send(ipv6_context->ustack,
|
|
(void *)ipv6_context->ustack->data_link_layer, pkt_len);
|
|
|
|
@@ -103,7 +104,8 @@ int iscsiL2AddMcAddr(pIPV6_CONTEXT ipv6_context, MAC_ADDR * new_mc_addr)
|
|
(char __FAR__ *)&all_zeroes_mc, sizeof(MAC_ADDR))) {
|
|
memcpy((char __FAR__ *)mc_addr,
|
|
(char __FAR__ *)new_mc_addr, sizeof(MAC_ADDR));
|
|
- LOG_DEBUG("IPV6: mc_addr added %x:%x:%x:%x:%x:%x",
|
|
+ LOG_DEBUG("IPv6: mc_addr added "
|
|
+ "%02x:%02x:%02x:%02x:%02x:%02x",
|
|
*(u8_t *) new_mc_addr,
|
|
*((u8_t *) new_mc_addr + 1),
|
|
*((u8_t *) new_mc_addr + 2),
|
|
@@ -150,10 +152,11 @@ void ipv6_init(struct ndpc_state *ndp, int cfg)
|
|
ipv6_arp_table = &ipv6_context->ipv6_arp_table[0];
|
|
ipv6_prefix_table = &ipv6_context->ipv6_prefix_table[0];
|
|
|
|
- memset((char __FAR__ *)ipv6_arp_table, 0, sizeof(ipv6_arp_table));
|
|
- memset((char __FAR__ *)ipv6_prefix_table, 0, sizeof(ipv6_prefix_table));
|
|
- memcpy((char __FAR__ *)&ipv6_context->mac_addr,
|
|
- (char __FAR__ *)mac_addr, sizeof(MAC_ADDR));
|
|
+ memset((char __FAR__*)ipv6_arp_table, 0, sizeof(*ipv6_arp_table));
|
|
+ memset((char __FAR__*)ipv6_prefix_table, 0,
|
|
+ sizeof(*ipv6_prefix_table));
|
|
+ memcpy((char __FAR__*)&ipv6_context->mac_addr,
|
|
+ (char __FAR__*)mac_addr, sizeof(MAC_ADDR));
|
|
/*
|
|
* Per RFC 2373.
|
|
* There are two types of local-use unicast addresses defined. These
|
|
@@ -167,33 +170,34 @@ void ipv6_init(struct ndpc_state *ndp, int cfg)
|
|
* |1111111010| 0 | interface ID |
|
|
* +----------+-------------------------+----------------------------+
|
|
*/
|
|
- ipv6_context->link_local_addr.addr8[0] = 0xfe;
|
|
- ipv6_context->link_local_addr.addr8[1] = 0x80;
|
|
- /* Bit 1 is 1 to indicate universal scope. */
|
|
- ipv6_context->link_local_addr.addr8[8] = mac_addr[0] | 0x2;
|
|
- ipv6_context->link_local_addr.addr8[9] = mac_addr[1];
|
|
- ipv6_context->link_local_addr.addr8[10] = mac_addr[2];
|
|
- ipv6_context->link_local_addr.addr8[11] = 0xff;
|
|
- ipv6_context->link_local_addr.addr8[12] = 0xfe;
|
|
- ipv6_context->link_local_addr.addr8[13] = mac_addr[3];
|
|
- ipv6_context->link_local_addr.addr8[14] = mac_addr[4];
|
|
- ipv6_context->link_local_addr.addr8[15] = mac_addr[5];
|
|
-
|
|
- ipv6_context->link_local_multi.addr8[0] = 0xff;
|
|
- ipv6_context->link_local_multi.addr8[1] = 0x02;
|
|
- ipv6_context->link_local_multi.addr8[11] = 0x01;
|
|
- ipv6_context->link_local_multi.addr8[12] = 0xff;
|
|
- ipv6_context->link_local_multi.addr8[13] |=
|
|
- ipv6_context->link_local_addr.addr8[13];
|
|
- ipv6_context->link_local_multi.addr16[7] =
|
|
- ipv6_context->link_local_addr.addr16[7];
|
|
-
|
|
- /* Default Prefix length is 64 */
|
|
- /* Add Link local address to the head of the ipv6 address
|
|
- list */
|
|
- ipv6_add_prefix_entry(ipv6_context,
|
|
- &ipv6_context->link_local_addr, 64);
|
|
-
|
|
+ if (ipv6_context->ustack->linklocal_autocfg != IPV6_LL_AUTOCFG_OFF) {
|
|
+ ipv6_context->link_local_addr.addr8[0] = 0xfe;
|
|
+ ipv6_context->link_local_addr.addr8[1] = 0x80;
|
|
+ /* Bit 1 is 1 to indicate universal scope. */
|
|
+ ipv6_context->link_local_addr.addr8[8] = mac_addr[0] | 0x2;
|
|
+ ipv6_context->link_local_addr.addr8[9] = mac_addr[1];
|
|
+ ipv6_context->link_local_addr.addr8[10] = mac_addr[2];
|
|
+ ipv6_context->link_local_addr.addr8[11] = 0xff;
|
|
+ ipv6_context->link_local_addr.addr8[12] = 0xfe;
|
|
+ ipv6_context->link_local_addr.addr8[13] = mac_addr[3];
|
|
+ ipv6_context->link_local_addr.addr8[14] = mac_addr[4];
|
|
+ ipv6_context->link_local_addr.addr8[15] = mac_addr[5];
|
|
+
|
|
+ ipv6_context->link_local_multi.addr8[0] = 0xff;
|
|
+ ipv6_context->link_local_multi.addr8[1] = 0x02;
|
|
+ ipv6_context->link_local_multi.addr8[11] = 0x01;
|
|
+ ipv6_context->link_local_multi.addr8[12] = 0xff;
|
|
+ ipv6_context->link_local_multi.addr8[13] |=
|
|
+ ipv6_context->link_local_addr.addr8[13];
|
|
+ ipv6_context->link_local_multi.addr16[7] =
|
|
+ ipv6_context->link_local_addr.addr16[7];
|
|
+
|
|
+ /* Default Prefix length is 64 */
|
|
+ /* Add Link local address to the head of the ipv6 address
|
|
+ list */
|
|
+ ipv6_add_prefix_entry(ipv6_context,
|
|
+ &ipv6_context->link_local_addr, 64);
|
|
+ }
|
|
/*
|
|
* Convert Multicast IP address to Multicast MAC adress per
|
|
* RFC 2464: Transmission of IPv6 Packets over Ethernet Networks
|
|
@@ -257,6 +261,7 @@ int ipv6_add_prefix_entry(pIPV6_CONTEXT ipv6_context,
|
|
int i;
|
|
pIPV6_PREFIX_ENTRY prefix_entry;
|
|
pIPV6_PREFIX_ENTRY ipv6_prefix_table = ipv6_context->ipv6_prefix_table;
|
|
+ char addr_str[INET6_ADDRSTRLEN];
|
|
|
|
/* Check if there is an valid entry already. */
|
|
for (i = 0; i < IPV6_NUM_OF_ADDRESS_ENTRY; i++) {
|
|
@@ -287,21 +292,13 @@ int ipv6_add_prefix_entry(pIPV6_CONTEXT ipv6_context,
|
|
|
|
prefix_entry->prefix_len = prefix_len / 8;
|
|
|
|
- memcpy((char __FAR__ *)&prefix_entry->address,
|
|
- (char __FAR__ *)ipv6_addr, sizeof(IPV6_ADDR));
|
|
-
|
|
-
|
|
- LOG_DEBUG("IPV6: add prefix ip addr "
|
|
- "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x "
|
|
- "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
|
|
- prefix_entry->address.addr8[0], prefix_entry->address.addr8[1],
|
|
- prefix_entry->address.addr8[2], prefix_entry->address.addr8[3],
|
|
- prefix_entry->address.addr8[4], prefix_entry->address.addr8[5],
|
|
- prefix_entry->address.addr8[6], prefix_entry->address.addr8[7],
|
|
- prefix_entry->address.addr8[8], prefix_entry->address.addr8[9],
|
|
- prefix_entry->address.addr8[10], prefix_entry->address.addr8[11],
|
|
- prefix_entry->address.addr8[12], prefix_entry->address.addr8[13],
|
|
- prefix_entry->address.addr8[14], prefix_entry->address.addr8[15]);
|
|
+ memcpy((char __FAR__*)&prefix_entry->address,
|
|
+ (char __FAR__*)ipv6_addr, sizeof(IPV6_ADDR));
|
|
+
|
|
+ inet_ntop(AF_INET6, &prefix_entry->address.addr8, addr_str,
|
|
+ sizeof(addr_str));
|
|
+
|
|
+ LOG_DEBUG("IPv6: add prefix IP addr %s", addr_str);
|
|
|
|
/* Put it on the list on head of the list. */
|
|
if (ipv6_context->addr_list != NULL) {
|
|
@@ -419,7 +416,7 @@ int ipv6_discover_address(pIPV6_CONTEXT ipv6_context)
|
|
sizeof(IPV6_ADDR));
|
|
|
|
icmp->icmpv6_cksum = 0;
|
|
- LOG_DEBUG("IPV6: Send rtr sol");
|
|
+ LOG_DEBUG("IPv6: Send rtr sol");
|
|
ipv6_send(ipv6_context, (u8_t *) icmp - (u8_t *) eth +
|
|
sizeof(ICMPV6_HDR) + sizeof(ICMPV6_OPT_LINK_ADDR));
|
|
return rc;
|
|
@@ -650,7 +647,7 @@ STATIC void ipv6_update_arp_table(pIPV6_CONTEXT ipv6_context,
|
|
int i;
|
|
pIPV6_ARP_ENTRY ipv6_arp_table = ipv6_context->ipv6_arp_table;
|
|
|
|
- LOG_DEBUG("IPV6: ARP update");
|
|
+ LOG_DEBUG("IPv6: Neighbor update");
|
|
/*
|
|
* Walk through the ARP mapping table and try to find an entry to
|
|
* update. If none is found, the IP -> MAC address mapping is
|
|
@@ -710,6 +707,7 @@ int ipv6_send_nd_solicited_packet(pIPV6_CONTEXT ipv6_context, pETH_HDR eth,
|
|
pICMPV6_HDR icmp;
|
|
int pkt_len = 0;
|
|
pIPV6_ADDR longest_match_addr;
|
|
+ char addr_str[INET6_ADDRSTRLEN];
|
|
|
|
ipv6->ipv6_nxt_hdr = IPPROTO_ICMPV6;
|
|
|
|
@@ -719,7 +717,7 @@ int ipv6_send_nd_solicited_packet(pIPV6_CONTEXT ipv6_context, pETH_HDR eth,
|
|
/* Use Link-local as source address */
|
|
if (ipv6_is_it_our_link_local_address(ipv6_context, &ipv6->ipv6_dst) ==
|
|
TRUE) {
|
|
- LOG_DEBUG("IPV6: NS using link local");
|
|
+ LOG_DEBUG("IPv6: NS using link local");
|
|
memcpy((char __FAR__ *)&ipv6->ipv6_src,
|
|
(char __FAR__ *)&ipv6_context->link_local_addr,
|
|
sizeof(IPV6_ADDR));
|
|
@@ -727,12 +725,12 @@ int ipv6_send_nd_solicited_packet(pIPV6_CONTEXT ipv6_context, pETH_HDR eth,
|
|
longest_match_addr =
|
|
ipv6_find_longest_match(ipv6_context, &ipv6->ipv6_dst);
|
|
if (longest_match_addr) {
|
|
- LOG_DEBUG("IPV6: NS using longest match addr");
|
|
+ LOG_DEBUG("IPv6: NS using longest match addr");
|
|
memcpy((char __FAR__ *)&ipv6->ipv6_src,
|
|
(char __FAR__ *)longest_match_addr,
|
|
sizeof(IPV6_ADDR));
|
|
} else {
|
|
- LOG_DEBUG("IPV6: NS using link local instead");
|
|
+ LOG_DEBUG("IPv6: NS using link local instead");
|
|
memcpy((char __FAR__ *)&ipv6->ipv6_src,
|
|
(char __FAR__ *)&ipv6_context->link_local_addr,
|
|
sizeof(IPV6_ADDR));
|
|
@@ -740,17 +738,8 @@ int ipv6_send_nd_solicited_packet(pIPV6_CONTEXT ipv6_context, pETH_HDR eth,
|
|
}
|
|
icmp = (pICMPV6_HDR) ((u8_t *) ipv6 + sizeof(IPV6_HDR));
|
|
|
|
- LOG_DEBUG
|
|
- ("IPV6: NS host ip addr %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x"
|
|
- " %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
|
|
- ipv6->ipv6_src.addr8[0], ipv6->ipv6_src.addr8[1],
|
|
- ipv6->ipv6_src.addr8[2], ipv6->ipv6_src.addr8[3],
|
|
- ipv6->ipv6_src.addr8[4], ipv6->ipv6_src.addr8[5],
|
|
- ipv6->ipv6_src.addr8[6], ipv6->ipv6_src.addr8[7],
|
|
- ipv6->ipv6_src.addr8[8], ipv6->ipv6_src.addr8[9],
|
|
- ipv6->ipv6_src.addr8[10], ipv6->ipv6_src.addr8[11],
|
|
- ipv6->ipv6_src.addr8[12], ipv6->ipv6_src.addr8[13],
|
|
- ipv6->ipv6_src.addr8[14], ipv6->ipv6_src.addr8[15]);
|
|
+ inet_ntop(AF_INET6, &ipv6->ipv6_src.addr8, addr_str, sizeof(addr_str));
|
|
+ LOG_DEBUG("IPv6: NS host IP addr: %s", addr_str);
|
|
/*
|
|
* Destination IP address to be resolved is after the ICMPv6
|
|
* header.
|
|
@@ -839,6 +828,7 @@ STATIC void ipv6_icmp_handle_router_adv(pIPV6_CONTEXT ipv6_context)
|
|
pICMPV6_OPT_HDR icmp_opt;
|
|
u16_t opt_len;
|
|
u16_t len;
|
|
+ char addr_str[INET6_ADDRSTRLEN];
|
|
|
|
if (ipv6_context->flags & IPV6_FLAGS_ROUTER_ADV_RECEIVED)
|
|
return;
|
|
@@ -868,7 +858,7 @@ STATIC void ipv6_icmp_handle_router_adv(pIPV6_CONTEXT ipv6_context)
|
|
}
|
|
|
|
if (ipv6_context->flags & IPV6_FLAGS_ROUTER_ADV_RECEIVED) {
|
|
- LOG_DEBUG("IPV6: RTR ADV nd_ra_flags=0x%x",
|
|
+ LOG_DEBUG("IPv6: RTR ADV nd_ra_flags = 0x%x",
|
|
icmp->nd_ra_flags_reserved);
|
|
if (icmp->nd_ra_curhoplimit > 0)
|
|
ipv6_context->hop_limit = icmp->nd_ra_curhoplimit;
|
|
@@ -880,21 +870,17 @@ STATIC void ipv6_icmp_handle_router_adv(pIPV6_CONTEXT ipv6_context)
|
|
ipv6_context->flags |= IPV6_FLAGS_OTHER_STATEFUL_CONFIG;
|
|
|
|
if (icmp->nd_ra_router_lifetime != 0) {
|
|
- /* This is a default router. */
|
|
- memcpy((char __FAR__ *)&ipv6_context->default_router,
|
|
- (char __FAR__ *)&ipv6->ipv6_src,
|
|
- sizeof(IPV6_ADDR));
|
|
- LOG_DEBUG("IPV6: def router "
|
|
- "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x "
|
|
- "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
|
|
- ipv6->ipv6_src.addr8[0], ipv6->ipv6_src.addr8[1],
|
|
- ipv6->ipv6_src.addr8[2], ipv6->ipv6_src.addr8[3],
|
|
- ipv6->ipv6_src.addr8[4], ipv6->ipv6_src.addr8[5],
|
|
- ipv6->ipv6_src.addr8[6], ipv6->ipv6_src.addr8[7],
|
|
- ipv6->ipv6_src.addr8[8], ipv6->ipv6_src.addr8[9],
|
|
- ipv6->ipv6_src.addr8[10], ipv6->ipv6_src.addr8[11],
|
|
- ipv6->ipv6_src.addr8[12], ipv6->ipv6_src.addr8[13],
|
|
- ipv6->ipv6_src.addr8[14], ipv6->ipv6_src.addr8[15]);
|
|
+ /* There is a default router. */
|
|
+ if (ipv6_context->ustack->router_autocfg !=
|
|
+ IPV6_RTR_AUTOCFG_OFF)
|
|
+ memcpy(
|
|
+ (char __FAR__*)&ipv6_context->default_router,
|
|
+ (char __FAR__*)&ipv6->ipv6_src,
|
|
+ sizeof(IPV6_ADDR));
|
|
+ inet_ntop(AF_INET6, &ipv6_context->default_router,
|
|
+ addr_str, sizeof(addr_str));
|
|
+ LOG_DEBUG("IPV6: Got default router IP addr: %s",
|
|
+ addr_str);
|
|
}
|
|
}
|
|
}
|
|
@@ -903,6 +889,7 @@ STATIC void ipv6_icmp_process_prefix(pIPV6_CONTEXT ipv6_context,
|
|
pICMPV6_OPT_PREFIX icmp_prefix)
|
|
{
|
|
IPV6_ADDR addr;
|
|
+ char addr_str[INET6_ADDRSTRLEN];
|
|
|
|
/* we only process on-link address info */
|
|
if (!(icmp_prefix->flags & ICMPV6_OPT_PREFIX_FLAG_ON_LINK))
|
|
@@ -917,6 +904,8 @@ STATIC void ipv6_icmp_process_prefix(pIPV6_CONTEXT ipv6_context,
|
|
(char __FAR__ *)&icmp_prefix->prefix, 8);
|
|
memcpy((char __FAR__ *)&addr.addr8[8],
|
|
&ipv6_context->link_local_addr.addr8[8], 8);
|
|
+ inet_ntop(AF_INET6, &addr, addr_str, sizeof(addr_str));
|
|
+ LOG_DEBUG("IPv6: Got RA ICMP option IP addr: %s", addr_str);
|
|
ipv6_add_prefix_entry(ipv6_context, &addr, 64);
|
|
}
|
|
}
|
|
@@ -929,11 +918,12 @@ STATIC void ipv6_icmp_handle_nd_adv(pIPV6_CONTEXT ipv6_context)
|
|
pICMPV6_OPT_LINK_ADDR link_opt = (pICMPV6_OPT_LINK_ADDR)((u8_t *)icmp +
|
|
sizeof(ICMPV6_HDR) + sizeof(IPV6_ADDR));
|
|
pIPV6_ADDR tar_addr6;
|
|
+ char addr_str[INET6_ADDRSTRLEN];
|
|
|
|
/* Added the multicast check for ARP table update */
|
|
/* Should we qualify for only our host's multicast and our
|
|
link_local_multicast?? */
|
|
- LOG_DEBUG("IPV6: Handle nd adv");
|
|
+ LOG_DEBUG("IPv6: Handle nd adv");
|
|
if ((ipv6_is_it_our_address(ipv6_context, &ipv6->ipv6_dst) == TRUE) ||
|
|
(memcmp((char __FAR__ *)&ipv6_context->link_local_multi,
|
|
(char __FAR__ *)&ipv6->ipv6_dst, sizeof(IPV6_ADDR)) == 0) ||
|
|
@@ -951,21 +941,14 @@ STATIC void ipv6_icmp_handle_nd_adv(pIPV6_CONTEXT ipv6_context)
|
|
if (link_opt->hdr.type == IPV6_ICMP_OPTION_TAR_ADDR) {
|
|
tar_addr6 = (pIPV6_ADDR)((u8_t *)icmp +
|
|
sizeof(ICMPV6_HDR));
|
|
- LOG_DEBUG("IPV6: tar mac %x:%x:%x:%x:%x:%x",
|
|
+ LOG_DEBUG("IPV6: Target MAC "
|
|
+ "%02x:%02x:%02x:%02x:%02x:%02x",
|
|
link_opt->link_addr[0], link_opt->link_addr[1],
|
|
link_opt->link_addr[2], link_opt->link_addr[3],
|
|
link_opt->link_addr[4], link_opt->link_addr[5]);
|
|
- LOG_DEBUG("IPV6: tar addr "
|
|
- "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x "
|
|
- "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
|
|
- tar_addr6->addr8[0], tar_addr6->addr8[1],
|
|
- tar_addr6->addr8[2], tar_addr6->addr8[3],
|
|
- tar_addr6->addr8[4], tar_addr6->addr8[5],
|
|
- tar_addr6->addr8[6], tar_addr6->addr8[7],
|
|
- tar_addr6->addr8[8], tar_addr6->addr8[9],
|
|
- tar_addr6->addr8[10], tar_addr6->addr8[11],
|
|
- tar_addr6->addr8[12], tar_addr6->addr8[13],
|
|
- tar_addr6->addr8[14], tar_addr6->addr8[15]);
|
|
+ inet_ntop(AF_INET6, &tar_addr6->addr8, addr_str,
|
|
+ sizeof(addr_str));
|
|
+ LOG_DEBUG("IPv6: Target IP addr %s", addr_str);
|
|
ipv6_update_arp_table(ipv6_context, tar_addr6,
|
|
(MAC_ADDR *)link_opt->link_addr);
|
|
}
|
|
@@ -985,14 +968,15 @@ STATIC void ipv6_icmp_handle_nd_sol(pIPV6_CONTEXT ipv6_context)
|
|
pIPV6_ADDR longest_match_addr;
|
|
pIPV6_ADDR tar_addr6;
|
|
|
|
- LOG_DEBUG("IPV6: Handle nd sol");
|
|
+ LOG_DEBUG("IPv6: Handle nd sol");
|
|
|
|
if ((memcmp((char __FAR__ *)&ipv6_context->mac_addr,
|
|
(char __FAR__ *)eth->dest_mac, sizeof(MAC_ADDR)) != 0) &&
|
|
(iscsiL2IsOurMcAddr(ipv6_context, (pMAC_ADDRESS) & eth->dest_mac) ==
|
|
FALSE)) {
|
|
/* This packet is not for us to handle */
|
|
- LOG_DEBUG("IPV6: MAC not addressed to us %x:%x:%x:%x:%x:%x",
|
|
+ LOG_DEBUG("IPv6: MAC not addressed to us "
|
|
+ "%02x:%02x:%02x:%02x:%02x:%02x",
|
|
eth->dest_mac[0], eth->dest_mac[1],
|
|
eth->dest_mac[2], eth->dest_mac[3],
|
|
eth->dest_mac[4], eth->dest_mac[5]);
|
|
@@ -1005,7 +989,7 @@ STATIC void ipv6_icmp_handle_nd_sol(pIPV6_CONTEXT ipv6_context)
|
|
sizeof(ICMPV6_HDR)))
|
|
== FALSE) {
|
|
/* This packet is not for us to handle */
|
|
- LOG_DEBUG("IPV6: IP not addressed to us");
|
|
+ LOG_DEBUG("IPv6: IP not addressed to us");
|
|
return;
|
|
}
|
|
|
|
@@ -1026,7 +1010,7 @@ STATIC void ipv6_icmp_handle_nd_sol(pIPV6_CONTEXT ipv6_context)
|
|
tar_addr6 = (pIPV6_ADDR)((u8_t *)icmp + sizeof(ICMPV6_HDR));
|
|
if (ipv6_is_it_our_link_local_address(ipv6_context, tar_addr6)
|
|
== TRUE) {
|
|
- LOG_DEBUG("IPV6: NA using link local");
|
|
+ LOG_DEBUG("IPv6: NA using link local");
|
|
memcpy((char __FAR__ *)&ipv6->ipv6_src,
|
|
(char __FAR__ *)&ipv6_context->link_local_addr,
|
|
sizeof(IPV6_ADDR));
|
|
@@ -1034,12 +1018,12 @@ STATIC void ipv6_icmp_handle_nd_sol(pIPV6_CONTEXT ipv6_context)
|
|
longest_match_addr =
|
|
ipv6_find_longest_match(ipv6_context, tar_addr6);
|
|
if (longest_match_addr) {
|
|
- LOG_DEBUG("IPV6: NA using longest match addr");
|
|
+ LOG_DEBUG("IPv6: NA using longest match addr");
|
|
memcpy((char __FAR__ *)&ipv6->ipv6_src,
|
|
(char __FAR__ *)longest_match_addr,
|
|
sizeof(IPV6_ADDR));
|
|
} else {
|
|
- LOG_DEBUG("IPV6: NA using link local instead");
|
|
+ LOG_DEBUG("IPv6: NA using link local instead");
|
|
memcpy((char __FAR__ *)&ipv6->ipv6_src,
|
|
(char __FAR__ *)&ipv6_context->link_local_addr,
|
|
sizeof(IPV6_ADDR));
|
|
@@ -1047,7 +1031,7 @@ STATIC void ipv6_icmp_handle_nd_sol(pIPV6_CONTEXT ipv6_context)
|
|
}
|
|
} else {
|
|
/* No target link address, just use whatever it sent to us */
|
|
- LOG_DEBUG("IPV6: NA use dst addr");
|
|
+ LOG_DEBUG("IPv6: NA use dst addr");
|
|
memcpy((char __FAR__ *)&ipv6->ipv6_src,
|
|
(char __FAR__ *)&tmp,
|
|
sizeof(IPV6_ADDR));
|
|
@@ -1085,7 +1069,7 @@ STATIC void ipv6_icmp_handle_nd_sol(pIPV6_CONTEXT ipv6_context)
|
|
*/
|
|
ipv6->ipv6_plen = HOST_TO_NET16((sizeof(ICMPV6_HDR) +
|
|
icmpv6_opt_len + sizeof(IPV6_ADDR)));
|
|
- LOG_DEBUG("IPV6: Send nd adv");
|
|
+ LOG_DEBUG("IPv6: Send nd adv");
|
|
ipv6_send(ipv6_context,
|
|
(u8_t *) icmp - (u8_t *) eth +
|
|
sizeof(ICMPV6_HDR) +
|
|
@@ -1118,7 +1102,7 @@ STATIC void ipv6_icmp_handle_echo_request(pIPV6_CONTEXT ipv6_context)
|
|
icmp->icmpv6_type = ICMPV6_ECHO_REPLY;
|
|
icmp->icmpv6_code = 0;
|
|
icmp->icmpv6_cksum = 0;
|
|
- LOG_DEBUG("IPV6: Send echo reply");
|
|
+ LOG_DEBUG("IPv6: Send echo reply");
|
|
ipv6_send(ipv6_context, (u8_t *) icmp - (u8_t *) eth +
|
|
sizeof(IPV6_HDR) + HOST_TO_NET16(ipv6->ipv6_plen));
|
|
return;
|
|
@@ -1126,7 +1110,8 @@ STATIC void ipv6_icmp_handle_echo_request(pIPV6_CONTEXT ipv6_context)
|
|
|
|
void ipv6_set_ip_params(pIPV6_CONTEXT ipv6_context,
|
|
pIPV6_ADDR src_ip, u8_t prefix_len,
|
|
- pIPV6_ADDR default_gateway)
|
|
+ pIPV6_ADDR default_gateway,
|
|
+ pIPV6_ADDR linklocal)
|
|
{
|
|
if (!(IPV6_IS_ADDR_UNSPECIFIED(src_ip))) {
|
|
ipv6_add_prefix_entry(ipv6_context, src_ip, prefix_len);
|
|
@@ -1146,9 +1131,30 @@ void ipv6_set_ip_params(pIPV6_CONTEXT ipv6_context,
|
|
}
|
|
|
|
if (!(IPV6_IS_ADDR_UNSPECIFIED(default_gateway))) {
|
|
- /* This is a default router. */
|
|
- memcpy((char __FAR__ *)&ipv6_context->default_router,
|
|
- (char __FAR__ *)default_gateway, sizeof(IPV6_ADDR));
|
|
+ /* Override the default gateway addr */
|
|
+ memcpy((char __FAR__*)&ipv6_context->default_router,
|
|
+ (char __FAR__*)default_gateway, sizeof(IPV6_ADDR));
|
|
+ ipv6_add_prefix_entry(ipv6_context, default_gateway,
|
|
+ prefix_len);
|
|
+ }
|
|
+ if (!(IPV6_IS_ADDR_UNSPECIFIED(linklocal))) {
|
|
+ /* Override the linklocal addr */
|
|
+ memcpy((char __FAR__*)&ipv6_context->link_local_addr,
|
|
+ (char __FAR__*)linklocal, sizeof(IPV6_ADDR));
|
|
+ ipv6_context->link_local_multi.addr8[0] = 0xff;
|
|
+ ipv6_context->link_local_multi.addr8[1] = 0x02;
|
|
+ ipv6_context->link_local_multi.addr8[11] = 0x01;
|
|
+ ipv6_context->link_local_multi.addr8[12] = 0xff;
|
|
+ ipv6_context->link_local_multi.addr8[13] |=
|
|
+ ipv6_context->link_local_addr.addr8[13];
|
|
+ ipv6_context->link_local_multi.addr16[7] =
|
|
+ ipv6_context->link_local_addr.addr16[7];
|
|
+
|
|
+ /* Default Prefix length is 64 */
|
|
+ /* Add Link local address to the head of the ipv6 address
|
|
+ list */
|
|
+ ipv6_add_prefix_entry(ipv6_context,
|
|
+ &ipv6_context->link_local_addr, 64);
|
|
}
|
|
}
|
|
|
|
@@ -1220,7 +1226,7 @@ u16_t ipv6_do_stateful_dhcpv6(pIPV6_CONTEXT ipv6_context, u32_t flags)
|
|
(IPV6_FLAGS_MANAGED_ADDR_CONFIG | IPV6_FLAGS_OTHER_STATEFUL_CONFIG);
|
|
|
|
if (!(ipv6_context->flags & IPV6_FLAGS_ROUTER_ADV_RECEIVED)) {
|
|
- LOG_DEBUG("IPV6: There is no IPv6 router on the network");
|
|
+ LOG_DEBUG("IPv6: There is no IPv6 router on the network");
|
|
ra_flags |=
|
|
(IPV6_FLAGS_MANAGED_ADDR_CONFIG |
|
|
IPV6_FLAGS_OTHER_STATEFUL_CONFIG);
|
|
@@ -1234,7 +1240,7 @@ u16_t ipv6_do_stateful_dhcpv6(pIPV6_CONTEXT ipv6_context, u32_t flags)
|
|
(ra_flags & IPV6_FLAGS_OTHER_STATEFUL_CONFIG))
|
|
task |= DHCPV6_TASK_GET_OTHER_PARAMS;
|
|
|
|
- LOG_DEBUG("IPV6: Stateful flags=0x%x, ra_flags=0x%x, task=0x%x", flags,
|
|
+ LOG_DEBUG("IPv6: Stateful flags=0x%x, ra_flags=0x%x, task=0x%x", flags,
|
|
ra_flags, task);
|
|
|
|
return task;
|
|
diff --git a/iscsiuio/src/uip/ipv6.h b/iscsiuio/src/uip/ipv6.h
|
|
index 167f5f6..ed2f3a4 100644
|
|
--- a/iscsiuio/src/uip/ipv6.h
|
|
+++ b/iscsiuio/src/uip/ipv6.h
|
|
@@ -343,7 +343,8 @@ int ipv6_add_prefix_entry(pIPV6_CONTEXT ipv6_context,
|
|
IPV6_ADDR * ipv6_addr, u8_t prefix_len);
|
|
void ipv6_set_ip_params(pIPV6_CONTEXT ipv6_context,
|
|
pIPV6_ADDR src_ip, u8_t prefix_len,
|
|
- pIPV6_ADDR default_gateway);
|
|
+ pIPV6_ADDR default_gateway,
|
|
+ pIPV6_ADDR linklocal);
|
|
void ipv6_set_host_addr(pIPV6_CONTEXT ipv6_context, pIPV6_ADDR src_ip);
|
|
int ipv6_get_default_router_ip_addrs(pIPV6_CONTEXT ipv6_context,
|
|
pIPV6_ADDR ip_addr);
|
|
diff --git a/iscsiuio/src/uip/ipv6_ndpc.c b/iscsiuio/src/uip/ipv6_ndpc.c
|
|
index 6d101ce..89dbd5e 100644
|
|
--- a/iscsiuio/src/uip/ipv6_ndpc.c
|
|
+++ b/iscsiuio/src/uip/ipv6_ndpc.c
|
|
@@ -65,6 +65,7 @@ static PT_THREAD(handle_ndp(struct uip_stack *ustack, int force))
|
|
pIPV6_CONTEXT ipv6c;
|
|
pDHCPV6_CONTEXT dhcpv6c = NULL;
|
|
u16_t task = 0;
|
|
+ char buf[INET6_ADDRSTRLEN];
|
|
|
|
s = ustack->ndpc;
|
|
if (s == NULL) {
|
|
@@ -86,6 +87,9 @@ static PT_THREAD(handle_ndp(struct uip_stack *ustack, int force))
|
|
if (s->state == NDPC_STATE_RTR_ADV)
|
|
goto rtr_adv;
|
|
|
|
+ /* For AUTOCFG == DHCPv6, do all
|
|
+ For == ND, skip DHCP only and do RTR
|
|
+ For == UNUSED/UNSPEC, do all as according to DHCP or not */
|
|
s->state = NDPC_STATE_RTR_SOL;
|
|
/* try_again: */
|
|
s->ticks = CLOCK_SECOND * IPV6_MAX_ROUTER_SOL_DELAY;
|
|
@@ -97,7 +101,7 @@ static PT_THREAD(handle_ndp(struct uip_stack *ustack, int force))
|
|
ipv6_autoconfig(s->ipv6_context);
|
|
|
|
timer_set(&s->timer, s->ticks);
|
|
- wait_rtr:
|
|
+wait_rtr:
|
|
s->ustack->uip_flags &= ~UIP_NEWDATA;
|
|
LOG_DEBUG("%s: ndpc_handle wait for rtr adv flags=0x%x",
|
|
s->nic->log_name, ipv6c->flags);
|
|
@@ -134,10 +138,12 @@ no_rtr_adv:
|
|
s->state = NDPC_STATE_RTR_ADV;
|
|
|
|
rtr_adv:
|
|
- /* Both Static IPv6 and DHCPv6 comes here */
|
|
+ if (!(ustack->ip_config & IPV6_CONFIG_DHCP))
|
|
+ goto staticv6;
|
|
|
|
+ /* Only DHCPv6 comes here */
|
|
task = ipv6_do_stateful_dhcpv6(ipv6c, ISCSI_FLAGS_DHCP_TCPIP_CONFIG);
|
|
- if (task && (ustack->ip_config == IPV6_CONFIG_DHCP)) {
|
|
+ if (task) {
|
|
/* Run the DHCPv6 engine */
|
|
|
|
if (!dhcpv6c)
|
|
@@ -187,6 +193,7 @@ wait_dhcp:
|
|
}
|
|
} while (dhcpv6c->dhcpv6_done == FALSE);
|
|
s->state = NDPC_STATE_DHCPV6_DONE;
|
|
+
|
|
LOG_DEBUG("%s: ndpc_handle got dhcpv6", s->nic->log_name);
|
|
|
|
/* End of DHCPv6 engine */
|
|
@@ -197,28 +204,25 @@ wait_dhcp:
|
|
s->nic->log_name);
|
|
PT_RESTART(&s->pt);
|
|
}
|
|
- IPV6_ADDR tmp, tmp2;
|
|
- char buf[INET6_ADDRSTRLEN];
|
|
-
|
|
+staticv6:
|
|
ipv6_disable_dhcpv6(ipv6c);
|
|
- memcpy(&tmp.addr8, &ustack->hostaddr6, sizeof(IPV6_ADDR));
|
|
- LOG_DEBUG("%s: host ip addr %02x:%02x:%02x:%02x:%02x:%02x:"
|
|
- "%02x:%02x", s->nic->log_name,
|
|
- ustack->hostaddr6[0], ustack->hostaddr6[1],
|
|
- ustack->hostaddr6[2], ustack->hostaddr6[3],
|
|
- ustack->hostaddr6[4], ustack->hostaddr6[5],
|
|
- ustack->hostaddr6[6], ustack->hostaddr6[7]);
|
|
- memset(&tmp2, 0, sizeof(tmp2));
|
|
- ipv6_set_ip_params(ipv6c, &tmp,
|
|
- ustack->prefix_len, &tmp2);
|
|
-
|
|
- ipv6_add_solit_node_address(ipv6c, &tmp);
|
|
-
|
|
- inet_ntop(AF_INET6, &tmp.addr8, buf, sizeof(buf));
|
|
- LOG_INFO("%s: Static hostaddr IP: %s", s->nic->log_name,
|
|
- buf);
|
|
-
|
|
}
|
|
+ /* Copy out the default_router_addr6 and ll */
|
|
+ if (ustack->router_autocfg != IPV6_RTR_AUTOCFG_OFF)
|
|
+ memcpy(&ustack->default_route_addr6,
|
|
+ &ipv6c->default_router, sizeof(IPV6_ADDR));
|
|
+ inet_ntop(AF_INET6, &ustack->default_route_addr6,
|
|
+ buf, sizeof(buf));
|
|
+ LOG_INFO("%s: Default router IP: %s", s->nic->log_name,
|
|
+ buf);
|
|
+
|
|
+ if (ustack->linklocal_autocfg != IPV6_LL_AUTOCFG_OFF)
|
|
+ memcpy(&ustack->linklocal6, &ipv6c->link_local_addr,
|
|
+ sizeof(IPV6_ADDR));
|
|
+ inet_ntop(AF_INET6, &ustack->linklocal6,
|
|
+ buf, sizeof(buf));
|
|
+ LOG_INFO("%s: Linklocal IP: %s", s->nic->log_name,
|
|
+ buf);
|
|
|
|
ipv6_loop:
|
|
s->state = NDPC_STATE_BACKGROUND_LOOP;
|
|
@@ -249,6 +253,8 @@ int ndpc_init(nic_t * nic, struct uip_stack *ustack,
|
|
pIPV6_CONTEXT ipv6c;
|
|
pDHCPV6_CONTEXT dhcpv6c;
|
|
struct ndpc_state *s = ustack->ndpc;
|
|
+ IPV6_ADDR src, gw, ll;
|
|
+ char buf[INET6_ADDRSTRLEN];
|
|
|
|
if (s) {
|
|
LOG_DEBUG("NDP: NDP context already allocated");
|
|
@@ -315,9 +321,30 @@ init2:
|
|
|
|
if (ustack->ip_config == IPV6_CONFIG_DHCP) {
|
|
/* DHCPv6 specific */
|
|
+ memset(&src, 0, sizeof(src));
|
|
} else {
|
|
/* Static v6 specific */
|
|
+ memcpy(&src.addr8, &ustack->hostaddr6, sizeof(IPV6_ADDR));
|
|
+ ipv6_add_solit_node_address(ipv6c, &src);
|
|
+
|
|
+ inet_ntop(AF_INET6, &src.addr8, buf, sizeof(buf));
|
|
+ LOG_INFO("%s: Static hostaddr IP: %s", s->nic->log_name,
|
|
+ buf);
|
|
}
|
|
+ /* Copy out the default_router_addr6 and ll */
|
|
+ if (ustack->router_autocfg == IPV6_RTR_AUTOCFG_OFF)
|
|
+ memcpy(&gw.addr8, &ustack->default_route_addr6,
|
|
+ sizeof(IPV6_ADDR));
|
|
+ else
|
|
+ memset(&gw, 0, sizeof(gw));
|
|
+
|
|
+ if (ustack->linklocal_autocfg == IPV6_LL_AUTOCFG_OFF)
|
|
+ memcpy(&ll.addr8, &ustack->linklocal6,
|
|
+ sizeof(IPV6_ADDR));
|
|
+ else
|
|
+ memset(&ll, 0, sizeof(ll));
|
|
+ ipv6_set_ip_params(ipv6c, &src,
|
|
+ ustack->prefix_len, &gw, &ll);
|
|
|
|
return 0;
|
|
error2:
|
|
@@ -367,16 +394,14 @@ int ndpc_request(struct uip_stack *ustack, void *in, void *out, int request)
|
|
//LOG_DEBUG("%s: NDP - Request %d", s->nic->log_name, request);
|
|
|
|
while (s->state != NDPC_STATE_BACKGROUND_LOOP) {
|
|
- LOG_DEBUG("%s: ndpc state not in background loop, run handler",
|
|
- s->nic->log_name);
|
|
+ LOG_DEBUG("%s: ndpc state not in background loop, run handler ",
|
|
+ "request = %d", s->nic->log_name, request);
|
|
handle_ndp(ustack, 1);
|
|
}
|
|
|
|
ipv6c = s->ipv6_context;
|
|
switch (request) {
|
|
case NEIGHBOR_SOLICIT:
|
|
- LOG_DEBUG("nd sol: in=%p in->eth=%p in->ipv6=%p", in, in,
|
|
- (u8_t *) in + 4);
|
|
*(int *)out = ipv6_send_nd_solicited_packet(ipv6c,
|
|
(pETH_HDR) ((pNDPC_REQPTR)in)->eth,
|
|
(pIPV6_HDR) ((pNDPC_REQPTR)in)->ipv6);
|
|
@@ -385,12 +410,6 @@ int ndpc_request(struct uip_stack *ustack, void *in, void *out, int request)
|
|
*(int *)out = ipv6_is_it_our_link_local_address(ipv6c,
|
|
(pIPV6_ADDR)in);
|
|
break;
|
|
- case GET_LINK_LOCAL_ADDR:
|
|
- *(pIPV6_ADDR *) out = &ipv6c->link_local_addr;
|
|
- break;
|
|
- case GET_DEFAULT_ROUTER_ADDR:
|
|
- *(pIPV6_ADDR *)out = &ipv6c->default_router;
|
|
- break;
|
|
case CHECK_ARP_TABLE:
|
|
*(int *)out = ipv6_ip_in_arp_table(ipv6c,
|
|
(pIPV6_ADDR) ((pNDPC_REQPTR)in)->ipv6,
|
|
@@ -399,7 +418,9 @@ int ndpc_request(struct uip_stack *ustack, void *in, void *out, int request)
|
|
case GET_HOST_ADDR:
|
|
*(pIPV6_ADDR *)out = ipv6_find_longest_match(ipv6c,
|
|
(pIPV6_ADDR)in);
|
|
+ break;
|
|
default:
|
|
+ ret = -EINVAL;
|
|
break;
|
|
}
|
|
return ret;
|
|
diff --git a/iscsiuio/src/uip/uip.c b/iscsiuio/src/uip/uip.c
|
|
index 9c79e07..d03b92e 100644
|
|
--- a/iscsiuio/src/uip/uip.c
|
|
+++ b/iscsiuio/src/uip/uip.c
|
|
@@ -1403,8 +1403,6 @@ void uip_process(struct uip_stack *ustack, u8_t flag)
|
|
#endif /* UIP_UDP */
|
|
|
|
/* This is IPv6 ICMPv6 processing code. */
|
|
- LOG_DEBUG(PFX "icmp6_input: length %d", ustack->uip_len);
|
|
-
|
|
if (ipv6_hdr->ip6_nxt != UIP_PROTO_ICMP6) {
|
|
/* We only allow ICMPv6 packets from here. */
|
|
++ustack->stats.ip.drop;
|
|
@@ -2344,7 +2342,7 @@ tcp_send:
|
|
uip_ip6addr_copy(IPv6_BUF(ustack)->srcipaddr,
|
|
ustack->hostaddr6);
|
|
uip_ip6addr_copy(IPv6_BUF(ustack)->destipaddr,
|
|
- uip_connr->ripaddr);
|
|
+ uip_connr->ripaddr6);
|
|
} else {
|
|
tcp_ipv4_hdr->proto = UIP_PROTO_TCP;
|
|
uip_ip4addr_copy(tcp_ipv4_hdr->srcipaddr, ustack->hostaddr);
|
|
diff --git a/iscsiuio/src/uip/uip.h b/iscsiuio/src/uip/uip.h
|
|
index 2b5f88c..ccac680 100644
|
|
--- a/iscsiuio/src/uip/uip.h
|
|
+++ b/iscsiuio/src/uip/uip.h
|
|
@@ -1031,6 +1031,7 @@ extern u16_t uip_urglen, uip_surglen;
|
|
*/
|
|
struct __attribute__ ((__packed__)) uip_conn {
|
|
uip_ip4addr_t ripaddr;
|
|
+ uip_ip6addr_t ripaddr6;
|
|
/**< The IP address of the remote host. */
|
|
|
|
u16_t lport; /**< The local TCP port, in network byte order. */
|
|
@@ -1564,6 +1565,7 @@ struct uip_stack {
|
|
a new connection. */
|
|
#endif /* UIP_ACTIVE_OPEN */
|
|
|
|
+#define IP_CONFIG_OFF 0x00
|
|
#define IPV4_CONFIG_OFF 0x01
|
|
#define IPV4_CONFIG_STATIC 0x02
|
|
#define IPV4_CONFIG_DHCP 0x04
|
|
@@ -1573,8 +1575,24 @@ struct uip_stack {
|
|
u8_t ip_config;
|
|
|
|
uip_ip4addr_t hostaddr, netmask, default_route_addr;
|
|
- uip_ip6addr_t hostaddr6, netmask6, default_route_addr6;
|
|
+ uip_ip6addr_t hostaddr6, netmask6, default_route_addr6,
|
|
+ linklocal6;
|
|
int prefix_len;
|
|
+ u8_t ipv6_autocfg;
|
|
+#define IPV6_AUTOCFG_DHCPV6 (1<<0)
|
|
+#define IPV6_AUTOCFG_ND (1<<1)
|
|
+#define IPV6_AUTOCFG_NOTSPEC (1<<6)
|
|
+#define IPV6_AUTOCFG_NOTUSED (1<<7)
|
|
+ u8_t linklocal_autocfg;
|
|
+#define IPV6_LL_AUTOCFG_ON (1<<0)
|
|
+#define IPV6_LL_AUTOCFG_OFF (1<<1)
|
|
+#define IPV6_LL_AUTOCFG_NOTSPEC (1<<6)
|
|
+#define IPV6_LL_AUTOCFG_NOTUSED (1<<7)
|
|
+ u8_t router_autocfg;
|
|
+#define IPV6_RTR_AUTOCFG_ON (1<<0)
|
|
+#define IPV6_RTR_AUTOCFG_OFF (1<<1)
|
|
+#define IPV6_RTR_AUTOCFG_NOTSPEC (1<<6)
|
|
+#define IPV6_RTR_AUTOCFG_NOTUSED (1<<7)
|
|
|
|
#define UIP_NEIGHBOR_ENTRIES 8
|
|
struct neighbor_entry neighbor_entries[UIP_NEIGHBOR_ENTRIES];
|
|
@@ -1586,7 +1604,6 @@ struct uip_stack {
|
|
pthread_mutex_t lock;
|
|
|
|
/* IPv6 support */
|
|
-
|
|
#define UIP_SUPPORT_IPv6_ENABLED 0x01
|
|
#define UIP_SUPPORT_IPv6_DISABLED 0x02
|
|
u8_t enable_IPv6;
|
|
diff --git a/iscsiuio/src/uip/uip_arp.c b/iscsiuio/src/uip/uip_arp.c
|
|
index 321281c..3ef3b07 100644
|
|
--- a/iscsiuio/src/uip/uip_arp.c
|
|
+++ b/iscsiuio/src/uip/uip_arp.c
|
|
@@ -265,10 +265,14 @@ uip_arp_arpin(nic_interface_t * nic_iface,
|
|
arp->sipaddr[0] = ustack->hostaddr[0];
|
|
arp->sipaddr[1] = ustack->hostaddr[1];
|
|
|
|
- if (nic_iface->vlan_id == 0)
|
|
+ if (nic_iface->vlan_id == 0) {
|
|
eth->type = htons(UIP_ETHTYPE_ARP);
|
|
- else
|
|
+ pkt->buf_size = sizeof(*arp) + sizeof(*eth);
|
|
+ } else {
|
|
eth->type = htons(UIP_ETHTYPE_8021Q);
|
|
+ pkt->buf_size = sizeof(*arp) +
|
|
+ sizeof(struct uip_vlan_eth_hdr);
|
|
+ }
|
|
pkt->buf_size = sizeof(*arp) + sizeof(*eth);
|
|
}
|
|
break;
|
|
diff --git a/iscsiuio/src/unix/iscsid_ipc.c b/iscsiuio/src/unix/iscsid_ipc.c
|
|
index 6bc5c11..d7372fc 100644
|
|
--- a/iscsiuio/src/unix/iscsid_ipc.c
|
|
+++ b/iscsiuio/src/unix/iscsid_ipc.c
|
|
@@ -70,20 +70,34 @@ struct iscsid_options {
|
|
pthread_t thread;
|
|
};
|
|
|
|
-struct ip_addr_mask {
|
|
- int ip_type;
|
|
- union {
|
|
- struct in_addr addr4;
|
|
- struct in6_addr addr6;
|
|
- } addr;
|
|
- union {
|
|
- struct in_addr nm4;
|
|
- struct in6_addr nm6;
|
|
- } netmask;
|
|
-#define addr4 addr.addr4
|
|
-#define addr6 addr.addr6
|
|
-#define nm4 netmask.nm4
|
|
-#define nm6 netmask.nm6
|
|
+struct iface_rec_decode {
|
|
+ /* General */
|
|
+ int32_t iface_num;
|
|
+ uint32_t ip_type;
|
|
+
|
|
+ /* IPv4 */
|
|
+ struct in_addr ipv4_addr;
|
|
+ struct in_addr ipv4_subnet_mask;
|
|
+ struct in_addr ipv4_gateway;
|
|
+
|
|
+ /* IPv6 */
|
|
+ struct in6_addr ipv6_addr;
|
|
+ struct in6_addr ipv6_subnet_mask;
|
|
+ uint32_t prefix_len;
|
|
+ struct in6_addr ipv6_linklocal;
|
|
+ struct in6_addr ipv6_router;
|
|
+
|
|
+ uint8_t ipv6_autocfg;
|
|
+ uint8_t linklocal_autocfg;
|
|
+ uint8_t router_autocfg;
|
|
+
|
|
+ uint8_t vlan_state;
|
|
+ uint8_t vlan_priority;
|
|
+ uint16_t vlan_id;
|
|
+
|
|
+#define MIN_MTU_SUPPORT 46
|
|
+#define MAX_MTU_SUPPORT 9000
|
|
+ uint16_t mtu;
|
|
};
|
|
|
|
/******************************************************************************
|
|
@@ -119,8 +133,7 @@ static void *enable_nic_thread(void *data)
|
|
pthread_exit(NULL);
|
|
}
|
|
|
|
-static int decode_cidr(char *in_ipaddr_str, struct ip_addr_mask *ipam,
|
|
- int *prefix_len)
|
|
+static int decode_cidr(char *in_ipaddr_str, struct iface_rec_decode *ird)
|
|
{
|
|
int rc = 0, i;
|
|
char *tmp, *tok;
|
|
@@ -130,7 +143,6 @@ static int decode_cidr(char *in_ipaddr_str, struct ip_addr_mask *ipam,
|
|
struct in_addr ia;
|
|
struct in6_addr ia6;
|
|
|
|
- memset(ipam, 0, sizeof(struct ip_addr_mask));
|
|
if (strlen(in_ipaddr_str) > NI_MAXHOST)
|
|
strncpy(ipaddr_str, in_ipaddr_str, NI_MAXHOST);
|
|
else
|
|
@@ -149,16 +161,16 @@ static int decode_cidr(char *in_ipaddr_str, struct ip_addr_mask *ipam,
|
|
|
|
/* Determine if the IP address passed from the iface file is
|
|
* an IPv4 or IPv6 address */
|
|
- rc = inet_pton(AF_INET, ipaddr_str, &ipam->addr6);
|
|
+ rc = inet_pton(AF_INET, ipaddr_str, &ird->ipv6_addr);
|
|
if (rc == 0) {
|
|
/* Test to determine if the addres is an IPv6 address */
|
|
- rc = inet_pton(AF_INET6, ipaddr_str, &ipam->addr6);
|
|
+ rc = inet_pton(AF_INET6, ipaddr_str, &ird->ipv6_addr);
|
|
if (rc == 0) {
|
|
LOG_ERR(PFX "Could not parse IP address: '%s'",
|
|
ipaddr_str);
|
|
goto out;
|
|
}
|
|
- ipam->ip_type = AF_INET6;
|
|
+ ird->ip_type = AF_INET6;
|
|
if (keepbits > 128) {
|
|
LOG_ERR(PFX "CIDR netmask > 128 for IPv6: %d(%s)",
|
|
keepbits, tmp);
|
|
@@ -166,15 +178,15 @@ static int decode_cidr(char *in_ipaddr_str, struct ip_addr_mask *ipam,
|
|
}
|
|
if (!keepbits) {
|
|
/* Default prefix mask to 64 */
|
|
- memcpy(&ipam->nm6.s6_addr, all_zeroes_addr6,
|
|
+ memcpy(&ird->ipv6_subnet_mask.s6_addr, all_zeroes_addr6,
|
|
sizeof(struct in6_addr));
|
|
+ ird->prefix_len = 64;
|
|
for (i = 0; i < 2; i++)
|
|
- ipam->nm6.s6_addr32[i] = 0xffffffff;
|
|
+ ird->ipv6_subnet_mask.s6_addr32[i] = 0xffffffff;
|
|
goto out;
|
|
}
|
|
- *prefix_len = keepbits;
|
|
- memcpy(&ia6.s6_addr, all_zeroes_addr6,
|
|
- sizeof(struct in6_addr));
|
|
+ ird->prefix_len = keepbits;
|
|
+ memcpy(&ia6.s6_addr, all_zeroes_addr6, sizeof(struct in6_addr));
|
|
for (i = 0; i < 4; i++) {
|
|
if (keepbits < 32) {
|
|
ia6.s6_addr32[i] = keepbits > 0 ?
|
|
@@ -184,12 +196,12 @@ static int decode_cidr(char *in_ipaddr_str, struct ip_addr_mask *ipam,
|
|
ia6.s6_addr32[i] = 0xFFFFFFFF;
|
|
keepbits -= 32;
|
|
}
|
|
- ipam->nm6 = ia6;
|
|
+ ird->ipv6_subnet_mask = ia6;
|
|
if (inet_ntop(AF_INET6, &ia6, str, sizeof(str)))
|
|
LOG_INFO(PFX "Using netmask: %s", str);
|
|
} else {
|
|
- ipam->ip_type = AF_INET;
|
|
- rc = inet_pton(AF_INET, ipaddr_str, &ipam->addr4);
|
|
+ ird->ip_type = AF_INET;
|
|
+ rc = inet_pton(AF_INET, ipaddr_str, &ird->ipv4_addr);
|
|
|
|
if (keepbits > 32) {
|
|
LOG_ERR(PFX "CIDR netmask > 32 for IPv4: %d(%s)",
|
|
@@ -197,54 +209,153 @@ static int decode_cidr(char *in_ipaddr_str, struct ip_addr_mask *ipam,
|
|
goto out;
|
|
}
|
|
ia.s_addr = keepbits > 0 ? 0x00 - (1 << (32 - keepbits)) : 0;
|
|
- ipam->nm4.s_addr = htonl(ia.s_addr);
|
|
- LOG_INFO(PFX "Using netmask: %s", inet_ntoa(ipam->nm4));
|
|
+ ird->ipv4_subnet_mask.s_addr = htonl(ia.s_addr);
|
|
+ LOG_INFO(PFX "Using netmask: %s",
|
|
+ inet_ntoa(ird->ipv4_subnet_mask));
|
|
}
|
|
out:
|
|
return rc;
|
|
}
|
|
|
|
+static int decode_iface(struct iface_rec_decode *ird, struct iface_rec *rec)
|
|
+{
|
|
+ int rc = 0;
|
|
+ char ipaddr_str[NI_MAXHOST];
|
|
+
|
|
+ /* Decodes the rec contents */
|
|
+ memset(ird, 0, sizeof(struct iface_rec_decode));
|
|
+
|
|
+ /* Detect for CIDR notation and strip off the netmask if present */
|
|
+ rc = decode_cidr(rec->ipaddress, ird);
|
|
+ if (rc && !ird->ip_type) {
|
|
+ LOG_ERR(PFX "cidr decode err: rc=%d, ip_type=%d",
|
|
+ rc, ird->ip_type);
|
|
+ /* Can't decode address, just exit */
|
|
+ return rc;
|
|
+ }
|
|
+ rc = 0;
|
|
+
|
|
+ ird->iface_num = rec->iface_num;
|
|
+ ird->vlan_id = rec->vlan_id;
|
|
+ if (rec->iface_num != IFACE_NUM_INVALID) {
|
|
+ ird->mtu = rec->mtu;
|
|
+ if (rec->vlan_id && strcmp(rec->vlan_state, "disable")) {
|
|
+ ird->vlan_state = 1;
|
|
+ ird->vlan_priority = rec->vlan_priority;
|
|
+ ird->vlan_id = rec->vlan_id;
|
|
+ }
|
|
+ if (ird->ip_type == AF_INET6) {
|
|
+ if (!strcmp(rec->ipv6_autocfg, "dhcpv6"))
|
|
+ ird->ipv6_autocfg = IPV6_AUTOCFG_DHCPV6;
|
|
+ else if (!strcmp(rec->ipv6_autocfg, "nd"))
|
|
+ ird->ipv6_autocfg = IPV6_AUTOCFG_ND;
|
|
+ else
|
|
+ ird->ipv6_autocfg = IPV6_AUTOCFG_NOTSPEC;
|
|
+
|
|
+ if (!strcmp(rec->linklocal_autocfg, "auto"))
|
|
+ ird->linklocal_autocfg = IPV6_LL_AUTOCFG_ON;
|
|
+ else if (!strcmp(rec->linklocal_autocfg, "off"))
|
|
+ ird->linklocal_autocfg = IPV6_LL_AUTOCFG_OFF;
|
|
+ else /* default */
|
|
+ ird->linklocal_autocfg = IPV6_LL_AUTOCFG_ON;
|
|
+
|
|
+ if (!strcmp(rec->router_autocfg, "auto"))
|
|
+ ird->router_autocfg = IPV6_RTR_AUTOCFG_ON;
|
|
+ else if (!strcmp(rec->router_autocfg, "off"))
|
|
+ ird->router_autocfg = IPV6_RTR_AUTOCFG_OFF;
|
|
+ else /* default */
|
|
+ ird->router_autocfg = IPV6_RTR_AUTOCFG_ON;
|
|
+
|
|
+ /* Decode the addresses based on the control flags */
|
|
+ /* For DHCP, ignore the IPv6 addr in the iface */
|
|
+ if (ird->ipv6_autocfg == IPV6_AUTOCFG_DHCPV6)
|
|
+ memcpy(&ird->ipv6_addr, all_zeroes_addr6,
|
|
+ sizeof(struct in6_addr));
|
|
+ /* Subnet mask priority: CIDR, then rec */
|
|
+ if (!ird->ipv6_subnet_mask.s6_addr)
|
|
+ inet_pton(AF_INET, rec->subnet_mask,
|
|
+ &ird->ipv6_subnet_mask);
|
|
+
|
|
+ /* For LL on, ignore the IPv6 addr in the iface */
|
|
+ if (ird->linklocal_autocfg == IPV6_LL_AUTOCFG_OFF) {
|
|
+ if (strlen(rec->ipv6_linklocal) > NI_MAXHOST)
|
|
+ strncpy(ipaddr_str, rec->ipv6_linklocal,
|
|
+ NI_MAXHOST);
|
|
+ else
|
|
+ strcpy(ipaddr_str, rec->ipv6_linklocal);
|
|
+ inet_pton(AF_INET6, ipaddr_str,
|
|
+ &ird->ipv6_linklocal);
|
|
+ }
|
|
+
|
|
+ /* For RTR on, ignore the IPv6 addr in the iface */
|
|
+ if (ird->router_autocfg == IPV6_RTR_AUTOCFG_OFF) {
|
|
+ if (strlen(rec->ipv6_router) > NI_MAXHOST)
|
|
+ strncpy(ipaddr_str, rec->ipv6_router,
|
|
+ NI_MAXHOST);
|
|
+ else
|
|
+ strcpy(ipaddr_str, rec->ipv6_router);
|
|
+ inet_pton(AF_INET6, ipaddr_str,
|
|
+ &ird->ipv6_router);
|
|
+ }
|
|
+ } else {
|
|
+ /* Subnet mask priority: CIDR, rec, default */
|
|
+ if (!ird->ipv4_subnet_mask.s_addr)
|
|
+ inet_pton(AF_INET, rec->subnet_mask,
|
|
+ &ird->ipv4_subnet_mask);
|
|
+ if (!ird->ipv4_subnet_mask.s_addr)
|
|
+ ird->ipv4_subnet_mask.s_addr =
|
|
+ calculate_default_netmask(
|
|
+ ird->ipv4_addr.s_addr);
|
|
+
|
|
+ if (strlen(rec->gateway) > NI_MAXHOST)
|
|
+ strncpy(ipaddr_str, rec->gateway, NI_MAXHOST);
|
|
+ else
|
|
+ strcpy(ipaddr_str, rec->gateway);
|
|
+ inet_pton(AF_INET, ipaddr_str, &ird->ipv4_gateway);
|
|
+ }
|
|
+ } else {
|
|
+ ird->ipv6_autocfg = IPV6_AUTOCFG_NOTUSED;
|
|
+ ird->linklocal_autocfg = IPV6_LL_AUTOCFG_NOTUSED;
|
|
+ ird->router_autocfg = IPV6_RTR_AUTOCFG_NOTUSED;
|
|
+ }
|
|
+ return rc;
|
|
+}
|
|
+
|
|
static int parse_iface(void *arg)
|
|
{
|
|
- int rc;
|
|
+ int rc, i;
|
|
nic_t *nic = NULL;
|
|
- nic_interface_t *nic_iface, *vlan_iface, *base_nic_iface;
|
|
+ nic_interface_t *nic_iface;
|
|
char *transport_name;
|
|
size_t transport_name_size;
|
|
nic_lib_handle_t *handle;
|
|
iscsid_uip_broadcast_t *data;
|
|
- short int vlan;
|
|
char ipv6_buf_str[INET6_ADDRSTRLEN];
|
|
int request_type = 0;
|
|
- struct in_addr netmask;
|
|
- int i, prefix_len = 64;
|
|
- struct ip_addr_mask ipam;
|
|
struct iface_rec *rec;
|
|
void *res;
|
|
+ struct iface_rec_decode ird;
|
|
+ struct in_addr src_match, dst_match;
|
|
|
|
data = (iscsid_uip_broadcast_t *) arg;
|
|
|
|
rec = &data->u.iface_rec.rec;
|
|
LOG_INFO(PFX "Received request for '%s' to set IP address: '%s' "
|
|
- "VLAN: '%d'", rec->netdev, rec->ipaddress, rec->vlan_id);
|
|
-
|
|
- vlan = rec->vlan_id;
|
|
- if (vlan && valid_vlan(vlan) == 0) {
|
|
- LOG_ERR(PFX "Invalid VLAN tag: %d", rec->vlan_id);
|
|
+ "VLAN: '%d'",
|
|
+ rec->netdev,
|
|
+ rec->ipaddress,
|
|
+ rec->vlan_id);
|
|
+
|
|
+ rc = decode_iface(&ird, rec);
|
|
+ if (ird.vlan_id && valid_vlan(ird.vlan_id) == 0) {
|
|
+ LOG_ERR(PFX "Invalid VLAN tag: %d", ird.vlan_id);
|
|
rc = -EIO;
|
|
goto early_exit;
|
|
}
|
|
-
|
|
- /* Detect for CIDR notation and strip off the netmask if present */
|
|
- rc = decode_cidr(rec->ipaddress, &ipam, &prefix_len);
|
|
- if (rc && !ipam.ip_type) {
|
|
- LOG_ERR(PFX "decode_cidr: rc=%d, ipam.ip_type=%d",
|
|
- rc, ipam.ip_type)
|
|
- goto early_exit;
|
|
- }
|
|
- if (ipam.ip_type == AF_INET6)
|
|
- inet_ntop(AF_INET6, &ipam.addr6, ipv6_buf_str,
|
|
- sizeof(ipv6_buf_str));
|
|
+ if (rc && !ird.ip_type) {
|
|
+ LOG_ERR(PFX "iface err: rc=%d, ip_type=%d", rc, ird.ip_type);
|
|
+ goto early_exit;
|
|
+ }
|
|
|
|
for (i = 0; i < 10; i++) {
|
|
struct timespec sleep_req, sleep_rem;
|
|
@@ -258,11 +369,13 @@ static int parse_iface(void *arg)
|
|
}
|
|
|
|
if (i >= 10) {
|
|
- LOG_WARN(PFX "Could not aquire nic_list_mutex lock");
|
|
+ LOG_WARN(PFX "Could not acquire nic_list_mutex lock");
|
|
rc = -EIO;
|
|
goto early_exit;
|
|
}
|
|
|
|
+ /* nic_list_mutex locked */
|
|
+
|
|
/* Check if we can find the NIC device using the netdev
|
|
* name */
|
|
rc = from_netdev_name_find_nic(rec->netdev, &nic);
|
|
@@ -298,21 +411,22 @@ static int parse_iface(void *arg)
|
|
rec->netdev);
|
|
}
|
|
|
|
+ pthread_mutex_lock(&nic->nic_mutex);
|
|
if (nic->flags & NIC_GOING_DOWN) {
|
|
+ pthread_mutex_unlock(&nic->nic_mutex);
|
|
rc = -EIO;
|
|
LOG_INFO(PFX "nic->flags GOING DOWN");
|
|
goto done;
|
|
}
|
|
|
|
- /* If we retry too many times allow iscsid to to timeout */
|
|
+ /* If we retry too many times allow iscsid to timeout */
|
|
if (nic->pending_count > 1000) {
|
|
- LOG_WARN(PFX "%s: pending count excceded 1000", nic->log_name);
|
|
-
|
|
- pthread_mutex_lock(&nic->nic_mutex);
|
|
nic->pending_count = 0;
|
|
nic->flags &= ~NIC_ENABLED_PENDING;
|
|
pthread_mutex_unlock(&nic->nic_mutex);
|
|
|
|
+ LOG_WARN(PFX "%s: pending count exceeded 1000", nic->log_name);
|
|
+
|
|
rc = 0;
|
|
goto done;
|
|
}
|
|
@@ -320,18 +434,19 @@ static int parse_iface(void *arg)
|
|
if (nic->flags & NIC_ENABLED_PENDING) {
|
|
struct timespec sleep_req, sleep_rem;
|
|
|
|
+ nic->pending_count++;
|
|
+ pthread_mutex_unlock(&nic->nic_mutex);
|
|
+
|
|
sleep_req.tv_sec = 0;
|
|
sleep_req.tv_nsec = 100000;
|
|
nanosleep(&sleep_req, &sleep_rem);
|
|
|
|
- pthread_mutex_lock(&nic->nic_mutex);
|
|
- nic->pending_count++;
|
|
- pthread_mutex_unlock(&nic->nic_mutex);
|
|
-
|
|
LOG_INFO(PFX "%s: enabled pending", nic->log_name);
|
|
+
|
|
rc = -EAGAIN;
|
|
goto done;
|
|
}
|
|
+ pthread_mutex_unlock(&nic->nic_mutex);
|
|
|
|
prepare_library(nic);
|
|
|
|
@@ -359,66 +474,9 @@ static int parse_iface(void *arg)
|
|
LOG_INFO(PFX "%s library set using transport_name %s",
|
|
nic->log_name, transport_name);
|
|
|
|
- /* 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 interface with "
|
|
- "ip_type: 0x%x creating it",
|
|
- nic->log_name, ipam.ip_type);
|
|
-
|
|
- /* Create the nic interface */
|
|
- nic_iface = nic_iface_init();
|
|
-
|
|
- if (nic_iface == NULL) {
|
|
- LOG_ERR(PFX "Couldn't allocate nic_iface", nic_iface);
|
|
- goto done;
|
|
- }
|
|
-
|
|
- nic_iface->protocol = ipam.ip_type;
|
|
- nic_add_nic_iface(nic, nic_iface);
|
|
-
|
|
- persist_all_nic_iface(nic);
|
|
-
|
|
- LOG_INFO(PFX "%s: created network interface", nic->log_name);
|
|
- } else {
|
|
- LOG_INFO(PFX "%s: using existing network interface",
|
|
- 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,
|
|
+ if (ird.ip_type == AF_INET) {
|
|
+ if (memcmp(&ird.ipv4_addr,
|
|
all_zeroes_addr4, sizeof(uip_ip4addr_t)) == 0) {
|
|
LOG_INFO(PFX "%s: requesting configuration using DHCP",
|
|
nic->log_name);
|
|
@@ -428,51 +486,161 @@ static int parse_iface(void *arg)
|
|
"static IP address", nic->log_name);
|
|
request_type = IPV4_CONFIG_STATIC;
|
|
}
|
|
- } else if (ipam.ip_type == AF_INET6) {
|
|
- if (memcmp(&ipam.addr6,
|
|
- all_zeroes_addr6, sizeof(uip_ip6addr_t)) == 0) {
|
|
- LOG_INFO(PFX
|
|
- "%s: requesting configuration using DHCPv6",
|
|
- nic->log_name);
|
|
+ } else if (ird.ip_type == AF_INET6) {
|
|
+ /* For the new 872_22, check ipv6_autocfg for DHCPv6 instead */
|
|
+ switch (ird.ipv6_autocfg) {
|
|
+ case IPV6_AUTOCFG_DHCPV6:
|
|
request_type = IPV6_CONFIG_DHCP;
|
|
- } else {
|
|
- LOG_INFO(PFX "%s: request configuration using static "
|
|
- "IPv6 address: '%s'",
|
|
- nic->log_name, ipv6_buf_str);
|
|
+ break;
|
|
+ case IPV6_AUTOCFG_ND:
|
|
request_type = IPV6_CONFIG_STATIC;
|
|
+ break;
|
|
+ case IPV6_AUTOCFG_NOTSPEC:
|
|
+ /* Treat NOTSPEC the same as NOTUSED for now */
|
|
+ case IPV6_AUTOCFG_NOTUSED:
|
|
+ /* For 871 */
|
|
+ default:
|
|
+ /* Just the IP address to determine */
|
|
+ if (memcmp(&ird.ipv6_addr,
|
|
+ all_zeroes_addr6,
|
|
+ sizeof(struct in6_addr)) == 0)
|
|
+ request_type = IPV6_CONFIG_DHCP;
|
|
+ else
|
|
+ request_type = IPV6_CONFIG_STATIC;
|
|
}
|
|
} else {
|
|
LOG_ERR(PFX "%s: unknown ip_type to configure: 0x%x",
|
|
- nic->log_name, ipam.ip_type);
|
|
+ nic->log_name, ird.ip_type);
|
|
|
|
rc = -EIO;
|
|
goto done;
|
|
}
|
|
|
|
+ pthread_mutex_lock(&nic->nic_mutex);
|
|
+
|
|
+ nic_iface = nic_find_nic_iface(nic, ird.ip_type, ird.vlan_id,
|
|
+ ird.iface_num, request_type);
|
|
+
|
|
+ if (nic->flags & NIC_PATHREQ_WAIT) {
|
|
+ if (!nic_iface ||
|
|
+ !(nic_iface->flags & NIC_IFACE_PATHREQ_WAIT)) {
|
|
+ int pathreq_wait;
|
|
+
|
|
+ if (nic_iface &&
|
|
+ (nic_iface->flags & NIC_IFACE_PATHREQ_WAIT2))
|
|
+ pathreq_wait = 12;
|
|
+ else
|
|
+ pathreq_wait = 10;
|
|
+
|
|
+ if (nic->pathreq_pending_count < pathreq_wait) {
|
|
+ struct timespec sleep_req, sleep_rem;
|
|
+
|
|
+ pthread_mutex_unlock(&nic->nic_mutex);
|
|
+
|
|
+ nic->pathreq_pending_count++;
|
|
+ sleep_req.tv_sec = 0;
|
|
+ sleep_req.tv_nsec = 100000;
|
|
+ nanosleep(&sleep_req, &sleep_rem);
|
|
+ /* Somebody else is waiting for PATH_REQ */
|
|
+ LOG_INFO(PFX "%s: path req pending cnt=%d",
|
|
+ nic->log_name,
|
|
+ nic->pathreq_pending_count);
|
|
+ rc = -EAGAIN;
|
|
+ goto done;
|
|
+ } else {
|
|
+ nic->pathreq_pending_count = 0;
|
|
+ LOG_DEBUG(PFX "%s: path req pending cnt "
|
|
+ "exceeded!", nic->log_name);
|
|
+ /* Allow to fall thru */
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ nic->flags |= NIC_PATHREQ_WAIT;
|
|
+
|
|
+ /* Create the network interface if it doesn't exist */
|
|
+ if (nic_iface == NULL) {
|
|
+ LOG_DEBUG(PFX "%s couldn't find interface with "
|
|
+ "ip_type: 0x%x creating it",
|
|
+ nic->log_name, ird.ip_type);
|
|
+ nic_iface = nic_iface_init();
|
|
+
|
|
+ if (nic_iface == NULL) {
|
|
+ pthread_mutex_unlock(&nic->nic_mutex);
|
|
+ LOG_ERR(PFX "%s Couldn't allocate "
|
|
+ "interface with ip_type: 0x%x",
|
|
+ nic->log_name, ird.ip_type);
|
|
+ goto done;
|
|
+ }
|
|
+ nic_iface->protocol = ird.ip_type;
|
|
+ nic_iface->vlan_id = ird.vlan_id;
|
|
+ nic_iface->vlan_priority = ird.vlan_priority;
|
|
+ if (ird.mtu >= MIN_MTU_SUPPORT && ird.mtu <= MAX_MTU_SUPPORT)
|
|
+ nic_iface->mtu = ird.mtu;
|
|
+ nic_iface->iface_num = ird.iface_num;
|
|
+ nic_iface->request_type = request_type;
|
|
+ nic_add_nic_iface(nic, nic_iface);
|
|
+
|
|
+ persist_all_nic_iface(nic);
|
|
+
|
|
+ LOG_INFO(PFX "%s: created network interface",
|
|
+ nic->log_name);
|
|
+ } else {
|
|
+ /* Move the nic_iface to the front */
|
|
+ set_nic_iface(nic, nic_iface);
|
|
+ LOG_INFO(PFX "%s: using existing network interface",
|
|
+ nic->log_name);
|
|
+ }
|
|
+
|
|
+ nic_iface->flags |= NIC_IFACE_PATHREQ_WAIT1;
|
|
+ if (nic->nl_process_thread == INVALID_THREAD) {
|
|
+ rc = pthread_create(&nic->nl_process_thread, NULL,
|
|
+ nl_process_handle_thread, nic);
|
|
+ if (rc != 0) {
|
|
+ LOG_ERR(PFX "%s: Could not create NIC NL "
|
|
+ "processing thread [%s]", nic->log_name,
|
|
+ strerror(rc));
|
|
+ nic->nl_process_thread = INVALID_THREAD;
|
|
+ /* Reset both WAIT flags */
|
|
+ nic_iface->flags &= ~NIC_IFACE_PATHREQ_WAIT;
|
|
+ nic->flags &= ~NIC_PATHREQ_WAIT;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ pthread_mutex_unlock(&nic->nic_mutex);
|
|
+
|
|
if (nic_iface->ustack.ip_config == request_type) {
|
|
+ /* Same request_type, check for STATIC address change */
|
|
if (request_type == IPV4_CONFIG_STATIC) {
|
|
- if (memcmp(nic_iface->ustack.hostaddr, &ipam.addr4,
|
|
+ if (memcmp(nic_iface->ustack.hostaddr, &ird.ipv4_addr,
|
|
sizeof(struct in_addr)))
|
|
- goto diff;
|
|
+ goto reacquire;
|
|
} else if (request_type == IPV6_CONFIG_STATIC) {
|
|
- if (memcmp(nic_iface->ustack.hostaddr6, &ipam.addr6,
|
|
+ if (memcmp(nic_iface->ustack.hostaddr6, &ird.ipv6_addr,
|
|
sizeof(struct in6_addr)))
|
|
- goto diff;
|
|
+ goto reacquire;
|
|
+ else
|
|
+ inet_ntop(AF_INET6, &ird.ipv6_addr,
|
|
+ ipv6_buf_str,
|
|
+ sizeof(ipv6_buf_str));
|
|
}
|
|
LOG_INFO(PFX "%s: IP configuration didn't change using 0x%x",
|
|
nic->log_name, nic_iface->ustack.ip_config);
|
|
- goto enable_nic;
|
|
-diff:
|
|
- /* Disable the NIC */
|
|
- nic_disable(nic, 0);
|
|
- } else {
|
|
- if (request_type == IPV4_CONFIG_DHCP
|
|
- || request_type == IPV6_CONFIG_DHCP)
|
|
- nic->flags |= NIC_RESET_UIP;
|
|
+ /* No need to acquire the IP address */
|
|
+ inet_ntop(AF_INET6, &ird.ipv6_addr, ipv6_buf_str,
|
|
+ sizeof(ipv6_buf_str));
|
|
|
|
- /* Disable the NIC */
|
|
- nic_disable(nic, 0);
|
|
+ goto enable_nic;
|
|
}
|
|
+reacquire:
|
|
+ /* Config needs to re-acquire for this nic_iface */
|
|
+ pthread_mutex_lock(&nic->nic_mutex);
|
|
+ nic_iface->flags |= NIC_IFACE_ACQUIRE;
|
|
+ pthread_mutex_unlock(&nic->nic_mutex);
|
|
+
|
|
+ /* Disable the nic loop from further processing, upon returned,
|
|
+ the nic_iface should be cleared */
|
|
+ nic_disable(nic, 0);
|
|
|
|
/* Check to see if this is using DHCP or if this is
|
|
* a static IPv4 address. This is done by checking
|
|
@@ -485,97 +653,96 @@ diff:
|
|
memset(nic_iface->ustack.hostaddr, 0, sizeof(struct in_addr));
|
|
LOG_INFO(PFX "%s: configuring using DHCP", nic->log_name);
|
|
nic_iface->ustack.ip_config = IPV4_CONFIG_DHCP;
|
|
-
|
|
break;
|
|
+
|
|
case IPV4_CONFIG_STATIC:
|
|
- memcpy(nic_iface->ustack.hostaddr, &ipam.addr4,
|
|
+ memcpy(nic_iface->ustack.hostaddr, &ird.ipv4_addr,
|
|
sizeof(struct in_addr));
|
|
LOG_INFO(PFX "%s: configuring using static IP "
|
|
"IPv4 address :%s ",
|
|
- nic->log_name, inet_ntoa(ipam.addr4));
|
|
- netmask.s_addr = ipam.nm4.s_addr;
|
|
- if (!netmask.s_addr)
|
|
- netmask.s_addr =
|
|
- calculate_default_netmask(ipam.addr4.s_addr);
|
|
- memcpy(nic_iface->ustack.netmask,
|
|
- &netmask, sizeof(netmask.s_addr));
|
|
- LOG_INFO(PFX " netmask :%s", inet_ntoa(netmask));
|
|
-
|
|
+ nic->log_name, inet_ntoa(ird.ipv4_addr));
|
|
+
|
|
+ if (ird.ipv4_subnet_mask.s_addr)
|
|
+ memcpy(nic_iface->ustack.netmask,
|
|
+ &ird.ipv4_subnet_mask, sizeof(struct in_addr));
|
|
+ LOG_INFO(PFX " netmask: %s", inet_ntoa(ird.ipv4_subnet_mask));
|
|
+
|
|
+ /* Default route */
|
|
+ if (ird.ipv4_gateway.s_addr) {
|
|
+ /* Check for validity */
|
|
+ src_match.s_addr = ird.ipv4_addr.s_addr &
|
|
+ ird.ipv4_subnet_mask.s_addr;
|
|
+ dst_match.s_addr = ird.ipv4_gateway.s_addr &
|
|
+ ird.ipv4_subnet_mask.s_addr;
|
|
+ if (src_match.s_addr == dst_match.s_addr)
|
|
+ memcpy(nic_iface->ustack.default_route_addr,
|
|
+ &ird.ipv4_gateway,
|
|
+ sizeof(struct in_addr));
|
|
+ }
|
|
nic_iface->ustack.ip_config = IPV4_CONFIG_STATIC;
|
|
break;
|
|
+
|
|
case IPV6_CONFIG_DHCP:
|
|
memset(nic_iface->ustack.hostaddr6, 0,
|
|
sizeof(struct in6_addr));
|
|
- nic_iface->ustack.prefix_len = prefix_len;
|
|
- if (ipam.nm6.s6_addr[0] | ipam.nm6.s6_addr[1] |
|
|
- ipam.nm6.s6_addr[2] | ipam.nm6.s6_addr[3] |
|
|
- ipam.nm6.s6_addr[4] | ipam.nm6.s6_addr[5] |
|
|
- ipam.nm6.s6_addr[6] | ipam.nm6.s6_addr[7])
|
|
+ nic_iface->ustack.prefix_len = ird.prefix_len;
|
|
+ nic_iface->ustack.ipv6_autocfg = ird.ipv6_autocfg;
|
|
+ nic_iface->ustack.linklocal_autocfg = ird.linklocal_autocfg;
|
|
+ nic_iface->ustack.router_autocfg = ird.router_autocfg;
|
|
+
|
|
+ if (memcmp(&ird.ipv6_subnet_mask, all_zeroes_addr6,
|
|
+ sizeof(struct in6_addr)))
|
|
memcpy(nic_iface->ustack.netmask6,
|
|
- &ipam.nm6, sizeof(struct in6_addr));
|
|
+ &ird.ipv6_subnet_mask, sizeof(struct in6_addr));
|
|
+ if (ird.linklocal_autocfg == IPV6_LL_AUTOCFG_OFF)
|
|
+ memcpy(nic_iface->ustack.linklocal6,
|
|
+ &ird.ipv6_linklocal, sizeof(struct in6_addr));
|
|
+ if (ird.router_autocfg == IPV6_RTR_AUTOCFG_OFF)
|
|
+ memcpy(nic_iface->ustack.default_route_addr6,
|
|
+ &ird.ipv6_router, sizeof(struct in6_addr));
|
|
+ inet_ntop(AF_INET6, &ird.ipv6_addr, ipv6_buf_str,
|
|
+ sizeof(ipv6_buf_str));
|
|
LOG_INFO(PFX "%s: configuring using DHCPv6",
|
|
nic->log_name);
|
|
nic_iface->ustack.ip_config = IPV6_CONFIG_DHCP;
|
|
break;
|
|
+
|
|
case IPV6_CONFIG_STATIC:
|
|
- memcpy(nic_iface->ustack.hostaddr6, &ipam.addr6,
|
|
+ memcpy(nic_iface->ustack.hostaddr6, &ird.ipv6_addr,
|
|
sizeof(struct in6_addr));
|
|
+ nic_iface->ustack.prefix_len = ird.prefix_len;
|
|
+ nic_iface->ustack.ipv6_autocfg = ird.ipv6_autocfg;
|
|
+ nic_iface->ustack.linklocal_autocfg = ird.linklocal_autocfg;
|
|
+ nic_iface->ustack.router_autocfg = ird.router_autocfg;
|
|
|
|
- nic_iface->ustack.prefix_len = prefix_len;
|
|
- if (ipam.nm6.s6_addr[0] | ipam.nm6.s6_addr[1] |
|
|
- ipam.nm6.s6_addr[2] | ipam.nm6.s6_addr[3] |
|
|
- ipam.nm6.s6_addr[4] | ipam.nm6.s6_addr[5] |
|
|
- ipam.nm6.s6_addr[6] | ipam.nm6.s6_addr[7])
|
|
+ if (memcmp(&ird.ipv6_subnet_mask, all_zeroes_addr6,
|
|
+ sizeof(struct in6_addr)))
|
|
memcpy(nic_iface->ustack.netmask6,
|
|
- &ipam.nm6, sizeof(struct in6_addr));
|
|
-
|
|
+ &ird.ipv6_subnet_mask, sizeof(struct in6_addr));
|
|
+ if (ird.linklocal_autocfg == IPV6_LL_AUTOCFG_OFF)
|
|
+ memcpy(nic_iface->ustack.linklocal6,
|
|
+ &ird.ipv6_linklocal, sizeof(struct in6_addr));
|
|
+ if (ird.router_autocfg == IPV6_RTR_AUTOCFG_OFF)
|
|
+ memcpy(nic_iface->ustack.default_route_addr6,
|
|
+ &ird.ipv6_router, sizeof(struct in6_addr));
|
|
+
|
|
+ inet_ntop(AF_INET6, &ird.ipv6_addr, ipv6_buf_str,
|
|
+ sizeof(ipv6_buf_str));
|
|
LOG_INFO(PFX "%s: configuring using static IP "
|
|
"IPv6 address: '%s'", nic->log_name, ipv6_buf_str);
|
|
|
|
nic_iface->ustack.ip_config = IPV6_CONFIG_STATIC;
|
|
break;
|
|
+
|
|
default:
|
|
LOG_INFO(PFX "%s: Unknown request type: 0x%x",
|
|
nic->log_name, request_type);
|
|
|
|
}
|
|
|
|
- /* Configuration changed, do VLAN WA */
|
|
- 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(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.hostaddr6,
|
|
- nic_iface->ustack.hostaddr6,
|
|
- sizeof(nic_iface->ustack.hostaddr6));
|
|
- memcpy(vlan_iface->ustack.netmask6,
|
|
- nic_iface->ustack.netmask6,
|
|
- sizeof(nic_iface->ustack.netmask6));
|
|
- }
|
|
- vlan_iface = vlan_iface->vlan_next;
|
|
- }
|
|
-
|
|
enable_nic:
|
|
- if (nic->state & NIC_STOPPED) {
|
|
- pthread_mutex_lock(&nic->nic_mutex);
|
|
- if (nic->flags & NIC_ENABLED_PENDING) {
|
|
- /* Still waiting */
|
|
- pthread_mutex_unlock(&nic->nic_mutex);
|
|
- rc = 0;
|
|
- goto enable_out;
|
|
- }
|
|
- nic->flags |= NIC_ENABLED_PENDING;
|
|
- pthread_mutex_unlock(&nic->nic_mutex);
|
|
-
|
|
+ switch (nic->state) {
|
|
+ case NIC_STOPPED:
|
|
/* This thread will be thrown away when completed */
|
|
if (nic->enable_thread != INVALID_THREAD) {
|
|
rc = pthread_join(nic->enable_thread, &res);
|
|
@@ -592,19 +759,27 @@ enable_nic:
|
|
nic->log_name);
|
|
eagain:
|
|
rc = -EAGAIN;
|
|
- } else {
|
|
+ break;
|
|
+
|
|
+ case NIC_RUNNING:
|
|
LOG_INFO(PFX "%s: NIC already enabled "
|
|
"flags: 0x%x state: 0x%x\n",
|
|
nic->log_name, nic->flags, nic->state);
|
|
rc = 0;
|
|
+ break;
|
|
+ default:
|
|
+ LOG_INFO(PFX "%s: NIC enable still in progress "
|
|
+ "flags: 0x%x state: 0x%x\n",
|
|
+ nic->log_name, nic->flags, nic->state);
|
|
+ rc = -EAGAIN;
|
|
}
|
|
-enable_out:
|
|
+
|
|
LOG_INFO(PFX "ISCSID_UIP_IPC_GET_IFACE: command: %x "
|
|
"name: %s, netdev: %s ipaddr: %s vlan: %d transport_name:%s",
|
|
data->header.command, rec->name, rec->netdev,
|
|
- (ipam.ip_type == AF_INET) ? inet_ntoa(ipam.addr4) :
|
|
+ (ird.ip_type == AF_INET) ? inet_ntoa(ird.ipv4_addr) :
|
|
ipv6_buf_str,
|
|
- vlan, rec->transport_name);
|
|
+ ird.vlan_id, rec->transport_name);
|
|
|
|
done:
|
|
pthread_mutex_unlock(&nic_list_mutex);
|
|
@@ -638,12 +813,13 @@ int process_iscsid_broadcast(int s2)
|
|
data = (iscsid_uip_broadcast_t *) calloc(1, sizeof(*data));
|
|
if (data == NULL) {
|
|
LOG_ERR(PFX "Couldn't allocate memory for iface data");
|
|
- return -ENOMEM;
|
|
+ rc = -ENOMEM;
|
|
+ goto error;
|
|
}
|
|
memset(data, 0, sizeof(*data));
|
|
|
|
size = fread(data, sizeof(iscsid_uip_broadcast_header_t), 1, fd);
|
|
- if (size == -1) {
|
|
+ if (!size) {
|
|
LOG_ERR(PFX "Could not read request: %d(%s)",
|
|
errno, strerror(errno));
|
|
rc = ferror(fd);
|
|
@@ -657,7 +833,7 @@ int process_iscsid_broadcast(int s2)
|
|
cmd, payload_len);
|
|
|
|
size = fread(&data->u.iface_rec, payload_len, 1, fd);
|
|
- if (size == -1) {
|
|
+ if (!size) {
|
|
LOG_ERR(PFX "Could not read data: %d(%s)",
|
|
errno, strerror(errno));
|
|
goto error;
|
|
diff --git a/iscsiuio/src/unix/libs/bnx2.c b/iscsiuio/src/unix/libs/bnx2.c
|
|
index 112d570..a8300c2 100644
|
|
--- a/iscsiuio/src/unix/libs/bnx2.c
|
|
+++ b/iscsiuio/src/unix/libs/bnx2.c
|
|
@@ -295,7 +295,7 @@ static int bnx2_uio_verify(nic_t * nic)
|
|
|
|
LOG_INFO(PFX "%s: Verified is a cnic_uio device", nic->log_name);
|
|
|
|
- error:
|
|
+error:
|
|
return rc;
|
|
}
|
|
|
|
@@ -395,7 +395,7 @@ static void bnx2_free(nic_t *nic)
|
|
/**
|
|
* bnx2_alloc() - Used to allocate a bnx2 structure
|
|
*/
|
|
-static bnx2_t *bnx2_alloc(nic_t * nic)
|
|
+static bnx2_t *bnx2_alloc(nic_t *nic)
|
|
{
|
|
bnx2_t *bp = malloc(sizeof(*bp));
|
|
if (bp == NULL) {
|
|
@@ -468,12 +468,14 @@ static int bnx2_open(nic_t * nic)
|
|
manually_trigger_uio_event(nic, nic->uio_minor);
|
|
|
|
/* udev might not have created the file yet */
|
|
+ pthread_mutex_unlock(&nic->nic_mutex);
|
|
sleep(1);
|
|
+ pthread_mutex_lock(&nic->nic_mutex);
|
|
}
|
|
}
|
|
if (fstat(nic->fd, &uio_stat) < 0) {
|
|
LOG_ERR(PFX "%s: Could not fstat device", nic->log_name);
|
|
- rc = -ENODEV;
|
|
+ errno = -ENODEV;
|
|
goto error_alloc_rx_ring;
|
|
}
|
|
nic->uio_minor = minor(uio_stat.st_rdev);
|
|
@@ -483,7 +485,7 @@ static int bnx2_open(nic_t * nic)
|
|
if (bp->bar0_fd < 0) {
|
|
LOG_ERR(PFX "%s: Could not open %s", nic->log_name,
|
|
sysfs_resc_path);
|
|
- rc = -ENODEV;
|
|
+ errno = -ENODEV;
|
|
goto error_alloc_rx_ring;
|
|
}
|
|
|
|
@@ -506,6 +508,7 @@ static int bnx2_open(nic_t * nic)
|
|
if (bp->rx_ring == NULL) {
|
|
LOG_ERR(PFX "%s: Could not allocate space for rx_ring",
|
|
nic->log_name);
|
|
+ errno = -ENOMEM;
|
|
goto error_alloc_rx_ring;
|
|
}
|
|
mlock(bp->rx_ring, sizeof(struct l2_fhdr *) * bp->rx_ring_size);
|
|
@@ -515,6 +518,7 @@ static int bnx2_open(nic_t * nic)
|
|
if (bp->rx_pkt_ring == NULL) {
|
|
LOG_ERR(PFX "%s: Could not allocate space for rx_pkt_ring",
|
|
nic->log_name);
|
|
+ errno = -ENOMEM;
|
|
goto error_alloc_rx_pkt_ring;
|
|
}
|
|
mlock(bp->rx_pkt_ring, sizeof(void *) * bp->rx_ring_size);
|
|
@@ -677,9 +681,10 @@ static int bnx2_open(nic_t * nic)
|
|
bnx2_wr32(bp, BNX2_RPM_SORT_USER2, val | BNX2_RPM_SORT_USER2_ENA);
|
|
|
|
rc = enable_multicast(nic);
|
|
- if (rc != 0)
|
|
+ if (rc != 0) {
|
|
+ errno = rc;
|
|
goto error_bufs;
|
|
-
|
|
+ }
|
|
msync(bp->reg, 0x12800, MS_SYNC);
|
|
LOG_INFO("%s: bnx2 uio initialized", nic->log_name);
|
|
|
|
@@ -707,6 +712,10 @@ error_alloc_rx_pkt_ring:
|
|
bp->rx_ring = NULL;
|
|
|
|
error_alloc_rx_ring:
|
|
+ if (nic->fd != INVALID_FD) {
|
|
+ close(nic->fd);
|
|
+ nic->fd = INVALID_FD;
|
|
+ }
|
|
bnx2_free(nic);
|
|
|
|
return errno;
|
|
@@ -878,8 +887,8 @@ void bnx2_start_xmit(nic_t * nic, size_t len, u16_t vlan_id)
|
|
rxbd = (struct rx_bd *)(((__u8 *) bp->tx_ring) + getpagesize());
|
|
|
|
if ((rxbd->rx_bd_haddr_hi == 0) && (rxbd->rx_bd_haddr_lo == 0)) {
|
|
- LOG_DEBUG(PFX "%s: trying to transmit when device is closed",
|
|
- nic->log_name);
|
|
+ LOG_PACKET(PFX "%s: trying to transmit when device is closed",
|
|
+ nic->log_name);
|
|
pthread_mutex_unlock(&nic->xmit_mutex);
|
|
return;
|
|
}
|
|
@@ -905,8 +914,8 @@ void bnx2_start_xmit(nic_t * nic, size_t len, u16_t vlan_id)
|
|
bnx2_reg_sync(bp, bp->tx_bidx_io, sizeof(__u16));
|
|
bnx2_reg_sync(bp, bp->tx_bseq_io, sizeof(__u32));
|
|
|
|
- LOG_DEBUG(PFX "%s: sent %d bytes using dev->tx_prod: %d",
|
|
- nic->log_name, len, bp->tx_prod);
|
|
+ LOG_PACKET(PFX "%s: sent %d bytes using dev->tx_prod: %d",
|
|
+ nic->log_name, len, bp->tx_prod);
|
|
}
|
|
|
|
/**
|
|
@@ -917,8 +926,8 @@ void bnx2_start_xmit(nic_t * nic, size_t len, u16_t vlan_id)
|
|
*/
|
|
int bnx2_write(nic_t * nic, nic_interface_t * nic_iface, packet_t * pkt)
|
|
{
|
|
- bnx2_t *bp = (bnx2_t *) nic->priv;
|
|
- struct uip_stack *uip = &nic_iface->ustack;
|
|
+ bnx2_t *bp;
|
|
+ struct uip_stack *uip;
|
|
|
|
/* Sanity Check: validate the parameters */
|
|
if (nic == NULL || nic_iface == NULL || pkt == NULL) {
|
|
@@ -927,6 +936,8 @@ int bnx2_write(nic_t * nic, nic_interface_t * nic_iface, packet_t * pkt)
|
|
" pkt == 0x%x", nic, nic_iface, pkt);
|
|
return -EINVAL;
|
|
}
|
|
+ bp = (bnx2_t *)nic->priv;
|
|
+ uip = &nic_iface->ustack;
|
|
|
|
if (pkt->buf_size == 0) {
|
|
LOG_ERR(PFX "%s: Trying to transmitted 0 sized packet",
|
|
@@ -935,22 +946,24 @@ int bnx2_write(nic_t * nic, nic_interface_t * nic_iface, packet_t * pkt)
|
|
}
|
|
|
|
if (pthread_mutex_trylock(&nic->xmit_mutex) != 0) {
|
|
- LOG_DEBUG(PFX "%s: Dropped previous transmitted packet",
|
|
- nic->log_name);
|
|
+ LOG_PACKET(PFX "%s: Dropped previous transmitted packet",
|
|
+ nic->log_name);
|
|
return -EINVAL;
|
|
}
|
|
|
|
bnx2_prepare_xmit_packet(nic, nic_iface, pkt);
|
|
- bnx2_start_xmit(nic, pkt->buf_size, nic_iface->vlan_id);
|
|
+ bnx2_start_xmit(nic, pkt->buf_size,
|
|
+ (nic_iface->vlan_priority << 12) |
|
|
+ nic_iface->vlan_id);
|
|
|
|
/* bump the bnx2 dev send statistics */
|
|
nic->stats.tx.packets++;
|
|
nic->stats.tx.bytes += uip->uip_len;
|
|
|
|
- LOG_DEBUG(PFX "%s: transmitted %d bytes "
|
|
- "dev->tx_cons: %d, dev->tx_prod: %d, dev->tx_bseq:%d",
|
|
- nic->log_name, pkt->buf_size,
|
|
- bp->tx_cons, bp->tx_prod, bp->tx_bseq);
|
|
+ LOG_PACKET(PFX "%s: transmitted %d bytes "
|
|
+ "dev->tx_cons: %d, dev->tx_prod: %d, dev->tx_bseq:%d",
|
|
+ nic->log_name, pkt->buf_size,
|
|
+ bp->tx_cons, bp->tx_prod, bp->tx_bseq);
|
|
|
|
return 0;
|
|
}
|
|
@@ -963,7 +976,7 @@ int bnx2_write(nic_t * nic, nic_interface_t * nic_iface, packet_t * pkt)
|
|
*/
|
|
static int bnx2_read(nic_t * nic, packet_t * pkt)
|
|
{
|
|
- bnx2_t *bp = (bnx2_t *) nic->priv;
|
|
+ bnx2_t *bp;
|
|
int rc = 0;
|
|
uint16_t hw_cons, sw_cons;
|
|
|
|
@@ -973,6 +986,7 @@ static int bnx2_read(nic_t * nic, packet_t * pkt)
|
|
" pkt == 0x%x", nic, pkt);
|
|
return -EINVAL;
|
|
}
|
|
+ bp = (bnx2_t *)nic->priv;
|
|
|
|
hw_cons = bp->get_rx_cons(bp);
|
|
sw_cons = bp->rx_cons;
|
|
@@ -984,8 +998,8 @@ static int bnx2_read(nic_t * nic, packet_t * pkt)
|
|
int len;
|
|
uint16_t errors;
|
|
|
|
- LOG_DEBUG(PFX "%s: clearing rx interrupt: %d %d %d",
|
|
- nic->log_name, sw_cons, hw_cons, rx_index);
|
|
+ LOG_PACKET(PFX "%s: clearing rx interrupt: %d %d %d",
|
|
+ nic->log_name, sw_cons, hw_cons, rx_index);
|
|
|
|
msync(rx_hdr, sizeof(struct l2_fhdr), MS_SYNC);
|
|
errors = ((rx_hdr->l2_fhdr_status & 0xffff0000) >> 16);
|
|
@@ -1033,8 +1047,8 @@ static int bnx2_read(nic_t * nic, packet_t * pkt)
|
|
|
|
rc = 1;
|
|
|
|
- LOG_DEBUG(PFX "%s: processing packet "
|
|
- "length: %d", nic->log_name, len);
|
|
+ LOG_PACKET(PFX "%s: processing packet "
|
|
+ "length: %d", nic->log_name, len);
|
|
} else {
|
|
/* If the NIC passes up a packet bigger
|
|
* then the RX buffer, flag it */
|
|
@@ -1073,21 +1087,23 @@ static int bnx2_read(nic_t * nic, packet_t * pkt)
|
|
*/
|
|
static int bnx2_clear_tx_intr(nic_t * nic)
|
|
{
|
|
- bnx2_t *bp = (bnx2_t *) nic->priv;
|
|
- uint16_t hw_cons = bp->get_tx_cons(bp);
|
|
+ bnx2_t *bp;
|
|
+ uint16_t hw_cons;
|
|
|
|
/* Sanity check: ensure the parameters passed in are valid */
|
|
if (unlikely(nic == NULL)) {
|
|
LOG_ERR(PFX "bnx2_read() nic == NULL");
|
|
return -EINVAL;
|
|
}
|
|
+ bp = (bnx2_t *) nic->priv;
|
|
+ hw_cons = bp->get_tx_cons(bp);
|
|
|
|
if (bp->flags & BNX2_UIO_TX_HAS_SENT) {
|
|
bp->flags &= ~BNX2_UIO_TX_HAS_SENT;
|
|
}
|
|
|
|
- LOG_DEBUG(PFX "%s: clearing tx interrupt [%d %d]",
|
|
- nic->log_name, bp->tx_cons, hw_cons);
|
|
+ LOG_PACKET(PFX "%s: clearing tx interrupt [%d %d]",
|
|
+ nic->log_name, bp->tx_cons, hw_cons);
|
|
|
|
bp->tx_cons = hw_cons;
|
|
|
|
@@ -1097,7 +1113,7 @@ static int bnx2_clear_tx_intr(nic_t * nic)
|
|
if (nic->tx_packet_queue != NULL) {
|
|
packet_t *pkt;
|
|
|
|
- LOG_DEBUG(PFX "%s: sending queued tx packet", nic->log_name);
|
|
+ LOG_PACKET(PFX "%s: sending queued tx packet", nic->log_name);
|
|
pkt = nic_dequeue_tx_packet(nic);
|
|
|
|
/* Got a TX packet buffer of the TX queue and put it onto
|
|
@@ -1106,13 +1122,14 @@ static int bnx2_clear_tx_intr(nic_t * nic)
|
|
bnx2_prepare_xmit_packet(nic, pkt->nic_iface, pkt);
|
|
|
|
bnx2_start_xmit(nic, pkt->buf_size,
|
|
+ (pkt->nic_iface->vlan_priority << 12) |
|
|
pkt->nic_iface->vlan_id);
|
|
|
|
- LOG_DEBUG(PFX "%s: transmitted queued packet %d bytes "
|
|
- "dev->tx_cons: %d, dev->tx_prod: %d, "
|
|
- "dev->tx_bseq:%d",
|
|
- nic->log_name, pkt->buf_size,
|
|
- bp->tx_cons, bp->tx_prod, bp->tx_bseq);
|
|
+ LOG_PACKET(PFX "%s: transmitted queued packet %d bytes "
|
|
+ "dev->tx_cons: %d, dev->tx_prod: %d, "
|
|
+ "dev->tx_bseq:%d",
|
|
+ nic->log_name, pkt->buf_size,
|
|
+ bp->tx_cons, bp->tx_prod, bp->tx_bseq);
|
|
|
|
return -EAGAIN;
|
|
}
|
|
diff --git a/iscsiuio/src/unix/libs/bnx2x.c b/iscsiuio/src/unix/libs/bnx2x.c
|
|
index fa32fbc..5e33420 100644
|
|
--- a/iscsiuio/src/unix/libs/bnx2x.c
|
|
+++ b/iscsiuio/src/unix/libs/bnx2x.c
|
|
@@ -1,5 +1,5 @@
|
|
/*
|
|
- * Copyright (c) 2009-2011, Broadcom Corporation
|
|
+ * Copyright (c) 2009-2012, Broadcom Corporation
|
|
*
|
|
* Written by: Benjamin Li (benli@broadcom.com)
|
|
*
|
|
@@ -288,11 +288,12 @@ static void bnx2x_set_drv_version_unknown(bnx2x_t * bp)
|
|
bp->version.sub_minor = BNX2X_UNKNOWN_SUB_MINOR_VERSION;
|
|
}
|
|
|
|
+/* Return: 1 = Unknown, 0 = Known */
|
|
static int bnx2x_is_drv_version_unknown(struct bnx2x_driver_version *version)
|
|
{
|
|
- if ((version->major == BNX2X_UNKNOWN_MAJOR_VERSION) &&
|
|
- (version->minor == BNX2X_UNKNOWN_MINOR_VERSION) &&
|
|
- (version->sub_minor == BNX2X_UNKNOWN_SUB_MINOR_VERSION)) {
|
|
+ if ((version->major == (uint16_t)BNX2X_UNKNOWN_MAJOR_VERSION) &&
|
|
+ (version->minor == (uint16_t)BNX2X_UNKNOWN_MINOR_VERSION) &&
|
|
+ (version->sub_minor == (uint16_t)BNX2X_UNKNOWN_SUB_MINOR_VERSION)) {
|
|
return 1;
|
|
}
|
|
|
|
@@ -595,7 +596,7 @@ static void bnx2x_free(nic_t *nic)
|
|
/**
|
|
* bnx2x_alloc() - Used to allocate a bnx2x structure
|
|
*/
|
|
-static bnx2x_t *bnx2x_alloc(nic_t * nic)
|
|
+static bnx2x_t *bnx2x_alloc(nic_t *nic)
|
|
{
|
|
bnx2x_t *bp = malloc(sizeof(*bp));
|
|
|
|
@@ -652,9 +653,13 @@ static int bnx2x_open(nic_t * nic)
|
|
if (bp == NULL)
|
|
return -ENOMEM;
|
|
|
|
- if (!bnx2x_is_drv_version_unknown(&bnx2x_version))
|
|
- bnx2x_get_drv_version(bp);
|
|
- else {
|
|
+ if (bnx2x_is_drv_version_unknown(&bnx2x_version)) {
|
|
+ /* If version is unknown, go read from ethtool */
|
|
+ rc = bnx2x_get_drv_version(bp);
|
|
+ if (rc)
|
|
+ goto open_error;
|
|
+ } else {
|
|
+ /* Version is not unknown, jsut use it */
|
|
bnx2x_version.major = bp->version.major;
|
|
bnx2x_version.minor = bp->version.minor;
|
|
bnx2x_version.sub_minor = bp->version.sub_minor;
|
|
@@ -663,7 +668,9 @@ static int bnx2x_open(nic_t * nic)
|
|
count = 0;
|
|
while ((nic->fd < 0) && count < 15) {
|
|
/* udev might not have created the file yet */
|
|
+ pthread_mutex_unlock(&nic->nic_mutex);
|
|
sleep(1);
|
|
+ pthread_mutex_lock(&nic->nic_mutex);
|
|
|
|
nic->fd = open(nic->uio_device_name, O_RDWR | O_NONBLOCK);
|
|
if (nic->fd != INVALID_FD) {
|
|
@@ -684,7 +691,9 @@ static int bnx2x_open(nic_t * nic)
|
|
manually_trigger_uio_event(nic, nic->uio_minor);
|
|
|
|
/* udev might not have created the file yet */
|
|
+ pthread_mutex_unlock(&nic->nic_mutex);
|
|
sleep(1);
|
|
+ pthread_mutex_lock(&nic->nic_mutex);
|
|
|
|
count++;
|
|
}
|
|
@@ -820,7 +829,15 @@ static int bnx2x_open(nic_t * nic)
|
|
nic->log_name);
|
|
goto open_error;
|
|
}
|
|
-
|
|
+ /* In E1/E1H use pci device function as read from sysfs.
|
|
+ * In E2/E3 read physical function from ME register since these chips
|
|
+ * support Physical Device Assignment where kernel BDF maybe arbitrary
|
|
+ * (depending on hypervisor).
|
|
+ */
|
|
+ if (CHIP_IS_E2_PLUS(bp)) {
|
|
+ func = (bnx2x_rd32(bp, BAR_ME_REGISTER) & ME_REG_ABS_PF_NUM) >>
|
|
+ ME_REG_ABS_PF_NUM_SHIFT;
|
|
+ }
|
|
bp->func = func;
|
|
bp->port = bp->func % PORT_MAX;
|
|
|
|
@@ -976,9 +993,12 @@ static int bnx2x_open(nic_t * nic)
|
|
val = bnx2x_rd32(bp, mf_cfg_addr + ovtag_offset);
|
|
val &= 0xffff;
|
|
/* SD mode, check for valid outer VLAN */
|
|
- if (val == 0xffff)
|
|
- goto open_error;
|
|
-
|
|
+ if (val == 0xffff) {
|
|
+ LOG_ERR(PFX "%s: Invalid OV detected for SD, "
|
|
+ " fallback to SF mode!\n",
|
|
+ nic->log_name);
|
|
+ goto SF;
|
|
+ }
|
|
/* Check for iSCSI protocol */
|
|
val = bnx2x_rd32(bp, mf_cfg_addr + proto_offset);
|
|
if ((val & 6) != 6)
|
|
@@ -995,10 +1015,9 @@ static int bnx2x_open(nic_t * nic)
|
|
mac[4] = (__u8) (val >> 8);
|
|
mac[5] = (__u8) val;
|
|
memcpy(nic->mac_addr, mac, 6);
|
|
-
|
|
}
|
|
}
|
|
-
|
|
+SF:
|
|
LOG_INFO(PFX "%s: Using mac address: %02x:%02x:%02x:%02x:%02x:%02x",
|
|
nic->log_name,
|
|
nic->mac_addr[0], nic->mac_addr[1], nic->mac_addr[2],
|
|
@@ -1053,6 +1072,10 @@ open_error:
|
|
close(bp->bar0_fd);
|
|
bp->bar0_fd = INVALID_FD;
|
|
}
|
|
+ if (nic->fd != INVALID_FD) {
|
|
+ close(nic->fd);
|
|
+ nic->fd = INVALID_FD;
|
|
+ }
|
|
bnx2x_free(nic);
|
|
|
|
return rc;
|
|
@@ -1165,9 +1188,12 @@ static int bnx2x_uio_close_resources(nic_t * nic, NIC_SHUTDOWN_T graceful)
|
|
static int bnx2x_close(nic_t * nic, NIC_SHUTDOWN_T graceful)
|
|
{
|
|
/* Sanity Check: validate the parameters */
|
|
- if (nic == NULL || nic->priv == NULL) {
|
|
- LOG_ERR(PFX "bnx2x_close(): nic == %p, bp == %p", nic,
|
|
- nic->priv);
|
|
+ if (nic == NULL) {
|
|
+ LOG_ERR(PFX "bnx2x_close(): nic == NULL");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+ if (nic->priv == NULL) {
|
|
+ LOG_ERR(PFX "bnx2x_close(): nic->priv == NULL");
|
|
return -EINVAL;
|
|
}
|
|
|
|
@@ -1227,8 +1253,8 @@ void bnx2x_start_xmit(nic_t * nic, size_t len, u16_t vlan_id)
|
|
rx_bd = (struct eth_rx_bd *)(((__u8 *) bp->tx_ring) + getpagesize());
|
|
|
|
if ((rx_bd->addr_hi == 0) && (rx_bd->addr_lo == 0)) {
|
|
- LOG_DEBUG(PFX "%s: trying to transmit when device is closed",
|
|
- nic->log_name);
|
|
+ LOG_PACKET(PFX "%s: trying to transmit when device is closed",
|
|
+ nic->log_name);
|
|
pthread_mutex_unlock(&nic->xmit_mutex);
|
|
return;
|
|
}
|
|
@@ -1251,7 +1277,7 @@ void bnx2x_start_xmit(nic_t * nic, size_t len, u16_t vlan_id)
|
|
bp->tx_bd_prod = BNX2X_NEXT_TX_BD(bp->tx_bd_prod);
|
|
|
|
barrier();
|
|
- if (nl_process_if_down == 0) {
|
|
+ if (nic->nl_process_if_down == 0) {
|
|
bnx2x_doorbell(bp, bp->tx_doorbell, 0x02 |
|
|
(bp->tx_bd_prod << 16));
|
|
bnx2x_flush_doorbell(bp, bp->tx_doorbell);
|
|
@@ -1262,8 +1288,8 @@ void bnx2x_start_xmit(nic_t * nic, size_t len, u16_t vlan_id)
|
|
*/
|
|
pthread_mutex_unlock(&nic->xmit_mutex);
|
|
}
|
|
- LOG_DEBUG(PFX "%s: sent %d bytes using bp->tx_prod: %d",
|
|
- nic->log_name, len, bp->tx_prod);
|
|
+ LOG_PACKET(PFX "%s: sent %d bytes using bp->tx_prod: %d",
|
|
+ nic->log_name, len, bp->tx_prod);
|
|
}
|
|
|
|
/**
|
|
@@ -1274,8 +1300,8 @@ void bnx2x_start_xmit(nic_t * nic, size_t len, u16_t vlan_id)
|
|
*/
|
|
int bnx2x_write(nic_t * nic, nic_interface_t * nic_iface, packet_t * pkt)
|
|
{
|
|
- bnx2x_t *bp = (bnx2x_t *) nic->priv;
|
|
- struct uip_stack *uip = &nic_iface->ustack;
|
|
+ bnx2x_t *bp;
|
|
+ struct uip_stack *uip;
|
|
int i = 0;
|
|
|
|
/* Sanity Check: validate the parameters */
|
|
@@ -1285,6 +1311,8 @@ int bnx2x_write(nic_t * nic, nic_interface_t * nic_iface, packet_t * pkt)
|
|
" pkt == 0x%x", nic, nic_iface, pkt);
|
|
return -EINVAL;
|
|
}
|
|
+ bp = (bnx2x_t *) nic->priv;
|
|
+ uip = &nic_iface->ustack;
|
|
|
|
if (pkt->buf_size == 0) {
|
|
LOG_ERR(PFX "%s: Trying to transmitted 0 sized packet",
|
|
@@ -1304,22 +1332,24 @@ int bnx2x_write(nic_t * nic, nic_interface_t * nic_iface, packet_t * pkt)
|
|
}
|
|
|
|
if (pthread_mutex_trylock(&nic->xmit_mutex) != 0) {
|
|
- LOG_DEBUG(PFX "%s: Dropped previous transmitted packet",
|
|
- nic->log_name);
|
|
+ LOG_PACKET(PFX "%s: Dropped previous transmitted packet",
|
|
+ nic->log_name);
|
|
return -EINVAL;
|
|
}
|
|
|
|
bnx2x_prepare_xmit_packet(nic, nic_iface, pkt);
|
|
- bnx2x_start_xmit(nic, pkt->buf_size, nic_iface->vlan_id);
|
|
+ bnx2x_start_xmit(nic, pkt->buf_size,
|
|
+ (nic_iface->vlan_priority << 12) |
|
|
+ nic_iface->vlan_id);
|
|
|
|
/* bump the cnic dev send statistics */
|
|
nic->stats.tx.packets++;
|
|
nic->stats.tx.bytes += uip->uip_len;
|
|
|
|
- LOG_DEBUG(PFX "%s: transmitted %d bytes "
|
|
- "dev->tx_cons: %d, dev->tx_prod: %d, dev->tx_bd_prod:%d",
|
|
- nic->log_name, pkt->buf_size,
|
|
- bp->tx_cons, bp->tx_prod, bp->tx_bd_prod);
|
|
+ LOG_PACKET(PFX "%s: transmitted %d bytes "
|
|
+ "dev->tx_cons: %d, dev->tx_prod: %d, dev->tx_bd_prod:%d",
|
|
+ nic->log_name, pkt->buf_size,
|
|
+ bp->tx_cons, bp->tx_prod, bp->tx_bd_prod);
|
|
|
|
return 0;
|
|
}
|
|
@@ -1348,7 +1378,7 @@ static inline int bnx2x_get_rx_pad(bnx2x_t * bp, union eth_rx_cqe *cqe)
|
|
*/
|
|
static int bnx2x_read(nic_t * nic, packet_t * pkt)
|
|
{
|
|
- bnx2x_t *bp = (bnx2x_t *) nic->priv;
|
|
+ bnx2x_t *bp;
|
|
int rc = 0;
|
|
uint16_t hw_cons, sw_cons, bd_cons, bd_prod;
|
|
|
|
@@ -1358,6 +1388,7 @@ static int bnx2x_read(nic_t * nic, packet_t * pkt)
|
|
" pkt == 0x%x", nic, pkt);
|
|
return -EINVAL;
|
|
}
|
|
+ bp = (bnx2x_t *) nic->priv;
|
|
|
|
hw_cons = bp->get_rx_cons(bp);
|
|
sw_cons = bp->rx_cons;
|
|
@@ -1383,8 +1414,8 @@ static int bnx2x_read(nic_t * nic, packet_t * pkt)
|
|
}
|
|
cqe_fp_flags = cqe->fast_path_cqe.type_error_flags;
|
|
|
|
- LOG_DEBUG(PFX "%s: clearing rx interrupt: %d %d",
|
|
- nic->log_name, sw_cons, hw_cons);
|
|
+ LOG_PACKET(PFX "%s: clearing rx interrupt: %d %d",
|
|
+ nic->log_name, sw_cons, hw_cons);
|
|
|
|
msync(cqe, cqe_size, MS_SYNC);
|
|
|
|
@@ -1416,9 +1447,9 @@ static int bnx2x_read(nic_t * nic, packet_t * pkt)
|
|
pkt->vlan_tag = 0;
|
|
}
|
|
|
|
- LOG_DEBUG(PFX
|
|
- "%s: processing packet length: %d",
|
|
- nic->log_name, len);
|
|
+ LOG_PACKET(PFX
|
|
+ "%s: processing packet length: %d",
|
|
+ nic->log_name, len);
|
|
|
|
/* bump the cnic dev recv statistics */
|
|
nic->stats.rx.packets++;
|
|
@@ -1453,14 +1484,16 @@ static int bnx2x_read(nic_t * nic, packet_t * pkt)
|
|
*/
|
|
static int bnx2x_clear_tx_intr(nic_t * nic)
|
|
{
|
|
- bnx2x_t *bp = (bnx2x_t *) nic->priv;
|
|
- uint16_t hw_cons = bp->get_tx_cons(bp);
|
|
+ bnx2x_t *bp;
|
|
+ uint16_t hw_cons;
|
|
|
|
/* Sanity check: ensure the parameters passed in are valid */
|
|
if (unlikely(nic == NULL)) {
|
|
LOG_ERR(PFX "bnx2x_read() nic == NULL");
|
|
return -EINVAL;
|
|
}
|
|
+ bp = (bnx2x_t *) nic->priv;
|
|
+ hw_cons = bp->get_tx_cons(bp);
|
|
|
|
if (bp->tx_cons == hw_cons) {
|
|
if (bp->tx_cons == bp->tx_prod) {
|
|
@@ -1473,8 +1506,8 @@ static int bnx2x_clear_tx_intr(nic_t * nic)
|
|
return -EAGAIN;
|
|
}
|
|
|
|
- LOG_DEBUG(PFX "%s: clearing tx interrupt [%d %d]",
|
|
- nic->log_name, bp->tx_cons, hw_cons);
|
|
+ LOG_PACKET(PFX "%s: clearing tx interrupt [%d %d]",
|
|
+ nic->log_name, bp->tx_cons, hw_cons);
|
|
bp->tx_cons = hw_cons;
|
|
|
|
/* There is a queued TX packet that needs to be sent out. The usual
|
|
@@ -1484,7 +1517,7 @@ static int bnx2x_clear_tx_intr(nic_t * nic)
|
|
packet_t *pkt;
|
|
int i;
|
|
|
|
- LOG_DEBUG(PFX "%s: sending queued tx packet", nic->log_name);
|
|
+ LOG_PACKET(PFX "%s: sending queued tx packet", nic->log_name);
|
|
pkt = nic_dequeue_tx_packet(nic);
|
|
|
|
/* Got a TX packet buffer of the TX queue and put it onto
|
|
@@ -1493,13 +1526,14 @@ static int bnx2x_clear_tx_intr(nic_t * nic)
|
|
bnx2x_prepare_xmit_packet(nic, pkt->nic_iface, pkt);
|
|
|
|
bnx2x_start_xmit(nic, pkt->buf_size,
|
|
+ (pkt->nic_iface->vlan_priority << 12) |
|
|
pkt->nic_iface->vlan_id);
|
|
|
|
- LOG_DEBUG(PFX "%s: transmitted queued packet %d bytes "
|
|
- "dev->tx_cons: %d, dev->tx_prod: %d, "
|
|
- "dev->tx_bd_prod:%d",
|
|
- nic->log_name, pkt->buf_size,
|
|
- bp->tx_cons, bp->tx_prod, bp->tx_bd_prod);
|
|
+ LOG_PACKET(PFX "%s: transmitted queued packet %d bytes "
|
|
+ "dev->tx_cons: %d, dev->tx_prod: %d, "
|
|
+ "dev->tx_bd_prod:%d",
|
|
+ nic->log_name, pkt->buf_size,
|
|
+ bp->tx_cons, bp->tx_prod, bp->tx_bd_prod);
|
|
|
|
return 0;
|
|
}
|
|
@@ -1512,9 +1546,9 @@ static int bnx2x_clear_tx_intr(nic_t * nic)
|
|
|
|
hw_cons = bp->get_tx_cons(bp);
|
|
if (bp->tx_cons != hw_cons) {
|
|
- LOG_DEBUG(PFX
|
|
- "%s: clearing tx interrupt [%d %d]",
|
|
- nic->log_name, bp->tx_cons, hw_cons);
|
|
+ LOG_PACKET(PFX
|
|
+ "%s: clearing tx interrupt [%d %d]",
|
|
+ nic->log_name, bp->tx_cons, hw_cons);
|
|
bp->tx_cons = hw_cons;
|
|
|
|
break;
|
|
diff --git a/iscsiuio/src/unix/libs/bnx2x.h b/iscsiuio/src/unix/libs/bnx2x.h
|
|
index 8e923b9..b758179 100644
|
|
--- a/iscsiuio/src/unix/libs/bnx2x.h
|
|
+++ b/iscsiuio/src/unix/libs/bnx2x.h
|
|
@@ -467,6 +467,18 @@ struct client_init_general_data {
|
|
#define BAR_XSTRORM_INTMEM 0x420000
|
|
#define BAR_TSTRORM_INTMEM 0x430000
|
|
|
|
+#define BAR_ME_REGISTER 0x450000
|
|
+#define ME_REG_PF_NUM_SHIFT 0
|
|
+#define ME_REG_PF_NUM\
|
|
+ (7L<<ME_REG_PF_NUM_SHIFT) /* Relative PF Num */
|
|
+#define ME_REG_VF_VALID (1<<8)
|
|
+#define ME_REG_VF_NUM_SHIFT 9
|
|
+#define ME_REG_VF_NUM_MASK (0x3f<<ME_REG_VF_NUM_SHIFT)
|
|
+#define ME_REG_VF_ERR (0x1<<3)
|
|
+#define ME_REG_ABS_PF_NUM_SHIFT 16
|
|
+#define ME_REG_ABS_PF_NUM\
|
|
+ (7L<<ME_REG_ABS_PF_NUM_SHIFT) /* Absolute PF Num */
|
|
+
|
|
#define USTORM_RX_PRODS_OFFSET(port, client_id) \
|
|
(IS_E1H_OFFSET ? (0x1000 + (port * 0x680) + (client_id * 0x40)) \
|
|
: (0x4000 + (port * 0x360) + (client_id * 0x30)))
|
|
diff --git a/iscsiuio/src/unix/libs/cnic.c b/iscsiuio/src/unix/libs/cnic.c
|
|
index 841c1ac..a81d47b 100644
|
|
--- a/iscsiuio/src/unix/libs/cnic.c
|
|
+++ b/iscsiuio/src/unix/libs/cnic.c
|
|
@@ -125,6 +125,7 @@ static int cnic_arp_send(nic_t * nic, nic_interface_t * nic_iface, int fd,
|
|
memcpy(arp->arp_tpa, &dst_ip, 4);
|
|
|
|
(*nic->nic_library->ops->start_xmit) (nic, pkt_size,
|
|
+ (nic_iface->vlan_priority << 12) |
|
|
nic_iface->vlan_id);
|
|
|
|
memcpy(&addr.s_addr, &dst_ip, sizeof(addr.s_addr));
|
|
@@ -166,15 +167,6 @@ static int cnic_neigh_soliciation_send(nic_t * nic,
|
|
memcpy(ipv6_hdr->ip6_dst.s6_addr, addr6_dst->s6_addr,
|
|
sizeof(struct in6_addr));
|
|
|
|
- LOG_DEBUG(PFX "dst ip addr %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
|
|
- ipv6_hdr->ip6_dst.s6_addr16[0],
|
|
- ipv6_hdr->ip6_dst.s6_addr16[1],
|
|
- ipv6_hdr->ip6_dst.s6_addr16[2],
|
|
- ipv6_hdr->ip6_dst.s6_addr16[3],
|
|
- ipv6_hdr->ip6_dst.s6_addr16[4],
|
|
- ipv6_hdr->ip6_dst.s6_addr16[5],
|
|
- ipv6_hdr->ip6_dst.s6_addr16[6],
|
|
- ipv6_hdr->ip6_dst.s6_addr16[7]);
|
|
nic_fill_ethernet_header(nic_iface, eth, nic->mac_addr, nic->mac_addr,
|
|
&pkt_size, (void *)&ipv6_hdr, ETHERTYPE_IPV6);
|
|
req_ptr.eth = (void *)eth;
|
|
@@ -196,6 +188,7 @@ static int cnic_neigh_soliciation_send(nic_t * nic,
|
|
eth->ether_shost[2], eth->ether_shost[3],
|
|
eth->ether_shost[4], eth->ether_shost[5]);
|
|
(*nic->nic_library->ops->start_xmit) (nic, pkt_size,
|
|
+ (nic_iface->vlan_priority << 12) |
|
|
nic_iface->vlan_id);
|
|
|
|
LOG_DEBUG(PFX "%s: Sent cnic ICMPv6 neighbor request %s",
|
|
@@ -261,12 +254,7 @@ static int cnic_nl_neigh_rsp(nic_t * nic, int fd,
|
|
}
|
|
if (ret) {
|
|
/* Get link local IPv6 address */
|
|
- if (ndpc_request(&nic_iface->ustack, NULL,
|
|
- &src_ipv6, GET_LINK_LOCAL_ADDR)) {
|
|
- src_ipv6 = (u8_t *)all_zeroes_addr6;
|
|
- LOG_DEBUG(PFX "RSP Get LL failed");
|
|
- goto src_done;
|
|
- }
|
|
+ src_ipv6 = (u8_t *)&nic_iface->ustack.linklocal6;
|
|
} else {
|
|
if (ndpc_request(&nic_iface->ustack,
|
|
&path_req->dst.v6_addr,
|
|
@@ -288,16 +276,18 @@ src_done:
|
|
addr_dst_str, sizeof(addr_dst_str));
|
|
}
|
|
memcpy(path_rsp->mac_addr, mac_addr, 6);
|
|
- path_rsp->vlan_id = path_req->vlan_id;
|
|
- path_rsp->pmtu = path_req->pmtu;
|
|
+ path_rsp->vlan_id = (nic_iface->vlan_priority << 12) |
|
|
+ nic_iface->vlan_id;
|
|
+ path_rsp->pmtu = nic_iface->mtu ? nic_iface->mtu : path_req->pmtu;
|
|
|
|
rc = __kipc_call(fd, ret_ev, sizeof(*ret_ev) + sizeof(*path_rsp));
|
|
if (rc > 0) {
|
|
LOG_DEBUG(PFX "neighbor reply sent back to kernel "
|
|
- "%s at %02x:%02x:%02x:%02x:%02x:%02x",
|
|
+ "%s at %02x:%02x:%02x:%02x:%02x:%02x with vlan %d",
|
|
addr_dst_str,
|
|
mac_addr[0], mac_addr[1],
|
|
- mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
|
|
+ mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5],
|
|
+ nic_iface->vlan_id);
|
|
|
|
} else {
|
|
LOG_ERR(PFX "send neighbor reply failed: %d", rc);
|
|
@@ -323,67 +313,18 @@ const static struct timeval tp_wait = {
|
|
*/
|
|
int cnic_handle_ipv4_iscsi_path_req(nic_t * nic, int fd,
|
|
struct iscsi_uevent *ev,
|
|
- struct iscsi_path *path)
|
|
+ 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];
|
|
int rc;
|
|
uint16_t arp_retry;
|
|
int status = 0;
|
|
-
|
|
- memset(mac_addr, 0, sizeof(mac_addr));
|
|
-
|
|
- pthread_mutex_lock(&nic_list_mutex);
|
|
-
|
|
- /* Find the proper interface via VLAN id */
|
|
- 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;
|
|
- }
|
|
- 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;
|
|
- }
|
|
-
|
|
- 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
|
|
|
|
+ memset(mac_addr, 0, sizeof(mac_addr));
|
|
memcpy(&dst_addr, &path->dst.v4_addr, sizeof(dst_addr));
|
|
memcpy(&src_addr, nic_iface->ustack.hostaddr, sizeof(src_addr));
|
|
|
|
@@ -445,20 +386,15 @@ int cnic_handle_ipv4_iscsi_path_req(nic_t * nic, int fd,
|
|
ts.tv_sec = tp_abs.tv_sec;
|
|
ts.tv_nsec = tp_abs.tv_usec * 1000;
|
|
|
|
- pthread_mutex_unlock(&nic_list_mutex);
|
|
+ /* Wait 1s for if_down */
|
|
+ pthread_mutex_lock(&nic->nl_process_mutex);
|
|
rc = pthread_cond_timedwait
|
|
- (&nl_process_if_down_cond,
|
|
- &nl_process_mutex, &ts);
|
|
+ (&nic->nl_process_if_down_cond,
|
|
+ &nic->nl_process_mutex, &ts);
|
|
|
|
if (rc == ETIMEDOUT) {
|
|
- pthread_mutex_unlock(&nl_process_mutex);
|
|
-
|
|
- if (pthread_mutex_trylock
|
|
- (&nic_list_mutex) != 0) {
|
|
- arp_retry = MAX_ARP_RETRY;
|
|
- goto done;
|
|
-
|
|
- }
|
|
+ pthread_mutex_unlock
|
|
+ (&nic->nl_process_mutex);
|
|
|
|
rc = uip_lookup_arp_entry(dst_addr.
|
|
s_addr,
|
|
@@ -466,8 +402,9 @@ int cnic_handle_ipv4_iscsi_path_req(nic_t * nic, int fd,
|
|
if (rc == 0)
|
|
goto done;
|
|
} else {
|
|
- nl_process_if_down = 0;
|
|
- pthread_mutex_unlock(&nl_process_mutex);
|
|
+ nic->nl_process_if_down = 0;
|
|
+ pthread_mutex_unlock
|
|
+ (&nic->nl_process_mutex);
|
|
|
|
arp_retry = MAX_ARP_RETRY;
|
|
goto done;
|
|
@@ -491,9 +428,6 @@ done:
|
|
|
|
cnic_nl_neigh_rsp(nic, fd, ev, path, mac_addr,
|
|
nic_iface, status, AF_INET);
|
|
-
|
|
- pthread_mutex_unlock(&nic_list_mutex);
|
|
-
|
|
return rc;
|
|
}
|
|
|
|
@@ -507,9 +441,9 @@ done:
|
|
*/
|
|
int cnic_handle_ipv6_iscsi_path_req(nic_t * nic, int fd,
|
|
struct iscsi_uevent *ev,
|
|
- struct iscsi_path *path)
|
|
+ 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;
|
|
@@ -525,52 +459,6 @@ int cnic_handle_ipv6_iscsi_path_req(nic_t * nic, int fd,
|
|
inet_ntop(AF_INET6, &path->dst.v6_addr,
|
|
addr_dst_str, sizeof(addr_dst_str));
|
|
|
|
- pthread_mutex_lock(&nic_list_mutex);
|
|
-
|
|
- /* Find the proper interface via VLAN id */
|
|
- 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;
|
|
- }
|
|
- 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_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 */
|
|
@@ -584,12 +472,7 @@ int cnic_handle_ipv6_iscsi_path_req(nic_t * nic, int fd,
|
|
if (rc) {
|
|
LOG_DEBUG(PFX "Use LL");
|
|
/* Get link local IPv6 address */
|
|
- if (ndpc_request(&nic_iface->ustack, NULL,
|
|
- &addr, GET_LINK_LOCAL_ADDR)) {
|
|
- neighbor_retry = MAX_ARP_RETRY;
|
|
- LOG_DEBUG(PFX "Use LL failed");
|
|
- goto done;
|
|
- }
|
|
+ addr = (struct in6_addr *)&nic_iface->ustack.linklocal6;
|
|
} else {
|
|
LOG_DEBUG(PFX "Use Best matched");
|
|
if (ndpc_request(&nic_iface->ustack,
|
|
@@ -618,21 +501,15 @@ int cnic_handle_ipv6_iscsi_path_req(nic_t * nic, int fd,
|
|
memcpy(&netmask.s6_addr, all_zeroes_addr6,
|
|
sizeof(struct in6_addr));
|
|
|
|
- LOG_DEBUG(PFX "src addr %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
|
|
- src_addr.s6_addr16[0], src_addr.s6_addr16[1],
|
|
- src_addr.s6_addr16[2], src_addr.s6_addr16[3],
|
|
- src_addr.s6_addr16[4], src_addr.s6_addr16[5],
|
|
- src_addr.s6_addr16[6], src_addr.s6_addr16[7]);
|
|
- LOG_DEBUG(PFX "dst addr %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
|
|
- dst_addr.s6_addr16[0], dst_addr.s6_addr16[1],
|
|
- dst_addr.s6_addr16[2], dst_addr.s6_addr16[3],
|
|
- dst_addr.s6_addr16[4], dst_addr.s6_addr16[5],
|
|
- dst_addr.s6_addr16[6], dst_addr.s6_addr16[7]);
|
|
- LOG_DEBUG(PFX "nm addr %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
|
|
- netmask.s6_addr16[0], netmask.s6_addr16[1],
|
|
- netmask.s6_addr16[2], netmask.s6_addr16[3],
|
|
- netmask.s6_addr16[4], netmask.s6_addr16[5],
|
|
- netmask.s6_addr16[6], netmask.s6_addr16[7]);
|
|
+ inet_ntop(AF_INET6, &src_addr.s6_addr16, addr_dst_str,
|
|
+ sizeof(addr_dst_str));
|
|
+ LOG_DEBUG(PFX "src IP addr %s", addr_dst_str);
|
|
+ inet_ntop(AF_INET6, &dst_addr.s6_addr16, addr_dst_str,
|
|
+ sizeof(addr_dst_str));
|
|
+ LOG_DEBUG(PFX "dst IP addr %s", addr_dst_str);
|
|
+ inet_ntop(AF_INET6, &netmask.s6_addr16, addr_dst_str,
|
|
+ sizeof(addr_dst_str));
|
|
+ LOG_DEBUG(PFX "prefix mask %s", addr_dst_str);
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
src_matching_addr.s6_addr32[i] = src_addr.s6_addr32[i] &
|
|
@@ -642,24 +519,22 @@ int cnic_handle_ipv6_iscsi_path_req(nic_t * nic, int fd,
|
|
if (src_matching_addr.s6_addr32[i] !=
|
|
dst_matching_addr.s6_addr32[i]) {
|
|
/* No match with the prefix mask, use default route */
|
|
- if (ndpc_request(&nic_iface->ustack, NULL, &addr,
|
|
- GET_DEFAULT_ROUTER_ADDR)) {
|
|
- neighbor_retry = MAX_ARP_RETRY;
|
|
- goto done;
|
|
- }
|
|
- if (memcmp(addr, all_zeroes_addr6, sizeof(*addr)))
|
|
- memcpy(&dst_addr, addr, sizeof(dst_addr));
|
|
- else {
|
|
+ if (memcmp(nic_iface->ustack.default_route_addr6,
|
|
+ all_zeroes_addr6, sizeof(*addr))) {
|
|
+ memcpy(&dst_addr,
|
|
+ nic_iface->ustack.default_route_addr6,
|
|
+ sizeof(dst_addr));
|
|
+ inet_ntop(AF_INET6, &dst_addr.s6_addr16,
|
|
+ addr_dst_str, sizeof(addr_dst_str));
|
|
+ LOG_DEBUG(PFX "Use default router IP addr %s",
|
|
+ addr_dst_str);
|
|
+ break;
|
|
+ } else {
|
|
neighbor_retry = MAX_ARP_RETRY;
|
|
goto done;
|
|
}
|
|
}
|
|
}
|
|
- LOG_DEBUG(PFX "dst addr %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
|
|
- dst_addr.s6_addr16[0], dst_addr.s6_addr16[1],
|
|
- dst_addr.s6_addr16[2], dst_addr.s6_addr16[3],
|
|
- dst_addr.s6_addr16[4], dst_addr.s6_addr16[5],
|
|
- dst_addr.s6_addr16[6], dst_addr.s6_addr16[7]);
|
|
|
|
#define MAX_ARP_RETRY 4
|
|
neighbor_retry = 0;
|
|
@@ -672,6 +547,8 @@ int cnic_handle_ipv6_iscsi_path_req(nic_t * nic, int fd,
|
|
goto done;
|
|
}
|
|
if (!rc) {
|
|
+ inet_ntop(AF_INET6, &dst_addr.s6_addr16,
|
|
+ addr_dst_str, sizeof(addr_dst_str));
|
|
LOG_DEBUG(PFX
|
|
"%s: Preparing to send IPv6 neighbor solicitation "
|
|
"to dst: '%s'", nic->log_name, addr_dst_str);
|
|
@@ -703,20 +580,14 @@ int cnic_handle_ipv6_iscsi_path_req(nic_t * nic, int fd,
|
|
ts.tv_sec = tp_abs.tv_sec;
|
|
ts.tv_nsec = tp_abs.tv_usec * 1000;
|
|
|
|
- pthread_mutex_unlock(&nic_list_mutex);
|
|
+ pthread_mutex_lock(&nic->nl_process_mutex);
|
|
rc = pthread_cond_timedwait
|
|
- (&nl_process_if_down_cond,
|
|
- &nl_process_mutex, &ts);
|
|
+ (&nic->nl_process_if_down_cond,
|
|
+ &nic->nl_process_mutex, &ts);
|
|
|
|
if (rc == ETIMEDOUT) {
|
|
- pthread_mutex_unlock(&nl_process_mutex);
|
|
-
|
|
- if (pthread_mutex_trylock
|
|
- (&nic_list_mutex) != 0) {
|
|
- neighbor_retry = MAX_ARP_RETRY;
|
|
- goto done;
|
|
-
|
|
- }
|
|
+ pthread_mutex_unlock
|
|
+ (&nic->nl_process_mutex);
|
|
|
|
req_ptr.eth = (void *)mac_addr;
|
|
req_ptr.ipv6 = (void *)&dst_addr;
|
|
@@ -730,8 +601,9 @@ int cnic_handle_ipv6_iscsi_path_req(nic_t * nic, int fd,
|
|
if (rc)
|
|
goto done;
|
|
} else {
|
|
- nl_process_if_down = 0;
|
|
- pthread_mutex_unlock(&nl_process_mutex);
|
|
+ nic->nl_process_if_down = 0;
|
|
+ pthread_mutex_unlock
|
|
+ (&nic->nl_process_mutex);
|
|
|
|
neighbor_retry = MAX_ARP_RETRY;
|
|
goto done;
|
|
@@ -752,9 +624,6 @@ done:
|
|
|
|
cnic_nl_neigh_rsp(nic, fd, ev, path, mac_addr,
|
|
nic_iface, status, AF_INET6);
|
|
-
|
|
- pthread_mutex_unlock(&nic_list_mutex);
|
|
-
|
|
return rc;
|
|
}
|
|
|
|
@@ -764,11 +633,12 @@ done:
|
|
* @param nic - The nic the message is directed towards
|
|
* @param fd - The file descriptor to be used to extract the private data
|
|
* @param ev - The iscsi_uevent
|
|
- * @param buf - The private message buffer
|
|
- * @param buf_len - The private message buffer length
|
|
+ * @param path - The private message buffer
|
|
+ * @param nic_iface - The nic_iface to use for this connection request
|
|
*/
|
|
int cnic_handle_iscsi_path_req(nic_t * nic, int fd, struct iscsi_uevent *ev,
|
|
- struct iscsi_path *path)
|
|
+ struct iscsi_path *path,
|
|
+ nic_interface_t *nic_iface)
|
|
{
|
|
|
|
LOG_DEBUG(PFX "%s: Netlink message with VLAN ID: %d, path MTU: %d "
|
|
@@ -777,9 +647,11 @@ int cnic_handle_iscsi_path_req(nic_t * nic, int fd, struct iscsi_uevent *ev,
|
|
path->ip_addr_len);
|
|
|
|
if (path->ip_addr_len == 4)
|
|
- return cnic_handle_ipv4_iscsi_path_req(nic, fd, ev, path);
|
|
+ return cnic_handle_ipv4_iscsi_path_req(nic, fd, ev, path,
|
|
+ nic_iface);
|
|
else if (path->ip_addr_len == 16)
|
|
- return cnic_handle_ipv6_iscsi_path_req(nic, fd, ev, path);
|
|
+ return cnic_handle_ipv6_iscsi_path_req(nic, fd, ev, path,
|
|
+ nic_iface);
|
|
else {
|
|
LOG_DEBUG(PFX "%s: unknown ip_addr_len: %d size dropping ",
|
|
nic->log_name, path->ip_addr_len);
|
|
diff --git a/iscsiuio/src/unix/libs/cnic.h b/iscsiuio/src/unix/libs/cnic.h
|
|
index 738deb8..679dab8 100644
|
|
--- a/iscsiuio/src/unix/libs/cnic.h
|
|
+++ b/iscsiuio/src/unix/libs/cnic.h
|
|
@@ -48,6 +48,7 @@ int cnic_nl_open();
|
|
void cnic_nl_close();
|
|
|
|
int cnic_handle_iscsi_path_req(nic_t * nic, int, struct iscsi_uevent *,
|
|
- struct iscsi_path *path);
|
|
+ struct iscsi_path *path,
|
|
+ nic_interface_t *nic_iface);
|
|
|
|
#endif /* __CNIC_NL_H__ */
|
|
diff --git a/iscsiuio/src/unix/main.c b/iscsiuio/src/unix/main.c
|
|
index 4f548e9..2008913 100644
|
|
--- a/iscsiuio/src/unix/main.c
|
|
+++ b/iscsiuio/src/unix/main.c
|
|
@@ -141,7 +141,6 @@ signal_wait:
|
|
break;
|
|
case SIGUSR1:
|
|
LOG_INFO("Caught SIGUSR1 signal, rotate log");
|
|
-retry:
|
|
fini_logger(SHUTDOWN_LOGGER);
|
|
rc = init_logger(main_log.log_file);
|
|
if (rc != 0)
|
|
diff --git a/iscsiuio/src/unix/nic.c b/iscsiuio/src/unix/nic.c
|
|
index 0934b56..0b3c538 100644
|
|
--- a/iscsiuio/src/unix/nic.c
|
|
+++ b/iscsiuio/src/unix/nic.c
|
|
@@ -64,6 +64,7 @@
|
|
|
|
#include "bnx2.h"
|
|
#include "bnx2x.h"
|
|
+#include "ipv6.h"
|
|
|
|
/******************************************************************************
|
|
* Constants
|
|
@@ -118,7 +119,7 @@ static void free_nic_library_handle(nic_lib_handle_t * handle)
|
|
* @param handle - This is the library handle to load
|
|
* @return 0 = Success; <0 = failure
|
|
*/
|
|
-static int load_nic_library(nic_lib_handle_t * handle)
|
|
+static int load_nic_library(nic_lib_handle_t *handle)
|
|
{
|
|
int rc;
|
|
char *library_name;
|
|
@@ -172,7 +173,7 @@ static int load_nic_library(nic_lib_handle_t * handle)
|
|
|
|
return 0;
|
|
|
|
- error:
|
|
+error:
|
|
pthread_mutex_unlock(&handle->mutex);
|
|
|
|
return rc;
|
|
@@ -197,9 +198,10 @@ int load_all_nic_libraries()
|
|
handle->ops = (*nic_get_ops[i]) ();
|
|
|
|
rc = load_nic_library(handle);
|
|
- if (rc != 0)
|
|
+ if (rc != 0) {
|
|
+ free_nic_library_handle(handle);
|
|
return rc;
|
|
-
|
|
+ }
|
|
/* Add the CNIC library to the list of library handles */
|
|
pthread_mutex_lock(&nic_lib_list_mutex);
|
|
|
|
@@ -270,7 +272,7 @@ NIC_LIBRARY_EXIST_T does_nic_uio_name_exist(char *name)
|
|
|
|
rc = NIC_LIBRARY_DOESNT_EXIST;
|
|
|
|
- done:
|
|
+done:
|
|
pthread_mutex_unlock(&nic_lib_list_mutex);
|
|
return rc;
|
|
}
|
|
@@ -300,7 +302,7 @@ NIC_LIBRARY_EXIST_T does_nic_library_exist(char *name)
|
|
|
|
rc = NIC_LIBRARY_DOESNT_EXIST;
|
|
|
|
- done:
|
|
+done:
|
|
pthread_mutex_unlock(&nic_lib_list_mutex);
|
|
return rc;
|
|
}
|
|
@@ -366,7 +368,7 @@ int find_nic_lib_using_pci_id(uint32_t vendor, uint32_t device,
|
|
}
|
|
rc = -EINVAL;
|
|
|
|
- done:
|
|
+done:
|
|
pthread_mutex_unlock(&nic_lib_list_mutex);
|
|
|
|
return rc;
|
|
@@ -393,13 +395,14 @@ nic_t *nic_init()
|
|
nic->next = NULL;
|
|
nic->thread = INVALID_THREAD;
|
|
nic->enable_thread = INVALID_THREAD;
|
|
- nic->flags |= NIC_UNITIALIZED | NIC_DISABLED;
|
|
- nic->state |= NIC_STOPPED;
|
|
+ nic->flags |= NIC_DISABLED;
|
|
+ nic->state = NIC_STOPPED;
|
|
nic->free_packet_queue = NULL;
|
|
nic->tx_packet_queue = NULL;
|
|
nic->nic_library = NULL;
|
|
nic->pci_id = NULL;
|
|
|
|
+ /* nic_mutex is used to protect nic_ops */
|
|
pthread_mutex_init(&nic->nic_mutex, NULL);
|
|
pthread_mutex_init(&nic->xmit_mutex, NULL);
|
|
pthread_mutex_init(&nic->free_packet_queue_mutex, NULL);
|
|
@@ -411,6 +414,15 @@ nic_t *nic_init()
|
|
|
|
nic->rx_poll_usec = DEFAULT_RX_POLL_USEC;
|
|
|
|
+ pthread_mutex_init(&nic->nl_process_mutex, NULL);
|
|
+ pthread_cond_init(&nic->nl_process_if_down_cond, NULL);
|
|
+ pthread_cond_init(&nic->nl_process_cond, NULL);
|
|
+ nic->nl_process_thread = INVALID_THREAD;
|
|
+ nic->nl_process_if_down = 0;
|
|
+ nic->nl_process_head = 0;
|
|
+ nic->nl_process_tail = 0;
|
|
+ memset(&nic->nl_process_ring, 0, sizeof(nic->nl_process_ring));
|
|
+
|
|
return nic;
|
|
}
|
|
|
|
@@ -432,7 +444,6 @@ void nic_add(nic_t * nic)
|
|
|
|
/**
|
|
* nic_remove() - Used to remove the NIC for the nic list
|
|
- nic_list_mutex must be taken
|
|
* @param nic - the nic to remove
|
|
*/
|
|
int nic_remove(nic_t * nic)
|
|
@@ -451,41 +462,66 @@ int nic_remove(nic_t * nic)
|
|
nic->ops->close(nic, 0);
|
|
|
|
nic->state = NIC_EXIT;
|
|
- pthread_mutex_unlock(&nic->nic_mutex);
|
|
|
|
if (nic->enable_thread != INVALID_THREAD) {
|
|
- LOG_ERR(PFX "%s: Canceling nic enable thread", nic->log_name);
|
|
+ LOG_DEBUG(PFX "%s: Canceling nic enable thread", nic->log_name);
|
|
|
|
rc = pthread_cancel(nic->enable_thread);
|
|
if (rc != 0)
|
|
- LOG_ERR(PFX "%s: Couldn't send cancel to nic enable "
|
|
- "thread", nic->log_name);
|
|
+ LOG_DEBUG(PFX "%s: Couldn't send cancel to nic enable "
|
|
+ "thread", nic->log_name);
|
|
|
|
- LOG_ERR(PFX "%s: Waiting to join nic enable thread",
|
|
- nic->log_name);
|
|
+ LOG_DEBUG(PFX "%s: Waiting to join nic enable thread",
|
|
+ nic->log_name);
|
|
rc = pthread_join(nic->enable_thread, &res);
|
|
if (rc != 0)
|
|
- LOG_ERR(PFX "%s: Couldn't join to canceled enable nic "
|
|
- "thread", nic->log_name);
|
|
+ LOG_DEBUG(PFX "%s: Couldn't join to canceled enable "
|
|
+ "nic thread", nic->log_name);
|
|
nic->enable_thread = INVALID_THREAD;
|
|
+ LOG_DEBUG(PFX "%s: nic enable thread cleaned", nic->log_name);
|
|
+ } else {
|
|
+ LOG_DEBUG(PFX "%s: NIC enable thread already canceled",
|
|
+ nic->log_name);
|
|
}
|
|
+
|
|
if (nic->thread != INVALID_THREAD) {
|
|
- LOG_ERR(PFX "%s: Canceling nic thread", nic->log_name);
|
|
+ LOG_DEBUG(PFX "%s: Canceling nic thread", nic->log_name);
|
|
|
|
rc = pthread_cancel(nic->thread);
|
|
if (rc != 0)
|
|
- LOG_ERR(PFX "%s: Couldn't send cancel to nic",
|
|
- nic->log_name);
|
|
+ LOG_DEBUG(PFX "%s: Couldn't send cancel to nic",
|
|
+ nic->log_name);
|
|
|
|
- LOG_ERR(PFX "%s: Waiting to join nic thread", nic->log_name);
|
|
+ LOG_DEBUG(PFX "%s: Waiting to join nic thread", nic->log_name);
|
|
rc = pthread_join(nic->thread, &res);
|
|
if (rc != 0)
|
|
- LOG_ERR(PFX "%s: Couldn't join to canceled nic thread",
|
|
- nic->log_name);
|
|
-
|
|
+ LOG_DEBUG(PFX "%s: Couldn't join to canceled nic "
|
|
+ "thread", nic->log_name);
|
|
nic->thread = INVALID_THREAD;
|
|
+ LOG_DEBUG(PFX "%s: nic thread cleaned", nic->log_name);
|
|
+ } else {
|
|
+ LOG_DEBUG(PFX "%s: NIC thread already canceled", nic->log_name);
|
|
+ }
|
|
+
|
|
+ if (nic->nl_process_thread != INVALID_THREAD) {
|
|
+ LOG_DEBUG(PFX "%s: Canceling nic nl thread", nic->log_name);
|
|
+
|
|
+ rc = pthread_cancel(nic->nl_process_thread);
|
|
+ if (rc != 0)
|
|
+ LOG_DEBUG(PFX "%s: Couldn't send cancel to nic nl "
|
|
+ "thread", nic->log_name);
|
|
+
|
|
+ LOG_DEBUG(PFX "%s: Waiting to join nic nl thread",
|
|
+ nic->log_name);
|
|
+ rc = pthread_join(nic->nl_process_thread, &res);
|
|
+ if (rc != 0)
|
|
+ LOG_DEBUG(PFX "%s: Couldn't join to canceled nic nl "
|
|
+ "thread", nic->log_name);
|
|
+ nic->nl_process_thread = INVALID_THREAD;
|
|
+ LOG_DEBUG(PFX "%s: nic nl thread cleaned", nic->log_name);
|
|
} else {
|
|
- LOG_ERR(PFX "%s: NIC thread already canceled", nic->log_name);
|
|
+ LOG_DEBUG(PFX "%s: NIC nl thread already canceled",
|
|
+ nic->log_name);
|
|
}
|
|
|
|
current = prev = nic_list;
|
|
@@ -505,7 +541,7 @@ int nic_remove(nic_t * nic)
|
|
|
|
/* Before freeing the nic, must free all the associated
|
|
nic_iface */
|
|
- nic_iface = nic->nic_iface;
|
|
+ nic_iface = current->nic_iface;
|
|
while (nic_iface != NULL) {
|
|
vlan_iface = nic_iface->vlan_next;
|
|
while (vlan_iface != NULL) {
|
|
@@ -608,7 +644,7 @@ error:
|
|
}
|
|
|
|
/**
|
|
- * net_iface_init() - This function is used to add an interface to the
|
|
+ * nic_iface_init() - This function is used to add an interface to the
|
|
* structure cnic_uio
|
|
* @return 0 on success, <0 on failure
|
|
*/
|
|
@@ -623,6 +659,8 @@ nic_interface_t *nic_iface_init()
|
|
memset(nic_iface, 0, sizeof(*nic_iface));
|
|
nic_iface->next = NULL;
|
|
nic_iface->vlan_next = NULL;
|
|
+ nic_iface->iface_num = IFACE_NUM_INVALID;
|
|
+ nic_iface->request_type = IP_CONFIG_OFF;
|
|
|
|
return nic_iface;
|
|
}
|
|
@@ -630,112 +668,57 @@ nic_interface_t *nic_iface_init()
|
|
/**
|
|
* nic_add_nic_iface() - This function is used to add an interface to the
|
|
* nic structure
|
|
+ * Called with nic_mutex held
|
|
* @param nic - struct nic device to add the interface to
|
|
* @param nic_iface - network interface used to add to the nic
|
|
* @return 0 on success, <0 on failure
|
|
*/
|
|
-int nic_add_nic_iface(nic_t * nic, nic_interface_t * nic_iface)
|
|
+int nic_add_nic_iface(nic_t *nic, nic_interface_t *nic_iface)
|
|
{
|
|
+ nic_interface_t *current, *prev;
|
|
+
|
|
+ /* Make sure it doesn't already exist */
|
|
+ current = nic_find_nic_iface(nic, nic_iface->protocol,
|
|
+ nic_iface->vlan_id, nic_iface->iface_num,
|
|
+ nic_iface->request_type);
|
|
+ if (current) {
|
|
+ LOG_DEBUG(PFX "%s: nic interface for VLAN: %d, protocol: %d"
|
|
+ " already exist", nic->log_name, nic_iface->vlan_id,
|
|
+ nic_iface->protocol);
|
|
+ return 0;
|
|
+ }
|
|
|
|
- pthread_mutex_lock(&nic->nic_mutex);
|
|
-
|
|
- /* Add the nic_interface */
|
|
- if (nic->nic_iface == NULL) {
|
|
- nic->nic_iface = nic_iface;
|
|
- } else {
|
|
- nic_interface_t *current = nic->nic_iface;
|
|
-
|
|
- /* Check to see if this interface already exists via 2
|
|
- * conditions: 1) VLAN 2) protocol */
|
|
- while (current != NULL) {
|
|
- if ((current->protocol == nic_iface->protocol) &&
|
|
- (current->vlan_id == nic_iface->vlan_id)) {
|
|
- LOG_WARN(PFX "%s: nic interface alread exists"
|
|
- "for VLAN: %d, protocol: %d",
|
|
- nic->log_name, current->vlan_id,
|
|
- current->protocol);
|
|
- goto error;
|
|
- }
|
|
- current = current->next;
|
|
- }
|
|
-
|
|
- /* This interface doesn't exists, we can safely add
|
|
- * this nic interface */
|
|
- current = nic->nic_iface;
|
|
- while (current->next != NULL) {
|
|
- current = current->next;
|
|
+ prev = NULL;
|
|
+ current = nic->nic_iface;
|
|
+ while (current != NULL) {
|
|
+ if (current->protocol == nic_iface->protocol) {
|
|
+ /* Replace parent */
|
|
+ nic_iface->vlan_next = current;
|
|
+ nic_iface->next = current->next;
|
|
+ current->next = NULL;
|
|
+ if (prev)
|
|
+ prev->next = nic_iface;
|
|
+ else
|
|
+ nic->nic_iface = nic_iface;
|
|
+ goto done;
|
|
}
|
|
-
|
|
- current->next = nic_iface;
|
|
+ prev = current;
|
|
+ current = current->next;
|
|
}
|
|
-
|
|
+ nic_iface->next = nic->nic_iface;
|
|
+ nic->nic_iface = nic_iface;
|
|
+done:
|
|
/* Set nic_interface common fields */
|
|
nic_iface->parent = nic;
|
|
+ memcpy(&nic_iface->ustack.uip_ethaddr.addr, nic->mac_addr, ETH_ALEN);
|
|
nic->num_of_nic_iface++;
|
|
|
|
LOG_INFO(PFX "%s: Added nic interface for VLAN: %d, protocol: %d",
|
|
nic->log_name, nic_iface->vlan_id, nic_iface->protocol);
|
|
|
|
-error:
|
|
- pthread_mutex_unlock(&nic->nic_mutex);
|
|
-
|
|
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
|
|
******************************************************************************/
|
|
@@ -752,13 +735,13 @@ int nic_process_intr(nic_t * nic, int discard_check)
|
|
struct timeval tv;
|
|
|
|
/* Simple sanity checks */
|
|
- if ((discard_check != 1) && (nic->state & NIC_RUNNING) != NIC_RUNNING) {
|
|
+ if (discard_check != 1 && nic->state != NIC_RUNNING) {
|
|
LOG_ERR(PFX "%s: Couldn't process interupt NIC not running",
|
|
nic->log_name);
|
|
return -EBUSY;
|
|
}
|
|
|
|
- if ((discard_check != 1) && (nic->fd == INVALID_FD)) {
|
|
+ if (discard_check != 1 && nic->fd == INVALID_FD) {
|
|
LOG_ERR(PFX "%s: NIC fd not valid", nic->log_name);
|
|
return -EIO;
|
|
}
|
|
@@ -767,11 +750,12 @@ int nic_process_intr(nic_t * nic, int discard_check)
|
|
FD_SET(nic->fd, &fdset);
|
|
|
|
tv.tv_sec = 0;
|
|
- if (nic->state & NIC_LONG_SLEEP) {
|
|
+ pthread_mutex_lock(&nic->nic_mutex);
|
|
+ if (nic->flags & NIC_LONG_SLEEP)
|
|
tv.tv_usec = 1000;
|
|
- } else {
|
|
+ else
|
|
tv.tv_usec = nic->rx_poll_usec;
|
|
- }
|
|
+ pthread_mutex_unlock(&nic->nic_mutex);
|
|
|
|
/* Wait for an interrupt to come in or timeout */
|
|
ret = select(nic->fd + 1, &fdset, NULL, NULL, &tv);
|
|
@@ -796,20 +780,20 @@ int nic_process_intr(nic_t * nic, int discard_check)
|
|
pthread_mutex_lock(&nic->nic_mutex);
|
|
if (ret > 0) {
|
|
nic->stats.interrupts++;
|
|
- LOG_DEBUG(PFX "%s: interrupt count: %d prev: %d",
|
|
- nic->log_name, count, nic->intr_count);
|
|
+ LOG_PACKET(PFX "%s: interrupt count: %d prev: %d",
|
|
+ nic->log_name, count, nic->intr_count);
|
|
|
|
if (count == nic->intr_count) {
|
|
- LOG_WARN(PFX "%s: got interrupt but count still the "
|
|
- "same", nic->log_name, count);
|
|
+ LOG_PACKET(PFX "%s: got interrupt but count still the "
|
|
+ "same", nic->log_name, count);
|
|
}
|
|
|
|
/* Check if we missed an interrupt. With UIO,
|
|
* the count should be incremental */
|
|
if (count != nic->intr_count + 1) {
|
|
nic->stats.missed_interrupts++;
|
|
- LOG_DEBUG(PFX "%s: Missed interrupt! on %d not %d",
|
|
- nic->log_name, count, nic->intr_count);
|
|
+ LOG_PACKET(PFX "%s: Missed interrupt! on %d not %d",
|
|
+ nic->log_name, count, nic->intr_count);
|
|
}
|
|
|
|
nic->intr_count = count;
|
|
@@ -833,9 +817,14 @@ static void prepare_ipv4_packet(nic_t * nic,
|
|
int queue_rc;
|
|
int vlan_id = 0;
|
|
|
|
- if (nic_iface->vlan_id && !(NIC_VLAN_STRIP_ENABLED & nic->flags))
|
|
- vlan_id = nic_iface->vlan_id;
|
|
-
|
|
+ /* If the rx vlan tag is not stripped and vlan is present in the pkt,
|
|
+ manual stripping is required because tx is using hw vlan tag! */
|
|
+ if (pkt->network_layer == pkt->data_link_layer +
|
|
+ sizeof(struct uip_vlan_eth_hdr)) {
|
|
+ /* VLAN is detected in the pkt buf */
|
|
+ memcpy(pkt->data_link_layer + 12, pkt->network_layer - 2,
|
|
+ pkt->buf_size - sizeof(struct uip_vlan_eth_hdr) + 2);
|
|
+ }
|
|
dest_ipv4_addr = uip_determine_dest_ipv4_addr(ustack, ipaddr);
|
|
if (dest_ipv4_addr == LOCAL_BROADCAST) {
|
|
uip_build_eth_header(ustack, ipaddr, NULL, pkt, vlan_id);
|
|
@@ -867,9 +856,12 @@ static void prepare_ipv6_packet(nic_t * nic,
|
|
struct uip_vlan_eth_hdr *eth_vlan;
|
|
int vlan_id = 0;
|
|
|
|
- if (nic_iface->vlan_id && !(NIC_VLAN_STRIP_ENABLED & nic->flags))
|
|
- vlan_id = nic_iface->vlan_id;
|
|
-
|
|
+ if (pkt->network_layer == pkt->data_link_layer +
|
|
+ sizeof(struct uip_vlan_eth_hdr)) {
|
|
+ /* VLAN is detected in the pkt buf */
|
|
+ memcpy(pkt->data_link_layer + 12, pkt->network_layer - 2,
|
|
+ pkt->buf_size - sizeof(struct uip_vlan_eth_hdr) + 2);
|
|
+ }
|
|
eth = (struct uip_eth_hdr *)ustack->data_link_layer;
|
|
eth_vlan = (struct uip_vlan_eth_hdr *)ustack->data_link_layer;
|
|
if (vlan_id == 0) {
|
|
@@ -897,96 +889,96 @@ static void prepare_ustack(nic_t * nic,
|
|
* there is a VLAN tag or not, or if the hardware
|
|
* has stripped out the
|
|
* VLAN tag */
|
|
- if ((nic_iface->vlan_id == 0) || (NIC_VLAN_STRIP_ENABLED & nic->flags)) {
|
|
- ustack->network_layer = ustack->data_link_layer +
|
|
- sizeof(struct uip_eth_hdr);
|
|
- } else {
|
|
- ustack->network_layer = ustack->data_link_layer +
|
|
- sizeof(struct uip_vlan_eth_hdr);
|
|
- }
|
|
+ ustack->network_layer = ustack->data_link_layer +
|
|
+ sizeof(struct uip_eth_hdr);
|
|
/* Init buffer to be IPv6 */
|
|
if (nic_iface->ustack.ip_config == IPV6_CONFIG_DHCP ||
|
|
nic_iface->ustack.ip_config == IPV6_CONFIG_STATIC) {
|
|
eth = (struct ether_header *)ustack->data_link_layer;
|
|
- eth->ether_type = UIP_ETHTYPE_IPv6;
|
|
+ eth->ether_type = htons(UIP_ETHTYPE_IPv6);
|
|
}
|
|
}
|
|
|
|
-static int check_timers(nic_t * nic,
|
|
- struct timer *periodic_timer, struct timer *arp_timer)
|
|
+int do_timers_per_nic_iface(nic_t *nic, nic_interface_t *nic_iface,
|
|
+ struct timer *arp_timer)
|
|
{
|
|
- if (timer_expired(periodic_timer)) {
|
|
- int i;
|
|
- nic_interface_t *current;
|
|
-
|
|
- timer_reset(periodic_timer);
|
|
+ packet_t *pkt;
|
|
+ struct uip_stack *ustack = &nic_iface->ustack;
|
|
+ int i;
|
|
|
|
- pthread_mutex_lock(&nic->nic_mutex);
|
|
+ pkt = get_next_free_packet(nic);
|
|
+ if (pkt == NULL)
|
|
+ return -EIO;
|
|
|
|
- current = nic->nic_iface;
|
|
- while (current != NULL) {
|
|
- packet_t *pkt;
|
|
- struct uip_stack *ustack = ¤t->ustack;
|
|
+ if (nic_iface->ustack.ip_config == AF_INET) {
|
|
+ for (i = 0; i < UIP_UDP_CONNS; i++) {
|
|
+ prepare_ustack(nic, nic_iface, ustack, pkt);
|
|
|
|
- pkt = get_next_free_packet(nic);
|
|
- if (pkt == NULL) {
|
|
- current = current->next;
|
|
- continue;
|
|
+ uip_udp_periodic(ustack, i);
|
|
+ /* If the above function invocation resulted
|
|
+ * in data that should be sent out on the
|
|
+ * network, the global variable uip_len is
|
|
+ * set to a value > 0. */
|
|
+ if (ustack->uip_len > 0) {
|
|
+ pkt->buf_size = ustack->uip_len;
|
|
+ prepare_ipv4_packet(nic, nic_iface, ustack,
|
|
+ pkt);
|
|
+ (*nic->ops->write) (nic, nic_iface, pkt);
|
|
+ ustack->uip_len = 0;
|
|
}
|
|
-
|
|
- for (i = 0; i < UIP_UDP_CONNS; i++) {
|
|
- prepare_ustack(nic, current, ustack, pkt);
|
|
-
|
|
- uip_udp_periodic(ustack, i);
|
|
- /* If the above function invocation resulted
|
|
- * in data that should be sent out on the
|
|
- * network, the global variable uip_len is
|
|
- * set to a value > 0. */
|
|
- if (ustack->uip_len > 0) {
|
|
- pkt->buf_size = ustack->uip_len;
|
|
-
|
|
- prepare_ipv4_packet(nic,
|
|
- current,
|
|
- ustack, pkt);
|
|
-
|
|
- (*nic->ops->write) (nic, current, pkt);
|
|
- ustack->uip_len = 0;
|
|
- }
|
|
+ }
|
|
+ } else {
|
|
+ /* Added periodic poll for IPv6 NDP engine */
|
|
+ if (ustack->ndpc != NULL) { /* If engine is active */
|
|
+ prepare_ustack(nic, nic_iface, ustack, pkt);
|
|
+
|
|
+ uip_ndp_periodic(ustack);
|
|
+ /* If the above function invocation resulted
|
|
+ * in data that should be sent out on the
|
|
+ * network, the global variable uip_len is
|
|
+ * set to a value > 0. */
|
|
+ if (ustack->uip_len > 0) {
|
|
+ pkt->buf_size = ustack->uip_len;
|
|
+ prepare_ipv6_packet(nic, nic_iface, ustack,
|
|
+ pkt);
|
|
+ (*nic->ops->write) (nic, nic_iface, pkt);
|
|
+ ustack->uip_len = 0;
|
|
}
|
|
+ }
|
|
+ }
|
|
+ /* Call the ARP timer function every 10 seconds. */
|
|
+ if (timer_expired(arp_timer)) {
|
|
+ timer_reset(arp_timer);
|
|
+ uip_arp_timer();
|
|
+ }
|
|
+ put_packet_in_free_queue(pkt, nic);
|
|
+ return 0;
|
|
+}
|
|
|
|
- /* Added periodic poll for IPv6 NDP engine */
|
|
- if (ustack->ndpc != NULL) { /* If engine is active */
|
|
- prepare_ustack(nic, current, ustack, pkt);
|
|
-
|
|
- uip_ndp_periodic(ustack);
|
|
- /* If the above function invocation resulted
|
|
- * in data that should be sent out on the
|
|
- * network, the global variable uip_len is
|
|
- * set to a value > 0. */
|
|
- if (ustack->uip_len > 0) {
|
|
- pkt->buf_size = ustack->uip_len;
|
|
- prepare_ipv6_packet(nic,
|
|
- current,
|
|
- ustack, pkt);
|
|
- (*nic->ops->write) (nic, current, pkt);
|
|
- ustack->uip_len = 0;
|
|
- }
|
|
- }
|
|
+static int check_timers(nic_t *nic,
|
|
+ struct timer *periodic_timer, struct timer *arp_timer)
|
|
+{
|
|
+ if (timer_expired(periodic_timer)) {
|
|
+ nic_interface_t *nic_iface, *vlan_iface;
|
|
|
|
- /* Call the ARP timer function every 10 seconds. */
|
|
- if (timer_expired(arp_timer)) {
|
|
- timer_reset(arp_timer);
|
|
- uip_arp_timer();
|
|
- }
|
|
+ timer_reset(periodic_timer);
|
|
|
|
- put_packet_in_free_queue(pkt, nic);
|
|
+ pthread_mutex_lock(&nic->nic_mutex);
|
|
|
|
- current = current->next;
|
|
+ nic_iface = nic->nic_iface;
|
|
+ while (nic_iface != NULL) {
|
|
+ do_timers_per_nic_iface(nic, nic_iface, arp_timer);
|
|
+ vlan_iface = nic_iface->vlan_next;
|
|
+ while (vlan_iface != NULL) {
|
|
+ do_timers_per_nic_iface(nic, vlan_iface,
|
|
+ arp_timer);
|
|
+ vlan_iface = vlan_iface->vlan_next;
|
|
+ }
|
|
+ nic_iface = nic_iface->next;
|
|
}
|
|
|
|
pthread_mutex_unlock(&nic->nic_mutex);
|
|
}
|
|
-
|
|
return 0;
|
|
}
|
|
|
|
@@ -1012,109 +1004,71 @@ int process_packets(nic_t * nic,
|
|
uint16_t type = 0;
|
|
int af_type = 0;
|
|
struct uip_stack *ustack;
|
|
- nic_interface_t *vlan_iface;
|
|
+ struct ip_hdr *ip;
|
|
+ pIPV6_HDR ip6;
|
|
+ void *dst_ip;
|
|
+ uint16_t vlan_id;
|
|
|
|
- if ((pkt->vlan_tag == 0) ||
|
|
+ pkt->data_link_layer = pkt->buf;
|
|
+
|
|
+ vlan_id = pkt->vlan_tag & 0xFFF;
|
|
+ if ((vlan_id == 0) ||
|
|
(NIC_VLAN_STRIP_ENABLED & nic->flags)) {
|
|
type = ntohs(ETH_BUF(pkt->buf)->type);
|
|
+ pkt->network_layer = pkt->data_link_layer +
|
|
+ sizeof(struct uip_eth_hdr);
|
|
} else {
|
|
type = ntohs(VLAN_ETH_BUF(pkt->buf)->type);
|
|
+ pkt->network_layer = pkt->data_link_layer +
|
|
+ sizeof(struct uip_vlan_eth_hdr);
|
|
}
|
|
|
|
switch (type) {
|
|
case UIP_ETHTYPE_IPv6:
|
|
af_type = AF_INET6;
|
|
+ ip6 = (pIPV6_HDR) pkt->network_layer;
|
|
+ dst_ip = (void *)&ip6->ipv6_dst;
|
|
break;
|
|
case UIP_ETHTYPE_IPv4:
|
|
- af_type = AF_INET;
|
|
- break;
|
|
case UIP_ETHTYPE_ARP:
|
|
af_type = AF_INET;
|
|
+ ip = (struct ip_hdr *) pkt->network_layer;
|
|
+ dst_ip = (void *)&ip->destipaddr;
|
|
break;
|
|
default:
|
|
- LOG_DEBUG(PFX "%s: Ignoring vlan:0x%x ethertype:0x%x",
|
|
- nic->log_name, pkt->vlan_tag, type);
|
|
+ LOG_PACKET(PFX "%s: Ignoring vlan:0x%x ethertype:0x%x",
|
|
+ nic->log_name, vlan_id, type);
|
|
goto done;
|
|
}
|
|
|
|
- /* check if we have the given VLAN interface */
|
|
- if (nic_iface == NULL) {
|
|
- nic_iface = nic_find_nic_iface_protocol(nic, 0,
|
|
- af_type);
|
|
- if (nic_iface == NULL) {
|
|
- LOG_INFO(PFX "%s: Couldn't find interface for "
|
|
- "VLAN: %d af_type %d creating it",
|
|
- nic->log_name, pkt->vlan_tag, af_type);
|
|
-
|
|
- /* Create the vlan interface */
|
|
- nic_iface = nic_iface_init();
|
|
-
|
|
- if (nic_iface == NULL) {
|
|
- LOG_WARN(PFX "%s: Couldn't "
|
|
- "allocate "
|
|
- "nic_iface for "
|
|
- "VLAN: %d af_type %d",
|
|
- nic->log_name, pkt->vlan_tag,
|
|
- af_type);
|
|
- rc = 0;
|
|
- goto done;
|
|
- }
|
|
-
|
|
- nic_iface->protocol = af_type;
|
|
- nic_iface->vlan_id = 0;
|
|
- nic_add_nic_iface(nic, nic_iface);
|
|
+ pthread_mutex_lock(&nic->nic_mutex);
|
|
|
|
- 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;
|
|
+ /* check if we have the given VLAN interface */
|
|
+ if (nic_iface != NULL) {
|
|
+ if (vlan_id != nic_iface->vlan_id) {
|
|
+ /* Matching nic_iface not found, drop */
|
|
+ pthread_mutex_unlock(&nic->nic_mutex);
|
|
+ rc = EINVAL; /* Return the +error code */
|
|
+ goto done;
|
|
}
|
|
+ goto nic_iface_present;
|
|
}
|
|
|
|
+ /* Best effort to find the correct instance
|
|
+ Input: protocol and vlan_tag */
|
|
+ nic_iface = nic_find_nic_iface(nic, af_type, vlan_id,
|
|
+ IFACE_NUM_INVALID,
|
|
+ IP_CONFIG_OFF);
|
|
+ if (nic_iface == NULL) {
|
|
+ /* Matching nic_iface not found */
|
|
+ pthread_mutex_unlock(&nic->nic_mutex);
|
|
+ LOG_PACKET(PFX "%s: Couldn't find interface for "
|
|
+ "VLAN: %d af_type %d",
|
|
+ nic->log_name, vlan_id, af_type);
|
|
+ rc = EINVAL; /* Return the +error code */
|
|
+ goto done;
|
|
+ }
|
|
+nic_iface_present:
|
|
pkt->nic_iface = nic_iface;
|
|
|
|
ustack = &nic_iface->ustack;
|
|
@@ -1123,27 +1077,17 @@ int process_packets(nic_t * nic,
|
|
ustack->uip_len = pkt->buf_size;
|
|
ustack->data_link_layer = pkt->buf;
|
|
|
|
- pkt->data_link_layer = pkt->buf;
|
|
-
|
|
/* Adjust the network layer pointer depending if there is a
|
|
* VLAN tag or not, or if the hardware has stripped out the
|
|
* VLAN tag */
|
|
- if ((pkt->vlan_tag == 0) ||
|
|
- (NIC_VLAN_STRIP_ENABLED & nic->flags)) {
|
|
+ if ((vlan_id == 0) ||
|
|
+ (NIC_VLAN_STRIP_ENABLED & nic->flags))
|
|
ustack->network_layer = ustack->data_link_layer +
|
|
sizeof(struct uip_eth_hdr);
|
|
- pkt->network_layer = pkt->data_link_layer +
|
|
- sizeof(struct uip_eth_hdr);
|
|
- type = ntohs(ETH_BUF(pkt->buf)->type);
|
|
- } else {
|
|
+ else
|
|
ustack->network_layer = ustack->data_link_layer +
|
|
sizeof(struct uip_vlan_eth_hdr);
|
|
- pkt->network_layer = pkt->data_link_layer +
|
|
- sizeof(struct uip_vlan_eth_hdr);
|
|
- type = ntohs(VLAN_ETH_BUF(pkt->buf)->type);
|
|
- }
|
|
|
|
- pthread_mutex_lock(&nic->nic_mutex);
|
|
/* determine how we should process this packet based on the
|
|
* ethernet type */
|
|
switch (type) {
|
|
@@ -1270,25 +1214,174 @@ static int process_dhcp_loop(nic_t * nic,
|
|
}
|
|
|
|
if (timercmp(&total_time, ¤t_time, <)) {
|
|
- LOG_ERR(PFX "%s: timeout waiting for DHCP",
|
|
+ LOG_ERR(PFX "%s: timeout waiting for DHCP/NDP",
|
|
nic->log_name);
|
|
+ if (nic_iface->ustack.ip_config == IPV6_CONFIG_DHCP ||
|
|
+ nic_iface->ustack.ip_config == IPV6_CONFIG_STATIC)
|
|
+ n->retry_count = IPV6_MAX_ROUTER_SOL_RETRY;
|
|
return -EIO;
|
|
}
|
|
}
|
|
|
|
if (nic->flags & NIC_GOING_DOWN)
|
|
return -EIO;
|
|
+ else if (nic->flags & NIC_DISABLED)
|
|
+ return -EINVAL;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
+/* Called with nic_mutex locked */
|
|
+static int do_acquisition(nic_t *nic, nic_interface_t *nic_iface,
|
|
+ struct timer *periodic_timer, struct timer *arp_timer)
|
|
+{
|
|
+ struct in_addr addr;
|
|
+ struct in6_addr addr6;
|
|
+ void *res;
|
|
+ char buf[INET6_ADDRSTRLEN];
|
|
+ int rc = -1;
|
|
+
|
|
+ /* New acquisition */
|
|
+ uip_init(&nic_iface->ustack, nic->flags & NIC_IPv6_ENABLED);
|
|
+ memcpy(&nic_iface->ustack.uip_ethaddr.addr, nic->mac_addr, ETH_ALEN);
|
|
+
|
|
+ LOG_INFO(PFX "%s: Initialized ip stack: VLAN: %d",
|
|
+ nic->log_name, nic_iface->vlan_id);
|
|
+
|
|
+ LOG_INFO(PFX "%s: mac: %02x:%02x:%02x:%02x:%02x:%02x",
|
|
+ nic->log_name,
|
|
+ nic_iface->mac_addr[0],
|
|
+ nic_iface->mac_addr[1],
|
|
+ nic_iface->mac_addr[2],
|
|
+ nic_iface->mac_addr[3],
|
|
+ nic_iface->mac_addr[4],
|
|
+ nic_iface->mac_addr[5]);
|
|
+
|
|
+ switch (nic_iface->ustack.ip_config) {
|
|
+ case IPV4_CONFIG_STATIC:
|
|
+ memcpy(&addr.s_addr, nic_iface->ustack.hostaddr,
|
|
+ sizeof(addr.s_addr));
|
|
+
|
|
+ LOG_INFO(PFX "%s: Using IP address: %s",
|
|
+ nic->log_name, inet_ntoa(addr));
|
|
+
|
|
+ memcpy(&addr.s_addr, nic_iface->ustack.netmask,
|
|
+ sizeof(addr.s_addr));
|
|
+
|
|
+ LOG_INFO(PFX "%s: Using netmask: %s",
|
|
+ nic->log_name, inet_ntoa(addr));
|
|
+
|
|
+ set_uip_stack(&nic_iface->ustack,
|
|
+ &nic_iface->ustack.hostaddr,
|
|
+ &nic_iface->ustack.netmask,
|
|
+ &nic_iface->ustack.default_route_addr,
|
|
+ nic_iface->mac_addr);
|
|
+ break;
|
|
+
|
|
+ case IPV4_CONFIG_DHCP:
|
|
+ set_uip_stack(&nic_iface->ustack,
|
|
+ &nic_iface->ustack.hostaddr,
|
|
+ &nic_iface->ustack.netmask,
|
|
+ &nic_iface->ustack.default_route_addr,
|
|
+ nic_iface->mac_addr);
|
|
+ if (dhcpc_init(nic, &nic_iface->ustack,
|
|
+ nic_iface->mac_addr, ETH_ALEN)) {
|
|
+ if (nic_iface->ustack.dhcpc) {
|
|
+ LOG_DEBUG(PFX "%s: DHCPv4 engine already "
|
|
+ "initialized!", nic->log_name);
|
|
+ goto skip;
|
|
+ } else {
|
|
+ LOG_DEBUG(PFX "%s: DHCPv4 engine failed "
|
|
+ "initialization!", nic->log_name);
|
|
+ goto error;
|
|
+ }
|
|
+ }
|
|
+ pthread_mutex_unlock(&nic->nic_mutex);
|
|
+ rc = process_dhcp_loop(nic, nic_iface, periodic_timer,
|
|
+ arp_timer);
|
|
+ pthread_mutex_lock(&nic->nic_mutex);
|
|
+
|
|
+ if (rc) {
|
|
+ LOG_ERR(PFX "%s: DHCP failed", nic->log_name);
|
|
+ /* For DHCPv4 failure, the ustack must be cleaned so
|
|
+ it can re-acquire on the next iscsid request */
|
|
+ uip_reset(&nic_iface->ustack);
|
|
+
|
|
+ /* Signal that the device enable is
|
|
+ done */
|
|
+ pthread_cond_broadcast(&nic->enable_done_cond);
|
|
+ pthread_mutex_unlock(&nic->nic_mutex);
|
|
+
|
|
+ if (nic->enable_thread == INVALID_THREAD)
|
|
+ goto dhcp_err;
|
|
+
|
|
+ rc = pthread_join(nic->enable_thread, &res);
|
|
+ if (rc != 0)
|
|
+ LOG_ERR(PFX "%s: Couldn't join to canceled "
|
|
+ "enable nic thread", nic->log_name);
|
|
+dhcp_err:
|
|
+ pthread_mutex_lock(&nic->nic_mutex);
|
|
+ goto error;
|
|
+ }
|
|
+
|
|
+ if (nic->flags & NIC_DISABLED) {
|
|
+ /* Break out of this loop */
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ LOG_INFO(PFX "%s: Initialized dhcp client", nic->log_name);
|
|
+ break;
|
|
+
|
|
+ case IPV6_CONFIG_DHCP:
|
|
+ case IPV6_CONFIG_STATIC:
|
|
+ if (ndpc_init(nic, &nic_iface->ustack, nic_iface->mac_addr,
|
|
+ ETH_ALEN)) {
|
|
+ LOG_DEBUG(PFX "%s: IPv6 engine already initialized!",
|
|
+ nic->log_name);
|
|
+ goto skip;
|
|
+ }
|
|
+ pthread_mutex_unlock(&nic->nic_mutex);
|
|
+ rc = process_dhcp_loop(nic, nic_iface, periodic_timer,
|
|
+ arp_timer);
|
|
+ pthread_mutex_lock(&nic->nic_mutex);
|
|
+ if (rc) {
|
|
+ /* Don't reset and allow to use RA and LL */
|
|
+ LOG_ERR(PFX "%s: IPv6 DHCP/NDP failed", nic->log_name);
|
|
+ }
|
|
+ if (nic_iface->ustack.ip_config == IPV6_CONFIG_STATIC) {
|
|
+ memcpy(&addr6.s6_addr, nic_iface->ustack.hostaddr6,
|
|
+ sizeof(addr6.s6_addr));
|
|
+ inet_ntop(AF_INET6, addr6.s6_addr, buf, sizeof(buf));
|
|
+ LOG_INFO(PFX "%s: hostaddr IP: %s", nic->log_name, buf);
|
|
+ memcpy(&addr6.s6_addr, nic_iface->ustack.netmask6,
|
|
+ sizeof(addr6.s6_addr));
|
|
+ inet_ntop(AF_INET6, addr6.s6_addr, buf, sizeof(buf));
|
|
+ LOG_INFO(PFX "%s: netmask IP: %s", nic->log_name, buf);
|
|
+ }
|
|
+ break;
|
|
+
|
|
+ default:
|
|
+ LOG_INFO(PFX "%s: ipconfig = %d?", nic->log_name,
|
|
+ nic_iface->ustack.ip_config);
|
|
+ }
|
|
+skip:
|
|
+ /* Mark acquisition done for this nic iface */
|
|
+ nic_iface->flags &= ~NIC_IFACE_ACQUIRE;
|
|
+
|
|
+ LOG_INFO(PFX "%s: enabled vlan %d protocol: %d", nic->log_name,
|
|
+ nic_iface->vlan_id, nic_iface->protocol);
|
|
+ return 0;
|
|
+
|
|
+error:
|
|
+ return -EIO;
|
|
+}
|
|
+
|
|
void *nic_loop(void *arg)
|
|
{
|
|
nic_t *nic = (nic_t *) arg;
|
|
int rc = -1;
|
|
- struct timer periodic_timer, arp_timer;
|
|
sigset_t set;
|
|
- void *res;
|
|
+ struct timer periodic_timer, arp_timer;
|
|
|
|
sigfillset(&set);
|
|
rc = pthread_sigmask(SIG_BLOCK, &set, NULL);
|
|
@@ -1302,10 +1395,11 @@ void *nic_loop(void *arg)
|
|
pthread_mutex_lock(&nic->nic_mutex);
|
|
pthread_cond_signal(&nic->nic_loop_started_cond);
|
|
|
|
+ /* nic_mutex must be locked */
|
|
while ((event_loop_stop == 0) &&
|
|
!(nic->flags & NIC_EXIT_MAIN_LOOP) &&
|
|
!(nic->flags & NIC_GOING_DOWN)) {
|
|
- nic_interface_t *nic_iface;
|
|
+ nic_interface_t *nic_iface, *vlan_iface;
|
|
|
|
if (nic->flags & NIC_DISABLED) {
|
|
LOG_DEBUG(PFX "%s: Waiting to be enabled",
|
|
@@ -1322,8 +1416,6 @@ void *nic_loop(void *arg)
|
|
}
|
|
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);
|
|
if (rc != 0) {
|
|
@@ -1331,18 +1423,17 @@ void *nic_loop(void *arg)
|
|
nic->log_name);
|
|
|
|
if (rc == -ENOTSUP)
|
|
- nic->flags &= NIC_EXIT_MAIN_LOOP;
|
|
+ nic->flags |= NIC_EXIT_MAIN_LOOP;
|
|
else
|
|
nic->flags &= ~NIC_ENABLED;
|
|
|
|
/* Signal that the device enable is done */
|
|
pthread_cond_broadcast(&nic->enable_done_cond);
|
|
pthread_mutex_unlock(&nic->nic_mutex);
|
|
-
|
|
goto dev_close;
|
|
}
|
|
-
|
|
nic_set_all_nic_iface_mac_to_parent(nic);
|
|
+ pthread_mutex_unlock(&nic->nic_mutex);
|
|
|
|
rc = alloc_free_queue(nic, 5);
|
|
if (rc != 5) {
|
|
@@ -1354,13 +1445,12 @@ void *nic_loop(void *arg)
|
|
"instead of %d", nic->log_name, 5);
|
|
/* Signal that the device enable is done */
|
|
pthread_cond_broadcast(&nic->enable_done_cond);
|
|
- pthread_mutex_unlock(&nic->nic_mutex);
|
|
goto dev_close;
|
|
}
|
|
}
|
|
/* Indication for the nic_disable routine that the nic
|
|
has started running */
|
|
- nic->state |= NIC_STARTED_RUNNING;
|
|
+ nic->state = NIC_STARTED_RUNNING;
|
|
|
|
/* Initialize the system clocks */
|
|
timer_set(&periodic_timer, CLOCK_SECOND / 2);
|
|
@@ -1369,192 +1459,25 @@ void *nic_loop(void *arg)
|
|
/* Prepare the stack for each of the VLAN interfaces */
|
|
pthread_mutex_lock(&nic->nic_mutex);
|
|
|
|
+ /* If DHCP fails, exit loop and restart the engine */
|
|
nic_iface = nic->nic_iface;
|
|
while (nic_iface != NULL) {
|
|
- uip_init(&nic_iface->ustack,
|
|
- nic->flags & NIC_IPv6_ENABLED);
|
|
- memcpy(&nic_iface->ustack.uip_ethaddr.addr,
|
|
- nic->mac_addr, 6);
|
|
-
|
|
- LOG_INFO(PFX "%s: Initialized ip stack: VLAN: %d",
|
|
- nic->log_name, nic_iface->vlan_id);
|
|
-
|
|
- LOG_INFO(PFX "%s: mac: %02x:%02x:%02x:%02x:%02x:%02x",
|
|
- nic->log_name,
|
|
- nic_iface->mac_addr[0],
|
|
- nic_iface->mac_addr[1],
|
|
- nic_iface->mac_addr[2],
|
|
- nic_iface->mac_addr[3],
|
|
- nic_iface->mac_addr[4],
|
|
- nic_iface->mac_addr[5]);
|
|
-
|
|
- if (nic_iface->ustack.ip_config == IPV4_CONFIG_STATIC) {
|
|
- struct in_addr addr;
|
|
- uip_ip4addr_t tmp = { 0, 0 };
|
|
-
|
|
- memcpy(&addr.s_addr, nic_iface->ustack.hostaddr,
|
|
- sizeof(addr.s_addr));
|
|
-
|
|
- LOG_INFO(PFX "%s: Using IP address: %s",
|
|
- nic->log_name, inet_ntoa(addr));
|
|
-
|
|
- memcpy(&addr.s_addr, nic_iface->ustack.netmask,
|
|
- sizeof(addr.s_addr));
|
|
-
|
|
- LOG_INFO(PFX "%s: Using netmask: %s",
|
|
- nic->log_name, inet_ntoa(addr));
|
|
-
|
|
- set_uip_stack(&nic_iface->ustack,
|
|
- &nic_iface->ustack.hostaddr,
|
|
- &nic_iface->ustack.netmask,
|
|
- &tmp, nic_iface->mac_addr);
|
|
-
|
|
- } else if (nic_iface->ustack.ip_config ==
|
|
- IPV4_CONFIG_DHCP) {
|
|
- struct uip_stack *ustack = &nic_iface->ustack;
|
|
- uip_ip4addr_t tmp = { 0, 0 };
|
|
-
|
|
- set_uip_stack(&nic_iface->ustack,
|
|
- &nic_iface->ustack.hostaddr,
|
|
- &nic_iface->ustack.netmask,
|
|
- &tmp, nic_iface->mac_addr);
|
|
- if (dhcpc_init(nic, ustack,
|
|
- nic_iface->mac_addr, ETH_ALEN)) {
|
|
- if (ustack->dhcpc) {
|
|
- LOG_DEBUG(PFX "%s: DHCPv4 "
|
|
- "engine already "
|
|
- "initialized!",
|
|
- nic->log_name);
|
|
- goto skip;
|
|
- } else {
|
|
- LOG_DEBUG(PFX "%s: DHCPv4 "
|
|
- "engine failed "
|
|
- "initialization!",
|
|
- nic->log_name);
|
|
- goto dev_close_free;
|
|
- }
|
|
- }
|
|
- pthread_mutex_unlock(&nic->nic_mutex);
|
|
- rc = process_dhcp_loop(nic, nic_iface,
|
|
+ if (nic_iface->flags & NIC_IFACE_ACQUIRE) {
|
|
+ do_acquisition(nic, nic_iface,
|
|
+ &periodic_timer,
|
|
+ &arp_timer);
|
|
+ }
|
|
+ vlan_iface = nic_iface->vlan_next;
|
|
+ while (vlan_iface != NULL) {
|
|
+ if (vlan_iface->flags & NIC_IFACE_ACQUIRE) {
|
|
+ do_acquisition(nic, vlan_iface,
|
|
&periodic_timer,
|
|
&arp_timer);
|
|
- pthread_mutex_lock(&nic->nic_mutex);
|
|
-
|
|
- if (rc) {
|
|
- LOG_ERR(PFX "%s: DHCP failed",
|
|
- nic->log_name);
|
|
- nic->flags |= NIC_DISABLED |
|
|
- NIC_RESET_UIP;
|
|
- nic->flags &= ~NIC_ENABLED;
|
|
- /* Signal that the device enable is
|
|
- done */
|
|
- pthread_cond_broadcast(
|
|
- &nic->enable_done_cond);
|
|
-
|
|
- pthread_mutex_unlock(&nic->nic_mutex);
|
|
-
|
|
- if (nic->enable_thread ==
|
|
- INVALID_THREAD)
|
|
- goto dev_close_free;
|
|
-
|
|
- rc = pthread_join(nic->enable_thread,
|
|
- &res);
|
|
- if (rc != 0)
|
|
- LOG_ERR(PFX "%s: Couldn't join "
|
|
- "to canceled enable nic"
|
|
- " thread",
|
|
- nic->log_name);
|
|
-
|
|
- goto dev_close_free;
|
|
}
|
|
-
|
|
- if (nic->flags & NIC_DISABLED) {
|
|
- pthread_mutex_unlock(&nic->nic_mutex);
|
|
- break;
|
|
- }
|
|
-
|
|
- LOG_INFO(PFX "%s: Initialized dhcp client",
|
|
- nic->log_name);
|
|
- } else if (nic_iface->ustack.ip_config ==
|
|
- IPV6_CONFIG_DHCP ||
|
|
- nic_iface->ustack.ip_config ==
|
|
- IPV6_CONFIG_STATIC) {
|
|
- struct in6_addr addr6;
|
|
- char buf[INET6_ADDRSTRLEN];
|
|
-
|
|
- /* Do router solicitation for both STATIC and
|
|
- DHCP - all NDP handling will take place in
|
|
- the DHCP loop
|
|
- STATIC - router advertisement will be handled
|
|
- in the uip background loop
|
|
- */
|
|
- if (ndpc_init(nic, &nic_iface->ustack,
|
|
- nic_iface->mac_addr, ETH_ALEN)) {
|
|
- LOG_DEBUG(PFX "%s: IPv6 engine already"
|
|
- "initialized!",
|
|
- nic->log_name);
|
|
- goto skip;
|
|
- }
|
|
- if (nic_iface->ustack.ip_config ==
|
|
- IPV6_CONFIG_DHCP) {
|
|
- pthread_mutex_unlock(&nic->nic_mutex);
|
|
- rc = process_dhcp_loop(nic, nic_iface,
|
|
- &periodic_timer,
|
|
- &arp_timer);
|
|
- pthread_mutex_lock(&nic->nic_mutex);
|
|
- if (rc) {
|
|
- /* Don't reset and allow to
|
|
- use RA and LL */
|
|
- LOG_ERR(PFX "%s: DHCPv6 failed",
|
|
- nic->log_name);
|
|
- }
|
|
- if (nic->flags & NIC_DISABLED) {
|
|
- pthread_mutex_unlock(&nic->
|
|
- nic_mutex);
|
|
- break;
|
|
- }
|
|
- } else {
|
|
- pthread_mutex_unlock(&nic->nic_mutex);
|
|
- rc = process_dhcp_loop(nic, nic_iface,
|
|
- &periodic_timer,
|
|
- &arp_timer);
|
|
- pthread_mutex_lock(&nic->nic_mutex);
|
|
- if (rc) {
|
|
- LOG_ERR(PFX "%s: IPv6 rtr "
|
|
- "failed",
|
|
- nic->log_name);
|
|
- }
|
|
- memcpy(&addr6.s6_addr,
|
|
- nic_iface->ustack.hostaddr6,
|
|
- sizeof(addr6.s6_addr));
|
|
- inet_ntop(AF_INET6,
|
|
- addr6.s6_addr,
|
|
- buf, sizeof(buf));
|
|
- LOG_INFO(PFX "%s: hostaddr IP: %s",
|
|
- nic->log_name, buf);
|
|
-
|
|
- memcpy(&addr6.s6_addr,
|
|
- nic_iface->ustack.netmask6,
|
|
- sizeof(addr6.s6_addr));
|
|
- inet_ntop(AF_INET6,
|
|
- addr6.s6_addr,
|
|
- buf, sizeof(buf));
|
|
- LOG_INFO(PFX "%s: netmask IP: %s",
|
|
- nic->log_name, buf);
|
|
- }
|
|
- } else {
|
|
- LOG_INFO(PFX "%s: ipconfig = %d?",
|
|
- nic->log_name,
|
|
- nic_iface->ustack.ip_config);
|
|
+ vlan_iface = vlan_iface->next;
|
|
}
|
|
-skip:
|
|
- LOG_INFO(PFX "%s: enabled vlan %d protocol: %d",
|
|
- nic->log_name,
|
|
- nic_iface->vlan_id, nic_iface->protocol);
|
|
-
|
|
- nic_iface = nic_iface->vlan_next;
|
|
+ nic_iface = nic_iface->next;
|
|
}
|
|
-
|
|
if (nic->flags & NIC_DISABLED) {
|
|
LOG_WARN(PFX "%s: nic was disabled during nic loop, "
|
|
"closing flag 0x%x",
|
|
@@ -1567,10 +1490,7 @@ skip:
|
|
|
|
/* This is when we start the processing of packets */
|
|
nic->start_time = time(NULL);
|
|
- nic->flags &= ~NIC_UNITIALIZED;
|
|
- nic->flags |= NIC_INITIALIZED;
|
|
- nic->state &= ~NIC_STOPPED;
|
|
- nic->state |= NIC_RUNNING;
|
|
+ nic->state = NIC_RUNNING;
|
|
|
|
nic->flags &= ~NIC_ENABLED_PENDING;
|
|
|
|
@@ -1580,14 +1500,14 @@ skip:
|
|
|
|
LOG_INFO(PFX "%s: entering main nic loop", nic->log_name);
|
|
|
|
- while ((nic->state & NIC_RUNNING) &&
|
|
+ while ((nic->state == NIC_RUNNING) &&
|
|
(event_loop_stop == 0) &&
|
|
!(nic->flags & NIC_GOING_DOWN)) {
|
|
/* Check the periodic and ARP timer */
|
|
check_timers(nic, &periodic_timer, &arp_timer);
|
|
rc = nic_process_intr(nic, 0);
|
|
while ((rc > 0) &&
|
|
- (nic->state & NIC_RUNNING) &&
|
|
+ (nic->state == NIC_RUNNING) &&
|
|
!(nic->flags & NIC_GOING_DOWN)) {
|
|
rc = process_packets(nic,
|
|
&periodic_timer,
|
|
@@ -1609,33 +1529,7 @@ dev_close:
|
|
} 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;
|
|
- }
|
|
}
|
|
-
|
|
- nic->flags |= NIC_UNITIALIZED;
|
|
- nic->flags &= ~NIC_INITIALIZED;
|
|
- nic->flags &= ~NIC_ENABLED_PENDING;
|
|
-
|
|
nic->pending_count = 0;
|
|
|
|
if (!(nic->flags & NIC_EXIT_MAIN_LOOP)) {
|
|
@@ -1643,6 +1537,9 @@ dev_close:
|
|
pthread_cond_broadcast(&nic->disable_wait_cond);
|
|
}
|
|
}
|
|
+ /* clean up the nic flags */
|
|
+ nic->flags &= ~NIC_ENABLED_PENDING;
|
|
+
|
|
pthread_mutex_unlock(&nic->nic_mutex);
|
|
|
|
LOG_INFO(PFX "%s: nic loop thread exited", nic->log_name);
|
|
diff --git a/iscsiuio/src/unix/nic.h b/iscsiuio/src/unix/nic.h
|
|
index 57d89b4..da900c5 100644
|
|
--- a/iscsiuio/src/unix/nic.h
|
|
+++ b/iscsiuio/src/unix/nic.h
|
|
@@ -67,6 +67,8 @@ extern struct nic_lib_handle *nic_lib_list;
|
|
extern pthread_mutex_t nic_list_mutex;
|
|
extern struct nic *nic_list;
|
|
|
|
+extern void *nl_process_handle_thread(void *arg);
|
|
+
|
|
/*******************************************************************************
|
|
* Constants
|
|
******************************************************************************/
|
|
@@ -117,20 +119,30 @@ struct nic_stats {
|
|
* NIC interface structure
|
|
******************************************************************************/
|
|
typedef struct nic_interface {
|
|
+ struct nic_interface *vlan_next;
|
|
struct nic_interface *next;
|
|
struct nic *parent;
|
|
|
|
uint16_t protocol;
|
|
uint16_t flags;
|
|
-#define NIC_IFACE_PERSIST 0x0001
|
|
+#define NIC_IFACE_PERSIST (1<<0)
|
|
+#define NIC_IFACE_ACQUIRE (1<<1)
|
|
+#define NIC_IFACE_PATHREQ_WAIT1 (1<<2)
|
|
+#define NIC_IFACE_PATHREQ_WAIT2 (1<<3)
|
|
+#define NIC_IFACE_PATHREQ_WAIT (NIC_IFACE_PATHREQ_WAIT1 | \
|
|
+ NIC_IFACE_PATHREQ_WAIT2)
|
|
uint8_t mac_addr[ETH_ALEN];
|
|
uint8_t vlan_priority;
|
|
uint16_t vlan_id;
|
|
+#define NO_VLAN 0x8000
|
|
|
|
+ uint16_t mtu;
|
|
time_t start_time;
|
|
|
|
struct uip_stack ustack;
|
|
- struct nic_interface *vlan_next;
|
|
+
|
|
+ int iface_num;
|
|
+ int request_type;
|
|
} nic_interface_t;
|
|
|
|
/******************************************************************************
|
|
@@ -178,8 +190,9 @@ typedef struct nic_ops {
|
|
int (*clear_tx_intr) (struct nic *);
|
|
int (*handle_iscsi_path_req) (struct nic *,
|
|
int,
|
|
- struct iscsi_uevent * ev,
|
|
- struct iscsi_path * path);
|
|
+ struct iscsi_uevent *ev,
|
|
+ struct iscsi_path *path,
|
|
+ nic_interface_t *nic_iface);
|
|
} net_ops_t;
|
|
|
|
typedef struct nic_lib_handle {
|
|
@@ -199,6 +212,9 @@ typedef struct nic {
|
|
#define NIC_DISABLED 0x0008
|
|
#define NIC_IPv6_ENABLED 0x0010
|
|
#define NIC_ADDED_MULICAST 0x0020
|
|
+#define NIC_LONG_SLEEP 0x0040
|
|
+#define NIC_PATHREQ_WAIT 0x0080
|
|
+
|
|
#define NIC_VLAN_STRIP_ENABLED 0x0100
|
|
#define NIC_MSIX_ENABLED 0x0200
|
|
#define NIC_TX_HAS_SENT 0x0400
|
|
@@ -214,7 +230,6 @@ typedef struct nic {
|
|
#define NIC_STOPPED 0x0001
|
|
#define NIC_STARTED_RUNNING 0x0002
|
|
#define NIC_RUNNING 0x0004
|
|
-#define NIC_LONG_SLEEP 0x0008
|
|
#define NIC_EXIT 0x0010
|
|
|
|
int fd; /* Holds the file descriptor to UIO */
|
|
@@ -232,6 +247,7 @@ typedef struct nic {
|
|
|
|
uint32_t intr_count; /* Total UIO interrupt count */
|
|
|
|
+ /* Held for nic ops manipulation */
|
|
pthread_mutex_t nic_mutex;
|
|
|
|
/* iSCSI ring ethernet MAC address */
|
|
@@ -268,6 +284,7 @@ typedef struct nic {
|
|
|
|
/* Number of retrys from iscsid */
|
|
uint32_t pending_count;
|
|
+ uint32_t pathreq_pending_count;
|
|
|
|
#define DEFAULT_RX_POLL_USEC 100 /* usec */
|
|
/* options enabled by the user */
|
|
@@ -295,6 +312,19 @@ typedef struct nic {
|
|
int (*process_intr) (struct nic * nic);
|
|
|
|
struct nic_ops *ops;
|
|
+
|
|
+ /* NL processing parameters */
|
|
+ pthread_t nl_process_thread;
|
|
+ pthread_cond_t nl_process_cond;
|
|
+ pthread_cond_t nl_process_if_down_cond;
|
|
+ pthread_mutex_t nl_process_mutex;
|
|
+ int nl_process_if_down;
|
|
+ int nl_process_head;
|
|
+ int nl_process_tail;
|
|
+#define NIC_NL_PROCESS_MAX_RING_SIZE 128
|
|
+#define NIC_NL_PROCESS_LAST_ENTRY (NIC_NL_PROCESS_MAX_RING_SIZE - 1)
|
|
+#define NIC_NL_PROCESS_NEXT_ENTRY(x) ((x + 1) & NIC_NL_PROCESS_MAX_RING_SIZE)
|
|
+ void *nl_process_ring[NIC_NL_PROCESS_MAX_RING_SIZE];
|
|
} nic_t;
|
|
|
|
/******************************************************************************
|
|
@@ -307,8 +337,6 @@ 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_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();
|
|
@@ -339,14 +367,6 @@ int enable_multicast(nic_t * nic);
|
|
int disable_multicast(nic_t * nic);
|
|
|
|
void nic_set_all_nic_iface_mac_to_parent(nic_t * nic);
|
|
-struct nic_interface *nic_find_nic_iface(nic_t * nic, uint16_t vlan_id);
|
|
-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 --git a/iscsiuio/src/unix/nic_nl.c b/iscsiuio/src/unix/nic_nl.c
|
|
index 971f350..34e2062 100644
|
|
--- a/iscsiuio/src/unix/nic_nl.c
|
|
+++ b/iscsiuio/src/unix/nic_nl.c
|
|
@@ -83,20 +83,6 @@ const static struct sockaddr_nl dest_addr = {
|
|
/* Netlink */
|
|
int nl_sock = INVALID_FD;
|
|
|
|
-/* Items used to handle the thread used to send/process ARP's */
|
|
-static pthread_t nl_process_thread;
|
|
-static pthread_cond_t nl_process_cond;
|
|
-pthread_cond_t nl_process_if_down_cond;
|
|
-pthread_mutex_t nl_process_mutex;
|
|
-int nl_process_if_down = 0;
|
|
-
|
|
-#define NL_PROCESS_MAX_RING_SIZE 128
|
|
-#define NL_PROCESS_LAST_ENTRY NL_PROCESS_MAX_RING_SIZE - 1
|
|
-#define NL_PROCESS_NEXT_ENTRY(x) ((x + 1) & NL_PROCESS_MAX_RING_SIZE)
|
|
-static int nl_process_head;
|
|
-static int nl_process_tail;
|
|
-static void *nl_process_ring[NL_PROCESS_MAX_RING_SIZE];
|
|
-
|
|
#define MAX_TX_DESC_CNT (TX_DESC_CNT - 1)
|
|
|
|
#define NEXT_TX_BD(x) (((x) & (MAX_TX_DESC_CNT - 1)) == \
|
|
@@ -222,10 +208,11 @@ int __kipc_call(int fd, void *iov_base, int iov_len)
|
|
static int pull_from_nl(char **buf)
|
|
{
|
|
int rc;
|
|
- size_t ev_size;
|
|
+ size_t ev_size, payload_size, alloc_size;
|
|
char nlm_ev[NLMSG_SPACE(sizeof(struct iscsi_uevent))];
|
|
struct nlmsghdr *nlh;
|
|
char *data = NULL;
|
|
+ struct iscsi_uevent *ev;
|
|
|
|
/* Take a quick peek at what how much uIP will need to read */
|
|
rc = nl_read(nl_sock, nlm_ev,
|
|
@@ -249,14 +236,26 @@ static int pull_from_nl(char **buf)
|
|
return -EINVAL;
|
|
}
|
|
|
|
- data = (char *)malloc(nlh->nlmsg_len);
|
|
+ ev = (struct iscsi_uevent *)NLMSG_DATA(nlh);
|
|
+ if (ev->type == ISCSI_KEVENT_PATH_REQ) {
|
|
+ ev_size = nlh->nlmsg_len - NLMSG_ALIGN(sizeof(struct nlmsghdr));
|
|
+ payload_size = ev_size - sizeof(struct iscsi_uevent);
|
|
+ if (payload_size < sizeof(struct iscsi_path))
|
|
+ alloc_size = nlh->nlmsg_len + (payload_size -
|
|
+ sizeof(struct iscsi_path));
|
|
+ else
|
|
+ alloc_size = nlh->nlmsg_len;
|
|
+ } else {
|
|
+ alloc_size = nlh->nlmsg_len;
|
|
+ }
|
|
+ data = (char *)malloc(alloc_size);
|
|
if (unlikely(data == NULL)) {
|
|
LOG_ERR(PFX "Couldn't allocate %d bytes for Netlink "
|
|
- "iSCSI message", nlh->nlmsg_len);
|
|
+ "iSCSI message", alloc_size);
|
|
return -ENOMEM;
|
|
}
|
|
|
|
- memset(data, 0, nlh->nlmsg_len);
|
|
+ memset(data, 0, alloc_size);
|
|
ev_size = nlh->nlmsg_len - NLMSG_ALIGN(sizeof(struct nlmsghdr));
|
|
rc = nl_read(nl_sock, data, (int)nlh->nlmsg_len, MSG_WAITALL);
|
|
if (rc <= 0) {
|
|
@@ -269,10 +268,9 @@ static int pull_from_nl(char **buf)
|
|
|
|
goto error;
|
|
}
|
|
-
|
|
*buf = data;
|
|
return 0;
|
|
- error:
|
|
+error:
|
|
if (data != NULL)
|
|
free(data);
|
|
|
|
@@ -284,9 +282,8 @@ const static struct timespec ctldev_sleep_req = {
|
|
.tv_nsec = 250000000,
|
|
};
|
|
|
|
-static int ctldev_handle(char *data)
|
|
+static int ctldev_handle(char *data, nic_t *nic)
|
|
{
|
|
- nic_t *nic = NULL;
|
|
int rc;
|
|
struct iscsi_uevent *ev;
|
|
uint8_t *payload;
|
|
@@ -294,18 +291,12 @@ static int ctldev_handle(char *data)
|
|
char *msg_type_str;
|
|
uint32_t host_no;
|
|
int i;
|
|
+ nic_interface_t *nic_iface = NULL;
|
|
|
|
ev = (struct iscsi_uevent *)NLMSG_DATA(data);
|
|
switch (ev->type) {
|
|
case ISCSI_KEVENT_PATH_REQ:
|
|
msg_type_str = "path_req";
|
|
-
|
|
- host_no = ev->r.req_path.host_no;
|
|
- break;
|
|
- case ISCSI_KEVENT_IF_DOWN:
|
|
- msg_type_str = "if_down";
|
|
-
|
|
- host_no = ev->r.notify_if_down.host_no;
|
|
break;
|
|
default:
|
|
/* We don't care about other iSCSI Netlink messages */
|
|
@@ -315,22 +306,16 @@ static int ctldev_handle(char *data)
|
|
}
|
|
|
|
/* This is a message that drivers should be interested in */
|
|
- LOG_INFO("Received: '%s': host_no: %d", msg_type_str, host_no);
|
|
-
|
|
- rc = from_host_no_find_associated_eth_device(host_no, &nic);
|
|
- if (rc != 0) {
|
|
- LOG_ERR(PFX "Dropping msg, couldn't find nic with host no:%d",
|
|
- host_no);
|
|
- goto error;
|
|
- }
|
|
+ LOG_INFO(PFX "%s: Processing '%s'", nic->log_name, msg_type_str);
|
|
|
|
payload = (uint8_t *) ((uint8_t *) ev) + sizeof(*ev);
|
|
path = (struct iscsi_path *)payload;
|
|
|
|
if (ev->type == ISCSI_KEVENT_PATH_REQ) {
|
|
struct timespec sleep_rem;
|
|
- nic_interface_t *nic_iface, *vlan_iface;
|
|
+ nic_interface_t *vlan_iface;
|
|
uint16_t ip_type;
|
|
+ int iface_num, vlan_id;
|
|
|
|
if (path->ip_addr_len == 4)
|
|
ip_type = AF_INET;
|
|
@@ -339,67 +324,107 @@ static int ctldev_handle(char *data)
|
|
else
|
|
ip_type = 0;
|
|
|
|
- /* Find the parent nic_iface */
|
|
- nic_iface = nic_find_nic_iface_protocol(nic, 0, ip_type);
|
|
+ /* Find the nic_iface to use */
|
|
+ iface_num = ev->r.req_path.iface_num ?
|
|
+ ev->r.req_path.iface_num : IFACE_NUM_INVALID;
|
|
+ vlan_id = path->vlan_id ? path->vlan_id : NO_VLAN;
|
|
+
|
|
+ LOG_DEBUG(PFX "%s: PATH_REQ with iface_num %d VLAN %d",
|
|
+ nic->log_name, iface_num, vlan_id);
|
|
+
|
|
+ pthread_mutex_lock(&nic->nic_mutex);
|
|
+
|
|
+ nic_iface = nic_find_nic_iface(nic, ip_type, vlan_id,
|
|
+ iface_num, IP_CONFIG_OFF);
|
|
if (nic_iface == NULL) {
|
|
- 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;
|
|
+ nic_iface = nic_find_nic_iface(nic, ip_type,
|
|
+ NO_VLAN,
|
|
+ IFACE_NUM_INVALID,
|
|
+ IP_CONFIG_OFF);
|
|
+ if (nic_iface == NULL) {
|
|
+ pthread_mutex_unlock(&nic->nic_mutex);
|
|
+ LOG_ERR(PFX "%s: Couldn't find nic iface parent"
|
|
+ " 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 (nic_iface->iface_num != IFACE_NUM_INVALID) {
|
|
+ /* New VLAN support:
|
|
+ Use the nic_iface found from the top
|
|
+ of the protocol family and ignore
|
|
+ the VLAN id from the path_req */
|
|
+ if (!(nic_iface->iface_num == 0 &&
|
|
+ nic_iface->vlan_id == 0 &&
|
|
+ path->vlan_id)) {
|
|
+ pthread_mutex_unlock(&nic->nic_mutex);
|
|
+ goto nic_iface_done;
|
|
}
|
|
-
|
|
- 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;
|
|
+ /* If iface_num == 0 and vlan_id == 0 but
|
|
+ the vlan_id from path_req is > 0,
|
|
+ then fallthru to the legacy support since
|
|
+ this is most likely from an older iscsid
|
|
+ (RHEL6.2/6.3 but has iface_num support)
|
|
+ */
|
|
}
|
|
- }
|
|
+ /* Legacy VLAN support:
|
|
+ This newly created nic_iface must inherit the
|
|
+ network parameters from the parent nic_iface
|
|
+ */
|
|
+ LOG_DEBUG(PFX "%s: Created the nic_iface for vlan: %d "
|
|
+ "ip_type: %d", nic->log_name, path->vlan_id,
|
|
+ ip_type);
|
|
+ vlan_iface = nic_iface_init();
|
|
+ if (vlan_iface == NULL) {
|
|
+ pthread_mutex_unlock(&nic->nic_mutex);
|
|
+ LOG_ERR(PFX "%s: Couldn't allocate "
|
|
+ "space for vlan: %d ip_type: "
|
|
+ "%d", nic->log_name, path->vlan_id,
|
|
+ ip_type);
|
|
+ goto error;
|
|
+ }
|
|
+ vlan_iface->protocol = ip_type;
|
|
+ vlan_iface->vlan_id = path->vlan_id;
|
|
+ nic_add_nic_iface(nic, vlan_iface);
|
|
+
|
|
+ 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 so when nic_close won't call uip_reset
|
|
+ to nullify nic_iface->ustack */
|
|
+ persist_all_nic_iface(nic);
|
|
+
|
|
+ nic_iface = vlan_iface;
|
|
+
|
|
+ pthread_mutex_unlock(&nic->nic_mutex);
|
|
|
|
+ /* nic_disable but not going down */
|
|
+ nic_disable(nic, 0);
|
|
+ } else {
|
|
+ pthread_mutex_unlock(&nic->nic_mutex);
|
|
+ }
|
|
+nic_iface_done:
|
|
/* Force enable the NIC */
|
|
- if ((nic->state & NIC_STOPPED) &&
|
|
- !(nic->flags & NIC_ENABLED_PENDING))
|
|
+ if (nic->state == NIC_STOPPED)
|
|
nic_enable(nic);
|
|
|
|
/* Ensure that the NIC is RUNNING */
|
|
rc = -EIO;
|
|
for (i = 0; i < 10; i++) {
|
|
- if ((nic->state & NIC_RUNNING) == NIC_RUNNING) {
|
|
+ if (nic->state == NIC_RUNNING) {
|
|
rc = 0;
|
|
break;
|
|
}
|
|
@@ -418,49 +443,25 @@ static int ctldev_handle(char *data)
|
|
}
|
|
|
|
if (nic->ops) {
|
|
- char eth_device_name[IFNAMSIZ];
|
|
-
|
|
switch (ev->type) {
|
|
case ISCSI_KEVENT_PATH_REQ:
|
|
/* pass the request up to the user space
|
|
* library driver */
|
|
- if (nic->ops->handle_iscsi_path_req) {
|
|
+ nic_iface->flags |= NIC_IFACE_PATHREQ_WAIT2;
|
|
+ nic_iface->flags &= ~NIC_IFACE_PATHREQ_WAIT1;
|
|
+ if (nic->ops->handle_iscsi_path_req)
|
|
nic->ops->handle_iscsi_path_req(nic,
|
|
nl_sock, ev,
|
|
- path);
|
|
- }
|
|
-
|
|
- LOG_INFO(PFX "%s: 'path_req' operation finished",
|
|
- nic->log_name);
|
|
-
|
|
- rc = 0;
|
|
- break;
|
|
- case ISCSI_KEVENT_IF_DOWN:
|
|
- memcpy(eth_device_name, nic->eth_device_name,
|
|
- sizeof(eth_device_name));
|
|
-
|
|
- pthread_mutex_lock(&nic_list_mutex);
|
|
-
|
|
+ path,
|
|
+ nic_iface);
|
|
+ nic_iface->flags &= ~NIC_IFACE_PATHREQ_WAIT;
|
|
pthread_mutex_lock(&nic->nic_mutex);
|
|
- nic->flags |= NIC_EXIT_MAIN_LOOP;
|
|
+ nic->flags &= ~NIC_PATHREQ_WAIT;
|
|
pthread_mutex_unlock(&nic->nic_mutex);
|
|
-
|
|
- pthread_cond_broadcast(&nic->enable_done_cond);
|
|
-
|
|
- nic_disable(nic, 1);
|
|
-
|
|
- nic_remove(nic);
|
|
- pthread_mutex_unlock(&nic_list_mutex);
|
|
-
|
|
- pthread_mutex_lock(&nl_process_mutex);
|
|
- nl_process_if_down = 0;
|
|
- pthread_mutex_unlock(&nl_process_mutex);
|
|
+ LOG_INFO(PFX "%s: 'path_req' operation finished",
|
|
+ nic->log_name);
|
|
|
|
rc = 0;
|
|
-
|
|
- LOG_INFO(PFX "%s: 'if_down' operation finished",
|
|
- eth_device_name);
|
|
-
|
|
break;
|
|
default:
|
|
rc = -EAGAIN;
|
|
@@ -468,55 +469,62 @@ static int ctldev_handle(char *data)
|
|
}
|
|
}
|
|
|
|
- error:
|
|
+error:
|
|
|
|
return rc;
|
|
}
|
|
|
|
-static void *nl_process_handle_thread(void *arg)
|
|
+/* NIC specific nl processing thread */
|
|
+void *nl_process_handle_thread(void *arg)
|
|
{
|
|
int rc;
|
|
+ nic_t *nic = (nic_t *)arg;
|
|
+
|
|
+ if (nic == NULL)
|
|
+ goto error;
|
|
|
|
while (!event_loop_stop) {
|
|
char *data = NULL;
|
|
|
|
- rc = pthread_cond_wait(&nl_process_cond, &nl_process_mutex);
|
|
+ rc = pthread_cond_wait(&nic->nl_process_cond,
|
|
+ &nic->nl_process_mutex);
|
|
if (rc != 0) {
|
|
LOG_ERR("Fatal error in NL processing thread "
|
|
"during wait[%s]", strerror(rc));
|
|
break;
|
|
}
|
|
|
|
- data = nl_process_ring[nl_process_head];
|
|
- nl_process_ring[nl_process_head] = NULL;
|
|
- nl_process_tail = NL_PROCESS_NEXT_ENTRY(nl_process_tail);
|
|
+ data = nic->nl_process_ring[nic->nl_process_head];
|
|
+ nic->nl_process_ring[nic->nl_process_head] = NULL;
|
|
+ nic->nl_process_tail =
|
|
+ NIC_NL_PROCESS_NEXT_ENTRY(nic->nl_process_tail);
|
|
|
|
- pthread_mutex_unlock(&nl_process_mutex);
|
|
+ pthread_mutex_unlock(&nic->nl_process_mutex);
|
|
|
|
if (data) {
|
|
- ctldev_handle(data);
|
|
+ ctldev_handle(data, nic);
|
|
free(data);
|
|
}
|
|
}
|
|
-
|
|
+error:
|
|
return NULL;
|
|
}
|
|
|
|
-static void flush_nl_process_ring()
|
|
+static void flush_nic_nl_process_ring(nic_t *nic)
|
|
{
|
|
int i;
|
|
|
|
- for (i = 0; i < NL_PROCESS_MAX_RING_SIZE; i++) {
|
|
- if (nl_process_ring[i] != NULL) {
|
|
- free(nl_process_ring[i]);
|
|
- nl_process_ring[i] = NULL;
|
|
+ for (i = 0; i < NIC_NL_PROCESS_MAX_RING_SIZE; i++) {
|
|
+ if (nic->nl_process_ring[i] != NULL) {
|
|
+ free(nic->nl_process_ring[i]);
|
|
+ nic->nl_process_ring[i] = NULL;
|
|
}
|
|
}
|
|
|
|
- nl_process_head = 0;
|
|
- nl_process_tail = 0;
|
|
+ nic->nl_process_head = 0;
|
|
+ nic->nl_process_tail = 0;
|
|
|
|
- LOG_DEBUG(PFX "Flushed NL ring");
|
|
+ LOG_DEBUG(PFX "%s: Flushed NIC NL ring", nic->log_name);
|
|
}
|
|
|
|
/**
|
|
@@ -528,25 +536,9 @@ static void flush_nl_process_ring()
|
|
int nic_nl_open()
|
|
{
|
|
int rc;
|
|
+ char *msg_type_str;
|
|
|
|
- /* Prepare the thread to issue the ARP's */
|
|
- nl_process_head = 0;
|
|
- nl_process_tail = 0;
|
|
- nl_process_if_down = 0;
|
|
- memset(&nl_process_ring, 0, sizeof(nl_process_ring));
|
|
-
|
|
- pthread_mutex_init(&nl_process_mutex, NULL);
|
|
- pthread_cond_init(&nl_process_cond, NULL);
|
|
- pthread_cond_init(&nl_process_if_down_cond, NULL);
|
|
-
|
|
- rc = pthread_create(&nl_process_thread, NULL,
|
|
- nl_process_handle_thread, NULL);
|
|
- if (rc != 0) {
|
|
- LOG_ERR("Could not create NL processing thread [%s]",
|
|
- strerror(rc));
|
|
- return -EIO;
|
|
- }
|
|
-
|
|
+ /* Prepare the thread to issue the ARP's */
|
|
nl_sock = socket(PF_NETLINK, SOCK_RAW, NETLINK_ISCSI);
|
|
if (nl_sock < 0) {
|
|
LOG_ERR(PFX "can not create NETLINK_ISCSI socket [%s]",
|
|
@@ -581,6 +573,8 @@ int nic_nl_open()
|
|
while (!event_loop_stop) {
|
|
struct iscsi_uevent *ev;
|
|
char *buf = NULL;
|
|
+ uint32_t host_no;
|
|
+ nic_t *nic;
|
|
|
|
rc = pull_from_nl(&buf);
|
|
if (rc != 0)
|
|
@@ -588,33 +582,91 @@ int nic_nl_open()
|
|
|
|
/* Try to abort ARP'ing if a if_down was recieved */
|
|
ev = (struct iscsi_uevent *)NLMSG_DATA(buf);
|
|
- if (ev->type == ISCSI_KEVENT_IF_DOWN) {
|
|
- LOG_INFO(PFX "Received if_down event");
|
|
+ switch (ev->type) {
|
|
+ case ISCSI_KEVENT_IF_DOWN:
|
|
+ host_no = ev->r.notify_if_down.host_no;
|
|
+ msg_type_str = "if_down";
|
|
+ break;
|
|
+ case ISCSI_KEVENT_PATH_REQ:
|
|
+ host_no = ev->r.req_path.host_no;
|
|
+ msg_type_str = "path_req";
|
|
+ break;
|
|
+ default:
|
|
+ /* We don't care about other iSCSI Netlink messages */
|
|
+ continue;
|
|
+ }
|
|
+ LOG_INFO(PFX "Received %s for host %d", msg_type_str, host_no);
|
|
|
|
- pthread_mutex_lock(&nl_process_mutex);
|
|
- /* Don't flush the nl ring if another if_down
|
|
- is in progress */
|
|
- if (!nl_process_if_down) {
|
|
- nl_process_if_down = 1;
|
|
+ /* Make sure the nic list doesn't get yanked */
|
|
+ pthread_mutex_lock(&nic_list_mutex);
|
|
|
|
- flush_nl_process_ring();
|
|
- }
|
|
- pthread_mutex_unlock(&nl_process_mutex);
|
|
+ rc = from_host_no_find_associated_eth_device(host_no, &nic);
|
|
+ if (rc != 0) {
|
|
+ pthread_mutex_unlock(&nic_list_mutex);
|
|
+ LOG_ERR(PFX "Dropping msg, couldn't find nic with host "
|
|
+ "no: %d", host_no);
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ /* Found the nic */
|
|
+ if (nic->nl_process_thread == INVALID_THREAD) {
|
|
+ /* If thread is not valid, just drop it */
|
|
+ pthread_mutex_unlock(&nic_list_mutex);
|
|
+ LOG_ERR(PFX "Dropping msg, nic nl process thread "
|
|
+ "not ready for host no: %d", host_no);
|
|
+ continue;
|
|
}
|
|
|
|
- if ((nl_process_head + 1 == nl_process_tail) ||
|
|
- (nl_process_tail == 0 &&
|
|
- nl_process_head == NL_PROCESS_LAST_ENTRY)) {
|
|
- LOG_WARN(PFX "No space on Netlink ring");
|
|
+ if (ev->type == ISCSI_KEVENT_IF_DOWN) {
|
|
+ char eth_device_name[IFNAMSIZ];
|
|
+
|
|
+ pthread_mutex_lock(&nic->nl_process_mutex);
|
|
+ nic->nl_process_if_down = 1;
|
|
+ flush_nic_nl_process_ring(nic);
|
|
+ pthread_cond_broadcast(&nic->nl_process_if_down_cond);
|
|
+ pthread_mutex_unlock(&nic->nl_process_mutex);
|
|
+
|
|
+ memcpy(eth_device_name, nic->eth_device_name,
|
|
+ sizeof(eth_device_name));
|
|
+
|
|
+ pthread_mutex_lock(&nic->nic_mutex);
|
|
+ nic->flags &= ~NIC_PATHREQ_WAIT;
|
|
+ nic->flags |= NIC_EXIT_MAIN_LOOP;
|
|
+ pthread_cond_broadcast(&nic->enable_done_cond);
|
|
+ pthread_mutex_unlock(&nic->nic_mutex);
|
|
+
|
|
+ pthread_mutex_lock(&nic->nl_process_mutex);
|
|
+ nic->nl_process_if_down = 0;
|
|
+ pthread_mutex_unlock(&nic->nl_process_mutex);
|
|
+
|
|
+ nic_disable(nic, 1);
|
|
+
|
|
+ nic_remove(nic);
|
|
+ pthread_mutex_unlock(&nic_list_mutex);
|
|
+
|
|
+ LOG_INFO(PFX "%s: 'if_down' operation finished",
|
|
+ eth_device_name);
|
|
+ continue;
|
|
+ }
|
|
+ /* Place msg into the nic specific queue */
|
|
+ pthread_mutex_lock(&nic->nl_process_mutex);
|
|
+ if ((nic->nl_process_head + 1 == nic->nl_process_tail) ||
|
|
+ (nic->nl_process_tail == 0 &&
|
|
+ nic->nl_process_head == NIC_NL_PROCESS_LAST_ENTRY)) {
|
|
+ pthread_mutex_unlock(&nic->nl_process_mutex);
|
|
+ pthread_mutex_unlock(&nic_list_mutex);
|
|
+ LOG_WARN(PFX "%s: No space on Netlink ring",
|
|
+ nic->log_name);
|
|
continue;
|
|
}
|
|
+ nic->nl_process_ring[nic->nl_process_head] = buf;
|
|
+ nic->nl_process_head =
|
|
+ NIC_NL_PROCESS_NEXT_ENTRY(nic->nl_process_head);
|
|
+ pthread_cond_signal(&nic->nl_process_cond);
|
|
|
|
- pthread_mutex_lock(&nl_process_mutex);
|
|
- nl_process_ring[nl_process_head] = buf;
|
|
- nl_process_head = NL_PROCESS_NEXT_ENTRY(nl_process_head);
|
|
+ pthread_mutex_unlock(&nic->nl_process_mutex);
|
|
|
|
- pthread_cond_signal(&nl_process_cond);
|
|
- pthread_mutex_unlock(&nl_process_mutex);
|
|
+ pthread_mutex_unlock(&nic_list_mutex);
|
|
|
|
LOG_DEBUG(PFX "Pulled nl event");
|
|
}
|
|
diff --git a/iscsiuio/src/unix/nic_utils.c b/iscsiuio/src/unix/nic_utils.c
|
|
index fe58df8..a1d3e72 100644
|
|
--- a/iscsiuio/src/unix/nic_utils.c
|
|
+++ b/iscsiuio/src/unix/nic_utils.c
|
|
@@ -65,7 +65,7 @@
|
|
*****************************************************************************/
|
|
static const char nic_uio_sysfs_name_tempate[] = "/sys/class/uio/uio%i/name";
|
|
static const char cnic_sysfs_uio_event_template[] =
|
|
- "/sys/class/uio/uio%d/event";
|
|
+ "/sys/class/uio/uio%d/event";
|
|
static const char base_uio_sysfs_name[] = "/sys/class/uio/";
|
|
static const char uio_name[] = "uio";
|
|
|
|
@@ -77,7 +77,7 @@ static const char base_iscsi_host_name[] = "/sys/class/iscsi_host/";
|
|
static const char host_template[] = "host%d";
|
|
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";
|
|
+ "/sys/class/iscsi_host/host%d/netdev";
|
|
static const char cnic_uio_sysfs_resc_template[] =
|
|
"/sys/class/uio/uio%i/device/resource%i";
|
|
|
|
@@ -208,6 +208,7 @@ int nic_discover_iscsi_hosts()
|
|
|
|
default:
|
|
/* There are iSCSI hosts */
|
|
+ pthread_mutex_lock(&nic_list_mutex);
|
|
for (i = 0; i < count; i++) {
|
|
int host_no;
|
|
char *raw = NULL;
|
|
@@ -267,6 +268,7 @@ int nic_discover_iscsi_hosts()
|
|
|
|
free(raw);
|
|
}
|
|
+ pthread_mutex_unlock(&nic_list_mutex);
|
|
|
|
/* Cleanup the scandir() call */
|
|
for (i = 0; i < count; i++)
|
|
@@ -402,6 +404,7 @@ static char *extract_none(struct dirent **files)
|
|
/**
|
|
* from_host_no_find_nic() - Given the host number
|
|
* this function will try to find the assoicated nic interface
|
|
+ * Must be called with nic_list_mutex lock
|
|
* @param host_no - minor number of the UIO device
|
|
* @param nic - pointer to the NIC will set if successful
|
|
* @return 0 on success, <0 on error
|
|
@@ -431,7 +434,6 @@ int from_host_no_find_associated_eth_device(int host_no, nic_t ** nic)
|
|
|
|
rc = -EIO;
|
|
|
|
- pthread_mutex_lock(&nic_list_mutex);
|
|
current_nic = nic_list;
|
|
while (current_nic != NULL) {
|
|
if (strcmp(raw, current_nic->eth_device_name) == 0) {
|
|
@@ -442,7 +444,6 @@ int from_host_no_find_associated_eth_device(int host_no, nic_t ** nic)
|
|
|
|
current_nic = current_nic->next;
|
|
}
|
|
- pthread_mutex_unlock(&nic_list_mutex);
|
|
|
|
free(raw);
|
|
|
|
@@ -923,7 +924,7 @@ int nic_enable(nic_t * nic)
|
|
nic->log_name, nic->flags, nic->state);
|
|
return -EINVAL;
|
|
}
|
|
- if (nic->state & NIC_STOPPED) {
|
|
+ if (nic->state == NIC_STOPPED) {
|
|
struct timespec ts;
|
|
struct timeval tp;
|
|
int rc;
|
|
@@ -940,48 +941,20 @@ int nic_enable(nic_t * nic)
|
|
rc = gettimeofday(&tp, NULL);
|
|
ts.tv_sec = tp.tv_sec;
|
|
ts.tv_nsec = tp.tv_usec * 1000;
|
|
- ts.tv_sec += 10;
|
|
+ ts.tv_sec += 100;
|
|
|
|
/* 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;
|
|
-
|
|
if (rc == 0 && nic->flags & NIC_ENABLED) {
|
|
LOG_DEBUG(PFX "%s: device enabled", nic->log_name);
|
|
} else {
|
|
- LOG_ERR(PFX "%s: waiting to finish nic_enable err:%s",
|
|
+ nic->flags &= ~NIC_ENABLED;
|
|
+ nic->flags |= NIC_DISABLED;
|
|
+ nic->flags &= ~NIC_ENABLED_PENDING;
|
|
+
|
|
+ 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;
|
|
- }
|
|
}
|
|
pthread_mutex_unlock(&nic->nic_mutex);
|
|
|
|
@@ -1001,7 +974,8 @@ int nic_enable(nic_t * nic)
|
|
*/
|
|
int nic_disable(nic_t * nic, int going_down)
|
|
{
|
|
- if (nic->state & (NIC_STARTED_RUNNING | NIC_RUNNING)) {
|
|
+ if (nic->state == NIC_STARTED_RUNNING ||
|
|
+ nic->state == NIC_RUNNING) {
|
|
struct timespec ts;
|
|
struct timeval tp;
|
|
int rc;
|
|
@@ -1012,8 +986,7 @@ int nic_disable(nic_t * nic, int going_down)
|
|
nic->flags &= ~NIC_ENABLED;
|
|
nic->flags |= NIC_DISABLED;
|
|
nic->flags &= ~NIC_STARTED_RUNNING;
|
|
- nic->state &= ~NIC_RUNNING;
|
|
- nic->state |= NIC_STOPPED;
|
|
+ nic->state = NIC_STOPPED;
|
|
|
|
if (going_down)
|
|
nic->flags |= NIC_GOING_DOWN;
|
|
@@ -1070,7 +1043,9 @@ void nic_remove_all()
|
|
nic = nic_list;
|
|
while (nic != NULL) {
|
|
nic_next = nic->next;
|
|
+ pthread_mutex_lock(&nic->nic_mutex);
|
|
nic_close(nic, 1, FREE_ALL_STRINGS);
|
|
+ pthread_mutex_unlock(&nic->nic_mutex);
|
|
nic_remove(nic);
|
|
nic = nic_next;
|
|
}
|
|
@@ -1127,14 +1102,13 @@ error:
|
|
* nic_set_all_nic_iface_mac_to_parent() - This is a utility function used to
|
|
* intialize all the MAC addresses of the network interfaces for a given
|
|
* CNIC UIO device
|
|
+ * Call with nic mutex held
|
|
* @param dev - CNIC UIO device to initialize
|
|
*/
|
|
-void nic_set_all_nic_iface_mac_to_parent(nic_t * nic)
|
|
+void nic_set_all_nic_iface_mac_to_parent(nic_t *nic)
|
|
{
|
|
nic_interface_t *current, *vlan_current;
|
|
|
|
- pthread_mutex_lock(&nic->nic_mutex);
|
|
-
|
|
current = nic->nic_iface;
|
|
while (current != NULL) {
|
|
/* Set the initial MAC address of this interface to the parent
|
|
@@ -1148,8 +1122,6 @@ void nic_set_all_nic_iface_mac_to_parent(nic_t * nic)
|
|
}
|
|
current = current->next;
|
|
}
|
|
-
|
|
- pthread_mutex_unlock(&nic->nic_mutex);
|
|
}
|
|
|
|
/*******************************************************************************
|
|
@@ -1272,143 +1244,144 @@ void nic_fill_ethernet_header(nic_interface_t * nic_iface,
|
|
* NIC interface management utility functions
|
|
******************************************************************************/
|
|
/**
|
|
- * nic_find_nic_iface() - This function is used to find an interface from the
|
|
- * NIC
|
|
- * @param nic - NIC to look for network interfaces
|
|
- * @param vlan_id - VLAN id to look for
|
|
- * @return nic_iface - if found network interface with the given VLAN ID
|
|
- * if not found a NULL is returned
|
|
- */
|
|
-nic_interface_t *nic_find_nic_iface(nic_t * nic, uint16_t vlan_id)
|
|
-{
|
|
- nic_interface_t *current;
|
|
-
|
|
- pthread_mutex_lock(&nic->nic_mutex);
|
|
-
|
|
- current = nic->nic_iface;
|
|
- while (current != NULL) {
|
|
- if (current->vlan_id == vlan_id) {
|
|
- pthread_mutex_unlock(&nic->nic_mutex);
|
|
- return current;
|
|
- }
|
|
-
|
|
- current = current->next;
|
|
- }
|
|
-
|
|
- pthread_mutex_unlock(&nic->nic_mutex);
|
|
-
|
|
- return NULL;
|
|
-}
|
|
-
|
|
-/**
|
|
- * nic_find_nic_iface_protocol() - This function is used to find an interface
|
|
- * from the NIC
|
|
+ * nic_find_nic_iface() - This function is used to find an interface
|
|
+ * from the NIC
|
|
* @param nic - NIC to look for network interfaces
|
|
* @param vlan_id - VLAN id to look for
|
|
* @param protocol - either AF_INET or AF_INET6
|
|
+ * @param iface_num - iface num to use if present
|
|
+ * @param request_type - IPV4/6 DHCP/STATIC
|
|
* @return nic_iface - if found network interface with the given VLAN ID
|
|
* if not found a NULL is returned
|
|
*/
|
|
-nic_interface_t *nic_find_nic_iface_protocol(nic_t * nic,
|
|
- uint16_t vlan_id,
|
|
- uint16_t protocol)
|
|
+nic_interface_t *nic_find_nic_iface(nic_t *nic,
|
|
+ uint16_t protocol,
|
|
+ uint16_t vlan_id,
|
|
+ int iface_num,
|
|
+ int request_type)
|
|
{
|
|
- nic_interface_t *current;
|
|
+ nic_interface_t *current = nic->nic_iface;
|
|
+ nic_interface_t *current_vlan = NULL;
|
|
|
|
- pthread_mutex_lock(&nic->nic_mutex);
|
|
-
|
|
- current = nic->nic_iface;
|
|
while (current != NULL) {
|
|
- if ((current->vlan_id == vlan_id) &&
|
|
- (current->protocol == protocol)) {
|
|
- pthread_mutex_unlock(&nic->nic_mutex);
|
|
- return current;
|
|
+ if (current->protocol != protocol)
|
|
+ goto next;
|
|
+
|
|
+ /* Check for iface_num first */
|
|
+ if (iface_num != IFACE_NUM_INVALID) {
|
|
+ if (current->iface_num == iface_num) {
|
|
+ /* Exception is when iface_num == 0, need to
|
|
+ check for request_type also if !=
|
|
+ IP_CONFIG_OFF */
|
|
+ if (!iface_num && request_type !=
|
|
+ IP_CONFIG_OFF) {
|
|
+ if (current->request_type ==
|
|
+ request_type)
|
|
+ goto found;
|
|
+ } else {
|
|
+ goto found;
|
|
+ }
|
|
+ }
|
|
+ } else if (vlan_id == NO_VLAN) {
|
|
+ /* Just return the top of the family */
|
|
+ goto found;
|
|
+ } else {
|
|
+ if ((current->vlan_id == vlan_id) &&
|
|
+ ((request_type == IP_CONFIG_OFF) ||
|
|
+ (current->request_type == request_type)))
|
|
+ goto found;
|
|
}
|
|
+ /* vlan_next loop */
|
|
+ current_vlan = current->vlan_next;
|
|
+ while (current_vlan != NULL) {
|
|
+ if (iface_num != IFACE_NUM_INVALID) {
|
|
+ if (current_vlan->iface_num == iface_num) {
|
|
+ if (!iface_num && request_type !=
|
|
+ IP_CONFIG_OFF) {
|
|
+ if (current_vlan->request_type
|
|
+ == request_type)
|
|
+ goto vlan_found;
|
|
+ } else {
|
|
+ goto vlan_found;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ if ((current_vlan->vlan_id == vlan_id) &&
|
|
+ ((request_type == IP_CONFIG_OFF) ||
|
|
+ (current_vlan->request_type == request_type)))
|
|
+ goto vlan_found;
|
|
|
|
+ current_vlan = current_vlan->vlan_next;
|
|
+ }
|
|
+next:
|
|
current = current->next;
|
|
}
|
|
-
|
|
- pthread_mutex_unlock(&nic->nic_mutex);
|
|
-
|
|
- return NULL;
|
|
+vlan_found:
|
|
+ current = current_vlan;
|
|
+found:
|
|
+ return current;
|
|
}
|
|
|
|
+/* Called with nic mutex held */
|
|
void persist_all_nic_iface(nic_t * nic)
|
|
{
|
|
- nic_interface_t *current, *vlan_iface;
|
|
-
|
|
- pthread_mutex_lock(&nic->nic_mutex);
|
|
+ nic_interface_t *current_vlan, *current;
|
|
|
|
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_vlan = current->vlan_next;
|
|
+ while (current_vlan != NULL) {
|
|
+ current_vlan->flags |= NIC_IFACE_PERSIST;
|
|
+ current_vlan = current_vlan->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;
|
|
}
|
|
|
|
+/* Sets the nic_iface to the front of the AF */
|
|
void set_nic_iface(nic_t *nic, nic_interface_t *nic_iface)
|
|
{
|
|
nic_interface_t *current, *prev;
|
|
+ nic_interface_t *current_vlan, *prev_vlan;
|
|
|
|
- pthread_mutex_lock(&nic->nic_mutex);
|
|
-
|
|
- if (nic->nic_iface == nic_iface)
|
|
- goto done;
|
|
-
|
|
- prev = nic->nic_iface;
|
|
- current = nic->nic_iface->next;
|
|
+ prev = NULL;
|
|
+ current = nic->nic_iface;
|
|
while (current != NULL) {
|
|
- if (current == nic_iface) {
|
|
- prev->next = current->next;
|
|
- current->next = nic->nic_iface;
|
|
- nic->nic_iface = current;
|
|
+ if (current->protocol != nic_iface->protocol)
|
|
+ goto next;
|
|
+ /* If its already on top of the list, exit */
|
|
+ if (current == nic_iface)
|
|
goto done;
|
|
+
|
|
+ prev_vlan = current;
|
|
+ current_vlan = current->vlan_next;
|
|
+
|
|
+ while (current_vlan != NULL) {
|
|
+ if (current_vlan == nic_iface) {
|
|
+ /* Found inside the vlan list */
|
|
+ /* For vlan == 0, place on top of
|
|
+ the AF list */
|
|
+ prev_vlan->vlan_next =
|
|
+ current_vlan->vlan_next;
|
|
+ current_vlan->vlan_next = current;
|
|
+ if (prev)
|
|
+ prev->next = current_vlan;
|
|
+ else
|
|
+ nic->nic_iface = current_vlan;
|
|
+ goto done;
|
|
+ }
|
|
+ prev_vlan = current_vlan;
|
|
+ current_vlan = current_vlan->vlan_next;
|
|
}
|
|
+next:
|
|
prev = current;
|
|
current = current->next;
|
|
}
|
|
done:
|
|
- pthread_mutex_unlock(&nic->nic_mutex);
|
|
+ return;
|
|
}
|
|
+
|
|
/*******************************************************************************
|
|
* Packet management utility functions
|
|
******************************************************************************/
|
|
@@ -1639,7 +1612,7 @@ int capture_file(char **raw, uint32_t * raw_size, const char *path)
|
|
}
|
|
|
|
read_size = fread(*raw, file_size, 1, fp);
|
|
- if (read_size < 0) {
|
|
+ if (!read_size) {
|
|
LOG_ERR("Could not read capture, path: %s len: %d [%s]",
|
|
path, file_size, strerror(ferror(fp)));
|
|
free(*raw);
|
|
diff --git a/iscsiuio/src/unix/nic_utils.h b/iscsiuio/src/unix/nic_utils.h
|
|
index ff76f6b..6c57701 100644
|
|
--- a/iscsiuio/src/unix/nic_utils.h
|
|
+++ b/iscsiuio/src/unix/nic_utils.h
|
|
@@ -67,7 +67,9 @@ void nic_fill_ethernet_header(nic_interface_t * nic_iface,
|
|
int *pkt_size, void **start_addr,
|
|
uint16_t ether_type);
|
|
|
|
-nic_interface_t *nic_find_nic_iface(nic_t * nic, uint16_t vlan_id);
|
|
+struct nic_interface *nic_find_nic_iface(nic_t *nic, uint16_t protocol,
|
|
+ uint16_t vlan_id, int iface_num,
|
|
+ int request_type);
|
|
void set_nic_iface(nic_t *nic, nic_interface_t *nic_iface);
|
|
|
|
void persist_all_nic_iface(nic_t * nic);
|
|
diff --git a/iscsiuio/src/unix/nic_vlan.c b/iscsiuio/src/unix/nic_vlan.c
|
|
index 4f8f551..90a6244 100644
|
|
--- a/iscsiuio/src/unix/nic_vlan.c
|
|
+++ b/iscsiuio/src/unix/nic_vlan.c
|
|
@@ -332,7 +332,8 @@ int find_vlans_using_phy_interface(struct vlan_handle *handle,
|
|
*/
|
|
int valid_vlan(short int vlan)
|
|
{
|
|
- if (vlan > 1 && vlan < 4095)
|
|
+ /* Allow vlan 1 to connect */
|
|
+ if (vlan > 0 && vlan < 4095)
|
|
return 1;
|
|
|
|
return 0;
|
|
diff --git a/iscsiuio/src/unix/packet.c b/iscsiuio/src/unix/packet.c
|
|
index 4d8bf55..5047030 100644
|
|
--- a/iscsiuio/src/unix/packet.c
|
|
+++ b/iscsiuio/src/unix/packet.c
|
|
@@ -88,7 +88,7 @@ void free_packet(struct packet *pkt)
|
|
* reset_packet() - This will reset the packet fields to default values
|
|
* @param pkt - the packet to reset
|
|
*/
|
|
-void reset_packet(packet_t * pkt)
|
|
+void reset_packet(packet_t *pkt)
|
|
{
|
|
pkt->next = NULL;
|
|
|
|
@@ -101,7 +101,7 @@ void reset_packet(packet_t * pkt)
|
|
pkt->network_layer = NULL;
|
|
}
|
|
|
|
-int alloc_free_queue(nic_t * nic, size_t num_of_packets)
|
|
+int alloc_free_queue(nic_t *nic, size_t num_of_packets)
|
|
{
|
|
int rc, i;
|
|
|