From 6648d72aebb373ada77784f56ae285540772dc66 Mon Sep 17 00:00:00 2001 From: Wenchao Hao Date: Thu, 27 Jan 2022 10:14:19 +0800 Subject: [PATCH] Remove unnecessary tool iscsiuio iscsiuio is used in conjunction with specific linux driver to improve performance, such as QLogic NetXtreme II or QLogic CNIC driver. It is not a necessary tool of open-iscsi. What's more, iscsiuio used a package uio which is out of maintain now, which would introduce CVEs unhandled. So I want to remove this tool from open-iscsi. Signed-off-by: Wenchao Hao --- ...csiuio-from-build-and-install-recipe.patch | 90 + 0015-Remove-iscsiuio-source-code.patch | 29936 ++++++++++++++++ ...scsiuio-from-config-and-service-file.patch | 52 + open-iscsi.spec | 16 +- 4 files changed, 30085 insertions(+), 9 deletions(-) create mode 100644 0014-Remove-iscsiuio-from-build-and-install-recipe.patch create mode 100644 0015-Remove-iscsiuio-source-code.patch create mode 100644 0016-Remove-iscsiuio-from-config-and-service-file.patch diff --git a/0014-Remove-iscsiuio-from-build-and-install-recipe.patch b/0014-Remove-iscsiuio-from-build-and-install-recipe.patch new file mode 100644 index 0000000..d14c4e6 --- /dev/null +++ b/0014-Remove-iscsiuio-from-build-and-install-recipe.patch @@ -0,0 +1,90 @@ +From 45d156fd3463924bf7d50d1656bacca160b42430 Mon Sep 17 00:00:00 2001 +From: Wenchao Hao +Date: Thu, 27 Jan 2022 09:36:39 +0800 +Subject: [PATCH 1/3] Remove iscsiuio from build and install recipe + +iscsiuio is to be used in conjunction with specific linux driver to +improve performance, such as QLogic NetXtreme II or QLogic CNIC driver. +It is not a necessary tool of open-iscsi. + +What's more, iscsiuio used a package uio which is out of maintain now, +which would introduce CVEs unhandled. So I want to remove this tool +from open-iscsi. + +This patch removes iscsiuio from build and install recipe. + +Signed-off-by: Wenchao Hao +--- + Makefile | 19 ++++--------------- + 1 file changed, 4 insertions(+), 15 deletions(-) + +diff --git a/Makefile b/Makefile +index 7f52cc8..5908ff9 100644 +--- a/Makefile ++++ b/Makefile +@@ -17,9 +17,9 @@ rulesdir = $(etcdir)/udev/rules.d + systemddir = $(prefix)/lib/systemd/system + + MANPAGES = doc/iscsid.8 doc/iscsiadm.8 doc/iscsi_discovery.8 \ +- iscsiuio/docs/iscsiuio.8 doc/iscsi_fw_login.8 doc/iscsi-iname.8 \ ++ doc/iscsi_fw_login.8 doc/iscsi-iname.8 \ + doc/iscsistart.8 +-PROGRAMS = usr/iscsid usr/iscsiadm utils/iscsi-iname iscsiuio/src/unix/iscsiuio \ ++PROGRAMS = usr/iscsid usr/iscsiadm utils/iscsi-iname \ + usr/iscsistart + SCRIPTS = utils/iscsi_discovery utils/iscsi_fw_login utils/iscsi_offload \ + utils/iscsi-gen-initiatorname +@@ -29,8 +29,7 @@ IFACEFILES = etc/iface.example + RULESFILES = utils/50-iscsi-firmware-login.rules + SYSTEMDFILES = etc/systemd/iscsi.service \ + etc/systemd/iscsi-init.service \ +- etc/systemd/iscsid.service etc/systemd/iscsid.socket \ +- etc/systemd/iscsiuio.service etc/systemd/iscsiuio.socket ++ etc/systemd/iscsid.service etc/systemd/iscsid.socket + + export DESTDIR prefix INSTALL + +@@ -59,30 +58,22 @@ endif + + all: user + +-user: iscsiuio/Makefile ++user: + $(MAKE) -C libopeniscsiusr + $(MAKE) -C utils/sysdeps + $(MAKE) -C utils/fwparam_ibft + $(MAKE) -C usr + $(MAKE) -C utils +- $(MAKE) -C iscsiuio + @echo + @echo "Compilation complete Output file" + @echo "----------------------------------- ----------------" + @echo "Built iSCSI daemon: usr/iscsid" + @echo "Built management application: usr/iscsiadm" + @echo "Built boot tool: usr/iscsistart" +- @echo "Built iscsiuio daemon: iscsiuio/src/unix/iscsiuio" + @echo "Built libopeniscsiusr library: libopeniscsiusr/libopeniscsiusr.so" + @echo + @echo "Read README file for detailed information." + +-iscsiuio/Makefile: iscsiuio/configure iscsiuio/Makefile.in +- cd iscsiuio; ./configure $(WITHOUT_ARG) +- +-iscsiuio/configure iscsiuio/Makefile.in: iscsiuio/configure.ac iscsiuio/Makefile.am +- cd iscsiuio; autoreconf --install +- + force: ; + + clean: +@@ -91,8 +82,6 @@ clean: + $(MAKE) -C utils clean + $(MAKE) -C usr clean + $(MAKE) -C libopeniscsiusr clean +- [ ! -f iscsiuio/Makefile ] || $(MAKE) -C iscsiuio clean +- [ ! -f iscsiuio/Makefile ] || $(MAKE) -C iscsiuio distclean + + # this is for safety + # now -jXXX will still be safe +-- +2.34.1 + diff --git a/0015-Remove-iscsiuio-source-code.patch b/0015-Remove-iscsiuio-source-code.patch new file mode 100644 index 0000000..d16679a --- /dev/null +++ b/0015-Remove-iscsiuio-source-code.patch @@ -0,0 +1,29936 @@ +From 2e9fb234583610262e37d0718b2dcade61cfa17e Mon Sep 17 00:00:00 2001 +From: Wenchao Hao +Date: Thu, 27 Jan 2022 09:52:18 +0800 +Subject: [PATCH 2/3] Remove iscsiuio source code + +iscsiuio is to be used in conjunction with specific linux driver to +improve performance, such as QLogic NetXtreme II or QLogic CNIC driver. +It is not a necessary tool of open-iscsi. + +What's more, iscsiuio used a package uio which is out of maintain now, +which would introduce CVEs unhandled. So I want to remove this tool +from open-iscsi. + +This patch removes iscsiuio source code + +Signed-off-by: Wenchao Hao +--- + etc/systemd/iscsiuio.service | 20 - + etc/systemd/iscsiuio.socket | 9 - + iscsiuio/.gitignore | 25 - + iscsiuio/AUTHORS | 0 + iscsiuio/ChangeLog | 7 - + iscsiuio/INSTALL | 290 -- + iscsiuio/Makefile.am | 33 - + iscsiuio/NEWS | 0 + iscsiuio/README | 224 -- + iscsiuio/RELEASE.TXT | 2100 -------------- + iscsiuio/configure.ac | 104 - + iscsiuio/docs/iscsiuio.8 | 89 - + iscsiuio/iscsiuiolog | 10 - + iscsiuio/src/.gitignore | 1 - + iscsiuio/src/Makefile.am | 1 - + iscsiuio/src/README | 13 - + iscsiuio/src/apps/Makefile.am | 1 - + iscsiuio/src/apps/README | 2 - + iscsiuio/src/apps/brcm-iscsi/Makefile.am | 13 - + .../src/apps/brcm-iscsi/Makefile.brcm-iscsi | 1 - + iscsiuio/src/apps/brcm-iscsi/brcm_iscsi.c | 89 - + iscsiuio/src/apps/brcm-iscsi/brcm_iscsi.h | 91 - + iscsiuio/src/apps/dhcpc/Makefile.am | 13 - + iscsiuio/src/apps/dhcpc/Makefile.dhcpc | 1 - + iscsiuio/src/apps/dhcpc/dhcpc.c | 417 --- + iscsiuio/src/apps/dhcpc/dhcpc.h | 86 - + iscsiuio/src/apps/dhcpc/dhcpv6.c | 517 ---- + iscsiuio/src/apps/dhcpc/dhcpv6.h | 253 -- + iscsiuio/src/uip-1.0-changelog.txt | 98 - + iscsiuio/src/uip/Makefile.am | 18 - + iscsiuio/src/uip/Makefile.include | 47 - + iscsiuio/src/uip/clock.h | 87 - + iscsiuio/src/uip/debug.h | 13 - + iscsiuio/src/uip/icmpv6.h | 302 -- + iscsiuio/src/uip/ipv6.c | 1306 --------- + iscsiuio/src/uip/ipv6.h | 332 --- + iscsiuio/src/uip/ipv6_ndpc.c | 432 --- + iscsiuio/src/uip/ipv6_ndpc.h | 98 - + iscsiuio/src/uip/ipv6_pkt.h | 50 - + iscsiuio/src/uip/lc-addrlabels.h | 80 - + iscsiuio/src/uip/lc-switch.h | 73 - + iscsiuio/src/uip/lc.h | 130 - + iscsiuio/src/uip/psock.c | 339 --- + iscsiuio/src/uip/psock.h | 383 --- + iscsiuio/src/uip/pt.h | 322 --- + iscsiuio/src/uip/timer.c | 127 - + iscsiuio/src/uip/timer.h | 84 - + iscsiuio/src/uip/uip-neighbor.c | 219 -- + iscsiuio/src/uip/uip-neighbor.h | 105 - + iscsiuio/src/uip/uip.c | 2434 ----------------- + iscsiuio/src/uip/uip.h | 1574 ----------- + iscsiuio/src/uip/uip_arch.h | 137 - + iscsiuio/src/uip/uip_arp.c | 479 ---- + iscsiuio/src/uip/uip_arp.h | 197 -- + iscsiuio/src/uip/uip_eth.c | 50 - + iscsiuio/src/uip/uip_eth.h | 43 - + iscsiuio/src/uip/uipopt.h | 536 ---- + iscsiuio/src/unix/.gitignore | 3 - + iscsiuio/src/unix/Makefile.am | 41 - + iscsiuio/src/unix/clock-arch.c | 54 - + iscsiuio/src/unix/clock-arch.h | 39 - + iscsiuio/src/unix/iscsid_ipc.c | 1255 --------- + iscsiuio/src/unix/iscsid_ipc.h | 52 - + iscsiuio/src/unix/libs/Makefile.am | 14 - + iscsiuio/src/unix/libs/bnx2.c | 1165 -------- + iscsiuio/src/unix/libs/bnx2.h | 304 -- + iscsiuio/src/unix/libs/bnx2x.c | 1676 ------------ + iscsiuio/src/unix/libs/bnx2x.h | 715 ----- + iscsiuio/src/unix/libs/cnic.c | 671 ----- + iscsiuio/src/unix/libs/cnic.h | 57 - + iscsiuio/src/unix/libs/qedi.c | 1195 -------- + iscsiuio/src/unix/libs/qedi.h | 159 -- + iscsiuio/src/unix/logger.c | 181 -- + iscsiuio/src/unix/logger.h | 129 - + iscsiuio/src/unix/main.c | 442 --- + iscsiuio/src/unix/nic.c | 1548 ----------- + iscsiuio/src/unix/nic.h | 407 --- + iscsiuio/src/unix/nic_id.c | 364 --- + iscsiuio/src/unix/nic_id.h | 47 - + iscsiuio/src/unix/nic_nl.c | 680 ----- + iscsiuio/src/unix/nic_nl.h | 54 - + iscsiuio/src/unix/nic_utils.c | 1813 ------------ + iscsiuio/src/unix/nic_utils.h | 104 - + iscsiuio/src/unix/nic_vlan.c | 337 --- + iscsiuio/src/unix/nic_vlan.h | 89 - + iscsiuio/src/unix/options.h | 118 - + iscsiuio/src/unix/packet.c | 145 - + iscsiuio/src/unix/packet.h | 78 - + iscsiuio/src/unix/ping.c | 518 ---- + iscsiuio/src/unix/ping.h | 73 - + iscsiuio/src/unix/uip-conf.h | 160 -- + 91 files changed, 29192 deletions(-) + delete mode 100644 etc/systemd/iscsiuio.service + delete mode 100644 etc/systemd/iscsiuio.socket + delete mode 100644 iscsiuio/.gitignore + delete mode 100644 iscsiuio/AUTHORS + delete mode 100644 iscsiuio/ChangeLog + delete mode 100644 iscsiuio/INSTALL + delete mode 100644 iscsiuio/Makefile.am + delete mode 100644 iscsiuio/NEWS + delete mode 100644 iscsiuio/README + delete mode 100644 iscsiuio/RELEASE.TXT + delete mode 100644 iscsiuio/configure.ac + delete mode 100644 iscsiuio/docs/iscsiuio.8 + delete mode 100644 iscsiuio/iscsiuiolog + delete mode 100644 iscsiuio/src/.gitignore + delete mode 100644 iscsiuio/src/Makefile.am + delete mode 100644 iscsiuio/src/README + delete mode 100644 iscsiuio/src/apps/Makefile.am + delete mode 100644 iscsiuio/src/apps/README + delete mode 100644 iscsiuio/src/apps/brcm-iscsi/Makefile.am + delete mode 100644 iscsiuio/src/apps/brcm-iscsi/Makefile.brcm-iscsi + delete mode 100644 iscsiuio/src/apps/brcm-iscsi/brcm_iscsi.c + delete mode 100644 iscsiuio/src/apps/brcm-iscsi/brcm_iscsi.h + delete mode 100644 iscsiuio/src/apps/dhcpc/Makefile.am + delete mode 100644 iscsiuio/src/apps/dhcpc/Makefile.dhcpc + delete mode 100644 iscsiuio/src/apps/dhcpc/dhcpc.c + delete mode 100644 iscsiuio/src/apps/dhcpc/dhcpc.h + delete mode 100644 iscsiuio/src/apps/dhcpc/dhcpv6.c + delete mode 100644 iscsiuio/src/apps/dhcpc/dhcpv6.h + delete mode 100644 iscsiuio/src/uip-1.0-changelog.txt + delete mode 100644 iscsiuio/src/uip/Makefile.am + delete mode 100644 iscsiuio/src/uip/Makefile.include + delete mode 100644 iscsiuio/src/uip/clock.h + delete mode 100644 iscsiuio/src/uip/debug.h + delete mode 100644 iscsiuio/src/uip/icmpv6.h + delete mode 100644 iscsiuio/src/uip/ipv6.c + delete mode 100644 iscsiuio/src/uip/ipv6.h + delete mode 100644 iscsiuio/src/uip/ipv6_ndpc.c + delete mode 100644 iscsiuio/src/uip/ipv6_ndpc.h + delete mode 100644 iscsiuio/src/uip/ipv6_pkt.h + delete mode 100644 iscsiuio/src/uip/lc-addrlabels.h + delete mode 100644 iscsiuio/src/uip/lc-switch.h + delete mode 100644 iscsiuio/src/uip/lc.h + delete mode 100644 iscsiuio/src/uip/psock.c + delete mode 100644 iscsiuio/src/uip/psock.h + delete mode 100644 iscsiuio/src/uip/pt.h + delete mode 100644 iscsiuio/src/uip/timer.c + delete mode 100644 iscsiuio/src/uip/timer.h + delete mode 100644 iscsiuio/src/uip/uip-neighbor.c + delete mode 100644 iscsiuio/src/uip/uip-neighbor.h + delete mode 100644 iscsiuio/src/uip/uip.c + delete mode 100644 iscsiuio/src/uip/uip.h + delete mode 100644 iscsiuio/src/uip/uip_arch.h + delete mode 100644 iscsiuio/src/uip/uip_arp.c + delete mode 100644 iscsiuio/src/uip/uip_arp.h + delete mode 100644 iscsiuio/src/uip/uip_eth.c + delete mode 100644 iscsiuio/src/uip/uip_eth.h + delete mode 100644 iscsiuio/src/uip/uipopt.h + delete mode 100644 iscsiuio/src/unix/.gitignore + delete mode 100644 iscsiuio/src/unix/Makefile.am + delete mode 100644 iscsiuio/src/unix/clock-arch.c + delete mode 100644 iscsiuio/src/unix/clock-arch.h + delete mode 100644 iscsiuio/src/unix/iscsid_ipc.c + delete mode 100644 iscsiuio/src/unix/iscsid_ipc.h + delete mode 100644 iscsiuio/src/unix/libs/Makefile.am + delete mode 100644 iscsiuio/src/unix/libs/bnx2.c + delete mode 100644 iscsiuio/src/unix/libs/bnx2.h + delete mode 100644 iscsiuio/src/unix/libs/bnx2x.c + delete mode 100644 iscsiuio/src/unix/libs/bnx2x.h + delete mode 100644 iscsiuio/src/unix/libs/cnic.c + delete mode 100644 iscsiuio/src/unix/libs/cnic.h + delete mode 100644 iscsiuio/src/unix/libs/qedi.c + delete mode 100644 iscsiuio/src/unix/libs/qedi.h + delete mode 100644 iscsiuio/src/unix/logger.c + delete mode 100644 iscsiuio/src/unix/logger.h + delete mode 100644 iscsiuio/src/unix/main.c + delete mode 100644 iscsiuio/src/unix/nic.c + delete mode 100644 iscsiuio/src/unix/nic.h + delete mode 100644 iscsiuio/src/unix/nic_id.c + delete mode 100644 iscsiuio/src/unix/nic_id.h + delete mode 100644 iscsiuio/src/unix/nic_nl.c + delete mode 100644 iscsiuio/src/unix/nic_nl.h + delete mode 100644 iscsiuio/src/unix/nic_utils.c + delete mode 100644 iscsiuio/src/unix/nic_utils.h + delete mode 100644 iscsiuio/src/unix/nic_vlan.c + delete mode 100644 iscsiuio/src/unix/nic_vlan.h + delete mode 100644 iscsiuio/src/unix/options.h + delete mode 100644 iscsiuio/src/unix/packet.c + delete mode 100644 iscsiuio/src/unix/packet.h + delete mode 100644 iscsiuio/src/unix/ping.c + delete mode 100644 iscsiuio/src/unix/ping.h + delete mode 100644 iscsiuio/src/unix/uip-conf.h + +diff --git a/etc/systemd/iscsiuio.service b/etc/systemd/iscsiuio.service +deleted file mode 100644 +index 923e019..0000000 +--- a/etc/systemd/iscsiuio.service ++++ /dev/null +@@ -1,20 +0,0 @@ +-[Unit] +-Description=iSCSI UserSpace I/O driver +-Documentation=man:iscsiuio(8) +-DefaultDependencies=no +-Conflicts=shutdown.target +-Requires=iscsid.service +-BindTo=iscsid.service +-After=network.target +-Before=remote-fs-pre.target iscsid.service +-Wants=remote-fs-pre.target +- +-[Service] +-Type=notify +-NotifyAccess=main +-ExecStart=/sbin/iscsiuio -f +-KillMode=mixed +-Restart=on-failure +- +-[Install] +-WantedBy=multi-user.target +diff --git a/etc/systemd/iscsiuio.socket b/etc/systemd/iscsiuio.socket +deleted file mode 100644 +index d42cedc..0000000 +--- a/etc/systemd/iscsiuio.socket ++++ /dev/null +@@ -1,9 +0,0 @@ +-[Unit] +-Description=Open-iSCSI iscsiuio Socket +-Documentation=man:iscsiuio(8) +- +-[Socket] +-ListenStream=@ISCSID_UIP_ABSTRACT_NAMESPACE +- +-[Install] +-WantedBy=sockets.target +diff --git a/iscsiuio/.gitignore b/iscsiuio/.gitignore +deleted file mode 100644 +index a27452a..0000000 +--- a/iscsiuio/.gitignore ++++ /dev/null +@@ -1,25 +0,0 @@ +-# Autogenerated files +-stamp-h1 +-Makefile.in +-Makefile +-configure +-config.h.in +-config.h +-config.guess +-config.log +-config.status +-config.sub +-COPYING +- +-.deps +-autom4te.cache +- +-# autotools +-aclocal.m4 +-compile +-depcomp +-install-sh +-libtool +-ltmain.sh +-missing +- +diff --git a/iscsiuio/AUTHORS b/iscsiuio/AUTHORS +deleted file mode 100644 +index e69de29..0000000 +diff --git a/iscsiuio/ChangeLog b/iscsiuio/ChangeLog +deleted file mode 100644 +index a91b4d5..0000000 +--- a/iscsiuio/ChangeLog ++++ /dev/null +@@ -1,7 +0,0 @@ +-Version 0.4.1 (July 20, 2009) +- * Fix from Mike Christie to determine page size from getpagesize() +- rather then the constant PAGE_SIZE. PAGE_SIZE is not defined om +- ia64 and ppc. +- * Update documentation to indicate IPv6 is not supported +- * Fix code to catch the message from the CNIC that the network +- interface is going down. +diff --git a/iscsiuio/INSTALL b/iscsiuio/INSTALL +deleted file mode 100644 +index c9fd2c0..0000000 +--- a/iscsiuio/INSTALL ++++ /dev/null +@@ -1,290 +0,0 @@ +-Installation Instructions +-************************* +- +-Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, +-2006, 2007, 2008 Free Software Foundation, Inc. +- +- This file is free documentation; the Free Software Foundation gives +-unlimited permission to copy, distribute and modify it. +- +-Basic Installation +-================== +- +- Briefly, the shell commands `./configure; make; make install' should +-configure, build, and install this package. The following +-more-detailed instructions are generic; see the `README' file for +-instructions specific to this package. +- +- The `configure' shell script attempts to guess correct values for +-various system-dependent variables used during compilation. It uses +-those values to create a `Makefile' in each directory of the package. +-It may also create one or more `.h' files containing system-dependent +-definitions. Finally, it creates a shell script `config.status' that +-you can run in the future to recreate the current configuration, and a +-file `config.log' containing compiler output (useful mainly for +-debugging `configure'). +- +- It can also use an optional file (typically called `config.cache' +-and enabled with `--cache-file=config.cache' or simply `-C') that saves +-the results of its tests to speed up reconfiguring. Caching is +-disabled by default to prevent problems with accidental use of stale +-cache files. +- +- If you need to do unusual things to compile the package, please try +-to figure out how `configure' could check whether to do them, and mail +-diffs or instructions to the address given in the `README' so they can +-be considered for the next release. If you are using the cache, and at +-some point `config.cache' contains results you don't want to keep, you +-may remove or edit it. +- +- The file `configure.ac' (or `configure.in') is used to create +-`configure' by a program called `autoconf'. You need `configure.ac' if +-you want to change it or regenerate `configure' using a newer version +-of `autoconf'. +- +-The simplest way to compile this package is: +- +- 1. `cd' to the directory containing the package's source code and type +- `./configure' to configure the package for your system. +- +- Running `configure' might take a while. While running, it prints +- some messages telling which features it is checking for. +- +- 2. Type `make' to compile the package. +- +- 3. Optionally, type `make check' to run any self-tests that come with +- the package. +- +- 4. Type `make install' to install the programs and any data files and +- documentation. +- +- 5. You can remove the program binaries and object files from the +- source code directory by typing `make clean'. To also remove the +- files that `configure' created (so you can compile the package for +- a different kind of computer), type `make distclean'. There is +- also a `make maintainer-clean' target, but that is intended mainly +- for the package's developers. If you use it, you may have to get +- all sorts of other programs in order to regenerate files that came +- with the distribution. +- +- 6. Often, you can also type `make uninstall' to remove the installed +- files again. +- +-Compilers and Options +-===================== +- +- Some systems require unusual options for compilation or linking that +-the `configure' script does not know about. Run `./configure --help' +-for details on some of the pertinent environment variables. +- +- You can give `configure' initial values for configuration parameters +-by setting variables in the command line or in the environment. Here +-is an example: +- +- ./configure CC=c99 CFLAGS=-g LIBS=-lposix +- +- *Note Defining Variables::, for more details. +- +-Compiling For Multiple Architectures +-==================================== +- +- You can compile the package for more than one kind of computer at the +-same time, by placing the object files for each architecture in their +-own directory. To do this, you can use GNU `make'. `cd' to the +-directory where you want the object files and executables to go and run +-the `configure' script. `configure' automatically checks for the +-source code in the directory that `configure' is in and in `..'. +- +- With a non-GNU `make', it is safer to compile the package for one +-architecture at a time in the source code directory. After you have +-installed the package for one architecture, use `make distclean' before +-reconfiguring for another architecture. +- +- On MacOS X 10.5 and later systems, you can create libraries and +-executables that work on multiple system types--known as "fat" or +-"universal" binaries--by specifying multiple `-arch' options to the +-compiler but only a single `-arch' option to the preprocessor. Like +-this: +- +- ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ +- CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ +- CPP="gcc -E" CXXCPP="g++ -E" +- +- This is not guaranteed to produce working output in all cases, you +-may have to build one architecture at a time and combine the results +-using the `lipo' tool if you have problems. +- +-Installation Names +-================== +- +- By default, `make install' installs the package's commands under +-`/usr/local/bin', include files under `/usr/local/include', etc. You +-can specify an installation prefix other than `/usr/local' by giving +-`configure' the option `--prefix=PREFIX'. +- +- You can specify separate installation prefixes for +-architecture-specific files and architecture-independent files. If you +-pass the option `--exec-prefix=PREFIX' to `configure', the package uses +-PREFIX as the prefix for installing programs and libraries. +-Documentation and other data files still use the regular prefix. +- +- In addition, if you use an unusual directory layout you can give +-options like `--bindir=DIR' to specify different values for particular +-kinds of files. Run `configure --help' for a list of the directories +-you can set and what kinds of files go in them. +- +- If the package supports it, you can cause programs to be installed +-with an extra prefix or suffix on their names by giving `configure' the +-option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. +- +-Optional Features +-================= +- +- Some packages pay attention to `--enable-FEATURE' options to +-`configure', where FEATURE indicates an optional part of the package. +-They may also pay attention to `--with-PACKAGE' options, where PACKAGE +-is something like `gnu-as' or `x' (for the X Window System). The +-`README' should mention any `--enable-' and `--with-' options that the +-package recognizes. +- +- For packages that use the X Window System, `configure' can usually +-find the X include and library files automatically, but if it doesn't, +-you can use the `configure' options `--x-includes=DIR' and +-`--x-libraries=DIR' to specify their locations. +- +-Particular systems +-================== +- +- On HP-UX, the default C compiler is not ANSI C compatible. If GNU +-CC is not installed, it is recommended to use the following options in +-order to use an ANSI C compiler: +- +- ./configure CC="cc -Ae" +- +-and if that doesn't work, install pre-built binaries of GCC for HP-UX. +- +- On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot +-parse its `' header file. The option `-nodtk' can be used as +-a workaround. If GNU CC is not installed, it is therefore recommended +-to try +- +- ./configure CC="cc" +- +-and if that doesn't work, try +- +- ./configure CC="cc -nodtk" +- +-Specifying the System Type +-========================== +- +- There may be some features `configure' cannot figure out +-automatically, but needs to determine by the type of machine the package +-will run on. Usually, assuming the package is built to be run on the +-_same_ architectures, `configure' can figure that out, but if it prints +-a message saying it cannot guess the machine type, give it the +-`--build=TYPE' option. TYPE can either be a short name for the system +-type, such as `sun4', or a canonical name which has the form: +- +- CPU-COMPANY-SYSTEM +- +-where SYSTEM can have one of these forms: +- +- OS KERNEL-OS +- +- See the file `config.sub' for the possible values of each field. If +-`config.sub' isn't included in this package, then this package doesn't +-need to know the machine type. +- +- If you are _building_ compiler tools for cross-compiling, you should +-use the option `--target=TYPE' to select the type of system they will +-produce code for. +- +- If you want to _use_ a cross compiler, that generates code for a +-platform different from the build platform, you should specify the +-"host" platform (i.e., that on which the generated programs will +-eventually be run) with `--host=TYPE'. +- +-Sharing Defaults +-================ +- +- If you want to set default values for `configure' scripts to share, +-you can create a site shell script called `config.site' that gives +-default values for variables like `CC', `cache_file', and `prefix'. +-`configure' looks for `PREFIX/share/config.site' if it exists, then +-`PREFIX/etc/config.site' if it exists. Or, you can set the +-`CONFIG_SITE' environment variable to the location of the site script. +-A warning: not all `configure' scripts look for a site script. +- +-Defining Variables +-================== +- +- Variables not defined in a site shell script can be set in the +-environment passed to `configure'. However, some packages may run +-configure again during the build, and the customized values of these +-variables may be lost. In order to avoid this problem, you should set +-them in the `configure' command line, using `VAR=value'. For example: +- +- ./configure CC=/usr/local2/bin/gcc +- +-causes the specified `gcc' to be used as the C compiler (unless it is +-overridden in the site shell script). +- +-Unfortunately, this technique does not work for `CONFIG_SHELL' due to +-an Autoconf bug. Until the bug is fixed you can use this workaround: +- +- CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash +- +-`configure' Invocation +-====================== +- +- `configure' recognizes the following options to control how it +-operates. +- +-`--help' +-`-h' +- Print a summary of all of the options to `configure', and exit. +- +-`--help=short' +-`--help=recursive' +- Print a summary of the options unique to this package's +- `configure', and exit. The `short' variant lists options used +- only in the top level, while the `recursive' variant lists options +- also present in any nested packages. +- +-`--version' +-`-V' +- Print the version of Autoconf used to generate the `configure' +- script, and exit. +- +-`--cache-file=FILE' +- Enable the cache: use and save the results of the tests in FILE, +- traditionally `config.cache'. FILE defaults to `/dev/null' to +- disable caching. +- +-`--config-cache' +-`-C' +- Alias for `--cache-file=config.cache'. +- +-`--quiet' +-`--silent' +-`-q' +- Do not print messages saying which checks are being made. To +- suppress all normal output, redirect it to `/dev/null' (any error +- messages will still be shown). +- +-`--srcdir=DIR' +- Look for the package's source code in directory DIR. Usually +- `configure' can determine that directory automatically. +- +-`--prefix=DIR' +- Use DIR as the installation prefix. *Note Installation Names:: +- for more details, including other options available for fine-tuning +- the installation locations. +- +-`--no-create' +-`-n' +- Run the configure checks, but stop before creating any output +- files. +- +-`configure' also accepts some other, not widely useful, options. Run +-`configure --help' for more details. +diff --git a/iscsiuio/Makefile.am b/iscsiuio/Makefile.am +deleted file mode 100644 +index 97f478f..0000000 +--- a/iscsiuio/Makefile.am ++++ /dev/null +@@ -1,33 +0,0 @@ +-SUBDIRS= src +- +-EXTRA_DIST = build_date +- +-build_date: +- if [ -n "$$SOURCE_DATE_EPOCH" ] ; then \ +- echo 'char *build_date = "'`LC_ALL=C.UTF-8 date --date=@$$SOURCE_DATE_EPOCH -u`'";' > build_date.c ; \ +- else \ +- echo 'char *build_date = "'`date`'";' > build_date.c ; \ +- fi +- echo 'char *build_date;'> build_date.h +- +-manprefix = /usr/share +-mandir = ${manprefix}/man +-logdir = /etc/logrotate.d +- +-install-am: all-am +- @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am install-man install-log install-brcm +- +-install-man: +- cat docs/iscsiuio.8 | GZIP=$(GZIP_ENV) gzip -c > iscsiuio.8.gz +- $(INSTALL) -d $(DESTDIR)$(mandir)/man8/ +- $(INSTALL_DATA) iscsiuio.8.gz $(DESTDIR)$(mandir)/man8/ +- +-install-log: +- $(INSTALL) -d $(DESTDIR)$(logdir)/ +- $(INSTALL_DATA) iscsiuiolog $(DESTDIR)$(logdir)/ +- +-install-brcm: +- $(RM) $(DESTDIR)$(sbindir)/brcm_iscsiuio +- (cd $(DESTDIR)/$(sbindir); \ +- $(RM) brcm_iscsiuio; \ +- $(LN_S) iscsiuio brcm_iscsiuio) +diff --git a/iscsiuio/NEWS b/iscsiuio/NEWS +deleted file mode 100644 +index e69de29..0000000 +diff --git a/iscsiuio/README b/iscsiuio/README +deleted file mode 100644 +index 53b700c..0000000 +--- a/iscsiuio/README ++++ /dev/null +@@ -1,224 +0,0 @@ +-Iscsiuio Userspace Tool +-Version 0.7.8.6 +-Jun 27, 2019 +------------------------------------------------------- +- +-This tool is to be used in conjunction with the QLogic NetXtreme II Linux +-driver (Kernel module name: 'bnx2' and 'bnx2x'), QLogic CNIC driver, +-and the QLogic iSCSI driver (Kernel module name: 'bnx2i'). +-This user space tool is used in conjunction with the following +-QLogic Network Controllers: +- bnx2: BCM5706, BCM5708, BCM5709 devices +- bnx2x: BCM57710, BCM57711, BCM57711E, BCM57712, BCM57712E, +- BCM57800, BCM57810, BCM57840 devices +- +-This utility will provide the ARP and DHCP functionality for the iSCSI offload. +-The communication to the driver is done via Userspace I/O (Kernel module name +-'uio'). +- +-There is one component to this application: +- +-1. 'iscsiuio' - This is the daemon which aids in creating iSCSI offloaded +- connections. +- +-Dependencies: +-======================================= +- +-Linux Kernel Dependencies: +-1. QLogic CNIC driver (cnic) +-1. QLogic iSCSI offload driver (bnx2i) +-2. Userspace I/O driver (uio) +- +-Directory Structure of this Package: +-======================================= +- +- +- | +- +-doc (documentation directory: man pages) +- | +- +-src +- | +- +- uip - the uIP stack +- | +- +- unix - iscsiuio source +- +- +- +-Compiling / Installing +-======================================= +- +-1. Please untar the tarball. +-2. Run the configure script. This will create the Makefiles and proper +- header files needed for the build. +-3. Run 'make'. This will create the binary, 'iscsiuio' +-4. Run 'make install' to place the binaries in their installed location. +- (The default location is '/sbin') +- +-iscsid IFACE Configuration File: +-======================================= +-The network interface configuration files are driven by the iscsid iface +-files. The configuration data is parsed by iscsid and passed to the uIP +-stack when the connection is established. +- +-One can use the following iscsiadm commands to create/set the configuration +-using the iface files: +- +-1. Create the iface file: +- +- iscsiadm -m iface -I --op=new +- +-2. Discover the targets associated with the new iface +- +- iscsiadm -m discovery -t st -p -I +- +-3. Update the iface file: +- +- To use a static IPv4 address: +- iscsiadm -m iface -I --op=update --name=iface.ipaddress --value= +- +- To use a DHCP address: +- iscsiadm -m iface -I --op=update --name=iface.ipaddress --value=0.0.0.0 +- +- The following values are required. +- +- To specify the bnx2i as the transport: +- iscsiadm -m iface -I --op=update --name=iface.transport_name --value=bnx2i +- +- To specify the network interface to offload with: +- +- a. Specify the physical network interface name +- iscsiadm -m iface -I --op=update --name=iface.net_ifacename --value= +- +- b. Specify the iSCSI MAC address of the iSCSI HBA +- iscsiadm -m iface -I --op=update --name=iface.hwaddress --value= +- +-4. Now all the settings should be set so that one could connect to their +- desired iSCSI target. +- +- iscsiadm -m node -p -T -I --login +- +-bnx2 Limitations: +-======================================= +-* RX iSCSI ring: +- * default ring size is 3 entries +- * default buffer size is 0x400 bytes +-* TX iSCSI ring: +- * default ring size of 1 entry +- * default buffer size is 0x400 bytes +- +-bnx2x Limitations: +-======================================= +-* RX iSCSI ring: +- * default ring size is 15 entries +- * default buffer size is 0x400 bytes +-* TX iSCSI ring: +- * default ring size of 1 entry +- * default buffer size is 0x400 bytes +- +-Other Limiations: +- +-Any packets larger then the buffer size will not be sent/received by the +-hardware and will be dropped. +- +-IPv6 support: +- +-IPv6 NDP (neighbor discovery protocol), DHCPv6 and Static IPv6 are now +-supported. The IPv6 address used for the connection will be matched against +-the DHCPv6/static IPv6 address, the RA (router advertise) address, and the +-assigned link local address. +- +-VLAN support: +- +-VLAN support is only supported when using static IP addresses. +-Also, currently only 1 VLAN is supported per physical network interface. +-Either non-VLAN offloaded traffic is allowed or VLAN offloaded traffic +-is allowed. The current implementation does not support both at the +-same time. +- +-Currently there is no explicit VLAN attributes in the iface file. +-To configure the VLAN offload, the iface.hwaddress attribute or +-physical net_ifacename (without the VLAN identifier) must be used +-to specify the HBA device. For the proper CNIC routing, the +-corresponding L2 interface which has the associated VLAN interface must +-have an IP address on the same subnet. +- +-The following attributes need to be filled when offloading via the +-VLAN interface: +- +- iface.iscsi_ifacename = +- iface.hwaddress = XX:XX:XX:XX:XX:XX +- iface.ipaddress = XX.XX.XX.XX +- iface.transport_name = bnx2i +- +-Setting IP address: +- +-On RHEL5.4, RHEL5.5+, RHEL6.0+, and SLES11SP1 distributions, +-discovery login is done over the Linux TCP/IP stack and L2 network +-interface. The ethx interface corresponding to the HBA must +-therefore be in the same IP subnet in order to reach the iSCSI +-target during discovery. However, the HBA's IP address should not +-be the same as the L2 ethx's IP address. +- +-Starting with RHEL6.1 and all other newer distributions, discovery +-using SendTargets is done over the HBA interface, so there is no +-need for the HBA and L2 network to be on the same subnet. However, +-if VLAN is used on the HBA, they still have to be on the same subnet +-as described above. +- +- +-Setting Netmask and Gateway addresses: +- +-With the current limitations of the iface file, there are no entries +-to allow the user to enter a netmask or gateway IP address. +- +-The only way to explicitly configure these options is to use DHCP +-addressing. Then the netmask/gateway are set on the DHCP server. +-These settings are then sent to uIP via the DHCPOFFERs. +- +-If the netmask is not defined then the netmask are automatically +-generated depending on the destination IP address. +- +-Debugging: +-======================================= +- +-By default, the iscsiuio daemon does not output any messages to the log file, +-'/var/log/iscsiuio.log'. Message logging is only enabled when the daemon is +-run under debug mode. +- +-To run the daemon in debug mode please pass the parameter '-d ' +- +-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 +- +-A sample banner message: +- +-INFO [Mon Jun 20 11:23:14 2011]Started iSCSI uio stack: Ver 0.7.0.6 +-INFO [Mon Jun 20 11:23:14 2011]Build date: Mon Jun 20 11:22:05 PDT 2011 +-INFO [Mon Jun 20 11:23:14 2011]Debug mode enabled +- +-These messages can be used to help debug any issues. +- +-When debugging issues like the iscsid, the iscsiuio daemon can be run +-in the foreground and the maximum debugging level should be used. +- +-To place the daemon in foreground mode please pass the parameter '-f' +- +-Note: The messages to the log file are not flushed unless debugging is enabled. +- +-Note: If the daemon iscsiuio is running, one will not be able to +- trample over the existing binary. One might see the following message: +- +- 'cannot create regular file `/sbin/iscsiuio': Text file busy' +- +- The solve this, please stop the iscsid service and then install. +- +-Warning: If full debug is enabled, this may quickly fill the partition +-containing the iscsiuio logs. This is because full debugging will log +-packet activity which on a busy network will quickly fill the logs. +- +-Note: If the bnx2i and cnic drivers are unloaded, then iscsiuio will also +-need to be restarted so that it can determine the iscsid version. +diff --git a/iscsiuio/RELEASE.TXT b/iscsiuio/RELEASE.TXT +deleted file mode 100644 +index 28e681b..0000000 +--- a/iscsiuio/RELEASE.TXT ++++ /dev/null +@@ -1,2100 +0,0 @@ +- Release Notes +- QLogic uIP Linux Driver +- Version 0.7.8.6 +- 06/27/2019 +- +- QLogic Corporation +- 26650 Aliso Viejo Pkwy, +- Aliso Viejo, CA 92656 +- +- Copyright (c) 2004 - 2013 Broadcom Corporation +- Copyright (c) 2014, QLogic Corporation +- All rights reserved +- +-uIP v0.7.8.6 (Jun 27, 2019) +-======================================================= +- Fixes: +- ------- +- 1. Problem: OS fails to boot after one path is +- disconnected from iSCSI MPIO config. +- Change: In the event of DHCP failure, killing of enable_nic_thread did +- not process any iscsid requests leading to error, +- iscsistart: Could not broadcast to uIP after 5 tries +- and login failure of active path. +- Added fix to not kill enable_nic_thread and allow further +- processing of iscsid requests and performing login +- to next active path. +- Impact: All +- +-uIP v0.7.8.5 (Nov 20, 2018) +-======================================================= +- Fixes: +- ------- +- 1. Problem: CQ102578: observing ISCSI initiator IP ping drop +- Change: 1. Do not flush tx queue on each uio interrupt +- 2. Use UIO BD index instead on buffer index. +- 3. Set buf_size in case of ICMP and ARP packet +- Impact: QL41xxx adapters +- +- 2. Problem: CQ103034 - Unable to boot iSCSI BFS in IPv6 DHCP config +- Change: Limit retries of performing dhcpv6 before declaring dhcp failure +- Impact: All +- +- 3. Problem: CQ102438: I/O fails to resume on multipath LUN during port toggle. +- Change: lib/cnic, lib/qedi, Release xmit_mutex in error code path and +- during clear tx queue. +- Impact: QL84xx adapters +- +- 4. Problem: Netlink buffer corruption when more than one host +- try to xmit packet at the same time +- Change: Add inter-host mutex while doing xmit +- Impact: All +- +-uIP v0.7.8.4 (Feb 22, 2018) +-======================================================= +- Fixes: +- ------- +- 1. Problem: CQ95605: iSCSI BFS in DHCP config intermittently fails to boot +- into the OS when source and destination addresses are in +- different networks. +- Change: Allow ARP for non-matching source and destination addresses. +- For source and destination IP addresses in different networks, +- continue with the ARP retries and further login process +- instead of assuming abrupt failure. iSCSI offload adapters +- may not rely on netmask information for successful iSCSI +- target login. +- Impact: All +- +-uIP v0.7.8.3 (May 18, 2017) +-======================================================= +- Fixes: +- ------- +- 1. Problem: CQ93985: iscsiuio seg faults if discovery done to not +- reachable target +- Change: Serialize xmit_mutex lock to prevent iscsiuio seg fault. +- Impact: All +- +- 2. Problem: CQ91497 - Initiator fails to acquire IPv6 DHCP address +- from the DHCP server +- Change: Initialize the transaction-id within the dhcpv6 packet with +- correct byte order, to fix the trans-id mismatch error. +- Impact: All +- +- 3. Problem: Missing qedi ping transport hook +- Change: Add qedi ping transport hook +- Impact: 10/25/40/50GGbE Controller (iSCSI) +- +-uIP v0.7.8.3 (Sept 28, 2016) +-======================================================= +- Enhancements +- ------------ +- 1. Change: Add support for the new qedi transport +- Impact: 10/25/40/50GGbE Controller (iSCSI) +- +-uIP v0.7.8.2 (Dec 10, 2013) +-======================================================= +- Fixes +- ----- +- 1. Problem: Cont00072053 - Some hardware iSCSI paths fail during test +- Cause: The test exercised a corner case where the ARP cache flush +- mechanism didn't work properly +- Change: Fixed the ARP cache flush mechanism +- Impact: All +- +- Enhancements +- ------------ +- 1. Change: Added a new tx doorbell field in the uio path to work with +- the new bnx2x/cnic drivers that supports VF_RSS +- Impact: 10G only +- +- 2. Change: Fixed the iface.subnet_mask decoding for IPv6 +- Impact: IPv6 +- +- +-uIP v0.7.8.1b (May 01, 2013) +-======================================================= +- Enhancements +- ------------ +- 1. Change: Performance optimization by caching the page size +- Impact: All +- +- 2. Change: Fixed a bug in the tx completion interrupt handler +- Impact: 10G only +- +- +-uIP v0.7.6.1g (Jan 14, 2013) +-======================================================= +- Fixes +- ----- +- 1. Problem: Cont00067316 - IPv6 address prefix length < 32 +- bits fails to connect +- Cause: CIDR notation has an order bug in the IPv6 section +- whenever the prefix length specified is < 32 +- Change: Fixed the network order bug +- Impact: IPv6 only +- +- +-uIP v0.7.6.1f (Nov 14, 2012) +-======================================================= +- Fixes +- ----- +- 1. Problem: Cont00065768 - RHEL5.X iscsiuio segfault possible +- if there is a specific 1024 byte size broadcast +- packet +- Cause: This is another corner case where the packet size +- is also exactly 1024 bytes + padding that exceeded +- the DMA rx buffer. The previous fix was not +- sufficient +- Change: Ensure that the packet size + padding do not +- exceed this limit. +- Impact: 10G only. 1G already has the guard against it. +- +- +-uIP v0.7.6.1e (Nov 07, 2012) +-======================================================= +- Fixes +- ----- +- 1. Problem: Cont00066397 - Unable to connect to iSCSI target +- with NPAR enabled on 57840 +- Cause: The PCI device ID for 57840_MF has been changed from +- 0x16ab to 0x16a4 +- Change: Updated the PCI id table to match exactly what the +- bnx2x 1.76 indicates +- Impact: 57840 MF +- +- +-uIP v0.7.6.1d (Oct 31, 2012) +-======================================================= +- Enhancements +- ------------ +- 1. Change: Added support for open-iscsi-2.0.873 +- Impact: All +- +- +-uIP v0.7.6.1c (Oct 15, 2012) +-======================================================= +- Enhancements +- ------------ +- 1. Change: Added support for 10G 57840 4x10 and 2x20 +- Impact: 10G 57840 +- +- +-uIP v0.7.6.1b (Oct 09, 2012) +-======================================================= +- Fixes +- ----- +- 1. Problem: Cont00065690 - Vconfig method of connecting over +- tagged vlan with IPv6 failed +- Cause: The new net param support changes has prevented +- the old vconfig method from execising the IPv6 +- acquisition engine properly +- Change: Ensure that this old vconfig method to run the IPv6 +- acquisition engine properly and to its entirety +- Impact: IPv6 + VLAN using the network VLAN configuration +- method +- +- 2. Problem: Cont00065768 - RHEL5.X iscsiuio segfault possible +- if there is a specific 1024 byte size broadcast +- packet +- Cause: This is a corner case where the packet size is +- exactly 1024 bytes + padding that exceeded the +- DMA rx buffer. This has been there since day 1. +- Change: Ensure that the packet size + padding do not +- exceed this limit. +- Impact: 10G only. 1G already has the guard against it. +- +- +- Enhancements +- ------------ +- 1. Change: Source optimization - backported source code fixes +- as reported from the upstream submission patch +- Impact: ALL +- +- +-uIP v0.7.4.2k (Aug 10, 2012) +-======================================================= +- Enhancements +- ------------ +- 1. Change: Enable HP SD mode +- Impact: 577XX/578XX +- +- +-uIP v0.7.4.2j (Jul 18, 2012) +-======================================================= +- Fixes +- ----- +- 1. 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 +- +- 2. 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 +- +- +-uIP v0.7.4.2i (Jul 11, 2012) +-======================================================= +- Fixes +- ----- +- 1. 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 +- +- +-uIP v0.7.4.2h (Jun 15, 2012) +-======================================================= +- Fixes +- ----- +- 1. 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 +- +- +-uIP v0.7.4.2g (Jun 08, 2012) +-======================================================= +- Fixes +- ----- +- 1. 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 +- +- +-uIP v0.7.4.2f (Jun 04, 2012) +-======================================================= +- Fixes +- ----- +- 1. 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 +- +- 2. 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 +- +- +-uIP v0.7.4.2e (May 30, 2012) +-======================================================= +- Fixes +- ----- +- 1. Problem: Cont00063443 - Compilation error on SLES11sp1 +- Cause: The iface_num field was not defined +- Change: Fixed all references to iface_num +- Impact: SLES11sp1 +- +- 2. 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 +- +- 3. 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 +- +- Enhancements +- ------------ +- 1. Added support for jumbo MTU (independent from the L2 MTU) +- +- +-uIP v0.7.4.2d (May 21, 2012) +-======================================================= +- Fixes +- ----- +- 1. 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 +- +- Enhancements +- ------------ +- 1. Allow VLAN tag = 1 (router management) to connect offload +- +- +-uIP v0.7.4.2c (May 09, 2012) +-======================================================= +- Fixes +- ----- +- 1. 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 +- +- 2. 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 +- +- +-uIP v0.7.4.2b (May 01, 2012) +-======================================================= +- Fixes +- ----- +- 1. 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 +- +- +-uIP v0.7.4.1j (Apr 24, 2012) +-======================================================= +- Fixes +- ----- +- 1. 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 +- +- +-uIP v0.7.4.1i (Apr 16, 2012) +-======================================================= +- Fixes +- ----- +- 1. 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 +- +- +-uIP v0.7.4.1h (Apr 13, 2012) +-======================================================= +- Enhancements +- ------------ +- 1. Added support for the new iface_num field in the iscsi_uevent +- path +- +- 2. Fixed bug in the nic_iface search engine based on iface_num +- +- +-uIP v0.7.4.1g (Mar 22, 2012) +-======================================================= +- Fixes +- ----- +- 1. 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 +- +- 2. 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 +- +- +-uIP v0.7.4.1f (Mar 19, 2012) +-======================================================= +- Fixes +- ----- +- 1. 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 +- +- +-uIP v0.7.4.1e (Mar 08, 2012) +-======================================================= +- Fixes +- ----- +- 1. 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 +- +- +-uIP v0.7.4.1d (Mar 02, 2012) +-======================================================= +- Fixes +- ----- +- 1. Problem: Cont00061708 - Unable to log into target after running +- driver load/unload +- Cause: A bug was introduced in the previous bug fix (CQ61459) +- where a pthread_cond_broadcast call was erroneously +- enabled +- Change: Restored this back +- Impact: All +- +- +-uIP v0.7.4.1c (Feb 16, 2012) +-======================================================= +- Fixes +- ----- +- 1. 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 +- +- Enhancements +- ------------ +- 1. Updated README +- +- +-uIP v0.7.4.1b (Feb 08, 2012) +-======================================================= +- Fixes +- ----- +- 1. 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 +- +- +-uIP v0.7.4.1a (Feb 01, 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 +- +- +- 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 +- +- +-uIP v0.7.2.1e (Jan 05, 2012) +-======================================================= +- Fixes +- ----- +- 1. Problem: Cont00060734 - ifupdown-mtu change stress with active +- session causes iscsiuio to fail +- Change: Fixed a race condition between the nic enable thread +- and when DHCP fails +- Impact: All +- +- +-uIP v0.7.2.1d (Dec 28, 2011) +-======================================================= +- Fixes +- ----- +- 1. Problem: Cont00060368 - segfault observed after failing both +- mpio paths +- Change: Various memory leaks were identified and resolved in +- the nic cleanup path +- Impact: All +- +- +-uIP v0.7.2.1c (Dec 16, 2011) +-======================================================= +- Enhancements +- ------------ +- 1. Change: Disable HP SD mode +- +- +-uIP v0.7.2.1b (Dec 14, 2011) +-======================================================= +- Enhancements +- ------------ +- 1. Change: Default iscsiuio logging to off. Use the '-d' +- option to enable +- +- +-uIP v0.7.0.14g (Oct 25, 2011) +-======================================================= +- Enhancements +- ------------ +- 1. Change: Fixed the compilation under RHEL6.2 +- 2. Change: Added oom_adjust call to prevent OOM Killer from killing +- iscsiuio when memory is low +- 3. Change: Added mlockall setting to prevent page swap +- +- +-uIP v0.7.0.14f (Oct 20, 2011) +-======================================================= +- Fixes +- ----- +- 1. Problem: Cont00058994 - DOS vulnerability in uip during UDP flood +- Cause: The warning messages from the UDP handler was logging +- at a rate faster than the log file logrotate rate +- Therefore, the system's OOM eventually got kicked in to +- start terminating running processes which includes iscsiuio +- Change: Moved several UDP warning messages from the default log +- level to the debug log level +- Impact: All (minor) +- +- 2. Problem: Cont00059288 - Show segfault w/ SLES11 SP1 Xen kernel +- Cause: The bnx2x chip_id was not read correctly from the PCIe BAR1 +- under the Xen kernel. The error was in the mmap area. +- Change: Corrected the mmapping of the PCI MMIO space. +- Impact: Xen kernels +- +- Enhancements +- ------------ +- 1. Change: Changed the log file open error to a warning and let +- the daemon progress. This was only observed under iSCSI boot +- +- +-uIP v0.7.0.14e (Sep 19, 2011) +-======================================================= +- Fixes +- ----- +- 1. Problem: Cont00058678 - Can not iboot target from ipv6 path +- using VLAN +- Cause: A bug was found in the path request path where the vlan +- iface's protocol family was not used correctly in the +- iface search +- Change: This has been corrected +- +- +-uIP v0.7.0.14d (Sep 16, 2011) +-======================================================= +- Fixes +- ----- +- 1. Problem: Cont00058602 - Can't iboot using IPv6 offload path +- Cause: The bug was exposed by a fix in 0.7.0.14c where the +- IPv6 router solicitation timeout exceeded the nic +- enable thread timeout. +- Change: The IPv6 router solicitation timeout has been adjusted +- +- +-uIP v0.7.0.14c (Sep 01, 2011) +-======================================================= +- Fixes +- ----- +- 1. Problem: Cont00058256 - Sessions fail after loginstress to via +- simultaneous ipv4 and ipv6 dhcp +- Cause: Switching between DHCPv4/v6 coupled with VLAN exposed +- a drawback in our nic_iface architecture design where +- VLAN is not specified by iscsid. +- Change: The code was optimized and improved the performance when +- switching between DHCPv4/v6+VLAN. However, the ultimate +- fix is to make use of the net config parameters introduced +- in the newer open-iscsi util which will identify the +- specific VLAN nic_iface to use. +- +- Enhancements +- ------------ +- 1. Change: Added support for bnx2x-1.71.00 +- +- +-uIP v0.7.0.14b (Aug 23, 2011) +-======================================================= +- Fixes +- ----- +- 1. Problem: Cont00057840 - RHEL6.2 inbox: Unable to connect to +- targets with 5709 +- Cause: For cases when the bnx2/bnx2x driver gets removed, the +- uio database that was built by cnic would have the device +- ->net reference removed. This has caused an unnecessary +- timeout of 5s for each stale uio entry in the database. +- Change: Adjusted the routine which seeks the device->net entry +- to include more logic instead of hard waiting for 5s. +- +- Enhancements +- ------------ +- 1. Change: Added support for RHEL6.2 for out-of-box release +- 2. Change: Updated the man page with -h and -p info +- 3. Change: Updated the -h info +- +- +-uIP v0.7.0.13 (Aug 10, 2011) +-======================================================= +- Fixes +- ----- +- 1. Problem: Cont00057768 - iscsiuio logrotate causes daemon failure +- Cause: The logrotate script will send a SIGUSR1 signal to notify +- the iscsiuio daemon of such action. However, the daemon +- wasn't programmed to catch this signal. +- Change: Restored the catching of this signal +- +- +-uIP v0.7.0.12 (Aug 04, 2011) +-======================================================= +- Fixes +- ----- +- 1. Problem: Cont00050634 - brcm_iscsiuio Tainted: running IoZone, +- Iometer and receiving a UDP flood on 3260 +- Cause: Upon iscsiuio termination, because of the UDP flood, +- the nic thread will be busy servicing those UDP packets +- while the signal handling thread will free up all nic +- resources. The two threads were not in sync. +- Change: Added a nic_remove_all routine to destroy all nic threads +- before the nic resources get freed. +- +- Enhancements +- ------------ +- 1. Change: Fixed all warnings as reported by RHELS' Coverity testing. +- +- +-uIP v0.7.0.11 (Aug 02, 2011) +-======================================================= +- Fixes +- ----- +- 1. Problem: Erroneous VLAN tag was being passed by iscsid for connect +- request +- Cause: The iscsid's iface_rec_t ipc message does not contain this +- vlan field. This field was added in uIP for future vlan +- support. Since the buffer allocated to receive such message +- in uIP didn't get initialized, therefore, garbled up VLAN +- tag was getting used. +- Change: Added the initialization of this buffer. +- +- +-uIP v0.7.0.10 (Jul 26, 2011) +-======================================================= +- Fixes +- ----- +- 1. Problem: Can't offload when switching from Static to DHCP then back to +- Static IPv4 when connecting through a VLAN interface +- Cause: The VLAN processing code did not reinstall the IP address +- from the default nic_iface to the associated VLAN nic_iface. +- This was only done on the very first time when the VLAN +- interface was created and not on subsequent instances. +- Change: Added code to mirror the default nic_iface IP/netmask/ip_config +- on the VLAN nic_iface on every new connection request. +- +- +-uIP v0.7.0.9 (Jul 19, 2011) +-======================================================= +- Fixes +- ----- +- 1. Problem: Can't offload to 57810 NPAR NIC +- Cause: The MF/VF variant of the PCI IDs were not supported previously +- Change: Added support for the MF/VF variants for 57800/57810/57840 +- +- +-uIP v0.7.0.8 (Jun 30, 2011) +-======================================================= +- Fixes +- ----- +- 1. Problem: Cont00056522 - Unable to connect to iSCSI target using +- netxtreme2 package 7.0.9 +- Cause: The iSCSI L2 ring's CID has changed from 17 to 49 +- Change: The code now gets L2 iSCSI ring CID from the l2_buf directly. +- This will work with any version of the cnic driver because +- the location is a zero before this change. +- +- +-uIP v0.7.0.7 (Jun 23, 2011) +-======================================================= +- Fixes +- ----- +- 1. Problem: Cont00056460 - iSCSI Offload boot RHEL5u5 x64 dropped tagged +- packets with iSCSI Offload Boot with untagged +- Cause: The ICMP echo replies to the target was corrupted in both +- 1g and 10g mode +- Change: The code will now handle both VLAN stripped and no VLAN stripped +- incoming packets correctly. Also modified the transmit routine +- to strip out any inline VLAN tag before setting up the hw to +- insert VLAN tag. +- +- +-uIP v0.7.0.6 (Jun 21, 2011) +-======================================================= +- Fixes +- ----- +- 1. Problem: Cont00056231 - DHCPv4 not working with iSCSI HBA w/ +- linux-nx2 v7.0.7 +- Cause: The 10g L2 FW HSI has been modified for PCIe performance +- enhancement in the 7.0.7 package (FW 1.70.20) which uIP +- has not adapted to. +- Change: The eth_rx_cqe size has been increased from 32B to 64B. +- +- Enhancements +- ------------ +- 1. Change: The utility name has changed from brcm_iscsiuio to iscsiuio +- as preparation for upstream submission. +- 2. Change: Updated README +- +- +-uIP v0.7.0.5 (Jun 02, 2011) +-======================================================= +- Fixes +- ----- +- 1. Problem: Cont00055915 - iSCSI does not connect on 57800 in 4-port mode +- Cause: The 4-port mode was not being determined correctly +- Change: Fixed the PORT4MODE register offset and the QZONE_ID macros +- +- +-uIP v0.7.0.4 (May 24, 2011) +-======================================================= +- Fixes +- ----- +- 1. Problem: Cont00055832 - linux iscsiboot can not login to target using +- offload path (57800) +- Cause: The device ID comparison routine did not take care of the case +- when one device ID is bitwise superset of another. +- Change: Fixed the device ID comparison routine. +- +- +-uIP v0.7.0.3 (May. 19, 2011) +-======================================================= +- Enhancements +- ------------ +- 1. Change: Updated all fixes to match the released uIP 0.6.4.17 +- +- 2. Change: Modified source and Copyright info as preparation for upstream +- submission +- +- +-uIP v0.7.0.2 (May. 03, 2011) +-======================================================= +- Fixes +- ----- +- 1. Problem: Cont00048972 - brcm-iscsi.log has no max size and would grow +- to consume all free space on hard disk +- Cause: There was no mechanism to rotate the log +- Change: Added logrotate entry and SIGUSR1 signal handling for log rotate +- action +- +- 2. Problem: Cont00054996 - Multi-session, multi-protocol mtu stress +- does not recover all sessions +- Cause: A segfault was observed during the load/unload module. The +- problem was caused by an illegal dereference of a pointer +- when IPv6 couldn't find the longest match address from +- the ARP (Neighbor) table. +- Change: Fixed the dereferencing error +- +- 3. Problem: Cont00054900 - Linux uIP - Please add ability to connect +- to routed target with static iface IPv6 +- Cause: Static IPv6 never runs the IPv6 NDP router sol/adv engine. +- Change: IPv6 NDP router sol/adv has now been added to static IPv6 +- operation. +- +- 4. Problem: Cont00054996 - Multi-session, multi-protocol mtu stress +- does not recover all sessions +- Cause: Segfaults were observed caused by the accessing of the IPv6 +- NDP structure while the nic is undergoing a reset either +- due to a DHCPv4 request from iscsid or the handling of +- if_down due to the NL handler from CNIC. +- Change: The fix involves the following: +- - Fixed the handling of staggered IPv4/v6 DHCP/static requests +- - Fixed memory leak due to reallocation of IPv4 and IPv6 +- DHCP structs +- - Fixed the pthread join stuck problem in the handling +- of the if_down NL message +- +- 5. Problem: Cont00054810 - Linux NMI - bnx2x_init_hw_common:PXP2 CFG +- failed running iSCSI MTU stress test +- Cause: This only happens in DHCPv4 mode. The problem was caused +- by contention between the elongated window of performing +- DHCP in the enable_nic thread while receiving the asynchronous +- if_down NL message (from the MTU change event) from the +- CNIC NL thread. The problem occurs when the enable_nic +- thread tries to call bnx2x_open while the other thread +- calls the bnx2x_close routine. +- Change: Fixed mutex lock bugs for the enable_nic thread. Also +- extended the nic_disable timeout to 10s to compensate for +- the DHCP operation. +- +- 6. Problem: Cont00054818 - RH6.0 - Unable to logout of iSCSI session +- after running PQA baseline scripts +- Cause: This was caused by the call to cancel the enable_nic +- thread when disabling the nic but failed to unlock the +- nic mutex that the enable_nic thread held. +- Change: Wake up the enable_nic thread and wait for it to complete +- instead of canceling it in the nic_disable path. +- +- 7. Problem: Cont00054725 - Previous static HBA IP will be used after +- a new static HBA IP has been created +- Cause: There was an assumption in the code where if the same +- nic_iface structure was found based on the nic/vlan pair, +- the specified IP address would not be used. Instead, it +- will continue to use the previous defined IP address. +- Change: The previous IP address will now be compared against the +- the specified IP address before finishing the parce +- iface request from iscsid. If different, the current +- nic will be disabled and then re-enabled with the newly +- specified IP address. +- +- 8. Problem: Cont00054571 - Unable to connect to routed ipv6 target +- with RA address and iface DHCPv6 +- Cause: The default router address was not being employed for +- the IPv6 neighbor negotiation. Additionally, the return +- address of our neighbor advertisement was incorrect as +- it should use the best matched src address instead. +- Change: Fixed both the IPv6 neighbor solicitation and advertisement +- transmission and handling. +- +- 9. Problem: Cont00054510 - fails to login to 32 session with blanket +- login IPv6 +- Cause: A bug was introduced in uIP 0.6.4.6 where the NIC_RUNNING +- flag might not be set when entering the main loop under +- certain situations depending on the nic bring up. +- Change: A new NIC_STARTED_RUNNING flag is now defined to fix CQ53511. +- +- 10. Problem: Cont00053807 - RA and link local are unable to connect if DHCPv6 +- fails +- Cause: The host link local address was not being searched as one of +- the host address to be replied to CNIC for the connect request. +- Change: The path reply now includes the search of host link local +- address as well. +- +- 11. Problem: Cont00054236 - iSCSI service must be restarted before an IPv6 +- connection can be made to the Equalogic target +- Cause: The problem was intermittent as it depends on which IPv6 address +- the target was redirecting to. Since uIP was only extracting +- the target's IPv6 address + MAC from the target's neighbor +- advertisement packet itself and not from the ICMPv6 option, so +- the wrong or no MAC address will get send down to CNIC for the +- connection establishment; hence the no connect. +- Change: Added the updating of the neighbor discovery table to also use +- the Target IPv6 address + MAC specified in the incoming neighbor +- advertisement's ICMPv6 option field. +- +- 12. Problem: Cont00053255 - bnx2x panic dump logging into multiple +- discovered IPv6 nodes (Equalogic IPv6 target) +- Cause: The bnx2x panic was fixed in the 10g fw 6.4.29. +- A IPv6 connectivity issue was then found and led to different +- kernel/uIP crashes. This was caused by the same IPv6 +- connectivity problem mentioned above. +- Change: Same as above +- +- 13. Problem: Cont00053728 - Sessions never recover after doing initiator-side +- cable pull test with IPv6 traffic against Equalogic targets +- Cause: It was discovered that the Equalogic would send out periodic +- neighbor solicitation to maintain the connection to the +- initiator. Since uIP was responding with the assigned IPv6 +- link local address in the neighbor advertisement +- unconditionally, the target was observed to stop transmitting on +- the connection specified. +- Change: The neighbor advertisement generated will now use the dst IPv6 +- address from the input neighbor solicitation packet instead of +- the assigned IPv6 link local address for both the packet and the +- ICMPv6 source IPv6 address. +- +- 14. Problem: Compile error under 32-bit OS +- Cause: A bug was introduced in the previous release 0.6.4.6 which +- caused a compilation error in 32-bit OS (64-bit compiles +- fine) +- Change: Fixed the bug +- +- 15. Problem: Cont00053807 - RA and Link local are unable to connect if dhcpv6 +- fails +- Cause: There was a bug in the nl reply where the RA address will never +- be sent back to CNIC for the connection request +- Change: The best matched address to the dst will now be sent back to +- CNIC in the path rsp. +- +- Enhancements +- ------------ +- 1. Change: Updated README to remove the 57713/E references +- +- 2. Change: Allow the ICMP option field in the IPv6 Neighbor Advertisement +- response to be included without discrimination. This fixes +- an issue connecting against the EQL via RA for DHCPv6. +- +- 3. Change: Updated README for the IPv6 operation, VLAN, and discovery. +- +- +-uIP v0.7.0.1 (Mar. 29, 2011) +-======================================================= +- Fixes +- ----- +- 1. Problem: Cont00053511 - bnx2x panic dump during ifup/down stress with +- iSCSI traffic +- Cause: The panic dump was resolved by the driver's rq dbell size fix. +- After that, uIP crashed due to the asynchronous if_down event +- that took the chip resources away while the nic thread is still +- continuing to try to send DHCP request. +- Change: Added synchronization between the two threads so proper clean up +- of the threads can occur. +- +- Enhancements +- ------------ +- 1. Change: Added support for E3 (57800, 57810, and 57840) +- +- +-uIP v0.6.4.5 (Mar. 23, 2011) +-======================================================= +- Enhancements +- ------------ +- 1. Change: Optimized the double VLAN fix of CQ53870 to match +- what will be submitted for RHELS5.7 and RHELS6.1 inbox +- +- +-uIP v0.6.4.4 (Mar. 17, 2011) +-======================================================= +- Fixes +- ----- +- 1. Problem: Cont00053870 - Unable to login to iSCSI target via offload +- through a Nexus 5020 switch with DCBx enabled +- Cause: Double VLAN tagging was observed due to DCBx enabled. +- The chip actually adds a VLAN tag if the txbd does not have +- VLAN tag enabled under the DCBx environment for PRI setting. +- Since uIP does not make use of hw assisted VLAN tagging, +- 2 VLAN tag was observed in the data stream. +- Change: Enabled hw assisted VLAN tagging in uIP for both 1g and 10g. +- +- 2. Problem: Cont00053792 - maxconnections intermittently fail and +- recover using iface DHCPv4 +- Cause: The DHCPv4 engine erroneously keeps on requesting for a +- new lease which tremendously hamper normal path_req +- operation. The problem is that the lease time parameter +- has overflowed when converted to ticks count. +- Change: Expanded the lease timer ticks count parameter from 16 to +- 32 bits. +- +- 3. Problem: Cont00053807 - RA and link local are unable to connect if +- DHCPv6 fails +- Cause: The DHCPv6 engine does not have the failover to use RA +- mechanism +- Change: Expanded to use best match address instead regardless of +- DHCPv6 success or not, or using static v6. +- +- Enhancements +- ------------ +- 1. Change: Cont00051823 - Added man page for brcm_iscsiuio +- +- +-uIP v0.6.4.3 (Mar. 15, 2011) +-======================================================= +- Fixes +- ----- +- 1. Problem: Cont00053719 - intermittent logging into targets that +- are not in the same subnet as defined in the iface +- Cause: The default route was used erroneously due to a miscompare +- Change: Fixed this comparison so if the requested dst is not in +- in the same subnet, uIP would not even ARP out. +- +- 2. Problem: Cont00053580 - Unable to do iSCSI boot into Linux OS using +- 57710 adapters +- Cause: The E1 iro USTORM_RX_PROD_OFFSET doesn't match the t6.4 fw +- Change: This is now fixed +- +- +-uIP v0.6.4.2 (Feb. 24, 2011) +-======================================================= +- Fixes +- ----- +- 1. Problem: Cont00050343 - HBA does not follow RFC2131 spec for IPv4 +- DHCP lease expiration +- Cause: The dhcp engine did not have this feature implemented +- Change: Added lease time tracking and renewal +- +- 2. Problem: Cont00050801 - Unable to connect to target after switching +- between DHCPv4 to static v4 +- Cause: The configuration flags got corrupted when switching between +- dhcp and static or vice versa. +- Change: Fixed the flag handling. Also needed to zero out the static +- ip address in the host memory when switching to dhcp. +- Otherwise, the static ip address will get used mistakenly. +- +- Enhancements +- ------------ +- 1. Change: Cont00051936 - Added IPv6 NDP and DHCPv6 support. +- +- +-uIP v0.6.4.1 (Jan. 27, 2011) +-======================================================= +- Fixes +- ----- +- 1. Problem: Cont00049766 - segfault seen while stopping iscsi service +- Cause: The logger output routine was accessing the log resource +- while another thread calls fini_logger to free the same +- resources +- Change: Added pthread mutex lock to the logger routine to exclude +- the initializer, user, and finisher +- +- Enhancements +- ------------ +- 1. Change: Added new t6.4 HSI and 57713 support. +- +- +-uIP v0.6.2.13 (Jan. 04, 2011) +-======================================================= +- Fixes +- ----- +- 1. Problem: Cont00049665 - iscsiboot:linux failed to boot into iscsi +- boot image in offload path after 5 iterations +- Cause: The hw consumer index for the uIP ring got out of sync +- with the producer index. This has led to the xmit mutex +- lock be held forever so subsequent ARP requests will not +- get transmitted to the wire +- Change: Added this out of sync detection and rescue the xmit mutex +- lock +- +-uIP v0.6.2.12 (Dec. 21, 2010) +-======================================================= +- Fixes +- ----- +- 1. Problem: Cont00051820 - Session fails to reconnect after gateway +- fallback +- Cause: Under the HSRP test scenario, it was found that an ARP +- request from the SUT is required in order for the HSRP +- router to begin sending packets downstream to the SUT. +- The default ARP age was originally set to 20 minutes +- before a new ARP request will get sent, +- Change: Changed the ARP age default to Linux default at 5 minutes +- +-uIP v0.6.2.11 (Dec. 17, 2010) +-======================================================= +- Fixes +- ----- +- 1. Problem: For IPv4, the gateway route was not being utilized +- when the subnet mask given or calculated does not +- match. This resulted in many unwanted connection +- attempts. +- Cause: A bug was found in the default gateway calculation +- logic which prevented the gateway address from being +- used. +- Change: Fixed the default gateway logic +- +- 2. Problem: For IPv6, there are scenarios where it won't connect +- Cause: The IPv6 subnet mask as extracted from the CIDR +- format might contain garbage data. This garbage data +- was then used as part of the subnet mask which would +- prevent the correct address mask. +- Change: Fixed the subnet mask +- +-uIP v0.6.2.10 (Dec. 15, 2010) +-======================================================= +- Fixes +- ----- +- 1. Problem: IPv6 does not connect for non-CIDR iface.ipaddress +- specification +- Cause: A bug where all ones was used as the IPv6 netmask +- instead of all zeroes. This prevented all IPv6 +- path requests from being honored +- Change: Fixed the subnet mask used +- +-uIP v0.6.2.9 (Dec. 14, 2010) +-======================================================= +- Enhancements +- ------------ +- 1. Change: Added IP address CIDR notation support for the +- iface.ipaddress field in the iface file. +- This will allow subnet mask to be defined and used. +- +-uIP v0.6.2.8 (Dec. 9, 2010) +-======================================================= +- Fixes +- ----- +- 1. Problem: ipv6 + ifup/down fails to reconnect +- +- Cause: There were 2 problems found: +- - the xmit_mutex lock was being held indefinitely +- - the nl_process_if_down flag for 10g doorbell ringing +- did not get reinitialized +- +- Change: Fixed the xmit_mutex deadlock via trylock +- Added nl_process_if_down initialization in the IF_DOWN +- process +- +- 2. Problem: Added fix for the NPAR disabled for 57712 +- +- Cause: The mac address was not handled correctly +- +- Change: Fixed the mac address handling. Also requires corresponding +- kernel component for the complete fix +- +-uIP v0.6.2.7 (Dec. 7, 2010) +-======================================================= +- Enhancements +- ------------ +- 1. Change: Use the gateway address from the DHCP server the +- destination IP address is not in the current subnet. +- +-uIP v0.6.2.6 (Nov. 16, 2010) +-======================================================= +- Fixes +- ----- +- 1. Problem: Warning message seen in the kernel logs, +- "uio uio2: uevent: unsupported action string" +- +- Cause: The improper string was echo'ed into the UIO trigger +- field. With an improper string, this message would +- appear in the kernel logs. +- +- Change: uIP will now write the string "online" to the UIO +- trigger field. This is the string expected by the +- Linux kernel base driver. +- +- 2. Problem: uIP would segfault during a heavily login/logout +- iSCSI subsystem reset senario +- +- Cause: A double free occurred in the logging portion of the +- uIP code, but this was root cause to a double free when +- manipulating the NetLink buffers. +- +- Change: Properly look at the return code from the routine which +- will read NetLink messages. Also only free buffers +- if they are allocated. +- +- Enhancements +- ------------ +- 1. Change: Add ability to print kernel version and machine +- architecture to further help debug problems. +- +- 2. Change: Apply the netmask from DHCP if provided. +- +-uIP v0.6.2.5 (Nov. 10, 2010) +-======================================================= +- Fixes +- ----- +- 1. Problem: iscsid would try to conenct with unintended iSCSI +- targets +- +- Cause: uIP would blindly return the iSCSI target MAC address +- regardless if the iSCSI target is reachable via the +- given port. +- +- Change: uIP will try to filter the requests coming from CNIC +- by automatically generating a network mask based off +- the configured IP addressed. Then this netmask is +- masked with the destination IP address. If there is +- a match, then the path_req is allowed through. +- +- 2. Problem: Problems reconnecting back to the target when running +- MTU stress tests. +- +- Cause: cnic/bnx2i and uIP could possibly get out of sync when +- an if_down message is sent. +- +- Change: uIP will now immediately react to the if_down message, +- and flush all the path req's and then to process to +- if_close. +- +- Enhancements +- ------------ +- 1. Change: Fix compile warnings for src/unix/nic_nl.c, +- and src/unix/main.c +- +-uIP v0.6.2.4 (Nov. 4, 2010) +-======================================================= +- Fixes +- ----- +- 1. Problem: iSCSI HBA: brcm_iscsiuio segfault during ifdown +- with many active sessions +- +- Cause: uIP will segfault when traversing the error path when +- an iSCSI connection is starting but the sysfs entries +- have not been created yet. +- +- Change: Use the errno value rather then the one from the file +- descriptor because the file descriptor will be NULL and +- the NULL dereference will cause a segfault. +- +- Enhancements +- ------------ +- 1. Change: Added initial changes for iSCSI multi-function support for +- 10G NIC's. +- 2. Change: Add more detailed messages for error pathes in nic_utils +- +-uIP v0.6.2.3 (October 28, 2010) +-======================================================= +- Enhancements +- ------------ +- 1. Change: Add support for bnx2x-1.62.x drivers +- +-uIP v0.6.2.2 (October 18, 2010) +-======================================================= +- Enhancements +- ------------ +- 1. Change: Only allow iSCSI connections with known bnx2x HSI's. +- +-uIP v0.6.2.1 (October 7, 2010) +-======================================================= +- Fixes +- ----- +- 1. Problem: After multiple MTU changes, the ethtool IOCTL used to +- determine the bnx2x driver version fails and eventually +- iSCSI connections would not reconnect. +- +- Cause: The socket file descriptor used during the ethtool IOCTL +- call was never closed and leaked. +- +- Change: On the error path when calling the ethtool IOCTL, the +- file descriptor is now properly closed. +- +-uIP v0.5.39 (September 15, 2010) +-======================================================= +- Fixes +- ----- +- 1. Problem: Could not offload IPv4 VLAN connection when the target tries +- to ARP the iSCSI initiator +- +- Cause: In the ARP reply, the ether field was incorrect. +- +- Change: Properly set the ether field to 802.1Q type (0x8100) +- +-uIP v0.5.38 (September 14, 2010) +-======================================================= +- Fixes +- ----- +- 1. Problem: uIP would cause a panic dump when the NIC was going down +- +- Cause: uIP and CNIC where not synchonized on NIC state +- +- Change: Check if the RX BD's which are zero'ed by CNIC when the +- NIC is going down. If the BD addresses are zero, then +- uIP will drop the TX packets. +- +-uIP v0.5.37 (August 21, 2010) +-======================================================= +- Fixes +- ----- +- 1. Problem: uIP would segfault on ifup/ifdown stress test when using +- DHCP to determine local IP address. +- +- Cause: The uIP would use a NULL buffer during data transmission. +- +- Change: Drop packets when there are no buffer avaliable. +- +-uIP v0.5.36 (August 21, 2010) +-======================================================= +- Fixes +- ----- +- 1. Problem: iSCSI boot would not completely login after the pivot +- root operation. +- +- Cause: The uIP would not properly start the NIC interface. +- +- Change: uIP should only check the NIC state to determine whether +- to start the NIC thread or not. +- +- 2. Problem: uIP would segfault during if'up if'down testing. +- +- Cause: The uIP would improperly start 2 NIC threads for the +- same NIC interface. +- +- Change: uIP should properly lock the NIC list when disabling/removing +- the NIC threads. +- +- +-uIP v0.5.35 (August 20, 2010) +-======================================================= +- Fixes +- ----- +- 1. Problem: Sessions would hang with ethtool self-test +- +- Cause: The uIP would hang because the socket layer was stuck +- because there is much contention for that socket. This +- would hang the CNIC thread. +- +- Change: Remove any IOCTL calls in uIP which may colide with +- the ethtool self test. The driver version is only +- capture during uIP initialization. +- +- 2. Problem: There were session recovery issue when using DHCP +- if up/down tests. +- +- Cause: The uIP would hang because the DHCP requests would +- timeout if the network interface is downed which would +- hang all the other uIP threads. +- +- Change: Ensure that the DHCP state machine had exit points +- if the network interface was down'ed. +- +- +-uIP v0.5.34 (August 18, 2010) +-======================================================= +- Fixes +- ----- +- 1. Problem: Sessions would not recover with ethtool self-test +- +- Cause: The uIP would hang because either the NetLink buffer is +- full or that any socket operations used to manipulate +- multicast addresses would block. +- +- Change: Ensure that the socket used for multicast addressing is +- set to nonblocking. Drain the NetLink buffer without +- using the eventing, but with a more aggressive poll routine. +- +- 2. Problem: Sessions would not recover with L2 driver load/unload on +- RHEL 6.0 SS9 +- +- Cause: The uIP would close the NIC thread too early and would +- deadlock on cloing the NIC thread. +- +- Change: Ensure that the NIC thread is canceled/closed only in one +- location, in the NIC remove routine. +- +- +-uIP v0.5.33 (August 17, 2010) +-======================================================= +- Fixes +- ----- +- 1. Problem: Error message seen from the uIP stack for valid packets. +- +- Cause: The uIP was incorrectly marking logging messages for valid +- packets as errors because it didn't know how to parase them. +- +- Change: Changed the following from error to debug message +- ipv6: invalid version +- ipv4: invalid version or header length. +- icmpv6: unknown ICMP message. +- ip: neither tcp nor icmp +- Changed the following from error to warn message +- udp: bad checksum +- tcp: bad checksum +- tcp: got reset, aborting connection. +- +- 2. Problem: After multiple iterations the loading and unloading of +- the Broadcom Linux drivers with active connections +- would not cause the sessions to recover on RHEL 6.0 +- snapshot 9. +- +- Cause: There was a deadlock in the nic mutex +- +- Change: Lock ordering for the nic mutex and nic list mutex must +- be inforced. +- +- 3. Problem: After multiple iterations of running the ethtool selftest +- the Broadcom Linux drivers with active connections +- would not cause the sessions to recover on RHEL 5.5. +- +- Cause: The Netlink buffer between uIP and CNIC would get full. +- +- Change: Poll more regularly for packets in the Netlink buffer +- from 4 times a second to 100 times a 1 second. +- Drain packets during the PATH_REQ packet pull. +- +- +-uIP v0.5.32 (August 14, 2010) +-======================================================= +- Fixes +- ----- +- 1. Problem: Error message 'nic eth0: Didn't find type 0xaa bb' seen. +- +- Cause: Valid non-DIX Ethernet packets as being passed to the +- uIP. uIP will drop these packets but should be logged +- correctly. +- +- Change: These packets are valid, and should only be logged for +- debugging purposes. +- +- 2. Problem: Error message 'Dropped previous transmitted packet' seen. +- +- Cause: The TX ring is full, and here uIP is trying to transmit a +- packet which will be dropped. This is a valid state but +- the log message is marked incorrectly +- +- Change: These messages are not warnings and should be logging when +- debugging is enabled. +- +- 3. Problem: Error message: "iscsi_ipc eth0 Transport name is not +- equal expected: got: bnx2i" seen. +- +- Cause: The iface_rec structure is different between iscsid version. +- For RHEL 5.5, iscsid is versioned 871, for RHEL 6.0 is +- versioned 872. +- +- Change: Allow uIP to compile against a different version of iscsid. +- +- +-uIP v0.5.31 (August 12, 2010) +-======================================================= +- Fixes +- ----- +- 1. Problem: Softlock would occur showing that the NetLink table +- lock was taken but never released. +- +- Cause: NetLink socket buffer would fill with constant PATH_REQ +- messages preventing PATH_REQ response from libiscsi +- +- Change: Now uIP will drain the NetLink buffer while looking for +- a response. +- +- Enhancements +- ------------ +- 1. Change: Add documentation for VLAN configuration and restrictions. +- +- +-uIP v0.5.30 (August 6, 2010) +-======================================================= +- Fixes +- ----- +- 1. Problem: iscsid thread will stall if closing the uio files nodes +- is stuck +- +- Cause: uIP would indefinitely block waiting for the mutex shared +- by the close routine. +- +- Change: Now uIP will try and poll a bit for the mutex. If it can't +- get this mutex in the iscsid thread then an error is return +- rather then hold the thread. +- +- 2. Problem: IPv6 Unicast Neighbor Adveriserments would have the +- ICMPv6 option header specifying a MAC. +- +- Cause: uIP should use the source IPv6 address to detmine whether +- to strip the option header or not and not the target address +- in the ICMPv6 field. +- +- Change: The uIP stack return a unicast IPv6 Neighbor Advertisement +- without the ICMPv6 option as a response to unicast +- IPv6 Neighbor Solicitations. +- +- 3. Problem: There would be TCP SYN packets with improper MAC address. +- +- Cause: A zero'ed MAC address was not passed to CNIC to indicate an +- error or if the IP address didn't resolve. +- +- Change: The uIP stack will now return a zero'ed MAC address if it +- can't find any entries. +- +- +-uIP v0.5.29 (August 6, 2010) +-======================================================= +- Fixes +- ----- +- 1. Problem: "uip udp: no matching connection found: lport: 35072" +- seen numerous times in the brcm_iscsiuio log file +- +- Cause: This message was incorrectly marked as an error +- +- Change: These messages are valid log entries especially if the +- packet was a broadcast UDP packet not destined for the SUT +- I will change the code to mark these logs entries as debug. +- +- +-uIP v0.5.28 (August 5, 2010) +-======================================================= +- Fixes +- ----- +- 1. Problem: Can't login into a redirected Equilogic Target +- +- Cause: The Equilogic Target uses a unicast IPv6 Neighbor +- Solicitation to test if the host is up. The uIP stack +- would return a Neighbor Advertisement with an unneeded +- ICMPv6 option. +- +- Change: Only have the uIP stack return a unicast IPv6 Neighbor +- Advertisement without the ICMPv6 option. +- +- 2. Problem: With older bnx2/bnx2x/cnic/bnx2i driver combinations +- uIP would segfault when these drivers were unloaded. +- +- Cause: When the older drivers were removed, the underlying uio +- instance was removed causing uIP to have a stale file handle. +- When uIP finally closes using this stale file handle, either +- uIP would segfault, or there would be an error in the +- uio_release() path. +- +- Change: Only have the uIP close if the UIO file node exists. +- +- +-uIP v0.5.27 (July 31, 2010) +-======================================================= +- Fixes +- ----- +- 1. Problem: iSCSI HBA: Unable to use DHCP address for iSCSI interface +- if a connection was previously made with a static address +- on bnx2 devices. +- +- Cause: Because the device is closed and reopen'ed the TX consumer +- indexes were not persisted +- +- Change: Only discard the TX consumer indexes only when the devices +- will be discarded or closed +- +- Enhancements +- ------------ +- 1. Change: Change CNIC references to bnx2 in the bnx2 user space +- driver. +- +- +-uIP v0.5.26 (July 30, 2010) +-======================================================= +- Fixes +- ----- +- 1. Problem: iSCSI HBA: Unable to use DHCP address for iSCSI interface +- if a connection was previously made with a static address on +- bnx2x devices. +- +- Cause: Because the device is closed and reopen'ed the TX consumer +- indexes were not persisted +- +- Change: Only discard the TX consumer indexes only when the devices +- will be discarded +- +- 2. Problem: IPv6 using VLAN's didn't login +- +- Cause: The uIP code used to determine if the packet was an IPv6 +- or not was not working. This VLAN packets for IPv6 were +- being mis-interpreted. +- +- Change: Make the function is_ipv6() VLAN aware +- +- 3. Problem: Persistant targets was not loggin in during boot +- +- Cause: If udev was slow and the /dev/uio* were creatly slowly +- uIP would fail. +- +- Change: Poll uIP waiting for /dev/uio* file nodes. +- +-uIP v0.5.25 (July 27, 2010) +-======================================================= +- Fixes +- ----- +- 1. Problem: When using IPv4 DHCP, there are no initial DHCP Discover +- packets were not seen on the wire. +- +- Cause: Packets generated from the app handler from the uIP stack +- were not placed on the wire. +- +- Change: Packets originating from the uIP stack are now always placed +- on the wire. +- +-uIP v0.5.24 (July 25, 2010) +-======================================================= +- Fixes +- ----- +- 1. Problem: One would see invalid packet packets flow through the +- uIP stack, where the logs would indicate there is a packet +- with an invalid length +- +- Cause: The BD and CQE consumer indexes were not properly incremented +- and masked. +- +- Change: The BD index is now properly masked. The CQE index is not +- incremented using the CQE index rather the mistaken BD index. +- +- Impact: 10G only +- +- 2. Problem: uIP would segfault during the booting of the machine. +- +- Cause: uIP was using a NULL data pointer because there was an +- incorrect packet passed to the stack. +- +- Change: Only allow uIP to process data if the packet exists. +- +- 3. Problem: uIP would stop processing packets +- +- Cause: The uIP code would not properly drain the CQE ring causing +- it to eventually be full +- +- Change: Consume all the CQE elements even if they are ethernet types +- or not. +- +- Impact: 10G only +- +- 4. Problem: uIP would stop after if/down of the network interface. +- +- Cause: uIP was not kick starting the NIC loop thread properly. +- +- Change: Ensure that the NIC loop thread is started by when iscsid +- request that the interface start the offload. Mark the NIC +- only if the thread is truly canceled. +- +- +-uIP v0.5.23 (July 20, 2010) +-======================================================= +- Fixes +- ----- +- 1. Problem: Segfault during brcm_iscsiuio initialization +- +- Cause: uIP was using a NULL data pointer, because a different +- thread re-initialized the uIP stack +- +- Change: Properly synchronize the initialization of the stack +- +- 2. Problem: Deadlock during the printing of heavy debug messages +- +- Cause: The variable macro structures would point to invalid +- data +- +- Change: With each invocation of va_copy() a corresponding +- invocation of va_end() in the same function for the proper +- cleanup +- +- 3. Problem: uIP would hang when the interface could go up/down +- +- Cause: uIP would get out of sync with the state of the network +- interface +- +- Change: Instead of detriving state from the UIO file nodes, uIP +- will take direction from iscsid on when interfaces will be +- started. +- +-uIP v0.5.22 (July 15, 2010) +-======================================================= +- Fixes +- ----- +- 1. Problem: Unable to reconnect via iSCSI offload after +- ifup/ifdown +- +- Cause: uIP was stuck on the thread when closing the NIC main +- loop +- +- Change: Properly synchronize the NetLink CNIC and uevent threads +- +- 2. Problem: uIP would crash during boot up. +- +- Cause: uIP would overwrite a memory location which was already +- freed during nic_remove(). +- +- Change: Since the NIC is freed there is no need to write to +- update the NIC flags +- +- Enhancements +- ------------ +- +- 1. Change: Added IPv6 Link Local support +- +- +-uIP v0.5.21 (July 5, 2010) +-======================================================= +- Fixes +- ----- +- 1. Problem: Unable to connect via iSCSI offload after +- changing L2 address +- +- Cause: uIP didn't notice the network inferface going down +- +- Change: Allow uIP to persist the stack's IP address after +- a reset +- +- 2. Problem: Unable to connect via IPv4 and IPv6 concurrently +- +- Cause: uIP didn't notice the network inferface going down +- +- Change: Allow uIP to persist the stack's IP address after +- a reset and properly bring up the interface +- +- 3. Problem: Unable to connect via VLAN +- +- Cause: IP address was no persisted after a device reset +- +- Change: When CNIC requests a path request, uIP will use the +- VLAN passed by the CNIC. +- +- +-uIP v0.5.20 (June 24, 2010) +- +- +-uIP v0.5.20 (June 24, 2010) +-======================================================= +- Fixes +- ----- +- 1. Problem: Certain IPv6 addresses are not repsonded to by +- the target. +- +- Cause: The MAC was generated from the target's IPv6 +- address not the deterived multicast IPv6 address. +- +- Change: The destination MAC address should be deterived +- from the packet's destination IPv6 address and +- not the target. +- +- 2. Problem: brcm_iscsiuio would segfault when L2 interface is +- bought up and down after being logged into +- +- Cause: The NIC thread was not stopped properly +- +- Change: When the UIO device is remove and when the +- cooresponding NIC tracked by brcm_iscsiuio, the +- daemon would properly wait for the NIC thread to +- stop. +- +- +-uIP v0.5.19 (June 22, 2010) +-======================================================= +- Fixes +- ----- +- 1. Problem: Can't login after boot +- +- Cause: If NIC interfaces are brough up and down quickly +- uIP wait on an invalid NIC thread +- +- Change: Only wait for the NIC thread if the NIC thread +- exists. +- +-uIP v0.5.18 (June 21, 2010) +-======================================================= +- Fixes +- ----- +- 1. Problem: Does not compile on SLES 11 SP1 +- +- Cause: Automake cached files were included as part of the +- uIP-0.5.17 package +- +- Change: Remove automake cached files, and allow these files +- to be generated each time the source is compiled +- +- 2. Problem: Does not always receive multicast packets +- +- Cause: Multicast bit was not set in SORT USER 2 register +- +- Change: brcm_iscsiuio will now set the SORT USER 2 registers +- with both the broadcast and multicast bits. +- +- 3. Problem: Existing iSCSI connections do not reconnect after +- operations which require equivalent driver +- load/unload operations +- +- Cause: Multiple path requests would trample NIC configurations +- +- Change: Allow only one path request at a time +- +-uIP v0.5.17 (June 16, 2010) +-======================================================= +- Fixes +- ----- +- 1. Problem: IPv6 neighbor solicitations from brcm_iscsiuio could +- not be responded to +- +- Cause: The IPv6 neighbor solicitation packet had an invalid +- multicast MAC address +- +- Change: Properly set the MAC address multicast bit and OR +- with the IPv6 destination address +- +- 2. Problem: NIC state was not properly synchronized and noticed +- by Shyam Iyer +- +- Change: Properly lock the NIC device when changing state +- +- Enhancements +- ------------ +- +- 1. Change: Listen for iscsid before daemonizing to close a timing +- gap which might allow iscsid to start before uIP is +- completely initialized. +- +-uIP v0.5.16 (June 2, 2010) +-======================================================= +- +- Enhancements +- ------------ +- +- 1. Change: Formally add IPv6 support. Only a static IPv6 address +- is supported. +- +-uIP v0.5.15 (May 20, 2010) +-======================================================= +- +- Fixes +- ----- +- 1. Problem: brcm_iscsiuio would echo packets off the wire +- +- Cause: Stale packets from the uIP stack could potentially +- make it onto the wire causing a network flood +- +- Change: Only place on the wire packets uIP intended to place +- on the wire. Drop all other packets. +- +-uIP v0.5.14 (May 18, 2010) +-======================================================= +- +- Fixes +- ----- +- 1. Problem: brcm_iscsiuio would crash when offloading using a +- bnx2x device /dev/mem could not be +- opened, (ie. SE Linux enabled) +- +- Cause: /dev/mem could not be opened, (ie. SE Linux enabled) +- and then the NIC would be improperly initialized. +- +- Change: If /dev/mem is not able to be opened, then the device +- is closed +- +- 2. Problem: brcm_iscsiuio would crash when brcm_iscsiuio is +- being shutdown +- +- Cause: The NIC mutex was deferenced imporperly when the NIC +- is being closed +- +- Change: Take the NIC mutex lock only when the NIC is closed. +- +-uIP v0.5.13 (May 16, 2010) +-======================================================= +- +- Fixes +- ----- +- 1. Problem: brcm_iscsiuio would crash with heavy traffic directed +- at the iSCSI traffic +- +- Cause: Packets which are sized between 1006-1024 bytes would +- crash brcm_iscsiuio because brcm_iscsiuio is not sized +- to handle such large packets +- +- Change: Drop large packets, properly hold the NIC mutex lock +- for the duration when NIC fields are being used. +- +- +-uIP v0.5.12 (May 13, 2010) +-======================================================= +- +- Fixes +- ----- +- 1. Problem: brcm_iscsiuio could crash on when L2 interface is +- ifdown'ed +- +- Cause: The local NIC pointer was not initialized properly +- in the routine parse_iface() +- +- Change: Properly initialize the NIC pointer +- +- 2. Problem: Documentation referred to older admin_client which +- doesn't exist any more because brcm_iscsiuio uses +- the iscsid iface file +- +- Change: Remove the stale references +- +- +-uIP v0.5.11 (May 11, 2010) +-======================================================= +- +- Fixes +- ----- +- 1. Problem: brcm_iscsiuio could crash on invalid packet sizes +- +- Cause: The hardware BD could be a large value because of a +- hardware error +- +- Change: Limit the size of the packet dumped to the MTU size +- +- Enhancements +- ------------ +- +- 1. Change: During the running of the configure script now +- the script will check for ar and ranlib binaries +- +- +-uIP v0.5.10 (May 03, 2010) +-======================================================= +- +- Fixes +- ----- +- 1. Problem: BCM57712 not recognized +- +- Cause: The PCI ID's in the bnx2x file were missing. +- +- Change: Added proper BCM57712, BCM57712E, BCM57713, BCM57713E +- PCI ID's +- +- 2. Problem: (CQ 47481) brcm_iscsiuio not installed in correct location +- +- Cause: Default install path for autoconf is /usr/local +- +- Change: Change the default prefix to '/' so the brcm_iscsiuio +- binary is installed to /sbin/ +- +- Enhancements +- ------------ +- +- 1. Change: Remove dependency on Yacc and Lex +- +- +-uIP v0.5.9 (April 28, 2010) +-======================================================= +- +- Fixes +- ----- +- 1. Problem: bnx2x T6.0 driver would not login +- +- Cause: The bnx2x code was not using the T6.0 HSI offsets +- +- Change: Determine to bnx2x driver version eariler to properly use the +- T4.8 or T6.0 HSI +- +- Enhancements +- ------------ +- +- 1. Change: Collapse all the various locks to use the NIC lock to shrink +- memory footprint +- +- 2. Change: Consolidate upper layer checksumming code +- +- +-uIP v0.5.5 (March 02, 2010) +-======================================================= +- +- Enhancements +- ------------ +- +- 1. Change: Add support for T6.0 bnx2x HSI and 57712. +- +- 2. Change: Initial support for IPv6 +- +-uIP v0.5.8 (April 22, 2010) +-======================================================= +- +- Enhancements +- ------------ +- +- 1. Change: Add support for T6.0 bnx2x HSI and 57712. +- +- 2. Change: Initial support for IPv6 +- +-uIP v0.5.7 (March 17, 2010) +-======================================================= +- +- Enhancements +- ------------ +- +- 1. Change: Add to documentation on discovering on a particular +- iface before logging in +- +-uIP v0.5.6 (Mar 05, 2009) +-======================================================= +- Fixes +- ----- +- 1. Problem: bnx2x panic dump would be seen when sending +- traffic to uIP +- +- Cause: The TX producer index was not properly +- incrementing when the wrapping occured +- +- Change: Do not skip the last TX producer index like the +- TX BD's +- +- Impact: None. +- +-uIP v0.5.5 (March 02, 2010) +-======================================================= +- Initial release +- +- Enhancements +- ------------ +- +- 1. Change: Add to documentation on debugging/logging for uIP +- +- +-uIP v0.5.4 (Feb 22, 2010) +-======================================================= +- Fixes +- ----- +- 1. Problem: Compile error where 'ETHERTYPE_VLAN' define +- is missing +- +- Cause: Certain distributions do not define 'ETHERTYPE_VLAN' +- in the header file "net/ethernet.h". +- +- Change: Added proper defines for ETHERTYPE_VLAN when necessary +- +- Impact: None. +- +- +-uIP v0.5.3 (Feb 18, 2010) +-======================================================= +- Fixes +- ----- +- 1. Problem: Using VLAN's on offloaded iSCSI connections +- +- Cause: (CQ45983) VLAN tags were not being properly inserted +- when sending the ARP request packets +- +- Change: Added VLAN tags when sending ARP request packets +- +- Impact: None. +- +- +-uIP v0.5.2 (Dec 10, 2009) +-======================================================= +- Fixes +- ----- +- 1. Problem: Switching between 10G and 1G iSCSI offloaded +- devices caused login connectivity problems +- +- Cause: The NIC devices within uIP were not cleanup +- properly. +- +- Change: The NIC structure is not re-initialized and the +- NIC thread is destroyed when the host network +- interface is brought down. +- +- Impact: None. +- +- +-uIP v0.5.1 (Dec 9, 2009) +-======================================================= +- Fixes +- ----- +- 1. Problem: 10G devices behind PCI bridges would not collect +- +- Cause: PCI bus:slot.func string was parsed incorrectly +- because the bridge string was used +- +- Change: Parse the proper PCI bus:slot.func string. +- +- Impact: None. +- +- +-uIP v0.5.0b (Nov 24, 2009) +-======================================================= +- Initial release +- +- Enhancements +- ------------ +- +- 1. Change: Add Broadcom 10G iSCSI offload support +- +- Impact: Linux +- +diff --git a/iscsiuio/configure.ac b/iscsiuio/configure.ac +deleted file mode 100644 +index 9b85448..0000000 +--- a/iscsiuio/configure.ac ++++ /dev/null +@@ -1,104 +0,0 @@ +-dnl iscsiuio uIP user space stack configure.ac file +-dnl +-dnl Copyright (c) 2004-2013 Broadcom Corporation +-dnl Copyright (c) 2014, QLogic 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 +-dnl the Free Software Foundation. +-dnl +-dnl Written by: Eddie Wai (eddie.wai@broadcom.com) +-dnl Benjamin Li (benli@broadcom.com) +-dnl +- +-PACKAGE=iscsiuio +-VERSION=0.7.8.6 +- +-AC_INIT([iscsiuio], [0.7.8.6], [QLogic-Storage-Upstream@cavium.com]) +- +-AM_INIT_AUTOMAKE +-AC_CONFIG_HEADER(config.h) +-AC_PATH_PROGS(BASH, bash) +- +-AC_PROG_CC +-AM_PROG_CC_C_O +- +-AC_PROG_RANLIB +- +-AC_GNU_SOURCE +-AC_PROG_INSTALL +-AC_PROG_GCC_TRADITIONAL +- +-# Checks for typedefs, structures, and compiler characteristics. +-AC_C_CONST +-AC_C_INLINE +-AC_TYPE_OFF_T +-AC_TYPE_SIZE_T +-AC_CHECK_TYPES(int8_t) +-AC_CHECK_TYPES(uint8_t) +-AC_CHECK_TYPES(int16_t) +-AC_CHECK_TYPES(uint16_t) +-AC_CHECK_TYPES(int32_t) +-AC_CHECK_TYPES(uint32_t) +-AC_CHECK_TYPES(int64_t) +-AC_CHECK_TYPES(uint64_t) +-AC_CHECK_SIZEOF(short, 2) +-AC_CHECK_SIZEOF(int, 4) +-AC_CHECK_SIZEOF(long, 4) +- +-AC_C_BIGENDIAN(AC_SUBST([ENDIAN],[BIG]),AC_SUBST([ENDIAN],[LITTLE])) +- +-AC_LIBTOOL_DLOPEN +- +-# libtool stuff +-AC_PROG_LIBTOOL +- +-: ${CFLAGS:="-O2"} +-CFLAGS="${CFLAGS} -Wall" +-## check for --enable-debug first before checking CFLAGS before +-## so that we don't mix -O and -g +-AC_ARG_ENABLE(debug, +-[ --enable-debug Turn on compiler debugging information (default=no)], +- [if eval "test x$enable_debug = xyes"; then +- CFLAGS="${CFLAGS} -g -O0" +- fi]) +-AM_CONDITIONAL([DEBUG], [test x$debug = xtrue]) +-## check for systemd support, default on +-AC_ARG_WITH([systemd], +- AS_HELP_STRING([--without-systemd], [Build without systemd]), +- [case "${withval}" in +- yes) with_libsystemd=yes ;; +- no) wth_libsystemd=no ;; +- *) AC_MSG_ERROR([bad value $withval for --with-systemd]) ;; +- esac],[with_libsystemd=auto]) +-AS_IF([test "$with_libsystemd" != no],[ +- PKG_CHECK_MODULES([LIBSYSTEMD],[libsystemd],[LDFLAGS=$LIBSYSTEMD_LIBS],[ +- if test "$with_libsystemd" = yes; then +- AC_MSG_ERROR([could not find libsystemd using pkg-config]) +- else +- CFLAGS="${CFLAGS} -DNO_SYSTEMD" +- fi +- ]) +-],[ +- CFLAGS="${CFLAGS} -DNO_SYSTEMD" +-]) +- +-AC_CONFIG_COMMANDS([default],[[ +- if [ -n "$SOURCE_DATE_EPOCH" ] ; then +- echo 'char *build_date = "'`LC_ALL=C.UTF-8 date --date=@$SOURCE_DATE_EPOCH -u`'";' > src/unix/build_date.c +- else +- echo 'char *build_date = "'`date`'";' > src/unix/build_date.c +- fi +- echo 'extern char *build_date;'> src/unix/build_date.h +-]],[[]]) +- +-AC_PREFIX_DEFAULT() +- +-AC_OUTPUT([Makefile +-src/Makefile +-src/apps/Makefile +-src/apps/dhcpc/Makefile +-src/apps/brcm-iscsi/Makefile +-src/uip/Makefile +-src/unix/Makefile +-src/unix/libs/Makefile]) +diff --git a/iscsiuio/docs/iscsiuio.8 b/iscsiuio/docs/iscsiuio.8 +deleted file mode 100644 +index ea2ae02..0000000 +--- a/iscsiuio/docs/iscsiuio.8 ++++ /dev/null +@@ -1,89 +0,0 @@ +-.\" Copyright (c) 2010-2013 Broadcom Corporation +-.\" Copyright (c) 2014, QLogic Corporation +-.\" This is free documentation; you can redistribute it and/or +-.\" modify it under the terms of the GNU General Public License as +-.\" published by the Free Software Foundation. +-.\" +-.\" bnx2.4,v 0.7.8.1b +-.\" +-.TH iscsiuio 8 "12/10/2013" "QLogic Corporation" +-.\" +-.\" NAME part +-.\" +-.SH NAME +-iscsiuio \- iSCSI UserSpace I/O driver +-.\" +-.\" SYNOPSIS part +-.\" +-.SH SYNOPSIS +-.B iscsiuio +-.RB [ -d -f -v ] +-.PP +-.\" +-.\" DESCRIPTION part +-.\" +-.SH DESCRIPTION +-iscsiuio is the UserSpace I/O driver for the QLogic NetXtreme II +-BCM5706/5708/5709 series PCI/PCI-X Gigabit Ethernet Network Interface Card +-(NIC) and for the QLogic NetXtreme II BCM57710/57711/57712/57800/57810/57840 +-series PCI-E 10 Gigabit Ethernet Network Interface Card. +-The driver has been tested on 2.6.28 kernels and above. +-.PP +-Refer to the README.TXT from the driver package on how to +-compile and install the driver. +-.PP +-Refer to various Linux documentations +-on how to configure network protocol and address. +-.\" +-.\" DRIVER DEPENDENCIES part +-.\" +-.SH DRIVER DEPENDENCIES +- +-.\" +-.\" PARAMETER part +-.\" +-.SH PARAMETERS +-There are very few parameters when running this application. +-.TP +-.BI -d|--debug +-This is to enable debug mode where debug messages will be sent to stdout +-The following debug modes are supported +-.P +-.RS +-DEBUG 4 - Print all messages +-.P +-INFO 3 - Print messages needed to follow the uIP code (default) +-.P +-WARN 2 - Print warning messages +-.P +-ERROR 1 - Only print critical errors +-.RE +-.PP +-.TP +-.TP +-.BI -f|--foreground +-This is to enable foreground mode so that this application doesn't get sent +-into the background. +-.PP +-.TP +-.BI -v|--version +-This is to print the version. +-.PP +-.TP +-.BI -p|--pid +-Use pidfile (default /run/iscsiuio.pid ) +-.PP +-.TP +-.BI -h|--help +-Display this help and exit. +- +- +-.\" +-.\" AUTHOR part +-.\" +-.SH AUTHOR +-Benjamin Li \- benli@broadcom.com +-.P +-Eddie Wai \- eddie.wai@broadcom.com +-.SH Maintained by +-QLogic-Storage-Upstream@qlogic.com +diff --git a/iscsiuio/iscsiuiolog b/iscsiuio/iscsiuiolog +deleted file mode 100644 +index 360947c..0000000 +--- a/iscsiuio/iscsiuiolog ++++ /dev/null +@@ -1,10 +0,0 @@ +-/var/log/iscsiuio.log { +- weekly +- missingok +- notifempty +- rotate 4 +- sharedscripts +- postrotate +- pkill -USR1 iscsiuio 2> /dev/null || true +- endscript +-} +diff --git a/iscsiuio/src/.gitignore b/iscsiuio/src/.gitignore +deleted file mode 100644 +index 10301e2..0000000 +--- a/iscsiuio/src/.gitignore ++++ /dev/null +@@ -1 +0,0 @@ +-*.a +diff --git a/iscsiuio/src/Makefile.am b/iscsiuio/src/Makefile.am +deleted file mode 100644 +index 44b0085..0000000 +--- a/iscsiuio/src/Makefile.am ++++ /dev/null +@@ -1 +0,0 @@ +-SUBDIRS = apps uip unix +diff --git a/iscsiuio/src/README b/iscsiuio/src/README +deleted file mode 100644 +index 9fca6fb..0000000 +--- a/iscsiuio/src/README ++++ /dev/null +@@ -1,13 +0,0 @@ +-uIP is a very small implementation of the TCP/IP stack that is written +-by Adam Dunkels . More information can be obtained +-at the uIP homepage at http://www.sics.se/~adam/uip/. +- +-This is version $Name: uip-1-0 $. +- +-The directory structure look as follows: +- +-apps/ - Example applications +-doc/ - Documentation +-lib/ - Library code used by some applications +-uip/ - uIP TCP/IP stack code +-unix/ - uIP as a user space process under FreeBSD or Linux +diff --git a/iscsiuio/src/apps/Makefile.am b/iscsiuio/src/apps/Makefile.am +deleted file mode 100644 +index 08ed18d..0000000 +--- a/iscsiuio/src/apps/Makefile.am ++++ /dev/null +@@ -1 +0,0 @@ +-SUBDIRS = dhcpc brcm-iscsi +diff --git a/iscsiuio/src/apps/README b/iscsiuio/src/apps/README +deleted file mode 100644 +index 0096c4e..0000000 +--- a/iscsiuio/src/apps/README ++++ /dev/null +@@ -1,2 +0,0 @@ +-This directory contains a few example applications. They are not all +-heavily tested, however. +diff --git a/iscsiuio/src/apps/brcm-iscsi/Makefile.am b/iscsiuio/src/apps/brcm-iscsi/Makefile.am +deleted file mode 100644 +index 00cbd8e..0000000 +--- a/iscsiuio/src/apps/brcm-iscsi/Makefile.am ++++ /dev/null +@@ -1,13 +0,0 @@ +-AM_CFLAGS = -I${top_srcdir}/src/unix \ +- -I${top_srcdir}/src/uip \ +- -I${top_srcdir}/src/apps/dhcpc \ +- -I${top_srcdir}/src/apps/brcm-iscsi \ +- -I${top_srcdir}/../include \ +- -I${top_srcdir}/../usr +- +-noinst_LIBRARIES = lib_apps_brcm_iscsi.a +- +-lib_apps_brcm_iscsi_a_SOURCES = brcm_iscsi.c +- +-lib_apps_brcm_iscsi_a_CFLAGS = $(AM_CFLAGS) \ +- -DBYTE_ORDER=@ENDIAN@ +diff --git a/iscsiuio/src/apps/brcm-iscsi/Makefile.brcm-iscsi b/iscsiuio/src/apps/brcm-iscsi/Makefile.brcm-iscsi +deleted file mode 100644 +index 732275f..0000000 +--- a/iscsiuio/src/apps/brcm-iscsi/Makefile.brcm-iscsi ++++ /dev/null +@@ -1 +0,0 @@ +-APP_SOURCES += brcm-iscsi.c +diff --git a/iscsiuio/src/apps/brcm-iscsi/brcm_iscsi.c b/iscsiuio/src/apps/brcm-iscsi/brcm_iscsi.c +deleted file mode 100644 +index 4223ca4..0000000 +--- a/iscsiuio/src/apps/brcm-iscsi/brcm_iscsi.c ++++ /dev/null +@@ -1,89 +0,0 @@ +-/* +- * Copyright (c) 2009-2011, Broadcom Corporation +- * Copyright (c) 2014, QLogic Corporation +- * +- * Written by: Benjamin Li +- * Based on code example from Adam Dunkels +- * +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. All advertising materials mentioning features or use of this software +- * must display the following acknowledgement: +- * This product includes software developed by Adam Dunkels. +- * 4. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- */ +-/** +- * \addtogroup brcm-iscsi +- * @{ +- */ +- +-/** +- * \file +- * An example of how to write uIP applications +- * with protosockets +- * \author +- * Benjamin Li +- */ +- +-/* +- * This is a short example of how to write uIP applications using +- * protosockets. +- */ +- +-/* +- * We define the application state (struct hello_world_state) in the +- * hello-world.h file, so we need to include it here. We also include +- * uip.h (since this cannot be included in hello-world.h) and +- * , since we use the memcpy() function in the code. +- */ +-#include "brcm_iscsi.h" +-#include "uip.h" +-#include +-#include +- +-#include "uip_arp.h" +- +-/*---------------------------------------------------------------------------*/ +-/* +- * The initialization function. We must explicitly call this function +- * from the system initialization code, some time after uip_init() is +- * called. +- */ +-void brcm_iscsi_init(void) +-{ +-} +- +-/*---------------------------------------------------------------------------*/ +-/* +- * In hello-world.h we have defined the UIP_APPCALL macro to +- * hello_world_appcall so that this funcion is uIP's application +- * function. This function is called whenever an uIP event occurs +- * (e.g. when a new connection is established, new data arrives, sent +- * data is acknowledged, data needs to be retransmitted, etc.). +- */ +-void brcm_iscsi_appcall(struct uip_stack *ustack) +-{ +-} +diff --git a/iscsiuio/src/apps/brcm-iscsi/brcm_iscsi.h b/iscsiuio/src/apps/brcm-iscsi/brcm_iscsi.h +deleted file mode 100644 +index 10bfc95..0000000 +--- a/iscsiuio/src/apps/brcm-iscsi/brcm_iscsi.h ++++ /dev/null +@@ -1,91 +0,0 @@ +-/* +- * Copyright (c) 2009-2011, Broadcom Corporation +- * Copyright (c) 2014, QLogic Corporation +- * +- * Written by: Benjamin Li +- * Based on code example from Adam Dunkels +- * +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. All advertising materials mentioning features or use of this software +- * must display the following acknowledgement: +- * This product includes software developed by Adam Dunkels. +- * 4. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- */ +-/** +- * \addtogroup apps +- * @{ +- */ +- +-/** +- * \defgroup helloworld Hello, world +- * @{ +- * +- * A small example showing how to write applications with +- * \ref psock "protosockets". +- */ +- +-/** +- * \file +- * Header file for an example of how to write uIP applications +- * with protosockets. +- * \author +- * Benjamin Li +- */ +- +-#ifndef __BRCM_ISCSI_H__ +-#define __BRCM_ISCSI_H__ +- +-/* Since this file will be included by uip.h, we cannot include uip.h +- here. But we might need to include uipopt.h if we need the u8_t and +- u16_t datatypes. */ +-#include "uipopt.h" +-#include "uip.h" +-#include "psock.h" +- +-/* Next, we define the hello_world_state structure. This is the state +- of our application, and the memory required for this state is +- allocated together with each TCP connection. One application state +- for each TCP connection. */ +-struct hello_world_state { +- struct psock p; +- u8_t inputbuffer[32]; +- u8_t name[40]; +- +- struct uip_udp_conn *conn; +-}; +- +-/* Finally we define the application function to be called by uIP. */ +-void brcm_iscsi_appcall(struct uip_stack *ustack); +-#ifndef UIP_APPCALL +-#define UIP_APPCALL brcm_iscsi_appcall +-#endif /* UIP_APPCALL */ +- +-void brcm_iscsi_init(void); +- +-#endif /* __BRCM_ISCSI_H__ */ +-/** @} */ +-/** @} */ +diff --git a/iscsiuio/src/apps/dhcpc/Makefile.am b/iscsiuio/src/apps/dhcpc/Makefile.am +deleted file mode 100644 +index 1c97993..0000000 +--- a/iscsiuio/src/apps/dhcpc/Makefile.am ++++ /dev/null +@@ -1,13 +0,0 @@ +-AM_CFLAGS = -I${top_srcdir}/src/unix \ +- -I${top_srcdir}/src/uip \ +- -I${top_srcdir}/src/apps/dhcpc \ +- -I${top_srcdir}/src/apps/brcm-iscsi \ +- -I${top_srcdir}/../include \ +- -I${top_srcdir}/../usr +- +-noinst_LIBRARIES = lib_apps_dhcpc.a +- +-lib_apps_dhcpc_a_SOURCES = dhcpc.c dhcpv6.c +- +-lib_apps_dhcpc_a_CFLAGS = $(AM_CFLAGS) \ +- -DBYTE_ORDER=@ENDIAN@ +diff --git a/iscsiuio/src/apps/dhcpc/Makefile.dhcpc b/iscsiuio/src/apps/dhcpc/Makefile.dhcpc +deleted file mode 100644 +index f84c84f..0000000 +--- a/iscsiuio/src/apps/dhcpc/Makefile.dhcpc ++++ /dev/null +@@ -1 +0,0 @@ +-APP_SOURCES += dhcpc.c timer.c +diff --git a/iscsiuio/src/apps/dhcpc/dhcpc.c b/iscsiuio/src/apps/dhcpc/dhcpc.c +deleted file mode 100644 +index f4a9994..0000000 +--- a/iscsiuio/src/apps/dhcpc/dhcpc.c ++++ /dev/null +@@ -1,417 +0,0 @@ +-/* +- * Copyright (c) 2005, Swedish Institute of Computer Science +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. Neither the name of the Institute nor the names of its contributors +- * may be used to endorse or promote products derived from this software +- * without specific prior written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND +- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE +- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +- * SUCH DAMAGE. +- * +- * This file is part of the uIP TCP/IP stack +- * +- */ +- +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include "uip.h" +-#include "dhcpc.h" +-#include "timer.h" +-#include "pt.h" +- +-#include "debug.h" +-#include "logger.h" +-#include "nic.h" +-#include "nic_utils.h" +- +-struct __attribute__ ((__packed__)) dhcp_msg { +- u8_t op, htype, hlen, hops; +- u8_t xid[4]; +- u16_t secs, flags; +- u8_t ciaddr[4]; +- u8_t yiaddr[4]; +- u8_t siaddr[4]; +- u8_t giaddr[4]; +- u8_t chaddr[16]; +-#ifndef UIP_CONF_DHCP_LIGHT +- u8_t sname[64]; +- u8_t file[128]; +-#endif +- u8_t options[312]; +-}; +- +-#define BOOTP_BROADCAST 0x8000 +- +-#define DHCP_REQUEST 1 +-#define DHCP_REPLY 2 +-#define DHCP_HTYPE_ETHERNET 1 +-#define DHCP_HLEN_ETHERNET 6 +-#define DHCP_MSG_LEN 236 +- +-#define DHCPC_SERVER_PORT 67 +-#define DHCPC_CLIENT_PORT 68 +- +-#define DHCPDISCOVER 1 +-#define DHCPOFFER 2 +-#define DHCPREQUEST 3 +-#define DHCPDECLINE 4 +-#define DHCPACK 5 +-#define DHCPNAK 6 +-#define DHCPRELEASE 7 +- +-#define DHCP_OPTION_SUBNET_MASK 1 +-#define DHCP_OPTION_ROUTER 3 +-#define DHCP_OPTION_DNS_SERVER 6 +-#define DHCP_OPTION_REQ_IPADDR 50 +-#define DHCP_OPTION_LEASE_TIME 51 +-#define DHCP_OPTION_MSG_TYPE 53 +-#define DHCP_OPTION_SERVER_ID 54 +-#define DHCP_OPTION_REQ_LIST 55 +-#define DHCP_OPTION_END 255 +- +-static u8_t xid[4] = { 0xad, 0xde, 0x12, 0x23 }; +-static const u8_t magic_cookie[4] = { 99, 130, 83, 99 }; +- +-struct dhcpc_options dhcpc_opt = { +- .enable_random_xid = 1, +-}; +- +-/*---------------------------------------------------------------------------*/ +-static u8_t *add_msg_type(u8_t *optptr, u8_t type) +-{ +- *optptr++ = DHCP_OPTION_MSG_TYPE; +- *optptr++ = 1; +- *optptr++ = type; +- return optptr; +-} +- +-/*---------------------------------------------------------------------------*/ +-static u8_t *add_server_id(struct dhcpc_state *s, u8_t *optptr) +-{ +- *optptr++ = DHCP_OPTION_SERVER_ID; +- *optptr++ = 4; +- memcpy(optptr, s->serverid, 4); +- return optptr + 4; +-} +- +-/*---------------------------------------------------------------------------*/ +-static u8_t *add_req_ipaddr(struct dhcpc_state *s, u8_t *optptr) +-{ +- *optptr++ = DHCP_OPTION_REQ_IPADDR; +- *optptr++ = 4; +- memcpy(optptr, s->ipaddr, 4); +- return optptr + 4; +-} +- +-/*---------------------------------------------------------------------------*/ +-static u8_t *add_req_options(u8_t *optptr) +-{ +- *optptr++ = DHCP_OPTION_REQ_LIST; +- *optptr++ = 3; +- *optptr++ = DHCP_OPTION_SUBNET_MASK; +- *optptr++ = DHCP_OPTION_ROUTER; +- *optptr++ = DHCP_OPTION_DNS_SERVER; +- return optptr; +-} +- +-/*---------------------------------------------------------------------------*/ +-static u8_t *add_end(u8_t *optptr) +-{ +- *optptr++ = DHCP_OPTION_END; +- return optptr; +-} +- +-/*---------------------------------------------------------------------------*/ +-static void create_msg(struct dhcpc_state *s, struct dhcp_msg *m) +-{ +- m->op = DHCP_REQUEST; +- m->htype = DHCP_HTYPE_ETHERNET; +- m->hlen = s->mac_len; +- m->hops = 0; +- memcpy(m->xid, xid, sizeof(m->xid)); +- m->secs = 0; +- m->flags = const_htons(BOOTP_BROADCAST); /* Broadcast bit. */ +- /* uip_ipaddr_copy(m->ciaddr, uip_hostaddr); */ +- memcpy(m->ciaddr, s->ustack->hostaddr, sizeof(m->ciaddr)); +- memset(m->yiaddr, 0, sizeof(m->yiaddr)); +- memset(m->siaddr, 0, sizeof(m->siaddr)); +- memset(m->giaddr, 0, sizeof(m->giaddr)); +- memcpy(m->chaddr, s->mac_addr, s->mac_len); +- memset(&m->chaddr[s->mac_len], 0, sizeof(m->chaddr) - s->mac_len); +-#ifndef UIP_CONF_DHCP_LIGHT +- memset(m->sname, 0, sizeof(m->sname)); +- memset(m->file, 0, sizeof(m->file)); +-#endif +- +- memcpy(m->options, magic_cookie, sizeof(magic_cookie)); +-} +- +-/*---------------------------------------------------------------------------*/ +-static void send_discover(struct dhcpc_state *s) +-{ +- u8_t *end; +- struct dhcp_msg *m = (struct dhcp_msg *)s->ustack->uip_appdata; +- +- create_msg(s, m); +- +- end = add_msg_type(&m->options[4], DHCPDISCOVER); +- end = add_req_options(end); +- end = add_end(end); +- +- uip_appsend(s->ustack, s->ustack->uip_appdata, +- end - (u8_t *) s->ustack->uip_appdata); +-} +- +-/*---------------------------------------------------------------------------*/ +-static void send_request(struct dhcpc_state *s) +-{ +- u8_t *end; +- struct dhcp_msg *m = (struct dhcp_msg *)s->ustack->uip_appdata; +- +- create_msg(s, m); +- +- end = add_msg_type(&m->options[4], DHCPREQUEST); +- end = add_server_id(s, end); +- end = add_req_ipaddr(s, end); +- end = add_end(end); +- +- uip_appsend(s->ustack, s->ustack->uip_appdata, +- end - (u8_t *) s->ustack->uip_appdata); +-} +- +-/*---------------------------------------------------------------------------*/ +-static u8_t parse_options(struct dhcpc_state *s, u8_t *optptr, int len) +-{ +- u8_t *end = optptr + len; +- u8_t type = 0; +- +- while (optptr < end) { +- switch (*optptr) { +- case DHCP_OPTION_SUBNET_MASK: +- memcpy(s->netmask, optptr + 2, 4); +- break; +- case DHCP_OPTION_ROUTER: +- memcpy(s->default_router, optptr + 2, 4); +- break; +- case DHCP_OPTION_DNS_SERVER: +- memcpy(s->dnsaddr, optptr + 2, 4); +- break; +- case DHCP_OPTION_MSG_TYPE: +- type = *(optptr + 2); +- break; +- case DHCP_OPTION_SERVER_ID: +- memcpy(s->serverid, optptr + 2, 4); +- break; +- case DHCP_OPTION_LEASE_TIME: +- memcpy(s->lease_time, optptr + 2, 4); +- break; +- case DHCP_OPTION_END: +- return type; +- } +- +- optptr += optptr[1] + 2; +- } +- return type; +-} +- +-/*---------------------------------------------------------------------------*/ +-static u8_t parse_msg(struct dhcpc_state *s) +-{ +- struct dhcp_msg *m = (struct dhcp_msg *)s->ustack->uip_appdata; +- +- if (m->op == DHCP_REPLY && +- memcmp(m->xid, xid, sizeof(xid)) == 0 && +- memcmp(m->chaddr, s->mac_addr, s->mac_len) == 0) { +- memcpy(s->ipaddr, m->yiaddr, 4); +- return parse_options(s, &m->options[4], uip_datalen(s->ustack)); +- } +- return 0; +-} +- +-/*---------------------------------------------------------------------------*/ +-static PT_THREAD(handle_dhcp(struct uip_stack *ustack)) +-{ +- struct dhcpc_state *s; +- s = ustack->dhcpc; +- +- if (s == NULL) { +- LOG_WARN("Could not find dhcpc state"); +- return PT_ENDED; +- } +- +- PT_BEGIN(&s->pt); +- +- /* try_again: */ +- s->state = STATE_SENDING; +- s->ticks = CLOCK_SECOND; +- +- do { +- send_discover(s); +- timer_set(&s->timer, s->ticks); +- PT_WAIT_UNTIL(&s->pt, uip_newdata(s->ustack) +- || timer_expired(&s->timer)); +- +- if (uip_newdata(s->ustack) && parse_msg(s) == DHCPOFFER) { +- s->state = STATE_OFFER_RECEIVED; +- break; +- } +- +- if (s->ticks < CLOCK_SECOND * 60) +- s->ticks += CLOCK_SECOND; +- else +- PT_RESTART(&s->pt); +- } while (s->state != STATE_OFFER_RECEIVED); +- +- s->ticks = CLOCK_SECOND; +- +- do { +- send_request(s); +- timer_set(&s->timer, s->ticks); +- s->ustack->uip_flags &= ~UIP_NEWDATA; +- PT_WAIT_UNTIL(&s->pt, uip_newdata(s->ustack) +- || timer_expired(&s->timer)); +- +- if (uip_newdata(s->ustack) && parse_msg(s) == DHCPACK) { +- s->state = STATE_CONFIG_RECEIVED; +- break; +- } +- +- if (s->ticks <= CLOCK_SECOND * 10) +- s->ticks += CLOCK_SECOND; +- else +- PT_RESTART(&s->pt); +- } while (s->state != STATE_CONFIG_RECEIVED); +- +- LOG_INFO("Got IP address %d.%d.%d.%d", +- uip_ipaddr1(s->ipaddr), uip_ipaddr2(s->ipaddr), +- uip_ipaddr3(s->ipaddr), uip_ipaddr4(s->ipaddr)); +- LOG_INFO("Got netmask %d.%d.%d.%d", +- uip_ipaddr1(s->netmask), uip_ipaddr2(s->netmask), +- uip_ipaddr3(s->netmask), uip_ipaddr4(s->netmask)); +- LOG_INFO("Got DNS server %d.%d.%d.%d", +- uip_ipaddr1(s->dnsaddr), uip_ipaddr2(s->dnsaddr), +- uip_ipaddr3(s->dnsaddr), uip_ipaddr4(s->dnsaddr)); +- LOG_INFO("Got default router %d.%d.%d.%d", +- uip_ipaddr1(s->default_router), uip_ipaddr2(s->default_router), +- uip_ipaddr3(s->default_router), +- uip_ipaddr4(s->default_router)); +- s->lease_time_nl32 = +- ntohs(s->lease_time[0]) * 65536ul + ntohs(s->lease_time[1]); +- LOG_INFO("Lease expires in %ld seconds", s->lease_time_nl32); +- +- s->last_update = time(NULL); +- +- set_uip_stack(s->ustack, +- (uip_ip4addr_t *) s->ipaddr, +- (uip_ip4addr_t *) s->netmask, +- (uip_ip4addr_t *) s->default_router, +- (uint8_t *) s->mac_addr); +- +- /* Put the stack thread back into a long sleep */ +- s->nic->flags |= NIC_LONG_SLEEP; +- +- /* timer_stop(&s.timer); */ +- +- /* Handle DHCP lease expiration */ +- s->ticks = CLOCK_SECOND * s->lease_time_nl32; +- 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->flags &= ~NIC_LONG_SLEEP; +- PT_RESTART(&s->pt); +- +- /* +- * PT_END restarts the thread so we do this instead. Eventually we +- * should reacquire expired leases here. +- */ +- +- while (1) +- PT_YIELD(&s->pt); +- +- PT_END(&(s->pt)); +-} +- +-/*---------------------------------------------------------------------------*/ +-int dhcpc_init(nic_t *nic, struct uip_stack *ustack, +- const void *mac_addr, int mac_len) +-{ +- uip_ip4addr_t addr; +- struct dhcpc_state *s = ustack->dhcpc; +- +- if (s) { +- LOG_DEBUG("DHCP: DHCP context already allocated"); +- return -EALREADY; +- } +- s = malloc(sizeof(*s)); +- if (s == NULL) { +- LOG_ERR("Couldn't allocate size for dhcpc info"); +- return -ENOMEM; +- } +- +- memset(s, 0, sizeof(*s)); +- s->nic = nic; +- s->ustack = ustack; +- s->mac_addr = mac_addr; +- s->mac_len = mac_len; +- s->state = STATE_INITIAL; +- +- /* Initialize XID to randomly */ +- if (dhcpc_opt.enable_random_xid == 1) { +- u32_t gen_xid; +- gen_xid = random(); +- memcpy(xid, &gen_xid, sizeof(gen_xid)); +- } +- uip_ipaddr(addr, 255, 255, 255, 255); +- s->conn = uip_udp_new(ustack, &addr, const_htons(DHCPC_SERVER_PORT)); +- if (s->conn != NULL) +- uip_udp_bind(s->conn, const_htons(DHCPC_CLIENT_PORT)); +- +- ustack->dhcpc = s; +- +- /* Let the RX poll value take over */ +- nic->flags &= ~NIC_LONG_SLEEP; +- +- PT_INIT(&s->pt); +- +- return 0; +-} +- +-/*---------------------------------------------------------------------------*/ +-void dhcpc_appcall(struct uip_stack *ustack) +-{ +- handle_dhcp(ustack); +-} +- +-/*---------------------------------------------------------------------------*/ +-void dhcpc_request(struct uip_stack *ustack) +-{ +- struct dhcpc_state *s = ustack->dhcpc; +- +- if (s != NULL && s->state == STATE_INITIAL) +- handle_dhcp(ustack); +-} +- +-/*---------------------------------------------------------------------------*/ +diff --git a/iscsiuio/src/apps/dhcpc/dhcpc.h b/iscsiuio/src/apps/dhcpc/dhcpc.h +deleted file mode 100644 +index 89cf086..0000000 +--- a/iscsiuio/src/apps/dhcpc/dhcpc.h ++++ /dev/null +@@ -1,86 +0,0 @@ +-/* +- * Copyright (c) 2005, Swedish Institute of Computer Science +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. Neither the name of the Institute nor the names of its contributors +- * may be used to endorse or promote products derived from this software +- * without specific prior written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND +- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE +- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +- * SUCH DAMAGE. +- * +- * This file is part of the uIP TCP/IP stack +- * +- */ +-#ifndef __DHCPC_H__ +-#define __DHCPC_H__ +- +-#include +- +-#include "nic.h" +-#include "timer.h" +-#include "pt.h" +-#include "uip.h" +- +-#define STATE_INITIAL 0 +-#define STATE_SENDING 1 +-#define STATE_OFFER_RECEIVED 2 +-#define STATE_CONFIG_RECEIVED 3 +- +-struct dhcpc_state { +- struct pt pt; +- +- nic_t *nic; +- struct uip_stack *ustack; +- char state; +- struct uip_udp_conn *conn; +- struct timer timer; +- u32_t ticks; +- const void *mac_addr; +- int mac_len; +- +- u8_t serverid[4]; +- +- u16_t lease_time[2]; +- u32_t lease_time_nl32; +- u16_t ipaddr[2]; +- u16_t netmask[2]; +- u16_t dnsaddr[2]; +- u16_t default_router[2]; +- +- time_t last_update; +-}; +- +-struct dhcpc_options { +- u8_t enable_random_xid; +- u8_t xid[4]; +-}; +- +-int dhcpc_init(nic_t *nic, struct uip_stack *ustack, +- const void *mac_addr, int mac_len); +-void dhcpc_request(struct uip_stack *ustack); +- +-void dhcpc_appcall(struct uip_stack *ustack); +- +-void dhcpc_configured(const struct dhcpc_state *s); +- +-#define UIP_UDP_APPCALL dhcpc_appcall +- +-#endif /* __DHCPC_H__ */ +diff --git a/iscsiuio/src/apps/dhcpc/dhcpv6.c b/iscsiuio/src/apps/dhcpc/dhcpv6.c +deleted file mode 100644 +index 461af0e..0000000 +--- a/iscsiuio/src/apps/dhcpc/dhcpv6.c ++++ /dev/null +@@ -1,517 +0,0 @@ +-/* +- * Copyright (c) 2011, Broadcom Corporation +- * Copyright (c) 2014, QLogic Corporation +- * +- * Written by: Eddie Wai +- * Based on code from Kevin Tran's iSCSI boot code +- * +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. All advertising materials mentioning features or use of this software +- * must display the following acknowledgement: +- * This product includes software developed by Adam Dunkels. +- * 4. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * dhcpv6.c - DHCPv6 engine +- * +- */ +-#include +-#include +- +-#include "ipv6.h" +-#include "ipv6_pkt.h" +-#include "dhcpv6.h" +-#include "logger.h" +- +-/* Local function prototypes */ +-static int dhcpv6_send_solicit_packet(struct dhcpv6_context *context); +-static int dhcpv6_send_request_packet(struct dhcpv6_context *context); +-static u16_t dhcpv6_init_packet(struct dhcpv6_context *context, u8_t type); +-static void dhcpv6_init_dhcpv6_server_addr(struct ipv6_addr *addr); +-static void dhcpv6_handle_advertise(struct dhcpv6_context *context, +- u16_t dhcpv6_len); +-static void dhcpv6_handle_reply(struct dhcpv6_context *context, +- u16_t dhcpv6_len); +-static int dhcpv6_process_opt_ia_na(struct dhcpv6_context *context, +- struct dhcpv6_opt_hdr *opt_hdr); +-static void dhcpv6_process_opt_dns_servers(struct dhcpv6_context *context, +- struct dhcpv6_opt_hdr *opt_hdr); +-static void dhcpv6_parse_vendor_option(struct dhcpv6_context *context, +- u8_t *option, int len); +- +-void dhcpv6_init(struct dhcpv6_context *context) +-{ +- context->seconds = 0; +- context->our_mac_addr = +- ipv6_get_link_addr(context->ipv6_context); +- +- /* Use the last four bytes of MAC address as base of the transaction +- ID */ +- context->dhcpv6_transaction_id = context->our_mac_addr->last_4_bytes; +- +- context->dhcpv6_done = FALSE; +- strcpy(context->dhcp_vendor_id, "BRCM ISAN"); +-} +- +-int dhcpv6_do_discovery(struct dhcpv6_context *context) +-{ +- int retc = ISCSI_FAILURE; +- +- context->eth = +- (struct eth_hdr *)context->ipv6_context->ustack->data_link_layer; +- context->ipv6 = +- (struct ipv6_hdr *)context->ipv6_context->ustack->network_layer; +- context->udp = +- (struct udp_hdr *)((u8_t *)context->ipv6 + sizeof(struct ipv6_hdr)); +- +- /* Send out DHCPv6 Solicit packet. */ +- dhcpv6_send_solicit_packet(context); +- +- return retc; +-} +- +-static int dhcpv6_send_solicit_packet(struct dhcpv6_context *context) +-{ +- u16_t packet_len; +- +- LOG_DEBUG("DHCPV6: Send solicit"); +- packet_len = dhcpv6_init_packet(context, DHCPV6_SOLICIT); +- context->dhcpv6_state = DHCPV6_STATE_SOLICIT_SENT; +- ipv6_send_udp_packet(context->ipv6_context, packet_len); +- +- return 0; +-} +- +-static int dhcpv6_send_request_packet(struct dhcpv6_context *context) +-{ +- u16_t packet_len; +- +- LOG_DEBUG("DHCPV6: Send request"); +- packet_len = dhcpv6_init_packet(context, DHCPV6_REQUEST); +- +- context->dhcpv6_state = DHCPV6_STATE_REQ_SENT; +- ipv6_send_udp_packet(context->ipv6_context, packet_len); +- +- return 0; +-} +- +-static u16_t dhcpv6_init_packet(struct dhcpv6_context *context, u8_t type) +-{ +- u16_t pkt_len; +- struct udp_hdr *udp = context->udp; +- union dhcpv6_hdr *dhcpv6; +- struct dhcpv6_option *opt; +- u16_t len; +- +- /* Initialize dest IP with well-known DHCP server address */ +- dhcpv6_init_dhcpv6_server_addr(&context->ipv6->ipv6_dst); +- /* Initialize dest MAC based on MC dest IP */ +- ipv6_mc_init_dest_mac(context->eth, context->ipv6); +- +- /* Initialize UDP header */ +- udp->src_port = HOST_TO_NET16(DHCPV6_CLIENT_PORT); +- udp->dest_port = HOST_TO_NET16(DHCPV6_SERVER_PORT); +- +- /* +- * DHCPv6 section has the following format per RFC 3315 +- * +- * 0 1 2 3 +- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- * | msg-type | transaction-id | +- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- * | | +- * . options . +- * . (variable) . +- * | | +- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- */ +- dhcpv6 = (union dhcpv6_hdr *)((u8_t *)udp + sizeof(struct udp_hdr)); +- +- if (dhcpv6->dhcpv6_type != type) +- context->dhcpv6_transaction_id++; +- +- dhcpv6->dhcpv6_trans_id = HOST_TO_NET16(context->dhcpv6_transaction_id); +- dhcpv6->dhcpv6_type = type; +- +- /* Keep track of length of all DHCP options. */ +- pkt_len = sizeof(union dhcpv6_hdr); +- +- if (dhcpv6->dhcpv6_type == DHCPV6_REQUEST) { +- /* We will send back whatever DHCPv6 sent us */ +- return ((u8_t *)udp - (u8_t *)context->eth + +- NET_TO_HOST16(udp->length)); +- } +- +- opt = (struct dhcpv6_option *)((u8_t *)dhcpv6 + +- sizeof(union dhcpv6_hdr)); +- /* Add client ID option */ +- opt->hdr.type = HOST_TO_NET16(DHCPV6_OPT_CLIENTID); +- opt->hdr.length = HOST_TO_NET16(sizeof(struct dhcpv6_opt_client_id)); +- opt->type.client_id.duid_type = +- 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 *)&opt->type.client_id.link_layer_addr, +- (char *)context->our_mac_addr, sizeof(struct mac_address)); +- pkt_len += sizeof(struct dhcpv6_opt_client_id) + +- sizeof(struct dhcpv6_opt_hdr); +- opt = (struct dhcpv6_option *)((u8_t *)opt + +- sizeof(struct dhcpv6_opt_client_id) + +- sizeof(struct dhcpv6_opt_hdr)); +- +- /* Add Vendor Class option if it's configured */ +- len = strlen(context->dhcp_vendor_id); +- if (len > 0) { +- opt->hdr.type = HOST_TO_NET16(DHCPV6_OPT_VENDOR_CLASS); +- opt->hdr.length = +- HOST_TO_NET16(sizeof(struct dhcpv6_vendor_class) +- + len - 1); +- opt->type.vendor_class.enterprise_number = +- HOST_TO_NET32(IANA_ENTERPRISE_NUM_BROADCOM); +- opt->type.vendor_class.vendor_class_length = HOST_TO_NET16(len); +- memcpy((char *)&opt->type.vendor_class. +- vendor_class_data[0], +- (char *)context->dhcp_vendor_id, len); +- pkt_len += +- sizeof(struct dhcpv6_vendor_class) - 1 + len + +- sizeof(struct dhcpv6_opt_hdr); +- opt = +- (struct dhcpv6_option *)((u8_t *)opt + +- sizeof(struct dhcpv6_vendor_class) - 1 + len + +- sizeof(struct dhcpv6_opt_hdr)); +- } +- +- /* Add IA_NA option */ +- opt->hdr.type = HOST_TO_NET16(DHCPV6_OPT_IA_NA); +- opt->hdr.length = HOST_TO_NET16(sizeof(struct dhcpv6_opt_id_assoc_na)); +- opt->type.ida_na.iaid = htonl(context->our_mac_addr->last_4_bytes); +- opt->type.ida_na.t1 = 0; +- opt->type.ida_na.t2 = 0; +- pkt_len += sizeof(struct dhcpv6_opt_id_assoc_na) + +- sizeof(struct dhcpv6_opt_hdr); +- opt = (struct dhcpv6_option *)((u8_t *)opt + +- sizeof(struct dhcpv6_opt_id_assoc_na) + +- sizeof(struct dhcpv6_opt_hdr)); +- /* Add Elapsed Time option */ +- opt->hdr.type = HOST_TO_NET16(DHCPV6_OPT_ELAPSED_TIME); +- opt->hdr.length = HOST_TO_NET16(sizeof(struct dhcpv6_opt_elapse_time)); +- opt->type.elapsed_time.time = HOST_TO_NET16(context->seconds); +- pkt_len += sizeof(struct dhcpv6_opt_elapse_time) + +- sizeof(struct dhcpv6_opt_hdr); +- +- /* Add Option Request List */ +- opt = (struct dhcpv6_option *)((u8_t *)opt + +- sizeof(struct dhcpv6_opt_elapse_time) + +- sizeof(struct dhcpv6_opt_hdr)); +- opt->hdr.type = HOST_TO_NET16(DHCPV6_OPT_ORO); +- opt->hdr.length = HOST_TO_NET16(3 * +- sizeof(struct dhcpv6_opt_request_list)); +- opt->type.list.request_code[0] = HOST_TO_NET16(DHCPV6_OPT_VENDOR_CLASS); +- opt->type.list.request_code[1] = HOST_TO_NET16(DHCPV6_OPT_VENDOR_OPTS); +- opt->type.list.request_code[2] = HOST_TO_NET16(DHCPV6_OPT_DNS_SERVERS); +- pkt_len += 3 * sizeof(struct dhcpv6_opt_request_list) + +- sizeof(struct dhcpv6_opt_hdr); +- +- udp->length = HOST_TO_NET16(sizeof(struct udp_hdr) + pkt_len); +- +- pkt_len += +- ((u8_t *)udp - (u8_t *)context->eth) + sizeof(struct udp_hdr); +- +- return pkt_len; +-} +- +-static void dhcpv6_init_dhcpv6_server_addr(struct ipv6_addr *addr) +-{ +- /* Well-known DHCPv6 server address is ff02::1:2 */ +- memset((char *)addr, 0, sizeof(struct ipv6_addr)); +- addr->addr8[0] = 0xff; +- addr->addr8[1] = 0x02; +- addr->addr8[13] = 0x01; +- addr->addr8[15] = 0x02; +-} +- +-void ipv6_udp_handle_dhcp(struct dhcpv6_context *context) +-{ +- union dhcpv6_hdr *dhcpv6; +- u16_t dhcpv6_len; +- +- if (context->dhcpv6_done == TRUE) +- return; +- +- dhcpv6 = (union dhcpv6_hdr *)((u8_t *)context->udp + +- sizeof(struct udp_hdr)); +- +- if (dhcpv6->dhcpv6_trans_id != +- HOST_TO_NET16(context->dhcpv6_transaction_id)) { +- LOG_ERR("DHCPv6 transaction-id error, sent %x, received %x", +- HOST_TO_NET16(context->dhcpv6_transaction_id), +- dhcpv6->dhcpv6_trans_id); +- return; +- } +- +- dhcpv6_len = +- NET_TO_HOST16(context->udp->length) - sizeof(struct udp_hdr); +- +- switch (dhcpv6->dhcpv6_type) { +- case DHCPV6_ADVERTISE: +- dhcpv6_handle_advertise(context, dhcpv6_len); +- break; +- +- case DHCPV6_REPLY: +- dhcpv6_handle_reply(context, dhcpv6_len); +- break; +- +- default: +- break; +- } +-} +- +-static void dhcpv6_handle_advertise(struct dhcpv6_context *context, +- u16_t dhcpv6_len) +-{ +- union dhcpv6_hdr *dhcpv6 = +- (union dhcpv6_hdr *)((u8_t *)context->udp + +- sizeof(struct udp_hdr)); +- struct dhcpv6_opt_hdr *opt; +- u16_t type; +- int i; +- int opt_len; +- u8_t *vendor_id = NULL; +- u16_t vendor_id_len = 0; +- u8_t *vendor_opt_data = NULL; +- int vendor_opt_len = 0; +- int addr_cnt = 0; +- +- /* We only handle DHCPv6 advertise if we recently sent DHCPv6 solicit */ +- if (context->dhcpv6_state != DHCPV6_STATE_SOLICIT_SENT) +- return; +- +- LOG_DEBUG("DHCPV6: handle advertise"); +- context->dhcpv6_state = DHCPV6_STATE_ADV_RCVD; +- +- i = 0; +- while (i < (dhcpv6_len - sizeof(union dhcpv6_hdr))) { +- opt = (struct dhcpv6_opt_hdr *)((u8_t *)dhcpv6 + +- sizeof(union dhcpv6_hdr) + i); +- opt_len = NET_TO_HOST16(opt->length); +- +- type = NET_TO_HOST16(opt->type); +- +- /* We only care about some of the options */ +- switch (type) { +- case DHCPV6_OPT_IA_NA: +- if (context-> +- dhcpv6_task & DHCPV6_TASK_GET_IP_ADDRESS) { +- addr_cnt += +- dhcpv6_process_opt_ia_na(context, opt); +- } +- break; +- +- case DHCPV6_OPT_VENDOR_CLASS: +- vendor_id_len = +- NET_TO_HOST16(((struct dhcpv6_option *)opt)->type. +- vendor_class.vendor_class_length); +- vendor_id = +- &((struct dhcpv6_option *)opt)->type.vendor_class. +- vendor_class_data[0]; +- break; +- +- case DHCPV6_OPT_VENDOR_OPTS: +- vendor_opt_len = opt_len - 4; +- vendor_opt_data = +- &((struct dhcpv6_option *)opt)->type.vendor_opts. +- vendor_opt_data[0]; +- break; +- +- case DHCPV6_OPT_DNS_SERVERS: +- if (context->dhcpv6_task & DHCPV6_TASK_GET_OTHER_PARAMS) +- dhcpv6_process_opt_dns_servers(context, opt); +- break; +- +- default: +- break; +- } +- +- i += NET_TO_HOST16(opt->length) + sizeof(struct dhcpv6_opt_hdr); +- } +- +- if (context->dhcpv6_task & DHCPV6_TASK_GET_OTHER_PARAMS) { +- if ((vendor_id_len > 0) && +- (strncmp((char *)vendor_id, +- (char *)context->dhcp_vendor_id, +- vendor_id_len) == 0)) { +- dhcpv6_parse_vendor_option(context, +- vendor_opt_data, +- vendor_opt_len); +- context->dhcpv6_done = TRUE; +- } +- } +- +- if (context->dhcpv6_task & DHCPV6_TASK_GET_IP_ADDRESS) { +- if (addr_cnt > 0) { +- /* +- * If we need to acquire IP address from the server, +- * we need to send Request to server to confirm. +- */ +- dhcpv6_send_request_packet(context); +- context->dhcpv6_done = TRUE; +- } +- } +- +- if (context->dhcpv6_done) { +- /* Keep track of IPv6 address of DHCHv6 server */ +- memcpy((char *)&context->dhcp_server, +- (char *)&context->ipv6->ipv6_src, +- sizeof(struct ipv6_addr)); +- } +-} +- +-static int dhcpv6_process_opt_ia_na(struct dhcpv6_context *context, +- struct dhcpv6_opt_hdr *opt_hdr) +-{ +- int i; +- int opt_len; +- struct dhcpv6_option *opt; +- int len; +- int addr_cnt; +- opt_len = NET_TO_HOST16(opt_hdr->length) - +- sizeof(struct dhcpv6_opt_id_assoc_na); +- +- i = 0; +- addr_cnt = 0; +- while (i < opt_len) { +- opt = +- (struct dhcpv6_option *)((u8_t *)opt_hdr + +- sizeof(struct dhcpv6_opt_hdr) + +- sizeof(struct dhcpv6_opt_id_assoc_na) + i); +- +- len = NET_TO_HOST16(opt->hdr.length); +- switch (NET_TO_HOST16(opt->hdr.type)) { +- case DHCPV6_OPT_IAADDR: +- if (len > +- (sizeof(struct dhcpv6_opt_hdr) + +- sizeof(struct dhcpv6_opt_iaa_addr))) { +- struct dhcpv6_option *in_opt; +- +- in_opt = (struct dhcpv6_option *)((u8_t *)opt + +- sizeof(struct dhcpv6_opt_hdr) + +- sizeof(struct dhcpv6_opt_iaa_addr)); +- if (in_opt->hdr.type == +- HOST_TO_NET16(DHCPV6_OPT_STATUS_CODE)) { +- /* This entry has error! */ +- if (in_opt->type.sts.status != 0) +- break; +- } +- } +- LOG_INFO("DHCPv6: Got IP Addr"); +- /* Status is OK, let's add this addr to our address +- list */ +- ipv6_add_prefix_entry(context->ipv6_context, +- &opt->type.iaa_addr.addr, 64); +- +- /* Add multicast address for this address */ +- ipv6_add_solit_node_address(context-> +- ipv6_context, +- &opt->type.iaa_addr.addr); +- addr_cnt++; +- break; +- +- default: +- break; +- } +- +- i += len + sizeof(struct dhcpv6_opt_hdr); +- } +- +- return addr_cnt; +-} +- +-static void dhcpv6_process_opt_dns_servers(struct dhcpv6_context *context, +- struct dhcpv6_opt_hdr *opt_hdr) +-{ +- int opt_len; +- +- opt_len = NET_TO_HOST16(opt_hdr->length); +- +- if (opt_len >= sizeof(struct ipv6_addr)) +- memcpy((char *)&context->primary_dns_server, +- (char *)&((struct dhcpv6_option *)opt_hdr)->type.dns. +- primary_addr, sizeof(struct ipv6_addr)); +- +- if (opt_len >= 2 * sizeof(struct ipv6_addr)) +- memcpy((char *)&context->secondary_dns_server, +- (char *)&((struct dhcpv6_option *)opt_hdr)->type.dns. +- secondary_addr, sizeof(struct ipv6_addr)); +-} +- +-static void dhcpv6_handle_reply(struct dhcpv6_context *context, +- u16_t dhcpv6_len) +-{ +- if (context->dhcpv6_state != DHCPV6_STATE_REQ_SENT) +- return; +- +- context->dhcpv6_done = TRUE; +-} +- +-static void dhcpv6_parse_vendor_option(struct dhcpv6_context *context, +- u8_t *option, int len) +-{ +- struct dhcpv6_option *opt; +- u16_t type; +- int opt_len; +- int data_len; +- int i; +- u8_t *data; +- +- for (i = 0; i < len; i += opt_len + sizeof(struct dhcpv6_opt_hdr)) { +- opt = (struct dhcpv6_option *)((u8_t *)option + i); +- type = HOST_TO_NET16(opt->hdr.type); +- opt_len = HOST_TO_NET16(opt->hdr.length); +- data = &opt->type.data[0]; +- data_len = strlen((char *)data); +- +- switch (type) { +- case 201: +- /* iSCSI target 1 */ +- break; +- +- case 202: +- /* iSCSI target 2 */ +- break; +- +- case 203: +- if (data_len > ISCSI_MAX_ISCSI_NAME_LENGTH) +- data_len = ISCSI_MAX_ISCSI_NAME_LENGTH; +- data[data_len] = '\0'; +- strcpy(context->initiatorName, (char *)data); +- break; +- +- default: +- break; +- } +- } +-} +diff --git a/iscsiuio/src/apps/dhcpc/dhcpv6.h b/iscsiuio/src/apps/dhcpc/dhcpv6.h +deleted file mode 100644 +index d4ec4b9..0000000 +--- a/iscsiuio/src/apps/dhcpc/dhcpv6.h ++++ /dev/null +@@ -1,253 +0,0 @@ +-/* +- * Copyright (c) 2011, Broadcom Corporation +- * Copyright (c) 2014, QLogic Corporation +- * +- * Written by: Eddie Wai +- * Based on code from Kevin Tran's iSCSI boot code +- * +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. All advertising materials mentioning features or use of this software +- * must display the following acknowledgement: +- * This product includes software developed by Adam Dunkels. +- * 4. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * dhcpv6.h - DHCPv6 engine header +- * +- */ +-#ifndef __IDHCPV6_H__ +-#define __IDHCPV6_H__ +- +-#include "ipv6_ndpc.h" +-#include "ipv6.h" +- +-#define ISCSI_MAX_ISCSI_NAME_LENGTH 128 +-/* DHCPv6 Message types. */ +-#define DHCPV6_SOLICIT 1 +-#define DHCPV6_ADVERTISE 2 +-#define DHCPV6_REQUEST 3 +-#define DHCPV6_CONFIRM 4 +-#define DHCPV6_RENEW 5 +-#define DHCPV6_REBIND 6 +-#define DHCPV6_REPLY 7 +-#define DHCPV6_RELEASE 8 +-#define DHCPV6_DECLINE 9 +-#define DHCPV6_RECONFIGURE 10 +-#define DHCPV6_INFO_REQUEST 11 +-#define DHCPV6_RELAY_FORW 12 +-#define DHCPV6_RELAY_REPL 13 +- +-/* Option codes. */ +-#define DHCPV6_OPT_CLIENTID 1 /* Client ID option - built by stack */ +-#define DHCPV6_OPT_SERVERID 2 /* Server ID option - built by stack */ +-#define DHCPV6_OPT_IA_NA 3 /* IA_NA option - built by user */ +-#define DHCPV6_OPT_IA_TA 4 /* IA_TA option - not supported */ +-#define DHCPV6_OPT_IAADDR 5 /* IA_ADDR option - built by user */ +-#define DHCPV6_OPT_ORO 6 /* Option Request Option - built by +- stack */ +-#define DHCPV6_OPT_PREFERENCE 7 /* Preference option - built by server +- */ +-#define DHCPV6_OPT_ELAPSED_TIME 8 /* Elapsed Time option - built by stack +- */ +-#define DHCPV6_OPT_RELAY_MSG 9 /* Relay Message option - not supported +- */ +-#define DHCPV6_OPT_AUTH 11 /* Authentication option - built by +- stack */ +-#define DHCPV6_OPT_UNICAST 12 /* Server Unicast option - built by +- server */ +-#define DHCPV6_OPT_STATUS_CODE 13 /* Status Code option - built by stack +- */ +-#define DHCPV6_OPT_RAPID_COMMIT 14 /* Rapid Commit option - built by user +- */ +-#define DHCPV6_OPT_USER_CLASS 15 /* User Class option - built by user */ +-#define DHCPV6_OPT_VENDOR_CLASS 16 /* Vendor Class option - built by user +- */ +-#define DHCPV6_OPT_VENDOR_OPTS 17 /* Vendor-Specific Information option - +- build by user */ +-#define DHCPV6_OPT_INTERFACE_ID 18 /* Interface ID option - not supported +- */ +-#define DHCPV6_OPT_RECONF_MSG 19 /* Reconfigure Message option - built +- by server */ +-#define DHCPV6_OPT_RECONF_ACCEPT 20 /* Reconfigure Accept option - built by +- user */ +-#define DHCPV6_OPT_SIP_SERVER_D 21 /* NOT SUPPORTED - included for +- completeness only */ +-#define DHCPV6_OPT_SIP_SERVER_A 22 /* NOT SUPPORTED - included for +- completeness only */ +-#define DHCPV6_OPT_DNS_SERVERS 23 /* DNS Recursive Name Server option - +- built by server */ +-#define DHCPV6_OPT_DOMAIN_LIST 24 /* Domain Search List option - not +- supported */ +-#define DHCPV6_MAX_OPT_CODES 25 /* This will be the count + 1 since +- the parsing array starts +- at [1] instead of [0] */ +- +-/* Authentication protocol types. */ +-#define DHCPV6_DELAYED_AUTH_PROT 2 /* Delayed Authentication protocol. */ +-#define DHCPV6_RECON_KEY_AUTH_PROT 3 /* Reconfigure Key Authentication +- protocol. */ +- +-struct dhcpv6_context { +-#define DHCP_VENDOR_ID_LEN 128 +- char dhcp_vendor_id[DHCP_VENDOR_ID_LEN]; +- struct mac_address *our_mac_addr; +- u32_t dhcpv6_transaction_id; +- u16_t seconds; +- int timeout; +- int dhcpv6_done; +- +-#define DHCPV6_STATE_UNKNOWN 0 +-#define DHCPV6_STATE_SOLICIT_SENT 1 +-#define DHCPV6_STATE_ADV_RCVD 2 +-#define DHCPV6_STATE_REQ_SENT 3 +-#define DHCPV6_STATE_CONFIRM_SENT 4 +- int dhcpv6_state; +- u16_t dhcpv6_task; +- struct ipv6_context *ipv6_context; +- struct eth_hdr *eth; +- struct ipv6_hdr *ipv6; +- struct udp_hdr *udp; +- +- char initiatorName[ISCSI_MAX_ISCSI_NAME_LENGTH]; +- struct ipv6_addr dhcp_server; +- struct ipv6_addr primary_dns_server; +- struct ipv6_addr secondary_dns_server; +- +-}; +- +-union dhcpv6_hdr { +- struct { +- u32_t type:8; +- u32_t trans_id:24; +- } field; +- +- u32_t type_transaction; +-}; +- +-#define dhcpv6_type field.type +-#define dhcpv6_trans_id field.trans_id +- +-struct dhcpv6_opt_hdr { +- u16_t type; +- u16_t length; +-}; +- +-struct dhcpv6_opt_client_id { +- u16_t duid_type; +-#define DHCPV6_DUID_TYPE_LINK_LAYER_AND_TIME 1 +-#define DHCPV6_DUID_TYPE_VENDOR_BASED 2 +-#define DHCPV6_DUID_TYPE_LINK_LAYER 3 +- u16_t hw_type; +-#define DHCPV6_HW_TYPE_ETHERNET 1 +- u32_t time; +- struct mac_address link_layer_addr; +-}; +- +-struct dhcpv6_opt_id_assoc_na { +- u32_t iaid; +-#define DHCPV6_OPT_IA_NA_IAID 0x306373L +- u32_t t1; +- u32_t t2; +-}; +- +-struct dhcpv6_opt_elapse_time { +- u16_t time; +-}; +- +-struct dhcpv6_opt_iaa_addr { +- struct ipv6_addr addr; +- u32_t preferred_lifetime; +- u32_t valid_lifetime; +-}; +- +-struct dhcpv6_opt_status { +- u16_t status; +-}; +- +-struct dhcpv6_opt_request_list { +- u16_t request_code[1]; +-}; +- +-struct dhcpv6_opt_dns { +- struct ipv6_addr primary_addr; +- struct ipv6_addr secondary_addr; +-}; +- +-struct dhcpv6_vendor_class { +- u32_t enterprise_number; +- u16_t vendor_class_length; +- u8_t vendor_class_data[1]; +-}; +- +-struct dhcpv6_vendor_opts { +- u32_t enterprise_number; +- u8_t vendor_opt_data[1]; +-}; +- +-struct dhcpv6_option { +- struct dhcpv6_opt_hdr hdr; +- union { +- struct dhcpv6_vendor_opts vendor_opts; +- struct dhcpv6_vendor_class vendor_class; +- struct dhcpv6_opt_client_id client_id; +- struct dhcpv6_opt_id_assoc_na ida_na; +- struct dhcpv6_opt_elapse_time elapsed_time; +- struct dhcpv6_opt_iaa_addr iaa_addr; +- struct dhcpv6_opt_status sts; +- struct dhcpv6_opt_request_list list; +- struct dhcpv6_opt_dns dns; +- u8_t data[1]; +- } type; +-}; +- +-#define DHCPV6_NUM_OF_RETRY 4 +- +-#define DHCPV6_ACK_TIMEOUT 2 +- +-#define IANA_ENTERPRISE_NUM_BROADCOM 0x113d +- +-/* QLogic Extended DHCP options used in iSCSI boot */ +-#define DHCPV6_TAG_FIRST_ISCSI_TARGET_NAME 201 +-#define DHCPV6_TAG_SECOND_ISCSI_TARGET_NAME 202 +-#define DHCPV6_TAG_ISCSI_INITIATOR_NAME 203 +- +-#define MAX_DHCP_RX_OFFERS 4 +-#define MAX_DHCP_OPTION43_LENGTH 1024 +- +-#define DHCPV6_TASK_GET_IP_ADDRESS 0x1 +-#define DHCPV6_TASK_GET_OTHER_PARAMS 0x2 +- +-enum { +- ISCSI_FAILURE, +- ISCSI_USER_ABORT, +- ISCSI_SUCCESS +-}; +- +-/* Function prototypes */ +-int dhcpv6_do_discovery(struct dhcpv6_context *context); +-void ipv6_udp_handle_dhcp(struct dhcpv6_context *context); +-void dhcpv6_init(struct dhcpv6_context *context); +- +-#endif /* __IDHCPV6_H__ */ +diff --git a/iscsiuio/src/uip-1.0-changelog.txt b/iscsiuio/src/uip-1.0-changelog.txt +deleted file mode 100644 +index 800e444..0000000 +--- a/iscsiuio/src/uip-1.0-changelog.txt ++++ /dev/null +@@ -1,98 +0,0 @@ +-* A new API: protosockets that are similar to BSD sockets but does not +- require any underlying multithreading system. +- +-* Very rudimentary IPv6 support +- +-* New application: DHCP client. Web server rewritten with protosockets. +- +-* Removed uIP zero-copy functionality in order to simplify uIP device +- driver coding: outbound packets are now *always* stored in full in +- the uip_buf buffer. +- +-* Checksum computation is now part of uip.c, but it still is possible +- to implement them in assembly code by specifying a configuration +- option. Checksum code now runs on architectures with 2-byte alignment. +- +-* Added TCP persistent timer. +- +-* Made all IP address representations use the new uip_ipaddr_ip +- datatype for clarity. +- +-* Updated window behavior so that sending to a host with a small open +- window works better now. +- +-* UDP API change: uip_udp_new() now takes port numbers in network byte +- order like TCP functions. +- +-* Allow reception of packets when no IP address is configured to make +- DHCP work. +- +-* Moved Ethernet address into main uIP module from ARP module. +- +-* Made constants explicit #defines and moved them out of the code +- (header sizes, TCP options, TCP header length field). +- +-* If uip_len is less than that reported by the IP header, the packet +- is discarded. If uip_len is greater than the length reported by the +- IP header, uip_len is adjusted. +- +-* Moved header size definitions into header file. +- +-* Added uIP call for polling an application without triggering any +- timer events. Removed redundant assignments of uip_len and uip_slen. +- +-* Removed compiler warning about icmp_input label being defined when +- UIP_PINGADDRCONF was not used. +- +-* Added UIP_APPDATA_SIZE macro that holds the available buffer size +- for user data. +- +-* Added uip_udp_bind() call. +- +-* Moved checksum code into main uIP module. +- +-* Switched the TCP, UDP and IP header structures to be structs rather +- than typedefs. +- +-* Prefixed TCP state names with UIP_ to avoid name space +- contamination. +- +-* Changed declarations of uip_appdatap and friends to void * to avoid +- explicit typecasts. +- +-* Bugfixes +- +- o TCP: Fixed bug with high byte of peer window size. +- +- o TCP: Fixed bug that in some cases prevented concurrent reception and +- transmission of TCP data. +- +- o TCP: uip_connect() didn't correctly calculate age of TIME_WAIT +- connections. +- +- o TCP: Array index for uip_conns[] array was out of bounds in +- comparison. Comparison changed to make index within bounds. +- +- o TCP: if the remote host crashes and tries to reestablish an old +- connection, uIP should respond with an ACK with the correct +- sequence and acknowledgment numbers, to which the remote host +- should respond with an ACK. uIP did not respond with the correct +- ACK. +- +- o TCP: Fixed check for SYNACK segment: now checks only relevant TCP +- control flags and discards flags reserved for future expansion. +- +- o TCP: Fixed bug where uIP did not inform application that a connection +- had been aborted during an active open. +- +- o TCP: FIN segment was accepted even though application had stopped +- incoming data with uip_stop(). +- +- o TCP: A FINACK segment would not always correctly acknowledge data. +- +- o UDP: checksums are now calculated after all fields have been +- filled in. +- +- o UDP: network byte order on lastport in uip_udp_new(). +- +- o IP: memset() bugs in IP fragment reassembly code fixed. +diff --git a/iscsiuio/src/uip/Makefile.am b/iscsiuio/src/uip/Makefile.am +deleted file mode 100644 +index 16170d7..0000000 +--- a/iscsiuio/src/uip/Makefile.am ++++ /dev/null +@@ -1,18 +0,0 @@ +-AM_CFLAGS = -I${top_srcdir}/src/unix \ +- -I${top_srcdir}/src/apps/dhcpc \ +- -I${top_srcdir}/src/apps/brcm-iscsi \ +- -I${top_srcdir}/../include \ +- -I${top_srcdir}/../usr +- +-noinst_LIBRARIES = lib_iscsi_uip.a +- +-lib_iscsi_uip_a_SOURCES = uip.c \ +- uip_arp.c \ +- psock.c \ +- timer.c \ +- uip-neighbor.c \ +- uip_eth.c \ +- ipv6_ndpc.c \ +- ipv6.c +- +-lib_iscsi_uip_a_CFLAGS = -DBYTE_ORDER=@ENDIAN@ $(AM_CFLAGS) +diff --git a/iscsiuio/src/uip/Makefile.include b/iscsiuio/src/uip/Makefile.include +deleted file mode 100644 +index aa3ac63..0000000 +--- a/iscsiuio/src/uip/Makefile.include ++++ /dev/null +@@ -1,47 +0,0 @@ +- +- +-ifdef APPS +- APPDIRS = $(foreach APP, $(APPS), ../apps/$(APP)) +- -include $(foreach APP, $(APPS), ../apps/$(APP)/Makefile.$(APP)) +- CFLAGS += $(addprefix -I../apps/,$(APPS)) +-endif +- +-ifndef CCDEP +- CCDEP = $(CC) +-endif +-ifndef CCDEPCFLAGS +- CCDEPCFLAGS = $(CFLAGS) +-endif +-ifndef OBJECTDIR +- OBJECTDIR = obj +-endif +- +-ifeq (${wildcard $(OBJECTDIR)},) +- DUMMY := ${shell mkdir $(OBJECTDIR)} +-endif +- +- +-vpath %.c . ../uip ../lib $(APPDIRS) +- +-$(OBJECTDIR)/%.o: %.c +- $(CC) $(CFLAGS) -c $< -o $@ +- +-$(OBJECTDIR)/%.d: %.c +- @set -e; rm -f $@; \ +- $(CCDEP) -MM $(CCDEPCFLAGS) $< > $@.$$$$; \ +- sed 's,\($*\)\.o[ :]*,$(OBJECTDIR)/\1.o $@ : ,g' < $@.$$$$ > $@; \ +- rm -f $@.$$$$ +- +-UIP_SOURCES=uip.c uip_arp.c uiplib.c psock.c timer.c uip-neighbor.c uip_eth.c ipv6_ndp.c ipv6.c +- +- +-ifneq ($(MAKECMDGOALS),clean) +--include $(addprefix $(OBJECTDIR)/,$(UIP_SOURCES:.c=.d) \ +- $(APP_SOURCES:.c=.d)) +-endif +- +-libuip.a: ${addprefix $(OBJECTDIR)/, $(UIP_SOURCES:.c=.o)} +- $(AR) rc $@ $^ +- +-libapps.a: ${addprefix $(OBJECTDIR)/, $(APP_SOURCES:.c=.o)} +- $(AR) rc $@ $^ +diff --git a/iscsiuio/src/uip/clock.h b/iscsiuio/src/uip/clock.h +deleted file mode 100644 +index d79326b..0000000 +--- a/iscsiuio/src/uip/clock.h ++++ /dev/null +@@ -1,87 +0,0 @@ +-/** +- * \defgroup clock Clock interface +- * +- * The clock interface is the interface between the \ref timer "timer library" +- * and the platform specific clock functionality. The clock +- * interface must be implemented for each platform that uses the \ref +- * timer "timer library". +- * +- * The clock interface does only one this: it measures time. The clock +- * interface provides a macro, CLOCK_SECOND, which corresponds to one +- * second of system time. +- * +- * \sa \ref timer "Timer library" +- * +- * @{ +- */ +- +-/* +- * Copyright (c) 2004, Swedish Institute of Computer Science. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. Neither the name of the Institute nor the names of its contributors +- * may be used to endorse or promote products derived from this software +- * without specific prior written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND +- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE +- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +- * SUCH DAMAGE. +- * +- * This file is part of the uIP TCP/IP stack +- * +- * Author: Adam Dunkels +- * +- */ +-#ifndef __CLOCK_H__ +-#define __CLOCK_H__ +- +-#include "clock-arch.h" +- +-/** +- * Initialize the clock library. +- * +- * This function initializes the clock library and should be called +- * from the main() function of the system. +- * +- */ +-void clock_init(void); +- +-/** +- * Get the current clock time. +- * +- * This function returns the current system clock time. +- * +- * \return The current clock time, measured in system ticks. +- */ +-clock_time_t clock_time(void); +- +-/** +- * A second, measured in system clock time. +- * +- * \hideinitializer +- */ +-#ifdef CLOCK_CONF_SECOND +-#define CLOCK_SECOND CLOCK_CONF_SECOND +-#else +-#define CLOCK_SECOND (clock_time_t)32 +-#endif +- +-#endif /* __CLOCK_H__ */ +- +-/** @} */ +diff --git a/iscsiuio/src/uip/debug.h b/iscsiuio/src/uip/debug.h +deleted file mode 100644 +index a58fa7a..0000000 +--- a/iscsiuio/src/uip/debug.h ++++ /dev/null +@@ -1,13 +0,0 @@ +-#ifndef __DEBUG_H__ +-#define __DEBUG_H__ +- +-#ifdef DEBUG +-#define UIP_DEBUG(args...) \ +- do { \ +- fprintf(stdout, args); \ +- fflush(stdout); \ +- } while (0); +-#else +-#endif +- +-#endif +diff --git a/iscsiuio/src/uip/icmpv6.h b/iscsiuio/src/uip/icmpv6.h +deleted file mode 100644 +index cbf9aa8..0000000 +--- a/iscsiuio/src/uip/icmpv6.h ++++ /dev/null +@@ -1,302 +0,0 @@ +-/* +- * Copyright (c) 2011, Broadcom Corporation +- * Copyright (c) 2014, QLogic Corporation +- * +- * Written by: Eddie Wai (eddie.wai@broadcom.com) +- * Based on Kevin Tran's iSCSI boot code +- * +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. All advertising materials mentioning features or use of this software +- * must display the following acknowledgement: +- * This product includes software developed by Adam Dunkels. +- * 4. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * icmpv6.h - This file contains macro definitions pertaining to ICMPv6 +- * +- * RFC 2463 : ICMPv6 Specification +- * RFC 2461 : Neighbor Discovery for IPv6 +- * +- */ +-#ifndef __ICMPV6_H__ +-#define __ICMPV6_H__ +- +-/* Base ICMP Header sizes */ +-#define IPV6_RTR_SOL_HDR_SIZE 8 +-#define IPV6_RTR_ADV_HDR_SIZE 16 +-#define IPV6_NEIGH_SOL_HDR_SIZE 24 +-#define IPV6_NEIGH_ADV_HDR_SIZE 24 +-#define IPV6_LINK_LAYER_OPT_SIZE 2 +-#define IPV6_LINK_LAYER_OPT_LENGTH 8 +-#define IPV6_MTU_OPT_SIZE 8 +-#define IPV6_PREFIX_OPT_SIZE 32 +-#define IPV6_ECHO_REQUEST_HDR_SIZE 8 +-#define IPV6_ECHO_REPLY_HDR_SIZE 8 +-#define IPV6_REDIRECT_SIZE 40 +-#define IPV6_DHAAD_REQ_HDR_SIZE 8 +-#define IPV6_DHAAD_REPLY_HDR_SIZE 8 +-#define IPV6_PRFXSOL_HDR_SIZE 8 +-#define IPV6_PRFXADV_HDR_SIZE 8 +-#define IPV6_RTR_ADV_INT_OPT_SIZE 8 +- +-/* ICMP Message Types */ +-/* Error messages are always less than 128 */ +-#define ICMPV6_DST_UNREACH 1 /* Destination Unreachable */ +-#define ICMPV6_PACKET_TOO_BIG 2 /* Packet Too Big */ +-#define ICMPV6_TIME_EXCEEDED 3 /* Time Exceeded */ +-#define ICMPV6_PARAM_PROB 4 /* Parameter Problem */ +- +-#define ICMPV6_RTR_SOL 133 /* Router Solicitation */ +-#define ICMPV6_RTR_ADV 134 /* Router Advertisement */ +-#define ICMPV6_NEIGH_SOL 135 /* Neighbor Solicitation */ +-#define ICMPV6_NEIGH_ADV 136 /* Neighbor Advertisement */ +-#define ICMPV6_REDIRECT 137 /* Redirect */ +-#define ICMPV6_ECHO_REQUEST 128 /* Echo Request */ +-#define ICMPV6_ECHO_REPLY 129 /* Echo Reply */ +-#define ICMPV6_WRUREQUEST 139 /* Who Are You Request */ +-#define ICMPV6_WRUREPLY 140 /* Who Are You Reply */ +-#define ICMPV6_ROUTER_RENUMBERING 138 /* Router Renumbering */ +-#define ICMPV6_HA_ADDR_DISC_REQ 144 /* Dynamic Home Agent Address +- Discovery Request */ +-#define ICMPV6_HA_ADDR_DISC_REPLY 145 /* Dynamic Home Agent Address +- Discovery Reply */ +-#define ICMPV6_MP_SOLICIT 146 /* Mobile Prefix Solicitation */ +-#define ICMPV6_MP_ADV 147 /* Mobile Prefix Reply */ +- +-/* Destination Unreachable Codes */ +-#define ICMPV6_DST_UNREACH_NOROUTE 0 +-#define ICMPV6_DST_UNREACH_ADMIN 1 +-#define ICMPV6_DST_UNREACH_ADDRESS 3 +-#define ICMPV6_DST_UNREACH_PORT 4 +- +-/* Time Exceeded Codes */ +-#define ICMPV6_TIME_EXCD_HPLMT 0 /* Hop Limit exceeded in transit */ +-#define ICMPV6_TIME_EXCD_REASM 1 /* Fragment reassembly time exceeded */ +- +-/* Parameter Problem Codes */ +-#define ICMPV6_PARM_PROB_HEADER 0 +-#define ICMPV6_PARM_PROB_NEXT_HDR 1 +-#define ICMPV6_PARM_PROB_OPTION 2 +- +-/* ICMP Option Types */ +-#define IPV6_ICMP_OPTION_SRC_ADDR 1 /* Source Link-Layer Address */ +-#define IPV6_ICMP_OPTION_TAR_ADDR 2 /* Target Link-Layer Address */ +-#define IPV6_ICMP_OPTION_PREFIX 3 /* Prefix */ +-#define IPV6_ICMP_OPTION_RED_HDR 4 /* Redirect Header */ +-#define IPV6_ICMP_OPTION_MTU 5 /* Link MTU */ +-#define IPV6_ICMP_OPTION_RTR_ADV_INT 7 /* Rtr Advertisement Interval */ +- +-/* ICMP Offsets */ +-#define IPV6_ICMP_TYPE_OFFSET 0 +-#define IPV6_ICMP_CODE_OFFSET 1 +-#define IPV6_ICMP_CKSUM_OFFSET 2 +-#define IPV6_ICMP_RESERVED_OFFSET 4 +-#define IPV6_ICMP_DATA_OFFSET 8 +- +-/* ICMP Router Solicitation Offsets */ +-#define IPV6_ICMP_RTR_SOL_RES_OFFSET 4 +-#define IPV6_ICMP_RTR_SOL_OPTIONS_OFFSET 8 +- +-/* ICMP Router Advertisement Offsets */ +-#define IPV6_ICMP_RTR_ADV_CURHOPLMT_OFFSET 4 +-#define IPV6_ICMP_RTR_ADV_MGDANDCFG_BIT_OFFSET 5 +-#define IPV6_ICMP_RTR_ADV_RTR_LIFETIME_OFFSET 6 +-#define IPV6_ICMP_RTR_ADV_RCHBL_TIME_OFFSET 8 +-#define IPV6_ICMP_RTR_ADV_RTRNS_TMR_OFFSET 12 +-#define IPV6_ICMP_RTR_ADV_OPTIONS_OFFSET 16 +- +-/* ICMP Neighbor Solicitation Offsets */ +-#define IPV6_ICMP_NEIGH_SOL_RES_OFFSET 4 +-#define IPV6_ICMP_NEIGH_SOL_TRGT_ADDRS_OFFSET 8 +-#define IPV6_ICMP_NEIGH_SOL_OPTIONS_OFFSET 24 +- +-/* ICMP Neighbor Advertisement Offsets */ +-#define IPV6_ICMP_NEIGH_ADV_FLAG_OFFSET 4 +-#define IPV6_ICMP_NEIGH_ADV_TRGT_ADDRS_OFFSET 8 +-#define IPV6_ICMP_NEIGH_ADV_OPTIONS_OFFSET 24 +- +-/* ICMP Redirect Offsets */ +-#define IPV6_ICMP_REDIRECT_TRGT_ADDRS_OFFSET 8 +-#define IPV6_ICMP_REDIRECT_DEST_ADDRS_OFFSET 24 +-#define IPV6_ICMP_REDIRECT_OPTIONS_OFFSET 40 +- +-/* ICMP Option Offsets */ +-#define IPV6_ICMP_OPTION_TYPE_OFFSET 0 +-#define IPV6_ICMP_OPTION_LENGTH_OFFSET 1 +- +-/* ICMP Link-Layer Address Option Offsets */ +-#define IPV6_ICMP_LL_OPTION_ADDRESS_OFFSET 2 +- +-/* ICMP Prefix Option Offsets */ +-#define IPV6_ICMP_PREFIX_PRE_LENGTH_OFFSET 2 +-#define IPV6_ICMP_PREFIX_FLAG_OFFSET 3 +-#define IPV6_ICMP_PREFIX_VALID_LIFETIME_OFFSET 4 +-#define IPV6_ICMP_PREFIX_PREF_LIFETIME_OFFSET 8 +-#define IPV6_ICMP_PREFIX_RES2_OFFSET 12 +-#define IPV6_ICMP_PREFIX_PREFIX_OFFSET 16 +- +-/* ICMP Redirected Header Option Offsets */ +-#define IPV6_ICMP_RED_OPTION_TYPE_OFFSET 0 +-#define IPV6_ICMP_RED_OPTION_LEN_OFFSET 1 +-#define IPV6_ICMP_RED_OPTION_RES1_OFFSET 2 +-#define IPV6_ICMP_RED_OPTION_RES2_OFFSET 4 +-#define IPV6_ICMP_RED_OPTION_DATA_OFFSET 8 +- +-/* ICMP MTU Option Offsets */ +-#define IPV6_ICMP_MTU_RESERVED_OFFSET 2 +-#define IPV6_ICMP_MTU_OFFSET 4 +- +-/* ICMP Echo Request Offsets */ +-#define IPV6_ICMP_ECHO_ID 4 +-#define IPV6_ICMP_ECHO_SEQ 6 +-#define IPV6_ICMP_ECHO_DATA 8 +- +-/* ICMP Destination Unreachable Offsets */ +-#define IPV6_DST_UNREACH_UNUSED 4 +-#define IPV6_DST_UNREACH_DATA 8 +- +-/* ICMP Parameter Problem Offsets */ +-#define IPV6_PARAM_PROB_PTR 4 +-#define IPV6_PARAM_PROT_DATA 8 +- +-/* ICMP Time Exceeded Offsets */ +-#define IPV6_TIME_EXCEEDED_DATA 8 +- +-/* ICMP Packet Too Big Offsets */ +-#define IPV6_PKT_TOO_BIG_MTU 4 +-#define IPV6_PKT_TOO_BIG_DATA 8 +- +-/* Home Agent Address Discovery Request Header Offsets */ +-#define ICMPV6_HA_ADDR_DISC_REQ_ID_OFFSET 4 +-#define ICMPV6_HA_ADDR_DISC_REQ_RSVD_OFFSET 6 +- +-/* Home Agent Address Discovery Reply Header Offsets */ +-#define ICMPV6_HA_ADDR_DISC_REPLY_ID_OFFSET 4 +-#define ICMPV6_HA_ADDR_DISC_REPLY_RSVD_OFFSET 6 +-#define ICMPV6_HA_ADDR_DISC_REPLY_HA_ADDR_OFFSET 8 +- +-/* Mobile Prefix Solicitation Header Offsets */ +-#define ICMPV6_MP_SOLICIT_ID_OFFSET 4 +-#define ICMPV6_MP_SOLICIT_RSVD_OFFSET 6 +- +-/* Mobile Prefix Advertisement Header Offsets */ +-#define ICMPV6_MP_ADV_ID_OFFSET 4 +-#define ICMPV6_MP_ADV_MGDANDCFG_BIT_OFFSET 6 +-#define ICMPV6_MP_ADV_OPT_OFFSET 8 +- +-/* Advertisement Interval Option Header Offsets */ +-#define ICMPV6_ADV_INT_TYPE_OFFSET 0 +-#define ICMPV6_ADV_INT_LEN_OFFSET 1 +-#define ICMPV6_ADV_INT_RSVD_OFFSET 2 +-#define ICMPV6_ADV_INT_ADV_INT_OFFSET 4 +- +-#define ICMPV6_HEADER_LEN 4 +- +-#define IPV6_PREFIX_FLAG_ONLINK 0x80 +-#define IPV6_PREFIX_FLAG_AUTO 0x40 +-#define IPV6_PREFIX_FLAG_ROUTER 0x20 +- +-#define IPV6_NA_FLAG_ROUTER 0x80 +-#define IPV6_NA_FLAG_SOLICITED 0x40 +-#define IPV6_NA_FLAG_OVERRIDE 0x20 +- +-/* Router Advertisement Flags */ +-#define IPV6_RA_MANAGED_FLAG 0x80 +-#define IPV6_RA_CONFIG_FLAG 0x40 +- +-/* Mobile Prefix Advertisement Flags */ +-#define IPV6_PA_MANAGED_FLAG 0x80 +-#define IPV6_PA_CONFIG_FLAG 0x40 +- +-/* Validation Values */ +-#define ICMPV6_VALID_HOP_LIMIT 255 /* Valid Hop Limit */ +-#define ICMPV6_VALID_CODE 0 /* Valid Code */ +-#define ICMPV6_RTRSOL_MIN_LENGTH 8 /* Minimum valid length for +- Router Solicitation */ +-#define ICMPV6_RTRADV_MIN_LENGTH 16 /* Minimum valid length for +- Router Advertisement */ +-#define ICMPV6_NEIGHSOL_MIN_LENGTH 24 /* Minimum valid length for +- Neighbor Solicitation */ +-#define ICMPV6_NEIGHADV_MIN_LENGTH 24 /* Minimum valid length for +- Neighbor Advertisement */ +-#define ICMPV6_REDIRECT_MIN_LENGTH 40 /* Minimum valid length for +- Neighbor Advertisement */ +- +-/* ICMPV6 Header */ +-struct icmpv6_hdr { +- u8_t icmpv6_type; /* type field */ +- u8_t icmpv6_code; /* code field */ +- u16_t icmpv6_cksum; /* checksum field */ +- union { +- u32_t icmpv6_un_data32[1]; /* type-specific field */ +- u16_t icmpv6_un_data16[2]; /* type-specific field */ +- u8_t icmpv6_un_data8[4]; /* type-specific field */ +- } data; +-}; +- +-#define icmpv6_data data.icmpv6_un_data32[0] +- +-struct icmpv6_opt_hdr { +- u8_t type; +- u8_t len; +-}; +- +-struct icmpv6_opt_link_addr { +- struct icmpv6_opt_hdr hdr; +- u8_t link_addr[6]; +-}; +- +-struct icmpv6_opt_prefix { +- struct icmpv6_opt_hdr hdr; +- u8_t prefix_len; +- u8_t flags; +-#define ICMPV6_OPT_PREFIX_FLAG_ON_LINK (1 << 7) +-#define ICMPV6_OPT_PREFIX_FLAG_BIT_A (1 << 6) +- u32_t valid_lifetime; +- u32_t preferred_lifetime; +- u32_t reserved; +- struct ipv6_addr prefix; +-}; +- +-/* Neighbor Solicitation */ +-struct icmpv6_nd_solicit { +- struct icmpv6_hdr nd_ns_hdr; +-}; +- +-/* Router Advertisement */ +-struct icmpv6_router_advert { +- struct icmpv6_hdr header; +- u32_t reachable_time; +- u32_t retransmit_timer; +-}; +- +-#define nd_ra_type header.icmpv6_type +-#define nd_ra_code header.icmpv6_code +-#define nd_ra_cksum header.icmpv6_cksum +-#define nd_ra_curhoplimit header.data.icmpv6_un_data8[0] +-#define nd_ra_flags_reserved header.data.icmpv6_un_data8[1] +-#define nd_ra_router_lifetime header.data.icmpv6_un_data16[1] +- +-#endif /* __ICMPV6_H__ */ +diff --git a/iscsiuio/src/uip/ipv6.c b/iscsiuio/src/uip/ipv6.c +deleted file mode 100644 +index 11cb4e9..0000000 +--- a/iscsiuio/src/uip/ipv6.c ++++ /dev/null +@@ -1,1306 +0,0 @@ +-/* +- * Copyright (c) 2011, Broadcom Corporation +- * Copyright (c) 2014, QLogic Corporation +- * +- * Written by: Eddie Wai (eddie.wai@broadcom.com) +- * Based on Kevin Tran's iSCSI boot code +- * +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. All advertising materials mentioning features or use of this software +- * must display the following acknowledgement: +- * This product includes software developed by Adam Dunkels. +- * 4. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * ipv6.c - This file contains simplifed IPv6 processing code. +- * +- */ +-#include +-#include +-#include +-#include "logger.h" +-#include "uip.h" +-#include "ipv6.h" +-#include "ipv6_pkt.h" +-#include "icmpv6.h" +-#include "uipopt.h" +-#include "dhcpv6.h" +-#include "ping.h" +- +-static inline int best_match_bufcmp(u8_t *a, u8_t *b, int len) +-{ +- int i; +- +- for (i = 0; i < len; i++) { +- if (a[i] != b[i]) +- break; +- } +- return i; +-} +- +-/* Local function prototypes */ +-static int ipv6_is_it_our_address(struct ipv6_context *context, +- struct ipv6_addr *ip_addr); +-static void ipv6_insert_protocol_chksum(struct ipv6_hdr *ipv6); +-static void ipv6_update_arp_table(struct ipv6_context *context, +- struct ipv6_addr *ip_addr, +- struct mac_address *mac_addr); +-static void ipv6_icmp_init_link_option(struct ipv6_context *context, +- struct icmpv6_opt_link_addr *link_opt, +- u8_t type); +-static void ipv6_icmp_rx(struct ipv6_context *context); +-static void ipv6_icmp_handle_nd_adv(struct ipv6_context *context); +-static void ipv6_icmp_handle_nd_sol(struct ipv6_context *context); +-static void ipv6_icmp_handle_echo_request(struct ipv6_context *context); +-static void ipv6_icmp_handle_router_adv(struct ipv6_context *context); +-static void ipv6_icmp_process_prefix(struct ipv6_context *context, +- struct icmpv6_opt_prefix *icmp_prefix); +-static void ipv6_udp_rx(struct ipv6_context *context); +- +-int iscsiL2Send(struct ipv6_context *context, int pkt_len) +-{ +- LOG_DEBUG("IPv6: iscsiL2Send"); +- uip_send(context->ustack, +- (void *)context->ustack->data_link_layer, pkt_len); +- +- return pkt_len; +-} +- +-int iscsiL2AddMcAddr(struct ipv6_context *context, +- struct mac_address *new_mc_addr) +-{ +- int i; +- struct mac_address *mc_addr; +- const struct mac_address all_zeroes_mc = { { { 0, 0, 0, 0, 0, 0 } } }; +- +- mc_addr = context->mc_addr; +- for (i = 0; i < MAX_MCADDR_TABLE; i++, mc_addr++) +- if (!memcmp((char *)mc_addr, +- (char *)new_mc_addr, sizeof(struct mac_address))) +- return TRUE; /* Already in the mc table */ +- +- mc_addr = context->mc_addr; +- for (i = 0; i < MAX_MCADDR_TABLE; i++, mc_addr++) { +- if (!memcmp((char *)mc_addr, +- (char *)&all_zeroes_mc, sizeof(struct mac_address))) { +- memcpy((char *)mc_addr, +- (char *)new_mc_addr, sizeof(struct mac_address)); +- 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), +- *((u8_t *)new_mc_addr + 3), +- *((u8_t *)new_mc_addr + 4), +- *((u8_t *)new_mc_addr + 5)); +- return TRUE; +- } +- } +- return FALSE; +-} +- +-int iscsiL2IsOurMcAddr(struct ipv6_context *context, +- struct mac_address *dest_mac) +-{ +- int i; +- struct mac_address *mc_addr; +- +- mc_addr = context->mc_addr; +- for (i = 0; i < MAX_MCADDR_TABLE; i++, mc_addr++) +- if (!memcmp((char *)mc_addr, +- (char *)dest_mac->addr, sizeof(struct mac_address))) +- return TRUE; +- return FALSE; +-} +- +-void ipv6_init(struct ndpc_state *ndp, int cfg) +-{ +- int i; +- struct ipv6_context *context = (struct ipv6_context *)ndp->ipv6_context; +- struct mac_address *mac_addr = (struct mac_address *)ndp->mac_addr; +- struct ipv6_arp_entry *ipv6_arp_table; +- struct ipv6_prefix_entry *ipv6_prefix_table; +- struct mac_address mc_addr; +- +- if (context == NULL) { +- LOG_ERR("IPV6: INIT ipv6_context is NULL"); +- return; +- } +- +- memset((char *)context, 0, sizeof(struct ipv6_context)); +- +- /* Associate the nic_iface's ustack to this ipv6_context */ +- context->ustack = ndp->ustack; +- +- ipv6_arp_table = &context->ipv6_arp_table[0]; +- ipv6_prefix_table = &context->ipv6_prefix_table[0]; +- +- memset((char *)ipv6_arp_table, 0, sizeof(*ipv6_arp_table)); +- memset((char *)ipv6_prefix_table, 0, sizeof(*ipv6_prefix_table)); +- memcpy((char *)&context->mac_addr, +- (char *)mac_addr, sizeof(struct mac_address)); +- /* +- * Per RFC 2373. +- * There are two types of local-use unicast addresses defined. These +- * are Link-Local and Site-Local. The Link-Local is for use on a single +- * link and the Site-Local is for use in a single site. Link-Local +- * addresses have the following format: +- * +- * | 10 | +- * | bits | 54 bits | 64 bits | +- * +----------+-------------------------+----------------------------+ +- * |1111111010| 0 | interface ID | +- * +----------+-------------------------+----------------------------+ +- */ +- if (context->ustack->linklocal_autocfg != IPV6_LL_AUTOCFG_OFF) { +- context->link_local_addr.addr8[0] = 0xfe; +- context->link_local_addr.addr8[1] = 0x80; +- /* Bit 1 is 1 to indicate universal scope. */ +- context->link_local_addr.addr8[8] = mac_addr->addr[0] | 0x2; +- context->link_local_addr.addr8[9] = mac_addr->addr[1]; +- context->link_local_addr.addr8[10] = mac_addr->addr[2]; +- context->link_local_addr.addr8[11] = 0xff; +- context->link_local_addr.addr8[12] = 0xfe; +- context->link_local_addr.addr8[13] = mac_addr->addr[3]; +- context->link_local_addr.addr8[14] = mac_addr->addr[4]; +- context->link_local_addr.addr8[15] = mac_addr->addr[5]; +- +- context->link_local_multi.addr8[0] = 0xff; +- context->link_local_multi.addr8[1] = 0x02; +- context->link_local_multi.addr8[11] = 0x01; +- context->link_local_multi.addr8[12] = 0xff; +- context->link_local_multi.addr8[13] |= +- context->link_local_addr.addr8[13]; +- context->link_local_multi.addr16[7] = +- 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(context, +- &context->link_local_addr, 64); +- } +- /* +- * Convert Multicast IP address to Multicast MAC adress per +- * RFC 2464: Transmission of IPv6 Packets over Ethernet Networks +- * +- * An IPv6 packet with a multicast destination address DST, consisting +- * of the sixteen octets DST[1] through DST[16], is transmitted to the +- * Ethernet multicast address whose first two octets are the value 3333 +- * hexadecimal and whose last four octets are the last four octets of +- * DST. +- * +- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- * |0 0 1 1 0 0 1 1|0 0 1 1 0 0 1 1| +- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- * | DST[13] | DST[14] | +- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- * | DST[15] | DST[16] | +- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- * +- * IPv6 requires the following Multicast IP addresses setup per node. +- */ +- for (i = 0; i < 3; i++) { +- mc_addr.addr[0] = 0x33; +- mc_addr.addr[1] = 0x33; +- mc_addr.addr[2] = 0x0; +- mc_addr.addr[3] = 0x0; +- mc_addr.addr[4] = 0x0; +- +- switch (i) { +- case 0: +- /* All Nodes Multicast IPv6 address : ff02::1 */ +- mc_addr.addr[5] = 0x1; +- break; +- +- case 1: +- /* All Host Multicast IPv6 address : ff02::3 */ +- mc_addr.addr[5] = 0x3; +- break; +- +- case 2: +- /* Solicited Node Multicast Address: ff02::01:ffxx:yyzz +- */ +- mc_addr.addr[2] = 0xff; +- mc_addr.addr[3] = mac_addr->addr[3]; +- mc_addr.addr[4] = mac_addr->addr[4]; +- mc_addr.addr[5] = mac_addr->addr[5]; +- break; +- +- default: +- break; +- } +- iscsiL2AddMcAddr(context, &mc_addr); +- } +- +- /* Default HOP number */ +- context->hop_limit = IPV6_HOP_LIMIT; +-} +- +-int ipv6_add_prefix_entry(struct ipv6_context *context, +- struct ipv6_addr *ip_addr, u8_t prefix_len) +-{ +- int i; +- struct ipv6_prefix_entry *prefix_entry; +- struct ipv6_prefix_entry *ipv6_prefix_table = +- 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++) { +- prefix_entry = &ipv6_prefix_table[i]; +- +- if (prefix_entry->prefix_len != 0) { +- if (memcmp((char *)&prefix_entry->ip_addr, +- (char *)ip_addr, +- sizeof(struct ipv6_addr)) == 0) { +- /* We already initialize on this interface. +- There is nothing to do */ +- return 0; +- } +- } +- } +- +- /* Find an unused entry */ +- for (i = 0; i < IPV6_NUM_OF_ADDRESS_ENTRY; i++) { +- prefix_entry = &ipv6_prefix_table[i]; +- +- if (prefix_entry->prefix_len == 0) +- break; +- } +- +- if (prefix_entry->prefix_len != 0) +- return -1; +- +- prefix_entry->prefix_len = prefix_len / 8; +- +- memcpy((char *)&prefix_entry->ip_addr, +- (char *)ip_addr, sizeof(struct ipv6_addr)); +- +- inet_ntop(AF_INET6, &prefix_entry->ip_addr.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 (context->addr_list != NULL) +- prefix_entry->next = context->addr_list; +- else +- prefix_entry->next = NULL; +- +- context->addr_list = prefix_entry; +- +- return 0; +-} +- +-void ipv6_rx_packet(struct ipv6_context *context, u16_t len) +-{ +- struct ipv6_hdr *ipv6; +- u16_t protocol; +- +- if (!context->ustack) { +- LOG_WARN("ipv6 rx pkt ipv6_context = %p ustack = %p", context, +- context->ustack); +- return; +- } +- ipv6 = (struct ipv6_hdr *)context->ustack->network_layer; +- /* Make sure it's an IPv6 packet */ +- if ((ipv6->ipv6_version_fc & 0xf0) != IPV6_VERSION) { +- /* It's not an IPv6 packet. Drop it. */ +- LOG_WARN("IPv6 version 0x%x not IPv6", ipv6->ipv6_version_fc); +- return; +- } +- protocol = ipv6_process_rx(ipv6); +- +- switch (protocol) { +- case IPPROTO_ICMPV6: +- ipv6_icmp_rx(context); +- break; +- +- case IPPROTO_UDP: +- /* Indicate to UDP processing code */ +- ipv6_udp_rx(context); +- break; +- +- default: +- break; +- } +-} +- +-void ipv6_mc_init_dest_mac(struct eth_hdr *eth, struct ipv6_hdr *ipv6) +-{ +- int i; +- /* +- * Initialize address mapping of IPV6 Multicast to multicast MAC +- * address per RFC 2464. +- * +- * An IPv6 packet with a multicast destination address DST, consisting +- * of the sixteen octets DST[1] through DST[16], is transmitted to the +- * Ethernet multicast address whose first two octets are the value 3333 +- * hexadecimal and whose last four octets are the last four octets of +- * DST. +- * +- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- * |0 0 1 1 0 0 1 1|0 0 1 1 0 0 1 1| +- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- * | DST[13] | DST[14] | +- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- * | DST[15] | DST[16] | +- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- */ +- eth->dest_mac.addr[0] = 0x33; +- eth->dest_mac.addr[1] = 0x33; +- for (i = 0; i < 4; i++) +- eth->dest_mac.addr[2 + i] = ipv6->ipv6_dst.addr8[12 + i]; +-} +- +-int ipv6_autoconfig(struct ipv6_context *context) +-{ +- return ipv6_discover_address(context); +-} +- +-int ipv6_discover_address(struct ipv6_context *context) +-{ +- struct eth_hdr *eth = +- (struct eth_hdr *)context->ustack->data_link_layer; +- struct ipv6_hdr *ipv6 = +- (struct ipv6_hdr *)context->ustack->network_layer; +- struct icmpv6_hdr *icmp = (struct icmpv6_hdr *)((u8_t *)ipv6 + +- sizeof(struct ipv6_hdr)); +- int rc = 0; +- +- /* Retrieve tx buffer */ +- if (eth == NULL || ipv6 == NULL) +- return -EAGAIN; +- +- /* Setup IPv6 All Routers Multicast address : ff02::2 */ +- memset((char *)&ipv6->ipv6_dst, 0, sizeof(struct ipv6_addr)); +- ipv6->ipv6_dst.addr8[0] = 0xff; +- ipv6->ipv6_dst.addr8[1] = 0x02; +- ipv6->ipv6_dst.addr8[15] = 0x02; +- ipv6->ipv6_hop_limit = 255; +- +- /* Initialize MAC header based on destination MAC address */ +- ipv6_mc_init_dest_mac(eth, ipv6); +- ipv6->ipv6_nxt_hdr = IPPROTO_ICMPV6; +- +- icmp->icmpv6_type = ICMPV6_RTR_SOL; +- icmp->icmpv6_code = 0; +- icmp->icmpv6_data = 0; +- icmp->icmpv6_cksum = 0; +- ipv6_icmp_init_link_option(context, +- (struct icmpv6_opt_link_addr *)((u8_t *)icmp +- + sizeof(struct icmpv6_hdr)), +- IPV6_ICMP_OPTION_SRC_ADDR); +- ipv6->ipv6_plen = HOST_TO_NET16((sizeof(struct icmpv6_hdr) + +- sizeof(struct icmpv6_opt_link_addr))); +- memcpy((char *)&ipv6->ipv6_src, +- (char *)&context->link_local_addr, +- sizeof(struct ipv6_addr)); +- +- icmp->icmpv6_cksum = 0; +- LOG_DEBUG("IPv6: Send rtr sol"); +- ipv6_send(context, (u8_t *) icmp - (u8_t *) eth + +- sizeof(struct icmpv6_hdr) + +- sizeof(struct icmpv6_opt_link_addr)); +- return rc; +-} +- +-u16_t ipv6_process_rx(struct ipv6_hdr *ipv6) +-{ +- return ipv6->ipv6_nxt_hdr; +-} +- +-int ipv6_send(struct ipv6_context *context, u16_t packet_len) +-{ +- struct eth_hdr *eth = +- (struct eth_hdr *)context->ustack->data_link_layer; +- struct ipv6_hdr *ipv6 = +- (struct ipv6_hdr *)context->ustack->network_layer; +- +- ipv6_setup_hdrs(context, eth, ipv6, packet_len); +- +- return iscsiL2Send(context, packet_len); +-} +- +-void ipv6_send_udp_packet(struct ipv6_context *context, u16_t packet_len) +-{ +- struct eth_hdr *eth = +- (struct eth_hdr *)context->ustack->data_link_layer; +- struct ipv6_hdr *ipv6 = +- (struct ipv6_hdr *)context->ustack->network_layer; +- struct udp_hdr *udp = (struct udp_hdr *)((u8_t *)ipv6 + +- sizeof(struct ipv6_hdr)); +- +- ipv6->ipv6_nxt_hdr = IPPROTO_UDP; +- ipv6->ipv6_plen = +- HOST_TO_NET16(packet_len - ((u8_t *)udp - (u8_t *)eth)); +- +- udp->chksum = 0; +- +- /* +- * We only use UDP packet for DHCPv6. The source address is always +- * link-local address. +- */ +- ipv6->ipv6_src.addr[0] = 0; +- +- /* Hop limit is always 1 for DHCPv6 packet. */ +- ipv6->ipv6_hop_limit = 1; +- +- ipv6_send(context, packet_len); +-} +- +-void ipv6_setup_hdrs(struct ipv6_context *context, struct eth_hdr *eth, +- struct ipv6_hdr *ipv6, u16_t packet_len) +-{ +- struct ipv6_addr *our_address; +- +- /* VLAN will be taken cared of in the nic layer */ +- eth->len_type = HOST_TO_NET16(LAYER2_TYPE_IPV6); +- memcpy((char *)ð->src_mac, +- (char *)&context->mac_addr, sizeof(struct mac_address)); +- +- /* Put the traffic class into the packet. */ +- memset(&ipv6->ipv6_version_fc, 0, sizeof(u32_t)); +- ipv6->ipv6_version_fc = IPV6_VERSION; +- if (ipv6->ipv6_hop_limit == 0) +- ipv6->ipv6_hop_limit = context->hop_limit; +- +- if (ipv6->ipv6_src.addr[0] == 0) { +- /* Need to initialize source IP address. */ +- our_address = ipv6_our_address(context); +- if (our_address != NULL) { +- /* Assume that caller has filled in the destination +- IP address */ +- memcpy((char *)&ipv6->ipv6_src, +- (char *)our_address, sizeof(struct ipv6_addr)); +- } +- } +- +- ipv6_insert_protocol_chksum(ipv6); +-} +- +-static void ipv6_insert_protocol_chksum(struct ipv6_hdr *ipv6) +-{ +- u32_t sum; +- u16_t *ptr; +- u16_t *protocol_data_ptr; +- int i; +- u16_t protocol_data_len; +- u16_t checksum; +- +- /* +- * This routine assumes that there is no extension header. This driver +- * doesn't user extension header to keep driver small and simple. +- * +- * Pseudo check consists of the following: +- * SRC IP, DST IP, Protocol Data Length, and Next Header. +- */ +- sum = 0; +- ptr = (u16_t *)&ipv6->ipv6_src.addr16[0]; +- +- for (i = 0; i < sizeof(struct ipv6_addr); i++) { +- sum += HOST_TO_NET16(*ptr); +- ptr++; +- } +- +- /* Keep track where the layer header is */ +- protocol_data_ptr = ptr; +- +- protocol_data_len = HOST_TO_NET16(ipv6->ipv6_plen); +- sum += protocol_data_len; +- sum += ipv6->ipv6_nxt_hdr; +- /* Sum now contains sum of IPv6 pseudo header. Let's add the data +- streams. */ +- if (protocol_data_len & 1) { +- /* Length of data is odd */ +- *((u8_t *) ptr + protocol_data_len) = 0; +- protocol_data_len++; +- } +- +- for (i = 0; i < protocol_data_len / 2; i++) { +- sum += HOST_TO_NET16(*ptr); +- ptr++; +- } +- +- sum = (sum >> 16) + (sum & 0xffff); +- sum += (sum >> 16); +- sum &= 0xffff; +- checksum = (u16_t) (~sum); +- checksum = HOST_TO_NET16(checksum); +- +- switch (ipv6->ipv6_nxt_hdr) { +- case IPPROTO_ICMPV6: +- /* Insert correct ICMPv6 checksum */ +- ((struct icmpv6_hdr *)(protocol_data_ptr))->icmpv6_cksum = +- checksum; +- break; +- case IPPROTO_UDP: +- /* Insert correct UDP checksum */ +- ((struct udp_hdr *)protocol_data_ptr)->chksum = checksum; +- break; +- default: +- break; +- } +-} +- +-int ipv6_is_it_our_link_local_address(struct ipv6_context *context, +- struct ipv6_addr *ip_addr) +-{ +- u8_t *test_addr = (u8_t *) ip_addr->addr8; +- u8_t test_remainder; +- +- if (test_addr[0] != context->link_local_addr.addr8[0]) +- return FALSE; +- +- test_remainder = (test_addr[1] & 0xC0) >> 6; +- if (test_remainder != 2) +- return FALSE; +- +- return TRUE; +-} +- +-static int ipv6_is_it_our_address(struct ipv6_context *context, +- struct ipv6_addr *ipv6_addr) +-{ +- struct ipv6_prefix_entry *ipv6_prefix; +- +- for (ipv6_prefix = context->addr_list; ipv6_prefix != NULL; +- ipv6_prefix = ipv6_prefix->next) { +- if (IPV6_ARE_ADDR_EQUAL(&ipv6_prefix->ip_addr, ipv6_addr)) +- return TRUE; +- } +- +- return FALSE; +-} +- +-struct ipv6_addr *ipv6_our_address(struct ipv6_context *context) +-{ +- return &context->link_local_addr; +-} +- +-int ipv6_ip_in_arp_table(struct ipv6_context *context, +- struct ipv6_addr *ip_addr, +- struct mac_address *mac_addr) +-{ +- struct ipv6_arp_entry *arp_entry; +- int i; +- +- for (i = 0; i < UIP_ARPTAB_SIZE; i++) { +- arp_entry = &context->ipv6_arp_table[i]; +- +- if (IPV6_ARE_ADDR_EQUAL(&arp_entry->ip_addr, ip_addr)) { +- memcpy((char *)mac_addr, &arp_entry->mac_addr, +- sizeof(struct mac_address)); +- return 1; +- } +- } +- return 0; +-} +- +-struct ipv6_addr *ipv6_find_longest_match(struct ipv6_context *context, +- struct ipv6_addr *ip_addr) +-{ +- struct ipv6_prefix_entry *ipv6_prefix; +- struct ipv6_prefix_entry *best_match = NULL; +- int longest_len = -1; +- int len; +- +- for (ipv6_prefix = context->addr_list; ipv6_prefix != NULL; +- ipv6_prefix = ipv6_prefix->next) { +- if (!IPV6_IS_ADDR_LINKLOCAL(&ipv6_prefix->ip_addr)) { +- len = best_match_bufcmp((u8_t *)&ipv6_prefix->ip_addr, +- (u8_t *)ip_addr, +- sizeof(struct ipv6_addr)); +- if (len > longest_len) { +- best_match = ipv6_prefix; +- longest_len = len; +- } +- } +- } +- +- if (best_match) +- return &best_match->ip_addr; +- +- return NULL; +-} +- +-void ipv6_arp_out(struct ipv6_context *context, int *uip_len) +-{ +- /* Empty routine */ +-} +- +- +-static void ipv6_update_arp_table(struct ipv6_context *context, +- struct ipv6_addr *ip_addr, +- struct mac_address *mac_addr) +-{ +- struct ipv6_arp_entry *arp_entry; +- int i; +- struct ipv6_arp_entry *ipv6_arp_table = context->ipv6_arp_table; +- +- 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 +- * inserted in the ARP table. +- */ +- for (i = 0; i < UIP_ARPTAB_SIZE; i++) { +- arp_entry = &ipv6_arp_table[i]; +- +- /* Only check those entries that are actually in use. */ +- if (arp_entry->ip_addr.addr[0] != 0) { +- /* +- * Check if the source IP address of the incoming +- * packet matches the IP address in this ARP table +- * entry. +- */ +- if (IPV6_ARE_ADDR_EQUAL(&arp_entry->ip_addr, ip_addr)) { +- /* An old entry found, update this and return */ +- memcpy((char *)&arp_entry->mac_addr, +- (char *)mac_addr, +- sizeof(struct mac_address)); +- arp_entry->time = context->arptime; +- return; +- } +- } +- } +- +- /* +- * If we get here, no existing ARP table entry was found, so we +- * create one. +- * +- * First, we try to find an unused entry in the ARP table. +- */ +- for (i = 0; i < UIP_ARPTAB_SIZE; i++) { +- arp_entry = &ipv6_arp_table[i]; +- +- if (arp_entry->ip_addr.addr[0] == 0) +- break; +- } +- +- if (i == UIP_ARPTAB_SIZE) +- return; +- +- /* Index j is the entry that is least used */ +- arp_entry = &ipv6_arp_table[i]; +- memcpy((char *)&arp_entry->ip_addr, (char *)ip_addr, +- sizeof(struct ipv6_addr)); +- memcpy((char *)&arp_entry->mac_addr, +- (char *)mac_addr, sizeof(struct mac_address)); +- +- arp_entry->time = context->arptime; +-} +- +-/* DestIP is intact */ +-int ipv6_send_nd_solicited_packet(struct ipv6_context *context, +- struct eth_hdr *eth, struct ipv6_hdr *ipv6) +-{ +- struct icmpv6_hdr *icmp; +- int pkt_len = 0; +- struct ipv6_addr *longest_match_addr; +- char addr_str[INET6_ADDRSTRLEN]; +- +- ipv6->ipv6_nxt_hdr = IPPROTO_ICMPV6; +- +- /* Depending on the IPv6 address of the target, we'll need to determine +- whether we use the assigned IPv6 address/RA or the link local address +- */ +- /* Use Link-local as source address */ +- if (ipv6_is_it_our_link_local_address(context, &ipv6->ipv6_dst) == +- TRUE) { +- LOG_DEBUG("IPv6: NS using link local"); +- memcpy((char *)&ipv6->ipv6_src, +- (char *)&context->link_local_addr, +- sizeof(struct ipv6_addr)); +- } else { +- longest_match_addr = +- ipv6_find_longest_match(context, &ipv6->ipv6_dst); +- if (longest_match_addr) { +- LOG_DEBUG("IPv6: NS using longest match addr"); +- memcpy((char *)&ipv6->ipv6_src, +- (char *)longest_match_addr, +- sizeof(struct ipv6_addr)); +- } else { +- LOG_DEBUG("IPv6: NS using link local instead"); +- memcpy((char *)&ipv6->ipv6_src, +- (char *)&context->link_local_addr, +- sizeof(struct ipv6_addr)); +- } +- } +- icmp = (struct icmpv6_hdr *)((u8_t *)ipv6 + sizeof(struct ipv6_hdr)); +- +- 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. +- */ +- memcpy((char *)((u8_t *)icmp + sizeof(struct icmpv6_hdr)), +- (char *)&ipv6->ipv6_dst, sizeof(struct ipv6_addr)); +- +- /* +- * Destination IP in the IPv6 header contains solicited-node multicast +- * address corresponding to the target address. +- * +- * ff02::01:ffxx:yyzz. Where xyz are least +- * significant of 24-bit MAC address. +- */ +- memset((char *)&ipv6->ipv6_dst, 0, sizeof(struct ipv6_addr) - 3); +- ipv6->ipv6_dst.addr8[0] = 0xff; +- ipv6->ipv6_dst.addr8[1] = 0x02; +- ipv6->ipv6_dst.addr8[11] = 0x01; +- ipv6->ipv6_dst.addr8[12] = 0xff; +- ipv6_mc_init_dest_mac(eth, ipv6); +- ipv6->ipv6_hop_limit = 255; +- +- icmp->icmpv6_type = ICMPV6_NEIGH_SOL; +- icmp->icmpv6_code = 0; +- icmp->icmpv6_data = 0; +- icmp->icmpv6_cksum = 0; +- ipv6_icmp_init_link_option(context, +- (struct icmpv6_opt_link_addr *)((u8_t *)icmp +- + sizeof(struct icmpv6_hdr) +- + sizeof(struct ipv6_addr)), +- IPV6_ICMP_OPTION_SRC_ADDR); +- ipv6->ipv6_plen = HOST_TO_NET16((sizeof(struct icmpv6_hdr) + +- sizeof(struct icmpv6_opt_link_addr) + +- sizeof(struct ipv6_addr))); +- /* Total packet size */ +- pkt_len = (u8_t *) icmp - (u8_t *) eth + +- sizeof(struct icmpv6_hdr) + +- sizeof(struct icmpv6_opt_link_addr) + sizeof(struct ipv6_addr); +- ipv6_setup_hdrs(context, eth, ipv6, pkt_len); +- return pkt_len; +-} +- +-static void ipv6_icmp_init_link_option(struct ipv6_context *context, +- struct icmpv6_opt_link_addr *link_opt, +- u8_t type) +-{ +- link_opt->hdr.type = type; +- link_opt->hdr.len = sizeof(struct icmpv6_opt_link_addr) / 8; +- memcpy((char *)&link_opt->link_addr, +- (char *)&context->mac_addr, sizeof(struct mac_address)); +-} +- +-static void ipv6_icmp_rx(struct ipv6_context *context) +-{ +- struct ipv6_hdr *ipv6 = +- (struct ipv6_hdr *)context->ustack->network_layer; +- struct icmpv6_hdr *icmp = (struct icmpv6_hdr *)((u8_t *)ipv6 + +- sizeof(struct ipv6_hdr)); +- uip_icmp_echo_hdr_t *icmp_echo_hdr = +- (uip_icmp_echo_hdr_t *)((u8_t *)ipv6 + +- sizeof(struct ipv6_hdr)); +- +- switch (icmp->icmpv6_type) { +- case ICMPV6_RTR_ADV: +- ipv6_icmp_handle_router_adv(context); +- break; +- +- case ICMPV6_NEIGH_SOL: +- ipv6_icmp_handle_nd_sol(context); +- break; +- +- case ICMPV6_NEIGH_ADV: +- ipv6_icmp_handle_nd_adv(context); +- break; +- +- case ICMPV6_ECHO_REQUEST: +- /* Response with ICMP reply */ +- ipv6_icmp_handle_echo_request(context); +- break; +- +- case ICMPV6_ECHO_REPLY: +- /* Handle ICMP reply */ +- process_icmp_packet(icmp_echo_hdr, context->ustack); +- break; +- +- default: +- break; +- } +-} +- +-static void ipv6_icmp_handle_router_adv(struct ipv6_context *context) +-{ +- struct ipv6_hdr *ipv6 = +- (struct ipv6_hdr *)context->ustack->network_layer; +- struct icmpv6_router_advert *icmp = +- (struct icmpv6_router_advert *)((u8_t *)ipv6 + sizeof(struct ipv6_hdr)); +- struct icmpv6_opt_hdr *icmp_opt; +- u16_t opt_len; +- u16_t len; +- char addr_str[INET6_ADDRSTRLEN]; +- +- if (context->flags & IPV6_FLAGS_ROUTER_ADV_RECEIVED) +- return; +- +- opt_len = HOST_TO_NET16(ipv6->ipv6_plen) - +- sizeof(struct icmpv6_router_advert); +- +- icmp_opt = (struct icmpv6_opt_hdr *)((u8_t *)icmp + +- sizeof(struct icmpv6_router_advert)); +- len = 0; +- while (len < opt_len) { +- icmp_opt = (struct icmpv6_opt_hdr *)((u8_t *)icmp + +- sizeof(struct icmpv6_router_advert) + +- len); +- +- switch (icmp_opt->type) { +- case IPV6_ICMP_OPTION_PREFIX: +- ipv6_icmp_process_prefix(context, +- (struct icmpv6_opt_prefix *)icmp_opt); +- context->flags |= IPV6_FLAGS_ROUTER_ADV_RECEIVED; +- break; +- +- default: +- break; +- } +- +- len += icmp_opt->len * 8; +- } +- +- if (context->flags & IPV6_FLAGS_ROUTER_ADV_RECEIVED) { +- LOG_DEBUG("IPv6: RTR ADV nd_ra_flags = 0x%x", +- icmp->nd_ra_flags_reserved); +- if (icmp->nd_ra_curhoplimit > 0) +- context->hop_limit = icmp->nd_ra_curhoplimit; +- +- if (icmp->nd_ra_flags_reserved & IPV6_RA_MANAGED_FLAG) +- context->flags |= IPV6_FLAGS_MANAGED_ADDR_CONFIG; +- +- if (icmp->nd_ra_flags_reserved & IPV6_RA_CONFIG_FLAG) +- context->flags |= IPV6_FLAGS_OTHER_STATEFUL_CONFIG; +- +- if (icmp->nd_ra_router_lifetime != 0) { +- /* There is a default router. */ +- if (context->ustack->router_autocfg != +- IPV6_RTR_AUTOCFG_OFF) +- memcpy( +- (char *)&context->default_router, +- (char *)&ipv6->ipv6_src, +- sizeof(struct ipv6_addr)); +- inet_ntop(AF_INET6, &context->default_router, +- addr_str, sizeof(addr_str)); +- LOG_DEBUG("IPv6: Got default router IP addr: %s", +- addr_str); +- } +- } +-} +- +-static void ipv6_icmp_process_prefix(struct ipv6_context *context, +- struct icmpv6_opt_prefix *icmp_prefix) +-{ +- struct 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)) +- return; +- +- /* +- * We only process prefix length of 64 since our Identifier is 64-bit +- */ +- if (icmp_prefix->prefix_len == 64) { +- /* Copy 64-bit from the local-link address to create +- IPv6 address */ +- memcpy((char *)&addr, +- (char *)&icmp_prefix->prefix, 8); +- memcpy((char *)&addr.addr8[8], +- &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(context, &addr, 64); +- } +-} +- +-static void ipv6_icmp_handle_nd_adv(struct ipv6_context *context) +-{ +- struct eth_hdr *eth = +- (struct eth_hdr *)context->ustack->data_link_layer; +- struct ipv6_hdr *ipv6 = +- (struct ipv6_hdr *)context->ustack->network_layer; +- struct icmpv6_hdr *icmp = (struct icmpv6_hdr *)((u8_t *)ipv6 + +- sizeof(struct ipv6_hdr)); +- struct icmpv6_opt_link_addr *link_opt = +- (struct icmpv6_opt_link_addr *)((u8_t *)icmp + +- sizeof(struct icmpv6_hdr) + sizeof(struct ipv6_addr)); +- struct ipv6_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"); +- if ((ipv6_is_it_our_address(context, &ipv6->ipv6_dst) == TRUE) || +- (memcmp((char *)&context->link_local_multi, +- (char *)&ipv6->ipv6_dst, sizeof(struct ipv6_addr)) == 0) || +- (memcmp((char *)&context->multi, +- (char *)&ipv6->ipv6_dst, sizeof(struct ipv6_addr)) == 0)) { +- /* +- * This is an ARP reply for our addresses. Let's update the +- * ARP table. +- */ +- ipv6_update_arp_table(context, &ipv6->ipv6_src, +- ð->src_mac); +- +- /* Now check for the target address option and update that as +- well */ +- if (link_opt->hdr.type == IPV6_ICMP_OPTION_TAR_ADDR) { +- tar_addr6 = (struct ipv6_addr *)((u8_t *)icmp + +- sizeof(struct icmpv6_hdr)); +- 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]); +- 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(context, tar_addr6, +- (struct mac_address *)link_opt->link_addr); +- } +- +- } +-} +- +-static void ipv6_icmp_handle_nd_sol(struct ipv6_context *context) +-{ +- struct eth_hdr *eth = +- (struct eth_hdr *)context->ustack->data_link_layer; +- struct ipv6_hdr *ipv6 = +- (struct ipv6_hdr *)context->ustack->network_layer; +- struct icmpv6_hdr *icmp = (struct icmpv6_hdr *)((u8_t *)ipv6 + +- sizeof(struct ipv6_hdr)); +- struct icmpv6_opt_link_addr *link_opt = +- (struct icmpv6_opt_link_addr *)((u8_t *)icmp + +- sizeof(struct icmpv6_hdr) + sizeof(struct ipv6_addr)); +- int icmpv6_opt_len = 0; +- struct ipv6_addr tmp; +- struct ipv6_addr *longest_match_addr, *tar_addr6; +- +- LOG_DEBUG("IPv6: Handle nd sol"); +- +- if ((memcmp((char *)&context->mac_addr, +- (char *)ð->dest_mac, sizeof(struct mac_address)) != 0) && +- (iscsiL2IsOurMcAddr(context, (struct mac_address *)ð->dest_mac) +- == FALSE)) { +- /* This packet is not for us to handle */ +- LOG_DEBUG("IPv6: MAC not addressed to us " +- "%02x:%02x:%02x:%02x:%02x:%02x", +- eth->dest_mac.addr[0], eth->dest_mac.addr[1], +- eth->dest_mac.addr[2], eth->dest_mac.addr[3], +- eth->dest_mac.addr[4], eth->dest_mac.addr[5]); +- return; +- } +- +- /* Also check for the icmpv6_data before generating the reply */ +- if (ipv6_is_it_our_address(context, +- (struct ipv6_addr *) ((u8_t *) icmp + +- sizeof(struct icmpv6_hdr))) +- == FALSE) { +- /* This packet is not for us to handle */ +- LOG_DEBUG("IPv6: IP not addressed to us"); +- return; +- } +- +- /* Copy source MAC to Destination MAC */ +- memcpy((char *)ð->dest_mac, +- (char *)ð->src_mac, sizeof(struct mac_address)); +- +- /* Dest IP contains source IP */ +- memcpy((char *)&tmp, +- (char *)&ipv6->ipv6_dst, sizeof(struct ipv6_addr)); +- memcpy((char *)&ipv6->ipv6_dst, +- (char *)&ipv6->ipv6_src, sizeof(struct ipv6_addr)); +- +- /* Examine the Neighbor Solicitation ICMPv6 target address field. +- If target address exist, use that to find best match src address +- for the reply */ +- if (link_opt->hdr.type == IPV6_ICMP_OPTION_SRC_ADDR) { +- tar_addr6 = (struct ipv6_addr *)((u8_t *)icmp + +- sizeof(struct icmpv6_hdr)); +- if (ipv6_is_it_our_link_local_address(context, tar_addr6) +- == TRUE) { +- LOG_DEBUG("IPv6: NA using link local"); +- memcpy((char *)&ipv6->ipv6_src, +- (char *)&context->link_local_addr, +- sizeof(struct ipv6_addr)); +- } else { +- longest_match_addr = +- ipv6_find_longest_match(context, tar_addr6); +- if (longest_match_addr) { +- LOG_DEBUG("IPv6: NA using longest match addr"); +- memcpy((char *)&ipv6->ipv6_src, +- (char *)longest_match_addr, +- sizeof(struct ipv6_addr)); +- } else { +- LOG_DEBUG("IPv6: NA using link local instead"); +- memcpy((char *)&ipv6->ipv6_src, +- (char *)&context->link_local_addr, +- sizeof(struct ipv6_addr)); +- } +- } +- } else { +- /* No target link address, just use whatever it sent to us */ +- LOG_DEBUG("IPv6: NA use dst addr"); +- memcpy((char *)&ipv6->ipv6_src, +- (char *)&tmp, +- sizeof(struct ipv6_addr)); +- } +- ipv6->ipv6_hop_limit = 255; +- icmp->icmpv6_type = ICMPV6_NEIGH_ADV; +- icmp->icmpv6_code = 0; +- icmp->icmpv6_data = 0; +- icmp->icmpv6_cksum = 0; +- icmp->data.icmpv6_un_data8[0] = +- IPV6_NA_FLAG_SOLICITED | IPV6_NA_FLAG_OVERRIDE; +- memcpy((char *)((u8_t *)icmp + sizeof(struct icmpv6_hdr)), +- (char *)&ipv6->ipv6_src, +- sizeof(struct ipv6_addr)); +- +- /* Add the target link address option only for all solicitation */ +- ipv6_icmp_init_link_option(context, +- (struct icmpv6_opt_link_addr *)((u8_t *)icmp + +- sizeof(struct icmpv6_hdr) + +- sizeof(struct ipv6_addr)), +- IPV6_ICMP_OPTION_TAR_ADDR); +- icmpv6_opt_len = sizeof(struct icmpv6_opt_link_addr); +- ipv6->ipv6_plen = HOST_TO_NET16((sizeof(struct icmpv6_hdr) + +- icmpv6_opt_len + sizeof(struct ipv6_addr))); +- LOG_DEBUG("IPv6: Send nd adv"); +- ipv6_send(context, +- (u8_t *) icmp - (u8_t *) eth + +- sizeof(struct icmpv6_hdr) + +- sizeof(struct icmpv6_opt_link_addr) + +- sizeof(struct ipv6_addr)); +- return; +-} +- +-static void ipv6_icmp_handle_echo_request(struct ipv6_context *context) +-{ +- struct eth_hdr *eth = +- (struct eth_hdr *)context->ustack->data_link_layer; +- struct ipv6_hdr *ipv6 = +- (struct ipv6_hdr *)context->ustack->network_layer; +- struct icmpv6_hdr *icmp = (struct icmpv6_hdr *)((u8_t *)ipv6 + +- sizeof(struct ipv6_hdr)); +- struct ipv6_addr temp; +- +- /* Copy source MAC to Destination MAC */ +- memcpy((char *)ð->dest_mac, +- (char *)ð->src_mac, sizeof(struct mac_address)); +- +- memcpy((char *)&temp, +- (char *)&ipv6->ipv6_dst, sizeof(struct ipv6_addr)); +- +- /* Dest IP contains source IP */ +- memcpy((char *)&ipv6->ipv6_dst, +- (char *)&ipv6->ipv6_src, sizeof(struct ipv6_addr)); +- /* Use Link-local as source address */ +- memcpy((char *)&ipv6->ipv6_src, +- (char *)&temp, sizeof(struct ipv6_addr)); +- +- ipv6->ipv6_hop_limit = context->hop_limit; +- icmp->icmpv6_type = ICMPV6_ECHO_REPLY; +- icmp->icmpv6_code = 0; +- icmp->icmpv6_cksum = 0; +- LOG_DEBUG("IPv6: Send echo reply"); +- ipv6_send(context, (u8_t *) icmp - (u8_t *) eth + +- sizeof(struct ipv6_hdr) + HOST_TO_NET16(ipv6->ipv6_plen)); +- return; +-} +- +-void ipv6_set_ip_params(struct ipv6_context *context, +- struct ipv6_addr *src_ip, u8_t prefix_len, +- struct ipv6_addr *default_gateway, +- struct ipv6_addr *linklocal) +-{ +- if (!(IPV6_IS_ADDR_UNSPECIFIED(src_ip))) { +- ipv6_add_prefix_entry(context, src_ip, prefix_len); +- /* Create the multi_dest address */ +- memset(&context->multi_dest, 0, sizeof(struct ipv6_addr)); +- context->multi_dest.addr8[0] = 0xff; +- context->multi_dest.addr8[1] = 0x02; +- context->multi_dest.addr8[11] = 0x01; +- context->multi_dest.addr8[12] = 0xff; +- context->multi_dest.addr8[13] = src_ip->addr8[13]; +- context->multi_dest.addr16[7] = src_ip->addr16[7]; +- /* Create the multi address */ +- memset(&context->multi, 0, sizeof(struct ipv6_addr)); +- context->multi.addr8[0] = 0xfc; +- context->multi.addr8[2] = 0x02; +- context->multi.addr16[7] = src_ip->addr16[7]; +- } +- +- if (!(IPV6_IS_ADDR_UNSPECIFIED(default_gateway))) { +- /* Override the default gateway addr */ +- memcpy((char *)&context->default_router, +- (char *)default_gateway, sizeof(struct ipv6_addr)); +- ipv6_add_prefix_entry(context, default_gateway, +- prefix_len); +- } +- if (!(IPV6_IS_ADDR_UNSPECIFIED(linklocal))) { +- /* Override the linklocal addr */ +- memcpy((char *)&context->link_local_addr, +- (char *)linklocal, sizeof(struct ipv6_addr)); +- context->link_local_multi.addr8[0] = 0xff; +- context->link_local_multi.addr8[1] = 0x02; +- context->link_local_multi.addr8[11] = 0x01; +- context->link_local_multi.addr8[12] = 0xff; +- context->link_local_multi.addr8[13] |= +- context->link_local_addr.addr8[13]; +- context->link_local_multi.addr16[7] = +- 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(context, +- &context->link_local_addr, 64); +- } +-} +- +-int ipv6_get_source_ip_addrs(struct ipv6_context *context, +- struct ipv6_addr_entry *addr_list) +-{ +- struct ipv6_prefix_entry *ipv6_prefix; +- int i; +- +- for (i = 0, ipv6_prefix = context->addr_list; ipv6_prefix != NULL; +- ipv6_prefix = ipv6_prefix->next) { +- memcpy((char *)&addr_list->ip_addr, +- (char *)&ipv6_prefix->ip_addr, +- sizeof(struct ipv6_addr)); +- addr_list->prefix_len = ipv6_prefix->prefix_len * 8; +- +- i++; +- addr_list++; +- } +- +- return i; +-} +- +-int ipv6_get_default_router_ip_addrs(struct ipv6_context *context, +- struct ipv6_addr *ip_addr) +-{ +- /* This is a default router. */ +- memcpy((char *)ip_addr, +- (char *)&context->default_router, +- sizeof(struct ipv6_addr)); +- +- return 1; +-} +- +-static void ipv6_udp_rx(struct ipv6_context *context) +-{ +- struct eth_hdr *eth = +- (struct eth_hdr *)context->ustack->data_link_layer; +- struct ipv6_hdr *ipv6 = +- (struct ipv6_hdr *)context->ustack->network_layer; +- struct udp_hdr *udp = (struct udp_hdr *)((u8_t *)ipv6 + +- sizeof(struct ipv6_hdr)); +- struct dhcpv6_context *dhcpv6c; +- +- /* +- * We only care about DHCPv6 packets from the DHCPv6 server. We drop +- * all others. +- */ +- if (!(context->flags & IPV6_FLAGS_DISABLE_DHCPV6)) { +- if ((udp->src_port == HOST_TO_NET16(DHCPV6_SERVER_PORT)) && +- (udp->dest_port == HOST_TO_NET16(DHCPV6_CLIENT_PORT))) { +- dhcpv6c = context->dhcpv6_context; +- dhcpv6c->eth = eth; +- dhcpv6c->ipv6 = ipv6; +- dhcpv6c->udp = udp; +- ipv6_udp_handle_dhcp(dhcpv6c); +- } +- } +-} +- +-struct mac_address *ipv6_get_link_addr(struct ipv6_context *context) +-{ +- return &context->mac_addr; +-} +- +-u16_t ipv6_do_stateful_dhcpv6(struct ipv6_context *context, u32_t flags) +-{ +- u16_t task = 0; +- u16_t ra_flags; +- +- ra_flags = context->flags & +- (IPV6_FLAGS_MANAGED_ADDR_CONFIG | IPV6_FLAGS_OTHER_STATEFUL_CONFIG); +- +- if (!(context->flags & IPV6_FLAGS_ROUTER_ADV_RECEIVED)) { +- LOG_DEBUG("IPv6: There is no IPv6 router on the network"); +- ra_flags |= +- (IPV6_FLAGS_MANAGED_ADDR_CONFIG | +- IPV6_FLAGS_OTHER_STATEFUL_CONFIG); +- } +- +- if ((flags & ISCSI_FLAGS_DHCP_TCPIP_CONFIG) && +- (ra_flags & IPV6_FLAGS_MANAGED_ADDR_CONFIG)) +- task |= DHCPV6_TASK_GET_IP_ADDRESS; +- +- if ((flags & ISCSI_FLAGS_DHCP_ISCSI_CONFIG) && +- (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, ra_flags, task); +- +- return task; +-} +- +-void ipv6_add_solit_node_address(struct ipv6_context *context, +- struct ipv6_addr *ip_addr) +-{ +- struct mac_address mac_addr; +- +- /* +- * Add Solicited Node Multicast Address for statically configured IPv6 +- * address. +- */ +- mac_addr.addr[0] = 0x33; +- mac_addr.addr[1] = 0x33; +- mac_addr.addr[2] = 0xff; +- mac_addr.addr[3] = ip_addr->addr8[13]; +- mac_addr.addr[4] = ip_addr->addr8[14]; +- mac_addr.addr[5] = ip_addr->addr8[15]; +- iscsiL2AddMcAddr(context, (struct mac_address *)&mac_addr); +-} +- +-void ipv6_cfg_link_local_addr(struct ipv6_context *context, +- struct ipv6_addr *ip_addr) +-{ +- memcpy((char *)&context->link_local_addr, +- (char *)ip_addr, sizeof(struct ipv6_addr)); +-} +- +-void ipv6_disable_dhcpv6(struct ipv6_context *context) +-{ +- context->flags |= IPV6_FLAGS_DISABLE_DHCPV6; +-} +diff --git a/iscsiuio/src/uip/ipv6.h b/iscsiuio/src/uip/ipv6.h +deleted file mode 100644 +index 3586437..0000000 +--- a/iscsiuio/src/uip/ipv6.h ++++ /dev/null +@@ -1,332 +0,0 @@ +-/* +- * Copyright (c) 2011, Broadcom Corporation +- * Copyright (c) 2014, QLogic Corporation +- * +- * Written by: Eddie Wai (eddie.wai@broadcom.com) +- * Based on Kevin Tran's iSCSI boot code +- * +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. All advertising materials mentioning features or use of this software +- * must display the following acknowledgement: +- * This product includes software developed by Adam Dunkels. +- * 4. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * ipv6.h - This file contains macro definitions pertaining to IPv6. +- * +- * RFC 2460 : IPv6 Specification. +- * RFC 2373 : IPv6 Addressing Architecture. +- * RFC 2462 : IPv6 Stateless Address Autoconfiguration. +- * RFC 2464 : Transmission of IPv6 Packets over Ethernet Networks. +- * +- */ +-#ifndef __IPV6_H__ +-#define __IPV6_H__ +- +-#include "ipv6_ndpc.h" +- +-#define FALSE 0 +-#define TRUE 1 +- +-#define LINK_LOCAL_PREFIX_LENGTH 2 +-#define LAYER2_HEADER_LENGTH 14 +-#define LAYER2_VLAN_HEADER_LENGTH 16 +-#define LAYER2_TYPE_IPV6 0x86dd +- +-struct ipv6_addr { +- union { +- u8_t addr8[16]; +- u16_t addr16[8]; +- u32_t addr[4]; +- }; +-}; +- +-struct udp_hdr { +- u16_t src_port; +- u16_t dest_port; +- u16_t length; +- u16_t chksum; +-}; +- +-struct mac_address { +- union { +- u8_t addr[6]; +- struct { +- u16_t first_2_bytes; +- u32_t last_4_bytes; +- } __attribute__ ((packed)); +- }; +-}; +- +-#define HOST_TO_NET16(a) htons(a) +-#define HOST_TO_NET32(a) htonl(a) +-#define NET_TO_HOST16(a) ntohs(a) +-/* +- * Local definition for masks +- */ +-#define IPV6_MASK0 { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } } } +-#define IPV6_MASK32 { { { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, \ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } } +-#define IPV6_MASK64 { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } } +-#define IPV6_MASK96 { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ +- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } } } +-#define IPV6_MASK128 { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ +- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } } } +- +-#ifdef BIG_ENDIAN +-#define IPV6_ADDR_INT32_ONE 1 +-#define IPV6_ADDR_INT32_TWO 2 +-#define IPV6_ADDR_INT32_MNL 0xff010000 +-#define IPV6_ADDR_INT32_MLL 0xff020000 +-#define IPV6_ADDR_INT32_SMP 0x0000ffff +-#define IPV6_ADDR_INT16_ULL 0xfe80 +-#define IPV6_ADDR_INT16_USL 0xfec0 +-#define IPV6_ADDR_INT16_MLL 0xff02 +-#else /* LITTE ENDIAN */ +-#define IPV6_ADDR_INT32_ONE 0x01000000 +-#define IPV6_ADDR_INT32_TWO 0x02000000 +-#define IPV6_ADDR_INT32_MNL 0x000001ff +-#define IPV6_ADDR_INT32_MLL 0x000002ff +-#define IPV6_ADDR_INT32_SMP 0xffff0000 +-#define IPV6_ADDR_INT16_ULL 0x80fe +-#define IPV6_ADDR_INT16_USL 0xc0fe +-#define IPV6_ADDR_INT16_MLL 0x02ff +-#endif +- +-/* +- * Definition of some useful macros to handle IP6 addresses +- */ +-#define IPV6_ADDR_ANY_INIT \ +- { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } } +-#define IPV6_ADDR_LOOPBACK_INIT \ +- { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } } } +-#define IPV6_ADDR_NODELOCAL_ALLNODES_INIT \ +- { { { 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } } } +-#define IPV6_ADDR_INTFACELOCAL_ALLNODES_INIT \ +- { { { 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } } } +-#define IPV6_ADDR_LINKLOCAL_ALLNODES_INIT \ +- { { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } } } +-#define IPV6_ADDR_LINKLOCAL_ALLROUTERS_INIT \ +- { { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 } } } +- +-#define IPV6_ARE_ADDR_EQUAL(a, b) \ +- (memcmp((char *)a, (char *)b, sizeof(struct ipv6_addr)) == 0) +- +-/* Unspecified IPv6 address */ +-#define IPV6_IS_ADDR_UNSPECIFIED(a) \ +- ((((a)->addr[0]) == 0) && \ +- (((a)->addr[1]) == 0) && \ +- (((a)->addr[2]) == 0) && \ +- (((a)->addr[3]) == 0)) +- +-/* IPv6 Scope Values */ +-#define IPV6_ADDR_SCOPE_INTFACELOCAL 0x01 /* Node-local scope */ +-#define IPV6_ADDR_SCOPE_LINKLOCAL 0x02 /* Link-local scope */ +-#define IPV6_ADDR_SCOPE_SITELOCAL 0x05 /* Site-local scope */ +-#define IPV6_ADDR_SCOPE_ORGLOCAL 0x08 /* Organization-local scope */ +-#define IPV6_ADDR_SCOPE_GLOBAL 0x0e /* Global scope */ +- +-/* Link-local Unicast : 10-bits much be 1111111010b --> 0xfe80. */ +-#define IPV6_IS_ADDR_LINKLOCAL(a) \ +- (((a)->addr8[0] == 0xfe) && (((a)->addr8[1] & 0xc0) == 0x80)) +- +-/* Site-local Unicast : 10-bits much be 1111111011b --> 0xfec0. */ +-#define IPV6_IS_ADDR_SITELOCAL(a) \ +- (((a)->addr8[0] == 0xfe) && (((a)->addr8[1] & 0xc0) == 0xc0)) +- +-/* Multicast : 10bits much be 11111111b. Next 4 bits is flags | 4-bit scope */ +-#define IPV6_IS_ADDR_MULTICAST(a) ((a)->addr8[0] == 0xff) +- +-#define IPV6_ADDR_MC_SCOPE(a) ((a)->addr8[1] & 0x0f) +- +-/* Multicast Scope */ +- +-struct eth_hdr { +- struct mac_address dest_mac; +- struct mac_address src_mac; +- u16_t len_type; +-}; +- +-struct ipv6_hdr { +- union { +- struct { +- u32_t ipv6_flow; /* Version (4-bit) | +- Traffic Class (8-bit) | +- Flow ID (20-bit) */ +- u16_t ipv6_plen; /* Payload length */ +- u8_t ipv6_nxt_hdr; /* Next Header */ +- u8_t ipv6_hop_limit; /* hop limit */ +- } ipv6_dw1; +- +- u8_t ipv6_version_fc; /* 4 bits version, top 4 bits class */ +- } ipv6_ctrl; +- +- struct ipv6_addr ipv6_src; /* Source address */ +- struct ipv6_addr ipv6_dst; /* Destination address */ +-}; +- +-#define ipv6_version_fc ipv6_ctrl.ipv6_version_fc +-#define ipv6_flow ipv6_ctrl.ipv6_dw1.ipv6_flow +-#define ipv6_plen ipv6_ctrl.ipv6_dw1.ipv6_plen +-#define ipv6_nxt_hdr ipv6_ctrl.ipv6_dw1.ipv6_nxt_hdr +-#define ipv6_hop_limit ipv6_ctrl.ipv6_dw1.ipv6_hop_limit +- +-#define IPV6_VERSION 0x60 +-#define IPV6_VERSION_MASK 0xf0 +-#define IPV6_HOP_LIMIT 64 +- +-/* Length of the IP header with no next header */ +-#define IPV6_HEADER_LEN sizeof(struct ipv6_hdr) +- +-#ifdef BIG_ENDIAN +-#define IPV6_FLOWINFO_MASK 0x0fffffff /* flow info (28 bits) */ +-#define IPV6_FLOWLABEL_MASK 0x000fffff /* flow label (20 bits) */ +-#else /* LITTLE_ENDIAN */ +-#define IPV6_FLOWINFO_MASK 0xffffff0f /* flow info (28 bits) */ +-#define IPV6_FLOWLABEL_MASK 0xffff0f00 /* flow label (20 bits) */ +-#endif +- +-struct packet_ipv6 { +- struct mac_address dest_mac; +- struct mac_address src_mac; +- u16_t len_type; +- struct ipv6_hdr ipv6; +- union { +- struct udp_hdr udp; +- } layer4_prot; +-}; +- +-struct packet_ipv6_vlan { +- struct mac_address dest_mac; +- struct mac_address src_mac; +- u16_t len_type; +- u16_t vlan_id; +- struct ipv6_hdr ipv6; +- union { +- struct udp_hdr udp; +- } layer4_prot; +-}; +- +-struct ipv6_arp_entry { +- struct ipv6_addr ip_addr; +- struct mac_address mac_addr; +- u8_t time; +-}; +- +-#define IPV6_NUM_OF_ADDRESS_ENTRY 4 +- +-struct ipv6_prefix_entry { +- struct ipv6_prefix_entry *next; +- struct ipv6_addr ip_addr; +- u8_t prefix_len; +-}; +- +-struct ipv6_addr_entry { +- struct ipv6_addr ip_addr; +- u8_t prefix_len; +-}; +- +-struct ipv6_context { +- u16_t flags; +-#define IPV6_FLAGS_MANAGED_ADDR_CONFIG (1 << 0) +-#define IPV6_FLAGS_OTHER_STATEFUL_CONFIG (1 << 1) +-#define IPV6_FLAGS_ROUTER_ADV_RECEIVED (1 << 2) +-#define IPV6_FLAGS_DISABLE_DHCPV6 (1 << 3) +- +- struct mac_address mac_addr; +- struct ipv6_addr link_local_addr; +- struct ipv6_addr link_local_multi; +- struct ipv6_addr multi; /* For Static IPv6 only */ +- struct ipv6_addr multi_dest; /* For Static IPv6 only */ +- struct ipv6_addr default_router; +- struct ipv6_prefix_entry *addr_list; +- u8_t hop_limit; +-#define UIP_ARPTAB_SIZE 16 +- +- struct uip_stack *ustack; +-#define MAX_MCADDR_TABLE 5 +- struct mac_address mc_addr[MAX_MCADDR_TABLE]; +- u8_t arptime; +- struct ipv6_arp_entry ipv6_arp_table[UIP_ARPTAB_SIZE]; +- struct ipv6_prefix_entry ipv6_prefix_table[IPV6_NUM_OF_ADDRESS_ENTRY]; +- +- /* VLAN support */ +- +- void *dhcpv6_context; +-}; +- +-#define ISCSI_FLAGS_DHCP_TCPIP_CONFIG (1<<0) +-#define ISCSI_FLAGS_DHCP_ISCSI_CONFIG (1<<1) +- +-#define IPV6_MAX_ROUTER_SOL_DELAY 4 +-#define IPV6_MAX_ROUTER_SOL_RETRY 3 +- +-#define DHCPV6_CLIENT_PORT 546 +-#define DHCPV6_SERVER_PORT 547 +- +-/* Function prototype */ +-void ipv6_init(struct ndpc_state *ndp, int cfg); +-int ipv6_autoconfig(struct ipv6_context *context); +-int ipv6_discover_address(struct ipv6_context *context); +-struct ipv6_addr *ipv6_our_address(struct ipv6_context *context); +-int ipv6_ip_in_arp_table(struct ipv6_context *context, +- struct ipv6_addr *ipv6_addr, +- struct mac_address *mac_addr); +-void ipv6_arp_timer(struct ipv6_context *context); +-void ipv6_arp_out(struct ipv6_context *context, int *uip_len); +-int ipv6_add_prefix_entry(struct ipv6_context *context, +- struct ipv6_addr *ip_addr, u8_t prefix_len); +-void ipv6_set_ip_params(struct ipv6_context *context, +- struct ipv6_addr *src_ip, u8_t prefix_len, +- struct ipv6_addr *default_gateway, +- struct ipv6_addr *linklocal); +-void ipv6_set_host_addr(struct ipv6_context *context, struct ipv6_addr *src_ip); +-int ipv6_get_default_router_ip_addrs(struct ipv6_context *context, +- struct ipv6_addr *ip_addr); +-struct mac_address *ipv6_get_link_addr(struct ipv6_context *context); +-u16_t ipv6_do_stateful_dhcpv6(struct ipv6_context *context, u32_t flags); +-void ipv6_add_solit_node_address(struct ipv6_context *context, +- struct ipv6_addr *ip_addr); +-int ipv6_get_source_ip_addrs(struct ipv6_context *context, +- struct ipv6_addr_entry *addr_list); +-void ipv6_cfg_link_local_addr(struct ipv6_context *context, +- struct ipv6_addr *ip_addr); +-void ipv6_disable_dhcpv6(struct ipv6_context *context); +-int ipv6_send_nd_solicited_packet(struct ipv6_context *context, +- struct eth_hdr *eth, struct ipv6_hdr *ipv6); +-int ipv6_is_it_our_link_local_address(struct ipv6_context *context, +- struct ipv6_addr *ip_addr); +-void ipv6_mc_init_dest_mac(struct eth_hdr *eth, struct ipv6_hdr *ipv6); +-struct ipv6_addr *ipv6_find_longest_match(struct ipv6_context *context, +- struct ipv6_addr *ip_addr); +- +-#endif /* __IPV6_H__ */ +diff --git a/iscsiuio/src/uip/ipv6_ndpc.c b/iscsiuio/src/uip/ipv6_ndpc.c +deleted file mode 100644 +index bb07c1d..0000000 +--- a/iscsiuio/src/uip/ipv6_ndpc.c ++++ /dev/null +@@ -1,432 +0,0 @@ +-/* +- * Copyright (c) 2011, Broadcom Corporation +- * Copyright (c) 2014, QLogic Corporation +- * +- * Written by: Eddie Wai (eddie.wai@broadcom.com) +- * Based on the Swedish Institute of Computer Science's +- * dhcpc.c code +- * +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. All advertising materials mentioning features or use of this software +- * must display the following acknowledgement: +- * This product includes software developed by Adam Dunkels. +- * 4. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * ipv6_ndpc.c - Top level IPv6 Network Discovery Protocol Engine (RFC4861) +- * +- */ +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include "uip.h" +-#include "ipv6_ndpc.h" +-#include "timer.h" +-#include "pt.h" +- +-#include "debug.h" +-#include "logger.h" +-#include "nic.h" +-#include "nic_utils.h" +-#include "ipv6.h" +-#include "ipv6_pkt.h" +-#include "dhcpv6.h" +- +-const int dhcpv6_retry_timeout[DHCPV6_NUM_OF_RETRY] = { 1, 2, 4, 8 }; +- +-static PT_THREAD(handle_ndp(struct uip_stack *ustack, int force)) +-{ +- struct ndpc_state *s; +- struct ipv6_context *ipv6c; +- struct dhcpv6_context *dhcpv6c = NULL; +- u16_t task = 0; +- char buf[INET6_ADDRSTRLEN]; +- +- s = ustack->ndpc; +- if (s == NULL) { +- LOG_DEBUG("NDP: Could not find ndpc state"); +- return PT_ENDED; +- } +- +- ipv6c = s->ipv6_context; +- if (!ipv6c) +- goto ndpc_state_null; +- +- dhcpv6c = s->dhcpv6_context; +- +- PT_BEGIN(&s->pt); +- +- if (s->state == NDPC_STATE_BACKGROUND_LOOP) +- goto ipv6_loop; +- +- 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; +- s->retry_count = 0; +- do { +- /* Perform router solicitation and wait for +- router advertisement */ +- LOG_DEBUG("%s: ndpc_handle send rtr sol", s->nic->log_name); +- ipv6_autoconfig(s->ipv6_context); +- +- timer_set(&s->timer, s->ticks); +-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); +- PT_WAIT_UNTIL(&s->pt, uip_newdata(s->ustack) +- || timer_expired(&s->timer) || force); +- +- if (uip_newdata(s->ustack)) { +- /* Validate incoming packets +- Note that the uip_len is init from nic loop */ +- ipv6_rx_packet(ipv6c, (u16_t) uip_datalen(s->ustack)); +- if (ipv6c->flags & IPV6_FLAGS_ROUTER_ADV_RECEIVED) { +- LOG_INFO("%s: ROUTER_ADV_RECEIVED", +- s->nic->log_name); +- /* Success */ +- break; +- } else if (!timer_expired(&s->timer)) { +- /* Yes new data, but not what we want, +- check for timer expiration before bumping +- tick */ +- goto wait_rtr; +- } +- } +- s->retry_count++; +- if (s->retry_count >= IPV6_MAX_ROUTER_SOL_RETRY) +- /* Max router solicitation retry reached. Move to +- IPv6 loop (no DHCPv6) */ +- goto no_rtr_adv; +- +- } while (!(ipv6c->flags & IPV6_FLAGS_ROUTER_ADV_RECEIVED)); +- +- LOG_DEBUG("%s: ndpc_handle got rtr adv", s->nic->log_name); +- s->retry_count = 0; +- +-no_rtr_adv: +- s->state = NDPC_STATE_RTR_ADV; +- +-rtr_adv: +- 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) { +- /* Run the DHCPv6 engine */ +- +- if (!dhcpv6c) +- goto ipv6_loop; +- +- dhcpv6c->dhcpv6_task = task; +- s->retry_count = 0; +- s->state = NDPC_STATE_DHCPV6_DIS; +- do { +- /* Do dhcpv6 */ +- dhcpv6c->timeout = dhcpv6_retry_timeout[s->retry_count]; +- s->ticks = CLOCK_SECOND * dhcpv6c->timeout; +- LOG_DEBUG("%s: ndpc_handle send dhcpv6 sol retry " +- "cnt=%d", s->nic->log_name, s->retry_count); +- dhcpv6_do_discovery(dhcpv6c); +- +- timer_set(&s->timer, s->ticks); +-wait_dhcp: +- s->ustack->uip_flags &= ~UIP_NEWDATA; +- PT_WAIT_UNTIL(&s->pt, uip_newdata(s->ustack) +- || timer_expired(&s->timer) || force); +- +- if (uip_newdata(s->ustack)) { +- /* Validate incoming packets +- Note that the uip_len is init from nic +- loop */ +- ipv6_rx_packet(ipv6c, +- (u16_t) uip_datalen(s->ustack)); +- if (dhcpv6c->dhcpv6_done == TRUE) +- break; +- else if (!timer_expired(&s->timer)) { +- /* Yes new data, but not what we want, +- check for timer expiration before +- bumping tick */ +- goto wait_dhcp; +- } +- } +- s->retry_count++; +- if (s->retry_count < DHCPV6_NUM_OF_RETRY) { +- dhcpv6c->seconds += dhcpv6c->timeout; +- } else { +- LOG_DEBUG("%s: ndpc_handle DHCP failed", +- s->nic->log_name); +- /* Allow to goto background loop */ +- goto ipv6_loop; +- } +- } 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 */ +- } else { +- /* Static IPv6 */ +- if (ustack->ip_config == IPV6_CONFIG_DHCP) { +- s->retry_count++; +- if (s->retry_count > DHCPV6_NUM_OF_RETRY) { +- LOG_DEBUG("%s: ndpc_handle DHCP failed", +- s->nic->log_name); +- } else { +- PT_RESTART(&s->pt); +- } +- } +-staticv6: +- ipv6_disable_dhcpv6(ipv6c); +- } +- /* 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(struct 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(struct 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; +- LOG_DEBUG("%s: Loop", s->nic->log_name); +- /* Background IPv6 loop */ +- while (1) { +- /* Handle all neightbor solicitation/advertisement here */ +- s->ustack->uip_flags &= ~UIP_NEWDATA; +- PT_WAIT_UNTIL(&s->pt, uip_newdata(s->ustack)); +- +- /* Validate incoming packets */ +- ipv6_rx_packet(ipv6c, (u16_t) uip_datalen(s->ustack)); +- } +- +-ndpc_state_null: +- +- while (1) +- PT_YIELD(&s->pt); +- +- PT_END(&(s->pt)); +-} +- +-/*---------------------------------------------------------------------------*/ +-int ndpc_init(nic_t *nic, struct uip_stack *ustack, +- const void *mac_addr, int mac_len) +-{ +- struct ipv6_context *ipv6c; +- struct dhcpv6_context *dhcpv6c; +- struct ndpc_state *s = ustack->ndpc; +- struct ipv6_addr src, gw, ll; +- char buf[INET6_ADDRSTRLEN]; +- +- if (s) { +- LOG_DEBUG("NDP: NDP context already allocated"); +- /* Already allocated, skip*/ +- return -EALREADY; +- } +- s = malloc(sizeof(*s)); +- if (s == NULL) { +- LOG_ERR("%s: Couldn't allocate size for ndpc info", +- nic->log_name); +- goto error; +- } +- memset(s, 0, sizeof(*s)); +- +- if (s->ipv6_context) { +- LOG_DEBUG("NDP: IPv6 context already allocated"); +- ipv6c = s->ipv6_context; +- goto init1; +- } +- ipv6c = malloc(sizeof(struct ipv6_context)); +- if (ipv6c == NULL) { +- LOG_ERR("%s: Couldn't allocate mem for IPv6 context info", +- nic->log_name); +- goto error1; +- } +-init1: +- if (s->dhcpv6_context) { +- LOG_DEBUG("NDP: DHCPv6 context already allocated"); +- dhcpv6c = s->dhcpv6_context; +- goto init2; +- } +- dhcpv6c = malloc(sizeof(struct dhcpv6_context)); +- if (dhcpv6c == NULL) { +- LOG_ERR("%s: Couldn't allocate mem for DHCPv6 context info", +- nic->log_name); +- goto error2; +- } +-init2: +- memset(s, 0, sizeof(*s)); +- memset(ipv6c, 0, sizeof(*ipv6c)); +- memset(dhcpv6c, 0, sizeof(*dhcpv6c)); +- +- s->ipv6_context = ipv6c; +- s->dhcpv6_context = dhcpv6c; +- +- s->nic = nic; +- s->ustack = ustack; +- s->mac_addr = (void *)mac_addr; +- s->mac_len = mac_len; +- s->state = NDPC_STATE_INIT; +- +- /* Init IPV6_CONTEXT */ +- ipv6_init(s, ustack->ip_config); +- +- dhcpv6c->ipv6_context = ipv6c; +- ipv6c->dhcpv6_context = dhcpv6c; +- +- /* Init DHCPV6_CONTEXT */ +- dhcpv6_init(dhcpv6c); +- +- ustack->ndpc = s; +- +- PT_INIT(&s->pt); +- +- if (ustack->ip_config == IPV6_CONFIG_DHCP) { +- /* DHCPv6 specific */ +- memset(&src, 0, sizeof(src)); +- } else { +- /* Static v6 specific */ +- memcpy(&src.addr8, &ustack->hostaddr6, +- sizeof(struct 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(struct ipv6_addr)); +- else +- memset(&gw, 0, sizeof(gw)); +- +- if (ustack->linklocal_autocfg == IPV6_LL_AUTOCFG_OFF) +- memcpy(&ll.addr8, &ustack->linklocal6, +- sizeof(struct ipv6_addr)); +- else +- memset(&ll, 0, sizeof(ll)); +- ipv6_set_ip_params(ipv6c, &src, +- ustack->prefix_len, &gw, &ll); +- +- return 0; +-error2: +- free(ipv6c); +- s->ipv6_context = NULL; +-error1: +- free(s); +- ustack->ndpc = NULL; +-error: +- return -ENOMEM; +-} +- +-/*---------------------------------------------------------------------------*/ +-void ndpc_call(struct uip_stack *ustack) +-{ +- handle_ndp(ustack, 0); +-} +- +-void ndpc_exit(struct ndpc_state *ndp) +-{ +- LOG_DEBUG("NDP - Exit ndpc_state = %p", ndp); +- if (!ndp) +- return; +- if (ndp->ipv6_context) +- free(ndp->ipv6_context); +- if (ndp->dhcpv6_context) +- free(ndp->dhcpv6_context); +- free(ndp); +-} +- +-int ndpc_request(struct uip_stack *ustack, void *in, void *out, int request) +-{ +- struct ndpc_state *s; +- struct ipv6_context *ipv6c; +- int ret = 0; +- +- if (!ustack) { +- LOG_DEBUG("NDP: ustack == NULL"); +- return -EINVAL; +- } +- s = ustack->ndpc; +- if (s == NULL) { +- LOG_DEBUG("NDP: Could not find ndpc state for request %d", +- request); +- return -EINVAL; +- } +- while (s->state != NDPC_STATE_BACKGROUND_LOOP) { +- 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: +- *(int *)out = ipv6_send_nd_solicited_packet(ipv6c, +- (struct eth_hdr *)((struct ndpc_reqptr *)in)->eth, +- (struct ipv6_hdr *)((struct ndpc_reqptr *)in)->ipv6); +- break; +- case CHECK_LINK_LOCAL_ADDR: +- *(int *)out = ipv6_is_it_our_link_local_address(ipv6c, +- (struct ipv6_addr *)in); +- break; +- case CHECK_ARP_TABLE: +- *(int *)out = ipv6_ip_in_arp_table(ipv6c, +- (struct ipv6_addr *)((struct ndpc_reqptr *)in)->ipv6, +- (struct mac_address *)((struct ndpc_reqptr *)in)->eth); +- break; +- case GET_HOST_ADDR: +- *(struct ipv6_addr **)out = ipv6_find_longest_match(ipv6c, +- (struct ipv6_addr *)in); +- break; +- default: +- ret = -EINVAL; +- break; +- } +- return ret; +-} +- +-/*---------------------------------------------------------------------------*/ +diff --git a/iscsiuio/src/uip/ipv6_ndpc.h b/iscsiuio/src/uip/ipv6_ndpc.h +deleted file mode 100644 +index 709a050..0000000 +--- a/iscsiuio/src/uip/ipv6_ndpc.h ++++ /dev/null +@@ -1,98 +0,0 @@ +-/* +- * Copyright (c) 2011, Broadcom Corporation +- * Copyright (c) 2014, QLogic Corporation +- * +- * Written by: Eddie Wai (eddie.wai@broadcom.com) +- * +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. All advertising materials mentioning features or use of this software +- * must display the following acknowledgement: +- * This product includes software developed by Adam Dunkels. +- * 4. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * ipv6_ndpc.h - Top level IPv6 Network Discovery Protocol Engine (RFC4861) +- * +- */ +-#ifndef __NDPC_H__ +-#define __NDPC_H__ +- +-#include +- +-#include "nic.h" +-#include "timer.h" +-#include "pt.h" +- +-struct ndpc_reqptr { +- void *eth; +- void *ipv6; +-}; +- +-struct ndpc_state { +- struct pt pt; +- +- nic_t *nic; +- struct uip_stack *ustack; +- char state; +- struct timer timer; +- u16_t ticks; +- void *mac_addr; +- int mac_len; +- int retry_count; +- +- time_t last_update; +- +- void *ipv6_context; +- void *dhcpv6_context; +-}; +- +-enum { +- NDPC_STATE_INIT, +- NDPC_STATE_RTR_SOL, +- NDPC_STATE_RTR_ADV, +- NDPC_STATE_DHCPV6_DIS, +- NDPC_STATE_DHCPV6_DONE, +- NDPC_STATE_BACKGROUND_LOOP +-}; +- +-int ndpc_init(nic_t *nic, struct uip_stack *ustack, +- const void *mac_addr, int mac_len); +-void ndpc_call(struct uip_stack *ustack); +-void ndpc_exit(struct ndpc_state *ndp); +- +-enum { +- NEIGHBOR_SOLICIT, +- CHECK_LINK_LOCAL_ADDR, +- GET_LINK_LOCAL_ADDR, +- GET_DEFAULT_ROUTER_ADDR, +- CHECK_ARP_TABLE, +- GET_HOST_ADDR +-}; +- +-int ndpc_request(struct uip_stack *ustack, void *in, void *out, int request); +- +-#define UIP_NDP_CALL ndpc_call +- +-#endif /* __NDPC_H__ */ +diff --git a/iscsiuio/src/uip/ipv6_pkt.h b/iscsiuio/src/uip/ipv6_pkt.h +deleted file mode 100644 +index b42f1aa..0000000 +--- a/iscsiuio/src/uip/ipv6_pkt.h ++++ /dev/null +@@ -1,50 +0,0 @@ +-/* +- * Copyright (c) 2011, Broadcom Corporation +- * Copyright (c) 2014, QLogic Corporation +- * +- * Written by: Eddie Wai (eddie.wai@broadcom.com) +- * Based on Kevin Tran's iSCSI boot code +- * +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. All advertising materials mentioning features or use of this software +- * must display the following acknowledgement: +- * This product includes software developed by Adam Dunkels. +- * 4. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * ipv6_packet.h - IPv6 routine include file +- * +- */ +-#ifndef __IPV6_PKT_H__ +-#define __IPV6_PKT_H__ +- +-u16_t ipv6_process_rx(struct ipv6_hdr *ipv6); +-void ipv6_rx_packet(struct ipv6_context *context, u16_t len); +-void ipv6_setup_hdrs(struct ipv6_context *context, struct eth_hdr *eth, +- struct ipv6_hdr *ipv6, u16_t packet_len); +-int ipv6_send(struct ipv6_context *context, u16_t packet_len); +-void ipv6_send_udp_packet(struct ipv6_context *context, u16_t packet_len); +- +-#endif /* __IPV6_PKT_H__ */ +diff --git a/iscsiuio/src/uip/lc-addrlabels.h b/iscsiuio/src/uip/lc-addrlabels.h +deleted file mode 100644 +index c394b22..0000000 +--- a/iscsiuio/src/uip/lc-addrlabels.h ++++ /dev/null +@@ -1,80 +0,0 @@ +-/* +- * Copyright (c) 2004-2005, Swedish Institute of Computer Science. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. Neither the name of the Institute nor the names of its contributors +- * may be used to endorse or promote products derived from this software +- * without specific prior written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND +- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE +- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +- * SUCH DAMAGE. +- * +- * This file is part of the uIP TCP/IP stack +- * +- * Author: Adam Dunkels +- * +- */ +- +-/** +- * \addtogroup lc +- * @{ +- */ +- +-/** +- * \file +- * Implementation of local continuations based on the "Labels as +- * values" feature of gcc +- * \author +- * Adam Dunkels +- * +- * This implementation of local continuations is based on a special +- * feature of the GCC C compiler called "labels as values". This +- * feature allows assigning pointers with the address of the code +- * corresponding to a particular C label. +- * +- * For more information, see the GCC documentation: +- * http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html +- * +- * Thanks to dividuum for finding the nice local scope label +- * implementation. +- */ +- +-#ifndef __LC_ADDRLABELS_H__ +-#define __LC_ADDRLABELS_H__ +- +-/** \hideinitializer */ +- +-#define LC_INIT(s) (s = NULL) +- +-#define LC_RESUME(s) \ +- do { \ +- if (s != NULL) { \ +- goto *s; \ +- } \ +- } while (0) +- +-#define LC_SET(s) \ +- do { ({ __label__ resume; resume: (s) = &&resume; }); } while (0) +- +-#define LC_END(s) +- +-#endif /* __LC_ADDRLABELS_H__ */ +- +-/** @} */ +diff --git a/iscsiuio/src/uip/lc-switch.h b/iscsiuio/src/uip/lc-switch.h +deleted file mode 100644 +index 1839b36..0000000 +--- a/iscsiuio/src/uip/lc-switch.h ++++ /dev/null +@@ -1,73 +0,0 @@ +-/* +- * Copyright (c) 2004-2005, Swedish Institute of Computer Science. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. Neither the name of the Institute nor the names of its contributors +- * may be used to endorse or promote products derived from this software +- * without specific prior written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND +- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE +- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +- * SUCH DAMAGE. +- * +- * This file is part of the uIP TCP/IP stack +- * +- * Author: Adam Dunkels +- * +- */ +- +-/** +- * \addtogroup lc +- * @{ +- */ +- +-/** +- * \file +- * Implementation of local continuations based on switch() statment +- * \author Adam Dunkels +- * +- * This implementation of local continuations uses the C switch() +- * statement to resume execution of a function somewhere inside the +- * function's body. The implementation is based on the fact that +- * switch() statements are able to jump directly into the bodies of +- * control structures such as if() or while() statmenets. +- * +- * This implementation borrows heavily from Simon Tatham's coroutines +- * implementation in C: +- * http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html +- */ +- +-#ifndef __LC_SWITCH_H__ +-#define __LC_SWTICH_H__ +- +-/* WARNING! lc implementation using switch() does not work if an +- LC_SET() is done within another switch() statement! */ +- +-/** \hideinitializer */ +-#define LC_INIT(s) s = 0; +- +-#define LC_RESUME(s) switch (s) { case 0: +- +-#define LC_SET(s) s = __LINE__; case __LINE__: +- +-#define LC_END(s) } +- +-#endif /* __LC_SWITCH_H__ */ +- +-/** @} */ +diff --git a/iscsiuio/src/uip/lc.h b/iscsiuio/src/uip/lc.h +deleted file mode 100644 +index 2e4a7bb..0000000 +--- a/iscsiuio/src/uip/lc.h ++++ /dev/null +@@ -1,130 +0,0 @@ +-/* +- * Copyright (c) 2004-2005, Swedish Institute of Computer Science. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. Neither the name of the Institute nor the names of its contributors +- * may be used to endorse or promote products derived from this software +- * without specific prior written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND +- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE +- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +- * SUCH DAMAGE. +- * +- * This file is part of the uIP TCP/IP stack +- * +- * Author: Adam Dunkels +- * +- */ +- +-/** +- * \addtogroup pt +- * @{ +- */ +- +-/** +- * \defgroup lc Local continuations +- * @{ +- * +- * Local continuations form the basis for implementing protothreads. A +- * local continuation can be set in a specific function to +- * capture the state of the function. After a local continuation has +- * been set can be resumed in order to restore the state of the +- * function at the point where the local continuation was set. +- * +- * +- */ +- +-/** +- * \file lc.h +- * Local continuations +- * \author +- * Adam Dunkels +- * +- */ +- +-#ifdef DOXYGEN +-/** +- * Initialize a local continuation. +- * +- * This operation initializes the local continuation, thereby +- * unsetting any previously set continuation state. +- * +- * \hideinitializer +- */ +-#define LC_INIT(lc) +- +-/** +- * Set a local continuation. +- * +- * The set operation saves the state of the function at the point +- * where the operation is executed. As far as the set operation is +- * concerned, the state of the function does not include the +- * call-stack or local (automatic) variables, but only the program +- * counter and such CPU registers that needs to be saved. +- * +- * \hideinitializer +- */ +-#define LC_SET(lc) +- +-/** +- * Resume a local continuation. +- * +- * The resume operation resumes a previously set local continuation, thus +- * restoring the state in which the function was when the local +- * continuation was set. If the local continuation has not been +- * previously set, the resume operation does nothing. +- * +- * \hideinitializer +- */ +-#define LC_RESUME(lc) +- +-/** +- * Mark the end of local continuation usage. +- * +- * The end operation signifies that local continuations should not be +- * used any more in the function. This operation is not needed for +- * most implementations of local continuation, but is required by a +- * few implementations. +- * +- * \hideinitializer +- */ +-#define LC_END(lc) +- +-/** +- * \var typedef lc_t; +- * +- * The local continuation type. +- * +- * \hideinitializer +- */ +-#endif /* DOXYGEN */ +- +-#ifndef __LC_H__ +-#define __LC_H__ +- +-#ifdef LC_CONF_INCLUDE +-#include LC_CONF_INCLUDE +-#else +-#include "lc-switch.h" +-#endif /* LC_CONF_INCLUDE */ +- +-#endif /* __LC_H__ */ +- +-/** @} */ +-/** @} */ +diff --git a/iscsiuio/src/uip/psock.c b/iscsiuio/src/uip/psock.c +deleted file mode 100644 +index fcffbe7..0000000 +--- a/iscsiuio/src/uip/psock.c ++++ /dev/null +@@ -1,339 +0,0 @@ +-/* +- * Copyright (c) 2004, Swedish Institute of Computer Science. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. Neither the name of the Institute nor the names of its contributors +- * may be used to endorse or promote products derived from this software +- * without specific prior written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND +- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE +- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +- * SUCH DAMAGE. +- * +- * This file is part of the uIP TCP/IP stack +- * +- * Author: Adam Dunkels +- * +- */ +- +-#include +-#include +- +-#include "uipopt.h" +-#include "psock.h" +-#include "uip.h" +- +-#define STATE_NONE 0 +-#define STATE_ACKED 1 +-#define STATE_READ 2 +-#define STATE_BLOCKED_NEWDATA 3 +-#define STATE_BLOCKED_CLOSE 4 +-#define STATE_BLOCKED_SEND 5 +-#define STATE_DATA_SENT 6 +- +-/* +- * Return value of the buffering functions that indicates that a +- * buffer was not filled by incoming data. +- * +- */ +-#define BUF_NOT_FULL 0 +-#define BUF_NOT_FOUND 0 +- +-/* +- * Return value of the buffering functions that indicates that a +- * buffer was completely filled by incoming data. +- * +- */ +-#define BUF_FULL 1 +- +-/* +- * Return value of the buffering functions that indicates that an +- * end-marker byte was found. +- * +- */ +-#define BUF_FOUND 2 +- +-/*---------------------------------------------------------------------------*/ +-static void buf_setup(struct psock_buf *buf, u8_t *bufptr, u16_t bufsize) +-{ +- buf->ptr = bufptr; +- buf->left = bufsize; +-} +- +-/*---------------------------------------------------------------------------*/ +-static u8_t +-buf_bufdata(struct psock_buf *buf, u16_t len, u8_t **dataptr, u16_t *datalen) +-{ +- if (*datalen < buf->left) { +- memcpy(buf->ptr, *dataptr, *datalen); +- buf->ptr += *datalen; +- buf->left -= *datalen; +- *dataptr += *datalen; +- *datalen = 0; +- return BUF_NOT_FULL; +- } else if (*datalen == buf->left) { +- memcpy(buf->ptr, *dataptr, *datalen); +- buf->ptr += *datalen; +- buf->left = 0; +- *dataptr += *datalen; +- *datalen = 0; +- return BUF_FULL; +- } else { +- memcpy(buf->ptr, *dataptr, buf->left); +- buf->ptr += buf->left; +- *datalen -= buf->left; +- *dataptr += buf->left; +- buf->left = 0; +- return BUF_FULL; +- } +-} +- +-/*---------------------------------------------------------------------------*/ +-static u8_t +-buf_bufto(register struct psock_buf *buf, u8_t endmarker, +- register u8_t **dataptr, register u16_t *datalen) +-{ +- u8_t c; +- while (buf->left > 0 && *datalen > 0) { +- c = *buf->ptr = **dataptr; +- ++*dataptr; +- ++buf->ptr; +- --*datalen; +- --buf->left; +- +- if (c == endmarker) +- return BUF_FOUND; +- } +- +- if (*datalen == 0) +- return BUF_NOT_FOUND; +- +- while (*datalen > 0) { +- c = **dataptr; +- --*datalen; +- ++*dataptr; +- +- if (c == endmarker) +- return BUF_FOUND | BUF_FULL; +- } +- +- return BUF_FULL; +-} +- +-/*---------------------------------------------------------------------------*/ +-static char send_data(register struct psock *s) +-{ +- if (s->state != STATE_DATA_SENT || uip_rexmit(s->ustack)) { +- if (s->sendlen > uip_mss(s->ustack)) +- uip_appsend(s->ustack, s->sendptr, uip_mss(s->ustack)); +- else +- uip_appsend(s->ustack, s->sendptr, s->sendlen); +- s->state = STATE_DATA_SENT; +- return 1; +- } +- return 0; +-} +- +-/*---------------------------------------------------------------------------*/ +-static char data_acked(struct psock *s) +-{ +- if (s->state == STATE_DATA_SENT && uip_acked(s->ustack)) { +- if (s->sendlen > uip_mss(s->ustack)) { +- s->sendlen -= uip_mss(s->ustack); +- s->sendptr += uip_mss(s->ustack); +- } else { +- s->sendptr += s->sendlen; +- s->sendlen = 0; +- } +- s->state = STATE_ACKED; +- return 1; +- } +- return 0; +-} +- +-/*---------------------------------------------------------------------------*/ +-PT_THREAD(psock_send(struct uip_stack *ustack, +- register struct psock *s, const u8_t *buf, +- unsigned int len)) +-{ +- PT_BEGIN(&s->psockpt); +- +- /* If there is no data to send, we exit immediately. */ +- if (len == 0) { +- PT_EXIT(&s->psockpt); +- } +- +- /* Save the length of and a pointer to the data that is to be +- sent. */ +- s->sendptr = buf; +- s->sendlen = len; +- +- s->state = STATE_NONE; +- +- /* We loop here until all data is sent. The s->sendlen variable is +- updated by the data_sent() function. */ +- while (s->sendlen > 0) { +- +- /* +- * The condition for this PT_WAIT_UNTIL is a little tricky: the +- * protothread will wait here until all data has been acked +- * (data_acked() returns true) and until all data has been sent +- * (send_data() returns true). The two functions data_acked() +- * and send_data() must be called in succession to ensure that +- * all data is sent. Therefore the & operator is used instead of +- * the && operator, which would cause only the data_acked() +- * function to be called when it returns false. +- */ +- PT_WAIT_UNTIL(&s->psockpt, data_acked(s) & send_data(s)); +- } +- +- s->state = STATE_NONE; +- +- PT_END(&s->psockpt); +-} +- +-/*---------------------------------------------------------------------------*/ +-PT_THREAD(psock_generator_send(register struct psock *s, +- unsigned short (*generate) (void *), void *arg)) +-{ +- PT_BEGIN(&s->psockpt); +- +- /* Ensure that there is a generator function to call. */ +- if (generate == NULL) { +- PT_EXIT(&s->psockpt); +- } +- +- /* Call the generator function to generate the data in the +- uip_appdata buffer. */ +- s->sendlen = generate(arg); +- s->sendptr = s->ustack->uip_appdata; +- +- s->state = STATE_NONE; +- do { +- /* Call the generator function again if we are called to perform +- a retransmission. */ +- if (uip_rexmit(s->ustack)) +- generate(arg); +- /* Wait until all data is sent and acknowledged. */ +- PT_WAIT_UNTIL(&s->psockpt, data_acked(s) & send_data(s)); +- } while (s->sendlen > 0); +- +- s->state = STATE_NONE; +- +- PT_END(&s->psockpt); +-} +- +-/*---------------------------------------------------------------------------*/ +-u16_t psock_datalen(struct psock *psock) +-{ +- return psock->bufsize - psock->buf.left; +-} +- +-/*---------------------------------------------------------------------------*/ +-char psock_newdata(struct psock *s) +-{ +- if (s->readlen > 0) { +- /* There is data in the uip_appdata buffer that has not yet been +- read with the PSOCK_READ functions. */ +- return 1; +- } else if (s->state == STATE_READ) { +- /* All data in uip_appdata buffer already consumed. */ +- s->state = STATE_BLOCKED_NEWDATA; +- return 0; +- } else if (uip_newdata(s->ustack)) { +- /* There is new data that has not been consumed. */ +- return 1; +- } else { +- /* There is no new data. */ +- return 0; +- } +-} +- +-/*---------------------------------------------------------------------------*/ +-PT_THREAD(psock_readto(register struct psock *psock, u8_t c)) +-{ +- PT_BEGIN(&psock->psockpt); +- +- buf_setup(&psock->buf, psock->bufptr, psock->bufsize); +- +- /* XXX: Should add buf_checkmarker() before do{} loop, if +- incoming data has been handled while waiting for a write. */ +- +- do { +- if (psock->readlen == 0) { +- PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock)); +- psock->state = STATE_READ; +- psock->readptr = (u8_t *) psock->ustack->uip_appdata; +- psock->readlen = uip_datalen(psock->ustack); +- } +- } while ((buf_bufto(&psock->buf, c, +- &psock->readptr, +- &psock->readlen) & BUF_FOUND) == 0); +- +- if (psock_datalen(psock) == 0) { +- psock->state = STATE_NONE; +- PT_RESTART(&psock->psockpt); +- } +- PT_END(&psock->psockpt); +-} +- +-/*---------------------------------------------------------------------------*/ +-PT_THREAD(psock_readbuf(register struct psock *psock)) +-{ +- PT_BEGIN(&psock->psockpt); +- +- buf_setup(&psock->buf, psock->bufptr, psock->bufsize); +- +- /* XXX: Should add buf_checkmarker() before do{} loop, if +- incoming data has been handled while waiting for a write. */ +- +- do { +- if (psock->readlen == 0) { +- PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock)); +- printf("Waited for newdata\n"); +- psock->state = STATE_READ; +- psock->readptr = (u8_t *) psock->ustack->uip_appdata; +- psock->readlen = uip_datalen(psock->ustack); +- } +- } while (buf_bufdata(&psock->buf, psock->bufsize, +- &psock->readptr, &psock->readlen) != BUF_FULL); +- +- if (psock_datalen(psock) == 0) { +- psock->state = STATE_NONE; +- PT_RESTART(&psock->psockpt); +- } +- PT_END(&psock->psockpt); +-} +- +-/*---------------------------------------------------------------------------*/ +-void +-psock_init(struct uip_stack *ustack, +- register struct psock *psock, u8_t *buffer, unsigned int buffersize) +-{ +- psock->state = STATE_NONE; +- psock->readlen = 0; +- psock->bufptr = buffer; +- psock->bufsize = buffersize; +- psock->ustack = ustack; +- buf_setup(&psock->buf, buffer, buffersize); +- PT_INIT(&psock->pt); +- PT_INIT(&psock->psockpt); +-} +- +-/*---------------------------------------------------------------------------*/ +diff --git a/iscsiuio/src/uip/psock.h b/iscsiuio/src/uip/psock.h +deleted file mode 100644 +index ea86ef5..0000000 +--- a/iscsiuio/src/uip/psock.h ++++ /dev/null +@@ -1,383 +0,0 @@ +-/* +- * Copyright (c) 2004, Swedish Institute of Computer Science. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. Neither the name of the Institute nor the names of its contributors +- * may be used to endorse or promote products derived from this software +- * without specific prior written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND +- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE +- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +- * SUCH DAMAGE. +- * +- * This file is part of the uIP TCP/IP stack +- * +- * Author: Adam Dunkels +- * +- */ +- +-/** +- * \defgroup psock Protosockets library +- * @{ +- * +- * The protosocket library provides an interface to the uIP stack that is +- * similar to the traditional BSD socket interface. Unlike programs +- * written for the ordinary uIP event-driven interface, programs +- * written with the protosocket library are executed in a sequential +- * fashion and does not have to be implemented as explicit state +- * machines. +- * +- * Protosockets only work with TCP connections. +- * +- * The protosocket library uses \ref pt protothreads to provide +- * sequential control flow. This makes the protosockets lightweight in +- * terms of memory, but also means that protosockets inherits the +- * functional limitations of protothreads. Each protosocket lives only +- * within a single function. Automatic variables (stack variables) are +- * not retained across a protosocket library function call. +- * +- * \note Because the protosocket library uses protothreads, local +- * variables will not always be saved across a call to a protosocket +- * library function. It is therefore advised that local variables are +- * used with extreme care. +- * +- * The protosocket library provides functions for sending data without +- * having to deal with retransmissions and acknowledgements, as well +- * as functions for reading data without having to deal with data +- * being split across more than one TCP segment. +- * +- * Because each protosocket runs as a protothread, the protosocket has to be +- * started with a call to PSOCK_BEGIN() at the start of the function +- * in which the protosocket is used. Similarly, the protosocket protothread can +- * be terminated by a call to PSOCK_EXIT(). +- * +- */ +- +-/** +- * \file +- * Protosocket library header file +- * \author +- * Adam Dunkels +- * +- */ +- +-#ifndef __PSOCK_H__ +-#define __PSOCK_H__ +- +-#include "uip.h" +-#include "uipopt.h" +-#include "pt.h" +- +- /* +- * The structure that holds the state of a buffer. +- * +- * This structure holds the state of a uIP buffer. The structure has +- * no user-visible elements, but is used through the functions +- * provided by the library. +- * +- */ +-struct psock_buf { +- u8_t *ptr; +- unsigned short left; +-}; +- +-/** +- * The representation of a protosocket. +- * +- * The protosocket structrure is an opaque structure with no user-visible +- * elements. +- */ +-struct psock { +- struct pt pt, psockpt; /* Protothreads - one that's using the psock +- functions, and one that runs inside the +- psock functions. */ +- const u8_t *sendptr; /* Pointer to the next data to be sent. */ +- u8_t *readptr; /* Pointer to the next data to be read. */ +- +- u8_t *bufptr; /* Pointer to the buffer used for buffering +- incoming data. */ +- +- u16_t sendlen; /* The number of bytes left to be sent. */ +- u16_t readlen; /* The number of bytes left to be read. */ +- +- struct psock_buf buf; /* The structure holding the state of the +- input buffer. */ +- unsigned int bufsize; /* The size of the input buffer. */ +- +- unsigned char state; /* The state of the protosocket. */ +- +- struct uip_stack *ustack; +-}; +- +-void psock_init(struct uip_stack *ustack, +- struct psock *psock, u8_t *buffer, unsigned int buffersize); +-/** +- * Initialize a protosocket. +- * +- * This macro initializes a protosocket and must be called before the +- * protosocket is used. The initialization also specifies the input buffer +- * for the protosocket. +- * +- * \param psock (struct psock *) A pointer to the protosocket to be +- * initialized +- * +- * \param buffer (char *) A pointer to the input buffer for the +- * protosocket. +- * +- * \param buffersize (unsigned int) The size of the input buffer. +- * +- * \hideinitializer +- */ +-#define PSOCK_INIT(psock, buffer, buffersize) \ +- psock_init(psock, buffer, buffersize) +- +-/** +- * Start the protosocket protothread in a function. +- * +- * This macro starts the protothread associated with the protosocket and +- * must come before other protosocket calls in the function it is used. +- * +- * \param psock (struct psock *) A pointer to the protosocket to be +- * started. +- * +- * \hideinitializer +- */ +-#define PSOCK_BEGIN(psock) PT_BEGIN(&((psock)->pt)) +- +-PT_THREAD(psock_send(struct uip_stack *ustack, +- struct psock *psock, const u8_t *buf, unsigned int len)); +-/** +- * Send data. +- * +- * This macro sends data over a protosocket. The protosocket protothread blocks +- * until all data has been sent and is known to have been received by +- * the remote end of the TCP connection. +- * +- * \param psock (struct psock *) A pointer to the protosocket over which +- * data is to be sent. +- * +- * \param data (char *) A pointer to the data that is to be sent. +- * +- * \param datalen (unsigned int) The length of the data that is to be +- * sent. +- * +- * \hideinitializer +- */ +-#define PSOCK_SEND(psock, data, datalen) \ +- PT_WAIT_THREAD(&((psock)->pt), psock_send(psock, data, datalen)) +- +-/** +- * \brief Send a null-terminated string. +- * \param psock Pointer to the protosocket. +- * \param str The string to be sent. +- * +- * This function sends a null-terminated string over the +- * protosocket. +- * +- * \hideinitializer +- */ +-#define PSOCK_SEND_STR(psock, str) \ +- PT_WAIT_THREAD(&((psock)->pt), psock_send(psock, str, strlen(str))) +- +-PT_THREAD(psock_generator_send(struct psock *psock, +- unsigned short (*f) (void *), void *arg)); +- +-/** +- * \brief Generate data with a function and send it +- * \param psock Pointer to the protosocket. +- * \param generator Pointer to the generator function +- * \param arg Argument to the generator function +- * +- * This function generates data and sends it over the +- * protosocket. This can be used to dynamically generate +- * data for a transmission, instead of generating the data +- * in a buffer beforehand. This function reduces the need for +- * buffer memory. The generator function is implemented by +- * the application, and a pointer to the function is given +- * as an argument with the call to PSOCK_GENERATOR_SEND(). +- * +- * The generator function should place the generated data +- * directly in the uip_appdata buffer, and return the +- * length of the generated data. The generator function is +- * called by the protosocket layer when the data first is +- * sent, and once for every retransmission that is needed. +- * +- * \hideinitializer +- */ +-#define PSOCK_GENERATOR_SEND(psock, generator, arg) \ +- PT_WAIT_THREAD(&((psock)->pt), \ +- psock_generator_send(psock, generator, arg)) +- +-/** +- * Close a protosocket. +- * +- * This macro closes a protosocket and can only be called from within the +- * protothread in which the protosocket lives. +- * +- * \param psock (struct psock *) A pointer to the protosocket that is to +- * be closed. +- * +- * \hideinitializer +- */ +-#define PSOCK_CLOSE(psock) uip_close() +- +-PT_THREAD(psock_readbuf(struct psock *psock)); +-/** +- * Read data until the buffer is full. +- * +- * This macro will block waiting for data and read the data into the +- * input buffer specified with the call to PSOCK_INIT(). Data is read +- * until the buffer is full.. +- * +- * \param psock (struct psock *) A pointer to the protosocket from which +- * data should be read. +- * +- * \hideinitializer +- */ +-#define PSOCK_READBUF(psock) \ +- PT_WAIT_THREAD(&((psock)->pt), psock_readbuf(psock)) +- +-PT_THREAD(psock_readto(struct psock *psock, unsigned char c)); +-/** +- * Read data up to a specified character. +- * +- * This macro will block waiting for data and read the data into the +- * input buffer specified with the call to PSOCK_INIT(). Data is only +- * read until the specifieed character appears in the data stream. +- * +- * \param psock (struct psock *) A pointer to the protosocket from which +- * data should be read. +- * +- * \param c (char) The character at which to stop reading. +- * +- * \hideinitializer +- */ +-#define PSOCK_READTO(psock, c) \ +- PT_WAIT_THREAD(&((psock)->pt), psock_readto(psock, c)) +- +-/** +- * The length of the data that was previously read. +- * +- * This macro returns the length of the data that was previously read +- * using PSOCK_READTO() or PSOCK_READ(). +- * +- * \param psock (struct psock *) A pointer to the protosocket holding the data. +- * +- * \hideinitializer +- */ +-#define PSOCK_DATALEN(psock) psock_datalen(psock) +- +-u16_t psock_datalen(struct psock *psock); +- +-/** +- * Exit the protosocket's protothread. +- * +- * This macro terminates the protothread of the protosocket and should +- * almost always be used in conjunction with PSOCK_CLOSE(). +- * +- * \sa PSOCK_CLOSE_EXIT() +- * +- * \param psock (struct psock *) A pointer to the protosocket. +- * +- * \hideinitializer +- */ +-#define PSOCK_EXIT(psock) PT_EXIT(&((psock)->pt)) +- +-/** +- * Close a protosocket and exit the protosocket's protothread. +- * +- * This macro closes a protosocket and exits the protosocket's protothread. +- * +- * \param psock (struct psock *) A pointer to the protosocket. +- * +- * \hideinitializer +- */ +-#define PSOCK_CLOSE_EXIT(psock) \ +- do { \ +- PSOCK_CLOSE(psock); \ +- PSOCK_EXIT(psock); \ +- } while (0) +- +-/** +- * Declare the end of a protosocket's protothread. +- * +- * This macro is used for declaring that the protosocket's protothread +- * ends. It must always be used together with a matching PSOCK_BEGIN() +- * macro. +- * +- * \param psock (struct psock *) A pointer to the protosocket. +- * +- * \hideinitializer +- */ +-#define PSOCK_END(psock) PT_END(&((psock)->pt)) +- +-char psock_newdata(struct psock *s); +- +-/** +- * Check if new data has arrived on a protosocket. +- * +- * This macro is used in conjunction with the PSOCK_WAIT_UNTIL() +- * macro to check if data has arrived on a protosocket. +- * +- * \param psock (struct psock *) A pointer to the protosocket. +- * +- * \hideinitializer +- */ +-#define PSOCK_NEWDATA(psock) psock_newdata(psock) +- +-/** +- * Wait until a condition is true. +- * +- * This macro blocks the protothread until the specified condition is +- * true. The macro PSOCK_NEWDATA() can be used to check if new data +- * arrives when the protosocket is waiting. +- * +- * Typically, this macro is used as follows: +- * +- \code +- PT_THREAD(thread(struct psock *s, struct timer *t)) +- { +- PSOCK_BEGIN(s); +- +- PSOCK_WAIT_UNTIL(s, PSOCK_NEWADATA(s) || timer_expired(t)); +- +- if(PSOCK_NEWDATA(s)) { +- PSOCK_READTO(s, '\n'); +- } else { +- handle_timed_out(s); +- } +- +- PSOCK_END(s); +- } +- \endcode +- * +- * \param psock (struct psock *) A pointer to the protosocket. +- * \param condition The condition to wait for. +- * +- * \hideinitializer +- */ +-#define PSOCK_WAIT_UNTIL(psock, condition) \ +- PT_WAIT_UNTIL(&((psock)->pt), (condition)); +- +-#define PSOCK_WAIT_THREAD(psock, condition) \ +- PT_WAIT_THREAD(&((psock)->pt), (condition)) +- +-#endif /* __PSOCK_H__ */ +- +-/** @} */ +diff --git a/iscsiuio/src/uip/pt.h b/iscsiuio/src/uip/pt.h +deleted file mode 100644 +index ffb1d15..0000000 +--- a/iscsiuio/src/uip/pt.h ++++ /dev/null +@@ -1,322 +0,0 @@ +-/* +- * Copyright (c) 2004-2005, Swedish Institute of Computer Science. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. Neither the name of the Institute nor the names of its contributors +- * may be used to endorse or promote products derived from this software +- * without specific prior written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND +- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE +- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +- * SUCH DAMAGE. +- * +- * This file is part of the uIP TCP/IP stack +- * +- * Author: Adam Dunkels +- * +- */ +- +-/** +- * \addtogroup pt +- * @{ +- */ +- +-/** +- * \file +- * Protothreads implementation. +- * \author +- * Adam Dunkels +- * +- */ +- +-#ifndef __PT_H__ +-#define __PT_H__ +- +-#include "lc.h" +- +-struct pt { +- unsigned short lc; +-}; +- +-#define PT_WAITING 0 +-#define PT_EXITED 1 +-#define PT_ENDED 2 +-#define PT_YIELDED 3 +- +-/** +- * \name Initialization +- * @{ +- */ +- +-/** +- * Initialize a protothread. +- * +- * Initializes a protothread. Initialization must be done prior to +- * starting to execute the protothread. +- * +- * \param pt A pointer to the protothread control structure. +- * +- * \sa PT_SPAWN() +- * +- * \hideinitializer +- */ +-#define PT_INIT(pt) LC_INIT((pt)->lc) +- +-/** @} */ +- +-/** +- * \name Declaration and definition +- * @{ +- */ +- +-/** +- * Declaration of a protothread. +- * +- * This macro is used to declare a protothread. All protothreads must +- * be declared with this macro. +- * +- * \param name_args The name and arguments of the C function +- * implementing the protothread. +- * +- * \hideinitializer +- */ +-#define PT_THREAD(name_args) char name_args +- +-/** +- * Declare the start of a protothread inside the C function +- * implementing the protothread. +- * +- * This macro is used to declare the starting point of a +- * protothread. It should be placed at the start of the function in +- * which the protothread runs. All C statements above the PT_BEGIN() +- * invokation will be executed each time the protothread is scheduled. +- * +- * \param pt A pointer to the protothread control structure. +- * +- * \hideinitializer +- */ +-#define PT_BEGIN(pt) { char PT_YIELD_FLAG __attribute__((__unused__)) = 1; LC_RESUME((pt)->lc) +- +-/** +- * Declare the end of a protothread. +- * +- * This macro is used for declaring that a protothread ends. It must +- * always be used together with a matching PT_BEGIN() macro. +- * +- * \param pt A pointer to the protothread control structure. +- * +- * \hideinitializer +- */ +-#define PT_END(pt) LC_END((pt)->lc); PT_YIELD_FLAG = 0; \ +- PT_INIT(pt); return PT_ENDED; } +- +-/** @} */ +- +-/** +- * \name Blocked wait +- * @{ +- */ +- +-/** +- * Block and wait until condition is true. +- * +- * This macro blocks the protothread until the specified condition is +- * true. +- * +- * \param pt A pointer to the protothread control structure. +- * \param condition The condition. +- * +- * \hideinitializer +- */ +-#define PT_WAIT_UNTIL(pt, condition) \ +- do { \ +- LC_SET((pt)->lc); \ +- if (!(condition)) { \ +- return PT_WAITING; \ +- } \ +- } while (0) +- +-/** +- * Block and wait while condition is true. +- * +- * This function blocks and waits while condition is true. See +- * PT_WAIT_UNTIL(). +- * +- * \param pt A pointer to the protothread control structure. +- * \param cond The condition. +- * +- * \hideinitializer +- */ +-#define PT_WAIT_WHILE(pt, cond) PT_WAIT_UNTIL((pt), !(cond)) +- +-/** @} */ +- +-/** +- * \name Hierarchical protothreads +- * @{ +- */ +- +-/** +- * Block and wait until a child protothread completes. +- * +- * This macro schedules a child protothread. The current protothread +- * will block until the child protothread completes. +- * +- * \note The child protothread must be manually initialized with the +- * PT_INIT() function before this function is used. +- * +- * \param pt A pointer to the protothread control structure. +- * \param thread The child protothread with arguments +- * +- * \sa PT_SPAWN() +- * +- * \hideinitializer +- */ +-#define PT_WAIT_THREAD(pt, thread) PT_WAIT_WHILE((pt), PT_SCHEDULE(thread)) +- +-/** +- * Spawn a child protothread and wait until it exits. +- * +- * This macro spawns a child protothread and waits until it exits. The +- * macro can only be used within a protothread. +- * +- * \param pt A pointer to the protothread control structure. +- * \param child A pointer to the child protothread's control structure. +- * \param thread The child protothread with arguments +- * +- * \hideinitializer +- */ +-#define PT_SPAWN(pt, child, thread) \ +- do { \ +- PT_INIT((child)); \ +- PT_WAIT_THREAD((pt), (thread)); \ +- } while (0) +- +-/** @} */ +- +-/** +- * \name Exiting and restarting +- * @{ +- */ +- +-/** +- * Restart the protothread. +- * +- * This macro will block and cause the running protothread to restart +- * its execution at the place of the PT_BEGIN() call. +- * +- * \param pt A pointer to the protothread control structure. +- * +- * \hideinitializer +- */ +-#define PT_RESTART(pt) \ +- do { \ +- PT_INIT(pt); \ +- return PT_WAITING; \ +- } while (0) +- +-/** +- * Exit the protothread. +- * +- * This macro causes the protothread to exit. If the protothread was +- * spawned by another protothread, the parent protothread will become +- * unblocked and can continue to run. +- * +- * \param pt A pointer to the protothread control structure. +- * +- * \hideinitializer +- */ +-#define PT_EXIT(pt) \ +- do { \ +- PT_INIT(pt); \ +- return PT_EXITED; \ +- } while (0) +- +-/** @} */ +- +-/** +- * \name Calling a protothread +- * @{ +- */ +- +-/** +- * Schedule a protothread. +- * +- * This function shedules a protothread. The return value of the +- * function is non-zero if the protothread is running or zero if the +- * protothread has exited. +- * +- * \param f The call to the C function implementing the protothread to +- * be scheduled +- * +- * \hideinitializer +- */ +-#define PT_SCHEDULE(f) ((f) == PT_WAITING) +- +-/** @} */ +- +-/** +- * \name Yielding from a protothread +- * @{ +- */ +- +-/** +- * Yield from the current protothread. +- * +- * This function will yield the protothread, thereby allowing other +- * processing to take place in the system. +- * +- * \param pt A pointer to the protothread control structure. +- * +- * \hideinitializer +- */ +-#define PT_YIELD(pt) \ +- do { \ +- PT_YIELD_FLAG = 0; \ +- LC_SET((pt)->lc); \ +- if (PT_YIELD_FLAG == 0) { \ +- return PT_YIELDED; \ +- } \ +- } while (0) +- +-/** +- * \brief Yield from the protothread until a condition occurs. +- * \param pt A pointer to the protothread control structure. +- * \param cond The condition. +- * +- * This function will yield the protothread, until the +- * specified condition evaluates to true. +- * +- * +- * \hideinitializer +- */ +-#define PT_YIELD_UNTIL(pt, cond) \ +- do { \ +- PT_YIELD_FLAG = 0; \ +- LC_SET((pt)->lc); \ +- if ((PT_YIELD_FLAG == 0) || !(cond)) { \ +- return PT_YIELDED; \ +- } \ +- } while (0) +- +-/** @} */ +- +-#endif /* __PT_H__ */ +- +-/** @} */ +diff --git a/iscsiuio/src/uip/timer.c b/iscsiuio/src/uip/timer.c +deleted file mode 100644 +index da77148..0000000 +--- a/iscsiuio/src/uip/timer.c ++++ /dev/null +@@ -1,127 +0,0 @@ +-/** +- * \addtogroup timer +- * @{ +- */ +- +-/** +- * \file +- * Timer library implementation. +- * \author +- * Adam Dunkels +- */ +- +-/* +- * Copyright (c) 2004, Swedish Institute of Computer Science. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. Neither the name of the Institute nor the names of its contributors +- * may be used to endorse or promote products derived from this software +- * without specific prior written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND +- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE +- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +- * SUCH DAMAGE. +- * +- * This file is part of the uIP TCP/IP stack +- * +- * Author: Adam Dunkels +- * +- */ +- +-#include "clock.h" +-#include "timer.h" +- +-/*---------------------------------------------------------------------------*/ +-/** +- * Set a timer. +- * +- * This function is used to set a timer for a time sometime in the +- * future. The function timer_expired() will evaluate to true after +- * the timer has expired. +- * +- * \param t A pointer to the timer +- * \param interval The interval before the timer expires. +- * +- */ +-void timer_set(struct timer *t, clock_time_t interval) +-{ +- t->interval = interval; +- t->start = clock_time(); +-} +- +-/*---------------------------------------------------------------------------*/ +-/** +- * Reset the timer with the same interval. +- * +- * This function resets the timer with the same interval that was +- * given to the timer_set() function. The start point of the interval +- * is the exact time that the timer last expired. Therefore, this +- * function will cause the timer to be stable over time, unlike the +- * timer_rester() function. +- * +- * \param t A pointer to the timer. +- * +- * \sa timer_restart() +- */ +-void timer_reset(struct timer *t) +-{ +- t->start += t->interval; +-} +- +-/*---------------------------------------------------------------------------*/ +-/** +- * Restart the timer from the current point in time +- * +- * This function restarts a timer with the same interval that was +- * given to the timer_set() function. The timer will start at the +- * current time. +- * +- * \note A periodic timer will drift if this function is used to reset +- * it. For preioric timers, use the timer_reset() function instead. +- * +- * \param t A pointer to the timer. +- * +- * \sa timer_reset() +- */ +-void timer_restart(struct timer *t) +-{ +- t->start = clock_time(); +-} +- +-/*---------------------------------------------------------------------------*/ +-/** +- * Check if a timer has expired. +- * +- * This function tests if a timer has expired and returns true or +- * false depending on its status. +- * +- * \param t A pointer to the timer +- * +- * \return Non-zero if the timer has expired, zero otherwise. +- * +- */ +-int timer_expired(struct timer *t) +-{ +- return (clock_time_t) (clock_time() - t->start) >= +- (clock_time_t) t->interval; +-} +- +-/*---------------------------------------------------------------------------*/ +- +-/** @} */ +diff --git a/iscsiuio/src/uip/timer.h b/iscsiuio/src/uip/timer.h +deleted file mode 100644 +index 12739fd..0000000 +--- a/iscsiuio/src/uip/timer.h ++++ /dev/null +@@ -1,84 +0,0 @@ +-/** +- * \defgroup timer Timer library +- * +- * The timer library provides functions for setting, resetting and +- * restarting timers, and for checking if a timer has expired. An +- * application must "manually" check if its timers have expired; this +- * is not done automatically. +- * +- * A timer is declared as a \c struct \c timer and all access to the +- * timer is made by a pointer to the declared timer. +- * +- * \note The timer library uses the \ref clock "Clock library" to +- * measure time. Intervals should be specified in the format used by +- * the clock library. +- * +- * @{ +- */ +- +-/** +- * \file +- * Timer library header file. +- * \author +- * Adam Dunkels +- */ +- +-/* +- * Copyright (c) 2004, Swedish Institute of Computer Science. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. Neither the name of the Institute nor the names of its contributors +- * may be used to endorse or promote products derived from this software +- * without specific prior written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND +- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE +- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +- * SUCH DAMAGE. +- * +- * This file is part of the uIP TCP/IP stack +- * +- * Author: Adam Dunkels +- * +- */ +-#ifndef __TIMER_H__ +-#define __TIMER_H__ +- +-#include "clock.h" +- +-/** +- * A timer. +- * +- * This structure is used for declaring a timer. The timer must be set +- * with timer_set() before it can be used. +- * +- * \hideinitializer +- */ +-struct timer { +- clock_time_t start; +- clock_time_t interval; +-}; +- +-void timer_set(struct timer *t, clock_time_t interval); +-void timer_reset(struct timer *t); +-void timer_restart(struct timer *t); +-int timer_expired(struct timer *t); +- +-#endif /* __TIMER_H__ */ +- +-/** @} */ +diff --git a/iscsiuio/src/uip/uip-neighbor.c b/iscsiuio/src/uip/uip-neighbor.c +deleted file mode 100644 +index 4c80c32..0000000 +--- a/iscsiuio/src/uip/uip-neighbor.c ++++ /dev/null +@@ -1,219 +0,0 @@ +-/* +- * Copyright (c) 2006, Swedish Institute of Computer Science. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. Neither the name of the Institute nor the names of its contributors +- * may be used to endorse or promote products derived from this software +- * without specific prior written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND +- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE +- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +- * SUCH DAMAGE. +- * +- * This file is part of the uIP TCP/IP stack +- * +- */ +- +-/** +- * \file +- * Database of link-local neighbors, used by IPv6 code and +- * to be used by a future ARP code rewrite. +- * \author +- * Adam Dunkels +- */ +- +-#include "logger.h" +-#include "uip.h" +-#include "uip-neighbor.h" +- +-#include +-#include +-#include +- +-/******************************************************************************* +- * Constants +- ******************************************************************************/ +-#define PFX "uip-neigh " +- +-#define MAX_TIME 128 +- +-/*---------------------------------------------------------------------------*/ +-void uip_neighbor_init(struct uip_stack *ustack) +-{ +- int i; +- +- pthread_mutex_lock(&ustack->lock); +- for (i = 0; i < UIP_NEIGHBOR_ENTRIES; ++i) { +- memset(&(ustack->neighbor_entries[i].ipaddr), 0, +- sizeof(ustack->neighbor_entries[i].ipaddr)); +- memset(&(ustack->neighbor_entries[i].mac_addr), 0, +- sizeof(ustack->neighbor_entries[i].mac_addr)); +- ustack->neighbor_entries[i].time = MAX_TIME; +- } +- pthread_mutex_unlock(&ustack->lock); +-} +- +-void uip_neighbor_add(struct uip_stack *ustack, +- struct in6_addr *addr6, struct uip_eth_addr *addr) +-{ +- int i, oldest; +- u8_t oldest_time; +- char buf[INET6_ADDRSTRLEN]; +- +- inet_ntop(AF_INET6, addr6, buf, sizeof(buf)); +- +- pthread_mutex_lock(&ustack->lock); +- +- /* Find the first unused entry or the oldest used entry. */ +- oldest_time = 0; +- oldest = 0; +- for (i = 0; i < UIP_NEIGHBOR_ENTRIES; ++i) { +- if (ustack->neighbor_entries[i].time == MAX_TIME) { +- oldest = i; +- break; +- } +- if (uip_ip6addr_cmp +- (ustack->neighbor_entries[i].ipaddr.s6_addr, addr6)) { +- oldest = i; +- break; +- } +- if (ustack->neighbor_entries[i].time > oldest_time) { +- oldest = i; +- oldest_time = ustack->neighbor_entries[i].time; +- } +- } +- +- /* Use the oldest or first free entry (either pointed to by the +- "oldest" variable). */ +- ustack->neighbor_entries[oldest].time = 0; +- uip_ip6addr_copy(ustack->neighbor_entries[oldest].ipaddr.s6_addr, +- addr6); +- memcpy(&ustack->neighbor_entries[oldest].mac_addr, addr, +- sizeof(struct uip_eth_addr)); +- +- LOG_DEBUG("Adding neighbor %s with " +- "mac address %02x:%02x:%02x:%02x:%02x:%02x at %d", +- buf, addr->addr[0], addr->addr[1], addr->addr[2], +- addr->addr[3], addr->addr[4], addr->addr[5], oldest); +- +- pthread_mutex_unlock(&ustack->lock); +-} +- +-/*---------------------------------------------------------------------------*/ +-static struct neighbor_entry *find_entry(struct uip_stack *ustack, +- struct in6_addr *addr6) +-{ +- int i; +- +- for (i = 0; i < UIP_NEIGHBOR_ENTRIES; ++i) { +- if (uip_ip6addr_cmp +- (ustack->neighbor_entries[i].ipaddr.s6_addr, +- addr6->s6_addr)) { +- return &ustack->neighbor_entries[i]; +- } +- } +- +- return NULL; +-} +- +-/*---------------------------------------------------------------------------*/ +-void uip_neighbor_update(struct uip_stack *ustack, struct in6_addr *addr6) +-{ +- struct neighbor_entry *e; +- +- pthread_mutex_lock(&ustack->lock); +- +- e = find_entry(ustack, addr6); +- if (e != NULL) +- e->time = 0; +- +- pthread_mutex_unlock(&ustack->lock); +-} +- +-/*---------------------------------------------------------------------------*/ +-int uip_neighbor_lookup(struct uip_stack *ustack, +- struct in6_addr *addr6, uint8_t *mac_addr) +-{ +- struct neighbor_entry *e; +- +- pthread_mutex_lock(&ustack->lock); +- e = find_entry(ustack, addr6); +- if (e != NULL) { +- char addr6_str[INET6_ADDRSTRLEN]; +- uint8_t *entry_mac_addr; +- +- addr6_str[0] = '\0'; +- inet_ntop(AF_INET6, addr6->s6_addr, addr6_str, +- sizeof(addr6_str)); +- entry_mac_addr = (uint8_t *)&e->mac_addr.addr; +- +- LOG_DEBUG(PFX +- "Found %s at %02x:%02x:%02x:%02x:%02x:%02x", +- addr6_str, +- entry_mac_addr[0], entry_mac_addr[1], +- entry_mac_addr[2], entry_mac_addr[3], +- entry_mac_addr[4], entry_mac_addr[5]); +- +- memcpy(mac_addr, entry_mac_addr, sizeof(e->mac_addr)); +- pthread_mutex_unlock(&ustack->lock); +- return 0; +- } +- +- pthread_mutex_unlock(&ustack->lock); +- return -ENOENT; +-} +- +-void uip_neighbor_out(struct uip_stack *ustack) +-{ +- struct neighbor_entry *e; +- struct uip_eth_hdr *eth_hdr = +- (struct uip_eth_hdr *)ustack->data_link_layer; +- struct uip_ipv6_hdr *ipv6_hdr = +- (struct uip_ipv6_hdr *)ustack->network_layer; +- +- pthread_mutex_lock(&ustack->lock); +- +- /* Find the destination IP address in the neighbor table and construct +- the Ethernet header. If the destination IP addres isn't on the +- local network, we use the default router's IP address instead. +- +- If not ARP table entry is found, we overwrite the original IP +- packet with an ARP request for the IP address. */ +- e = find_entry(ustack, (struct in6_addr *)ipv6_hdr->destipaddr); +- if (e == NULL) { +- struct uip_eth_addr eth_addr_tmp; +- +- memcpy(ð_addr_tmp, eth_hdr->src.addr, sizeof(eth_addr_tmp)); +- memcpy(eth_hdr->src.addr, ustack->uip_ethaddr.addr, +- sizeof(eth_hdr->src.addr)); +- memcpy(eth_hdr->dest.addr, ð_addr_tmp, +- sizeof(eth_hdr->dest.addr)); +- +- pthread_mutex_unlock(&ustack->lock); +- return; +- } +- +- memcpy(eth_hdr->dest.addr, &e->mac_addr, sizeof(eth_hdr->dest.addr)); +- memcpy(eth_hdr->src.addr, ustack->uip_ethaddr.addr, +- sizeof(eth_hdr->src.addr)); +- +- pthread_mutex_unlock(&ustack->lock); +-} +- +-/*---------------------------------------------------------------------------*/ +diff --git a/iscsiuio/src/uip/uip-neighbor.h b/iscsiuio/src/uip/uip-neighbor.h +deleted file mode 100644 +index d10c57b..0000000 +--- a/iscsiuio/src/uip/uip-neighbor.h ++++ /dev/null +@@ -1,105 +0,0 @@ +-/* +- * Copyright (c) 2006, Swedish Institute of Computer Science. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. Neither the name of the Institute nor the names of its contributors +- * may be used to endorse or promote products derived from this software +- * without specific prior written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND +- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE +- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +- * SUCH DAMAGE. +- * +- * This file is part of the uIP TCP/IP stack +- * +- */ +- +-/** +- * \file +- * Header file for database of link-local neighbors, used by +- * IPv6 code and to be used by future ARP code. +- * \author +- * Adam Dunkels +- */ +- +-#ifndef __UIP_NEIGHBOR_H__ +-#define __UIP_NEIGHBOR_H__ +- +-#include "uip.h" +-#include "uip_eth.h" +- +-/* ICMP types */ +-/* ICMPv6 error Messages */ +-#define ICMPV6_DEST_UNREACH 1 +-#define ICMPV6_PKT_TOOBIG 2 +-#define ICMPV6_TIME_EXCEED 3 +-#define ICMPV6_PARAMPROB 4 +- +-/* ICMPv6 Informational Messages */ +-#define ICMPV6_ECHO_REQUEST 128 +-#define ICMPV6_ECHO_REPLY 129 +-#define ICMPV6_MGM_QUERY 130 +-#define ICMPV6_MGM_REPORT 131 +-#define ICMPV6_MGM_REDUCTION 132 +- +-/* Codes for Destination Unreachable */ +-#define ICMPV6_NOROUTE 0 +-#define ICMPV6_ADM_PROHIBITED 1 +-#define ICMPV6_NOT_NEIGHBOUR 2 +-#define ICMPV6_ADDR_UNREACH 3 +-#define ICMPV6_PORT_UNREACH 4 +- +-/* Codes for Time Exceeded */ +-#define ICMPV6_EXC_HOPLIMIT 0 +-#define ICMPV6_EXC_FRAGTIME 1 +- +-/* Codes for Parameter Problem */ +-#define ICMPV6_HDR_FIELD 0 +-#define ICMPV6_UNK_NEXTHDR 1 +-#define ICMPV6_UNK_OPTION 2 +- +-#if 0 +-struct __attribute__ ((__packed__)) icmpv6_hdr { +- u8_t type; +- u8_t code; +- u16_t checksum; +- union { +- struct { +- u16_t id; +- u16_t sequence; +- } echo; +- u32_t gateway; +- struct { +- u16_t unused; +- u16_t mtu; +- } frag; +- } un; +-}; +-#endif +- +-void uip_neighbor_init(struct uip_stack *ustack); +-void uip_neighbor_add(struct uip_stack *ustack, +- struct in6_addr *addr6, struct uip_eth_addr *addr); +-void uip_neighbor_update(struct uip_stack *ustack, struct in6_addr *addr6); +-int uip_neighbor_lookup(struct uip_stack *ustack, struct in6_addr *ipaddr, +- uint8_t *mac_addr); +-void uip_neighbor_periodic(void); +-void uip_neighbor_out(struct uip_stack *ustack); +- +-#endif /* __UIP-NEIGHBOR_H__ */ +diff --git a/iscsiuio/src/uip/uip.c b/iscsiuio/src/uip/uip.c +deleted file mode 100644 +index e0a7221..0000000 +--- a/iscsiuio/src/uip/uip.c ++++ /dev/null +@@ -1,2434 +0,0 @@ +-#include +-#include +-#include +-#include +-#include +-#include "uip.h" +-#include "dhcpc.h" +-#include "ipv6_ndpc.h" +-#include "brcm_iscsi.h" +-#include "ping.h" +- +-/** +- * \defgroup uip The uIP TCP/IP stack +- * @{ +- * +- * uIP is an implementation of the TCP/IP protocol stack intended for +- * small 8-bit and 16-bit microcontrollers. +- * +- * uIP provides the necessary protocols for Internet communication, +- * with a very small code footprint and RAM requirements - the uIP +- * code size is on the order of a few kilobytes and RAM usage is on +- * the order of a few hundred bytes. +- */ +- +-/** +- * \file +- * The uIP TCP/IP stack code. +- * \author Adam Dunkels +- */ +- +-/* +- * Copyright (c) 2001-2003, Adam Dunkels. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * This file is part of the uIP TCP/IP stack. +- * +- * +- */ +- +-/* +- * uIP is a small implementation of the IP, UDP and TCP protocols (as +- * well as some basic ICMP stuff). The implementation couples the IP, +- * UDP, TCP and the application layers very tightly. To keep the size +- * of the compiled code down, this code frequently uses the goto +- * statement. While it would be possible to break the uip_process() +- * function into many smaller functions, this would increase the code +- * size because of the overhead of parameter passing and the fact that +- * the optimier would not be as efficient. +- * +- * The principle is that we have a small buffer, called the uip_buf, +- * in which the device driver puts an incoming packet. The TCP/IP +- * stack parses the headers in the packet, and calls the +- * application. If the remote host has sent data to the application, +- * this data is present in the uip_buf and the application read the +- * data from there. It is up to the application to put this data into +- * a byte stream if needed. The application will not be fed with data +- * that is out of sequence. +- * +- * If the application whishes to send data to the peer, it should put +- * its data into the uip_buf. The uip_appdata pointer points to the +- * first available byte. The TCP/IP stack will calculate the +- * checksums, and fill in the necessary header fields and finally send +- * the packet back to the peer. +-*/ +- +-#include "logger.h" +- +-#include "uip.h" +-#include "uipopt.h" +-#include "uip_arch.h" +-#include "uip_eth.h" +-#include "uip-neighbor.h" +- +-#include +- +-/******************************************************************************* +- * Constants +- ******************************************************************************/ +-#define PFX "uip " +- +-static const uip_ip4addr_t all_ones_addr4 = { 0xffff, 0xffff }; +- +-const uip_ip6addr_t all_zeroes_addr6 = { +- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 +-}; +-const uip_ip4addr_t all_zeroes_addr4 = { 0x0000, 0x0000 }; +- +-const uint8_t mutlicast_ipv6_prefix[16] = { +- 0xfc, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +-}; +- +-const uint8_t link_local_addres_prefix[16] = { +- 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +-}; +-const uint32_t link_local_address_prefix_length = 10; +- +-/* Structures and definitions. */ +-#define TCP_FIN 0x01 +-#define TCP_SYN 0x02 +-#define TCP_RST 0x04 +-#define TCP_PSH 0x08 +-#define TCP_ACK 0x10 +-#define TCP_URG 0x20 +-#define TCP_CTL 0x3f +- +-#define TCP_OPT_END 0 /* End of TCP options list */ +-#define TCP_OPT_NOOP 1 /* "No-operation" TCP option */ +-#define TCP_OPT_MSS 2 /* Maximum segment size TCP option */ +- +-#define TCP_OPT_MSS_LEN 4 /* Length of TCP MSS option. */ +- +-#define ICMP_ECHO_REPLY 0 +-#define ICMP_ECHO 8 +- +-#define ICMP6_ECHO_REPLY 129 +-#define ICMP6_ECHO 128 +-#define ICMP6_NEIGHBOR_SOLICITATION 135 +-#define ICMP6_NEIGHBOR_ADVERTISEMENT 136 +- +-#define ICMP6_FLAG_S (1 << 6) +- +-#define ICMP6_OPTION_SOURCE_LINK_ADDRESS 1 +-#define ICMP6_OPTION_TARGET_LINK_ADDRESS 2 +- +-/* Macros. */ +-#define FBUF ((struct uip_tcpip_hdr *)&uip_reassbuf[0]) +-#define UDPBUF(ustack) ((struct uip_udpip_hdr *)ustack->network_layer) +- +-/****************************************************************************** +- * Utility Functions +- *****************************************************************************/ +-static int is_ipv6(struct uip_stack *ustack) +-{ +- u16_t type; +- +- type = ETH_BUF(ustack->uip_buf)->type; +- type = ntohs(type); +- if (type == UIP_ETHTYPE_8021Q) +- type = ntohs(VLAN_ETH_BUF(ustack->uip_buf)->type); +- else +- type = ntohs(ETH_BUF(ustack->uip_buf)->type); +- +- return (type == UIP_ETHTYPE_IPv6); +-} +- +-int is_ipv6_link_local_address(uip_ip6addr_t *addr) +-{ +- u8_t *test_adddr = (u8_t *) addr; +- u8_t test_remainder; +- +- if (test_adddr[0] != link_local_addres_prefix[0]) +- return 0; +- +- test_remainder = (test_adddr[1] & 0xC0) >> 6; +- if (test_remainder != 2) +- return 0; +- +- return 1; +-} +- +-void uip_sethostaddr4(struct uip_stack *ustack, uip_ip4addr_t *addr) +-{ +- pthread_mutex_lock(&ustack->lock); +- uip_ip4addr_copy(ustack->hostaddr, (addr)); +- pthread_mutex_unlock(&ustack->lock); +-} +- +-void uip_setdraddr4(struct uip_stack *ustack, uip_ip4addr_t *addr) +-{ +- pthread_mutex_lock(&ustack->lock); +- uip_ip4addr_copy(ustack->default_route_addr, (addr)); +- pthread_mutex_unlock(&ustack->lock); +-} +- +-void uip_setnetmask4(struct uip_stack *ustack, uip_ip4addr_t *addr) +-{ +- pthread_mutex_lock(&ustack->lock); +- uip_ip4addr_copy(ustack->netmask, (addr)); +- pthread_mutex_unlock(&ustack->lock); +-} +- +-void uip_setethernetmac(struct uip_stack *ustack, uint8_t *mac) +-{ +- pthread_mutex_lock(&ustack->lock); +- memcpy(ustack->uip_ethaddr.addr, (mac), 6); +- pthread_mutex_unlock(&ustack->lock); +-} +- +-void set_uip_stack(struct uip_stack *ustack, +- uip_ip4addr_t *ip, +- uip_ip4addr_t *netmask, +- uip_ip4addr_t *default_route, uint8_t *mac_addr) +-{ +- if (ip) +- uip_sethostaddr4(ustack, ip); +- if (netmask) +- uip_setnetmask4(ustack, netmask); +- if (default_route) +- uip_setdraddr4(ustack, default_route); +- if (mac_addr) +- uip_setethernetmac(ustack, mac_addr); +-} +- +-#if !UIP_ARCH_ADD32 +-void uip_add32(u8_t *op32, u16_t op16, u8_t *uip_acc32) +-{ +- uip_acc32[3] = op32[3] + (op16 & 0xff); +- uip_acc32[2] = op32[2] + (op16 >> 8); +- uip_acc32[1] = op32[1]; +- uip_acc32[0] = op32[0]; +- +- if (uip_acc32[2] < (op16 >> 8)) { +- ++uip_acc32[1]; +- if (uip_acc32[1] == 0) +- ++uip_acc32[0]; +- } +- +- if (uip_acc32[3] < (op16 & 0xff)) { +- ++uip_acc32[2]; +- if (uip_acc32[2] == 0) { +- ++uip_acc32[1]; +- if (uip_acc32[1] == 0) +- ++uip_acc32[0]; +- } +- } +-} +- +-#endif /* UIP_ARCH_ADD32 */ +- +-#if !UIP_ARCH_CHKSUM +-/*---------------------------------------------------------------------------*/ +-static u16_t chksum(u16_t sum, const u8_t *data, u16_t len) +-{ +- u16_t t; +- const u8_t *dataptr; +- const u8_t *last_byte; +- +- dataptr = data; +- last_byte = data + len - 1; +- +- while (dataptr < last_byte) { /* At least two more bytes */ +- t = (dataptr[0] << 8) + dataptr[1]; +- sum += t; +- if (sum < t) +- sum++; /* carry */ +- dataptr += 2; +- } +- +- if (dataptr == last_byte) { +- t = (dataptr[0] << 8) + 0; +- sum += t; +- if (sum < t) +- sum++; /* carry */ +- } +- +- /* Return sum in host byte order. */ +- return sum; +-} +- +-/*---------------------------------------------------------------------------*/ +-u16_t uip_chksum(u16_t *data, u16_t len) +-{ +- return htons(chksum(0, (u8_t *)data, len)); +-} +- +-/*---------------------------------------------------------------------------*/ +-#ifndef UIP_ARCH_IPCHKSUM +-u16_t uip_ipchksum(struct uip_stack *ustack) +-{ +- u16_t sum; +- u16_t uip_iph_len; +- +- if (is_ipv6(ustack)) +- uip_iph_len = UIP_IPv6_H_LEN; +- else +- uip_iph_len = UIP_IPv4_H_LEN; +- +- sum = chksum(0, ustack->network_layer, uip_iph_len); +- return (sum == 0) ? 0xffff : htons(sum); +-} +-#endif +- +-/*---------------------------------------------------------------------------*/ +-static u16_t upper_layer_chksum_ipv4(struct uip_stack *ustack, u8_t proto) +-{ +- u16_t upper_layer_len; +- u16_t sum; +- struct uip_tcp_ipv4_hdr *tcp_ipv4_hdr = NULL; +- +- tcp_ipv4_hdr = (struct uip_tcp_ipv4_hdr *)ustack->network_layer; +- +- upper_layer_len = (((u16_t) (tcp_ipv4_hdr->len[0]) << 8) + +- tcp_ipv4_hdr->len[1]); +- /* check for underflow from an invalid length field */ +- if (upper_layer_len < UIP_IPv4_H_LEN) { +- /* return 0 as an invalid checksum */ +- return 0; +- } +- upper_layer_len -= UIP_IPv4_H_LEN; +- +- /* First sum pseudoheader. */ +- /* IP protocol and length fields. This addition cannot carry. */ +- sum = upper_layer_len + proto; +- +- sum = +- chksum(sum, (u8_t *)&tcp_ipv4_hdr->srcipaddr[0], +- 2 * sizeof(uip_ip4addr_t)); +- /* Sum TCP header and data. */ +- sum = chksum(sum, ustack->network_layer + UIP_IPv4_H_LEN, +- upper_layer_len); +- +- return (sum == 0) ? 0xffff : htons(sum); +-} +- +-/*---------------------------------------------------------------------------*/ +-static uint16_t upper_layer_checksum_ipv6(uint8_t *data, uint8_t proto) +-{ +- uint16_t upper_layer_len; +- uint16_t sum; +- struct ip6_hdr *ipv6_hdr; +- uint8_t *upper_layer; +- uint32_t val; +- +- ipv6_hdr = (struct ip6_hdr *)data; +- +- upper_layer_len = ntohs(ipv6_hdr->ip6_plen); +- +- /* First sum pseudoheader. */ +- sum = 0; +- sum = chksum(sum, (const u8_t *)ipv6_hdr->ip6_src.s6_addr, +- sizeof(ipv6_hdr->ip6_src)); +- sum = chksum(sum, (const u8_t *)ipv6_hdr->ip6_dst.s6_addr, +- sizeof(ipv6_hdr->ip6_dst)); +- +- val = htons(upper_layer_len); +- sum = chksum(sum, (u8_t *)&val, sizeof(val)); +- +- val = htons(proto); +- sum = chksum(sum, (u8_t *)&val, sizeof(val)); +- +- upper_layer = (uint8_t *)(ipv6_hdr + 1); +- sum = chksum(sum, upper_layer, upper_layer_len); +- +- return (sum == 0) ? 0xffff : htons(sum); +-} +- +-/*---------------------------------------------------------------------------*/ +- +-u16_t uip_icmp6chksum(struct uip_stack *ustack) +-{ +- uint8_t *data = ustack->network_layer; +- +- return upper_layer_checksum_ipv6(data, UIP_PROTO_ICMP6); +-} +- +-uint16_t icmpv6_checksum(uint8_t *data) +-{ +- return upper_layer_checksum_ipv6(data, IPPROTO_ICMPV6); +-} +- +-/*---------------------------------------------------------------------------*/ +-u16_t uip_tcpchksum(struct uip_stack *ustack) +-{ +- return upper_layer_chksum_ipv4(ustack, UIP_PROTO_TCP); +-} +- +-/*---------------------------------------------------------------------------*/ +-#if UIP_UDP_CHECKSUMS +-static u16_t uip_udpchksum_ipv4(struct uip_stack *ustack) +-{ +- return upper_layer_chksum_ipv4(ustack, UIP_PROTO_UDP); +-} +- +-static u16_t uip_udpchksum_ipv6(struct uip_stack *ustack) +-{ +- uint8_t *data = ustack->network_layer; +- +- return upper_layer_checksum_ipv6(data, UIP_PROTO_UDP); +-} +- +-u16_t uip_udpchksum(struct uip_stack *ustack) +-{ +- if (is_ipv6(ustack)) +- return uip_udpchksum_ipv6(ustack); +- else +- return uip_udpchksum_ipv4(ustack); +-} +-#endif /* UIP_UDP_CHECKSUMS */ +-#endif /* UIP_ARCH_CHKSUM */ +-/*---------------------------------------------------------------------------*/ +-void uip_init(struct uip_stack *ustack, uint8_t ipv6_enabled) +-{ +- u8_t c; +- +- for (c = 0; c < UIP_LISTENPORTS; ++c) +- ustack->uip_listenports[c] = 0; +- for (c = 0; c < UIP_CONNS; ++c) +- ustack->uip_conns[c].tcpstateflags = UIP_CLOSED; +-#if UIP_ACTIVE_OPEN +- ustack->lastport = 1024; +-#endif /* UIP_ACTIVE_OPEN */ +- +-#if UIP_UDP +- for (c = 0; c < UIP_UDP_CONNS; ++c) +- ustack->uip_udp_conns[c].lport = 0; +-#endif /* UIP_UDP */ +- +- /* IPv4 initialization. */ +-#if UIP_FIXEDADDR == 0 +- /* uip_hostaddr[0] = uip_hostaddr[1] = 0; */ +-#endif /* UIP_FIXEDADDR */ +- +- /* zero out the uIP statistics */ +- memset(&ustack->stats, 0, sizeof(ustack->stats)); +- +- /* prepare the uIP lock */ +- pthread_mutex_init(&ustack->lock, NULL); +- +- if (ipv6_enabled) +- ustack->enable_IPv6 = UIP_SUPPORT_IPv6_ENABLED; +- else +- ustack->enable_IPv6 = UIP_SUPPORT_IPv6_DISABLED; +- +- ustack->dhcpc = NULL; +- ustack->ndpc = NULL; +- ustack->ping_conf = NULL; +-} +-void uip_reset(struct uip_stack *ustack) +-{ +- /* There was an associated DHCP object, this memory needs to be +- * freed */ +- if (ustack->dhcpc) +- free(ustack->dhcpc); +- +- ndpc_exit(ustack->ndpc); +- +- memset(ustack, 0, sizeof(*ustack)); +-} +- +-/*---------------------------------------------------------------------------*/ +-#if UIP_ACTIVE_OPEN +-struct uip_conn *uip_connect(struct uip_stack *ustack, uip_ip4addr_t *ripaddr, +- u16_t rport) +-{ +- u8_t c; +- register struct uip_conn *conn, *cconn; +- +- /* Find an unused local port. */ +-again: +- ++ustack->lastport; +- +- if (ustack->lastport >= 32000) +- ustack->lastport = 4096; +- +- /* Check if this port is already in use, and if so try to find +- another one. */ +- for (c = 0; c < UIP_CONNS; ++c) { +- conn = &ustack->uip_conns[c]; +- if (conn->tcpstateflags != UIP_CLOSED && +- conn->lport == htons(ustack->lastport)) { +- goto again; +- } +- } +- +- conn = 0; +- for (c = 0; c < UIP_CONNS; ++c) { +- cconn = &ustack->uip_conns[c]; +- if (cconn->tcpstateflags == UIP_CLOSED) { +- conn = cconn; +- break; +- } +- if (cconn->tcpstateflags == UIP_TIME_WAIT) { +- if (conn == 0 || cconn->timer > conn->timer) +- conn = cconn; +- } +- } +- +- if (conn == 0) +- return 0; +- +- conn->tcpstateflags = UIP_SYN_SENT; +- +- conn->snd_nxt[0] = ustack->iss[0]; +- conn->snd_nxt[1] = ustack->iss[1]; +- conn->snd_nxt[2] = ustack->iss[2]; +- conn->snd_nxt[3] = ustack->iss[3]; +- +- conn->initialmss = conn->mss = UIP_TCP_MSS; +- +- conn->len = 1; /* TCP length of the SYN is one. */ +- conn->nrtx = 0; +- conn->timer = 1; /* Send the SYN next time around. */ +- conn->rto = UIP_RTO; +- conn->sa = 0; +- conn->sv = 16; /* Initial value of the RTT variance. */ +- conn->lport = htons(ustack->lastport); +- conn->rport = rport; +- uip_ip4addr_copy(&conn->ripaddr, ripaddr); +- +- return conn; +-} +-#endif /* UIP_ACTIVE_OPEN */ +-/*---------------------------------------------------------------------------*/ +-#if UIP_UDP +-struct uip_udp_conn *uip_udp_new(struct uip_stack *ustack, +- uip_ip4addr_t *ripaddr, u16_t rport) +-{ +- u8_t c; +- register struct uip_udp_conn *conn; +- +- /* Find an unused local port. */ +-again: +- ++ustack->lastport; +- +- if (ustack->lastport >= 32000) +- ustack->lastport = 4096; +- +- for (c = 0; c < UIP_UDP_CONNS; ++c) { +- if (ustack->uip_udp_conns[c].lport == htons(ustack->lastport)) +- goto again; +- } +- +- conn = 0; +- for (c = 0; c < UIP_UDP_CONNS; ++c) { +- if (ustack->uip_udp_conns[c].lport == 0) { +- conn = &ustack->uip_udp_conns[c]; +- break; +- } +- } +- +- if (conn == 0) +- return 0; +- +- conn->lport = htons(ustack->lastport); +- conn->rport = rport; +- if (ripaddr == NULL) +- memset(conn->ripaddr, 0, sizeof(uip_ip4addr_t)); +- else +- uip_ip4addr_copy(&conn->ripaddr, ripaddr); +- conn->ttl = UIP_TTL; +- +- return conn; +-} +-#endif /* UIP_UDP */ +-/*---------------------------------------------------------------------------*/ +-void uip_unlisten(struct uip_stack *ustack, u16_t port) +-{ +- u8_t c; +- +- for (c = 0; c < UIP_LISTENPORTS; ++c) { +- if (ustack->uip_listenports[c] == port) { +- ustack->uip_listenports[c] = 0; +- return; +- } +- } +-} +- +-/*---------------------------------------------------------------------------*/ +-void uip_listen(struct uip_stack *ustack, u16_t port) +-{ +- u8_t c; +- +- for (c = 0; c < UIP_LISTENPORTS; ++c) { +- if (ustack->uip_listenports[c] == 0) { +- ustack->uip_listenports[c] = port; +- return; +- } +- } +-} +- +-/** +- * Is new incoming data available? +- * +- * Will reduce to non-zero if there is new data for the application +- * present at the uip_appdata pointer. The size of the data is +- * avaliable through the uip_len variable. +- * +- * \hideinitializer +- */ +-int uip_newdata(struct uip_stack *ustack) +-{ +- return ustack->uip_flags & UIP_NEWDATA; +-} +- +-/** +- * Has previously sent data been acknowledged? +- * +- * Will reduce to non-zero if the previously sent data has been +- * acknowledged by the remote host. This means that the application +- * can send new data. +- * +- * \hideinitializer +- */ +-#define uip_acked() (uip_flags & UIP_ACKDATA) +- +-/** +- * Has the connection just been connected? +- * +- * Reduces to non-zero if the current connection has been connected to +- * a remote host. This will happen both if the connection has been +- * actively opened (with uip_connect()) or passively opened (with +- * uip_listen()). +- * +- * \hideinitializer +- */ +-int uip_connected(struct uip_stack *ustack) +-{ +- return ustack->uip_flags & UIP_CONNECTED; +-} +- +-/** +- * Has the connection been closed by the other end? +- * +- * Is non-zero if the connection has been closed by the remote +- * host. The application may then do the necessary clean-ups. +- * +- * \hideinitializer +- */ +-int uip_closed(struct uip_stack *ustack) +-{ +- return ustack->uip_flags & UIP_CLOSE; +-} +- +-/** +- * Has the connection been aborted by the other end? +- * +- * Non-zero if the current connection has been aborted (reset) by the +- * remote host. +- * +- * \hideinitializer +- */ +-int uip_aborted(struct uip_stack *ustack) +-{ +- return ustack->uip_flags & UIP_ABORT; +-} +- +-/** +- * Has the connection timed out? +- * +- * Non-zero if the current connection has been aborted due to too many +- * retransmissions. +- * +- * \hideinitializer +- */ +-int uip_timedout(struct uip_stack *ustack) +-{ +- return ustack->uip_flags & UIP_TIMEDOUT; +-} +- +-/** +- * Do we need to retransmit previously data? +- * +- * Reduces to non-zero if the previously sent data has been lost in +- * the network, and the application should retransmit it. The +- * application should send the exact same data as it did the last +- * time, using the uip_send() function. +- * +- * \hideinitializer +- */ +-int uip_rexmit(struct uip_stack *ustack) +-{ +- return ustack->uip_flags & UIP_REXMIT; +-} +- +-/** +- * Is the connection being polled by uIP? +- * +- * Is non-zero if the reason the application is invoked is that the +- * current connection has been idle for a while and should be +- * polled. +- * +- * The polling event can be used for sending data without having to +- * wait for the remote host to send data. +- * +- * \hideinitializer +- */ +-int uip_poll(struct uip_stack *ustack) +-{ +- return ustack->uip_flags & UIP_POLL; +-} +- +-int uip_initialmss(struct uip_stack *ustack) +-{ +- return ustack->uip_conn->initialmss; +-} +- +-int uip_mss(struct uip_stack *ustack) +-{ +- return ustack->uip_conn->mss; +-} +- +-/*---------------------------------------------------------------------------*/ +-/* XXX: IP fragment reassembly: not well-tested. */ +- +-#if UIP_REASSEMBLY && !UIP_CONF_IPV6 +-#define UIP_REASS_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN) +-static u8_t uip_reassbuf[UIP_REASS_BUFSIZE]; +-static u8_t uip_reassbitmap[UIP_REASS_BUFSIZE / (8 * 8)]; +-static const u8_t bitmap_bits[8] = { 0xff, 0x7f, 0x3f, 0x1f, +- 0x0f, 0x07, 0x03, 0x01 +-}; +-static u16_t uip_reasslen; +-static u8_t uip_reassflags; +-#define UIP_REASS_FLAG_LASTFRAG 0x01 +-static u8_t uip_reasstmr; +- +-#define IP_MF 0x20 +- +-static u8_t uip_reass(void) +-{ +- u16_t offset, len; +- u16_t i; +- +- /* If ip_reasstmr is zero, no packet is present in the buffer, so we +- write the IP header of the fragment into the reassembly +- buffer. The timer is updated with the maximum age. */ +- if (uip_reasstmr == 0) { +- memcpy(uip_reassbuf, &BUF(ustack)->vhl, uip_iph_len); +- uip_reasstmr = UIP_REASS_MAXAGE; +- uip_reassflags = 0; +- /* Clear the bitmap. */ +- memset(uip_reassbitmap, 0, sizeof(uip_reassbitmap)); +- } +- +- /* Check if the incoming fragment matches the one currently present +- in the reasembly buffer. If so, we proceed with copying the +- fragment into the buffer. */ +- if (BUF(ustack)->srcipaddr[0] == FBUF(ustack)->srcipaddr[0] && +- BUF(ustack)->srcipaddr[1] == FBUF(ustack)->srcipaddr[1] && +- BUF(ustack)->destipaddr[0] == FBUF(ustack)->destipaddr[0] && +- BUF(ustack)->destipaddr[1] == FBUF(ustack)->destipaddr[1] && +- BUF(ustack)->ipid[0] == FBUF(ustack)->ipid[0] && +- BUF(ustack)->ipid[1] == FBUF(ustack)->ipid[1]) { +- +- len = +- (BUF(ustack)->len[0] << 8) + BUF(ustack)->len[1] - +- (BUF(ustack)->vhl & 0x0f) * 4; +- offset = +- (((BUF(ustack)->ipoffset[0] & 0x3f) << 8) + +- BUF(ustack)->ipoffset[1]) * 8; +- +- /* If the offset or the offset + fragment length overflows the +- reassembly buffer, we discard the entire packet. */ +- if (offset > UIP_REASS_BUFSIZE || +- offset + len > UIP_REASS_BUFSIZE) { +- uip_reasstmr = 0; +- goto nullreturn; +- } +- +- /* Copy the fragment into the reassembly buffer, at the right +- offset. */ +- memcpy(&uip_reassbuf[uip_iph_len + offset], +- (char *)BUF + (int)((BUF(ustack)->vhl & 0x0f) * 4), len); +- +- /* Update the bitmap. */ +- if (offset / (8 * 8) == (offset + len) / (8 * 8)) { +- /* If the two endpoints are in the same byte, we only +- update that byte. */ +- +- uip_reassbitmap[offset / (8 * 8)] |= +- bitmap_bits[(offset / 8) & 7] & +- ~bitmap_bits[((offset + len) / 8) & 7]; +- } else { +- /* If the two endpoints are in different bytes, we +- update the bytes in the endpoints and fill the +- stuff inbetween with 0xff. */ +- uip_reassbitmap[offset / (8 * 8)] |= +- bitmap_bits[(offset / 8) & 7]; +- for (i = 1 + offset / (8 * 8); +- i < (offset + len) / (8 * 8); ++i) { +- uip_reassbitmap[i] = 0xff; +- } +- uip_reassbitmap[(offset + len) / (8 * 8)] |= +- ~bitmap_bits[((offset + len) / 8) & 7]; +- } +- +- /* If this fragment has the More Fragments flag set to zero, we +- know that this is the last fragment, so we can calculate the +- size of the entire packet. We also set the +- IP_REASS_FLAG_LASTFRAG flag to indicate that we have received +- the final fragment. */ +- +- if ((BUF(ustack)->ipoffset[0] & IP_MF) == 0) { +- uip_reassflags |= UIP_REASS_FLAG_LASTFRAG; +- uip_reasslen = offset + len; +- } +- +- /* Finally, we check if we have a full packet in the buffer. +- We do this by checking if we have the last fragment and if +- all bits in the bitmap are set. */ +- if (uip_reassflags & UIP_REASS_FLAG_LASTFRAG) { +- /* Check all bytes up to and including all but the last +- byte in the bitmap. */ +- for (i = 0; i < uip_reasslen / (8 * 8) - 1; ++i) { +- if (uip_reassbitmap[i] != 0xff) +- goto nullreturn; +- } +- /* Check the last byte in the bitmap. It should contain +- just the right amount of bits. */ +- if (uip_reassbitmap[uip_reasslen / (8 * 8)] != +- (u8_t) ~bitmap_bits[uip_reasslen / 8 & 7]) +- goto nullreturn; +- +- /* If we have come this far, we have a full packet in +- the buffer, so we allocate a pbuf and copy the +- packet into it. We also reset the timer. */ +- uip_reasstmr = 0; +- memcpy(BUF, FBUF, uip_reasslen); +- +- /* Pretend to be a "normal" (i.e., not fragmented) IP +- packet from now on. */ +- BUF(ustack)->ipoffset[0] = BUF(ustack)->ipoffset[1] = 0; +- BUF(ustack)->len[0] = uip_reasslen >> 8; +- BUF(ustack)->len[1] = uip_reasslen & 0xff; +- BUF(ustack)->ipchksum = 0; +- BUF(ustack)->ipchksum = ~(uip_ipchksum()); +- +- return uip_reasslen; +- } +- } +- +-nullreturn: +- return 0; +-} +-#endif /* UIP_REASSEMBLY */ +-/*---------------------------------------------------------------------------*/ +-static void uip_add_rcv_nxt(struct uip_stack *ustack, u16_t n) +-{ +- u8_t uip_acc32[4]; +- +- uip_add32(ustack->uip_conn->rcv_nxt, n, uip_acc32); +- ustack->uip_conn->rcv_nxt[0] = uip_acc32[0]; +- ustack->uip_conn->rcv_nxt[1] = uip_acc32[1]; +- ustack->uip_conn->rcv_nxt[2] = uip_acc32[2]; +- ustack->uip_conn->rcv_nxt[3] = uip_acc32[3]; +-} +- +-/*---------------------------------------------------------------------------*/ +- +-/** @} */ +- +-/** +- * \defgroup uipdevfunc uIP device driver functions +- * @{ +- * +- * These functions are used by a network device driver for interacting +- * with uIP. +- */ +- +-/** +- * Process an incoming packet. +- * +- * This function should be called when the device driver has received +- * a packet from the network. The packet from the device driver must +- * be present in the uip_buf buffer, and the length of the packet +- * should be placed in the uip_len variable. +- * +- * When the function returns, there may be an outbound packet placed +- * in the uip_buf packet buffer. If so, the uip_len variable is set to +- * the length of the packet. If no packet is to be sent out, the +- * uip_len variable is set to 0. +- * +- * The usual way of calling the function is presented by the source +- * code below. +- \code +- uip_len = devicedriver_poll(); +- if(uip_len > 0) { +- uip_input(); +- if(uip_len > 0) { +- devicedriver_send(); +- } +- } +- \endcode +- * +- * \note If you are writing a uIP device driver that needs ARP +- * (Address Resolution Protocol), e.g., when running uIP over +- * Ethernet, you will need to call the uIP ARP code before calling +- * this function: +- \code +- #define BUF ((struct uip_eth_hdr *)&uip_buf[0]) +- uip_len = ethernet_devicedrver_poll(); +- if(uip_len > 0) { +- if (BUF(ustack)->type == HTONS(UIP_ETHTYPE_IP)) { +- uip_arp_ipin(); +- uip_input(); +- if (uip_len > 0) { +- uip_arp_out(); +- ethernet_devicedriver_send(); +- } +- } else if (BUF(ustack)->type == HTONS(UIP_ETHTYPE_ARP)) { +- uip_arp_arpin(); +- if (uip_len > 0) +- ethernet_devicedriver_send(); +- } +- \endcode +- * +- * \hideinitializer +- */ +-void uip_input(struct uip_stack *ustack) +-{ +- uip_process(ustack, UIP_DATA); +-} +- +-/** +- * Periodic processing for a connection identified by its number. +- * +- * This function does the necessary periodic processing (timers, +- * polling) for a uIP TCP conneciton, and should be called when the +- * periodic uIP timer goes off. It should be called for every +- * connection, regardless of whether they are open of closed. +- * +- * When the function returns, it may have an outbound packet waiting +- * for service in the uIP packet buffer, and if so the uip_len +- * variable is set to a value larger than zero. The device driver +- * should be called to send out the packet. +- * +- * The ususal way of calling the function is through a for() loop like +- * this: +- \code +- for(i = 0; i < UIP_CONNS; ++i) { +- uip_periodic(i); +- if(uip_len > 0) { +- devicedriver_send(); +- } +- } +- \endcode +- * +- * \note If you are writing a uIP device driver that needs ARP +- * (Address Resolution Protocol), e.g., when running uIP over +- * Ethernet, you will need to call the uip_arp_out() function before +- * calling the device driver: +- \code +- for(i = 0; i < UIP_CONNS; ++i) { +- uip_periodic(i); +- if(uip_len > 0) { +- uip_arp_out(); +- ethernet_devicedriver_send(); +- } +- } +- \endcode +- * +- * \param conn The number of the connection which is to be periodically polled. +- * +- * \hideinitializer +- */ +-void uip_periodic(struct uip_stack *ustack, int conn) +-{ +- ustack->uip_conn = &ustack->uip_conns[conn]; +- uip_process(ustack, UIP_TIMER); +-} +- +-#if UIP_UDP +-/** +- * Periodic processing for a UDP connection identified by its number. +- * +- * This function is essentially the same as uip_periodic(), but for +- * UDP connections. It is called in a similar fashion as the +- * uip_periodic() function: +- \code +- for(i = 0; i < UIP_UDP_CONNS; i++) { +- uip_udp_periodic(i); +- if(uip_len > 0) { +- devicedriver_send(); +- } +- } +- \endcode +- * +- * \note As for the uip_periodic() function, special care has to be +- * taken when using uIP together with ARP and Ethernet: +- \code +- for(i = 0; i < UIP_UDP_CONNS; i++) { +- uip_udp_periodic(i); +- if(uip_len > 0) { +- uip_arp_out(); +- ethernet_devicedriver_send(); +- } +- } +- \endcode +- * +- * \param conn The number of the UDP connection to be processed. +- * +- * \hideinitializer +- */ +-void uip_udp_periodic(struct uip_stack *ustack, int conn) +-{ +- ustack->uip_udp_conn = &ustack->uip_udp_conns[conn]; +- uip_process(ustack, UIP_UDP_TIMER); +-} +-#endif +- +-void uip_ndp_periodic(struct uip_stack *ustack) +-{ +- uip_process(ustack, UIP_NDP_TIMER); +-} +- +-void uip_process(struct uip_stack *ustack, u8_t flag) +-{ +- u8_t c; +- u16_t tmp16; +- register struct uip_conn *uip_connr = ustack->uip_conn; +- +- u16_t uip_iph_len = 0; +- u16_t uip_ip_udph_len = 0; +- u16_t uip_ip_tcph_len = 0; +- struct ip6_hdr *ipv6_hdr = NULL; +- struct uip_tcp_ipv4_hdr *tcp_ipv4_hdr = NULL; +- struct uip_tcp_hdr *tcp_hdr = NULL; +- struct uip_icmpv4_hdr *icmpv4_hdr = NULL; +- struct uip_icmpv6_hdr *icmpv6_hdr __attribute__((__unused__)) = NULL; +- struct uip_udp_hdr *udp_hdr = NULL; +- +- /* Drop invalid packets */ +- if (ustack->uip_buf == NULL) { +- LOG_ERR(PFX "ustack->uip_buf == NULL."); +- return; +- } +- +- if (is_ipv6(ustack)) { +- uint8_t *buf; +- uip_iph_len = UIP_IPv6_H_LEN; +- uip_ip_udph_len = UIP_IPv6_UDPH_LEN; +- uip_ip_tcph_len = UIP_IPv6_TCPH_LEN; +- +- ipv6_hdr = (struct ip6_hdr *)ustack->network_layer; +- +- buf = ustack->network_layer; +- buf += sizeof(struct uip_ipv6_hdr); +- tcp_hdr = (struct uip_tcp_hdr *)buf; +- +- buf = ustack->network_layer; +- buf += sizeof(struct uip_ipv6_hdr); +- udp_hdr = (struct uip_udp_hdr *)buf; +- +- buf = ustack->network_layer; +- buf += sizeof(struct uip_ipv6_hdr); +- icmpv6_hdr = (struct uip_icmpv6_hdr *)buf; +- } else { +- uint8_t *buf; +- +- uip_iph_len = UIP_IPv4_H_LEN; +- uip_ip_udph_len = UIP_IPv4_UDPH_LEN; +- uip_ip_tcph_len = UIP_IPv4_TCPH_LEN; +- +- tcp_ipv4_hdr = (struct uip_tcp_ipv4_hdr *)ustack->network_layer; +- +- buf = ustack->network_layer; +- buf += sizeof(struct uip_ipv4_hdr); +- tcp_hdr = (struct uip_tcp_hdr *)buf; +- +- buf = ustack->network_layer; +- buf += sizeof(struct uip_ipv4_hdr); +- icmpv4_hdr = (struct uip_icmpv4_hdr *)buf; +- +- buf = ustack->network_layer; +- buf += sizeof(struct uip_ipv4_hdr); +- udp_hdr = (struct uip_udp_hdr *)buf; +- } /* End of ipv6 */ +- +-#if UIP_UDP +- if (flag == UIP_UDP_SEND_CONN) +- goto udp_send; +-#endif /* UIP_UDP */ +- ustack->uip_sappdata = ustack->uip_appdata = ustack->network_layer + +- uip_ip_tcph_len; +- +- /* Check if we were invoked because of a poll request for a +- particular connection. */ +- if (flag == UIP_POLL_REQUEST) { +- if ((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED +- && !uip_outstanding(uip_connr)) { +- ustack->uip_flags = UIP_POLL; +- UIP_APPCALL(ustack); +- goto appsend; +- } +- goto drop; +- +- /* Check if we were invoked because of the perodic timer +- firing. */ +- } else if (flag == UIP_TIMER) { +-#if UIP_REASSEMBLY +- if (uip_reasstmr != 0) +- --uip_reasstmr; +-#endif /* UIP_REASSEMBLY */ +- /* Increase the initial sequence number. */ +- if (++ustack->iss[3] == 0) { +- if (++ustack->iss[2] == 0) { +- if (++ustack->iss[1] == 0) +- ++ustack->iss[0]; +- } +- } +- +- /* Reset the length variables. */ +- ustack->uip_len = 0; +- ustack->uip_slen = 0; +- +- /* Check if the connection is in a state in which we simply wait +- for the connection to time out. If so, we increase the +- connection's timer and remove the connection if it times +- out. */ +- if (uip_connr->tcpstateflags == UIP_TIME_WAIT || +- uip_connr->tcpstateflags == UIP_FIN_WAIT_2) { +- ++(uip_connr->timer); +- if (uip_connr->timer == UIP_TIME_WAIT_TIMEOUT) +- uip_connr->tcpstateflags = UIP_CLOSED; +- } else if (uip_connr->tcpstateflags != UIP_CLOSED) { +- /* If the connection has outstanding data, we increase +- the connection's timer and see if it has reached the +- RTO value in which case we retransmit. */ +- if (uip_outstanding(uip_connr)) { +- if (uip_connr->timer-- == 0) { +- if (uip_connr->nrtx == UIP_MAXRTX || +- ((uip_connr->tcpstateflags == +- UIP_SYN_SENT +- || uip_connr->tcpstateflags == +- UIP_SYN_RCVD) +- && uip_connr->nrtx == +- UIP_MAXSYNRTX)) { +- uip_connr->tcpstateflags = +- UIP_CLOSED; +- +- /* We call UIP_APPCALL() with +- uip_flags set to UIP_TIMEDOUT +- to inform the application +- that the connection has timed +- out. */ +- ustack->uip_flags = +- UIP_TIMEDOUT; +- UIP_APPCALL(ustack); +- +- /* We also send a reset packet +- to the remote host. */ +- tcp_hdr->flags = +- TCP_RST | TCP_ACK; +- goto tcp_send_nodata; +- } +- +- /* Exponential backoff. */ +- uip_connr->timer = +- UIP_RTO << (uip_connr->nrtx > +- 4 ? 4 : uip_connr-> +- nrtx); +- ++(uip_connr->nrtx); +- +- /* Ok, so we need to retransmit. +- We do this differently depending on +- which state we are in. +- In ESTABLISHED, we call upon the +- application so that it may prepare +- the data for the retransmit. +- In SYN_RCVD, we resend the SYNACK +- that we sent earlier and in LAST_ACK +- we have to retransmit our FINACK. */ +- ++ustack->stats.tcp.rexmit; +- switch (uip_connr-> +- tcpstateflags & UIP_TS_MASK) { +- case UIP_SYN_RCVD: +- /* In the SYN_RCVD state, we +- should retransmit our SYNACK +- */ +- goto tcp_send_synack; +-#if UIP_ACTIVE_OPEN +- case UIP_SYN_SENT: +- /* In the SYN_SENT state, +- we retransmit out SYN. */ +- tcp_hdr->flags = 0; +- goto tcp_send_syn; +-#endif /* UIP_ACTIVE_OPEN */ +- +- case UIP_ESTABLISHED: +- /* In the ESTABLISHED state, +- we call upon the application +- to do the actual retransmit +- after which we jump into +- the code for sending out the +- packet (the apprexmit +- label). */ +- ustack->uip_flags = UIP_REXMIT; +- UIP_APPCALL(ustack); +- goto apprexmit; +- +- case UIP_FIN_WAIT_1: +- case UIP_CLOSING: +- case UIP_LAST_ACK: +- /* In all these states we should +- retransmit a FINACK. */ +- goto tcp_send_finack; +- +- } +- } +- } else if ((uip_connr->tcpstateflags & UIP_TS_MASK) == +- UIP_ESTABLISHED) { +- /* If there was no need for a retransmission, +- we poll the application for new data. */ +- ustack->uip_flags = UIP_POLL; +- UIP_APPCALL(ustack); +- goto appsend; +- } +- } +- goto drop; +- } /* End of UIP_TIMER */ +-#if UIP_UDP +- if (flag == UIP_UDP_TIMER) { +- /* This is for IPv4 DHCP only! */ +- if (ustack->uip_udp_conn->lport != 0) { +- ustack->uip_conn = NULL; +- ustack->uip_sappdata = ustack->uip_appdata = +- ustack->network_layer + uip_ip_udph_len; +- ustack->uip_len = ustack->uip_slen = 0; +- ustack->uip_flags = UIP_POLL; +- UIP_UDP_APPCALL(ustack); +- goto udp_send; +- } else { +- goto drop; +- } +- } +-#endif +- if (flag == UIP_NDP_TIMER) { +- /* This is for IPv6 NDP Only! */ +- if (1) { /* If NDP engine active */ +- ustack->uip_len = ustack->uip_slen = 0; +- ustack->uip_flags = UIP_POLL; +- goto ndp_send; +- } +- } +- +- /* This is where the input processing starts. */ +- ++ustack->stats.ip.recv; +- +- /* Start of IP input header processing code. */ +- +- if (is_ipv6(ustack)) { +- u8_t version = ((ipv6_hdr->ip6_vfc) & 0xf0) >> 4; +- +- /* Check validity of the IP header. */ +- if (version != 0x6) { /* IP version and header length. */ +- ++ustack->stats.ip.drop; +- ++ustack->stats.ip.vhlerr; +- LOG_DEBUG(PFX "ipv6: invalid version(0x%x).", version); +- goto drop; +- } +- } else { +- /* Check validity of the IP header. */ +- if (tcp_ipv4_hdr->vhl != 0x45) { +- /* IP version and header length. */ +- ++ustack->stats.ip.drop; +- ++ustack->stats.ip.vhlerr; +- LOG_DEBUG(PFX +- "ipv4: invalid version or header length: " +- "0x%x.", +- tcp_ipv4_hdr->vhl); +- goto drop; +- } +- } +- +- /* Check the size of the packet. If the size reported to us in +- uip_len is smaller the size reported in the IP header, we assume +- that the packet has been corrupted in transit. If the size of +- uip_len is larger than the size reported in the IP packet header, +- the packet has been padded and we set uip_len to the correct +- value.. */ +- +- if (is_ipv6(ustack)) { +- u16_t len = ntohs(ipv6_hdr->ip6_plen); +- if (len > ustack->uip_len) { +- LOG_DEBUG(PFX +- "ip: packet shorter than reported in IP header" +- ":IPv6_BUF(ustack)->len: %d ustack->uip_len: " +- "%d", len, ustack->uip_len); +- goto drop; +- } +- } else { +- if ((tcp_ipv4_hdr->len[0] << 8) + +- tcp_ipv4_hdr->len[1] <= ustack->uip_len) { +- ustack->uip_len = (tcp_ipv4_hdr->len[0] << 8) + +- tcp_ipv4_hdr->len[1]; +- } else { +- LOG_DEBUG(PFX +- "ip: packet shorter than reported in IP header" +- ":tcp_ipv4_hdr->len: %d ustack->uip_len:%d.", +- (tcp_ipv4_hdr->len[0] << 8) + +- tcp_ipv4_hdr->len[1], ustack->uip_len); +- goto drop; +- } +- } +- +- if (!is_ipv6(ustack)) { +- /* Check the fragment flag. */ +- if ((tcp_ipv4_hdr->ipoffset[0] & 0x3f) != 0 || +- tcp_ipv4_hdr->ipoffset[1] != 0) { +-#if UIP_REASSEMBLY +- uip_len = uip_reass(); +- if (uip_len == 0) +- goto drop; +-#else /* UIP_REASSEMBLY */ +- ++ustack->stats.ip.drop; +- ++ustack->stats.ip.fragerr; +- LOG_WARN(PFX "ip: fragment dropped."); +- goto drop; +-#endif /* UIP_REASSEMBLY */ +- } +- } +- +- if (!is_ipv6(ustack)) { +- /* ipv4 */ +- if (uip_ip4addr_cmp(ustack->hostaddr, all_zeroes_addr4)) { +- /* If we are configured to use ping IP address +- configuration and hasn't been assigned an IP +- address yet, we accept all ICMP packets. */ +-#if UIP_PINGADDRCONF && !UIP_CONF_IPV6 +- if (tcp_ipv4_hdr->proto == UIP_PROTO_ICMP) { +- LOG_WARN(PFX +- "ip: possible ping config packet " +- "received."); +- goto icmp_input; +- } else { +- LOG_WARN(PFX +- "ip: packet dropped since no " +- "address assigned."); +- goto drop; +- } +-#endif /* UIP_PINGADDRCONF */ +- } else { +- int broadcast_addr = 0xFFFFFFFF; +- /* If IP broadcast support is configured, we check for +- a broadcast UDP packet, which may be destined to us +- */ +- if ((tcp_ipv4_hdr->proto == UIP_PROTO_UDP) && +- (uip_ip4addr_cmp +- (tcp_ipv4_hdr->destipaddr, &broadcast_addr)) +- /*&& +- uip_ipchksum() == 0xffff */ +- ) { +- goto udp_input; +- } +- +- /* Check if the packet is destined for our IP address +- */ +- if (!uip_ip4addr_cmp(tcp_ipv4_hdr->destipaddr, +- ustack->hostaddr)) { +- ++ustack->stats.ip.drop; +- goto drop; +- } +- } +- if (uip_ipchksum(ustack) != 0xffff) { +- /* Compute and check the IP header checksum. */ +- ++ustack->stats.ip.drop; +- ++ustack->stats.ip.chkerr; +- LOG_ERR(PFX "ip: bad checksum."); +- goto drop; +- } +- } /* End of ipv4 */ +- +- if (is_ipv6(ustack)) { +- if (ipv6_hdr->ip6_nxt == UIP_PROTO_TCP) { +- /* Check for TCP packet. If so, proceed with TCP input +- processing. */ +- goto ndp_newdata; +- } +-#if UIP_UDP +- if (ipv6_hdr->ip6_nxt == UIP_PROTO_UDP) +- goto ndp_newdata; +-#endif /* UIP_UDP */ +- +- /* This is IPv6 ICMPv6 processing code. */ +- if (ipv6_hdr->ip6_nxt != UIP_PROTO_ICMP6) { +- /* We only allow ICMPv6 packets from here. */ +- ++ustack->stats.ip.drop; +- ++ustack->stats.ip.protoerr; +- goto drop; +- } +- +- ++ustack->stats.icmp.recv; +- +-ndp_newdata: +- /* This call is to handle the IPv6 Network Discovery Protocol */ +- ustack->uip_flags = UIP_NEWDATA; +- ustack->uip_slen = 0; +-ndp_send: +- UIP_NDP_CALL(ustack); +- if (ustack->uip_slen != 0) { +- ustack->uip_len = ustack->uip_slen; +- goto send; +- } else { +- goto drop; +- } +- } else { +- /* IPv4 Processing */ +- if (tcp_ipv4_hdr->proto == UIP_PROTO_TCP) { +- /* Check for TCP packet. If so, proceed with TCP input +- processing. */ +- goto tcp_input; +- } +-#if UIP_UDP +- if (tcp_ipv4_hdr->proto == UIP_PROTO_UDP) +- goto udp_input; +-#endif /* UIP_UDP */ +- +- /* ICMPv4 processing code follows. */ +- if (tcp_ipv4_hdr->proto != UIP_PROTO_ICMP) { +- /* We only allow ICMP packets from here. */ +- ++ustack->stats.ip.drop; +- ++ustack->stats.ip.protoerr; +- LOG_DEBUG(PFX "ip: neither tcp nor icmp."); +- goto drop; +- } +-#if UIP_PINGADDRCONF +-icmp_input: +-#endif /* UIP_PINGADDRCONF */ +- ++ustack->stats.icmp.recv; +- +- if (icmpv4_hdr->type == ICMP_ECHO_REPLY) { +- if (process_icmp_packet(icmpv4_hdr, ustack) == 0) +- goto drop; +- } +- +- /* ICMP echo (i.e., ping) processing. This is simple, we only +- change the ICMP type from ECHO to ECHO_REPLY and adjust the +- ICMP checksum before we return the packet. */ +- if (icmpv4_hdr->type != ICMP_ECHO) { +- ++ustack->stats.icmp.drop; +- ++ustack->stats.icmp.typeerr; +- LOG_DEBUG(PFX "icmp: not icmp echo."); +- goto drop; +- } +- +- /* If we are configured to use ping IP address assignment, we +- use the destination IP address of this ping packet and assign +- it to ourself. */ +-#if UIP_PINGADDRCONF +- if ((ustack->hostaddr[0] | ustack->hostaddr[1]) == 0) { +- ustack->hostaddr[0] = tcp_ipv4_hdr->destipaddr[0]; +- ustack->hostaddr[1] = tcp_ipv4_hdr->destipaddr[1]; +- } +-#endif /* UIP_PINGADDRCONF */ +- +- icmpv4_hdr->type = ICMP_ECHO_REPLY; +- +- if (icmpv4_hdr->icmpchksum >= htons(0xffff - +- (ICMP_ECHO << 8))) { +- icmpv4_hdr->icmpchksum += htons(ICMP_ECHO << 8) + 1; +- } else { +- icmpv4_hdr->icmpchksum += htons(ICMP_ECHO << 8); +- } +- +- /* Swap IP addresses. */ +- uip_ip4addr_copy(tcp_ipv4_hdr->destipaddr, +- tcp_ipv4_hdr->srcipaddr); +- uip_ip4addr_copy(tcp_ipv4_hdr->srcipaddr, ustack->hostaddr); +- +- ++ustack->stats.icmp.sent; +- goto send; +- +- /* End of IPv4 input header processing code. */ +- } +- +-#if UIP_UDP +- /* UDP input processing. */ +-udp_input: +- /* UDP processing is really just a hack. We don't do anything to the +- UDP/IP headers, but let the UDP application do all the hard +- work. If the application sets uip_slen, it has a packet to +- send. */ +-#if UIP_UDP_CHECKSUMS +- ustack->uip_len = ustack->uip_len - uip_ip_udph_len; +- ustack->uip_appdata = ustack->network_layer + uip_ip_udph_len; +- if (UDPBUF(ustack)->udpchksum != 0 && uip_udpchksum(ustack) != 0xffff) { +- ++ustack->stats.udp.drop; +- ++ustack->stats.udp.chkerr; +- LOG_DEBUG(PFX "udp: bad checksum."); +- goto drop; +- } +-#else /* UIP_UDP_CHECKSUMS */ +- uip_len = uip_len - uip_ip_udph_len; +-#endif /* UIP_UDP_CHECKSUMS */ +- +- if (is_ipv6(ustack)) +- goto udp_found; +- +- /* Demultiplex this UDP packet between the UDP "connections". */ +- for (ustack->uip_udp_conn = &ustack->uip_udp_conns[0]; +- ustack->uip_udp_conn < &ustack->uip_udp_conns[UIP_UDP_CONNS]; +- ++ustack->uip_udp_conn) { +- /* If the local UDP port is non-zero, the connection is +- considered to be used. If so, the local port number is +- checked against the destination port number in the +- received packet. If the two port +- numbers match, the remote port number is checked if the +- connection is bound to a remote port. Finally, if the +- connection is bound to a remote IP address, the source IP +- address of the packet is checked. */ +- +- if (ustack->uip_udp_conn->lport != 0 && +- UDPBUF(ustack)->destport == ustack->uip_udp_conn->lport && +- (ustack->uip_udp_conn->rport == 0 || +- UDPBUF(ustack)->srcport == ustack->uip_udp_conn->rport) && +- (uip_ip4addr_cmp(ustack->uip_udp_conn->ripaddr, +- all_zeroes_addr4) || +- uip_ip4addr_cmp(ustack->uip_udp_conn->ripaddr, +- all_ones_addr4) || +- uip_ip4addr_cmp(tcp_ipv4_hdr->srcipaddr, +- ustack->uip_udp_conn->ripaddr))) { +- goto udp_found; +- } +- } +- LOG_DEBUG(PFX +- "udp: no matching connection found: dest port: %d src port: " +- "%d", udp_hdr->destport, udp_hdr->srcport); +- goto drop; +- +-udp_found: +- ustack->uip_conn = NULL; +- ustack->uip_flags = UIP_NEWDATA; +- ustack->uip_sappdata = ustack->uip_appdata = ustack->network_layer + +- uip_ip_udph_len; +- ustack->uip_slen = 0; +- if (is_ipv6(ustack)) +- UIP_NDP_CALL(ustack); +- else +- UIP_UDP_APPCALL(ustack); +-udp_send: +- if (ustack->uip_slen == 0) +- goto drop; +- +- ustack->uip_len = ustack->uip_slen + uip_ip_udph_len; +- +- if (is_ipv6(ustack)) { +- goto ip_send_nolen; +- } else { +- tcp_ipv4_hdr->len[0] = (ustack->uip_len >> 8); +- tcp_ipv4_hdr->len[1] = (ustack->uip_len & 0xff); +- tcp_ipv4_hdr->ttl = ustack->uip_udp_conn->ttl; +- tcp_ipv4_hdr->proto = UIP_PROTO_UDP; +- } +- +- udp_hdr->udplen = htons(ustack->uip_slen + UIP_UDPH_LEN); +- udp_hdr->udpchksum = 0; +- +- udp_hdr->srcport = ustack->uip_udp_conn->lport; +- udp_hdr->destport = ustack->uip_udp_conn->rport; +- +- uip_ip4addr_copy(tcp_ipv4_hdr->srcipaddr, ustack->hostaddr); +- uip_ip4addr_copy(tcp_ipv4_hdr->destipaddr, +- ustack->uip_udp_conn->ripaddr); +- +- ustack->uip_appdata = ustack->network_layer + uip_ip_tcph_len; +- +- if (ustack->uip_buf == NULL) { +- LOG_WARN(PFX "uip_buf == NULL on udp send"); +- goto drop; +- } +-#if UIP_UDP_CHECKSUMS +- /* Calculate UDP checksum. */ +- udp_hdr->udpchksum = ~(uip_udpchksum(ustack)); +- if (udp_hdr->udpchksum == 0) +- udp_hdr->udpchksum = 0xffff; +-#endif /* UIP_UDP_CHECKSUMS */ +- +- goto ip_send_nolen; +-#endif /* UIP_UDP */ +- +- /* TCP input processing. */ +-tcp_input: +- ++ustack->stats.tcp.recv; +- +- /* Start of TCP input header processing code. */ +- +- if (uip_tcpchksum(ustack) != 0xffff) { /* Compute and check the TCP +- checksum. */ +- ++ustack->stats.tcp.drop; +- ++ustack->stats.tcp.chkerr; +- LOG_WARN(PFX "tcp: bad checksum."); +- goto drop; +- } +- +- if (is_ipv6(ustack)) { +- /* Demultiplex this segment. */ +- /* First check any active connections. */ +- for (uip_connr = &ustack->uip_conns[0]; +- uip_connr <= &ustack->uip_conns[UIP_CONNS - 1]; +- ++uip_connr) { +- if (uip_connr->tcpstateflags != UIP_CLOSED && +- tcp_hdr->destport == uip_connr->lport && +- tcp_hdr->srcport == uip_connr->rport && +- uip_ip6addr_cmp(IPv6_BUF(ustack)->srcipaddr, +- uip_connr->ripaddr)) { +- goto found; +- } +- } +- } else { +- /* Demultiplex this segment. */ +- /* First check any active connections. */ +- for (uip_connr = &ustack->uip_conns[0]; +- uip_connr <= &ustack->uip_conns[UIP_CONNS - 1]; +- ++uip_connr) { +- if (uip_connr->tcpstateflags != UIP_CLOSED && +- tcp_hdr->destport == uip_connr->lport && +- tcp_hdr->srcport == uip_connr->rport && +- uip_ip4addr_cmp(tcp_ipv4_hdr->srcipaddr, +- uip_connr->ripaddr)) { +- goto found; +- } +- } +- } +- +- /* If we didn't find and active connection that expected the packet, +- either this packet is an old duplicate, or this is a SYN packet +- destined for a connection in LISTEN. If the SYN flag isn't set, +- it is an old packet and we send a RST. */ +- if ((tcp_hdr->flags & TCP_CTL) != TCP_SYN) +- goto reset; +- +- tmp16 = tcp_hdr->destport; +- /* Next, check listening connections. */ +- for (c = 0; c < UIP_LISTENPORTS; ++c) { +- if (tmp16 == ustack->uip_listenports[c]) +- goto found_listen; +- } +- +- /* No matching connection found, so we send a RST packet. */ +- ++ustack->stats.tcp.synrst; +-reset: +- +- /* We do not send resets in response to resets. */ +- if (tcp_hdr->flags & TCP_RST) +- goto drop; +- +- ++ustack->stats.tcp.rst; +- +- tcp_hdr->flags = TCP_RST | TCP_ACK; +- ustack->uip_len = uip_ip_tcph_len; +- tcp_hdr->tcpoffset = 5 << 4; +- +- /* Flip the seqno and ackno fields in the TCP header. */ +- c = tcp_hdr->seqno[3]; +- tcp_hdr->seqno[3] = tcp_hdr->ackno[3]; +- tcp_hdr->ackno[3] = c; +- +- c = tcp_hdr->seqno[2]; +- tcp_hdr->seqno[2] = tcp_hdr->ackno[2]; +- tcp_hdr->ackno[2] = c; +- +- c = tcp_hdr->seqno[1]; +- tcp_hdr->seqno[1] = tcp_hdr->ackno[1]; +- tcp_hdr->ackno[1] = c; +- +- c = tcp_hdr->seqno[0]; +- tcp_hdr->seqno[0] = tcp_hdr->ackno[0]; +- tcp_hdr->ackno[0] = c; +- +- /* We also have to increase the sequence number we are +- acknowledging. If the least significant byte overflowed, we need +- to propagate the carry to the other bytes as well. */ +- if (++tcp_hdr->ackno[3] == 0) { +- if (++tcp_hdr->ackno[2] == 0) { +- if (++tcp_hdr->ackno[1] == 0) +- ++tcp_hdr->ackno[0]; +- } +- } +- +- /* Swap port numbers. */ +- tmp16 = tcp_hdr->srcport; +- tcp_hdr->srcport = tcp_hdr->destport; +- tcp_hdr->destport = tmp16; +- +- /* Swap IP addresses. */ +- if (is_ipv6(ustack)) { +- uip_ip6addr_copy(IPv6_BUF(ustack)->destipaddr, +- IPv6_BUF(ustack)->srcipaddr); +- uip_ip6addr_copy(IPv6_BUF(ustack)->srcipaddr, +- ustack->hostaddr6); +- } else { +- uip_ip4addr_copy(tcp_ipv4_hdr->destipaddr, +- tcp_ipv4_hdr->srcipaddr); +- uip_ip4addr_copy(tcp_ipv4_hdr->srcipaddr, ustack->hostaddr); +- } +- +- /* And send out the RST packet! */ +- goto tcp_send_noconn; +- +- /* This label will be jumped to if we matched the incoming packet +- with a connection in LISTEN. In that case, we should create a new +- connection and send a SYNACK in return. */ +-found_listen: +- /* First we check if there are any connections avaliable. Unused +- connections are kept in the same table as used connections, but +- unused ones have the tcpstate set to CLOSED. Also, connections in +- TIME_WAIT are kept track of and we'll use the oldest one if no +- CLOSED connections are found. Thanks to Eddie C. Dost for a very +- nice algorithm for the TIME_WAIT search. */ +- uip_connr = 0; +- for (c = 0; c < UIP_CONNS; ++c) { +- if (ustack->uip_conns[c].tcpstateflags == UIP_CLOSED) { +- uip_connr = &ustack->uip_conns[c]; +- break; +- } +- if (ustack->uip_conns[c].tcpstateflags == UIP_TIME_WAIT) { +- if (uip_connr == 0 || +- ustack->uip_conns[c].timer > uip_connr->timer) { +- uip_connr = &ustack->uip_conns[c]; +- } +- } +- } +- +- if (uip_connr == 0) { +- /* All connections are used already, we drop packet and hope +- that the remote end will retransmit the packet at a time when +- we have more spare connections. */ +- ++ustack->stats.tcp.syndrop; +- LOG_WARN(PFX "tcp: found no unused connections."); +- goto drop; +- } +- ustack->uip_conn = uip_connr; +- +- /* Fill in the necessary fields for the new connection. */ +- uip_connr->rto = uip_connr->timer = UIP_RTO; +- uip_connr->sa = 0; +- uip_connr->sv = 4; +- uip_connr->nrtx = 0; +- uip_connr->lport = tcp_hdr->destport; +- uip_connr->rport = tcp_hdr->srcport; +- if (is_ipv6(ustack)) { +- uip_ip6addr_copy(uip_connr->ripaddr, +- IPv6_BUF(ustack)->srcipaddr); +- } else { +- uip_ip4addr_copy(uip_connr->ripaddr, tcp_ipv4_hdr->srcipaddr); +- } +- uip_connr->tcpstateflags = UIP_SYN_RCVD; +- +- uip_connr->snd_nxt[0] = ustack->iss[0]; +- uip_connr->snd_nxt[1] = ustack->iss[1]; +- uip_connr->snd_nxt[2] = ustack->iss[2]; +- uip_connr->snd_nxt[3] = ustack->iss[3]; +- uip_connr->len = 1; +- +- /* rcv_nxt should be the seqno from the incoming packet + 1. */ +- uip_connr->rcv_nxt[3] = tcp_hdr->seqno[3]; +- uip_connr->rcv_nxt[2] = tcp_hdr->seqno[2]; +- uip_connr->rcv_nxt[1] = tcp_hdr->seqno[1]; +- uip_connr->rcv_nxt[0] = tcp_hdr->seqno[0]; +- uip_add_rcv_nxt(ustack, 1); +- +- /* Parse the TCP MSS option, if present. */ +- if ((tcp_hdr->tcpoffset & 0xf0) > 0x50) { +- for (c = 0; c < ((tcp_hdr->tcpoffset >> 4) - 5) << 2;) { +- ustack->opt = +- ustack->uip_buf[uip_ip_tcph_len + UIP_LLH_LEN + c]; +- if (ustack->opt == TCP_OPT_END) { +- /* End of options. */ +- break; +- } else if (ustack->opt == TCP_OPT_NOOP) { +- ++c; +- /* NOP option. */ +- } else if (ustack->opt == TCP_OPT_MSS && +- ustack->uip_buf[uip_ip_tcph_len + +- UIP_LLH_LEN + 1 + c] == +- TCP_OPT_MSS_LEN) { +- /* An MSS option with the right option length.*/ +- tmp16 = +- ((u16_t) ustack-> +- uip_buf[uip_ip_tcph_len + UIP_LLH_LEN + 2 + +- c] << 8) | (u16_t) ustack-> +- uip_buf[uip_ip_tcph_len + UIP_LLH_LEN + 3 + +- c]; +- uip_connr->initialmss = uip_connr->mss = +- tmp16 > UIP_TCP_MSS ? UIP_TCP_MSS : tmp16; +- +- /* And we are done processing options. */ +- break; +- } else { +- /* All other options have a length field, so +- that we easily can skip past them. */ +- if (ustack->uip_buf[uip_ip_tcph_len + UIP_LLH_LEN + 1 + c] == 0) { +- /* If the length field is zero, the +- options are malformed +- and we don't process them further. */ +- break; +- } +- if ((ustack->uip_buf[uip_ip_tcph_len + UIP_LLH_LEN + 1 + c]) > (256 - c)) { +- /* u8 overflow, actually there should +- * never be more than 40 bytes of options */ +- break; +- } +- c += ustack->uip_buf[uip_ip_tcph_len + UIP_LLH_LEN + 1 + c]; +- } +- } +- } +- +- /* Our response will be a SYNACK. */ +-#if UIP_ACTIVE_OPEN +-tcp_send_synack: +- tcp_hdr->flags = TCP_ACK; +- +-tcp_send_syn: +- tcp_hdr->flags |= TCP_SYN; +-#else /* UIP_ACTIVE_OPEN */ +-tcp_send_synack: +- tcp_hdr->flags = TCP_SYN | TCP_ACK; +-#endif /* UIP_ACTIVE_OPEN */ +- +- /* We send out the TCP Maximum Segment Size option with our +- SYNACK. */ +- tcp_hdr->optdata[0] = TCP_OPT_MSS; +- tcp_hdr->optdata[1] = TCP_OPT_MSS_LEN; +- tcp_hdr->optdata[2] = (UIP_TCP_MSS) / 256; +- tcp_hdr->optdata[3] = (UIP_TCP_MSS) & 255; +- ustack->uip_len = uip_ip_tcph_len + TCP_OPT_MSS_LEN; +- tcp_hdr->tcpoffset = ((UIP_TCPH_LEN + TCP_OPT_MSS_LEN) / 4) << 4; +- goto tcp_send; +- +- /* This label will be jumped to if we found an active connection. */ +-found: +- ustack->uip_conn = uip_connr; +- ustack->uip_flags = 0; +- /* We do a very naive form of TCP reset processing; we just accept +- any RST and kill our connection. We should in fact check if the +- sequence number of this reset is wihtin our advertised window +- before we accept the reset. */ +- if (tcp_hdr->flags & TCP_RST) { +- uip_connr->tcpstateflags = UIP_CLOSED; +- LOG_WARN(PFX "tcp: got reset, aborting connection."); +- ustack->uip_flags = UIP_ABORT; +- UIP_APPCALL(ustack); +- goto drop; +- } +- /* Calculated the length of the data, if the application has sent +- any data to us. */ +- c = (tcp_hdr->tcpoffset >> 4) << 2; +- /* uip_len will contain the length of the actual TCP data. This is +- calculated by subtracing the length of the TCP header (in +- c) and the length of the IP header (20 bytes). */ +- ustack->uip_len = ustack->uip_len - c - uip_iph_len; +- +- /* First, check if the sequence number of the incoming packet is +- what we're expecting next. If not, we send out an ACK with the +- correct numbers in. */ +- if (!(((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) && +- ((tcp_hdr->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)))) { +- if ((ustack->uip_len > 0 +- || ((tcp_hdr->flags & (TCP_SYN | TCP_FIN)) != 0)) +- && (tcp_hdr->seqno[0] != uip_connr->rcv_nxt[0] +- || tcp_hdr->seqno[1] != uip_connr->rcv_nxt[1] +- || tcp_hdr->seqno[2] != uip_connr->rcv_nxt[2] +- || tcp_hdr->seqno[3] != uip_connr->rcv_nxt[3])) { +- goto tcp_send_ack; +- } +- } +- +- { +- u8_t uip_acc32[4]; +- +- /* Next, check if the incoming segment acks any outstanding +- data. If so, we update the sequence number, reset the len of +- the outstanding data, calc RTT estimations, and reset the +- retransmission timer. */ +- if ((tcp_hdr->flags & TCP_ACK) && uip_outstanding(uip_connr)) { +- uip_add32(uip_connr->snd_nxt, uip_connr->len, +- uip_acc32); +- +- if (tcp_hdr->ackno[0] == uip_acc32[0] && +- tcp_hdr->ackno[1] == uip_acc32[1] && +- tcp_hdr->ackno[2] == uip_acc32[2] && +- tcp_hdr->ackno[3] == uip_acc32[3]) { +- /* Update sequence number. */ +- uip_connr->snd_nxt[0] = uip_acc32[0]; +- uip_connr->snd_nxt[1] = uip_acc32[1]; +- uip_connr->snd_nxt[2] = uip_acc32[2]; +- uip_connr->snd_nxt[3] = uip_acc32[3]; +- +- /* Do RTT estimation, unless we have done +- retransmissions. */ +- if (uip_connr->nrtx == 0) { +- signed char m; +- m = uip_connr->rto - uip_connr->timer; +- /* This is taken directly from VJs +- original code in his paper */ +- m = m - (uip_connr->sa >> 3); +- uip_connr->sa += m; +- if (m < 0) +- m = -m; +- m = m - (uip_connr->sv >> 2); +- uip_connr->sv += m; +- uip_connr->rto = +- (uip_connr->sa >> 3) + +- uip_connr->sv; +- +- } +- /* Set the acknowledged flag. */ +- ustack->uip_flags = UIP_ACKDATA; +- /* Reset the retransmission timer. */ +- uip_connr->timer = uip_connr->rto; +- +- /* Reset length of outstanding data. */ +- uip_connr->len = 0; +- } +- +- } +- +- } +- +- /* Do different things depending on in what state the connection is. */ +- switch (uip_connr->tcpstateflags & UIP_TS_MASK) { +- /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not +- implemented, since we force the application to close when the +- peer sends a FIN (hence the application goes directly from +- ESTABLISHED to LAST_ACK). */ +- case UIP_SYN_RCVD: +- /* In SYN_RCVD we have sent out a SYNACK in response to a SYN, +- and we are waiting for an ACK that acknowledges the data we +- sent out the last time. Therefore, we want to have the +- UIP_ACKDATA flag set. +- If so, we enter the ESTABLISHED state. */ +- if (ustack->uip_flags & UIP_ACKDATA) { +- uip_connr->tcpstateflags = UIP_ESTABLISHED; +- ustack->uip_flags = UIP_CONNECTED; +- uip_connr->len = 0; +- if (ustack->uip_len > 0) { +- ustack->uip_flags |= UIP_NEWDATA; +- uip_add_rcv_nxt(ustack, ustack->uip_len); +- } +- ustack->uip_slen = 0; +- UIP_APPCALL(ustack); +- goto appsend; +- } +- goto drop; +-#if UIP_ACTIVE_OPEN +- case UIP_SYN_SENT: +- /* In SYN_SENT, we wait for a SYNACK that is sent in response to +- our SYN. The rcv_nxt is set to sequence number in the SYNACK +- plus one, and we send an ACK. We move into the ESTABLISHED +- state. */ +- if ((ustack->uip_flags & UIP_ACKDATA) && +- (tcp_hdr->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)) { +- +- /* Parse the TCP MSS option, if present. */ +- if ((tcp_hdr->tcpoffset & 0xf0) > 0x50) { +- for (c = 0; +- c < +- ((tcp_hdr->tcpoffset >> 4) - 5) << 2;) { +- ustack->opt = +- ustack->uip_buf[uip_ip_tcph_len + +- UIP_LLH_LEN + c]; +- if (ustack->opt == TCP_OPT_END) { +- /* End of options. */ +- break; +- } else if (ustack->opt == +- TCP_OPT_NOOP) { +- ++c; +- /* NOP option. */ +- } else if (ustack->opt == TCP_OPT_MSS && +- ustack-> +- uip_buf[uip_ip_tcph_len + +- UIP_LLH_LEN + 1 + +- c] == +- TCP_OPT_MSS_LEN) { +- /* An MSS option with the right +- option length. */ +- tmp16 = +- (ustack-> +- uip_buf[uip_ip_tcph_len + +- UIP_LLH_LEN + 2 + +- c] << 8) | ustack-> +- uip_buf[uip_ip_tcph_len + +- UIP_LLH_LEN + 3 + +- c]; +- uip_connr->initialmss = +- uip_connr->mss = +- tmp16 > +- UIP_TCP_MSS ? UIP_TCP_MSS : +- tmp16; +- +- /* And we are done processing +- options. */ +- break; +- } else { +- /* All other options have a +- length field, so that we +- easily can skip past them */ +- if (ustack-> +- uip_buf[uip_ip_tcph_len + +- UIP_LLH_LEN + 1 + +- c] == 0) { +- /* If the length field +- is zero, the options +- are malformed and we +- don't process them +- further. */ +- break; +- } +- if ((ustack->uip_buf[uip_ip_tcph_len +- + UIP_LLH_LEN + 1 + +- c]) > (256 - c)) { +- /* u8 overflow, actually there should +- * never be more than 40 bytes of +- * options */ +- break; +- } +- c += ustack-> +- uip_buf[uip_ip_tcph_len + +- UIP_LLH_LEN + 1 + +- c]; +- } +- } +- } +- uip_connr->tcpstateflags = UIP_ESTABLISHED; +- uip_connr->rcv_nxt[0] = tcp_hdr->seqno[0]; +- uip_connr->rcv_nxt[1] = tcp_hdr->seqno[1]; +- uip_connr->rcv_nxt[2] = tcp_hdr->seqno[2]; +- uip_connr->rcv_nxt[3] = tcp_hdr->seqno[3]; +- uip_add_rcv_nxt(ustack, 1); +- ustack->uip_flags = UIP_CONNECTED | UIP_NEWDATA; +- uip_connr->len = 0; +- ustack->uip_len = 0; +- ustack->uip_slen = 0; +- UIP_APPCALL(ustack); +- goto appsend; +- } +- /* Inform the application that the connection failed */ +- ustack->uip_flags = UIP_ABORT; +- UIP_APPCALL(ustack); +- /* The connection is closed after we send the RST */ +- ustack->uip_conn->tcpstateflags = UIP_CLOSED; +- goto reset; +-#endif /* UIP_ACTIVE_OPEN */ +- +- case UIP_ESTABLISHED: +- /* In the ESTABLISHED state, we call upon the application to +- feed data into the uip_buf. If the UIP_ACKDATA flag is set, +- the application should put new data into the buffer, +- otherwise we are retransmitting an old segment, and the +- application should put that data into the buffer. +- +- If the incoming packet is a FIN, we should close the +- connection on this side as well, and we send out a FIN and +- enter the LAST_ACK state. We require that there is no +- outstanding data; otherwise the sequence numbers will be +- screwed up. */ +- +- if (tcp_hdr->flags & TCP_FIN +- && !(uip_connr->tcpstateflags & UIP_STOPPED)) { +- if (uip_outstanding(uip_connr)) +- goto drop; +- uip_add_rcv_nxt(ustack, 1 + ustack->uip_len); +- ustack->uip_flags |= UIP_CLOSE; +- if (ustack->uip_len > 0) +- ustack->uip_flags |= UIP_NEWDATA; +- UIP_APPCALL(ustack); +- uip_connr->len = 1; +- uip_connr->tcpstateflags = UIP_LAST_ACK; +- uip_connr->nrtx = 0; +-tcp_send_finack: +- tcp_hdr->flags = TCP_FIN | TCP_ACK; +- goto tcp_send_nodata; +- } +- +- /* Check the URG flag. If this is set, the segment carries +- urgent data that we must pass to the application. */ +- if ((tcp_hdr->flags & TCP_URG) != 0) { +-#if UIP_URGDATA > 0 +- uip_urglen = (tcp_hdr->urgp[0] << 8) | tcp_hdr->urgp[1]; +- if (uip_urglen > uip_len) { +- /* There is more urgent data in the next segment +- to come. */ +- uip_urglen = uip_len; +- } +- uip_add_rcv_nxt(uip_urglen); +- uip_len -= uip_urglen; +- uip_urgdata = uip_appdata; +- uip_appdata += uip_urglen; +- } else { +- uip_urglen = 0; +-#else /* UIP_URGDATA > 0 */ +- tmp16 = (tcp_hdr->urgp[0] << 8) | tcp_hdr->urgp[1]; +- if (tmp16 <= ustack->uip_len) { +- ustack->uip_appdata = ((char *)ustack->uip_appdata) + tmp16; +- ustack->uip_len -= tmp16; +- } else { +- /* invalid urgent pointer length greater than frame */ +- /* we're discarding urgent data anyway, throw it all out */ +- ustack->uip_appdata = ((char *)ustack->uip_appdata) + ustack->uip_len; +- ustack->uip_len = 0; +- } +-#endif /* UIP_URGDATA > 0 */ +- } +- +- /* If uip_len > 0 we have TCP data in the packet, and we flag +- this by setting the UIP_NEWDATA flag and update the sequence +- number we acknowledge. If the application has stopped the +- dataflow using uip_stop(), we must not accept any data +- packets from the remote host. */ +- if (ustack->uip_len > 0 +- && !(uip_connr->tcpstateflags & UIP_STOPPED)) { +- ustack->uip_flags |= UIP_NEWDATA; +- uip_add_rcv_nxt(ustack, ustack->uip_len); +- } +- +- /* Check if the available buffer space advertised by the other +- end is smaller than the initial MSS for this connection. +- If so, we set the current MSS to the window size to ensure +- that the application does not send more data than the other +- end can handle. +- +- If the remote host advertises a zero window, we set the MSS +- to the initial MSS so that the application will send an +- entire MSS of data. This data will not be acknowledged by +- the receiver, and the application will retransmit it. +- This is called the "persistent timer" and uses the +- retransmission mechanim. +- */ +- tmp16 = +- ((u16_t) tcp_hdr->wnd[0] << 8) + (u16_t) tcp_hdr->wnd[1]; +- if (tmp16 > uip_connr->initialmss || tmp16 == 0) +- tmp16 = uip_connr->initialmss; +- uip_connr->mss = tmp16; +- +- /* If this packet constitutes an ACK for outstanding data +- (flagged by the UIP_ACKDATA flag, we should call the +- application since it might want to send more data. +- If the incoming packet had data from the peer +- (as flagged by the UIP_NEWDATA flag), the application +- must also be notified. +- +- When the application is called, the global variable uip_len +- contains the length of the incoming data. The application can +- access the incoming data through the global pointer +- uip_appdata, which usually points uip_ip_tcph_len + +- UIP_LLH_LEN bytes into the uip_buf array. +- +- If the application wishes to send any data, this data should +- be put into the uip_appdata and the length of the data should +- be put into uip_len. If the application don't have any data +- to send, uip_len must be set to 0. */ +- if (ustack->uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) { +- ustack->uip_slen = 0; +- UIP_APPCALL(ustack); +- +-appsend: +- +- if (ustack->uip_flags & UIP_ABORT) { +- ustack->uip_slen = 0; +- uip_connr->tcpstateflags = UIP_CLOSED; +- tcp_hdr->flags = TCP_RST | TCP_ACK; +- goto tcp_send_nodata; +- } +- +- if (ustack->uip_flags & UIP_CLOSE) { +- ustack->uip_slen = 0; +- uip_connr->len = 1; +- uip_connr->tcpstateflags = UIP_FIN_WAIT_1; +- uip_connr->nrtx = 0; +- tcp_hdr->flags = TCP_FIN | TCP_ACK; +- goto tcp_send_nodata; +- } +- +- /* If uip_slen > 0, the application has data to be sent +- */ +- if (ustack->uip_slen > 0) { +- +- /* If the connection has acknowledged data, the +- contents of the ->len variable should be +- discarded. */ +- if ((ustack->uip_flags & UIP_ACKDATA) != 0) +- uip_connr->len = 0; +- +- /* If the ->len variable is non-zero the +- connection has already data in transit and +- cannot send anymore right now. */ +- if (uip_connr->len == 0) { +- +- /* The application cannot send more than +- what is allowed by the mss (the +- minumum of the MSS and the available +- window). */ +- if (ustack->uip_slen > uip_connr->mss) { +- ustack->uip_slen = +- uip_connr->mss; +- } +- +- /* Remember how much data we send out +- now so that we know when everything +- has been acknowledged. */ +- uip_connr->len = ustack->uip_slen; +- } else { +- +- /* If the application already had +- unacknowledged data, we make sure +- that the application does not send +- (i.e., retransmit) out more than it +- previously sent out. */ +- ustack->uip_slen = uip_connr->len; +- } +- } +- uip_connr->nrtx = 0; +-apprexmit: +- ustack->uip_appdata = ustack->uip_sappdata; +- +- /* If the application has data to be sent, or if the +- incoming packet had new data in it, we must send +- out a packet. */ +- if (ustack->uip_slen > 0 && uip_connr->len > 0) { +- /* Add the length of the IP and TCP headers. */ +- ustack->uip_len = +- uip_connr->len + uip_ip_tcph_len; +- /* We always set the ACK flag in response +- packets. */ +- tcp_hdr->flags = TCP_ACK | TCP_PSH; +- /* Send the packet. */ +- goto tcp_send_noopts; +- } +- /* If there is no data to send, just send out a pure ACK +- if there is newdata. */ +- if (ustack->uip_flags & UIP_NEWDATA) { +- ustack->uip_len = uip_ip_tcph_len; +- tcp_hdr->flags = TCP_ACK; +- goto tcp_send_noopts; +- } +- } +- goto drop; +- case UIP_LAST_ACK: +- /* We can close this connection if the peer has acknowledged our +- FIN. This is indicated by the UIP_ACKDATA flag. */ +- if (ustack->uip_flags & UIP_ACKDATA) { +- uip_connr->tcpstateflags = UIP_CLOSED; +- ustack->uip_flags = UIP_CLOSE; +- UIP_APPCALL(ustack); +- } +- break; +- +- case UIP_FIN_WAIT_1: +- /* The application has closed the connection, but the remote +- host hasn't closed its end yet. Thus we do nothing but wait +- for a FIN from the other side. */ +- if (ustack->uip_len > 0) +- uip_add_rcv_nxt(ustack, ustack->uip_len); +- if (tcp_hdr->flags & TCP_FIN) { +- if (ustack->uip_flags & UIP_ACKDATA) { +- uip_connr->tcpstateflags = UIP_TIME_WAIT; +- uip_connr->timer = 0; +- uip_connr->len = 0; +- } else { +- uip_connr->tcpstateflags = UIP_CLOSING; +- } +- uip_add_rcv_nxt(ustack, 1); +- ustack->uip_flags = UIP_CLOSE; +- UIP_APPCALL(ustack); +- goto tcp_send_ack; +- } else if (ustack->uip_flags & UIP_ACKDATA) { +- uip_connr->tcpstateflags = UIP_FIN_WAIT_2; +- uip_connr->len = 0; +- goto drop; +- } +- if (ustack->uip_len > 0) +- goto tcp_send_ack; +- goto drop; +- +- case UIP_FIN_WAIT_2: +- if (ustack->uip_len > 0) +- uip_add_rcv_nxt(ustack, ustack->uip_len); +- if (tcp_hdr->flags & TCP_FIN) { +- uip_connr->tcpstateflags = UIP_TIME_WAIT; +- uip_connr->timer = 0; +- uip_add_rcv_nxt(ustack, 1); +- ustack->uip_flags = UIP_CLOSE; +- UIP_APPCALL(ustack); +- goto tcp_send_ack; +- } +- if (ustack->uip_len > 0) +- goto tcp_send_ack; +- goto drop; +- +- case UIP_TIME_WAIT: +- goto tcp_send_ack; +- +- case UIP_CLOSING: +- if (ustack->uip_flags & UIP_ACKDATA) { +- uip_connr->tcpstateflags = UIP_TIME_WAIT; +- uip_connr->timer = 0; +- } +- } +- goto drop; +- +- /* We jump here when we are ready to send the packet, and just want +- to set the appropriate TCP sequence numbers in the TCP header. */ +-tcp_send_ack: +- tcp_hdr->flags = TCP_ACK; +-tcp_send_nodata: +- ustack->uip_len = uip_ip_tcph_len; +-tcp_send_noopts: +- tcp_hdr->tcpoffset = (UIP_TCPH_LEN / 4) << 4; +-tcp_send: +- /* We're done with the input processing. We are now ready to send a +- reply. Our job is to fill in all the fields of the TCP and IP +- headers before calculating the checksum and finally send the +- packet. */ +- tcp_hdr->ackno[0] = uip_connr->rcv_nxt[0]; +- tcp_hdr->ackno[1] = uip_connr->rcv_nxt[1]; +- tcp_hdr->ackno[2] = uip_connr->rcv_nxt[2]; +- tcp_hdr->ackno[3] = uip_connr->rcv_nxt[3]; +- +- tcp_hdr->seqno[0] = uip_connr->snd_nxt[0]; +- tcp_hdr->seqno[1] = uip_connr->snd_nxt[1]; +- tcp_hdr->seqno[2] = uip_connr->snd_nxt[2]; +- tcp_hdr->seqno[3] = uip_connr->snd_nxt[3]; +- +- if (is_ipv6(ustack)) { +- IPv6_BUF(ustack)->proto = UIP_PROTO_TCP; +- uip_ip6addr_copy(IPv6_BUF(ustack)->srcipaddr, +- ustack->hostaddr6); +- uip_ip6addr_copy(IPv6_BUF(ustack)->destipaddr, +- uip_connr->ripaddr6); +- } else { +- tcp_ipv4_hdr->proto = UIP_PROTO_TCP; +- uip_ip4addr_copy(tcp_ipv4_hdr->srcipaddr, ustack->hostaddr); +- uip_ip4addr_copy(tcp_ipv4_hdr->destipaddr, uip_connr->ripaddr); +- } +- +- tcp_hdr->srcport = uip_connr->lport; +- tcp_hdr->destport = uip_connr->rport; +- +- if (uip_connr->tcpstateflags & UIP_STOPPED) { +- /* If the connection has issued uip_stop(), we advertise a zero +- window so that the remote host will stop sending data. */ +- tcp_hdr->wnd[0] = tcp_hdr->wnd[1] = 0; +- } else { +- tcp_hdr->wnd[0] = ((UIP_RECEIVE_WINDOW) >> 8); +- tcp_hdr->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff); +- } +- +-tcp_send_noconn: +- if (is_ipv6(ustack)) { +- IPv6_BUF(ustack)->ttl = UIP_TTL; +- +- /* For IPv6, the IP length field does not include the IPv6 IP +- header length. */ +- IPv6_BUF(ustack)->len[0] = +- ((ustack->uip_len - uip_iph_len) >> 8); +- IPv6_BUF(ustack)->len[1] = +- ((ustack->uip_len - uip_iph_len) & 0xff); +- } else { +- tcp_ipv4_hdr->ttl = UIP_TTL; +- tcp_ipv4_hdr->len[0] = (ustack->uip_len >> 8); +- tcp_ipv4_hdr->len[1] = (ustack->uip_len & 0xff); +- } +- +- tcp_hdr->urgp[0] = tcp_hdr->urgp[1] = 0; +- +- /* Calculate TCP checksum. */ +- tcp_hdr->tcpchksum = 0; +- tcp_hdr->tcpchksum = ~(uip_tcpchksum(ustack)); +- +-ip_send_nolen: +- +- if (!is_ipv6(ustack)) { +- tcp_ipv4_hdr->vhl = 0x45; +- tcp_ipv4_hdr->tos = 0; +- tcp_ipv4_hdr->ipoffset[0] = tcp_ipv4_hdr->ipoffset[1] = 0; +- ++ustack->ipid; +- tcp_ipv4_hdr->ipid[0] = ustack->ipid >> 8; +- tcp_ipv4_hdr->ipid[1] = ustack->ipid & 0xff; +- /* Calculate IP checksum. */ +- tcp_ipv4_hdr->ipchksum = 0; +- tcp_ipv4_hdr->ipchksum = ~(uip_ipchksum(ustack)); +- } +- +- ++ustack->stats.tcp.sent; +-send: +- if (is_ipv6(ustack)) { +- LOG_DEBUG(PFX "Sending packet with length %d (%d)", +- ustack->uip_len, ipv6_hdr ? ipv6_hdr->ip6_plen : 0); +- } else { +- LOG_DEBUG(PFX "Sending packet with length %d (%d)", +- ustack->uip_len, +- (tcp_ipv4_hdr->len[0] << 8) | tcp_ipv4_hdr->len[1]); +- } +- ++ustack->stats.ip.sent; +- /* Return and let the caller do the actual transmission. */ +- ustack->uip_flags = 0; +- return; +-drop: +- ustack->uip_len = 0; +- ustack->uip_flags = 0; +- return; +-} +- +-/*---------------------------------------------------------------------------*/ +-void uip_send(struct uip_stack *ustack, const void *data, int len) +-{ +- if (len > 0) { +- ustack->uip_slen = len; +- if (data != ustack->uip_buf) +- memcpy(ustack->uip_buf, (data), ustack->uip_slen); +- } +-} +- +-void uip_appsend(struct uip_stack *ustack, const void *data, int len) +-{ +- if (len > 0) { +- ustack->uip_slen = len; +- if (data != ustack->uip_sappdata) +- memcpy(ustack->uip_sappdata, (data), ustack->uip_slen); +- } +-} +- +-u16_t uip_datalen(struct uip_stack *ustack) +-{ +- return ustack->uip_len; +-} +- +-/** @} */ +diff --git a/iscsiuio/src/uip/uip.h b/iscsiuio/src/uip/uip.h +deleted file mode 100644 +index 9d9428a..0000000 +--- a/iscsiuio/src/uip/uip.h ++++ /dev/null +@@ -1,1574 +0,0 @@ +- +-/** +- * \addtogroup uip +- * @{ +- */ +- +-/** +- * \file +- * Header file for the uIP TCP/IP stack. +- * \author Adam Dunkels +- * +- * The uIP TCP/IP stack header file contains definitions for a number +- * of C macros that are used by uIP programs as well as internal uIP +- * structures, TCP/IP header structures and function declarations. +- * +- */ +- +-/* +- * Copyright (c) 2001-2003, Adam Dunkels. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * This file is part of the uIP TCP/IP stack. +- * +- * +- */ +- +-#ifndef __UIP_H__ +-#define __UIP_H__ +- +-#include +-#include +- +-#include "uipopt.h" +- +-#include "debug.h" +- +-#include "uip_eth.h" +- +-/* Forware declaration */ +-struct uip_stack; +- +-/** +- * Repressentation of an IP address. +- * +- */ +-typedef u16_t uip_ip4addr_t[2]; +-typedef u16_t uip_ip6addr_t[8]; +- +-extern const uip_ip6addr_t all_zeroes_addr6; +-extern const uip_ip4addr_t all_zeroes_addr4; +- +-#define ETH_BUF(buf) ((struct uip_eth_hdr *)buf) +-#define VLAN_ETH_BUF(buf) ((struct uip_vlan_eth_hdr *)buf) +-#define IPv4_BUF(buf) ((struct uip_tcp_ipv4_hdr *)buf) +-#define IPv6_BUF(buf) ((struct uip_tcp_ipv6_hdr *)buf) +- +-/*---------------------------------------------------------------------------*/ +-/* First, the functions that should be called from the +- * system. Initialization, the periodic timer and incoming packets are +- * handled by the following three functions. +- */ +- +-/** +- * Set the IP address of this host. +- * +- * The IP address is represented as a 4-byte array where the first +- * octet of the IP address is put in the first member of the 4-byte +- * array. +- * +- * Example: +- \code +- +- uip_ipaddr_t addr; +- +- uip_ipaddr(&addr, 192,168,1,2); +- uip_sethostaddr(&addr); +- +- \endcode +- * \param addr A pointer to an IP address of type uip_ipaddr_t; +- * +- * \sa uip_ipaddr() +- * +- * \hideinitializer +- */ +-void uip_sethostaddr4(struct uip_stack *ustack, uip_ip4addr_t *addr); +- +-/** +- * Set the default router's IP address. +- * +- * \param addr A pointer to a uip_ipaddr_t variable containing the IP +- * address of the default router. +- * +- * \sa uip_ipaddr() +- * +- * \hideinitializer +- */ +-void uip_setdraddr4(struct uip_stack *ustack, uip_ip4addr_t *addr); +- +-/** +- * Set the netmask. +- * +- * \param addr A pointer to a uip_ipaddr_t variable containing the IP +- * address of the netmask. +- * +- * \sa uip_ipaddr() +- * +- * \hideinitializer +- */ +-void uip_setnetmask4(struct uip_stack *ustack, uip_ip4addr_t *addr); +- +-/** +- * Set the ethernet MAC address. +- * +- * \param addr A pointer to a uip_ipaddr_t variable containing the IP +- * address of the netmask. +- * +- * \sa uip_ipaddr() +- * +- * \hideinitializer +- */ +-void uip_setethernetmac(struct uip_stack *ustack, uint8_t *mac); +- +-/** +- * Get the default router's IP address. +- * +- * \param addr A pointer to a uip_ipaddr_t variable that will be +- * filled in with the IP address of the default router. +- * +- * \hideinitializer +- */ +-#define uip_getdraddr(addr) uip_ipaddr_copy((addr), uip_draddr) +- +-/** +- * Get the netmask. +- * +- * \param addr A pointer to a uip_ipaddr_t variable that will be +- * filled in with the value of the netmask. +- * +- * \hideinitializer +- */ +-#define uip_getnetmask(addr) uip_ipaddr_copy((addr), uip_netmask) +- +-void set_uip_stack(struct uip_stack *ustack, +- uip_ip4addr_t *ip, +- uip_ip4addr_t *netmask, +- uip_ip4addr_t *default_route, uint8_t *mac_addr); +- +-/** @} */ +- +-/** +- * \defgroup uipinit uIP initialization functions +- * @{ +- * +- * The uIP initialization functions are used for booting uIP. +- */ +- +-/** +- * uIP initialization function. +- * +- * This function should be called at boot up to initilize the uIP +- * TCP/IP stack. +- */ +-void uip_init(struct uip_stack *ustack, uint8_t enable_ipv6); +- +-/** +- * uIP reset function. +- * +- * This function should be called at to reset the uIP TCP/IP stack. +- */ +-void uip_reset(struct uip_stack *ustack); +- +-/** +- * uIP initialization function. +- * +- * This function may be used at boot time to set the initial ip_id. +- */ +-void uip_setipid(u16_t id); +- +-/** +- * +- * +- */ +-#define uip_conn_active(conn) (uip_conns[conn].tcpstateflags != UIP_CLOSED) +- +-#if UIP_UDP +-void uip_udp_periodic(struct uip_stack *ustack, int conn); +-#endif /* UIP_UDP */ +- +-void uip_ndp_periodic(struct uip_stack *ustack); +- +-/** +- * The uIP packet buffer. +- * +- * The uip_buf array is used to hold incoming and outgoing +- * packets. The device driver should place incoming data into this +- * buffer. When sending data, the device driver should read the link +- * level headers and the TCP/IP headers from this buffer. The size of +- * the link level headers is configured by the UIP_LLH_LEN define. +- * +- * \note The application data need not be placed in this buffer, so +- * the device driver must read it from the place pointed to by the +- * uip_appdata pointer as illustrated by the following example: +- \code +- void +- devicedriver_send(void) +- { +- hwsend(&uip_buf[0], UIP_LLH_LEN); +- if(uip_len <= UIP_LLH_LEN + UIP_TCPIP_HLEN) { +- hwsend(&uip_buf[UIP_LLH_LEN], uip_len - UIP_LLH_LEN); +- } else { +- hwsend(&uip_buf[UIP_LLH_LEN], UIP_TCPIP_HLEN); +- hwsend(uip_appdata, uip_len - UIP_TCPIP_HLEN - UIP_LLH_LEN); +- } +- } +- \endcode +- */ +-/*extern u8_t uip_buf[UIP_BUFSIZE+2]; */ +- +-/** @} */ +- +-/*---------------------------------------------------------------------------*/ +-/* Functions that are used by the uIP application program. Opening and +- * closing connections, sending and receiving data, etc. is all +- * handled by the functions below. +-*/ +-/** +- * \defgroup uipappfunc uIP application functions +- * @{ +- * +- * Functions used by an application running of top of uIP. +- */ +- +-/** +- * Start listening to the specified port. +- * +- * \note Since this function expects the port number in network byte +- * order, a conversion using HTONS() or htons() is necessary. +- * +- \code +- uip_listen(HTONS(80)); +- \endcode +- * +- * \param port A 16-bit port number in network byte order. +- */ +-void uip_listen(struct uip_stack *ustack, u16_t port); +- +-/** +- * Stop listening to the specified port. +- * +- * \note Since this function expects the port number in network byte +- * order, a conversion using HTONS() or htons() is necessary. +- * +- \code +- uip_unlisten(HTONS(80)); +- \endcode +- * +- * \param port A 16-bit port number in network byte order. +- */ +-void uip_unlisten(struct uip_stack *ustack, u16_t port); +- +-/** +- * Connect to a remote host using TCP. +- * +- * This function is used to start a new connection to the specified +- * port on the specied host. It allocates a new connection identifier, +- * sets the connection to the SYN_SENT state and sets the +- * retransmission timer to 0. This will cause a TCP SYN segment to be +- * sent out the next time this connection is periodically processed, +- * which usually is done within 0.5 seconds after the call to +- * uip_connect(). +- * +- * \note This function is avaliable only if support for active open +- * has been configured by defining UIP_ACTIVE_OPEN to 1 in uipopt.h. +- * +- * \note Since this function requires the port number to be in network +- * byte order, a conversion using HTONS() or htons() is necessary. +- * +- \code +- uip_ipaddr_t ipaddr; +- +- uip_ipaddr(&ipaddr, 192,168,1,2); +- uip_connect(&ipaddr, HTONS(80)); +- \endcode +- * +- * \param ripaddr The IP address of the remote hot. +- * +- * \param port A 16-bit port number in network byte order. +- * +- * \return A pointer to the uIP connection identifier for the new connection, +- * or NULL if no connection could be allocated. +- * +- */ +-struct uip_conn *uip_connect(struct uip_stack *ustack, +- uip_ip4addr_t *ripaddr, u16_t port); +- +-/** +- * \internal +- * +- * Check if a connection has outstanding (i.e., unacknowledged) data. +- * +- * \param conn A pointer to the uip_conn structure for the connection. +- * +- * \hideinitializer +- */ +-#define uip_outstanding(conn) ((conn)->len) +- +-/** +- * Send data on the current connection. +- * +- * This function is used to send out a single segment of TCP +- * data. Only applications that have been invoked by uIP for event +- * processing can send data. +- * +- * The amount of data that actually is sent out after a call to this +- * funcion is determined by the maximum amount of data TCP allows. uIP +- * will automatically crop the data so that only the appropriate +- * amount of data is sent. The function uip_mss() can be used to query +- * uIP for the amount of data that actually will be sent. +- * +- * \note This function does not guarantee that the sent data will +- * arrive at the destination. If the data is lost in the network, the +- * application will be invoked with the uip_rexmit() event being +- * set. The application will then have to resend the data using this +- * function. +- * +- * \param data A pointer to the data which is to be sent. +- * +- * \param len The maximum amount of data bytes to be sent. +- * +- * \hideinitializer +- */ +-void uip_send(struct uip_stack *ustack, const void *data, int len); +-void uip_appsend(struct uip_stack *ustack, const void *data, int len); +- +-/** +- * The length of any incoming data that is currently avaliable (if avaliable) +- * in the uip_appdata buffer. +- * +- * The test function uip_data() must first be used to check if there +- * is any data available at all. +- * +- * \hideinitializer +- */ +-/*void uip_datalen(void);*/ +-u16_t uip_datalen(struct uip_stack *ustack); +- +-/** +- * The length of any out-of-band data (urgent data) that has arrived +- * on the connection. +- * +- * \note The configuration parameter UIP_URGDATA must be set for this +- * function to be enabled. +- * +- * \hideinitializer +- */ +-#define uip_urgdatalen() uip_urglen +- +-/** +- * Close the current connection. +- * +- * This function will close the current connection in a nice way. +- * +- * \hideinitializer +- */ +-#define uip_close() (uip_flags = UIP_CLOSE) +- +-/** +- * Abort the current connection. +- * +- * This function will abort (reset) the current connection, and is +- * usually used when an error has occured that prevents using the +- * uip_close() function. +- * +- * \hideinitializer +- */ +-#define uip_abort() (uip_flags = UIP_ABORT) +- +-/** +- * Tell the sending host to stop sending data. +- * +- * This function will close our receiver's window so that we stop +- * receiving data for the current connection. +- * +- * \hideinitializer +- */ +-#define uip_stop() (uip_conn->tcpstateflags |= UIP_STOPPED) +- +-/** +- * Find out if the current connection has been previously stopped with +- * uip_stop(). +- * +- * \hideinitializer +- */ +-#define uip_stopped(conn) ((conn)->tcpstateflags & UIP_STOPPED) +- +-/** +- * Restart the current connection, if is has previously been stopped +- * with uip_stop(). +- * +- * This function will open the receiver's window again so that we +- * start receiving data for the current connection. +- * +- * \hideinitializer +- */ +-#define uip_restart() do { uip_flags |= UIP_NEWDATA; \ +- uip_conn->tcpstateflags &= ~UIP_STOPPED; \ +- } while (0) +- +-/* uIP tests that can be made to determine in what state the current +- connection is, and what the application function should do. */ +- +-/** +- * Is the current connection a UDP connection? +- * +- * This function checks whether the current connection is a UDP connection. +- * +- * \hideinitializer +- * +- */ +-#define uip_udpconnection() (uip_conn == NULL) +- +-/** +- * Function declarations for hte uip_flags +- */ +-/** +- * Is new incoming data available? +- * +- * Will reduce to non-zero if there is new data for the application +- * present at the uip_appdata pointer. The size of the data is +- * avaliable through the uip_len variable. +- * +- * \hideinitializer +- */ +-int uip_newdata(struct uip_stack *ustack); +- +-/** +- * Has previously sent data been acknowledged? +- * +- * Will reduce to non-zero if the previously sent data has been +- * acknowledged by the remote host. This means that the application +- * can send new data. +- * +- * \hideinitializer +- */ +-int uip_acked(struct uip_stack *ustack); +- +-/** +- * Has the connection just been connected? +- * +- * Reduces to non-zero if the current connection has been connected to +- * a remote host. This will happen both if the connection has been +- * actively opened (with uip_connect()) or passively opened (with +- * uip_listen()). +- * +- * \hideinitializer +- */ +-int uip_connected(struct uip_stack *ustack); +- +-/** +- * Has the connection been closed by the other end? +- * +- * Is non-zero if the connection has been closed by the remote +- * host. The application may then do the necessary clean-ups. +- * +- * \hideinitializer +- */ +-int uip_closed(struct uip_stack *ustack); +- +-/** +- * Has the connection been aborted by the other end? +- * +- * Non-zero if the current connection has been aborted (reset) by the +- * remote host. +- * +- * \hideinitializer +- */ +-int uip_aborted(struct uip_stack *ustack); +- +-/** +- * Has the connection timed out? +- * +- * Non-zero if the current connection has been aborted due to too many +- * retransmissions. +- * +- * \hideinitializer +- */ +-int uip_timedout(struct uip_stack *ustack); +- +-/** +- * Do we need to retransmit previously data? +- * +- * Reduces to non-zero if the previously sent data has been lost in +- * the network, and the application should retransmit it. The +- * application should send the exact same data as it did the last +- * time, using the uip_send() function. +- * +- * \hideinitializer +- */ +-int uip_rexmit(struct uip_stack *ustack); +- +-/** +- * Is the connection being polled by uIP? +- * +- * Is non-zero if the reason the application is invoked is that the +- * current connection has been idle for a while and should be +- * polled. +- * +- * The polling event can be used for sending data without having to +- * wait for the remote host to send data. +- * +- * \hideinitializer +- */ +-int uip_poll(struct uip_stack *ustack); +- +-/** +- * Get the initial maxium segment size (MSS) of the current +- * connection. +- * +- * \hideinitializer +- */ +-int uip_initialmss(struct uip_stack *ustack); +- +-/** +- * Get the current maxium segment size that can be sent on the current +- * connection. +- * +- * The current maxiumum segment size that can be sent on the +- * connection is computed from the receiver's window and the MSS of +- * the connection (which also is available by calling +- * uip_initialmss()). +- * +- * \hideinitializer +- */ +-int uip_mss(struct uip_stack *ustack); +- +-/** +- * Set up a new UDP connection. +- * +- * This function sets up a new UDP connection. The function will +- * automatically allocate an unused local port for the new +- * connection. However, another port can be chosen by using the +- * uip_udp_bind() call, after the uip_udp_new() function has been +- * called. +- * +- * Example: +- \code +- uip_ipaddr_t addr; +- struct uip_udp_conn *c; +- +- uip_ipaddr(&addr, 192,168,2,1); +- c = uip_udp_new(&addr, HTONS(12345)); +- if(c != NULL) { +- uip_udp_bind(c, HTONS(12344)); +- } +- \endcode +- * \param ripaddr The IP address of the remote host. +- * +- * \param rport The remote port number in network byte order. +- * +- * \return The uip_udp_conn structure for the new connection or NULL +- * if no connection could be allocated. +- */ +-struct uip_udp_conn *uip_udp_new(struct uip_stack *ustack, +- uip_ip4addr_t *ripaddr, u16_t rport); +- +-/** +- * Removed a UDP connection. +- * +- * \param conn A pointer to the uip_udp_conn structure for the connection. +- * +- * \hideinitializer +- */ +-#define uip_udp_remove(conn) ((conn)->lport = 0) +- +-/** +- * Bind a UDP connection to a local port. +- * +- * \param conn A pointer to the uip_udp_conn structure for the +- * connection. +- * +- * \param port The local port number, in network byte order. +- * +- * \hideinitializer +- */ +-#define uip_udp_bind(conn, port) ((conn)->lport = port) +- +-/** +- * Send a UDP datagram of length len on the current connection. +- * +- * This function can only be called in response to a UDP event (poll +- * or newdata). The data must be present in the uip_buf buffer, at the +- * place pointed to by the uip_appdata pointer. +- * +- * \param len The length of the data in the uip_buf buffer. +- * +- * \hideinitializer +- */ +-#define uip_udp_send(len) uip_appsend((char *)uip_appdata, len) +- +-/** @} */ +- +-/* uIP convenience and converting functions. */ +- +-/** +- * \defgroup uipconvfunc uIP conversion functions +- * @{ +- * +- * These functions can be used for converting between different data +- * formats used by uIP. +- */ +- +-/** +- * Construct an IP address from four bytes. +- * +- * This function constructs an IP address of the type that uIP handles +- * internally from four bytes. The function is handy for specifying IP +- * addresses to use with e.g. the uip_connect() function. +- * +- * Example: +- \code +- uip_ipaddr_t ipaddr; +- struct uip_conn *c; +- +- uip_ipaddr(&ipaddr, 192,168,1,2); +- c = uip_connect(&ipaddr, HTONS(80)); +- \endcode +- * +- * \param addr A pointer to a uip_ipaddr_t variable that will be +- * filled in with the IP address. +- * +- * \param addr0 The first octet of the IP address. +- * \param addr1 The second octet of the IP address. +- * \param addr2 The third octet of the IP address. +- * \param addr3 The forth octet of the IP address. +- * +- * \hideinitializer +- */ +-#define uip_ipaddr(addr, addr0, addr1, addr2, addr3) do { \ +- ((u16_t *)(addr))[0] = const_htons(((addr0) << 8) | (addr1)); \ +- ((u16_t *)(addr))[1] = const_htons(((addr2) << 8) | (addr3)); \ +- } while (0) +- +-/** +- * Construct an IPv6 address from eight 16-bit words. +- * +- * This function constructs an IPv6 address. +- * +- * \hideinitializer +- */ +-#define uip_ip6addr(addr, addr0, addr1, addr2, addr3, addr4, addr5, addr6, \ +- addr7) \ +- do { \ +- ((u16_t *)(addr))[0] = HTONS((addr0)); \ +- ((u16_t *)(addr))[1] = HTONS((addr1)); \ +- ((u16_t *)(addr))[2] = HTONS((addr2)); \ +- ((u16_t *)(addr))[3] = HTONS((addr3)); \ +- ((u16_t *)(addr))[4] = HTONS((addr4)); \ +- ((u16_t *)(addr))[5] = HTONS((addr5)); \ +- ((u16_t *)(addr))[6] = HTONS((addr6)); \ +- ((u16_t *)(addr))[7] = HTONS((addr7)); \ +- } while (0) +- +-/** +- * Copy an IP address to another IP address. +- * +- * Copies an IP address from one place to another. +- * +- * Example: +- \code +- uip_ipaddr_t ipaddr1, ipaddr2; +- +- uip_ipaddr(&ipaddr1, 192,16,1,2); +- uip_ipaddr_copy(&ipaddr2, &ipaddr1); +- \endcode +- * +- * \param dest The destination for the copy. +- * \param src The source from where to copy. +- * +- * \hideinitializer +- */ +-#define uip_ip4addr_copy(dest, src) memcpy(dest, src, sizeof(uip_ip4addr_t)) +-#define uip_ip6addr_copy(dest, src) memcpy(dest, src, sizeof(uip_ip6addr_t)) +- +-/** +- * Compare two IP addresses +- * +- * Compares two IP addresses. +- * +- * Example: +- \code +- uip_ipaddr_t ipaddr1, ipaddr2; +- +- uip_ipaddr(&ipaddr1, 192,16,1,2); +- if(uip_ipaddr_cmp(&ipaddr2, &ipaddr1)) { +- printf("They are the same"); +- } +- \endcode +- * +- * \param addr1 The first IP address. +- * \param addr2 The second IP address. +- * +- * \hideinitializer +- */ +-#define uip_ip4addr_cmp(addr1, addr2) (memcmp(addr1, addr2, \ +- sizeof(uip_ip4addr_t)) == 0) +-#define uip_ip6addr_cmp(addr1, addr2) (memcmp(addr1, addr2, \ +- sizeof(uip_ip6addr_t)) == 0) +- +-/** +- * Compare two IP addresses with netmasks +- * +- * Compares two IP addresses with netmasks. The masks are used to mask +- * out the bits that are to be compared. +- * +- * Example: +- \code +- uip_ipaddr_t ipaddr1, ipaddr2, mask; +- +- uip_ipaddr(&mask, 255,255,255,0); +- uip_ipaddr(&ipaddr1, 192,16,1,2); +- uip_ipaddr(&ipaddr2, 192,16,1,3); +- if(uip_ipaddr_maskcmp(&ipaddr1, &ipaddr2, &mask)) { +- printf("They are the same"); +- } +- \endcode +- * +- * \param addr1 The first IP address. +- * \param addr2 The second IP address. +- * \param mask The netmask. +- * +- * \hideinitializer +- */ +-#define uip_ip4addr_maskcmp(addr1, addr2, mask) \ +- (((((u16_t *)addr1)[0] & ((u16_t *)mask)[0]) == \ +- (((u16_t *)addr2)[0] & ((u16_t *)mask)[0])) && \ +- ((((u16_t *)addr1)[1] & ((u16_t *)mask)[1]) == \ +- (((u16_t *)addr2)[1] & ((u16_t *)mask)[1]))) +- +-/** +- * Mask out the network part of an IP address. +- * +- * Masks out the network part of an IP address, given the address and +- * the netmask. +- * +- * Example: +- \code +- uip_ipaddr_t ipaddr1, ipaddr2, netmask; +- +- uip_ipaddr(&ipaddr1, 192,16,1,2); +- uip_ipaddr(&netmask, 255,255,255,0); +- uip_ipaddr_mask(&ipaddr2, &ipaddr1, &netmask); +- \endcode +- * +- * In the example above, the variable "ipaddr2" will contain the IP +- * address 192.168.1.0. +- * +- * \param dest Where the result is to be placed. +- * \param src The IP address. +- * \param mask The netmask. +- * +- * \hideinitializer +- */ +-#define uip_ip4addr_mask(dest, src, mask) do { \ +- ((u16_t *)dest)[0] = ((u16_t *)src)[0] & ((u16_t *)mask)[0]; \ +- ((u16_t *)dest)[1] = ((u16_t *)src)[1] & ((u16_t *)mask)[1]; \ +- } while (0) +- +-/** +- * Pick the first octet of an IP address. +- * +- * Picks out the first octet of an IP address. +- * +- * Example: +- \code +- uip_ipaddr_t ipaddr; +- u8_t octet; +- +- uip_ipaddr(&ipaddr, 1,2,3,4); +- octet = uip_ipaddr1(&ipaddr); +- \endcode +- * +- * In the example above, the variable "octet" will contain the value 1. +- * +- * \hideinitializer +- */ +-#define uip_ipaddr1(addr) (htons(((u16_t *)(addr))[0]) >> 8) +- +-/** +- * Pick the second octet of an IP address. +- * +- * Picks out the second octet of an IP address. +- * +- * Example: +- \code +- uip_ipaddr_t ipaddr; +- u8_t octet; +- +- uip_ipaddr(&ipaddr, 1,2,3,4); +- octet = uip_ipaddr2(&ipaddr); +- \endcode +- * +- * In the example above, the variable "octet" will contain the value 2. +- * +- * \hideinitializer +- */ +-#define uip_ipaddr2(addr) (htons(((u16_t *)(addr))[0]) & 0xff) +- +-/** +- * Pick the third octet of an IP address. +- * +- * Picks out the third octet of an IP address. +- * +- * Example: +- \code +- uip_ipaddr_t ipaddr; +- u8_t octet; +- +- uip_ipaddr(&ipaddr, 1,2,3,4); +- octet = uip_ipaddr3(&ipaddr); +- \endcode +- * +- * In the example above, the variable "octet" will contain the value 3. +- * +- * \hideinitializer +- */ +-#define uip_ipaddr3(addr) (htons(((u16_t *)(addr))[1]) >> 8) +- +-/** +- * Pick the fourth octet of an IP address. +- * +- * Picks out the fourth octet of an IP address. +- * +- * Example: +- \code +- uip_ipaddr_t ipaddr; +- u8_t octet; +- +- uip_ipaddr(&ipaddr, 1,2,3,4); +- octet = uip_ipaddr4(&ipaddr); +- \endcode +- * +- * In the example above, the variable "octet" will contain the value 4. +- * +- * \hideinitializer +- */ +-#define uip_ipaddr4(addr) (htons(((u16_t *)(addr))[1]) & 0xff) +- +-/** +- * Convert 16-bit quantity from host byte order to network byte order. +- * +- * This macro is primarily used for converting constants from host +- * byte order to network byte order. For converting variables to +- * network byte order, use the htons() function instead. +- * +- * \hideinitializer +- */ +-#if 0 +-#ifndef HTONS +-# if UIP_BYTE_ORDER == UIP_BIG_ENDIAN +-# define HTONS(n) (n) +-# else /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */ +-# define HTONS(n) (u16_t)((((u16_t) (n)) << 8) | (((u16_t) (n)) >> 8)) +-# endif /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */ +-#else +-#error "HTONS already defined!" +-#endif /* HTONS */ +-#endif +- +-#if UIP_BYTE_ORDER == UIP_BIG_ENDIAN +-# error "Should not be here" +-# define const_htons(n) (n) +-# else /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */ +-# define const_htons(n) (u16_t)((((u16_t) (n)) << 8) | (((u16_t) (n)) >> 8)) +-# endif /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */ +- +-/* BWL */ +-#if 0 +-/** +- * Convert 16-bit quantity from host byte order to network byte order. +- * +- * This function is primarily used for converting variables from host +- * byte order to network byte order. For converting constants to +- * network byte order, use the HTONS() macro instead. +- */ +-#ifndef htons +-u16_t htons(u16_t val); +-#endif /* htons */ +-#ifndef ntohs +-#define ntohs htons +-#endif +-#endif +- +-/** @} */ +- +-/** +- * Pointer to the application data in the packet buffer. +- * +- * This pointer points to the application data when the application is +- * called. If the application wishes to send data, the application may +- * use this space to write the data into before calling uip_send(). +- */ +-/* extern void *uip_appdata; */ +- +-#if UIP_URGDATA > 0 +-/* u8_t *uip_urgdata: +- * +- * This pointer points to any urgent data that has been received. Only +- * present if compiled with support for urgent data (UIP_URGDATA). +- */ +-extern void *uip_urgdata; +-#endif /* UIP_URGDATA > 0 */ +- +-/** +- * \defgroup uipdrivervars Variables used in uIP device drivers +- * @{ +- * +- * uIP has a few global variables that are used in device drivers for +- * uIP. +- */ +- +-/** +- * The length of the packet in the uip_buf buffer. +- * +- * The global variable uip_len holds the length of the packet in the +- * uip_buf buffer. +- * +- * When the network device driver calls the uIP input function, +- * uip_len should be set to the length of the packet in the uip_buf +- * buffer. +- * +- * When sending packets, the device driver should use the contents of +- * the uip_len variable to determine the length of the outgoing +- * packet. +- * +- */ +-/* extern u16_t uip_len; */ +- +-/** @} */ +- +-#if UIP_URGDATA > 0 +-extern u16_t uip_urglen, uip_surglen; +-#endif /* UIP_URGDATA > 0 */ +- +-/** +- * Representation of a uIP TCP connection. +- * +- * The uip_conn structure is used for identifying a connection. All +- * but one field in the structure are to be considered read-only by an +- * application. The only exception is the appstate field whos purpose +- * is to let the application store application-specific state (e.g., +- * file pointers) for the connection. The type of this field is +- * configured in the "uipopt.h" header file. +- */ +-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. */ +- u16_t rport; /**< The local remote TCP port, in network byte +- order. */ +- +- u8_t rcv_nxt[4]; +- /**< The sequence number that we expect to +- receive next. */ +- u8_t snd_nxt[4]; +- /**< The sequence number that was last sent by +- us. */ +- u16_t len; /**< Length of the data that was previously sent. */ +- u16_t mss; /**< Current maximum segment size for the +- connection. */ +- u16_t initialmss; +- /**< Initial maximum segment size for the +- connection. */ +- u8_t sa; /**< Retransmission time-out calculation state +- variable. */ +- u8_t sv; /**< Retransmission time-out calculation state +- variable. */ +- u8_t rto; /**< Retransmission time-out. */ +- u8_t tcpstateflags; +- /**< TCP state and flags. */ +- u8_t timer; /**< The retransmission timer. */ +- u8_t nrtx; /**< The number of retransmissions for the last +- segment sent. */ +-}; +- +-/** +- * \addtogroup uiparch +- * @{ +- */ +- +-/** +- * 4-byte array used for the 32-bit sequence number calculations. +- */ +-extern u8_t uip_acc32[4]; +- +-/** @} */ +- +-#if UIP_UDP +-/** +- * Representation of a uIP UDP connection. +- */ +-struct uip_udp_conn { +- uip_ip4addr_t ripaddr; +- /**< The IP address of the remote peer. */ +- u16_t lport; /**< The local port number in network byte order. */ +- u16_t rport; /**< The remote port number in network byte order. */ +- u8_t ttl; /**< Default time-to-live. */ +- +- /** The application state. */ +-/* uip_udp_appstate_t appstate; */ +-}; +- +-#endif /* UIP_UDP */ +- +-/** +- * The structure holding the TCP/IP statistics that are gathered if +- * UIP_STATISTICS is set to 1. +- * +- */ +-struct uip_stats { +- struct { +- uip_stats_t drop; +- /**< Number of dropped packets at the IP +- layer. */ +- uip_stats_t recv; +- /**< Number of received packets at the IP +- layer. */ +- uip_stats_t sent; +- /**< Number of sent packets at the IP +- layer. */ +- uip_stats_t vhlerr; +- /**< Number of packets dropped due to wrong +- IP version or header length. */ +- uip_stats_t hblenerr; +- /**< Number of packets dropped due to wrong +- IP length, high byte. */ +- uip_stats_t lblenerr; +- /**< Number of packets dropped due to wrong +- IP length, low byte. */ +- uip_stats_t fragerr; +- /**< Number of packets dropped since they +- were IP fragments. */ +- uip_stats_t chkerr; +- /**< Number of packets dropped due to IP +- checksum errors. */ +- uip_stats_t protoerr; +- /**< Number of packets dropped since they +- were neither ICMP, UDP nor TCP. */ +- } ip; /**< IP statistics. */ +- struct { +- uip_stats_t drop; +- /**< Number of dropped ICMP packets. */ +- uip_stats_t recv; +- /**< Number of received ICMP packets. */ +- uip_stats_t sent; +- /**< Number of sent ICMP packets. */ +- uip_stats_t typeerr; +- /**< Number of ICMP packets with a wrong +- type. */ +- } icmp; /**< ICMP statistics. */ +- struct { +- uip_stats_t drop; +- /**< Number of dropped TCP segments. */ +- uip_stats_t recv; +- /**< Number of recived TCP segments. */ +- uip_stats_t sent; +- /**< Number of sent TCP segments. */ +- uip_stats_t chkerr; +- /**< Number of TCP segments with a bad +- checksum. */ +- uip_stats_t ackerr; +- /**< Number of TCP segments with a bad ACK +- number. */ +- uip_stats_t rst; +- /**< Number of recevied TCP RST (reset) segments. */ +- uip_stats_t rexmit; +- /**< Number of retransmitted TCP segments. */ +- uip_stats_t syndrop; +- /**< Number of dropped SYNs due to too few +- connections was avaliable. */ +- uip_stats_t synrst; +- /**< Number of SYNs for closed ports, +- triggering a RST. */ +- } tcp; /**< TCP statistics. */ +-#if UIP_UDP +- struct { +- uip_stats_t drop; +- /**< Number of dropped UDP segments. */ +- uip_stats_t recv; +- /**< Number of recived UDP segments. */ +- uip_stats_t sent; +- /**< Number of sent UDP segments. */ +- uip_stats_t chkerr; +- /**< Number of UDP segments with a bad +- checksum. */ +- } udp; /**< UDP statistics. */ +-#endif /* UIP_UDP */ +-}; +- +-/*---------------------------------------------------------------------------*/ +-/* All the stuff below this point is internal to uIP and should not be +- * used directly by an application or by a device driver. +- */ +-/*---------------------------------------------------------------------------*/ +-/* u8_t uip_flags: +- * +- * When the application is called, uip_flags will contain the flags +- * that are defined in this file. Please read below for more +- * infomation. +- */ +-/* extern u8_t uip_flags; */ +- +-/* The following flags may be set in the global variable uip_flags +- before calling the application callback. The UIP_ACKDATA, +- UIP_NEWDATA, and UIP_CLOSE flags may both be set at the same time, +- whereas the others are mutualy exclusive. Note that these flags +- should *NOT* be accessed directly, but only through the uIP +- functions/macros. */ +- +-#define UIP_ACKDATA 1 /* Signifies that the outstanding data was +- acked and the application should send +- out new data instead of retransmitting +- the last data. */ +-#define UIP_NEWDATA 2 /* Flags the fact that the peer has sent +- us new data. */ +-#define UIP_REXMIT 4 /* Tells the application to retransmit the +- data that was last sent. */ +-#define UIP_POLL 8 /* Used for polling the application, to +- check if the application has data that +- it wants to send. */ +-#define UIP_CLOSE 16 /* The remote host has closed the +- connection, thus the connection has +- gone away. Or the application signals +- that it wants to close the +- connection. */ +-#define UIP_ABORT 32 /* The remote host has aborted the +- connection, thus the connection has +- gone away. Or the application signals +- that it wants to abort the +- connection. */ +-#define UIP_CONNECTED 64 /* We have got a connection from a remote +- host and have set up a new connection +- for it, or an active connection has +- been successfully established. */ +- +-#define UIP_TIMEDOUT 128 /* The connection has been aborted due to +- too many retransmissions. */ +- +-void uip_input(struct uip_stack *ustack); +-void uip_periodic(struct uip_stack *ustack, int conn); +- +-/* uip_process(flag): +- * +- * The actual uIP function which does all the work. +- */ +-void uip_process(struct uip_stack *ustack, u8_t flag); +- +-/* The following flags are passed as an argument to the uip_process() +- function. They are used to distinguish between the two cases where +- uip_process() is called. It can be called either because we have +- incoming data that should be processed, or because the periodic +- timer has fired. These values are never used directly, but only in +- the macrose defined in this file. */ +- +-#define UIP_DATA 1 /* Tells uIP that there is incoming +- data in the uip_buf buffer. The +- length of the data is stored in the +- global variable uip_len. */ +-#define UIP_TIMER 2 /* Tells uIP that the periodic timer +- has fired. */ +-#define UIP_POLL_REQUEST 3 /* Tells uIP that a connection should +- be polled. */ +-#define UIP_UDP_SEND_CONN 4 /* Tells uIP that a UDP datagram +- should be constructed in the +- uip_buf buffer. */ +-#if UIP_UDP +-#define UIP_UDP_TIMER 5 +-#endif /* UIP_UDP */ +- +-#define UIP_NDP_TIMER 6 +- +-/* The TCP states used in the uip_conn->tcpstateflags. */ +-#define UIP_CLOSED 0 +-#define UIP_SYN_RCVD 1 +-#define UIP_SYN_SENT 2 +-#define UIP_ESTABLISHED 3 +-#define UIP_FIN_WAIT_1 4 +-#define UIP_FIN_WAIT_2 5 +-#define UIP_CLOSING 6 +-#define UIP_TIME_WAIT 7 +-#define UIP_LAST_ACK 8 +-#define UIP_TS_MASK 15 +- +-#define UIP_STOPPED 16 +- +-struct __attribute__ ((__packed__)) uip_tcp_hdr { +- /* TCP header. */ +- u16_t srcport, destport; +- u8_t seqno[4], ackno[4], tcpoffset, flags, wnd[2]; +- u16_t tcpchksum; +- u8_t urgp[2]; +- u8_t optdata[4]; +-}; +- +-struct __attribute__ ((__packed__)) uip_ipv4_hdr { +- /* IPv4 header. */ +- u8_t vhl, tos, len[2], ipid[2], ipoffset[2], ttl, proto; +- u16_t ipchksum; +- u16_t srcipaddr[2], destipaddr[2]; +-}; +- +-struct __attribute__ ((__packed__)) uip_ipv6_hdr { +- /* IPv6 header. */ +- u8_t vtc, tcflow; +- u16_t flow; +- u16_t len; +- u8_t proto, ttl; +- uip_ip6addr_t srcipaddr, destipaddr; +-}; +- +-/* The TCP and IPv4 headers. */ +-struct __attribute__ ((__packed__)) uip_tcp_ipv4_hdr { +- /* IPv4 header. */ +- u8_t vhl, tos, len[2], ipid[2], ipoffset[2], ttl, proto; +- u16_t ipchksum; +- u16_t srcipaddr[2], destipaddr[2]; +- +- /* TCP header. */ +- u16_t srcport, destport; +- u8_t seqno[4], ackno[4], tcpoffset, flags, wnd[2]; +- u16_t tcpchksum; +- u8_t urgp[2]; +- u8_t optdata[4]; +-}; +- +-/* The TCP and IP headers. */ +-struct __attribute__ ((__packed__)) uip_tcp_ipv6_hdr { +- /* IPv6 header. */ +- u8_t vtc, tcflow; +- u16_t flow; +- u8_t len[2]; +- u8_t proto, ttl; +- uip_ip6addr_t srcipaddr, destipaddr; +- +- /* TCP header. */ +- u16_t srcport, destport; +- u8_t seqno[4], ackno[4], tcpoffset, flags, wnd[2]; +- u16_t tcpchksum; +- u8_t urgp[2]; +- u8_t optdata[4]; +-}; +- +-/* The ICMPv4 */ +-struct __attribute__ ((__packed__)) uip_icmpv4_hdr { +- /* ICMP (echo) header. */ +- u8_t type, icode; +- u16_t icmpchksum; +- u16_t id, seqno; +-}; +- +-typedef struct uip_icmpv4_hdr uip_icmp_echo_hdr_t; +- +-/* The ICMPv6 */ +-struct __attribute__ ((__packed__)) uip_icmpv6_hdr { +- /* ICMP (echo) header. */ +- u8_t type, icode; +- u16_t icmpchksum; +- u8_t flags, reserved1, reserved2, reserved3; +- u8_t icmp6data[16]; +- u8_t options[1]; +-}; +- +-/* The ICMP and IP headers. */ +-struct __attribute__ ((__packed__)) uip_icmpip_hdr { +-#if UIP_CONF_IPV6 +- /* IPv6 header. */ +- u8_t vtc, tcf; +- u16_t flow; +- u8_t len[2]; +- u8_t proto, ttl; +- uip_ip6addr_t srcipaddr, destipaddr; +-#else /* UIP_CONF_IPV6 */ +- /* IPv4 header. */ +- u8_t vhl, tos, len[2], ipid[2], ipoffset[2], ttl, proto; +- u16_t ipchksum; +- u16_t srcipaddr[2], destipaddr[2]; +-#endif /* UIP_CONF_IPV6 */ +- +- /* ICMP (echo) header. */ +- u8_t type, icode; +- u16_t icmpchksum; +-#if !UIP_CONF_IPV6 +- u16_t id, seqno; +-#else /* !UIP_CONF_IPV6 */ +- u8_t flags, reserved1, reserved2, reserved3; +- u8_t icmp6data[16]; +- u8_t options[1]; +-#endif /* !UIP_CONF_IPV6 */ +-}; +- +-/* The UDP */ +-struct __attribute__ ((__packed__)) uip_udp_hdr { +- /* UDP header. */ +- u16_t srcport, destport; +- u16_t udplen; +- u16_t udpchksum; +-}; +- +-/* The UDP and IP headers. */ +-struct __attribute__ ((__packed__)) uip_udpip_hdr { +-#if UIP_CONF_IPV6 +- /* IPv6 header. */ +- u8_t vtc, tcf; +- u16_t flow; +- u8_t len[2]; +- u8_t proto, ttl; +- uip_ip6addr_t srcipaddr, destipaddr; +-#else /* UIP_CONF_IPV6 */ +- /* IP header. */ +- u8_t vhl, tos, len[2], ipid[2], ipoffset[2], ttl, proto; +- u16_t ipchksum; +- u16_t srcipaddr[2], destipaddr[2]; +-#endif /* UIP_CONF_IPV6 */ +- +- /* UDP header. */ +- u16_t srcport, destport; +- u16_t udplen; +- u16_t udpchksum; +-}; +- +-/** +- * The buffer size available for user data in the \ref uip_buf buffer. +- * +- * This macro holds the available size for user data in the \ref +- * uip_buf buffer. The macro is intended to be used for checking +- * bounds of available user data. +- * +- * Example: +- \code +- snprintf(uip_appdata, UIP_APPDATA_SIZE, "%u\n", i); +- \endcode +- * +- * \hideinitializer +- */ +-#define UIP_APPDATA_SIZE (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN) +- +-#define UIP_PROTO_ICMP 1 +-#define UIP_PROTO_TCP 6 +-#define UIP_PROTO_UDP 17 +-#define UIP_PROTO_ICMP6 58 +- +-/* Header sizes. */ +-#define UIP_IPv6_H_LEN 40 /* Size of IPv6 header */ +-#define UIP_IPv4_H_LEN 20 /* Size of IPv4 header */ +- +-#define UIP_UDPH_LEN 8 /* Size of UDP header */ +-#define UIP_TCPH_LEN 20 /* Size of TCP header */ +- +-#define UIP_IPv4_UDPH_LEN (UIP_UDPH_LEN + UIP_IPv4_H_LEN) /* Size of IPv4 +- + UDP +- header */ +-#define UIP_IPv4_TCPH_LEN (UIP_TCPH_LEN + UIP_IPv4_H_LEN) /* Size of IPv4 +- + TCP +- header */ +-#define UIP_TCP_IPv4_HLEN UIP_IPv4_TCPH_LEN +- +-#define UIP_IPv6_UDPH_LEN (UIP_UDPH_LEN + UIP_IPv6_H_LEN) /* Size of IPv6 +- + UDP +- header */ +-#define UIP_IPv6_TCPH_LEN (UIP_TCPH_LEN + UIP_IPv6_H_LEN) /* Size of IPv6 +- + TCP +- header */ +-#define UIP_TCP_IPv6_HLEN UIP_IPv6_TCPH_LEN +- +-/** +- * Calculate the Internet checksum over a buffer. +- * +- * The Internet checksum is the one's complement of the one's +- * complement sum of all 16-bit words in the buffer. +- * +- * See RFC1071. +- * +- * \param buf A pointer to the buffer over which the checksum is to be +- * computed. +- * +- * \param len The length of the buffer over which the checksum is to +- * be computed. +- * +- * \return The Internet checksum of the buffer. +- */ +-u16_t uip_chksum(u16_t *buf, u16_t len); +- +-/** +- * Calculate the IP header checksum of the packet header in uip_buf. +- * +- * The IP header checksum is the Internet checksum of the 20 bytes of +- * the IP header. +- * +- * \return The IP header checksum of the IP header in the uip_buf +- * buffer. +- */ +-u16_t uip_ipchksum(struct uip_stack *ustack); +- +-/** +- * Calculate the TCP checksum of the packet in uip_buf and uip_appdata. +- * +- * The TCP checksum is the Internet checksum of data contents of the +- * TCP segment, and a pseudo-header as defined in RFC793. +- * +- * \return The TCP checksum of the TCP segment in uip_buf and pointed +- * to by uip_appdata. +- */ +-u16_t uip_tcpchksum(struct uip_stack *ustack); +- +-/** +- * Calculate the UDP checksum of the packet in uip_buf and uip_appdata. +- * +- * The UDP checksum is the Internet checksum of data contents of the +- * UDP segment, and a pseudo-header as defined in RFC768. +- * +- * \return The UDP checksum of the UDP segment in uip_buf and pointed +- * to by uip_appdata. +- */ +-u16_t uip_udpchksum(struct uip_stack *ustack); +- +-/* IPv6 checksum */ +-uint16_t icmpv6_checksum(uint8_t *data); +- +-struct neighbor_entry { +- struct in6_addr ipaddr; +- struct uip_eth_addr mac_addr; +- u8_t time; +-}; +- +-struct uip_stack { +- struct uip_eth_addr uip_ethaddr; +- +- u8_t *uip_buf; +- +- uint8_t *data_link_layer; /* Pointer to the data link layer */ +- uint8_t *network_layer; /* Pointer to the network layer */ +- void *uip_appdata; /* The uip_appdata pointer points to +- application data. */ +- void *uip_sappdata; /* The uip_appdata pointer points to +- the application data which is to +- be sent. */ +-#if UIP_URGDATA > 0 +- void *uip_urgdata; /* The uip_urgdata pointer points to +- urgent data (out-of-band data), if +- present. */ +- u16_t uip_urglen, uip_surglen; +-#endif /* UIP_URGDATA > 0 */ +- +- u16_t uip_len, uip_slen; /* The uip_len is either 8 or 16 bits, +- depending on the maximum packet +- size. */ +- u8_t uip_flags; /* The uip_flags variable is used for +- communication between the TCP/IP stack +- and the application program. */ +- struct uip_conn *uip_conn; /* uip_conn always points to the current +- connection. */ +- +- struct uip_conn uip_conns[UIP_CONNS]; +- /* The uip_conns array holds all TCP +- connections. */ +- u16_t uip_listenports[UIP_LISTENPORTS]; +- /* The uip_listenports list all currently +- listning ports. */ +-#if UIP_UDP +- struct uip_udp_conn *uip_udp_conn; +- struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS]; +-#endif /* UIP_UDP */ +- +- u16_t ipid; /* This ipid variable is an increasing +- number that is used for the IP ID +- field. */ +- +- u8_t iss[4]; /* The iss variable is used for the TCP +- initial sequence number. */ +- +-#if UIP_ACTIVE_OPEN +- u16_t lastport; /* Keeps track of the last port used for +- 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 +-#define IPV6_CONFIG_OFF 0x10 +-#define IPV6_CONFIG_STATIC 0x20 +-#define IPV6_CONFIG_DHCP 0x40 +- u8_t ip_config; +- +- uip_ip4addr_t hostaddr, netmask, default_route_addr; +- 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]; +- +- struct uip_stats stats; +- +- u8_t opt; +- +- pthread_mutex_t lock; +- +- /* IPv6 support */ +-#define UIP_SUPPORT_IPv6_ENABLED 0x01 +-#define UIP_SUPPORT_IPv6_DISABLED 0x02 +- u8_t enable_IPv6; +- +- /* DHCPC client attached */ +- void *dhcpc; +- +- /* NDP client */ +- void *ndpc; +- +- void *ping_conf; +-}; +- +-/******************************************************************************* +- * IPv6 Support +- ******************************************************************************/ +-int set_ipv6_link_local_address(struct uip_stack *ustack); +-int is_ipv6_link_local_address(uip_ip6addr_t *addr); +- +-void dump_uip_packet(struct uip_stack *ustack); +-u16_t uip_icmp6chksum(struct uip_stack *ustack); +- +-#endif /* __UIP_H__ */ +- +-/** @} */ +diff --git a/iscsiuio/src/uip/uip_arch.h b/iscsiuio/src/uip/uip_arch.h +deleted file mode 100644 +index 3ddacec..0000000 +--- a/iscsiuio/src/uip/uip_arch.h ++++ /dev/null +@@ -1,137 +0,0 @@ +-/** +- * \addtogroup uip +- * {@ +- */ +- +-/** +- * \defgroup uiparch Architecture specific uIP functions +- * @{ +- * +- * The functions in the architecture specific module implement the IP +- * check sum and 32-bit additions. +- * +- * The IP checksum calculation is the most computationally expensive +- * operation in the TCP/IP stack and it therefore pays off to +- * implement this in efficient assembler. The purpose of the uip-arch +- * module is to let the checksum functions to be implemented in +- * architecture specific assembler. +- * +- */ +- +-/** +- * \file +- * Declarations of architecture specific functions. +- * \author Adam Dunkels +- */ +- +-/* +- * Copyright (c) 2001, Adam Dunkels. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * This file is part of the uIP TCP/IP stack. +- * +- * +- */ +- +-#ifndef __UIP_ARCH_H__ +-#define __UIP_ARCH_H__ +- +-#include "uip.h" +- +-/** +- * Carry out a 32-bit addition. +- * +- * Because not all architectures for which uIP is intended has native +- * 32-bit arithmetic, uIP uses an external C function for doing the +- * required 32-bit additions in the TCP protocol processing. This +- * function should add the two arguments and place the result in the +- * global variable uip_acc32. +- * +- * \note The 32-bit integer pointed to by the op32 parameter and the +- * result in the uip_acc32 variable are in network byte order (big +- * endian). +- * +- * \param op32 A pointer to a 4-byte array representing a 32-bit +- * integer in network byte order (big endian). +- * +- * \param op16 A 16-bit integer in host byte order. +- */ +-void uip_add32(u8_t *op32, u16_t op16, u8_t *uip_add32); +- +-/** +- * Calculate the Internet checksum over a buffer. +- * +- * The Internet checksum is the one's complement of the one's +- * complement sum of all 16-bit words in the buffer. +- * +- * See RFC1071. +- * +- * \note This function is not called in the current version of uIP, +- * but future versions might make use of it. +- * +- * \param buf A pointer to the buffer over which the checksum is to be +- * computed. +- * +- * \param len The length of the buffer over which the checksum is to +- * be computed. +- * +- * \return The Internet checksum of the buffer. +- */ +-u16_t uip_chksum(u16_t *buf, u16_t len); +- +-/** +- * Calculate the IP header checksum of the packet header in uip_buf. +- * +- * The IP header checksum is the Internet checksum of the 20 bytes of +- * the IP header. +- * +- * \return The IP header checksum of the IP header in the uip_buf +- * buffer. +- */ +-u16_t uip_ipchksum(struct uip_stack *ustack); +- +-/** +- * Calculate the TCP checksum of the packet in uip_buf and uip_appdata. +- * +- * The TCP checksum is the Internet checksum of data contents of the +- * TCP segment, and a pseudo-header as defined in RFC793. +- * +- * \note The uip_appdata pointer that points to the packet data may +- * point anywhere in memory, so it is not possible to simply calculate +- * the Internet checksum of the contents of the uip_buf buffer. +- * +- * \return The TCP checksum of the TCP segment in uip_buf and pointed +- * to by uip_appdata. +- */ +-u16_t uip_tcpchksum(struct uip_stack *ustack); +- +-u16_t uip_udpchksum(struct uip_stack *ustack); +- +-/** @} */ +-/** @} */ +- +-#endif /* __UIP_ARCH_H__ */ +diff --git a/iscsiuio/src/uip/uip_arp.c b/iscsiuio/src/uip/uip_arp.c +deleted file mode 100644 +index 1b3761f..0000000 +--- a/iscsiuio/src/uip/uip_arp.c ++++ /dev/null +@@ -1,479 +0,0 @@ +-#include +-#include +-#include +- +-#include "logger.h" +-#include "packet.h" +- +-/** +- * \addtogroup uip +- * @{ +- */ +- +-/** +- * \defgroup uiparp uIP Address Resolution Protocol +- * @{ +- * +- * The Address Resolution Protocol ARP is used for mapping between IP +- * addresses and link level addresses such as the Ethernet MAC +- * addresses. ARP uses broadcast queries to ask for the link level +- * address of a known IP address and the host which is configured with +- * the IP address for which the query was meant, will respond with its +- * link level address. +- * +- * \note This ARP implementation only supports Ethernet. +- */ +- +-/** +- * \file +- * Implementation of the ARP Address Resolution Protocol. +- * \author Adam Dunkels +- * +- */ +- +-/* +- * Copyright (c) 2001-2003, Adam Dunkels. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * This file is part of the uIP TCP/IP stack. +- * +- * +- */ +- +-#include "uip_arp.h" +-#include "uip_eth.h" +- +-#include +-#include +- +-static const struct uip_eth_addr broadcast_ethaddr = { +- {0xff, 0xff, 0xff, 0xff, 0xff, 0xff} }; +-static const u16_t broadcast_ipaddr[2] = { 0xffff, 0xffff }; +- +-pthread_mutex_t arp_table_mutex = PTHREAD_MUTEX_INITIALIZER; +-static struct arp_entry arp_table[UIP_ARPTAB_SIZE]; +- +-static u8_t arptime; +- +-/** +- * Initialize the ARP module. +- * +- */ +-/*----------------------------------------------------------------------------*/ +-void uip_arp_init(void) +-{ +- u8_t i; +- for (i = 0; i < UIP_ARPTAB_SIZE; ++i) +- memset(&arp_table[i], 0, sizeof(arp_table[i])); +- +- pthread_mutex_init(&arp_table_mutex, NULL); +-} +- +-/*----------------------------------------------------------------------------*/ +-/** +- * Periodic ARP processing function. +- * +- * This function performs periodic timer processing in the ARP module +- * and should be called at regular intervals. The recommended interval +- * is 10 seconds between the calls. +- * +- */ +-/*----------------------------------------------------------------------------*/ +-void uip_arp_timer(void) +-{ +- u8_t i; +- struct arp_entry *tabptr; +- +- ++arptime; +- for (i = 0; i < UIP_ARPTAB_SIZE; ++i) { +- tabptr = &arp_table[i]; +- if ((tabptr->ipaddr[0] | tabptr->ipaddr[1]) != 0 && +- (u8_t)(arptime - tabptr->time) >= UIP_ARP_MAXAGE) +- memset(tabptr->ipaddr, 0, 4); +- } +- +-} +- +-/*----------------------------------------------------------------------------*/ +-static void uip_arp_update(u16_t *ipaddr, struct uip_eth_addr *ethaddr) +-{ +- u8_t i; +- struct arp_entry *tabptr; +- +- pthread_mutex_lock(&arp_table_mutex); +- /* Walk through the ARP mapping table and try to find an entry to +- update. If none is found, the IP -> MAC address mapping is +- inserted in the ARP table. */ +- for (i = 0; i < UIP_ARPTAB_SIZE; ++i) { +- +- tabptr = &arp_table[i]; +- /* Only check those entries that are actually in use. */ +- if (tabptr->ipaddr[0] != 0 && tabptr->ipaddr[1] != 0) { +- +- /* Check if the source IP address of the incoming packet +- matches the IP address in this ARP table entry. */ +- if (ipaddr[0] == tabptr->ipaddr[0] && +- ipaddr[1] == tabptr->ipaddr[1]) { +- +- tabptr->time = arptime; +- +- pthread_mutex_unlock(&arp_table_mutex); +- return; +- } +- } +- } +- +- /* If we get here, no existing ARP table entry was found, so we +- create one. */ +- +- /* First, we try to find an unused entry in the ARP table. */ +- for (i = 0; i < UIP_ARPTAB_SIZE; ++i) { +- tabptr = &arp_table[i]; +- if (tabptr->ipaddr[0] == 0 && tabptr->ipaddr[1] == 0) +- break; +- } +- +- /* If no unused entry is found, we try to find the oldest entry and +- throw it away. */ +- if (i == UIP_ARPTAB_SIZE) { +- u8_t c; +- u8_t tmpage = 0; +- c = 0; +- for (i = 0; i < UIP_ARPTAB_SIZE; ++i) { +- tabptr = &arp_table[i]; +- if ((u8_t)(arptime - tabptr->time) > tmpage) { +- tmpage = (u8_t)(arptime - tabptr->time); +- c = i; +- } +- } +- i = c; +- tabptr = &arp_table[i]; +- } +- +- /* Now, i is the ARP table entry which we will fill with the new +- information. */ +- memcpy(tabptr->ipaddr, ipaddr, 4); +- memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6); +- tabptr->time = arptime; +- +- pthread_mutex_unlock(&arp_table_mutex); +-} +- +-/** +- * ARP processing for incoming ARP packets. +- * +- * This function should be called by the device driver when an ARP +- * packet has been received. The function will act differently +- * depending on the ARP packet type: if it is a reply for a request +- * that we previously sent out, the ARP cache will be filled in with +- * the values from the ARP reply. If the incoming ARP packet is an ARP +- * request for our IP address, an ARP reply packet is created and put +- * into the uip_buf[] buffer. +- * +- * When the function returns, the value of the global variable uip_len +- * indicates whether the device driver should send out a packet or +- * not. If uip_len is zero, no packet should be sent. If uip_len is +- * non-zero, it contains the length of the outbound packet that is +- * present in the uip_buf[] buffer. +- * +- * This function expects an ARP packet with a prepended Ethernet +- * header in the uip_buf[] buffer, and the length of the packet in the +- * global variable uip_len. +- */ +-void uip_arp_ipin(struct uip_stack *ustack, packet_t *pkt) +-{ +- struct ip_hdr *ip; +- struct uip_eth_hdr *eth; +- +- eth = (struct uip_eth_hdr *)pkt->data_link_layer; +- ip = (struct ip_hdr *)pkt->network_layer; +- +- if (uip_ip4addr_cmp(ip->destipaddr, ustack->hostaddr)) { +- /* First, we register the one who made the request in our ARP +- table, since it is likely that we will do more communication +- with this host in the future. */ +- uip_arp_update(ip->srcipaddr, ð->src); +- } +-} +- +-void +-uip_arp_arpin(nic_interface_t *nic_iface, +- struct uip_stack *ustack, packet_t *pkt) +-{ +- struct arp_hdr *arp; +- struct uip_eth_hdr *eth; +- +- if (pkt->buf_size < sizeof(struct arp_hdr)) { +- pkt->buf_size = 0; +- return; +- } +- pkt->buf_size = 0; +- +- eth = (struct uip_eth_hdr *)pkt->data_link_layer; +- arp = (struct arp_hdr *)pkt->network_layer; +- +- switch (arp->opcode) { +- case const_htons(ARP_REQUEST): +- /* ARP request. If it asked for our address, we send out a +- reply. */ +- if (uip_ip4addr_cmp(arp->dipaddr, ustack->hostaddr)) { +- /* First, we register the one who made the request in +- our ARP table, since it is likely that we will do +- more communication with this host in the future. */ +- uip_arp_update(arp->sipaddr, &arp->shwaddr); +- +- /* The reply opcode is 2. */ +- arp->opcode = htons(2); +- +- memcpy(arp->dhwaddr.addr, arp->shwaddr.addr, 6); +- memcpy(arp->shwaddr.addr, ustack->uip_ethaddr.addr, 6); +- memcpy(eth->src.addr, ustack->uip_ethaddr.addr, 6); +- memcpy(eth->dest.addr, arp->dhwaddr.addr, 6); +- +- arp->dipaddr[0] = arp->sipaddr[0]; +- arp->dipaddr[1] = arp->sipaddr[1]; +- arp->sipaddr[0] = ustack->hostaddr[0]; +- arp->sipaddr[1] = ustack->hostaddr[1]; +- +- if (nic_iface->vlan_id == 0) { +- eth->type = htons(UIP_ETHTYPE_ARP); +- 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); +- } +- } +- break; +- case const_htons(ARP_REPLY): +- uip_arp_update(arp->sipaddr, &arp->shwaddr); +- break; +- default: +- LOG_WARN("Unknown ARP opcode: %d", ntohs(arp->opcode)); +- break; +- } +- +- return; +-} +- +-/** +- * Prepend Ethernet header to an outbound IP packet and see if we need +- * to send out an ARP request. +- * +- * This function should be called before sending out an IP packet. The +- * function checks the destination IP address of the IP packet to see +- * what Ethernet MAC address that should be used as a destination MAC +- * address on the Ethernet. +- * +- * If the destination IP address is in the local network (determined +- * by logical ANDing of netmask and our IP address), the function +- * checks the ARP cache to see if an entry for the destination IP +- * address is found. If so, an Ethernet header is prepended and the +- * function returns. If no ARP cache entry is found for the +- * destination IP address, the packet in the uip_buf[] is replaced by +- * an ARP request packet for the IP address. The IP packet is dropped +- * and it is assumed that they higher level protocols (e.g., TCP) +- * eventually will retransmit the dropped packet. +- * +- * If the destination IP address is not on the local network, the IP +- * address of the default router is used instead. +- * +- * When the function returns, a packet is present in the uip_buf[] +- * buffer, and the length of the packet is in the global variable +- * uip_len. +- */ +- +-dest_ipv4_addr_t +-uip_determine_dest_ipv4_addr(struct uip_stack *ustack, u16_t *ipaddr) +-{ +- struct uip_eth_hdr *eth; +- struct ip_hdr *ip_buf; +- +- eth = (struct uip_eth_hdr *)ustack->data_link_layer; +- ip_buf = (struct ip_hdr *)ustack->network_layer; +- +- /* Find the destination IP address in the ARP table and construct +- the Ethernet header. If the destination IP addres isn't on the +- local network, we use the default router's IP address instead. +- +- If not ARP table entry is found, we overwrite the original IP +- packet with an ARP request for the IP address. */ +- +- /* First check if destination is a local broadcast. */ +- if (uip_ip4addr_cmp(ip_buf->destipaddr, broadcast_ipaddr)) { +- memcpy(ð->dest, broadcast_ethaddr.addr, 6); +- +- return LOCAL_BROADCAST; +- } else { +- /* Check if the destination address is on the local network. */ +- if (!uip_ip4addr_maskcmp(ip_buf->destipaddr, +- ustack->hostaddr, ustack->netmask)) { +- /* Destination address was not on the local network, +- so we need to use the default router's IP address +- instead of the destination address when determining +- the MAC address. */ +- uip_ip4addr_copy(ipaddr, ustack->default_route_addr); +- } else { +- /* Else, we use the destination IP address. */ +- uip_ip4addr_copy(ipaddr, ip_buf->destipaddr); +- } +- +- return NONLOCAL_BROADCAST; +- } +-} +- +-arp_out_t is_in_arp_table(u16_t *ipaddr, struct arp_entry **tabptr) +-{ +- u8_t i; +- +- pthread_mutex_lock(&arp_table_mutex); +- +- for (i = 0; i < UIP_ARPTAB_SIZE; ++i) { +- if (uip_ip4addr_cmp(ipaddr, arp_table[i].ipaddr)) { +- *tabptr = &arp_table[i]; +- break; +- } +- } +- +- pthread_mutex_unlock(&arp_table_mutex); +- +- if (i == UIP_ARPTAB_SIZE) +- return NOT_IN_ARP_TABLE; +- else +- return IS_IN_ARP_TABLE; +-} +- +-void uip_build_arp_request(struct uip_stack *ustack, u16_t *ipaddr) +-{ +- struct arp_hdr *arp; +- struct uip_eth_hdr *eth; +- +- arp = (struct arp_hdr *)ustack->network_layer; +- eth = (struct uip_eth_hdr *)ustack->data_link_layer; +- +- /* The destination address was not in our ARP table, so we +- overwrite the IP packet with an ARP request. */ +- +- memset(eth->dest.addr, 0xff, 6); +- memset(arp->dhwaddr.addr, 0x00, 6); +- memcpy(eth->src.addr, ustack->uip_ethaddr.addr, 6); +- memcpy(arp->shwaddr.addr, ustack->uip_ethaddr.addr, 6); +- +- uip_ip4addr_copy(arp->dipaddr, ipaddr); +- uip_ip4addr_copy(arp->sipaddr, ustack->hostaddr); +- arp->opcode = const_htons(ARP_REQUEST); /* ARP request. */ +- arp->hwtype = const_htons(ARP_HWTYPE_ETH); +- arp->protocol = const_htons(UIP_ETHTYPE_IPv4); +- arp->hwlen = 6; +- arp->protolen = 4; +- eth->type = const_htons(UIP_ETHTYPE_ARP); +- +- ustack->uip_appdata = &ustack->uip_buf[UIP_TCP_IPv4_HLEN + UIP_LLH_LEN]; +- +- ustack->uip_len = sizeof(*arp) + sizeof(*eth); +-} +- +-void +-uip_build_eth_header(struct uip_stack *ustack, +- u16_t *ipaddr, +- struct arp_entry *tabptr, +- struct packet *pkt, u16_t vlan_id) +-{ +- struct uip_ipv4_hdr *ip_buf; +- struct uip_eth_hdr *eth; +- struct uip_vlan_eth_hdr *eth_vlan; +- +- ip_buf = (struct uip_ipv4_hdr *)ustack->network_layer; +- eth = (struct uip_eth_hdr *)ustack->data_link_layer; +- eth_vlan = (struct uip_vlan_eth_hdr *)ustack->data_link_layer; +- +- /* First check if destination is a local broadcast. */ +- if (uip_ip4addr_cmp(ip_buf->destipaddr, broadcast_ipaddr)) { +- memcpy(eth->dest.addr, broadcast_ethaddr.addr, 6); +- } else { +- /* Build an ethernet header. */ +- memcpy(eth->dest.addr, tabptr->ethaddr.addr, 6); +- } +- memcpy(eth->src.addr, ustack->uip_ethaddr.addr, 6); +- +- if (vlan_id == 0) { +- eth->type = htons(UIP_ETHTYPE_IPv4); +- +- ustack->uip_len += sizeof(struct uip_eth_hdr); +- pkt->buf_size += sizeof(struct uip_eth_hdr); +- } else { +- eth_vlan->tpid = htons(UIP_ETHTYPE_8021Q); +- eth_vlan->vid = htons(vlan_id); +- eth_vlan->type = htons(UIP_ETHTYPE_IPv4); +- +- ustack->uip_len += sizeof(struct uip_vlan_eth_hdr); +- pkt->buf_size += sizeof(struct uip_vlan_eth_hdr); +- } +-} +- +-static struct arp_entry *uip_get_arp_entry(int index) +-{ +- return &arp_table[index]; +-} +- +-int uip_lookup_arp_entry(uint32_t ip_addr, uint8_t *mac_addr) +-{ +- int i; +- int rc = -EINVAL; +- +- pthread_mutex_lock(&arp_table_mutex); +- +- for (i = 0; i < UIP_ARPTAB_SIZE; ++i) { +- struct arp_entry *entry = uip_get_arp_entry(i); +- +- if (((entry->ipaddr[1] << 16) == (ip_addr & 0xffff0000)) && +- ((entry->ipaddr[0]) == (ip_addr & 0x0000ffff))) { +- struct in_addr addr; +- char *addr_str; +- +- addr.s_addr = ip_addr; +- addr_str = inet_ntoa(addr); +- +- memcpy(mac_addr, entry->ethaddr.addr, 6); +- +- LOG_INFO("Found %s at %02x:%02x:%02x:%02x:%02x:%02x", +- addr_str, +- mac_addr[0], mac_addr[1], mac_addr[2], +- mac_addr[3], mac_addr[4], mac_addr[5]); +- rc = 0; +- break; +- } +- } +- +- pthread_mutex_unlock(&arp_table_mutex); +- return rc; +-} +- +-/*----------------------------------------------------------------------------*/ +- +-/** @} */ +-/** @} */ +diff --git a/iscsiuio/src/uip/uip_arp.h b/iscsiuio/src/uip/uip_arp.h +deleted file mode 100644 +index 339d57d..0000000 +--- a/iscsiuio/src/uip/uip_arp.h ++++ /dev/null +@@ -1,197 +0,0 @@ +-/** +- * \addtogroup uip +- * @{ +- */ +- +-/** +- * \addtogroup uiparp +- * @{ +- */ +- +-/** +- * \file +- * Macros and definitions for the ARP module. +- * \author Adam Dunkels +- */ +- +-/* +- * Copyright (c) 2001-2003, Adam Dunkels. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * This file is part of the uIP TCP/IP stack. +- * +- * +- */ +- +-#ifndef __UIP_ARP_H__ +-#define __UIP_ARP_H__ +- +-#include "packet.h" +-#include "uip.h" +-#include "uip_eth.h" +- +-#define ARP_REQUEST 1 +-#define ARP_REPLY 2 +- +-#define ARP_HWTYPE_ETH 1 +- +-struct __attribute__ ((__packed__)) arp_hdr { +- u16_t hwtype; +- u16_t protocol; +- u8_t hwlen; +- u8_t protolen; +- u16_t opcode; +- struct uip_eth_addr shwaddr; +- u16_t sipaddr[2]; +- struct uip_eth_addr dhwaddr; +- u16_t dipaddr[2]; +-}; +- +-struct __attribute__ ((__packed__)) ip_hdr { +- /* IP header. */ +- u8_t vhl, tos, len[2], ipid[2], ipoffset[2], ttl, proto; +- u16_t ipchksum; +- u16_t srcipaddr[2], destipaddr[2]; +-}; +- +-struct __attribute__ ((__packed__)) ethip_hdr { +- struct uip_eth_hdr ethhdr; +- /* IP header. */ +- u8_t vhl, tos, len[2], ipid[2], ipoffset[2], ttl, proto; +- u16_t ipchksum; +- u16_t srcipaddr[2], destipaddr[2]; +-}; +- +-struct arp_entry { +- u16_t ipaddr[2]; +- struct uip_eth_addr ethaddr; +- u8_t time; +-}; +- +-/* The uip_arp_init() function must be called before any of the other +- ARP functions. */ +-void uip_arp_init(void); +- +-/* The uip_arp_ipin() function should be called whenever an IP packet +- arrives from the Ethernet. This function refreshes the ARP table or +- inserts a new mapping if none exists. The function assumes that an +- IP packet with an Ethernet header is present in the uip_buf buffer +- and that the length of the packet is in the uip_len variable. */ +-/*void uip_arp_ipin(void);*/ +-/* #define uip_arp_ipin() */ +-void uip_arp_ipin(struct uip_stack *ustack, struct packet *pkt); +- +-/* The uip_arp_arpin() should be called when an ARP packet is received +- by the Ethernet driver. This function also assumes that the +- Ethernet frame is present in the uip_buf buffer. When the +- uip_arp_arpin() function returns, the contents of the uip_buf +- buffer should be sent out on the Ethernet if the uip_len variable +- is > 0. */ +-void uip_arp_arpin(nic_interface_t *nic_iface, +- struct uip_stack *ustack, struct packet *pkt); +- +-typedef enum { +- ARP_SENT = 1, +- ETH_HEADER_APPEDEND = 2, +-} arp_out_t; +- +-typedef enum { +- LOCAL_BROADCAST = 1, +- NONLOCAL_BROADCAST = 2, +-} dest_ipv4_addr_t; +- +-typedef enum { +- IS_IN_ARP_TABLE = 1, +- NOT_IN_ARP_TABLE = 2, +-} arp_table_query_t; +- +-dest_ipv4_addr_t +-uip_determine_dest_ipv4_addr(struct uip_stack *ustack, u16_t *ipaddr); +-arp_out_t is_in_arp_table(u16_t *ipaddr, struct arp_entry **tabptr); +- +-void uip_build_arp_request(struct uip_stack *ustack, u16_t *ipaddr); +- +-void +-uip_build_eth_header(struct uip_stack *ustack, +- u16_t *ipaddr, +- struct arp_entry *tabptr, +- struct packet *pkt, u16_t vlan_id); +- +-/* The uip_arp_out() function should be called when an IP packet +- should be sent out on the Ethernet. This function creates an +- Ethernet header before the IP header in the uip_buf buffer. The +- Ethernet header will have the correct Ethernet MAC destination +- address filled in if an ARP table entry for the destination IP +- address (or the IP address of the default router) is present. If no +- such table entry is found, the IP packet is overwritten with an ARP +- request and we rely on TCP to retransmit the packet that was +- overwritten. In any case, the uip_len variable holds the length of +- the Ethernet frame that should be transmitted. */ +-arp_out_t uip_arp_out(struct uip_stack *ustack); +- +-/* The uip_arp_timer() function should be called every ten seconds. It +- is responsible for flushing old entries in the ARP table. */ +-void uip_arp_timer(void); +- +-int uip_lookup_arp_entry(uint32_t ip_addr, uint8_t *mac_addr); +- +-/** @} */ +- +-/** +- * \addtogroup uipconffunc +- * @{ +- */ +- +-/** +- * Specifiy the Ethernet MAC address. +- * +- * The ARP code needs to know the MAC address of the Ethernet card in +- * order to be able to respond to ARP queries and to generate working +- * Ethernet headers. +- * +- * \note This macro only specifies the Ethernet MAC address to the ARP +- * code. It cannot be used to change the MAC address of the Ethernet +- * card. +- * +- * \param eaddr A pointer to a struct uip_eth_addr containing the +- * Ethernet MAC address of the Ethernet card. +- * +- * \hideinitializer +- */ +-#define uip_setethaddr(eaddr) do { \ +- uip_ethaddr.addr[0] = eaddr.addr[0]; \ +- uip_ethaddr.addr[1] = eaddr.addr[1]; \ +- uip_ethaddr.addr[2] = eaddr.addr[2]; \ +- uip_ethaddr.addr[3] = eaddr.addr[3]; \ +- uip_ethaddr.addr[4] = eaddr.addr[4]; \ +- uip_ethaddr.addr[5] = eaddr.addr[5]; \ +- } while (0) +- +-/** @} */ +-/** @} */ +- +-#endif /* __UIP_ARP_H__ */ +diff --git a/iscsiuio/src/uip/uip_eth.c b/iscsiuio/src/uip/uip_eth.c +deleted file mode 100644 +index 9e1ea81..0000000 +--- a/iscsiuio/src/uip/uip_eth.c ++++ /dev/null +@@ -1,50 +0,0 @@ +-/* +- * Copyright (c) 2009-2011, Broadcom Corporation +- * Copyright (c) 2014, QLogic Corporation +- * +- * Written by: Benjamin Li (benli@broadcom.com) +- * +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. All advertising materials mentioning features or use of this software +- * must display the following acknowledgement: +- * This product includes software developed by Adam Dunkels. +- * 4. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * uip_eth.c - CNIC UIO uIP user space stack +- * +- */ +- +-#include "uip.h" +-#include "uip_eth.h" +- +-int is_vlan_packet(struct uip_vlan_eth_hdr *hdr) +-{ +- /* The TPID field in a 802.1Q Header must be 0x8100 */ +- if (hdr->tpid == const_htons(UIP_ETHTYPE_8021Q)) +- return 1; +- +- return 0; +-} +diff --git a/iscsiuio/src/uip/uip_eth.h b/iscsiuio/src/uip/uip_eth.h +deleted file mode 100644 +index 830c04c..0000000 +--- a/iscsiuio/src/uip/uip_eth.h ++++ /dev/null +@@ -1,43 +0,0 @@ +-#ifndef __UIP_ETH_H__ +-#define __UIP_ETH_H__ +- +-#include "uipopt.h" +- +-/******************************************************************************* +- * Ether types +- ******************************************************************************/ +-#define UIP_ETHTYPE_ARP 0x0806 +-#define UIP_ETHTYPE_IPv4 0x0800 +-#define UIP_ETHTYPE_8021Q 0x8100 +-#define UIP_ETHTYPE_IPv6 0x86dd +- +-/** +- * Representation of a 48-bit Ethernet address. +- */ +-struct uip_eth_addr { +- u8_t addr[6]; +-}; +- +-/** +- * The Ethernet header. +- */ +-struct __attribute__ ((__packed__)) uip_eth_hdr { +- struct uip_eth_addr dest; +- struct uip_eth_addr src; +- u16_t type; +-}; +- +-/** +- * The 802.1Q Ethernet header (VLAN). +- */ +-struct __attribute__ ((__packed__)) uip_vlan_eth_hdr { +- struct uip_eth_addr dest; +- struct uip_eth_addr src; +- u16_t tpid; +- u16_t vid; +- u16_t type; +-}; +- +-int is_vlan_packet(struct uip_vlan_eth_hdr *hdr); +- +-#endif /* __UIP_ETH_H__ */ +diff --git a/iscsiuio/src/uip/uipopt.h b/iscsiuio/src/uip/uipopt.h +deleted file mode 100644 +index bcc8949..0000000 +--- a/iscsiuio/src/uip/uipopt.h ++++ /dev/null +@@ -1,536 +0,0 @@ +-/** +- * \defgroup uipopt Configuration options for uIP +- * @{ +- * +- * uIP is configured using the per-project configuration file +- * uipopt.h. This file contains all compile-time options for uIP and +- * should be tweaked to match each specific project. The uIP +- * distribution contains a documented example "uipopt.h" that can be +- * copied and modified for each project. +- * +- * \note Most of the configuration options in the uipopt.h should not +- * be changed, but rather the per-project uip-conf.h file. +- */ +- +-/** +- * \file +- * Configuration options for uIP. +- * \author Adam Dunkels +- * +- * This file is used for tweaking various configuration options for +- * uIP. You should make a copy of this file into one of your project's +- * directories instead of editing this example "uipopt.h" file that +- * comes with the uIP distribution. +- */ +- +-/* +- * Copyright (c) 2001-2003, Adam Dunkels. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * This file is part of the uIP TCP/IP stack. +- * +- * +- */ +- +-#ifndef __UIPOPT_H__ +-#define __UIPOPT_H__ +- +-#ifndef UIP_LITTLE_ENDIAN +-#define UIP_LITTLE_ENDIAN 3412 +-#endif /* UIP_LITTLE_ENDIAN */ +-#ifndef UIP_BIG_ENDIAN +-#define UIP_BIG_ENDIAN 1234 +-#endif /* UIP_BIG_ENDIAN */ +- +-#include "uip-conf.h" +- +-/*----------------------------------------------------------------------------*/ +- +-/** +- * \name Static configuration options +- * @{ +- * +- * These configuration options can be used for setting the IP address +- * settings statically, but only if UIP_FIXEDADDR is set to 1. The +- * configuration options for a specific node includes IP address, +- * netmask and default router as well as the Ethernet address. The +- * netmask, default router and Ethernet address are appliciable only +- * if uIP should be run over Ethernet. +- * +- * All of these should be changed to suit your project. +-*/ +- +-/** +- * Determines if uIP should use a fixed IP address or not. +- * +- * If uIP should use a fixed IP address, the settings are set in the +- * uipopt.h file. If not, the macros uip_sethostaddr(), +- * uip_setdraddr() and uip_setnetmask() should be used instead. +- * +- * \hideinitializer +- */ +-#define UIP_FIXEDADDR 0 +- +-/** +- * Ping IP address asignment. +- * +- * uIP uses a "ping" packets for setting its own IP address if this +- * option is set. If so, uIP will start with an empty IP address and +- * the destination IP address of the first incoming "ping" (ICMP echo) +- * packet will be used for setting the hosts IP address. +- * +- * \note This works only if UIP_FIXEDADDR is 0. +- * +- * \hideinitializer +- */ +-#ifdef UIP_CONF_PINGADDRCONF +-#define UIP_PINGADDRCONF UIP_CONF_PINGADDRCONF +-#else /* UIP_CONF_PINGADDRCONF */ +-#define UIP_PINGADDRCONF 0 +-#endif /* UIP_CONF_PINGADDRCONF */ +- +-/** +- * Specifies if the uIP ARP module should be compiled with a fixed +- * Ethernet MAC address or not. +- * +- * If this configuration option is 0, the macro uip_setethaddr() can +- * be used to specify the Ethernet address at run-time. +- * +- * \hideinitializer +- */ +-#define UIP_FIXEDETHADDR 0 +- +-/** @} */ +-/*------------------------------------------------------------------------------*/ +-/** +- * \name IP configuration options +- * @{ +- * +- */ +-/** +- * The IP TTL (time to live) of IP packets sent by uIP. +- * +- * This should normally not be changed. +- */ +-#define UIP_TTL 64 +- +-/** +- * Turn on support for IP packet reassembly. +- * +- * uIP supports reassembly of fragmented IP packets. This features +- * requires an additonal amount of RAM to hold the reassembly buffer +- * and the reassembly code size is approximately 700 bytes. The +- * reassembly buffer is of the same size as the uip_buf buffer +- * (configured by UIP_BUFSIZE). +- * +- * \note IP packet reassembly is not heavily tested. +- * +- * \hideinitializer +- */ +-#define UIP_REASSEMBLY 0 +- +-/** +- * The maximum time an IP fragment should wait in the reassembly +- * buffer before it is dropped. +- * +- */ +-#define UIP_REASS_MAXAGE 40 +- +-/** @} */ +- +-/*----------------------------------------------------------------------------*/ +-/** +- * \name UDP configuration options +- * @{ +- */ +- +-/** +- * Toggles wether UDP support should be compiled in or not. +- * +- * \hideinitializer +- */ +-#ifdef UIP_CONF_UDP +-#define UIP_UDP UIP_CONF_UDP +-#else /* UIP_CONF_UDP */ +-#define UIP_UDP 0 +-#endif /* UIP_CONF_UDP */ +- +-/** +- * Toggles if UDP checksums should be used or not. +- * +- * \note Support for UDP checksums is currently not included in uIP, +- * so this option has no function. +- * +- * \hideinitializer +- */ +-#ifdef UIP_CONF_UDP_CHECKSUMS +-#define UIP_UDP_CHECKSUMS UIP_CONF_UDP_CHECKSUMS +-#else +-#define UIP_UDP_CHECKSUMS 0 +-#endif +- +-/** +- * The maximum amount of concurrent UDP connections. +- * +- * \hideinitializer +- */ +-#ifdef UIP_CONF_UDP_CONNS +-#define UIP_UDP_CONNS UIP_CONF_UDP_CONNS +-#else /* UIP_CONF_UDP_CONNS */ +-#define UIP_UDP_CONNS 10 +-#endif /* UIP_CONF_UDP_CONNS */ +- +-/** +- * The name of the function that should be called when UDP datagrams arrive. +- * +- * \hideinitializer +- */ +- +-/** @} */ +-/*------------------------------------------------------------------------------*/ +-/** +- * \name TCP configuration options +- * @{ +- */ +- +-/** +- * Determines if support for opening connections from uIP should be +- * compiled in. +- * +- * If the applications that are running on top of uIP for this project +- * do not need to open outgoing TCP connections, this configration +- * option can be turned off to reduce the code size of uIP. +- * +- * \hideinitializer +- */ +-#define UIP_ACTIVE_OPEN 1 +- +-/** +- * The maximum number of simultaneously open TCP connections. +- * +- * Since the TCP connections are statically allocated, turning this +- * configuration knob down results in less RAM used. Each TCP +- * connection requires approximatly 30 bytes of memory. +- * +- * \hideinitializer +- */ +-#ifndef UIP_CONF_MAX_CONNECTIONS +-#define UIP_CONNS 10 +-#else /* UIP_CONF_MAX_CONNECTIONS */ +-#define UIP_CONNS UIP_CONF_MAX_CONNECTIONS +-#endif /* UIP_CONF_MAX_CONNECTIONS */ +- +-/** +- * The maximum number of simultaneously listening TCP ports. +- * +- * Each listening TCP port requires 2 bytes of memory. +- * +- * \hideinitializer +- */ +-#ifndef UIP_CONF_MAX_LISTENPORTS +-#define UIP_LISTENPORTS 20 +-#else /* UIP_CONF_MAX_LISTENPORTS */ +-#define UIP_LISTENPORTS UIP_CONF_MAX_LISTENPORTS +-#endif /* UIP_CONF_MAX_LISTENPORTS */ +- +-/** +- * Determines if support for TCP urgent data notification should be +- * compiled in. +- * +- * Urgent data (out-of-band data) is a rarely used TCP feature that +- * very seldom would be required. +- * +- * \hideinitializer +- */ +-#define UIP_URGDATA 0 +- +-/** +- * The initial retransmission timeout counted in timer pulses. +- * +- * This should not be changed. +- */ +-#define UIP_RTO 3 +- +-/** +- * The maximum number of times a segment should be retransmitted +- * before the connection should be aborted. +- * +- * This should not be changed. +- */ +-#define UIP_MAXRTX 8 +- +-/** +- * The maximum number of times a SYN segment should be retransmitted +- * before a connection request should be deemed to have been +- * unsuccessful. +- * +- * This should not need to be changed. +- */ +-#define UIP_MAXSYNRTX 5 +- +-/** +- * The TCP maximum segment size. +- * +- * This is should not be to set to more than +- * UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN. +- */ +-#define UIP_TCP_MSS (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCP_IPv4_HLEN) +- +-/** +- * The size of the advertised receiver's window. +- * +- * Should be set low (i.e., to the size of the uip_buf buffer) is the +- * application is slow to process incoming data, or high (32768 bytes) +- * if the application processes data quickly. +- * +- * \hideinitializer +- */ +-#ifndef UIP_CONF_RECEIVE_WINDOW +-#define UIP_RECEIVE_WINDOW UIP_TCP_MSS +-#else +-#define UIP_RECEIVE_WINDOW UIP_CONF_RECEIVE_WINDOW +-#endif +- +-/** +- * How long a connection should stay in the TIME_WAIT state. +- * +- * This configiration option has no real implication, and it should be +- * left untouched. +- */ +-#define UIP_TIME_WAIT_TIMEOUT 120 +- +-/** @} */ +-/*------------------------------------------------------------------------------*/ +-/** +- * \name ARP configuration options +- * @{ +- */ +- +-/** +- * The size of the ARP table. +- * +- * This option should be set to a larger value if this uIP node will +- * have many connections from the local network. +- * +- * \hideinitializer +- */ +-#ifdef UIP_CONF_ARPTAB_SIZE +-#define UIP_ARPTAB_SIZE UIP_CONF_ARPTAB_SIZE +-#else +-#define UIP_ARPTAB_SIZE 16 +-#endif +- +-/** +- * The maxium age of ARP table entries measured in 10ths of seconds. +- * +- * An UIP_ARP_MAXAGE of 120 corresponds to 20 minutes (BSD +- * default). +- * Changed the default to 30 which corresponds to 5 minutes (Linux default) +- */ +-#define UIP_ARP_MAXAGE 30 +- +-/** @} */ +- +-/*----------------------------------------------------------------------------*/ +- +-/** +- * \name General configuration options +- * @{ +- */ +- +-/** +- * The size of the uIP packet buffer. +- * +- * The uIP packet buffer should not be smaller than 60 bytes, and does +- * not need to be larger than 1500 bytes. Lower size results in lower +- * TCP throughput, larger size results in higher TCP throughput. +- * +- * \hideinitializer +- */ +-#ifndef UIP_CONF_BUFFER_SIZE +-#define UIP_BUFSIZE 400 +-#else /* UIP_CONF_BUFFER_SIZE */ +-#define UIP_BUFSIZE UIP_CONF_BUFFER_SIZE +-#endif /* UIP_CONF_BUFFER_SIZE */ +- +-/** +- * Determines if statistics support should be compiled in. +- * +- * The statistics is useful for debugging and to show the user. +- * +- * \hideinitializer +- */ +-#ifndef UIP_CONF_STATISTICS +-#define UIP_STATISTICS 0 +-#else /* UIP_CONF_STATISTICS */ +-#define UIP_STATISTICS UIP_CONF_STATISTICS +-#endif /* UIP_CONF_STATISTICS */ +- +-/** +- * Determines if logging of certain events should be compiled in. +- * +- * This is useful mostly for debugging. The function uip_log() +- * must be implemented to suit the architecture of the project, if +- * logging is turned on. +- * +- * \hideinitializer +- */ +-#ifndef UIP_CONF_LOGGING +-#define UIP_LOGGING 0 +-#else /* UIP_CONF_LOGGING */ +-#define UIP_LOGGING UIP_CONF_LOGGING +-#endif /* UIP_CONF_LOGGING */ +- +-/** +- * Broadcast support. +- * +- * This flag configures IP broadcast support. This is useful only +- * together with UDP. +- * +- * \hideinitializer +- * +- */ +-#ifndef UIP_CONF_BROADCAST +-#define UIP_BROADCAST 0 +-#else /* UIP_CONF_BROADCAST */ +-#define UIP_BROADCAST UIP_CONF_BROADCAST +-#endif /* UIP_CONF_BROADCAST */ +- +-/** +- * Print out a uIP log message. +- * +- * This function must be implemented by the module that uses uIP, and +- * is called by uIP whenever a log message is generated. +- */ +-void uip_log(char *msg); +- +-/** +- * The link level header length. +- * +- * This is the offset into the uip_buf where the IP header can be +- * found. For Ethernet, this should be set to 14. For SLIP, this +- * should be set to 0. +- * +- * \hideinitializer +- */ +-#ifdef UIP_CONF_LLH_LEN +-#define UIP_LLH_LEN UIP_CONF_LLH_LEN +-#else /* UIP_CONF_LLH_LEN */ +-#define UIP_LLH_LEN 14 +-#endif /* UIP_CONF_LLH_LEN */ +- +-#if 0 +-/** @} */ +-/*------------------------------------------------------------------------------*/ +-/** +- * \name CPU architecture configuration +- * @{ +- * +- * The CPU architecture configuration is where the endianess of the +- * CPU on which uIP is to be run is specified. Most CPUs today are +- * little endian, and the most notable exception are the Motorolas +- * which are big endian. The BYTE_ORDER macro should be changed to +- * reflect the CPU architecture on which uIP is to be run. +- */ +- +-/** +- * The byte order of the CPU architecture on which uIP is to be run. +- * +- * This option can be either BIG_ENDIAN (Motorola byte order) or +- * LITTLE_ENDIAN (Intel byte order). +- * +- * \hideinitializer +- */ +-#ifdef UIP_CONF_BYTE_ORDER +-#define UIP_BYTE_ORDER UIP_CONF_BYTE_ORDER +-#else /* UIP_CONF_BYTE_ORDER */ +-#define UIP_BYTE_ORDER UIP_LITTLE_ENDIAN +-#endif /* UIP_CONF_BYTE_ORDER */ +-#endif +- +-/** @} */ +-/*------------------------------------------------------------------------------*/ +- +-/** +- * \name Appication specific configurations +- * @{ +- * +- * An uIP application is implemented using a single application +- * function that is called by uIP whenever a TCP/IP event occurs. The +- * name of this function must be registered with uIP at compile time +- * using the UIP_APPCALL definition. +- * +- * uIP applications can store the application state within the +- * uip_conn structure by specifying the type of the application +- * structure by typedef:ing the type uip_tcp_appstate_t and uip_udp_appstate_t. +- * +- * The file containing the definitions must be included in the +- * uipopt.h file. +- * +- * The following example illustrates how this can look. +- \code +- +-void httpd_appcall(void); +-#define UIP_APPCALL httpd_appcall +- +-struct httpd_state { +- u8_t state; +- u16_t count; +- char *dataptr; +- char *script; +-}; +-typedef struct httpd_state uip_tcp_appstate_t +- \endcode +- */ +- +-/** +- * \var #define UIP_APPCALL +- * +- * The name of the application function that uIP should call in +- * response to TCP/IP events. +- * +- */ +- +-/** +- * \var typedef uip_tcp_appstate_t +- * +- * The type of the application state that is to be stored in the +- * uip_conn structure. This usually is typedef:ed to a struct holding +- * application state information. +- */ +- +-/** +- * \var typedef uip_udp_appstate_t +- * +- * The type of the application state that is to be stored in the +- * uip_conn structure. This usually is typedef:ed to a struct holding +- * application state information. +- */ +-/** @} */ +-/** @} */ +- +-#endif /* __UIPOPT_H__ */ +diff --git a/iscsiuio/src/unix/.gitignore b/iscsiuio/src/unix/.gitignore +deleted file mode 100644 +index b3b37db..0000000 +--- a/iscsiuio/src/unix/.gitignore ++++ /dev/null +@@ -1,3 +0,0 @@ +-build_date.c +-build_date.h +-iscsiuio +diff --git a/iscsiuio/src/unix/Makefile.am b/iscsiuio/src/unix/Makefile.am +deleted file mode 100644 +index a989ef0..0000000 +--- a/iscsiuio/src/unix/Makefile.am ++++ /dev/null +@@ -1,41 +0,0 @@ +-SUBDIRS= libs +- +-AM_CFLAGS = -I${top_srcdir}/src/uip \ +- -I${top_srcdir}/src/apps/brcm-iscsi \ +- -I${top_srcdir}/src/apps/dhcpc \ +- -I${top_srcdir}/src/unix/libs \ +- -I${top_srcdir}/../include \ +- -I${top_srcdir}/../usr +- +-sbin_PROGRAMS = iscsiuio +- +-iscsiuio_SOURCES = build_date.c \ +- main.c \ +- clock-arch.c \ +- logger.c \ +- nic.c \ +- nic_id.c \ +- nic_vlan.c \ +- nic_nl.c \ +- nic_utils.c \ +- packet.c \ +- iscsid_ipc.c \ +- ping.c \ +- ${top_srcdir}/../utils/sysdeps/sysdeps.c +- +-iscsiuio_CFLAGS = $(AM_CFLAGS) \ +- $(LIBNL_CFLAGS) \ +- -DBYTE_ORDER=@ENDIAN@ +- +-iscsiuio_LDFLAGS= $(AM_LDADD) \ +- -ldl \ +- -rdynamic \ +- $(LIBNL_LIBS) \ +- -lpthread +- +-iscsiuio_LDADD = ${top_srcdir}/src/uip/lib_iscsi_uip.a \ +- ${top_srcdir}/src/apps/dhcpc/lib_apps_dhcpc.a\ +- ${top_srcdir}/src/apps/brcm-iscsi/lib_apps_brcm_iscsi.a \ +- ${top_srcdir}/src/unix/libs/lib_iscsiuio_hw_cnic.a +- +-iscsiuio_YFLAGS = -d +diff --git a/iscsiuio/src/unix/clock-arch.c b/iscsiuio/src/unix/clock-arch.c +deleted file mode 100644 +index d853101..0000000 +--- a/iscsiuio/src/unix/clock-arch.c ++++ /dev/null +@@ -1,54 +0,0 @@ +-/* +- * Copyright (c) 2006, Swedish Institute of Computer Science. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. Neither the name of the Institute nor the names of its contributors +- * may be used to endorse or promote products derived from this software +- * without specific prior written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND +- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE +- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +- * SUCH DAMAGE. +- * +- * This file is part of the uIP TCP/IP stack +- * +- */ +- +-/** +- * \file +- * Implementation of architecture-specific clock functionality +- * \author +- * Adam Dunkels +- */ +- +-#include "clock-arch.h" +-#include +- +-/*---------------------------------------------------------------------------*/ +-clock_time_t clock_time(void) +-{ +- struct timeval tv; +- struct timezone tz; +- +- gettimeofday(&tv, &tz); +- +- return tv.tv_sec * 1000 + tv.tv_usec / 1000; +-} +- +-/*---------------------------------------------------------------------------*/ +diff --git a/iscsiuio/src/unix/clock-arch.h b/iscsiuio/src/unix/clock-arch.h +deleted file mode 100644 +index 888933f..0000000 +--- a/iscsiuio/src/unix/clock-arch.h ++++ /dev/null +@@ -1,39 +0,0 @@ +-/* +- * Copyright (c) 2006, Swedish Institute of Computer Science. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. Neither the name of the Institute nor the names of its contributors +- * may be used to endorse or promote products derived from this software +- * without specific prior written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND +- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE +- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +- * SUCH DAMAGE. +- * +- * This file is part of the uIP TCP/IP stack +- * +- */ +- +-#ifndef __CLOCK_ARCH_H__ +-#define __CLOCK_ARCH_H__ +- +-typedef int clock_time_t; +-#define CLOCK_CONF_SECOND 1000 +- +-#endif /* __CLOCK_ARCH_H__ */ +diff --git a/iscsiuio/src/unix/iscsid_ipc.c b/iscsiuio/src/unix/iscsid_ipc.c +deleted file mode 100644 +index ea03d37..0000000 +--- a/iscsiuio/src/unix/iscsid_ipc.c ++++ /dev/null +@@ -1,1255 +0,0 @@ +-/* +- * Copyright (c) 2009-2011, Broadcom Corporation +- * Copyright (c) 2014, QLogic Corporation +- * +- * Written by: Benjamin Li (benli@broadcom.com) +- * +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. All advertising materials mentioning features or use of this software +- * must display the following acknowledgement: +- * This product includes software developed by Adam Dunkels. +- * 4. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * iscsi_ipc.c - Generic NIC management/utility functions +- * +- */ +- +-#define _GNU_SOURCE +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#define PFX "iscsi_ipc " +- +-#include "nic.h" +-#include "nic_utils.h" +-#include "nic_vlan.h" +-#include "options.h" +-#include "mgmt_ipc.h" +-#include "iscsid_ipc.h" +-#include "uip.h" +-#include "uip_mgmt_ipc.h" +-#include "sysdeps.h" +- +-#include "logger.h" +-#include "uip.h" +-#include "ping.h" +- +-/* private iscsid options stucture */ +-struct iscsid_options { +- int fd; +- pthread_t thread; +-}; +- +-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; +-}; +- +-#define PEERUSER_MAX 64 +- +-/****************************************************************************** +- * Globals +- *****************************************************************************/ +-static struct iscsid_options iscsid_opts = { +- .fd = INVALID_FD, +- .thread = INVALID_THREAD, +-}; +- +-/****************************************************************************** +- * iscsid Functions +- *****************************************************************************/ +- +-static void *enable_nic_thread(void *data) +-{ +- nic_t *nic = (nic_t *) data; +- +- prepare_nic_thread(nic); +- LOG_INFO(PFX "%s: started NIC enable thread state: 0x%x", +- nic->log_name, nic->state) +- +- /* Enable the NIC */ +- nic_enable(nic); +- +- nic->enable_thread = INVALID_THREAD; +- +- pthread_exit(NULL); +-} +- +-static int decode_cidr(char *in_ipaddr_str, struct iface_rec_decode *ird) +-{ +- int rc = 0, i; +- char *tmp, *tok; +- char ipaddr_str[NI_MAXHOST]; +- char str[INET6_ADDRSTRLEN]; +- unsigned long keepbits = 0; +- struct in_addr ia; +- struct in6_addr ia6; +- +- strlcpy(ipaddr_str, in_ipaddr_str, NI_MAXHOST); +- +- /* Find the CIDR if any */ +- tmp = strchr(ipaddr_str, '/'); +- if (tmp) { +- /* CIDR found, now decode, tmpbuf = ip, tmp = netmask */ +- tmp = ipaddr_str; +- tok = strsep(&tmp, "/"); +- LOG_INFO(PFX "in cidr: bitmask '%s' ip '%s'", tmp, tok); +- keepbits = strtoull(tmp, NULL, 10); +- } +- +- /* Determine if the IP address passed from the iface file is +- * an IPv4 or IPv6 address */ +- 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, &ird->ipv6_addr); +- if (rc == 0) { +- LOG_ERR(PFX "Could not parse IP address: '%s'", +- ipaddr_str); +- goto out; +- } +- ird->ip_type = AF_INET6; +- if (keepbits > 128) { +- LOG_ERR(PFX "CIDR netmask > 128 for IPv6: %d(%s)", +- keepbits, tmp); +- goto out; +- } +- if (!keepbits) { +- /* Default prefix mask to 64 */ +- memcpy(&ird->ipv6_subnet_mask.s6_addr, all_zeroes_addr6, +- sizeof(struct in6_addr)); +- ird->prefix_len = 64; +- for (i = 0; i < 2; i++) +- ird->ipv6_subnet_mask.s6_addr32[i] = 0xffffffff; +- goto out; +- } +- 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 ? +- 0x00 - (1 << (32 - keepbits)) : 0; +- ia6.s6_addr32[i] = htonl(ia6.s6_addr32[i]); +- break; +- } else +- ia6.s6_addr32[i] = 0xFFFFFFFF; +- keepbits -= 32; +- } +- ird->ipv6_subnet_mask = ia6; +- if (inet_ntop(AF_INET6, &ia6, str, sizeof(str))) +- LOG_INFO(PFX "Using netmask: %s", str); +- } else { +- 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)", +- keepbits, tmp); +- goto out; +- } +- ia.s_addr = keepbits > 0 ? 0x00 - (1 << (32 - keepbits)) : 0; +- 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_INET6, 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) { +- strlcpy(ipaddr_str, rec->ipv6_linklocal, +- NI_MAXHOST); +- 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) { +- strlcpy(ipaddr_str, rec->ipv6_router, +- NI_MAXHOST); +- 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); +- +- strlcpy(ipaddr_str, rec->gateway, NI_MAXHOST); +- 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 void *perform_ping(void *arg) +-{ +- struct ping_conf *png_c = (struct ping_conf *)arg; +- nic_interface_t *nic_iface = png_c->nic_iface; +- nic_t *nic = nic_iface->parent; +- iscsid_uip_broadcast_t *data; +- struct sockaddr_in *addr; +- struct sockaddr_in6 *addr6; +- uip_ip6addr_t dst_addr; +- int rc = 0; +- int datalen; +- struct timespec ts = {.tv_sec = 5, +- .tv_nsec = 0}; +- +- data = (iscsid_uip_broadcast_t *)png_c->data; +- datalen = data->u.ping_rec.datalen; +- if ((datalen > STD_MTU_SIZE) || (datalen < 0)) { +- LOG_ERR(PFX "Ping datalen invalid: %d", datalen); +- rc = -EINVAL; +- goto ping_done; +- } +- +- memset(dst_addr, 0, sizeof(uip_ip6addr_t)); +- if (nic_iface->protocol == AF_INET) { +- /* IPv4 */ +- addr = (struct sockaddr_in *)&data->u.ping_rec.ipaddr; +- memcpy(dst_addr, &addr->sin_addr.s_addr, sizeof(uip_ip4addr_t)); +- } else { +- /* IPv6 */ +- addr6 = (struct sockaddr_in6 *)&data->u.ping_rec.ipaddr; +- memcpy(dst_addr, &addr6->sin6_addr.s6_addr, +- sizeof(uip_ip6addr_t)); +- } +- +- /* Ensure that the NIC is RUNNING */ +- if ((nic->state != NIC_RUNNING) || !(nic->flags & NIC_ENABLED)) { +- pthread_mutex_lock(&nic->nic_mutex); +- rc = pthread_cond_timedwait(&nic->enable_done_cond, +- &nic->nic_mutex, &ts); +- if ((rc == 0) && (nic->state == NIC_RUNNING)) { +- LOG_DEBUG(PFX "%s: nic running", nic->log_name); +- } else if (rc) { +- LOG_DEBUG(PFX "%s: err %d", nic->log_name, rc); +- rc = -EAGAIN; +- } +- pthread_mutex_unlock(&nic->nic_mutex); +- } +- +- if (rc || nic->state != NIC_RUNNING) { +- png_c->state = rc; +- goto ping_done; +- } +- +- ping_init(png_c, dst_addr, nic_iface->protocol, datalen); +- +- rc = do_ping_from_nic_iface(png_c); +- if (png_c->state == -1) +- png_c->state = rc; +- +-ping_done: +- LOG_INFO(PFX "ping thread end"); +- nic->ping_thread = INVALID_THREAD; +- pthread_exit(NULL); +-} +- +-static int parse_iface(void *arg, int do_ping) +-{ +- int rc, i; +- nic_t *nic = NULL; +- nic_interface_t *nic_iface; +- char *transport_name; +- size_t transport_name_size; +- nic_lib_handle_t *handle; +- iscsid_uip_broadcast_t *data; +- char ipv6_buf_str[INET6_ADDRSTRLEN]; +- int request_type = 0; +- struct iface_rec *rec; +- struct iface_rec_decode ird; +- struct in_addr src_match, dst_match; +- pthread_attr_t attr; +- struct ping_conf *png_c; +- +- data = (iscsid_uip_broadcast_t *) arg; +- if (do_ping) +- rec = &data->u.ping_rec.ifrec; +- else +- 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); +- +- 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; +- } +- 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; +- +- if (pthread_mutex_trylock(&nic_list_mutex) == 0) +- break; +- +- sleep_req.tv_sec = 0; +- sleep_req.tv_nsec = 100000; +- nanosleep(&sleep_req, &sleep_rem); +- } +- +- if (i >= 10) { +- 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); +- +- if (rc != 0) { +- LOG_WARN(PFX "Couldn't find NIC: %s, creating an instance", +- rec->netdev); +- +- nic = nic_init(); +- if (nic == NULL) { +- LOG_ERR(PFX "Couldn't allocate space for NIC %s", +- rec->netdev); +- +- rc = -ENOMEM; +- goto done; +- } +- +- strncpy(nic->eth_device_name, +- rec->netdev, +- sizeof(nic->eth_device_name)); +- nic->config_device_name = nic->eth_device_name; +- nic->log_name = nic->eth_device_name; +- +- if (nic_fill_name(nic) != 0) { +- free(nic); +- rc = -EIO; +- goto done; +- } +- +- nic_add(nic); +- } else { +- LOG_INFO(PFX " %s, using existing NIC", +- 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 timeout */ +- if (nic->pending_count > 1000) { +- 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; +- } +- +- 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 = 2; +- sleep_req.tv_nsec = 0; +- nanosleep(&sleep_req, &sleep_rem); +- +- pthread_mutex_lock(&nic->nic_mutex); +- if (!(nic->flags & NIC_ENABLED) || +- nic->state != NIC_RUNNING) { +- 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); +- +- /* Sanity Check to ensure the transport names are the same */ +- handle = nic->nic_library; +- if (handle != NULL) { +- (*handle->ops->lib_ops.get_transport_name) (&transport_name, +- &transport_name_size); +- +- if (strncmp(transport_name, +- rec->transport_name, +- transport_name_size) != 0) { +- LOG_ERR(PFX "%s Transport name is not equal " +- "expected: %s got: %s", +- nic->log_name, +- rec->transport_name, +- transport_name); +- } +- } else { +- LOG_ERR(PFX "%s Couldn't find nic library ", nic->log_name); +- rc = -EIO; +- goto done; +- } +- +- LOG_INFO(PFX "%s library set using transport_name %s", +- nic->log_name, transport_name); +- +- /* Determine how to configure the IP address */ +- 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); +- request_type = IPV4_CONFIG_DHCP; +- } else { +- LOG_INFO(PFX "%s: requesting configuration using " +- "static IP address", nic->log_name); +- request_type = IPV4_CONFIG_STATIC; +- } +- } 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; +- 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, 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) { +- pthread_attr_init(&attr); +- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); +- rc = pthread_create(&nic->nl_process_thread, &attr, +- 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, &ird.ipv4_addr, +- sizeof(struct in_addr))) +- goto reacquire; +- } else if (request_type == IPV6_CONFIG_STATIC) { +- if (memcmp(nic_iface->ustack.hostaddr6, &ird.ipv6_addr, +- sizeof(struct in6_addr))) +- 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); +- /* No need to acquire the IP address */ +- inet_ntop(AF_INET6, &ird.ipv6_addr, ipv6_buf_str, +- sizeof(ipv6_buf_str)); +- +- 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 +- * if the IP address is equal to 0.0.0.0. If it is +- * then the user has specified to use DHCP. If not +- * then the user has spcicied to use a static IP address +- * an the default netmask will be used */ +- switch (request_type) { +- case IPV4_CONFIG_DHCP: +- 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, &ird.ipv4_addr, +- sizeof(struct in_addr)); +- LOG_INFO(PFX "%s: configuring using static IP " +- "IPv4 address :%s ", +- 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 = 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, +- &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, &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; +- +- if (memcmp(&ird.ipv6_subnet_mask, all_zeroes_addr6, +- sizeof(struct in6_addr))) +- memcpy(nic_iface->ustack.netmask6, +- &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); +- +- } +- +-enable_nic: +- switch (nic->state) { +- case NIC_STOPPED: +- /* This thread will be thrown away when completed */ +- if (nic->enable_thread != INVALID_THREAD) { +- rc = pthread_cancel(nic->enable_thread); +- if (rc != 0) { +- LOG_INFO(PFX "%s: failed to cancel enable NIC " +- "thread\n", nic->log_name); +- goto eagain; +- } +- } +- pthread_attr_init(&attr); +- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); +- rc = pthread_create(&nic->enable_thread, &attr, +- enable_nic_thread, (void *)nic); +- if (rc != 0) +- LOG_WARN(PFX "%s: failed starting enable NIC thread\n", +- nic->log_name); +-eagain: +- rc = -EAGAIN; +- 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; +- } +- +- 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, +- (ird.ip_type == AF_INET) ? inet_ntoa(ird.ipv4_addr) : +- ipv6_buf_str, +- ird.vlan_id, rec->transport_name); +- +- if (do_ping) { +- if (nic->ping_thread != INVALID_THREAD) { +- rc = pthread_cancel(nic->ping_thread); +- if (rc != 0) { +- LOG_INFO(PFX "%s: failed to cancel ping thread", +- nic->log_name); +- rc = -EAGAIN; +- goto done; +- } +- } +- +- png_c = malloc(sizeof(struct ping_conf)); +- if (!png_c) { +- LOG_ERR(PFX "Memory alloc failed for ping conf"); +- rc = -ENOMEM; +- goto done; +- } +- +- memset(png_c, 0, sizeof(struct ping_conf)); +- png_c->nic_iface = nic_iface; +- png_c->data = arg; +- nic_iface->ustack.ping_conf = png_c; +- +- /* Spawn a thread to perform ping operation. +- * This thread will exit when done. +- */ +- rc = pthread_create(&nic->ping_thread, NULL, +- perform_ping, (void *)png_c); +- if (rc != 0) { +- LOG_WARN(PFX "%s: failed starting ping thread\n", +- nic->log_name); +- } else { +- pthread_join(nic->ping_thread, NULL); +- rc = png_c->state; +- if (rc == -EAGAIN) +- png_c->state = 0; +- } +- free(png_c); +- nic_iface->ustack.ping_conf = NULL; +- } +- +-done: +- pthread_mutex_unlock(&nic_list_mutex); +- +-early_exit: +- return rc; +-} +- +-/** +- * process_iscsid_broadcast() - This function is used to process the +- * broadcast messages from iscsid +- * +- * s2 is an open file descriptor, which +- * must not be left open upon return +- */ +-int process_iscsid_broadcast(int s2) +-{ +- int rc = 0; +- iscsid_uip_broadcast_t *data; +- iscsid_uip_rsp_t rsp; +- FILE *fd; +- size_t size; +- iscsid_uip_cmd_e cmd; +- uint32_t payload_len; +- +- fd = fdopen(s2, "r+"); +- if (fd == NULL) { +- LOG_ERR(PFX "Couldn't open file descriptor: %d(%s)", +- errno, strerror(errno)); +- close(s2); +- return -EIO; +- } +- +- /* This will be freed by parse_iface_thread() */ +- data = (iscsid_uip_broadcast_t *) calloc(1, sizeof(*data)); +- if (data == NULL) { +- LOG_ERR(PFX "Couldn't allocate memory for iface data"); +- rc = -ENOMEM; +- goto error; +- } +- memset(data, 0, sizeof(*data)); +- +- size = fread(data, sizeof(iscsid_uip_broadcast_header_t), 1, fd); +- if (!size) { +- LOG_ERR(PFX "Could not read request: %d(%s)", +- errno, strerror(errno)); +- rc = ferror(fd); +- goto error; +- } +- +- cmd = data->header.command; +- payload_len = data->header.payload_len; +- if (payload_len > sizeof(data->u)) { +- LOG_ERR(PFX "Data payload length too large (%d). Corrupt payload?", +- payload_len); +- rc = -EINVAL; +- goto error; +- } +- +- LOG_DEBUG(PFX "recv iscsid request: cmd: %d, payload_len: %d", +- cmd, payload_len); +- +- memset(&rsp, 0, sizeof(rsp)); +- +- switch (cmd) { +- case ISCSID_UIP_IPC_GET_IFACE: +- size = fread(&data->u.iface_rec, payload_len, 1, fd); +- if (!size) { +- LOG_ERR(PFX "Could not read data: %d(%s)", +- errno, strerror(errno)); +- goto error; +- } +- +- rc = parse_iface(data, 0); +- switch (rc) { +- case 0: +- rsp.command = cmd; +- rsp.err = ISCSID_UIP_MGMT_IPC_DEVICE_UP; +- break; +- case -EAGAIN: +- rsp.command = cmd; +- rsp.err = ISCSID_UIP_MGMT_IPC_DEVICE_INITIALIZING; +- break; +- default: +- rsp.command = cmd; +- rsp.err = ISCSID_UIP_MGMT_IPC_ERR; +- } +- +- break; +- case ISCSID_UIP_IPC_PING: +- size = fread(&data->u.ping_rec, payload_len, 1, fd); +- if (!size) { +- LOG_ERR(PFX "Could not read data: %d(%s)", +- errno, strerror(errno)); +- goto error; +- } +- +- rc = parse_iface(data, 1); +- rsp.command = cmd; +- rsp.ping_sc = rc; +- +- switch (rc) { +- case 0: +- rsp.err = ISCSID_UIP_MGMT_IPC_DEVICE_UP; +- break; +- case -EAGAIN: +- rsp.err = ISCSID_UIP_MGMT_IPC_DEVICE_INITIALIZING; +- break; +- default: +- rsp.err = ISCSID_UIP_MGMT_IPC_ERR; +- } +- +- break; +- default: +- LOG_WARN(PFX "Unknown iscsid broadcast command: %x", +- data->header.command); +- +- /* Send a response back to iscsid to tell it the +- operation succeeded */ +- rsp.command = cmd; +- rsp.err = ISCSID_UIP_MGMT_IPC_OK; +- break; +- } +- +- size = fwrite(&rsp, sizeof(rsp), 1, fd); +- if (size == -1) { +- LOG_ERR(PFX "Could not send response: %d(%s)", +- errno, strerror(errno)); +- rc = ferror(fd); +- } +- +-error: +- if (data) +- free(data); +- fclose(fd); +- +- return rc; +-} +- +-static void iscsid_loop_close(void *arg) +-{ +- close(iscsid_opts.fd); +- +- LOG_INFO(PFX "iSCSI daemon socket closed"); +-} +- +-/* +- * check that the peer user is privilidged +- * +- * return 1 if peer is ok else 0 +- * +- * XXX: this function is copied from iscsid_ipc.c and should be +- * moved into a common library +- */ +-static int +-mgmt_peeruser(int sock, char *user) +-{ +- struct ucred peercred; +- socklen_t so_len = sizeof(peercred); +- struct passwd *pass; +- +- errno = 0; +- if (getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &peercred, +- &so_len) != 0 || so_len != sizeof(peercred)) { +- /* We didn't get a valid credentials struct. */ +- LOG_ERR(PFX "peeruser_unux: error receiving credentials: %m"); +- return 0; +- } +- +- pass = getpwuid(peercred.uid); +- if (pass == NULL) { +- LOG_ERR(PFX "peeruser_unix: unknown local user with uid %d", +- (int) peercred.uid); +- return 0; +- } +- +- strlcpy(user, pass->pw_name, PEERUSER_MAX); +- return 1; +-} +- +-/** +- * iscsid_loop() - This is the function which will process the broadcast +- * messages from iscsid +- * +- */ +-static void *iscsid_loop(void *arg) +-{ +- int rc; +- sigset_t set; +- char user[PEERUSER_MAX]; +- +- pthread_cleanup_push(iscsid_loop_close, arg); +- +- sigfillset(&set); +- rc = pthread_sigmask(SIG_BLOCK, &set, NULL); +- if (rc != 0) { +- LOG_ERR(PFX +- "Couldn't set signal mask for the iscisd listening " +- "thread"); +- } +- +- LOG_DEBUG(PFX "Started iscsid listening thread"); +- +- while (1) { +- struct sockaddr_un remote; +- socklen_t sock_len; +- int s2; +- +- LOG_DEBUG(PFX "Waiting for iscsid command"); +- +- sock_len = sizeof(remote); +- s2 = accept(iscsid_opts.fd, +- (struct sockaddr *)&remote, &sock_len); +- if (s2 == -1) { +- if (errno == EAGAIN) { +- LOG_DEBUG("Got EAGAIN from accept"); +- sleep(1); +- continue; +- } else if (errno == EINTR) { +- LOG_DEBUG("Got EINTR from accept"); +- /* The program is terminating, time to exit */ +- break; +- } +- +- LOG_ERR(PFX "Could not accept: %d(%s)", +- s2, strerror(errno)); +- continue; +- } +- +- if (!mgmt_peeruser(iscsid_opts.fd, user) || strncmp(user, "root", PEERUSER_MAX)) { +- close(s2); +- LOG_ERR(PFX "Access error: non-administrative connection rejected"); +- break; +- } +- +- /* this closes the file descriptor s2 */ +- process_iscsid_broadcast(s2); +- } +- +- pthread_cleanup_pop(0); +- +- LOG_ERR(PFX "exit iscsid listening thread"); +- +- pthread_exit(NULL); +-} +- +-#define SD_SOCKET_FDS_START 3 +- +-static int ipc_systemd(void) +-{ +- char *env; +- +- env = getenv("LISTEN_PID"); +- +- if (!env || (strtoul(env, NULL, 10) != getpid())) +- return -EINVAL; +- +- env = getenv("LISTEN_FDS"); +- +- if (!env) +- return -EINVAL; +- +- if (strtoul(env, NULL, 10) != 1) { +- LOG_ERR("Did not receive exactly one IPC socket from systemd"); +- return -EINVAL; +- } +- +- return SD_SOCKET_FDS_START; +-} +- +-/****************************************************************************** +- * Initialize/Cleanup routines +- ******************************************************************************/ +-/** +- * iscsid_init() - This function will setup the thread used to listen for +- * the iscsid broadcast messages +- * @return 0 on success, <0 on failure +- */ +-int iscsid_init() +-{ +- int rc, addr_len; +- struct sockaddr_un addr; +- +- iscsid_opts.fd = ipc_systemd(); +- if (iscsid_opts.fd >= 0) +- return 0; +- +- iscsid_opts.fd = socket(AF_LOCAL, SOCK_STREAM, 0); +- if (iscsid_opts.fd < 0) { +- LOG_ERR(PFX "Can not create IPC socket"); +- return iscsid_opts.fd; +- } +- +- addr_len = offsetof(struct sockaddr_un, sun_path) + strlen(ISCSID_UIP_NAMESPACE) + 1; +- +- memset(&addr, 0, sizeof(addr)); +- addr.sun_family = AF_LOCAL; +- memcpy((char *)&addr.sun_path + 1, ISCSID_UIP_NAMESPACE, +- strlen(ISCSID_UIP_NAMESPACE)); +- +- rc = bind(iscsid_opts.fd, (struct sockaddr *)&addr, addr_len); +- if (rc < 0) { +- LOG_ERR(PFX "Can not bind IPC socket: %s", strerror(errno)); +- goto error; +- } +- +- rc = listen(iscsid_opts.fd, 32); +- if (rc < 0) { +- LOG_ERR(PFX "Can not listen IPC socket: %s", strerror(errno)); +- goto error; +- } +- +- return 0; +-error: +- close(iscsid_opts.fd); +- iscsid_opts.fd = INVALID_FD; +- +- return rc; +-} +- +-/** +- * iscsid_start() - This function will start the thread used to listen for +- * the iscsid broadcast messages +- * @return 0 on success, <0 on failure +- */ +-int iscsid_start() +-{ +- pthread_attr_t attr; +- int rc; +- +- pthread_attr_init(&attr); +- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); +- rc = pthread_create(&iscsid_opts.thread, &attr, iscsid_loop, NULL); +- if (rc != 0) { +- LOG_ERR(PFX "Could not start iscsid listening thread rc=%d", +- rc); +- goto error; +- } +- +- return 0; +- +-error: +- close(iscsid_opts.fd); +- iscsid_opts.fd = INVALID_FD; +- +- return rc; +-} +- +-/** +- * iscsid_cleanup() - This is called when stoping the thread listening +- * for the iscsid broadcast messages +- */ +-void iscsid_cleanup() +-{ +- int rc; +- +- if (iscsid_opts.fd != INVALID_FD && +- iscsid_opts.thread != INVALID_THREAD) { +- rc = pthread_cancel(iscsid_opts.thread); +- if (rc != 0) { +- LOG_ERR("Could not cancel iscsid listening thread: %s", +- strerror(rc)); +- } +- } +- +- LOG_INFO(PFX "iscsid listening thread has shutdown"); +-} +diff --git a/iscsiuio/src/unix/iscsid_ipc.h b/iscsiuio/src/unix/iscsid_ipc.h +deleted file mode 100644 +index 60bcd71..0000000 +--- a/iscsiuio/src/unix/iscsid_ipc.h ++++ /dev/null +@@ -1,52 +0,0 @@ +-/* +- * Copyright (c) 2009-2011, Broadcom Corporation +- * Copyright (c) 2014, QLogic Corporation +- * +- * Written by: Benjamin Li (benli@broadcom.com) +- * +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. All advertising materials mentioning features or use of this software +- * must display the following acknowledgement: +- * This product includes software developed by Adam Dunkels. +- * 4. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * iscsid_ipc.h: Generic NIC management/utility functions +- * +- */ +-#ifndef __ISCSID_IPC_H__ +-#define __ISCSID_IPC_H__ +- +-#include "uip.h" +-#include "mgmt_ipc.h" +- +-enum mgmt_ipc_err iscsid_connect(int *fd); +-int iscsid_get_ipaddr(int fd, uip_ip4addr_t *ipaddr); +- +-int iscsid_init(); +-int iscsid_start(); +-void iscsid_cleanup(); +- +-#endif /* __ISCSID_IPC_H__ */ +diff --git a/iscsiuio/src/unix/libs/Makefile.am b/iscsiuio/src/unix/libs/Makefile.am +deleted file mode 100644 +index 737546b..0000000 +--- a/iscsiuio/src/unix/libs/Makefile.am ++++ /dev/null +@@ -1,14 +0,0 @@ +-AM_CFLAGS = -I${top_srcdir}/src/uip \ +- -I${top_srcdir}/src/unix \ +- -I${top_srcdir}/src/unix/libs \ +- -I${top_srcdir}/src/apps/dhcpc \ +- -I${top_srcdir}/../include \ +- -I${top_srcdir}/../usr +- +-noinst_LIBRARIES = lib_iscsiuio_hw_cnic.a +- +-lib_iscsiuio_hw_cnic_a_SOURCES = ../build_date.c \ +- cnic.c \ +- bnx2.c \ +- bnx2x.c \ +- qedi.c +diff --git a/iscsiuio/src/unix/libs/bnx2.c b/iscsiuio/src/unix/libs/bnx2.c +deleted file mode 100644 +index 1181cf4..0000000 +--- a/iscsiuio/src/unix/libs/bnx2.c ++++ /dev/null +@@ -1,1165 +0,0 @@ +-/* +- * Copyright (c) 2009-2011, Broadcom Corporation +- * Copyright (c) 2014, QLogic Corporation +- * +- * Written by: Benjamin Li (benli@broadcom.com) +- * +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. All advertising materials mentioning features or use of this software +- * must display the following acknowledgement: +- * This product includes software developed by Adam Dunkels. +- * 4. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * bnx2.c - bnx2 user space driver +- * +- */ +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include "config.h" +- +-#include "build_date.h" +-#include "bnx2.h" +-#include "cnic.h" +-#include "logger.h" +-#include "nic.h" +-#include "nic_utils.h" +-#include "options.h" +- +-#define PFX "bnx2 " +- +-/* Foward struct declarations */ +-struct nic_ops bnx2_op; +- +-/******************************************************************************* +- * NIC Library Strings +- ******************************************************************************/ +-static const char library_name[] = "bnx2"; +-static const char library_version[] = PACKAGE_VERSION; +-static const char library_uio_name[] = "bnx2_cnic"; +- +-/* The name that should be returned from /sys/class/uio/uio0/name */ +-static const char cnic_uio_sysfs_name_tempate[] = "/sys/class/uio/uio%i/name"; +-static const char cnic_uio_sysfs_name[] = "bnx2_cnic"; +- +-/******************************************************************************* +- * String constants used to display human readable adapter name +- ******************************************************************************/ +-static const char hp_NC370T[] = +- "HP NC370T Multifunction Gigabit Server Adapter"; +-static const char hp_NC370I[] = +- "HP NC370i Multifunction Gigabit Server Adapter"; +-static const char brcm_5706S[] = "QLogic NetXtreme II BCM5706 1000Base-SX"; +-static const char hp_NC370F[] = +- "HP NC370F Multifunction Gigabit Server Adapter"; +-static const char brcm_5708C[] = "QLogic NetXtreme II BCM5708 1000Base-T"; +-static const char brcm_5708S[] = "QLogic NetXtreme II BCM5708 1000Base-SX"; +-static const char brcm_5709C[] = "QLogic NetXtreme II BCM5709 1000Base-T"; +-static const char brcm_5709S[] = "QLogic NetXtreme II BCM5709 1000Base-SX"; +-static const char brcm_5716C[] = "QLogic NetXtreme II BCM5716 1000Base-T"; +-static const char brcm_5716S[] = "QLogic NetXtreme II BCM5716 1000Base-SX"; +- +-/******************************************************************************* +- * PCI ID constants +- ******************************************************************************/ +-#define PCI_VENDOR_ID_BROADCOM 0x14e4 +-#define PCI_DEVICE_ID_NX2_5709 0x1639 +-#define PCI_DEVICE_ID_NX2_5709S 0x163a +-#define PCI_DEVICE_ID_NX2_5706 0x164a +-#define PCI_DEVICE_ID_NX2_5708 0x164c +-#define PCI_DEVICE_ID_NX2_5706S 0x16aa +-#define PCI_DEVICE_ID_NX2_5708S 0x16ac +- +-#define PCI_VENDOR_ID_HP 0x103c +- +-#define PCI_ANY_ID (~0) +- +-/* This is the table used to match PCI vendor and device ID's to the +- * human readable string names of the devices */ +-static const struct pci_device_id bnx2_pci_tbl[] = { +- {PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5706, +- PCI_VENDOR_ID_HP, 0x3101, hp_NC370T}, +- {PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5706, +- PCI_VENDOR_ID_HP, 0x3106, hp_NC370I}, +- {PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5706, +- PCI_ANY_ID, PCI_ANY_ID, brcm_5706S}, +- {PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5708, +- PCI_ANY_ID, PCI_ANY_ID, brcm_5708C}, +- {PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5706S, +- PCI_VENDOR_ID_HP, 0x3102, hp_NC370F}, +- {PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5706S, +- PCI_ANY_ID, PCI_ANY_ID, brcm_5706S}, +- {PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5708S, +- PCI_ANY_ID, PCI_ANY_ID, brcm_5708S}, +- {PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5709, +- PCI_ANY_ID, PCI_ANY_ID, brcm_5709C}, +- {PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5709S, +- PCI_ANY_ID, PCI_ANY_ID, brcm_5709S}, +- {PCI_VENDOR_ID_BROADCOM, 0x163b, +- PCI_ANY_ID, PCI_ANY_ID, brcm_5716C}, +- {PCI_VENDOR_ID_BROADCOM, 0x163c, +- PCI_ANY_ID, PCI_ANY_ID, brcm_5716S}, +-}; +- +-/******************************************************************************* +- * bnx2 Library Functions +- ******************************************************************************/ +-/** +- * bnx2_get_library_name() - Used to get the name of this NIC libary +- * @param name - This function will return the pointer to this NIC +- * library name +- * @param name_size +- */ +-static void bnx2_get_library_name(char **name, size_t *name_size) +-{ +- *name = (char *)library_name; +- *name_size = sizeof(library_name); +-} +- +-/** +- * bnx2_get_library_version() - Used to get the version string of this +- * NIC libary +- * @param version - This function will return the pointer to this NIC +- * library version string +- * @param version_size - This will be set with the version size +- */ +-static void bnx2_get_library_version(char **version, size_t *version_size) +-{ +- *version = (char *)library_version; +- *version_size = sizeof(library_version); +-} +- +-/** +- * bnx2_get_build_date() - Used to get the build date string of this library +- * @param version - This function will return the pointer to this NIC +- * library build date string +- * @param version_size - This will be set with the build date string size +- */ +-static void bnx2_get_build_date(char **build, size_t *build_size) +-{ +- *build = (char *)build_date; +- *build_size = sizeof(build_date); +-} +- +-/** +- * bnx2_get_transport_name() - Used to get the transport name associated +- * with this this NIC libary +- * @param transport_name - This function will return the pointer to this NIC +- * library's associated transport string +- * @param transport_name_size - This will be set with the transport name size +- */ +-static void bnx2_get_transport_name(char **transport_name, +- size_t *transport_name_size) +-{ +- *transport_name = (char *)bnx2i_library_transport_name; +- *transport_name_size = bnx2i_library_transport_name_size; +-} +- +-/** +- * bnx2_get_uio_name() - Used to get the uio name associated with this this +- * NIC libary +- * @param uio_name - This function will return the pointer to this NIC +- * library's associated uio string +- * @param transport_name_size - This will be set with the uio name size +- */ +-static void bnx2_get_uio_name(char **uio_name, size_t *uio_name_size) +-{ +- *uio_name = (char *)library_uio_name; +- *uio_name_size = sizeof(library_uio_name); +-} +- +-/** +- * bnx2_get_pci_table() - Used to get the PCI table for this NIC libary +- * to determine which NIC's based off of PCI ID's +- * are supported +- * @param table - This function will return the pointer to the PCI table +- * @param entries - This function will return the number of entries in the NIC +- * library's PCI table +- */ +-static void bnx2_get_pci_table(struct pci_device_id **table, uint32_t *entries) +-{ +- *table = (struct pci_device_id *)bnx2_pci_tbl; +- *entries = (uint32_t) (sizeof(bnx2_pci_tbl) / sizeof(bnx2_pci_tbl[0])); +-} +- +-/** +- * bnx2_get_ops() - Used to get the NIC library op table +- * @param op - The op table of this NIC library +- */ +-struct nic_ops *bnx2_get_ops() +-{ +- return &bnx2_op; +-} +- +-/******************************************************************************* +- * bnx2 Utility Functions +- ******************************************************************************/ +-/******************************************************************************* +- * Utility Functions Used to read register from the bnx2 device +- ******************************************************************************/ +-static void bnx2_wr32(bnx2_t *bp, __u32 off, __u32 val) +-{ +- *((volatile __u32 *)(bp->reg + off)) = val; +-} +- +-static void bnx2_wr16(bnx2_t *bp, __u32 off, __u16 val) +-{ +- *((volatile __u16 *)(bp->reg + off)) = val; +-} +- +-static __u32 bnx2_rd32(bnx2_t *bp, __u32 off) +-{ +- return *((volatile __u32 *)(bp->reg + off)); +-} +- +-static int bnx2_reg_sync(bnx2_t *bp, __u32 off, __u16 length) +-{ +- return msync(bp->reg + off, length, MS_SYNC); +-} +- +-/** +- * bnx2_get_chip_id() - Used to retrive the chip ID from the nic +- * @param dev - Device used to determin NIC type +- * @return Chip ID read from the MISC ID register +- */ +-static int bnx2_get_chip_id(bnx2_t *bp) +-{ +- return bnx2_rd32(bp, BNX2_MISC_ID); +-} +- +-/** +- * bnx2_uio_verify() +- * +- */ +-static int bnx2_uio_verify(nic_t *nic) +-{ +- char *raw = NULL, *raw_tmp; +- uint32_t raw_size = 0; +- char temp_path[sizeof(cnic_uio_sysfs_name_tempate) + 8]; +- int rc = 0; +- +- /* Build the path to determine uio name */ +- snprintf(temp_path, sizeof(temp_path), +- cnic_uio_sysfs_name_tempate, nic->uio_minor); +- +- rc = capture_file(&raw, &raw_size, temp_path); +- if (rc != 0) +- goto error; +- +- /* sanitize name string by replacing newline with null termination */ +- raw_tmp = raw; +- while (*raw_tmp != '\n') +- raw_tmp++; +- *raw_tmp = '\0'; +- +- if (strncmp(raw, cnic_uio_sysfs_name, sizeof(cnic_uio_sysfs_name)) != +- 0) { +- LOG_ERR(PFX "%s: uio names not equal: " +- "expecting %s got %s from %s", +- nic->log_name, cnic_uio_sysfs_name, raw, temp_path); +- rc = -EIO; +- } +- +- free(raw); +- +- LOG_INFO(PFX "%s: Verified is a cnic_uio device", nic->log_name); +- +-error: +- return rc; +-} +- +-/******************************************************************************* +- * bnx2 Utility Functions to get to the hardware consumer indexes +- ******************************************************************************/ +-static __u16 bnx2_get_rx_msix(bnx2_t *bp) +-{ +- struct status_block_msix *sblk = bp->status_blk.msix; +- __u16 rx_cons; +- +- msync(sblk, sizeof(*sblk), MS_SYNC); +- rx_cons = sblk->status_rx_quick_consumer_index; +- barrier(); +- if ((rx_cons & (MAX_RX_DESC_CNT)) == (MAX_RX_DESC_CNT)) +- rx_cons++; +- +- return rx_cons; +-} +- +-static __u16 bnx2_get_rx_msi(bnx2_t *bp) +-{ +- struct status_block *sblk = bp->status_blk.msi; +- __u16 rx_cons; +- +- msync(sblk, sizeof(*sblk), MS_SYNC); +- rx_cons = BNX2_SBLK_EVEN_IDX(sblk->rx2); +- barrier(); +- if ((rx_cons & (MAX_RX_DESC_CNT)) == (MAX_RX_DESC_CNT)) +- rx_cons++; +- +- return rx_cons; +-} +- +-static __u16 bnx2_get_tx_msix(bnx2_t *bp) +-{ +- struct status_block_msix *sblk = bp->status_blk.msix; +- __u16 tx_cons; +- +- msync(sblk, sizeof(*sblk), MS_SYNC); +- tx_cons = sblk->status_tx_quick_consumer_index; +- barrier(); +- if ((tx_cons & (MAX_TX_DESC_CNT)) == (MAX_TX_DESC_CNT)) +- tx_cons++; +- +- return tx_cons; +-} +- +-static __u16 bnx2_get_tx_msi(bnx2_t *bp) +-{ +- struct status_block *sblk = bp->status_blk.msi; +- __u16 tx_cons; +- +- msync(sblk, sizeof(*sblk), MS_SYNC); +- tx_cons = BNX2_SBLK_EVEN_IDX(sblk->tx2); +- barrier(); +- if ((tx_cons & (MAX_TX_DESC_CNT)) == (MAX_TX_DESC_CNT)) +- tx_cons++; +- +- return tx_cons; +-} +- +-typedef enum { +- CNIC_VLAN_STRIPPING_ENABLED = 1, +- CNIC_VLAN_STRIPPING_DISABLED = 2, +-} CNIC_VLAN_STRIPPING_MODE; +- +-/** +- * bnx2_strip_vlan_enabled() - This will query the device to determine whether +- * VLAN tag stripping is enabled or not +- * @param dev - device to check stripping or not +- * @ return CNIC_VLAN_STRIPPING_ENABLED stripping is enabled +- * CNIC_VLAN_STRIPPING_DISABLED stripping is not enabled +- */ +-static CNIC_VLAN_STRIPPING_MODE bnx2_strip_vlan_enabled(bnx2_t *bp) +-{ +- uint32_t val; +- +- val = bnx2_rd32(bp, BNX2_EMAC_RX_MODE); +- +- if (val & BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG) +- return CNIC_VLAN_STRIPPING_DISABLED; +- else +- return CNIC_VLAN_STRIPPING_ENABLED; +-} +- +-/** +- * bnx2_free() - Used to free a bnx2 structure +- */ +-static void bnx2_free(nic_t *nic) +-{ +- if (nic->priv) +- free(nic->priv); +- nic->priv = NULL; +-} +- +- +-/** +- * bnx2_alloc() - Used to allocate a bnx2 structure +- */ +-static bnx2_t *bnx2_alloc(nic_t *nic) +-{ +- bnx2_t *bp = malloc(sizeof(*bp)); +- if (bp == NULL) { +- LOG_ERR(PFX "%s: Could not allocate bnx2 space", nic->log_name); +- return NULL; +- } +- +- /* Clear out the bnx2 contents */ +- memset(bp, 0, sizeof(*bp)); +- +- bp->bar0_fd = INVALID_FD; +- bp->flags = BNX2_UIO_TX_HAS_SENT; +- +- bp->parent = nic; +- nic->priv = (void *)bp; +- +- return bp; +-} +- +-/** +- * bnx2_open() - This will initialize all the hardware resources +- * @param dev - The struct nic device to open +- * @return 0 on success, on failure a errno will be returned +- */ +-static int bnx2_open(nic_t *nic) +-{ +- bnx2_t *bp; +- struct stat uio_stat; +- int i, rc; +- __u32 val; +- uint32_t tx_cid; +- __u32 msix_vector = 0; +- char sysfs_resc_path[80]; +- +- /* Sanity Check: validate the parameters */ +- if (nic == NULL) { +- LOG_ERR(PFX "bnx2_open(): nic == NULL"); +- return -EINVAL; +- } +- +- if ((nic->priv) != NULL && +- (((bnx2_t *) (nic->priv))->flags & BNX2_OPENED)) { +- return 0; +- } +- +- bp = bnx2_alloc(nic); +- if (bp == NULL) { +- LOG_ERR(PFX "bnx2_open(): Couldn't allocate bp priv struct", +- nic->log_name); +- return -ENOMEM; +- } +- +- while (nic->fd < 0) { +- nic->fd = open(nic->uio_device_name, O_RDWR | O_NONBLOCK); +- if (nic->fd != INVALID_FD) { +- LOG_ERR(PFX +- "%s: uio device has been brought up via pid: " +- "%d on fd: %d", +- nic->uio_device_name, getpid(), nic->fd); +- +- rc = bnx2_uio_verify(nic); +- if (rc != 0) +- continue; +- +- break; +- } else { +- LOG_WARN(PFX "%s: Could not open device: %s, [%s]", +- nic->log_name, nic->uio_device_name, +- strerror(errno)); +- 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); +- errno = -ENODEV; +- goto error_alloc_rx_ring; +- } +- nic->uio_minor = minor(uio_stat.st_rdev); +- +- cnic_get_sysfs_pci_resource_path(nic, 0, sysfs_resc_path, 80); +- bp->bar0_fd = open(sysfs_resc_path, O_RDWR | O_SYNC); +- if (bp->bar0_fd < 0) { +- LOG_ERR(PFX "%s: Could not open %s", nic->log_name, +- sysfs_resc_path); +- errno = -ENODEV; +- goto error_alloc_rx_ring; +- } +- +- /* TODO: hardcoded with the cnic driver */ +- bp->rx_ring_size = 3; +- bp->rx_buffer_size = 0x400; +- +- LOG_DEBUG(PFX "%s: using rx ring size: %d, rx buffer size: %d", +- nic->log_name, bp->rx_ring_size, bp->rx_buffer_size); +- +- /* Determine the number of UIO events that have already occured */ +- rc = detemine_initial_uio_events(nic, &nic->intr_count); +- if (rc != 0) { +- LOG_ERR("Could not determine the number ofinitial UIO events"); +- nic->intr_count = 0; +- } +- +- /* Allocate space for rx ring pointer */ +- bp->rx_ring = malloc(sizeof(struct l2_fhdr *) * bp->rx_ring_size); +- 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); +- +- /* Allocate space for rx pkt ring */ +- bp->rx_pkt_ring = malloc(sizeof(void *) * bp->rx_ring_size); +- 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); +- +- bp->reg = mmap(NULL, 0x12800, PROT_READ | PROT_WRITE, MAP_SHARED, +- bp->bar0_fd, (off_t) 0); +- if (bp->reg == MAP_FAILED) { +- LOG_INFO(PFX "%s: Couldn't mmap registers: %s", +- nic->log_name, strerror(errno)); +- bp->reg = NULL; +- goto error_regs; +- } +- +- msync(bp->reg, 0x12800, MS_SYNC); +- LOG_DEBUG(PFX "Chip ID: %x", bnx2_get_chip_id(bp)); +- +- /* on a 5709 when using MSI-X the status block is at an offset */ +- if (BNX2_CHIP_NUM(bnx2_get_chip_id(bp)) == CHIP_NUM_5709) { +- /* determine if we are using MSI-X */ +- val = bnx2_rd32(bp, BNX2_TSCH_TSS_CFG); +- if (val) { +- /* We are in MSI-X mode */ +- uint32_t base_cid = ((val >> 10) & 0x7ff) << 3; +- msix_vector = (val >> 24) & 0xf; +- +- bp->status_blk_size = (128 * 9); +- +- tx_cid = base_cid + msix_vector - 1; +- bp->flags |= BNX2_UIO_MSIX_ENABLED; +- +- bp->get_tx_cons = bnx2_get_tx_msix; +- bp->get_rx_cons = bnx2_get_rx_msix; +- +- LOG_DEBUG(PFX "%s: tss_cfg: 0x%x tx cid: %d", +- nic->log_name, val, tx_cid); +- +- LOG_INFO(PFX "%s: detected using MSI-X vector: %d", +- nic->log_name, msix_vector); +- } else { +- /* We are not in MSI-X mode */ +- bp->status_blk_size = 64; +- tx_cid = 20; +- +- bp->get_tx_cons = bnx2_get_tx_msi; +- bp->get_rx_cons = bnx2_get_rx_msi; +- } +- } else { +- bp->status_blk_size = 64; +- tx_cid = 20; +- +- bp->get_tx_cons = bnx2_get_tx_msi; +- bp->get_rx_cons = bnx2_get_rx_msi; +- } +- +- bp->sblk_map = mmap(NULL, bp->status_blk_size, +- PROT_READ | PROT_WRITE, MAP_SHARED, +- nic->fd, (off_t) nic->page_size); +- if (bp->sblk_map == MAP_FAILED) { +- LOG_INFO(PFX "%s: Could not mmap status block: %s", +- nic->log_name, strerror(errno)); +- goto error_sblk; +- } +- +- if (bp->flags & BNX2_UIO_MSIX_ENABLED) { +- uint8_t *status_blk = (uint8_t *) bp->sblk_map; +- status_blk += (msix_vector * 128); +- +- bp->status_blk.msix = (struct status_block_msix *)status_blk; +- +- LOG_DEBUG(PFX "%s: msix initial cons: tx:%d rx:%d", +- nic->log_name, +- bp->status_blk.msix->status_tx_quick_consumer_index, +- bp->status_blk.msix->status_rx_quick_consumer_index); +- } else { +- bp->status_blk.msi = (struct status_block *)bp->sblk_map; +- +- LOG_DEBUG(PFX "%s: msi initial tx:%d rx:%d", +- nic->log_name, +- BNX2_SBLK_EVEN_IDX(bp->status_blk.msi->tx2), +- BNX2_SBLK_EVEN_IDX(bp->status_blk.msi->rx2)); +- } +- +- bp->tx_ring = mmap(NULL, 2 * nic->page_size, +- PROT_READ | PROT_WRITE, MAP_SHARED, nic->fd, +- (off_t) 2 * nic->page_size); +- if (bp->tx_ring == MAP_FAILED) { +- LOG_INFO(PFX "%s: Could not mmap tx ring: %s", +- nic->log_name, strerror(errno)); +- bp->tx_ring = NULL; +- goto error_tx_ring; +- } +- +- bp->bufs = mmap(NULL, (bp->rx_ring_size + 1) * bp->rx_buffer_size, +- PROT_READ | PROT_WRITE, +- MAP_SHARED, nic->fd, (off_t) 3 * nic->page_size); +- if (bp->bufs == MAP_FAILED) { +- LOG_INFO(PFX "%s: Could not mmap buffers: %s", +- nic->log_name, strerror(errno)); +- bp->bufs = NULL; +- goto error_bufs; +- } +- +- bp->tx_bidx_io = MB_GET_CID_ADDR(tx_cid) + BNX2_L2CTX_TX_HOST_BIDX; +- bp->tx_bseq_io = MB_GET_CID_ADDR(tx_cid) + BNX2_L2CTX_TX_HOST_BSEQ; +- LOG_INFO(PFX "%s: tx_bidx_io: 0x%x tx_bseq_io: 0x%x", +- nic->log_name, bp->tx_bidx_io, bp->tx_bseq_io); +- +- bp->rx_bidx_io = MB_GET_CID_ADDR(2) + BNX2_L2CTX_HOST_BDIDX; +- bp->rx_bseq_io = MB_GET_CID_ADDR(2) + BNX2_L2CTX_HOST_BSEQ; +- +- bp->tx_cons = 0; +- bp->tx_prod = 0; +- bp->tx_pkt = bp->bufs; +- +- bp->rx_index = 0; +- bp->rx_cons = 0; +- bp->rx_prod = bp->rx_ring_size; +- bp->rx_bseq = bp->rx_prod * bp->rx_buffer_size; +- bnx2_wr16(bp, bp->rx_bidx_io, bp->rx_prod); +- bnx2_wr32(bp, bp->rx_bseq_io, bp->rx_bseq); +- +- bnx2_reg_sync(bp, bp->rx_bidx_io, sizeof(__u16)); +- bnx2_reg_sync(bp, bp->rx_bseq_io, sizeof(__u32)); +- +- for (i = 0; i < bp->rx_ring_size; i++) { +- void *ptr = bp->bufs + (bp->rx_buffer_size * (i + 1)); +- +- bp->rx_ring[i] = (struct l2_fhdr *)ptr; +- bp->rx_pkt_ring[i] = ptr + sizeof(struct l2_fhdr) + 2; +- } +- +- /* Read the MAC address used for the iSCSI interface */ +- val = bnx2_rd32(bp, BNX2_EMAC_MAC_MATCH4); +- nic->mac_addr[0] = (__u8) (val >> 8); +- nic->mac_addr[1] = (__u8) val; +- +- val = bnx2_rd32(bp, BNX2_EMAC_MAC_MATCH5); +- nic->mac_addr[2] = (__u8) (val >> 24); +- nic->mac_addr[3] = (__u8) (val >> 16); +- nic->mac_addr[4] = (__u8) (val >> 8); +- nic->mac_addr[5] = (__u8) val; +- +- LOG_INFO(PFX "%s: Using mac address: %2x:%2x:%2x:%2x:%2x:%2x", +- nic->log_name, +- nic->mac_addr[0], nic->mac_addr[1], nic->mac_addr[2], +- nic->mac_addr[3], nic->mac_addr[4], nic->mac_addr[5]); +- +- /* Determine if Hardware VLAN tag stripping is enabled or not */ +- if (CNIC_VLAN_STRIPPING_ENABLED == bnx2_strip_vlan_enabled(bp)) +- nic->flags |= NIC_VLAN_STRIP_ENABLED; +- +- /* Prepare the multicast addresses */ +- val = 4 | BNX2_RPM_SORT_USER2_BC_EN | BNX2_RPM_SORT_USER2_MC_EN; +- if (BNX2_CHIP_NUM(bnx2_get_chip_id(bp)) != CHIP_NUM_5709) +- val |= BNX2_RPM_SORT_USER2_PROM_VLAN; +- +- bnx2_wr32(bp, BNX2_RPM_SORT_USER2, 0x0); +- bnx2_wr32(bp, BNX2_RPM_SORT_USER2, val); +- bnx2_wr32(bp, BNX2_RPM_SORT_USER2, val | BNX2_RPM_SORT_USER2_ENA); +- +- rc = enable_multicast(nic); +- if (rc != 0) { +- errno = rc; +- goto error_bufs; +- } +- msync(bp->reg, 0x12800, MS_SYNC); +- LOG_INFO("%s: bnx2 uio initialized", nic->log_name); +- +- bp->flags |= BNX2_OPENED; +- +- return 0; +- +-error_bufs: +- munmap(bp->tx_ring, 2 * nic->page_size); +- +-error_tx_ring: +- munmap(bp->status_blk.msi, bp->status_blk_size); +- +-error_sblk: +- munmap(bp->reg, 0x12800); +- +-error_regs: +- munlock(bp->rx_pkt_ring, sizeof(void *) * bp->rx_ring_size); +- free(bp->rx_pkt_ring); +- bp->rx_pkt_ring = NULL; +- +-error_alloc_rx_pkt_ring: +- munlock(bp->rx_ring, sizeof(struct l2_fhdr *) * bp->rx_ring_size); +- free(bp->rx_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; +-} +- +-/** +- * bnx2_uio_close_resources() - Used to free resource for the bnx2 NIC +- * @param nic - NIC device to free resource +- * @param graceful - whether to wait to close gracefully +- * @return 0 on success, <0 on failure +- */ +-static int bnx2_uio_close_resources(nic_t *nic, NIC_SHUTDOWN_T graceful) +-{ +- bnx2_t *bp = (bnx2_t *) nic->priv; +- int rc = 0; +- +- /* Remove the multicast addresses if added */ +- if ((nic->flags & NIC_ADDED_MULICAST) && +- (graceful == ALLOW_GRACEFUL_SHUTDOWN)) +- disable_multicast(nic); +- +- /* Check if there is an assoicated bnx2 device */ +- if (bp == NULL) { +- LOG_WARN(PFX "%s: when closing resources there is " +- "no assoicated bnx2", nic->log_name); +- return -EIO; +- } +- +- /* Clean up allocated memory */ +- if (bp->rx_ring != NULL) { +- free(bp->rx_ring); +- bp->rx_ring = NULL; +- } +- +- if (bp->rx_pkt_ring != NULL) { +- free(bp->rx_pkt_ring); +- bp->rx_pkt_ring = NULL; +- } +- +- /* Clean up mapped registers */ +- if (bp->bufs != NULL) { +- rc = munmap(bp->bufs, +- (bp->rx_ring_size + 1) * bp->rx_buffer_size); +- if (rc != 0) +- LOG_WARN(PFX "%s: Couldn't unmap bufs", nic->log_name); +- bp->bufs = NULL; +- } +- +- if (bp->tx_ring != NULL) { +- rc = munmap(bp->tx_ring, 2 * nic->page_size); +- if (rc != 0) +- LOG_WARN(PFX "%s: Couldn't unmap tx_rings", +- nic->log_name); +- bp->tx_ring = NULL; +- } +- +- if (bp->status_blk.msix != NULL || bp->status_blk.msi != NULL) { +- rc = munmap(bp->sblk_map, bp->status_blk_size); +- if (rc != 0) +- LOG_WARN(PFX "%s: Couldn't unmap status block", +- nic->log_name); +- bp->sblk_map = NULL; +- +- bp->status_blk.msix = NULL; +- bp->status_blk.msi = NULL; +- } +- +- if (bp->reg != NULL) { +- rc = munmap(bp->reg, 0x12800); +- if (rc != 0) +- LOG_WARN(PFX "%s: Couldn't unmap regs", nic->log_name); +- bp->reg = NULL; +- } +- +- if (bp->bar0_fd != INVALID_FD) { +- close(bp->bar0_fd); +- bp->bar0_fd = INVALID_FD; +- } +- +- if (nic->fd != INVALID_FD) { +- rc = close(nic->fd); +- if (rc != 0) { +- LOG_WARN(PFX +- "%s: Couldn't close uio file descriptor: %d", +- nic->log_name, nic->fd); +- } else { +- LOG_DEBUG(PFX "%s: Closed uio file descriptor: %d", +- nic->log_name, nic->fd); +- } +- +- nic->fd = INVALID_FD; +- } else { +- LOG_WARN(PFX "%s: Invalid uio file descriptor: %d", +- nic->log_name, nic->fd); +- } +- +- LOG_INFO(PFX "%s: Closed all resources", nic->log_name); +- +- return 0; +-} +- +-/** +- * bnx2_close() - Used to close the NIC device +- * @param nic - NIC device to close +- * @param graceful - whether to wait to close gracefully +- * @return 0 if successful, <0 if there is an error +- */ +-static int bnx2_close(nic_t *nic, NIC_SHUTDOWN_T graceful) +-{ +- /* Sanity Check: validate the parameters */ +- if (nic == NULL) { +- LOG_ERR(PFX "bnx2_close(): nic == NULL"); +- return -EINVAL; +- } +- +- LOG_INFO(PFX "Closing NIC device: %s", nic->log_name); +- +- bnx2_uio_close_resources(nic, graceful); +- bnx2_free(nic); +- +- return 0; +-} +- +-static void bnx2_prepare_xmit_packet(nic_t *nic, +- nic_interface_t *nic_iface, +- struct packet *pkt) +-{ +- bnx2_t *bp = (bnx2_t *) nic->priv; +- struct uip_vlan_eth_hdr *eth_vlan = (struct uip_vlan_eth_hdr *)pkt->buf; +- struct uip_eth_hdr *eth = (struct uip_eth_hdr *)bp->tx_pkt; +- +- if (eth_vlan->tpid == htons(UIP_ETHTYPE_8021Q)) { +- memcpy(bp->tx_pkt, pkt->buf, sizeof(struct uip_eth_hdr)); +- eth->type = eth_vlan->type; +- pkt->buf_size -= (sizeof(struct uip_vlan_eth_hdr) - +- sizeof(struct uip_eth_hdr)); +- memcpy(bp->tx_pkt + sizeof(struct uip_eth_hdr), +- pkt->buf + sizeof(struct uip_vlan_eth_hdr), +- pkt->buf_size - sizeof(struct uip_eth_hdr)); +- } else +- memcpy(bp->tx_pkt, pkt->buf, pkt->buf_size); +- +- msync(bp->tx_pkt, pkt->buf_size, MS_SYNC); +-} +- +-/** +- * bnx2_get_tx_pkt() - This function is used to a TX packet from the NIC +- * @param nic - The NIC device to send the packet +- * +- */ +-void *bnx2_get_tx_pkt(nic_t *nic) +-{ +- bnx2_t *bp = (bnx2_t *) nic->priv; +- return bp->tx_pkt; +-} +- +-/** +- * bnx2_start_xmit() - This function is used to send a packet of data +- * @param nic - The NIC device to send the packet +- * @param len - the length of the TX packet +- * +- */ +-void bnx2_start_xmit(nic_t *nic, size_t len, u16_t vlan_id) +-{ +- bnx2_t *bp = (bnx2_t *) nic->priv; +- uint16_t ring_prod; +- struct tx_bd *txbd; +- struct rx_bd *rxbd; +- rxbd = (struct rx_bd *)(((__u8 *) bp->tx_ring) + nic->page_size); +- +- if ((rxbd->rx_bd_haddr_hi == 0) && (rxbd->rx_bd_haddr_lo == 0)) { +- LOG_PACKET(PFX "%s: trying to transmit when device is closed", +- nic->log_name); +- pthread_mutex_unlock(&nic->xmit_mutex); +- return; +- } +- +- ring_prod = TX_RING_IDX(bp->tx_prod); +- txbd = &bp->tx_ring[ring_prod]; +- +- txbd->tx_bd_mss_nbytes = len; +- +- if (vlan_id) { +- txbd->tx_bd_vlan_tag_flags = (vlan_id << 16) | +- TX_BD_FLAGS_VLAN_TAG | TX_BD_FLAGS_END | TX_BD_FLAGS_START; +- } else +- txbd->tx_bd_vlan_tag_flags = TX_BD_FLAGS_END | +- TX_BD_FLAGS_START; +- +- bp->tx_bseq += len; +- bp->tx_prod = NEXT_TX_BD(bp->tx_prod); +- +- bnx2_wr16(bp, bp->tx_bidx_io, bp->tx_prod); +- bnx2_wr32(bp, bp->tx_bseq_io, bp->tx_bseq); +- +- bnx2_reg_sync(bp, bp->tx_bidx_io, sizeof(__u16)); +- bnx2_reg_sync(bp, bp->tx_bseq_io, sizeof(__u32)); +- +- LOG_PACKET(PFX "%s: sent %d bytes using dev->tx_prod: %d", +- nic->log_name, len, bp->tx_prod); +-} +- +-/** +- * bnx2_write() - Used to write the data to the hardware +- * @param nic - NIC hardware to read from +- * @param pkt - The packet which will hold the data to be sent on the wire +- * @return 0 if successful, <0 if failed +- */ +-int bnx2_write(nic_t *nic, nic_interface_t *nic_iface, packet_t *pkt) +-{ +- bnx2_t *bp; +- struct uip_stack *uip; +- +- /* Sanity Check: validate the parameters */ +- if (nic == NULL || nic_iface == NULL || pkt == NULL) { +- LOG_ERR(PFX "%s: bnx2_write() nic == 0x%p || " +- " nic_iface == 0x%p || " +- " 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", +- nic->log_name); +- return -EINVAL; +- } +- +- if (pthread_mutex_trylock(&nic->xmit_mutex) != 0) { +- 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_priority << 12) | +- nic_iface->vlan_id); +- +- /* bump the bnx2 dev send statistics */ +- nic->stats.tx.packets++; +- nic->stats.tx.bytes += uip->uip_len; +- +- 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; +-} +- +-/** +- * bnx2_read() - Used to read the data from the hardware +- * @param nic - NIC hardware to read from +- * @param pkt - The packet which will hold the data +- * @return 0 if successful, <0 if failed +- */ +-static int bnx2_read(nic_t *nic, packet_t *pkt) +-{ +- bnx2_t *bp; +- int rc = 0; +- uint16_t hw_cons, sw_cons; +- +- /* Sanity Check: validate the parameters */ +- if (unlikely(nic == NULL || pkt == NULL)) { +- LOG_ERR(PFX "%s: bnx2_write() nic == 0x%p || " +- " pkt == 0x%x", nic, pkt); +- return -EINVAL; +- } +- bp = (bnx2_t *)nic->priv; +- +- hw_cons = bp->get_rx_cons(bp); +- sw_cons = bp->rx_cons; +- +- if (sw_cons != hw_cons) { +- uint8_t rx_index = bp->rx_index % 3; +- struct l2_fhdr *rx_hdr = bp->rx_ring[rx_index]; +- void *rx_pkt = bp->rx_pkt_ring[rx_index]; +- int len; +- uint16_t errors; +- +- 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); +- len = ((rx_hdr->l2_fhdr_vtag_len & 0xffff0000) >> 16) - 4; +- +- if (unlikely((errors & (L2_FHDR_ERRORS_BAD_CRC | +- L2_FHDR_ERRORS_PHY_DECODE | +- L2_FHDR_ERRORS_ALIGNMENT | +- L2_FHDR_ERRORS_TOO_SHORT | +- L2_FHDR_ERRORS_GIANT_FRAME)) || +- (len <= 0) || +- (len > (bp->rx_buffer_size - +- (sizeof(struct l2_fhdr) + 2))) || +- (len > pkt->max_buf_size))) { +- /* One of the fields in the BD is bad */ +- uint16_t status = ((rx_hdr->l2_fhdr_status & +- 0x0000ffff)); +- +- LOG_ERR(PFX "%s: Recv error: 0x%x status: 0x%x " +- "len: %d", nic->log_name, errors, status, len); +- +- if ((len < (bp->rx_buffer_size - +- (sizeof(struct l2_fhdr) + 2))) && +- (len < pkt->max_buf_size)) +- dump_packet_to_log(pkt->nic_iface, rx_pkt, len); +- } else { +- if (len < (bp->rx_buffer_size - +- (sizeof(struct l2_fhdr) + 2))) { +- msync(rx_pkt, len, MS_SYNC); +- /* Copy the data */ +- memcpy(pkt->buf, rx_pkt, len); +- pkt->buf_size = len; +- +- /* Properly set the packet flags */ +- /* check if there is VLAN tagging on the +- * packet */ +- if (rx_hdr->l2_fhdr_status & +- L2_FHDR_STATUS_VLAN_TAG) { +- pkt->vlan_tag = +- rx_hdr->l2_fhdr_vtag_len & 0x0FFF; +- pkt->flags |= VLAN_TAGGED; +- } else { +- pkt->vlan_tag = 0; +- } +- +- rc = 1; +- +- 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 */ +- LOG_ERR(PFX "%s: invalid packet length %d " +- "receive ", nic->log_name, len); +- } +- } +- +- bp->rx_index++; +- sw_cons = NEXT_RX_BD(sw_cons); +- bp->rx_prod = NEXT_RX_BD(bp->rx_prod); +- bp->rx_bseq += 0x400; +- +- bp->rx_cons = sw_cons; +- bnx2_wr16(bp, bp->rx_bidx_io, bp->rx_prod); +- bnx2_wr32(bp, bp->rx_bseq_io, bp->rx_bseq); +- +- bnx2_reg_sync(bp, bp->rx_bidx_io, sizeof(__u16)); +- bnx2_reg_sync(bp, bp->rx_bseq_io, sizeof(__u32)); +- +- /* bump the bnx2 dev recv statistics */ +- nic->stats.rx.packets++; +- nic->stats.rx.bytes += pkt->buf_size; +- } +- +- return rc; +-} +- +-/******************************************************************************* +- * Clearing TX interrupts +- ******************************************************************************/ +-/** +- * bnx2_clear_tx_intr() - This routine is called when a TX interrupt occurs +- * @param nic - the nic the interrupt occured on +- * @return 0 on success +- */ +-static int bnx2_clear_tx_intr(nic_t *nic) +-{ +- 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_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 +- * case is when stack will send an ARP packet out before sending the +- * intended packet */ +- if (nic->tx_packet_queue != NULL) { +- packet_t *pkt; +- +- 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 +- * the hardware */ +- if (pkt != NULL) { +- 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_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; +- } +- } +- +- pthread_mutex_unlock(&nic->xmit_mutex); +- +- return 0; +-} +- +-/******************************************************************************* +- * bnx2 NIC op's table +- ******************************************************************************/ +-struct nic_ops bnx2_op = { +- .description = "bnx2", +- .open = bnx2_open, +- .close = bnx2_close, +- .write = bnx2_write, +- .get_tx_pkt = bnx2_get_tx_pkt, +- .start_xmit = bnx2_start_xmit, +- .read = bnx2_read, +- .clear_tx_intr = bnx2_clear_tx_intr, +- .handle_iscsi_path_req = cnic_handle_iscsi_path_req, +- +- .lib_ops = { +- .get_library_name = bnx2_get_library_name, +- .get_pci_table = bnx2_get_pci_table, +- .get_library_version = bnx2_get_library_version, +- .get_build_date = bnx2_get_build_date, +- .get_transport_name = bnx2_get_transport_name, +- .get_uio_name = bnx2_get_uio_name, +- }, +-}; +diff --git a/iscsiuio/src/unix/libs/bnx2.h b/iscsiuio/src/unix/libs/bnx2.h +deleted file mode 100644 +index 3ec9437..0000000 +--- a/iscsiuio/src/unix/libs/bnx2.h ++++ /dev/null +@@ -1,304 +0,0 @@ +-/* +- * Copyright (c) 2009-2011, Broadcom Corporation +- * Copyright (c) 2014, QLogic Corporation +- * +- * Written by: Benjamin Li (benli@broadcom.com) +- * +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. All advertising materials mentioning features or use of this software +- * must display the following acknowledgement: +- * This product includes software developed by Adam Dunkels. +- * 4. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * bnx2.h - bnx2 user space driver +- * +- */ +-#ifndef __BNX2_H__ +-#define __BNX2_H__ +- +-#include "nic.h" +- +-/****************************************************************************** +- * Default BNX2 values +- ******************************************************************************/ +-#define DEFAULT_NUM_RXBD 3 +-#define DEFAULT_RX_LEN 0x400 +- +-/****************************************************************************** +- * BNX2 Hardware structures +- ******************************************************************************/ +-/* status_block definition for MSI */ +-struct status_block { +- volatile __u32 status_attn_bits; +- volatile __u32 status_attn_bits_ack; +- volatile __u32 tx0; +- volatile __u32 tx2; +- volatile __u32 rx0; +- volatile __u32 rx2; +- volatile __u32 rx4; +- volatile __u32 rx6; +- volatile __u32 rx8; +- volatile __u32 rx10; +- volatile __u32 rx12; +- volatile __u32 rx14; +- volatile __u32 cmd; +- volatile __u32 idx; +-}; +- +-/* status_block definition for MSI-X */ +-struct status_block_msix { +-#if 0 +-#if defined(__BIG_ENDIAN) +- __u16 status_tx_quick_consumer_index; +- __u16 status_rx_quick_consumer_index; +- __u16 status_completion_producer_index; +- __u16 status_cmd_consumer_index; +- __u32 status_unused; +- __u16 status_idx; +- __u8 status_unused2; +- __u8 status_blk_num; +-#elif defined(__LITTLE_ENDIAN) +- __u16 status_rx_quick_consumer_index; +- __u16 status_tx_quick_consumer_index; +- __u16 status_cmd_consumer_index; +- __u16 status_completion_producer_index; +- __u32 status_unused; +- __u8 status_blk_num; +- __u8 status_unused2; +- __u16 status_idx; +-#endif +-#endif +- __u16 status_rx_quick_consumer_index; +- __u16 status_tx_quick_consumer_index; +- __u16 status_cmd_consumer_index; +- __u16 status_completion_producer_index; +- __u32 status_unused; +- __u8 status_blk_num; +- __u8 status_unused2; +- __u16 status_idx; +-}; +- +-/* TX Buffer descriptor */ +-struct tx_bd { +- __u32 tx_bd_haddr_hi; +- __u32 tx_bd_haddr_lo; +- __u32 tx_bd_mss_nbytes; +- __u32 tx_bd_vlan_tag_flags; +-#define TX_BD_FLAGS_VLAN_TAG (1<<3) +-#define TX_BD_FLAGS_END (1<<6) +-#define TX_BD_FLAGS_START (1<<7) +-}; +- +-/* RX Buffer descriptor */ +-struct rx_bd { +- __u32 rx_bd_haddr_hi; +- __u32 rx_bd_haddr_lo; +- +- __u32 rx_bd_len; +- __u32 rx_bd_flags; +-#define RX_BD_FLAGS_END (1<<2) +-#define RX_BD_FLAGS_START (1<<3) +- +-}; +- +-/* This is the RX L2 Frame header */ +-struct l2_fhdr { +- __u32 l2_fhdr_status; +-#define L2_FHDR_ERRORS_BAD_CRC (1<<17) +-#define L2_FHDR_ERRORS_PHY_DECODE (1<<18) +-#define L2_FHDR_ERRORS_ALIGNMENT (1<<19) +-#define L2_FHDR_ERRORS_TOO_SHORT (1<<20) +-#define L2_FHDR_ERRORS_GIANT_FRAME (1<<21) +-#define L2_FHDR_ERRORS_TCP_XSUM (1<<28) +-#define L2_FHDR_ERRORS_UDP_XSUM (1<<31) +- +-#define L2_FHDR_STATUS_UDP_DATAGRAM (1<<15) +-#define L2_FHDR_STATUS_TCP_DATAGRAM (1<<14) +-#define L2_FHDR_STATUS_IP_DATAGRAM (1<<13) +-#define L2_FHDR_STATUS_LLC_SNAP (1<<7) +-#define L2_FHDR_STATUS_VLAN_TAG (1<<6) +- +- __u32 l2_fhdr_hash; +- +- __u32 l2_fhdr_vtag_len; +- __u32 l2_fhdr_xsum; +-}; +- +-/****************************************************************************** +- * BNX2 Registers Defitions/Values +- ******************************************************************************/ +-#define BNX2_MISC_ID 0x00000808 +-#define BNX2_EMAC_MAC_MATCH4 0x00001420 +-#define BNX2_EMAC_MAC_MATCH5 0x00001424 +- +-#define BNX2_EMAC_RX_MODE 0x000014c8 +-#define BNX2_EMAC_RX_MODE_RESET (1L<<0) +-#define BNX2_EMAC_RX_MODE_FLOW_EN (1L<<2) +-#define BNX2_EMAC_RX_MODE_KEEP_MAC_CONTROL (1L<<3) +-#define BNX2_EMAC_RX_MODE_KEEP_PAUSE (1L<<4) +-#define BNX2_EMAC_RX_MODE_ACCEPT_OVERSIZE (1L<<5) +-#define BNX2_EMAC_RX_MODE_ACCEPT_RUNTS (1L<<6) +-#define BNX2_EMAC_RX_MODE_LLC_CHK (1L<<7) +-#define BNX2_EMAC_RX_MODE_PROMISCUOUS (1L<<8) +-#define BNX2_EMAC_RX_MODE_NO_CRC_CHK (1L<<9) +-#define BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG (1L<<10) +-#define BNX2_EMAC_RX_MODE_FILT_BROADCAST (1L<<11) +-#define BNX2_EMAC_RX_MODE_SORT_MODE (1L<<12) +- +-#define BNX2_RPM_SORT_USER2 0x00001828 +-#define BNX2_RPM_SORT_USER2_PM_EN (0xffffL<<0) +-#define BNX2_RPM_SORT_USER2_BC_EN (1L<<16) +-#define BNX2_RPM_SORT_USER2_MC_EN (1L<<17) +-#define BNX2_RPM_SORT_USER2_MC_HSH_EN (1L<<18) +-#define BNX2_RPM_SORT_USER2_PROM_EN (1L<<19) +-#define BNX2_RPM_SORT_USER2_VLAN_EN (0xfL<<20) +-#define BNX2_RPM_SORT_USER2_PROM_VLAN (1L<<24) +-#define BNX2_RPM_SORT_USER2_ENA (1L<<31) +- +-/* +- * tsch_reg definition +- * offset: 0x4c00 +- */ +-#define BNX2_TSCH_TSS_CFG 0x00004c1c +-#define BNX2_TSCH_TSS_CFG_TSS_START_CID (0x7ffL<<8) +-#define BNX2_TSCH_TSS_CFG_NUM_OF_TSS_CON (0xfL<<24) +-#define CNIC_UIO_INVALID_FD -1 +- +-#define BNX2_L2CTX_TX_HOST_BIDX 0x00000088 +-#define BNX2_L2CTX_TX_HOST_BSEQ 0x00000090 +- +-#define BNX2_L2CTX_HOST_BDIDX 0x00000004 +-#define BNX2_L2CTX_HOST_BSEQ 0x00000008 +- +-/* Used to determin the CHIP ID */ +-/* chip num:16-31, rev:12-15, metal:4-11, bond_id:0-3 */ +-#define BNX2_CHIP_NUM(bp) ((bp) & 0xffff0000) +-#define CHIP_NUM_5706 0x57060000 +-#define CHIP_NUM_5708 0x57080000 +-#define CHIP_NUM_5709 0x57090000 +- +-#define CHIP_REV(bp) ((bp) & 0x0000f000) +-#define CHIP_REV_Ax 0x00000000 +-#define CHIP_REV_Bx 0x00001000 +-#define CHIP_REV_Cx 0x00002000 +- +-#define CHIP_METAL(bp) ((bp) & 0x00000ff0) +-#define CHIP_BONDING(bp) ((bp) & 0x0000000f) +- +-#define CHIP_ID(bp) ((bp) & 0xfffffff0) +-#define CHIP_ID_5706_A0 0x57060000 +-#define CHIP_ID_5706_A1 0x57060010 +-#define CHIP_ID_5706_A2 0x57060020 +-#define CHIP_ID_5708_A0 0x57080000 +-#define CHIP_ID_5708_B0 0x57081000 +-#define CHIP_ID_5708_B1 0x57081010 +-#define CHIP_ID_5709_A0 0x57090000 +-#define CHIP_ID_5709_A1 0x57090010 +- +-#define CHIP_BOND_ID(bp) ((bp) & 0xf) +- +-#define BNX2_SBLK_EVEN_IDX(x) (((x) & 0xffff0000) >> 16) +- +-#define TX_DESC_CNT (4096 / sizeof(struct tx_bd)) +-#define MAX_TX_DESC_CNT (TX_DESC_CNT - 1) +- +-#define NEXT_TX_BD(x) ((((x) & (MAX_TX_DESC_CNT - 1)) == \ +- (MAX_TX_DESC_CNT - 1)) ? \ +- (x) + 2 : (x) + 1) +- +-#define TX_RING_IDX(x) ((x) & MAX_TX_DESC_CNT) +- +-#define RX_DESC_CNT (4096 / sizeof(struct rx_bd)) +-#define MAX_RX_DESC_CNT (RX_DESC_CNT - 1) +- +-#define NEXT_RX_BD(x) ((((x) & (MAX_RX_DESC_CNT - 1)) == \ +- (MAX_RX_DESC_CNT - 1)) ? \ +- (x) + 2 : (x) + 1) +- +-#define MB_KERNEL_CTX_SHIFT 8 +-#define MB_KERNEL_CTX_SIZE (1 << MB_KERNEL_CTX_SHIFT) +-#define MB_KERNEL_CTX_MASK (MB_KERNEL_CTX_SIZE - 1) +-#define MB_GET_CID_ADDR(_cid) (0x10000 + ((_cid) << MB_KERNEL_CTX_SHIFT)) +- +-typedef struct bnx2 { +- nic_t *parent; +- +- uint16_t flags; +-#define BNX2_UIO_MSIX_ENABLED 0x0001 +-#define BNX2_UIO_TX_HAS_SENT 0x0002 +-#define BNX2_OPENED 0x0004 +- +- int bar0_fd; +- void *reg; /* Pointer to the mapped registers */ +- +- __u32 tx_bidx_io; +- __u32 tx_bseq_io; +- +- __u16 tx_prod; +- __u16 tx_cons; +- __u32 tx_bseq; +- +- __u32 rx_bidx_io; +- __u32 rx_bseq_io; +- +- __u16 rx_prod; +- __u16 rx_cons; +- __u32 rx_bseq; +- +- /* RX ring parameters */ +- uint32_t rx_ring_size; +- uint32_t rx_buffer_size; +- +- void *bufs; /* Pointer to the mapped buffer space */ +- +- /* Hardware Status Block locations */ +- void *sblk_map; +- union { +- struct status_block *msi; +- struct status_block_msix *msix; +- } status_blk; +- size_t status_blk_size; +- +- __u16(*get_rx_cons) (struct bnx2 *); +- __u16(*get_tx_cons) (struct bnx2 *); +- +- uint16_t rx_index; +- struct l2_fhdr **rx_ring; +- void **rx_pkt_ring; +- +- struct tx_bd *tx_ring; +- void *tx_pkt; +- +- struct l2_fhdr rcv_l2_fhdr; +- __u8 rcv_buf[1500 + 2]; +- __u32 rcv_size; +-} bnx2_t; +- +-/****************************************************************************** +- * bnx2 Function Declarations +- ******************************************************************************/ +-struct nic_ops *bnx2_get_ops(); +-#endif /* __BNX2_H__ */ +diff --git a/iscsiuio/src/unix/libs/bnx2x.c b/iscsiuio/src/unix/libs/bnx2x.c +deleted file mode 100644 +index 7481e86..0000000 +--- a/iscsiuio/src/unix/libs/bnx2x.c ++++ /dev/null +@@ -1,1676 +0,0 @@ +-/* +- * Copyright (c) 2009-2011, Broadcom Corporation +- * Copyright (c) 2014, QLogic Corporation +- * +- * Written by: Benjamin Li (benli@broadcom.com) +- * +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. All advertising materials mentioning features or use of this software +- * must display the following acknowledgement: +- * This product includes software developed by Adam Dunkels. +- * 4. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * bnx2x.c - bnx2x user space driver +- * +- */ +- +-/* include nic.h before linux/ethtool.h to avoid redefinitions of +- * eth structs +-*/ +-#include "nic.h" +-#include +-#include +-#include +-#include +-#include /* Needed for linux/ethtool.h on RHEL 5.x */ +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include "config.h" +- +-#include "build_date.h" +-#include "bnx2x.h" +-#include "cnic.h" +-#include "logger.h" +-#include "nic_id.h" +-#include "nic_utils.h" +-#include "options.h" +- +-#define PFX "bnx2x " +- +-/* Foward struct declarations */ +-struct nic_ops bnx2x_op; +- +-/******************************************************************************* +- * NIC Library Strings +- ******************************************************************************/ +-static const char library_name[] = "bnx2x"; +-static const char library_version[] = PACKAGE_VERSION; +-static const char library_uio_name[] = "bnx2x_cnic"; +- +-/* The name that should be returned from /sys/class/uio/uio0/name */ +-static const char cnic_uio_sysfs_name_tempate[] = "/sys/class/uio/uio%i/name"; +-static const char bnx2x_uio_sysfs_name[] = "bnx2x_cnic"; +- +-/******************************************************************************* +- * String constants used to display human readable adapter name +- ******************************************************************************/ +-static const char brcm_57710[] = "QLogic NetXtreme II BCM57710 10-Gigabit"; +-static const char brcm_57711[] = "QLogic NetXtreme II BCM57711 10-Gigabit"; +-static const char brcm_57711e[] = "QLogic NetXtreme II BCM57711E 10-Gigabit"; +-static const char brcm_57712[] = "QLogic NetXtreme II BCM57712 10-Gigabit"; +-static const char brcm_57712_MF[] = "QLogic NetXtreme II BCM57712 MF " +- "10-Gigabit"; +-static const char brcm_57712_VF[] = "QLogic NetXtreme II BCM57712 VF " +- "10-Gigabit"; +-static const char brcm_57713[] = "QLogic NetXtreme II BCM57713 10-Gigabit"; +-static const char brcm_57713e[] = "QLogic NetXtreme II BCM57713E 10-Gigabit"; +-static const char brcm_57800[] = "QLogic NetXtreme II BCM57800 10-Gigabit"; +-static const char brcm_57800_MF[] = "QLogic NetXtreme II BCM57800 MF " +- "10-Gigabit"; +-static const char brcm_57800_VF[] = "QLogic NetXtreme II BCM57800 VF " +- "10-Gigabit"; +-static const char brcm_57810[] = "QLogic NetXtreme II BCM57810 10-Gigabit"; +-static const char brcm_57810_MF[] = "QLogic NetXtreme II BCM57810 MF " +- "10-Gigabit"; +-static const char brcm_57810_VF[] = "QLogic NetXtreme II BCM57810 VF " +- "10-Gigabit"; +-static const char brcm_57811[] = "QLogic NetXtreme II BCM57811 10-Gigabit"; +-static const char brcm_57811_MF[] = "QLogic NetXtreme II BCM57811 MF " +- "10-Gigabit"; +-static const char brcm_57811_VF[] = "QLogic NetXtreme II BCM57811 VF " +- "10-Gigabit"; +-static const char brcm_57840[] = "QLogic NetXtreme II BCM57840 10-Gigabit"; +-static const char brcm_57840_MF[] = "QLogic NetXtreme II BCM57840 MF " +- "10-Gigabit"; +-static const char brcm_57840_VF[] = "QLogic NetXtreme II BCM57840 VF " +- "10-Gigabit"; +-static const char brcm_57840_4_10[] = "QLogic NetXtreme II BCM57840 4x" +- "10-Gigabit"; +-static const char brcm_57840_2_20[] = "QLogic NetXtreme II BCM57840 2x" +- "20-Gigabit"; +- +-/******************************************************************************* +- * PCI ID constants +- ******************************************************************************/ +-#define PCI_VENDOR_ID_BROADCOM 0x14e4 +-#define PCI_VENDOR_ID_QLOGIC 0x1077 +-#define PCI_DEVICE_ID_NX2_57710 0x164e +-#define PCI_DEVICE_ID_NX2_57711 0x164f +-#define PCI_DEVICE_ID_NX2_57711E 0x1650 +-#define PCI_DEVICE_ID_NX2_57712 0x1662 +-#define PCI_DEVICE_ID_NX2_57712_MF 0x1663 +-#define PCI_DEVICE_ID_NX2_57712_VF 0x166f +-#define PCI_DEVICE_ID_NX2_57713 0x1651 +-#define PCI_DEVICE_ID_NX2_57713E 0x1652 +-#define PCI_DEVICE_ID_NX2_57800 0x168a +-#define PCI_DEVICE_ID_NX2_57800_MF 0x16a5 +-#define PCI_DEVICE_ID_NX2_57800_VF 0x16a9 +-#define PCI_DEVICE_ID_NX2_57810 0x168e +-#define PCI_DEVICE_ID_NX2_57810_MF 0x16ae +-#define PCI_DEVICE_ID_NX2_57810_VF 0x16af +-#define PCI_DEVICE_ID_NX2_57811 0x163d +-#define PCI_DEVICE_ID_NX2_57811_MF 0x163e +-#define PCI_DEVICE_ID_NX2_57811_VF 0x163f +-#define PCI_DEVICE_ID_NX2_57840_OBSOLETE 0x168d +-#define PCI_DEVICE_ID_NX2_57840_MF_OBSOLETE 0x16ab +-#define PCI_DEVICE_ID_NX2_57840_4_10 0x16a1 +-#define PCI_DEVICE_ID_NX2_57840_2_20 0x16a2 +-#define PCI_DEVICE_ID_NX2_57840_MF 0x16a4 +-#define PCI_DEVICE_ID_NX2_57840_VF 0x16ad +-#define PCI_ANY_ID (~0) +- +-/* This is the table used to match PCI vendor and device ID's to the +- * human readable string names of the devices */ +-static const struct pci_device_id bnx2x_pci_tbl[] = { +- {PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_57710, +- PCI_ANY_ID, PCI_ANY_ID, brcm_57710}, +- {PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_57711, +- PCI_ANY_ID, PCI_ANY_ID, brcm_57711}, +- {PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_57711E, +- PCI_ANY_ID, PCI_ANY_ID, brcm_57711e}, +- {PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_57712, +- PCI_ANY_ID, PCI_ANY_ID, brcm_57712}, +- {PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_57712_MF, +- PCI_ANY_ID, PCI_ANY_ID, brcm_57712_MF}, +- {PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_57712_VF, +- PCI_ANY_ID, PCI_ANY_ID, brcm_57712_VF}, +- {PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_57713, +- PCI_ANY_ID, PCI_ANY_ID, brcm_57713}, +- {PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_57713E, +- PCI_ANY_ID, PCI_ANY_ID, brcm_57713e}, +- {PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_57800, +- PCI_ANY_ID, PCI_ANY_ID, brcm_57800}, +- {PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_57800_MF, +- PCI_ANY_ID, PCI_ANY_ID, brcm_57800_MF}, +- {PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_57800_VF, +- PCI_ANY_ID, PCI_ANY_ID, brcm_57800_VF}, +- {PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_57810, +- PCI_ANY_ID, PCI_ANY_ID, brcm_57810}, +- {PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_57810_MF, +- PCI_ANY_ID, PCI_ANY_ID, brcm_57810_MF}, +- {PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_57810_VF, +- PCI_ANY_ID, PCI_ANY_ID, brcm_57810_VF}, +- {PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_57811, +- PCI_ANY_ID, PCI_ANY_ID, brcm_57811}, +- {PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_57811_MF, +- PCI_ANY_ID, PCI_ANY_ID, brcm_57811_MF}, +- {PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_57811_VF, +- PCI_ANY_ID, PCI_ANY_ID, brcm_57811_VF}, +- {PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_57840_OBSOLETE, +- PCI_ANY_ID, PCI_ANY_ID, brcm_57840}, +- {PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_57840_MF_OBSOLETE, +- PCI_ANY_ID, PCI_ANY_ID, brcm_57840_MF}, +- {PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_57840_4_10, +- PCI_ANY_ID, PCI_ANY_ID, brcm_57840_4_10}, +- {PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_57840_2_20, +- PCI_ANY_ID, PCI_ANY_ID, brcm_57840_2_20}, +- {PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_57840_MF, +- PCI_ANY_ID, PCI_ANY_ID, brcm_57840_MF}, +- {PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_57840_VF, +- PCI_ANY_ID, PCI_ANY_ID, brcm_57840_VF}, +- {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_NX2_57840_4_10, +- PCI_ANY_ID, PCI_ANY_ID, brcm_57840_4_10}, +- {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_NX2_57840_2_20, +- PCI_ANY_ID, PCI_ANY_ID, brcm_57840_2_20}, +- {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_NX2_57840_MF, +- PCI_ANY_ID, PCI_ANY_ID, brcm_57840_MF}, +- {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_NX2_57840_VF, +- PCI_ANY_ID, PCI_ANY_ID, brcm_57840_VF}, +-}; +- +-static struct iro e1_iro[2] = { +- {0x45a0, 0x90, 0x8, 0x0, 0x8}, /* T6.0 */ +- {0x50c8, 0x90, 0x8, 0x0, 0x8}, /* T6.4 */ +-}; +- +-static struct iro e1h_iro[2] = { +- {0x1c40, 0xe0, 0x8, 0x0, 0x8}, /* T6.0 */ +- {0x1e00, 0xe0, 0x8, 0x0, 0x8}, /* T6.4 */ +-}; +- +-static struct iro e2_iro[2] = { +- {0x6000, 0x20, 0x0, 0x0, 0x8}, /* T6.0 */ +- {0x6000, 0x20, 0x0, 0x0, 0x8}, /* T6.4 */ +-}; +- +-struct bnx2x_driver_version bnx2x_version = { +- BNX2X_UNKNOWN_MAJOR_VERSION, +- BNX2X_UNKNOWN_MINOR_VERSION, +- BNX2X_UNKNOWN_SUB_MINOR_VERSION, +-}; +- +-static int bnx2x_clear_tx_intr(nic_t *nic); +- +-/******************************************************************************* +- * BNX2X Library Functions +- ******************************************************************************/ +-/** +- * bnx2x_get_library_name() - Used to get the name of this NIC libary +- * @param name - This function will return the pointer to this NIC +- * library name +- * @param name_size +- */ +-static void bnx2x_get_library_name(char **name, size_t *name_size) +-{ +- *name = (char *)library_name; +- *name_size = sizeof(library_name); +-} +- +-/** +- * bnx2x_get_library_version() - Used to get the version string of this +- * NIC libary +- * @param version - This function will return the pointer to this NIC +- * library version string +- * @param version_size - This will be set with the version size +- */ +-static void bnx2x_get_library_version(char **version, size_t *version_size) +-{ +- *version = (char *)library_version; +- *version_size = sizeof(library_version); +-} +- +-/** +- * bnx2x_get_build_date() - Used to get the build date string of this library +- * @param version - This function will return the pointer to this NIC +- * library build date string +- * @param version_size - This will be set with the build date string size +- */ +-static void bnx2x_get_build_date(char **build, size_t *build_size) +-{ +- *build = (char *)build_date; +- *build_size = sizeof(build_date); +-} +- +-/** +- * bnx2x_get_transport_name() - Used to get the transport name associated +- * with this this NIC libary +- * @param transport_name - This function will return the pointer to this NIC +- * library's associated transport string +- * @param transport_name_size - This will be set with the transport name size +- */ +-static void bnx2x_get_transport_name(char **transport_name, +- size_t *transport_name_size) +-{ +- *transport_name = (char *)bnx2i_library_transport_name; +- *transport_name_size = bnx2i_library_transport_name_size; +-} +- +-/** +- * bnx2x_get_uio_name() - Used to get the uio name associated with this this +- * NIC libary +- * @param uio_name - This function will return the pointer to this NIC +- * library's associated uio string +- * @param transport_name_size - This will be set with the uio name size +- */ +-static void bnx2x_get_uio_name(char **uio_name, size_t *uio_name_size) +-{ +- *uio_name = (char *)library_uio_name; +- *uio_name_size = sizeof(library_uio_name); +-} +- +-/** +- * bnx2x_get_pci_table() - Used to get the PCI table for this NIC libary to +- * determine which NIC's based off of PCI ID's are +- * supported +- * @param table - This function will return the pointer to the PCI table +- * @param entries - This function will return the number of entries in the NIC +- * library's PCI table +- */ +-static void bnx2x_get_pci_table(struct pci_device_id **table, +- uint32_t *entries) +-{ +- *table = (struct pci_device_id *)bnx2x_pci_tbl; +- *entries = +- (uint32_t) (sizeof(bnx2x_pci_tbl) / sizeof(bnx2x_pci_tbl[0])); +-} +- +-/** +- * bnx2x_get_ops() - Used to get the NIC library op table +- * @param op - The op table of this NIC library +- */ +-struct nic_ops *bnx2x_get_ops() +-{ +- return &bnx2x_op; +-} +- +-/******************************************************************************* +- * bnx2x Utility Functions +- ******************************************************************************/ +-/******************************************************************************* +- * Utility Functions Used to read register from the bnx2x device +- ******************************************************************************/ +-static void bnx2x_set_drv_version_unknown(bnx2x_t *bp) +-{ +- bp->version.major = BNX2X_UNKNOWN_MAJOR_VERSION; +- bp->version.minor = BNX2X_UNKNOWN_MINOR_VERSION; +- 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 == (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; +- } +- +- return 0; +-} +- +-static void bnx2x_set_drv_version_default(bnx2x_t *bp) +-{ +- bp->version.major = BNX2X_DEFAULT_MAJOR_VERSION; +- bp->version.minor = BNX2X_DEFAULT_MINOR_VERSION; +- bp->version.sub_minor = BNX2X_DEFAULT_SUB_MINOR_VERSION; +-} +- +-/** +- * bnx2x_get_drv_version() - Used to determine the driver version +- * @param bp - Device used to determine bnx2x driver version +- */ +-static int bnx2x_get_drv_version(bnx2x_t *bp) +-{ +- nic_t *nic = bp->parent; +- int fd, rc; +- struct ifreq ifr; +- struct ethtool_drvinfo drvinfo; +- char *tok, *save_ptr = NULL; +- +- /* Setup our control structures. */ +- memset(&ifr, 0, sizeof(ifr)); +- strcpy(ifr.ifr_name, nic->eth_device_name); +- +- /* Open control socket. */ +- fd = socket(AF_INET, SOCK_DGRAM, 0); +- if (fd < 0) { +- LOG_ERR(PFX "%s: Cannot get socket to determine version " +- "[0x%x %s]", nic->log_name, errno, strerror(errno)); +- return -EIO; +- } +- +- memset(&drvinfo, 0, sizeof(drvinfo)); +- drvinfo.cmd = ETHTOOL_GDRVINFO; +- ifr.ifr_data = (caddr_t) &drvinfo; +- rc = ioctl(fd, SIOCETHTOOL, &ifr); +- if (rc < 0) { +- LOG_ERR(PFX "%s: call to ethool IOCTL failed [0x%x %s]", +- nic->log_name, errno, strerror(errno)); +- goto error; +- } +- +- tok = strtok_r(drvinfo.version, ".", &save_ptr); +- if (tok == NULL) { +- rc = -EIO; +- goto error; +- } +- bp->version.major = atoi(tok); +- +- tok = strtok_r(NULL, ".", &save_ptr); +- if (tok == NULL) { +- rc = -EIO; +- goto error; +- } +- bp->version.minor = atoi(tok); +- +- tok = strtok_r(NULL, ".", &save_ptr); +- if (tok == NULL) { +- rc = -EIO; +- goto error; +- } +- bp->version.sub_minor = atoi(tok); +- +- LOG_INFO(PFX "%s: interface version %d.%d.%d", nic->log_name, +- bp->version.major, bp->version.minor, bp->version.sub_minor); +- +- close(fd); +- +- return 0; +- +-error: +- close(fd); +- bnx2x_set_drv_version_unknown(bp); +- +- LOG_ERR(PFX "%s: error parsing driver string: '%s'", +- nic->log_name, drvinfo.version); +- +- return rc; +- +-} +- +-static inline int bnx2x_is_ver70(bnx2x_t *bp) +-{ +- return (bp->version.major == 1 && bp->version.minor >= 70); +-} +- +-static inline int bnx2x_is_ver60(bnx2x_t *bp) +-{ +- return (bp->version.major == 1 && (bp->version.minor == 60 || +- bp->version.minor == 62 || +- bp->version.minor == 64)); +-} +- +-static inline int bnx2x_is_ver60_plus(bnx2x_t *bp) +-{ +- return bnx2x_is_ver60(bp) || bnx2x_is_ver70(bp); +-} +- +-static inline int bnx2x_is_ver52(bnx2x_t *bp) +-{ +- return (bp->version.major == 1 && bp->version.minor == 52); +-} +- +-static void bnx2x_wr32(bnx2x_t *bp, __u32 off, __u32 val) +-{ +- *((volatile __u32 *)(bp->reg + off)) = val; +-} +- +-static void bnx2x_doorbell(bnx2x_t *bp, __u32 off, __u32 val) +-{ +- *((volatile __u32 *)(bp->reg2 + off)) = val; +-} +- +-static void bnx2x_flush_doorbell(bnx2x_t *bp, __u32 off) +-{ +- volatile __u32 tmp __attribute__((__unused__)); +- +- barrier(); +- tmp = *((volatile __u32 *)(bp->reg2 + off)); +-} +- +-static __u32 bnx2x_rd32(bnx2x_t *bp, __u32 off) +-{ +- return *((volatile __u32 *)(bp->reg + off)); +-} +- +-static int bnx2x_reg_sync(bnx2x_t *bp, __u32 off, __u16 length) +-{ +- return msync(bp->reg + off, length, MS_SYNC); +-} +- +-static void bnx2x_update_rx_prod(bnx2x_t *bp) +-{ +- struct ustorm_eth_rx_producers rx_prods = { 0 }; +- int i; +- +- rx_prods.bd_prod = bp->rx_bd_prod; +- rx_prods.cqe_prod = bp->rx_prod; +- +- barrier(); +- +- for (i = 0; i < sizeof(struct ustorm_eth_rx_producers) / 4; i++) +- bnx2x_wr32(bp, bp->rx_prod_io + i * 4, +- ((__u32 *)&rx_prods)[i]); +- +- barrier(); +- +- bnx2x_reg_sync(bp, bp->rx_prod_io, +- sizeof(struct ustorm_eth_rx_producers)); +-} +- +-/** +- * bnx2x_get_chip_id() - Used to retrive the chip ID from the nic +- * @param dev - Device used to determin NIC type +- * @return Chip ID read from the MISC ID register +- */ +-static int bnx2x_get_chip_id(bnx2x_t *bp) +-{ +- int val, id; +- +- /* Get the chip revision id and number. */ +- /* chip num:16-31, rev:12-15, metal:4-11, bond_id:0-3 */ +- val = bnx2x_rd32(bp, BNX2X_MISC_REG_CHIP_NUM); +- id = ((val & 0xffff) << 16); +- val = bnx2x_rd32(bp, BNX2X_MISC_REG_CHIP_REV); +- id |= ((val & 0xf) << 12); +- val = bnx2x_rd32(bp, BNX2X_MISC_REG_CHIP_METAL); +- id |= ((val & 0xff) << 4); +- val = bnx2x_rd32(bp, BNX2X_MISC_REG_BOND_ID); +- id |= (val & 0xf); +- +- return id; +-} +- +-/** +- * bnx2x_uio_verify() +- * +- */ +-static int bnx2x_uio_verify(nic_t *nic) +-{ +- char *raw = NULL, *raw_tmp; +- uint32_t raw_size = 0; +- char temp_path[sizeof(cnic_uio_sysfs_name_tempate) + 8]; +- int rc = 0; +- +- /* Build the path to determine uio name */ +- snprintf(temp_path, sizeof(temp_path), +- cnic_uio_sysfs_name_tempate, nic->uio_minor); +- +- rc = capture_file(&raw, &raw_size, temp_path); +- if (rc != 0) +- goto error; +- +- /* sanitize name string by replacing newline with null termination */ +- raw_tmp = raw; +- while (*raw_tmp != '\n') +- raw_tmp++; +- *raw_tmp = '\0'; +- +- if (strncmp(raw, bnx2x_uio_sysfs_name, +- sizeof(bnx2x_uio_sysfs_name)) != 0) { +- LOG_ERR(PFX "%s: uio names not equal: " +- "expecting %s got %s from %s", +- nic->log_name, bnx2x_uio_sysfs_name, raw, temp_path); +- rc = -EIO; +- } +- +- free(raw); +- +- LOG_INFO(PFX "%s: Verified is a cnic_uio device", nic->log_name); +- +-error: +- return rc; +-} +- +-/******************************************************************************* +- * bnx2x Utility Functions to get to the hardware consumer indexes +- ******************************************************************************/ +-static __u16 bnx2x_get_rx(bnx2x_t *bp) +-{ +- struct host_def_status_block *sblk = bp->status_blk.def; +- __u16 rx_comp_cons; +- +- msync(sblk, sizeof(*sblk), MS_SYNC); +- rx_comp_cons = +- sblk->u_def_status_block. +- index_values[HC_INDEX_DEF_U_ETH_ISCSI_RX_CQ_CONS]; +- if ((rx_comp_cons & BNX2X_MAX_RCQ_DESC_CNT(bp)) == +- BNX2X_MAX_RCQ_DESC_CNT(bp)) +- rx_comp_cons++; +- +- return rx_comp_cons; +-} +- +-static __u16 bnx2x_get_rx_60(bnx2x_t *bp) +-{ +- struct host_sp_status_block *sblk = bp->status_blk.sp; +- __u16 rx_comp_cons; +- +- msync(sblk, sizeof(*sblk), MS_SYNC); +- rx_comp_cons = +- sblk->sp_sb.index_values[HC_SP_INDEX_ETH_ISCSI_RX_CQ_CONS]; +- if ((rx_comp_cons & BNX2X_MAX_RCQ_DESC_CNT(bp)) == +- BNX2X_MAX_RCQ_DESC_CNT(bp)) +- rx_comp_cons++; +- +- return rx_comp_cons; +-} +- +-static __u16 bnx2x_get_tx(bnx2x_t *bp) +-{ +- struct host_def_status_block *sblk = bp->status_blk.def; +- __u16 tx_cons; +- +- msync(sblk, sizeof(*sblk), MS_SYNC); +- tx_cons = +- sblk->c_def_status_block. +- index_values[HC_INDEX_DEF_C_ETH_ISCSI_CQ_CONS]; +- +- return tx_cons; +-} +- +-static __u16 bnx2x_get_tx_60(bnx2x_t *bp) +-{ +- struct host_sp_status_block *sblk = bp->status_blk.sp; +- __u16 tx_cons; +- +- msync(sblk, sizeof(*sblk), MS_SYNC); +- tx_cons = sblk->sp_sb.index_values[HC_SP_INDEX_ETH_ISCSI_CQ_CONS]; +- +- return tx_cons; +-} +- +-typedef enum { +- CNIC_VLAN_STRIPPING_ENABLED = 1, +- CNIC_VLAN_STRIPPING_DISABLED = 2, +-} CNIC_VLAN_STRIPPING_MODE; +- +-/** +- * bnx2x_strip_vlan_enabled() - This will query the device to determine whether +- * VLAN tag stripping is enabled or not +- * @param dev - device to check stripping or not +- * @ return CNIC_VLAN_STRIPPING_ENABLED stripping is enabled +- * CNIC_VLAN_STRIPPING_DISABLED stripping is not enabled +- */ +-static CNIC_VLAN_STRIPPING_MODE bnx2x_strip_vlan_enabled(bnx2x_t *bp) +-{ +- return CNIC_VLAN_STRIPPING_DISABLED; +-} +- +-/** +- * bnx2x_free() - Used to free a bnx2x structure +- */ +-static void bnx2x_free(nic_t *nic) +-{ +- if (nic->priv) +- free(nic->priv); +- nic->priv = NULL; +-} +- +-/** +- * bnx2x_alloc() - Used to allocate a bnx2x structure +- */ +-static bnx2x_t *bnx2x_alloc(nic_t *nic) +-{ +- bnx2x_t *bp = malloc(sizeof(*bp)); +- +- if (bp == NULL) { +- LOG_ERR(PFX "%s: Could not allocate BNX2X space", +- nic->log_name); +- return NULL; +- } +- +- /* Clear out the CNIC contents */ +- memset(bp, 0, sizeof(*bp)); +- +- bp->bar0_fd = INVALID_FD; +- bp->bar2_fd = INVALID_FD; +- +- bp->parent = nic; +- nic->priv = (void *)bp; +- +- bnx2x_set_drv_version_unknown(bp); +- +- return bp; +-} +- +-/** +- * bnx2x_open() - This will initialize all the hardware resources underneath +- * a struct cnic_uio device +- * @param dev - The struct cnic_uio device to attach the hardware with +- * @return 0 on success, on failure a errno will be returned +- */ +-static int bnx2x_open(nic_t *nic) +-{ +- bnx2x_t *bp; +- struct stat uio_stat; +- int i, rc; +- __u32 val; +- int count; +- char sysfs_resc_path[80]; +- uint32_t bus; +- uint32_t slot; +- uint32_t func; +- uint32_t mode; +- __u32 proto_offset; +- __u32 ovtag_offset; +- +- /* Sanity Check: validate the parameters */ +- if (nic == NULL) { +- LOG_ERR(PFX "nic == NULL"); +- return -EINVAL; +- } +- +- if ((nic->priv) != NULL && +- (((bnx2x_t *) (nic->priv))->flags & BNX2X_OPENED)) { +- return 0; +- } +- +- bp = bnx2x_alloc(nic); +- if (bp == NULL) +- return -ENOMEM; +- +- if (bnx2x_is_drv_version_unknown(&bnx2x_version)) { +- /* If version is unknown, go read from ethtool */ +- rc = bnx2x_get_drv_version(bp); +- if (rc) +- bnx2x_set_drv_version_default(bp); +- else if (!(bnx2x_is_ver60_plus(bp) || bnx2x_is_ver52(bp))) +- bnx2x_set_drv_version_default(bp); +- +- LOG_INFO(PFX "%s: bnx2x Use baseline version %d.%d.%d", +- nic->log_name, +- bp->version.major, bp->version.minor, +- bp->version.sub_minor); +- } else { +- /* Version is not unknown, just use it */ +- bnx2x_version.major = bp->version.major; +- bnx2x_version.minor = bp->version.minor; +- bnx2x_version.sub_minor = bp->version.sub_minor; +- } +- +- 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) { +- LOG_ERR(PFX "%s: uio device has been brought up " +- "via pid: %d on fd: %d", +- nic->uio_device_name, getpid(), nic->fd); +- +- rc = bnx2x_uio_verify(nic); +- if (rc != 0) +- continue; +- +- break; +- } else { +- LOG_WARN(PFX "%s: Could not open device: %s, [%s]", +- nic->log_name, nic->uio_device_name, +- strerror(errno)); +- +- 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++; +- } +- } +- if (nic->fd == INVALID_FD) { +- LOG_ERR(PFX "%s: Could not open device: %s, [%s]", +- nic->log_name, nic->uio_device_name, +- strerror(errno)); +- rc = errno; +- goto open_error; +- } +- if (fstat(nic->fd, &uio_stat) < 0) { +- LOG_ERR(PFX "%s: Could not fstat device", nic->log_name); +- rc = -ENODEV; +- goto open_error; +- } +- nic->uio_minor = minor(uio_stat.st_rdev); +- +- cnic_get_sysfs_pci_resource_path(nic, 0, sysfs_resc_path, 80); +- bp->bar0_fd = open(sysfs_resc_path, O_RDWR | O_SYNC); +- if (bp->bar0_fd < 0) { +- LOG_ERR(PFX "%s: Could not open %s", nic->log_name, +- sysfs_resc_path); +- rc = -ENODEV; +- goto open_error; +- } +- +- bp->reg = mmap(NULL, BNX2X_BAR_SIZE, PROT_READ | PROT_WRITE, +- MAP_SHARED, bp->bar0_fd, (off_t) 0); +- +- if (bp->reg == MAP_FAILED) { +- LOG_INFO(PFX "%s: Couldn't mmap BAR registers: %s", +- nic->log_name, strerror(errno)); +- bp->reg = NULL; +- rc = errno; +- goto open_error; +- } +- +- msync(bp->reg, BNX2X_BAR_SIZE, MS_SYNC); +- +- cnic_get_sysfs_pci_resource_path(nic, 2, sysfs_resc_path, 80); +- bp->bar2_fd = open(sysfs_resc_path, O_RDWR | O_SYNC); +- if (bp->bar2_fd < 0) { +- LOG_ERR(PFX "%s: Could not open %s", nic->log_name, +- sysfs_resc_path); +- rc = -ENODEV; +- goto open_error; +- } +- +- bp->reg2 = mmap(NULL, BNX2X_BAR2_SIZE, PROT_READ | PROT_WRITE, +- MAP_SHARED, bp->bar2_fd, (off_t) 0); +- +- if (bp->reg2 == MAP_FAILED) { +- LOG_INFO(PFX "%s: Couldn't mmap BAR2 registers: %s", +- nic->log_name, strerror(errno)); +- bp->reg2 = NULL; +- rc = errno; +- goto open_error; +- } +- +- /* TODO: hardcoded with the cnic driver */ +- bp->rx_ring_size = 15; +- bp->rx_buffer_size = 0x400; +- +- LOG_DEBUG(PFX "%s: using rx ring size: %d, rx buffer size: %d", +- nic->log_name, bp->rx_ring_size, bp->rx_buffer_size); +- +- /* Determine the number of UIO events that have already occured */ +- rc = detemine_initial_uio_events(nic, &nic->intr_count); +- if (rc != 0) { +- LOG_ERR("Could not determine the number ofinitial UIO events"); +- nic->intr_count = 0; +- } +- +- /* Allocate space for rx pkt ring */ +- bp->rx_pkt_ring = malloc(sizeof(void *) * bp->rx_ring_size); +- if (bp->rx_pkt_ring == NULL) { +- LOG_ERR(PFX "%s: Could not allocate space for rx_pkt_ring", +- nic->log_name); +- rc = errno; +- goto open_error; +- } +- +- if (bnx2x_is_ver60_plus(bp)) +- bp->status_blk_size = sizeof(struct host_sp_status_block); +- else if (bnx2x_is_ver52(bp)) +- bp->status_blk_size = sizeof(struct host_def_status_block); +- else { +- LOG_INFO(PFX "%s: Unsupported bnx2x driver [%d.%d]", +- nic->log_name, bp->version.major, bp->version.minor); +- +- rc = -ENOTSUP; +- goto open_error; +- } +- +- bp->status_blk.def = mmap(NULL, bp->status_blk_size, +- PROT_READ | PROT_WRITE, MAP_SHARED, +- nic->fd, (off_t) nic->page_size); +- if (bp->status_blk.def == MAP_FAILED) { +- LOG_INFO(PFX "%s: Could not mmap status block: %s", +- nic->log_name, strerror(errno)); +- bp->status_blk.def = NULL; +- rc = errno; +- goto open_error; +- } +- +- bp->tx_ring = mmap(NULL, 4 * nic->page_size, +- PROT_READ | PROT_WRITE, +- MAP_SHARED | MAP_LOCKED, +- nic->fd, (off_t) 2 * nic->page_size); +- if (bp->tx_ring == MAP_FAILED) { +- LOG_INFO(PFX "%s: Could not mmap tx ring: %s", +- nic->log_name, strerror(errno)); +- bp->tx_ring = NULL; +- rc = errno; +- goto open_error; +- } +- +- bp->rx_comp_ring.cqe = (union eth_rx_cqe *) +- (((__u8 *) bp->tx_ring) + 2 * nic->page_size); +- +- bp->bufs = mmap(NULL, (bp->rx_ring_size + 1) * bp->rx_buffer_size, +- PROT_READ | PROT_WRITE, +- MAP_SHARED | MAP_LOCKED, +- nic->fd, (off_t) 3 * nic->page_size); +- if (bp->bufs == MAP_FAILED) { +- LOG_INFO(PFX "%s: Could not mmap buffers: %s", +- nic->log_name, strerror(errno)); +- bp->bufs = NULL; +- rc = errno; +- goto open_error; +- } +- +- bp->chip_id = bnx2x_get_chip_id(bp); +- LOG_DEBUG(PFX "Chip ID: %x", bp->chip_id); +- +- rc = get_bus_slot_func_num(nic, &bus, &slot, &func); +- if (rc != 0) { +- LOG_INFO(PFX "%s: Couldn't determine bus:slot.func", +- 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; +- +- if (CHIP_IS_E2_PLUS(bp)) { +- __u32 val = bnx2x_rd32(bp, MISC_REG_PORT4MODE_EN_OVWR); +- if (!(val & 1)) +- val = bnx2x_rd32(bp, MISC_REG_PORT4MODE_EN); +- else +- val = (val >> 1) & 1; +- +- if (val) +- bp->pfid = func >> 1; +- else +- bp->pfid = func & 0x6; +- } else { +- bp->pfid = func; +- } +- +- if (bnx2x_is_ver60_plus(bp)) +- bp->port = bp->pfid & 1; +- +- bp->cid = 17; +- bp->client_id = 17; +- +- if (bnx2x_is_ver60_plus(bp)) { +- struct client_init_general_data *data = bp->bufs; +- +- bp->client_id = data->client_id; +- if (data->uid.cid) +- bp->cid = data->uid.cid; +- if (bp->version.minor >= 78 && bp->version.sub_minor >= 55 && +- data->uid.cid_override_key == UIO_USE_TX_DOORBELL) { +- bp->tx_doorbell = data->uid.tx_db_off; +- LOG_INFO(PFX "%s: tx doorbell override offset = 0x%x", +- nic->log_name, bp->tx_doorbell); +- } +- } +- +- LOG_INFO(PFX "%s: func 0x%x, pfid 0x%x, client_id 0x%x, cid 0x%x", +- nic->log_name, bp->func, bp->pfid, bp->client_id, bp->cid); +- +- if (CHIP_IS_E1(bp)) +- bp->iro = e1_iro; +- else if (CHIP_IS_E1H(bp)) +- bp->iro = e1h_iro; +- else if (CHIP_IS_E2_PLUS(bp)) +- bp->iro = e2_iro; +- +- if (bnx2x_is_ver60_plus(bp)) { +- __u32 cl_qzone_id = BNX2X_CL_QZONE_ID(bp, bp->client_id); +- +- bp->iro_idx = 0; +- if (bp->version.minor >= 64) { +- bp->iro_idx = 1; +- cl_qzone_id = BNX2X_CL_QZONE_ID_64(bp, bp->client_id); +- } +- +- bp->rx_prod_io = BAR_USTRORM_INTMEM + +- (CHIP_IS_E2_PLUS(bp) ? +- USTORM_RX_PRODS_E2_OFFSET(cl_qzone_id) : +- USTORM_RX_PRODS_E1X_OFFSET(bp->port, bp->client_id)); +- +- if (!bp->tx_doorbell) +- bp->tx_doorbell = bp->cid * 0x80 + 0x40; +- +- bp->get_rx_cons = bnx2x_get_rx_60; +- bp->get_tx_cons = bnx2x_get_tx_60; +- bp->tx_vlan_tag_bit = ETH_TX_BD_FLAGS_VLAN_TAG_T6X; +- } else { +- bp->rx_prod_io = BAR_USTRORM_INTMEM + +- USTORM_RX_PRODS_OFFSET(bp->port, bp->client_id); +- +- bp->tx_doorbell = bp->cid * nic->page_size + 0x40; +- +- bp->get_rx_cons = bnx2x_get_rx; +- bp->get_tx_cons = bnx2x_get_tx; +- bp->tx_vlan_tag_bit = ETH_TX_BD_FLAGS_VLAN_TAG_T5X; +- } +- +- bp->tx_cons = 0; +- bp->tx_prod = 0; +- bp->tx_bd_prod = 0; +- bp->tx_pkt = bp->bufs; +- +- bp->rx_index = 0; +- bp->rx_cons = 0; +- bp->rx_bd_cons = 0; +- bp->rx_prod = 127; +- bp->rx_bd_prod = bp->rx_ring_size; +- +- for (i = 0; i < bp->rx_ring_size; i++) { +- void *ptr = bp->bufs + (bp->rx_buffer_size * (i + 1)); +- +- bp->rx_pkt_ring[i] = ptr; +- } +- +- val = bnx2x_rd32(bp, MISC_REG_SHARED_MEM_ADDR); +- +- bp->shmem_base = val; +- val = bnx2x_rd32(bp, bp->shmem_base + SHMEM_ISCSI_MAC_UPPER(bp)); +- nic->mac_addr[0] = (__u8) (val >> 8); +- nic->mac_addr[1] = (__u8) val; +- val = bnx2x_rd32(bp, bp->shmem_base + SHMEM_ISCSI_MAC_LOWER(bp)); +- nic->mac_addr[2] = (__u8) (val >> 24); +- nic->mac_addr[3] = (__u8) (val >> 16); +- nic->mac_addr[4] = (__u8) (val >> 8); +- nic->mac_addr[5] = (__u8) val; +- +- if (bnx2x_is_ver60_plus(bp) && CHIP_IS_E2_PLUS(bp)) { +- __u32 mf_cfg_addr = 0; +- __u32 mac_offset; +- __u8 mac[6]; +- +- val = bnx2x_rd32(bp, (BNX2X_PATH(bp) ? MISC_REG_GENERIC_CR_1 : +- MISC_REG_GENERIC_CR_0)); +- bp->shmem_base2 = val; +- if (bp->shmem_base2) { +- /* size */ +- val = bnx2x_rd32(bp, bp->shmem_base2); +- +- if (val > 0x10) +- mf_cfg_addr = +- bnx2x_rd32(bp, bp->shmem_base2 + 0x10); +- } +- +- if (!mf_cfg_addr) +- mf_cfg_addr = bp->shmem_base + 0x7e4; +- +- /* shared_feat_cfg.config */ +- mode = bnx2x_rd32(bp, bp->shmem_base + 0x354); +- mode &= 0x700; +- LOG_DEBUG(PFX "%s: mode = 0x%x", nic->log_name, mode); +- switch (mode) { +- case 0x300: /* SI mode */ +- mac_offset = 0xe4 + (bp->func * 0x28) + 4; +- val = bnx2x_rd32(bp, mf_cfg_addr + mac_offset); +- mac[0] = (__u8) (val >> 8); +- mac[1] = (__u8) val; +- mac_offset += 4; +- val = bnx2x_rd32(bp, mf_cfg_addr + mac_offset); +- mac[2] = (__u8) (val >> 24); +- mac[3] = (__u8) (val >> 16); +- mac[4] = (__u8) (val >> 8); +- mac[5] = (__u8) val; +- +- if (mac[0] != 0xff) { +- memcpy(nic->mac_addr, mac, 6); +- } else if (bp->func > 1) { +- LOG_INFO(PFX "%s: Invalid mac address: " +- "%02x:%02x:%02x:%02x:%02x:%02x, abort", +- nic->log_name, +- mac[0], mac[1], mac[2], +- mac[3], mac[4], mac[5]); +- rc = -ENOTSUP; +- goto open_error; +- } +- break; +- +- case 0x0: /* MF SD mode */ +- case 0x500: +- case 0x600: +- proto_offset = 0x24 + (bp->func * 0x18); +- ovtag_offset = proto_offset + 0xc; +- +- rc = -ENOTSUP; +- val = bnx2x_rd32(bp, mf_cfg_addr + ovtag_offset); +- val &= 0xffff; +- /* SD mode, check for valid outer VLAN */ +- 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) +- goto open_error; +- +- mac_offset = proto_offset + 0x4; +- val = bnx2x_rd32(bp, mf_cfg_addr + mac_offset); +- mac[0] = (__u8) (val >> 8); +- mac[1] = (__u8) val; +- mac_offset += 4; +- val = bnx2x_rd32(bp, mf_cfg_addr + mac_offset); +- mac[2] = (__u8) (val >> 24); +- mac[3] = (__u8) (val >> 16); +- mac[4] = (__u8) (val >> 8); +- mac[5] = (__u8) val; +- memcpy(nic->mac_addr, mac, 6); +- break; +- } +- } +-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], +- nic->mac_addr[3], nic->mac_addr[4], nic->mac_addr[5]); +- +- /* Determine if Hardware VLAN tag stripping is enabled or not */ +- if (CNIC_VLAN_STRIPPING_ENABLED == bnx2x_strip_vlan_enabled(bp)) +- nic->flags |= NIC_VLAN_STRIP_ENABLED; +- +- msync(bp->reg, BNX2X_BAR_SIZE, MS_SYNC); +- +- LOG_INFO("%s: bnx2x initialized", nic->log_name); +- +- bnx2x_update_rx_prod(bp); +- bp->flags |= BNX2X_OPENED; +- +- return 0; +- +-open_error: +- if (bp->tx_ring) { +- munmap(bp->tx_ring, 4 * nic->page_size); +- bp->tx_ring = NULL; +- } +- +- if (bp->status_blk.def) { +- munmap(bp->status_blk.def, bp->status_blk_size); +- bp->status_blk.def = NULL; +- } +- +- if (bp->reg) { +- munmap(bp->reg, BNX2X_BAR_SIZE); +- bp->reg = NULL; +- } +- +- if (bp->reg2) { +- munmap(bp->reg2, BNX2X_BAR2_SIZE); +- bp->reg2 = NULL; +- } +- +- if (bp->rx_pkt_ring) { +- free(bp->rx_pkt_ring); +- bp->rx_pkt_ring = NULL; +- } +- +- if (bp->bar2_fd != INVALID_FD) { +- close(bp->bar2_fd); +- bp->bar2_fd = INVALID_FD; +- } +- +- if (bp->bar0_fd != INVALID_FD) { +- close(bp->bar0_fd); +- bp->bar0_fd = INVALID_FD; +- } +- if (nic->fd != INVALID_FD) { +- close(nic->fd); +- nic->fd = INVALID_FD; +- } +- bnx2x_free(nic); +- +- return rc; +-} +- +-/** +- * bnx2x_uio_close_resources() - Used to free resource for the NIC/CNIC +- * @param nic - NIC device to free resource +- * @param graceful - whether to wait to close gracefully +- * @return 0 on success, <0 on failure +- */ +-static int bnx2x_uio_close_resources(nic_t *nic, NIC_SHUTDOWN_T graceful) +-{ +- bnx2x_t *bp = (bnx2x_t *) nic->priv; +- int rc = 0; +- +- /* Check if there is an assoicated bnx2x device */ +- if (bp == NULL) { +- LOG_WARN(PFX "%s: when closing resources there is " +- "no assoicated bnx2x", nic->log_name); +- return -EIO; +- } +- +- /* Clean up allocated memory */ +- +- if (bp->rx_pkt_ring != NULL) { +- free(bp->rx_pkt_ring); +- bp->rx_pkt_ring = NULL; +- } +- +- /* Clean up mapped registers */ +- if (bp->bufs != NULL) { +- rc = munmap(bp->bufs, +- (bp->rx_ring_size + 1) * bp->rx_buffer_size); +- if (rc != 0) +- LOG_WARN(PFX "%s: Couldn't unmap bufs", nic->log_name); +- bp->bufs = NULL; +- } +- +- if (bp->tx_ring != NULL) { +- rc = munmap(bp->tx_ring, 4 * nic->page_size); +- if (rc != 0) +- LOG_WARN(PFX "%s: Couldn't unmap tx_rings", +- nic->log_name); +- bp->tx_ring = NULL; +- } +- +- if (bp->status_blk.def != NULL) { +- rc = munmap(bp->status_blk.def, bp->status_blk_size); +- if (rc != 0) +- LOG_WARN(PFX "%s: Couldn't unmap status block", +- nic->log_name); +- bp->status_blk.def = NULL; +- } +- +- if (bp->reg != NULL) { +- rc = munmap(bp->reg, BNX2X_BAR_SIZE); +- if (rc != 0) +- LOG_WARN(PFX "%s: Couldn't unmap regs", nic->log_name); +- bp->reg = NULL; +- } +- +- if (bp->reg2 != NULL) { +- rc = munmap(bp->reg2, BNX2X_BAR2_SIZE); +- if (rc != 0) +- LOG_WARN(PFX "%s: Couldn't unmap regs", nic->log_name); +- bp->reg2 = NULL; +- } +- +- if (bp->bar2_fd != INVALID_FD) { +- close(bp->bar2_fd); +- bp->bar2_fd = INVALID_FD; +- } +- +- if (bp->bar0_fd != INVALID_FD) { +- close(bp->bar0_fd); +- bp->bar0_fd = INVALID_FD; +- } +- +- if (nic->fd != INVALID_FD) { +- rc = close(nic->fd); +- if (rc != 0) { +- LOG_WARN(PFX +- "%s: Couldn't close uio file descriptor: %d", +- nic->log_name, nic->fd); +- } else { +- LOG_DEBUG(PFX "%s: Closed uio file descriptor: %d", +- nic->log_name, nic->fd); +- } +- +- nic->fd = INVALID_FD; +- } else { +- LOG_WARN(PFX "%s: Invalid uio file descriptor: %d", +- nic->log_name, nic->fd); +- } +- +- bnx2x_set_drv_version_unknown(bp); +- +- LOG_INFO(PFX "%s: Closed all resources", nic->log_name); +- +- return 0; +-} +- +-/** +- * bnx2x_close() - Used to close the NIC device +- * @param nic - NIC device to close +- * @param graceful - whether to wait to close gracefully +- * @return 0 if successful, <0 if there is an error +- */ +-static int bnx2x_close(nic_t *nic, NIC_SHUTDOWN_T graceful) +-{ +- /* Sanity Check: validate the parameters */ +- 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; +- } +- +- LOG_INFO(PFX "Closing NIC device: %s", nic->log_name); +- +- bnx2x_uio_close_resources(nic, graceful); +- bnx2x_free(nic); +- +- return 0; +-} +- +-static void bnx2x_prepare_xmit_packet(nic_t *nic, +- nic_interface_t *nic_iface, +- struct packet *pkt) +-{ +- bnx2x_t *bp = (bnx2x_t *) nic->priv; +- struct uip_vlan_eth_hdr *eth_vlan = (struct uip_vlan_eth_hdr *)pkt->buf; +- struct uip_eth_hdr *eth = (struct uip_eth_hdr *)bp->tx_pkt; +- +- if (eth_vlan->tpid == htons(UIP_ETHTYPE_8021Q)) { +- memcpy(bp->tx_pkt, pkt->buf, sizeof(struct uip_eth_hdr)); +- eth->type = eth_vlan->type; +- pkt->buf_size -= (sizeof(struct uip_vlan_eth_hdr) - +- sizeof(struct uip_eth_hdr)); +- memcpy(bp->tx_pkt + sizeof(struct uip_eth_hdr), +- pkt->buf + sizeof(struct uip_vlan_eth_hdr), +- pkt->buf_size - sizeof(struct uip_eth_hdr)); +- } else +- memcpy(bp->tx_pkt, pkt->buf, pkt->buf_size); +- +- msync(bp->tx_pkt, pkt->buf_size, MS_SYNC); +-} +- +-/** +- * bnx2x_get_tx_pkt() - This function is used to a TX packet from the NIC +- * @param nic - The NIC device to send the packet +- */ +-void *bnx2x_get_tx_pkt(nic_t *nic) +-{ +- bnx2x_t *bp = (bnx2x_t *) nic->priv; +- return bp->tx_pkt; +-} +- +-/** +- * bnx2x_start_xmit() - This function is used to send a packet of data +- * @param nic - The NIC device to send the packet +- * @param len - the length of the TX packet +- * +- */ +-void bnx2x_start_xmit(nic_t *nic, size_t len, u16_t vlan_id) +-{ +- bnx2x_t *bp = (bnx2x_t *) nic->priv; +- uint16_t ring_prod; +- struct eth_tx_start_bd *txbd; +- struct eth_tx_bd *txbd2; +- struct eth_rx_bd *rx_bd; +- rx_bd = (struct eth_rx_bd *)(((__u8 *) bp->tx_ring) + nic->page_size); +- +- if ((rx_bd->addr_hi == 0) && (rx_bd->addr_lo == 0)) { +- LOG_PACKET(PFX "%s: trying to transmit when device is closed", +- nic->log_name); +- return; +- } +- +- ring_prod = BNX2X_TX_RING_IDX(bp->tx_bd_prod); +- txbd = &bp->tx_ring[ring_prod]; +- +- BNX2X_SET_TX_VLAN(bp, txbd, vlan_id); +- +- bp->tx_prod++; +- bp->tx_bd_prod = BNX2X_NEXT_TX_BD(bp->tx_bd_prod); +- bp->tx_bd_prod = BNX2X_NEXT_TX_BD(bp->tx_bd_prod); +- +- ring_prod = BNX2X_TX_RING_IDX(bp->tx_bd_prod); +- txbd2 = (struct eth_tx_bd *)&bp->tx_ring[ring_prod]; +- +- txbd2->nbytes = len - 0x10; +- txbd2->total_pkt_bytes = len; +- +- bp->tx_bd_prod = BNX2X_NEXT_TX_BD(bp->tx_bd_prod); +- +- barrier(); +- 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); +- } else { +- LOG_ERR(PFX "Pkt transmission failed."); +- } +- +- LOG_PACKET(PFX "%s: sent %d bytes using bp->tx_prod: %d", +- nic->log_name, len, bp->tx_prod); +-} +- +-/** +- * bnx2x_write() - Used to write the data to the hardware +- * @param nic - NIC hardware to read from +- * @param pkt - The packet which will hold the data to be sent on the wire +- * @return 0 if successful, <0 if failed +- */ +-int bnx2x_write(nic_t *nic, nic_interface_t *nic_iface, packet_t *pkt) +-{ +- bnx2x_t *bp; +- struct uip_stack *uip; +- int i = 0; +- +- /* Sanity Check: validate the parameters */ +- if (nic == NULL || nic_iface == NULL || pkt == NULL) { +- LOG_ERR(PFX "%s: bnx2x_write() nic == 0x%p || " +- " nic_iface == 0x%p || " +- " 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", +- nic->log_name); +- return -EINVAL; +- } +- +- /* Try to wait for a TX completion */ +- for (i = 0; i < 15; i++) { +- struct timespec sleep_req = {.tv_sec = 0, .tv_nsec = 5000000 }, +- sleep_rem; +- +- if (bnx2x_clear_tx_intr(nic) == 0) +- break; +- +- nanosleep(&sleep_req, &sleep_rem); +- } +- +- if (pthread_mutex_trylock(&nic->xmit_mutex) != 0) { +- 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_priority << 12) | +- nic_iface->vlan_id); +- +- /* bump the cnic dev send statistics */ +- nic->stats.tx.packets++; +- nic->stats.tx.bytes += uip->uip_len; +- +- 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); +- +- pthread_mutex_unlock(&nic->xmit_mutex); +- +- return 0; +-} +- +-static inline int bnx2x_get_rx_pad(bnx2x_t *bp, union eth_rx_cqe *cqe) +-{ +- int pad = 0; +- +- if (bnx2x_is_ver70(bp)) +- pad = ((union eth_rx_cqe_70 *)cqe)->fast_path_cqe_70. \ +- placement_offset; +- else if (bnx2x_is_ver60(bp)) { +- if (bp->version.minor >= 64) +- pad = cqe->fast_path_cqe_64.placement_offset; +- else +- pad = cqe->fast_path_cqe.placement_offset; +- } +- return pad; +-} +- +-/** +- * bnx2x_read() - Used to read the data from the hardware +- * @param nic - NIC hardware to read from +- * @param pkt - The packet which will hold the data +- * @return 0 if successful, <0 if failed +- */ +-static int bnx2x_read(nic_t *nic, packet_t *pkt) +-{ +- bnx2x_t *bp; +- int rc = 0; +- uint16_t hw_cons, sw_cons, bd_cons, bd_prod; +- +- /* Sanity Check: validate the parameters */ +- if (nic == NULL || pkt == NULL) { +- LOG_ERR(PFX "%s: bnx2x_read() nic == 0x%p || " +- " pkt == 0x%x", nic, pkt); +- return -EINVAL; +- } +- bp = (bnx2x_t *) nic->priv; +- +- hw_cons = bp->get_rx_cons(bp); +- sw_cons = bp->rx_cons; +- bd_cons = BNX2X_RX_BD(bp->rx_bd_cons); +- bd_prod = BNX2X_RX_BD(bp->rx_bd_prod); +- +- if (sw_cons != hw_cons) { +- uint16_t comp_ring_index = sw_cons & BNX2X_MAX_RCQ_DESC_CNT(bp); +- uint8_t ring_index; +- union eth_rx_cqe *cqe; +- __u8 cqe_fp_flags; +- void *rx_pkt; +- int len, pad, cqe_size, max_len; +- rc = 1; +- +- if (bnx2x_is_ver70(bp)) { +- cqe = (union eth_rx_cqe *) +- &bp->rx_comp_ring.cqe70[comp_ring_index]; +- cqe_size = sizeof(union eth_rx_cqe_70); +- } else { +- cqe = &bp->rx_comp_ring.cqe[comp_ring_index]; +- cqe_size = sizeof(union eth_rx_cqe); +- } +- cqe_fp_flags = cqe->fast_path_cqe.type_error_flags; +- +- LOG_PACKET(PFX "%s: clearing rx interrupt: %d %d", +- nic->log_name, sw_cons, hw_cons); +- +- msync(cqe, cqe_size, MS_SYNC); +- +- if (!(cqe_fp_flags & ETH_FAST_PATH_RX_CQE_TYPE)) { +- ring_index = bd_cons % 15; +- len = cqe->fast_path_cqe.pkt_len; +- pad = bnx2x_get_rx_pad(bp, cqe); +- rx_pkt = bp->rx_pkt_ring[ring_index] + pad; +- +- /* Doto query MTU size of physical device */ +- /* Ensure len is valid */ +- max_len = pkt->max_buf_size < bp->rx_buffer_size ? +- pkt->max_buf_size : bp->rx_buffer_size; +- if (len + pad > max_len) { +- LOG_DEBUG(PFX "%s: bad BD length: %d", +- nic->log_name, len); +- len = max_len - pad; +- } +- if (len > 0) { +- msync(rx_pkt, len, MS_SYNC); +- /* Copy the data */ +- memcpy(pkt->buf, rx_pkt, len); +- pkt->buf_size = len; +- +- /* Properly set the packet flags */ +- /* check if there is VLAN tagging */ +- if (cqe->fast_path_cqe.vlan_tag != 0) { +- pkt->vlan_tag = +- cqe->fast_path_cqe.vlan_tag; +- pkt->flags |= VLAN_TAGGED; +- } else { +- pkt->vlan_tag = 0; +- } +- +- LOG_PACKET(PFX +- "%s: processing packet length: %d", +- nic->log_name, len); +- +- /* bump the cnic dev recv statistics */ +- nic->stats.rx.packets++; +- nic->stats.rx.bytes += pkt->buf_size; +- } +- +- bd_cons = BNX2X_NEXT_RX_IDX(bd_cons); +- bd_prod = BNX2X_NEXT_RX_IDX(bd_prod); +- +- } +- sw_cons = BNX2X_NEXT_RCQ_IDX(bp, sw_cons); +- bp->rx_prod = BNX2X_NEXT_RCQ_IDX(bp, bp->rx_prod); +- } +- bp->rx_cons = sw_cons; +- bp->rx_bd_cons = bd_cons; +- bp->rx_bd_prod = bd_prod; +- bp->rx_hw_prod = hw_cons; +- +- if (rc) +- bnx2x_update_rx_prod(bp); +- +- return rc; +-} +- +-/******************************************************************************* +- * Clearing TX interrupts +- ******************************************************************************/ +-/** +- * bnx2x_clear_tx_intr() - This routine is called when a TX interrupt occurs +- * @param nic - the nic the interrupt occured on +- * @return 0 on success +- */ +-static int bnx2x_clear_tx_intr(nic_t *nic) +-{ +- 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) +- return 0; +- return -EAGAIN; +- } +- +- if (pthread_mutex_trylock(&nic->xmit_mutex)) { +- LOG_ERR(PFX "%s: unable to get xmit_mutex.", nic->log_name); +- return -EINVAL; +- } +- +- 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 +- * case is when stack will send an ARP packet out before sending the +- * intended packet */ +- if (nic->tx_packet_queue != NULL) { +- packet_t *pkt; +- int i; +- +- 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 +- * the hardware */ +- if (pkt != NULL) { +- 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_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); +- +- pthread_mutex_unlock(&nic->xmit_mutex); +- return 0; +- } +- +- /* Try to wait for a TX completion */ +- for (i = 0; i < 15; i++) { +- struct timespec sleep_req = {.tv_sec = 0, +- .tv_nsec = 5000000 +- }, sleep_rem; +- +- hw_cons = bp->get_tx_cons(bp); +- if (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; +- } +- +- nanosleep(&sleep_req, &sleep_rem); +- } +- } +- +- pthread_mutex_unlock(&nic->xmit_mutex); +- +- return 0; +-} +- +-/******************************************************************************* +- * bnx2x NIC op's table +- ******************************************************************************/ +-struct nic_ops bnx2x_op = { +- .description = "bnx2x", +- .open = bnx2x_open, +- .close = bnx2x_close, +- .write = bnx2x_write, +- .get_tx_pkt = bnx2x_get_tx_pkt, +- .start_xmit = bnx2x_start_xmit, +- .read = bnx2x_read, +- .clear_tx_intr = bnx2x_clear_tx_intr, +- .handle_iscsi_path_req = cnic_handle_iscsi_path_req, +- +- .lib_ops = { +- .get_library_name = bnx2x_get_library_name, +- .get_pci_table = bnx2x_get_pci_table, +- .get_library_version = bnx2x_get_library_version, +- .get_build_date = bnx2x_get_build_date, +- .get_transport_name = bnx2x_get_transport_name, +- .get_uio_name = bnx2x_get_uio_name, +- }, +-}; +diff --git a/iscsiuio/src/unix/libs/bnx2x.h b/iscsiuio/src/unix/libs/bnx2x.h +deleted file mode 100644 +index e204cbb..0000000 +--- a/iscsiuio/src/unix/libs/bnx2x.h ++++ /dev/null +@@ -1,715 +0,0 @@ +-/* +- * Copyright (c) 2009-2011, Broadcom Corporation +- * +- * Written by: Benjamin Li (benli@broadcom.com) +- * +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. All advertising materials mentioning features or use of this software +- * must display the following acknowledgement: +- * This product includes software developed by Adam Dunkels. +- * 4. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * bnx2x.h - bnx2x user space driver +- * +- */ +-#ifndef __BNX2X_H__ +-#define __BNX2X_H__ +- +-#include "nic.h" +- +-/****************************************************************************** +- * Default CNIC values +- ******************************************************************************/ +-#define DEFAULT_BNX2X_NUM_RXBD 15 +-#define DEFAULT_BNX2X_RX_LEN 0x400 +- +-/****************************************************************************** +- * BNX2X Hardware structures +- ******************************************************************************/ +-#define HC_USTORM_DEF_SB_NUM_INDICES 8 +-#define HC_CSTORM_DEF_SB_NUM_INDICES 8 +-#define HC_XSTORM_DEF_SB_NUM_INDICES 4 +-#define HC_TSTORM_DEF_SB_NUM_INDICES 4 +- +-struct atten_def_status_block { +- volatile __u32 attn_bits; +- volatile __u32 attn_bits_ack; +- volatile __u8 status_block_id; +- volatile __u8 reserved0; +- volatile __u16 attn_bits_index; +- volatile __u32 reserved1; +-}; +- +-struct cstorm_def_status_block_u { +- volatile __u16 index_values[HC_USTORM_DEF_SB_NUM_INDICES]; +- volatile __u16 status_block_index; +- volatile __u8 func; +- volatile __u8 status_block_id; +- volatile __u32 __flags; +-}; +- +-struct cstorm_def_status_block_c { +- volatile __u16 index_values[HC_CSTORM_DEF_SB_NUM_INDICES]; +- volatile __u16 status_block_index; +- volatile __u8 func; +- volatile __u8 status_block_id; +- volatile __u32 __flags; +-}; +- +-struct xstorm_def_status_block { +- volatile __u16 index_values[HC_XSTORM_DEF_SB_NUM_INDICES]; +- volatile __u16 status_block_index; +- volatile __u8 func; +- volatile __u8 status_block_id; +- volatile __u32 __flags; +-}; +- +-struct tstorm_def_status_block { +- volatile __u16 index_values[HC_TSTORM_DEF_SB_NUM_INDICES]; +- volatile __u16 status_block_index; +- volatile __u8 func; +- volatile __u8 status_block_id; +- volatile __u32 __flags; +-}; +- +-struct host_def_status_block { +- struct atten_def_status_block atten_status_block; +- struct cstorm_def_status_block_u u_def_status_block; +- struct cstorm_def_status_block_c c_def_status_block; +- struct xstorm_def_status_block x_def_status_block; +- struct tstorm_def_status_block t_def_status_block; +-}; +- +-#define HC_INDEX_DEF_U_ETH_ISCSI_RX_CQ_CONS 1 +-#define HC_INDEX_DEF_U_ETH_ISCSI_RX_BD_CONS 3 +-#define HC_INDEX_DEF_C_ETH_ISCSI_CQ_CONS 5 +- +-struct atten_sp_status_block { +- __u32 attn_bits; +- __u32 attn_bits_ack; +- __u8 status_block_id; +- __u8 reserved0; +- __u16 attn_bits_index; +- __u32 reserved1; +-}; +- +-#define HC_SP_SB_MAX_INDICES 16 +- +-struct hc_sp_status_block { +- __u16 index_values[HC_SP_SB_MAX_INDICES]; +- __u16 running_index; +- __u16 rsrv; +- __u32 rsrv1; +-}; +- +-struct host_sp_status_block { +- struct atten_sp_status_block atten_status_block; +- struct hc_sp_status_block sp_sb; +-}; +- +-#define HC_SP_INDEX_ETH_ISCSI_CQ_CONS 5 +-#define HC_SP_INDEX_ETH_ISCSI_RX_CQ_CONS 1 +- +-/* +- * VLAN mode on TX BDs +- */ +-enum eth_tx_vlan_type { +- X_ETH_NO_VLAN = 0, +- X_ETH_OUTBAND_VLAN = 1, +- X_ETH_INBAND_VLAN = 2, +- X_ETH_FW_ADDED_VLAN = 3, +- MAX_ETH_TX_VLAN_TYPE +-}; +- +-/* TX Buffer descriptor */ +-struct eth_tx_bd_flags { +- __u8 as_bitfield; +-/* t6.X HSI */ +-#define ETH_TX_BD_FLAGS_IP_CSUM_T6X (0x1<<0) +-#define ETH_TX_BD_FLAGS_IP_CSUM_SHIFT_T6X 0 +-#define ETH_TX_BD_FLAGS_L4_CSUM_T6X (0x1<<1) +-#define ETH_TX_BD_FLAGS_L4_CSUM_SHIFT_T6X 1 +-#define ETH_TX_BD_FLAGS_VLAN_MODE_T6X (0x3<<2) +-#define ETH_TX_BD_FLAGS_VLAN_MODE_SHIFT_T6X 2 +-#define ETH_TX_BD_FLAGS_START_BD_T6X (0x1<<4) +-#define ETH_TX_BD_FLAGS_START_BD_SHIFT_T6X 4 +-#define ETH_TX_BD_FLAGS_IS_UDP_T6X (0x1<<5) +-#define ETH_TX_BD_FLAGS_IS_UDP_SHIFT_T6X 5 +-#define ETH_TX_BD_FLAGS_SW_LSO_T6X (0x1<<6) +-#define ETH_TX_BD_FLAGS_SW_LSO_SHIFT_T6X 6 +-#define ETH_TX_BD_FLAGS_IPV6_T6X (0x1<<7) +-#define ETH_TX_BD_FLAGS_IPV6_SHIFT_T6X 7 +- +-/* Legacy t5.2 HSI defines */ +-#define ETH_TX_BD_FLAGS_VLAN_TAG_T5X (0x1<<0) +-#define ETH_TX_BD_FLAGS_VLAN_TAG_SHIFT_T5X 0 +-#define ETH_TX_BD_FLAGS_IP_CSUM_T5X (0x1<<1) +-#define ETH_TX_BD_FLAGS_IP_CSUM_SHIFT_T5X 1 +-#define ETH_TX_BD_FLAGS_L4_CSUM_T5X (0x1<<2) +-#define ETH_TX_BD_FLAGS_L4_CSUM_SHIFT_T5X 2 +-#define ETH_TX_BD_FLAGS_END_BD_T5X (0x1<<3) +-#define ETH_TX_BD_FLAGS_END_BD_SHIFT_T5X 3 +-#define ETH_TX_BD_FLAGS_START_BD_T5X (0x1<<4) +-#define ETH_TX_BD_FLAGS_START_BD_SHIFT_T5X 4 +-#define ETH_TX_BD_FLAGS_HDR_POOL_T5X (0x1<<5) +-#define ETH_TX_BD_FLAGS_HDR_POOL_SHIFT_T5X 5 +-#define ETH_TX_BD_FLAGS_SW_LSO_T5X (0x1<<6) +-#define ETH_TX_BD_FLAGS_SW_LSO_SHIFT_T5X 6 +-#define ETH_TX_BD_FLAGS_IPV6_T5X (0x1<<7) +-#define ETH_TX_BD_FLAGS_IPV6_SHIFT_T5X 7 +-}; +- +-#define ETH_TX_BD_FLAGS_VLAN_TAG_T6X \ +- (X_ETH_OUTBAND_VLAN << ETH_TX_BD_FLAGS_VLAN_MODE_SHIFT_T6X) +- +-#define BNX2X_SET_TX_VLAN(bp, txbd, vlan_id) \ +- do { \ +- if (vlan_id) { \ +- (txbd)->vlan = vlan_id; \ +- (txbd)->bd_flags.as_bitfield |= \ +- (bp)->tx_vlan_tag_bit; \ +- } else { \ +- (txbd)->vlan = (bp)->tx_prod; \ +- (txbd)->bd_flags.as_bitfield &= \ +- ~(bp)->tx_vlan_tag_bit; \ +- } \ +- } while (0) +- +-struct eth_tx_start_bd { +- __u32 addr_lo; +- __u32 addr_hi; +- __u16 nbd; +- __u16 nbytes; +- __u16 vlan; +- struct eth_tx_bd_flags bd_flags; +- __u8 general_data; +-#define ETH_TX_START_BD_HDR_NBDS (0x3F<<0) +-#define ETH_TX_START_BD_HDR_NBDS_SHIFT 0 +-#define ETH_TX_START_BD_ETH_ADDR_TYPE (0x3<<6) +-#define ETH_TX_START_BD_ETH_ADDR_TYPE_SHIFT 6 +-}; +- +-struct eth_tx_bd { +- __u32 addr_lo; +- __u32 addr_hi; +- __u16 total_pkt_bytes; +- __u16 nbytes; +- __u8 reserved[4]; +-}; +- +-/* RX Buffer descriptor */ +-struct eth_rx_bd { +- __u32 addr_lo; +- __u32 addr_hi; +-}; +- +-struct ramrod_data { +- volatile __u32 data_lo; +- volatile __u32 data_hi; +-}; +- +-struct common_ramrod_eth_rx_cqe { +- volatile __u8 ramrod_type; +-#define COMMON_RAMROD_ETH_RX_CQE_TYPE (0x1<<0) +-#define COMMON_RAMROD_ETH_RX_CQE_TYPE_SHIFT 0 +-#define COMMON_RAMROD_ETH_RX_CQE_RESERVED0 (0x7F<<1) +-#define COMMON_RAMROD_ETH_RX_CQE_RESERVED0_SHIFT 1 +- volatile __u8 conn_type; +- volatile __u16 reserved1; +- volatile __u32 conn_and_cmd_data; +-#define COMMON_RAMROD_ETH_RX_CQE_CID (0xFFFFFF<<0) +-#define COMMON_RAMROD_ETH_RX_CQE_CID_SHIFT 0 +-#define COMMON_RAMROD_ETH_RX_CQE_CMD_ID (0xFF<<24) +-#define COMMON_RAMROD_ETH_RX_CQE_CMD_ID_SHIFT 24 +- struct ramrod_data protocol_data; +- __u32 reserved2[4]; +-}; +- +-struct common_ramrod_eth_rx_cqe_70 { +- volatile __u8 ramrod_type; +- volatile __u8 conn_type; +- volatile __u16 reserved1; +- volatile __u32 conn_and_cmd_data; +- struct ramrod_data protocol_data; +- __u32 echo; +- __u32 reserved2[11]; +-}; +- +-struct parsing_flags { +- volatile __u16 flags; +-}; +- +-struct eth_fast_path_rx_cqe { +- volatile __u8 type_error_flags; +-#define ETH_FAST_PATH_RX_CQE_TYPE (0x1<<0) +-#define ETH_FAST_PATH_RX_CQE_TYPE_SHIFT 0 +-#define ETH_FAST_PATH_RX_CQE_PHY_DECODE_ERR_FLG (0x1<<1) +-#define ETH_FAST_PATH_RX_CQE_PHY_DECODE_ERR_FLG_SHIFT 1 +-#define ETH_FAST_PATH_RX_CQE_IP_BAD_XSUM_FLG (0x1<<2) +-#define ETH_FAST_PATH_RX_CQE_IP_BAD_XSUM_FLG_SHIFT 2 +-#define ETH_FAST_PATH_RX_CQE_L4_BAD_XSUM_FLG (0x1<<3) +-#define ETH_FAST_PATH_RX_CQE_L4_BAD_XSUM_FLG_SHIFT 3 +-#define ETH_FAST_PATH_RX_CQE_START_FLG (0x1<<4) +-#define ETH_FAST_PATH_RX_CQE_START_FLG_SHIFT 4 +-#define ETH_FAST_PATH_RX_CQE_END_FLG (0x1<<5) +-#define ETH_FAST_PATH_RX_CQE_END_FLG_SHIFT 5 +-#define ETH_FAST_PATH_RX_CQE_RESERVED0 (0x3<<6) +-#define ETH_FAST_PATH_RX_CQE_RESERVED0_SHIFT 6 +- volatile __u8 status_flags; +-#define ETH_FAST_PATH_RX_CQE_RSS_HASH_TYPE (0x7<<0) +-#define ETH_FAST_PATH_RX_CQE_RSS_HASH_TYPE_SHIFT 0 +-#define ETH_FAST_PATH_RX_CQE_RSS_HASH_FLG (0x1<<3) +-#define ETH_FAST_PATH_RX_CQE_RSS_HASH_FLG_SHIFT 3 +-#define ETH_FAST_PATH_RX_CQE_BROADCAST_FLG (0x1<<4) +-#define ETH_FAST_PATH_RX_CQE_BROADCAST_FLG_SHIFT 4 +-#define ETH_FAST_PATH_RX_CQE_MAC_MATCH_FLG (0x1<<5) +-#define ETH_FAST_PATH_RX_CQE_MAC_MATCH_FLG_SHIFT 5 +-#define ETH_FAST_PATH_RX_CQE_IP_XSUM_NO_VALIDATION_FLG (0x1<<6) +-#define ETH_FAST_PATH_RX_CQE_IP_XSUM_NO_VALIDATION_FLG_SHIFT 6 +-#define ETH_FAST_PATH_RX_CQE_L4_XSUM_NO_VALIDATION_FLG (0x1<<7) +-#define ETH_FAST_PATH_RX_CQE_L4_XSUM_NO_VALIDATION_FLG_SHIFT 7 +- volatile __u8 placement_offset; +- volatile __u8 queue_index; +- volatile __u32 rss_hash_result; +- volatile __u16 vlan_tag; +- volatile __u16 pkt_len; +- volatile __u16 len_on_bd; +- struct parsing_flags pars_flags; +- volatile __u16 sgl[8]; +-}; +- +-union eth_sgl_or_raw_data { +- volatile __u16 sgl[8]; +- volatile __u32 raw_data[4]; +-}; +- +-struct eth_fast_path_rx_cqe_64 { +- volatile __u8 type_error_flags; +-#define ETH_FAST_PATH_RX_CQE_TYPE_64 (0x3<<0) +-#define ETH_FAST_PATH_RX_CQE_TYPE_SHIFT_64 0 +-#define ETH_FAST_PATH_RX_CQE_SGL_RAW_SEL (0x1<<2) +-#define ETH_FAST_PATH_RX_CQE_SGL_RAW_SEL_SHIFT 2 +-#define ETH_FAST_PATH_RX_CQE_PHY_DECODE_ERR_FLG_64 (0x1<<3) +-#define ETH_FAST_PATH_RX_CQE_PHY_DECODE_ERR_FLG_SHIFT_64 3 +-#define ETH_FAST_PATH_RX_CQE_IP_BAD_XSUM_FLG_64 (0x1<<4) +-#define ETH_FAST_PATH_RX_CQE_IP_BAD_XSUM_FLG_SHIFT_64 4 +-#define ETH_FAST_PATH_RX_CQE_L4_BAD_XSUM_FLG_64 (0x1<<5) +-#define ETH_FAST_PATH_RX_CQE_L4_BAD_XSUM_FLG_SHIFT_64 5 +-#define ETH_FAST_PATH_RX_CQE_RESERVED0_64 (0x3<<6) +-#define ETH_FAST_PATH_RX_CQE_RESERVED0_SHIFT_64 6 +- volatile __u8 status_flags; +-#define ETH_FAST_PATH_RX_CQE_RSS_HASH_TYPE (0x7<<0) +-#define ETH_FAST_PATH_RX_CQE_RSS_HASH_TYPE_SHIFT 0 +-#define ETH_FAST_PATH_RX_CQE_RSS_HASH_FLG (0x1<<3) +-#define ETH_FAST_PATH_RX_CQE_RSS_HASH_FLG_SHIFT 3 +-#define ETH_FAST_PATH_RX_CQE_BROADCAST_FLG (0x1<<4) +-#define ETH_FAST_PATH_RX_CQE_BROADCAST_FLG_SHIFT 4 +-#define ETH_FAST_PATH_RX_CQE_MAC_MATCH_FLG (0x1<<5) +-#define ETH_FAST_PATH_RX_CQE_MAC_MATCH_FLG_SHIFT 5 +-#define ETH_FAST_PATH_RX_CQE_IP_XSUM_NO_VALIDATION_FLG (0x1<<6) +-#define ETH_FAST_PATH_RX_CQE_IP_XSUM_NO_VALIDATION_FLG_SHIFT 6 +-#define ETH_FAST_PATH_RX_CQE_L4_XSUM_NO_VALIDATION_FLG (0x1<<7) +-#define ETH_FAST_PATH_RX_CQE_L4_XSUM_NO_VALIDATION_FLG_SHIFT 7 +- volatile __u8 queue_index; +- volatile __u8 placement_offset; +- volatile __u32 rss_hash_result; +- volatile __u16 vlan_tag; +- volatile __u16 pkt_len; +- volatile __u16 len_on_bd; +- struct parsing_flags pars_flags; +- union eth_sgl_or_raw_data sgl_or_raw_data; +-}; +- +-struct eth_fast_path_rx_cqe_70 { +- volatile __u8 type_error_flags; +- volatile __u8 status_flags; +- volatile __u8 queue_index; +- volatile __u8 placement_offset; +- volatile __u32 rss_hash_result; +- volatile __u16 vlan_tag; +- volatile __u16 pkt_len; +- volatile __u16 len_on_bd; +- struct parsing_flags pars_flags; +- union eth_sgl_or_raw_data sgl_or_raw_data; +- __u32 reserved1[8]; +-}; +- +-struct eth_rx_cqe_next_page { +- __u32 addr_lo; +- __u32 addr_hi; +- __u32 reserved[6]; +-}; +- +-struct eth_rx_cqe_next_page_70 { +- __u32 addr_lo; +- __u32 addr_hi; +- __u32 reserved[14]; +-}; +- +-union eth_rx_cqe { +- struct eth_fast_path_rx_cqe fast_path_cqe; +- struct eth_fast_path_rx_cqe_64 fast_path_cqe_64; +- struct common_ramrod_eth_rx_cqe ramrod_cqe; +- struct eth_rx_cqe_next_page next_page_cqe; +-}; +- +-union eth_rx_cqe_70 { +- struct eth_fast_path_rx_cqe_70 fast_path_cqe_70; +- struct common_ramrod_eth_rx_cqe_70 ramrod_cqe_70; +- struct eth_rx_cqe_next_page_70 next_page_cqe_70; +-}; +- +-struct uio_init_data { +- __u32 cid; +- __u32 tx_db_off; +- __u32 cid_override_key; +-#define UIO_USE_TX_DOORBELL 0x017855DB +-}; +- +-struct client_init_general_data { +- __u8 client_id; +- __u8 statistics_counter_id; +- __u8 statistics_en_flg; +- __u8 is_fcoe_flg; +- __u8 activate_flg; +- __u8 sp_client_id; +- __u16 mtu; +- __u8 statistics_zero_flg; +- __u8 func_id; +- __u8 cos; +- __u8 traffic_type; +- struct uio_init_data uid; +-}; +- +-/****************************************************************************** +- * BNX2X Registers and HSI +- ******************************************************************************/ +-#define BNX2X_BAR_SIZE 0x500000 +-#define BNX2X_BAR2_SIZE 0x12000 +- +-#define BNX2X_CHIP_ID(bp) (bp->chip_id & 0xfffffff0) +- +-#define PORT_MAX 2 +- +-/* [R 4] This field indicates the type of the device. '0' - 2 Ports; '1' - 1 +- * Port. */ +-#define BNX2X_MISC_REG_BOND_ID 0xa400 +-/* [R 8] These bits indicate the metal revision of the chip. This value +- * starts at 0x00 for each all-layer tape-out and increments by one for each +- * tape-out. */ +-#define BNX2X_MISC_REG_CHIP_METAL 0xa404 +-/* [R 16] These bits indicate the part number for the chip. */ +-#define BNX2X_MISC_REG_CHIP_NUM 0xa408 +-/* [R 4] These bits indicate the base revision of the chip. This value +- * starts at 0x0 for the A0 tape-out and increments by one for each +- * all-layer tape-out. */ +-#define BNX2X_MISC_REG_CHIP_REV 0xa40c +- +-/* From the bnx2x driver */ +-#define CHIP_NUM(bp) (bp->chip_id >> 16) +-#define CHIP_NUM_57710 0x164e +-#define CHIP_NUM_57711 0x164f +-#define CHIP_NUM_57711E 0x1650 +-#define CHIP_NUM_57712 0x1662 +-#define CHIP_NUM_57712_MF 0x1663 +-#define CHIP_NUM_57712_VF 0x166f +-#define CHIP_NUM_57713 0x1651 +-#define CHIP_NUM_57713E 0x1652 +-#define CHIP_NUM_57800 0x168a +-#define CHIP_NUM_57800_MF 0x16a5 +-#define CHIP_NUM_57800_VF 0x16a9 +-#define CHIP_NUM_57810 0x168e +-#define CHIP_NUM_57810_MF 0x16ae +-#define CHIP_NUM_57810_VF 0x16af +-#define CHIP_NUM_57811 0x163d +-#define CHIP_NUM_57811_MF 0x163e +-#define CHIP_NUM_57811_VF 0x163f +-#define CHIP_NUM_57840_OBSOLETE 0x168d +-#define CHIP_NUM_57840_MF_OBSOLETE 0x16ab +-#define CHIP_NUM_57840_4_10 0x16a1 +-#define CHIP_NUM_57840_2_20 0x16a2 +-#define CHIP_NUM_57840_MF 0x16a4 +-#define CHIP_NUM_57840_VF 0x16ad +- +-#define CHIP_IS_E1(bp) (CHIP_NUM(bp) == CHIP_NUM_57710) +-#define CHIP_IS_57711(bp) (CHIP_NUM(bp) == CHIP_NUM_57711) +-#define CHIP_IS_57711E(bp) (CHIP_NUM(bp) == CHIP_NUM_57711E) +-#define CHIP_IS_57712(bp) (CHIP_NUM(bp) == CHIP_NUM_57712) +-#define CHIP_IS_57712_VF(bp) (CHIP_NUM(bp) == CHIP_NUM_57712_VF) +-#define CHIP_IS_57712_MF(bp) (CHIP_NUM(bp) == CHIP_NUM_57712_MF) +-#define CHIP_IS_57800(bp) (CHIP_NUM(bp) == CHIP_NUM_57800) +-#define CHIP_IS_57800_VF(bp) (CHIP_NUM(bp) == CHIP_NUM_57800_MF) +-#define CHIP_IS_57800_MF(bp) (CHIP_NUM(bp) == CHIP_NUM_57800_VF) +-#define CHIP_IS_57810(bp) (CHIP_NUM(bp) == CHIP_NUM_57810) +-#define CHIP_IS_57810_VF(bp) (CHIP_NUM(bp) == CHIP_NUM_57810_MF) +-#define CHIP_IS_57810_MF(bp) (CHIP_NUM(bp) == CHIP_NUM_57810_VF) +-#define CHIP_IS_57811(bp) (CHIP_NUM(bp) == CHIP_NUM_57811) +-#define CHIP_IS_57811_VF(bp) (CHIP_NUM(bp) == CHIP_NUM_57811_MF) +-#define CHIP_IS_57811_MF(bp) (CHIP_NUM(bp) == CHIP_NUM_57811_VF) +- +-#define CHIP_IS_57840(bp) \ +- ((CHIP_NUM(bp) == CHIP_NUM_57840_4_10) || \ +- (CHIP_NUM(bp) == CHIP_NUM_57840_2_20) || \ +- (CHIP_NUM(bp) == CHIP_NUM_57840_OBSOLETE)) +-#define CHIP_IS_57840_MF(bp) ((CHIP_NUM(bp) == CHIP_NUM_57840_MF) || \ +- (CHIP_NUM(bp) == CHIP_NUM_57840_MF_OBSOLETE)) +-#define CHIP_IS_57840_VF(bp) (CHIP_NUM(bp) == CHIP_NUM_57840_VF) +-#define CHIP_IS_E1H(bp) (CHIP_IS_57711(bp) || \ +- CHIP_IS_57711E(bp)) +- +-#define CHIP_IS_E2(bp) (CHIP_IS_57712(bp) || \ +- CHIP_IS_57712_MF(bp) || \ +- CHIP_IS_57712_VF(bp)) +-#define CHIP_IS_E3(bp) (CHIP_IS_57800(bp) || \ +- CHIP_IS_57800_MF(bp) || \ +- CHIP_IS_57800_VF(bp) || \ +- CHIP_IS_57810(bp) || \ +- CHIP_IS_57810_MF(bp) || \ +- CHIP_IS_57810_VF(bp) || \ +- CHIP_IS_57840(bp) || \ +- CHIP_IS_57840_MF(bp) || \ +- CHIP_IS_57840_VF(bp) || \ +- CHIP_IS_57811(bp) || \ +- CHIP_IS_57811_MF(bp) || \ +- CHIP_IS_57811_VF(bp)) +- +-#define CHIP_IS_E1x(bp) (CHIP_IS_E1((bp)) || CHIP_IS_E1H((bp))) +-#define USES_WARPCORE(bp) (CHIP_IS_E3(bp)) +-#define IS_E1H_OFFSET (!CHIP_IS_E1H(bp)) +-/* End of From the bnx2x driver */ +- +-#define CHIP_IS_E2_PLUS(bp) (CHIP_IS_E2(bp) || CHIP_IS_E3(bp)) +- +-#define MISC_REG_SHARED_MEM_ADDR 0xa2b4 +- +-#define MISC_REG_BOND_ID 0xa400 +-#define MISC_REG_CHIP_METAL 0xa404 +-#define MISC_REG_CHIP_NUM 0xa408 +-#define MISC_REG_CHIP_REV 0xa40c +- +-#define MISC_REG_PORT4MODE_EN 0xa750 +-#define MISC_REG_PORT4MODE_EN_OVWR 0xa720 +- +-#define MISC_REG_GENERIC_CR_0 0xa460 +-#define MISC_REG_GENERIC_CR_1 0xa464 +- +-#define BAR_USTRORM_INTMEM 0x400000 +-#define BAR_CSTRORM_INTMEM 0x410000 +-#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<iro[bp->iro_idx]) +- +-#define USTORM_RX_PRODS_E1X_OFFSET(port, client_id) \ +- (IRO_ENT.base + ((port) * IRO_ENT.m1) + ((client_id) * IRO_ENT.m2)) +- +-#define USTORM_RX_PRODS_E2_OFFSET(qzone_id) \ +- (IRO_ENT.base + ((qzone_id) * IRO_ENT.m1)) +- +-#define ETH_MAX_RX_CLIENTS_E1H 28 +-#define ETH_MAX_RX_CLIENTS_E2 28 +- +-#define BNX2X_CL_QZONE_ID(bp, cli) \ +- (cli + (bp->port * (CHIP_IS_E2(bp) ? \ +- ETH_MAX_RX_CLIENTS_E2 : \ +- ETH_MAX_RX_CLIENTS_E1H))) +- +-#define BNX2X_CL_QZONE_ID_64(bp, cli) \ +- (CHIP_IS_E2_PLUS(bp) ? (cli) : \ +- (cli + (bp->port * ETH_MAX_RX_CLIENTS_E1H))) +- +-#define BNX2X_PATH(bp) (!CHIP_IS_E2_PLUS(bp) ? 0 : (bp)->func & 1) +- +-#define SHMEM_P0_ISCSI_MAC_UPPER 0x4c +-#define SHMEM_P0_ISCSI_MAC_LOWER 0x50 +-#define SHMEM_P1_ISCSI_MAC_UPPER 0x1dc +-#define SHMEM_P1_ISCSI_MAC_LOWER 0x1e0 +- +-#define SHMEM_ISCSI_MAC_UPPER(bp) \ +- (((bp)->port == 0) ? \ +- SHMEM_P0_ISCSI_MAC_UPPER : SHMEM_P1_ISCSI_MAC_UPPER) +- +-#define SHMEM_ISCSI_MAC_LOWER(bp) \ +- (((bp)->port == 0) ? \ +- SHMEM_P0_ISCSI_MAC_LOWER : SHMEM_P1_ISCSI_MAC_LOWER) +- +-#define BNX2X_RCQ_DESC_CNT (4096 / sizeof(union eth_rx_cqe)) +-#define BNX2X_RCQ_DESC_CNT_70 (4096 / sizeof(union eth_rx_cqe_70)) +-#define BNX2X_MAX_RCQ_DESC_CNT(bp) \ +- ((bnx2x_is_ver70(bp) ? BNX2X_RCQ_DESC_CNT_70 : BNX2X_RCQ_DESC_CNT) - 1) +- +-#define BNX2X_RX_DESC_CNT (4096 / sizeof(struct eth_rx_bd)) +-#define BNX2X_MAX_RX_DESC_CNT (BNX2X_RX_DESC_CNT - 2) +-#define BNX2X_NUM_RX_BD (BNX2X_RX_DESC_CNT * 1) +-#define BNX2X_MAX_RX_BD (BNX2X_NUM_RX_BD - 1) +- +-#define BNX2X_TX_DESC_CNT (4096 / sizeof(struct eth_tx_start_bd)) +-#define BNX2X_MAX_TX_DESC_CNT (BNX2X_TX_DESC_CNT - 1) +- +-#define BNX2X_NEXT_RX_IDX(x) ((((x) & (BNX2X_RX_DESC_CNT - 1)) == \ +- (BNX2X_MAX_RX_DESC_CNT - 1)) ? \ +- (x) + 3 : (x) + 1) +- +-#define BNX2X_NEXT_RCQ_IDX(bp, x) \ +- ((((x) & BNX2X_MAX_RCQ_DESC_CNT(bp)) == \ +- (BNX2X_MAX_RCQ_DESC_CNT(bp) - 1)) ? (x) + 2 : (x) + 1) +-#define BNX2X_RX_BD(x) ((x) & BNX2X_MAX_RX_BD) +- +-#define BNX2X_NEXT_TX_BD(x) ((((x) & (BNX2X_MAX_TX_DESC_CNT - 1)) == \ +- (BNX2X_MAX_TX_DESC_CNT - 1)) ? \ +- (x) + 2 : (x) + 1) +- +-#define BNX2X_TX_RING_IDX(x) ((x) & BNX2X_MAX_TX_DESC_CNT) +- +-struct ustorm_eth_rx_producers { +- __u16 cqe_prod; +- __u16 bd_prod; +- __u16 sge_prod; +- __u16 reserved; +-}; +- +-#define BNX2X_DEFAULT_MAJOR_VERSION 1 +-#define BNX2X_DEFAULT_MINOR_VERSION 70 +-#define BNX2X_DEFAULT_SUB_MINOR_VERSION 1 +-#define BNX2X_UNKNOWN_MAJOR_VERSION -1 +-#define BNX2X_UNKNOWN_MINOR_VERSION -1 +-#define BNX2X_UNKNOWN_SUB_MINOR_VERSION -1 +-struct bnx2x_driver_version { +- uint16_t major; +- uint16_t minor; +- uint16_t sub_minor; +-}; +- +-typedef struct bnx2x { +- nic_t *parent; +- +- struct bnx2x_driver_version version; +- +- uint16_t flags; +-#define CNIC_UIO_UNITIALIZED 0x0001 +-#define CNIC_UIO_INITIALIZED 0x0002 +-#define CNIC_UIO_ENABLED 0x0004 +-#define CNIC_UIO_DISABLED 0x0008 +-#define CNIC_UIO_IPv6_ENABLED 0x0010 +-#define CNIC_UIO_ADDED_MULICAST 0x0020 +-#define CNIC_UIO_MSIX_ENABLED 0x0200 +-#define CNIC_UIO_TX_HAS_SENT 0x0400 +-#define BNX2X_OPENED 0x0800 +- +- void *reg; /* Pointer to the BAR1 mapped registers */ +- void *reg2; /* Pointer to the BAR2 mapped registers */ +- +- int bar0_fd; +- int bar2_fd; +- +- __u32 chip_id; +- __u32 shmem_base; +- __u32 shmem_base2; +- int func; +- int port; +- int pfid; +- __u32 cid; +- __u32 client_id; +- +- struct iro *iro; +- int iro_idx; +- +- __u32 tx_doorbell; +- +- __u16 tx_prod; +- __u16 tx_bd_prod; +- __u16 tx_cons; +- __u8 tx_vlan_tag_bit; +- +- __u32 rx_prod_io; +- +- __u16 rx_prod; +- __u16 rx_bd_prod; +- __u16 rx_cons; +- __u16 rx_bd_cons; +- __u16 rx_hw_prod; +- +- __u16(*get_rx_cons) (struct bnx2x *); +- __u16(*get_tx_cons) (struct bnx2x *); +- +- /* RX ring parameters */ +- uint32_t rx_ring_size; +- uint32_t rx_buffer_size; +- +- void *bufs; /* Pointer to the mapped buffer space */ +- +- /* Hardware Status Block locations */ +- void *sblk_map; +- union { +- struct host_def_status_block *def; +- struct host_sp_status_block *sp; +- } status_blk; +- +- int status_blk_size; +- +- uint16_t rx_index; +- union { +- union eth_rx_cqe *cqe; +- union eth_rx_cqe_70 *cqe70; +- } rx_comp_ring; +- void **rx_pkt_ring; +- +- struct eth_tx_start_bd *tx_ring; +- void *tx_pkt; +- +-} bnx2x_t; +- +-/****************************************************************************** +- * bnx2x Function Declarations +- ******************************************************************************/ +-void bnx2x_start_xmit(nic_t *nic, size_t len, u16_t vlan_id); +- +-struct nic_ops *bnx2x_get_ops(); +-#endif /* __BNX2X_H__ */ +diff --git a/iscsiuio/src/unix/libs/cnic.c b/iscsiuio/src/unix/libs/cnic.c +deleted file mode 100644 +index 9cdf933..0000000 +--- a/iscsiuio/src/unix/libs/cnic.c ++++ /dev/null +@@ -1,671 +0,0 @@ +-/* +- * Copyright (c) 2009-2011, Broadcom Corporation +- * Copyright (c) 2014, QLogic Corporation +- * +- * Written by: Benjamin Li (benli@broadcom.com) +- * +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. All advertising materials mentioning features or use of this software +- * must display the following acknowledgement: +- * This product includes software developed by Adam Dunkels. +- * 4. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * cnic.c - CNIC UIO uIP user space stack +- * +- */ +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include "uip_arp.h" +-#include "nic.h" +-#include "nic_utils.h" +-#include "logger.h" +-#include "options.h" +- +-#include "cnic.h" +-#include "iscsi_if.h" +-#include "ipv6_ndpc.h" +-#include "qedi.h" +- +-/******************************************************************************* +- * Constants +- ******************************************************************************/ +-#define PFX "CNIC " +- +-/******************************************************************************* +- * Constants shared between the bnx2 and bnx2x modules +- ******************************************************************************/ +-const char bnx2i_library_transport_name[] = "bnx2i"; +-const size_t bnx2i_library_transport_name_size = +- sizeof(bnx2i_library_transport_name); +- +-/******************************************************************************* +- * Constants for qedi module +- ******************************************************************************/ +-const char qedi_library_transport_name[] = "qedi"; +-const size_t qedi_library_transport_name_size = +- sizeof(qedi_library_transport_name); +- +-/****************************************************************************** +- * Netlink Functions +- ******************************************************************************/ +- +-static int cnic_arp_send(nic_t *nic, nic_interface_t *nic_iface, int fd, +- __u8 *mac_addr, __u32 ip_addr, char *addr_str) +-{ +- struct ether_header *eth; +- struct ether_arp *arp; +- __u32 dst_ip = ip_addr; +- int pkt_size = sizeof(*eth) + sizeof(*arp); +- int rc; +- struct in_addr addr; +- static const uint8_t multicast_mac[] = { +- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; +- +- LOG_DEBUG(PFX "%s: host:%d - try getting xmit mutex cnic arp send", +- nic->log_name, nic->host_no); +- rc = pthread_mutex_trylock(&nic->xmit_mutex); +- if (rc != 0) { +- LOG_DEBUG(PFX "%s: could not get xmit_mutex", nic->log_name); +- return -EAGAIN; +- } +- +- eth = (*nic->ops->get_tx_pkt) (nic); +- if (eth == NULL) { +- LOG_WARN(PFX "%s: couldn't get tx packet", nic->log_name); +- pthread_mutex_unlock(&nic->xmit_mutex); +- return -EAGAIN; +- } +- +- nic_fill_ethernet_header(nic_iface, eth, +- nic->mac_addr, (void *)multicast_mac, +- &pkt_size, (void *)&arp, ETHERTYPE_ARP); +- +- arp->arp_hrd = htons(ARPHRD_ETHER); +- arp->arp_pro = htons(ETHERTYPE_IP); +- arp->arp_hln = ETH_ALEN; +- arp->arp_pln = 4; +- arp->arp_op = htons(ARPOP_REQUEST); +- memcpy(arp->arp_sha, nic->mac_addr, ETH_ALEN); +- memset(arp->arp_tha, 0, ETH_ALEN); +- +- /* Copy the IP address's into the ARP response */ +- memcpy(arp->arp_spa, nic_iface->ustack.hostaddr, 4); +- 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)); +- LOG_DEBUG(PFX "%s: Sent cnic arp request for IP: %s", +- nic->log_name, addr_str); +- pthread_mutex_unlock(&nic->xmit_mutex); +- +- return 0; +-} +- +-static int cnic_neigh_soliciation_send(nic_t *nic, +- nic_interface_t *nic_iface, int fd, +- __u8 *mac_addr, +- struct in6_addr *addr6_dst, +- char *addr_str) +-{ +- struct ether_header *eth; +- struct ip6_hdr *ipv6_hdr; +- int rc, pkt_size; +- char buf[INET6_ADDRSTRLEN]; +- struct ndpc_reqptr req_ptr; +- +- rc = pthread_mutex_trylock(&nic->xmit_mutex); +- if (rc != 0) { +- LOG_WARN(PFX "%s: could not get xmit_mutex", nic->log_name); +- return -EAGAIN; +- } +- +- /* Build the ethernet header */ +- eth = (*nic->ops->get_tx_pkt) (nic); +- if (eth == NULL) { +- LOG_WARN(PFX "%s: couldn't get tx packet", nic->log_name); +- return -EAGAIN; +- } +- +- /* Copy the requested target address to the ipv6.dst */ +- ipv6_hdr = +- (struct ip6_hdr *)((u8_t *) eth + sizeof(struct ether_header)); +- +- memcpy(ipv6_hdr->ip6_dst.s6_addr, addr6_dst->s6_addr, +- sizeof(struct in6_addr)); +- +- 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; +- req_ptr.ipv6 = (void *)ipv6_hdr; +- if (ndpc_request(&nic_iface->ustack, &req_ptr, &pkt_size, +- NEIGHBOR_SOLICIT)) +- return -EAGAIN; +- +- /* Debug to print out the pkt context */ +- inet_ntop(AF_INET6, ipv6_hdr->ip6_dst.s6_addr, buf, sizeof(buf)); +- LOG_DEBUG(PFX "%s: ipv6 dst addr: %s", nic->log_name, buf); +- LOG_DEBUG(PFX "neighbor sol content " +- "dst mac %02x:%02x:%02x:%02x:%02x:%02x", +- eth->ether_dhost[0], eth->ether_dhost[1], +- eth->ether_dhost[2], eth->ether_dhost[3], +- eth->ether_dhost[4], eth->ether_dhost[5]); +- LOG_DEBUG(PFX "src mac %02x:%02x:%02x:%02x:%02x:%02x", +- eth->ether_shost[0], eth->ether_shost[1], +- 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", +- nic->log_name, addr_str); +- +- pthread_mutex_unlock(&nic->xmit_mutex); +- +- return 0; +-} +- +-static int cnic_nl_neigh_rsp(nic_t *nic, int fd, +- struct iscsi_uevent *ev, +- struct iscsi_path *path_req, +- __u8 *mac_addr, +- nic_interface_t *nic_iface, int status, int type) +-{ +- int rc; +- uint8_t *ret_buf; +- struct iscsi_uevent *ret_ev; +- struct iscsi_path *path_rsp; +- struct sockaddr_nl dest_addr; +- char addr_dst_str[INET6_ADDRSTRLEN]; +- +- memset(&dest_addr, 0, sizeof(dest_addr)); +- dest_addr.nl_family = AF_NETLINK; +- dest_addr.nl_pid = 0; +- dest_addr.nl_groups = 0; /* unicast */ +- +- ret_buf = calloc(1, NLMSG_SPACE(sizeof(struct iscsi_uevent) + 256)); +- if (ret_buf == NULL) { +- LOG_ERR(PFX "Could not allocate memory for path req resposne"); +- return -ENOMEM; +- } +- +- memset(ret_buf, 0, NLMSG_SPACE(sizeof(struct iscsi_uevent) + 256)); +- +- /* prepare the iscsi_uevent buffer */ +- ret_ev = (struct iscsi_uevent *)ret_buf; +- ret_ev->type = ISCSI_UEVENT_PATH_UPDATE; +- ret_ev->transport_handle = ev->transport_handle; +- ret_ev->u.set_path.host_no = ev->r.req_path.host_no; +- +- /* Prepare the iscsi_path buffer */ +- path_rsp = (struct iscsi_path *)(ret_buf + sizeof(*ret_ev)); +- path_rsp->handle = path_req->handle; +- if (type == AF_INET) { +- path_rsp->ip_addr_len = 4; +- memcpy(&path_rsp->src.v4_addr, nic_iface->ustack.hostaddr, +- sizeof(nic_iface->ustack.hostaddr)); +- +- inet_ntop(AF_INET, &path_rsp->src.v4_addr, +- addr_dst_str, sizeof(addr_dst_str)); +- } else { +- u8_t *src_ipv6; +- int ret; +- +- /* 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 */ +- if (ndpc_request(&nic_iface->ustack, &path_req->dst.v6_addr, +- &ret, CHECK_LINK_LOCAL_ADDR)) { +- src_ipv6 = (u8_t *)all_zeroes_addr6; +- LOG_DEBUG(PFX "RSP Check LL failed"); +- goto src_done; +- } +- if (ret) { +- /* Get link local IPv6 address */ +- src_ipv6 = (u8_t *)&nic_iface->ustack.linklocal6; +- } else { +- if (ndpc_request(&nic_iface->ustack, +- &path_req->dst.v6_addr, +- &src_ipv6, GET_HOST_ADDR)) { +- src_ipv6 = (u8_t *)all_zeroes_addr6; +- LOG_DEBUG(PFX "RSP Get host addr failed"); +- } +- if (src_ipv6 == NULL) { +- src_ipv6 = (u8_t *)all_zeroes_addr6; +- LOG_DEBUG(PFX "RSP no Best matched addr found"); +- } +- } +-src_done: +- path_rsp->ip_addr_len = 16; +- memcpy(&path_rsp->src.v6_addr, src_ipv6, +- sizeof(nic_iface->ustack.hostaddr6)); +- +- inet_ntop(AF_INET6, &path_rsp->src.v6_addr, +- addr_dst_str, sizeof(addr_dst_str)); +- } +- memcpy(path_rsp->mac_addr, mac_addr, 6); +- 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 with vlan %d", +- addr_dst_str, +- mac_addr[0], mac_addr[1], +- 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); +- } +- +- free(ret_buf); +- +- return rc; +-} +- +-static const struct timeval tp_wait = { +- .tv_sec = 0, +- .tv_usec = 250000, +-}; +- +-/** +- * cnic_handle_ipv4_iscsi_path_req() - This function will handle the IPv4 +- * path req calls the bnx2i kernel module +- * @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 +- */ +-int cnic_handle_ipv4_iscsi_path_req(nic_t *nic, int fd, +- struct iscsi_uevent *ev, +- struct iscsi_path *path, +- nic_interface_t *nic_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; +-#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)); +- +- if (nic_iface->ustack.netmask[0] | nic_iface->ustack.netmask[1]) +- memcpy(&netmask.s_addr, nic_iface->ustack.netmask, +- sizeof(src_addr)); +- else +- netmask.s_addr = calculate_default_netmask(dst_addr.s_addr); +- +- src_matching_addr.s_addr = src_addr.s_addr & netmask.s_addr; +- dst_matching_addr.s_addr = dst_addr.s_addr & netmask.s_addr; +- +- LOG_DEBUG(PFX "%s: src=%s", nic->log_name, inet_ntoa(src_addr)); +- LOG_DEBUG(PFX "%s: dst=%s", nic->log_name, inet_ntoa(dst_addr)); +- LOG_DEBUG(PFX "%s: nm=%s", nic->log_name, inet_ntoa(netmask)); +- if (src_matching_addr.s_addr != dst_matching_addr.s_addr) { +- /* If there is an assigned gateway address then use it +- * if the source address doesn't match */ +- if (nic_iface->ustack.default_route_addr[0] | +- nic_iface->ustack.default_route_addr[1]) { +- memcpy(&dst_addr, +- &nic_iface->ustack.default_route_addr, +- sizeof(dst_addr)); +- } else { +- LOG_DEBUG(PFX "%s: no default route address", +- nic->log_name); +- } +- } +- arp_retry = 0; +- +- rc = uip_lookup_arp_entry(dst_addr.s_addr, mac_addr); +- if (rc != 0) { +- while ((arp_retry < MAX_ARP_RETRY) && (event_loop_stop == 0)) { +- char *dst_addr_str; +- int count; +- struct timespec ts; +- struct timeval tp; +- struct timeval tp_abs; +- +- dst_addr_str = inet_ntoa(dst_addr); +- +- LOG_INFO(PFX "%s: Didn't find IPv4: '%s' in ARP table", +- nic->log_name, dst_addr_str); +- rc = cnic_arp_send(nic, nic_iface, fd, +- mac_addr, +- dst_addr.s_addr, dst_addr_str); +- if (rc != 0) { +- status = -EIO; +- goto done; +- } +- +- for (count = 0; count < 8; count++) { +- /* Convert from timeval to timespec */ +- rc = gettimeofday(&tp, NULL); +- +- timeradd(&tp, &tp_wait, &tp_abs); +- +- ts.tv_sec = tp_abs.tv_sec; +- ts.tv_nsec = tp_abs.tv_usec * 1000; +- +- /* Wait 1s for if_down */ +- pthread_mutex_lock(&nic->nl_process_mutex); +- rc = pthread_cond_timedwait +- (&nic->nl_process_if_down_cond, +- &nic->nl_process_mutex, &ts); +- +- if (rc == ETIMEDOUT) { +- pthread_mutex_unlock +- (&nic->nl_process_mutex); +- +- rc = uip_lookup_arp_entry(dst_addr. +- s_addr, +- mac_addr); +- if (rc == 0) +- goto done; +- } else { +- nic->nl_process_if_down = 0; +- pthread_mutex_unlock +- (&nic->nl_process_mutex); +- +- arp_retry = MAX_ARP_RETRY; +- goto done; +- +- } +- } +- +- arp_retry++; +- } +- } +- +-done: +- +- if (arp_retry >= MAX_ARP_RETRY) { +- status = -EIO; +- rc = -EIO; +- } +- +- if (ev) { +- cnic_nl_neigh_rsp(nic, fd, ev, path, mac_addr, +- nic_iface, status, AF_INET); +- } +- +- return rc; +-} +- +-/** +- * cnic_handle_ipv6_iscsi_path_req() - This function will handle the IPv4 +- * path req calls the bnx2i kernel module +- * @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 +- */ +-int cnic_handle_ipv6_iscsi_path_req(nic_t *nic, int fd, +- struct iscsi_uevent *ev, +- struct iscsi_path *path, +- nic_interface_t *nic_iface) +-{ +- __u8 mac_addr[6]; +- int rc, i; +- uint16_t neighbor_retry; +- int status = 0; +- char addr_dst_str[INET6_ADDRSTRLEN]; +- struct in6_addr src_addr, dst_addr, +- src_matching_addr, dst_matching_addr, netmask; +- struct in6_addr *addr; +- struct ndpc_reqptr req_ptr; +- +- memset(mac_addr, 0, sizeof(mac_addr)); +- +- inet_ntop(AF_INET6, &path->dst.v6_addr, +- addr_dst_str, sizeof(addr_dst_str)); +- +- /* 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 */ +- memcpy(&dst_addr, &path->dst.v6_addr, sizeof(struct in6_addr)); +- if (ndpc_request(&nic_iface->ustack, &dst_addr, +- &rc, CHECK_LINK_LOCAL_ADDR)) { +- neighbor_retry = MAX_ARP_RETRY; +- LOG_DEBUG(PFX "Check LL failed"); +- goto done; +- } +- if (rc) { +- LOG_DEBUG(PFX "Use LL"); +- /* Get link local IPv6 address */ +- addr = (struct in6_addr *)&nic_iface->ustack.linklocal6; +- } else { +- LOG_DEBUG(PFX "Use Best matched"); +- if (ndpc_request(&nic_iface->ustack, +- &dst_addr, +- &addr, GET_HOST_ADDR)) { +- neighbor_retry = MAX_ARP_RETRY; +- LOG_DEBUG(PFX "Use Best matched failed"); +- goto done; +- } +- if (addr == NULL) { +- neighbor_retry = MAX_ARP_RETRY; +- LOG_DEBUG(PFX "No Best matched found"); +- goto done; +- } +- } +- /* Got the best matched src IP address */ +- memcpy(&src_addr, addr, sizeof(struct in6_addr)); +- +- if (nic_iface->ustack.netmask6[0] | nic_iface->ustack.netmask6[1] | +- nic_iface->ustack.netmask6[2] | nic_iface->ustack.netmask6[3] | +- nic_iface->ustack.netmask6[4] | nic_iface->ustack.netmask6[5] | +- nic_iface->ustack.netmask6[6] | nic_iface->ustack.netmask6[7]) +- memcpy(&netmask.s6_addr, nic_iface->ustack.netmask6, +- sizeof(struct in6_addr)); +- else +- memcpy(&netmask.s6_addr, all_zeroes_addr6, +- sizeof(struct in6_addr)); +- +- 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] & +- netmask.s6_addr32[i]; +- dst_matching_addr.s6_addr32[i] = dst_addr.s6_addr32[i] & +- netmask.s6_addr32[i]; +- if (src_matching_addr.s6_addr32[i] != +- dst_matching_addr.s6_addr32[i]) { +- /* No match with the prefix mask, use default route */ +- 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; +- } +- } +- } +- +-#define MAX_ARP_RETRY 4 +- neighbor_retry = 0; +- +- req_ptr.eth = (void *)mac_addr; +- req_ptr.ipv6 = (void *)&dst_addr; +- if (ndpc_request(&nic_iface->ustack, &req_ptr, &rc, CHECK_ARP_TABLE)) { +- /* ndpc request failed, skip neighbor solicit send */ +- neighbor_retry = MAX_ARP_RETRY; +- 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); +- while ((neighbor_retry < MAX_ARP_RETRY) +- && (event_loop_stop == 0)) { +- int count; +- struct timespec ts; +- struct timeval tp; +- struct timeval tp_abs; +- +- LOG_INFO(PFX "%s: Didn't find IPv6: '%s'\n", +- nic->log_name, addr_dst_str); +- +- rc = cnic_neigh_soliciation_send(nic, nic_iface, fd, +- mac_addr, +- &dst_addr, +- addr_dst_str); +- if (rc != 0) { +- status = -EIO; +- goto done; +- } +- +- for (count = 0; count < 8; count++) { +- /* Convert from timeval to timespec */ +- rc = gettimeofday(&tp, NULL); +- +- timeradd(&tp, &tp_wait, &tp_abs); +- +- ts.tv_sec = tp_abs.tv_sec; +- ts.tv_nsec = tp_abs.tv_usec * 1000; +- +- pthread_mutex_lock(&nic->nl_process_mutex); +- rc = pthread_cond_timedwait +- (&nic->nl_process_if_down_cond, +- &nic->nl_process_mutex, &ts); +- +- if (rc == ETIMEDOUT) { +- pthread_mutex_unlock +- (&nic->nl_process_mutex); +- +- req_ptr.eth = (void *)mac_addr; +- req_ptr.ipv6 = (void *)&dst_addr; +- if (ndpc_request +- (&nic_iface->ustack, &req_ptr, &rc, +- CHECK_ARP_TABLE)) { +- /* ndpc request failed, +- force retry */ +- rc = 0; +- } +- if (rc) +- goto done; +- } else { +- nic->nl_process_if_down = 0; +- pthread_mutex_unlock +- (&nic->nl_process_mutex); +- +- neighbor_retry = MAX_ARP_RETRY; +- goto done; +- } +- } +- neighbor_retry++; +- } +- } +- +-done: +- if (neighbor_retry >= MAX_ARP_RETRY) { +- status = -EIO; +- rc = -EIO; +- } +- +- if (ev) { +- cnic_nl_neigh_rsp(nic, fd, ev, path, mac_addr, +- nic_iface, status, AF_INET6); +- } +- return rc; +-} +- +-/** +- * cnic_handle_iscsi_path_req() - This function will handle the path req calls +- * the bnx2i kernel module +- * @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 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, +- nic_interface_t *nic_iface) +-{ +- +- LOG_DEBUG(PFX "%s: Netlink message with VLAN ID: %d, path MTU: %d " +- "minor: %d ip_addr_len: %d", +- nic->log_name, path->vlan_id, path->pmtu, 0 /* TODO FIX */ , +- path->ip_addr_len); +- +- if (path->ip_addr_len == 4) +- 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, +- nic_iface); +- else { +- LOG_DEBUG(PFX "%s: unknown ip_addr_len: %d size dropping ", +- nic->log_name, path->ip_addr_len); +- return -EIO; +- } +-} +diff --git a/iscsiuio/src/unix/libs/cnic.h b/iscsiuio/src/unix/libs/cnic.h +deleted file mode 100644 +index c86595c..0000000 +--- a/iscsiuio/src/unix/libs/cnic.h ++++ /dev/null +@@ -1,57 +0,0 @@ +-/* +- * Copyright (c) 2009-2011, Broadcom Corporation +- * Copyright (c) 2014, QLogic Corporation +- * +- * Written by: Benjamin Li (benli@broadcom.com) +- * +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. All advertising materials mentioning features or use of this software +- * must display the following acknowledgement: +- * This product includes software developed by Adam Dunkels. +- * 4. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * cnic.h - CNIC UIO uIP user space stack +- * +- */ +-#ifndef __CNIC_NL_H__ +-#define __CNIC_NL_H__ +- +-/******************************************************************************* +- * Constants shared between the bnx2 and bnx2x modules +- ******************************************************************************/ +-extern const char bnx2i_library_transport_name[]; +-extern const size_t bnx2i_library_transport_name_size; +-extern const char qedi_library_transport_name[]; +-extern const size_t qedi_library_transport_name_size; +- +-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, +- nic_interface_t *nic_iface); +- +-#endif /* __CNIC_NL_H__ */ +diff --git a/iscsiuio/src/unix/libs/qedi.c b/iscsiuio/src/unix/libs/qedi.c +deleted file mode 100644 +index 1af8d1b..0000000 +--- a/iscsiuio/src/unix/libs/qedi.c ++++ /dev/null +@@ -1,1195 +0,0 @@ +-/* +- * Copyright (c) 2016, Cavium Inc. +- * +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. All advertising materials mentioning features or use of this software +- * must display the following acknowledgement: +- * This product includes software developed by Adam Dunkels. +- * 4. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * qedi.c - qedi user space driver +- * This file handles different qedi NIC operations, +- * qedi_open - initializes all hardware resources under NIC device +- * qedi_close - closes the NIC device +- * qedi_read - reads data to the hardware +- * qedi_write - writes data to the hardware +- * qedi_start_xmit - sends a pkt of data on NIC device +- * qedi_get_tx_pkt - gets a Tx pkt from NIC +- * qedi_clear_tx_intr - clears the Tx interrupt +- * NOTE: nic_t is used as NIC device, +- * qedi is not attached to netdev hence it is not mandatory +- * for netdev to be upd +- */ +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include "config.h" +- +-#include "build_date.h" +-#include "bnx2x.h" +-#include "qedi.h" +-#include "cnic.h" +-#include "logger.h" +-#include "nic.h" +-#include "nic_id.h" +-#include "nic_utils.h" +-#include "options.h" +- +-#define PFX "qedi " +- +-extern int nl_sock; +- +-static pthread_mutex_t host_mutex = PTHREAD_MUTEX_INITIALIZER; +- +-/* Foward struct declarations */ +-struct nic_ops qedi_op; +- +-/******************************************************************************* +- * NIC Library Strings +- ******************************************************************************/ +-static const char library_name[] = "qedi"; +-static const char library_version[] = PACKAGE_VERSION; +-static const char library_uio_name[] = "qedi_uio"; +- +-/* The name that should be returned from /sys/class/uio/uio0/name */ +-static const char cnic_uio_sysfs_name_tempate[] = "/sys/class/uio/uio%i/name"; +-static const char qedi_uio_sysfs_name[] = "qedi_uio"; +-static const char qedi_host_mac_template[] = +- "/sys/class/iscsi_host/host%i/hwaddress"; +- +-struct qedi_driver_version qedi_version = { +- QEDI_UNKNOWN_MAJOR_VERSION, +- QEDI_UNKNOWN_MINOR_VERSION, +- QEDI_UNKNOWN_SUB_MINOR_VERSION, +-}; +- +-static int qedi_clear_tx_intr(nic_t *nic); +- +-/******************************************************************************* +- * QEDI Library Functions +- ******************************************************************************/ +-/** +- * qedi_get_library_name() - Used to get the name of this NIC library +- * @param name - This function will return the pointer to this NIC +- * library name +- * @param name_size +- */ +-static void qedi_get_library_name(char **name, size_t *name_size) +-{ +- *name = (char *)library_name; +- *name_size = sizeof(library_name); +-} +- +-/** +- * qedi_get_library_version() - Used to get the version string of this +- * NIC library +- * @param version - This function will return the pointer to this NIC +- * library version string +- * @param version_size - This will be set with the version size +- */ +-static void qedi_get_library_version(char **version, size_t *version_size) +-{ +- *version = (char *)library_version; +- *version_size = sizeof(library_version); +-} +- +-/** +- * qedi_get_build_date() - Used to get the build date string of this library +- * @param version - This function will return the pointer to this NIC +- * library build date string +- * @param version_size - This will be set with the build date string size +- */ +-static void qedi_get_build_date(char **build, size_t *build_size) +-{ +- *build = (char *)build_date; +- *build_size = sizeof(build_date); +-} +- +-/** +- * qedi_get_transport_name() - Used to get the transport name associated +- * with this this NIC library +- * @param transport_name - This function will return the pointer to this NIC +- * library's associated transport string +- * @param transport_name_size - This will be set with the transport name size +- */ +-static void qedi_get_transport_name(char **transport_name, +- size_t *transport_name_size) +-{ +- *transport_name = (char *)qedi_library_transport_name; +- *transport_name_size = qedi_library_transport_name_size; +-} +- +-/** +- * qedi_get_uio_name() - Used to get the uio name associated with this this +- * NIC library +- * @param uio_name - This function will return the pointer to this NIC +- * library's associated uio string +- * @param transport_name_size - This will be set with the uio name size +- */ +-static void qedi_get_uio_name(char **uio_name, size_t *uio_name_size) +-{ +- *uio_name = (char *)library_uio_name; +- *uio_name_size = sizeof(library_uio_name); +-} +- +-/** +- * qedi_get_ops() - Used to get the NIC library op table +- * @param op - The op table of this NIC library +- */ +-struct nic_ops *qedi_get_ops() +-{ +- return &qedi_op; +-} +- +-/******************************************************************************* +- * qedi Utility Functions +- ******************************************************************************/ +-/******************************************************************************* +- * Utility Functions Used to read register from the qedi device +- ******************************************************************************/ +-static void qedi_set_drv_version_unknown(qedi_t *bp) +-{ +- bp->version.major = QEDI_UNKNOWN_MAJOR_VERSION; +- bp->version.minor = QEDI_UNKNOWN_MINOR_VERSION; +- bp->version.sub_minor = QEDI_UNKNOWN_SUB_MINOR_VERSION; +-} +- +-/* Return: 1 = Unknown, 0 = Known */ +-static int qedi_is_drv_version_unknown(struct qedi_driver_version *version) +-{ +- if ((version->major == (uint16_t)QEDI_UNKNOWN_MAJOR_VERSION) && +- (version->minor == (uint16_t)QEDI_UNKNOWN_MINOR_VERSION) && +- (version->sub_minor == (uint16_t)QEDI_UNKNOWN_SUB_MINOR_VERSION)) { +- return 1; +- } +- +- return 0; +-} +- +-/** +- * qedi_get_drv_version() - Used to determine the driver version +- * @param bp - Device used to determine qedi driver version +- */ +-static int qedi_get_drv_version(qedi_t *bp) +-{ +- nic_t *nic = bp->parent; +- +- /* +- * CAPABILITIES: Get the iscsi driver version from qedi +- * This may be obtained from sysfs +- */ +- LOG_INFO(PFX "%s: qedi driver using version %d.%d.%d", +- nic->log_name, +- bp->version.major, bp->version.minor, bp->version.sub_minor); +- +- return 0; +-} +- +-/******************************************************************************/ +- +-/** +- * qedi_get_chip_id() - Used to retrieve the chip ID from the nic +- * @param dev - Device used to determin NIC type +- * @return Chip ID read from the MISC ID register +- */ +-static int qedi_get_chip_id(qedi_t *bp) +-{ +- /* int val, id; */ +- +- /* Get the chip revision id and number. */ +- /* chip num:16-31, rev:12-15, metal:4-11, bond_id:0-3 */ +- /* +- * CAPABILITIES: Get the CHIP info from qedi through sysfs or uio struct. +- */ +- return 0; +-} +- +-/** +- * qedi_uio_verify() +- * +- */ +-static int qedi_uio_verify(nic_t *nic) +-{ +- char *raw = NULL, *raw_tmp; +- uint32_t raw_size = 0; +- char temp_path[sizeof(cnic_uio_sysfs_name_tempate) + 8]; +- int rc = 0; +- +- /* Build the path to determine uio name */ +- snprintf(temp_path, sizeof(temp_path), +- cnic_uio_sysfs_name_tempate, nic->uio_minor); +- +- rc = capture_file(&raw, &raw_size, temp_path); +- if (rc != 0) +- goto error; +- +- /* sanitize name string by replacing newline with null termination */ +- raw_tmp = raw; +- while (*raw_tmp != '\n') +- raw_tmp++; +- *raw_tmp = '\0'; +- +- if (strncmp(raw, qedi_uio_sysfs_name, +- sizeof(qedi_uio_sysfs_name)) != 0) { +- LOG_ERR(PFX "%s: uio names not equal: expecting %s got %s from %s", +- nic->log_name, qedi_uio_sysfs_name, raw, temp_path); +- rc = -EIO; +- } +- +- free(raw); +- +- LOG_INFO(PFX "%s: Verified is a qedi_uio device", nic->log_name); +- +-error: +- return rc; +-} +- +-static int qedi_get_mac_addr(qedi_t *bp) +-{ +- nic_t *nic = bp->parent; +- char *raw = NULL, *raw_tmp; +- uint32_t raw_size = 0; +- char temp_path[sizeof(qedi_host_mac_template) + 8]; +- int rc = 0; +- +- /* Build the path to determine mac address */ +- snprintf(temp_path, sizeof(temp_path), +- qedi_host_mac_template, nic->host_no); +- +- rc = capture_file(&raw, &raw_size, temp_path); +- if (rc != 0) +- goto error; +- +- /* sanitize name string by replacing newline with null termination */ +- raw_tmp = raw; +- while (*raw_tmp != '\n') +- raw_tmp++; +- *raw_tmp = '\0'; +- +- rc = sscanf(raw, "%02x:%02x:%02x:%02x:%02x:%02x", +- (uint32_t *)&nic->mac_addr[0], (uint32_t *)&nic->mac_addr[1], +- (uint32_t *)&nic->mac_addr[2], (uint32_t *)&nic->mac_addr[3], +- (uint32_t *)&nic->mac_addr[4], (uint32_t *)&nic->mac_addr[5]); +- if (rc != 1) { +- LOG_WARN(PFX "%s: Could not parse mac_addr", +- nic->log_name); +- rc = -ENODEV; +- goto error; +- } +- +-error: +- if (raw) +- free(raw); +- return rc; +-} +- +-/******************************************************************************* +- * qedi Utility Functions to get to the hardware consumer indexes +- ******************************************************************************/ +- +-static __u32 qedi_get_rx(qedi_t *bp) +-{ +- return ((struct qedi_uio_ctrl *)bp->uctrl_map)->host_rx_cons; +-} +- +-static __u32 qedi_get_tx(qedi_t *bp) +-{ +- return ((struct qedi_uio_ctrl *)bp->uctrl_map)->hw_tx_cons; +-} +- +-/** +- * qedi_free() - Used to free a qedi structure +- */ +-static void qedi_free(nic_t *nic) +-{ +- if (nic->priv) +- free(nic->priv); +- nic->priv = NULL; +-} +- +-/** +- * qedi_alloc() - Used to allocate a qedi structure +- */ +-static qedi_t *qedi_alloc(nic_t *nic) +-{ +- qedi_t *bp = malloc(sizeof(*bp)); +- +- if (!bp) { +- LOG_ERR(PFX "%s: Could not allocate QEDI space", +- nic->log_name); +- return NULL; +- } +- +- /* Clear out the CNIC contents */ +- memset(bp, 0, sizeof(*bp)); +- +- bp->parent = nic; +- nic->priv = (void *)bp; +- get_iscsi_transport_handle(nic, &nic->transport_handle); +- qedi_set_drv_version_unknown(bp); +- +- return bp; +-} +- +-int uio_get_map_offset(nic_t *nic, uint8_t map, uint32_t *offset) +-{ +- char *raw = NULL; +- uint32_t raw_size = 0; +- ssize_t elements_read; +- char temp_path[sizeof(UIO_OFFSET_TMPL) + 8]; +- int rc = 0; +- +- /* Capture RX buffer size */ +- snprintf(temp_path, sizeof(temp_path), +- UIO_OFFSET_TMPL, nic->uio_minor, map); +- +- rc = capture_file(&raw, &raw_size, temp_path); +- if (rc != 0) +- goto error; +- +- elements_read = sscanf(raw, "0x%x", offset); +- if (elements_read != 1) { +- LOG_ERR(PFX "%s: Couldn't get the offset from %s", +- nic->log_name, temp_path); +- rc = -EIO; +- goto error; +- } +- +- rc = 0; +-error: +- if (raw) +- free(raw); +- +- return rc; +-} +- +-int uio_get_map_info(nic_t *nic, uint8_t map, char *attr, uint32_t *val) +-{ +- char *raw = NULL; +- uint32_t raw_size = 0; +- ssize_t elements_read; +- char temp_path[sizeof(UIO_ATTR_TMPL) + 8]; +- int rc = 0; +- +- /* Capture RX buffer size */ +- snprintf(temp_path, sizeof(temp_path), +- UIO_ATTR_TMPL, nic->uio_minor, map, attr); +- +- rc = capture_file(&raw, &raw_size, temp_path); +- if (rc != 0) +- goto error; +- +- elements_read = sscanf(raw, "0x%x", val); +- if (elements_read != 1) { +- LOG_ERR(PFX "%s: Couldn't get the offset from %s", +- nic->log_name, temp_path); +- rc = -EIO; +- goto error; +- } +- +- rc = 0; +-error: +- if (raw) +- free(raw); +- +- return rc; +-} +- +-/** +- * qedi_open() - This will initialize all the hardware resources underneath +- * a struct cnic_uio device +- * @param dev - The struct cnic_uio device to attach the hardware with +- * @return 0 on success, on failure a errno will be returned +- */ +-static int qedi_open(nic_t *nic) +-{ +- qedi_t *bp = NULL; +- struct stat uio_stat; +- int i, rc; +- size_t count; +- uint32_t bus; +- uint32_t slot; +- uint32_t func; +- uint32_t offset; +- +- /* Sanity Check: validate the parameters */ +- if (!nic) { +- LOG_ERR(PFX "nic == NULL"); +- return -EINVAL; +- } +- +- if ((nic->priv) != NULL && +- (((qedi_t *)(nic->priv))->flags & QEDI_OPENED)) { +- return 0; +- } +- +- if (nic->host_no == INVALID_HOST_NO) { +- rc = sscanf(nic->config_device_name, "host%d", &nic->host_no); +- if (rc != 1) { +- LOG_WARN(PFX "%s: Could not parse for host number", +- nic->config_device_name); +- rc = -ENODEV; +- goto open_error; +- } +- } +- +- bp = qedi_alloc(nic); +- if (!bp) +- return -ENOMEM; +- +- if (qedi_is_drv_version_unknown(&qedi_version)) { +- /* If version is unknown, go read from ethtool */ +- rc = qedi_get_drv_version(bp); +- if (rc) +- goto open_error; +- } else { +- /* Version is not unknown, just use it */ +- qedi_version.major = bp->version.major; +- qedi_version.minor = bp->version.minor; +- qedi_version.sub_minor = bp->version.sub_minor; +- } +- +- 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) { +- LOG_ERR(PFX "%s: uio device has been brought up via pid: %d on fd: %d", +- nic->uio_device_name, getpid(), nic->fd); +- +- rc = qedi_uio_verify(nic); +- if (rc != 0) +- continue; +- +- break; +- } else { +- LOG_WARN(PFX "%s: Could not open device: %s, [%s]", +- nic->log_name, nic->uio_device_name, +- strerror(errno)); +- +- 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++; +- } +- } +- if (nic->fd == INVALID_FD) { +- LOG_ERR(PFX "%s: Could not open device: %s, [%s]", +- nic->log_name, nic->uio_device_name, +- strerror(errno)); +- rc = errno; +- goto open_error; +- } +- if (fstat(nic->fd, &uio_stat) < 0) { +- LOG_ERR(PFX "%s: Could not fstat device", nic->log_name); +- rc = -ENODEV; +- goto open_error; +- } +- nic->uio_minor = minor(uio_stat.st_rdev); +- +- /* +- * CAPABILITIES: acquire the rx buffer size and rx ring size from qedi +- */ +- +- bp->rx_ring_size = RX_RING_SIZE; +- bp->rx_buffer_size = PKT_BUF_SIZE; +- +- LOG_DEBUG(PFX "%s: using rx ring size: %d, rx buffer size: %d", +- nic->log_name, bp->rx_ring_size, bp->rx_buffer_size); +- +- /* Determine the number of UIO events that have already occurred */ +- rc = detemine_initial_uio_events(nic, &nic->intr_count); +- if (rc != 0) { +- LOG_ERR(PFX "Could not get the no. of initial UIO events"); +- nic->intr_count = 0; +- } +- +- /* Allocate space for rx pkt ring */ +- bp->rx_pkt_ring = malloc(sizeof(void *) * bp->rx_ring_size); +- if (!bp->rx_pkt_ring) { +- LOG_ERR(PFX "%s: Could not allocate space for rx_pkt_ring", +- nic->log_name); +- rc = errno; +- goto open_error; +- } +- +- /* +- * Map the uio struct and packet buffer +- */ +- offset = 0; +- rc = uio_get_map_info(nic, QEDI_UCTRL_MAP_REG, "size", &offset); +- if (rc) { +- LOG_INFO(PFX "Failed to get the map size rc=%d", rc); +- goto open_error; +- } +- LOG_INFO(PFX "uctrl map size=%u", offset); +- +- offset = 0; +- rc = uio_get_map_info(nic, QEDI_RING_MAP_REG, "size", &offset); +- if (rc) { +- LOG_INFO(PFX "Failed to get the map size rc=%d", rc); +- goto open_error; +- } +- LOG_INFO(PFX "ring map size=%u", offset); +- +- offset = 0; +- rc = uio_get_map_info(nic, QEDI_BUF_MAP_REG, "size", &offset); +- if (rc) { +- LOG_INFO(PFX "Failed to get the map size rc=%d", rc); +- goto open_error; +- } +- LOG_INFO(PFX "buf map size=%u", offset); +- +- offset = 0; +- rc = uio_get_map_offset(nic, QEDI_UCTRL_MAP_REG, &offset); +- if (rc) { +- LOG_INFO(PFX "Failed to get the map offset rc=%d", rc); +- goto open_error; +- } +- +- bp->uctrl_map = mmap(NULL, sizeof(struct qedi_uio_ctrl), +- PROT_READ | PROT_WRITE, +- MAP_SHARED | MAP_LOCKED, +- nic->fd, (off_t)0); +- if (bp->uctrl_map == MAP_FAILED) { +- LOG_INFO(PFX "%s: Could not mmap uio ctrl struct: %s", +- nic->log_name, strerror(errno)); +- bp->uctrl_map = NULL; +- rc = errno; +- goto open_error; +- } +- +- bp->uctrl_map_offset = offset; +- bp->uctrl_map += offset; +- +- bp->rx_comp_ring = mmap(NULL, nic->page_size, +- PROT_READ | PROT_WRITE, MAP_SHARED | MAP_LOCKED, +- nic->fd, (off_t)nic->page_size); +- if (bp->rx_comp_ring == MAP_FAILED) { +- LOG_INFO(PFX "%s: Could not mmap rx_comp_ring: %s", +- nic->log_name, strerror(errno)); +- bp->rx_comp_ring = NULL; +- rc = errno; +- goto open_error; +- } +- +- bp->bufs = mmap(NULL, (bp->rx_ring_size + 1) * bp->rx_buffer_size, +- PROT_READ | PROT_WRITE, MAP_SHARED | MAP_LOCKED, +- nic->fd, (off_t)2 * nic->page_size); +- if (bp->bufs == MAP_FAILED) { +- LOG_INFO(PFX "%s: Could not mmap pkt buffers: %s", +- nic->log_name, strerror(errno)); +- bp->bufs = NULL; +- rc = errno; +- goto open_error; +- } +- +- /* +- * Get all CHIP related info from qedi +- */ +- bp->chip_id = qedi_get_chip_id(bp); +- LOG_DEBUG(PFX "Chip ID: %x", bp->chip_id); +- +- rc = get_bus_slot_func_num(nic, &bus, &slot, &func); +- if (rc != 0) { +- LOG_INFO(PFX "%s: Couldn't determine bus:slot.func", +- nic->log_name); +- goto open_error; +- } +- +- /* +- * Get all function, pfid, client_id and cid info from qedi +- */ +- LOG_INFO(PFX "%s: func 0x%x, pfid 0x%x, client_id 0x%x, cid 0x%x", +- nic->log_name, bp->func, bp->pfid, bp->client_id, bp->cid); +- +- bp->get_rx_cons = qedi_get_rx; +- bp->get_tx_cons = qedi_get_tx; +- bp->tx_cons = 0; +- bp->tx_prod = 0; +- bp->tx_bd_prod = 0; +- bp->tx_pkt = bp->bufs; +- bp->rx_pkts = bp->bufs + bp->rx_buffer_size; +- +- bp->rx_index = 0; +- bp->rx_cons = 0; +- bp->rx_bd_cons = 0; +- bp->rx_prod = 127; +- bp->rx_bd_prod = bp->rx_ring_size; +- +- for (i = 0; i < bp->rx_ring_size; i++) { +- void *ptr = bp->bufs + (bp->rx_buffer_size * (i + 1)); +- +- bp->rx_pkt_ring[i] = ptr; +- } +- +- qedi_get_mac_addr(bp); +- 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], +- nic->mac_addr[3], nic->mac_addr[4], nic->mac_addr[5]); +- +- qedi_get_library_name(&nic->library_name, &count); +- LOG_INFO("%s: qedi initialized", nic->log_name); +- +- bp->flags |= QEDI_OPENED; +- +- return 0; +- +-open_error: +- +- if (bp->bufs) { +- munmap(bp->bufs, (bp->rx_ring_size + 1) * bp->rx_buffer_size); +- bp->bufs = NULL; +- } +- +- if (bp->rx_comp_ring) { +- munmap(bp->rx_comp_ring, nic->page_size); +- bp->rx_comp_ring = NULL; +- } +- +- if (bp->uctrl_map) { +- bp->uctrl_map -= bp->uctrl_map_offset; +- munmap(bp->uctrl_map, sizeof(struct qedi_uio_ctrl)); +- bp->uctrl_map = NULL; +- } +- +- if (bp->rx_pkt_ring) { +- free(bp->rx_pkt_ring); +- bp->rx_pkt_ring = NULL; +- } +- +- if (nic->fd != INVALID_FD) { +- close(nic->fd); +- nic->fd = INVALID_FD; +- } +- +- qedi_free(nic); +- +- return rc; +-} +- +-/** +- * qedi_uio_close_resources() - Used to free resource for the NIC/CNIC +- * @param nic - NIC device to free resource +- * @param graceful - whether to wait to close gracefully +- * @return 0 on success, <0 on failure +- */ +-static int qedi_uio_close_resources(nic_t *nic, NIC_SHUTDOWN_T graceful) +-{ +- qedi_t *bp = (qedi_t *)nic->priv; +- int rc = 0; +- +- /* Check if there is an assoicated qedi device */ +- if (!bp) { +- LOG_WARN(PFX "%s: when closing resources there is no assoicated qedi", +- nic->log_name); +- return -EIO; +- } +- +- /* Clean up allocated memory */ +- +- if (bp->rx_pkt_ring) { +- free(bp->rx_pkt_ring); +- bp->rx_pkt_ring = NULL; +- } +- +- /* Clean up mapped registers */ +- if (bp->bufs) { +- rc = munmap(bp->bufs, +- (bp->rx_ring_size + 1) * bp->rx_buffer_size); +- if (rc != 0) +- LOG_ERR(PFX "%s: Couldn't unmap bufs", nic->log_name); +- bp->bufs = NULL; +- } +- +- if (bp->rx_comp_ring) { +- rc = munmap(bp->rx_comp_ring, nic->page_size); +- if (rc != 0) +- LOG_ERR(PFX "%s: Couldn't unmap ring", nic->log_name); +- bp->rx_comp_ring = NULL; +- } +- +- if (bp->uctrl_map) { +- bp->uctrl_map -= bp->uctrl_map_offset; +- rc = munmap(bp->uctrl_map, sizeof(struct qedi_uio_ctrl)); +- if (rc != 0) { +- LOG_ERR(PFX "%s: Couldn't unmap uio ctrl", +- nic->log_name); +- } +- bp->uctrl_map = NULL; +- } +- +- if (nic->fd != INVALID_FD) { +- rc = close(nic->fd); +- if (rc != 0) { +- LOG_ERR(PFX +- "%s: Couldn't close uio file descriptor: %d", +- nic->log_name, nic->fd); +- } else { +- LOG_DEBUG(PFX "%s: Closed uio file descriptor: %d", +- nic->log_name, nic->fd); +- } +- +- nic->fd = INVALID_FD; +- } else { +- LOG_ERR(PFX "%s: Invalid uio file descriptor: %d", +- nic->log_name, nic->fd); +- } +- +- qedi_set_drv_version_unknown(bp); +- +- LOG_INFO(PFX "%s: Closed all resources", nic->log_name); +- +- return 0; +-} +- +-/** +- * qedi_close() - Used to close the NIC device +- * @param nic - NIC device to close +- * @param graceful - whether to wait to close gracefully +- * @return 0 if successful, <0 if there is an error +- */ +-static int qedi_close(nic_t *nic, NIC_SHUTDOWN_T graceful) +-{ +- /* Sanity Check: validate the parameters */ +- if (!nic) { +- LOG_ERR(PFX "%s: nic == NULL", __func__); +- return -EINVAL; +- } +- if (!nic->priv) { +- LOG_ERR(PFX "%s: nic->priv == NULL", __func__); +- return -EINVAL; +- } +- +- LOG_INFO(PFX "Closing NIC device: %s", nic->log_name); +- +- qedi_uio_close_resources(nic, graceful); +- qedi_free(nic); +- +- return 0; +-} +- +-static void qedi_prepare_xmit_packet(nic_t *nic, +- nic_interface_t *nic_iface, +- struct packet *pkt) +-{ +- qedi_t *bp = (qedi_t *)nic->priv; +- struct uip_vlan_eth_hdr *eth_vlan = (struct uip_vlan_eth_hdr *)pkt->buf; +- struct uip_eth_hdr *eth = (struct uip_eth_hdr *)bp->tx_pkt; +- +- LOG_DEBUG(PFX "%s: pkt->buf_size=%d tpid=0x%x", nic->log_name, +- pkt->buf_size, eth_vlan->tpid); +- +- if (eth_vlan->tpid == htons(UIP_ETHTYPE_8021Q)) { +- memcpy(bp->tx_pkt, pkt->buf, sizeof(struct uip_eth_hdr)); +- eth->type = eth_vlan->type; +- pkt->buf_size -= (sizeof(struct uip_vlan_eth_hdr) - +- sizeof(struct uip_eth_hdr)); +- +- LOG_DEBUG(PFX "%s: pkt->buf_size=%d type=0x%x", nic->log_name, +- pkt->buf_size, eth->type); +- LOG_DEBUG(PFX "%s: pkt->buf_size - eth_hdr_size = %d", nic->log_name, +- pkt->buf_size - sizeof(struct uip_eth_hdr)); +- +- memcpy(bp->tx_pkt + sizeof(struct uip_eth_hdr), +- pkt->buf + sizeof(struct uip_vlan_eth_hdr), +- pkt->buf_size - sizeof(struct uip_eth_hdr)); +- } else { +- LOG_DEBUG(PFX "%s: NO VLAN pkt->buf_size=%d", nic->log_name, +- pkt->buf_size); +- memcpy(bp->tx_pkt, pkt->buf, pkt->buf_size); +- } +- +- msync(bp->tx_pkt, pkt->buf_size, MS_SYNC); +-} +- +-/** +- * qedi_get_tx_pkt() - This function is used to a TX packet from the NIC +- * @param nic - The NIC device to send the packet +- */ +-void *qedi_get_tx_pkt(nic_t *nic) +-{ +- qedi_t *bp = (qedi_t *)nic->priv; +- +- return bp->tx_pkt; +-} +- +-/** +- * qedi_start_xmit() - This function is used to send a packet of data +- * @param nic - The NIC device to send the packet +- * @param len - the length of the TX packet +- * +- */ +-void qedi_start_xmit(nic_t *nic, size_t len, u16_t vlan_id) +-{ +- qedi_t *bp = (qedi_t *)nic->priv; +- uint8_t *ubuf; +- struct iscsi_uevent *ev; +- struct iscsi_path *path_data; +- struct qedi_uio_ctrl *uctrl; +- int rc = 0; +- uint16_t buflen; +- +- uctrl = (struct qedi_uio_ctrl *)bp->uctrl_map; +- +- buflen = sizeof(struct iscsi_uevent) + sizeof(struct iscsi_path); +- ubuf = calloc(1, NLMSG_SPACE(buflen)); +- if (!ubuf) { +- LOG_ERR(PFX "%s: alloc failed for uevent buf", __func__); +- return; +- } +- +- memset(ubuf, 0, NLMSG_SPACE(buflen)); +- +- /* prepare the iscsi_uevent buffer */ +- ev = (struct iscsi_uevent *)ubuf; +- ev->type = ISCSI_UEVENT_PATH_UPDATE; +- ev->transport_handle = nic->transport_handle; +- ev->u.set_path.host_no = nic->host_no; +- +- /* Prepare the iscsi_path buffer */ +- path_data = (struct iscsi_path *)(ubuf + sizeof(struct iscsi_uevent)); +- path_data->handle = QEDI_PATH_HANDLE; +- path_data->vlan_id = vlan_id; +- uctrl->host_tx_pkt_len = len; +- LOG_DEBUG(PFX "%s: host_no:%d vlan_id=%d, tx_pkt_len=%d", +- nic->log_name, ev->u.set_path.host_no, path_data->vlan_id, uctrl->host_tx_pkt_len); +- +- LOG_DEBUG(PFX "%s: ACQUIRE HOST MUTEX", nic->log_name); +- pthread_mutex_lock(&host_mutex); +- rc = __kipc_call(nl_sock, ev, buflen); +- if (rc > 0) { +- bp->tx_prod++; +- uctrl->host_tx_prod++; +- LOG_DEBUG(PFX "%s: bp->tx_prod: %d, uctrl->host_tx_prod=%d", +- nic->log_name, bp->tx_prod, uctrl->host_tx_prod); +- +- msync(uctrl, sizeof(struct qedi_uio_ctrl), MS_SYNC); +- LOG_PACKET(PFX "%s: sent %d bytes using bp->tx_prod: %d", +- nic->log_name, len, bp->tx_prod); +- } else { +- LOG_ERR(PFX "Pkt transmission failed: %d", rc); +- } +- +- LOG_DEBUG(PFX "%s: RELEASE HOST MUTEX", nic->log_name); +- pthread_mutex_unlock(&host_mutex); +- free(ubuf); +-} +- +-/** +- * qedi_write() - Used to write the data to the hardware +- * @param nic - NIC hardware to read from +- * @param pkt - The packet which will hold the data to be sent on the wire +- * @return 0 if successful, <0 if failed +- */ +-int qedi_write(nic_t *nic, nic_interface_t *nic_iface, packet_t *pkt) +-{ +- qedi_t *bp; +- struct uip_stack *uip; +- int i = 0; +- +- /* Sanity Check: validate the parameters */ +- if (!nic || !nic_iface || !pkt) { +- LOG_ERR(PFX "%s: qedi_write() nic == 0x%p || nic_iface == 0x%p || pkt == 0x%x", +- nic, nic_iface, pkt); +- return -EINVAL; +- } +- bp = (qedi_t *)nic->priv; +- uip = &nic_iface->ustack; +- +- if (pkt->buf_size == 0) { +- LOG_ERR(PFX "%s: Trying to transmitted 0 sized packet", +- nic->log_name); +- return -EINVAL; +- } +- +- /* Try to wait for a TX completion */ +- for (i = 0; i < 15; i++) { +- struct timespec sleep_req = {.tv_sec = 0, .tv_nsec = 5000000 }, +- sleep_rem; +- +- LOG_DEBUG(PFX "%s: host:%d - calling clear_tx_intr from qedi_write", +- nic->log_name, nic->host_no); +- if (qedi_clear_tx_intr(nic) == 0) +- break; +- +- nanosleep(&sleep_req, &sleep_rem); +- } +- +- LOG_DEBUG(PFX "%s: host:%d - try getting xmit mutex", +- nic->log_name, nic->host_no); +- if (pthread_mutex_trylock(&nic->xmit_mutex) != 0) { +- LOG_DEBUG(PFX "%s: Dropped previous transmitted packet", +- nic->log_name); +- return -EINVAL; +- } +- +- qedi_prepare_xmit_packet(nic, nic_iface, pkt); +- qedi_start_xmit(nic, pkt->buf_size, +- (nic_iface->vlan_priority << 12) | +- nic_iface->vlan_id); +- +- /* bump up the tx stats */ +- 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_DEBUG(PFX "%s: host:%d - releasing xmit mutex", +- nic->log_name, nic->host_no); +- pthread_mutex_unlock(&nic->xmit_mutex); +- +- return 0; +-} +- +-/** +- * qedi_read() - Used to read the data from the hardware +- * @param nic - NIC hardware to read from +- * @param pkt - The packet which will hold the data +- * @return 0 if successful, < 0 if failed +- */ +-static int qedi_read(nic_t *nic, packet_t *pkt) +-{ +- qedi_t *bp; +- void *rx_pkt; +- int rc = 0; +- uint32_t sw_cons, bd_cons; +- uint32_t hw_prod, bd_prod; +- uint32_t rx_pkt_idx; +- int len; +- struct qedi_rx_bd *rx_bd; +- struct qedi_uio_ctrl *uctrl; +- uint16_t vlan_id; +- +- /* Sanity Check: validate the parameters */ +- if (!nic || !pkt) { +- LOG_ERR(PFX "%s: qedi_read() nic == 0x%p || pkt == 0x%x", +- nic, pkt); +- return -EINVAL; +- } +- +- bp = (qedi_t *)nic->priv; +- msync(bp->uctrl_map, sizeof(struct qedi_uio_ctrl), MS_SYNC); +- msync(bp->rx_comp_ring, nic->page_size, MS_SYNC); +- uctrl = (struct qedi_uio_ctrl *)bp->uctrl_map; +- hw_prod = uctrl->hw_rx_prod; +- bd_prod = uctrl->hw_rx_bd_prod; +- sw_cons = uctrl->host_rx_cons; +- bd_cons = uctrl->host_rx_bd_cons; +- rx_bd = bp->rx_comp_ring + (bd_prod * sizeof(*rx_bd)); +- len = rx_bd->rx_pkt_len; +- rx_pkt_idx = rx_bd->rx_pkt_index; +- vlan_id = rx_bd->vlan_id; +- +- LOG_DEBUG(PFX "%s:hw_prod %d bd_prod %d, rx_pkt_idx %d, rxlen %d", +- nic->log_name, hw_prod, bd_prod, rx_bd->rx_pkt_index, len); +- LOG_DEBUG(PFX "%s: sw_con %d bd_cons %d num BD %d", +- nic->log_name, sw_cons, bd_cons, QEDI_NUM_RX_BD); +- +- if (bd_cons != bd_prod) { +- LOG_DEBUG(PFX "%s: clearing rx interrupt: %d %d", +- nic->log_name, sw_cons, hw_prod); +- rc = 1; +- rx_pkt = bp->rx_pkts + (bp->rx_buffer_size * rx_pkt_idx); +- +- if (len > 0) { +- msync(rx_pkt, len, MS_SYNC); +- /* Copy the data */ +- memcpy(pkt->buf, rx_pkt, len); +- pkt->buf_size = len; +- if (vlan_id) { +- pkt->vlan_tag = vlan_id; +- pkt->flags |= VLAN_TAGGED; +- } else { +- pkt->vlan_tag = 0; +- } +- +- LOG_DEBUG(PFX "%s: processing packet length: %d", +- nic->log_name, len); +- +- /* bump up the recv stats */ +- nic->stats.rx.packets++; +- nic->stats.rx.bytes += pkt->buf_size; +- } else { +- rc = 0; +- } +- +- sw_cons = (sw_cons + 1) % RX_RING_SIZE; +- bd_cons = (bd_cons + 1) % QEDI_NUM_RX_BD; +- uctrl->host_rx_cons_cnt++; +- } +- +- uctrl->host_rx_bd_cons = bd_cons; +- uctrl->host_rx_cons = sw_cons; +- +- msync(uctrl, sizeof(struct qedi_uio_ctrl), MS_SYNC); +- msync(bp->rx_comp_ring, nic->page_size, MS_SYNC); +- return rc; +-} +- +-/******************************************************************************* +- * Clearing TX interrupts +- ******************************************************************************/ +-/** +- * qedi_clear_tx_intr() - This routine is called when a TX interrupt occurs +- * @param nic - the nic the interrupt occurred on +- * @return 0 on success +- */ +- +-static int qedi_clear_tx_intr(nic_t *nic) +-{ +- qedi_t *bp; +- uint32_t hw_cons; +- struct qedi_uio_ctrl *uctrl; +- +- /* Sanity check: ensure the parameters passed in are valid */ +- if (unlikely(!nic)) { +- LOG_ERR(PFX "%s: nic == NULL", __func__); +- return -EINVAL; +- } +- +- bp = (qedi_t *)nic->priv; +- uctrl = (struct qedi_uio_ctrl *)bp->uctrl_map; +- msync(bp->uctrl_map, sizeof(struct qedi_uio_ctrl), MS_SYNC); +- hw_cons = uctrl->hw_tx_cons; +- +- if (bp->tx_cons == hw_cons) { +- if (bp->tx_cons == bp->tx_prod) +- return 0; +- return -EAGAIN; +- } +- +- if (pthread_mutex_trylock(&nic->xmit_mutex)) { +- LOG_ERR(PFX "%s: unable to get xmit_mutex.", nic->log_name); +- return -EINVAL; +- } +- +- LOG_DEBUG(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 +- * case is when stack will send an ARP packet out before sending the +- * intended packet +- */ +- if (nic->tx_packet_queue) { +- packet_t *pkt; +- int i; +- +- LOG_DEBUG(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 +- * the hardware +- */ +- if (pkt) { +- qedi_prepare_xmit_packet(nic, pkt->nic_iface, pkt); +- +- qedi_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); +- +- pthread_mutex_unlock(&nic->xmit_mutex); +- return 0; +- } +- +- /* Try to wait for a TX completion */ +- for (i = 0; i < 15; i++) { +- struct timespec sleep_req = {.tv_sec = 0, +- .tv_nsec = 5000000 +- }, sleep_rem; +- +- hw_cons = uctrl->hw_tx_cons; +- if (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; +- } +- +- nanosleep(&sleep_req, &sleep_rem); +- } +- } +- +- LOG_DEBUG(PFX "%s: host:%d - releasing xmit mutex", +- nic->log_name, nic->host_no); +- pthread_mutex_unlock(&nic->xmit_mutex); +- +- return 0; +-} +- +-/******************************************************************************* +- * qedi NIC op's table +- ******************************************************************************/ +-struct nic_ops qedi_op = { +- .description = "qedi", +- .open = qedi_open, +- .close = qedi_close, +- .write = qedi_write, +- .get_tx_pkt = qedi_get_tx_pkt, +- .start_xmit = qedi_start_xmit, +- .read = qedi_read, +- .clear_tx_intr = qedi_clear_tx_intr, +- .handle_iscsi_path_req = cnic_handle_iscsi_path_req, +- +- .lib_ops = { +- .get_library_name = qedi_get_library_name, +- .get_library_version = qedi_get_library_version, +- .get_build_date = qedi_get_build_date, +- .get_transport_name = qedi_get_transport_name, +- .get_uio_name = qedi_get_uio_name, +- }, +-}; +diff --git a/iscsiuio/src/unix/libs/qedi.h b/iscsiuio/src/unix/libs/qedi.h +deleted file mode 100644 +index 7e0140a..0000000 +--- a/iscsiuio/src/unix/libs/qedi.h ++++ /dev/null +@@ -1,159 +0,0 @@ +-/* +- * Copyright (c) 2016, Cavium Inc. +- * +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. All advertising materials mentioning features or use of this software +- * must display the following acknowledgement: +- * This product includes software developed by Adam Dunkels. +- * 4. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * qedi.h - qedi user space driver +- * +- */ +-#ifndef __QEDI_H__ +-#define __QEDI_H__ +- +-#include "nic.h" +- +-#define RX_RING_SIZE 15 +-#define PKT_BUF_SIZE 0X400 +-#define QEDI_PAGE_SIZE 4096 +- +-#define QEDI_UNKNOWN_MAJOR_VERSION -1 +-#define QEDI_UNKNOWN_MINOR_VERSION -1 +-#define QEDI_UNKNOWN_SUB_MINOR_VERSION -1 +-struct qedi_driver_version { +- uint16_t major; +- uint16_t minor; +- uint16_t sub_minor; +-}; +- +-#define QEDI_UCTRL_MAP_REG 0 +-#define QEDI_RING_MAP_REG 1 +-#define QEDI_BUF_MAP_REG 2 +-#define UIO_ATTR_TMPL "/sys/class/uio/uio%u/maps/map%u/%s" +-#define UIO_ADDR_TMPL "/sys/class/uio/uio%u/maps/map%u/addr" +-#define UIO_OFFSET_TMPL "/sys/class/uio/uio%u/maps/map%u/offset" +-#define UIO_SIZE_TMPL "/sys/class/uio/uio%u/maps/map%u/size" +- +-struct qedi_uio_ctrl { +- /* meta data */ +- __u32 uio_hsi_version; +- +- /* user writes */ +- __u32 host_tx_prod; +- __u32 host_rx_cons; +- __u32 host_rx_bd_cons; +- __u32 host_tx_pkt_len; +- __u32 host_rx_cons_cnt; +- +- /* driver writes */ +- __u32 hw_tx_cons; +- __u32 hw_rx_prod; +- __u32 hw_rx_bd_prod; +- __u32 hw_rx_prod_cnt; +- +- /* other */ +- __u8 mac_addr[6]; +- __u8 reserve[2]; +-}; +- +-struct qedi_rx_bd { +- __u32 rx_pkt_index; +- __u32 rx_pkt_len; +- __u16 vlan_id; +-}; +- +-#define QEDI_RX_DESC_CNT (QEDI_PAGE_SIZE / sizeof(struct qedi_rx_bd)) +-#define QEDI_MAX_RX_DESC_CNT (QEDI_RX_DESC_CNT - 1) +-#define QEDI_NUM_RX_BD (QEDI_RX_DESC_CNT * 1) +-#define QEDI_MAX_RX_BD (QEDI_NUM_RX_BD - 1) +- +-#define QEDI_NEXT_RX_IDX(x) ((((x) & (QEDI_MAX_RX_DESC_CNT)) == \ +- (QEDI_MAX_RX_DESC_CNT - 1)) ? \ +- (x) + 2 : (x) + 1) +- +-#define QEDI_PATH_HANDLE 0xFE0000000 +- +-typedef struct qedi { +- nic_t *parent; +- +- struct qedi_driver_version version; +- +- uint16_t flags; +-#define CNIC_UIO_UNITIALIZED 0x0001 +-#define CNIC_UIO_INITIALIZED 0x0002 +-#define CNIC_UIO_ENABLED 0x0004 +-#define CNIC_UIO_DISABLED 0x0008 +-#define CNIC_UIO_IPv6_ENABLED 0x0010 +-#define CNIC_UIO_ADDED_MULICAST 0x0020 +-#define CNIC_UIO_MSIX_ENABLED 0x0200 +-#define CNIC_UIO_TX_HAS_SENT 0x0400 +-#define QEDI_OPENED 0x0800 +- +- __u32 chip_id; +- int func; +- int port; +- int pfid; +- __u32 cid; +- __u32 client_id; +- +- __u32 tx_prod; +- __u32 tx_bd_prod; +- __u32 tx_cons; +- __u8 tx_vlan_tag_bit; +- +- __u32 rx_prod; +- __u32 rx_bd_prod; +- __u32 rx_cons; +- __u32 rx_bd_cons; +- __u32 rx_hw_prod; +- +- __u32 (*get_rx_cons)(struct qedi *); +- __u32 (*get_tx_cons)(struct qedi *); +- +- /* RX ring parameters */ +- uint32_t rx_ring_size; +- uint32_t rx_buffer_size; +- +- void *bufs; /* Pointer to the mapped buffer space */ +- void *uctrl_map; /* UIO control structure */ +- uint32_t uctrl_map_offset; /* UIO control structure mmap offset */ +- +- uint32_t rx_index; +- void *rx_comp_ring; +- void **rx_pkt_ring; +- void *tx_pkt; +- void *rx_pkts; +-} qedi_t; +- +-/****************************************************************************** +- * qedi Function Declarations +- ******************************************************************************/ +-void qedi_start_xmit(nic_t *nic, size_t len, u16_t vlan_id); +-struct nic_ops *qedi_get_ops(); +- +-#endif /* __QEDI_H__ */ +diff --git a/iscsiuio/src/unix/logger.c b/iscsiuio/src/unix/logger.c +deleted file mode 100644 +index 87e16cd..0000000 +--- a/iscsiuio/src/unix/logger.c ++++ /dev/null +@@ -1,181 +0,0 @@ +-/* +- * Copyright (c) 2009-2011, Broadcom Corporation +- * Copyright (c) 2014, QLogic Corporation +- * +- * Written by: Benjamin Li (benli@broadcom.com) +- * +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. All advertising materials mentioning features or use of this software +- * must display the following acknowledgement: +- * This product includes software developed by Adam Dunkels. +- * 4. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * logger.c - Logging Utilities +- * +- */ +-#include +-#include +-#include +-#include +-#include +- +-#include "options.h" +-#include "logger.h" +- +-/****************************************************************************** +- * Default logger values +- ******************************************************************************/ +-static const char default_logger_filename[] = "/var/log/iscsiuio.log"; +- +-struct logger main_log = { +- .enabled = LOGGER_ENABLED, +- .fp = NULL, +- .log_file = (char *)default_logger_filename, +- .level = LOG_LEVEL_INFO, +- .lock = PTHREAD_MUTEX_INITIALIZER, +- +- .stats = { +- .debug = 0, +- .info = 0, +- .warn = 0, +- .error = 0, +- +- .last_log_time = 0, +- }, +-}; +- +-/****************************************************************************** +- * Logger Functions +- ******************************************************************************/ +-/** +- * log_uip() - Main logging function +- * @param level_str - log level string +- * @param fmt - log format +- */ +-void log_uip(char *level_str, char *fmt, ...) +-{ +- char time_buf[32]; +- va_list ap, ap2; +- +- pthread_mutex_lock(&main_log.lock); +- va_start(ap, fmt); +- +- if (main_log.fp == NULL) +- goto end; +- +- main_log.stats.last_log_time = time(NULL); +- strftime(time_buf, 26, "%a %b %d %T %Y", +- localtime(&main_log.stats.last_log_time)); +- va_copy(ap2, ap); +- +- if (main_log.enabled == LOGGER_ENABLED) { +- fprintf(main_log.fp, "%s [%s]", level_str, time_buf); +- vfprintf(main_log.fp, fmt, ap); +- fprintf(main_log.fp, "\n"); +- } +- +- if (opt.debug == DEBUG_ON) { +- fprintf(stdout, "%s [%s]", level_str, time_buf); +- vfprintf(stdout, fmt, ap2); +- fprintf(stdout, "\n"); +- +- /* Force the printing of the log file */ +- fflush(main_log.fp); +- +- /* Force the printing of the log out to standard output */ +- fflush(stdout); +- } +- +-end: +- va_end(ap2); +- va_end(ap); +- pthread_mutex_unlock(&main_log.lock); +-} +- +-/****************************************************************************** +- * Initialize/Clean up routines +- ******************************************************************************/ +-/** +- * init_logger() - Prepare the logger +- * @param filename - path to where the log will be written to +- * @return 0 on success, <0 on failure +- */ +-int init_logger(char *filename) +-{ +- int rc = 0; +- +- pthread_mutex_lock(&main_log.lock); +- +- if (opt.debug != DEBUG_ON) { +- rc = -EIO; +- goto disable; +- } +- main_log.fp = fopen(filename, "a"); +- if (main_log.fp == NULL) { +- fprintf(stderr, "WARN: Could not create log file: %s <%s>\n", +- filename, strerror(errno)); +- rc = -EIO; +- } +-disable: +- if (rc) +- main_log.enabled = LOGGER_DISABLED; +- else +- main_log.enabled = LOGGER_ENABLED; +- +- pthread_mutex_unlock(&main_log.lock); +- +- if (!rc) +- LOG_INFO("Initialize logger using log file: %s", filename); +- +- return rc; +-} +- +-void fini_logger(int type) +-{ +- pthread_mutex_lock(&main_log.lock); +- +- if (main_log.fp != NULL) { +- fclose(main_log.fp); +- main_log.fp = NULL; +- +- if (opt.debug == DEBUG_ON) { +- printf("Closed logger\n"); +- fflush(stdout); +- } +- } +- +- if (type == SHUTDOWN_LOGGER) { +- if ((main_log.log_file != NULL) && +- (main_log.log_file != default_logger_filename)) { +- free(main_log.log_file); +- main_log.log_file = NULL; +- } +- } +- +- main_log.enabled = LOGGER_DISABLED; +- +- pthread_mutex_unlock(&main_log.lock); +-} +diff --git a/iscsiuio/src/unix/logger.h b/iscsiuio/src/unix/logger.h +deleted file mode 100644 +index 06e2084..0000000 +--- a/iscsiuio/src/unix/logger.h ++++ /dev/null +@@ -1,129 +0,0 @@ +-/* +- * Copyright (c) 2009-2011, Broadcom Corporation +- * Copyright (c) 2014, QLogic Corporation +- * +- * Written by: Benjamin Li (benli@broadcom.com) +- * +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. All advertising materials mentioning features or use of this software +- * must display the following acknowledgement: +- * This product includes software developed by Adam Dunkels. +- * 4. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * logger.h - Logging Utilities +- * +- */ +-#ifndef __LOGGER_H__ +-#define __LOGGER_H__ +- +-#include +-#include +-#include +-#include +-#include +- +-/******************************************************************************* +- * Logger Levels +- ******************************************************************************/ +-#define LOG_LEVEL_PACKET 5 +-#define LOG_LEVEL_DEBUG 4 +-#define LOG_LEVEL_INFO 3 +-#define LOG_LEVEL_WARN 2 +-#define LOG_LEVEL_ERR 1 +-#define LOG_LEVEL_UNKNOWN 0 +- +-#define LOG_LEVEL_PACKET_STR "PKT " +-#define LOG_LEVEL_DEBUG_STR "DBG " +-#define LOG_LEVEL_INFO_STR "INFO " +-#define LOG_LEVEL_WARN_STR "WARN " +-#define LOG_LEVEL_ERR_STR "ERR " +-#define LOG_LEVEL_UNKNOWN_STR "? " +- +-/******************************************************************************* +- * Logging Macro's +- ******************************************************************************/ +-#define LOG_PACKET(fmt, args...) { if (LOG_LEVEL_PACKET <= \ +- main_log.level) { \ +- log_uip(LOG_LEVEL_PACKET_STR, fmt,\ +- ##args);\ +- } } +-#define LOG_DEBUG(fmt, args...) { if (LOG_LEVEL_DEBUG <= main_log.level) { \ +- log_uip(LOG_LEVEL_DEBUG_STR, fmt,\ +- ##args);\ +- } } +- +-#define LOG_INFO(fmt, args...) { if (LOG_LEVEL_INFO <= main_log.level) { \ +- log_uip(LOG_LEVEL_INFO_STR, fmt,\ +- ##args); \ +- } } +-#define LOG_WARN(fmt, args...) { if (LOG_LEVEL_WARN <= main_log.level) { \ +- log_uip(LOG_LEVEL_WARN_STR, fmt,\ +- ##args); \ +- } } +-#define LOG_ERR(fmt, args...) { if (LOG_LEVEL_ERR <= main_log.level) { \ +- log_uip(LOG_LEVEL_ERR_STR, fmt,\ +- ##args); \ +- } } +- +-/******************************************************************************* +- * Logging Statistics +- ******************************************************************************/ +-struct logger_stats { +- uint64_t debug; +- uint64_t info; +- uint64_t warn; +- uint64_t error; +- +- time_t last_log_time; +-}; +- +-/******************************************************************************* +- * Logger Structure +- ******************************************************************************/ +-struct logger { +- FILE *fp; +- char *log_file; +- int8_t level; +- +-#define LOGGER_ENABLED 0x01 +-#define LOGGER_DISABLED 0x02 +- int8_t enabled; +- +- pthread_mutex_t lock; +- +- struct logger_stats stats; +-}; +- +-extern struct logger main_log; +- +-int init_logger(char *); +-void log_uip(char *level_str, char *fmt, ...); +-void fini_logger(int); +- +-#define CLOSE_LOGGER 0x01 +-#define SHUTDOWN_LOGGER 0x02 +- +-#endif +diff --git a/iscsiuio/src/unix/main.c b/iscsiuio/src/unix/main.c +deleted file mode 100644 +index 0c9ad49..0000000 +--- a/iscsiuio/src/unix/main.c ++++ /dev/null +@@ -1,442 +0,0 @@ +-/* +- * Copyright (c) 2001, Adam Dunkels. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. All advertising materials mentioning features or use of this software +- * must display the following acknowledgement: +- * This product includes software developed by Adam Dunkels. +- * 4. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * This file is part of the uIP TCP/IP stack. +- * +- * +- */ +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#ifndef NO_SYSTEMD +-#include +-#endif +-#include +- +-#include "uip.h" +-#include "uip_arp.h" +-#include "uip_eth.h" +- +-#include "timer.h" +- +-#include "build_date.h" +-#include "config.h" +-#include "iscsid_ipc.h" +-#include "logger.h" +-#include "nic.h" +-#include "nic_id.h" +-#include "nic_nl.h" +-#include "nic_utils.h" +-#include "options.h" +-#include "packet.h" +- +-#include "dhcpc.h" +- +-#include "iscsid_ipc.h" +-#include "brcm_iscsi.h" +- +-/******************************************************************************* +- * Constants +- ******************************************************************************/ +-#define PFX "main " +- +-static const char default_pid_filepath[] = "/run/iscsiuio.pid"; +- +-/******************************************************************************* +- * Global Variables +- ******************************************************************************/ +-static const struct option long_options[] = { +- {"foreground", no_argument, NULL, 'f'}, +- {"debug", required_argument, NULL, 'd'}, +- {"pid", required_argument, NULL, 'p'}, +- {"version", no_argument, NULL, 'v'}, +- {"help", no_argument, NULL, 'h'}, +- {NULL, no_argument, NULL, 0} +-}; +- +-struct options opt = { +- .debug = DEBUG_OFF, +-}; +- +-int event_loop_stop; +-extern nic_t *nic_list; +- +-struct utsname cur_utsname; +- +-/** +- * cleanup() - This function is called when this program is to be closed +- * This function will clean up all the cnic uio interfaces and +- * flush/close the logger +- */ +-static void cleanup() +-{ +- iscsid_cleanup(); +- +- nic_remove_all(); +- +- unload_all_nic_libraries(); +- +- LOG_INFO("Done waiting for cnic's/stacks to gracefully close"); +- +- fini_logger(SHUTDOWN_LOGGER); +-} +- +-/** +- * signal_handle_thread() - This is the signal handling thread of this program +- * This is the only thread which will handle signals. +- * All signals are routed here and handled here to +- * provide consistant handling. +- */ +-static pthread_t signal_thread; +-static void *signal_handle_thread(void *arg) +-{ +- sigset_t set; +- int rc; +- int signal; +- +- sigfillset(&set); +- +- LOG_INFO("signal handling thread ready"); +- +-signal_wait: +- rc = sigwait(&set, &signal); +- +- switch (signal) { +- case SIGINT: +- LOG_INFO("Caught SIGINT signal"); +- break; +- case SIGUSR1: +- LOG_INFO("Caught SIGUSR1 signal, rotate log"); +- fini_logger(SHUTDOWN_LOGGER); +- rc = init_logger(main_log.log_file); +- if (rc != 0) +- fprintf(stderr, "WARN: Could not initialize the logger in " +- "signal!\n"); +- goto signal_wait; +- default: +- break; +- } +- event_loop_stop = 1; +- +- LOG_INFO("terminating..."); +- +- cleanup(); +- exit(EXIT_SUCCESS); +-} +- +-static void show_version() +-{ +- printf("%s: Version '%s', Build Date: '%s'\n", +- APP_NAME, PACKAGE_VERSION, build_date); +-} +- +-static void main_usage() +-{ +- show_version(); +- +- printf("\nUsage: %s [OPTION]\n", APP_NAME); +- printf("iscsiuio daemon.\n" +- "-f, --foreground make the program run in the foreground\n" +- "-d, --debug debuglevel print debugging information\n" +- "-p, --pid pidfile use pid file (default %s).\n" +- "-h, --help display this help and exit\n" +- "-v, --version display version and exit\n", +- default_pid_filepath); +-} +- +-static void daemon_init() +-{ +- int fd; +- int res; +- +- fd = open("/dev/null", O_RDWR); +- assert(fd >= 0); +- +- dup2(fd, 0); +- dup2(fd, 1); +- dup2(fd, 2); +- setsid(); +- res = chdir("/"); +- assert(res == 0); +- close(fd); +-} +- +-#define ISCSI_OOM_PATH_LEN 48 +- +-int oom_adjust(void) +-{ +- int fd; +- char path[ISCSI_OOM_PATH_LEN]; +- struct stat statb; +- +- if (nice(-10) < 0) +- LOG_DEBUG("Could not increase process priority: %s", +- strerror(errno)); +- +- snprintf(path, ISCSI_OOM_PATH_LEN, "/proc/%d/oom_score_adj", getpid()); +- if (stat(path, &statb)) { +- /* older kernel so use old oom_adj file */ +- snprintf(path, ISCSI_OOM_PATH_LEN, "/proc/%d/oom_adj", +- getpid()); +- } +- fd = open(path, O_WRONLY); +- if (fd < 0) +- return -1; +- if (write(fd, "-16", 3) < 0) /* for 2.6.11 */ +- LOG_DEBUG("Could not set oom score to -16: %s", +- strerror(errno)); +- if (write(fd, "-17", 3) < 0) /* for Andrea's patch */ +- LOG_DEBUG("Could not set oom score to -17: %s", +- strerror(errno)); +- close(fd); +- return 0; +-} +- +- +-/******************************************************************************* +- * Main routine +- ******************************************************************************/ +-int main(int argc, char *argv[]) +-{ +- int rc; +- sigset_t set; +- const char *pid_file = default_pid_filepath; +- int fd; +- int foreground = 0; +- pid_t pid; +- pthread_attr_t attr; +- int pipefds[2]; +- +- /* Record the start time for the user space daemon */ +- opt.start_time = time(NULL); +- +- /* parse the parameters */ +- while (1) { +- int c, option_index; +- +- c = getopt_long(argc, argv, "fd:p:vh", +- long_options, &option_index); +- +- if (c == -1) +- break; +- +- switch (c) { +- +- case 'f': +- foreground = 1; +- break; +- +- /* Enable debugging mode */ +- case 'd': +- main_log.level = atoi(optarg); +- opt.debug = DEBUG_ON; +- break; +- case 'p': +- pid_file = optarg; +- break; +- case 'v': +- show_version(); +- exit(EXIT_SUCCESS); +- case 'h': +- default: +- main_usage(); +- exit(EXIT_SUCCESS); +- } +- } +- +- if (main_log.enabled == LOGGER_ENABLED) { +- /* initialize the logger */ +- rc = init_logger(main_log.log_file); +- if (rc != 0 && opt.debug == DEBUG_ON) +- fprintf(stderr, "WARN: Could not initialize the logger\n"); +- } +- +- LOG_INFO("Started iSCSI uio stack: Ver " PACKAGE_VERSION); +- LOG_INFO("Build date: %s", build_date); +- +- if (opt.debug == DEBUG_ON) +- LOG_INFO("Debug mode enabled"); +- +- event_loop_stop = 0; +- nic_list = NULL; +- +- /* Determine the current kernel version */ +- memset(&cur_utsname, 0, sizeof(cur_utsname)); +- +- rc = uname(&cur_utsname); +- if (rc == 0) { +- LOG_INFO("Running on sysname: '%s', release: '%s', " +- "version '%s' machine: '%s'", +- cur_utsname.sysname, cur_utsname.release, +- cur_utsname.version, cur_utsname.machine); +- } else +- LOG_WARN("Could not determine kernel version"); +- +- /* Initialze the iscsid listener */ +- rc = iscsid_init(); +- if (rc != 0) +- goto error; +- +- if (!foreground) { +- char buf[64]; +- ssize_t written_bytes; +- +- fd = open(pid_file, O_WRONLY | O_CREAT, 0644); +- if (fd < 0) { +- fprintf(stderr, "ERR: Unable to create pid file: %s\n", +- pid_file); +- exit(1); +- } +- +- if (pipe(pipefds) < 0) { +- fprintf(stderr, "ERR: Unable to create a PIPE: %s\n", +- strerror(errno)); +- exit(1); +- } +- +- pid = fork(); +- if (pid < 0) { +- fprintf(stderr, "ERR: Starting daemon failed\n"); +- exit(1); +- } else if (pid) { +- char msgbuf[4]; +- int res; +- +- /* parent: wait for child msg then exit */ +- close(pipefds[1]); /* close unused end */ +- res = read(pipefds[0], msgbuf, sizeof(msgbuf)); +- assert(res > 0); +- exit(0); +- } +- +- /* the child */ +- rc = chdir("/"); +- if (rc == -1) +- fprintf(stderr, "WARN: Unable to chdir(\") [%s]\n", strerror(errno)); +- +- if (lockf(fd, F_TLOCK, 0) < 0) { +- fprintf(stderr, "ERR: Unable to lock pid file: %s [%s]\n", +- pid_file, strerror(errno)); +- exit(1); +- } +- +- rc = ftruncate(fd, 0); +- if (rc == -1) +- fprintf(stderr, "WARN: ftruncate(%d, 0) failed [%s]\n", +- fd, strerror(errno)); +- +- sprintf(buf, "%d\n", getpid()); +- written_bytes = write(fd, buf, strlen(buf)); +- if (written_bytes == -1) { +- fprintf(stderr, "ERR: Could not write pid file [%s]\n", +- strerror(errno)); +- exit(1); +- } +- close(fd); +- +- daemon_init(); +- } +- +- /* Load the NIC libraries */ +- rc = load_all_nic_libraries(); +- if (rc != 0) +- goto error; +- +- brcm_iscsi_init(); +- +- /* ensure we don't see any signals */ +- sigemptyset(&set); +- sigaddset(&set, SIGINT); +- sigaddset(&set, SIGQUIT); +- sigaddset(&set, SIGTERM); +- sigaddset(&set, SIGUSR1); +- rc = pthread_sigmask(SIG_SETMASK, &set, NULL); +- +- /* Spin off the signal handling thread */ +- pthread_attr_init(&attr); +- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); +- rc = pthread_create(&signal_thread, &attr, signal_handle_thread, NULL); +- if (rc != 0) +- LOG_ERR("Could not create signal handling thread"); +- +- /* Using sysfs to discover iSCSI hosts */ +- nic_discover_iscsi_hosts(); +- +- /* oom-killer will not kill us at the night... */ +- if (oom_adjust()) +- LOG_DEBUG("Can not adjust oom-killer's pardon"); +- +- /* we don't want our active sessions to be paged out... */ +- if (mlockall(MCL_CURRENT | MCL_FUTURE)) { +- LOG_ERR("failed to mlockall, exiting..."); +- goto error; +- } +- +- /* Start the iscsid listener */ +- rc = iscsid_start(); +- if (rc != 0) +- goto error; +- +- if (!foreground) { +- int res; +- +- /* signal parent they can go away now */ +- close(pipefds[0]); /* close unused end */ +- res = write(pipefds[1], "ok\n", 3); +- assert(res > 0); +- close(pipefds[1]); +- } +- +-#ifndef NO_SYSTEMD +- sd_notify(0, "READY=1\n" +- "STATUS=Ready to process requests\n"); +-#endif +- +- /* NetLink connection to listen to NETLINK_ISCSI private messages */ +- if (nic_nl_open() != 0) +- goto error; +- +-error: +- cleanup(); +- exit(EXIT_FAILURE); +-} +diff --git a/iscsiuio/src/unix/nic.c b/iscsiuio/src/unix/nic.c +deleted file mode 100644 +index f449935..0000000 +--- a/iscsiuio/src/unix/nic.c ++++ /dev/null +@@ -1,1548 +0,0 @@ +-/* +- * Copyright (c) 2009-2011, Broadcom Corporation +- * Copyright (c) 2014, QLogic Corporation +- * +- * Written by: Benjamin Li (benli@broadcom.com) +- * +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. All advertising materials mentioning features or use of this software +- * must display the following acknowledgement: +- * This product includes software developed by Adam Dunkels. +- * 4. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * nic.c - Generic NIC management/utility functions +- * +- */ +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include "dhcpc.h" +-#include "ipv6_ndpc.h" +- +-#include "logger.h" +-#include "nic.h" +-#include "nic_utils.h" +-#include "options.h" +- +-#include "uip.h" +-#include "uip_arp.h" +-#include "uip_eth.h" +-#include "uip-neighbor.h" +- +-#include "bnx2.h" +-#include "bnx2x.h" +-#include "qedi.h" +-#include "ipv6.h" +- +-/****************************************************************************** +- * Constants +- *****************************************************************************/ +-#define PFX "nic " +-#define PCI_ANY_ID (~0) +- +-/****************************************************************************** +- * Global variables +- *****************************************************************************/ +-/* Used to store a list of NIC libraries */ +-pthread_mutex_t nic_lib_list_mutex = PTHREAD_MUTEX_INITIALIZER; +-nic_lib_handle_t *nic_lib_list; +- +-/* Used to store a list of active cnic devices */ +-pthread_mutex_t nic_list_mutex = PTHREAD_MUTEX_INITIALIZER; +-nic_t *nic_list; +- +-/****************************************************************************** +- * Functions to handle NIC libraries +- *****************************************************************************/ +-/** +- * alloc_nic_library_handle() - Used to allocate a NIC library handle +- * @return NULL if memory couldn't be allocated, pointer to the handle +- * to the NIC library handle +- */ +-static nic_lib_handle_t *alloc_nic_library_handle() +-{ +- nic_lib_handle_t *handle; +- +- handle = malloc(sizeof(*handle)); +- if (handle == NULL) { +- LOG_ERR("Could not allocate memory for library handle"); +- return NULL; +- } +- +- memset(handle, 0, sizeof(*handle)); +- handle->ops = NULL; +- +- pthread_mutex_init(&handle->mutex, NULL); +- +- return handle; +-} +- +-static void free_nic_library_handle(nic_lib_handle_t *handle) +-{ +- free(handle); +-} +- +-/** +- * load_nic_library() - This function is used to load a NIC library +- * @param handle - This is the library handle to load +- * @return 0 = Success; <0 = failure +- */ +-static int load_nic_library(nic_lib_handle_t *handle) +-{ +- int rc; +- char *library_name; +- size_t library_name_size; +- char *library_version; +- size_t library_version_size; +- char *build_date_str; +- size_t build_date_str_size; +- +- pthread_mutex_lock(&handle->mutex); +- +- /* Validate the NIC ops table ensure that all the fields are not NULL */ +- if ((handle->ops->open) == NULL || +- (handle->ops->close) == NULL || +- (handle->ops->read) == NULL || +- (handle->ops->write) == NULL || +- (handle->ops->clear_tx_intr == NULL)) { +- LOG_ERR("Invalid NIC ops table: open: 0x%x, close: 0x%x," +- "read: 0x%x, write: 0x%x clear_tx_intr: 0x%x " +- "lib_ops: 0x%x", +- handle->ops->open, handle->ops->close, +- handle->ops->read, handle->ops->write, +- handle->ops->clear_tx_intr, handle->ops->lib_ops); +- rc = -EINVAL; +- handle->ops = NULL; +- goto error; +- } +- +- /* Validate the NIC library ops table to ensure that all the proper +- * fields are filled */ +- if ((handle->ops->lib_ops.get_library_name == NULL) || +- (handle->ops->lib_ops.get_library_version == NULL) || +- (handle->ops->lib_ops.get_build_date == NULL) || +- (handle->ops->lib_ops.get_transport_name == NULL)) { +- rc = -EINVAL; +- goto error; +- } +- +- (*handle->ops->lib_ops.get_library_name) (&library_name, +- &library_name_size); +- (*handle->ops->lib_ops.get_library_version) (&library_version, +- &library_version_size); +- (*handle->ops->lib_ops.get_build_date) (&build_date_str, +- &build_date_str_size); +- +- LOG_DEBUG("Loaded nic library '%s' Version: '%s' build on %s'", +- library_name, library_version, build_date_str); +- +- pthread_mutex_unlock(&handle->mutex); +- +- return 0; +- +-error: +- pthread_mutex_unlock(&handle->mutex); +- +- return rc; +-} +- +-static struct nic_ops *(*nic_get_ops[]) () = { +-bnx2_get_ops, bnx2x_get_ops, qedi_get_ops}; +- +-int load_all_nic_libraries() +-{ +- int rc, i = 0; +- nic_lib_handle_t *handle; +- +- for (i = 0; i < sizeof(nic_get_ops) / sizeof(nic_get_ops[0]); i++) { +- /* Add the CNIC library */ +- handle = alloc_nic_library_handle(); +- if (handle == NULL) { +- LOG_ERR("Could not allocate memory for CNIC nic lib"); +- return -ENOMEM; +- } +- +- handle->ops = (*nic_get_ops[i]) (); +- +- rc = load_nic_library(handle); +- 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); +- +- /* Add this library to the list of nic libraries we +- * know about */ +- if (nic_lib_list == NULL) { +- nic_lib_list = handle; +- } else { +- nic_lib_handle_t *current = nic_lib_list; +- +- while (current->next != NULL) +- current = current->next; +- +- current->next = handle; +- } +- pthread_mutex_unlock(&nic_lib_list_mutex); +- +- LOG_DEBUG("Added '%s' nic library", handle->ops->description); +- } +- +- return rc; +-} +- +-int unload_all_nic_libraries() +-{ +- nic_lib_handle_t *current, *next; +- +- pthread_mutex_lock(&nic_lib_list_mutex); +- current = nic_lib_list; +- +- while (current != NULL) { +- next = current->next; +- free_nic_library_handle(current); +- +- current = next; +- } +- +- pthread_mutex_unlock(&nic_lib_list_mutex); +- +- nic_lib_list = NULL; +- +- return 0; +-} +- +-NIC_LIBRARY_EXIST_T does_nic_uio_name_exist(char *name, +- nic_lib_handle_t **handle) +-{ +- NIC_LIBRARY_EXIST_T rc; +- nic_lib_handle_t *current; +- +- pthread_mutex_lock(&nic_lib_list_mutex); +- current = nic_lib_list; +- +- while (current != NULL) { +- char *uio_name; +- size_t uio_name_size; +- +- (*current->ops->lib_ops.get_uio_name) (&uio_name, +- &uio_name_size); +- +- if (strncmp(name, uio_name, uio_name_size) == 0) { +- if (handle) +- *handle = current; +- +- rc = NIC_LIBRARY_EXSITS; +- goto done; +- } +- +- current = current->next; +- } +- +- rc = NIC_LIBRARY_DOESNT_EXIST; +- +-done: +- pthread_mutex_unlock(&nic_lib_list_mutex); +- return rc; +-} +- +-NIC_LIBRARY_EXIST_T does_nic_library_exist(char *name, +- nic_lib_handle_t **handle) +-{ +- NIC_LIBRARY_EXIST_T rc; +- nic_lib_handle_t *current; +- +- pthread_mutex_lock(&nic_lib_list_mutex); +- current = nic_lib_list; +- +- while (current != NULL) { +- char *library_name; +- size_t library_name_size; +- +- (*current->ops->lib_ops.get_library_name) (&library_name, +- &library_name_size); +- +- if (strncmp(name, library_name, library_name_size) == 0) { +- if (handle) +- *handle = current; +- +- rc = NIC_LIBRARY_EXSITS; +- goto done; +- } +- +- current = current->next; +- } +- +- rc = NIC_LIBRARY_DOESNT_EXIST; +- +-done: +- pthread_mutex_unlock(&nic_lib_list_mutex); +- return rc; +-} +- +-/** +- * find_nic_lib_using_pci_id() - Find the proper NIC library using the +- * PCI ID's +- * @param vendor - PCI vendor ID to search on +- * @param device - PCI device ID to search on +- * @param subvendor - PCI subvendor ID to search on +- * @param subdevice - PCI subdevice ID to search on +- * @param handle - This function will return the nic lib handle if found +- * @return 0 if found, <0 not found +- */ +-int find_nic_lib_using_pci_id(uint32_t vendor, uint32_t device, +- uint32_t subvendor, uint32_t subdevice, +- nic_lib_handle_t **handle, +- struct pci_device_id **pci_entry) +-{ +- int rc; +- nic_lib_handle_t *current; +- +- pthread_mutex_lock(&nic_lib_list_mutex); +- current = nic_lib_list; +- +- while (current != NULL) { +- struct pci_device_id *pci_table; +- uint32_t entries; +- int i; +- +- if (current->ops->lib_ops.get_pci_table != NULL) { +- current->ops->lib_ops.get_pci_table(&pci_table, +- &entries); +- } else { +- current = current->next; +- continue; +- } +- /* Sanity check the the pci table coming from the +- * hardware library */ +- if (entries > MAX_PCI_DEVICE_ENTRIES) { +- LOG_WARN(PFX "Too many pci_table entries(%d) skipping", +- entries); +- continue; +- } +- +- for (i = 0; i < entries; i++) { +- LOG_DEBUG(PFX "Checking against: " +- "vendor: 0x%x device:0x%x " +- "subvendor:0x%x subdevice:0x%x", +- pci_table[i].vendor, pci_table[i].device, +- pci_table[i].subvendor, +- pci_table[i].subdevice); +- +- if ((pci_table[i].vendor == vendor) && +- (pci_table[i].device == device) && +- (pci_table[i].subvendor == PCI_ANY_ID || +- pci_table[i].subvendor == subvendor) && +- (pci_table[i].subdevice == PCI_ANY_ID || +- pci_table[i].subdevice == subdevice)) { +- *handle = current; +- *pci_entry = &pci_table[i]; +- rc = 0; +- goto done; +- } +- } +- +- current = current->next; +- } +- rc = -EINVAL; +- +-done: +- pthread_mutex_unlock(&nic_lib_list_mutex); +- +- return rc; +-} +- +-/** +- * nic_init() - This will properly initialize a struct cnic_uio device +- * @return NULL is there is a failure and pointer to an allocated/initialized +- * struct cnic_uio on success +- */ +-nic_t *nic_init() +-{ +- nic_t *nic; +- +- nic = malloc(sizeof(*nic)); +- if (nic == NULL) { +- LOG_ERR("Couldn't malloc space for nic"); +- return NULL; +- } +- +- memset(nic, 0, sizeof(*nic)); +- nic->uio_minor = -1; +- nic->fd = INVALID_FD; +- nic->host_no = INVALID_HOST_NO; +- nic->next = NULL; +- nic->thread = INVALID_THREAD; +- nic->enable_thread = INVALID_THREAD; +- 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->page_size = getpagesize(); +- +- /* 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); +- +- pthread_cond_init(&nic->enable_wait_cond, NULL); +- pthread_cond_init(&nic->enable_done_cond, NULL); +- pthread_cond_init(&nic->nic_loop_started_cond, NULL); +- pthread_cond_init(&nic->disable_wait_cond, NULL); +- +- 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)); +- +- nic->ping_thread = INVALID_THREAD; +- +- return nic; +-} +- +-void nic_add(nic_t *nic) +-{ +- /* Add this device to our list of nics */ +- if (nic_list == NULL) { +- nic_list = nic; +- } else { +- nic_t *current = nic_list; +- +- while (current->next != NULL) +- current = current->next; +- +- current->next = nic; +- } +-} +- +-/** +- * nic_remove() - Used to remove the NIC for the nic list +- * @param nic - the nic to remove +- */ +-int nic_remove(nic_t *nic) +-{ +- int rc; +- nic_t *prev, *current; +- struct stat file_stat; +- nic_interface_t *nic_iface, *next_nic_iface, *vlan_iface; +- +- pthread_mutex_lock(&nic->nic_mutex); +- +- /* Check if the file node exists before closing */ +- if (nic->uio_device_name) { +- rc = stat(nic->uio_device_name, &file_stat); +- if ((rc == 0) && (nic->ops)) +- nic->ops->close(nic, 0); +- } +- pthread_mutex_unlock(&nic->nic_mutex); +- +- nic->state = NIC_EXIT; +- +- if (nic->enable_thread != INVALID_THREAD) { +- LOG_DEBUG(PFX "%s: Canceling nic enable thread", nic->log_name); +- +- rc = pthread_cancel(nic->enable_thread); +- if (rc != 0) +- LOG_DEBUG(PFX "%s: Couldn't send cancel to nic enable " +- "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_DEBUG(PFX "%s: Canceling nic thread", nic->log_name); +- +- rc = pthread_cancel(nic->thread); +- if (rc != 0) +- LOG_DEBUG(PFX "%s: Couldn't send cancel to nic", +- 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); +- +- nic->nl_process_thread = INVALID_THREAD; +- LOG_DEBUG(PFX "%s: nic nl thread cleaned", nic->log_name); +- } else { +- LOG_DEBUG(PFX "%s: NIC nl thread already canceled", +- nic->log_name); +- } +- +- current = prev = nic_list; +- while (current != NULL) { +- if (current == nic) +- break; +- +- prev = current; +- current = current->next; +- } +- +- if (current != NULL) { +- if (current == nic_list) +- nic_list = current->next; +- else +- prev->next = current->next; +- +- /* Before freeing the nic, must free all the associated +- nic_iface */ +- nic_iface = current->nic_iface; +- while (nic_iface != NULL) { +- vlan_iface = nic_iface->vlan_next; +- while (vlan_iface != NULL) { +- next_nic_iface = vlan_iface->vlan_next; +- free(vlan_iface); +- vlan_iface = next_nic_iface; +- } +- next_nic_iface = nic_iface->next; +- free(nic_iface); +- nic_iface = next_nic_iface; +- } +- free(nic); +- } else { +- LOG_ERR(PFX "%s: Couldn't find nic to remove", nic->log_name); +- } +- +- return 0; +-} +- +-/** +- * nic_close() - Used to indicate to a NIC that it should close +- * Must be called with nic->nic_mutex +- * @param nic - the nic to close +- * @param graceful - ALLOW_GRACEFUL_SHUTDOWN will check the nic state +- * before proceeding to close() +- * FORCE_SHUTDOWN will force the nic to close() +- * reguardless of the state +- * @param clean - this will free the proper strings assoicated +- * with the NIC +- * +- */ +-void nic_close(nic_t *nic, NIC_SHUTDOWN_T graceful, int clean) +-{ +- int rc; +- nic_interface_t *nic_iface, *vlan_iface; +- struct stat file_stat; +- +- /* The NIC could be configured by the uIP config file +- * but not assoicated with a hardware library just yet +- * we will need to check for this */ +- if (nic->ops == NULL) { +- LOG_WARN(PFX "%s: when closing nic->ops == NULL", +- nic->log_name); +- goto error; +- } +- +- /* Check if the file node exists */ +- rc = stat(nic->uio_device_name, &file_stat); +- if ((rc == 0) && (nic->ops)) +- rc = (*nic->ops->close) (nic, graceful); +- if (rc != 0) { +- LOG_ERR(PFX "%s: Could not close nic", nic->log_name); +- } else { +- nic->state = NIC_STOPPED; +- nic->flags &= ~NIC_ENABLED; +- nic->flags |= NIC_DISABLED; +- } +- +- nic_iface = nic->nic_iface; +- while (nic_iface != NULL) { +- if (!((nic_iface->flags & NIC_IFACE_PERSIST) == +- NIC_IFACE_PERSIST)) { +- uip_reset(&nic_iface->ustack); +- vlan_iface = nic_iface->vlan_next; +- while (vlan_iface != NULL) { +- uip_reset(&vlan_iface->ustack); +- vlan_iface = vlan_iface->vlan_next; +- } +- } +- nic_iface = nic_iface->next; +- } +- +- /* The NIC must be destroyed and init'ed once again, +- * POSIX defines that the mutex will be undefined it +- * init'ed twice without a destroy */ +- pthread_mutex_destroy(&nic->xmit_mutex); +- pthread_mutex_init(&nic->xmit_mutex, NULL); +- +- if (clean & FREE_CONFIG_NAME) { +- /* Free any named strings we might be holding onto */ +- if (nic->flags & NIC_CONFIG_NAME_MALLOC) { +- free(nic->config_device_name); +- nic->flags &= ~NIC_CONFIG_NAME_MALLOC; +- } +- nic->config_device_name = NULL; +- } +- +- if (clean & FREE_UIO_NAME) { +- if (nic->flags & NIC_UIO_NAME_MALLOC) { +- free(nic->uio_device_name); +- nic->uio_device_name = NULL; +- +- nic->flags &= ~NIC_UIO_NAME_MALLOC; +- } +- } +- +- LOG_ERR(PFX "%s: nic closed", nic->log_name); +-error: +- return; +-} +- +-/** +- * nic_iface_init() - This function is used to add an interface to the +- * structure cnic_uio +- * @return 0 on success, <0 on failure +- */ +-nic_interface_t *nic_iface_init() +-{ +- nic_interface_t *nic_iface = malloc(sizeof(*nic_iface)); +- if (nic_iface == NULL) { +- LOG_ERR("Could not allocate space for nic iface"); +- return NULL; +- } +- +- 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; +-} +- +-/** +- * 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) +-{ +- 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; +- } +- +- 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; +- } +- 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); +- +- return 0; +-} +- +-/****************************************************************************** +- * Routine to process interrupts from the NIC device +- ******************************************************************************/ +-/** +- * nic_process_intr() - Routine used to process interrupts from the hardware +- * @param nic - NIC hardware to process the interrupt on +- * @return 0 on success, <0 on failure +- */ +-int nic_process_intr(nic_t *nic, int discard_check) +-{ +- fd_set fdset; +- int ret; +- int count; +- struct timeval tv; +- +- /* Simple sanity checks */ +- if (discard_check != 1 && nic->state != NIC_RUNNING) { +- LOG_ERR(PFX "%s: Couldn't process interrupt NIC not running", +- nic->log_name); +- return -EBUSY; +- } +- +- if (discard_check != 1 && nic->fd == INVALID_FD) { +- LOG_ERR(PFX "%s: NIC fd not valid", nic->log_name); +- return -EIO; +- } +- +- FD_ZERO(&fdset); +- FD_SET(nic->fd, &fdset); +- +- tv.tv_sec = 0; +- pthread_mutex_lock(&nic->nic_mutex); +- if (nic->flags & NIC_LONG_SLEEP) +- tv.tv_usec = 1000; +- 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); +- switch (ret) { +- case 1: +- /* Usually there should only be one file descriptor ready +- * to read */ +- break; +- case 0: +- return ret; +- case -1: +- LOG_ERR(PFX "%s: error waiting for interrupt: %s", +- nic->log_name, strerror(errno)); +- return 0; +- default: +- LOG_ERR(PFX "%s: unknown number of FD's, ignoring: %d ret", +- nic->log_name, ret); +- return 0; +- } +- +- ret = read(nic->fd, &count, sizeof(count)); +- pthread_mutex_lock(&nic->nic_mutex); +- if (ret > 0) { +- nic->stats.interrupts++; +- LOG_PACKET(PFX "%s: interrupt count: %d prev: %d", +- nic->log_name, count, nic->intr_count); +- +- if (count == nic->intr_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_PACKET(PFX "%s: Missed interrupt! on %d not %d", +- nic->log_name, count, nic->intr_count); +- } +- +- nic->intr_count = count; +- +- if (strcmp(nic->ops->description, "qedi")) { +- LOG_DEBUG(PFX "%s: host:%d - calling clear_tx_intr from process_intr", +- nic->log_name, nic->host_no); +- (*nic->ops->clear_tx_intr) (nic); +- } +- +- ret = 1; +- } +- pthread_mutex_unlock(&nic->nic_mutex); +- +- return ret; +-} +- +-void prepare_ipv4_packet(nic_t *nic, +- nic_interface_t *nic_iface, +- struct uip_stack *ustack, packet_t *pkt) +-{ +- u16_t ipaddr[2]; +- arp_table_query_t arp_query; +- dest_ipv4_addr_t dest_ipv4_addr; +- struct arp_entry *tabptr; +- int queue_rc; +- int vlan_id = 0; +- +- /* 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); +- return; +- } +- +- arp_query = is_in_arp_table(ipaddr, &tabptr); +- +- switch (arp_query) { +- case IS_IN_ARP_TABLE: +- uip_build_eth_header(ustack, +- ipaddr, tabptr, pkt, vlan_id); +- break; +- case NOT_IN_ARP_TABLE: +- queue_rc = nic_queue_tx_packet(nic, nic_iface, pkt); +- if (queue_rc) { +- LOG_ERR("could not queue TX packet: %d", queue_rc); +- } else { +- uip_build_arp_request(ustack, ipaddr); +- } +- break; +- default: +- LOG_ERR("Unknown arp state"); +- break; +- } +-} +- +-void prepare_ipv6_packet(nic_t *nic, +- nic_interface_t *nic_iface, +- struct uip_stack *ustack, packet_t *pkt) +-{ +- struct uip_eth_hdr *eth; +- struct uip_vlan_eth_hdr *eth_vlan; +- int vlan_id = 0; +- +- 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) { +- eth->type = htons(UIP_ETHTYPE_IPv6); +- } else { +- eth_vlan->tpid = htons(UIP_ETHTYPE_8021Q); +- eth_vlan->vid = htons(vlan_id); +- eth_vlan->type = htons(UIP_ETHTYPE_IPv6); +- } +-} +- +-void prepare_ustack(nic_t *nic, +- nic_interface_t *nic_iface, +- struct uip_stack *ustack, struct packet *pkt) +-{ +- struct ether_header *eth = NULL; +- ustack->uip_buf = pkt->buf; +- ustack->uip_len = pkt->buf_size; +- +- pkt->nic = nic; +- pkt->nic_iface = nic_iface; +- +- ustack->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 */ +- 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 = htons(UIP_ETHTYPE_IPv6); +- } +-} +- +-int do_timers_per_nic_iface(nic_t *nic, nic_interface_t *nic_iface, +- struct timer *arp_timer) +-{ +- packet_t *pkt; +- struct uip_stack *ustack = &nic_iface->ustack; +- int i; +- +- pkt = get_next_free_packet(nic); +- if (pkt == NULL) +- return -EIO; +- +- if (nic_iface->protocol == AF_INET) { +- for (i = 0; i < UIP_UDP_CONNS; i++) { +- prepare_ustack(nic, nic_iface, 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, nic_iface, ustack, +- pkt); +- +- (*nic->ops->write) (nic, nic_iface, 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; +-} +- +-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; +- +- timer_reset(periodic_timer); +- +- pthread_mutex_lock(&nic->nic_mutex); +- +- 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; +-} +- +-int process_packets(nic_t *nic, +- struct timer *periodic_timer, +- struct timer *arp_timer, nic_interface_t *nic_iface) +-{ +- int rc; +- packet_t *pkt; +- +- pkt = get_next_free_packet(nic); +- if (pkt == NULL) { +- LOG_DEBUG(PFX "%s: Couldn't get buffer for processing packet", +- nic->log_name); +- return -ENOMEM; +- } +- +- pthread_mutex_lock(&nic->nic_mutex); +- rc = (*nic->ops->read) (nic, pkt); +- pthread_mutex_unlock(&nic->nic_mutex); +- +- if ((rc != 0) && (pkt->buf_size > 0)) { +- uint16_t type = 0; +- int af_type = 0; +- struct uip_stack *ustack; +- uint16_t vlan_id; +- +- pkt->data_link_layer = pkt->buf; +- +- vlan_id = pkt->vlan_tag & 0xFFF; +- if ((vlan_id == 0) || +- (NIC_VLAN_STRIP_ENABLED & nic->flags)) { +- struct uip_eth_hdr *hdr = ETH_BUF(pkt->buf); +- type = ntohs(hdr->type); +- pkt->network_layer = pkt->data_link_layer + +- sizeof(struct uip_eth_hdr); +- } else { +- struct uip_vlan_eth_hdr *hdr = VLAN_ETH_BUF(pkt->buf); +- type = ntohs(hdr->type); +- pkt->network_layer = pkt->data_link_layer + +- sizeof(struct uip_vlan_eth_hdr); +- } +- +- switch (type) { +- case UIP_ETHTYPE_IPv6: +- af_type = AF_INET6; +- break; +- case UIP_ETHTYPE_IPv4: +- case UIP_ETHTYPE_ARP: +- af_type = AF_INET; +- LOG_DEBUG(PFX "%s: ARP or IPv4 vlan:0x%x ethertype:0x%x", +- nic->log_name, vlan_id, type); +- break; +- default: +- LOG_DEBUG(PFX "%s: Ignoring vlan:0x%x ethertype:0x%x", +- nic->log_name, vlan_id, type); +- goto done; +- } +- +- pthread_mutex_lock(&nic->nic_mutex); +- +- /* 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_DEBUG(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; +- LOG_DEBUG(PFX "%s: found nic iface, type=0x%x, bufsize=%d", +- nic->log_name, type, pkt->buf_size); +- +- ustack = &nic_iface->ustack; +- +- ustack->uip_buf = pkt->buf; +- ustack->uip_len = pkt->buf_size; +- ustack->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 ((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); +- +- /* determine how we should process this packet based on the +- * ethernet type */ +- switch (type) { +- case UIP_ETHTYPE_IPv6: +- uip_input(ustack); +- if (ustack->uip_len > 0) { +- /* The pkt generated has already consulted +- the IPv6 ARP table */ +- pkt->buf_size = ustack->uip_len; +- prepare_ipv6_packet(nic, nic_iface, +- ustack, pkt); +- +- (*nic->ops->write) (nic, nic_iface, pkt); +- } +- break; +- case UIP_ETHTYPE_IPv4: +- uip_arp_ipin(ustack, pkt); +- uip_input(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_ipv4_packet(nic, nic_iface, +- ustack, pkt); +- +- LOG_DEBUG(PFX "%s: write called after arp_ipin, uip_len=%d", +- nic->log_name, ustack->uip_len); +- (*nic->ops->write) (nic, nic_iface, pkt); +- } +- +- break; +- case UIP_ETHTYPE_ARP: +- uip_arp_arpin(nic_iface, ustack, pkt); +- +- /* 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 (pkt->buf_size > 0) { +- pkt->buf_size = ustack->uip_len; +- LOG_DEBUG(PFX "%s: write called after arp_arpin, bufsize=%d", +- nic->log_name, pkt->buf_size); +- (*nic->ops->write) (nic, nic_iface, pkt); +- } +- break; +- } +- ustack->uip_len = 0; +- pthread_mutex_unlock(&nic->nic_mutex); +- } +- +-done: +- put_packet_in_free_queue(pkt, nic); +- +- return rc; +-} +- +-static int process_dhcp_loop(nic_t *nic, +- nic_interface_t *nic_iface, +- struct timer *periodic_timer, +- struct timer *arp_timer) +-{ +- struct dhcpc_state *s; +- struct ndpc_state *n; +- int rc; +- struct timeval start_time; +- struct timeval current_time; +- struct timeval wait_time; +- struct timeval total_time; +- +- /* 10s loop time to wait for DHCP */ +- switch (nic_iface->ustack.ip_config) { +- case IPV4_CONFIG_DHCP: +- wait_time.tv_sec = 10; +- break; +- case IPV6_CONFIG_DHCP: +- wait_time.tv_sec = 15; +- break; +- case IPV6_CONFIG_STATIC: +- wait_time.tv_sec = 4; +- break; +- default: +- wait_time.tv_sec = 2; +- } +- wait_time.tv_usec = 0; +- +- s = nic_iface->ustack.dhcpc; +- n = nic_iface->ustack.ndpc; +- +- if (gettimeofday(&start_time, NULL)) { +- LOG_ERR(PFX "%s: Couldn't get time of day to start DHCP timer", +- nic->log_name); +- return -EIO; +- } +- +- timeradd(&start_time, &wait_time, &total_time); +- +- periodic_timer->start = periodic_timer->start - +- periodic_timer->interval; +- +- while ((event_loop_stop == 0) && +- (nic->flags & NIC_ENABLED) && !(nic->flags & NIC_GOING_DOWN)) { +- +- if (nic_iface->ustack.ip_config == IPV4_CONFIG_DHCP) { +- if (s->state == STATE_CONFIG_RECEIVED) +- break; +- } +- if (nic_iface->ustack.ip_config == IPV6_CONFIG_DHCP || +- nic_iface->ustack.ip_config == IPV6_CONFIG_STATIC) { +- if (n->state == NDPC_STATE_BACKGROUND_LOOP) +- break; +- } +- +- /* Check the periodic and ARP timer */ +- check_timers(nic, periodic_timer, arp_timer); +- +- rc = nic_process_intr(nic, 1); +- +- while ((rc > 0) && (!(nic->flags & NIC_GOING_DOWN))) { +- rc = process_packets(nic, +- periodic_timer, +- arp_timer, nic_iface); +- } +- +- if (gettimeofday(¤t_time, NULL)) { +- LOG_ERR(PFX "%s: Couldn't get current time for " +- "DHCP start", nic->log_name); +- return -EIO; +- } +- +- if (timercmp(&total_time, ¤t_time, <)) { +- 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; +- 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, +- NULL, NULL, NULL, +- nic_iface->mac_addr); +- break; +- +- case IPV4_CONFIG_DHCP: +- set_uip_stack(&nic_iface->ustack, +- NULL, NULL, NULL, +- 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); +- 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; +- sigset_t set; +- struct timer periodic_timer, arp_timer; +- +- sigfillset(&set); +- rc = pthread_sigmask(SIG_BLOCK, &set, NULL); +- if (rc != 0) { +- /* TODO: determine if we need to exit this thread if we fail +- * to set the signal mask */ +- LOG_ERR(PFX "%s: Couldn't set signal mask", nic->log_name); +- } +- +- /* Signal the device to enable itself */ +- 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, *vlan_iface; +- +- if (nic->flags & NIC_DISABLED) { +- LOG_DEBUG(PFX "%s: Waiting to be enabled", +- nic->log_name); +- +- /* Wait for the device to be enabled */ +- /* nic_mutex is already locked */ +- pthread_cond_wait(&nic->enable_wait_cond, +- &nic->nic_mutex); +- +- if (nic->state == NIC_EXIT) { +- pthread_mutex_unlock(&nic->nic_mutex); +- pthread_exit(NULL); +- } +- LOG_DEBUG(PFX "%s: is now enabled", nic->log_name); +- } +- /* initialize the device to send/rec data */ +- rc = (*nic->ops->open) (nic); +- if (rc != 0) { +- LOG_ERR(PFX "%s: Could not initialize CNIC UIO device", +- nic->log_name); +- +- if (rc == -ENOTSUP) +- 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) { +- if (rc != 0) { +- LOG_WARN(PFX "%s: Allocated %d packets " +- "instead of %d", nic->log_name, rc, 5); +- } else { +- LOG_ERR(PFX "%s: No packets allocated " +- "instead of %d", nic->log_name, 5); +- /* Signal that the device enable is done */ +- pthread_cond_broadcast(&nic->enable_done_cond); +- goto dev_close; +- } +- } +- /* Indication for the nic_disable routine that the nic +- has started running */ +- nic->state = NIC_STARTED_RUNNING; +- +- /* Initialize the system clocks */ +- timer_set(&periodic_timer, CLOCK_SECOND / 2); +- timer_set(&arp_timer, CLOCK_SECOND * 10); +- +- /* 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) { +- 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); +- } +- vlan_iface = vlan_iface->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", +- nic->log_name, nic->flags); +- /* Signal that the device enable is done */ +- pthread_cond_broadcast(&nic->enable_done_cond); +- pthread_mutex_unlock(&nic->nic_mutex); +- goto dev_close_free; +- } +- +- /* This is when we start the processing of packets */ +- nic->start_time = time(NULL); +- nic->state = NIC_RUNNING; +- +- nic->flags &= ~NIC_ENABLED_PENDING; +- +- /* Signal that the device enable is done */ +- pthread_cond_broadcast(&nic->enable_done_cond); +- +- LOG_INFO(PFX "%s: entering main nic loop", nic->log_name); +- +- while ((nic->state == NIC_RUNNING) && +- (event_loop_stop == 0) && +- !(nic->flags & NIC_GOING_DOWN)) { +- pthread_mutex_unlock(&nic->nic_mutex); +- /* 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->flags & NIC_GOING_DOWN)) { +- rc = process_packets(nic, +- &periodic_timer, +- &arp_timer, NULL); +- } +- pthread_mutex_lock(&nic->nic_mutex); +- } +- +- LOG_INFO(PFX "%s: exited main processing loop", nic->log_name); +- +-dev_close_free: +- free_free_queue(nic); +-dev_close: +- +- if (nic->flags & NIC_GOING_DOWN) { +- nic_close(nic, 1, FREE_NO_STRINGS); +- +- nic->flags &= ~NIC_GOING_DOWN; +- } else { +- pthread_mutex_destroy(&nic->xmit_mutex); +- pthread_mutex_init(&nic->xmit_mutex, NULL); +- } +- nic->pending_count = 0; +- +- if (!(nic->flags & NIC_EXIT_MAIN_LOOP)) { +- /* Signal we are done closing CNIC/UIO device */ +- 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); +- +- nic->thread = INVALID_THREAD; +- +- pthread_exit(NULL); +-} +diff --git a/iscsiuio/src/unix/nic.h b/iscsiuio/src/unix/nic.h +deleted file mode 100644 +index 2c41e6e..0000000 +--- a/iscsiuio/src/unix/nic.h ++++ /dev/null +@@ -1,407 +0,0 @@ +-/* +- * Copyright (c) 2009-2011, Broadcom Corporation +- * Copyright (c) 2014, QLogic Corporation +- * +- * Written by: Benjamin Li (benli@broadcom.com) +- * +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. All advertising materials mentioning features or use of this software +- * must display the following acknowledgement: +- * This product includes software developed by Adam Dunkels. +- * 4. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * nic.h - NIC header file +- * +- */ +- +-#include +- +-#ifndef __NIC_H__ +-#define __NIC_H__ +- +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include "nic_nl.h" +-#include "packet.h" +-#include "uip.h" +-#include "timer.h" +- +-#include "iscsi_if.h" +- +-/* Foward declarations */ +-struct nic_ops; +-struct nic_lib_handle; +-struct packet; +-struct nic_op; +- +-extern pthread_mutex_t nic_lib_list_mutex; +-extern struct nic_lib_handle *nic_lib_list; +- +-/* Used to store a list of active cnic devices */ +-extern pthread_mutex_t nic_list_mutex; +-extern struct nic *nic_list; +- +-extern void *nl_process_handle_thread(void *arg); +- +-/******************************************************************************* +- * Constants +- ******************************************************************************/ +-#define MAX_PCI_DEVICE_ENTRIES 64 /* Maxium number of pci_device_id +- entries a hw library may contain */ +- +-#define FREE_CONFIG_NAME 0x0001 +-#define FREE_UIO_NAME 0x0002 +-#define FREE_ALL_STRINGS (FREE_CONFIG_NAME | FREE_UIO_NAME) +-#define FREE_NO_STRINGS 0x0000 +- +-/****************************************************************************** +- * Enumerations +- ******************************************************************************/ +-typedef enum { +- ALLOW_GRACEFUL_SHUTDOWN = 1, +- FORCE_SHUTDOWN = 2, +-} NIC_SHUTDOWN_T; +- +-/******************************************************************************* +- * Structure used to hold PCI vendor, device, subvendor and subdevice ID's +- ******************************************************************************/ +-struct pci_device_id { +- const uint32_t vendor, device; /* Vendor and device ID or PCI_ANY_ID */ +- const uint32_t subvendor, subdevice; /* Subsystem ID's/PCI_ANY_ID */ +- const char *device_name; /* Data private to the driver */ +-}; +- +-/****************************************************************************** +- * NIC statistics structure +- ******************************************************************************/ +-struct nic_stats { +- uint64_t interrupts; +- uint64_t missed_interrupts; +- +- struct { +- uint64_t packets; +- uint64_t bytes; +- } tx; +- +- struct { +- uint64_t packets; +- uint64_t bytes; +- } rx; +-}; +- +-/****************************************************************************** +- * 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 (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; +- +-#define IFACE_NUM_PRESENT (1<<0) +-#define IFACE_NUM_INVALID -1 +- int iface_num; +- int request_type; +-} nic_interface_t; +- +-/****************************************************************************** +- * NIC lib operations structure +- ******************************************************************************/ +-struct nic_lib_ops { +- /* Used to get the NIC library name */ +- void (*get_library_name) (char **library_name, +- size_t *library_name_size); +- +- /* Used to get to the PCI table supported by the NIC library */ +- void (*get_pci_table) (struct pci_device_id **table, +- uint32_t *entries); +- +- /* Used to get the version of this NIC library */ +- void (*get_library_version) (char **version_string, +- size_t *version_string_size); +- +- /* Used to get the NIC library build date */ +- void (*get_build_date) (char **build_date_string, +- size_t *build_date_string_size); +- +- /* Used to get the transport name assoicated with this library */ +- void (*get_transport_name) (char **transport_name, +- size_t *transport_name_size); +- +- /* Used to get the uio name assoicated with this library */ +- void (*get_uio_name) (char **uio_name, size_t *uio_name_size); +- +-}; +- +-/******************************************************************************* +- * NIC op table definition +- ******************************************************************************/ +-typedef struct nic_ops { +- struct nic_lib_ops lib_ops; +- +- char *description; +- int (*open) (struct nic *); +- int (*close) (struct nic *, NIC_SHUTDOWN_T); +- int (*read) (struct nic *, struct packet *); +- int (*write) (struct nic *, nic_interface_t *, struct packet *); +- void *(*get_tx_pkt) (struct nic *); +- void (*start_xmit) (struct nic *, size_t, u16_t vlan_id); +- int (*clear_tx_intr) (struct nic *); +- int (*handle_iscsi_path_req) (struct nic *, +- int, +- struct iscsi_uevent *ev, +- struct iscsi_path *path, +- nic_interface_t *nic_iface); +-} net_ops_t; +- +-typedef struct nic_lib_handle { +- struct nic_lib_handle *next; +- +- pthread_mutex_t mutex; +- struct nic_ops *ops; +-} nic_lib_handle_t; +- +-typedef struct nic { +- struct nic *next; +- +- uint32_t flags; +-#define NIC_UNITIALIZED 0x0001 +-#define NIC_INITIALIZED 0x0002 +-#define NIC_ENABLED 0x0004 +-#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 +-#define NIC_ENABLED_PENDING 0x0800 +- +-#define NIC_UIO_NAME_MALLOC 0x1000 +-#define NIC_CONFIG_NAME_MALLOC 0x2000 +-#define NIC_EXIT_MAIN_LOOP 0x4000 +-#define NIC_GOING_DOWN 0x8000 +-#define NIC_RESET_UIP 0x10000 +- +- uint16_t state; +-#define NIC_STOPPED 0x0001 +-#define NIC_STARTED_RUNNING 0x0002 +-#define NIC_RUNNING 0x0004 +-#define NIC_EXIT 0x0010 +- +- int fd; /* Holds the file descriptor to UIO */ +- uint16_t uio_minor; /* Holds the UIO minor number */ +- +- uint32_t host_no; /* Holds the associated host number */ +- +- char *library_name; /* Name of the library to assoicate with */ +- char *log_name; /* Human friendly name used in the log +- file */ +- char *config_device_name; /* Name read from the XML configuration +- file */ +- char eth_device_name[IFNAMSIZ]; /* Network interface name */ +- char *uio_device_name; /* UIO device name */ +- +- uint32_t intr_count; /* Total UIO interrupt count */ +- +- int page_size; +- +- /* Held for nic ops manipulation */ +- pthread_mutex_t nic_mutex; +- +- /* iSCSI ring ethernet MAC address */ +- __u8 mac_addr[ETH_ALEN]; +- +- /* Used to manage the network interfaces of this device */ +- __u32 num_of_nic_iface; +- nic_interface_t *nic_iface; +- +- /* Wait for the device to be enabled */ +- pthread_cond_t enable_wait_cond; +- +- /* Wait for the device to be finished enabled */ +- pthread_cond_t enable_done_cond; +- +- /* Wait for the nic loop to start */ +- pthread_cond_t nic_loop_started_cond; +- +- /* Wait for the device to be disabled */ +- pthread_cond_t disable_wait_cond; +- +- /* Held when transmitting */ +- pthread_mutex_t xmit_mutex; +- +- /* The thread this device is running on */ +- pthread_t thread; +- +- /* The thread used to enable the device */ +- pthread_t enable_thread; +- +- /* Statistical Information on this device */ +- time_t start_time; +- struct nic_stats stats; +- +- /* 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 */ +- uint32_t rx_poll_usec; +- +- /* Used to hold hardware specific data */ +- void *priv; +- +- /* Used to hold the TX packets that are needed to be sent */ +- struct packet *tx_packet_queue; +- +- /* Mutex to protect the list of free packets */ +- pthread_mutex_t free_packet_queue_mutex; +- +- /* Used to hold the free packets that are needed to be sent */ +- struct packet *free_packet_queue; +- +- /* Points to the NIC library */ +- nic_lib_handle_t *nic_library; +- +- /* Points to the PCI table entry */ +- struct pci_device_id *pci_id; +- +- /* Used to process the interrupt */ +- 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]; +- +- /* The thread used to perform ping */ +- pthread_t ping_thread; +- uint64_t transport_handle; +-} nic_t; +- +-/****************************************************************************** +- * Function Prototypes +- *****************************************************************************/ +-int load_all_nic_libraries(); +- +-nic_t *nic_init(); +-void nic_add(nic_t *nic); +-int nic_remove(nic_t *nic); +- +-int nic_add_nic_iface(nic_t *nic, nic_interface_t *nic_iface); +-int nic_process_intr(nic_t *nic, int discard_check); +- +-nic_interface_t *nic_iface_init(); +- +-typedef enum { +- NIC_LIBRARY_EXSITS = 1, +- NIC_LIBRARY_DOESNT_EXIST = 2, +-} NIC_LIBRARY_EXIST_T; +- +-NIC_LIBRARY_EXIST_T does_nic_uio_name_exist(char *name, +- nic_lib_handle_t **handle); +-NIC_LIBRARY_EXIST_T does_nic_library_exist(char *name, +- nic_lib_handle_t **handle); +- +-/******************************************************************************* +- * Packet management utility functions +- ******************************************************************************/ +-struct packet *get_next_tx_packet(nic_t *nic); +-struct packet *get_next_free_packet(nic_t *nic); +-void put_packet_in_tx_queue(struct packet *pkt, nic_t *nic); +-void put_packet_in_free_queue(struct packet *pkt, nic_t *nic); +- +-int unload_all_nic_libraries(); +-void nic_close(nic_t *nic, NIC_SHUTDOWN_T graceful, int clean); +- +-/* Use this function to fill in minor number and uio, and eth names */ +-int nic_fill_name(nic_t *nic); +- +-int enable_multicast(nic_t *nic); +-int disable_multicast(nic_t *nic); +- +-void nic_set_all_nic_iface_mac_to_parent(nic_t *nic); +-int find_nic_lib_using_pci_id(uint32_t vendor, uint32_t device, +- uint32_t subvendor, uint32_t subdevice, +- nic_lib_handle_t **handle, +- struct pci_device_id **pci_entry); +- +-void *nic_loop(void *arg); +- +-int nic_packet_capture(struct nic *, struct packet *pkt); +- +-int process_packets(nic_t *nic, +- struct timer *periodic_timer, +- struct timer *arp_timer, nic_interface_t *nic_iface); +- +-void prepare_ustack(nic_t *nic, +- nic_interface_t *nic_iface, +- struct uip_stack *ustack, struct packet *pkt); +- +-void prepare_ipv4_packet(nic_t *nic, +- nic_interface_t *nic_iface, +- struct uip_stack *ustack, struct packet *pkt); +- +-void prepare_ipv6_packet(nic_t *nic, +- nic_interface_t *nic_iface, +- struct uip_stack *ustack, struct packet *pkt); +- +-#endif /* __NIC_H__ */ +diff --git a/iscsiuio/src/unix/nic_id.c b/iscsiuio/src/unix/nic_id.c +deleted file mode 100644 +index 6da0a38..0000000 +--- a/iscsiuio/src/unix/nic_id.c ++++ /dev/null +@@ -1,364 +0,0 @@ +-/* +- * Copyright (c) 2009-2011, Broadcom Corporation +- * Copyright (c) 2014, QLogic Corporation +- * +- * Written by: Benjamin Li (benli@broadcom.com) +- * +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. All advertising materials mentioning features or use of this software +- * must display the following acknowledgement: +- * This product includes software developed by Adam Dunkels. +- * 4. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * nic_id.c - Using sysfs to determine the PCI vendor, device, subvendor and +- * subdevice ID's +- * +- */ +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include "logger.h" +-#include "nic.h" +- +-#define PFX "nic_id " +- +-/******************************************************************************* +- * Sysfs constant strings used to get PCI vendor, and device ID's +- ******************************************************************************/ +-const char uio_vendor_id_template[] = "/sys/class/uio/uio%d/device/vendor"; +-const char uio_subvendor_id_template[] = +- "/sys/class/uio/uio%d/device/subsystem_vendor"; +-const char uio_device_id_template[] = "/sys/class/uio/uio%d/device/device"; +-const char uio_subdevice_id_template[] = +- "/sys/class/uio/uio%d/device/subsystem_device"; +-const char uio_device_symlink_template[] = "/sys/class/uio/uio%d/device"; +- +-/** +- * get_id() - Utility function to read hex values from sysfs +- * @param nic - NIC device to use +- * @param sysfs_template - sysfs path template to use +- * @param sysfs_template_size - sysfs path template size in bytes +- * @parm id - this is the value returned from the sysfs entry +- * @return 0 on success <0 on failure +- */ +-static int get_id(nic_t *nic, +- const char *sysfs_template, +- const size_t sysfs_template_size, uint32_t *id) +-{ +- int rc = 0; +- FILE *fp; +- size_t chars_read; +- char buf[7]; +- char *path; +- size_t path_size; +- +- path_size = sysfs_template_size + 4; +- path = malloc(path_size); +- if (path == NULL) { +- LOG_ERR("Could not allocate memory for %s", sysfs_template); +- return -ENOMEM; +- } +- +- snprintf(path, path_size, sysfs_template, nic->uio_minor); +- +- fp = fopen(path, "r"); +- if (fp == NULL) { +- LOG_ERR(PFX "%s: Could not open path: %s [%s]", +- nic->log_name, path, strerror(errno)); +- rc = -EIO; +- goto error_fopen; +- } +- +- chars_read = fread(buf, sizeof(buf), 1, fp); +- if (chars_read != 1) { +- LOG_ERR(PFX "%s: Could not read from: %s [%s]", +- nic->log_name, path, strerror(ferror(fp))); +- rc = -EIO; +- goto error; +- } +- +- chars_read = sscanf(buf, "%x", id); +- if (chars_read != 1) { +- LOG_ERR(PFX "%s: Could interpret value: %s from: %s [%s]", +- nic->log_name, buf, path, strerror(errno)); +- rc = -EIO; +- goto error; +- } +- +-error: +- fclose(fp); +- +-error_fopen: +- free(path); +- +- return rc; +-} +- +-static int get_vendor(nic_t *nic, uint32_t *id) +-{ +- return get_id(nic, +- uio_vendor_id_template, sizeof(uio_vendor_id_template), +- id); +-} +- +-static int get_subvendor(nic_t *nic, uint32_t *id) +-{ +- return get_id(nic, +- uio_subvendor_id_template, +- sizeof(uio_subvendor_id_template), id); +-} +- +-static int get_device(nic_t *nic, uint32_t *id) +-{ +- return get_id(nic, +- uio_device_id_template, +- sizeof(uio_device_id_template), id); +-} +- +-static int get_subdevice(nic_t *nic, uint32_t *id) +-{ +- return get_id(nic, +- uio_subdevice_id_template, +- sizeof(uio_subdevice_id_template), id); +-} +- +-int get_bus_slot_func_num(nic_t *nic, +- uint32_t *bus, uint32_t *slot, uint32_t *func) +-{ +- size_t size; +- char *path, *tok, *tok2; +- int path_tokens, i; +- size_t path_size; +- char *read_pci_bus_slot_func_str; +- char pci_bus_slot_func_str[32]; +- int rc; +- char *saveptr; +- +- path_size = sizeof(uio_device_symlink_template) + 4; +- path = malloc(path_size); +- if (path == NULL) { +- LOG_ERR(PFX "%s: Could not allocate path memory for %s", +- nic->log_name, uio_device_symlink_template); +- rc = -ENOMEM; +- goto error_alloc_path; +- } +- +- read_pci_bus_slot_func_str = malloc(128); +- if (read_pci_bus_slot_func_str == NULL) { +- LOG_ERR(PFX "%s: Could not allocate read pci bus memory for %s", +- nic->log_name, uio_device_symlink_template); +- rc = -ENOMEM; +- goto error_alloc_read_pci_bus; +- } +- +- snprintf(path, path_size, uio_device_symlink_template, nic->uio_minor); +- +- size = readlink(path, read_pci_bus_slot_func_str, 128); +- if (size == -1) { +- LOG_ERR(PFX "%s: Error with %s: %s", +- nic->log_name, path, strerror(errno)); +- rc = errno; +- goto error; +- } +- +- if (size > ((128) - 1)) { +- read_pci_bus_slot_func_str[128 - 1] = '\0'; +- LOG_ERR(PFX "%s: not enough space (%d) for reading PCI " +- "slot:bus.func %s: %s", +- nic->log_name, size, path, strerror(errno)); +- rc = -EIO; +- goto error; +- } +- +- /* readlink() doesn't NULL terminate the string */ +- read_pci_bus_slot_func_str[size] = '\0'; +- +- path_tokens = 0; +- tok = strtok_r(read_pci_bus_slot_func_str, "/", &saveptr); +- while (tok != NULL) { +- path_tokens++; +- tok = strtok_r(NULL, "/", &saveptr); +- } +- +- size = readlink(path, read_pci_bus_slot_func_str, 128); +- if (size == -1) { +- LOG_ERR(PFX "%s: Error with %s: %s", +- nic->log_name, path, strerror(errno)); +- rc = errno; +- goto error; +- } +- +- if (size > ((128) - 1)) { +- read_pci_bus_slot_func_str[128 - 1] = '\0'; +- LOG_ERR(PFX "%s: not enough space for reading PCI " +- "slot:bus.func %s: %s", +- nic->log_name, path, strerror(errno)); +- rc = -EIO; +- goto error; +- } +- +- /* readlink() doesn't NULL terminate the string */ +- read_pci_bus_slot_func_str[size] = '\0'; +- +- tok = strtok_r(read_pci_bus_slot_func_str, "/", &saveptr); +- for (i = 0; i < path_tokens - 1; i++) +- tok = strtok_r(NULL, "/", &saveptr); +- strcpy(pci_bus_slot_func_str, tok); +- +- tok = strtok_r(pci_bus_slot_func_str, ":", &saveptr); +- if (tok == NULL) { +- LOG_ERR(PFX "%s: Error with slot string: %s", +- nic->log_name, pci_bus_slot_func_str); +- rc = -EIO; +- goto error; +- } +- +- tok = strtok_r(NULL, ":", &saveptr); +- if (tok == NULL) { +- LOG_ERR(PFX "%s: Error parsing slot: %s", +- nic->log_name, pci_bus_slot_func_str); +- rc = -EIO; +- goto error; +- } +- +- sscanf(tok, "%x", bus); +- +- /* Need to extract the next token "xx.x" */ +- tok = strtok_r(NULL, ":", &saveptr); +- if (tok == NULL) { +- LOG_ERR(PFX "%s: Error extracing bus.func: %s", +- nic->log_name, pci_bus_slot_func_str); +- rc = -EIO; +- goto error; +- } +- +- tok2 = strtok_r(tok, ".", &saveptr); +- if (tok2 == NULL) { +- LOG_ERR(PFX "%s: Error parsing bus: %s", +- nic->log_name, pci_bus_slot_func_str); +- rc = -EIO; +- goto error; +- } +- +- sscanf(tok2, "%x", slot); +- +- tok2 = strtok_r(NULL, ".", &saveptr); +- if (tok2 == NULL) { +- LOG_ERR(PFX "%s: Error parsing func: %s", +- nic->log_name, pci_bus_slot_func_str); +- rc = -EIO; +- goto error; +- } +- +- sscanf(tok2, "%x", func); +- LOG_INFO(PFX "%s: is found at %02x:%02x.%02x", nic->log_name, +- *bus, *slot, *func); +- rc = 0; +-error: +- free(read_pci_bus_slot_func_str); +-error_alloc_read_pci_bus: +- free(path); +-error_alloc_path: +- return rc; +-} +- +-/** +- * find_set_nic_lib() - Match the NIC library to the NIC +- * @param nic - NIC device to determine which NIC library to use +- * @return 0 on success <0 on failure +- */ +-int find_set_nic_lib(nic_t *nic) +-{ +- uint32_t vendor; +- uint32_t subvendor; +- uint32_t device; +- uint32_t subdevice; +- +- uint32_t pci_bus; +- uint32_t pci_slot; +- uint32_t pci_func; +- int rc = 0; +- +- nic_lib_handle_t *handle; +- struct pci_device_id *pci_entry; +- size_t name_size; +- +- rc = get_vendor(nic, &vendor); +- if (rc != 0) { +- LOG_ERR(PFX "%s: Could not get vendor id [0x%x]", +- nic->log_name, rc); +- return rc; +- } +- +- rc = get_subvendor(nic, &subvendor); +- if (rc != 0) { +- LOG_ERR(PFX "%s: Could not get subvendor id [0x%x]", +- nic->log_name, rc); +- return rc; +- } +- +- rc = get_device(nic, &device); +- if (rc != 0) { +- LOG_ERR(PFX "%s: Could not get device id [0x%x]", +- nic->log_name, rc); +- return rc; +- } +- +- rc = get_subdevice(nic, &subdevice); +- if (rc != 0) { +- LOG_ERR(PFX "%s: Could not get subdevice id [0x%x]", +- nic->log_name, rc); +- return rc; +- } +- +- get_bus_slot_func_num(nic, &pci_bus, &pci_slot, &pci_func); +- +- LOG_DEBUG(PFX "%s: Looking for device vendor: " +- "0x%x subvendor: 0x%x device: 0x%x subdevice: 0x%x", +- nic->log_name, vendor, subvendor, device, subdevice); +- +- rc = find_nic_lib_using_pci_id(vendor, device, subvendor, subdevice, +- &handle, &pci_entry); +- +- if (rc != 0) { +- LOG_WARN(PFX "%s: Couldn't find proper NIC library", +- nic->log_name); +- return rc; +- } +- +- nic->nic_library = handle; +- nic->pci_id = pci_entry; +- +- /* Prepare the NIC library op table */ +- nic->ops = handle->ops; +- (*nic->ops->lib_ops.get_library_name) (&nic->library_name, &name_size); +- +- return 0; +-} +diff --git a/iscsiuio/src/unix/nic_id.h b/iscsiuio/src/unix/nic_id.h +deleted file mode 100644 +index 340580f..0000000 +--- a/iscsiuio/src/unix/nic_id.h ++++ /dev/null +@@ -1,47 +0,0 @@ +-/* +- * Copyright (c) 2009-2011, Broadcom Corporation +- * Copyright (c) 2014, QLogic Corporation +- * +- * Written by: Benjamin Li (benli@broadcom.com) +- * +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. All advertising materials mentioning features or use of this software +- * must display the following acknowledgement: +- * This product includes software developed by Adam Dunkels. +- * 4. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * nic_id.h - NIC uIP NetLink user space stack +- * +- */ +-#ifndef __NIC_ID_H__ +-#define __NIC_ID_H__ +- +-int find_set_nic_lib(nic_t *nic); +- +-int get_bus_slot_func_num(nic_t *nic, +- uint32_t *bus, uint32_t *slot, uint32_t *func); +- +-#endif /* __NIC_ID_H__ */ +diff --git a/iscsiuio/src/unix/nic_nl.c b/iscsiuio/src/unix/nic_nl.c +deleted file mode 100644 +index dee462e..0000000 +--- a/iscsiuio/src/unix/nic_nl.c ++++ /dev/null +@@ -1,680 +0,0 @@ +-/* +- * Copyright (c) 2009-2011, Broadcom Corporation +- * Copyright (c) 2014, QLogic Corporation +- * +- * Written by: Benjamin Li (benli@broadcom.com) +- * +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. All advertising materials mentioning features or use of this software +- * must display the following acknowledgement: +- * This product includes software developed by Adam Dunkels. +- * 4. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * nic_nl.c - NIC uIP NetLink user space stack +- * +- */ +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include "uip_arp.h" +-#include "logger.h" +-#include "options.h" +- +-#include "nic.h" +-#include "nic_nl.h" +-#include "nic_utils.h" +- +-/******************************************************************************* +- * Constants +- ******************************************************************************/ +-#define PFX "NIC_NL " +- +-static u8_t nlm_sendbuf[NLM_BUF_DEFAULT_MAX]; +- +-static struct sockaddr_nl src_addr; +- +-static const struct sockaddr_nl dest_addr = { +- .nl_family = AF_NETLINK, +- .nl_pid = 0, /* kernel */ +- .nl_groups = 0, /* unicast */ +-}; +- +-#define POLL_NL 0 +-#define POLL_MAX 1 +- +-/* Netlink */ +-int nl_sock = INVALID_FD; +- +-static int nl_read(int ctrl_fd, char *data, int size, int flags) +-{ +- int rc; +- struct iovec iov; +- struct msghdr msg; +- +- iov.iov_base = data; +- iov.iov_len = size; +- +- memset(&src_addr, 0, sizeof(src_addr)); +- src_addr.nl_family = AF_NETLINK; +- src_addr.nl_pid = getpid(); +- src_addr.nl_groups = 1; +- +- memset(&msg, 0, sizeof(msg)); +- msg.msg_name = (void *)&src_addr; +- msg.msg_namelen = sizeof(src_addr); +- msg.msg_iov = &iov; +- msg.msg_iovlen = 1; +- +- rc = recvmsg(ctrl_fd, &msg, flags); +- +- return rc; +-} +- +-static int +-kwritev(int fd, enum iscsi_uevent_e type, struct iovec *iovp, int count) +-{ +- int i, rc; +- struct nlmsghdr *nlh; +- struct msghdr msg; +- struct iovec iov; +- int datalen = 0; +- +- for (i = 0; i < count; i++) +- datalen += iovp[i].iov_len; +- +- nlh = (struct nlmsghdr *)nlm_sendbuf; +- memset(nlh, 0, NLMSG_SPACE(datalen)); +- +- nlh->nlmsg_len = NLMSG_SPACE(datalen); +- nlh->nlmsg_pid = getpid(); +- nlh->nlmsg_flags = 0; +- nlh->nlmsg_type = type; +- +- datalen = 0; +- for (i = 0; i < count; i++) { +- memcpy(NLMSG_DATA(nlh) + datalen, iovp[i].iov_base, +- iovp[i].iov_len); +- datalen += iovp[i].iov_len; +- } +- iov.iov_base = (void *)nlh; +- iov.iov_len = nlh->nlmsg_len; +- +- memset(&msg, 0, sizeof(msg)); +- msg.msg_name = (void *)&dest_addr; +- msg.msg_namelen = sizeof(dest_addr); +- msg.msg_iov = &iov; +- msg.msg_iovlen = 1; +- +- do { +- rc = sendmsg(fd, &msg, 0); +- if (rc == -ENOMEM) { +- LOG_ERR(PFX "sendmsg: alloc_skb() failed"); +- sleep(1); +- } else if (rc < 0) { +- LOG_ERR(PFX "sendmsg: bug?: on %d %s[0x%x]", +- fd, strerror(errno), errno); +- sleep(1); +- } +- } while ((rc < 0) && (event_loop_stop == 0)); +- +- return rc; +-} +- +-/* +- * __kipc_call() should never block. Therefore +- * Netlink's xmit logic is serialized. This means we do not allocate on +- * xmit path. Instead we reuse nlm_sendbuf buffer. +- * +- * Transport must assure non-blocking operations for: +- * +- * - session_create() +- * - conn_create() +- * - conn_bind() +- * _ set_param() +- * - conn_start() +- * - conn_stop() +- * +- * Its OK to block for cleanup for short period of time in operatations for: +- * +- * - conn_destroy() +- * - session_destroy() +- * +- * FIXME: interface needs to be extended to allow longer blocking on +- * cleanup. (Dima) +- */ +-int __kipc_call(int fd, void *iov_base, int iov_len) +-{ +- int rc; +- struct iovec iov; +- struct iscsi_uevent *ev = iov_base; +- enum iscsi_uevent_e type = ev->type; +- +- /* Sanity check */ +- if (iov_base == NULL) +- return -EINVAL; +- +- iov.iov_base = iov_base; +- iov.iov_len = iov_len; +- +- rc = kwritev(fd, type, &iov, 1); +- +- return rc; +-} +- +-static int pull_from_nl(char **buf) +-{ +- int rc; +- 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, +- NLMSG_SPACE(sizeof(struct iscsi_uevent)), +- MSG_PEEK | MSG_WAITALL); +- if (rc <= 0) { +- LOG_ERR("can not read nlm_ev, error %s[%d]", +- strerror(errno), rc); +- if (rc == 0) +- return -EIO; +- else +- return errno; +- } +- nlh = (struct nlmsghdr *)nlm_ev; +- +- if (unlikely(nlh->nlmsg_len < NLMSG_ALIGN(sizeof(struct nlmsghdr)))) { +- LOG_ERR(PFX "Invalid nlh->nlmsg_len length: " +- "nlh->nlmsg_len(%d) < " +- "NLMSG_ALIGN(sizeof(struct nlmsghdr))(%d)", +- nlh->nlmsg_len, NLMSG_ALIGN(sizeof(struct nlmsghdr))); +- return -EINVAL; +- } +- +- 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", alloc_size); +- return -ENOMEM; +- } +- +- memset(data, 0, alloc_size); +- rc = nl_read(nl_sock, data, (int)nlh->nlmsg_len, MSG_WAITALL); +- if (rc <= 0) { +- LOG_ERR("can not read nlm_ev, error %s[%d]", +- strerror(errno), rc); +- if (rc == 0) +- rc = -EIO; +- else +- rc = errno; +- +- goto error; +- } +- *buf = data; +- return 0; +-error: +- if (data != NULL) +- free(data); +- +- return rc; +-} +- +-static const struct timespec ctldev_sleep_req = { +- .tv_sec = 0, +- .tv_nsec = 250000000, +-}; +- +-static int ctldev_handle(char *data, nic_t *nic) +-{ +- int rc = 0; +- struct iscsi_uevent *ev; +- uint8_t *payload; +- struct iscsi_path *path; +- char *msg_type_str; +- 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"; +- break; +- default: +- /* We don't care about other iSCSI Netlink messages */ +- LOG_DEBUG(PFX "Received ev->type: 0x%x", ev->type); +- rc = 0; +- goto error; +- } +- +- /* This is a message that drivers should be interested in */ +- 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 *vlan_iface; +- uint16_t ip_type; +- int iface_num, vlan_id; +- +- if (path->ip_addr_len == 4) +- ip_type = AF_INET; +- else if (path->ip_addr_len == 16) +- ip_type = AF_INET6; +- else +- ip_type = 0; +-#ifdef REQ_PATH_IFACE_NUM +- /* Find the nic_iface to use */ +- iface_num = ev->r.req_path.iface_num ? +- ev->r.req_path.iface_num : IFACE_NUM_INVALID; +-#else +- iface_num = IFACE_NUM_INVALID; +-#endif +- 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) { +- 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; +- } +- /* 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; +- nic_iface->flags |= NIC_IFACE_ACQUIRE; +- +- 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_enable(nic); +- +- /* Ensure that the NIC is RUNNING */ +- rc = -EIO; +- for (i = 0; i < 10; i++) { +- if (nic->state == NIC_RUNNING) { +- rc = 0; +- break; +- } +- +- nanosleep(&ctldev_sleep_req, &sleep_rem); +- } +- +- if (rc != 0) { +- LOG_WARN(PFX "%s[vlan: %d protocol: %d]: not running, " +- "cmd: 0x%x nic state: 0x%x flags: 0x%x", +- nic->log_name, +- nic_iface->vlan_id, nic_iface->protocol, +- ev->type, nic->state, nic->flags); +- goto error; +- } +- } +- +- if (nic->ops) { +- switch (ev->type) { +- case ISCSI_KEVENT_PATH_REQ: +- /* pass the request up to the user space +- * library driver */ +- 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, +- nic_iface); +- nic_iface->flags &= ~NIC_IFACE_PATHREQ_WAIT; +- pthread_mutex_lock(&nic->nic_mutex); +- nic->flags &= ~NIC_PATHREQ_WAIT; +- pthread_mutex_unlock(&nic->nic_mutex); +- LOG_INFO(PFX "%s: 'path_req' operation finished", +- nic->log_name); +- +- rc = 0; +- break; +- default: +- rc = -EAGAIN; +- break; +- } +- } +- +-error: +- +- return rc; +-} +- +-/* 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; +- +- pthread_mutex_lock(&nic->nl_process_mutex); +- rc = pthread_cond_wait(&nic->nl_process_cond, +- &nic->nl_process_mutex); +- if (rc != 0) { +- pthread_mutex_unlock(&nic->nl_process_mutex); +- LOG_ERR("Fatal error in NL processing thread " +- "during wait[%s]", strerror(rc)); +- break; +- } +- +- 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(&nic->nl_process_mutex); +- +- if (data) { +- ctldev_handle(data, nic); +- free(data); +- } +- } +-error: +- return NULL; +-} +- +-static void flush_nic_nl_process_ring(nic_t *nic) +-{ +- int i; +- +- 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; +- } +- } +- +- nic->nl_process_head = 0; +- nic->nl_process_tail = 0; +- +- LOG_DEBUG(PFX "%s: Flushed NIC NL ring", nic->log_name); +-} +- +-/** +- * nic_nl_open() - This is called when opening/creating the Netlink listening +- * thread +- * @param dev - CNIC UIO device to create a NetLink listener on +- * @return 0 on success, <0 on failure +- */ +-int nic_nl_open() +-{ +- int rc = 0; +- char *msg_type_str; +- +- /* 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]", +- strerror(errno)); +- rc = -ENOMEM; +- goto error; +- } +- +- memset(&src_addr, 0, sizeof(src_addr)); +- src_addr.nl_family = AF_NETLINK; +- src_addr.nl_pid = getpid(); +- src_addr.nl_groups = ISCSI_NL_GRP_UIP; +- +- while ((!event_loop_stop)) { +- rc = bind(nl_sock, +- (struct sockaddr *)&src_addr, sizeof(src_addr)); +- if (rc == 0) +- break; +- +- LOG_ERR(PFX "waiting binding to NETLINK_ISCSI socket"); +- +- sleep(1); +- } +- +- if (event_loop_stop) { +- rc = -EINVAL; +- goto error; +- } +- +- LOG_INFO(PFX "Netlink to CNIC on pid %d is ready", src_addr.nl_pid); +- +- 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) +- continue; +- +- /* Try to abort ARP'ing if a if_down was received */ +- ev = (struct iscsi_uevent *)NLMSG_DATA(buf); +- 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); +- +- /* Make sure the nic list doesn't get yanked */ +- pthread_mutex_lock(&nic_list_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 (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_unlock(&nic->nl_process_mutex); +- +- pthread_mutex_unlock(&nic_list_mutex); +- +- LOG_DEBUG(PFX "Pulled nl event"); +- } +- +- LOG_INFO(PFX "Netlink thread exit'ing"); +- rc = 0; +- +-error: +- return rc; +-} +diff --git a/iscsiuio/src/unix/nic_nl.h b/iscsiuio/src/unix/nic_nl.h +deleted file mode 100644 +index c68d81c..0000000 +--- a/iscsiuio/src/unix/nic_nl.h ++++ /dev/null +@@ -1,54 +0,0 @@ +-/* +- * Copyright (c) 2009-2011, Broadcom Corporation +- * Copyright (c) 2014, QLogic Corporation +- * +- * Written by: Benjamin Li (benli@broadcom.com) +- * +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. All advertising materials mentioning features or use of this software +- * must display the following acknowledgement: +- * This product includes software developed by Adam Dunkels. +- * 4. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * nic_nl.h - NIC uIP NetLink user space stack +- * +- */ +- +-#ifndef __NIC_NL_H__ +-#define __NIC_NL_H__ +- +-#include +- +-int nic_nl_open(); +-void nic_nl_close(); +- +-int __kipc_call(int fd, void *iov_base, int iov_len); +- +-extern pthread_cond_t nl_process_if_down_cond; +-extern pthread_mutex_t nl_process_mutex; +-extern int nl_process_if_down; +- +-#endif /* __NIC_NL_H__ */ +diff --git a/iscsiuio/src/unix/nic_utils.c b/iscsiuio/src/unix/nic_utils.c +deleted file mode 100644 +index ec4535d..0000000 +--- a/iscsiuio/src/unix/nic_utils.c ++++ /dev/null +@@ -1,1813 +0,0 @@ +-/* +- * Copyright (c) 2009-2011, Broadcom Corporation +- * Copyright (c) 2014, QLogic Corporation +- * +- * Written by: Benjamin Li (benli@broadcom.com) +- * +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. All advertising materials mentioning features or use of this software +- * must display the following acknowledgement: +- * This product includes software developed by Adam Dunkels. +- * 4. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * nic_util.c - shared NIC utility functions +- * +- */ +-#include +-#include +-#include +-#define _GNU_SOURCE +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include "logger.h" +-#include "nic.h" +-#include "nic_id.h" +-#include "nic_vlan.h" +-#include "nic_utils.h" +-#include "options.h" +- +-#define PFX "nic_utils " +- +-/****************************************************************************** +- * String constants +- *****************************************************************************/ +-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"; +-static const char base_uio_sysfs_name[] = "/sys/class/uio/"; +-static const char uio_name[] = "uio"; +- +-static const char uio_base_dir[] = "/dev/uio"; +-static const char uio_udev_path_template[] = "/dev/uio%hd"; +-static const char uio_uevent_path_template[] = "/sys/class/uio/uio%d/uevent"; +- +-static const char base_iscsi_host_name[] = "/sys/class/iscsi_host/"; +-static const char host_template[] = "host%d"; +-static const char iscsi_host_path_netdev_template[] = +- "/sys/class/iscsi_host/host%d/netdev"; +-static const char cnic_uio_sysfs_resc_template[] = +- "/sys/class/uio/uio%i/device/resource%i"; +-static const char iscsi_transport_handle_template[] = +- "/sys/class/iscsi_transport/%s/handle"; +-static const char host_pfx[] = "host"; +- +-/** +- * manually_trigger_uio_event() - If the uio file node doesn't exist then +- * try to retrigger udev to create the file +- * node by touch the uevent file in sysfs +- * @param nic - the nic to trigger on +- * @param uio_minor - UIO the minor number to use +- * @return 0 on success +- */ +-int manually_trigger_uio_event(nic_t *nic, int uio_minor) +-{ +- int fd; +- char uio_uevent_path[sizeof(uio_uevent_path_template) + 10]; +- char enable_str[] = "online"; +- int rc; +- size_t bytes_wrote; +- +- rc = sprintf(uio_uevent_path, uio_uevent_path_template, uio_minor); +- if (rc < 0) { +- LOG_ERR(PFX "%s: Could not build uio uevent path", +- nic->log_name); +- return -EIO; +- } +- +- LOG_DEBUG(PFX "%s: triggering UIO uevent path: %s", +- nic->log_name, uio_uevent_path); +- +- fd = open(uio_uevent_path, O_WRONLY); +- if (fd == -1) { +- LOG_ERR(PFX "%s: Could not open uio uevent path: %s [%s]", +- nic->log_name, uio_uevent_path, strerror(errno)); +- return -EIO; +- } +- +- bytes_wrote = write(fd, enable_str, sizeof(enable_str)); +- if (bytes_wrote != sizeof(enable_str)) { +- LOG_ERR(PFX "%s: Could write to uio uevent path: %s [%s]", +- nic->log_name, uio_uevent_path, strerror(errno)); +- rc = -EIO; +- } else +- rc = 0; +- +- close(fd); +- return rc; +-} +- +-static int wait_for_file_node_timed(nic_t *nic, char *filepath, int seconds) +-{ +- struct timeval start_time; +- struct timeval wait_time; +- struct timeval total_time; +- struct timespec sleep_req, sleep_rem; +- +- sleep_req.tv_sec = 0; +- sleep_req.tv_nsec = 250000000; +- +- wait_time.tv_sec = seconds; +- wait_time.tv_usec = 0; +- +- if (gettimeofday(&start_time, NULL)) { +- LOG_ERR(PFX "%s: Couldn't gettimeofday() during watch file: %s" +- "[%s]", nic->log_name, filepath, strerror(errno)); +- return -EIO; +- } +- +- timeradd(&start_time, &wait_time, &total_time); +- +- while (1) { +- struct timeval current_time; +- struct stat file_stat; +- +- /* Check if the file node exists */ +- if (stat(filepath, &file_stat) == 0) +- return 0; +- +- if (gettimeofday(¤t_time, NULL)) { +- LOG_ERR(PFX "%s: Couldn't get current time for " +- "watching file: %s [%s]", +- nic->log_name, filepath, strerror(errno)); +- return -EIO; +- } +- +- /* Timeout has excceded return -ETIME */ +- if (timercmp(&total_time, ¤t_time, <)) { +- LOG_ERR(PFX "%s: timeout waiting %d secs for file: %s", +- nic->log_name, seconds, filepath); +- return -ETIME; +- } +- +- nanosleep(&sleep_req, &sleep_rem); +- } +-} +- +-/****************************************************************************** +- * Autodiscovery of iscsi_hosts +- *****************************************************************************/ +-static int filter_host_name(const struct dirent *entry) +-{ +- if ((memcmp(entry->d_name, "host", 4) == 0)) +- return 1; +- else +- return 0; +-} +- +-int nic_discover_iscsi_hosts() +-{ +- struct dirent **files; +- int count; +- int i; +- int rc; +- +- count = scandir(base_iscsi_host_name, &files, filter_host_name, +- alphasort); +- +- switch (count) { +- case 0: +- /* Currently there are no iSCSI hosts */ +- rc = 0; +- break; +- +- case -1: +- LOG_WARN(PFX "Error when scanning path: %s[%s]", +- base_iscsi_host_name, strerror(errno)); +- rc = -EINVAL; +- break; +- +- default: +- /* There are iSCSI hosts */ +- pthread_mutex_lock(&nic_list_mutex); +- for (i = 0; i < count; i++) { +- int host_no; +- char *raw = NULL; +- uint32_t raw_size = 0; +- char temp_path[sizeof(iscsi_host_path_netdev_template) + +- 8]; +- rc = sscanf(files[i]->d_name, host_template, &host_no); +- nic_t *nic; +- +- LOG_INFO(PFX "Found host[%d]: %s", +- host_no, files[i]->d_name); +- +- /* Build the path to determine netdev name */ +- snprintf(temp_path, sizeof(temp_path), +- iscsi_host_path_netdev_template, host_no); +- +- rc = capture_file(&raw, &raw_size, temp_path); +- if (rc != 0) +- continue; +- +- rc = from_host_no_find_associated_eth_device(host_no, +- &nic); +- if (rc != 0) { +- /* Normalize the string */ +- if (raw[raw_size - 1] == '\n') +- raw[raw_size - 1] = '\0'; +- +- nic = nic_init(); +- if (nic == NULL) { +- LOG_ERR(PFX "Couldn't allocate " +- "space for NIC %s " +- "during scan", raw); +- +- free(raw); +- rc = -ENOMEM; +- break; +- } +- +- strncpy(nic->eth_device_name, raw, raw_size); +- nic->config_device_name = nic->eth_device_name; +- nic->log_name = nic->eth_device_name; +- nic->host_no = host_no; +- +- if (nic_fill_name(nic) != 0) { +- free(nic); +- free(raw); +- rc = -EIO; +- continue; +- } +- +- nic_add(nic); +- +- LOG_INFO(PFX "NIC not found creating an " +- "instance for host_no: %d %s", +- host_no, nic->eth_device_name); +- } else +- LOG_INFO(PFX "%s: NIC found host_no: %d", +- nic->log_name, host_no); +- +- free(raw); +- } +- pthread_mutex_unlock(&nic_list_mutex); +- +- /* Cleanup the scandir() call */ +- for (i = 0; i < count; i++) +- free(files[i]); +- free(files); +- +- rc = 0; +- break; +- } +- +- return rc; +-} +- +-/****************************************************************************** +- * Enable/Disable Multicast on physical interface +- *****************************************************************************/ +-static int nic_util_enable_disable_multicast(nic_t *nic, uint32_t cmd) +-{ +- int rc = 0; +- struct uip_eth_addr multicast_addr; +- int fd; +- struct ifreq ifr; +- +- /* adding ethernet multicast address for IPv6 */ +- memcpy(&multicast_addr, nic->mac_addr, ETH_ALEN); +- multicast_addr.addr[0] = 0x33; +- multicast_addr.addr[1] = 0x33; +- multicast_addr.addr[2] = 0xff; +- +- /* Prepare the request */ +- memset(&ifr, 0, sizeof(ifr)); +- strncpy(ifr.ifr_name, nic->eth_device_name, +- sizeof(ifr.ifr_name)); +- memcpy(ifr.ifr_hwaddr.sa_data, multicast_addr.addr, ETH_ALEN); +- +- fd = socket(AF_INET, SOCK_DGRAM, 0); +- if (fd < 0) { +- LOG_ERR(PFX "%s: Couldn't create socket to %s " +- "multicast address: %s", +- nic->log_name, +- cmd == SIOCADDMULTI ? "added" : "delete", +- strerror(errno)); +- return errno; +- } +- +- rc = fcntl(fd, F_SETFL, O_NONBLOCK); +- if (rc != 0) { +- LOG_WARN("%s: Couldn't set to ethtool IOCTL to " +- "non-blocking [%s]", nic->log_name, strerror(errno)); +- } +- +- if (ioctl(fd, cmd, (char *)&ifr) != 0) { +- LOG_ERR("%s: Couldn't issue ioctl socket to %s " +- "multicast address: %s", +- nic->log_name, +- cmd == SIOCADDMULTI ? "add" : "delete", +- strerror(errno)); +- rc = errno; +- goto error; +- } +- +- LOG_INFO(PFX "%s: %s address %02x:%02x:%02x:%02x:%02x:%02x " +- "to multicast list", +- nic->log_name, +- cmd == SIOCADDMULTI ? "Added" : "Deleted", +- multicast_addr.addr[0], multicast_addr.addr[1], +- multicast_addr.addr[2], multicast_addr.addr[3], +- multicast_addr.addr[4], multicast_addr.addr[5]); +- +- if (cmd == SIOCADDMULTI) +- nic->flags |= NIC_ADDED_MULICAST; +- else +- nic->flags &= ~NIC_ADDED_MULICAST; +- +-error: +- close(fd); +- +- return rc; +-} +- +-/** +- * enable_multicast() - This fuction is used to enable +- * the listening of multicast addresses for a given network interface +- * @param nic - NIC device to enable multicast on +- * @return 0 for success or <0 for failure +- */ +-int enable_multicast(nic_t *nic) +-{ +- return nic_util_enable_disable_multicast(nic, SIOCADDMULTI); +-} +- +-/** +- * disable_multicast() - This fuction is used to disable +- * the listening of multicast addresses for a given network interface +- * @param dev - NIC device to disable multicast on +- * @return 0 for success or <0 for failure +- */ +-int disable_multicast(nic_t *nic) +-{ +- return nic_util_enable_disable_multicast(nic, SIOCDELMULTI); +-} +- +-/******************************************************************************* +- * Finding associated UIO/physical network interfaces +- ******************************************************************************/ +-static int filter_net_name(const struct dirent *entry) +-{ +- if ((memcmp(entry->d_name, "net:", 4) == 0)) +- return 1; +- else +- return 0; +-} +- +-static char *extract_net_name(struct dirent **files) +-{ +- return strstr(files[0]->d_name, ":"); +-} +- +-static int filter_dot_out(const struct dirent *entry) +-{ +- if ((memcmp(entry->d_name, ".", 1) == 0)) +- return 0; +- else +- return 1; +-} +- +-static char *extract_none(struct dirent **files) +-{ +- return files[0]->d_name; +-} +- +-/** +- * 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 +- */ +-int from_host_no_find_associated_eth_device(int host_no, nic_t **nic) +-{ +- nic_t *current_nic = nic_list; +- char *raw = NULL, *raw_tmp; +- uint32_t raw_size = 0; +- +- char temp_path[sizeof(iscsi_host_path_netdev_template) + 8]; +- int rc = -EIO; +- +- /* Build the path to determine uio name */ +- snprintf(temp_path, sizeof(temp_path), +- iscsi_host_path_netdev_template, host_no); +- +- rc = capture_file(&raw, &raw_size, temp_path); +- if (rc != 0) +- goto error; +- +- /* sanitize name string by replacing newline with null termination */ +- raw_tmp = raw; +- while (*raw_tmp != '\n' && raw_size--) +- raw_tmp++; +- *raw_tmp = '\0'; +- +- rc = -EIO; +- +- current_nic = nic_list; +- while (current_nic != NULL) { +- if (strcmp(raw, current_nic->eth_device_name) == 0) { +- *nic = current_nic; +- rc = 0; +- break; +- } +- +- current_nic = current_nic->next; +- } +- +- free(raw); +- +-error: +- return rc; +-} +- +-/******************************************************************************* +- * NIC packet handling functions +- ******************************************************************************/ +-/** +- * from_uio_find_associated_eth_device() - Given the uio minor number +- * this function will try to find the assoicated phyisical network +- * interface +- * @param uio_minor - minor number of the UIO device +- * @param name - char buffer which will be filled if successful +- * @param name_size - size of the name buffer +- * @return >0 minor number <0 an error +- */ +-static int from_uio_find_associated_eth_device(nic_t *nic, +- int uio_minor, +- char *name, size_t name_size) +-{ +- char *path; +- int rc; +- int count; +- struct dirent **files; +- char *parsed_name; +- int i; +- int path_iterator; +- char *search_paths[] = { "/sys/class/uio/uio%i/device/", +- "/sys/class/uio/uio%i/device/net" +- }; +- int path_to[] = { 5, 1 }; +- int (*search_filters[]) (const struct dirent *) = { +- filter_net_name, filter_dot_out,}; +- char *(*extract_name[]) (struct dirent **files) = { +- extract_net_name, extract_none,}; +- int extract_name_offset[] = { 1, 0 }; +- +- path = malloc(PATH_MAX); +- if (path == NULL) { +- LOG_ERR(PFX "Could not allocate memory for path"); +- rc = -ENOMEM; +- goto error; +- } +- +- for (path_iterator = 0; +- path_iterator < sizeof(search_paths) / sizeof(search_paths[0]); +- path_iterator++) { +- /* Build the path to determine uio name */ +- rc = sprintf(path, search_paths[path_iterator], uio_minor); +- +- wait_for_file_node_timed(nic, path, path_to[path_iterator]); +- +- count = scandir(path, &files, +- search_filters[path_iterator], alphasort); +- +- switch (count) { +- case 1: +- parsed_name = (*extract_name[path_iterator]) (files); +- if (parsed_name == NULL) { +- LOG_WARN(PFX "Couldn't find delimiter in: %s", +- files[0]->d_name); +- +- break; +- } +- +- strncpy(name, +- parsed_name + +- extract_name_offset[path_iterator], name_size); +- +- free(files[0]); +- free(files); +- +- rc = 0; +- break; +- +- case 0: +- rc = -EINVAL; +- break; +- +- case -1: +- LOG_WARN(PFX "Error when scanning path: %s[%s]", +- path, strerror(errno)); +- rc = -EINVAL; +- break; +- +- default: +- LOG_WARN(PFX +- "Too many entries when looking for device: %s", +- path); +- +- /* Cleanup the scandir() call */ +- for (i = 0; i < count; i++) +- free(files[i]); +- free(files); +- +- rc = -EINVAL; +- break; +- } +- +- if (rc == 0) +- break; +- } +- +-error: +- free(path); +- +- return rc; +-} +- +-/** +- * from_uio_find_associated_host() - Given the uio minor number +- * this function will try to find the assoicated iscsi host +- * @param uio_minor - minor number of the UIO device +- * @param name - char buffer which will be filled if successful +- * @param name_size - size of the name buffer +- * @return >0 minor number <0 an error +- */ +-static int from_uio_find_associated_host(nic_t *nic, int uio_minor, +- char *name, size_t name_size) +-{ +- char *path; +- int rc; +- int count; +- struct dirent **files; +- char *parsed_name; +- int i; +- int path_iterator; +- char *search_paths[] = { "/sys/class/uio/uio%i/device/" }; +- int path_to[] = { 5, 1 }; +- int (*search_filters[]) (const struct dirent *) = { filter_host_name, }; +- char *(*extract_name[]) (struct dirent **files) = { extract_none, }; +- int extract_name_offset[] = { 0 }; +- +- path = malloc(PATH_MAX); +- if (!path) { +- LOG_ERR(PFX "Could not allocate memory for path"); +- rc = -ENOMEM; +- goto error; +- } +- +- for (path_iterator = 0; +- path_iterator < sizeof(search_paths) / sizeof(search_paths[0]); +- path_iterator++) { +- /* Build the path to determine uio name */ +- rc = sprintf(path, search_paths[path_iterator], uio_minor); +- +- wait_for_file_node_timed(nic, path, path_to[path_iterator]); +- +- count = scandir(path, &files, +- search_filters[path_iterator], alphasort); +- +- switch (count) { +- case 1: { +- char *parsed_src; +- size_t parsed_size; +- +- parsed_name = (*extract_name[path_iterator]) (files); +- if (!parsed_name) { +- LOG_WARN(PFX "Couldn't find delimiter in: %s", +- files[0]->d_name); +- +- break; +- } +- +- parsed_src = parsed_name + extract_name_offset[path_iterator]; +- parsed_size = strlen(parsed_src); +- if (parsed_size >= name_size) { +- LOG_WARN(PFX "uio device name too long: %s (max %d)", +- parsed_src, (int)name_size - 1); +- rc = -EINVAL; +- } else { +- strncpy(name, parsed_src, name_size); +- rc = 0; +- } +- +- free(files[0]); +- free(files); +- +- break; +- } +- +- case 0: +- rc = -EINVAL; +- break; +- +- case -1: +- LOG_WARN(PFX "Error when scanning path: %s[%s]", +- path, strerror(errno)); +- rc = -EINVAL; +- break; +- +- default: +- LOG_WARN(PFX +- "Too many entries when looking for device: %s", +- path); +- +- /* Cleanup the scandir() call */ +- for (i = 0; i < count; i++) +- free(files[i]); +- free(files); +- +- rc = -EINVAL; +- break; +- } +- +- if (rc == 0) +- break; +- } +- +-error: +- free(path); +- +- return rc; +-} +- +-/** +- * filter_uio_name() - This is the callback used by scandir when looking for +- * the number of uio entries +- */ +-static int filter_uio_name(const struct dirent *entry) +-{ +- /* Only return if the name of the file begins with 'uio' */ +- if ((memcmp(entry->d_name, uio_name, sizeof(uio_name) - 1) == 0)) +- return 1; +- else +- return 0; +-} +- +-/** +- * from_netdev_name_find_nic() - This is used to find the NIC device given +- * the netdev name +- * @param interface_name - name of the interface to search on +- * @param nic - pointer of the pointer to the NIC +- * @return 0 on success, <0 on failure +- */ +-int from_netdev_name_find_nic(char *interface_name, nic_t **nic) +-{ +- nic_t *current_nic; +- +- current_nic = nic_list; +- while (current_nic != NULL) { +- if (strcmp(interface_name, current_nic->eth_device_name) == 0) +- break; +- +- current_nic = current_nic->next; +- } +- +- if (current_nic == NULL) +- return -EINVAL; +- +- *nic = current_nic; +- return 0; +-} +- +-/** +- * from_phys_name_find_assoicated_uio_device() - This is used to find the +- * uio minor +- * when given a network interface name +- * @param interface_name - network interface name to search for +- * @return >0 minor number <0 an error +- */ +-int from_phys_name_find_assoicated_uio_device(nic_t *nic) +-{ +- char *path = NULL; +- int count; +- struct dirent **files; +- int i; +- int rc; +- char *interface_name = nic->config_device_name; +- +- if (interface_name == NULL) +- interface_name = nic->eth_device_name; +- +- /* Wait at least 10 seconds for uio sysfs entries to appear */ +- rc = wait_for_file_node_timed(nic, (char *)base_uio_sysfs_name, 10); +- if (rc != 0) +- return rc; +- +- count = scandir(base_uio_sysfs_name, +- &files, filter_uio_name, alphasort); +- +- switch (count) { +- case 0: +- LOG_WARN(PFX "Couldn't find %s to determine uio minor", +- interface_name); +- return -EINVAL; +- +- case -1: +- LOG_WARN(PFX "Error when scanning for %s in path: %s [%s]", +- interface_name, base_uio_sysfs_name, strerror(errno)); +- return -EINVAL; +- } +- +- path = malloc(PATH_MAX); +- if (path == NULL) { +- LOG_ERR(PFX "Could not allocate memory for path"); +- return -ENOMEM; +- } +- +- /* Run through the contents of the filtered files to see if the +- * network interface name matches that of the uio device */ +- for (i = 0; i < count; i++) { +- int uio_minor; +- char eth_name[IFNAMSIZ]; +- +- rc = sscanf(files[i]->d_name, "uio%d", &uio_minor); +- if (rc != 1) { +- LOG_WARN("Could not parse: %s", files[i]->d_name); +- continue; +- } +- +- if (!memcmp(host_pfx, nic->config_device_name, +- strlen(host_pfx))) { +- rc = from_uio_find_associated_host(nic, uio_minor, +- eth_name, +- sizeof(eth_name)); +- } else { +- rc = from_uio_find_associated_eth_device(nic, uio_minor, +- eth_name, +- sizeof(eth_name)); +- } +- if (rc != 0) { +- LOG_WARN("uio minor: %d not valid [%D]", uio_minor, rc); +- continue; +- } +- +- if (strncmp(eth_name, interface_name, sizeof(eth_name)) == 0) { +- memcpy(nic->eth_device_name, +- eth_name, sizeof(nic->eth_device_name)); +- +- LOG_INFO(PFX "%s associated with uio%d", +- nic->eth_device_name, uio_minor); +- +- rc = uio_minor; +- goto done; +- } +- } +- +- LOG_WARN("Could not find assoicate uio device with %s", interface_name); +- +- rc = -EINVAL; +-done: +- if (path != NULL) +- free(path); +- +- for (i = 0; i < count; i++) +- free(files[i]); +- free(files); +- +- return rc; +- +-} +- +-/** +- * nic_verify_uio_sysfs_name() - Using the name entry in sysfs it will try to +- * match the NIC library name +- * @param nic - The NIC hardware to check +- * +- */ +-int nic_verify_uio_sysfs_name(nic_t *nic) +-{ +- char *raw = NULL, *raw_tmp; +- uint32_t raw_size = 0; +- char temp_path[sizeof(nic_uio_sysfs_name_tempate) + 8]; +- int rc = 0; +- nic_lib_handle_t *handle = NULL; +- size_t name_size; +- +- +- /* Build the path to determine uio name */ +- snprintf(temp_path, sizeof(temp_path), +- nic_uio_sysfs_name_tempate, nic->uio_minor); +- +- rc = capture_file(&raw, &raw_size, temp_path); +- if (rc != 0) +- goto error; +- +- /* sanitize name string by replacing newline with null termination */ +- raw_tmp = raw; +- while (*raw_tmp != '\n' && raw_size--) +- raw_tmp++; +- *raw_tmp = '\0'; +- +- /* If the nic library is not set then check if there is a library +- * which matches the uio sysfs name */ +- if (nic->nic_library == NULL) { +- NIC_LIBRARY_EXIST_T exist; +- +- exist = does_nic_uio_name_exist(raw, &handle); +- if (exist == NIC_LIBRARY_DOESNT_EXIST) { +- LOG_ERR(PFX "%s: could not find library for uio name: %s", +- nic->log_name, raw); +- rc = -EINVAL; +- goto error; +- } +- +- /* fill the lib info */ +- nic->nic_library = handle; +- nic->ops = handle->ops; +- (*nic->ops->lib_ops.get_library_name) (&nic->library_name, +- &name_size); +- } else { +- /* Get the uio sysfs name from the NIC library */ +- (*nic->ops->lib_ops.get_uio_name) (&raw_tmp, &name_size); +- +- if (strncmp(raw, raw_tmp, name_size) != 0) { +- LOG_ERR(PFX "%s: uio names not equal: " +- "expecting %s got %s from %s", +- nic->log_name, raw, raw_tmp, temp_path); +- rc = -EINVAL; +- goto error; +- } +- } +- +- LOG_INFO(PFX "%s: Verified uio name %s with library %s", +- nic->log_name, raw, nic->library_name); +- +-error: +- if (raw) +- free(raw); +- +- return rc; +-} +- +-/** +- * nic_fill_name() - This will initialize all the hardware resources underneath +- * a struct cnic_uio device +- * @param nic - The nic device to attach the hardware with +- * @return 0 on success, on failure a errno will be returned +- */ +-int nic_fill_name(nic_t *nic) +-{ +- int rc; +- +- if ((nic->config_device_name != NULL) && +- (memcmp(uio_base_dir, nic->config_device_name, +- sizeof(uio_base_dir) - 1) == 0)) { +- uint16_t uio_minor; +- char eth_name[sizeof(nic->eth_device_name)]; +- +- wait_for_file_node_timed(nic, nic->config_device_name, 5); +- +- /* Determine the minor number for the UIO device */ +- rc = sscanf(nic->config_device_name, uio_udev_path_template, +- &uio_minor); +- if (rc != 1) { +- LOG_WARN(PFX "%s: Could not parse for minor number", +- nic->uio_device_name); +- return -EINVAL; +- } else +- nic->uio_minor = uio_minor; +- +- nic->uio_device_name = nic->config_device_name; +- +- /* Determine the assoicated physical network interface */ +- rc = from_uio_find_associated_eth_device(nic, +- nic->uio_minor, +- eth_name, +- sizeof(eth_name)); +- if (rc != 0) { +- LOG_WARN(PFX "%s: Couldn't find associated eth device", +- nic->uio_device_name); +- } else { +- memcpy(nic->eth_device_name, +- eth_name, sizeof(eth_name)); +- } +- +- LOG_INFO(PFX "%s: configured for uio device for %s", +- nic->log_name, nic->uio_device_name); +- +- } else { +- LOG_INFO(PFX "looking for uio device for %s", +- nic->config_device_name); +- +- rc = from_phys_name_find_assoicated_uio_device(nic); +- if (rc < 0) { +- LOG_ERR(PFX "Could not determine UIO name for %s", +- nic->config_device_name); +- +- return -rc; +- } +- +- nic->uio_minor = rc; +- +- if (nic->flags & NIC_UIO_NAME_MALLOC) +- free(nic->uio_device_name); +- +- nic->uio_device_name = +- malloc(sizeof(uio_udev_path_template) + 8); +- if (nic->uio_device_name == NULL) { +- LOG_INFO(PFX "%s: Couldn't malloc space for uio name", +- nic->log_name); +- return -ENOMEM; +- } +- +- snprintf(nic->uio_device_name, +- sizeof(uio_udev_path_template) + 8, +- uio_udev_path_template, nic->uio_minor); +- +- nic->flags |= NIC_UIO_NAME_MALLOC; +- } +- +- return 0; +-} +- +-void cnic_get_sysfs_pci_resource_path(nic_t *nic, int resc_no, +- char *sys_path, size_t size) +-{ +- /* Build the path to sysfs pci resource */ +- snprintf(sys_path, size, +- cnic_uio_sysfs_resc_template, nic->uio_minor, resc_no); +- +-} +- +-void prepare_library(nic_t *nic) +-{ +- int rc; +- NIC_LIBRARY_EXIST_T exist; +- nic_lib_handle_t *handle = NULL; +- +- nic_fill_name(nic); +- +- /* No assoicated library, we can skip it */ +- if (nic->library_name != NULL) { +- /* Check that we have the proper NIC library loaded */ +- exist = does_nic_library_exist(nic->library_name, &handle); +- if (exist == NIC_LIBRARY_DOESNT_EXIST) { +- LOG_ERR(PFX "NIC library doesn't exists: %s", +- nic->library_name); +- goto error; +- } else if (handle && (nic->nic_library == handle) && +- (nic->ops == handle->ops)) { +- LOG_INFO("%s: Have NIC library '%s'", +- nic->log_name, nic->library_name); +- } +- } +- +- /* Verify the NIC library to use */ +- rc = nic_verify_uio_sysfs_name(nic); +- if (rc != 0) { +- /* Determine the NIC library to use based on the PCI Id */ +- rc = find_set_nic_lib(nic); +- if (rc != 0) { +- LOG_ERR(PFX "%s: Couldn't find NIC library", +- nic->log_name); +- goto error; +- } +- +- } +- +- LOG_INFO("%s: found NIC with library '%s'", +- nic->log_name, nic->library_name); +-error: +- return; +-} +- +-void prepare_nic_thread(nic_t *nic) +-{ +- pthread_attr_t attr; +- int rc; +- +- pthread_mutex_lock(&nic->nic_mutex); +- if (nic->thread == INVALID_THREAD) { +- struct timespec ts; +- struct timeval tp; +- +- LOG_INFO(PFX "%s: spinning up thread for nic", nic->log_name); +- +- /* Try to spin up the nic thread */ +- pthread_attr_init(&attr); +- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); +- rc = pthread_create(&nic->thread, &attr, nic_loop, nic); +- if (rc != 0) { +- LOG_ERR(PFX "%s: Couldn't create thread for nic", +- nic->log_name); +- goto error; +- } +- +- /* Convert from timeval to timespec */ +- rc = gettimeofday(&tp, NULL); +- ts.tv_sec = tp.tv_sec; +- ts.tv_nsec = tp.tv_usec * 1000; +- ts.tv_sec += 5; /* TODO: hardcoded wait for 5 seconds */ +- +- /* Wait for the nic loop thread to to running */ +- rc = pthread_cond_timedwait(&nic->nic_loop_started_cond, +- &nic->nic_mutex, &ts); +- +- LOG_INFO("Created nic thread: %s", nic->log_name); +- } +- +- pthread_mutex_unlock(&nic->nic_mutex); +- +-error: +- return; +-} +- +-/******************************************************************************* +- * Functions used to enable/disable the NIC +- ******************************************************************************/ +-/** +- * nic_enable() - Function used to enable the NIC +- * @param nic - NIC to enable +- * @return 0 on success, <0 on failure +- */ +-int nic_enable(nic_t *nic) +-{ +- if (nic->flags & NIC_GOING_DOWN) { +- LOG_INFO(PFX "%s: NIC device is going down, " +- "flag: 0x%x state: 0x%x", +- nic->log_name, nic->flags, nic->state); +- return -EINVAL; +- } +- if (nic->state == NIC_STOPPED) { +- struct timespec ts; +- struct timeval tp; +- int rc; +- +- pthread_mutex_lock(&nic->nic_mutex); +- /* Signal the device to enable itself */ +- pthread_cond_broadcast(&nic->enable_wait_cond); +- +- nic->flags &= ~NIC_DISABLED; +- nic->flags |= NIC_ENABLED; +- nic->flags |= NIC_ENABLED_PENDING; +- +- /* Convert from timeval to timespec */ +- rc = gettimeofday(&tp, NULL); +- ts.tv_sec = tp.tv_sec; +- ts.tv_nsec = tp.tv_usec * 1000; +- ts.tv_sec += 100; +- +- /* Wait for the device to be enabled */ +- rc = pthread_cond_timedwait(&nic->enable_done_cond, +- &nic->nic_mutex, &ts); +- if (rc == 0 && nic->flags & NIC_ENABLED) { +- LOG_DEBUG(PFX "%s: device enabled", nic->log_name); +- } else { +- 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)); +- } +- pthread_mutex_unlock(&nic->nic_mutex); +- +- return rc; +- } else { +- LOG_INFO(PFX "%s: device already enabled: " +- "flag: 0x%x state: 0x%x", +- nic->log_name, nic->flags, nic->state); +- return -EALREADY; +- } +-} +- +-/** +- * nic_disable() - Function used to disable the NIC +- * @param nic - NIC to disble +- * @return void +- */ +-void nic_disable(nic_t *nic, int going_down) +-{ +- if (nic->state == NIC_STARTED_RUNNING || +- nic->state == NIC_RUNNING) { +- struct timespec ts; +- struct timeval tp; +- int rc; +- +- /* Wait for the device to be disabled */ +- pthread_mutex_lock(&nic->nic_mutex); +- +- nic->flags &= ~NIC_ENABLED; +- nic->flags |= NIC_DISABLED; +- nic->flags &= ~NIC_STARTED_RUNNING; +- nic->state = NIC_STOPPED; +- +- if (going_down) +- nic->flags |= NIC_GOING_DOWN; +- +- /* Convert from timeval to timespec */ +- rc = gettimeofday(&tp, NULL); +- if (rc) { +- LOG_ERR("gettimeofday failed, should never happen: %d\n", errno); +- pthread_mutex_unlock(&nic->nic_mutex); +- return; +- } +- +- ts.tv_sec = tp.tv_sec; +- ts.tv_nsec = tp.tv_usec * 1000; +- ts.tv_sec += 5; /* TODO: hardcoded wait for 5 seconds */ +- +- /* Wait for the device to be disabled */ +- rc = pthread_cond_timedwait(&nic->disable_wait_cond, +- &nic->nic_mutex, &ts); +- if (rc) { +- LOG_ERR("cond_timedwait failed, should never happen: %d\n", errno); +- } +- +- pthread_mutex_unlock(&nic->nic_mutex); +- +- LOG_DEBUG(PFX "%s: device disabled", nic->log_name); +- +- } else { +- LOG_WARN(PFX "%s: device already disabled: " +- "flag: 0x%x state: 0x%x", +- nic->log_name, nic->flags, nic->state); +- } +-} +- +-void nic_close_all() +-{ +- nic_t *nic; +- +- pthread_mutex_lock(&nic_list_mutex); +- +- /* Start the shutdown process */ +- nic = nic_list; +- while (nic != NULL) { +- pthread_mutex_lock(&nic->nic_mutex); +- nic_close(nic, 1, FREE_ALL_STRINGS); +- pthread_mutex_unlock(&nic->nic_mutex); +- +- nic = nic->next; +- } +- pthread_mutex_unlock(&nic_list_mutex); +- +- LOG_INFO(PFX "All NICs closed"); +-} +- +-void nic_remove_all() +-{ +- nic_t *nic, *nic_next; +- +- pthread_mutex_lock(&nic_list_mutex); +- +- /* Start the shutdown process */ +- 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; +- } +- pthread_mutex_unlock(&nic_list_mutex); +- +- LOG_INFO(PFX "All NICs removed"); +-} +- +- +-/****************************************************************************** +- * Routines to read initialized UIO values from sysfs +- *****************************************************************************/ +-/** +- * determine_initial_uio_events() - This utility function will +- * determine the number of uio events that have occured on the +- * given device. This value is read from the UIO sysfs entry +- * @param dev - device to read from +- * @param num_of_event - number of UIO events +- * @return 0 is success, <0 failure +- */ +-int detemine_initial_uio_events(nic_t *nic, uint32_t *num_of_events) +-{ +- char *raw = NULL; +- uint32_t raw_size = 0; +- ssize_t elements_read; +- char temp_path[sizeof(cnic_sysfs_uio_event_template) + 8]; +- int rc; +- +- /* Capture RX buffer size */ +- snprintf(temp_path, sizeof(temp_path), +- cnic_sysfs_uio_event_template, nic->uio_minor); +- +- rc = capture_file(&raw, &raw_size, temp_path); +- if (rc != 0) +- goto error; +- +- elements_read = sscanf(raw, "%d", num_of_events); +- if (elements_read != 1) { +- LOG_ERR(PFX "%s: Couldn't parse UIO events size from %s", +- nic->log_name, temp_path); +- rc = -EIO; +- goto error; +- } +- +- rc = 0; +-error: +- if (raw) +- free(raw); +- +- return rc; +-} +- +-int get_iscsi_transport_handle(nic_t *nic, uint64_t *handle) +-{ +- char *raw = NULL; +- uint32_t raw_size = 0; +- ssize_t elements_read; +- char temp_path[sizeof(iscsi_transport_handle_template) + 8]; +- int rc; +- +- /* Capture RX buffer size */ +- snprintf(temp_path, sizeof(temp_path), +- iscsi_transport_handle_template, nic->library_name); +- +- rc = capture_file(&raw, &raw_size, temp_path); +- if (rc != 0) +- goto error; +- +- elements_read = sscanf(raw, "%" PRIu64, handle); +- if (elements_read != 1) { +- LOG_ERR(PFX "%s: Couldn't parse transport handle from %s", +- nic->log_name, temp_path); +- rc = -EIO; +- goto error; +- } +- +- rc = 0; +-error: +- if (raw != NULL) +- free(raw); +- +- return rc; +-} +- +-/** +- * 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) +-{ +- nic_interface_t *current, *vlan_current; +- +- current = nic->nic_iface; +- while (current != NULL) { +- /* Set the initial MAC address of this interface to the parent +- * adapter */ +- memcpy(current->mac_addr, nic->mac_addr, 6); +- +- vlan_current = current->vlan_next; +- while (vlan_current != NULL) { +- memcpy(vlan_current->mac_addr, nic->mac_addr, 6); +- vlan_current = vlan_current->vlan_next; +- } +- current = current->next; +- } +-} +- +-/******************************************************************************* +- * NIC packet handling functions +- ******************************************************************************/ +-/** +- * nic_alloc_packet_buffer() - Used to allocate a packet buffer used to +- * send a TX packet later +- * @param nic - nic device to send the packet on +- * @param nic_iface - nic interface to send out on +- * @param buf - pointer to the buffer to send +- * @param buf_size - size in bytes of the buffer to send +- * @return pointer to the allocated packet buffer +- * NULL if memory could not be allocated +- */ +-static packet_t *nic_alloc_packet_buffer(nic_t *nic, +- nic_interface_t *nic_iface, +- uint8_t *buf, size_t buf_size) +-{ +- packet_t *pkt; +- +- pkt = malloc(sizeof(*pkt) + buf_size); +- if (pkt == NULL) { +- LOG_ERR(PFX "%s: Couldn't allocate space for packet buffer", +- nic->log_name); +- return NULL; +- } +- +- pkt->next = NULL; +- pkt->nic = nic; +- pkt->nic_iface = nic_iface; +- pkt->buf_size = buf_size; +- memcpy(pkt->buf, buf, buf_size); +- +- return pkt; +-} +- +-/** +- * nic_queue_tx_packet() - Used to queue a TX packet buffer to send later +- * @param nic - NIC device to send the packet on +- * @param nic_iface - NIC interface to send on the packet on +- * @param pkt - packet to queue +- * @return 0 if successful or <0 if unsuccessful +- */ +-int nic_queue_tx_packet(nic_t *nic, +- nic_interface_t *nic_iface, packet_t *pkt) +-{ +- packet_t *queued_pkt; +- +- queued_pkt = nic_alloc_packet_buffer(nic, nic_iface, +- pkt->buf, pkt->buf_size); +- if (queued_pkt == NULL) { +- LOG_ERR(PFX "%s: Couldn't allocate tx packet to queue", +- nic->log_name); +- return -ENOMEM; +- } +- +- if (nic->tx_packet_queue == NULL) { +- nic->tx_packet_queue = queued_pkt; +- } else { +- packet_t *current_pkt; +- +- current_pkt = nic->tx_packet_queue; +- while (current_pkt->next != NULL) +- current_pkt = current_pkt->next; +- +- current_pkt->next = queued_pkt; +- } +- +- LOG_DEBUG(PFX "%s: tx packet queued", nic->log_name); +- +- return 0; +-} +- +-/** +- * nic_dequeue_tx_packet() - Used pop a TX packet buffer of the TX +- * @param dev - cnic_uio device to send the packet on +- * @param buf - pointer to the buffer to send +- * @param buf_size - size in bytes of the buffer to send +- * @return NULL if there are no more TX packet buffers to send +- * pointer to the packet buffer which is detached from the device +- */ +-packet_t *nic_dequeue_tx_packet(nic_t *nic) +-{ +- packet_t *pkt; +- +- pkt = nic->tx_packet_queue; +- +- /* There is a packet buffer to send, time to detach it from the +- * cnic_uio device */ +- if (pkt != NULL) { +- nic->tx_packet_queue = pkt->next; +- pkt->next = NULL; +- } +- +- return pkt; +-} +- +-void nic_fill_ethernet_header(nic_interface_t *nic_iface, +- void *data, +- void *src_addr, void *dest_addr, +- int *pkt_size, void **start_addr, +- uint16_t ether_type) +-{ +- struct ether_header *eth; +- uint16_t *vlan_hdr; +- +- eth = data; +- +- memcpy(eth->ether_shost, src_addr, ETH_ALEN); +- memcpy(eth->ether_dhost, dest_addr, ETH_ALEN); +- +- vlan_hdr = (uint16_t *) (eth + 1); +- eth->ether_type = htons(ether_type); +- +- *start_addr = vlan_hdr; +-} +- +-/******************************************************************************* +- * 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 +- * @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(nic_t *nic, +- uint16_t protocol, +- uint16_t vlan_id, +- int iface_num, +- int request_type) +-{ +- nic_interface_t *current = nic->nic_iface; +- nic_interface_t *current_vlan = NULL; +- +- while (current != NULL) { +- LOG_DEBUG(PFX "%s: incoming protocol: %d, vlan_id:%d iface_num: %d, request_type: %d", +- nic->log_name, protocol, vlan_id, iface_num, request_type); +- LOG_DEBUG(PFX "%s: host:%d iface_num: 0x%x VLAN: %d protocol: %d", +- nic->log_name, nic->host_no, current->iface_num, current->vlan_id, current->protocol); +- 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; +- } +-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, *current; +- +- current = nic->nic_iface; +- while (current != NULL) { +- current->flags |= NIC_IFACE_PERSIST; +- current_vlan = current->vlan_next; +- while (current_vlan != NULL) { +- current_vlan->flags |= NIC_IFACE_PERSIST; +- current_vlan = current_vlan->vlan_next; +- } +- current = current->next; +- } +-} +- +-/* 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; +- +- prev = NULL; +- current = nic->nic_iface; +- while (current != NULL) { +- 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: +- return; +-} +- +-/******************************************************************************* +- * Packet management utility functions +- ******************************************************************************/ +-/** +- * get_next_packet_in_queue() - This function will return the next packet in +- * the queue +- * @param queue - the queue to pull the packet from +- * @return the packet in the queue +- */ +-static packet_t *get_next_packet_in_queue(packet_t **queue) +-{ +- packet_t *pkt; +- +- if (*queue == NULL) +- return NULL; +- +- pkt = *queue; +- *queue = pkt->next; +- +- return pkt; +-} +- +-/** +- * get_next_tx_packet() - This function will return the next packet in +- * the TX queue +- * @param nic - NIC to pull the TX packet from +- * @return the packet in hte queue +- */ +-packet_t *get_next_tx_packet(nic_t *nic) +-{ +- return get_next_packet_in_queue(&nic->tx_packet_queue); +-} +- +-/** +- * get_next_free_packet() - This function will return the next packet in +- * the free queue +- * @param nic - NIC to pull the RX packet from +- * @return the packet in hte queue +- */ +-packet_t *get_next_free_packet(nic_t *nic) +-{ +- packet_t *pkt; +- pthread_mutex_lock(&nic->free_packet_queue_mutex); +- pkt = get_next_packet_in_queue(&nic->free_packet_queue); +- pthread_mutex_unlock(&nic->free_packet_queue_mutex); +- +- if (pkt != NULL) +- reset_packet(pkt); +- +- return pkt; +-} +- +-/** +- * put_packet_in_queue() - This function will place the packet in the given +- * queue +- * @param pkt - the packet to place +- * @param queue - the queue to place the packet +- * @return the packet in the queue +- */ +-static void put_packet_in_queue(packet_t *pkt, packet_t **queue) +-{ +- if (*queue == NULL) +- *queue = pkt; +- else { +- pkt->next = *queue; +- *queue = pkt; +- } +-} +- +-/** +- * put_packet_in_tx_queue() - This function will place the packet in +- * the TX queue +- * @param pkt - packet to place +- * @param nic - NIC to pull the TX packet from +- * @return the packet in hte queue +- */ +-void put_packet_in_tx_queue(packet_t *pkt, nic_t *nic) +-{ +- return put_packet_in_queue(pkt, &nic->tx_packet_queue); +-} +- +-/** +- * put_packet_in_free_queue() - This function will place the packet in +- * the RX queue +- * @param pkt - packet to place +- * @param nic - NIC to pull the RX packet from +- * @return the packet in hte queue +- */ +-void put_packet_in_free_queue(packet_t *pkt, nic_t *nic) +-{ +- pthread_mutex_lock(&nic->free_packet_queue_mutex); +- put_packet_in_queue(pkt, &nic->free_packet_queue); +- pthread_mutex_unlock(&nic->free_packet_queue_mutex); +-} +- +-uint32_t calculate_default_netmask(uint32_t ip_addr) +-{ +- uint32_t netmask; +- +- if (IN_CLASSA(ntohl(ip_addr))) +- netmask = htonl(IN_CLASSA_NET); +- else if (IN_CLASSB(ntohl(ip_addr))) +- netmask = htonl(IN_CLASSB_NET); +- else if (IN_CLASSC(ntohl(ip_addr))) +- netmask = htonl(IN_CLASSC_NET); +- else { +- LOG_ERR("Unable to guess netmask for address %x\n", &ip_addr); +- return -1; +- } +- +- return netmask; +-} +- +-void dump_packet_to_log(struct nic_interface *iface, +- uint8_t *buf, uint16_t buf_len) +-{ +- +- FILE *file; +- char str[80]; +- int i, count; +- +- file = fmemopen(str, sizeof(str), "w+"); +- if (file == NULL) { +- LOG_ERR(PFX "Could not create logging file stream for packet " +- "logging: [%d: %s]", errno, strerror(errno)); +- return; +- } +- +- LOG_PACKET(PFX "%s: Start packet dump len: %d", iface->parent->log_name, +- buf_len); +- +- for (i = 0; i < buf_len; i++) { +- rewind(file); +- fprintf(file, "%03x: ", i); +- +- for (count = 0; (count < 8) && i < buf_len; count++, i++) +- fprintf(file, " %02x", buf[i]); +- fflush(file); +- +- LOG_PACKET(PFX "%s: %s", iface->parent->log_name, str); +- } +- +- LOG_PACKET(PFX "%s: end packet dump", iface->parent->log_name); +- +- fclose(file); +-} +- +-/******************************************************************************* +- * File Management +- ******************************************************************************/ +- /** +- * determine_file_size_read() - when fstat doesn't work on filepath +- * within the /proc filesytem, we need to read/count the size of the file +- * until we hit a EOF +- * @parm filepath - path of the file in which to determine the filesize in +- * bytes +- * @return file size in bytes, <0 on failure +- */ +-int determine_file_size_read(const char *filepath) +-{ +- size_t total_size = 0; +- ssize_t size = 1; +- int fd; +- char buf[1024]; +- +- fd = open(filepath, O_RDONLY); +- if (fd == -1) { +- LOG_ERR("Could not open file: %s [%s]", +- filepath, strerror(errno)); +- return -1; +- } +- +- while (size > 0) { +- size = read(fd, buf, sizeof(buf)); +- +- switch (size) { +- case 0: +- break; +- case -1: +- LOG_ERR("Error reading file: %s [%s]", +- filepath, strerror(errno)); +- total_size = -1; +- break; +- default: +- total_size += size; +- break; +- } +- } +- +- close(fd); +- +- return total_size; +-} +- +-/** +- * capture_file() - Used to capture a file into a buffer +- * @param raw - This pointer will be set to the buffer which will hold the +- * file contents +- * @param raw_size - This is the size of the buffer returned +- * @param path - The file path to capture the data from +- * @return 0 is returned on success, <0 is returned on failure +- */ +-int capture_file(char **raw, uint32_t *raw_size, const char *path) +-{ +- FILE *fp; +- size_t read_size; +- int rc = 0; +- int file_size; +- +- file_size = determine_file_size_read(path); +- if (file_size < 0) { +- LOG_ERR("Could not determine size %s", path); +- return -EIO; +- } +- +- fp = fopen(path, "r"); +- if (fp == NULL) { +- LOG_ERR("Could not open path %s [%s]", path, strerror(errno)); +- return -EIO; +- } +- +- *raw = malloc(file_size); +- if (*raw == NULL) { +- LOG_ERR("Could not malloc space for capture %s", path); +- rc = -ENOMEM; +- goto error; +- } +- +- read_size = fread(*raw, file_size, 1, fp); +- if (!read_size) { +- LOG_ERR("Could not read capture, path: %s len: %d [%s]", +- path, file_size, strerror(ferror(fp))); +- free(*raw); +- *raw = NULL; +- rc = errno; +- } else +- *raw_size = file_size; +- +-error: +- fclose(fp); +- +- LOG_INFO("Done capturing %s", path); +- +- return rc; +-} +diff --git a/iscsiuio/src/unix/nic_utils.h b/iscsiuio/src/unix/nic_utils.h +deleted file mode 100644 +index e4cf5c1..0000000 +--- a/iscsiuio/src/unix/nic_utils.h ++++ /dev/null +@@ -1,104 +0,0 @@ +-/* +- * Copyright (c) 2009-2011, Broadcom Corporation +- * Copyright (c) 2014, QLogic Corporation +- * +- * Written by: Benjamin Li (benli@broadcom.com) +- * +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. All advertising materials mentioning features or use of this software +- * must display the following acknowledgement: +- * This product includes software developed by Adam Dunkels. +- * 4. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * nic_util.h - NIC utility functions +- * +- */ +-#ifndef __NIC_UTILS_H__ +-#define __NIC_UTILS_H__ +- +-#include "nic.h" +- +-/****************************************************************************** +- * Function Prototype +- ******************************************************************************/ +-int manually_trigger_uio_event(nic_t *nic, int uio_minor); +- +-int nic_discover_iscsi_hosts(); +- +-int enable_mutlicast(nic_t *nic); +-int disable_mutlicast(nic_t *nic); +- +-int from_netdev_name_find_nic(char *interface_name, nic_t **nic); +- +-int from_host_no_find_associated_eth_device(int host_no, nic_t **nic); +- +-int from_phys_name_find_assoicated_uio_device(nic_t *nic); +- +-int nic_queue_tx_packet(nic_t *nic, +- nic_interface_t *nic_iface, packet_t *pkt); +- +-packet_t *nic_dequeue_tx_packet(nic_t *nic); +- +-void nic_fill_ethernet_header(nic_interface_t *nic_iface, +- void *data, +- void *src_addr, void *dest_addr, +- int *pkt_size, void **start_addr, +- uint16_t ether_type); +- +-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); +- +-int add_vlan_interfaces(nic_t *nic); +- +-int nic_verify_uio_sysfs_name(nic_t *nic); +-void cnic_get_sysfs_pci_resource_path(nic_t *nic, int resc_no, +- char *sys_path, size_t size); +-void nic_close_all(); +-void nic_remove_all(); +- +-int detemine_initial_uio_events(nic_t *nic, uint32_t *num_of_events); +- +-uint32_t calculate_default_netmask(uint32_t ip_addr); +- +-void prepare_nic_thread(nic_t *nic); +-void prepare_library(nic_t *nic); +- +-int nic_enable(nic_t *nic); +-void nic_disable(nic_t *nic, int going_down); +- +-void dump_packet_to_log(struct nic_interface *iface, +- uint8_t *buf, uint16_t buf_len); +- +-int determine_file_size_read(const char *filepath); +-int capture_file(char **raw, uint32_t *raw_size, const char *path); +- +-int get_iscsi_transport_handle(nic_t *nic, uint64_t *handle); +- +-#endif /* __NIC_UTILS_H__ */ +diff --git a/iscsiuio/src/unix/nic_vlan.c b/iscsiuio/src/unix/nic_vlan.c +deleted file mode 100644 +index eb33381..0000000 +--- a/iscsiuio/src/unix/nic_vlan.c ++++ /dev/null +@@ -1,337 +0,0 @@ +-/* +- * Copyright (c) 2009-2011, Broadcom Corporation +- * Copyright (c) 2014, QLogic Corporation +- * +- * Written by: Benjamin Li (benli@broadcom.com) +- * +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. All advertising materials mentioning features or use of this software +- * must display the following acknowledgement: +- * This product includes software developed by Adam Dunkels. +- * 4. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * nic_vlan.c - uIP user space stack VLAN utilities +- * +- */ +-#define _GNU_SOURCE +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include +-#include +-#include +-#include +- +-#include "logger.h" +-#include "nic.h" +-#include "nic_utils.h" +-#include "nic_vlan.h" +- +-/******************************************************************************* +- * Constants +- ******************************************************************************/ +-#define PFX "vlan" +- +-static const char proc_vlan_config_path[] = "/proc/net/vlan/config"; +- +-/******************************************************************************* +- * Resolving Found VLAN's for CNIC +- ******************************************************************************/ +-int init_vlan_found_handle(struct vlan_found_handle *found_handle, +- struct vlan_handle *handle) +-{ +- memset(found_handle, 0, sizeof(*found_handle)); +- +- found_handle->entries = malloc(found_handle->num_of_entries * +- sizeof(struct vlan_found_entry)); +- if (found_handle->entries == NULL) { +- LOG_ERR("Could not allocate space for found entries"); +- return -ENOMEM; +- } +- +- found_handle->handle = handle; +- found_handle->num_of_entries = handle->num_of_entries; +- +- memset(found_handle->entries, 0, found_handle->num_of_entries * +- sizeof(struct vlan_found_entry)); +- +- handle->outstanding_found_handles++; +- +- return 0; +-} +- +-void release_vlan_found_handle(struct vlan_found_handle *found_handle) +-{ +- if (found_handle->entries != NULL) { +- free(found_handle->entries); +- found_handle->entries = NULL; +- } +- +- found_handle->num_of_entries = 0; +- +- found_handle->handle->outstanding_found_handles--; +- +- found_handle->handle = NULL; +- +-} +- +-/******************************************************************************* +- * Resolving VLAN's for CNIC +- ******************************************************************************/ +-/** +- * init_vlan_handle() - Used to initialize struct ipv4_route_handle so +- * that is can be used +- * @param handle - Pointer to struct ipv4_route_handle to initialize +- * @return 0 on success and <0 on failure +- */ +-void init_vlan_table(struct vlan_handle *handle) +-{ +- handle->entries = NULL; +- handle->num_of_entries = 0; +-} +- +-/** +- * parse_vlan_table() - Given the raw dump of a Linux vlan table, this +- * function will parse the into entries held by +- * struct vlan_handle +- * @param handle - struct vlan_handle used to hold the parsed contents +- * @param raw - buffer to parse the contents from +- * @param raw_size - size of the buffer in bytes +- * @return 0 on success, <0 on failure +- */ +-int parse_vlan_table(struct vlan_handle *handle, char *raw, uint32_t raw_size) +-{ +- FILE *fp; +- int i; +- char *token; +- size_t size; +- int rc; +- +- token = raw; +- +- /* determine the number of entries */ +- while (*token != '\0') { +- if (*token == '\n') +- handle->num_of_entries++; +- +- token++; +- } +- +- /* There are 2 lines which describe the vlan table +- * This lines need to be skipped with counting */ +- handle->num_of_entries -= 2; +- +- LOG_INFO("Number of vlan entries: %d", handle->num_of_entries); +- +- size = handle->num_of_entries * sizeof(struct vlan_entry); +- handle->entries = malloc(size); +- if (handle->entries == NULL) { +- LOG_ERR +- ("Couldn't malloc space to parse vlan table. entires: %d " +- "size: %d", +- handle->num_of_entries, size); +- return -ENOMEM; +- } +- +- fp = fmemopen(raw, raw_size, "r"); +- if (fp == NULL) { +- LOG_ERR("Could not open raw dump of vlan table"); +- rc = errno; +- goto fmemopen_error; +- } +- +- if (fscanf(fp, "%*[^\n]\n") < 0) { /* Skip the first line. */ +- LOG_ERR("Empty or missing line, or read error"); +- rc = -EIO; +- goto error; +- } +- +- if (fscanf(fp, "%*[^\n]\n") < 0) { /* Skip the second line. */ +- LOG_ERR("Empty or missing line, or read error"); +- rc = -EIO; +- goto error; +- } +- +- i = 0; +- /* Time to parse the routing table */ +- while (1) { +- struct vlan_entry *entry = &handle->entries[i]; +- int r; +- +- r = fscanf(fp, "%15s |%hu |%15s", +- entry->vlan_iface_name, +- &entry->vlan_id, entry->phy_iface_name); +- if (r != 3) { +- if (feof(fp)) { /* EOF with no (nonspace) chars read. */ +- break; +- } +- +- LOG_WARN("Parsing error: parsed %d elements", r); +- break; +- } +- +- i++; +- +- LOG_DEBUG("Vlan %d: vlan iface:%s vlan id:%d phys iface:%s", +- i, +- entry->vlan_iface_name, +- entry->vlan_id, entry->phy_iface_name); +- } +- +- fclose(fp); +- +- return 0; +- +-error: +- fclose(fp); +- +-fmemopen_error: +- if (handle->entries != NULL) +- free(handle->entries); +- +- return rc; +-} +- +-/** +- * capture_vlan_table() - This function will snapshot the Linux vlan +- * routing table for further processing +- * @param handle - struct vlan_handle used to hold the routing context +- * @return 0 on success, <0 on failure +- */ +-int capture_vlan_table(struct vlan_handle *handle) +-{ +- char *raw = NULL; +- uint32_t raw_size = 0; +- int rc; +- +- rc = capture_file(&raw, &raw_size, proc_vlan_config_path); +- if (rc != 0) +- goto error; +- +- rc = parse_vlan_table(handle, raw, raw_size); +- if (rc != 0) +- goto error; +- +-error: +- if (raw != NULL) +- free(raw); +- +- return rc; +-} +- +-/** +- * release_vlan_table() - This function will free all resources used by +- * the handle +- * @param handle - struct vlan_handle used to hold the routing context +- */ +-void release_vlan_table(struct vlan_handle *handle) +-{ +- if (handle->entries != NULL) { +- free(handle->entries); +- handle->entries = NULL; +- } +- +- handle->num_of_entries = 0; +-} +- +-/** +- * find_phy_using_vlan_interface() - Given the interface name determine VLAN +- * tag ID to match either the physical or VLAN interface name +- * @param vlan_iface_name - VLAN interface used to find the physical +- * interface +- * @param phy_iface_name - returned value is the physical interface name +- * @param vlan_id - returned value is the VLAN id +- * @return 1 is returned if the interface is a VLAN, 0 if the interface is not +- * <0 is returned if there is an error +- */ +-int find_phy_using_vlan_interface(struct vlan_handle *handle, +- char *vlan_iface_name, +- char **phy_iface_name, uint16_t *vlan_id) +-{ +- int i, rc = 0; +- +- for (i = 0; i < handle->num_of_entries; i++) { +- struct vlan_entry *entry = &handle->entries[i]; +- +- /* Compare VLAN interface names to find a match */ +- if (strcmp(entry->vlan_iface_name, vlan_iface_name) == 0) { +- *phy_iface_name = entry->phy_iface_name; +- *vlan_id = entry->vlan_id; +- rc = 1; +- break; +- } +- } +- +- return rc; +-} +- +-/** +- * find_vlans_using_phy_interface() - Given the physical interface name this +- * function will determine the VLAN interface name and VLAN ID +- * @param iface_name - physical interface used to find the vlan interface +- * @param vlan_iface_name - returned value is the VLAN interface name +- * @return The number of VLAN interfaces found +- */ +-int find_vlans_using_phy_interface(struct vlan_handle *handle, +- struct vlan_found_handle *found_handle, +- char *phy_iface_name) +-{ +- int i, num_found = 0; +- +- for (i = 0; i < handle->num_of_entries; i++) { +- struct vlan_entry *entry = &handle->entries[i]; +- +- /* Compare interface names to find a match */ +- if (strcmp(entry->phy_iface_name, phy_iface_name) == 0) { +- found_handle->entries[i].found = VLAN_ENTRY_FOUND; +- num_found++; +- } +- } +- +- return num_found; +-} +- +-/** +- * valid_vlan() - determine if the vlan value which is passed is valid +- * @param vlan - vlan value to test +- * @return 0 - not valid, 1 - valid +- */ +-int valid_vlan(short int vlan) +-{ +- /* Allow vlan 1 to connect */ +- if (vlan > 0 && vlan < 4095) +- return 1; +- +- return 0; +-} +diff --git a/iscsiuio/src/unix/nic_vlan.h b/iscsiuio/src/unix/nic_vlan.h +deleted file mode 100644 +index 610f721..0000000 +--- a/iscsiuio/src/unix/nic_vlan.h ++++ /dev/null +@@ -1,89 +0,0 @@ +-/* +- * Copyright (c) 2009-2011, Broadcom Corporation +- * Copyright (c) 2014, QLogic Corporation +- * +- * Written by: Benjamin Li (benli@broadcom.com) +- * +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. All advertising materials mentioning features or use of this software +- * must display the following acknowledgement: +- * This product includes software developed by Adam Dunkels. +- * 4. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * nic_vlan.h - uIP user space stack VLAN utilities +- * +- */ +-#ifndef __NIC_VLAN_H__ +-#define __NIC_VLAN_H__ +- +-#include +- +-/* Used to hold entries in the vlan table */ +-struct vlan_entry { +- char vlan_iface_name[16]; +- char phy_iface_name[16]; +- uint16_t vlan_id; +-}; +- +-struct vlan_handle { +- struct vlan_entry *entries; +- uint32_t num_of_entries; +- +- uint32_t outstanding_found_handles; +-}; +- +-struct vlan_found_entry { +-#define VLAN_ENTRY_FOUND 1 +-#define VLAN_ENTRY_NOT_FOUND 0 +- uint8_t found; +-}; +- +-struct vlan_found_handle { +- struct vlan_handle *handle; +- uint32_t num_of_entries; +- struct vlan_found_entry *entries; +-}; +- +-/******************************************************************************* +- * Function Prototypes +- ******************************************************************************/ +-void init_vlan_table(struct vlan_handle *handle); +-int capture_vlan_table(struct vlan_handle *handle); +-void release_vlan_table(struct vlan_handle *handle); +- +-int find_phy_using_vlan_interface(struct vlan_handle *handle, +- char *vlan_iface_name, +- char **phy_iface_name, uint16_t *vlan_id); +-int find_vlans_using_phy_interface(struct vlan_handle *handle, +- struct vlan_found_handle *found_handle, +- char *phy_iface_name); +- +-int init_vlan_found_handle(struct vlan_found_handle *found_handle, +- struct vlan_handle *handle); +-void release_vlan_found_handle(struct vlan_found_handle *found_handle); +- +-int valid_vlan(short int vlan); +-#endif /* __NIC_VLAN_H__ */ +diff --git a/iscsiuio/src/unix/options.h b/iscsiuio/src/unix/options.h +deleted file mode 100644 +index 63b8635..0000000 +--- a/iscsiuio/src/unix/options.h ++++ /dev/null +@@ -1,118 +0,0 @@ +-/* +- * Copyright (c) 2009-2011, Broadcom Corporation +- * Copyright (c) 2014, QLogic Corporation +- * +- * Written by: Benjamin Li (benli@broadcom.com) +- * +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. All advertising materials mentioning features or use of this software +- * must display the following acknowledgement: +- * This product includes software developed by Adam Dunkels. +- * 4. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * options.h - CNIC UIO uIP user space stack +- * +- */ +-#ifndef __OPTIONS_H__ +-#define __OPTIONS_H__ +- +-#include +-#include +-#include +- +-/****************************************************************************** +- * Constants which are tuned at compile time by the user +- *****************************************************************************/ +- +-/** +- * MAX_COUNT_NIC_NL_RESP - This is the maximum number of polls uIP will +- * try for a kernel response after a PATH_REQ +- */ +-#define MAX_COUNT_NIC_NL_RESP 128 +- +-/** +- * NLM_BUF_DEFAULT_MAX - This is the buffer size allocated for the send/receive +- * buffers used by the uIP Netlink subsystem. This +- * value is in bytes. +- */ +-#define NLM_BUF_DEFAULT_MAX 8192 /* bytes */ +- +-/****************************************************************************** +- * Non adjustable constants +- *****************************************************************************/ +-#ifndef ETHERTYPE_IP +-#define ETHERTYPE_IP 0x0800 /* IP */ +-#endif /* ETHERTYPE_IP */ +- +-#ifndef ETHERTYPE_IPV6 +-#define ETHERTYPE_IPV6 0x86dd /* IP protocol version 6 */ +-#endif /* ETHERTYPE_IPV6 */ +- +-#ifndef ETHERTYPE_ARP +-#define ETHERTYPE_ARP 0x0806 /* Address resolution */ +-#endif /* ETHERTYPE_ARP */ +- +-#ifndef ETHERTYPE_VLAN +-#define ETHERTYPE_VLAN 0x8100 /* IEEE 802.1Q VLAN tagging */ +-#endif /* ETHERTYPE_VLAN */ +- +-#define APP_NAME "iscsiuio" +-/* BUILD_DATE is automatically generated from the Makefile */ +- +-#define DEBUG_OFF 0x1 +-#define DEBUG_ON 0x2 +- +-#define INVALID_FD -1 +-#define INVALID_THREAD -1 +-#define INVALID_HOST_NO -1 +- +-struct options { +- char debug; +- +- /* Time the userspace daemon was started */ +- time_t start_time; +-}; +- +-extern int event_loop_stop; +-extern struct options opt; +- +-#ifdef WORDS_BIGENDIAN +-#define ntohll(x) (x) +-#define htonll(x) (x) +-#else +-#define ntohll(x) bswap_64(x) +-#define htonll(x) bswap_64(x) +-#endif +- +-# define likely(x) __builtin_expect(!!(x), 1) +-# define unlikely(x) __builtin_expect(!!(x), 0) +- +-/* taken from Linux kernel, include/linux/compiler-gcc.h */ +-/* Optimization barrier */ +-/* The "volatile" is due to gcc bugs */ +-#define barrier() __asm__ __volatile__("": : :"memory") +- +-#endif +diff --git a/iscsiuio/src/unix/packet.c b/iscsiuio/src/unix/packet.c +deleted file mode 100644 +index 3ce2c6b..0000000 +--- a/iscsiuio/src/unix/packet.c ++++ /dev/null +@@ -1,145 +0,0 @@ +-/* +- * Copyright (c) 2009-2011, Broadcom Corporation +- * Copyright (c) 2014, QLogic Corporation +- * +- * Written by: Benjamin Li (benli@broadcom.com) +- * +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. All advertising materials mentioning features or use of this software +- * must display the following acknowledgement: +- * This product includes software developed by Adam Dunkels. +- * 4. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * packet.c - packet management +- * +- */ +-#include +-#include +-#include +- +-#include "logger.h" +-#include "packet.h" +-#include "nic.h" +- +-/** +- * alloc_packet() - Function used to allocate memory for a packet +- * @param max_buf_size - max packet size +- * @param priv_size - size of the assoicated private data +- * @return NULL if failed, on success return a pointer to the packet +- */ +-struct packet *alloc_packet(size_t max_buf_size, size_t priv_size) +-{ +- struct packet *pkt; +- void *priv; +- +- pkt = malloc(max_buf_size + sizeof(struct packet)); +- if (pkt == NULL) { +- LOG_ERR("Could not allocate any memory for packet"); +- return NULL; +- } +- memset(pkt, 0, max_buf_size + sizeof(struct packet)); +- +- priv = malloc(priv_size); +- if (priv == NULL) { +- LOG_ERR("Could not allocate any memory for private structure"); +- goto free_pkt; +- } +- memset(priv, 0, priv_size); +- pkt->max_buf_size = max_buf_size; +- pkt->priv = priv; +- +- return pkt; +- +-free_pkt: +- free(pkt); +- +- return NULL; +-} +- +-void free_packet(struct packet *pkt) +-{ +- if (pkt->priv != NULL) +- free(pkt->priv); +- +- free(pkt); +-} +- +-/** +- * reset_packet() - This will reset the packet fields to default values +- * @param pkt - the packet to reset +- */ +-void reset_packet(packet_t *pkt) +-{ +- pkt->next = NULL; +- +- pkt->flags = 0; +- pkt->vlan_tag = 0; +- +- pkt->buf_size = 0; +- +- pkt->data_link_layer = NULL; +- pkt->network_layer = NULL; +-} +- +-int alloc_free_queue(nic_t *nic, size_t num_of_packets) +-{ +- int i; +- +- pthread_mutex_lock(&nic->free_packet_queue_mutex); +- for (i = 0; i < num_of_packets; i++) { +- packet_t *pkt; +- +- pkt = alloc_packet(STD_MTU_SIZE, STD_MTU_SIZE); +- if (pkt == NULL) { +- goto done; +- } +- +- reset_packet(pkt); +- +- pkt->next = nic->free_packet_queue; +- nic->free_packet_queue = pkt; +- } +- +-done: +- pthread_mutex_unlock(&nic->free_packet_queue_mutex); +- +- return i; +-} +- +-void free_free_queue(nic_t *nic) +-{ +- packet_t *pkt, *pkt_next; +- +- pthread_mutex_lock(&nic->free_packet_queue_mutex); +- pkt = nic->free_packet_queue; +- while (pkt) { +- pkt_next = pkt->next; +- free_packet(pkt); +- pkt = pkt_next; +- } +- nic->free_packet_queue = NULL; +- pthread_mutex_unlock(&nic->free_packet_queue_mutex); +-} +diff --git a/iscsiuio/src/unix/packet.h b/iscsiuio/src/unix/packet.h +deleted file mode 100644 +index 19d1db9..0000000 +--- a/iscsiuio/src/unix/packet.h ++++ /dev/null +@@ -1,78 +0,0 @@ +-/* +- * Copyright (c) 2009-2011, Broadcom Corporation +- * Copyright (c) 2014, QLogic Corporation +- * +- * Written by: Benjamin Li (benli@broadcom.com) +- * +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. All advertising materials mentioning features or use of this software +- * must display the following acknowledgement: +- * This product includes software developed by Adam Dunkels. +- * 4. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * packet.h - packet definitions +- * +- */ +-#include +- +-#ifndef __PACKET_H__ +-#define __PACKET_H__ +- +-#include "nic.h" +- +-#define STD_MTU_SIZE 1500 +- +-struct nic; +-struct nic_interface; +- +-typedef struct packet { +- struct packet *next; +- +- uint32_t flags; +-#define VLAN_TAGGED 0x0001 +- uint16_t vlan_tag; +- +- size_t max_buf_size; +- size_t buf_size; +- +- uint8_t *data_link_layer; +- uint8_t *network_layer; +- +- struct nic *nic; +- struct nic_interface *nic_iface; +- +- void *priv; +- uint8_t buf[]; +-} packet_t; +- +-/****************************************************************************** +- * Packet Function Declarations +- *****************************************************************************/ +-int alloc_free_queue(struct nic *, size_t num_of_packets); +-void free_free_queue(struct nic *); +-void reset_packet(packet_t *pkt); +- +-#endif /* __PACKET_H__ */ +diff --git a/iscsiuio/src/unix/ping.c b/iscsiuio/src/unix/ping.c +deleted file mode 100644 +index 58a6d14..0000000 +--- a/iscsiuio/src/unix/ping.c ++++ /dev/null +@@ -1,518 +0,0 @@ +-/* +- * Copyright (c) 2015, QLogic Corporation +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. All advertising materials mentioning features or use of this software +- * must display the following acknowledgement: +- * This product includes software developed by Adam Dunkels. +- * 4. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * ping.c - Ping implementation for iscsiuio using ICMP/ICMPv6 +- * +- */ +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include "iscsi_if.h" +- +-#include "uip.h" +-#include "uip_arp.h" +-#include "uip_eth.h" +-#include "dhcpc.h" +-#include "ipv6_ndpc.h" +-#include "ipv6.h" +- +-#include "logger.h" +-#include "nic.h" +-#include "nic_utils.h" +-#include "options.h" +-#include "packet.h" +-#include "bnx2.h" +-#include "bnx2x.h" +-#include "cnic.h" +-#include "ping.h" +- +-#define PFX "ping " +- +-static void fill_payload_data(struct uip_stack *ustack) +-{ +- if (ustack->uip_slen) +- memset(ustack->uip_appdata, 'A', ustack->uip_slen); +-} +- +-static int prepare_icmpv4_req_pkt(struct ping_conf *png_c, struct packet *pkt, +- uip_ip4addr_t *dst_addr) +-{ +- nic_interface_t *nic_iface = png_c->nic_iface; +- struct uip_stack *ustack = &nic_iface->ustack; +- struct uip_ipv4_hdr *ipv4_hdr = NULL; +- struct uip_icmpv4_hdr *icmpv4_hdr = NULL; +- u16_t uip_iph_len = 0; +- u16_t icmpv4_hdr_len = 0; +- u16_t uip_ip_icmph_len = 0; +- int mtu = 1500; +- int rc = 0; +- +- uip_iph_len = UIP_IPv4_H_LEN; +- icmpv4_hdr_len = sizeof(*icmpv4_hdr); +- uip_ip_icmph_len = uip_iph_len + icmpv4_hdr_len; +- +- ipv4_hdr = (struct uip_ipv4_hdr *)ustack->network_layer; +- +- icmpv4_hdr = (struct uip_icmpv4_hdr *) (ustack->network_layer + +- sizeof(struct uip_ipv4_hdr)); +- +- /* fill IP header */ +- ipv4_hdr->vhl = 0x45; +- ipv4_hdr->tos = 0; +- ++ustack->ipid; +- ipv4_hdr->ipid[0] = ustack->ipid >> 8; +- ipv4_hdr->ipid[1] = ustack->ipid & 0xff; +- ipv4_hdr->ipoffset[0] = 0; +- ipv4_hdr->ipoffset[1] = 0; +- ipv4_hdr->ttl = UIP_TTL; +- ipv4_hdr->proto = UIP_PROTO_ICMP; +- uip_ip4addr_copy(ipv4_hdr->srcipaddr, ustack->hostaddr); +- uip_ip4addr_copy(ipv4_hdr->destipaddr, dst_addr); +- +- LOG_INFO(PFX "src ipaddr: %d.%d.%d.%d", +- uip_ipaddr1(ipv4_hdr->srcipaddr), +- uip_ipaddr2(ipv4_hdr->srcipaddr), +- uip_ipaddr3(ipv4_hdr->srcipaddr), +- uip_ipaddr4(ipv4_hdr->srcipaddr)); +- +- LOG_INFO(PFX "dest ipaddr: %d.%d.%d.%d", +- uip_ipaddr1(ipv4_hdr->destipaddr), +- uip_ipaddr2(ipv4_hdr->destipaddr), +- uip_ipaddr3(ipv4_hdr->destipaddr), +- uip_ipaddr4(ipv4_hdr->destipaddr)); +- +- /* fill ICMP header */ +- icmpv4_hdr->type = ICMP_ECHO; +- icmpv4_hdr->icode = 0; +- icmpv4_hdr->id = getpid() & 0xffff; +- png_c->id = icmpv4_hdr->id; +- icmpv4_hdr->seqno = ustack->ipid; +- png_c->seqno =icmpv4_hdr->seqno; +- +- /* appdata and sappdata point to the icmp payload */ +- ustack->uip_appdata = ustack->network_layer + uip_ip_icmph_len; +- ustack->uip_sappdata = ustack->uip_appdata; +- +- if (nic_iface->mtu) +- mtu = nic_iface->mtu; +- +- if ((mtu - uip_ip_icmph_len) > png_c->datalen) { +- ustack->uip_slen = png_c->datalen; +- } else { +- png_c->state = ISCSI_PING_OVERSIZE_PACKET; +- LOG_ERR(PFX "MTU=%d, payload=%d\n", +- mtu, png_c->datalen); +- rc = -EINVAL; +- goto done; +- } +- +- fill_payload_data(ustack); +- +- /* Calculate ICMP checksum. */ +- icmpv4_hdr->icmpchksum = 0; +- icmpv4_hdr->icmpchksum = ~(uip_chksum((u16_t *)icmpv4_hdr, +- icmpv4_hdr_len + +- ustack->uip_slen)); +- if (icmpv4_hdr->icmpchksum == 0) +- icmpv4_hdr->icmpchksum = 0xffff; +- +- /* IPv4 total length = IPv4 HLEN + ICMP HLEN + Payload len */ +- ustack->uip_len = uip_ip_icmph_len + ustack->uip_slen; +- ipv4_hdr->len[0] = (ustack->uip_len >> 8); +- ipv4_hdr->len[1] = (ustack->uip_len & 0xff); +- +- /* Calculate IP checksum. */ +- ipv4_hdr->ipchksum = 0; +- ipv4_hdr->ipchksum = ~(uip_ipchksum(ustack)); +- if (ipv4_hdr->ipchksum == 0) +- ipv4_hdr->ipchksum = 0xffff; +- +- ++ustack->stats.ip.sent; +- /* Return and let the caller do the actual transmission. */ +- ustack->uip_flags = 0; +- +-done: +- return rc; +-} +- +-static void prepare_icmpv6_req_pkt(struct ping_conf *png_c, struct packet *pkt, +- uip_ip6addr_t *dst_addr, +- uip_ip6addr_t *src_addr) +-{ +- nic_interface_t *nic_iface = png_c->nic_iface; +- struct uip_stack *ustack = &nic_iface->ustack; +- struct uip_ipv6_hdr *ipv6_hdr = NULL; +- uip_icmp_echo_hdr_t *icmp_echo_hdr = NULL; +- u16_t uip_iph_len = 0; +- u16_t icmp_echo_hdr_len = 0; +- u16_t uip_ip_icmph_len = 0; +- char ipbuf[INET6_ADDRSTRLEN] = {0}; +- +- uip_iph_len = UIP_IPv6_H_LEN; +- icmp_echo_hdr_len = sizeof(*icmp_echo_hdr); +- uip_ip_icmph_len = uip_iph_len + icmp_echo_hdr_len; +- +- ipv6_hdr = (struct uip_ipv6_hdr *)ustack->network_layer; +- +- icmp_echo_hdr = (uip_icmp_echo_hdr_t *) (ustack->network_layer + +- sizeof(struct uip_ipv6_hdr)); +- +- /* fill IPv6 header */ +- ipv6_hdr->vtc = 0x60; +- ipv6_hdr->tcflow = 0; +- ipv6_hdr->flow = 0; +- ipv6_hdr->proto = UIP_PROTO_ICMP6; +- ipv6_hdr->ttl = UIP_TTL; +- uip_ip6addr_copy(ipv6_hdr->srcipaddr, src_addr); +- uip_ip6addr_copy(ipv6_hdr->destipaddr, dst_addr); +- +- memset(ipbuf, 0, sizeof(ipbuf)); +- if (inet_ntop(AF_INET6, &ipv6_hdr->srcipaddr, ipbuf, INET6_ADDRSTRLEN)) +- LOG_INFO(PFX "src ipaddr=%s", ipbuf); +- +- memset(ipbuf, 0, sizeof(ipbuf)); +- if (inet_ntop(AF_INET6, &ipv6_hdr->destipaddr, ipbuf, INET6_ADDRSTRLEN)) +- LOG_INFO(PFX "dest ipaddr=%s", ipbuf); +- +- /* fill ICMP header */ +- icmp_echo_hdr->type = ICMPV6_ECHO_REQ; +- icmp_echo_hdr->icode = 0; +- icmp_echo_hdr->id = HOST_TO_NET16(getpid() & 0xffff); +- png_c->id = icmp_echo_hdr->id; +- ++ustack->ipid; +- icmp_echo_hdr->seqno = HOST_TO_NET16(ustack->ipid); +- png_c->seqno = icmp_echo_hdr->seqno; +- +- /* appdata and sappdata point to the icmp payload */ +- ustack->uip_appdata = ustack->network_layer + uip_ip_icmph_len; +- ustack->uip_sappdata = ustack->uip_appdata; +- ustack->uip_slen = png_c->datalen; +- +- fill_payload_data(ustack); +- +- /* Total length = ETH HLEN + IPv6 HLEN + ICMP HLEN + Data len */ +- ustack->uip_len = UIP_LLH_LEN + uip_ip_icmph_len + ustack->uip_slen; +- /* IPv6 payload len */ +- ipv6_hdr->len = HOST_TO_NET16(icmp_echo_hdr_len + ustack->uip_slen); +- +- /* Calculate ICMP checksum. */ +- icmp_echo_hdr->icmpchksum = 0; +- icmp_echo_hdr->icmpchksum = ~(uip_icmp6chksum(ustack)); +- +- ++ustack->stats.ip.sent; +- /* Return and let the caller do the actual transmission. */ +- ustack->uip_flags = 0; +- return; +-} +- +-static int chk_arp_entry_for_dst_addr(nic_t *nic, nic_interface_t *nic_iface, +- void *addr) +-{ +- struct iscsi_path path; +- uip_ip4addr_t dst_addr4; +- uip_ip6addr_t dst_addr6; +- +- if (nic_iface->protocol == AF_INET) { +- memcpy(dst_addr4, addr, sizeof(uip_ip4addr_t)); +- memcpy(&path.dst.v4_addr, dst_addr4, sizeof(struct in_addr)); +- path.ip_addr_len = 4; +- } else { +- memcpy(dst_addr6, addr, sizeof(uip_ip6addr_t)); +- memcpy(&path.dst.v6_addr, dst_addr6, sizeof(struct in6_addr)); +- path.ip_addr_len = 16; +- } +- +- return cnic_handle_iscsi_path_req(nic, 0, NULL, &path, nic_iface); +-} +- +-static int fill_icmpv6_eth_hdr(struct uip_stack *ustack, +- uip_ip6addr_t *dst_addr6) +-{ +- struct uip_eth_hdr *eth; +- __u8 mac_addr[6]; +- struct ndpc_reqptr req_ptr; +- int rc = 0; +- int ret = 0; +- +- eth = (struct uip_eth_hdr *)ustack->data_link_layer; +- memcpy(eth->src.addr, ustack->uip_ethaddr.addr, sizeof(eth->src.addr)); +- +- memset(mac_addr, 0, sizeof(mac_addr)); +- req_ptr.eth = (void *)mac_addr; +- req_ptr.ipv6 = (void *)dst_addr6; +- +- ret = ndpc_request(ustack, &req_ptr, &rc, CHECK_ARP_TABLE); +- if (ret) { +- LOG_DEBUG(PFX "ndpc request failed"); +- rc = ret; +- } else if (rc) { +- memcpy(eth->dest.addr, mac_addr, sizeof(eth->dest.addr)); +- LOG_DEBUG(PFX "ipv6 arp entry present"); +- rc = 0; +- } else { +- LOG_DEBUG(PFX "ipv6 arp entry not present"); +- rc = -EAGAIN; +- } +- +- return rc; +-} +- +-static int determine_src_ipv6_addr(nic_interface_t *nic_iface, +- uip_ip6addr_t *dst_addr6, +- uip_ip6addr_t *src_addr6) +-{ +- struct in6_addr *addr; +- int rc = 0; +- int ret = 0; +- +- if (nic_iface->ustack.ip_config == IPV6_CONFIG_STATIC) { +- memcpy(src_addr6, &nic_iface->ustack.hostaddr6, +- sizeof(uip_ip6addr_t)); +- goto done; +- } +- +- ret = ndpc_request(&nic_iface->ustack, dst_addr6, +- &rc, CHECK_LINK_LOCAL_ADDR); +- if (ret) { +- LOG_DEBUG(PFX "Check LL failed"); +- rc = ret; +- goto done; +- } +- +- if (rc) { +- LOG_DEBUG(PFX "Use LL"); +- /* Get link local IPv6 address */ +- addr = (struct in6_addr *)&nic_iface->ustack.linklocal6; +- rc = 0; +- } else { +- LOG_DEBUG(PFX "Use Best matched"); +- ret = ndpc_request(&nic_iface->ustack, +- dst_addr6, +- &addr, GET_HOST_ADDR); +- if (ret) { +- LOG_DEBUG(PFX "Use Best matched failed"); +- rc = ret; +- goto done; +- } +- if (addr == NULL) { +- LOG_DEBUG(PFX "No Best matched found"); +- rc = -EINVAL; +- goto done; +- } +- } +- +- /* Got the best matched src IP address */ +- memcpy(src_addr6, addr, sizeof(struct in6_addr)); +- +-done: +- return rc; +-} +- +-void ping_init(struct ping_conf *png_c, void *addr, u16_t type, int datalen) +-{ +- png_c->dst_addr = addr; +- png_c->proto = type; +- png_c->state = PING_INIT_STATE; +- png_c->datalen = datalen; +- return; +-} +- +-int do_ping_from_nic_iface(struct ping_conf *png_c) +-{ +- packet_t *pkt; +- nic_interface_t *nic_iface = png_c->nic_iface; +- nic_t *nic = nic_iface->parent; +- struct uip_stack *ustack = &nic_iface->ustack; +- uip_ip4addr_t dst_addr4; +- uip_ip6addr_t dst_addr6; +- uip_ip6addr_t src_addr6; +- struct timer ping_timer; +- int rc = 0; +- +- memset(dst_addr4, 0, sizeof(uip_ip4addr_t)); +- memset(dst_addr6, 0, sizeof(uip_ip6addr_t)); +- memset(src_addr6, 0, sizeof(uip_ip6addr_t)); +- +- if (nic_iface->protocol == AF_INET) +- memcpy(dst_addr4, png_c->dst_addr, sizeof(uip_ip4addr_t)); +- else +- memcpy(dst_addr6, png_c->dst_addr, sizeof(uip_ip6addr_t)); +- +- rc = chk_arp_entry_for_dst_addr(nic, nic_iface, png_c->dst_addr); +- +- if (rc && (nic_iface->protocol == AF_INET)) { +- png_c->state = ISCSI_PING_NO_ARP_RECEIVED; +- LOG_ERR(PFX "ARP failure for IPv4 dest addr"); +- goto done; +- } else if ((rc < 1) && (nic_iface->protocol == AF_INET6)) { +- png_c->state = ISCSI_PING_NO_ARP_RECEIVED; +- LOG_ERR(PFX "ARP failure for IPv6 dest addr"); +- goto done; +- } else if (rc < 0) { +- LOG_ERR(PFX "ARP failure"); +- goto done; +- } +- +- pthread_mutex_lock(&nic->nic_mutex); +- pkt = get_next_free_packet(nic); +- if (pkt == NULL) { +- pthread_mutex_unlock(&nic->nic_mutex); +- LOG_ERR(PFX "Unable to get a free packet buffer"); +- rc = -EIO; +- goto done; +- } +- +- prepare_ustack(nic, nic_iface, ustack, pkt); +- +- if (nic_iface->protocol == AF_INET) { +- rc = prepare_icmpv4_req_pkt(png_c, pkt, &dst_addr4); +- if (rc) +- goto put_pkt; +- +- /* 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); +- +- LOG_DEBUG(PFX "Send ICMP echo request"); +- (*nic->ops->write) (nic, nic_iface, pkt); +- ustack->uip_len = 0; +- } +- } else { +- rc = determine_src_ipv6_addr(nic_iface, &dst_addr6, &src_addr6); +- if (rc) +- goto put_pkt; +- +- prepare_icmpv6_req_pkt(png_c, pkt, &dst_addr6, &src_addr6); +- +- /* 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); +- rc = fill_icmpv6_eth_hdr(ustack, &dst_addr6); +- if (rc) { +- ustack->uip_len = 0; +- goto put_pkt; +- } +- +- LOG_DEBUG(PFX "Send ICMPv6 echo request"); +- (*nic->ops->write) (nic, nic_iface, pkt); +- ustack->uip_len = 0; +- } +- } +- +-put_pkt: +- put_packet_in_free_queue(pkt, nic); +- pthread_mutex_unlock(&nic->nic_mutex); +- +- if (rc) { +- LOG_DEBUG(PFX "Ping request not transmitted"); +- goto done; +- } +- +- timer_set(&ping_timer, CLOCK_SECOND * 10); +- +- while ((event_loop_stop == 0) && +- (nic->flags & NIC_ENABLED) && !(nic->flags & NIC_GOING_DOWN)) { +- +- rc = nic_process_intr(nic, 1); +- +- while ((rc > 0) && (!(nic->flags & NIC_GOING_DOWN))) { +- rc = process_packets(nic, NULL, NULL, nic_iface); +- } +- +- if (!rc && (png_c->state == ISCSI_PING_SUCCESS)) { +- LOG_INFO(PFX "PING successful!"); +- break; +- } +- +- if (timer_expired(&ping_timer)) { +- png_c->state = ISCSI_PING_TIMEOUT; +- LOG_ERR(PFX "PING timeout"); +- rc = -EIO; +- break; +- } +- } +- +-done: +- return rc; +-} +- +-int process_icmp_packet(uip_icmp_echo_hdr_t *icmp_hdr, +- struct uip_stack *ustack) +-{ +- struct ping_conf *png_c = (struct ping_conf *)ustack->ping_conf; +- int rc = 0; +- +- LOG_INFO(PFX "Verify ICMP echo reply"); +- +- if ((icmp_hdr->type == ICMPV6_ECHO_REPLY && +- png_c->proto == AF_INET6) || +- (icmp_hdr->type == ICMP_ECHO_REPLY && +- png_c->proto == AF_INET)) { +- +- if ((icmp_hdr->icode == 0) && +- (icmp_hdr->id == png_c->id) && +- (icmp_hdr->seqno == png_c->seqno)) { +- png_c->state = ISCSI_PING_SUCCESS; +- } else { +- rc = 1; +- } +- } else { +- rc = 1; +- } +- +- if (rc) { +- LOG_INFO(PFX "ICMP echo reply verification failed!"); +- } else { +- LOG_INFO(PFX "ICMP echo reply OK"); +- } +- +- return rc; +-} +diff --git a/iscsiuio/src/unix/ping.h b/iscsiuio/src/unix/ping.h +deleted file mode 100644 +index 82ace6f..0000000 +--- a/iscsiuio/src/unix/ping.h ++++ /dev/null +@@ -1,73 +0,0 @@ +-/* +- * Copyright (c) 2015, QLogic Corporation +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. All advertising materials mentioning features or use of this software +- * must display the following acknowledgement: +- * This product includes software developed by Adam Dunkels. +- * 4. The name of the author may not be used to endorse or promote +- * products derived from this software without specific prior +- * written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * ping.h - PING header file +- * +- */ +- +-#ifndef __PING_H__ +-#define __PING_H__ +- +-#include "nic_nl.h" +-#include "uip.h" +- +-#define ICMP_ECHO_REPLY 0 +-#define ICMP_ECHO 8 +- +-#define ICMPV6_ECHO_REQ 128 +-#define ICMPV6_ECHO_REPLY 129 +- +-#define DEF_ICMP_PAYLOAD 32 +-#define DEF_ICMPV6_PAYLOAD 16 +- +-#define PING_INIT_STATE (-1) +- +-struct ping_conf +-{ +- nic_t *nic; +- nic_interface_t *nic_iface; +- void *data; +- int state; +- void *dst_addr; +- u16_t proto; +- u16_t id; +- u16_t seqno; +- u16_t datalen; +-}; +- +-void ping_init(struct ping_conf *png_c, void *addr, u16_t type, int datalen); +- +-int do_ping_from_nic_iface(struct ping_conf *png_c); +- +-int process_icmp_packet(uip_icmp_echo_hdr_t *icmp_hdr, +- struct uip_stack *ustack); +- +-#endif /* __PING_H__ */ +diff --git a/iscsiuio/src/unix/uip-conf.h b/iscsiuio/src/unix/uip-conf.h +deleted file mode 100644 +index e6e11a5..0000000 +--- a/iscsiuio/src/unix/uip-conf.h ++++ /dev/null +@@ -1,160 +0,0 @@ +-/** +- * \addtogroup uipopt +- * @{ +- */ +- +-/** +- * \name Project-specific configuration options +- * @{ +- * +- * uIP has a number of configuration options that can be overridden +- * for each project. These are kept in a project-specific uip-conf.h +- * file and all configuration names have the prefix UIP_CONF. +- */ +- +-/* +- * Copyright (c) 2006, Swedish Institute of Computer Science. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. Neither the name of the Institute nor the names of its contributors +- * may be used to endorse or promote products derived from this software +- * without specific prior written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND +- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE +- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +- * SUCH DAMAGE. +- * +- * This file is part of the uIP TCP/IP stack +- * +- */ +- +-/** +- * \file +- * An example uIP configuration file +- * \author +- * Adam Dunkels +- */ +- +-#ifndef __UIP_CONF_H__ +-#define __UIP_CONF_H__ +- +-#include +- +-/** +- * 8 bit datatype +- * +- * This typedef defines the 8-bit type used throughout uIP. +- * +- * \hideinitializer +- */ +-typedef uint8_t u8_t; +- +-/** +- * 16 bit datatype +- * +- * This typedef defines the 16-bit type used throughout uIP. +- * +- * \hideinitializer +- */ +-typedef uint16_t u16_t; +- +-/** +- * 32 bit datatype +- * +- * This typedef defines the 16-bit type used throughout uIP. +- * +- * \hideinitializer +- */ +-typedef uint32_t u32_t; +- +-/** +- * Statistics datatype +- * +- * This typedef defines the dataype used for keeping statistics in +- * uIP. +- * +- * \hideinitializer +- */ +-typedef uint64_t uip_stats_t; +- +-/** +- * Maximum number of TCP connections. +- * +- * \hideinitializer +- */ +-#define UIP_CONF_MAX_CONNECTIONS 40 +- +-/** +- * Maximum number of listening TCP ports. +- * +- * \hideinitializer +- */ +-#define UIP_CONF_MAX_LISTENPORTS 40 +- +-/** +- * uIP buffer size. +- * +- * \hideinitializer +- */ +-#define UIP_CONF_BUFFER_SIZE 420 +- +-/** +- * CPU byte order. +- * +- * \hideinitializer +- */ +-#define UIP_CONF_BYTE_ORDER LITTLE_ENDIAN +- +-/** +- * Logging on or off +- * +- * \hideinitializer +- */ +-#define UIP_CONF_LOGGING 1 +- +-/** +- * UDP support on or off +- * +- * \hideinitializer +- */ +-#define UIP_CONF_UDP 1 +- +-/** +- * UDP checksums on or off +- * +- * \hideinitializer +- */ +-#define UIP_CONF_UDP_CHECKSUMS 1 +- +-/** +- * uIP statistics on or off +- * +- * \hideinitializer +- */ +-#define UIP_CONF_STATISTICS 1 +- +-#define UIP_CONF_IPV6 0 +- +-#define INET_ADDRSTRLEN 16 +-#define INET6_ADDRSTRLEN 46 +- +-#endif /* __UIP_CONF_H__ */ +- +-/** @} */ +-/** @} */ +-- +2.34.1 + diff --git a/0016-Remove-iscsiuio-from-config-and-service-file.patch b/0016-Remove-iscsiuio-from-config-and-service-file.patch new file mode 100644 index 0000000..07a6a87 --- /dev/null +++ b/0016-Remove-iscsiuio-from-config-and-service-file.patch @@ -0,0 +1,52 @@ +From 3ae85fdd120146eb7abcf25bb4588baec85076bf Mon Sep 17 00:00:00 2001 +From: Wenchao Hao +Date: Thu, 27 Jan 2022 10:11:12 +0800 +Subject: [PATCH 3/3] Remove iscsiuio from config and service file + +iscsiuio is to be used in conjunction with specific linux driver to +improve performance, such as QLogic NetXtreme II or QLogic CNIC driver. +It is not a necessary tool of open-iscsi. + +What's more, iscsiuio used a package uio which is out of maintain now, +which would introduce CVEs unhandled. So I want to remove this tool +from open-iscsi. + +This patch removes iscsiuio from config and service file + +Signed-off-by: Wenchao Hao +--- + etc/iscsid.conf | 2 +- + etc/systemd/iscsid.service | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/etc/iscsid.conf b/etc/iscsid.conf +index f21ed3d..8d2808e 100644 +--- a/etc/iscsid.conf ++++ b/etc/iscsid.conf +@@ -19,7 +19,7 @@ + # the time then leave this attribute commented out. + # + # Default for Fedora and RHEL. (uncomment to activate). +-# iscsid.startup = /bin/systemctl start iscsid.socket iscsiuio.socket ++# iscsid.startup = /bin/systemctl start iscsid.socket + # + # Default if you are not using systemd (uncomment to activate) + # iscsid.startup = /usr/bin/service start iscsid +diff --git a/etc/systemd/iscsid.service b/etc/systemd/iscsid.service +index 70c7fbd..49347f5 100644 +--- a/etc/systemd/iscsid.service ++++ b/etc/systemd/iscsid.service +@@ -1,8 +1,8 @@ + [Unit] + Description=Open-iSCSI +-Documentation=man:iscsid(8) man:iscsiuio(8) man:iscsiadm(8) ++Documentation=man:iscsid(8) man:iscsiadm(8) + DefaultDependencies=no +-After=network-online.target iscsiuio.service iscsi-init.service ++After=network-online.target iscsi-init.service + Before=remote-fs-pre.target + Wants=remote-fs-pre.target + +-- +2.34.1 + diff --git a/open-iscsi.spec b/open-iscsi.spec index a23d932..94008cf 100644 --- a/open-iscsi.spec +++ b/open-iscsi.spec @@ -4,7 +4,7 @@ Name: open-iscsi Version: 2.1.5 -Release: 3 +Release: 4 Summary: ISCSI software initiator daemon and utility programs License: GPLv2+ and BSD URL: http://www.open-iscsi.com @@ -22,6 +22,9 @@ patch10: 0010-fix-iscsiadm-op-new-report-to-cannot-rename-error.patch patch11: 0011-Fix-compiler-error-introduced-with-recent-IPv6-commi.patch patch12: 0012-Remove-iscsid.service-s-dependence-of-iscsi-init.ser.patch patch13: 0013-Remove-session-info-password-print.patch +patch14: 0014-Remove-iscsiuio-from-build-and-install-recipe.patch +patch15: 0015-Remove-iscsiuio-source-code.patch +patch16: 0016-Remove-iscsiuio-from-config-and-service-file.patch BuildRequires: flex bison doxygen kmod-devel systemd-units gcc git isns-utils-devel systemd-devel BuildRequires: autoconf automake libtool libmount-devel openssl-devel pkg-config @@ -76,12 +79,6 @@ This contains man files for the using of %{name}. perl -i -pe 's|^exec_prefix = /$|exec_prefix = %{_exec_prefix}|' Makefile %build -cd iscsiuio -touch AUTHORS NEWS -autoreconf --install -%{configure} -cd .. - %make_build OPTFLAGS="%{optflags} %{?__global_ldflags} -DUSE_KMOD -lkmod" LIB_DIR=%{_libdir} @@ -96,7 +93,6 @@ make DESTDIR=%{?buildroot} LIB_DIR=%{_libdir} \ install -pm 755 usr/iscsistart $RPM_BUILD_ROOT%{_sbindir} install -d $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d -install -pm 644 iscsiuio/iscsiuiolog $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d install -d $RPM_BUILD_ROOT%{_sysconfdir}/{iscsi,iscsi/nodes,iscsi/send_targets,iscsi/static,iscsi/isns,iscsi/slp,iscsi/ifaces} install -d $RPM_BUILD_ROOT/var/lock/iscsi touch $RPM_BUILD_ROOT/var/lock/iscsi/lock @@ -143,7 +139,6 @@ fi %dir %{_sysconfdir}/iscsi %attr(0600,root,root) %config(noreplace) %{_sysconfdir}/iscsi/iscsid.conf - %config(noreplace) %{_sysconfdir}/logrotate.d/iscsiuiolog %config %{_sysconfdir}/iscsi/ifaces/iface.example %ghost %{_sysconfdir}/iscsi/initiatorname.iscsi @@ -156,6 +151,9 @@ fi %{_mandir}/man8/* %changelog +* Thu Jan 26 2022 haowenchao - 2.1.5-4 +- Remove tool iscsiuio + * Tue Jan 25 2022 haowenchao - 2.1.5-3 - Remove password print in session info display