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