diff --git a/.gitignore b/.gitignore index 5ae3769..48c1b60 100644 --- a/.gitignore +++ b/.gitignore @@ -1,16 +1,8 @@ -open-iscsi-5.0.4.446.tar.gz -open-iscsi-5.0.5.476.tar.bz2 -open-iscsi-5.0.5.595.tar.bz2 -open-iscsi-6.0.5.595.tar.bz2 -open-iscsi-1.1-645.tar.bz2 -open-iscsi-6.1.1.645.tar.bz2 -open-iscsi-6.1.1.685.tar.bz2 -open-iscsi-6.2.0.695.tar.bz2 -open-iscsi-2.0-754.tar.gz -open-iscsi-2.0-865.2.tar.gz -open-iscsi-2.0-865.13.tar.gz -open-iscsi-2.0-868-test1.tar.gz -open-iscsi-2.0-870-rc1.tar.gz -open-iscsi-2.0-870.1.tar.gz -open-iscsi-2.0-872-rc1-bnx2i.tar.gz -open-iscsi-2.0-872-rc4-bnx2i.tar.gz +/open-iscsi-2.0-870.1.tar.gz +/open-iscsi-2.0-871.1.1-bnx2i.tar.gz +/open-iscsi-2.0-872-rc1.tar.gz +/open-iscsi-2.0-872-rc1-bnx2i.tar.gz +/open-iscsi-2.0-872-rc2-bnx2i.tar.gz +/open-iscsi-2.0-872-rc3.tar.gz +/open-iscsi-2.0-872-rc3-bnx2i.tar.gz +/open-iscsi-2.0-872-rc4-bnx2i.tar.gz diff --git a/iscsi-initiator-utils-Add-Netconfig-support-through-libiscsi.patch b/iscsi-initiator-utils-Add-Netconfig-support-through-libiscsi.patch new file mode 100644 index 0000000..1696d02 --- /dev/null +++ b/iscsi-initiator-utils-Add-Netconfig-support-through-libiscsi.patch @@ -0,0 +1,85 @@ +From e35bdee97477e65866b2c110f0e4b1affe4e983d Mon Sep 17 00:00:00 2001 +From: Harish Zunjarrao +Date: Wed, 12 Oct 2011 19:12:03 +0530 +Subject: [PATCH 1/2] iscsi tools: Add Netconfig support through libiscsi + +Signed-off-by: Harish Zunjarrao +Signed-off-by: Vikas Chaudhary +--- + libiscsi/libiscsi.c | 25 +++++++++++++++++++++++++ + libiscsi/libiscsi.h | 16 ++++++++++++++++ + 2 files changed, 41 insertions(+), 0 deletions(-) + +diff --git a/libiscsi/libiscsi.c b/libiscsi/libiscsi.c +index 42f2e3b..dc63fcd 100644 +--- a/libiscsi/libiscsi.c ++++ b/libiscsi/libiscsi.c +@@ -38,9 +38,13 @@ + #include "fw_context.h" + #include "iscsid_req.h" + #include "iscsi_err.h" ++#include "iscsi_ipc.h" ++#include "transport.h" + + #define CHECK(a) { context->error_str[0] = 0; rc = a; if (rc) goto leave; } + ++extern struct iscsi_ipc *ipc; ++ + /* UGLY, not thread safe :( */ + static int sysfs_initialized = 0; + +@@ -610,3 +614,24 @@ int libiscsi_get_firmware_initiator_name(char *initiatorname) + + return 0; + } ++ ++int libiscsi_set_netconfig(struct libiscsi_context *context, ++ uint32_t host_no, char *transport_name, ++ struct iovec *iovs, int param_count) ++{ ++ struct iscsi_transport *t = NULL; ++ int fd; ++ int rc = 1; ++ ++ t = iscsi_sysfs_get_transport_by_name(transport_name); ++ if (!t) ++ return ENODEV; ++ ++ fd = ipc->ctldev_open(); ++ if (fd < 0) ++ return ENODEV; ++ ++ rc = ipc->set_net_config(t->handle, host_no, iovs, param_count); ++ ipc->ctldev_close(); ++ return rc; ++} +diff --git a/libiscsi/libiscsi.h b/libiscsi/libiscsi.h +index 756590e..61ce0ea 100644 +--- a/libiscsi/libiscsi.h ++++ b/libiscsi/libiscsi.h +@@ -335,6 +335,22 @@ PUBLIC int libiscsi_get_firmware_network_config( + */ + PUBLIC int libiscsi_get_firmware_initiator_name(char *initiatorname); + ++/** \brief Set Network Configuration Settings ++ * ++ * Set Network Configuration Settings ++ * ++ * \param context libiscsi context to operate on. ++ * \param host_no Host number of the port. ++ * \param transport_name Transport Class Name. ++ * \param iovs Pointer to IO Vectors of Netconfig paramaters. ++ * \param param_count Number to IO Vectors. ++ * ++ * \return 0 on success, ENODEV when set netconfig failed. ++ */ ++PUBLIC int libiscsi_set_netconfig(struct libiscsi_context *context, ++ uint32_t host_no, char *transport_name, ++ struct iovec *iovs, int param_count); ++ + #undef PUBLIC + + #ifdef __cplusplus +-- +1.7.1 + diff --git a/iscsi-initiator-utils-ISCSISTART-Bring-up-the-corresponding-network-interf.patch b/iscsi-initiator-utils-ISCSISTART-Bring-up-the-corresponding-network-interf.patch new file mode 100644 index 0000000..75071e2 --- /dev/null +++ b/iscsi-initiator-utils-ISCSISTART-Bring-up-the-corresponding-network-interf.patch @@ -0,0 +1,38 @@ +From 81225b1134210be0a58bec6e2532267e42b4ada2 Mon Sep 17 00:00:00 2001 +From: Eddie Wai +Date: Wed, 5 Sep 2012 14:14:20 -0700 +Subject: [PATCH 2/4] ISCSISTART: Bring up the corresponding network interface + for iboot + +This is needed for the iSCSI offload boot. + +Snip from M. Christie: +Note that we must bring up the interface before iface_setup_from_boot_context, +because we will want iscsi_sysfs_get_host_no_from_hwaddress to be able to match +a MAC to a iscsi host. For some bnx2i cards, the card has to be ifupd for the +iscsi interface to have a MAC. If it is not ifupd we have seen MACs with all +zeros or no iscsi_hosts on different cards. + +Signed-off-by: Eddie Wai +--- + usr/iface.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/usr/iface.c b/usr/iface.c +index 4c612af..0f6b6d1 100644 +--- a/usr/iface.c ++++ b/usr/iface.c +@@ -915,6 +915,10 @@ int iface_setup_from_boot_context(struct iface_rec *iface, + transport_name)) + t = iscsi_sysfs_get_transport_by_name(transport_name); + ++ if (net_ifup_netdev(context->iface)) ++ log_warning("Could not bring up netdev %s for boot", ++ context->iface); ++ + hostno = iscsi_sysfs_get_host_no_from_hwaddress(context->mac, + &rc); + if (rc) { +-- +1.7.11.4 + diff --git a/iscsi-initiator-utils-Prep-for-open-iscsi-2.0.873-release.patch b/iscsi-initiator-utils-Prep-for-open-iscsi-2.0.873-release.patch new file mode 100644 index 0000000..ddbe5bc --- /dev/null +++ b/iscsi-initiator-utils-Prep-for-open-iscsi-2.0.873-release.patch @@ -0,0 +1,359 @@ +From ba0a0bccb38dfb443c24a1090dc6c18c9b1d2939 Mon Sep 17 00:00:00 2001 +From: Mike Christie +Date: Sun, 20 May 2012 19:59:24 -0500 +Subject: [PATCH] Prep for open-iscsi-2.0.873 release + +Update Changelog, README and version.h for new release. +--- + Changelog | 252 +++++++++++++++++++++++++++++++++------------------------- + README | 35 +++++--- + usr/version.h | 2 +- + 3 files changed, 171 insertions(+), 118 deletions(-) + +diff --git a/Changelog b/Changelog +index c1df8bd..880ae43 100644 +--- a/Changelog ++++ b/Changelog +@@ -1,114 +1,152 @@ +-open-iscsi-2.0-872 - open-iscsi-2.0.871 ++open-iscsi-2.0-872 - open-iscsi-2.0.873 + +-Avi Kaplan (2): +- Remove unused field iscsi_conn from struct iscsi_sw_tcp_conn +- Change restore_callbacks argument iscsi_sw_tcp_conn to iscsi_conn ++Ales Kozumplik (1): ++ fwparam_sysfs: fix pathname manipulation error in fwparam_sysfs_boot_info. + +-Erez Zilber (1): +- Fix 2.6.14-23_compat.patch to support all RHEL 5.X versions ++Eddie Wai (3): ++ ISCSID: Fixed a race condition in the INVALID_HOST path ++ ISCSID: Fixed iface update for the new iface net config params ++ ISCSIADM: Included the new iface net params to the node creation + +-Hannes Reinecke (2): +- Allow update of discovery records. +- Update 2.6.27_compat.patch for SLES 11 ++Hannes Reinecke (6): ++ iscsid sends SIGTERM to PID 0 ++ iscsid: Implement --no-pid-file ++ Keep startup mode in sync when specified in config file ++ Allow LOCK_DIR to be set via CFLAGS ++ Allow 'onboot' as loginall parameter ++ boot.suse: Update with latest fixes + +-Mike Christie (91): +- Don't kill iscsid if logout from all nodes fail +- iscsid: fix ISCSI_ERR_INVALID_HOST err handling +- iscsid: add flag to indicate if driver needs iscsid to set ip +- iscsid: add be2iscsi template +- iscsid be2iscsi: add more driver limits +- iscsid: start iscsid automatically when needed +- iscsid: fix segfault during session sync up +- iscsiadm: fix discovery record use +- iscsi mod: sync to linux-2.6-iscsi tree's 2.6.33 feature window patches +- iscsid: handle new replacement_timeout values +- iscsi tools: support tgt reset timeout +- iscsi-iname: fix misleading help description +- iscsid: fix iferror log message +- iscsi mod: Update 2.6.14-23_compat.patch patch +- iscsiadm: fix login/logout message +- do not use a semarg in shared-mem for semop calls +- Fix wrong logs in log.c +- update 2.6.26 compat patch +- iscsi tools: Allow empty username for CHAP +- iscsi ibft/boot: fix net dev loopup +- iscsistart option to bring up NICs using configuration in iBFT. +- ibft boot: mv setup nics to fw_entry.c so iscsiadm can use it +- iscsistart ibft: fix fwparam network cmd +- iscsid be2iscsi: don't set set_host_ip +- iscsi tools: merge functions to get net iface name from mac address +- ibft boot: do not setup nic if offload can be used +- iscsistart ibft boot: setup iscsi offload during boot +- ibft boot: remove be2iscsi +- iscsi tools: idbm/fw function cleanup +- iscsi tool: trivial fixes +- ibft boot: add offload ibft support to iscsiadm +- iscsiadm: only do auto iface setup when iface mode is run +- ibft boot: add iscsiadm offload ibft rec support +- doc: add iscsistart man page +- doc: add iscsi-iname man page +- ibft boot: fix dev to iface matching +- offload boot: turn off +- iscsi tools: nic setup cleanup +- iscsi tools: fix compile errors +- iscsi kern: fix 2.6.27 compat patch +- iscsiadm: add nonpersistent mode to discovery mode +- iscsi tool: mv idbm_node_setup_defaults to idbm.c +- iscsi tools: cleanup get_global_string_param use +- iscsi tools: make config file parser a little smarter. +- iscsiadm: mv session management functions to new file +- st discovery: fix reopen max handling +- iscsid: have iscsid watch for new portals using sendtargets +- iscsi tools: mv iscsid request helpers to its own file +- iscsi tools: add str prefix to strings.c functions +- iscsi tools: use open-isns services +- iscsi tools: add MaxXmitDataSegmentLength param +- iscsi tools: do not exit on mem alloc failures during discovery +- Fix makefile cleanup +- iscsid: add isns discovery daemon and SCN support +- iscsid: support discovery daemon auto logout +- isns: fix compilation +- iscsi tools: fix null sysfs string handling +- iscsi tools: fix compilation on s390 +- Update version number to 872 +- iscsi tools: fix MaxXmitDataSegmentLength=0 handling +- be2iscsi iscsi tool: fix MaxXmitDataSegmentLength handling +- iscsi tools: be2iscsi: fix initial_r2t_en handling +- iscsi tools: prep for userspace libiscsi +- iscsi tools: add log_info helper +- iscsi tools: fix port handling for iscsiadm commands +- iscsi tools: fix port handling for iscsiadm commands take 2 +- iscsid: fix discoveryd shutdown +- iscsi scripts: use iscsiadm -k to shutdown daemon +- iscsiadm: fix discovery record management +- iscsid: fix sendtargets discovery daemon CHAP handling +- iscsiadm: mv disc code to new function +- iscsiadm: fix disc port handling +- iscsiadm: add new discovery mode +- iscsiadm: add isns db support +- iscsiadm: cleanup default port handling +- iscsid: use isns discovery rec for isns discoveryd setttings +- iscsiadm: fix iface mode ENODEV handling +- iscsiadm: mark discovery mode as depreciated +- sync to upstream +- 2.6.33 - 34 kernel compat patch +- 2.6.28 - 32 kernel compat patch +- 2.6.27 kernel compat patch +- 2.6.26 kernel compat patch +- 2.6.24 - 25 kernel compat patch +- 2.6.14 - 23 kernel compat patch +- iscsiadm: fix discovery2 db op return value +- iscsiadm: print isns recs in discovery mode +- iscsi boot: add support for iscsi boot sysfs module +- iscsiadm: rename discovery2 mode as discoverydb +- iscsiadm: fix boot code compile error +- iscsiadm: fix iface update/delete return value fix ++Jim Ramsay (12): ++ Add specific session information to session_rec_t ++ Add support for multiple sessions per iface to iscsid ++ Add multiple sessions per iface commandline syntax ++ Add new node.session.nr_sessions config parameter ++ Implement leading-login support ++ Fix dcb_app.c compile error with old kernels ++ Check all ifaces during discovery even if some timeout ++ iscsid: In foreground mode, treat SIGINT like SIGTERM ++ Revise bind_conn_to_iface logic ++ iscsi tools: Fix warnings reported by gcc-4.5.2 ++ fwparam_ibft: Fix warnings reported by gcc-4.5.2 ++ open-isns: Fix warnings reported by gcc-4.5.2 + +-Ritesh Raj Sarraf (3): +- fix some spelling errors reported by lintian +- minor manpage updates +- Fix CVE-2009-1297 ++Karen Xie (1): ++ open-iscsi: add transport cxgb4i + +-Wulf C. Krueger (1): +- Use DESTDIR when generating an InitiatorName. ++Lalit Chandivade (2): ++ iscsiadm: add netconfig support ++ iscsi tools: manage qla4xxx iscsi sessions with iscsiadm ++ ++Manish Rangankar (1): ++ iscsid: Fixed iscsid restart issue for offload iSCSI login ++ ++Mark Rustad (7): ++ Add some consts to char * parameters that are not changed ++ Add dcb_app.h for DCB support ++ Add dcb_app.c for DCB support ++ Add initial DCB support ++ iscsid: Fix netdev check ++ Remove redundant initialization ++ iscsid: Add IEEE DCB support ++ ++Mike Christie (86): ++ iscsid: remove bogus debug log msg in isns_disc_new_portals ++ isns: Fix endless loop when pollhup is returned ++ iscsi tools: fix multi pdu sendtargets discovery sequences ++ iscsi boot: fix iscsi_boot sysfs parsing ++ Use pass through interface for sendtargets (take4) Currenly offload cards like bnx2i, be2iscsi, cxgb3i must use a normal eth for discovery. This patch allows us to do discovery using the iscsi class passthrough interface. ++ Add userspace/tools iscsi error code defs ++ iscsi tools: fix iscsiadm exit codes ++ iscsid: modify data drop ++ iscsi doc: document iscsiadm host argument ++ iscsid: add new auth error code ++ iscsi tools: convert discovery code to iscsi error codes ++ iscsi tools: document iface rp_filter use ++ iscsi tools: disable isns dsa code ++ iscsi tools: support hostnames in node mode ++ iscsi tools: fix discovery return code ++ iscsiadm: fix offload discovery retry ++ iscsid: fix signal handler debug msg ++ iscsiadm: fix discovery exit code ++ iscsi tools: fix dcbnl.h compile error ++ iscsid: retry initial connect ++ iscsi tools/kernel: switch make defaults ++ iscsi tools: fix comment about sysfs lookup failures ++ iscsi tools: fix netlink bug allocation ++ iscsi tools: Don't try to bind offload EPs to sockets ++ iscsi tools: fix oom_adj use ++ iscsi tools: fix bnx2i boot due to MAC mismatch ++ iscsiadm: fix discoverydb help ++ Update SUSE init script ++ iscsi tools: revert commit c440cbe7ba2464f8baadedb55b00754c36773c2c ++ Add a TODO ++ TODO: mark down Jose as working on idr ++ Update TODO ++ iscsi tools: fix iname sysfs handling ++ iscsi tools: handle compile warnings about unused variables ++ iscsiadm: print kernel iface info ++ iscsi tools: add tgt reset to session info and fix unknown values ++ iscsi tools: fix default iface binding setup ++ iscsi tools: fix iscsiadm return value on failed login ++ iscsi tools: don't build with openssl ++ iscsi tools: check NULL pointer first and add limit check in str_remove_initial ++ iscsi tools: fix README sid lookup info ++ iscsid: print out more informative error string for kernel errors ++ iscsi tools: fix netlink msg setup ++ iscsi tools: fix up vlan support ++ update todo ++ iscsiadm: fix printing of unknown host values ++ Do not run configure for open-isns on every build ++ iscsi tools: fix ipv6 ibft/firmware boot ++ iscsid: don't sync qla4xxx flash sessions ++ iscsid: kill session if already exists. ++ isns: remove rfc files. ++ iscsistart: allow any rec/iscsid.conf setting as arg ++ iscsistart: support params in offload/ibft mode ++ iscsi tools: never use hdr digest with iser ++ iscsi tools: update iscsi_if.h for host event ++ iscsi tools: added ping support ++ iscsi tools: Add support to display a host's CHAP list and delete ++ iscsi tools: fix conn state compilation warnings ++ iscsi tools: allow default to have different transort names ++ iscsiadm: print ping status string ++ iscsi tools: fix hostname with port handling ++ iscsi tools: have iscsid/iscsiadm load modules as needed ++ iscsi tools: have iscsiadm load offload modules ++ init: update red hat init script for module changes ++ iscsi tools: create def ifaces on demand ++ iscsi tools: iscsiadm modprobe support ++ iscsi tools: remove class version check ++ iscsi tools: remove unused len variable ++ iscsiadm: support multiple params in one call ++ iscsid: remove DCB support ++ iscsiadm: print port speed and link state ++ iscsi tools: check for loaded module before loading ++ iscsistart: have iscsistart use same multi param code as iscsiadm ++ iscsi tools: print and load boot transport ++ iscsiadm: load iface before checking for hostno/mac match ++ iscsistart: fix iface overriding ++ iscsiadm: make sure offload drivers are loaded in host mode ++ iscsi tools: have iscsi tools bring up offload net iface ++ iscsi tools: fix bnx2i login ++ iscsi tools: fix ipv6 handling ++ iscsistart: fix invalid param handling ++ iscsiadm: added command line option '--interval' ++ iscsi tools: fix unknown param warnings ++ iscsi tools: fix socket leak in transport probe ++ iscsi tools: remove useless NULL iface check ++ iscsi tools: use strlpy in net code ++ ++Nilesh Javali (1): ++ iscsi tools: update documents for CHAP command ++ ++Rahul Gupta (1): ++ iscsi tools: Displaying timeout and CHAP in iscisadm info ++ ++Vikas Chaudhary (2): ++ iscsi tools: update documents for ping command ++ iscsi tools: remove un-necessary print message ++ ++Wang Sheng-Hui (1): ++ usr/config.h: fix comment for struct iscsi_session_timeout_config + +diff --git a/README b/README +index 0f6293f..3bca590 100644 +--- a/README ++++ b/README +@@ -4,7 +4,7 @@ + + ================================================================= + +- July 1, 2010 ++ May 20, 2012 + Contents + ======== + +@@ -74,29 +74,44 @@ the cache sync command will fail. + - iscsiadm's -P 3 option will not print out scsi devices. + - iscsid will not automatically online devices. + +-By default the kernel source found at ++By default the kernel's iSCSI modules will be used. Running: ++ ++ make ++ make install ++ ++will install the iSCSI tools iscsiadm and iscsid to /sbin. ++ ++For 2.6.14 - 2.6.34 the modules in the kernel dir can built and install ++by running: ++ ++ make kernel ++ ++When building those modules the kernel source found at + /lib/modules/`uname -a`/build + will be used to compile the open-iscsi modules. To specify a different + kernel to build against use: + +- make KSRC= ++ make kernel KSRC= + + or cross-compilation: + +- make KSRC= KARCH="ARCH=um" ++ make kernel KSRC= KARCH="ARCH=um" + + To compile on SUSE Linux you'll have to use + +- make KSRC=/usr/src/linux \ ++ make kernel KSRC=/usr/src/linux \ + KBUILD_OUTPUT=/usr/src/linux-obj// + + where is the kernel configuration to use (eg. 'smp'). + +-For Red Hat/Fedora and Debian distributions open-iscsi can be installed by +-typing "make install". This will copy iscsid and iscsiadm to /usr/sbin, the +-init script to /etc/init.d, and the kernel modules: iscsi_tcp.ko, +-libiscsi_tcp.ko, libiscsi.ko and scsi_transport_iscsi to +-/lib/modules/`uname -r`/kernel/drivers/scsi/ overwriting existing iscsi modules. ++To install the kernel modules that were built run: ++ ++ make install_kernel ++ ++This will copy: iscsi_tcp.ko, libiscsi_tcp.ko, libiscsi.ko and ++scsi_transport_iscsi to ++/lib/modules/`uname -r`/kernel/drivers/scsi/ ++overwriting existing iscsi modules. + + For Debian, be sure to install the linux-headers package that + corresponds to your kernel in order to compile the kernel modules +diff --git a/usr/version.h b/usr/version.h +index 797eca4..a090522 100644 +--- a/usr/version.h ++++ b/usr/version.h +@@ -6,7 +6,7 @@ + * This may not be the same value as the kernel versions because + * some other maintainer could merge a patch without going through us + */ +-#define ISCSI_VERSION_STR "2.0-872" ++#define ISCSI_VERSION_STR "2.0-873" + #define ISCSI_VERSION_FILE "/sys/module/scsi_transport_iscsi/version" + + #endif +-- +1.7.11.7 + diff --git a/iscsi-initiator-utils-add-libiscsi.patch b/iscsi-initiator-utils-add-libiscsi.patch index 4b0e16e..83fb229 100644 --- a/iscsi-initiator-utils-add-libiscsi.patch +++ b/iscsi-initiator-utils-add-libiscsi.patch @@ -1,6 +1,6 @@ -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/libiscsi.c open-iscsi-2.0-872-rc4-bnx2i.build/libiscsi/libiscsi.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/libiscsi.c open-iscsi-2.0-872-rc4-bnx2i.work/libiscsi/libiscsi.c --- open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/libiscsi.c 1969-12-31 18:00:00.000000000 -0600 -+++ open-iscsi-2.0-872-rc4-bnx2i.build/libiscsi/libiscsi.c 2011-08-14 16:53:58.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/libiscsi/libiscsi.c 2012-03-05 23:15:31.000000000 -0600 @@ -0,0 +1,612 @@ +/* + * iSCSI Administration library @@ -614,9 +614,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/libiscsi.c open-iscsi-2.0 + + return 0; +} -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/libiscsi.doxy open-iscsi-2.0-872-rc4-bnx2i.build/libiscsi/libiscsi.doxy +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/libiscsi.doxy open-iscsi-2.0-872-rc4-bnx2i.work/libiscsi/libiscsi.doxy --- open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/libiscsi.doxy 1969-12-31 18:00:00.000000000 -0600 -+++ open-iscsi-2.0-872-rc4-bnx2i.build/libiscsi/libiscsi.doxy 2011-08-14 16:46:24.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/libiscsi/libiscsi.doxy 2012-03-05 23:15:31.000000000 -0600 @@ -0,0 +1,1473 @@ +# Doxyfile 1.5.7.1 + @@ -2091,9 +2091,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/libiscsi.doxy open-iscsi- +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/libiscsi.h open-iscsi-2.0-872-rc4-bnx2i.build/libiscsi/libiscsi.h +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/libiscsi.h open-iscsi-2.0-872-rc4-bnx2i.work/libiscsi/libiscsi.h --- open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/libiscsi.h 1969-12-31 18:00:00.000000000 -0600 -+++ open-iscsi-2.0-872-rc4-bnx2i.build/libiscsi/libiscsi.h 2011-08-14 16:53:58.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/libiscsi/libiscsi.h 2012-03-05 23:15:31.000000000 -0600 @@ -0,0 +1,344 @@ +/* + * iSCSI Administration library @@ -2439,9 +2439,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/libiscsi.h open-iscsi-2.0 +#endif /* __cplusplus */ + +#endif -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/Makefile open-iscsi-2.0-872-rc4-bnx2i.build/libiscsi/Makefile +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/Makefile open-iscsi-2.0-872-rc4-bnx2i.work/libiscsi/Makefile --- open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/Makefile 1969-12-31 18:00:00.000000000 -0600 -+++ open-iscsi-2.0-872-rc4-bnx2i.build/libiscsi/Makefile 2011-08-14 16:46:24.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/libiscsi/Makefile 2012-03-05 23:16:31.000000000 -0600 @@ -0,0 +1,61 @@ +# This Makefile will work only with GNU make. + @@ -2458,7 +2458,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/Makefile open-iscsi-2.0-8 + +COMMON_SRCS = sysdeps.o +# sources shared between iscsid, iscsiadm and iscsistart -+ISCSI_LIB_SRCS = netlink.o transport.o cxgbi.o be2iscsi.o iscsi_timer.o initiator_common.o iscsi_err.o session_info.o iscsi_util.o dcb_app.o io.o auth.o discovery.o login.o log.o md5.o sha1.o iface.o idbm.o sysfs.o iscsi_sysfs.o iscsi_net_util.o iscsid_req.o ++ISCSI_LIB_SRCS = netlink.o transport.o iser.o cxgbi.o be2iscsi.o iscsi_timer.o initiator_common.o iscsi_err.o session_info.o iscsi_util.o dcb_app.o io.o auth.o discovery.o login.o log.o md5.o sha1.o iface.o idbm.o sysfs.o iscsi_sysfs.o iscsi_net_util.o iscsid_req.o +FW_PARAM_SRCS = fw_entry.o prom_lex.o prom_parse.tab.o fwparam_ppc.o fwparam_sysfs.o + +# sources shared with the userspace utils, note we build these separately @@ -2504,9 +2504,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/Makefile open-iscsi-2.0-8 + gcc $(CFLAGS) -M `ls *.c` > .depend + +-include .depend ../usr/.depend -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/pylibiscsi.c open-iscsi-2.0-872-rc4-bnx2i.build/libiscsi/pylibiscsi.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/pylibiscsi.c open-iscsi-2.0-872-rc4-bnx2i.work/libiscsi/pylibiscsi.c --- open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/pylibiscsi.c 1969-12-31 18:00:00.000000000 -0600 -+++ open-iscsi-2.0-872-rc4-bnx2i.build/libiscsi/pylibiscsi.c 2011-08-14 16:53:58.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/libiscsi/pylibiscsi.c 2012-03-05 23:15:31.000000000 -0600 @@ -0,0 +1,638 @@ +/* + * iSCSI Administration library @@ -3146,9 +3146,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/pylibiscsi.c open-iscsi-2 + Py_INCREF(&PyIscsiNode_Type); + PyModule_AddObject(m, "node", (PyObject *) &PyIscsiNode_Type); +} -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/setup.py open-iscsi-2.0-872-rc4-bnx2i.build/libiscsi/setup.py +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/setup.py open-iscsi-2.0-872-rc4-bnx2i.work/libiscsi/setup.py --- open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/setup.py 1969-12-31 18:00:00.000000000 -0600 -+++ open-iscsi-2.0-872-rc4-bnx2i.build/libiscsi/setup.py 2011-08-14 16:46:24.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/libiscsi/setup.py 2012-03-05 23:15:31.000000000 -0600 @@ -0,0 +1,9 @@ +from distutils.core import setup, Extension + @@ -3159,9 +3159,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/setup.py open-iscsi-2.0-8 + +setup (name = 'PyIscsi',version = '1.0', + description = 'libiscsi python bindings', ext_modules = [module1]) -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/tests/test_discovery_firmware.c open-iscsi-2.0-872-rc4-bnx2i.build/libiscsi/tests/test_discovery_firmware.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/tests/test_discovery_firmware.c open-iscsi-2.0-872-rc4-bnx2i.work/libiscsi/tests/test_discovery_firmware.c --- open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/tests/test_discovery_firmware.c 1969-12-31 18:00:00.000000000 -0600 -+++ open-iscsi-2.0-872-rc4-bnx2i.build/libiscsi/tests/test_discovery_firmware.c 2011-08-14 16:46:24.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/libiscsi/tests/test_discovery_firmware.c 2012-03-05 23:15:31.000000000 -0600 @@ -0,0 +1,53 @@ +/* + * iSCSI Administration library @@ -3216,9 +3216,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/tests/test_discovery_firm + + return rc; +} -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/tests/test_discovery_sendtargets.c open-iscsi-2.0-872-rc4-bnx2i.build/libiscsi/tests/test_discovery_sendtargets.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/tests/test_discovery_sendtargets.c open-iscsi-2.0-872-rc4-bnx2i.work/libiscsi/tests/test_discovery_sendtargets.c --- open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/tests/test_discovery_sendtargets.c 1969-12-31 18:00:00.000000000 -0600 -+++ open-iscsi-2.0-872-rc4-bnx2i.build/libiscsi/tests/test_discovery_sendtargets.c 2011-08-14 16:46:24.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/libiscsi/tests/test_discovery_sendtargets.c 2012-03-05 23:15:31.000000000 -0600 @@ -0,0 +1,60 @@ +/* + * iSCSI Administration library @@ -3280,9 +3280,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/tests/test_discovery_send + + return rc; +} -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/tests/test_get_auth.c open-iscsi-2.0-872-rc4-bnx2i.build/libiscsi/tests/test_get_auth.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/tests/test_get_auth.c open-iscsi-2.0-872-rc4-bnx2i.work/libiscsi/tests/test_get_auth.c --- open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/tests/test_get_auth.c 1969-12-31 18:00:00.000000000 -0600 -+++ open-iscsi-2.0-872-rc4-bnx2i.build/libiscsi/tests/test_get_auth.c 2011-08-14 16:46:24.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/libiscsi/tests/test_get_auth.c 2012-03-05 23:15:31.000000000 -0600 @@ -0,0 +1,70 @@ +/* + * iSCSI Administration library @@ -3354,9 +3354,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/tests/test_get_auth.c ope + + return rc; +} -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/tests/test_get_initiator_name.c open-iscsi-2.0-872-rc4-bnx2i.build/libiscsi/tests/test_get_initiator_name.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/tests/test_get_initiator_name.c open-iscsi-2.0-872-rc4-bnx2i.work/libiscsi/tests/test_get_initiator_name.c --- open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/tests/test_get_initiator_name.c 1969-12-31 18:00:00.000000000 -0600 -+++ open-iscsi-2.0-872-rc4-bnx2i.build/libiscsi/tests/test_get_initiator_name.c 2011-08-14 16:46:24.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/libiscsi/tests/test_get_initiator_name.c 2012-03-05 23:15:31.000000000 -0600 @@ -0,0 +1,38 @@ +/* + * iSCSI Administration library @@ -3396,9 +3396,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/tests/test_get_initiator_ + + return 0; +} -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/tests/test_get_network_config.c open-iscsi-2.0-872-rc4-bnx2i.build/libiscsi/tests/test_get_network_config.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/tests/test_get_network_config.c open-iscsi-2.0-872-rc4-bnx2i.work/libiscsi/tests/test_get_network_config.c --- open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/tests/test_get_network_config.c 1969-12-31 18:00:00.000000000 -0600 -+++ open-iscsi-2.0-872-rc4-bnx2i.build/libiscsi/tests/test_get_network_config.c 2011-08-14 16:46:24.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/libiscsi/tests/test_get_network_config.c 2012-03-05 23:15:31.000000000 -0600 @@ -0,0 +1,45 @@ +/* + * iSCSI Administration library @@ -3445,9 +3445,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/tests/test_get_network_co + + return 0; +} -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/tests/test_login.c open-iscsi-2.0-872-rc4-bnx2i.build/libiscsi/tests/test_login.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/tests/test_login.c open-iscsi-2.0-872-rc4-bnx2i.work/libiscsi/tests/test_login.c --- open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/tests/test_login.c 1969-12-31 18:00:00.000000000 -0600 -+++ open-iscsi-2.0-872-rc4-bnx2i.build/libiscsi/tests/test_login.c 2011-08-14 16:46:24.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/libiscsi/tests/test_login.c 2012-03-05 23:15:31.000000000 -0600 @@ -0,0 +1,52 @@ +/* + * iSCSI Administration library @@ -3501,9 +3501,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/tests/test_login.c open-i + + return rc; +} -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/tests/test_logout.c open-iscsi-2.0-872-rc4-bnx2i.build/libiscsi/tests/test_logout.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/tests/test_logout.c open-iscsi-2.0-872-rc4-bnx2i.work/libiscsi/tests/test_logout.c --- open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/tests/test_logout.c 1969-12-31 18:00:00.000000000 -0600 -+++ open-iscsi-2.0-872-rc4-bnx2i.build/libiscsi/tests/test_logout.c 2011-08-14 16:46:24.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/libiscsi/tests/test_logout.c 2012-03-05 23:15:31.000000000 -0600 @@ -0,0 +1,51 @@ +/* + * iSCSI Administration library @@ -3556,9 +3556,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/tests/test_logout.c open- + + return rc; +} -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/tests/test_params.c open-iscsi-2.0-872-rc4-bnx2i.build/libiscsi/tests/test_params.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/tests/test_params.c open-iscsi-2.0-872-rc4-bnx2i.work/libiscsi/tests/test_params.c --- open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/tests/test_params.c 1969-12-31 18:00:00.000000000 -0600 -+++ open-iscsi-2.0-872-rc4-bnx2i.build/libiscsi/tests/test_params.c 2011-08-14 16:46:24.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/libiscsi/tests/test_params.c 2012-03-05 23:15:31.000000000 -0600 @@ -0,0 +1,103 @@ +/* + * iSCSI Administration library @@ -3663,9 +3663,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/tests/test_params.c open- + + return rc; +} -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/tests/test_set_auth.c open-iscsi-2.0-872-rc4-bnx2i.build/libiscsi/tests/test_set_auth.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/tests/test_set_auth.c open-iscsi-2.0-872-rc4-bnx2i.work/libiscsi/tests/test_set_auth.c --- open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/tests/test_set_auth.c 1969-12-31 18:00:00.000000000 -0600 -+++ open-iscsi-2.0-872-rc4-bnx2i.build/libiscsi/tests/test_set_auth.c 2011-08-14 16:46:24.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/libiscsi/tests/test_set_auth.c 2012-03-05 23:15:31.000000000 -0600 @@ -0,0 +1,58 @@ +/* + * iSCSI Administration library @@ -3725,10 +3725,10 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/tests/test_set_auth.c ope + + return rc; +} -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/Makefile open-iscsi-2.0-872-rc4-bnx2i.build/Makefile ---- open-iscsi-2.0-872-rc4-bnx2i.base/Makefile 2011-08-14 16:53:01.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.build/Makefile 2011-08-14 16:46:24.000000000 -0500 -@@ -32,6 +32,7 @@ user: ; +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/Makefile open-iscsi-2.0-872-rc4-bnx2i.work/Makefile +--- open-iscsi-2.0-872-rc4-bnx2i.base/Makefile 2012-03-05 23:19:56.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/Makefile 2012-03-05 23:15:31.000000000 -0600 +@@ -32,6 +32,7 @@ user: utils/open-isns/Makefile $(MAKE) -C utils/fwparam_ibft $(MAKE) -C usr $(MAKE) -C utils @@ -3736,7 +3736,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/Makefile open-iscsi-2.0-872-rc4-bn @echo @echo "Compilation complete Output file" @echo "----------------------------------- ----------------" -@@ -53,6 +54,7 @@ kernel: force +@@ -56,6 +57,7 @@ kernel: force force: ; clean: @@ -3744,9 +3744,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/Makefile open-iscsi-2.0-872-rc4-bn $(MAKE) -C utils/sysdeps clean $(MAKE) -C utils/fwparam_ibft clean $(MAKE) -C utils clean -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/usr/discovery.c open-iscsi-2.0-872-rc4-bnx2i.build/usr/discovery.c ---- open-iscsi-2.0-872-rc4-bnx2i.base/usr/discovery.c 2011-08-14 16:53:01.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.build/usr/discovery.c 2011-08-14 16:46:24.000000000 -0500 +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/usr/discovery.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/discovery.c +--- open-iscsi-2.0-872-rc4-bnx2i.base/usr/discovery.c 2012-03-05 23:19:56.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/discovery.c 2012-03-05 23:15:31.000000000 -0600 @@ -36,6 +36,7 @@ #include "types.h" #include "iscsi_proto.h" @@ -3783,10 +3783,10 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/usr/discovery.c open-iscsi-2.0-872 int discovery_fw(void *data, struct iface_rec *iface, struct list_head *rec_list) -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i.build/usr/idbm.c ---- open-iscsi-2.0-872-rc4-bnx2i.base/usr/idbm.c 2011-08-14 16:53:01.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.build/usr/idbm.c 2011-08-14 16:46:24.000000000 -0500 -@@ -1274,9 +1274,9 @@ int idbm_print_all_discovery(int info_le +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/idbm.c +--- open-iscsi-2.0-872-rc4-bnx2i.base/usr/idbm.c 2012-03-05 23:20:05.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/idbm.c 2012-03-05 23:15:31.000000000 -0600 +@@ -1300,9 +1300,9 @@ int idbm_print_all_discovery(int info_le * fn should return -1 if it skipped the rec, a ISCSI_ERR error code if * the operation failed or 0 if fn was run successfully. */ @@ -3799,9 +3799,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/usr/idbm.c open-iscsi-2.0-872-rc4- { DIR *iface_dirfd; struct dirent *iface_dent; -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/usr/idbm.h open-iscsi-2.0-872-rc4-bnx2i.build/usr/idbm.h ---- open-iscsi-2.0-872-rc4-bnx2i.base/usr/idbm.h 2011-08-14 16:53:01.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.build/usr/idbm.h 2011-08-14 16:46:24.000000000 -0500 +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/usr/idbm.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/idbm.h +--- open-iscsi-2.0-872-rc4-bnx2i.base/usr/idbm.h 2012-03-05 23:20:05.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/idbm.h 2012-03-05 23:15:31.000000000 -0600 @@ -98,6 +98,9 @@ struct rec_op_data { node_rec_t *match_rec; idbm_iface_op_fn *fn; @@ -3812,9 +3812,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/usr/idbm.h open-iscsi-2.0-872-rc4- extern int idbm_for_each_portal(int *found, void *data, idbm_portal_op_fn *fn, char *targetname); extern int idbm_for_each_node(int *found, void *data, -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/usr/iscsi_ipc.h open-iscsi-2.0-872-rc4-bnx2i.build/usr/iscsi_ipc.h ---- open-iscsi-2.0-872-rc4-bnx2i.base/usr/iscsi_ipc.h 2011-08-14 16:53:01.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.build/usr/iscsi_ipc.h 2011-08-14 16:46:24.000000000 -0500 +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/usr/iscsi_ipc.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_ipc.h +--- open-iscsi-2.0-872-rc4-bnx2i.base/usr/iscsi_ipc.h 2012-03-05 23:19:56.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_ipc.h 2012-03-05 23:15:31.000000000 -0600 @@ -136,4 +136,6 @@ struct iscsi_ipc { int (*recv_conn_state) (struct iscsi_conn *conn, uint32_t *state); }; @@ -3822,9 +3822,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/usr/iscsi_ipc.h open-iscsi-2.0-872 +struct iscsi_ipc *ipc; + #endif /* ISCSI_IPC_H */ -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/usr/Makefile open-iscsi-2.0-872-rc4-bnx2i.build/usr/Makefile ---- open-iscsi-2.0-872-rc4-bnx2i.base/usr/Makefile 2011-08-14 16:53:01.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.build/usr/Makefile 2011-08-14 16:46:24.000000000 -0500 +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/usr/Makefile open-iscsi-2.0-872-rc4-bnx2i.work/usr/Makefile +--- open-iscsi-2.0-872-rc4-bnx2i.base/usr/Makefile 2012-03-05 23:19:56.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/Makefile 2012-03-05 23:15:31.000000000 -0600 @@ -33,7 +33,7 @@ endif OPTFLAGS ?= -O2 -g WARNFLAGS ?= -Wall -Wstrict-prototypes diff --git a/iscsi-initiator-utils-add-rh-ver.patch b/iscsi-initiator-utils-add-rh-ver.patch index 6bdf7fe..2dd36b2 100644 --- a/iscsi-initiator-utils-add-rh-ver.patch +++ b/iscsi-initiator-utils-add-rh-ver.patch @@ -4,8 +4,8 @@ * This may not be the same value as the kernel versions because * some other maintainer could merge a patch without going through us */ --#define ISCSI_VERSION_STR "2.0-872" -+#define ISCSI_VERSION_STR "2.0-872.18.f17" +-#define ISCSI_VERSION_STR "2.0-873" ++#define ISCSI_VERSION_STR "6.2.0-873.2.el6" #define ISCSI_VERSION_FILE "/sys/module/scsi_transport_iscsi/version" #endif diff --git a/iscsi-initiator-utils-iscsid-fix-iscsid-segfault-during-qla4xxx-login.patch b/iscsi-initiator-utils-iscsid-fix-iscsid-segfault-during-qla4xxx-login.patch new file mode 100644 index 0000000..1e47306 --- /dev/null +++ b/iscsi-initiator-utils-iscsid-fix-iscsid-segfault-during-qla4xxx-login.patch @@ -0,0 +1,43 @@ +From bc6380ddce06ae2ce9a5b4f2952879175ba47c06 Mon Sep 17 00:00:00 2001 +From: Mike Christie +Date: Wed, 5 Sep 2012 16:18:16 -0500 +Subject: [PATCH 1/4] iscsid: fix iscsid segfault during qla4xxx login + +If the kernel sends multiple ISCSI_KEVENT_CONN_LOGIN_STATE +events for the same login event iscsid will segault. + +When we get a conn error we will set the r_stage to reopen, then when +session_conn_process_login handles the first login event we set the r_stage +to R_STAGE_NO_CHANGE. But then it looks like if we get a second login event +r_stage is no_change and session_conn_process_login will run again and +call mgmt_ipc_write_rsp on a bad qtask. +--- + usr/initiator.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/usr/initiator.c b/usr/initiator.c +index c9d792e..597e0ff 100644 +--- a/usr/initiator.c ++++ b/usr/initiator.c +@@ -1041,7 +1041,7 @@ static void session_scan_host(struct iscsi_session *session, int hostno, + exit(0); + } else if (pid > 0) { + reap_inc(); +- if (qtask) { ++ if (qtask && qtask->mgmt_ipc_fd >= 0) { + close(qtask->mgmt_ipc_fd); + free(qtask); + } +@@ -1666,6 +1666,9 @@ static void session_conn_process_login(void *data) + if (state == ISCSI_CONN_STATE_FREE) + goto failed_login; + ++ if (conn->state == ISCSI_CONN_STATE_LOGGED_IN) ++ return; ++ + conn->state = ISCSI_CONN_STATE_LOGGED_IN; + /* + * ok we were in_login and now we got the notification that we are +-- +1.7.11.4 + diff --git a/iscsi-initiator-utils-libiscsi-partial-offload-discovery.patch b/iscsi-initiator-utils-libiscsi-partial-offload-discovery.patch new file mode 100644 index 0000000..efbf5c2 --- /dev/null +++ b/iscsi-initiator-utils-libiscsi-partial-offload-discovery.patch @@ -0,0 +1,166 @@ +From c4331b7523afccba5176797901209a9d03afa997 Mon Sep 17 00:00:00 2001 +From: Ales Kozumplik +Date: Thu, 18 Nov 2010 17:13:36 +0100 +Subject: [PATCH] libiscsi: reimplement fw discovery so partial devices are used properly. + +Related: rhbz#442980 +--- + libiscsi/libiscsi.c | 120 ++++++++++++++++++++++++++++++-------------------- + 1 files changed, 72 insertions(+), 48 deletions(-) + +diff --git a/libiscsi/libiscsi.c b/libiscsi/libiscsi.c +index 19eae58..626e67c 100644 +--- a/libiscsi/libiscsi.c ++++ b/libiscsi/libiscsi.c +@@ -93,6 +93,16 @@ void libiscsi_cleanup(struct libiscsi_context *context) + free(context); + } + ++static void free_iface_list(struct list_head *ifaces) ++{ ++ struct iface_rec *iface, *tmp_iface; ++ ++ list_for_each_entry_safe(iface, tmp_iface, ifaces, list) { ++ list_del(&iface->list); ++ free(iface); ++ } ++} ++ + static void free_rec_list(struct list_head *rec_list) + { + struct node_rec *rec, *tmp; +@@ -188,69 +198,83 @@ leave: + int libiscsi_discover_firmware(struct libiscsi_context *context, + int *nr_found, struct libiscsi_node **found_nodes) + { +- struct boot_context fw_entry; +- struct node_rec rec; ++ struct list_head targets, ifaces, rec_list; ++ discovery_rec_t drec; + int rc = 0; + +- if (nr_found) ++ INIT_LIST_HEAD(&targets); ++ INIT_LIST_HEAD(&ifaces); ++ INIT_LIST_HEAD(&rec_list); ++ ++ if (nr_found) { + *nr_found = 0; +- if (found_nodes) ++ } ++ ++ if (found_nodes) { + *found_nodes = NULL; ++ } + +- memset(&fw_entry, 0, sizeof fw_entry); +- rc = fw_get_entry(&fw_entry); ++ rc = fw_get_targets(&targets); + if (rc) { +- strcpy(context->error_str, "Could not read fw values."); ++ log_error("%s: Could not get list of targets from firmware " ++ "(err %d).\n", __func__, rc); + return rc; + } + +- memset(&rec, 0, sizeof rec); +- idbm_node_setup_defaults(&rec); +- +- strlcpy(rec.name, fw_entry.targetname, TARGET_NAME_MAXLEN); +- rec.tpgt = 1; +- strlcpy(rec.conn[0].address, fw_entry.target_ipaddr, NI_MAXHOST); +- rec.conn[0].port = fw_entry.target_port; +- +- iface_setup_defaults(&rec.iface); +- strncpy(rec.iface.iname, fw_entry.initiatorname, +- sizeof(fw_entry.initiatorname)); +- strncpy(rec.session.auth.username, fw_entry.chap_name, +- sizeof(fw_entry.chap_name)); +- strncpy((char *)rec.session.auth.password, fw_entry.chap_password, +- sizeof(fw_entry.chap_password)); +- strncpy(rec.session.auth.username_in, fw_entry.chap_name_in, +- sizeof(fw_entry.chap_name_in)); +- strncpy((char *)rec.session.auth.password_in, +- fw_entry.chap_password_in, +- sizeof(fw_entry.chap_password_in)); +- rec.session.auth.password_length = +- strlen((char *)fw_entry.chap_password); +- rec.session.auth.password_in_length = +- strlen((char *)fw_entry.chap_password_in); +- +- CHECK(idbm_add_node(&rec, NULL, 1 /* overwrite */)) ++ CHECK(iface_create_ifaces_from_boot_contexts(&ifaces, &targets)); ++ ++ memset(&drec, 0, sizeof(drec)); ++ drec.type = DISCOVERY_TYPE_FW; ++ rc = idbm_bind_ifaces_to_nodes(discovery_fw, &drec, &ifaces, &rec_list); ++ if (rc) { ++ log_error("%s: Could not determine target nodes from firmware " ++ "(err %d).\n", __func__, rc); ++ goto leave; ++ } ++ ++ int node_count = 0; ++ struct list_head *pos; ++ list_for_each(pos, &rec_list) { ++ ++node_count; ++ } + +- if (nr_found) +- *nr_found = 1; ++ struct libiscsi_node* new_nodes; ++ /* allocate enough space for all the nodes */ ++ new_nodes = calloc(node_count, sizeof *new_nodes); ++ if (new_nodes == NULL) { ++ rc = ENOMEM; ++ log_error("%s: %s.\n", __func__, strerror(ENOMEM)); ++ goto leave; ++ } ++ ++ struct node_rec *rec; ++ struct libiscsi_node *new_node = new_nodes; ++ /* in one loop, add nodes to idbm and create libiscsi_node entries */ ++ list_for_each_entry(rec, &rec_list, list) { ++ CHECK(idbm_add_node(rec, NULL, 1 /* overwrite */)); ++ ++ strlcpy(new_node->name, rec->name, LIBISCSI_VALUE_MAXLEN); ++ new_node->tpgt = rec->tpgt; ++ strlcpy(new_node->address, rec->conn[0].address, NI_MAXHOST); ++ new_node->port = rec->conn[0].port; ++ ++ ++new_node; ++ } + ++ /* update output parameters */ ++ if (nr_found) { ++ *nr_found = node_count; ++ } + if (found_nodes) { +- *found_nodes = calloc(1, sizeof **found_nodes); +- if (*found_nodes == NULL) { +- snprintf(context->error_str, +- sizeof(context->error_str), strerror(ENOMEM)); +- rc = ENOMEM; +- goto leave; +- } +- strlcpy((*found_nodes)[0].name, rec.name, +- LIBISCSI_VALUE_MAXLEN); +- (*found_nodes)[0].tpgt = rec.tpgt; +- strlcpy((*found_nodes)[0].address, +- rec.conn[0].address, NI_MAXHOST); +- (*found_nodes)[0].port = rec.conn[0].port; ++ *found_nodes = new_nodes; + } + + leave: ++ fw_free_targets(&targets); ++ ++ free_iface_list(&ifaces); ++ free_rec_list(&rec_list); ++ + return rc; + } + +-- +1.7.3.2 + diff --git a/iscsi-initiator-utils-libiscsi-to-support-offload.patch b/iscsi-initiator-utils-libiscsi-to-support-offload.patch new file mode 100644 index 0000000..5d8631f --- /dev/null +++ b/iscsi-initiator-utils-libiscsi-to-support-offload.patch @@ -0,0 +1,237 @@ +From 1971024a7c6c2c2cf848aba93bd85a707875f216 Mon Sep 17 00:00:00 2001 +From: Manish Rangankar +Date: Wed, 12 Oct 2011 18:57:25 +0530 +Subject: [PATCH 2/2] iscsi tools: Modified libisci to support offload. + +For an offload solution like qla4xxx requires to do discovery on per port +basis from application. To do that libiscsi need to be modified to take +iSCSI HW address as a input parameter and find out the current active +iface for a given port. Using this iface we can do discovery to a +given port. + +Signed-off-by: Manish Rangankar +--- + libiscsi/libiscsi.c | 148 +++++++++++++++++++++++++++++++++++++++++++++++++++ + libiscsi/libiscsi.h | 33 +++++++++++ + usr/iface.c | 2 +- + 3 files changed, 182 insertions(+), 1 deletions(-) + +diff --git a/libiscsi/libiscsi.c b/libiscsi/libiscsi.c +index dc63fcd..9b15f01 100644 +--- a/libiscsi/libiscsi.c ++++ b/libiscsi/libiscsi.c +@@ -202,6 +202,154 @@ leave: + return rc; + } + ++static int get_active_ifaces_form_host(struct list_head *ifaces, char *hw_addr, ++ const char *address, int *nr_iface) ++{ ++ int iptype = ISCSI_IFACE_TYPE_IPV4; ++ struct iface_rec *usr_iface, *tmp_iface; ++ struct list_head t_ifaces; ++ int rc = 0; ++ ++ INIT_LIST_HEAD(&t_ifaces); ++ ++ iface_link_ifaces(&t_ifaces); ++ list_for_each_entry_safe(usr_iface, tmp_iface, &t_ifaces, list) { ++ (*nr_iface)++; ++ if (strcmp(usr_iface->hwaddress, hw_addr)) { ++ (*nr_iface)--; ++ list_del(&usr_iface->list); ++ free(usr_iface); ++ } ++ } ++ ++ if (!strstr(address, ".") && strstr(address, ":")) ++ iptype = ISCSI_IFACE_TYPE_IPV6; ++ else if (strstr(address, ".") && !strstr(address, ":")) ++ iptype = ISCSI_IFACE_TYPE_IPV4; ++ ++ list_for_each_entry_safe(usr_iface, tmp_iface, &t_ifaces, list) { ++ if (iptype == ISCSI_IFACE_TYPE_IPV4) { ++ if (strstr(usr_iface->name, "ipv4")) { ++ iface_link(ifaces, usr_iface); ++ goto exit_iface; ++ } ++ } else if (iptype == ISCSI_IFACE_TYPE_IPV6) { ++ if (strstr(usr_iface->name, "ipv6")) { ++ iface_link(ifaces, usr_iface); ++ goto exit_iface; ++ } ++ } ++ } ++ ++exit_iface: ++ free_iface_list(&t_ifaces); ++ return rc; ++} ++ ++int libiscsi_discover_sendtargets_by_hwaddr(struct libiscsi_context *context, ++ const char *address, int port, ++ const struct libiscsi_auth_info *auth_info, char *hw_addr, ++ int *nr_found, struct libiscsi_node **found_nodes) ++{ ++ struct discovery_rec drec; ++ LIST_HEAD(bound_rec_list); ++ struct list_head *ifaces, tmp; ++ struct node_rec *rec; ++ int rc = 0, found = 0, nr_iface = 0; ++ ++ INIT_LIST_HEAD(&bound_rec_list); ++ INIT_LIST_HEAD(&tmp); ++ ++ if (hw_addr == NULL) { ++ strcpy(context->error_str, "Invalid argument"); ++ rc = EINVAL; ++ return rc; ++ } ++ ++ rc = get_active_ifaces_form_host(&tmp, hw_addr, address, ++ &nr_iface); ++ if (rc == EINVAL) { ++ strcpy(context->error_str, "Invalid argument"); ++ return rc; ++ } else if (nr_iface == 0) { ++ strcpy(context->error_str, "No iface record"); ++ return ENODEV; ++ } ++ ifaces = &tmp; ++ ++ if (nr_found) ++ *nr_found = 0; ++ if (found_nodes) ++ *found_nodes = NULL; ++ ++ CHECK(libiscsi_verify_auth_info(context, auth_info)) ++ ++ /* Fill the drec struct with all needed info */ ++ memset(&drec, 0, sizeof drec); ++ idbm_sendtargets_defaults(&drec.u.sendtargets); ++ drec.type = DISCOVERY_TYPE_SENDTARGETS; ++ strlcpy(drec.address, address, sizeof(drec.address)); ++ drec.port = port ? port : ISCSI_LISTEN_PORT; ++ switch (auth_info ? auth_info->method : libiscsi_auth_none) { ++ case libiscsi_auth_chap: ++ drec.u.sendtargets.auth.authmethod = AUTH_METHOD_CHAP; ++ strlcpy(drec.u.sendtargets.auth.username, ++ auth_info->chap.username, AUTH_STR_MAX_LEN); ++ strlcpy((char *)drec.u.sendtargets.auth.password, ++ auth_info->chap.password, AUTH_STR_MAX_LEN); ++ drec.u.sendtargets.auth.password_length = ++ strlen((char *)drec.u.sendtargets.auth.password); ++ strlcpy(drec.u.sendtargets.auth.username_in, ++ auth_info->chap.reverse_username, AUTH_STR_MAX_LEN); ++ strlcpy((char *)drec.u.sendtargets.auth.password_in, ++ auth_info->chap.reverse_password, AUTH_STR_MAX_LEN); ++ drec.u.sendtargets.auth.password_in_length = ++ strlen((char *)drec.u.sendtargets.auth.password_in); ++ break; ++ } ++ ++ CHECK(idbm_add_discovery(&drec)) ++ CHECK(idbm_bind_ifaces_to_nodes(discovery_sendtargets, ++ &drec, ifaces, &bound_rec_list)) ++ ++ /* now add/update records */ ++ list_for_each_entry(rec, &bound_rec_list, list) { ++ CHECK(idbm_add_node(rec, &drec, 1 /* overwrite */)) ++ found++; ++ } ++ ++ if (nr_found) ++ *nr_found = found; ++ ++ if (found_nodes && found) { ++ *found_nodes = calloc(found, sizeof **found_nodes); ++ if (*found_nodes == NULL) { ++ snprintf(context->error_str, ++ sizeof(context->error_str), strerror(ENOMEM)); ++ rc = ENOMEM; ++ goto leave; ++ } ++ found = 0; ++ list_for_each_entry(rec, &bound_rec_list, list) { ++ strlcpy((*found_nodes)[found].name, rec->name, ++ LIBISCSI_VALUE_MAXLEN); ++ (*found_nodes)[found].tpgt = rec->tpgt; ++ strlcpy((*found_nodes)[found].address, ++ rec->conn[0].address, NI_MAXHOST); ++ (*found_nodes)[found].port = rec->conn[0].port; ++ strlcpy((*found_nodes)[found].iface, ++ rec->iface.name, LIBISCSI_VALUE_MAXLEN); ++ found++; ++ } ++ } ++ ++leave: ++ free_iface_list(ifaces); ++ free_rec_list(&bound_rec_list); ++ return rc; ++} ++ ++ + int libiscsi_discover_firmware(struct libiscsi_context *context, + int *nr_found, struct libiscsi_node **found_nodes) + { +diff --git a/libiscsi/libiscsi.h b/libiscsi/libiscsi.h +index 61ce0ea..1d8ae7c 100644 +--- a/libiscsi/libiscsi.h ++++ b/libiscsi/libiscsi.h +@@ -142,6 +142,39 @@ PUBLIC int libiscsi_discover_sendtargets(struct libiscsi_context *context, + const char *address, int port, const struct libiscsi_auth_info *auth_info, + int *nr_found, struct libiscsi_node **found_nodes); + ++/** \brief Discover iSCSI nodes using sendtargets and add them to the node db. ++ * ++ * This function connects to the given address and port and then tries to ++ * discover iSCSI nodes for a given iSCSI port using the sendtargets protocol. ++ * Any found nodes are added to the local iSCSI node database and are returned ++ * in a dynamically allocated array. ++ * ++ * Note that the (optional) authentication info is for authenticating the ++ * discovery, and is not for the found nodes! If the connection(s) to the ++ * node(s) need authentication too, you can set the username / password for ++ * those (which can be different!) using the libiscsi_node_set_auth() function. ++ * ++ * \param context libiscsi context to operate on. ++ * \param address Hostname or IP-address to connect to. ++ * \param port Port to connect to, or 0 for the default port. ++ * \param auth_info Authentication information, or NULL. ++ * \param hw_addr iSCSI iface mac address. ++ * \param nr_found The number of found nodes will be returned ++ * through this pointer if not NULL. ++ * \param found_nodes The address of the dynamically allocated array ++ * of found nodes will be returned through this ++ * pointer if not NULL. The caller must free this ++ * array using free(). ++ * \return 0 on success, otherwise a standard error code ++ * (from errno.h). ++ */ ++PUBLIC int libiscsi_discover_sendtargets_by_hwaddr( ++ struct libiscsi_context *context, ++ const char *address, int port, ++ const struct libiscsi_auth_info *auth_info, ++ char *hw_addr, int *nr_found, ++ struct libiscsi_node **found_nodes); ++ + /** \brief Read iSCSI node info from firmware and add them to the node db. + * + * This function discovers iSCSI nodes using firmware (ppc or ibft). Any found +diff --git a/usr/iface.c b/usr/iface.c +index 9431a97..1531291 100644 +--- a/usr/iface.c ++++ b/usr/iface.c +@@ -789,7 +789,7 @@ int iface_for_each_iface(void *data, int skip_def, int *nr_found, + return err; + } + +-static int iface_link(void *data, struct iface_rec *iface) ++int iface_link(void *data, struct iface_rec *iface) + { + struct list_head *ifaces = data; + struct iface_rec *iface_copy; +-- +1.7.1 + diff --git a/iscsi-initiator-utils-log-login-failed.patch b/iscsi-initiator-utils-log-login-failed.patch new file mode 100644 index 0000000..af7f253 --- /dev/null +++ b/iscsi-initiator-utils-log-login-failed.patch @@ -0,0 +1,138 @@ +diff -aurp open-iscsi-2.0-872-rc4-bnx2i/README open-iscsi-2.0-872-rc4-bnx2i.work/README +--- open-iscsi-2.0-872-rc4-bnx2i/README 2011-01-31 03:10:47.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/README 2011-01-31 06:36:18.000000000 -0600 +@@ -403,8 +403,9 @@ this the following is not needed for sof + Warning!!!!!! + This feature is experimental. The interface may change. When reporting + bugs, if you cannot do a "ping -I ethX target_portal", then check your +-network settings first. If you cannot ping the portal, then you will +-not be able to bind a session to a NIC. ++network settings first. Make sure the rp_filter setting is set to 0 or 2 ++(see Prep section below for more info). If you cannot ping the portal, ++then you will not be able to bind a session to a NIC. + + What is a scsi_host and iface for software, hardware and partial + offload iscsi? +@@ -422,6 +423,32 @@ structure. For each HBA port or for soft + device (ethX) or NIC, that you wish to bind sessions to you must create + a iface config /var/lib/iscsi/ifaces. + ++Prep: ++ ++The iface binding feature requires the sysctl setting ++net.ipv4.conf.default.rp_filter to be set to 0 or 2. This can be set ++in /etc/sysctl.conf by having the line: ++ ++net.ipv4.conf.default.rp_filter = N ++ ++where N is 0 or 2. Note that when setting this you may have to reboot ++the box for the value to take effect. ++ ++ ++rp_filter information from Documentation/networking/ip-sysctl.txt: ++ ++rp_filter - INTEGER ++ 0 - No source validation. ++ 1 - Strict mode as defined in RFC3704 Strict Reverse Path ++ Each incoming packet is tested against the FIB and if the interface ++ is not the best reverse path the packet check will fail. ++ By default failed packets are discarded. ++ 2 - Loose mode as defined in RFC3704 Loose Reverse Path ++ Each incoming packet's source address is also tested against the FIB ++ and if the source address is not reachable via any interface ++ the packet check will fail. ++ ++ + Running: + + # iscsiadm -m iface +diff -aurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/initiator.c +--- open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c 2011-01-31 06:23:53.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/initiator.c 2011-01-31 06:36:18.000000000 -0600 +@@ -670,11 +670,11 @@ session_conn_reopen(iscsi_conn_t *conn, + + static int iscsi_retry_initial_login(struct iscsi_conn *conn) + { ++ struct iscsi_session *session = conn->session; + int initial_login_retry_max; + struct timeval now, timeout, fail_time; + +- initial_login_retry_max = +- conn->session->nrec.session.initial_login_retry_max; ++ initial_login_retry_max = session->nrec.session.initial_login_retry_max; + + memset(&now, 0, sizeof(now)); + memset(&timeout, 0, sizeof(timeout)); +@@ -684,7 +684,7 @@ static int iscsi_retry_initial_login(str + if (gettimeofday(&now, NULL)) { + log_error("Could not get time of day. Dropping down to " + "max retry check.\n"); +- return initial_login_retry_max > conn->session->reopen_cnt; ++ return initial_login_retry_max > session->reopen_cnt; + } + timeradd(&conn->initial_connect_time, &timeout, &fail_time); + +@@ -693,9 +693,13 @@ static int iscsi_retry_initial_login(str + * then it is time to give up + */ + if (timercmp(&now, &fail_time, >)) { +- log_debug(1, "Giving up on initial login attempt after " +- "%u seconds.\n", +- initial_login_retry_max * conn->login_timeout); ++ log_error("Login timed out. Could not login to [target: %s, " ++ "portal: %s,%d] through [iface: %s].", ++ session->nrec.name, ++ session->nrec.conn[conn->id].address, ++ session->nrec.conn[conn->id].port, ++ session->nrec.iface.name); ++ iscsi_warn_on_iface_cfg(&conn->session->nrec); + return 0; + } + +diff -aurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_util.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_util.c +--- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_util.c 2011-01-31 03:10:47.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_util.c 2011-01-31 06:36:18.000000000 -0600 +@@ -259,3 +259,16 @@ int iscsi_match_session(void *data, stru + info->persistent_address, + info->persistent_port, &info->iface); + } ++ ++void iscsi_warn_on_iface_cfg(struct node_rec *rec) ++{ ++ if (strcmp(rec->iface.name, DEFAULT_IFACENAME) && ++ !strcmp(rec->iface.transport_name, DEFAULT_TRANSPORT) && ++ (iface_is_bound_by_hwaddr(&rec->iface) || ++ iface_is_bound_by_netdev(&rec->iface))) ++ log_error("Make sure you can ping the portal with " ++ "'ping -I ethX IP', and try adjusting " ++ "net.ipv4.conf.default.rp_filter to 2 or 0 " ++ "in /etc/sysctl.conf (a reboot may be needed " ++ "after changing the sysctl settings)."); ++} +diff -aurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_util.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_util.h +--- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_util.h 2011-01-31 03:10:47.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_util.h 2011-01-31 06:36:18.000000000 -0600 +@@ -21,4 +21,6 @@ extern int __iscsi_match_session(struct + extern char *strstrip(char *s); + extern char *cfg_get_string_param(char *pathname, const char *key); + ++extern void iscsi_warn_on_iface_cfg(struct node_rec *rec); ++ + #endif +diff -aurp open-iscsi-2.0-872-rc4-bnx2i/usr/session_mgmt.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/session_mgmt.c +--- open-iscsi-2.0-872-rc4-bnx2i/usr/session_mgmt.c 2011-01-31 03:10:47.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/session_mgmt.c 2011-01-31 06:36:18.000000000 -0600 +@@ -42,6 +42,13 @@ static void log_login_msg(struct node_re + rec->name, rec->conn[0].address, + rec->conn[0].port); + iscsi_err_print_msg(rc); ++ ++ /* ++ * If using iface binding with tcp then warn about ++ * change in kernel behavior. ++ */ ++ if (rc == ISCSI_ERR_TRANS_TIMEOUT) ++ iscsi_warn_on_iface_cfg(rec); + } else + log_info("Login to [iface: %s, target: %s, portal: " + "%s,%d] successful.", rec->iface.name, diff --git a/iscsi-initiator-utils-mod-iface-andport-fixes.patch b/iscsi-initiator-utils-mod-iface-andport-fixes.patch new file mode 100644 index 0000000..44f281c --- /dev/null +++ b/iscsi-initiator-utils-mod-iface-andport-fixes.patch @@ -0,0 +1,1706 @@ +diff -aurp open-iscsi-2.0-872-rc4-bnx2i/include/iscsi_if.h open-iscsi-2.0-872-rc4-bnx2i.work/include/iscsi_if.h +--- open-iscsi-2.0-872-rc4-bnx2i/include/iscsi_if.h 2012-04-05 16:03:19.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/include/iscsi_if.h 2012-04-05 16:04:06.000000000 -0500 +@@ -270,7 +270,8 @@ struct iscsi_uevent { + } host_event; + struct msg_ping_comp { + uint32_t host_no; +- uint32_t status; ++ uint32_t status; /* enum ++ * iscsi_ping_status_code */ + uint32_t pid; /* unique ping id associated + with each ping request */ + uint32_t data_size; +@@ -515,6 +516,20 @@ enum iscsi_host_param { + #define ISCSI_HOST_NETDEV_NAME (1ULL << ISCSI_HOST_PARAM_NETDEV_NAME) + #define ISCSI_HOST_IPADDRESS (1ULL << ISCSI_HOST_PARAM_IPADDRESS) + ++/* iSCSI PING status/error code */ ++enum iscsi_ping_status_code { ++ ISCSI_PING_SUCCESS = 0, ++ ISCSI_PING_FW_DISABLED = 0x1, ++ ISCSI_PING_IPADDR_INVALID = 0x2, ++ ISCSI_PING_LINKLOCAL_IPV6_ADDR_INVALID = 0x3, ++ ISCSI_PING_TIMEOUT = 0x4, ++ ISCSI_PING_INVALID_DEST_ADDR = 0x5, ++ ISCSI_PING_OVERSIZE_PACKET = 0x6, ++ ISCSI_PING_ICMP_ERROR = 0x7, ++ ISCSI_PING_MAX_REQ_EXCEEDED = 0x8, ++ ISCSI_PING_NO_ARP_RECEIVED = 0x9, ++}; ++ + #define iscsi_ptr(_handle) ((void*)(unsigned long)_handle) + #define iscsi_handle(_ptr) ((uint64_t)(unsigned long)_ptr) + +diff -aurp open-iscsi-2.0-872-rc4-bnx2i/include/iscsi_net_util.h open-iscsi-2.0-872-rc4-bnx2i.work/include/iscsi_net_util.h +--- open-iscsi-2.0-872-rc4-bnx2i/include/iscsi_net_util.h 2012-04-05 16:03:19.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/include/iscsi_net_util.h 2012-04-05 16:04:06.000000000 -0500 +@@ -7,5 +7,6 @@ extern int net_get_transport_name_from_n + extern int net_get_netdev_from_hwaddress(char *hwaddress, char *netdev); + extern int net_setup_netdev(char *netdev, char *local_ip, char *mask, + char *gateway, char *remote_ip, int needs_bringup); ++extern int net_ifup_netdev(char *netdev); + + #endif +diff -aurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/include/config.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/include/config.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/include/config.h 2012-04-05 16:03:19.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/include/config.h 2012-04-05 16:04:06.000000000 -0500 +@@ -59,6 +59,9 @@ typedef struct iface_rec { + * 1 = enable */ + uint16_t mtu; + uint16_t port; ++ char port_state[ISCSI_MAX_STR_LEN]; ++ char port_speed[ISCSI_MAX_STR_LEN]; ++ + /* + * TODO: we may have to make this bigger and interconnect + * specific for infinniband +diff -aurp open-iscsi-2.0-872-rc4-bnx2i/libiscsi/libiscsi.c open-iscsi-2.0-872-rc4-bnx2i.work/libiscsi/libiscsi.c +--- open-iscsi-2.0-872-rc4-bnx2i/libiscsi/libiscsi.c 2012-04-05 16:03:19.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/libiscsi/libiscsi.c 2012-04-05 16:04:06.000000000 -0500 +@@ -626,12 +626,15 @@ int libiscsi_node_set_parameter(struct l + const char *parameter, const char *value) + { + int nr_found = 0, rc; +- struct db_set_param set_param = { +- .name = (char *)parameter, +- .value = (char *)value, +- }; ++ LIST_HEAD(param_list); ++ struct user_param param; + +- CHECK(idbm_for_each_iface(&nr_found, &set_param, idbm_node_set_param, ++ INIT_LIST_HEAD(¶m.list); ++ param.name = (char *)parameter; ++ param.value = (char *)value; ++ list_add_tail(¶m.list, ¶m_list); ++ ++ CHECK(idbm_for_each_iface(&nr_found, ¶m_list, idbm_node_set_param, + (char *)node->name, node->tpgt, + (char *)node->address, node->port)) + if (nr_found == 0) { +diff -aurp open-iscsi-2.0-872-rc4-bnx2i/usr/config.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/config.h +--- open-iscsi-2.0-872-rc4-bnx2i/usr/config.h 2012-04-05 16:03:19.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/config.h 2012-04-05 16:04:06.000000000 -0500 +@@ -229,6 +229,8 @@ typedef struct iface_rec { + * 1 = enable */ + uint16_t mtu; + uint16_t port; ++ char port_state[ISCSI_MAX_STR_LEN]; ++ char port_speed[ISCSI_MAX_STR_LEN]; + /* + * TODO: we may have to make this bigger and interconnect + * specific for infinniband +diff -aurp open-iscsi-2.0-872-rc4-bnx2i/usr/discovery.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/discovery.c +--- open-iscsi-2.0-872-rc4-bnx2i/usr/discovery.c 2012-04-05 16:03:05.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/discovery.c 2012-04-05 16:04:20.000000000 -0500 +@@ -849,7 +849,7 @@ iscsi_alloc_session(struct iscsi_sendtar + session->isid[4] = 0; + session->isid[5] = 0; + +- if (iface && strlen(iface->iname)) { ++ if (strlen(iface->iname)) { + strcpy(initiator_name, iface->iname); + /* MNC TODO add iface alias */ + } else { +diff -aurp open-iscsi-2.0-872-rc4-bnx2i/usr/host.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/host.c +--- open-iscsi-2.0-872-rc4-bnx2i/usr/host.c 2012-04-05 16:03:19.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/host.c 2012-04-05 16:04:06.000000000 -0500 +@@ -174,6 +174,16 @@ static int print_host_iface(void *data, + iface->ipv6_router); + } + ++ if (!strlen(iface->port_state)) ++ printf("%sPort State: %s\n", prefix, UNKNOWN_VALUE); ++ else ++ printf("%sPort State: %s\n", prefix, iface->port_state); ++ ++ if (!strlen(iface->port_speed)) ++ printf("%sPort Speed: %s\n", prefix, UNKNOWN_VALUE); ++ else ++ printf("%sPort Speed: %s\n", prefix, iface->port_speed); ++ + if (!iface->port) + printf("%sPort: %s\n", prefix, UNKNOWN_VALUE); + else +@@ -285,6 +295,7 @@ int host_info_print(int info_level, uint + break; + } + ++ transport_probe_for_offload(); + err = iscsi_sysfs_for_each_host(&flags, &num_found, + host_info_print_tree); + break; +diff -aurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/idbm.c +--- open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c 2012-04-05 16:03:19.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/idbm.c 2012-04-05 16:04:06.000000000 -0500 +@@ -608,6 +608,7 @@ setup_passwd_len: + for (i=0; i '%s'", name, + info[i].value, value); + /* parse recinfo by type */ +@@ -2358,70 +2359,86 @@ idbm_slp_defaults(struct iscsi_slp_confi + sizeof(struct iscsi_slp_config)); + } + +-int idbm_parse_param(char *param, struct node_rec *rec) ++struct user_param *idbm_alloc_user_param(char *name, char *value) + { +- char *name, *value; +- recinfo_t *info; +- int rc; ++ struct user_param *param; + +- name = param; ++ param = calloc(1, sizeof(*param)); ++ if (!param) ++ return NULL; + +- value = strchr(param, '='); +- if (!value) { +- log_error("Invalid --param %s. Missing setting.\n", param); +- return ISCSI_ERR_INVAL; +- } +- *value = '\0'; +- value++; ++ INIT_LIST_HEAD(¶m->list); + +- info = idbm_recinfo_alloc(MAX_KEYS); +- if (!info) { +- log_error("Could not allocate memory to setup params.\n"); +- return ISCSI_ERR_NOMEM; +- } ++ param->name = strdup(name); ++ if (!param->name) ++ goto free_param; + +- idbm_recinfo_node(rec, info); ++ param->value = strdup(value); ++ if (!param->value) ++ goto free_name; + +- rc = idbm_rec_update_param(info, name, value, 0); +- if (rc) +- log_error("Could not set %s to %s. Check that %s is a " +- "valid parameter.\n", name, value, name); +- free(info); +- return rc; ++ return param; ++ ++free_name: ++ free(param->name); ++free_param: ++ free(param); ++ return NULL; + } + +-int idbm_node_set_param(void *data, node_rec_t *rec) ++int idbm_node_set_rec_from_param(struct list_head *params, node_rec_t *rec, ++ int verify) + { +- struct db_set_param *param = data; ++ struct user_param *param; + recinfo_t *info; + int rc = 0; + ++ if (list_empty(params)) ++ return 0; ++ + info = idbm_recinfo_alloc(MAX_KEYS); + if (!info) + return ISCSI_ERR_NOMEM; + + idbm_recinfo_node(rec, info); + +- rc = idbm_verify_param(info, param->name); +- if (rc) +- goto free_info; +- +- rc = idbm_rec_update_param(info, param->name, param->value, 0); +- if (rc) +- goto free_info; ++ if (verify) { ++ list_for_each_entry(param, params, list) { ++ rc = idbm_verify_param(info, param->name); ++ if (rc) ++ goto free_info; ++ } ++ } + +- rc = idbm_rec_write(rec); +- if (rc) +- goto free_info; ++ list_for_each_entry(param, params, list) { ++ rc = idbm_rec_update_param(info, param->name, param->value, 0); ++ if (rc) { ++ if (rc == ISCSI_ERR_INVAL) ++ log_error("Unknown parameter %s.", param->name); ++ goto free_info; ++ } ++ } + + free_info: + free(info); + return rc; + } + ++int idbm_node_set_param(void *data, node_rec_t *rec) ++{ ++ int rc; ++ ++ rc = idbm_node_set_rec_from_param(data, rec, 1); ++ if (rc) ++ return rc; ++ ++ return idbm_rec_write(rec); ++} ++ + int idbm_discovery_set_param(void *data, discovery_rec_t *rec) + { +- struct db_set_param *param = data; ++ struct list_head *params = data; ++ struct user_param *param; + recinfo_t *info; + int rc = 0; + +@@ -2431,13 +2448,17 @@ int idbm_discovery_set_param(void *data, + + idbm_recinfo_discovery((discovery_rec_t *)rec, info); + +- rc = idbm_verify_param(info, param->name); +- if (rc) +- goto free_info; ++ list_for_each_entry(param, params, list) { ++ rc = idbm_verify_param(info, param->name); ++ if (rc) ++ goto free_info; ++ } + +- rc = idbm_rec_update_param(info, param->name, param->value, 0); +- if (rc) +- goto free_info; ++ list_for_each_entry(param, params, list) { ++ rc = idbm_rec_update_param(info, param->name, param->value, 0); ++ if (rc) ++ goto free_info; ++ } + + rc = idbm_discovery_write((discovery_rec_t *)rec); + if (rc) +diff -aurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/idbm.h +--- open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.h 2012-04-05 16:03:19.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/idbm.h 2012-04-05 16:04:06.000000000 -0500 +@@ -26,6 +26,7 @@ + #include + #include "initiator.h" + #include "config.h" ++#include "list.h" + + #define ISCSIVAR "/var/lib/iscsi/" + +@@ -82,7 +83,9 @@ typedef struct idbm { + discovery_rec_t drec_isns; + recinfo_t dinfo_isns[MAX_KEYS]; + } idbm_t; +-struct db_set_param { ++ ++struct user_param { ++ struct list_head list; + char *name; + char *value; + }; +@@ -145,9 +148,11 @@ extern int idbm_discovery_read(discovery + extern int idbm_rec_read(node_rec_t *out_rec, char *target_name, + int tpgt, char *addr, int port, + struct iface_rec *iface); +-extern int idbm_parse_param(char *param, struct node_rec *rec); ++extern int idbm_node_set_rec_from_param(struct list_head *params, ++ node_rec_t *rec, int verify); + extern int idbm_node_set_param(void *data, node_rec_t *rec); + extern int idbm_discovery_set_param(void *data, discovery_rec_t *rec); ++struct user_param *idbm_alloc_user_param(char *name, char *value); + extern void idbm_node_setup_defaults(node_rec_t *rec); + extern struct node_rec *idbm_find_rec_in_list(struct list_head *rec_list, + char *targetname, char *addr, +diff -aurp open-iscsi-2.0-872-rc4-bnx2i/usr/iface.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/iface.c +--- open-iscsi-2.0-872-rc4-bnx2i/usr/iface.c 2012-04-05 16:03:19.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iface.c 2012-04-05 16:04:06.000000000 -0500 +@@ -169,7 +169,7 @@ free_conf: + int iface_conf_read(struct iface_rec *iface) + { + struct iface_rec *def_iface; +- int rc; ++ int rc, retry = 0; + + def_iface = iface_match_default(iface); + if (def_iface) { +@@ -197,12 +197,24 @@ int iface_conf_read(struct iface_rec *if + return 0; + } + ++retry_read: + rc = idbm_lock(); + if (rc) + return rc; + + rc = __iface_conf_read(iface); + idbm_unlock(); ++ ++ /* ++ * cmd was run before running -m iface, so force def bindings ++ * creation to see if that was the one requested ++ */ ++ if (retry < 1 && rc == ISCSI_ERR_IDBM) { ++ iface_setup_host_bindings(); ++ retry++; ++ goto retry_read; ++ } ++ + return rc; + } + +@@ -277,11 +289,11 @@ free_conf: + return rc; + } + +-int iface_conf_update(struct db_set_param *param, +- struct iface_rec *iface) ++int iface_conf_update(struct list_head *params, struct iface_rec *iface) + { + struct iface_rec *def_iface; + recinfo_t *info; ++ struct user_param *param; + int rc = 0; + + def_iface = iface_match_default(iface); +@@ -296,13 +308,18 @@ int iface_conf_update(struct db_set_para + return ISCSI_ERR_NOMEM; + + idbm_recinfo_iface(iface, info); +- rc = idbm_verify_param(info, param->name); +- if (rc) +- goto free_info; + +- rc = idbm_rec_update_param(info, param->name, param->value, 0); +- if (rc) +- goto free_info; ++ list_for_each_entry(param, params, list) { ++ rc = idbm_verify_param(info, param->name); ++ if (rc) ++ goto free_info; ++ } ++ ++ list_for_each_entry(param, params, list) { ++ rc = idbm_rec_update_param(info, param->name, param->value, 0); ++ if (rc) ++ goto free_info; ++ } + + rc = iface_conf_write(iface); + free_info: +@@ -449,6 +466,7 @@ static int iface_setup_binding_from_kern + { + struct host_info *hinfo = data; + struct iface_rec iface; ++ char iface_path[PATH_MAX]; + + if (!strlen(hinfo->iface.hwaddress)) { + log_error("Invalid offload iSCSI host %u. Missing " +@@ -474,7 +492,11 @@ static int iface_setup_binding_from_kern + hinfo->iface.transport_name, hinfo->iface.hwaddress); + } + +- if (iface_conf_read(&iface)) { ++ memset(iface_path, 0, sizeof(iface_path)); ++ snprintf(iface_path, PATH_MAX, "%s/%s", IFACE_CONFIG_DIR, ++ iface.name); ++ ++ if (access(iface_path, F_OK) != 0) { + /* not found so create it */ + if (iface_conf_write(&iface)) { + log_error("Could not create default iface conf %s.", +@@ -532,6 +554,8 @@ void iface_setup_host_bindings(void) + } + idbm_unlock(); + ++ transport_probe_for_offload(); ++ + if (iscsi_sysfs_for_each_host(NULL, &nr_found, + __iface_setup_host_bindings)) + log_error("Could not scan scsi hosts. HW/OFFLOAD iscsi " +@@ -869,7 +893,8 @@ void iface_link_ifaces(struct list_head + int iface_setup_from_boot_context(struct iface_rec *iface, + struct boot_context *context) + { +- struct iscsi_transport *t; ++ struct iscsi_transport *t = NULL; ++ char transport_name[ISCSI_TRANSPORT_NAME_MAXLEN]; + uint32_t hostno; + int rc; + +@@ -884,6 +909,12 @@ int iface_setup_from_boot_context(struct + return 0; + } + } else if (strlen(context->iface)) { ++ memset(transport_name, 0, ISCSI_TRANSPORT_NAME_MAXLEN); ++ /* make sure offload driver is loaded */ ++ if (!net_get_transport_name_from_netdev(context->iface, ++ transport_name)) ++ t = iscsi_sysfs_get_transport_by_name(transport_name); ++ + hostno = iscsi_sysfs_get_host_no_from_hwaddress(context->mac, + &rc); + if (rc) { +@@ -904,7 +935,8 @@ int iface_setup_from_boot_context(struct + /* + * set up for access through a offload card. + */ +- t = iscsi_sysfs_get_transport_by_hba(hostno); ++ if (!t) ++ t = iscsi_sysfs_get_transport_by_hba(hostno); + if (!t) { + log_error("Could not get transport for host%u. " + "Make sure the iSCSI driver is loaded.", +diff -aurp open-iscsi-2.0-872-rc4-bnx2i/usr/iface.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/iface.h +--- open-iscsi-2.0-872-rc4-bnx2i/usr/iface.h 2012-04-05 16:03:19.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iface.h 2012-04-05 16:04:06.000000000 -0500 +@@ -26,7 +26,6 @@ + + struct iface_rec; + struct list_head; +-struct db_set_param; + struct boot_context; + + extern void iface_copy(struct iface_rec *dst, struct iface_rec *src); +@@ -46,7 +45,7 @@ extern int iface_print_tree(void *data, + extern void iface_setup_host_bindings(void); + extern int iface_get_by_net_binding(struct iface_rec *pattern, + struct iface_rec *out_rec); +-extern int iface_conf_update(struct db_set_param *set_param, ++extern int iface_conf_update(struct list_head *params, + struct iface_rec *iface); + extern int iface_conf_write(struct iface_rec *iface); + extern int iface_conf_delete(struct iface_rec *iface); +diff -aurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator_common.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/initiator_common.c +--- open-iscsi-2.0-872-rc4-bnx2i/usr/initiator_common.c 2012-04-05 16:03:19.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/initiator_common.c 2012-04-05 16:04:06.000000000 -0500 +@@ -35,6 +35,7 @@ + #include "host.h" + #include "sysdeps.h" + #include "iscsi_err.h" ++#include "iscsi_net_util.h" + + struct iscsi_session *session_find_by_sid(uint32_t sid) + { +@@ -596,6 +597,8 @@ int iscsi_host_set_net_params(struct ifa + { + struct iscsi_transport *t = session->t; + int rc = 0; ++ char *netdev; ++ struct host_info hinfo; + + log_debug(3, "setting iface %s, dev %s, set ip %s, hw %s, " + "transport %s.\n", +@@ -612,6 +615,21 @@ int iscsi_host_set_net_params(struct ifa + return EINVAL; + } + ++ /* these type of drivers need the netdev upd */ ++ if (strlen(iface->netdev)) ++ netdev = iface->netdev; ++ else { ++ memset(&hinfo, 0, sizeof(hinfo)); ++ hinfo.host_no = session->hostno; ++ iscsi_sysfs_get_hostinfo_by_host_no(&hinfo); ++ ++ netdev = hinfo.iface.netdev; ++ } ++ ++ if (net_ifup_netdev(netdev)) ++ log_warning("Could not brining up netdev %s. Try running " ++ "'ifup %s' first if login fails.", netdev, netdev); ++ + rc = iscsi_set_net_config(t, session, iface); + if (rc != 0) + return rc; +diff -aurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsiadm.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsiadm.c +--- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsiadm.c 2012-04-05 16:03:19.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsiadm.c 2012-04-05 16:04:06.000000000 -0500 +@@ -110,6 +110,7 @@ static struct option const long_options[ + {"ip", required_argument, NULL, 'a'}, + {"packetsize", required_argument, NULL, 'b'}, + {"count", required_argument, NULL, 'c'}, ++ {"interval", required_argument, NULL, 'i'}, + {NULL, 0, NULL, 0}, + }; + static char *short_options = "RlDVhm:a:b:c:C:p:P:T:H:i:I:U:k:L:d:r:n:v:o:sSt:u"; +@@ -1116,6 +1117,17 @@ do_sendtargets(discovery_rec_t *drec, st + free(iface); + continue; + } ++ /* check for transport name first to make sure it is loaded */ ++ t = iscsi_sysfs_get_transport_by_name(iface->transport_name); ++ if (!t) { ++ log_error("Could not load transport %s." ++ "Dropping interface %s.", ++ iface->transport_name, iface->name); ++ list_del(&iface->list); ++ free(iface); ++ continue; ++ } ++ + host_no = iscsi_sysfs_get_host_no_from_hwinfo(iface, &rc); + if (rc || host_no == -1) { + log_debug(1, "Could not match iface" iface_fmt " to " +@@ -1124,18 +1136,6 @@ do_sendtargets(discovery_rec_t *drec, st + continue; + } + +- t = iscsi_sysfs_get_transport_by_hba(host_no); +- if (!t) { +- log_error("Could not match hostno %d to " +- "transport. Dropping interface %s," +- iface_fmt " ,%s.", +- host_no, iface->transport_name, +- iface_str(iface), iface->ipaddress); +- list_del(&iface->list); +- free(iface); +- continue; +- } +- + if (t->caps & CAP_SENDTARGETS_OFFLOAD) { + do_offload_sendtargets(drec, host_no, do_login); + list_del(&iface->list); +@@ -1346,8 +1346,6 @@ get_chap: + goto exit_chap_info; + } + +- log_info("Valid CHAP Entries = %d\n", valid_chap_entries); +- + crec = (struct iscsi_chap_rec *) (req_buf + + sizeof(struct iscsi_uevent)); + +@@ -1440,13 +1438,45 @@ static int exec_host_chap_op(int op, int + return rc; + } + ++static int verify_iface_params(struct list_head *params, struct node_rec *rec) ++{ ++ struct user_param *param; ++ ++ list_for_each_entry(param, params, list) { ++ if (!strcmp(param->name, IFACE_ISCSINAME)) { ++ log_error("Can not update " ++ "iface.iscsi_ifacename. Delete it, " ++ "and then create a new one."); ++ return ISCSI_ERR_INVAL; ++ } ++ ++ if (iface_is_bound_by_hwaddr(&rec->iface) && ++ !strcmp(param->name, IFACE_NETNAME)) { ++ log_error("Can not update interface binding " ++ "from hwaddress to net_ifacename. " ++ "You must delete the interface and " ++ "create a new one"); ++ return ISCSI_ERR_INVAL; ++ } ++ ++ if (iface_is_bound_by_netdev(&rec->iface) && ++ !strcmp(param->name, IFACE_HWADDR)) { ++ log_error("Can not update interface binding " ++ "from net_ifacename to hwaddress. " ++ "You must delete the interface and " ++ "create a new one"); ++ return ISCSI_ERR_INVAL; ++ } ++ } ++ return 0; ++} ++ + /* TODO: merge iter helpers and clean them up, so we can use them here */ + static int exec_iface_op(int op, int do_show, int info_level, + struct iface_rec *iface, uint32_t host_no, +- char *name, char *value) ++ struct list_head *params) + { + struct host_info hinfo; +- struct db_set_param set_param; + struct node_rec *rec = NULL; + int rc = 0; + +@@ -1502,7 +1532,7 @@ delete_fail: + iscsi_err_to_str(rc)); + break; + case OP_UPDATE: +- if (!iface || !name || !value) { ++ if (!iface || list_empty(params)) { + log_error("Update requires name, value, and iface."); + rc = ISCSI_ERR_INVAL; + break; +@@ -1520,42 +1550,16 @@ delete_fail: + "sessions then log back in for the " + "new settings to take affect."); + +- if (!strcmp(name, IFACE_ISCSINAME)) { +- log_error("Can not update " +- "iface.iscsi_ifacename. Delete it, " +- "and then create a new one."); +- rc = ISCSI_ERR_INVAL; +- break; +- } +- +- if (iface_is_bound_by_hwaddr(&rec->iface) && +- !strcmp(name, IFACE_NETNAME)) { +- log_error("Can not update interface binding " +- "from hwaddress to net_ifacename. "); +- log_error("You must delete the interface and " +- "create a new one"); +- rc = ISCSI_ERR_INVAL; +- break; +- } +- +- if (iface_is_bound_by_netdev(&rec->iface) && +- !strcmp(name, IFACE_HWADDR)) { +- log_error("Can not update interface binding " +- "from net_ifacename to hwaddress. "); +- log_error("You must delete the interface and " +- "create a new one"); +- rc = ISCSI_ERR_INVAL; ++ rc = verify_iface_params(params, rec); ++ if (rc) + break; +- } +- set_param.name = name; +- set_param.value = value; + + /* pass rec's iface because it has the db values */ +- rc = iface_conf_update(&set_param, &rec->iface); ++ rc = iface_conf_update(params, &rec->iface); + if (rc) + goto update_fail; + +- rc = __for_each_matched_rec(0, rec, &set_param, ++ rc = __for_each_matched_rec(0, rec, params, + idbm_node_set_param); + if (rc == ISCSI_ERR_NO_OBJS_FOUND) + rc = 0; +@@ -1638,14 +1642,62 @@ update_fail: + return rc; + } + ++static int verify_node_params(struct list_head *params, struct node_rec *rec) ++{ ++ struct user_param *param; ++ ++ if (list_empty(params)) { ++ log_error("update requires name and value"); ++ return ISCSI_ERR_INVAL; ++ } ++ ++ list_for_each_entry(param, params, list) { ++ /* compat - old tools used node and iface transport name */ ++ if (!strncmp(param->name, "iface.", 6) && ++ strcmp(param->name, "iface.transport_name")) { ++ log_error("Cannot modify %s. Use iface mode to update " ++ "this value.", param->name); ++ return ISCSI_ERR_INVAL; ++ } ++ ++ if (!strcmp(param->name, "node.transport_name")) { ++ free(param->name); ++ param->name = strdup("iface.transport_name"); ++ if (!param->name) { ++ log_error("Could not allocate memory for " ++ "param."); ++ return ISCSI_ERR_NOMEM; ++ } ++ } ++ /* ++ * tmp hack - we added compat crap above for the transport, ++ * but want to fix Doran's issue in this release too. However ++ * his patch is too harsh on many settings and we do not have ++ * time to update apps so we have this tmp hack until we ++ * can settle on a good interface that distros can use ++ * and we can mark stable. ++ */ ++ if (!strcmp(param->name, "iface.transport_name")) { ++ if (iscsi_check_for_running_session(rec)) { ++ log_warning("Cannot modify node/iface " ++ "transport name while a session " ++ "is using it. Log out the session " ++ "then update record."); ++ return ISCSI_ERR_SESS_EXISTS; ++ } ++ } ++ } ++ ++ return 0; ++} ++ + /* TODO cleanup arguments */ + static int exec_node_op(int op, int do_login, int do_logout, + int do_show, int do_rescan, int do_stats, + int info_level, struct node_rec *rec, +- char *name, char *value) ++ struct list_head *params) + { + int rc = 0; +- struct db_set_param set_param; + + if (rec) + log_debug(2, "%s: %s:%s node [%s,%s,%d] sid %u", __FUNCTION__, +@@ -1708,46 +1760,11 @@ static int exec_node_op(int op, int do_l + } + + if (op == OP_UPDATE) { +- if (!name || !value) { +- log_error("update requires name and value"); +- rc = ISCSI_ERR_INVAL; +- goto out; +- } +- +- /* compat - old tools used node and iface transport name */ +- if (!strncmp(name, "iface.", 6) && +- strcmp(name, "iface.transport_name")) { +- log_error("Cannot modify %s. Use iface mode to update " +- "this value.", name); +- rc = ISCSI_ERR_INVAL; ++ rc = verify_node_params(params, rec); ++ if (rc) + goto out; +- } +- +- if (!strcmp(name, "node.transport_name")) +- name = "iface.transport_name"; +- /* +- * tmp hack - we added compat crap above for the transport, +- * but want to fix Doran's issue in this release too. However +- * his patch is too harsh on many settings and we do not have +- * time to update apps so we have this tmp hack until we +- * can settle on a good interface that distros can use +- * and we can mark stable. +- */ +- if (!strcmp(name, "iface.transport_name")) { +- if (iscsi_check_for_running_session(rec)) { +- log_warning("Cannot modify node/iface " +- "transport name while a session " +- "is using it. Log out the session " +- "then update record."); +- rc = ISCSI_ERR_SESS_EXISTS; +- goto out; +- } +- } + +- set_param.name = name; +- set_param.value = value; +- +- rc = for_each_matched_rec(rec, &set_param, idbm_node_set_param); ++ rc = for_each_matched_rec(rec, params, idbm_node_set_param); + goto out; + } else if (op == OP_DELETE) { + rc = for_each_matched_rec(rec, NULL, delete_node); +@@ -2002,7 +2019,7 @@ static int exec_discover(int disc_type, + + static int exec_disc2_op(int disc_type, char *ip, int port, + struct list_head *ifaces, int info_level, int do_login, +- int do_discover, int op, char *name, char *value, ++ int do_discover, int op, struct list_head *params, + int do_show) + { + struct discovery_rec drec; +@@ -2081,16 +2098,12 @@ do_db_op: + if (rc) + log_error("Unable to delete record!"); + } else if (op == OP_UPDATE) { +- struct db_set_param set_param; +- +- if (!name || !value) { ++ if (list_empty(params)) { + log_error("Update requires name and value."); + rc = ISCSI_ERR_INVAL; + goto done; + } +- set_param.name = name; +- set_param.value = value; +- rc = idbm_discovery_set_param(&set_param, &drec); ++ rc = idbm_discovery_set_param(params, &drec); + } else { + log_error("Operation is not supported."); + rc = ISCSI_ERR_INVAL; +@@ -2102,7 +2115,7 @@ done: + + static int exec_disc_op(int disc_type, char *ip, int port, + struct list_head *ifaces, int info_level, int do_login, +- int do_discover, int op, char *name, char *value, ++ int do_discover, int op, struct list_head *params, + int do_show) + { + struct discovery_rec drec; +@@ -2228,6 +2241,8 @@ static uint32_t parse_host_info(char *op + + *rc = 0; + if (strstr(optarg, ":")) { ++ transport_probe_for_offload(); ++ + host_no = iscsi_sysfs_get_host_no_from_hwaddress(optarg, + &err); + if (err) { +@@ -2245,13 +2260,46 @@ static uint32_t parse_host_info(char *op + return host_no; + } + ++static char *iscsi_ping_stat_strs[] = { ++ /* ISCSI_PING_SUCCESS */ ++ "success", ++ /* ISCSI_PING_FW_DISABLED */ ++ "firmware disabled", ++ /* ISCSI_PING_IPADDR_INVALID */ ++ "invalid IP address", ++ /* ISCSI_PING_LINKLOCAL_IPV6_ADDR_INVALID */ ++ "invalid link local IPv6 address", ++ /* ISCSI_PING_TIMEOUT */ ++ "timed out", ++ /* ISCSI_PING_INVALID_DEST_ADDR */ ++ "invalid destination address", ++ /* ISCSI_PING_OVERSIZE_PACKET */ ++ "oversized packet", ++ /* ISCSI_PING_ICMP_ERROR */ ++ "ICMP error", ++ /* ISCSI_PING_MAX_REQ_EXCEEDED */ ++ "Max request exceeded", ++ /* ISCSI_PING_NO_ARP_RECEIVED */ ++ "No ARP response received", ++}; ++ ++static char *iscsi_ping_stat_to_str(uint32_t status) ++{ ++ if (status < 0 || status > ISCSI_PING_NO_ARP_RECEIVED) { ++ log_error("Invalid ping status %u\n", status); ++ return NULL; ++ } ++ ++ return iscsi_ping_stat_strs[status]; ++} ++ + static int exec_ping_op(struct iface_rec *iface, char *ip, int size, int count, + int interval) + { + int rc = ISCSI_ERR; + uint32_t iface_type = ISCSI_IFACE_TYPE_IPV4; + struct iscsi_transport *t = NULL; +- uint32_t host_no; ++ uint32_t host_no, status = 0; + struct sockaddr_storage addr; + int i; + +@@ -2324,11 +2372,15 @@ static int exec_ping_op(struct iface_rec + * the iscsi if to send a ping, we can add a transport + * callout here. + */ ++ status = 0; + rc = ipc->exec_ping(t->handle, host_no, + (struct sockaddr *)&addr, iface->iface_num, +- iface_type, size); +- if (!rc) ++ iface_type, size, &status); ++ if (!rc && !status) + printf("Ping %d completed\n", i); ++ else if (status) ++ printf("Ping %d failed: %s\n", i, ++ iscsi_ping_stat_to_str(status)); + else + printf("Ping %d failed: %s\n", i, iscsi_err_to_str(rc)); + +@@ -2357,7 +2409,10 @@ main(int argc, char **argv) + struct iface_rec *iface = NULL, *tmp; + struct node_rec *rec = NULL; + uint32_t host_no = -1; ++ struct user_param *param; ++ struct list_head params; + ++ INIT_LIST_HEAD(¶ms); + INIT_LIST_HEAD(&ifaces); + /* do not allow ctrl-c for now... */ + memset(&sa_old, 0, sizeof(struct sigaction)); +@@ -2499,6 +2554,18 @@ main(int argc, char **argv) + case 'h': + usage(0); + } ++ ++ if (name && value) { ++ param = idbm_alloc_user_param(name, value); ++ if (!param) { ++ log_error("Cannot allocate memory for params."); ++ rc = ISCSI_ERR_NOMEM; ++ goto free_ifaces; ++ } ++ list_add_tail(¶m->list, ¶ms); ++ name = NULL; ++ value = NULL; ++ } + } + + if (optopt) { +@@ -2585,7 +2652,7 @@ main(int argc, char **argv) + ping_interval); + else + rc = exec_iface_op(op, do_show, info_level, iface, +- host_no, name, value); ++ host_no, ¶ms); + + break; + case MODE_DISCOVERYDB: +@@ -2597,7 +2664,7 @@ main(int argc, char **argv) + } + + rc = exec_disc2_op(type, ip, port, &ifaces, info_level, +- do_login, do_discover, op, name, value, ++ do_login, do_discover, op, ¶ms, + do_show); + break; + case MODE_DISCOVERY: +@@ -2609,7 +2676,7 @@ main(int argc, char **argv) + } + + rc = exec_disc_op(type, ip, port, &ifaces, info_level, +- do_login, do_discover, op, name, value, ++ do_login, do_discover, op, ¶ms, + do_show); + break; + case MODE_NODE: +@@ -2653,7 +2720,7 @@ main(int argc, char **argv) + + rc = exec_node_op(op, do_login, do_logout, do_show, + do_rescan, do_stats, info_level, rec, +- name, value); ++ ¶ms); + break; + case MODE_SESSION: + if ((rc = verify_mode_params(argc, argv, +@@ -2723,7 +2790,7 @@ main(int argc, char **argv) + /* drop down to node ops */ + rc = exec_node_op(op, do_login, do_logout, do_show, + do_rescan, do_stats, info_level, +- rec, name, value); ++ rec, ¶ms); + free_info: + free(info); + goto out; +@@ -2737,7 +2804,7 @@ free_info: + if (do_logout || do_rescan || do_stats) { + rc = exec_node_op(op, do_login, do_logout, + do_show, do_rescan, do_stats, +- info_level, NULL, name, value); ++ info_level, NULL, ¶ms); + goto out; + } + +diff -aurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsid.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsid.c +--- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsid.c 2012-04-05 16:03:19.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsid.c 2012-04-05 16:04:06.000000000 -0500 +@@ -409,11 +409,6 @@ int main(int argc, char *argv[]) + exit(ISCSI_ERR); + } + +- if (iscsi_sysfs_check_class_version()) { +- log_close(log_pid); +- exit(ISCSI_ERR); +- } +- + umask(0177); + + mgmt_ipc_fd = -1; +diff -aurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_ipc.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_ipc.h +--- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_ipc.h 2012-04-05 16:03:19.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_ipc.h 2012-04-05 16:04:06.000000000 -0500 +@@ -137,7 +137,7 @@ struct iscsi_ipc { + + int (*exec_ping) (uint64_t transport_handle, uint32_t host_no, + struct sockaddr *addr, uint32_t iface_num, +- uint32_t iface_type, uint32_t size); ++ uint32_t iface_type, uint32_t size, uint32_t *status); + + int (*get_chap) (uint64_t transport_handle, uint32_t host_no, + uint16_t chap_tbl_idx, uint32_t num_entries, +diff -aurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_net_util.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_net_util.c +--- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_net_util.c 2012-04-05 16:03:19.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_net_util.c 2012-04-05 16:04:24.000000000 -0500 +@@ -72,7 +72,7 @@ int net_get_transport_name_from_netdev(c + ifr.ifr_data = (caddr_t)&drvinfo; + err = ioctl(fd, SIOCETHTOOL, &ifr); + if (err < 0) { +- log_error("Could not get driver."); ++ log_error("Could not get driver %s.", netdev); + err = errno; + goto close_sock; + } +@@ -228,7 +228,7 @@ int net_setup_netdev(char *netdev, char + + /* Bring up interface */ + memset(&ifr, 0, sizeof(ifr)); +- strncpy(ifr.ifr_name, netdev, IFNAMSIZ); ++ strlcpy(ifr.ifr_name, netdev, IFNAMSIZ); + ifr.ifr_flags = IFF_UP | IFF_RUNNING; + if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0) { + log_error("Could not bring up netdev %s (err %d - %s)", +@@ -238,7 +238,7 @@ int net_setup_netdev(char *netdev, char + } + /* Set IP address */ + memset(&ifr, 0, sizeof(ifr)); +- strncpy(ifr.ifr_name, netdev, IFNAMSIZ); ++ strlcpy(ifr.ifr_name, netdev, IFNAMSIZ); + memcpy(&ifr.ifr_addr, &sk_ipaddr, sizeof(struct sockaddr)); + if (ioctl(sock, SIOCSIFADDR, &ifr) < 0) { + log_error("Could not set ip for %s (err %d - %s)", +@@ -249,7 +249,7 @@ int net_setup_netdev(char *netdev, char + + /* Set netmask */ + memset(&ifr, 0, sizeof(ifr)); +- strncpy(ifr.ifr_name, netdev, IFNAMSIZ); ++ strlcpy(ifr.ifr_name, netdev, IFNAMSIZ); + memcpy(&ifr.ifr_addr, &sk_netmask, sizeof(struct sockaddr)); + if (ioctl(sock, SIOCSIFNETMASK, &ifr) < 0) { + log_error("Could not set ip for %s (err %d - %s)", +@@ -304,6 +304,59 @@ int net_setup_netdev(char *netdev, char + done: + close(sock); + return ret; ++} ++ ++/** ++ * net_ifup_netdev - bring up network interface ++ * @netdev: netdevice to bring up. ++ */ ++int net_ifup_netdev(char *netdev) ++{ ++ struct ifreq ifr; ++ int sock; ++ int ret = 0; ++ ++ if (!strlen(netdev)) { ++ log_error("No netdev name in fw entry.\n"); ++ return EINVAL; ++ } ++ ++ /* Create socket for making networking changes */ ++ if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { ++ log_error("Could not open socket to manage network " ++ "(err %d - %s)", errno, strerror(errno)); ++ return errno; ++ } ++ ++ memset(&ifr, 0, sizeof(ifr)); ++ strlcpy(ifr.ifr_name, netdev, IFNAMSIZ); ++ if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) { ++ log_error("Could not bring up netdev %s (err %d - %s)", ++ netdev, errno, strerror(errno)); ++ ret = errno; ++ goto done; ++ } ++ ++ if (ifr.ifr_flags & IFF_UP) { ++ log_debug(3, "%s up\n", netdev); ++ goto done; ++ } ++ ++ log_debug(3, "bringing %s up\n", netdev); ++ ++ /* Bring up interface */ ++ memset(&ifr, 0, sizeof(ifr)); ++ strlcpy(ifr.ifr_name, netdev, IFNAMSIZ); ++ ifr.ifr_flags = IFF_UP; ++ if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0) { ++ log_error("Could not bring up netdev %s (err %d - %s)", ++ netdev, errno, strerror(errno)); ++ ret = errno; ++ goto done; ++ } ++done: ++ close(sock); ++ return ret; + } + + +diff -aurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsistart.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsistart.c +--- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsistart.c 2012-04-05 16:03:19.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsistart.c 2012-04-05 16:04:06.000000000 -0500 +@@ -40,6 +40,7 @@ + #include "log.h" + #include "iscsi_util.h" + #include "idbm.h" ++#include "idbm_fields.h" + #include "version.h" + #include "iscsi_sysfs.h" + #include "iscsi_settings.h" +@@ -48,6 +49,7 @@ + #include "sysdeps.h" + #include "iscsid_req.h" + #include "iscsi_err.h" ++#include "iface.h" + + /* global config info */ + /* initiator needs initiator name/alias */ +@@ -58,11 +60,6 @@ static node_rec_t config_rec; + static LIST_HEAD(targets); + static LIST_HEAD(user_params); + +-struct user_param { +- struct list_head list; +- char *param_string; +-}; +- + static char program_name[] = "iscsistart"; + + /* used by initiator */ +@@ -145,11 +142,34 @@ static int apply_params(struct node_rec + rec->conn[0].timeo.noop_out_timeout = -1; + + list_for_each_entry(param, &user_params, list) { +- rc = idbm_parse_param(param->param_string, rec); +- if (rc) +- return rc; ++ /* ++ * user may not have passed in all params that were set by ++ * ibft/iscsi_boot, so clear out values that might conflict ++ * with user overrides ++ */ ++ if (!strcmp(param->name, IFACE_NETNAME)) { ++ /* overriding netname so MAC will be for old netdev */ ++ memset(rec->iface.hwaddress, 0, ++ sizeof(rec->iface.hwaddress)); ++ } else if (!strcmp(param->name, IFACE_HWADDR)) { ++ /* overriding MAC so netdev will be for old MAC */ ++ memset(rec->iface.netdev, 0, sizeof(rec->iface.netdev)); ++ } else if (!strcmp(param->name, IFACE_TRANSPORTNAME)) { ++ /* ++ * switching drivers so all old binding info is no ++ * longer valid. Old values were either for offload ++ * and we are switching to software or the reverse, ++ * or switching types of cards (bnx2i to cxgb3i). ++ */ ++ memset(&rec->iface, 0, sizeof(rec->iface)); ++ iface_setup_defaults(&rec->iface); ++ } + } + ++ rc = idbm_node_set_rec_from_param(&user_params, rec, 0); ++ if (rc) ++ return rc; ++ + /* + * For root boot we could not change this in older versions so + * if user did not override then use the defaults. +@@ -167,23 +187,32 @@ static int apply_params(struct node_rec + return 0; + } + +-static int alloc_param(char *param_string) ++static int parse_param(char *param_str) + { + struct user_param *param; ++ char *name, *value; + +- param = calloc(1, sizeof(*param)); +- if (!param) { +- printf("Could not allocate for param.\n"); +- return ISCSI_ERR_NOMEM; ++ name = param_str; ++ ++ value = strchr(param_str, '='); ++ if (!value) { ++ log_error("Invalid --param %s. Missing value.", param_str); ++ return ISCSI_ERR_INVAL; ++ } ++ *value = '\0'; ++ ++ value++; ++ if (!strlen(value)) { ++ log_error("Invalid --param %s. Missing value.", param_str); ++ return ISCSI_ERR_INVAL; + } + +- INIT_LIST_HEAD(¶m->list); +- param->param_string = strdup(param_string); +- if (!param->param_string) { +- printf("Could not allocate for param.\n"); +- free(param); ++ param = idbm_alloc_user_param(name, value); ++ if (!param) { ++ log_error("Could not allocate memory for param."); + return ISCSI_ERR_NOMEM; + } ++ + list_add(¶m->list, &user_params); + return 0; + } +@@ -196,7 +225,7 @@ static int login_session(struct node_rec + + rc = apply_params(rec); + if (rc) +- exit(rc); ++ return rc; + + printf("%s: Logging into %s %s:%d,%d\n", program_name, rec->name, + rec->conn[0].address, rec->conn[0].port, +@@ -316,8 +345,6 @@ int main(int argc, char *argv[]) + log_init(program_name, DEFAULT_AREA_SIZE, log_do_log_std, NULL); + + sysfs_init(); +- if (iscsi_sysfs_check_class_version()) +- exit(ISCSI_ERR_SYSFS_LOOKUP); + + while ((ch = getopt_long(argc, argv, "P:i:t:g:a:p:d:u:w:U:W:bNfvh", + long_options, &longindex)) >= 0) { +@@ -399,7 +426,7 @@ int main(int argc, char *argv[]) + fw_free_targets(&targets); + exit(0); + case 'P': +- err = alloc_param(optarg); ++ err = parse_param(optarg); + if (err) + exit(err); + break; +diff -aurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_sysfs.c +--- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.c 2012-04-05 16:03:19.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_sysfs.c 2012-04-05 16:04:06.000000000 -0500 +@@ -532,6 +532,12 @@ static int iscsi_sysfs_read_iface(struct + ret = 0; + } + ++ sysfs_get_str(host_id, ISCSI_HOST_SUBSYS, "port_state", ++ iface->port_state, sizeof(iface->port_state)); ++ ++ sysfs_get_str(host_id, ISCSI_HOST_SUBSYS, "port_speed", ++ iface->port_speed, sizeof(iface->port_speed)); ++ + /* + * this is on the session, because we support multiple bindings + * per device. +@@ -1144,13 +1150,31 @@ static uint32_t get_target_no_from_sid(u + + } + ++int iscsi_sysfs_is_transport_loaded(char *transport_name) ++{ ++ struct iscsi_transport *t; ++ ++ /* sync up kernel and userspace */ ++ read_transports(); ++ ++ /* check if the transport is loaded and matches */ ++ list_for_each_entry(t, &transports, list) { ++ if (t->handle && !strncmp(t->name, transport_name, ++ ISCSI_TRANSPORT_NAME_MAXLEN)) ++ return 1; ++ } ++ ++ return 0; ++} ++ + struct iscsi_transport *iscsi_sysfs_get_transport_by_name(char *transport_name) + { + struct iscsi_transport *t; ++ int retry = 0; + ++retry: + /* sync up kernel and userspace */ +- if (read_transports()) +- return NULL; ++ read_transports(); + + /* check if the transport is loaded and matches */ + list_for_each_entry(t, &transports, list) { +@@ -1158,6 +1182,13 @@ struct iscsi_transport *iscsi_sysfs_get_ + ISCSI_TRANSPORT_NAME_MAXLEN)) + return t; + } ++ ++ if (retry < 1) { ++ retry++; ++ if (!transport_load_kmod(transport_name)) ++ goto retry; ++ } ++ + return NULL; + } + +@@ -1366,40 +1397,3 @@ char *iscsi_sysfs_get_iscsi_kernel_versi + { + return sysfs_attr_get_value("/module/scsi_transport_iscsi", "version"); + } +- +-int iscsi_sysfs_check_class_version(void) +-{ +- char *version; +- int i; +- +- version = iscsi_sysfs_get_iscsi_kernel_version(); +- if (!version) +- goto fail; +- +- log_warning("transport class version %s. iscsid version %s", +- version, ISCSI_VERSION_STR); +- +- for (i = 0; i < strlen(version); i++) { +- if (version[i] == '-') +- break; +- } +- +- if (i == strlen(version)) +- goto fail; +- +- /* +- * We want to make sure the release and interface are the same. +- * It is ok for the svn versions to be different. +- */ +- if (!strncmp(version, ISCSI_VERSION_STR, i) || +- /* support 2.6.18 */ +- !strncmp(version, "1.1", 3)) +- return 0; +- +-fail: +- log_error( "Missing or Invalid version from %s. Make sure a up " +- "to date scsi_transport_iscsi module is loaded and a up to" +- "date version of iscsid is running. Exiting...", +- ISCSI_VERSION_FILE); +- return -1; +-} +diff -aurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_sysfs.h +--- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.h 2012-04-05 16:03:19.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_sysfs.h 2012-04-05 16:04:06.000000000 -0500 +@@ -36,7 +36,6 @@ struct iscsi_auth_config; + + extern void free_transports(void); + extern char *iscsi_sysfs_get_iscsi_kernel_version(void); +-extern int iscsi_sysfs_check_class_version(void); + extern int iscsi_sysfs_get_sessioninfo_by_id(struct session_info *info, + char *sys_session); + extern int iscsi_sysfs_session_has_leadconn(uint32_t sid); +@@ -89,6 +88,7 @@ extern struct iscsi_transport *iscsi_sys + extern struct iscsi_transport *iscsi_sysfs_get_transport_by_session(char *sys_session); + extern struct iscsi_transport *iscsi_sysfs_get_transport_by_sid(uint32_t sid); + extern struct iscsi_transport *iscsi_sysfs_get_transport_by_name(char *transport_name); ++extern int iscsi_sysfs_is_transport_loaded(char *transport_name); + extern int iscsi_sysfs_session_supports_nop(int sid); + extern int iscsi_sysfs_session_user_created(int sid); + +diff -aurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_util.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_util.c +--- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_util.c 2012-04-05 16:03:19.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_util.c 2012-04-05 16:04:06.000000000 -0500 +@@ -90,13 +90,24 @@ str_to_ipport(char *str, int *port, int + + if (!strchr(ip, '.')) { + if (*ip == '[') { ++ /* IPv6 with [] */ + if (!(sport = strchr(ip, ']'))) + return NULL; + *sport++ = '\0'; + ip++; + str = sport; +- } else +- sport = NULL; ++ } else { ++ /* hostname or ipv6 */ ++ sport = strchr(ip, ':'); ++ if (sport) { ++ if (strchr(sport + 1, ':')) ++ /* ipv6 */ ++ sport = NULL; ++ else ++ /* hostname:port */ ++ str = sport; ++ } ++ } + } + + if (sport && (sport = strchr(str, ':'))) { +@@ -178,7 +189,6 @@ char *strstrip(char *s) + char *cfg_get_string_param(char *pathname, const char *key) + { + FILE *f = NULL; +- int len; + char *line, buffer[1024]; + char *value = NULL, *param, *comment; + +@@ -187,7 +197,6 @@ char *cfg_get_string_param(char *pathnam + return NULL; + } + +- len = strlen(key); + if ((f = fopen(pathname, "r"))) { + while ((line = fgets(buffer, sizeof (buffer), f))) { + param = strstr(line, key); +diff -aurp open-iscsi-2.0-872-rc4-bnx2i/usr/Makefile open-iscsi-2.0-872-rc4-bnx2i.work/usr/Makefile +--- open-iscsi-2.0-872-rc4-bnx2i/usr/Makefile 2012-04-05 16:03:19.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/Makefile 2012-04-05 16:04:06.000000000 -0500 +@@ -33,7 +33,7 @@ endif + OPTFLAGS ?= -O2 -g + WARNFLAGS ?= -Wall -Wstrict-prototypes + CFLAGS += $(OPTFLAGS) $(WARNFLAGS) -I../include -I. -I../utils/open-isns \ +- -D$(OSNAME) $(IPC_CFLAGS) -DISNS_ENABLE ++ -D$(OSNAME) $(IPC_CFLAGS) -DISNS_ENABLE + PROGRAMS = iscsid iscsiadm iscsistart + + # libc compat files +@@ -57,7 +57,7 @@ all: $(PROGRAMS) + + iscsid: $(ISCSI_LIB_SRCS) $(INITIATOR_SRCS) $(DISCOVERY_SRCS) \ + iscsid.o session_mgmt.o discoveryd.o +- $(CC) $(CFLAGS) $^ -o $@ -L../utils/open-isns -lisns ++ $(CC) $(CFLAGS) $^ -o $@ -L../utils/open-isns -lisns + + iscsiadm: $(ISCSI_LIB_SRCS) $(DISCOVERY_SRCS) iscsiadm.o session_mgmt.o + $(CC) $(CFLAGS) $^ -o $@ -L../utils/open-isns -lisns +diff -aurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/netlink.c +--- open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c 2012-04-05 16:03:19.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/netlink.c 2012-04-05 16:04:06.000000000 -0500 +@@ -1085,13 +1085,15 @@ ksend_ping(uint64_t transport_handle, ui + + static int kexec_ping(uint64_t transport_handle, uint32_t host_no, + struct sockaddr *addr, uint32_t iface_num, +- uint32_t iface_type, uint32_t size) ++ uint32_t iface_type, uint32_t size, uint32_t *status) + { + struct pollfd pfd; + struct timeval ping_timer; + int timeout, fd, rc; + uint32_t pid; + ++ *status = 0; ++ + fd = ipc->ctldev_open(); + if (fd < 0) { + log_error("Could not open netlink socket."); +@@ -1151,10 +1153,8 @@ static int kexec_ping(uint64_t transport + if (pid != ping_event.pid) + continue; + +- if (ping_event.status == 0) +- rc = 0; +- else +- rc = ISCSI_ERR; ++ rc = 0; ++ *status = ping_event.status; + break; + } + +diff -aurp open-iscsi-2.0-872-rc4-bnx2i/usr/transport.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/transport.c +--- open-iscsi-2.0-872-rc4-bnx2i/usr/transport.c 2012-04-05 16:03:19.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/transport.c 2012-04-05 16:04:16.000000000 -0500 +@@ -19,7 +19,17 @@ + #include + #include + #include ++#ifdef USE_KMOD ++#include ++#endif ++#include ++#include ++#include ++#include ++#include + ++#include "sysdeps.h" ++#include "iscsi_err.h" + #include "initiator.h" + #include "transport.h" + #include "log.h" +@@ -100,6 +110,152 @@ static struct iscsi_transport_template * + NULL + }; + ++int transport_probe_for_offload(void) ++{ ++ struct if_nameindex *ifni; ++ char transport_name[ISCSI_TRANSPORT_NAME_MAXLEN]; ++ int i, sockfd; ++ struct ifreq if_hwaddr; ++ ++ ifni = if_nameindex(); ++ if (!ifni) { ++ log_error("Could not search for transport modules: %s", ++ strerror(errno)); ++ return ISCSI_ERR_TRANS_NOT_FOUND; ++ } ++ ++ sockfd = socket(AF_INET, SOCK_DGRAM, 0); ++ if (sockfd < 0) { ++ log_error("Could not open socket for ioctl: %s", ++ strerror(errno)); ++ goto free_ifni; ++ } ++ ++ for (i = 0; ifni[i].if_index && ifni[i].if_name; i++) { ++ struct if_nameindex *n = &ifni[i]; ++ ++ log_debug(6, "kmod probe found %s\n", n->if_name); ++ ++ strlcpy(if_hwaddr.ifr_name, n->if_name, IFNAMSIZ); ++ if (ioctl(sockfd, SIOCGIFHWADDR, &if_hwaddr) < 0) ++ continue; ++ ++ /* check for ARPHRD_ETHER (ethernet) */ ++ if (if_hwaddr.ifr_hwaddr.sa_family != 1) ++ continue; ++ ++ if (net_get_transport_name_from_netdev(n->if_name, ++ transport_name)) ++ continue; ++ ++ transport_load_kmod(transport_name); ++ } ++ close(sockfd); ++ ++free_ifni: ++ if_freenameindex(ifni); ++ return 0; ++} ++ ++/* ++ * Most distros still do not have wide libkmod use, so ++ * use modprobe for now ++ */ ++#ifdef USE_KMOD ++int transport_load_kmod(char *transport_name) ++{ ++ struct kmod_ctx *ctx; ++ struct kmod_module *mod; ++ int rc; ++ ++ ctx = kmod_new(NULL, NULL); ++ if (!ctx) { ++ log_error("Could not load transport module %s. Out of " ++ "memory.", transport_name); ++ return ISCSI_ERR_NOMEM; ++ } ++ ++ kmod_load_resources(ctx); ++ ++ /* ++ * dumb dumb dumb - named iscsi_tcp and ib_iser differently from ++ * transport name ++ */ ++ if (!strcmp(transport_name, "tcp")) ++ rc = kmod_module_new_from_name(ctx, "iscsi_tcp", &mod); ++ else if (!strcmp(transport_name, "iser")) ++ rc = kmod_module_new_from_name(ctx, "ib_iser", &mod); ++ else ++ rc = kmod_module_new_from_name(ctx, transport_name, &mod); ++ if (rc) { ++ log_error("Failed to load module %s.", transport_name); ++ rc = ISCSI_ERR_TRANS_NOT_FOUND; ++ goto unref_mod; ++ } ++ ++ rc = kmod_module_probe_insert_module(mod, KMOD_PROBE_APPLY_BLACKLIST, ++ NULL, NULL, NULL, NULL); ++ if (rc) { ++ log_error("Could not insert module %s. Kmod error %d", ++ transport_name, rc); ++ rc = ISCSI_ERR_TRANS_NOT_FOUND; ++ } ++ kmod_module_unref(mod); ++ ++unref_mod: ++ kmod_unref(ctx); ++ return rc; ++} ++ ++#else ++ ++int transport_load_kmod(char *transport_name) ++{ ++ char *cmdline[4]; ++ pid_t pid; ++ ++ cmdline[0] = "/sbin/modprobe"; ++ cmdline[1] = "-qb"; ++ cmdline[3] = NULL; ++ ++ /* ++ * dumb dumb mistake - named iscsi_tcp and ib_iser differently from ++ * transport name ++ */ ++ if (!strcmp(transport_name, "tcp")) ++ cmdline[2] = "iscsi_tcp"; ++ else if (!strcmp(transport_name, "iser")) ++ cmdline[2] = "ib_iser"; ++ else ++ cmdline[2] = transport_name; ++ ++ if (iscsi_sysfs_is_transport_loaded(cmdline[2])) ++ return 0; ++ ++ pid = fork(); ++ if (pid == 0) { ++ if (execv("/sbin/modprobe", cmdline) < 0) { ++ log_error("Failed to load module %s: %s", ++ transport_name, strerror(errno)); ++ exit(-errno); ++ } ++ exit(0); ++ } else if (pid < 0) { ++ log_error("Failed to fork process to load module %s: %s", ++ transport_name, strerror(errno)); ++ return ISCSI_ERR_TRANS_NOT_FOUND; ++ } ++ ++ if (waitpid(pid, NULL, 0) < 0) { ++ log_error("Failed to load module %s", transport_name); ++ return ISCSI_ERR_TRANS_NOT_FOUND; ++ } ++ ++ return 0; ++} ++ ++#endif ++ + int set_transport_template(struct iscsi_transport *t) + { + struct iscsi_transport_template *tmpl; +diff -aurp open-iscsi-2.0-872-rc4-bnx2i/usr/transport.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/transport.h +--- open-iscsi-2.0-872-rc4-bnx2i/usr/transport.h 2012-04-05 16:03:19.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/transport.h 2012-04-05 16:04:06.000000000 -0500 +@@ -51,5 +51,7 @@ struct iscsi_transport { + }; + + extern int set_transport_template(struct iscsi_transport *t); ++extern int transport_load_kmod(char *transport_name); ++extern int transport_probe_for_offload(void); + + #endif +diff -aurp open-iscsi-2.0-872-rc4-bnx2i/utils/fwparam_ibft/fw_entry.c open-iscsi-2.0-872-rc4-bnx2i.work/utils/fwparam_ibft/fw_entry.c +--- open-iscsi-2.0-872-rc4-bnx2i/utils/fwparam_ibft/fw_entry.c 2012-04-05 16:03:19.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/utils/fwparam_ibft/fw_entry.c 2012-04-05 16:04:06.000000000 -0500 +@@ -35,6 +35,8 @@ + #include "idbm_fields.h" + #include "iscsi_net_util.h" + #include "iscsi_err.h" ++#include "config.h" ++#include "iface.h" + + /** + * fw_setup_nics - setup nics (ethXs) based on ibft net info +@@ -146,11 +148,19 @@ void fw_free_targets(struct list_head *l + + static void dump_initiator(struct boot_context *context) + { ++ struct iface_rec iface; ++ ++ memset(&iface, 0, sizeof(iface)); ++ iface_setup_defaults(&iface); ++ iface_setup_from_boot_context(&iface, context); ++ + if (strlen(context->initiatorname)) + printf("%s = %s\n", IFACE_INAME, context->initiatorname); + + if (strlen(context->isid)) + printf("%s = %s\n", IFACE_ISID, context->isid); ++ ++ printf("%s = %s\n", IFACE_TRANSPORTNAME, iface.transport_name); + } + + static void dump_target(struct boot_context *context) diff --git a/iscsi-initiator-utils-ping-and-chap.patch b/iscsi-initiator-utils-ping-and-chap.patch new file mode 100644 index 0000000..286a852 --- /dev/null +++ b/iscsi-initiator-utils-ping-and-chap.patch @@ -0,0 +1,1141 @@ +diff -aurp open-iscsi-2.0-872-rc4-bnx2i/doc/iscsiadm.8 open-iscsi-2.0-872-rc4-bnx2i.work/doc/iscsiadm.8 +--- open-iscsi-2.0-872-rc4-bnx2i/doc/iscsiadm.8 2012-03-06 05:22:41.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/doc/iscsiadm.8 2012-03-06 05:22:26.000000000 -0600 +@@ -12,11 +12,11 @@ iscsiadm \- open-iscsi administration ut + + \fBiscsiadm\fR \-m session [ \-hV ] [ \-d debug_level ] [ \-P printlevel ] [ \-r sessionid | sysfsdir [ \-R ] [ \-u | \-s | \-o new ] ] + +-\fBiscsiadm\fR \-m iface [ \-hV ] [ \-d debug_level ] [ \-P printlevel ] [ \-I ifacename | \-H hostno|MAC ] [ [ \-o operation ] [ \-n name ] [ \-v value ] ] ++\fBiscsiadm\fR \-m iface [ \-hV ] [ \-d debug_level ] [ \-P printlevel ] [ \-I ifacename | \-H hostno|MAC ] [ [ \-o operation ] [ \-n name ] [ \-v value ] ] [ \-C ping [ \-a ip ] [ \-b packetsize ] [ \-c count ] [ \-i interval ] ] + + \fBiscsiadm\fR \-m fw [\-l] + +-\fBiscsiadm\fR \-m host [ \-P printlevel ] [ \-H hostno|MAC ] ++\fBiscsiadm\fR \-m host [ \-P printlevel ] [ \-H hostno|MAC ] [ -C chap [ -o operation ] [ -v chap_tbl_idx ] ] + + \fBiscsiadm\fR \-k priority + +@@ -41,6 +41,32 @@ daemon (iscsid) be running. + .SH OPTIONS + + .TP ++\fB\-a\fR, \fB\-\-ip=\fIipaddr\fP ++\fIipaddr\fR can be IPv4 or IPv6. ++ ++This option is only valid for ping submode. ++ ++.TP ++\fB\-b\fR, \fB\-\-packetsize=\fIpacketsize\fP ++Specify the ping \fIpacketsize\fR. ++ ++This option is only valid for ping submode. ++ ++.TP ++\fB\-c\fR, \fB\-\-count=\fIcount\fP ++\fIcount\fR specify number of ping iterations. ++ ++This option is only valid for ping submode. ++ ++.TP ++\fB\-C\fR, \fB\-\-submode=\fIop\fP ++Specify the submode for mode. op must be name of submode. ++ ++Currently iscsiadm support ping as submode for iface. For example, ++ ++iscsiadm -m iface -I ifacename -C ping -a ipaddr -b packetsize -c count -i interval ++ ++.TP + \fB\-d\fR, \fB\-\-debug=\fIdebug_level\fP + print debugging information. Valid values for debug_level are 0 to 8. + +@@ -55,6 +81,12 @@ the scsi host number assigned to the hos + MAC address of a scsi host. + + .TP ++\fB\-i\fR, \fB\-\-interval=\fIinterval\fP ++\fIinterval\fP specify delay between two ping iterations. ++ ++This option is only valid for ping submode. ++ ++.TP + \fB\-I\fR, \fB\-\-interface=\fI[iface]\fR + The interface argument specifies the iSCSI interface to use for the operation. + iSCSI interfaces (iface) are defined in /var/lib/iscsi/ifaces. For hardware +diff -aurp open-iscsi-2.0-872-rc4-bnx2i/include/iscsi_err.h open-iscsi-2.0-872-rc4-bnx2i.work/include/iscsi_err.h +--- open-iscsi-2.0-872-rc4-bnx2i/include/iscsi_err.h 2012-03-06 05:22:41.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/include/iscsi_err.h 2012-03-06 05:22:26.000000000 -0600 +@@ -58,8 +58,12 @@ enum { + ISCSI_ERR_ISNS_QUERY = 25, + /* iSNS registration/deregistration failed */ + ISCSI_ERR_ISNS_REG_FAILED = 26, ++ /* operation not supported */ ++ ISCSI_ERR_OP_NOT_SUPP = 27, ++ /* device or resource in use */ ++ ISCSI_ERR_BUSY = 28, + /* Operation failed, but retrying layer may succeed */ +- ISCSI_ERR_AGAIN = 27, ++ ISCSI_ERR_AGAIN = 29, + + /* Always last. Indicates end of error code space */ + ISCSI_MAX_ERR_VAL, +diff -aurp open-iscsi-2.0-872-rc4-bnx2i/include/iscsi_if.h open-iscsi-2.0-872-rc4-bnx2i.work/include/iscsi_if.h +--- open-iscsi-2.0-872-rc4-bnx2i/include/iscsi_if.h 2012-03-06 05:22:41.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/include/iscsi_if.h 2012-03-06 05:22:26.000000000 -0600 +@@ -65,8 +65,11 @@ enum iscsi_uevent_e { + + ISCSI_UEVENT_PATH_UPDATE = UEVENT_BASE + 20, + ISCSI_UEVENT_SET_IFACE_PARAMS = UEVENT_BASE + 21, ++ ISCSI_UEVENT_PING = UEVENT_BASE + 22, ++ ISCSI_UEVENT_GET_CHAP = UEVENT_BASE + 23, ++ ISCSI_UEVENT_DELETE_CHAP = UEVENT_BASE + 24, + +- ISCSI_UEVENT_MAX = ISCSI_UEVENT_SET_IFACE_PARAMS, ++ ISCSI_UEVENT_MAX = ISCSI_UEVENT_DELETE_CHAP, + + /* up events */ + ISCSI_KEVENT_RECV_PDU = KEVENT_BASE + 1, +@@ -80,8 +83,9 @@ enum iscsi_uevent_e { + ISCSI_KEVENT_IF_DOWN = KEVENT_BASE + 8, + ISCSI_KEVENT_CONN_LOGIN_STATE = KEVENT_BASE + 9, + ISCSI_KEVENT_HOST_EVENT = KEVENT_BASE + 10, ++ ISCSI_KEVENT_PING_COMP = KEVENT_BASE + 11, + +- ISCSI_KEVENT_MAX = ISCSI_KEVENT_HOST_EVENT, ++ ISCSI_KEVENT_MAX = ISCSI_KEVENT_PING_COMP, + }; + + enum iscsi_tgt_dscvr { +@@ -195,6 +199,26 @@ struct iscsi_uevent { + uint32_t host_no; + uint32_t count; + } set_iface_params; ++ struct msg_iscsi_ping { ++ uint32_t host_no; ++ uint32_t iface_num; ++ uint32_t iface_type; ++ uint32_t payload_size; ++ uint32_t pid; /* unique ping id associated ++ with each ping request */ ++ } iscsi_ping; ++ struct msg_get_chap { ++ uint32_t host_no; ++ uint32_t num_entries; /* number of CHAP entries ++ * on request, number of ++ * valid CHAP entries on ++ * response */ ++ uint16_t chap_tbl_idx; ++ } get_chap; ++ struct msg_delete_chap { ++ uint32_t host_no; ++ uint16_t chap_tbl_idx; ++ } delete_chap; + } u; + union { + /* messages k -> u */ +@@ -244,6 +268,13 @@ struct iscsi_uevent { + uint32_t data_size; + enum iscsi_host_event_code code; + } host_event; ++ struct msg_ping_comp { ++ uint32_t host_no; ++ uint32_t status; ++ uint32_t pid; /* unique ping id associated ++ with each ping request */ ++ uint32_t data_size; ++ } ping_comp; + } r; + } __attribute__ ((aligned (sizeof(uint64_t)))); + +@@ -566,4 +597,20 @@ struct iscsi_stats { + __attribute__ ((aligned (sizeof(uint64_t)))); + }; + ++enum chap_type_e { ++ CHAP_TYPE_OUT, ++ CHAP_TYPE_IN, ++}; ++ ++#define ISCSI_CHAP_AUTH_NAME_MAX_LEN 256 ++#define ISCSI_CHAP_AUTH_SECRET_MAX_LEN 256 ++ ++struct iscsi_chap_rec { ++ uint16_t chap_tbl_idx; ++ enum chap_type_e chap_type; ++ char username[ISCSI_CHAP_AUTH_NAME_MAX_LEN]; ++ uint8_t password[ISCSI_CHAP_AUTH_SECRET_MAX_LEN]; ++ uint8_t password_length; ++}; ++ + #endif +diff -aurp open-iscsi-2.0-872-rc4-bnx2i/README open-iscsi-2.0-872-rc4-bnx2i.work/README +--- open-iscsi-2.0-872-rc4-bnx2i/README 2012-03-06 05:22:41.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/README 2012-03-06 05:22:26.000000000 -0600 +@@ -366,7 +366,9 @@ Usage: iscsiadm [OPTION] + iscsi_ifacename. + + See below for examples. +- -m host --host=hostno|MAC --print=level ++ -m iface --interface=iscsi_ifacename -C ping --ip=[ipaddr] --packetsize=[size] ++ --count=[count] --interval=[interval] ++ -m host --host=hostno|MAC --print=level -C chap --op=[op] --value=[chap_tbl_idx] + Display information for a specific host. The host + can be passed in by host number or by MAC address. + If a host is not passed in then info +diff -aurp open-iscsi-2.0-872-rc4-bnx2i/usr/host.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/host.h +--- open-iscsi-2.0-872-rc4-bnx2i/usr/host.h 2012-03-06 05:22:41.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/host.h 2012-03-06 05:22:26.000000000 -0600 +@@ -5,6 +5,9 @@ + #include "types.h" + #include "config.h" + ++#define MAX_CHAP_BUF_SZ 4096 ++#define REQ_CHAP_BUF_SZ (MAX_CHAP_BUF_SZ + sizeof(struct iscsi_uevent)) ++ + struct host_info { + struct iface_rec iface; + uint32_t host_no; +diff -aurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/idbm.c +--- open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c 2012-03-06 05:22:41.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/idbm.c 2012-03-06 05:22:26.000000000 -0600 +@@ -449,6 +449,30 @@ void idbm_recinfo_iface(iface_rec_t *r, + __recinfo_uint16(IFACE_PORT, ri, r, port, IDBM_SHOW, num, 1); + } + ++static void idbm_recinfo_host_chap(struct iscsi_chap_rec *r, recinfo_t *ri) ++{ ++ int num = 0; ++ ++ __recinfo_uint16(HOST_AUTH_INDEX, ri, r, chap_tbl_idx, IDBM_SHOW, ++ num, 1); ++ ++ if (r->chap_type == CHAP_TYPE_OUT) { ++ __recinfo_str(HOST_AUTH_USERNAME, ri, r, username, IDBM_SHOW, ++ num, 0); ++ __recinfo_str(HOST_AUTH_PASSWORD, ri, r, password, IDBM_MASKED, ++ num, 1); ++ __recinfo_int(HOST_AUTH_PASSWORD_LEN, ri, r, password_length, ++ IDBM_HIDE, num, 1); ++ } else { ++ __recinfo_str(HOST_AUTH_USERNAME_IN, ri, r, username, IDBM_SHOW, ++ num, 0); ++ __recinfo_str(HOST_AUTH_PASSWORD_IN, ri, r, password, ++ IDBM_MASKED, num, 1); ++ __recinfo_int(HOST_AUTH_PASSWORD_IN_LEN, ri, r, password_length, ++ IDBM_HIDE, num, 1); ++ } ++} ++ + recinfo_t *idbm_recinfo_alloc(int max_keys) + { + recinfo_t *info; +@@ -479,6 +503,9 @@ void idbm_print(int type, void *rec, int + case IDBM_PRINT_TYPE_IFACE: + idbm_recinfo_iface((struct iface_rec *)rec, info); + break; ++ case IDBM_PRINT_TYPE_HOST_CHAP: ++ idbm_recinfo_host_chap((struct iscsi_chap_rec *)rec, info); ++ break; + } + + fprintf(f, "%s\n", ISCSI_BEGIN_REC); +@@ -849,6 +876,13 @@ int idbm_print_iface_info(void *data, st + return 0; + } + ++int idbm_print_host_chap_info(struct iscsi_chap_rec *chap) ++{ ++ /* User only calls this to print chap so always print */ ++ idbm_print(IDBM_PRINT_TYPE_HOST_CHAP, chap, 1, stdout); ++ return 0; ++} ++ + int idbm_print_node_flat(void *data, node_rec_t *rec) + { + if (strchr(rec->conn[0].address, '.')) +diff -aurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm_fields.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/idbm_fields.h +--- open-iscsi-2.0-872-rc4-bnx2i/usr/idbm_fields.h 2012-03-06 05:22:41.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/idbm_fields.h 2012-03-06 05:22:26.000000000 -0600 +@@ -116,4 +116,14 @@ + #define DISC_ISNS_ADDR "discovery.sendtargets.address" + #define DISC_ISNS_PORT "discovery.sendtargets.port" + ++/* host auth fields */ ++#define HOST_AUTH_INDEX "host.auth.tbl_idx" ++#define HOST_AUTH_METHOD "host.auth.authmethod" ++#define HOST_AUTH_USERNAME "host.auth.username" ++#define HOST_AUTH_PASSWORD "host.auth.password" ++#define HOST_AUTH_PASSWORD_LEN "host.auth.password_length" ++#define HOST_AUTH_USERNAME_IN "host.auth.username_in" ++#define HOST_AUTH_PASSWORD_IN "host.auth.password_in" ++#define HOST_AUTH_PASSWORD_IN_LEN "host.auth.password_in_length" ++ + #endif +diff -aurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/idbm.h +--- open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.h 2012-03-06 05:22:41.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/idbm.h 2012-03-06 05:22:26.000000000 -0600 +@@ -168,6 +168,7 @@ enum { + IDBM_PRINT_TYPE_DISCOVERY, + IDBM_PRINT_TYPE_NODE, + IDBM_PRINT_TYPE_IFACE, ++ IDBM_PRINT_TYPE_HOST_CHAP, + }; + + extern void idbm_print(int type, void *rec, int show, FILE *f); +@@ -180,4 +181,6 @@ extern struct node_rec *idbm_create_rec( + extern struct node_rec * + idbm_create_rec_from_boot_context(struct boot_context *context); + ++extern int idbm_print_host_chap_info(struct iscsi_chap_rec *chap); ++ + #endif /* IDBM_H */ +diff -aurp open-iscsi-2.0-872-rc4-bnx2i/usr/iface.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/iface.c +--- open-iscsi-2.0-872-rc4-bnx2i/usr/iface.c 2012-03-06 05:22:41.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iface.c 2012-03-06 05:23:54.000000000 -0600 +@@ -425,12 +425,23 @@ int iface_get_by_net_binding(struct ifac + return ISCSI_ERR_NO_OBJS_FOUND; + } + +-static int iface_get_iptype(struct iface_rec *iface) ++int iface_get_iptype(struct iface_rec *iface) + { +- if (strcmp(iface->bootproto, "dhcp") && !strstr(iface->ipaddress, ".")) +- return ISCSI_IFACE_TYPE_IPV6; +- else +- return ISCSI_IFACE_TYPE_IPV4; ++ /* address might not be set if user config with another tool */ ++ if (!strlen(iface->ipaddress) || ++ !strcmp(UNKNOWN_VALUE, iface->ipaddress)) { ++ /* try to figure out by name */ ++ if (strstr(iface->name, "ipv4")) ++ return ISCSI_IFACE_TYPE_IPV4; ++ else ++ return ISCSI_IFACE_TYPE_IPV6; ++ } else { ++ if (strcmp(iface->bootproto, "dhcp") && ++ !strstr(iface->ipaddress, ".")) ++ return ISCSI_IFACE_TYPE_IPV6; ++ else ++ return ISCSI_IFACE_TYPE_IPV4; ++ } + } + + static int iface_setup_binding_from_kern_iface(void *data, +@@ -606,7 +617,7 @@ int iface_match(struct iface_rec *patter + return 1; + + if (!strcmp(pattern->name, iface->name)) { +- if (strcmp(pattern->name, DEFAULT_IFACENAME)) ++ if (!strcmp(pattern->name, DEFAULT_IFACENAME)) + return 1; + /* + * For default we allow the same name, but different +diff -aurp open-iscsi-2.0-872-rc4-bnx2i/usr/iface.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/iface.h +--- open-iscsi-2.0-872-rc4-bnx2i/usr/iface.h 2012-03-06 05:22:41.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iface.h 2012-03-06 05:22:26.000000000 -0600 +@@ -60,6 +60,7 @@ extern int iface_get_param_count(struct + int iface_all); + extern int iface_build_net_config(struct iface_rec *iface_primary, + int iface_all, struct iovec *iovs); ++extern int iface_get_iptype(struct iface_rec *iface); + + #define iface_fmt "[hw=%s,ip=%s,net_if=%s,iscsi_if=%s]" + #define iface_str(_iface) \ +diff -aurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsiadm.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsiadm.c +--- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsiadm.c 2012-03-06 05:22:41.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsiadm.c 2012-03-06 05:23:31.000000000 -0600 +@@ -27,6 +27,7 @@ + #include + #include + #include ++#include + #include + + #include "initiator.h" +@@ -51,6 +52,7 @@ + #include "isns-proto.h" + #include "iscsi_err.h" + #include "iscsi_ipc.h" ++#include "iscsi_timer.h" + + static char program_name[] = "iscsiadm"; + static char config_file[TARGET_NAME_MAXLEN]; +@@ -64,6 +66,8 @@ enum iscsiadm_mode { + MODE_HOST, + MODE_IFACE, + MODE_FW, ++ MODE_PING, ++ MODE_CHAP + }; + + enum iscsiadm_op { +@@ -102,9 +106,13 @@ static struct option const long_options[ + {"show", no_argument, NULL, 'S'}, + {"version", no_argument, NULL, 'V'}, + {"help", no_argument, NULL, 'h'}, ++ {"submode", required_argument, NULL, 'C'}, ++ {"ip", required_argument, NULL, 'a'}, ++ {"packetsize", required_argument, NULL, 'b'}, ++ {"count", required_argument, NULL, 'c'}, + {NULL, 0, NULL, 0}, + }; +-static char *short_options = "RlDVhm:p:P:T:H:I:U:k:L:d:r:n:v:o:sSt:u"; ++static char *short_options = "RlDVhm:a:b:c:C:p:P:T:H:i:I:U:k:L:d:r:n:v:o:sSt:u"; + + static void usage(int status) + { +@@ -116,12 +124,12 @@ static void usage(int status) + iscsiadm -m discoverydb [ -hV ] [ -d debug_level ] [-P printlevel] [ -t type -p ip:port -I ifaceN ... [ -Dl ] ] | [ [ -p ip:port -t type] \ + [ -o operation ] [ -n name ] [ -v value ] [ -lD ] ] \n\ + iscsiadm -m discovery [ -hV ] [ -d debug_level ] [-P printlevel] [ -t type -p ip:port -I ifaceN ... [ -l ] ] | [ [ -p ip:port ] [ -l | -D ] ] \n\ +-iiscsiadm -m node [ -hV ] [ -d debug_level ] [ -P printlevel ] [ -L all,manual,automatic ] [ -U all,manual,automatic ] [ -S ] [ [ -T targetname -p ip:port -I ifaceN ] [ -l | -u | -R | -s] ] \ ++iscsiadm -m node [ -hV ] [ -d debug_level ] [ -P printlevel ] [ -L all,manual,automatic ] [ -U all,manual,automatic ] [ -S ] [ [ -T targetname -p ip:port -I ifaceN ] [ -l | -u | -R | -s] ] \ + [ [ -o operation ] [ -n name ] [ -v value ] ]\n\ + iscsiadm -m session [ -hV ] [ -d debug_level ] [ -P printlevel] [ -r sessionid | sysfsdir [ -R | -u | -s ] [ -o operation ] [ -n name ] [ -v value ] ]\n\ +-iscsiadm -m iface [ -hV ] [ -d debug_level ] [ -P printlevel ] [ -I ifacename | -H hostno|MAC ] [ [ -o operation ] [ -n name ] [ -v value ] ]\n\ ++iscsiadm -m iface [ -hV ] [ -d debug_level ] [ -P printlevel ] [ -I ifacename | -H hostno|MAC ] [ [ -o operation ] [ -n name ] [ -v value ] ] [ -C ping [ -a ip ] [ -b packetsize ] [ -c count ] [ -i interval ] ]\n\ + iscsiadm -m fw [ -l ]\n\ +-iscsiadm -m host [ -P printlevel ] [ -H hostno|MAC ]\n\ ++iscsiadm -m host [ -P printlevel ] [ -H hostno|MAC ] [ -C chap [ -o operation ] [ -v chap_tbl_idx ] ]\n\ + iscsiadm -k priority\n"); + } + exit(status); +@@ -178,6 +186,21 @@ str_to_mode(char *str) + } + + static int ++str_to_submode(char *str) ++{ ++ int sub_mode; ++ ++ if (!strcmp("ping", str)) ++ sub_mode = MODE_PING; ++ else if (!strcmp("chap", str)) ++ sub_mode = MODE_CHAP; ++ else ++ sub_mode = -1; ++ ++ return sub_mode; ++} ++ ++static int + str_to_type(char *str) + { + int type; +@@ -1277,6 +1300,146 @@ free_buf: + return ISCSI_SUCCESS; + } + ++static int get_host_chap_info(uint32_t host_no) ++{ ++ struct iscsi_transport *t = NULL; ++ struct iscsi_chap_rec *crec = NULL; ++ char *req_buf = NULL; ++ uint32_t valid_chap_entries; ++ uint32_t num_entries; ++ uint16_t chap_tbl_idx = 0; ++ int rc = 0; ++ int fd, i = 0; ++ ++ t = iscsi_sysfs_get_transport_by_hba(host_no); ++ if (!t) { ++ log_error("Could not match hostno %d to " ++ "transport.", host_no); ++ rc = ISCSI_ERR_TRANS_NOT_FOUND; ++ goto exit_chap_info; ++ } ++ ++ num_entries = MAX_CHAP_BUF_SZ / sizeof(*crec); ++ ++ req_buf = calloc(1, REQ_CHAP_BUF_SZ); ++ if (!req_buf) { ++ log_error("Could not allocate memory for CHAP request."); ++ rc = ISCSI_ERR_NOMEM; ++ goto exit_chap_info; ++ } ++ ++ fd = ipc->ctldev_open(); ++ if (fd < 0) { ++ rc = ISCSI_ERR_INTERNAL; ++ log_error("Netlink open failed."); ++ goto exit_chap_info; ++ } ++ ++get_chap: ++ memset(req_buf, 0, REQ_CHAP_BUF_SZ); ++ ++ rc = ipc->get_chap(t->handle, host_no, chap_tbl_idx, num_entries, ++ req_buf, &valid_chap_entries); ++ if (rc < 0) { ++ log_error("get_chap_info failed. errno=%d", errno); ++ rc = ISCSI_ERR; ++ goto exit_chap_info; ++ } ++ ++ log_info("Valid CHAP Entries = %d\n", valid_chap_entries); ++ ++ crec = (struct iscsi_chap_rec *) (req_buf + ++ sizeof(struct iscsi_uevent)); ++ ++ if (valid_chap_entries) ++ chap_tbl_idx = ++ (crec + (valid_chap_entries - 1))->chap_tbl_idx + 1; ++ ++ /* print chap info */ ++ for (i = 0; i < valid_chap_entries; i++) { ++ idbm_print_host_chap_info(crec); ++ crec++; ++ } ++ ++ if (valid_chap_entries != num_entries) ++ goto exit_chap_info; ++ else ++ goto get_chap; ++ ++ ipc->ctldev_close(); ++ ++exit_chap_info: ++ if (req_buf) ++ free(req_buf); ++ ++ return rc; ++} ++ ++static int delete_host_chap_info(uint32_t host_no, char *value) ++{ ++ struct iscsi_transport *t = NULL; ++ int fd, rc = 0; ++ uint16_t chap_tbl_idx; ++ ++ if (!value) { ++ log_error("CHAP deletion requires --value=table_index."); ++ return ISCSI_ERR_INVAL; ++ } ++ ++ chap_tbl_idx = (uint16_t)atoi(value); ++ ++ t = iscsi_sysfs_get_transport_by_hba(host_no); ++ if (!t) { ++ log_error("Could not match hostno %d to " ++ "transport.", host_no); ++ rc = ISCSI_ERR_TRANS_NOT_FOUND; ++ goto exit_delete_chap; ++ } ++ ++ fd = ipc->ctldev_open(); ++ if (fd < 0) { ++ log_error("Netlink open failed."); ++ rc = ISCSI_ERR_INTERNAL; ++ goto exit_delete_chap; ++ } ++ ++ log_info("Deleteing CHAP index: %d\n", chap_tbl_idx); ++ rc = ipc->delete_chap(t->handle, host_no, chap_tbl_idx); ++ if (rc < 0) { ++ log_error("CHAP Delete failed."); ++ if (rc == -EBUSY) { ++ rc = ISCSI_ERR_BUSY; ++ log_error("CHAP index %d is in use.", chap_tbl_idx); ++ } else ++ rc = ISCSI_ERR; ++ } ++ ++ ipc->ctldev_close(); ++ ++exit_delete_chap: ++ return rc; ++} ++ ++static int exec_host_chap_op(int op, int info_level, uint32_t host_no, ++ char *value) ++{ ++ int rc = ISCSI_ERR_INVAL; ++ ++ switch (op) { ++ case OP_SHOW: ++ rc = get_host_chap_info(host_no); ++ break; ++ case OP_DELETE: ++ rc = delete_host_chap_info(host_no, value); ++ break; ++ default: ++ log_error("Invalid operation."); ++ break; ++ } ++ ++ return rc; ++} ++ + /* TODO: merge iter helpers and clean them up, so we can use them here */ + static int exec_iface_op(int op, int do_show, int info_level, + struct iface_rec *iface, uint32_t host_no, +@@ -2082,6 +2245,101 @@ static uint32_t parse_host_info(char *op + return host_no; + } + ++static int exec_ping_op(struct iface_rec *iface, char *ip, int size, int count, ++ int interval) ++{ ++ int rc = ISCSI_ERR; ++ uint32_t iface_type = ISCSI_IFACE_TYPE_IPV4; ++ struct iscsi_transport *t = NULL; ++ uint32_t host_no; ++ struct sockaddr_storage addr; ++ int i; ++ ++ if (!iface) { ++ log_error("Ping requires iface."); ++ rc = ISCSI_ERR_INVAL; ++ goto ping_exit; ++ } ++ ++ if (!ip) { ++ log_error("Ping requires destination ipaddress."); ++ rc = ISCSI_ERR_INVAL; ++ goto ping_exit; ++ } ++ ++ if (size <= 0) { ++ log_error("Invalid packet size: %d.", size); ++ rc = ISCSI_ERR_INVAL; ++ goto ping_exit; ++ } ++ ++ if (count <= 0) { ++ log_error("Invalid number of packets to transmit: %d.", count); ++ rc = ISCSI_ERR_INVAL; ++ goto ping_exit; ++ } ++ ++ if (interval < 0) { ++ log_error("Invalid timing interval: %d.", interval); ++ rc = ISCSI_ERR_INVAL; ++ goto ping_exit; ++ } ++ ++ rc = iface_conf_read(iface); ++ if (rc) { ++ log_error("Could not read iface %s (%d).", iface->name, rc); ++ goto ping_exit; ++ } ++ ++ ++ iface_type = iface_get_iptype(iface); ++ ++ t = iscsi_sysfs_get_transport_by_name(iface->transport_name); ++ if (!t) { ++ log_error("Can't find transport."); ++ rc = ISCSI_ERR_INVAL; ++ goto ping_exit; ++ } ++ ++ host_no = iscsi_sysfs_get_host_no_from_hwinfo(iface, &rc); ++ if (host_no == -1) { ++ log_error("Can't find host_no."); ++ rc = ISCSI_ERR_INVAL; ++ goto ping_exit; ++ } ++ ++ rc = resolve_address(ip, NULL, &addr); ++ if (rc) { ++ log_error("Invalid IP address."); ++ rc = ISCSI_ERR_INVAL; ++ goto ping_exit; ++ } ++ ++ /* TODO: move this. It is needed by interface for pid */ ++ srand(time(NULL)); ++ ++ for (i = 1; i <= count; i++) { ++ /* ++ * To support drivers like bnx2i that do not use ++ * the iscsi if to send a ping, we can add a transport ++ * callout here. ++ */ ++ rc = ipc->exec_ping(t->handle, host_no, ++ (struct sockaddr *)&addr, iface->iface_num, ++ iface_type, size); ++ if (!rc) ++ printf("Ping %d completed\n", i); ++ else ++ printf("Ping %d failed: %s\n", i, iscsi_err_to_str(rc)); ++ ++ if (i < count) ++ sleep(interval); ++ } ++ ++ping_exit: ++ return rc; ++} ++ + int + main(int argc, char **argv) + { +@@ -2091,7 +2349,8 @@ main(int argc, char **argv) + int rc=0, sid=-1, op=OP_NOOP, type=-1, do_logout=0, do_stats=0; + int do_login_all=0, do_logout_all=0, info_level=-1, num_ifaces = 0; + int tpgt = PORTAL_GROUP_TAG_UNKNOWN, killiscsid=-1, do_show=0; +- int do_discover = 0; ++ int packet_size=32, ping_count=1, ping_interval=0; ++ int do_discover = 0, sub_mode = -1; + struct sigaction sa_old; + struct sigaction sa_new; + struct list_head ifaces; +@@ -2196,12 +2455,27 @@ main(int argc, char **argv) + case 'm': + mode = str_to_mode(optarg); + break; ++ case 'C': ++ sub_mode = str_to_submode(optarg); ++ break; + case 'T': + targetname = optarg; + break; + case 'p': + ip = str_to_ipport(optarg, &port, &tpgt); + break; ++ case 'a': ++ ip = optarg; ++ break; ++ case 'b': ++ packet_size = atoi(optarg); ++ break; ++ case 'c': ++ ping_count = atoi(optarg); ++ break; ++ case 'i': ++ ping_interval = atoi(optarg); ++ break; + case 'I': + iface = iface_alloc(optarg, &rc); + if (rc == ISCSI_ERR_INVAL) { +@@ -2262,19 +2536,35 @@ main(int argc, char **argv) + + switch (mode) { + case MODE_HOST: +- if ((rc = verify_mode_params(argc, argv, "HdmP", 0))) { ++ if ((rc = verify_mode_params(argc, argv, "CHdmPov", 0))) { + log_error("host mode: option '-%c' is not " + "allowed/supported", rc); + rc = ISCSI_ERR_INVAL; + goto out; + } +- +- rc = host_info_print(info_level, host_no); ++ if (sub_mode != -1) { ++ switch (sub_mode) { ++ case MODE_CHAP: ++ if (!op || !host_no) { ++ log_error("CHAP mode requires host " ++ "no and valid operation"); ++ rc = ISCSI_ERR_INVAL; ++ break; ++ } ++ rc = exec_host_chap_op(op, info_level, host_no, ++ value); ++ break; ++ default: ++ log_error("Invalid Sub Mode"); ++ break; ++ } ++ } else ++ rc = host_info_print(info_level, host_no); + break; + case MODE_IFACE: + iface_setup_host_bindings(); + +- if ((rc = verify_mode_params(argc, argv, "HIdnvmPo", 0))) { ++ if ((rc = verify_mode_params(argc, argv, "HIdnvmPoCabci", 0))) { + log_error("iface mode: option '-%c' is not " + "allowed/supported", rc); + rc = ISCSI_ERR_INVAL; +@@ -2289,8 +2579,14 @@ main(int argc, char **argv) + "interface. Using the first one " + "%s.", iface->name); + } +- rc = exec_iface_op(op, do_show, info_level, iface, host_no, +- name, value); ++ ++ if (sub_mode == MODE_PING) ++ rc = exec_ping_op(iface, ip, packet_size, ping_count, ++ ping_interval); ++ else ++ rc = exec_iface_op(op, do_show, info_level, iface, ++ host_no, name, value); ++ + break; + case MODE_DISCOVERYDB: + if ((rc = verify_mode_params(argc, argv, "DSIPdmntplov", 0))) { +diff -aurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_err.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_err.c +--- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_err.c 2012-03-06 05:22:41.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_err.c 2012-03-06 05:22:26.000000000 -0600 +@@ -49,7 +49,9 @@ static char *iscsi_err_msgs[] = { + /* 24 */ "iSCSI login failed due to authorization failure", + /* 25 */ "iSNS query failed", + /* 26 */ "iSNS registration failed", +- /* 27 */ "Retryable failure", ++ /* 27 */ "operation not supported", ++ /* 28 */ "device or resource in use", ++ /* 29 */ "Retryable failure", + }; + + char *iscsi_err_to_str(int err) +diff -aurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_ipc.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_ipc.h +--- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_ipc.h 2012-03-06 05:22:41.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_ipc.h 2012-03-06 05:22:26.000000000 -0600 +@@ -134,6 +134,17 @@ struct iscsi_ipc { + struct iovec *iovs, uint32_t param_count); + + int (*recv_conn_state) (struct iscsi_conn *conn, uint32_t *state); ++ ++ int (*exec_ping) (uint64_t transport_handle, uint32_t host_no, ++ struct sockaddr *addr, uint32_t iface_num, ++ uint32_t iface_type, uint32_t size); ++ ++ int (*get_chap) (uint64_t transport_handle, uint32_t host_no, ++ uint16_t chap_tbl_idx, uint32_t num_entries, ++ char *chap_buf, uint32_t *valid_chap_entries); ++ ++ int (*delete_chap) (uint64_t transport_handle, uint32_t host_no, ++ uint16_t chap_tbl_idx); + }; + + struct iscsi_ipc *ipc; +diff -aurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/netlink.c +--- open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c 2012-03-06 05:22:41.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/netlink.c 2012-03-06 05:23:02.000000000 -0600 +@@ -25,10 +25,12 @@ + #include + #include + #include ++#include + #include + #include + #include + #include ++#include + #include + + #include "types.h" +@@ -39,6 +41,8 @@ + #include "iscsi_sysfs.h" + #include "transport.h" + #include "iscsi_netlink.h" ++#include "iscsi_err.h" ++#include "iscsi_timer.h" + + static int ctrl_fd; + static struct sockaddr_nl src_addr, dest_addr; +@@ -64,6 +68,15 @@ static int ctldev_handle(void); + + #define NLM_SETPARAM_DEFAULT_MAX (NI_MAXHOST + 1 + sizeof(struct iscsi_uevent)) + ++struct iscsi_ping_event { ++ uint32_t host_no; ++ uint32_t pid; ++ int32_t status; ++ int active; ++}; ++ ++struct iscsi_ping_event ping_event; ++ + struct nlattr *iscsi_nla_alloc(uint16_t type, uint16_t len) + { + struct nlattr *attr; +@@ -323,6 +336,9 @@ __kipc_call(struct iovec *iovp, int coun + } else if (ev->type == ISCSI_UEVENT_GET_STATS) { + /* kget_stats() will read */ + return 0; ++ } else if (ev->type == ISCSI_UEVENT_GET_CHAP) { ++ /* kget_chap() will read */ ++ return 0; + } else { + if ((rc = nlpayload_read(ctrl_fd, (void*)ev, + sizeof(*ev), 0)) < 0) { +@@ -1002,7 +1018,7 @@ kset_net_config(uint64_t transport_handl + return 0; + } + +-static int krecv_conn_state(struct iscsi_conn *conn, int *state) ++static int krecv_conn_state(struct iscsi_conn *conn, uint32_t *state) + { + int rc; + +@@ -1024,6 +1040,218 @@ exit: + return rc; + } + ++ ++ ++ ++static int ++ksend_ping(uint64_t transport_handle, uint32_t host_no, struct sockaddr *addr, ++ uint32_t iface_num, uint32_t iface_type, uint32_t pid, uint32_t size) ++{ ++ int rc, addrlen; ++ struct iscsi_uevent *ev; ++ struct iovec iov[2]; ++ ++ log_debug(8, "in %s", __FUNCTION__); ++ ++ memset(setparam_buf, 0, NLM_SETPARAM_DEFAULT_MAX); ++ ev = (struct iscsi_uevent *)setparam_buf; ++ ev->type = ISCSI_UEVENT_PING; ++ ev->transport_handle = transport_handle; ++ ev->u.iscsi_ping.host_no = host_no; ++ ev->u.iscsi_ping.iface_num = iface_num; ++ ev->u.iscsi_ping.iface_type = iface_type; ++ ev->u.iscsi_ping.payload_size = size; ++ ev->u.iscsi_ping.pid = pid; ++ ++ if (addr->sa_family == PF_INET) ++ addrlen = sizeof(struct sockaddr_in); ++ else if (addr->sa_family == PF_INET6) ++ addrlen = sizeof(struct sockaddr_in6); ++ else { ++ log_error("%s unknown addr family %d\n", ++ __FUNCTION__, addr->sa_family); ++ return -EINVAL; ++ } ++ memcpy(setparam_buf + sizeof(*ev), addr, addrlen); ++ ++ iov[1].iov_base = ev; ++ iov[1].iov_len = sizeof(*ev) + addrlen; ++ rc = __kipc_call(iov, 2); ++ if (rc < 0) ++ return rc; ++ ++ return 0; ++} ++ ++static int kexec_ping(uint64_t transport_handle, uint32_t host_no, ++ struct sockaddr *addr, uint32_t iface_num, ++ uint32_t iface_type, uint32_t size) ++{ ++ struct pollfd pfd; ++ struct timeval ping_timer; ++ int timeout, fd, rc; ++ uint32_t pid; ++ ++ fd = ipc->ctldev_open(); ++ if (fd < 0) { ++ log_error("Could not open netlink socket."); ++ return ISCSI_ERR; ++ } ++ ++ /* prepare to poll */ ++ memset(&pfd, 0, sizeof(pfd)); ++ pfd.fd = fd; ++ pfd.events = POLLIN | POLLPRI; ++ ++ /* get unique ping id */ ++ pid = rand(); ++ ++ rc = ksend_ping(transport_handle, host_no, addr, iface_num, ++ iface_type, pid, size); ++ if (rc != 0) { ++ switch (rc) { ++ case -ENOSYS: ++ rc = ISCSI_ERR_OP_NOT_SUPP; ++ break; ++ case -EINVAL: ++ rc = ISCSI_ERR_INVAL; ++ break; ++ default: ++ rc = ISCSI_ERR; ++ } ++ goto close_nl; ++ } ++ ++ ping_event.host_no = -1; ++ ping_event.pid = -1; ++ ping_event.status = -1; ++ ping_event.active = -1; ++ ++ iscsi_timer_set(&ping_timer, 30); ++ ++ timeout = iscsi_timer_msecs_until(&ping_timer); ++ ++ while (1) { ++ pfd.revents = 0; ++ rc = poll(&pfd, 1, timeout); ++ ++ if (iscsi_timer_expired(&ping_timer)) { ++ rc = ISCSI_ERR_TRANS_TIMEOUT; ++ break; ++ } ++ ++ if (rc > 0) { ++ if (pfd.revents & (POLLIN | POLLPRI)) { ++ timeout = iscsi_timer_msecs_until(&ping_timer); ++ rc = ipc->ctldev_handle(); ++ ++ if (ping_event.active != 1) ++ continue; ++ ++ if (pid != ping_event.pid) ++ continue; ++ ++ if (ping_event.status == 0) ++ rc = 0; ++ else ++ rc = ISCSI_ERR; ++ break; ++ } ++ ++ if (pfd.revents & POLLHUP) { ++ rc = ISCSI_ERR_TRANS; ++ break; ++ } ++ ++ if (pfd.revents & POLLNVAL) { ++ rc = ISCSI_ERR_INTERNAL; ++ break; ++ } ++ ++ if (pfd.revents & POLLERR) { ++ rc = ISCSI_ERR_INTERNAL; ++ break; ++ } ++ } else if (rc < 0) { ++ rc = ISCSI_ERR_INTERNAL; ++ break; ++ } ++ } ++ ++close_nl: ++ ipc->ctldev_close(); ++ return rc; ++} ++ ++static int kget_chap(uint64_t transport_handle, uint32_t host_no, ++ uint16_t chap_tbl_idx, uint32_t num_entries, ++ char *chap_buf, uint32_t *valid_chap_entries) ++{ ++ int rc = 0; ++ int ev_size; ++ struct iscsi_uevent ev; ++ struct iovec iov[2]; ++ char nlm_ev[NLMSG_SPACE(sizeof(struct iscsi_uevent))]; ++ struct nlmsghdr *nlh; ++ ++ memset(&ev, 0, sizeof(struct iscsi_uevent)); ++ ++ ev.type = ISCSI_UEVENT_GET_CHAP; ++ ev.transport_handle = transport_handle; ++ ev.u.get_chap.host_no = host_no; ++ ev.u.get_chap.chap_tbl_idx = chap_tbl_idx; ++ ev.u.get_chap.num_entries = num_entries; ++ ++ iov[1].iov_base = &ev; ++ iov[1].iov_len = sizeof(ev); ++ rc = __kipc_call(iov, 2); ++ if (rc < 0) ++ return rc; ++ ++ if ((rc = nl_read(ctrl_fd, nlm_ev, ++ NLMSG_SPACE(sizeof(struct iscsi_uevent)), ++ MSG_PEEK)) < 0) { ++ log_error("can not read nlm_ev, error %d", rc); ++ return rc; ++ } ++ ++ nlh = (struct nlmsghdr *)nlm_ev; ++ ev_size = nlh->nlmsg_len - NLMSG_ALIGN(sizeof(struct nlmsghdr)); ++ ++ if ((rc = nlpayload_read(ctrl_fd, (void *)chap_buf, ev_size, 0)) < 0) { ++ log_error("can not read from NL socket, error %d", rc); ++ return rc; ++ } ++ ++ *valid_chap_entries = ev.u.get_chap.num_entries; ++ ++ return rc; ++} ++ ++static int kdelete_chap(uint64_t transport_handle, uint32_t host_no, ++ uint16_t chap_tbl_idx) ++{ ++ int rc = 0; ++ struct iscsi_uevent ev; ++ struct iovec iov[2]; ++ ++ memset(&ev, 0, sizeof(struct iscsi_uevent)); ++ ++ ev.type = ISCSI_UEVENT_DELETE_CHAP; ++ ev.transport_handle = transport_handle; ++ ev.u.delete_chap.host_no = host_no; ++ ev.u.delete_chap.chap_tbl_idx = chap_tbl_idx; ++ ++ iov[1].iov_base = &ev; ++ iov[1].iov_len = sizeof(ev); ++ ++ rc = __kipc_call(iov, 2); ++ if (rc < 0) ++ return rc; ++ ++ return rc; ++} ++ + static void drop_data(struct nlmsghdr *nlh) + { + int ev_size; +@@ -1041,7 +1269,7 @@ static int ctldev_handle(void) + char nlm_ev[NLMSG_SPACE(sizeof(struct iscsi_uevent))]; + struct nlmsghdr *nlh; + struct iscsi_ev_context *ev_context; +- uint32_t sid = 0, cid = 0, state = 0; ++ uint32_t sid = 0, cid = 0; + + log_debug(7, "in %s", __FUNCTION__); + +@@ -1060,11 +1288,17 @@ static int ctldev_handle(void) + /* old kernels sent ISCSI_UEVENT_CREATE_SESSION on creation */ + case ISCSI_UEVENT_CREATE_SESSION: + drop_data(nlh); ++ if (!ipc_ev_clbk) ++ return 0; ++ + if (ipc_ev_clbk->create_session) + ipc_ev_clbk->create_session(ev->r.c_session_ret.host_no, + ev->r.c_session_ret.sid); + return 0; + case ISCSI_KEVENT_DESTROY_SESSION: ++ if (!ipc_ev_clbk) ++ return 0; ++ + drop_data(nlh); + if (ipc_ev_clbk->destroy_session) + ipc_ev_clbk->destroy_session(ev->r.d_session.host_no, +@@ -1081,7 +1315,6 @@ static int ctldev_handle(void) + case ISCSI_KEVENT_CONN_LOGIN_STATE: + sid = ev->r.conn_login.sid; + cid = ev->r.conn_login.cid; +- state = ev->r.conn_login.state; + break; + case ISCSI_KEVENT_UNBIND_SESSION: + sid = ev->r.unbind_session.sid; +@@ -1106,6 +1339,14 @@ static int ctldev_handle(void) + + drop_data(nlh); + return 0; ++ case ISCSI_KEVENT_PING_COMP: ++ ping_event.host_no = ev->r.ping_comp.host_no; ++ ping_event.pid = ev->r.ping_comp.pid; ++ ping_event.status = ev->r.ping_comp.status; ++ ping_event.active = 1; ++ ++ drop_data(nlh); ++ return 0; + default: + if ((ev->type > ISCSI_UEVENT_MAX && ev->type < KEVENT_BASE) || + (ev->type > ISCSI_KEVENT_MAX)) +@@ -1299,6 +1540,9 @@ struct iscsi_ipc nl_ipc = { + .recv_pdu_end = krecv_pdu_end, + .set_net_config = kset_net_config, + .recv_conn_state = krecv_conn_state, ++ .exec_ping = kexec_ping, ++ .get_chap = kget_chap, ++ .delete_chap = kdelete_chap, + }; + struct iscsi_ipc *ipc = &nl_ipc; + diff --git a/iscsi-initiator-utils-sync-iscsi.patch b/iscsi-initiator-utils-sync-iscsi.patch index bde2f24..3d52d45 100644 --- a/iscsi-initiator-utils-sync-iscsi.patch +++ b/iscsi-initiator-utils-sync-iscsi.patch @@ -1,6 +1,6 @@ -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/Changelog open-iscsi-2.0-872-rc4-bnx2i.sync/Changelog +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/Changelog open-iscsi-2.0-872-rc4-bnx2i.work/Changelog --- open-iscsi-2.0-872-rc4-bnx2i/Changelog 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/Changelog 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/Changelog 2012-03-05 23:02:46.000000000 -0600 @@ -1,132 +1,114 @@ -open-iscsi-2.0-871 - open-iscsi-2.0.870 +open-iscsi-2.0-872 - open-iscsi-2.0.871 @@ -243,9 +243,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/Changelog open-iscsi-2.0-872-rc4-bnx2i. +Wulf C. Krueger (1): + Use DESTDIR when generating an InitiatorName. -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/doc/iscsiadm.8 open-iscsi-2.0-872-rc4-bnx2i.sync/doc/iscsiadm.8 +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/doc/iscsiadm.8 open-iscsi-2.0-872-rc4-bnx2i.work/doc/iscsiadm.8 --- open-iscsi-2.0-872-rc4-bnx2i/doc/iscsiadm.8 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/doc/iscsiadm.8 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/doc/iscsiadm.8 2012-03-05 23:02:46.000000000 -0600 @@ -10,13 +10,13 @@ iscsiadm \- open-iscsi administration ut \fBiscsiadm\fR \-m node [ \-hV ] [ \-d debug_level ] [ \-P printlevel ] [ \-L all,manual,automatic ] [ \-U all,manual,automatic ] [ \-S ] [ [ \-T targetname \-p ip:port \-I iface ] [ \-l | \-u | \-R | \-s] ] [ [ \-o operation ] [ \-n name ] [ \-v value ] [ \-p ip:port ] ] @@ -475,10 +475,10 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/doc/iscsiadm.8 open-iscsi-2.0-872-rc4-b .SH EXAMPLES .nf -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/doc/iscsid.8 open-iscsi-2.0-872-rc4-bnx2i.sync/doc/iscsid.8 +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/doc/iscsid.8 open-iscsi-2.0-872-rc4-bnx2i.work/doc/iscsid.8 --- open-iscsi-2.0-872-rc4-bnx2i/doc/iscsid.8 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/doc/iscsid.8 2011-08-14 16:48:25.000000000 -0500 -@@ -35,6 +35,9 @@ run under user ID \fIuid\fR (default is ++++ open-iscsi-2.0-872-rc4-bnx2i.work/doc/iscsid.8 2012-03-05 23:02:46.000000000 -0600 +@@ -35,6 +35,9 @@ run under user ID \fIuid\fR (default is .BI [-g|--gid=]\fIgid\fP run under user group ID \fIgid\fR (default is the current user group ID). .TP @@ -488,9 +488,23 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/doc/iscsid.8 open-iscsi-2.0-872-rc4-bnx .BI [-p|--pid=]\fIpid\-file\fP write process ID to \fIpid\-file\fR rather than the default \fI/var/run/iscsid.pid\fR -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/etc/iface.example open-iscsi-2.0-872-rc4-bnx2i.sync/etc/iface.example +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/doc/iscsistart.8 open-iscsi-2.0-872-rc4-bnx2i.work/doc/iscsistart.8 +--- open-iscsi-2.0-872-rc4-bnx2i/doc/iscsistart.8 2010-07-11 04:05:58.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/doc/iscsistart.8 2012-03-05 23:06:00.000000000 -0600 +@@ -51,6 +51,10 @@ Bring up the network as specified by iBF + .BI [-f|--fwparam_print] + Print the iBFT or OF info to STDOUT + .TP ++.BI [-P|--param=]\fINAME=VALUE\fP ++Set the parameter with the name NAME to VALUE. NAME is one of the settings ++in the node record or iscsid.conf. Multiple params can be passed in. ++.TP + .BI [-h|--help] + Display this help and exit + .TP +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/etc/iface.example open-iscsi-2.0-872-rc4-bnx2i.work/etc/iface.example --- open-iscsi-2.0-872-rc4-bnx2i/etc/iface.example 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/etc/iface.example 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/etc/iface.example 2012-03-05 23:02:46.000000000 -0600 @@ -60,3 +60,138 @@ # the same subnet. # iface.net_ifacename = eth0 @@ -630,9 +644,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/etc/iface.example open-iscsi-2.0-872-rc +# iface.vlan = +# iface.iface_num = 0 +# END RECORD -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/etc/initd/boot.suse open-iscsi-2.0-872-rc4-bnx2i.sync/etc/initd/boot.suse +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/etc/initd/boot.suse open-iscsi-2.0-872-rc4-bnx2i.work/etc/initd/boot.suse --- open-iscsi-2.0-872-rc4-bnx2i/etc/initd/boot.suse 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/etc/initd/boot.suse 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/etc/initd/boot.suse 2012-03-05 23:02:46.000000000 -0600 @@ -4,36 +4,37 @@ # ### BEGIN INIT INFO @@ -713,9 +727,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/etc/initd/boot.suse open-iscsi-2.0-872- exit 1 ;; esac -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/etc/initd/initd.suse open-iscsi-2.0-872-rc4-bnx2i.sync/etc/initd/initd.suse +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/etc/initd/initd.suse open-iscsi-2.0-872-rc4-bnx2i.work/etc/initd/initd.suse --- open-iscsi-2.0-872-rc4-bnx2i/etc/initd/initd.suse 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/etc/initd/initd.suse 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/etc/initd/initd.suse 2012-03-05 23:02:46.000000000 -0600 @@ -5,20 +5,22 @@ ### BEGIN INIT INFO # Provides: iscsi @@ -1262,9 +1276,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/etc/initd/initd.suse open-iscsi-2.0-872 exit 1 ;; esac -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/etc/iscsid.conf open-iscsi-2.0-872-rc4-bnx2i.sync/etc/iscsid.conf +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/etc/iscsid.conf open-iscsi-2.0-872-rc4-bnx2i.work/etc/iscsid.conf --- open-iscsi-2.0-872-rc4-bnx2i/etc/iscsid.conf 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/etc/iscsid.conf 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/etc/iscsid.conf 2012-03-05 23:02:46.000000000 -0600 @@ -39,6 +39,10 @@ iscsid.startup = /sbin/iscsid # To manually startup the session set to "manual". The default is manual. node.startup = manual @@ -1288,9 +1302,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/etc/iscsid.conf open-iscsi-2.0-872-rc4- #************ # Workarounds -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/include/iscsi_err.h open-iscsi-2.0-872-rc4-bnx2i.sync/include/iscsi_err.h +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/include/iscsi_err.h open-iscsi-2.0-872-rc4-bnx2i.work/include/iscsi_err.h --- open-iscsi-2.0-872-rc4-bnx2i/include/iscsi_err.h 1969-12-31 18:00:00.000000000 -0600 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/include/iscsi_err.h 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/include/iscsi_err.h 2012-03-05 23:02:46.000000000 -0600 @@ -0,0 +1,69 @@ +/* + * Return codes used by iSCSI tools. @@ -1361,9 +1375,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/include/iscsi_err.h open-iscsi-2.0-872- +extern char *iscsi_err_to_str(int err); + +#endif -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/include/iscsi_if.h open-iscsi-2.0-872-rc4-bnx2i.sync/include/iscsi_if.h +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/include/iscsi_if.h open-iscsi-2.0-872-rc4-bnx2i.work/include/iscsi_if.h --- open-iscsi-2.0-872-rc4-bnx2i/include/iscsi_if.h 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/include/iscsi_if.h 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/include/iscsi_if.h 2012-03-05 23:06:18.000000000 -0600 @@ -64,6 +64,9 @@ enum iscsi_uevent_e { ISCSI_UEVENT_TRANSPORT_EP_CONNECT_THROUGH_HOST = UEVENT_BASE + 19, @@ -1374,17 +1388,32 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/include/iscsi_if.h open-iscsi-2.0-872-r /* up events */ ISCSI_KEVENT_RECV_PDU = KEVENT_BASE + 1, -@@ -75,6 +78,9 @@ enum iscsi_uevent_e { +@@ -75,6 +78,10 @@ enum iscsi_uevent_e { ISCSI_KEVENT_PATH_REQ = KEVENT_BASE + 7, ISCSI_KEVENT_IF_DOWN = KEVENT_BASE + 8, + ISCSI_KEVENT_CONN_LOGIN_STATE = KEVENT_BASE + 9, ++ ISCSI_KEVENT_HOST_EVENT = KEVENT_BASE + 10, + -+ ISCSI_KEVENT_MAX = ISCSI_KEVENT_CONN_LOGIN_STATE, ++ ISCSI_KEVENT_MAX = ISCSI_KEVENT_HOST_EVENT, }; enum iscsi_tgt_dscvr { -@@ -177,6 +183,10 @@ struct iscsi_uevent { +@@ -83,6 +90,13 @@ enum iscsi_tgt_dscvr { + ISCSI_TGT_DSCVR_SLP = 3, + }; + ++enum iscsi_host_event_code { ++ ISCSI_EVENT_LINKUP = 1, ++ ISCSI_EVENT_LINKDOWN, ++ /* must always be last */ ++ ISCSI_EVENT_MAX, ++}; ++ + struct iscsi_uevent { + uint32_t type; /* k/u events type */ + uint32_t iferror; /* carries interface or resource errors */ +@@ -177,6 +191,10 @@ struct iscsi_uevent { struct msg_set_path { uint32_t host_no; } set_path; @@ -1395,7 +1424,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/include/iscsi_if.h open-iscsi-2.0-872-r } u; union { /* messages k -> u */ -@@ -198,6 +208,11 @@ struct iscsi_uevent { +@@ -198,6 +216,11 @@ struct iscsi_uevent { uint32_t cid; uint64_t recv_handle; } recv_req; @@ -1407,7 +1436,15 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/include/iscsi_if.h open-iscsi-2.0-872-r struct msg_conn_error { uint32_t sid; uint32_t cid; -@@ -219,6 +234,21 @@ struct iscsi_uevent { +@@ -216,9 +239,29 @@ struct iscsi_uevent { + struct msg_notify_if_down { + uint32_t host_no; + } notify_if_down; ++ struct msg_host_event { ++ uint32_t host_no; ++ uint32_t data_size; ++ enum iscsi_host_event_code code; ++ } host_event; } r; } __attribute__ ((aligned (sizeof(uint64_t)))); @@ -1429,7 +1466,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/include/iscsi_if.h open-iscsi-2.0-872-r /* * To keep the struct iscsi_uevent size the same for userspace code * compatibility, the main structure for ISCSI_UEVENT_PATH_UPDATE and -@@ -242,6 +272,70 @@ struct iscsi_path { +@@ -242,6 +285,71 @@ struct iscsi_path { uint16_t pmtu; } __attribute__ ((aligned (sizeof(uint64_t)))); @@ -1481,10 +1518,11 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/include/iscsi_if.h open-iscsi-2.0-872-r + ISCSI_NET_PARAM_VLAN_ID = 13, + ISCSI_NET_PARAM_VLAN_PRIORITY = 14, + ISCSI_NET_PARAM_VLAN_ENABLED = 15, -+ ISCSI_NET_PARAM_IFACE_TYPE = 16, -+ ISCSI_NET_PARAM_IFACE_NAME = 17, -+ ISCSI_NET_PARAM_MTU = 18, -+ ISCSI_NET_PARAM_PORT = 19, ++ ISCSI_NET_PARAM_VLAN_TAG = 16, ++ ISCSI_NET_PARAM_IFACE_TYPE = 17, ++ ISCSI_NET_PARAM_IFACE_NAME = 18, ++ ISCSI_NET_PARAM_MTU = 19, ++ ISCSI_NET_PARAM_PORT = 20, +}; + +enum iscsi_conn_state { @@ -1500,7 +1538,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/include/iscsi_if.h open-iscsi-2.0-872-r /* * Common error codes */ -@@ -268,6 +362,7 @@ enum iscsi_err { +@@ -268,6 +376,7 @@ enum iscsi_err { ISCSI_ERR_INVALID_HOST = ISCSI_ERR_BASE + 18, ISCSI_ERR_XMIT_FAILED = ISCSI_ERR_BASE + 19, ISCSI_ERR_TCP_CONN_CLOSE = ISCSI_ERR_BASE + 20, @@ -1508,7 +1546,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/include/iscsi_if.h open-iscsi-2.0-872-r }; /* -@@ -296,7 +391,7 @@ enum iscsi_param { +@@ -296,7 +405,7 @@ enum iscsi_param { ISCSI_PARAM_PERSISTENT_PORT, ISCSI_PARAM_SESS_RECOVERY_TMO, @@ -1517,7 +1555,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/include/iscsi_if.h open-iscsi-2.0-872-r ISCSI_PARAM_CONN_PORT, ISCSI_PARAM_CONN_ADDRESS, -@@ -318,6 +413,7 @@ enum iscsi_param { +@@ -318,6 +427,7 @@ enum iscsi_param { ISCSI_PARAM_INITIATOR_NAME, ISCSI_PARAM_TGT_RESET_TMO, @@ -1525,7 +1563,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/include/iscsi_if.h open-iscsi-2.0-872-r /* must always be last */ ISCSI_PARAM_MAX, }; -@@ -358,6 +454,7 @@ enum iscsi_param { +@@ -358,6 +468,7 @@ enum iscsi_param { #define ISCSI_ISID (1ULL << ISCSI_PARAM_ISID) #define ISCSI_INITIATOR_NAME (1ULL << ISCSI_PARAM_INITIATOR_NAME) #define ISCSI_TGT_RESET_TMO (1ULL << ISCSI_PARAM_TGT_RESET_TMO) @@ -1533,7 +1571,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/include/iscsi_if.h open-iscsi-2.0-872-r /* iSCSI HBA params */ enum iscsi_host_param { -@@ -394,6 +491,7 @@ enum iscsi_host_param { +@@ -394,6 +505,7 @@ enum iscsi_host_param { #define CAP_DIGEST_OFFLOAD 0x1000 /* offload hdr and data digests */ #define CAP_PADDING_OFFLOAD 0x2000 /* offload padding insertion, removal, and verification */ @@ -1541,9 +1579,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/include/iscsi_if.h open-iscsi-2.0-872-r /* * These flags describes reason of stop_conn() call -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/Makefile open-iscsi-2.0-872-rc4-bnx2i.sync/Makefile +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/Makefile open-iscsi-2.0-872-rc4-bnx2i.work/Makefile --- open-iscsi-2.0-872-rc4-bnx2i/Makefile 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/Makefile 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/Makefile 2012-03-05 23:04:27.000000000 -0600 @@ -24,10 +24,10 @@ IFACEFILES = etc/iface.example # using '$(MAKE)' instead of just 'make' allows make to run in parallel # over multiple makefile. @@ -1551,13 +1589,24 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/Makefile open-iscsi-2.0-872-rc4-bnx2i.s -all: user kernel +all: user - user: ; +-user: ; - cd utils/open-isns; ./configure; $(MAKE) -+ cd utils/open-isns; ./configure --with-security=no; $(MAKE) ++user: utils/open-isns/Makefile ++ $(MAKE) -C utils/open-isns $(MAKE) -C utils/sysdeps $(MAKE) -C utils/fwparam_ibft $(MAKE) -C usr -@@ -68,7 +68,7 @@ clean: +@@ -41,6 +41,9 @@ user: ; + @echo + @echo "Read README file for detailed information." + ++utils/open-isns/Makefile: utils/open-isns/configure utils/open-isns/Makefile.in ++ cd utils/open-isns; ./configure CFLAGS="$(OPTFLAGS)" --with-security=no ++ + kernel: force + $(MAKE) -C kernel + @echo "Kernel Compilation complete Output file" +@@ -68,7 +71,7 @@ clean: install_initd_suse install_initd_redhat install_initd_debian \ install_etc install_iface install_doc install_kernel install_iname @@ -1566,9 +1615,18 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/Makefile open-iscsi-2.0-872-rc4-bnx2i.s install_initd install_iname install_iface install_user: install_programs install_doc install_etc \ -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/README open-iscsi-2.0-872-rc4-bnx2i.sync/README +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/README open-iscsi-2.0-872-rc4-bnx2i.work/README --- open-iscsi-2.0-872-rc4-bnx2i/README 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/README 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/README 2012-03-05 23:03:47.000000000 -0600 +@@ -166,7 +166,7 @@ term node to refer to a portal on a targ + require that --targetname and --portal argument be used when in node mode. + + For session mode, a session id (sid) is used. The sid of a session can be +-found by running iscsiadm -m session -i. The session id is not currently ++found by running iscsiadm -m session -P 1. The session id is not currently + persistent and is partially determined by when the session is setup. + + Note that some of the iSCSI Node and iSCSI Discovery operations @@ -371,9 +371,10 @@ Usage: iscsiadm [OPTION] iscsi_ifacename. @@ -1719,418 +1777,10 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/README open-iscsi-2.0-872-rc4-bnx2i.syn - iSCSI Login to a specific portal through the NIC setup as iface0: ./iscsiadm -m node -T iqn.2005-03.com.max -p 192.168.0.4:3260 \ -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/TODO open-iscsi-2.0-872-rc4-bnx2i.sync/TODO ---- open-iscsi-2.0-872-rc4-bnx2i/TODO 1969-12-31 18:00:00.000000000 -0600 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/TODO 2011-08-14 16:48:25.000000000 -0500 -@@ -0,0 +1,404 @@ -+iSCSI DEVELOPMENT HOWTO AND TODO -+-------------------------------- -+July 7th 2011 -+ -+ -+If you are admin or user and just want to send a fix, just send the fix any -+way you can. We can port the patch to the proper tree and fix up the patch -+for you. Engineers that would like to do more advanced development then the -+following guideline should be followed. -+ -+Submitting Patches -+------------------ -+Code should follow the Linux kernel codying style doc: -+http://www.kernel.org/doc/Documentation/CodingStyle -+ -+Patches should be submitted to the open-iscsi list open-iscsi@googlegroups.com. -+They should be made with "git diff" or "diff -up" or "diff -uprN", and -+kernel patches must have a "Signed-off-by" line. See section 12 -+http://www.kernel.org/doc/Documentation/SubmittingPatches for more -+information on the the signed off line. -+ -+Getting the Code -+---------------- -+Kernel patches should be made against the linux-2.6-iscsi tree. This can -+be downloaded from kernel.org with git with the following commands: -+ -+git clone git://git.kernel.org/pub/scm/linux/kernel/git/mnc/linux-2.6-iscsi.git -+ -+Userspace patches should be made against the open-iscsi git tree: -+ -+git clone git://git.kernel.org/pub/scm/linux/kernel/git/mnc/open-iscsi.git -+ -+ -+ -+KERNEL TODO ITEMS -+----------------- -+ -+1. Make iSCSI log messages humanly readable. In many cases the iscsi tools -+and modules will log a error number value. The most well known is conn -+error 1011. Users should not have to search on google for what this means. -+ -+We should: -+ -+1. Write a simple table to convert the error values to a string and print -+them out. -+ -+2. Document the values, how you commonly hit them and common solutions -+in the iSCSI docs. -+ -+See scsi_transport_iscsi.c:iscsi_conn_error_event for where the evil -+"detected conn error 1011" is printed. See the enum iscsi_err in iscsi_if.h -+for a definition of the error code values. -+ -+--------------------------------------------------------------------------- -+ -+2. Implement iSCSI dev loss support. -+ -+Currently if a session is down for longer than replacement/recovery_timeout -+seconds, the iscsi layer will unblock the devices and fail IO. Other -+transport, like FC and SAS, will do something similar. FC has a -+fast_io_fail tmo which will unblock devices and fail IO, then it has a -+dev_loss_tmo which will delete the devices accessed through that port. -+ -+iSCSI needs to implement dev_loss_tmo behavior, because apps are beginning -+to expect this behavior. An initial path was made here: -+http://groups.google.com/group/open-iscsi/msg/031510ab4cecccfd?dmode=source -+ -+Since all drivers want this behavior we want to make it common. We need to -+change the patch in that link to add a dev_loss_tmo handler callback to the -+scsi_transport_template struct, and add some common sysfs and helpers -+functions to manage the dev_loss_tmo variable. -+ -+ -+*Being worked on by Vikek S -+ -+--------------------------------------------------------------------------- -+ -+3. Reduce locking contention between session lock. -+ -+The session lock is basically one big lock that protects everything -+in the iscsi_session. This lock could be broken down into smaller locks -+and maybe even replaced with something that would not require a lock. -+ -+For example: -+ -+1. The session lock serializes access to the current R2T the initiator is -+handling (a R2T from the target or the initialR2T if being used). libiscsi/ -+libiscsi_tcp will call iscsi_tcp_get_curr_r2t and grab the session lock in -+the xmit path from the xmit thread and then in the recv path -+libiscsi_tcp/iscsi_tcp will call iscsi_tcp_r2t_rsp (this function is called -+with the session lock held). We could add a new per iscsi_task lock and -+use that to gaurd the R2T. -+ -+2. For iscsi_tcp and cxgb*i, libiscsi uses the session->cmdqueue linked list -+and the session lock to queue IO from the queuecommand function (run from -+scsi softirq or kblockd context) to the iscsi xmit thread. Once the task is -+sent from that thread, it is deleted from the list. -+ -+It seems we should be able to remove the linked list use here. The tasks -+are all preallocated in the session->cmds array. We can access that -+array and check the task->state (see fail_scsi_tasks for an example). -+We just need to come up with a way to safely set the task state, -+wake the xmit thread and make sure that tasks are executed in the order -+that the scsi layer sent them to our queuecommand function. -+ -+A starting point on the queueing: -+We might be able to create a workqueue per processor, queue the work, -+which in this case is the execution of the task, from the queuecommand, -+then rely on the work queue synchronization and serialization code. -+Not 100% sure about this. -+ -+Alternative to changing the threading: -+Can we figure out a way to just remove the xmit thread? We currently -+cannot because the network may only be able to send 1000 bytes, but -+to send the current command we need to send 2000. We cannot sleep -+from the queuecommand context until another 1000 bytes frees up and for -+iscsi_tcp we cannot sleep from the recv conext (this happens because we -+could have got a R2T from target and are handling it from the recv path). -+ -+ -+Note: that for iser and offload drivers like bnx2i and be2iscsi their -+is no xmit thread used. -+ -+Note2: cxgb*i does not actually need the xmit thread so a side project -+could be to convert that driver. -+ -+ -+--------------------------------------------------------------------------- -+ -+4. Make memory access more efficient on multi-processor machines. -+We are moving twords per process queues in the block layer, so it would -+be a good idea to move the iscsi structs to be allocated on a per process -+basis. -+ -+--------------------------------------------------------------------------- -+ -+5. Make blk_iopoll support (see block/blk-iopoll.c and be2iscsi for an -+example) being able to round robin IO across processors or complete -+on the processor it was queued on -+(today it always completes the IO on the processor the softirq was raised on), -+and convert bnx2i, ib_iser and cxgb*i to it. -+ -+Not sure if it will help iscsi_tcp and cxgb, because their completion is done -+from the network softirq which does polling already. With irq balancing it -+can also be spread over all processors too. -+ -+--------------------------------------------------------------------------- -+ -+6. Replace iscsi_get_next_target_id with idr use. -+ -+iscsi_tcp and ib_iser allocate a session per host, so the target_id is -+always just 0. The offload drivers allocate a host per pci resource, so they -+will have multiple sessions for each host. When a session is added, -+iscsi_add_session will try to find a target_id to use by looping over -+all the targets on the host. We could replace that loop with idr. -+ -+ -+* Being worked on by John Jose. -+ -+--------------------------------------------------------------------------- -+ -+7. When userspace calls into the kernel using the iscsi netlink interface -+to execute oprations like creating/destroying a session, create a connection -+to a target, etc the rx_queue_mutex is held the entire time (see -+iscsi_if_rx for the iscsi netlink interface entry point). This means -+if the driver should block every thing will be held up. -+ -+iscsi_tcp does not block, but some offload drivers might for a couple seconds -+to 10 or 15 secs while it figures out what is going on or cleans up. This a -+major problem for things like multipath where one connection blocking up the -+recovery of every other connection will delay IO from re-flowing quickly. -+ -+We should looking into breaking up the rx_queue_mutex into finer grained -+locks or making it multi threaded. For the latter we could queue operations -+into workqueues. -+ -+--------------------------------------------------------------------------- -+ -+7. Add tracing support to iscsi modules. See the scsi layer's -+trace_scsi_dispatch_cmd_start for an example. -+ -+Well, actually in general look into all the tracing stuff available -+(trace_printk/ftrace, etc) and use one. -+ -+See http://lwn.net/Articles/291091/ for some details on what is out -+there. We can only use something that is upstream though. -+ -+--------------------------------------------------------------------------- -+ -+8. Improve the iscsi driver logging. Each driver has a different -+way to control logging. We should unify them and make it managable -+by iscsiadm. So each driver would use a common format, there would -+be a common kernel interface to set the logging level, etc. -+ -+--------------------------------------------------------------------------- -+ -+9. Implement more features from the iSCSI RFC if they are worth it. -+ -+- Error Recovery Level (ERL) 1 support - will help tape support. -+- Multi R2T support - Might improve write performance. -+- OutOfOrder support - Might imrpove performance. -+ -+--------------------------------------------------------------------------- -+ -+10. Add support for digest/CRC offload. -+ -+--------------------------------------------------------------------------- -+ -+11. Finish intel IOAT support. I started this here: -+http://groups.google.com/group/open-iscsi/msg/2626b8606edbe690?dmode=source -+but could only test on boxes with 1 gig interfaces which showed no -+difference in performance. Intel had said they saw significant throughput -+gains when using 10 gig. -+ -+--------------------------------------------------------------------------- -+ -+12. Remove the login buffer preallocated buffer. Storage drivers must be able -+to make forward process, so that they can always write out a page incase the -+kernel needs to allocate the page to another process. If the connection were -+to be disconnected and the initiator needed to relogin to the target at this -+time, we might not be abe to allocate a page for the login commands buffer. -+ -+To work around the problem the initiator prealloctes a 8K (sometimes -+more depending on the page size) buffer for each session (see iscsi_conn_setup' -+s __get_free_pages call). This is obviously very wasteful since it will be -+a rate occurance. Can we think of a way to allow multiple sessions to -+be relogged in at the same time, but not have to preallocate so many -+buffers? -+ -+--------------------------------------------------------------------------- -+ -+13. Support iSCSI over swap safely. -+ -+Basically just need to hook iscsi_tcp into the patches that -+were submitted here for NBD. -+ -+https://lwn.net/Articles/446831/ -+ -+ -+--------------------------------------------------------------------------- -+ -+ -+ -+ -+ -+USERSPACE TODO ITEMS -+-------------------- -+1. The iscsi tools, iscsid, iscsiadm and iscsid, have a debug flag, -d N, that -+allows the user to control the amount of output that is logged. The argument -+N is a integer from 1 to 8, with 8 printing out the most output. -+ -+The problem is that the values from 1 to 8 do not really mean much. It would -+helpful if we could replace them with something that controls what exactly -+the iscsi tools and kernel modules log. -+ -+For example, if we made the debug level argument a bitmap then -+ -+iscsiadm -m node --login -d LOGIN_ERRS,PDUS,FUNCTION -+ -+might print out extended iscsi login error information (LOGIN_ERRS), -+the iSCSI packets that were sent/receieved (PDUS), and the functions -+that were run (FUNCTION). Note, the use of a bitmapp and the debug -+levels are just an example. Feel free to do something else. -+ -+ -+We would want to be able to have iscsiadm control the iscsi kernel -+logging as well. There are interfaces like -+/sys/module/libiscsi/paramters/*debug* -+/sys/module/libiscsi_tcp/paramters/*debug* -+/sys/module/iscsi_tcp/paramters/*debug* -+/sys/module/scsi_transport_iscsi/paramters/*debug* -+ -+but we would want to extend the debugging options to be finer grained -+and we would want to make it supportable by all iscsi drivers. -+(see #8 on the kernel todo). -+ -+--------------------------------------------------------------------------- -+ -+2. "iscsiadm -m session -P 3" can print out a lot of information about the -+session, but not all configuration values are printed. -+ -+iscsiadm should be modified to print out other settings like timeouts, -+Chap settings, the iSCSI values that were requested vs negotiated for, etc. -+ -+--------------------------------------------------------------------------- -+ -+3. iscsiadm cannot update a setting of a running session. If you want -+to change a timeout you have to run the iscsiadm logout command, -+then update the record value, then login: -+ -+iscsiadm -m node -T target -p ip -u -+iscsidm -m node -T target -p ip -o update -n node.session.timeo.replacement_timeout -v 30 -+iscsiadm -m node -T target -p ip -l -+ -+iscsiadm should be modified to allow updating of a setting without having -+to run the iscsiadm command. -+ -+Note that for some settings like iSCSI ones (ImmediateData, FirstBurstLength, -+etc) that must be negotiated with the target we will have to logout the -+target then re-login, but we should not have to completely destroy the session -+and scsi devices like is done when running the iscsiadm logout command. We -+should be able to pass iscsid the new values and then have iscsid logout and -+relogin. -+ -+Other settings like the abort timeout will not need a logout/login. We can -+just pass those to the kernel or iscsid to use. -+ -+ -+*Being worked on by Tomoaki Nishimura -+ -+--------------------------------------------------------------------------- -+ -+4. iscsiadm will attempt to perform logins/logouts in parallel. Running -+iscsiadm -m node -L, will cause iscsiadm to login to all portals with -+the startup=automatic field set at the same time. -+ -+To log into a target, iscsiadm opens a socket to iscsid, sends iscsid a -+request to login to a target, iscsid performs the iSCSI login operation, -+then iscsid sends iscsiadm a reply. -+ -+To perform multiple logins iscsiadm will open a socket for each login -+request, then wait for a reply. This is a problem because for 1000s of targets -+we will have 1000s of sockets open. There is a rlimit to control how many -+files a process can have open and iscsiadm currently runs setrlimit to -+increase this. -+ -+With users creating lots of virtual iscsi interfaces on the target and -+initiator with each having multiple paths it beomes inefficient to open -+a socket for each requests. -+ -+At the very least we want to handle setrlimit RLIMIT_NOFILE limit better, -+and it would be best to just stop openening a socket per login request. -+ -+--------------------------------------------------------------------------- -+ -+5. Make iSCSI log messages humanly readable. In many cases the iscsi tools -+will log a error number value. The most well known is conn error 1011. -+Users should not have to search on google for what this means. -+ -+We should: -+ -+1. Write a simple table to convert the error values to a string and print -+them out. -+ -+2. Document the values, how you commonly hit them and common solutions -+in the iSCSI docs. -+ -+ -+See session_conn_error and __check_iscsi_status_class as a start. -+ -+--------------------------------------------------------------------------- -+ -+6. Implement broadcast/multicasts support, so the initiator can -+find iSNS servers without the user having to set the iSNS server address. -+ -+See -+5.6.5.14. Name Service Heartbeat (Heartbeat) -+in -+http://tools.ietf.org/html//rfc4171 -+ -+--------------------------------------------------------------------------- -+ -+7. Open-iscsi uses the open-isns iSNS library. The library might be a little -+too complicated and a little too heavy for what we need. Investigate -+replacing it. -+ -+Also explore merging the open-isns and linux-isns projects, so we do not have -+to support multiple isns clients/servers in linux. -+ -+--------------------------------------------------------------------------- -+ -+8. Implement the DHCP iSNS option support, so we the initiator can -+find the iSNS sever without the user having to set the iSNS server address. -+See: -+http://www.ietf.org/rfc/rfc4174.txt -+ -+--------------------------------------------------------------------------- -+ -+9. Some iscsiadm/iscsid operations that access the iscsi DB and sysfs can be -+up to Big O(N^2). Some of the code was written when we thought 64 sessions -+would be a lot and the norm would be 4 or 8. Due to virtualization, cloud use, -+and targets like equallogic that do a target per logical unit (device) we can -+see 1000s of sessions. -+ -+- We should look into making the record DB more efficient. Maybe -+time to use a real DB (something small simple and efficient since this -+needs to run in places like the initramfs). -+ -+- Rewrite code to look up a running session so we do not have loop -+over every session in sysfs. -+ -+ -+--------------------------------------------------------------------------- -+ -+10. Look into using udev's libudev for our sysfs access in iscsiadm/iscsid/ -+iscsistart. -+ -+--------------------------------------------------------------------------- -+ -+11. iSCSI lib. -+ -+I am working on this one. Hopefully it should be done soon. -+ -+--------------------------------------------------------------------------- -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/actor.c open-iscsi-2.0-872-rc4-bnx2i.sync/usr/actor.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/actor.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/actor.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/actor.c 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/actor.c 2011-08-14 16:48:25.000000000 -0500 -@@ -113,14 +113,13 @@ actor_schedule_private(actor_t *thread, ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/actor.c 2012-03-05 23:02:46.000000000 -0600 +@@ -113,14 +113,13 @@ actor_schedule_private(actor_t *thread, * state to scheduled, else add current time to ttschedule and * insert in the queue at the correct point */ if (delay_time == 0) { @@ -2151,9 +1801,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/actor.c open-iscsi-2.0-872-rc4-bnx2 } else { thread->state = ACTOR_SCHEDULED; if (head) -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/auth.c open-iscsi-2.0-872-rc4-bnx2i.sync/usr/auth.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/auth.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/auth.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/auth.c 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/auth.c 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/auth.c 2012-03-05 23:02:46.000000000 -0600 @@ -194,27 +194,20 @@ get_random_bytes(unsigned char *data, un fd = open("/dev/urandom", O_RDONLY); while (length > 0) { @@ -2185,9 +1835,18 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/auth.c open-iscsi-2.0-872-rc4-bnx2i r = r ^ (r >> 8); r = r ^ (r >> 5); n = (n << 2) | (r & 0x3); -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/config.h open-iscsi-2.0-872-rc4-bnx2i.sync/usr/config.h +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/config.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/config.h --- open-iscsi-2.0-872-rc4-bnx2i/usr/config.h 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/config.h 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/config.h 2012-03-05 23:03:29.000000000 -0600 +@@ -73,7 +73,7 @@ struct iscsi_connection_timeout_config { + int noop_out_timeout; + }; + +-/* all per-connection timeouts go in this structure. ++/* all per-session timeouts go in this structure. + * this structure is per-session, and can be configured + * by TargetName but not by Subnet. + */ @@ -141,7 +141,8 @@ struct iscsi_sendtargets_config { int discoveryd_poll_inval; struct iscsi_auth_config auth; @@ -2253,9 +1912,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/config.h open-iscsi-2.0-872-rc4-bnx session_rec_t session; conn_rec_t conn[ISCSI_CONN_MAX]; iface_rec_t iface; -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/cxgb3i.c open-iscsi-2.0-872-rc4-bnx2i.sync/usr/cxgb3i.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/cxgb3i.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/cxgb3i.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/cxgb3i.c 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/cxgb3i.c 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/cxgb3i.c 1969-12-31 18:00:00.000000000 -0600 @@ -1,24 +0,0 @@ -/* - * cxgb3i helpers @@ -2281,9 +1940,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/cxgb3i.c open-iscsi-2.0-872-rc4-bnx - if (conn->max_recv_dlength > 8192) - conn->max_recv_dlength = 8192; -} -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/cxgb3i.h open-iscsi-2.0-872-rc4-bnx2i.sync/usr/cxgb3i.h +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/cxgb3i.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/cxgb3i.h --- open-iscsi-2.0-872-rc4-bnx2i/usr/cxgb3i.h 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/cxgb3i.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/cxgb3i.h 1969-12-31 18:00:00.000000000 -0600 @@ -1,8 +0,0 @@ -#ifndef CXGB3I_TRANSPORT -#define CXGB3I_TRANSPORT @@ -2293,9 +1952,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/cxgb3i.h open-iscsi-2.0-872-rc4-bnx -extern void cxgb3i_create_conn(struct iscsi_conn *conn); - -#endif -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/cxgbi.c open-iscsi-2.0-872-rc4-bnx2i.sync/usr/cxgbi.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/cxgbi.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/cxgbi.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/cxgbi.c 1969-12-31 18:00:00.000000000 -0600 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/cxgbi.c 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/cxgbi.c 2012-03-05 23:02:46.000000000 -0600 @@ -0,0 +1,24 @@ +/* + * cxgb3i/cxgb4i helpers @@ -2321,9 +1980,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/cxgbi.c open-iscsi-2.0-872-rc4-bnx2 + if (conn->max_recv_dlength > 8192) + conn->max_recv_dlength = 8192; +} -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/cxgbi.h open-iscsi-2.0-872-rc4-bnx2i.sync/usr/cxgbi.h +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/cxgbi.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/cxgbi.h --- open-iscsi-2.0-872-rc4-bnx2i/usr/cxgbi.h 1969-12-31 18:00:00.000000000 -0600 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/cxgbi.h 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/cxgbi.h 2012-03-05 23:02:46.000000000 -0600 @@ -0,0 +1,8 @@ +#ifndef CXGBI_TRANSPORT +#define CXGBI_TRANSPORT @@ -2333,9 +1992,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/cxgbi.h open-iscsi-2.0-872-rc4-bnx2 +extern void cxgbi_create_conn(struct iscsi_conn *conn); + +#endif -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/dcb_app.c open-iscsi-2.0-872-rc4-bnx2i.sync/usr/dcb_app.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/dcb_app.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/dcb_app.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/dcb_app.c 1969-12-31 18:00:00.000000000 -0600 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/dcb_app.c 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/dcb_app.c 2012-03-05 23:02:46.000000000 -0600 @@ -0,0 +1,387 @@ +/******************************************************************************* + @@ -2724,9 +2383,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/dcb_app.c open-iscsi-2.0-872-rc4-bn + return get_app_pri(ifname, DCB_APP_IDTYPE_ETHTYPE, ethtype, + IEEE_SMASK_ETHTYPE); +} -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/dcb_app.h open-iscsi-2.0-872-rc4-bnx2i.sync/usr/dcb_app.h +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/dcb_app.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/dcb_app.h --- open-iscsi-2.0-872-rc4-bnx2i/usr/dcb_app.h 1969-12-31 18:00:00.000000000 -0600 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/dcb_app.h 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/dcb_app.h 2012-03-05 23:02:46.000000000 -0600 @@ -0,0 +1,41 @@ +/******************************************************************************* + @@ -2769,9 +2428,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/dcb_app.h open-iscsi-2.0-872-rc4-bn +int get_dcb_app_pri_by_port_sel(const char *ifname, int port, int sel); + +#endif /* _DCB_APP_H_ */ -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/dcbnl.h open-iscsi-2.0-872-rc4-bnx2i.sync/usr/dcbnl.h +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/dcbnl.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/dcbnl.h --- open-iscsi-2.0-872-rc4-bnx2i/usr/dcbnl.h 1969-12-31 18:00:00.000000000 -0600 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/dcbnl.h 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/dcbnl.h 2012-03-05 23:02:46.000000000 -0600 @@ -0,0 +1,653 @@ +/* + * Local copy of the kernel's dcbnl.h @@ -3426,9 +3085,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/dcbnl.h open-iscsi-2.0-872-rc4-bnx2 +}; + +#endif /* __LINUX_DCBNL_H__ */ -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/discovery.c open-iscsi-2.0-872-rc4-bnx2i.sync/usr/discovery.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/discovery.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/discovery.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/discovery.c 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/discovery.c 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/discovery.c 2012-03-05 23:02:46.000000000 -0600 @@ -43,6 +43,12 @@ #include "fw_context.h" #include "iscsid_req.h" @@ -4874,9 +4533,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/discovery.c open-iscsi-2.0-872-rc4- return rc; } -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/discoveryd.c open-iscsi-2.0-872-rc4-bnx2i.sync/usr/discoveryd.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/discoveryd.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/discoveryd.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/discoveryd.c 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/discoveryd.c 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/discoveryd.c 2012-03-05 23:02:46.000000000 -0600 @@ -44,6 +44,7 @@ #include "isns.h" #include "paths.h" @@ -5120,9 +4779,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/discoveryd.c open-iscsi-2.0-872-rc4 fork_disc(data, drec, drec->u.isns.discoveryd_poll_inval, start_isns); return 0; -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/event_poll.c open-iscsi-2.0-872-rc4-bnx2i.sync/usr/event_poll.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/event_poll.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/event_poll.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/event_poll.c 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/event_poll.c 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/event_poll.c 2012-03-05 23:02:46.000000000 -0600 @@ -35,6 +35,7 @@ #include "iscsi_ipc.h" #include "actor.h" @@ -5138,9 +4797,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/event_poll.c open-iscsi-2.0-872-rc4 - mgmt_ipc_write_rsp(shutdown_qtask, MGMT_IPC_OK); + mgmt_ipc_write_rsp(shutdown_qtask, ISCSI_SUCCESS); } -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/host.c open-iscsi-2.0-872-rc4-bnx2i.sync/usr/host.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/host.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/host.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/host.c 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/host.c 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/host.c 2012-03-05 23:04:22.000000000 -0600 @@ -33,6 +33,7 @@ #include "transport.h" #include "initiator.h" @@ -5149,7 +4808,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/host.c open-iscsi-2.0-872-rc4-bnx2i static int match_host_to_session(void *data, struct session_info *info) { -@@ -117,6 +118,47 @@ static int host_info_print_flat(void *da +@@ -117,6 +118,92 @@ static int host_info_print_flat(void *da return 0; } @@ -5167,22 +4826,67 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/host.c open-iscsi-2.0-872-rc4-bnx2i + printf("%sIPaddress: %s\n", prefix, UNKNOWN_VALUE); + else if (strchr(iface->ipaddress, '.')) { + printf("%sIPaddress: %s\n", prefix, iface->ipaddress); -+ printf("%sGateway: %s\n", prefix, iface->gateway); -+ printf("%sSubnet: %s\n", prefix, iface->subnet_mask); -+ printf("%sBootProto: %s\n", prefix, iface->bootproto); ++ ++ if (!strlen(iface->gateway)) ++ printf("%sGateway: %s\n", prefix, UNKNOWN_VALUE); ++ else ++ printf("%sGateway: %s\n", prefix, iface->gateway); ++ if (!strlen(iface->subnet_mask)) ++ printf("%sSubnet: %s\n", prefix, UNKNOWN_VALUE); ++ else ++ printf("%sSubnet: %s\n", prefix, iface->subnet_mask); ++ if (!strlen(iface->bootproto)) ++ printf("%sBootProto: %s\n", prefix, UNKNOWN_VALUE); ++ else ++ printf("%sBootProto: %s\n", prefix, iface->bootproto); + } else { + printf("%sIPaddress: [%s]\n", prefix, iface->ipaddress); -+ printf("%sIPaddress Autocfg: %s\n", prefix, iface->ipv6_autocfg); -+ printf("%sLink Local Address: [%s]\n", prefix, -+ iface->ipv6_linklocal); -+ printf("%sLink Local Autocfg: %s\n", prefix, -+ iface->linklocal_autocfg); -+ printf("%sRouter Address: [%s]\n", prefix, iface->ipv6_router); ++ ++ if (!strlen(iface->ipv6_autocfg)) ++ printf("%sIPaddress Autocfg: %s\n", prefix, ++ UNKNOWN_VALUE); ++ else ++ printf("%sIPaddress Autocfg: %s\n", prefix, ++ iface->ipv6_autocfg); ++ if (!strlen(iface->ipv6_linklocal)) ++ printf("%sLink Local Address: %s\n", prefix, ++ UNKNOWN_VALUE); ++ else ++ printf("%sLink Local Address: [%s]\n", prefix, ++ iface->ipv6_linklocal); ++ if (!strlen(iface->linklocal_autocfg)) ++ printf("%sLink Local Autocfg: %s\n", prefix, ++ UNKNOWN_VALUE); ++ else ++ printf("%sLink Local Autocfg: %s\n", prefix, ++ iface->linklocal_autocfg); ++ if (!strlen(iface->ipv6_router)) ++ printf("%sRouter Address: %s\n", prefix, ++ UNKNOWN_VALUE); ++ else ++ printf("%sRouter Address: [%s]\n", prefix, ++ iface->ipv6_router); + } + -+ printf("%sMTU: %u\n", prefix, iface->mtu); -+ printf("%svlan ID: %u\n", prefix, iface->vlan_id); -+ printf("%svlan priority: %u\n", prefix, iface->vlan_priority); ++ if (!iface->port) ++ printf("%sPort: %s\n", prefix, UNKNOWN_VALUE); ++ else ++ printf("%sPort: %u\n", prefix, iface->port); ++ ++ if (!iface->mtu) ++ printf("%sMTU: %s\n", prefix, UNKNOWN_VALUE); ++ else ++ printf("%sMTU: %u\n", prefix, iface->mtu); ++ ++ if (iface->vlan_id == UINT16_MAX) ++ printf("%sVLAN ID: %s\n", prefix, UNKNOWN_VALUE); ++ else ++ printf("%sVLAN ID: %u\n", prefix, iface->vlan_id); ++ ++ if (iface->vlan_priority == UINT8_MAX) ++ printf("%sVLAN priority: %s\n", prefix, UNKNOWN_VALUE); ++ else ++ printf("%sVLAN priority: %u\n", prefix, iface->vlan_priority); + return 0; +} + @@ -5197,7 +4901,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/host.c open-iscsi-2.0-872-rc4-bnx2i static int host_info_print_tree(void *data, struct host_info *hinfo) { struct list_head sessions; -@@ -127,6 +169,7 @@ static int host_info_print_tree(void *da +@@ -127,6 +214,7 @@ static int host_info_print_tree(void *da INIT_LIST_HEAD(&sessions); @@ -5205,7 +4909,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/host.c open-iscsi-2.0-872-rc4-bnx2i printf("Host Number: %u\n", hinfo->host_no); if (!iscsi_sysfs_get_host_state(state, hinfo->host_no)) printf("\tState: %s\n", state); -@@ -134,6 +177,8 @@ static int host_info_print_tree(void *da +@@ -134,6 +222,8 @@ static int host_info_print_tree(void *da printf("\tState: Unknown\n"); print_host_info(&hinfo->iface, "\t"); @@ -5214,7 +4918,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/host.c open-iscsi-2.0-872-rc4-bnx2i if (!session_info_flags) return 0; -@@ -150,7 +195,7 @@ static int host_info_print_tree(void *da +@@ -150,7 +240,7 @@ static int host_info_print_tree(void *da printf("\tSessions:\n"); printf("\t*********\n"); @@ -5223,7 +4927,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/host.c open-iscsi-2.0-872-rc4-bnx2i session_info_free_list(&sessions); return 0; } -@@ -200,13 +245,16 @@ int host_info_print(int info_level, uint +@@ -200,13 +290,16 @@ int host_info_print(int info_level, uint break; default: log_error("Invalid info level %d. Try 0 - 4.", info_level); @@ -5243,9 +4947,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/host.c open-iscsi-2.0-872-rc4-bnx2i + } return 0; } -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i.sync/usr/idbm.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/idbm.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/idbm.c 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/idbm.c 2012-03-05 23:06:00.000000000 -0600 @@ -40,6 +40,7 @@ #include "iface.h" #include "sysdeps.h" @@ -5301,7 +5005,40 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i /* * Note: because we do not add the iface.iscsi_ifacename to * sysfs iscsiadm does some weird matching. We can change the iface -@@ -247,6 +272,8 @@ idbm_recinfo_node(node_rec_t *r, recinfo +@@ -230,6 +255,32 @@ idbm_recinfo_node(node_rec_t *r, recinfo + __recinfo_str(IFACE_TRANSPORTNAME, ri, r, iface.transport_name, + IDBM_SHOW, num, 1); + __recinfo_str(IFACE_INAME, ri, r, iface.iname, IDBM_SHOW, num, 1); ++ __recinfo_str(IFACE_BOOT_PROTO, ri, r, iface.bootproto, IDBM_SHOW, ++ num, 1); ++ __recinfo_str(IFACE_SUBNET_MASK, ri, r, iface.subnet_mask, ++ IDBM_SHOW, num, 1); ++ __recinfo_str(IFACE_GATEWAY, ri, r, iface.gateway, IDBM_SHOW, num, 1); ++ __recinfo_str(IFACE_IPV6_AUTOCFG, ri, r, iface.ipv6_autocfg, ++ IDBM_SHOW, num, 1); ++ __recinfo_str(IFACE_LINKLOCAL_AUTOCFG, ri, r, iface.linklocal_autocfg, ++ IDBM_SHOW, num, 1); ++ __recinfo_str(IFACE_ROUTER_AUTOCFG, ri, r, iface.router_autocfg, ++ IDBM_SHOW, num, 1); ++ __recinfo_str(IFACE_LINKLOCAL, ri, r, iface.ipv6_linklocal, ++ IDBM_SHOW, num, 1); ++ __recinfo_str(IFACE_ROUTER, ri, r, iface.ipv6_router, IDBM_SHOW, num, ++ 1); ++ __recinfo_str(IFACE_STATE, ri, r, iface.state, IDBM_SHOW, num, 1); ++ __recinfo_uint16(IFACE_VLAN_ID, ri, r, iface.vlan_id, IDBM_SHOW, num, ++ 1); ++ __recinfo_uint8(IFACE_VLAN_PRIORITY, ri, r, iface.vlan_priority, ++ IDBM_SHOW, num, 1); ++ __recinfo_str(IFACE_VLAN_STATE, ri, r, iface.vlan_state, IDBM_SHOW, ++ num, 1); ++ __recinfo_int(IFACE_NUM, ri, r, iface.iface_num, IDBM_SHOW, num, 1); ++ __recinfo_uint16(IFACE_MTU, ri, r, iface.mtu, IDBM_SHOW, num, 1); ++ __recinfo_uint16(IFACE_PORT, ri, r, iface.port, IDBM_SHOW, num, 1); ++ + __recinfo_str(NODE_DISC_ADDR, ri, r, disc_address, IDBM_SHOW, + num, 0); + __recinfo_int(NODE_DISC_PORT, ri, r, disc_port, IDBM_SHOW, +@@ -247,6 +298,8 @@ idbm_recinfo_node(node_rec_t *r, recinfo session.cmds_max, IDBM_SHOW, num, 1); __recinfo_int(SESSION_QDEPTH, ri, r, session.queue_depth, IDBM_SHOW, num, 1); @@ -5310,7 +5047,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i __recinfo_int_o2(SESSION_AUTH_METHOD, ri, r, session.auth.authmethod, IDBM_SHOW, "None", "CHAP", num, 1); __recinfo_str(SESSION_USERNAME, ri, r, -@@ -369,6 +396,27 @@ void idbm_recinfo_iface(iface_rec_t *r, +@@ -369,6 +422,27 @@ void idbm_recinfo_iface(iface_rec_t *r, __recinfo_str(IFACE_TRANSPORTNAME, ri, r, transport_name, IDBM_SHOW, num, 1); __recinfo_str(IFACE_INAME, ri, r, iname, IDBM_SHOW, num, 1); @@ -5338,7 +5075,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i } recinfo_t *idbm_recinfo_alloc(int max_keys) -@@ -426,6 +474,31 @@ void idbm_print(int type, void *rec, int +@@ -426,6 +500,31 @@ void idbm_print(int type, void *rec, int } static void @@ -5370,7 +5107,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i idbm_discovery_setup_defaults(discovery_rec_t *rec, discovery_type_e type) { memset(rec, 0, sizeof(discovery_rec_t)); -@@ -443,7 +516,10 @@ idbm_discovery_setup_defaults(discovery_ +@@ -443,7 +542,10 @@ idbm_discovery_setup_defaults(discovery_ rec->u.sendtargets.conn_timeo.login_timeout=15; rec->u.sendtargets.conn_timeo.auth_timeout = 45; rec->u.sendtargets.conn_timeo.active_timeout=30; @@ -5382,7 +5119,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i DEF_INI_DISC_MAX_RECV_SEG_LEN; break; case DISCOVERY_TYPE_SLP: -@@ -485,6 +561,20 @@ setup_passwd_len: +@@ -485,6 +587,20 @@ setup_passwd_len: *(int*)info[i].data = strtoul(value, NULL, 10); goto updated; @@ -5403,7 +5140,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i } else if (info[i].type == TYPE_STR) { if (!info[i].data) continue; -@@ -515,7 +605,7 @@ setup_passwd_len: +@@ -515,7 +631,7 @@ setup_passwd_len: } } @@ -5412,7 +5149,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i updated: strlcpy((char*)info[i].value, value, VALUE_MAXVAL); -@@ -556,12 +646,12 @@ int idbm_verify_param(recinfo_t *info, c +@@ -556,12 +672,12 @@ int idbm_verify_param(recinfo_t *info, c else { log_error("Cannot modify %s. It is used to look up " "the record and cannot be changed.", name); @@ -5427,7 +5164,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i } void idbm_recinfo_config(recinfo_t *info, FILE *f) -@@ -627,7 +717,7 @@ void idbm_recinfo_config(recinfo_t *info +@@ -627,7 +743,7 @@ void idbm_recinfo_config(recinfo_t *info } *(value+i) = 0; @@ -5436,7 +5173,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i } while (line); } -@@ -781,19 +871,19 @@ get_params_from_disc_link(char *link, ch +@@ -781,19 +897,19 @@ get_params_from_disc_link(char *link, ch (*target) = link; *address = strchr(*target, ','); if (!(*address)) @@ -5460,7 +5197,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i *(*ifaceid)++ = '\0'; return 0; } -@@ -809,8 +899,9 @@ int idbm_lock(void) +@@ -809,8 +925,9 @@ int idbm_lock(void) if (access(LOCK_DIR, F_OK) != 0) { if (mkdir(LOCK_DIR, 0660) != 0) { @@ -5472,7 +5209,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i } } -@@ -827,7 +918,7 @@ int idbm_lock(void) +@@ -827,7 +944,7 @@ int idbm_lock(void) log_error("Maybe you are not root?"); log_error("Could not lock discovery DB: %s: %s", LOCK_WRITE_FILE, strerror(errno)); @@ -5481,7 +5218,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i } else if (i == 0) log_debug(2, "Waiting for discovery DB lock"); -@@ -880,7 +971,7 @@ static int __idbm_rec_read(node_rec_t *o +@@ -880,7 +997,7 @@ static int __idbm_rec_read(node_rec_t *o info = idbm_recinfo_alloc(MAX_KEYS); if (!info) @@ -5490,7 +5227,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i rc = idbm_lock(); if (rc) -@@ -888,8 +979,9 @@ static int __idbm_rec_read(node_rec_t *o +@@ -888,8 +1005,9 @@ static int __idbm_rec_read(node_rec_t *o f = fopen(conf, "r"); if (!f) { @@ -5502,7 +5239,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i goto unlock; } -@@ -916,7 +1008,7 @@ idbm_rec_read(node_rec_t *out_rec, char +@@ -916,7 +1034,7 @@ idbm_rec_read(node_rec_t *out_rec, char portal = calloc(1, PATH_MAX); if (!portal) @@ -5511,7 +5248,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i /* try old style portal as config */ snprintf(portal, PATH_MAX, "%s/%s/%s,%d", NODE_CONFIG_DIR, -@@ -929,14 +1021,14 @@ idbm_rec_read(node_rec_t *out_rec, char +@@ -929,14 +1047,14 @@ idbm_rec_read(node_rec_t *out_rec, char targetname, ip, port, tpgt, iface->name); log_debug(5, "rec read looking for config file %s.", portal); if (!strlen(iface->name)) { @@ -5529,7 +5266,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i } read: -@@ -1073,22 +1165,16 @@ int idbm_for_each_isns_drec(void *data, +@@ -1073,22 +1191,16 @@ int idbm_for_each_isns_drec(void *data, static int __idbm_print_all_by_drec(void *data, struct discovery_rec *drec) { int info_level = *(int *)data; @@ -5555,7 +5292,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i } static int idbm_print_all_st(int info_level) -@@ -1168,11 +1254,23 @@ int idbm_print_all_discovery(int info_le +@@ -1168,11 +1280,23 @@ int idbm_print_all_discovery(int info_le return found; } @@ -5583,7 +5320,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i idbm_iface_op_fn *fn, char *targetname, int tpgt, char *ip, int port) { -@@ -1185,7 +1283,7 @@ int idbm_for_each_iface(int *found, void +@@ -1185,7 +1309,7 @@ int idbm_for_each_iface(int *found, void portal = calloc(1, PATH_MAX); if (!portal) @@ -5592,7 +5329,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i if (tpgt >= 0) goto read_iface; -@@ -1195,7 +1293,7 @@ int idbm_for_each_iface(int *found, void +@@ -1195,7 +1319,7 @@ int idbm_for_each_iface(int *found, void ip, port); if (stat(portal, &statb)) { log_error("iface iter could not stat %s.", portal); @@ -5601,7 +5338,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i goto free_portal; } -@@ -1217,11 +1315,13 @@ read_iface: +@@ -1217,11 +1341,13 @@ read_iface: iface_dirfd = opendir(portal); if (!iface_dirfd) { log_error("iface iter could not read dir %s.", portal); @@ -5616,7 +5353,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i if (!strcmp(iface_dent->d_name, ".") || !strcmp(iface_dent->d_name, "..")) continue; -@@ -1233,14 +1333,12 @@ read_iface: +@@ -1233,14 +1359,12 @@ read_iface: if (__idbm_rec_read(&rec, portal)) continue; @@ -5635,7 +5372,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i } closedir(iface_dirfd); -@@ -1263,17 +1361,18 @@ int idbm_for_each_portal(int *found, voi +@@ -1263,17 +1387,18 @@ int idbm_for_each_portal(int *found, voi portal = calloc(1, PATH_MAX); if (!portal) @@ -5656,7 +5393,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i if (!strcmp(portal_dent->d_name, ".") || !strcmp(portal_dent->d_name, "..")) -@@ -1288,11 +1387,12 @@ int idbm_for_each_portal(int *found, voi +@@ -1288,11 +1413,12 @@ int idbm_for_each_portal(int *found, voi if (tmp_tpgt) *tmp_tpgt++ = '\0'; @@ -5672,7 +5409,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i } closedir(portal_dirfd); done: -@@ -1314,14 +1414,17 @@ int idbm_for_each_node(int *found, void +@@ -1314,14 +1440,17 @@ int idbm_for_each_node(int *found, void return 0; while ((node_dent = readdir(node_dirfd))) { @@ -5693,7 +5430,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i } closedir(node_dirfd); -@@ -1376,17 +1479,17 @@ idbm_discovery_read(discovery_rec_t *out +@@ -1376,17 +1505,17 @@ idbm_discovery_read(discovery_rec_t *out FILE *f; if (drec_type > 1) @@ -5714,7 +5451,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i goto free_info; } -@@ -1402,8 +1505,9 @@ idbm_discovery_read(discovery_rec_t *out +@@ -1402,8 +1531,9 @@ idbm_discovery_read(discovery_rec_t *out f = idbm_open_rec_r(portal, disc_type_to_config_vals[drec_type].config_name); if (!f) { @@ -5726,7 +5463,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i goto unlock; } -@@ -1474,14 +1578,15 @@ static int idbm_rec_write(node_rec_t *re +@@ -1474,14 +1604,15 @@ static int idbm_rec_write(node_rec_t *re portal = malloc(PATH_MAX); if (!portal) { log_error("Could not alloc portal\n"); @@ -5745,7 +5482,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i goto free_portal; } } -@@ -1489,8 +1594,9 @@ static int idbm_rec_write(node_rec_t *re +@@ -1489,8 +1620,9 @@ static int idbm_rec_write(node_rec_t *re snprintf(portal, PATH_MAX, "%s/%s", NODE_CONFIG_DIR, rec->name); if (access(portal, F_OK) != 0) { if (mkdir(portal, 0660) != 0) { @@ -5757,7 +5494,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i goto free_portal; } } -@@ -1531,13 +1637,13 @@ static int idbm_rec_write(node_rec_t *re +@@ -1531,13 +1663,13 @@ static int idbm_rec_write(node_rec_t *re * Old style portal as a file, but with tpgt. Let's update it. */ if (unlink(portal)) { @@ -5775,7 +5512,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i goto unlock; } -@@ -1546,9 +1652,9 @@ mkdir_portal: +@@ -1546,9 +1678,9 @@ mkdir_portal: rec->name, rec->conn[0].address, rec->conn[0].port, rec->tpgt); if (stat(portal, &statb)) { if (mkdir(portal, 0660) != 0) { @@ -5788,7 +5525,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i goto unlock; } } -@@ -1559,8 +1665,8 @@ mkdir_portal: +@@ -1559,8 +1691,8 @@ mkdir_portal: open_conf: f = fopen(portal, "w"); if (!f) { @@ -5799,7 +5536,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i goto unlock; } -@@ -1581,12 +1687,12 @@ idbm_discovery_write(discovery_rec_t *re +@@ -1581,12 +1713,12 @@ idbm_discovery_write(discovery_rec_t *re int rc = 0; if (rec->type > 1) @@ -5814,7 +5551,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i } rc = idbm_lock(); -@@ -1597,8 +1703,9 @@ idbm_discovery_write(discovery_rec_t *re +@@ -1597,8 +1729,9 @@ idbm_discovery_write(discovery_rec_t *re disc_type_to_config_vals[rec->type].config_root); if (access(portal, F_OK) != 0) { if (mkdir(portal, 0660) != 0) { @@ -5826,7 +5563,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i goto unlock; } } -@@ -1610,8 +1717,8 @@ idbm_discovery_write(discovery_rec_t *re +@@ -1610,8 +1743,8 @@ idbm_discovery_write(discovery_rec_t *re f = idbm_open_rec_w(portal, disc_type_to_config_vals[rec->type].config_name); if (!f) { @@ -5837,7 +5574,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i goto unlock; } -@@ -1655,9 +1762,9 @@ static int setup_disc_to_node_link(char +@@ -1655,9 +1788,9 @@ static int setup_disc_to_node_link(char case DISCOVERY_TYPE_FW: if (access(FW_CONFIG_DIR, F_OK) != 0) { if (mkdir(FW_CONFIG_DIR, 0660) != 0) { @@ -5850,7 +5587,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i } } -@@ -1669,9 +1776,9 @@ static int setup_disc_to_node_link(char +@@ -1669,9 +1802,9 @@ static int setup_disc_to_node_link(char case DISCOVERY_TYPE_STATIC: if (access(STATIC_CONFIG_DIR, F_OK) != 0) { if (mkdir(STATIC_CONFIG_DIR, 0660) != 0) { @@ -5863,7 +5600,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i } } -@@ -1683,9 +1790,9 @@ static int setup_disc_to_node_link(char +@@ -1683,9 +1816,9 @@ static int setup_disc_to_node_link(char case DISCOVERY_TYPE_ISNS: if (access(ISNS_CONFIG_DIR, F_OK) != 0) { if (mkdir(ISNS_CONFIG_DIR, 0660) != 0) { @@ -5876,7 +5613,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i } } -@@ -1732,7 +1839,7 @@ static int setup_disc_to_node_link(char +@@ -1732,7 +1865,7 @@ static int setup_disc_to_node_link(char break; case DISCOVERY_TYPE_SLP: default: @@ -5885,7 +5622,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i } return rc; -@@ -1773,7 +1880,7 @@ int idbm_add_node(node_rec_t *newrec, di +@@ -1773,7 +1906,7 @@ int idbm_add_node(node_rec_t *newrec, di node_portal = calloc(2, PATH_MAX); if (!node_portal) @@ -5894,7 +5631,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i disc_portal = node_portal + PATH_MAX; snprintf(node_portal, PATH_MAX, "%s/%s/%s,%d,%d", NODE_CONFIG_DIR, -@@ -1795,9 +1902,10 @@ int idbm_add_node(node_rec_t *newrec, di +@@ -1795,9 +1928,10 @@ int idbm_add_node(node_rec_t *newrec, di log_debug(7, "link from %s to %s exists", node_portal, disc_portal); else { @@ -5907,7 +5644,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i } } idbm_unlock(); -@@ -1812,10 +1920,12 @@ static int idbm_bind_iface_to_nodes(idbm +@@ -1812,10 +1946,12 @@ static int idbm_bind_iface_to_nodes(idbm { struct node_rec *rec, *tmp; struct list_head new_recs; @@ -5922,7 +5659,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i list_for_each_entry_safe(rec, tmp, &new_recs, list) { list_del_init(&rec->list); -@@ -1825,6 +1935,20 @@ static int idbm_bind_iface_to_nodes(idbm +@@ -1825,6 +1961,20 @@ static int idbm_bind_iface_to_nodes(idbm return 0; } @@ -5943,7 +5680,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i int idbm_bind_ifaces_to_nodes(idbm_disc_nodes_fn *disc_node_fn, void *data, struct list_head *ifaces, struct list_head *bound_recs) -@@ -1856,7 +1980,7 @@ int idbm_bind_ifaces_to_nodes(idbm_disc_ +@@ -1856,7 +2006,7 @@ int idbm_bind_ifaces_to_nodes(idbm_disc_ rc = idbm_bind_iface_to_nodes(disc_node_fn, data, iface, bound_recs); free(iface); @@ -5952,7 +5689,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i goto fail; found = 1; } -@@ -1883,7 +2007,7 @@ int idbm_bind_ifaces_to_nodes(idbm_disc_ +@@ -1883,7 +2033,7 @@ int idbm_bind_ifaces_to_nodes(idbm_disc_ rc = idbm_bind_iface_to_nodes(disc_node_fn, data, iface, bound_recs); @@ -5961,7 +5698,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i goto fail; } } -@@ -1960,7 +2084,7 @@ int idbm_delete_discovery(discovery_rec_ +@@ -1960,7 +2110,7 @@ int idbm_delete_discovery(discovery_rec_ portal = calloc(1, PATH_MAX); if (!portal) @@ -5970,7 +5707,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i snprintf(portal, PATH_MAX, "%s/%s,%d", disc_type_to_config_vals[drec->type].config_root, -@@ -2017,7 +2141,7 @@ static int idbm_remove_disc_to_node_link +@@ -2017,7 +2167,7 @@ static int idbm_remove_disc_to_node_link tmprec = malloc(sizeof(*tmprec)); if (!tmprec) @@ -5979,7 +5716,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i memset(portal, 0, PATH_MAX); snprintf(portal, PATH_MAX, "%s/%s/%s,%d,%d/%s", NODE_CONFIG_DIR, -@@ -2045,9 +2169,9 @@ static int idbm_remove_disc_to_node_link +@@ -2045,9 +2195,9 @@ static int idbm_remove_disc_to_node_link if (!stat(portal, &statb)) { if (unlink(portal)) { @@ -5992,7 +5729,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i } else log_debug(7, "rmd %s", portal); } else -@@ -2073,7 +2197,7 @@ int idbm_delete_node(node_rec_t *rec) +@@ -2073,7 +2223,7 @@ int idbm_delete_node(node_rec_t *rec) portal = calloc(1, PATH_MAX); if (!portal) @@ -6001,7 +5738,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i rc = idbm_remove_disc_to_node_link(rec, portal); if (rc) -@@ -2100,15 +2224,15 @@ int idbm_delete_node(node_rec_t *rec) +@@ -2100,15 +2250,15 @@ int idbm_delete_node(node_rec_t *rec) if (!stat(portal, &statb)) goto rm_conf; @@ -6022,7 +5759,46 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i goto unlock; } -@@ -2178,7 +2302,7 @@ int idbm_node_set_param(void *data, node +@@ -2170,6 +2320,38 @@ idbm_slp_defaults(struct iscsi_slp_confi + sizeof(struct iscsi_slp_config)); + } + ++int idbm_parse_param(char *param, struct node_rec *rec) ++{ ++ char *name, *value; ++ recinfo_t *info; ++ int rc; ++ ++ name = param; ++ ++ value = strchr(param, '='); ++ if (!value) { ++ log_error("Invalid --param %s. Missing setting.\n", param); ++ return ISCSI_ERR_INVAL; ++ } ++ *value = '\0'; ++ value++; ++ ++ info = idbm_recinfo_alloc(MAX_KEYS); ++ if (!info) { ++ log_error("Could not allocate memory to setup params.\n"); ++ return ISCSI_ERR_NOMEM; ++ } ++ ++ idbm_recinfo_node(rec, info); ++ ++ rc = idbm_rec_update_param(info, name, value, 0); ++ if (rc) ++ log_error("Could not set %s to %s. Check that %s is a " ++ "valid parameter.\n", name, value, name); ++ free(info); ++ return rc; ++} ++ + int idbm_node_set_param(void *data, node_rec_t *rec) + { + struct db_set_param *param = data; +@@ -2178,7 +2360,7 @@ int idbm_node_set_param(void *data, node info = idbm_recinfo_alloc(MAX_KEYS); if (!info) @@ -6031,7 +5807,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i idbm_recinfo_node(rec, info); -@@ -2207,7 +2331,7 @@ int idbm_discovery_set_param(void *data, +@@ -2207,7 +2389,7 @@ int idbm_discovery_set_param(void *data, info = idbm_recinfo_alloc(MAX_KEYS); if (!info) @@ -6040,7 +5816,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i idbm_recinfo_discovery((discovery_rec_t *)rec, info); -@@ -2242,7 +2366,7 @@ int idbm_init(idbm_get_config_file_fn *f +@@ -2242,7 +2424,7 @@ int idbm_init(idbm_get_config_file_fn *f db = malloc(sizeof(idbm_t)); if (!db) { log_error("out of memory on idbm allocation"); @@ -6049,7 +5825,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i } memset(db, 0, sizeof(idbm_t)); db->get_config_file = fn; -@@ -2348,10 +2472,12 @@ void idbm_node_setup_defaults(node_rec_t +@@ -2348,10 +2530,12 @@ void idbm_node_setup_defaults(node_rec_t rec->tpgt = PORTAL_GROUP_TAG_UNKNOWN; rec->disc_type = DISCOVERY_TYPE_STATIC; @@ -6062,7 +5838,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i rec->session.initial_login_retry_max = DEF_INITIAL_LOGIN_RETRIES_MAX; rec->session.reopen_max = 32; rec->session.auth.authmethod = 0; -@@ -2362,16 +2488,10 @@ void idbm_node_setup_defaults(node_rec_t +@@ -2362,16 +2546,10 @@ void idbm_node_setup_defaults(node_rec_t rec->session.err_timeo.tgt_reset_timeout = DEF_TGT_RESET_TIMEO; rec->session.err_timeo.host_reset_timeout = DEF_HOST_RESET_TIMEO; rec->session.timeo.replacement_timeout = DEF_REPLACEMENT_TIMEO; @@ -6083,7 +5859,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i for (i=0; iconn[i].startup = ISCSI_STARTUP_MANUAL; -@@ -2385,13 +2505,7 @@ void idbm_node_setup_defaults(node_rec_t +@@ -2385,13 +2563,7 @@ void idbm_node_setup_defaults(node_rec_t rec->conn[i].timeo.noop_out_interval = DEF_NOOP_OUT_INTERVAL; rec->conn[i].timeo.noop_out_timeout = DEF_NOOP_OUT_TIMEO; @@ -6098,7 +5874,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i } iface_setup_defaults(&rec->iface); -@@ -2404,7 +2518,8 @@ idbm_find_rec_in_list(struct list_head * +@@ -2404,7 +2576,8 @@ idbm_find_rec_in_list(struct list_head * struct node_rec *rec; list_for_each_entry(rec, rec_list, list) { @@ -6108,9 +5884,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i return rec; } -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm_fields.h open-iscsi-2.0-872-rc4-bnx2i.sync/usr/idbm_fields.h +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm_fields.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/idbm_fields.h --- open-iscsi-2.0-872-rc4-bnx2i/usr/idbm_fields.h 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/idbm_fields.h 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/idbm_fields.h 2012-03-05 23:02:46.000000000 -0600 @@ -10,6 +10,7 @@ #define NODE_NAME "node.name" #define NODE_TPGT "node.tpgt" @@ -6147,9 +5923,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm_fields.h open-iscsi-2.0-872-rc /* discovery fields */ #define DISC_STARTUP "discovery.startup" -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.h open-iscsi-2.0-872-rc4-bnx2i.sync/usr/idbm.h +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/idbm.h --- open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.h 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/idbm.h 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/idbm.h 2012-03-05 23:06:00.000000000 -0600 @@ -39,6 +39,8 @@ #define TYPE_INT 0 #define TYPE_INT_O 1 @@ -6169,9 +5945,17 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.h open-iscsi-2.0-872-rc4-bnx2i extern int idbm_for_each_portal(int *found, void *data, idbm_portal_op_fn *fn, char *targetname); extern int idbm_for_each_node(int *found, void *data, -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iface.c open-iscsi-2.0-872-rc4-bnx2i.sync/usr/iface.c +@@ -140,6 +139,7 @@ extern int idbm_discovery_read(discovery + extern int idbm_rec_read(node_rec_t *out_rec, char *target_name, + int tpgt, char *addr, int port, + struct iface_rec *iface); ++extern int idbm_parse_param(char *param, struct node_rec *rec); + extern int idbm_node_set_param(void *data, node_rec_t *rec); + extern int idbm_discovery_set_param(void *data, discovery_rec_t *rec); + extern void idbm_node_setup_defaults(node_rec_t *rec); +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iface.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/iface.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/iface.c 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/iface.c 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iface.c 2012-03-05 23:05:52.000000000 -0600 @@ -26,6 +26,7 @@ #include #include @@ -6180,15 +5964,16 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iface.c open-iscsi-2.0-872-rc4-bnx2 #include "log.h" #include "list.h" -@@ -39,6 +40,7 @@ +@@ -39,6 +40,8 @@ #include "host.h" #include "fw_context.h" #include "sysdeps.h" +#include "iscsi_err.h" ++#include "iscsi_netlink.h" /* * Default ifaces for use with transports that do not bind to hardware -@@ -101,13 +103,13 @@ struct iface_rec *iface_alloc(char *ifna +@@ -101,13 +104,13 @@ struct iface_rec *iface_alloc(char *ifna struct iface_rec *iface; if (!strlen(ifname) || strlen(ifname) + 1 > ISCSI_MAX_IFACE_LEN) { @@ -6204,7 +5989,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iface.c open-iscsi-2.0-872-rc4-bnx2 return NULL; } -@@ -125,11 +127,11 @@ static int __iface_conf_read(struct ifac +@@ -125,11 +128,11 @@ static int __iface_conf_read(struct ifac iface_conf = calloc(1, PATH_MAX); if (!iface_conf) @@ -6218,7 +6003,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iface.c open-iscsi-2.0-872-rc4-bnx2 goto free_conf; } -@@ -147,7 +149,7 @@ static int __iface_conf_read(struct ifac +@@ -147,7 +150,7 @@ static int __iface_conf_read(struct ifac iface_setup_defaults(iface); rc = 0; } else @@ -6227,7 +6012,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iface.c open-iscsi-2.0-872-rc4-bnx2 goto free_info; } -@@ -213,12 +215,12 @@ int iface_conf_delete(struct iface_rec * +@@ -213,12 +216,12 @@ int iface_conf_delete(struct iface_rec * if (def_iface) { log_error("iface %s is a special interface and " "cannot be deleted.\n", iface->name); @@ -6242,7 +6027,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iface.c open-iscsi-2.0-872-rc4-bnx2 sprintf(iface_conf, "%s/%s", IFACE_CONFIG_DIR, iface->name); rc = idbm_lock(); -@@ -226,7 +228,7 @@ int iface_conf_delete(struct iface_rec * +@@ -226,7 +229,7 @@ int iface_conf_delete(struct iface_rec * goto free_conf; if (unlink(iface_conf)) @@ -6251,7 +6036,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iface.c open-iscsi-2.0-872-rc4-bnx2 idbm_unlock(); free_conf: -@@ -246,17 +248,17 @@ int iface_conf_write(struct iface_rec *i +@@ -246,17 +249,17 @@ int iface_conf_write(struct iface_rec *i log_error("iface %s is a special interface and " "is not stored in %s.\n", iface->name, IFACE_CONFIG_DIR); @@ -6272,7 +6057,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iface.c open-iscsi-2.0-872-rc4-bnx2 goto free_conf; } -@@ -285,12 +287,12 @@ int iface_conf_update(struct db_set_para +@@ -285,12 +288,12 @@ int iface_conf_update(struct db_set_para if (def_iface) { log_error("iface %s is a special interface and " "cannot be modified.\n", iface->name); @@ -6287,7 +6072,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iface.c open-iscsi-2.0-872-rc4-bnx2 idbm_recinfo_iface(iface, info); rc = idbm_verify_param(info, param->name); -@@ -298,10 +300,8 @@ int iface_conf_update(struct db_set_para +@@ -298,10 +301,8 @@ int iface_conf_update(struct db_set_para goto free_info; rc = idbm_rec_update_param(info, param->name, param->value, 0); @@ -6299,7 +6084,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iface.c open-iscsi-2.0-872-rc4-bnx2 rc = iface_conf_write(iface); free_info: -@@ -309,6 +309,7 @@ free_info: +@@ -309,6 +310,7 @@ free_info: return rc; } @@ -6307,7 +6092,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iface.c open-iscsi-2.0-872-rc4-bnx2 static int iface_get_next_id(void) { struct stat statb; -@@ -346,6 +347,7 @@ static int iface_get_next_id(void) +@@ -346,6 +348,7 @@ static int iface_get_next_id(void) free(iface_conf); return rc; } @@ -6315,7 +6100,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iface.c open-iscsi-2.0-872-rc4-bnx2 struct iface_search { struct iface_rec *pattern; -@@ -362,7 +364,8 @@ static int __iface_get_by_net_binding(vo +@@ -362,7 +365,8 @@ static int __iface_get_by_net_binding(vo } if (iface_is_bound_by_hwaddr(search->pattern)) { @@ -6325,26 +6110,148 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iface.c open-iscsi-2.0-872-rc4-bnx2 iface_copy(search->found, iface); return 1; } else -@@ -418,7 +421,7 @@ int iface_get_by_net_binding(struct ifac +@@ -418,15 +422,64 @@ int iface_get_by_net_binding(struct ifac __iface_get_by_net_binding); if (rc == 1) return 0; - return ENODEV; + return ISCSI_ERR_NO_OBJS_FOUND; ++} ++ ++static int iface_get_iptype(struct iface_rec *iface) ++{ ++ if (strcmp(iface->bootproto, "dhcp") && !strstr(iface->ipaddress, ".")) ++ return ISCSI_IFACE_TYPE_IPV6; ++ else ++ return ISCSI_IFACE_TYPE_IPV4; ++} ++ ++static int iface_setup_binding_from_kern_iface(void *data, ++ struct iface_rec *kern_iface) ++{ ++ struct host_info *hinfo = data; ++ struct iface_rec iface; ++ ++ if (!strlen(hinfo->iface.hwaddress)) { ++ log_error("Invalid offload iSCSI host %u. Missing " ++ "hwaddress. Try upgrading %s driver.\n", ++ hinfo->host_no, hinfo->iface.transport_name); ++ return 0; ++ } ++ ++ memset(&iface, 0, sizeof(struct iface_rec)); ++ strcpy(iface.hwaddress, hinfo->iface.hwaddress); ++ strcpy(iface.transport_name, hinfo->iface.transport_name); ++ ++ if (kern_iface) { ++ iface.iface_num = kern_iface->iface_num; ++ ++ snprintf(iface.name, sizeof(iface.name), "%s.%s.%s.%u", ++ kern_iface->transport_name, ++ kern_iface->hwaddress, ++ iface_get_iptype(kern_iface) == ISCSI_IFACE_TYPE_IPV4 ? ++ "ipv4" : "ipv6", kern_iface->iface_num); ++ } else { ++ snprintf(iface.name, sizeof(iface.name), "%s.%s", ++ hinfo->iface.transport_name, hinfo->iface.hwaddress); ++ } ++ ++ if (iface_conf_read(&iface)) { ++ /* not found so create it */ ++ if (iface_conf_write(&iface)) { ++ log_error("Could not create default iface conf %s.", ++ iface.name); ++ /* fall through - will not be persistent */ ++ } ++ } ++ ++ return 0; } static int __iface_setup_host_bindings(void *data, struct host_info *hinfo) -@@ -438,7 +441,8 @@ static int __iface_setup_host_bindings(v + { + struct iface_rec *def_iface; +- struct iface_rec iface; + struct iscsi_transport *t; +- int i = 0; ++ int i = 0, nr_found; + + t = iscsi_sysfs_get_transport_by_hba(hinfo->host_no); + if (!t) +@@ -438,25 +491,12 @@ static int __iface_setup_host_bindings(v return 0; } - if (iface_get_by_net_binding(&hinfo->iface, &iface) == ENODEV) { -+ if (iface_get_by_net_binding(&hinfo->iface, &iface) == -+ ISCSI_ERR_NO_OBJS_FOUND) { - /* Must be a new port */ - if (!strlen(hinfo->iface.hwaddress)) { - log_error("Invalid offload iSCSI host %u. Missing " -@@ -704,7 +708,7 @@ int iface_for_each_iface(void *data, int +- /* Must be a new port */ +- if (!strlen(hinfo->iface.hwaddress)) { +- log_error("Invalid offload iSCSI host %u. Missing " +- "hwaddress. Try upgrading %s driver.\n", +- hinfo->host_no, t->name); +- return 0; +- } +- +- memset(&iface, 0, sizeof(struct iface_rec)); +- strcpy(iface.hwaddress, hinfo->iface.hwaddress); +- strcpy(iface.transport_name, hinfo->iface.transport_name); +- snprintf(iface.name, sizeof(iface.name), "%s.%s", +- t->name, hinfo->iface.hwaddress); +- if (iface_conf_write(&iface)) +- log_error("Could not create default iface conf %s.", +- iface.name); +- /* fall through - will not be persistent */ +- } ++ nr_found = 0; ++ iscsi_sysfs_for_each_iface_on_host(hinfo, hinfo->host_no, ++ &nr_found, ++ iface_setup_binding_from_kern_iface); ++ if (!nr_found) ++ iface_setup_binding_from_kern_iface(hinfo, NULL); + return 0; + } + +@@ -492,10 +532,40 @@ void iface_copy(struct iface_rec *dst, s + { + if (strlen(src->name)) + strcpy(dst->name, src->name); ++ if (src->iface_num) ++ dst->iface_num = src->iface_num; + if (strlen(src->netdev)) + strcpy(dst->netdev, src->netdev); + if (strlen(src->ipaddress)) + strcpy(dst->ipaddress, src->ipaddress); ++ if (strlen(src->subnet_mask)) ++ strcpy(dst->subnet_mask, src->subnet_mask); ++ if (strlen(src->gateway)) ++ strcpy(dst->gateway, src->gateway); ++ if (strlen(src->bootproto)) ++ strcpy(dst->bootproto, src->bootproto); ++ if (strlen(src->ipv6_linklocal)) ++ strcpy(dst->ipv6_linklocal, src->ipv6_linklocal); ++ if (strlen(src->ipv6_router)) ++ strcpy(dst->ipv6_router, src->ipv6_router); ++ if (strlen(src->ipv6_autocfg)) ++ strcpy(dst->ipv6_autocfg, src->ipv6_autocfg); ++ if (strlen(src->linklocal_autocfg)) ++ strcpy(dst->linklocal_autocfg, src->linklocal_autocfg); ++ if (strlen(src->router_autocfg)) ++ strcpy(dst->router_autocfg, src->router_autocfg); ++ if (src->vlan_id) ++ dst->vlan_id = src->vlan_id; ++ if (src->vlan_priority) ++ dst->vlan_priority = src->vlan_priority; ++ if (strlen(src->vlan_state)) ++ strcpy(dst->vlan_state, src->vlan_state); ++ if (strlen(src->state)) ++ strcpy(dst->state, src->state); ++ if (src->mtu) ++ dst->mtu = src->mtu; ++ if (src->port) ++ dst->port = src->port; + if (strlen(src->hwaddress)) + strcpy(dst->hwaddress, src->hwaddress); + if (strlen(src->transport_name)) +@@ -704,7 +774,7 @@ int iface_for_each_iface(void *data, int iface_dent->d_name); iface = iface_alloc(iface_dent->d_name, &err); if (!iface || err) { @@ -6353,7 +6260,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iface.c open-iscsi-2.0-872-rc4-bnx2 log_error("Invalid iface name %s. Must be " "from 1 to %d characters.", iface_dent->d_name, -@@ -756,7 +760,7 @@ static int iface_link(void *data, struct +@@ -756,7 +826,7 @@ static int iface_link(void *data, struct iface_copy = calloc(1, sizeof(*iface_copy)); if (!iface_copy) @@ -6362,7 +6269,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iface.c open-iscsi-2.0-872-rc4-bnx2 memcpy(iface_copy, iface, sizeof(*iface_copy)); INIT_LIST_HEAD(&iface_copy->list); -@@ -788,42 +792,54 @@ void iface_link_ifaces(struct list_head +@@ -788,46 +858,57 @@ void iface_link_ifaces(struct list_head int iface_setup_from_boot_context(struct iface_rec *iface, struct boot_context *context) { @@ -6435,7 +6342,11 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iface.c open-iscsi-2.0-872-rc4-bnx2 memset(iface->name, 0, sizeof(iface->name)); snprintf(iface->name, sizeof(iface->name), "%s.%s", iface->transport_name, context->mac); -@@ -885,3 +901,821 @@ fail: +- + strlcpy(iface->hwaddress, context->mac, + sizeof(iface->hwaddress)); + strlcpy(iface->ipaddress, context->ipaddr, +@@ -885,3 +966,841 @@ fail: } return rc; } @@ -6459,9 +6370,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iface.c open-iscsi-2.0-872-rc4-bnx2 + if (strcmp(iface_params->primary->hwaddress, iface->hwaddress)) + return 0; + -+ if (strcmp(iface->bootproto, "dhcp") && !strstr(iface->ipaddress, ".")) -+ iptype = ISCSI_IFACE_TYPE_IPV6; -+ ++ iptype = iface_get_iptype(iface); + if (iptype == ISCSI_IFACE_TYPE_IPV4) { + + if (strcmp(iface->state, "disable")) { @@ -6651,14 +6560,16 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iface.c open-iscsi-2.0-872-rc4-bnx2 + int len; + struct iscsi_iface_param_info *net_param; + uint16_t port = 3260; ++ struct nlattr *attr; + -+ len = sizeof(struct iscsi_iface_param_info) + 2; -+ iov->iov_base = calloc(len, sizeof(char)); -+ if (!(iov->iov_base)) ++ len = sizeof(struct iscsi_iface_param_info) + sizeof(port); ++ iov->iov_base = iscsi_nla_alloc(ISCSI_NET_PARAM_PORT, len); ++ if (!iov->iov_base) + return 1; ++ attr = iov->iov_base; ++ iov->iov_len = NLA_ALIGN(attr->nla_len); + -+ iov->iov_len = len; -+ net_param = (struct iscsi_iface_param_info *)(iov->iov_base); ++ net_param = (struct iscsi_iface_param_info *)ISCSI_NLA_DATA(attr); + net_param->param = ISCSI_NET_PARAM_PORT; + net_param->iface_type = iface_type; + net_param->iface_num = iface->iface_num; @@ -6676,14 +6587,16 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iface.c open-iscsi-2.0-872-rc4-bnx2 + int len; + struct iscsi_iface_param_info *net_param; + uint16_t mtu = 0; ++ struct nlattr *attr; + + len = sizeof(struct iscsi_iface_param_info) + 2; -+ iov->iov_base = calloc(len, sizeof(char)); ++ iov->iov_base = iscsi_nla_alloc(ISCSI_NET_PARAM_MTU, len); + if (!(iov->iov_base)) + return 1; ++ attr = iov->iov_base; ++ iov->iov_len = NLA_ALIGN(attr->nla_len); + -+ iov->iov_len = len; -+ net_param = (struct iscsi_iface_param_info *)(iov->iov_base); ++ net_param = (struct iscsi_iface_param_info *)ISCSI_NLA_DATA(attr); + net_param->param = ISCSI_NET_PARAM_MTU; + net_param->iface_type = iface_type; + net_param->iface_num = iface->iface_num; @@ -6701,15 +6614,17 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iface.c open-iscsi-2.0-872-rc4-bnx2 + int len; + struct iscsi_iface_param_info *net_param; + uint16_t vlan = 0; ++ struct nlattr *attr; + + len = sizeof(struct iscsi_iface_param_info) + 2; -+ iov->iov_base = calloc(len, sizeof(char)); ++ iov->iov_base = iscsi_nla_alloc(ISCSI_NET_PARAM_VLAN_TAG, len); + if (!(iov->iov_base)) + return 1; + -+ iov->iov_len = len; -+ net_param = (struct iscsi_iface_param_info *)(iov->iov_base); -+ net_param->param = ISCSI_NET_PARAM_VLAN_ID; ++ attr = iov->iov_base; ++ iov->iov_len = NLA_ALIGN(attr->nla_len); ++ net_param = (struct iscsi_iface_param_info *)ISCSI_NLA_DATA(attr); ++ net_param->param = ISCSI_NET_PARAM_VLAN_TAG; + net_param->iface_type = iface_type; + net_param->iface_num = iface->iface_num; + net_param->param_type = ISCSI_NET_PARAM; @@ -6732,14 +6647,16 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iface.c open-iscsi-2.0-872-rc4-bnx2 +{ + int len; + struct iscsi_iface_param_info *net_param; ++ struct nlattr *attr; + + len = sizeof(struct iscsi_iface_param_info) + 1; -+ iov->iov_base = calloc(len, sizeof(char)); ++ iov->iov_base = iscsi_nla_alloc(ISCSI_NET_PARAM_VLAN_ENABLED, len); + if (!(iov->iov_base)) + return 1; + -+ iov->iov_len = len; -+ net_param = (struct iscsi_iface_param_info *)(iov->iov_base); ++ attr = iov->iov_base; ++ iov->iov_len = NLA_ALIGN(attr->nla_len); ++ net_param = (struct iscsi_iface_param_info *)ISCSI_NLA_DATA(attr); + net_param->param = ISCSI_NET_PARAM_VLAN_ENABLED; + net_param->iface_type = iface_type; + net_param->iface_num = iface->iface_num; @@ -6758,14 +6675,16 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iface.c open-iscsi-2.0-872-rc4-bnx2 +{ + int len; + struct iscsi_iface_param_info *net_param; ++ struct nlattr *attr; + + len = sizeof(struct iscsi_iface_param_info) + 1; -+ iov->iov_base = calloc(len, sizeof(char)); ++ iov->iov_base = iscsi_nla_alloc(ISCSI_NET_PARAM_IFACE_ENABLE, len); + if (!(iov->iov_base)) + return 1; + -+ iov->iov_len = len; -+ net_param = (struct iscsi_iface_param_info *)(iov->iov_base); ++ attr = iov->iov_base; ++ iov->iov_len = NLA_ALIGN(attr->nla_len); ++ net_param = (struct iscsi_iface_param_info *)ISCSI_NLA_DATA(attr); + net_param->param = ISCSI_NET_PARAM_IFACE_ENABLE; + net_param->iface_type = iface_type; + net_param->iface_num = iface->iface_num; @@ -6783,14 +6702,16 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iface.c open-iscsi-2.0-872-rc4-bnx2 +{ + int len; + struct iscsi_iface_param_info *net_param; ++ struct nlattr *attr; + + len = sizeof(struct iscsi_iface_param_info) + 1; -+ iov->iov_base = calloc(len, sizeof(char)); ++ iov->iov_base = iscsi_nla_alloc(ISCSI_NET_PARAM_IPV4_BOOTPROTO, len); + if (!(iov->iov_base)) + return 1; + -+ iov->iov_len = len; -+ net_param = (struct iscsi_iface_param_info *)(iov->iov_base); ++ attr = iov->iov_base; ++ iov->iov_len = NLA_ALIGN(attr->nla_len); ++ net_param = (struct iscsi_iface_param_info *)ISCSI_NLA_DATA(attr); + net_param->param = ISCSI_NET_PARAM_IPV4_BOOTPROTO; + net_param->iface_type = ISCSI_IFACE_TYPE_IPV4; + net_param->iface_num = iface->iface_num; @@ -6808,14 +6729,16 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iface.c open-iscsi-2.0-872-rc4-bnx2 +{ + int len; + struct iscsi_iface_param_info *net_param; ++ struct nlattr *attr; + + len = sizeof(struct iscsi_iface_param_info) + 1; -+ iov->iov_base = calloc(len, sizeof(char)); ++ iov->iov_base = iscsi_nla_alloc(ISCSI_NET_PARAM_IPV6_ADDR_AUTOCFG, len); + if (!(iov->iov_base)) + return 1; + -+ iov->iov_len = len; -+ net_param = (struct iscsi_iface_param_info *)(iov->iov_base); ++ attr = iov->iov_base; ++ iov->iov_len = NLA_ALIGN(attr->nla_len); ++ net_param = (struct iscsi_iface_param_info *)ISCSI_NLA_DATA(attr); + net_param->param = ISCSI_NET_PARAM_IPV6_ADDR_AUTOCFG; + net_param->iface_type = ISCSI_IFACE_TYPE_IPV6; + net_param->param_type = ISCSI_NET_PARAM; @@ -6837,14 +6760,17 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iface.c open-iscsi-2.0-872-rc4-bnx2 +{ + int len; + struct iscsi_iface_param_info *net_param; ++ struct nlattr *attr; + + len = sizeof(struct iscsi_iface_param_info) + 1; -+ iov->iov_base = calloc(len, sizeof(char)); ++ iov->iov_base = iscsi_nla_alloc(ISCSI_NET_PARAM_IPV6_LINKLOCAL_AUTOCFG, ++ len); + if (!(iov->iov_base)) + return 1; + -+ iov->iov_len = len; -+ net_param = (struct iscsi_iface_param_info *)(iov->iov_base); ++ attr = iov->iov_base; ++ iov->iov_len = NLA_ALIGN(attr->nla_len); ++ net_param = (struct iscsi_iface_param_info *)ISCSI_NLA_DATA(attr); + net_param->param = ISCSI_NET_PARAM_IPV6_LINKLOCAL_AUTOCFG; + net_param->iface_type = ISCSI_IFACE_TYPE_IPV6; + net_param->param_type = ISCSI_NET_PARAM; @@ -6863,14 +6789,17 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iface.c open-iscsi-2.0-872-rc4-bnx2 +{ + int len; + struct iscsi_iface_param_info *net_param; ++ struct nlattr *attr; + + len = sizeof(struct iscsi_iface_param_info) + 1; -+ iov->iov_base = calloc(len, sizeof(char)); ++ iov->iov_base = iscsi_nla_alloc(ISCSI_NET_PARAM_IPV6_ROUTER_AUTOCFG, ++ len); + if (!(iov->iov_base)) + return 1; + -+ iov->iov_len = len; -+ net_param = (struct iscsi_iface_param_info *)(iov->iov_base); ++ attr = iov->iov_base; ++ iov->iov_len = NLA_ALIGN(attr->nla_len); ++ net_param = (struct iscsi_iface_param_info *)ISCSI_NLA_DATA(attr); + net_param->param = ISCSI_NET_PARAM_IPV6_ROUTER_AUTOCFG; + net_param->iface_type = ISCSI_IFACE_TYPE_IPV6; + net_param->param_type = ISCSI_NET_PARAM; @@ -6891,14 +6820,16 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iface.c open-iscsi-2.0-872-rc4-bnx2 + int rc = 1; + int len; + struct iscsi_iface_param_info *net_param; ++ struct nlattr *attr; + + len = sizeof(struct iscsi_iface_param_info) + 4; -+ iov->iov_base = calloc(len, sizeof(char)); ++ iov->iov_base = iscsi_nla_alloc(param, len); + if (!(iov->iov_base)) + return 1; + -+ iov->iov_len = len; -+ net_param = (struct iscsi_iface_param_info *)(iov->iov_base); ++ attr = iov->iov_base; ++ iov->iov_len = NLA_ALIGN(attr->nla_len); ++ net_param = (struct iscsi_iface_param_info *)ISCSI_NLA_DATA(attr); + net_param->param = param; + net_param->iface_type = ISCSI_IFACE_TYPE_IPV4; + net_param->iface_num = iface->iface_num; @@ -6945,14 +6876,16 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iface.c open-iscsi-2.0-872-rc4-bnx2 + int rc; + int len; + struct iscsi_iface_param_info *net_param; ++ struct nlattr *attr; + + len = sizeof(struct iscsi_iface_param_info) + 16; -+ iov->iov_base = calloc(len, sizeof(char)); ++ iov->iov_base = iscsi_nla_alloc(param, len); + if (!(iov->iov_base)) + return 1; + -+ iov->iov_len = len; -+ net_param = (struct iscsi_iface_param_info *)(iov->iov_base); ++ attr = iov->iov_base; ++ iov->iov_len = NLA_ALIGN(attr->nla_len); ++ net_param = (struct iscsi_iface_param_info *)ISCSI_NLA_DATA(attr); + net_param->param = param; + net_param->iface_type = ISCSI_IFACE_TYPE_IPV6; + net_param->iface_num = iface->iface_num; @@ -7004,12 +6937,10 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iface.c open-iscsi-2.0-872-rc4-bnx2 + if (strcmp(net_config->primary->hwaddress, iface->hwaddress)) + return 0; + -+ if (strcmp(iface->bootproto, "dhcp") && !strstr(iface->ipaddress, ".")) -+ iptype = ISCSI_IFACE_TYPE_IPV6; -+ + /* start at 2, because 0 is for nlmsghdr and 1 for event */ + iov = net_config->iovs + 2; + ++ iptype = iface_get_iptype(iface); + if (iptype == ISCSI_IFACE_TYPE_IPV4) { + if (!strcmp(iface->state, "disable")) { + if (!iface_fill_net_state(&iov[net_config->count], @@ -7257,9 +7188,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iface.c open-iscsi-2.0-872-rc4-bnx2 + rc, net_config.count); + return net_config.count; +} -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iface.h open-iscsi-2.0-872-rc4-bnx2i.sync/usr/iface.h +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iface.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/iface.h --- open-iscsi-2.0-872-rc4-bnx2i/usr/iface.h 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/iface.h 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iface.h 2012-03-05 23:02:46.000000000 -0600 @@ -54,6 +54,10 @@ extern int iface_setup_from_boot_context struct boot_context *context); extern int iface_create_ifaces_from_boot_contexts(struct list_head *ifaces, @@ -7271,18 +7202,19 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iface.h open-iscsi-2.0-872-rc4-bnx2 #define iface_fmt "[hw=%s,ip=%s,net_if=%s,iscsi_if=%s]" #define iface_str(_iface) \ -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4-bnx2i.sync/usr/initiator.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/initiator.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/initiator.c 2011-08-14 16:48:25.000000000 -0500 -@@ -46,6 +46,7 @@ ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/initiator.c 2012-03-05 23:05:40.000000000 -0600 +@@ -46,6 +46,8 @@ #include "iscsi_settings.h" #include "iface.h" #include "sysdeps.h" +#include "iscsi_err.h" ++#include "kern_err_table.h" #define ISCSI_CONN_ERR_REOPEN_DELAY 3 #define ISCSI_INTERNAL_ERR_REOPEN_DELAY 5 -@@ -53,31 +54,17 @@ +@@ -53,31 +55,17 @@ #define PROC_DIR "/proc" static void iscsi_login_timedout(void *data); @@ -7319,7 +7251,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- ipc->ctldev_bufmax); if (!conn->context_pool[i]) { int j; -@@ -91,7 +78,7 @@ static int iscsi_conn_context_alloc(iscs +@@ -91,7 +79,7 @@ static int iscsi_conn_context_alloc(iscs return 0; } @@ -7328,7 +7260,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- { int i; -@@ -107,10 +94,10 @@ static void iscsi_conn_context_free(iscs +@@ -107,10 +95,10 @@ static void iscsi_conn_context_free(iscs } } @@ -7342,7 +7274,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- int i; if (ev_size > ipc->ctldev_bufmax) -@@ -121,26 +108,26 @@ struct iscsi_conn_context *iscsi_conn_co +@@ -121,26 +109,26 @@ struct iscsi_conn_context *iscsi_conn_co continue; if (!conn->context_pool[i]->allocated) { @@ -7380,7 +7312,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- } static void session_online_devs(int host_no, int sid) -@@ -205,11 +192,11 @@ __check_iscsi_status_class(iscsi_session +@@ -205,11 +193,11 @@ __check_iscsi_status_class(iscsi_session log_error("session %d login rejected: Initiator " "failed authentication with target", session->id); @@ -7394,7 +7326,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- case ISCSI_LOGIN_STATUS_TGT_NOT_FOUND: log_error("conn %d login rejected: initiator " "error - target not found (%02x/%02x)", -@@ -250,183 +237,6 @@ __check_iscsi_status_class(iscsi_session +@@ -250,183 +238,6 @@ __check_iscsi_status_class(iscsi_session return CONN_LOGIN_FAILED; } @@ -7578,7 +7510,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- static int __session_conn_create(iscsi_session_t *session, int cid) { -@@ -434,12 +244,12 @@ __session_conn_create(iscsi_session_t *s +@@ -434,12 +245,12 @@ __session_conn_create(iscsi_session_t *s conn_rec_t *conn_rec = &session->nrec.conn[cid]; int err; @@ -7594,7 +7526,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- conn->session = session; /* * TODO: we must export the socket_fd/transport_eph from sysfs -@@ -486,14 +296,15 @@ __session_conn_create(iscsi_session_t *s +@@ -486,14 +297,15 @@ __session_conn_create(iscsi_session_t *s conn->noop_out_interval = DEF_NOOP_OUT_INTERVAL; } @@ -7612,7 +7544,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- if (err) return err; return 0; -@@ -506,7 +317,7 @@ session_release(iscsi_session_t *session +@@ -506,7 +318,7 @@ session_release(iscsi_session_t *session if (session->target_alias) free(session->target_alias); @@ -7621,7 +7553,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- free(session); } -@@ -524,11 +335,10 @@ __session_create(node_rec_t *rec, struct +@@ -524,11 +336,10 @@ __session_create(node_rec_t *rec, struct log_debug(2, "Allocted session %p", session); INIT_LIST_HEAD(&session->list); @@ -7634,7 +7566,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- /* save node record. we might need it for redirection */ memcpy(&session->nrec, rec, sizeof(node_rec_t)); -@@ -570,7 +380,7 @@ __session_create(node_rec_t *rec, struct +@@ -570,7 +381,7 @@ __session_create(node_rec_t *rec, struct session->isid[5] = 0; /* setup authentication variables for the session*/ @@ -7643,7 +7575,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- session->param_mask = ~0ULL; if (!(t->caps & CAP_MULTI_R2T)) -@@ -601,18 +411,18 @@ __session_create(node_rec_t *rec, struct +@@ -601,18 +412,18 @@ __session_create(node_rec_t *rec, struct static void iscsi_flush_context_pool(struct iscsi_session *session) { @@ -7667,7 +7599,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- } } } -@@ -633,15 +443,16 @@ conn_delete_timers(iscsi_conn_t *conn) +@@ -633,15 +444,16 @@ conn_delete_timers(iscsi_conn_t *conn) actor_delete(&conn->nop_out_timer); } @@ -7687,7 +7619,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- if (session->id == -1) goto cleanup; -@@ -649,15 +460,15 @@ session_conn_shutdown(iscsi_conn_t *conn +@@ -649,15 +461,15 @@ session_conn_shutdown(iscsi_conn_t *conn if (!iscsi_sysfs_session_has_leadconn(session->id)) goto cleanup; @@ -7707,7 +7639,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- } } -@@ -665,16 +476,18 @@ session_conn_shutdown(iscsi_conn_t *conn +@@ -665,16 +477,17 @@ session_conn_shutdown(iscsi_conn_t *conn if (ipc->destroy_conn(session->t->handle, session->id, conn->id)) { log_error("can not safely destroy connection %d", conn->id); @@ -7718,10 +7650,8 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- cleanup: if (session->id != -1) { log_debug(2, "kdestroy session %u", session->id); -- if (ipc->destroy_session(session->t->handle, session->id)) { + session->r_stage = R_STAGE_SESSION_DESTOYED; -+ err = ipc->destroy_session(session->t->handle, session->id); -+ if (err) { + if (ipc->destroy_session(session->t->handle, session->id)) { log_error("can not safely destroy session %d", session->id); - return MGMT_IPC_ERR_INTERNAL; @@ -7957,7 +7887,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- log_debug(1, "ignoring conn error in CLEANUP_WAIT. " "let connection stop"); return; -@@ -1020,19 +843,19 @@ __conn_error_handle(iscsi_session_t *ses +@@ -1020,19 +843,20 @@ __conn_error_handle(iscsi_session_t *ses static void session_conn_error(void *data) { @@ -7969,10 +7899,13 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- + iscsi_conn_t *conn = ev_context->conn; iscsi_session_t *session = conn->session; - log_warning("Kernel reported iSCSI connection %d:%d error (%d) " +- log_warning("Kernel reported iSCSI connection %d:%d error (%d) " ++ log_warning("Kernel reported iSCSI connection %d:%d error (%d - %s) " "state (%d)", session->id, conn->id, error, - conn->state); +- conn->state); - iscsi_conn_context_put(conn_context); ++ kern_err_code_to_string(error), conn->state); ++ + iscsi_ev_context_put(ev_context); switch (error) { @@ -7982,7 +7915,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- log_error("BUG: Could not shutdown session."); break; default: -@@ -1046,14 +869,14 @@ static void iscsi_login_timedout(void *d +@@ -1046,14 +870,14 @@ static void iscsi_login_timedout(void *d struct iscsi_conn *conn = qtask->conn; switch (conn->state) { @@ -8002,7 +7935,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- break; } } -@@ -1125,7 +948,7 @@ static void conn_send_nop_out(void *data +@@ -1125,7 +949,7 @@ static void conn_send_nop_out(void *data * we cannot start new request during logout and the logout timer * will figure things out. */ @@ -8011,7 +7944,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- return; __send_nopout(conn); -@@ -1136,17 +959,6 @@ static void conn_send_nop_out(void *data +@@ -1136,17 +960,6 @@ static void conn_send_nop_out(void *data &conn->nop_out_timer, conn->noop_out_timeout); } @@ -8029,7 +7962,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- void free_initiator(void) { struct iscsi_transport *t; -@@ -1170,7 +982,7 @@ static void session_scan_host(struct isc +@@ -1170,7 +983,7 @@ static void session_scan_host(struct isc pid = iscsi_sysfs_scan_host(hostno, 1); if (pid == 0) { @@ -8038,7 +7971,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- if (session) iscsi_sysfs_for_each_device( -@@ -1185,306 +997,37 @@ static void session_scan_host(struct isc +@@ -1185,306 +998,37 @@ static void session_scan_host(struct isc free(qtask); } } else @@ -8298,7 +8231,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- - MGMT_IPC_ERR_LOGIN_FAILURE); - return; - } -- + - if (rc == -ENOSYS) { - switch (conntbl[i].param) { - case ISCSI_PARAM_PING_TMO: @@ -8314,7 +8247,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- - break; - } - } - +- - print_param_value(conntbl[i].param, conntbl[i].value, - conntbl[i].type); + if (iscsi_session_set_params(conn)) { @@ -8355,7 +8288,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- if (session->r_stage == R_STAGE_NO_CHANGE || session->r_stage == R_STAGE_SESSION_REDIRECT) { /* -@@ -1501,10 +1044,10 @@ setup_full_feature_phase(iscsi_conn_t *c +@@ -1501,10 +1045,10 @@ setup_full_feature_phase(iscsi_conn_t *c session->nrec.conn[conn->id].port, session->nrec.iface.name); } else { @@ -8368,7 +8301,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- log_warning("connection%d:%d is operational after recovery " "(%d attempts)", session->id, conn->id, session->reopen_cnt); -@@ -1527,12 +1070,12 @@ setup_full_feature_phase(iscsi_conn_t *c +@@ -1527,12 +1071,12 @@ setup_full_feature_phase(iscsi_conn_t *c static void iscsi_logout_timedout(void *data) { @@ -8385,7 +8318,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- * was some nasty error */ log_debug(3, "logout timeout, dropping conn...\n"); -@@ -1542,9 +1085,9 @@ static void iscsi_logout_timedout(void * +@@ -1542,9 +1086,9 @@ static void iscsi_logout_timedout(void * static int iscsi_send_logout(iscsi_conn_t *conn) { struct iscsi_logout hdr; @@ -8397,7 +8330,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- return EINVAL; memset(&hdr, 0, sizeof(struct iscsi_logout)); -@@ -1556,14 +1099,14 @@ static int iscsi_send_logout(iscsi_conn_ +@@ -1556,14 +1100,14 @@ static int iscsi_send_logout(iscsi_conn_ if (!iscsi_io_send_pdu(conn, (struct iscsi_hdr*)&hdr, ISCSI_DIGEST_NONE, NULL, ISCSI_DIGEST_NONE, 0)) return EIO; @@ -8416,7 +8349,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- conn->logout_timeout, EV_CONN_LOGOUT_TIMER); log_debug(3, "logout timeout timer %u\n", -@@ -1575,16 +1118,18 @@ static int iscsi_send_logout(iscsi_conn_ +@@ -1575,16 +1119,18 @@ static int iscsi_send_logout(iscsi_conn_ static void iscsi_stop(void *data) { @@ -8441,7 +8374,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- if (rc) log_error("BUG: Could not shutdown session."); } -@@ -1683,6 +1228,7 @@ static void iscsi_recv_login_rsp(struct +@@ -1683,6 +1229,7 @@ static void iscsi_recv_login_rsp(struct { struct iscsi_session *session = conn->session; iscsi_login_context_t *c = &conn->login_context; @@ -8449,7 +8382,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- if (iscsi_login_rsp(session, c)) { log_debug(1, "login_rsp ret (%d)", c->ret); -@@ -1703,6 +1249,9 @@ static void iscsi_recv_login_rsp(struct +@@ -1703,6 +1250,9 @@ static void iscsi_recv_login_rsp(struct switch (__check_iscsi_status_class(session, conn->id, c->status_class, c->status_detail)) { @@ -8459,7 +8392,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- case CONN_LOGIN_FAILED: goto failed; case CONN_LOGIN_IMM_REDIRECT_RETRY: -@@ -1718,10 +1267,9 @@ static void iscsi_recv_login_rsp(struct +@@ -1718,10 +1268,9 @@ static void iscsi_recv_login_rsp(struct if (conn->current_stage != ISCSI_FULL_FEATURE_PHASE) { /* more nego. needed! */ @@ -8472,7 +8405,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- return; } } else -@@ -1730,36 +1278,35 @@ static void iscsi_recv_login_rsp(struct +@@ -1730,36 +1279,35 @@ static void iscsi_recv_login_rsp(struct return; retry: /* retry if not initial login or initial login has not timed out */ @@ -8521,7 +8454,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- switch (hdr.opcode & ISCSI_OPCODE_MASK) { case ISCSI_OP_NOOP_IN: -@@ -1776,18 +1323,18 @@ static void session_conn_recv_pdu(void * +@@ -1776,18 +1324,18 @@ static void session_conn_recv_pdu(void * break; } break; @@ -8545,7 +8478,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- log_error("Invalid state. Dropping PDU.\n"); } } -@@ -1908,35 +1455,66 @@ retry_create: +@@ -1908,35 +1456,72 @@ retry_create: return err; } @@ -8570,9 +8503,15 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- + conn->state = ISCSI_CONN_STATE_IN_LOGIN; + if (ipc->start_conn(session->t->handle, session->id, conn->id, + &rc) || rc) { -+ log_error("can't start connection %d:%d retcode %d (%d)", -+ session->id, conn->id, rc, errno); -+ iscsi_login_eh(conn, c->qtask, ISCSI_ERR_INTERNAL); ++ if (rc == -EEXIST) { ++ log_error("Session already exists."); ++ session_conn_shutdown(conn, c->qtask, ++ ISCSI_ERR_SESS_EXISTS); ++ } else { ++ log_error("can't start connection %d:%d retcode (%d)", ++ session->id, conn->id, rc); ++ iscsi_login_eh(conn, c->qtask, ISCSI_ERR_INTERNAL); ++ } + return; + } + @@ -8623,7 +8562,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- } else if (rc > 0) { /* connected! */ memset(c, 0, sizeof(iscsi_login_context_t)); -@@ -1945,26 +1523,26 @@ static void session_conn_poll(void *data +@@ -1945,26 +1530,26 @@ static void session_conn_poll(void *data if (session->id == -1) { if (conn->id == 0 && session_ipc_create(session)) { log_error("Can't create session."); @@ -8658,7 +8597,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- /* * TODO: use the iface number or some other value * so this will be persistent -@@ -1977,7 +1555,7 @@ static void session_conn_poll(void *data +@@ -1977,7 +1562,7 @@ static void session_conn_poll(void *data log_error("can't bind conn %d:%d to session %d, " "retcode %d (%d)", session->id, conn->id, session->id, rc, errno); @@ -8667,7 +8606,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- return; } log_debug(3, "bound iSCSI connection %d:%d to session %d", -@@ -1990,14 +1568,19 @@ static void session_conn_poll(void *data +@@ -1990,14 +1575,19 @@ static void session_conn_poll(void *data conn->exp_statsn = iscsi_sysfs_get_exp_statsn(session->id); @@ -8690,7 +8629,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- return; } } else { -@@ -2011,70 +1594,125 @@ cleanup: +@@ -2011,70 +1601,126 @@ cleanup: session_conn_shutdown(conn, qtask, err); } @@ -8738,9 +8677,10 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- + session->nrec.conn[conn->id].address, + session->nrec.conn[conn->id].port, + session->nrec.iface.name); -+ } else ++ } else { + session->notify_qtask = NULL; -+ ++ mgmt_ipc_write_rsp(c->qtask, ISCSI_SUCCESS); ++ } + + /* + * reset ERL=0 reopen counter @@ -8853,7 +8793,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- } static iscsi_session_t* session_find_by_rec(node_rec_t *rec) -@@ -2087,7 +1725,8 @@ static iscsi_session_t* session_find_by_ +@@ -2087,7 +1733,8 @@ static iscsi_session_t* session_find_by_ if (__iscsi_match_session(rec, session->nrec.name, session->nrec.conn[0].address, session->nrec.conn[0].port, @@ -8863,7 +8803,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- return session; } } -@@ -2111,65 +1750,24 @@ static int session_is_running(node_rec_t +@@ -2111,65 +1758,24 @@ static int session_is_running(node_rec_t return 0; } @@ -8937,7 +8877,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- if ((!(t->caps & CAP_RECOVERY_L0) && rec->session.iscsi.ERL != 0) || -@@ -2222,27 +1820,22 @@ session_login_task(node_rec_t *rec, queu +@@ -2222,27 +1828,22 @@ session_login_task(node_rec_t *rec, queu session = __session_create(rec, t); if (!session) @@ -8971,7 +8911,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- } if (gettimeofday(&conn->initial_connect_time, NULL)) -@@ -2250,26 +1843,37 @@ session_login_task(node_rec_t *rec, queu +@@ -2250,26 +1851,37 @@ session_login_task(node_rec_t *rec, queu "login errors iscsid may give up the initial " "login early. You should manually login."); @@ -9015,7 +8955,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- iscsi_sync_session(node_rec_t *rec, queue_task_t *qtask, uint32_t sid) { iscsi_session_t *session; -@@ -2278,38 +1882,32 @@ iscsi_sync_session(node_rec_t *rec, queu +@@ -2278,38 +1890,32 @@ iscsi_sync_session(node_rec_t *rec, queu t = iscsi_sysfs_get_transport_by_name(rec->iface.transport_name); if (!t) @@ -9061,7 +9001,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- return 0; destroy_session: -@@ -2329,37 +1927,35 @@ static int session_unbind(struct iscsi_s +@@ -2329,37 +1935,35 @@ static int session_unbind(struct iscsi_s return err; } @@ -9106,7 +9046,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- if (conn->logout_qtask) goto invalid_state; -@@ -2368,41 +1964,45 @@ invalid_state: +@@ -2368,41 +1972,45 @@ invalid_state: conn->logout_qtask = qtask; switch (conn->state) { @@ -9164,7 +9104,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- } /* -@@ -2412,7 +2012,7 @@ iscsi_host_send_targets(queue_task_t *qt +@@ -2412,7 +2020,7 @@ iscsi_host_send_targets(queue_task_t *qt * the card will have sessions preset in the FLASH and will log into them * automaotically then send us notification that a session is setup. */ @@ -9173,7 +9113,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- { struct iscsi_transport *transport; -@@ -2428,7 +2028,20 @@ void iscsi_async_session_creation(uint32 +@@ -2428,7 +2036,20 @@ void iscsi_async_session_creation(uint32 session_scan_host(NULL, host_no, NULL); } @@ -9195,9 +9135,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4- +{ + ipc_register_ev_callback(&ipc_clbk); +} -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator_common.c open-iscsi-2.0-872-rc4-bnx2i.sync/usr/initiator_common.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator_common.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/initiator_common.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/initiator_common.c 1969-12-31 18:00:00.000000000 -0600 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/initiator_common.c 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/initiator_common.c 2012-03-05 23:02:46.000000000 -0600 @@ -0,0 +1,607 @@ +/* + * Common code for setting up discovery and normal sessions. @@ -9806,9 +9746,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator_common.c open-iscsi-2.0-8 + } + return 0; +} -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.h open-iscsi-2.0-872-rc4-bnx2i.sync/usr/initiator.h +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/initiator.h --- open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.h 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/initiator.h 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/initiator.h 2012-03-05 23:02:46.000000000 -0600 @@ -39,25 +39,18 @@ #define INITIATOR_NAME_FILE ISCSI_CONFIG_ROOT"initiatorname.iscsi" @@ -9976,9 +9916,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.h open-iscsi-2.0-872-rc4- +extern int iscsi_setup_portal(struct iscsi_conn *conn, char *address, int port); #endif /* INITIATOR_H */ -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/io.c open-iscsi-2.0-872-rc4-bnx2i.sync/usr/io.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/io.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/io.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/io.c 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/io.c 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/io.c 2012-03-05 23:02:46.000000000 -0600 @@ -26,11 +26,14 @@ #include #include @@ -10408,9 +10348,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/io.c open-iscsi-2.0-872-rc4-bnx2i.s } return h_bytes + ahs_bytes + d_bytes; -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsiadm.c open-iscsi-2.0-872-rc4-bnx2i.sync/usr/iscsiadm.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsiadm.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsiadm.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsiadm.c 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/iscsiadm.c 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsiadm.c 2012-03-05 23:02:46.000000000 -0600 @@ -4,6 +4,7 @@ * Copyright (C) 2004 Dmitry Yusupov, Alex Aizman * Copyright (C) 2006 Mike Christie @@ -10553,7 +10493,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsiadm.c open-iscsi-2.0-872-rc4-b } return err; -@@ -313,7 +324,7 @@ static int link_recs(void *data, struct +@@ -313,7 +324,7 @@ static int link_recs(void *data, struct rec_copy = calloc(1, sizeof(*rec_copy)); if (!rec_copy) @@ -10830,7 +10770,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsiadm.c open-iscsi-2.0-872-rc4-b { struct rec_op_data op_data; int nr_found = 0, rc; -@@ -475,30 +591,51 @@ static int for_each_rec(struct node_rec +@@ -475,30 +591,51 @@ static int for_each_rec(struct node_rec op_data.match_rec = rec; op_data.fn = fn; @@ -11004,7 +10944,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsiadm.c open-iscsi-2.0-872-rc4-b } return idbm_delete_node(rec); -@@ -822,18 +954,18 @@ static int delete_stale_rec(void *data, +@@ -822,18 +954,18 @@ static int delete_stale_rec(void *data, * if we are not from the same discovery source * ignore it */ @@ -11028,7 +10968,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsiadm.c open-iscsi-2.0-872-rc4-b } static int -@@ -918,8 +1050,12 @@ do_software_sendtargets(discovery_rec_t +@@ -918,8 +1050,12 @@ do_software_sendtargets(discovery_rec_t rc = idbm_bind_ifaces_to_nodes(discovery_sendtargets, drec, ifaces, &rec_list); if (rc) { @@ -11486,7 +11426,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsiadm.c open-iscsi-2.0-872-rc4-b */ static int exec_discover(int disc_type, char *ip, int port, struct list_head *ifaces, int info_level, -@@ -1506,15 +1776,16 @@ static int exec_discover(int disc_type, +@@ -1506,15 +1776,16 @@ static int exec_discover(int disc_type, if (ip == NULL) { log_error("Please specify portal as [:]"); @@ -11506,7 +11446,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsiadm.c open-iscsi-2.0-872-rc4-b } else { printf("New discovery record for [%s,%d] added.\n", ip, port); -@@ -1527,7 +1798,7 @@ static int exec_discover(int disc_type, +@@ -1527,7 +1798,7 @@ static int exec_discover(int disc_type, if (!do_discover) { log_error("Discovery record [%s,%d] not found.", ip, port); @@ -11515,7 +11455,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsiadm.c open-iscsi-2.0-872-rc4-b } /* Just add default rec for user */ -@@ -1539,11 +1810,11 @@ static int exec_discover(int disc_type, +@@ -1539,11 +1810,11 @@ static int exec_discover(int disc_type, if (rc) { log_error("Could not add new discovery " "record."); @@ -11529,7 +11469,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsiadm.c open-iscsi-2.0-872-rc4-b rc = 0; switch (disc_type) { -@@ -1563,9 +1834,7 @@ static int exec_discover(int disc_type, +@@ -1563,9 +1834,7 @@ static int exec_discover(int disc_type, break; } @@ -11540,7 +11480,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsiadm.c open-iscsi-2.0-872-rc4-b } static int exec_disc2_op(int disc_type, char *ip, int port, -@@ -1587,12 +1856,12 @@ static int exec_disc2_op(int disc_type, +@@ -1587,12 +1856,12 @@ static int exec_disc2_op(int disc_type, rc = exec_discover(disc_type, ip, port, ifaces, info_level, do_login, do_discover, op, &drec); @@ -11555,7 +11495,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsiadm.c open-iscsi-2.0-872-rc4-b goto done; case DISCOVERY_TYPE_ISNS: if (port < 0) -@@ -1600,29 +1869,30 @@ static int exec_disc2_op(int disc_type, +@@ -1600,29 +1869,30 @@ static int exec_disc2_op(int disc_type, rc = exec_discover(disc_type, ip, port, ifaces, info_level, do_login, do_discover, op, &drec); @@ -12004,9 +11944,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsiadm.c open-iscsi-2.0-872-rc4-b } break; default: -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsid.c open-iscsi-2.0-872-rc4-bnx2i.sync/usr/iscsid.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsid.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsid.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsid.c 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/iscsid.c 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsid.c 2012-03-05 23:05:31.000000000 -0600 @@ -31,6 +31,8 @@ #include #include @@ -12070,7 +12010,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsid.c open-iscsi-2.0-872-rc4-bnx /* * Just rescan the device in case this is the first startup. -@@ -213,7 +213,8 @@ static int sync_session(void *data, stru +@@ -213,13 +213,17 @@ static int sync_session(void *data, stru host_no = iscsi_sysfs_get_host_no_from_sid(info->sid, &err); if (err) { log_error("Could not get host no from sid %u. Can not " @@ -12080,7 +12020,16 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsid.c open-iscsi-2.0-872-rc4-bnx return 0; } iscsi_sysfs_scan_host(host_no, 0); -@@ -272,7 +273,7 @@ static int sync_session(void *data, stru + return 0; + } + ++ if (!iscsi_sysfs_session_user_created(info->sid)) ++ return 0; ++ + memset(&rec, 0, sizeof(node_rec_t)); + /* + * We might get the local ip address for software. We do not +@@ -272,7 +276,7 @@ static int sync_session(void *data, stru retry: rc = iscsid_exec_req(&req, &rsp, 0); @@ -12089,7 +12038,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsid.c open-iscsi-2.0-872-rc4-bnx retries++; sleep(1); goto retry; -@@ -302,7 +303,12 @@ static void iscsid_shutdown(void) +@@ -302,7 +306,12 @@ static void iscsid_shutdown(void) static void catch_signal(int signo) { @@ -12103,7 +12052,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsid.c open-iscsi-2.0-872-rc4-bnx switch (signo) { case SIGTERM: iscsid_shutdown(); -@@ -318,7 +324,7 @@ static void missing_iname_warn(char *ini +@@ -318,7 +327,7 @@ static void missing_iname_warn(char *ini log_error("Warning: InitiatorName file %s does not exist or does not " "contain a properly formated InitiatorName. If using " "software iscsi (iscsi_tcp or ib_iser) or partial offload " @@ -12112,7 +12061,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsid.c open-iscsi-2.0-872-rc4-bnx "into or discover targets. Please create a file %s that " "contains a sting with the format: InitiatorName=" "iqn.yyyy-mm.[:identifier].\n\n" -@@ -337,17 +343,10 @@ int main(int argc, char *argv[]) +@@ -337,17 +346,10 @@ int main(int argc, char *argv[]) uid_t uid = 0; struct sigaction sa_old; struct sigaction sa_new; @@ -12132,7 +12081,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsid.c open-iscsi-2.0-872-rc4-bnx &longindex)) >= 0) { switch (ch) { case 'c': -@@ -368,6 +367,9 @@ int main(int argc, char *argv[]) +@@ -368,6 +370,9 @@ int main(int argc, char *argv[]) case 'g': gid = strtoul(optarg, NULL, 10); break; @@ -12142,7 +12091,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsid.c open-iscsi-2.0-872-rc4-bnx case 'p': pid_file = optarg; break; -@@ -388,17 +390,25 @@ int main(int argc, char *argv[]) +@@ -388,17 +393,25 @@ int main(int argc, char *argv[]) log_pid = log_init(program_name, DEFAULT_AREA_SIZE, daemonize ? log_do_log_daemon : log_do_log_std, NULL); if (log_pid < 0) @@ -12171,7 +12120,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsid.c open-iscsi-2.0-872-rc4-bnx } umask(0177); -@@ -410,24 +420,26 @@ int main(int argc, char *argv[]) +@@ -410,24 +423,26 @@ int main(int argc, char *argv[]) if ((mgmt_ipc_fd = mgmt_ipc_listen()) < 0) { log_close(log_pid); @@ -12206,7 +12155,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsid.c open-iscsi-2.0-872-rc4-bnx } else if (pid) { log_error("iSCSI daemon with pid=%d started!", pid); exit(0); -@@ -435,18 +447,29 @@ int main(int argc, char *argv[]) +@@ -435,18 +450,29 @@ int main(int argc, char *argv[]) if ((control_fd = ipc->ctldev_open()) < 0) { log_close(log_pid); @@ -12245,7 +12194,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsid.c open-iscsi-2.0-872-rc4-bnx daemon_init(); } else { -@@ -498,6 +521,7 @@ int main(int argc, char *argv[]) +@@ -498,6 +524,7 @@ int main(int argc, char *argv[]) } else reap_inc(); @@ -12253,7 +12202,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsid.c open-iscsi-2.0-872-rc4-bnx increase_max_files(); discoveryd_start(daemon_config.initiator_name); -@@ -509,7 +533,7 @@ int main(int argc, char *argv[]) +@@ -509,7 +536,7 @@ int main(int argc, char *argv[]) if (mlockall(MCL_CURRENT | MCL_FUTURE)) { log_error("failed to mlockall, exiting..."); log_close(log_pid); @@ -12262,9 +12211,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsid.c open-iscsi-2.0-872-rc4-bnx } actor_init(); -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsid.h open-iscsi-2.0-872-rc4-bnx2i.sync/usr/iscsid.h +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsid.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsid.h --- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsid.h 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/iscsid.h 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsid.h 2012-03-05 23:02:46.000000000 -0600 @@ -31,6 +31,5 @@ struct iscsi_daemon_config { char *initiator_alias; }; @@ -12272,9 +12221,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsid.h open-iscsi-2.0-872-rc4-bnx -extern int control_fd; #endif /* ISCSID_H */ -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsid_req.c open-iscsi-2.0-872-rc4-bnx2i.sync/usr/iscsid_req.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsid_req.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsid_req.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsid_req.c 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/iscsid_req.c 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsid_req.c 2012-03-05 23:02:46.000000000 -0600 @@ -31,6 +31,7 @@ #include "mgmt_ipc.h" #include "iscsi_util.h" @@ -12405,9 +12354,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsid_req.c open-iscsi-2.0-872-rc4 - }; - log_error("initiator reported error (%d - %s)", err, err_msgs[err]); -} -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsid_req.h open-iscsi-2.0-872-rc4-bnx2i.sync/usr/iscsid_req.h +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsid_req.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsid_req.h --- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsid_req.h 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/iscsid_req.h 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsid_req.h 2012-03-05 23:02:46.000000000 -0600 @@ -27,7 +27,6 @@ struct node_rec; extern int iscsid_exec_req(struct iscsiadm_req *req, struct iscsiadm_rsp *rsp, @@ -12416,9 +12365,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsid_req.h open-iscsi-2.0-872-rc4 extern int iscsid_req_wait(int cmd, int fd); extern int iscsid_req_by_rec_async(int cmd, struct node_rec *rec, int *fd); extern int iscsid_req_by_rec(int cmd, struct node_rec *rec); -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_err.c open-iscsi-2.0-872-rc4-bnx2i.sync/usr/iscsi_err.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_err.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_err.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_err.c 1969-12-31 18:00:00.000000000 -0600 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/iscsi_err.c 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_err.c 2012-03-05 23:02:46.000000000 -0600 @@ -0,0 +1,72 @@ +/* + * iSCSI error helpers @@ -12492,9 +12441,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_err.c open-iscsi-2.0-872-rc4- + log_error("initiator reported error (%d - %s)", err, + iscsi_err_msgs[err]); +} -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_ipc.h open-iscsi-2.0-872-rc4-bnx2i.sync/usr/iscsi_ipc.h +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_ipc.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_ipc.h --- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_ipc.h 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/iscsi_ipc.h 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_ipc.h 2012-03-05 23:02:46.000000000 -0600 @@ -34,6 +34,26 @@ enum { }; @@ -12534,9 +12483,46 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_ipc.h open-iscsi-2.0-872-rc4- }; #endif /* ISCSI_IPC_H */ -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_net_util.c open-iscsi-2.0-872-rc4-bnx2i.sync/usr/iscsi_net_util.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_netlink.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_netlink.h +--- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_netlink.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_netlink.h 2012-03-05 23:04:01.000000000 -0600 +@@ -0,0 +1,33 @@ ++/* ++ * iSCSI Netlink attr helpers ++ * ++ * Copyright (C) 2011 Red Hat, Inc. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published ++ * by the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * See the file COPYING included with this distribution for more details. ++ */ ++ ++#ifndef ISCSI_NLA_H ++#define ISCSI_NLA_H ++ ++#include ++ ++struct iovec; ++ ++#define ISCSI_NLA_HDRLEN ((int) NLA_ALIGN(sizeof(struct nlattr))) ++#define ISCSI_NLA_DATA(nla) ((void *)((char*)(nla) + ISCSI_NLA_HDRLEN)) ++#define ISCSI_NLA_LEN(len) ((len) + NLA_ALIGN(ISCSI_NLA_HDRLEN)) ++#define ISCSI_NLA_TOTAL_LEN(len) (NLA_ALIGN(ISCSI_NLA_LEN(len))) ++ ++extern struct nlattr *iscsi_nla_alloc(uint16_t type, uint16_t len); ++ ++#endif +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_net_util.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_net_util.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_net_util.c 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/iscsi_net_util.c 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_net_util.c 2012-03-05 23:02:46.000000000 -0600 @@ -41,6 +41,7 @@ struct iscsi_net_driver { static struct iscsi_net_driver net_drivers[] = { #ifdef OFFLOAD_BOOT_SUPPORTED @@ -12545,9 +12531,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_net_util.c open-iscsi-2.0-872 {"bnx2", "bnx2i" }, {"bnx2x", "bnx2i"}, #endif -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsistart.c open-iscsi-2.0-872-rc4-bnx2i.sync/usr/iscsistart.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsistart.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsistart.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsistart.c 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/iscsistart.c 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsistart.c 2012-03-05 23:06:04.000000000 -0600 @@ -47,6 +47,7 @@ #include "iface.h" #include "sysdeps.h" @@ -12556,8 +12542,16 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsistart.c open-iscsi-2.0-872-rc4 /* global config info */ /* initiator needs initiator name/alias */ -@@ -57,10 +58,8 @@ static node_rec_t config_rec; +@@ -55,12 +56,16 @@ struct iscsi_daemon_config *dconfig = &d + + static node_rec_t config_rec; static LIST_HEAD(targets); ++static LIST_HEAD(user_params); ++ ++struct user_param { ++ struct list_head list; ++ char *param_string; ++}; static char program_name[] = "iscsistart"; -static int mgmt_ipc_fd; @@ -12567,7 +12561,20 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsistart.c open-iscsi-2.0-872-rc4 extern struct iscsi_ipc *ipc; static struct option const long_options[] = { -@@ -108,7 +107,7 @@ Open-iSCSI initiator.\n\ +@@ -77,6 +82,7 @@ static struct option const long_options[ + {"fwparam_connect", no_argument, NULL, 'b'}, + {"fwparam_network", no_argument, NULL, 'N'}, + {"fwparam_print", no_argument, NULL, 'f'}, ++ {"param", required_argument, NULL, 'P'}, + {"help", no_argument, NULL, 'h'}, + {"version", no_argument, NULL, 'v'}, + {NULL, 0, NULL, 0}, +@@ -104,11 +110,12 @@ Open-iSCSI initiator.\n\ + -b, --fwparam_connect create a session to the target using iBFT or OF\n\ + -N, --fwparam_network bring up the network as specified by iBFT or OF\n\ + -f, --fwparam_print print the iBFT or OF info to STDOUT \n\ ++ -P, --param=NAME=VALUE set parameter with the name NAME to VALUE\n\ + -h, --help display this help and exit\n\ -v, --version display version and exit\n\ "); } @@ -12576,7 +12583,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsistart.c open-iscsi-2.0-872-rc4 } static int stop_event_loop(void) -@@ -121,7 +120,7 @@ static int stop_event_loop(void) +@@ -121,26 +128,75 @@ static int stop_event_loop(void) req.command = MGMT_IPC_IMMEDIATE_STOP; rc = iscsid_exec_req(&req, &rsp, 0); if (rc) { @@ -12585,7 +12592,83 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsistart.c open-iscsi-2.0-872-rc4 log_error("Could not stop event_loop\n"); } return rc; -@@ -155,12 +154,12 @@ retry: + } + ++static int apply_params(struct node_rec *rec) ++{ ++ struct user_param *param; ++ int rc; ++ ++ /* Must init this so we can check if user overrode them */ ++ rec->session.initial_login_retry_max = -1; ++ rec->conn[0].timeo.noop_out_interval = -1; ++ rec->conn[0].timeo.noop_out_timeout = -1; ++ ++ list_for_each_entry(param, &user_params, list) { ++ rc = idbm_parse_param(param->param_string, rec); ++ if (rc) ++ return rc; ++ } ++ ++ /* ++ * For root boot we could not change this in older versions so ++ * if user did not override then use the defaults. ++ * ++ * Increase to account for boot using static setup. ++ */ ++ if (rec->session.initial_login_retry_max == -1) ++ rec->session.initial_login_retry_max = 30; ++ /* we used to not be able to answer so turn off */ ++ if (rec->conn[0].timeo.noop_out_interval == -1) ++ rec->conn[0].timeo.noop_out_interval = 0; ++ if (rec->conn[0].timeo.noop_out_timeout == -1) ++ rec->conn[0].timeo.noop_out_timeout = 0; ++ ++ return 0; ++} ++ ++static int alloc_param(char *param_string) ++{ ++ struct user_param *param; ++ ++ param = calloc(1, sizeof(*param)); ++ if (!param) { ++ printf("Could not allocate for param.\n"); ++ return ISCSI_ERR_NOMEM; ++ } ++ ++ INIT_LIST_HEAD(¶m->list); ++ param->param_string = strdup(param_string); ++ if (!param->param_string) { ++ printf("Could not allocate for param.\n"); ++ free(param); ++ return ISCSI_ERR_NOMEM; ++ } ++ list_add(¶m->list, &user_params); ++ return 0; ++} + + static int login_session(struct node_rec *rec) + { + iscsiadm_req_t req; + iscsiadm_rsp_t rsp; + int rc, retries = 0; +- /* +- * For root boot we cannot change this so increase to account +- * for boot using static setup. +- */ +- rec->session.initial_login_retry_max = 30; +- /* we cannot answer so turn off */ +- rec->conn[0].timeo.noop_out_interval = 0; +- rec->conn[0].timeo.noop_out_timeout = 0; ++ ++ rc = apply_params(rec); ++ if (rc) ++ exit(rc); + + printf("%s: Logging into %s %s:%d,%d\n", program_name, rec->name, + rec->conn[0].address, rec->conn[0].port, +@@ -155,12 +211,12 @@ retry: * handle race where iscsid proc is starting up while we are * trying to connect. */ @@ -12600,7 +12683,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsistart.c open-iscsi-2.0-872-rc4 return rc; } -@@ -229,7 +228,7 @@ do { \ +@@ -229,7 +285,7 @@ do { \ if (strlen(str) > max_len) { \ printf("%s: invalid %s %s. Max %s length is %d.\n", \ program_name, param, str, param, max_len); \ @@ -12609,24 +12692,27 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsistart.c open-iscsi-2.0-872-rc4 } \ } while (0); -@@ -242,6 +241,7 @@ int main(int argc, char *argv[]) +@@ -242,6 +298,7 @@ int main(int argc, char *argv[]) struct boot_context *context, boot_context; struct sigaction sa_old; struct sigaction sa_new; -+ int control_fd, mgmt_ipc_fd; ++ int control_fd, mgmt_ipc_fd, err; pid_t pid; idbm_node_setup_defaults(&config_rec); -@@ -260,7 +260,7 @@ int main(int argc, char *argv[]) +@@ -260,9 +317,9 @@ int main(int argc, char *argv[]) sysfs_init(); if (iscsi_sysfs_check_class_version()) - exit(1); + exit(ISCSI_ERR_SYSFS_LOOKUP); - while ((ch = getopt_long(argc, argv, "i:t:g:a:p:d:u:w:U:W:bNfvh", +- while ((ch = getopt_long(argc, argv, "i:t:g:a:p:d:u:w:U:W:bNfvh", ++ while ((ch = getopt_long(argc, argv, "P:i:t:g:a:p:d:u:w:U:W:bNfvh", long_options, &longindex)) >= 0) { -@@ -316,25 +316,24 @@ int main(int argc, char *argv[]) + switch (ch) { + case 'i': +@@ -316,25 +373,24 @@ int main(int argc, char *argv[]) ret = fw_get_entry(&boot_context); if (ret) { printf("Could not get boot entry.\n"); @@ -12656,7 +12742,19 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsistart.c open-iscsi-2.0-872-rc4 } list_for_each_entry(context, &targets, list) -@@ -350,18 +349,18 @@ int main(int argc, char *argv[]) +@@ -342,6 +398,11 @@ int main(int argc, char *argv[]) + + fw_free_targets(&targets); + exit(0); ++ case 'P': ++ err = alloc_param(optarg); ++ if (err) ++ exit(err); ++ break; + case 'v': + printf("%s version %s\n", program_name, + ISCSI_VERSION_STR); +@@ -350,18 +411,18 @@ int main(int argc, char *argv[]) usage(0); break; default: @@ -12678,7 +12776,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsistart.c open-iscsi-2.0-872-rc4 } else if (pid) { int status, rc, rc2; -@@ -376,7 +375,7 @@ int main(int argc, char *argv[]) +@@ -376,7 +437,7 @@ int main(int argc, char *argv[]) waitpid(pid, &status, WUNTRACED); if (rc || rc2) @@ -12687,7 +12785,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsistart.c open-iscsi-2.0-872-rc4 log_debug(1, "iscsi parent done"); exit(0); -@@ -385,12 +384,12 @@ int main(int argc, char *argv[]) +@@ -385,12 +446,12 @@ int main(int argc, char *argv[]) mgmt_ipc_fd = mgmt_ipc_listen(); if (mgmt_ipc_fd < 0) { log_error("Could not setup mgmt ipc\n"); @@ -12702,7 +12800,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsistart.c open-iscsi-2.0-872-rc4 memset(&daemon_config, 0, sizeof (daemon_config)); daemon_config.initiator_name = initiatorname; -@@ -420,6 +419,7 @@ int main(int argc, char *argv[]) +@@ -420,6 +481,7 @@ int main(int argc, char *argv[]) /* * Start Main Event Loop */ @@ -12710,9 +12808,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsistart.c open-iscsi-2.0-872-rc4 actor_init(); event_loop(ipc, control_fd, mgmt_ipc_fd); ipc->ctldev_close(); -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.c open-iscsi-2.0-872-rc4-bnx2i.sync/usr/iscsi_sysfs.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_sysfs.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.c 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/iscsi_sysfs.c 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_sysfs.c 2012-03-05 23:05:31.000000000 -0600 @@ -36,6 +36,7 @@ #include "iface.h" #include "session_info.h" @@ -12748,7 +12846,37 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.c open-iscsi-2.0-872-rc } if (list_empty(&t->list)) -@@ -238,7 +243,7 @@ uint32_t iscsi_sysfs_get_host_no_from_si +@@ -226,6 +231,29 @@ void iscsi_sysfs_get_negotiated_session_ + &conf->MaxOutstandingR2T); + } + ++/* ++ * iscsi_sysfs_session_user_created - return if session was setup by userspace ++ * @sid: id of session to test ++ * ++ * Returns -1 if we could not tell due to kernel not supporting the ++ * feature. 0 is returned if kernel created it. And 1 is returned ++ * if userspace created it. ++ */ ++int iscsi_sysfs_session_user_created(int sid) ++{ ++ char id[NAME_SIZE]; ++ pid_t pid; ++ ++ snprintf(id, sizeof(id), ISCSI_SESSION_ID, sid); ++ if (sysfs_get_int(id, ISCSI_SESSION_SUBSYS, "creator", &pid)) ++ return -1; ++ ++ if (pid == -1) ++ return 0; ++ else ++ return 1; ++} ++ + uint32_t iscsi_sysfs_get_host_no_from_sid(uint32_t sid, int *err) + { + struct sysfs_device *session_dev, *host_dev; +@@ -238,7 +266,7 @@ uint32_t iscsi_sysfs_get_host_no_from_si ISCSI_SESSION_SUBSYS, id)) { log_error("Could not lookup devpath for %s. Possible sysfs " "incompatibility.\n", id); @@ -12757,7 +12885,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.c open-iscsi-2.0-872-rc return 0; } -@@ -246,7 +251,7 @@ uint32_t iscsi_sysfs_get_host_no_from_si +@@ -246,7 +274,7 @@ uint32_t iscsi_sysfs_get_host_no_from_si if (!session_dev) { log_error("Could not get dev for %s. Possible sysfs " "incompatibility.\n", id); @@ -12766,7 +12894,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.c open-iscsi-2.0-872-rc return 0; } -@@ -271,7 +276,7 @@ uint32_t iscsi_sysfs_get_host_no_from_si +@@ -271,7 +299,7 @@ uint32_t iscsi_sysfs_get_host_no_from_si if (!host_dev) { log_error("Could not get host dev for %s. Possible " "sysfs incompatibility.\n", id); @@ -12775,7 +12903,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.c open-iscsi-2.0-872-rc return 0; } } -@@ -301,7 +306,7 @@ static uint32_t get_host_no_from_netdev( +@@ -301,7 +329,7 @@ static uint32_t get_host_no_from_netdev( info = calloc(1, sizeof(*info)); if (!info) { @@ -12784,7 +12912,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.c open-iscsi-2.0-872-rc return -1; } strcpy(info->iface.netdev, netdev); -@@ -311,7 +316,7 @@ static uint32_t get_host_no_from_netdev( +@@ -311,7 +339,7 @@ static uint32_t get_host_no_from_netdev( if (local_rc == 1) host_no = info->host_no; else @@ -12793,7 +12921,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.c open-iscsi-2.0-872-rc free(info); return host_no; } -@@ -320,14 +325,14 @@ static int __get_host_no_from_hwaddress( +@@ -320,14 +348,14 @@ static int __get_host_no_from_hwaddress( { struct host_info *ret_info = data; @@ -12810,7 +12938,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.c open-iscsi-2.0-872-rc { uint32_t host_no = -1; struct host_info *info; -@@ -337,17 +342,17 @@ static uint32_t get_host_no_from_hwaddre +@@ -337,17 +365,17 @@ static uint32_t get_host_no_from_hwaddre info = calloc(1, sizeof(*info)); if (!info) { @@ -12831,7 +12959,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.c open-iscsi-2.0-872-rc free(info); return host_no; } -@@ -374,7 +379,7 @@ static uint32_t get_host_no_from_ipaddre +@@ -374,7 +402,7 @@ static uint32_t get_host_no_from_ipaddre info = calloc(1, sizeof(*info)); if (!info) { @@ -12840,7 +12968,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.c open-iscsi-2.0-872-rc return -1; } strcpy(info->iface.ipaddress, address); -@@ -384,7 +389,7 @@ static uint32_t get_host_no_from_ipaddre +@@ -384,7 +412,7 @@ static uint32_t get_host_no_from_ipaddre if (local_rc == 1) host_no = info->host_no; else @@ -12849,7 +12977,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.c open-iscsi-2.0-872-rc free(info); return host_no; } -@@ -396,7 +401,8 @@ uint32_t iscsi_sysfs_get_host_no_from_hw +@@ -396,7 +424,8 @@ uint32_t iscsi_sysfs_get_host_no_from_hw if (strlen(iface->hwaddress) && strcasecmp(iface->hwaddress, DEFAULT_HWADDRESS)) @@ -12859,7 +12987,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.c open-iscsi-2.0-872-rc else if (strlen(iface->netdev) && strcasecmp(iface->netdev, DEFAULT_NETDEV)) host_no = get_host_no_from_netdev(iface->netdev, &tmp_rc); -@@ -404,7 +410,7 @@ uint32_t iscsi_sysfs_get_host_no_from_hw +@@ -404,7 +433,7 @@ uint32_t iscsi_sysfs_get_host_no_from_hw strcasecmp(iface->ipaddress, DEFAULT_IPADDRESS)) host_no = get_host_no_from_ipaddress(iface->ipaddress, &tmp_rc); else @@ -12868,7 +12996,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.c open-iscsi-2.0-872-rc *rc = tmp_rc; return host_no; -@@ -417,9 +423,9 @@ uint32_t iscsi_sysfs_get_host_no_from_hw +@@ -417,11 +446,12 @@ uint32_t iscsi_sysfs_get_host_no_from_hw * qla4xxx. */ static int iscsi_sysfs_read_iface(struct iface_rec *iface, int host_no, @@ -12876,11 +13004,15 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.c open-iscsi-2.0-872-rc + char *session, char *iface_kern_id) { - char id[NAME_SIZE]; ++ uint32_t tmp_host_no, iface_num; + char host_id[NAME_SIZE]; struct iscsi_transport *t; - int ret; +- int ret; ++ int ret, iface_type; -@@ -430,26 +436,31 @@ static int iscsi_sysfs_read_iface(struct + t = iscsi_sysfs_get_transport_by_hba(host_no); + if (!t) +@@ -430,26 +460,31 @@ static int iscsi_sysfs_read_iface(struct else strcpy(iface->transport_name, t->name); @@ -12918,7 +13050,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.c open-iscsi-2.0-872-rc iface->netdev, sizeof(iface->netdev)); if (ret) log_debug(7, "could not read netdev for host%d\n", host_no); -@@ -459,7 +470,7 @@ static int iscsi_sysfs_read_iface(struct +@@ -459,7 +494,7 @@ static int iscsi_sysfs_read_iface(struct * host level because we cannot create different initiator ports * (cannot set isid either). The LLD also exports the iname at the * hba level so apps can see it, but we no longer set the iname for @@ -12927,7 +13059,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.c open-iscsi-2.0-872-rc * initiator names and of course software iscsi can support anything. */ ret = 1; -@@ -481,7 +492,7 @@ static int iscsi_sysfs_read_iface(struct +@@ -481,7 +516,7 @@ static int iscsi_sysfs_read_iface(struct } if (ret) { @@ -12936,7 +13068,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.c open-iscsi-2.0-872-rc iface->iname, sizeof(iface->iname)); if (ret) /* -@@ -493,6 +504,8 @@ static int iscsi_sysfs_read_iface(struct +@@ -493,6 +528,8 @@ static int iscsi_sysfs_read_iface(struct */ log_debug(7, "Could not read initiatorname for " "host%d\n", host_no); @@ -12945,7 +13077,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.c open-iscsi-2.0-872-rc } /* -@@ -523,12 +536,63 @@ static int iscsi_sysfs_read_iface(struct +@@ -523,12 +560,67 @@ static int iscsi_sysfs_read_iface(struct iface_str(iface)); } } @@ -12974,28 +13106,32 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.c open-iscsi-2.0-872-rc + "link_local_addr", iface->ipv6_linklocal, + sizeof(iface->ipv6_linklocal)); + -+ if (sysfs_get_str(iface_kern_id, ISCSI_IFACE_SUBSYS, -+ "linklocal_autocfg", -+ iface->linklocal_autocfg, -+ sizeof(iface->linklocal_autocfg))) { -+ /* misspelled in some test kernels */ -+ sysfs_get_str(iface_kern_id, ISCSI_IFACE_SUBSYS, -+ "link_local_autocfg", -+ iface->linklocal_autocfg, -+ sizeof(iface->linklocal_autocfg)); -+ } ++ sysfs_get_str(iface_kern_id, ISCSI_IFACE_SUBSYS, ++ "link_local_autocfg", iface->linklocal_autocfg, ++ sizeof(iface->linklocal_autocfg)); + + sysfs_get_str(iface_kern_id, ISCSI_IFACE_SUBSYS, "router_addr", + iface->ipv6_router, + sizeof(iface->ipv6_router)); + } + -+ sysfs_get_uint16(iface_kern_id, ISCSI_IFACE_SUBSYS, "mtu", -+ &iface->mtu); -+ sysfs_get_uint16(iface_kern_id, ISCSI_IFACE_SUBSYS, "vlan", -+ &iface->vlan_id); -+ sysfs_get_uint8(iface_kern_id, ISCSI_IFACE_SUBSYS, "vlan_priority", -+ &iface->vlan_priority); ++ if (sysfs_get_uint16(iface_kern_id, ISCSI_IFACE_SUBSYS, "port", ++ &iface->port)) ++ iface->port = 0; ++ if (sysfs_get_uint16(iface_kern_id, ISCSI_IFACE_SUBSYS, "mtu", ++ &iface->mtu)) ++ iface->mtu = 0; ++ if (sysfs_get_uint16(iface_kern_id, ISCSI_IFACE_SUBSYS, "vlan_id", ++ &iface->vlan_id)) ++ iface->vlan_id = UINT16_MAX; ++ ++ if (sysfs_get_uint8(iface_kern_id, ISCSI_IFACE_SUBSYS, "vlan_priority", ++ &iface->vlan_priority)) ++ iface->vlan_priority = UINT8_MAX; ++ ++ if (sscanf(iface_kern_id, "ipv%d-iface-%u-%u", &iface_type, ++ &tmp_host_no, &iface_num) == 3) ++ iface->iface_num = iface_num; +done: + if (ret) + return ISCSI_ERR_SYSFS_LOOKUP; @@ -13011,7 +13147,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.c open-iscsi-2.0-872-rc } int iscsi_sysfs_for_each_host(void *data, int *nr_found, -@@ -540,7 +604,7 @@ int iscsi_sysfs_for_each_host(void *data +@@ -540,7 +632,7 @@ int iscsi_sysfs_for_each_host(void *data info = malloc(sizeof(*info)); if (!info) @@ -13020,7 +13156,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.c open-iscsi-2.0-872-rc n = scandir(ISCSI_HOST_DIR, &namelist, trans_filter, alphasort); -@@ -572,6 +636,50 @@ free_info: +@@ -572,6 +664,50 @@ free_info: return rc; } @@ -13071,7 +13207,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.c open-iscsi-2.0-872-rc /** * sysfs_session_has_leadconn - checks if session has lead conn in kernel * @sid: session id -@@ -631,7 +739,7 @@ int iscsi_sysfs_get_sid_from_path(char * +@@ -631,7 +767,7 @@ int iscsi_sysfs_get_sid_from_path(char * if (!dev) { log_error("Could not get dev for %s. Possible sysfs " "incompatibility.\n", devpath); @@ -13080,7 +13216,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.c open-iscsi-2.0-872-rc } if (!strncmp(dev->kernel, "session", 7)) -@@ -645,8 +753,7 @@ int iscsi_sysfs_get_sid_from_path(char * +@@ -645,8 +781,7 @@ int iscsi_sysfs_get_sid_from_path(char * } log_error("Unable to find sid in path %s", session); @@ -13090,7 +13226,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.c open-iscsi-2.0-872-rc } int iscsi_sysfs_get_sessioninfo_by_id(struct session_info *info, char *session) -@@ -657,21 +764,65 @@ int iscsi_sysfs_get_sessioninfo_by_id(st +@@ -657,21 +792,65 @@ int iscsi_sysfs_get_sessioninfo_by_id(st if (sscanf(session, "session%d", &info->sid) != 1) { log_error("invalid session '%s'", session); @@ -13160,7 +13296,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.c open-iscsi-2.0-872-rc } snprintf(id, sizeof(id), ISCSI_CONN_ID, info->sid); -@@ -727,13 +878,13 @@ int iscsi_sysfs_get_sessioninfo_by_id(st +@@ -727,13 +906,13 @@ int iscsi_sysfs_get_sessioninfo_by_id(st ret = 0; host_no = iscsi_sysfs_get_host_no_from_sid(info->sid, &ret); if (ret) { @@ -13178,7 +13314,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.c open-iscsi-2.0-872-rc log_debug(7, "found targetname %s address %s pers address %s port %d " "pers port %d driver %s iface name %s ipaddress %s " "netdev %s hwaddress %s iname %s", -@@ -745,7 +896,7 @@ int iscsi_sysfs_get_sessioninfo_by_id(st +@@ -745,7 +924,7 @@ int iscsi_sysfs_get_sessioninfo_by_id(st info->iface.iname); return 0; } @@ -13187,7 +13323,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.c open-iscsi-2.0-872-rc int iscsi_sysfs_for_each_session(void *data, int *nr_found, iscsi_sysfs_session_op_fn *fn) { -@@ -755,7 +906,7 @@ int iscsi_sysfs_for_each_session(void *d +@@ -755,7 +934,7 @@ int iscsi_sysfs_for_each_session(void *d info = calloc(1, sizeof(*info)); if (!info) @@ -13196,7 +13332,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.c open-iscsi-2.0-872-rc n = scandir(ISCSI_SESSION_DIR, &namelist, trans_filter, alphasort); -@@ -797,8 +948,10 @@ int iscsi_sysfs_get_session_state(char * +@@ -797,8 +976,10 @@ int iscsi_sysfs_get_session_state(char * char id[NAME_SIZE]; snprintf(id, sizeof(id), ISCSI_SESSION_ID, sid); @@ -13209,7 +13345,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.c open-iscsi-2.0-872-rc } int iscsi_sysfs_get_host_state(char *state, int host_no) -@@ -806,8 +959,10 @@ int iscsi_sysfs_get_host_state(char *sta +@@ -806,8 +987,10 @@ int iscsi_sysfs_get_host_state(char *sta char id[NAME_SIZE]; snprintf(id, sizeof(id), ISCSI_HOST_ID, host_no); @@ -13222,7 +13358,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.c open-iscsi-2.0-872-rc } int iscsi_sysfs_get_device_state(char *state, int host_no, int target, int lun) -@@ -818,7 +973,7 @@ int iscsi_sysfs_get_device_state(char *s +@@ -818,7 +1001,7 @@ int iscsi_sysfs_get_device_state(char *s if (sysfs_get_str(id, SCSI_SUBSYS, "state", state, SCSI_MAX_STATE_VALUE)) { log_debug(3, "Could not read attr state for %s\n", id); @@ -13231,7 +13367,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.c open-iscsi-2.0-872-rc } return 0; -@@ -828,7 +983,6 @@ char *iscsi_sysfs_get_blockdev_from_lun( +@@ -828,7 +1011,6 @@ char *iscsi_sysfs_get_blockdev_from_lun( { char devpath[PATH_SIZE]; char path_full[PATH_SIZE]; @@ -13239,7 +13375,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.c open-iscsi-2.0-872-rc char id[NAME_SIZE]; DIR *dirfd; struct dirent *dent; -@@ -845,9 +999,8 @@ char *iscsi_sysfs_get_blockdev_from_lun( +@@ -845,9 +1027,8 @@ char *iscsi_sysfs_get_blockdev_from_lun( } sysfs_len = strlcpy(path_full, sysfs_path, sizeof(path_full)); @@ -13250,7 +13386,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.c open-iscsi-2.0-872-rc strlcat(path_full, devpath, sizeof(path_full)); dirfd = opendir(path_full); -@@ -912,14 +1065,13 @@ static uint32_t get_target_no_from_sid(u +@@ -912,14 +1093,13 @@ static uint32_t get_target_no_from_sid(u { char devpath[PATH_SIZE]; char path_full[PATH_SIZE]; @@ -13266,7 +13402,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.c open-iscsi-2.0-872-rc snprintf(id, sizeof(id), "session%u", sid); if (!sysfs_lookup_devpath_by_subsys_id(devpath, sizeof(devpath), -@@ -935,9 +1087,8 @@ static uint32_t get_target_no_from_sid(u +@@ -935,9 +1115,8 @@ static uint32_t get_target_no_from_sid(u * /class/iscsi_session/sessionX/device. */ sysfs_len = strlcpy(path_full, sysfs_path, sizeof(path_full)); @@ -13277,7 +13413,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.c open-iscsi-2.0-872-rc strlcat(path_full, devpath, sizeof(path_full)); strlcat(path_full, "/device", sizeof(devpath)); -@@ -970,7 +1121,8 @@ struct iscsi_transport *iscsi_sysfs_get_ +@@ -970,7 +1149,8 @@ struct iscsi_transport *iscsi_sysfs_get_ struct iscsi_transport *t; /* sync up kernel and userspace */ @@ -13287,7 +13423,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.c open-iscsi-2.0-872-rc /* check if the transport is loaded and matches */ list_for_each_entry(t, &transports, list) { -@@ -1043,6 +1195,19 @@ int iscsi_sysfs_get_exp_statsn(int sid) +@@ -1043,6 +1223,19 @@ int iscsi_sysfs_get_exp_statsn(int sid) return exp_statsn; } @@ -13307,7 +13443,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.c open-iscsi-2.0-872-rc int iscsi_sysfs_for_each_device(void *data, int host_no, uint32_t sid, void (* fn)(void *data, int host_no, int target, int lun)) -@@ -1061,7 +1226,7 @@ int iscsi_sysfs_for_each_device(void *da +@@ -1061,7 +1254,7 @@ int iscsi_sysfs_for_each_device(void *da ISCSI_SESSION_SUBSYS, id)) { log_debug(3, "Could not lookup devpath for %s %s\n", ISCSI_SESSION_SUBSYS, id); @@ -13316,9 +13452,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.c open-iscsi-2.0-872-rc } snprintf(path_full, sizeof(path_full), "%s%s/device/target%d:0:%d", -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.h open-iscsi-2.0-872-rc4-bnx2i.sync/usr/iscsi_sysfs.h +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_sysfs.h --- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.h 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/iscsi_sysfs.h 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_sysfs.h 2012-03-05 23:05:31.000000000 -0600 @@ -43,7 +43,11 @@ extern int iscsi_sysfs_session_has_leadc typedef int (iscsi_sysfs_session_op_fn)(void *, struct session_info *); @@ -13339,17 +13475,18 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.h open-iscsi-2.0-872-rc extern int iscsi_sysfs_get_hostinfo_by_host_no(struct host_info *hinfo); extern int iscsi_sysfs_get_sid_from_path(char *session); extern char *iscsi_sysfs_get_blockdev_from_lun(int hostno, int target, int sid); -@@ -84,6 +89,7 @@ extern struct iscsi_transport *iscsi_sys +@@ -84,6 +89,8 @@ extern struct iscsi_transport *iscsi_sys extern struct iscsi_transport *iscsi_sysfs_get_transport_by_session(char *sys_session); extern struct iscsi_transport *iscsi_sysfs_get_transport_by_sid(uint32_t sid); extern struct iscsi_transport *iscsi_sysfs_get_transport_by_name(char *transport_name); +extern int iscsi_sysfs_session_supports_nop(int sid); ++extern int iscsi_sysfs_session_user_created(int sid); extern struct list_head transports; -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_timer.c open-iscsi-2.0-872-rc4-bnx2i.sync/usr/iscsi_timer.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_timer.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_timer.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_timer.c 1969-12-31 18:00:00.000000000 -0600 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/iscsi_timer.c 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_timer.c 2012-03-05 23:02:46.000000000 -0600 @@ -0,0 +1,86 @@ +/* + * iSCSI timer @@ -13437,9 +13574,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_timer.c open-iscsi-2.0-872-rc + + return msecs; +} -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_timer.h open-iscsi-2.0-872-rc4-bnx2i.sync/usr/iscsi_timer.h +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_timer.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_timer.h --- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_timer.h 1969-12-31 18:00:00.000000000 -0600 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/iscsi_timer.h 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_timer.h 2012-03-05 23:02:46.000000000 -0600 @@ -0,0 +1,28 @@ +/* + * iSCSI timer @@ -13469,9 +13606,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_timer.h open-iscsi-2.0-872-rc +extern int iscsi_timer_msecs_until(struct timeval *timer); + +#endif -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_util.c open-iscsi-2.0-872-rc4-bnx2i.sync/usr/iscsi_util.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_util.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_util.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_util.c 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/iscsi_util.c 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_util.c 2012-03-05 23:02:46.000000000 -0600 @@ -25,12 +25,15 @@ #include #include @@ -13665,9 +13802,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_util.c open-iscsi-2.0-872-rc4 + info->persistent_port, NULL, + MATCH_ANY_SID); } -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_util.h open-iscsi-2.0-872-rc4-bnx2i.sync/usr/iscsi_util.h +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_util.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_util.h --- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_util.h 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/iscsi_util.h 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_util.h 2012-03-05 23:02:46.000000000 -0600 @@ -14,9 +14,14 @@ extern int increase_max_files(void); extern char *str_to_ipport(char *str, int *port, int *tgpt); @@ -13684,9 +13821,161 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_util.h open-iscsi-2.0-872-rc4 extern char *strstrip(char *s); extern char *cfg_get_string_param(char *pathname, const char *key); -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/log.c open-iscsi-2.0-872-rc4-bnx2i.sync/usr/log.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iser.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/iser.c +--- open-iscsi-2.0-872-rc4-bnx2i/usr/iser.c 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iser.c 2012-03-05 23:06:13.000000000 -0600 +@@ -0,0 +1,22 @@ ++/* ++ * iser helpers ++ * ++ * Copyright (C) 2012 Red Hat, Inc. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published ++ * by the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++#include "initiator.h" ++ ++void iser_create_conn(struct iscsi_conn *conn) ++{ ++ /* header digests not supported in iser */ ++ conn->hdrdgst_en = ISCSI_DIGEST_NONE; ++} +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iser.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/iser.h +--- open-iscsi-2.0-872-rc4-bnx2i/usr/iser.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iser.h 2012-03-05 23:06:13.000000000 -0600 +@@ -0,0 +1,8 @@ ++#ifndef ISER_TRANSPORT ++#define ISER_TRANSPORT ++ ++struct iscsi_conn; ++ ++extern void iser_create_conn(struct iscsi_conn *conn); ++ ++#endif +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/kern_err_table.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/kern_err_table.c +--- open-iscsi-2.0-872-rc4-bnx2i/usr/kern_err_table.c 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/kern_err_table.c 2012-03-05 23:03:56.000000000 -0600 +@@ -0,0 +1,83 @@ ++/* ++ * Copyright (C) 2011 Aastha Mehta ++ * Copyright (C) 2011 Mike Christie ++ * ++ * maintained by open-iscsi@googlegroups.com ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published ++ * by the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * See the file COPYING included with this distribution for more details. ++ */ ++#include ++#include ++#include ++#include "iscsi_if.h" ++ ++#include "kern_err_table.h" ++ ++const char *kern_err_code_to_string(int err) ++{ ++ switch (err){ ++ case ISCSI_OK: ++ return "ISCSI_OK: operation successful"; ++ case ISCSI_ERR_DATASN: ++ return "ISCSI_ERR_DATASN: Received invalid data sequence " ++ "number from target"; ++ case ISCSI_ERR_DATA_OFFSET: ++ return "ISCSI_ERR_DATA_OFFSET: Seeking offset beyond the size " ++ "of the iSCSI segment"; ++ case ISCSI_ERR_MAX_CMDSN: ++ return "ISCSI_ERR_MAX_CMDSN: Received invalid command sequence " ++ "number from target"; ++ case ISCSI_ERR_EXP_CMDSN: ++ return "ISCSI_ERR_EXP_CMDSN: Received invalid expected command " "sequence number from target"; ++ case ISCSI_ERR_BAD_OPCODE: ++ return "ISCSI_ERR_BAD_OPCODE: Received an invalid iSCSI opcode"; ++ case ISCSI_ERR_DATALEN: ++ return "ISCSI_ERR_DATALEN: Invalid data length value"; ++ case ISCSI_ERR_AHSLEN: ++ return "ISCSI_ERR_AHSLEN: Received an invalid AHS length"; ++ case ISCSI_ERR_PROTO: ++ return "ISCSI_ERR_PROTO: iSCSI protocol violation"; ++ case ISCSI_ERR_LUN: ++ return "ISCSI_ERR_LUN: LUN mismatch"; ++ case ISCSI_ERR_BAD_ITT: ++ return "ISCSI_ERR_BAD_ITT: Received invalid initiator task tag " "from target"; ++ case ISCSI_ERR_CONN_FAILED: ++ return "ISCSI_ERR_CONN_FAILED: iSCSI connection failed"; ++ case ISCSI_ERR_R2TSN: ++ return "ISCSI_ERR_R2TSN: Received invalid R2T (Ready to " ++ "Transfer) data sequence number from target"; ++ case ISCSI_ERR_SESSION_FAILED: ++ return "ISCSI_ERR_SESSION_FAILED: iSCSI session failed"; ++ case ISCSI_ERR_HDR_DGST: ++ return "ISCSI_ERR_HDR_DGST: Header digest mismatch"; ++ case ISCSI_ERR_DATA_DGST: ++ return "ISCSI_ERR_DATA_DGST: Data digest mismatch"; ++ case ISCSI_ERR_PARAM_NOT_FOUND: ++ return "ISCSI_ERR_PARAM_NOT_FOUND: Parameter not found"; ++ case ISCSI_ERR_NO_SCSI_CMD: ++ return "ISCSI_ERR_NO_SCSI_CMD: Could not look up SCSI command"; ++ case ISCSI_ERR_INVALID_HOST: ++ return "ISCSI_ERR_INVALID_HOST: iSCSI host is in an invalid " ++ "state"; ++ case ISCSI_ERR_XMIT_FAILED: ++ return "ISCSI_ERR_XMIT_FAILED: Transmission of iSCSI packet " ++ "failed"; ++ case ISCSI_ERR_TCP_CONN_CLOSE: ++ return "ISCSI_ERR_TCP_CONN_CLOSE: TCP connection closed"; ++ case ISCSI_ERR_SCSI_EH_SESSION_RST: ++ return "ISCSI_ERR_SCSI_EH_SESSION_RST: Session was dropped as " ++ "a result of SCSI error recovery"; ++ default: ++ return "Invalid or unknown error code"; ++ } ++} +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/kern_err_table.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/kern_err_table.h +--- open-iscsi-2.0-872-rc4-bnx2i/usr/kern_err_table.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/kern_err_table.h 2012-03-05 23:03:56.000000000 -0600 +@@ -0,0 +1,23 @@ ++/* ++ * Copyright (C) 2011 Aastha Mehta ++ * Copyright (C) 2011 Mike Christie ++ * ++ * maintained by open-iscsi@googlegroups.com ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published ++ * by the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * See the file COPYING included with this distribution for more details. ++ */ ++#ifndef __KERN_ERR_TABLE_H__ ++#define __KERN_ERR_TABLE_H__ ++ ++extern const char *kern_err_code_to_string(int); ++#endif +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/log.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/log.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/log.c 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/log.c 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/log.c 2012-03-05 23:02:46.000000000 -0600 @@ -326,6 +326,7 @@ void log_info(const char *fmt, ...) va_end(ap); } @@ -13714,9 +14003,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/log.c open-iscsi-2.0-872-rc4-bnx2i. + waitpid(pid, &status, 0); + } } -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/login.c open-iscsi-2.0-872-rc4-bnx2i.sync/usr/login.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/login.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/login.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/login.c 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/login.c 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/login.c 2012-03-05 23:02:46.000000000 -0600 @@ -27,11 +27,14 @@ #include #include @@ -13849,9 +14138,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/login.c open-iscsi-2.0-872-rc4-bnx2 } while (conn->current_stage != ISCSI_FULL_FEATURE_PHASE); c->ret = LOGIN_OK; -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/Makefile open-iscsi-2.0-872-rc4-bnx2i.sync/usr/Makefile +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/Makefile open-iscsi-2.0-872-rc4-bnx2i.work/usr/Makefile --- open-iscsi-2.0-872-rc4-bnx2i/usr/Makefile 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/Makefile 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/Makefile 2012-03-05 23:06:13.000000000 -0600 @@ -21,10 +21,12 @@ ifeq ($(OSNAME),Linux) endif endif @@ -13874,12 +14163,12 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/Makefile open-iscsi-2.0-872-rc4-bnx - iscsid_req.o $(SYSDEPS_SRCS) +ISCSI_LIB_SRCS = iscsi_util.o io.o auth.o iscsi_timer.o login.o log.o md5.o \ + sha1.o iface.o idbm.o sysfs.o host.o session_info.o iscsi_sysfs.o \ -+ iscsi_net_util.o iscsid_req.o transport.o cxgbi.o be2iscsi.o \ ++ iscsi_net_util.o iscsid_req.o transport.o iser.o cxgbi.o be2iscsi.o \ + initiator_common.o iscsi_err.o $(IPC_OBJ) $(SYSDEPS_SRCS) $(DCB_OBJ) # core initiator files -INITIATOR_SRCS = initiator.o scsi.o actor.o event_poll.o mgmt_ipc.o \ - transport.o cxgb3i.o be2iscsi.o -+INITIATOR_SRCS = initiator.o scsi.o actor.o event_poll.o mgmt_ipc.o ++INITIATOR_SRCS = initiator.o scsi.o actor.o event_poll.o mgmt_ipc.o kern_err_table.o + # fw boot files FW_BOOT_SRCS = $(wildcard ../utils/fwparam_ibft/*.o) @@ -13903,9 +14192,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/Makefile open-iscsi-2.0-872-rc4-bnx iscsistart.o statics.o $(CC) $(CFLAGS) -static $^ -o $@ clean: -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/mgmt_ipc.c open-iscsi-2.0-872-rc4-bnx2i.sync/usr/mgmt_ipc.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/mgmt_ipc.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/mgmt_ipc.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/mgmt_ipc.c 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/mgmt_ipc.c 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/mgmt_ipc.c 2012-03-05 23:02:46.000000000 -0600 @@ -35,6 +35,7 @@ #include "transport.h" #include "sysdeps.h" @@ -14172,7 +14461,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/mgmt_ipc.c open-iscsi-2.0-872-rc4-b { if (!qtask) return; -@@ -446,7 +435,8 @@ mgmt_ipc_write_rsp(queue_task_t *qtask, +@@ -446,7 +435,8 @@ mgmt_ipc_write_rsp(queue_task_t *qtask, } qtask->rsp.err = err; @@ -14214,9 +14503,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/mgmt_ipc.c open-iscsi-2.0-872-rc4-b } err: -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/mgmt_ipc.h open-iscsi-2.0-872-rc4-bnx2i.sync/usr/mgmt_ipc.h +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/mgmt_ipc.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/mgmt_ipc.h --- open-iscsi-2.0-872-rc4-bnx2i/usr/mgmt_ipc.h 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/mgmt_ipc.h 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/mgmt_ipc.h 2012-03-05 23:02:46.000000000 -0600 @@ -26,30 +26,6 @@ #define ISCSIADM_NAMESPACE "ISCSIADM_ABSTRACT_NAMESPACE" #define PEERUSER_MAX 64 @@ -14286,10 +14575,10 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/mgmt_ipc.h open-iscsi-2.0-872-rc4-b int mgmt_ipc_listen(void); void mgmt_ipc_close(int fd); void mgmt_ipc_handle(int accept_fd); -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bnx2i.sync/usr/netlink.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/netlink.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/netlink.c 2011-08-14 16:48:25.000000000 -0500 -@@ -33,7 +33,6 @@ ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/netlink.c 2012-03-05 23:06:18.000000000 -0600 +@@ -33,12 +33,12 @@ #include "types.h" #include "iscsi_if.h" @@ -14297,7 +14586,13 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn #include "log.h" #include "iscsi_ipc.h" #include "initiator.h" -@@ -50,23 +49,25 @@ static void *nlm_sendbuf; + #include "iscsi_sysfs.h" + #include "transport.h" ++#include "iscsi_netlink.h" + + static int ctrl_fd; + static struct sockaddr_nl src_addr, dest_addr; +@@ -50,23 +50,38 @@ static void *nlm_sendbuf; static void *nlm_recvbuf; static void *pdu_sendbuf; static void *setparam_buf; @@ -14311,17 +14606,29 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn +#define NLM_BUF_DEFAULT_MAX (NLMSG_SPACE(ISCSI_DEF_MAX_RECV_SEG_LEN + \ + sizeof(struct iscsi_uevent) + \ + sizeof(struct iscsi_hdr))) -+ + +-#define PDU_SENDBUF_DEFAULT_MAX \ +- (ISCSI_DEF_MAX_RECV_SEG_LEN + sizeof(struct iscsi_hdr)) +#define PDU_SENDBUF_DEFAULT_MAX (ISCSI_DEF_MAX_RECV_SEG_LEN + \ + sizeof(struct iscsi_uevent) + \ + sizeof(struct iscsi_hdr)) --#define PDU_SENDBUF_DEFAULT_MAX \ -- (ISCSI_DEF_MAX_RECV_SEG_LEN + sizeof(struct iscsi_hdr)) -- -#define NLM_SETPARAM_DEFAULT_MAX \ - (NI_MAXHOST + 1 + sizeof(struct iscsi_uevent)) +#define NLM_SETPARAM_DEFAULT_MAX (NI_MAXHOST + 1 + sizeof(struct iscsi_uevent)) ++ ++struct nlattr *iscsi_nla_alloc(uint16_t type, uint16_t len) ++{ ++ struct nlattr *attr; ++ ++ attr = calloc(1, ISCSI_NLA_TOTAL_LEN(len)); ++ if (!attr) ++ return NULL; ++ ++ attr->nla_len = ISCSI_NLA_LEN(len); ++ attr->nla_type = type; ++ return attr; ++} static int kread(char *data, int count) @@ -14332,7 +14639,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn memcpy(data, recvbuf + recvlen, count); recvlen += count; -@@ -107,6 +108,12 @@ nlpayload_read(int ctrl_fd, char *data, +@@ -107,6 +122,12 @@ nlpayload_read(int ctrl_fd, char *data, iov.iov_base = nlm_recvbuf; iov.iov_len = NLMSG_SPACE(count); @@ -14345,7 +14652,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn memset(iov.iov_base, 0, iov.iov_len); memset(&msg, 0, sizeof(msg)); -@@ -142,7 +149,8 @@ nlpayload_read(int ctrl_fd, char *data, +@@ -142,7 +163,8 @@ nlpayload_read(int ctrl_fd, char *data, */ rc = recvmsg(ctrl_fd, &msg, flags); @@ -14355,7 +14662,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn return rc; } -@@ -153,7 +161,6 @@ kwritev(enum iscsi_uevent_e type, struct +@@ -153,7 +175,6 @@ kwritev(enum iscsi_uevent_e type, struct int i, rc; struct nlmsghdr *nlh; struct msghdr msg; @@ -14363,19 +14670,19 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn int datalen = 0; log_debug(7, "in %s", __FUNCTION__); -@@ -172,27 +179,25 @@ kwritev(enum iscsi_uevent_e type, struct +@@ -172,27 +193,25 @@ kwritev(enum iscsi_uevent_e type, struct } nlh = nlm_sendbuf; - memset(nlh, 0, NLMSG_SPACE(datalen)); + memset(nlh, 0, NLMSG_SPACE(0)); - -- nlh->nlmsg_len = NLMSG_SPACE(datalen); ++ + datalen = 0; + for (i = 1; i < count; i++) + datalen += iovp[i].iov_len; -+ -+ nlh->nlmsg_len = NLMSG_ALIGN(datalen); + +- nlh->nlmsg_len = NLMSG_SPACE(datalen); ++ nlh->nlmsg_len = datalen + sizeof(*nlh); nlh->nlmsg_pid = getpid(); nlh->nlmsg_flags = 0; nlh->nlmsg_type = type; @@ -14401,7 +14708,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn do { /* -@@ -253,19 +258,15 @@ kwritev(enum iscsi_uevent_e type, struct +@@ -253,19 +272,15 @@ kwritev(enum iscsi_uevent_e type, struct * cleanup. (Dima) */ static int @@ -14424,7 +14731,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn do { if ((rc = nlpayload_read(ctrl_fd, (void*)ev, -@@ -325,6 +326,7 @@ ksendtargets(uint64_t transport_handle, +@@ -325,6 +340,7 @@ ksendtargets(uint64_t transport_handle, { int rc, addrlen; struct iscsi_uevent *ev; @@ -14432,7 +14739,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn log_debug(7, "in %s", __FUNCTION__); -@@ -346,7 +348,9 @@ ksendtargets(uint64_t transport_handle, +@@ -346,7 +362,9 @@ ksendtargets(uint64_t transport_handle, } memcpy(setparam_buf + sizeof(*ev), addr, addrlen); @@ -14443,7 +14750,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn if (rc < 0) { log_error("sendtargets failed rc%d\n", rc); return rc; -@@ -361,6 +365,7 @@ kcreate_session(uint64_t transport_handl +@@ -361,6 +379,7 @@ kcreate_session(uint64_t transport_handl { int rc; struct iscsi_uevent ev; @@ -14451,7 +14758,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn log_debug(7, "in %s", __FUNCTION__); -@@ -381,9 +386,11 @@ kcreate_session(uint64_t transport_handl +@@ -381,9 +400,11 @@ kcreate_session(uint64_t transport_handl ev.u.c_bound_session.ep_handle = ep_handle; } @@ -14465,7 +14772,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn *hostno = ev.r.c_session_ret.host_no; *out_sid = ev.r.c_session_ret.sid; -@@ -396,6 +403,7 @@ kdestroy_session(uint64_t transport_hand +@@ -396,6 +417,7 @@ kdestroy_session(uint64_t transport_hand { int rc; struct iscsi_uevent ev; @@ -14473,7 +14780,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn log_debug(7, "in %s", __FUNCTION__); -@@ -405,9 +413,11 @@ kdestroy_session(uint64_t transport_hand +@@ -405,9 +427,11 @@ kdestroy_session(uint64_t transport_hand ev.transport_handle = transport_handle; ev.u.d_session.sid = sid; @@ -14487,7 +14794,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn return 0; } -@@ -417,6 +427,7 @@ kunbind_session(uint64_t transport_handl +@@ -417,6 +441,7 @@ kunbind_session(uint64_t transport_handl { int rc; struct iscsi_uevent ev; @@ -14495,7 +14802,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn log_debug(7, "in %s", __FUNCTION__); -@@ -426,9 +437,11 @@ kunbind_session(uint64_t transport_handl +@@ -426,9 +451,11 @@ kunbind_session(uint64_t transport_handl ev.transport_handle = transport_handle; ev.u.d_session.sid = sid; @@ -14509,7 +14816,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn return 0; } -@@ -439,6 +452,7 @@ kcreate_conn(uint64_t transport_handle, +@@ -439,6 +466,7 @@ kcreate_conn(uint64_t transport_handle, { int rc; struct iscsi_uevent ev; @@ -14517,7 +14824,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn log_debug(7, "in %s", __FUNCTION__); -@@ -449,7 +463,10 @@ kcreate_conn(uint64_t transport_handle, +@@ -449,7 +477,10 @@ kcreate_conn(uint64_t transport_handle, ev.u.c_conn.cid = cid; ev.u.c_conn.sid = sid; @@ -14529,7 +14836,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn log_debug(7, "returned %d", rc); return rc; } -@@ -466,6 +483,7 @@ kdestroy_conn(uint64_t transport_handle, +@@ -466,6 +497,7 @@ kdestroy_conn(uint64_t transport_handle, { int rc; struct iscsi_uevent ev; @@ -14537,7 +14844,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn log_debug(7, "in %s", __FUNCTION__); -@@ -476,9 +494,11 @@ kdestroy_conn(uint64_t transport_handle, +@@ -476,9 +508,11 @@ kdestroy_conn(uint64_t transport_handle, ev.u.d_conn.sid = sid; ev.u.d_conn.cid = cid; @@ -14551,7 +14858,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn return 0; } -@@ -489,6 +509,7 @@ kbind_conn(uint64_t transport_handle, ui +@@ -489,6 +523,7 @@ kbind_conn(uint64_t transport_handle, ui { int rc; struct iscsi_uevent ev; @@ -14559,7 +14866,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn log_debug(7, "in %s", __FUNCTION__); -@@ -501,9 +522,11 @@ kbind_conn(uint64_t transport_handle, ui +@@ -501,9 +536,11 @@ kbind_conn(uint64_t transport_handle, ui ev.u.b_conn.transport_eph = transport_eph; ev.u.b_conn.is_leading = is_leading; @@ -14573,7 +14880,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn *retcode = ev.r.retcode; -@@ -515,6 +538,7 @@ ksend_pdu_begin(uint64_t transport_handl +@@ -515,6 +552,7 @@ ksend_pdu_begin(uint64_t transport_handl int hdr_size, int data_size) { struct iscsi_uevent *ev; @@ -14581,7 +14888,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn log_debug(7, "in %s", __FUNCTION__); -@@ -523,8 +547,13 @@ ksend_pdu_begin(uint64_t transport_handl +@@ -523,8 +561,13 @@ ksend_pdu_begin(uint64_t transport_handl exit(-EIO); } @@ -14596,7 +14903,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn xmitlen = sizeof(*ev); ev = xmitbuf; memset(ev, 0, sizeof(*ev)); -@@ -545,7 +574,7 @@ ksend_pdu_end(uint64_t transport_handle, +@@ -545,7 +588,7 @@ ksend_pdu_end(uint64_t transport_handle, { int rc; struct iscsi_uevent *ev; @@ -14605,7 +14912,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn log_debug(7, "in %s", __FUNCTION__); -@@ -559,10 +588,11 @@ ksend_pdu_end(uint64_t transport_handle, +@@ -559,10 +602,11 @@ ksend_pdu_end(uint64_t transport_handle, exit(-EIO); } @@ -14620,7 +14927,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn goto err; if (ev->r.retcode) { *retcode = ev->r.retcode; -@@ -592,6 +622,7 @@ kset_host_param(uint64_t transport_handl +@@ -592,6 +636,7 @@ kset_host_param(uint64_t transport_handl struct iscsi_uevent *ev; char *param_str; int rc, len; @@ -14628,7 +14935,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn log_debug(7, "in %s", __FUNCTION__); -@@ -618,9 +649,11 @@ kset_host_param(uint64_t transport_handl +@@ -618,9 +663,11 @@ kset_host_param(uint64_t transport_handl } ev->u.set_host_param.len = len = strlen(param_str) + 1; @@ -14642,7 +14949,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn return 0; } -@@ -632,6 +665,7 @@ kset_param(uint64_t transport_handle, ui +@@ -632,6 +679,7 @@ kset_param(uint64_t transport_handle, ui struct iscsi_uevent *ev; char *param_str; int rc, len; @@ -14650,7 +14957,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn log_debug(7, "in %s", __FUNCTION__); -@@ -659,9 +693,11 @@ kset_param(uint64_t transport_handle, ui +@@ -659,9 +707,11 @@ kset_param(uint64_t transport_handle, ui } ev->u.set_param.len = len = strlen(param_str) + 1; @@ -14664,7 +14971,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn return 0; } -@@ -671,6 +707,7 @@ kstop_conn(uint64_t transport_handle, ui +@@ -671,6 +721,7 @@ kstop_conn(uint64_t transport_handle, ui { int rc; struct iscsi_uevent ev; @@ -14672,7 +14979,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn log_debug(7, "in %s", __FUNCTION__); -@@ -682,9 +719,11 @@ kstop_conn(uint64_t transport_handle, ui +@@ -682,9 +733,11 @@ kstop_conn(uint64_t transport_handle, ui ev.u.stop_conn.cid = cid; ev.u.stop_conn.flag = flag; @@ -14686,7 +14993,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn return 0; } -@@ -695,6 +734,7 @@ kstart_conn(uint64_t transport_handle, u +@@ -695,6 +748,7 @@ kstart_conn(uint64_t transport_handle, u { int rc; struct iscsi_uevent ev; @@ -14694,7 +15001,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn log_debug(7, "in %s", __FUNCTION__); -@@ -705,9 +745,11 @@ kstart_conn(uint64_t transport_handle, u +@@ -705,9 +759,11 @@ kstart_conn(uint64_t transport_handle, u ev.u.start_conn.sid = sid; ev.u.start_conn.cid = cid; @@ -14708,7 +15015,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn *retcode = ev.r.retcode; return 0; -@@ -716,18 +758,34 @@ kstart_conn(uint64_t transport_handle, u +@@ -716,18 +772,34 @@ kstart_conn(uint64_t transport_handle, u static int krecv_pdu_begin(struct iscsi_conn *conn) { @@ -14746,7 +15053,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn return 0; } -@@ -744,7 +802,7 @@ krecv_pdu_end(struct iscsi_conn *conn) +@@ -744,7 +816,7 @@ krecv_pdu_end(struct iscsi_conn *conn) log_debug(3, "recv PDU finished for pdu handle 0x%p", recvbuf); @@ -14755,7 +15062,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn conn->recv_context = NULL; recvbuf = NULL; return 0; -@@ -756,6 +814,7 @@ ktransport_ep_connect(iscsi_conn_t *conn +@@ -756,6 +828,7 @@ ktransport_ep_connect(iscsi_conn_t *conn int rc, addrlen; struct iscsi_uevent *ev; struct sockaddr *dst_addr = (struct sockaddr *)&conn->saddr; @@ -14763,7 +15070,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn log_debug(7, "in %s", __FUNCTION__); -@@ -783,7 +842,10 @@ ktransport_ep_connect(iscsi_conn_t *conn +@@ -783,7 +856,10 @@ ktransport_ep_connect(iscsi_conn_t *conn } memcpy(setparam_buf + sizeof(*ev), dst_addr, addrlen); @@ -14775,7 +15082,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn return rc; if (!ev->r.ep_connect_ret.handle) -@@ -801,6 +863,7 @@ ktransport_ep_poll(iscsi_conn_t *conn, i +@@ -801,6 +877,7 @@ ktransport_ep_poll(iscsi_conn_t *conn, i { int rc; struct iscsi_uevent ev; @@ -14783,7 +15090,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn log_debug(7, "in %s", __FUNCTION__); -@@ -811,7 +874,10 @@ ktransport_ep_poll(iscsi_conn_t *conn, i +@@ -811,7 +888,10 @@ ktransport_ep_poll(iscsi_conn_t *conn, i ev.u.ep_poll.ep_handle = conn->transport_ep_handle; ev.u.ep_poll.timeout_ms = timeout_ms; @@ -14795,7 +15102,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn return rc; return ev.r.retcode; -@@ -822,6 +888,7 @@ ktransport_ep_disconnect(iscsi_conn_t *c +@@ -822,6 +902,7 @@ ktransport_ep_disconnect(iscsi_conn_t *c { int rc; struct iscsi_uevent ev; @@ -14803,7 +15110,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn log_debug(7, "in %s", __FUNCTION__); -@@ -834,7 +901,10 @@ ktransport_ep_disconnect(iscsi_conn_t *c +@@ -834,7 +915,10 @@ ktransport_ep_disconnect(iscsi_conn_t *c ev.transport_handle = conn->session->t->handle; ev.u.ep_disconnect.ep_handle = conn->transport_ep_handle; @@ -14815,7 +15122,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn log_error("connnection %d:%d transport disconnect failed for " "ep %" PRIu64 " with error %d.", conn->session->id, conn->id, conn->transport_ep_handle, rc); -@@ -851,6 +921,7 @@ kget_stats(uint64_t transport_handle, ui +@@ -851,6 +935,7 @@ kget_stats(uint64_t transport_handle, ui struct iscsi_uevent ev; char nlm_ev[NLMSG_SPACE(sizeof(struct iscsi_uevent))]; struct nlmsghdr *nlh; @@ -14823,7 +15130,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn log_debug(7, "in %s", __FUNCTION__); -@@ -861,9 +932,11 @@ kget_stats(uint64_t transport_handle, ui +@@ -861,9 +946,11 @@ kget_stats(uint64_t transport_handle, ui ev.u.get_stats.sid = sid; ev.u.get_stats.cid = cid; @@ -14837,7 +15144,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn if ((rc = nl_read(ctrl_fd, nlm_ev, NLMSG_SPACE(sizeof(struct iscsi_uevent)), MSG_PEEK)) < 0) { -@@ -889,12 +962,60 @@ kget_stats(uint64_t transport_handle, ui +@@ -889,12 +976,60 @@ kget_stats(uint64_t transport_handle, ui return 0; } @@ -14899,7 +15206,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn } static int ctldev_handle(void) -@@ -905,8 +1026,8 @@ static int ctldev_handle(void) +@@ -905,8 +1040,8 @@ static int ctldev_handle(void) iscsi_conn_t *conn = NULL; char nlm_ev[NLMSG_SPACE(sizeof(struct iscsi_uevent))]; struct nlmsghdr *nlh; @@ -14910,7 +15217,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn log_debug(7, "in %s", __FUNCTION__); -@@ -925,13 +1046,15 @@ static int ctldev_handle(void) +@@ -925,13 +1060,15 @@ static int ctldev_handle(void) /* old kernels sent ISCSI_UEVENT_CREATE_SESSION on creation */ case ISCSI_UEVENT_CREATE_SESSION: drop_data(nlh); @@ -14930,7 +15237,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn return 0; case ISCSI_KEVENT_RECV_PDU: sid = ev->r.recv_req.sid; -@@ -941,22 +1064,41 @@ static int ctldev_handle(void) +@@ -941,22 +1078,59 @@ static int ctldev_handle(void) sid = ev->r.connerror.sid; cid = ev->r.connerror.cid; break; @@ -14944,6 +15251,24 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn /* session wide event so cid is 0 */ cid = 0; break; ++ case ISCSI_KEVENT_HOST_EVENT: ++ switch (ev->r.host_event.code) { ++ case ISCSI_EVENT_LINKUP: ++ log_warning("Host%u: Link Up.\n", ++ ev->r.host_event.host_no); ++ break; ++ case ISCSI_EVENT_LINKDOWN: ++ log_warning("Host%u: Link Down.\n", ++ ev->r.host_event.host_no); ++ break; ++ default: ++ log_debug(7, "Host%u: Unknwon host event: %u.\n", ++ ev->r.host_event.host_no, ++ ev->r.host_event.code); ++ } ++ ++ drop_data(nlh); ++ return 0; default: - log_error("Unknown kernel event %d. You may want to upgrade " - "your iscsi tools.", ev->type); @@ -14976,7 +15301,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn "event.\n", sid, cid); drop_data(nlh); return -ENXIO; -@@ -964,19 +1106,20 @@ static int ctldev_handle(void) +@@ -964,19 +1138,20 @@ static int ctldev_handle(void) conn = &session->conn[0]; ev_size = nlh->nlmsg_len - NLMSG_ALIGN(sizeof(struct nlmsghdr)); @@ -15002,7 +15327,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn log_error("can not read from NL socket, error %d", rc); /* retry later */ return rc; -@@ -988,26 +1131,34 @@ static int ctldev_handle(void) +@@ -988,26 +1163,34 @@ static int ctldev_handle(void) */ switch (ev->type) { case ISCSI_KEVENT_RECV_PDU: @@ -15046,7 +15371,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn } static int -@@ -1114,5 +1265,12 @@ struct iscsi_ipc nl_ipc = { +@@ -1114,5 +1297,12 @@ struct iscsi_ipc nl_ipc = { .read = kread, .recv_pdu_begin = krecv_pdu_begin, .recv_pdu_end = krecv_pdu_end, @@ -15059,9 +15384,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bn +{ + ipc_ev_clbk = ev_clbk; +} -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/session_info.c open-iscsi-2.0-872-rc4-bnx2i.sync/usr/session_info.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/session_info.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/session_info.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/session_info.c 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/session_info.c 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/session_info.c 2012-03-05 23:02:46.000000000 -0600 @@ -13,6 +13,7 @@ #include "initiator.h" #include "iface.h" @@ -15223,9 +15548,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/session_info.c open-iscsi-2.0-872-r + } return 0; } -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/session_info.h open-iscsi-2.0-872-rc4-bnx2i.sync/usr/session_info.h +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/session_info.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/session_info.h --- open-iscsi-2.0-872-rc4-bnx2i/usr/session_info.h 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/session_info.h 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/session_info.h 2012-03-05 23:02:46.000000000 -0600 @@ -9,12 +9,29 @@ struct list; @@ -15273,9 +15598,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/session_info.h open-iscsi-2.0-872-r + unsigned int flags, int do_show); #endif -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/session_mgmt.c open-iscsi-2.0-872-rc4-bnx2i.sync/usr/session_mgmt.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/session_mgmt.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/session_mgmt.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/session_mgmt.c 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/session_mgmt.c 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/session_mgmt.c 2012-03-05 23:02:46.000000000 -0600 @@ -3,7 +3,7 @@ * * Copyright (C) 2010 Mike Christie @@ -15456,7 +15781,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/session_mgmt.c open-iscsi-2.0-872-r struct node_rec *)) { struct node_rec *curr_rec, *tmp; -@@ -191,7 +256,6 @@ int iscsi_login_portals(void *data, int +@@ -191,7 +256,6 @@ int iscsi_login_portals(void *data, int if (!err) (*nr_found)++; } @@ -15464,7 +15789,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/session_mgmt.c open-iscsi-2.0-872-r if (wait) { err = iscsid_login_reqs_wait(&login_list); if (err && !ret) -@@ -199,13 +263,50 @@ int iscsi_login_portals(void *data, int +@@ -199,13 +263,50 @@ int iscsi_login_portals(void *data, int } else iscsid_reqs_close(&login_list); @@ -15584,9 +15909,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/session_mgmt.c open-iscsi-2.0-872-r session_info_free_list(&session_list); return ret; } -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/session_mgmt.h open-iscsi-2.0-872-rc4-bnx2i.sync/usr/session_mgmt.h +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/session_mgmt.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/session_mgmt.h --- open-iscsi-2.0-872-rc4-bnx2i/usr/session_mgmt.h 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/session_mgmt.h 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/session_mgmt.h 2012-03-05 23:02:46.000000000 -0600 @@ -10,7 +10,11 @@ extern int iscsi_login_portal(void *data extern int iscsi_login_portal_nowait(struct node_rec *rec); extern int iscsi_login_portals(void *data, int *nr_found, int wait, @@ -15600,9 +15925,33 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/session_mgmt.h open-iscsi-2.0-872-r struct node_rec *)); extern int iscsi_logout_portal(struct session_info *info, struct list_head *list); -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/sysfs.c open-iscsi-2.0-872-rc4-bnx2i.sync/usr/sysfs.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/strings.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/strings.c +--- open-iscsi-2.0-872-rc4-bnx2i/usr/strings.c 2010-07-11 04:05:58.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/strings.c 2012-03-05 23:03:42.000000000 -0600 +@@ -97,11 +97,17 @@ int str_enlarge_data(struct str_buffer * + + void str_remove_initial(struct str_buffer *s, int length) + { +- char *remaining = s->buffer + length; +- int amount = s->data_length - length; ++ char *remaining; ++ int amount; + + if (s && length) { +- memmove(s->buffer, remaining, amount); ++ remaining = s->buffer + length; ++ amount = s->data_length - length; ++ ++ if (amount < 0) ++ amount = 0; ++ if (amount) ++ memmove(s->buffer, remaining, amount); + s->data_length = amount; + s->buffer[amount] = '\0'; + } +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/sysfs.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/sysfs.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/sysfs.c 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/sysfs.c 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/sysfs.c 2012-03-05 23:02:46.000000000 -0600 @@ -547,7 +547,7 @@ found: } @@ -15656,10 +16005,10 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/sysfs.c open-iscsi-2.0-872-rc4-bnx2 int sysfs_set_param(char *id, char *subsys, char *attr_name, char *write_buf, ssize_t buf_size) { -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/sysfs.h open-iscsi-2.0-872-rc4-bnx2i.sync/usr/sysfs.h +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/sysfs.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/sysfs.h --- open-iscsi-2.0-872-rc4-bnx2i/usr/sysfs.h 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/sysfs.h 2011-08-14 16:48:25.000000000 -0500 -@@ -51,14 +51,18 @@ extern char *sysfs_attr_get_value(const ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/sysfs.h 2012-03-05 23:02:46.000000000 -0600 +@@ -51,14 +51,18 @@ extern char *sysfs_attr_get_value(const extern int sysfs_resolve_link(char *path, size_t size); extern int sysfs_lookup_devpath_by_subsys_id(char *devpath, size_t len, const char *subsystem, const char *id); @@ -15680,19 +16029,29 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/sysfs.h open-iscsi-2.0-872-rc4-bnx2 extern int sysfs_set_param(char *id, char *subsys, char *attr_name, char *write_buf, ssize_t buf_size); -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/transport.c open-iscsi-2.0-872-rc4-bnx2i.sync/usr/transport.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/transport.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/transport.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/transport.c 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/usr/transport.c 2011-08-14 16:48:25.000000000 -0500 -@@ -25,7 +25,7 @@ ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/transport.c 2012-03-05 23:06:13.000000000 -0600 +@@ -25,8 +25,9 @@ #include "log.h" #include "iscsi_util.h" #include "iscsi_sysfs.h" -#include "cxgb3i.h" +#include "cxgbi.h" #include "be2iscsi.h" ++#include "iser.h" struct iscsi_transport_template iscsi_tcp = { -@@ -49,7 +49,16 @@ struct iscsi_transport_template cxgb3i = + .name = "tcp", +@@ -41,6 +42,7 @@ struct iscsi_transport_template iscsi_is + .ep_connect = ktransport_ep_connect, + .ep_poll = ktransport_ep_poll, + .ep_disconnect = ktransport_ep_disconnect, ++ .create_conn = iser_create_conn, + }; + + struct iscsi_transport_template cxgb3i = { +@@ -49,7 +51,16 @@ struct iscsi_transport_template cxgb3i = .ep_connect = ktransport_ep_connect, .ep_poll = ktransport_ep_poll, .ep_disconnect = ktransport_ep_disconnect, @@ -15710,7 +16069,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/transport.c open-iscsi-2.0-872-rc4- }; struct iscsi_transport_template bnx2i = { -@@ -70,12 +79,17 @@ struct iscsi_transport_template be2iscsi +@@ -70,12 +81,17 @@ struct iscsi_transport_template be2iscsi struct iscsi_transport_template qla4xxx = { .name = "qla4xxx", @@ -15728,7 +16087,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/transport.c open-iscsi-2.0-872-rc4- &bnx2i, &qla4xxx, &be2iscsi, -@@ -97,6 +111,7 @@ int set_transport_template(struct iscsi_ +@@ -97,6 +113,7 @@ int set_transport_template(struct iscsi_ } } @@ -15737,9 +16096,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/transport.c open-iscsi-2.0-872-rc4- + "is probably needed.\n", t->name); return ENOSYS; } -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/fwparam_ibft/fw_entry.c open-iscsi-2.0-872-rc4-bnx2i.sync/utils/fwparam_ibft/fw_entry.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/fwparam_ibft/fw_entry.c open-iscsi-2.0-872-rc4-bnx2i.work/utils/fwparam_ibft/fw_entry.c --- open-iscsi-2.0-872-rc4-bnx2i/utils/fwparam_ibft/fw_entry.c 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/utils/fwparam_ibft/fw_entry.c 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/utils/fwparam_ibft/fw_entry.c 2012-03-05 23:02:46.000000000 -0600 @@ -34,6 +34,7 @@ #include "fwparam.h" #include "idbm_fields.h" @@ -15778,9 +16137,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/fwparam_ibft/fw_entry.c open-iscs if (strlen(context->iface)) printf("%s = %s\n", IFACE_NETNAME, context->iface); } -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/fwparam_ibft/fwparam_ppc.c open-iscsi-2.0-872-rc4-bnx2i.sync/utils/fwparam_ibft/fwparam_ppc.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/fwparam_ibft/fwparam_ppc.c open-iscsi-2.0-872-rc4-bnx2i.work/utils/fwparam_ibft/fwparam_ppc.c --- open-iscsi-2.0-872-rc4-bnx2i/utils/fwparam_ibft/fwparam_ppc.c 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/utils/fwparam_ibft/fwparam_ppc.c 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/utils/fwparam_ibft/fwparam_ppc.c 2012-03-05 23:02:46.000000000 -0600 @@ -30,6 +30,7 @@ #include "iscsi_obp.h" #include "prom_parse.h" @@ -15882,9 +16241,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/fwparam_ibft/fwparam_ppc.c open-i else { fill_context(context, ofwdevs[0]); list_add_tail(&context->list, list); -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/fwparam_ibft/fwparam_sysfs.c open-iscsi-2.0-872-rc4-bnx2i.sync/utils/fwparam_ibft/fwparam_sysfs.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/fwparam_ibft/fwparam_sysfs.c open-iscsi-2.0-872-rc4-bnx2i.work/utils/fwparam_ibft/fwparam_sysfs.c --- open-iscsi-2.0-872-rc4-bnx2i/utils/fwparam_ibft/fwparam_sysfs.c 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/utils/fwparam_ibft/fwparam_sysfs.c 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/utils/fwparam_ibft/fwparam_sysfs.c 2012-03-05 23:02:46.000000000 -0600 @@ -36,6 +36,7 @@ #include "fwparam.h" #include "sysdeps.h" @@ -15917,7 +16276,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/fwparam_ibft/fwparam_sysfs.c open done: closedir(dirfd); return rc; -@@ -401,12 +402,12 @@ static int get_targets(struct list_head +@@ -401,12 +402,12 @@ static int get_targets(struct list_head rc = fill_tgt_context(subsys, target_list[i], context); if (rc) @@ -15932,7 +16291,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/fwparam_ibft/fwparam_sysfs.c open for (nic = 0; nic < nic_cnt; nic++) { int id; -@@ -420,21 +421,31 @@ static int get_targets(struct list_head +@@ -420,21 +421,31 @@ static int get_targets(struct list_head if (nic == nic_cnt) { printf("Invalid nic-assoc of %d. Max id %d.\n", nic_idx, nic_cnt); @@ -16000,9 +16359,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/fwparam_ibft/fwparam_sysfs.c open if (rc) fw_free_targets(list); return rc; -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/fwparam_ibft/prom_lex.c open-iscsi-2.0-872-rc4-bnx2i.sync/utils/fwparam_ibft/prom_lex.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/fwparam_ibft/prom_lex.c open-iscsi-2.0-872-rc4-bnx2i.work/utils/fwparam_ibft/prom_lex.c --- open-iscsi-2.0-872-rc4-bnx2i/utils/fwparam_ibft/prom_lex.c 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/utils/fwparam_ibft/prom_lex.c 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/utils/fwparam_ibft/prom_lex.c 2012-03-05 23:02:46.000000000 -0600 @@ -8,7 +8,7 @@ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 @@ -16395,7 +16754,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/fwparam_ibft/prom_lex.c open-iscs /* zero only the new slots.*/ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); -@@ -2025,7 +2038,7 @@ YY_BUFFER_STATE yy_scan_buffer (char * +@@ -2025,7 +2038,7 @@ YY_BUFFER_STATE yy_scan_buffer (char * /** Setup the input buffer state to scan a string. The next call to yylex() will * scan from a @e copy of @a str. @@ -16404,7 +16763,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/fwparam_ibft/prom_lex.c open-iscs * * @return the newly allocated buffer state object. * @note If you want to scan bytes that may contain NUL values, then use -@@ -2039,8 +2052,8 @@ YY_BUFFER_STATE yy_scan_string (yyconst +@@ -2039,8 +2052,8 @@ YY_BUFFER_STATE yy_scan_string (yyconst /** Setup the input buffer state to scan the given bytes. The next call to yylex() will * scan from a @e copy of @a bytes. @@ -16424,9 +16783,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/fwparam_ibft/prom_lex.c open-iscs -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/fwparam_ibft/prom_lex.l open-iscsi-2.0-872-rc4-bnx2i.sync/utils/fwparam_ibft/prom_lex.l +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/fwparam_ibft/prom_lex.l open-iscsi-2.0-872-rc4-bnx2i.work/utils/fwparam_ibft/prom_lex.l --- open-iscsi-2.0-872-rc4-bnx2i/utils/fwparam_ibft/prom_lex.l 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/utils/fwparam_ibft/prom_lex.l 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/utils/fwparam_ibft/prom_lex.l 2012-03-05 23:02:46.000000000 -0600 @@ -43,6 +43,8 @@ void dbgprint(const char *item) { fprint %option noyywrap @@ -16436,9 +16795,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/fwparam_ibft/prom_lex.l open-iscs VDEVICE vdevice VDEVINST gscsi -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/open-isns/client.c open-iscsi-2.0-872-rc4-bnx2i.sync/utils/open-isns/client.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/open-isns/client.c open-iscsi-2.0-872-rc4-bnx2i.work/utils/open-isns/client.c --- open-iscsi-2.0-872-rc4-bnx2i/utils/open-isns/client.c 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/utils/open-isns/client.c 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/utils/open-isns/client.c 2012-03-05 23:02:46.000000000 -0600 @@ -123,8 +123,10 @@ static isns_security_t * __create_security_context(const char *name, const char *auth_key, const char *server_key) @@ -16450,9 +16809,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/open-isns/client.c open-iscsi-2.0 if (!isns_config.ic_security) return NULL; -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/open-isns/db-file.c open-iscsi-2.0-872-rc4-bnx2i.sync/utils/open-isns/db-file.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/open-isns/db-file.c open-iscsi-2.0-872-rc4-bnx2i.work/utils/open-isns/db-file.c --- open-iscsi-2.0-872-rc4-bnx2i/utils/open-isns/db-file.c 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/utils/open-isns/db-file.c 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/utils/open-isns/db-file.c 2012-03-05 23:02:46.000000000 -0600 @@ -310,7 +310,7 @@ __dbe_file_load_object(const char *filen /* Stash away the parent's index; we resolve them later on @@ -16471,9 +16830,27617 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/open-isns/db-file.c open-iscsi-2. isns_object_t *parent; if (index == 0) -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/open-isns/Makefile.in open-iscsi-2.0-872-rc4-bnx2i.sync/utils/open-isns/Makefile.in +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/open-isns/db-policy.c open-iscsi-2.0-872-rc4-bnx2i.work/utils/open-isns/db-policy.c +--- open-iscsi-2.0-872-rc4-bnx2i/utils/open-isns/db-policy.c 2010-07-11 04:05:58.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/utils/open-isns/db-policy.c 2012-03-05 23:03:38.000000000 -0600 +@@ -7,8 +7,10 @@ + #include + #include + #include ++#ifdef WITH_SECURITY + #include + #include ++#endif + #include "isns.h" + #include "security.h" + #include "objects.h" +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/open-isns/doc/rfc2608.txt open-iscsi-2.0-872-rc4-bnx2i.work/utils/open-isns/doc/rfc2608.txt +--- open-iscsi-2.0-872-rc4-bnx2i/utils/open-isns/doc/rfc2608.txt 2010-07-11 04:05:58.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/utils/open-isns/doc/rfc2608.txt 1969-12-31 18:00:00.000000000 -0600 +@@ -1,3027 +0,0 @@ +- +- +- +- +- +- +-Network Working Group E. Guttman +-Request for Comments: 2608 C. Perkins +-Updates: 2165 Sun Microsystems +-Category: Standards Track J. Veizades +- @Home Network +- M. Day +- Vinca Corporation +- June 1999 +- +- +- Service Location Protocol, Version 2 +- +-Status of This Memo +- +- This document specifies an Internet standards track protocol for the +- Internet community, and requests discussion and suggestions for +- improvements. Please refer to the current edition of the "Internet +- Official Protocol Standards" (STD 1) for the standardization state +- and status of this protocol. Distribution of this memo is unlimited. +- +-Copyright Notice +- +- Copyright (C) The Internet Society (1999). All Rights Reserved. +- +-Abstract +- +- The Service Location Protocol provides a scalable framework for the +- discovery and selection of network services. Using this protocol, +- computers using the Internet need little or no static configuration +- of network services for network based applications. This is +- especially important as computers become more portable, and users +- less tolerant or able to fulfill the demands of network system +- administration. +- +-Table of Contents +- +- 1. Introduction 3 +- 1.1. Applicability Statement . . . . . . . . . . . . . . . 3 +- 2. Terminology 4 +- 2.1. Notation Conventions . . . . . . . . . . . . . . . . . 4 +- 3. Protocol Overview 5 +- 4. URLs used with Service Location 8 +- 4.1. Service: URLs . . . . . . . . . . . . . . . . . . . . 9 +- 4.2. Naming Authorities . . . . . . . . . . . . . . . . . 10 +- 4.3. URL Entries . . . . . . . . . . . . . . . . . . . . . 10 +- 5. Service Attributes 10 +- 6. Required Features 12 +- 6.1. Use of Ports, UDP, and Multicast . . . . . . . . . . 13 +- +- +- +-Guttman, et al. Standards Track [Page 1] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +- 6.2. Use of TCP . . . . . . . . . . . . . . . . . . . . . 14 +- 6.3. Retransmission of SLP messages . . . . . . . . . . . 15 +- 6.4. Strings in SLP messages . . . . . . . . . . . . . . . 16 +- 6.4.1. Scope Lists in SLP . . . . . . . . . . . . . . 16 +- 7. Errors 17 +- 8. Required SLP Messages 17 +- 8.1. Service Request . . . . . . . . . . . . . . . . . . . 19 +- 8.2. Service Reply . . . . . . . . . . . . . . . . . . . . 21 +- 8.3. Service Registration . . . . . . . . . . . . . . . . . 22 +- 8.4. Service Acknowledgment . . . . . . . . . . . . . . . . 23 +- 8.5. Directory Agent Advertisement. . . . . . . . . . . . . 24 +- 8.6. Service Agent Advertisement. . . . . . . . . . . . . . 25 +- 9. Optional Features 26 +- 9.1. Service Location Protocol Extensions . . . . . . . . . 27 +- 9.2. Authentication Blocks . . . . . . . . . . . . . . . . 28 +- 9.2.1. SLP Message Authentication Rules . . . . . . . 29 +- 9.2.2. DSA with SHA-1 in Authentication Blocks . . . 30 +- 9.3. Incremental Service Registration . . . . . . . . . . 30 +- 9.4. Tag Lists . . . . . . . . . . . . . . . . . . . . . . 31 +- 10. Optional SLP Messages 32 +- 10.1. Service Type Request . . . . . . . . . . . . . . . . 32 +- 10.2. Service Type Reply . . . . . . . . . . . . . . . . . 32 +- 10.3. Attribute Request . . . . . . . . . . . . . . . . . . 33 +- 10.4. Attribute Reply . . . . . . . . . . . . . . . . . . . 34 +- 10.5. Attribute Request/Reply Examples . . . . . . . . . . . 34 +- 10.6. Service Deregistration . . . . . . . . . . . . . . . 36 +- 11. Scopes 37 +- 11.1. Scope Rules . . . . . . . . . . . . . . . . . . . . . 37 +- 11.2. Administrative and User Selectable Scopes. . . . . . . 38 +- 12. Directory Agents 38 +- 12.1. Directory Agent Rules . . . . . . . . . . . . . . . . 39 +- 12.2. Directory Agent Discovery . . . . . . . . . . . . . . 39 +- 12.2.1. Active DA Discovery . . . . . . . . . . . . . 40 +- 12.2.2. Passive DA Advertising . . . . . . . . . . . . 40 +- 12.3. Reliable Unicast to DAs and SAs. . . . . . . . . . . . 41 +- 12.4. DA Scope Configuration . . . . . . . . . . . . . . . 41 +- 12.5. DAs and Authentication Blocks. . . . . . . . . . . . . 41 +- 13. Protocol Timing Defaults 42 +- 14. Optional Configuration 43 +- 15. IANA Considerations 44 +- 16. Internationalization Considerations 45 +- 17. Security Considerations 46 +- A. Appendix: Changes to the Service Location Protocol from +- v1 to v2 48 +- B. Appendix: Service Discovery by Type: Minimal SLPv2 Features 48 +- C. Appendix: DAAdverts with arbitrary URLs 49 +- D. Appendix: SLP Protocol Extensions 50 +- D.1. Required Attribute Missing Option . . . . . . . . . . 50 +- +- +- +-Guttman, et al. Standards Track [Page 2] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +- E. Acknowledgments 50 +- F. References 51 +- G. Authors' Addresses 53 +- H. Full Copyright Statement 54 +- +-1. Introduction +- +- The Service Location Protocol (SLP) provides a flexible and scalable +- framework for providing hosts with access to information about the +- existence, location, and configuration of networked services. +- Traditionally, users have had to find services by knowing the name of +- a network host (a human readable text string) which is an alias for a +- network address. SLP eliminates the need for a user to know the name +- of a network host supporting a service. Rather, the user supplies +- the desired type of service and a set of attributes which describe +- the service. Based on that description, the Service Location +- Protocol resolves the network address of the service for the user. +- +- SLP provides a dynamic configuration mechanism for applications in +- local area networks. Applications are modeled as clients that need +- to find servers attached to any of the available networks within an +- enterprise. For cases where there are many different clients and/or +- services available, the protocol is adapted to make use of nearby +- Directory Agents that offer a centralized repository for advertised +- services. +- +- This document updates SLPv1 [RFC 2165], correcting protocol errors, +- adding some enhancements and removing some requirements. This +- specification has two parts. The first describes the required +- features of the protocol. The second describes the extended features +- of the protocol which are optional, and allow greater scalability. +- +-1.1. Applicability Statement +- +- SLP is intended to function within networks under cooperative +- administrative control. Such networks permit a policy to be +- implemented regarding security, multicast routing and organization of +- services and clients into groups which are not be feasible on the +- scale of the Internet as a whole. +- +- SLP has been designed to serve enterprise networks with shared +- services, and it may not necessarily scale for wide-area service +- discovery throughout the global Internet, or in networks where there +- are hundreds of thousands of clients or tens of thousands of +- services. +- +- +- +- +- +- +-Guttman, et al. Standards Track [Page 3] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +-2. Terminology +- +- User Agent (UA) +- A process working on the user's behalf to establish +- contact with some service. The UA retrieves service +- information from the Service Agents or Directory Agents. +- +- Service Agent (SA) A process working on the behalf of one or more +- services to advertise the services. +- +- Directory Agent (DA) A process which collects service +- advertisements. There can only be one DA present per +- given host. +- +- Service Type Each type of service has a unique Service Type +- string. +- +- Naming Authority The agency or group which catalogues given +- Service Types and Attributes. The default Naming +- Authority is IANA. +- +- Scope A set of services, typically making up a logical +- administrative group. +- +- URL A Universal Resource Locator [8]. +- +-2.1. Notation Conventions +- +- The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +- "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +- document are to be interpreted as described in RFC 2119 [9]. +- +- Syntax Syntax for string based protocols follow the +- conventions defined for ABNF [11]. +- +- Strings All strings are encoded using the UTF-8 [23] +- transformation of the Unicode [6] character set and +- are NOT null terminated when transmitted. Strings +- are preceded by a two byte length field. +- +- A comma delimited list of strings with the +- following syntax: +- +- string-list = string / string `,' string-list +- +- In format diagrams, any field ending with a \ indicates a variable +- length field, given by a prior length field in the protocol. +- +- +- +- +-Guttman, et al. Standards Track [Page 4] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +-3. Protocol Overview +- +- The Service Location Protocol supports a framework by which client +- applications are modeled as 'User Agents' and services are advertised +- by 'Service Agents.' A third entity, called a 'Directory Agent' +- provides scalability to the protocol. +- +- The User Agent issues a 'Service Request' (SrvRqst) on behalf of the +- client application, specifying the characteristics of the service +- which the client requires. The User Agent will receive a Service +- Reply (SrvRply) specifying the location of all services in the +- network which satisfy the request. +- +- The Service Location Protocol framework allows the User Agent to +- directly issue requests to Service Agents. In this case the request +- is multicast. Service Agents receiving a request for a service which +- they advertise unicast a reply containing the service's location. +- +- +------------+ ----Multicast SrvRqst----> +---------------+ +- | User Agent | | Service Agent | +- +------------+ <----Unicast SrvRply------ +---------------+ +- +- In larger networks, one or more Directory Agents are used. The +- Directory Agent functions as a cache. Service Agents send register +- messages (SrvReg) containing all the services they advertise to +- Directory Agents and receive acknowledgements in reply (SrvAck). +- These advertisements must be refreshed with the Directory Agent or +- they expire. User Agents unicast requests to Directory Agents +- instead of Service Agents if any Directory Agents are known. +- +- +-------+ -Unicast SrvRqst-> +-----------+ <-Unicast SrvReg- +--------+ +- | User | | Directory | |Service | +- | Agent | | Agent | | Agent | +- +-------+ <-Unicast SrvRply- +-----------+ -Unicast SrvAck-> +--------+ +- +- User and Service Agents discover Directory Agents two ways. First, +- they issue a multicast Service Request for the 'Directory Agent' +- service when they start up. Second, the Directory Agent sends an +- unsolicited advertisement infrequently, which the User and Service +- Agents listen for. In either case the Agents receive a DA +- Advertisement (DAAdvert). +- +- +---------------+ --Multicast SrvRqst-> +-----------+ +- | User or | <--Unicast DAAdvert-- | Directory | +- | Service Agent | | Agent | +- +---------------+ <-Multicast DAAdvert- +-----------+ +- +- +- +- +- +-Guttman, et al. Standards Track [Page 5] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +- Services are grouped together using 'scopes'. These are strings +- which identify services which are administratively identified. A +- scope could indicate a location, administrative grouping, proximity +- in a network topology or some other category. Service Agents and +- Directory Agents are always assigned a scope string. +- +- A User Agent is normally assigned a scope string (in which case the +- User Agent will only be able to discover that particular grouping of +- services). This allows a network administrator to 'provision' +- services to users. Alternatively, the User Agent may be configured +- with no scope at all. In that case, it will discover all available +- scopes and allow the client application to issue requests for any +- service available on the network. +- +- +---------+ Multicast +-----------+ Unicast +-----------+ +- | Service | <--SrvRqst-- | User | --SrvRqst-> | Directory | +- | Agent | | Agent | | Agent | +- | Scope=X | Unicast | Scope=X,Y | Unicast | Scope=Y | +- +---------+ --SrvRply--> +-----------+ <-SrvRply-- +-----------+ +- +- In the above illustration, the User Agent is configured with scopes X +- and Y. If a service is sought in scope X, the request is multicast. +- If it is sought in scope Y, the request is unicast to the DA. +- Finally, if the request is to be made in both scopes, the request +- must be both unicast and multicast. +- +- Service Agents and User Agents may verify digital signatures provided +- with DAAdverts. User Agents and Directory Agents may verify service +- information registered by Service Agents. The keying material to use +- to verify digital signatures is identified using a SLP Security +- Parameter Index, or SLP SPI. +- +- Every host configured to generate a digital signature includes the +- SLP SPI used to verify it in the Authentication Block it transmits. +- Every host which can verify a digital signature must be configured +- with keying material and other parameters corresponding with the SLP +- SPI such that it can perform verifying calculations. +- +- SAs MUST accept multicast service requests and unicast service +- requests. SAs MAY accept other requests (Attribute and Service Type +- Requests). SAs MUST listen for multicast DA Advertisements. +- +- The features described up to this point are required to implement. A +- minimum implementation consists of a User Agent, Service Agent or +- both. +- +- There are several optional features in the protocol. Note that DAs +- MUST support all these message types, but DA support is itself +- +- +- +-Guttman, et al. Standards Track [Page 6] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +- optional to deploy on networks using SLP. UAs and SAs MAY support +- these message types. These operations are primarily for interactive +- use (browsing or selectively updating service registrations.) UAs +- and SAs either support them or not depending on the requirements and +- constraints of the environment where they will be used. +- +- Service Type Request A request for all types of service on the +- network. This allows generic service browsers +- to be built. +- +- Service Type Reply A reply to a Service Type Request. +- +- Attribute Request A request for attributes of a given type of +- service or attributes of a given service. +- +- Attribute Reply A reply to an Attribute Request. +- +- Service Deregister A request to deregister a service or some +- attributes of a service. +- +- Service Update A subsequent SrvRqst to an advertisement. +- This allows individual dynamic attributes to +- be updated. +- +- SA Advertisement In the absence of Directory Agents, a User +- agent may request Service Agents in order +- to discover their scope configuration. The +- User Agent may use these scopes in requests. +- +- In the absence of Multicast support, Broadcast MAY be used. The +- location of DAs may be staticly configured, discovered using SLP as +- described above, or configured using DHCP. If a message is too large, +- it may be unicast using TCP. +- +- A SLPv2 implementation SHOULD support SLPv1 [22]. This support +- includes: +- +- 1. SLPv2 DAs are deployed, phasing out SLPv1 DAs. +- +- 2. Unscoped SLPv1 requests are considered to be of DEFAULT scope. +- SLPv1 UAs MUST be reconfigured to have a scope if possible. +- +- 3. There is no way for an SLPv2 DA to behave as an unscoped SLPv1 +- DA. SLPv1 SAs MUST be reconfigured to have a scope if possible. +- +- 4. SLPv2 DAs answer SLPv1 requests with SLPv1 replies and SLPv2 +- requests with SLPv2 replies. +- +- +- +- +-Guttman, et al. Standards Track [Page 7] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +- 5. SLPv2 DAs use registrations from SLPv1 and SLPv2 in the same +- way. That is, incoming requests from agents using either version +- of the protocol will be matched against this common set of +- registered services. +- +- 6. SLPv2 registrations which use Language Tags which are greater +- than 2 characters long will be inaccessible to SLPv1 UAs. +- +- 7. SLPv2 DAs MUST return only service type strings in SrvTypeRply +- messages which conform to SLPv1 service type string syntax, ie. +- they MUST NOT return Service Type strings for abstract service +- types. +- +- 8. SLPv1 SrvRqsts and AttrRqsts by Service Type do not match Service +- URLs with abstract service types. They only match Service URLs +- with concrete service types. +- +- SLPv1 UAs will not receive replies from SLPv2 SAs and SLPv2 UAs will +- not receive replies from SLPv1 SAs. In order to interoperate UAs and +- SAs of different versions require a SLPv2 DA to be present on the +- network which supports both protocols. +- +- The use of abstract service types in SLPv2 presents a backward +- compatibility issue for SLPv1. It is possible that a SLPv1 UA will +- request a service type which is actually an abstract service type. +- Based on the rules above, the SLPv1 UA will never receive an abstract +- Service URL reply. For example, the service type 'service:x' in a +- SLPv1 AttrRqst will not return the attributes of 'service:x:y://orb'. +- If the request was made with SLPv2, it would return the attributes of +- this service. +- +-4. URLs used with Service Location +- +- A Service URL indicates the location of a service. This URL may be +- of the service: scheme [13] (reviewed in section 4.1), or any other +- URL scheme conforming to the URI standard [8], except that URLs +- without address specifications SHOULD NOT be advertised by SLP. The +- service type for an 'generic' URL is its scheme name. For example, +- the service type string for "http://www.srvloc.org" would be "http". +- +- Reserved characters in URLs follow the rules in RFC 2396 [8]. +- +- +- +- +- +- +- +- +- +- +-Guttman, et al. Standards Track [Page 8] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +-4.1. Service: URLs +- +- Service URL syntax and semantics are defined in [13]. Any network +- service may be encoded in a Service URL. +- +- This section provides an introduction to Service URLs and an example +- showing a simple application of them, representing standard network +- services. +- +- A Service URL may be of the form: +- +- "service:""://" +- +- The Service Type of this service: URL is defined to be the string up +- to (but not including) the final `:' before , the address +- specification. +- +- is a hostname (which should be used if possible) or dotted +- decimal notation for a hostname, followed by an optional `:' and +- port number. +- +- A service: scheme URL may be formed with any standard protocol name +- by concatenating "service:" and the reserved port [1] name. For +- example, "service:tftp://myhost" would indicate a tftp service. A +- tftp service on a nonstandard port could be +- "service:tftp://bad.glad.org:8080". +- +- Service Types SHOULD be defined by a "Service Template" [13], which +- provides expected attributes, values and protocol behavior. An +- abstract service type (also described in [13]) has the form +- +- "service::". +- +- The service type string "service:" matches all +- services of that abstract type. If the concrete type is included +- also, only these services match the request. For example: a SrvRqst +- or AttrRqst which specifies "service:printer" as the Service Type +- will match the URL service:printer:lpr://hostname and +- service:printer:http://hostname. If the requests specified +- "service:printer:http" they would match only the latter URL. +- +- An optional substring MAY follow the last `.' character in the +- (or in the case of an abstract service type +- URL). This substring is the Naming Authority, as described in Section +- 9.6. Service types with different Naming Authorities are quite +- distinct. In other words, service:x.one and service:x.two are +- different service types, as are service:abstract.one:y and +- service:abstract.two:y. +- +- +- +-Guttman, et al. Standards Track [Page 9] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +-4.2. Naming Authorities +- +- A Naming Authority MAY optionally be included as part of the Service +- Type string. The Naming Authority of a service defines the meaning +- of the Service Types and attributes registered with and provided by +- Service Location. The Naming Authority itself is typically a string +- which uniquely identifies an organization. IANA is the implied +- Naming Authority when no string is appended. "IANA" itself MUST NOT +- be included explicitly. +- +- Naming Authorities may define Service Types which are experimental, +- proprietary or for private use. Using a Naming Authority, one may +- either simply ignore attributes upon registration or create a local- +- use only set of attributes for one's site. The procedure to use is +- to create a 'unique' Naming Authority string and then specify the +- Standard Attribute Definitions as described above. This Naming +- Authority will accompany registration and queries, as described in +- Sections 8.1 and 8.3. Service Types SHOULD be registered with IANA +- to allow for Internet-wide interoperability. +- +-4.3. URL Entries +- +- 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 +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | Reserved | Lifetime | URL Length | +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- |URL len, contd.| URL (variable length) \ +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- |# of URL auths | Auth. blocks (if any) \ +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- +- SLP stores URLs in protocol elements called URL Entries, which +- associate a length, a lifetime, and possibly authentication +- information along with the URL. URL Entries, defined as shown above, +- are used in Service Replies and Service Registrations. +- +-5. Service Attributes +- +- A service advertisement is often accompanied by Service Attributes. +- These attributes are used by UAs in Service Requests to select +- appropriate services. +- +- The allowable attributes which may be used are typically specified by +- a Service Template [13] for a particular service type. Services +- which are advertised according to a standard template MUST register +- all service attributes which the standard template requires. URLs +- with schemes other than "service:" MAY be registered with attributes. +- +- +- +-Guttman, et al. Standards Track [Page 10] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +- Non-standard attribute names SHOULD begin with "x-", because no +- standard attribute name will ever have those initial characters. +- +- An attribute list is a string encoding of the attributes of a +- service. The following ABNF [11] grammar defines attribute lists: +- +- attr-list = attribute / attribute `,' attr-list +- attribute = `(' attr-tag `=' attr-val-list `)' / attr-tag +- attr-val-list = attr-val / attr-val `,' attr-val-list +- attr-tag = 1*safe-tag +- attr-val = intval / strval / boolval / opaque +- intval = [-]1*DIGIT +- strval = 1*safe-val +- boolval = "true" / "false" +- opaque = "\FF" 1*escape-val +- safe-val = ; Any character except reserved. +- safe-tag = ; Any character except reserved, star and bad-tag. +- reserved = `(' / `)' / `,' / `\' / `!' / `<' / `=' / `>' / `~' / CTL +- escape-val = `\' HEXDIG HEXDIG +- bad-tag = CR / LF / HTAB / `_' +- star = `*' +- +- The , if present, MUST be scanned prior to evaluation for +- all occurrences of the escape character `\'. Reserved characters +- MUST be escaped (other characters MUST NOT be escaped). All escaped +- characters must be restored to their value before attempting string +- matching. For Opaque values, escaped characters are not converted - +- they are interpreted as bytes. +- +- Boolean Strings which have the form "true" or "false" can +- only take one value and may only be compared with +- '='. Booleans are case insensitive when compared. +- +- Integer Strings which take the form [-] 1* and fall +- in the range "-2147483648" to "2147483647" are +- considered to be Integers. These are compared using +- integer comparison. +- +- String All other Strings are matched using strict lexical +- ordering (see Section 6.4). +- +- Opaque Opaque values are sequences of bytes. These are +- distinguished from Strings since they begin with +- the sequence "\FF". This, unescaped, is an illegal +- UTF-8 encoding, indicating that what follows is a +- sequence of bytes expressed in escape notation which +- constitute the binary value. For example, a '0' byte +- is encoded "\FF\00". +- +- +- +-Guttman, et al. Standards Track [Page 11] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +- A string which contains escaped values other than from the reserved +- set of characters is illegal. If such a string is included in an +- , or search filter, the SA or DA which receives +- it MUST return a PARSE_ERROR to the message. +- +- A keyword has only an , and no values. Attributes can have +- one or multiple values. All values are expressed as strings. +- +- When values have been advertised by a SA or are registered in a DA, +- they can take on implicit typing rules for matching incoming +- requests. +- +- Stored values must be consistent, i.e., x=4,true,sue,\ff\00\00 is +- disallowed. A DA or SA receiving such an MUST return an +- INVALID_REGISTRATION error. +- +-6. Required Features +- +- This section defines the minimal implementation requirements for SAs +- and UAs as well as their interaction with DAs. A DA is not required +- for SLP to function, but if it is present, the UA and SA MUST +- interact with it as defined below. +- +- A minimal implementation may consist of either a UA or SA or both. +- The only required features of a UA are that it can issue SrvRqsts +- according to the rules below and interpret DAAdverts, SAAdverts and +- SrvRply messages. The UA MUST issue requests to DAs as they are +- discovered. An SA MUST reply to appropriate SrvRqsts with SrvRply or +- SAAdvert messages. The SA MUST also register with DAs as they are +- discovered. +- +- UAs perform discovery by issuing Service Request messages. SrvRqst +- messages are issued, using UDP, following these prioritized rules: +- +- 1. A UA issues a request to a DA which it has been configured with +- by DHCP. +- +- 2. A UA issues requests to DAs which it has been statically +- configured with. +- +- 3. UA uses multicast/convergence SrvRqsts to discover DAs, then uses +- that set of DAs. A UA that does not know of any DAs SHOULD retry +- DA discovery, increasing the waiting interval between subsequent +- attempts exponentially (doubling the wait interval each time.) +- The recommended minimum waiting interval is CONFIG_DA_FIND +- seconds. +- +- +- +- +- +-Guttman, et al. Standards Track [Page 12] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +- 4. A UA with no knowledge of DAs sends requests using multicast +- convergence to SAs. SAs unicast replies to UAs according to the +- multicast convergence algorithm. +- +- UAs and SAs are configured with a list of scopes to use according to +- these prioritized rules: +- +- 1. With DHCP. +- +- 2. With static configuration. The static configuration may be +- explicitly set to NO SCOPE for UAs, if the User Selectable Scope +- model is used. See section 11.2. +- +- 3. In the absence of configuration, the agent's scope is "DEFAULT". +- +- A UA MUST issue requests with one or more of the scopes it has been +- configured to use. +- +- A UA which has been statically configured with NO SCOPE LIST will use +- DA or SA discovery to determine its scope list dynamically. In this +- case it uses an empty scope list to discover DAs and possibly SAs. +- Then it uses the scope list it obtains from DAAdverts and possibly +- SAAdverts in subsequent requests. +- +- The SA MUST register all its services with any DA it discovers, if +- the DA advertises any of the scopes it has been configured with. A +- SA obtains information about DAs as a UA does. In addition, the SA +- MUST listen for multicast unsolicited DAAdverts. The SA registers by +- sending SrvReg messages to DAs, which reply with SrvReg messages to +- indicate success. SAs register in ALL the scopes they were +- configured to use. +- +-6.1. Use of Ports, UDP, and Multicast +- +- DAs MUST accept unicast requests and multicast directory agent +- discovery service requests (for the service type "service:directory- +- agent"). +- +- SAs MUST accept multicast requests and unicast requests both. The SA +- can distinguish between them by whether the REQUEST MCAST flag is set +- in the SLP Message header. +- +- The Service Location Protocol uses multicast for discovering DAs and +- for issuing requests to SAs by default. +- +- The reserved listening port for SLP is 427. This is the destination +- port for all SLP messages. SLP messages MAY be transmitted on an +- ephemeral port. Replies and acknowledgements are sent to the port +- +- +- +-Guttman, et al. Standards Track [Page 13] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +- from which the request was issued. The default maximum transmission +- unit for UDP messages is 1400 bytes excluding UDP and other headers. +- +- If a SLP message does not fit into a UDP datagram it MUST be +- truncated to fit, and the OVERFLOW flag is set in the reply message. +- A UA which receives a truncated message MAY open a TCP connection +- (see section 6.2) with the DA or SA and retransmit the request, using +- the same XID. It MAY also attempt to make use of the truncated reply +- or reformulate a more restrictive request which will result in a +- smaller reply. +- +- SLP Requests messages are multicast to The Administratively Scoped +- SLP Multicast [17] address, which is 239.255.255.253. The default +- TTL to use for multicast is 255. +- +- In isolated networks, broadcasts will work in place of multicast. To +- that end, SAs SHOULD and DAs MUST listen for broadcast Service +- Location messages at port 427. This allows UAs which do not support +- multicast the use of Service Location on isolated networks. +- +- Setting multicast TTL to less than 255 (the default) limits the range +- of SLP discovery in a network, and localizes service information in +- the network. +- +-6.2. Use of TCP +- +- A SrvReg or SrvDeReg may be too large to fit into a datagram. To +- send such large SLP messages, a TCP (unicast) connection MUST be +- established. +- +- To avoid the need to implement TCP, one MUST insure that: +- +- - UAs never issue requests larger than the Path MTU. SAs can omit +- TCP support only if they never have to receive unicast requests +- longer than the path MTU. +- +- - UAs can accept replies with the 'OVERFLOW' flag set, and make use +- of the first result included, or reformulate the request. +- +- - Ensure that a SA can send a SrvRply, SrvReg, or SrvDeReg in +- a single datagram. This means limiting the size of URLs, +- the number of attributes and the number of authenticators +- transmitted. +- +- DAs MUST be able to respond to UDP and TCP requests, as well as +- multicast DA Discovery SrvRqsts. SAs MUST be able to respond to TCP +- unless the SA will NEVER receive a request or send a reply which will +- exceed a datagram in size (e.g., some embedded systems). +- +- +- +-Guttman, et al. Standards Track [Page 14] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +- A TCP connection MAY be used for a single SLP transaction, or for +- multiple transactions. Since there are length fields in the message +- headers, SLP Agents can send multiple requests along a connection and +- read the return stream for acknowledgments and replies. +- +- The initiating agent SHOULD close the TCP connection. The DA SHOULD +- wait at least CONFIG_CLOSE_CONN seconds before closing an idle +- connection. DAs and SAs SHOULD close an idle TCP connection after +- CONFIG_CLOSE_CONN seconds to ensure robust operation, even when the +- initiating agent neglects to close it. See Section 13 for timing +- rules. +- +-6.3. Retransmission of SLP messages +- +- Requests which fail to elicit a response are retransmitted. The +- initial retransmission occurs after a CONFIG_RETRY wait period. +- Retransmissions MUST be made with exponentially increasing wait +- intervals (doubling the wait each time). This applies to unicast as +- well as multicast SLP requests. +- +- Unicast requests to a DA or SA should be retransmitted until either a +- response (which might be an error) has been obtained, or for +- CONFIG_RETRY_MAX seconds. +- +- Multicast requests SHOULD be reissued over CONFIG_MC_MAX seconds +- until a result has been obtained. UAs need only wait till they +- obtain the first reply which matches their request. That is, +- retransmission is not required if the requesting agent is prepared to +- use the 'first reply' instead of 'as many replies as possible within +- a bounded time interval.' +- +- When SLP SrvRqst, SrvTypeRqst, and AttrRqst messages are multicast, +- they contain a of previous responders. Initially the +- is empty. When these requests are unicast, the is +- always empty. +- +- Any DA or SA which sees its address in the MUST NOT respond +- to the request. +- +- The message SHOULD be retransmitted until the causes no +- further responses to be elicited or the previous responder list and +- the request will not fit into a single datagram or until +- CONFIG_MC_MAX seconds elapse. +- +- UAs which retransmit a request use the same XID. This allows a DA or +- SA to cache its reply to the original request and then send it again, +- should a duplicate request arrive. This cached information should +- only be held very briefly. XIDs SHOULD be randomly chosen to avoid +- +- +- +-Guttman, et al. Standards Track [Page 15] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +- duplicate XIDs in requests if UAs restart frequently. +- +-6.4. Strings in SLP messages +- +- The escape character is a backslash (UTF-8 0x5c) followed by the two +- hexadecimal digits of the escaped character. Only reserved +- characters are escaped. For example, a comma (UTF-8 0x29) is escaped +- as `\29', and a backslash `\' is escaped as `\5c'. String lists used +- in SLP define the comma to be the delimiter between list elements, so +- commas in data strings must be escaped in this manner. Backslashes +- are the escape character so they also must always be escaped when +- included in a string literally. +- +- String comparison for order and equality in SLP MUST be case +- insensitive inside the 0x00-0x7F subrange of UTF-8 (which corresponds +- to ASCII character encoding). Case insensitivity SHOULD be supported +- throughout the entire UTF-8 encoded Unicode [6] character set. +- +- The case insensitivity rule applies to all string matching in SLPv2, +- including Scope strings, SLP SPI strings, service types, attribute +- tags and values in query handling, language tags, previous responder +- lists. Comparisons of URL strings, however, is case sensitive. +- +- White space (SPACE, CR, LF, TAB) internal to a string value is folded +- to a single SPACE character for the sake of string comparisons. +- White space preceding or following a string value is ignored for the +- purposes of string comparison. For example, " Some String " +- matches "SOME STRING". +- +- String comparisons (using comparison operators such as `<=' or `>=') +- are done using lexical ordering in UTF-8 encoded characters, not +- using any language specific rules. +- +- The reserved character `*' may precede, follow or be internal to a +- string value in order to indicate substring matching. The query +- including this character matches any character sequence which +- conforms to the letters which are not wildcarded. +- +-6.4.1. Scope Lists in SLP +- +- Scope Lists in SLPv2 have the following grammar: +- +- scope-list = scope-val / scope-val `,' scope-list +- scope-val = 1*safe +- safe = ; Any character except reserved. +- reserved = `(' / `)' / `,' / `\' / `!' / `<' / `=' / `>' / `~' / CTL +- / `;' / `*' / `+' +- escape-val = `\' HEXDIG HEXDIG +- +- +- +-Guttman, et al. Standards Track [Page 16] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +- Scopes which include any reserved characters must replace the escaped +- character with the escaped-val format. +- +-7. Errors +- +- If the Error Code in a SLP reply message is nonzero, the rest of the +- message MAY be truncated. No data is necessarily transmitted or +- should be expected after the header and the error code, except +- possibly for some optional extensions to clarify the error, for +- example as in section D.1. +- +- Errors are only returned for unicast requests. Multicast requests +- are silently discarded if they result in an error. +- +- LANGUAGE_NOT_SUPPORTED = 1: There is data for the service type in +- the scope in the AttrRqst or SrvRqst, but not in the requested +- language. +- PARSE_ERROR = 2: The message fails to obey SLP syntax. +- INVALID_REGISTRATION = 3: The SrvReg has problems -- e.g., a zero +- lifetime or an omitted Language Tag. +- SCOPE_NOT_SUPPORTED = 4: The SLP message did not include a scope in +- its supported by the SA or DA. +- AUTHENTICATION_UNKNOWN = 5: The DA or SA receives a request for an +- unsupported SLP SPI. +- AUTHENTICATION_ABSENT = 6: The DA expected URL and ATTR +- authentication in the SrvReg and did not receive it. +- AUTHENTICATION_FAILED = 7: The DA detected an authentication error in +- an Authentication block. +- VER_NOT_SUPPORTED = 9: Unsupported version number in message header. +- INTERNAL_ERROR = 10: The DA (or SA) is too sick to respond. +- DA_BUSY_NOW = 11: UA or SA SHOULD retry, using exponential back off. +- OPTION_NOT_UNDERSTOOD = 12: The DA (or SA) received an unknown option +- from the mandatory range (see section 9.1). +- INVALID_UPDATE = 13: The DA received a SrvReg without FRESH set, for +- an unregistered service or with inconsistent Service Types. +- MSG_NOT_SUPPORTED = 14: The SA received an AttrRqst or SrvTypeRqst +- and does not support it. +- REFRESH_REJECTED = 15: The SA sent a SrvReg or partial SrvDereg to a +- DA more frequently than the DA's min-refresh-interval. +- +-8. Required SLP Messages +- +- All length fields in SLP messages are in network byte order. Where ' +- tuples' are defined, these are sequences of bytes, in the precise +- order listed, in network byte order. +- +- SLP messages all begin with the following header: +- +- +- +- +-Guttman, et al. Standards Track [Page 17] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +- 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 +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | Version | Function-ID | Length | +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | Length, contd.|O|F|R| reserved |Next Ext Offset| +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | Next Extension Offset, contd.| XID | +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | Language Tag Length | Language Tag \ +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- +- Message Type Abbreviation Function-ID +- +- Service Request SrvRqst 1 +- Service Reply SrvRply 2 +- Service Registration SrvReg 3 +- Service Deregister SrvDeReg 4 +- Service Acknowledge SrvAck 5 +- Attribute Request AttrRqst 6 +- Attribute Reply AttrRply 7 +- DA Advertisement DAAdvert 8 +- Service Type Request SrvTypeRqst 9 +- Service Type Reply SrvTypeRply 10 +- SA Advertisement SAAdvert 11 +- +- SAs and UAs MUST support SrvRqst, SrvRply and DAAdvert. SAs MUST +- also support SrvReg, SAAdvert and SrvAck. For UAs and SAs, support +- for other messages are OPTIONAL. +- +- - Length is the length of the entire SLP message, header included. +- - The flags are: OVERFLOW (0x80) is set when a message's length +- exceeds what can fit into a datagram. FRESH (0x40) is set on +- every new SrvReg. REQUEST MCAST (0x20) is set when multicasting +- or broadcasting requests. Reserved bits MUST be 0. +- - Next Extension Offset is set to 0 unless extensions are used. +- The first extension begins at 'offset' bytes, from the message's +- beginning. It is placed after the SLP message data. See +- Section 9.1 for how to interpret unrecognized SLP Extensions. +- - XID is set to a unique value for each unique request. If the +- request is retransmitted, the same XID is used. Replies set +- the XID to the same value as the xid in the request. Only +- unsolicited DAAdverts are sent with an XID of 0. +- - Lang Tag Length is the length in bytes of the Language Tag field. +- - Language Tag conforms to [7]. The Language Tag in a reply MUST +- be the same as the Language Tag in the request. This field must +- be encoded 1*8ALPHA *("-" 1*8ALPHA). +- +- +- +- +-Guttman, et al. Standards Track [Page 18] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +- If an option is specified, and not included in the message, the +- receiver MUST respond with a PARSE_ERROR. +- +-8.1. Service Request +- +- 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 +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | Service Location header (function = SrvRqst = 1) | +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | length of | String \ +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | length of | String \ +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | length of | String \ +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | length of predicate string | Service Request \ +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | length of string | String \ +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- +- In order for a Service to match a SrvRqst, it must belong to at least +- one requested scope, support the requested service type, and match +- the predicate. If the predicate is present, the language of the +- request (ignoring the dialect part of the Language Tag) must match +- the advertised service. +- +- is the Previous Responder List. This contains +- dotted decimal notation IP (v4) addresses, and is iteratively +- multicast to obtain all possible results (see Section 6.3). UAs +- SHOULD implement this discovery algorithm. SAs MUST use this to +- discover all available DAs in their scope, if they are not already +- configured with DA addresses by some other means. +- +- A SA silently drops all requests which include the SA's address in +- the . An SA which has multiple network interfaces MUST check +- if any of the entries in the equal any of its interfaces. +- An entry in the PRList which does not conform to an IPv4 dotted +- decimal address is ignored: The rest of the is processed +- normally and an error is not returned. +- +- Once a plus the request exceeds the path MTU, multicast +- convergence stops. This algorithm is not intended to find all +- instances; it finds 'enough' to provide useful results. +- +- The is a of configured scope names. SAs +- and DAs which have been configured with any of the scopes in this +- list will respond. DAs and SAs MUST reply to unicast requests with a +- +- +- +-Guttman, et al. Standards Track [Page 19] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +- SCOPE_NOT_SUPPORTED error if the is omitted or fails to +- include a scope they support (see Section 11). The only exceptions +- to this are described in Section 11.2. +- +- The string is discussed in Section 4. Normally, a +- SrvRqst elicits a SrvRply. There are two exceptions: If the +- is set to "service:directory-agent", DAs respond to +- the SrvRqst with a DAAdvert (see Section 8.5.) If set to +- "service:service-agent", SAs respond with a SAAdvert (see Section +- 8.6.) If this field is omitted, a PARSE_ERROR is returned - as this +- field is REQUIRED. +- +- The is a LDAPv3 search filter [14]. This field is +- OPTIONAL. Services may be discovered simply by type and scope. +- Otherwise, services are discovered which satisfy the . If +- present, it is compared to each registered service. If the attribute +- in the filter has been registered with multiple values, the filter is +- compared to each value and the results are ORed together, i.e., +- "(x=3)" matches a registration of (x=1,2,3); "(!(Y=0))" matches +- (y=0,1) since Y can be nonzero. Note the matching is case +- insensitive. Keywords (i.e., attributes without values) are matched +- with a "presence" filter, as in "(keyword=*)". +- +- An incoming request term MUST have the same type as the attribute in +- a registration in order to match. Thus, "(x=33)" will not match ' +- x=true', etc. while "(y=foo)" will match 'y=FOO'. +- "(|(x=33)(y=foo))" will be satisfied, even though "(x=33)" cannot be +- satisfied, because of the `|' (boolean disjunction). +- +- Wildcard matching MUST be done with the '=' filter. In any other +- case, a PARSE_ERROR is returned. Request terms which include +- wildcards are interpreted to be Strings. That is, (x=34*) would +- match 'x=34foo', but not 'x=3432' since the first value is a String +- while the second value is an Integer; Strings don't match Integers. +- +- Examples of Predicates follow. indicates the service type of the +- SrvRqst, gives the and

is the predicate string. +- +- =service:http =DEFAULT

= (empty string) +- This is a minimal request string. It matches all http +- services advertised with the default scope. +- +- =service:pop3 =SALES,DEFAULT

=(user=wump) +- This is a request for all pop3 services available in +- the SALES or DEFAULT scope which serve mail to the user +- `wump'. +- +- +- +- +- +-Guttman, et al. Standards Track [Page 20] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +- =service:backup =BLDG 32

=(&(q<=3)(speed>=1000)) +- This returns the backup service which has a queue length +- less than 3 and a speed greater than 1000. It will +- return this only for services registered with the BLDG 32 +- scope. +- +- =service:directory-agent =DEFAULT

= +- This returns DAAdverts for all DAs in the DEFAULT scope. +- +- DAs are discovered by sending a SrvRqst with the service type set to +- "service:directory-agent". If a predicate is included in the +- SrvRqst, the DA SHOULD respond only if the predicate can be satisfied +- with the DA's attributes. The MUST contain all scopes +- configured for the UA or SA which is discovering DAs. +- +- The string indicates a SLP SPI that the requester has been +- configured with. If this string is omitted, the responder does not +- include any Authentication Blocks in its reply. If it is included, +- the responder MUST return a reply which has an associated +- authentication block with the SLP SPI in the SrvRqst. If no replies +- may be returned because the SLP SPI is not supported, the responder +- returns an AUTHENTICATION_UNKNOWN error. +- +-8.2. Service Reply +- +- 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 +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | Service Location header (function = SrvRply = 2) | +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | Error Code | URL Entry count | +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | ... \ +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- +- The service reply contains zero or more URL entries (see Section +- 4.3). A service reply with zero URL entries MUST be returned in +- response to a unicast Service Request, if no matching URLs are +- present. A service reply with zero URL entries MUST NOT be sent in +- response to a multicast or broadcast service request (instead, if +- there was no match found or an error processing the request, the +- service reply should not be generated at all). +- +- If the reply overflows, the UA MAY simply use the first URL Entry in +- the list. A URL obtained by SLP may not be cached longer than +- Lifetime seconds, unless there is a URL Authenticator block present. +- +- +- +- +- +-Guttman, et al. Standards Track [Page 21] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +- In that case, the cache lifetime is indicated by the Timestamp in the +- URL Authenticator (see Section 9.2). +- +- An authentication block is returned in the URL Entries, including the +- SLP SPI in the SrvRqst. If no SLP SPI was included in the request, +- no Authentication Blocks are returned in the reply. URL +- Authentication Blocks are defined in Section 9.2.1. +- +- If a SrvRply is sent by UDP, a URL Entry MUST NOT be included unless +- it fits entirely without truncation. +- +-8.3. Service Registration +- +- 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 +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | Service Location header (function = SrvReg = 3) | +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | \ +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | length of service type string | \ +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | length of | \ +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | length of attr-list string | \ +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- |# of AttrAuths |(if present) Attribute Authentication Blocks...\ +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- +- The is a URL Entry (see section 4.3). The Lifetime defines +- how long a DA can cache the registration. SAs SHOULD reregister +- before this lifetime expires (but SHOULD NOT more often than once per +- second). The Lifetime MAY be set to any value between 0 and 0xffff +- (maximum, around 18 hours). Long-lived registrations remain stale +- longer if the service fails and the SA does not deregister the +- service. +- +- The defines the service type of the URL to be +- registered, regardless of the scheme of the URL. The +- MUST contain the names of all scopes configured for the SA, which the +- DA it is registering with supports. The default value for the +- is "DEFAULT" (see Section 11). +- +- The SA MUST register consistently with all DAs. If a SA is +- configured with scopes X and Y and there are three DAs, whose scopes +- are "X", "Y" and "X,Y" respectively, the SA will register the with +- all three DAs in their respective scopes. All future updates and +- deregistrations of the service must be sent to the same set of DAs in +- +- +- +-Guttman, et al. Standards Track [Page 22] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +- the same scopes the service was initially registered in. +- +- The , if present, specifies the attributes and values to +- be associated with the URL by the DA (see Section 5). +- +- A SA configured with the ability to sign service registrations MUST +- sign each of the URLs and Attribute Lists using each of the keys it +- is configured to use, and the DA it is registering with accepts. +- (The SA MUST acquire DAAdverts for all DAs it will register with to +- obtain the DA's SLP SPI list and attributes, as described in Section +- 8.5). The SA supplies a SLP SPI in each authentication block +- indicating the SLP SPI configuration required to verify the digital +- signature. The format of the digital signatures used is defined in +- section 9.2.1. +- +- Subsequent registrations of previously registered services MUST +- contain the same list of SLP SPIs as previous ones or else DAs will +- reject them, replying with an AUTHENTICATION_ABSENT error. +- +- A registration with the FRESH flag set will replace *entirely* any +- previous registration for the same URL in the same language. If the +- FRESH flag is not set, the registration is an "incremental" +- registration (see Section 9.3). +- +-8.4. Service Acknowledgment +- +- 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 +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | Service Location header (function = SrvAck = 5) | +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | Error Code | +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- +- A DA returns a SrvAck to an SA after a SrvReg. It carries only a two +- byte Error Code (see Section 7). +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-Guttman, et al. Standards Track [Page 23] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +-8.5. Directory Agent Advertisement +- +- 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 +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | Service Location header (function = DAAdvert = 8) | +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | Error Code | DA Stateless Boot Timestamp | +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- |DA Stateless Boot Time,, contd.| Length of URL | +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- \ URL \ +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | Length of | \ +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | Length of | \ +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | Length of | String \ +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | # Auth Blocks | Authentication block (if any) \ +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- +- The Error Code is set to 0 when the DAAdvert is multicast. If the +- DAAdvert is being returned due to a unicast SrvRqst (ie. a request +- without the REQUEST MCAST flag set) the DA returns the same errors a +- SrvRply would. +- +- The of the SrvRqst must either be omitted or include a +- scope which the DA supports. The DA Stateless Boot Timestamp +- indicates the state of the DA (see section 12.1). +- +- The DA MAY include a list of its attributes in the DAAdvert. This +- list SHOULD be kept short, as the DAAdvert must fit into a datagram +- in order to be multicast. +- +- A potential scaling problem occurs in SLPv2 if SAs choose too low a +- Lifetime. In this case, an onerous amount of reregistration occurs +- as more services are deployed. SLPv2 allows DAs to control SAs +- frequency of registration. A DA MAY reissue a DAAdvert with a new +- set of attributes at any time, to change the reregistration behavior +- of SAs. These apply only to subsequent registrations; existing +- service registrations with the DA retain their registered lifetimes. +- +- If the DAAdvert includes the attribute "min-refresh-interval" it MUST +- be set to a single Integer value indicating a number of seconds. If +- this attribute is present SAs MUST NOT refresh any particular service +- advertisement more frequently than this value. If SrvReg with the +- FRESH FLAG not set or SrvDereg with a non-empty tag list updating a +- +- +- +-Guttman, et al. Standards Track [Page 24] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +- particular service are received more often than the value for the +- DA's advertised "min-refresh-interval" attribute the DA SHOULD reject +- the message and return a REFRESH_REJECTED error in the SrvAck. +- +- The URL is "service:directory-agent://" of the DA, where +- is the dotted decimal numeric address of the DA. The of +- the DA MUST NOT be NULL. +- +- The SLP SPI List is the list of SPIs that the DA is capable of +- verifying. SAs MUST NOT register services with authentication blocks +- for those SLP SPIs which are not on the list. DAs will reject +- service registrations which they cannot verify, returning an +- AUTHENTICATION_UNKNOWN error. +- +- The format of DAAdvert signatures is defined in Section 9.2.1. +- +- The SLP SPI which is used to verify the DAAdvert is included in the +- Authentication Block. When DAAdverts are multicast, they may have to +- transmit multiple DAAdvert Authentication Blocks. If the DA is +- configured to be able to generate signatures for more than one SPI, +- the DA MUST include one Authentication Block for each SPI. If all +- these Authentication Blocks do not fit in a single datagram (to +- multicast or broadcast) the DA MUST send separate DAAdverts so that +- Authentication Blocks for all the SPIs the DA is capable of +- generating are sent. +- +- If the DAAdvert is being sent in response to a SrvRqst, the DAAdvert +- contains only the authentication block with the SLP SPI in the +- SrvRqst, if the DA is configured to be able to produce digital +- signatures using that SLP SPI. If the SrvRqst is unicast to the DA +- (the REQUEST MCAST flag in the header is not set) and an unsupported +- SLP SPI is included, the DA replies with a DAAdvert with the Error +- Code set to an AUTHENTICATION_UNKNOWN error. +- +- UAs SHOULD be configured with SLP SPIs that will allow them to verify +- DA Advertisements. If the UA is configured with SLP SPIs and +- receives a DAAdvert which fails to be verified using one of them, the +- UA MUST discard it. +- +-8.6. Service Agent Advertisement +- +- User Agents MUST NOT solicit SA Advertisements if they have been +- configured to use a particular DA, if they have been configured with +- a or if DAs have been discovered. UAs solicit SA +- Advertisements only when they are explicitly configured to use User +- Selectable scopes (see Section 11.2) in order to discover the scopes +- that SAs support. This allows UAs without scope configuration to +- make use of either DAs or SAs without any functional difference +- +- +- +-Guttman, et al. Standards Track [Page 25] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +- except performance. +- +- A SA MAY be configured with attributes, and SHOULD support the +- attribute 'service-type' whose value is all the service types of +- services represented by the SA. SAs MUST NOT respond if the SrvRqst +- predicate is not satisfied. For example, only SAs offering 'nfs' +- services SHOULD respond with a SAAdvert to a SrvRqst for service type +- "service:service-agent" which includes a predicate "(service- +- type=nfs)". +- +- 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 +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | Service Location header (function = SAAdvert = 11) | +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | Length of URL | URL \ +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | Length of | \ +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | Length of | \ +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | # auth blocks | authentication block (if any) \ +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- +- The SA responds only to multicast SA discovery requests which either +- include no or a scope which they are configured to use. +- +- The SAAdvert MAY include a list of attributes the SA supports. This +- attribute list SHOULD be kept short so that the SAAdvert will not +- exceed the path MTU in size. +- +- The URL is "service:service-agent://" of the SA, where +- is the dotted decimal numeric address of the SA. The of +- the SA MUST NOT be null. +- +- The SAAdvert contains one SAAdvert Authentication block for each SLP +- SPI the SA can produce Authentication Blocks for. If the UA can +- verify the Authentication Block of the SAAdvert, and the SAAdvert +- fails to be verified, the UA MUST discard it. +- +-9. Optional Features +- +- The features described in this section are not mandatory. Some are +- useful for interactive use of SLP (where a user rather than a program +- will select services, using a browsing interface for example) and for +- scalability of SLP to larger networks. +- +- +- +- +- +-Guttman, et al. Standards Track [Page 26] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +-9.1. Service Location Protocol Extensions +- +- The format of a Service Location Extension is: +- +- 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 +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | Extension ID | Next Extension Offset | +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | Offset, contd.| Extension Data \ +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- +- Extension IDs are assigned in the following way: +- +- 0x0000-0x3FFF Standardized. Optional to implement. Ignore if +- unrecognized. +- 0x4000-0x7FFF Standardized. Mandatory to implement. A UA or SA +- which receives this option in a reply and does not understand +- it MUST silently discard the reply. A DA or SA which receives +- this option in a request and does not understand it MUST return +- an OPTION_NOT_UNDERSTOOD error. +- 0x8000-0x8FFF For private use (not standardized). Optional to +- implement. Ignore if unrecognized. +- 0x9000-0xFFFF Reserved. +- +- The three byte offset to next extension indicates the position of the +- next extension as offset from the beginning of the SLP message. +- +- The offset value is 0 if there are no extensions following the +- current extension. +- +- If the offset is 0, the length of the current Extension Data is +- determined by subtracting total length of the SLP message as given in +- the SLP message header minus the offset of the current extension. +- +- Extensions defined in this document are in Section D. See section 15 +- for procedures that are required when specifying new SLP extensions. +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-Guttman, et al. Standards Track [Page 27] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +-9.2. Authentication Blocks +- +- 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 +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | Block Structure Descriptor | Authentication Block Length | +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | Timestamp | +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | SLP SPI String Length | SLP SPI String \ +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | Structured Authentication Block ... \ +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- +- Authentication blocks are returned with certain SLP messages to +- verify that the contents have not been modified, and have been +- transmitted by an authorized agent. The authentication data +- (contained in the Structured Authentication Block) is typically case +- sensitive. Even though SLP registration data (e.g., attribute +- values) are typically are not case sensitive, the case of the +- registration data has to be preserved by the registering DA so that +- UAs will be able to verify the data used for calculating digital +- signature data. +- +- The Block Structure Descriptor (BSD) identifies the format of the +- Authenticator which follows. BSDs 0x0000-0x7FFF will be maintained +- by IANA. BSDs 0x8000-0x8FFF are for private use. +- +- The Authentication Block Length is the length of the entire block, +- starting with the BSD. +- +- The Timestamp is the time that the authenticator expires (to prevent +- replay attacks.) The Timestamp is a 32-bit unsigned fixed-point +- number of seconds relative to 0h on 1 January 1970. SAs use this +- value to indicate when the validity of the digital signature expires. +- This Timestamp will wrap back to 0 in the year 2106. Once the value +- of the Timestamp wraps, the time at which the Timestamp is relative +- to resets. For example, after 06h28 and 16 seconds 5 February 2106, +- all Timestamp values will be relative to that epoch date. +- +- The SLP Security Parameters Index (SPI) string identifies the key +- length, algorithm parameters and keying material to be used by agents +- to verify the signature data in the Structured Authentication Block. +- The SLP SPI string has the same grammar as the defined in +- Section 6.4.1. +- +- Reserved characters in SLP SPI strings must be escaped using the same +- convention as used throughout SLPv2. +- +- +- +-Guttman, et al. Standards Track [Page 28] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +- SLP SPIs deployed in a site MUST be unique. An SLP SPI used for +- BSD=0x0002 must not be the same as used for some other BSD. +- +- All SLP agents MUST implement DSA [20] (BSD=0x0002). SAs MUST +- register services with DSA authentication blocks, and they MAY +- register them with other authentication blocks using other +- algorithms. SAs MUST use DSA authentication blocks in SrvDeReg +- messages and DAs MUST use DSA authentication blocks in unsolicited +- DAAdverts. +- +-9.2.1. SLP Message Authentication Rules +- +- The sections below define how to calculate the value to apply to the +- algorithm identified by the BSD value. The components listed are +- used as if they were a contiguous single byte aligned buffer in the +- order given. +- +- URL +- 16-bit Length of SLP SPI String, SLP SPI String. +- 16-bit Length of URL, URL, +- 32-bit Timestamp. +- +- Attribute List +- 16-bit Length of SLP SPI String, SLP SPI String, +- 16-bit length of , , +- 32-bit Timestamp. +- +- DAAdvert +- 16-bit Length of SLP SPI String, SLP SPI String, +- 32-bit DA Stateless Boot Timestamp, +- 16-bit Length of URL, URL, +- 16-bit Length of , , +- 16-bit Length of DA's , DA's , +- 16-bit Length of DA's , DA's , +- 32-bit Timestamp. +- +- The first SLP SPI is the SLP SPI in the Authentication +- Block. This SLP SPI indicates the keying material and other +- parameters to use to verify the DAAdvert. The SLP SPI List is +- the list of SLP SPIs the DA itself supports, and is able to +- verify. +- +- SAAdvert +- 16-bit Length of SLP SPI String, SLP SPI String, +- 16-bit Length of URL, URL, +- 16-bit Length of , , +- 16-bit Length of , , +- 32-bit Timestamp. +- +- +- +-Guttman, et al. Standards Track [Page 29] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +-9.2.2 DSA with SHA-1 in Authentication Blocks +- +- BSD=0x0002 is defined to be DSA with SHA-1. The signature +- calculation is defined by [20]. The signature format conforms to +- that in the X.509 v3 certificate: +- +- 1. The signature algorithm identifier (an OID) +- 2. The signature value (an octet string) +- 3. The certificate path. +- +- All data is represented in ASN.1 encoding: +- +- id-dsa-with-sha1 ID ::= { +- iso(1) member-body(2) us(840) x9-57 (10040) +- x9cm(4) 3 } +- +- i.e., the ASN.1 encoding of 1.2.840.10040.4.3 followed immediately +- by: +- +- Dss-Sig-Value ::= SEQUENCE { +- r INTEGER, +- s INTEGER } +- +- i.e., the binary ASN.1 encoding of r and s computed using DSA and +- SHA-1. This is followed by a certificate path, as defined by X.509 +- [10], [2], [3], [4], [5]. +- +- Authentication Blocks for BSD=0x0002 have the following format. In +- the future, BSDs may be assigned which have different formats. +- +- 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 +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | ASN.1 encoded DSA signature \ +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- +-9.3. Incremental Service Registration +- +- Incremental registrations update attribute values for a previously +- registered service. Incremental service registrations are useful +- when only a single attribute has changed, for instance. In an +- incremental registration, the FRESH flag in the SrvReg header is NOT +- set. +- +- The new registration's attributes replace the previous +- registration's, but do not affect attributes which were included +- previously and are not present in the update. +- +- +- +- +-Guttman, et al. Standards Track [Page 30] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +- For example, suppose service:x://a.org has been registered with +- attributes A=1, B=2, C=3. If an incremental registration comes for +- service:x://a.org with attributes C=30, D=40, then the attributes for +- the service after the update are A=1, B=2, C=30, D=40. +- +- Incremental registrations MUST NOT be performed for services +- registered with Authentication Blocks. These must be registered with +- ALL attributes, with the FRESH flag in the SrvReg header set. DAs +- which receive such registration messages return an +- AUTHENTICATION_FAILED error. +- +- If the FRESH flag is not set and the DA does not have a prior +- registration for the service, the incremental registration fails with +- error code INVALID_UPDATE. +- +- The SA MUST use the same in an update message as was +- used in the prior registration. If this is not done, the DA returns +- a SCOPE_NOT_SUPPORTED error. In order to change the scope of a +- service advertisement it MUST be deregistered first and reregistered +- with a new . +- +- The SA MUST use the same in an update message as was +- used in a prior registration of the same URL. If this is not done, +- the DA returns an INVALID_UPDATE error. +- +-9.4. Tag Lists +- +- Tag lists are used in SrvDeReg and AttrReq messages. The syntax of a +- item is: +- +- tag-filter = simple-tag / substring +- simple-tag = 1*filt-char +- substring = [initial] any [final] +- initial = 1*filt-char +- any = `*' *(filt-char `*') +- final = 1*filt-char +- filt-char = Any character excluding and (see +- grammar in Section 5). +- +- Wild card characters in a item match arbitrary sequences +- of characters. For instance "*bob*" matches "some bob I know", +- "bigbob", "bobby" and "bob". +- +- +- +- +- +- +- +- +- +-Guttman, et al. Standards Track [Page 31] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +-10. Optional SLP Messages +- +- The additional requests provide features for user interaction and for +- efficient updating of service advertisements with dynamic attributes. +- +-10.1. Service Type Request +- +- The Service Type Request (SrvTypeRqst) allows a UA to discover all +- types of service on a network. This is useful for general purpose +- service browsers. +- +- 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 +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | Service Location header (function = SrvTypeRqst = 9) | +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | length of PRList | String \ +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | length of Naming Authority | \ +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | length of | String \ +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- +- The list and are interpreted as in Section 8.1. +- +- The Naming Authority string, if present in the request, will limit +- the reply to Service Type strings with the specified Naming +- Authority. If the Naming Authority string is absent, the IANA +- registered service types will be returned. If the length of the +- Naming Authority is set to 0xFFFF, the Naming Authority string is +- omitted and ALL Service Types are returned, regardless of Naming +- Authority. +- +-10.2. Service Type Reply +- +- 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 +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | Service Location header (function = SrvTypeRply = 10) | +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | Error Code | length of | +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | \ +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- +- The service-type Strings (as described in Section 4.1) are provided +- in , which is a . +- +- +- +- +-Guttman, et al. Standards Track [Page 32] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +- If a service type has a Naming Authority other than IANA it MUST be +- returned following the service type string and a `.' character. +- Service types with the IANA Naming Authority do not include a Naming +- Authority string. +- +-10.3. Attribute Request +- +- The Attribute Request (AttrRqst) allows a UA to discover attributes +- of a given service (by supplying its URL) or for an entire service +- type. The latter feature allows the UA to construct a query for an +- available service by selecting desired features. The UA may request +- that all attributes are returned, or only a subset of them. +- +- 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 +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | Service Location header (function = AttrRqst = 6) | +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | length of PRList | String \ +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | length of URL | URL \ +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | length of | string \ +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | length of string | string \ +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | length of string | string \ +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- +- The , and string are interpreted as in +- Section 8.1. +- +- The URL field can take two forms. It can simply be a Service Type +- (see Section 4.1), such as "http" or "service:tftp". In this case, +- all attributes and the full range of values for each attribute of all +- services of the given Service Type is returned. +- +- The URL field may alternatively be a full URL, such as +- "service:printer:lpr://igore.wco.ftp.com:515/draft" or +- "nfs://max.net/znoo". In this, only the registered attributes for +- the specified URL are returned. +- +- The field is a of attribute tags, as defined +- in Section 9.4 which indicates the attributes to return in the +- AttrRply. If is omitted, all attributes are returned. +- MUST be omitted and a full URL MUST be included when +- attributes when a SLP SPI List string is included, otherwise the DA +- will reply with an AUTHENTICATION_FAILED error. +- +- +- +-Guttman, et al. Standards Track [Page 33] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +-10.4. Attribute Reply +- +- 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 +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | Service Location header (function = AttrRply = 7) | +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | Error Code | length of | +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | \ +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- |# of AttrAuths | Attribute Authentication Block (if present) \ +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- +- The format of the and the Authentication Block is as +- specified for SrvReg (see Section 9.2.1). +- +- Attribute replies SHOULD be returned with the original case of the +- string registration intact, as they are likely to be human readable. +- In the case where the AttrRqst was by service type, all attributes +- defined for the service type, and all their values are returned. +- +- Although white space is folded for string matching, attribute tags +- and values MUST be returned with their original white space +- preserved. +- +- Only one copy of each attribute tag or String value should be +- returned, arbitrarily choosing one version (with respect to upper and +- lower case and white space internal to the strings): Duplicate +- attributes and values SHOULD be removed. An arbitrary version of the +- string value and tag name is chosen for the merge. For example: +- "(A=a a,b)" merged with "(a=A A,B)" may yield "(a=a a,B)". +- +-10.5. Attribute Request/Reply Examples +- +- Suppose that printer services have been registered as follows: +- +- Registered Service: +- URL = service:printer:lpr://igore.wco.ftp.com/draft +- scope-list = Development +- Lang. Tag = en +- Attributes = (Name=Igore),(Description=For developers only), +- (Protocol=LPR),(location-description=12th floor), +- (Operator=James Dornan \3cdornan@monster\3e), +- (media-size=na-letter),(resolution=res-600),x-OK +- +- URL = service:printer:lpr://igore.wco.ftp.com/draft +- scope-list = Development +- +- +- +-Guttman, et al. Standards Track [Page 34] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +- Lang. Tag = de +- Attributes = (Name=Igore),(Description=Nur fuer Entwickler), +- (Protocol=LPR),(location-description=13te Etage), +- (Operator=James Dornan \3cdornan@monster\3e), +- (media-size=na-letter),(resolution=res-600),x-OK +- +- URL = service:printer:http://not.wco.ftp.com/cgi-bin/pub-prn +- scope-list = Development +- Lang. Tag = en +- Attributes = (Name=Not),(Description=Experimental IPP printer), +- (Protocol=http),(location-description=QA bench), +- (media-size=na-letter),(resolution=other),x-BUSY +- +- Notice the first printer, "Igore" is registered in both English and +- German. The `<' and `>' characters in the Operator attribute value +- which are part of the Email address had to be escaped, as they are +- reserved characters for values. +- +- Attribute tags are not translated, though attribute values may be, +- see [13]. +- +- The attribute Request: +- +- URL = service:printer:lpr://igore.wco.ftp.com/draft +- scope-list = Development +- Lang. Tag = de +- tag-list = resolution,loc* +- +- receives the Attribute Reply: +- +- (location-description=13te Etage),(resolution=res-600) +- +- The attribute Request: +- +- URL = service:printer +- scope-list = Development +- Lang. Tag = en +- tag-list = x-*,resolution,protocol +- +- receives an Attribute Reply containing: +- +- (protocols=http,LPR),(resolution=res-600,other),x-OK,x-BUSY +- +- The first request is by service instance and returns the requested +- values, in German. The second request is by abstract service type +- (see Section 4) and returns values from both "Igore" and "Not". +- +- +- +- +- +-Guttman, et al. Standards Track [Page 35] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +- An attribute Authentication Block is returned if an authentication +- block with the SLP SPI in the AttrRqst can be returned. Note that +- the returned from a DA with an Authentication Block MUST +- be identical to the registered by a SA, in order for the +- authentication verification calculations to be possible. +- +- A SA or DA only returns an Attribute Authentication Block if the +- AttrRqst included a full URL in the request and no tag list. +- +- If an SLP SPI is specified in a unicast request (the REQUEST MCAST +- flag in the header is not set) and the SA or DA cannot return an +- Authentication Block with that SLP SPI, an AUTHENTICATION_UNKNOWN +- error is returned. The # of Attr Auths field is set to 0 if there no +- Authentication Block is included, or 1 if an Authentication Block +- follows. +- +-10.6. Service Deregistration +- +- A DA deletes a service registration when its Lifetime expires. +- Services SHOULD be deregistered when they are no longer available, +- rather than leaving the registrations to time out. +- +- 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 +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | Service Location header (function = SrvDeReg = 4) | +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | Length of | \ +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | URL Entry \ +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | Length of | \ +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- +- The is a (see section 2.1). +- +- The SA MUST retry if there is no response from the DA, see Section +- 12.3. The DA acknowledges a SrvDeReg with a SrvAck. Once the SA +- receives an acknowledgment indicating success, the service and/or +- attributes are no longer advertised by the DA. The DA deregisters the +- service or service attributes from every scope specified in the +- SrvDeReg which it was previously registered in. +- +- The SA MUST deregister all services with the same scope list used to +- register the service with a DA. If this is not done in the SrvDeReg +- message, the DA returns a SCOPE_NOT_SUPPORTED error. The Lifetime +- field in the URL Entry is ignored for the purposes of the SrvDeReg. +- +- +- +- +-Guttman, et al. Standards Track [Page 36] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +- The is a of attribute tags to deregister as +- defined in Section 9.4. If no is present, the SrvDeReg +- deregisters the service in all languages it has been registered in. +- If the is present, the SrvDeReg deregisters the attributes +- whose tags are listed in the tag spec. Services registered with +- Authentication Blocks MUST NOT include a in a SrvDeReg +- message: A DA will respond with an AUTHENTICATION_FAILED error in +- this case. +- +- If the service to be deregistered was registered with an +- authentication block or blocks, a URL authentication block for each +- of the SLP SPIs registered must be included in the SrvDeReg. +- Otherwise, the DA returns an AUTHENTICATION_ABSENT error. If the +- message fails to be verified by the DA, an AUTHENTICATION_FAILED +- error is returned by the DA. +- +-11. Scopes +- +- Scopes are sets of services. The primary use of Scopes is to provide +- the ability to create administrative groupings of services. A set of +- services may be assigned a scope by network administrators. A client +- seeking services is configured to use one or more scopes. The user +- will only discover those services which have been configured for him +- or her to use. By configuring UAs and SAs with scopes, +- administrators may provision services. Scopes strings are case +- insensitive. The default SCOPE string is "DEFAULT". +- +- Scopes are the primary means an administrator has to scale SLP +- deployments to larger networks. When DAs with NON-DEFAULT scopes are +- present on the network, further gains can be had by configuring UAs +- and SAs to have a predefined non-default scope. These agents can +- then perform DA discovery and make requests using their scope. This +- will limit the number of replies. +- +-11.1. Scope Rules +- +- SLP messages which fail to contain a scope that the receiving Agent +- is configured to use are dropped (if the request was multicast) or a +- SCOPE_NOT_SUPPORTED error is returned (if the request was unicast). +- Every SrvRqst (except for DA and SA discovery requests), SrvReg, +- AttrRqst, SrvTypeRqst, DAAdvert, and SAAdvert message MUST include a +- . +- +- A UA MUST unicast its SLP messages to a DA which supports the desired +- scope, in preference to multicasting a request to SAs. A UA MAY +- multicast the request if no DA is available in the scope it is +- configured to use. +- +- +- +- +-Guttman, et al. Standards Track [Page 37] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +-11.2. Administrative and User Selectable Scopes +- +- All requests and services are scoped. The two exceptions are +- SrvRqsts for "service:directory-agent" and "service:service-agent". +- These MAY have a zero-length when used to enable the +- user to make scope selections. In this case UAs obtain their scope +- list from DAAdverts (or if DAs are not available, from SAAdverts.) +- +- Otherwise, if SAs and UAs are to use any scope other than the default +- (i.e., "DEFAULT"), the UAs and SAs are configured with lists of +- scopes to use by system administrators, perhaps automatically by way +- of DHCP option 78 or 79 [21]. Such administrative scoping allows +- services to be provisioned, so that users will only see services they +- are intended to see. +- +- User configurable scopes allow a user to discover any service, but +- require them to do their own selection of scope. This is similar to +- the way AppleTalk [12] and SMB [19] networking allow user selection +- of AppleTalk Zone or workgroups. +- +- Note that the two configuration choices are not compatible. One +- model allows administrators control over service provision. The +- other delegates this to users (who may not be prepared to do any +- configuration of their system). +- +-12. Directory Agents +- +- DAs cache service location and attribute information. They exist to +- enhance the performance and scalability of SLP. Multiple DAs provide +- further scalability and robustness of operation, since they can each +- store service information for the same SAs, in case one of the DAs +- fails. +- +- A DA provides a centralized store for service information. This is +- useful in a network with several subnets or with many SLP Agents. +- The DA address can be dynamically configured with UAs and SAs using +- DHCP, or by using static configuration. +- +- SAs configured to use DAs with DHCP or static configuration MUST +- unicast a SrvRqst to the DA, when the SA is initialized. The SrvRqst +- omits the scope list and sets the service type of the request to +- "service:directory-agent". The DA will return a DAAdvert with its +- attributes, SLP SPI list, and other parameters which are essential +- for proper SA to DA communication. +- +- Passive detection of DAs by SAs enables services to be advertised +- consistently among DAs of the same scope. Advertisements expire if +- not renewed, leaving only transient stale registrations in DAs, even +- +- +- +-Guttman, et al. Standards Track [Page 38] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +- in the case of a failure of a SA. +- +- A single DA can support many UAs. UAs send the same requests to DAs +- that they would send to SAs and expect the same results. DAs reduce +- the load on SAs, making simpler implementations of SAs possible. +- +- UAs MUST be prepared for the possibility that the service information +- they obtain from DAs is stale. +- +-12.1. Directory Agent Rules +- +- When DAs are present, each SA MUST register its services with DAs +- that support one or more of its scope(s). +- +- UAs MUST unicast requests directly to a DA (when scoping rules +- allow), hence avoiding using the multicast convergence algorithm, to +- obtain service information. This decreases network utilization and +- increases the speed at which UAs can obtain service information. +- +- DAs MUST flush service advertisements once their lifetime expires or +- their URL Authentication Block "Timestamp" of expiration is past. +- +- DAAdverts MUST include DA Stateless Boot Timestamp, in the same +- format as the Authentication Block (see Section 9.2). The Timestamp +- in the Authentication Block indicates the time at which all previous +- registrations were lost (i.e., the last stateless reboot). The +- Timestamp is set to 0 in a DAAdvert to notify UAs and SAs that the DA +- is going down. DAs MUST NOT use equal or lesser Boot Timestamps to +- previous ones, if they go down and restart without service +- registration state. This would mislead SAs to not reregister with +- the DA. +- +- DAs which receive a multicast SrvRqst for the service type +- "service:directory-agent" MUST silently discard it if the is (a) not omitted and (b) does not include a scope they are +- configured to use. Otherwise the DA MUST respond with a DAAdvert. +- +- DAs MUST respond to AttrRqst and SrvTypeRqst messages (these are +- OPTIONAL only for SAs, not DAs.) +- +-12.2. Directory Agent Discovery +- +- UAs can discover DAs using static configuration, DHCP options 78 and +- 79, or by multicasting (or broadcasting) Service Requests using the +- convergence algorithm in Section 6.3. +- +- +- +- +- +- +-Guttman, et al. Standards Track [Page 39] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +- See Section 6 regarding unsolicited DAAdverts. Section 12.2.2 +- describes how SAs may reduce the number of times they must reregister +- with DAs in response to unsolicited DAAdverts. +- +- DAs MUST send unsolicited DAAdverts once per CONFIG_DA_BEAT. An +- unsolicited DAAdvert has an XID of 0. SAs MUST listen for DAAdverts, +- passively, as described in Section 8.5. UAs MAY do this. If they do +- not listen for unsolicited DAAdverts, however, they will not discover +- DAs as they become available. UAs SHOULD, in this case, do periodic +- active DA discovery, see Section 6. +- +- A URL with the scheme "service:directory-agent" indicates the DA's +- location as defined in Section 8.5. For example: +- "service:directory-agent://foobawooba.org". +- +- The following sections suggest timing algorithms which enhance the +- scalability of SLP. +- +-12.2.1. Active DA Discovery +- +- After a UA or SA restarts, its initial DA discovery request SHOULD be +- delayed for some random time uniformly distributed from 0 to +- CONFIG_START_WAIT seconds. +- +- The UA or SA sends the DA Discovery request using a SrvRqst, as +- described in Section 8.1. DA Discovery requests MUST include a +- Previous Responder List. SrvRqsts for Active DA Discovery SHOULD NOT +- be sent more than once per CONFIG_DA_FIND seconds. +- +- After discovering a new DA, a SA MUST wait a random time between 0 +- and CONFIG_REG_ACTIVE seconds before registering their services. +- +-12.2.2. Passive DA Advertising +- +- A DA MUST multicast (or broadcast) an unsolicited DAAdvert every +- CONFIG_DA_BEAT seconds. CONFIG_DA_BEAT SHOULD be specified to +- prevent DAAdverts from using more than 1% of the available bandwidth. +- +- All UAs and SAs which receive the unsolicited DAAdvert SHOULD examine +- its DA stateless Boot Timestamp. If it is set to 0, the DA is going +- down and no further messages should be sent to it. +- +- If a SA detects a DA it has never encountered (with a nonzero +- timestamp,) the SA must register with it. SAs MUST examine the +- DAAdvert's timestamp to determine if the DA has had a stateless +- reboot since the SA last registered with it. If so it registers with +- the DA. SAs MUST wait a random interval between 0 and +- CONFIG_REG_PASSIVE before beginning DA registration. +- +- +- +-Guttman, et al. Standards Track [Page 40] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +-12.3. Reliable Unicast to DAs and SAs +- +- If a DA or SA fails to respond to a unicast UDP message in +- CONFIG_RETRY seconds, the message should be retried. The wait +- interval for each subsequent retransmission MUST exponentially +- increase, doubling each time. If a DA or SA fails to respond after +- CONFIG_RETRY_MAX seconds, the sender should consider the receiver to +- have gone down. The UA should use a different DA. If no such DA +- responds, DA discovery should be used to find a new DA. If no DA is +- available, multicast requests to SAs are used. +- +-12.4. DA Scope Configuration +- +- By default, DAs are configured with the "DEFAULT" scope. +- Administrators may add other configured scopes, in order to support +- UAs and SAs in non default scopes. The default configuration MUST +- NOT be removed from the DA unless: +- +- - There are other DAs which support the "DEFAULT" scope, or +- +- - All UAs and SAs have been configured with non-default scopes. +- +- Non-default scopes can be phased-in as the SLP deployment grows. +- Default scopes should be phased out only when the non-default scopes +- are universally configured. +- +- If a DA and SA are coresident on a host (quite possibly implemented +- by the same process), configuration of the host is considerably +- simplified if the SA supports only scopes also supported by the DA. +- That is, the SA SHOULD NOT advertise services in any scopes which are +- not supported by the coresident DA. This means that incoming requests +- can be answered by a single data store; the SA and DA registrations +- do not need to be kept separately. +- +-12.5. DAs and Authentication Blocks +- +- DAs are not configured to sign service registrations or attribute +- lists. They simply cache services registered by Service Agents. DAs +- MUST NOT accept registrations including authentication blocks for SLP +- SPIs which it is not configured with, see Section 8.5. +- +- A DA protects registrations which are made with authentication blocks +- using SLP SPIs it is configured to use. If a service S is +- registered, a subsequent registration (which will replace the +- adertisement) or a deregistration (which will remove it) MUST include +- an Authentication Block with the corresponding SLP SPI, see Section +- 8.3 and Section 10.6. +- +- +- +- +-Guttman, et al. Standards Track [Page 41] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +- Example: +- +- A DA is configured to be able to verify Authentication Blocks with +- SLP SPIs "X,Y", that is X and Y. +- +- An SA registers a service with an Authentication Block with SPI "Z". +- The DA stores the registration, but discards the Authentication +- Block. If a UA requests a service with an SLP SPI string "Z", the DA +- will respond with an AUTHENTICATION_UNKNOWN error. +- +- An SA registers a service S with Authentication Blocks including SLP +- SPIs "X" and "Y". If a UA requests a service with an SLP SPI string +- "X" the DA will be able to return S (if the service type, language, +- scope and predicate of the SrvRqst match S) The DA will also return +- the Authentication Block with SLP SPI set to "X". If the DA receives +- a subsequent SrvDeReg for S (which will remove the advertisement) or +- a subsequent SrvReg for S (which will replace it), the message must +- include two URL Authentication Blocks, one each for SPIs "X" and "Y". +- If either of these were absent, the DA would return an +- AUTHENTICATION_ABSENT error. +- +-13. Protocol Timing Defaults +- +-Interval name Section Default Value Meaning +-------------------- ------- ------------- ------------------------ +-CONFIG_MC_MAX 6.3 15 seconds Max time to wait for a +- complete multicast query +- response (all values.) +-CONFIG_START_WAIT 12.2.1 3 seconds Wait to perform DA +- discovery on reboot. +-CONFIG_RETRY 12.3 2 seconds Wait interval before +- initial retransmission +- of multicast or unicast +- requests. +-CONFIG_RETRY_MAX 12.3 15 seconds Give up on unicast +- request retransmission. +-CONFIG_DA_BEAT 12.2.2 3 hours DA Heartbeat, so that SAs +- passively detect new DAs. +-CONFIG_DA_FIND 12.3 900 seconds Minimum interval to wait +- before repeating Active +- DA discovery. +-CONFIG_REG_PASSIVE 12.2 1-3 seconds Wait to register services +- on passive DA discovery. +-CONFIG_REG_ACTIVE 8.3 1-3 seconds Wait to register services +- on active DA discovery. +-CONFIG_CLOSE_CONN 6.2 5 minutes DAs and SAs close idle +- connections. +- +- +- +- +-Guttman, et al. Standards Track [Page 42] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +-14. Optional Configuration +- +- Broadcast Only +- Any SLP agent SHOULD be configurable to use broadcast +- only. See Sections 6.1 and 12.2. +- +- Predefined DA +- A UA or SA SHOULD be configurable to use a predefined DA. +- +- No DA Discovery +- The UA or SA SHOULD be configurable to ONLY use +- predefined and DHCP-configured DAs and perform no active +- or passive DA discovery. +- +- Multicast TTL +- The default multicast TTL is 255. Agents SHOULD be +- configurable to use other values. A lower value will +- focus the multicast convergence algorithm on smaller +- subnetworks, decreasing the number of responses and +- increases the performance of service location. This +- may result in UAs obtaining different results for the +- identical requests depending on where they are connected +- to the network. +- +- Timing Values +- Time values other than the default MAY be configurable. +- See Section 13. +- +- Scopes +- A UA MAY be configurable to support User Selectable +- scopes by omitting all predefined scopes. See +- Section 11.2. A UA or SA MUST be configurable to use +- specific scopes by default. Additionally, a UA or SA +- MUST be configurable to use specific scopes for requests +- for and registrations of specific service types. The +- scope or scopes of a DA MUST be configurable. The +- default value for a DA is to have the scope "DEFAULT" if +- not otherwise configured. +- +- DHCP Configuration +- DHCP options 78 and 79 may be used to configure SLP. If +- DA locations are configured using DHCP, these SHOULD +- be used in preference to DAs discovered actively or +- passively. One or more of the scopes configured using +- DHCP MUST be used in requests. The entire configured +- MUST be used in registration and DA +- configuration messages. +- +- +- +- +-Guttman, et al. Standards Track [Page 43] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +- Service Template +- UAs and SAs MAY be configured by using Service Templates. +- Besides simplifying the specification of attribute +- values, this also allows them to enforce the inclusion +- of 'required' attributes in SrvRqst, SrvReg and SrvDeReg +- messages. DAs MAY be configured with templates to +- allow them to WARN UAs and SAs in these cases. See +- Section 10.4. +- +- SLP SPI for service discovery +- Agents SHOULD be configurable to support SLP SPIs using +- the following parameters: BSD=2 (DSA with SHA-1) and +- a public key identified by the SLP SPI String. In +- the future, when a Public Key Infrastructure exists, +- SLP Agents may be able to obtain public keys and +- cryptographic parameters corresponding to the names used +- in SLP SPI Strings. +- +- Note that if the SLP SPI string chosen is identical +- to a scope string, it is effectively the same as a +- Protected Scope in SLPv1. Namely, every SA advertising +- in that scope would be configured with the same Private +- Key. Every DA and UA of that scope would be configured +- with the appropriate Public Key to verify signatures +- produced by those SAs. This is a convenient way to +- configure SLP deployments in the absence of a Public Key +- Infrastructure. Currently, it would be too difficult to +- manage the keying of UAs and DAs if each SA had its own +- key. +- +- SLP SPI for Directory Agent discovery +- Agents SHOULD be configurable to support SLP SPIs as +- above, to be used when discovering DAs. This SPI SHOULD +- be sent in SrvRqsts to discover DAs and be used to verify +- multicast DAAdvert messages. +- +- SA and DA Private Key +- SAs and DAs which can generate digital signatures require +- a Private Key and a corresponding SLP SPI indentifier +- to include in the Authentication Block. The SLP SPI +- identifies the Public Key to use to verify the digital +- signature in the Authentication Block. +- +-15. IANA Considerations +- +- SLP includes four sets of identifiers which may be registered with +- IANA. The policies for these registrations (See [18]) are noted in +- each case. +- +- +- +-Guttman, et al. Standards Track [Page 44] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +- The Block Structure Descriptor (BSD) identifies the format of the +- Authenticator which follows. BSDs 0x8000-0x8FFF are for Private Use. +- +- Further Block Structured Descriptor (BSD) values, from the range +- 0x0003-0x7FFF may be standardized in the future by submitting a +- document which describes: +- +- - The data format of the Structured Authenticator block. +- +- - Which cryptographic algorithm to use (including a reference +- to a technical specification of the algorithm.) +- +- - The format of any keying material required for +- preconfiguring UAs, DAs and SAs. Also include any +- considerations regarding key distribution. +- +- - Security considerations to alert others to the strengths and +- weaknesses of the approach. +- +- The IANA will assign Cryptographic BSD numbers on the basis of IETF +- Consenus. +- +- New function-IDs, in the range 12-255, may be standardized by the +- method of IETF Consensus. +- +- New SLP Extensions with types in the range 2-65535 may be registered +- following review by a Designated Expert. +- +- New error numbers in the range 15-65535 are assigned on the basis of +- a Standards Action. +- +- Protocol elements used with Service Location Protocol may also +- require IANA registration actions. SLP is used in conjunction with +- "service:" URLs and Service Templates [13]. These are standardized +- by review of a Designated Expert and a mailing list (See [13].) +- +-16. Internationalization Considerations +- +- SLP messages support the use of multiple languages by providing a +- Language Tag field in the common message header (see Section 8). +- +- Services MAY be registered in multiple languages. This provides +- attributes so that users with different language skills may select +- services interactively. +- +- Attribute tags are not translated. Attribute values may be +- translated unless the Service Template [13] defines the attribute +- values to be 'literal'. +- +- +- +-Guttman, et al. Standards Track [Page 45] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +- A service which is registered in multiple languages may be queried in +- multiple languages. The language of the SrvRqst or AttrRqst is used +- to satisfy the request. If the requested language is not supported, +- a LANGUAGE_NOT_SUPPORTED error is returned. SrvRply and AttrRply +- messages are always in the same language of the request. +- +- A DA or SA MAY be configured with translations of Service Templates +- [13] for the same service type. This will allow the DA or SA to +- translate a request (say in Italian) to the language of the service +- advertisement (say in English) and then translate the reply back to +- Italian. Similarly, a UA MAY use templates to translate outgoing +- requests and incoming replies. +- +- The dialect field in the Language Tag MAY be used: Requests which +- can be fulfilled by matching a language and dialect will be preferred +- to those which match only the language portion. Otherwise, dialects +- have no effect on matching requests. +- +-17. Security Considerations +- +- SLP provides for authentication of service URLs and service +- attributes. This provides UAs and DAs with knowledge of the +- integrity of service URLs and attributes included in SLP messages. +- The only systems which can generate digital signatures are those +- which have been configured by administrators in advance. Agents +- which verify signed data may assume it is 'trustworthy' inasmuch as +- administrators have ensured the cryptographic keying of SAs and DAs +- reflects 'trustworthiness.' +- +- Service Location does not provide confidentiality. Because the +- objective of this protocol is to advertise services to a community of +- users, confidentiality might not generally be needed when this +- protocol is used in non-sensitive environments. Specialized schemes +- might be able to provide confidentiality, if needed in the future. +- Sites requiring confidentiality should implement the IP Encapsulating +- Security Payload (ESP) [3] to provide confidentiality for Service +- Location messages. +- +- If Agents are not configured to generate Authentication Blocks and +- Agents are not configured to verify them, an adversary might easily +- use this protocol to advertise services on servers controlled by the +- adversary and thereby gain access to users' private information. +- Further, an adversary using this protocol will find it much easier to +- engage in selective denial of service attacks. Sites that are in +- potentially hostile environments (e.g., are directly connected to the +- Internet) should consider the advantages of distributing keys +- associated with SLP SPIs prior to deploying the sensitive directory +- agents or service agents. +- +- +- +-Guttman, et al. Standards Track [Page 46] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +- SLP is useful as a bootstrap protocol. It may be used in +- environments in which no preconfiguration is possible. In such +- situations, a certain amount of "blind faith" is required: Without +- any prior configuration it is impossible to use any of the security +- mechanisms described above. SLP will make use of the mechanisms +- provided by the Security Area of the IETF for key distribution as +- they become available. At this point it would only be possible to +- gain the benefits associated with the use of Authentication Blocks if +- cryptographic information and SLP SPIs can be preconfigured with the +- end systems before they use SLP. +- +- SLPv2 enables a number of security policies with the mechanisms it +- includes. A SLPv2 UA could, for instance, reject any SLP message +- which did not carry an authentication block which it could verify. +- This is not the only policy which is possible to implement. +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-Guttman, et al. Standards Track [Page 47] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +-A. Appendix: Changes to the Service Location Protocol from v1 to v2 +- +- SLP version 2 (SLPv2) corrects race conditions present in SLPv1 [22]. +- In addition, authentication has been reworked to provide more +- flexibility and protection (especially for DA Advertisements). SLPv2 +- also changes the formats and definition of many flags and values and +- reduces the number of 'required features.' SLPv2 clarifies and +- changes the use of 'Scopes', eliminating support for 'unscoped +- directory agents' and 'unscoped requests'. SLPv2 uses LDAPv3 +- compatible string encodings of attributes and search filters. Other +- changes (such as Language and Character set handling) adopt practices +- recommended by the Internet Engineering Steering Group. +- +- Effort has been made to make SLPv2 operate the same whether DAs are +- present or not. For this reason, a new message (the SAAdvert) has +- been added. This allows UAs to discover scope information in the +- absence of administrative configuration and DAs. This was not +- possible in SLPv1. +- +- SLPv2 is incompatible in some respects with SLPv1. If a DA which +- supports both SLPv1 and SLPv2 with the same scope is present, +- services advertised by SAs using either version of the protocol will +- be available to both SLPv1 and SLPv2 UAs. SLPv1 DAs SHOULD be phased +- out and replace with SLPv2 DAs which support both versions of the +- protocol. +- +- SLPv1 allows services to be advertised and requested without a scope. +- Further, DAs can be configured without a scope. This is incompatible +- with SLPv2 and presents scalability problems. To facilitate this +- forward migration, SLPv1 agents MUST use scopes for all registrations +- and requests. SLPv1 DAs MUST be configured with a scope list. This +- constitutes a revision of RFC 2165 [22]. +- +-B. Appendix: Service Discovery by Type: Minimal SLPv2 Features +- +- Service Agents may advertise services without attributes. This will +- enable only discovery of services by type. Service types discovered +- this way will have a Service Template [13] defined which specifies +- explicitly that no attributes are associated with the service +- advertisement. Service types associated with Service Templates which +- specify attributes MUST NOT be advertised by SAs which do not support +- attributes. +- +- While discovery of service by service type is a subset of the +- features possible using SLPv2 this form of discovery is consistent +- with the current generation of products that allow simple browsing of +- all services in a 'zone' or 'workgroup' by type. In some cases, +- attribute discovery, security and feature negotiation is handled by +- +- +- +-Guttman, et al. Standards Track [Page 48] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +- application layer protocols - all that is required is the basic +- discovery of services that support a certain service. +- +- UAs requesting only service of that service type would only need to +- support service type and scope fields of the Service Request. UAs +- would still perform DA discovery and unicast SLPv2 SrvRqst messages +- to DAs in their scope once they were discovered instead of +- multicasting them. +- +- SAs would also perform DA discovery and use a SLPv2 SrvReg to +- register all their advertised services with SLPv2 DAs in their scope. +- These advertisements would needless to say contain no attribute +- string. +- +- These minimal SAs could ignore the Language Tag in requests since +- SrvRqst messages would contain no attributes, hence no strings would +- be internationalized. Further, any non-null predicate string would +- fail to match a service advertisement with no attributes, so these +- SAs would not have to parse and interpret search filters. Overflow +- will never occur in SrvRqst, SrvRply or SrvReg messages so TCP +- message handling would not have to be implemented. Finally, all +- AttrRqst messages could be dropped by the SA, since no attributes are +- supported. +- +-C. Appendix: DAAdverts with arbitrary URLs +- +- Using Active DA Discovery, a SrvRqst with its service type field set +- to "service:directory-agent". DAs will respond with a DAAdvert +- containing a URL with the "service:directory-agent:" scheme. This is +- the same DAAdvert that such a DA would multicast in unsolicited DA +- advertisements. +- +- A UA or SA which receives an unsolicited DAAdvert MUST examine the +- URL to determine if it has a recognized scheme. If the UA or SA does +- not recognize the DAAdvert's URL scheme, the DAAdvert is silently +- discarded. This document specifies only how to use URLs with the +- "service:directory-agent:" scheme. +- +- This provides the possibility for forward compatibility with future +- versions of SLP and enables other services to advertise their ability +- to serve as a clearinghouse for service location information. +- +- For example, if LDAPv3 [15] is used for service registration and +- discovery by a set of end systems, they could interpret a LDAP URL +- [16] to passively discover the LDAP server to use for this purpose. +- This document does not specify how this is done: SLPv2 agents +- without further support would simply discard this DAAdvert. +- +- +- +- +-Guttman, et al. Standards Track [Page 49] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +-D. Appendix: SLP Protocol Extensions +- +-D.1. Required Attribute Missing Option +- +- 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 +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | Extension Type = 0x0001 | Extension Length | +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- | Template IDVer Length | Template IDVer String \ +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- |Required Attr Length| Required Attr \ +- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- +- Required attributes and the format of the IDVer string are defined by +- [13]. +- +- If a SA or DA receives a SrvRqst or a SrvReg which fails to include a +- Required Attribute for the requested Service Type (according to the +- Service Template), it MAY return the Required Attribute Extension in +- addition to the reply corresponding to the message. The sender +- SHOULD reissue the message with a search filter including the +- attributes listed in the returned Required Attribute Extension. +- Similarly, the Required Attribute Extension may be returned in +- response to a SrvDereg message that contains a required attribute +- tag. +- +- The Template IDVer String is the name and version number string of +- the Service Template which defines the given attribute as required. +- It SHOULD be included, but can be omitted if a given SA or DA has +- been individually configured to have 'required attributes.' +- +- The Required Attribute MUST NOT include wild cards. +- +-E. Acknowledgments +- +- This document incorporates ideas from work on several discovery +- protocols, including RDP by Perkins and Harjono, and PDS by Michael +- Day. We are grateful for contributions by Ye Gu and Peter Ford. +- John Veizades was instrumental in the standardization of the Service +- Location Protocol. Implementors at Novell, Axis Communications and +- Sun Microsystems have contributed significantly to make this a much +- clearer and more consistent document. +- +- +- +- +- +- +- +- +-Guttman, et al. Standards Track [Page 50] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +-F. References +- +- [1] Port numbers, July 1997. +- ftp://ftp.isi.edu/in-notes/iana/assignments/port-numbers. +- +- [2] ISO/IEC JTC1/SC 21. Certificate Extensions. Draft Amendment +- DAM 4 to ISO/IEC 9594-2, December 1996. +- +- [3] ISO/IEC JTC1/SC 21. Certificate Extensions. Draft Amendment +- DAM 2 to ISO/IEC 9594-6, December 1996. +- +- [4] ISO/IEC JTC1/SC 21. Certificate Extensions. Draft Amendment +- DAM 1 to ISO/IEC 9594-7, December 1996. +- +- [5] ISO/IEC JTC1/SC 21. Certificate Extensions. Draft Amendment +- DAM 1 to ISO/IEC 9594-8, December 1996. +- +- [6] Unicode Technical Report #8. The Unicode Standard, version 2.1. +- Technical report, The Unicode Consortium, 1998. +- +- [7] Alvestrand, H., "Tags for the Identification of Languages", +- RFC 1766, March 1995. +- +- [8] Berners-Lee, T., Fielding, R. and L. Masinter, "Uniform +- Resource Identifiers (URI): Generic Syntax", RFC 2396, +- August 1998. +- +- [9] Bradner, S., "Key Words for Use in RFCs to Indicate Requirement +- Levels", BCP 14, RFC 2119, March 1997. +- +- [10] CCITT. The Directory Authentication Framework. Recommendation +- X.509, 1988. +- +- [11] Crocker, D. and P. Overell, "Augmented BNF for Syntax +- Specifications: ABNF", RFC 2234, November 1997. +- +- [12] S. Gursharan, R. Andrews, and A. Oppenheimer. Inside AppleTalk. +- Addison-Wesley, 1990. +- +- [13] Guttman, E., Perkins, C. and J. Kempf, "Service Templates and +- service: Schemes", RFC 2609, June 1999. +- +- [14] Howes, T., "The String Representation of LDAP Search Filters", +- RFC 2254, December 1997. +- +- [15] Wahl, M., Howes, T. and S. Kille, "Lightweight Directory +- Access Protocol (v3)", RFC 2251, December 1997. +- +- +- +- +-Guttman, et al. Standards Track [Page 51] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +- [16] Howes, T. and M. Smith, "The LDAP URL Format", RFC 2255, +- December 1997. +- +- [17] Meyer, D., "Administratively Scoped IP Multicast", RFC 2365, +- July 1998. +- +- [18] Narten, T. and H. Alvestrand, "Guidelines for Writing +- an IANA Considerations Section in RFCs, BCP 26, RFC 2434, +- October 1998. +- +- [19] Microsoft Networks. SMB File Sharing Protocol Extensions 3.0, +- Document Version 1.09, November 1989. +- +- [20] National Institute of Standards and Technology. Digital +- signature standard. Technical Report NIST FIPS PUB 186, U.S. +- Department of Commerce, May 1994. +- +- [21] Perkins, C. and E. Guttman, "DHCP Options for Service Location +- Protocol", RFC 2610, June 1999. +- +- [22] Veizades, J., Guttman, E., Perkins, C. and S. Kaplan, "Service +- Location Protocol", RFC 2165, July 1997. +- +- [23] Yergeau, F., "UTF-8, a transformation format of ISO 10646", +- RFC 2279, January 1998. +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-Guttman, et al. Standards Track [Page 52] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +-G. Authors' Addresses +- +- Erik Guttman +- Sun Microsystems +- Bahnstr. 2 +- 74915 Waibstadt +- Germany +- +- Phone: +49 7263 911 701 +- EMail: Erik.Guttman@sun.com +- +- +- Charles Perkins +- Sun Microsystems +- 901 San Antonio Road +- Palo Alto, CA 94040 +- USA +- +- Phone: +1 650 786 6464 +- EMail: cperkins@sun.com +- +- +- John Veizades +- @Home Network +- 425 Broadway +- Redwood City, CA 94043 +- USA +- +- Phone: +1 650 569 5243 +- EMail: veizades@home.net +- +- +- Michael Day +- Vinca Corporation. +- 1201 North 800 East +- Orem, Utah 84097 USA +- +- Phone: +1 801 376-5083 +- EMail: mday@vinca.com +- +- +- +- +- +- +- +- +- +- +- +- +-Guttman, et al. Standards Track [Page 53] +- +-RFC 2608 Service Location Protocol, Version 2 June 1999 +- +- +-H. Full Copyright Statement +- +- Copyright (C) The Internet Society (1999). All Rights Reserved. +- +- This document and translations of it may be copied and furnished to +- others, and derivative works that comment on or otherwise explain it +- or assist in its implementation may be prepared, copied, published +- and distributed, in whole or in part, without restriction of any +- kind, provided that the above copyright notice and this paragraph are +- included on all such copies and derivative works. However, this +- document itself may not be modified in any way, such as by removing +- the copyright notice or references to the Internet Society or other +- Internet organizations, except as needed for the purpose of +- developing Internet standards in which case the procedures for +- copyrights defined in the Internet Standards process must be +- followed, or as required to translate it into languages other than +- English. +- +- The limited permissions granted above are perpetual and will not be +- revoked by the Internet Society or its successors or assigns. +- +- This document and the information contained herein is provided on an +- "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING +- TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING +- BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION +- HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF +- MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE." +- +-Acknowledgement +- +- Funding for the RFC Editor function is currently provided by the +- Internet Society. +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-Guttman, et al. Standards Track [Page 54] +- +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/open-isns/doc/rfc3279.txt open-iscsi-2.0-872-rc4-bnx2i.work/utils/open-isns/doc/rfc3279.txt +--- open-iscsi-2.0-872-rc4-bnx2i/utils/open-isns/doc/rfc3279.txt 2010-07-11 04:05:58.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/utils/open-isns/doc/rfc3279.txt 1969-12-31 18:00:00.000000000 -0600 +@@ -1,1515 +0,0 @@ +- +- +- +- +- +- +-Network Working Group W. Polk +-Request for Comments: 3279 NIST +-Obsoletes: 2528 R. Housley +-Category: Standards Track RSA Laboratories +- L. Bassham +- NIST +- April 2002 +- +- Algorithms and Identifiers for the +- Internet X.509 Public Key Infrastructure +- Certificate and Certificate Revocation List (CRL) Profile +- +-Status of this Memo +- +- This document specifies an Internet standards track protocol for the +- Internet community, and requests discussion and suggestions for +- improvements. Please refer to the current edition of the "Internet +- Official Protocol Standards" (STD 1) for the standardization state +- and status of this protocol. Distribution of this memo is unlimited. +- +-Copyright Notice +- +- Copyright (C) The Internet Society (2002). All Rights Reserved. +- +-Abstract +- +- This document specifies algorithm identifiers and ASN.1 encoding +- formats for digital signatures and subject public keys used in the +- Internet X.509 Public Key Infrastructure (PKI). Digital signatures +- are used to sign certificates and certificate revocation list (CRLs). +- Certificates include the public key of the named subject. +- +-Table of Contents +- +- 1 Introduction . . . . . . . . . . . . . . . . . . . . . . 2 +- 2 Algorithm Support . . . . . . . . . . . . . . . . . . . . 3 +- 2.1 One-Way Hash Functions . . . . . . . . . . . . . . . . 3 +- 2.1.1 MD2 One-Way Hash Functions . . . . . . . . . . . . . 3 +- 2.1.2 MD5 One-Way Hash Functions . . . . . . . . . . . . . 4 +- 2.1.3 SHA-1 One-Way Hash Functions . . . . . . . . . . . . 4 +- 2.2 Signature Algorithms . . . . . . . . . . . . . . . . . 4 +- 2.2.1 RSA Signature Algorithm . . . . . . . . . . . . . . . 5 +- 2.2.2 DSA Signature Algorithm . . . . . . . . . . . . . . . 6 +- 2.2.3 Elliptic Curve Digital Signature Algorithm . . . . . 7 +- 2.3 Subject Public Key Algorithms . . . . . . . . . . . . . 7 +- 2.3.1 RSA Keys . . . . . . . . . . . . . . . . . . . . . . 8 +- 2.3.2 DSA Signature Keys . . . . . . . . . . . . . . . . . 9 +- 2.3.3 Diffie-Hellman Key Exchange Keys . . . . . . . . . . 10 +- +- +- +-Polk, et al. Standards Track [Page 1] +- +-RFC 3279 Algorithms and Identifiers April 2002 +- +- +- 2.3.4 KEA Public Keys . . . . . . . . . . . . . . . . . . . 11 +- 2.3.5 ECDSA and ECDH Public Keys . . . . . . . . . . . . . 13 +- 3 ASN.1 Module . . . . . . . . . . . . . . . . . . . . . . 18 +- 4 References . . . . . . . . . . . . . . . . . . . . . . . 24 +- 5 Security Considerations . . . . . . . . . . . . . . . . . 25 +- 6 Intellectual Property Rights . . . . . . . . . . . . . . 26 +- 7 Author Addresses . . . . . . . . . . . . . . . . . . . . 26 +- 8 Full Copyright Statement . . . . . . . . . . . . . . . . 27 +- +-1 Introduction +- +- The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +- "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +- document are to be interpreted as described in [RFC 2119]. +- +- This document specifies algorithm identifiers and ASN.1 [X.660] +- encoding formats for digital signatures and subject public keys used +- in the Internet X.509 Public Key Infrastructure (PKI). This +- specification supplements [RFC 3280], "Internet X.509 Public Key +- Infrastructure: Certificate and Certificate Revocation List (CRL) +- Profile." Implementations of this specification MUST also conform to +- RFC 3280. +- +- This specification defines the contents of the signatureAlgorithm, +- signatureValue, signature, and subjectPublicKeyInfo fields within +- Internet X.509 certificates and CRLs. +- +- This document identifies one-way hash functions for use in the +- generation of digital signatures. These algorithms are used in +- conjunction with digital signature algorithms. +- +- This specification describes the encoding of digital signatures +- generated with the following cryptographic algorithms: +- +- * Rivest-Shamir-Adelman (RSA); +- * Digital Signature Algorithm (DSA); and +- * Elliptic Curve Digital Signature Algorithm (ECDSA). +- +- This document specifies the contents of the subjectPublicKeyInfo +- field in Internet X.509 certificates. For each algorithm, the +- appropriate alternatives for the the keyUsage extension are provided. +- This specification describes encoding formats for public keys used +- with the following cryptographic algorithms: +- +- * Rivest-Shamir-Adelman (RSA); +- * Digital Signature Algorithm (DSA); +- * Diffie-Hellman (DH); +- * Key Encryption Algorithm (KEA); +- +- +- +-Polk, et al. Standards Track [Page 2] +- +-RFC 3279 Algorithms and Identifiers April 2002 +- +- +- * Elliptic Curve Digital Signature Algorithm (ECDSA); and +- * Elliptic Curve Diffie-Hellman (ECDH). +- +-2 Algorithm Support +- +- This section describes cryptographic algorithms which may be used +- with the Internet X.509 certificate and CRL profile [RFC 3280]. This +- section describes one-way hash functions and digital signature +- algorithms which may be used to sign certificates and CRLs, and +- identifies object identifiers (OIDs) for public keys contained in a +- certificate. +- +- Conforming CAs and applications MUST, at a minimum, support digital +- signatures and public keys for one of the specified algorithms. When +- using any of the algorithms identified in this specification, +- conforming CAs and applications MUST support them as described. +- +-2.1 One-way Hash Functions +- +- This section identifies one-way hash functions for use in the +- Internet X.509 PKI. One-way hash functions are also called message +- digest algorithms. SHA-1 is the preferred one-way hash function for +- the Internet X.509 PKI. However, PEM uses MD2 for certificates [RFC +- 1422] [RFC 1423] and MD5 is used in other legacy applications. For +- these reasons, MD2 and MD5 are included in this profile. The data +- that is hashed for certificate and CRL signing is fully described in +- [RFC 3280]. +- +-2.1.1 MD2 One-way Hash Function +- +- MD2 was developed by Ron Rivest for RSA Security. RSA Security has +- recently placed the MD2 algorithm in the public domain. Previously, +- RSA Data Security had granted license for use of MD2 for non- +- commercial Internet Privacy-Enhanced Mail (PEM). MD2 may continue to +- be used with PEM certificates, but SHA-1 is preferred. MD2 produces +- a 128-bit "hash" of the input. MD2 is fully described in [RFC 1319]. +- +- At the Selected Areas in Cryptography '95 conference in May 1995, +- Rogier and Chauvaud presented an attack on MD2 that can nearly find +- collisions [RC95]. Collisions occur when one can find two different +- messages that generate the same message digest. A checksum operation +- in MD2 is the only remaining obstacle to the success of the attack. +- For this reason, the use of MD2 for new applications is discouraged. +- It is still reasonable to use MD2 to verify existing signatures, as +- the ability to find collisions in MD2 does not enable an attacker to +- find new messages having a previously computed hash value. +- +- +- +- +- +-Polk, et al. Standards Track [Page 3] +- +-RFC 3279 Algorithms and Identifiers April 2002 +- +- +-2.1.2 MD5 One-way Hash Function +- +- MD5 was developed by Ron Rivest for RSA Security. RSA Security has +- placed the MD5 algorithm in the public domain. MD5 produces a 128- +- bit "hash" of the input. MD5 is fully described in [RFC 1321]. +- +- Den Boer and Bosselaers [DB94] have found pseudo-collisions for MD5, +- but there are no other known cryptanalytic results. The use of MD5 +- for new applications is discouraged. It is still reasonable to use +- MD5 to verify existing signatures. +- +-2.1.3 SHA-1 One-way Hash Function +- +- SHA-1 was developed by the U.S. Government. SHA-1 produces a 160-bit +- "hash" of the input. SHA-1 is fully described in [FIPS 180-1]. RFC +- 3174 [RFC 3174] also describes SHA-1, and it provides an +- implementation of the algorithm. +- +-2.2 Signature Algorithms +- +- Certificates and CRLs conforming to [RFC 3280] may be signed with any +- public key signature algorithm. The certificate or CRL indicates the +- algorithm through an algorithm identifier which appears in the +- signatureAlgorithm field within the Certificate or CertificateList. +- This algorithm identifier is an OID and has optionally associated +- parameters. This section identifies algorithm identifiers and +- parameters that MUST be used in the signatureAlgorithm field in a +- Certificate or CertificateList. +- +- Signature algorithms are always used in conjunction with a one-way +- hash function. +- +- This section identifies OIDS for RSA, DSA, and ECDSA. The contents +- of the parameters component for each algorithm vary; details are +- provided for each algorithm. +- +- The data to be signed (e.g., the one-way hash function output value) +- is formatted for the signature algorithm to be used. Then, a private +- key operation (e.g., RSA encryption) is performed to generate the +- signature value. This signature value is then ASN.1 encoded as a BIT +- STRING and included in the Certificate or CertificateList in the +- signature field. +- +- +- +- +- +- +- +- +- +-Polk, et al. Standards Track [Page 4] +- +-RFC 3279 Algorithms and Identifiers April 2002 +- +- +-2.2.1 RSA Signature Algorithm +- +- The RSA algorithm is named for its inventors: Rivest, Shamir, and +- Adleman. This profile includes three signature algorithms based on +- the RSA asymmetric encryption algorithm. The signature algorithms +- combine RSA with either the MD2, MD5, or the SHA-1 one-way hash +- functions. +- +- The signature algorithm with SHA-1 and the RSA encryption algorithm +- is implemented using the padding and encoding conventions described +- in PKCS #1 [RFC 2313]. The message digest is computed using the +- SHA-1 hash algorithm. +- +- The RSA signature algorithm, as specified in PKCS #1 [RFC 2313] +- includes a data encoding step. In this step, the message digest and +- the OID for the one-way hash function used to compute the digest are +- combined. When performing the data encoding step, the md2, md5, and +- id-sha1 OIDs MUST be used to specify the MD2, MD5, and SHA-1 one-way +- hash functions, respectively: +- +- md2 OBJECT IDENTIFIER ::= { +- iso(1) member-body(2) US(840) rsadsi(113549) +- digestAlgorithm(2) 2 } +- +- md5 OBJECT IDENTIFIER ::= { +- iso(1) member-body(2) US(840) rsadsi(113549) +- digestAlgorithm(2) 5 } +- +- id-sha1 OBJECT IDENTIFIER ::= { +- iso(1) identified-organization(3) oiw(14) secsig(3) +- algorithms(2) 26 } +- +- The signature algorithm with MD2 and the RSA encryption algorithm is +- defined in PKCS #1 [RFC 2313]. As defined in PKCS #1 [RFC 2313], the +- ASN.1 OID used to identify this signature algorithm is: +- +- md2WithRSAEncryption OBJECT IDENTIFIER ::= { +- iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) +- pkcs-1(1) 2 } +- +- The signature algorithm with MD5 and the RSA encryption algorithm is +- defined in PKCS #1 [RFC 2313]. As defined in PKCS #1 [RFC 2313], the +- ASN.1 OID used to identify this signature algorithm is: +- +- md5WithRSAEncryption OBJECT IDENTIFIER ::= { +- iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) +- pkcs-1(1) 4 } +- +- +- +- +-Polk, et al. Standards Track [Page 5] +- +-RFC 3279 Algorithms and Identifiers April 2002 +- +- +- The ASN.1 object identifier used to identify this signature algorithm +- is: +- +- sha-1WithRSAEncryption OBJECT IDENTIFIER ::= { +- iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) +- pkcs-1(1) 5 } +- +- When any of these three OIDs appears within the ASN.1 type +- AlgorithmIdentifier, the parameters component of that type SHALL be +- the ASN.1 type NULL. +- +- The RSA signature generation process and the encoding of the result +- is described in detail in PKCS #1 [RFC 2313]. +- +-2.2.2 DSA Signature Algorithm +- +- The Digital Signature Algorithm (DSA) is defined in the Digital +- Signature Standard (DSS). DSA was developed by the U.S. Government, +- and DSA is used in conjunction with the SHA-1 one-way hash function. +- DSA is fully described in [FIPS 186]. The ASN.1 OID used to identify +- this signature algorithm is: +- +- id-dsa-with-sha1 OBJECT IDENTIFIER ::= { +- iso(1) member-body(2) us(840) x9-57 (10040) +- x9cm(4) 3 } +- +- When the id-dsa-with-sha1 algorithm identifier appears as the +- algorithm field in an AlgorithmIdentifier, the encoding SHALL omit +- the parameters field. That is, the AlgorithmIdentifier SHALL be a +- SEQUENCE of one component: the OBJECT IDENTIFIER id-dsa-with-sha1. +- +- The DSA parameters in the subjectPublicKeyInfo field of the +- certificate of the issuer SHALL apply to the verification of the +- signature. +- +- When signing, the DSA algorithm generates two values. These values +- are commonly referred to as r and s. To easily transfer these two +- values as one signature, they SHALL be ASN.1 encoded using the +- following ASN.1 structure: +- +- Dss-Sig-Value ::= SEQUENCE { +- r INTEGER, +- s INTEGER } +- +- +- +- +- +- +- +- +-Polk, et al. Standards Track [Page 6] +- +-RFC 3279 Algorithms and Identifiers April 2002 +- +- +-2.2.3 ECDSA Signature Algorithm +- +- The Elliptic Curve Digital Signature Algorithm (ECDSA) is defined in +- [X9.62]. The ASN.1 object identifiers used to identify ECDSA are +- defined in the following arc: +- +- ansi-X9-62 OBJECT IDENTIFIER ::= { +- iso(1) member-body(2) us(840) 10045 } +- +- id-ecSigType OBJECT IDENTIFIER ::= { +- ansi-X9-62 signatures(4) } +- +- ECDSA is used in conjunction with the SHA-1 one-way hash function. +- The ASN.1 object identifier used to identify ECDSA with SHA-1 is: +- +- ecdsa-with-SHA1 OBJECT IDENTIFIER ::= { +- id-ecSigType 1 } +- +- When the ecdsa-with-SHA1 algorithm identifier appears as the +- algorithm field in an AlgorithmIdentifier, the encoding MUST omit the +- parameters field. That is, the AlgorithmIdentifier SHALL be a +- SEQUENCE of one component: the OBJECT IDENTIFIER ecdsa-with-SHA1. +- +- The elliptic curve parameters in the subjectPublicKeyInfo field of +- the certificate of the issuer SHALL apply to the verification of the +- signature. +- +- When signing, the ECDSA algorithm generates two values. These values +- are commonly referred to as r and s. To easily transfer these two +- values as one signature, they MUST be ASN.1 encoded using the +- following ASN.1 structure: +- +- Ecdsa-Sig-Value ::= SEQUENCE { +- r INTEGER, +- s INTEGER } +- +-2.3 Subject Public Key Algorithms +- +- Certificates conforming to [RFC 3280] may convey a public key for any +- public key algorithm. The certificate indicates the algorithm +- through an algorithm identifier. This algorithm identifier is an OID +- and optionally associated parameters. +- +- This section identifies preferred OIDs and parameters for the RSA, +- DSA, Diffie-Hellman, KEA, ECDSA, and ECDH algorithms. Conforming CAs +- MUST use the identified OIDs when issuing certificates containing +- +- +- +- +- +-Polk, et al. Standards Track [Page 7] +- +-RFC 3279 Algorithms and Identifiers April 2002 +- +- +- public keys for these algorithms. Conforming applications supporting +- any of these algorithms MUST, at a minimum, recognize the OID +- identified in this section. +- +-2.3.1 RSA Keys +- +- The OID rsaEncryption identifies RSA public keys. +- +- pkcs-1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) +- rsadsi(113549) pkcs(1) 1 } +- +- rsaEncryption OBJECT IDENTIFIER ::= { pkcs-1 1} +- +- The rsaEncryption OID is intended to be used in the algorithm field +- of a value of type AlgorithmIdentifier. The parameters field MUST +- have ASN.1 type NULL for this algorithm identifier. +- +- The RSA public key MUST be encoded using the ASN.1 type RSAPublicKey: +- +- RSAPublicKey ::= SEQUENCE { +- modulus INTEGER, -- n +- publicExponent INTEGER } -- e +- +- where modulus is the modulus n, and publicExponent is the public +- exponent e. The DER encoded RSAPublicKey is the value of the BIT +- STRING subjectPublicKey. +- +- This OID is used in public key certificates for both RSA signature +- keys and RSA encryption keys. The intended application for the key +- MAY be indicated in the key usage field (see [RFC 3280]). The use of +- a single key for both signature and encryption purposes is not +- recommended, but is not forbidden. +- +- If the keyUsage extension is present in an end entity certificate +- which conveys an RSA public key, any combination of the following +- values MAY be present: +- +- digitalSignature; +- nonRepudiation; +- keyEncipherment; and +- dataEncipherment. +- +- If the keyUsage extension is present in a CA or CRL issuer +- certificate which conveys an RSA public key, any combination of the +- following values MAY be present: +- +- digitalSignature; +- nonRepudiation; +- +- +- +-Polk, et al. Standards Track [Page 8] +- +-RFC 3279 Algorithms and Identifiers April 2002 +- +- +- keyEncipherment; +- dataEncipherment; +- keyCertSign; and +- cRLSign. +- +- However, this specification RECOMMENDS that if keyCertSign or cRLSign +- is present, both keyEncipherment and dataEncipherment SHOULD NOT be +- present. +- +-2.3.2 DSA Signature Keys +- +- The Digital Signature Algorithm (DSA) is defined in the Digital +- Signature Standard (DSS) [FIPS 186]. The DSA OID supported by this +- profile is: +- +- id-dsa OBJECT IDENTIFIER ::= { +- iso(1) member-body(2) us(840) x9-57(10040) x9cm(4) 1 } +- +- The id-dsa algorithm syntax includes optional domain parameters. +- These parameters are commonly referred to as p, q, and g. When +- omitted, the parameters component MUST be omitted entirely. That is, +- the AlgorithmIdentifier MUST be a SEQUENCE of one component: the +- OBJECT IDENTIFIER id-dsa. +- +- If the DSA domain parameters are present in the subjectPublicKeyInfo +- AlgorithmIdentifier, the parameters are included using the following +- ASN.1 structure: +- +- Dss-Parms ::= SEQUENCE { +- p INTEGER, +- q INTEGER, +- g INTEGER } +- +- The AlgorithmIdentifier within subjectPublicKeyInfo is the only place +- within a certificate where the parameters may be used. If the DSA +- algorithm parameters are omitted from the subjectPublicKeyInfo +- AlgorithmIdentifier and the CA signed the subject certificate using +- DSA, then the certificate issuer's DSA parameters apply to the +- subject's DSA key. If the DSA domain parameters are omitted from the +- SubjectPublicKeyInfo AlgorithmIdentifier and the CA signed the +- subject certificate using a signature algorithm other than DSA, then +- the subject's DSA domain parameters are distributed by other means. +- If the subjectPublicKeyInfo AlgorithmIdentifier field omits the +- parameters component, the CA signed the subject with a signature +- algorithm other than DSA, and the subject's DSA parameters are not +- available through other means, then clients MUST reject the +- certificate. +- +- +- +- +-Polk, et al. Standards Track [Page 9] +- +-RFC 3279 Algorithms and Identifiers April 2002 +- +- +- The DSA public key MUST be ASN.1 DER encoded as an INTEGER; this +- encoding shall be used as the contents (i.e., the value) of the +- subjectPublicKey component (a BIT STRING) of the SubjectPublicKeyInfo +- data element. +- +- DSAPublicKey ::= INTEGER -- public key, Y +- +- If the keyUsage extension is present in an end entity certificate +- which conveys a DSA public key, any combination of the following +- values MAY be present: +- +- digitalSignature; +- nonRepudiation; +- +- If the keyUsage extension is present in a CA or CRL issuer +- certificate which conveys a DSA public key, any combination of the +- following values MAY be present: +- +- digitalSignature; +- nonRepudiation; +- keyCertSign; and +- cRLSign. +- +-2.3.3 Diffie-Hellman Key Exchange Keys +- +- The Diffie-Hellman OID supported by this profile is defined in +- [X9.42]. +- +- dhpublicnumber OBJECT IDENTIFIER ::= { iso(1) member-body(2) +- us(840) ansi-x942(10046) number-type(2) 1 } +- +- The dhpublicnumber OID is intended to be used in the algorithm field +- of a value of type AlgorithmIdentifier. The parameters field of that +- type, which has the algorithm-specific syntax ANY DEFINED BY +- algorithm, have the ASN.1 type DomainParameters for this algorithm. +- +- DomainParameters ::= SEQUENCE { +- p INTEGER, -- odd prime, p=jq +1 +- g INTEGER, -- generator, g +- q INTEGER, -- factor of p-1 +- j INTEGER OPTIONAL, -- subgroup factor +- validationParms ValidationParms OPTIONAL } +- +- ValidationParms ::= SEQUENCE { +- seed BIT STRING, +- pgenCounter INTEGER } +- +- +- +- +- +-Polk, et al. Standards Track [Page 10] +- +-RFC 3279 Algorithms and Identifiers April 2002 +- +- +- The fields of type DomainParameters have the following meanings: +- +- p identifies the prime p defining the Galois field; +- +- g specifies the generator of the multiplicative subgroup of order +- g; +- +- q specifies the prime factor of p-1; +- +- j optionally specifies the value that satisfies the equation +- p=jq+1 to support the optional verification of group parameters; +- +- seed optionally specifies the bit string parameter used as the +- seed for the domain parameter generation process; and +- +- pgenCounter optionally specifies the integer value output as part +- of the of the domain parameter prime generation process. +- +- If either of the domain parameter generation components (pgenCounter +- or seed) is provided, the other MUST be present as well. +- +- The Diffie-Hellman public key MUST be ASN.1 encoded as an INTEGER; +- this encoding shall be used as the contents (i.e., the value) of the +- subjectPublicKey component (a BIT STRING) of the SubjectPublicKeyInfo +- data element. +- +- DHPublicKey ::= INTEGER -- public key, y = g^x mod p +- +- If the keyUsage extension is present in a certificate which conveys a +- DH public key, the following values may be present: +- +- keyAgreement; +- encipherOnly; and +- decipherOnly. +- +- If present, the keyUsage extension MUST assert keyAgreement and MAY +- assert either encipherOnly and decipherOnly. The keyUsage extension +- MUST NOT assert both encipherOnly and decipherOnly. +- +-2.3.4 KEA Public Keys +- +- This section identifies the preferred OID and parameters for the +- inclusion of a KEA public key in a certificate. The Key Exchange +- Algorithm (KEA) is a key agreement algorithm. Two parties may +- generate a "pairwise key" if and only if they share the same KEA +- parameters. The KEA parameters are not included in a certificate; +- instead a domain identifier is supplied in the parameters field. +- +- +- +- +-Polk, et al. Standards Track [Page 11] +- +-RFC 3279 Algorithms and Identifiers April 2002 +- +- +- When the SubjectPublicKeyInfo field contains a KEA key, the algorithm +- identifier and parameters SHALL be as defined in [SDN.701r]: +- +- id-keyExchangeAlgorithm OBJECT IDENTIFIER ::= +- { 2 16 840 1 101 2 1 1 22 } +- +- KEA-Parms-Id ::= OCTET STRING +- +- CAs MUST populate the parameters field of the AlgorithmIdentifier +- within the SubjectPublicKeyInfo field of each certificate containing +- a KEA public key with an 80-bit parameter identifier (OCTET STRING), +- also known as the domain identifier. The domain identifier is +- computed in three steps: +- +- (1) the KEA domain parameters (p, q, and g) are DER encoded using +- the Dss-Parms structure; +- +- (2) a 160-bit SHA-1 hash is generated from the parameters; and +- +- (3) the 160-bit hash is reduced to 80-bits by performing an +- "exclusive or" of the 80 high order bits with the 80 low order +- bits. +- +- The resulting value is encoded such that the most significant byte of +- the 80-bit value is the first octet in the octet string. The Dss- +- Parms is provided above in Section 2.3.2. +- +- A KEA public key, y, is conveyed in the subjectPublicKey BIT STRING +- such that the most significant bit (MSB) of y becomes the MSB of the +- BIT STRING value field and the least significant bit (LSB) of y +- becomes the LSB of the BIT STRING value field. This results in the +- following encoding: +- +- BIT STRING tag; +- BIT STRING length; +- 0 (indicating that there are zero unused bits in the final octet +- of y); and +- BIT STRING value field including y. +- +- The key usage extension may optionally appear in a KEA certificate. +- If a KEA certificate includes the keyUsage extension, only the +- following values may be asserted: +- +- keyAgreement; +- encipherOnly; and +- decipherOnly. +- +- +- +- +- +-Polk, et al. Standards Track [Page 12] +- +-RFC 3279 Algorithms and Identifiers April 2002 +- +- +- If present, the keyUsage extension MUST assert keyAgreement and MAY +- assert either encipherOnly and decipherOnly. The keyUsage extension +- MUST NOT assert both encipherOnly and decipherOnly. +- +-2.3.5 ECDSA and ECDH Keys +- +- This section identifies the preferred OID and parameter encoding for +- the inclusion of an ECDSA or ECDH public key in a certificate. The +- Elliptic Curve Digital Signature Algorithm (ECDSA) is defined in +- [X9.62]. ECDSA is the elliptic curve mathematical analog of the +- Digital Signature Algorithm [FIPS 186]. The Elliptic Curve Diffie +- Hellman (ECDH) algorithm is a key agreement algorithm defined in +- [X9.63]. +- +- ECDH is the elliptic curve mathematical analog of the Diffie-Hellman +- key agreement algorithm as specified in [X9.42]. The ECDSA and ECDH +- specifications use the same OIDs and parameter encodings. The ASN.1 +- object identifiers used to identify these public keys are defined in +- the following arc: +- +- ansi-X9-62 OBJECT IDENTIFIER ::= +- { iso(1) member-body(2) us(840) 10045 } +- +- When certificates contain an ECDSA or ECDH public key, the +- id-ecPublicKey algorithm identifier MUST be used. The id-ecPublicKey +- algorithm identifier is defined as follows: +- +- id-public-key-type OBJECT IDENTIFIER ::= { ansi-X9.62 2 } +- +- id-ecPublicKey OBJECT IDENTIFIER ::= { id-publicKeyType 1 } +- +- This OID is used in public key certificates for both ECDSA signature +- keys and ECDH encryption keys. The intended application for the key +- may be indicated in the key usage field (see [RFC 3280]). The use of +- a single key for both signature and encryption purposes is not +- recommended, but is not forbidden. +- +- ECDSA and ECDH require use of certain parameters with the public key. +- The parameters may be inherited from the issuer, implicitly included +- through reference to a "named curve," or explicitly included in the +- certificate. +- +- EcpkParameters ::= CHOICE { +- ecParameters ECParameters, +- namedCurve OBJECT IDENTIFIER, +- implicitlyCA NULL } +- +- +- +- +- +-Polk, et al. Standards Track [Page 13] +- +-RFC 3279 Algorithms and Identifiers April 2002 +- +- +- When the parameters are inherited, the parameters field SHALL contain +- implictlyCA, which is the ASN.1 value NULL. When parameters are +- specified by reference, the parameters field SHALL contain the +- named-Curve choice, which is an object identifier. When the +- parameters are explicitly included, they SHALL be encoded in the +- ASN.1 structure ECParameters: +- +- ECParameters ::= SEQUENCE { +- version ECPVer, -- version is always 1 +- fieldID FieldID, -- identifies the finite field over +- -- which the curve is defined +- curve Curve, -- coefficients a and b of the +- -- elliptic curve +- base ECPoint, -- specifies the base point P +- -- on the elliptic curve +- order INTEGER, -- the order n of the base point +- cofactor INTEGER OPTIONAL -- The integer h = #E(Fq)/n +- } +- +- ECPVer ::= INTEGER {ecpVer1(1)} +- +- Curve ::= SEQUENCE { +- a FieldElement, +- b FieldElement, +- seed BIT STRING OPTIONAL } +- +- FieldElement ::= OCTET STRING +- +- ECPoint ::= OCTET STRING +- +- The value of FieldElement SHALL be the octet string representation of +- a field element following the conversion routine in [X9.62], Section +- 4.3.3. The value of ECPoint SHALL be the octet string representation +- of an elliptic curve point following the conversion routine in +- [X9.62], Section 4.3.6. Note that this octet string may represent an +- elliptic curve point in compressed or uncompressed form. +- +- Implementations that support elliptic curve according to this +- specification MUST support the uncompressed form and MAY support the +- compressed form. +- +- The components of type ECParameters have the following meanings: +- +- version specifies the version number of the elliptic curve +- parameters. It MUST have the value 1 (ecpVer1). +- +- +- +- +- +- +-Polk, et al. Standards Track [Page 14] +- +-RFC 3279 Algorithms and Identifiers April 2002 +- +- +- fieldID identifies the finite field over which the elliptic curve +- is defined. Finite fields are represented by values of the +- parameterized type FieldID, constrained to the values of the +- objects defined in the information object set FieldTypes. +- Additional detail regarding fieldID is provided below. +- +- curve specifies the coefficients a and b of the elliptic curve E. +- Each coefficient is represented as a value of type FieldElement, +- an OCTET STRING. seed is an optional parameter used to derive the +- coefficients of a randomly generated elliptic curve. +- +- base specifies the base point P on the elliptic curve. The base +- point is represented as a value of type ECPoint, an OCTET STRING. +- +- order specifies the order n of the base point. +- +- cofactor is the integer h = #E(Fq)/n. This parameter is specified +- as OPTIONAL. However, the cofactor MUST be included in ECDH +- public key parameters. The cofactor is not required to support +- ECDSA, except in parameter validation. The cofactor MAY be +- included to support parameter validation for ECDSA keys. +- Parameter validation is not required by this specification. +- +- The AlgorithmIdentifier within SubjectPublicKeyInfo is the only place +- within a certificate where the parameters may be used. If the +- elliptic curve parameters are specified as implicitlyCA in the +- SubjectPublicKeyInfo AlgorithmIdentifier and the CA signed the +- subject certificate using ECDSA, then the certificate issuer's ECDSA +- parameters apply to the subject's ECDSA key. If the elliptic curve +- parameters are specified as implicitlyCA in the SubjectPublicKeyInfo +- AlgorithmIdentifier and the CA signed the certificate using a +- signature algorithm other than ECDSA, then clients MUST not make use +- of the elliptic curve public key. +- +- FieldID ::= SEQUENCE { +- fieldType OBJECT IDENTIFIER, +- parameters ANY DEFINED BY fieldType } +- +- FieldID is a SEQUENCE of two components, fieldType and parameters. +- The fieldType contains an object identifier value that uniquely +- identifies the type contained in the parameters. +- +- The object identifier id-fieldType specifies an arc containing the +- object identifiers of each field type. It has the following value: +- +- id-fieldType OBJECT IDENTIFIER ::= { ansi-X9-62 fieldType(1) } +- +- +- +- +- +-Polk, et al. Standards Track [Page 15] +- +-RFC 3279 Algorithms and Identifiers April 2002 +- +- +- The object identifiers prime-field and characteristic-two-field name +- the two kinds of fields defined in this Standard. They have the +- following values: +- +- prime-field OBJECT IDENTIFIER ::= { id-fieldType 1 } +- +- Prime-p ::= INTEGER -- Field size p (p in bits) +- +- characteristic-two-field OBJECT IDENTIFIER ::= { id-fieldType 2 } +- +- Characteristic-two ::= SEQUENCE { +- m INTEGER, -- Field size 2^m +- basis OBJECT IDENTIFIER, +- parameters ANY DEFINED BY basis } +- +- The object identifier id-characteristic-two-basis specifies an arc +- containing the object identifiers for each type of basis for the +- characteristic-two finite fields. It has the following value: +- +- id-characteristic-two-basis OBJECT IDENTIFIER ::= { +- characteristic-two-field basisType(1) } +- +- The object identifiers gnBasis, tpBasis and ppBasis name the three +- kinds of basis for characteristic-two finite fields defined by +- [X9.62]. They have the following values: +- +- gnBasis OBJECT IDENTIFIER ::= { id-characteristic-two-basis 1 } +- +- -- for gnBasis, the value of the parameters field is NULL +- +- tpBasis OBJECT IDENTIFIER ::= { id-characteristic-two-basis 2 } +- +- -- type of parameters field for tpBasis is Trinomial +- +- Trinomial ::= INTEGER +- +- ppBasis OBJECT IDENTIFIER ::= { id-characteristic-two-basis 3 } +- +- -- type of parameters field for ppBasis is Pentanomial +- +- Pentanomial ::= SEQUENCE { +- k1 INTEGER, +- k2 INTEGER, +- k3 INTEGER } +- +- +- +- +- +- +- +-Polk, et al. Standards Track [Page 16] +- +-RFC 3279 Algorithms and Identifiers April 2002 +- +- +- The elliptic curve public key (an ECPoint which is an OCTET STRING) +- is mapped to a subjectPublicKey (a BIT STRING) as follows: the most +- significant bit of the OCTET STRING becomes the most significant bit +- of the BIT STRING, and the least significant bit of the OCTET STRING +- becomes the least significant bit of the BIT STRING. Note that this +- octet string may represent an elliptic curve point in compressed or +- uncompressed form. Implementations that support elliptic curve +- according to this specification MUST support the uncompressed form +- and MAY support the compressed form. +- +- If the keyUsage extension is present in a CA or CRL issuer +- certificate which conveys an elliptic curve public key, any +- combination of the following values MAY be present: +- +- digitalSignature; +- nonRepudiation; and +- keyAgreement. +- +- If the keyAgreement value is present, either of the following values +- MAY be present: +- +- encipherOnly; and +- decipherOnly. +- +- The keyUsage extension MUST NOT assert both encipherOnly and +- decipherOnly. +- +- If the keyUsage extension is present in a CA certificate which +- conveys an elliptic curve public key, any combination of the +- following values MAY be present: +- +- digitalSignature; +- nonRepudiation; +- keyAgreement; +- keyCertSign; and +- cRLSign. +- +- As above, if the keyUsage extension asserts keyAgreement then it MAY +- assert either encipherOnly and decipherOnly. However, this +- specification RECOMMENDS that if keyCertSign or cRLSign is present, +- keyAgreement, encipherOnly, and decipherOnly SHOULD NOT be present. +- +- +- +- +- +- +- +- +- +- +-Polk, et al. Standards Track [Page 17] +- +-RFC 3279 Algorithms and Identifiers April 2002 +- +- +-3 ASN.1 Module +- +- PKIX1Algorithms88 { iso(1) identified-organization(3) dod(6) +- internet(1) security(5) mechanisms(5) pkix(7) id-mod(0) +- id-mod-pkix1-algorithms(17) } +- +- DEFINITIONS EXPLICIT TAGS ::= BEGIN +- +- -- EXPORTS All; +- +- -- IMPORTS NONE; +- +- -- +- -- One-way Hash Functions +- -- +- +- md2 OBJECT IDENTIFIER ::= { +- iso(1) member-body(2) us(840) rsadsi(113549) +- digestAlgorithm(2) 2 } +- +- md5 OBJECT IDENTIFIER ::= { +- iso(1) member-body(2) us(840) rsadsi(113549) +- digestAlgorithm(2) 5 } +- +- id-sha1 OBJECT IDENTIFIER ::= { +- iso(1) identified-organization(3) oiw(14) secsig(3) +- algorithms(2) 26 } +- +- -- +- -- DSA Keys and Signatures +- -- +- +- -- OID for DSA public key +- +- id-dsa OBJECT IDENTIFIER ::= { +- iso(1) member-body(2) us(840) x9-57(10040) x9algorithm(4) 1 } +- +- -- encoding for DSA public key +- +- DSAPublicKey ::= INTEGER -- public key, y +- +- Dss-Parms ::= SEQUENCE { +- p INTEGER, +- q INTEGER, +- g INTEGER } +- +- +- +- +- +- +-Polk, et al. Standards Track [Page 18] +- +-RFC 3279 Algorithms and Identifiers April 2002 +- +- +- -- OID for DSA signature generated with SHA-1 hash +- +- id-dsa-with-sha1 OBJECT IDENTIFIER ::= { +- iso(1) member-body(2) us(840) x9-57 (10040) x9algorithm(4) 3 } +- +- -- encoding for DSA signature generated with SHA-1 hash +- +- Dss-Sig-Value ::= SEQUENCE { +- r INTEGER, +- s INTEGER } +- +- -- +- -- RSA Keys and Signatures +- -- +- +- -- arc for RSA public key and RSA signature OIDs +- +- pkcs-1 OBJECT IDENTIFIER ::= { +- iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1 } +- +- -- OID for RSA public keys +- +- rsaEncryption OBJECT IDENTIFIER ::= { pkcs-1 1 } +- +- -- OID for RSA signature generated with MD2 hash +- +- md2WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 2 } +- +- -- OID for RSA signature generated with MD5 hash +- +- md5WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 4 } +- +- -- OID for RSA signature generated with SHA-1 hash +- +- sha1WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 5 } +- +- -- encoding for RSA public key +- +- RSAPublicKey ::= SEQUENCE { +- modulus INTEGER, -- n +- publicExponent INTEGER } -- e +- +- +- +- +- +- +- +- +- +- +-Polk, et al. Standards Track [Page 19] +- +-RFC 3279 Algorithms and Identifiers April 2002 +- +- +- -- +- -- Diffie-Hellman Keys +- -- +- +- dhpublicnumber OBJECT IDENTIFIER ::= { +- iso(1) member-body(2) us(840) ansi-x942(10046) +- number-type(2) 1 } +- +- -- encoding for DSA public key +- +- DHPublicKey ::= INTEGER -- public key, y = g^x mod p +- +- DomainParameters ::= SEQUENCE { +- p INTEGER, -- odd prime, p=jq +1 +- g INTEGER, -- generator, g +- q INTEGER, -- factor of p-1 +- j INTEGER OPTIONAL, -- subgroup factor, j>= 2 +- validationParms ValidationParms OPTIONAL } +- +- ValidationParms ::= SEQUENCE { +- seed BIT STRING, +- pgenCounter INTEGER } +- +- -- +- -- KEA Keys +- -- +- +- id-keyExchangeAlgorithm OBJECT IDENTIFIER ::= +- { 2 16 840 1 101 2 1 1 22 } +- +- KEA-Parms-Id ::= OCTET STRING +- +- -- +- -- Elliptic Curve Keys, Signatures, and Curves +- -- +- +- ansi-X9-62 OBJECT IDENTIFIER ::= { +- iso(1) member-body(2) us(840) 10045 } +- +- FieldID ::= SEQUENCE { -- Finite field +- fieldType OBJECT IDENTIFIER, +- parameters ANY DEFINED BY fieldType } +- +- -- Arc for ECDSA signature OIDS +- +- id-ecSigType OBJECT IDENTIFIER ::= { ansi-X9-62 signatures(4) } +- +- +- +- +- +-Polk, et al. Standards Track [Page 20] +- +-RFC 3279 Algorithms and Identifiers April 2002 +- +- +- -- OID for ECDSA signatures with SHA-1 +- +- ecdsa-with-SHA1 OBJECT IDENTIFIER ::= { id-ecSigType 1 } +- +- -- OID for an elliptic curve signature +- -- format for the value of an ECDSA signature value +- +- ECDSA-Sig-Value ::= SEQUENCE { +- r INTEGER, +- s INTEGER } +- +- -- recognized field type OIDs are defined in the following arc +- +- id-fieldType OBJECT IDENTIFIER ::= { ansi-X9-62 fieldType(1) } +- +- -- where fieldType is prime-field, the parameters are of type Prime-p +- +- prime-field OBJECT IDENTIFIER ::= { id-fieldType 1 } +- +- Prime-p ::= INTEGER -- Finite field F(p), where p is an odd prime +- +- -- where fieldType is characteristic-two-field, the parameters are +- -- of type Characteristic-two +- +- characteristic-two-field OBJECT IDENTIFIER ::= { id-fieldType 2 } +- +- Characteristic-two ::= SEQUENCE { +- m INTEGER, -- Field size 2^m +- basis OBJECT IDENTIFIER, +- parameters ANY DEFINED BY basis } +- +- -- recognized basis type OIDs are defined in the following arc +- +- id-characteristic-two-basis OBJECT IDENTIFIER ::= { +- characteristic-two-field basisType(3) } +- +- -- gnbasis is identified by OID gnBasis and indicates +- -- parameters are NULL +- +- gnBasis OBJECT IDENTIFIER ::= { id-characteristic-two-basis 1 } +- +- -- parameters for this basis are NULL +- +- -- trinomial basis is identified by OID tpBasis and indicates +- -- parameters of type Pentanomial +- +- tpBasis OBJECT IDENTIFIER ::= { id-characteristic-two-basis 2 } +- +- +- +- +-Polk, et al. Standards Track [Page 21] +- +-RFC 3279 Algorithms and Identifiers April 2002 +- +- +- -- Trinomial basis representation of F2^m +- -- Integer k for reduction polynomial xm + xk + 1 +- +- Trinomial ::= INTEGER +- +- -- for pentanomial basis is identified by OID ppBasis and indicates +- -- parameters of type Pentanomial +- +- ppBasis OBJECT IDENTIFIER ::= { id-characteristic-two-basis 3 } +- +- -- Pentanomial basis representation of F2^m +- -- reduction polynomial integers k1, k2, k3 +- -- f(x) = x**m + x**k3 + x**k2 + x**k1 + 1 +- +- Pentanomial ::= SEQUENCE { +- k1 INTEGER, +- k2 INTEGER, +- k3 INTEGER } +- +- -- The object identifiers gnBasis, tpBasis and ppBasis name +- -- three kinds of basis for characteristic-two finite fields +- +- FieldElement ::= OCTET STRING -- Finite field element +- +- ECPoint ::= OCTET STRING -- Elliptic curve point +- +- -- Elliptic Curve parameters may be specified explicitly, +- -- specified implicitly through a "named curve", or +- -- inherited from the CA +- +- EcpkParameters ::= CHOICE { +- ecParameters ECParameters, +- namedCurve OBJECT IDENTIFIER, +- implicitlyCA NULL } +- +- ECParameters ::= SEQUENCE { -- Elliptic curve parameters +- version ECPVer, +- fieldID FieldID, +- curve Curve, +- base ECPoint, -- Base point G +- order INTEGER, -- Order n of the base point +- cofactor INTEGER OPTIONAL } -- The integer h = #E(Fq)/n +- +- ECPVer ::= INTEGER {ecpVer1(1)} +- +- +- +- +- +- +- +-Polk, et al. Standards Track [Page 22] +- +-RFC 3279 Algorithms and Identifiers April 2002 +- +- +- Curve ::= SEQUENCE { +- a FieldElement, -- Elliptic curve coefficient a +- b FieldElement, -- Elliptic curve coefficient b +- seed BIT STRING OPTIONAL } +- +- id-publicKeyType OBJECT IDENTIFIER ::= { ansi-X9-62 keyType(2) } +- +- id-ecPublicKey OBJECT IDENTIFIER ::= { id-publicKeyType 1 } +- +- -- Named Elliptic Curves in ANSI X9.62. +- +- ellipticCurve OBJECT IDENTIFIER ::= { ansi-X9-62 curves(3) } +- +- c-TwoCurve OBJECT IDENTIFIER ::= { +- ellipticCurve characteristicTwo(0) } +- +- c2pnb163v1 OBJECT IDENTIFIER ::= { c-TwoCurve 1 } +- c2pnb163v2 OBJECT IDENTIFIER ::= { c-TwoCurve 2 } +- c2pnb163v3 OBJECT IDENTIFIER ::= { c-TwoCurve 3 } +- c2pnb176w1 OBJECT IDENTIFIER ::= { c-TwoCurve 4 } +- c2tnb191v1 OBJECT IDENTIFIER ::= { c-TwoCurve 5 } +- c2tnb191v2 OBJECT IDENTIFIER ::= { c-TwoCurve 6 } +- c2tnb191v3 OBJECT IDENTIFIER ::= { c-TwoCurve 7 } +- c2onb191v4 OBJECT IDENTIFIER ::= { c-TwoCurve 8 } +- c2onb191v5 OBJECT IDENTIFIER ::= { c-TwoCurve 9 } +- c2pnb208w1 OBJECT IDENTIFIER ::= { c-TwoCurve 10 } +- c2tnb239v1 OBJECT IDENTIFIER ::= { c-TwoCurve 11 } +- c2tnb239v2 OBJECT IDENTIFIER ::= { c-TwoCurve 12 } +- c2tnb239v3 OBJECT IDENTIFIER ::= { c-TwoCurve 13 } +- c2onb239v4 OBJECT IDENTIFIER ::= { c-TwoCurve 14 } +- c2onb239v5 OBJECT IDENTIFIER ::= { c-TwoCurve 15 } +- c2pnb272w1 OBJECT IDENTIFIER ::= { c-TwoCurve 16 } +- c2pnb304w1 OBJECT IDENTIFIER ::= { c-TwoCurve 17 } +- c2tnb359v1 OBJECT IDENTIFIER ::= { c-TwoCurve 18 } +- c2pnb368w1 OBJECT IDENTIFIER ::= { c-TwoCurve 19 } +- c2tnb431r1 OBJECT IDENTIFIER ::= { c-TwoCurve 20 } +- +- primeCurve OBJECT IDENTIFIER ::= { ellipticCurve prime(1) } +- +- prime192v1 OBJECT IDENTIFIER ::= { primeCurve 1 } +- prime192v2 OBJECT IDENTIFIER ::= { primeCurve 2 } +- prime192v3 OBJECT IDENTIFIER ::= { primeCurve 3 } +- prime239v1 OBJECT IDENTIFIER ::= { primeCurve 4 } +- prime239v2 OBJECT IDENTIFIER ::= { primeCurve 5 } +- prime239v3 OBJECT IDENTIFIER ::= { primeCurve 6 } +- prime256v1 OBJECT IDENTIFIER ::= { primeCurve 7 } +- +- END +- +- +- +-Polk, et al. Standards Track [Page 23] +- +-RFC 3279 Algorithms and Identifiers April 2002 +- +- +-4 References +- +- [FIPS 180-1] Federal Information Processing Standards Publication +- (FIPS PUB) 180-1, Secure Hash Standard, 17 April 1995. +- [Supersedes FIPS PUB 180 dated 11 May 1993.] +- +- [FIPS 186-2] Federal Information Processing Standards Publication +- (FIPS PUB) 186, Digital Signature Standard, 27 January +- 2000. [Supersedes FIPS PUB 186-1 dated 15 December +- 1998.] +- +- [P1363] IEEE P1363, "Standard Specifications for Public-Key +- Cryptography", 2001. +- +- [RC95] Rogier, N. and Chauvaud, P., "The compression function +- of MD2 is not collision free," Presented at Selected +- Areas in Cryptography '95, May 1995. +- +- [RFC 1034] Mockapetris, P., "Domain Names - Concepts and +- Facilities", STD 13, RFC 1034, November 1987. +- +- [RFC 1319] Kaliski, B., "The MD2 Message-Digest Algorithm", RFC +- 1319, April 1992. +- +- [RFC 1321] Rivest, R., "The MD5 Message-Digest Algorithm", RFC +- 1321, April 1992. +- +- [RFC 1422] Kent, S., "Privacy Enhancement for Internet Electronic +- Mail: Part II: Certificate-Based Key Management", RFC +- 1422, February 1993. +- +- [RFC 1423] Balenson, D., "Privacy Enhancement for Internet +- Electronic Mail: Part III: Algorithms, Modes, and +- Identifiers", RFC 1423, February 1993. +- +- [RFC 2119] Bradner, S., "Key Words for Use in RFCs to Indicate +- Requirement Levels", BCP 14, RFC 2119, March 1997. +- +- [RFC 2313] Kaliski, B., "PKCS #1: RSA Encryption Version 1.5", +- RFC 2313, March 1998. +- +- [RFC 2459] Housley, R., Ford, W., Polk, W. and D. Solo "Internet +- X.509 Public Key Infrastructure: Certificate and CRL +- Profile", RFC 2459, January, 1999. +- +- [RFC 3174] Eastlake, D. and P. Jones, "US Secure Hash Algorithm 1 +- (SHA1)", RFC 3174, September 2001. +- +- +- +- +-Polk, et al. Standards Track [Page 24] +- +-RFC 3279 Algorithms and Identifiers April 2002 +- +- +- [RFC 3280] Housley, R., Polk, W., Ford, W. and D. Solo, "Internet +- X.509 Public Key Infrastructure Certificate and +- Certificate Revocation List (CRL) Profile", RFC 3280, +- April 2002. +- +- [SDN.701r] SDN.701, "Message Security Protocol 4.0", Revision A +- 1997-02-06. +- +- [X.208] CCITT Recommendation X.208: Specification of Abstract +- Syntax Notation One (ASN.1), 1988. +- +- [X.660] ITU-T Recommendation X.660 Information Technology - +- ASN.1 encoding rules: Specification of Basic Encoding +- Rules (BER), Canonical Encoding Rules (CER) and +- Distinguished Encoding Rules (DER), 1997. +- +- [X9.42] ANSI X9.42-2000, "Public Key Cryptography for The +- Financial Services Industry: Agreement of Symmetric +- Keys Using Discrete Logarithm Cryptography", December, +- 1999. +- +- [X9.62] X9.62-1998, "Public Key Cryptography For The Financial +- Services Industry: The Elliptic Curve Digital +- Signature Algorithm (ECDSA)", January 7, 1999. +- +- [X9.63] ANSI X9.63-2001, "Public Key Cryptography For The +- Financial Services Industry: Key Agreement and Key +- Transport Using Elliptic Curve Cryptography", Work in +- Progress. +- +-5 Security Considerations +- +- This specification does not constrain the size of public keys or +- their parameters for use in the Internet PKI. However, the key size +- selected impacts the strength achieved when implementing +- cryptographic services. Selection of appropriate key sizes is +- critical to implementing appropriate security. +- +- This specification does not identify particular elliptic curves for +- use in the Internet PKI. However, the particular curve selected +- impact the strength of the digital signatures. Some curves are +- cryptographically stronger than others! +- +- In general, use of "well-known" curves, such as the "named curves" +- from ANSI X9.62, is a sound strategy. For additional information, +- refer to X9.62 Appendix H.1.3, "Key Length Considerations" and +- Appendix A.1, "Avoiding Cryptographically Weak Keys". +- +- +- +- +-Polk, et al. Standards Track [Page 25] +- +-RFC 3279 Algorithms and Identifiers April 2002 +- +- +- This specification supplements RFC 3280. The security considerations +- section of that document applies to this specification as well. +- +-6 Intellectual Property Rights +- +- The IETF has been notified of intellectual property rights claimed in +- regard to some or all of the specification contained in this +- document. For more information consult the online list of claimed +- rights. +- +- The IETF takes no position regarding the validity or scope of any +- intellectual property or other rights that might be claimed to +- pertain to the implementation or use of the technology described in +- this document or the extent to which any license under such rights +- might or might not be available; neither does it represent that it +- has made any effort to identify any such rights. Information on the +- IETF's procedures with respect to rights in standards-track and +- standards- related documentation can be found in BCP-11. Copies of +- claims of rights made available for publication and any assurances of +- licenses to be made available, or the result of an attempt made to +- obtain a general license or permission for the use of such +- proprietary rights by implementors or users of this specification can +- be obtained from the IETF Secretariat. +- +-7 Author Addresses: +- +- Tim Polk +- NIST +- 100 Bureau Drive, Stop 8930 +- Gaithersburg, MD 20899-8930 +- USA +- EMail: tim.polk@nist.gov +- +- Russell Housley +- RSA Laboratories +- 918 Spring Knoll Drive +- Herndon, VA 20170 +- USA +- EMail: rhousley@rsasecurity.com +- +- Larry Bassham +- NIST +- 100 Bureau Drive, Stop 8930 +- Gaithersburg, MD 20899-8930 +- USA +- EMail: lbassham@nist.gov +- +- +- +- +- +-Polk, et al. Standards Track [Page 26] +- +-RFC 3279 Algorithms and Identifiers April 2002 +- +- +-8. Full Copyright Statement +- +- Copyright (C) The Internet Society (2002). All Rights Reserved. +- +- This document and translations of it may be copied and furnished to +- others, and derivative works that comment on or otherwise explain it +- or assist in its implementation may be prepared, copied, published +- and distributed, in whole or in part, without restriction of any +- kind, provided that the above copyright notice and this paragraph are +- included on all such copies and derivative works. However, this +- document itself may not be modified in any way, such as by removing +- the copyright notice or references to the Internet Society or other +- Internet organizations, except as needed for the purpose of +- developing Internet standards in which case the procedures for +- copyrights defined in the Internet Standards process must be +- followed, or as required to translate it into languages other than +- English. +- +- The limited permissions granted above are perpetual and will not be +- revoked by the Internet Society or its successors or assigns. +- +- This document and the information contained herein is provided on an +- "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING +- TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING +- BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION +- HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF +- MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +- +-Acknowledgement +- +- Funding for the RFC Editor function is currently provided by the +- Internet Society. +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-Polk, et al. Standards Track [Page 27] +- +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/open-isns/doc/rfc3720.txt open-iscsi-2.0-872-rc4-bnx2i.work/utils/open-isns/doc/rfc3720.txt +--- open-iscsi-2.0-872-rc4-bnx2i/utils/open-isns/doc/rfc3720.txt 2010-07-11 04:05:58.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/utils/open-isns/doc/rfc3720.txt 1969-12-31 18:00:00.000000000 -0600 +@@ -1,14395 +0,0 @@ +- +- +- +- +- +- +-Network Working Group J. Satran +-Request for Comments: 3720 K. Meth +-Category: Standards Track IBM +- C. Sapuntzakis +- Cisco Systems +- M. Chadalapaka +- Hewlett-Packard Co. +- E. Zeidner +- IBM +- April 2004 +- +- +- Internet Small Computer Systems Interface (iSCSI) +- +-Status of this Memo +- +- This document specifies an Internet standards track protocol for the +- Internet community, and requests discussion and suggestions for +- improvements. Please refer to the current edition of the "Internet +- Official Protocol Standards" (STD 1) for the standardization state +- and status of this protocol. Distribution of this memo is unlimited. +- +-Copyright Notice +- +- Copyright (C) The Internet Society (2003). All Rights Reserved. +- +-Abstract +- +- This document describes a transport protocol for Internet Small +- Computer Systems Interface (iSCSI) that works on top of TCP. The +- iSCSI protocol aims to be fully compliant with the standardized SCSI +- architecture model. +- +- SCSI is a popular family of protocols that enable systems to +- communicate with I/O devices, especially storage devices. SCSI +- protocols are request/response application protocols with a common +- standardized architecture model and basic command set, as well as +- standardized command sets for different device classes (disks, tapes, +- media-changers etc.). +- +- As system interconnects move from the classical bus structure to a +- network structure, SCSI has to be mapped to network transport +- protocols. IP networks now meet the performance requirements of fast +- system interconnects and as such are good candidates to "carry" SCSI. +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 1] +- +-RFC 3720 iSCSI April 2004 +- +- +-Table of Contents +- +- 1. Introduction. . . . . . . . . . . . . . . . . . . . . . . . . 9 +- 2. Definitions and Acronyms. . . . . . . . . . . . . . . . . . . 10 +- 2.1. Definitions. . . . . . . . . . . . . . . . . . . . . . 10 +- 2.2. Acronyms . . . . . . . . . . . . . . . . . . . . . . . 14 +- 2.3. Conventions. . . . . . . . . . . . . . . . . . . . . . 16 +- 2.3.1. Word Rule. . . . . . . . . . . . . . . . . . 16 +- 2.3.2. Half-Word Rule . . . . . . . . . . . . . . . 17 +- 2.3.3. Byte Rule. . . . . . . . . . . . . . . . . . 17 +- 3. Overview. . . . . . . . . . . . . . . . . . . . . . . . . . . 17 +- 3.1. SCSI Concepts. . . . . . . . . . . . . . . . . . . . . 17 +- 3.2. iSCSI Concepts and Functional Overview . . . . . . . . 18 +- 3.2.1. Layers and Sessions. . . . . . . . . . . . . 19 +- 3.2.2. Ordering and iSCSI Numbering . . . . . . . . 19 +- 3.2.2.1. Command Numbering and +- Acknowledging . . . . . . . . . . 20 +- 3.2.2.2. Response/Status Numbering and +- Acknowledging . . . . . . . . . . 23 +- 3.2.2.3. Data Sequencing . . . . . . . . 24 +- 3.2.3. iSCSI Login. . . . . . . . . . . . . . . . . 24 +- 3.2.4. iSCSI Full Feature Phase . . . . . . . . . . 25 +- 3.2.4.1. Command Connection Allegiance . . 26 +- 3.2.4.2. Data Transfer Overview. . . . . . 27 +- 3.2.4.3. Tags and Integrity Checks . . . . 28 +- 3.2.4.4. Task Management . . . . . . . . . 28 +- 3.2.5. iSCSI Connection Termination . . . . . . . . 29 +- 3.2.6. iSCSI Names. . . . . . . . . . . . . . . . . 29 +- 3.2.6.1. iSCSI Name Properties . . . . . . 30 +- 3.2.6.2. iSCSI Name Encoding . . . . . . . 31 +- 3.2.6.3. iSCSI Name Structure. . . . . . . 32 +- 3.2.6.3.1. Type "iqn." (iSCSI +- Qualified Name) . . . 32 +- 3.2.6.3.2. Type "eui." (IEEE +- EUI-64 format). . . . 34 +- 3.2.7. Persistent State . . . . . . . . . . . . . . 34 +- 3.2.8. Message Synchronization and Steering . . . . 35 +- 3.2.8.1. Sync/Steering and iSCSI PDU +- Length . . . . . . . . . . . . . 36 +- 3.3. iSCSI Session Types. . . . . . . . . . . . . . . . . . 36 +- 3.4. SCSI to iSCSI Concepts Mapping Model . . . . . . . . . 37 +- 3.4.1. iSCSI Architecture Model . . . . . . . . . . 37 +- 3.4.2. SCSI Architecture Model. . . . . . . . . . . 39 +- 3.4.3. Consequences of the Model. . . . . . . . . . 41 +- 3.4.3.1. I_T Nexus State . . . . . . . . . 42 +- 3.5. Request/Response Summary . . . . . . . . . . . . . . . 42 +- 3.5.1. Request/Response Types Carrying SCSI Payload 43 +- 3.5.1.1. SCSI-Command . . . . . . . . . . 43 +- +- +- +-Satran, et al. Standards Track [Page 2] +- +-RFC 3720 iSCSI April 2004 +- +- +- 3.5.1.2. SCSI-Response . . . . . . . . . 43 +- 3.5.1.3. Task Management Function Request. 44 +- 3.5.1.4. Task Management Function Response 44 +- 3.5.1.5. SCSI Data-Out and SCSI Data-In. . 44 +- 3.5.1.6. Ready To Transfer (R2T) . . . . . 45 +- 3.5.2. Requests/Responses carrying SCSI and iSCSI +- Payload. . . . . . . . . . . . . . . . . . . 46 +- 3.5.2.1. Asynchronous Message. . . . . . . 46 +- 3.5.3. Requests/Responses Carrying iSCSI Only +- Payload. . . . . . . . . . . . . . . . . . . 46 +- 3.5.3.1. Text Request and Text Response. . 46 +- 3.5.3.2. Login Request and Login Response. 47 +- 3.5.3.3. Logout Request and Response . . . 47 +- 3.5.3.4. SNACK Request . . . . . . . . . . 48 +- 3.5.3.5. Reject. . . . . . . . . . . . . . 48 +- 3.5.3.6. NOP-Out Request and NOP-In +- Response . . . . . . . . . . . . 48 +- 4. SCSI Mode Parameters for iSCSI. . . . . . . . . . . . . . . . 48 +- 5. Login and Full Feature Phase Negotiation. . . . . . . . . . . 48 +- 5.1. Text Format. . . . . . . . . . . . . . . . . . . . . . 50 +- 5.2. Text Mode Negotiation. . . . . . . . . . . . . . . . . 53 +- 5.2.1. List negotiations. . . . . . . . . . . . . . 56 +- 5.2.2. Simple-value Negotiations. . . . . . . . . . 56 +- 5.3. Login Phase. . . . . . . . . . . . . . . . . . . . . . 57 +- 5.3.1. Login Phase Start. . . . . . . . . . . . . . 60 +- 5.3.2. iSCSI Security Negotiation . . . . . . . . . 62 +- 5.3.3. Operational Parameter Negotiation During +- the Login Phase. . . . . . . . . . . . . . . 63 +- 5.3.4. Connection Reinstatement . . . . . . . . . . 64 +- 5.3.5. Session Reinstatement, Closure, and Timeout. 64 +- 5 5.3.5.1. Loss of Nexus +- Notification. . . . . 65 +- 5.3.6. Session Continuation and Failure . . . . . . 65 +- 5.4. Operational Parameter Negotiation Outside the Login +- Phase. . . . . . . . . . . . . . . . . . . . . . . . . 66 +- 6. iSCSI Error Handling and Recovery . . . . . . . . . . . . . . 67 +- 6.1. Overview . . . . . . . . . . . . . . . . . . . . . . . 67 +- 6.1.1. Background . . . . . . . . . . . . . . . . . 67 +- 6.1.2. Goals. . . . . . . . . . . . . . . . . . . . 67 +- 6.1.3. Protocol Features and State Expectations . . 68 +- 6.1.4. Recovery Classes . . . . . . . . . . . . . . 69 +- 6.1.4.1. Recovery Within-command . . . . . 69 +- 6.1.4.2. Recovery Within-connection. . . . 70 +- 6.1.4.3. Connection Recovery . . . . . . . 71 +- 6.1.4.4. Session Recovery. . . . . . . . . 72 +- 6.1.5. Error Recovery Hierarchy . . . . . . . . . . . 72 +- 6.2. Retry and Reassign in Recovery . . . . . . . . . . . . 74 +- 6.2.1. Usage of Retry . . . . . . . . . . . . . . . 74 +- +- +- +-Satran, et al. Standards Track [Page 3] +- +-RFC 3720 iSCSI April 2004 +- +- +- 6.2.2. Allegiance Reassignment. . . . . . . . . . . 75 +- 6.3. Usage Of Reject PDU in Recovery. . . . . . . . . . . . 76 +- 6.4. Connection Timeout Management. . . . . . . . . . . . . 76 +- 6.4.1. Timeouts on Transport Exception Events . . . 77 +- 6.4.2. Timeouts on Planned Decommissioning. . . . . 77 +- 6.5. Implicit Termination of Tasks. . . . . . . . . . . . . 77 +- 6.6. Format Errors. . . . . . . . . . . . . . . . . . . . . 78 +- 6.7. Digest Errors. . . . . . . . . . . . . . . . . . . . . 78 +- 6.8. Sequence Errors. . . . . . . . . . . . . . . . . . . . 80 +- 6.9. SCSI Timeouts. . . . . . . . . . . . . . . . . . . . . 81 +- 6.10. Negotiation Failures . . . . . . . . . . . . . . . . . 81 +- 6.11. Protocol Errors. . . . . . . . . . . . . . . . . . . . 82 +- 6.12. Connection Failures. . . . . . . . . . . . . . . . . . 82 +- 6.13. Session Errors . . . . . . . . . . . . . . . . . . . . 83 +- 7. State Transitions . . . . . . . . . . . . . . . . . . . . . . 84 +- 7.1. Standard Connection State Diagrams . . . . . . . . . . 84 +- 7.1.1. State Descriptions for Initiators and +- Targets. . . . . . . . . . . . . . . . . . . 84 +- 7.1.2. State Transition Descriptions for Initiators +- and Targets. . . . . . . . . . . . . . . . . 85 +- 7.1.3. Standard Connection State Diagram for an +- Initiator. . . . . . . . . . . . . . . . . . 88 +- 7.1.4. Standard Connection State Diagram for a +- Target . . . . . . . . . . . . . . . . . . . 90 +- 7.2. Connection Cleanup State Diagram for Initiators and +- Targets. . . . . . . . . . . . . . . . . . . . . . . . 92 +- 7.2.1. State Descriptions for Initiators and +- Targets. . . . . . . . . . . . . . . . . . . 94 +- 7.2.2. State Transition Descriptions for Initiators +- and Targets. . . . . . . . . . . . . . . . . 94 +- 7.3. Session State Diagrams . . . . . . . . . . . . . . . . 95 +- 7.3.1. Session State Diagram for an Initiator . . . 95 +- 7.3.2. Session State Diagram for a Target . . . . . 96 +- 7.3.3. State Descriptions for Initiators and +- Targets. . . . . . . . . . . . . . . . . . . 97 +- 7.3.4. State Transition Descriptions for Initiators +- and Targets. . . . . . . . . . . . . . . . . 98 +- 8. Security Considerations . . . . . . . . . . . . . . . . . . . 99 +- 8.1. iSCSI Security Mechanisms. . . . . . . . . . . . . . . 100 +- 8.2. In-band Initiator-Target Authentication. . . . . . . . 100 +- 8.2.1. CHAP Considerations. . . . . . . . . . . . . 101 +- 8.2.2. SRP Considerations . . . . . . . . . . . . . 103 +- 8.3. IPsec. . . . . . . . . . . . . . . . . . . . . . . . . 104 +- 8.3.1. Data Integrity and Authentication. . . . . . 104 +- 8.3.2. Confidentiality. . . . . . . . . . . . . . . 105 +- 8.3.3. Policy, Security Associations, and +- Cryptographic Key Management . . . . . . . . 105 +- 9. Notes to Implementers . . . . . . . . . . . . . . . . . . . . 106 +- +- +- +-Satran, et al. Standards Track [Page 4] +- +-RFC 3720 iSCSI April 2004 +- +- +- 9.1. Multiple Network Adapters. . . . . . . . . . . . . . . 106 +- 9.1.1. Conservative Reuse of ISIDs. . . . . . . . . 107 +- 9.1.2. iSCSI Name, ISID, and TPGT Use . . . . . . . 107 +- 9.2. Autosense and Auto Contingent Allegiance (ACA) . . . . 109 +- 9.3. iSCSI Timeouts . . . . . . . . . . . . . . . . . . . . 109 +- 9.4. Command Retry and Cleaning Old Command Instances . . . 110 +- 9.5. Synch and Steering Layer and Performance . . . . . . . 110 +- 9.6. Considerations for State-dependent Devices and +- Long-lasting SCSI Operations . . . . . . . . . . . . . 111 +- 9.6.1. Determining the Proper ErrorRecoveryLevel. . 112 +- 10. iSCSI PDU Formats . . . . . . . . . . . . . . . . . . . . . . 112 +- 10.1. iSCSI PDU Length and Padding . . . . . . . . . . . . . 113 +- 10.2. PDU Template, Header, and Opcodes. . . . . . . . . . . 113 +- 10.2.1. Basic Header Segment (BHS) . . . . . . . . . 114 +- 10.2.1.1. I . . . . . . . . . . . . . . . . 115 +- 10.2.1.2. Opcode. . . . . . . . . . . . . . 115 +- 10.2.1.3. Final (F) bit . . . . . . . . . . 116 +- 10.2.1.4. Opcode-specific Fields. . . . . . 116 +- 10.2.1.5. TotalAHSLength. . . . . . . . . . 116 +- 10.2.1.6. DataSegmentLength . . . . . . . . 116 +- 10.2.1.7. LUN . . . . . . . . . . . . . . . 116 +- 10.2.1.8. Initiator Task Tag. . . . . . . . 117 +- 10.2.2. Additional Header Segment (AHS) . . . . . . . 117 +- 10.2.2.1. AHSType . . . . . . . . . . . . . 117 +- 10.2.2.2. AHSLength . . . . . . . . . . . . 117 +- 10.2.2.3. Extended CDB AHS. . . . . . . . . 118 +- 10.2.2.4. Bidirectional Expected Read-Data +- Length AHS. . . . . . . . . . . . 118 +- 10.2.3. Header Digest and Data Digest. . . . . . . . 118 +- 10.2.4. Data Segment . . . . . . . . . . . . . . . . 119 +- 10.3. SCSI Command . . . . . . . . . . . . . . . . . . . . . 119 +- 10.3.1. Flags and Task Attributes (byte 1) . . . . . 120 +- 10.3.2. CmdSN - Command Sequence Number. . . . . . . 120 +- 10.3.3. ExpStatSN. . . . . . . . . . . . . . . . . . 120 +- 10.3.4. Expected Data Transfer Length. . . . . . . . 121 +- 10.3.5. CDB - SCSI Command Descriptor Block. . . . . 121 +- 10.3.6. Data Segment - Command Data. . . . . . . . . 121 +- 10.4. SCSI Response. . . . . . . . . . . . . . . . . . . . . 122 +- 10.4.1. Flags (byte 1) . . . . . . . . . . . . . . . 123 +- 10.4.2. Status . . . . . . . . . . . . . . . . . . . 123 +- 10.4.3. Response . . . . . . . . . . . . . . . . . . 124 +- 10.4.4. SNACK Tag. . . . . . . . . . . . . . . . . . 125 +- 10.4.5. Residual Count . . . . . . . . . . . . . . . 125 +- 10.4.6. Bidirectional Read Residual Count. . . . . . 125 +- 10.4.7. Data Segment - Sense and Response Data +- Segment. . . . . . . . . . . . . . . . . . . 125 +- 10.4.7.1. SenseLength . . . . . . . . . . . 126 +- 10.4.7.2. Sense Data. . . . . . . . . . . . 126 +- +- +- +-Satran, et al. Standards Track [Page 5] +- +-RFC 3720 iSCSI April 2004 +- +- +- 10.4.8. ExpDataSN. . . . . . . . . . . . . . . . . . 127 +- 10.4.9. StatSN - Status Sequence Number. . . . . . . 127 +- 10.4.10. ExpCmdSN - Next Expected CmdSN from this +- Initiator. . . . . . . . . . . . . . . . . . 128 +- 10.4.11. MaxCmdSN - Maximum CmdSN from this Initiator 128 +- 10.5. Task Management Function Request . . . . . . . . . . . 129 +- 10.5.1. Function . . . . . . . . . . . . . . . . . . 129 +- 10.5.2. TotalAHSLength and DataSegmentLength . . . . 132 +- 10.5.3. LUN. . . . . . . . . . . . . . . . . . . . . 132 +- 10.5.4. Referenced Task Tag. . . . . . . . . . . . . 132 +- 10.5.5. RefCmdSN . . . . . . . . . . . . . . . . . . 132 +- 10.5.6. ExpDataSN. . . . . . . . . . . . . . . . . . 133 +- 10.6. Task Management Function Response. . . . . . . . . . . 134 +- 10.6.1. Response . . . . . . . . . . . . . . . . . . 134 +- 10.6.2. Task Management Actions on Task Sets . . . . 136 +- 10.6.3. TotalAHSLength and DataSegmentLength . . . . 137 +- 10.7. SCSI Data-Out & SCSI Data-In . . . . . . . . . . . . . 137 +- 10.7.1. F (Final) Bit. . . . . . . . . . . . . . . . 139 +- 10.7.2. A (Acknowledge) Bit. . . . . . . . . . . . . 139 +- 10.7.3. Flags (byte 1) . . . . . . . . . . . . . . . 140 +- 10.7.4. Target Transfer Tag and LUN. . . . . . . . . 140 +- 10.7.5. DataSN . . . . . . . . . . . . . . . . . . . 141 +- 10.7.6. Buffer Offset. . . . . . . . . . . . . . . . 141 +- 10.7.7. DataSegmentLength. . . . . . . . . . . . . . 141 +- 10.8. Ready To Transfer (R2T). . . . . . . . . . . . . . . . 142 +- 10.8.1. TotalAHSLength and DataSegmentLength . . . . 143 +- 10.8.2. R2TSN. . . . . . . . . . . . . . . . . . . . 143 +- 10.8.3. StatSN . . . . . . . . . . . . . . . . . . . 144 +- 10.8.4. Desired Data Transfer Length and Buffer +- Offset . . . . . . . . . . . . . . . . . . . 144 +- 10.8.5. Target Transfer Tag. . . . . . . . . . . . . 144 +- 10.9. Asynchronous Message . . . . . . . . . . . . . . . . . 145 +- 10.9.1. AsyncEvent . . . . . . . . . . . . . . . . . 146 +- 10.9.2. AsyncVCode . . . . . . . . . . . . . . . . . 147 +- 10.9.3. LUN. . . . . . . . . . . . . . . . . . . . . 147 +- 10.9.4. Sense Data and iSCSI Event Data. . . . . . . 148 +- 10.9.4.1. SenseLength . . . . . . . . . . . 148 +- 10.10. Text Request . . . . . . . . . . . . . . . . . . . . . 149 +- 10.10.1. F (Final) Bit. . . . . . . . . . . . . . . . 150 +- 10.10.2. C (Continue) Bit . . . . . . . . . . . . . . 150 +- 10.10.3. Initiator Task Tag . . . . . . . . . . . . . 150 +- 10.10.4. Target Transfer Tag. . . . . . . . . . . . . 150 +- 10.10.5. Text . . . . . . . . . . . . . . . . . . . . 151 +- 10.11. Text Response. . . . . . . . . . . . . . . . . . . . . 152 +- 10.11.1. F (Final) Bit. . . . . . . . . . . . . . . . 152 +- 10.11.2. C (Continue) Bit . . . . . . . . . . . . . . 153 +- 10.11.3. Initiator Task Tag . . . . . . . . . . . . . 153 +- 10.11.4. Target Transfer Tag. . . . . . . . . . . . . 153 +- +- +- +-Satran, et al. Standards Track [Page 6] +- +-RFC 3720 iSCSI April 2004 +- +- +- 10.11.5. StatSN . . . . . . . . . . . . . . . . . . . 154 +- 10.11.6. Text Response Data . . . . . . . . . . . . . 154 +- 10.12. Login Request. . . . . . . . . . . . . . . . . . . . . 154 +- 10.12.1. T (Transit) Bit. . . . . . . . . . . . . . . 155 +- 10.12.2. C (Continue) Bit . . . . . . . . . . . . . . 155 +- 10.12.3. CSG and NSG. . . . . . . . . . . . . . . . . 156 +- 10.12.4. Version. . . . . . . . . . . . . . . . . . . 156 +- 10.12.4.1. Version-max. . . . . . . . . . . 156 +- 10.12.4.2. Version-min. . . . . . . . . . . 156 +- 10.12.5. ISID . . . . . . . . . . . . . . . . . . . . 157 +- 10.12.6. TSIH . . . . . . . . . . . . . . . . . . . . 158 +- 10.12.7. Connection ID - CID. . . . . . . . . . . . . 158 +- 10.12.8. CmdSN. . . . . . . . . . . . . . . . . . . . 159 +- 10.12.9. ExpStatSN. . . . . . . . . . . . . . . . . . 159 +- 10.12.10. Login Parameters . . . . . . . . . . . . . . 159 +- 10.13. Login Response . . . . . . . . . . . . . . . . . . . . 160 +- 10.13.1. Version-max. . . . . . . . . . . . . . . . . 160 +- 10.13.2. Version-active . . . . . . . . . . . . . . . 161 +- 10.13.3. TSIH . . . . . . . . . . . . . . . . . . . . 161 +- 10.13.4. StatSN . . . . . . . . . . . . . . . . . . . 161 +- 10.13.5. Status-Class and Status-Detail . . . . . . . 161 +- 10.13.6. T (Transit) Bit. . . . . . . . . . . . . . . 164 +- 10.13.7. C (Continue) Bit . . . . . . . . . . . . . . 164 +- 10.13.8. Login Parameters . . . . . . . . . . . . . . 164 +- 10.14. Logout Request . . . . . . . . . . . . . . . . . . . . 165 +- 10.14.1. Reason Code. . . . . . . . . . . . . . . . . 167 +- 10.14.2. TotalAHSLength and DataSegmentLength . . . . 168 +- 10.14.3. CID. . . . . . . . . . . . . . . . . . . . . 168 +- 10.14.4. ExpStatSN. . . . . . . . . . . . . . . . . . 168 +- 10.14.5. Implicit termination of tasks. . . . . . . . 168 +- 10.15. Logout Response. . . . . . . . . . . . . . . . . . . . 169 +- 10.15.1. Response . . . . . . . . . . . . . . . . . . 170 +- 10.15.2. TotalAHSLength and DataSegmentLength . . . . 170 +- 10.15.3. Time2Wait. . . . . . . . . . . . . . . . . . 170 +- 10.15.4. Time2Retain. . . . . . . . . . . . . . . . . 170 +- 10.16. SNACK Request. . . . . . . . . . . . . . . . . . . . . 171 +- 10.16.1. Type . . . . . . . . . . . . . . . . . . . . 172 +- 10.16.2. Data Acknowledgement . . . . . . . . . . . . 173 +- 10.16.3. Resegmentation . . . . . . . . . . . . . . . 173 +- 10.16.4. Initiator Task Tag . . . . . . . . . . . . . 174 +- 10.16.5. Target Transfer Tag or SNACK Tag . . . . . . 174 +- 10.16.6. BegRun . . . . . . . . . . . . . . . . . . . 174 +- 10.16.7. RunLength. . . . . . . . . . . . . . . . . . 174 +- 10.17. Reject . . . . . . . . . . . . . . . . . . . . . . . . 175 +- 10.17.1. Reason . . . . . . . . . . . . . . . . . . . 176 +- 10.17.2. DataSN/R2TSN . . . . . . . . . . . . . . . . 177 +- 10.17.3. StatSN, ExpCmdSN and MaxCmdSN. . . . . . . . 177 +- 10.17.4. Complete Header of Bad PDU . . . . . . . . . 177 +- +- +- +-Satran, et al. Standards Track [Page 7] +- +-RFC 3720 iSCSI April 2004 +- +- +- 10.18. NOP-Out. . . . . . . . . . . . . . . . . . . . . . . . 178 +- 10.18.1. Initiator Task Tag . . . . . . . . . . . . . 179 +- 10.18.2. Target Transfer Tag. . . . . . . . . . . . . 179 +- 10.18.3. Ping Data. . . . . . . . . . . . . . . . . . 179 +- 10.19. NOP-In . . . . . . . . . . . . . . . . . . . . . . . . 180 +- 10.19.1. Target Transfer Tag. . . . . . . . . . . . . 181 +- 10.19.2. StatSN . . . . . . . . . . . . . . . . . . . 181 +- 10.19.3. LUN. . . . . . . . . . . . . . . . . . . . . 181 +- 11. iSCSI Security Text Keys and Authentication Methods . . . . . 181 +- 11.1. AuthMethod . . . . . . . . . . . . . . . . . . . . . . 182 +- 11.1.1. Kerberos . . . . . . . . . . . . . . . . . . 184 +- 11.1.2. Simple Public-Key Mechanism (SPKM) . . . . . 184 +- 11.1.3. Secure Remote Password (SRP) . . . . . . . . 185 +- 11.1.4. Challenge Handshake Authentication Protocol +- (CHAP) . . . . . . . . . . . . . . . . . . . 186 +- 12. Login/Text Operational Text Keys. . . . . . . . . . . . . . . 187 +- 12.1. HeaderDigest and DataDigest. . . . . . . . . . . . . . 188 +- 12.2. MaxConnections . . . . . . . . . . . . . . . . . . . . 190 +- 12.3. SendTargets. . . . . . . . . . . . . . . . . . . . . . 191 +- 12.4. TargetName . . . . . . . . . . . . . . . . . . . . . . 191 +- 12.5. InitiatorName. . . . . . . . . . . . . . . . . . . . . 192 +- 12.6. TargetAlias. . . . . . . . . . . . . . . . . . . . . . 192 +- 12.7. InitiatorAlias . . . . . . . . . . . . . . . . . . . . 193 +- 12.8. TargetAddress. . . . . . . . . . . . . . . . . . . . . 193 +- 12.9. TargetPortalGroupTag . . . . . . . . . . . . . . . . . 194 +- 12.10. InitialR2T . . . . . . . . . . . . . . . . . . . . . . 194 +- 12.11. ImmediateData. . . . . . . . . . . . . . . . . . . . . 195 +- 12.12. MaxRecvDataSegmentLength . . . . . . . . . . . . . . . 196 +- 12.13. MaxBurstLength . . . . . . . . . . . . . . . . . . . . 196 +- 12.14. FirstBurstLength . . . . . . . . . . . . . . . . . . . 197 +- 12.15. DefaultTime2Wait . . . . . . . . . . . . . . . . . . . 197 +- 12.16. DefaultTime2Retain . . . . . . . . . . . . . . . . . . 198 +- 12.17. MaxOutstandingR2T. . . . . . . . . . . . . . . . . . . 198 +- 12.18. DataPDUInOrder . . . . . . . . . . . . . . . . . . . . 198 +- 12.19. DataSequenceInOrder. . . . . . . . . . . . . . . . . . 199 +- 12.20. ErrorRecoveryLevel . . . . . . . . . . . . . . . . . . 199 +- 12.21. SessionType. . . . . . . . . . . . . . . . . . . . . . 200 +- 12.22. The Private or Public Extension Key Format . . . . . . 200 +- 13. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 201 +- 13.1. Naming Requirements. . . . . . . . . . . . . . . . . . 203 +- 13.2. Mechanism Specification Requirements . . . . . . . . . 203 +- 13.3. Publication Requirements . . . . . . . . . . . . . . . 203 +- 13.4. Security Requirements. . . . . . . . . . . . . . . . . 203 +- 13.5. Registration Procedure . . . . . . . . . . . . . . . . 204 +- 13.5.1. Present the iSCSI extension item to the +- Community. . . . . . . . . . . . . . . . . . 204 +- 13.5.2. iSCSI extension item review and IESG +- approval . . . . . . . . . . . . . . . . . . 204 +- +- +- +-Satran, et al. Standards Track [Page 8] +- +-RFC 3720 iSCSI April 2004 +- +- +- 13.5.3. IANA Registration. . . . . . . . . . . . . . 204 +- 13.5.4. Standard iSCSI extension item-label format . 204 +- 13.6. IANA Procedures for Registering iSCSI extension items. 205 +- References. . . . . . . . . . . . . . . . . . . . . . . . . . . . 205 +- Appendix A. Sync and Steering with Fixed Interval Markers . . . . 209 +- A.1. Markers At Fixed Intervals . . . . . . . . . . . . . . 209 +- A.2. Initial Marker-less Interval . . . . . . . . . . . . . 210 +- A.3. Negotiation. . . . . . . . . . . . . . . . . . . . . . 210 +- A.3.1. OFMarker, IFMarker . . . . . . . . . . . . . 210 +- A.3.2. OFMarkInt, IFMarkInt . . . . . . . . . . . . 211 +- Appendix B. Examples . . . . . . . . . . . . . . . . . . . . . . 212 +- B.1. Read Operation Example . . . . . . . . . . . . . . . . 212 +- B.2. Write Operation Example. . . . . . . . . . . . . . . . 213 +- B.3. R2TSN/DataSN Use Examples. . . . . . . . . . . . . . . 214 +- B.4. CRC Examples . . . . . . . . . . . . . . . . . . . . . 217 +- Appendix C. Login Phase Examples . . . . . . . . . . . . . . . . 219 +- Appendix D. SendTargets Operation. . . . . . . . . . . . . . . . 229 +- Appendix E. Algorithmic Presentation of Error Recovery Classes . 233 +- E.1. General Data Structure and Procedure Description . . . 233 +- E.2. Within-command Error Recovery Algorithms . . . . . . . 234 +- E.2.1. Procedure Descriptions . . . . . . . . . . . 234 +- E.2.2. Initiator Algorithms . . . . . . . . . . . . 235 +- E.2.3. Target Algorithms. . . . . . . . . . . . . . 237 +- E.3. Within-connection Recovery Algorithms. . . . . . . . . 240 +- E.3.1. Procedure Descriptions . . . . . . . . . . . 240 +- E.3.2. Initiator Algorithms . . . . . . . . . . . . 241 +- E.3.3. Target Algorithms. . . . . . . . . . . . . . 243 +- E.4. Connection Recovery Algorithms . . . . . . . . . . . . 243 +- E.4.1. Procedure Descriptions . . . . . . . . . . . 243 +- E.4.2. Initiator Algorithms . . . . . . . . . . . . 244 +- E.4.3. Target Algorithms. . . . . . . . . . . . . . 246 +- Appendix F. Clearing Effects of Various Events on Targets. . . . 249 +- F.1. Clearing Effects on iSCSI Objects. . . . . . . . . . . 249 +- F.2. Clearing Effects on SCSI Objects . . . . . . . . . . . 253 +- Acknowledgements. . . . . . . . . . . . . . . . . . . . . . . . . 254 +- Authors' Addresses. . . . . . . . . . . . . . . . . . . . . . . . 256 +- Full Copyright Statement. . . . . . . . . . . . . . . . . . . . . 257 +- +-1. Introduction +- +- The Small Computer Systems Interface (SCSI) is a popular family of +- protocols for communicating with I/O devices, especially storage +- devices. SCSI is a client-server architecture. Clients of a SCSI +- interface are called "initiators". Initiators issue SCSI "commands" +- to request services from components, logical units of a server known +- as a "target". A "SCSI transport" maps the client-server SCSI +- protocol to a specific interconnect. An Initiator is one endpoint of +- a SCSI transport and a target is the other endpoint. +- +- +- +-Satran, et al. Standards Track [Page 9] +- +-RFC 3720 iSCSI April 2004 +- +- +- The SCSI protocol has been mapped over various transports, including +- Parallel SCSI, IPI, IEEE-1394 (firewire) and Fibre Channel. These +- transports are I/O specific and have limited distance capabilities. +- +- The iSCSI protocol defined in this document describes a means of +- transporting SCSI packets over TCP/IP (see [RFC791], [RFC793], +- [RFC1035], [RFC1122]), providing for an interoperable solution which +- can take advantage of existing Internet infrastructure, Internet +- management facilities, and address distance limitations. +- +-2. Definitions and Acronyms +- +-2.1. Definitions +- +- - Alias: An alias string can also be associated with an iSCSI Node. +- The alias allows an organization to associate a user-friendly +- string with the iSCSI Name. However, the alias string is not a +- substitute for the iSCSI Name. +- +- - CID (Connection ID): Connections within a session are identified by +- a connection ID. It is a unique ID for this connection within the +- session for the initiator. It is generated by the initiator and +- presented to the target during login requests and during logouts +- that close connections. +- +- - Connection: A connection is a TCP connection. Communication +- between the initiator and target occurs over one or more TCP +- connections. The TCP connections carry control messages, SCSI +- commands, parameters, and data within iSCSI Protocol Data Units +- (iSCSI PDUs). +- +- - iSCSI Device: A SCSI Device using an iSCSI service delivery +- subsystem. Service Delivery Subsystem is defined by [SAM2] as a +- transport mechanism for SCSI commands and responses. +- +- - iSCSI Initiator Name: The iSCSI Initiator Name specifies the +- worldwide unique name of the initiator. +- +- - iSCSI Initiator Node: The "initiator". The word "initiator" has +- been appropriately qualified as either a port or a device in the +- rest of the document when the context is ambiguous. All +- unqualified usages of "initiator" refer to an initiator port (or +- device) depending on the context. +- +- - iSCSI Layer: This layer builds/receives iSCSI PDUs and +- relays/receives them to/from one or more TCP connections that form +- an initiator-target "session". +- +- +- +- +-Satran, et al. Standards Track [Page 10] +- +-RFC 3720 iSCSI April 2004 +- +- +- - iSCSI Name: The name of an iSCSI initiator or iSCSI target. +- +- - iSCSI Node: The iSCSI Node represents a single iSCSI initiator or +- iSCSI target. There are one or more iSCSI Nodes within a Network +- Entity. The iSCSI Node is accessible via one or more Network +- Portals. An iSCSI Node is identified by its iSCSI Name. The +- separation of the iSCSI Name from the addresses used by and for the +- iSCSI Node allows multiple iSCSI Nodes to use the same address, and +- the same iSCSI Node to use multiple addresses. +- +- - iSCSI Target Name: The iSCSI Target Name specifies the worldwide +- unique name of the target. +- +- - iSCSI Target Node: The "target". +- +- - iSCSI Task: An iSCSI task is an iSCSI request for which a response +- is expected. +- +- - iSCSI Transfer Direction: The iSCSI transfer direction is defined +- with regard to the initiator. Outbound or outgoing transfers are +- transfers from the initiator to the target, while inbound or +- incoming transfers are from the target to the initiator. +- +- - ISID: The initiator part of the Session Identifier. It is +- explicitly specified by the initiator during Login. +- +- - I_T nexus: According to [SAM2], the I_T nexus is a relationship +- between a SCSI Initiator Port and a SCSI Target Port. For iSCSI, +- this relationship is a session, defined as a relationship between +- an iSCSI Initiator's end of the session (SCSI Initiator Port) and +- the iSCSI Target's Portal Group. The I_T nexus can be identified +- by the conjunction of the SCSI port names; that is, the I_T nexus +- identifier is the tuple (iSCSI Initiator Name + ',i,'+ ISID, iSCSI +- Target Name + ',t,'+ Portal Group Tag). +- +- - Network Entity: The Network Entity represents a device or gateway +- that is accessible from the IP network. A Network Entity must have +- one or more Network Portals, each of which can be used to gain +- access to the IP network by some iSCSI Nodes contained in that +- Network Entity. +- +- - Network Portal: The Network Portal is a component of a Network +- Entity that has a TCP/IP network address and that may be used by an +- iSCSI Node within that Network Entity for the connection(s) within +- one of its iSCSI sessions. A Network Portal in an initiator is +- identified by its IP address. A Network Portal in a target is +- identified by its IP address and its listening TCP port. +- +- +- +- +-Satran, et al. Standards Track [Page 11] +- +-RFC 3720 iSCSI April 2004 +- +- +- - Originator: In a negotiation or exchange, the party that initiates +- the negotiation or exchange. +- +- - PDU (Protocol Data Unit): The initiator and target divide their +- communications into messages. The term "iSCSI protocol data unit" +- (iSCSI PDU) is used for these messages. +- +- - Portal Groups: iSCSI supports multiple connections within the same +- session; some implementations will have the ability to combine +- connections in a session across multiple Network Portals. A Portal +- Group defines a set of Network Portals within an iSCSI Network +- Entity that collectively supports the capability of coordinating a +- session with connections spanning these portals. Not all Network +- Portals within a Portal Group need participate in every session +- connected through that Portal Group. One or more Portal Groups may +- provide access to an iSCSI Node. Each Network Portal, as utilized +- by a given iSCSI Node, belongs to exactly one portal group within +- that node. +- +- - Portal Group Tag: This 16-bit quantity identifies a Portal Group +- within an iSCSI Node. All Network Portals with the same portal +- group tag in the context of a given iSCSI Node are in the same +- Portal Group. +- +- - Recovery R2T: An R2T generated by a target upon detecting the loss +- of one or more Data-Out PDUs through one of the following means: a +- digest error, a sequence error, or a sequence reception timeout. A +- recovery R2T carries the next unused R2TSN, but requests all or +- part of the data burst that an earlier R2T (with a lower R2TSN) had +- already requested. +- +- - Responder: In a negotiation or exchange, the party that responds to +- the originator of the negotiation or exchange. +- +- - SCSI Device: This is the SAM2 term for an entity that contains one +- or more SCSI ports that are connected to a service delivery +- subsystem and supports a SCSI application protocol. For example, a +- SCSI Initiator Device contains one or more SCSI Initiator Ports and +- zero or more application clients. A Target Device contains one or +- more SCSI Target Ports and one or more device servers and +- associated logical units. For iSCSI, the SCSI Device is the +- component within an iSCSI Node that provides the SCSI +- functionality. As such, there can be at most, one SCSI Device +- within a given iSCSI Node. Access to the SCSI Device can only be +- achieved in an iSCSI normal operational session. The SCSI Device +- Name is defined to be the iSCSI Name of the node. +- +- +- +- +- +-Satran, et al. Standards Track [Page 12] +- +-RFC 3720 iSCSI April 2004 +- +- +- - SCSI Layer: This builds/receives SCSI CDBs (Command Descriptor +- Blocks) and relays/receives them with the remaining command execute +- [SAM2] parameters to/from the iSCSI Layer. +- +- - Session: The group of TCP connections that link an initiator with a +- target form a session (loosely equivalent to a SCSI I-T nexus). +- TCP connections can be added and removed from a session. Across +- all connections within a session, an initiator sees one and the +- same target. +- +- - SCSI Initiator Port: This maps to the endpoint of an iSCSI normal +- operational session. An iSCSI normal operational session is +- negotiated through the login process between an iSCSI initiator +- node and an iSCSI target node. At successful completion of this +- process, a SCSI Initiator Port is created within the SCSI Initiator +- Device. The SCSI Initiator Port Name and SCSI Initiator Port +- Identifier are both defined to be the iSCSI Initiator Name together +- with (a) a label that identifies it as an initiator port +- name/identifier and (b) the ISID portion of the session identifier. +- +- - SCSI Port: This is the SAM2 term for an entity in a SCSI Device +- that provides the SCSI functionality to interface with a service +- delivery subsystem. For iSCSI, the definition of the SCSI +- Initiator Port and the SCSI Target Port are different. +- +- - SCSI Port Name: A name made up as UTF-8 [RFC2279] characters and +- includes the iSCSI Name + 'i' or 't' + ISID or Portal Group Tag. +- +- +- - SCSI Target Port: This maps to an iSCSI Target Portal Group. +- +- - SCSI Target Port Name and SCSI Target Port Identifier: These are +- both defined to be the iSCSI Target Name together with (a) a label +- that identifies it as a target port name/identifier and (b) the +- portal group tag. +- +- - SSID (Session ID): A session between an iSCSI initiator and an +- iSCSI target is defined by a session ID that is a tuple composed of +- an initiator part (ISID) and a target part (Target Portal Group +- Tag). The ISID is explicitly specified by the initiator at session +- establishment. The Target Portal Group Tag is implied by the +- initiator through the selection of the TCP endpoint at connection +- establishment. The TargetPortalGroupTag key must also be returned +- by the target as a confirmation during connection establishment +- when TargetName is given. +- +- - Target Portal Group Tag: A numerical identifier (16-bit) for an +- iSCSI Target Portal Group. +- +- +- +-Satran, et al. Standards Track [Page 13] +- +-RFC 3720 iSCSI April 2004 +- +- +- - TSIH (Target Session Identifying Handle): A target assigned tag for +- a session with a specific named initiator. The target generates it +- during session establishment. Its internal format and content are +- not defined by this protocol, except for the value 0 that is +- reserved and used by the initiator to indicate a new session. It +- is given to the target during additional connection establishment +- for the same session. +- +-2.2. Acronyms +- +- Acronym Definition +- ------------------------------------------------------------ +- 3DES Triple Data Encryption Standard +- ACA Auto Contingent Allegiance +- AEN Asynchronous Event Notification +- AES Advanced Encryption Standard +- AH Additional Header (not the IPsec AH!) +- AHS Additional Header Segment +- API Application Programming Interface +- ASC Additional Sense Code +- ASCII American Standard Code for Information Interchange +- ASCQ Additional Sense Code Qualifier +- BHS Basic Header Segment +- CBC Cipher Block Chaining +- CD Compact Disk +- CDB Command Descriptor Block +- CHAP Challenge Handshake Authentication Protocol +- CID Connection ID +- CO Connection Only +- CRC Cyclic Redundancy Check +- CRL Certificate Revocation List +- CSG Current Stage +- CSM Connection State Machine +- DES Data Encryption Standard +- DNS Domain Name Server +- DOI Domain of Interpretation +- DVD Digital Versatile Disk +- ESP Encapsulating Security Payload +- EUI Extended Unique Identifier +- FFP Full Feature Phase +- FFPO Full Feature Phase Only +- FIM Fixed Interval Marker +- Gbps Gigabits per Second +- HBA Host Bus Adapter +- HMAC Hashed Message Authentication Code +- I_T Initiator_Target +- I_T_L Initiator_Target_LUN +- IANA Internet Assigned Numbers Authority +- +- +- +-Satran, et al. Standards Track [Page 14] +- +-RFC 3720 iSCSI April 2004 +- +- +- ID Identifier +- IDN Internationalized Domain Name +- IEEE Institute of Electrical & Electronics Engineers +- IETF Internet Engineering Task Force +- IKE Internet Key Exchange +- I/O Input - Output +- IO Initialize Only +- IP Internet Protocol +- IPsec Internet Protocol Security +- IPv4 Internet Protocol Version 4 +- IPv6 Internet Protocol Version 6 +- IQN iSCSI Qualified Name +- ISID Initiator Session ID +- ITN iSCSI Target Name +- ITT Initiator Task Tag +- KRB5 Kerberos V5 +- LFL Lower Functional Layer +- LTDS Logical-Text-Data-Segment +- LO Leading Only +- LU Logical Unit +- LUN Logical Unit Number +- MAC Message Authentication Codes +- NA Not Applicable +- NIC Network Interface Card +- NOP No Operation +- NSG Next Stage +- OS Operating System +- PDU Protocol Data Unit +- PKI Public Key Infrastructure +- R2T Ready To Transfer +- R2TSN Ready To Transfer Sequence Number +- RDMA Remote Direct Memory Access +- RFC Request For Comments +- SAM SCSI Architecture Model +- SAM2 SCSI Architecture Model - 2 +- SAN Storage Area Network +- SCSI Small Computer Systems Interface +- SN Sequence Number +- SNACK Selective Negative Acknowledgment - also +- Sequence Number Acknowledgement for data +- SPKM Simple Public-Key Mechanism +- SRP Secure Remote Password +- SSID Session ID +- SW Session Wide +- TCB Task Control Block +- TCP Transmission Control Protocol +- TPGT Target Portal Group Tag +- TSIH Target Session Identifying Handle +- +- +- +-Satran, et al. Standards Track [Page 15] +- +-RFC 3720 iSCSI April 2004 +- +- +- TTT Target Transfer Tag +- UFL Upper Functional Layer +- ULP Upper Level Protocol +- URN Uniform Resource Names [RFC2396] +- UTF Universal Transformation Format +- WG Working Group +- +-2.3. Conventions +- +- In examples, "I->" and "T->" show iSCSI PDUs sent by the initiator +- and target respectively. +- +- The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +- "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +- document are to be interpreted as described in BCP 14 [RFC2119]. +- +- iSCSI messages - PDUs - are represented by diagrams as in the +- following example: +- +- Byte/ 0 | 1 | 2 | 3 | +- / | | | | +- |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +- +---------------+---------------+---------------+---------------+ +- 0| Basic Header Segment (BHS) | +- +---------------+---------------+---------------+---------------+ +- ---------- +- +| | +- +---------------+---------------+---------------+---------------+ +- +- The diagrams include byte and bit numbering. +- +- The following representation and ordering rules are observed in this +- document: +- +- - Word Rule +- - Half-word Rule +- - Byte Rule +- +-2.3.1. Word Rule +- +- A word holds four consecutive bytes. Whenever a word has numeric +- content, it is considered an unsigned number in base 2 positional +- representation with the lowest numbered byte (e.g., byte 0) bit 0 +- representing 2**31 and bit 1 representing 2**30 through lowest +- numbered byte + 3 (e.g., byte 3) bit 7 representing 2**0. +- +- Decimal and hexadecimal representation of word values map this +- representation to decimal or hexadecimal positional notation. +- +- +- +-Satran, et al. Standards Track [Page 16] +- +-RFC 3720 iSCSI April 2004 +- +- +-2.3.2. Half-Word Rule +- +- A half-word holds two consecutive bytes. Whenever a half-word has +- numeric content it is considered an unsigned number in base 2 +- positional representation with the lowest numbered byte (e.g., byte +- 0), bit 0 representing 2**15 and bit 1 representing 2**14 through +- lowest numbered byte + 1 (e.g., byte 1), bit 7 representing 2**0. +- +- Decimal and hexadecimal representation of half-word values map this +- representation to decimal or hexadecimal positional notation. +- +-2.3.3. Byte Rule +- +- For every PDU, bytes are sent and received in increasing numbered +- order (network order). +- +- Whenever a byte has numerical content, it is considered an unsigned +- number in base 2 positional representation with bit 0 representing +- 2**7 and bit 1 representing 2**6 through bit 7 representing 2**0. +- +-3. Overview +- +-3.1. SCSI Concepts +- +- The SCSI Architecture Model-2 [SAM2] describes in detail the +- architecture of the SCSI family of I/O protocols. This section +- provides a brief background of the SCSI architecture and is intended +- to familiarize readers with its terminology. +- +- At the highest level, SCSI is a family of interfaces for requesting +- services from I/O devices, including hard drives, tape drives, CD and +- DVD drives, printers, and scanners. In SCSI terminology, an +- individual I/O device is called a "logical unit" (LU). +- +- SCSI is a client-server architecture. Clients of a SCSI interface +- are called "initiators". Initiators issue SCSI "commands" to request +- services from components, logical units, of a server known as a +- "target". The "device server" on the logical unit accepts SCSI +- commands and processes them. +- +- A "SCSI transport" maps the client-server SCSI protocol to a specific +- interconnect. Initiators are one endpoint of a SCSI transport. The +- "target" is the other endpoint. A target can contain multiple +- Logical Units (LUs). Each Logical Unit has an address within a +- target called a Logical Unit Number (LUN). +- +- A SCSI task is a SCSI command or possibly a linked set of SCSI +- commands. Some LUs support multiple pending (queued) tasks, but the +- +- +- +-Satran, et al. Standards Track [Page 17] +- +-RFC 3720 iSCSI April 2004 +- +- +- queue of tasks is managed by the logical unit. The target uses an +- initiator provided "task tag" to distinguish between tasks. Only one +- command in a task can be outstanding at any given time. +- +- Each SCSI command results in an optional data phase and a required +- response phase. In the data phase, information can travel from the +- initiator to target (e.g., WRITE), target to initiator (e.g., READ), +- or in both directions. In the response phase, the target returns the +- final status of the operation, including any errors. +- +- Command Descriptor Blocks (CDB) are the data structures used to +- contain the command parameters that an initiator sends to a target. +- The CDB content and structure is defined by [SAM2] and device-type +- specific SCSI standards. +- +-3.2. iSCSI Concepts and Functional Overview +- +- The iSCSI protocol is a mapping of the SCSI remote procedure +- invocation model (see [SAM2]) over the TCP protocol. SCSI commands +- are carried by iSCSI requests and SCSI responses and status are +- carried by iSCSI responses. iSCSI also uses the request response +- mechanism for iSCSI protocol mechanisms. +- +- For the remainder of this document, the terms "initiator" and +- "target" refer to "iSCSI initiator node" and "iSCSI target node", +- respectively (see Section 3.4.1 iSCSI Architecture Model) unless +- otherwise qualified. +- +- In keeping with similar protocols, the initiator and target divide +- their communications into messages. This document uses the term +- "iSCSI protocol data unit" (iSCSI PDU) for these messages. +- +- For performance reasons, iSCSI allows a "phase-collapse". A command +- and its associated data may be shipped together from initiator to +- target, and data and responses may be shipped together from targets. +- +- The iSCSI transfer direction is defined with respect to the +- initiator. Outbound or outgoing transfers are transfers from an +- initiator to a target, while inbound or incoming transfers are from a +- target to an initiator. +- +- An iSCSI task is an iSCSI request for which a response is expected. +- +- In this document "iSCSI request", "iSCSI command", request, or +- (unqualified) command have the same meaning. Also, unless otherwise +- specified, status, response, or numbered response have the same +- meaning. +- +- +- +- +-Satran, et al. Standards Track [Page 18] +- +-RFC 3720 iSCSI April 2004 +- +- +-3.2.1. Layers and Sessions +- +- The following conceptual layering model is used to specify initiator +- and target actions and the way in which they relate to transmitted +- and received Protocol Data Units: +- +- a) the SCSI layer builds/receives SCSI CDBs (Command Descriptor +- Blocks) and passes/receives them with the remaining command +- execute parameters ([SAM2]) to/from +- +- b) the iSCSI layer that builds/receives iSCSI PDUs and +- relays/receives them to/from one or more TCP connections; the +- group of connections form an initiator-target "session". +- +- Communication between the initiator and target occurs over one or +- more TCP connections. The TCP connections carry control messages, +- SCSI commands, parameters, and data within iSCSI Protocol Data Units +- (iSCSI PDUs). The group of TCP connections that link an initiator +- with a target form a session (loosely equivalent to a SCSI I_T nexus, +- see Section 3.4.2 SCSI Architecture Model). A session is defined by +- a session ID that is composed of an initiator part and a target part. +- TCP connections can be added and removed from a session. Each +- connection within a session is identified by a connection ID (CID). +- +- Across all connections within a session, an initiator sees one +- "target image". All target identifying elements, such as LUN, are +- the same. A target also sees one "initiator image" across all +- connections within a session. Initiator identifying elements, such +- as the Initiator Task Tag, are global across the session regardless +- of the connection on which they are sent or received. +- +- iSCSI targets and initiators MUST support at least one TCP connection +- and MAY support several connections in a session. For error recovery +- purposes, targets and initiators that support a single active +- connection in a session SHOULD support two connections during +- recovery. +- +-3.2.2. Ordering and iSCSI Numbering +- +- iSCSI uses Command and Status numbering schemes and a Data sequencing +- scheme. +- +- Command numbering is session-wide and is used for ordered command +- delivery over multiple connections. It can also be used as a +- mechanism for command flow control over a session. +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 19] +- +-RFC 3720 iSCSI April 2004 +- +- +- Status numbering is per connection and is used to enable missing +- status detection and recovery in the presence of transient or +- permanent communication errors. +- +- Data sequencing is per command or part of a command (R2T triggered +- sequence) and is used to detect missing data and/or R2T PDUs due to +- header digest errors. +- +- Typically, fields in the iSCSI PDUs communicate the Sequence Numbers +- between the initiator and target. During periods when traffic on a +- connection is unidirectional, iSCSI NOP-Out/In PDUs may be utilized +- to synchronize the command and status ordering counters of the target +- and initiator. +- +- The iSCSI session abstraction is equivalent to the SCSI I_T nexus, +- and the iSCSI session provides an ordered command delivery from the +- SCSI initiator to the SCSI target. For detailed design +- considerations that led to the iSCSI session model as it is defined +- here and how it relates the SCSI command ordering features defined in +- SCSI specifications to the iSCSI concepts see [CORD]. +- +-3.2.2.1. Command Numbering and Acknowledging +- +- iSCSI performs ordered command delivery within a session. All +- commands (initiator-to-target PDUs) in transit from the initiator to +- the target are numbered. +- +- iSCSI considers a task to be instantiated on the target in response +- to every request issued by the initiator. A set of task management +- operations including abort and reassign (see Section 10.5 Task +- Management Function Request) may be performed on any iSCSI task. +- +- Some iSCSI tasks are SCSI tasks, and many SCSI activities are related +- to a SCSI task ([SAM2]). In all cases, the task is identified by the +- Initiator Task Tag for the life of the task. +- +- The command number is carried by the iSCSI PDU as CmdSN +- (Command Sequence Number). The numbering is session-wide. Outgoing +- iSCSI PDUs carry this number. The iSCSI initiator allocates CmdSNs +- with a 32-bit unsigned counter (modulo 2**32). Comparisons and +- arithmetic on CmdSN use Serial Number Arithmetic as defined in +- [RFC1982] where SERIAL_BITS = 32. +- +- Commands meant for immediate delivery are marked with an immediate +- delivery flag; they MUST also carry the current CmdSN. CmdSN does +- not advance after a command marked for immediate delivery is sent. +- +- +- +- +- +-Satran, et al. Standards Track [Page 20] +- +-RFC 3720 iSCSI April 2004 +- +- +- Command numbering starts with the first login request on the first +- connection of a session (the leading login on the leading connection) +- and command numbers are incremented by 1 for every non-immediate +- command issued afterwards. +- +- If immediate delivery is used with task management commands, these +- commands may reach the target before the tasks on which they are +- supposed to act. However their CmdSN serves as a marker of their +- position in the stream of commands. The initiator and target must +- ensure that the task management commands act as specified by [SAM2]. +- For example, both commands and responses appear as if delivered in +- order. Whenever CmdSN for an outgoing PDU is not specified by an +- explicit rule, CmdSN will carry the current value of the local CmdSN +- variable (see later in this section). +- +- The means by which an implementation decides to mark a PDU for +- immediate delivery or by which iSCSI decides by itself to mark a PDU +- for immediate delivery are beyond the scope of this document. +- +- The number of commands used for immediate delivery is not limited and +- their delivery for execution is not acknowledged through the +- numbering scheme. Immediate commands MAY be rejected by the iSCSI +- target layer due to a lack of resources. An iSCSI target MUST be +- able to handle at least one immediate task management command and one +- immediate non-task-management iSCSI command per connection at any +- time. +- +- In this document, delivery for execution means delivery to the SCSI +- execution engine or an iSCSI protocol specific execution engine +- (e.g., for text requests with public or private extension keys +- involving an execution component). With the exception of the +- commands marked for immediate delivery, the iSCSI target layer MUST +- deliver the commands for execution in the order specified by CmdSN. +- Commands marked for immediate delivery may be delivered by the iSCSI +- target layer for execution as soon as detected. iSCSI may avoid +- delivering some commands to the SCSI target layer if required by a +- prior SCSI or iSCSI action (e.g., CLEAR TASK SET Task Management +- request received before all the commands on which it was supposed to +- act). +- +- On any connection, the iSCSI initiator MUST send the commands in +- increasing order of CmdSN, except for commands that are retransmitted +- due to digest error recovery and connection recovery. +- +- For the numbering mechanism, the initiator and target maintain the +- following three variables for each session: +- +- +- +- +- +-Satran, et al. Standards Track [Page 21] +- +-RFC 3720 iSCSI April 2004 +- +- +- - CmdSN - the current command Sequence Number, advanced by 1 on +- each command shipped except for commands marked for immediate +- delivery. CmdSN always contains the number to be assigned to +- the next Command PDU. +- - ExpCmdSN - the next expected command by the target. The target +- acknowledges all commands up to, but not including, this +- number. The initiator treats all commands with CmdSN less than +- ExpCmdSN as acknowledged. The target iSCSI layer sets the +- ExpCmdSN to the largest non-immediate CmdSN that it can deliver +- for execution plus 1 (no holes in the CmdSN sequence). +- - MaxCmdSN - the maximum number to be shipped. The queuing +- capacity of the receiving iSCSI layer is MaxCmdSN - ExpCmdSN + +- 1. +- +- The initiator's ExpCmdSN and MaxCmdSN are derived from +- target-to-initiator PDU fields. Comparisons and arithmetic on +- ExpCmdSN and MaxCmdSN MUST use Serial Number Arithmetic as defined in +- [RFC1982] where SERIAL_BITS = 32. +- +- The target MUST NOT transmit a MaxCmdSN that is less than +- ExpCmdSN-1. For non-immediate commands, the CmdSN field can take any +- value from ExpCmdSN to MaxCmdSN inclusive. The target MUST silently +- ignore any non-immediate command outside of this range or non- +- immediate duplicates within the range. The CmdSN carried by +- immediate commands may lie outside the ExpCmdSN to MaxCmdSN range. +- For example, if the initiator has previously sent a non-immediate +- command carrying the CmdSN equal to MaxCmdSN, the target window is +- closed. For group task management commands issued as immediate +- commands, CmdSN indicates the scope of the group action (e.g., on +- ABORT TASK SET indicates which commands are aborted). +- +- MaxCmdSN and ExpCmdSN fields are processed by the initiator as +- follows: +- +- - If the PDU MaxCmdSN is less than the PDU ExpCmdSN-1 (in Serial +- Arithmetic Sense), they are both ignored. +- - If the PDU MaxCmdSN is greater than the local MaxCmdSN (in +- Serial Arithmetic Sense), it updates the local MaxCmdSN; +- otherwise, it is ignored. +- - If the PDU ExpCmdSN is greater than the local ExpCmdSN (in +- Serial Arithmetic Sense), it updates the local ExpCmdSN; +- otherwise, it is ignored. +- +- This sequence is required because updates may arrive out of order +- (e.g., the updates are sent on different TCP connections). +- +- iSCSI initiators and targets MUST support the command numbering +- scheme. +- +- +- +-Satran, et al. Standards Track [Page 22] +- +-RFC 3720 iSCSI April 2004 +- +- +- A numbered iSCSI request will not change its allocated CmdSN, +- regardless of the number of times and circumstances in which it is +- reissued (see Section 6.2.1 Usage of Retry). At the target, CmdSN is +- only relevant when the command has not created any state related to +- its execution (execution state); afterwards, CmdSN becomes +- irrelevant. Testing for the execution state (represented by +- identifying the Initiator Task Tag) MUST precede any other action at +- the target. If no execution state is found, it is followed by +- ordering and delivery. If an execution state is found, it is +- followed by delivery. +- +- If an initiator issues a command retry for a command with CmdSN R on +- a connection when the session CmdSN value is Q, it MUST NOT advance +- the CmdSN past R + 2**31 -1 unless the connection is no longer +- operational (i.e., it has returned to the FREE state, see Section +- 7.1.3 Standard Connection State Diagram for an Initiator), the +- connection has been reinstated (see Section 5.3.4 Connection +- Reinstatement), or a non-immediate command with CmdSN equal or +- greater than Q was issued subsequent to the command retry on the same +- connection and the reception of that command is acknowledged by the +- target (see Section 9.4 Command Retry and Cleaning Old Command +- Instances). +- +- A target MUST NOT issue a command response or Data-In PDU with status +- before acknowledging the command. However, the acknowledgement can +- be included in the response or Data-In PDU. +- +-3.2.2.2. Response/Status Numbering and Acknowledging +- +- Responses in transit from the target to the initiator are numbered. +- The StatSN (Status Sequence Number) is used for this purpose. StatSN +- is a counter maintained per connection. ExpStatSN is used by the +- initiator to acknowledge status. The status sequence number space is +- 32-bit unsigned-integers and the arithmetic operations are the +- regular mod(2**32) arithmetic. +- +- Status numbering starts with the Login response to the first Login +- request of the connection. The Login response includes an initial +- value for status numbering (any initial value is valid). +- +- To enable command recovery, the target MAY maintain enough state +- information for data and status recovery after a connection failure. +- A target doing so can safely discard all of the state information +- maintained for recovery of a command after the delivery of the status +- for the command (numbered StatSN) is acknowledged through ExpStatSN. +- +- A large absolute difference between StatSN and ExpStatSN may indicate +- a failed connection. Initiators MUST undertake recovery actions if +- +- +- +-Satran, et al. Standards Track [Page 23] +- +-RFC 3720 iSCSI April 2004 +- +- +- the difference is greater than an implementation defined constant +- that MUST NOT exceed 2**31-1. +- +- Initiators and Targets MUST support the response-numbering scheme. +- +-3.2.2.3. Data Sequencing +- +- Data and R2T PDUs transferred as part of some command execution MUST +- be sequenced. The DataSN field is used for data sequencing. For +- input (read) data PDUs, DataSN starts with 0 for the first data PDU +- of an input command and advances by 1 for each subsequent data PDU. +- For output data PDUs, DataSN starts with 0 for the first data PDU of +- a sequence (the initial unsolicited sequence or any data PDU sequence +- issued to satisfy an R2T) and advances by 1 for each subsequent data +- PDU. R2Ts are also sequenced per command. For example, the first +- R2T has an R2TSN of 0 and advances by 1 for each subsequent R2T. For +- bidirectional commands, the target uses the DataSN/R2TSN to sequence +- Data-In and R2T PDUs in one continuous sequence (undifferentiated). +- Unlike command and status, data PDUs and R2Ts are not acknowledged by +- a field in regular outgoing PDUs. Data-In PDUs can be acknowledged +- on demand by a special form of the SNACK PDU. Data and R2T PDUs are +- implicitly acknowledged by status for the command. The DataSN/R2TSN +- field enables the initiator to detect missing data or R2T PDUs. +- +- For any read or bidirectional command, a target MUST issue less than +- 2**32 combined R2T and Data-In PDUs. Any output data sequence MUST +- contain less than 2**32 Data-Out PDUs. +- +-3.2.3. iSCSI Login +- +- The purpose of the iSCSI login is to enable a TCP connection for +- iSCSI use, authentication of the parties, negotiation of the +- session's parameters and marking of the connection as belonging to an +- iSCSI session. +- +- A session is used to identify to a target all the connections with a +- given initiator that belong to the same I_T nexus. (For more details +- on how a session relates to an I_T nexus, see Section 3.4.2 SCSI +- Architecture Model). +- +- The targets listen on a well-known TCP port or other TCP port for +- incoming connections. The initiator begins the login process by +- connecting to one of these TCP ports. +- +- As part of the login process, the initiator and target SHOULD +- authenticate each other and MAY set a security association protocol +- for the session. This can occur in many different ways and is +- subject to negotiation. +- +- +- +-Satran, et al. Standards Track [Page 24] +- +-RFC 3720 iSCSI April 2004 +- +- +- To protect the TCP connection, an IPsec security association MAY be +- established before the Login request. For information on using IPsec +- security for iSCSI see Chapter 8 and [RFC3723]. +- +- The iSCSI Login Phase is carried through Login requests and +- responses. Once suitable authentication has occurred and operational +- parameters have been set, the session transitions to the Full Feature +- Phase and the initiator may start to send SCSI commands. The +- security policy for whether, and by what means, a target chooses to +- authorize an initiator is beyond the scope of this document. For a +- more detailed description of the Login Phase, see Chapter 5. +- +- The login PDU includes the ISID part of the session ID (SSID). The +- target portal group that services the login is implied by the +- selection of the connection endpoint. For a new session, the TSIH is +- zero. As part of the response, the target generates a TSIH. +- +- During session establishment, the target identifies the SCSI +- initiator port (the "I" in the "I_T nexus") through the value pair +- (InitiatorName, ISID). We describe InitiatorName later in this +- section. Any persistent state (e.g., persistent reservations) on the +- target that is associated with a SCSI initiator port is identified +- based on this value pair. Any state associated with the SCSI target +- port (the "T" in the "I_T nexus") is identified externally by the +- TargetName and portal group tag (see Section 3.4.1 iSCSI Architecture +- Model). ISID is subject to reuse restrictions because it is used to +- identify a persistent state (see Section 3.4.3 Consequences of the +- Model). +- +- Before the Full Feature Phase is established, only Login Request and +- Login Response PDUs are allowed. Login requests and responses MUST +- be used exclusively during Login. On any connection, the login phase +- MUST immediately follow TCP connection establishment and a subsequent +- Login Phase MUST NOT occur before tearing down a connection. +- +- A target receiving any PDU except a Login request before the Login +- phase is started MUST immediately terminate the connection on which +- the PDU was received. Once the Login phase has started, if the +- target receives any PDU except a Login request, it MUST send a Login +- reject (with Status "invalid during login") and then disconnect. If +- the initiator receives any PDU except a Login response, it MUST +- immediately terminate the connection. +- +-3.2.4. iSCSI Full Feature Phase +- +- Once the initiator is authorized to do so, the iSCSI session is in +- the iSCSI Full Feature Phase. A session is in Full Feature Phase +- after successfully finishing the Login Phase on the first (leading) +- +- +- +-Satran, et al. Standards Track [Page 25] +- +-RFC 3720 iSCSI April 2004 +- +- +- connection of a session. A connection is in Full Feature Phase if +- the session is in Full Feature Phase and the connection login has +- completed successfully. An iSCSI connection is not in Full Feature +- Phase +- +- a) when it does not have an established transport connection, +- +- OR +- +- b) when it has a valid transport connection, but a successful +- login was not performed or the connection is currently logged +- out. +- +- In a normal Full Feature Phase, the initiator may send SCSI commands +- and data to the various LUs on the target by encapsulating them in +- iSCSI PDUs that go over the established iSCSI session. +- +-3.2.4.1. Command Connection Allegiance +- +- For any iSCSI request issued over a TCP connection, the corresponding +- response and/or other related PDU(s) MUST be sent over the same +- connection. We call this "connection allegiance". If the original +- connection fails before the command is completed, the connection +- allegiance of the command may be explicitly reassigned to a different +- transport connection as described in detail in Section 6.2 Retry and +- Reassign in Recovery. +- +- Thus, if an initiator issues a READ command, the target MUST send the +- requested data, if any, followed by the status to the initiator over +- the same TCP connection that was used to deliver the SCSI command. +- If an initiator issues a WRITE command, the initiator MUST send the +- data, if any, for that command over the same TCP connection that was +- used to deliver the SCSI command. The target MUST return Ready To +- Transfer (R2T), if any, and the status over the same TCP connection +- that was used to deliver the SCSI command. Retransmission requests +- (SNACK PDUs) and the data and status that they generate MUST also use +- the same connection. +- +- However, consecutive commands that are part of a SCSI linked +- command-chain task (see [SAM2]) MAY use different connections. +- Connection allegiance is strictly per-command and not per-task. +- During the iSCSI Full Feature Phase, the initiator and target MAY +- interleave unrelated SCSI commands, their SCSI Data, and responses +- over the session. +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 26] +- +-RFC 3720 iSCSI April 2004 +- +- +-3.2.4.2. Data Transfer Overview +- +- Outgoing SCSI data (initiator to target user data or command +- parameters) is sent as either solicited data or unsolicited data. +- Solicited data are sent in response to R2T PDUs. Unsolicited data +- can be sent as part of an iSCSI command PDU ("immediate data") or in +- separate iSCSI data PDUs. +- +- Immediate data are assumed to originate at offset 0 in the initiator +- SCSI write-buffer (outgoing data buffer). All other Data PDUs have +- the buffer offset set explicitly in the PDU header. +- +- An initiator may send unsolicited data up to FirstBurstLength as +- immediate (up to the negotiated maximum PDU length), in a separate +- PDU sequence or both. All subsequent data MUST be solicited. The +- maximum length of an individual data PDU or the immediate-part of the +- first unsolicited burst MAY be negotiated at login. +- +- The maximum amount of unsolicited data that can be sent with a +- command is negotiated at login through the FirstBurstLength key. A +- target MAY separately enable immediate data (through the +- ImmediateData key) without enabling the more general (separate data +- PDUs) form of unsolicited data (through the InitialR2T key). +- +- Unsolicited data on write are meant to reduce the effect of latency +- on throughput (no R2T is needed to start sending data). In addition, +- immediate data is meant to reduce the protocol overhead (both +- bandwidth and execution time). +- +- An iSCSI initiator MAY choose not to send unsolicited data, only +- immediate data or FirstBurstLength bytes of unsolicited data with a +- command. If any non-immediate unsolicited data is sent, the total +- unsolicited data MUST be either FirstBurstLength, or all of the data +- if the total amount is less than the FirstBurstLength. +- +- It is considered an error for an initiator to send unsolicited data +- PDUs to a target that operates in R2T mode (only solicited data are +- allowed). It is also an error for an initiator to send more +- unsolicited data, whether immediate or as separate PDUs, than +- FirstBurstLength. +- +- An initiator MUST honor an R2T data request for a valid outstanding +- command (i.e., carrying a valid Initiator Task Tag) and deliver all +- the requested data provided the command is supposed to deliver +- outgoing data and the R2T specifies data within the command bounds. +- The initiator action is unspecified for receiving an R2T request that +- specifies data, all or part, outside of the bounds of the command. +- +- +- +- +-Satran, et al. Standards Track [Page 27] +- +-RFC 3720 iSCSI April 2004 +- +- +- A target SHOULD NOT silently discard data and then request +- retransmission through R2T. Initiators SHOULD NOT keep track of the +- data transferred to or from the target (scoreboarding). SCSI targets +- perform residual count calculation to check how much data was +- actually transferred to or from the device by a command. This may +- differ from the amount the initiator sent and/or received for reasons +- such as retransmissions and errors. Read or bidirectional commands +- implicitly solicit the transmission of the entire amount of data +- covered by the command. SCSI data packets are matched to their +- corresponding SCSI commands by using tags specified in the protocol. +- +- In addition, iSCSI initiators and targets MUST enforce some ordering +- rules. When unsolicited data is used, the order of the unsolicited +- data on each connection MUST match the order in which the commands on +- that connection are sent. Command and unsolicited data PDUs may be +- interleaved on a single connection as long as the ordering +- requirements of each are maintained (e.g., command N+1 MAY be sent +- before the unsolicited Data-Out PDUs for command N, but the +- unsolicited Data-Out PDUs for command N MUST precede the unsolicited +- Data-Out PDUs of command N+1). A target that receives data out of +- order MAY terminate the session. +- +-3.2.4.3. Tags and Integrity Checks +- +- Initiator tags for pending commands are unique initiator-wide for a +- session. Target tags are not strictly specified by the protocol. It +- is assumed that target tags are used by the target to tag (alone or +- in combination with the LUN) the solicited data. Target tags are +- generated by the target and "echoed" by the initiator. These +- mechanisms are designed to accomplish efficient data delivery along +- with a large degree of control over the data flow. +- +- As the Initiator Task Tag is used to identify a task during its +- execution, the iSCSI initiator and target MUST verify that all other +- fields used in task-related PDUs have values that are consistent with +- the values used at the task instantiation based on the Initiator Task +- Tag (e.g., the LUN used in an R2T PDU MUST be the same as the one +- used in the SCSI command PDU used to instantiate the task). Using +- inconsistent field values is considered a protocol error. +- +-3.2.4.4. Task Management +- +- SCSI task management assumes that individual tasks and task groups +- can be aborted solely based on the task tags (for individual tasks) +- or the timing of the task management command (for task groups), and +- that the task management action is executed synchronously - i.e., no +- message involving an aborted task will be seen by the SCSI initiator +- after receiving the task management response. In iSCSI initiators +- +- +- +-Satran, et al. Standards Track [Page 28] +- +-RFC 3720 iSCSI April 2004 +- +- +- and targets interact asynchronously over several connections. iSCSI +- specifies the protocol mechanism and implementation requirements +- needed to present a synchronous view while using an asynchronous +- infrastructure. +- +-3.2.5. iSCSI Connection Termination +- +- An iSCSI connection may be terminated by use of a transport +- connection shutdown or a transport reset. Transport reset is assumed +- to be an exceptional event. +- +- Graceful TCP connection shutdowns are done by sending TCP FINs. A +- graceful transport connection shutdown SHOULD only be initiated by +- either party when the connection is not in iSCSI Full Feature Phase. +- A target MAY terminate a Full Feature Phase connection on internal +- exception events, but it SHOULD announce the fact through an +- Asynchronous Message PDU. Connection termination with outstanding +- commands may require recovery actions. +- +- If a connection is terminated while in Full Feature Phase, connection +- cleanup (see section 7) is required prior to recovery. By doing +- connection cleanup before starting recovery, the initiator and target +- will avoid receiving stale PDUs after recovery. +- +-3.2.6. iSCSI Names +- +- Both targets and initiators require names for the purpose of +- identification. In addition, names enable iSCSI storage resources to +- be managed regardless of location (address). An iSCSI node name is +- also the SCSI device name of an iSCSI device. The iSCSI name of a +- SCSI device is the principal object used in authentication of targets +- to initiators and initiators to targets. This name is also used to +- identify and manage iSCSI storage resources. +- +- iSCSI names must be unique within the operational domain of the end +- user. However, because the operational domain of an IP network is +- potentially worldwide, the iSCSI name formats are architected to be +- worldwide unique. To assist naming authorities in the construction +- of worldwide unique names, iSCSI provides two name formats for +- different types of naming authorities. +- +- iSCSI names are associated with iSCSI nodes, and not iSCSI network +- adapter cards, to ensure that the replacement of network adapter +- cards does not require reconfiguration of all SCSI and iSCSI resource +- allocation information. +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 29] +- +-RFC 3720 iSCSI April 2004 +- +- +- Some SCSI commands require that protocol-specific identifiers be +- communicated within SCSI CDBs. See Section 3.4.2 SCSI Architecture +- Model for the definition of the SCSI port name/identifier for iSCSI +- ports. +- +- An initiator may discover the iSCSI Target Names to which it has +- access, along with their addresses, using the SendTargets text +- request, or other techniques discussed in [RFC3721]. +- +-3.2.6.1. iSCSI Name Properties +- +- Each iSCSI node, whether an initiator or target, MUST have an iSCSI +- name. +- +- Initiators and targets MUST support the receipt of iSCSI names of up +- to the maximum length of 223 bytes. +- +- The initiator MUST present both its iSCSI Initiator Name and the +- iSCSI Target Name to which it wishes to connect in the first login +- request of a new session or connection. The only exception is if a +- discovery session (see Section 2.3 iSCSI Session Types) is to be +- established. In this case, the iSCSI Initiator Name is still +- required, but the iSCSI Target Name MAY be omitted. +- +- iSCSI names have the following properties: +- +- a) iSCSI names are globally unique. No two initiators or targets +- can have the same name. +- b) iSCSI names are permanent. An iSCSI initiator node or target +- node has the same name for its lifetime. +- c) iSCSI names do not imply a location or address. An iSCSI +- initiator or target can move, or have multiple addresses. A +- change of address does not imply a change of name. +- d) iSCSI names do not rely on a central name broker; the naming +- authority is distributed. +- e) iSCSI names support integration with existing unique naming +- schemes. +- f) iSCSI names rely on existing naming authorities. iSCSI does +- not create any new naming authority. +- +- The encoding of an iSCSI name has the following properties: +- +- a) iSCSI names have the same encoding method regardless of the +- underlying protocols. +- b) iSCSI names are relatively simple to compare. The algorithm +- for comparing two iSCSI names for equivalence does not rely on +- an external server. +- +- +- +- +-Satran, et al. Standards Track [Page 30] +- +-RFC 3720 iSCSI April 2004 +- +- +- c) iSCSI names are composed only of displayable characters. iSCSI +- names allow the use of international character sets but are not +- case sensitive. No whitespace characters are used in iSCSI +- names. +- d) iSCSI names may be transported using both binary and +- ASCII-based protocols. +- +- An iSCSI name really names a logical software entity, and is not tied +- to a port or other hardware that can be changed. For instance, an +- initiator name should name the iSCSI initiator node, not a particular +- NIC or HBA. When multiple NICs are used, they should generally all +- present the same iSCSI initiator name to the targets, because they +- are simply paths to the same SCSI layer. In most operating systems, +- the named entity is the operating system image. +- +- Similarly, a target name should not be tied to hardware interfaces +- that can be changed. A target name should identify the logical +- target and must be the same for the target regardless of the physical +- portion being addressed. This assists iSCSI initiators in +- determining that the two targets it has discovered are really two +- paths to the same target. +- +- The iSCSI name is designed to fulfill the functional requirements for +- Uniform Resource Names (URN) [RFC1737]. For example, it is required +- that the name have a global scope, be independent of address or +- location, and be persistent and globally unique. Names must be +- extensible and scalable with the use of naming authorities. The name +- encoding should be both human and machine readable. See [RFC1737] +- for further requirements. +- +-3.2.6.2. iSCSI Name Encoding +- +- An iSCSI name MUST be a UTF-8 encoding of a string of Unicode +- characters with the following properties: +- +- - It is in Normalization Form C (see "Unicode Normalization +- Forms" [UNICODE]). +- - It only contains characters allowed by the output of the iSCSI +- stringprep template (described in [RFC3722]). +- - The following characters are used for formatting iSCSI names: +- +- - dash ('-'=U+002d) +- - dot ('.'=U+002e) +- - colon (':'=U+003a) +- +- - The UTF-8 encoding of the name is not larger than 223 bytes. +- +- +- +- +- +-Satran, et al. Standards Track [Page 31] +- +-RFC 3720 iSCSI April 2004 +- +- +- The stringprep process is described in [RFC3454]; iSCSI's use of the +- stringprep process is described in [RFC3722]. Stringprep is a method +- designed by the Internationalized Domain Name (IDN) working group to +- translate human-typed strings into a format that can be compared as +- opaque strings. Strings MUST NOT include punctuation, spacing, +- diacritical marks, or other characters that could get in the way of +- readability. The stringprep process also converts strings into +- equivalent strings of lower-case characters. +- +- The stringprep process does not need to be implemented if the names +- are only generated using numeric and lower-case (any character set) +- alphabetic characters. +- +- Once iSCSI names encoded in UTF-8 are "normalized" they may be safely +- compared byte-for-byte. +- +-3.2.6.3. iSCSI Name Structure +- +- An iSCSI name consists of two parts--a type designator followed by a +- unique name string. +- +- The iSCSI name does not define any new naming authorities. Instead, +- it supports two existing ways of designating naming authorities: an +- iSCSI-Qualified Name, using domain names to identify a naming +- authority, and the EUI format, where the IEEE Registration Authority +- assists in the formation of worldwide unique names (EUI-64 format). +- +- The type designator strings currently defined are: +- +- iqn. - iSCSI Qualified name +- eui. - Remainder of the string is an IEEE EUI-64 +- identifier, in ASCII-encoded hexadecimal. +- +- These two naming authority designators were considered sufficient at +- the time of writing this document. The creation of additional naming +- type designators for iSCSI may be considered by the IETF and detailed +- in separate RFCs. +- +-3.2.6.3.1. Type "iqn." (iSCSI Qualified Name) +- +- This iSCSI name type can be used by any organization that owns a +- domain name. This naming format is useful when an end user or +- service provider wishes to assign iSCSI names for targets and/or +- initiators. +- +- To generate names of this type, the person or organization generating +- the name must own a registered domain name. This domain name does +- not have to be active, and does not have to resolve to an address; it +- +- +- +-Satran, et al. Standards Track [Page 32] +- +-RFC 3720 iSCSI April 2004 +- +- +- just needs to be reserved to prevent others from generating iSCSI +- names using the same domain name. +- +- Since a domain name can expire, be acquired by another entity, or may +- be used to generate iSCSI names by both owners, the domain name must +- be additionally qualified by a date during which the naming authority +- owned the domain name. For this reason, a date code is provided as +- part of the "iqn." format. +- +- The iSCSI qualified name string consists of: +- +- - The string "iqn.", used to distinguish these names from "eui." +- formatted names. +- - A date code, in yyyy-mm format. This date MUST be a date +- during which the naming authority owned the domain name used in +- this format, and SHOULD be the first month in which the domain +- name was owned by this naming authority at 00:01 GMT of the +- first day of the month. This date code uses the Gregorian +- calendar. All four digits in the year must be present. Both +- digits of the month must be present, with January == "01" and +- December == "12". The dash must be included. +- - A dot "." +- - The reversed domain name of the naming authority (person or +- organization) creating this iSCSI name. +- - An optional, colon (:) prefixed, string within the character +- set and length boundaries that the owner of the domain name +- deems appropriate. This may contain product types, serial +- numbers, host identifiers, or software keys (e.g., it may +- include colons to separate organization boundaries). With the +- exception of the colon prefix, the owner of the domain name can +- assign everything after the reversed domain name as desired. +- It is the responsibility of the entity that is the naming +- authority to ensure that the iSCSI names it assigns are +- worldwide unique. For example, "Example Storage Arrays, Inc.", +- might own the domain name "example.com". +- +- The following are examples of iSCSI qualified names that might be +- generated by "EXAMPLE Storage Arrays, Inc." +- +- Naming String defined by +- Type Date Auth "example.com" naming authority +- +--++-----+ +---------+ +--------------------------------+ +- | || | | | | | +- +- iqn.2001-04.com.example:storage:diskarrays-sn-a8675309 +- iqn.2001-04.com.example +- iqn.2001-04.com.example:storage.tape1.sys1.xyz +- iqn.2001-04.com.example:storage.disk2.sys1.xyz +- +- +- +-Satran, et al. Standards Track [Page 33] +- +-RFC 3720 iSCSI April 2004 +- +- +- +-3.2.6.3.2. Type "eui." (IEEE EUI-64 format) +- +- The IEEE Registration Authority provides a service for assigning +- globally unique identifiers [EUI]. The EUI-64 format is used to +- build a global identifier in other network protocols. For example, +- Fibre Channel defines a method of encoding it into a WorldWideName. +- For more information on registering for EUI identifiers, see [OUI]. +- +- The format is "eui." followed by an EUI-64 identifier (16 +- ASCII-encoded hexadecimal digits). +- +- Example iSCSI name: +- +- Type EUI-64 identifier (ASCII-encoded hexadecimal) +- +--++--------------+ +- | || | +- eui.02004567A425678D +- +- The IEEE EUI-64 iSCSI name format might be used when a manufacturer +- is already registered with the IEEE Registration Authority and uses +- EUI-64 formatted worldwide unique names for its products. +- +- More examples of name construction are discussed in [RFC3721]. +- +-3.2.7. Persistent State +- +- iSCSI does not require any persistent state maintenance across +- sessions. However, in some cases, SCSI requires persistent +- identification of the SCSI initiator port name (See Section 3.4.2 +- SCSI Architecture Model and Section 3.4.3 Consequences of the Model). +- +- iSCSI sessions do not persist through power cycles and boot +- operations. +- +- All iSCSI session and connection parameters are re-initialized upon +- session and connection creation. +- +- Commands persist beyond connection termination if the session +- persists and command recovery within the session is supported. +- However, when a connection is dropped, command execution, as +- perceived by iSCSI (i.e., involving iSCSI protocol exchanges for the +- affected task), is suspended until a new allegiance is established by +- the 'task reassign' task management function. (See Section 10.5 Task +- Management Function Request.) +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 34] +- +-RFC 3720 iSCSI April 2004 +- +- +-3.2.8. Message Synchronization and Steering +- +- iSCSI presents a mapping of the SCSI protocol onto TCP. This +- encapsulation is accomplished by sending iSCSI PDUs of varying +- lengths. Unfortunately, TCP does not have a built-in mechanism for +- signaling message boundaries at the TCP layer. iSCSI overcomes this +- obstacle by placing the message length in the iSCSI message header. +- This serves to delineate the end of the current message as well as +- the beginning of the next message. +- +- In situations where IP packets are delivered in order from the +- network, iSCSI message framing is not an issue and messages are +- processed one after the other. In the presence of IP packet +- reordering (i.e., frames being dropped), legacy TCP implementations +- store the "out of order" TCP segments in temporary buffers until the +- missing TCP segments arrive, upon which the data must be copied to +- the application buffers. In iSCSI, it is desirable to steer the SCSI +- data within these out of order TCP segments into the pre-allocated +- SCSI buffers rather than store them in temporary buffers. This +- decreases the need for dedicated reassembly buffers as well as the +- latency and bandwidth related to extra copies. +- +- Relying solely on the "message length" information from the iSCSI +- message header may make it impossible to find iSCSI message +- boundaries in subsequent TCP segments due to the loss of a TCP +- segment that contains the iSCSI message length. The missing TCP +- segment(s) must be received before any of the following segments can +- be steered to the correct SCSI buffers (due to the inability to +- determine the iSCSI message boundaries). Since these segments cannot +- be steered to the correct location, they must be saved in temporary +- buffers that must then be copied to the SCSI buffers. +- +- Different schemes can be used to recover synchronization. To make +- these schemes work, iSCSI implementations have to make sure that the +- appropriate protocol layers are provided with enough information to +- implement a synchronization and/or data steering mechanism. One of +- these schemes is detailed in Appendix A. - Sync and Steering with +- Fixed Interval Markers -. +- +- The Fixed Interval Markers (FIM) scheme works by inserting markers in +- the payload stream at fixed intervals that contain the offset for the +- start of the next iSCSI PDU. +- +- Under normal circumstances (no PDU loss or data reception out of +- order), iSCSI data steering can be accomplished by using the +- identifying tag and the data offset fields in the iSCSI header in +- addition to the TCP sequence number from the TCP header. The +- +- +- +- +-Satran, et al. Standards Track [Page 35] +- +-RFC 3720 iSCSI April 2004 +- +- +- identifying tag helps associate the PDU with a SCSI buffer address +- while the data offset and TCP sequence number are used to determine +- the offset within the buffer. +- +- When the part of the TCP data stream containing an iSCSI PDU header +- is delayed or lost, markers may be used to minimize the damage as +- follows: +- +- - Markers indicate where the next iSCSI PDU starts and enable +- continued processing when iSCSI headers have to be dropped due to +- data errors discovered at the iSCSI level (e.g., iSCSI header CRC +- errors). +- +- - Markers help minimize the amount of data that has to be kept by +- the TCP/iSCSI layer while waiting for a late TCP packet arrival +- or recovery, because later they might help find iSCSI PDU headers +- and use the information contained in those to steer data to SCSI +- buffers. +- +-3.2.8.1. Sync/Steering and iSCSI PDU Length +- +- When a large iSCSI message is sent, the TCP segment(s) that contain +- the iSCSI header may be lost. The remaining TCP segment(s), up to +- the next iSCSI message, must be buffered (in temporary buffers) +- because the iSCSI header that indicates to which SCSI buffers the +- data are to be steered was lost. To minimize the amount of +- buffering, it is recommended that the iSCSI PDU length be restricted +- to a small value (perhaps a few TCP segments in length). During +- login, each end of the iSCSI session specifies the maximum iSCSI PDU +- length it will accept. +- +-3.3. iSCSI Session Types +- +- iSCSI defines two types of sessions: +- +- a) Normal operational session - an unrestricted session. +- b) Discovery-session - a session only opened for target +- discovery. The target MUST ONLY accept text requests with the +- SendTargets key and a logout request with the reason "close +- the session". All other requests MUST be rejected. +- +- The session type is defined during login with the key=value parameter +- in the login command. +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 36] +- +-RFC 3720 iSCSI April 2004 +- +- +-3.4. SCSI to iSCSI Concepts Mapping Model +- +- The following diagram shows an example of how multiple iSCSI Nodes +- (targets in this case) can coexist within the same Network Entity and +- can share Network Portals (IP addresses and TCP ports). Other more +- complex configurations are also possible. For detailed descriptions +- of the components of these diagrams, see Section 3.4.1 iSCSI +- Architecture Model. +- +- +-----------------------------------+ +- | Network Entity (iSCSI Client) | +- | | +- | +-------------+ | +- | | iSCSI Node | | +- | | (Initiator) | | +- | +-------------+ | +- | | | | +- | +--------------+ +--------------+ | +- | |Network Portal| |Network Portal| | +- | | 10.1.30.4 | | 10.1.40.6 | | +- +-+--------------+-+--------------+-+ +- | | +- | IP Networks | +- | | +- +-+--------------+-+--------------+-+ +- | |Network Portal| |Network Portal| | +- | | 10.1.30.21 | | 10.1.40.3 | | +- | | TCP Port 3260| | TCP Port 3260| | +- | +--------------+ +--------------+ | +- | | | | +- | ----------------- | +- | | | | +- | +-------------+ +--------------+ | +- | | iSCSI Node | | iSCSI Node | | +- | | (Target) | | (Target) | | +- | +-------------+ +--------------+ | +- | | +- | Network Entity (iSCSI Server) | +- +-----------------------------------+ +- +-3.4.1. iSCSI Architecture Model +- +- This section describes the part of the iSCSI architecture model that +- has the most bearing on the relationship between iSCSI and the SCSI +- Architecture Model. +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 37] +- +-RFC 3720 iSCSI April 2004 +- +- +- a) Network Entity - represents a device or gateway that is +- accessible from the IP network. A Network Entity must have +- one or more Network Portals (see item d), each of which can be +- used by some iSCSI Nodes (see item (b)) contained in that +- Network Entity to gain access to the IP network. +- +- b) iSCSI Node - represents a single iSCSI initiator or iSCSI +- target. There are one or more iSCSI Nodes within a Network +- Entity. The iSCSI Node is accessible via one or more Network +- Portals (see item d). An iSCSI Node is identified by its +- iSCSI Name (see Section 3.2.6 iSCSI Names and Chapter 12). +- The separation of the iSCSI Name from the addresses used by +- and for the iSCSI node allows multiple iSCSI nodes to use the +- same addresses, and the same iSCSI node to use multiple +- addresses. +- +- c) An alias string may also be associated with an iSCSI Node. +- The alias allows an organization to associate a user friendly +- string with the iSCSI Name. However, the alias string is not +- a substitute for the iSCSI Name. +- +- d) Network Portal - a component of a Network Entity that has a +- TCP/IP network address and that may be used by an iSCSI Node +- within that Network Entity for the connection(s) within one of +- its iSCSI sessions. In an initiator, it is identified by its +- IP address. In a target, it is identified by its IP address +- and its listening TCP port. +- +- e) Portal Groups - iSCSI supports multiple connections within the +- same session; some implementations will have the ability to +- combine connections in a session across multiple Network +- Portals. A Portal Group defines a set of Network Portals +- within an iSCSI Node that collectively supports the capability +- of coordinating a session with connections that span these +- portals. Not all Network Portals within a Portal Group need +- to participate in every session connected through that Portal +- Group. One or more Portal Groups may provide access to an +- iSCSI Node. Each Network Portal, as utilized by a given iSCSI +- Node, belongs to exactly one portal group within that node. +- Portal Groups are identified within an iSCSI Node by a portal +- group tag, a simple unsigned-integer between 0 and 65535 (see +- Section 12.3 SendTargets). All Network Portals with the same +- portal group tag in the context of a given iSCSI Node are in +- the same Portal Group. +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 38] +- +-RFC 3720 iSCSI April 2004 +- +- +- Both iSCSI Initiators and iSCSI Targets have portal groups, +- though only the iSCSI Target Portal Groups are used directly +- in the iSCSI protocol (e.g., in SendTargets). For references +- to the initiator Portal Groups, see Section 9.1.1 Conservative +- Reuse of ISIDs. +- +- f) Portals within a Portal Group should support similar session +- parameters, because they may participate in a common session. +- +- The following diagram shows an example of one such configuration on a +- target and how a session that shares Network Portals within a Portal +- Group may be established. +- +- ----------------------------IP Network--------------------- +- | | | +- +----|---------------|-----+ +----|---------+ +- | +---------+ +---------+ | | +---------+ | +- | | Network | | Network | | | | Network | | +- | | Portal | | Portal | | | | Portal | | +- | +--|------+ +---------+ | | +---------+ | +- | | | | | | | +- | | Portal | | | | Portal | +- | | Group 1 | | | | Group 2 | +- +--------------------------+ +--------------+ +- | | | +- +--------|---------------|--------------------|--------------------+ +- | | | | | +- | +----------------------------+ +-----------------------------+ | +- | | iSCSI Session (Target side)| | iSCSI Session (Target side) | | +- | | | | | | +- | | (TSIH = 56) | | (TSIH = 48) | | +- | +----------------------------+ +-----------------------------+ | +- | | +- | iSCSI Target Node | +- | (within Network Entity, not shown) | +- +------------------------------------------------------------------+ +- +-3.4.2. SCSI Architecture Model +- +- This section describes the relationship between the SCSI Architecture +- Model [SAM2] and the constructs of the SCSI device, SCSI port and I_T +- nexus, and the iSCSI constructs described in Section 3.4.1 iSCSI +- Architecture Model. +- +- This relationship implies implementation requirements in order to +- conform to the SAM2 model and other SCSI operational functions. +- These requirements are detailed in Section 3.4.3 Consequences of the +- Model. +- +- +- +-Satran, et al. Standards Track [Page 39] +- +-RFC 3720 iSCSI April 2004 +- +- +- The following list outlines mappings of SCSI architectural elements +- to iSCSI. +- +- a) SCSI Device - the SAM2 term for an entity that contains one or +- more SCSI ports that are connected to a service delivery +- subsystem and supports a SCSI application protocol. For +- example, a SCSI Initiator Device contains one or more SCSI +- Initiator Ports and zero or more application clients. A SCSI +- Target Device contains one or more SCSI Target Ports and one +- or more logical units. For iSCSI, the SCSI Device is the +- component within an iSCSI Node that provides the SCSI +- functionality. As such, there can be one SCSI Device, at +- most, within an iSCSI Node. Access to the SCSI Device can +- only be achieved in an iSCSI normal operational session (see +- Section 3.3 iSCSI Session Types). The SCSI Device Name is +- defined to be the iSCSI Name of the node and MUST be used in +- the iSCSI protocol. +- +- b) SCSI Port - the SAM2 term for an entity in a SCSI Device that +- provides the SCSI functionality to interface with a service +- delivery subsystem or transport. For iSCSI, the definition of +- SCSI Initiator Port and SCSI Target Port are different. +- +- SCSI Initiator Port: This maps to one endpoint of an iSCSI +- normal operational session (see Section 3.3 iSCSI Session +- Types). An iSCSI normal operational session is negotiated +- through the login process between an iSCSI initiator node and +- an iSCSI target node. At successful completion of this +- process, a SCSI Initiator Port is created within the SCSI +- Initiator Device. The SCSI Initiator Port Name and SCSI +- Initiator Port Identifier are both defined to be the iSCSI +- Initiator Name together with (a) a label that identifies it as +- an initiator port name/identifier and (b) the ISID portion of +- the session identifier. +- +- SCSI Target Port: This maps to an iSCSI Target Portal Group. +- The SCSI Target Port Name and the SCSI Target Port Identifier +- are both defined to be the iSCSI Target Name together with (a) +- a label that identifies it as a target port name/identifier +- and (b) the portal group tag. +- +- The SCSI Port Name MUST be used in iSCSI. When used in SCSI +- parameter data, the SCSI port name MUST be encoded as: +- - The iSCSI Name in UTF-8 format, followed by +- - a comma separator (1 byte), followed by +- - the ASCII character 'i' (for SCSI Initiator Port) or the +- ASCII character 't' (for SCSI Target Port) (1 byte), +- followed by +- +- +- +-Satran, et al. Standards Track [Page 40] +- +-RFC 3720 iSCSI April 2004 +- +- +- - a comma separator (1 byte), followed by +- - a text encoding as a hex-constant (see Section 5.1 Text +- Format) of the ISID (for SCSI initiator port) or the portal +- group tag (for SCSI target port) including the initial 0X +- or 0x and the terminating null (15 bytes). +- +- The ASCII character 'i' or 't' is the label that identifies +- this port as either a SCSI Initiator Port or a SCSI Target +- Port. +- +- c) I_T nexus - a relationship between a SCSI Initiator Port and a +- SCSI Target Port, according to [SAM2]. For iSCSI, this +- relationship is a session, defined as a relationship between +- an iSCSI Initiator's end of the session (SCSI Initiator Port) +- and the iSCSI Target's Portal Group. The I_T nexus can be +- identified by the conjunction of the SCSI port names or by the +- iSCSI session identifier SSID. iSCSI defines the I_T nexus +- identifier to be the tuple (iSCSI Initiator Name + 'i' + ISID, +- iSCSI Target Name + 't' + Portal Group Tag). +- +- NOTE: The I_T nexus identifier is not equal to the session +- identifier (SSID). +- +-3.4.3. Consequences of the Model +- +- This section describes implementation and behavioral requirements +- that result from the mapping of SCSI constructs to the iSCSI +- constructs defined above. Between a given SCSI initiator port and a +- given SCSI target port, only one I_T nexus (session) can exist. No +- more than one nexus relationship (parallel nexus) is allowed by +- [SAM2]. Therefore, at any given time, only one session can exist +- between a given iSCSI initiator node and an iSCSI target node, with +- the same session identifier (SSID). +- +- These assumptions lead to the following conclusions and requirements: +- +- ISID RULE: Between a given iSCSI Initiator and iSCSI Target Portal +- Group (SCSI target port), there can only be one session with a given +- value for ISID that identifies the SCSI initiator port. See Section +- 10.12.5 ISID. +- +- The structure of the ISID that contains a naming authority component +- (see Section 10.12.5 ISID and [RFC3721]) provides a mechanism to +- facilitate compliance with the ISID rule. (See Section 9.1.1 +- Conservative Reuse of ISIDs.) +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 41] +- +-RFC 3720 iSCSI April 2004 +- +- +- The iSCSI Initiator Node should manage the assignment of ISIDs prior +- to session initiation. The "ISID RULE" does not preclude the use of +- the same ISID from the same iSCSI Initiator with different Target +- Portal Groups on the same iSCSI target or on other iSCSI targets (see +- Section 9.1.1 Conservative Reuse of ISIDs). Allowing this would be +- analogous to a single SCSI Initiator Port having relationships +- (nexus) with multiple SCSI target ports on the same SCSI target +- device or SCSI target ports on other SCSI target devices. It is also +- possible to have multiple sessions with different ISIDs to the same +- Target Portal Group. Each such session would be considered to be +- with a different initiator even when the sessions originate from the +- same initiator device. The same ISID may be used by a different +- iSCSI initiator because it is the iSCSI Name together with the ISID +- that identifies the SCSI Initiator Port. +- +- NOTE: A consequence of the ISID RULE and the specification for the +- I_T nexus identifier is that two nexus with the same identifier +- should never exist at the same time. +- +- TSIH RULE: The iSCSI Target selects a non-zero value for the TSIH at +- session creation (when an initiator presents a 0 value at Login). +- After being selected, the same TSIH value MUST be used whenever the +- initiator or target refers to the session and a TSIH is required. +- +-3.4.3.1. I_T Nexus State +- +- Certain nexus relationships contain an explicit state (e.g., +- initiator-specific mode pages) that may need to be preserved by the +- device server [SAM2] in a logical unit through changes or failures in +- the iSCSI layer (e.g., session failures). In order for that state to +- be restored, the iSCSI initiator should reestablish its session +- (re-login) to the same Target Portal Group using the previous ISID. +- That is, it should perform session recovery as described in Chapter +- 6. This is because the SCSI initiator port identifier and the SCSI +- target port identifier (or relative target port) form the datum that +- the SCSI logical unit device server uses to identify the I_T nexus. +- +-3.5. Request/Response Summary +- +- This section lists and briefly describes all the iSCSI PDU types +- (request and responses). +- +- All iSCSI PDUs are built as a set of one or more header segments +- (basic and auxiliary) and zero or one data segments. The header +- group and the data segment may each be followed by a CRC (digest). +- +- The basic header segment has a fixed length of 48 bytes. +- +- +- +- +-Satran, et al. Standards Track [Page 42] +- +-RFC 3720 iSCSI April 2004 +- +- +-3.5.1. Request/Response Types Carrying SCSI Payload +- +-3.5.1.1. SCSI-Command +- +- This request carries the SCSI CDB and all the other SCSI execute +- command procedure call (see [SAM2]) IN arguments such as task +- attributes, Expected Data Transfer Length for one or both transfer +- directions (the latter for bidirectional commands), and Task Tag (as +- part of the I_T_L_x nexus). The I_T_L nexus is derived by the +- initiator and target from the LUN field in the request and the I_T +- nexus is implicit in the session identification. +- +- In addition, the SCSI-command PDU carries information required for +- the proper operation of the iSCSI protocol - the command sequence +- number (CmdSN) for the session and the expected status number +- (ExpStatSN) for the connection. +- +- All or part of the SCSI output (write) data associated with the SCSI +- command may be sent as part of the SCSI-Command PDU as a data +- segment. +- +-3.5.1.2. SCSI-Response +- +- The SCSI-Response carries all the SCSI execute-command procedure call +- (see [SAM2]) OUT arguments and the SCSI execute-command procedure +- call return value. +- +- The SCSI-Response contains the residual counts from the operation, if +- any, an indication of whether the counts represent an overflow or an +- underflow, and the SCSI status if the status is valid or a response +- code (a non-zero return value for the execute-command procedure call) +- if the status is not valid. +- +- For a valid status that indicates that the command has been +- processed, but resulted in an exception (e.g., a SCSI CHECK +- CONDITION), the PDU data segment contains the associated sense data. +- The use of Autosense ([SAM2]) is REQUIRED by iSCSI. +- +- Some data segment content may also be associated (in the data +- segment) with a non-zero response code. +- +- In addition, the SCSI-Response PDU carries information required for +- the proper operation of the iSCSI protocol: +- +- - The number of Data-In PDUs that a target has sent (to enable +- the initiator to check that all have arrived). +- - StatSN - the Status Sequence Number on this connection. +- +- +- +- +-Satran, et al. Standards Track [Page 43] +- +-RFC 3720 iSCSI April 2004 +- +- +- - ExpCmdSN - the next Expected Command Sequence Number at the +- target. +- - MaxCmdSN - the maximum CmdSN acceptable at the target from +- this initiator. +- +-3.5.1.3 Task Management Function Request +- +- The Task Management function request provides an initiator with a way +- to explicitly control the execution of one or more SCSI Tasks or +- iSCSI functions. The PDU carries a function identifier (which task +- management function to perform) and enough information to +- unequivocally identify the task or task-set on which to perform the +- action, even if the task(s) to act upon has not yet arrived or has +- been discarded due to an error. +- +- The referenced tag identifies an individual task if the function +- refers to an individual task. +- +- The I_T_L nexus identifies task sets. In iSCSI the I_T_L nexus is +- identified by the LUN and the session identification (the session +- identifies an I_T nexus). +- +- For task sets, the CmdSN of the Task Management function request +- helps identify the tasks upon which to act, namely all tasks +- associated with a LUN and having a CmdSN preceding the Task +- Management function request CmdSN. +- +- For a Task Management function, the coordination between responses to +- the tasks affected and the Task Management function response is done +- by the target. +- +-3.5.1.4. Task Management Function Response +- +- The Task Management function response carries an indication of +- function completion for a Task Management function request including +- how it was completed (response and qualifier) and additional +- information for failure responses. +- +- After the Task Management response indicates Task Management function +- completion, the initiator will not receive any additional responses +- from the affected tasks. +- +-3.5.1.5. SCSI Data-Out and SCSI Data-In +- +- SCSI Data-Out and SCSI Data-In are the main vehicles by which SCSI +- data payload is carried between initiator and target. Data payload +- is associated with a specific SCSI command through the Initiator Task +- Tag. For target convenience, outgoing solicited data also carries a +- +- +- +-Satran, et al. Standards Track [Page 44] +- +-RFC 3720 iSCSI April 2004 +- +- +- Target Transfer Tag (copied from R2T) and the LUN. Each PDU contains +- the payload length and the data offset relative to the buffer address +- contained in the SCSI execute command procedure call. +- +- In each direction, the data transfer is split into "sequences". An +- end-of-sequence is indicated by the F bit. +- +- An outgoing sequence is either unsolicited (only the first sequence +- can be unsolicited) or consists of all the Data-Out PDUs sent in +- response to an R2T. +- +- Input sequences are built to enable the direction switching for +- bidirectional commands. +- +- For input, the target may request positive acknowledgement of input +- data. This is limited to sessions that support error recovery and is +- implemented through the A bit in the SCSI Data-In PDU header. +- +- Data-In and Data-Out PDUs also carry the DataSN to enable the +- initiator and target to detect missing PDUs (discarded due to an +- error). +- +- In addition, StatSN is carried by the Data-In PDUs. +- +- To enable a SCSI command to be processed while involving a minimum +- number of messages, the last SCSI Data-In PDU passed for a command +- may also contain the status if the status indicates termination with +- no exceptions (no sense or response involved). +- +-3.5.1.6. Ready To Transfer (R2T) +- +- R2T is the mechanism by which the SCSI target "requests" the +- initiator for output data. R2T specifies to the initiator the offset +- of the requested data relative to the buffer address from the execute +- command procedure call and the length of the solicited data. +- +- To help the SCSI target associate the resulting Data-Out with an R2T, +- the R2T carries a Target Transfer Tag that will be copied by the +- initiator in the solicited SCSI Data-Out PDUs. There are no protocol +- specific requirements with regard to the value of these tags, but it +- is assumed that together with the LUN, they will enable the target to +- associate data with an R2T. +- +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 45] +- +-RFC 3720 iSCSI April 2004 +- +- +- R2T also carries information required for proper operation of the +- iSCSI protocol, such as: +- +- - R2TSN (to enable an initiator to detect a missing R2T) +- - StatSN +- - ExpCmdSN +- - MaxCmdSN +- +-3.5.2. Requests/Responses carrying SCSI and iSCSI Payload +- +-3.5.2.1. Asynchronous Message +- +- Asynchronous Messages are used to carry SCSI asynchronous events +- (AEN) and iSCSI asynchronous messages. +- +- When carrying an AEN, the event details are reported as sense data in +- the data segment. +- +-3.5.3. Requests/Responses Carrying iSCSI Only Payload +- +-3.5.3.1. Text Request and Text Response +- +- Text requests and responses are designed as a parameter negotiation +- vehicle and as a vehicle for future extension. +- +- In the data segment, Text Requests/Responses carry text information +- using a simple "key=value" syntax. +- +- Text Request/Responses may form extended sequences using the same +- Initiator Task Tag. The initiator uses the F (Final) flag bit in the +- text request header to indicate its readiness to terminate a +- sequence. The target uses the F (Final) flag bit in the text +- response header to indicate its consent to sequence termination. +- +- Text Request and Responses also use the Target Transfer Tag to +- indicate continuation of an operation or a new beginning. A target +- that wishes to continue an operation will set the Target Transfer Tag +- in a Text Response to a value different from the default 0xffffffff. +- An initiator willing to continue will copy this value into the Target +- Transfer Tag of the next Text Request. If the initiator wants to +- restart the current target negotiation (start fresh) will set the +- Target Transfer Tag to 0xffffffff. +- +- Although a complete exchange is always started by the initiator, +- specific parameter negotiations may be initiated by the initiator or +- target. +- +- +- +- +- +-Satran, et al. Standards Track [Page 46] +- +-RFC 3720 iSCSI April 2004 +- +- +-3.5.3.2. Login Request and Login Response +- +- Login Requests and Responses are used exclusively during the Login +- Phase of each connection to set up the session and connection +- parameters. (The Login Phase consists of a sequence of login +- requests and responses carrying the same Initiator Task Tag.) +- +- A connection is identified by an arbitrarily selected connection-ID +- (CID) that is unique within a session. +- +- Similar to the Text Requests and Responses, Login Requests/Responses +- carry key=value text information with a simple syntax in the data +- segment. +- +- The Login Phase proceeds through several stages (security +- negotiation, operational parameter negotiation) that are selected +- with two binary coded fields in the header -- the "current stage" +- (CSG) and the "next stage" (NSG) with the appearance of the latter +- being signaled by the "transit" flag (T). +- +- The first Login Phase of a session plays a special role, called the +- leading login, which determines some header fields (e.g., the version +- number, the maximum number of connections, and the session +- identification). +- +- The CmdSN initial value is also set by the leading login. +- +- StatSN for each connection is initiated by the connection login. +- +- A login request may indicate an implied logout (cleanup) of the +- connection to be logged in (a connection restart) by using the same +- Connection ID (CID) as an existing connection, as well as the same +- session identifying elements of the session to which the old +- connection was associated. +- +-3.5.3.3. Logout Request and Response +- +- Logout Requests and Responses are used for the orderly closing of +- connections for recovery or maintenance. The logout request may be +- issued following a target prompt (through an asynchronous message) or +- at an initiators initiative. When issued on the connection to be +- logged out, no other request may follow it. +- +- The Logout Response indicates that the connection or session cleanup +- is completed and no other responses will arrive on the connection (if +- received on the logging out connection). In addition, the Logout +- Response indicates how long the target will continue to hold +- resources for recovery (e.g., command execution that continues on a +- +- +- +-Satran, et al. Standards Track [Page 47] +- +-RFC 3720 iSCSI April 2004 +- +- +- new connection) in the text key Time2Retain and how long the +- initiator must wait before proceeding with recovery in the text key +- Time2Wait. +- +-3.5.3.4. SNACK Request +- +- With the SNACK Request, the initiator requests retransmission of +- numbered-responses or data from the target. A single SNACK request +- covers a contiguous set of missing items, called a run, of a given +- type of items. The type is indicated in a type field in the PDU +- header. The run is composed of an initial item (StatSN, DataSN, +- R2TSN) and the number of missed Status, Data, or R2T PDUs. For long +- Data-In sequences, the target may request (at predefined minimum +- intervals) a positive acknowledgement for the data sent. A SNACK +- request with a type field that indicates ACK and the number of +- Data-In PDUs acknowledged conveys this positive acknowledgement. +- +-3.5.3.5. Reject +- +- Reject enables the target to report an iSCSI error condition (e.g., +- protocol, unsupported option) that uses a Reason field in the PDU +- header and includes the complete header of the bad PDU in the Reject +- PDU data segment. +- +-3.5.3.6. NOP-Out Request and NOP-In Response +- +- This request/response pair may be used by an initiator and target as +- a "ping" mechanism to verify that a connection/session is still +- active and all of its components are operational. Such a ping may be +- triggered by the initiator or target. The triggering party indicates +- that it wants a reply by setting a value different from the default +- 0xffffffff in the corresponding Initiator/Target Transfer Tag. +- +- NOP-In/NOP-Out may also be used "unidirectional" to convey to the +- initiator/target command, status or data counter values when there is +- no other "carrier" and there is a need to update the initiator/ +- target. +- +-4. SCSI Mode Parameters for iSCSI +- +- There are no iSCSI specific mode pages. +- +-5. Login and Full Feature Phase Negotiation +- +- iSCSI parameters are negotiated at session or connection +- establishment by using Login Requests and Responses (see Section +- 3.2.3 iSCSI Login) and during the Full Feature Phase (Section 3.2.4 +- iSCSI Full Feature Phase) by using Text Requests and Responses. In +- +- +- +-Satran, et al. Standards Track [Page 48] +- +-RFC 3720 iSCSI April 2004 +- +- +- both cases the mechanism used is an exchange of iSCSI-text-key=value +- pairs. For brevity iSCSI-text-keys are called just keys in the rest +- of this document. +- +- Keys are either declarative or require negotiation and the key +- description indicates if the key is declarative or requires +- negotiation. +- +- For the declarative keys, the declaring party sets a value for the +- key. The key specification indicates if the key can be declared by +- the initiator, target or both. +- +- For the keys that require negotiation one of the parties (the +- proposing party) proposes a value or set of values by including the +- key=value in the data part of a Login or Text Request or Response +- PDUs. The other party (the accepting party) makes a selection based +- on the value or list of values proposed and includes the selected +- value in a key=value in the data part of one of the following Login +- or Text Response or Request PDUs. For most of the keys both the +- initiator and target can be proposing parties. +- +- The login process proceeds in two stages - the security negotiation +- stage and the operational parameter negotiation stage. Both stages +- are optional but at least one of them has to be present to enable the +- setting of some mandatory parameters. +- +- If present, the security negotiation stage precedes the operational +- parameter negotiation stage. +- +- Progression from stage to stage is controlled by the T (Transition) +- bit in the Login Request/Response PDU header. Through the T bit set +- to 1, the initiator indicates that it would like to transition. The +- target agrees to the transition (and selects the next stage) when +- ready. A field in the Login PDU header indicates the current stage +- (CSG) and during transition, another field indicates the next stage +- (NSG) proposed (initiator) and selected (target). +- +- The text negotiation process is used to negotiate or declare +- operational parameters. The negotiation process is controlled by the +- F (final) bit in the PDU header. During text negotiations, the F bit +- is used by the initiator to indicate that it is ready to finish the +- negotiation and by the Target to acquiesce the end of negotiation. +- +- Since some key=value pairs may not fit entirely in a single PDU, the +- C (continuation) bit is used (both in Login and Text) to indicate +- that "more follows". +- +- +- +- +- +-Satran, et al. Standards Track [Page 49] +- +-RFC 3720 iSCSI April 2004 +- +- +- The text negotiation uses an additional mechanism by which a target +- may deliver larger amounts of data to an enquiring initiator. The +- target sets a Target Task Tag to be used as a bookmark that when +- returned by the initiator, means "go on". If reset to a "neutral +- value", it means "forget about the rest". +- +- This chapter details types of keys and values used, the syntax rules +- for parameter formation, and the negotiation schemes to be used with +- different types of parameters. +- +-5.1. Text Format +- +- The initiator and target send a set of key=value pairs encoded in +- UTF-8 Unicode. All the text keys and text values specified in this +- document are to be presented and interpreted in the case in which +- they appear in this document. They are case sensitive. +- +- The following character symbols are used in this document for text +- items (the hexadecimal values represent Unicode code points): +- +- (a-z, A-Z) - letters +- (0-9) - digits +- " " (0x20) - space +- "." (0x2e) - dot +- "-" (0x2d) - minus +- "+" (0x2b) - plus +- "@" (0x40) - commercial at +- "_" (0x5f) - underscore +- "=" (0x3d) - equal +- ":" (0x3a) - colon +- "/" (0x2f) - solidus or slash +- "[" (0x5b) - left bracket +- "]" (0x5d) - right bracket +- null (0x00) - null separator +- "," (0x2c) - comma +- "~" (0x7e) - tilde +- +- Key=value pairs may span PDU boundaries. An initiator or target that +- sends partial key=value text within a PDU indicates that more text +- follows by setting the C bit in the Text or Login Request or Text or +- Login Response to 1. Data segments in a series of PDUs that have the +- C bit set to 1 and end with a PDU that have the C bit set to 0, or +- include a single PDU that has the C bit set to 0, have to be +- considered as forming a single logical-text-data-segment (LTDS). +- +- Every key=value pair, including the last or only pair in a LTDS, MUST +- be followed by one null (0x00) delimiter. +- +- +- +- +-Satran, et al. Standards Track [Page 50] +- +-RFC 3720 iSCSI April 2004 +- +- +- A key-name is whatever precedes the first "=" in the key=value pair. +- The term key is used frequently in this document in place of +- key-name. +- +- A value is whatever follows the first "=" in the key=value pair up to +- the end of the key=value pair, but not including the null delimiter. +- +- The following definitions will be used in the rest of this document: +- +- standard-label: A string of one or more characters that consist of +- letters, digits, dot, minus, plus, commercial at, or underscore. +- A standard-label MUST begin with a capital letter and must not +- exceed 63 characters. +- +- key-name: A standard-label. +- +- text-value: A string of zero or more characters that consist of +- letters, digits, dot, minus, plus, commercial at, underscore, +- slash, left bracket, right bracket, or colon. +- +- iSCSI-name-value: A string of one or more characters that consist +- of minus, dot, colon, or any character allowed by the output of +- the iSCSI string-prep template as specified in [RFC3722] (see +- also Section 3.2.6.2 iSCSI Name Encoding). +- +- iSCSI-local-name-value: A UTF-8 string; no null characters are +- allowed in the string. This encoding is to be used for localized +- (internationalized) aliases. +- +- boolean-value: The string "Yes" or "No". +- +- hex-constant: A hexadecimal constant encoded as a string that +- starts with "0x" or "0X" followed by one or more digits or the +- letters a, b, c, d, e, f, A, B, C, D, E, or F. Hex-constants are +- used to encode numerical values or binary strings. When used to +- encode numerical values, the excessive use of leading 0 digits is +- discouraged. The string following 0X (or 0x) represents a base16 +- number that starts with the most significant base16 digit, +- followed by all other digits in decreasing order of significance +- and ending with the least-significant base16 digit. When used to +- encode binary strings, hexadecimal constants have an implicit +- byte-length that includes four bits for every hexadecimal digit +- of the constant, including leading zeroes. For example, a +- hex-constant of n hexadecimal digits has a byte-length of (the +- integer part of) (n+1)/2. +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 51] +- +-RFC 3720 iSCSI April 2004 +- +- +- decimal-constant: An unsigned decimal number with the digit 0 or a +- string of one or more digits that start with a non-zero digit. +- Decimal-constants are used to encode numerical values or binary +- strings. Decimal constants can only be used to encode binary +- strings if the string length is explicitly specified. There is +- no implicit length for decimal strings. Decimal-constant MUST +- NOT be used for parameter values if the values can be equal or +- greater than 2**64 (numerical) or for binary strings that can be +- longer than 64 bits. +- +- base64-constant: base64 constant encoded as a string that starts +- with "0b" or "0B" followed by 1 or more digits or letters or plus +- or slash or equal. The encoding is done according to [RFC2045] +- and each character, except equal, represents a base64 digit or a +- 6-bit binary string. Base64-constants are used to encode +- numerical-values or binary strings. When used to encode +- numerical values, the excessive use of leading 0 digits (encoded +- as A) is discouraged. The string following 0B (or 0b) represents +- a base64 number that starts with the most significant base64 +- digit, followed by all other digits in decreasing order of +- significance and ending with the least-significant base64 digit; +- the least significant base64 digit may be optionally followed by +- pad digits (encoded as equal) that are not considered as part of +- the number. When used to encode binary strings, base64-constants +- have an implicit +- byte-length that includes six bits for every character of the +- constant, excluding trailing equals (i.e., a base64-constant of n +- base64 characters excluding the trailing equals has a byte-length +- of ((the integer part of) (n*3/4)). Correctly encoded base64 +- strings cannot have n values of 1, 5 ... k*4+1. +- +- numerical-value: An unsigned integer always less than 2**64 encoded +- as a decimal-constant or a hex-constant. Unsigned integer +- arithmetic applies to numerical-values. +- +- large-numerical-value: An unsigned integer that can be larger than +- or equal to 2**64 encoded as a hex constant, or +- base64-constant. Unsigned integer arithmetic applies to +- large-numeric-values. +- +- numeric-range: Two numerical-values separated by a tilde where the +- value to the right of tilde must not be lower than the value to +- the left. +- +- regular-binary-value: A binary string not longer than 64 bits +- encoded as a decimal constant, hex constant, or base64-constant. +- The length of the string is either specified by the key +- definition or is the implicit byte-length of the encoded string. +- +- +- +-Satran, et al. Standards Track [Page 52] +- +-RFC 3720 iSCSI April 2004 +- +- +- large-binary-value: A binary string longer than 64 bits encoded as +- a hex-constant or base64-constant. The length of the string is +- either specified by the key definition or is the implicit +- byte-length of the encoded string. +- +- binary-value: A regular-binary-value or a large-binary-value. +- Operations on binary values are key specific. +- +- simple-value: Text-value, iSCSI-name-value, boolean-value, +- numeric-value, a numeric-range, or a binary-value. +- +- list-of-values: A sequence of text-values separated by a comma. +- +- If not otherwise specified, the maximum length of a simple-value (not +- its encoded representation) is 255 bytes, not including the delimiter +- (comma or zero byte). +- +- Any iSCSI target or initiator MUST support receiving at least 8192 +- bytes of key=value data in a negotiation sequence. When proposing or +- accepting authentication methods that explicitly require support for +- very long authentication items, the initiator and target MUST support +- receiving of at least 64 kilobytes of key=value data (see Appendix +- 11.1.2 - Simple Public-Key Mechanism (SPKM) - that require support +- for public key certificates). +- +-5.2. Text Mode Negotiation +- +- During login, and thereafter, some session or connection parameters +- are either declared or negotiated through an exchange of textual +- information. +- +- The initiator starts the negotiation and/or declaration through a +- Text or Login Request and indicates when it is ready for completion +- (by setting the F bit to 1 and keeping it to 1 in a Text Request or +- the T bit in the Login Request). As negotiation text may span PDU +- boundaries, a Text or Login Request or Text or Login Response PDU +- that has the C bit set to 1 MUST NOT have the F/T bit set to 1. +- +- A target receiving a Text or Login Request with the C bit set to 1 +- MUST answer with a Text or Login Response with no data segment +- (DataSegmentLength 0). An initiator receiving a Text or Login +- Response with the C bit set to 1 MUST answer with a Text or Login +- Request with no data segment (DataSegmentLength 0). +- +- A target or initiator SHOULD NOT use a Text or Login Response or Text +- or Login Request with no data segment (DataSegmentLength 0) unless +- explicitly required by a general or a key-specific negotiation rule. +- +- +- +- +-Satran, et al. Standards Track [Page 53] +- +-RFC 3720 iSCSI April 2004 +- +- +- The format of a declaration is: +- +- Declarer-> = +- +- The general format of text negotiation is: +- +- Proposer-> = +- Acceptor-> ={|NotUnderstood|Irrelevant|Reject} +- +- Thus a declaration is a one-way textual exchange while a negotiation +- is a two-way exchange. +- +- The proposer or declarer can either be the initiator or the target, +- and the acceptor can either be the target or initiator, respectively. +- Targets are not limited to respond to key=value pairs as proposed by +- the initiator. The target may propose key=value pairs of its own. +- +- All negotiations are explicit (i.e., the result MUST only be based on +- newly exchanged or declared values). There are no implicit +- proposals. If a proposal is not made, then a reply cannot be +- expected. Conservative design also requires that default values +- should not be relied upon when use of some other value has serious +- consequences. +- +- The value proposed or declared can be a numerical-value, a +- numerical-range defined by lower and upper values with both integers +- separated by a tilde, a binary value, a text-value, an +- iSCSI-name-value, an iSCSI-local-name-value, a boolean-value (Yes or +- No), or a list of comma separated text-values. A range, a +- large-numerical-value, an iSCSI-name-value and an +- iSCSI-local-name-value MAY ONLY be used if it is explicitly allowed. +- An accepted value can be a numerical-value, a large-numerical-value, +- a text-value, or a boolean-value. +- +- If a specific key is not relevant for the current negotiation, the +- acceptor may answer with the constant "Irrelevant" for all types of +- negotiation. However the negotiation is not considered as failed if +- the answer is "Irrelevant". The "Irrelevant" answer is meant for +- those cases in which several keys are presented by a proposing party +- but the selection made by the acceptor for one of the keys makes +- other keys irrelevant. The following example illustrates the use of +- "Irrelevant": +- +- I->T OFMarker=Yes,OFMarkInt=2048~8192 +- T->I OFMarker=No,OFMarkInt=Irrelevant +- +- I->T X#vkey1=(bla,alb,None),X#vkey2=(bla,alb) +- T->I X#vkey1=None,X#vkey2=Irrelevant +- +- +- +-Satran, et al. Standards Track [Page 54] +- +-RFC 3720 iSCSI April 2004 +- +- +- +- Any key not understood by the acceptor may be ignored by the acceptor +- without affecting the basic function. However, the answer for a key +- not understood MUST be key=NotUnderstood. +- +- The constants "None", "Reject", "Irrelevant", and "NotUnderstood" are +- reserved and MUST ONLY be used as described here. Violation of this +- rule is a protocol error (in particular the use of "Reject", +- "Irrelevant", and "NotUnderstood" as proposed values). +- +- Reject or Irrelevant are legitimate negotiation options where allowed +- but their excessive use is discouraged. A negotiation is considered +- complete when the acceptor has sent the key value pair even if the +- value is "Reject", "Irrelevant", or "NotUnderstood. Sending the key +- again would be a re-negotiation and is forbidden for many keys. +- +- If the acceptor sends "Reject" as an answer the negotiated key is +- left at its current value (or default if no value was set). If the +- current value is not acceptable to the proposer on the connection or +- to the session it is sent, the proposer MAY choose to terminate the +- connection or session. +- +- All keys in this document, except for the X extension formats, MUST +- be supported by iSCSI initiators and targets when used as specified +- here. If used as specified, these keys MUST NOT be answered with +- NotUnderstood. +- +- Implementers may introduce new keys by prefixing them with +- "X-", followed by their (reversed) domain name, or with new keys +- registered with IANA prefixing them with X#. For example, the entity +- owning the domain example.com can issue: +- +- X-com.example.bar.foo.do_something=3 +- +- or a new registered key may be used as in: +- +- X#SuperCalyPhraGilistic=Yes +- +- Implementers MAY also introduce new values, but ONLY for new keys or +- authentication methods (see Section 11 iSCSI Security Text Keys and +- Authentication Methods), or digests (see Section 12.1 HeaderDigest +- and DataDigest). +- +- Whenever parameter action or acceptance is dependent on other +- parameters, the dependency rules and parameter sequence must be +- specified with the parameters. +- +- +- +- +- +-Satran, et al. Standards Track [Page 55] +- +-RFC 3720 iSCSI April 2004 +- +- +- In the Login Phase (see Section 5.3 Login Phase), every stage is a +- separate negotiation. In the FullFeaturePhase, a Text Request +- Response sequence is a negotiation. Negotiations MUST be handled as +- atomic operations. For example, all negotiated values go into effect +- after the negotiation concludes in agreement or are ignored if the +- negotiation fails. +- +- Some parameters may be subject to integrity rules (e.g., parameter-x +- must not exceed parameter-y or parameter-u not 1 implies parameter-v +- be Yes). Whenever required, integrity rules are specified with the +- keys. Checking for compliance with the integrity rule must only be +- performed after all the parameters are available (the existent and +- the newly negotiated). An iSCSI target MUST perform integrity +- checking before the new parameters take effect. An initiator MAY +- perform integrity checking. +- +- An iSCSI initiator or target MAY terminate a negotiation that does +- not end within a reasonable time or number of exchanges. +- +-5.2.1. List negotiations +- +- In list negotiation, the originator sends a list of values (which may +- include "None") in its order of preference. +- +- The responding party MUST respond with the same key and the first +- value that it supports (and is allowed to use for the specific +- originator) selected from the originator list. +- +- The constant "None" MUST always be used to indicate a missing +- function. However, "None" is only a valid selection if it is +- explicitly proposed. +- +- If an acceptor does not understand any particular value in a list, it +- MUST ignore it. If an acceptor does not support, does not +- understand, or is not allowed to use any of the proposed options with +- a specific originator, it may use the constant "Reject" or terminate +- the negotiation. The selection of a value not proposed MUST be +- handled as a protocol error. +- +-5.2.2. Simple-value Negotiations +- +- For simple-value negotiations, the accepting party MUST answer with +- the same key. The value it selects becomes the negotiation result. +- +- Proposing a value not admissible (e.g., not within the specified +- bounds) MAY be answered with the constant "Reject" or the acceptor +- MAY select an admissible value. +- +- +- +- +-Satran, et al. Standards Track [Page 56] +- +-RFC 3720 iSCSI April 2004 +- +- +- The selection by the acceptor, of a value not admissible under the +- selection rules is considered a protocol error. The selection rules +- are key-specific. +- +- For a numerical range, the value selected must be an integer within +- the proposed range or "Reject" (if the range is unacceptable). +- +- In Boolean negotiations (i.e., those that result in keys taking the +- values Yes or No), the accepting party MUST answer with the same key +- and the result of the negotiation when the received value does not +- determine that result by itself. The last value transmitted becomes +- the negotiation result. The rules for selecting the value to answer +- with are expressed as Boolean functions of the value received, and +- the value that the accepting party would have selected if given a +- choice. +- +- Specifically, the two cases in which answers are OPTIONAL are: +- +- - The Boolean function is "AND" and the value "No" is received. +- The outcome of the negotiation is "No". +- - The Boolean function is "OR" and the value "Yes" is received. +- The outcome of the negotiation is "Yes". +- +- Responses are REQUIRED in all other cases, and the value chosen and +- sent by the acceptor becomes the outcome of the negotiation. +- +-5.3. Login Phase +- +- The Login Phase establishes an iSCSI connection between an initiator +- and a target; it also creates a new session or associates the +- connection to an existing session. The Login Phase sets the iSCSI +- protocol parameters, security parameters, and authenticates the +- initiator and target to each other. +- +- The Login Phase is only implemented via Login Request and Responses. +- The whole Login Phase is considered as a single task and has a single +- Initiator Task Tag (similar to the linked SCSI commands). +- +- The default MaxRecvDataSegmentLength is used during Login. +- +- The Login Phase sequence of requests and responses proceeds as +- follows: +- +- - Login initial request +- - Login partial response (optional) +- - More Login Requests and Responses (optional) +- - Login Final-Response (mandatory) +- +- +- +- +-Satran, et al. Standards Track [Page 57] +- +-RFC 3720 iSCSI April 2004 +- +- +- The initial Login Request of any connection MUST include the +- InitiatorName key=value pair. The initial Login Request of the first +- connection of a session MAY also include the SessionType key=value +- pair. For any connection within a session whose type is not +- "Discovery", the first Login Request MUST also include the TargetName +- key=value pair. +- +- The Login Final-response accepts or rejects the Login Request. +- +- The Login Phase MAY include a SecurityNegotiation stage and a +- LoginOperationalNegotiation stage or both, but MUST include at least +- one of them. The included stage MAY be empty except for the +- mandatory names. +- +- The Login Requests and Responses contain a field (CSG) that indicates +- the current negotiation stage (SecurityNegotiation or +- LoginOperationalNegotiation). If both stages are used, the +- SecurityNegotiation MUST precede the LoginOperationalNegotiation. +- +- Some operational parameters can be negotiated outside the login +- through Text Requests and Responses. +- +- Security MUST be completely negotiated within the Login Phase. The +- use of underlying IPsec security is specified in Chapter 8 and in +- [RFC3723]. iSCSI support for security within the protocol only +- consists of authentication in the Login Phase. +- +- In some environments, a target or an initiator is not interested in +- authenticating its counterpart. It is possible to bypass +- authentication through the Login Request and Response. +- +- The initiator and target MAY want to negotiate iSCSI authentication +- parameters. Once this negotiation is completed, the channel is +- considered secure. +- +- Most of the negotiation keys are only allowed in a specific stage. +- The SecurityNegotiation keys appear in Chapter 11 and the +- LoginOperationalNegotiation keys appear in Chapter 12. Only a +- limited set of keys (marked as Any-Stage in Chapter 12) may be used +- in any of the two stages. +- +- Any given Login Request or Response belongs to a specific stage; this +- determines the negotiation keys allowed with the request or response. +- It is considered to be a protocol error to send a key that is not +- allowed in the current stage. +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 58] +- +-RFC 3720 iSCSI April 2004 +- +- +- Stage transition is performed through a command exchange (request/ +- response) that carries the T bit and the same CSG code. During this +- exchange, the next stage is selected by the target through the "next +- stage" code (NSG). The selected NSG MUST NOT exceed the value stated +- by the initiator. The initiator can request a transition whenever it +- is ready, but a target can only respond with a transition after one +- is proposed by the initiator. +- +- In a negotiation sequence, the T bit settings in one pair of Login +- Request-Responses have no bearing on the T bit settings of the next +- pair. An initiator that has a T bit set to 1 in one pair and is +- answered with a T bit setting of 0, may issue the next request with +- the T bit set to 0. +- +- When a transition is requested by the initiator and acknowledged by +- the target, both the initiator and target switch to the selected +- stage. +- +- Targets MUST NOT submit parameters that require an additional +- initiator Login Request in a Login Response with the T bit set to 1. +- +- Stage transitions during login (including entering and exit) are only +- possible as outlined in the following table: +- +- +-----------------------------------------------------------+ +- |From To -> | Security | Operational | FullFeature | +- | | | | | | +- | V | | | | +- +-----------------------------------------------------------+ +- | (start) | yes | yes | no | +- +-----------------------------------------------------------+ +- | Security | no | yes | yes | +- +-----------------------------------------------------------+ +- | Operational | no | no | yes | +- +-----------------------------------------------------------+ +- +- The Login Final-Response that accepts a Login Request can only come +- as a response to a Login Request with the T bit set to 1, and both +- the request and response MUST indicate FullFeaturePhase as the next +- phase via the NSG field. +- +- Neither the initiator nor the target should attempt to declare or +- negotiate a parameter more than once during login except for +- responses to specific keys that explicitly allow repeated key +- declarations (e.g., TargetAddress). An attempt to +- renegotiate/redeclare parameters not specifically allowed MUST be +- detected by the initiator and target. If such an attempt is detected +- +- +- +- +-Satran, et al. Standards Track [Page 59] +- +-RFC 3720 iSCSI April 2004 +- +- +- by the target, the target MUST respond with Login reject (initiator +- error); if detected by the initiator, the initiator MUST drop the +- connection. +- +-5.3.1. Login Phase Start +- +- The Login Phase starts with a Login Request from the initiator to the +- target. The initial Login Request includes: +- +- - Protocol version supported by the initiator. +- - iSCSI Initiator Name and iSCSI Target Name +- - ISID, TSIH, and connection Ids +- - Negotiation stage that the initiator is ready to enter. +- +- A login may create a new session or it may add a connection to an +- existing session. Between a given iSCSI Initiator Node (selected +- only by an InitiatorName) and a given iSCSI target defined by an +- iSCSI TargetName and a Target Portal Group Tag, the login results are +- defined by the following table: +- +- +- +------------------------------------------------------------------+ +- |ISID | TSIH | CID | Target action | +- +------------------------------------------------------------------+ +- |new | non-zero | any | fail the login | +- | | | | ("session does not exist") | +- +------------------------------------------------------------------+ +- |new | zero | any | instantiate a new session | +- +------------------------------------------------------------------+ +- |existing | zero | any | do session reinstatement | +- | | | | (see section 5.3.5) | +- +------------------------------------------------------------------+ +- |existing | non-zero | new | add a new connection to | +- | | existing | | the session | +- +------------------------------------------------------------------+ +- |existing | non-zero |existing| do connection reinstatement| +- | | existing | | (see section 5.3.4) | +- +------------------------------------------------------------------+ +- |existing | non-zero | any | fail the login | +- | | new | | ("session does not exist") | +- +------------------------------------------------------------------+ +- +- Determination of "existing" or "new" are made by the target. +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 60] +- +-RFC 3720 iSCSI April 2004 +- +- +- Optionally, the Login Request may include: +- +- - Security parameters +- OR +- - iSCSI operational parameters +- AND/OR +- - The next negotiation stage that the initiator is ready to +- enter. +- +- The target can answer the login in the following ways: +- +- - Login Response with Login reject. This is an immediate rejection +- from the target that causes the connection to terminate and the +- session to terminate if this is the first (or only) connection of +- a new session. The T bit and the CSG and NSG fields are +- reserved. +- - Login Response with Login Accept as a final response (T bit set +- to 1 and the NSG in both request and response are set to +- FullFeaturePhase). The response includes the protocol version +- supported by the target and the session ID, and may include iSCSI +- operational or security parameters (that depend on the current +- stage). +- - Login Response with Login Accept as a partial response (NSG not +- set to FullFeaturePhase in both request and response) that +- indicates the start of a negotiation sequence. The response +- includes the protocol version supported by the target and either +- security or iSCSI parameters (when no security mechanism is +- chosen) supported by the target. +- +- If the initiator decides to forego the SecurityNegotiation stage, it +- issues the Login with the CSG set to LoginOperationalNegotiation and +- the target may reply with a Login Response that indicates that it is +- unwilling to accept the connection (see Section 10.13 Login Response) +- without SecurityNegotiation and will terminate the connection with a +- response of Authentication failure (see Section 10.13.5 Status-Class +- and Status-Detail). +- +- If the initiator is willing to negotiate iSCSI security, but is +- unwilling to make the initial parameter proposal and may accept a +- connection without iSCSI security, it issues the Login with the T bit +- set to 1, the CSG set to SecurityNegotiation, and the NSG set to +- LoginOperationalNegotiation. If the target is also ready to skip +- security, the Login Response only contains the TargetPortalGroupTag +- key (see Section 12.9 TargetPortalGroupTag), the T bit set to 1, the +- CSG set to SecurityNegotiation, and the NSG set to +- LoginOperationalNegotiation. +- +- +- +- +- +-Satran, et al. Standards Track [Page 61] +- +-RFC 3720 iSCSI April 2004 +- +- +- An initiator that chooses to operate without iSCSI security, with all +- the operational parameters taking the default values, issues the +- Login with the T bit set to 1, the CSG set to +- LoginOperationalNegotiation, and the NSG set to FullFeaturePhase. If +- the target is also ready to forego security and can finish its +- LoginOperationalNegotiation, the Login Response has T bit set to 1, +- the CSG set to LoginOperationalNegotiation, and the NSG set to +- FullFeaturePhase in the next stage. +- +- During the Login Phase the iSCSI target MUST return the +- TargetPortalGroupTag key with the first Login Response PDU with which +- it is allowed to do so (i.e., the first Login Response issued after +- the first Login Request with the C bit set to 0) for all session +- types when TargetName is given and the response is not a redirection. +- The TargetPortalGroupTag key value indicates the iSCSI portal group +- servicing the Login Request PDU. If the reconfiguration of iSCSI +- portal groups is a concern in a given environment, the iSCSI +- initiator should use this key to ascertain that it had indeed +- initiated the Login Phase with the intended target portal group. +- +-5.3.2. iSCSI Security Negotiation +- +- The security exchange sets the security mechanism and authenticates +- the initiator user and the target to each other. The exchange +- proceeds according to the authentication method chosen in the +- negotiation phase and is conducted using the Login Requests' and +- responses' key=value parameters. +- +- An initiator directed negotiation proceeds as follows: +- +- - The initiator sends a Login Request with an ordered list of the +- options it supports (authentication algorithm). The options are +- listed in the initiator's order of preference. The initiator MAY +- also send private or public extension options. +- +- - The target MUST reply with the first option in the list it +- supports and is allowed to use for the specific initiator unless +- it does not support any, in which case it MUST answer with +- "Reject" (see Section 5.2 Text Mode Negotiation). The parameters +- are encoded in UTF8 as key=value. For security parameters, see +- Chapter 11. +- +- - When the initiator considers that it is ready to conclude the +- SecurityNegotiation stage, it sets the T bit to 1 and the NSG to +- what it would like the next stage to be. The target will then +- set the T bit to 1 and set the NSG to the next stage in the Login +- Response when it finishes sending its security keys. The next +- +- +- +- +-Satran, et al. Standards Track [Page 62] +- +-RFC 3720 iSCSI April 2004 +- +- +- stage selected will be the one the target selected. If the next +- stage is FullFeaturePhase, the target MUST respond with a Login +- Response with the TSIH value. +- +- If the security negotiation fails at the target, then the target MUST +- send the appropriate Login Response PDU. If the security negotiation +- fails at the initiator, the initiator SHOULD close the connection. +- +- It should be noted that the negotiation might also be directed by the +- target if the initiator does support security, but is not ready to +- direct the negotiation (propose options). +- +-5.3.3. Operational Parameter Negotiation During the Login Phase +- +- Operational parameter negotiation during the login MAY be done: +- +- - Starting with the first Login Request if the initiator does not +- propose any security/integrity option. +- +- - Starting immediately after the security negotiation if the +- initiator and target perform such a negotiation. +- +- Operational parameter negotiation MAY involve several Login +- Request-Response exchanges started and terminated by the initiator. +- The initiator MUST indicate its intent to terminate the negotiation +- by setting the T bit to 1; the target sets the T bit to 1 on the last +- response. +- +- If the target responds to a Login Request that has the T bit set to 1 +- with a Login Response that has the T bit set to 0, the initiator +- should keep sending the Login Request (even empty) with the T bit set +- to 1, while it still wants to switch stage, until it receives the +- Login Response that has the T bit set to 1 or it receives a key that +- requires it to set the T bit to 0. +- +- Some session specific parameters can only be specified during the +- Login Phase of the first connection of a session (i.e., begun by a +- Login Request that contains a zero-valued TSIH) - the leading Login +- Phase (e.g., the maximum number of connections that can be used for +- this session). +- +- A session is operational once it has at least one connection in +- FullFeaturePhase. New or replacement connections can only be added +- to a session after the session is operational. +- +- For operational parameters, see Chapter 12. +- +- +- +- +- +-Satran, et al. Standards Track [Page 63] +- +-RFC 3720 iSCSI April 2004 +- +- +-5.3.4. Connection Reinstatement +- +- Connection reinstatement is the process of an initiator logging in +- with an ISID-TSIH-CID combination that is possibly active from the +- target's perspective, which causes the implicit logging out of the +- connection corresponding to the CID, and reinstating a new Full +- Feature Phase iSCSI connection in its place (with the same CID). +- Thus, the TSIH in the Login PDU MUST be non-zero and the CID does not +- change during a connection reinstatement. The Login Request performs +- the logout function of the old connection if an explicit logout was +- not performed earlier. In sessions with a single connection, this +- may imply the opening of a second connection with the sole purpose of +- cleaning up the first. Targets MUST support opening a second +- connection even when they do not support multiple connections in Full +- Feature Phase if ErrorRecoveryLevel is 2 and SHOULD support opening a +- second connection if ErrorRecoveryLevel is less than 2. +- +- If the operational ErrorRecoveryLevel is 2, connection reinstatement +- enables future task reassignment. If the operational +- ErrorRecoveryLevel is less than 2, connection reinstatement is the +- replacement of the old CID without enabling task reassignment. In +- this case, all the tasks that were active on the old CID must be +- immediately terminated without further notice to the initiator. +- +- The initiator connection state MUST be CLEANUP_WAIT (section 7.1.3) +- when the initiator attempts a connection reinstatement. +- +- In practical terms, in addition to the implicit logout of the old +- connection, reinstatement is equivalent to a new connection login. +- +-5.3.5. Session Reinstatement, Closure, and Timeout +- +- Session reinstatement is the process of the initiator logging in with +- an ISID that is possibly active from the target's perspective. Thus +- implicitly logging out the session that corresponds to the ISID and +- reinstating a new iSCSI session in its place (with the same ISID). +- Therefore, the TSIH in the Login PDU MUST be zero to signal session +- reinstatement. Session reinstatement causes all the tasks that were +- active on the old session to be immediately terminated by the target +- without further notice to the initiator. +- +- The initiator session state MUST be FAILED (Section 7.3 Session State +- Diagrams) when the initiator attempts a session reinstatement. +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 64] +- +-RFC 3720 iSCSI April 2004 +- +- +- Session closure is an event defined to be one of the following: +- +- - A successful "session close" logout. +- - A successful "connection close" logout for the last Full Feature +- Phase connection when no other connection in the session is +- waiting for cleanup (Section 7.2 Connection Cleanup State Diagram +- for Initiators and Targets) and no tasks in the session are +- waiting for reassignment. +- +- Session timeout is an event defined to occur when the last connection +- state timeout expires and no tasks are waiting for reassignment. +- This takes the session to the FREE state (N6 transition in the +- session state diagram). +- +-5.3.5.1. Loss of Nexus Notification +- +- The iSCSI layer provides the SCSI layer with the "I_T nexus loss" +- notification when any one of the following events happens: +- +- a) Successful completion of session reinstatement. +- b) Session closure event. +- c) Session timeout event. +- +- Certain SCSI object clearing actions may result due to the +- notification in the SCSI end nodes, as documented in Appendix F. +- - Clearing Effects of Various Events on Targets -. +- +-5.3.6. Session Continuation and Failure +- +- Session continuation is the process by which the state of a +- preexisting session continues to be used by connection reinstatement +- (Section 5.3.4 Connection Reinstatement), or by adding a connection +- with a new CID. Either of these actions associates the new transport +- connection with the session state. +- +- Session failure is an event where the last Full Feature Phase +- connection reaches the CLEANUP_WAIT state (Section 7.2 Connection +- Cleanup State Diagram for Initiators and Targets), or completes a +- successful recovery logout, thus causing all active tasks (that are +- formerly allegiant to the connection) to start waiting for task +- reassignment. +- +- +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 65] +- +-RFC 3720 iSCSI April 2004 +- +- +-5.4. Operational Parameter Negotiation Outside the Login Phase +- +- Some operational parameters MAY be negotiated outside (after) the +- Login Phase. +- +- Parameter negotiation in Full Feature Phase is done through Text +- requests and responses. Operational parameter negotiation MAY +- involve several Text request-response exchanges, which the initiator +- always starts and terminates using the same Initiator Task Tag. The +- initiator MUST indicate its intent to terminate the negotiation by +- setting the F bit to 1; the target sets the F bit to 1 on the last +- response. +- +- If the target responds to a Text request with the F bit set to 1 and +- with a Text response with the F bit set to 0, the initiator should +- keep sending the Text request (even empty) with the F bit set to 1, +- while it still wants to finish the negotiation, until it receives the +- Text response with the F bit set to 1. Responding to a Text request +- with the F bit set to 1 with an empty (no key=value pairs) response +- with the F bit set to 0 is discouraged. +- +- Targets MUST NOT submit parameters that require an additional +- initiator Text request in a Text response with the F bit set to 1. +- +- In a negotiation sequence, the F bit settings in one pair of Text +- request-responses have no bearing on the F bit settings of the next +- pair. An initiator that has the F bit set to 1 in a request and is +- being answered with an F bit setting of 0 may issue the next request +- with the F bit set to 0. +- +- Whenever the target responds with the F bit set to 0, it MUST set the +- Target Transfer Tag to a value other than the default 0xffffffff. +- +- An initiator MAY reset an operational parameter negotiation by +- issuing a Text request with the Target Transfer Tag set to the value +- 0xffffffff after receiving a response with the Target Transfer Tag +- set to a value other than 0xffffffff. A target may reset an +- operational parameter negotiation by answering a Text request with a +- Reject PDU. +- +- Neither the initiator nor the target should attempt to declare or +- negotiate a parameter more than once during any negotiation sequence +- without an intervening operational parameter negotiation reset, +- except for responses to specific keys that explicitly allow repeated +- key declarations (e.g., TargetAddress). If detected by the target, +- this MUST result in a Reject PDU with a reason of "protocol error". +- The initiator MUST reset the negotiation as outlined above. +- +- +- +- +-Satran, et al. Standards Track [Page 66] +- +-RFC 3720 iSCSI April 2004 +- +- +- Parameters negotiated by a text exchange negotiation sequence only +- become effective after the negotiation sequence is completed. +- +-6. iSCSI Error Handling and Recovery +- +-6.1. Overview +- +-6.1.1. Background +- +- The following two considerations prompted the design of much of the +- error recovery functionality in iSCSI: +- +- i) An iSCSI PDU may fail the digest check and be dropped, despite +- being received by the TCP layer. The iSCSI layer must +- optionally be allowed to recover such dropped PDUs. +- ii) A TCP connection may fail at any time during the data +- transfer. All the active tasks must optionally be allowed to +- continue on a different TCP connection within the same +- session. +- +- Implementations have considerable flexibility in deciding what degree +- of error recovery to support, when to use it and by which mechanisms +- to achieve the required behavior. Only the externally visible +- actions of the error recovery mechanisms must be standardized to +- ensure interoperability. +- +- This chapter describes a general model for recovery in support of +- interoperability. See Appendix E. - Algorithmic Presentation of +- Error Recovery Classes - for further detail on how the described +- model may be implemented. Compliant implementations do not have to +- match the implementation details of this model as presented, but the +- external behavior of such implementations must correspond to the +- externally observable characteristics of the presented model. +- +-6.1.2. Goals +- +- The major design goals of the iSCSI error recovery scheme are as +- follows: +- +- a) Allow iSCSI implementations to meet different requirements by +- defining a collection of error recovery mechanisms that +- implementations may choose from. +- b) Ensure interoperability between any two implementations +- supporting different sets of error recovery capabilities. +- c) Define the error recovery mechanisms to ensure command +- ordering even in the face of errors, for initiators that +- demand ordering. +- +- +- +- +-Satran, et al. Standards Track [Page 67] +- +-RFC 3720 iSCSI April 2004 +- +- +- d) Do not make additions in the fast path, but allow moderate +- complexity in the error recovery path. +- e) Prevent both the initiator and target from attempting to +- recover the same set of PDUs at the same time. For example, +- there must be a clear "error recovery functionality +- distribution" between the initiator and target. +- +-6.1.3. Protocol Features and State Expectations +- +- The initiator mechanisms defined in connection with error recovery +- are: +- +- a) NOP-OUT to probe sequence numbers of the target (section +- 10.18) +- b) Command retry (section 6.2.1) +- c) Recovery R2T support (section 6.7) +- d) Requesting retransmission of status/data/R2T using the SNACK +- facility (section 10.16) +- e) Acknowledging the receipt of the data (section 10.16) +- f) Reassigning the connection allegiance of a task to a different +- TCP connection (section 6.2.2) +- g) Terminating the entire iSCSI session to start afresh (section +- 6.1.4.4) +- +- The target mechanisms defined in connection with error recovery are: +- +- a) NOP-IN to probe sequence numbers of the initiator (section +- 10.19) +- b) Requesting retransmission of data using the recovery R2T +- feature (section 6.7) +- c) SNACK support (section 10.16) d) Requesting that parts of +- read data be acknowledged (section 10.7.2) +- e) Allegiance reassignment support (section 6.2.2) +- f) Terminating the entire iSCSI session to force the initiator to +- start over (section 6.1.4.4) +- +- For any outstanding SCSI command, it is assumed that iSCSI, in +- conjunction with SCSI at the initiator, is able to keep enough +- information to be able to rebuild the command PDU, and that outgoing +- data is available (in host memory) for retransmission while the +- command is outstanding. It is also assumed that at the target, +- incoming data (read data) MAY be kept for recovery or it can be +- reread from a device server. +- +- It is further assumed that a target will keep the "status & sense" +- for a command it has executed if it supports status retransmission. +- A target that agrees to support data retransmission is expected to be +- prepared to retransmit the outgoing data (i.e., Data-In) on request +- +- +- +-Satran, et al. Standards Track [Page 68] +- +-RFC 3720 iSCSI April 2004 +- +- +- until either the status for the completed command is acknowledged, or +- the data in question has been separately acknowledged. +- +-6.1.4. Recovery Classes +- +- iSCSI enables the following classes of recovery (in the order of +- increasing scope of affected iSCSI tasks): +- +- - Within a command (i.e., without requiring command restart). +- - Within a connection (i.e., without requiring the connection to +- be rebuilt, but perhaps requiring command restart). +- - Connection recovery (i.e., perhaps requiring connections to be +- rebuilt and commands to be reissued). +- - Session recovery. +- +- The recovery scenarios detailed in the rest of this section are +- representative rather than exclusive. In every case, they detail the +- lowest class recovery that MAY be attempted. The implementer is left +- to decide under which circumstances to escalate to the next recovery +- class and/or what recovery classes to implement. Both the iSCSI +- target and initiator MAY escalate the error handling to an error +- recovery class, which impacts a larger number of iSCSI tasks in any +- of the cases identified in the following discussion. +- +- In all classes, the implementer has the choice of deferring errors to +- the SCSI initiator (with an appropriate response code), in which case +- the task, if any, has to be removed from the target and all the side +- effects, such as ACA, must be considered. +- +- Use of within-connection and within-command recovery classes MUST NOT +- be attempted before the connection is in Full Feature Phase. +- +- In the detailed description of the recovery classes, the mandating +- terms (MUST, SHOULD, MAY, etc.) indicate normative actions to be +- executed if the recovery class is supported and used. +- +-6.1.4.1. Recovery Within-command +- +- At the target, the following cases lend themselves to +- within-command recovery: +- +- - Lost data PDU - realized through one of the following: +- +- a) Data digest error - dealt with as specified in Section 6.7 +- Digest Errors, using the option of a recovery R2T. +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 69] +- +-RFC 3720 iSCSI April 2004 +- +- +- b) Sequence reception timeout (no data or +- partial-data-and-no-F-bit) - considered an implicit sequence +- error and dealt with as specified in Section 6.8 Sequence +- Errors, using the option of a recovery R2T. +- c) Header digest error, which manifests as a sequence reception +- timeout or a sequence error - dealt with as specified in +- Section 6.8 Sequence Errors, using the option of a recovery +- R2T. +- +- At the initiator, the following cases lend themselves to +- within-command recovery: +- +- Lost data PDU or lost R2T - realized through one of the +- following: +- +- a) Data digest error - dealt with as specified in Section 6.7 +- Digest Errors, using the option of a SNACK. +- b) Sequence reception timeout (no status) or response reception +- timeout - dealt with as specified in Section 6.8 Sequence +- Errors, using the option of a SNACK. +- c) Header digest error, which manifests as a sequence reception +- timeout or a sequence error - dealt with as specified in +- Section 6.8 Sequence Errors, using the option of a SNACK. +- +- To avoid a race with the target, which may already have a recovery +- R2T or a termination response on its way, an initiator SHOULD NOT +- originate a SNACK for an R2T based on its internal timeouts (if any). +- Recovery in this case is better left to the target. +- +- The timeout values used by the initiator and target are outside the +- scope of this document. Sequence reception timeout is generally a +- large enough value to allow the data sequence transfer to be +- complete. +- +-6.1.4.2. Recovery Within-connection +- +- At the initiator, the following cases lend themselves to +- within-connection recovery: +- +- - Requests not acknowledged for a long time. Requests are +- acknowledged explicitly through ExpCmdSN or implicitly by +- receiving data and/or status. The initiator MAY retry +- non-acknowledged commands as specified in Section 6.2 Retry and +- Reassign in Recovery. +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 70] +- +-RFC 3720 iSCSI April 2004 +- +- +- - Lost iSCSI numbered Response. It is recognized by either +- identifying a data digest error on a Response PDU or a Data-In +- PDU carrying the status, or by receiving a Response PDU with a +- higher StatSN than expected. In the first case, digest error +- handling is done as specified in Section 6.7 Digest Errors using +- the option of a SNACK. In the second case, sequence error +- handling is done as specified in Section 6.8 Sequence Errors, +- using the option of a SNACK. +- +- At the target, the following cases lend themselves to +- within-connection recovery: +- +- - Status/Response not acknowledged for a long time. The target MAY +- issue a NOP-IN (with a valid Target Transfer Tag or otherwise) +- that carries the next status sequence number it is going to use +- in the StatSN field. This helps the initiator detect any missing +- StatSN(s) and issue a SNACK for the status. +- +- The timeout values used by the initiator and the target are outside +- the scope of this document. +- +-6.1.4.3. Connection Recovery +- +- At an iSCSI initiator, the following cases lend themselves to +- connection recovery: +- +- - TCP connection failure: The initiator MUST close the connection. +- It then MUST either implicitly or explicitly logout the failed +- connection with the reason code "remove the connection for +- recovery" and reassign connection allegiance for all commands +- still in progress associated with the failed connection on one or +- more connections (some or all of which MAY be newly established +- connections) using the "Task reassign" task management function +- (see Section 10.5.1 Function). For an initiator, a command is in +- progress as long as it has not received a response or a Data-In +- PDU including status. +- +- Note: The logout function is mandatory. However, a new connection +- establishment is only mandatory if the failed connection was the +- last or only connection in the session. +- +- - Receiving an Asynchronous Message that indicates one or all +- connections in a session has been dropped. The initiator MUST +- handle it as a TCP connection failure for the connection(s) +- referred to in the Message. +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 71] +- +-RFC 3720 iSCSI April 2004 +- +- +- At an iSCSI target, the following cases lend themselves to connection +- recovery: +- +- - TCP connection failure. The target MUST close the connection and, +- if more than one connection is available, the target SHOULD send +- an Asynchronous Message that indicates it has dropped the +- connection. Then, the target will wait for the initiator to +- continue recovery. +- +-6.1.4.4. Session Recovery +- +- Session recovery should be performed when all other recovery attempts +- have failed. Very simple initiators and targets MAY perform session +- recovery on all iSCSI errors and rely on recovery on the SCSI layer +- and above. +- +- Session recovery implies the closing of all TCP connections, +- internally aborting all executing and queued tasks for the given +- initiator at the target, terminating all outstanding SCSI commands +- with an appropriate SCSI service response at the initiator, and +- restarting a session on a new set of connection(s) (TCP connection +- establishment and login on all new connections). +- +- For possible clearing effects of session recovery on SCSI and iSCSI +- objects, refer to Appendix F. - Clearing Effects of Various Events on +- Targets -. +- +-6.1.5. Error Recovery Hierarchy +- +- The error recovery classes described so far are organized into a +- hierarchy for ease in understanding and to limit the implementation +- complexity. With few and well defined recovery levels +- interoperability is easier to achieve. The attributes of this +- hierarchy are as follows: +- +- a) Each level is a superset of the capabilities of the previous +- level. For example, Level 1 support implies supporting all +- capabilities of Level 0 and more. +- b) As a corollary, supporting a higher error recovery level means +- increased sophistication and possibly an increase in resource +- requirements. +- c) Supporting error recovery level "n" is advertised and +- negotiated by each iSCSI entity by exchanging the text key +- "ErrorRecoveryLevel=n". The lower of the two exchanged values +- is the operational ErrorRecoveryLevel for the session. +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 72] +- +-RFC 3720 iSCSI April 2004 +- +- +- The following diagram represents the error recovery hierarchy. +- +- + +- / +- / 2 \ <-- Connection recovery +- +-----+ +- / 1 \ <-- Digest failure recovery +- +---------+ +- / 0 \ <-- Session failure recovery +- +-------------+ +- +- The following table lists the error recovery capabilities expected +- from the implementations that support each error recovery level. +- +- +-------------------+--------------------------------------------+ +- |ErrorRecoveryLevel | Associated Error recovery capabilities | +- +-------------------+--------------------------------------------+ +- | 0 | Session recovery class | +- | | (Section 6.1.4.4 Session Recovery) | +- +-------------------+--------------------------------------------+ +- | 1 | Digest failure recovery (See Note below.) | +- | | plus the capabilities of ER Level 0 | +- +-------------------+--------------------------------------------+ +- | 2 | Connection recovery class | +- | | (Section 6.1.4.3 Connection Recovery) | +- | | plus the capabilities of ER Level 1 | +- +-------------------+--------------------------------------------+ +- +- Note: Digest failure recovery is comprised of two recovery classes: +- Within-Connection recovery class (Section 6.1.4.2 Recovery Within- +- connection) and Within-Command recovery class (Section 6.1.4.1 +- Recovery Within-command). +- +- When a defined value of ErrorRecoveryLevel is proposed by an +- originator in a text negotiation, the originator MUST support the +- functionality defined for the proposed value and additionally, the +- functionality corresponding to any defined value numerically less +- than the proposed. When a defined value of ErrorRecoveryLevel is +- returned by a responder in a text negotiation, the responder MUST +- support the functionality corresponding to the ErrorRecoveryLevel it +- is accepting. +- +- When either party attempts to use error recovery functionality beyond +- what is negotiated, the recovery attempts MAY fail unless an a priori +- agreement outside the scope of this document exists between the two +- parties to provide such support. +- +- +- +- +- +-Satran, et al. Standards Track [Page 73] +- +-RFC 3720 iSCSI April 2004 +- +- +- Implementations MUST support error recovery level "0", while the rest +- are OPTIONAL to implement. In implementation terms, the above +- striation means that the following incremental sophistication with +- each level is required. +- +- +-------------------+---------------------------------------------+ +- |Level transition | Incremental requirement | +- +-------------------+---------------------------------------------+ +- | 0->1 | PDU retransmissions on the same connection | +- +-------------------+---------------------------------------------+ +- | 1->2 | Retransmission across connections and | +- | | allegiance reassignment | +- +-------------------+---------------------------------------------+ +- +-6.2. Retry and Reassign in Recovery +- +- This section summarizes two important and somewhat related iSCSI +- protocol features used in error recovery. +- +-6.2.1. Usage of Retry +- +- By resending the same iSCSI command PDU ("retry") in the absence of a +- command acknowledgement (by way of an ExpCmdSN update) or a response, +- an initiator attempts to "plug" (what it thinks are) the +- discontinuities in CmdSN ordering on the target end. Discarded +- command PDUs, due to digest errors, may have created these +- discontinuities. +- +- Retry MUST NOT be used for reasons other than plugging command +- sequence gaps, and in particular, cannot be used for requesting PDU +- retransmissions from a target. Any such PDU retransmission requests +- for a currently allegiant command in progress may be made using the +- SNACK mechanism described in section 10.16, although the usage of +- SNACK is OPTIONAL. +- +- If initiators, as part of plugging command sequence gaps as described +- above, inadvertently issue retries for allegiant commands already in +- progress (i.e., targets did not see the discontinuities in CmdSN +- ordering), the duplicate commands are silently ignored by targets as +- specified in section 3.2.2.1. +- +- When an iSCSI command is retried, the command PDU MUST carry the +- original Initiator Task Tag and the original operational attributes +- (e.g., flags, function names, LUN, CDB etc.) as well as the original +- CmdSN. The command being retried MUST be sent on the same connection +- as the original command unless the original connection was already +- successfully logged out. +- +- +- +- +-Satran, et al. Standards Track [Page 74] +- +-RFC 3720 iSCSI April 2004 +- +- +-6.2.2. Allegiance Reassignment +- +- By issuing a "task reassign" task management request (Section 10.5.1 +- Function), the initiator signals its intent to continue an already +- active command (but with no current connection allegiance) as part of +- connection recovery. This means that a new connection allegiance is +- requested for the command, which seeks to associate it to the +- connection on which the task management request is being issued. +- Before the allegiance reassignment is attempted for a task, an +- implicit or explicit Logout with the reason code "remove the +- connection for recovery" ( see section 10.14) MUST be successfully +- completed for the previous connection to which the task was +- allegiant. +- +- In reassigning connection allegiance for a command, the targets +- SHOULD continue the command from its current state. For example, +- when reassigning read commands, the target SHOULD take advantage of +- the ExpDataSN field provided by the Task Management function request +- (which must be set to zero if there was no data transfer) and bring +- the read command to completion by sending the remaining data and +- sending (or resending) the status. ExpDataSN acknowledges all data +- sent up to, but not including, the Data-In PDU and or R2T with DataSN +- (or R2TSN) equal to ExpDataSN. However, targets may choose to +- send/receive all unacknowledged data or all of the data on a +- reassignment of connection allegiance if unable to recover or +- maintain an accurate state. Initiators MUST not subsequently request +- data retransmission through Data SNACK for PDUs numbered less than +- ExpDataSN (i.e., prior to the acknowledged sequence number). For all +- types of commands, a reassignment request implies that the task is +- still considered in progress by the initiator and the target must +- conclude the task appropriately if the target returns the "Function +- Complete" response to the reassignment request. This might possibly +- involve retransmission of data/R2T/status PDUs as necessary, but MUST +- involve the (re)transmission of the status PDU. +- +- It is OPTIONAL for targets to support the allegiance reassignment. +- This capability is negotiated via the ErrorRecoveryLevel text key +- during the login time. When a target does not support allegiance +- reassignment, it MUST respond with a Task Management response code of +- "Allegiance reassignment not supported". If allegiance reassignment +- is supported by the target, but the task is still allegiant to a +- different connection, or a successful recovery Logout of the +- previously allegiant connection was not performed, the target MUST +- respond with a Task Management response code of "Task still +- allegiant". +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 75] +- +-RFC 3720 iSCSI April 2004 +- +- +- If allegiance reassignment is supported by the target, the Task +- Management response to the reassignment request MUST be issued before +- the reassignment becomes effective. +- +- If a SCSI Command that involves data input is reassigned, any SNACK +- Tag it holds for a final response from the original connection is +- deleted and the default value of 0 MUST be used instead. +- +-6.3. Usage Of Reject PDU in Recovery +- +- Targets MUST NOT implicitly terminate an active task by sending a +- Reject PDU for any PDU exchanged during the life of the task. If the +- target decides to terminate the task, a Response PDU (SCSI, Text, +- Task, etc.) must be returned by the target to conclude the task. If +- the task had never been active before the Reject (i.e., the Reject is +- on the command PDU), targets should not send any further responses +- because the command itself is being discarded. +- +- The above rule means that the initiator can eventually expect a +- response on receiving Rejects, if the received Reject is for a PDU +- other than the command PDU itself. The non-command Rejects only have +- diagnostic value in logging the errors, and they can be used for +- retransmission decisions by the initiators. +- +- The CmdSN of the rejected command PDU (if it is a non-immediate +- command) MUST NOT be considered received by the target (i.e., a +- command sequence gap must be assumed for the CmdSN), even though the +- CmdSN of the rejected command PDU may be reliably ascertained. Upon +- receiving the Reject, the initiator MUST plug the CmdSN gap in order +- to continue to use the session. The gap may be plugged either by +- transmitting a command PDU with the same CmdSN, or by aborting the +- task (see section 6.9 on how an abort may plug a CmdSN gap). +- +- When a data PDU is rejected and its DataSN can be ascertained, a +- target MUST advance ExpDataSN for the current data burst if a +- recovery R2T is being generated. The target MAY advance its +- ExpDataSN if it does not attempt to recover the lost data PDU. +- +-6.4. Connection Timeout Management +- +- iSCSI defines two session-global timeout values (in seconds) +- - Time2Wait and Time2Retain - that are applicable when an iSCSI Full +- Feature Phase connection is taken out of service either intentionally +- or by an exception. Time2Wait is the initial "respite time" before +- attempting an explicit/implicit Logout for the CID in question or +- task reassignment for the affected tasks (if any). Time2Retain is +- the maximum time after the initial respite interval that the task +- and/or connection state(s) is/are guaranteed to be maintained on the +- +- +- +-Satran, et al. Standards Track [Page 76] +- +-RFC 3720 iSCSI April 2004 +- +- +- target to cater to a possible recovery attempt. Recovery attempts +- for the connection and/or task(s) SHOULD NOT be made before Time2Wait +- seconds, but MUST be completed within Time2Retain seconds after that +- initial Time2Wait waiting period. +- +-6.4.1. Timeouts on Transport Exception Events +- +- A transport connection shutdown or a transport reset without any +- preceding iSCSI protocol interactions informing the end-points of the +- fact causes a Full Feature Phase iSCSI connection to be abruptly +- terminated. The timeout values to be used in this case are the +- negotiated values of defaultTime2Wait (Section 12.15 +- DefaultTime2Wait) and DefaultTime2Retain (Section 12.16 +- DefaultTime2Retain) text keys for the session. +- +-6.4.2. Timeouts on Planned Decommissioning +- +- Any planned decommissioning of a Full Feature Phase iSCSI connection +- is preceded by either a Logout Response PDU, or an Async Message PDU. +- The Time2Wait and Time2Retain field values (section 10.15) in a +- Logout Response PDU, and the Parameter2 and Parameter3 fields of an +- Async Message (AsyncEvent types "drop the connection" or "drop all +- the connections"; section 10.9.1) specify the timeout values to be +- used in each of these cases. +- +- These timeout values are only applicable for the affected connection, +- and the tasks active on that connection. These timeout values have +- no bearing on initiator timers (if any) that are already running on +- connections or tasks associated with that session. +- +-6.5. Implicit Termination of Tasks +- +- A target implicitly terminates the active tasks due to iSCSI protocol +- dynamics in the following cases: +- +- a) When a connection is implicitly or explicitly logged out with +- the reason code of "Close the connection" and there are active +- tasks allegiant to that connection. +- +- b) When a connection fails and the connection state eventually +- times out (state transition M1 in Section 7.2.2 State +- Transition Descriptions for Initiators and Targets) and there +- are active tasks allegiant to that connection. +- +- c) When a successful Logout with the reason code of "remove the +- connection for recovery" is performed while there are active +- tasks allegiant to that connection, and those tasks eventually +- +- +- +- +-Satran, et al. Standards Track [Page 77] +- +-RFC 3720 iSCSI April 2004 +- +- +- time out after the Time2Wait and Time2Retain periods without +- allegiance reassignment. +- +- d) When a connection is implicitly or explicitly logged out with +- the reason code of "Close the session" and there are active +- tasks in that session. +- +- If the tasks terminated in the above cases a), b, c) and d)are SCSI +- tasks, they must be internally terminated as if with CHECK CONDITION +- status. This status is only meaningful for appropriately handling +- the internal SCSI state and SCSI side effects with respect to +- ordering because this status is never communicated back as a +- terminating status to the initiator. However additional actions may +- have to be taken at SCSI level depending on the SCSI context as +- defined by the SCSI standards (e.g., queued commands and ACA, in +- cases a), b), and c), after the tasks are terminated, the target MUST +- report a Unit Attention condition on the next command processed on +- any connection for each affected I_T_L nexus with the status of CHECK +- CONDITION, and the ASC/ASCQ value of 47h/7Fh - "SOME COMMANDS CLEARED +- BY ISCSI PROTOCOL EVENT" , etc. - see [SAM2] and [SPC3]). +- +-6.6. Format Errors +- +- The following two explicit violations of PDU layout rules are format +- errors: +- +- a) Illegal contents of any PDU header field except the Opcode +- (legal values are specified in Section 10 iSCSI PDU Formats). +- b) Inconsistent field contents (consistent field contents are +- specified in Section 10 iSCSI PDU Formats). +- +- Format errors indicate a major implementation flaw in one of the +- parties. +- +- When a target or an initiator receives an iSCSI PDU with a format +- error, it MUST immediately terminate all transport connections in the +- session either with a connection close or with a connection reset and +- escalate the format error to session recovery (see Section 6.1.4.4 +- Session Recovery). +- +-6.7. Digest Errors +- +- The discussion of the legal choices in handling digest errors below +- excludes session recovery as an explicit option, but either party +- detecting a digest error may choose to escalate the error to session +- recovery. +- +- +- +- +- +-Satran, et al. Standards Track [Page 78] +- +-RFC 3720 iSCSI April 2004 +- +- +- When a target or an initiator receives any iSCSI PDU, with a header +- digest error, it MUST either discard the header and all data up to +- the beginning of a later PDU or close the connection. Because the +- digest error indicates that the length field of the header may have +- been corrupted, the location of the beginning of a later PDU needs to +- be reliably ascertained by other means such as the operation of a +- sync and steering layer. +- +- When a target receives any iSCSI PDU with a payload digest error, it +- MUST answer with a Reject PDU with a reason code of +- Data-Digest-Error and discard the PDU. +- +- - If the discarded PDU is a solicited or unsolicited iSCSI data +- PDU (for immediate data in a command PDU, non-data PDU rule +- below applies), the target MUST do one of the following: +- a) Request retransmission with a recovery R2T. +- b) Terminate the task with a response PDU with a CHECK +- CONDITION Status and an iSCSI Condition of "protocol service +- CRC error" (Section 10.4.7.2 Sense Data). If the target +- chooses to implement this option, it MUST wait to receive +- all the data (signaled by a Data PDU with the final bit set +- for all outstanding R2Ts) before sending the response PDU. +- A task management command (such as an abort task) from the +- initiator during this wait may also conclude the task. +- - No further action is necessary for targets if the discarded PDU +- is a non-data PDU. In case of immediate data being present on +- a discarded command, the immediate data is implicitly recovered +- when the task is retried (see section 6.2.1), followed by the +- entire data transfer for the task. +- +- When an initiator receives any iSCSI PDU with a payload digest error, +- it MUST discard the PDU. +- +- - If the discarded PDU is an iSCSI data PDU, the initiator MUST do +- one of the following: +- +- a) Request the desired data PDU through SNACK. In response to the +- SNACK, the target MUST either resend the data PDU or reject the +- SNACK with a Reject PDU with a reason code of "SNACK reject" in +- which case: +- i) If the status has not already been sent for the command, +- the target MUST terminate the command with a CHECK +- CONDITION Status and an iSCSI Condition of "SNACK rejected" +- (Section 10.4.7.2 Sense Data). +- ii) If the status was already sent, no further action is +- necessary for the target. The initiator in this case MUST +- wait for the status to be received and then discard it, so +- as to internally signal the completion with CHECK CONDITION +- +- +- +-Satran, et al. Standards Track [Page 79] +- +-RFC 3720 iSCSI April 2004 +- +- +- Status and an iSCSI Condition of "protocol service CRC +- error" (Section 10.4.7.2 Sense Data). +- b) Abort the task and terminate the command with an error. +- +- - If the discarded PDU is a response PDU, the initiator MUST do one +- of the following: +- +- a) Request PDU retransmission with a status SNACK. +- b) Logout the connection for recovery and continue the tasks on a +- different connection instance as described in Section 6.2 Retry +- and Reassign in Recovery. +- c) Logout to close the connection (abort all the commands +- associated with the connection). +- +- - No further action is necessary for initiators if the discarded PDU +- is an unsolicited PDU (e.g., Async, Reject). Task timeouts as in +- the initiator waiting for a command completion, or process +- timeouts, as in the target waiting for a Logout, will ensure that +- the correct operational behavior will result in these cases +- despite the discarded PDU. +- +-6.8. Sequence Errors +- +- When an initiator receives an iSCSI R2T/data PDU with an out of order +- R2TSN/DataSN or a SCSI response PDU with an ExpDataSN that implies +- missing data PDU(s), it means that the initiator must have detected a +- header or payload digest error on one or more earlier R2T/data PDUs. +- The initiator MUST address these implied digest errors as described +- in Section 6.7 Digest Errors. When a target receives a data PDU with +- an out of order DataSN, it means that the target must have hit a +- header or payload digest error on at least one of the earlier data +- PDUs. The target MUST address these implied digest errors as +- described in Section 6.7 Digest Errors. +- +- When an initiator receives an iSCSI status PDU with an out of order +- StatSN that implies missing responses, it MUST address the one or +- more missing status PDUs as described in Section 6.7 Digest Errors. +- As a side effect of receiving the missing responses, the initiator +- may discover missing data PDUs. If the initiator wants to recover +- the missing data for a command, it MUST NOT acknowledge the received +- responses that start from the StatSN of the relevant command, until +- it has completed receiving all the data PDUs of the command. +- +- When an initiator receives duplicate R2TSNs (due to proactive +- retransmission of R2Ts by the target) or duplicate DataSNs (due to +- proactive SNACKs by the initiator), it MUST discard the duplicates. +- +- +- +- +- +-Satran, et al. Standards Track [Page 80] +- +-RFC 3720 iSCSI April 2004 +- +- +-6.9. SCSI Timeouts +- +- An iSCSI initiator MAY attempt to plug a command sequence gap on the +- target end (in the absence of an acknowledgement of the command by +- way of ExpCmdSN) before the ULP timeout by retrying the +- unacknowledged command, as described in Section 6.2 Retry and +- Reassign in Recovery. +- +- On a ULP timeout for a command (that carried a CmdSN of n), if the +- iSCSI initiator intends to continue the session, it MUST abort the +- command by either using an appropriate Task Management function +- request for the specific command, or a "close the connection" Logout. +- When using an ABORT TASK, if the ExpCmdSN is still less than (n+1), +- the target may see the abort request while missing the original +- command itself due to one of the following reasons: +- +- - Original command was dropped due to digest error. +- - Connection on which the original command was sent was +- successfully logged out. Upon logout, the unacknowledged +- commands issued on the connection being logged out are +- discarded. +- +- If the abort request is received and the original command is missing, +- targets MUST consider the original command with that RefCmdSN to be +- received and issue a Task Management response with the response code: +- "Function Complete". This response concludes the task on both ends. +- If the abort request is received and the target can determine (based +- on the Referenced Task Tag) that the command was received and +- executed and also that the response was sent prior to the abort, then +- the target MUST respond with the response code of "Task Does Not +- Exist". +- +-6.10. Negotiation Failures +- +- Text request and response sequences, when used to set/negotiate +- operational parameters, constitute the negotiation/parameter setting. +- A negotiation failure is considered to be one or more of the +- following: +- +- - None of the choices, or the stated value, is acceptable to one +- of the sides in the negotiation. +- - The text request timed out and possibly terminated. +- - The text request was answered with a Reject PDU. +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 81] +- +-RFC 3720 iSCSI April 2004 +- +- +- The following two rules should be used to address negotiation +- failures: +- +- - During Login, any failure in negotiation MUST be considered a +- login process failure and the Login Phase must be terminated, +- and with it, the connection. If the target detects the +- failure, it must terminate the login with the appropriate Login +- Response code. +- +- - A failure in negotiation, while in the Full Feature Phase, will +- terminate the entire negotiation sequence that may consist of a +- series of text requests that use the same Initiator Task Tag. +- The operational parameters of the session or the connection +- MUST continue to be the values agreed upon during an earlier +- successful negotiation (i.e., any partial results of this +- unsuccessful negotiation MUST NOT take effect and MUST be +- discarded). +- +-6.11. Protocol Errors +- +- Mapping framed messages over a "stream" connection, such as TCP, +- makes the proposed mechanisms vulnerable to simple software framing +- errors. On the other hand, the introduction of framing mechanisms to +- limit the effects of these errors may be onerous on performance for +- simple implementations. Command Sequence Numbers and the above +- mechanisms for connection drop and reestablishment help handle this +- type of mapping errors. +- +- All violations of iSCSI PDU exchange sequences specified in this +- document are also protocol errors. This category of errors can only +- be addressed by fixing the implementations; iSCSI defines Reject and +- response codes to enable this. +- +-6.12. Connection Failures +- +- iSCSI can keep a session in operation if it is able to +- keep/establish at least one TCP connection between the initiator and +- the target in a timely fashion. Targets and/or initiators may +- recognize a failing connection by either transport level means (TCP), +- a gap in the command sequence number, a response stream that is not +- filled for a long time, or by a failing iSCSI NOP (acting as a ping). +- The latter MAY be used periodically to increase the speed and +- likelihood of detecting connection failures. Initiators and targets +- MAY also use the keep-alive option on the TCP connection to enable +- early link failure detection on otherwise idle links. +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 82] +- +-RFC 3720 iSCSI April 2004 +- +- +- On connection failure, the initiator and target MUST do one of the +- following: +- +- - Attempt connection recovery within the session (Section 6.1.4.3 +- Connection Recovery). +- +- - Logout the connection with the reason code "closes the +- connection" (Section 10.14.5 Implicit termination of tasks), +- re-issue missing commands, and implicitly terminate all active +- commands. This option requires support for the +- within-connection recovery class (Section 6.1.4.2 Recovery +- Within-connection). +- +- - Perform session recovery (Section 6.1.4.4 Session Recovery). +- +- Either side may choose to escalate to session recovery (via the +- initiator dropping all the connections, or via an Async Message that +- announces the similar intent from a target), and the other side MUST +- give it precedence. On a connection failure, a target MUST terminate +- and/or discard all of the active immediate commands regardless of +- which of the above options is used (i.e., immediate commands are not +- recoverable across connection failures). +- +-6.13. Session Errors +- +- If all of the connections of a session fail and cannot be +- reestablished in a short time, or if initiators detect protocol +- errors repeatedly, an initiator may choose to terminate a session and +- establish a new session. +- +- In this case, the initiator takes the following actions: +- +- - Resets or closes all the transport connections. +- - Terminates all outstanding requests with an appropriate +- response before initiating a new session. If the same I_T +- nexus is intended to be reestablished, the initiator MUST +- employ session reinstatement (see section 5.3.5). +- +- When the session timeout (the connection state timeout for the last +- failed connection) happens on the target, it takes the following +- actions: +- +- - Resets or closes the TCP connections (closes the session). +- - Terminates all active tasks that were allegiant to the +- connection(s) that constituted the session. +- +- A target MUST also be prepared to handle a session reinstatement +- request from the initiator, that may be addressing session errors. +- +- +- +-Satran, et al. Standards Track [Page 83] +- +-RFC 3720 iSCSI April 2004 +- +- +-7. State Transitions +- +- iSCSI connections and iSCSI sessions go through several well-defined +- states from the time they are created to the time they are cleared. +- +- The connection state transitions are described in two separate but +- dependent state diagrams for ease in understanding. The first +- diagram, "standard connection state diagram", describes the +- connection state transitions when the iSCSI connection is not waiting +- for, or undergoing, a cleanup by way of an explicit or implicit +- Logout. The second diagram, "connection cleanup state diagram", +- describes the connection state transitions while performing the iSCSI +- connection cleanup. +- +- The "session state diagram" describes the state transitions an iSCSI +- session would go through during its lifetime, and it depends on the +- states of possibly multiple iSCSI connections that participate in the +- session. +- +- States and state transitions are described in the text, tables and +- diagrams. The diagrams are used for illustration. The text and the +- tables are the governing specification. +- +-7.1. Standard Connection State Diagrams +- +-7.1.1. State Descriptions for Initiators and Targets +- +- State descriptions for the standard connection state diagram are as +- follows: +- +- -S1: FREE +- -initiator: State on instantiation, or after successful +- connection closure. +- -target: State on instantiation, or after successful connection +- closure. +- -S2: XPT_WAIT +- -initiator: Waiting for a response to its transport connection +- establishment request. +- -target: Illegal +- -S3: XPT_UP +- -initiator: Illegal +- -target: Waiting for the Login process to commence. +- -S4: IN_LOGIN +- -initiator: Waiting for the Login process to conclude, possibly +- involving several PDU exchanges. +- -target: Waiting for the Login process to conclude, possibly +- involving several PDU exchanges. +- +- +- +- +-Satran, et al. Standards Track [Page 84] +- +-RFC 3720 iSCSI April 2004 +- +- +- -S5: LOGGED_IN +- -initiator: In Full Feature Phase, waiting for all internal, +- iSCSI, and transport events. +- -target: In Full Feature Phase, waiting for all internal, iSCSI, +- and transport events. +- -S6: IN_LOGOUT +- -initiator: Waiting for a Logout response. +- -target: Waiting for an internal event signaling completion of +- logout processing. +- -S7: LOGOUT_REQUESTED +- -initiator: Waiting for an internal event signaling readiness to +- proceed with Logout. +- -target: Waiting for the Logout process to start after having +- requested a Logout via an Async Message. +- -S8: CLEANUP_WAIT +- -initiator: Waiting for the context and/or resources to initiate +- the cleanup processing for this CSM. +- -target: Waiting for the cleanup process to start for this CSM. +- +-7.1.2. State Transition Descriptions for Initiators and Targets +- +- -T1: +- -initiator: Transport connect request was made (e.g., TCP SYN +- sent). +- -target: Illegal +- -T2: +- -initiator: Transport connection request timed out, a transport +- reset was received, or an internal event of receiving a +- Logout response (success) on another connection for a +- "close the session" Logout request was received. +- -target:Illegal +- -T3: +- -initiator: Illegal +- -target: Received a valid transport connection request that +- establishes the transport connection. +- -T4: +- -initiator: Transport connection established, thus prompting the +- initiator to start the iSCSI Login. +- -target: Initial iSCSI Login Request was received. +- -T5: +- -initiator: The final iSCSI Login Response with a Status-Class +- of zero was received. +- -target: The final iSCSI Login Request to conclude the Login +- Phase was received, thus prompting the target to send the +- final iSCSI Login Response with a Status-Class of zero. +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 85] +- +-RFC 3720 iSCSI April 2004 +- +- +- -T6: +- -initiator: Illegal +- -target: Timed out waiting for an iSCSI Login, transport +- disconnect indication was received, transport reset was +- received, or an internal event indicating a transport +- timeout was received. In all these cases, the connection is +- to be closed. +- -T7: +- -initiator - one of the following events caused the transition: +- - The final iSCSI Login Response was received with a +- non-zero Status-Class. +- - Login timed out. +- - A transport disconnect indication was received. +- - A transport reset was received. +- - An internal event was received indicating a transport +- timeout. +- - An internal event of receiving a Logout response (success) +- on another connection for a "close the session" Logout +- request was received. +- +- In all these cases, the transport connection is closed. +- +- -target - one of the following events caused the transition: +- - The final iSCSI Login Request to conclude the Login Phase +- was received, prompting the target to send the final iSCSI +- Login Response with a non-zero Status-Class. +- - Login timed out. +- - Transport disconnect indication was received. +- - Transport reset was received. +- - An internal event indicating a transport timeout was +- received. +- - On another connection a "close the session" Logout request +- was received. +- In all these cases, the connection is to be closed. +- -T8: +- -initiator: An internal event of receiving a Logout response +- (success) on another connection for a "close the session" +- Logout request was received, thus closing this connection +- requiring no further cleanup. +- -target: An internal event of sending a Logout response +- (success) on another connection for a "close the session" +- Logout request was received, or an internal event of a +- successful connection/session reinstatement is received, +- thus prompting the target to close this connection cleanly. +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 86] +- +-RFC 3720 iSCSI April 2004 +- +- +- -T9, T10: +- -initiator: An internal event that indicates the readiness to +- start the Logout process was received, thus prompting an +- iSCSI Logout to be sent by the initiator. +- -target: An iSCSI Logout request was received. +- -T11, T12: +- -initiator: Async PDU with AsyncEvent "Request Logout" was +- received. +- -target: An internal event that requires the decommissioning of +- the connection is received, thus causing an Async PDU with +- an AsyncEvent "Request Logout" to be sent. +- -T13: +- -initiator: An iSCSI Logout response (success) was received, or +- an internal event of receiving a Logout response (success) +- on another connection for a "close the session" Logout +- request was received. +- -target: An internal event was received that indicates +- successful processing of the Logout, which prompts an iSCSI +- Logout response (success) to be sent; an internal event of +- sending a Logout response (success) on another connection +- for a "close the session" Logout request was received; or an +- internal event of a successful connection/session +- reinstatement is received. In all these cases, the +- transport connection is closed. +- +- -T14: +- -initiator: Async PDU with AsyncEvent "Request Logout" was +- received again. +- -target: Illegal +- -T15, T16: +- -initiator: One or more of the following events caused this +- transition: +- -Internal event that indicates a transport connection +- timeout was received thus prompting transport RESET or +- transport connection closure. +- -A transport RESET. +- -A transport disconnect indication. +- -Async PDU with AsyncEvent "Drop connection" (for this CID). +- -Async PDU with AsyncEvent "Drop all connections". +- -target: One or more of the following events caused this +- transition: +- -Internal event that indicates a transport connection +- timeout was received, thus prompting transport RESET or +- transport connection closure. +- -An internal event of a failed connection/session +- reinstatement is received. +- -A transport RESET. +- -A transport disconnect indication. +- +- +- +-Satran, et al. Standards Track [Page 87] +- +-RFC 3720 iSCSI April 2004 +- +- +- -Internal emergency cleanup event was received which prompts +- an Async PDU with AsyncEvent "Drop connection" (for this +- CID), or event "Drop all connections". +- -T17: +- -initiator: One or more of the following events caused this +- transition: +- -Logout response, (failure i.e., a non-zero status) was +- received, or Logout timed out. +- -Any of the events specified for T15 and T16. +- -target: One or more of the following events caused this +- transition: +- -Internal event that indicates a failure of the Logout +- processing was received, which prompts a Logout response +- (failure, i.e., a non-zero status) to be sent. +- -Any of the events specified for T15 and T16. +- -T18: +- -initiator: An internal event of receiving a Logout response +- (success) on another connection for a "close the session" +- Logout request was received. +- -target: An internal event of sending a Logout response +- (success) on another connection for a "close the session" +- Logout request was received, or an internal event of a +- successful connection/session reinstatement is received. In +- both these cases, the connection is closed. +- +- The CLEANUP_WAIT state (S8) implies that there are possible iSCSI +- tasks that have not reached conclusion and are still considered busy. +- +-7.1.3. Standard Connection State Diagram for an Initiator +- +- Symbolic names for States: +- +- S1: FREE +- S2: XPT_WAIT +- S4: IN_LOGIN +- S5: LOGGED_IN +- S6: IN_LOGOUT +- S7: LOGOUT_REQUESTED +- S8: CLEANUP_WAIT +- +- +- +- +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 88] +- +-RFC 3720 iSCSI April 2004 +- +- +- States S5, S6, and S7 constitute the Full Feature Phase operation of +- the connection. +- +- The state diagram is as follows: +- +- -------<-------------+ +- +--------->/ S1 \<----+ | +- T13| +->\ /<-+ \ | +- | / ---+--- \ \ | +- | / | T2 \ | | +- | T8 | |T1 | | | +- | | | / |T7 | +- | | | / | | +- | | | / | | +- | | V / / | +- | | ------- / / | +- | | / S2 \ / | +- | | \ / / | +- | | ---+--- / | +- | | |T4 / | +- | | V / | T18 +- | | ------- / | +- | | / S4 \ | +- | | \ / | +- | | ---+--- | T15 +- | | |T5 +--------+---------+ +- | | | /T16+-----+------+ | +- | | | / -+-----+--+ | | +- | | | / / S7 \ |T12| | +- | | | / +->\ /<-+ V V +- | | | / / -+----- ------- +- | | | / /T11 |T10 / S8 \ +- | | V / / V +----+ \ / +- | | ---+-+- ----+-- | ------- +- | | / S5 \T9 / S6 \<+ ^ +- | +-----\ /--->\ / T14 | +- | ------- --+----+------+T17 +- +---------------------------+ +- +- +- +- +- +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 89] +- +-RFC 3720 iSCSI April 2004 +- +- +- The following state transition table represents the above diagram. +- Each row represents the starting state for a given transition, which +- after taking a transition marked in a table cell would end in the +- state represented by the column of the cell. For example, from state +- S1, the connection takes the T1 transition to arrive at state S2. +- The fields marked "-" correspond to undefined transitions. +- +- +----+---+---+---+---+----+---+ +- |S1 |S2 |S4 |S5 |S6 |S7 |S8 | +- ---+----+---+---+---+---+----+---+ +- S1| - |T1 | - | - | - | - | - | +- ---+----+---+---+---+---+----+---+ +- S2|T2 |- |T4 | - | - | - | - | +- ---+----+---+---+---+---+----+---+ +- S4|T7 |- |- |T5 | - | - | - | +- ---+----+---+---+---+---+----+---+ +- S5|T8 |- |- | - |T9 |T11 |T15| +- ---+----+---+---+---+---+----+---+ +- S6|T13 |- |- | - |T14|- |T17| +- ---+----+---+---+---+---+----+---+ +- S7|T18 |- |- | - |T10|T12 |T16| +- ---+----+---+---+---+---+----+---+ +- S8| - |- |- | - | - | - | - | +- ---+----+---+---+---+---+----+---+ +- +-7.1.4. Standard Connection State Diagram for a Target +- +- Symbolic names for States: +- +- S1: FREE +- S3: XPT_UP +- S4: IN_LOGIN +- S5: LOGGED_IN +- S6: IN_LOGOUT +- S7: LOGOUT_REQUESTED +- S8: CLEANUP_WAIT +- +- States S5, S6, and S7 constitute the Full Feature Phase operation of +- the connection. +- +- +- +- +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 90] +- +-RFC 3720 iSCSI April 2004 +- +- +- The state diagram is as follows: +- +- -------<-------------+ +- +--------->/ S1 \<----+ | +- T13| +->\ /<-+ \ | +- | / ---+--- \ \ | +- | / | T6 \ | | +- | T8 | |T3 | | | +- | | | / |T7 | +- | | | / | | +- | | | / | | +- | | V / / | +- | | ------- / / | +- | | / S3 \ / | +- | | \ / / | T18 +- | | ---+--- / | +- | | |T4 / | +- | | V / | +- | | ------- / | +- | | / S4 \ | +- | | \ / | +- | | ---+--- T15 | +- | | |T5 +--------+---------+ +- | | | /T16+-----+------+ | +- | | | / -+-----+---+ | | +- | | | / / S7 \ |T12| | +- | | | / +->\ /<-+ V V +- | | | / / -+----- ------- +- | | | / /T11 |T10 / S8 \ +- | | V / / V \ / +- | | ---+-+- ------- ------- +- | | / S5 \T9 / S6 \ ^ +- | +-----\ /--->\ / | +- | ------- --+----+--------+T17 +- +---------------------------+ +- +- The following state transition table represents the above diagram, +- and follows the conventions described for the initiator diagram. +- +- +- +- +- +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 91] +- +-RFC 3720 iSCSI April 2004 +- +- +- +----+---+---+---+---+----+---+ +- |S1 |S3 |S4 |S5 |S6 |S7 |S8 | +- ---+----+---+---+---+---+----+---+ +- S1| - |T3 | - | - | - | - | - | +- ---+----+---+---+---+---+----+---+ +- S3|T6 |- |T4 | - | - | - | - | +- ---+----+---+---+---+---+----+---+ +- S4|T7 |- |- |T5 | - | - | - | +- ---+----+---+---+---+---+----+---+ +- S5|T8 |- |- | - |T9 |T11 |T15| +- ---+----+---+---+---+---+----+---+ +- S6|T13 |- |- | - |- |- |T17| +- ---+----+---+---+---+---+----+---+ +- S7|T18 |- |- | - |T10|T12 |T16| +- ---+----+---+---+---+---+----+---+ +- S8| - |- |- | - | - | - | - | +- ---+----+---+---+---+---+----+---+ +- +-7.2. Connection Cleanup State Diagram for Initiators and Targets +- +- Symbolic names for states: +- +- R1: CLEANUP_WAIT (same as S8) +- R2: IN_CLEANUP +- R3: FREE (same as S1) +- +- Whenever a connection state machine (e.g., CSM-C) enters the +- CLEANUP_WAIT state (S8), it must go through the state transitions +- described in the connection cleanup state diagram either a) using a +- separate full-feature phase connection (let's call it CSM-E) in the +- LOGGED_IN state in the same session, or b) using a new transport +- connection (let's call it CSM-I) in the FREE state that is to be +- added to the same session. In the CSM-E case, an explicit logout for +- the CID that corresponds to CSM-C (either as a connection or session +- logout) needs to be performed to complete the cleanup. In the CSM-I +- case, an implicit logout for the CID that corresponds to CSM-C needs +- to be performed by way of connection reinstatement (section 5.3.4) +- for that CID. In either case, the protocol exchanges on CSM-E or +- CSM-I determine the state transitions for CSM-C. Therefore, this +- cleanup state diagram is only applicable to the instance of the +- connection in cleanup (i.e., CSM-C). In the case of an implicit +- logout for example, CSM-C reaches FREE (R3) at the time CSM-I reaches +- LOGGED_IN. In the case of an explicit logout, CSM-C reaches FREE +- (R3) when CSM-E receives a successful logout response while +- continuing to be in the LOGGED_IN state. +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 92] +- +-RFC 3720 iSCSI April 2004 +- +- +- An initiator must initiate an explicit or implicit connection logout +- for a connection in the CLEANUP_WAIT state, if the initiator intends +- to continue using the associated iSCSI session. +- +- The following state diagram applies to both initiators and targets. +- +- ------- +- / R1 \ +- +--\ /<-+ +- / ---+--- +- / | \ M3 +- M1 | |M2 | +- | | / +- | | / +- | | / +- | V / +- | ------- / +- | / R2 \ +- | \ / +- | ------- +- | | +- | |M4 +- | | +- | | +- | | +- | V +- | ------- +- | / R3 \ +- +---->\ / +- ------- +- +- The following state transition table represents the above diagram, +- and follows the same conventions as in earlier sections. +- +- +----+----+----+ +- |R1 |R2 |R3 | +- -----+----+----+----+ +- R1 | - |M2 |M1 | +- -----+----+----+----+ +- R2 |M3 | - |M4 | +- -----+----+----+----+ +- R3 | - | - | - | +- -----+----+----+----+ +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 93] +- +-RFC 3720 iSCSI April 2004 +- +- +-7.2.1. State Descriptions for Initiators and Targets +- +- -R1: CLEANUP_WAIT (Same as S8) +- -initiator: Waiting for the internal event to initiate the +- cleanup processing for CSM-C. +- -target: Waiting for the cleanup process to start for CSM-C. +- -R2: IN_CLEANUP +- -initiator: Waiting for the connection cleanup process to +- conclude for CSM-C. +- -target: Waiting for the connection cleanup process to conclude +- for CSM-C. +- -R3: FREE (Same as S1) +- -initiator: End state for CSM-C. +- -target: End state for CSM-C. +- +-7.2.2. State Transition Descriptions for Initiators and Targets +- +- -M1: One or more of the following events was received: +- -initiator: +- -An internal event that indicates connection state timeout. +- -An internal event of receiving a successful Logout response +- on a different connection for a "close the session" +- Logout. +- -target: +- -An internal event that indicates connection state timeout. +- -An internal event of sending a Logout response (success) on +- a different connection for a "close the session" Logout +- request. +- +- -M2: An implicit/explicit logout process was initiated by the +- initiator. +- -In CSM-I usage: +- -initiator: An internal event requesting the connection (or +- session) reinstatement was received, thus prompting a +- connection (or session) reinstatement Login to be sent +- transitioning CSM-I to state IN_LOGIN. +- -target: A connection/session reinstatement Login was +- received while in state XPT_UP. +- -In CSM-E usage: +- -initiator: An internal event that indicates that an +- explicit logout was sent for this CID in state LOGGED_IN. +- -target: An explicit logout was received for this CID in +- state LOGGED_IN. +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 94] +- +-RFC 3720 iSCSI April 2004 +- +- +- -M3: Logout failure detected +- -In CSM-I usage: +- -initiator: CSM-I failed to reach LOGGED_IN and arrived into +- FREE instead. +- -target: CSM-I failed to reach LOGGED_IN and arrived into +- FREE instead. +- -In CSM-E usage: +- -initiator: CSM-E either moved out of LOGGED_IN, or Logout +- timed out and/or aborted, or Logout response (failure) +- was received. +- -target: CSM-E either moved out of LOGGED_IN, Logout timed +- out and/or aborted, or an internal event that indicates a +- failed Logout processing was received. A Logout response +- (failure) was sent in the last case. +- +- -M4: Successful implicit/explicit logout was performed. +- +- - In CSM-I usage: +- -initiator: CSM-I reached state LOGGED_IN, or an internal +- event of receiving a Logout response (success) on another +- connection for a "close the session" Logout request was +- received. +- -target: CSM-I reached state LOGGED_IN, or an internal event +- of sending a Logout response (success) on a different +- connection for a "close the session" Logout request was +- received. +- - In CSM-E usage: +- -initiator: CSM-E stayed in LOGGED_IN and received a Logout +- response (success), or an internal event of receiving a +- Logout response (success) on another connection for a +- "close the session" Logout request was received. +- -target: CSM-E stayed in LOGGED_IN and an internal event +- indicating a successful Logout processing was received, +- or an internal event of sending a Logout response +- (success) on a different connection for a "close the +- session" Logout request was received. +- +-7.3. Session State Diagrams +- +-7.3.1. Session State Diagram for an Initiator +- +- Symbolic Names for States: +- +- Q1: FREE +- Q3: LOGGED_IN +- Q4: FAILED +- +- State Q3 represents the Full Feature Phase operation of the session. +- +- +- +-Satran, et al. Standards Track [Page 95] +- +-RFC 3720 iSCSI April 2004 +- +- +- The state diagram is as follows: +- +- ------- +- / Q1 \ +- +------>\ /<-+ +- / ---+--- | +- / | |N3 +- N6 | |N1 | +- | | | +- | N4 | | +- | +--------+ | / +- | | | | / +- | | | | / +- | | V V / +- -+--+-- -----+- +- / Q4 \ N5 / Q3 \ +- \ /<---\ / +- ------- ------- +- +- The state transition table is as follows: +- +- +----+----+----+ +- |Q1 |Q3 |Q4 | +- -----+----+----+----+ +- Q1 | - |N1 | - | +- -----+----+----+----+ +- Q3 |N3 | - |N5 | +- -----+----+----+----+ +- Q4 |N6 |N4 | - | +- -----+----+----+----+ +- +-7.3.2. Session State Diagram for a Target +- +- Symbolic Names for States: +- +- Q1: FREE +- Q2: ACTIVE +- Q3: LOGGED_IN +- Q4: FAILED +- Q5: IN_CONTINUE +- +- State Q3 represents the Full Feature Phase operation of the session. +- +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 96] +- +-RFC 3720 iSCSI April 2004 +- +- +- The state diagram is as follows: +- +- ------- +- +------------------>/ Q1 \ +- / +-------------->\ /<-+ +- | | ---+--- | +- | | ^ | |N3 +- N6 | |N11 N9| V N1 | +- | | +------ | +- | | / Q2 \ | +- | | \ / | +- | --+---- +--+--- | +- | / Q5 \ | | +- | \ / N10 | | +- | +-+---+------------+ |N2 / +- | ^ | | | / +- |N7| |N8 | | / +- | | | | V / +- -+--+-V V----+- +- / Q4 \ N5 / Q3 \ +- \ /<-------------\ / +- ------- ------- +- +- The state transition table is as follows: +- +- +----+----+----+----+----+ +- |Q1 |Q2 |Q3 |Q4 |Q5 | +- -----+----+----+----+----+----+ +- Q1 | - |N1 | - | - | - | +- -----+----+----+----+----+----+ +- Q2 |N9 | - |N2 | - | - | +- -----+----+----+----+----+----+ +- Q3 |N3 | - | - |N5 | - | +- -----+----+----+----+----+----+ +- Q4 |N6 | - | - | - |N7 | +- -----+----+----+----+----+----+ +- Q5 |N11 | - |N10 |N8 | - | +- -----+----+----+----+----+----+ +- +-7.3.3. State Descriptions for Initiators and Targets +- +- -Q1: FREE +- -initiator: State on instantiation or after cleanup. +- -target: State on instantiation or after cleanup. +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 97] +- +-RFC 3720 iSCSI April 2004 +- +- +- -Q2: ACTIVE +- -initiator: Illegal. +- -target: The first iSCSI connection in the session transitioned +- to IN_LOGIN, waiting for it to complete the login process. +- +- -Q3: LOGGED_IN +- -initiator: Waiting for all session events. +- -target: Waiting for all session events. +- +- -Q4: FAILED +- -initiator: Waiting for session recovery or session +- continuation. +- -target: Waiting for session recovery or session continuation. +- +- -Q5: IN_CONTINUE +- -initiator: Illegal. +- -target: Waiting for session continuation attempt to reach a +- conclusion. +- +-7.3.4. State Transition Descriptions for Initiators and Targets +- +- -N1: +- -initiator: At least one transport connection reached the +- LOGGED_IN state. +- -target: The first iSCSI connection in the session had reached +- the IN_LOGIN state. +- +- -N2: +- -initiator: Illegal. +- -target: At least one iSCSI connection reached the LOGGED_IN +- state. +- +- -N3: +- -initiator: Graceful closing of the session via session closure +- (Section 5.3.6 Session Continuation and Failure). +- -target: Graceful closing of the session via session closure +- (Section 5.3.6 Session Continuation and Failure) or a +- successful session reinstatement cleanly closed the session. +- +- -N4: +- -initiator: A session continuation attempt succeeded. +- -target: Illegal. +- +- -N5: +- -initiator: Session failure (Section 5.3.6 Session Continuation +- and Failure) occurred. +- -target: Session failure (Section 5.3.6 Session Continuation and +- Failure) occurred. +- +- +- +-Satran, et al. Standards Track [Page 98] +- +-RFC 3720 iSCSI April 2004 +- +- +- -N6: +- -initiator: Session state timeout occurred, or a session +- reinstatement cleared this session instance. This results +- in the freeing of all associated resources and the session +- state is discarded. +- -target: Session state timeout occurred, or a session +- reinstatement cleared this session instance. This results +- in the freeing of all associated resources and the session +- state is discarded. +- +- -N7: +- -initiator: Illegal. +- -target: A session continuation attempt is initiated. +- +- -N8: +- -initiator: Illegal. +- -target: The last session continuation attempt failed. +- +- -N9: +- -initiator: Illegal. +- -target: Login attempt on the leading connection failed. +- +- -N10: +- -initiator: Illegal. +- -target: A session continuation attempt succeeded. +- +- -N11: +- -initiator: Illegal. +- -target: A successful session reinstatement cleanly closed the +- session. +- +-8. Security Considerations +- +- Historically, native storage systems have not had to consider +- security because their environments offered minimal security risks. +- That is, these environments consisted of storage devices either +- directly attached to hosts or connected via a Storage Area Network +- (SAN) distinctly separate from the communications network. The use +- of storage protocols, such as SCSI, over IP-networks requires that +- security concerns be addressed. iSCSI implementations MUST provide +- means of protection against active attacks (e.g., pretending to be +- another identity, message insertion, deletion, modification, and +- replaying) and passive attacks (e.g., eavesdropping, gaining +- advantage by analyzing the data sent over the line). +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 99] +- +-RFC 3720 iSCSI April 2004 +- +- +- Although technically possible, iSCSI SHOULD NOT be configured without +- security. iSCSI configured without security should be confined, in +- extreme cases, to closed environments without any security risk. +- [RFC3723] specifies the mechanisms that must be used in order to +- mitigate risks fully described in that document. +- +- The following section describes the security mechanisms provided by +- an iSCSI implementation. +- +-8.1. iSCSI Security Mechanisms +- +- The entities involved in iSCSI security are the initiator, target, +- and the IP communication end points. iSCSI scenarios in which +- multiple initiators or targets share a single communication end point +- are expected. To accommodate such scenarios, iSCSI uses two separate +- security mechanisms: In-band authentication between the initiator and +- the target at the iSCSI connection level (carried out by exchange of +- iSCSI Login PDUs), and packet protection (integrity, authentication, +- and confidentiality) by IPsec at the IP level. The two security +- mechanisms complement each other. The in-band authentication +- provides end-to-end trust (at login time) between the iSCSI initiator +- and the target while IPsec provides a secure channel between the IP +- communication end points. +- +- Further details on typical iSCSI scenarios and the relation between +- the initiators, targets, and the communication end points can be +- found in [RFC3723]. +- +-8.2. In-band Initiator-Target Authentication +- +- During login, the target MAY authenticate the initiator and the +- initiator MAY authenticate the target. The authentication is +- performed on every new iSCSI connection by an exchange of iSCSI Login +- PDUs using a negotiated authentication method. +- +- The authentication method cannot assume an underlying IPsec +- protection, because IPsec is optional to use. An attacker should +- gain as little advantage as possible by inspecting the authentication +- phase PDUs. Therefore, a method using clear text (or equivalent) +- passwords is not acceptable; on the other hand, identity protection +- is not strictly required. +- +- The authentication mechanism protects against an unauthorized login +- to storage resources by using a false identity (spoofing). Once the +- authentication phase is completed, if the underlying IPsec is not +- used, all PDUs are sent and received in clear. The authentication +- +- +- +- +- +-Satran, et al. Standards Track [Page 100] +- +-RFC 3720 iSCSI April 2004 +- +- +- mechanism alone (without underlying IPsec) should only be used when +- there is no risk of eavesdropping, message insertion, deletion, +- modification, and replaying. +- +- Section 11 iSCSI Security Text Keys and Authentication Methods +- defines several authentication methods and the exact steps that must +- be followed in each of them, including the iSCSI-text-keys and their +- allowed values in each step. Whenever an iSCSI initiator gets a +- response whose keys, or their values, are not according to the step +- definition, it MUST abort the connection. Whenever an iSCSI target +- gets a response whose keys, or their values, are not according to the +- step definition, it MUST answer with a Login reject with the +- "Initiator Error" or "Missing Parameter" status. These statuses are +- not intended for cryptographically incorrect values such as the CHAP +- response, for which "Authentication Failure" status MUST be +- specified. The importance of this rule can be illustrated in CHAP +- with target authentication (see Section 11.1.4 Challenge Handshake +- Authentication Protocol (CHAP)) where the initiator would have been +- able to conduct a reflection attack by omitting his response key +- (CHAP_R) using the same CHAP challenge as the target and reflecting +- the target's response back to the target. In CHAP, this is prevented +- because the target must answer the missing CHAP_R key with a Login +- reject with the "Missing Parameter" status. +- +- For some of the authentication methods, a key specifies the identity +- of the iSCSI initiator or target for authentication purposes. The +- value associated with that key MAY be different from the iSCSI name +- and SHOULD be configurable. (CHAP_N, see Section 11.1.4 Challenge +- Handshake Authentication Protocol (CHAP) and SRP_U, see Section +- 11.1.3 Secure Remote Password (SRP)). +- +-8.2.1. CHAP Considerations +- +- Compliant iSCSI initiators and targets MUST implement the CHAP +- authentication method [RFC1994] (according to Section 11.1.4 +- Challenge Handshake Authentication Protocol (CHAP) including the +- target authentication option). +- +- When CHAP is performed over a non-encrypted channel, it is vulnerable +- to an off-line dictionary attack. Implementations MUST support use +- of up to 128 bit random CHAP secrets, including the means to generate +- such secrets and to accept them from an external generation source. +- Implementations MUST NOT provide secret generation (or expansion) +- means other than random generation. +- +- An administrative entity of an environment in which CHAP is used with +- a secret that has less than 96 random bits MUST enforce IPsec +- encryption (according to the implementation requirements in Section +- +- +- +-Satran, et al. Standards Track [Page 101] +- +-RFC 3720 iSCSI April 2004 +- +- +- 8.3.2 Confidentiality) to protect the connection. Moreover, in this +- case IKE authentication with group pre-shared cryptographic keys +- SHOULD NOT be used unless it is not essential to protect group +- members against off-line dictionary attacks by other members. +- +- CHAP secrets MUST be an integral number of bytes (octets). A +- compliant implementation SHOULD NOT continue with the login step in +- which it should send a CHAP response (CHAP_R, Section 11.1.4 +- Challenge Handshake Authentication Protocol (CHAP)) unless it can +- verify that the CHAP secret is at least 96 bits, or that IPsec +- encryption is being used to protect the connection. +- +- Any CHAP secret used for initiator authentication MUST NOT be +- configured for authentication of any target, and any CHAP secret used +- for target authentication MUST NOT be configured for authentication +- of any initiator. If the CHAP response received by one end of an +- iSCSI connection is the same as the CHAP response that the receiving +- endpoint would have generated for the same CHAP challenge, the +- response MUST be treated as an authentication failure and cause the +- connection to close (this ensures that the same CHAP secret is not +- used for authentication in both directions). Also, if an iSCSI +- implementation can function as both initiator and target, different +- CHAP secrets and identities MUST be configured for these two roles. +- The following is an example of the attacks prevented by the above +- requirements: +- +- Rogue wants to impersonate Storage to Alice, and knows that a +- single secret is used for both directions of Storage-Alice +- authentication. +- +- Rogue convinces Alice to open two connections to Rogue, and Rogue +- identifies itself as Storage on both connections. +- +- Rogue issues a CHAP challenge on connection 1, waits for Alice to +- respond, and then reflects Alice's challenge as the initial +- challenge to Alice on connection 2. +- +- If Alice doesn't check for the reflection across connections, +- Alice's response on connection 2 enables Rogue to impersonate +- Storage on connection 1, even though Rogue does not know the +- Alice-Storage CHAP secret. +- +- Originators MUST NOT reuse the CHAP challenge sent by the Responder +- for the other direction of a bidirectional authentication. +- Responders MUST check for this condition and close the iSCSI TCP +- connection if it occurs. +- +- +- +- +- +-Satran, et al. Standards Track [Page 102] +- +-RFC 3720 iSCSI April 2004 +- +- +- The same CHAP secret SHOULD NOT be configured for authentication of +- multiple initiators or multiple targets, as this enables any of them +- to impersonate any other one of them, and compromising one of them +- enables the attacker to impersonate any of them. It is recommended +- that iSCSI implementations check for use of identical CHAP secrets by +- different peers when this check is feasible, and take appropriate +- measures to warn users and/or administrators when this is detected. +- +- When an iSCSI initiator or target authenticates itself to +- counterparts in multiple administrative domains, it SHOULD use a +- different CHAP secret for each administrative domain to avoid +- propagating security compromises across domains. +- +- Within a single administrative domain: +- - A single CHAP secret MAY be used for authentication of an initiator +- to multiple targets. +- - A single CHAP secret MAY be used for an authentication of a target +- to multiple initiators when the initiators use an external server +- (e.g., RADIUS) to verify the target's CHAP responses and do not know +- the target's CHAP secret. +- +- If an external response verification server (e.g., RADIUS) is not +- used, employing a single CHAP secret for authentication of a target +- to multiple initiators requires that all such initiators know that +- target secret. Any of these initiators can impersonate the target to +- any other such initiator, and compromise of such an initiator enables +- an attacker to impersonate the target to all such initiators. +- Targets SHOULD use separate CHAP secrets for authentication to each +- initiator when such risks are of concern; in this situation it may be +- useful to configure a separate logical iSCSI target with its own +- iSCSI Node Name for each initiator or group of initiators among which +- such separation is desired. +- +-8.2.2. SRP Considerations +- +- The strength of the SRP authentication method (specified in +- [RFC2945]) is dependent on the characteristics of the group being +- used (i.e., the prime modulus N and generator g). As described in +- [RFC2945], N is required to be a Sophie-German prime (of the form +- N = 2q + 1, where q is also prime) and the generator g is a primitive +- root of GF(n). In iSCSI authentication, the prime modulus N MUST be +- at least 768 bits. +- +- The list of allowed SRP groups is provided in [RFC3723]. +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 103] +- +-RFC 3720 iSCSI April 2004 +- +- +-8.3. IPsec +- +- iSCSI uses the IPsec mechanism for packet protection (cryptographic +- integrity, authentication, and confidentiality) at the IP level +- between the iSCSI communicating end points. The following sections +- describe the IPsec protocols that must be implemented for data +- integrity and authentication, confidentiality, and cryptographic key +- management. +- +- An iSCSI initiator or target may provide the required IPsec support +- fully integrated or in conjunction with an IPsec front-end device. +- In the latter case, the compliance requirements with regard to IPsec +- support apply to the "combined device". Only the "combined device" +- is to be considered an iSCSI device. +- +- Detailed considerations and recommendations for using IPsec for iSCSI +- are provided in [RFC3723]. +- +-8.3.1. Data Integrity and Authentication +- +- Data authentication and integrity is provided by a cryptographic +- keyed Message Authentication Code in every sent packet. This code +- protects against message insertion, deletion, and modification. +- Protection against message replay is realized by using a sequence +- counter. +- +- An iSCSI compliant initiator or target MUST provide data integrity +- and authentication by implementing IPsec [RFC2401] with ESP [RFC2406] +- in tunnel mode and MAY provide data integrity and authentication by +- implementing IPsec with ESP in transport mode. The IPsec +- implementation MUST fulfill the following iSCSI specific +- requirements: +- +- - HMAC-SHA1 MUST be implemented [RFC2404]. +- - AES CBC MAC with XCBC extensions SHOULD be implemented +- [RFC3566]. +- +- The ESP anti-replay service MUST also be implemented. +- +- At the high speeds iSCSI is expected to operate, a single IPsec SA +- could rapidly cycle through the 32-bit IPsec sequence number space. +- In view of this, it may be desirable in the future for an iSCSI +- implementation that operates at speeds of 1 Gbps or greater to +- implement the IPsec sequence number extension [SEQ-EXT]. +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 104] +- +-RFC 3720 iSCSI April 2004 +- +- +-8.3.2. Confidentiality +- +- Confidentiality is provided by encrypting the data in every packet. +- When confidentiality is used it MUST be accompanied by data integrity +- and authentication to provide comprehensive protection against +- eavesdropping, message insertion, deletion, modification, and +- replaying. +- +- An iSCSI compliant initiator or target MUST provide confidentiality +- by implementing IPsec [RFC2401] with ESP [RFC2406] in tunnel mode and +- MAY provide confidentiality by implementing IPsec with ESP in +- transport mode, with the following iSCSI specific requirements: +- +- - 3DES in CBC mode MUST be implemented [RFC2451]. +- - AES in Counter mode SHOULD be implemented [RFC3686]. +- +- DES in CBC mode SHOULD NOT be used due to its inherent weakness. The +- NULL encryption algorithm MUST also be implemented. +- +-8.3.3. Policy, Security Associations, and Cryptographic Key Management +- +- A compliant iSCSI implementation MUST meet the cryptographic key +- management requirements of the IPsec protocol suite. Authentication, +- security association negotiation, and cryptographic key management +- MUST be provided by implementing IKE [RFC2409] using the IPsec DOI +- [RFC2407] with the following iSCSI specific requirements: +- +- - Peer authentication using a pre-shared cryptographic key MUST be +- supported. Certificate-based peer authentication using digital +- signatures MAY be supported. Peer authentication using the +- public key encryption methods outlined in IKE sections 5.2 and +- 5.3[7] SHOULD NOT be used. +- +- - When digital signatures are used to achieve authentication, an +- IKE negotiator SHOULD use IKE Certificate Request Payload(s) to +- specify the certificate authority. IKE negotiators SHOULD check +- the pertinent Certificate Revocation List (CRL) before accepting +- a PKI certificate for use in IKE authentication procedures. +- +- - Conformant iSCSI implementations MUST support IKE Main Mode and +- SHOULD support Aggressive Mode. IKE main mode with pre-shared +- key authentication method SHOULD NOT be used when either the +- initiator or the target uses dynamically assigned IP addresses. +- While in many cases pre-shared keys offer good security, +- situations in which dynamically assigned addresses are used force +- the use of a group pre-shared key, which creates vulnerability to +- a man-in-the-middle attack. +- +- +- +- +-Satran, et al. Standards Track [Page 105] +- +-RFC 3720 iSCSI April 2004 +- +- +- - In the IKE Phase 2 Quick Mode, exchanges for creating the Phase 2 +- SA, the Identity Payload, fields MUST be present. ID_IPV4_ADDR, +- ID_IPV6_ADDR (if the protocol stack supports IPv6) and ID_FQDN +- Identity payloads MUST be supported; ID_USER_FQDN SHOULD be +- supported. The IP Subnet, IP Address Range, ID_DER_ASN1_DN, and +- ID_DER_ASN1_GN formats SHOULD NOT be used. The ID_KEY_ID +- Identity Payload MUST NOT be used. +- +- Manual cryptographic keying MUST NOT be used because it does not +- provide the necessary re-keying support. +- +- When IPsec is used, the receipt of an IKE Phase 2 delete message +- SHOULD NOT be interpreted as a reason for tearing down the iSCSI TCP +- connection. If additional traffic is sent on it, a new IKE Phase 2 +- SA will be created to protect it. +- +- The method used by the initiator to determine whether the target +- should be connected using IPsec is regarded as an issue of IPsec +- policy administration, and thus not defined in the iSCSI standard. +- +- If an iSCSI target is discovered via a SendTargets request in a +- discovery session not using IPsec, the initiator should assume that +- it does not need IPsec to establish a session to that target. If an +- iSCSI target is discovered using a discovery session that does use +- IPsec, the initiator SHOULD use IPsec when establishing a session to +- that target. +- +-9. Notes to Implementers +- +- This section notes some of the performance and reliability +- considerations of the iSCSI protocol. This protocol was designed to +- allow efficient silicon and software implementations. The iSCSI task +- tag mechanism was designed to enable Direct Data Placement (DDP - a +- DMA form) at the iSCSI level or lower. +- +- The guiding assumption made throughout the design of this protocol is +- that targets are resource constrained relative to initiators. +- +- Implementers are also advised to consider the implementation +- consequences of the iSCSI to SCSI mapping model as outlined in +- Section 3.4.3 Consequences of the Model. +- +-9.1. Multiple Network Adapters +- +- The iSCSI protocol allows multiple connections, not all of which need +- to go over the same network adapter. If multiple network connections +- are to be utilized with hardware support, the iSCSI protocol +- +- +- +- +-Satran, et al. Standards Track [Page 106] +- +-RFC 3720 iSCSI April 2004 +- +- +- command-data-status allegiance to one TCP connection ensures that +- there is no need to replicate information across network adapters or +- otherwise require them to cooperate. +- +- However, some task management commands may require some loose form of +- cooperation or replication at least on the target. +- +-9.1.1. Conservative Reuse of ISIDs +- +- Historically, the SCSI model (and implementations and applications +- based on that model) has assumed that SCSI ports are static, physical +- entities. Recent extensions to the SCSI model have taken advantage +- of persistent worldwide unique names for these ports. In iSCSI +- however, the SCSI initiator ports are the endpoints of dynamically +- created sessions, so the presumptions of "static and physical" do not +- apply. In any case, the model clauses (particularly, Section 3.4.2 +- SCSI Architecture Model) provide for persistent, reusable names for +- the iSCSI-type SCSI initiator ports even though there does not need +- to be any physical entity bound to these names. +- +- To both minimize the disruption of legacy applications and to better +- facilitate the SCSI features that rely on persistent names for SCSI +- ports, iSCSI implementations SHOULD attempt to provide a stable +- presentation of SCSI Initiator Ports (both to the upper OS-layers and +- to the targets to which they connect). This can be achieved in an +- initiator implementation by conservatively reusing ISIDs. In other +- words, the same ISID should be used in the Login process to multiple +- target portal groups (of the same iSCSI Target or different iSCSI +- Targets). The ISID RULE (Section 3.4.3 Consequences of the Model) +- only prohibits reuse to the same target portal group. It does not +- "preclude" reuse to other target portal groups. The principle of +- conservative reuse "encourages" reuse to other target portal groups. +- When a SCSI target device sees the same (InitiatorName, ISID) pair in +- different sessions to different target portal groups, it can identify +- the underlying SCSI Initiator Port on each session as the same SCSI +- port. In effect, it can recognize multiple paths from the same +- source. +- +-9.1.2. iSCSI Name, ISID, and TPGT Use +- +- The designers of the iSCSI protocol envisioned there being one iSCSI +- Initiator Node Name per operating system image on a machine. This +- enables SAN resource configuration and authentication schemes based +- on a system's identity. It supports the notion that it should be +- possible to assign access to storage resources based on "initiator +- device" identity. +- +- +- +- +- +-Satran, et al. Standards Track [Page 107] +- +-RFC 3720 iSCSI April 2004 +- +- +- When there are multiple hardware or software components coordinated +- as a single iSCSI Node, there must be some (logical) entity that +- represents the iSCSI Node that makes the iSCSI Node Name available to +- all components involved in session creation and login. Similarly, +- this entity that represents the iSCSI Node must be able to coordinate +- session identifier resources (ISID for initiators) to enforce both +- the ISID and TSIH RULES (see Section 3.4.3 Consequences of the +- Model). +- +- For targets, because of the closed environment, implementation of +- this entity should be straightforward. However, vendors of iSCSI +- hardware (e.g., NICs or HBAs) intended for targets, SHOULD provide +- mechanisms for configuration of the iSCSI Node Name across the portal +- groups instantiated by multiple instances of these components within +- a target. +- +- However, complex targets making use of multiple Target Portal Group +- Tags may reconfigure them to achieve various quality goals. The +- initiators have two mechanisms at their disposal to discover and/or +- check reconfiguring targets - the discovery session type and a key +- returned by the target during login to confirm the TPGT. An +- initiator should attempt to "rediscover" the target configuration +- anytime a session is terminated unexpectedly. +- +- For initiators, in the long term, it is expected that operating +- system vendors will take on the role of this entity and provide +- standard APIs that can inform components of their iSCSI Node Name and +- can configure and/or coordinate ISID allocation, use, and reuse. +- +- Recognizing that such initiator APIs are not available today, other +- implementations of the role of this entity are possible. For +- example, a human may instantiate the (common) Node name as part of +- the installation process of each iSCSI component involved in session +- creation and login. This may be done either by pointing the +- component to a vendor-specific location for this datum or to a +- system-wide location. The structure of the ISID namespace (see +- Section 10.12.5 ISID and [RFC3721]) facilitates implementation of the +- ISID coordination by allowing each component vendor to independently +- (of other vendor's components) coordinate allocation, use, and reuse +- of its own partition of the ISID namespace in a vendor-specific +- manner. Partitioning of the ISID namespace within initiator portal +- groups managed by that vendor allows each such initiator portal group +- to act independently of all other portal groups when selecting an +- ISID for a login; this facilitates enforcement of the ISID RULE (see +- Section 3.4.3 Consequences of the Model) at the initiator. +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 108] +- +-RFC 3720 iSCSI April 2004 +- +- +- A vendor of iSCSI hardware (e.g., NICs or HBAs) intended for use in +- initiators MUST implement a mechanism for configuring the iSCSI Node +- Name. Vendors, and administrators must ensure that iSCSI Node Names +- are unique worldwide. It is therefore important that when one +- chooses to reuse the iSCSI Node Name of a disabled unit, not to +- re-assign that name to the original unit unless its worldwide +- uniqueness can be ascertained again. +- +- In addition, a vendor of iSCSI hardware must implement a mechanism to +- configure and/or coordinate ISIDs for all sessions managed by +- multiple instances of that hardware within a given iSCSI Node. Such +- configuration might be either permanently pre-assigned at the factory +- (in a necessarily globally unique way), statically assigned (e.g., +- partitioned across all the NICs at initialization in a locally unique +- way), or dynamically assigned (e.g., on-line allocator, also in a +- locally unique way). In the latter two cases, the configuration may +- be via public APIs (perhaps driven by an independent vendor's +- software, such as the OS vendor) or via private APIs driven by the +- vendor's own software. +- +-9.2. Autosense and Auto Contingent Allegiance (ACA) +- +- Autosense refers to the automatic return of sense data to the +- initiator in case a command did not complete successfully. iSCSI +- initiators and targets MUST support and use autosense. +- +- ACA helps preserve ordered command execution in the presence of +- errors. As iSCSI can have many commands in-flight between initiator +- and target, iSCSI initiators and targets SHOULD support ACA. +- +-9.3. iSCSI Timeouts +- +- iSCSI recovery actions are often dependent on iSCSI time-outs being +- recognized and acted upon before SCSI time-outs. Determining the +- right time-outs to use for various iSCSI actions (command +- acknowledgements expected, status acknowledgements, etc.) is very +- much dependent on infrastructure (hardware, links, TCP/IP stack, +- iSCSI driver). As a guide, the implementer may use an average +- Nop-Out/Nop-In turnaround delay multiplied by a "safety factor" +- (e.g., 4) as a good estimate for the basic delay of the iSCSI stack +- for a given connection. The safety factor should account for the +- network load variability. For connection teardown the implementer +- may want to consider also the TCP common practice for the given +- infrastructure. +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 109] +- +-RFC 3720 iSCSI April 2004 +- +- +- Text negotiations MAY also be subject to either time-limits or limits +- in the number of exchanges. Those SHOULD be generous enough to avoid +- affecting interoperability (e.g., allowing each key to be negotiated +- on a separate exchange). +- +- The relation between iSCSI timeouts and SCSI timeouts should also be +- considered. SCSI timeouts should be longer than iSCSI timeouts plus +- the time required for iSCSI recovery whenever iSCSI recovery is +- planned. Alternatively, an implementer may choose to interlock iSCSI +- timeouts and recovery with SCSI timeouts so that SCSI recovery will +- become active only where iSCSI is not planned to, or failed to, +- recover. +- +- The implementer may also want to consider the interaction between +- various iSCSI exception events - such as a digest failure - and +- subsequent timeouts. When iSCSI error recovery is active, a digest +- failure is likely to result in discovering a missing command or data +- PDU. In these cases, an implementer may want to lower the timeout +- values to enable faster initiation for recovery procedures. +- +-9.4. Command Retry and Cleaning Old Command Instances +- +- To avoid having old, retried command instances appear in a valid +- command window after a command sequence number wrap around, the +- protocol requires (see Section 3.2.2.1 Command Numbering and +- Acknowledging) that on every connection on which a retry has been +- issued, a non-immediate command be issued and acknowledged within a +- 2**31-1 commands interval from the CmdSN of the retried command. +- This requirement can be fulfilled by an implementation in several +- ways. +- +- The simplest technique to use is to send a (non-retry) non-immediate +- SCSI command (or a NOP if no SCSI command is available for a while) +- after every command retry on the connection on which the retry was +- attempted. As errors are deemed rare events, this technique is +- probably the most effective, as it does not involve additional checks +- at the initiator when issuing commands. +- +-9.5. Synch and Steering Layer and Performance +- +- While a synch and steering layer is optional, an initiator/target +- that does not have it working against a target/initiator that demands +- synch and steering may experience performance degradation caused by +- packet reordering and loss. Providing a synch and steering mechanism +- is recommended for all high-speed implementations. +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 110] +- +-RFC 3720 iSCSI April 2004 +- +- +-9.6. Considerations for State-dependent Devices and Long-lasting SCSI +- Operations +- +- Sequential access devices operate on the principle that the position +- of the device is based on the last command processed. As such, +- command processing order and knowledge of whether or not the previous +- command was processed is of the utmost importance to maintain data +- integrity. For example, inadvertent retries of SCSI commands when it +- is not known if the previous SCSI command was processed is a +- potential data integrity risk. +- +- For a sequential access device, consider the scenario in which a SCSI +- SPACE command to backspace one filemark is issued and then re-issued +- due to no status received for the command. If the first SPACE +- command was actually processed, the re-issued SPACE command, if +- processed, will cause the position to change. Thus, a subsequent +- write operation will write data to the wrong position and any +- previous data at that position will be overwritten. +- +- For a medium changer device, consider the scenario in which an +- EXCHANGE MEDIUM command (the SOURCE ADDRESS and DESTINATION ADDRESS +- are the same thus performing a swap) is issued and then re-issued due +- to no status received for the command. If the first EXCHANGE MEDIUM +- command was actually processed, the re-issued EXCHANGE MEDIUM +- command, if processed, will perform the swap again. The net effect +- is that a swap was not performed thus leaving a data integrity +- exposure. +- +- All commands that change the state of the device (as in SPACE +- commands for sequential access devices, and EXCHANGE MEDIUM for +- medium changer device), MUST be issued as non-immediate commands for +- deterministic and in order delivery to iSCSI targets. +- +- For many of those state changing commands, the execution model also +- assumes that the command is executed exactly once. Devices +- implementing READ POSITION and LOCATE provide a means for SCSI level +- command recovery and new tape-class devices should support those +- commands. In their absence a retry at SCSI level is difficult and +- error recovery at iSCSI level is advisable. +- +- Devices operating on long latency delivery subsystems and performing +- long lasting SCSI operations may need mechanisms that enable +- connection replacement while commands are running (e.g., during an +- extended copy operation). +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 111] +- +-RFC 3720 iSCSI April 2004 +- +- +-9.6.1. Determining the Proper ErrorRecoveryLevel +- +- The implementation and use of a specific ErrorRecoveryLevel should be +- determined based on the deployment scenarios of a given iSCSI +- implementation. Generally, the following factors must be considered +- before deciding on the proper level of recovery: +- +- a) Application resilience to I/O failures. +- b) Required level of availability in the face of transport +- connection failures. +- c) Probability of transport layer "checksum escape". This in +- turn decides the iSCSI digest failure frequency, and thus the +- criticality of iSCSI-level error recovery. The details of +- estimating this probability are outside the scope of this +- document. +- +- +- A consideration of the above factors for SCSI tape devices as an +- example suggests that implementations SHOULD use ErrorRecoveryLevel=1 +- when transport connection failure is not a concern and SCSI level +- recovery is unavailable, and ErrorRecoveryLevel=2 when the connection +- failure is also of high likelihood during a backup/retrieval. +- +- For extended copy operations, implementations SHOULD use +- ErrorRecoveryLevel=2 whenever there is a relatively high likelihood +- of connection failure. +- +-10. iSCSI PDU Formats +- +- All multi-byte integers that are specified in formats defined in this +- document are to be represented in network byte order (i.e., big +- endian). Any field that appears in this document assumes that the +- most significant byte is the lowest numbered byte and the most +- significant bit (within byte or field) is the lowest numbered bit +- unless specified otherwise. +- +- Any compliant sender MUST set all bits not defined and all reserved +- fields to zero unless specified otherwise. Any compliant receiver +- MUST ignore any bit not defined and all reserved fields unless +- specified otherwise. Receipt of reserved code values in defined +- fields MUST be reported as a protocol error. +- +- Reserved fields are marked by the word "reserved", some abbreviation +- of "reserved", or by "." for individual bits when no other form of +- marking is technically feasible. +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 112] +- +-RFC 3720 iSCSI April 2004 +- +- +-10.1. iSCSI PDU Length and Padding +- +- iSCSI PDUs are padded to the closest integer number of four byte +- words. The padding bytes SHOULD be sent as 0. +- +-10.2. PDU Template, Header, and Opcodes +- +- All iSCSI PDUs have one or more header segments and, optionally, a +- data segment. After the entire header segment group a header-digest +- MAY follow. The data segment MAY also be followed by a data-digest. +- +- The Basic Header Segment (BHS) is the first segment in all of the +- iSCSI PDUs. The BHS is a fixed-length 48-byte header segment. It +- MAY be followed by Additional Header Segments (AHS), a Header-Digest, +- a Data Segment, and/or a Data-Digest. +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 113] +- +-RFC 3720 iSCSI April 2004 +- +- +- The overall structure of an iSCSI PDU is as follows: +- +- Byte/ 0 | 1 | 2 | 3 | +- / | | | | +- |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +- +---------------+---------------+---------------+---------------+ +- 0/ Basic Header Segment (BHS) / +- +/ / +- +---------------+---------------+---------------+---------------+ +- 48/ Additional Header Segment 1 (AHS) (optional) / +- +/ / +- +---------------+---------------+---------------+---------------+ +- / Additional Header Segment 2 (AHS) (optional) / +- +/ / +- +---------------+---------------+---------------+---------------+ +- ---- +- +---------------+---------------+---------------+---------------+ +- / Additional Header Segment n (AHS) (optional) / +- +/ / +- +---------------+---------------+---------------+---------------+ +- ---- +- +---------------+---------------+---------------+---------------+ +- k/ Header-Digest (optional) / +- +/ / +- +---------------+---------------+---------------+---------------+ +- l/ Data Segment(optional) / +- +/ / +- +---------------+---------------+---------------+---------------+ +- m/ Data-Digest (optional) / +- +/ / +- +---------------+---------------+---------------+---------------+ +- +- All PDU segments and digests are padded to the closest integer number +- of four byte words. For example, all PDU segments and digests start +- at a four byte word boundary and the padding ranges from 0 to 3 +- bytes. The padding bytes SHOULD be sent as 0. +- +- iSCSI response PDUs do not have AH Segments. +- +-10.2.1. Basic Header Segment (BHS) +- +- The BHS is 48 bytes long. The Opcode and DataSegmentLength fields +- appear in all iSCSI PDUs. In addition, when used, the Initiator Task +- Tag and Logical Unit Number always appear in the same location in the +- header. +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 114] +- +-RFC 3720 iSCSI April 2004 +- +- +- The format of the BHS is: +- +- Byte/ 0 | 1 | 2 | 3 | +- / | | | | +- |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +- +---------------+---------------+---------------+---------------+ +- 0|.|I| Opcode |F| Opcode-specific fields | +- +---------------+---------------+---------------+---------------+ +- 4|TotalAHSLength | DataSegmentLength | +- +---------------+---------------+---------------+---------------+ +- 8| LUN or Opcode-specific fields | +- + + +- 12| | +- +---------------+---------------+---------------+---------------+ +- 16| Initiator Task Tag | +- +---------------+---------------+---------------+---------------+ +- 20/ Opcode-specific fields / +- +/ / +- +---------------+---------------+---------------+---------------+ +- 48 +- +-10.2.1.1 I +- +- For request PDUs, the I bit set to 1 is an immediate delivery marker. +- +-10.2.1.2. Opcode +- +- The Opcode indicates the type of iSCSI PDU the header encapsulates. +- +- The Opcodes are divided into two categories: initiator opcodes and +- target opcodes. Initiator opcodes are in PDUs sent by the initiator +- (request PDUs). Target opcodes are in PDUs sent by the target +- (response PDUs). +- +- Initiators MUST NOT use target opcodes and targets MUST NOT use +- initiator opcodes. +- +- Initiator opcodes defined in this specification are: +- +- 0x00 NOP-Out +- 0x01 SCSI Command (encapsulates a SCSI Command Descriptor Block) +- 0x02 SCSI Task Management function request +- 0x03 Login Request +- 0x04 Text Request +- 0x05 SCSI Data-Out (for WRITE operations) +- 0x06 Logout Request +- 0x10 SNACK Request +- 0x1c-0x1e Vendor specific codes +- +- +- +-Satran, et al. Standards Track [Page 115] +- +-RFC 3720 iSCSI April 2004 +- +- +- +- Target opcodes are: +- +- 0x20 NOP-In +- 0x21 SCSI Response - contains SCSI status and possibly sense +- information or other response information. +- 0x22 SCSI Task Management function response +- 0x23 Login Response +- 0x24 Text Response +- 0x25 SCSI Data-In - for READ operations. +- 0x26 Logout Response +- 0x31 Ready To Transfer (R2T) - sent by target when it is ready +- to receive data. +- 0x32 Asynchronous Message - sent by target to indicate certain +- special conditions. +- 0x3c-0x3e Vendor specific codes +- 0x3f Reject +- +- All other opcodes are reserved. +- +-10.2.1.3. Final (F) bit +- +- When set to 1 it indicates the final (or only) PDU of a sequence. +- +-10.2.1.4. Opcode-specific Fields +- +- These fields have different meanings for different opcode types. +- +-10.2.1.5. TotalAHSLength +- +- Total length of all AHS header segments in units of four byte words +- including padding, if any. +- +- The TotalAHSLength is only used in PDUs that have an AHS and MUST be +- 0 in all other PDUs. +- +-10.2.1.6. DataSegmentLength +- +- This is the data segment payload length in bytes (excluding padding). +- The DataSegmentLength MUST be 0 whenever the PDU has no data segment. +- +-10.2.1.7. LUN +- +- Some opcodes operate on a specific Logical Unit. The Logical Unit +- Number (LUN) field identifies which Logical Unit. If the opcode does +- not relate to a Logical Unit, this field is either ignored or may be +- used in an opcode specific way. The LUN field is 64-bits and should +- +- +- +- +-Satran, et al. Standards Track [Page 116] +- +-RFC 3720 iSCSI April 2004 +- +- +- be formatted in accordance with [SAM2]. For example, LUN[0] from +- [SAM2] is BHS byte 8 and so on up to LUN[7] from [SAM2], which is BHS +- byte 15. +- +-10.2.1.8. Initiator Task Tag +- +- The initiator assigns a Task Tag to each iSCSI task it issues. While +- a task exists, this tag MUST uniquely identify the task session-wide. +- SCSI may also use the initiator task tag as part of the SCSI task +- identifier when the timespan during which an iSCSI initiator task tag +- must be unique extends over the timespan during which a SCSI task tag +- must be unique. However, the iSCSI Initiator Task Tag must exist and +- be unique even for untagged SCSI commands. +- +-10.2.2. Additional Header Segment (AHS) +- +- The general format of an AHS is: +- +- Byte/ 0 | 1 | 2 | 3 | +- / | | | | +- |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +- +---------------+---------------+---------------+---------------+ +- 0| AHSLength | AHSType | AHS-Specific | +- +---------------+---------------+---------------+---------------+ +- 4/ AHS-Specific / +- +/ / +- +---------------+---------------+---------------+---------------+ +- x +- +-10.2.2.1. AHSType +- +- The AHSType field is coded as follows: +- +- bit 0-1 - Reserved +- +- bit 2-7 - AHS code +- +- 0 - Reserved +- 1 - Extended CDB +- 2 - Expected Bidirectional Read Data Length +- 3 - 63 Reserved +- +-10.2.2.2. AHSLength +- +- This field contains the effective length in bytes of the AHS +- excluding AHSType and AHSLength and padding, if any. The AHS is +- padded to the smallest integer number of 4 byte words (i.e., from 0 +- up to 3 padding bytes). +- +- +- +-Satran, et al. Standards Track [Page 117] +- +-RFC 3720 iSCSI April 2004 +- +- +-10.2.2.3. Extended CDB AHS +- +- The format of the Extended CDB AHS is: +- +- Byte/ 0 | 1 | 2 | 3 | +- / | | | | +- |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +- +---------------+---------------+---------------+---------------+ +- 0| AHSLength (CDBLength-15) | 0x01 | Reserved | +- +---------------+---------------+---------------+---------------+ +- 4/ ExtendedCDB...+padding / +- +/ / +- +---------------+---------------+---------------+---------------+ +- x +- +- This type of AHS MUST NOT be used if the CDBLength is less than 17. +- The length includes the reserved byte 3. +- +-10.2.2.4. Bidirectional Expected Read-Data Length AHS +- +- The format of the Bidirectional Read Expected Data Transfer Length +- AHS is: +- +- Byte/ 0 | 1 | 2 | 3 | +- / | | | | +- |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +- +---------------+---------------+---------------+---------------+ +- 0| AHSLength (0x0005) | 0x02 | Reserved | +- +---------------+---------------+---------------+---------------+ +- 4| Expected Read-Data Length | +- +---------------+---------------+---------------+---------------+ +- 8 +- +-10.2.3. Header Digest and Data Digest +- +- Optional header and data digests protect the integrity of the header +- and data, respectively. The digests, if present, are located, +- respectively, after the header and PDU-specific data, and cover +- respectively the header and the PDU data, each including the padding +- bytes, if any. +- +- The existence and type of digests are negotiated during the Login +- Phase. +- +- The separation of the header and data digests is useful in iSCSI +- routing applications, in which only the header changes when a message +- is forwarded. In this case, only the header digest should be +- recalculated. +- +- +- +-Satran, et al. Standards Track [Page 118] +- +-RFC 3720 iSCSI April 2004 +- +- +- Digests are not included in data or header length fields. +- +- A zero-length Data Segment also implies a zero-length data-digest. +- +-10.2.4. Data Segment +- +- The (optional) Data Segment contains PDU associated data. Its +- payload effective length is provided in the BHS field - +- DataSegmentLength. The Data Segment is also padded to an integer +- number of 4 byte words. +- +-10.3. SCSI Command +- +- The format of the SCSI Command PDU is: +- +- Byte/ 0 | 1 | 2 | 3 | +- / | | | | +- |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +- +---------------+---------------+---------------+---------------+ +- 0|.|I| 0x01 |F|R|W|. .|ATTR | Reserved | +- +---------------+---------------+---------------+---------------+ +- 4|TotalAHSLength | DataSegmentLength | +- +---------------+---------------+---------------+---------------+ +- 8| Logical Unit Number (LUN) | +- + + +- 12| | +- +---------------+---------------+---------------+---------------+ +- 16| Initiator Task Tag | +- +---------------+---------------+---------------+---------------+ +- 20| Expected Data Transfer Length | +- +---------------+---------------+---------------+---------------+ +- 24| CmdSN | +- +---------------+---------------+---------------+---------------+ +- 28| ExpStatSN | +- +---------------+---------------+---------------+---------------+ +- 32/ SCSI Command Descriptor Block (CDB) / +- +/ / +- +---------------+---------------+---------------+---------------+ +- 48/ AHS (Optional) / +- +---------------+---------------+---------------+---------------+ +- x/ Header Digest (Optional) / +- +---------------+---------------+---------------+---------------+ +- y/ (DataSegment, Command Data) (Optional) / +- +/ / +- +---------------+---------------+---------------+---------------+ +- z/ Data Digest (Optional) / +- +---------------+---------------+---------------+---------------+ +- +- +- +- +-Satran, et al. Standards Track [Page 119] +- +-RFC 3720 iSCSI April 2004 +- +- +-10.3.1. Flags and Task Attributes (byte 1) +- +- The flags for a SCSI Command are: +- +- bit 0 (F) is set to 1 when no unsolicited SCSI Data-Out PDUs follow +- this PDU. When F=1 for a write and if Expected Data +- Transfer Length is larger than the DataSegmentLength, the +- target may solicit additional data through R2T. +- +- bit 1 (R) is set to 1 when the command is expected to input data. +- +- bit 2 (W) is set to 1 when the command is expected to output data. +- +- bit 3-4 Reserved. +- +- bit 5-7 contains Task Attributes. +- +- Task Attributes (ATTR) have one of the following integer values (see +- [SAM2] for details): +- +- 0 - Untagged +- 1 - Simple +- 2 - Ordered +- 3 - Head of Queue +- 4 - ACA +- 5-7 - Reserved +- +- Setting both the W and the F bit to 0 is an error. Either or both of +- R and W MAY be 1 when either the Expected Data Transfer Length and/or +- Bidirectional Read Expected Data Transfer Length are 0, but they MUST +- NOT both be 0 when the Expected Data Transfer Length and/or +- Bidirectional Read Expected Data Transfer Length are not 0 (i.e., +- when some data transfer is expected the transfer direction is +- indicated by the R and/or W bit). +- +-10.3.2. CmdSN - Command Sequence Number +- +- Enables ordered delivery across multiple connections in a single +- session. +- +-10.3.3. ExpStatSN +- +- Command responses up to ExpStatSN-1 (mod 2**32) have been received +- (acknowledges status) on the connection. +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 120] +- +-RFC 3720 iSCSI April 2004 +- +- +-10.3.4. Expected Data Transfer Length +- +- For unidirectional operations, the Expected Data Transfer Length +- field contains the number of bytes of data involved in this SCSI +- operation. For a unidirectional write operation (W flag set to 1 and +- R flag set to 0), the initiator uses this field to specify the number +- of bytes of data it expects to transfer for this operation. For a +- unidirectional read operation (W flag set to 0 and R flag set to 1), +- the initiator uses this field to specify the number of bytes of data +- it expects the target to transfer to the initiator. It corresponds +- to the SAM2 byte count. +- +- For bidirectional operations (both R and W flags are set to 1), this +- field contains the number of data bytes involved in the write +- transfer. For bidirectional operations, an additional header segment +- MUST be present in the header sequence that indicates the +- Bidirectional Read Expected Data Transfer Length. The Expected Data +- Transfer Length field and the Bidirectional Read Expected Data +- Transfer Length field correspond to the SAM2 byte count +- +- If the Expected Data Transfer Length for a write and the length of +- the immediate data part that follows the command (if any) are the +- same, then no more data PDUs are expected to follow. In this case, +- the F bit MUST be set to 1. +- +- If the Expected Data Transfer Length is higher than the +- FirstBurstLength (the negotiated maximum amount of unsolicited data +- the target will accept), the initiator MUST send the maximum amount +- of unsolicited data OR ONLY the immediate data, if any. +- +- Upon completion of a data transfer, the target informs the initiator +- (through residual counts) of how many bytes were actually processed +- (sent and/or received) by the target. +- +-10.3.5. CDB - SCSI Command Descriptor Block +- +- There are 16 bytes in the CDB field to accommodate the commonly used +- CDBs. Whenever the CDB is larger than 16 bytes, an Extended CDB AHS +- MUST be used to contain the CDB spillover. +- +-10.3.6. Data Segment - Command Data +- +- Some SCSI commands require additional parameter data to accompany the +- SCSI command. This data may be placed beyond the boundary of the +- iSCSI header in a data segment. Alternatively, user data (e.g., from +- a WRITE operation) can be placed in the data segment (both cases are +- +- +- +- +- +-Satran, et al. Standards Track [Page 121] +- +-RFC 3720 iSCSI April 2004 +- +- +- referred to as immediate data). These data are governed by the rules +- for solicited vs. unsolicited data outlined in Section 3.2.4.2 Data +- Transfer Overview. +- +-10.4. SCSI Response +- +- The format of the SCSI Response PDU is: +- +- Byte/ 0 | 1 | 2 | 3 | +- / | | | | +- |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +- +---------------+---------------+---------------+---------------+ +- 0|.|.| 0x21 |1|. .|o|u|O|U|.| Response | Status | +- +---------------+---------------+---------------+---------------+ +- 4|TotalAHSLength | DataSegmentLength | +- +---------------+---------------+---------------+---------------+ +- 8| Reserved | +- + + +- 12| | +- +---------------+---------------+---------------+---------------+ +- 16| Initiator Task Tag | +- +---------------+---------------+---------------+---------------+ +- 20| SNACK Tag or Reserved | +- +---------------+---------------+---------------+---------------+ +- 24| StatSN | +- +---------------+---------------+---------------+---------------+ +- 28| ExpCmdSN | +- +---------------+---------------+---------------+---------------+ +- 32| MaxCmdSN | +- +---------------+---------------+---------------+---------------+ +- 36| ExpDataSN or Reserved | +- +---------------+---------------+---------------+---------------+ +- 40| Bidirectional Read Residual Count or Reserved | +- +---------------+---------------+---------------+---------------+ +- 44| Residual Count or Reserved | +- +---------------+---------------+---------------+---------------+ +- 48| Header-Digest (Optional) | +- +---------------+---------------+---------------+---------------+ +- / Data Segment (Optional) / +- +/ / +- +---------------+---------------+---------------+---------------+ +- | Data-Digest (Optional) | +- +---------------+---------------+---------------+---------------+ +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 122] +- +-RFC 3720 iSCSI April 2004 +- +- +-10.4.1. Flags (byte 1) +- +- bit 1-2 Reserved. +- +- bit 3 - (o) set for Bidirectional Read Residual Overflow. In this +- case, the Bidirectional Read Residual Count indicates the number +- of bytes that were not transferred to the initiator because the +- initiator's Expected Bidirectional Read Data Transfer Length was +- not sufficient. +- +- bit 4 - (u) set for Bidirectional Read Residual Underflow. In this +- case, the Bidirectional Read Residual Count indicates the number +- of bytes that were not transferred to the initiator out of the +- number of bytes expected to be transferred. +- +- bit 5 - (O) set for Residual Overflow. In this case, the Residual +- Count indicates the number of bytes that were not transferred +- because the initiator's Expected Data Transfer Length was not +- sufficient. For a bidirectional operation, the Residual Count +- contains the residual for the write operation. +- +- bit 6 - (U) set for Residual Underflow. In this case, the Residual +- Count indicates the number of bytes that were not transferred out +- of the number of bytes that were expected to be transferred. For +- a bidirectional operation, the Residual Count contains the +- residual for the write operation. +- +- bit 7 - (0) Reserved. +- +- Bits O and U and bits o and u are mutually exclusive (i.e., having +- both o and u or O and U set to 1 is a protocol error). For a +- response other than "Command Completed at Target", bits 3-6 MUST be +- 0. +- +-10.4.2. Status +- +- The Status field is used to report the SCSI status of the command (as +- specified in [SAM2]) and is only valid if the Response Code is +- Command Completed at target. +- +- +- +- +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 123] +- +-RFC 3720 iSCSI April 2004 +- +- +- Some of the status codes defined in [SAM2] are: +- +- 0x00 GOOD +- 0x02 CHECK CONDITION +- 0x08 BUSY +- 0x18 RESERVATION CONFLICT +- 0x28 TASK SET FULL +- 0x30 ACA ACTIVE +- 0x40 TASK ABORTED +- +- See [SAM2] for the complete list and definitions. +- +- If a SCSI device error is detected while data from the initiator is +- still expected (the command PDU did not contain all the data and the +- target has not received a Data PDU with the final bit Set), the +- target MUST wait until it receives a Data PDU with the F bit set in +- the last expected sequence before sending the Response PDU. +- +-10.4.3. Response +- +- This field contains the iSCSI service response. +- +- iSCSI service response codes defined in this specification are: +- +- 0x00 - Command Completed at Target +- 0x01 - Target Failure +- 0x80-0xff - Vendor specific +- +- All other response codes are reserved. +- +- The Response is used to report a Service Response. The mapping of +- the response code into a SCSI service response code value, if needed, +- is outside the scope of this document. However, in symbolic terms +- response value 0x00 maps to the SCSI service response (see [SAM2] and +- [SPC3]) of TASK COMPLETE or LINKED COMMAND COMPLETE. All other +- Response values map to the SCSI service response of SERVICE DELIVERY +- OR TARGET FAILURE. +- +- If a PDU that includes SCSI status (Response PDU or Data-In PDU +- including status) does not arrive before the session is terminated, +- the SCSI service response is SERVICE DELIVERY OR TARGET FAILURE. +- +- A non-zero Response field indicates a failure to execute the command +- in which case the Status and Flag fields are undefined. +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 124] +- +-RFC 3720 iSCSI April 2004 +- +- +-10.4.4. SNACK Tag +- +- This field contains a copy of the SNACK Tag of the last SNACK Tag +- accepted by the target on the same connection and for the command for +- which the response is issued. Otherwise it is reserved and should be +- set to 0. +- +- After issuing a R-Data SNACK the initiator must discard any SCSI +- status unless contained in an SCSI Response PDU carrying the same +- SNACK Tag as the last issued R-Data SNACK for the SCSI command on the +- current connection. +- +- For a detailed discussion on R-Data SNACK see Section 10.16 SNACK +- Request. +- +-10.4.5. Residual Count +- +- The Residual Count field MUST be valid in the case where either the U +- bit or the O bit is set. If neither bit is set, the Residual Count +- field is reserved. Targets may set the residual count and initiators +- may use it when the response code is "completed at target" (even if +- the status returned is not GOOD). If the O bit is set, the Residual +- Count indicates the number of bytes that were not transferred because +- the initiator's Expected Data Transfer Length was not sufficient. If +- the U bit is set, the Residual Count indicates the number of bytes +- that were not transferred out of the number of bytes expected to be +- transferred. +- +-10.4.6. Bidirectional Read Residual Count +- +- The Bidirectional Read Residual Count field MUST be valid in the case +- where either the u bit or the o bit is set. If neither bit is set, +- the Bidirectional Read Residual Count field is reserved. Targets may +- set the Bidirectional Read Residual Count and initiators may use it +- when the response code is "completed at target". If the o bit is +- set, the Bidirectional Read Residual Count indicates the number of +- bytes that were not transferred to the initiator because the +- initiator's Expected Bidirectional Read Transfer Length was not +- sufficient. If the u bit is set, the Bidirectional Read Residual +- Count indicates the number of bytes that were not transferred to the +- initiator out of the number of bytes expected to be transferred. +- +-10.4.7. Data Segment - Sense and Response Data Segment +- +- iSCSI targets MUST support and enable autosense. If Status is CHECK +- CONDITION (0x02), then the Data Segment MUST contain sense data for +- the failed command. +- +- +- +- +-Satran, et al. Standards Track [Page 125] +- +-RFC 3720 iSCSI April 2004 +- +- +- For some iSCSI responses, the response data segment MAY contain some +- response related information, (e.g., for a target failure, it may +- contain a vendor specific detailed description of the failure). +- +- If the DataSegmentLength is not 0, the format of the Data Segment is +- as follows: +- +- Byte/ 0 | 1 | 2 | 3 | +- / | | | | +- |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +- +---------------+---------------+---------------+---------------+ +- 0|SenseLength | Sense Data | +- +---------------+---------------+---------------+---------------+ +- x/ Sense Data / +- +---------------+---------------+---------------+---------------+ +- y/ Response Data / +- / / +- +---------------+---------------+---------------+---------------+ +- z| +- +-10.4.7.1. SenseLength +- +- Length of Sense Data. +- +-10.4.7.2. Sense Data +- +- The Sense Data contains detailed information about a check condition +- and [SPC3] specifies the format and content of the Sense Data. +- +- Certain iSCSI conditions result in the command being terminated at +- the target (response Command Completed at Target) with a SCSI Check +- Condition Status as outlined in the next table: +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 126] +- +-RFC 3720 iSCSI April 2004 +- +- +- +--------------------------+----------+---------------------------+ +- | iSCSI Condition |Sense | Additional Sense Code & | +- | |Key | Qualifier | +- +--------------------------+----------+---------------------------+ +- | Unexpected unsolicited |Aborted | ASC = 0x0c ASCQ = 0x0c | +- | data |Command-0B| Write Error | +- +--------------------------+----------+---------------------------+ +- | Incorrect amount of data |Aborted | ASC = 0x0c ASCQ = 0x0d | +- | |Command-0B| Write Error | +- +--------------------------+----------+---------------------------+ +- | Protocol Service CRC |Aborted | ASC = 0x47 ASCQ = 0x05 | +- | error |Command-0B| CRC Error Detected | +- +--------------------------+----------+---------------------------+ +- | SNACK rejected |Aborted | ASC = 0x11 ASCQ = 0x13 | +- | |Command-0B| Read Error | +- +--------------------------+----------+---------------------------+ +- +- The target reports the "Incorrect amount of data" condition if during +- data output the total data length to output is greater than +- FirstBurstLength and the initiator sent unsolicited non-immediate +- data but the total amount of unsolicited data is different than +- FirstBurstLength. The target reports the same error when the amount +- of data sent as a reply to an R2T does not match the amount +- requested. +- +-10.4.8. ExpDataSN +- +- The number of R2T and Data-In (read) PDUs the target has sent for the +- command. +- +- This field MUST be 0 if the response code is not Command Completed at +- Target or the target sent no Data-In PDUs for the command. +- +-10.4.9. StatSN - Status Sequence Number +- +- StatSN is a Sequence Number that the target iSCSI layer generates per +- connection and that in turn, enables the initiator to acknowledge +- status reception. StatSN is incremented by 1 for every +- response/status sent on a connection except for responses sent as a +- result of a retry or SNACK. In the case of responses sent due to a +- retransmission request, the StatSN MUST be the same as the first time +- the PDU was sent unless the connection has since been restarted. +- +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 127] +- +-RFC 3720 iSCSI April 2004 +- +- +-10.4.10. ExpCmdSN - Next Expected CmdSN from this Initiator +- +- ExpCmdSN is a Sequence Number that the target iSCSI returns to the +- initiator to acknowledge command reception. It is used to update a +- local variable with the same name. An ExpCmdSN equal to MaxCmdSN+1 +- indicates that the target cannot accept new commands. +- +-10.4.11. MaxCmdSN - Maximum CmdSN from this Initiator +- +- MaxCmdSN is a Sequence Number that the target iSCSI returns to the +- initiator to indicate the maximum CmdSN the initiator can send. It +- is used to update a local variable with the same name. If MaxCmdSN +- is equal to ExpCmdSN-1, this indicates to the initiator that the +- target cannot receive any additional commands. When MaxCmdSN changes +- at the target while the target has no pending PDUs to convey this +- information to the initiator, it MUST generate a NOP-IN to carry the +- new MaxCmdSN. +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 128] +- +-RFC 3720 iSCSI April 2004 +- +- +-10.5. Task Management Function Request +- +- Byte/ 0 | 1 | 2 | 3 | +- / | | | | +- |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +- +---------------+---------------+---------------+---------------+ +- 0|.|I| 0x02 |1| Function | Reserved | +- +---------------+---------------+---------------+---------------+ +- 4|TotalAHSLength | DataSegmentLength | +- +---------------+---------------+---------------+---------------+ +- 8| Logical Unit Number (LUN) or Reserved | +- + + +- 12| | +- +---------------+---------------+---------------+---------------+ +- 16| Initiator Task Tag | +- +---------------+---------------+---------------+---------------+ +- 20| Referenced Task Tag or 0xffffffff | +- +---------------+---------------+---------------+---------------+ +- 24| CmdSN | +- +---------------+---------------+---------------+---------------+ +- 28| ExpStatSN | +- +---------------+---------------+---------------+---------------+ +- 32| RefCmdSN or Reserved | +- +---------------+---------------+---------------+---------------+ +- 36| ExpDataSN or Reserved | +- +---------------+---------------+---------------+---------------+ +- 40/ Reserved / +- +/ / +- +---------------+---------------+---------------+---------------+ +- 48| Header-Digest (Optional) | +- +---------------+---------------+---------------+---------------+ +- +-10.5.1. Function +- +- The Task Management functions provide an initiator with a way to +- explicitly control the execution of one or more Tasks (SCSI and iSCSI +- tasks). The Task Management function codes are listed below. For a +- more detailed description of SCSI task management, see [SAM2]. +- +- 1 - ABORT TASK - aborts the task identified by the Referenced Task +- Tag field. +- +- 2 - ABORT TASK SET - aborts all Tasks issued via this session on the +- logical unit. +- +- 3 - CLEAR ACA - clears the Auto Contingent Allegiance condition. +- +- +- +- +- +-Satran, et al. Standards Track [Page 129] +- +-RFC 3720 iSCSI April 2004 +- +- +- 4 - CLEAR TASK SET - aborts all Tasks in the appropriate task set as +- defined by the TST field in the Control mode page (see [SPC3]). +- +- 5 - LOGICAL UNIT RESET +- +- 6 - TARGET WARM RESET +- +- 7 - TARGET COLD RESET +- +- 8 - TASK REASSIGN - reassigns connection allegiance for the task +- identified by the Referenced Task Tag field to this connection, +- thus resuming the iSCSI exchanges for the task. +- +- For all these functions, the Task Management function response MUST +- be returned as detailed in Section 10.6 Task Management Function +- Response. All these functions apply to the referenced tasks +- regardless of whether they are proper SCSI tasks or tagged iSCSI +- operations. Task management requests must act on all the commands +- from the same session having a CmdSN lower than the task management +- CmdSN. LOGICAL UNIT RESET, TARGET WARM RESET and TARGET COLD RESET +- may affect commands from other sessions or commands from the same +- session with CmdSN equal or exceeding CmdSN. +- +- If the task management request is marked for immediate delivery, it +- must be considered immediately for execution, but the operations +- involved (all or part of them) may be postponed to allow the target +- to receive all relevant tasks. According to [SAM2], for all the +- tasks covered by the Task Management response (i.e., with CmdSN lower +- than the task management command CmdSN) but except the Task +- Management response to a TASK REASSIGN, additional responses MUST NOT +- be delivered to the SCSI layer after the Task Management response. +- The iSCSI initiator MAY deliver to the SCSI layer all responses +- received before the Task Management response (i.e., it is a matter of +- implementation if the SCSI responses, received before the Task +- Management response but after the task management request was issued, +- are delivered to the SCSI layer by the iSCSI layer in the initiator). +- The iSCSI target MUST ensure that no responses for the tasks covered +- by a task management function are delivered to the iSCSI initiator +- after the Task Management response except for a task covered by a +- TASK REASSIGN. +- +- For ABORT TASK SET and CLEAR TASK SET, the issuing initiator MUST +- continue to respond to all valid target transfer tags (received via +- R2T, Text Response, NOP-In, or SCSI Data-In PDUs) related to the +- affected task set, even after issuing the task management request. +- The issuing initiator SHOULD however terminate (i.e., by setting the +- F-bit to 1) these response sequences as quickly as possible. The +- target on its part MUST wait for responses on all affected target +- +- +- +-Satran, et al. Standards Track [Page 130] +- +-RFC 3720 iSCSI April 2004 +- +- +- transfer tags before acting on either of these two task management +- requests. In case all or part of the response sequence is not +- received (due to digest errors) for a valid TTT, the target MAY treat +- it as a case of within-command error recovery class (see Section +- 6.1.4.1 Recovery Within-command) if it is supporting +- ErrorRecoveryLevel >= 1, or alternatively may drop the connection to +- complete the requested task set function. +- +- If an ABORT TASK is issued for a task created by an immediate command +- then RefCmdSN MUST be that of the Task Management request itself +- (i.e., CmdSN and RefCmdSN are equal); otherwise RefCmdSN MUST be set +- to the CmdSN of the task to be aborted (lower than CmdSN). +- +- If the connection is still active (it is not undergoing an implicit +- or explicit logout), ABORT TASK MUST be issued on the same connection +- to which the task to be aborted is allegiant at the time the Task +- Management Request is issued. If the connection is implicitly or +- explicitly logged out (i.e., no other request will be issued on the +- failing connection and no other response will be received on the +- failing connection), then an ABORT TASK function request may be +- issued on another connection. This Task Management request will then +- establish a new allegiance for the command to be aborted as well as +- abort it (i.e., the task to be aborted will not have to be retried or +- reassigned, and its status, if issued but not acknowledged, will be +- reissued followed by the Task Management response). +- +- At the target an ABORT TASK function MUST NOT be executed on a Task +- Management request; such a request MUST result in Task Management +- response of "Function rejected". +- +- For the LOGICAL UNIT RESET function, the target MUST behave as +- dictated by the Logical Unit Reset function in [SAM2]. +- +- The implementation of the TARGET WARM RESET function and the TARGET +- COLD RESET function is OPTIONAL and when implemented, should act as +- described below. The TARGET WARM RESET is also subject to SCSI +- access controls on the requesting initiator as defined in [SPC3]. +- When authorization fails at the target, the appropriate response as +- described in Section 10.6 Task Management Function Response MUST be +- returned by the target. The TARGET COLD RESET function is not +- subject to SCSI access controls, but its execution privileges may be +- managed by iSCSI mechanisms such as login authentication. +- +- When executing the TARGET WARM RESET and TARGET COLD RESET functions, +- the target cancels all pending operations on all Logical Units known +- by the issuing initiator. Both functions are equivalent to the +- Target Reset function specified by [SAM2]. They can affect many +- other initiators logged in with the servicing SCSI target port. +- +- +- +-Satran, et al. Standards Track [Page 131] +- +-RFC 3720 iSCSI April 2004 +- +- +- The target MUST treat the TARGET COLD RESET function additionally as +- a power on event, thus terminating all of its TCP connections to all +- initiators (all sessions are terminated). For this reason, the +- Service Response (defined by [SAM2]) for this SCSI task management +- function may not be reliably delivered to the issuing initiator port. +- +- For the TASK REASSIGN function, the target should reassign the +- connection allegiance to this new connection (and thus resume iSCSI +- exchanges for the task). TASK REASSIGN MUST ONLY be received by the +- target after the connection on which the command was previously +- executing has been successfully logged-out. The Task Management +- response MUST be issued before the reassignment becomes effective. +- For additional usage semantics see Section 6.2 Retry and Reassign in +- Recovery. +- +- At the target a TASK REASSIGN function request MUST NOT be executed +- to reassign the connection allegiance of a Task Management function +- request, an active text negotiation task, or a Logout task; such a +- request MUST result in Task Management response of "Function +- rejected". +- +- TASK REASSIGN MUST be issued as an immediate command. +- +-10.5.2. TotalAHSLength and DataSegmentLength +- +- For this PDU TotalAHSLength and DataSegmentLength MUST be 0. +- +-10.5.3. LUN +- +- This field is required for functions that address a specific LU +- (ABORT TASK, CLEAR TASK SET, ABORT TASK SET, CLEAR ACA, LOGICAL UNIT +- RESET) and is reserved in all others. +- +-10.5.4. Referenced Task Tag +- +- The Initiator Task Tag of the task to be aborted for the ABORT TASK +- function or reassigned for the TASK REASSIGN function. For all the +- other functions this field MUST be set to the reserved value +- 0xffffffff. +- +-10.5.5. RefCmdSN +- +- If an ABORT TASK is issued for a task created by an immediate command +- then RefCmdSN MUST be that of the Task Management request itself +- (i.e., CmdSN and RefCmdSN are equal). +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 132] +- +-RFC 3720 iSCSI April 2004 +- +- +- For an ABORT TASK of a task created by non-immediate command RefCmdSN +- MUST be set to the CmdSN of the task identified by the Referenced +- Task Tag field. Targets must use this field as described in section +- 10.6.1 when the task identified by the Referenced Task Tag field is +- not with the target. +- +- Otherwise, this field is reserved. +- +-10.5.6. ExpDataSN +- +- For recovery purposes, the iSCSI target and initiator maintain a data +- acknowledgement reference number - the first input DataSN number +- unacknowledged by the initiator. When issuing a new command, this +- number is set to 0. If the function is TASK REASSIGN, which +- establishes a new connection allegiance for a previously issued Read +- or Bidirectional command, ExpDataSN will contain an updated data +- acknowledgement reference number or the value 0; the latter +- indicating that the data acknowledgement reference number is +- unchanged. The initiator MUST discard any data PDUs from the +- previous execution that it did not acknowledge and the target MUST +- transmit all Data-In PDUs (if any) starting with the data +- acknowledgement reference number. The number of retransmitted PDUs +- may or may not be the same as the original transmission depending on +- if there was a change in MaxRecvDataSegmentLength in the +- reassignment. The target MAY also send no more Data-In PDUs if all +- data has been acknowledged. +- +- The value of ExpDataSN MUST be 0 or higher than the DataSN of the +- last acknowledged Data-In PDU, but not larger than DataSN+1 of the +- last Data-In PDU sent by the target. Any other value MUST be ignored +- by the target. +- +- For other functions this field is reserved. +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 133] +- +-RFC 3720 iSCSI April 2004 +- +- +-10.6. Task Management Function Response +- +- Byte/ 0 | 1 | 2 | 3 | +- / | | | | +- |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +- +---------------+---------------+---------------+---------------+ +- 0|.|.| 0x22 |1| Reserved | Response | Reserved | +- +---------------+---------------+---------------+---------------+ +- 4|TotalAHSLength | DataSegmentLength | +- +---------------------------------------------------------------+ +- 8/ Reserved / +- / / +- +---------------+---------------+---------------+---------------+ +- 16| Initiator Task Tag | +- +---------------+---------------+---------------+---------------+ +- 20| Reserved | +- +---------------+---------------+---------------+---------------+ +- 24| StatSN | +- +---------------+---------------+---------------+---------------+ +- 28| ExpCmdSN | +- +---------------+---------------+---------------+---------------+ +- 32| MaxCmdSN | +- +---------------+---------------+---------------+---------------+ +- 36/ Reserved / +- +/ / +- +---------------+---------------+---------------+---------------+ +- 48| Header-Digest (Optional) | +- +---------------+---------------+---------------+---------------+ +- +- For the functions ABORT TASK, ABORT TASK SET, CLEAR ACA, CLEAR TASK +- SET, LOGICAL UNIT RESET, TARGET COLD RESET, TARGET WARM RESET and +- TASK REASSIGN, the target performs the requested Task Management +- function and sends a Task Management response back to the initiator. +- For TASK REASSIGN, the new connection allegiance MUST ONLY become +- effective at the target after the target issues the Task Management +- Response. +- +-10.6.1. Response +- +- The target provides a Response, which may take on the following +- values: +- +- a) 0 - Function complete. +- b) 1 - Task does not exist. +- c) 2 - LUN does not exist. +- d) 3 - Task still allegiant. +- e) 4 - Task allegiance reassignment not supported. +- +- +- +- +-Satran, et al. Standards Track [Page 134] +- +-RFC 3720 iSCSI April 2004 +- +- +- f) 5 - Task management function not supported. +- g) 6 - Function authorization failed. +- h) 255 - Function rejected. +- +- All other values are reserved. +- +- For a discussion on usage of response codes 3 and 4, see Section +- 6.2.2 Allegiance Reassignment. +- +- For the TARGET COLD RESET and TARGET WARM RESET functions, the target +- cancels all pending operations across all Logical Units known to the +- issuing initiator. For the TARGET COLD RESET function, the target +- MUST then close all of its TCP connections to all initiators +- (terminates all sessions). +- +- The mapping of the response code into a SCSI service response code +- value, if needed, is outside the scope of this document. However, in +- symbolic terms Response values 0 and 1 map to the SCSI service +- response of FUNCTION COMPLETE. All other Response values map to the +- SCSI service response of FUNCTION REJECTED. If a Task Management +- function response PDU does not arrive before the session is +- terminated, the SCSI service response is SERVICE DELIVERY OR TARGET +- FAILURE. +- +- The response to ABORT TASK SET and CLEAR TASK SET MUST only be issued +- by the target after all of the commands affected have been received +- by the target, the corresponding task management functions have been +- executed by the SCSI target, and the delivery of all responses +- delivered until the task management function completion have been +- confirmed (acknowledged through ExpStatSN) by the initiator on all +- connections of this session. For the exact timeline of events, refer +- to Section 10.6.2 Task Management Actions on Task Sets. +- +- For the ABORT TASK function, +- +- a) If the Referenced Task Tag identifies a valid task leading to +- a successful termination, then targets must return the +- "Function complete" response. +- b) If the Referenced Task Tag does not identify an existing task, +- but if the CmdSN indicated by the RefCmdSN field in the Task +- Management function request is within the valid CmdSN window +- and less than the CmdSN of the Task Management function +- request itself, then targets must consider the CmdSN received +- and return the "Function complete" response. +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 135] +- +-RFC 3720 iSCSI April 2004 +- +- +- c) If the Referenced Task Tag does not identify an existing task +- and if the CmdSN indicated by the RefCmdSN field in the Task +- Management function request is outside the valid CmdSN window, +- then targets must return the "Task does not exist" response. +- +-10.6.2. Task Management Actions on Task Sets +- +- The execution of ABORT TASK SET and CLEAR TASK SET Task Management +- function requests consists of the following sequence of events in the +- specified order on each of the entities. +- +- The initiator: +- +- a) Issues ABORT TASK SET/CLEAR TASK SET request. +- b) Continues to respond to each target transfer tag received +- for the affected task set. +- c) Receives any responses for the tasks in the affected task +- set (may process them as usual because they are guaranteed +- to be valid). +- d) Receives the task set management response, thus concluding +- all the tasks in the affected task set. +- +- The target: +- +- a) Receives the ABORT TASK SET/CLEAR TASK SET request. +- b) Waits for all target transfer tags to be responded to and +- for all affected tasks in the task set to be received. +- c) Propagates the command to and receives the response from the +- target SCSI layer. +- d) Takes note of last-sent StatSN on each of the connections in +- the iSCSI sessions (one or more) sharing the affected task +- set, and waits for acknowledgement of each StatSN (may +- solicit for acknowledgement by way of a NOP-In). If some +- tasks originate from non-iSCSI I_T_L nexi then the means by +- which the target insures that all affected tasks have +- returned their status to the initiator are defined by the +- specific protocol. +- +- e) Sends the task set management response to the issuing +- initiator. +- +- +- +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 136] +- +-RFC 3720 iSCSI April 2004 +- +- +-10.6.3. TotalAHSLength and DataSegmentLength +- +- For this PDU TotalAHSLength and DataSegmentLength MUST be 0. +- +-10.7. SCSI Data-Out & SCSI Data-In +- +- The SCSI Data-Out PDU for WRITE operations has the following format: +- +- Byte/ 0 | 1 | 2 | 3 | +- / | | | | +- |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +- +---------------+---------------+---------------+---------------+ +- 0|.|.| 0x05 |F| Reserved | +- +---------------+---------------+---------------+---------------+ +- 4|TotalAHSLength | DataSegmentLength | +- +---------------+---------------+---------------+---------------+ +- 8| LUN or Reserved | +- + + +- 12| | +- +---------------+---------------+---------------+---------------+ +- 16| Initiator Task Tag | +- +---------------+---------------+---------------+---------------+ +- 20| Target Transfer Tag or 0xffffffff | +- +---------------+---------------+---------------+---------------+ +- 24| Reserved | +- +---------------+---------------+---------------+---------------+ +- 28| ExpStatSN | +- +---------------+---------------+---------------+---------------+ +- 32| Reserved | +- +---------------+---------------+---------------+---------------+ +- 36| DataSN | +- +---------------+---------------+---------------+---------------+ +- 40| Buffer Offset | +- +---------------+---------------+---------------+---------------+ +- 44| Reserved | +- +---------------+---------------+---------------+---------------+ +- 48| Header-Digest (Optional) | +- +---------------+---------------+---------------+---------------+ +- / DataSegment / +- +/ / +- +---------------+---------------+---------------+---------------+ +- | Data-Digest (Optional) | +- +---------------+---------------+---------------+---------------+ +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 137] +- +-RFC 3720 iSCSI April 2004 +- +- +- The SCSI Data-In PDU for READ operations has the following format: +- +- Byte/ 0 | 1 | 2 | 3 | +- / | | | | +- |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +- +---------------+---------------+---------------+---------------+ +- 0|.|.| 0x25 |F|A|0 0 0|O|U|S| Reserved |Status or Rsvd | +- +---------------+---------------+---------------+---------------+ +- 4|TotalAHSLength | DataSegmentLength | +- +---------------+---------------+---------------+---------------+ +- 8| LUN or Reserved | +- + + +- 12| | +- +---------------+---------------+---------------+---------------+ +- 16| Initiator Task Tag | +- +---------------+---------------+---------------+---------------+ +- 20| Target Transfer Tag or 0xffffffff | +- +---------------+---------------+---------------+---------------+ +- 24| StatSN or Reserved | +- +---------------+---------------+---------------+---------------+ +- 28| ExpCmdSN | +- +---------------+---------------+---------------+---------------+ +- 32| MaxCmdSN | +- +---------------+---------------+---------------+---------------+ +- 36| DataSN | +- +---------------+---------------+---------------+---------------+ +- 40| Buffer Offset | +- +---------------+---------------+---------------+---------------+ +- 44| Residual Count | +- +---------------+---------------+---------------+---------------+ +- 48| Header-Digest (Optional) | +- +---------------+---------------+---------------+---------------+ +- / DataSegment / +- +/ / +- +---------------+---------------+---------------+---------------+ +- | Data-Digest (Optional) | +- +---------------+---------------+---------------+---------------+ +- +- Status can accompany the last Data-In PDU if the command did not end +- with an exception (i.e., the status is "good status" - GOOD, +- CONDITION MET or INTERMEDIATE CONDITION MET). The presence of status +- (and of a residual count) is signaled though the S flag bit. +- Although targets MAY choose to send even non-exception status in +- separate responses, initiators MUST support non-exception status in +- Data-In PDUs. +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 138] +- +-RFC 3720 iSCSI April 2004 +- +- +-10.7.1. F (Final) Bit +- +- For outgoing data, this bit is 1 for the last PDU of unsolicited data +- or the last PDU of a sequence that answers an R2T. +- +- For incoming data, this bit is 1 for the last input (read) data PDU +- of a sequence. Input can be split into several sequences, each +- having its own F bit. Splitting the data stream into sequences does +- not affect DataSN counting on Data-In PDUs. It MAY be used as a +- "change direction" indication for Bidirectional operations that need +- such a change. +- +- DataSegmentLength MUST not exceed MaxRecvDataSegmentLength for the +- direction it is sent and the total of all the DataSegmentLength of +- all PDUs in a sequence MUST not exceed MaxBurstLength (or +- FirstBurstLength for unsolicited data). However the number of +- individual PDUs in a sequence (or in total) may be higher than the +- MaxBurstLength (or FirstBurstLength) to MaxRecvDataSegmentLength +- ratio (as PDUs may be limited in length by the sender capabilities). +- Using DataSegmentLength of 0 may increase beyond what is reasonable +- for the number of PDUs and should therefore be avoided. +- +- For Bidirectional operations, the F bit is 1 for both the end of the +- input sequences and the end of the output sequences. +- +-10.7.2. A (Acknowledge) Bit +- +- For sessions with ErrorRecoveryLevel 1 or higher, the target sets +- this bit to 1 to indicate that it requests a positive acknowledgement +- from the initiator for the data received. The target should use the +- A bit moderately; it MAY only set the A bit to 1 once every +- MaxBurstLength bytes, or on the last Data-In PDU that concludes the +- entire requested read data transfer for the task from the target's +- perspective, and it MUST NOT do so more frequently. The target MUST +- NOT set to 1 the A bit for sessions with ErrorRecoveryLevel=0. The +- initiator MUST ignore the A bit set to 1 for sessions with +- ErrorRecoveryLevel=0. +- +- On receiving a Data-In PDU with the A bit set to 1 on a session with +- ErrorRecoveryLevel greater than 0, if there are no holes in the read +- data until that Data-In PDU, the initiator MUST issue a SNACK of type +- DataACK except when it is able to acknowledge the status for the task +- immediately via ExpStatSN on other outbound PDUs if the status for +- the task is also received. In the latter case (acknowledgement +- through ExpStatSN), sending a SNACK of type DataACK in response to +- the A bit is OPTIONAL, but if it is done, it must not be sent after +- the status acknowledgement through ExpStatSN. If the initiator has +- detected holes in the read data prior to that Data-In PDU, it MUST +- +- +- +-Satran, et al. Standards Track [Page 139] +- +-RFC 3720 iSCSI April 2004 +- +- +- postpone issuing the SNACK of type DataACK until the holes are +- filled. An initiator also MUST NOT acknowledge the status for the +- task before those holes are filled. A status acknowledgement for a +- task that generated the Data-In PDUs is considered by the target as +- an implicit acknowledgement of the Data-In PDUs if such an +- acknowledgement was requested by the target. +- +-10.7.3. Flags (byte 1) +- +- The last SCSI Data packet sent from a target to an initiator for a +- SCSI command that completed successfully (with a status of GOOD, +- CONDITION MET, INTERMEDIATE or INTERMEDIATE CONDITION MET) may also +- optionally contain the Status for the data transfer. As Sense Data +- cannot be sent together with the Command Status, if the command is +- completed with an error, then the response and sense data MUST be +- sent in a SCSI Response PDU (i.e., MUST NOT be sent in a SCSI Data +- packet). If Status is sent with the data, then a SCSI Response PDU +- MUST NOT be sent as this would violate SCSI rules (a single status). +- For Bidirectional commands, the status MUST be sent in a SCSI +- Response PDU. +- +- bit 2-4 - Reserved. +- +- bit 5-6 - used the same as in a SCSI Response. These bits are +- only valid when S is set to 1. For details see Section +- 10.4.1 Flags (byte 1). +- +- bit 7 S (status)- set to indicate that the Command Status field +- contains status. If this bit is set to 1, the F bit +- MUST also be set to 1. +- +- The fields StatSN, Status, and Residual Count only have meaningful +- content if the S bit is set to 1 and their values are defined in +- Section 10.4 SCSI Response. +- +-10.7.4. Target Transfer Tag and LUN +- +- On outgoing data, the Target Transfer Tag is provided to the target +- if the transfer is honoring an R2T. In this case, the Target +- Transfer Tag field is a replica of the Target Transfer Tag provided +- with the R2T. +- +- On incoming data, the Target Transfer Tag and LUN MUST be provided by +- the target if the A bit is set to 1; otherwise they are reserved. +- The Target Transfer Tag and LUN are copied by the initiator into the +- SNACK of type DataACK that it issues as a result of receiving a SCSI +- Data-In PDU with the A bit set to 1. +- +- +- +- +-Satran, et al. Standards Track [Page 140] +- +-RFC 3720 iSCSI April 2004 +- +- +- The Target Transfer Tag values are not specified by this protocol +- except that the value 0xffffffff is reserved and means that the +- Target Transfer Tag is not supplied. If the Target Transfer Tag is +- provided, then the LUN field MUST hold a valid value and be +- consistent with whatever was specified with the command; otherwise, +- the LUN field is reserved. +- +-10.7.5. DataSN +- +- For input (read) or bidirectional Data-In PDUs, the DataSN is the +- input PDU number within the data transfer for the command identified +- by the Initiator Task Tag. +- +- R2T and Data-In PDUs, in the context of bidirectional commands, share +- the numbering sequence (see Section 3.2.2.3 Data Sequencing). +- +- For output (write) data PDUs, the DataSN is the Data-Out PDU number +- within the current output sequence. The current output sequence is +- either identified by the Initiator Task Tag (for unsolicited data) or +- is a data sequence generated for one R2T (for data solicited through +- R2T). +- +-10.7.6. Buffer Offset +- +- The Buffer Offset field contains the offset of this PDU payload data +- within the complete data transfer. The sum of the buffer offset and +- length should not exceed the expected transfer length for the +- command. +- +- The order of data PDUs within a sequence is determined by +- DataPDUInOrder. When set to Yes, it means that PDUs have to be in +- increasing Buffer Offset order and overlays are forbidden. +- +- The ordering between sequences is determined by DataSequenceInOrder. +- When set to Yes, it means that sequences have to be in increasing +- Buffer Offset order and overlays are forbidden. +- +-10.7.7. DataSegmentLength +- +- This is the data payload length of a SCSI Data-In or SCSI Data-Out +- PDU. The sending of 0 length data segments should be avoided, but +- initiators and targets MUST be able to properly receive 0 length data +- segments. +- +- The Data Segments of Data-In and Data-Out PDUs SHOULD be filled to +- the integer number of 4 byte words (real payload) unless the F bit is +- set to 1. +- +- +- +- +-Satran, et al. Standards Track [Page 141] +- +-RFC 3720 iSCSI April 2004 +- +- +-10.8. Ready To Transfer (R2T) +- +- Byte/ 0 | 1 | 2 | 3 | +- / | | | | +- |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +- +---------------+---------------+---------------+---------------+ +- 0|.|.| 0x31 |1| Reserved | +- +---------------+---------------+---------------+---------------+ +- 4|TotalAHSLength | DataSegmentLength | +- +---------------+---------------+---------------+---------------+ +- 8| LUN | +- + + +- 12| | +- +---------------+---------------+---------------+---------------+ +- 16| Initiator Task Tag | +- +---------------+---------------+---------------+---------------+ +- 20| Target Transfer Tag | +- +---------------+---------------+---------------+---------------+ +- 24| StatSN | +- +---------------+---------------+---------------+---------------+ +- 28| ExpCmdSN | +- +---------------+---------------+---------------+---------------+ +- 32| MaxCmdSN | +- +---------------+---------------+---------------+---------------+ +- 36| R2TSN | +- +---------------+---------------+---------------+---------------+ +- 40| Buffer Offset | +- +---------------+---------------+---------------+---------------+ +- 44| Desired Data Transfer Length | +- +---------------------------------------------------------------+ +- 48| Header-Digest (Optional) | +- +---------------+---------------+---------------+---------------+ +- +- When an initiator has submitted a SCSI Command with data that passes +- from the initiator to the target (WRITE), the target may specify +- which blocks of data it is ready to receive. The target may request +- that the data blocks be delivered in whichever order is convenient +- for the target at that particular instant. This information is +- passed from the target to the initiator in the Ready To Transfer +- (R2T) PDU. +- +- In order to allow write operations without an explicit initial R2T, +- the initiator and target MUST have negotiated the key InitialR2T to +- No during Login. +- +- An R2T MAY be answered with one or more SCSI Data-Out PDUs with a +- matching Target Transfer Tag. If an R2T is answered with a single +- Data-Out PDU, the Buffer Offset in the Data PDU MUST be the same as +- +- +- +-Satran, et al. Standards Track [Page 142] +- +-RFC 3720 iSCSI April 2004 +- +- +- the one specified by the R2T, and the data length of the Data PDU +- MUST be the same as the Desired Data Transfer Length specified in the +- R2T. If the R2T is answered with a sequence of Data PDUs, the Buffer +- Offset and Length MUST be within the range of those specified by R2T, +- and the last PDU MUST have the F bit set to 1. If the last PDU +- (marked with the F bit) is received before the Desired Data Transfer +- Length is transferred, a target MAY choose to Reject that +- +- PDU with "Protocol error" reason code. DataPDUInOrder governs the +- Data-Out PDU ordering. If DataPDUInOrder is set to Yes, the Buffer +- Offsets and Lengths for consecutive PDUs MUST form a continuous +- non-overlapping range and the PDUs MUST be sent in increasing offset +- order. +- +- The target may send several R2T PDUs. It, therefore, can have a +- number of pending data transfers. The number of outstanding R2T PDUs +- are limited by the value of the negotiated key MaxOutstandingR2T. +- Within a connection, outstanding R2Ts MUST be fulfilled by the +- initiator in the order in which they were received. +- +- R2T PDUs MAY also be used to recover Data Out PDUs. Such an R2T +- (Recovery-R2T) is generated by a target upon detecting the loss of +- one or more Data-Out PDUs due to: +- +- - Digest error +- - Sequence error +- - Sequence reception timeout +- +- A Recovery-R2T carries the next unused R2TSN, but requests part of or +- the entire data burst that an earlier R2T (with a lower R2TSN) had +- already requested. +- +- DataSequenceInOrder governs the buffer offset ordering in consecutive +- R2Ts. If DataSequenceInOrder is Yes, then consecutive R2Ts MUST +- refer to continuous non-overlapping ranges except for Recovery-R2Ts. +- +-10.8.1. TotalAHSLength and DataSegmentLength +- +- For this PDU TotalAHSLength and DataSegmentLength MUST be 0. +- +-10.8.2. R2TSN +- +- R2TSN is the R2T PDU input PDU number within the command identified +- by the Initiator Task Tag. +- +- For bidirectional commands R2T and Data-In PDUs share the input PDU +- numbering sequence (see Section 3.2.2.3 Data Sequencing). +- +- +- +- +-Satran, et al. Standards Track [Page 143] +- +-RFC 3720 iSCSI April 2004 +- +- +-10.8.3. StatSN +- +- The StatSN field will contain the next StatSN. The StatSN for this +- connection is not advanced after this PDU is sent. +- +-10.8.4. Desired Data Transfer Length and Buffer Offset +- +- The target specifies how many bytes it wants the initiator to send +- because of this R2T PDU. The target may request the data from the +- initiator in several chunks, not necessarily in the original order of +- the data. The target, therefore, also specifies a Buffer Offset that +- indicates the point at which the data transfer should begin, relative +- to the beginning of the total data transfer. The Desired Data +- Transfer Length MUST NOT be 0 and MUST not exceed MaxBurstLength. +- +-10.8.5. Target Transfer Tag +- +- The target assigns its own tag to each R2T request that it sends to +- the initiator. This tag can be used by the target to easily identify +- the data it receives. The Target Transfer Tag and LUN are copied in +- the outgoing data PDUs and are only used by the target. There is no +- protocol rule about the Target Transfer Tag except that the value +- 0xffffffff is reserved and MUST NOT be sent by a target in an R2T. +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 144] +- +-RFC 3720 iSCSI April 2004 +- +- +-10.9. Asynchronous Message +- +- An Asynchronous Message may be sent from the target to the initiator +- without correspondence to a particular command. The target specifies +- the reason for the event and sense data. +- +- Byte/ 0 | 1 | 2 | 3 | +- / | | | | +- |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +- +---------------+---------------+---------------+---------------+ +- 0|.|.| 0x32 |1| Reserved | +- +---------------+---------------+---------------+---------------+ +- 4|TotalAHSLength | DataSegmentLength | +- +---------------+---------------+---------------+---------------+ +- 8| LUN or Reserved | +- + + +- 12| | +- +---------------+---------------+---------------+---------------+ +- 16| 0xffffffff | +- +---------------+---------------+---------------+---------------+ +- 20| Reserved | +- +---------------+---------------+---------------+---------------+ +- 24| StatSN | +- +---------------+---------------+---------------+---------------+ +- 28| ExpCmdSN | +- +---------------+---------------+---------------+---------------+ +- 32| MaxCmdSN | +- +---------------+---------------+---------------+---------------+ +- 36| AsyncEvent | AsyncVCode | Parameter1 or Reserved | +- +---------------+---------------+---------------+---------------+ +- 40| Parameter2 or Reserved | Parameter3 or Reserved | +- +---------------+---------------+---------------+---------------+ +- 44| Reserved | +- +---------------+---------------+---------------+---------------+ +- 48| Header-Digest (Optional) | +- +---------------+---------------+---------------+---------------+ +- / DataSegment - Sense Data and iSCSI Event Data / +- +/ / +- +---------------+---------------+---------------+---------------+ +- | Data-Digest (Optional) | +- +---------------+---------------+---------------+---------------+ +- +- Some Asynchronous Messages are strictly related to iSCSI while others +- are related to SCSI [SAM2]. +- +- StatSN counts this PDU as an acknowledgeable event (StatSN is +- advanced), which allows for initiator and target state +- synchronization. +- +- +- +-Satran, et al. Standards Track [Page 145] +- +-RFC 3720 iSCSI April 2004 +- +- +-10.9.1. AsyncEvent +- +- The codes used for iSCSI Asynchronous Messages (events) are: +- +- 0 - a SCSI Asynchronous Event is reported in the sense data. +- Sense Data that accompanies the report, in the data segment, +- identifies the condition. The sending of a SCSI Event +- (Asynchronous Event Reporting in SCSI terminology) is +- dependent on the target support for SCSI asynchronous event +- reporting (see [SAM2]) as indicated in the standard INQUIRY +- data (see [SPC3]). Its use may be enabled by parameters in +- the SCSI Control mode page (see [SPC3]). +- +- 1 - target requests Logout. This Async Message MUST be sent on +- the same connection as the one requesting to be logged out. +- The initiator MUST honor this request by issuing a Logout as +- early as possible, but no later than Parameter3 seconds. +- Initiator MUST send a Logout with a reason code of "Close the +- connection" OR "Close the session" to close all the +- connections. Once this message is received, the initiator +- SHOULD NOT issue new iSCSI commands on the connection to be +- logged out. The target MAY reject any new I/O requests that +- it receives after this Message with the reason code "Waiting +- for Logout". If the initiator does not Logout in Parameter3 +- seconds, the target should send an Async PDU with iSCSI event +- code "Dropped the connection" if possible, or simply terminate +- the transport connection. Parameter1 and Parameter2 are +- reserved. +- +- 2 - target indicates it will drop the connection. The Parameter1 +- field indicates the CID of the connection that is going to be +- dropped. +- +- The Parameter2 field (Time2Wait) indicates, in seconds, the +- minimum time to wait before attempting to reconnect or +- reassign. +- +- The Parameter3 field (Time2Retain) indicates the maximum time +- allowed to reassign commands after the initial wait (in +- Parameter2). +- +- If the initiator does not attempt to reconnect and/or reassign +- the outstanding commands within the time specified by +- Parameter3, or if Parameter3 is 0, the target will terminate +- all outstanding commands on this connection. In this case, no +- other responses should be expected from the target for the +- outstanding commands on this connection. +- +- +- +- +-Satran, et al. Standards Track [Page 146] +- +-RFC 3720 iSCSI April 2004 +- +- +- A value of 0 for Parameter2 indicates that reconnect can be +- attempted immediately. +- +- 3 - target indicates it will drop all the connections of this +- session. +- +- Parameter1 field is reserved. +- +- The Parameter2 field (Time2Wait) indicates, in seconds, the +- minimum time to wait before attempting to reconnect. The +- Parameter3 field (Time2Retain) indicates the maximum time +- allowed to reassign commands after the initial wait (in +- Parameter2). +- +- If the initiator does not attempt to reconnect and/or reassign +- the outstanding commands within the time specified by +- Parameter3, or if Parameter3 is 0, the session is terminated. +- +- In this case, the target will terminate all outstanding +- commands in this session; no other responses should be +- expected from the target for the outstanding commands in this +- session. A value of 0 for Parameter2 indicates that reconnect +- can be attempted immediately. +- +- 4 - target requests parameter negotiation on this connection. The +- initiator MUST honor this request by issuing a Text Request +- (that can be empty) on the same connection as early as +- possible, but no later than Parameter3 seconds, unless a Text +- Request is already pending on the connection, or by issuing a +- Logout Request. If the initiator does not issue a Text +- Request the target may reissue the Asynchronous Message +- requesting parameter negotiation. +- +- 255 - vendor specific iSCSI Event. The AsyncVCode details the +- vendor code, and data MAY accompany the report. +- +- All other event codes are reserved. +- +-10.9.2. AsyncVCode +- +- AsyncVCode is a vendor specific detail code that is only valid if the +- AsyncEvent field indicates a vendor specific event. Otherwise, it is +- reserved. +- +-10.9.3. LUN +- +- The LUN field MUST be valid if AsyncEvent is 0. Otherwise, this +- field is reserved. +- +- +- +-Satran, et al. Standards Track [Page 147] +- +-RFC 3720 iSCSI April 2004 +- +- +-10.9.4. Sense Data and iSCSI Event Data +- +- For a SCSI event, this data accompanies the report in the data +- segment and identifies the condition. +- +- For an iSCSI event, additional vendor-unique data MAY accompany the +- Async event. Initiators MAY ignore the data when not understood +- while processing the rest of the PDU. +- +- If the DataSegmentLength is not 0, the format of the DataSegment is +- as follows: +- +- Byte/ 0 | 1 | 2 | 3 | +- / | | | | +- |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +- +---------------+---------------+---------------+---------------+ +- 0|SenseLength | Sense Data | +- +---------------+---------------+---------------+---------------+ +- x/ Sense Data / +- +---------------+---------------+---------------+---------------+ +- y/ iSCSI Event Data / +- / / +- +---------------+---------------+---------------+---------------+ +- z| +- +-10.9.4.1. SenseLength +- +- This is the length of Sense Data. When the Sense Data field is empty +- (e.g., the event is not a SCSI event) SenseLength is 0. +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 148] +- +-RFC 3720 iSCSI April 2004 +- +- +-10.10. Text Request +- +- The Text Request is provided to allow for the exchange of information +- and for future extensions. It permits the initiator to inform a +- target of its capabilities or to request some special operations. +- +- Byte/ 0 | 1 | 2 | 3 | +- / | | | | +- |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +- +---------------+---------------+---------------+---------------+ +- 0|.|I| 0x04 |F|C| Reserved | +- +---------------+---------------+---------------+---------------+ +- 4|TotalAHSLength | DataSegmentLength | +- +---------------+---------------+---------------+---------------+ +- 8| LUN or Reserved | +- + + +- 12| | +- +---------------+---------------+---------------+---------------+ +- 16| Initiator Task Tag | +- +---------------+---------------+---------------+---------------+ +- 20| Target Transfer Tag or 0xffffffff | +- +---------------+---------------+---------------+---------------+ +- 24| CmdSN | +- +---------------+---------------+---------------+---------------+ +- 28| ExpStatSN | +- +---------------+---------------+---------------+---------------+ +- 32/ Reserved / +- +/ / +- +---------------+---------------+---------------+---------------+ +- 48| Header-Digest (Optional) | +- +---------------+---------------+---------------+---------------+ +- / DataSegment (Text) / +- +/ / +- +---------------+---------------+---------------+---------------+ +- | Data-Digest (Optional) | +- +---------------+---------------+---------------+---------------+ +- +- An initiator MUST have at most one outstanding Text Request on a +- connection at any given time. +- +- On a connection failure, an initiator must either explicitly abort +- any active allegiant text negotiation task or must cause such a task +- to be implicitly terminated by the target. +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 149] +- +-RFC 3720 iSCSI April 2004 +- +- +-10.10.1. F (Final) Bit +- +- When set to 1, indicates that this is the last or only text request +- in a sequence of Text Requests; otherwise, it indicates that more +- Text Requests will follow. +- +-10.10.2. C (Continue) Bit +- +- When set to 1, indicates that the text (set of key=value pairs) in +- this Text Request is not complete (it will be continued on subsequent +- Text Requests); otherwise, it indicates that this Text Request ends a +- set of key=value pairs. A Text Request with the C bit set to 1 MUST +- have the F bit set to 0. +- +-10.10.3. Initiator Task Tag +- +- The initiator assigned identifier for this Text Request. If the +- command is sent as part of a sequence of text requests and responses, +- the Initiator Task Tag MUST be the same for all the requests within +- the sequence (similar to linked SCSI commands). The I bit for all +- requests in a sequence also MUST be the same. +- +-10.10.4. Target Transfer Tag +- +- When the Target Transfer Tag is set to the reserved value 0xffffffff, +- it tells the target that this is a new request and the target resets +- any internal state associated with the Initiator Task Tag (resets the +- current negotiation state). +- +- The target sets the Target Transfer Tag in a text response to a value +- other than the reserved value 0xffffffff whenever it indicates that +- it has more data to send or more operations to perform that are +- associated with the specified Initiator Task Tag. It MUST do so +- whenever it sets the F bit to 0 in the response. By copying the +- Target Transfer Tag from the response to the next Text Request, the +- initiator tells the target to continue the operation for the specific +- Initiator Task Tag. The initiator MUST ignore the Target Transfer +- Tag in the Text Response when the F bit is set to 1. +- +- This mechanism allows the initiator and target to transfer a large +- amount of textual data over a sequence of text-command/text-response +- exchanges, or to perform extended negotiation sequences. +- +- If the Target Transfer Tag is not 0xffffffff, the LUN field MUST be +- sent by the target in the Text Response. +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 150] +- +-RFC 3720 iSCSI April 2004 +- +- +- A target MAY reset its internal negotiation state if an exchange is +- stalled by the initiator for a long time or if it is running out of +- resources. +- +- Long text responses are handled as in the following example: +- +- I->T Text SendTargets=All (F=1,TTT=0xffffffff) +- T->I Text (F=0,TTT=0x12345678) +- I->T Text (F=1, TTT=0x12345678) +- T->I Text (F=0, TTT=0x12345678) +- I->T Text (F=1, TTT=0x12345678) +- ... +- T->I Text (F=1, TTT=0xffffffff) +- +-10.10.5. Text +- +- The data lengths of a text request MUST NOT exceed the iSCSI target +- MaxRecvDataSegmentLength (a per connection and per direction +- negotiated parameter). The text format is specified in Section 5.2 +- Text Mode Negotiation. +- +- Chapter 11 and Chapter 12 list some basic Text key=value pairs, some +- of which can be used in Login Request/Response and some in Text +- Request/Response. +- +- A key=value pair can span Text request or response boundaries. A +- key=value pair can start in one PDU and continue on the next. In +- other words the end of a PDU does not necessarily signal the end of a +- key=value pair. +- +- The target responds by sending its response back to the initiator. +- The response text format is similar to the request text format. The +- text response MAY refer to key=value pairs presented in an earlier +- text request and the text in the request may refer to earlier +- responses. +- +- Chapter 5 details the rules for the Text Requests and Responses. +- +- Text operations are usually meant for parameter setting/ +- negotiations, but can also be used to perform some long lasting +- operations. +- +- Text operations that take a long time should be placed in their own +- Text request. +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 151] +- +-RFC 3720 iSCSI April 2004 +- +- +-10.11. Text Response +- +- The Text Response PDU contains the target's responses to the +- initiator's Text request. The format of the Text field matches that +- of the Text request. +- +- Byte/ 0 | 1 | 2 | 3 | +- / | | | | +- |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +- +---------------+---------------+---------------+---------------+ +- 0|.|.| 0x24 |F|C| Reserved | +- +---------------+---------------+---------------+---------------+ +- 4|TotalAHSLength | DataSegmentLength | +- +---------------+---------------+---------------+---------------+ +- 8| LUN or Reserved | +- + + +- 12| | +- +---------------+---------------+---------------+---------------+ +- 16| Initiator Task Tag | +- +---------------+---------------+---------------+---------------+ +- 20| Target Transfer Tag or 0xffffffff | +- +---------------+---------------+---------------+---------------+ +- 24| StatSN | +- +---------------+---------------+---------------+---------------+ +- 28| ExpCmdSN | +- +---------------+---------------+---------------+---------------+ +- 32| MaxCmdSN | +- +---------------+---------------+---------------+---------------+ +- 36/ Reserved / +- +/ / +- +---------------+---------------+---------------+---------------+ +- 48| Header-Digest (Optional) | +- +---------------+---------------+---------------+---------------+ +- / DataSegment (Text) / +- +/ / +- +---------------+---------------+---------------+---------------+ +- | Data-Digest (Optional) | +- +---------------+---------------+---------------+---------------+ +- +-10.11.1. F (Final) Bit +- +- When set to 1, in response to a Text Request with the Final bit set +- to 1, the F bit indicates that the target has finished the whole +- operation. Otherwise, if set to 0 in response to a Text Request with +- the Final Bit set to 1, it indicates that the target has more work to +- do (invites a follow-on text request). A Text Response with the F +- bit set to 1 in response to a Text Request with the F bit set to 0 is +- a protocol error. +- +- +- +-Satran, et al. Standards Track [Page 152] +- +-RFC 3720 iSCSI April 2004 +- +- +- A Text Response with the F bit set to 1 MUST NOT contain key=value +- pairs that may require additional answers from the initiator. +- +- A Text Response with the F bit set to 1 MUST have a Target Transfer +- Tag field set to the reserved value of 0xffffffff. +- +- A Text Response with the F bit set to 0 MUST have a Target Transfer +- Tag field set to a value other than the reserved 0xffffffff. +- +-10.11.2. C (Continue) Bit +- +- When set to 1, indicates that the text (set of key=value pairs) in +- this Text Response is not complete (it will be continued on +- subsequent Text Responses); otherwise, it indicates that this Text +- Response ends a set of key=value pairs. A Text Response with the C +- bit set to 1 MUST have the F bit set to 0. +- +-10.11.3. Initiator Task Tag +- +- The Initiator Task Tag matches the tag used in the initial Text +- Request. +- +-10.11.4. Target Transfer Tag +- +- When a target has more work to do (e.g., cannot transfer all the +- remaining text data in a single Text Response or has to continue the +- negotiation) and has enough resources to proceed, it MUST set the +- Target Transfer Tag to a value other than the reserved value of +- 0xffffffff. Otherwise, the Target Transfer Tag MUST be set to +- 0xffffffff. +- +- When the Target Transfer Tag is not 0xffffffff, the LUN field may be +- significant. +- +- The initiator MUST copy the Target Transfer Tag and LUN in its next +- request to indicate that it wants the rest of the data. +- +- When the target receives a Text Request with the Target Transfer Tag +- set to the reserved value of 0xffffffff, it resets its internal +- information (resets state) associated with the given Initiator Task +- Tag (restarts the negotiation). +- +- When a target cannot finish the operation in a single Text Response, +- and does not have enough resources to continue, it rejects the Text +- Request with the appropriate Reject code. +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 153] +- +-RFC 3720 iSCSI April 2004 +- +- +- A target may reset its internal state associated with an Initiator +- Task Tag (the current negotiation state), state expressed through the +- Target Transfer Tag if the initiator fails to continue the exchange +- for some time. The target may reject subsequent Text Requests with +- the Target Transfer Tag set to the "stale" value. +- +-10.11.5. StatSN +- +- The target StatSN variable is advanced by each Text Response sent. +- +-10.11.6. Text Response Data +- +- The data lengths of a text response MUST NOT exceed the iSCSI +- initiator MaxRecvDataSegmentLength (a per connection and per +- direction negotiated parameter). +- +- The text in the Text Response Data is governed by the same rules as +- the text in the Text Request Data (see Section 10.10.5 Text). +- +- Although the initiator is the requesting party and controls the +- request-response initiation and termination, the target can offer +- key=value pairs of its own as part of a sequence and not only in +- response to the initiator. +- +-10.12. Login Request +- +- After establishing a TCP connection between an initiator and a +- target, the initiator MUST start a Login Phase to gain further access +- to the target's resources. +- +- The Login Phase (see Chapter 5) consists of a sequence of Login +- Requests and Responses that carry the same Initiator Task Tag. +- +- Login Requests are always considered as immediate. +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 154] +- +-RFC 3720 iSCSI April 2004 +- +- +- Byte/ 0 | 1 | 2 | 3 | +- / | | | | +- |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +- +---------------+---------------+---------------+---------------+ +- 0|.|1| 0x03 |T|C|.|.|CSG|NSG| Version-max | Version-min | +- +---------------+---------------+---------------+---------------+ +- 4|TotalAHSLength | DataSegmentLength | +- +---------------+---------------+---------------+---------------+ +- 8| ISID | +- + +---------------+---------------+ +- 12| | TSIH | +- +---------------+---------------+---------------+---------------+ +- 16| Initiator Task Tag | +- +---------------+---------------+---------------+---------------+ +- 20| CID | Reserved | +- +---------------+---------------+---------------+---------------+ +- 24| CmdSN | +- +---------------+---------------+---------------+---------------+ +- 28| ExpStatSN or Reserved | +- +---------------+---------------+---------------+---------------+ +- 32| Reserved | +- +---------------+---------------+---------------+---------------+ +- 36| Reserved | +- +---------------+---------------+---------------+---------------+ +- 40/ Reserved / +- +/ / +- +---------------+---------------+---------------+---------------+ +- 48/ DataSegment - Login Parameters in Text request Format / +- +/ / +- +---------------+---------------+---------------+---------------+ +- +-10.12.1. T (Transit) Bit +- +- If set to 1, indicates that the initiator is ready to transit to the +- next stage. +- +- If the T bit is set to 1 and NSG is FullFeaturePhase, then this also +- indicates that the initiator is ready for the Final Login Response +- (see Chapter 5). +- +-10.12.2. C (Continue) Bit +- +- When set to 1, indicates that the text (set of key=value pairs) in +- this Login Request is not complete (it will be continued on +- subsequent Login Requests); otherwise, it indicates that this Login +- Request ends a set of key=value pairs. A Login Request with the C +- bit set to 1 MUST have the T bit set to 0. +- +- +- +- +-Satran, et al. Standards Track [Page 155] +- +-RFC 3720 iSCSI April 2004 +- +- +-10.12.3. CSG and NSG +- +- Through these fields, Current Stage (CSG) and Next Stage (NSG), the +- Login negotiation requests and responses are associated with a +- specific stage in the session (SecurityNegotiation, +- LoginOperationalNegotiation, FullFeaturePhase) and may indicate the +- next stage to which they want to move (see Chapter 5). The next +- stage value is only valid when the T bit is 1; otherwise, it is +- reserved. +- +- The stage codes are: +- +- - 0 - SecurityNegotiation +- - 1 - LoginOperationalNegotiation +- - 3 - FullFeaturePhase +- +- All other codes are reserved. +- +-10.12.4. Version +- +- The version number of the current draft is 0x00. As such, all +- devices MUST carry version 0x00 for both Version-min and Version-max. +- +-10.12.4.1. Version-max +- +- Maximum Version number supported. +- +- All Login Requests within the Login Phase MUST carry the same +- Version-max. +- +- The target MUST use the value presented with the first Login Request. +- +-10.12.4.2. Version-min +- +- All Login Requests within the Login Phase MUST carry the same +- Version-min. The target MUST use the value presented with the first +- Login Request. +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 156] +- +-RFC 3720 iSCSI April 2004 +- +- +-10.12.5. ISID +- +- This is an initiator-defined component of the session identifier and +- is structured as follows (see [RFC3721] and Section 9.1.1 +- Conservative Reuse of ISIDs for details): +- +- Byte/ 0 | 1 | 2 | 3 | +- / | | | | +- |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +- +---------------+---------------+---------------+---------------+ +- 8| T | A | B | C | +- +---------------+---------------+---------------+---------------+ +- 12| D | +- +---------------+---------------+ +- +- The T field identifies the format and usage of A, B, C, and D as +- indicated below: +- +- T +- +- 00b OUI-Format +- A&B are a 22 bit OUI +- (the I/G & U/L bits are omitted) +- C&D 24 bit qualifier +- 01b EN - Format (IANA Enterprise Number) +- A - Reserved +- B&C EN (IANA Enterprise Number) +- D - Qualifier +- 10b "Random" +- A - Reserved +- B&C Random +- D - Qualifier +- 11b A,B,C&D Reserved +- +- For the T field values 00b and 01b, a combination of A and B (for +- 00b) or B and C (for 01b) identifies the vendor or organization whose +- component (software or hardware) generates this ISID. A vendor or +- organization with one or more OUIs, or one or more Enterprise +- Numbers, MUST use at least one of these numbers and select the +- appropriate value for the T field when its components generate ISIDs. +- An OUI or EN MUST be set in the corresponding fields in network byte +- order (byte big-endian). +- +- If the T field is 10b, B and C are set to a random 24-bit unsigned +- integer value in network byte order (byte big-endian). See [RFC3721] +- for how this affects the principle of "conservative reuse". +- +- +- +- +- +-Satran, et al. Standards Track [Page 157] +- +-RFC 3720 iSCSI April 2004 +- +- +- The Qualifier field is a 16 or 24-bit unsigned integer value that +- provides a range of possible values for the ISID within the selected +- namespace. It may be set to any value within the constraints +- specified in the iSCSI protocol (see Section 3.4.3 Consequences of +- the Model and Section 9.1.1 Conservative Reuse of ISIDs). +- +- The T field value of 11b is reserved. +- +- If the ISID is derived from something assigned to a hardware adapter +- or interface by a vendor, as a preset default value, it MUST be +- configurable to a value assigned according to the SCSI port behavior +- desired by the system in which it is installed (see Section 9.1.1 +- Conservative Reuse of ISIDs and Section 9.1.2 iSCSI Name, ISID, and +- TPGT Use). The resultant ISID MUST also be persistent over power +- cycles, reboot, card swap, etc. +- +-10.12.6. TSIH +- +- TSIH must be set in the first Login Request. The reserved value 0 +- MUST be used on the first connection for a new session. Otherwise, +- the TSIH sent by the target at the conclusion of the successful login +- of the first connection for this session MUST be used. The TSIH +- identifies to the target the associated existing session for this new +- connection. +- +- All Login Requests within a Login Phase MUST carry the same TSIH. +- +- The target MUST check the value presented with the first Login +- Request and act as specified in Section 5.3.1 Login Phase Start. +- +-10.12.7. Connection ID - CID +- +- A unique ID for this connection within the session. +- +- All Login Requests within the Login Phase MUST carry the same CID. +- +- The target MUST use the value presented with the first Login Request. +- +- A Login Request with a non-zero TSIH and a CID equal to that of an +- existing connection implies a logout of the connection followed by a +- Login (see Section 5.3.4 Connection Reinstatement). For the details +- of the implicit Logout Request, see Section 10.14 Logout Request. +- +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 158] +- +-RFC 3720 iSCSI April 2004 +- +- +-10.12.8. CmdSN +- +- CmdSN is either the initial command sequence number of a session (for +- the first Login Request of a session - the "leading" login), or the +- command sequence number in the command stream if the login is for a +- new connection in an existing session. +- +- Examples: +- +- - Login on a leading connection - if the leading login carries +- the CmdSN 123, all other Login Requests in the same Login Phase +- carry the CmdSN 123 and the first non-immediate command in +- FullFeaturePhase also carries the CmdSN 123. +- +- - Login on other than a leading connection - if the current CmdSN +- at the time the first login on the connection is issued is 500, +- then that PDU carries CmdSN=500. Subsequent Login Requests +- that are needed to complete this Login Phase may carry a CmdSN +- higher than 500 if non-immediate requests that were issued on +- other connections in the same session advance CmdSN. +- +- If the Login Request is a leading Login Request, the target MUST use +- the value presented in CmdSN as the target value for ExpCmdSN. +- +-10.12.9. ExpStatSN +- +- For the first Login Request on a connection this is ExpStatSN for the +- old connection and this field is only valid if the Login Request +- restarts a connection (see Section 5.3.4 Connection Reinstatement). +- +- For subsequent Login Requests it is used to acknowledge the Login +- Responses with their increasing StatSN values. +- +-10.12.10. Login Parameters +- +- The initiator MUST provide some basic parameters in order to enable +- the target to determine if the initiator may use the target's +- resources and the initial text parameters for the security exchange. +- +- All the rules specified in Section 10.10.5 Text for text requests +- also hold for Login Requests. Keys and their explanations are listed +- in Chapter 11 (security negotiation keys) and Chapter 12 (operational +- parameter negotiation keys). All keys in Chapter 12, except for the +- X extension formats, MUST be supported by iSCSI initiators and +- targets. Keys in Chapter 11 only need to be supported when the +- function to which they refer is mandatory to implement. +- +- +- +- +- +-Satran, et al. Standards Track [Page 159] +- +-RFC 3720 iSCSI April 2004 +- +- +-10.13. Login Response +- +- The Login Response indicates the progress and/or end of the Login +- Phase. +- +- Byte/ 0 | 1 | 2 | 3 | +- / | | | | +- |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +- +---------------+---------------+---------------+---------------+ +- 0|.|.| 0x23 |T|C|.|.|CSG|NSG| Version-max | Version-active| +- +---------------+---------------+---------------+---------------+ +- 4|TotalAHSLength | DataSegmentLength | +- +---------------+---------------+---------------+---------------+ +- 8| ISID | +- + +---------------+---------------+ +- 12| | TSIH | +- +---------------+---------------+---------------+---------------+ +- 16| Initiator Task Tag | +- +---------------+---------------+---------------+---------------+ +- 20| Reserved | +- +---------------+---------------+---------------+---------------+ +- 24| StatSN | +- +---------------+---------------+---------------+---------------+ +- 28| ExpCmdSN | +- +---------------+---------------+---------------+---------------+ +- 32| MaxCmdSN | +- +---------------+---------------+---------------+---------------+ +- 36| Status-Class | Status-Detail | Reserved | +- +---------------+---------------+---------------+---------------+ +- 40/ Reserved / +- +/ / +- +---------------+---------------+---------------+---------------+ +- 48/ DataSegment - Login Parameters in Text request Format / +- +/ / +- +---------------+---------------+---------------+---------------+ +- +-10.13.1. Version-max +- +- This is the highest version number supported by the target. +- +- All Login Responses within the Login Phase MUST carry the same +- Version-max. +- +- The initiator MUST use the value presented as a response to the first +- Login Request. +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 160] +- +-RFC 3720 iSCSI April 2004 +- +- +-10.13.2. Version-active +- +- Indicates the highest version supported by the target and initiator. +- If the target does not support a version within the range specified +- by the initiator, the target rejects the login and this field +- indicates the lowest version supported by the target. +- +- All Login Responses within the Login Phase MUST carry the same +- Version-active. +- +- The initiator MUST use the value presented as a response to the first +- Login Request. +- +-10.13.3. TSIH +- +- The TSIH is the target assigned session identifying handle. Its +- internal format and content are not defined by this protocol except +- for the value 0 that is reserved. With the exception of the Login +- Final-Response in a new session, this field should be set to the TSIH +- provided by the initiator in the Login Request. For a new session, +- the target MUST generate a non-zero TSIH and ONLY return it in the +- Login Final-Response (see Section 5.3 Login Phase). +- +-10.13.4. StatSN +- +- For the first Login Response (the response to the first Login +- Request), this is the starting status Sequence Number for the +- connection. The next response of any kind, including the next Login +- Response, if any, in the same Login Phase, will carry this number + +- 1. This field is only valid if the Status-Class is 0. +- +-10.13.5. Status-Class and Status-Detail +- +- The Status returned in a Login Response indicates the execution +- status of the Login Phase. The status includes: +- +- Status-Class +- Status-Detail +- +- 0 Status-Class indicates success. +- +- A non-zero Status-Class indicates an exception. In this case, +- Status-Class is sufficient for a simple initiator to use when +- handling exceptions, without having to look at the Status-Detail. +- The Status-Detail allows finer-grained exception handling for more +- sophisticated initiators and for better information for logging. +- +- +- +- +- +-Satran, et al. Standards Track [Page 161] +- +-RFC 3720 iSCSI April 2004 +- +- +- The status classes are as follows: +- +- 0 - Success - indicates that the iSCSI target successfully +- received, understood, and accepted the request. The numbering +- fields (StatSN, ExpCmdSN, MaxCmdSN) are only valid if +- Status-Class is 0. +- +- 1 - Redirection - indicates that the initiator must take further +- action to complete the request. This is usually due to the +- target moving to a different address. All of the redirection +- status class responses MUST return one or more text key +- parameters of the type "TargetAddress", which indicates the +- target's new address. A redirection response MAY be issued by +- a target prior or after completing a security negotiation if a +- security negotiation is required. A redirection SHOULD be +- accepted by an initiator even without having the target +- complete a security negotiation if any security negotiation is +- required, and MUST be accepted by the initiator after the +- completion of the security negotiation if any security +- negotiation is required. +- +- 2 - Initiator Error (not a format error) - indicates that the +- initiator most likely caused the error. This MAY be due to a +- request for a resource for which the initiator does not have +- permission. The request should not be tried again. +- +- 3 - Target Error - indicates that the target sees no errors in the +- initiator's Login Request, but is currently incapable of +- fulfilling the request. The initiator may re-try the same +- Login Request later. +- +- The table below shows all of the currently allocated status codes. +- The codes are in hexadecimal; the first byte is the status class and +- the second byte is the status detail. +- +- ----------------------------------------------------------------- +- Status | Code | Description +- |(hex) | +- ----------------------------------------------------------------- +- Success | 0000 | Login is proceeding OK (*1). +- ----------------------------------------------------------------- +- Target moved | 0101 | The requested iSCSI Target Name (ITN) +- temporarily | | has temporarily moved +- | | to the address provided. +- ----------------------------------------------------------------- +- Target moved | 0102 | The requested ITN has permanently moved +- permanently | | to the address provided. +- ----------------------------------------------------------------- +- +- +- +-Satran, et al. Standards Track [Page 162] +- +-RFC 3720 iSCSI April 2004 +- +- +- Initiator | 0200 | Miscellaneous iSCSI initiator +- error | | errors. +- ---------------------------------------------------------------- +- Authentication| 0201 | The initiator could not be +- failure | | successfully authenticated or target +- | | authentication is not supported. +- ----------------------------------------------------------------- +- Authorization | 0202 | The initiator is not allowed access +- failure | | to the given target. +- ----------------------------------------------------------------- +- Not found | 0203 | The requested ITN does not +- | | exist at this address. +- ----------------------------------------------------------------- +- Target removed| 0204 | The requested ITN has been removed and +- | |no forwarding address is provided. +- ----------------------------------------------------------------- +- Unsupported | 0205 | The requested iSCSI version range is +- version | | not supported by the target. +- ----------------------------------------------------------------- +- Too many | 0206 | Too many connections on this SSID. +- connections | | +- ----------------------------------------------------------------- +- Missing | 0207 | Missing parameters (e.g., iSCSI +- parameter | | Initiator and/or Target Name). +- ----------------------------------------------------------------- +- Can't include | 0208 | Target does not support session +- in session | | spanning to this connection (address). +- ----------------------------------------------------------------- +- Session type | 0209 | Target does not support this type of +- not supported | | of session or not from this Initiator. +- ----------------------------------------------------------------- +- Session does | 020a | Attempt to add a connection +- not exist | | to a non-existent session. +- ----------------------------------------------------------------- +- Invalid during| 020b | Invalid Request type during Login. +- login | | +- ----------------------------------------------------------------- +- Target error | 0300 | Target hardware or software error. +- ----------------------------------------------------------------- +- Service | 0301 | The iSCSI service or target is not +- unavailable | | currently operational. +- ----------------------------------------------------------------- +- Out of | 0302 | The target has insufficient session, +- resources | | connection, or other resources. +- ----------------------------------------------------------------- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 163] +- +-RFC 3720 iSCSI April 2004 +- +- +- (*1) If the response T bit is 1 in both the request and the matching +- response, and the NSG is FullFeaturePhase in both the request and the +- matching response, the Login Phase is finished and the initiator may +- proceed to issue SCSI commands. +- +- If the Status Class is not 0, the initiator and target MUST close the +- TCP connection. +- +- If the target wishes to reject the Login Request for more than one +- reason, it should return the primary reason for the rejection. +- +-10.13.6. T (Transit) bit +- +- The T bit is set to 1 as an indicator of the end of the stage. If +- the T bit is set to 1 and NSG is FullFeaturePhase, then this is also +- the Final Login Response (see Chapter 5). A T bit of 0 indicates a +- "partial" response, which means "more negotiation needed". +- +- A Login Response with a T bit set to 1 MUST NOT contain key=value +- pairs that may require additional answers from the initiator within +- the same stage. +- +- If the status class is 0, the T bit MUST NOT be set to 1 if the T bit +- in the request was set to 0. +- +-10.13.7. C (Continue) Bit +- +- When set to 1, indicates that the text (set of key=value pairs) in +- this Login Response is not complete (it will be continued on +- subsequent Login Responses); otherwise, it indicates that this Login +- Response ends a set of key=value pairs. A Login Response with the C +- bit set to 1 MUST have the T bit set to 0. +- +-10.13.8. Login Parameters +- +- The target MUST provide some basic parameters in order to enable the +- initiator to determine if it is connected to the correct port and the +- initial text parameters for the security exchange. +- +- All the rules specified in Section 10.11.6 Text Response Data for +- text responses also hold for Login Responses. Keys and their +- explanations are listed in Chapter 11 (security negotiation keys) and +- Chapter 12 (operational parameter negotiation keys). All keys in +- Chapter 12, except for the X extension formats, MUST be supported by +- iSCSI initiators and targets. Keys in Chapter 11, only need to be +- supported when the function to which they refer is mandatory to +- implement. +- +- +- +- +-Satran, et al. Standards Track [Page 164] +- +-RFC 3720 iSCSI April 2004 +- +- +-10.14. Logout Request +- +- The Logout Request is used to perform a controlled closing of a +- connection. +- +- An initiator MAY use a Logout Request to remove a connection from a +- session or to close an entire session. +- +- After sending the Logout Request PDU, an initiator MUST NOT send any +- new iSCSI requests on the closing connection. If the Logout Request +- is intended to close the session, new iSCSI requests MUST NOT be sent +- on any of the connections participating in the session. +- +- When receiving a Logout Request with the reason code of "close the +- connection" or "close the session", the target MUST terminate all +- pending commands, whether acknowledged via ExpCmdSN or not, on that +- connection or session respectively. +- +- When receiving a Logout Request with the reason code "remove +- connection for recovery", the target MUST discard all requests not +- yet acknowledged via ExpCmdSN that were issued on the specified +- connection, and suspend all data/status/R2T transfers on behalf of +- pending commands on the specified connection. +- +- The target then issues the Logout Response and half-closes the TCP +- connection (sends FIN). After receiving the Logout Response and +- attempting to receive the FIN (if still possible), the initiator MUST +- completely close the logging-out connection. For the terminated +- commands, no additional responses should be expected. +- +- A Logout for a CID may be performed on a different transport +- connection when the TCP connection for the CID has already been +- terminated. In such a case, only a logical "closing" of the iSCSI +- connection for the CID is implied with a Logout. +- +- All commands that were not terminated or not completed (with status) +- and acknowledged when the connection is closed completely can be +- reassigned to a new connection if the target supports connection +- recovery. +- +- If an initiator intends to start recovery for a failing connection, +- it MUST use the Logout Request to "clean-up" the target end of a +- failing connection and enable recovery to start, or the Login Request +- with a non-zero TSIH and the same CID on a new connection for the +- same effect (see Section 10.14.3 CID). In sessions with a single +- connection, the connection can be closed and then a new connection +- reopened. A connection reinstatement login can be used for recovery +- (see Section 5.3.4 Connection Reinstatement). +- +- +- +-Satran, et al. Standards Track [Page 165] +- +-RFC 3720 iSCSI April 2004 +- +- +- A successful completion of a Logout Request with the reason code of +- "close the connection" or "remove the connection for recovery" +- results at the target in the discarding of unacknowledged commands +- received on the connection being logged out. These are commands that +- have arrived on the connection being logged out, but have not been +- delivered to SCSI because one or more commands with a smaller CmdSN +- has not been received by iSCSI. See Section 3.2.2.1 Command +- Numbering and Acknowledging. The resulting holes the in command +- sequence numbers will have to be handled by appropriate recovery (see +- Chapter 6) unless the session is also closed. +- +- The entire logout discussion in this section is also applicable for +- an implicit Logout realized via a connection reinstatement or session +- reinstatement. When a Login Request performs an implicit Logout, the +- implicit Logout is performed as if having the reason codes specified +- below: +- +- Reason code Type of implicit Logout +- ------------------------------------------- +- 0 session reinstatement +- 1 connection reinstatement when +- the operational ErrorRecoveryLevel < 2 +- 2 connection reinstatement when +- the operational ErrorRecoveryLevel = 2 +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 166] +- +-RFC 3720 iSCSI April 2004 +- +- +- Byte/ 0 | 1 | 2 | 3 | +- / | | | | +- |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +- +---------------+---------------+---------------+---------------+ +- 0|.|I| 0x06 |1| Reason Code | Reserved | +- +---------------+---------------+---------------+---------------+ +- 4|TotalAHSLength | DataSegmentLength | +- +---------------------------------------------------------------+ +- 8/ Reserved / +- +/ / +- +---------------+---------------+---------------+---------------+ +- 16| Initiator Task Tag | +- +---------------+---------------+---------------+---------------+ +- 20| CID or Reserved | Reserved | +- +---------------+---------------+---------------+---------------+ +- 24| CmdSN | +- +---------------+---------------+---------------+---------------+ +- 28| ExpStatSN | +- +---------------+---------------+---------------+---------------+ +- 32/ Reserved / +- +/ / +- +---------------+---------------+---------------+---------------+ +- 48| Header-Digest (Optional) | +- +---------------+---------------+---------------+---------------+ +- +-10.14.1. Reason Code +- +- Reason Code indicates the reason for Logout as follows: +- +- 0 - close the session. All commands associated with the session +- (if any) are terminated. +- +- 1 - close the connection. All commands associated with connection +- (if any) are terminated. +- +- 2 - remove the connection for recovery. Connection is closed and +- all commands associated with it, if any, are to be prepared +- for a new allegiance. +- +- All other values are reserved. +- +- +- +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 167] +- +-RFC 3720 iSCSI April 2004 +- +- +-10.14.2. TotalAHSLength and DataSegmentLength +- +- For this PDU TotalAHSLength and DataSegmentLength MUST be 0. +- +-10.14.3. CID +- +- This is the connection ID of the connection to be closed (including +- closing the TCP stream). This field is only valid if the reason code +- is not "close the session". +- +-10.14.4. ExpStatSN +- +- This is the last ExpStatSN value for the connection to be closed. +- +-10.14.5. Implicit termination of tasks +- +- A target implicitly terminates the active tasks due to the iSCSI +- protocol in the following cases: +- +- a) When a connection is implicitly or explicitly logged out with +- the reason code of "Close the connection" and there are active +- tasks allegiant to that connection. +- +- b) When a connection fails and eventually the connection state +- times out (state transition M1 in Section 7.2.2 State +- Transition Descriptions for Initiators and Targets) and there +- are active tasks allegiant to that connection. +- +- c) When a successful recovery Logout is performed while there are +- active tasks allegiant to that connection, and those tasks +- eventually time out after the Time2Wait and Time2Retain +- periods without allegiance reassignment. +- +- d) When a connection is implicitly or explicitly logged out with +- the reason code of "Close the session" and there are active +- tasks in that session. +- +- If the tasks terminated in any of the above cases are SCSI tasks, +- they must be internally terminated as if with CHECK CONDITION status. +- This status is only meaningful for appropriately handling the +- internal SCSI state and SCSI side effects with respect to ordering +- because this status is never communicated back as a terminating +- status to the initiator. However additional actions may have to be +- taken at SCSI level depending on the SCSI context as defined by the +- SCSI standards (e.g., queued commands and ACA, in cases a), b), and +- c), after the tasks are terminated, the target MUST report a Unit +- Attention condition on the next command processed on any connection +- for each affected I_T_L nexus with the status of CHECK CONDITION, and +- +- +- +-Satran, et al. Standards Track [Page 168] +- +-RFC 3720 iSCSI April 2004 +- +- +- the ASC/ASCQ value of 47h/7Fh - "SOME COMMANDS CLEARED BY ISCSI +- PROTOCOL EVENT" - etc. - see [SAM2] and [SPC3]). +- +-10.15. Logout Response +- +- The Logout Response is used by the target to indicate if the cleanup +- operation for the connection(s) has completed. +- +- After Logout, the TCP connection referred by the CID MUST be closed +- at both ends (or all connections must be closed if the logout reason +- was session close). +- +- Byte/ 0 | 1 | 2 | 3 | +- / | | | | +- |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +- +---------------+---------------+---------------+---------------+ +- 0|.|.| 0x26 |1| Reserved | Response | Reserved | +- +---------------+---------------+---------------+---------------+ +- 4|TotalAHSLength | DataSegmentLength | +- +---------------------------------------------------------------+ +- 8/ Reserved / +- +/ / +- +---------------+---------------+---------------+---------------+ +- 16| Initiator Task Tag | +- +---------------+---------------+---------------+---------------+ +- 20| Reserved | +- +---------------+---------------+---------------+---------------+ +- 24| StatSN | +- +---------------+---------------+---------------+---------------+ +- 28| ExpCmdSN | +- +---------------+---------------+---------------+---------------+ +- 32| MaxCmdSN | +- +---------------+---------------+---------------+---------------+ +- 36| Reserved | +- +---------------------------------------------------------------+ +- 40| Time2Wait | Time2Retain | +- +---------------+---------------+---------------+---------------+ +- 44| Reserved | +- +---------------+---------------+---------------+---------------+ +- 48| Header-Digest (Optional) | +- +---------------+---------------+---------------+---------------+ +- +- +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 169] +- +-RFC 3720 iSCSI April 2004 +- +- +-10.15.1. Response +- +- Logout Response: +- +- 0 - connection or session closed successfully. +- +- 1 - CID not found. +- +- 2 - connection recovery is not supported. If Logout reason code +- was recovery and target does not support it as indicated by the +- ErrorRecoveryLevel. +- +- 3 - cleanup failed for various reasons. +- +-10.15.2. TotalAHSLength and DataSegmentLength +- +- For this PDU TotalAHSLength and DataSegmentLength MUST be 0. +- +-10.15.3. Time2Wait +- +- If the Logout Response code is 0 and if the operational +- ErrorRecoveryLevel is 2, this is the minimum amount of time, in +- seconds, to wait before attempting task reassignment. If the Logout +- Response code is 0 and if the operational ErrorRecoveryLevel is less +- than 2, this field is to be ignored. +- +- This field is invalid if the Logout Response code is 1. +- +- If the Logout response code is 2 or 3, this field specifies the +- minimum time to wait before attempting a new implicit or explicit +- logout. +- +- If Time2Wait is 0, the reassignment or a new Logout may be attempted +- immediately. +- +-10.15.4. Time2Retain +- +- If the Logout response code is 0 and if the operational +- ErrorRecoveryLevel is 2, this is the maximum amount of time, in +- seconds, after the initial wait (Time2Wait), the target waits for the +- allegiance reassignment for any active task after which the task +- state is discarded. If the Logout response code is 0 and if the +- operational ErrorRecoveryLevel is less than 2, this field is to be +- ignored. +- +- This field is invalid if the Logout response code is 1. +- +- +- +- +- +-Satran, et al. Standards Track [Page 170] +- +-RFC 3720 iSCSI April 2004 +- +- +- If the Logout response code is 2 or 3, this field specifies the +- maximum amount of time, in seconds, after the initial wait +- (Time2Wait), the target waits for a new implicit or explicit logout. +- +- If it is the last connection of a session, the whole session state is +- discarded after Time2Retain. +- +- If Time2Retain is 0, the target has already discarded the connection +- (and possibly the session) state along with the task states. No +- reassignment or Logout is required in this case. +- +-10.16. SNACK Request +- +- Byte/ 0 | 1 | 2 | 3 | +- / | | | | +- |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +- +---------------+---------------+---------------+---------------+ +- 0|.|.| 0x10 |1|.|.|.| Type | Reserved | +- +---------------+---------------+---------------+---------------+ +- 4|TotalAHSLength | DataSegmentLength | +- +---------------+---------------+---------------+---------------+ +- 8| LUN or Reserved | +- + + +- 12| | +- +---------------+---------------+---------------+---------------+ +- 16| Initiator Task Tag or 0xffffffff | +- +---------------+---------------+---------------+---------------+ +- 20| Target Transfer Tag or SNACK Tag or 0xffffffff | +- +---------------+---------------+---------------+---------------+ +- 24| Reserved | +- +---------------+---------------+---------------+---------------+ +- 28| ExpStatSN | +- +---------------+---------------+---------------+---------------+ +- 32/ Reserved / +- +/ / +- +---------------+---------------+---------------+---------------+ +- 40| BegRun | +- +---------------------------------------------------------------+ +- 44| RunLength | +- +---------------------------------------------------------------+ +- 48| Header-Digest (Optional) | +- +---------------+---------------+---------------+---------------+ +- +- If the implementation supports ErrorRecoveryLevel greater than zero, +- it MUST support all SNACK types. +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 171] +- +-RFC 3720 iSCSI April 2004 +- +- +- The SNACK is used by the initiator to request the retransmission of +- numbered-responses, data, or R2T PDUs from the target. The SNACK +- request indicates the numbered-responses or data "runs" whose +- retransmission is requested by the target, where the run starts with +- the first StatSN, DataSN, or R2TSN whose retransmission is requested +- and indicates the number of Status, Data, or R2T PDUs requested +- including the first. 0 has special meaning when used as a starting +- number and length: +- +- - When used in RunLength, it means all PDUs starting with the +- initial. +- - When used in both BegRun and RunLength, it means all +- unacknowledged PDUs. +- +- The numbered-response(s) or R2T(s), requested by a SNACK, MUST be +- delivered as exact replicas of the ones that the target transmitted +- originally except for the fields ExpCmdSN, MaxCmdSN, and ExpDataSN, +- which MUST carry the current values. R2T(s)requested by SNACK MUST +- also carry the current value of StatSN. +- +- The numbered Data-In PDUs, requested by a Data SNACK MUST be +- delivered as exact replicas of the ones that the target transmitted +- originally except for the fields ExpCmdSN and MaxCmdSN, which MUST +- carry the current values and except for resegmentation (see Section +- 10.16.3 Resegmentation). +- +- Any SNACK that requests a numbered-response, Data, or R2T that was +- not sent by the target or was already acknowledged by the initiator, +- MUST be rejected with a reason code of "Protocol error". +- +-10.16.1. Type +- +- This field encodes the SNACK function as follows: +- +- 0-Data/R2T SNACK - requesting retransmission of one or more Data- +- In or R2T PDUs. +- +- 1-Status SNACK - requesting retransmission of one or more numbered +- responses. +- +- 2-DataACK - positively acknowledges Data-In PDUs. +- +- 3-R-Data SNACK - requesting retransmission of Data-In PDUs with +- possible resegmentation and status tagging. +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 172] +- +-RFC 3720 iSCSI April 2004 +- +- +- All other values are reserved. +- +- Data/R2T SNACK, Status SNACK, or R-Data SNACK for a command MUST +- precede status acknowledgement for the given command. +- +-10.16.2. Data Acknowledgement +- +- If an initiator operates at ErrorRecoveryLevel 1 or higher, it MUST +- issue a SNACK of type DataACK after receiving a Data-In PDU with the +- A bit set to 1. However, if the initiator has detected holes in the +- input sequence, it MUST postpone issuing the SNACK of type DataACK +- until the holes are filled. An initiator MAY ignore the A bit if it +- deems that the bit is being set aggressively by the target (i.e., +- before the MaxBurstLength limit is reached). +- +- The DataACK is used to free resources at the target and not to +- request or imply data retransmission. +- +- An initiator MUST NOT request retransmission for any data it had +- already acknowledged. +- +-10.16.3. Resegmentation +- +- If the initiator MaxRecvDataSegmentLength changed between the +- original transmission and the time the initiator requests +- retransmission, the initiator MUST issue a R-Data SNACK (see Section +- 10.16.1 Type). With R-Data SNACK, the initiator indicates that it +- discards all the unacknowledged data and expects the target to resend +- it. It also expects resegmentation. In this case, the retransmitted +- Data-In PDUs MAY be different from the ones originally sent in order +- to reflect changes in MaxRecvDataSegmentLength. Their DataSN starts +- with the BegRun of the last DataACK received by the target if any was +- received; otherwise it starts with 0 and is increased by 1 for each +- resent Data-In PDU. +- +- A target that has received a R-Data SNACK MUST return a SCSI Response +- that contains a copy of the SNACK Tag field from the R-Data SNACK in +- the SCSI Response SNACK Tag field as its last or only Response. For +- example, if it has already sent a response containing another value +- in the SNACK Tag field or had the status included in the last Data-In +- PDU, it must send a new SCSI Response PDU. If a target sends more +- than one SCSI Response PDU due to this rule, all SCSI responses must +- carry the same StatSN (see Section 10.4.4 SNACK Tag). If an +- initiator attempts to recover a lost SCSI Response (with a +- Status SNACK, see Section 10.16.1 Type) when more than one response +- has been sent, the target will send the SCSI Response with the latest +- content known to the target, including the last SNACK Tag for the +- command. +- +- +- +-Satran, et al. Standards Track [Page 173] +- +-RFC 3720 iSCSI April 2004 +- +- +- For considerations in allegiance reassignment of a task to a +- connection with a different MaxRecvDataSegmentLength, refer to +- Section 6.2.2 Allegiance Reassignment. +- +-10.16.4. Initiator Task Tag +- +- For Status SNACK and DataACK, the Initiator Task Tag MUST be set to +- the reserved value 0xffffffff. In all other cases, the Initiator +- Task Tag field MUST be set to the Initiator Task Tag of the +- referenced command. +- +-10.16.5. Target Transfer Tag or SNACK Tag +- +- For an R-Data SNACK, this field MUST contain a value that is +- different from 0 or 0xffffffff and is unique for the task (identified +- by the Initiator Task Tag). This value MUST be copied by the iSCSI +- target in the last or only SCSI Response PDU it issues for the +- command. +- +- For DataACK, the Target Transfer Tag MUST contain a copy of the +- Target Transfer Tag and LUN provided with the SCSI Data-In PDU with +- the A bit set to 1. +- +- In all other cases, the Target Transfer Tag field MUST be set to the +- reserved value of 0xffffffff. +- +-10.16.6. BegRun +- +- The DataSN, R2TSN, or StatSN of the first PDU whose retransmission is +- requested (Data/R2T and Status SNACK), or the next expected DataSN +- (DataACK SNACK). +- +- BegRun 0 when used in conjunction with RunLength 0 means resend all +- unacknowledged Data-In, R2T or Response PDUs. +- +- BegRun MUST be 0 for a R-Data SNACK. +- +-10.16.7. RunLength +- +- The number of PDUs whose retransmission is requested. +- +- RunLength 0 signals that all Data-In, R2T, or Response PDUs carrying +- the numbers equal to or greater than BegRun have to be resent. +- +- The RunLength MUST also be 0 for a DataACK SNACK in addition to +- R-Data SNACK. +- +- +- +- +- +-Satran, et al. Standards Track [Page 174] +- +-RFC 3720 iSCSI April 2004 +- +- +-10.17. Reject +- +- Byte/ 0 | 1 | 2 | 3 | +- / | | | | +- |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +- +---------------+---------------+---------------+---------------+ +- 0|.|.| 0x3f |1| Reserved | Reason | Reserved | +- +---------------+---------------+---------------+---------------+ +- 4|TotalAHSLength | DataSegmentLength | +- +---------------+---------------+---------------+---------------+ +- 8/ Reserved / +- +/ / +- +---------------+---------------+---------------+---------------+ +- 16| 0xffffffff | +- +---------------+---------------+---------------+---------------+ +- 20| Reserved | +- +---------------+---------------+---------------+---------------+ +- 24| StatSN | +- +---------------+---------------+---------------+---------------+ +- 28| ExpCmdSN | +- +---------------+---------------+---------------+---------------+ +- 32| MaxCmdSN | +- +---------------+---------------+---------------+---------------+ +- 36| DataSN/R2TSN or Reserved | +- +---------------+---------------+---------------+---------------+ +- 40| Reserved | +- +---------------+---------------+---------------+---------------+ +- 44| Reserved | +- +---------------+---------------+---------------+---------------+ +- 48| Header-Digest (Optional) | +- +---------------+---------------+---------------+---------------+ +- xx/ Complete Header of Bad PDU / +- +/ / +- +---------------+---------------+---------------+---------------+ +- yy/Vendor specific data (if any) / +- / / +- +---------------+---------------+---------------+---------------+ +- zz| Data-Digest (Optional) | +- +---------------+---------------+---------------+---------------+ +- +- Reject is used to indicate an iSCSI error condition (protocol, +- unsupported option, etc.). +- +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 175] +- +-RFC 3720 iSCSI April 2004 +- +- +-10.17.1. Reason +- +- The reject Reason is coded as follows: +- +- +------+----------------------------------------+------------------+ +- | Code | Explanation | Can the original | +- | (hex)| | PDU be re-sent? | +- +------+----------------------------------------+------------------+ +- | 0x01 | Reserved | no | +- | | | | +- | 0x02 | Data (payload) Digest Error | yes (Note 1) | +- | | | | +- | 0x03 | SNACK Reject | yes | +- | | | | +- | 0x04 | Protocol Error (e.g., SNACK request for| no | +- | | a status that was already acknowledged)| | +- | | | | +- | 0x05 | Command not supported | no | +- | | | | +- | 0x06 | Immediate Command Reject - too many | yes | +- | | immediate commands | | +- | | | | +- | 0x07 | Task in progress | no | +- | | | | +- | 0x08 | Invalid Data ACK | no | +- | | | | +- | 0x09 | Invalid PDU field | no (Note 2) | +- | | | | +- | 0x0a | Long Operation Reject - Can't generate | yes | +- | | Target Transfer Tag - out of resources | | +- | | | | +- | 0x0b | Negotiation Reset | no | +- | | | | +- | 0x0c | Waiting for Logout | no | +- +------+----------------------------------------+------------------+ +- +- Note 1: For iSCSI, Data-Out PDU retransmission is only done if the +- target requests retransmission with a recovery R2T. However, if this +- is the data digest error on immediate data, the initiator may choose +- to retransmit the whole PDU including the immediate data. +- +- Note 2: A target should use this reason code for all invalid values +- of PDU fields that are meant to describe a task, a response, or a +- data transfer. Some examples are invalid TTT/ITT, buffer offset, LUN +- qualifying a TTT, and an invalid sequence number in a SNACK. +- +- All other values for Reason are reserved. +- +- +- +- +-Satran, et al. Standards Track [Page 176] +- +-RFC 3720 iSCSI April 2004 +- +- +- In all the cases in which a pre-instantiated SCSI task is terminated +- because of the reject, the target MUST issue a proper SCSI command +- response with CHECK CONDITION as described in Section 10.4.3 +- Response. In these cases in which a status for the SCSI task was +- already sent before the reject, no additional status is required. If +- the error is detected while data from the initiator is still expected +- (i.e., the command PDU did not contain all the data and the target +- has not received a Data-Out PDU with the Final bit set to 1 for the +- unsolicited data, if any, and all outstanding R2Ts, if any), the +- target MUST wait until it receives the last expected Data-Out PDUs +- with the F bit set to 1 before sending the Response PDU. +- +- For additional usage semantics of Reject PDU, see Section 6.3 Usage +- Of Reject PDU in Recovery. +- +-10.17.2. DataSN/R2TSN +- +- This field is only valid if the rejected PDU is a Data/R2T SNACK and +- the Reject reason code is "Protocol error" (see Section 10.16 SNACK +- Request). The DataSN/R2TSN is the next Data/R2T sequence number that +- the target would send for the task, if any. +- +-10.17.3. StatSN, ExpCmdSN and MaxCmdSN +- +- These fields carry their usual values and are not related to the +- rejected command. StatSN is advanced after a Reject. +- +-10.17.4. Complete Header of Bad PDU +- +- The target returns the header (not including digest) of the PDU in +- error as the data of the response. +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 177] +- +-RFC 3720 iSCSI April 2004 +- +- +-10.18. NOP-Out +- +- Byte/ 0 | 1 | 2 | 3 | +- / | | | | +- |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +- +---------------+---------------+---------------+---------------+ +- 0|.|I| 0x00 |1| Reserved | +- +---------------+---------------+---------------+---------------+ +- 4|TotalAHSLength | DataSegmentLength | +- +---------------+---------------+---------------+---------------+ +- 8| LUN or Reserved | +- + + +- 12| | +- +---------------+---------------+---------------+---------------+ +- 16| Initiator Task Tag or 0xffffffff | +- +---------------+---------------+---------------+---------------+ +- 20| Target Transfer Tag or 0xffffffff | +- +---------------+---------------+---------------+---------------+ +- 24| CmdSN | +- +---------------+---------------+---------------+---------------+ +- 28| ExpStatSN | +- +---------------+---------------+---------------+---------------+ +- 32/ Reserved / +- +/ / +- +---------------+---------------+---------------+---------------+ +- 48| Header-Digest (Optional) | +- +---------------+---------------+---------------+---------------+ +- / DataSegment - Ping Data (optional) / +- +/ / +- +---------------+---------------+---------------+---------------+ +- | Data-Digest (Optional) | +- +---------------+---------------+---------------+---------------+ +- +- A NOP-Out may be used by an initiator as a "ping request" to verify +- that a connection/session is still active and all its components are +- operational. The NOP-In response is the "ping echo". +- +- A NOP-Out is also sent by an initiator in response to a NOP-In. +- +- A NOP-Out may also be used to confirm a changed ExpStatSN if another +- PDU will not be available for a long time. +- +- Upon receipt of a NOP-In with the Target Transfer Tag set to a valid +- value (not the reserved 0xffffffff), the initiator MUST respond with +- a NOP-Out. In this case, the NOP-Out Target Transfer Tag MUST +- contain a copy of the NOP-In Target Transfer Tag. +- +- +- +- +- +-Satran, et al. Standards Track [Page 178] +- +-RFC 3720 iSCSI April 2004 +- +- +-10.18.1. Initiator Task Tag +- +- The NOP-Out MUST have the Initiator Task Tag set to a valid value +- only if a response in the form of NOP-In is requested (i.e., the +- NOP-Out is used as a ping request). Otherwise, the Initiator Task +- Tag MUST be set to 0xffffffff. +- +- When a target receives the NOP-Out with a valid Initiator Task Tag, +- it MUST respond with a Nop-In Response (see Section 10.19 NOP-In). +- +- If the Initiator Task Tag contains 0xffffffff, the I bit MUST be set +- to 1 and the CmdSN is not advanced after this PDU is sent. +- +-10.18.2. Target Transfer Tag +- +- A target assigned identifier for the operation. +- +- The NOP-Out MUST only have the Target Transfer Tag set if it is +- issued in response to a NOP-In with a valid Target Transfer Tag. In +- this case, it copies the Target Transfer Tag from the NOP-In PDU. +- Otherwise, the Target Transfer Tag MUST be set to 0xffffffff. +- +- When the Target Transfer Tag is set to a value other than 0xffffffff, +- the LUN field MUST also be copied from the NOP-In. +- +-10.18.3. Ping Data +- +- Ping data are reflected in the NOP-In Response. The length of the +- reflected data are limited to MaxRecvDataSegmentLength. The length +- of ping data are indicated by the DataSegmentLength. 0 is a valid +- value for the DataSegmentLength and indicates the absence of ping +- data. +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 179] +- +-RFC 3720 iSCSI April 2004 +- +- +-10.19. NOP-In +- +- Byte/ 0 | 1 | 2 | 3 | +- / | | | | +- |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +- +---------------+---------------+---------------+---------------+ +- 0|.|.| 0x20 |1| Reserved | +- +---------------+---------------+---------------+---------------+ +- 4|TotalAHSLength | DataSegmentLength | +- +---------------+---------------+---------------+---------------+ +- 8| LUN or Reserved | +- + + +- 12| | +- +---------------+---------------+---------------+---------------+ +- 16| Initiator Task Tag or 0xffffffff | +- +---------------+---------------+---------------+---------------+ +- 20| Target Transfer Tag or 0xffffffff | +- +---------------+---------------+---------------+---------------+ +- 24| StatSN | +- +---------------+---------------+---------------+---------------+ +- 28| ExpCmdSN | +- +---------------+---------------+---------------+---------------+ +- 32| MaxCmdSN | +- +---------------+---------------+---------------+---------------+ +- 36/ Reserved / +- +/ / +- +---------------+---------------+---------------+---------------+ +- 48| Header-Digest (Optional) | +- +---------------+---------------+---------------+---------------+ +- / DataSegment - Return Ping Data / +- +/ / +- +---------------+---------------+---------------+---------------+ +- | Data-Digest (Optional) | +- +---------------+---------------+---------------+---------------+ +- +- NOP-In is either sent by a target as a response to a NOP-Out, as a +- "ping" to an initiator, or as a means to carry a changed ExpCmdSN +- and/or MaxCmdSN if another PDU will not be available for a long time +- (as determined by the target). +- +- When a target receives the NOP-Out with a valid Initiator Task Tag +- (not the reserved value 0xffffffff), it MUST respond with a NOP-In +- with the same Initiator Task Tag that was provided in the NOP-Out +- request. It MUST also duplicate up to the first +- MaxRecvDataSegmentLength bytes of the initiator provided Ping Data. +- For such a response, the Target Transfer Tag MUST be 0xffffffff. +- +- +- +- +- +-Satran, et al. Standards Track [Page 180] +- +-RFC 3720 iSCSI April 2004 +- +- +- Otherwise, when a target sends a NOP-In that is not a response to a +- Nop-Out received from the initiator, the Initiator Task Tag MUST be +- set to 0xffffffff and the Data Segment MUST NOT contain any data +- (DataSegmentLength MUST be 0). +- +-10.19.1. Target Transfer Tag +- +- If the target is responding to a NOP-Out, this is set to the reserved +- value 0xffffffff. +- +- If the target is sending a NOP-In as a Ping (intending to receive a +- corresponding NOP-Out), this field is set to a valid value (not the +- reserved 0xffffffff). +- +- If the target is initiating a NOP-In without wanting to receive a +- corresponding NOP-Out, this field MUST hold the reserved value of +- 0xffffffff. +- +-10.19.2. StatSN +- +- The StatSN field will always contain the next StatSN. However, when +- the Initiator Task Tag is set to 0xffffffff, StatSN for the +- connection is not advanced after this PDU is sent. +- +-10.19.3. LUN +- +- A LUN MUST be set to a correct value when the Target Transfer Tag is +- valid (not the reserved value 0xffffffff). +- +-11. iSCSI Security Text Keys and Authentication Methods +- +- Only the following keys are used during the SecurityNegotiation stage +- of the Login Phase: +- +- SessionType +- InitiatorName +- TargetName +- TargetAddress +- InitiatorAlias +- TargetAlias +- TargetPortalGroupTag +- AuthMethod and the keys used by the authentication methods +- specified under Section 11.1 AuthMethod along with all of +- their associated keys as well as Vendor Specific +- Authentication Methods. +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 181] +- +-RFC 3720 iSCSI April 2004 +- +- +- Other keys MUST NOT be used. +- +- SessionType, InitiatorName, TargetName, InitiatorAlias, TargetAlias, +- and TargetPortalGroupTag are described in Chapter 12 as they can be +- used also in the OperationalNegotiation stage. +- +- All security keys have connection-wide applicability. +- +-11.1. AuthMethod +- +- Use: During Login - Security Negotiation Senders: Initiator and +- Target Scope: connection +- +- AuthMethod = +- +- The main item of security negotiation is the authentication method +- (AuthMethod). +- +- The authentication methods that can be used (appear in the +- list-of-values) are either those listed in the following table or are +- vendor-unique methods: +- +- +------------------------------------------------------------+ +- | Name | Description | +- +------------------------------------------------------------+ +- | KRB5 | Kerberos V5 - defined in [RFC1510] | +- +------------------------------------------------------------+ +- | SPKM1 | Simple Public-Key GSS-API Mechanism | +- | | defined in [RFC2025] | +- +------------------------------------------------------------+ +- | SPKM2 | Simple Public-Key GSS-API Mechanism | +- | | defined in [RFC2025] | +- +------------------------------------------------------------+ +- | SRP | Secure Remote Password | +- | | defined in [RFC2945] | +- +------------------------------------------------------------+ +- | CHAP | Challenge Handshake Authentication Protocol| +- | | defined in [RFC1994] | +- +------------------------------------------------------------+ +- | None | No authentication | +- +------------------------------------------------------------+ +- +- The AuthMethod selection is followed by an "authentication exchange" +- specific to the authentication method selected. +- +- The authentication method proposal may be made by either the +- initiator or the target. However the initiator MUST make the first +- step specific to the selected authentication method as soon as it is +- +- +- +-Satran, et al. Standards Track [Page 182] +- +-RFC 3720 iSCSI April 2004 +- +- +- selected. It follows that if the target makes the authentication +- method proposal the initiator sends the first keys(s) of the exchange +- together with its authentication method selection. +- +- The authentication exchange authenticates the initiator to the +- target, and optionally, the target to the initiator. Authentication +- is OPTIONAL to use but MUST be supported by the target and initiator. +- +- The initiator and target MUST implement CHAP. All other +- authentication methods are OPTIONAL. +- +- Private or public extension algorithms MAY also be negotiated for +- authentication methods. Whenever a private or public extension +- algorithm is part of the default offer (the offer made in absence of +- explicit administrative action) the implementer MUST ensure that CHAP +- is listed as an alternative in the default offer and "None" is not +- part of the default offer. +- +- Extension authentication methods MUST be named using one of the +- following two formats: +- +- a) Z-reversed.vendor.dns_name.do_something= +- b) Z<#>= +- +- Authentication methods named using the Z- format are used as private +- extensions. Authentication methods named using the Z# format are +- used as public extensions that must be registered with IANA and MUST +- be described by an informational RFC. +- +- For all of the public or private extension authentication methods, +- the method specific keys MUST conform to the format specified in +- Section 5.1 Text Format for standard-label. +- +- To identify the vendor for private extension authentication methods, +- we suggest you use the reversed DNS-name as a prefix to the proper +- digest names. +- +- The part of digest-name following Z- and Z# MUST conform to the +- format for standard-label specified in Section 5.1 Text Format. +- +- Support for public or private extension authentication methods is +- OPTIONAL. +- +- The following subsections define the specific exchanges for each of +- the standardized authentication methods. As mentioned earlier the +- first step is always done by the initiator. +- +- +- +- +- +-Satran, et al. Standards Track [Page 183] +- +-RFC 3720 iSCSI April 2004 +- +- +-11.1.1. Kerberos +- +- For KRB5 (Kerberos V5) [RFC1510] and [RFC1964], the initiator MUST +- use: +- +- KRB_AP_REQ= +- +- where KRB_AP_REQ is the client message as defined in [RFC1510]. +- +- The default principal name assumed by an iSCSI initiator or target +- (prior to any administrative configuration action) MUST be the iSCSI +- Initiator Name or iSCSI Target Name respectively, prefixed by the +- string "iscsi/". +- +- If the initiator authentication fails, the target MUST respond with a +- Login reject with "Authentication Failure" status. Otherwise, if the +- initiator has selected the mutual authentication option (by setting +- MUTUAL-REQUIRED in the ap-options field of the KRB_AP_REQ), the +- target MUST reply with: +- +- KRB_AP_REP= +- +- where KRB_AP_REP is the server's response message as defined in +- [RFC1510]. +- +- If mutual authentication was selected and target authentication +- fails, the initiator MUST close the connection. +- +- KRB_AP_REQ and KRB_AP_REP are binary-values and their binary length +- (not the length of the character string that represents them in +- encoded form) MUST not exceed 65536 bytes. +- +-11.1.2. Simple Public-Key Mechanism (SPKM) +- +- For SPKM1 and SPKM2 [RFC2025], the initiator MUST use: +- +- SPKM_REQ= +- +- where SPKM-REQ is the first initiator token as defined in [RFC2025]. +- +- [RFC2025] defines situations where each side may send an error token +- that may cause the peer to re-generate and resend its last token. +- This scheme is followed in iSCSI, and the error token syntax is: +- +- SPKM_ERROR= +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 184] +- +-RFC 3720 iSCSI April 2004 +- +- +- However, SPKM-DEL tokens that are defined by [RFC2025] for fatal +- errors will not be used by iSCSI. If the target needs to send a +- SPKM-DEL token, it will, instead, send a Login "login reject" message +- with the "Authentication Failure" status and terminate the +- connection. If the initiator needs to send a SPKM-DEL token, it will +- close the connection. +- +- In the following sections, we assume that no SPKM-ERROR tokens are +- required. +- +- If the initiator authentication fails, the target MUST return an +- error. Otherwise, if the AuthMethod is SPKM1 or if the initiator has +- selected the mutual authentication option (by setting mutual-state +- bit in the options field of the REQ-TOKEN in the SPKM-REQ), the +- target MUST reply with: +- +- SPKM_REP_TI= +- +- where SPKM-REP-TI is the target token as defined in [RFC2025]. +- +- If mutual authentication was selected and target authentication +- fails, the initiator MUST close the connection. Otherwise, if the +- AuthMethod is SPKM1, the initiator MUST continue with: +- +- SPKM_REP_IT= +- +- where SPKM-REP-IT is the second initiator token as defined in +- [RFC2025]. If the initiator authentication fails, the target MUST +- answer with a Login reject with "Authentication Failure" status. +- +- SPKM requires support for very long authentication items. +- +- All the SPKM-* tokens are binary-values and their binary length (not +- the length of the character string that represents them in encoded +- form) MUST not exceed 65536 bytes. +- +-11.1.3. Secure Remote Password (SRP) +- +- For SRP [RFC2945], the initiator MUST use: +- +- SRP_U= TargetAuth=Yes /* or TargetAuth=No */ +- +- The target MUST answer with a Login reject with the "Authorization +- Failure" status or reply with: +- +- SRP_GROUP= SRP_s= +- +- Where G1,G2... are proposed groups, in order of preference. +- +- +- +-Satran, et al. Standards Track [Page 185] +- +-RFC 3720 iSCSI April 2004 +- +- +- The initiator MUST either close the connection or continue with: +- +- SRP_A= SRP_GROUP= +- +- Where G is one of G1,G2... that were proposed by the target. +- +- The target MUST answer with a Login reject with the "Authentication +- Failure" status or reply with: +- +- SRP_B= +- +- The initiator MUST close the connection or continue with: +- +- SRP_M= +- +- If the initiator authentication fails, the target MUST answer with a +- Login reject with "Authentication Failure" status. Otherwise, if the +- initiator sent TargetAuth=Yes in the first message (requiring target +- authentication), the target MUST reply with: +- +- SRP_HM= +- +- If the target authentication fails, the initiator MUST close the +- connection. +- +- Where U, s, A, B, M, and H(A | M | K) are defined in [RFC2945] (using +- the SHA1 hash function, such as SRP-SHA1) and G,Gn (Gn stands for +- G1,G2...) are identifiers of SRP groups specified in [RFC3723]. G, +- Gn, and U are text strings, s,A,B,M, and H(A | M | K) are +- binary-values. The length of s,A,B,M and H(A | M | K) in binary form +- (not the length of the character string that represents them in +- encoded form) MUST not exceed 1024 bytes. +- +- For the SRP_GROUP, all the groups specified in [RFC3723] up to 1536 +- bits (i.e., SRP-768, SRP-1024, SRP-1280, SRP-1536) must be supported +- by initiators and targets. To guarantee interoperability, targets +- MUST always offer "SRP-1536" as one of the proposed groups. +- +-11.1.4. Challenge Handshake Authentication Protocol (CHAP) +- +- For CHAP [RFC1994], in the first step, the initiator MUST send: +- +- CHAP_A= +- +- Where A1,A2... are proposed algorithms, in order of preference. +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 186] +- +-RFC 3720 iSCSI April 2004 +- +- +- In the second step, the target MUST answer with a Login reject with +- the "Authentication Failure" status or reply with: +- +- CHAP_A= CHAP_I= CHAP_C= +- +- Where A is one of A1,A2... that were proposed by the initiator. +- +- In the third step, the initiator MUST continue with: +- +- CHAP_N= CHAP_R= +- +- or, if it requires target authentication, with: +- +- CHAP_N= CHAP_R= CHAP_I= CHAP_C= +- +- If the initiator authentication fails, the target MUST answer with a +- Login reject with "Authentication Failure" status. Otherwise, if the +- initiator required target authentication, the target MUST either +- answer with a Login reject with "Authentication Failure" or reply +- with: +- +- CHAP_N= CHAP_R= +- +- If target authentication fails, the initiator MUST close the +- connection. +- +- Where N, (A,A1,A2), I, C, and R are (correspondingly) the Name, +- Algorithm, Identifier, Challenge, and Response as defined in +- [RFC1994], N is a text string, A,A1,A2, and I are numbers, and C and +- R are large-binary-values and their binary length (not the length of +- the character string that represents them in encoded form) MUST not +- exceed 1024 bytes. +- +- For the Algorithm, as stated in [RFC1994], one value is required to +- be implemented: +- +- 5 (CHAP with MD5) +- +- To guarantee interoperability, initiators MUST always offer it as one +- of the proposed algorithms. +- +-12. Login/Text Operational Text Keys +- +- Some session specific parameters MUST only be carried on the leading +- connection and cannot be changed after the leading connection login +- (e.g., MaxConnections, the maximum number of connections). This +- +- +- +- +- +-Satran, et al. Standards Track [Page 187] +- +-RFC 3720 iSCSI April 2004 +- +- +- holds for a single connection session with regard to connection +- restart. The keys that fall into this category have the use: LO +- (Leading Only). +- +- Keys that can only be used during login have the use: IO (initialize +- only), while those that can be used in both the Login Phase and Full +- Feature Phase have the use: ALL. +- +- Keys that can only be used during Full Feature Phase use FFPO (Full +- Feature Phase only). +- +- Keys marked as Any-Stage may also appear in the SecurityNegotiation +- stage while all other keys described in this chapter are operational +- keys. +- +- Keys that do not require an answer are marked as Declarative. +- +- Key scope is indicated as session-wide (SW) or connection-only (CO). +- +- Result function, wherever mentioned, states the function that can be +- applied to check the validity of the responder selection. Minimum +- means that the selected value cannot exceed the offered value. +- Maximum means that the selected value cannot be lower than the +- offered value. AND means that the selected value must be a possible +- result of a Boolean "and" function with an arbitrary Boolean value +- (e.g., if the offered value is No the selected value must be No). OR +- means that the selected value must be a possible result of a Boolean +- "or" function with an arbitrary Boolean value (e.g., if the offered +- value is Yes the selected value must be Yes). +- +-12.1. HeaderDigest and DataDigest +- +- Use: IO +- Senders: Initiator and Target +- Scope: CO +- +- HeaderDigest = +- DataDigest = +- +- Default is None for both HeaderDigest and DataDigest. +- +- Digests enable the checking of end-to-end, non-cryptographic data +- integrity beyond the integrity checks provided by the link layers and +- the covering of the whole communication path including all elements +- that may change the network level PDUs such as routers, switches, and +- proxies. +- +- +- +- +- +-Satran, et al. Standards Track [Page 188] +- +-RFC 3720 iSCSI April 2004 +- +- +- The following table lists cyclic integrity checksums that can be +- negotiated for the digests and that MUST be implemented by every +- iSCSI initiator and target. These digest options only have error +- detection significance. +- +- +---------------------------------------------+ +- | Name | Description | Generator | +- +---------------------------------------------+ +- | CRC32C | 32 bit CRC |0x11edc6f41| +- +---------------------------------------------+ +- | None | no digest | +- +---------------------------------------------+ +- +- The generator polynomial for this digest is given in +- hex-notation (e.g., 0x3b stands for 0011 1011 and the polynomial is +- x**5+X**4+x**3+x+1). +- +- When the Initiator and Target agree on a digest, this digest MUST be +- used for every PDU in Full Feature Phase. +- +- Padding bytes, when present in a segment covered by a CRC, SHOULD be +- set to 0 and are included in the CRC. +- +- The CRC MUST be calculated by a method that produces the same +- results as the following process: +- +- - The PDU bits are considered as the coefficients of a +- polynomial M(x) of degree n-1; bit 7 of the lowest numbered +- byte is considered the most significant bit (x^n-1), followed +- by bit 6 of the lowest numbered byte through bit 0 of the +- highest numbered byte (x^0). +- +- - The most significant 32 bits are complemented. +- +- - The polynomial is multiplied by x^32 then divided by G(x). The +- generator polynomial produces a remainder R(x) of degree <= 31. +- +- - The coefficients of R(x) are considered a 32 bit sequence. +- +- - The bit sequence is complemented and the result is the CRC. +- +- - The CRC bits are mapped into the digest word. The x^31 +- coefficient in bit 7 of the lowest numbered byte of the digest +- continuing through to the byte up to the x^24 coefficient in +- bit 0 of the lowest numbered byte, continuing with the x^23 +- coefficient in bit 7 of next byte through x^0 in bit 0 of the +- highest numbered byte. +- +- +- +- +-Satran, et al. Standards Track [Page 189] +- +-RFC 3720 iSCSI April 2004 +- +- +- - Computing the CRC over any segment (data or header) extended +- to include the CRC built using the generator 0x11edc6f41 will +- always get the value 0x1c2d19ed as its final remainder (R(x)). +- This value is given here in its polynomial form (i.e., not +- mapped as the digest word). +- +- For a discussion about selection criteria for the CRC, see +- [RFC3385]. For a detailed analysis of the iSCSI polynomial, see +- [Castagnoli93]. +- +- Private or public extension algorithms MAY also be negotiated for +- digests. Whenever a private or public digest extension algorithm is +- part of the default offer (the offer made in absence of explicit +- administrative action) the implementer MUST ensure that CRC32C is +- listed as an alternative in the default offer and "None" is not +- part of the default offer. +- +- Extension digest algorithms MUST be named using one of the following +- two formats: +- +- a) Y-reversed.vendor.dns_name.do_something= +- b) Y<#>= +- +- Digests named using the Y- format are used for private purposes +- (unregistered). Digests named using the Y# format (public extension) +- must be registered with IANA and MUST be described by an +- informational RFC. +- +- For private extension digests, to identify the vendor, we suggest +- you use the reversed DNS-name as a prefix to the proper digest +- names. +- +- The part of digest-name following Y- and Y# MUST conform to the +- format for standard-label specified in Section 5.1 Text Format. +- +- Support for public or private extension digests is OPTIONAL. +- +-12.2. MaxConnections +- +- Use: LO +- Senders: Initiator and Target +- Scope: SW +- Irrelevant when: SessionType=Discovery +- +- MaxConnections= +- +- Default is 1. +- Result function is Minimum. +- +- +- +-Satran, et al. Standards Track [Page 190] +- +-RFC 3720 iSCSI April 2004 +- +- +- +- Initiator and target negotiate the maximum number of connections +- requested/acceptable. +- +-12.3. SendTargets +- +- Use: FFPO +- Senders: Initiator +- Scope: SW +- +- For a complete description, see Appendix D. - SendTargets +- Operation -. +- +-12.4. TargetName +- +- Use: IO by initiator, FFPO by target - only as response to a +- SendTargets, Declarative, Any-Stage +- +- Senders: Initiator and Target +- Scope: SW +- +- TargetName= +- +- Examples: +- +- TargetName=iqn.1993-11.com.disk-vendor:diskarrays.sn.45678 +- TargetName=eui.020000023B040506 +- +- The initiator of the TCP connection MUST provide this key to the +- remote endpoint in the first login request if the initiator is not +- establishing a discovery session. The iSCSI Target Name specifies +- the worldwide unique name of the target. +- +- The TargetName key may also be returned by the "SendTargets" text +- request (which is its only use when issued by a target). +- +- TargetName MUST not be redeclared within the login phase. +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 191] +- +-RFC 3720 iSCSI April 2004 +- +- +-12.5. InitiatorName +- +- Use: IO, Declarative, Any-Stage +- Senders: Initiator +- Scope: SW +- +- InitiatorName= +- +- Examples: +- +- InitiatorName=iqn.1992-04.com.os-vendor.plan9:cdrom.12345 +- InitiatorName=iqn.2001-02.com.ssp.users:customer235.host90 +- +- The initiator of the TCP connection MUST provide this key to the +- remote endpoint at the first Login of the Login Phase for every +- connection. The InitiatorName key enables the initiator to identify +- itself to the remote endpoint. +- +- InitiatorName MUST not be redeclared within the login phase. +- +-12.6. TargetAlias +- +- Use: ALL, Declarative, Any-Stage +- Senders: Target +- Scope: SW +- +- TargetAlias= +- +- Examples: +- +- TargetAlias=Bob-s Disk +- TargetAlias=Database Server 1 Log Disk +- TargetAlias=Web Server 3 Disk 20 +- +- If a target has been configured with a human-readable name or +- description, this name SHOULD be communicated to the initiator during +- a Login Response PDU if SessionType=Normal (see Section 12.21 +- SessionType). This string is not used as an identifier, nor is it +- meant to be used for authentication or authorization decisions. It +- can be displayed by the initiator's user interface in a list of +- targets to which it is connected. +- +- +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 192] +- +-RFC 3720 iSCSI April 2004 +- +- +-12.7. InitiatorAlias +- +- Use: ALL, Declarative, Any-Stage +- Senders: Initiator +- Scope: SW +- +- InitiatorAlias= +- +- Examples: +- +- InitiatorAlias=Web Server 4 +- InitiatorAlias=spyalley.nsa.gov +- InitiatorAlias=Exchange Server +- +- If an initiator has been configured with a human-readable name or +- description, it SHOULD be communicated to the target during a Login +- Request PDU. If not, the host name can be used instead. This string +- is not used as an identifier, nor is meant to be used for +- authentication or authorization decisions. It can be displayed by +- the target's user interface in a list of initiators to which it is +- connected. +- +-12.8. TargetAddress +- +- Use: ALL, Declarative, Any-Stage +- Senders: Target +- Scope: SW +- +- TargetAddress=domainname[:port][,portal-group-tag] +- +- The domainname can be specified as either a DNS host name, a +- dotted-decimal IPv4 address, or a bracketed IPv6 address as specified +- in [RFC2732]. +- +- If the TCP port is not specified, it is assumed to be the +- IANA-assigned default port for iSCSI (see Section 13 IANA +- Considerations). +- +- If the TargetAddress is returned as the result of a redirect status +- in a login response, the comma and portal group tag MUST be omitted. +- +- If the TargetAddress is returned within a SendTargets response, the +- portal group tag MUST be included. +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 193] +- +-RFC 3720 iSCSI April 2004 +- +- +- Examples: +- +- TargetAddress=10.0.0.1:5003,1 +- TargetAddress=[1080:0:0:0:8:800:200C:417A],65 +- TargetAddress=[1080::8:800:200C:417A]:5003,1 +- TargetAddress=computingcenter.example.com,23 +- +- Use of the portal-group-tag is described in Appendix D. +- - SendTargets Operation -. The formats for the port and +- portal-group-tag are the same as the one specified in Section 12.9 +- TargetPortalGroupTag. +- +-12.9. TargetPortalGroupTag +- +- Use: IO by target, Declarative, Any-Stage +- Senders: Target +- Scope: SW +- +- TargetPortalGroupTag=<16-bit-binary-value> +- +- Examples: +- TargetPortalGroupTag=1 +- +- The target portal group tag is a 16-bit binary-value that uniquely +- identifies a portal group within an iSCSI target node. This key +- carries the value of the tag of the portal group that is servicing +- the Login request. The iSCSI target returns this key to the +- initiator in the Login Response PDU to the first Login Request PDU +- that has the C bit set to 0 when TargetName is given by the +- initiator. +- +- For the complete usage expectations of this key see Section 5.3 Login +- Phase. +- +-12.10. InitialR2T +- +- Use: LO +- Senders: Initiator and Target +- Scope: SW +- Irrelevant when: SessionType=Discovery +- +- InitialR2T= +- +- Examples: +- +- I->InitialR2T=No +- T->InitialR2T=No +- +- +- +- +-Satran, et al. Standards Track [Page 194] +- +-RFC 3720 iSCSI April 2004 +- +- +- Default is Yes. +- Result function is OR. +- +- The InitialR2T key is used to turn off the default use of R2T for +- unidirectional and the output part of bidirectional commands, thus +- allowing an initiator to start sending data to a target as if it has +- received an initial R2T with Buffer Offset=Immediate Data Length and +- Desired Data Transfer Length=(min(FirstBurstLength, Expected Data +- Transfer Length) - Received Immediate Data Length). +- +- The default action is that R2T is required, unless both the initiator +- and the target send this key-pair attribute specifying InitialR2T=No. +- Only the first outgoing data burst (immediate data and/or separate +- PDUs) can be sent unsolicited (i.e., not requiring an explicit R2T). +- +-12.11. ImmediateData +- +- Use: LO +- Senders: Initiator and Target +- Scope: SW +- Irrelevant when: SessionType=Discovery +- +- ImmediateData= +- +- Default is Yes. +- Result function is AND. +- +- The initiator and target negotiate support for immediate data. To +- turn immediate data off, the initiator or target must state its +- desire to do so. ImmediateData can be turned on if both the +- initiator and target have ImmediateData=Yes. +- +- If ImmediateData is set to Yes and InitialR2T is set to Yes +- (default), then only immediate data are accepted in the first burst. +- +- If ImmediateData is set to No and InitialR2T is set to Yes, then the +- initiator MUST NOT send unsolicited data and the target MUST reject +- unsolicited data with the corresponding response code. +- +- If ImmediateData is set to No and InitialR2T is set to No, then the +- initiator MUST NOT send unsolicited immediate data, but MAY send one +- unsolicited burst of Data-Out PDUs. +- +- If ImmediateData is set to Yes and InitialR2T is set to No, then the +- initiator MAY send unsolicited immediate data and/or one unsolicited +- burst of Data-Out PDUs. +- +- +- +- +- +-Satran, et al. Standards Track [Page 195] +- +-RFC 3720 iSCSI April 2004 +- +- +- The following table is a summary of unsolicited data options: +- +- +----------+-------------+------------------+--------------+ +- |InitialR2T|ImmediateData| Unsolicited |Immediate Data| +- | | | Data Out PDUs | | +- +----------+-------------+------------------+--------------+ +- | No | No | Yes | No | +- +----------+-------------+------------------+--------------+ +- | No | Yes | Yes | Yes | +- +----------+-------------+------------------+--------------+ +- | Yes | No | No | No | +- +----------+-------------+------------------+--------------+ +- | Yes | Yes | No | Yes | +- +----------+-------------+------------------+--------------+ +- +-12.12. MaxRecvDataSegmentLength +- +- Use: ALL, Declarative +- Senders: Initiator and Target +- Scope: CO +- +- MaxRecvDataSegmentLength= +- +- Default is 8192 bytes. +- +- The initiator or target declares the maximum data segment length in +- bytes it can receive in an iSCSI PDU. +- +- The transmitter (initiator or target) is required to send PDUs with a +- data segment that does not exceed MaxRecvDataSegmentLength of the +- receiver. +- +- A target receiver is additionally limited by MaxBurstLength for +- solicited data and FirstBurstLength for unsolicited data. An +- initiator MUST NOT send solicited PDUs exceeding MaxBurstLength nor +- unsolicited PDUs exceeding FirstBurstLength (or +- FirstBurstLength-Immediate Data Length if immediate data were sent). +- +-12.13. MaxBurstLength +- +- Use: LO +- Senders: Initiator and Target +- Scope: SW +- Irrelevant when: SessionType=Discovery +- +- MaxBurstLength= +- +- +- +- +- +-Satran, et al. Standards Track [Page 196] +- +-RFC 3720 iSCSI April 2004 +- +- +- Default is 262144 (256 Kbytes). +- Result function is Minimum. +- +- The initiator and target negotiate maximum SCSI data payload in bytes +- in a Data-In or a solicited Data-Out iSCSI sequence. A sequence +- consists of one or more consecutive Data-In or Data-Out PDUs that end +- with a Data-In or Data-Out PDU with the F bit set to one. +- +-12.14. FirstBurstLength +- +- Use: LO +- Senders: Initiator and Target +- Scope: SW +- Irrelevant when: SessionType=Discovery +- Irrelevant when: ( InitialR2T=Yes and ImmediateData=No ) +- +- FirstBurstLength= +- +- Default is 65536 (64 Kbytes). +- Result function is Minimum. +- +- The initiator and target negotiate the maximum amount in bytes of +- unsolicited data an iSCSI initiator may send to the target during the +- execution of a single SCSI command. This covers the immediate data +- (if any) and the sequence of unsolicited Data-Out PDUs (if any) that +- follow the command. +- +- FirstBurstLength MUST NOT exceed MaxBurstLength. +- +-12.15. DefaultTime2Wait +- +- Use: LO +- Senders: Initiator and Target +- Scope: SW +- +- DefaultTime2Wait= +- +- Default is 2. +- Result function is Maximum. +- +- The initiator and target negotiate the minimum time, in seconds, to +- wait before attempting an explicit/implicit logout or an active task +- reassignment after an unexpected connection termination or a +- connection reset. +- +- A value of 0 indicates that logout or active task reassignment can be +- attempted immediately. +- +- +- +- +-Satran, et al. Standards Track [Page 197] +- +-RFC 3720 iSCSI April 2004 +- +- +-12.16. DefaultTime2Retain +- +- Use: LO Senders: Initiator and Target Scope: SW +- +- DefaultTime2Retain= +- +- Default is 20. Result function is Minimum. +- +- The initiator and target negotiate the maximum time, in seconds after +- an initial wait (Time2Wait), before which an active task reassignment +- is still possible after an unexpected connection termination or a +- connection reset. +- +- This value is also the session state timeout if the connection in +- question is the last LOGGED_IN connection in the session. +- +- A value of 0 indicates that connection/task state is immediately +- discarded by the target. +- +-12.17. MaxOutstandingR2T +- +- Use: LO +- Senders: Initiator and Target +- Scope: SW +- +- MaxOutstandingR2T= +- Irrelevant when: SessionType=Discovery +- +- Default is 1. +- Result function is Minimum. +- +- Initiator and target negotiate the maximum number of outstanding R2Ts +- per task, excluding any implied initial R2T that might be part of +- that task. An R2T is considered outstanding until the last data PDU +- (with the F bit set to 1) is transferred, or a sequence reception +- timeout (Section 6.1.4.1 Recovery Within-command) is encountered for +- that data sequence. +- +-12.18. DataPDUInOrder +- +- Use: LO +- Senders: Initiator and Target +- Scope: SW +- Irrelevant when: SessionType=Discovery +- +- DataPDUInOrder= +- +- +- +- +- +-Satran, et al. Standards Track [Page 198] +- +-RFC 3720 iSCSI April 2004 +- +- +- Default is Yes. +- Result function is OR. +- +- No is used by iSCSI to indicate that the data PDUs within sequences +- can be in any order. Yes is used to indicate that data PDUs within +- sequences have to be at continuously increasing addresses and +- overlays are forbidden. +- +-12.19. DataSequenceInOrder +- +- Use: LO +- Senders: Initiator and Target +- Scope: SW +- Irrelevant when: SessionType=Discovery +- +- DataSequenceInOrder= +- +- Default is Yes. +- Result function is OR. +- +- A Data Sequence is a sequence of Data-In or Data-Out PDUs that end +- with a Data-In or Data-Out PDU with the F bit set to one. A Data-Out +- sequence is sent either unsolicited or in response to an R2T. +- Sequences cover an offset-range. +- +- If DataSequenceInOrder is set to No, Data PDU sequences may be +- transferred in any order. +- +- If DataSequenceInOrder is set to Yes, Data Sequences MUST be +- transferred using continuously non-decreasing sequence offsets (R2T +- buffer offset for writes, or the smallest SCSI Data-In buffer offset +- within a read data sequence). +- +- If DataSequenceInOrder is set to Yes, a target may retry at most the +- last R2T, and an initiator may at most request retransmission for the +- last read data sequence. For this reason, if ErrorRecoveryLevel is +- not 0 and DataSequenceInOrder is set to Yes then MaxOustandingR2T +- MUST be set to 1. +- +-12.20. ErrorRecoveryLevel +- +- Use: LO +- Senders: Initiator and Target +- Scope: SW +- +- ErrorRecoveryLevel= +- +- +- +- +- +-Satran, et al. Standards Track [Page 199] +- +-RFC 3720 iSCSI April 2004 +- +- +- Default is 0. +- Result function is Minimum. +- +- The initiator and target negotiate the recovery level supported. +- +- Recovery levels represent a combination of recovery capabilities. +- Each recovery level includes all the capabilities of the lower +- recovery levels and adds some new ones to them. +- +- In the description of recovery mechanisms, certain recovery classes +- are specified. Section 6.1.5 Error Recovery Hierarchy describes the +- mapping between the classes and the levels. +- +-12.21. SessionType +- +- Use: LO, Declarative, Any-Stage +- Senders: Initiator +- Scope: SW +- +- SessionType= +- +- Default is Normal. +- +- The initiator indicates the type of session it wants to create. The +- target can either accept it or reject it. +- +- A discovery session indicates to the Target that the only purpose of +- this Session is discovery. The only requests a target accepts in +- this type of session are a text request with a SendTargets key and a +- logout request with reason "close the session". +- +- The discovery session implies MaxConnections = 1 and overrides both +- the default and an explicit setting. +- +-12.22. The Private or Public Extension Key Format +- +- Use: ALL +- Senders: Initiator and Target +- Scope: specific key dependent +- +- X-reversed.vendor.dns_name.do_something= +- +- or +- +- X<#>= +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 200] +- +-RFC 3720 iSCSI April 2004 +- +- +- Keys with this format are used for public or private extension +- purposes. These keys always start with X- if unregistered with IANA +- (private) or X# if registered with IANA (public). +- +- For unregistered keys, to identify the vendor, we suggest you use the +- reversed DNS-name as a prefix to the key-proper. +- +- The part of key-name following X- and X# MUST conform to the format +- for key-name specified in Section 5.1 Text Format. +- +- For IANA registered keys the string following X# must be registered +- with IANA and the use of the key MUST be described by an +- informational RFC. +- +- Vendor specific keys MUST ONLY be used in normal sessions. +- +- Support for public or private extension keys is OPTIONAL. +- +-13. IANA Considerations +- +- This section conforms to [RFC2434]. +- +- The well-known user TCP port number for iSCSI connections assigned by +- IANA is 3260 and this is the default iSCSI port. Implementations +- needing a system TCP port number may use port 860, the port assigned +- by IANA as the iSCSI system port; however in order to use port 860, +- it MUST be explicitly specified - implementations MUST NOT default to +- use of port 860, as 3260 is the only allowed default. +- +- Extension keys, authentication methods, or digest types for which a +- vendor or group of vendors intend to provide publicly available +- descriptions MUST be described by an RFC and MUST be registered with +- IANA. +- +- The IANA has set up the following three registries: +- +- a) iSCSI extended key registry +- b) iSCSI authentication methods registry +- c) iSCSI digests registry +- +- [RFC3723] also instructs IANA to maintain a registry for the values +- of the SRP_GROUP key. The format of these values must conform to the +- one specified for iSCSI extension item-label in Section 13.5.4 +- Standard iSCSI extension item-label format. +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 201] +- +-RFC 3720 iSCSI April 2004 +- +- +- For the iSCSI authentication methods registry and the iSCSI digests +- registry, IANA MUST also assign a 16-bit unsigned integer number (the +- method number for the authentication method and the digest number for +- the digest). +- +- The following initial values for the registry for authentication +- methods are specified by the standards action of this document: +- +- Authentication Method | Number | +- +----------------------------------------+--------+ +- | CHAP | 1 | +- +----------------------------------------+--------+ +- | SRP | 2 | +- +----------------------------------------+--------+ +- | KRB5 | 3 | +- +----------------------------------------+--------+ +- | SPKM1 | 4 | +- +----------------------------------------+--------+ +- | SPKM2 | 5 | +- +----------------------------------------+--------+ +- +- All other record numbers from 0 to 255 are reserved. IANA will +- register numbers above 255. +- +- Authentication methods with numbers above 255 MUST be unique within +- the registry and MUST be used with the prefix Z#. +- +- +- The following initial values for the registry for digests are +- specified by the standards action of this document: +- +- Digest | Number | +- +----------------------------------------+--------+ +- | CRC32C | 1 | +- +----------------------------------------+--------+ +- +- All other record numbers from 0 to 255 are reserved. IANA will +- register numbers above 255. +- +- Digests with numbers above 255 MUST be unique within the registry and +- MUST be used with the prefix Y#. +- +- The RFC that describes the item to be registered MUST indicate in the +- IANA Considerations section the string and iSCSI registry to which it +- should be recorded. +- +- Extension Keys, Authentication Methods, and digests (iSCSI extension +- items) must conform to a number of requirements as described below. +- +- +- +-Satran, et al. Standards Track [Page 202] +- +-RFC 3720 iSCSI April 2004 +- +- +-13.1. Naming Requirements +- +- Each iSCSI extension item must have a unique name in its category. +- This name will be used as a standard-label for the key, access +- method, or digest and must conform to the syntax specified in Section +- 13.5.4 Standard iSCSI extension item-label format for iSCSI extension +- item-labels. +- +-13.2. Mechanism Specification Requirements +- +- For iSCSI extension items all of the protocols and procedures used by +- a given iSCSI extension item must be described, either in the +- specification of the iSCSI extension item itself or in some other +- publicly available specification, in sufficient detail for the iSCSI +- extension item to be implemented by any competent implementor. Use +- of secret and/or proprietary methods in iSCSI extension items are +- expressly prohibited. In addition, the restrictions imposed by +- [RFC1602] on the standardization of patented algorithms must be +- respected. +- +-13.3. Publication Requirements +- +- All iSCSI extension items must be described by an RFC. The RFC may +- be informational rather than Standards-Track, although Standards +- Track review and approval are encouraged for all iSCSI extension +- items. +- +-13.4. Security Requirements +- +- Any known security issues that arise from the use of the iSCSI +- extension item must be completely and fully described. It is not +- required that the iSCSI extension item be secure or that it be free +- from risks, but that the known risks be identified. Publication of a +- new iSCSI extension item does not require an exhaustive security +- review, and the security considerations section is subject to +- continuing evaluation. +- +- Additional security considerations should be addressed by publishing +- revised versions of the iSCSI extension item specification. +- +- For each of these registries, IANA must record the registered string, +- which MUST conform to the format rules described in Section 13.5.4 +- Standard iSCSI extension item-label format for iSCSI extension +- item-labels, and the RFC number that describes it. The key prefix +- (X#, Y# or Z#) is not part of the recorded string. +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 203] +- +-RFC 3720 iSCSI April 2004 +- +- +-13.5. Registration Procedure +- +- Registration of a new iSCSI extension item starts with the +- construction of an Internet Draft to become an RFC. +- +-13.5.1. Present the iSCSI extension item to the Community +- +- Send a proposed access type specification to the IPS WG mailing list, +- or if the IPS WG is disbanded at the registration time, to a mailing +- list designated by the IETF Transport Area Director for a review +- period of a month. The intent of the public posting is to solicit +- comments and feedback on the iSCSI extension item specification and a +- review of any security considerations. +- +-13.5.2. iSCSI extension item review and IESG approval +- +- When the one month period has passed, the IPS WG chair or a person +- nominated by the IETF Transport Area Director (the iSCSI extension +- item reviewer) forwards the Internet Draft to the IESG for +- publication as an informational RFC or rejects it. If the +- specification is a standards track document, the usual IETF +- procedures for such documents are followed. +- +- Decisions made by the iSCSI extension item reviewer must be published +- within two weeks after the month-long review period. Decisions made +- by the iSCSI extension item reviewer can be appealed through the IESG +- appeal process. +- +-13.5.3. IANA Registration +- +- Provided that the iSCSI extension item has either passed review or +- has been successfully appealed to the IESG, and the specification is +- published as an RFC, then IANA will register the iSCSI extension item +- and make the registration available to the community. +- +-13.5.4. Standard iSCSI extension item-label format +- +- The following character symbols are used iSCSI extension item-labels +- (the hexadecimal values represent Unicode code points): +- +- (a-z, A-Z) - letters +- (0-9) - digits +- "." (0x2e) - dot +- "-" (0x2d) - minus +- "+" (0x2b) - plus +- "@" (0x40) - commercial at +- "_" (0x5f) - underscore +- +- +- +- +-Satran, et al. Standards Track [Page 204] +- +-RFC 3720 iSCSI April 2004 +- +- +- An iSCSI extension item-label is a string of one or more characters +- that consist of letters, digits, dot, minus, plus, commercial at, or +- underscore. An iSCSI extension item-label MUST begin with a capital +- letter and must not exceed 63 characters. +- +-13.6. IANA Procedures for Registering iSCSI extension items +- +- The identity of the iSCSI extension item reviewer is communicated to +- the IANA by the IESG. Then, the IANA only acts in response to iSCSI +- extension item definitions that are approved by the iSCSI extension +- item reviewer and forwarded by the reviewer to the IANA for +- registration, or in response to a communication from the IESG that an +- iSCSI extension item definition appeal has overturned the iSCSI +- extension item reviewer's ruling. +- +-References +- +-Normative References +- +- [CAM] ANSI X3.232-199X, Common Access Method-3. +- +- [EUI] "Guidelines for 64-bit Global Identifier (EUI-64)", +- http: +- //standards.ieee.org/regauth/oui/tutorials/EUI64.html +- +- [OUI] "IEEE OUI and Company_Id Assignments", +- http://standards.ieee.org/regauth/oui +- +- [RFC791] Postel, J., "Internet Protocol", STD 5, RFC 791, +- September 1981. +- +- [RFC793] Postel, J., "Transmission Control Protocol", STD 7, +- RFC 793, September 1981. +- +- [RFC1035] Mockapetris, P., "Domain Names - Implementation and +- Specification", STD 13, RFC 1035, November 1987. +- +- [RFC1122] Braden, R., Ed., "Requirements for Internet Hosts- +- Communication Layer", STD 3, RFC 1122, October 1989. +- +- [RFC1510] Kohl, J. and C. Neuman, "The Kerberos Network +- Authentication Service (V5)", RFC 1510, September +- 1993. +- +- [RFC1737] Sollins, K. and L. Masinter "Functional Requirements +- for Uniform Resource Names"RFC 1737, December 1994. +- +- +- +- +- +-Satran, et al. Standards Track [Page 205] +- +-RFC 3720 iSCSI April 2004 +- +- +- [RFC1964] Linn, J., "The Kerberos Version 5 GSS-API Mechanism", +- RFC 1964, June 1996. +- +- [RFC1982] Elz, R. and R. Bush, "Serial Number Arithmetic", RFC +- 1982, August 1996. +- +- [RFC1994] Simpson, W., "PPP Challenge Handshake Authentication +- Protocol (CHAP)", RFC 1994, August 1996. +- +- [RFC2025] Adams, C., "The Simple Public-Key GSS-API Mechanism +- (SPKM)", RFC 2025, October 1996. +- +- [RFC2045] Borenstein, N. and N. Freed, "MIME (Multipurpose +- Internet Mail Extensions) Part One: Mechanisms for +- Specifying and Describing the Format of Internet +- Message Bodies", RFC 2045, November 1996. +- +- [RFC2119] Bradner, S. "Key Words for use in RFCs to Indicate +- Requirement Levels", BCP 14, RFC 2119, March 1997. +- +- [RFC2279] Yergeau, F., "UTF-8, a Transformation Format of ISO +- 10646", RFC 2279 October 1996. +- +- [RFC2373] Hinden, R. and S. Deering, "IP Version 6 Addressing +- Architecture", RFC 2373, July 1998. +- +- [RFC2396] Berners-Lee, T., Fielding, R. and L. Masinter "Uniform +- Resource Identifiers", RFC 2396, August 1998. +- +- [RFC2401] Kent, S. and R. Atkinson, "Security Architecture for +- the Internet Protocol", RFC 2401, November 1998. +- +- [RFC2404] Madson, C. and R. Glenn, "The Use of HMAC-SHA-1-96 +- within ESP and AH", RFC 2404, November 1998. +- +- [RFC2406] Kent, S. and R. Atkinson, "IP Encapsulating Security +- Payload (ESP)", RFC 2406, November 1998. +- +- [RFC2407] Piper, D., "The Internet IP Security Domain of +- Interpretation of ISAKMP", RFC 2407, November 1998. +- +- [RFC2409] Harkins, D. and D. Carrel, "The Internet Key Exchange +- (IKE)", RFC2409, November 1998. +- +- [RFC2434] Narten, T. and H. Alvestrand, "Guidelines for Writing +- an IANA Considerations Section in RFCs.", BCP 26, RFC +- 2434, October 1998. +- +- +- +- +-Satran, et al. Standards Track [Page 206] +- +-RFC 3720 iSCSI April 2004 +- +- +- [RFC2451] Pereira, R. and R. Adams " The ESP CBC-Mode Cipher +- Algorithms", RFC 2451, November 1998. +- +- [RFC2732] Hinden, R., Carpenter, B. and L. Masinter, "Format for +- Literal IPv6 Addresses in URL's", RFC 2451, December +- 1999. +- +- [RFC2945] Wu, T., "The SRP Authentication and Key Exchange +- System", RFC 2945, September 2000. +- +- [RFC3066] Alvestrand, H., "Tags for the Identification of +- Languages", STD 47, RFC 3066, January 2001. +- +- [RFC3454] Hoffman, P. and M. Blanchet, "Preparation of +- Internationalized Strings ("stringprep")", RFC 3454, +- December 2002. +- +- [RFC3566] Frankel, S. and H. Herbert, "The AES-XCBC-MAC-96 +- Algorithm and Its Use With IPsec", RFC 3566, September +- 2003. +- +- [RFC3686] Housley, R., "Using Advanced Encryption Standard (AES) +- Counter Mode with IPsec Encapsulating Security Payload +- (ESP)", RFC 3686, January 2004. +- +- [RFC3722] Bakke, M., "String Profile for Internet Small Computer +- Systems Interface (iSCSI) Names", RFC 3722, March +- 2004. +- +- [RFC3723] Aboba, B., Tseng, J., Walker, J., Rangan, V. and F. +- Travostino, "Securing Block Storage Protocols over +- IP", RFC 3723, March 2004. +- +- [SAM2] T10/1157D, SCSI Architecture Model - 2 (SAM-2). +- +- [SBC] NCITS.306-1998, SCSI-3 Block Commands (SBC). +- +- [SPC3] T10/1416-D, SCSI Primary Commands-3. +- +- [UNICODE] Unicode Standard Annex #15, "Unicode Normalization +- Forms", http://www.unicode.org/unicode/reports/tr15 +- +- +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 207] +- +-RFC 3720 iSCSI April 2004 +- +- +-Informative References +- +- [BOOT] P. Sarkar, et al., "Bootstrapping Clients using the +- iSCSI Protocol", Work in Progress, July 2003. +- +- [Castagnoli93] G. Castagnoli, S. Braeuer and M. Herrman "Optimization +- of Cyclic Redundancy-Check Codes with 24 and 32 Parity +- Bits", IEEE Transact. on Communications, Vol. 41, No. +- 6, June 1993. +- +- [CORD] Chadalapaka, M. and R. Elliott, "SCSI Command +- Ordering Considerations with iSCSI", Work in Progress. +- +- [RFC3347] Krueger, M., Haagens, R., Sapuntzakis, C. and M. +- Bakke, "Small Computer Systems Interface protocol over +- the Internet (iSCSI) Requirements and Design +- Considerations", RFC 3347, July 2002. +- +- [RFC3385] Sheinwald, D., Staran, J., Thaler, P. and V. Cavanna, +- "Internet Protocol Small Computer System Interface +- (iSCSI) Cyclic Redundancy Check (CRC)/Checksum +- Considerations", RFC 3385, September 2002. +- +- [RFC3721] Bakke M., Hafner, J., Hufferd, J., Voruganti, K. and +- M. Krueger, "Internet Small Computer Systems Interface +- (iSCSI) Naming and Discovery, RFC 3721, March 2004. +- +- [SEQ-EXT] Kent, S., "IP Encapsulating Security Payload (ESP)", +- Work in Progress, July 2002. +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 208] +- +-RFC 3720 iSCSI April 2004 +- +- +-Appendix A. Sync and Steering with Fixed Interval Markers +- +- This appendix presents a simple scheme for synchronization (PDU +- boundary retrieval). It uses markers that include synchronization +- information placed at fixed intervals in the TCP stream. +- +- A Marker consists of: +- +- Byte / 0 | 1 | 2 | 3 | +- / | | | | +- |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +- +---------------+---------------+---------------+---------------+ +- 0| Next-iSCSI-PDU-start pointer - copy #1 | +- +---------------+---------------+---------------+---------------+ +- 4| Next-iSCSI-PDU-start pointer - copy #2 | +- +---------------+---------------+---------------+---------------+ +- +- The Marker scheme uses payload byte stream counting that includes +- every byte placed by iSCSI in the TCP stream except for the markers +- themselves. It also excludes any bytes that TCP counts but are not +- originated by iSCSI. +- +- Markers MUST NOT be included in digest calculation. +- +- The Marker indicates the offset to the next iSCSI PDU header. The +- Marker is eight bytes in length and contains two 32-bit offset fields +- that indicate how many bytes to skip in the TCP stream in order to +- find the next iSCSI PDU header. The marker uses two copies of the +- pointer so that a marker that spans a TCP packet boundary should +- leave at least one valid copy in one of the packets. +- +- The structure and semantics of an inserted marker are independent of +- the marker interval. +- +- The use of markers is negotiable. The initiator and target MAY +- indicate their readiness to receive and/or send markers during login +- separately for each connection. The default is No. +- +-A.1. Markers At Fixed Intervals +- +- A marker is inserted at fixed intervals in the TCP byte stream. +- During login, each end of the iSCSI session specifies the interval at +- which it is willing to receive the marker, or it disables the marker +- altogether. If a receiver indicates that it desires a marker, the +- sender MAY agree (during negotiation) and provide the marker at the +- desired interval. However, in certain environments, a sender that +- does not provide markers to a receiver that wants markers may suffer +- an appreciable performance degradation. +- +- +- +-Satran, et al. Standards Track [Page 209] +- +-RFC 3720 iSCSI April 2004 +- +- +- The marker interval and the initial marker-less interval are counted +- in terms of the bytes placed in the TCP stream data by iSCSI. +- +- When reduced to iSCSI terms, markers MUST indicate the offset to a +- 4-byte word boundary in the stream. The least significant two bits +- of each marker word are reserved and are considered 0 for offset +- computation. +- +- Padding iSCSI PDU payloads to 4-byte word boundaries simplifies +- marker manipulation. +- +-A.2. Initial Marker-less Interval +- +- To enable the connection setup including the Login Phase negotiation, +- marking (if any) is only started at the first marker interval after +- the end of the Login Phase. However, in order to enable the marker +- inclusion and exclusion mechanism to work without knowledge of the +- length of the Login Phase, the first marker will be placed in the TCP +- stream as if the Marker-less interval had included markers. +- +- Thus, all markers appear in the stream at locations conforming to the +- formula: [(MI + 8) * n - 8] where MI = Marker Interval, n = integer +- number. +- +- For example, if the marker interval is 512 bytes and the login ended +- at byte 1003 (first iSCSI placed byte is 0), the first marker will be +- inserted after byte 1031 in the stream. +- +-A.3. Negotiation +- +- The following operational key=value pairs are used to negotiate the +- fixed interval markers. The direction (output or input) is relative +- to the initiator. +- +-A.3.1. OFMarker, IFMarker +- +- Use: IO +- Senders: Initiator and Target +- Scope: CO +- +- OFMarker= +- IFMarker= +- +- Default is No. +- +- Result function is AND. +- +- +- +- +- +-Satran, et al. Standards Track [Page 210] +- +-RFC 3720 iSCSI April 2004 +- +- +- OFMarker is used to turn on or off the initiator to target markers +- on the connection. IFMarker is used to turn on or off the target to +- initiator markers on the connection. +- +- Examples: +- +- I->OFMarker=Yes,IFMarker=Yes +- T->OFMarker=Yes,IFMarker=Yes +- +- Results in the Marker being used in both directions while: +- +- I->OFMarker=Yes,IFMarker=Yes +- T->OFMarker=Yes,IFMarker=No +- +- Results in Marker being used from the initiator to the target, but +- not from the target to initiator. +- +-A.3.2. OFMarkInt, IFMarkInt +- +- Use: IO +- Senders: Initiator and Target +- Scope: CO +- OFMarkInt is Irrelevant when: OFMarker=No +- IFMarkInt is Irrelevant when: IFMarker=No +- +- Offering: +- +- OFMarkInt= +- IFMarkInt= +- +- Responding: +- +- OFMarkInt=|Reject +- IFMarkInt=|Reject +- +- OFMarkInt is used to set the interval for the initiator to target +- markers on the connection. IFMarkInt is used to set the interval for +- the target to initiator markers on the connection. +- +- For the offering, the initiator or target indicates the minimum to +- maximum interval (in 4-byte words) it wants the markers for one or +- both directions. In case it only wants a specific value, only a +- single value has to be specified. The responder selects a value +- within the minimum and maximum offered or the only value offered or +- indicates through the xFMarker key=value its inability to set and/or +- receive markers. When the interval is unacceptable the responder +- answers with "Reject". Reject is resetting the marker function in +- the specified direction (Output or Input) to No. +- +- +- +-Satran, et al. Standards Track [Page 211] +- +-RFC 3720 iSCSI April 2004 +- +- +- The interval is measured from the end of a marker to the beginning of +- the next marker. For example, a value of 1024 means 1024 words (4096 +- bytes of iSCSI payload between markers). +- +- The default is 2048. +- +-Appendix B. Examples +- +-B.1. Read Operation Example +- +- +------------------+-----------------------+----------------------+ +- |Initiator Function| PDU Type | Target Function | +- +------------------+-----------------------+----------------------+ +- | Command request |SCSI Command (READ)>>> | | +- | (read) | | | +- +------------------+-----------------------+----------------------+ +- | | |Prepare Data Transfer | +- +------------------+-----------------------+----------------------+ +- | Receive Data | <<< SCSI Data-In | Send Data | +- +------------------+-----------------------+----------------------+ +- | Receive Data | <<< SCSI Data-In | Send Data | +- +------------------+-----------------------+----------------------+ +- | Receive Data | <<< SCSI Data-In | Send Data | +- +------------------+-----------------------+----------------------+ +- | | <<< SCSI Response |Send Status and Sense | +- +------------------+-----------------------+----------------------+ +- | Command Complete | | | +- +------------------+-----------------------+----------------------+ +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 212] +- +-RFC 3720 iSCSI April 2004 +- +- +-B.2. Write Operation Example +- +- +------------------+-----------------------+---------------------+ +- |Initiator Function| PDU Type | Target Function | +- +------------------+-----------------------+---------------------+ +- | Command request |SCSI Command (WRITE)>>>| Receive command | +- | (write) | | and queue it | +- +------------------+-----------------------+---------------------+ +- | | | Process old commands| +- +------------------+-----------------------+---------------------+ +- | | | Ready to process | +- | | <<< R2T | WRITE command | +- +------------------+-----------------------+---------------------+ +- | Send Data | SCSI Data-Out >>> | Receive Data | +- +------------------+-----------------------+---------------------+ +- | | <<< R2T | Ready for data | +- +------------------+-----------------------+---------------------+ +- | | <<< R2T | Ready for data | +- +------------------+-----------------------+---------------------+ +- | Send Data | SCSI Data-Out >>> | Receive Data | +- +------------------+-----------------------+---------------------+ +- | Send Data | SCSI Data-Out >>> | Receive Data | +- +------------------+-----------------------+---------------------+ +- | | <<< SCSI Response |Send Status and Sense| +- +------------------+-----------------------+---------------------+ +- | Command Complete | | | +- +------------------+-----------------------+---------------------+ +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 213] +- +-RFC 3720 iSCSI April 2004 +- +- +-B.3. R2TSN/DataSN Use Examples +- +- Output (write) data DataSN/R2TSN Example +- +- +------------------+-----------------------+----------------------+ +- |Initiator Function| PDU Type & Content | Target Function | +- +------------------+-----------------------+----------------------+ +- | Command request |SCSI Command (WRITE)>>>| Receive command | +- | (write) | | and queue it | +- +------------------+-----------------------+----------------------+ +- | | | Process old commands | +- +------------------+-----------------------+----------------------+ +- | | <<< R2T | Ready for data | +- | | R2TSN = 0 | | +- +------------------+-----------------------+----------------------+ +- | | <<< R2T | Ready for more data | +- | | R2TSN = 1 | | +- +------------------+-----------------------+----------------------+ +- | Send Data | SCSI Data-Out >>> | Receive Data | +- | for R2TSN 0 | DataSN = 0, F=0 | | +- +------------------+-----------------------+----------------------+ +- | Send Data | SCSI Data-Out >>> | Receive Data | +- | for R2TSN 0 | DataSN = 1, F=1 | | +- +------------------+-----------------------+----------------------+ +- | Send Data | SCSI Data >>> | Receive Data | +- | for R2TSN 1 | DataSN = 0, F=1 | | +- +------------------+-----------------------+----------------------+ +- | | <<< SCSI Response |Send Status and Sense | +- | | ExpDataSN = 0 | | +- +------------------+-----------------------+----------------------+ +- | Command Complete | | | +- +------------------+-----------------------+----------------------+ +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 214] +- +-RFC 3720 iSCSI April 2004 +- +- +- Input (read) data DataSN Example +- +- +------------------+-----------------------+----------------------+ +- |Initiator Function| PDU Type | Target Function | +- +------------------+-----------------------+----------------------+ +- | Command request |SCSI Command (READ)>>> | | +- | (read) | | | +- +------------------+-----------------------+----------------------+ +- | | | Prepare Data Transfer| +- +------------------+-----------------------+----------------------+ +- | Receive Data | <<< SCSI Data-In | Send Data | +- | | DataSN = 0, F=0 | | +- +------------------+-----------------------+----------------------+ +- | Receive Data | <<< SCSI Data-In | Send Data | +- | | DataSN = 1, F=0 | | +- +------------------+-----------------------+----------------------+ +- | Receive Data | <<< SCSI Data-In | Send Data | +- | | DataSN = 2, F=1 | | +- +------------------+-----------------------+----------------------+ +- | | <<< SCSI Response |Send Status and Sense | +- | | ExpDataSN = 3 | | +- +------------------+-----------------------+----------------------+ +- | Command Complete | | | +- +------------------+-----------------------+----------------------+ +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 215] +- +-RFC 3720 iSCSI April 2004 +- +- +- Bidirectional DataSN Example +- +- +------------------+-----------------------+----------------------+ +- |Initiator Function| PDU Type | Target Function | +- +------------------+-----------------------+----------------------+ +- | Command request |SCSI Command >>> | | +- | (Read-Write) | Read-Write | | +- +------------------+-----------------------+----------------------+ +- | | | Process old commands | +- +------------------+-----------------------+----------------------+ +- | | <<< R2T | Ready to process | +- | | R2TSN = 0 | WRITE command | +- +------------------+-----------------------+----------------------+ +- | * Receive Data | <<< SCSI Data-In | Send Data | +- | | DataSN = 1, F=0 | | +- +------------------+-----------------------+----------------------+ +- | * Receive Data | <<< SCSI Data-In | Send Data | +- | | DataSN = 2, F=1 | | +- +------------------+-----------------------+----------------------+ +- | * Send Data | SCSI Data-Out >>> | Receive Data | +- | for R2TSN 0 | DataSN = 0, F=1 | | +- +------------------+-----------------------+----------------------+ +- | | <<< SCSI Response |Send Status and Sense | +- | | ExpDataSN = 3 | | +- +------------------+-----------------------+----------------------+ +- | Command Complete | | | +- +------------------+-----------------------+----------------------+ +- +- *) Send data and Receive Data may be transferred simultaneously as in +- an atomic Read-Old-Write-New or sequentially as in an atomic +- Read-Update-Write (in the latter case the R2T may follow the received +- data). +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 216] +- +-RFC 3720 iSCSI April 2004 +- +- +- Unsolicited and immediate output (write) data with DataSN Example +- +- +------------------+-----------------------+----------------------+ +- |Initiator Function| PDU Type & Content | Target Function | +- +------------------+-----------------------+----------------------+ +- | Command request |SCSI Command (WRITE)>>>| Receive command | +- | (write) |F=0 | and data | +- |+ Immediate data | | and queue it | +- +------------------+-----------------------+----------------------+ +- | Send Unsolicited | SCSI Write Data >>> | Receive more Data | +- | Data | DataSN = 0, F=1 | | +- +------------------+-----------------------+----------------------+ +- | | | Process old commands | +- +------------------+-----------------------+----------------------+ +- | | <<< R2T | Ready for more data | +- | | R2TSN = 0 | | +- +------------------+-----------------------+----------------------+ +- | Send Data | SCSI Write Data >>> | Receive Data | +- | for R2TSN 0 | DataSN = 0, F=1 | | +- +------------------+-----------------------+----------------------+ +- | | <<< SCSI Response |Send Status and Sense | +- | | | | +- +------------------+-----------------------+----------------------+ +- | Command Complete | | | +- +------------------+-----------------------+----------------------+ +- +-B.4. CRC Examples +- +- N.B. all Values are Hexadecimal +- +- 32 bytes of zeroes: +- +- Byte: 0 1 2 3 +- +- 0: 00 00 00 00 +- ... +- 28: 00 00 00 00 +- +- CRC: aa 36 91 8a +- +- 32 bytes of ones: +- +- Byte: 0 1 2 3 +- +- 0: ff ff ff ff +- ... +- 28: ff ff ff ff +- +- +- +- +-Satran, et al. Standards Track [Page 217] +- +-RFC 3720 iSCSI April 2004 +- +- +- CRC: 43 ab a8 62 +- +- 32 bytes of incrementing 00..1f: +- +- Byte: 0 1 2 3 +- +- 0: 00 01 02 03 +- ... +- 28: 1c 1d 1e 1f +- +- CRC: 4e 79 dd 46 +- +- 32 bytes of decrementing 1f..00: +- +- Byte: 0 1 2 3 +- +- 0: 1f 1e 1d 1c +- ... +- 28: 03 02 01 00 +- +- CRC: 5c db 3f 11 +- +- An iSCSI - SCSI Read (10) Command PDU +- +- Byte: 0 1 2 3 +- +- 0: 01 c0 00 00 +- 4: 00 00 00 00 +- 8: 00 00 00 00 +- 12: 00 00 00 00 +- 16: 14 00 00 00 +- 20: 00 00 04 00 +- 24: 00 00 00 14 +- 28: 00 00 00 18 +- 32: 28 00 00 00 +- 36: 00 00 00 00 +- 40: 02 00 00 00 +- 44: 00 00 00 00 +- +- CRC: 56 3a 96 d9 +- +- +- +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 218] +- +-RFC 3720 iSCSI April 2004 +- +- +-Appendix C. Login Phase Examples +- +- In the first example, the initiator and target authenticate each +- other via Kerberos: +- +- I-> Login (CSG,NSG=0,1 T=1) +- InitiatorName=iqn.1999-07.com.os:hostid.77 +- TargetName=iqn.1999-07.com.example:diskarray.sn.88 +- AuthMethod=KRB5,SRP,None +- +- T-> Login (CSG,NSG=0,0 T=0) +- AuthMethod=KRB5 +- +- I-> Login (CSG,NSG=0,1 T=1) +- KRB_AP_REQ= +- +- (krb_ap_req contains the Kerberos V5 ticket and authenticator +- with MUTUAL-REQUIRED set in the ap-options field) +- +- If the authentication is successful, the target proceeds with: +- +- T-> Login (CSG,NSG=0,1 T=1) +- KRB_AP_REP= +- +- (krb_ap_rep is the Kerberos V5 mutual authentication reply) +- +- If the authentication is successful, the initiator may proceed +- with: +- +- I-> Login (CSG,NSG=1,0 T=0) FirstBurstLength=8192 +- T-> Login (CSG,NSG=1,0 T=0) FirstBurstLength=4096 +- MaxBurstLength=8192 +- I-> Login (CSG,NSG=1,0 T=0) MaxBurstLength=8192 +- ... more iSCSI Operational Parameters +- +- T-> Login (CSG,NSG=1,0 T=0) +- ... more iSCSI Operational Parameters +- +- And at the end: +- +- I-> Login (CSG,NSG=1,3 T=1) +- optional iSCSI parameters +- +- T-> Login (CSG,NSG=1,3 T=1) "login accept" +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 219] +- +-RFC 3720 iSCSI April 2004 +- +- +- If the initiator's authentication by the target is not +- successful, the target responds with: +- +- T-> Login "login reject" +- +- instead of the Login KRB_AP_REP message, and terminates the +- connection. +- +- If the target's authentication by the initiator is not +- successful, the initiator terminates the connection (without +- responding to the Login KRB_AP_REP message). +- +- In the next example only the initiator is authenticated by the +- target via Kerberos: +- +- I-> Login (CSG,NSG=0,1 T=1) +- InitiatorName=iqn.1999-07.com.os:hostid.77 +- TargetName=iqn.1999-07.com.example:diskarray.sn.88 +- AuthMethod=SRP,KRB5,None +- +- T-> Login-PR (CSG,NSG=0,0 T=0) +- AuthMethod=KRB5 +- +- I-> Login (CSG,NSG=0,1 T=1) +- KRB_AP_REQ=krb_ap_req +- +- (MUTUAL-REQUIRED not set in the ap-options field of krb_ap_req) +- +- If the authentication is successful, the target proceeds with: +- +- T-> Login (CSG,NSG=0,1 T=1) +- +- I-> Login (CSG,NSG=1,0 T=0) +- ... iSCSI parameters +- +- T-> Login (CSG,NSG=1,0 T=0) +- ... iSCSI parameters +- +- . . . +- +- T-> Login (CSG,NSG=1,3 T=1)"login accept" +- +- +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 220] +- +-RFC 3720 iSCSI April 2004 +- +- +- In the next example, the initiator and target authenticate each +- other via SPKM1: +- +- I-> Login (CSG,NSG=0,1 T=1) +- InitiatorName=iqn.1999-07.com.os:hostid.77 +- TargetName=iqn.1999-07.com.example:diskarray.sn.88 +- AuthMethod=SPKM1,KRB5,None +- +- T-> Login (CSG,NSG=0,0 T=0) +- AuthMethod=SPKM1 +- +- I-> Login (CSG,NSG=0,0 T=0) +- SPKM_REQ= +- +- (spkm-req is the SPKM-REQ token with the mutual-state bit in the +- options field of the REQ-TOKEN set) +- +- T-> Login (CSG,NSG=0,0 T=0) +- SPKM_REP_TI= +- +- If the authentication is successful, the initiator proceeds: +- +- I-> Login (CSG,NSG=0,1 T=1) +- SPKM_REP_IT= +- +- If the authentication is successful, the target proceeds with: +- +- T-> Login (CSG,NSG=0,1 T=1) +- +- The initiator may proceed: +- +- I-> Login (CSG,NSG=1,0 T=0) ... iSCSI parameters +- T-> Login (CSG,NSG=1,0 T=0) ... iSCSI parameters +- +- And at the end: +- +- I-> Login (CSG,NSG=1,3 T=1) +- optional iSCSI parameters +- +- T-> Login (CSG,NSG=1,3 T=1) "login accept" +- +- +- If the target's authentication by the initiator is not +- successful, the initiator terminates the connection (without +- responding to the Login SPKM_REP_TI message). +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 221] +- +-RFC 3720 iSCSI April 2004 +- +- +- If the initiator's authentication by the target is not +- successful, the target responds with: +- +- T-> Login "login reject" +- +- instead of the Login "proceed and change stage" message, and +- terminates the connection. +- +- +- In the next example, the initiator and target authenticate each +- other via SPKM2: +- +- I-> Login (CSG,NSG=0,0 T=0) +- InitiatorName=iqn.1999-07.com.os:hostid.77 +- TargetName=iqn.1999-07.com.example:diskarray.sn.88 +- AuthMethod=SPKM1,SPKM2 +- +- T-> Login-PR (CSG,NSG=0,0 T=0) +- AuthMethod=SPKM2 +- +- I-> Login (CSG,NSG=0,1 T=1) +- SPKM_REQ= +- +- (spkm-req is the SPKM-REQ token with the mutual-state bit in the +- options field of the REQ-TOKEN not set) +- +- If the authentication is successful, the target proceeds with: +- +- T-> Login (CSG,NSG=0,1 T=1) +- +- The initiator may proceed: +- +- I-> Login (CSG,NSG=1,0 T=0) +- ... iSCSI parameters +- +- T-> Login (CSG,NSG=1,0 T=0) +- ... iSCSI parameters +- +- And at the end: +- +- I-> Login (CSG,NSG=1,3 T=1) +- optional iSCSI parameters +- +- T-> Login (CSG,NSG=1,3 T=1) "login accept" +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 222] +- +-RFC 3720 iSCSI April 2004 +- +- +- In the next example, the initiator and target authenticate each +- other via SRP: +- +- I-> Login (CSG,NSG=0,1 T=1) +- InitiatorName=iqn.1999-07.com.os:hostid.77 +- TargetName=iqn.1999-07.com.example:diskarray.sn.88 +- AuthMethod=KRB5,SRP,None +- +- T-> Login-PR (CSG,NSG=0,0 T=0) +- AuthMethod=SRP +- +- I-> Login (CSG,NSG=0,0 T=0) +- SRP_U= +- TargetAuth=Yes +- +- T-> Login (CSG,NSG=0,0 T=0) +- SRP_GROUP=SRP-1536,SRP-1024 +- SRP_s= +- +- I-> Login (CSG,NSG=0,0 T=0) +- SRP_GROUP=SRP-1536 +- SRP_A= +- +- T-> Login (CSG,NSG=0,0 T=0) +- SRP_B= +- +- I-> Login (CSG,NSG=0,1 T=1) +- SRP_M= +- +- If the initiator authentication is successful, the target +- proceeds: +- +- T-> Login (CSG,NSG=0,1 T=1) +- SRP_HM= +- +- Where N, g, s, A, B, M, and H(A | M | K) are defined in [RFC2945]. +- +- If the target authentication is not successful, the initiator +- terminates the connection; otherwise, it proceeds. +- +- I-> Login (CSG,NSG=1,0 T=0) +- ... iSCSI parameters +- +- T-> Login (CSG,NSG=1,0 T=0) +- ... iSCSI parameters +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 223] +- +-RFC 3720 iSCSI April 2004 +- +- +- And at the end: +- +- I-> Login (CSG,NSG=1,3 T=1) +- optional iSCSI parameters +- +- T-> Login (CSG,NSG=1,3 T=1) "login accept" +- +- If the initiator authentication is not successful, the target +- responds with: +- +- T-> Login "login reject" +- +- Instead of the T-> Login SRP_HM= message and +- terminates the connection. +- +- In the next example, the initiator and target authenticate each +- other via SRP: +- +- I-> Login (CSG,NSG=0,1 T=1) +- InitiatorName=iqn.1999-07.com.os:hostid.77 +- TargetName=iqn.1999-07.com.example:diskarray.sn.88 +- AuthMethod=KRB5,SRP,None +- +- T-> Login-PR (CSG,NSG=0,0 T=0) +- AuthMethod=SRP +- +- I-> Login (CSG,NSG=0,0 T=0) +- SRP_U= +- TargetAuth=No +- +- T-> Login (CSG,NSG=0,0 T=0) +- SRP_GROUP=SRP-1536 +- SRP_s= +- +- I-> Login (CSG,NSG=0,0 T=0) +- SRP_GROUP=SRP-1536 +- SRP_A= +- +- T-> Login (CSG,NSG=0,0 T=0) +- SRP_B= +- +- I-> Login (CSG,NSG=0,1 T=1) +- SRP_M= +- +- If the initiator authentication is successful, the target +- proceeds: +- +- T-> Login (CSG,NSG=0,1 T=1) +- +- +- +-Satran, et al. Standards Track [Page 224] +- +-RFC 3720 iSCSI April 2004 +- +- +- +- I-> Login (CSG,NSG=1,0 T=0) +- ... iSCSI parameters +- +- T-> Login (CSG,NSG=1,0 T=0) +- ... iSCSI parameters +- +- And at the end: +- +- I-> Login (CSG,NSG=1,3 T=1) +- optional iSCSI parameters +- +- T-> Login (CSG,NSG=1,3 T=1) "login accept" +- +- In the next example the initiator and target authenticate each other +- via CHAP: +- +- I-> Login (CSG,NSG=0,0 T=0) +- InitiatorName=iqn.1999-07.com.os:hostid.77 +- TargetName=iqn.1999-07.com.example:diskarray.sn.88 +- AuthMethod=KRB5,CHAP,None +- +- T-> Login-PR (CSG,NSG=0,0 T=0) +- AuthMethod=CHAP +- +- I-> Login (CSG,NSG=0,0 T=0) +- CHAP_A= +- +- T-> Login (CSG,NSG=0,0 T=0) +- CHAP_A= +- CHAP_I= +- CHAP_C= +- +- I-> Login (CSG,NSG=0,1 T=1) +- CHAP_N= +- CHAP_R= +- CHAP_I= +- CHAP_C= +- +- +- +- +- +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 225] +- +-RFC 3720 iSCSI April 2004 +- +- +- If the initiator authentication is successful, the target +- proceeds: +- +- T-> Login (CSG,NSG=0,1 T=1) +- CHAP_N= +- CHAP_R= +- +- If the target authentication is not successful, the initiator +- aborts the connection; otherwise, it proceeds. +- +- I-> Login (CSG,NSG=1,0 T=0) +- ... iSCSI parameters +- T-> Login (CSG,NSG=1,0 T=0) +- ... iSCSI parameters +- +- And at the end: +- +- I-> Login (CSG,NSG=1,3 T=1) +- optional iSCSI parameters +- +- T-> Login (CSG,NSG=1,3 T=1) "login accept" +- +- If the initiator authentication is not successful, the target +- responds with: +- +- T-> Login "login reject" +- +- Instead of the Login CHAP_R= "proceed and change +- stage" message and terminates the connection. +- +- In the next example, only the initiator is authenticated by the +- target via CHAP: +- +- I-> Login (CSG,NSG=0,1 T=0) +- InitiatorName=iqn.1999-07.com.os:hostid.77 +- TargetName=iqn.1999-07.com.example:diskarray.sn.88 +- AuthMethod=KRB5,CHAP,None +- +- T-> Login-PR (CSG,NSG=0,0 T=0) +- AuthMethod=CHAP +- +- I-> Login (CSG,NSG=0,0 T=0) +- CHAP_A= +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 226] +- +-RFC 3720 iSCSI April 2004 +- +- +- T-> Login (CSG,NSG=0,0 T=0) +- CHAP_A= +- CHAP_I= +- CHAP_C= +- +- I-> Login (CSG,NSG=0,1 T=1) +- CHAP_N= +- CHAP_R= +- +- If the initiator authentication is successful, the target +- proceeds: +- +- T-> Login (CSG,NSG=0,1 T=1) +- +- I-> Login (CSG,NSG=1,0 T=0) +- ... iSCSI parameters +- +- T-> Login (CSG,NSG=1,0 T=0) +- ... iSCSI parameters +- +- And at the end: +- +- I-> Login (CSG,NSG=1,3 T=1) +- optional iSCSI parameters +- +- T-> Login (CSG,NSG=1,3 T=1) "login accept" +- +- In the next example, the initiator does not offer any security +- parameters. It therefore may offer iSCSI parameters on the Login PDU +- with the T bit set to 1, and the target may respond with a final +- Login Response PDU immediately: +- +- I-> Login (CSG,NSG=1,3 T=1) +- InitiatorName=iqn.1999-07.com.os:hostid.77 +- TargetName=iqn.1999-07.com.example:diskarray.sn.88 +- ... iSCSI parameters +- +- T-> Login (CSG,NSG=1,3 T=1) "login accept" +- ... ISCSI parameters +- +- In the next example, the initiator does offer security +- parameters on the Login PDU, but the target does not choose +- any (i.e., chooses the "None" values): +- +- I-> Login (CSG,NSG=0,1 T=1) +- InitiatorName=iqn.1999-07.com.os:hostid.77 +- TargetName=iqn.1999-07.com.example:diskarray.sn.88 +- AuthMethod=KRB5,SRP,None +- +- +- +-Satran, et al. Standards Track [Page 227] +- +-RFC 3720 iSCSI April 2004 +- +- +- +- T-> Login-PR (CSG,NSG=0,1 T=1) +- AuthMethod=None +- +- I-> Login (CSG,NSG=1,0 T=0) +- ... iSCSI parameters +- +- T-> Login (CSG,NSG=1,0 T=0) +- ... iSCSI parameters +- +- And at the end: +- +- I-> Login (CSG,NSG=1,3 T=1) +- optional iSCSI parameters +- +- T-> Login (CSG,NSG=1,3 T=1) "login accept" +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 228] +- +-RFC 3720 iSCSI April 2004 +- +- +-Appendix D. SendTargets Operation +- +- To reduce the amount of configuration required on an initiator, iSCSI +- provides the SendTargets text request. The initiator uses the +- SendTargets request to get a list of targets to which it may have +- access, as well as the list of addresses (IP address and TCP port) on +- which these targets may be accessed. +- +- To make use of SendTargets, an initiator must first establish one of +- two types of sessions. If the initiator establishes the session +- using the key "SessionType=Discovery", the session is a discovery +- session, and a target name does not need to be specified. Otherwise, +- the session is a normal, operational session. The SendTargets +- command MUST only be sent during the Full Feature Phase of a normal +- or discovery session. +- +- A system that contains targets MUST support discovery sessions on +- each of its iSCSI IP address-port pairs, and MUST support the +- SendTargets command on the discovery session. In a discovery +- session, a target MUST return all path information (target name and +- IP address-port pairs and portal group tags) for the targets on the +- target network entity which the requesting initiator is authorized to +- access. +- +- A target MUST support the SendTargets command on operational +- sessions; these will only return path information about the target to +- which the session is connected, and do not need to return information +- about other target names that may be defined in the responding +- system. +- +- An initiator MAY make use of the SendTargets as it sees fit. +- +- A SendTargets command consists of a single Text request PDU. This +- PDU contains exactly one text key and value. The text key MUST be +- SendTargets. The expected response depends upon the value, as well +- as whether the session is a discovery or operational session. +- +- The value must be one of: +- +- All +- +- The initiator is requesting that information on all relevant +- targets known to the implementation be returned. This value +- MUST be supported on a discovery session, and MUST NOT be +- supported on an operational session. +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 229] +- +-RFC 3720 iSCSI April 2004 +- +- +- +- +- If an iSCSI target name is specified, the session should respond +- with addresses for only the named target, if possible. This +- value MUST be supported on discovery sessions. A discovery +- session MUST be capable of returning addresses for those +- targets that would have been returned had value=All had been +- designated. +- +- +- +- The session should only respond with addresses for the target to +- which the session is logged in. This MUST be supported on +- operational sessions, and MUST NOT return targets other than +- the one to which the session is logged in. +- +- The response to this command is a text response that contains a list +- of zero or more targets and, optionally, their addresses. Each +- target is returned as a target record. A target record begins with +- the TargetName text key, followed by a list of TargetAddress text +- keys, and bounded by the end of the text response or the next +- TargetName key, which begins a new record. No text keys other than +- TargetName and TargetAddress are permitted within a SendTargets +- response. +- +- For the format of the TargetName, see Section 12.4 TargetName. +- +- In a discovery session, a target MAY respond to a SendTargets request +- with its complete list of targets, or with a list of targets that is +- based on the name of the initiator logged in to the session. +- +- A SendTargets response MUST NOT contain target names if there are no +- targets for the requesting initiator to access. +- +- Each target record returned includes zero or more TargetAddress +- fields. +- +- Each target record starts with one text key of the form: +- +- TargetName= +- +- Followed by zero or more address keys of the form: +- +- TargetAddress=[:], +- +- +- The hostname-or-ipaddress contains a domain name, IPv4 address, or +- IPv6 address, as specified for the TargetAddress key. +- +- +- +-Satran, et al. Standards Track [Page 230] +- +-RFC 3720 iSCSI April 2004 +- +- +- A hostname-or-ipaddress duplicated in TargetAddress responses for a +- given node (the port is absent or equal) would probably indicate that +- multiple address families are in use at once (IPV6 and IPV4). +- +- Each TargetAddress belongs to a portal group, identified by its +- numeric portal group tag (as in Section 12.9 TargetPortalGroupTag). +- The iSCSI target name, together with this tag, constitutes the SCSI +- port identifier; the tag only needs to be unique within a given +- target's name list of addresses. +- +- Multiple-connection sessions can span iSCSI addresses that belong to +- the same portal group. +- +- Multiple-connection sessions cannot span iSCSI addresses that belong +- to different portal groups. +- +- If a SendTargets response reports an iSCSI address for a target, it +- SHOULD also report all other addresses in its portal group in the +- same response. +- +- A SendTargets text response can be longer than a single Text Response +- PDU, and makes use of the long text responses as specified. +- +- After obtaining a list of targets from the discovery target session, +- an iSCSI initiator may initiate new sessions to log in to the +- discovered targets for full operation. The initiator MAY keep the +- discovery session open, and MAY send subsequent SendTargets commands +- to discover new targets. +- +- Examples: +- +- This example is the SendTargets response from a single target that +- has no other interface ports. +- +- Initiator sends text request that contains: +- +- SendTargets=All +- +- Target sends a text response that contains: +- +- TargetName=iqn.1993-11.com.example:diskarray.sn.8675309 +- +- All the target had to return in the simple case was the target name. +- It is assumed by the initiator that the IP address and TCP port for +- this target are the same as used on the current connection to the +- default iSCSI target. +- +- +- +- +- +-Satran, et al. Standards Track [Page 231] +- +-RFC 3720 iSCSI April 2004 +- +- +- The next example has two internal iSCSI targets, each accessible via +- two different ports with different IP addresses. The following is +- the text response: +- +- TargetName=iqn.1993-11.com.example:diskarray.sn.8675309 +- TargetAddress=10.1.0.45:3000,1 TargetAddress=10.1.1.45:3000,2 +- TargetName=iqn.1993-11.com.example:diskarray.sn.1234567 +- TargetAddress=10.1.0.45:3000,1 TargetAddress=10.1.1.45:3000,2 +- +- Both targets share both addresses; the multiple addresses are likely +- used to provide multi-path support. The initiator may connect to +- either target name on either address. Each of the addresses has its +- own portal group tag; they do not support spanning +- multiple-connection sessions with each other. Keep in mind that the +- portal group tags for the two named targets are independent of one +- another; portal group "1" on the first target is not necessarily the +- same as portal group "1" on the second target. +- +- In the above example, a DNS host name or an IPv6 address could have +- been returned instead of an IPv4 address. +- +- The next text response shows a target that supports spanning sessions +- across multiple addresses, and further illustrates the use of the +- portal group tags: +- +- TargetName=iqn.1993-11.com.example:diskarray.sn.8675309 +- +- TargetAddress=10.1.0.45:3000,1 TargetAddress=10.1.1.46:3000,1 +- TargetAddress=10.1.0.47:3000,2 TargetAddress=10.1.1.48:3000,2 +- TargetAddress=10.1.1.49:3000,3 +- +- In this example, any of the target addresses can be used to reach the +- same target. A single-connection session can be established to any +- of these TCP addresses. A multiple-connection session could span +- addresses .45 and .46 or .47 and .48, but cannot span any other +- combination. A TargetAddress with its own tag (.49) cannot be +- combined with any other address within the same session. +- +- This SendTargets response does not indicate whether .49 supports +- multiple connections per session; it is communicated via the +- MaxConnections text key upon login to the target. +- +- +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 232] +- +-RFC 3720 iSCSI April 2004 +- +- +-Appendix E. Algorithmic Presentation of Error Recovery Classes +- +- This appendix illustrates the error recovery classes using a +- pseudo-programming-language. The procedure names are chosen to be +- obvious to most implementers. Each of the recovery classes described +- has initiator procedures as well as target procedures. These +- algorithms focus on outlining the mechanics of error recovery +- classes, and do not exhaustively describe all other aspects/cases. +- Examples of this approach are: +- +- +- - Handling for only certain Opcode types is shown. +- +- - Only certain reason codes (e.g., Recovery in Logout command) +- are outlined. +- +- - Resultant cases, such as recovery of Synchronization on a +- header digest error are considered out-of-scope in these +- algorithms. In this particular example, a header digest error +- may lead to connection recovery if some type of sync and +- steering layer is not implemented. +- +- These algorithms strive to convey the iSCSI error recovery concepts +- in the simplest terms, and are not designed to be optimal. +- +-E.1. General Data Structure and Procedure Description +- +- This section defines the procedures and data structures that are +- commonly used by all the error recovery algorithms. The structures +- may not be the exhaustive representations of what is required for a +- typical implementation. +- +- Data structure definitions - +- struct TransferContext { +- int TargetTransferTag; +- int ExpectedDataSN; +- }; +- +- struct TCB { /* task control block */ +- Boolean SoFarInOrder; +- int ExpectedDataSN; /* used for both R2Ts, and Data */ +- int MissingDataSNList[MaxMissingDPDU]; +- Boolean FbitReceived; +- Boolean StatusXferd; +- Boolean CurrentlyAllegiant; +- int ActiveR2Ts; +- int Response; +- char *Reason; +- +- +- +-Satran, et al. Standards Track [Page 233] +- +-RFC 3720 iSCSI April 2004 +- +- +- struct TransferContext +- TransferContextList[MaxOutStandingR2T]; +- int InitiatorTaskTag; +- int CmdSN; +- +- int SNACK_Tag; +- +- }; +- +- struct Connection { +- struct Session SessionReference; +- Boolean SoFarInOrder; +- int CID; +- int State; +- +- int CurrentTimeout; +- int ExpectedStatSN; +- int MissingStatSNList[MaxMissingSPDU]; +- Boolean PerformConnectionCleanup; +- }; +- +- struct Session { +- int NumConnections; +- int CmdSN; +- int Maxconnections; +- int ErrorRecoveryLevel; +- struct iSCSIEndpoint OtherEndInfo; +- struct Connection ConnectionList[MaxSupportedConns]; +- }; +- +- Procedure descriptions - +- Receive-a-In-PDU(transport connection, inbound PDU); +- check-basic-validity(inbound PDU); +- Start-Timer(timeout handler, argument, timeout value); +- Build-And-Send-Reject(transport connection, bad PDU, reason code); +- +-E.2. Within-command Error Recovery Algorithms +- +-E.2.1. Procedure Descriptions +- +- Recover-Data-if-Possible(last required DataSN, task control +- block); +- Build-And-Send-DSnack(task control block); +- Build-And-Send-RDSnack(task control block); +- Build-And-Send-Abort(task control block); +- SCSI-Task-Completion(task control block); +- Build-And-Send-A-Data-Burst(transport connection, data-descriptor, +- task control block); +- +- +- +-Satran, et al. Standards Track [Page 234] +- +-RFC 3720 iSCSI April 2004 +- +- +- Build-And-Send-R2T(transport connection, data-descriptor, +- task control block); +- Build-And-Send-Status(transport connection, task control block); +- Transfer-Context-Timeout-Handler(transfer context); +- +- +- Notes: +- +- - One procedure used in this section: Handle-Status-SNACK- +- request is defined in Within-connection recovery algorithms. +- +- - The Response processing pseudo-code, shown in the target +- algorithms, applies to all solicited PDUs that carry StatSN - +- SCSI Response, Text Response etc. +- +-E.2.2. Initiator Algorithms +- +-Recover-Data-if-Possible(LastRequiredDataSN, TCB) +-{ +- if (operational ErrorRecoveryLevel > 0) { +- if (# of missing PDUs is trackable) { +- Note the missing DataSNs in TCB. +- if (the task spanned a change in +- MaxRecvDataSegmentLength) { +- if (TCB.StatusXferd is TRUE) +- drop the status PDU; +- Build-And-Send-RDSnack(TCB); +- } else { +- Build-And-Send-DSnack(TCB); +- } +- } else { +- TCB.Reason = "Protocol service CRC error"; +- } +- } else { +- TCB.Reason = "Protocol service CRC error"; +- } +- if (TCB.Reason == "Protocol service CRC error") { +- Clear the missing PDU list in the TCB. +- if (TCB.StatusXferd is not TRUE) +- Build-And-Send-Abort(TCB); +- } +-} +- +-Receive-a-In-PDU(Connection, CurrentPDU) +-{ +- check-basic-validity(CurrentPDU); +- if (Header-Digest-Bad) discard, return; +- Retrieve TCB for CurrentPDU.InitiatorTaskTag. +- +- +- +-Satran, et al. Standards Track [Page 235] +- +-RFC 3720 iSCSI April 2004 +- +- +- if ((CurrentPDU.type == Data) +- or (CurrentPDU.type = R2T)) { +- if (Data-Digest-Bad for Data) { +- send-data-SNACK = TRUE; +- LastRequiredDataSN = CurrentPDU.DataSN; +- } else { +- if (TCB.SoFarInOrder = TRUE) { +- if (current DataSN is expected) { +- Increment TCB.ExpectedDataSN. +- } else { +- +- TCB.SoFarInOrder = FALSE; +- send-data-SNACK = TRUE; +- } +- } else { +- if (current DataSN was considered missing) { +- remove current DataSN from missing PDU list. +- } else if (current DataSN is higher than expected) +-{ +- send-data-SNACK = TRUE; +- } else { +- discard, return; +- } +- Adjust TCB.ExpectedDataSN if appropriate. +- } +- LastRequiredDataSN = CurrentPDU.DataSN - 1; +- } +- if (send-data-SNACK is TRUE and +- task is not already considered failed) { +- Recover-Data-if-Possible(LastRequiredDataSN, TCB); +- } +- if (missing data PDU list is empty) { +- TCB.SoFarInOrder = TRUE; +- } +- if (CurrentPDU.type == R2T) { +- Increment ActiveR2Ts for this task. +- +- Create a data-descriptor for the data burst. +- Build-And-Send-A-Data-Burst(Connection, data-descriptor, +- +- TCB); +- } +- } else if (CurrentPDU.type == Response) { +- if (Data-Digest-Bad) { +- send-status-SNACK = TRUE; +- } else { +- TCB.StatusXferd = TRUE; +- Store the status information in TCB. +- +- +- +-Satran, et al. Standards Track [Page 236] +- +-RFC 3720 iSCSI April 2004 +- +- +- if (ExpDataSN does not match) { +- TCB.SoFarInOrder = FALSE; +- Recover-Data-if-Possible(current DataSN, TCB); +- } +- if (missing data PDU list is empty) { +- TCB.SoFarInOrder = TRUE; +- } +- } +- } else { /* REST UNRELATED TO WITHIN-COMMAND-RECOVERY, NOT +- SHOWN */ +- } +- if ((TCB.SoFarInOrder == TRUE) and +- (TCB.StatusXferd == TRUE)) { +- SCSI-Task-Completion(TCB); +- } +-} +- +-E.2.3. Target Algorithms +- +-Receive-a-In-PDU(Connection, CurrentPDU) +-{ +- check-basic-validity(CurrentPDU); +- if (Header-Digest-Bad) discard, return; +- Retrieve TCB for CurrentPDU.InitiatorTaskTag. +- if (CurrentPDU.type == Data) { +- Retrieve TContext from CurrentPDU.TargetTransferTag; +- if (Data-Digest-Bad) { +- Build-And-Send-Reject(Connection, CurrentPDU, +- Payload-Digest-Error); +- Note the missing data PDUs in MissingDataRange[]. +- send-recovery-R2T = TRUE; +- } else { +- if (current DataSN is not expected) { +- Note the missing data PDUs in MissingDataRange[]. +- send-recovery-R2T = TRUE; +- } +- if (CurrentPDU.Fbit == TRUE) { +- if (current PDU is solicited) { +- Decrement TCB.ActiveR2Ts. +- } +- if ((current PDU is unsolicited and +- data received is less than I/O length and +- data received is less than FirstBurstLength) +- or (current PDU is solicited and the length of +- this burst is less than expected)) { +- send-recovery-R2T = TRUE; +- Note the missing data in MissingDataRange[]. +- } +- +- +- +-Satran, et al. Standards Track [Page 237] +- +-RFC 3720 iSCSI April 2004 +- +- +- } +- } +- Increment TContext.ExpectedDataSN. +- if (send-recovery-R2T is TRUE and +- task is not already considered failed) { +- if (operational ErrorRecoveryLevel > 0) { +- Increment TCB.ActiveR2Ts. +- Create a data-descriptor for the data burst +- from MissingDataRange. +- Build-And-Send-R2T(Connection, data-descriptor, TCB); +- } else { +- if (current PDU is the last unsolicited) +- TCB.Reason = "Not enough unsolicited data"; +- else +- TCB.Reason = "Protocol service CRC error"; +- } +- } +- if (TCB.ActiveR2Ts == 0) { +- Build-And-Send-Status(Connection, TCB); +- } +- } else if (CurrentPDU.type == SNACK) { +- snack-failure = FALSE; +- if (operational ErrorRecoveryLevel > 0) { +- if (CurrentPDU.type == Data/R2T) { +- if (the request is satisfiable) { +- +- if (request for Data) { +- Create a data-descriptor for the data burst +- from BegRun and RunLength. +- Build-And-Send-A-Data-Burst(Connection, +- +- data-descriptor, TCB); +- } else { /* R2T */ +- Create a data-descriptor for the data burst +- from BegRun and RunLength. +- Build-And-Send-R2T(Connection, data-descriptor, +- TCB); +- } +- } else { +- snack-failure = TRUE; +- } +- } else if (CurrentPDU.type == status) { +- Handle-Status-SNACK-request(Connection, CurrentPDU); +- } else if (CurrentPDU.type == DataACK) { +- Consider all data upto CurrentPDU.BegRun as +- acknowledged. +- Free up the retransmission resources for that data. +- } else if (CurrentPDU.type == R-Data SNACK) { +- +- +- +-Satran, et al. Standards Track [Page 238] +- +-RFC 3720 iSCSI April 2004 +- +- +- Create a data descriptor for a data burst covering +- all unacknowledged data. +- Build-And-Send-A-Data-Burst(Connection, +- data-descriptor, TCB); +- TCB.SNACK_Tag = CurrentPDU.SNACK_Tag; +- if (there's no more data to send) { +- Build-And-Send-Status(Connection, TCB); +- } +- } +- } else { /* operational ErrorRecoveryLevel = 0 */ +- snack-failure = TRUE; +- +- } +- if (snack-failure == TRUE) { +- Build-And-Send-Reject(Connection, CurrentPDU, +- SNACK-Reject); +- if (TCB.StatusXferd != TRUE) { +- TCB.Reason = "SNACK Rejected"; +- Build-And-Send-Status(Connection, TCB); +- } +- } +- +- } else { /* REST UNRELATED TO WITHIN-COMMAND-RECOVERY, NOT SHOWN */ +- } +-} +- +-Transfer-Context-Timeout-Handler(TContext) +-{ +- Retrieve TCB and Connection from TContext. +- Decrement TCB.ActiveR2Ts. +- if (operational ErrorRecoveryLevel > 0 and +- task is not already considered failed) { +- Note the missing data PDUs in MissingDataRange[]. +- Create a data-descriptor for the data burst +- from MissingDataRange[]. +- Build-And-Send-R2T(Connection, data-descriptor, TCB); +- } else { +- TCB.Reason = "Protocol service CRC error"; +- if (TCB.ActiveR2Ts = 0) { +- Build-And-Send-Status(Connection, TCB); +- } +- } +-} +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 239] +- +-RFC 3720 iSCSI April 2004 +- +- +-E.3. Within-connection Recovery Algorithms +- +-E.3.1. Procedure Descriptions +- +-Procedure descriptions: +-Recover-Status-if-Possible(transport connection, +- currently received PDU); +-Evaluate-a-StatSN(transport connection, currently received PDU); +-Retransmit-Command-if-Possible(transport connection, CmdSN); +-Build-And-Send-SSnack(transport connection); +-Build-And-Send-Command(transport connection, task control block); +-Command-Acknowledge-Timeout-Handler(task control block); +-Status-Expect-Timeout-Handler(transport connection); +-Build-And-Send-Nop-Out(transport connection); +-Handle-Status-SNACK-request(transport connection, status SNACK +-PDU); +-Retransmit-Status-Burst(status SNACK, task control block); +-Is-Acknowledged(beginning StatSN, run length); +- +-Implementation-specific tunables: +-InitiatorProactiveSNACKEnabled +- +- Notes: +- +- - The initiator algorithms only deal with unsolicited Nop-In PDUs +- for generating status SNACKs. A solicited Nop-In PDU has an +- assigned StatSN, which, when out of order, could trigger the +- out of order StatSN handling in Within-command algorithms, +- again leading to Recover-Status-if-Possible. +- +- +- - The pseudo-code shown may result in the retransmission of +- unacknowledged commands in more cases than necessary. This +- will not, however, affect the correctness of the operation +- because the target is required to discard the duplicate CmdSNs. +- +- - The procedure Build-And-Send-Async is defined in the Connection +- recovery algorithms. +- +- - The procedure Status-Expect-Timeout-Handler describes how +- initiators may proactively attempt to retrieve the Status if +- they so choose. This procedure is assumed to be triggered much +- before the standard ULP timeout. +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 240] +- +-RFC 3720 iSCSI April 2004 +- +- +-E.3.2. Initiator Algorithms +- +-Recover-Status-if-Possible(Connection, CurrentPDU) +-{ +- if ((Connection.state == LOGGED_IN) and +- connection is not already considered failed) { +- if (operational ErrorRecoveryLevel > 0) { +- if (# of missing PDUs is trackable) { +- Note the missing StatSNs in Connection +- that were not already requested with SNACK; +- Build-And-Send-SSnack(Connection); +- } else { +- Connection.PerformConnectionCleanup = TRUE; +- } +- } else { +- Connection.PerformConnectionCleanup = TRUE; +- } +- if (Connection.PerformConnectionCleanup == TRUE) { +- Start-Timer(Connection-Cleanup-Handler, Connection, 0); +- } +- } +-} +- +-Retransmit-Command-if-Possible(Connection, CmdSN) +-{ +- +- if (operational ErrorRecoveryLevel > 0) { +- Retrieve the InitiatorTaskTag, and thus TCB for the CmdSN. +- Build-And-Send-Command(Connection, TCB); +- } +-} +- +-Evaluate-a-StatSN(Connection, CurrentPDU) +-{ +- send-status-SNACK = FALSE; +- if (Connection.SoFarInOrder == TRUE) { +- if (current StatSN is the expected) { +- Increment Connection.ExpectedStatSN. +- } else { +- Connection.SoFarInOrder = FALSE; +- send-status-SNACK = TRUE; +- } +- } else { +- if (current StatSN was considered missing) { +- remove current StatSN from the missing list. +- } else { +- if (current StatSN is higher than expected){ +- send-status-SNACK = TRUE; +- +- +- +-Satran, et al. Standards Track [Page 241] +- +-RFC 3720 iSCSI April 2004 +- +- +- } else { +- send-status-SNACK = FALSE; +- discard the PDU; +- } +- } +- Adjust Connection.ExpectedStatSN if appropriate. +- if (missing StatSN list is empty) { +- Connection.SoFarInOrder = TRUE; +- } +- } +- return send-status-SNACK; +-} +- +-Receive-a-In-PDU(Connection, CurrentPDU) +-{ +- check-basic-validity(CurrentPDU); +- if (Header-Digest-Bad) discard, return; +- Retrieve TCB for CurrentPDU.InitiatorTaskTag. +- if (CurrentPDU.type == Nop-In) { +- if (the PDU is unsolicited) { +- if (current StatSN is not expected) { +- Recover-Status-if-Possible(Connection, +- CurrentPDU); +- } +- if (current ExpCmdSN is not Session.CmdSN) { +- Retransmit-Command-if-Possible(Connection, +- CurrentPDU.ExpCmdSN); +- } +- } +- } else if (CurrentPDU.type == Reject) { +- if (it is a data digest error on immediate data) { +- Retransmit-Command-if-Possible(Connection, +- CurrentPDU.BadPDUHeader.CmdSN); +- } +- } else if (CurrentPDU.type == Response) { +- send-status-SNACK = Evaluate-a-StatSN(Connection, +- CurrentPDU); +- if (send-status-SNACK == TRUE) +- Recover-Status-if-Possible(Connection, CurrentPDU); +- } else { /* REST UNRELATED TO WITHIN-CONNECTION-RECOVERY, +- * NOT SHOWN */ +- } +-} +- +-Command-Acknowledge-Timeout-Handler(TCB) +-{ +- Retrieve the Connection for TCB. +- Retransmit-Command-if-Possible(Connection, TCB.CmdSN); +- +- +- +-Satran, et al. Standards Track [Page 242] +- +-RFC 3720 iSCSI April 2004 +- +- +-} +- +-Status-Expect-Timeout-Handler(Connection) +-{ +- if (operational ErrorRecoveryLevel > 0) { +- Build-And-Send-Nop-Out(Connection); +- } else if (InitiatorProactiveSNACKEnabled){ +- if ((Connection.state == LOGGED_IN) and +- connection is not already considered failed) { +- Build-And-Send-SSnack(Connection); +- } +- } +-} +- +-E.3.3. Target Algorithms +- +-Handle-Status-SNACK-request(Connection, CurrentPDU) +-{ +- if (operational ErrorRecoveryLevel > 0) { +- if (request for an acknowledged run) { +- Build-And-Send-Reject(Connection, CurrentPDU, +- Protocol-Error); +- } else if (request for an untransmitted run) { +- discard, return; +- } else { +- Retransmit-Status-Burst(CurrentPDU, TCB); +- } else { +- Build-And-Send-Async(Connection, DroppedConnection, +- DefaultTime2Wait, +- DefaultTime2Retain); +- } +-} +- +-E.4. Connection Recovery Algorithms +- +-E.4.1. Procedure Descriptions +- +-Build-And-Send-Async(transport connection, reason code, +- minimum time, maximum time); +-Pick-A-Logged-In-Connection(session); +-Build-And-Send-Logout(transport connection, logout connection +- identifier, reason code); +-PerformImplicitLogout(transport connection, logout connection +- identifier, target information); +-PerformLogin(transport connection, target information); +-CreateNewTransportConnection(target information); +-Build-And-Send-Command(transport connection, task control block); +-Connection-Cleanup-Handler(transport connection); +- +- +- +-Satran, et al. Standards Track [Page 243] +- +-RFC 3720 iSCSI April 2004 +- +- +-Connection-Resource-Timeout-Handler(transport connection); +-Quiesce-And-Prepare-for-New-Allegiance(session, task control +-block); +-Build-And-Send-Logout-Response(transport connection, +- CID of connection in recovery, reason +-code); +-Build-And-Send-TaskMgmt-Response(transport connection, +- task mgmt command PDU, response code); +-Establish-New-Allegiance(task control block, transport +-connection); +-Schedule-Command-To-Continue(task control block); +- +-Notes: +- - Transport exception conditions, such as unexpected connection +- termination, connection reset, and hung connection while the +- connection is in the full-feature phase, are all assumed to be +- asynchronously signaled to the iSCSI layer using the +- Transport_Exception_Handler procedure. +- +-E.4.2. Initiator Algorithms +- +- Receive-a-In-PDU(Connection, CurrentPDU) { +- check-basic-validity(CurrentPDU); +- if (Header-Digest-Bad) discard, return; +- +- Retrieve TCB from CurrentPDU.InitiatorTaskTag. +- if (CurrentPDU.type == Async) { +- if (CurrentPDU.AsyncEvent == ConnectionDropped) { +- Retrieve the AffectedConnection for +- CurrentPDU.Parameter1. +- AffectedConnection.CurrentTimeout = +- CurrentPDU.Parameter3; +- AffectedConnection.State = CLEANUP_WAIT; +- Start-Timer(Connection-Cleanup-Handler, +- AffectedConnection, +- CurrentPDU.Parameter2); +- } else if (CurrentPDU.AsyncEvent == LogoutRequest)) { +- AffectedConnection = Connection; +- AffectedConnection.State = LOGOUT_REQUESTED; +- AffectedConnection.PerformConnectionCleanup = TRUE; +- AffectedConnection.CurrentTimeout = +- CurrentPDU.Parameter3; +- Start-Timer(Connection-Cleanup-Handler, +- AffectedConnection, 0); +- } else if (CurrentPDU.AsyncEvent == SessionDropped)) { +- for (each Connection) { +- Connection.State = CLEANUP_WAIT; +- Connection.CurrentTimeout = CurrentPDU.Parameter3; +- +- +- +-Satran, et al. Standards Track [Page 244] +- +-RFC 3720 iSCSI April 2004 +- +- +- Start-Timer(Connection-Cleanup-Handler, +- Connection, CurrentPDU.Parameter2); +- } +- Session.state = FAILED; +- } +- +- } else if (CurrentPDU.type == LogoutResponse) { +- Retrieve the CleanupConnection for CurrentPDU.CID. +- if (CurrentPDU.Response = failure) { +- CleanupConnection.State = CLEANUP_WAIT; +- } else { +- CleanupConnection.State = FREE; +- } +- } else if (CurrentPDU.type == LoginResponse) { +- if (this is a response to an implicit Logout) { +- Retrieve the CleanupConnection. +- if (successful) { +- CleanupConnection.State = FREE; +- Connection.State = LOGGED_IN; +- } else { +- CleanupConnection.State = CLEANUP_WAIT; +- DestroyTransportConnection(Connection); +- } +- } +- } else { /* REST UNRELATED TO CONNECTION-RECOVERY, +- +- * NOT SHOWN */ +- } +- if (CleanupConnection.State == FREE) { +- for (each command that was active on CleanupConnection) { +- /* Establish new connection allegiance */ +- NewConnection = Pick-A-Logged-In-Connection(Session); +- Build-And-Send-Command(NewConnection, TCB); +- } +- } } +- +- Connection-Cleanup-Handler(Connection) { +- Retrieve Session from Connection. +- if (Connection can still exchange iSCSI PDUs) { +- NewConnection = Connection; +- } else { +- Start-Timer(Connection-Resource-Timeout-Handler, +- Connection, Connection.CurrentTimeout); +- if (there are other logged-in connections) { +- NewConnection = Pick-A-Logged-In- +- Connection(Session); +- } else { +- NewConnection = +- +- +- +-Satran, et al. Standards Track [Page 245] +- +-RFC 3720 iSCSI April 2004 +- +- +- CreateTransportConnection(Session.OtherEndInfo); +- Initiate an implicit Logout on NewConnection for +- Connection.CID. +- return; +- } +- } +- Build-And-Send-Logout(NewConnection, Connection.CID, +- RecoveryRemove); } +- +- Transport_Exception_Handler(Connection) { +- Connection.PerformConnectionCleanup = TRUE; +- if (the event is an unexpected transport disconnect) { +- Connection.State = CLEANUP_WAIT; +- +- Connection.CurrentTimeout = DefaultTime2Retain; +- Start-Timer(Connection-Cleanup-Handler, Connection, +- DefaultTime2Wait); +- +- } else { +- Connection.State = FREE; +- } } +- +-E.4.3. Target Algorithms +- +- Receive-a-In-PDU(Connection, CurrentPDU) +- { +- check-basic-validity(CurrentPDU); +- if (Header-Digest-Bad) discard, return; +- else if (Data-Digest-Bad) { +- Build-And-Send-Reject(Connection, CurrentPDU, +- Payload-Digest-Error); +- discard, return; +- } +- Retrieve TCB and Session. +- if (CurrentPDU.type == Logout) { +- if (CurrentPDU.ReasonCode = RecoveryRemove) { +- Retrieve the CleanupConnection from CurrentPDU.CID). +- for (each command active on CleanupConnection) { +- Quiesce-And-Prepare-for-New-Allegiance(Session, +- TCB); +- TCB.CurrentlyAllegiant = FALSE; +- } +- Cleanup-Connection-State(CleanupConnection); +- if ((quiescing successful) and (cleanup successful)) { +- Build-And-Send-Logout-Response(Connection, +- CleanupConnection.CID, Success); +- } else { +- Build-And-Send-Logout-Response(Connection, +- +- +- +-Satran, et al. Standards Track [Page 246] +- +-RFC 3720 iSCSI April 2004 +- +- +- CleanupConnection.CID, Failure); +- } +- } +- } else if ((CurrentPDU.type == Login) and +- operational ErrorRecoveryLevel == 2) { +- Retrieve the CleanupConnection from CurrentPDU.CID). +- for (each command active on CleanupConnection) { +- Quiesce-And-Prepare-for-New-Allegiance(Session, TCB); +- TCB.CurrentlyAllegiant = FALSE; +- } +- Cleanup-Connection-State(CleanupConnection); +- if ((quiescing successful) and (cleanup successful)) { +- Continue with the rest of the Login processing; +- } else { +- Build-And-Send-Login-Response(Connection, +- CleanupConnection.CID, Target Error); +- } +- } +- +- } else if (CurrentPDU.type == TaskManagement) { +- if (CurrentPDU.function == "TaskReassign") { +- if (Session.ErrorRecoveryLevel < 2) { +- Build-And-Send-TaskMgmt-Response(Connection, +- CurrentPDU, "Allegiance reassignment +- not supported"); +- } else if (task is not found) { +- Build-And-Send-TaskMgmt-Response(Connection, +- CurrentPDU, "Task not in task set"); +- } else if (task is currently allegiant) { +- Build-And-Send-TaskMgmt-Response(Connection, +- CurrentPDU, "Task still allegiant"); +- } else { +- Establish-New-Allegiance(TCB, Connection); +- TCB.CurrentlyAllegiant = TRUE; +- Schedule-Command-To-Continue(TCB); +- } +- } +- } else { /* REST UNRELATED TO CONNECTION-RECOVERY, +- * NOT SHOWN */ +- } +- } +- +- Transport_Exception_Handler(Connection) +- { +- Connection.PerformConnectionCleanup = TRUE; +- if (the event is an unexpected transport disconnect) { +- Connection.State = CLEANUP_WAIT; +- Start-Timer(Connection-Resource-Timeout-Handler, +- +- +- +-Satran, et al. Standards Track [Page 247] +- +-RFC 3720 iSCSI April 2004 +- +- +- Connection, +- +- (DefaultTime2Wait+DefaultTime2Retain)); +- if (this Session has full-feature phase connections +- left) +- { +- DifferentConnection = +- Pick-A-Logged-In-Connection(Session); +- Build-And-Send-Async(DifferentConnection, +- DroppedConnection, DefaultTime2Wait, +- DefaultTime2Retain); +- } +- } else { +- Connection.State = FREE; +- } +- } +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 248] +- +-RFC 3720 iSCSI April 2004 +- +- +-Appendix F. Clearing Effects of Various Events on Targets +- +-F.1. Clearing Effects on iSCSI Objects +- +- The following tables describe the target behavior on receiving the +- events specified in the rows of the table. The second table is an +- extension of the first table and defines clearing actions for more +- objects on the same events. The legend is: +- +- Y = Yes (cleared/discarded/reset on the event specified in the +- row). Unless otherwise noted, the clearing action is only +- applicable for the issuing initiator port. +- N = No (not affected on the event specified in the row, i.e., +- stays at previous value). +- NA = Not Applicable or Not Defined. +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 249] +- +-RFC 3720 iSCSI April 2004 +- +- +- +-----+-----+-----+-----+-----+ +- |IT(1)|IC(2)|CT(5)|ST(6)|PP(7)| +- +---------------------+-----+-----+-----+-----+-----+ +- |connection failure(8)|Y |Y |N |N |Y | +- +---------------------+-----+-----+-----+-----+-----+ +- |connection state |NA |NA |Y |N |NA | +- |timeout (9) | | | | | | +- +---------------------+-----+-----+-----+-----+-----+ +- |session timeout/ |Y |Y |Y |Y |Y(14)| +- |closure/reinstatement| | | | | | +- |(10) | | | | | | +- +---------------------+-----+-----+-----+-----+-----+ +- |session continuation |NA |NA |N(11)|N |NA | +- |(12) | | | | | | +- +---------------------+-----+-----+-----+-----+-----+ +- |successful connection|Y |Y |Y |N |Y(13)| +- |close logout | | | | | | +- +---------------------+-----+-----+-----+-----+-----+ +- |session failure (18) |Y |Y |N |N |Y | +- +---------------------+-----+-----+-----+-----+-----+ +- |successful recovery |Y |Y |N |N |Y(13)| +- |Logout | | | | | | +- +---------------------+-----+-----+-----+-----+-----+ +- |failed Logout |Y |Y |N |N |Y | +- +---------------------+-----+-----+-----+-----+-----+ +- |connection Login |NA |NA |NA |Y(15)|NA | +- |(leading) | | | | | | +- +---------------------+-----+-----+-----+-----+-----+ +- |connection Login |NA |NA |N(11)|N |Y | +- |(non-leading) | | | | | | +- +---------------------+-----+-----+-----+-----+-----+ +- |target cold reset(16)|Y |Y |Y |Y |Y | +- +---------------------+-----+-----+-----+-----+-----+ +- |target warm reset(16)|Y |Y |Y |Y |Y | +- +---------------------+-----+-----+-----+-----+-----+ +- |LU reset(19) |Y |Y |Y |Y |Y | +- +---------------------+-----+-----+-----+-----+-----+ +- |powercycle(16) |Y |Y |Y |Y |Y | +- +---------------------+-----+-----+-----+-----+-----+ +- +- 1. Incomplete TTTs - Target Transfer Tags on which the target is +- still expecting PDUs to be received. Examples include TTTs received +- via R2T, NOP-IN, etc. +- +- 2. Immediate Commands - immediate commands, but waiting for +- execution on a target. For example, Abort Task Set. +- +- +- +- +- +-Satran, et al. Standards Track [Page 250] +- +-RFC 3720 iSCSI April 2004 +- +- +- 5. Connection Tasks - tasks that are active on the iSCSI connection +- in question. +- +- 6. Session Tasks - tasks that are active on the entire iSCSI +- session. A union of "connection tasks" on all participating +- connections. +- +- 7. Partial PDUs (if any) - PDUs that are partially sent and waiting +- for transport window credit to complete the transmission. +- +- 8. Connection failure is a connection exception condition - one of +- the transport connections shutdown, transport connections reset, or +- transport connections timed out, which abruptly terminated the iSCSI +- full-feature phase connection. A connection failure always takes the +- connection state machine to the CLEANUP_WAIT state. +- +- 9. Connection state timeout happens if a connection spends more time +- that agreed upon during Login negotiation in the CLEANUP_WAIT state, +- and this takes the connection to the FREE state (M1 transition in +- connection cleanup state diagram). +- +- 10. These are defined in Section 5.3.5 Session Reinstatement, +- Closure, and Timeout. +- +- 11. This clearing effect is "Y" only if it is a connection +- reinstatement and the operational ErrorRecoveryLevel is less than 2. +- +- 12. Session continuation is defined in Section 5.3.6 Session +- Continuation and Failure. +- +- 13. This clearing effect is only valid if the connection is being +- logged out on a different connection and when the connection being +- logged out on the target may have some partial PDUs pending to be +- sent. In all other cases, the effect is "NA". +- +- 14. This clearing effect is only valid for a "close the session" +- logout in a multi-connection session. In all other cases, the effect +- is "NA". +- +- 15. Only applicable if this leading connection login is a session +- reinstatement. If this is not the case, it is "NA". +- +- 16. This operation affects all logged-in initiators. +- +- 18. Session failure is defined in Section 5.3.6 Session Continuation +- and Failure. +- +- +- +- +- +-Satran, et al. Standards Track [Page 251] +- +-RFC 3720 iSCSI April 2004 +- +- +- 19. This operation affects all logged-in initiators and the clearing +- effects are only applicable to the LU being reset. +- +- +-----+-----+-----+-----+-----+ +- |DC(1)|DD(2)|SS(3)|CS(4)|DS(5)| +- +---------------------+-----+-----+-----+-----+-----+ +- |connection failure |N |Y |N |N |N | +- +---------------------+-----+-----+-----+-----+-----+ +- |connection state |Y |NA |Y |N |NA | +- |timeout | | | | | | +- +---------------------+-----+-----+-----+-----+-----+ +- |session timeout/ |Y |Y |Y(7) |Y |NA | +- |closure/reinstatement| | | | | | +- +---------------------+-----+-----+-----+-----+-----+ +- |session continuation |N(11)|NA*12|NA |N |NA*13| +- +---------------------+-----+-----+-----+-----+-----+ +- |successful connection|Y |Y |Y |N |NA | +- |close Logout | | | | | | +- +---------------------+-----+-----+-----+-----+-----+ +- |session failure |N |Y |N |N |N | +- +---------------------+-----+-----+-----+-----+-----+ +- |successful recovery |Y |Y |Y |N |N | +- |Logout | | | | | | +- +---------------------+-----+-----+-----+-----+-----+ +- |failed Logout |N |Y(9) |N |N |N | +- +---------------------+-----+-----+-----+-----+-----+ +- |connection Login |NA |NA |N(8) |N(8) |NA | +- |(leading | | | | | | +- +---------------------+-----+-----+-----+-----+-----+ +- |connection Login |N(11)|NA*12|N(8) |N |NA*13| +- |(non-leading) | | | | | | +- +---------------------+-----+-----+-----+-----+-----+ +- |target cold reset |Y |Y |Y |Y(10)|NA | +- +---------------------+-----+-----+-----+-----+-----+ +- |target warm reset |Y |Y |N |N |NA | +- +---------------------+-----+-----+-----+-----+-----+ +- |LU reset |N |Y |N |N |N | +- +---------------------+-----+-----+-----+-----+-----+ +- |powercycle |Y |Y |Y |Y(10)|NA | +- +---------------------+-----+-----+-----+-----+-----+ +- +- 1. Discontiguous Commands - commands allegiant to the connection in +- question and waiting to be reordered in the iSCSI layer. All "Y"s in +- this column assume that the task causing the event (if indeed the +- event is the result of a task) is issued as an immediate command, +- because the discontiguities can be ahead of the task. +- +- +- +- +- +-Satran, et al. Standards Track [Page 252] +- +-RFC 3720 iSCSI April 2004 +- +- +- 2. Discontiguous Data - data PDUs received for the task in question +- and waiting to be reordered due to prior discontiguities in DataSN. +- +- 3. StatSN +- +- 4. CmdSN +- +- 5. DataSN +- +- 7. It clears the StatSN on all the connections. +- +- 8. This sequence number is instantiated on this event. +- +- 9. A logout failure drives the connection state machine to the +- CLEANUP_WAIT state, similar to the connection failure event. Hence, +- it has a similar effect on this and several other protocol aspects. +- +- 10. This is cleared by virtue of the fact that all sessions with all +- initiators are terminated. +- +- 11. This clearing effect is "Y" if it is a connection reinstatement. +- +- 12. This clearing effect is "Y" only if it is a connection +- reinstatement and the operational ErrorRecoveryLevel is 2. +- +- 13. This clearing effect is "N" only if it is a connection +- reinstatement and the operational ErrorRecoveryLevel is 2. +- +-F.2. Clearing Effects on SCSI Objects +- +- The only iSCSI protocol action that can effect clearing actions on +- SCSI objects is the "I_T nexus loss" notification (Section 4.3.5.1 +- Loss of Nexus notification). [SPC3] describes the clearing effects +- of this notification on a variety of SCSI attributes. In addition, +- SCSI standards documents (such as [SAM2] and [SBC]) define additional +- clearing actions that may take place for several SCSI objects on SCSI +- events such as LU resets and power-on resets. +- +- Since iSCSI defines a target cold reset as a protocol-equivalent to a +- target power-cycle, the iSCSI target cold reset must also be +- considered as the power-on reset event in interpreting the actions +- defined in the SCSI standards. +- +- When the iSCSI session is reconstructed (between the same SCSI ports +- with the same nexus identifier) reestablishing the same I_T nexus, +- all SCSI objects that are defined to not clear on the "I_T nexus +- loss" notification event, such as persistent reservations, are +- automatically associated to this new session. +- +- +- +-Satran, et al. Standards Track [Page 253] +- +-RFC 3720 iSCSI April 2004 +- +- +-Acknowledgements +- +- This protocol was developed by a design team that, in addition to the +- authors, included Daniel Smith, Ofer Biran, Jim Hafner and John +- Hufferd (IBM), Mark Bakke (Cisco), Randy Haagens (HP), Matt Wakeley +- (Agilent, now Sierra Logic), Luciano Dalle Ore (Quantum), and Paul +- Von Stamwitz (Adaptec, now TrueSAN Networks). +- +- Furthermore, a large group of people contributed to this work through +- their review, comments, and valuable insights. We are grateful to +- all of them. We especially thank those people who found the time and +- patience to take part in our weekly phone conferences and +- intermediate meetings in Almaden and Haifa, which helped shape this +- document: Prasenjit Sarkar, Meir Toledano, John Dowdy, Steve Legg, +- Alain Azagury (IBM), Dave Nagle (CMU), David Black (EMC), John Matze +- (Veritas - now Okapi Software), Steve DeGroote, Mark Schrandt +- (Cisco), Gabi Hecht (Gadzoox), Robert Snively and Brian Forbes +- (Brocade), Nelson Nachum (StorAge), and Uri Elzur (Broadcom). Many +- others helped edit and improve this document within the IPS working +- group. We are especially grateful to David Robinson and Raghavendra +- Rao (Sun), Charles Monia, Joshua Tseng (Nishan), Somesh Gupta +- (Silverback), Michael Krause, Pierre Labat, Santosh Rao, Matthew +- Burbridge, Bob Barry, Robert Elliott, Nick Martin (HP), Stephen +- Bailey (Sandburst), Steve Senum, Ayman Ghanem, Dave Peterson (Cisco), +- Barry Reinhold (Trebia Networks), Bob Russell (UNH), Eddy Quicksall +- (iVivity, Inc.), Bill Lynn and Michael Fischer (Adaptec), Vince +- Cavanna, Pat Thaler (Agilent), Jonathan Stone (Stanford), Luben +- Tuikov (Splentec), Paul Koning (EqualLogic), Michael Krueger +- (Windriver), Martins Krikis (Intel), Doug Otis (Sanlight), John +- Marberg (IBM), Robert Griswold and Bill Moody (Crossroads), Bill +- Studenmund (Wasabi Systems), Elizabeth Rodriguez (Brocade) and Yaron +- Klein (Sanrad). The recovery chapter was enhanced with the help of +- Stephen Bailey (Sandburst), Somesh Gupta (Silverback), and Venkat +- Rangan (Rhapsody Networks). Eddy Quicksall contributed some examples +- and began the Definitions section. Michael Fischer and Bob Barry +- started the Acronyms section. Last, but not least, we thank Ralph +- Weber for keeping us in line with T10 (SCSI) standardization. +- +- We would like to thank Steve Hetzler for his unwavering support and +- for coming up with such a good name for the protocol, and Micky +- Rodeh, Jai Menon, Clod Barrera, and Andy Bechtolsheim for helping +- make this work happen. +- +- In addition to this document, we recommend you acquaint yourself with +- the following in order to get a full understanding of the iSCSI +- specification: "iSCSI Naming & Discovery"[RFC3721], "Bootstrapping +- Clients using the iSCSI Protocol" [BOOT], "Securing Block Storage +- Protocols over IP" [RFC3723] documents, "iSCSI Requirements and +- +- +- +-Satran, et al. Standards Track [Page 254] +- +-RFC 3720 iSCSI April 2004 +- +- +- Design Considerations" [RFC3347] and "SCSI Command Ordering +- Considerations with iSCSI" [CORD]. +- +- The "iSCSI Naming & Discovery" document is authored by: +- +- Mark Bakke (Cisco), Jim Hafner, John Hufferd, Kaladhar Voruganti +- (IBM), and Marjorie Krueger (HP). +- +- The "Bootstrapping Clients using the iSCSI Protocol" document is +- authored by: +- +- Prasenjit Sarkar (IBM), Duncan Missimer (HP), and Costa +- Sapuntzakis (Cisco). +- +- The "Securing Block Storage Protocols over IP" document is authored +- by: +- +- Bernard Aboba (Microsoft), Joshua Tseng (Nishan), Jesse Walker +- (Intel), Venkat Rangan (Rhapsody Networks), and Franco +- Travostino (Nortel Networks). +- +- The "iSCSI Requirements and Design Considerations" document is +- authored by: +- +- Marjorie Krueger, Randy Haagens (HP), Costa Sapuntzakis, and Mark +- Bakke (Cisco). +- +- The "SCSI Command Ordering Considerations with iSCSI" document is +- authored by: +- +- Mallikarjun Chadalapaka, Rob Elliot (HP) +- +- We are grateful to all of them for their good work and for helping us +- correlate this document with the ones they produced. +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 255] +- +-RFC 3720 iSCSI April 2004 +- +- +-Authors' Addresses +- +- Julian Satran +- IBM Research Laboratory in Haifa +- Haifa University Campus - Mount Carmel +- Haifa 31905, Israel +- +- Phone +972.4.829.6264 +- EMail: Julian_Satran@il.ibm.com +- +- +- Kalman Meth +- IBM Research Laboratory in Haifa +- Haifa University Campus - Mount Carmel +- Haifa 31905, Israel +- +- Phone +972.4.829.6341 +- EMail: meth@il.ibm.com +- +- +- Costa Sapuntzakis +- Stanford University +- 353 Serra Mall Dr #407 +- Stanford, CA 94305 +- +- Phone: +1.650.723.2458 +- EMail: csapuntz@alum.mit.edu +- +- +- Efri Zeidner +- XIV Ltd. +- 1 Azrieli Center, +- Tel-Aviv 67021, Israel +- +- Phone: +972.3.607.4722 +- EMail: efri@xiv.co.il +- +- +- Mallikarjun Chadalapaka +- Hewlett-Packard Company +- 8000 Foothills Blvd. +- Roseville, CA 95747-5668, USA +- +- Phone: +1.916.785.5621 +- EMail: cbm@rose.hp.com +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 256] +- +-RFC 3720 iSCSI April 2004 +- +- +-Full Copyright Statement +- +- Copyright (C) The Internet Society (2004). This document is subject +- to the rights, licenses and restrictions contained in BCP 78, and +- except as set forth therein, the authors retain all their rights. +- +- This document and the information contained herein are provided on an +- "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS +- OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET +- ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, +- INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE +- INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED +- WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +- +-Intellectual Property +- +- The IETF takes no position regarding the validity or scope of any +- Intellectual Property Rights or other rights that might be claimed to +- pertain to the implementation or use of the technology described in +- this document or the extent to which any license under such rights +- might or might not be available; nor does it represent that it has +- made any independent effort to identify any such rights. Information +- on the procedures with respect to rights in RFC documents can be +- found in BCP 78 and BCP 79. +- +- Copies of IPR disclosures made to the IETF Secretariat and any +- assurances of licenses to be made available, or the result of an +- attempt made to obtain a general license or permission for the use of +- such proprietary rights by implementers or users of this +- specification can be obtained from the IETF on-line IPR repository at +- http://www.ietf.org/ipr. +- +- The IETF invites any interested party to bring to its attention any +- copyrights, patents or patent applications, or other proprietary +- rights that may cover technology that may be required to implement +- this standard. Please address the information to the IETF at ietf- +- ipr@ietf.org. +- +-Acknowledgement +- +- Funding for the RFC Editor function is currently provided by the +- Internet Society. +- +- +- +- +- +- +- +- +- +-Satran, et al. Standards Track [Page 257] +- +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/open-isns/doc/rfc3722.txt open-iscsi-2.0-872-rc4-bnx2i.work/utils/open-isns/doc/rfc3722.txt +--- open-iscsi-2.0-872-rc4-bnx2i/utils/open-isns/doc/rfc3722.txt 2010-07-11 04:05:58.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/utils/open-isns/doc/rfc3722.txt 1969-12-31 18:00:00.000000000 -0600 +@@ -1,451 +0,0 @@ +- +- +- +- +- +- +-Network Working Group M. Bakke +-Request for Comments: 3722 Cisco +-Category: Standards Track April 2004 +- +- +- String Profile for Internet Small Computer +- Systems Interface (iSCSI) Names +- +-Status of this Memo +- +- This document specifies an Internet standards track protocol for the +- Internet community, and requests discussion and suggestions for +- improvements. Please refer to the current edition of the "Internet +- Official Protocol Standards" (STD 1) for the standardization state +- and status of this protocol. Distribution of this memo is unlimited. +- +-Copyright Notice +- +- Copyright (C) The Internet Society (2004). All Rights Reserved. +- +-Abstract +- +- This document describes how to prepare internationalized iSCSI names +- to increase the likelihood that name input and comparison work in +- ways that make sense for typical users throughout the world. +- +- The Internet Small Computer Systems Interface (iSCSI) protocol +- provides a way for hosts to access SCSI devices over an IP network. +- The iSCSI end-points, called initiators and targets, each have a +- globally-unique name that must be transcribable, as well as easily +- compared. +- +-1. Introduction +- +- The iSCSI protocol [RFC3720] provides a way for hosts to access SCSI +- [SAM2] devices over an IP network. The iSCSI end-points, called +- initiators and targets, each have a globally-unique name, defined in +- [RFC3721]. +- +- An iSCSI name is a string of UTF-8 [RFC3629] characters that includes +- a type designator, a naming authority based on domain names, and a +- unique part within the naming authority. The unique part may be +- generated based on anything the naming authority deems useful, and +- may include user input. +- +- These names may need to be transcribed (sent between two +- administrators via email, voice, paper, etc), so a case-insensitive +- comparison would be desirable. However, these names must often be +- +- +- +-Bakke Standards Track [Page 1] +- +-RFC 3722 String Profile for iSCSI Names April 2004 +- +- +- compared by initiator and target implementations, most of which are +- done in simple, embedded software. This makes case-sensitive +- comparison highly desirable for these implementors. +- +- However, a completely case-sensitive implementation would result in +- identifiers such as "example-name" and "Example-Name" being +- different, which could lead to confusion as these names are +- transcribed. +- +- The goal, then, is to generate iSCSI names that can be transcribed +- and entered by users, and also compared byte-for-byte, with minimal +- confusion. To attain these goals, iSCSI names are generalized using +- a normalized character set (converted to lower case or equivalent), +- with no white space allowed, and very limited punctuation. +- +- For those using only ASCII characters (U+0000 to U+007F), the +- following characters are allowed: +- +- - ASCII dash character ('-' = U+002d) +- - ASCII dot character ('.' = U+002e) +- - ASCII colon character (':' = U+003a) +- - ASCII lower-case characters ('a'..'z' = U+0061..U+007a) +- - ASCII digit characters ('0'..'9' = U+0030..U+0039) +- +- In addition, any upper-case characters input via a user interface +- MUST be mapped to their lower-case equivalents. +- +- This document specifies the valid character set for iSCSI names, +- along with the rules for normalizing and generating iSCSI names based +- on user input or other information that contains international +- characters. +- +- In particular, it defines the following, as required by [RFC3454]: +- +- - The intended applicability of the profile: internationalized iSCSI +- names. +- +- - The character repertoire that is the input and output to +- stringprep: Unicode 3.2, specified in section 3. +- +- - The mappings used: specified in section 4. +- +- - The Unicode normalization used: specified in section 5. +- +- - The characters that are prohibited as output: specified in section +- 6. +- +- This profile MUST be used with the iSCSI protocol. +- +- +- +-Bakke Standards Track [Page 2] +- +-RFC 3722 String Profile for iSCSI Names April 2004 +- +- +-2. Terminology +- +- The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +- "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +- document are to be interpreted as described in [RFC2119]. +- +- Examples in this document use the notation for code points and names +- from the Unicode Standard [Unicode3.2] and ISO/IEC 10646 [ISO10646]. +- For example, the letter "a" may be represented as either "U+0061" or +- "LATIN SMALL LETTER A". In the lists of prohibited characters, the +- "U+" is left off to make the lists easier to read. The comments for +- character ranges are shown in square brackets (such as "[SYMBOLS]") +- and do not come from the standards. +- +-3. Character Repertoire +- +- This profile uses Unicode 3.2, as defined in [RFC3454] Appendix A. +- +-4. Mapping +- +- This profile specifies mapping using the following tables from +- [RFC3454]. The following mapping tables MUST be used when generating +- iSCSI names from Unicode characters. +- +- Table B.1 +- Table B.2 +- +-5. Normalization +- +- Unicode normalization form KC MUST be used with this profile, as +- described in [RFC3454]. +- +-6. Prohibited Output +- +- This profile specifies prohibiting using the following tables from +- [RFC3454]. Characters appearing within these tables MUST NOT be used +- within an iSCSI name. +- +- Table C.1.1 +- Table C.1.2 +- Table C.2.1 +- Table C.2.2 +- Table C.3 +- Table C.4 +- Table C.5 +- Table C.6 +- +- +- +- +- +-Bakke Standards Track [Page 3] +- +-RFC 3722 String Profile for iSCSI Names April 2004 +- +- +- Table C.7 +- Table C.8 +- Table C.9 +- +- Important note: this profile MUST be used with the iSCSI protocol. +- The iSCSI protocol has additional naming rules that are checked +- outside of this profile. +- +- In addition, this profile adds the following prohibitions. The full +- set of prohibited characters are those from the tables above plus +- those listed individually below. +- +-6.1. Inappropriate Characters from Common Input Mechanisms +- +- u+3002 is used as if it were u+002e in many domain name input +- mechanisms used by applications, particularly in Asia. The character +- u+3002 MUST NOT be used in an iSCSI name. +- +- 3002; ideographic full stop +- +-6.2. Currently-prohibited ASCII characters +- +- Some of the ASCII characters that are currently prohibited in iSCSI +- names by [RFC3721] are also used in protocol elements such as URIs. +- Some examples are described in [RFC2396] and [RFC2732]. Note that +- there are many other RFCs that define additional URI schemes. +- +- The other characters in the range U+0000 to U+007F that are not +- currently allowed are prohibited in iSCSI names to reserve them for +- future use in protocol elements. Note that the dash (U+002D), dot +- (U+002E), and colon (U+003A) are not prohibited. +- +- The following characters MUST NOT be used in iSCSI names: +- +- 0000-002C; [ASCII CONTROL CHARACTERS and SPACE through ,] +- 002F; [ASCII /] +- 003B-0040; [ASCII ; through @] +- 005B-0060; [ASCII [ through `] +- 007B-007F; [ASCII { through DEL] +- +-7. Bidirectional Characters +- +- This profile specifies checking bidirectional strings as described in +- [RFC3454] section 6. +- +- +- +- +- +- +- +-Bakke Standards Track [Page 4] +- +-RFC 3722 String Profile for iSCSI Names April 2004 +- +- +-8. Unassigned Code Points in Internationalized Domain Names +- +- If the processing in [RFC3720] specifies that a list of unassigned +- code points be used, the system uses table A.1 from [RFC3454] as its +- list of unassigned code points. +- +-9. Security Considerations +- +- ISO/IEC 10646 has many characters that look similar. In many cases, +- users of security protocols might do visual matching, such as when +- comparing the names of trusted third parties. This profile does +- nothing to map similar-looking characters together. +- +- iSCSI names may be used by an initiator to verify that a target it +- has discovered is the correct one, and by a target to verify that an +- initiator is to be allowed access. If these names are interpreted +- and compared differently by different iSCSI implementations, an +- initiator could gain access to the wrong target, or could be denied +- access to a legitimate target. +- +-10. IANA Considerations +- +- This is a profile of stringprep. It has been registered in the IANA +- "Stringprep Profiles" registry. This process is described in the +- IANA Considerations section of [RFC3454]. +- +-11. Summary +- +- This document describes a stringprep profile to be used with programs +- generating names for iSCSI initiators and targets. +- +-12. Acknowledgements +- +- This document was produced as a result of discussions on iSCSI name +- formats with Joe Czap, Jim Hafner, Howard Hall, Jack Harwood, John +- Hufferd, Marjorie Krueger, Lawrence Lamers, Todd Sperry, Joshua +- Tseng, and Kaladhar Voruganti, as well as discussions on the +- normalization of names into identifiers with Paul Hoffman and Marc +- Blanchet. +- +- Thanks also to Bob Snively for suggesting the use of the nameprep +- process for iSCSI name normalization. +- +- Most of this document was copied from the stringprep profile for +- Internationalized Domain Names [RFC3491], written by Paul Hoffman and +- Marc Blanchet. +- +- +- +- +- +-Bakke Standards Track [Page 5] +- +-RFC 3722 String Profile for iSCSI Names April 2004 +- +- +-13. References +- +-13.1. Normative References +- +- [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate +- Requirement Levels", BCP 14, RFC 2119, March 1997. +- +- [RFC3454] Hoffman, P. and M. Blanchet, "Preparation of +- Internationalized Strings ("stringprep")", RFC 3454, +- December 2002. +- +- [RFC3720] Satran, J., Meth, K., Sapuntzakis, C. Chadalapaka, M. +- and E. Zeidner, "Internet Small Computer Systems +- Interface (iSCSI)", RFC 3720, April 2004. +- +-13.2. Informative References +- +- [RFC2396] Berners-Lee, T., Fielding, R. and L. Masinter, "Uniform +- Resource Identifiers", RFC 2396, August 1998. +- +- [RFC2732] Hinden, R., Carpenter, B. and L. Masinter, "Format for +- Literal IPv6 Addresses in URL's", RFC 2732, December +- 1999. +- +- [RFC3491] Hoffman, P. and M. Blanchet, "Nameprep: A Stringprep +- Profile for Internationalized Domain Names", RFC 3491, +- March 2003. +- [RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO +- 10646", STD 63, RFC 3629, November 2003. +- +- [RFC3721] Bakke, M., Hafner, J., Hufferd, J., Voruganti, K. and M. +- Krueger, "Internet Small Computer Systems Interface +- (iSCSI) Naming and Discovery", RFC 3721, April 2004. +- +- [SAM2] ANSI T10. "SCSI Architectural Model 2", March 2000. +- +- [Unicode3.2] The Unicode Standard, Version 3.2.0: The Unicode +- Consortium. The Unicode Standard, Version 3.2.0 is +- defined by The Unicode Standard, Version 3.0 (Reading, +- MA, Addison-Wesley, 2000. ISBN 0-201-61633-5), as +- amended by the Unicode Standard Annex #27: Unicode 3.1 +- (http://www.unicode.org/unicode/reports/tr27/) and by +- the Unicode Standard Annex #28: Unicode 3.2 +- (http://www.unicode.org/unicode/reports/tr28/). +- +- +- +- +- +- +- +-Bakke Standards Track [Page 6] +- +-RFC 3722 String Profile for iSCSI Names April 2004 +- +- +- [ISO10646] ISO/IEC 10646-1:2000. International Standard -- +- Information technology -- Universal Multiple-Octet Coded +- Character Set (UCS) -- Part 1: Architecture and Basic +- Multilingual Plane. +- +-14. Author's Address +- +- Mark Bakke +- Cisco Systems, Inc. +- 6450 Wedgwood Road +- Maple Grove, MN +- USA 55311 +- +- Voice: +1 763-398-1000 +- EMail: mbakke@cisco.com +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-Bakke Standards Track [Page 7] +- +-RFC 3722 String Profile for iSCSI Names April 2004 +- +- +-15. Full Copyright Statement +- +- Copyright (C) The Internet Society (2004). This document is subject +- to the rights, licenses and restrictions contained in BCP 78, and +- except as set forth therein, the authors retain all their rights. +- +- This document and the information contained herein are provided on an +- "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS +- OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET +- ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, +- INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE +- INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED +- WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +- +-Intellectual Property +- +- The IETF takes no position regarding the validity or scope of any +- Intellectual Property Rights or other rights that might be claimed to +- pertain to the implementation or use of the technology described in +- this document or the extent to which any license under such rights +- might or might not be available; nor does it represent that it has +- made any independent effort to identify any such rights. Information +- on the procedures with respect to rights in RFC documents can be +- found in BCP 78 and BCP 79. +- +- Copies of IPR disclosures made to the IETF Secretariat and any +- assurances of licenses to be made available, or the result of an +- attempt made to obtain a general license or permission for the use of +- such proprietary rights by implementers or users of this +- specification can be obtained from the IETF on-line IPR repository at +- http://www.ietf.org/ipr. +- +- The IETF invites any interested party to bring to its attention any +- copyrights, patents or patent applications, or other proprietary +- rights that may cover technology that may be required to implement +- this standard. Please address the information to the IETF at ietf- +- ipr@ietf.org. +- +-Acknowledgement +- +- Funding for the RFC Editor function is currently provided by the +- Internet Society. +- +- +- +- +- +- +- +- +- +-Bakke Standards Track [Page 8] +- +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/open-isns/doc/rfc4018.txt open-iscsi-2.0-872-rc4-bnx2i.work/utils/open-isns/doc/rfc4018.txt +--- open-iscsi-2.0-872-rc4-bnx2i/utils/open-isns/doc/rfc4018.txt 2010-07-11 04:05:58.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/utils/open-isns/doc/rfc4018.txt 1969-12-31 18:00:00.000000000 -0600 +@@ -1,1291 +0,0 @@ +- +- +- +- +- +- +-Network Working Group M. Bakke +-Request for Comments: 4018 Cisco +-Category: Standards Track J. Hufferd +- K. Voruganti +- IBM +- M. Krueger +- HP +- T. Sperry +- Adaptec +- April 2005 +- +- +- Finding Internet Small Computer Systems Interface (iSCSI) Targets +- and Name Servers by Using Service Location Protocol version 2 (SLPv2) +- +-Status of This Memo +- +- This document specifies an Internet standards track protocol for the +- Internet community, and requests discussion and suggestions for +- improvements. Please refer to the current edition of the "Internet +- Official Protocol Standards" (STD 1) for the standardization state +- and status of this protocol. Distribution of this memo is unlimited. +- +-Copyright Notice +- +- Copyright (C) The Internet Society (2005). +- +-Abstract +- +- The iSCSI protocol provides a way for hosts to access SCSI devices +- over an IP network. This document defines the use of the Service +- Location Protocol (SLP) by iSCSI hosts, devices, and management +- services, along with the SLP service type templates that describe the +- services they provide. +- +-Table of Contents +- +- 1. Introduction................................................ 2 +- 2. Notation Conventions........................................ 2 +- 3. Terminology................................................. 3 +- 4. Using SLP for iSCSI Service Discovery....................... 4 +- 5. iSCSI SLP Templates......................................... 11 +- 6. Security Considerations..................................... 18 +- 7. IANA Considerations......................................... 19 +- 8. Summary..................................................... 19 +- 9. Normative References........................................ 19 +- 10. Informative References...................................... 20 +- 11. Acknowledgements............................................ 21 +- +- +- +-Bakke & Hufferd Standards Track [Page 1] +- +-RFC 4018 iSCSI and SLPv2 April 2005 +- +- +-1. Introduction +- +- iSCSI [RFC3720] is a protocol used to transport SCSI [SAM2] commands, +- data, and status across an IP network. This protocol is connection- +- oriented and is currently defined over TCP. iSCSI uses a client- +- server relationship. The client end of the connection is an +- initiator, and it sends SCSI commands; the server end of the +- connection is called a target, and it receives and executes the +- commands. +- +- There are several methods an iSCSI initiator can use to find the +- targets to which it should connect. Two of these methods can be +- accomplished without the use of SLP: +- +- - Each target and its address can be statically configured on the +- initiator. +- +- - Each address providing targets can be configured on the initiator; +- iSCSI provides a mechanism by which the initiator can query the +- address for a list of targets. +- +- The above methods are further defined in "iSCSI Naming and Discovery +- Requirements" [RFC3721]. +- +- Each of the above methods requires a small amount of configuration to +- be done on each initiator. The ability to discover targets and name +- services without having to configure initiators is a desirable +- feature. The Service Location Protocol (SLP) [RFC2608] is an IETF +- standards track protocol providing several features that will +- simplify locating iSCSI services. This document describes how SLP +- can be used in iSCSI environments to discover targets, addresses +- providing targets, and storage management servers. +- +-2. Notation Conventions +- +- In this document, the key words "MUST", "MUST NOT", "REQUIRED", +- "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", +- and "OPTIONAL" are to be interpreted as described in [RFC2119]. +- +- +- +- +- +- +- +- +- +- +- +- +- +-Bakke & Hufferd Standards Track [Page 2] +- +-RFC 4018 iSCSI and SLPv2 April 2005 +- +- +-3. Terminology +- +- Here are some definitions that may aid readers who are unfamiliar +- with SLP, SCSI, or iSCSI. Some of these definitions have been +- reproduced from [RFC2608] and "Finding an RSIP Server with SLP" +- [RFC3105]. +- +- User Agent (UA) A process working on the client's behalf +- to establish contact with some service. +- The UA retrieves service information from +- the Service Agents or Directory Agents. +- +- Service Agent (SA) A process working on behalf of one or more +- services to advertise the services and +- their capabilities. +- +- Directory Agent (DA) A process that collects service +- advertisements. There can only be one DA +- present per given host. +- +- Scope A named set of services, typically making +- up a logical administrative group. +- +- Service Advertisement A URL, attributes, and a lifetime +- (indicating how long the advertisement is +- valid) providing service access +- information and capabilities description +- for a particular service. +- +- Initiator A logical entity, typically within a host, +- that sends SCSI commands to targets to be +- executed. An initiator is usually present +- in the form of a device driver. +- +- Target A logical entity, typically within a +- storage controller or gateway that +- receives SCSI commands from an initiator +- and executes them. A target includes one +- or more Logical Units (LUs); each LU is a +- SCSI device, such as a disk or tape drive. +- +- iSCSI Name A UTF-8 character string that serves as a +- unique identifier for iSCSI initiators and +- targets. Its format and usage is further +- defined in [RFC3721]. +- +- iSCSI Client A logical entity, typically a host that +- includes at least one iSCSI Initiator. +- +- +- +-Bakke & Hufferd Standards Track [Page 3] +- +-RFC 4018 iSCSI and SLPv2 April 2005 +- +- +- iSCSI Server A logical entity, typically a storage +- controller or gateway that includes at +- least one iSCSI Target. +- +- Storage Management Server An addressable entity that provides +- management services that benefit an iSCSI +- environment. "Storage management server" +- is used as a generic term and does not +- indicate a specific protocol or service. +- +-4. Using SLP for iSCSI Service Discovery +- +- Two entities are involved in iSCSI discovery. The end result is that +- an iSCSI initiator (e.g., a host) discovers iSCSI targets, usually +- provided by storage controllers or gateways. +- +- iSCSI targets are registered with SLP as a set of service URLs, one +- for each address on which the target may be accessed. Initiators +- discover these targets by using SLP service requests. Targets that +- do not directly support SLP or that are under the control of a +- management service may be registered by a proxy service agent as part +- of the software providing this service. +- +- iSCSI entities may also use SLP to discover higher-level management +- services when these are needed. +- +- This section first describes the use of SLP for discovery of targets +- by iSCSI initiators, it then describes the use of SLP to discover +- storage management servers. +- +- This document assumes that SLPv2 will be used for discovering iSCSI- +- related services; no attempt is made to include support for SLPv1. +- +-4.1. Discovering iSCSI Targets with SLP +- +- The following diagram shows the relationship among iSCSI clients, +- servers, initiators, and targets. An iSCSI client includes at least +- one iSCSI initiator, and an SLP user agent (UA). An iSCSI server +- includes at least one iSCSI target an SLP service agent (SA). Some +- entities, such as extended copy engines, include both initiators and +- targets. These include both an SA, for its targets to be discovered, +- and a UA, for its initiator(s) to discover other targets. +- +- +- +- +- +- +- +- +- +-Bakke & Hufferd Standards Track [Page 4] +- +-RFC 4018 iSCSI and SLPv2 April 2005 +- +- +- +---------------------------------+ +- | iSCSI Client | +- | +-----------+ | +- | | iSCSI | | +- | | initiator | | +- | | "myhost" | | +- | +-----------+ | +- | | +- +--------------------------+------+ +- | iSCSI Driver | UA | +- +--------------------------+------+ +- | TCP/UDP/IP | +- +----------------+----------------+ +- | Interface 1 | Interface 2 | +- +----------------+----------------+ +- | | +- +------------+ | | +------------+ +- | SLP DA | | | | SLP DA | +- | (optional) |----+ IP Networks +----| (optional) | +- +------------+ | | +------------+ +- | | +- +-----------------+-----------------| +- | Interface 1 | Interface 2 | +- | 192.0.2.131 | 192.0.2.3 | +- +-----------------+-----------------+ +- | TCP/UDP/IP | +- +---------------------------+-------+ +- | iSCSI Driver | SA | +- +---------------------------+-------| +- | | +- | +--------+ +--------+ +---------+ | +- | | iSCSI | | iSCSI | | iSCSI | | +- | | target | | target | | target | | +- | | "one" | | "two" | | "three" | | +- | +--------+ +--------+ +---------+ | +- | iSCSI Server | +- +-----------------------------------+ +- +- In the above drawing, the iSCSI server has three iSCSI targets that +- the client could discover, named "one", "two" and "three". The iSCSI +- client has an iSCSI initiator with the name "myhost". The iSCSI +- client may use the initiator name in its SLP Service Requests as a +- filter to discover only targets that are configured to accept iSCSI +- connections from "myhost". +- +- Each iSCSI target and initiator has a unique name, called an iSCSI +- Name. This identifier is the same regardless of the network path +- (through adapter cards, networks, and interfaces on the storage +- +- +- +-Bakke & Hufferd Standards Track [Page 5] +- +-RFC 4018 iSCSI and SLPv2 April 2005 +- +- +- device) over which the target is discovered and accessed. For this +- example, the iSCSI names "one", "two", and "three" are used for the +- targets; the initiator uses the name "myhost". An actual iSCSI name +- would incorporate more structure, including a naming authority, and +- is not described here. +- +- Each of the iSCSI targets in the drawing can appear at two addresses, +- since two network interfaces are present. Each target would have two +- service URLs, unless a single service URL included a DNS host name +- mapping to both addresses. +- +- An iSCSI target URL consists of its fully qualified host name or IP +- address, the TCP port on which it is listening, and its iSCSI name. +- An iSCSI server must register each of its individual targets at each +- of its network addresses. +- +- The iSCSI server constructs a service advertisement of the type +- "service:iscsi:target" for each of the service URLs it wishes to +- register. The advertisement contains a lifetime, along with other +- attributes that are defined in the service template. +- +- If the server in the above drawing is listening at TCP port 3260 for +- both network addresses, the service URLs registered would be +- +- - 192.0.2.131:3260/one +- +- - 192.0.2.131:3260/two +- +- - 192.0.2.131:3260/three +- +- - 192.0.2.3:3260/one +- +- - 192.0.2.3:3260/two +- +- - 192.0.2.3:3260/three +- +- The remainder of the discovery procedure is identical to that used by +- any client/server pair implementing SLP: +- +- 1. If an SLP DA is found, the SA contacts the DA and registers the +- service advertisement. Whether or not one or more SLPv2 DAs are +- discovered, the SA maintains the advertisement itself and answers +- multicast UA queries directly. +- +- 2. When the iSCSI initiator requires contact information for an +- iSCSI target, the UA either contacts the DA by using unicast or +- the SA by using multicast. If a UA is configured with the +- address of the SA, it may avoid multicast and may contact an SA +- +- +- +-Bakke & Hufferd Standards Track [Page 6] +- +-RFC 4018 iSCSI and SLPv2 April 2005 +- +- +- by using unicast. The UA includes a query based on the +- attributes to indicate the characteristics of the target(s) it +- requires. +- +- 3. Once the UA has the host name or address of the iSCSI server, as +- well as the port number and iSCSI Target Name, it can begin the +- normal iSCSI login to the target. +- +- As information contained in the iSCSI target template may exceed +- common network datagram sizes, the SLP implementation for both UAs +- and SAs supporting this template MUST implement SLP over TCP. +- +-4.1.1. Finding Targets Based on Initiator Credentials +- +- To be allowed access to an iSCSI target, an initiator must be +- authenticated. The initiator may be required by the target to +- produce one or more of the following credentials: +- +- - An iSCSI Initiator Name +- +- - An IP address +- +- - A CHAP, SRP, or Kerberos credential +- +- - Any combination of the above +- +- Most iSCSI targets allow access to only one or two initiators. In +- the ideal discovery scenario, an initiator would send an SLP request +- and receive responses ONLY for targets to which the initiator is +- guaranteed a successful login. To achieve this goal, the iSCSI +- target template contains the following attributes, each of which +- allows a list of values: +- +- 1. auth-name: This attribute contains the list of initiator names +- allowed to access this target, or the value "any", indicating +- that no specific initiator name is required. +- +- 2. auth-addr: This attribute contains the list of host names +- and/or IP addresses that will be allowed access to this target, +- or the value "any", indicating that no specific address or +- host name is required. If a large number of addresses is to +- be allowed (perhaps a subnet), this attribute may contain the +- value "any". +- +- +- +- +- +- +- +- +-Bakke & Hufferd Standards Track [Page 7] +- +-RFC 4018 iSCSI and SLPv2 April 2005 +- +- +- 3. auth-cred: This attribute contains a list of "method/identifier" +- credentials that will be allowed access to the target, provided +- they can produce the correct password or other verifier during +- the login process. If no specific credentials are required, the +- value "any" is used. +- +- The list of valid method strings for auth-cred are defined in +- [RFC3720], section 11.1, "AuthMethod". The identifier used after the +- "/" is defined by the specific AuthMethod, also in [RFC3720]. +- Examples showing initiator searches based on auth-xxxx attributes are +- shown in the target-specific template section below. +- +- Also note that the auth-xxxx attributes are considered security +- policy information. If these attributes are distributed, IPsec MUST +- be implemented as specified in the Security Implementation section +- below. +- +-4.1.2. Supporting Access by Multiple Identities to the Same Target +- +- If a target is to allow access to multiple host identities, more than +- one combination of auth-xxxx attributes will have to be allowed. In +- some of these cases, it is not possible to express the entire set of +- valid combinations of auth-xxxx attributes within a single registered +- service URL. For example, if a target can be addressed by +- +- auth-name=myhost1 AND auth-cred=CHAP/user1 (identity1) +- +- OR +- +- auth-name-myhost2 AND auth-cred=CHAP/user2 (identity2) +- +- the above cannot be specified in a single registered service URL, +- since (auth-name=myhost1, auth-name=myhost2, auth-cred=CHAP/user1, +- auth-cred=CHAP/user2) would allow either auth-name to be used with +- either auth-cred. This necessitates the ability to register a target +- and address under more than one service URL; one for (identity1) and +- one for (identity2). +- +- Because service URLs must be unique, (identity1) and (identity2) must +- each be registered under a unique service URL. For systems that +- support the configuration of multiple identities to access a target, +- the service URL must contain an additional, opaque string defining +- the identity. This appears after the iSCSI name in the URL string +- and is separated by a "/". Each registered (target-address, target- +- name, initiator-identity) tuple can then register a set of auth-xxxx +- attributes. +- +- +- +- +- +-Bakke & Hufferd Standards Track [Page 8] +- +-RFC 4018 iSCSI and SLPv2 April 2005 +- +- +-4.1.3. Using SLP in a Non-multicast Environment +- +- In some networks, the use of multicast for discovery purposes is +- either unavailable or not allowed. These include public or service- +- provider networks that are placed between an iSCSI client and a +- server. These are probably most common between two iSCSI gateways, +- one at a storage service provider site, and one at a customer site. +- +- In these networks, an initiator may allow the addresses of one or +- more SAs to be configured instead of or in addition to its DA +- configuration. The initiator would then make unicast SLP service +- requests directly to these SAs, without the use of multicast to +- discover them first. +- +- This functionality is well within the scope of the current SLP +- protocol. The main consequence for implementors is that an initiator +- configured to make direct unicast requests to an SA will have to add +- this to the SLP API, if it is following the service location API +- defined in [RFC2614]. +- +-4.2. Discovering Storage Management Services with SLP +- +- Storage management servers can be built to manage and control access +- to targets in a variety of ways. They can provide extended services +- beyond discovery, which could include storage allocation and +- management. None of these services are defined here; the intent of +- this document is to allow these services to be discovered by both +- clients and servers, in addition to the target discovery already +- being performed. +- +- The following drawing shows an iSCSI client, an iSCSI server, and a +- storage management server. To simplify the drawing, the second IP +- network is not shown but is assumed to exist. The storage management +- server would use its own protocol (smsp) to provide capabilities to +- iSCSI clients and servers; these clients and servers can both use SLP +- to discover the storage management server. +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-Bakke & Hufferd Standards Track [Page 9] +- +-RFC 4018 iSCSI and SLPv2 April 2005 +- +- +- +---------------------------+ +- | iSCSI Client | +- | | +- | +-----------+ | +- | | iSCSI | | +- | | initiator | | +- | +-----------+ | +- | | +- +---------------+------+----+ +------------+ +- | iSCSI Driver | smsp | UA | | SLP DA | +- +---------------+------+----+ | | +- | TCP/UDP/IP | | (optional) | +- +---------------+------+----+ +------------+ +- | | +- | IP Network | +- ------------------------------------------ +- | | +- | | +- +---------------+-----------+ +---------------------+ +- | TCP/UDP/IP | | TCP/UDP/IP | +- +---------------+------+----+ +---------------------+ +- | iSCSI Driver | smsp | UA | | SA | smsp | +- +---------------+------+----+ +---------------------+ +- | | | | +- | +--------+ +--------+ | | storage mgmt server | +- | | iSCSI | | iSCSI | | | | +- | | target | | target | | +---------------------+ +- | | 1 | | 2 | | +- | +--------+ +--------+ | +- | | +- | iSCSI Server | +- +---------------------------+ +- +- Note the difference between the storage management server model and +- the previously defined target discovery model. When target discovery +- was used, the iSCSI Server implemented an SA, to be discovered by the +- initiator's UA. In the storage management server model, the iSCSI +- clients and servers both implement UAs, and the management server +- implements the SA. +- +- A storage management server's URL contains the domain name or IP +- address and TCP or UDP port number. No other information is +- required. +- +- The storage management server constructs a service advertisement of +- the type "service:iscsi:sms" for each of the addresses at which it +- appears. The advertisement contains the URL and a lifetime, along +- with other attributes that are defined in the service template. +- +- +- +-Bakke & Hufferd Standards Track [Page 10] +- +-RFC 4018 iSCSI and SLPv2 April 2005 +- +- +- The remainder of the discovery procedure is identical to that used to +- discover iSCSI targets, except that both initiators and targets would +- normally be "clients" of the storage management service. +- +- Targets that support a storage management service implement a UA in +- addition to the SA. A target may alternatively just implement the UA +- and allow the storage management service to advertise its targets +- appropriately by providing an SA and registering the appropriate +- service:iscsi:target registrations on the target's behalf: The target +- device would not have to advertise its own targets. This has no +- impact on the initiator. +- +- This allows the initiators' discovery of targets to be completely +- interoperable regardless of which storage management service is used, +- or whether one is used at all, or whether the target registrations +- are provided directly by the target or by the management service. +- +-4.3. Internationalization Considerations +- +- SLP allows internationalized strings to be registered and retrieved. +- Attributes in the template that are not marked with an 'L' (literal) +- will be registered in a localized manner. An "en" (English) +- localization MUST be registered, and others MAY be registered. +- +- Attributes that include non-ASCII characters will be encoded by using +- UTF-8, as discussed in [RFC3722] and [RFC3491]. +- +-5. iSCSI SLP Templates +- +- Three templates are provided: an iSCSI target template, a management +- service template, and an abstract template to encapsulate the two. +- +-5.1. The iSCSI Abstract Service Type Template +- +- This template defines the abstract service "service:iscsi". It is +- used as a top-level service to encapsulate all other iSCSI-related +- services. +- +- Name of submitter: Mark Bakke +- Language of service template: en +- Security Considerations: See section 6. +- +- Template Text: +- -------------------------template begins here----------------------- +- template-type=iscsi +- template-version=1.0 +- +- template-description= +- +- +- +-Bakke & Hufferd Standards Track [Page 11] +- +-RFC 4018 iSCSI and SLPv2 April 2005 +- +- +- This is an abstract service type. The purpose of the iscsi +- service type is to encompass all of the services used to support +- the iSCSI protocol. +- +- template-url-syntax= +- url-path= ; Depends on the concrete service type. +- +- --------------------------template ends here------------------------ +- +-5.2. The iSCSI Target Concrete Service Type Template +- +- This template defines the service "service:iscsi:target". An entity +- containing iSCSI targets that wishes them discovered via SLP would +- register each of them, with each of their addresses, as this service +- type. +- +- Initiators (and perhaps management services) wishing to discover +- targets in this way will generally use one of the following queries: +- +- 1. Find a specific target, given its iSCSI Target Name: +- +- Service: service:iscsi:target +- Scope: initiator-scope-list +- Query: (iscsi-name=iqn.2001-04.com.example:sn.456) +- +- 2. Find all of the iSCSI Target Names that may allow access to a +- given initiator: +- +- Service: service:iscsi:target +- Scope: initiator-scope-list +- Query: (auth-name=iqn.1998-03.com.example:hostid.045A7B) +- +- 3. Find all of the iSCSI Target Names that may allow access to +- any initiator: +- +- Service: service:iscsi:target +- Scope: initiator-scope-list +- Query: (auth-name=any) +- +- 4. Find all of the iSCSI Target Names that may allow access to +- this initiator, or that will allow access to any initiator: +- +- Service: service:iscsi:target +- Scope: initiator-scope-list +- Query: &(auth-name=iqn.1998-03.com.example:hostid.045A7B) +- (auth-name=any) +- +- +- +- +- +-Bakke & Hufferd Standards Track [Page 12] +- +-RFC 4018 iSCSI and SLPv2 April 2005 +- +- +- 5. Find all of the iSCSI Target Names that may allow access to +- a given CHAP user name: +- +- Service: service:iscsi:target +- Scope: initiator-scope-list +- Query: (auth-cred=chap/my-user-name) +- +- 6. Find all of the iSCSI Target Names that may allow access to a +- given initiator that supports two IP addresses, a CHAP credential +- and SRP credential, and an initiator name: +- +- Service: service:iscsi:target +- Scope: initiator-scope-list +- Query: &(|(auth-name=iqn.com.example:host47)(auth-name=any) +- |(auth-addr=192.0.2.3)(auth-addr=192.0.2.131)(auth-addr=any) +- |(auth-cred=chap/foo)(auth-cred=srp/my-user-name) +- (auth-cred=any)) +- +- 7. Find the iSCSI Target Names from which the given initiator is +- allowed to boot: +- +- Service: service:iscsi:target +- Scope: initiator-scope-list +- Query: (boot-list=iqn.1998-03.com.example:hostid.045A7B) +- +- 8. In addition, a management service may wish to discover all +- targets: +- +- Service: service:iscsi:target +- Scope: management-server-scope-list +- Query: +- +- More details on booting from an iSCSI target are defined in [BOOT]. +- +- Name of submitter: Mark Bakke +- Language of service template: en +- Security Considerations: see section 6. +- +- Template Text: +- -------------------------template begins here----------------------- +- template-type=iscsi:target +- template-version=1.0 +- +- template-description= +- +- This is a concrete service type. The iscsi:target service type is +- used to register individual target addresses to be discovered +- by others. UAs will generally search for these by including one of +- +- +- +-Bakke & Hufferd Standards Track [Page 13] +- +-RFC 4018 iSCSI and SLPv2 April 2005 +- +- +- the following: +- +- - the iSCSI target name +- - iSCSI initiator identifiers (iSCSI name, credential, IP address) +- - the service URL +- +- template-url-syntax= +- url-path = hostport "/" iscsi-name [ "/" identity ] +- hostport = host [ ":" port ] +- host = hostname / hostnumber ; DNS name or IP address +- hostname = *( domainlabel "." ) toplabel +- alphanum = ALPHA / DIGIT +- domainlabel = alphanum / alphanum *[alphanum / "-"] alphanum +- toplabel = ALPHA / ALPHA *[ alphanum / "-" ] alphanum +- hostnumber = ipv4-number / ipv6-addr ; IPv4 or IPv6 address +- ipv4-number = 1*3DIGIT 3("." 1*3DIGIT) +- ipv6-addr = "[" ipv6-number "]" +- ipv6-number = 6( h16 ":" ) ls32 +- / "::" 5( h16 ":" ) ls32 +- / [ h16 ] "::" 4( h16 ":" ) ls32 +- / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32 +- / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32 +- / [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32 +- / [ *4( h16 ":" ) h16 ] "::" ls32 +- / [ *5( h16 ":" ) h16 ] "::" h16 +- / [ *6( h16 ":" ) h16 ] "::" +- ls32 = ( h16 ":" h16 ) / ipv4-number +- ; least-significant 32 bits of ipv6 address +- h16 = 1*4HEXDIG +- port = 1*DIGIT +- iscsi-name = iscsi-char ; iSCSI target name +- identity = iscsi-char ; optional identity string +- iscsi-char = ALPHA / DIGIT / escaped / ":" / "-" / "." +- ; Intended to allow UTF-8 encoded strings +- escaped = 1*("\" HEXDIG HEXDIG) +- ; +- ; The iscsi-name part of the URL is required and must be the iSCSI +- ; name of the target being registered. +- ; A device representing multiple targets must individually +- ; register each target/address combination with SLP. +- ; The identity part of the URL is optional, and is used to +- ; indicate an identity that is allowed to access this target. +- ; +- ; Example (split into two lines for clarity): +- ; service:iscsi:target://192.0.2.3:3260/ +- ; iqn.2001-04.com.example:sn.45678 +- ; +- ; IPv6 addresses are also supported; they use the notation +- +- +- +-Bakke & Hufferd Standards Track [Page 14] +- +-RFC 4018 iSCSI and SLPv2 April 2005 +- +- +- ; specified above and in [RFC3513], section 2.2 +- +- iscsi-name = string +- # The iSCSI Name of this target. +- # This must match the iscsi-name in the url-path. +- +- portal-group = integer +- # The iSCSI portal group tag for this address. Addresses sharing +- # the same iscsi-name and portal-group tag can be used within the +- # same iSCSI session. Portal groups are described in [RFC3720]. +- +- transports = string M L +- tcp +- # This is a list of transport protocols that the registered +- # entity supports. iSCSI is currently supported over TCP, +- # but it is anticipated that it could be supported over other +- # transports, such as SCTP, in the future. +- tcp +- +- mgmt-entity = string O +- # The fully qualified domain name, or IP address in dotted-decimal +- # notation, of the management interface of the entity containing +- # this target. +- # +- +- alias = string O +- # The alias string contains a descriptive name of the target. +- +- auth-name = string M X +- # A list of iSCSI Initiator Names that can access this target. +- # Normal iSCSI names will be 80 characters or less; max length +- # is 255. +- # Normally, only one or a few values will be in the list. +- # Using the equivalence search on this will evaluate to "true" +- # if any one of the items in this list matches the query. +- # If this list contains the default name "any", any initiator +- # is allowed to access this target, provided it matches +- # the other auth-xxx attributes. +- # +- # This attribute contains security policy information. If this +- # attribute is distributed via an Attribute Reply message, +- # IPsec MUST be implemented. +- +- auth-addr = string M X +- # A list of initiator IP addresses (or host names) which will +- # be allowed access to this target. If this list contains the +- # default name "any", any IP address is allowed access to this +- # target, provided it matches the other auth-xxx attributes. +- +- +- +-Bakke & Hufferd Standards Track [Page 15] +- +-RFC 4018 iSCSI and SLPv2 April 2005 +- +- +- # +- # This attribute contains security policy information. If this +- # attribute is distributed via an Attribute Reply message, +- # IPsec MUST be implemented. +- +- auth-cred = string M X +- # A list of credentials which will be allowed access to the target +- # (provided they can provide the correct password or other +- # authenticator). Entries in this list are of the form +- # "method/identifier", where the currently defined methods are +- # "chap" and "srp", both of which take usernames as their +- # identifiers. +- # +- # This attribute contains security policy information. If this +- # attribute is distributed via an Attribute Reply message, +- # IPsec MUST be implemented. +- +- boot-list = string M O +- # A list of iSCSI Initiator Names that can boot from this target. +- # This list works precisely like the auth-name attribute. A name +- # appearing in this list must either appear in the access-list, +- # or the access-list must contain the initiator name "iscsi". +- # Otherwise, an initiator will be unable to find its boot +- # target. If boot-list contains the name "iscsi", any host can boot +- # from it, but I am not sure if this is useful to anyone. If this +- # attribute is not registered, this target is not "bootable". +- # +- # Note that the LUN the host boots from is not specified here; a +- # host will generally attempt to boot from LUN 0. +- # +- # It is quite possible that other attributes will need to be defined +- # here for booting as well. +- # +- # This attribute contains security policy information. If this +- # attribute is distributed via an Attribute Reply message, +- # IPsec MUST be implemented. +- +- --------------------------template ends here------------------------ +- +-5.3. iSCSI Storage Management Service Templates +- +- This template defines the service "service:iscsi:sms". An entity +- supporting one or more iSCSI management service protocols may +- register itself with SLP as this service type. iSCSI clients and +- servers wishing to discover storage management services using SLP +- will usually search for them by the protocol(s) they support: +- +- +- +- +- +-Bakke & Hufferd Standards Track [Page 16] +- +-RFC 4018 iSCSI and SLPv2 April 2005 +- +- +- Service: service:iscsi:sms +- Scope: initiator-scope-list +- Query: (protocols=isns) +- +- Name of submitter: Mark Bakke +- Language of service template: en +- Security Considerations: see section 6. +- +- Template Text: +- -------------------------template begins here----------------------- +- template-type=iscsi:sms +- template-version=1.0 +- +- template-description= +- This is a concrete service type. The iscsi:sms service type +- provides the capability for entities supporting iSCSI to discover +- appropriate management services. +- +- template-url-syntax= +- url-path = ; The URL of the management service [RFC2608]. +- +- protocols = string M +- # The list of protocols supported by this name service. This +- # list may be expanded in the future. There is no default. +- # +- # "isns" - This management service supports the use of the iSNS +- # protocol for access management, health monitoring, and +- # discovery management services. This protocol is defined +- # in [ISNS]. +- isns +- +- transports = string M L +- tcp +- # This is a list of transport protocols that the registered +- # entity supports. +- tcp, udp +- +- server-priority = integer +- # The priority a client should give this server, when choosing +- # between multiple servers with the same protocol type. +- # When multiple servers are discovered for a given protocol type, +- # this parameter indicates their relative precedence. Server +- # precedence is protocol-specific; for some protocols, the primary +- # server may have the highest server-priority value, while for +- +- +- +- +- +- +- +-Bakke & Hufferd Standards Track [Page 17] +- +-RFC 4018 iSCSI and SLPv2 April 2005 +- +- +- # others it may have the lowest. For example, with iSNS, the primary +- # server has the lowest value (value 0). +- +- --------------------------template ends here------------------------ +- +-6. Security Considerations +- +- The SLPv2 security model as specified in [RFC2608] does not provide +- confidentiality but does provide an authentication mechanism for UAs +- to ensure that service advertisements only come from trusted SAs, +- with the exception that it does not provide a mechanism to +- authenticate "zero-result responses". See [RFC3723] for a discussion +- of the SLPv2 [RFC2608] security model. +- +- Once a target or management server is discovered, authentication and +- authorization are handled by the iSCSI protocol, or by the management +- server's protocol. It is the responsibility of the providers of +- these services to ensure that an inappropriately advertised or +- discovered service does not compromise their security. +- +- When no security is used for SLPv2, there is a risk of distribution +- of false discovery information. The primary countermeasure for this +- risk is authentication. When this risk is a significant concern, +- IPsec SAs and iSCSI in-band authentication SHOULD be used for iSCSI +- traffic subject to this risk to ensure that iSCSI traffic only flows +- between endpoints that have participated in IKE authentication and +- iSCSI in-band authentication. For example, if an attacker +- distributes discovery information falsely claiming that it is an +- iSCSI target, it will lack the secret information necessary to +- complete IKE authentication or iSCSI in-band authentication +- successfully and therefore will be prevented from falsely sending or +- receiving iSCSI traffic. +- +- A risk remains of a denial of service attack based on repeated use of +- false discovery information that will cause initiation of IKE +- negotiation. The countermeasures for this are administrative +- configuration of each iSCSI Target to limit the peers it is willing +- to communicate with (i.e., by IP address range and/or DNS domain), +- and maintenance of a negative authentication cache to avoid +- repeatedly contacting an iSCSI Target that fails to authenticate. +- These three measures (i.e., IP address range limits, DNS domain +- limits, negative authentication cache) MUST be implemented. +- +- The auth-name, auth-addr, auth-cred, and boot-list attributes +- comprise security policy information. When these are distributed, +- IPsec MUST be implemented. +- +- +- +- +- +-Bakke & Hufferd Standards Track [Page 18] +- +-RFC 4018 iSCSI and SLPv2 April 2005 +- +- +-6.1. Security Implementation +- +- Security for SLPv2 in an IP storage environment is specified in +- [RFC3723]. IPsec is mandatory-to-implement for IPS clients and +- servers. Thus, all IP storage clients, including those invoking SLP, +- can be assumed to support IPsec. SLP servers, however, cannot be +- assumed to implement IPsec, since there is no such requirement in +- standard SLP. In particular, SLP Directory Agents (DA) may be +- running on machines other than those running the IPS protocols. +- +- IPsec SHOULD be implemented for SLPv2 as specified in [RFC3723]; this +- includes ESP with a non-null transform to provide both authentication +- and confidentiality. +- +- When SLPv2 can be used to distribute auth-name, auth-addr, auth-cred, +- and boot-list information (see section 5.2 above), IPsec MUST be +- implemented, as these items are considered sensitive security policy +- information. If IPsec is not implemented, auth-name, auth-addr, +- auth-cred, and boot-list information MUST NOT be distributed via +- SLPv2 and MUST NOT be used if discovered via SLPv2. +- +- Because the IP storage services have their own authentication +- capabilities when located, SLPv2 authentication is OPTIONAL to +- implement and use (as discussed in more detail in [RFC3723]). +- +-7. IANA Considerations +- +- This document describes three SLP Templates. They have been reviewed +- and approved by the IESG and registered in the IANA's "SVRLOC +- Templates" registry. This process is described in the IANA +- Considerations section of [RFC2609]. +- +-8. Summary +- +- This document describes how SLP can be used by iSCSI initiators to +- find iSCSI targets and storage management servers. Service type +- templates for iSCSI targets and storage management servers are +- presented. +- +-9. Normative References +- +- [RFC2608] Guttman, E., Perkins, C., Veizades, J., and M. Day, +- "Service Location Protocol, Version 2", RFC 2608, June +- 1999. +- +- [RFC2609] Guttman, E., Perkins, C., and J. Kempf, "Service +- Templates and Service: Schemes", RFC 2609, June 1999. +- +- +- +- +-Bakke & Hufferd Standards Track [Page 19] +- +-RFC 4018 iSCSI and SLPv2 April 2005 +- +- +- [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate +- Requirement Levels", BCP 14, RFC 2119, March 1997. +- +- [RFC3491] Hoffman, P. and M. Blanchet, "Nameprep: A Stringprep +- Profile for Internationalized Domain Names (IDN)", RFC +- 3491, March 2003. +- +- [RFC3513] Hinden, R. and S. Deering, "Internet Protocol Version 6 +- (IPv6) Addressing Architecture", RFC 3513, April 2003. +- +- [RFC3720] Satran, J., Meth, K., Sapuntzakis, C., Chadalapaka, M., +- and E. Zeidner, "Internet Small Computer Systems +- Interface (iSCSI)", RFC 3720, April 2004. +- +- [RFC3722] Bakke, M., "String Profile for Internet Small Computer +- Systems Interface (iSCSI) Names", RFC 3722, April 2004. +- +- [RFC3723] Aboba, B., Tseng, J., Walker, J., Rangan, V., and F. +- Travostino, "Securing Block Storage Protocols over IP", +- RFC 3723, April 2004. +- +-10. Informative References +- +- [RFC2614] Kempf, J. and E. Guttman, "An API for Service Location", +- RFC 2614, June 1999. +- +- [SAM2] ANSI T10. "SCSI Architectural Model 2", March 2000. +- +- [RFC3721] Bakke, M., Hafner, J., Hufferd, J., Voruganti, K., and M. +- Krueger, "Internet Small Computer Systems Interface +- (iSCSI) Naming and Discovery", RFC 3721, April 2004. +- +- [ISNS] Tseng, J., Gibbons, K., Travostino, F., Du Laney, C. and +- J. Souza, "Internet Storage Name Service", Work in +- Progress, February 2004. +- +- [BOOT] Sarkar, P., Missimer, D. and C. Sapuntzakis, "A Standard +- for Bootstrapping Clients using the iSCSI Protocol", Work +- in Progress, March 2004. +- +- [RFC3105] Kempf, J. and G. Montenegro, "Finding an RSIP Server with +- SLP", RFC 3105, October 2001. +- +- +- +- +- +- +- +- +- +-Bakke & Hufferd Standards Track [Page 20] +- +-RFC 4018 iSCSI and SLPv2 April 2005 +- +- +-11. Acknowledgements +- +- This document was produced by the iSCSI Naming and Discovery team, +- including Joe Czap, Jim Hafner, John Hufferd, and Kaladhar Voruganti +- (IBM), Howard Hall (Pirus), Jack Harwood (EMC), Yaron Klein (Sanrad), +- Marjorie Krueger (HP), Lawrence Lamers (San Valley), Todd Sperry +- (Adaptec), and Joshua Tseng (Nishan). Thanks also to Julian Satran +- (IBM) for suggesting the use of SLP for iSCSI discovery, and to Matt +- Peterson (Caldera) and James Kempf (Sun) for reviewing the document +- from an SLP perspective. +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-Bakke & Hufferd Standards Track [Page 21] +- +-RFC 4018 iSCSI and SLPv2 April 2005 +- +- +-Authors' Addresses +- +- Mark Bakke +- Cisco Systems, Inc. +- 7900 International Drive, Suite 400 +- Bloomington, MN +- USA 55425 +- +- EMail: mbakke@cisco.com +- +- +- Kaladhar Voruganti +- IBM Almaden Research Center +- 650 Harry Road +- San Jose, CA 95120 +- +- EMail: kaladhar@us.ibm.com +- +- +- John L. Hufferd +- IBM Storage Systems Group +- 5600 Cottle Road +- San Jose, CA 95193 +- +- Phone: +1 408 997-6136 +- EMail: jlhufferd@comcast.net +- +- +- Marjorie Krueger +- Hewlett-Packard Corporation +- 8000 Foothills Blvd +- Roseville, CA 95747-5668, USA +- +- Phone: +1 916 785-2656 +- EMail: marjorie_krueger@hp.com +- +- +- Todd Sperry +- Adaptec, Inc. +- 691 South Milpitas Boulevard +- Milpitas, Ca. 95035 +- +- Phone: +1 408 957-4980 +- EMail: todd_sperry@adaptec.com +- +- +- +- +- +- +- +-Bakke & Hufferd Standards Track [Page 22] +- +-RFC 4018 iSCSI and SLPv2 April 2005 +- +- +-Full Copyright Statement +- +- Copyright (C) The Internet Society (2005). +- +- This document is subject to the rights, licenses and restrictions +- contained in BCP 78, and except as set forth therein, the authors +- retain all their rights. +- +- This document and the information contained herein are provided on an +- "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS +- OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET +- ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, +- INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE +- INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED +- WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +- +-Intellectual Property +- +- The IETF takes no position regarding the validity or scope of any +- Intellectual Property Rights or other rights that might be claimed to +- pertain to the implementation or use of the technology described in +- this document or the extent to which any license under such rights +- might or might not be available; nor does it represent that it has +- made any independent effort to identify any such rights. Information +- on the procedures with respect to rights in RFC documents can be +- found in BCP 78 and BCP 79. +- +- Copies of IPR disclosures made to the IETF Secretariat and any +- assurances of licenses to be made available, or the result of an +- attempt made to obtain a general license or permission for the use of +- such proprietary rights by implementers or users of this +- specification can be obtained from the IETF on-line IPR repository at +- http://www.ietf.org/ipr. +- +- The IETF invites any interested party to bring to its attention any +- copyrights, patents or patent applications, or other proprietary +- rights that may cover technology that may be required to implement +- this standard. Please address the information to the IETF at ietf- +- ipr@ietf.org. +- +-Acknowledgement +- +- Funding for the RFC Editor function is currently provided by the +- Internet Society. +- +- +- +- +- +- +- +-Bakke & Hufferd Standards Track [Page 23] +- +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/open-isns/doc/rfc4171.txt open-iscsi-2.0-872-rc4-bnx2i.work/utils/open-isns/doc/rfc4171.txt +--- open-iscsi-2.0-872-rc4-bnx2i/utils/open-isns/doc/rfc4171.txt 2010-07-11 04:05:58.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/utils/open-isns/doc/rfc4171.txt 1969-12-31 18:00:00.000000000 -0600 +@@ -1,6891 +0,0 @@ +- +- +- +- +- +- +-Network Working Group J. Tseng +-Request for Comments: 4171 Riverbed Technology +-Category: Standards Track K. Gibbons +- McDATA Corporation +- F. Travostino +- Nortel +- C. Du Laney +- Rincon Research Corporation +- J. Souza +- Microsoft +- September 2005 +- +- +- Internet Storage Name Service (iSNS) +- +-Status of This Memo +- +- This document specifies an Internet standards track protocol for the +- Internet community, and requests discussion and suggestions for +- improvements. Please refer to the current edition of the "Internet +- Official Protocol Standards" (STD 1) for the standardization state +- and status of this protocol. Distribution of this memo is unlimited. +- +-Copyright Notice +- +- Copyright (C) The Internet Society (2005). +- +-Abstract +- +- This document specifies the Internet Storage Name Service (iSNS) +- protocol, used for interaction between iSNS servers and iSNS clients, +- which facilitates automated discovery, management, and configuration +- of iSCSI and Fibre Channel devices (using iFCP gateways) on a TCP/IP +- network. iSNS provides intelligent storage discovery and management +- services comparable to those found in Fibre Channel networks, +- allowing a commodity IP network to function in a capacity similar to +- that of a storage area network. iSNS facilitates a seamless +- integration of IP and Fibre Channel networks due to its ability to +- emulate Fibre Channel fabric services and to manage both iSCSI and +- Fibre Channel devices. iSNS thereby provides value in any storage +- network comprised of iSCSI devices, Fibre Channel devices (using iFCP +- gateways), or any combination thereof. +- +- +- +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 1] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +-Table of Contents +- +- 1. Introduction................................................... 6 +- 1.1. Conventions Used in This Document........................ 6 +- 1.2. Purpose of This Document................................. 6 +- 2. iSNS Overview.................................................. 6 +- 2.1. iSNS Architectural Components ........................... 7 +- 2.1.1. iSNS Protocol (iSNSP) ........................... 7 +- 2.1.2. iSNS Client...................................... 7 +- 2.1.3. iSNS Server...................................... 7 +- 2.1.4. iSNS Database ................................... 7 +- 2.1.5. iSCSI............................................ 7 +- 2.1.6. iFCP............................................. 7 +- 2.2. iSNS Functional Overview................................. 8 +- 2.2.1. Name Registration Service........................ 8 +- 2.2.2. Discovery Domain and Login Control Service....... 8 +- 2.2.3. State Change Notification Service............... 10 +- 2.2.4. Open Mapping between +- Fibre Channel and iSCSI Devices................. 11 +- 2.3. iSNS Usage Model........................................ 11 +- 2.3.1. iSCSI Initiator................................. 12 +- 2.3.2. iSCSI Target.................................... 12 +- 2.3.3. iSCSI-FC Gateway................................ 12 +- 2.3.4. iFCP Gateway.................................... 12 +- 2.3.5. Management Station.............................. 12 +- 2.4. Administratively Controlled iSNS Settings............... 13 +- 2.5. iSNS Server Discovery .................................. 14 +- 2.5.1. Service Location Protocol (SLP)................. 14 +- 2.5.2. Dynamic Host Configuration Protocol (DHCP)...... 14 +- 2.5.3. iSNS Heartbeat Message.......................... 14 +- 2.6. iSNS and Network Address Translation (NAT).............. 14 +- 2.7. Transfer of iSNS Database Records between iSNS Servers.. 15 +- 2.8. Backup iSNS Servers..................................... 17 +- 2.9. Transport Protocols..................................... 19 +- 2.9.1. Use of TCP for iSNS Communication............... 19 +- 2.9.2. Use of UDP for iSNS Communication............... 20 +- 2.9.3. iSNS Multicast and Broadcast Messages........... 20 +- 2.10. Simple Network Management Protocol (SNMP) Requirements.. 21 +- 3. iSNS Object Model............................................. 21 +- 3.1. Network Entity Object .................................. 22 +- 3.2. Portal Object .......................................... 22 +- 3.3. Storage Node Object..................................... 22 +- 3.4. Portal Group Object..................................... 23 +- 3.5. FC Device Object........................................ 24 +- 3.6. Discovery Domain Object................................. 24 +- 3.7. Discovery Domain Set Object............................. 24 +- 3.8. iSNS Database Model..................................... 24 +- 4. iSNS Implementation Requirements.............................. 25 +- +- +- +-Tseng, et al. Standards Track [Page 2] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- 4.1. iSCSI Requirements...................................... 25 +- 4.1.1. Required Attributes for Support of iSCSI........ 26 +- 4.1.2. Examples: iSCSI Object Model Diagrams........... 28 +- 4.1.3. Required Commands and +- Response Messages for Support of iSCSI.......... 30 +- 4.2. iFCP Requirements....................................... 31 +- 4.2.1. Required Attributes for Support of iFCP......... 31 +- 4.2.2. Example: iFCP Object Model Diagram.............. 32 +- 4.2.3. Required Commands and +- Response Messages for Support of iFCP........... 34 +- 5. iSNSP Message Format.......................................... 35 +- 5.1. iSNSP PDU Header........................................ 35 +- 5.1.1. iSNSP Version................................... 36 +- 5.1.2. iSNSP Function ID............................... 36 +- 5.1.3. iSNSP PDU Length................................ 36 +- 5.1.4. iSNSP Flags..................................... 36 +- 5.1.5. iSNSP Transaction ID............................ 36 +- 5.1.6. iSNSP Sequence ID............................... 37 +- 5.2. iSNSP Message Segmentation and Reassembly............... 37 +- 5.3. iSNSP PDU Payload....................................... 37 +- 5.3.1. Attribute Value 4-Byte Alignment................ 38 +- 5.4. iSNSP Response Status Codes............................. 39 +- 5.5. Authentication for iSNS Multicast and Broadcast Messages 39 +- 5.6. Registration and Query Messages......................... 41 +- 5.6.1. Source Attribute................................ 42 +- 5.6.2. Message Key Attributes.......................... 42 +- 5.6.3. Delimiter Attribute............................. 42 +- 5.6.4. Operating Attributes............................ 43 +- 5.6.5. Registration and Query Request Message Types ... 44 +- 5.7. Response Messages....................................... 66 +- 5.7.1. Status Code..................................... 66 +- 5.7.2. Message Key Attributes in Response.............. 66 +- 5.7.3. Delimiter Attribute in Response................. 67 +- 5.7.4. Operating Attributes in Response................ 67 +- 5.7.5. Registration and Query Response Message Type.... 67 +- 5.8. Vendor-Specific Messages................................ 72 +- 6. iSNS Attributes............................................... 73 +- 6.1. iSNS Attribute Summary.................................. 73 +- 6.2. Entity Identifier-Keyed Attributes...................... 76 +- 6.2.1. Entity Identifier (EID)......................... 76 +- 6.2.2. Entity Protocol................................. 76 +- 6.2.3. Management IP Address .......................... 77 +- 6.2.4. Entity Registration Timestamp .................. 77 +- 6.2.5. Protocol Version Range.......................... 77 +- 6.2.6. Registration Period............................. 78 +- 6.2.7. Entity Index.................................... 78 +- 6.2.8. Entity Next Index............................... 79 +- 6.2.9. Entity ISAKMP Phase-1 Proposals................. 79 +- +- +- +-Tseng, et al. Standards Track [Page 3] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- 6.2.10. Entity Certificate.............................. 79 +- 6.3. Portal-Keyed Attributes................................. 80 +- 6.3.1. Portal IP Address............................... 80 +- 6.3.2. Portal TCP/UDP Port............................. 80 +- 6.3.3. Portal Symbolic Name............................ 80 +- 6.3.4. Entity Status Inquiry Interval.................. 81 +- 6.3.5. ESI Port........................................ 82 +- 6.3.6. Portal Index.................................... 82 +- 6.3.7. SCN Port........................................ 82 +- 6.3.8. Portal Next Index............................... 83 +- 6.3.9. Portal Security Bitmap.......................... 83 +- 6.3.10. Portal ISAKMP Phase-1 Proposals................. 84 +- 6.3.11. Portal ISAKMP Phase-2 Proposals................. 84 +- 6.3.12. Portal Certificate.............................. 84 +- 6.4. iSCSI Node-Keyed Attributes............................. 84 +- 6.4.1. iSCSI Name...................................... 85 +- 6.4.2. iSCSI Node Type................................. 85 +- 6.4.3. iSCSI Node Alias................................ 86 +- 6.4.4. iSCSI Node SCN Bitmap .......................... 86 +- 6.4.5. iSCSI Node Index................................ 87 +- 6.4.6. WWNN Token...................................... 87 +- 6.4.7. iSCSI Node Next Index .......................... 89 +- 6.4.8. iSCSI AuthMethod................................ 89 +- 6.5. Portal Group (PG) Object-Keyed Attributes............... 89 +- 6.5.1. Portal Group iSCSI Name......................... 90 +- 6.5.2. PG Portal IP Addr............................... 90 +- 6.5.3. PG Portal TCP/UDP Port.......................... 90 +- 6.5.4. Portal Group Tag (PGT).......................... 90 +- 6.5.5. Portal Group Index.............................. 90 +- 6.5.6. Portal Group Next Index......................... 91 +- 6.6. FC Port Name-Keyed Attributes .......................... 91 +- 6.6.1. FC Port Name (WWPN)............................. 91 +- 6.6.2. Port ID (FC_ID)................................. 91 +- 6.6.3. FC Port Type.................................... 92 +- 6.6.4. Symbolic Port Name.............................. 92 +- 6.6.5. Fabric Port Name (FWWN)......................... 92 +- 6.6.6. Hard Address.................................... 92 +- 6.6.7. Port IP Address................................. 92 +- 6.6.8. Class of Service (COS).......................... 93 +- 6.6.9. FC-4 Types...................................... 93 +- 6.6.10. FC-4 Descriptor................................. 93 +- 6.6.11. FC-4 Features .................................. 93 +- 6.6.12. iFCP SCN Bitmap................................. 93 +- 6.6.13. Port Role....................................... 94 +- 6.6.14. Permanent Port Name (PPN)....................... 95 +- 6.7. Node-Keyed Attributes .................................. 95 +- 6.7.1. FC Node Name (WWNN)............................. 95 +- 6.7.2. Symbolic Node Name.............................. 95 +- +- +- +-Tseng, et al. Standards Track [Page 4] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- 6.7.3. Node IP Address................................. 95 +- 6.7.4. Node IPA........................................ 96 +- 6.7.5. Proxy iSCSI Name................................ 96 +- 6.8. Other Attributes........................................ 96 +- 6.8.1. FC-4 Type Code.................................. 96 +- 6.8.2. iFCP Switch Name................................ 96 +- 6.8.3. iFCP Transparent Mode Commands.................. 97 +- 6.9. iSNS Server-Specific Attributes......................... 97 +- 6.9.1. iSNS Server Vendor OUI.......................... 98 +- 6.10. Vendor-Specific Attributes.............................. 98 +- 6.10.1. Vendor-Specific Server Attributes............... 98 +- 6.10.2. Vendor-Specific Entity Attributes............... 98 +- 6.10.3. Vendor-Specific Portal Attributes............... 99 +- 6.10.4. Vendor-Specific iSCSI Node Attributes........... 99 +- 6.10.5. Vendor-Specific FC Port Name Attributes......... 99 +- 6.10.6. Vendor-Specific FC Node Name Attributes......... 99 +- 6.10.7. Vendor-Specific Discovery Domain Attributes..... 99 +- 6.10.8. Vendor-Specific Discovery Domain Set Attributes. 99 +- 6.10.9. Other Vendor-Specific Attributes................ 99 +- 6.11. Discovery Domain Registration Attributes............... 100 +- 6.11.1. DD Set ID Keyed Attributes..................... 100 +- 6.11.2. DD ID Keyed Attributes......................... 101 +- 7. Security Considerations...................................... 103 +- 7.1. iSNS Security Threat Analysis ......................... 103 +- 7.2. iSNS Security Implementation and Usage Requirements.... 104 +- 7.3. Discovering Security Requirements of Peer Devices...... 105 +- 7.4. Configuring Security Policies of iFCP/iSCSI Devices.... 106 +- 7.5. Resource Issues........................................ 107 +- 7.6. iSNS Interaction with IKE and IPSec.................... 107 +- 8. IANA Considerations.......................................... 107 +- 8.1. Registry of Block Storage Protocols.................... 107 +- 8.2. Registry of Standard iSNS Attributes .................. 108 +- 8.3. Block Structure Descriptor (BSD) Registry.............. 108 +- 9. Normative References......................................... 109 +- 10. Informative References....................................... 110 +- Appendix A: iSNS Examples........................................ 112 +- A.1. iSCSI Initialization Example........................... 112 +- A.1.1. Simple iSCSI Target Registration............... 112 +- A.1.2. Target Registration and DD Configuration....... 114 +- A.1.3. Initiator Registration and Target Discovery.... 117 +- Acknowledgements................................................. 121 +- +- +- +- +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 5] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +-1. Introduction +- +-1.1. Conventions Used in This Document +- +- "iSNS" refers to the storage network model and associated services +- covered in the text of this document. +- +- The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +- "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +- document are to be interpreted as described in [RFC2119]. +- +- All frame formats are in big endian network byte order. +- +- All unused fields and bitmaps, including those that are RESERVED, +- SHOULD be set to zero when sending and ignored when receiving. +- +-1.2. Purpose of This Document +- +- This is a standards track document containing normative text +- specifying the iSNS Protocol, used by iSCSI and iFCP devices to +- communicate with the iSNS server. This document focuses on the +- interaction between iSNS servers and iSNS clients; interactions among +- multiple authoritative primary iSNS servers are a potential topic for +- future work. +- +-2. iSNS Overview +- +- iSNS facilitates scalable configuration and management of iSCSI and +- Fibre Channel (FCP) storage devices in an IP network by providing a +- set of services comparable to that available in Fibre Channel +- networks. iSNS thus allows a commodity IP network to function at a +- level of intelligence comparable to a Fibre Channel fabric. iSNS +- allows the administrator to go beyond a simple device-by-device +- management model, where each storage device is manually and +- individually configured with its own list of known initiators and +- targets. Using the iSNS, each storage device subordinates its +- discovery and management responsibilities to the iSNS server. The +- iSNS server thereby serves as the consolidated configuration point +- through which management stations can configure and manage the entire +- storage network, including both iSCSI and Fibre Channel devices. +- +- iSNS can be implemented to support iSCSI and/or iFCP protocols as +- needed; an iSNS implementation MAY provide support for one or both of +- these protocols as desired by the implementor. Implementation +- requirements within each of these protocols are further discussed in +- Section 5. Use of iSNS is OPTIONAL for iSCSI and REQUIRED for iFCP. +- +- +- +- +- +-Tseng, et al. Standards Track [Page 6] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +-2.1. iSNS Architectural Components +- +-2.1.1. iSNS Protocol (iSNSP) +- +- The iSNS Protocol (iSNSP) is a flexible and lightweight protocol that +- specifies how iSNS clients and servers communicate. It is suitable +- for various platforms, including switches and targets as well as +- server hosts. +- +-2.1.2. iSNS Client +- +- iSNS clients initiate transactions with iSNS servers using the iSNSP. +- iSNS clients are processes that are co-resident in the storage +- device, and that can register device attribute information, download +- information about other registered clients in a common Discovery +- Domain (DD), and receive asynchronous notification of events that +- occur in their DD(s). Management stations are a special type of iSNS +- client that have access to all DDs stored in the iSNS. +- +-2.1.3. iSNS Server +- +- iSNS servers respond to iSNS protocol queries and requests, and +- initiate iSNS protocol State Change Notifications. Properly +- authenticated information submitted by a registration request is +- stored in an iSNS database. +- +-2.1.4. iSNS Database +- +- The iSNS database is the information repository for the iSNS +- server(s). It maintains information about iSNS client attributes. A +- directory-enabled implementation of iSNS may store client attributes +- in an LDAP directory infrastructure. +- +-2.1.5. iSCSI +- +- iSCSI (Internet SCSI) is an encapsulation of SCSI for a new +- generation of storage devices interconnected with TCP/IP [iSCSI]. +- +-2.1.6. iFCP +- +- iFCP (Internet FCP) is a gateway-to-gateway protocol designed to +- interconnect existing Fibre Channel and SCSI devices using TCP/IP. +- iFCP maps the existing FCP standard and associated Fibre Channel +- services to TCP/IP [iFCP]. +- +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 7] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +-2.2. iSNS Functional Overview +- +- There are four main functions of the iSNS: +- +- 1) A Name Service Providing Storage Resource Discovery +- +- 2) Discovery Domain (DD) and Login Control Service +- +- 3) State Change Notification Service +- +- 4) Open Mapping of Fibre Channel and iSCSI Devices +- +-2.2.1. Name Registration Service +- +- The iSNS provides a registration function to allow all entities in a +- storage network to register and query the iSNS database. Both +- targets and initiators can register in the iSNS database, as well as +- query for information about other initiators and targets. This +- allows, for example, a client initiator to obtain information about +- target devices from the iSNS server. This service is modeled on the +- Fibre Channel Generic Services Name Server described in FC-GS-4, with +- extensions, operating within the context of an IP network. +- +- The naming registration service also provides the ability to obtain a +- network-unique Domain ID for iFCP gateways when one is required. +- +-2.2.2. Discovery Domain and Login Control Service +- +- The Discovery Domain (DD) Service facilitates the partitioning of +- Storage Nodes into more manageable groupings for administrative and +- login control purposes. It allows the administrator to limit the +- login process of each host to the more appropriate subset of targets +- registered in the iSNS. This is particularly important for reducing +- the number of unnecessary logins (iSCSI logins or Fibre Channel Port +- Logins), and for limiting the amount of time that the host spends +- initializing login relationships as the size of the storage network +- scales up. Storage Nodes must be in at least one common enabled DD +- in order to obtain information about each other. Devices can be +- members of multiple DDs simultaneously. +- +- Login Control allows targets to delegate their access +- control/authorization policies to the iSNS server. This is +- consistent with the goal of centralizing management of those storage +- devices using the iSNS server. The target node or device downloads +- the list of authorized initiators from the iSNS. Each node or device +- is uniquely identified by an iSCSI Name or FC Port Name. Only +- +- +- +- +- +-Tseng, et al. Standards Track [Page 8] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- initiators that match the required identification and authorization +- provided by the iSNS will be allowed access by that target Node +- during session establishment. +- +- Placing Portals of a Network Entity into Discovery Domains allows +- administrators to indicate the preferred IP Portal interface through +- which storage traffic should access specific Storage Nodes of that +- Network Entity. If no Portals of a Network Entity have been placed +- into a DD, then queries scoped to that DD SHALL report all Portals of +- that Network Entity. If one or more Portals of a Network Entity have +- been placed into a DD, then queries scoped to that DD SHALL report +- only those Portals that have been explicitly placed in the DD. +- +- DDs can be managed offline through a separate management workstation +- using the iSNSP or SNMP. If the target opts to use the Login Control +- feature of the iSNS, the target delegates management of access +- control policy (i.e., the list of initiators allowed to log in to +- that target) to the management workstations that are managing the +- configuration in the iSNS database. +- +- If administratively authorized, a target can upload its own Login +- Control list. This is accomplished using the DDReg message and +- listing the iSCSI name of each initiator to be registered in the +- target's DD. +- +- An implementation MAY decide that newly registered devices that have +- not explicitly been placed into a DD by the management station will +- be placed into a "default DD" contained in a "default DDS" whose +- initial DD Set Status value is "enabled". This makes them visible to +- other devices in the default DD. Other implementations MAY decide +- that they are registered with no DD, making them inaccessible to +- source-scoped iSNSP messages. +- +- The iSNS server uses the Source Attribute of each iSNSP message to +- determine the originator of the request and to scope the operation to +- a set of Discovery Domains. In addition, the Node Type (specified in +- the iFCP or iSCSI Node Type bitmap field) may also be used to +- determine authorization for the specified iSNS operation. For +- example, only Control Nodes are authorized to create or delete +- discovery domains. +- +- Valid and active Discovery Domains (DDs) belong to at least one +- active Discovery Domain Set (DDS). Discovery Domains that do not +- belong to an activated DDS are not enabled. The iSNS server MUST +- maintain the state of DD membership for all Storage Nodes, even for +- those that have been deregistered. DD membership is persistent +- regardless of whether a Storage Node is actively registered in the +- iSNS database. +- +- +- +-Tseng, et al. Standards Track [Page 9] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +-2.2.3. State Change Notification Service +- +- The State Change Notification (SCN) service allows the iSNS Server to +- issue notifications about network events that affect the operational +- state of Storage Nodes. The iSNS client may register for +- notifications on behalf of its Storage Nodes for notification of +- events detected by the iSNS Server. SCNs notify iSNS clients of +- explicit or implicit changes to the iSNS database; they do not +- necessarily indicate the state of connectivity to peer storage +- devices in the network. The response of a storage device to receipt +- of an SCN is implementation-specific; the policy for responding to +- SCNs is outside of the scope of this document. +- +- There are two types of SCN registrations: regular registrations and +- management registrations. Management registrations result in +- management SCNs, whereas regular registrations result in regular +- SCNs. The type of registration and SCN message is indicated in the +- SCN bitmap (see Sections 6.4.4 and 6.6.12). +- +- A regular SCN registration indicates that the Discovery Domain +- Service SHALL be used to control the distribution of SCN messages. +- Receipt of regular SCNs is limited to the discovery domains in which +- the SCN-triggering event takes place. Regular SCNs do not contain +- information about discovery domains. +- +- A management SCN registration can only by requested by Control Nodes. +- Management SCNs resulting from management registrations are not bound +- by the Discovery Domain service. Authorization to request management +- SCN registrations may be administratively controlled. +- +- The iSNS server SHOULD be implemented with hardware and software +- resources sufficient to support the expected number of iSNS clients. +- However, if resources are unexpectedly exhausted, then the iSNS +- server MAY refuse SCN service by returning an SCN Registration +- Rejected (Status Code 17). The rejection might occur in situations +- where the network size or current number of SCN registrations has +- passed an implementation-specific threshold. A client not allowed to +- register for SCNs may decide to monitor its sessions with other +- storage devices directly. +- +- +- The specific notification mechanism by which the iSNS server learns +- of the events that trigger SCNs is implementation-specific, but can +- include examples such as explicit notification messages from an iSNS +- client to the iSNS server, or a hardware interrupt to a switch-hosted +- iSNS server as a result of link failure. +- +- +- +- +- +-Tseng, et al. Standards Track [Page 10] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +-2.2.4. Open Mapping between Fibre Channel and iSCSI Devices +- +- The iSNS database stores naming and discovery information about both +- Fibre Channel and iSCSI devices. This allows the iSNS server to +- store mappings of a Fibre Channel device to a proxy iSCSI device +- "image" in the IP network. Similarly, mappings of an iSCSI device to +- a "proxy WWN" can be stored under the WWNN Token field for that iSCSI +- device. +- +- Furthermore, through use of iSCSI-FC gateways, Fibre Channel-aware +- management stations can interact with the iSNS server to retrieve +- information about Fibre Channel devices, and use this information to +- manage Fibre Channel and iSCSI devices. This allows management +- functions such as Discovery Domains and State Change Notifications to +- be applied seamlessly to both iSCSI and Fibre Channel devices, +- facilitating integration of IP networks with Fibre Channel devices +- and fabrics. +- +- Note that Fibre Channel attributes are stored as iFCP attributes, and +- that the ability to store this information in the iSNS server is +- useful even if the iFCP protocol is not implemented. In particular, +- tag 101 can be used to store a "Proxy iSCSI Name" for Fibre Channel +- devices registered in the iSNS server. This field is used to +- associate the FC device with an iSCSI registration entry that is used +- for the Fibre Channel device to communicate with iSCSI devices in the +- IP network. Conversely, tag 37 (see Section 6.1) contains a WWNN +- Token field, which can be used to store an FC Node Name (WWNN) value +- used by iSCSI-FC gateways to represent an iSCSI device in the Fibre +- Channel domain. +- +- By storing the mapping between Fibre Channel and iSCSI devices in the +- iSNS server, this information becomes open to any authorized iSNS +- client wishing to retrieve and use this information. In many cases, +- this provides advantages over storing the information internally +- within an iSCSI-FC gateway, where the mapping is inaccessible to +- other devices except by proprietary mechanisms. +- +-2.3. iSNS Usage Model +- +- The following is a high-level description of how each type of device +- in a storage network can utilize iSNS. Each type of device interacts +- with the iSNS server as an iSNS client and must register itself in +- the iSNS database in order to access services provided by the iSNS. +- +- +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 11] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +-2.3.1. iSCSI Initiator +- +- An iSCSI initiator will query the iSNS server to discover the +- presence and location of iSCSI target devices. It may also request +- state change notifications (SCNs) so that it can be notified of new +- targets that appear on the network after the initial bootup and +- discovery. SCNs can also inform the iSCSI initiator of targets that +- have been removed from or no longer available in the storage network, +- so that incomplete storage sessions can be gracefully terminated and +- resources for non-existent targets can be reallocated. +- +-2.3.2. iSCSI Target +- +- An iSCSI target allows itself to be discovered by iSCSI initiators by +- registering its presence in the iSNS server. It may also register +- for SCNs in order to detect the addition or removal of initiators for +- resource allocation purposes. The iSCSI target device may also +- register for Entity Status Inquiry (ESI) messages, which allow the +- iSNS to monitor the target device's availability in the storage +- network. +- +-2.3.3. iSCSI-FC Gateway +- +- An iSCSI-FC gateway bridges devices in a Fibre Channel network to an +- iSCSI/IP network. It may use the iSNS server to store FC device +- attributes discovered in the FC name server, as well as mappings of +- FC device identifiers to iSCSI device identifiers. iSNS has the +- capability to store all attributes of both iSCSI and Fibre Channel +- devices; iSCSI devices are managed through direct interaction using +- iSNS, while FC devices can be indirectly managed through iSNS +- interactions with the iSCSI-FC gateway. This allows both iSCSI and +- Fibre Channel devices to be managed in a seamless management +- framework. +- +-2.3.4. iFCP Gateway +- +- An iFCP gateway uses iSNS to emulate the services provided by a Fibre +- Channel name server for FC devices in its gateway region. iSNS +- provides basic discovery and zoning configuration information to be +- enforced by the iFCP gateway. When queried, iSNS returns information +- on the N_Port network address used to establish iFCP sessions between +- FC devices supported by iFCP gateways. +- +-2.3.5. Management Station +- +- A management station uses iSNS to monitor storage devices and to +- enable or disable storage sessions by configuring discovery domains. +- A management station usually interacts with the iSNS server as a +- +- +- +-Tseng, et al. Standards Track [Page 12] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- Control Node endowed with access to all iSNS database records and +- with special privileges to configure discovery domains. Through +- manipulation of discovery domains, the management station controls +- the scope of device discovery for iSNS clients querying the iSNS +- server. +- +-2.4. Administratively Controlled iSNS Settings +- +- Some important operational settings for the iSNS server are +- configured using administrative means, such as a configuration file, +- a console port, an SNMP, or another implementation-specific method. +- These administratively-controlled settings cannot be configured using +- the iSNS Protocol, and therefore the iSNS server implementation MUST +- provide for such an administrative control interface. +- +- The following is a list of parameters that are administratively +- controlled for the iSNS server. In the absence of alternative +- settings provided by the administrator, the following specified +- default settings MUST be used. +- +- Setting Default Setting +- ------- --------------- +- ESI Non-Response Threshold 3 (see 5.6.5.13) +- Management SCNs (Control Nodes only) enabled (see 5.6.5.8) +- Default DD/DDS disabled +- DD/DDS Modification +- - Control Node enabled +- - iSCSI Target Node Type disabled +- - iSCSI Initiator Node Type disabled +- - iFCP Target Port Role disabled +- - iFCP Initiator Port Role disabled +- Authorized Control Nodes N/A +- +- ESI Non-Response Threshold: determines the number of ESI messages +- sent without receiving a response before the network +- entity is deregistered from the iSNS database. +- +- Management SCN for Control Node: determines whether a registered +- Control Node is permitted to register to receive +- Management SCNs. +- +- Default DD/DDS: determines whether a newly registered device not +- explicitly placed into a discovery domain (DD) and +- discovery domain set (DDS) is placed into a default +- DD/DDS. +- +- DD/DDS Modification: determines whether the specified type of Node is +- allowed to add, delete or update DDs and DDSs. +- +- +- +-Tseng, et al. Standards Track [Page 13] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- Authorized Control Nodes: a list of Nodes identified by iSCSI Name or +- FC Port Name WWPN that are authorized to register as +- Control Nodes. +- +-2.5. iSNS Server Discovery +- +-2.5.1. Service Location Protocol (SLP) +- +- The Service Location Protocol (SLP) provides a flexible and scalable +- framework for providing hosts with access to information about the +- existence, location, and configuration of networked services, +- including the iSNS server. SLP can be used by iSNS clients to +- discover the IP address or FQDN of the iSNS server. To implement +- discovery through SLP, a Service Agent (SA) should be cohosted in the +- iSNS server, and a User Agent (UA) should be in each iSNS client. +- Each client multicasts a discovery message requesting the IP address +- of the iSNS server(s). The SA responds to this request. Optionally, +- the location of the iSNS server can be stored in the SLP Directory +- Agent (DA). +- +- Note that a complete description and specification of SLP can be +- found in [RFC2608], and is beyond the scope of this document. A +- service template for using SLP to locate iSNS servers can be found in +- [iSCSI-SLP]. +- +-2.5.2. Dynamic Host Configuration Protocol (DHCP) +- +- The IP address of the iSNS server can be stored in a DHCP server to +- be downloaded by iSNS clients using a DHCP option. The DHCP option +- number to be used for distributing the iSNS server location is found +- in [iSNSOption]. +- +-2.5.3. iSNS Heartbeat Message +- +- The iSNS heartbeat message is described in Section 5.6.5.14. It +- allows iSNS clients within the broadcast or multicast domain of the +- iSNS server to discover the location of the active iSNS server and +- any backup servers. +- +-2.6. iSNS and Network Address Translation (NAT) +- +- The existence of NAT will have an impact upon information retrieved +- from the iSNS server. If the iSNS client exists in an addressing +- domain different from that of the iSNS server, then IP address +- information stored in the iSNS server may not be correct when +- interpreted in the domain of the iSNS client. +- +- +- +- +- +-Tseng, et al. Standards Track [Page 14] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- There are several possible approaches to allow operation of iSNS +- within a NAT network. The first approach is to require use of the +- canonical TCP port number by both targets and initiators when +- addressing targets across a NAT boundary, and for the iSNS client not +- to query for nominal IP addresses. Rather, the iSNS client queries +- for the DNS Fully Qualified Domain Name stored in the Entity +- Identifier field when seeking addressing information. Once +- retrieved, the DNS name can be interpreted in each address domain and +- mapped to the appropriate IP address by local DNS servers. +- +- A second approach is to deploy a distributed network of iSNS servers. +- Local iSNS servers are deployed inside and outside NAT boundaries, +- with each local server storing relevant IP addresses for their +- respective NAT domains. Updates among the network of decentralized, +- local iSNS servers are handled using LDAP and appropriate NAT +- translation rules implemented within the update mechanism in each +- server. +- +- Finally, note that it is possible for an iSNS server in the private +- addressing domain behind a NAT boundary to exclusively support iSNS +- clients that are operating in the global IP addressing domain. If +- this is the case, the administrator only needs to ensure that the +- appropriate mappings are configured on the NAT gateways to allow the +- iSNS clients to initiate iSNSP sessions to the iSNS server. All +- registered addresses contained in the iSNS server are thus public IP +- addresses for use outside the NAT boundary. Care should be taken to +- ensure that there are no iSNS clients querying the server from inside +- the NAT boundary. +- +-2.7. Transfer of iSNS Database Records between iSNS Servers +- +- Transfer of iSNS database records between iSNS servers has important +- applications, including the following: +- +- 1) An independent organization needs to transfer storage information +- to a different organization. Each organization independently +- maintains its own iSNS infrastructure. To facilitate discovery +- of storage assets of the peer organization using IP, iSNS +- database records can be transferred between authoritative iSNS +- servers from each organization. This allows storage sessions to +- be established directly between devices residing in each +- organization's storage network infrastructure over a common IP +- network. +- +- 2) Multiple iSNS servers are desired for redundancy. Backup servers +- need to maintain copies of the primary server's dynamically +- changing database. +- +- +- +- +-Tseng, et al. Standards Track [Page 15] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- To support the above applications, information in an iSNS server can +- be distributed to other iSNS servers either using the iSNS protocol, +- or through out-of-band mechanisms using non-iSNS protocols. The +- following examples illustrate possible methods for transferring data +- records between iSNS servers. In the first example, a back-end LDAP +- information base is used to support the iSNS server, and the data is +- transferred using the LDAP protocol. Once the record transfer of the +- remote device is completed, it becomes visible and accessible to +- local devices using the local iSNS server. This allows local devices +- to establish sessions with remote devices (provided that firewall +- boundaries can be negotiated). +- +- +-------------------------+ +-------------------------+ +- |+------+ iSNSP | | iSNSP +-----+ | +- ||dev A |<----->+------+ | | +------+<----->|dev C| | +- |+------+ | | | | | | +-----+ | +- |+------+ iSNSP |local | | | |remote| iSNSP +-----+ | +- ||dev B |<----->| iSNS | | | | iSNS |<----->|dev D| | +- |+------+ |server| | | |server| +-----+ | +- |........ +--+---+ | WAN | +---+--+ | +- |.dev C'. | | Link | | | +- |........ | ============= | | +- | | | | | | +- | +--+---+ | | +---+--+ | +- | | local|<--- <--- <--- <-|remote| | +- | | LDAP | | LDAP: | | LDAP | | +- | +------+ Xfer "dev C"| +------+ | +- +-------------------------+ +-------------------------+ +- Enterprise Enterprise +- Network A Network B +- +- In the above diagram, two business partners wish to share storage +- "dev C". Using LDAP, the record for "dev C" can be transferred from +- Network B to Network A. Once accessible to the local iSNS server in +- Network A, local devices A and B can now discover and connect to "dev +- C". +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 16] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- +-------------------------+ +-------------------------+ +- |+------+ iSNSP | | iSNSP +-----+ | +- ||dev A |<----->+------+ | | +------+<----->|dev C| | +- |+------+ | | | | | | +-----+ | +- |+------+ iSNSP |local | | | |remote| iSNSP +-----+ | +- ||dev B |<----->| iSNS | | | | iSNS |<----->|dev D| | +- |+------+ |server| | | |server| +-----+ | +- |........ +------+ | WAN | +---+--+ | +- |.dev C'. ^ | Link | | | +- |........ | ============= v | +- | | | | |SNMP | +- | | | | | | +- | +--+----+ | | v | +- | | SNMP |<--- <--- <--- <---- | +- | | Mgmt | | SNMP: Xfer "dev C" | +- | |Station| | | | +- | +-------+ | | | +- +-------------------------+ +-------------------------+ +- Enterprise Enterprise +- Network A Network B +- +- The above diagram illustrates a second example of how iSNS records +- can be shared. This method uses an SNMP-based management station to +- retrieve (GET) the desired record for "dev C" manually, and then to +- store (SET) it on the local iSNS server directly. Once the record is +- transferred to the local iSNS server in Network A, "dev C" becomes +- visible and accessible (provided that firewall boundaries can be +- negotiated) to other devices in Network A. +- +- Other methods, including proprietary protocols, can be used to +- transfer device records between iSNS servers. Further discussion and +- explanation of these methodologies is beyond the scope of this +- document. +- +-2.8. Backup iSNS Servers +- +- This section offers a broad framework for implementation and +- deployment of iSNS backup servers. Server failover and recovery are +- topics of continuing research, and adequate resolution of issues such +- as split brain and primary server selection is dependent on the +- specific implementation requirements and deployment needs. The +- failover mechanisms discussed in this document focus on the +- interaction between iSNS clients and iSNS servers. Specifically, +- what is covered in this document includes the following: +- +- - iSNS client behavior and the iSNS protocol interaction between the +- client and multiple iSNS servers, some of which are backup +- servers. +- +- +- +-Tseng, et al. Standards Track [Page 17] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- - Required failover behaviors of the collection of iSNS servers that +- includes active and backup servers. +- +- However, note that this document does not specify the complete +- functional failover requirements of each iSNS server. In particular, +- it does not specify the complete set of protocol interactions among +- the iSNS servers that are required to achieve stable failover +- operation in an interoperable manner. +- +- For the purposes of this discussion, the specified backup mechanisms +- pertain to interaction among different logical iSNS servers. Note +- that it is possible to create multiple physical iSNS servers to form +- a single logical iSNS server cluster, and thus to distribute iSNS +- transaction processing among multiple physical servers. However, a +- more detailed discussion of the interactions between physical servers +- within a logical iSNS server cluster is beyond the scope of this +- document. +- +- Multiple logical iSNS servers can be used to provide redundancy in +- the event that the active iSNS server fails or is removed from the +- network. The methods described in Section 2.7 above can be used to +- transfer name server records to backup iSNS servers. Each backup +- server maintains a redundant copy of the name server database found +- in the primary iSNS server, and can respond to iSNS protocol messages +- in the same way as the active server. Each backup server SHOULD +- monitor the health and status of the active iSNS server, including +- checking to make sure its own database is synchronized with the +- active server's database. How each backup server accomplishes this +- is implementation-dependent, and may (or may not) include using the +- iSNS protocol. If the iSNS protocol is used, then the backup server +- MAY register itself in the active server's iSNS database as a Control +- Node, allowing it to receive state-change notifications. +- +- Generally, the administrator or some automated election process is +- responsible for initial and subsequent designation of the primary +- server and each backup server. +- +- A maximum of one logical backup iSNS server SHALL exist at any +- individual IP address, in order to avoid conflicts from multiple +- servers listening on the same canonical iSNS TCP or UDP port number. +- +- The iSNS heartbeat can also be used to coordinate the designation and +- selection of primary and backup iSNS servers. +- +- Each backup server MUST note its relative precedence in the active +- server's list of backup servers. If its precedence is not already +- known, each backup server MAY learn it from the iSNS heartbeat +- message, by noting the position of its IP address in the ordered list +- +- +- +-Tseng, et al. Standards Track [Page 18] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- of backup server IP addresses. For example, if it is the first +- backup listed in the heartbeat message, then its backup precedence is +- 1. If it is the third backup server listed, then its backup +- precedence is 3. +- +- If a backup server establishes that it has lost connectivity to the +- active server and other backup servers of higher precedence, then it +- SHOULD assume that it is the active server. The method of +- determining whether connectivity has been lost is implementation- +- specific. One possible approach is to assume that if the backup +- server does not receive iSNS heartbeat messages for a period of time, +- then connectivity to the active server has been lost. Alternatively, +- the backup server may establish TCP connections to the active server +- and other backup servers, with loss of connectivity determined +- through non-response to periodic echo or polling messages (using +- iSNSP, SNMP, or other protocols). +- +- When a backup server becomes the active server, it SHALL assume all +- active server responsibilities, including (if used) transmission of +- the iSNS heartbeat message. If transmitting the iSNS heartbeat, the +- backup server replaces the active Server IP Address and TCP/UDP Port +- entries with its own IP address and TCP/UDP Port, and begins +- incrementing the counter field from the last known value from the +- previously-active iSNS server. However, it MUST NOT change the +- original ordered list of backup server IP Address and TCP/UDP Port +- entries. If the primary backup server or other higher-precedence +- backup server returns, then the existing active server is responsible +- for ensuring that the new active server's database is up-to-date +- before demoting itself to its original status as backup. +- +- Since the primary and backup iSNS servers maintain a coordinated +- database, no re-registration by an iSNS Client is required when a +- backup server takes the active server role. Likewise, no re- +- registration by an iSNS Client is required when the previous primary +- server returns to the active server role. +- +-2.9. Transport Protocols +- +- The iSNS Protocol is transport-neutral. Query and registration +- messages are transported over TCP or UDP. iSNS heartbeat messages +- are transported using IP multicast or broadcast. +- +-2.9.1. Use of TCP for iSNS Communication +- +- It MUST be possible to use TCP for iSNS communication. The iSNS +- server MUST accept TCP connections for client registrations. To +- receive Entity Status Inquiry (ESI) (see Section 5.6.5.13) monitoring +- the use of TCP, the client registers the Portal ESI Interval and the +- +- +- +-Tseng, et al. Standards Track [Page 19] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- port number of the TCP port that will be used to receive ESI +- messages. The iSNS server initiates the TCP connection used to +- deliver the ESI message. This TCP connection does not need to be +- continuously open. +- +- To receive SCN notifications using TCP, the client registers the +- iSCSI or iFCP SCN Bitmap and the port number of the TCP port in the +- Portal used to receive SCNs. The iSNS server initiates the TCP +- connection used to deliver the SCN message. This TCP connection does +- not need to be continuously open. +- +- It is possible for an iSNS client to use the same TCP connection for +- SCN, ESI, and iSNS queries. Alternatively, separate connections may +- be used. +- +-2.9.2. Use of UDP for iSNS Communication +- +- The iSNS server MAY accept UDP messages for client registrations. +- The iSNS server MUST accept registrations from clients requesting +- UDP-based ESI and SCN messages. +- +- To receive UDP-based ESI monitoring messages, the client registers +- the port number of the UDP port in at least one Portal to be used to +- receive and respond to ESI messages from the iSNS server. If a +- Network Entity has multiple Portals with registered ESI UDP Ports, +- then ESI messages SHALL be delivered to every Portal registered to +- receive such messages. +- +- To receive UDP-based SCN notification messages, the client registers +- the port number of the UDP port in at least one Portal to be used to +- receive SCN messages from the iSNS server. If a Network Entity has +- multiple Portals with registered SCN UDP Ports, then SCN messages +- SHALL be delivered to each Portal registered to receive such +- messages. +- +- When using UDP to transport iSNS messages, each UDP datagram MUST +- contain exactly one iSNS PDU (see Section 5). +- +-2.9.3. iSNS Multicast and Broadcast Messages +- +- iSNS multicast messages are transported using IP multicast or +- broadcast. The iSNS heartbeat is the only iSNS multicast or +- broadcast message. This message is originated by the iSNS server and +- sent to all iSNS clients that are listening on the IP multicast +- address allocated for the iSNS heartbeat. +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 20] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +-2.10. Simple Network Management Protocol (SNMP) Requirements +- +- The iSNS Server may be managed via the iSNS MIB [iSNSMIB] using an +- SNMP management framework [RFC3411]. For a detailed overview of the +- documents that describe the current Internet-Standard Management +- Framework, please refer to Section 7 of RFC 3410 [RFC3410]. The iSNS +- MIB provides the ability to configure and monitor an iSNS server +- without using the iSNS protocol directly. SNMP management frameworks +- have several requirements for object indexing in order for objects to +- be accessed or added. +- +- SNMP uses an Object Identifier (OID) for object identification. The +- size of each OID is restricted to a maximum of 128 sub-identifiers. +- Both the iSCSI and iFCP protocol contain identifiers, such as the +- iSCSI Name, that are greater the 128 characters in length. Using +- such identifiers as an index would result in more than 128 sub- +- identifiers per OID. In order to support objects that have key +- identifiers whose maximum length is longer than the maximum SNMP- +- supported length, the iSNS server provides secondary non-zero integer +- index identifiers. These indexes SHALL be persistent for as long as +- the server is active. Furthermore, index values for recently +- deregistered objects SHOULD NOT be reused in the short term. Object +- attributes, including indexes, are described in detail in Section 6. +- +- For SNMP based management applications to create a new entry in a +- table of objects, a valid OID must be available to specify the table +- row. The iSNS server supports this by providing, for each type of +- object that can be added via SNMP, an object attribute that returns +- the next available non-zero integer index. This allows an SNMP +- client to request an OID to be used for registering a new object in +- the server. Object attributes, including next available index +- attributes, are described in detail in Section 6. +- +-3. iSNS Object Model +- +- iSNS provides the framework for the registration, discovery, and +- management of iSCSI devices and Fibre Channel-based devices (using +- iFCP). This architecture framework provides elements needed to +- describe various storage device objects and attributes that may exist +- on an IP storage network. Objects defined in this architecture +- framework include Network Entity, Portal, Storage Node, FC Device, +- Discovery Domain, and Discovery Domain Set. Each of these objects is +- described in greater detail in the following sections. +- +- +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 21] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +-3.1. Network Entity Object +- +- The Network Entity object is a container of Storage Node objects and +- Portal objects. It represents the infrastructure supporting access +- to a unique set of one or more Storage Nodes. The Entity Identifier +- attribute uniquely distinguishes a Network Entity, and is the key +- used to register a Network Entity object in an iSNS server. All +- Storage Nodes and Portals contained within a single Network Entity +- object operate as a cohesive unit. +- +- Note that it is possible for a single physical device or gateway to +- be represented by more than one logical Network Entity in the iSNS +- database. For example, one of the Storage Nodes on a physical device +- may be accessible from only a subset of the network interfaces (i.e., +- Portals) available on that device. In this case, a logical network +- entity (i.e., a "shadow entity") is created and used to contain the +- Portals and Storage Nodes that can operate cooperatively. No object +- (Portals, Storage Nodes, etc.) can be contained in more than one +- logical Network Entity. +- +- Similarly, it is possible for a logical Network Entity to be +- supported by more than one physical device or gateway. For example, +- multiple FC-iSCSI gateways may be used to bridge FC devices in a +- single Fibre Channel network. Collectively, the multiple gateways +- can be used to support a single logical Network Entity that is used +- to contain all the devices in that Fibre Channel network. +- +-3.2. Portal Object +- +- The Portal object is an interface through which access to Storage +- Nodes within the Network Entity can be obtained. The IP address and +- TCP/UDP Port number attributes uniquely distinguish a Portal object, +- and combined are the key used to register a Portal object in an iSNS +- server. A Portal is contained in one and only one Network Entity, +- and may be contained in one or more DDs (see Section 3.6). +- +-3.3. Storage Node Object +- +- The Storage Node object is the logical endpoint of an iSCSI or iFCP +- session. In iFCP, the session endpoint is represented by the World +- Wide Port Name (WWPN). In iSCSI, the session endpoint is represented +- by the iSCSI Name of the device. For iSCSI, the iSCSI Name attribute +- uniquely distinguishes a Storage Node, and is the key used to +- register a Storage Node object in an iSNS Server. For iFCP, the FC +- Port Name (WWPN) attribute uniquely distinguishes a Storage Node, and +- is the key used to register a Storage Node object in the iSNS Server. +- Storage Node is contained in only one Network Entity object and may +- be contained in one or more DDs (see Section 3.6). +- +- +- +-Tseng, et al. Standards Track [Page 22] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +-3.4. Portal Group Object +- +- The Portal Group (PG) object represents an association between a +- Portal and an iSCSI Node. Each Portal and iSCSI Storage Node +- registered in an Entity can be associated using a Portal Group (PG) +- object. The PG Tag (PGT), if non-NULL, indicates that the associated +- Portal provides access to the associated iSCSI Storage Node in the +- Entity. All Portals that have the same PGT value for a specific +- iSCSI Storage Node allow coordinated access to that node. +- +- A PG object MAY be registered when a Portal or iSCSI Storage Node is +- registered. Each Portal to iSCSI Node association is represented by +- one and only one PG object. In order for a Portal to provide access +- to an iSCSI Node, the PGT of the PG object MUST be non-NULL. If the +- PGT value registered for a specified Portal and iSCSI Node is NULL, +- or if no PGT value is registered, then the Portal does not provide +- access to that iSCSI Node in the Entity. +- +- The PGT value indicates whether access to an iSCSI Node can be +- coordinated across multiple Portals. All Portals that have the same +- PGT value for a specific iSCSI Node can provide coordinated access to +- that iSCSI Node. According to the iSCSI Specification, coordinated +- access to an iSCSI node indicates the capability of coordinating an +- iSCSI session with connections that span these Portals [iSCSI]. +- +- The PG object is uniquely distinguished by the iSCSI Name, Portal IP +- Address, and Portal TCP Port values of the associated Storage Node +- and Portal objects. These are represented in the iSNS Server by the +- PG iSCSI Name, PG Portal IP Address, and PG Portal TCP/UDP Port +- attributes, respectively. The PG object is also uniquely +- distinguished in the iSNS Server by the PG Index value. +- +- A new PG object can only be registered by referencing its associated +- iSCSI Storage Node or Portal object. A pre-existing PG object can be +- modified or queried by using its Portal Group Index as message key, +- or by referencing its associated iSCSI Storage Node or Portal object. +- A 0-length Tag, Length, Value TLV is used to register a PGT NULL +- value. +- +- The PG object is deregistered if and only if its associated iSCSI +- Node and Portal objects are both removed. +- +- +- +- +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 23] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +-3.5. Device Object +- +- The FC Device represents the Fibre Channel Node. This object +- contains information that may be useful in the management of the +- Fibre Channel device. The FC Node Name (WWNN) attribute uniquely +- distinguishes an FC Device, and is the key used to register an FC +- Device object in the iSNS Server. +- +- The FC Device is contained in one or more Storage Node objects. +- +-3.6. Discovery Domain Object +- +- Discovery Domains (DD) are a security and management mechanism used +- to administer access and connectivity to storage devices. For query +- and registration purposes, they are considered containers for Storage +- Node and Portal objects. A query by an iSNS client that is not from +- a Control Node only returns information about objects with which it +- shares at least one active DD. The only exception to this rule is +- with Portals; if Storage Nodes of a Network Entity are registered in +- the DD without Portals, then all Portals of that Network Entity are +- implicit members of that DD. The Discovery Domain ID (DD_ID) +- attribute uniquely distinguishes a Discovery Domain object, and is +- the key used to register a Discovery Domain object in the iSNS +- Server. +- +- A DD is considered active if it is a member of at least one active DD +- Set. DDs that are not members of at least one enabled DDS are +- considered disabled. A Storage Node can be a member of one or more +- DDs. An enabled DD establishes connectivity among the Storage Nodes +- in that DD. +- +-3.7. Discovery Domain Set Object +- +- The Discovery Domain Set (DDS) is a container object for Discovery +- Domains (DDs). DDSs may contain one or more DDs. Similarly, each DD +- can be a member of one or more DDSs. DDSs are a mechanism to store +- coordinated sets of DD mappings in the iSNS server. Active DDs are +- members of at least one active DD Set. Multiple DDSs may be +- considered active at the same time. The Discovery Domain Set ID +- (DDS_ID) attribute uniquely distinguishes a Discovery Domain Set +- object, and is the key used to register a Discovery Domain Set object +- in the iSNS Server. +- +-3.8. Database Model +- +- As presented to the iSNS client, each object of a specific type in +- the iSNS database MUST have an implicit internal linear ordering +- based on the key(s) for that object type. This ordering provides the +- +- +- +-Tseng, et al. Standards Track [Page 24] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- ability to respond to DevGetNext queries (see Section 5.6.5.3). The +- ordering of objects in the iSNS database SHOULD NOT be changed with +- respect to that implied ordering, as a consequence of object +- insertions and deletions. That is, the relative order of surviving +- object entries in the iSNS database SHOULD be preserved so that the +- DevGetNext message encounters generally reasonable behavior. +- +- The following diagram shows the various objects described above and +- their relationship to each other. +- +- +--------------+ +-----------+ +- | NETWORK |1 *| | +- | ENTITY |----| PORTAL | +- | | | | +- +--------------+ +-----------+ +- |1 |1 |* +- | | | +- | |* | +- | +----------+ | +- | | PORTAL | | +- | | GROUP | | +- | +----------+ | +- | |* | +- | | | +- |* |1 |* +- +-----------+ +--------------+ +-----------+ +-----------+ +- | FC |1 *| STORAGE |* *| DISCOVERY |* *| DISCOVERY | +- | DEVICE |----| NODE |----| DOMAIN |----| DOMAIN | +- | | | | | | | SET | +- +-----------+ +--------------+ +-----------+ +-----------+ +- +- * represents 0 to many possible relationships +- +-4. iSNS Implementation Requirements +- +- This section details specific requirements for support of each of +- these IP storage protocols. Implementation requirements for security +- are described in Section 7. +- +-4.1. iSCSI Requirements +- +- Use of iSNS in support of iSCSI is OPTIONAL. iSCSI devices MAY be +- manually configured with the iSCSI Name and IP address of peer +- devices, without the aid or intervention of iSNS. iSCSI devices may +- also use SLP [RFC2608] to discover peer iSCSI devices. However, iSNS +- is useful for scaling a storage network to a larger number of iSCSI +- devices. +- +- +- +- +-Tseng, et al. Standards Track [Page 25] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +-4.1.1. Required Attributes for Support of iSCSI +- +- The following attributes are available to support iSCSI. Attributes +- indicated in the REQUIRED for Server column MUST be implemented by an +- iSNS server used to support iSCSI. Attributes indicated in the +- REQUIRED for Client column MUST be implemented by an iSCSI device +- that elects to use the iSNS. Attributes indicated in the K (Key) +- column uniquely identify the object type in the iSNS Server. A more +- detailed description of each attribute is found in Section 6. +- +- REQUIRED for: +- Object Attribute K Server Client +- ------ --------- - ------ ------ +- NETWORK ENTITY Entity Identifier * * * +- Entity Protocol * * +- Management IP Address * +- Timestamp * +- Protocol Version Range * +- Registration Period * +- Entity Index * +- Entity IKE Phase-1 Proposal +- Entity Certificate +- +- PORTAL IP Address * * * +- TCP/UDP Port * * * +- Portal Symbolic Name * +- ESI Interval * +- ESI Port * +- Portal Index * +- SCN Port * +- Portal Security Bitmap * +- Portal IKE Phase-1 Proposal +- Portal IKE Phase-2 Proposal +- Portal Certificate +- +- PORTAL GROUP PG iSCSI Name * * * +- PG IP Address * * * +- PG TCP/UDP Port * * * +- PG Tag * * +- PG Index * +- +- +- +- +- +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 26] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- STORAGE NODE iSCSI Name * * * +- iSCSI Node Type * * +- Alias * +- iSCSI SCN Bitmap * +- iSCSI Node Index * +- WWNN Token +- iSCSI AuthMethod +- iSCSI Node Certificate +- +- DISCOVERY DOMAIN DD ID * * * +- DD Symbolic Name * +- DD Member iSCSI Node Index * +- DD Member iSCSI Name * +- DD Member Portal Index * +- DD Member Portal IP Addr * +- DD Member Portal TCP/UDP * +- DD Features * +- +- DISCOVERY DOMAIN DDS Identifier * * +- SET DDS Symbolic Name * +- DDS Status * +- +- All iSCSI user-specified and vendor-specified attributes are OPTIONAL +- to implement and use. +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 27] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +-4.1.2. Examples: iSCSI Object Model Diagrams +- +- The following diagram models how a simple iSCSI-based initiator and +- target is represented using database objects stored in the iSNS +- server. In this implementation, each target and initiator is +- attached to a single Portal. +- +- +----------------------------------------------------------------+ +- | IP Network | +- +------------+--------------------------------------+------------+ +- | | +- | | +- +-----+------+------+-----+ +-----+------+------+-----+ +- | | PORTAL | | | | PORTAL | | +- | | -IP Addr 1 | | | | -IP Addr 2 | | +- | | -TCP Port 1 | | | | -TCP Port 2 | | +- | +-----+ +-----+ | | +-----+ +-----+ | +- | | | | | | | | +- | +-----+ +-----+ | | +-----+ +-----+ | +- | | PORTAL GROUP| | | | PORTAL GROUP| | +- | | -Prtl Tag 1 | | | | -Prtl Tag 2 | | +- | +-----+ +-----+ | | +-----+ +-----+ | +- | | | | | | | | +- | +--------+ +--------+ | | +-------+ +--------+ | +- | | | | | | | | +- | | STORAGE NODE | | | | STORAGE NODE | | +- | | -iSCSI Name | | | | -iSCSI Name | | +- | | -Alias: "server1"| | | | -Alias: "disk1"| | +- | | -Type: initiator | | | | -Type: target | | +- | | | | | | | | +- | +-------------------+ | | +------------------+ | +- | | | | +- | NETWORK ENTITY | | NETWORK ENTITY | +- | -Entity ID (FQDN): | | -Entity ID (FQDN): | +- | "strg1.example.com" | | "strg2.example.net" | +- | -Protocol: iSCSI | | -Protocol: iSCSI | +- | | | | +- +-------------------------+ +-------------------------+ +- +- The object model can be expanded to describe more complex devices, +- such as an iSCSI device with more than one storage controller, in +- which each controller is accessible through any of multiple Portal +- interfaces, possibly using multiple Portal Groups. The storage +- controllers on this device can be accessed through alternate Portal +- interfaces if any original interface should fail. The following +- diagram describes such a device: +- +- +- +- +- +-Tseng, et al. Standards Track [Page 28] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- +---------------------------------------------------------------+ +- | IP Network | +- +-------------------+-----------------------+-------------------+ +- | | +- | | +- +------------+------+------+---------+------+------+------------+ +- | | PORTAL 1 | | PORTAL 2 | | +- | | -IP Addr 1 | | -IP Addr 2 | | +- | | -TCP Port 1 | | -TCP Port 2 | | +- | +-----+ +-----+ +-----+ +-----+ | +- | | | | | | +- | +---------------+ +---------------------+ +---------------+ | +- | +-------+ +----------------+ +-------------------+ +------+ | +- | | | | | | | | +- | +-------+ +-------+ +------+ +--------+ +--------+ +------+ | +- | | | | | | | | +- | | STORAGE NODE 1 | | STORAGE NODE 2 | | STORAGE NODE 3 | | +- | | -iSCSI Name 1 | | -iSCSI Name 2 | | -iSCSI Name 3 | | +- | | -Alias: "disk1"| | -Alias: "disk2"| | -Alias: "disk3"| | +- | | -Type: target | | -Type: target | | -Type: target | | +- | | | | | | | | +- | +-----------------+ +-----------------+ +-----------------+ | +- | | +- | NETWORK ENTITY | +- | -Entity ID (FQDN): "dev1.example.com" | +- | -Protocol: iSCSI | +- | | +- | Portal Group Object Table | +- | Storage-Node Portal Portal-Group-Tag | +- | 1 1 10 | +- | 1 2 NULL (no access permitted) | +- | 2 1 20 | +- | 2 2 20 | +- | 3 1 30 | +- | 3 2 10 | +- | | +- +---------------------------------------------------------------+ +- +- Storage Node 1 is accessible via Portal 1 with a PGT of 10. It does +- not have a Portal Group Tag (PGT) assigned for Portal 2, so Storage +- Node 1 cannot be accessed via Portal 2. +- +- Storage Node 2 can be accessed via both Portal 1 and Portal 2. Since +- Storage Node 2 has the same PGT value assigned to both Portal 1 and +- Portal 2, in this case 20, coordinated access via the Portals is +- available [iSCSI]. +- +- +- +- +- +-Tseng, et al. Standards Track [Page 29] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- Storage Node 3 can be accessed via Portal 1 or Portal 2. However, +- since Storage Node 3 has different PGT values assigned to each +- Portal, in this case 10 and 30, access is not coordinated [iSCSI]. +- Because PGTs are assigned within the context of a Storage Node, the +- PGT value of 10 used for Storage Node 1 and Storage Node 3 are not +- interrelated. +- +-4.1.3. Required Commands and Response Messages for Support of iSCSI +- +- The following iSNSP messages and responses are available in support +- of iSCSI. Messages indicated in the REQUIRED for Server column MUST +- be implemented in iSNS servers used for iSCSI devices. Messages +- indicated in the REQUIRED for Client column MUST be implemented in +- iSCSI devices that elect to use the iSNS server. +- +- REQUIRED for: +- Message Description Abbreviation Func_ID Server Client +- ------------------- ------------ ------- ------ ------ +- RESERVED 0x0000 +- Device Attr Reg Request DevAttrReg 0x0001 * * +- Dev Attr Query Request DevAttrQry 0x0002 * * +- Dev Get Next Request DevGetNext 0x0003 * +- Deregister Dev Request DevDereg 0x0004 * * +- SCN Register Request SCNReg 0x0005 * +- SCN Deregister Request SCNDereg 0x0006 * +- SCN Event SCNEvent 0x0007 * +- State Change Notification SCN 0x0008 * +- DD Register DDReg 0x0009 * * +- DD Deregister DDDereg 0x000A * * +- DDS Register DDSReg 0x000B * * +- DDS Deregister DDSDereg 0x000C * * +- Entity Status Inquiry ESI 0x000D * +- Name Service Heartbeat Heartbeat 0x000E +- RESERVED 0x000F-0x00FF +- Vendor Specific 0x0100-0x01FF +- RESERVED 0x0200-0x7FFF +- +- The following are iSNSP response messages used in support of iSCSI: +- +- REQUIRED for: +- Response Message Desc Abbreviation Func_ID Server Client +- --------------------- ------------ ------- ------ ------ +- RESERVED 0x8000 +- Device Attr Register Rsp DevAttrRegRsp 0x8001 * * +- Device Attr Query Rsp DevAttrQryRsp 0x8002 * * +- Device Get Next Rsp DevGetNextRsp 0x8003 * +- Device Dereg Rsp DevDeregRsp 0x8004 * * +- SCN Register Rsp SCNRegRsp 0x8005 * +- +- +- +-Tseng, et al. Standards Track [Page 30] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- SCN Deregister Rsp SCNDeregRsp 0x8006 * +- SCN Event Rsp SCNEventRsp 0x8007 * +- SCN Response SCNRsp 0x8008 * +- DD Register Rsp DDRegRsp 0x8009 * * +- DD Deregister Rsp DDDeregRsp 0x800A * * +- DDS Register Rsp DDSRegRsp 0x800B * * +- DDS Deregister Rsp DDSDeregRsp 0x800C * * +- Entity Stat Inquiry Rsp ESIRsp 0x800D * +- RESERVED 0x800E-0x80FF +- Vendor Specific 0x8100-0x81FF +- RESERVED 0x8200-0xFFFF +- +-4.2. iFCP Requirements +- +- In iFCP, use of iSNS is REQUIRED. No alternatives exist for support +- of iFCP Naming & Discovery functions. +- +-4.2.1. Required Attributes for Support of iFCP +- +- The following table displays attributes that are used by iSNS to +- support iFCP. Attributes indicated in the REQUIRED for Server column +- MUST be implemented by the iSNS server that supports iFCP. +- Attributes indicated in the REQUIRED for Client column MUST be +- supported by iFCP gateways. Attributes indicated in the K (Key) +- column uniquely identify the object type in the iSNS Server. A more +- detailed description of each attribute is found in Section 6. +- +- REQUIRED for: +- Object Attribute K Server Client +- ------ --------- - ------ ------ +- NETWORK ENTITY Entity Identifier * * * +- Entity Protocol * * +- Management IP Address * +- Timestamp * +- Protocol Version Range * +- Registration period +- Entity Index +- Entity IKE Phase-1 Proposal +- Entity Certificate +- +- PORTAL IP Address * * * +- TCP/UDP Port * * * +- Symbolic Name * +- ESI Interval * +- ESI Port * +- SCN Port * +- Portal IKE Phase-1 Proposal +- Portal IKE Phase-2 Proposal +- +- +- +-Tseng, et al. Standards Track [Page 31] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- Portal Certificate +- Security Bitmap * +- +- STORAGE NODE FC Port Name (WWPN) * * * +- (FC Port) Port_ID * * +- FC Port Type * * +- Port Symbolic Name * +- Fabric Port Name (FWWN) * +- Hard Address * +- Port IP Address * +- Class of Service * +- FC FC-4 Types * +- FC FC-4 Descriptors * +- FC FC-4 Features * +- SCN Bitmap * +- iFCP Port Role * +- Permanent Port Name * +- +- FC DEVICE FC Node Name (WWNN) * * * +- (FC Node) Node Symbolic Name * +- Node IP Address * +- Node IPA * +- Proxy iSCSI Name +- +- DISCOVERY DOMAIN DD ID * * * +- DD Symbolic Name * +- DD Member FC Port Name * +- DD Member Portal Index * +- DD Member Portal IP Addr * +- DD Member Portal TCP/UDP * +- +- DISCOVERY DOMAIN DDS ID * * +- SET DDS Symbolic Name * +- DDS Status * +- +- OTHER Switch Name +- Preferred_ID +- Assigned_ID +- Virtual_Fabric_ID +- +- All iFCP user-specified and vendor-specified attributes are OPTIONAL +- to implement and use. +- +-4.2.2. Example: iFCP Object Model Diagram +- +- The iFCP protocol allows native Fibre Channel devices or Fibre +- Channel fabrics connected to an iFCP gateway to be directly +- internetworked using IP. +- +- +- +-Tseng, et al. Standards Track [Page 32] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- When supporting iFCP, the iSNS server stores Fibre Channel device +- attributes, iFCP gateway attributes, and Fibre Channel fabric switch +- attributes that might also be stored in an FC name server. +- +- The following diagram shows a representation of a gateway supporting +- multiple Fibre Channel devices behind it. The two Portal objects +- represent IP interfaces on the iFCP gateway that can be used to +- access any of the three Storage Node objects behind it. Note that +- the FC Device object is not contained in the Network Entity object. +- However, each FC Device has a relationship to one or more Storage +- Node objects. +- +- +--------------------------------------------------------+ +- | IP Network | +- +--------+-----------------+-----------------------------+ +- | | +- +-+------+------+---+------+------+----------------------+ +- | | PORTAL | | PORTAL | NETWORK ENTITY | +- | | -IP Addr 1 | | -IP Addr 2 | -Entity ID (FQDN): | +- | | -TCP Port 1 | | -TCP Port 2 | "gtwy1.example.com" | +- | +-----+ +-----+ +-----+ +-----+ -Protocol: iFCP | +- | | | | | | +- | +-----+ +---------------+ +----------------------+ | +- | +-----+ +---------------+ +-------------+ +------+ | +- | | | | | | | | +- | +-----+ +-----+ +----+ +------+ +----+ +------+ | +- | |STORAGE NODE | |STORAGE NODE | |STORAGE NODE | | +- | | -WWPN 1 | | -WWPN 2 | | -WWPN 3 | | +- | | -Port ID 1 | | -Port ID 2 | | -Port ID 3 | | +- | | -FWWN 1 | | -FWWN 2 | | -FWWN 3 | | +- | | -FC COS | | -FC COS | | -FC COS | | +- | +------+------+ +-------+-----+ +----+--------+ | +- +--------|-------------------|------------|--------------+ +- | | | +- +------+------+ +---+------------+---+ +- | FC DEVICE | | FC DEVICE | +- | -WWNN 1 | | -WWNN 2 | +- | | | | +- +-------------+ +--------------------+ +- +- +- +- +- +- +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 33] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +-4.2.3. Required Commands and Response Messages for Support of iFCP +- +- The iSNSP messages and responses displayed in the following tables +- are available to support iFCP gateways. Messages indicated in the +- REQUIRED TO IMPLEMENT column MUST be supported by the iSNS server +- used by iFCP gateways. Messages indicated in the REQUIRED TO USE +- column MUST be supported by the iFCP gateways themselves. +- +- REQUIRED for: +- Message Description Abbreviation Func ID Server Client +- ------------------- ------------ ------- ------ ------ +- RESERVED 0x0000 +- Device Attr Reg Request DevAttrReg 0x0001 * * +- Device Attr Query Request DevAttrQry 0x0002 * * +- Device Get Next Request DevGetNext 0x0003 * +- Device Dereg Request DevDereg 0x0004 * * +- SCN Register Request SCNReg 0x0005 * +- SCN Deregister Request SCNDereg 0x0006 * +- SCN Event SCNEvent 0x0007 * +- State Change Notification SCN 0x0008 * +- DD Register DDReg 0x0009 * * +- DD Deregister DDDereg 0x000A * * +- DDS Register DDSReg 0x000B * * +- DDS Deregister DDSDereg 0x000C * * +- Entity Status Inquiry ESI 0x000D * +- Name Service Heartbeat Heartbeat 0x000E * +- Reserved Reserved 0x000F-0x0010 +- Request FC_DOMAIN_ID RqstDomId 0x0011 +- Release FC_DOMAIN_ID RlseDomId 0x0012 +- Get FC_DOMAIN_IDs GetDomId 0x0013 +- RESERVED 0x0014-0x00FF +- Vendor Specific 0x0100-0x01FF +- RESERVED 0x0200-0x7FFF +- +- The following are iSNSP response messages in support of iFCP: +- +- REQUIRED for: +- Response Message Desc Abbreviation Func_ID Server Client +- --------------------- ------------ ------- ------ ------ +- RESERVED 0x8000 +- Device Attr Reg Rsp DevAttrRegRsp 0x8001 * * +- Device Attr Query Rsp DevAttrQryRsp 0x8002 * * +- Device Get Next Rsp DevGetNextRsp 0x8003 * +- Device Deregister Rsp DevDeregRsp 0x8004 * * +- SCN Register Rsp SCNRegRsp 0x8005 * +- SCN Deregister Rsp SCNDeregRsp 0x8006 * +- SCN Event Rsp SCNEventRsp 0x8007 * +- SCN Rsp SCNRsp 0x8008 * +- +- +- +-Tseng, et al. Standards Track [Page 34] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- DD Register Rsp DDRegRsp 0x8009 * * +- DD Deregister Rsp DDDeregRsp 0x800A * * +- DDS Register Rsp DDSRegRsp 0x800B * * +- DDS Deregister Rsp DDSDeregRsp 0x800C * * +- Entity Status Inquiry Rsp ESIRsp 0x800D * +- NOT USED 0x800E +- RESERVED 0x800F-0x8010 +- Request FC_DOMAIN_ID Rsp RqstDomIdRsp 0x8011 +- Release FC_DOMAIN_ID Rsp RlseDomIdRsp 0x8012 +- Get FC_DOMAIN_IDs GetDomIdRsp 0x0013 +- RESERVED 0x8014-0x80FF +- Vendor Specific 0x8100-0x81FF +- RESERVED 0x8200-0xFFFF +- +-5. iSNSP Message Format +- +- The iSNSP message format is similar to the format of other common +- protocols such as DHCP, DNS and BOOTP. An iSNSP message may be sent +- in one or more iSNS Protocol Data Units (PDU). Each PDU is 4-byte +- aligned. The following describes the format of the iSNSP PDU: +- +- Byte MSb LSb +- Offset 0 15 16 31 +- +---------------------+----------------------+ +- 0 | iSNSP VERSION | FUNCTION ID | 4 Bytes +- +---------------------+----------------------+ +- 4 | PDU LENGTH | FLAGS | 4 Bytes +- +---------------------+----------------------+ +- 8 | TRANSACTION ID | SEQUENCE ID | 4 Bytes +- +---------------------+----------------------+ +- 12 | | +- | PDU PAYLOAD | N Bytes +- | ... | +- +--------------------------------------------+ +- 12+N | AUTHENTICATION BLOCK (Multicast/Broadcast) | L Bytes +- +--------------------------------------------+ +- Total Length = 12 + N + L +- +-5.1. iSNSP PDU Header +- +- The iSNSP PDU header contains the iSNSP VERSION, FUNCTION ID, PDU +- LENGTH, FLAGS, TRANSACTION ID, and SEQUENCE ID fields as defined +- below. +- +- +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 35] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +-5.1.1. iSNSP Version +- +- The iSNSP version described in this document is 0x0001. All other +- values are RESERVED. The iSNS server MAY reject messages for iSNSP +- version numbers that it does not support. +- +-5.1.2. iSNSP Function ID +- +- The FUNCTION ID defines the type of iSNS message and the operation to +- be executed. FUNCTION_ID values with the leading bit cleared +- indicate query, registration, and notification messages, whereas +- FUNCTION_ID values with the leading bit set indicate response +- messages. +- +- See Section 4 under the appropriate protocol (i.e., iSCSI or iFCP) +- for a mapping of the FUNCTION_ID value to the iSNSP Command or +- Response message. All PDUs comprising an iSNSP message must have the +- same FUNCTION_ID value. +- +-5.1.3. iSNSP PDU Length +- +- The iSNS PDU Length specifies the length of the PDU PAYLOAD field in +- bytes. The PDU Payload contains TLV attributes for the operation. +- +- Additionally, response messages contain a success/failure code. The +- PDU Length MUST be 4-byte aligned. +- +-5.1.4. iSNSP Flags +- +- The FLAGS field indicates additional information about the message +- and the type of Network Entity that generated the message. The +- following table displays the valid flags: +- +- Bit Position Enabled (1) means: +- ------------ ----------------- +- 16 Sender is the iSNS client +- 17 Sender is the iSNS server +- 18 Authentication block is present +- 19 Replace flag (for DevAttrReg) +- 20 Last PDU of the iSNS message +- 21 First PDU of the iSNS message +- 22-31 RESERVED +- +-5.1.5. iSNSP Transaction ID +- +- The TRANSACTION ID MUST be set to a unique value for each +- concurrently outstanding request message. Replies MUST use the same +- TRANSACTION ID value as the associated iSNS request message. If a +- +- +- +-Tseng, et al. Standards Track [Page 36] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- message is retransmitted, the original TRANSACTION ID value MUST be +- used. All PDUs comprising an iSNSP message must have the same +- TRANSACTION ID value. +- +-5.1.6. iSNSP Sequence ID +- +- The SEQUENCE ID has a unique value for each PDU within a single +- transaction. The SEQUENCE_ID value of the first PDU transmitted in a +- given iSNS message MUST be zero (0), and each SEQUENCE_ID value in +- each PDU MUST be numbered sequentially in the order in which the PDUs +- are transmitted. Note that the two-byte SEQUENCE ID allows for up to +- 65536 PDUs per iSNS message. +- +-5.2. iSNSP Message Segmentation and Reassembly +- +- iSNS messages may be carried in one or more iSNS PDUs. If only one +- iSNS PDU is used to carry the iSNS message, then bit 21 (First PDU) +- and bit 20 in the FLAGS field (Last PDU) SHALL both be set. If +- multiple PDUs are used to carry the iSNS message, then bit 21 SHALL +- be set in the first PDU of the message, and bit 20 SHALL be set in +- the last PDU. +- +- All PDUs comprising the same iSNSP message SHALL have the same +- FUNCTION_ID and TRANSACTION_ID values. Each PDU comprising an iSNSP +- message SHALL have a unique SEQUENCE_ID value. +- +-5.3. iSNSP PDU Payload +- +- The iSNSP PDU PAYLOAD is of variable length and contains attributes +- used for registration and query operations. The attribute data items +- use a format similar to that of other protocols, such as DHCP +- [RFC2131] options. Each iSNS attribute is specified in the PDU +- Payload using Tag-Length-Value (TLV) data format, as shown below: +- +- Byte MSb LSb +- Offset 0 31 +- +--------------------------------------------+ +- 0 | Attribute Tag | 4 Bytes +- +--------------------------------------------+ +- 4 | Attribute Length (N) | 4 Bytes +- +--------------------------------------------+ +- 8 | | +- | Attribute Value | N Bytes +- | | +- +--------------------------------------------+ +- Total Length = 8 + N +- +- +- +- +- +-Tseng, et al. Standards Track [Page 37] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- Attribute Tag: a 4-byte field that identifies the attribute as +- defined in Section 6.1. This field contains the +- tag value from the indicated table. +- +- Attribute Length: a 4-byte field that indicates the length, in bytes, +- of the value field to follow in the TLV. For +- variable-length attributes, the value field MUST +- contain padding bytes, if necessary, in order to +- achieve 4-byte alignment. A "zero-length TLV" +- contains only the attribute tag and length fields. +- +- Attribute Value: a variable-length field containing the attribute +- value and padding bytes (if necessary). +- +- The above format is used to identify each attribute in the PDU +- Payload. Note that TLV boundaries need not be aligned with PDU +- boundaries; PDUs may carry one or more TLVs, or any fraction thereof. +- The Response Status Code, contained in response message PDU Payloads +- and described below, is not in TLV format. PDU Payloads for messages +- that do not contain iSNS attributes, such as the Name Service +- Heartbeat, do not use the TLV format. +- +-5.3.1. Attribute Value 4-Byte Alignment +- +- All attribute values are aligned to 4-byte boundaries. For variable +- length attributes, if necessary, the TLV length MUST be increased to +- the next 4-byte boundary through padding with bytes containing zero +- (0). If an attribute value is padded, a combination of the tag and +- attribute value itself is used to determine the actual value length +- and number of pad bytes. There is no explicit count of the number of +- pad bytes provided in the TLV. +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 38] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +-5.4. iSNSP Response Status Codes +- +- All iSNSP response messages contain a 4-byte Status Code field as the +- first field in the iSNSP PDU PAYLOAD. If the original iSNSP request +- message was processed normally by the iSNS server, or by the iSNS +- client for ESI and SCN messages, then this field SHALL contain a +- status code of 0 (Successful). A non-zero status code indicates +- rejection of the entire iSNS client request message. +- +- Status Code Status Description +- ----------- ----------------- +- 0 Successful +- 1 Unknown Error +- 2 Message Format Error +- 3 Invalid Registration +- 4 RESERVED +- 5 Invalid Query +- 6 Source Unknown +- 7 Source Absent +- 8 Source Unauthorized +- 9 No Such Entry +- 10 Version Not Supported +- 11 Internal Error +- 12 Busy +- 13 Option Not Understood +- 14 Invalid Update +- 15 Message (FUNCTION_ID) Not Supported +- 16 SCN Event Rejected +- 17 SCN Registration Rejected +- 18 Attribute Not Implemented +- 19 FC_DOMAIN_ID Not Available +- 20 FC_DOMAIN_ID Not Allocated +- 21 ESI Not Available +- 22 Invalid Deregistration +- 23 Registration Feature Not Supported +- 24 and above RESERVED +- +-5.5. Authentication for iSNS Multicast and Broadcast Messages +- +- For iSNS multicast and broadcast messages (see Section 2.9.3), the +- iSNSP provides authentication capability. The following section +- details the iSNS Authentication Block, which is identical in format +- to the SLP authentication block [RFC2608]. iSNS unicast messages +- SHOULD NOT include the authentication block, but rather should rely +- upon IPSec security mechanisms. +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 39] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- If a message contains an authentication block, then the +- "Authentication block present" bit in the iSNSP PDU header FLAGS +- field SHALL be enabled. +- +- If a PKI is available with an [X.509] Certificate Authority (CA), +- then public key authentication of the iSNS server is possible. The +- authentication block leverages the DSA with SHA-1 algorithm, which +- can easily integrate into a public key infrastructure. +- +- The authentication block contains a digital signature for the +- multicast message. The digital signature is calculated on a per-PDU +- basis. The authentication block contains the following information: +- +- 1. A time stamp, to prevent replay attacks. +- 2. A structured authenticator containing a signature calculated over +- the time stamp and the message being secured. +- 3. An indicator of the cryptographic algorithm that was used to +- calculate the signature. +- 4. An indicator of the keying material and algorithm parameters, +- used to calculate the signature. +- +- The authentication block is described in the following figure: +- +- Byte MSb LSb +- Offset 0 31 +- +----------------------------------+ +- 0 | BLOCK STRUCTURE DESCRIPTOR | 4 Bytes +- +----------------------------------+ +- 4 | AUTHENTICATION BLOCK LENGTH | 4 Bytes +- +----------------------------------+ +- 8 | TIMESTAMP | 8 Bytes +- +----------------------------------+ +- 16 | SPI STRING LENGTH | 4 Bytes +- +----------------------------------+ +- 20 | SPI STRING | N Bytes +- +----------------------------------+ +- 20 + N | STRUCTURED AUTHENTICATOR | M Bytes +- +----------------------------------+ +- Total Length = 20 + N + M +- +- BLOCK STRUCTURE DESCRIPTOR (BSD): Defines the structure and algorithm +- to use for the STRUCTURED AUTHENTICATOR. BSD values from +- 0x00000000 to 0x00007FFF are assigned by IANA, while +- values 0x00008000 to 0x00008FFF are for private use. +- +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 40] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- AUTHENTICATION BLOCK LENGTH: Defines the length of the authentication +- block, beginning with the BSD field and running through +- the last byte of the STRUCTURED AUTHENTICATOR. +- +- TIMESTAMP: This is an 8-byte unsigned, fixed-point integer giving the +- number of seconds since 00:00:00 GMT on January 1, 1970. +- +- SPI STRING LENGTH: The length of the SPI STRING field. +- +- SPI STRING (Security Parameters Index): Index to the key and +- algorithm used by the message recipient to decode the +- STRUCTURED AUTHENTICATOR field. +- +- STRUCTURED AUTHENTICATOR: Contains the digital signature. For the +- default BSD value of 0x0002, this field SHALL contain the +- binary ASN.1 encoding of output values from the DSA with +- SHA-1 signature calculation as specified in Section 2.2.2 +- of [RFC3279]. +- +-5.6. Registration and Query Messages +- +- The iSNSP registration and query message PDU Payloads contain a list +- of attributes, and have the following format: +- +- +----------------------------------------+ +- | Source Attribute (Requests Only) | +- +----------------------------------------+ +- | Message Key Attribute[1] (if present) | +- +----------------------------------------+ +- | Message Key Attribute[2] (if present) | +- +----------------------------------------+ +- | . . . | +- +----------------------------------------+ +- | - Delimiter Attribute - | +- +----------------------------------------+ +- | Operating Attribute[1] (if present) | +- +----------------------------------------+ +- | Operating Attribute[2] (if present) | +- +----------------------------------------+ +- | Operating Attribute[3] (if present) | +- +----------------------------------------+ +- | . . . | +- +----------------------------------------+ +- +- Each Source, Message Key, Delimiter, and Operating attribute is +- specified in the PDU Payload using the Tag-Length-Value (TLV) data +- format. iSNS Registration and Query messages are sent by iSNS Clients +- +- +- +- +-Tseng, et al. Standards Track [Page 41] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- to the iSNS server IP Address and well-known TCP/UDP Port. The iSNS +- Responses will be sent to the iSNS Client IP address and TCP/UDP port +- number from the original request message. +- +-5.6.1. Source Attribute +- +- The Source Attribute is used to identify the Storage Node to the iSNS +- server for queries and other messages that require source +- identification. The Source Attribute uniquely identifies the source +- of the message. Valid Source Attribute types are shown below. +- +- Valid Source Attributes +- ----------------------- +- iSCSI Name +- FC Port Name WWPN +- +- For a query operation, the Source Attribute is used to limit the +- scope of the specified operation to the Discovery Domains of which +- the source is a member. Special Control Nodes, identified by the +- Source Attribute, may be administratively configured to perform the +- specified operation on all objects in the iSNS database without +- scoping to Discovery Domains. +- +- For messages that change the contents of the iSNS database, the iSNS +- server MUST verify that the Source Attribute identifies either a +- Control Node or a Storage Node that is a part of the Network Entity +- containing the added, deleted, or modified objects. +- +-5.6.2. Message Key Attributes +- +- Message Key attributes are used to identify matching objects in the +- iSNS database for iSNS query and registration messages. If present, +- the Message Key MUST be a Registration or Query Key for an object as +- described in Sections 5.6.5 and 6.1. A Message Key is not required +- when a query spans the entire set of objects available to the Source +- or a registration is for a new Entity. +- +- iSCSI Names used in the Message Key MUST be normalized according to +- the stringprep template [STRINGPREP]. Entity Identifiers (EIDs) used +- in the Message Key MUST be normalized according to the nameprep +- template [NAMEPREP]. +- +-5.6.3. Delimiter Attribute +- +- The Delimiter Attribute separates the Message Key attributes from the +- Operating Attributes in a PDU Payload. The Delimiter Attribute has a +- tag value of 0 and a length value of 0. The Delimiter Attribute is +- always 8 bytes long (a 4-byte tag field and a 4-byte length field, +- +- +- +-Tseng, et al. Standards Track [Page 42] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- all containing zeros). If a Message Key is not required for a +- message, then the Delimiter Attribute immediately follows the Source +- Attribute. +- +-5.6.4. Operating Attributes +- +- The Operating Attributes are a list of one or more key and non-key +- attributes related to the actual iSNS registration or query operation +- being performed. +- +- Operating Attributes include object key attributes and non-key +- attributes. Object key attributes uniquely identify iSNS objects. +- Key attributes MUST precede the non-key attributes of each object in +- the Operating Attributes. The tag value distinguishes the attribute +- as an object key attribute (i.e., tag=1, 16&17, 32, 64, and 96) or a +- non-key attribute. iSCSI Names used in the Operating Attributes MUST +- be normalized according to the stringprep template [STRINGPREP]. +- Entity Identifiers (EIDs) used in the Operating Attributes MUST be +- normalized according to the nameprep template [NAMEPREP]. +- +- The ordering of Operating Attributes in the message is important for +- determining the relationships among objects and their ownership of +- non-key attributes. iSNS protocol messages that violate these +- ordering rules SHALL be rejected with the Status Code of 2 (Message +- Format Error). See the message descriptions for proper operating +- attribute ordering requirements. +- +- Some objects are keyed by more than one object key attribute value. +- For example, the Portal object is keyed by attribute tags 16 and 17. +- When describing an object keyed by more than one key attribute, every +- object key attribute of that object MUST be listed sequentially by +- tag value in the message before non-key attributes of that object and +- key attributes of the next object. A group of key attributes of this +- kind is treated as a single logical key attribute when identifying an +- object. +- +- Non-key attributes that immediately follow key attributes MUST be +- attributes of the object referenced by the key attributes. All non- +- key attributes of an object MUST be listed before the object key +- attributes introducing the next object. +- +- Objects MUST be listed in inheritance order, according to their +- containment order. Storage Node and Portal objects and their +- respective attributes MUST follow the Network Entity object to which +- they have a relationship. Similarly, FC Device objects MUST follow +- the Storage Node object to which they have a relationship. +- +- +- +- +- +-Tseng, et al. Standards Track [Page 43] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- Vendor-specific objects defined by tag values in the range 1537-2048 +- have the same requirements described above. +- +-5.6.4.1. Operating Attributes for Query and Get Next Requests +- +- In Query and Get Next request messages, TLV attributes with length +- value of 0 are used to indicate which Operating Attributes are to be +- returned in the corresponding response. Operating Attribute values +- that match the TLV attributes in the original message are returned in +- the response message. +- +-5.6.5. Registration and Query Request Message Types +- +- The following describes each query and message type. +- +-5.6.5.1. Device Attribute Registration Request (DevAttrReg) +- +- The DevAttrReg message type is 0x0001. The DevAttrReg message +- provides the means for iSNS clients to update existing objects or +- register new objects. The value of the replace bit in the FLAGs +- field determines whether the DevAttrReg message updates or replaces +- an existing registration. +- +- The Source Attribute identifies the Node initiating the registration +- request. +- +- The Message Key identifies the object the DevAttrReg message acts +- upon. It MUST contain the key attribute(s) identifying an object. +- This object MUST contain all attributes and related subordinate +- object attributes that will be included in the Operating Attributes +- of the DevAttrReg PDU Payload. The key attribute(s) identifying this +- object MUST also be included among the Operating Attributes. +- +- If the Message Key contains an EID and no pre-existing objects match +- the Message Key, then the DevAttrReg message SHALL create a new +- Entity with the specified EID and any new object(s) specified by the +- Operating Attributes. The replace bit SHALL be ignored. +- +- If the Message Key does not contain an EID, and no pre-existing +- objects match the Message Key, then the DevAttrReg message SHALL be +- rejected with a status code of 3 (Invalid Registration). +- +- If the Message Key is not present, then the DevAttrReg message +- implicitly registers a new Network Entity. In this case, the replace +- bit SHALL be ignored; a new Network Entity SHALL be created. +- Existing entities, their objects, and their relationships remain +- unchanged. +- +- +- +- +-Tseng, et al. Standards Track [Page 44] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- The replace bit determines the kind of operation conducted on the +- object identified in the DevAttrReg Message Key. The replace bit +- only applies to the DevAttrReg message; it is ignored for all other +- message types. +- +- If the replace bit is set, then the objects, attributes, and +- relationships specified in the Operating Attributes SHALL replace the +- object identified by the Message Key. The object and all of its +- subordinate objects SHALL be deregistered, and the appropriate SCNs +- SHALL be sent by the iSNS server for the deregistered objects. The +- objects listed in the Operating Attributes are then used to replace +- the just-deregistered objects. Note that additional SCNs SHALL be +- sent for the newly-registered objects, if appropriate. Existing +- objects and relationships that are not identified or that are +- subordinate to the object identified by the Message Key MUST NOT be +- affected or changed. +- +- If the replace bit is not set, then the message updates the +- attributes of the object identified by the Message Key and its +- subordinate objects. Existing object containment relationships MUST +- NOT be changed. For existing objects, key attributes MUST NOT be +- modified, but new subordinate objects MAY be added. +- +- The Operating Attributes represent objects, attributes, and +- relationships that are to be registered. Multiple related objects +- and attributes MAY be registered in a single DevAttrReg message. The +- ordering of the objects in this message indicates the structure of, +- and associations among, the objects to be registered. At least one +- object MUST be listed in the Operating Attributes. Additional +- objects (if any) MUST be subordinate to the first object listed. Key +- attributes MUST precede non-key attributes of each object. A given +- object may only appear a maximum of once in the Operating Attributes +- of a message. If the Node identified by the Source Attribute is not +- a Control Node, then the objects in the operating attributes MUST be +- members of the same Network Entity as the Source Node. +- +- For example, to establish relationships between a Network Entity +- object and its Portal and Storage Node objects, the Operating +- Attributes list the key and non-key attributes of the Network Entity +- object, followed by the key and non-key attributes of each Portal and +- Storage Node object to be linked to that Network Entity. Similarly, +- an FC Device object that follows a Storage Node object is considered +- subordinate to that Storage Node. +- +- New PG objects are registered when an associated Portal or iSCSI Node +- object is registered. An explicit PG object registration MAY follow +- a Portal or iSCSI Node object registration in a DevAttrReg message. +- +- +- +- +-Tseng, et al. Standards Track [Page 45] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- When a Portal is registered, the Portal attributes MAY immediately be +- followed by a PGT attribute. The PGT attribute SHALL be followed by +- the set of PG iSCSI Names representing nodes that will be associated +- to the Portal using the indicated PGT value. Additional sets of PGTs +- and PG iSCSI Names to be associated to the registered Portal MAY +- follow. Indicated PGT values are assigned to the PG object +- associated with the newly registered Portal and to the iSCSI Storage +- Node(s) referenced immediately following the PGT attribute in the +- operating attributes. +- +- When an iSCSI Storage Node is registered, the Storage Node attributes +- MAY immediately be followed by a PGT attribute. The PGT attribute +- SHALL be followed by the set of PG Portal IP-Address, PG TCP/UDP Port +- pairs representing Portal objects that will be associated with the +- Storage Node using the indicated PGT value. Additional sets of PGTs +- and PG Portal IP-Address PG TCP/UDP Port pairs to be associated with +- the registered Storage Node MAY follow. Indicated PGT values are +- assigned to the PG object associated with the newly registered iSCSI +- Storage Node and Portal object(s) referenced immediately following +- the PGT attribute in the operating attributes. +- +- If the PGT value is not included in the Storage Node or Portal object +- registration, and if a PGT value was not previously registered for +- the relationship, then the PGT for the corresponding PG object SHALL +- be registered with a value of 0x00000001. If the PGT attribute is +- included in the registration message as a 0-length TLV, then the PGT +- value for the corresponding PG object SHALL be registered as NULL. A +- 0-length TLV for the PGT in an update registration message overwrites +- the previous PGT value with NULL, indicating that there is no +- relationship between the Storage Node and Portal. +- +- A maximum of one Network Entity object can be created or updated with +- a single DevAttrReg message. Consequently, the Operating Attributes +- MUST NOT contain more than one Network Entity object. There is no +- limit to the number of Portal, Storage Node, and FC Device objects +- that can listed in the Operating Attributes, provided they are all +- subordinate to the listed Network Entity object. +- +- If the Message Key and Operating Attributes do not contain an EID +- attribute, or if the EID attribute has a length of 0, then a new +- Network Entity object SHALL be created and the iSNS server SHALL +- supply a unique EID value for it. The assigned EID value SHALL be +- included in the DevAttrReg Response message. If the Message Key and +- Operating Attributes contain an EID that does not match the EID of an +- existing Network Entity in the iSNS database, then a new Network +- Entity SHALL be created and assigned the value contained in that EID +- attribute. Finally, if the Message Key and Operating Attributes +- contain an EID that matches the EID of an existing object in the iSNS +- +- +- +-Tseng, et al. Standards Track [Page 46] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- database, then the objects, attributes, and relationships specified +- in the Operating Attributes SHALL be appended to the existing Network +- Entity identified by the EID. +- +- A registration message that creates a new Network Entity object MUST +- contain at least one Portal or one Storage Node. If the message does +- not, then it SHALL be considered invalid and result in a response +- with Status Code of 3 (Invalid Registration). +- +- If an iSNS Server does not support a registration feature, such as +- explicit PG object registration, then the server SHALL return a +- Status Code of 23 (Registration Feature Not Supported). +- +- Note that the iSNS server may modify or reject the registration of +- certain attributes, such as ESI Interval. In addition, the iSNS +- server may assign values for additional Operating Attributes that are +- not explicitly registered in the original DevAttrReg message, such as +- the EID and WWNN Token. +- +-5.6.5.2. Device Attribute Query Request (DevAttrQry) +- +- The DevAttrQry message type is 0x0002. The DevAttrQry message +- provides an iSNS client with the means to query the iSNS server for +- object attributes. +- +- The Source Attribute identifies the Node initiating the request. For +- non-Control Nodes initiating the DevAttrQry message, the query is +- scoped to the Discovery Domains of which the initiating Node is a +- member. The DevAttrQry message SHALL only return information on +- Storage Nodes and their related parent and subordinate objects, where +- the Storage Node has a common Discovery Domain with the Node +- identified in the Source Attribute. +- +- The Message Key may contain key or non-key attributes or no +- attributes at all. If multiple attributes are used as the Message +- Key, then they MUST all be from the same object type (e.g., IP +- address and TCP/UDP Port are attributes of the Portal object type). +- A Message Key with non-key attributes may match multiple instances of +- the specific object type. A Message Key with zero-length TLV(s) is +- scoped to every object of the type indicated by the zero-length +- TLV(s). An empty Message Key field indicates the query is scoped to +- the entire database accessible by the source Node. +- +- The DevAttrQry response message returns attributes of objects listed +- in the Operating Attributes that are related to the Message Key of +- the original DevAttrQry message. The Operating Attributes of the +- DevAttrQry message contain zero-length TLVs that specify the +- attributes that are to be returned in the DevAttrQryRsp message. A +- +- +- +-Tseng, et al. Standards Track [Page 47] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- Message Key containing zero-length TLVs indicates that the set of +- attributes specified in the Operating Attributes are to be returned +- for each object matching the type indicated by the Message Key. +- +- If the Message Key contains non-zero length TLVs, then Operating +- Attributes for the object matching the Message Key SHALL be returned +- in the DevAttrQryRsp message. Each attribute type (i.e., zero-length +- TLV) in the Operating Attributes indicates an attribute from the +- object matching the Message Key, or from other objects in the same +- Entity having a relationship to the object matching the Message Key, +- is to be returned in the response. The ordering of the object keys +- and associated attributes returned in the DevAttrQry response message +- SHALL be the same as in the original query message. If no objects +- match the Message Key, then the DevAttrQryRsp message SHALL NOT +- return any operating attributes. Such a message and its +- corresponding response SHALL NOT be considered an error. +- +- The Portal Group object determines whether a relationship exists +- between a given Storage Node and Portal object. If the PGT of the +- Portal Group is not NULL, then a relationship exists between the +- indicated Storage Node and Portal; if the PGT is NULL, then no +- relationship exists. Therefore, the value (NULL or not NULL) of the +- PGT attribute of each Portal Group object determines the structure +- and ordering of the DevAttrQry response to a query for Storage Nodes +- and Portals. +- +- For example, an iSNS database contains a Network Entity having two +- Portals and two Nodes. Each Storage Node has two Portal Groups, one +- with a NULL PGT value for one Portal and another with a non-NULL PGT +- value for the other Portal. The DevAttrQry message contains a +- Message Key entry matching one of the Nodes, and Operating Attributes +- with zero-length TLVs listing first the Node attributes, Portal +- attributes, and then the PG attributes. The response message SHALL +- therefore return first the matching Node object, then the requested +- attributes of the one Portal object that can be used to access the +- Storage Node (as indicated by the PGT), and finally the requested +- attributes of the PG object used to access that Storage Node. The +- order in which each object's attributes are listed is the same as the +- ordering of the object's attributes in the Operating Attributes of +- the original request message. +- +- If the Message Key Attribute contains zero-length TLV(s), then the +- query returns requested attributes for all objects matching the +- Message Key type (DD restrictions SHALL apply for non-Control Nodes). +- If multiple objects match the Message Key type, then the attributes +- for each object matching the Message Key MUST be listed before the +- attributes for the next matching object are listed in the query +- +- +- +- +-Tseng, et al. Standards Track [Page 48] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- response. In other words, the process described above must be +- iterated in the message response for each object that matches the +- Message Key type specified by the zero-length TLV(s). +- +- For example, an iSNS database contains only one Network Entity having +- two Portals and three Nodes. All PG objects in the Entity have a PGT +- value of 0x00000001. In the DevAttrQry message, the Message Key +- contains a zero-length TLV specifying a Node type, and Operating +- Attributes listing first the Node attributes, and then the Portal +- attributes. The response message will return, in the following +- order, the attributes for the first, next, and last Node objects, +- each followed by attributes for both Portals. If that same +- DevAttrQry message had instead contained a zero-length TLV specifying +- the Network Entity type, then the response message would have +- returned attributes for all three Node objects, followed by +- attributes for the two Portals. +- +- If there is no Message Key Attribute, then the query returns all +- attributes in the iSNS database (once again, DD restrictions SHALL +- apply for non-Control Nodes). All attributes matching the type +- specified by each zero-length TLV in the Operating Attributes SHALL +- be listed. All attributes of each type SHALL be listed before the +- attributes matching the next zero-length TLV are listed. +- +- For example, an iSNS database contains two Entities, each having two +- Nodes and two Portals. The DevAttrQry message contains no Message +- Key attribute, and Operating Attributes list first the Portal +- attributes, and then the Node attributes. The Operating Attributes +- of the response message will return attributes from each of the four +- Portals, followed by attributes from each of the four nodes. +- +- If a DevAttrQry message requests an attribute for which the iSNS +- server has no value, then the server SHALL NOT return the requested +- attribute in the query response. Such query and response messages +- SHALL NOT be considered errors. +- +- Registration and query messages for iSNS server-specific attributes +- (i.e., tags in the range 132 to 384) SHALL be formatted using the +- identifying key attribute of the Storage Node originating the query +- (i.e., iSCSI Name or FC Port Name WWPN) for both the Source Attribute +- and Message Key attribute. Operating Attributes SHALL include the +- TLV of the server-specific attribute being requested. +- +- DD membership can be discovered through the DevAttrQry message by +- including either DD member attributes (i.e., DD Member iSCSI Index, +- DD Member iSCSI Node, DD Member iFCP Node, DD Member Portal Index, DD +- Member Portal IP Addr, and DD Member Portal TCP/UDP) or the object +- key of the Storage Node or Portal (i.e., iSCSI Name, iSCSI Index, +- +- +- +-Tseng, et al. Standards Track [Page 49] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- Portal IP Addr, Portal TCP/UDP Port, and Portal Index) in the +- Operating Attributes. Using DD member attributes SHALL return both +- registered and unregistered member Storage Nodes and/or Portals of a +- DD. DevAttrQry messages using the Storage Node and/or Portal object +- key SHALL return only member Storage Nodes or Portals that are +- currently registered in the iSNS database. +- +- The DevAttrQry message SHALL support the following minimum set of +- Message Key Attributes: +- +- Valid Message Key Attributes for Queries +- ---------------------------------------- +- Entity Identifier +- Entity Protocol +- Portal IP-Address & Portal TCP/UDP Port +- Portal Index +- iSCSI Node Type +- iSCSI Name +- iSCSI Index +- PG Index +- FC Port Name WWPN +- FC Port Type +- FC-4 Type +- Discovery Domain ID +- Discovery Domain Set ID +- Source Attribute (for server-specific attributes) +- Switch Name (FC Device WWNN--for Virtual_Fabric_ID queries) +- +-5.6.5.3. Device Get Next Request (DevGetNext) +- +- The DevGetNext message type is 0x0003. This message provides the +- iSNS client with the means to retrieve each and every instance of an +- object type exactly once. +- +- The Source Attribute identifies the Node initiating the DevGetNext +- request, and is used to scope the retrieval process to the Discovery +- Domains of which the initiating Node is a member. +- +- The Message Key Attribute may be an Entity Identifier (EID), iSCSI +- Name, iSCSI Index, Portal IP Address and TCP/UDP Port, Portal Index, +- PG Index, FC Node Name WWNN, or FC Port Name WWPN. If the TLV length +- of the Message Key Attribute(s) is zero, then the first object entry +- in the iSNS database matching the Message Key type SHALL be returned +- in the Message Key of the corresponding DevGetNextRsp message. If +- non-zero-length TLV attributes are contained in the Message Key, then +- the DevGetNext response message SHALL return the next object stored +- after the object identified by the Message Key in the original +- DevGetNext request message. +- +- +- +-Tseng, et al. Standards Track [Page 50] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- If the Message Key provided matches the last object instance in the +- iSNS database, then the Status Code of 9 (No Such Entry) SHALL be +- returned in the response. +- +- The Operating Attributes can be used to specify the scope of the +- DevGetNext request, and to specify the attributes of the next object, +- which are to be returned in the DevGetNext response message. All +- Operating Attributes MUST be attributes of the object type identified +- by the Message Key. For example, if the Message Key is an Entity_ID +- attribute, then the Operating Attributes MUST NOT contain attributes +- of Portals. +- +- Non-zero-length TLV attributes in the Operating Attributes are used +- to scope the DevGetNext message. Only the next object with attribute +- values that match the non-zero-length TLV attributes SHALL be +- returned in the DevGetNext response message. +- +- Zero-length TLV attributes MUST be listed after non-zero-length +- attributes in the Operating Attributes of the DevGetNext request +- message. Zero-length TLV attributes specify the attributes of the +- next object which are to be returned in the DevGetNext response +- message. +- +- Note that there are no specific requirements concerning the order in +- which object entries are retrieved from the iSNS database; the +- retrieval order of object entries using the DevGetNext message is +- implementation specific. +- +- The iSNS client is responsible for ensuring that information acquired +- through use of the DevGetNext message is accurate and up-to-date. +- There is no assurance that the iSNS database will not change between +- successive DevGetNext request messages. If the Message Key provided +- does not match an existing database entry, then attributes for the +- next object key following the provided Message Key SHALL be returned. +- For example, an object entry may have been deleted between successive +- DevGetNext messages. This may result in a DevGetNext request in +- which the Message Key does not match an existing object entry. In +- this case, attributes for the next object stored in the iSNS database +- are returned. +- +-5.6.5.4. Device Deregister Request (DevDereg) +- +- The DevDereg message type is 0x0004. This message is used to remove +- object entries from the iSNS database. One or more objects may be +- removed through a single DevDereg message. Note that deregistered +- Storage Node objects will retain membership in their Discovery +- Domain(s) until explicit deregistration of the membership(s) or +- Discovery Domain(s). +- +- +- +-Tseng, et al. Standards Track [Page 51] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- Upon receiving the DevDereg, the iSNS server removes all objects +- identified by the Operating Attribute(s), and all subordinate objects +- that are solely dependent on those identified objects. For example, +- removal of a Network Entity also results in removal of all associated +- Portal, Portal Group, Storage Node, and FC Device objects associated +- with that Network Entity. FC Device objects SHALL not be +- deregistered in this manner unless all Storage Nodes associated with +- them have been deregistered. +- +- The DevDereg request PDU Payload contains a Source Attribute and +- Operating Attribute(s); there are no Message Key Attributes. If the +- Node identified by the Source Attribute is not a Control Node, then +- it MUST be from the same Network Entity as the object(s) identified +- for removal by the Operating Attribute(s). Valid Operating +- Attributes are shown below: +- +- Valid Operating Attributes for DevDereg +- --------------------------------------- +- Entity Identifier +- Portal IP-Address & Portal TCP/UDP Port +- Portal Index +- iSCSI Name +- iSCSI Index +- FC Port Name WWPN +- FC Node Name WWNN +- +- The removal of the object may result in SCN messages to the +- appropriate iSNS clients. +- +- Attempted deregistration of non-existing entries SHALL not be +- considered an error. +- +- If all Nodes and Portals associated with a Network Entity are +- deregistered, then the Network Entity SHALL also be removed. +- +- If both the Portal and iSCSI Storage Node objects associated with a +- Portal Group object are removed, then that Portal Group object SHALL +- also be removed. The Portal Group object SHALL remain registered as +- long as either of its associated Portal or iSCSI Storage Node objects +- remain registered. If a deleted Storage Node or Portal object is +- subsequently re-registered, then a relationship between the re- +- registered object and an existing Portal or Storage Node object +- registration, indicated by the PG object, SHALL be restored. +- +- +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 52] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +-5.6.5.5. SCN Register Request (SCNReg) +- +- The SCNReg message type is 0x0005. The State Change Notification +- Registration Request (SCNReg) message allows an iSNS client to +- register a Storage Node to receive State Change Notification (SCN) +- messages. +- +- The SCN notifies the Storage Node of changes to any Storage Nodes +- within any DD of which it is a member. If the Storage Node is a +- Control Node, it SHALL receive SCN notifications for changes in the +- entire network. Note that whereas SCNReg sets the SCN Bitmap field, +- the DevAttrReg message registers the UDP or TCP Port used by each +- Portal to receive SCN messages. If no SCN Port fields of any Portals +- of the Storage Node are registered to receive SCN messages, then the +- SCNReg message SHALL be rejected with Status Code 17 (SCN +- Registration Rejected). +- +- The SCNReg request PDU Payload contains a Source Attribute, a Message +- Key Attribute, and an Operating Attribute. Valid Message Key +- Attributes for a SCNReg are shown below: +- +- Valid Message Key Attributes for SCNReg +- --------------------------------------- +- iSCSI Name +- FC Port Name WWPN +- +- The node with the iSCSI Name or FC Port Name WWPN attribute that +- matches the Message Key in the SCNReg message is registered to +- receive SCNs using the specified SCN bitmap. A maximum of one Node +- SHALL be registered for each SCNReg message. +- +- The SCN Bitmap is the only operating attribute of this message, and +- it always overwrites the previous contents of this field in the iSNS +- database. The bitmap indicates the SCN event types for which the +- Node is registering. +- +- Note that the settings of this bitmap determine whether the SCN +- registration is for regular SCNs or management SCNs. Control Nodes +- MAY conduct registrations for management SCNs; iSNS clients that are +- not supporting Control Nodes MUST NOT conduct registrations for +- management SCNs. Control Nodes that register for management SCNs +- receive a copy of every SCN message generated by the iSNS server. It +- is recommended that management registrations be used only when needed +- in order to conserve iSNS server resources. In addition, a Control +- Node that conducts such registrations should be prepared to receive +- the anticipated volume of SCN message traffic. +- +- +- +- +- +-Tseng, et al. Standards Track [Page 53] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +-5.6.5.6. SCN Deregister Request (SCNDereg) +- +- The SCNDereg message type is 0x0006. The SCNDereg message allows an +- iSNS client to stop receiving State Change Notification (SCN) +- messages. +- +- The SCNDereg request message PDU Payload contains a Source Attribute +- and Message Key Attribute(s). Valid Message Key Attributes for a +- SCNDereg are shown below: +- +- Valid Message Key Attributes for SCNDereg +- ----------------------------------------- +- iSCSI Name +- FC Port Name WWPN +- +- The node with an iSCSI Name or FC Port Name WWPN attribute that +- matches the Message Key Attributes in the SCNDereg message is +- deregistered for SCNs. The SCN bitmap field of such Nodes are +- cleared. A maximum of one Node SHALL be deregistered for each +- SCNDereg message. +- +- There are no Operating Attributes in the SCNDereg message. +- +-5.6.5.7. SCN Event (SCNEvent) +- +- The SCNEvent message type is 0x0007. The SCNEvent is a message sent +- by an iSNS client to request generation of a State Change +- Notification (SCN) message by the iSNS server. The SCN, sent by the +- iSNS server, then notifies iFCP, iSCSI, and Control Nodes within the +- affected DD of the change indicated in the SCNEvent. +- +- Most SCNs are automatically generated by the iSNS server when Nodes +- are registered or deregistered from the directory database. SCNs are +- also generated when a network management application or Control Node +- makes changes to the DD membership in the iSNS server. However, an +- iSNS client can trigger an SCN by using SCNEvent. +- +- The SCNEvent message PDU Payload contains a Source Attribute, a +- Message Key Attribute, and an Operating Attribute. Valid Key +- Attributes for a SCNEvent are shown below: +- +- Valid Message Key Attributes for SCNEvent +- ----------------------------------------- +- iSCSI Name +- FC Port Name WWPN +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 54] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- The Operating Attributes section SHALL contain the SCN Event Bitmap +- attribute. The bitmap indicates the event that caused the SCNEvent +- to be generated. +- +-5.6.5.8. State Change Notification (SCN) +- +- The SCN message type is 0x0008. The SCN is a message generated by +- the iSNS server, notifying a registered Storage Node of changes. +- There are two types of SCN registrations: regular registrations and +- management registrations. Regular SCNs notify iSNS clients of events +- within the discovery domain. Management SCNs notify Control Nodes +- that register for management SCNs of events occurring anywhere in the +- network. +- +- If no active TCP connection to the SCN recipient exists, then the SCN +- message SHALL be sent to one Portal of the registered Storage Node +- that has a registered TCP or UDP Port value in the SCN Port field. +- If more than one Portal of the Storage Node has a registered SCN Port +- value, then the SCN SHALL be delivered to any one of the indicated +- Portals, provided that the selected Portal is not the subject of the +- SCN. +- +- The types of events that can trigger an SCN message, and the amount +- of information contained in the SCN message, depend on the registered +- SCN Event Bitmap for the Storage Node. The iSCSI Node SCN Bitmap is +- described in Section 6.4.4. The iFCP SCN Bitmap is described in +- Section 6.6.12. +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 55] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- The format of the SCN PDU Payload is shown below: +- +- +----------------------------------------+ +- | Destination Attribute | +- +----------------------------------------+ +- | Timestamp | +- +----------------------------------------+ +- | Source SCN Bitmap 1 | +- +----------------------------------------+ +- | Source Attribute [1] | +- +----------------------------------------+ +- | Source Attribute [2](if present) | +- +----------------------------------------+ +- | Source Attribute [3](if present) | +- +----------------------------------------+ +- | Source Attribute [n](if present) | +- +----------------------------------------+ +- | Source SCN Bitmap 2 (if present) | +- +----------------------------------------+ +- | . . . | +- +----------------------------------------+ +- +- All PDU Payload attributes are in TLV format. +- +- The Destination Attribute is the Node identifier that is receiving +- the SCN. The Destination Attribute can be an iSCSI Name or FC Port +- Name. +- +- The Timestamp field, using the Timestamp TLV format, described in +- Section 6.2.4, indicates the time the SCN was generated. +- +- The Source SCN Bitmap field indicates the type of SCN notification +- (i.e., regular or management SCN), and the type of event that caused +- the SCN to be generated; it does not necessarily correlate with the +- original SCN bitmap registered in the iSNS server. +- +- Following the timestamp, the SCN message SHALL list the SCN bitmap, +- followed by the key attribute (i.e., iSCSI Name or FC Port Name) of +- the Storage Node affected by the SCN event. If the SCN is a +- Management SCN, then the SCN message SHALL also list the DD_ID and/or +- DDS_ID of the Discovery Domains and Discovery Domain Sets (if any) +- that caused the change in state for that Storage Node. These +- additional attributes (i.e., DD_ID and/or DDS_ID) shall immediately +- follow the iSCSI Name or FC Port Name and precede the next SCN bitmap +- for the next notification message (if any). The SCN bitmap is used +- as a delineator for SCN messages providing multiple state change +- notifications. +- +- +- +- +-Tseng, et al. Standards Track [Page 56] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- For example, a regular SCN for notifying an iSNS client of a new +- Portal available for a particular iSCSI target would contain the SCN +- bitmap followed by the iSCSI Name of the target device as the source +- attribute. If the SCN were a management SCN, then the iSCSI Name +- would be followed by the DD_ID(s) of the shared Discovery Domains +- that allow the destination Storage Node to have visibility to the +- affected Storage Node. If a Discovery Domain Set (DDS) was enabled +- in order to provide this visibility, then the appropriate DDS_ID +- would be included as well. +- +- A management SCN is also generated to notify a Control Node of the +- creation, deletion, or modification of a Discovery Domain or +- Discovery Domain Set. In this case, the DD_ID and/or DDS_ID of the +- affected Discovery Domain and/or Discovery Domain Set would follow +- the SCN bitmap. +- +- For example, a management SCN to notify a Control Node of a new DD +- within a Discovery Domain Set would contain both the DD_ID and the +- DDS_ID of the affected Discovery Domain and Discovery Domain Set +- among the Source Attributes. +- +- See Sections 6.4.4 and 6.6.12 for additional information on the SCN +- Bitmap. +- +-5.6.5.9. DD Register (DDReg) +- +- The DDReg message type is 0x0009. This message is used to create a +- new Discovery Domain (DD), to update an existing DD Symbolic Name +- and/or DD Features attribute, and to add DD members. +- +- DDs are uniquely defined using DD_IDs. DD registration attributes +- are described in Section 6.11. +- +- The DDReg message PDU Payload contains the Source Attribute and +- optional Message Key and Operating Attributes. +- +- The Message Key, if used, contains the DD_ID of the Discovery Domain +- to be registered. If the Message Key contains a DD_ID of an existing +- DD entry in the iSNS database, then the DDReg message SHALL attempt +- to update the existing entry. If the DD_ID in the Message Key (if +- used) does not match an existing DD entry, then the iSNS server SHALL +- reject the DDReg message with a status code of 3 (Invalid +- Registration). If the DD_ID is included in both the Message Key and +- Operating Attributes, then the DD_ID value in the Message Key MUST be +- the same as the DD_ID value in the Operating Attributes. +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 57] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- A DDReg message with no Message Key SHALL result in the attempted +- creation of a new Discovery Domain (DD). If the DD_ID attribute +- (with non-zero length) is included among the Operating Attributes in +- the DDReg message, then the new Discovery Domain SHALL be assigned +- the value contained in that DD_ID attribute. Otherwise, if the DD_ID +- attribute is not contained among the Operating Attributes of the +- DDReg message, or if the DD_ID is an operating attribute with a TLV +- length of 0, then the iSNS server SHALL assign a DD_ID value. The +- assigned DD_ID value is then returned in the DDReg Response message. +- The Operating Attributes can also contain the DD Member iSCSI Node +- Index, DD Member iSCSI Name, DD Member FC Port Name, DD Member Portal +- IP Address, DD Member Portal TCP/UDP Port Number, or DD Member Portal +- Index of members to be added to the DD. It may also contain the +- DD_Symbolic_Name and/or DD_Features of the DD. +- +- This message SHALL add any DD members listed as Operating Attributes +- to the Discovery Domain specified by the DD_ID. If the DD_Features +- attribute is an Operating Attribute, then it SHALL be stored in the +- iSNS server as the feature list for the specified DD. If the +- DD_Symbolic_Name is an operating attribute and its value is unique +- (i.e., it does not match the registered DD_Symbolic_Name for another +- DD), then the value SHALL be stored in the iSNS database as the +- DD_Symbolic_Name for the specified Discovery Domain. If the value +- for the DD_Symbolic_Name is not unique, then the iSNS server SHALL +- reject the attempted DD registration with a status code of 3 (Invalid +- Registration). +- +- When creating a new DD, if the DD_Symbolic_Name is not included in +- the Operating Attributes, or if it is included with a zero-length +- TLV, then the iSNS server SHALL provide a unique DD_Symbolic_Name +- value for the created DD. The assigned DD_Symbolic_Name value SHALL +- be returned in the DDRegRsp message. +- +- When creating a new DD, if the DD_Features attribute is not included +- in the Operating Attributes, then the iSNS server SHALL assign the +- default value. The default value for DD_Features is 0. +- +- DD Member iSCSI Name, DD Member iFCP Node, DD Member Portal IP +- Address, and DD Member TCP/UDP Port Number attributes included in the +- Operating Attributes need not match currently existing iSNS database +- entries. This allows, for example, a Storage Node to be added to a +- DD even if the Storage Node is not currently registered in the iSNS +- database. A Storage Node or Portal can thereby be added to a DD at +- the time of the DDs creation, even if the Storage Node or Portal is +- not currently active in the storage network. +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 58] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- If the Operating Attributes contain a DD Member iSCSI Name value for +- a Storage Node that is currently not registered in the iSNS database, +- then the iSNS server MUST allocate an unused iSCSI Node Index for +- that Storage Node. The assigned iSCSI Node Index SHALL be returned +- in the DDRegRsp message as the DD Member iSCSI Node Index. The +- allocated iSCSI Node Index value SHALL be assigned to the Storage +- Node if and when it registers in the iSNS database. +- +- If the Operating Attributes contain a DD Member Portal IP Addr and DD +- Member Portal TCP/UDP value for a Portal that is not currently +- registered in the iSNS database, then the iSNS server MUST allocate +- an unused Portal Index value for that Portal. The assigned Portal +- Index value SHALL be returned in the DDRegRsp message as the DD +- Member Portal Index. The allocated Portal Index value SHALL be +- assigned to the Portal if and when it registers in the iSNS database. +- +- DD Member iSCSI Node Index and DD Member Portal Index attributes that +- are provided in the Operating Attributes MUST match a corresponding +- iSCSI Node Index or Portal Index of an existing Storage Node or +- Portal entry in the iSNS database. Furthermore, the DD Member iSCSI +- Node Index and DD Member Portal Index SHALL NOT be used to add +- Storage Nodes or Portals to a DD unless those Storage Nodes or +- Portals are actively registered in the iSNS database. +- +-5.6.5.10. DD Deregister (DDDereg) +- +- The DDDereg message type is 0x000A. This message allows an iSNS +- client to deregister an existing Discovery Domain (DD) and to remove +- members from an existing DD. +- +- DDs are uniquely identified using DD_IDs. DD registration attributes +- are described in Section 6.11. +- +- The DDDereg message PDU Payload contains a Source Attribute, Message +- Key Attribute, and optional Operating Attributes. +- +- The Message Key Attribute for a DDDereg message is the DD ID for the +- Discovery Domain being removed or having members removed. If the DD +- ID matches an existing DD and there are no Operating Attributes, then +- the DD SHALL be removed and a success Status Code returned. Any +- existing members of that DD SHALL remain in the iSNS database without +- membership in the just-removed DD. +- +- If the DD ID matches an existing DD and there are Operating +- Attributes matching DD members, then the DD members identified by the +- Operating Attributes SHALL be removed from the DD and a successful +- Status Code returned. +- +- +- +- +-Tseng, et al. Standards Track [Page 59] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- If a DD Member iSCSI Name identified in the Operating Attributes +- contains an iSCSI Name for a Storage Node that is not currently +- registered in the iSNS database or contained in another DD, then the +- association between that Storage Node and its pre-assigned iSCSI Node +- Index SHALL be removed. The pre-assigned iSCSI Node Index value no +- longer has an association to a specific iSCSI Name and can now be +- re-assigned. +- +- If a DD Member Portal IP Address and DD Member TCP/UDP Port +- identified in the Operating Attributes reference a Portal that is not +- currently registered in the iSNS database or contained in another DD, +- then the association between that Portal and its pre-assigned Portal +- Index SHALL be removed. The pre-assigned Portal Index value can now +- be reassigned. +- +- The attempted deregistration of non-existent DD entries SHALL not be +- considered an error. +- +-5.6.5.11. DDS Register (DDSReg) +- +- The DDSReg message type is 0x000B. This message allows an iSNS +- client to create a new Discovery Domain Set (DDS), to update an +- existing DDS Symbolic Name and/or DDS Status, or to add DDS members. +- +- DDSs are uniquely defined using DDS_IDs. DDS registration attributes +- are described in Section 6.11.1. +- +- The DDSReg message PDU Payload contains the Source Attribute and, +- optionally, Message Key and Operating Attributes. +- +- The Message Key, if used, contains the DDS_ID of the Discover Domain +- Set to be registered or modified. If the Message Key contains a +- DDS_ID of an existing DDS entry in the iSNS database, then the DDSReg +- message SHALL attempt to update the existing entry. If the DDS_ID in +- the Message Key (if used) does not match an existing DDS entry, then +- the iSNS server SHALL reject the DDSReg message with a status code of +- 3 (Invalid Registration). If the DDS_ID is included in both the +- Message Key and Operating Attributes, then the DDS_ID value in the +- Message Key MUST be the same as the DDS_ID value in the Operating +- Attributes. +- +- A DDSReg message with no Message Key SHALL result in the attempted +- creation of a new Discovery Domain Set (DDS). If the DDS_ID +- attribute (with non-zero length) is included among the Operating +- Attributes in the DDSReg message, then the new Discovery Domain Set +- SHALL be assigned the value contained in that DDS_ID attribute. +- Otherwise, if the DDS_ID attribute is not contained among the +- Operating Attributes of the DDSReg message, or if the DDS_ID is an +- +- +- +-Tseng, et al. Standards Track [Page 60] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- operating attribute with a TLV length of 0, then the iSNS server +- SHALL assign a DDS_ID value. The assigned DDS_ID value is then +- returned in the DDSReg Response message. The Operating Attributes +- can also contain the DDS_Symbolic_Name, the DDS Status, and the +- DD_IDs of Discovery Domains to be added to the DDS. +- +- When creating a new DDS, if the DDS Symbolic Name is included in the +- Operating Attributes and its value is unique (i.e., it does not match +- the registered DDS Symbolic Name for another DDS), then the value +- SHALL be stored in the iSNS database as the DDS Symbolic Name for +- that DDS. If the value for the DDS Symbolic Name is not unique, then +- the iSNS server SHALL reject the attempted DDS registration with a +- status code of 3 (Invalid Registration). +- +- When creating a new DDS, if the DDS Symbolic Name is not included in +- the Operating Attributes, or if it is included with a zero-length +- TLV, then the iSNS server SHALL provide a unique DDS Symbolic Name +- value for the created DDS. The assigned DDS Symbolic Name value +- SHALL be returned in the DDSRegRsp message. +- +- This message SHALL add any DD_IDs listed as Operating Attributes to +- the Discovery Domain Set specified by the DDS_ID Message Key +- Attribute. In addition, if the DDS_Symbolic_Name is an operating +- attribute and the value is unique, then it SHALL be stored in the +- iSNS database as the DDS_Symbolic_Name for the specified Discovery +- Domain Set. +- +- If a DD_ID listed in the Operating Attributes does not match an +- existing DD, then a new DD using the DD_ID SHALL be created. In this +- case for the new DD, the iSNS server SHALL assign a unique value for +- the DD Symbolic Name and SHALL set the DD Features attribute to the +- default value of 0. These assigned values SHALL be returned in the +- DDSRegRsp message. +- +-5.6.5.12. DDS Deregister (DDSDereg) +- +- The DDSDereg message type is 0x000C. This message allows an iSNS +- client to deregister an existing Discovery Domain Set (DDS) or to +- remove some DDs from an existing DDS. +- +- The DDSDereg message PDU Payload contains a Source Attribute, a +- Message Key Attribute, and optional Operating Attributes. +- +- The Message Key Attribute for a DDSDereg message is the DDS ID for +- the DDS being removed or having members removed. If the DDS ID +- matches an existing DDS and there are no Operating Attributes, then +- +- +- +- +- +-Tseng, et al. Standards Track [Page 61] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- the DDS SHALL be removed and a success Status Code returned. Any +- existing members of that DDS SHALL remain in the iSNS database +- without membership in the just-removed DDS. +- +- If the DDS ID matches an existing DDS, and there are Operating +- Attributes matching DDS members, then the DDS members SHALL be +- removed from the DDS and a success Status Code returned. +- +- The attempted deregistration of non-existent DDS entries SHALL not be +- considered an error. +- +-5.6.5.13. Entity Status Inquiry (ESI) +- +- The ESI message type is 0x000D. This message is sent by the iSNS +- server, and is used to verify that an iSNS client Portal is reachable +- and available. The ESI message is sent to the ESI UDP port provided +- during registration, or to the TCP connection used for ESI +- registration, depending on which communication type that is being +- used. +- +- The ESI message PDU Payload contains the following attributes in TLV +- format and in the order listed: the current iSNS timestamp, the EID, +- the Portal IP Address, and the Portal TCP/UDP Port. The format of +- this message is shown below: +- +- +----------------------------------------+ +- | Timestamp | +- +----------------------------------------+ +- | Entity_ID | +- +----------------------------------------+ +- | Portal IP Address | +- +----------------------------------------+ +- | Portal TCP/UDP Port | +- +----------------------------------------+ +- +- The ESI response message PDU Payload contains a status code, followed +- by the Attributes from the original ESI message. +- +- If the Portal fails to respond to an administratively-determined +- number of consecutive ESI messages, then the iSNS server SHALL remove +- that Portal from the iSNS database. If there are no other remaining +- ESI-monitored Portals for the associated Network Entity, then the +- Network Entity SHALL also be removed. The appropriate State Change +- Notifications, if any, SHALL be triggered. +- +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 62] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +-5.6.5.14. Name Service Heartbeat (Heartbeat) +- +- This message, if used, is only sent by the active iSNS server. It +- allows iSNS clients and backup servers listening to a broadcast or +- multicast address to discover the IP address of the primary and +- backup iSNS servers. It also allows concerned parties to monitor the +- health and status of the primary iSNS server. +- +- This message is NOT in TLV format. There is no response message to +- the Name Service Heartbeat. +- +- MSb LSb +- 0 31 +- +------------------------------------------------+ +- | Active Server IP-Address | 16 Bytes +- +------------------------------------------------+ +- | iSNS TCP Port | iSNS UDP Port | 4 Bytes +- +------------------------------------------------+ +- | Interval | 4 Bytes +- +------------------------------------------------+ +- | Counter | 4 Bytes +- +------------------------------------------------+ +- | RESERVED | Backup Servers | 4 Bytes +- +------------------------------------------------+ +- | Primary Backup Server IP Address(if any) | 16 Bytes +- +------------------------------------------------+ +- |Backup TCP Port(if any)|Backup UDP Port(if any) | 4 Bytes +- +------------------------------------------------+ +- | 2nd Backup Server IP Address(if any) | 16 Bytes +- +------------------------------------------------+ +- |Backup TCP Port(if any)|Backup UDP Port(if any) | 4 Bytes +- +------------------------------------------------+ +- | . . . | +- +------------------------------------------------+ +- | VENDOR SPECIFIC | +- +------------------------------------------------+ +- +- The heartbeat PDU Payload contains the following: +- +- Active Server IP Address: the IP Address of the active iSNS server in +- IPv6 format. When this field contains an IPv4 +- value, it is stored as an IPv4-mapped IPv6 address. +- That is, the most significant 10 bytes are set to +- 0x00, with the next two bytes set to 0xFFFF +- [RFC2373]. When this field contains an IPv6 value, +- the entire 16-byte field is used. +- +- Active TCP Port: the TCP Port of the server currently in use. +- +- +- +-Tseng, et al. Standards Track [Page 63] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- Active UDP Port: the UDP Port of the server currently in use, +- otherwise 0. +- +- Interval: the interval, in seconds, of the heartbeat. +- +- Counter: a count that begins at 0 when this server becomes +- active. The count increments by one for each +- heartbeat sent since this server became active. +- +- Backup Servers: the number of iSNS backup servers. The IP address, +- TCP Port, and UDP Port of each iSNS backup server +- follow this field. Note that if backup servers are +- used, then the active iSNS server SHOULD be among +- the list of backup servers. +- +- The content of the remainder of this message after the list of backup +- servers is vendor-specific. Vendors may use additional fields to +- coordinate between multiple iSNS servers, and/or to identify vendor- +- specific features. +- +-5.6.5.15. Request FC_DOMAIN_ID (RqstDomId) +- +- The RqstDomId message type is 0x0011. This message is used for iFCP +- Transparent Mode to allocate non-overlapping FC_DOMAIN_ID values +- between 1 and 239. The iSNS server becomes the address assignment +- authority for the entire iFCP fabric. To obtain multiple +- FC_DOMAIN_ID values, this request must be repeated to the iSNS server +- multiple times. iSNS clients that acquire FC_DOMAIN_ID values from +- an iSNS server MUST register for ESI monitoring from that iSNS +- server. +- +- The RqstDomId PDU Payload contains three TLV attributes in the +- following order: the requesting Switch Name (WWN) as the Source +- Attribute, the Virtual_Fabric_ID as the Message Key Attribute, and +- Preferred ID as the operating attribute. The Virtual_Fabric_ID is a +- string identifying the domain space for which the iSNS server SHALL +- allocate non-overlapping integer FC_DOMAIN_ID values between 1 and +- 239. The Preferred_ID is the nominal FC_DOMAIN_ID value requested by +- the iSNS client. If the Preferred_ID value is available and has not +- already been allocated for the Virtual_Fabric_ID specified in the +- message, the iSNS server SHALL return the requested Preferred_ID +- value as the Assigned_ID to the requesting client. +- +- The RqstDomId response contains a Status Code, and the TLV attribute +- Assigned ID, which contains the integer value in the space requested. +- If no further unallocated values are available from this space, the +- iSNS server SHALL respond with the Status Code 18 "FC_DOMAIN_ID Not +- Available". +- +- +- +-Tseng, et al. Standards Track [Page 64] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- Once a FC_DOMAIN_ID value has been allocated to an iSNS client by the +- iSNS server for a given Virtual_Fabric_ID, that FC_DOMAIN_ID value +- SHALL NOT be reused until it has been deallocated, or until ESI +- monitoring detects that the iSNS client no longer exists on the +- network and objects for that client are removed from the iSNS +- database. +- +- The iSNS server and client SHALL use TCP to transmit and receive +- RqstDomId, RqstDomIdRsp, RlseDomId, and RlseDomIdRsp messages. +- +-5.6.5.16. Release FC_DOMAIN_ID (RlseDomId) +- +- The RlseDomId message type is 0x0012. This message may be used by +- iFCP Transparent Mode to release integer identifier values used to +- assign 3-byte Fibre Channel PORT_ID values. +- +- The RlseDomId message contains three TLV attributes in the following +- order: the requesting EID as the Source Attribute, the +- Virtual_Fabric_ID as the Message Key Attribute, and Assigned_ID as +- the operating attribute. Upon receiving the RlseDomId message, the +- iSNS server SHALL deallocate the FC_DOMAIN_ID value contained in the +- Assigned_ID attribute for the Virtual_Fabric_ID attribute specified. +- Upon deallocation, that FC_DOMAIN_ID value can then be requested by +- and assigned to a different iSNS client. +- +- The iSNS server and client SHALL use TCP to transmit and receive +- RqstDomId, RqstDomIdRsp, RlseDomId, and RlseDomIdRsp messages. +- +-5.6.5.17. Get FC_DOMAIN_IDs (GetDomId) +- +- The GetDomId message type is 0x0013. This message is used to learn +- the currently-allocated FC_DOMAIN_ID values for a given +- Virtual_Fabric_ID. +- +- The GetDomId message PDU Payload contains a Source Attribute and +- Message Key Attribute. +- +- The Message Key Attribute for the GetDomId message is the +- Virtual_Fabric_ID. The response to this message returns all the +- FC_DOMAIN_ID values that have been allocated for the +- Virtual_Fabric_ID specified. +- +- +- +- +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 65] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +-5.7. Messages +- +- The iSNSP response message PDU Payloads contain a Status Code, +- followed by a list of attributes, and have the following format: +- +- MSb LSb +- 0 31 +- +----------------------------------------+ +- | 4-byte STATUS CODE | +- +----------------------------------------+ +- | Message Key Attribute[1] (if present) | +- +----------------------------------------+ +- | Message Key Attribute[2] (if present) | +- +----------------------------------------+ +- | . . . | +- +----------------------------------------+ +- | - Delimiter Attribute - (if present) | +- +----------------------------------------+ +- | Operating Attribute[1] (if present) | +- +----------------------------------------+ +- | Operating Attribute[2] (if present) | +- +----------------------------------------+ +- | Operating Attribute[3] (if present) | +- +----------------------------------------+ +- | . . . | +- +----------------------------------------+ +- +- The iSNSP Response messages SHALL be sent to the iSNS Client IP +- Address and the originating TCP/UDP Port that was used for the +- associated registration and query message. +- +-5.7.1. Status Code +- +- The first field in an iSNSP response message PDU Payload is the +- Status Code for the operation that was performed. The Status Code +- encoding is defined in Section 5.4. +- +-5.7.2. Message Key Attributes in Response +- +- Depending on the specific iSNSP request, the response message MAY +- contain Message Key Attributes. Message Key Attributes generally +- contain the interesting key attributes that are affected by the +- operation specified in the original iSNS registration or query +- message. +- +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 66] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +-5.7.3. Delimiter Attribute in Response +- +- The Delimiter Attribute separates the key and Operating Attributes in +- a response message, if they exist. The Delimiter Attribute has a tag +- value of 0 and a length value of 0. The Delimiter Attribute is +- effectively 8 bytes long: a 4-byte tag containing 0x00000000, and a 4 +- Byte length field containing 0x00000000. +- +-5.7.4. Operating Attributes in Response +- +- The Operating Attributes in a response are the results related to the +- iSNS registration or query operation being performed. Some response +- messages will not have Operating Attributes. +- +-5.7.5. Registration and Query Response Message Types +- +- The following sections describe each query and message type. +- +-5.7.5.1. Device Attribute Registration Response (DevAttrRegRsp) +- +- The DevAttrRegRsp message type is 0x8001. The DevAttrRegRsp message +- contains the results for the DevAttrReg message with the same +- TRANSACTION ID. +- +- The Message Key in the DevAttrRegRsp message SHALL return the Message +- Key in the original registration message. If the iSNS server +- assigned the Entity Identifier for a Network Entity, then the Message +- Key Attribute field SHALL contain the assigned Entity Identifier. +- +- The Operating Attributes of the DevAttrRegRsp message SHALL contain +- the affected object's key and non-key attributes that have been +- explicitly modified or created by the original DevAttrReg message. +- Among the Operating Attributes, each modified or added non-key +- attribute SHALL be listed after its key attribute(s) in the +- DevAttrRegRsp message. Implicitly registered attributes MUST NOT be +- returned in the DevAttrRegRsp message. Implicitly registered +- attributes are those that are assigned a fixed default value or +- secondary index value by the iSNS server. +- +- Implicitly registered PG objects (i.e., PG objects that are not +- explicitly included in the registration or replace message) MUST NOT +- have their key or non-key attributes returned in the DevAttrRegRsp +- message. However, explicitly registered PG objects (i.e., those with +- PGT values that are explicitly included in the registration or +- replace message) SHALL have their PGT values returned in the +- DevAttrRegRsp message. +- +- +- +- +- +-Tseng, et al. Standards Track [Page 67] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- For example, three Portals are registered in the original DevAttrReg +- request message. Due to lack of resources, the iSNS server needs to +- modify the registered ESI Interval value of one of those Portals. To +- accomplish this, the iSNS server returns the key attributes +- identifying the Portal, followed by the non-key modified ESI Interval +- attribute value, as Operating Attributes of the corresponding +- DevAttrRegRsp message. +- +- If the iSNS server rejects a registration due to invalid attribute +- values or types, then the indicated status code SHALL be 3 (Invalid +- Registration). If this occurs, then the iSNS server MAY include the +- list of invalid attributes in the Operating Attributes of the +- DevAttrRsp message. +- +- Some attributes values (e.g., ESI Interval, Registration Period) in +- the original registration message MAY be modified by the iSNS server. +- This can occur only for a limited set of attribute types, as +- indicated in the table in Section 6.1. When this occurs, the +- registration SHALL be considered a success (with status code 0), and +- the changed value(s) indicated in the Operating Attributes of the +- DevAttrRsp message. +- +-5.7.5.2. Device Attribute Query Response (DevAttrQryRsp) +- +- The DevAttrQryRsp message type is 0x8002. The DevAttrQryRsp message +- contains the results for the DevAttrQry message with the same +- TRANSACTION ID. +- +- The Message Key in the DevAttrQryRsp message SHALL return the Message +- Key in the original query message. +- +- If no Operating Attributes are included in the original query, then +- all Operating Attributes SHALL be returned in the response. +- +- For a successful query result, the DevAttrQryRsp Operating Attributes +- SHALL contain the results of the original DevAttrQry message. +- +-5.7.5.3. Device Get Next Response (DevGetNextRsp) +- +- The DevGetNextRsp message type is 0x8003. The DevGetNextRsp message +- contains the results for the DevGetNext message with the same +- TRANSACTION ID. +- +- The Message Key Attribute field returns the object keys for the next +- object after the Message Key Attribute in the original DevGetNext +- message. +- +- +- +- +- +-Tseng, et al. Standards Track [Page 68] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- The Operating Attribute field returns the Operating Attributes of the +- next object as requested in the original DevGetNext message. The +- values of the Operating Attributes are those associated with the +- object identified by the Message Key Attribute field of the +- DevGetNextRsp message. +- +-5.7.5.4. Deregister Device Response (DevDeregRsp) +- +- The DevDeregRsp message type is 0x8004. This message is the response +- to the DevDereg request message. +- +- This message response does not contain a Message Key, but MAY contain +- Operating Attributes. +- +- In the event of an error, this response message contains the +- appropriate status code as well as a list of objects from the +- original DevDereg message that were not successfully deregistered +- from the iSNS database. This list of objects is contained in the +- Operating Attributes of the DevDeregRsp message. Note that an +- attempted deregistration of a non-existent object does not constitute +- an error, and non-existent entries SHALL not be returned in the +- DevDeregRsp message. +- +-5.7.5.5. SCN Register Response (SCNRegRsp) +- +- The SCNRegRsp message type is 0x8005. This message is the response +- to the SCNReg request message. +- +- The SCNRegRsp message does not contain any Message Key or Operating +- Attributes. +- +-5.7.5.6. SCN Deregister Response (SCNDeregRsp) +- +- The SCNDeregRsp message type is 0x8006. This message is the response +- to the SCNDereg request message. +- +- The SCNDeregRsp message does not contain any Message Key or Operating +- Attributes. +- +-5.7.5.7. SCN Event Response (SCNEventRsp) +- +- The SCNEventRsp message type is 0x8007. This message is the response +- to the SCNEvent request message. +- +- The SCNEventRsp message does not contain any Message Key or Operating +- Attributes. +- +- +- +- +- +-Tseng, et al. Standards Track [Page 69] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +-5.7.5.8. SCN Response (SCNRsp) +- +- The SCNRsp message type is 0x8008. This message is sent by an iSNS +- client, and provides confirmation that the SCN message was received +- and processed. +- +- The SCNRsp response contains the SCN Destination Attribute +- representing the Node identifier that received the SCN. +- +-5.7.5.9. DD Register Response (DDRegRsp) +- +- The DDRegRsp message type is 0x8009. This message is the response to +- the DDReg request message. +- +- The Message Key in the DDRegRsp message SHALL return the Message Key +- in the original query message. If the original DDReg message did not +- have a Message Key, then the DDRegRsp message SHALL not have a +- Message Key. +- +- If the DDReg operation is successful, the DD ID of the DD created or +- updated SHALL be returned as an operating attribute of the message. +- +- If the DD Symbolic Name attribute or DD Features attribute was +- assigned or updated during the DDReg operation, then any new values +- SHALL be returned as an operating attribute of the DDRegRsp message. +- +- If the iSNS server rejects a DDReg due to invalid attribute values or +- types, then the indicated status code SHALL be 3 (Invalid +- Registration). If this occurs, then the iSNS server MAY include the +- list of invalid attributes in the Operating Attributes of the +- DDRegRsp message. +- +-5.7.5.10. DD Deregister Response (DDDeregRsp) +- +- The DDDeregRsp message type is 0x800A. This message is the response +- to the DDDereg request message. +- +- The DDDeregRsp message does not contain any Message Key or Operating +- Attributes. +- +- +- +- +- +- +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 70] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +-5.7.5.11. DDS Register Response (DDSRegRsp) +- +- The DDSRegRsp message type is 0x800B. This message is the response +- to the DDSReg request message. +- +- The Message Key in the DDSRegRsp message SHALL contain the Message +- Key of the original DDSReg message. If the original DDSReg message +- did not have a Message Key, then the DDSRegRsp message SHALL NOT have +- a Message Key. +- +- If the DDSReg operation is successful, the DDS ID of the DDS created +- or updated SHALL be returned as an operating attribute of the +- message. +- +- If the DDS Symbolic Name attribute or DDS Status attribute was +- assigned or updated during the DDSRegRsp operation, then any new +- values SHALL be returned as an operating attribute of the DDSRegRsp +- message. +- +- If the iSNS server rejects a DDSReg due to invalid attribute values +- or types, then the indicated status code SHALL be 3 (Invalid +- Registration). If this occurs, then the iSNS server MAY include the +- list of invalid attributes in the Operating Attributes of the +- DDSRegRsp message. +- +-5.7.5.12. DDS Deregister Response (DDSDeregRsp) +- +- The DDSDeregRsp message type is 0x800C. This message is the response +- to the DDSDereg request message. +- +- The DDSDeregRsp message does not contain any Message Key or Operating +- Attributes. +- +-5.7.5.13. Entity Status Inquiry Response (ESIRsp) +- +- The ESIRsp message type is 0x800D. This message is sent by an iSNS +- client and provides confirmation that the ESI message was received +- and processed. +- +- The ESIRsp response message PDU Payload contains the attributes from +- the original ESI message. These attributes represent the Portal that +- is responding to the ESI. The ESIRsp Attributes are in the order +- they were provided in the original ESI message. +- +- Upon receiving the ESIRsp from the iSNS client, the iSNS server SHALL +- update the timestamp attribute for that Network Entity and Portal. +- +- +- +- +- +-Tseng, et al. Standards Track [Page 71] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +-5.7.5.14. Request FC_DOMAIN_ID Response (RqstDomIdRsp) +- +- The RqstDomIdRsp message type is 0x8011. This message provides the +- response for RqstDomId. +- +- The RqstDomId response contains a Status Code and the TLV attribute +- Assigned ID, which contains the integer value in the space requested. +- If no further unallocated values are available from this space, the +- iSNS server SHALL respond with the Status Code 19 "FC_DOMAIN_ID Not +- Available". +- +- Once a FC_DOMAIN_ID value is allocated by the iSNS server, it SHALL +- NOT be reused until it has been deallocated by the iSNS client to +- which the value was assigned, or until the ESI message detects that +- the iSNS client no longer exists on the network. +- +- The iSNS server and client SHALL use TCP to transmit and receive +- RqstDomId, RqstDomIdRsp, RlseDomId, and RlseDomIdRsp messages. +- +-5.7.5.15. Release FC_DOMAIN_ID Response (RlseDomIdRsp) +- +- The RlseDomIdRsp message type is 0x8012. This message provides the +- response for RlseDomId. The response contains an Error indicating +- whether the request was successful. If the Assigned_ID value in the +- original RlseDomId message is not allocated, then the iSNS server +- SHALL respond with this message using the Status Code 20 +- "FC_DOMAIN_ID Not Allocated". +- +- The iSNS server and client SHALL use TCP to transmit and receive +- RqstDomId, RqstDomIdRsp, RlseDomId, and RlseDomIdRsp messages. +- +-5.7.5.16. Get FC_DOMAIN_IDs Response (GetDomIdRsp) +- +- The GetDomIdRsp message type is 0x8013. This message is used to +- determine which FC_DOMAIN_ID values have been allocated for the +- Virtual_Fabric_ID specified in the original GetDomId request message. +- +- The GetDomId response message PDU Payload contains a Status Code +- indicating whether the request was successful, and a list of the +- Assigned IDs from the space requested. The Assigned_ID attributes +- are listed in TLV format. +- +-5.8. Vendor-Specific Messages +- +- Vendor-specific iSNSP messages have a functional ID of between 0x0100 +- and 0x01FF, whereas vendor-specific responses have a functional ID of +- between 0x8100 and 0x81FF. The first Message Key Attribute in a +- +- +- +- +-Tseng, et al. Standards Track [Page 72] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- vendor-specific message SHALL be the company OUI (tag=256) +- identifying the original creator of the proprietary iSNSP message. +- The contents of the remainder of the message are vendor-specific. +- +-6. iSNS Attributes +- +- Attributes can be stored in the iSNS server using iSNSP registration +- messages, and they can be retrieved using iSNSP query messages. +- Unless otherwise indicated, these attributes are supplied by iSNS +- clients using iSNSP registration messages. +- +-6.1. iSNS Attribute Summary +- +- The complete registry of iSNS attributes is maintained by IANA, and +- the following table summarizes the initial set of iSNS attributes +- available at the time of publication of this document. +- +- Attributes Length Tag Reg Key Query Key +- ---------- ------ --- ------- --------- +- Delimiter 0 0 N/A N/A +- Entity Identifier (EID) 4-256 1 1 1|2|16&17|32|64 +- Entity Protocol 4 2 1 1|2|16&17|32|64 +- Management IP Address 16 3 1 1|2|16&17|32|64 +- Timestamp 8 4 -- 1|2|16&17|32|64 +- Protocol Version Range 4 5 1 1|2|16&17|32|64 +- Registration Period 4 6 1 1|2|16&17|32|64 +- Entity Index 4 7 1 1|2|16&17|32|64 +- Entity Next Index 4 8 -- 1|2|16&17|32|64 +- Entity ISAKMP Phase-1 var 11 1 1|2|16&17|32|64 +- Entity Certificate var 12 1 1|2|16&17|32|64 +- Portal IP Address 16 16 1 1|16&17|32|64 +- Portal TCP/UDP Port 4 17 1 1|16&17|32|64 +- Portal Symbolic Name 4-256 18 16&17 1|16&17|32|64 +- ESI Interval 4 19 16&17 1|16&17|32|64 +- ESI Port 4 20 16&17 1|16&17|32|64 +- Portal Index 4 22 16&17 1|16&17|32|64 +- SCN Port 4 23 16&17 1|16&17|32|64 +- Portal Next Index 4 24 -- 1|16&17|32|64 +- Portal Security Bitmap 4 27 16&17 1|16&17|32|64 +- Portal ISAKMP Phase-1 var 28 16&17 1|16&17|32|64 +- Portal ISAKMP Phase-2 var 29 16&17 1|16&17|32|64 +- Portal Certificate var 31 16&17 1|16&17|32|64 +- iSCSI Name 4-224 32 1 1|16&17|32|33 +- iSCSI Node Type 4 33 32 1|16&17|32 +- iSCSI Alias 4-256 34 32 1|16&17|32 +- iSCSI SCN Bitmap 4 35 32 1|16&17|32 +- iSCSI Node Index 4 36 32 1|16&17|32 +- WWNN Token 8 37 32 1|16&17|32 +- +- +- +-Tseng, et al. Standards Track [Page 73] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- iSCSI Node Next Index 4 38 -- 1|16&17|32 +- iSCSI AuthMethod var 42 32 1|16&17|32 +- PG iSCSI Name 4-224 48 32|16&17 1|16&17|32|52 +- PG Portal IP Addr 16 49 32|16&17 1|16&17|32|52 +- PG Portal TCP/UDP Port 4 50 32|16&17 1|16&17|32|52 +- PG Tag (PGT) 4 51 32|16&17 1|16&17|32|52 +- PG Index 4 52 32|16&17 1|16&17|32|52 +- PG Next Index 4 53 -- 1|16&17|32|52 +- FC Port Name WWPN 8 64 1 1|16&17|64|66|96|128 +- Port ID 4 65 64 1|16&17|64 +- FC Port Type 4 66 64 1|16&17|64 +- Symbolic Port Name 4-256 67 64 1|16&17|64 +- Fabric Port Name 8 68 64 1|16&17|64 +- Hard Address 4 69 64 1|16&17|64 +- Port IP-Address 16 70 64 1|16&17|64 +- Class of Service 4 71 64 1|16&17|64 +- FC-4 Types 32 72 64 1|16&17|64 +- FC-4 Descriptor 4-256 73 64 1|16&17|64 +- FC-4 Features 128 74 64 1|16&17|64 +- iFCP SCN bitmap 4 75 64 1|16&17|64 +- Port Role 4 76 64 1|16&17|64 +- Permanent Port Name 8 77 -- 1|16&17|64 +- FC-4 Type Code 4 95 -- 1|16&17|64 +- FC Node Name WWNN 8 96 64 1|16&17|64|96 +- Symbolic Node Name 4-256 97 96 64|96 +- Node IP-Address 16 98 96 64|96 +- Node IPA 8 99 96 64|96 +- Proxy iSCSI Name 4-256 101 96 64|96 +- Switch Name 8 128 128 128 +- Preferred ID 4 129 128 128 +- Assigned ID 4 130 128 128 +- Virtual_Fabric_ID 4-256 131 128 128 +- iSNS Server Vendor OUI 4 256 -- SOURCE Attribute +- Vendor-Spec iSNS Srvr 257-384 -- SOURCE Attribute +- Vendor-Spec Entity 385-512 1 1|2|16&17|32|64 +- Vendor-Spec Portal 513-640 16&17 1|16&17|32|64 +- Vendor-Spec iSCSI Node 641-768 32 16&17|32 +- Vendor-Spec FC Port Name 769-896 64 1|16&17|64 +- Vendor-Spec FC Node Name 897-1024 96 64|96 +- Vendor-Specific DDS 1025-1280 2049 2049 +- Vendor-Specific DD 1281-1536 2065 2065 +- Other Vendor-Specific 1537-2048 +- DD_Set ID 4 2049 2049 1|32|64|2049|2065 +- DD_Set Sym Name 4-256 2050 2049 2049 +- DD_Set Status 4 2051 2049 2049 +- DD_Set_Next_ID 4 2052 -- 2049 +- DD_ID 4 2065 2049 1|32|64|2049|2065 +- DD_Symbolic Name 4-256 2066 2065 2065 +- +- +- +-Tseng, et al. Standards Track [Page 74] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- DD_Member iSCSI Index 4 2067 2065 2065 +- DD_Member iSCSI Name 4-224 2068 2065 2065 +- DD_Member FC Port Name 8 2069 2065 2065 +- DD_Member Portal Index 4 2070 2065 2065 +- DD_Member Portal IP Addr 16 2071 2065 2065 +- DD_Member Portal TCP/UDP 4 2072 2065 2065 +- DD_Features 4 2078 2065 2065 +- DD_ID Next ID 4 2079 -- 2065 +- +- The following are descriptions of the columns used in the above +- table: +- +- Length: indicates the attribute length in bytes used for the TLV +- format. Variable-length identifiers are NULL-terminated +- and 4-byte aligned (NULLs are included in the length). +- +- Tag: the IANA-assigned integer tag value used to identify the +- attribute. All undefined tag values are reserved. +- +- Reg Key: indicates the tag values for the object key in DevAttrReg +- messages for registering a new attribute value in the +- database. These tags represent attributes defined as +- object keys in Section 4. +- +- Query Key: indicates the possible tag values for the Message Key and +- object key that are used in the DevAttrQry messages for +- retrieving a stored value from the iSNS database. +- +- The following is a summary of iSNS attribute tag values available for +- future allocation by IANA at the time of publication: +- +- Tag Values Reg Key Query Key +- ---------- ------- --------- +- 9-10, 13-15 1 1|2|16&17|32|64 +- 21, 25-26, 30 16&17 1|16&17|32|64 +- 39-41, 44-47 32 1|16&17|32 +- 54-63 32|16&17 1|16&17|32|52 +- 78-82, 85-94 64 1|16&17|64 +- 102-127 96 64|96 +- 132-255 -- SOURCE Attribute +- 2053-2064 2049 2049 +- 2073-2077 2065 2065 +- 2080-65535 To be assigned To be assigned +- +- Registration and query keys for attributes with tags in the range +- 2080 to 65535 are to be documented in the RFC introducing the new +- iSNS attributes. IANA will maintain registration of these values as +- required by the new RFC. +- +- +- +-Tseng, et al. Standards Track [Page 75] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- New iSNS attributes with any of the above tag values MAY also be +- designated as "read-only" attributes. The new RFC introducing these +- attributes as "read-only" SHALL document them as such, and IANA will +- record their corresponding Registration Keys (Reg Keys) as "--". +- +-6.2. Entity Identifier-Keyed Attributes +- +- The following attributes are stored in the iSNS server using the +- Entity Identifier attribute as the key. +- +-6.2.1. Entity Identifier (EID) +- +- The Entity Identifier (EID) is variable-length UTF-8 encoded NULL- +- terminated text-based description for a Network Entity. This key +- attribute uniquely identifies each Network Entity registered in the +- iSNS server. The attribute length varies from 4 to 256 bytes +- (including the NULL termination), and is a unique value within the +- iSNS server. +- +- If the iSNS client does not provide an EID during registration, the +- iSNS server SHALL generate one that is unique within the iSNS +- database. If an EID is to be generated, then the EID attribute value +- in the registration message SHALL be empty (0 length). The generated +- EID SHALL be returned in the registration response. +- +- In environments where the iSNS server is integrated with a DNS +- infrastructure, the Entity Identifier may be used to store the Fully +- Qualified Domain Name (FQDN) of the iSCSI or iFCP device. FQDNs of +- greater than 255 bytes MUST NOT be used. +- +- If FQDNs are not used, the iSNS server can be used to generate EIDs. +- EIDs generated by the iSNS server MUST begin with the string "isns:". +- iSNS clients MUST NOT generate and register EIDs beginning with the +- string "isns:". +- +- This field MUST be normalized according to the nameprep template +- [NAMEPREP] before it is stored in the iSNS database. +- +-6.2.2. Entity Protocol +- +- The Entity Protocol is a required 4-byte integer attribute that +- indicates the block storage protocol used by the registered NETWORK +- ENTITY. Values used for this attribute are assigned and maintained +- by IANA. The initial set of protocols supported by iSNS is as +- follows: +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 76] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- Value Entity Protocol Type +- ----- -------------------- +- 1 No Protocol +- 2 iSCSI +- 3 iFCP +- All others To be assigned by IANA +- +- 'No Protocol' is used to indicate that the Network Entity does not +- support an IP block storage protocol. A Control Node or monitoring +- Node would likely (but not necessarily) use this value. +- +- This attribute is required during initial registration of the Network +- Entity. +- +-6.2.3. Management IP Address +- +- This field contains the IP Address that may be used to manage the +- Network Entity and all Storage Nodes contained therein via the iSNS +- MIB [iSNSMIB]. Some implementations may also use this IP address to +- support vendor-specific proprietary management protocols. The +- Management IP Address is a 16-byte field that may contain an IPv4 or +- IPv6 address. When this field contains an IPv4 value, it is stored +- as an IPv4-mapped IPv6 address. That is, the most significant 10 +- bytes are set to 0x00, with the next two bytes set to 0xFFFF +- [RFC2373]. When this field contains an IPv6 value, the entire 16- +- byte field is used. If this field is not set, then in-band +- management through the IP address of one of the Portals of the +- Network Entity is assumed. +- +-6.2.4. Entity Registration Timestamp +- +- This field indicates the most recent time when the Network Entity +- registration occurred or when an associated object attribute was +- updated or queried by the iSNS client registering the Network Entity. +- The time format is, in seconds, the update period since the standard +- base time of 00:00:00 GMT on January 1, 1970. This field cannot be +- explicitly registered. This timestamp TLV format is also used in the +- SCN and ESI messages. +- +-6.2.5. Protocol Version Range +- +- This field contains the minimum and maximum version of the block +- storage protocol supported by the Network Entity. The most +- significant two bytes contain the maximum version supported, and the +- least significant two bytes contain the minimum version supported. +- If a range is not registered, then the Network Entity is assumed to +- +- +- +- +- +-Tseng, et al. Standards Track [Page 77] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- support all versions of the protocol. The value 0xffff is a wildcard +- that indicates no minimum or maximum. If the Network Entity does not +- support a protocol, then this field SHALL be set to 0. +- +-6.2.6. Registration Period +- +- This 4-byte unsigned integer field indicates the maximum period, in +- seconds, that the registration SHALL be maintained by the server +- without receipt of an iSNS message from the iSNS client that +- registered the Network Entity. Entities that are not registered for +- ESI monitoring MUST have a non-zero Registration Period. If a +- Registration Period is not requested by the iSNS client and Entity +- Status Inquiry (ESI) messages are not enabled for that client, then +- the Registration Period SHALL be set to a non-zero value by the iSNS +- server. This implementation-specific value for the Registration +- Period SHALL be returned in the registration response to the iSNS +- client. The Registration Period may be set to zero, indicating its +- non-use, only if ESI messages are enabled for that Network Entity. +- +- The registration SHALL be removed from the iSNS database if an iSNS +- Protocol message is not received from the iSNS client before the +- registration period has expired. Receipt of any iSNS Protocol +- message from the iSNS client automatically refreshes the Entity +- Registration Period and Entity Registration Timestamp. To prevent a +- registration from expiring, the iSNS client should send an iSNS +- Protocol message to the iSNS server at intervals shorter than the +- registration period. Such a message can be as simple as a query for +- one of its own attributes, using its associated iSCSI Name or FC Port +- Name WWPN as the Source attribute. +- +- For an iSNS client that is supporting a Network Entity with multiple +- Storage Node objects, receipt of an iSNS message from any Storage +- Node of that Network Entity is sufficient to refresh the registration +- for all Storage Node objects of the Network Entity. +- +- If ESI support is requested as part of a Portal registration, the ESI +- Response message received from the iSNS client by the iSNS server +- SHALL refresh the registration. +- +-6.2.7. Entity Index +- +- The Entity Index is an unsigned non-zero integer value that uniquely +- identifies each Network Entity registered in the iSNS server. Upon +- initial registration of a Network Entity, the iSNS server assigns an +- unused value for the Entity Index. Each Network Entity in the iSNS +- database MUST be assigned a value for the Entity Index that is not +- +- +- +- +- +-Tseng, et al. Standards Track [Page 78] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- assigned to any other Network Entity. Furthermore, Entity Index +- values for recently deregistered Network Entities SHOULD NOT be +- reused in the short term. +- +- The Entity Index MAY be used to represent the Network Entity in +- situations when the Entity Identifier is too long or otherwise +- inappropriate. An example of this is when SNMP is used for +- management, as described in Section 2.10. +- +-6.2.8. Entity Next Index +- +- This is a virtual attribute containing a 4-byte integer value that +- indicates the next available (i.e., unused) Entity Index value. This +- attribute may only be queried; the iSNS server SHALL return an error +- code of 3 (Invalid Registration) to any client that attempts to +- register a value for this attribute. A Message Key is not required +- when exclusively querying for this attribute. +- +- The Entity Next Index MAY be used by an SNMP client to create an +- entry in the iSNS server. SNMP requirements are described in Section +- 2.10. +- +-6.2.9. Entity ISAKMP Phase-1 Proposals +- +- This field contains the IKE Phase-1 proposal, listing in decreasing +- order of preference the protection suites acceptable to protect all +- IKE Phase-2 messages sent and received by the Network Entity. This +- includes Phase-2 SAs from the iSNS client to the iSNS server as well +- as to peer iFCP and/or iSCSI devices. This attribute contains the SA +- payload, proposal payload(s), and transform payload(s) in the ISAKMP +- format defined in [RFC2408]. +- +- This field should be used if the implementer wishes to define a +- single phase-1 SA security configuration used to protect all phase-2 +- IKE traffic. If the implementer desires to have a different phase-1 +- SA security configuration to protect each Portal interface, then the +- Portal Phase-1 Proposal (Section 6.3.10) should be used. +- +-6.2.10. Entity Certificate +- +- This attribute contains one or more X.509 certificates that are bound +- to the Network Entity. This certificate is uploaded and registered +- to the iSNS server by clients wishing to allow other clients to +- authenticate themselves and to access the services offered by that +- Network Entity. The format of the X.509 certificate is found in +- [RFC3280]. This certificate MUST contain a Subject Name with an +- empty sequence and MUST contain a SubjectAltName extension encoded +- +- +- +- +-Tseng, et al. Standards Track [Page 79] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- with the dNSName type. The Entity Identifier (Section 6.2.1) of the +- identified Entity MUST be stored in the SubjectAltName field of the +- certificate. +- +-6.3. Portal-Keyed Attributes +- +- The following Portal attributes are registered in the iSNS database +- using the combined Portal IP-Address and Portal TCP/UDP Port as the +- key. Each Portal is associated with one Entity Identifier object +- key. +- +-6.3.1. Portal IP Address +- +- This attribute is the IP address of the Portal through which a +- Storage Node can transmit and receive storage data. The Portal IP +- Address is a 16-byte field that may contain an IPv4 or IPv6 address. +- When this field contains an IPv4 address, it is stored as an IPv4- +- mapped IPv6 address. That is, the most significant 10 bytes are set +- to 0x00, with the next 2 bytes set to 0xFFFF [RFC2373]. When this +- field contains an IPv6 address, the entire 16-byte field is used. +- The Portal IP Address and the Portal TCP/UDP Port number (see 6.3.2 +- below) are used as a key to identify a Portal uniquely. It is a +- required attribute for registration of a Portal. +- +-6.3.2. Portal TCP/UDP Port +- +- The TCP/UDP port of the Portal through which a Storage Node can +- transmit and receive storage data. Bits 16 to 31 represents the +- TCP/UDP port number. Bit 15 represents the port type. If bit 15 is +- set, then the port type is UDP. Otherwise it is TCP. Bits 0 to 14 +- are reserved. +- +- If the field value is 0, then the port number is the implied +- canonical port number and type of the protocol indicated by the +- associated Entity Type. +- +- The Portal IP Address and the Portal TCP/UDP Port number are used as +- a key to identify a Portal uniquely. It is a required attribute for +- registration of a Portal. +- +-6.3.3. Portal Symbolic Name +- +- A variable-length UTF-8 encoded NULL-terminated text-based +- description of up to 256 bytes. The Portal Symbolic Name is a user- +- readable description of the Portal entry in the iSNS server. +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 80] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +-6.3.4. Entity Status Inquiry Interval +- +- This field indicates the requested time, in seconds, between Entity +- Status Inquiry (ESI) messages sent from the iSNS server to this +- Network Entity. ESI messages can be used to verify that a Portal +- registration continues to be valid. To request monitoring by the +- iSNS server, an iSNS client registers a non-zero value for this +- Portal attribute using a DevAttrReg message. The client MUST +- register an ESI Port on at least one of its Portals to receive the +- ESI monitoring. +- +- If the iSNS server does not receive an expected response to an ESI +- message, it SHALL attempt an administratively configured number of +- re-transmissions of the ESI message. The ESI Interval period begins +- with the iSNS server's receipt of the last ESI Response. All re- +- transmissions MUST be sent before twice the ESI Interval period has +- passed. If no response is received from any of the ESI messages, +- then the Portal SHALL be deregistered. Note that only Portals that +- have registered a value in their ESI Port field can be deregistered +- in this way. +- +- If all Portals associated with a Network Entity that have registered +- for ESI messages are deregistered due to non-response, and if no +- registrations have been received from the client for at least two ESI +- Interval periods, then the Network Entity and all associated objects +- (including Storage Nodes) SHALL be deregistered. +- +- If the iSNS server is unable to support ESI messages or the ESI +- Interval requested, it SHALL either reject the ESI request by +- returning an "ESI Not Available" Status Code or modify the ESI +- Interval attribute by selecting its own suitable value and returning +- that value in the Operating Attributes of the registration response +- message. +- +- If at any time an iSNS client that is registered for ESI messages has +- not received an ESI message to any of its Portals as expected, then +- the client MAY attempt to query the iSNS server using a DevAttrQry +- message using its Entity_ID as the key. If the query result is the +- error "no such entry", then the client SHALL close all remaining TCP +- connections to the iSNS server and assume that it is no longer +- registered in the iSNS database. Such a client MAY attempt re- +- registration. +- +- +- +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 81] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +-6.3.5. ESI Port +- +- This field contains the TCP or UDP port used for ESI monitoring by +- the iSNS server at the Portal IP Address. Bits 16 to 31 represent +- the port number. If bit 15 is set, then the port type is UDP. +- Otherwise, the port is TCP. Bits 0 to 14 are reserved. +- +- If the iSNS client registers a valid TCP or UDP port number in this +- field, then the client SHALL allow ESI messages to be received at the +- indicated TCP or UDP port. If a TCP port is registered and a pre- +- existing TCP connection from that TCP port to the iSNS server does +- not already exist, then the iSNS client SHALL accept new TCP +- connections from the iSNS server at the indicated TCP port. +- +- The iSNS server SHALL return an error if a Network Entity is +- registered for ESI monitoring and none of the Portals of that Network +- Entity has an entry for the ESI Port field. If multiple Portals have +- a registered ESI port, then the ESI message may be delivered to any +- one of the indicated Portals. +- +-6.3.6. Portal Index +- +- The Portal Index is a 4-byte non-zero integer value that uniquely +- identifies each Portal registered in the iSNS database. Upon initial +- registration of a Portal, the iSNS server assigns an unused value for +- the Portal Index of that Portal. Each Portal in the iSNS database +- MUST be assigned a value for the Portal Index that is not assigned to +- any other Portal. Furthermore, Portal Index values for recently +- deregistered Portals SHOULD NOT be reused in the short term. +- +- The Portal Index MAY be used to represent a registered Portal in +- situations where the Portal IP-Address and Portal TCP/UDP Port is +- unwieldy to use. An example of this is when SNMP is used for +- management, as described in Section 2.10. +- +-6.3.7. SCN Port +- +- This field contains the TCP or UDP port used by the iSNS client to +- receive SCN messages from the iSNS server. When a value is +- registered for this attribute, an SCN message may be received on the +- indicated port for any of the Storage Nodes supported by the Portal. +- Bits 16 to 31 contain the port number. If bit 15 is set, then the +- port type is UDP. Otherwise, the port type is TCP. Bits 0 to 14 are +- reserved. +- +- If the iSNS client registers a valid TCP or UDP port number in this +- field, then the client SHALL allow SCN messages to be received at the +- indicated TCP or UDP port. If a TCP port is registered and a pre- +- +- +- +-Tseng, et al. Standards Track [Page 82] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- existing TCP connection from that TCP port to the iSNS server does +- not already exist, then the iSNS client SHALL accept new TCP +- connections from the iSNS server at the indicated TCP port. +- +- The iSNS server SHALL return an error if an SCN registration message +- is received and none of the Portals of the Network Entity has an +- entry for the SCN Port. If multiple Portals have a registered SCN +- Port, then the SCN SHALL be delivered to any one of the indicated +- Portals of that Network Entity. +- +-6.3.8. Portal Next Index +- +- This is a virtual attribute containing a 4-byte integer value that +- indicates the next available (i.e., unused) Portal Index value. This +- attribute may only be queried; the iSNS server SHALL return an error +- code of 3 (Invalid Registration) to any client that attempts to +- register a value for this attribute. A Message Key is not required +- when exclusively querying for this attribute. +- +- The Portal Next Index MAY be used by an SNMP client to create an +- entry in the iSNS server. SNMP requirements are described in Section +- 2.10. +- +-6.3.9. Portal Security Bitmap +- +- This 4-byte field contains flags that indicate security attribute +- settings for the Portal. Bit 31 (Lsb) of this field must be 1 +- (enabled) for this field to contain significant information. If Bit +- 31 is enabled, this signifies that the iSNS server can be used to +- store and distribute security policies and settings for iSNS clients +- (i.e., iSCSI devices). Bit 30 must be 1 for bits 25-29 to contain +- significant information. All other bits are reserved for non- +- IKE/IPSec security mechanisms to be specified in the future. +- +- Bit Position Flag Description +- ------------ ---------------- +- 25 1 = Tunnel Mode Preferred; 0 = No Preference +- 26 1 = Transport Mode Preferred; 0 = No Preference +- 27 1 = Perfect Forward Secrecy (PFS) Enabled; +- 0 = PFS Disabled +- 28 1 = Aggressive Mode Enabled; 0 = Disabled +- 29 1 = Main Mode Enabled; 0 = MM Disabled +- 30 1 = IKE/IPSec Enabled; 0 = IKE/IPSec Disabled +- 31 (Lsb) 1 = Bitmap VALID; 0 = INVALID +- All others RESERVED +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 83] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +-6.3.10. Portal ISAKMP Phase-1 Proposals +- +- This field contains the IKE Phase-1 proposal listing in decreasing +- order of preference of the protection suites acceptable to protect +- all IKE Phase-2 messages sent and received by the Portal. This +- includes Phase-2 SAs from the iSNS client to the iSNS server as well +- as to peer iFCP and/or iSCSI devices. This attribute contains the SA +- payload, proposal payload(s), and transform payload(s) in the ISAKMP +- format defined in [RFC2408]. +- +- This field should be used if the implementer wishes to define phase-1 +- SA security configuration on a per-Portal basis, as opposed to on a +- per-Network Entity basis. If the implementer desires to have a +- single phase-1 SA security configuration to protect all phase-2 +- traffic regardless of the interface used, then the Entity Phase-1 +- Proposal (Section 6.2.9) should be used. +- +-6.3.11. Portal ISAKMP Phase-2 Proposals +- +- This field contains the IKE Phase-2 proposal, in ISAKMP format +- [RFC2408], listing in decreasing order of preference the security +- proposals acceptable to protect traffic sent and received by the +- Portal. This field is used only if bits 31, 30, and 29 of the +- +- Security Bitmap (see 6.3.9) are enabled. This attribute contains the +- SA payload, proposal payload(s), and associated transform payload(s) +- in the ISAKMP format defined in [RFC2408]. +- +-6.3.12. Portal Certificate +- +- This attribute contains one or more X.509 certificates that are a +- credential of the Portal. This certificate is used to identify and +- authenticate communications to the IP address and TCP/UDP Port +- supported by the Portal. The format of the X.509 certificate is +- specified in [RFC3280]. This certificate MUST contain a Subject Name +- with an empty sequence and MUST contain a SubjectAltName extension +- encoded with the iPAddress type. The Portal IP Address (Section +- 6.3.1) of the identified Portal SHALL be stored in the SubjectAltName +- field of the certificate. +- +-6.4. iSCSI Node-Keyed Attributes +- +- The following attributes are stored in the iSNS database using the +- iSCSI Name attribute as the key. Each set of Node-Keyed attributes +- is associated with one Entity Identifier object key. +- +- Although the iSCSI Name key is associated with one Entity Identifier, +- it is unique across the entire iSNS database. +- +- +- +-Tseng, et al. Standards Track [Page 84] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +-6.4.1. iSCSI Name +- +- This is a variable-length UTF-8 encoded NULL-terminated text-based +- description of up to 224 bytes. This key attribute is required for +- iSCSI Storage Nodes and is provided by the iSNS client. The +- registered iSCSI Name MUST conform to the format described in [iSCSI] +- for iSCSI Names. The maximum size for an iSCSI Name is 223 bytes. +- Including the NULL character and 4-byte alignment (see Section +- 5.3.1), the maximum iSCSI Name field size is 224 bytes. +- +- If an iSCSI Name is registered without an EID key, then a Network +- Entity SHALL be created and an EID assigned. The assigned EID SHALL +- be returned in the registration response as an operating attribute. +- +- This field MUST be normalized according to the stringprep template +- [STRINGPREP] before it is stored in the iSNS database. +- +-6.4.2. iSCSI Node Type +- +- This required 32-bit field is a bitmap indicating the type of iSCSI +- Storage Node. The bit positions are defined below. A set bit (1) +- indicates that the Node has the corresponding characteristics. +- +- Bit Position Node Type +- ------------ --------- +- 29 Control +- 30 Initiator +- 31 (Lsb) Target +- All others RESERVED +- +- If the Target bit is set to 1, then the Node represents an iSCSI +- target. The Target bit MAY be set by iSNS clients using the iSNSP. +- +- If the Initiator bit is set to 1, then the Node represents an iSCSI +- initiator. The Initiator bit MAY be set by iSNS clients using the +- iSNSP. +- +- If the control bit is set to 1, then the Node represents a gateway, a +- management station, a backup iSNS server, or another device that is +- not an initiator or target, but that requires the ability to send and +- receive iSNSP messages, including state change notifications. +- Setting the control bit is an administrative task that MUST be +- performed on the iSNS server; iSNS clients SHALL NOT be allowed to +- change this bit using the iSNSP. +- +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 85] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- This field MAY be used by the iSNS server to distinguish among +- permissions by different iSCSI Node types for accessing various iSNS +- functions. More than one Node Type bit may be simultaneously +- enabled. +- +-6.4.3. iSCSI Node Alias +- +- This is a variable-length UTF-8 encoded NULL-terminated text-based +- description of up to 256 bytes. The Alias is a user-readable +- description of the Node entry in the iSNS database. +- +-6.4.4. iSCSI Node SCN Bitmap +- +- The iSCSI Node SCN Bitmap indicates events for which the registering +- iSNS client wishes to receive a notification message. The following +- table displays events that result in notifications, and the bit field +- in the SCN Bitmap that, when enabled, results in the corresponding +- notification. +- +- Note that this field is of dual use: it is used in the SCN +- registration process to define interested events that will trigger an +- SCN message, and it is also contained in each SCN message itself, to +- indicate the type of event that triggered the SCN message. A set bit +- (1) indicates the corresponding type of SCN. +- +- Bit Position Flag Description +- ------------ ---------------- +- 24 INITIATOR AND SELF INFORMATION ONLY +- 25 TARGET AND SELF INFORMATION ONLY +- 26 MANAGEMENT REGISTRATION/SCN +- 27 OBJECT REMOVED +- 28 OBJECT ADDED +- 29 OBJECT UPDATED +- 30 DD/DDS MEMBER REMOVED (Mgmt Reg/SCN only) +- 31 (Lsb) DD/DDS MEMBER ADDED (Mgmt Reg/SCN only) +- All others RESERVED +- +- DD/DDS MEMBER REMOVED indicates that an existing member of a +- Discovery Domain and/or Discovery Domain Set has been removed. +- +- DD/DDS MEMBER ADDED indicates that a new member was added to an +- existing DD and/or DDS. +- +- OBJECT REMOVED, OBJECT ADDED, and OBJECT UPDATED indicate a Network +- Entity, Portal, Storage Node, FC Device, DD, and/or DDS object was +- removed from, added to, or updated in the Discovery Domain or in the +- iSNS database (Control Nodes only). +- +- +- +- +-Tseng, et al. Standards Track [Page 86] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- Regular SCNs provide information about objects that are updated in, +- added to or removed from Discovery Domains of which the Storage Node +- is a member. An SCN or SCN registration is considered a regular SCN +- or regular SCN registration if the MANAGEMENT REGISTRATION/SCN flag +- is cleared. All iSNS clients may register for regular SCNs. +- +- Management SCNs provide information about all changes to the network, +- regardless of discovery domain membership. Registration for +- management SCNs is indicated by setting bit 26 to 1. Only Control +- Nodes may register for management SCNs. Bits 30 and 31 may only be +- enabled if bit 26 is set to 1. +- +- TARGET AND SELF INFORMATION ONLY SCNs (bit 25) provides information +- only about changes to target devices, or if the iSCSI Storage Node +- itself has undergone a change. Similarly, INITIATOR AND SELF +- INFORMATION ONLY SCNs (bit 24) provides information only about +- changes to initiator Nodes, or to the target itself. +- +-6.4.5. iSCSI Node Index +- +- The iSCSI Node Index is a 4-byte non-zero integer value used as a key +- that uniquely identifies each iSCSI Storage Node registered in the +- iSNS database. Upon initial registration of the iSCSI Storage Node, +- the iSNS server assigns an unused value for the iSCSI Node Index. +- Each iSCSI Node MUST be assigned a value for the iSCSI Node Index +- that is not assigned to any other iSCSI Storage Node. Furthermore, +- iSCSI Node Index values for recently deregistered iSCSI Storage Nodes +- SHOULD NOT be reused in the short term. +- +- The iSCSI Node Index may be used as a key to represent a registered +- Node in situations where the iSCSI Name is too long to be used as a +- key. An example of this is when SNMP is used for management, as +- described in Section 2.10. +- +- The value assigned for the iSCSI Node Index SHALL persist as long as +- the iSCSI Storage Node is registered in the iSNS database or a member +- of a Discovery Domain. An iSCSI Node Index value that is assigned +- for a Storage Node SHALL NOT be used for any other Storage Node as +- long as the original node is registered in the iSNS database or a +- member of a Discovery Domain. +- +-6.4.6. WWNN Token +- +- This field contains a globally unique 64-bit integer value that can +- be used to represent the World Wide Node Name of the iSCSI device in +- a Fibre Channel fabric. This identifier is used during the device +- registration process and MUST conform to the requirements in [FC-FS]. +- +- +- +- +-Tseng, et al. Standards Track [Page 87] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- The FC-iSCSI gateway uses the value found in this field to register +- the iSCSI device in the Fibre Channel name server. It is stored in +- the iSNS server to prevent conflict when "proxy" WWNN values are +- assigned to iSCSI initiators establishing storage sessions to devices +- in the FC fabric. +- +- If the iSNS client does not assign a value for WWNN Token, then the +- iSNS server SHALL provide a value for this field upon initial +- registration of the iSCSI Storage Node. The process by which the +- WWNN Token is assigned by the iSNS server MUST conform to the +- following requirements: +- +- 1. The assigned WWNN Token value MUST be unique among all WWN +- entries in the existing iSNS database, and among all devices that +- can potentially be registered in the iSNS database. +- +- 2. Once the value is assigned, the iSNS server MUST persistently +- save the mapping between the WWNN Token value and registered +- iSCSI Name. That is, successive re-registrations of the iSCSI +- Storage Node keyed by the same iSCSI Name maintain the original +- mapping to the associated WWNN Token value in the iSNS server. +- Similarly, the mapping SHALL be persistent across iSNS server +- reboots. Once assigned, the mapping can only be changed if a +- DevAttrReg message from an authorized iSNS client explicitly +- provides a different WWNN Token value. +- +- 3. Once a WWNN Token value has been assigned and mapped to an iSCSI +- name, that WWNN Token value SHALL NOT be reused or mapped to any +- other iSCSI name. +- +- 4. The assigned WWNN Token value MUST conform to the formatting +- requirements of [FC-FS] for World Wide Names (WWNs). +- +- An iSNS client, such as an FC-iSCSI gateway or the iSCSI initiator, +- MAY register its own WWNN Token value or overwrite the iSNS Server- +- supplied WWNN Token value, if it wishes to supply its own iSCSI-FC +- name mapping. This is accomplished using the DevAttrReg message with +- the WWNN Token (tag=37) as an operating attribute. Once overwritten, +- the new WWNN Token value MUST be stored and saved by the iSNS server, +- and all requirements specified above continue to apply. If an iSNS +- client attempts to register a value for this field that is not unique +- in the iSNS database or that is otherwise invalid, then the +- registration SHALL be rejected with an Status Code of 3 (Invalid +- Registration). +- +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 88] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- There MAY be matching records in the iSNS database for the Fibre +- Channel device specified by the WWNN Token. These records may +- contain device attributes for that FC device registered in the Fibre +- Channel fabric name server. +- +-6.4.7. iSCSI Node Next Index +- +- This is a virtual attribute containing a 4-byte integer value that +- indicates the next available (i.e., unused) iSCSI Node Index value. +- This attribute may only be queried; the iSNS server SHALL return an +- error code of 3 (Invalid Registration) to any client that attempts to +- register a value for this attribute. A Message Key is not required +- when exclusively querying for this attribute. +- +- The iSCSI Node Next Index MAY be used by an SNMP client to create an +- entry in the iSNS server. SNMP requirements are described in Section +- 2.10. +- +-6.4.8. iSCSI AuthMethod +- +- This attribute contains a NULL-terminated string of UTF-8 text +- listing the iSCSI authentication methods enabled for this iSCSI +- Storage Node, in order of preference. The text values used to +- identify iSCSI authentication methods are embedded in this string +- attribute and delineated by a comma. The text values are identical +- to those found in the main iSCSI document [iSCSI]; additional +- vendor-specific text values are also possible. +- +- Text Value Description Reference +- ---------- ----------- --------- +- KB5 Kerberos V5 [RFC1510] +- SPKM1 Simple Public Key GSS-API [RFC2025] +- SPKM2 Simple Public Key GSS-API [RFC2025] +- SRP Secure Remote Password [RFC2945] +- CHAP Challenge Handshake Protocol [RFC1994] +- none No iSCSI Authentication +- +-6.5. Portal Group (PG) Object-Keyed Attributes +- +- The following attributes are used to associate Portal and iSCSI +- Storage Node objects. PG objects are stored in the iSNS database +- using the PG iSCSI Name, the PG Portal IP Address, and the PG Portal +- TCP/UDP Port as keys. New PG objects are implicitly or explicitly +- created at the time that the corresponding Portal and/or iSCSI +- Storage Node objects are registered. Section 3.4 has a general +- discussion of PG usage. For further details on use of Portal Groups, +- see [iSCSI]. +- +- +- +- +-Tseng, et al. Standards Track [Page 89] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +-6.5.1. Portal Group iSCSI Name +- +- This is the iSCSI Name for the iSCSI Storage Node that is associated +- with the PG object. This name MAY represent an iSCSI Storage Node +- not currently registered in the server. +- +-6.5.2. PG Portal IP Addr +- +- This is the Portal IP Address attribute for the Portal that is +- associated with the PG object. This Portal IP Address MAY be that of +- a Portal that is not currently registered in the server. +- +-6.5.3. PG Portal TCP/UDP Port +- +- This is the Portal TCP/UDP Port attribute for the Portal that is +- associated with the PG object. This Portal TCP/UDP Port MAY be that +- of a Portal that is not currently registered in the server. +- +-6.5.4. Portal Group Tag (PGT) +- +- This field is used to group Portals in order to coordinate +- connections in a session across Portals to a specified iSCSI Node. +- The PGT is a value in the range of 0-65535, or NULL. A NULL PGT +- value is registered by using 0 for the length in the TLV during +- registration. The two least significant bytes of the value contain +- the PGT for the object. The two most significant bytes are reserved. +- If a PGT value is not explicitly registered for an iSCSI Storage Node +- and Portal pair, then the PGT value SHALL be implicitly registered as +- 0x00000001. +- +-6.5.5. Portal Group Index +- +- The PG Index is a 4-byte non-zero integer value used as a key that +- uniquely identifies each PG object registered in the iSNS database. +- Upon initial registration of a PG object, the iSNS server MUST assign +- an unused value for the PG Index. Furthermore, PG Index values for +- recently deregistered PG objects SHOULD NOT be reused in the short +- term. +- +- The PG Index MAY be used as the key to reference a registered PG in +- situations where a unique index for each PG object is required. It +- MAY also be used as the message key in an iSNS message to query or +- update a pre-existing PG object. An example of this is when SNMP is +- used for management, as described in Section 2.10. The value +- assigned for the PG Index SHALL persist as long as the server is +- active. +- +- +- +- +- +-Tseng, et al. Standards Track [Page 90] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +-6.5.6. Portal Group Next Index +- +- The PG Next Index is a virtual attribute containing a 4-byte integer +- value that indicates the next available (i.e., unused) PG Index +- value. This attribute may only be queried; the iSNS server SHALL +- return an error code of 3 (Invalid Registration) to any client that +- attempts to register a value for this attribute. A Message Key is +- not required when exclusively querying for this attribute. +- +- The Portal Group Next Index MAY be used by an SNMP client to create +- an entry in the iSNS server. SNMP requirements are described in +- Section 2.10. +- +-6.6. FC Port Name-Keyed Attributes +- +- The following attributes are registered in the iSNS database using +- the FC Port World Wide Name (WWPN) attribute as the key. Each set of +- FC Port-Keyed attributes is associated with one Entity Identifier +- object key. +- +- Although the FC Port World Wide Name is associated with one Entity +- Identifier, it is also globally unique. +- +-6.6.1. FC Port Name (WWPN) +- +- This 64-bit identifier uniquely defines the FC Port, and it is the +- World Wide Port Name (WWPN) of the corresponding Fibre Channel +- device. This attribute is the key for the iFCP Storage Node. This +- globally unique identifier is used during the device registration +- process, and it uses a value conforming to IEEE EUI-64 [EUI-64]. +- +-6.6.2. Port ID (FC_ID) +- +- The Port Identifier is a Fibre Channel address identifier assigned to +- an N_Port or NL_Port during fabric login. The format of the Port +- Identifier is defined in [FC-FS]. The least significant 3 bytes +- contain this address identifier. The most significant byte is +- RESERVED. +- +- +- +- +- +- +- +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 91] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +-6.6.3. FC Port Type +- +- Indicates the type of FC port. Encoded values for this field are +- listed in the following table: +- +- Type Description +- ---- ----------- +- 0x0000 Unidentified/Null Entry +- 0x0001 Fibre Channel N_Port +- 0x0002 Fibre Channel NL_Port +- 0x0003 Fibre Channel F/NL_Port +- 0x0004-0080 RESERVED +- 0x0081 Fibre Channel F_Port +- 0x0082 Fibre Channel FL_Port +- 0x0083 RESERVED +- 0x0084 Fibre Channel E_Port +- 0x0085-00FF RESERVED +- 0xFF11 RESERVED +- 0xFF12 iFCP Port +- 0xFF13-FFFF RESERVED +- +-6.6.4. Symbolic Port Name +- +- This is a variable-length UTF-8 encoded NULL-terminated text-based +- description of up to 256 bytes that is associated with the iSNS- +- registered FC Port Name in the network. +- +-6.6.5. Fabric Port Name (FWWN) +- +- This 64-bit identifier uniquely defines the fabric port. If the port +- of the FC Device is attached to a Fibre Channel fabric port with a +- registered Port Name, then that fabric Port Name SHALL be indicated +- in this field. +- +-6.6.6. Hard Address +- +- This field is the requested hard address 24-bit NL Port Identifier, +- included in the iSNSP for compatibility with Fibre Channel Arbitrated +- Loop devices and topologies. The least significant 3 bytes of this +- field contain the address. The most significant byte is RESERVED. +- +-6.6.7. Port IP Address +- +- The Fibre Channel IP address associated with the FC Port. When this +- field contains an IPv4 value, it is stored as an IPv4-mapped IPv6 +- address. That is, the most significant 10 bytes are set to 0x00, +- with the next two bytes set to 0xFFFF [RFC2373]. When an IPv6 value +- is contained in this field, then the entire 16-byte field is used. +- +- +- +-Tseng, et al. Standards Track [Page 92] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +-6.6.8. Class of Service (COS) +- +- This 32-bit bit-map field indicates the Fibre Channel Class of +- Service types that are supported by the registered port. In the +- following table, a set bit (1) indicates a Class of Service +- supported. +- +- Bit Position Description +- ------------ ----------- +- 29 Fibre Channel Class 2 Supported +- 28 Fibre Channel Class 3 Supported +- +-6.6.9. FC-4 Types +- +- This 32-byte field indicates the FC-4 protocol types supported by the +- associated port. This field can be used to support Fibre Channel +- devices and is consistent with FC-GS-4. +- +-6.6.10. FC-4 Descriptor +- +- This is a variable-length UTF-8 encoded NULL-terminated text-based +- description of up to 256 bytes that is associated with the iSNS- +- registered device port in the network. This field can be used to +- support Fibre Channel devices and is consistent with FC-GS-4. +- +-6.6.11. FC-4 Features +- +- This is a 128-byte array, 4 bits per type, for the FC-4 protocol +- types supported by the associated port. This field can be used to +- support Fibre Channel devices and is consistent with FC-GS-4. +- +-6.6.12. iFCP SCN Bitmap +- +- This field indicates the events the iSNS client is interested in. +- These events can cause SCNs to be generated. SCNs provide +- information about objects that are updated in, added to or removed +- from Discovery Domains of which the source and destination are a +- member. Management SCNs provide information about all changes to the +- network. A set bit (1) indicates the type of SCN for the bitmap as +- follows: +- +- +- +- +- +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 93] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- Bit Position Flag Description +- ------------ ---------------- +- 24 INITIATOR AND SELF INFORMATION ONLY +- 25 TARGET AND SELF INFORMATION ONLY +- 26 MANAGEMENT REGISTRATION/SCN +- 27 OBJECT REMOVED +- 28 OBJECT ADDED +- 29 OBJECT UPDATED +- 30 DD/DDS MEMBER REMOVED (Mgmt Reg/SCN only) +- 31 (Lsb) DD/DDS MEMBER ADDED (Mgmt Reg/SCN only) +- All others RESERVED +- +- Further information on the use of the bit positions specified above +- can be found in Section 6.4.4. +- +-6.6.13. Port Role +- +- This required 32-bit field is a bitmap indicating the type of iFCP +- Storage Node. The bit fields are defined below. A set bit indicates +- the Node has the corresponding characteristics. +- +- Bit Position Node Type +- ------------ --------- +- 29 Control +- 30 FCP Initiator +- 31 (Lsb) FCP Target +- All Others RESERVED +- +- If the 'Target' bit is set to 1, then the port represents an FC +- target. Setting of the 'Target' bit MAY be performed by iSNS clients +- using the iSNSP. +- +- If the 'Initiator' bit is set to 1, then the port represents an FC +- initiator. Setting of the 'Initiator' bit MAY be performed by iSNS +- clients using the iSNSP. +- +- If the 'Control' bit is set to 1, then the port represents a gateway, +- a management station, an iSNS backup server, or another device. +- +- This is usually a special device that is neither an initiator nor a +- target, which requires the ability to send and receive iSNSP +- messages, including state-change notifications. Setting the control +- bit is an administrative task that MUST be administratively +- configured on the iSNS server; iSNS clients SHALL NOT be allowed to +- change this bit using the iSNSP. +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 94] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- This field MAY be used by the iSNS server to distinguish among +- permissions by different iSNS clients. For example, an iSNS server +- implementation may be administratively configured to allow only +- targets to receive ESIs, or to permit only Control Nodes to add, +- modify, or delete discovery domains. +- +-6.6.14. Permanent Port Name (PPN) +- +- The Permanent Port Name can be used to support Fibre Channel devices +- and is consistent with the PPN description in FC-GS-4 [FC-GS-4]. The +- format of the PPN is identical to the FC Port Name WWPN attribute +- format. +- +-6.7. Node-Keyed Attributes +- +- The following attributes are registered in the iSNS database using +- the FC Node Name (WWNN) attribute as the key. Each set of FC Node- +- Keyed attributes represents a single device and can be associated +- with many FC Ports. +- +- The FC Node Name is unique across the entire iSNS database. +- +-6.7.1. FC Node Name (WWNN) +- +- The FC Node Name is a 64-bit identifier that is the World Wide Node +- Name (WWNN) of the corresponding Fibre Channel device. This +- attribute is the key for the FC Device. This globally unique +- identifier is used during the device registration process, and it +- uses a value conforming to IEEE EUI-64 [EUI-64]. +- +-6.7.2. Symbolic Node Name +- +- This is a variable-length UTF-8 encoded NULL-terminated text-based +- description of up to 256 bytes that is associated with the iSNS- +- registered FC Device in the network. +- +-6.7.3. Node IP Address +- +- This IP address is associated with the device Node in the network. +- This field is included for compatibility with Fibre Channel. When +- this field contains an IPv4 value, it is stored as an IPv4-mapped +- IPv6 address. That is, the most significant 10 bytes are set to +- 0x00, with the next two bytes set to 0xFFFF [RFC2373]. When an IPv6 +- value is contained in this field, the entire 16-byte field is used. +- +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 95] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +-6.7.4. Node IPA +- +- This field is the 8-byte Fibre Channel Initial Process Associator +- (IPA) associated with the device Node in the network. The initial +- process associator is used for communication between Fibre Channel +- devices. +- +-6.7.5. Proxy iSCSI Name +- +- This is a variable-length UTF-8 encoded NULL-terminated text-based +- field that contains the iSCSI Name used to represent the FC Node in +- the IP network. It is used as a pointer to the matching iSCSI Name +- entry in the iSNS server. Its value is usually registered by an FC- +- iSCSI gateway connecting the IP network to the fabric containing the +- FC device. +- +- Note that if this field is used, there SHOULD be a matching entry in +- the iSNS database for the iSCSI device specified by the iSCSI name. +- The database entry should include the full range of iSCSI attributes +- needed for discovery and management of the "iSCSI proxy image" of the +- FC device. +- +-6.8. Other Attributes +- +- The following are not attributes of the previously-defined objects. +- +-6.8.1. FC-4 Type Code +- +- This is a 4-byte field used to provide a FC-4 type during a FC-4 Type +- query. The FC-4 types are consistent with the FC-4 Types as defined +- in FC-FS. Byte 0 contains the FC-4 type. All other bytes are +- reserved. +- +-6.8.2. iFCP Switch Name +- +- The iFCP Switch Name is a 64-bit World Wide Name (WWN) identifier +- that uniquely identifies a distinct iFCP gateway in the network. +- This globally unique identifier is used during the switch +- registration/FC_DOMAIN_ID assignment process. The iFCP Switch Name +- value used MUST conform to the requirements stated in [FC-FS] for +- World Wide Names. The iSNS server SHALL track the state of all +- FC_DOMAIN_ID values that have been allocated to each iFCP Switch +- Name. If a given iFCP Switch Name is deregistered from the iSNS +- database, then all FC_DOMAIN_ID values allocated to that iFCP Switch +- Name SHALL be returned to the unused pool of values. +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 96] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +-6.8.3. iFCP Transparent Mode Commands +- +-6.8.3.1. Preferred ID +- +- This is a 4-byte unsigned integer field, and it is the requested +- value that the iSNS client wishes to use for the FC_DOMAIN_ID. The +- iSNS server SHALL grant the iSNS client the use of the requested +- value as the FC_DOMAIN_ID, if the requested value has not already +- been allocated. If the requested value is not available, the iSNS +- server SHALL return a different value that has not been allocated. +- +-6.8.3.2. Assigned ID +- +- This is a 4-byte unsigned integer field that is used by an iFCP +- gateway to reserve its own unique FC_DOMAIN_ID value from the range 1 +- to 239. When a FC_DOMAIN_ID is no longer required, it SHALL be +- released by the iFCP gateway using the RlseDomId message. The iSNS +- server MUST use the Entity Status Inquiry message to determine +- whether an iFCP gateway is still present on the network. +- +-6.8.3.3. Virtual_Fabric_ID +- +- This is a variable-length UTF-8 encoded NULL-terminated text-based +- field of up to 256 bytes. The Virtual_Fabric_ID string is used as a +- key attribute to identify a range of non-overlapping FC_DOMAIN_ID +- values to be allocated using RqstDomId. Each Virtual_Fabric_ID +- string submitted by an iSNS client SHALL have its own range of non- +- overlapping FC_DOMAIN_ID values to be allocated to iSNS clients. +- +- +-6.9. iSNS Server-Specific Attributes +- +- Access to the following attributes may be administratively +- controlled. These attributes are specific to the iSNS server +- instance; the same value is returned for all iSNS clients accessing +- the iSNS server. Only query messages may be performed on these +- attributes. Attempted registrations of values for these attributes +- SHALL return a status code of 3 (Invalid Registration). +- +- A query for an iSNS Server-Specific attribute MUST contain the +- identifying key attribute (i.e., iSCSI Name or FC Port Name WWPN) of +- the Node originating the registration or query message as the Source +- and Message Key attributes. The Operating Attributes are the +- server-specific attributes being registered or queried. +- +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 97] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +-6.9.1. iSNS Server Vendor OUI +- +- This attribute is the OUI (Organizationally Unique Identifier) +- [802-1990] identifying the specific vendor implementing the iSNS +- server. This attribute can only be queried; iSNS clients SHALL NOT be +- allowed to register a value for the iSNS Server Vendor OUI. +- +-6.10. Vendor-Specific Attributes +- +- iSNS server implementations MAY define vendor-specific attributes for +- private use. These attributes MAY be used to store optional data +- that is registered and/or queried by iSNS clients in order to gain +- optional capabilities. Note that any implementation of vendor- +- specific attributes in the iSNS server SHALL NOT impose any form of +- mandatory behavior on the part of the iSNS client. +- +- The tag values used for vendor-specific and user-specific use are +- defined in Section 6.1. To avoid misinterpreting proprietary +- attributes, the vendor's own OUI (Organizationally Unique Identifier) +- MUST be placed in the upper three bytes of the attribute value field +- itself. +- +- The OUI is defined in IEEE Std 802-1990 and is the same constant used +- to generate 48 bit Universal LAN MAC addresses. A vendor's own iSNS +- implementation will then be able to recognize the OUI in the +- attribute field and be able to execute vendor-specific handling of +- the attribute. +- +-6.10.1. Vendor-Specific Server Attributes +- +- Attributes with tags in the range 257 to 384 are vendor-specific or +- site-specific attributes of the iSNS server. Values for these +- attributes are administratively set by the specific vendor providing +- the iSNS server implementation. Query access to these attributes may +- be administratively controlled. These attributes are unique for each +- logical iSNS server instance. Query messages for these attributes +- SHALL use the key identifier (i.e., iSCSI Name or FC Port Name WWPN) +- for both the Source attribute and Message Key attribute. These +- attributes can only be queried; iSNS clients SHALL NOT be allowed to +- register a value for server attributes. +- +-6.10.2. Vendor-Specific Entity Attributes +- +- Attributes in the range 385 to 512 are vendor-specific or site- +- specific attributes used to describe the Network Entity object. +- These attributes are keyed by the Entity Identifier attribute +- (tag=1). +- +- +- +- +-Tseng, et al. Standards Track [Page 98] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +-6.10.3. Vendor-Specific Portal Attributes +- +- Attributes in the range 513 to 640 are vendor-specific or site- +- specific attributes used to describe the Portal object. These +- attributes are keyed by the Portal IP-Address (tag=16) and Portal +- TCP/UDP Port (tag=17). +- +-6.10.4. Vendor-Specific iSCSI Node Attributes +- +- Attributes in the range 641 to 768 are vendor-specific or site- +- specific attributes used to describe the iSCSI Node object. These +- attributes are keyed by the iSCSI Name (tag=32). +- +-6.10.5. Vendor-Specific FC Port Name Attributes +- +- Attributes in the range 769 to 896 are vendor-specific or site- +- specific attributes used to describe the N_Port Port Name object. +- These attributes are keyed by the FC Port Name WWPN (tag=64). +- +-6.10.6. Vendor-Specific FC Node Name Attributes +- +- Attributes in the range 897 to 1024 are vendor-specific or site- +- specific attributes used to describe the FC Node Name object. These +- attributes are keyed by the FC Node Name WWNN (tag=96). +- +-6.10.7. Vendor-Specific Discovery Domain Attributes +- +- Attributes in the range 1025 to 1280 are vendor-specific or site- +- specific attributes used to describe the Discovery Domain object. +- These attributes are keyed by the DD_ID (tag=104). +- +-6.10.8. Vendor-Specific Discovery Domain Set Attributes +- +- Attributes in the range 1281 to 1536 are vendor-specific or site- +- specific attributes used to describe the Discovery Domain Set object. +- These attributes are keyed by the DD Set ID (tag=101) +- +-6.10.9. Other Vendor-Specific Attributes +- +- Attributes in the range 1537 to 2048 can be used for key and non-key +- attributes that describe new vendor-specific objects specific to the +- vendor's iSNS server implementation. +- +- +- +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 99] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +-6.11. Discovery Domain Registration Attributes +- +-6.11.1. DD Set ID Keyed Attributes +- +-6.11.1.1. Discovery Domain Set ID (DDS ID) +- +- The DDS ID is an unsigned non-zero integer identifier used in the +- iSNS directory database as a key to indicate a Discovery Domain Set +- uniquely. A DDS is a collection of Discovery Domains that can be +- enabled or disabled by a management station. This value is used as a +- key for DDS attribute queries. When a Discovery Domain is +- registered, it is initially not in any DDS. +- +- If the iSNS client does not provide a DDS_ID in a DDS registration +- request message, the iSNS server SHALL generate a DDS_ID value that +- is unique within the iSNS database for that new DDS. The created DDS +- ID SHALL be returned in the response message. The DDS ID value of 0 +- is reserved, and the DDS ID value of 1 is used for the default DDS +- (see Section 2.2.2). +- +-6.11.1.2. Discovery Domain Set Symbolic Name +- +- A variable-length UTF-8 encoded NULL-terminated text-based field of +- up to 256 bytes. This is a user-readable field used to assist a +- network administrator in tracking the DDS function. When a client +- registers a DDS symbolic name, the iSNS server SHALL verify it is +- unique. If the name is not unique, then the DDS registration SHALL +- be rejected with an "Invalid Registration" Status Code. The invalid +- attribute(s), in this case the DDS symbolic name, SHALL be included +- in the response. +- +-6.11.1.3. Discovery Domain Set Status +- +- The DDS_Status field is a 32-bit bitmap indicating the status of the +- DDS. Bit 0 of the bitmap indicates whether the DDS is Enabled (1) or +- Disabled (0). The default value for the DDS Enabled flag is Disabled +- (0). +- +- Bit Position DDS Status +- ------------ --------- +- 31 (Lsb) DDS Enabled (1) / DDS Disabled (0) +- All others RESERVED +- +-6.11.1.4. Discovery Domain Set Next ID +- +- This is a virtual attribute containing a 4-byte integer value that +- indicates the next available (i.e., unused) Discovery Domain Set +- Index value. This attribute may only be queried; the iSNS server +- +- +- +-Tseng, et al. Standards Track [Page 100] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- SHALL return an error code of 3 (Invalid Registration) to any client +- that attempts to register a value for this attribute. A Message Key +- is not required when exclusively querying for this attribute. +- +- The Discovery Domain Set Next Index MAY be used by an SNMP client to +- create an entry in the iSNS server. SNMP requirements are described +- in Section 2.10. +- +-6.11.2. DD ID Keyed Attributes +- +-6.11.2.1. Discovery Domain ID (DD ID) +- +- The DD ID is an unsigned non-zero integer identifier used in the iSNS +- directory database as a key to identify a Discovery Domain uniquely. +- This value is used as the key for any DD attribute query. If the +- iSNS client does not provide a DD_ID in a DD registration request +- message, the iSNS server SHALL generate a DD_ID value that is unique +- within the iSNS database for that new DD (i.e., the iSNS client will +- be registered in a new DD). The created DD ID SHALL be returned in +- the response message. The DD ID value of 0 is reserved, and the DD +- ID value of 1 is used for the default DD (see Section 2.2.2). +- +-6.11.2.2. Discovery Domain Symbolic Name +- +- A variable-length UTF-8 encoded NULL-terminated text-based field of +- up to 256 bytes. When a client registers a DD symbolic name, the +- iSNS server SHALL verify it is unique. If the name is not unique, +- then the DD registration SHALL be rejected with an "Invalid +- Registration" Status Code. The invalid attribute(s), in this case +- the DD symbolic name, SHALL be included in the response. +- +-6.11.2.3. Discovery Domain Member: iSCSI Node Index +- +- This is the iSCSI Node Index of a Storage Node that is a member of +- the DD. The DD may have a list of 0 to n members. The iSCSI Node +- Index is one alternative representation of membership in a Discovery +- Domain, the other alternative being the iSCSI Name. The Discovery +- Domain iSCSI Node Index is a 4-byte non-zero integer value. +- +- The iSCSI Node Index can be used to represent a DD member in +- situations where the iSCSI Name is too long to be used. An example +- of this is when SNMP is used for management, as described in Section +- 2.10. +- +- The iSCSI Node Index and the iSCSI Name stored as a member in a DD +- SHALL be consistent with the iSCSI Node Index and iSCSI Name +- attributes registered for the Storage Node object in the iSNS server. +- +- +- +- +-Tseng, et al. Standards Track [Page 101] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +-6.11.2.4. Discovery Domain Member: iSCSI Name +- +- A variable-length UTF-8 encoded NULL-terminated text-based field of +- up to 224 bytes. It indicates membership for the specified iSCSI +- Storage Node in the Discovery Domain. Note that the referenced +- Storage Node does not need to be actively registered in the iSNS +- database before the iSNS client uses this attribute. There is no +- limit to the number of members that may be in a DD. Membership is +- represented by the iSCSI Name of the iSCSI Storage Node. +- +-6.11.2.5. Discovery Domain Member: FC Port Name +- +- This 64-bit identifier attribute indicates membership for an iFCP +- Storage Node (FC Port) in the Discovery Domain. Note that the +- referenced Storage Node does not need to be actively registered in +- the iSNS database before the iSNS client uses this attribute. There +- is no limit to the number of members that may be in a DD. Membership +- is represented by the FC Port Name (WWPN) of the iFCP Storage Node. +- +-6.11.2.6. Discovery Domain Member: Portal Index +- +- This attribute indicates membership in the Discovery Domain for a +- Portal. It is an alternative representation for Portal membership to +- the Portal IP Address and Portal TCP/UDP Port. The referenced Portal +- MUST be actively registered in the iSNS database before the iSNS +- client uses this attribute. +- +-6.11.2.7. Discovery Domain Member: Portal IP Address +- +- This attribute and the Portal TCP/UDP Port attribute indicate +- membership in the Discovery Domain for the specified Portal. Note +- that the referenced Portal does not need to be actively registered in +- the iSNS database before the iSNS client uses this attribute. +- +-6.11.2.8. Discovery Domain Member: Portal TCP/UDP Port +- +- This attribute and the Portal IP Address attribute indicate +- membership in the Discovery Domain for the specified Portal. Note +- that the referenced Portal does not need to be actively registered in +- the iSNS database before the iSNS client uses this attribute. +- +-6.11.2.9. Discovery Domain Features +- +- The Discovery Domain Features is a bitmap indicating the features of +- this DD. The bit positions are defined below. A bit set to 1 +- indicates the DD has the corresponding characteristics. +- +- +- +- +- +-Tseng, et al. Standards Track [Page 102] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- Bit Position DD Feature +- ------------ ---------- +- 31 (Lsb) Boot List Enabled (1)/Boot List Disabled (0) +- All others RESERVED +- +- Boot List: this feature indicates that the target(s) in this DD +- provides boot capabilities for the member initiators, as described in +- [iSCSI-boot]. +- +-6.11.2.10. Discovery Domain Next ID +- +- This is a virtual attribute containing a 4-byte integer value that +- indicates the next available (i.e., unused) Discovery Domain Index +- value. This attribute may only be queried; the iSNS server SHALL +- return an error code of 3 (Invalid Registration) to any client that +- attempts to register a value for this attribute. A Message Key is +- not required when exclusively querying for this attribute. +- +-7. Security Considerations +- +-7.1. iSNS Security Threat Analysis +- +- When the iSNS protocol is deployed, the interaction between iSNS +- server and iSNS clients is subject to the following security threats: +- +- a) An attacker could alter iSNS protocol messages, such as to direct +- iSCSI and iFCP devices to establish connections with rogue peer +- devices, or to weaken/eliminate IPSec protection for iSCSI or +- iFCP traffic. +- +- b) An attacker could masquerade as the real iSNS server using false +- iSNS heartbeat messages. This could cause iSCSI and iFCP devices +- to use rogue iSNS servers. +- +- c) An attacker could gain knowledge about iSCSI and iFCP devices by +- snooping iSNS protocol messages. Such information could aid an +- attacker in mounting a direct attack on iSCSI and iFCP devices, +- such as a denial-of-service attack or outright physical theft. +- +- To address these threats, the following capabilities are needed: +- +- a) Unicast iSNS protocol messages may need to be authenticated. In +- addition, to protect against threat c), confidentiality support +- is desirable and is REQUIRED when certain functions of iSNS +- server are utilized. +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 103] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- b) Multicast iSNS protocol messages such as the iSNS heartbeat +- message may need to be authenticated. These messages need not be +- confidential since they do not leak critical information. +- +-7.2. iSNS Security Implementation and Usage Requirements +- +- If the iSNS server is used to distribute authorizations for +- communications between iFCP and iSCSI peer devices, IPsec ESP with +- null transform MUST be implemented, and non-null transform MAY be +- implemented. If a non-null transform is implemented, then the DES +- encryption algorithm SHOULD NOT be used. +- +- If the iSNS server is used to distribute security policy for iFCP and +- iSCSI devices, then authentication, data integrity, and +- confidentiality MUST be supported and used. Where confidentiality is +- desired or required, IPSec ESP with non-null transform SHOULD be +- used, and the DES encryption algorithm SHOULD NOT be used. +- +- If the iSNS server is used to provide the boot list for clients, as +- described in Section 6.11.2.9, then the iSCSI boot client SHOULD +- implement a secure iSNS connection. +- +- In order to protect against an attacker masquerading as an iSNS +- server, client devices MUST support the ability to authenticate +- broadcast or multicast messages such as the iSNS heartbeat. The iSNS +- authentication block (which is identical in format to the SLP +- authentication block) SHALL be used for this purpose. iSNS clients +- MUST implement the iSNS authentication block and MUST support BSD +- value 0x002. If the iSNS server supports broadcast or multicast iSNS +- messages (i.e., the heartbeat), then the server MUST implement the +- iSNS authentication block and MUST support BSD value 0x002. Note +- that the authentication block is used only for iSNS broadcast or +- multicast messages and MUST NOT be used in unicast iSNS messages. +- +- There is no requirement that the communicating identities in iSNS +- protocol messages be kept confidential. Specifically, the identity +- and location of the iSNS server is not considered confidential. +- +- For protecting unicast iSNS protocol messages, iSNS servers +- supporting security MUST implement ESP in tunnel mode and MAY +- implement transport mode. +- +- All iSNS implementations supporting security MUST support the replay +- protection mechanisms of IPsec. +- +- iSNS security implementations MUST support both IKE Main Mode and +- Aggressive Mode for authentication, negotiation of security +- associations, and key management, using the IPSec DOI [RFC2407]. +- +- +- +-Tseng, et al. Standards Track [Page 104] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- Manual keying SHOULD NOT be used since it does not provide the +- necessary rekeying support. Conforming iSNS security implementations +- MUST support authentication using a pre-shared key, and MAY support +- certificate-based peer authentication using digital signatures. Peer +- authentication using the public key encryption methods outlined in +- IKEs Sections 5.2 and 5.3 [RFC2409] SHOULD NOT be supported. +- +- Conforming iSNS implementations MUST support both IKE Main Mode and +- Aggressive Mode. IKE Main Mode with pre-shared key authentication +- SHOULD NOT be used when either of the peers use dynamically assigned +- IP addresses. Although Main Mode with pre-shared key authentication +- offers good security in many cases, situations where dynamically +- assigned addresses are used force the use of a group pre-shared key, +- which is vulnerable to man-in-the-middle attack. IKE Identity +- Payload ID_KEY_ID MUST NOT be used. +- +- When digital signatures are used for authentication, either IKE Main +- Mode or IKE Aggressive Mode MAY be used. In all cases, access to +- locally stored secret information (pre-shared key or private key for +- digital signing) MUST be suitably restricted, since compromise of the +- secret information nullifies the security properties of the IKE/IPsec +- protocols. +- +- When digital signatures are used to achieve authentication, an IKE +- negotiator SHOULD use IKE Certificate Request Payload(s) to specify +- the certificate authority (or authorities) that are trusted in +- accordance with its local policy. IKE negotiators SHOULD check the +- pertinent Certificate Revocation List (CRL) before accepting a PKI +- certificate for use in IKE's authentication procedures. +- +- When the iSNS server is used without security, IP block storage +- protocol implementations MUST support a negative cache for +- authentication failures. This allows implementations to avoid +- continually contacting discovered endpoints that fail authentication +- within IPsec or at the application layer (in the case of iSCSI +- Login). The negative cache need not be maintained within the IPsec +- implementation, but rather within the IP block storage protocol +- implementation. +- +-7.3. Discovering Security Requirements of Peer Devices +- +- Once communication between iSNS clients and the iSNS server has been +- secured through use of IPSec, the iSNS client devices have the +- capability to discover the security settings that they need to use +- for their peer-to-peer communications using the iSCSI and/or iFCP +- protocols. This provides a potential scaling advantage over device- +- by-device configuration of individual security policies for each +- iSCSI and iFCP device. +- +- +- +-Tseng, et al. Standards Track [Page 105] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- The iSNS server stores security settings for each iSCSI and iFCP +- device interface. These security settings, which can be retrieved by +- authorized hosts, include use or non-use of IPSec, IKE, Main Mode, +- and Aggressive Mode. For example, IKE may not be enabled for a +- particular interface of a peer device. If a peer device can learn of +- this in advance by consulting the iSNS server, it will not need to +- waste time and resources attempting to initiate an IKE phase 1 +- session with that peer device interface. +- +- If iSNS is used for this purpose, then the minimum information that +- should be learned from the iSNS server is the use or non-use of IKE +- and IPSec by each iFCP or iSCSI peer device interface. This +- information is encoded in the Security Bitmap field of each Portal of +- the peer device, and is applicable on a per-interface basis for the +- peer device. iSNS queries for acquiring security configuration data +- about peer devices MUST be protected by IPSec/ESP authentication. +- +-7.4. Configuring Security Policies of iFCP/iSCSI Devices +- +- Use of iSNS for distribution of security policies offers the +- potential to reduce the burden of manual device configuration, and to +- decrease the probability of communications failures due to +- incompatible security policies. If iSNS is used to distribute +- security policies, then IPSec authentication, data integrity, and +- confidentiality MUST be used to protect all iSNS protocol messages. +- +- The complete IKE/IPSec configuration of each iFCP and/or iSCSI device +- can be stored in the iSNS server, including policies that are used +- for IKE Phase 1 and Phase 2 negotiations between client devices. The +- IKE payload format includes a series of one or more proposals that +- the iSCSI or iFCP device will use when negotiating the appropriate +- IPsec policy to use to protect iSCSI or iFCP traffic. +- +- In addition, the iSCSI Authentication Methods used by each iSCSI +- device can also be stored in the iSNS server. The iSCSI AuthMethod +- field (tag=42) contains a null-terminated string embedded with the +- text values indicating iSCSI authentication methods to be used by +- that iSCSI device. +- +- Note that iSNS distribution of security policy is not necessary if +- the security settings can be determined by other means, such as +- manual configuration or IPsec security policy distribution. If a +- network entity has already obtained its security configuration via +- other mechanisms, then it MUST NOT request security policy via iSNS. +- +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 106] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +-7.5. Resource Issues +- +- The iSNS protocol is lightweight and will not generate a significant +- amount of traffic. iSNS traffic is characterized by occasional +- registration, notification, and update messages that do not consume +- significant amounts of bandwidth. Even software-based IPSec +- implementations should not have a problem handling the traffic loads +- generated by the iSNS protocol. +- +- To fulfill iSNS security requirements, the only additional resources +- needed beyond what is already required for iSCSI and iFCP involve the +- iSNS server. Because iSCSI and iFCP end nodes are already required +- to implement IKE and IPSec, these existing requirements can also be +- used to fulfill IKE and IPSec requirements for iSNS clients. +- +-7.6. iSNS Interaction with IKE and IPSec +- +- When IPSec security is enabled, each iSNS client with at least one +- Storage Node that is registered in the iSNS database SHALL maintain +- at least one phase-1 security association with the iSNS server. All +- iSNS protocol messages between iSNS clients and the iSNS server SHALL +- be protected by a phase-2 security association. +- +- When a Network Entity is removed from the iSNS database, the iSNS +- server SHALL send a phase-1 delete message to the associated iSNS +- client IKE peer, and tear down all phase-1 and phase-2 SAs associated +- with that iSNS client. +- +-8. IANA Considerations +- +- The well-known TCP and UDP port number for iSNS is 3205. +- +- The standards action of this RFC creates two registries to be +- maintained by IANA in support of iSNSP and assigns initial values for +- both registries. The first registry is of Block Storage Protocols +- supported by iSNS. The second registry is a detailed registry of +- standard iSNS attributes that can be registered to and queried from +- the iSNS server. Note that this RFC uses the registry created for +- Block Structure Descriptor (BSD) in Section 15 of Service Location +- Protocol, Version 2 [RFC2608]. +- +-8.1. Registry of Block Storage Protocols +- +- In order to maintain a registry of block storage protocols supported +- by iSNSP, IANA will assign a 32-bit unsigned integer number for each +- block storage protocol supported by iSNS. This number is stored in +- the iSNS database as the Entity Protocol. The initial set of values +- to be maintained by IANA for Entity Protocol is indicated in the +- +- +- +-Tseng, et al. Standards Track [Page 107] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- table in Section 6.2.2. Additional values for new block storage +- protocols to be supported by iSNS SHALL be assigned by the IPS WG +- Chairperson, or by a Designated Expert [RFC2434] appointed by the +- IETF Transport Area Director. +- +-8.2. Registry of Standard iSNS Attributes +- +- IANA is responsible for creating and maintaining the Registry of +- Standard iSNS Attributes. The initial list of iSNS attributes is +- described in Section 6. For each iSNS attribute this information +- MUST include, its tag value, the attribute length, and the tag values +- for the set of permissible registration and query keys that can be +- used for that attribute. The initial list of iSNS attributes to be +- maintained by IANA is indicated in Section 6.1. +- +- Additions of new standard attributes to the Registry of Standard iSNS +- Attributes SHALL require IETF Consensus [RFC2434]. The RFC required +- for this process SHALL specify use of tag values reserved for IANA +- allocation in Section 6.1. The RFC SHALL specify as a minimum, the +- new attribute tag value, attribute length, and the set of permissible +- registration and query keys that can be used for the new attribute. +- The RFC SHALL also include a discussion of the reasons for the new +- attribute(s) and how the new attribute(s) are to be used. +- +- As part of the process of obtaining IETF Consensus, the proposed RFC +- and its supporting documentation SHALL be made available to the IPS +- WG mailing list or, if the IPS WG is disbanded at the time, to a +- mailing list designated by the IETF Transport Area Director. The +- review and comment period SHALL last at least three months before the +- IPS WG Chair or a person designated by the IETF Transport Area +- Director decides either to reject the proposal or to forward the +- draft to the IESG for publication as an RFC. When the specification +- is published as an RFC, then IANA will register the new iSNS +- attribute(s) and make the registration available to the community. +- +-8.3. Block Structure Descriptor (BSD) Registry +- +- Note that IANA is already responsible for assigning and maintaining +- values used for the Block Structure Descriptor for the iSNS +- Authentication Block (see Section 5.5). Section 15 of [RFC2608] +- describes the process for allocation of new BSD values. +- +- +- +- +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 108] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +-9. Normative References +- +- [iSCSI] Satran, J., Meth, K., Sapuntzakis, C., Chadalapaka, M., +- and E. Zeidner, "Internet Small Computer Systems +- Interface (iSCSI)", RFC 3720, April 2004. +- +- [iFCP] Monia, C., Mullendore, R., Travostino, F., Jeong, W., +- and M. Edwards, "iFCP - A Protocol for Internet Fibre +- Channel Storage Networking", RFC 4172, September 2005. +- +- [iSNSOption] Monia, C., Tseng, J., and K. Gibbons, The IPv4 Dynamic +- Host Configuration Protocol (DHCP) Option for the +- Internet Storage Name Service, RFC 4174, September 2005. +- +- [RFC2608] Guttman, E., Perkins, C., Veizades, J., and M. Day, +- "Service Location Protocol, Version 2 ", RFC 2608, June +- 1999. +- +- [iSCSI-SLP] Bakke, M., Hufferd, J., Voruganti, K., Krueger, M., and +- T. Sperry, "Finding Internet Small Computer Systems +- Interface (iSCSI) Targets and Name Servers by Using +- Service Location Protocol version 2 (SLP), RFC 4018, +- April 2005. +- +- [iSCSI-boot] Sarkar, P., Missimer, D., and C. Sapuntzakis, +- "Bootstrapping Clients using the Internet Samll Computer +- System Interface (iSCSI) Protocol", RFC 4173, September +- 2005. +- +- [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate +- Requirement Levels", BCP 14, RFC 2119, March 1997. +- +- [STRINGPREP] Bakke, M., "String Profile for Internet Small Computer +- Systems Interface (iSCSI) Names", RFC 3722, April 2004. +- +- [NAMEPREP] Hoffman, P. Nameprep: A Stringprep Profile for +- Internationalized Domain Names, July 2002. +- +- [RFC2407] Piper, D., "The Internet IP Security Domain of +- Interpretation for ISAKMP", RFC 2407, November 1998. +- +- [RFC2408] Maughan, D., Schertler, M., Schneider, M., and J. +- Turner, "Internet Security Association and Key +- Management Protocol (ISAKMP)", RFC 2408, November 1998. +- +- [RFC2409] Harkins, D. and D. Carrel, "The Internet Key Exchange +- (IKE)", RFC 2409, November 1998. +- +- +- +- +-Tseng, et al. Standards Track [Page 109] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- [EUI-64] Guidelines for 64-bit Global Identifier (EUI-64) +- Registration Authority, May 2001, IEEE +- +- [RFC3279] Bassham, L., Polk, W., and R. Housley, "Algorithms and +- Identifiers for the Internet X.509 Public Key +- Infrastructure Certificate and Certificate Revocation +- List (CRL) Profile", RFC 3279, April 2002. +- +- [RFC3280] Housley, R., Polk, W., Ford, W., and D. Solo, "Internet +- X.509 Public Key Infrastructure Certificate and +- Certificate Revocation List (CRL) Profile", RFC 3280, +- April 2002. +- +- [802-1990] IEEE Standards for Local and Metropolitan Area Networks: +- Overview and Architecture, Technical Committee on +- Computer Communications of the IEEE Computer Society, +- May 31, 1990 +- +- [FC-FS] Fibre Channel Framing and Signaling Interface, NCITS +- Working Draft Project 1331-D +- +-10. Informative References +- +- [iSNSMIB] Gibbons, K., et al., "Definitions of Managed Objects for +- iSNS (Internet Storage name Service)", Work in Progress, +- July 2003. +- +- [X.509] ITU-T Recommendation X.509 (1997 E): Information +- Technology - Open Systems Interconnection - The +- Directory: Authentication Framework, June 1997 +- +- [FC-GS-4] Fibre Channel Generic Services-4 (work in progress), +- NCITS Working Draft Project 1505-D +- +- [RFC1510] Kohl, J. and C. Neuman, "The Kerberos Network +- Authentication Service (V5)", RFC 1510, September 1993. +- +- [RFC2025] Adams, C., "The Simple Public-Key GSS-API Mechanism +- (SPKM)", RFC 2025, October 1996. +- +- [RFC2434] Narten, T. and H. Alvestrand, "Guidelines for Writing an +- IANA Considerations Section in RFCs", BCP 26, RFC 2434, +- October 1998. +- +- [RFC2945] Wu, T., "The SRP Authentication and Key Exchange +- System", RFC 2945, September 2000. +- +- +- +- +- +-Tseng, et al. Standards Track [Page 110] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- [RFC1994] Simpson, W., "PPP Challenge Handshake Authentication +- Protocol (CHAP)", RFC 1994, August 1996. +- +- [RFC2131] Droms, R., "Dynamic Host Configuration Protocol", RFC +- 2131, March 1997. +- +- [RFC3410] Case, J., Mundy, R., Partain, D., and B. Stewart, +- "Introduction and Applicability Statements for +- Internet-Standard Management Framework", RFC 3410, +- December 2002. +- +- [RFC3411] Harrington, D., Presuhn, R., and B. Wijnen, "An +- Architecture for Describing Simple Network Management +- Protocol (SNMP) Management Frameworks", STD 62, RFC +- 3411, December 2002. +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 111] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +-Appendix A: iSNS Examples +- +-A.1. iSCSI Initialization Example +- +- This example assumes an SLP Service Agent (SA) has been implemented +- on the iSNS host, and an SLP User Agent (UA) has been implemented on +- the iSNS initiator. See [RFC2608] for further details on SAs and +- UAs. This example also assumes that the target is configured to use +- the iSNS server, and have its access control policy subordinated to +- the iSNS server. +- +-A.1.1. Simple iSCSI Target Registration +- +- In this example, a simple target with a single iSCSI name registers +- with the iSNS server. The target is represented in the iSNS by an +- Entity containing one Storage Node, one Portal, and an implicitly +- registered Portal Group that provides a relationship between the +- Storage Node and Portal. The target has not been assigned a Fully +- Qualified Domain Name (FQDN) by the administrator. In this example, +- because a PG object is not explicitly registered, a Portal Group with +- a PGT of 1 is implicitly registered. In this example SLP is used to +- discover the location of the iSNS Server. An alternative is to use +- the iSNS DHCP option [iSNSOption] to discover the iSNS server. +- +- +--------------------------+------------------+-------------------+ +- | iSCSI Target Device | iSNS Server |Management Station | +- +--------------------------+------------------+-------------------+ +- |Discover iSNS--SLP------->| |/*mgmt station is | +- | |<--SLP--iSNS Here:| administratively | +- | | 192.0.2.100 | authorized to view| +- | | | all DDs. Device | +- | DevAttrReg--------->| | NAMEabcd was | +- |Src:(tag=32) "NAMEabcd" | | previously placed | +- |Key: | | into DDabcd along | +- |Oper Attrs: | | with devpdq and | +- |tag=1: NULL | | devrst. | +- |tag=2: "iSCSI" | | | +- |tag=16: 192.0.2.5 | | | +- |tag=17: 5001 | | | +- |tag=32: "NAMEabcd" | | | +- |tag=33: target | | | +- |tag=34: "disk 1" | | | +- | |<---DevAttrRegRsp | | +- | |SUCCESS | | +- | |Key:(tag=1) "isns:0001" | +- | |Oper Attrs: | | +- | |tag=1: "isns:0001"| | +- | |tag=2: "iSCSI" | | +- +- +- +-Tseng, et al. Standards Track [Page 112] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- | |tag=16: 192.0.2.5 | | +- | |tag=17: 5001 | | +- | |tag=32: "NAMEabcd"|/* previously | +- | |tag=33: target | placed in a DD */ | +- | |tag=34: "disk 1" | | +- | | | | +- | | SCN-------->| | +- | |(or SNMP notification) | +- | |dest:(tag=32):"MGMTname1" | +- | |time:(tag=4): | +- | |tag=35: "MGT-SCN, OBJ-ADD" | +- | |tag=32: "NAMEabcd"| | +- | | |<-------SCNRsp | +- | DevAttrQry--------->| | | +- |Src:(tag=32) "NAMEabcd" | | | +- |Key:(tag=33) "initiator" | | | +- |Oper Attrs: | | | +- |tag=16: NULL | | | +- |tag=17: NULL | | | +- |tag=32: NULL | | | +- |/*Query asks for all initr| | | +- |devices' IP address, port |<---DevAttrQryRsp | | +- |number, and Name*/ |SUCCESS | | +- | |tag=16:192.0.2.1 | | +- | |tag=17:50000 | | +- | |tag=32:"devpdq" | | +- | |tag=16:192.0.2.2 | | +- | |tag=17:50000 | | +- | |tag=32:"devrst" | | +- |/*************************| |<-----DevAttrQry | +- |Our target "NAMEabcd" | |src: "MGMTname1" | +- |discovers two initiators | key:(tag=32)"NAMEabcd" +- |in shared DDs. It will | |Op Attrs: | +- |accept iSCSI logins from | |tag=16: NULL | +- |these two identified | |tag=17: NULL | +- |initiators presented by | |tag=32: NULL | +- |iSNS | | | +- |*************************/| DevAttrQryRsp--->| | +- | |SUCCESS | | +- | |tag=16: 192.0.2.5 | | +- | |tag=17: 5001 | | +- | |tag=32: "NAMEabcd"| | +- +--------------------------+------------------+-------------------+ +- +- +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 113] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +-A.1.2. Target Registration and DD Configuration +- +- In this example, a more complex target, with two Storage Nodes and +- two Portals using ESI monitoring, registers with the iSNS. This +- target has been configured with a Fully Qualified Domain Name (FQDN) +- in the DNS servers, and the user wishes to use this identifier for +- the device. The target explicitly registers Portal Groups to +- describe how each Portal provides access to each Storage Node. One +- target Storage Node allows coordinated access through both Portals. +- The other Storage Node allows access, but not coordinated access, +- through both Portals. +- +- +--------------------------+------------------+-------------------+ +- | iSCSI Target Device | iSNS Server |Management Station | +- +--------------------------+------------------+-------------------+ +- |Discover iSNS--SLP--> | |/*mgmt station is | +- | |<--SLP--iSNS Here:| administratively | +- | | 192.0.2.100 | authorized to view| +- | DevAttrReg--> | | all DDs */ | +- |Src: | | | +- |tag=32: "NAMEabcd" | | | +- |Msg Key: | | | +- |tag=1: "jbod1.example.com"| | | +- |Oper Attrs: | | | +- |tag=1: "jbod1.example.com"| | | +- |tag=2: "iSCSI" | | | +- |tag=16: 192.0.2.4 | | | +- |tag=17: 5001 | | | +- |tag=19: 5 | | | +- |tag=20: 5002 | | | +- |tag=16: 192.0.2.5 | | | +- |tag=17: 5001 | | | +- |tag=19: 5 | | | +- |tag=20: 5002 | | | +- |tag=32: "NAMEabcd" | | | +- |tag=33: "Target" | | | +- |tag=34: "Storage Array 1" | | | +- |tag=51: 10 | | | +- |tag=49: 192.0.2.4 | | | +- |tag=50: 5001 | | | +- |tag=49: 192.0.2.5 | | | +- |tag=50: 5001 | | | +- |tag=32: "NAMEefgh" | | | +- |tag=33: "Target" | | | +- |tag=34: "Storage Array 2" |/*****************| | +- |tag=51: 20 |jbod1.example.com is | +- |tag=49: 192.0.2.4 |now registered in | | +- |tag=50: 5001 |iSNS, but is not | | +- +- +- +-Tseng, et al. Standards Track [Page 114] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- |tag=51: 30 |in any DD. Therefore, | +- |tag=49: 192.0.2.5 |no other devices | | +- |tag=50: 5001 |can "see" it. | | +- | |*****************/| | +- | |<--DevAttrRegRsp | | +- | |SUCCESS | | +- | |Msg Key: | | +- | |tag=1: "jbod1.example.com" | +- | |Oper Attrs: | | +- | |tag=1: "jbod1.example.com" | +- | |tag=2: "iSCSI" | | +- | |tag=16: 192.0.2.4 | | +- | |tag=17: 5001 | | +- | |tag=19: 5 | | +- | |tag=20: 5002 | | +- | |tag=16: 192.0.2.5 | | +- | |tag=17: 5001 | | +- | |tag=19: 5 | | +- | |tag=20: 5002 | | +- | |tag=32: "NAMEabcd"| | +- | |tag=33: "Target" | | +- | |tag=34: "Storage Array 1" | +- | |tag=48: "NAMEabcd"| | +- | |tag=49: 192.0.2.4 | | +- | |tag=50: 5001 | | +- | |tag=51: 10 | | +- | |tag=48: "NAMEabcd"| | +- | |tag=49: 192.0.2.5 | | +- | |tag=50: 5001 | | +- | |tag=51: 10 | | +- | |tag=32: "NAMEefgh"| | +- | |tag=33: "Target" | | +- | |tag=34: "Storage Array 2" | +- | |tag=43: X.509 cert| | +- | |tag=48: "NAMEefgh"| | +- | |tag=49: 192.0.2.4 | | +- | |tag=50: 5001 | | +- | |tag=51: 20 | | +- | |tag=48: "NAMEefgh"| | +- | |tag=49: 192.0.2.5 | | +- | |tag=50: 5001 | | +- | |tag=51: 30 | | +- | | | | +- | | SCN------> | | +- | | (or SNMP notification) | +- | |dest:(tag=32)"mgmt.example.com" | +- | |time:(tag=4): | +- | |tag=35: "MGT-SCN, OBJ-ADD" | +- +- +- +-Tseng, et al. Standards Track [Page 115] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- | |tag=32: "NAMEabcd"| | +- | |tag=35: "MGT-SCN, OBJ-ADD" | +- | |tag=32: "NAMEefgh"| | +- | | |<--SCNRsp | +- | | |SUCCESS | +- | | tag=32:"mgmt.example.com"| +- | | | | +- | | |<--DevAttrQry | +- | | |Src: | +- | | tag=32:"mgmt.example.com" +- | | |Msg Key: | +- | | |tag=32: "NAMEabcd" | +- | | |Oper Attrs: | +- | | |tag=16: <0-length> | +- | | |tag=17: <0-length> | +- | | |tag=32: <0-length> | +- | | | | +- | | DevAttrQryRsp--> | | +- | |SUCCESS | | +- | |Msg Key: | | +- | |tag=32: "NAMEabcd"| | +- | |Oper Attrs: | | +- | |tag=16: 192.0.2.4 | | +- | |tag=17: 5001 | | +- | |tag=32:"NAMEabcd" | | +- | |tag=16: 192.0.2.5 | | +- | |tag=17: 5001 | | +- | |tag=32:"NAMEabcd" | | +- | | |Src: | +- | | tag=32:"mgmt.example.com" +- | | |Msg Key: | +- | | |tag=32: "NAMEefgh" | +- | | |Oper Attrs: | +- | | |tag=16: <0-length> | +- | | |tag=17: <0-length> | +- | | |tag=32: <0-length> | +- | | | | +- | | DevAttrQryRsp--> | | +- | |SUCCESS | | +- | |Msg Key: | | +- | |tag=32: "NAMEefgh"| | +- | |Oper Attrs: | | +- | |tag=16: 192.0.2.4 | | +- | |tag=17: 5001 | | +- | |tag=32:"NAMEefgh" | | +- | |tag=16: 192.0.2.5 |/**Mgmt Station ***| +- | |tag=17: 5001 |displays device, | +- | |tag=32:"NAMEefgh" |the operator decides +- +- +- +-Tseng, et al. Standards Track [Page 116] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- | | |to place "NAMEabcd"| +- | | |into Domain "DDxyz"| +- |/*************************| |******************/| +- |Target is now registered | | | +- |in iSNS. It is then placed| |<--DDReg | +- |in a pre-existing DD with | |Src: | +- |DD_ID 123 by a management | tag=32:"mgmt.example.com" +- |station. | |Msg Key: | +- |*************************/| |tag=2065: 123 | +- | | |Oper Attrs: | +- | | |tag=2068: "NAMEabcd" +- | | DDRegRsp-----> | | +- | |SUCCESS | | +- | |Msg Key: | | +- | |tag=2065: 123 | | +- | |Oper Attrs: | | +- | |tag=2065: 123 | | +- +--------------------------+------------------+-------------------+ +- +-A.1.3. Initiator Registration and Target Discovery +- +- The following example illustrates a new initiator registering with +- the iSNS, and discovering the target NAMEabcd from the example in +- A.1.2. +- +- +--------------------------+------------------+-------------------+ +- | iSCSI Initiator | iSNS |Management Station | +- +--------------------------+------------------+-------------------+ +- |Discover iSNS--SLP--> | |/*mgmt station is | +- | |<--SLP--iSNS Here:| administratively | +- | | 192.36.53.1 | authorized to view| +- |DevAttrReg--> | | all DDs ********/ | +- |Src: | | | +- |tag=32: "NAMEijkl" | | | +- |Msg Key: | | | +- |tag=1: "svr1.example.com" | | | +- |Oper Attrs: | | | +- |tag=1: "svr1.example.com" | | | +- |tag=2: "iSCSI" | | | +- |tag=16: 192.20.3.1 |/*****************| | +- |tag=17: 5001 |Device not in any | | +- |tag=19: 5 |DD, so it is | | +- |tag=20: 5002 |inaccessible by | | +- |tag=32: "NAMEijkl" |other devices | | +- |tag=33: "Initiator" |*****************/| | +- |tag=34: "Server1" | | | +- |tag=51: 11 | | | +- |tag=49: 192.20.3.1 | | | +- +- +- +-Tseng, et al. Standards Track [Page 117] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- |tag=50: 5001 | | | +- | |<--DevAttrRegRsp | | +- | |SUCCESS | | +- | |Msg Key: | | +- | |tag=1: "svr1.example.com" | +- | |Oper Attrs: | | +- | |tag=1: "svr1.example.com" | +- | |tag=2: "iSCSI" | | +- | |tag=16: 192.20.3.1| | +- | |tag=17: 5001 | | +- | |tag=19: 5 | | +- | |tag=20: 5002 | | +- | |tag=32: "NAMEijkl"| | +- | |tag=33: "Initiator" | +- | |tag=34: "Server1" | | +- | |tag=48: "NAMEijkl"| | +- | |tag=49: 192.20.3.1| | +- | |tag=50: 5001 | | +- | |tag=51: 11 | | +- | | | | +- | | SCN------> | | +- | | (or SNMP notification) | +- | |dest:(tag=32)"mgmt.example.com" | +- | |time:(tag=4): | +- | |tag=35: "MGT-SCN, OBJ-ADD" | +- | |tag=32: "NAMEijkl"| | +- | | | | +- | | |<------SCNRsp | +- | | |SUCCESS | +- | | tag=32:"mgmt.example.com" +- | | | | +- |SCNReg--> | | | +- |Src: | | | +- |tag=32: "NAMEijkl" | | | +- |Msg Key: | | | +- |tag=32: "NAMEijkl" | | | +- |Oper Attrs: | | | +- |tag=35: | | +- | |<--SCNRegRsp | | +- | |SUCCESS | | +- | | | | +- | | |<----DevAttrQry | +- | | |Src: | +- | | tag=32:"mgmt.example.com" +- | | |Msg Key: | +- | | |tag=32: "NAMEijkl" | +- | | |Oper Attrs: | +- | | |tag=16: <0-length> | +- +- +- +-Tseng, et al. Standards Track [Page 118] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- | | |tag=17: <0-length> | +- | | |tag=32: <0-length> | +- | | DevAttrQryRsp--->| | +- | |SUCCESS | | +- | |Msg Key: | | +- | |tag=32: "NAMEijkl"| | +- | |Oper Attrs: | | +- | |tag=16:192.20.3.1 | | +- | |tag=17: 5001 | | +- | |tag=32:"NAMEijkl" | | +- | | |/**Mgmt Station ***| +- | | |displays device, the +- | | |operator decides to| +- | | |place "NAMEijkl" into +- | | |pre-existing Disc | +- | | |Domain "DDxyz" with| +- | | |device NAMEabcd | +- | | |******************/| +- | | |<--DDReg | +- | | |Src: | +- | | tag=32:"mgmt.example.com" +- | | |Msg Key: | +- | | |tag=2065: 123 | +- | | |Oper Attrs: | +- | | |tag=2068: "NAMEijkl" +- | | | | +- | | DDRegRsp---->| | +- | |SUCCESS | | +- | |Msg Key: | | +- | |tag=2065: 123 | | +- | |Oper Attrs: | | +- | |tag=2065: 123 |/******************| +- | | |"NAMEijkl" has been| +- | | |moved to "DDxyz" | +- | | |******************/| +- | | SCN------>| | +- | |dest:(tag=32)"mgmt.example.com" | +- | |time:(tag=4): | +- | |tag=35: | +- | |tag=2065: 123 | | +- | |tag=2068: "NAMEijkl" | +- | | | | +- | | |<------SCNRsp | +- | | |SUCCESS | +- | | tag=32:"mgmt.example.com" +- | |<-----SCN | | +- | |dest:(tag=32)"NAMEijkl" | +- | |time:(tag=4): | +- +- +- +-Tseng, et al. Standards Track [Page 119] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- | |tag=35: | +- | |tag=32: "NAMEijkl"| | +- | SCNRsp------> | | | +- |SUCCESS | | | +- |tag=32:"NAMEijkl" | | | +- | | | | +- | |/*****************| | +- | |Note that NAMEabcd| | +- | |also receives an | | +- | |SCN that NAMEijkl | | +- | |is in the same DD | | +- | |*****************/| | +- | (to "NAMEabcd")|<-----SCN | | +- | |dest:(tag=32)"NAMEabcd" | +- | |time:(tag=4): | +- | |tag=35: | +- | |tag=32: "NAMEijkl"| | +- | SCNRsp------> | | | +- |SUCCESS | | | +- |tag=32:"NAMEabcd" | | | +- | | | | +- | DevAttrQry----------->| | | +- |Src: | | | +- |tag=32: "NAMEijkl" | | | +- |Msg Key: | | | +- |tag=33: "Target" | | | +- |Oper Attrs: | | | +- |tag=16: <0-length> | | | +- |tag=17: <0-length> | | | +- |tag=32: <0-length> | | | +- |tag=34: <0-length> | | | +- |tag=43: <0-length> | | | +- |tag=48: <0-length> | | | +- |tag=49: <0-length> | | | +- |tag=50: <0-length> | | | +- |tag=51: <0-length> | | | +- | |<--DevAttrQryRsp | | +- | |SUCCESS | | +- | |Msg Key: | | +- | |tag=33:"Target" | | +- | |Oper Attrs: | | +- | |tag=16: 192.0.2.4 | | +- | |tag=17: 5001 | | +- | |tag=32: "NAMEabcd"| | +- | |tag=34: "Storage Array 1" | +- | |tag=16: 192.0.2.5 | | +- | |tag=17: 5001 | | +- | |tag=32: "NAMEabcd"| | +- +- +- +-Tseng, et al. Standards Track [Page 120] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +- | |tag=34: "Storage Array 1" | +- | |tag=43: X.509 cert| | +- | |tag=48: "NAMEabcd"| | +- | |tag=49: 192.0.2.4 | | +- | |tag=50: 5001 | | +- | |tag=51: 10 | | +- | |tag=48: "NAMEabcd"| | +- | |tag=49: 192.0.2.5 | | +- | |tag=50: 5001 | | +- | |tag=51: 10 | | +- | | | | +- |/***The initiator has discovered | | +- |the target, and has everything | | +- |needed to complete iSCSI login | | +- |The same process occurs on the | | +- |target side; the SCN prompts the | | +- |target to download the list of | | +- |authorized initiators from the | | +- |iSNS (i.e., those initiators in the | | +- |same DD as the target.************/ | | +- +--------------------------+------------------+-------------------+ +- +-Acknowledgements +- +- Numerous individuals contributed to the creation of this document +- through their careful review and submissions of comments and +- recommendations. We acknowledge the following persons for their +- technical contributions to this document: Mark Bakke (Cisco), John +- Hufferd (IBM), Julian Satran (IBM), Kaladhar Voruganti(IBM), Joe Czap +- (IBM), John Dowdy (IBM), Tom McSweeney (IBM), Jim Hafner (IBM), Chad +- Gregory (Intel), Yaron Klein (Sanrad), Larry Lamers (Adaptec), Jack +- Harwood (EMC), David Black (EMC), David Robinson (Sun), Alan Warwick +- (Microsoft), Bob Snead (Microsoft), Fa Yoeu (Intransa), Joe White +- (McDATA), Charles Monia (McDATA), Larry Hofer (McDATA), Ken Hirata +- (Vixel), Howard Hall (Pirus), Malikarjun Chadalapaka (HP), Marjorie +- Krueger (HP), Siva Vaddepuri (McDATA), and Vinai Singh (American +- Megatrends). +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 121] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +-Authors' Addresses +- +- Josh Tseng +- Riverbed Technology +- 501 2nd Street, Suite 410 +- San Francisco, CA 94107 +- +- Phone: (650)274-2109 +- EMail: joshtseng@yahoo.com +- +- +- Kevin Gibbons +- McDATA Corporation +- 4555 Great America Parkway +- Santa Clara, CA 95054-1208 +- +- Phone: (408) 567-5765 +- EMail: kevin.gibbons@mcdata.com +- +- +- Franco Travostino +- Nortel +- 600 Technology Park Drive +- Billerica, MA 01821 USA +- +- Phone: (978) 288-7708 +- EMail: travos@nortel.com +- +- +- Curt du Laney +- Rincon Research Corporation +- 101 North Wilmot Road, Suite 101 +- Tucson AZ 85711 +- +- Phone: (520) 519-4409 +- EMail: cdl@rincon.com +- +- +- Joe Souza +- Microsoft Corporation +- One Microsoft Way +- Redmond, WA 98052-6399 +- +- Phone: (425) 706-3135 +- EMail: joes@exmsft.com +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 122] +- +-RFC 4171 Internet Storage Name Service (iSNS) September 2005 +- +- +-Full Copyright Statement +- +- Copyright (C) The Internet Society (2005). +- +- This document is subject to the rights, licenses and restrictions +- contained in BCP 78, and except as set forth therein, the authors +- retain all their rights. +- +- This document and the information contained herein are provided on an +- "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS +- OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET +- ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, +- INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE +- INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED +- WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +- +-Intellectual Property +- +- The IETF takes no position regarding the validity or scope of any +- Intellectual Property Rights or other rights that might be claimed to +- pertain to the implementation or use of the technology described in +- this document or the extent to which any license under such rights +- might or might not be available; nor does it represent that it has +- made any independent effort to identify any such rights. Information +- on the procedures with respect to rights in RFC documents can be +- found in BCP 78 and BCP 79. +- +- Copies of IPR disclosures made to the IETF Secretariat and any +- assurances of licenses to be made available, or the result of an +- attempt made to obtain a general license or permission for the use of +- such proprietary rights by implementers or users of this +- specification can be obtained from the IETF on-line IPR repository at +- http://www.ietf.org/ipr. +- +- The IETF invites any interested party to bring to its attention any +- copyrights, patents or patent applications, or other proprietary +- rights that may cover technology that may be required to implement +- this standard. Please address the information to the IETF at ietf- +- ipr@ietf.org. +- +-Acknowledgement +- +- Funding for the RFC Editor function is currently provided by the +- Internet Society. +- +- +- +- +- +- +- +-Tseng, et al. Standards Track [Page 123] +- +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/open-isns/Makefile.in open-iscsi-2.0-872-rc4-bnx2i.work/utils/open-isns/Makefile.in --- open-iscsi-2.0-872-rc4-bnx2i/utils/open-isns/Makefile.in 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/utils/open-isns/Makefile.in 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/utils/open-isns/Makefile.in 2012-03-05 23:02:46.000000000 -0600 @@ -32,7 +32,6 @@ LIBOBJS = server.o \ security.o \ authblock.o \ @@ -16482,9 +44449,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/open-isns/Makefile.in open-iscsi- register.o \ query.o \ getnext.o \ -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/open-isns/objects.h open-iscsi-2.0-872-rc4-bnx2i.sync/utils/open-isns/objects.h +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/open-isns/objects.h open-iscsi-2.0-872-rc4-bnx2i.work/utils/open-isns/objects.h --- open-iscsi-2.0-872-rc4-bnx2i/utils/open-isns/objects.h 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/utils/open-isns/objects.h 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/utils/open-isns/objects.h 2012-03-05 23:02:46.000000000 -0600 @@ -83,6 +83,7 @@ struct isns_object { isns_attr_list_t ie_attrs; @@ -16493,9 +44460,31 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/open-isns/objects.h open-iscsi-2. isns_object_template_t *ie_template; isns_relation_t * ie_relation; -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/open-isns/socket.c open-iscsi-2.0-872-rc4-bnx2i.sync/utils/open-isns/socket.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/open-isns/security.h open-iscsi-2.0-872-rc4-bnx2i.work/utils/open-isns/security.h +--- open-iscsi-2.0-872-rc4-bnx2i/utils/open-isns/security.h 2010-07-11 04:05:58.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/utils/open-isns/security.h 2012-03-05 23:03:38.000000000 -0600 +@@ -6,11 +6,16 @@ + + #ifndef ISNS_SECURITY_H + #define ISNS_SECURITY_H +- +-#include + #include "buffer.h" + #include "util.h" + ++ ++#ifdef WITH_SECURITY ++#include ++#else ++#define EVP_PKEY void ++#endif ++ + /* + * Security context + */ +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/open-isns/socket.c open-iscsi-2.0-872-rc4-bnx2i.work/utils/open-isns/socket.c --- open-iscsi-2.0-872-rc4-bnx2i/utils/open-isns/socket.c 2010-07-11 04:05:58.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.sync/utils/open-isns/socket.c 2011-08-14 16:48:25.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/utils/open-isns/socket.c 2012-03-05 23:02:46.000000000 -0600 @@ -562,7 +562,7 @@ void isns_net_stream_accept(isns_socket_t *sock) { @@ -16514,3 +44503,14 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/open-isns/socket.c open-iscsi-2.0 /* POLLHUP while connecting means we failed */ if (sock->is_state == ISNS_SOCK_CONNECTING) isns_net_stream_error(sock, ECONNREFUSED); +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/open-isns/util.h open-iscsi-2.0-872-rc4-bnx2i.work/utils/open-isns/util.h +--- open-iscsi-2.0-872-rc4-bnx2i/utils/open-isns/util.h 2010-07-11 04:05:58.000000000 -0500 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/utils/open-isns/util.h 2012-03-05 23:03:38.000000000 -0600 +@@ -9,6 +9,7 @@ + + #include + #include ++#include + #include + #include + #include // for strdup diff --git a/iscsi-initiator-utils-sync-uio-0.7.2.1.patch b/iscsi-initiator-utils-sync-uio-0.7.2.1.patch new file mode 100644 index 0000000..d707851 --- /dev/null +++ b/iscsi-initiator-utils-sync-uio-0.7.2.1.patch @@ -0,0 +1,74897 @@ +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/aclocal.m4 open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/aclocal.m4 +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/aclocal.m4 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/aclocal.m4 2012-04-09 21:52:14.000000000 -0500 +@@ -0,0 +1,7277 @@ ++# generated automatically by aclocal 1.9.6 -*- Autoconf -*- ++ ++# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, ++# 2005 Free Software Foundation, Inc. ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY, to the extent permitted by law; without ++# even the implied warranty of MERCHANTABILITY or FITNESS FOR A ++# PARTICULAR PURPOSE. ++ ++# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- ++ ++# serial 48 AC_PROG_LIBTOOL ++ ++ ++# AC_PROVIDE_IFELSE(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED) ++# ----------------------------------------------------------- ++# If this macro is not defined by Autoconf, define it here. ++m4_ifdef([AC_PROVIDE_IFELSE], ++ [], ++ [m4_define([AC_PROVIDE_IFELSE], ++ [m4_ifdef([AC_PROVIDE_$1], ++ [$2], [$3])])]) ++ ++ ++# AC_PROG_LIBTOOL ++# --------------- ++AC_DEFUN([AC_PROG_LIBTOOL], ++[AC_REQUIRE([_AC_PROG_LIBTOOL])dnl ++dnl If AC_PROG_CXX has already been expanded, run AC_LIBTOOL_CXX ++dnl immediately, otherwise, hook it in at the end of AC_PROG_CXX. ++ AC_PROVIDE_IFELSE([AC_PROG_CXX], ++ [AC_LIBTOOL_CXX], ++ [define([AC_PROG_CXX], defn([AC_PROG_CXX])[AC_LIBTOOL_CXX ++ ])]) ++dnl And a similar setup for Fortran 77 support ++ AC_PROVIDE_IFELSE([AC_PROG_F77], ++ [AC_LIBTOOL_F77], ++ [define([AC_PROG_F77], defn([AC_PROG_F77])[AC_LIBTOOL_F77 ++])]) ++ ++dnl Quote A][M_PROG_GCJ so that aclocal doesn't bring it in needlessly. ++dnl If either AC_PROG_GCJ or A][M_PROG_GCJ have already been expanded, run ++dnl AC_LIBTOOL_GCJ immediately, otherwise, hook it in at the end of both. ++ AC_PROVIDE_IFELSE([AC_PROG_GCJ], ++ [AC_LIBTOOL_GCJ], ++ [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], ++ [AC_LIBTOOL_GCJ], ++ [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ], ++ [AC_LIBTOOL_GCJ], ++ [ifdef([AC_PROG_GCJ], ++ [define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[AC_LIBTOOL_GCJ])]) ++ ifdef([A][M_PROG_GCJ], ++ [define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[AC_LIBTOOL_GCJ])]) ++ ifdef([LT_AC_PROG_GCJ], ++ [define([LT_AC_PROG_GCJ], ++ defn([LT_AC_PROG_GCJ])[AC_LIBTOOL_GCJ])])])]) ++])])# AC_PROG_LIBTOOL ++ ++ ++# _AC_PROG_LIBTOOL ++# ---------------- ++AC_DEFUN([_AC_PROG_LIBTOOL], ++[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl ++AC_BEFORE([$0],[AC_LIBTOOL_CXX])dnl ++AC_BEFORE([$0],[AC_LIBTOOL_F77])dnl ++AC_BEFORE([$0],[AC_LIBTOOL_GCJ])dnl ++ ++# This can be used to rebuild libtool when needed ++LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh" ++ ++# Always use our own libtool. ++LIBTOOL='$(SHELL) $(top_builddir)/libtool' ++AC_SUBST(LIBTOOL)dnl ++ ++# Prevent multiple expansion ++define([AC_PROG_LIBTOOL], []) ++])# _AC_PROG_LIBTOOL ++ ++ ++# AC_LIBTOOL_SETUP ++# ---------------- ++AC_DEFUN([AC_LIBTOOL_SETUP], ++[AC_PREREQ(2.50)dnl ++AC_REQUIRE([AC_ENABLE_SHARED])dnl ++AC_REQUIRE([AC_ENABLE_STATIC])dnl ++AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl ++AC_REQUIRE([AC_CANONICAL_HOST])dnl ++AC_REQUIRE([AC_CANONICAL_BUILD])dnl ++AC_REQUIRE([AC_PROG_CC])dnl ++AC_REQUIRE([AC_PROG_LD])dnl ++AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl ++AC_REQUIRE([AC_PROG_NM])dnl ++ ++AC_REQUIRE([AC_PROG_LN_S])dnl ++AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl ++# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers! ++AC_REQUIRE([AC_OBJEXT])dnl ++AC_REQUIRE([AC_EXEEXT])dnl ++dnl ++ ++AC_LIBTOOL_SYS_MAX_CMD_LEN ++AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE ++AC_LIBTOOL_OBJDIR ++ ++AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl ++_LT_AC_PROG_ECHO_BACKSLASH ++ ++case $host_os in ++aix3*) ++ # AIX sometimes has problems with the GCC collect2 program. For some ++ # reason, if we set the COLLECT_NAMES environment variable, the problems ++ # vanish in a puff of smoke. ++ if test "X${COLLECT_NAMES+set}" != Xset; then ++ COLLECT_NAMES= ++ export COLLECT_NAMES ++ fi ++ ;; ++esac ++ ++# Sed substitution that helps us do robust quoting. It backslashifies ++# metacharacters that are still active within double-quoted strings. ++Xsed='sed -e 1s/^X//' ++[sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'] ++ ++# Same as above, but do not quote variable references. ++[double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g'] ++ ++# Sed substitution to delay expansion of an escaped shell variable in a ++# double_quote_subst'ed string. ++delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' ++ ++# Sed substitution to avoid accidental globbing in evaled expressions ++no_glob_subst='s/\*/\\\*/g' ++ ++# Constants: ++rm="rm -f" ++ ++# Global variables: ++default_ofile=libtool ++can_build_shared=yes ++ ++# All known linkers require a `.a' archive for static linking (except MSVC, ++# which needs '.lib'). ++libext=a ++ltmain="$ac_aux_dir/ltmain.sh" ++ofile="$default_ofile" ++with_gnu_ld="$lt_cv_prog_gnu_ld" ++ ++AC_CHECK_TOOL(AR, ar, false) ++AC_CHECK_TOOL(RANLIB, ranlib, :) ++AC_CHECK_TOOL(STRIP, strip, :) ++ ++old_CC="$CC" ++old_CFLAGS="$CFLAGS" ++ ++# Set sane defaults for various variables ++test -z "$AR" && AR=ar ++test -z "$AR_FLAGS" && AR_FLAGS=cru ++test -z "$AS" && AS=as ++test -z "$CC" && CC=cc ++test -z "$LTCC" && LTCC=$CC ++test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS ++test -z "$DLLTOOL" && DLLTOOL=dlltool ++test -z "$LD" && LD=ld ++test -z "$LN_S" && LN_S="ln -s" ++test -z "$MAGIC_CMD" && MAGIC_CMD=file ++test -z "$NM" && NM=nm ++test -z "$SED" && SED=sed ++test -z "$OBJDUMP" && OBJDUMP=objdump ++test -z "$RANLIB" && RANLIB=: ++test -z "$STRIP" && STRIP=: ++test -z "$ac_objext" && ac_objext=o ++ ++# Determine commands to create old-style static archives. ++old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs' ++old_postinstall_cmds='chmod 644 $oldlib' ++old_postuninstall_cmds= ++ ++if test -n "$RANLIB"; then ++ case $host_os in ++ openbsd*) ++ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" ++ ;; ++ *) ++ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" ++ ;; ++ esac ++ old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" ++fi ++ ++_LT_CC_BASENAME([$compiler]) ++ ++# Only perform the check for file, if the check method requires it ++case $deplibs_check_method in ++file_magic*) ++ if test "$file_magic_cmd" = '$MAGIC_CMD'; then ++ AC_PATH_MAGIC ++ fi ++ ;; ++esac ++ ++AC_PROVIDE_IFELSE([AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no) ++AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL], ++enable_win32_dll=yes, enable_win32_dll=no) ++ ++AC_ARG_ENABLE([libtool-lock], ++ [AC_HELP_STRING([--disable-libtool-lock], ++ [avoid locking (might break parallel builds)])]) ++test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes ++ ++AC_ARG_WITH([pic], ++ [AC_HELP_STRING([--with-pic], ++ [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], ++ [pic_mode="$withval"], ++ [pic_mode=default]) ++test -z "$pic_mode" && pic_mode=default ++ ++# Use C for the default configuration in the libtool script ++tagname= ++AC_LIBTOOL_LANG_C_CONFIG ++_LT_AC_TAGCONFIG ++])# AC_LIBTOOL_SETUP ++ ++ ++# _LT_AC_SYS_COMPILER ++# ------------------- ++AC_DEFUN([_LT_AC_SYS_COMPILER], ++[AC_REQUIRE([AC_PROG_CC])dnl ++ ++# If no C compiler was specified, use CC. ++LTCC=${LTCC-"$CC"} ++ ++# If no C compiler flags were specified, use CFLAGS. ++LTCFLAGS=${LTCFLAGS-"$CFLAGS"} ++ ++# Allow CC to be a program name with arguments. ++compiler=$CC ++])# _LT_AC_SYS_COMPILER ++ ++ ++# _LT_CC_BASENAME(CC) ++# ------------------- ++# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. ++AC_DEFUN([_LT_CC_BASENAME], ++[for cc_temp in $1""; do ++ case $cc_temp in ++ compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; ++ distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; ++ \-*) ;; ++ *) break;; ++ esac ++done ++cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` ++]) ++ ++ ++# _LT_COMPILER_BOILERPLATE ++# ------------------------ ++# Check for compiler boilerplate output or warnings with ++# the simple compiler test code. ++AC_DEFUN([_LT_COMPILER_BOILERPLATE], ++[ac_outfile=conftest.$ac_objext ++printf "$lt_simple_compile_test_code" >conftest.$ac_ext ++eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err ++_lt_compiler_boilerplate=`cat conftest.err` ++$rm conftest* ++])# _LT_COMPILER_BOILERPLATE ++ ++ ++# _LT_LINKER_BOILERPLATE ++# ---------------------- ++# Check for linker boilerplate output or warnings with ++# the simple link test code. ++AC_DEFUN([_LT_LINKER_BOILERPLATE], ++[ac_outfile=conftest.$ac_objext ++printf "$lt_simple_link_test_code" >conftest.$ac_ext ++eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err ++_lt_linker_boilerplate=`cat conftest.err` ++$rm conftest* ++])# _LT_LINKER_BOILERPLATE ++ ++ ++# _LT_AC_SYS_LIBPATH_AIX ++# ---------------------- ++# Links a minimal program and checks the executable ++# for the system default hardcoded library path. In most cases, ++# this is /usr/lib:/lib, but when the MPI compilers are used ++# the location of the communication and MPI libs are included too. ++# If we don't find anything, use the default library path according ++# to the aix ld manual. ++AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX], ++[AC_LINK_IFELSE(AC_LANG_PROGRAM,[ ++aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } ++}'` ++# Check for a 64-bit object if we didn't find anything. ++if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } ++}'`; fi],[]) ++if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ++])# _LT_AC_SYS_LIBPATH_AIX ++ ++ ++# _LT_AC_SHELL_INIT(ARG) ++# ---------------------- ++AC_DEFUN([_LT_AC_SHELL_INIT], ++[ifdef([AC_DIVERSION_NOTICE], ++ [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)], ++ [AC_DIVERT_PUSH(NOTICE)]) ++$1 ++AC_DIVERT_POP ++])# _LT_AC_SHELL_INIT ++ ++ ++# _LT_AC_PROG_ECHO_BACKSLASH ++# -------------------------- ++# Add some code to the start of the generated configure script which ++# will find an echo command which doesn't interpret backslashes. ++AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH], ++[_LT_AC_SHELL_INIT([ ++# Check that we are running under the correct shell. ++SHELL=${CONFIG_SHELL-/bin/sh} ++ ++case X$ECHO in ++X*--fallback-echo) ++ # Remove one level of quotation (which was required for Make). ++ ECHO=`echo "$ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','` ++ ;; ++esac ++ ++echo=${ECHO-echo} ++if test "X[$]1" = X--no-reexec; then ++ # Discard the --no-reexec flag, and continue. ++ shift ++elif test "X[$]1" = X--fallback-echo; then ++ # Avoid inline document here, it may be left over ++ : ++elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then ++ # Yippee, $echo works! ++ : ++else ++ # Restart under the correct shell. ++ exec $SHELL "[$]0" --no-reexec ${1+"[$]@"} ++fi ++ ++if test "X[$]1" = X--fallback-echo; then ++ # used as fallback echo ++ shift ++ cat </dev/null 2>&1 && unset CDPATH ++ ++if test -z "$ECHO"; then ++if test "X${echo_test_string+set}" != Xset; then ++# find a string as large as possible, as long as the shell can cope with it ++ for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do ++ # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... ++ if (echo_test_string=`eval $cmd`) 2>/dev/null && ++ echo_test_string=`eval $cmd` && ++ (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null ++ then ++ break ++ fi ++ done ++fi ++ ++if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ : ++else ++ # The Solaris, AIX, and Digital Unix default echo programs unquote ++ # backslashes. This makes it impossible to quote backslashes using ++ # echo "$something" | sed 's/\\/\\\\/g' ++ # ++ # So, first we look for a working echo in the user's PATH. ++ ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++ for dir in $PATH /usr/ucb; do ++ IFS="$lt_save_ifs" ++ if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && ++ test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ echo="$dir/echo" ++ break ++ fi ++ done ++ IFS="$lt_save_ifs" ++ ++ if test "X$echo" = Xecho; then ++ # We didn't find a better echo, so look for alternatives. ++ if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ # This shell has a builtin print -r that does the trick. ++ echo='print -r' ++ elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && ++ test "X$CONFIG_SHELL" != X/bin/ksh; then ++ # If we have ksh, try running configure again with it. ++ ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} ++ export ORIGINAL_CONFIG_SHELL ++ CONFIG_SHELL=/bin/ksh ++ export CONFIG_SHELL ++ exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"} ++ else ++ # Try using printf. ++ echo='printf %s\n' ++ if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ # Cool, printf works ++ : ++ elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && ++ test "X$echo_testing_string" = 'X\t' && ++ echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL ++ export CONFIG_SHELL ++ SHELL="$CONFIG_SHELL" ++ export SHELL ++ echo="$CONFIG_SHELL [$]0 --fallback-echo" ++ elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && ++ test "X$echo_testing_string" = 'X\t' && ++ echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ echo="$CONFIG_SHELL [$]0 --fallback-echo" ++ else ++ # maybe with a smaller string... ++ prev=: ++ ++ for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do ++ if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null ++ then ++ break ++ fi ++ prev="$cmd" ++ done ++ ++ if test "$prev" != 'sed 50q "[$]0"'; then ++ echo_test_string=`eval $prev` ++ export echo_test_string ++ exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"} ++ else ++ # Oops. We lost completely, so just stick with echo. ++ echo=echo ++ fi ++ fi ++ fi ++ fi ++fi ++fi ++ ++# Copy echo and quote the copy suitably for passing to libtool from ++# the Makefile, instead of quoting the original, which is used later. ++ECHO=$echo ++if test "X$ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then ++ ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo" ++fi ++ ++AC_SUBST(ECHO) ++])])# _LT_AC_PROG_ECHO_BACKSLASH ++ ++ ++# _LT_AC_LOCK ++# ----------- ++AC_DEFUN([_LT_AC_LOCK], ++[AC_ARG_ENABLE([libtool-lock], ++ [AC_HELP_STRING([--disable-libtool-lock], ++ [avoid locking (might break parallel builds)])]) ++test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes ++ ++# Some flags need to be propagated to the compiler or linker for good ++# libtool support. ++case $host in ++ia64-*-hpux*) ++ # Find out which ABI we are using. ++ echo 'int i;' > conftest.$ac_ext ++ if AC_TRY_EVAL(ac_compile); then ++ case `/usr/bin/file conftest.$ac_objext` in ++ *ELF-32*) ++ HPUX_IA64_MODE="32" ++ ;; ++ *ELF-64*) ++ HPUX_IA64_MODE="64" ++ ;; ++ esac ++ fi ++ rm -rf conftest* ++ ;; ++*-*-irix6*) ++ # Find out which ABI we are using. ++ echo '[#]line __oline__ "configure"' > conftest.$ac_ext ++ if AC_TRY_EVAL(ac_compile); then ++ if test "$lt_cv_prog_gnu_ld" = yes; then ++ case `/usr/bin/file conftest.$ac_objext` in ++ *32-bit*) ++ LD="${LD-ld} -melf32bsmip" ++ ;; ++ *N32*) ++ LD="${LD-ld} -melf32bmipn32" ++ ;; ++ *64-bit*) ++ LD="${LD-ld} -melf64bmip" ++ ;; ++ esac ++ else ++ case `/usr/bin/file conftest.$ac_objext` in ++ *32-bit*) ++ LD="${LD-ld} -32" ++ ;; ++ *N32*) ++ LD="${LD-ld} -n32" ++ ;; ++ *64-bit*) ++ LD="${LD-ld} -64" ++ ;; ++ esac ++ fi ++ fi ++ rm -rf conftest* ++ ;; ++ ++x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) ++ # Find out which ABI we are using. ++ echo 'int i;' > conftest.$ac_ext ++ if AC_TRY_EVAL(ac_compile); then ++ case `/usr/bin/file conftest.o` in ++ *32-bit*) ++ case $host in ++ x86_64-*linux*) ++ LD="${LD-ld} -m elf_i386" ++ ;; ++ ppc64-*linux*|powerpc64-*linux*) ++ LD="${LD-ld} -m elf32ppclinux" ++ ;; ++ s390x-*linux*) ++ LD="${LD-ld} -m elf_s390" ++ ;; ++ sparc64-*linux*) ++ LD="${LD-ld} -m elf32_sparc" ++ ;; ++ esac ++ ;; ++ *64-bit*) ++ case $host in ++ x86_64-*linux*) ++ LD="${LD-ld} -m elf_x86_64" ++ ;; ++ ppc*-*linux*|powerpc*-*linux*) ++ LD="${LD-ld} -m elf64ppc" ++ ;; ++ s390*-*linux*) ++ LD="${LD-ld} -m elf64_s390" ++ ;; ++ sparc*-*linux*) ++ LD="${LD-ld} -m elf64_sparc" ++ ;; ++ esac ++ ;; ++ esac ++ fi ++ rm -rf conftest* ++ ;; ++ ++*-*-sco3.2v5*) ++ # On SCO OpenServer 5, we need -belf to get full-featured binaries. ++ SAVE_CFLAGS="$CFLAGS" ++ CFLAGS="$CFLAGS -belf" ++ AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, ++ [AC_LANG_PUSH(C) ++ AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) ++ AC_LANG_POP]) ++ if test x"$lt_cv_cc_needs_belf" != x"yes"; then ++ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf ++ CFLAGS="$SAVE_CFLAGS" ++ fi ++ ;; ++sparc*-*solaris*) ++ # Find out which ABI we are using. ++ echo 'int i;' > conftest.$ac_ext ++ if AC_TRY_EVAL(ac_compile); then ++ case `/usr/bin/file conftest.o` in ++ *64-bit*) ++ case $lt_cv_prog_gnu_ld in ++ yes*) LD="${LD-ld} -m elf64_sparc" ;; ++ *) LD="${LD-ld} -64" ;; ++ esac ++ ;; ++ esac ++ fi ++ rm -rf conftest* ++ ;; ++ ++AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL], ++[*-*-cygwin* | *-*-mingw* | *-*-pw32*) ++ AC_CHECK_TOOL(DLLTOOL, dlltool, false) ++ AC_CHECK_TOOL(AS, as, false) ++ AC_CHECK_TOOL(OBJDUMP, objdump, false) ++ ;; ++ ]) ++esac ++ ++need_locks="$enable_libtool_lock" ++ ++])# _LT_AC_LOCK ++ ++ ++# AC_LIBTOOL_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, ++# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) ++# ---------------------------------------------------------------- ++# Check whether the given compiler option works ++AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], ++[AC_REQUIRE([LT_AC_PROG_SED]) ++AC_CACHE_CHECK([$1], [$2], ++ [$2=no ++ ifelse([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) ++ printf "$lt_simple_compile_test_code" > conftest.$ac_ext ++ lt_compiler_flag="$3" ++ # Insert the option either (1) after the last *FLAGS variable, or ++ # (2) before a word containing "conftest.", or (3) at the end. ++ # Note that $ac_compile itself does not contain backslashes and begins ++ # with a dollar sign (not a hyphen), so the echo should work correctly. ++ # The option is referenced via a variable to avoid confusing sed. ++ lt_compile=`echo "$ac_compile" | $SED \ ++ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ ++ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ ++ -e 's:$: $lt_compiler_flag:'` ++ (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) ++ (eval "$lt_compile" 2>conftest.err) ++ ac_status=$? ++ cat conftest.err >&AS_MESSAGE_LOG_FD ++ echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD ++ if (exit $ac_status) && test -s "$ac_outfile"; then ++ # The compiler can only warn and ignore the option if not recognized ++ # So say no if there are warnings other than the usual output. ++ $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp ++ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 ++ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then ++ $2=yes ++ fi ++ fi ++ $rm conftest* ++]) ++ ++if test x"[$]$2" = xyes; then ++ ifelse([$5], , :, [$5]) ++else ++ ifelse([$6], , :, [$6]) ++fi ++])# AC_LIBTOOL_COMPILER_OPTION ++ ++ ++# AC_LIBTOOL_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, ++# [ACTION-SUCCESS], [ACTION-FAILURE]) ++# ------------------------------------------------------------ ++# Check whether the given compiler option works ++AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], ++[AC_CACHE_CHECK([$1], [$2], ++ [$2=no ++ save_LDFLAGS="$LDFLAGS" ++ LDFLAGS="$LDFLAGS $3" ++ printf "$lt_simple_link_test_code" > conftest.$ac_ext ++ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then ++ # The linker can only warn and ignore the option if not recognized ++ # So say no if there are warnings ++ if test -s conftest.err; then ++ # Append any errors to the config.log. ++ cat conftest.err 1>&AS_MESSAGE_LOG_FD ++ $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp ++ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 ++ if diff conftest.exp conftest.er2 >/dev/null; then ++ $2=yes ++ fi ++ else ++ $2=yes ++ fi ++ fi ++ $rm conftest* ++ LDFLAGS="$save_LDFLAGS" ++]) ++ ++if test x"[$]$2" = xyes; then ++ ifelse([$4], , :, [$4]) ++else ++ ifelse([$5], , :, [$5]) ++fi ++])# AC_LIBTOOL_LINKER_OPTION ++ ++ ++# AC_LIBTOOL_SYS_MAX_CMD_LEN ++# -------------------------- ++AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], ++[# find the maximum length of command line arguments ++AC_MSG_CHECKING([the maximum length of command line arguments]) ++AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl ++ i=0 ++ teststring="ABCD" ++ ++ case $build_os in ++ msdosdjgpp*) ++ # On DJGPP, this test can blow up pretty badly due to problems in libc ++ # (any single argument exceeding 2000 bytes causes a buffer overrun ++ # during glob expansion). Even if it were fixed, the result of this ++ # check would be larger than it should be. ++ lt_cv_sys_max_cmd_len=12288; # 12K is about right ++ ;; ++ ++ gnu*) ++ # Under GNU Hurd, this test is not required because there is ++ # no limit to the length of command line arguments. ++ # Libtool will interpret -1 as no limit whatsoever ++ lt_cv_sys_max_cmd_len=-1; ++ ;; ++ ++ cygwin* | mingw*) ++ # On Win9x/ME, this test blows up -- it succeeds, but takes ++ # about 5 minutes as the teststring grows exponentially. ++ # Worse, since 9x/ME are not pre-emptively multitasking, ++ # you end up with a "frozen" computer, even though with patience ++ # the test eventually succeeds (with a max line length of 256k). ++ # Instead, let's just punt: use the minimum linelength reported by ++ # all of the supported platforms: 8192 (on NT/2K/XP). ++ lt_cv_sys_max_cmd_len=8192; ++ ;; ++ ++ amigaos*) ++ # On AmigaOS with pdksh, this test takes hours, literally. ++ # So we just punt and use a minimum line length of 8192. ++ lt_cv_sys_max_cmd_len=8192; ++ ;; ++ ++ netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) ++ # This has been around since 386BSD, at least. Likely further. ++ if test -x /sbin/sysctl; then ++ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` ++ elif test -x /usr/sbin/sysctl; then ++ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` ++ else ++ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs ++ fi ++ # And add a safety zone ++ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` ++ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ++ ;; ++ ++ interix*) ++ # We know the value 262144 and hardcode it with a safety zone (like BSD) ++ lt_cv_sys_max_cmd_len=196608 ++ ;; ++ ++ osf*) ++ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure ++ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not ++ # nice to cause kernel panics so lets avoid the loop below. ++ # First set a reasonable default. ++ lt_cv_sys_max_cmd_len=16384 ++ # ++ if test -x /sbin/sysconfig; then ++ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in ++ *1*) lt_cv_sys_max_cmd_len=-1 ;; ++ esac ++ fi ++ ;; ++ sco3.2v5*) ++ lt_cv_sys_max_cmd_len=102400 ++ ;; ++ sysv5* | sco5v6* | sysv4.2uw2*) ++ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` ++ if test -n "$kargmax"; then ++ lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` ++ else ++ lt_cv_sys_max_cmd_len=32768 ++ fi ++ ;; ++ *) ++ # If test is not a shell built-in, we'll probably end up computing a ++ # maximum length that is only half of the actual maximum length, but ++ # we can't tell. ++ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} ++ while (test "X"`$SHELL [$]0 --fallback-echo "X$teststring" 2>/dev/null` \ ++ = "XX$teststring") >/dev/null 2>&1 && ++ new_result=`expr "X$teststring" : ".*" 2>&1` && ++ lt_cv_sys_max_cmd_len=$new_result && ++ test $i != 17 # 1/2 MB should be enough ++ do ++ i=`expr $i + 1` ++ teststring=$teststring$teststring ++ done ++ teststring= ++ # Add a significant safety factor because C++ compilers can tack on massive ++ # amounts of additional arguments before passing them to the linker. ++ # It appears as though 1/2 is a usable value. ++ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` ++ ;; ++ esac ++]) ++if test -n $lt_cv_sys_max_cmd_len ; then ++ AC_MSG_RESULT($lt_cv_sys_max_cmd_len) ++else ++ AC_MSG_RESULT(none) ++fi ++])# AC_LIBTOOL_SYS_MAX_CMD_LEN ++ ++ ++# _LT_AC_CHECK_DLFCN ++# ------------------ ++AC_DEFUN([_LT_AC_CHECK_DLFCN], ++[AC_CHECK_HEADERS(dlfcn.h)dnl ++])# _LT_AC_CHECK_DLFCN ++ ++ ++# _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, ++# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) ++# --------------------------------------------------------------------- ++AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF], ++[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl ++if test "$cross_compiling" = yes; then : ++ [$4] ++else ++ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 ++ lt_status=$lt_dlunknown ++ cat > conftest.$ac_ext < ++#endif ++ ++#include ++ ++#ifdef RTLD_GLOBAL ++# define LT_DLGLOBAL RTLD_GLOBAL ++#else ++# ifdef DL_GLOBAL ++# define LT_DLGLOBAL DL_GLOBAL ++# else ++# define LT_DLGLOBAL 0 ++# endif ++#endif ++ ++/* We may have to define LT_DLLAZY_OR_NOW in the command line if we ++ find out it does not work in some platform. */ ++#ifndef LT_DLLAZY_OR_NOW ++# ifdef RTLD_LAZY ++# define LT_DLLAZY_OR_NOW RTLD_LAZY ++# else ++# ifdef DL_LAZY ++# define LT_DLLAZY_OR_NOW DL_LAZY ++# else ++# ifdef RTLD_NOW ++# define LT_DLLAZY_OR_NOW RTLD_NOW ++# else ++# ifdef DL_NOW ++# define LT_DLLAZY_OR_NOW DL_NOW ++# else ++# define LT_DLLAZY_OR_NOW 0 ++# endif ++# endif ++# endif ++# endif ++#endif ++ ++#ifdef __cplusplus ++extern "C" void exit (int); ++#endif ++ ++void fnord() { int i=42;} ++int main () ++{ ++ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); ++ int status = $lt_dlunknown; ++ ++ if (self) ++ { ++ if (dlsym (self,"fnord")) status = $lt_dlno_uscore; ++ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; ++ /* dlclose (self); */ ++ } ++ else ++ puts (dlerror ()); ++ ++ exit (status); ++}] ++EOF ++ if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then ++ (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null ++ lt_status=$? ++ case x$lt_status in ++ x$lt_dlno_uscore) $1 ;; ++ x$lt_dlneed_uscore) $2 ;; ++ x$lt_dlunknown|x*) $3 ;; ++ esac ++ else : ++ # compilation failed ++ $3 ++ fi ++fi ++rm -fr conftest* ++])# _LT_AC_TRY_DLOPEN_SELF ++ ++ ++# AC_LIBTOOL_DLOPEN_SELF ++# ---------------------- ++AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], ++[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl ++if test "x$enable_dlopen" != xyes; then ++ enable_dlopen=unknown ++ enable_dlopen_self=unknown ++ enable_dlopen_self_static=unknown ++else ++ lt_cv_dlopen=no ++ lt_cv_dlopen_libs= ++ ++ case $host_os in ++ beos*) ++ lt_cv_dlopen="load_add_on" ++ lt_cv_dlopen_libs= ++ lt_cv_dlopen_self=yes ++ ;; ++ ++ mingw* | pw32*) ++ lt_cv_dlopen="LoadLibrary" ++ lt_cv_dlopen_libs= ++ ;; ++ ++ cygwin*) ++ lt_cv_dlopen="dlopen" ++ lt_cv_dlopen_libs= ++ ;; ++ ++ darwin*) ++ # if libdl is installed we need to link against it ++ AC_CHECK_LIB([dl], [dlopen], ++ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ ++ lt_cv_dlopen="dyld" ++ lt_cv_dlopen_libs= ++ lt_cv_dlopen_self=yes ++ ]) ++ ;; ++ ++ *) ++ AC_CHECK_FUNC([shl_load], ++ [lt_cv_dlopen="shl_load"], ++ [AC_CHECK_LIB([dld], [shl_load], ++ [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"], ++ [AC_CHECK_FUNC([dlopen], ++ [lt_cv_dlopen="dlopen"], ++ [AC_CHECK_LIB([dl], [dlopen], ++ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], ++ [AC_CHECK_LIB([svld], [dlopen], ++ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], ++ [AC_CHECK_LIB([dld], [dld_link], ++ [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"]) ++ ]) ++ ]) ++ ]) ++ ]) ++ ]) ++ ;; ++ esac ++ ++ if test "x$lt_cv_dlopen" != xno; then ++ enable_dlopen=yes ++ else ++ enable_dlopen=no ++ fi ++ ++ case $lt_cv_dlopen in ++ dlopen) ++ save_CPPFLAGS="$CPPFLAGS" ++ test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" ++ ++ save_LDFLAGS="$LDFLAGS" ++ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" ++ ++ save_LIBS="$LIBS" ++ LIBS="$lt_cv_dlopen_libs $LIBS" ++ ++ AC_CACHE_CHECK([whether a program can dlopen itself], ++ lt_cv_dlopen_self, [dnl ++ _LT_AC_TRY_DLOPEN_SELF( ++ lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, ++ lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) ++ ]) ++ ++ if test "x$lt_cv_dlopen_self" = xyes; then ++ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" ++ AC_CACHE_CHECK([whether a statically linked program can dlopen itself], ++ lt_cv_dlopen_self_static, [dnl ++ _LT_AC_TRY_DLOPEN_SELF( ++ lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, ++ lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) ++ ]) ++ fi ++ ++ CPPFLAGS="$save_CPPFLAGS" ++ LDFLAGS="$save_LDFLAGS" ++ LIBS="$save_LIBS" ++ ;; ++ esac ++ ++ case $lt_cv_dlopen_self in ++ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; ++ *) enable_dlopen_self=unknown ;; ++ esac ++ ++ case $lt_cv_dlopen_self_static in ++ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; ++ *) enable_dlopen_self_static=unknown ;; ++ esac ++fi ++])# AC_LIBTOOL_DLOPEN_SELF ++ ++ ++# AC_LIBTOOL_PROG_CC_C_O([TAGNAME]) ++# --------------------------------- ++# Check to see if options -c and -o are simultaneously supported by compiler ++AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O], ++[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl ++AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], ++ [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)], ++ [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no ++ $rm -r conftest 2>/dev/null ++ mkdir conftest ++ cd conftest ++ mkdir out ++ printf "$lt_simple_compile_test_code" > conftest.$ac_ext ++ ++ lt_compiler_flag="-o out/conftest2.$ac_objext" ++ # Insert the option either (1) after the last *FLAGS variable, or ++ # (2) before a word containing "conftest.", or (3) at the end. ++ # Note that $ac_compile itself does not contain backslashes and begins ++ # with a dollar sign (not a hyphen), so the echo should work correctly. ++ lt_compile=`echo "$ac_compile" | $SED \ ++ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ ++ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ ++ -e 's:$: $lt_compiler_flag:'` ++ (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) ++ (eval "$lt_compile" 2>out/conftest.err) ++ ac_status=$? ++ cat out/conftest.err >&AS_MESSAGE_LOG_FD ++ echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD ++ if (exit $ac_status) && test -s out/conftest2.$ac_objext ++ then ++ # The compiler can only warn and ignore the option if not recognized ++ # So say no if there are warnings ++ $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp ++ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 ++ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then ++ _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes ++ fi ++ fi ++ chmod u+w . 2>&AS_MESSAGE_LOG_FD ++ $rm conftest* ++ # SGI C++ compiler will create directory out/ii_files/ for ++ # template instantiation ++ test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files ++ $rm out/* && rmdir out ++ cd .. ++ rmdir conftest ++ $rm conftest* ++]) ++])# AC_LIBTOOL_PROG_CC_C_O ++ ++ ++# AC_LIBTOOL_SYS_HARD_LINK_LOCKS([TAGNAME]) ++# ----------------------------------------- ++# Check to see if we can do hard links to lock some files if needed ++AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], ++[AC_REQUIRE([_LT_AC_LOCK])dnl ++ ++hard_links="nottested" ++if test "$_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then ++ # do not overwrite the value of need_locks provided by the user ++ AC_MSG_CHECKING([if we can lock with hard links]) ++ hard_links=yes ++ $rm conftest* ++ ln conftest.a conftest.b 2>/dev/null && hard_links=no ++ touch conftest.a ++ ln conftest.a conftest.b 2>&5 || hard_links=no ++ ln conftest.a conftest.b 2>/dev/null && hard_links=no ++ AC_MSG_RESULT([$hard_links]) ++ if test "$hard_links" = no; then ++ AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) ++ need_locks=warn ++ fi ++else ++ need_locks=no ++fi ++])# AC_LIBTOOL_SYS_HARD_LINK_LOCKS ++ ++ ++# AC_LIBTOOL_OBJDIR ++# ----------------- ++AC_DEFUN([AC_LIBTOOL_OBJDIR], ++[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], ++[rm -f .libs 2>/dev/null ++mkdir .libs 2>/dev/null ++if test -d .libs; then ++ lt_cv_objdir=.libs ++else ++ # MS-DOS does not allow filenames that begin with a dot. ++ lt_cv_objdir=_libs ++fi ++rmdir .libs 2>/dev/null]) ++objdir=$lt_cv_objdir ++])# AC_LIBTOOL_OBJDIR ++ ++ ++# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH([TAGNAME]) ++# ---------------------------------------------- ++# Check hardcoding attributes. ++AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], ++[AC_MSG_CHECKING([how to hardcode library paths into programs]) ++_LT_AC_TAGVAR(hardcode_action, $1)= ++if test -n "$_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)" || \ ++ test -n "$_LT_AC_TAGVAR(runpath_var, $1)" || \ ++ test "X$_LT_AC_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then ++ ++ # We can hardcode non-existant directories. ++ if test "$_LT_AC_TAGVAR(hardcode_direct, $1)" != no && ++ # If the only mechanism to avoid hardcoding is shlibpath_var, we ++ # have to relink, otherwise we might link with an installed library ++ # when we should be linking with a yet-to-be-installed one ++ ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)" != no && ++ test "$_LT_AC_TAGVAR(hardcode_minus_L, $1)" != no; then ++ # Linking always hardcodes the temporary library directory. ++ _LT_AC_TAGVAR(hardcode_action, $1)=relink ++ else ++ # We can link without hardcoding, and we can hardcode nonexisting dirs. ++ _LT_AC_TAGVAR(hardcode_action, $1)=immediate ++ fi ++else ++ # We cannot hardcode anything, or else we can only hardcode existing ++ # directories. ++ _LT_AC_TAGVAR(hardcode_action, $1)=unsupported ++fi ++AC_MSG_RESULT([$_LT_AC_TAGVAR(hardcode_action, $1)]) ++ ++if test "$_LT_AC_TAGVAR(hardcode_action, $1)" = relink; then ++ # Fast installation is not supported ++ enable_fast_install=no ++elif test "$shlibpath_overrides_runpath" = yes || ++ test "$enable_shared" = no; then ++ # Fast installation is not necessary ++ enable_fast_install=needless ++fi ++])# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH ++ ++ ++# AC_LIBTOOL_SYS_LIB_STRIP ++# ------------------------ ++AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP], ++[striplib= ++old_striplib= ++AC_MSG_CHECKING([whether stripping libraries is possible]) ++if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then ++ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" ++ test -z "$striplib" && striplib="$STRIP --strip-unneeded" ++ AC_MSG_RESULT([yes]) ++else ++# FIXME - insert some real tests, host_os isn't really good enough ++ case $host_os in ++ darwin*) ++ if test -n "$STRIP" ; then ++ striplib="$STRIP -x" ++ AC_MSG_RESULT([yes]) ++ else ++ AC_MSG_RESULT([no]) ++fi ++ ;; ++ *) ++ AC_MSG_RESULT([no]) ++ ;; ++ esac ++fi ++])# AC_LIBTOOL_SYS_LIB_STRIP ++ ++ ++# AC_LIBTOOL_SYS_DYNAMIC_LINKER ++# ----------------------------- ++# PORTME Fill in your ld.so characteristics ++AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER], ++[AC_MSG_CHECKING([dynamic linker characteristics]) ++library_names_spec= ++libname_spec='lib$name' ++soname_spec= ++shrext_cmds=".so" ++postinstall_cmds= ++postuninstall_cmds= ++finish_cmds= ++finish_eval= ++shlibpath_var= ++shlibpath_overrides_runpath=unknown ++version_type=none ++dynamic_linker="$host_os ld.so" ++sys_lib_dlsearch_path_spec="/lib /usr/lib" ++if test "$GCC" = yes; then ++ sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` ++ if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then ++ # if the path contains ";" then we assume it to be the separator ++ # otherwise default to the standard path separator (i.e. ":") - it is ++ # assumed that no part of a normal pathname contains ";" but that should ++ # okay in the real world where ";" in dirpaths is itself problematic. ++ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` ++ else ++ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ++ fi ++else ++ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" ++fi ++need_lib_prefix=unknown ++hardcode_into_libs=no ++ ++# when you set need_version to no, make sure it does not cause -set_version ++# flags to be left without arguments ++need_version=unknown ++ ++case $host_os in ++aix3*) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' ++ shlibpath_var=LIBPATH ++ ++ # AIX 3 has no versioning support, so we append a major version to the name. ++ soname_spec='${libname}${release}${shared_ext}$major' ++ ;; ++ ++aix4* | aix5*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ hardcode_into_libs=yes ++ if test "$host_cpu" = ia64; then ++ # AIX 5 supports IA64 ++ library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' ++ shlibpath_var=LD_LIBRARY_PATH ++ else ++ # With GCC up to 2.95.x, collect2 would create an import file ++ # for dependence libraries. The import file would start with ++ # the line `#! .'. This would cause the generated library to ++ # depend on `.', always an invalid library. This was fixed in ++ # development snapshots of GCC prior to 3.0. ++ case $host_os in ++ aix4 | aix4.[[01]] | aix4.[[01]].*) ++ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' ++ echo ' yes ' ++ echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then ++ : ++ else ++ can_build_shared=no ++ fi ++ ;; ++ esac ++ # AIX (on Power*) has no versioning support, so currently we can not hardcode correct ++ # soname into executable. Probably we can add versioning support to ++ # collect2, so additional links can be useful in future. ++ if test "$aix_use_runtimelinking" = yes; then ++ # If using run time linking (on AIX 4.2 or later) use lib.so ++ # instead of lib.a to let people know that these are not ++ # typical AIX shared libraries. ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ else ++ # We preserve .a as extension for shared libraries through AIX4.2 ++ # and later when we are not doing run time linking. ++ library_names_spec='${libname}${release}.a $libname.a' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ fi ++ shlibpath_var=LIBPATH ++ fi ++ ;; ++ ++amigaos*) ++ library_names_spec='$libname.ixlibrary $libname.a' ++ # Create ${libname}_ixlibrary.a entries in /sys/libs. ++ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ++ ;; ++ ++beos*) ++ library_names_spec='${libname}${shared_ext}' ++ dynamic_linker="$host_os ld.so" ++ shlibpath_var=LIBRARY_PATH ++ ;; ++ ++bsdi[[45]]*) ++ version_type=linux ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" ++ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" ++ # the default ld.so.conf also contains /usr/contrib/lib and ++ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow ++ # libtool to hard-code these into programs ++ ;; ++ ++cygwin* | mingw* | pw32*) ++ version_type=windows ++ shrext_cmds=".dll" ++ need_version=no ++ need_lib_prefix=no ++ ++ case $GCC,$host_os in ++ yes,cygwin* | yes,mingw* | yes,pw32*) ++ library_names_spec='$libname.dll.a' ++ # DLL is installed to $(libdir)/../bin by postinstall_cmds ++ postinstall_cmds='base_file=`basename \${file}`~ ++ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ ++ dldir=$destdir/`dirname \$dlpath`~ ++ test -d \$dldir || mkdir -p \$dldir~ ++ $install_prog $dir/$dlname \$dldir/$dlname~ ++ chmod a+x \$dldir/$dlname' ++ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ ++ dlpath=$dir/\$dldll~ ++ $rm \$dlpath' ++ shlibpath_overrides_runpath=yes ++ ++ case $host_os in ++ cygwin*) ++ # Cygwin DLLs use 'cyg' prefix rather than 'lib' ++ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' ++ sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" ++ ;; ++ mingw*) ++ # MinGW DLLs use traditional 'lib' prefix ++ soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' ++ sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` ++ if echo "$sys_lib_search_path_spec" | [grep ';[c-zC-Z]:/' >/dev/null]; then ++ # It is most probably a Windows format PATH printed by ++ # mingw gcc, but we are running on Cygwin. Gcc prints its search ++ # path with ; separators, and with drive letters. We can handle the ++ # drive letters (cygwin fileutils understands them), so leave them, ++ # especially as we might pass files found there to a mingw objdump, ++ # which wouldn't understand a cygwinified path. Ahh. ++ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` ++ else ++ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ++ fi ++ ;; ++ pw32*) ++ # pw32 DLLs use 'pw' prefix rather than 'lib' ++ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' ++ ;; ++ esac ++ ;; ++ ++ *) ++ library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' ++ ;; ++ esac ++ dynamic_linker='Win32 ld.exe' ++ # FIXME: first we should search . and the directory the executable is in ++ shlibpath_var=PATH ++ ;; ++ ++darwin* | rhapsody*) ++ dynamic_linker="$host_os dyld" ++ version_type=darwin ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' ++ soname_spec='${libname}${release}${major}$shared_ext' ++ shlibpath_overrides_runpath=yes ++ shlibpath_var=DYLD_LIBRARY_PATH ++ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' ++ # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. ++ if test "$GCC" = yes; then ++ sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` ++ else ++ sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' ++ fi ++ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ++ ;; ++ ++dgux*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ ;; ++ ++freebsd1*) ++ dynamic_linker=no ++ ;; ++ ++kfreebsd*-gnu) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ dynamic_linker='GNU ld.so' ++ ;; ++ ++freebsd* | dragonfly*) ++ # DragonFly does not have aout. When/if they implement a new ++ # versioning mechanism, adjust this. ++ if test -x /usr/bin/objformat; then ++ objformat=`/usr/bin/objformat` ++ else ++ case $host_os in ++ freebsd[[123]]*) objformat=aout ;; ++ *) objformat=elf ;; ++ esac ++ fi ++ version_type=freebsd-$objformat ++ case $version_type in ++ freebsd-elf*) ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' ++ need_version=no ++ need_lib_prefix=no ++ ;; ++ freebsd-*) ++ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' ++ need_version=yes ++ ;; ++ esac ++ shlibpath_var=LD_LIBRARY_PATH ++ case $host_os in ++ freebsd2*) ++ shlibpath_overrides_runpath=yes ++ ;; ++ freebsd3.[[01]]* | freebsdelf3.[[01]]*) ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ ++ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ ;; ++ freebsd*) # from 4.6 on ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ esac ++ ;; ++ ++gnu*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ hardcode_into_libs=yes ++ ;; ++ ++hpux9* | hpux10* | hpux11*) ++ # Give a soname corresponding to the major version so that dld.sl refuses to ++ # link against other versions. ++ version_type=sunos ++ need_lib_prefix=no ++ need_version=no ++ case $host_cpu in ++ ia64*) ++ shrext_cmds='.so' ++ hardcode_into_libs=yes ++ dynamic_linker="$host_os dld.so" ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ if test "X$HPUX_IA64_MODE" = X32; then ++ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" ++ else ++ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" ++ fi ++ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ++ ;; ++ hppa*64*) ++ shrext_cmds='.sl' ++ hardcode_into_libs=yes ++ dynamic_linker="$host_os dld.sl" ++ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH ++ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" ++ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ++ ;; ++ *) ++ shrext_cmds='.sl' ++ dynamic_linker="$host_os dld.sl" ++ shlibpath_var=SHLIB_PATH ++ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ ;; ++ esac ++ # HP-UX runs *really* slowly unless shared libraries are mode 555. ++ postinstall_cmds='chmod 555 $lib' ++ ;; ++ ++interix3*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ ;; ++ ++irix5* | irix6* | nonstopux*) ++ case $host_os in ++ nonstopux*) version_type=nonstopux ;; ++ *) ++ if test "$lt_cv_prog_gnu_ld" = yes; then ++ version_type=linux ++ else ++ version_type=irix ++ fi ;; ++ esac ++ need_lib_prefix=no ++ need_version=no ++ soname_spec='${libname}${release}${shared_ext}$major' ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' ++ case $host_os in ++ irix5* | nonstopux*) ++ libsuff= shlibsuff= ++ ;; ++ *) ++ case $LD in # libtool.m4 will add one of these switches to LD ++ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") ++ libsuff= shlibsuff= libmagic=32-bit;; ++ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") ++ libsuff=32 shlibsuff=N32 libmagic=N32;; ++ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") ++ libsuff=64 shlibsuff=64 libmagic=64-bit;; ++ *) libsuff= shlibsuff= libmagic=never-match;; ++ esac ++ ;; ++ esac ++ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH ++ shlibpath_overrides_runpath=no ++ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" ++ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" ++ hardcode_into_libs=yes ++ ;; ++ ++# No shared lib support for Linux oldld, aout, or coff. ++linux*oldld* | linux*aout* | linux*coff*) ++ dynamic_linker=no ++ ;; ++ ++# This must be Linux ELF. ++linux*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ # This implies no fast_install, which is unacceptable. ++ # Some rework will be needed to allow for fast_install ++ # before this can be enabled. ++ hardcode_into_libs=yes ++ ++ # find out which ABI we are using ++ libsuff= ++ case "$host_cpu" in ++ x86_64*|s390x*|powerpc64*) ++ echo '[#]line __oline__ "configure"' > conftest.$ac_ext ++ if AC_TRY_EVAL(ac_compile); then ++ case `/usr/bin/file conftest.$ac_objext` in ++ *64-bit*) ++ libsuff=64 ++ sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}" ++ ;; ++ esac ++ fi ++ rm -rf conftest* ++ ;; ++ esac ++ ++ # Append ld.so.conf contents to the search path ++ if test -f /etc/ld.so.conf; then ++ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` ++ sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff} $lt_ld_extra" ++ fi ++ ++ # We used to test for /lib/ld.so.1 and disable shared libraries on ++ # powerpc, because MkLinux only supported shared libraries with the ++ # GNU dynamic linker. Since this was broken with cross compilers, ++ # most powerpc-linux boxes support dynamic linking these days and ++ # people can always --disable-shared, the test was removed, and we ++ # assume the GNU/Linux dynamic linker is in use. ++ dynamic_linker='GNU/Linux ld.so' ++ ;; ++ ++knetbsd*-gnu) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ dynamic_linker='GNU ld.so' ++ ;; ++ ++netbsd*) ++ version_type=sunos ++ need_lib_prefix=no ++ need_version=no ++ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' ++ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' ++ dynamic_linker='NetBSD (a.out) ld.so' ++ else ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ dynamic_linker='NetBSD ld.elf_so' ++ fi ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ ++newsos6) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ ;; ++ ++nto-qnx*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ ;; ++ ++openbsd*) ++ version_type=sunos ++ sys_lib_dlsearch_path_spec="/usr/lib" ++ need_lib_prefix=no ++ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. ++ case $host_os in ++ openbsd3.3 | openbsd3.3.*) need_version=yes ;; ++ *) need_version=no ;; ++ esac ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' ++ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then ++ case $host_os in ++ openbsd2.[[89]] | openbsd2.[[89]].*) ++ shlibpath_overrides_runpath=no ++ ;; ++ *) ++ shlibpath_overrides_runpath=yes ++ ;; ++ esac ++ else ++ shlibpath_overrides_runpath=yes ++ fi ++ ;; ++ ++os2*) ++ libname_spec='$name' ++ shrext_cmds=".dll" ++ need_lib_prefix=no ++ library_names_spec='$libname${shared_ext} $libname.a' ++ dynamic_linker='OS/2 ld.exe' ++ shlibpath_var=LIBPATH ++ ;; ++ ++osf3* | osf4* | osf5*) ++ version_type=osf ++ need_lib_prefix=no ++ need_version=no ++ soname_spec='${libname}${release}${shared_ext}$major' ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ shlibpath_var=LD_LIBRARY_PATH ++ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" ++ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ++ ;; ++ ++solaris*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ # ldd complains unless libraries are executable ++ postinstall_cmds='chmod +x $lib' ++ ;; ++ ++sunos4*) ++ version_type=sunos ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' ++ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ if test "$with_gnu_ld" = yes; then ++ need_lib_prefix=no ++ fi ++ need_version=yes ++ ;; ++ ++sysv4 | sysv4.3*) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ case $host_vendor in ++ sni) ++ shlibpath_overrides_runpath=no ++ need_lib_prefix=no ++ export_dynamic_flag_spec='${wl}-Blargedynsym' ++ runpath_var=LD_RUN_PATH ++ ;; ++ siemens) ++ need_lib_prefix=no ++ ;; ++ motorola) ++ need_lib_prefix=no ++ need_version=no ++ shlibpath_overrides_runpath=no ++ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ++ ;; ++ esac ++ ;; ++ ++sysv4*MP*) ++ if test -d /usr/nec ;then ++ version_type=linux ++ library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' ++ soname_spec='$libname${shared_ext}.$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ fi ++ ;; ++ ++sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) ++ version_type=freebsd-elf ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ hardcode_into_libs=yes ++ if test "$with_gnu_ld" = yes; then ++ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' ++ shlibpath_overrides_runpath=no ++ else ++ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' ++ shlibpath_overrides_runpath=yes ++ case $host_os in ++ sco3.2v5*) ++ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ++ ;; ++ esac ++ fi ++ sys_lib_dlsearch_path_spec='/usr/lib' ++ ;; ++ ++uts4*) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ ;; ++ ++*) ++ dynamic_linker=no ++ ;; ++esac ++AC_MSG_RESULT([$dynamic_linker]) ++test "$dynamic_linker" = no && can_build_shared=no ++ ++variables_saved_for_relink="PATH $shlibpath_var $runpath_var" ++if test "$GCC" = yes; then ++ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" ++fi ++])# AC_LIBTOOL_SYS_DYNAMIC_LINKER ++ ++ ++# _LT_AC_TAGCONFIG ++# ---------------- ++AC_DEFUN([_LT_AC_TAGCONFIG], ++[AC_ARG_WITH([tags], ++ [AC_HELP_STRING([--with-tags@<:@=TAGS@:>@], ++ [include additional configurations @<:@automatic@:>@])], ++ [tagnames="$withval"]) ++ ++if test -f "$ltmain" && test -n "$tagnames"; then ++ if test ! -f "${ofile}"; then ++ AC_MSG_WARN([output file `$ofile' does not exist]) ++ fi ++ ++ if test -z "$LTCC"; then ++ eval "`$SHELL ${ofile} --config | grep '^LTCC='`" ++ if test -z "$LTCC"; then ++ AC_MSG_WARN([output file `$ofile' does not look like a libtool script]) ++ else ++ AC_MSG_WARN([using `LTCC=$LTCC', extracted from `$ofile']) ++ fi ++ fi ++ if test -z "$LTCFLAGS"; then ++ eval "`$SHELL ${ofile} --config | grep '^LTCFLAGS='`" ++ fi ++ ++ # Extract list of available tagged configurations in $ofile. ++ # Note that this assumes the entire list is on one line. ++ available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'` ++ ++ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," ++ for tagname in $tagnames; do ++ IFS="$lt_save_ifs" ++ # Check whether tagname contains only valid characters ++ case `$echo "X$tagname" | $Xsed -e 's:[[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]]::g'` in ++ "") ;; ++ *) AC_MSG_ERROR([invalid tag name: $tagname]) ++ ;; ++ esac ++ ++ if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null ++ then ++ AC_MSG_ERROR([tag name \"$tagname\" already exists]) ++ fi ++ ++ # Update the list of available tags. ++ if test -n "$tagname"; then ++ echo appending configuration tag \"$tagname\" to $ofile ++ ++ case $tagname in ++ CXX) ++ if test -n "$CXX" && ( test "X$CXX" != "Xno" && ++ ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || ++ (test "X$CXX" != "Xg++"))) ; then ++ AC_LIBTOOL_LANG_CXX_CONFIG ++ else ++ tagname="" ++ fi ++ ;; ++ ++ F77) ++ if test -n "$F77" && test "X$F77" != "Xno"; then ++ AC_LIBTOOL_LANG_F77_CONFIG ++ else ++ tagname="" ++ fi ++ ;; ++ ++ GCJ) ++ if test -n "$GCJ" && test "X$GCJ" != "Xno"; then ++ AC_LIBTOOL_LANG_GCJ_CONFIG ++ else ++ tagname="" ++ fi ++ ;; ++ ++ RC) ++ AC_LIBTOOL_LANG_RC_CONFIG ++ ;; ++ ++ *) ++ AC_MSG_ERROR([Unsupported tag name: $tagname]) ++ ;; ++ esac ++ ++ # Append the new tag name to the list of available tags. ++ if test -n "$tagname" ; then ++ available_tags="$available_tags $tagname" ++ fi ++ fi ++ done ++ IFS="$lt_save_ifs" ++ ++ # Now substitute the updated list of available tags. ++ if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then ++ mv "${ofile}T" "$ofile" ++ chmod +x "$ofile" ++ else ++ rm -f "${ofile}T" ++ AC_MSG_ERROR([unable to update list of available tagged configurations.]) ++ fi ++fi ++])# _LT_AC_TAGCONFIG ++ ++ ++# AC_LIBTOOL_DLOPEN ++# ----------------- ++# enable checks for dlopen support ++AC_DEFUN([AC_LIBTOOL_DLOPEN], ++ [AC_BEFORE([$0],[AC_LIBTOOL_SETUP]) ++])# AC_LIBTOOL_DLOPEN ++ ++ ++# AC_LIBTOOL_WIN32_DLL ++# -------------------- ++# declare package support for building win32 DLLs ++AC_DEFUN([AC_LIBTOOL_WIN32_DLL], ++[AC_BEFORE([$0], [AC_LIBTOOL_SETUP]) ++])# AC_LIBTOOL_WIN32_DLL ++ ++ ++# AC_ENABLE_SHARED([DEFAULT]) ++# --------------------------- ++# implement the --enable-shared flag ++# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. ++AC_DEFUN([AC_ENABLE_SHARED], ++[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl ++AC_ARG_ENABLE([shared], ++ [AC_HELP_STRING([--enable-shared@<:@=PKGS@:>@], ++ [build shared libraries @<:@default=]AC_ENABLE_SHARED_DEFAULT[@:>@])], ++ [p=${PACKAGE-default} ++ case $enableval in ++ yes) enable_shared=yes ;; ++ no) enable_shared=no ;; ++ *) ++ enable_shared=no ++ # Look at the argument we got. We use all the common list separators. ++ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," ++ for pkg in $enableval; do ++ IFS="$lt_save_ifs" ++ if test "X$pkg" = "X$p"; then ++ enable_shared=yes ++ fi ++ done ++ IFS="$lt_save_ifs" ++ ;; ++ esac], ++ [enable_shared=]AC_ENABLE_SHARED_DEFAULT) ++])# AC_ENABLE_SHARED ++ ++ ++# AC_DISABLE_SHARED ++# ----------------- ++# set the default shared flag to --disable-shared ++AC_DEFUN([AC_DISABLE_SHARED], ++[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl ++AC_ENABLE_SHARED(no) ++])# AC_DISABLE_SHARED ++ ++ ++# AC_ENABLE_STATIC([DEFAULT]) ++# --------------------------- ++# implement the --enable-static flag ++# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. ++AC_DEFUN([AC_ENABLE_STATIC], ++[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl ++AC_ARG_ENABLE([static], ++ [AC_HELP_STRING([--enable-static@<:@=PKGS@:>@], ++ [build static libraries @<:@default=]AC_ENABLE_STATIC_DEFAULT[@:>@])], ++ [p=${PACKAGE-default} ++ case $enableval in ++ yes) enable_static=yes ;; ++ no) enable_static=no ;; ++ *) ++ enable_static=no ++ # Look at the argument we got. We use all the common list separators. ++ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," ++ for pkg in $enableval; do ++ IFS="$lt_save_ifs" ++ if test "X$pkg" = "X$p"; then ++ enable_static=yes ++ fi ++ done ++ IFS="$lt_save_ifs" ++ ;; ++ esac], ++ [enable_static=]AC_ENABLE_STATIC_DEFAULT) ++])# AC_ENABLE_STATIC ++ ++ ++# AC_DISABLE_STATIC ++# ----------------- ++# set the default static flag to --disable-static ++AC_DEFUN([AC_DISABLE_STATIC], ++[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl ++AC_ENABLE_STATIC(no) ++])# AC_DISABLE_STATIC ++ ++ ++# AC_ENABLE_FAST_INSTALL([DEFAULT]) ++# --------------------------------- ++# implement the --enable-fast-install flag ++# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. ++AC_DEFUN([AC_ENABLE_FAST_INSTALL], ++[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl ++AC_ARG_ENABLE([fast-install], ++ [AC_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], ++ [optimize for fast installation @<:@default=]AC_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], ++ [p=${PACKAGE-default} ++ case $enableval in ++ yes) enable_fast_install=yes ;; ++ no) enable_fast_install=no ;; ++ *) ++ enable_fast_install=no ++ # Look at the argument we got. We use all the common list separators. ++ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," ++ for pkg in $enableval; do ++ IFS="$lt_save_ifs" ++ if test "X$pkg" = "X$p"; then ++ enable_fast_install=yes ++ fi ++ done ++ IFS="$lt_save_ifs" ++ ;; ++ esac], ++ [enable_fast_install=]AC_ENABLE_FAST_INSTALL_DEFAULT) ++])# AC_ENABLE_FAST_INSTALL ++ ++ ++# AC_DISABLE_FAST_INSTALL ++# ----------------------- ++# set the default to --disable-fast-install ++AC_DEFUN([AC_DISABLE_FAST_INSTALL], ++[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl ++AC_ENABLE_FAST_INSTALL(no) ++])# AC_DISABLE_FAST_INSTALL ++ ++ ++# AC_LIBTOOL_PICMODE([MODE]) ++# -------------------------- ++# implement the --with-pic flag ++# MODE is either `yes' or `no'. If omitted, it defaults to `both'. ++AC_DEFUN([AC_LIBTOOL_PICMODE], ++[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl ++pic_mode=ifelse($#,1,$1,default) ++])# AC_LIBTOOL_PICMODE ++ ++ ++# AC_PROG_EGREP ++# ------------- ++# This is predefined starting with Autoconf 2.54, so this conditional ++# definition can be removed once we require Autoconf 2.54 or later. ++m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP], ++[AC_CACHE_CHECK([for egrep], [ac_cv_prog_egrep], ++ [if echo a | (grep -E '(a|b)') >/dev/null 2>&1 ++ then ac_cv_prog_egrep='grep -E' ++ else ac_cv_prog_egrep='egrep' ++ fi]) ++ EGREP=$ac_cv_prog_egrep ++ AC_SUBST([EGREP]) ++])]) ++ ++ ++# AC_PATH_TOOL_PREFIX ++# ------------------- ++# find a file program which can recognise shared library ++AC_DEFUN([AC_PATH_TOOL_PREFIX], ++[AC_REQUIRE([AC_PROG_EGREP])dnl ++AC_MSG_CHECKING([for $1]) ++AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, ++[case $MAGIC_CMD in ++[[\\/*] | ?:[\\/]*]) ++ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ++ ;; ++*) ++ lt_save_MAGIC_CMD="$MAGIC_CMD" ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++dnl $ac_dummy forces splitting on constant user-supplied paths. ++dnl POSIX.2 word splitting is done only on the output of word expansions, ++dnl not every word. This closes a longstanding sh security hole. ++ ac_dummy="ifelse([$2], , $PATH, [$2])" ++ for ac_dir in $ac_dummy; do ++ IFS="$lt_save_ifs" ++ test -z "$ac_dir" && ac_dir=. ++ if test -f $ac_dir/$1; then ++ lt_cv_path_MAGIC_CMD="$ac_dir/$1" ++ if test -n "$file_magic_test_file"; then ++ case $deplibs_check_method in ++ "file_magic "*) ++ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` ++ MAGIC_CMD="$lt_cv_path_MAGIC_CMD" ++ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | ++ $EGREP "$file_magic_regex" > /dev/null; then ++ : ++ else ++ cat <&2 ++ ++*** Warning: the command libtool uses to detect shared libraries, ++*** $file_magic_cmd, produces output that libtool cannot recognize. ++*** The result is that libtool may fail to recognize shared libraries ++*** as such. This will affect the creation of libtool libraries that ++*** depend on shared libraries, but programs linked with such libtool ++*** libraries will work regardless of this problem. Nevertheless, you ++*** may want to report the problem to your system manager and/or to ++*** bug-libtool@gnu.org ++ ++EOF ++ fi ;; ++ esac ++ fi ++ break ++ fi ++ done ++ IFS="$lt_save_ifs" ++ MAGIC_CMD="$lt_save_MAGIC_CMD" ++ ;; ++esac]) ++MAGIC_CMD="$lt_cv_path_MAGIC_CMD" ++if test -n "$MAGIC_CMD"; then ++ AC_MSG_RESULT($MAGIC_CMD) ++else ++ AC_MSG_RESULT(no) ++fi ++])# AC_PATH_TOOL_PREFIX ++ ++ ++# AC_PATH_MAGIC ++# ------------- ++# find a file program which can recognise a shared library ++AC_DEFUN([AC_PATH_MAGIC], ++[AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) ++if test -z "$lt_cv_path_MAGIC_CMD"; then ++ if test -n "$ac_tool_prefix"; then ++ AC_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) ++ else ++ MAGIC_CMD=: ++ fi ++fi ++])# AC_PATH_MAGIC ++ ++ ++# AC_PROG_LD ++# ---------- ++# find the pathname to the GNU or non-GNU linker ++AC_DEFUN([AC_PROG_LD], ++[AC_ARG_WITH([gnu-ld], ++ [AC_HELP_STRING([--with-gnu-ld], ++ [assume the C compiler uses GNU ld @<:@default=no@:>@])], ++ [test "$withval" = no || with_gnu_ld=yes], ++ [with_gnu_ld=no]) ++AC_REQUIRE([LT_AC_PROG_SED])dnl ++AC_REQUIRE([AC_PROG_CC])dnl ++AC_REQUIRE([AC_CANONICAL_HOST])dnl ++AC_REQUIRE([AC_CANONICAL_BUILD])dnl ++ac_prog=ld ++if test "$GCC" = yes; then ++ # Check if gcc -print-prog-name=ld gives a path. ++ AC_MSG_CHECKING([for ld used by $CC]) ++ case $host in ++ *-*-mingw*) ++ # gcc leaves a trailing carriage return which upsets mingw ++ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; ++ *) ++ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; ++ esac ++ case $ac_prog in ++ # Accept absolute paths. ++ [[\\/]]* | ?:[[\\/]]*) ++ re_direlt='/[[^/]][[^/]]*/\.\./' ++ # Canonicalize the pathname of ld ++ ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'` ++ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do ++ ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"` ++ done ++ test -z "$LD" && LD="$ac_prog" ++ ;; ++ "") ++ # If it fails, then pretend we aren't using GCC. ++ ac_prog=ld ++ ;; ++ *) ++ # If it is relative, then search for the first ld in PATH. ++ with_gnu_ld=unknown ++ ;; ++ esac ++elif test "$with_gnu_ld" = yes; then ++ AC_MSG_CHECKING([for GNU ld]) ++else ++ AC_MSG_CHECKING([for non-GNU ld]) ++fi ++AC_CACHE_VAL(lt_cv_path_LD, ++[if test -z "$LD"; then ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++ for ac_dir in $PATH; do ++ IFS="$lt_save_ifs" ++ test -z "$ac_dir" && ac_dir=. ++ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then ++ lt_cv_path_LD="$ac_dir/$ac_prog" ++ # Check to see if the program is GNU ld. I'd rather use --version, ++ # but apparently some variants of GNU ld only accept -v. ++ # Break only if it was the GNU/non-GNU ld that we prefer. ++ case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null; then ++ case $host_cpu in ++ i*86 ) ++ # Not sure whether the presence of OpenBSD here was a mistake. ++ # Let's accept both of them until this is cleared up. ++ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' ++ lt_cv_file_magic_cmd=/usr/bin/file ++ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ++ ;; ++ esac ++ else ++ lt_cv_deplibs_check_method=pass_all ++ fi ++ ;; ++ ++gnu*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++hpux10.20* | hpux11*) ++ lt_cv_file_magic_cmd=/usr/bin/file ++ case $host_cpu in ++ ia64*) ++ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' ++ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ++ ;; ++ hppa*64*) ++ [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'] ++ lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ++ ;; ++ *) ++ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library' ++ lt_cv_file_magic_test_file=/usr/lib/libc.sl ++ ;; ++ esac ++ ;; ++ ++interix3*) ++ # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here ++ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' ++ ;; ++ ++irix5* | irix6* | nonstopux*) ++ case $LD in ++ *-32|*"-32 ") libmagic=32-bit;; ++ *-n32|*"-n32 ") libmagic=N32;; ++ *-64|*"-64 ") libmagic=64-bit;; ++ *) libmagic=never-match;; ++ esac ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++# This must be Linux ELF. ++linux*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++netbsd*) ++ if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then ++ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' ++ else ++ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' ++ fi ++ ;; ++ ++newos6*) ++ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' ++ lt_cv_file_magic_cmd=/usr/bin/file ++ lt_cv_file_magic_test_file=/usr/lib/libnls.so ++ ;; ++ ++nto-qnx*) ++ lt_cv_deplibs_check_method=unknown ++ ;; ++ ++openbsd*) ++ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then ++ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' ++ else ++ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' ++ fi ++ ;; ++ ++osf3* | osf4* | osf5*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++solaris*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++sysv4 | sysv4.3*) ++ case $host_vendor in ++ motorola) ++ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' ++ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ++ ;; ++ ncr) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ sequent) ++ lt_cv_file_magic_cmd='/bin/file' ++ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ++ ;; ++ sni) ++ lt_cv_file_magic_cmd='/bin/file' ++ lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" ++ lt_cv_file_magic_test_file=/lib/libc.so ++ ;; ++ siemens) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ pc) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ esac ++ ;; ++ ++sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++esac ++]) ++file_magic_cmd=$lt_cv_file_magic_cmd ++deplibs_check_method=$lt_cv_deplibs_check_method ++test -z "$deplibs_check_method" && deplibs_check_method=unknown ++])# AC_DEPLIBS_CHECK_METHOD ++ ++ ++# AC_PROG_NM ++# ---------- ++# find the pathname to a BSD-compatible name lister ++AC_DEFUN([AC_PROG_NM], ++[AC_CACHE_CHECK([for BSD-compatible nm], lt_cv_path_NM, ++[if test -n "$NM"; then ++ # Let the user override the test. ++ lt_cv_path_NM="$NM" ++else ++ lt_nm_to_check="${ac_tool_prefix}nm" ++ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then ++ lt_nm_to_check="$lt_nm_to_check nm" ++ fi ++ for lt_tmp_nm in $lt_nm_to_check; do ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do ++ IFS="$lt_save_ifs" ++ test -z "$ac_dir" && ac_dir=. ++ tmp_nm="$ac_dir/$lt_tmp_nm" ++ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then ++ # Check to see if the nm accepts a BSD-compat flag. ++ # Adding the `sed 1q' prevents false positives on HP-UX, which says: ++ # nm: unknown option "B" ignored ++ # Tru64's nm complains that /dev/null is an invalid object file ++ case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in ++ */dev/null* | *'Invalid file or object type'*) ++ lt_cv_path_NM="$tmp_nm -B" ++ break ++ ;; ++ *) ++ case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in ++ */dev/null*) ++ lt_cv_path_NM="$tmp_nm -p" ++ break ++ ;; ++ *) ++ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but ++ continue # so that we can try to find one that supports BSD flags ++ ;; ++ esac ++ ;; ++ esac ++ fi ++ done ++ IFS="$lt_save_ifs" ++ done ++ test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm ++fi]) ++NM="$lt_cv_path_NM" ++])# AC_PROG_NM ++ ++ ++# AC_CHECK_LIBM ++# ------------- ++# check for math library ++AC_DEFUN([AC_CHECK_LIBM], ++[AC_REQUIRE([AC_CANONICAL_HOST])dnl ++LIBM= ++case $host in ++*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*) ++ # These system don't have libm, or don't need it ++ ;; ++*-ncr-sysv4.3*) ++ AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") ++ AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") ++ ;; ++*) ++ AC_CHECK_LIB(m, cos, LIBM="-lm") ++ ;; ++esac ++])# AC_CHECK_LIBM ++ ++ ++# AC_LIBLTDL_CONVENIENCE([DIRECTORY]) ++# ----------------------------------- ++# sets LIBLTDL to the link flags for the libltdl convenience library and ++# LTDLINCL to the include flags for the libltdl header and adds ++# --enable-ltdl-convenience to the configure arguments. Note that ++# AC_CONFIG_SUBDIRS is not called here. If DIRECTORY is not provided, ++# it is assumed to be `libltdl'. LIBLTDL will be prefixed with ++# '${top_builddir}/' and LTDLINCL will be prefixed with '${top_srcdir}/' ++# (note the single quotes!). If your package is not flat and you're not ++# using automake, define top_builddir and top_srcdir appropriately in ++# the Makefiles. ++AC_DEFUN([AC_LIBLTDL_CONVENIENCE], ++[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl ++ case $enable_ltdl_convenience in ++ no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;; ++ "") enable_ltdl_convenience=yes ++ ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; ++ esac ++ LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la ++ LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) ++ # For backwards non-gettext consistent compatibility... ++ INCLTDL="$LTDLINCL" ++])# AC_LIBLTDL_CONVENIENCE ++ ++ ++# AC_LIBLTDL_INSTALLABLE([DIRECTORY]) ++# ----------------------------------- ++# sets LIBLTDL to the link flags for the libltdl installable library and ++# LTDLINCL to the include flags for the libltdl header and adds ++# --enable-ltdl-install to the configure arguments. Note that ++# AC_CONFIG_SUBDIRS is not called here. If DIRECTORY is not provided, ++# and an installed libltdl is not found, it is assumed to be `libltdl'. ++# LIBLTDL will be prefixed with '${top_builddir}/'# and LTDLINCL with ++# '${top_srcdir}/' (note the single quotes!). If your package is not ++# flat and you're not using automake, define top_builddir and top_srcdir ++# appropriately in the Makefiles. ++# In the future, this macro may have to be called after AC_PROG_LIBTOOL. ++AC_DEFUN([AC_LIBLTDL_INSTALLABLE], ++[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl ++ AC_CHECK_LIB(ltdl, lt_dlinit, ++ [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no], ++ [if test x"$enable_ltdl_install" = xno; then ++ AC_MSG_WARN([libltdl not installed, but installation disabled]) ++ else ++ enable_ltdl_install=yes ++ fi ++ ]) ++ if test x"$enable_ltdl_install" = x"yes"; then ++ ac_configure_args="$ac_configure_args --enable-ltdl-install" ++ LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la ++ LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) ++ else ++ ac_configure_args="$ac_configure_args --enable-ltdl-install=no" ++ LIBLTDL="-lltdl" ++ LTDLINCL= ++ fi ++ # For backwards non-gettext consistent compatibility... ++ INCLTDL="$LTDLINCL" ++])# AC_LIBLTDL_INSTALLABLE ++ ++ ++# AC_LIBTOOL_CXX ++# -------------- ++# enable support for C++ libraries ++AC_DEFUN([AC_LIBTOOL_CXX], ++[AC_REQUIRE([_LT_AC_LANG_CXX]) ++])# AC_LIBTOOL_CXX ++ ++ ++# _LT_AC_LANG_CXX ++# --------------- ++AC_DEFUN([_LT_AC_LANG_CXX], ++[AC_REQUIRE([AC_PROG_CXX]) ++AC_REQUIRE([_LT_AC_PROG_CXXCPP]) ++_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}CXX]) ++])# _LT_AC_LANG_CXX ++ ++# _LT_AC_PROG_CXXCPP ++# ------------------ ++AC_DEFUN([_LT_AC_PROG_CXXCPP], ++[ ++AC_REQUIRE([AC_PROG_CXX]) ++if test -n "$CXX" && ( test "X$CXX" != "Xno" && ++ ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || ++ (test "X$CXX" != "Xg++"))) ; then ++ AC_PROG_CXXCPP ++fi ++])# _LT_AC_PROG_CXXCPP ++ ++# AC_LIBTOOL_F77 ++# -------------- ++# enable support for Fortran 77 libraries ++AC_DEFUN([AC_LIBTOOL_F77], ++[AC_REQUIRE([_LT_AC_LANG_F77]) ++])# AC_LIBTOOL_F77 ++ ++ ++# _LT_AC_LANG_F77 ++# --------------- ++AC_DEFUN([_LT_AC_LANG_F77], ++[AC_REQUIRE([AC_PROG_F77]) ++_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}F77]) ++])# _LT_AC_LANG_F77 ++ ++ ++# AC_LIBTOOL_GCJ ++# -------------- ++# enable support for GCJ libraries ++AC_DEFUN([AC_LIBTOOL_GCJ], ++[AC_REQUIRE([_LT_AC_LANG_GCJ]) ++])# AC_LIBTOOL_GCJ ++ ++ ++# _LT_AC_LANG_GCJ ++# --------------- ++AC_DEFUN([_LT_AC_LANG_GCJ], ++[AC_PROVIDE_IFELSE([AC_PROG_GCJ],[], ++ [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],[], ++ [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ],[], ++ [ifdef([AC_PROG_GCJ],[AC_REQUIRE([AC_PROG_GCJ])], ++ [ifdef([A][M_PROG_GCJ],[AC_REQUIRE([A][M_PROG_GCJ])], ++ [AC_REQUIRE([A][C_PROG_GCJ_OR_A][M_PROG_GCJ])])])])])]) ++_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}GCJ]) ++])# _LT_AC_LANG_GCJ ++ ++ ++# AC_LIBTOOL_RC ++# ------------- ++# enable support for Windows resource files ++AC_DEFUN([AC_LIBTOOL_RC], ++[AC_REQUIRE([LT_AC_PROG_RC]) ++_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}RC]) ++])# AC_LIBTOOL_RC ++ ++ ++# AC_LIBTOOL_LANG_C_CONFIG ++# ------------------------ ++# Ensure that the configuration vars for the C compiler are ++# suitably defined. Those variables are subsequently used by ++# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. ++AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG], [_LT_AC_LANG_C_CONFIG]) ++AC_DEFUN([_LT_AC_LANG_C_CONFIG], ++[lt_save_CC="$CC" ++AC_LANG_PUSH(C) ++ ++# Source file extension for C test sources. ++ac_ext=c ++ ++# Object file extension for compiled C test sources. ++objext=o ++_LT_AC_TAGVAR(objext, $1)=$objext ++ ++# Code to be used in simple compile tests ++lt_simple_compile_test_code="int some_variable = 0;\n" ++ ++# Code to be used in simple link tests ++lt_simple_link_test_code='int main(){return(0);}\n' ++ ++_LT_AC_SYS_COMPILER ++ ++# save warnings/boilerplate of simple test code ++_LT_COMPILER_BOILERPLATE ++_LT_LINKER_BOILERPLATE ++ ++AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1) ++AC_LIBTOOL_PROG_COMPILER_PIC($1) ++AC_LIBTOOL_PROG_CC_C_O($1) ++AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) ++AC_LIBTOOL_PROG_LD_SHLIBS($1) ++AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) ++AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) ++AC_LIBTOOL_SYS_LIB_STRIP ++AC_LIBTOOL_DLOPEN_SELF ++ ++# Report which library types will actually be built ++AC_MSG_CHECKING([if libtool supports shared libraries]) ++AC_MSG_RESULT([$can_build_shared]) ++ ++AC_MSG_CHECKING([whether to build shared libraries]) ++test "$can_build_shared" = "no" && enable_shared=no ++ ++# On AIX, shared libraries and static libraries use the same namespace, and ++# are all built from PIC. ++case $host_os in ++aix3*) ++ test "$enable_shared" = yes && enable_static=no ++ if test -n "$RANLIB"; then ++ archive_cmds="$archive_cmds~\$RANLIB \$lib" ++ postinstall_cmds='$RANLIB $lib' ++ fi ++ ;; ++ ++aix4* | aix5*) ++ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then ++ test "$enable_shared" = yes && enable_static=no ++ fi ++ ;; ++esac ++AC_MSG_RESULT([$enable_shared]) ++ ++AC_MSG_CHECKING([whether to build static libraries]) ++# Make sure either enable_shared or enable_static is yes. ++test "$enable_shared" = yes || enable_static=yes ++AC_MSG_RESULT([$enable_static]) ++ ++AC_LIBTOOL_CONFIG($1) ++ ++AC_LANG_POP ++CC="$lt_save_CC" ++])# AC_LIBTOOL_LANG_C_CONFIG ++ ++ ++# AC_LIBTOOL_LANG_CXX_CONFIG ++# -------------------------- ++# Ensure that the configuration vars for the C compiler are ++# suitably defined. Those variables are subsequently used by ++# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. ++AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG], [_LT_AC_LANG_CXX_CONFIG(CXX)]) ++AC_DEFUN([_LT_AC_LANG_CXX_CONFIG], ++[AC_LANG_PUSH(C++) ++AC_REQUIRE([AC_PROG_CXX]) ++AC_REQUIRE([_LT_AC_PROG_CXXCPP]) ++ ++_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ++_LT_AC_TAGVAR(allow_undefined_flag, $1)= ++_LT_AC_TAGVAR(always_export_symbols, $1)=no ++_LT_AC_TAGVAR(archive_expsym_cmds, $1)= ++_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= ++_LT_AC_TAGVAR(hardcode_direct, $1)=no ++_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= ++_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= ++_LT_AC_TAGVAR(hardcode_libdir_separator, $1)= ++_LT_AC_TAGVAR(hardcode_minus_L, $1)=no ++_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported ++_LT_AC_TAGVAR(hardcode_automatic, $1)=no ++_LT_AC_TAGVAR(module_cmds, $1)= ++_LT_AC_TAGVAR(module_expsym_cmds, $1)= ++_LT_AC_TAGVAR(link_all_deplibs, $1)=unknown ++_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds ++_LT_AC_TAGVAR(no_undefined_flag, $1)= ++_LT_AC_TAGVAR(whole_archive_flag_spec, $1)= ++_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no ++ ++# Dependencies to place before and after the object being linked: ++_LT_AC_TAGVAR(predep_objects, $1)= ++_LT_AC_TAGVAR(postdep_objects, $1)= ++_LT_AC_TAGVAR(predeps, $1)= ++_LT_AC_TAGVAR(postdeps, $1)= ++_LT_AC_TAGVAR(compiler_lib_search_path, $1)= ++ ++# Source file extension for C++ test sources. ++ac_ext=cpp ++ ++# Object file extension for compiled C++ test sources. ++objext=o ++_LT_AC_TAGVAR(objext, $1)=$objext ++ ++# Code to be used in simple compile tests ++lt_simple_compile_test_code="int some_variable = 0;\n" ++ ++# Code to be used in simple link tests ++lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }\n' ++ ++# ltmain only uses $CC for tagged configurations so make sure $CC is set. ++_LT_AC_SYS_COMPILER ++ ++# save warnings/boilerplate of simple test code ++_LT_COMPILER_BOILERPLATE ++_LT_LINKER_BOILERPLATE ++ ++# Allow CC to be a program name with arguments. ++lt_save_CC=$CC ++lt_save_LD=$LD ++lt_save_GCC=$GCC ++GCC=$GXX ++lt_save_with_gnu_ld=$with_gnu_ld ++lt_save_path_LD=$lt_cv_path_LD ++if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then ++ lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx ++else ++ $as_unset lt_cv_prog_gnu_ld ++fi ++if test -n "${lt_cv_path_LDCXX+set}"; then ++ lt_cv_path_LD=$lt_cv_path_LDCXX ++else ++ $as_unset lt_cv_path_LD ++fi ++test -z "${LDCXX+set}" || LD=$LDCXX ++CC=${CXX-"c++"} ++compiler=$CC ++_LT_AC_TAGVAR(compiler, $1)=$CC ++_LT_CC_BASENAME([$compiler]) ++ ++# We don't want -fno-exception wen compiling C++ code, so set the ++# no_builtin_flag separately ++if test "$GXX" = yes; then ++ _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ++else ++ _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= ++fi ++ ++if test "$GXX" = yes; then ++ # Set up default GNU C++ configuration ++ ++ AC_PROG_LD ++ ++ # Check if GNU C++ uses GNU ld as the underlying linker, since the ++ # archiving commands below assume that GNU ld is being used. ++ if test "$with_gnu_ld" = yes; then ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' ++ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' ++ ++ # If archive_cmds runs LD, not CC, wlarc should be empty ++ # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to ++ # investigate it a little bit more. (MM) ++ wlarc='${wl}' ++ ++ # ancient GNU ld didn't support --whole-archive et. al. ++ if eval "`$CC -print-prog-name=ld` --help 2>&1" | \ ++ grep 'no-whole-archive' > /dev/null; then ++ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' ++ else ++ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= ++ fi ++ else ++ with_gnu_ld=no ++ wlarc= ++ ++ # A generic and very simple default shared library creation ++ # command for GNU C++ for the case where it uses the native ++ # linker, instead of GNU ld. If possible, this setting should ++ # overridden to take advantage of the native linker features on ++ # the platform it is being used on. ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' ++ fi ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' ++ ++else ++ GXX=no ++ with_gnu_ld=no ++ wlarc= ++fi ++ ++# PORTME: fill in a description of your system's C++ link characteristics ++AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) ++_LT_AC_TAGVAR(ld_shlibs, $1)=yes ++case $host_os in ++ aix3*) ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ aix4* | aix5*) ++ if test "$host_cpu" = ia64; then ++ # On IA64, the linker does run time linking by default, so we don't ++ # have to do anything special. ++ aix_use_runtimelinking=no ++ exp_sym_flag='-Bexport' ++ no_entry_flag="" ++ else ++ aix_use_runtimelinking=no ++ ++ # Test if we are trying to use run time linking or normal ++ # AIX style linking. If -brtl is somewhere in LDFLAGS, we ++ # need to do runtime linking. ++ case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*) ++ for ld_flag in $LDFLAGS; do ++ case $ld_flag in ++ *-brtl*) ++ aix_use_runtimelinking=yes ++ break ++ ;; ++ esac ++ done ++ ;; ++ esac ++ ++ exp_sym_flag='-bexport' ++ no_entry_flag='-bnoentry' ++ fi ++ ++ # When large executables or shared objects are built, AIX ld can ++ # have problems creating the table of contents. If linking a library ++ # or program results in "error TOC overflow" add -mminimal-toc to ++ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not ++ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. ++ ++ _LT_AC_TAGVAR(archive_cmds, $1)='' ++ _LT_AC_TAGVAR(hardcode_direct, $1)=yes ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' ++ _LT_AC_TAGVAR(link_all_deplibs, $1)=yes ++ ++ if test "$GXX" = yes; then ++ case $host_os in aix4.[[012]]|aix4.[[012]].*) ++ # We only want to do this on AIX 4.2 and lower, the check ++ # below for broken collect2 doesn't work under 4.3+ ++ collect2name=`${CC} -print-prog-name=collect2` ++ if test -f "$collect2name" && \ ++ strings "$collect2name" | grep resolve_lib_name >/dev/null ++ then ++ # We have reworked collect2 ++ _LT_AC_TAGVAR(hardcode_direct, $1)=yes ++ else ++ # We have old collect2 ++ _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported ++ # It fails to find uninstalled libraries when the uninstalled ++ # path is not listed in the libpath. Setting hardcode_minus_L ++ # to unsupported forces relinking ++ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= ++ fi ++ ;; ++ esac ++ shared_flag='-shared' ++ if test "$aix_use_runtimelinking" = yes; then ++ shared_flag="$shared_flag "'${wl}-G' ++ fi ++ else ++ # not using gcc ++ if test "$host_cpu" = ia64; then ++ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release ++ # chokes on -Wl,-G. The following line is correct: ++ shared_flag='-G' ++ else ++ if test "$aix_use_runtimelinking" = yes; then ++ shared_flag='${wl}-G' ++ else ++ shared_flag='${wl}-bM:SRE' ++ fi ++ fi ++ fi ++ ++ # It seems that -bexpall does not export symbols beginning with ++ # underscore (_), so it is better to generate a list of symbols to export. ++ _LT_AC_TAGVAR(always_export_symbols, $1)=yes ++ if test "$aix_use_runtimelinking" = yes; then ++ # Warning - without using the other runtime loading flags (-brtl), ++ # -berok will link without error, but may produce a broken library. ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok' ++ # Determine the default libpath from the value encoded in an empty executable. ++ _LT_AC_SYS_LIBPATH_AIX ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" ++ ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" ++ else ++ if test "$host_cpu" = ia64; then ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs" ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" ++ else ++ # Determine the default libpath from the value encoded in an empty executable. ++ _LT_AC_SYS_LIBPATH_AIX ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" ++ # Warning - without using the other run time loading flags, ++ # -berok will link without error, but may produce a broken library. ++ _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' ++ # Exported symbols can be pulled into shared objects from archives ++ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='$convenience' ++ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes ++ # This is similar to how AIX traditionally builds its shared libraries. ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' ++ fi ++ fi ++ ;; ++ ++ beos*) ++ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported ++ # Joseph Beckenbach says some releases of gcc ++ # support --undefined. This deserves some investigation. FIXME ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ else ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ ++ chorus*) ++ case $cc_basename in ++ *) ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ esac ++ ;; ++ ++ cygwin* | mingw* | pw32*) ++ # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, ++ # as there is no search path for DLLs. ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported ++ _LT_AC_TAGVAR(always_export_symbols, $1)=no ++ _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ++ ++ if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' ++ # If the export-symbols file already is a .def file (1st line ++ # is EXPORTS), use it as is; otherwise, prepend... ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then ++ cp $export_symbols $output_objdir/$soname.def; ++ else ++ echo EXPORTS > $output_objdir/$soname.def; ++ cat $export_symbols >> $output_objdir/$soname.def; ++ fi~ ++ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' ++ else ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ darwin* | rhapsody*) ++ case $host_os in ++ rhapsody* | darwin1.[[012]]) ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress' ++ ;; ++ *) # Darwin 1.3 on ++ if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ++ else ++ case ${MACOSX_DEPLOYMENT_TARGET} in ++ 10.[[012]]) ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ++ ;; ++ 10.*) ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}dynamic_lookup' ++ ;; ++ esac ++ fi ++ ;; ++ esac ++ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ++ _LT_AC_TAGVAR(hardcode_direct, $1)=no ++ _LT_AC_TAGVAR(hardcode_automatic, $1)=yes ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported ++ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='' ++ _LT_AC_TAGVAR(link_all_deplibs, $1)=yes ++ ++ if test "$GXX" = yes ; then ++ lt_int_apple_cc_single_mod=no ++ output_verbose_link_cmd='echo' ++ if $CC -dumpspecs 2>&1 | $EGREP 'single_module' >/dev/null ; then ++ lt_int_apple_cc_single_mod=yes ++ fi ++ if test "X$lt_int_apple_cc_single_mod" = Xyes ; then ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' ++ else ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' ++ fi ++ _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' ++ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds ++ if test "X$lt_int_apple_cc_single_mod" = Xyes ; then ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ else ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ fi ++ _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ else ++ case $cc_basename in ++ xlc*) ++ output_verbose_link_cmd='echo' ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' ++ _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' ++ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ ;; ++ *) ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ esac ++ fi ++ ;; ++ ++ dgux*) ++ case $cc_basename in ++ ec++*) ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ ghcx*) ++ # Green Hills C++ Compiler ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ *) ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ esac ++ ;; ++ freebsd[[12]]*) ++ # C++ shared libraries reported to be fairly broken before switch to ELF ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ freebsd-elf*) ++ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ++ ;; ++ freebsd* | kfreebsd*-gnu | dragonfly*) ++ # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF ++ # conventions ++ _LT_AC_TAGVAR(ld_shlibs, $1)=yes ++ ;; ++ gnu*) ++ ;; ++ hpux9*) ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ++ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ++ _LT_AC_TAGVAR(hardcode_direct, $1)=yes ++ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, ++ # but as the default ++ # location of the library. ++ ++ case $cc_basename in ++ CC*) ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ aCC*) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ # ++ # There doesn't appear to be a way to prevent this compiler from ++ # explicitly linking system object files so we need to strip them ++ # from the output so that they don't get included in the library ++ # dependencies. ++ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "[[-]]L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ++ ;; ++ *) ++ if test "$GXX" = yes; then ++ _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ++ else ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ esac ++ ;; ++ hpux10*|hpux11*) ++ if test $with_gnu_ld = no; then ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ++ ++ case $host_cpu in ++ hppa*64*|ia64*) ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' ++ ;; ++ *) ++ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ++ ;; ++ esac ++ fi ++ case $host_cpu in ++ hppa*64*|ia64*) ++ _LT_AC_TAGVAR(hardcode_direct, $1)=no ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ *) ++ _LT_AC_TAGVAR(hardcode_direct, $1)=yes ++ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, ++ # but as the default ++ # location of the library. ++ ;; ++ esac ++ ++ case $cc_basename in ++ CC*) ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ aCC*) ++ case $host_cpu in ++ hppa*64*) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ ;; ++ ia64*) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ ;; ++ *) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ ;; ++ esac ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ # ++ # There doesn't appear to be a way to prevent this compiler from ++ # explicitly linking system object files so we need to strip them ++ # from the output so that they don't get included in the library ++ # dependencies. ++ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ++ ;; ++ *) ++ if test "$GXX" = yes; then ++ if test $with_gnu_ld = no; then ++ case $host_cpu in ++ hppa*64*) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ ;; ++ ia64*) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ ;; ++ *) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ ;; ++ esac ++ fi ++ else ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ esac ++ ;; ++ interix3*) ++ _LT_AC_TAGVAR(hardcode_direct, $1)=no ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' ++ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ++ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. ++ # Instead, shared libraries are loaded at an image base (0x10000000 by ++ # default) and relocated if they conflict, which is a slow very memory ++ # consuming and fragmenting process. To avoid this, we pick a random, ++ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link ++ # time. Moving up from 0x10000000 also allows more sbrk(2) space. ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ++ ;; ++ irix5* | irix6*) ++ case $cc_basename in ++ CC*) ++ # SGI C++ ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' ++ ++ # Archives containing C++ object files must be created using ++ # "CC -ar", where "CC" is the IRIX C++ compiler. This is ++ # necessary to make sure instantiated templates are included ++ # in the archive. ++ _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' ++ ;; ++ *) ++ if test "$GXX" = yes; then ++ if test "$with_gnu_ld" = no; then ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ else ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib' ++ fi ++ fi ++ _LT_AC_TAGVAR(link_all_deplibs, $1)=yes ++ ;; ++ esac ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ++ ;; ++ linux*) ++ case $cc_basename in ++ KCC*) ++ # Kuck and Associates, Inc. (KAI) C++ Compiler ++ ++ # KCC will only create a shared library if the output file ++ # ends with ".so" (or ".sl" for HP-UX), so rename the library ++ # to its proper name (with version) after linking. ++ _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ # ++ # There doesn't appear to be a way to prevent this compiler from ++ # explicitly linking system object files so we need to strip them ++ # from the output so that they don't get included in the library ++ # dependencies. ++ output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ++ ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath,$libdir' ++ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' ++ ++ # Archives containing C++ object files must be created using ++ # "CC -Bstatic", where "CC" is the KAI C++ compiler. ++ _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ++ ;; ++ icpc*) ++ # Intel C++ ++ with_gnu_ld=yes ++ # version 8.0 and above of icpc choke on multiply defined symbols ++ # if we add $predep_objects and $postdep_objects, however 7.1 and ++ # earlier do not add the objects themselves. ++ case `$CC -V 2>&1` in ++ *"Version 7."*) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ ;; ++ *) # Version 8.0 or newer ++ tmp_idyn= ++ case $host_cpu in ++ ia64*) tmp_idyn=' -i_dynamic';; ++ esac ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ ;; ++ esac ++ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' ++ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' ++ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' ++ ;; ++ pgCC*) ++ # Portland Group C++ compiler ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ++ ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' ++ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' ++ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' ++ ;; ++ cxx*) ++ # Compaq C++ ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' ++ ++ runpath_var=LD_RUN_PATH ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ # ++ # There doesn't appear to be a way to prevent this compiler from ++ # explicitly linking system object files so we need to strip them ++ # from the output so that they don't get included in the library ++ # dependencies. ++ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ++ ;; ++ esac ++ ;; ++ lynxos*) ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ m88k*) ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ mvs*) ++ case $cc_basename in ++ cxx*) ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ *) ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ esac ++ ;; ++ netbsd*) ++ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then ++ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' ++ wlarc= ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ++ _LT_AC_TAGVAR(hardcode_direct, $1)=yes ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ fi ++ # Workaround some broken pre-1.5 toolchains ++ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ++ ;; ++ openbsd2*) ++ # C++ shared libraries are fairly broken ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ openbsd*) ++ _LT_AC_TAGVAR(hardcode_direct, $1)=yes ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' ++ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' ++ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ++ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' ++ fi ++ output_verbose_link_cmd='echo' ++ ;; ++ osf3*) ++ case $cc_basename in ++ KCC*) ++ # Kuck and Associates, Inc. (KAI) C++ Compiler ++ ++ # KCC will only create a shared library if the output file ++ # ends with ".so" (or ".sl" for HP-UX), so rename the library ++ # to its proper name (with version) after linking. ++ _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' ++ ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ++ ++ # Archives containing C++ object files must be created using ++ # "CC -Bstatic", where "CC" is the KAI C++ compiler. ++ _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ++ ++ ;; ++ RCC*) ++ # Rational C++ 2.4.1 ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ cxx*) ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' ++ ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ # ++ # There doesn't appear to be a way to prevent this compiler from ++ # explicitly linking system object files so we need to strip them ++ # from the output so that they don't get included in the library ++ # dependencies. ++ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ++ ;; ++ *) ++ if test "$GXX" = yes && test "$with_gnu_ld" = no; then ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' ++ ++ else ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ esac ++ ;; ++ osf4* | osf5*) ++ case $cc_basename in ++ KCC*) ++ # Kuck and Associates, Inc. (KAI) C++ Compiler ++ ++ # KCC will only create a shared library if the output file ++ # ends with ".so" (or ".sl" for HP-UX), so rename the library ++ # to its proper name (with version) after linking. ++ _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' ++ ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ++ ++ # Archives containing C++ object files must be created using ++ # the KAI C++ compiler. ++ _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ++ ;; ++ RCC*) ++ # Rational C++ 2.4.1 ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ cxx*) ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ ++ echo "-hidden">> $lib.exp~ ++ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~ ++ $rm $lib.exp' ++ ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ # ++ # There doesn't appear to be a way to prevent this compiler from ++ # explicitly linking system object files so we need to strip them ++ # from the output so that they don't get included in the library ++ # dependencies. ++ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ++ ;; ++ *) ++ if test "$GXX" = yes && test "$with_gnu_ld" = no; then ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' ++ ++ else ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ esac ++ ;; ++ psos*) ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ sunos4*) ++ case $cc_basename in ++ CC*) ++ # Sun C++ 4.x ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ lcc*) ++ # Lucid ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ *) ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ esac ++ ;; ++ solaris*) ++ case $cc_basename in ++ CC*) ++ # Sun C++ 4.2, 5.x and Centerline C++ ++ _LT_AC_TAGVAR(archive_cmds_need_lc,$1)=yes ++ _LT_AC_TAGVAR(no_undefined_flag, $1)=' -zdefs' ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ ++ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' ++ ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ case $host_os in ++ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; ++ *) ++ # The C++ compiler is used as linker so we must use $wl ++ # flag to pass the commands to the underlying system ++ # linker. We must also pass each convience library through ++ # to the system linker between allextract/defaultextract. ++ # The C++ compiler will combine linker options so we ++ # cannot just pass the convience library names through ++ # without $wl. ++ # Supported since Solaris 2.6 (maybe 2.5.1?) ++ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ++ ;; ++ esac ++ _LT_AC_TAGVAR(link_all_deplibs, $1)=yes ++ ++ output_verbose_link_cmd='echo' ++ ++ # Archives containing C++ object files must be created using ++ # "CC -xar", where "CC" is the Sun C++ compiler. This is ++ # necessary to make sure instantiated templates are included ++ # in the archive. ++ _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ++ ;; ++ gcx*) ++ # Green Hills C++ Compiler ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' ++ ++ # The C++ compiler must be used to create the archive. ++ _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ++ ;; ++ *) ++ # GNU C++ compiler with Solaris linker ++ if test "$GXX" = yes && test "$with_gnu_ld" = no; then ++ _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' ++ if $CC --version | grep -v '^2\.7' > /dev/null; then ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ ++ $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" ++ else ++ # g++ 2.7 appears to require `-G' NOT `-shared' on this ++ # platform. ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ ++ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" ++ fi ++ ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' ++ fi ++ ;; ++ esac ++ ;; ++ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) ++ _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' ++ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ runpath_var='LD_RUN_PATH' ++ ++ case $cc_basename in ++ CC*) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ *) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ esac ++ ;; ++ sysv5* | sco3.2v5* | sco5v6*) ++ # Note: We can NOT use -z defs as we might desire, because we do not ++ # link with -lc, and that would cause any symbols used from libc to ++ # always be unresolved, which means just about no library would ++ # ever link correctly. If we're not using GNU ld we use -z text ++ # though, which does catch some bad symbols but isn't as heavy-handed ++ # as -z defs. ++ # For security reasons, it is highly recommended that you always ++ # use absolute paths for naming shared libraries, and exclude the ++ # DT_RUNPATH tag from executables and libraries. But doing so ++ # requires that you compile everything twice, which is a pain. ++ # So that behaviour is only enabled if SCOABSPATH is set to a ++ # non-empty value in the environment. Most likely only useful for ++ # creating official distributions of packages. ++ # This is a hack until libtool officially supports absolute path ++ # names for shared libraries. ++ _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' ++ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' ++ _LT_AC_TAGVAR(link_all_deplibs, $1)=yes ++ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' ++ runpath_var='LD_RUN_PATH' ++ ++ case $cc_basename in ++ CC*) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ *) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ esac ++ ;; ++ tandem*) ++ case $cc_basename in ++ NCC*) ++ # NonStop-UX NCC 3.20 ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ *) ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ esac ++ ;; ++ vxworks*) ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ *) ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++esac ++AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)]) ++test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no ++ ++_LT_AC_TAGVAR(GCC, $1)="$GXX" ++_LT_AC_TAGVAR(LD, $1)="$LD" ++ ++AC_LIBTOOL_POSTDEP_PREDEP($1) ++AC_LIBTOOL_PROG_COMPILER_PIC($1) ++AC_LIBTOOL_PROG_CC_C_O($1) ++AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) ++AC_LIBTOOL_PROG_LD_SHLIBS($1) ++AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) ++AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) ++ ++AC_LIBTOOL_CONFIG($1) ++ ++AC_LANG_POP ++CC=$lt_save_CC ++LDCXX=$LD ++LD=$lt_save_LD ++GCC=$lt_save_GCC ++with_gnu_ldcxx=$with_gnu_ld ++with_gnu_ld=$lt_save_with_gnu_ld ++lt_cv_path_LDCXX=$lt_cv_path_LD ++lt_cv_path_LD=$lt_save_path_LD ++lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld ++lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld ++])# AC_LIBTOOL_LANG_CXX_CONFIG ++ ++# AC_LIBTOOL_POSTDEP_PREDEP([TAGNAME]) ++# ------------------------------------ ++# Figure out "hidden" library dependencies from verbose ++# compiler output when linking a shared library. ++# Parse the compiler output and extract the necessary ++# objects, libraries and library flags. ++AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP],[ ++dnl we can't use the lt_simple_compile_test_code here, ++dnl because it contains code intended for an executable, ++dnl not a library. It's possible we should let each ++dnl tag define a new lt_????_link_test_code variable, ++dnl but it's only used here... ++ifelse([$1],[],[cat > conftest.$ac_ext < conftest.$ac_ext < conftest.$ac_ext < conftest.$ac_ext <> "$cfgfile" ++ifelse([$1], [], ++[#! $SHELL ++ ++# `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services. ++# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) ++# NOTE: Changes made to this file will be lost: look at ltmain.sh. ++# ++# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 ++# Free Software Foundation, Inc. ++# ++# This file is part of GNU Libtool: ++# Originally by Gordon Matzigkeit , 1996 ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++# ++# As a special exception to the GNU General Public License, if you ++# distribute this file as part of a program that contains a ++# configuration script generated by Autoconf, you may include it under ++# the same distribution terms that you use for the rest of that program. ++ ++# A sed program that does not truncate output. ++SED=$lt_SED ++ ++# Sed that helps us avoid accidentally triggering echo(1) options like -n. ++Xsed="$SED -e 1s/^X//" ++ ++# The HP-UX ksh and POSIX shell print the target directory to stdout ++# if CDPATH is set. ++(unset CDPATH) >/dev/null 2>&1 && unset CDPATH ++ ++# The names of the tagged configurations supported by this script. ++available_tags= ++ ++# ### BEGIN LIBTOOL CONFIG], ++[# ### BEGIN LIBTOOL TAG CONFIG: $tagname]) ++ ++# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: ++ ++# Shell to use when invoking shell scripts. ++SHELL=$lt_SHELL ++ ++# Whether or not to build shared libraries. ++build_libtool_libs=$enable_shared ++ ++# Whether or not to build static libraries. ++build_old_libs=$enable_static ++ ++# Whether or not to add -lc for building shared libraries. ++build_libtool_need_lc=$_LT_AC_TAGVAR(archive_cmds_need_lc, $1) ++ ++# Whether or not to disallow shared libs when runtime libs are static ++allow_libtool_libs_with_static_runtimes=$_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1) ++ ++# Whether or not to optimize for fast installation. ++fast_install=$enable_fast_install ++ ++# The host system. ++host_alias=$host_alias ++host=$host ++host_os=$host_os ++ ++# The build system. ++build_alias=$build_alias ++build=$build ++build_os=$build_os ++ ++# An echo program that does not interpret backslashes. ++echo=$lt_echo ++ ++# The archiver. ++AR=$lt_AR ++AR_FLAGS=$lt_AR_FLAGS ++ ++# A C compiler. ++LTCC=$lt_LTCC ++ ++# LTCC compiler flags. ++LTCFLAGS=$lt_LTCFLAGS ++ ++# A language-specific compiler. ++CC=$lt_[]_LT_AC_TAGVAR(compiler, $1) ++ ++# Is the compiler the GNU C compiler? ++with_gcc=$_LT_AC_TAGVAR(GCC, $1) ++ ++gcc_dir=\`gcc -print-file-name=. | $SED 's,/\.$,,'\` ++gcc_ver=\`gcc -dumpversion\` ++ ++# An ERE matcher. ++EGREP=$lt_EGREP ++ ++# The linker used to build libraries. ++LD=$lt_[]_LT_AC_TAGVAR(LD, $1) ++ ++# Whether we need hard or soft links. ++LN_S=$lt_LN_S ++ ++# A BSD-compatible nm program. ++NM=$lt_NM ++ ++# A symbol stripping program ++STRIP=$lt_STRIP ++ ++# Used to examine libraries when file_magic_cmd begins "file" ++MAGIC_CMD=$MAGIC_CMD ++ ++# Used on cygwin: DLL creation program. ++DLLTOOL="$DLLTOOL" ++ ++# Used on cygwin: object dumper. ++OBJDUMP="$OBJDUMP" ++ ++# Used on cygwin: assembler. ++AS="$AS" ++ ++# The name of the directory that contains temporary libtool files. ++objdir=$objdir ++ ++# How to create reloadable object files. ++reload_flag=$lt_reload_flag ++reload_cmds=$lt_reload_cmds ++ ++# How to pass a linker flag through the compiler. ++wl=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) ++ ++# Object file suffix (normally "o"). ++objext="$ac_objext" ++ ++# Old archive suffix (normally "a"). ++libext="$libext" ++ ++# Shared library suffix (normally ".so"). ++shrext_cmds='$shrext_cmds' ++ ++# Executable file suffix (normally ""). ++exeext="$exeext" ++ ++# Additional compiler flags for building library objects. ++pic_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) ++pic_mode=$pic_mode ++ ++# What is the maximum length of a command? ++max_cmd_len=$lt_cv_sys_max_cmd_len ++ ++# Does compiler simultaneously support -c and -o options? ++compiler_c_o=$lt_[]_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1) ++ ++# Must we lock files when doing compilation? ++need_locks=$lt_need_locks ++ ++# Do we need the lib prefix for modules? ++need_lib_prefix=$need_lib_prefix ++ ++# Do we need a version for libraries? ++need_version=$need_version ++ ++# Whether dlopen is supported. ++dlopen_support=$enable_dlopen ++ ++# Whether dlopen of programs is supported. ++dlopen_self=$enable_dlopen_self ++ ++# Whether dlopen of statically linked programs is supported. ++dlopen_self_static=$enable_dlopen_self_static ++ ++# Compiler flag to prevent dynamic linking. ++link_static_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_static, $1) ++ ++# Compiler flag to turn off builtin functions. ++no_builtin_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) ++ ++# Compiler flag to allow reflexive dlopens. ++export_dynamic_flag_spec=$lt_[]_LT_AC_TAGVAR(export_dynamic_flag_spec, $1) ++ ++# Compiler flag to generate shared objects directly from archives. ++whole_archive_flag_spec=$lt_[]_LT_AC_TAGVAR(whole_archive_flag_spec, $1) ++ ++# Compiler flag to generate thread-safe objects. ++thread_safe_flag_spec=$lt_[]_LT_AC_TAGVAR(thread_safe_flag_spec, $1) ++ ++# Library versioning type. ++version_type=$version_type ++ ++# Format of library name prefix. ++libname_spec=$lt_libname_spec ++ ++# List of archive names. First name is the real one, the rest are links. ++# The last name is the one that the linker finds with -lNAME. ++library_names_spec=$lt_library_names_spec ++ ++# The coded name of the library, if different from the real name. ++soname_spec=$lt_soname_spec ++ ++# Commands used to build and install an old-style archive. ++RANLIB=$lt_RANLIB ++old_archive_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_cmds, $1) ++old_postinstall_cmds=$lt_old_postinstall_cmds ++old_postuninstall_cmds=$lt_old_postuninstall_cmds ++ ++# Create an old-style archive from a shared archive. ++old_archive_from_new_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_new_cmds, $1) ++ ++# Create a temporary old-style archive to link instead of a shared archive. ++old_archive_from_expsyms_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) ++ ++# Commands used to build and install a shared archive. ++archive_cmds=$lt_[]_LT_AC_TAGVAR(archive_cmds, $1) ++archive_expsym_cmds=$lt_[]_LT_AC_TAGVAR(archive_expsym_cmds, $1) ++postinstall_cmds=$lt_postinstall_cmds ++postuninstall_cmds=$lt_postuninstall_cmds ++ ++# Commands used to build a loadable module (assumed same as above if empty) ++module_cmds=$lt_[]_LT_AC_TAGVAR(module_cmds, $1) ++module_expsym_cmds=$lt_[]_LT_AC_TAGVAR(module_expsym_cmds, $1) ++ ++# Commands to strip libraries. ++old_striplib=$lt_old_striplib ++striplib=$lt_striplib ++ ++# Dependencies to place before the objects being linked to create a ++# shared library. ++predep_objects=\`echo $lt_[]_LT_AC_TAGVAR(predep_objects, $1) | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` ++ ++# Dependencies to place after the objects being linked to create a ++# shared library. ++postdep_objects=\`echo $lt_[]_LT_AC_TAGVAR(postdep_objects, $1) | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` ++ ++# Dependencies to place before the objects being linked to create a ++# shared library. ++predeps=$lt_[]_LT_AC_TAGVAR(predeps, $1) ++ ++# Dependencies to place after the objects being linked to create a ++# shared library. ++postdeps=$lt_[]_LT_AC_TAGVAR(postdeps, $1) ++ ++# The library search path used internally by the compiler when linking ++# a shared library. ++compiler_lib_search_path=\`echo $lt_[]_LT_AC_TAGVAR(compiler_lib_search_path, $1) | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` ++ ++# Method to check whether dependent libraries are shared objects. ++deplibs_check_method=$lt_deplibs_check_method ++ ++# Command to use when deplibs_check_method == file_magic. ++file_magic_cmd=$lt_file_magic_cmd ++ ++# Flag that allows shared libraries with undefined symbols to be built. ++allow_undefined_flag=$lt_[]_LT_AC_TAGVAR(allow_undefined_flag, $1) ++ ++# Flag that forces no undefined symbols. ++no_undefined_flag=$lt_[]_LT_AC_TAGVAR(no_undefined_flag, $1) ++ ++# Commands used to finish a libtool library installation in a directory. ++finish_cmds=$lt_finish_cmds ++ ++# Same as above, but a single script fragment to be evaled but not shown. ++finish_eval=$lt_finish_eval ++ ++# Take the output of nm and produce a listing of raw symbols and C names. ++global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe ++ ++# Transform the output of nm in a proper C declaration ++global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl ++ ++# Transform the output of nm in a C name address pair ++global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address ++ ++# This is the shared library runtime path variable. ++runpath_var=$runpath_var ++ ++# This is the shared library path variable. ++shlibpath_var=$shlibpath_var ++ ++# Is shlibpath searched before the hard-coded library search path? ++shlibpath_overrides_runpath=$shlibpath_overrides_runpath ++ ++# How to hardcode a shared library path into an executable. ++hardcode_action=$_LT_AC_TAGVAR(hardcode_action, $1) ++ ++# Whether we should hardcode library paths into libraries. ++hardcode_into_libs=$hardcode_into_libs ++ ++# Flag to hardcode \$libdir into a binary during linking. ++# This must work even if \$libdir does not exist. ++hardcode_libdir_flag_spec=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) ++ ++# If ld is used when linking, flag to hardcode \$libdir into ++# a binary during linking. This must work even if \$libdir does ++# not exist. ++hardcode_libdir_flag_spec_ld=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1) ++ ++# Whether we need a single -rpath flag with a separated argument. ++hardcode_libdir_separator=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_separator, $1) ++ ++# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the ++# resulting binary. ++hardcode_direct=$_LT_AC_TAGVAR(hardcode_direct, $1) ++ ++# Set to yes if using the -LDIR flag during linking hardcodes DIR into the ++# resulting binary. ++hardcode_minus_L=$_LT_AC_TAGVAR(hardcode_minus_L, $1) ++ ++# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into ++# the resulting binary. ++hardcode_shlibpath_var=$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1) ++ ++# Set to yes if building a shared library automatically hardcodes DIR into the library ++# and all subsequent libraries and executables linked against it. ++hardcode_automatic=$_LT_AC_TAGVAR(hardcode_automatic, $1) ++ ++# Variables whose values should be saved in libtool wrapper scripts and ++# restored at relink time. ++variables_saved_for_relink="$variables_saved_for_relink" ++ ++# Whether libtool must link a program against all its dependency libraries. ++link_all_deplibs=$_LT_AC_TAGVAR(link_all_deplibs, $1) ++ ++# Compile-time system search path for libraries ++sys_lib_search_path_spec=\`echo $lt_sys_lib_search_path_spec | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` ++ ++# Run-time system search path for libraries ++sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec ++ ++# Fix the shell variable \$srcfile for the compiler. ++fix_srcfile_path="$_LT_AC_TAGVAR(fix_srcfile_path, $1)" ++ ++# Set to yes if exported symbols are required. ++always_export_symbols=$_LT_AC_TAGVAR(always_export_symbols, $1) ++ ++# The commands to list exported symbols. ++export_symbols_cmds=$lt_[]_LT_AC_TAGVAR(export_symbols_cmds, $1) ++ ++# The commands to extract the exported symbol list from a shared archive. ++extract_expsyms_cmds=$lt_extract_expsyms_cmds ++ ++# Symbols that should not be listed in the preloaded symbols. ++exclude_expsyms=$lt_[]_LT_AC_TAGVAR(exclude_expsyms, $1) ++ ++# Symbols that must always be exported. ++include_expsyms=$lt_[]_LT_AC_TAGVAR(include_expsyms, $1) ++ ++ifelse([$1],[], ++[# ### END LIBTOOL CONFIG], ++[# ### END LIBTOOL TAG CONFIG: $tagname]) ++ ++__EOF__ ++ ++ifelse([$1],[], [ ++ case $host_os in ++ aix3*) ++ cat <<\EOF >> "$cfgfile" ++ ++# AIX sometimes has problems with the GCC collect2 program. For some ++# reason, if we set the COLLECT_NAMES environment variable, the problems ++# vanish in a puff of smoke. ++if test "X${COLLECT_NAMES+set}" != Xset; then ++ COLLECT_NAMES= ++ export COLLECT_NAMES ++fi ++EOF ++ ;; ++ esac ++ ++ # We use sed instead of cat because bash on DJGPP gets confused if ++ # if finds mixed CR/LF and LF-only lines. Since sed operates in ++ # text mode, it properly converts lines to CR/LF. This bash problem ++ # is reportedly fixed, but why not run on old versions too? ++ sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1) ++ ++ mv -f "$cfgfile" "$ofile" || \ ++ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") ++ chmod +x "$ofile" ++]) ++else ++ # If there is no Makefile yet, we rely on a make rule to execute ++ # `config.status --recheck' to rerun these tests and create the ++ # libtool script then. ++ ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` ++ if test -f "$ltmain_in"; then ++ test -f Makefile && make "$ltmain" ++ fi ++fi ++])# AC_LIBTOOL_CONFIG ++ ++ ++# AC_LIBTOOL_PROG_COMPILER_NO_RTTI([TAGNAME]) ++# ------------------------------------------- ++AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], ++[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl ++ ++_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= ++ ++if test "$GCC" = yes; then ++ _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ++ ++ AC_LIBTOOL_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], ++ lt_cv_prog_compiler_rtti_exceptions, ++ [-fno-rtti -fno-exceptions], [], ++ [_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) ++fi ++])# AC_LIBTOOL_PROG_COMPILER_NO_RTTI ++ ++ ++# AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE ++# --------------------------------- ++AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], ++[AC_REQUIRE([AC_CANONICAL_HOST]) ++AC_REQUIRE([AC_PROG_NM]) ++AC_REQUIRE([AC_OBJEXT]) ++# Check for command to grab the raw symbol name followed by C symbol from nm. ++AC_MSG_CHECKING([command to parse $NM output from $compiler object]) ++AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], ++[ ++# These are sane defaults that work on at least a few old systems. ++# [They come from Ultrix. What could be older than Ultrix?!! ;)] ++ ++# Character class describing NM global symbol codes. ++symcode='[[BCDEGRST]]' ++ ++# Regexp to match symbols that can be accessed directly from C. ++sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' ++ ++# Transform an extracted symbol line into a proper C declaration ++lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'" ++ ++# Transform an extracted symbol line into symbol name and symbol address ++lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" ++ ++# Define system-specific variables. ++case $host_os in ++aix*) ++ symcode='[[BCDT]]' ++ ;; ++cygwin* | mingw* | pw32*) ++ symcode='[[ABCDGISTW]]' ++ ;; ++hpux*) # Its linker distinguishes data from code symbols ++ if test "$host_cpu" = ia64; then ++ symcode='[[ABCDEGRST]]' ++ fi ++ lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" ++ lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" ++ ;; ++linux*) ++ if test "$host_cpu" = ia64; then ++ symcode='[[ABCDGIRSTW]]' ++ lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" ++ lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" ++ fi ++ ;; ++irix* | nonstopux*) ++ symcode='[[BCDEGRST]]' ++ ;; ++osf*) ++ symcode='[[BCDEGQRST]]' ++ ;; ++solaris*) ++ symcode='[[BDRT]]' ++ ;; ++sco3.2v5*) ++ symcode='[[DT]]' ++ ;; ++sysv4.2uw2*) ++ symcode='[[DT]]' ++ ;; ++sysv5* | sco5v6* | unixware* | OpenUNIX*) ++ symcode='[[ABDT]]' ++ ;; ++sysv4) ++ symcode='[[DFNSTU]]' ++ ;; ++esac ++ ++# Handle CRLF in mingw tool chain ++opt_cr= ++case $build_os in ++mingw*) ++ opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp ++ ;; ++esac ++ ++# If we're using GNU nm, then use its standard symbol codes. ++case `$NM -V 2>&1` in ++*GNU* | *'with BFD'*) ++ symcode='[[ABCDGIRSTW]]' ;; ++esac ++ ++# Try without a prefix undercore, then with it. ++for ac_symprfx in "" "_"; do ++ ++ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. ++ symxfrm="\\1 $ac_symprfx\\2 \\2" ++ ++ # Write the raw and C identifiers. ++ lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" ++ ++ # Check to see that the pipe works correctly. ++ pipe_works=no ++ ++ rm -f conftest* ++ cat > conftest.$ac_ext < $nlist) && test -s "$nlist"; then ++ # Try sorting and uniquifying the output. ++ if sort "$nlist" | uniq > "$nlist"T; then ++ mv -f "$nlist"T "$nlist" ++ else ++ rm -f "$nlist"T ++ fi ++ ++ # Make sure that we snagged all the symbols we need. ++ if grep ' nm_test_var$' "$nlist" >/dev/null; then ++ if grep ' nm_test_func$' "$nlist" >/dev/null; then ++ cat < conftest.$ac_ext ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++EOF ++ # Now generate the symbol file. ++ eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext' ++ ++ cat <> conftest.$ac_ext ++#if defined (__STDC__) && __STDC__ ++# define lt_ptr_t void * ++#else ++# define lt_ptr_t char * ++# define const ++#endif ++ ++/* The mapping between symbol names and symbols. */ ++const struct { ++ const char *name; ++ lt_ptr_t address; ++} ++lt_preloaded_symbols[[]] = ++{ ++EOF ++ $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext ++ cat <<\EOF >> conftest.$ac_ext ++ {0, (lt_ptr_t) 0} ++}; ++ ++#ifdef __cplusplus ++} ++#endif ++EOF ++ # Now try linking the two files. ++ mv conftest.$ac_objext conftstm.$ac_objext ++ lt_save_LIBS="$LIBS" ++ lt_save_CFLAGS="$CFLAGS" ++ LIBS="conftstm.$ac_objext" ++ CFLAGS="$CFLAGS$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" ++ if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then ++ pipe_works=yes ++ fi ++ LIBS="$lt_save_LIBS" ++ CFLAGS="$lt_save_CFLAGS" ++ else ++ echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD ++ fi ++ else ++ echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD ++ fi ++ else ++ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD ++ fi ++ else ++ echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD ++ cat conftest.$ac_ext >&5 ++ fi ++ rm -f conftest* conftst* ++ ++ # Do not use the global_symbol_pipe unless it works. ++ if test "$pipe_works" = yes; then ++ break ++ else ++ lt_cv_sys_global_symbol_pipe= ++ fi ++done ++]) ++if test -z "$lt_cv_sys_global_symbol_pipe"; then ++ lt_cv_sys_global_symbol_to_cdecl= ++fi ++if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then ++ AC_MSG_RESULT(failed) ++else ++ AC_MSG_RESULT(ok) ++fi ++]) # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE ++ ++ ++# AC_LIBTOOL_PROG_COMPILER_PIC([TAGNAME]) ++# --------------------------------------- ++AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC], ++[_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)= ++_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= ++_LT_AC_TAGVAR(lt_prog_compiler_static, $1)= ++ ++AC_MSG_CHECKING([for $compiler option to produce PIC]) ++ ifelse([$1],[CXX],[ ++ # C++ specific cases for pic, static, wl, etc. ++ if test "$GXX" = yes; then ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' ++ ++ case $host_os in ++ aix*) ++ # All AIX code is PIC. ++ if test "$host_cpu" = ia64; then ++ # AIX 5 now supports IA64 processor ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ fi ++ ;; ++ amigaos*) ++ # FIXME: we need at least 68020 code to build shared libraries, but ++ # adding the `-m68020' flag to GCC prevents building anything better, ++ # like `-m68040'. ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ++ ;; ++ beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) ++ # PIC is the default for these OSes. ++ ;; ++ mingw* | os2* | pw32*) ++ # This hack is so that the source file can tell whether it is being ++ # built for inclusion in a dll (and should export symbols for example). ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' ++ ;; ++ darwin* | rhapsody*) ++ # PIC is the default on this platform ++ # Common symbols not allowed in MH_DYLIB files ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ++ ;; ++ *djgpp*) ++ # DJGPP does not support shared libraries at all ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= ++ ;; ++ interix3*) ++ # Interix 3.x gcc -fpic/-fPIC options generate broken code. ++ # Instead, we relocate shared libraries at runtime. ++ ;; ++ sysv4*MP*) ++ if test -d /usr/nec; then ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic ++ fi ++ ;; ++ hpux*) ++ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but ++ # not for PA HP-UX. ++ case $host_cpu in ++ hppa*64*|ia64*) ++ ;; ++ *) ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ++ ;; ++ esac ++ ;; ++ *) ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ++ ;; ++ esac ++ else ++ case $host_os in ++ aix4* | aix5*) ++ # All AIX code is PIC. ++ if test "$host_cpu" = ia64; then ++ # AIX 5 now supports IA64 processor ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ else ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' ++ fi ++ ;; ++ chorus*) ++ case $cc_basename in ++ cxch68*) ++ # Green Hills C++ Compiler ++ # _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ++ ;; ++ esac ++ ;; ++ darwin*) ++ # PIC is the default on this platform ++ # Common symbols not allowed in MH_DYLIB files ++ case $cc_basename in ++ xlc*) ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-qnocommon' ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ ;; ++ esac ++ ;; ++ dgux*) ++ case $cc_basename in ++ ec++*) ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ ;; ++ ghcx*) ++ # Green Hills C++ Compiler ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ freebsd* | kfreebsd*-gnu | dragonfly*) ++ # FreeBSD uses GNU C++ ++ ;; ++ hpux9* | hpux10* | hpux11*) ++ case $cc_basename in ++ CC*) ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' ++ if test "$host_cpu" != ia64; then ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ++ fi ++ ;; ++ aCC*) ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' ++ case $host_cpu in ++ hppa*64*|ia64*) ++ # +Z the default ++ ;; ++ *) ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ++ ;; ++ esac ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ interix*) ++ # This is c89, which is MS Visual C++ (no shared libs) ++ # Anyone wants to do a port? ++ ;; ++ irix5* | irix6* | nonstopux*) ++ case $cc_basename in ++ CC*) ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ++ # CC pic flag -KPIC is the default. ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ linux*) ++ case $cc_basename in ++ KCC*) ++ # KAI C++ Compiler ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ++ ;; ++ icpc* | ecpc*) ++ # Intel C++ ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' ++ ;; ++ pgCC*) ++ # Portland Group C++ compiler. ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ ;; ++ cxx*) ++ # Compaq C++ ++ # Make sure the PIC flag is empty. It appears that all Alpha ++ # Linux and Compaq Tru64 Unix objects are PIC. ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ lynxos*) ++ ;; ++ m88k*) ++ ;; ++ mvs*) ++ case $cc_basename in ++ cxx*) ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ netbsd*) ++ ;; ++ osf3* | osf4* | osf5*) ++ case $cc_basename in ++ KCC*) ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ++ ;; ++ RCC*) ++ # Rational C++ 2.4.1 ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ++ ;; ++ cxx*) ++ # Digital/Compaq C++ ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ # Make sure the PIC flag is empty. It appears that all Alpha ++ # Linux and Compaq Tru64 Unix objects are PIC. ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ psos*) ++ ;; ++ solaris*) ++ case $cc_basename in ++ CC*) ++ # Sun C++ 4.2, 5.x and Centerline C++ ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ++ ;; ++ gcx*) ++ # Green Hills C++ Compiler ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ sunos4*) ++ case $cc_basename in ++ CC*) ++ # Sun C++ 4.x ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ ;; ++ lcc*) ++ # Lucid ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ tandem*) ++ case $cc_basename in ++ NCC*) ++ # NonStop-UX NCC 3.20 ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) ++ case $cc_basename in ++ CC*) ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ ;; ++ esac ++ ;; ++ vxworks*) ++ ;; ++ *) ++ _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ++ ;; ++ esac ++ fi ++], ++[ ++ if test "$GCC" = yes; then ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' ++ ++ case $host_os in ++ aix*) ++ # All AIX code is PIC. ++ if test "$host_cpu" = ia64; then ++ # AIX 5 now supports IA64 processor ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ fi ++ ;; ++ ++ amigaos*) ++ # FIXME: we need at least 68020 code to build shared libraries, but ++ # adding the `-m68020' flag to GCC prevents building anything better, ++ # like `-m68040'. ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ++ ;; ++ ++ beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) ++ # PIC is the default for these OSes. ++ ;; ++ ++ mingw* | pw32* | os2*) ++ # This hack is so that the source file can tell whether it is being ++ # built for inclusion in a dll (and should export symbols for example). ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' ++ ;; ++ ++ darwin* | rhapsody*) ++ # PIC is the default on this platform ++ # Common symbols not allowed in MH_DYLIB files ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ++ ;; ++ ++ interix3*) ++ # Interix 3.x gcc -fpic/-fPIC options generate broken code. ++ # Instead, we relocate shared libraries at runtime. ++ ;; ++ ++ msdosdjgpp*) ++ # Just because we use GCC doesn't mean we suddenly get shared libraries ++ # on systems that don't support them. ++ _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ++ enable_shared=no ++ ;; ++ ++ sysv4*MP*) ++ if test -d /usr/nec; then ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic ++ fi ++ ;; ++ ++ hpux*) ++ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but ++ # not for PA HP-UX. ++ case $host_cpu in ++ hppa*64*|ia64*) ++ # +Z the default ++ ;; ++ *) ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ++ ;; ++ esac ++ ;; ++ ++ *) ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ++ ;; ++ esac ++ else ++ # PORTME Check for flag to pass linker flags through the system compiler. ++ case $host_os in ++ aix*) ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ if test "$host_cpu" = ia64; then ++ # AIX 5 now supports IA64 processor ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ else ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' ++ fi ++ ;; ++ darwin*) ++ # PIC is the default on this platform ++ # Common symbols not allowed in MH_DYLIB files ++ case $cc_basename in ++ xlc*) ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-qnocommon' ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ ;; ++ esac ++ ;; ++ ++ mingw* | pw32* | os2*) ++ # This hack is so that the source file can tell whether it is being ++ # built for inclusion in a dll (and should export symbols for example). ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' ++ ;; ++ ++ hpux9* | hpux10* | hpux11*) ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but ++ # not for PA HP-UX. ++ case $host_cpu in ++ hppa*64*|ia64*) ++ # +Z the default ++ ;; ++ *) ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ++ ;; ++ esac ++ # Is there a better lt_prog_compiler_static that works with the bundled CC? ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' ++ ;; ++ ++ irix5* | irix6* | nonstopux*) ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ # PIC (with -KPIC) is the default. ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ++ ;; ++ ++ newsos6) ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ ;; ++ ++ linux*) ++ case $cc_basename in ++ icc* | ecc*) ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' ++ ;; ++ pgcc* | pgf77* | pgf90* | pgf95*) ++ # Portland Group compilers (*not* the Pentium gcc compiler, ++ # which looks to be a dead project) ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ ;; ++ ccc*) ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ # All Alpha code is PIC. ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ++ ;; ++ esac ++ ;; ++ ++ osf3* | osf4* | osf5*) ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ # All OSF/1 code is PIC. ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ++ ;; ++ ++ solaris*) ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ case $cc_basename in ++ f77* | f90* | f95*) ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; ++ *) ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; ++ esac ++ ;; ++ ++ sunos4*) ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ ;; ++ ++ sysv4 | sysv4.2uw2* | sysv4.3*) ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ ;; ++ ++ sysv4*MP*) ++ if test -d /usr/nec ;then ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ fi ++ ;; ++ ++ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ ;; ++ ++ unicos*) ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ++ ;; ++ ++ uts4*) ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ ;; ++ ++ *) ++ _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ++ ;; ++ esac ++ fi ++]) ++AC_MSG_RESULT([$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)]) ++ ++# ++# Check to make sure the PIC flag actually works. ++# ++if test -n "$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)"; then ++ AC_LIBTOOL_COMPILER_OPTION([if $compiler PIC flag $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) works], ++ _LT_AC_TAGVAR(lt_prog_compiler_pic_works, $1), ++ [$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])], [], ++ [case $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) in ++ "" | " "*) ;; ++ *) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)" ;; ++ esac], ++ [_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= ++ _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) ++fi ++case $host_os in ++ # For platforms which do not support PIC, -DPIC is meaningless: ++ *djgpp*) ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= ++ ;; ++ *) ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])" ++ ;; ++esac ++ ++# ++# Check to make sure the static flag actually works. ++# ++wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_AC_TAGVAR(lt_prog_compiler_static, $1)\" ++AC_LIBTOOL_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], ++ _LT_AC_TAGVAR(lt_prog_compiler_static_works, $1), ++ $lt_tmp_static_flag, ++ [], ++ [_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=]) ++]) ++ ++ ++# AC_LIBTOOL_PROG_LD_SHLIBS([TAGNAME]) ++# ------------------------------------ ++# See if the linker supports building shared libraries. ++AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS], ++[AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) ++ifelse([$1],[CXX],[ ++ _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ++ case $host_os in ++ aix4* | aix5*) ++ # If we're using GNU nm, then we don't want the "-C" option. ++ # -C means demangle to AIX nm, but means don't demangle with GNU nm ++ if $NM -V 2>&1 | grep 'GNU' > /dev/null; then ++ _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' ++ else ++ _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' ++ fi ++ ;; ++ pw32*) ++ _LT_AC_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" ++ ;; ++ cygwin* | mingw*) ++ _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]] /s/.* \([[^ ]]*\)/\1 DATA/;/^.* __nm__/s/^.* __nm__\([[^ ]]*\) [[^ ]]*/\1 DATA/;/^I /d;/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols' ++ ;; ++ *) ++ _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ++ ;; ++ esac ++],[ ++ runpath_var= ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)= ++ _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no ++ _LT_AC_TAGVAR(archive_cmds, $1)= ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)= ++ _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)= ++ _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1)= ++ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= ++ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= ++ _LT_AC_TAGVAR(thread_safe_flag_spec, $1)= ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= ++ _LT_AC_TAGVAR(hardcode_direct, $1)=no ++ _LT_AC_TAGVAR(hardcode_minus_L, $1)=no ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported ++ _LT_AC_TAGVAR(link_all_deplibs, $1)=unknown ++ _LT_AC_TAGVAR(hardcode_automatic, $1)=no ++ _LT_AC_TAGVAR(module_cmds, $1)= ++ _LT_AC_TAGVAR(module_expsym_cmds, $1)= ++ _LT_AC_TAGVAR(always_export_symbols, $1)=no ++ _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ++ # include_expsyms should be a list of space-separated symbols to be *always* ++ # included in the symbol list ++ _LT_AC_TAGVAR(include_expsyms, $1)= ++ # exclude_expsyms can be an extended regexp of symbols to exclude ++ # it will be wrapped by ` (' and `)$', so one must not match beginning or ++ # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', ++ # as well as any symbol that contains `d'. ++ _LT_AC_TAGVAR(exclude_expsyms, $1)="_GLOBAL_OFFSET_TABLE_" ++ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out ++ # platforms (ab)use it in PIC code, but their linkers get confused if ++ # the symbol is explicitly referenced. Since portable code cannot ++ # rely on this symbol name, it's probably fine to never include it in ++ # preloaded symbol tables. ++ extract_expsyms_cmds= ++ # Just being paranoid about ensuring that cc_basename is set. ++ _LT_CC_BASENAME([$compiler]) ++ case $host_os in ++ cygwin* | mingw* | pw32*) ++ # FIXME: the MSVC++ port hasn't been tested in a loooong time ++ # When not using gcc, we currently assume that we are using ++ # Microsoft Visual C++. ++ if test "$GCC" != yes; then ++ with_gnu_ld=no ++ fi ++ ;; ++ interix*) ++ # we just hope/assume this is gcc and not c89 (= MSVC++) ++ with_gnu_ld=yes ++ ;; ++ openbsd*) ++ with_gnu_ld=no ++ ;; ++ esac ++ ++ _LT_AC_TAGVAR(ld_shlibs, $1)=yes ++ if test "$with_gnu_ld" = yes; then ++ # If archive_cmds runs LD, not CC, wlarc should be empty ++ wlarc='${wl}' ++ ++ # Set some defaults for GNU ld with shared library support. These ++ # are reset later if shared libraries are not supported. Putting them ++ # here allows them to be overridden if necessary. ++ runpath_var=LD_RUN_PATH ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' ++ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' ++ # ancient GNU ld didn't support --whole-archive et. al. ++ if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then ++ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' ++ else ++ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= ++ fi ++ supports_anon_versioning=no ++ case `$LD -v 2>/dev/null` in ++ *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 ++ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... ++ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... ++ *\ 2.11.*) ;; # other 2.11 versions ++ *) supports_anon_versioning=yes ;; ++ esac ++ ++ # See if GNU ld supports shared libraries. ++ case $host_os in ++ aix3* | aix4* | aix5*) ++ # On AIX/PPC, the GNU linker is very broken ++ if test "$host_cpu" != ia64; then ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ cat <&2 ++ ++*** Warning: the GNU linker, at least up to release 2.9.1, is reported ++*** to be unable to reliably create shared libraries on AIX. ++*** Therefore, libtool is disabling shared libraries support. If you ++*** really care for shared libraries, you may want to modify your PATH ++*** so that a non-GNU linker is found, and then restart. ++ ++EOF ++ fi ++ ;; ++ ++ amigaos*) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes ++ ++ # Samuel A. Falvo II reports ++ # that the semantics of dynamic libraries on AmigaOS, at least up ++ # to version 4, is to share data among multiple programs linked ++ # with the same dynamic library. Since this doesn't match the ++ # behavior of shared libraries on other platforms, we can't use ++ # them. ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ ++ beos*) ++ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported ++ # Joseph Beckenbach says some releases of gcc ++ # support --undefined. This deserves some investigation. FIXME ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ else ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ ++ cygwin* | mingw* | pw32*) ++ # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, ++ # as there is no search path for DLLs. ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported ++ _LT_AC_TAGVAR(always_export_symbols, $1)=no ++ _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ++ _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]] /s/.* \([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols' ++ ++ if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' ++ # If the export-symbols file already is a .def file (1st line ++ # is EXPORTS), use it as is; otherwise, prepend... ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then ++ cp $export_symbols $output_objdir/$soname.def; ++ else ++ echo EXPORTS > $output_objdir/$soname.def; ++ cat $export_symbols >> $output_objdir/$soname.def; ++ fi~ ++ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' ++ else ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ ++ interix3*) ++ _LT_AC_TAGVAR(hardcode_direct, $1)=no ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' ++ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ++ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. ++ # Instead, shared libraries are loaded at an image base (0x10000000 by ++ # default) and relocated if they conflict, which is a slow very memory ++ # consuming and fragmenting process. To avoid this, we pick a random, ++ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link ++ # time. Moving up from 0x10000000 also allows more sbrk(2) space. ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ++ ;; ++ ++ linux*) ++ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then ++ tmp_addflag= ++ case $cc_basename,$host_cpu in ++ pgcc*) # Portland Group C compiler ++ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' ++ tmp_addflag=' $pic_flag' ++ ;; ++ pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers ++ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' ++ tmp_addflag=' $pic_flag -Mnomain' ;; ++ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 ++ tmp_addflag=' -i_dynamic' ;; ++ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 ++ tmp_addflag=' -i_dynamic -nofor_main' ;; ++ ifc* | ifort*) # Intel Fortran compiler ++ tmp_addflag=' -nofor_main' ;; ++ esac ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ ++ if test $supports_anon_versioning = yes; then ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $output_objdir/$libname.ver~ ++ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ ++ $echo "local: *; };" >> $output_objdir/$libname.ver~ ++ $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' ++ fi ++ else ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ ++ netbsd*) ++ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then ++ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' ++ wlarc= ++ else ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ fi ++ ;; ++ ++ solaris*) ++ if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ cat <&2 ++ ++*** Warning: The releases 2.8.* of the GNU linker cannot reliably ++*** create shared libraries on Solaris systems. Therefore, libtool ++*** is disabling shared libraries support. We urge you to upgrade GNU ++*** binutils to release 2.9.1 or newer. Another option is to modify ++*** your PATH or compiler configuration so that the native linker is ++*** used, and then restart. ++ ++EOF ++ elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ else ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ ++ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) ++ case `$LD -v 2>&1` in ++ *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ cat <<_LT_EOF 1>&2 ++ ++*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not ++*** reliably create shared libraries on SCO systems. Therefore, libtool ++*** is disabling shared libraries support. We urge you to upgrade GNU ++*** binutils to release 2.16.91.0.3 or newer. Another option is to modify ++*** your PATH or compiler configuration so that the native linker is ++*** used, and then restart. ++ ++_LT_EOF ++ ;; ++ *) ++ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' ++ else ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ esac ++ ;; ++ ++ sunos4*) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' ++ wlarc= ++ _LT_AC_TAGVAR(hardcode_direct, $1)=yes ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ ++ *) ++ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ else ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ esac ++ ++ if test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no; then ++ runpath_var= ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= ++ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= ++ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= ++ fi ++ else ++ # PORTME fill in a description of your system's linker (not GNU ld) ++ case $host_os in ++ aix3*) ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported ++ _LT_AC_TAGVAR(always_export_symbols, $1)=yes ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' ++ # Note: this linker hardcodes the directories in LIBPATH if there ++ # are no directories specified by -L. ++ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes ++ if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then ++ # Neither direct hardcoding nor static linking is supported with a ++ # broken collect2. ++ _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported ++ fi ++ ;; ++ ++ aix4* | aix5*) ++ if test "$host_cpu" = ia64; then ++ # On IA64, the linker does run time linking by default, so we don't ++ # have to do anything special. ++ aix_use_runtimelinking=no ++ exp_sym_flag='-Bexport' ++ no_entry_flag="" ++ else ++ # If we're using GNU nm, then we don't want the "-C" option. ++ # -C means demangle to AIX nm, but means don't demangle with GNU nm ++ if $NM -V 2>&1 | grep 'GNU' > /dev/null; then ++ _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' ++ else ++ _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' ++ fi ++ aix_use_runtimelinking=no ++ ++ # Test if we are trying to use run time linking or normal ++ # AIX style linking. If -brtl is somewhere in LDFLAGS, we ++ # need to do runtime linking. ++ case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*) ++ for ld_flag in $LDFLAGS; do ++ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then ++ aix_use_runtimelinking=yes ++ break ++ fi ++ done ++ ;; ++ esac ++ ++ exp_sym_flag='-bexport' ++ no_entry_flag='-bnoentry' ++ fi ++ ++ # When large executables or shared objects are built, AIX ld can ++ # have problems creating the table of contents. If linking a library ++ # or program results in "error TOC overflow" add -mminimal-toc to ++ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not ++ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. ++ ++ _LT_AC_TAGVAR(archive_cmds, $1)='' ++ _LT_AC_TAGVAR(hardcode_direct, $1)=yes ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' ++ _LT_AC_TAGVAR(link_all_deplibs, $1)=yes ++ ++ if test "$GCC" = yes; then ++ case $host_os in aix4.[[012]]|aix4.[[012]].*) ++ # We only want to do this on AIX 4.2 and lower, the check ++ # below for broken collect2 doesn't work under 4.3+ ++ collect2name=`${CC} -print-prog-name=collect2` ++ if test -f "$collect2name" && \ ++ strings "$collect2name" | grep resolve_lib_name >/dev/null ++ then ++ # We have reworked collect2 ++ _LT_AC_TAGVAR(hardcode_direct, $1)=yes ++ else ++ # We have old collect2 ++ _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported ++ # It fails to find uninstalled libraries when the uninstalled ++ # path is not listed in the libpath. Setting hardcode_minus_L ++ # to unsupported forces relinking ++ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= ++ fi ++ ;; ++ esac ++ shared_flag='-shared' ++ if test "$aix_use_runtimelinking" = yes; then ++ shared_flag="$shared_flag "'${wl}-G' ++ fi ++ else ++ # not using gcc ++ if test "$host_cpu" = ia64; then ++ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release ++ # chokes on -Wl,-G. The following line is correct: ++ shared_flag='-G' ++ else ++ if test "$aix_use_runtimelinking" = yes; then ++ shared_flag='${wl}-G' ++ else ++ shared_flag='${wl}-bM:SRE' ++ fi ++ fi ++ fi ++ ++ # It seems that -bexpall does not export symbols beginning with ++ # underscore (_), so it is better to generate a list of symbols to export. ++ _LT_AC_TAGVAR(always_export_symbols, $1)=yes ++ if test "$aix_use_runtimelinking" = yes; then ++ # Warning - without using the other runtime loading flags (-brtl), ++ # -berok will link without error, but may produce a broken library. ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok' ++ # Determine the default libpath from the value encoded in an empty executable. ++ _LT_AC_SYS_LIBPATH_AIX ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" ++ else ++ if test "$host_cpu" = ia64; then ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs" ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" ++ else ++ # Determine the default libpath from the value encoded in an empty executable. ++ _LT_AC_SYS_LIBPATH_AIX ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" ++ # Warning - without using the other run time loading flags, ++ # -berok will link without error, but may produce a broken library. ++ _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' ++ # Exported symbols can be pulled into shared objects from archives ++ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='$convenience' ++ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes ++ # This is similar to how AIX traditionally builds its shared libraries. ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' ++ fi ++ fi ++ ;; ++ ++ amigaos*) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes ++ # see comment about different semantics on the GNU ld section ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ ++ bsdi[[45]]*) ++ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ++ ;; ++ ++ cygwin* | mingw* | pw32*) ++ # When not using gcc, we currently assume that we are using ++ # Microsoft Visual C++. ++ # hardcode_libdir_flag_spec is actually meaningless, as there is ++ # no search path for DLLs. ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported ++ # Tell ltmain to make .lib files, not .a files. ++ libext=lib ++ # Tell ltmain to make .dll files, not .so files. ++ shrext_cmds=".dll" ++ # FIXME: Setting linknames here is a bad hack. ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' ++ # The linker will automatically build a .lib file if we build a DLL. ++ _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='true' ++ # FIXME: Should let the user specify the lib program. ++ _LT_AC_TAGVAR(old_archive_cmds, $1)='lib /OUT:$oldlib$oldobjs$old_deplibs' ++ _LT_AC_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`' ++ _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ++ ;; ++ ++ darwin* | rhapsody*) ++ case $host_os in ++ rhapsody* | darwin1.[[012]]) ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress' ++ ;; ++ *) # Darwin 1.3 on ++ if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ++ else ++ case ${MACOSX_DEPLOYMENT_TARGET} in ++ 10.[[012]]) ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ++ ;; ++ 10.*) ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}dynamic_lookup' ++ ;; ++ esac ++ fi ++ ;; ++ esac ++ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ++ _LT_AC_TAGVAR(hardcode_direct, $1)=no ++ _LT_AC_TAGVAR(hardcode_automatic, $1)=yes ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported ++ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='' ++ _LT_AC_TAGVAR(link_all_deplibs, $1)=yes ++ if test "$GCC" = yes ; then ++ output_verbose_link_cmd='echo' ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' ++ _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' ++ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ else ++ case $cc_basename in ++ xlc*) ++ output_verbose_link_cmd='echo' ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' ++ _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' ++ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ ;; ++ *) ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ esac ++ fi ++ ;; ++ ++ dgux*) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ ++ freebsd1*) ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ ++ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor ++ # support. Future versions do this automatically, but an explicit c++rt0.o ++ # does not break anything, and helps significantly (at the cost of a little ++ # extra space). ++ freebsd2.2*) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ++ _LT_AC_TAGVAR(hardcode_direct, $1)=yes ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ ++ # Unfortunately, older versions of FreeBSD 2 do not have this feature. ++ freebsd2*) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' ++ _LT_AC_TAGVAR(hardcode_direct, $1)=yes ++ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ ++ # FreeBSD 3 and greater uses gcc -shared to do shared libraries. ++ freebsd* | kfreebsd*-gnu | dragonfly*) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ++ _LT_AC_TAGVAR(hardcode_direct, $1)=yes ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ ++ hpux9*) ++ if test "$GCC" = yes; then ++ _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ++ else ++ _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ++ fi ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ++ _LT_AC_TAGVAR(hardcode_direct, $1)=yes ++ ++ # hardcode_minus_L: Not really in the search PATH, ++ # but as the default location of the library. ++ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes ++ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ++ ;; ++ ++ hpux10*) ++ if test "$GCC" = yes -a "$with_gnu_ld" = no; then ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' ++ fi ++ if test "$with_gnu_ld" = no; then ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ++ ++ _LT_AC_TAGVAR(hardcode_direct, $1)=yes ++ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ++ ++ # hardcode_minus_L: Not really in the search PATH, ++ # but as the default location of the library. ++ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes ++ fi ++ ;; ++ ++ hpux11*) ++ if test "$GCC" = yes -a "$with_gnu_ld" = no; then ++ case $host_cpu in ++ hppa*64*) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ ia64*) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ *) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ esac ++ else ++ case $host_cpu in ++ hppa*64*) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ ia64*) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ *) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ esac ++ fi ++ if test "$with_gnu_ld" = no; then ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ++ ++ case $host_cpu in ++ hppa*64*|ia64*) ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' ++ _LT_AC_TAGVAR(hardcode_direct, $1)=no ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ *) ++ _LT_AC_TAGVAR(hardcode_direct, $1)=yes ++ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ++ ++ # hardcode_minus_L: Not really in the search PATH, ++ # but as the default location of the library. ++ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes ++ ;; ++ esac ++ fi ++ ;; ++ ++ irix5* | irix6* | nonstopux*) ++ if test "$GCC" = yes; then ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ else ++ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' ++ fi ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ++ _LT_AC_TAGVAR(link_all_deplibs, $1)=yes ++ ;; ++ ++ netbsd*) ++ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then ++ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out ++ else ++ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF ++ fi ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ++ _LT_AC_TAGVAR(hardcode_direct, $1)=yes ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ ++ newsos6) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ _LT_AC_TAGVAR(hardcode_direct, $1)=yes ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ ++ openbsd*) ++ _LT_AC_TAGVAR(hardcode_direct, $1)=yes ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' ++ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ++ else ++ case $host_os in ++ openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ++ ;; ++ *) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' ++ ;; ++ esac ++ fi ++ ;; ++ ++ os2*) ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported ++ _LT_AC_TAGVAR(archive_cmds, $1)='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' ++ _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ++ ;; ++ ++ osf3*) ++ if test "$GCC" = yes; then ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ else ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' ++ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' ++ fi ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ++ ;; ++ ++ osf4* | osf5*) # as osf3* with the addition of -msym flag ++ if test "$GCC" = yes; then ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' ++ else ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' ++ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ ++ $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' ++ ++ # Both c and cxx compiler support -rpath directly ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ++ fi ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ++ ;; ++ ++ solaris*) ++ _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text' ++ if test "$GCC" = yes; then ++ wlarc='${wl}' ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ ++ $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' ++ else ++ wlarc='' ++ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ ++ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' ++ fi ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ case $host_os in ++ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; ++ *) ++ # The compiler driver will combine linker options so we ++ # cannot just pass the convience library names through ++ # without $wl, iff we do not link with $LD. ++ # Luckily, gcc supports the same syntax we need for Sun Studio. ++ # Supported since Solaris 2.6 (maybe 2.5.1?) ++ case $wlarc in ++ '') ++ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; ++ *) ++ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;; ++ esac ;; ++ esac ++ _LT_AC_TAGVAR(link_all_deplibs, $1)=yes ++ ;; ++ ++ sunos4*) ++ if test "x$host_vendor" = xsequent; then ++ # Use $CC to link under sequent, because it throws in some extra .o ++ # files that make .init and .fini sections work. ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' ++ fi ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_AC_TAGVAR(hardcode_direct, $1)=yes ++ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ ++ sysv4) ++ case $host_vendor in ++ sni) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ _LT_AC_TAGVAR(hardcode_direct, $1)=yes # is this really true??? ++ ;; ++ siemens) ++ ## LD is ld it makes a PLAMLIB ++ ## CC just makes a GrossModule. ++ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' ++ _LT_AC_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' ++ _LT_AC_TAGVAR(hardcode_direct, $1)=no ++ ;; ++ motorola) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ _LT_AC_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie ++ ;; ++ esac ++ runpath_var='LD_RUN_PATH' ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ ++ sysv4.3*) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' ++ ;; ++ ++ sysv4*MP*) ++ if test -d /usr/nec; then ++ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ runpath_var=LD_RUN_PATH ++ hardcode_runpath_var=yes ++ _LT_AC_TAGVAR(ld_shlibs, $1)=yes ++ fi ++ ;; ++ ++ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7*) ++ _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' ++ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ runpath_var='LD_RUN_PATH' ++ ++ if test "$GCC" = yes; then ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ fi ++ ;; ++ ++ sysv5* | sco3.2v5* | sco5v6*) ++ # Note: We can NOT use -z defs as we might desire, because we do not ++ # link with -lc, and that would cause any symbols used from libc to ++ # always be unresolved, which means just about no library would ++ # ever link correctly. If we're not using GNU ld we use -z text ++ # though, which does catch some bad symbols but isn't as heavy-handed ++ # as -z defs. ++ _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' ++ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' ++ _LT_AC_TAGVAR(link_all_deplibs, $1)=yes ++ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' ++ runpath_var='LD_RUN_PATH' ++ ++ if test "$GCC" = yes; then ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ fi ++ ;; ++ ++ uts4*) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ ++ *) ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ esac ++ fi ++]) ++AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)]) ++test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no ++ ++# ++# Do we need to explicitly link libc? ++# ++case "x$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)" in ++x|xyes) ++ # Assume -lc should be added ++ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes ++ ++ if test "$enable_shared" = yes && test "$GCC" = yes; then ++ case $_LT_AC_TAGVAR(archive_cmds, $1) in ++ *'~'*) ++ # FIXME: we may have to deal with multi-command sequences. ++ ;; ++ '$CC '*) ++ # Test whether the compiler implicitly links with -lc since on some ++ # systems, -lgcc has to come before -lc. If gcc already passes -lc ++ # to ld, don't add -lc before -lgcc. ++ AC_MSG_CHECKING([whether -lc should be explicitly linked in]) ++ $rm conftest* ++ printf "$lt_simple_compile_test_code" > conftest.$ac_ext ++ ++ if AC_TRY_EVAL(ac_compile) 2>conftest.err; then ++ soname=conftest ++ lib=conftest ++ libobjs=conftest.$ac_objext ++ deplibs= ++ wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) ++ pic_flag=$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) ++ compiler_flags=-v ++ linker_flags=-v ++ verstring= ++ output_objdir=. ++ libname=conftest ++ lt_save_allow_undefined_flag=$_LT_AC_TAGVAR(allow_undefined_flag, $1) ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)= ++ if AC_TRY_EVAL(_LT_AC_TAGVAR(archive_cmds, $1) 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) ++ then ++ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ++ else ++ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes ++ fi ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag ++ else ++ cat conftest.err 1>&5 ++ fi ++ $rm conftest* ++ AC_MSG_RESULT([$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)]) ++ ;; ++ esac ++ fi ++ ;; ++esac ++])# AC_LIBTOOL_PROG_LD_SHLIBS ++ ++ ++# _LT_AC_FILE_LTDLL_C ++# ------------------- ++# Be careful that the start marker always follows a newline. ++AC_DEFUN([_LT_AC_FILE_LTDLL_C], [ ++# /* ltdll.c starts here */ ++# #define WIN32_LEAN_AND_MEAN ++# #include ++# #undef WIN32_LEAN_AND_MEAN ++# #include ++# ++# #ifndef __CYGWIN__ ++# # ifdef __CYGWIN32__ ++# # define __CYGWIN__ __CYGWIN32__ ++# # endif ++# #endif ++# ++# #ifdef __cplusplus ++# extern "C" { ++# #endif ++# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved); ++# #ifdef __cplusplus ++# } ++# #endif ++# ++# #ifdef __CYGWIN__ ++# #include ++# DECLARE_CYGWIN_DLL( DllMain ); ++# #endif ++# HINSTANCE __hDllInstance_base; ++# ++# BOOL APIENTRY ++# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) ++# { ++# __hDllInstance_base = hInst; ++# return TRUE; ++# } ++# /* ltdll.c ends here */ ++])# _LT_AC_FILE_LTDLL_C ++ ++ ++# _LT_AC_TAGVAR(VARNAME, [TAGNAME]) ++# --------------------------------- ++AC_DEFUN([_LT_AC_TAGVAR], [ifelse([$2], [], [$1], [$1_$2])]) ++ ++ ++# old names ++AC_DEFUN([AM_PROG_LIBTOOL], [AC_PROG_LIBTOOL]) ++AC_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) ++AC_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) ++AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) ++AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) ++AC_DEFUN([AM_PROG_LD], [AC_PROG_LD]) ++AC_DEFUN([AM_PROG_NM], [AC_PROG_NM]) ++ ++# This is just to silence aclocal about the macro not being used ++ifelse([AC_DISABLE_FAST_INSTALL]) ++ ++AC_DEFUN([LT_AC_PROG_GCJ], ++[AC_CHECK_TOOL(GCJ, gcj, no) ++ test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" ++ AC_SUBST(GCJFLAGS) ++]) ++ ++AC_DEFUN([LT_AC_PROG_RC], ++[AC_CHECK_TOOL(RC, windres, no) ++]) ++ ++# NOTE: This macro has been submitted for inclusion into # ++# GNU Autoconf as AC_PROG_SED. When it is available in # ++# a released version of Autoconf we should remove this # ++# macro and use it instead. # ++# LT_AC_PROG_SED ++# -------------- ++# Check for a fully-functional sed program, that truncates ++# as few characters as possible. Prefer GNU sed if found. ++AC_DEFUN([LT_AC_PROG_SED], ++[AC_MSG_CHECKING([for a sed that does not truncate output]) ++AC_CACHE_VAL(lt_cv_path_SED, ++[# Loop through the user's path and test for sed and gsed. ++# Then use that list of sed's as ones to test for truncation. ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for lt_ac_prog in sed gsed; do ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then ++ lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" ++ fi ++ done ++ done ++done ++IFS=$as_save_IFS ++lt_ac_max=0 ++lt_ac_count=0 ++# Add /usr/xpg4/bin/sed as it is typically found on Solaris ++# along with /bin/sed that truncates output. ++for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do ++ test ! -f $lt_ac_sed && continue ++ cat /dev/null > conftest.in ++ lt_ac_count=0 ++ echo $ECHO_N "0123456789$ECHO_C" >conftest.in ++ # Check for GNU sed and select it if it is found. ++ if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then ++ lt_cv_path_SED=$lt_ac_sed ++ break ++ fi ++ while true; do ++ cat conftest.in conftest.in >conftest.tmp ++ mv conftest.tmp conftest.in ++ cp conftest.in conftest.nl ++ echo >>conftest.nl ++ $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break ++ cmp -s conftest.out conftest.nl || break ++ # 10000 chars as input seems more than enough ++ test $lt_ac_count -gt 10 && break ++ lt_ac_count=`expr $lt_ac_count + 1` ++ if test $lt_ac_count -gt $lt_ac_max; then ++ lt_ac_max=$lt_ac_count ++ lt_cv_path_SED=$lt_ac_sed ++ fi ++ done ++done ++]) ++SED=$lt_cv_path_SED ++AC_SUBST([SED]) ++AC_MSG_RESULT([$SED]) ++]) ++ ++# Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# AM_AUTOMAKE_VERSION(VERSION) ++# ---------------------------- ++# Automake X.Y traces this macro to ensure aclocal.m4 has been ++# generated from the m4 files accompanying Automake X.Y. ++AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"]) ++ ++# AM_SET_CURRENT_AUTOMAKE_VERSION ++# ------------------------------- ++# Call AM_AUTOMAKE_VERSION so it can be traced. ++# This function is AC_REQUIREd by AC_INIT_AUTOMAKE. ++AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], ++ [AM_AUTOMAKE_VERSION([1.9.6])]) ++ ++# AM_AUX_DIR_EXPAND -*- Autoconf -*- ++ ++# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets ++# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to ++# `$srcdir', `$srcdir/..', or `$srcdir/../..'. ++# ++# Of course, Automake must honor this variable whenever it calls a ++# tool from the auxiliary directory. The problem is that $srcdir (and ++# therefore $ac_aux_dir as well) can be either absolute or relative, ++# depending on how configure is run. This is pretty annoying, since ++# it makes $ac_aux_dir quite unusable in subdirectories: in the top ++# source directory, any form will work fine, but in subdirectories a ++# relative path needs to be adjusted first. ++# ++# $ac_aux_dir/missing ++# fails when called from a subdirectory if $ac_aux_dir is relative ++# $top_srcdir/$ac_aux_dir/missing ++# fails if $ac_aux_dir is absolute, ++# fails when called from a subdirectory in a VPATH build with ++# a relative $ac_aux_dir ++# ++# The reason of the latter failure is that $top_srcdir and $ac_aux_dir ++# are both prefixed by $srcdir. In an in-source build this is usually ++# harmless because $srcdir is `.', but things will broke when you ++# start a VPATH build or use an absolute $srcdir. ++# ++# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, ++# iff we strip the leading $srcdir from $ac_aux_dir. That would be: ++# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` ++# and then we would define $MISSING as ++# MISSING="\${SHELL} $am_aux_dir/missing" ++# This will work as long as MISSING is not called from configure, because ++# unfortunately $(top_srcdir) has no meaning in configure. ++# However there are other variables, like CC, which are often used in ++# configure, and could therefore not use this "fixed" $ac_aux_dir. ++# ++# Another solution, used here, is to always expand $ac_aux_dir to an ++# absolute PATH. The drawback is that using absolute paths prevent a ++# configured tree to be moved without reconfiguration. ++ ++AC_DEFUN([AM_AUX_DIR_EXPAND], ++[dnl Rely on autoconf to set up CDPATH properly. ++AC_PREREQ([2.50])dnl ++# expand $ac_aux_dir to an absolute path ++am_aux_dir=`cd $ac_aux_dir && pwd` ++]) ++ ++# AM_CONDITIONAL -*- Autoconf -*- ++ ++# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005 ++# Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# serial 7 ++ ++# AM_CONDITIONAL(NAME, SHELL-CONDITION) ++# ------------------------------------- ++# Define a conditional. ++AC_DEFUN([AM_CONDITIONAL], ++[AC_PREREQ(2.52)dnl ++ ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], ++ [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl ++AC_SUBST([$1_TRUE]) ++AC_SUBST([$1_FALSE]) ++if $2; then ++ $1_TRUE= ++ $1_FALSE='#' ++else ++ $1_TRUE='#' ++ $1_FALSE= ++fi ++AC_CONFIG_COMMANDS_PRE( ++[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then ++ AC_MSG_ERROR([[conditional "$1" was never defined. ++Usually this means the macro was only invoked conditionally.]]) ++fi])]) ++ ++ ++# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 ++# Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# serial 8 ++ ++# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be ++# written in clear, in which case automake, when reading aclocal.m4, ++# will think it sees a *use*, and therefore will trigger all it's ++# C support machinery. Also note that it means that autoscan, seeing ++# CC etc. in the Makefile, will ask for an AC_PROG_CC use... ++ ++ ++# _AM_DEPENDENCIES(NAME) ++# ---------------------- ++# See how the compiler implements dependency checking. ++# NAME is "CC", "CXX", "GCJ", or "OBJC". ++# We try a few techniques and use that to set a single cache variable. ++# ++# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was ++# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular ++# dependency, and given that the user is not expected to run this macro, ++# just rely on AC_PROG_CC. ++AC_DEFUN([_AM_DEPENDENCIES], ++[AC_REQUIRE([AM_SET_DEPDIR])dnl ++AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl ++AC_REQUIRE([AM_MAKE_INCLUDE])dnl ++AC_REQUIRE([AM_DEP_TRACK])dnl ++ ++ifelse([$1], CC, [depcc="$CC" am_compiler_list=], ++ [$1], CXX, [depcc="$CXX" am_compiler_list=], ++ [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], ++ [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], ++ [depcc="$$1" am_compiler_list=]) ++ ++AC_CACHE_CHECK([dependency style of $depcc], ++ [am_cv_$1_dependencies_compiler_type], ++[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then ++ # We make a subdir and do the tests there. Otherwise we can end up ++ # making bogus files that we don't know about and never remove. For ++ # instance it was reported that on HP-UX the gcc test will end up ++ # making a dummy file named `D' -- because `-MD' means `put the output ++ # in D'. ++ mkdir conftest.dir ++ # Copy depcomp to subdir because otherwise we won't find it if we're ++ # using a relative directory. ++ cp "$am_depcomp" conftest.dir ++ cd conftest.dir ++ # We will build objects and dependencies in a subdirectory because ++ # it helps to detect inapplicable dependency modes. For instance ++ # both Tru64's cc and ICC support -MD to output dependencies as a ++ # side effect of compilation, but ICC will put the dependencies in ++ # the current directory while Tru64 will put them in the object ++ # directory. ++ mkdir sub ++ ++ am_cv_$1_dependencies_compiler_type=none ++ if test "$am_compiler_list" = ""; then ++ am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` ++ fi ++ for depmode in $am_compiler_list; do ++ # Setup a source with many dependencies, because some compilers ++ # like to wrap large dependency lists on column 80 (with \), and ++ # we should not choose a depcomp mode which is confused by this. ++ # ++ # We need to recreate these files for each test, as the compiler may ++ # overwrite some of them when testing with obscure command lines. ++ # This happens at least with the AIX C compiler. ++ : > sub/conftest.c ++ for i in 1 2 3 4 5 6; do ++ echo '#include "conftst'$i'.h"' >> sub/conftest.c ++ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with ++ # Solaris 8's {/usr,}/bin/sh. ++ touch sub/conftst$i.h ++ done ++ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf ++ ++ case $depmode in ++ nosideeffect) ++ # after this tag, mechanisms are not by side-effect, so they'll ++ # only be used when explicitly requested ++ if test "x$enable_dependency_tracking" = xyes; then ++ continue ++ else ++ break ++ fi ++ ;; ++ none) break ;; ++ esac ++ # We check with `-c' and `-o' for the sake of the "dashmstdout" ++ # mode. It turns out that the SunPro C++ compiler does not properly ++ # handle `-M -o', and we need to detect this. ++ if depmode=$depmode \ ++ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ ++ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ ++ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ ++ >/dev/null 2>conftest.err && ++ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && ++ grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && ++ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then ++ # icc doesn't choke on unknown options, it will just issue warnings ++ # or remarks (even with -Werror). So we grep stderr for any message ++ # that says an option was ignored or not supported. ++ # When given -MP, icc 7.0 and 7.1 complain thusly: ++ # icc: Command line warning: ignoring option '-M'; no argument required ++ # The diagnosis changed in icc 8.0: ++ # icc: Command line remark: option '-MP' not supported ++ if (grep 'ignoring option' conftest.err || ++ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else ++ am_cv_$1_dependencies_compiler_type=$depmode ++ break ++ fi ++ fi ++ done ++ ++ cd .. ++ rm -rf conftest.dir ++else ++ am_cv_$1_dependencies_compiler_type=none ++fi ++]) ++AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) ++AM_CONDITIONAL([am__fastdep$1], [ ++ test "x$enable_dependency_tracking" != xno \ ++ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ++]) ++ ++ ++# AM_SET_DEPDIR ++# ------------- ++# Choose a directory name for dependency files. ++# This macro is AC_REQUIREd in _AM_DEPENDENCIES ++AC_DEFUN([AM_SET_DEPDIR], ++[AC_REQUIRE([AM_SET_LEADING_DOT])dnl ++AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ++]) ++ ++ ++# AM_DEP_TRACK ++# ------------ ++AC_DEFUN([AM_DEP_TRACK], ++[AC_ARG_ENABLE(dependency-tracking, ++[ --disable-dependency-tracking speeds up one-time build ++ --enable-dependency-tracking do not reject slow dependency extractors]) ++if test "x$enable_dependency_tracking" != xno; then ++ am_depcomp="$ac_aux_dir/depcomp" ++ AMDEPBACKSLASH='\' ++fi ++AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) ++AC_SUBST([AMDEPBACKSLASH]) ++]) ++ ++# Generate code to set up dependency tracking. -*- Autoconf -*- ++ ++# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 ++# Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++#serial 3 ++ ++# _AM_OUTPUT_DEPENDENCY_COMMANDS ++# ------------------------------ ++AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], ++[for mf in $CONFIG_FILES; do ++ # Strip MF so we end up with the name of the file. ++ mf=`echo "$mf" | sed -e 's/:.*$//'` ++ # Check whether this is an Automake generated Makefile or not. ++ # We used to match only the files named `Makefile.in', but ++ # some people rename them; so instead we look at the file content. ++ # Grep'ing the first line is not enough: some people post-process ++ # each Makefile.in and add a new line on top of each file to say so. ++ # So let's grep whole file. ++ if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then ++ dirpart=`AS_DIRNAME("$mf")` ++ else ++ continue ++ fi ++ # Extract the definition of DEPDIR, am__include, and am__quote ++ # from the Makefile without running `make'. ++ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` ++ test -z "$DEPDIR" && continue ++ am__include=`sed -n 's/^am__include = //p' < "$mf"` ++ test -z "am__include" && continue ++ am__quote=`sed -n 's/^am__quote = //p' < "$mf"` ++ # When using ansi2knr, U may be empty or an underscore; expand it ++ U=`sed -n 's/^U = //p' < "$mf"` ++ # Find all dependency output files, they are included files with ++ # $(DEPDIR) in their names. We invoke sed twice because it is the ++ # simplest approach to changing $(DEPDIR) to its actual value in the ++ # expansion. ++ for file in `sed -n " ++ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ ++ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do ++ # Make sure the directory exists. ++ test -f "$dirpart/$file" && continue ++ fdir=`AS_DIRNAME(["$file"])` ++ AS_MKDIR_P([$dirpart/$fdir]) ++ # echo "creating $dirpart/$file" ++ echo '# dummy' > "$dirpart/$file" ++ done ++done ++])# _AM_OUTPUT_DEPENDENCY_COMMANDS ++ ++ ++# AM_OUTPUT_DEPENDENCY_COMMANDS ++# ----------------------------- ++# This macro should only be invoked once -- use via AC_REQUIRE. ++# ++# This code is only required when automatic dependency tracking ++# is enabled. FIXME. This creates each `.P' file that we will ++# need in order to bootstrap the dependency handling code. ++AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], ++[AC_CONFIG_COMMANDS([depfiles], ++ [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], ++ [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ++]) ++ ++# Do all the work for Automake. -*- Autoconf -*- ++ ++# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 ++# Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# serial 12 ++ ++# This macro actually does too much. Some checks are only needed if ++# your package does certain things. But this isn't really a big deal. ++ ++# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) ++# AM_INIT_AUTOMAKE([OPTIONS]) ++# ----------------------------------------------- ++# The call with PACKAGE and VERSION arguments is the old style ++# call (pre autoconf-2.50), which is being phased out. PACKAGE ++# and VERSION should now be passed to AC_INIT and removed from ++# the call to AM_INIT_AUTOMAKE. ++# We support both call styles for the transition. After ++# the next Automake release, Autoconf can make the AC_INIT ++# arguments mandatory, and then we can depend on a new Autoconf ++# release and drop the old call support. ++AC_DEFUN([AM_INIT_AUTOMAKE], ++[AC_PREREQ([2.58])dnl ++dnl Autoconf wants to disallow AM_ names. We explicitly allow ++dnl the ones we care about. ++m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl ++AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl ++AC_REQUIRE([AC_PROG_INSTALL])dnl ++# test to see if srcdir already configured ++if test "`cd $srcdir && pwd`" != "`pwd`" && ++ test -f $srcdir/config.status; then ++ AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) ++fi ++ ++# test whether we have cygpath ++if test -z "$CYGPATH_W"; then ++ if (cygpath --version) >/dev/null 2>/dev/null; then ++ CYGPATH_W='cygpath -w' ++ else ++ CYGPATH_W=echo ++ fi ++fi ++AC_SUBST([CYGPATH_W]) ++ ++# Define the identity of the package. ++dnl Distinguish between old-style and new-style calls. ++m4_ifval([$2], ++[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl ++ AC_SUBST([PACKAGE], [$1])dnl ++ AC_SUBST([VERSION], [$2])], ++[_AM_SET_OPTIONS([$1])dnl ++ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl ++ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl ++ ++_AM_IF_OPTION([no-define],, ++[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) ++ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl ++ ++# Some tools Automake needs. ++AC_REQUIRE([AM_SANITY_CHECK])dnl ++AC_REQUIRE([AC_ARG_PROGRAM])dnl ++AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) ++AM_MISSING_PROG(AUTOCONF, autoconf) ++AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) ++AM_MISSING_PROG(AUTOHEADER, autoheader) ++AM_MISSING_PROG(MAKEINFO, makeinfo) ++AM_PROG_INSTALL_SH ++AM_PROG_INSTALL_STRIP ++AC_REQUIRE([AM_PROG_MKDIR_P])dnl ++# We need awk for the "check" target. The system "awk" is bad on ++# some platforms. ++AC_REQUIRE([AC_PROG_AWK])dnl ++AC_REQUIRE([AC_PROG_MAKE_SET])dnl ++AC_REQUIRE([AM_SET_LEADING_DOT])dnl ++_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], ++ [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], ++ [_AM_PROG_TAR([v7])])]) ++_AM_IF_OPTION([no-dependencies],, ++[AC_PROVIDE_IFELSE([AC_PROG_CC], ++ [_AM_DEPENDENCIES(CC)], ++ [define([AC_PROG_CC], ++ defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl ++AC_PROVIDE_IFELSE([AC_PROG_CXX], ++ [_AM_DEPENDENCIES(CXX)], ++ [define([AC_PROG_CXX], ++ defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl ++]) ++]) ++ ++ ++# When config.status generates a header, we must update the stamp-h file. ++# This file resides in the same directory as the config header ++# that is generated. The stamp files are numbered to have different names. ++ ++# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the ++# loop where config.status creates the headers, so we can generate ++# our stamp files there. ++AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], ++[# Compute $1's index in $config_headers. ++_am_stamp_count=1 ++for _am_header in $config_headers :; do ++ case $_am_header in ++ $1 | $1:* ) ++ break ;; ++ * ) ++ _am_stamp_count=`expr $_am_stamp_count + 1` ;; ++ esac ++done ++echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) ++ ++# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# AM_PROG_INSTALL_SH ++# ------------------ ++# Define $install_sh. ++AC_DEFUN([AM_PROG_INSTALL_SH], ++[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl ++install_sh=${install_sh-"$am_aux_dir/install-sh"} ++AC_SUBST(install_sh)]) ++ ++# Copyright (C) 2003, 2005 Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# serial 2 ++ ++# Check whether the underlying file-system supports filenames ++# with a leading dot. For instance MS-DOS doesn't. ++AC_DEFUN([AM_SET_LEADING_DOT], ++[rm -rf .tst 2>/dev/null ++mkdir .tst 2>/dev/null ++if test -d .tst; then ++ am__leading_dot=. ++else ++ am__leading_dot=_ ++fi ++rmdir .tst 2>/dev/null ++AC_SUBST([am__leading_dot])]) ++ ++# Check to see how 'make' treats includes. -*- Autoconf -*- ++ ++# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# serial 3 ++ ++# AM_MAKE_INCLUDE() ++# ----------------- ++# Check to see how make treats includes. ++AC_DEFUN([AM_MAKE_INCLUDE], ++[am_make=${MAKE-make} ++cat > confinc << 'END' ++am__doit: ++ @echo done ++.PHONY: am__doit ++END ++# If we don't find an include directive, just comment out the code. ++AC_MSG_CHECKING([for style of include used by $am_make]) ++am__include="#" ++am__quote= ++_am_result=none ++# First try GNU make style include. ++echo "include confinc" > confmf ++# We grep out `Entering directory' and `Leaving directory' ++# messages which can occur if `w' ends up in MAKEFLAGS. ++# In particular we don't look at `^make:' because GNU make might ++# be invoked under some other name (usually "gmake"), in which ++# case it prints its new name instead of `make'. ++if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then ++ am__include=include ++ am__quote= ++ _am_result=GNU ++fi ++# Now try BSD make style include. ++if test "$am__include" = "#"; then ++ echo '.include "confinc"' > confmf ++ if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then ++ am__include=.include ++ am__quote="\"" ++ _am_result=BSD ++ fi ++fi ++AC_SUBST([am__include]) ++AC_SUBST([am__quote]) ++AC_MSG_RESULT([$_am_result]) ++rm -f confinc confmf ++]) ++ ++# Copyright (C) 1999, 2000, 2001, 2003, 2005 Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# serial 3 ++ ++# AM_PROG_CC_C_O ++# -------------- ++# Like AC_PROG_CC_C_O, but changed for automake. ++AC_DEFUN([AM_PROG_CC_C_O], ++[AC_REQUIRE([AC_PROG_CC_C_O])dnl ++AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl ++# FIXME: we rely on the cache variable name because ++# there is no other way. ++set dummy $CC ++ac_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']` ++if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" != yes"; then ++ # Losing compiler, so override with the script. ++ # FIXME: It is wrong to rewrite CC. ++ # But if we don't then we get into trouble of one sort or another. ++ # A longer-term fix would be to have automake use am__CC in this case, ++ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" ++ CC="$am_aux_dir/compile $CC" ++fi ++]) ++ ++# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- ++ ++# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2005 ++# Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# serial 4 ++ ++# AM_MISSING_PROG(NAME, PROGRAM) ++# ------------------------------ ++AC_DEFUN([AM_MISSING_PROG], ++[AC_REQUIRE([AM_MISSING_HAS_RUN]) ++$1=${$1-"${am_missing_run}$2"} ++AC_SUBST($1)]) ++ ++ ++# AM_MISSING_HAS_RUN ++# ------------------ ++# Define MISSING if not defined so far and test if it supports --run. ++# If it does, set am_missing_run to use it, otherwise, to nothing. ++AC_DEFUN([AM_MISSING_HAS_RUN], ++[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl ++test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" ++# Use eval to expand $SHELL ++if eval "$MISSING --run true"; then ++ am_missing_run="$MISSING --run " ++else ++ am_missing_run= ++ AC_MSG_WARN([`missing' script is too old or missing]) ++fi ++]) ++ ++# Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# AM_PROG_MKDIR_P ++# --------------- ++# Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise. ++# ++# Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories ++# created by `make install' are always world readable, even if the ++# installer happens to have an overly restrictive umask (e.g. 077). ++# This was a mistake. There are at least two reasons why we must not ++# use `-m 0755': ++# - it causes special bits like SGID to be ignored, ++# - it may be too restrictive (some setups expect 775 directories). ++# ++# Do not use -m 0755 and let people choose whatever they expect by ++# setting umask. ++# ++# We cannot accept any implementation of `mkdir' that recognizes `-p'. ++# Some implementations (such as Solaris 8's) are not thread-safe: if a ++# parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c' ++# concurrently, both version can detect that a/ is missing, but only ++# one can create it and the other will error out. Consequently we ++# restrict ourselves to GNU make (using the --version option ensures ++# this.) ++AC_DEFUN([AM_PROG_MKDIR_P], ++[if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then ++ # We used to keeping the `.' as first argument, in order to ++ # allow $(mkdir_p) to be used without argument. As in ++ # $(mkdir_p) $(somedir) ++ # where $(somedir) is conditionally defined. However this is wrong ++ # for two reasons: ++ # 1. if the package is installed by a user who cannot write `.' ++ # make install will fail, ++ # 2. the above comment should most certainly read ++ # $(mkdir_p) $(DESTDIR)$(somedir) ++ # so it does not work when $(somedir) is undefined and ++ # $(DESTDIR) is not. ++ # To support the latter case, we have to write ++ # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), ++ # so the `.' trick is pointless. ++ mkdir_p='mkdir -p --' ++else ++ # On NextStep and OpenStep, the `mkdir' command does not ++ # recognize any option. It will interpret all options as ++ # directories to create, and then abort because `.' already ++ # exists. ++ for d in ./-p ./--version; ++ do ++ test -d $d && rmdir $d ++ done ++ # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. ++ if test -f "$ac_aux_dir/mkinstalldirs"; then ++ mkdir_p='$(mkinstalldirs)' ++ else ++ mkdir_p='$(install_sh) -d' ++ fi ++fi ++AC_SUBST([mkdir_p])]) ++ ++# Helper functions for option handling. -*- Autoconf -*- ++ ++# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# serial 3 ++ ++# _AM_MANGLE_OPTION(NAME) ++# ----------------------- ++AC_DEFUN([_AM_MANGLE_OPTION], ++[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) ++ ++# _AM_SET_OPTION(NAME) ++# ------------------------------ ++# Set option NAME. Presently that only means defining a flag for this option. ++AC_DEFUN([_AM_SET_OPTION], ++[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) ++ ++# _AM_SET_OPTIONS(OPTIONS) ++# ---------------------------------- ++# OPTIONS is a space-separated list of Automake options. ++AC_DEFUN([_AM_SET_OPTIONS], ++[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) ++ ++# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) ++# ------------------------------------------- ++# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. ++AC_DEFUN([_AM_IF_OPTION], ++[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) ++ ++# Check to make sure that the build environment is sane. -*- Autoconf -*- ++ ++# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 ++# Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# serial 4 ++ ++# AM_SANITY_CHECK ++# --------------- ++AC_DEFUN([AM_SANITY_CHECK], ++[AC_MSG_CHECKING([whether build environment is sane]) ++# Just in case ++sleep 1 ++echo timestamp > conftest.file ++# Do `set' in a subshell so we don't clobber the current shell's ++# arguments. Must try -L first in case configure is actually a ++# symlink; some systems play weird games with the mod time of symlinks ++# (eg FreeBSD returns the mod time of the symlink's containing ++# directory). ++if ( ++ set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` ++ if test "$[*]" = "X"; then ++ # -L didn't work. ++ set X `ls -t $srcdir/configure conftest.file` ++ fi ++ rm -f conftest.file ++ if test "$[*]" != "X $srcdir/configure conftest.file" \ ++ && test "$[*]" != "X conftest.file $srcdir/configure"; then ++ ++ # If neither matched, then we have a broken ls. This can happen ++ # if, for instance, CONFIG_SHELL is bash and it inherits a ++ # broken ls alias from the environment. This has actually ++ # happened. Such a system could not be considered "sane". ++ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken ++alias in your environment]) ++ fi ++ ++ test "$[2]" = conftest.file ++ ) ++then ++ # Ok. ++ : ++else ++ AC_MSG_ERROR([newly created file is older than distributed files! ++Check your system clock]) ++fi ++AC_MSG_RESULT(yes)]) ++ ++# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# AM_PROG_INSTALL_STRIP ++# --------------------- ++# One issue with vendor `install' (even GNU) is that you can't ++# specify the program used to strip binaries. This is especially ++# annoying in cross-compiling environments, where the build's strip ++# is unlikely to handle the host's binaries. ++# Fortunately install-sh will honor a STRIPPROG variable, so we ++# always use install-sh in `make install-strip', and initialize ++# STRIPPROG with the value of the STRIP variable (set by the user). ++AC_DEFUN([AM_PROG_INSTALL_STRIP], ++[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl ++# Installed binaries are usually stripped using `strip' when the user ++# run `make install-strip'. However `strip' might not be the right ++# tool to use in cross-compilation environments, therefore Automake ++# will honor the `STRIP' environment variable to overrule this program. ++dnl Don't test for $cross_compiling = yes, because it might be `maybe'. ++if test "$cross_compiling" != no; then ++ AC_CHECK_TOOL([STRIP], [strip], :) ++fi ++INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" ++AC_SUBST([INSTALL_STRIP_PROGRAM])]) ++ ++# Check how to create a tarball. -*- Autoconf -*- ++ ++# Copyright (C) 2004, 2005 Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# serial 2 ++ ++# _AM_PROG_TAR(FORMAT) ++# -------------------- ++# Check how to create a tarball in format FORMAT. ++# FORMAT should be one of `v7', `ustar', or `pax'. ++# ++# Substitute a variable $(am__tar) that is a command ++# writing to stdout a FORMAT-tarball containing the directory ++# $tardir. ++# tardir=directory && $(am__tar) > result.tar ++# ++# Substitute a variable $(am__untar) that extract such ++# a tarball read from stdin. ++# $(am__untar) < result.tar ++AC_DEFUN([_AM_PROG_TAR], ++[# Always define AMTAR for backward compatibility. ++AM_MISSING_PROG([AMTAR], [tar]) ++m4_if([$1], [v7], ++ [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], ++ [m4_case([$1], [ustar],, [pax],, ++ [m4_fatal([Unknown tar format])]) ++AC_MSG_CHECKING([how to create a $1 tar archive]) ++# Loop over all known methods to create a tar archive until one works. ++_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' ++_am_tools=${am_cv_prog_tar_$1-$_am_tools} ++# Do not fold the above two line into one, because Tru64 sh and ++# Solaris sh will not grok spaces in the rhs of `-'. ++for _am_tool in $_am_tools ++do ++ case $_am_tool in ++ gnutar) ++ for _am_tar in tar gnutar gtar; ++ do ++ AM_RUN_LOG([$_am_tar --version]) && break ++ done ++ am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' ++ am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' ++ am__untar="$_am_tar -xf -" ++ ;; ++ plaintar) ++ # Must skip GNU tar: if it does not support --format= it doesn't create ++ # ustar tarball either. ++ (tar --version) >/dev/null 2>&1 && continue ++ am__tar='tar chf - "$$tardir"' ++ am__tar_='tar chf - "$tardir"' ++ am__untar='tar xf -' ++ ;; ++ pax) ++ am__tar='pax -L -x $1 -w "$$tardir"' ++ am__tar_='pax -L -x $1 -w "$tardir"' ++ am__untar='pax -r' ++ ;; ++ cpio) ++ am__tar='find "$$tardir" -print | cpio -o -H $1 -L' ++ am__tar_='find "$tardir" -print | cpio -o -H $1 -L' ++ am__untar='cpio -i -H $1 -d' ++ ;; ++ none) ++ am__tar=false ++ am__tar_=false ++ am__untar=false ++ ;; ++ esac ++ ++ # If the value was cached, stop now. We just wanted to have am__tar ++ # and am__untar set. ++ test -n "${am_cv_prog_tar_$1}" && break ++ ++ # tar/untar a dummy directory, and stop if the command works ++ rm -rf conftest.dir ++ mkdir conftest.dir ++ echo GrepMe > conftest.dir/file ++ AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) ++ rm -rf conftest.dir ++ if test -s conftest.tar; then ++ AM_RUN_LOG([$am__untar /dev/null 2>&1 && break ++ fi ++done ++rm -rf conftest.dir ++ ++AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) ++AC_MSG_RESULT([$am_cv_prog_tar_$1])]) ++AC_SUBST([am__tar]) ++AC_SUBST([am__untar]) ++]) # _AM_PROG_TAR ++ +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/ChangeLog open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/ChangeLog +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/ChangeLog 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/ChangeLog 2012-04-09 21:52:14.000000000 -0500 +@@ -0,0 +1,7 @@ ++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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/compile open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/compile +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/compile 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/compile 2012-04-09 21:52:14.000000000 -0500 +@@ -0,0 +1,142 @@ ++#! /bin/sh ++# Wrapper for compilers which do not understand `-c -o'. ++ ++scriptversion=2005-05-14.22 ++ ++# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc. ++# Written by Tom Tromey . ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2, or (at your option) ++# any later version. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ ++# As a special exception to the GNU General Public License, if you ++# distribute this file as part of a program that contains a ++# configuration script generated by Autoconf, you may include it under ++# the same distribution terms that you use for the rest of that program. ++ ++# This file is maintained in Automake, please report ++# bugs to or send patches to ++# . ++ ++case $1 in ++ '') ++ echo "$0: No command. Try \`$0 --help' for more information." 1>&2 ++ exit 1; ++ ;; ++ -h | --h*) ++ cat <<\EOF ++Usage: compile [--help] [--version] PROGRAM [ARGS] ++ ++Wrapper for compilers which do not understand `-c -o'. ++Remove `-o dest.o' from ARGS, run PROGRAM with the remaining ++arguments, and rename the output as expected. ++ ++If you are trying to build a whole package this is not the ++right script to run: please start by reading the file `INSTALL'. ++ ++Report bugs to . ++EOF ++ exit $? ++ ;; ++ -v | --v*) ++ echo "compile $scriptversion" ++ exit $? ++ ;; ++esac ++ ++ofile= ++cfile= ++eat= ++ ++for arg ++do ++ if test -n "$eat"; then ++ eat= ++ else ++ case $1 in ++ -o) ++ # configure might choose to run compile as `compile cc -o foo foo.c'. ++ # So we strip `-o arg' only if arg is an object. ++ eat=1 ++ case $2 in ++ *.o | *.obj) ++ ofile=$2 ++ ;; ++ *) ++ set x "$@" -o "$2" ++ shift ++ ;; ++ esac ++ ;; ++ *.c) ++ cfile=$1 ++ set x "$@" "$1" ++ shift ++ ;; ++ *) ++ set x "$@" "$1" ++ shift ++ ;; ++ esac ++ fi ++ shift ++done ++ ++if test -z "$ofile" || test -z "$cfile"; then ++ # If no `-o' option was seen then we might have been invoked from a ++ # pattern rule where we don't need one. That is ok -- this is a ++ # normal compilation that the losing compiler can handle. If no ++ # `.c' file was seen then we are probably linking. That is also ++ # ok. ++ exec "$@" ++fi ++ ++# Name of file we expect compiler to create. ++cofile=`echo "$cfile" | sed -e 's|^.*/||' -e 's/\.c$/.o/'` ++ ++# Create the lock directory. ++# Note: use `[/.-]' here to ensure that we don't use the same name ++# that we are using for the .o file. Also, base the name on the expected ++# object file name, since that is what matters with a parallel build. ++lockdir=`echo "$cofile" | sed -e 's|[/.-]|_|g'`.d ++while true; do ++ if mkdir "$lockdir" >/dev/null 2>&1; then ++ break ++ fi ++ sleep 1 ++done ++# FIXME: race condition here if user kills between mkdir and trap. ++trap "rmdir '$lockdir'; exit 1" 1 2 15 ++ ++# Run the compile. ++"$@" ++ret=$? ++ ++if test -f "$cofile"; then ++ mv "$cofile" "$ofile" ++elif test -f "${cofile}bj"; then ++ mv "${cofile}bj" "$ofile" ++fi ++ ++rmdir "$lockdir" ++exit $ret ++ ++# Local Variables: ++# mode: shell-script ++# sh-indentation: 2 ++# eval: (add-hook 'write-file-hooks 'time-stamp) ++# time-stamp-start: "scriptversion=" ++# time-stamp-format: "%:y-%02m-%02d.%02H" ++# time-stamp-end: "$" ++# End: +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/config.guess open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/config.guess +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/config.guess 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/config.guess 2012-04-09 21:52:14.000000000 -0500 +@@ -0,0 +1,1548 @@ ++#! /bin/sh ++# Attempt to guess a canonical system name. ++# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, ++# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 ++# Free Software Foundation, Inc. ++ ++timestamp='2008-09-28' ++ ++# This file is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA ++# 02110-1301, USA. ++# ++# As a special exception to the GNU General Public License, if you ++# distribute this file as part of a program that contains a ++# configuration script generated by Autoconf, you may include it under ++# the same distribution terms that you use for the rest of that program. ++ ++ ++# Originally written by Per Bothner . ++# Please send patches to . Submit a context ++# diff and a properly formatted ChangeLog entry. ++# ++# This script attempts to guess a canonical system name similar to ++# config.sub. If it succeeds, it prints the system name on stdout, and ++# exits with 0. Otherwise, it exits with 1. ++# ++# The plan is that this can be called by configure scripts if you ++# don't specify an explicit build system type. ++ ++me=`echo "$0" | sed -e 's,.*/,,'` ++ ++usage="\ ++Usage: $0 [OPTION] ++ ++Output the configuration name of the system \`$me' is run on. ++ ++Operation modes: ++ -h, --help print this help, then exit ++ -t, --time-stamp print date of last modification, then exit ++ -v, --version print version number, then exit ++ ++Report bugs and patches to ." ++ ++version="\ ++GNU config.guess ($timestamp) ++ ++Originally written by Per Bothner. ++Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, ++2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. ++ ++This is free software; see the source for copying conditions. There is NO ++warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." ++ ++help=" ++Try \`$me --help' for more information." ++ ++# Parse command line ++while test $# -gt 0 ; do ++ case $1 in ++ --time-stamp | --time* | -t ) ++ echo "$timestamp" ; exit ;; ++ --version | -v ) ++ echo "$version" ; exit ;; ++ --help | --h* | -h ) ++ echo "$usage"; exit ;; ++ -- ) # Stop option processing ++ shift; break ;; ++ - ) # Use stdin as input. ++ break ;; ++ -* ) ++ echo "$me: invalid option $1$help" >&2 ++ exit 1 ;; ++ * ) ++ break ;; ++ esac ++done ++ ++if test $# != 0; then ++ echo "$me: too many arguments$help" >&2 ++ exit 1 ++fi ++ ++trap 'exit 1' 1 2 15 ++ ++# CC_FOR_BUILD -- compiler used by this script. Note that the use of a ++# compiler to aid in system detection is discouraged as it requires ++# temporary files to be created and, as you can see below, it is a ++# headache to deal with in a portable fashion. ++ ++# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still ++# use `HOST_CC' if defined, but it is deprecated. ++ ++# Portable tmp directory creation inspired by the Autoconf team. ++ ++set_cc_for_build=' ++trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; ++trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; ++: ${TMPDIR=/tmp} ; ++ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || ++ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || ++ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || ++ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; ++dummy=$tmp/dummy ; ++tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; ++case $CC_FOR_BUILD,$HOST_CC,$CC in ++ ,,) echo "int x;" > $dummy.c ; ++ for c in cc gcc c89 c99 ; do ++ if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then ++ CC_FOR_BUILD="$c"; break ; ++ fi ; ++ done ; ++ if test x"$CC_FOR_BUILD" = x ; then ++ CC_FOR_BUILD=no_compiler_found ; ++ fi ++ ;; ++ ,,*) CC_FOR_BUILD=$CC ;; ++ ,*,*) CC_FOR_BUILD=$HOST_CC ;; ++esac ; set_cc_for_build= ;' ++ ++# This is needed to find uname on a Pyramid OSx when run in the BSD universe. ++# (ghazi@noc.rutgers.edu 1994-08-24) ++if (test -f /.attbin/uname) >/dev/null 2>&1 ; then ++ PATH=$PATH:/.attbin ; export PATH ++fi ++ ++UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown ++UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown ++UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown ++UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown ++ ++if [ "${UNAME_SYSTEM}" = "Linux" ] ; then ++ eval $set_cc_for_build ++ cat << EOF > $dummy.c ++ #include ++ #ifdef __UCLIBC__ ++ # ifdef __UCLIBC_CONFIG_VERSION__ ++ LIBC=uclibc __UCLIBC_CONFIG_VERSION__ ++ # else ++ LIBC=uclibc ++ # endif ++ #else ++ LIBC=gnu ++ #endif ++EOF ++ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep LIBC= | sed -e 's: ::g'` ++fi ++ ++# Note: order is significant - the case branches are not exclusive. ++ ++case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in ++ *:NetBSD:*:*) ++ # NetBSD (nbsd) targets should (where applicable) match one or ++ # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, ++ # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently ++ # switched to ELF, *-*-netbsd* would select the old ++ # object file format. This provides both forward ++ # compatibility and a consistent mechanism for selecting the ++ # object file format. ++ # ++ # Note: NetBSD doesn't particularly care about the vendor ++ # portion of the name. We always set it to "unknown". ++ sysctl="sysctl -n hw.machine_arch" ++ UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ ++ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` ++ case "${UNAME_MACHINE_ARCH}" in ++ armeb) machine=armeb-unknown ;; ++ arm*) machine=arm-unknown ;; ++ sh3el) machine=shl-unknown ;; ++ sh3eb) machine=sh-unknown ;; ++ sh5el) machine=sh5le-unknown ;; ++ *) machine=${UNAME_MACHINE_ARCH}-unknown ;; ++ esac ++ # The Operating System including object format, if it has switched ++ # to ELF recently, or will in the future. ++ case "${UNAME_MACHINE_ARCH}" in ++ arm*|i386|m68k|ns32k|sh3*|sparc|vax) ++ eval $set_cc_for_build ++ if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ ++ | grep __ELF__ >/dev/null ++ then ++ # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). ++ # Return netbsd for either. FIX? ++ os=netbsd ++ else ++ os=netbsdelf ++ fi ++ ;; ++ *) ++ os=netbsd ++ ;; ++ esac ++ # The OS release ++ # Debian GNU/NetBSD machines have a different userland, and ++ # thus, need a distinct triplet. However, they do not need ++ # kernel version information, so it can be replaced with a ++ # suitable tag, in the style of linux-gnu. ++ case "${UNAME_VERSION}" in ++ Debian*) ++ release='-gnu' ++ ;; ++ *) ++ release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ++ ;; ++ esac ++ # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: ++ # contains redundant information, the shorter form: ++ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. ++ echo "${machine}-${os}${release}" ++ exit ;; ++ *:OpenBSD:*:*) ++ UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` ++ echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} ++ exit ;; ++ *:ekkoBSD:*:*) ++ echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} ++ exit ;; ++ *:SolidBSD:*:*) ++ echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} ++ exit ;; ++ macppc:MirBSD:*:*) ++ echo powerpc-unknown-mirbsd${UNAME_RELEASE} ++ exit ;; ++ *:MirBSD:*:*) ++ echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} ++ exit ;; ++ alpha:OSF1:*:*) ++ case $UNAME_RELEASE in ++ *4.0) ++ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ++ ;; ++ *5.*) ++ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ++ ;; ++ esac ++ # According to Compaq, /usr/sbin/psrinfo has been available on ++ # OSF/1 and Tru64 systems produced since 1995. I hope that ++ # covers most systems running today. This code pipes the CPU ++ # types through head -n 1, so we only detect the type of CPU 0. ++ ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` ++ case "$ALPHA_CPU_TYPE" in ++ "EV4 (21064)") ++ UNAME_MACHINE="alpha" ;; ++ "EV4.5 (21064)") ++ UNAME_MACHINE="alpha" ;; ++ "LCA4 (21066/21068)") ++ UNAME_MACHINE="alpha" ;; ++ "EV5 (21164)") ++ UNAME_MACHINE="alphaev5" ;; ++ "EV5.6 (21164A)") ++ UNAME_MACHINE="alphaev56" ;; ++ "EV5.6 (21164PC)") ++ UNAME_MACHINE="alphapca56" ;; ++ "EV5.7 (21164PC)") ++ UNAME_MACHINE="alphapca57" ;; ++ "EV6 (21264)") ++ UNAME_MACHINE="alphaev6" ;; ++ "EV6.7 (21264A)") ++ UNAME_MACHINE="alphaev67" ;; ++ "EV6.8CB (21264C)") ++ UNAME_MACHINE="alphaev68" ;; ++ "EV6.8AL (21264B)") ++ UNAME_MACHINE="alphaev68" ;; ++ "EV6.8CX (21264D)") ++ UNAME_MACHINE="alphaev68" ;; ++ "EV6.9A (21264/EV69A)") ++ UNAME_MACHINE="alphaev69" ;; ++ "EV7 (21364)") ++ UNAME_MACHINE="alphaev7" ;; ++ "EV7.9 (21364A)") ++ UNAME_MACHINE="alphaev79" ;; ++ esac ++ # A Pn.n version is a patched version. ++ # A Vn.n version is a released version. ++ # A Tn.n version is a released field test version. ++ # A Xn.n version is an unreleased experimental baselevel. ++ # 1.2 uses "1.2" for uname -r. ++ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` ++ exit ;; ++ Alpha\ *:Windows_NT*:*) ++ # How do we know it's Interix rather than the generic POSIX subsystem? ++ # Should we change UNAME_MACHINE based on the output of uname instead ++ # of the specific Alpha model? ++ echo alpha-pc-interix ++ exit ;; ++ 21064:Windows_NT:50:3) ++ echo alpha-dec-winnt3.5 ++ exit ;; ++ Amiga*:UNIX_System_V:4.0:*) ++ echo m68k-unknown-sysv4 ++ exit ;; ++ *:[Aa]miga[Oo][Ss]:*:*) ++ echo ${UNAME_MACHINE}-unknown-amigaos ++ exit ;; ++ *:[Mm]orph[Oo][Ss]:*:*) ++ echo ${UNAME_MACHINE}-unknown-morphos ++ exit ;; ++ *:OS/390:*:*) ++ echo i370-ibm-openedition ++ exit ;; ++ *:z/VM:*:*) ++ echo s390-ibm-zvmoe ++ exit ;; ++ *:OS400:*:*) ++ echo powerpc-ibm-os400 ++ exit ;; ++ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) ++ echo arm-acorn-riscix${UNAME_RELEASE} ++ exit ;; ++ arm:riscos:*:*|arm:RISCOS:*:*) ++ echo arm-unknown-riscos ++ exit ;; ++ SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) ++ echo hppa1.1-hitachi-hiuxmpp ++ exit ;; ++ Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) ++ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. ++ if test "`(/bin/universe) 2>/dev/null`" = att ; then ++ echo pyramid-pyramid-sysv3 ++ else ++ echo pyramid-pyramid-bsd ++ fi ++ exit ;; ++ NILE*:*:*:dcosx) ++ echo pyramid-pyramid-svr4 ++ exit ;; ++ DRS?6000:unix:4.0:6*) ++ echo sparc-icl-nx6 ++ exit ;; ++ DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) ++ case `/usr/bin/uname -p` in ++ sparc) echo sparc-icl-nx7; exit ;; ++ esac ;; ++ sun4H:SunOS:5.*:*) ++ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` ++ exit ;; ++ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) ++ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` ++ exit ;; ++ i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) ++ echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` ++ exit ;; ++ sun4*:SunOS:6*:*) ++ # According to config.sub, this is the proper way to canonicalize ++ # SunOS6. Hard to guess exactly what SunOS6 will be like, but ++ # it's likely to be more like Solaris than SunOS4. ++ echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` ++ exit ;; ++ sun4*:SunOS:*:*) ++ case "`/usr/bin/arch -k`" in ++ Series*|S4*) ++ UNAME_RELEASE=`uname -v` ++ ;; ++ esac ++ # Japanese Language versions have a version number like `4.1.3-JL'. ++ echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` ++ exit ;; ++ sun3*:SunOS:*:*) ++ echo m68k-sun-sunos${UNAME_RELEASE} ++ exit ;; ++ sun*:*:4.2BSD:*) ++ UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` ++ test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 ++ case "`/bin/arch`" in ++ sun3) ++ echo m68k-sun-sunos${UNAME_RELEASE} ++ ;; ++ sun4) ++ echo sparc-sun-sunos${UNAME_RELEASE} ++ ;; ++ esac ++ exit ;; ++ aushp:SunOS:*:*) ++ echo sparc-auspex-sunos${UNAME_RELEASE} ++ exit ;; ++ # The situation for MiNT is a little confusing. The machine name ++ # can be virtually everything (everything which is not ++ # "atarist" or "atariste" at least should have a processor ++ # > m68000). The system name ranges from "MiNT" over "FreeMiNT" ++ # to the lowercase version "mint" (or "freemint"). Finally ++ # the system name "TOS" denotes a system which is actually not ++ # MiNT. But MiNT is downward compatible to TOS, so this should ++ # be no problem. ++ atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) ++ echo m68k-atari-mint${UNAME_RELEASE} ++ exit ;; ++ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) ++ echo m68k-atari-mint${UNAME_RELEASE} ++ exit ;; ++ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) ++ echo m68k-atari-mint${UNAME_RELEASE} ++ exit ;; ++ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) ++ echo m68k-milan-mint${UNAME_RELEASE} ++ exit ;; ++ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) ++ echo m68k-hades-mint${UNAME_RELEASE} ++ exit ;; ++ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) ++ echo m68k-unknown-mint${UNAME_RELEASE} ++ exit ;; ++ m68k:machten:*:*) ++ echo m68k-apple-machten${UNAME_RELEASE} ++ exit ;; ++ powerpc:machten:*:*) ++ echo powerpc-apple-machten${UNAME_RELEASE} ++ exit ;; ++ RISC*:Mach:*:*) ++ echo mips-dec-mach_bsd4.3 ++ exit ;; ++ RISC*:ULTRIX:*:*) ++ echo mips-dec-ultrix${UNAME_RELEASE} ++ exit ;; ++ VAX*:ULTRIX*:*:*) ++ echo vax-dec-ultrix${UNAME_RELEASE} ++ exit ;; ++ 2020:CLIX:*:* | 2430:CLIX:*:*) ++ echo clipper-intergraph-clix${UNAME_RELEASE} ++ exit ;; ++ mips:*:*:UMIPS | mips:*:*:RISCos) ++ eval $set_cc_for_build ++ sed 's/^ //' << EOF >$dummy.c ++#ifdef __cplusplus ++#include /* for printf() prototype */ ++ int main (int argc, char *argv[]) { ++#else ++ int main (argc, argv) int argc; char *argv[]; { ++#endif ++ #if defined (host_mips) && defined (MIPSEB) ++ #if defined (SYSTYPE_SYSV) ++ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); ++ #endif ++ #if defined (SYSTYPE_SVR4) ++ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); ++ #endif ++ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) ++ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); ++ #endif ++ #endif ++ exit (-1); ++ } ++EOF ++ $CC_FOR_BUILD -o $dummy $dummy.c && ++ dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && ++ SYSTEM_NAME=`$dummy $dummyarg` && ++ { echo "$SYSTEM_NAME"; exit; } ++ echo mips-mips-riscos${UNAME_RELEASE} ++ exit ;; ++ Motorola:PowerMAX_OS:*:*) ++ echo powerpc-motorola-powermax ++ exit ;; ++ Motorola:*:4.3:PL8-*) ++ echo powerpc-harris-powermax ++ exit ;; ++ Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) ++ echo powerpc-harris-powermax ++ exit ;; ++ Night_Hawk:Power_UNIX:*:*) ++ echo powerpc-harris-powerunix ++ exit ;; ++ m88k:CX/UX:7*:*) ++ echo m88k-harris-cxux7 ++ exit ;; ++ m88k:*:4*:R4*) ++ echo m88k-motorola-sysv4 ++ exit ;; ++ m88k:*:3*:R3*) ++ echo m88k-motorola-sysv3 ++ exit ;; ++ AViiON:dgux:*:*) ++ # DG/UX returns AViiON for all architectures ++ UNAME_PROCESSOR=`/usr/bin/uname -p` ++ if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] ++ then ++ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ ++ [ ${TARGET_BINARY_INTERFACE}x = x ] ++ then ++ echo m88k-dg-dgux${UNAME_RELEASE} ++ else ++ echo m88k-dg-dguxbcs${UNAME_RELEASE} ++ fi ++ else ++ echo i586-dg-dgux${UNAME_RELEASE} ++ fi ++ exit ;; ++ M88*:DolphinOS:*:*) # DolphinOS (SVR3) ++ echo m88k-dolphin-sysv3 ++ exit ;; ++ M88*:*:R3*:*) ++ # Delta 88k system running SVR3 ++ echo m88k-motorola-sysv3 ++ exit ;; ++ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) ++ echo m88k-tektronix-sysv3 ++ exit ;; ++ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) ++ echo m68k-tektronix-bsd ++ exit ;; ++ *:IRIX*:*:*) ++ echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` ++ exit ;; ++ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. ++ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id ++ exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' ++ i*86:AIX:*:*) ++ echo i386-ibm-aix ++ exit ;; ++ ia64:AIX:*:*) ++ if [ -x /usr/bin/oslevel ] ; then ++ IBM_REV=`/usr/bin/oslevel` ++ else ++ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} ++ fi ++ echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} ++ exit ;; ++ *:AIX:2:3) ++ if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then ++ eval $set_cc_for_build ++ sed 's/^ //' << EOF >$dummy.c ++ #include ++ ++ main() ++ { ++ if (!__power_pc()) ++ exit(1); ++ puts("powerpc-ibm-aix3.2.5"); ++ exit(0); ++ } ++EOF ++ if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` ++ then ++ echo "$SYSTEM_NAME" ++ else ++ echo rs6000-ibm-aix3.2.5 ++ fi ++ elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then ++ echo rs6000-ibm-aix3.2.4 ++ else ++ echo rs6000-ibm-aix3.2 ++ fi ++ exit ;; ++ *:AIX:*:[456]) ++ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` ++ if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then ++ IBM_ARCH=rs6000 ++ else ++ IBM_ARCH=powerpc ++ fi ++ if [ -x /usr/bin/oslevel ] ; then ++ IBM_REV=`/usr/bin/oslevel` ++ else ++ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} ++ fi ++ echo ${IBM_ARCH}-ibm-aix${IBM_REV} ++ exit ;; ++ *:AIX:*:*) ++ echo rs6000-ibm-aix ++ exit ;; ++ ibmrt:4.4BSD:*|romp-ibm:BSD:*) ++ echo romp-ibm-bsd4.4 ++ exit ;; ++ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and ++ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to ++ exit ;; # report: romp-ibm BSD 4.3 ++ *:BOSX:*:*) ++ echo rs6000-bull-bosx ++ exit ;; ++ DPX/2?00:B.O.S.:*:*) ++ echo m68k-bull-sysv3 ++ exit ;; ++ 9000/[34]??:4.3bsd:1.*:*) ++ echo m68k-hp-bsd ++ exit ;; ++ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) ++ echo m68k-hp-bsd4.4 ++ exit ;; ++ 9000/[34678]??:HP-UX:*:*) ++ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` ++ case "${UNAME_MACHINE}" in ++ 9000/31? ) HP_ARCH=m68000 ;; ++ 9000/[34]?? ) HP_ARCH=m68k ;; ++ 9000/[678][0-9][0-9]) ++ if [ -x /usr/bin/getconf ]; then ++ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` ++ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` ++ case "${sc_cpu_version}" in ++ 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 ++ 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 ++ 532) # CPU_PA_RISC2_0 ++ case "${sc_kernel_bits}" in ++ 32) HP_ARCH="hppa2.0n" ;; ++ 64) HP_ARCH="hppa2.0w" ;; ++ '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 ++ esac ;; ++ esac ++ fi ++ if [ "${HP_ARCH}" = "" ]; then ++ eval $set_cc_for_build ++ sed 's/^ //' << EOF >$dummy.c ++ ++ #define _HPUX_SOURCE ++ #include ++ #include ++ ++ int main () ++ { ++ #if defined(_SC_KERNEL_BITS) ++ long bits = sysconf(_SC_KERNEL_BITS); ++ #endif ++ long cpu = sysconf (_SC_CPU_VERSION); ++ ++ switch (cpu) ++ { ++ case CPU_PA_RISC1_0: puts ("hppa1.0"); break; ++ case CPU_PA_RISC1_1: puts ("hppa1.1"); break; ++ case CPU_PA_RISC2_0: ++ #if defined(_SC_KERNEL_BITS) ++ switch (bits) ++ { ++ case 64: puts ("hppa2.0w"); break; ++ case 32: puts ("hppa2.0n"); break; ++ default: puts ("hppa2.0"); break; ++ } break; ++ #else /* !defined(_SC_KERNEL_BITS) */ ++ puts ("hppa2.0"); break; ++ #endif ++ default: puts ("hppa1.0"); break; ++ } ++ exit (0); ++ } ++EOF ++ (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` ++ test -z "$HP_ARCH" && HP_ARCH=hppa ++ fi ;; ++ esac ++ if [ ${HP_ARCH} = "hppa2.0w" ] ++ then ++ eval $set_cc_for_build ++ ++ # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating ++ # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler ++ # generating 64-bit code. GNU and HP use different nomenclature: ++ # ++ # $ CC_FOR_BUILD=cc ./config.guess ++ # => hppa2.0w-hp-hpux11.23 ++ # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess ++ # => hppa64-hp-hpux11.23 ++ ++ if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | ++ grep __LP64__ >/dev/null ++ then ++ HP_ARCH="hppa2.0w" ++ else ++ HP_ARCH="hppa64" ++ fi ++ fi ++ echo ${HP_ARCH}-hp-hpux${HPUX_REV} ++ exit ;; ++ ia64:HP-UX:*:*) ++ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` ++ echo ia64-hp-hpux${HPUX_REV} ++ exit ;; ++ 3050*:HI-UX:*:*) ++ eval $set_cc_for_build ++ sed 's/^ //' << EOF >$dummy.c ++ #include ++ int ++ main () ++ { ++ long cpu = sysconf (_SC_CPU_VERSION); ++ /* The order matters, because CPU_IS_HP_MC68K erroneously returns ++ true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct ++ results, however. */ ++ if (CPU_IS_PA_RISC (cpu)) ++ { ++ switch (cpu) ++ { ++ case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; ++ case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; ++ case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; ++ default: puts ("hppa-hitachi-hiuxwe2"); break; ++ } ++ } ++ else if (CPU_IS_HP_MC68K (cpu)) ++ puts ("m68k-hitachi-hiuxwe2"); ++ else puts ("unknown-hitachi-hiuxwe2"); ++ exit (0); ++ } ++EOF ++ $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && ++ { echo "$SYSTEM_NAME"; exit; } ++ echo unknown-hitachi-hiuxwe2 ++ exit ;; ++ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) ++ echo hppa1.1-hp-bsd ++ exit ;; ++ 9000/8??:4.3bsd:*:*) ++ echo hppa1.0-hp-bsd ++ exit ;; ++ *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) ++ echo hppa1.0-hp-mpeix ++ exit ;; ++ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) ++ echo hppa1.1-hp-osf ++ exit ;; ++ hp8??:OSF1:*:*) ++ echo hppa1.0-hp-osf ++ exit ;; ++ i*86:OSF1:*:*) ++ if [ -x /usr/sbin/sysversion ] ; then ++ echo ${UNAME_MACHINE}-unknown-osf1mk ++ else ++ echo ${UNAME_MACHINE}-unknown-osf1 ++ fi ++ exit ;; ++ parisc*:Lites*:*:*) ++ echo hppa1.1-hp-lites ++ exit ;; ++ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) ++ echo c1-convex-bsd ++ exit ;; ++ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) ++ if getsysinfo -f scalar_acc ++ then echo c32-convex-bsd ++ else echo c2-convex-bsd ++ fi ++ exit ;; ++ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) ++ echo c34-convex-bsd ++ exit ;; ++ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) ++ echo c38-convex-bsd ++ exit ;; ++ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) ++ echo c4-convex-bsd ++ exit ;; ++ CRAY*Y-MP:*:*:*) ++ echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' ++ exit ;; ++ CRAY*[A-Z]90:*:*:*) ++ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ ++ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ ++ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ ++ -e 's/\.[^.]*$/.X/' ++ exit ;; ++ CRAY*TS:*:*:*) ++ echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' ++ exit ;; ++ CRAY*T3E:*:*:*) ++ echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' ++ exit ;; ++ CRAY*SV1:*:*:*) ++ echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' ++ exit ;; ++ *:UNICOS/mp:*:*) ++ echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' ++ exit ;; ++ F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) ++ FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` ++ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` ++ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` ++ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" ++ exit ;; ++ 5000:UNIX_System_V:4.*:*) ++ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` ++ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` ++ echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" ++ exit ;; ++ i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) ++ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} ++ exit ;; ++ sparc*:BSD/OS:*:*) ++ echo sparc-unknown-bsdi${UNAME_RELEASE} ++ exit ;; ++ *:BSD/OS:*:*) ++ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} ++ exit ;; ++ *:FreeBSD:*:*) ++ case ${UNAME_MACHINE} in ++ pc98) ++ echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; ++ amd64) ++ echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; ++ *) ++ echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; ++ esac ++ exit ;; ++ i*:CYGWIN*:*) ++ echo ${UNAME_MACHINE}-pc-cygwin ++ exit ;; ++ *:MINGW*:*) ++ echo ${UNAME_MACHINE}-pc-mingw32 ++ exit ;; ++ i*:windows32*:*) ++ # uname -m includes "-pc" on this system. ++ echo ${UNAME_MACHINE}-mingw32 ++ exit ;; ++ i*:PW*:*) ++ echo ${UNAME_MACHINE}-pc-pw32 ++ exit ;; ++ *:Interix*:[3456]*) ++ case ${UNAME_MACHINE} in ++ x86) ++ echo i586-pc-interix${UNAME_RELEASE} ++ exit ;; ++ EM64T | authenticamd | genuineintel) ++ echo x86_64-unknown-interix${UNAME_RELEASE} ++ exit ;; ++ IA64) ++ echo ia64-unknown-interix${UNAME_RELEASE} ++ exit ;; ++ esac ;; ++ [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) ++ echo i${UNAME_MACHINE}-pc-mks ++ exit ;; ++ i*:Windows_NT*:* | Pentium*:Windows_NT*:*) ++ # How do we know it's Interix rather than the generic POSIX subsystem? ++ # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we ++ # UNAME_MACHINE based on the output of uname instead of i386? ++ echo i586-pc-interix ++ exit ;; ++ i*:UWIN*:*) ++ echo ${UNAME_MACHINE}-pc-uwin ++ exit ;; ++ amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) ++ echo x86_64-unknown-cygwin ++ exit ;; ++ p*:CYGWIN*:*) ++ echo powerpcle-unknown-cygwin ++ exit ;; ++ prep*:SunOS:5.*:*) ++ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` ++ exit ;; ++ *:GNU:*:*) ++ # the GNU system ++ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` ++ exit ;; ++ *:GNU/*:*:*) ++ # other systems with GNU libc and userland ++ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu ++ exit ;; ++ i*86:Minix:*:*) ++ echo ${UNAME_MACHINE}-pc-minix ++ exit ;; ++ arm*:Linux:*:*) ++ eval $set_cc_for_build ++ if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ ++ | grep -q __ARM_EABI__ ++ then ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} ++ else ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi ++ fi ++ exit ;; ++ avr32*:Linux:*:*) ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} ++ exit ;; ++ cris:Linux:*:*) ++ echo cris-axis-linux-${LIBC} ++ exit ;; ++ crisv32:Linux:*:*) ++ echo crisv32-axis-linux-${LIBC} ++ exit ;; ++ frv:Linux:*:*) ++ echo frv-unknown-linux-${LIBC} ++ exit ;; ++ ia64:Linux:*:*) ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} ++ exit ;; ++ m32r*:Linux:*:*) ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} ++ exit ;; ++ m68*:Linux:*:*) ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} ++ exit ;; ++ mips:Linux:*:*) ++ eval $set_cc_for_build ++ sed 's/^ //' << EOF >$dummy.c ++ #undef CPU ++ #undef mips ++ #undef mipsel ++ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) ++ CPU=mipsel ++ #else ++ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) ++ CPU=mips ++ #else ++ CPU= ++ #endif ++ #endif ++EOF ++ eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' ++ /^CPU/{ ++ s: ::g ++ p ++ }'`" ++ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } ++ ;; ++ mips64:Linux:*:*) ++ eval $set_cc_for_build ++ sed 's/^ //' << EOF >$dummy.c ++ #undef CPU ++ #undef mips64 ++ #undef mips64el ++ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) ++ CPU=mips64el ++ #else ++ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) ++ CPU=mips64 ++ #else ++ CPU= ++ #endif ++ #endif ++EOF ++ eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' ++ /^CPU/{ ++ s: ::g ++ p ++ }'`" ++ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } ++ ;; ++ or32:Linux:*:*) ++ echo or32-unknown-linux-${LIBC} ++ exit ;; ++ ppc:Linux:*:*) ++ echo powerpc-unknown-linux-${LIBC} ++ exit ;; ++ ppc64:Linux:*:*) ++ echo powerpc64-unknown-linux-${LIBC} ++ exit ;; ++ alpha:Linux:*:*) ++ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in ++ EV5) UNAME_MACHINE=alphaev5 ;; ++ EV56) UNAME_MACHINE=alphaev56 ;; ++ PCA56) UNAME_MACHINE=alphapca56 ;; ++ PCA57) UNAME_MACHINE=alphapca56 ;; ++ EV6) UNAME_MACHINE=alphaev6 ;; ++ EV67) UNAME_MACHINE=alphaev67 ;; ++ EV68*) UNAME_MACHINE=alphaev68 ;; ++ esac ++ objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null ++ if test "$?" = 0 ; then LIBC="gnulibc1" ; fi ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} ++ exit ;; ++ padre:Linux:*:*) ++ echo sparc-unknown-linux-gnu ++ exit ;; ++ parisc:Linux:*:* | hppa:Linux:*:*) ++ # Look for CPU level ++ case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in ++ PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; ++ PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; ++ *) echo hppa-unknown-linux-${LIBC} ;; ++ esac ++ exit ;; ++ parisc64:Linux:*:* | hppa64:Linux:*:*) ++ echo hppa64-unknown-linux-${LIBC} ++ exit ;; ++ s390:Linux:*:* | s390x:Linux:*:*) ++ echo ${UNAME_MACHINE}-ibm-linux ++ exit ;; ++ sh64*:Linux:*:*) ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} ++ exit ;; ++ sh*:Linux:*:*) ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} ++ exit ;; ++ sparc:Linux:*:* | sparc64:Linux:*:*) ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} ++ exit ;; ++ vax:Linux:*:*) ++ echo ${UNAME_MACHINE}-dec-linux-${LIBC} ++ exit ;; ++ x86_64:Linux:*:*) ++ echo x86_64-unknown-linux-${LIBC} ++ exit ;; ++ xtensa*:Linux:*:*) ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} ++ exit ;; ++ i*86:Linux:*:*) ++ # The BFD linker knows what the default object file format is, so ++ # first see if it will tell us. cd to the root directory to prevent ++ # problems with other programs or directories called `ld' in the path. ++ # Set LC_ALL=C to ensure ld outputs messages in English. ++ ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ ++ | sed -ne '/supported targets:/!d ++ s/[ ][ ]*/ /g ++ s/.*supported targets: *// ++ s/ .*// ++ p'` ++ case "$ld_supported_targets" in ++ elf32-i386) ++ TENTATIVE="${UNAME_MACHINE}-pc-linux-${LIBC}" ++ ;; ++ a.out-i386-linux) ++ echo "${UNAME_MACHINE}-pc-linux-${LIBC}aout" ++ exit ;; ++ "") ++ # Either a pre-BFD a.out linker (linux-gnuoldld) or ++ # one that does not give us useful --help. ++ echo "${UNAME_MACHINE}-pc-linux-${LIBC}oldld" ++ exit ;; ++ esac ++ # This should get integrated into the C code below, but now we hack ++ if [ "$LIBC" != "gnu" ] ; then echo "$TENTATIVE" && exit 0 ; fi ++ # Determine whether the default compiler is a.out or elf ++ eval $set_cc_for_build ++ sed 's/^ //' << EOF >$dummy.c ++ #include ++ #ifdef __ELF__ ++ # ifdef __GLIBC__ ++ # if __GLIBC__ >= 2 ++ LIBC=gnu ++ # else ++ LIBC=gnulibc1 ++ # endif ++ # else ++ LIBC=gnulibc1 ++ # endif ++ #else ++ #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) ++ LIBC=gnu ++ #else ++ LIBC=gnuaout ++ #endif ++ #endif ++ #ifdef __dietlibc__ ++ LIBC=dietlibc ++ #endif ++EOF ++ eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' ++ /^LIBC/{ ++ s: ::g ++ p ++ }'`" ++ test x"${LIBC}" != x && { ++ echo "${UNAME_MACHINE}-pc-linux-${LIBC}" ++ exit ++ } ++ test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } ++ ;; ++ i*86:DYNIX/ptx:4*:*) ++ # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. ++ # earlier versions are messed up and put the nodename in both ++ # sysname and nodename. ++ echo i386-sequent-sysv4 ++ exit ;; ++ i*86:UNIX_SV:4.2MP:2.*) ++ # Unixware is an offshoot of SVR4, but it has its own version ++ # number series starting with 2... ++ # I am not positive that other SVR4 systems won't match this, ++ # I just have to hope. -- rms. ++ # Use sysv4.2uw... so that sysv4* matches it. ++ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} ++ exit ;; ++ i*86:OS/2:*:*) ++ # If we were able to find `uname', then EMX Unix compatibility ++ # is probably installed. ++ echo ${UNAME_MACHINE}-pc-os2-emx ++ exit ;; ++ i*86:XTS-300:*:STOP) ++ echo ${UNAME_MACHINE}-unknown-stop ++ exit ;; ++ i*86:atheos:*:*) ++ echo ${UNAME_MACHINE}-unknown-atheos ++ exit ;; ++ i*86:syllable:*:*) ++ echo ${UNAME_MACHINE}-pc-syllable ++ exit ;; ++ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) ++ echo i386-unknown-lynxos${UNAME_RELEASE} ++ exit ;; ++ i*86:*DOS:*:*) ++ echo ${UNAME_MACHINE}-pc-msdosdjgpp ++ exit ;; ++ i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) ++ UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` ++ if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then ++ echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} ++ else ++ echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} ++ fi ++ exit ;; ++ i*86:*:5:[678]*) ++ # UnixWare 7.x, OpenUNIX and OpenServer 6. ++ case `/bin/uname -X | grep "^Machine"` in ++ *486*) UNAME_MACHINE=i486 ;; ++ *Pentium) UNAME_MACHINE=i586 ;; ++ *Pent*|*Celeron) UNAME_MACHINE=i686 ;; ++ esac ++ echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} ++ exit ;; ++ i*86:*:3.2:*) ++ if test -f /usr/options/cb.name; then ++ UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then ++ UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` ++ (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 ++ (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ ++ && UNAME_MACHINE=i586 ++ (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ ++ && UNAME_MACHINE=i686 ++ (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ ++ && UNAME_MACHINE=i686 ++ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL ++ else ++ echo ${UNAME_MACHINE}-pc-sysv32 ++ fi ++ exit ;; ++ pc:*:*:*) ++ # Left here for compatibility: ++ # uname -m prints for DJGPP always 'pc', but it prints nothing about ++ # the processor, so we play safe by assuming i386. ++ echo i386-pc-msdosdjgpp ++ exit ;; ++ Intel:Mach:3*:*) ++ echo i386-pc-mach3 ++ exit ;; ++ paragon:*:*:*) ++ echo i860-intel-osf1 ++ exit ;; ++ i860:*:4.*:*) # i860-SVR4 ++ if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then ++ echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 ++ else # Add other i860-SVR4 vendors below as they are discovered. ++ echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 ++ fi ++ exit ;; ++ mini*:CTIX:SYS*5:*) ++ # "miniframe" ++ echo m68010-convergent-sysv ++ exit ;; ++ mc68k:UNIX:SYSTEM5:3.51m) ++ echo m68k-convergent-sysv ++ exit ;; ++ M680?0:D-NIX:5.3:*) ++ echo m68k-diab-dnix ++ exit ;; ++ M68*:*:R3V[5678]*:*) ++ test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; ++ 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) ++ OS_REL='' ++ test -r /etc/.relid \ ++ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` ++ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ ++ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } ++ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ ++ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; ++ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) ++ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ ++ && { echo i486-ncr-sysv4; exit; } ;; ++ m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) ++ echo m68k-unknown-lynxos${UNAME_RELEASE} ++ exit ;; ++ mc68030:UNIX_System_V:4.*:*) ++ echo m68k-atari-sysv4 ++ exit ;; ++ TSUNAMI:LynxOS:2.*:*) ++ echo sparc-unknown-lynxos${UNAME_RELEASE} ++ exit ;; ++ rs6000:LynxOS:2.*:*) ++ echo rs6000-unknown-lynxos${UNAME_RELEASE} ++ exit ;; ++ PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) ++ echo powerpc-unknown-lynxos${UNAME_RELEASE} ++ exit ;; ++ SM[BE]S:UNIX_SV:*:*) ++ echo mips-dde-sysv${UNAME_RELEASE} ++ exit ;; ++ RM*:ReliantUNIX-*:*:*) ++ echo mips-sni-sysv4 ++ exit ;; ++ RM*:SINIX-*:*:*) ++ echo mips-sni-sysv4 ++ exit ;; ++ *:SINIX-*:*:*) ++ if uname -p 2>/dev/null >/dev/null ; then ++ UNAME_MACHINE=`(uname -p) 2>/dev/null` ++ echo ${UNAME_MACHINE}-sni-sysv4 ++ else ++ echo ns32k-sni-sysv ++ fi ++ exit ;; ++ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort ++ # says ++ echo i586-unisys-sysv4 ++ exit ;; ++ *:UNIX_System_V:4*:FTX*) ++ # From Gerald Hewes . ++ # How about differentiating between stratus architectures? -djm ++ echo hppa1.1-stratus-sysv4 ++ exit ;; ++ *:*:*:FTX*) ++ # From seanf@swdc.stratus.com. ++ echo i860-stratus-sysv4 ++ exit ;; ++ i*86:VOS:*:*) ++ # From Paul.Green@stratus.com. ++ echo ${UNAME_MACHINE}-stratus-vos ++ exit ;; ++ *:VOS:*:*) ++ # From Paul.Green@stratus.com. ++ echo hppa1.1-stratus-vos ++ exit ;; ++ mc68*:A/UX:*:*) ++ echo m68k-apple-aux${UNAME_RELEASE} ++ exit ;; ++ news*:NEWS-OS:6*:*) ++ echo mips-sony-newsos6 ++ exit ;; ++ R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) ++ if [ -d /usr/nec ]; then ++ echo mips-nec-sysv${UNAME_RELEASE} ++ else ++ echo mips-unknown-sysv${UNAME_RELEASE} ++ fi ++ exit ;; ++ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. ++ echo powerpc-be-beos ++ exit ;; ++ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. ++ echo powerpc-apple-beos ++ exit ;; ++ BePC:BeOS:*:*) # BeOS running on Intel PC compatible. ++ echo i586-pc-beos ++ exit ;; ++ BePC:Haiku:*:*) # Haiku running on Intel PC compatible. ++ echo i586-pc-haiku ++ exit ;; ++ SX-4:SUPER-UX:*:*) ++ echo sx4-nec-superux${UNAME_RELEASE} ++ exit ;; ++ SX-5:SUPER-UX:*:*) ++ echo sx5-nec-superux${UNAME_RELEASE} ++ exit ;; ++ SX-6:SUPER-UX:*:*) ++ echo sx6-nec-superux${UNAME_RELEASE} ++ exit ;; ++ SX-7:SUPER-UX:*:*) ++ echo sx7-nec-superux${UNAME_RELEASE} ++ exit ;; ++ SX-8:SUPER-UX:*:*) ++ echo sx8-nec-superux${UNAME_RELEASE} ++ exit ;; ++ SX-8R:SUPER-UX:*:*) ++ echo sx8r-nec-superux${UNAME_RELEASE} ++ exit ;; ++ Power*:Rhapsody:*:*) ++ echo powerpc-apple-rhapsody${UNAME_RELEASE} ++ exit ;; ++ *:Rhapsody:*:*) ++ echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} ++ exit ;; ++ *:Darwin:*:*) ++ UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown ++ case $UNAME_PROCESSOR in ++ unknown) UNAME_PROCESSOR=powerpc ;; ++ esac ++ echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} ++ exit ;; ++ *:procnto*:*:* | *:QNX:[0123456789]*:*) ++ UNAME_PROCESSOR=`uname -p` ++ if test "$UNAME_PROCESSOR" = "x86"; then ++ UNAME_PROCESSOR=i386 ++ UNAME_MACHINE=pc ++ fi ++ echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} ++ exit ;; ++ *:QNX:*:4*) ++ echo i386-pc-qnx ++ exit ;; ++ NSE-?:NONSTOP_KERNEL:*:*) ++ echo nse-tandem-nsk${UNAME_RELEASE} ++ exit ;; ++ NSR-?:NONSTOP_KERNEL:*:*) ++ echo nsr-tandem-nsk${UNAME_RELEASE} ++ exit ;; ++ *:NonStop-UX:*:*) ++ echo mips-compaq-nonstopux ++ exit ;; ++ BS2000:POSIX*:*:*) ++ echo bs2000-siemens-sysv ++ exit ;; ++ DS/*:UNIX_System_V:*:*) ++ echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} ++ exit ;; ++ *:Plan9:*:*) ++ # "uname -m" is not consistent, so use $cputype instead. 386 ++ # is converted to i386 for consistency with other x86 ++ # operating systems. ++ if test "$cputype" = "386"; then ++ UNAME_MACHINE=i386 ++ else ++ UNAME_MACHINE="$cputype" ++ fi ++ echo ${UNAME_MACHINE}-unknown-plan9 ++ exit ;; ++ *:TOPS-10:*:*) ++ echo pdp10-unknown-tops10 ++ exit ;; ++ *:TENEX:*:*) ++ echo pdp10-unknown-tenex ++ exit ;; ++ KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) ++ echo pdp10-dec-tops20 ++ exit ;; ++ XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) ++ echo pdp10-xkl-tops20 ++ exit ;; ++ *:TOPS-20:*:*) ++ echo pdp10-unknown-tops20 ++ exit ;; ++ *:ITS:*:*) ++ echo pdp10-unknown-its ++ exit ;; ++ SEI:*:*:SEIUX) ++ echo mips-sei-seiux${UNAME_RELEASE} ++ exit ;; ++ *:DragonFly:*:*) ++ echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ++ exit ;; ++ *:*VMS:*:*) ++ UNAME_MACHINE=`(uname -p) 2>/dev/null` ++ case "${UNAME_MACHINE}" in ++ A*) echo alpha-dec-vms ; exit ;; ++ I*) echo ia64-dec-vms ; exit ;; ++ V*) echo vax-dec-vms ; exit ;; ++ esac ;; ++ *:XENIX:*:SysV) ++ echo i386-pc-xenix ++ exit ;; ++ i*86:skyos:*:*) ++ echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' ++ exit ;; ++ i*86:rdos:*:*) ++ echo ${UNAME_MACHINE}-pc-rdos ++ exit ;; ++esac ++ ++#echo '(No uname command or uname output not recognized.)' 1>&2 ++#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 ++ ++eval $set_cc_for_build ++cat >$dummy.c < ++# include ++#endif ++main () ++{ ++#if defined (sony) ++#if defined (MIPSEB) ++ /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, ++ I don't know.... */ ++ printf ("mips-sony-bsd\n"); exit (0); ++#else ++#include ++ printf ("m68k-sony-newsos%s\n", ++#ifdef NEWSOS4 ++ "4" ++#else ++ "" ++#endif ++ ); exit (0); ++#endif ++#endif ++ ++#if defined (__arm) && defined (__acorn) && defined (__unix) ++ printf ("arm-acorn-riscix\n"); exit (0); ++#endif ++ ++#if defined (hp300) && !defined (hpux) ++ printf ("m68k-hp-bsd\n"); exit (0); ++#endif ++ ++#if defined (NeXT) ++#if !defined (__ARCHITECTURE__) ++#define __ARCHITECTURE__ "m68k" ++#endif ++ int version; ++ version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; ++ if (version < 4) ++ printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); ++ else ++ printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); ++ exit (0); ++#endif ++ ++#if defined (MULTIMAX) || defined (n16) ++#if defined (UMAXV) ++ printf ("ns32k-encore-sysv\n"); exit (0); ++#else ++#if defined (CMU) ++ printf ("ns32k-encore-mach\n"); exit (0); ++#else ++ printf ("ns32k-encore-bsd\n"); exit (0); ++#endif ++#endif ++#endif ++ ++#if defined (__386BSD__) ++ printf ("i386-pc-bsd\n"); exit (0); ++#endif ++ ++#if defined (sequent) ++#if defined (i386) ++ printf ("i386-sequent-dynix\n"); exit (0); ++#endif ++#if defined (ns32000) ++ printf ("ns32k-sequent-dynix\n"); exit (0); ++#endif ++#endif ++ ++#if defined (_SEQUENT_) ++ struct utsname un; ++ ++ uname(&un); ++ ++ if (strncmp(un.version, "V2", 2) == 0) { ++ printf ("i386-sequent-ptx2\n"); exit (0); ++ } ++ if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ ++ printf ("i386-sequent-ptx1\n"); exit (0); ++ } ++ printf ("i386-sequent-ptx\n"); exit (0); ++ ++#endif ++ ++#if defined (vax) ++# if !defined (ultrix) ++# include ++# if defined (BSD) ++# if BSD == 43 ++ printf ("vax-dec-bsd4.3\n"); exit (0); ++# else ++# if BSD == 199006 ++ printf ("vax-dec-bsd4.3reno\n"); exit (0); ++# else ++ printf ("vax-dec-bsd\n"); exit (0); ++# endif ++# endif ++# else ++ printf ("vax-dec-bsd\n"); exit (0); ++# endif ++# else ++ printf ("vax-dec-ultrix\n"); exit (0); ++# endif ++#endif ++ ++#if defined (alliant) && defined (i860) ++ printf ("i860-alliant-bsd\n"); exit (0); ++#endif ++ ++ exit (1); ++} ++EOF ++ ++$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && ++ { echo "$SYSTEM_NAME"; exit; } ++ ++# Apollos put the system type in the environment. ++ ++test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } ++ ++# Convex versions that predate uname can use getsysinfo(1) ++ ++if [ -x /usr/convex/getsysinfo ] ++then ++ case `getsysinfo -f cpu_type` in ++ c1*) ++ echo c1-convex-bsd ++ exit ;; ++ c2*) ++ if getsysinfo -f scalar_acc ++ then echo c32-convex-bsd ++ else echo c2-convex-bsd ++ fi ++ exit ;; ++ c34*) ++ echo c34-convex-bsd ++ exit ;; ++ c38*) ++ echo c38-convex-bsd ++ exit ;; ++ c4*) ++ echo c4-convex-bsd ++ exit ;; ++ esac ++fi ++ ++cat >&2 < in order to provide the needed ++information to handle your system. ++ ++config.guess timestamp = $timestamp ++ ++uname -m = `(uname -m) 2>/dev/null || echo unknown` ++uname -r = `(uname -r) 2>/dev/null || echo unknown` ++uname -s = `(uname -s) 2>/dev/null || echo unknown` ++uname -v = `(uname -v) 2>/dev/null || echo unknown` ++ ++/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` ++/bin/uname -X = `(/bin/uname -X) 2>/dev/null` ++ ++hostinfo = `(hostinfo) 2>/dev/null` ++/bin/universe = `(/bin/universe) 2>/dev/null` ++/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` ++/bin/arch = `(/bin/arch) 2>/dev/null` ++/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` ++/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` ++ ++UNAME_MACHINE = ${UNAME_MACHINE} ++UNAME_RELEASE = ${UNAME_RELEASE} ++UNAME_SYSTEM = ${UNAME_SYSTEM} ++UNAME_VERSION = ${UNAME_VERSION} ++EOF ++ ++exit 1 ++ ++# Local variables: ++# eval: (add-hook 'write-file-hooks 'time-stamp) ++# time-stamp-start: "timestamp='" ++# time-stamp-format: "%:y-%02m-%02d" ++# time-stamp-end: "'" ++# End: +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/config.h.in open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/config.h.in +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/config.h.in 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/config.h.in 2012-04-09 21:52:14.000000000 -0500 +@@ -0,0 +1,111 @@ ++/* config.h.in. Generated from configure.ac by autoheader. */ ++ ++/* Define to 1 if you have the header file. */ ++#undef HAVE_DLFCN_H ++ ++/* Define to 1 if the system has the type `int16_t'. */ ++#undef HAVE_INT16_T ++ ++/* Define to 1 if the system has the type `int32_t'. */ ++#undef HAVE_INT32_T ++ ++/* Define to 1 if the system has the type `int64_t'. */ ++#undef HAVE_INT64_T ++ ++/* Define to 1 if the system has the type `int8_t'. */ ++#undef HAVE_INT8_T ++ ++/* Define to 1 if you have the header file. */ ++#undef HAVE_INTTYPES_H ++ ++/* Define to 1 if you have the header file. */ ++#undef HAVE_MEMORY_H ++ ++/* Define to 1 if you have the header file. */ ++#undef HAVE_STDINT_H ++ ++/* Define to 1 if you have the header file. */ ++#undef HAVE_STDLIB_H ++ ++/* Define to 1 if you have the header file. */ ++#undef HAVE_STRINGS_H ++ ++/* Define to 1 if you have the header file. */ ++#undef HAVE_STRING_H ++ ++/* Define to 1 if you have the header file. */ ++#undef HAVE_SYS_STAT_H ++ ++/* Define to 1 if you have the header file. */ ++#undef HAVE_SYS_TYPES_H ++ ++/* Define to 1 if the system has the type `uint16_t'. */ ++#undef HAVE_UINT16_T ++ ++/* Define to 1 if the system has the type `uint32_t'. */ ++#undef HAVE_UINT32_T ++ ++/* Define to 1 if the system has the type `uint64_t'. */ ++#undef HAVE_UINT64_T ++ ++/* Define to 1 if the system has the type `uint8_t'. */ ++#undef HAVE_UINT8_T ++ ++/* Define to 1 if you have the header file. */ ++#undef HAVE_UNISTD_H ++ ++/* Define to 1 if your C compiler doesn't accept -c and -o together. */ ++#undef NO_MINUS_C_MINUS_O ++ ++/* Name of package */ ++#undef PACKAGE ++ ++/* Define to the address where bug reports for this package should be sent. */ ++#undef PACKAGE_BUGREPORT ++ ++/* Define to the full name of this package. */ ++#undef PACKAGE_NAME ++ ++/* Define to the full name and version of this package. */ ++#undef PACKAGE_STRING ++ ++/* Define to the one symbol short name of this package. */ ++#undef PACKAGE_TARNAME ++ ++/* Define to the version of this package. */ ++#undef PACKAGE_VERSION ++ ++/* The size of a `int', as computed by sizeof. */ ++#undef SIZEOF_INT ++ ++/* The size of a `long', as computed by sizeof. */ ++#undef SIZEOF_LONG ++ ++/* The size of a `short', as computed by sizeof. */ ++#undef SIZEOF_SHORT ++ ++/* Define to 1 if you have the ANSI C header files. */ ++#undef STDC_HEADERS ++ ++/* Version number of package */ ++#undef VERSION ++ ++/* Enable GNU extensions on systems that have them. */ ++#ifndef _GNU_SOURCE ++# undef _GNU_SOURCE ++#endif ++ ++/* Define to empty if `const' does not conform to ANSI C. */ ++#undef const ++ ++/* Define to `__inline__' or `__inline' if that's what the C compiler ++ calls it, or to nothing if 'inline' is not supported under any name. */ ++#ifndef __cplusplus ++#undef inline ++#endif ++ ++/* Define to `long' if does not define. */ ++#undef off_t ++ ++/* Define to `unsigned' if does not define. */ ++#undef size_t +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/config.sub open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/config.sub +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/config.sub 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/config.sub 2012-04-09 21:52:14.000000000 -0500 +@@ -0,0 +1,1695 @@ ++#! /bin/sh ++# Configuration validation subroutine script. ++# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, ++# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 ++# Free Software Foundation, Inc. ++ ++timestamp='2008-09-08' ++ ++# This file is (in principle) common to ALL GNU software. ++# The presence of a machine in this file suggests that SOME GNU software ++# can handle that machine. It does not imply ALL GNU software can. ++# ++# This file is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA ++# 02110-1301, USA. ++# ++# As a special exception to the GNU General Public License, if you ++# distribute this file as part of a program that contains a ++# configuration script generated by Autoconf, you may include it under ++# the same distribution terms that you use for the rest of that program. ++ ++ ++# Please send patches to . Submit a context ++# diff and a properly formatted ChangeLog entry. ++# ++# Configuration subroutine to validate and canonicalize a configuration type. ++# Supply the specified configuration type as an argument. ++# If it is invalid, we print an error message on stderr and exit with code 1. ++# Otherwise, we print the canonical config type on stdout and succeed. ++ ++# This file is supposed to be the same for all GNU packages ++# and recognize all the CPU types, system types and aliases ++# that are meaningful with *any* GNU software. ++# Each package is responsible for reporting which valid configurations ++# it does not support. The user should be able to distinguish ++# a failure to support a valid configuration from a meaningless ++# configuration. ++ ++# The goal of this file is to map all the various variations of a given ++# machine specification into a single specification in the form: ++# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM ++# or in some cases, the newer four-part form: ++# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM ++# It is wrong to echo any other type of specification. ++ ++me=`echo "$0" | sed -e 's,.*/,,'` ++ ++usage="\ ++Usage: $0 [OPTION] CPU-MFR-OPSYS ++ $0 [OPTION] ALIAS ++ ++Canonicalize a configuration name. ++ ++Operation modes: ++ -h, --help print this help, then exit ++ -t, --time-stamp print date of last modification, then exit ++ -v, --version print version number, then exit ++ ++Report bugs and patches to ." ++ ++version="\ ++GNU config.sub ($timestamp) ++ ++Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, ++2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. ++ ++This is free software; see the source for copying conditions. There is NO ++warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." ++ ++help=" ++Try \`$me --help' for more information." ++ ++# Parse command line ++while test $# -gt 0 ; do ++ case $1 in ++ --time-stamp | --time* | -t ) ++ echo "$timestamp" ; exit ;; ++ --version | -v ) ++ echo "$version" ; exit ;; ++ --help | --h* | -h ) ++ echo "$usage"; exit ;; ++ -- ) # Stop option processing ++ shift; break ;; ++ - ) # Use stdin as input. ++ break ;; ++ -* ) ++ echo "$me: invalid option $1$help" ++ exit 1 ;; ++ ++ *local*) ++ # First pass through any local machine types. ++ echo $1 ++ exit ;; ++ ++ * ) ++ break ;; ++ esac ++done ++ ++case $# in ++ 0) echo "$me: missing argument$help" >&2 ++ exit 1;; ++ 1) ;; ++ *) echo "$me: too many arguments$help" >&2 ++ exit 1;; ++esac ++ ++# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). ++# Here we must recognize all the valid KERNEL-OS combinations. ++maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` ++case $maybe_os in ++ nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ ++ uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ ++ storm-chaos* | os2-emx* | rtmk-nova*) ++ os=-$maybe_os ++ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ++ ;; ++ *) ++ basic_machine=`echo $1 | sed 's/-[^-]*$//'` ++ if [ $basic_machine != $1 ] ++ then os=`echo $1 | sed 's/.*-/-/'` ++ else os=; fi ++ ;; ++esac ++ ++### Let's recognize common machines as not being operating systems so ++### that things like config.sub decstation-3100 work. We also ++### recognize some manufacturers as not being operating systems, so we ++### can provide default operating systems below. ++case $os in ++ -sun*os*) ++ # Prevent following clause from handling this invalid input. ++ ;; ++ -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ ++ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ ++ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ ++ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ ++ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ ++ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ ++ -apple | -axis | -knuth | -cray) ++ os= ++ basic_machine=$1 ++ ;; ++ -sim | -cisco | -oki | -wec | -winbond) ++ os= ++ basic_machine=$1 ++ ;; ++ -scout) ++ ;; ++ -wrs) ++ os=-vxworks ++ basic_machine=$1 ++ ;; ++ -chorusos*) ++ os=-chorusos ++ basic_machine=$1 ++ ;; ++ -chorusrdb) ++ os=-chorusrdb ++ basic_machine=$1 ++ ;; ++ -hiux*) ++ os=-hiuxwe2 ++ ;; ++ -sco6) ++ os=-sco5v6 ++ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ++ ;; ++ -sco5) ++ os=-sco3.2v5 ++ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ++ ;; ++ -sco4) ++ os=-sco3.2v4 ++ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ++ ;; ++ -sco3.2.[4-9]*) ++ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` ++ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ++ ;; ++ -sco3.2v[4-9]*) ++ # Don't forget version if it is 3.2v4 or newer. ++ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ++ ;; ++ -sco5v6*) ++ # Don't forget version if it is 3.2v4 or newer. ++ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ++ ;; ++ -sco*) ++ os=-sco3.2v2 ++ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ++ ;; ++ -udk*) ++ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ++ ;; ++ -isc) ++ os=-isc2.2 ++ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ++ ;; ++ -clix*) ++ basic_machine=clipper-intergraph ++ ;; ++ -isc*) ++ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ++ ;; ++ -lynx*) ++ os=-lynxos ++ ;; ++ -ptx*) ++ basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ++ ;; ++ -windowsnt*) ++ os=`echo $os | sed -e 's/windowsnt/winnt/'` ++ ;; ++ -psos*) ++ os=-psos ++ ;; ++ -mint | -mint[0-9]*) ++ basic_machine=m68k-atari ++ os=-mint ++ ;; ++esac ++ ++# Decode aliases for certain CPU-COMPANY combinations. ++case $basic_machine in ++ # Recognize the basic CPU types without company name. ++ # Some are omitted here because they have special meanings below. ++ 1750a | 580 \ ++ | a29k \ ++ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ ++ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ ++ | am33_2.0 \ ++ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ ++ | bfin \ ++ | c4x | clipper \ ++ | d10v | d30v | dlx | dsp16xx | dvp \ ++ | fido | fr30 | frv \ ++ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ ++ | i370 | i860 | i960 | ia64 \ ++ | ip2k | iq2000 \ ++ | m32c | m32r | m32rle | m68000 | m68k | m88k \ ++ | maxq | mb | microblaze | mcore | mep | metag \ ++ | mips | mipsbe | mipseb | mipsel | mipsle \ ++ | mips16 \ ++ | mips64 | mips64el \ ++ | mips64octeon | mips64octeonel \ ++ | mips64orion | mips64orionel \ ++ | mips64r5900 | mips64r5900el \ ++ | mips64vr | mips64vrel \ ++ | mips64vr4100 | mips64vr4100el \ ++ | mips64vr4300 | mips64vr4300el \ ++ | mips64vr5000 | mips64vr5000el \ ++ | mips64vr5900 | mips64vr5900el \ ++ | mipsisa32 | mipsisa32el \ ++ | mipsisa32r2 | mipsisa32r2el \ ++ | mipsisa64 | mipsisa64el \ ++ | mipsisa64r2 | mipsisa64r2el \ ++ | mipsisa64sb1 | mipsisa64sb1el \ ++ | mipsisa64sr71k | mipsisa64sr71kel \ ++ | mipstx39 | mipstx39el \ ++ | mn10200 | mn10300 \ ++ | mt \ ++ | msp430 \ ++ | nios | nios2 \ ++ | ns16k | ns32k \ ++ | or32 \ ++ | pdp10 | pdp11 | pj | pjl \ ++ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ ++ | pyramid \ ++ | score \ ++ | sh | sh[1234] | sh[24]a | sh[24]a*eb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ ++ | sh64 | sh64le \ ++ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ ++ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ ++ | spu | strongarm \ ++ | tahoe | thumb | tic4x | tic80 | tron \ ++ | v850 | v850e \ ++ | we32k \ ++ | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ ++ | z8k | z80) ++ basic_machine=$basic_machine-unknown ++ ;; ++ m6811 | m68hc11 | m6812 | m68hc12) ++ # Motorola 68HC11/12. ++ basic_machine=$basic_machine-unknown ++ os=-none ++ ;; ++ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ++ ;; ++ ms1) ++ basic_machine=mt-unknown ++ ;; ++ ++ # We use `pc' rather than `unknown' ++ # because (1) that's what they normally are, and ++ # (2) the word "unknown" tends to confuse beginning users. ++ i*86 | x86_64) ++ basic_machine=$basic_machine-pc ++ ;; ++ # Object if more than one company name word. ++ *-*-*) ++ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 ++ exit 1 ++ ;; ++ # Recognize the basic CPU types with company name. ++ 580-* \ ++ | a29k-* \ ++ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ ++ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ ++ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ ++ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ ++ | avr-* | avr32-* \ ++ | bfin-* | bs2000-* \ ++ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ ++ | clipper-* | craynv-* | cydra-* \ ++ | d10v-* | d30v-* | dlx-* \ ++ | elxsi-* \ ++ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ ++ | h8300-* | h8500-* \ ++ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ ++ | i*86-* | i860-* | i960-* | ia64-* \ ++ | ip2k-* | iq2000-* \ ++ | m32c-* | m32r-* | m32rle-* \ ++ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ ++ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ ++ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ ++ | mips16-* \ ++ | mips64-* | mips64el-* \ ++ | mips64octeon-* | mips64octeonel-* \ ++ | mips64orion-* | mips64orionel-* \ ++ | mips64r5900-* | mips64r5900el-* \ ++ | mips64vr-* | mips64vrel-* \ ++ | mips64vr4100-* | mips64vr4100el-* \ ++ | mips64vr4300-* | mips64vr4300el-* \ ++ | mips64vr5000-* | mips64vr5000el-* \ ++ | mips64vr5900-* | mips64vr5900el-* \ ++ | mipsisa32-* | mipsisa32el-* \ ++ | mipsisa32r2-* | mipsisa32r2el-* \ ++ | mipsisa64-* | mipsisa64el-* \ ++ | mipsisa64r2-* | mipsisa64r2el-* \ ++ | mipsisa64sb1-* | mipsisa64sb1el-* \ ++ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ ++ | mipstx39-* | mipstx39el-* \ ++ | mmix-* \ ++ | mt-* \ ++ | msp430-* \ ++ | nios-* | nios2-* \ ++ | none-* | np1-* | ns16k-* | ns32k-* \ ++ | orion-* \ ++ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ ++ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ ++ | pyramid-* \ ++ | romp-* | rs6000-* \ ++ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]a*eb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ ++ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ ++ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ ++ | sparclite-* \ ++ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ ++ | tahoe-* | thumb-* \ ++ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \ ++ | tron-* \ ++ | v850-* | v850e-* | vax-* \ ++ | we32k-* \ ++ | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ ++ | xstormy16-* | xtensa*-* \ ++ | ymp-* \ ++ | z8k-* | z80-*) ++ ;; ++ # Recognize the basic CPU types without company name, with glob match. ++ xtensa*) ++ basic_machine=$basic_machine-unknown ++ ;; ++ # Recognize the various machine names and aliases which stand ++ # for a CPU type and a company and sometimes even an OS. ++ 386bsd) ++ basic_machine=i386-unknown ++ os=-bsd ++ ;; ++ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) ++ basic_machine=m68000-att ++ ;; ++ 3b*) ++ basic_machine=we32k-att ++ ;; ++ a29khif) ++ basic_machine=a29k-amd ++ os=-udi ++ ;; ++ abacus) ++ basic_machine=abacus-unknown ++ ;; ++ adobe68k) ++ basic_machine=m68010-adobe ++ os=-scout ++ ;; ++ alliant | fx80) ++ basic_machine=fx80-alliant ++ ;; ++ altos | altos3068) ++ basic_machine=m68k-altos ++ ;; ++ am29k) ++ basic_machine=a29k-none ++ os=-bsd ++ ;; ++ amd64) ++ basic_machine=x86_64-pc ++ ;; ++ amd64-*) ++ basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ++ ;; ++ amdahl) ++ basic_machine=580-amdahl ++ os=-sysv ++ ;; ++ amiga | amiga-*) ++ basic_machine=m68k-unknown ++ ;; ++ amigaos | amigados) ++ basic_machine=m68k-unknown ++ os=-amigaos ++ ;; ++ amigaunix | amix) ++ basic_machine=m68k-unknown ++ os=-sysv4 ++ ;; ++ apollo68) ++ basic_machine=m68k-apollo ++ os=-sysv ++ ;; ++ apollo68bsd) ++ basic_machine=m68k-apollo ++ os=-bsd ++ ;; ++ aux) ++ basic_machine=m68k-apple ++ os=-aux ++ ;; ++ balance) ++ basic_machine=ns32k-sequent ++ os=-dynix ++ ;; ++ blackfin) ++ basic_machine=bfin-unknown ++ os=-linux ++ ;; ++ blackfin-*) ++ basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` ++ os=-linux ++ ;; ++ c90) ++ basic_machine=c90-cray ++ os=-unicos ++ ;; ++ cegcc) ++ basic_machine=arm-unknown ++ os=-cegcc ++ ;; ++ convex-c1) ++ basic_machine=c1-convex ++ os=-bsd ++ ;; ++ convex-c2) ++ basic_machine=c2-convex ++ os=-bsd ++ ;; ++ convex-c32) ++ basic_machine=c32-convex ++ os=-bsd ++ ;; ++ convex-c34) ++ basic_machine=c34-convex ++ os=-bsd ++ ;; ++ convex-c38) ++ basic_machine=c38-convex ++ os=-bsd ++ ;; ++ cray | j90) ++ basic_machine=j90-cray ++ os=-unicos ++ ;; ++ craynv) ++ basic_machine=craynv-cray ++ os=-unicosmp ++ ;; ++ cr16) ++ basic_machine=cr16-unknown ++ os=-elf ++ ;; ++ crds | unos) ++ basic_machine=m68k-crds ++ ;; ++ crisv32 | crisv32-* | etraxfs*) ++ basic_machine=crisv32-axis ++ ;; ++ cris | cris-* | etrax*) ++ basic_machine=cris-axis ++ ;; ++ crx) ++ basic_machine=crx-unknown ++ os=-elf ++ ;; ++ da30 | da30-*) ++ basic_machine=m68k-da30 ++ ;; ++ decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) ++ basic_machine=mips-dec ++ ;; ++ decsystem10* | dec10*) ++ basic_machine=pdp10-dec ++ os=-tops10 ++ ;; ++ decsystem20* | dec20*) ++ basic_machine=pdp10-dec ++ os=-tops20 ++ ;; ++ delta | 3300 | motorola-3300 | motorola-delta \ ++ | 3300-motorola | delta-motorola) ++ basic_machine=m68k-motorola ++ ;; ++ delta88) ++ basic_machine=m88k-motorola ++ os=-sysv3 ++ ;; ++ dicos) ++ basic_machine=i686-pc ++ os=-dicos ++ ;; ++ djgpp) ++ basic_machine=i586-pc ++ os=-msdosdjgpp ++ ;; ++ dpx20 | dpx20-*) ++ basic_machine=rs6000-bull ++ os=-bosx ++ ;; ++ dpx2* | dpx2*-bull) ++ basic_machine=m68k-bull ++ os=-sysv3 ++ ;; ++ ebmon29k) ++ basic_machine=a29k-amd ++ os=-ebmon ++ ;; ++ elxsi) ++ basic_machine=elxsi-elxsi ++ os=-bsd ++ ;; ++ encore | umax | mmax) ++ basic_machine=ns32k-encore ++ ;; ++ es1800 | OSE68k | ose68k | ose | OSE) ++ basic_machine=m68k-ericsson ++ os=-ose ++ ;; ++ fx2800) ++ basic_machine=i860-alliant ++ ;; ++ genix) ++ basic_machine=ns32k-ns ++ ;; ++ gmicro) ++ basic_machine=tron-gmicro ++ os=-sysv ++ ;; ++ go32) ++ basic_machine=i386-pc ++ os=-go32 ++ ;; ++ h3050r* | hiux*) ++ basic_machine=hppa1.1-hitachi ++ os=-hiuxwe2 ++ ;; ++ h8300hms) ++ basic_machine=h8300-hitachi ++ os=-hms ++ ;; ++ h8300xray) ++ basic_machine=h8300-hitachi ++ os=-xray ++ ;; ++ h8500hms) ++ basic_machine=h8500-hitachi ++ os=-hms ++ ;; ++ harris) ++ basic_machine=m88k-harris ++ os=-sysv3 ++ ;; ++ hp300-*) ++ basic_machine=m68k-hp ++ ;; ++ hp300bsd) ++ basic_machine=m68k-hp ++ os=-bsd ++ ;; ++ hp300hpux) ++ basic_machine=m68k-hp ++ os=-hpux ++ ;; ++ hp3k9[0-9][0-9] | hp9[0-9][0-9]) ++ basic_machine=hppa1.0-hp ++ ;; ++ hp9k2[0-9][0-9] | hp9k31[0-9]) ++ basic_machine=m68000-hp ++ ;; ++ hp9k3[2-9][0-9]) ++ basic_machine=m68k-hp ++ ;; ++ hp9k6[0-9][0-9] | hp6[0-9][0-9]) ++ basic_machine=hppa1.0-hp ++ ;; ++ hp9k7[0-79][0-9] | hp7[0-79][0-9]) ++ basic_machine=hppa1.1-hp ++ ;; ++ hp9k78[0-9] | hp78[0-9]) ++ # FIXME: really hppa2.0-hp ++ basic_machine=hppa1.1-hp ++ ;; ++ hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) ++ # FIXME: really hppa2.0-hp ++ basic_machine=hppa1.1-hp ++ ;; ++ hp9k8[0-9][13679] | hp8[0-9][13679]) ++ basic_machine=hppa1.1-hp ++ ;; ++ hp9k8[0-9][0-9] | hp8[0-9][0-9]) ++ basic_machine=hppa1.0-hp ++ ;; ++ hppa-next) ++ os=-nextstep3 ++ ;; ++ hppaosf) ++ basic_machine=hppa1.1-hp ++ os=-osf ++ ;; ++ hppro) ++ basic_machine=hppa1.1-hp ++ os=-proelf ++ ;; ++ i370-ibm* | ibm*) ++ basic_machine=i370-ibm ++ ;; ++# I'm not sure what "Sysv32" means. Should this be sysv3.2? ++ i*86v32) ++ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` ++ os=-sysv32 ++ ;; ++ i*86v4*) ++ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` ++ os=-sysv4 ++ ;; ++ i*86v) ++ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` ++ os=-sysv ++ ;; ++ i*86sol2) ++ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` ++ os=-solaris2 ++ ;; ++ i386mach) ++ basic_machine=i386-mach ++ os=-mach ++ ;; ++ i386-vsta | vsta) ++ basic_machine=i386-unknown ++ os=-vsta ++ ;; ++ iris | iris4d) ++ basic_machine=mips-sgi ++ case $os in ++ -irix*) ++ ;; ++ *) ++ os=-irix4 ++ ;; ++ esac ++ ;; ++ isi68 | isi) ++ basic_machine=m68k-isi ++ os=-sysv ++ ;; ++ m68knommu) ++ basic_machine=m68k-unknown ++ os=-linux ++ ;; ++ m68knommu-*) ++ basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` ++ os=-linux ++ ;; ++ m88k-omron*) ++ basic_machine=m88k-omron ++ ;; ++ magnum | m3230) ++ basic_machine=mips-mips ++ os=-sysv ++ ;; ++ merlin) ++ basic_machine=ns32k-utek ++ os=-sysv ++ ;; ++ mingw32) ++ basic_machine=i386-pc ++ os=-mingw32 ++ ;; ++ mingw32ce) ++ basic_machine=arm-unknown ++ os=-mingw32ce ++ ;; ++ miniframe) ++ basic_machine=m68000-convergent ++ ;; ++ *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) ++ basic_machine=m68k-atari ++ os=-mint ++ ;; ++ mipsEE* | ee | ps2) ++ basic_machine=mips64r5900el-scei ++ case $os in ++ -linux*) ++ ;; ++ *) ++ os=-elf ++ ;; ++ esac ++ ;; ++ iop) ++ basic_machine=mipsel-scei ++ os=-irx ++ ;; ++ dvp) ++ basic_machine=dvp-scei ++ os=-elf ++ ;; ++ mips3*-*) ++ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ++ ;; ++ mips3*) ++ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ++ ;; ++ monitor) ++ basic_machine=m68k-rom68k ++ os=-coff ++ ;; ++ morphos) ++ basic_machine=powerpc-unknown ++ os=-morphos ++ ;; ++ msdos) ++ basic_machine=i386-pc ++ os=-msdos ++ ;; ++ ms1-*) ++ basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ++ ;; ++ mvs) ++ basic_machine=i370-ibm ++ os=-mvs ++ ;; ++ ncr3000) ++ basic_machine=i486-ncr ++ os=-sysv4 ++ ;; ++ netbsd386) ++ basic_machine=i386-unknown ++ os=-netbsd ++ ;; ++ netwinder) ++ basic_machine=armv4l-rebel ++ os=-linux ++ ;; ++ news | news700 | news800 | news900) ++ basic_machine=m68k-sony ++ os=-newsos ++ ;; ++ news1000) ++ basic_machine=m68030-sony ++ os=-newsos ++ ;; ++ news-3600 | risc-news) ++ basic_machine=mips-sony ++ os=-newsos ++ ;; ++ necv70) ++ basic_machine=v70-nec ++ os=-sysv ++ ;; ++ next | m*-next ) ++ basic_machine=m68k-next ++ case $os in ++ -nextstep* ) ++ ;; ++ -ns2*) ++ os=-nextstep2 ++ ;; ++ *) ++ os=-nextstep3 ++ ;; ++ esac ++ ;; ++ nh3000) ++ basic_machine=m68k-harris ++ os=-cxux ++ ;; ++ nh[45]000) ++ basic_machine=m88k-harris ++ os=-cxux ++ ;; ++ nindy960) ++ basic_machine=i960-intel ++ os=-nindy ++ ;; ++ mon960) ++ basic_machine=i960-intel ++ os=-mon960 ++ ;; ++ nonstopux) ++ basic_machine=mips-compaq ++ os=-nonstopux ++ ;; ++ np1) ++ basic_machine=np1-gould ++ ;; ++ nsr-tandem) ++ basic_machine=nsr-tandem ++ ;; ++ op50n-* | op60c-*) ++ basic_machine=hppa1.1-oki ++ os=-proelf ++ ;; ++ openrisc | openrisc-*) ++ basic_machine=or32-unknown ++ ;; ++ os400) ++ basic_machine=powerpc-ibm ++ os=-os400 ++ ;; ++ OSE68000 | ose68000) ++ basic_machine=m68000-ericsson ++ os=-ose ++ ;; ++ os68k) ++ basic_machine=m68k-none ++ os=-os68k ++ ;; ++ pa-hitachi) ++ basic_machine=hppa1.1-hitachi ++ os=-hiuxwe2 ++ ;; ++ paragon) ++ basic_machine=i860-intel ++ os=-osf ++ ;; ++ parisc) ++ basic_machine=hppa-unknown ++ os=-linux ++ ;; ++ parisc-*) ++ basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` ++ os=-linux ++ ;; ++ pbd) ++ basic_machine=sparc-tti ++ ;; ++ pbb) ++ basic_machine=m68k-tti ++ ;; ++ pc532 | pc532-*) ++ basic_machine=ns32k-pc532 ++ ;; ++ pc98) ++ basic_machine=i386-pc ++ ;; ++ pc98-*) ++ basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ++ ;; ++ pentium | p5 | k5 | k6 | nexgen | viac3) ++ basic_machine=i586-pc ++ ;; ++ pentiumpro | p6 | 6x86 | athlon | athlon_*) ++ basic_machine=i686-pc ++ ;; ++ pentiumii | pentium2 | pentiumiii | pentium3) ++ basic_machine=i686-pc ++ ;; ++ pentium4) ++ basic_machine=i786-pc ++ ;; ++ pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) ++ basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ++ ;; ++ pentiumpro-* | p6-* | 6x86-* | athlon-*) ++ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ++ ;; ++ pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) ++ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ++ ;; ++ pentium4-*) ++ basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ++ ;; ++ pn) ++ basic_machine=pn-gould ++ ;; ++ power) basic_machine=power-ibm ++ ;; ++ ppc) basic_machine=powerpc-unknown ++ ;; ++ ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ++ ;; ++ ppcle | powerpclittle | ppc-le | powerpc-little) ++ basic_machine=powerpcle-unknown ++ ;; ++ ppcle-* | powerpclittle-*) ++ basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ++ ;; ++ ppc64) basic_machine=powerpc64-unknown ++ ;; ++ ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ++ ;; ++ ppc64le | powerpc64little | ppc64-le | powerpc64-little) ++ basic_machine=powerpc64le-unknown ++ ;; ++ ppc64le-* | powerpc64little-*) ++ basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ++ ;; ++ ps2) ++ basic_machine=i386-ibm ++ ;; ++ pw32) ++ basic_machine=i586-unknown ++ os=-pw32 ++ ;; ++ rdos) ++ basic_machine=i386-pc ++ os=-rdos ++ ;; ++ rom68k) ++ basic_machine=m68k-rom68k ++ os=-coff ++ ;; ++ rm[46]00) ++ basic_machine=mips-siemens ++ ;; ++ rtpc | rtpc-*) ++ basic_machine=romp-ibm ++ ;; ++ s390 | s390-*) ++ basic_machine=s390-ibm ++ ;; ++ s390x | s390x-*) ++ basic_machine=s390x-ibm ++ ;; ++ sa29200) ++ basic_machine=a29k-amd ++ os=-udi ++ ;; ++ sb1) ++ basic_machine=mipsisa64sb1-unknown ++ ;; ++ sb1el) ++ basic_machine=mipsisa64sb1el-unknown ++ ;; ++ sde) ++ basic_machine=mipsisa32-sde ++ os=-elf ++ ;; ++ sei) ++ basic_machine=mips-sei ++ os=-seiux ++ ;; ++ sequent) ++ basic_machine=i386-sequent ++ ;; ++ sh) ++ basic_machine=sh-hitachi ++ os=-hms ++ ;; ++ sh5el) ++ basic_machine=sh5le-unknown ++ ;; ++ sh64) ++ basic_machine=sh64-unknown ++ ;; ++ sparclite-wrs | simso-wrs) ++ basic_machine=sparclite-wrs ++ os=-vxworks ++ ;; ++ sps7) ++ basic_machine=m68k-bull ++ os=-sysv2 ++ ;; ++ spur) ++ basic_machine=spur-unknown ++ ;; ++ st2000) ++ basic_machine=m68k-tandem ++ ;; ++ stratus) ++ basic_machine=i860-stratus ++ os=-sysv4 ++ ;; ++ sun2) ++ basic_machine=m68000-sun ++ ;; ++ sun2os3) ++ basic_machine=m68000-sun ++ os=-sunos3 ++ ;; ++ sun2os4) ++ basic_machine=m68000-sun ++ os=-sunos4 ++ ;; ++ sun3os3) ++ basic_machine=m68k-sun ++ os=-sunos3 ++ ;; ++ sun3os4) ++ basic_machine=m68k-sun ++ os=-sunos4 ++ ;; ++ sun4os3) ++ basic_machine=sparc-sun ++ os=-sunos3 ++ ;; ++ sun4os4) ++ basic_machine=sparc-sun ++ os=-sunos4 ++ ;; ++ sun4sol2) ++ basic_machine=sparc-sun ++ os=-solaris2 ++ ;; ++ sun3 | sun3-*) ++ basic_machine=m68k-sun ++ ;; ++ sun4) ++ basic_machine=sparc-sun ++ ;; ++ sun386 | sun386i | roadrunner) ++ basic_machine=i386-sun ++ ;; ++ sv1) ++ basic_machine=sv1-cray ++ os=-unicos ++ ;; ++ symmetry) ++ basic_machine=i386-sequent ++ os=-dynix ++ ;; ++ t3e) ++ basic_machine=alphaev5-cray ++ os=-unicos ++ ;; ++ t90) ++ basic_machine=t90-cray ++ os=-unicos ++ ;; ++ tic54x | c54x*) ++ basic_machine=tic54x-unknown ++ os=-coff ++ ;; ++ tic55x | c55x*) ++ basic_machine=tic55x-unknown ++ os=-coff ++ ;; ++ tic6x | c6x*) ++ basic_machine=tic6x-unknown ++ os=-coff ++ ;; ++ tile*) ++ basic_machine=tile-unknown ++ os=-linux-gnu ++ ;; ++ tx39) ++ basic_machine=mipstx39-unknown ++ ;; ++ tx39el) ++ basic_machine=mipstx39el-unknown ++ ;; ++ toad1) ++ basic_machine=pdp10-xkl ++ os=-tops20 ++ ;; ++ tower | tower-32) ++ basic_machine=m68k-ncr ++ ;; ++ tpf) ++ basic_machine=s390x-ibm ++ os=-tpf ++ ;; ++ udi29k) ++ basic_machine=a29k-amd ++ os=-udi ++ ;; ++ ultra3) ++ basic_machine=a29k-nyu ++ os=-sym1 ++ ;; ++ v810 | necv810) ++ basic_machine=v810-nec ++ os=-none ++ ;; ++ vaxv) ++ basic_machine=vax-dec ++ os=-sysv ++ ;; ++ vms) ++ basic_machine=vax-dec ++ os=-vms ++ ;; ++ vpp*|vx|vx-*) ++ basic_machine=f301-fujitsu ++ ;; ++ vxworks960) ++ basic_machine=i960-wrs ++ os=-vxworks ++ ;; ++ vxworks68) ++ basic_machine=m68k-wrs ++ os=-vxworks ++ ;; ++ vxworks29k) ++ basic_machine=a29k-wrs ++ os=-vxworks ++ ;; ++ w65*) ++ basic_machine=w65-wdc ++ os=-none ++ ;; ++ w89k-*) ++ basic_machine=hppa1.1-winbond ++ os=-proelf ++ ;; ++ xbox) ++ basic_machine=i686-pc ++ os=-mingw32 ++ ;; ++ xps | xps100) ++ basic_machine=xps100-honeywell ++ ;; ++ ymp) ++ basic_machine=ymp-cray ++ os=-unicos ++ ;; ++ z8k-*-coff) ++ basic_machine=z8k-unknown ++ os=-sim ++ ;; ++ z80-*-coff) ++ basic_machine=z80-unknown ++ os=-sim ++ ;; ++ none) ++ basic_machine=none-none ++ os=-none ++ ;; ++ ++# Here we handle the default manufacturer of certain CPU types. It is in ++# some cases the only manufacturer, in others, it is the most popular. ++ w89k) ++ basic_machine=hppa1.1-winbond ++ ;; ++ op50n) ++ basic_machine=hppa1.1-oki ++ ;; ++ op60c) ++ basic_machine=hppa1.1-oki ++ ;; ++ romp) ++ basic_machine=romp-ibm ++ ;; ++ mmix) ++ basic_machine=mmix-knuth ++ ;; ++ rs6000) ++ basic_machine=rs6000-ibm ++ ;; ++ vax) ++ basic_machine=vax-dec ++ ;; ++ pdp10) ++ # there are many clones, so DEC is not a safe bet ++ basic_machine=pdp10-unknown ++ ;; ++ pdp11) ++ basic_machine=pdp11-dec ++ ;; ++ we32k) ++ basic_machine=we32k-att ++ ;; ++ sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) ++ basic_machine=sh-unknown ++ ;; ++ sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) ++ basic_machine=sparc-sun ++ ;; ++ cydra) ++ basic_machine=cydra-cydrome ++ ;; ++ orion) ++ basic_machine=orion-highlevel ++ ;; ++ orion105) ++ basic_machine=clipper-highlevel ++ ;; ++ mac | mpw | mac-mpw) ++ basic_machine=m68k-apple ++ ;; ++ pmac | pmac-mpw) ++ basic_machine=powerpc-apple ++ ;; ++ *-unknown) ++ # Make sure to match an already-canonicalized machine name. ++ ;; ++ *) ++ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 ++ exit 1 ++ ;; ++esac ++ ++# Here we canonicalize certain aliases for manufacturers. ++case $basic_machine in ++ *-digital*) ++ basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ++ ;; ++ *-commodore*) ++ basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ++ ;; ++ *) ++ ;; ++esac ++ ++# Decode manufacturer-specific aliases for certain operating systems. ++ ++if [ x"$os" != x"" ] ++then ++case $os in ++ # First match some system type aliases ++ # that might get confused with valid system types. ++ # -solaris* is a basic system type, with this one exception. ++ -solaris1 | -solaris1.*) ++ os=`echo $os | sed -e 's|solaris1|sunos4|'` ++ ;; ++ -solaris) ++ os=-solaris2 ++ ;; ++ -svr4*) ++ os=-sysv4 ++ ;; ++ -unixware*) ++ os=-sysv4.2uw ++ ;; ++ -gnu/linux*) ++ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ++ ;; ++ # First accept the basic system types. ++ # The portable systems comes first. ++ # Each alternative MUST END IN A *, to match a version number. ++ # -sysv* is not here because it comes later, after sysvr4. ++ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ ++ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ ++ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ ++ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ ++ | -aos* \ ++ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ ++ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ ++ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ ++ | -openbsd* | -solidbsd* \ ++ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ ++ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ ++ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ ++ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ ++ | -chorusos* | -chorusrdb* | -cegcc* \ ++ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ ++ | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ ++ | -uxpv* | -beos* | -mpeix* | -udk* \ ++ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ ++ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ ++ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ ++ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ ++ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ ++ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ ++ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -irx*) ++ # Remember, each alternative MUST END IN *, to match a version number. ++ ;; ++ -qnx*) ++ case $basic_machine in ++ x86-* | i*86-*) ++ ;; ++ *) ++ os=-nto$os ++ ;; ++ esac ++ ;; ++ -nto-qnx*) ++ ;; ++ -nto*) ++ os=`echo $os | sed -e 's|nto|nto-qnx|'` ++ ;; ++ -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ ++ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ ++ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ++ ;; ++ -mac*) ++ os=`echo $os | sed -e 's|mac|macos|'` ++ ;; ++ -linux-dietlibc) ++ os=-linux-dietlibc ++ ;; ++ -linux*) ++ os=`echo $os | sed -e 's|linux|linux-gnu|'` ++ ;; ++ -sunos5*) ++ os=`echo $os | sed -e 's|sunos5|solaris2|'` ++ ;; ++ -sunos6*) ++ os=`echo $os | sed -e 's|sunos6|solaris3|'` ++ ;; ++ -opened*) ++ os=-openedition ++ ;; ++ -os400*) ++ os=-os400 ++ ;; ++ -wince*) ++ os=-wince ++ ;; ++ -osfrose*) ++ os=-osfrose ++ ;; ++ -osf*) ++ os=-osf ++ ;; ++ -utek*) ++ os=-bsd ++ ;; ++ -dynix*) ++ os=-bsd ++ ;; ++ -acis*) ++ os=-aos ++ ;; ++ -atheos*) ++ os=-atheos ++ ;; ++ -syllable*) ++ os=-syllable ++ ;; ++ -386bsd) ++ os=-bsd ++ ;; ++ -ctix* | -uts*) ++ os=-sysv ++ ;; ++ -nova*) ++ os=-rtmk-nova ++ ;; ++ -ns2 ) ++ os=-nextstep2 ++ ;; ++ -nsk*) ++ os=-nsk ++ ;; ++ # Preserve the version number of sinix5. ++ -sinix5.*) ++ os=`echo $os | sed -e 's|sinix|sysv|'` ++ ;; ++ -sinix*) ++ os=-sysv4 ++ ;; ++ -tpf*) ++ os=-tpf ++ ;; ++ -triton*) ++ os=-sysv3 ++ ;; ++ -oss*) ++ os=-sysv3 ++ ;; ++ -svr4) ++ os=-sysv4 ++ ;; ++ -svr3) ++ os=-sysv3 ++ ;; ++ -sysvr4) ++ os=-sysv4 ++ ;; ++ # This must come after -sysvr4. ++ -sysv*) ++ ;; ++ -ose*) ++ os=-ose ++ ;; ++ -es1800*) ++ os=-ose ++ ;; ++ -xenix) ++ os=-xenix ++ ;; ++ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) ++ os=-mint ++ ;; ++ -aros*) ++ os=-aros ++ ;; ++ -kaos*) ++ os=-kaos ++ ;; ++ -zvmoe) ++ os=-zvmoe ++ ;; ++ -dicos*) ++ os=-dicos ++ ;; ++ -none) ++ ;; ++ *) ++ # Get rid of the `-' at the beginning of $os. ++ os=`echo $os | sed 's/[^-]*-//'` ++ echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 ++ exit 1 ++ ;; ++esac ++else ++ ++# Here we handle the default operating systems that come with various machines. ++# The value should be what the vendor currently ships out the door with their ++# machine or put another way, the most popular os provided with the machine. ++ ++# Note that if you're going to try to match "-MANUFACTURER" here (say, ++# "-sun"), then you have to tell the case statement up towards the top ++# that MANUFACTURER isn't an operating system. Otherwise, code above ++# will signal an error saying that MANUFACTURER isn't an operating ++# system, and we'll never get to this point. ++ ++case $basic_machine in ++ score-*) ++ os=-elf ++ ;; ++ spu-*) ++ os=-elf ++ ;; ++ *-acorn) ++ os=-riscix1.2 ++ ;; ++ arm*-rebel) ++ os=-linux ++ ;; ++ arm*-semi) ++ os=-aout ++ ;; ++ c4x-* | tic4x-*) ++ os=-coff ++ ;; ++ # This must come before the *-dec entry. ++ pdp10-*) ++ os=-tops20 ++ ;; ++ pdp11-*) ++ os=-none ++ ;; ++ *-dec | vax-*) ++ os=-ultrix4.2 ++ ;; ++ m68*-apollo) ++ os=-domain ++ ;; ++ i386-sun) ++ os=-sunos4.0.2 ++ ;; ++ m68000-sun) ++ os=-sunos3 ++ # This also exists in the configure program, but was not the ++ # default. ++ # os=-sunos4 ++ ;; ++ m68*-cisco) ++ os=-aout ++ ;; ++ mep-*) ++ os=-elf ++ ;; ++ mips*-cisco) ++ os=-elf ++ ;; ++ mips*-*) ++ os=-elf ++ ;; ++ or32-*) ++ os=-coff ++ ;; ++ *-tti) # must be before sparc entry or we get the wrong os. ++ os=-sysv3 ++ ;; ++ sparc-* | *-sun) ++ os=-sunos4.1.1 ++ ;; ++ *-be) ++ os=-beos ++ ;; ++ *-haiku) ++ os=-haiku ++ ;; ++ *-ibm) ++ os=-aix ++ ;; ++ *-knuth) ++ os=-mmixware ++ ;; ++ *-wec) ++ os=-proelf ++ ;; ++ *-winbond) ++ os=-proelf ++ ;; ++ *-oki) ++ os=-proelf ++ ;; ++ *-hp) ++ os=-hpux ++ ;; ++ *-hitachi) ++ os=-hiux ++ ;; ++ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) ++ os=-sysv ++ ;; ++ *-cbm) ++ os=-amigaos ++ ;; ++ *-dg) ++ os=-dgux ++ ;; ++ *-dolphin) ++ os=-sysv3 ++ ;; ++ m68k-ccur) ++ os=-rtu ++ ;; ++ m88k-omron*) ++ os=-luna ++ ;; ++ *-next ) ++ os=-nextstep ++ ;; ++ *-sequent) ++ os=-ptx ++ ;; ++ *-crds) ++ os=-unos ++ ;; ++ *-ns) ++ os=-genix ++ ;; ++ i370-*) ++ os=-mvs ++ ;; ++ *-next) ++ os=-nextstep3 ++ ;; ++ *-gould) ++ os=-sysv ++ ;; ++ *-highlevel) ++ os=-bsd ++ ;; ++ *-encore) ++ os=-bsd ++ ;; ++ *-sgi) ++ os=-irix ++ ;; ++ *-siemens) ++ os=-sysv4 ++ ;; ++ *-masscomp) ++ os=-rtu ++ ;; ++ f30[01]-fujitsu | f700-fujitsu) ++ os=-uxpv ++ ;; ++ *-rom68k) ++ os=-coff ++ ;; ++ *-*bug) ++ os=-coff ++ ;; ++ *-apple) ++ os=-macos ++ ;; ++ *-atari*) ++ os=-mint ++ ;; ++ *) ++ os=-none ++ ;; ++esac ++fi ++ ++# Here we handle the case where we know the os, and the CPU type, but not the ++# manufacturer. We pick the logical manufacturer. ++vendor=unknown ++case $basic_machine in ++ *-unknown) ++ case $os in ++ -riscix*) ++ vendor=acorn ++ ;; ++ -sunos*) ++ vendor=sun ++ ;; ++ -aix*) ++ vendor=ibm ++ ;; ++ -beos*) ++ vendor=be ++ ;; ++ -hpux*) ++ vendor=hp ++ ;; ++ -mpeix*) ++ vendor=hp ++ ;; ++ -hiux*) ++ vendor=hitachi ++ ;; ++ -unos*) ++ vendor=crds ++ ;; ++ -dgux*) ++ vendor=dg ++ ;; ++ -luna*) ++ vendor=omron ++ ;; ++ -genix*) ++ vendor=ns ++ ;; ++ -mvs* | -opened*) ++ vendor=ibm ++ ;; ++ -os400*) ++ vendor=ibm ++ ;; ++ -ptx*) ++ vendor=sequent ++ ;; ++ -tpf*) ++ vendor=ibm ++ ;; ++ -vxsim* | -vxworks* | -windiss*) ++ vendor=wrs ++ ;; ++ -aux*) ++ vendor=apple ++ ;; ++ -hms*) ++ vendor=hitachi ++ ;; ++ -mpw* | -macos*) ++ vendor=apple ++ ;; ++ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) ++ vendor=atari ++ ;; ++ -vos*) ++ vendor=stratus ++ ;; ++ esac ++ basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ++ ;; ++esac ++ ++echo $basic_machine$os ++exit ++ ++# Local variables: ++# eval: (add-hook 'write-file-hooks 'time-stamp) ++# time-stamp-start: "timestamp='" ++# time-stamp-format: "%:y-%02m-%02d" ++# time-stamp-end: "'" ++# End: +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/configure open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/configure +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/configure 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/configure 2012-04-09 21:53:58.000000000 -0500 +@@ -0,0 +1,22786 @@ ++#! /bin/sh ++# Guess values for system-dependent variables and create Makefiles. ++# Generated by GNU Autoconf 2.59 for iscsiuio 0.7.2.1. ++# ++# Report bugs to . ++# ++# Copyright (C) 2003 Free Software Foundation, Inc. ++# This configure script is free software; the Free Software Foundation ++# gives unlimited permission to copy, distribute and modify it. ++## --------------------- ## ++## M4sh Initialization. ## ++## --------------------- ## ++ ++# Be Bourne compatible ++if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then ++ emulate sh ++ NULLCMD=: ++ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which ++ # is contrary to our usage. Disable this feature. ++ alias -g '${1+"$@"}'='"$@"' ++elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then ++ set -o posix ++fi ++DUALCASE=1; export DUALCASE # for MKS sh ++ ++# Support unset when possible. ++if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then ++ as_unset=unset ++else ++ as_unset=false ++fi ++ ++ ++# Work around bugs in pre-3.0 UWIN ksh. ++$as_unset ENV MAIL MAILPATH ++PS1='$ ' ++PS2='> ' ++PS4='+ ' ++ ++# NLS nuisances. ++for as_var in \ ++ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ ++ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ ++ LC_TELEPHONE LC_TIME ++do ++ if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then ++ eval $as_var=C; export $as_var ++ else ++ $as_unset $as_var ++ fi ++done ++ ++# Required to use basename. ++if expr a : '\(a\)' >/dev/null 2>&1; then ++ as_expr=expr ++else ++ as_expr=false ++fi ++ ++if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then ++ as_basename=basename ++else ++ as_basename=false ++fi ++ ++ ++# Name of the executable. ++as_me=`$as_basename "$0" || ++$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ ++ X"$0" : 'X\(//\)$' \| \ ++ X"$0" : 'X\(/\)$' \| \ ++ . : '\(.\)' 2>/dev/null || ++echo X/"$0" | ++ sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } ++ /^X\/\(\/\/\)$/{ s//\1/; q; } ++ /^X\/\(\/\).*/{ s//\1/; q; } ++ s/.*/./; q'` ++ ++ ++# PATH needs CR, and LINENO needs CR and PATH. ++# Avoid depending upon Character Ranges. ++as_cr_letters='abcdefghijklmnopqrstuvwxyz' ++as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' ++as_cr_Letters=$as_cr_letters$as_cr_LETTERS ++as_cr_digits='0123456789' ++as_cr_alnum=$as_cr_Letters$as_cr_digits ++ ++# The user is always right. ++if test "${PATH_SEPARATOR+set}" != set; then ++ echo "#! /bin/sh" >conf$$.sh ++ echo "exit 0" >>conf$$.sh ++ chmod +x conf$$.sh ++ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then ++ PATH_SEPARATOR=';' ++ else ++ PATH_SEPARATOR=: ++ fi ++ rm -f conf$$.sh ++fi ++ ++ ++ as_lineno_1=$LINENO ++ as_lineno_2=$LINENO ++ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` ++ test "x$as_lineno_1" != "x$as_lineno_2" && ++ test "x$as_lineno_3" = "x$as_lineno_2" || { ++ # Find who we are. Look in the path if we contain no path at all ++ # relative or not. ++ case $0 in ++ *[\\/]* ) as_myself=$0 ;; ++ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break ++done ++ ++ ;; ++ esac ++ # We did not find ourselves, most probably we were run as `sh COMMAND' ++ # in which case we are not to be found in the path. ++ if test "x$as_myself" = x; then ++ as_myself=$0 ++ fi ++ if test ! -f "$as_myself"; then ++ { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 ++ { (exit 1); exit 1; }; } ++ fi ++ case $CONFIG_SHELL in ++ '') ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for as_base in sh bash ksh sh5; do ++ case $as_dir in ++ /*) ++ if ("$as_dir/$as_base" -c ' ++ as_lineno_1=$LINENO ++ as_lineno_2=$LINENO ++ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` ++ test "x$as_lineno_1" != "x$as_lineno_2" && ++ test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then ++ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } ++ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } ++ CONFIG_SHELL=$as_dir/$as_base ++ export CONFIG_SHELL ++ exec "$CONFIG_SHELL" "$0" ${1+"$@"} ++ fi;; ++ esac ++ done ++done ++;; ++ esac ++ ++ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO ++ # uniformly replaced by the line number. The first 'sed' inserts a ++ # line-number line before each line; the second 'sed' does the real ++ # work. The second script uses 'N' to pair each line-number line ++ # with the numbered line, and appends trailing '-' during ++ # substitution so that $LINENO is not a special case at line end. ++ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the ++ # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) ++ sed '=' <$as_myself | ++ sed ' ++ N ++ s,$,-, ++ : loop ++ s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, ++ t loop ++ s,-$,, ++ s,^['$as_cr_digits']*\n,, ++ ' >$as_me.lineno && ++ chmod +x $as_me.lineno || ++ { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 ++ { (exit 1); exit 1; }; } ++ ++ # Don't try to exec as it changes $[0], causing all sort of problems ++ # (the dirname of $[0] is not the place where we might find the ++ # original and so on. Autoconf is especially sensible to this). ++ . ./$as_me.lineno ++ # Exit status is that of the last command. ++ exit ++} ++ ++ ++case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in ++ *c*,-n*) ECHO_N= ECHO_C=' ++' ECHO_T=' ' ;; ++ *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; ++ *) ECHO_N= ECHO_C='\c' ECHO_T= ;; ++esac ++ ++if expr a : '\(a\)' >/dev/null 2>&1; then ++ as_expr=expr ++else ++ as_expr=false ++fi ++ ++rm -f conf$$ conf$$.exe conf$$.file ++echo >conf$$.file ++if ln -s conf$$.file conf$$ 2>/dev/null; then ++ # We could just check for DJGPP; but this test a) works b) is more generic ++ # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). ++ if test -f conf$$.exe; then ++ # Don't use ln at all; we don't have any links ++ as_ln_s='cp -p' ++ else ++ as_ln_s='ln -s' ++ fi ++elif ln conf$$.file conf$$ 2>/dev/null; then ++ as_ln_s=ln ++else ++ as_ln_s='cp -p' ++fi ++rm -f conf$$ conf$$.exe conf$$.file ++ ++if mkdir -p . 2>/dev/null; then ++ as_mkdir_p=: ++else ++ test -d ./-p && rmdir ./-p ++ as_mkdir_p=false ++fi ++ ++as_executable_p="test -f" ++ ++# Sed expression to map a string onto a valid CPP name. ++as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" ++ ++# Sed expression to map a string onto a valid variable name. ++as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" ++ ++ ++# IFS ++# We need space, tab and new line, in precisely that order. ++as_nl=' ++' ++IFS=" $as_nl" ++ ++# CDPATH. ++$as_unset CDPATH ++ ++ ++ ++# Check that we are running under the correct shell. ++SHELL=${CONFIG_SHELL-/bin/sh} ++ ++case X$ECHO in ++X*--fallback-echo) ++ # Remove one level of quotation (which was required for Make). ++ ECHO=`echo "$ECHO" | sed 's,\\\\\$\\$0,'$0','` ++ ;; ++esac ++ ++echo=${ECHO-echo} ++if test "X$1" = X--no-reexec; then ++ # Discard the --no-reexec flag, and continue. ++ shift ++elif test "X$1" = X--fallback-echo; then ++ # Avoid inline document here, it may be left over ++ : ++elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then ++ # Yippee, $echo works! ++ : ++else ++ # Restart under the correct shell. ++ exec $SHELL "$0" --no-reexec ${1+"$@"} ++fi ++ ++if test "X$1" = X--fallback-echo; then ++ # used as fallback echo ++ shift ++ cat </dev/null 2>&1 && unset CDPATH ++ ++if test -z "$ECHO"; then ++if test "X${echo_test_string+set}" != Xset; then ++# find a string as large as possible, as long as the shell can cope with it ++ for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do ++ # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... ++ if (echo_test_string=`eval $cmd`) 2>/dev/null && ++ echo_test_string=`eval $cmd` && ++ (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null ++ then ++ break ++ fi ++ done ++fi ++ ++if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ : ++else ++ # The Solaris, AIX, and Digital Unix default echo programs unquote ++ # backslashes. This makes it impossible to quote backslashes using ++ # echo "$something" | sed 's/\\/\\\\/g' ++ # ++ # So, first we look for a working echo in the user's PATH. ++ ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++ for dir in $PATH /usr/ucb; do ++ IFS="$lt_save_ifs" ++ if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && ++ test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ echo="$dir/echo" ++ break ++ fi ++ done ++ IFS="$lt_save_ifs" ++ ++ if test "X$echo" = Xecho; then ++ # We didn't find a better echo, so look for alternatives. ++ if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ # This shell has a builtin print -r that does the trick. ++ echo='print -r' ++ elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && ++ test "X$CONFIG_SHELL" != X/bin/ksh; then ++ # If we have ksh, try running configure again with it. ++ ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} ++ export ORIGINAL_CONFIG_SHELL ++ CONFIG_SHELL=/bin/ksh ++ export CONFIG_SHELL ++ exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"} ++ else ++ # Try using printf. ++ echo='printf %s\n' ++ if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ # Cool, printf works ++ : ++ elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && ++ test "X$echo_testing_string" = 'X\t' && ++ echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL ++ export CONFIG_SHELL ++ SHELL="$CONFIG_SHELL" ++ export SHELL ++ echo="$CONFIG_SHELL $0 --fallback-echo" ++ elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && ++ test "X$echo_testing_string" = 'X\t' && ++ echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ echo="$CONFIG_SHELL $0 --fallback-echo" ++ else ++ # maybe with a smaller string... ++ prev=: ++ ++ for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do ++ if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null ++ then ++ break ++ fi ++ prev="$cmd" ++ done ++ ++ if test "$prev" != 'sed 50q "$0"'; then ++ echo_test_string=`eval $prev` ++ export echo_test_string ++ exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"} ++ else ++ # Oops. We lost completely, so just stick with echo. ++ echo=echo ++ fi ++ fi ++ fi ++ fi ++fi ++fi ++ ++# Copy echo and quote the copy suitably for passing to libtool from ++# the Makefile, instead of quoting the original, which is used later. ++ECHO=$echo ++if test "X$ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then ++ ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo" ++fi ++ ++ ++ ++ ++tagnames=${tagnames+${tagnames},}CXX ++ ++tagnames=${tagnames+${tagnames},}F77 ++ ++# Name of the host. ++# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, ++# so uname gets run too. ++ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` ++ ++exec 6>&1 ++ ++# ++# Initializations. ++# ++ac_default_prefix=/usr/local ++ac_config_libobj_dir=. ++cross_compiling=no ++subdirs= ++MFLAGS= ++MAKEFLAGS= ++SHELL=${CONFIG_SHELL-/bin/sh} ++ ++# Maximum number of lines to put in a shell here document. ++# This variable seems obsolete. It should probably be removed, and ++# only ac_max_sed_lines should be used. ++: ${ac_max_here_lines=38} ++ ++# Identity of this package. ++PACKAGE_NAME='iscsiuio' ++PACKAGE_TARNAME='iscsiuio' ++PACKAGE_VERSION='0.7.2.1' ++PACKAGE_STRING='iscsiuio 0.7.2.1' ++PACKAGE_BUGREPORT='eddie.wai@broadcom.com' ++ ++# Factoring default headers for most tests. ++ac_includes_default="\ ++#include ++#if HAVE_SYS_TYPES_H ++# include ++#endif ++#if HAVE_SYS_STAT_H ++# include ++#endif ++#if STDC_HEADERS ++# include ++# include ++#else ++# if HAVE_STDLIB_H ++# include ++# endif ++#endif ++#if HAVE_STRING_H ++# if !STDC_HEADERS && HAVE_MEMORY_H ++# include ++# endif ++# include ++#endif ++#if HAVE_STRINGS_H ++# include ++#endif ++#if HAVE_INTTYPES_H ++# include ++#else ++# if HAVE_STDINT_H ++# include ++# endif ++#endif ++#if HAVE_UNISTD_H ++# include ++#endif" ++ ++ac_default_prefix= ++ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar BASH CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE RANLIB ac_ct_RANLIB CPP EGREP ENDIAN build build_cpu build_vendor build_os host host_cpu host_vendor host_os SED LN_S ECHO AR ac_ct_AR CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL DEBUG_TRUE DEBUG_FALSE LIBOBJS LTLIBOBJS' ++ac_subst_files='' ++ ++# Initialize some variables set by options. ++ac_init_help= ++ac_init_version=false ++# The variables have the same names as the options, with ++# dashes changed to underlines. ++cache_file=/dev/null ++exec_prefix=NONE ++no_create= ++no_recursion= ++prefix=NONE ++program_prefix=NONE ++program_suffix=NONE ++program_transform_name=s,x,x, ++silent= ++site= ++srcdir= ++verbose= ++x_includes=NONE ++x_libraries=NONE ++ ++# Installation directory options. ++# These are left unexpanded so users can "make install exec_prefix=/foo" ++# and all the variables that are supposed to be based on exec_prefix ++# by default will actually change. ++# Use braces instead of parens because sh, perl, etc. also accept them. ++bindir='${exec_prefix}/bin' ++sbindir='${exec_prefix}/sbin' ++libexecdir='${exec_prefix}/libexec' ++datadir='${prefix}/share' ++sysconfdir='${prefix}/etc' ++sharedstatedir='${prefix}/com' ++localstatedir='${prefix}/var' ++libdir='${exec_prefix}/lib' ++includedir='${prefix}/include' ++oldincludedir='/usr/include' ++infodir='${prefix}/info' ++mandir='${prefix}/man' ++ ++ac_prev= ++for ac_option ++do ++ # If the previous option needs an argument, assign it. ++ if test -n "$ac_prev"; then ++ eval "$ac_prev=\$ac_option" ++ ac_prev= ++ continue ++ fi ++ ++ ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` ++ ++ # Accept the important Cygnus configure options, so we can diagnose typos. ++ ++ case $ac_option in ++ ++ -bindir | --bindir | --bindi | --bind | --bin | --bi) ++ ac_prev=bindir ;; ++ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) ++ bindir=$ac_optarg ;; ++ ++ -build | --build | --buil | --bui | --bu) ++ ac_prev=build_alias ;; ++ -build=* | --build=* | --buil=* | --bui=* | --bu=*) ++ build_alias=$ac_optarg ;; ++ ++ -cache-file | --cache-file | --cache-fil | --cache-fi \ ++ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ++ ac_prev=cache_file ;; ++ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ ++ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) ++ cache_file=$ac_optarg ;; ++ ++ --config-cache | -C) ++ cache_file=config.cache ;; ++ ++ -datadir | --datadir | --datadi | --datad | --data | --dat | --da) ++ ac_prev=datadir ;; ++ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ ++ | --da=*) ++ datadir=$ac_optarg ;; ++ ++ -disable-* | --disable-*) ++ ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` ++ # Reject names that are not valid shell variable names. ++ expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && ++ { echo "$as_me: error: invalid feature name: $ac_feature" >&2 ++ { (exit 1); exit 1; }; } ++ ac_feature=`echo $ac_feature | sed 's/-/_/g'` ++ eval "enable_$ac_feature=no" ;; ++ ++ -enable-* | --enable-*) ++ ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` ++ # Reject names that are not valid shell variable names. ++ expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && ++ { echo "$as_me: error: invalid feature name: $ac_feature" >&2 ++ { (exit 1); exit 1; }; } ++ ac_feature=`echo $ac_feature | sed 's/-/_/g'` ++ case $ac_option in ++ *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; ++ *) ac_optarg=yes ;; ++ esac ++ eval "enable_$ac_feature='$ac_optarg'" ;; ++ ++ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ ++ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ ++ | --exec | --exe | --ex) ++ ac_prev=exec_prefix ;; ++ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ ++ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ ++ | --exec=* | --exe=* | --ex=*) ++ exec_prefix=$ac_optarg ;; ++ ++ -gas | --gas | --ga | --g) ++ # Obsolete; use --with-gas. ++ with_gas=yes ;; ++ ++ -help | --help | --hel | --he | -h) ++ ac_init_help=long ;; ++ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ++ ac_init_help=recursive ;; ++ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ++ ac_init_help=short ;; ++ ++ -host | --host | --hos | --ho) ++ ac_prev=host_alias ;; ++ -host=* | --host=* | --hos=* | --ho=*) ++ host_alias=$ac_optarg ;; ++ ++ -includedir | --includedir | --includedi | --included | --include \ ++ | --includ | --inclu | --incl | --inc) ++ ac_prev=includedir ;; ++ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ ++ | --includ=* | --inclu=* | --incl=* | --inc=*) ++ includedir=$ac_optarg ;; ++ ++ -infodir | --infodir | --infodi | --infod | --info | --inf) ++ ac_prev=infodir ;; ++ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) ++ infodir=$ac_optarg ;; ++ ++ -libdir | --libdir | --libdi | --libd) ++ ac_prev=libdir ;; ++ -libdir=* | --libdir=* | --libdi=* | --libd=*) ++ libdir=$ac_optarg ;; ++ ++ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ ++ | --libexe | --libex | --libe) ++ ac_prev=libexecdir ;; ++ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ ++ | --libexe=* | --libex=* | --libe=*) ++ libexecdir=$ac_optarg ;; ++ ++ -localstatedir | --localstatedir | --localstatedi | --localstated \ ++ | --localstate | --localstat | --localsta | --localst \ ++ | --locals | --local | --loca | --loc | --lo) ++ ac_prev=localstatedir ;; ++ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ ++ | --localstate=* | --localstat=* | --localsta=* | --localst=* \ ++ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) ++ localstatedir=$ac_optarg ;; ++ ++ -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ++ ac_prev=mandir ;; ++ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) ++ mandir=$ac_optarg ;; ++ ++ -nfp | --nfp | --nf) ++ # Obsolete; use --without-fp. ++ with_fp=no ;; ++ ++ -no-create | --no-create | --no-creat | --no-crea | --no-cre \ ++ | --no-cr | --no-c | -n) ++ no_create=yes ;; ++ ++ -no-recursion | --no-recursion | --no-recursio | --no-recursi \ ++ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ++ no_recursion=yes ;; ++ ++ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ ++ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ ++ | --oldin | --oldi | --old | --ol | --o) ++ ac_prev=oldincludedir ;; ++ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ ++ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ ++ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) ++ oldincludedir=$ac_optarg ;; ++ ++ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ++ ac_prev=prefix ;; ++ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) ++ prefix=$ac_optarg ;; ++ ++ -program-prefix | --program-prefix | --program-prefi | --program-pref \ ++ | --program-pre | --program-pr | --program-p) ++ ac_prev=program_prefix ;; ++ -program-prefix=* | --program-prefix=* | --program-prefi=* \ ++ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) ++ program_prefix=$ac_optarg ;; ++ ++ -program-suffix | --program-suffix | --program-suffi | --program-suff \ ++ | --program-suf | --program-su | --program-s) ++ ac_prev=program_suffix ;; ++ -program-suffix=* | --program-suffix=* | --program-suffi=* \ ++ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) ++ program_suffix=$ac_optarg ;; ++ ++ -program-transform-name | --program-transform-name \ ++ | --program-transform-nam | --program-transform-na \ ++ | --program-transform-n | --program-transform- \ ++ | --program-transform | --program-transfor \ ++ | --program-transfo | --program-transf \ ++ | --program-trans | --program-tran \ ++ | --progr-tra | --program-tr | --program-t) ++ ac_prev=program_transform_name ;; ++ -program-transform-name=* | --program-transform-name=* \ ++ | --program-transform-nam=* | --program-transform-na=* \ ++ | --program-transform-n=* | --program-transform-=* \ ++ | --program-transform=* | --program-transfor=* \ ++ | --program-transfo=* | --program-transf=* \ ++ | --program-trans=* | --program-tran=* \ ++ | --progr-tra=* | --program-tr=* | --program-t=*) ++ program_transform_name=$ac_optarg ;; ++ ++ -q | -quiet | --quiet | --quie | --qui | --qu | --q \ ++ | -silent | --silent | --silen | --sile | --sil) ++ silent=yes ;; ++ ++ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ++ ac_prev=sbindir ;; ++ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ ++ | --sbi=* | --sb=*) ++ sbindir=$ac_optarg ;; ++ ++ -sharedstatedir | --sharedstatedir | --sharedstatedi \ ++ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ ++ | --sharedst | --shareds | --shared | --share | --shar \ ++ | --sha | --sh) ++ ac_prev=sharedstatedir ;; ++ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ ++ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ ++ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ ++ | --sha=* | --sh=*) ++ sharedstatedir=$ac_optarg ;; ++ ++ -site | --site | --sit) ++ ac_prev=site ;; ++ -site=* | --site=* | --sit=*) ++ site=$ac_optarg ;; ++ ++ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ++ ac_prev=srcdir ;; ++ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) ++ srcdir=$ac_optarg ;; ++ ++ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ ++ | --syscon | --sysco | --sysc | --sys | --sy) ++ ac_prev=sysconfdir ;; ++ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ ++ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) ++ sysconfdir=$ac_optarg ;; ++ ++ -target | --target | --targe | --targ | --tar | --ta | --t) ++ ac_prev=target_alias ;; ++ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) ++ target_alias=$ac_optarg ;; ++ ++ -v | -verbose | --verbose | --verbos | --verbo | --verb) ++ verbose=yes ;; ++ ++ -version | --version | --versio | --versi | --vers | -V) ++ ac_init_version=: ;; ++ ++ -with-* | --with-*) ++ ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` ++ # Reject names that are not valid shell variable names. ++ expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && ++ { echo "$as_me: error: invalid package name: $ac_package" >&2 ++ { (exit 1); exit 1; }; } ++ ac_package=`echo $ac_package| sed 's/-/_/g'` ++ case $ac_option in ++ *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; ++ *) ac_optarg=yes ;; ++ esac ++ eval "with_$ac_package='$ac_optarg'" ;; ++ ++ -without-* | --without-*) ++ ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` ++ # Reject names that are not valid shell variable names. ++ expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && ++ { echo "$as_me: error: invalid package name: $ac_package" >&2 ++ { (exit 1); exit 1; }; } ++ ac_package=`echo $ac_package | sed 's/-/_/g'` ++ eval "with_$ac_package=no" ;; ++ ++ --x) ++ # Obsolete; use --with-x. ++ with_x=yes ;; ++ ++ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ ++ | --x-incl | --x-inc | --x-in | --x-i) ++ ac_prev=x_includes ;; ++ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ ++ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) ++ x_includes=$ac_optarg ;; ++ ++ -x-libraries | --x-libraries | --x-librarie | --x-librari \ ++ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ++ ac_prev=x_libraries ;; ++ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ ++ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) ++ x_libraries=$ac_optarg ;; ++ ++ -*) { echo "$as_me: error: unrecognized option: $ac_option ++Try \`$0 --help' for more information." >&2 ++ { (exit 1); exit 1; }; } ++ ;; ++ ++ *=*) ++ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` ++ # Reject names that are not valid shell variable names. ++ expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && ++ { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 ++ { (exit 1); exit 1; }; } ++ ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ++ eval "$ac_envvar='$ac_optarg'" ++ export $ac_envvar ;; ++ ++ *) ++ # FIXME: should be removed in autoconf 3.0. ++ echo "$as_me: WARNING: you should use --build, --host, --target" >&2 ++ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && ++ echo "$as_me: WARNING: invalid host type: $ac_option" >&2 ++ : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ++ ;; ++ ++ esac ++done ++ ++if test -n "$ac_prev"; then ++ ac_option=--`echo $ac_prev | sed 's/_/-/g'` ++ { echo "$as_me: error: missing argument to $ac_option" >&2 ++ { (exit 1); exit 1; }; } ++fi ++ ++# Be sure to have absolute paths. ++for ac_var in exec_prefix prefix ++do ++ eval ac_val=$`echo $ac_var` ++ case $ac_val in ++ [\\/$]* | ?:[\\/]* | NONE | '' ) ;; ++ *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 ++ { (exit 1); exit 1; }; };; ++ esac ++done ++ ++# Be sure to have absolute paths. ++for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ ++ localstatedir libdir includedir oldincludedir infodir mandir ++do ++ eval ac_val=$`echo $ac_var` ++ case $ac_val in ++ [\\/$]* | ?:[\\/]* ) ;; ++ *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 ++ { (exit 1); exit 1; }; };; ++ esac ++done ++ ++# There might be people who depend on the old broken behavior: `$host' ++# used to hold the argument of --host etc. ++# FIXME: To remove some day. ++build=$build_alias ++host=$host_alias ++target=$target_alias ++ ++# FIXME: To remove some day. ++if test "x$host_alias" != x; then ++ if test "x$build_alias" = x; then ++ cross_compiling=maybe ++ echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. ++ If a cross compiler is detected then cross compile mode will be used." >&2 ++ elif test "x$build_alias" != "x$host_alias"; then ++ cross_compiling=yes ++ fi ++fi ++ ++ac_tool_prefix= ++test -n "$host_alias" && ac_tool_prefix=$host_alias- ++ ++test "$silent" = yes && exec 6>/dev/null ++ ++ ++# Find the source files, if location was not specified. ++if test -z "$srcdir"; then ++ ac_srcdir_defaulted=yes ++ # Try the directory containing this script, then its parent. ++ ac_confdir=`(dirname "$0") 2>/dev/null || ++$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ ++ X"$0" : 'X\(//\)[^/]' \| \ ++ X"$0" : 'X\(//\)$' \| \ ++ X"$0" : 'X\(/\)' \| \ ++ . : '\(.\)' 2>/dev/null || ++echo X"$0" | ++ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } ++ /^X\(\/\/\)[^/].*/{ s//\1/; q; } ++ /^X\(\/\/\)$/{ s//\1/; q; } ++ /^X\(\/\).*/{ s//\1/; q; } ++ s/.*/./; q'` ++ srcdir=$ac_confdir ++ if test ! -r $srcdir/$ac_unique_file; then ++ srcdir=.. ++ fi ++else ++ ac_srcdir_defaulted=no ++fi ++if test ! -r $srcdir/$ac_unique_file; then ++ if test "$ac_srcdir_defaulted" = yes; then ++ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 ++ { (exit 1); exit 1; }; } ++ else ++ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 ++ { (exit 1); exit 1; }; } ++ fi ++fi ++(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || ++ { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 ++ { (exit 1); exit 1; }; } ++srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` ++ac_env_build_alias_set=${build_alias+set} ++ac_env_build_alias_value=$build_alias ++ac_cv_env_build_alias_set=${build_alias+set} ++ac_cv_env_build_alias_value=$build_alias ++ac_env_host_alias_set=${host_alias+set} ++ac_env_host_alias_value=$host_alias ++ac_cv_env_host_alias_set=${host_alias+set} ++ac_cv_env_host_alias_value=$host_alias ++ac_env_target_alias_set=${target_alias+set} ++ac_env_target_alias_value=$target_alias ++ac_cv_env_target_alias_set=${target_alias+set} ++ac_cv_env_target_alias_value=$target_alias ++ac_env_CC_set=${CC+set} ++ac_env_CC_value=$CC ++ac_cv_env_CC_set=${CC+set} ++ac_cv_env_CC_value=$CC ++ac_env_CFLAGS_set=${CFLAGS+set} ++ac_env_CFLAGS_value=$CFLAGS ++ac_cv_env_CFLAGS_set=${CFLAGS+set} ++ac_cv_env_CFLAGS_value=$CFLAGS ++ac_env_LDFLAGS_set=${LDFLAGS+set} ++ac_env_LDFLAGS_value=$LDFLAGS ++ac_cv_env_LDFLAGS_set=${LDFLAGS+set} ++ac_cv_env_LDFLAGS_value=$LDFLAGS ++ac_env_CPPFLAGS_set=${CPPFLAGS+set} ++ac_env_CPPFLAGS_value=$CPPFLAGS ++ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} ++ac_cv_env_CPPFLAGS_value=$CPPFLAGS ++ac_env_CPP_set=${CPP+set} ++ac_env_CPP_value=$CPP ++ac_cv_env_CPP_set=${CPP+set} ++ac_cv_env_CPP_value=$CPP ++ac_env_CXX_set=${CXX+set} ++ac_env_CXX_value=$CXX ++ac_cv_env_CXX_set=${CXX+set} ++ac_cv_env_CXX_value=$CXX ++ac_env_CXXFLAGS_set=${CXXFLAGS+set} ++ac_env_CXXFLAGS_value=$CXXFLAGS ++ac_cv_env_CXXFLAGS_set=${CXXFLAGS+set} ++ac_cv_env_CXXFLAGS_value=$CXXFLAGS ++ac_env_CXXCPP_set=${CXXCPP+set} ++ac_env_CXXCPP_value=$CXXCPP ++ac_cv_env_CXXCPP_set=${CXXCPP+set} ++ac_cv_env_CXXCPP_value=$CXXCPP ++ac_env_F77_set=${F77+set} ++ac_env_F77_value=$F77 ++ac_cv_env_F77_set=${F77+set} ++ac_cv_env_F77_value=$F77 ++ac_env_FFLAGS_set=${FFLAGS+set} ++ac_env_FFLAGS_value=$FFLAGS ++ac_cv_env_FFLAGS_set=${FFLAGS+set} ++ac_cv_env_FFLAGS_value=$FFLAGS ++ ++# ++# Report the --help message. ++# ++if test "$ac_init_help" = "long"; then ++ # Omit some internal or obsolete options to make the list less imposing. ++ # This message is too long to be a string in the A/UX 3.1 sh. ++ cat <<_ACEOF ++\`configure' configures iscsiuio 0.7.2.1 to adapt to many kinds of systems. ++ ++Usage: $0 [OPTION]... [VAR=VALUE]... ++ ++To assign environment variables (e.g., CC, CFLAGS...), specify them as ++VAR=VALUE. See below for descriptions of some of the useful variables. ++ ++Defaults for the options are specified in brackets. ++ ++Configuration: ++ -h, --help display this help and exit ++ --help=short display options specific to this package ++ --help=recursive display the short help of all the included packages ++ -V, --version display version information and exit ++ -q, --quiet, --silent do not print \`checking...' messages ++ --cache-file=FILE cache test results in FILE [disabled] ++ -C, --config-cache alias for \`--cache-file=config.cache' ++ -n, --no-create do not create output files ++ --srcdir=DIR find the sources in DIR [configure dir or \`..'] ++ ++_ACEOF ++ ++ cat <<_ACEOF ++Installation directories: ++ --prefix=PREFIX install architecture-independent files in PREFIX ++ [$ac_default_prefix] ++ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX ++ [PREFIX] ++ ++By default, \`make install' will install all the files in ++\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify ++an installation prefix other than \`$ac_default_prefix' using \`--prefix', ++for instance \`--prefix=\$HOME'. ++ ++For better control, use the options below. ++ ++Fine tuning of the installation directories: ++ --bindir=DIR user executables [EPREFIX/bin] ++ --sbindir=DIR system admin executables [EPREFIX/sbin] ++ --libexecdir=DIR program executables [EPREFIX/libexec] ++ --datadir=DIR read-only architecture-independent data [PREFIX/share] ++ --sysconfdir=DIR read-only single-machine data [PREFIX/etc] ++ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] ++ --localstatedir=DIR modifiable single-machine data [PREFIX/var] ++ --libdir=DIR object code libraries [EPREFIX/lib] ++ --includedir=DIR C header files [PREFIX/include] ++ --oldincludedir=DIR C header files for non-gcc [/usr/include] ++ --infodir=DIR info documentation [PREFIX/info] ++ --mandir=DIR man documentation [PREFIX/man] ++_ACEOF ++ ++ cat <<\_ACEOF ++ ++Program names: ++ --program-prefix=PREFIX prepend PREFIX to installed program names ++ --program-suffix=SUFFIX append SUFFIX to installed program names ++ --program-transform-name=PROGRAM run sed PROGRAM on installed program names ++ ++System types: ++ --build=BUILD configure for building on BUILD [guessed] ++ --host=HOST cross-compile to build programs to run on HOST [BUILD] ++_ACEOF ++fi ++ ++if test -n "$ac_init_help"; then ++ case $ac_init_help in ++ short | recursive ) echo "Configuration of iscsiuio 0.7.2.1:";; ++ esac ++ cat <<\_ACEOF ++ ++Optional Features: ++ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) ++ --enable-FEATURE[=ARG] include FEATURE [ARG=yes] ++ --disable-dependency-tracking speeds up one-time build ++ --enable-dependency-tracking do not reject slow dependency extractors ++ --enable-shared[=PKGS] ++ build shared libraries [default=yes] ++ --enable-static[=PKGS] ++ build static libraries [default=yes] ++ --enable-fast-install[=PKGS] ++ optimize for fast installation [default=yes] ++ --disable-libtool-lock avoid locking (might break parallel builds) ++ --enable-debug Turn on compiler debugging information (default=no) ++ ++Optional Packages: ++ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] ++ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) ++ --with-gnu-ld assume the C compiler uses GNU ld [default=no] ++ --with-pic try to use only PIC/non-PIC objects [default=use ++ both] ++ --with-tags[=TAGS] ++ include additional configurations [automatic] ++ --with-iscsid-version Compile against a certain version of iscsid (default="$ISCSID_VERSION_DEFAULT") ++ ++Some influential environment variables: ++ CC C compiler command ++ CFLAGS C compiler flags ++ LDFLAGS linker flags, e.g. -L if you have libraries in a ++ nonstandard directory ++ CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have ++ headers in a nonstandard directory ++ CPP C preprocessor ++ CXX C++ compiler command ++ CXXFLAGS C++ compiler flags ++ CXXCPP C++ preprocessor ++ F77 Fortran 77 compiler command ++ FFLAGS Fortran 77 compiler flags ++ ++Use these variables to override the choices made by `configure' or to help ++it to find libraries and programs with nonstandard names/locations. ++ ++Report bugs to . ++_ACEOF ++fi ++ ++if test "$ac_init_help" = "recursive"; then ++ # If there are subdirs, report their specific --help. ++ ac_popdir=`pwd` ++ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue ++ test -d $ac_dir || continue ++ ac_builddir=. ++ ++if test "$ac_dir" != .; then ++ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` ++ # A "../" for each directory in $ac_dir_suffix. ++ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` ++else ++ ac_dir_suffix= ac_top_builddir= ++fi ++ ++case $srcdir in ++ .) # No --srcdir option. We are building in place. ++ ac_srcdir=. ++ if test -z "$ac_top_builddir"; then ++ ac_top_srcdir=. ++ else ++ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` ++ fi ;; ++ [\\/]* | ?:[\\/]* ) # Absolute path. ++ ac_srcdir=$srcdir$ac_dir_suffix; ++ ac_top_srcdir=$srcdir ;; ++ *) # Relative path. ++ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ++ ac_top_srcdir=$ac_top_builddir$srcdir ;; ++esac ++ ++# Do not use `cd foo && pwd` to compute absolute paths, because ++# the directories may not exist. ++case `pwd` in ++.) ac_abs_builddir="$ac_dir";; ++*) ++ case "$ac_dir" in ++ .) ac_abs_builddir=`pwd`;; ++ [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; ++ *) ac_abs_builddir=`pwd`/"$ac_dir";; ++ esac;; ++esac ++case $ac_abs_builddir in ++.) ac_abs_top_builddir=${ac_top_builddir}.;; ++*) ++ case ${ac_top_builddir}. in ++ .) ac_abs_top_builddir=$ac_abs_builddir;; ++ [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; ++ *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; ++ esac;; ++esac ++case $ac_abs_builddir in ++.) ac_abs_srcdir=$ac_srcdir;; ++*) ++ case $ac_srcdir in ++ .) ac_abs_srcdir=$ac_abs_builddir;; ++ [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; ++ *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; ++ esac;; ++esac ++case $ac_abs_builddir in ++.) ac_abs_top_srcdir=$ac_top_srcdir;; ++*) ++ case $ac_top_srcdir in ++ .) ac_abs_top_srcdir=$ac_abs_builddir;; ++ [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; ++ *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; ++ esac;; ++esac ++ ++ cd $ac_dir ++ # Check for guested configure; otherwise get Cygnus style configure. ++ if test -f $ac_srcdir/configure.gnu; then ++ echo ++ $SHELL $ac_srcdir/configure.gnu --help=recursive ++ elif test -f $ac_srcdir/configure; then ++ echo ++ $SHELL $ac_srcdir/configure --help=recursive ++ elif test -f $ac_srcdir/configure.ac || ++ test -f $ac_srcdir/configure.in; then ++ echo ++ $ac_configure --help ++ else ++ echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 ++ fi ++ cd $ac_popdir ++ done ++fi ++ ++test -n "$ac_init_help" && exit 0 ++if $ac_init_version; then ++ cat <<\_ACEOF ++iscsiuio configure 0.7.2.1 ++generated by GNU Autoconf 2.59 ++ ++Copyright (C) 2003 Free Software Foundation, Inc. ++This configure script is free software; the Free Software Foundation ++gives unlimited permission to copy, distribute and modify it. ++_ACEOF ++ exit 0 ++fi ++exec 5>config.log ++cat >&5 <<_ACEOF ++This file contains any messages produced by compilers while ++running configure, to aid debugging if configure makes a mistake. ++ ++It was created by iscsiuio $as_me 0.7.2.1, which was ++generated by GNU Autoconf 2.59. Invocation command line was ++ ++ $ $0 $@ ++ ++_ACEOF ++{ ++cat <<_ASUNAME ++## --------- ## ++## Platform. ## ++## --------- ## ++ ++hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` ++uname -m = `(uname -m) 2>/dev/null || echo unknown` ++uname -r = `(uname -r) 2>/dev/null || echo unknown` ++uname -s = `(uname -s) 2>/dev/null || echo unknown` ++uname -v = `(uname -v) 2>/dev/null || echo unknown` ++ ++/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` ++/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` ++ ++/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` ++/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` ++/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` ++hostinfo = `(hostinfo) 2>/dev/null || echo unknown` ++/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` ++/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` ++/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` ++ ++_ASUNAME ++ ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ echo "PATH: $as_dir" ++done ++ ++} >&5 ++ ++cat >&5 <<_ACEOF ++ ++ ++## ----------- ## ++## Core tests. ## ++## ----------- ## ++ ++_ACEOF ++ ++ ++# Keep a trace of the command line. ++# Strip out --no-create and --no-recursion so they do not pile up. ++# Strip out --silent because we don't want to record it for future runs. ++# Also quote any args containing shell meta-characters. ++# Make two passes to allow for proper duplicate-argument suppression. ++ac_configure_args= ++ac_configure_args0= ++ac_configure_args1= ++ac_sep= ++ac_must_keep_next=false ++for ac_pass in 1 2 ++do ++ for ac_arg ++ do ++ case $ac_arg in ++ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; ++ -q | -quiet | --quiet | --quie | --qui | --qu | --q \ ++ | -silent | --silent | --silen | --sile | --sil) ++ continue ;; ++ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) ++ ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; ++ esac ++ case $ac_pass in ++ 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; ++ 2) ++ ac_configure_args1="$ac_configure_args1 '$ac_arg'" ++ if test $ac_must_keep_next = true; then ++ ac_must_keep_next=false # Got value, back to normal. ++ else ++ case $ac_arg in ++ *=* | --config-cache | -C | -disable-* | --disable-* \ ++ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ ++ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ ++ | -with-* | --with-* | -without-* | --without-* | --x) ++ case "$ac_configure_args0 " in ++ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; ++ esac ++ ;; ++ -* ) ac_must_keep_next=true ;; ++ esac ++ fi ++ ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" ++ # Get rid of the leading space. ++ ac_sep=" " ++ ;; ++ esac ++ done ++done ++$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } ++$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } ++ ++# When interrupted or exit'd, cleanup temporary files, and complete ++# config.log. We remove comments because anyway the quotes in there ++# would cause problems or look ugly. ++# WARNING: Be sure not to use single quotes in there, as some shells, ++# such as our DU 5.0 friend, will then `close' the trap. ++trap 'exit_status=$? ++ # Save into config.log some information that might help in debugging. ++ { ++ echo ++ ++ cat <<\_ASBOX ++## ---------------- ## ++## Cache variables. ## ++## ---------------- ## ++_ASBOX ++ echo ++ # The following way of writing the cache mishandles newlines in values, ++{ ++ (set) 2>&1 | ++ case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in ++ *ac_space=\ *) ++ sed -n \ ++ "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; ++ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" ++ ;; ++ *) ++ sed -n \ ++ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" ++ ;; ++ esac; ++} ++ echo ++ ++ cat <<\_ASBOX ++## ----------------- ## ++## Output variables. ## ++## ----------------- ## ++_ASBOX ++ echo ++ for ac_var in $ac_subst_vars ++ do ++ eval ac_val=$`echo $ac_var` ++ echo "$ac_var='"'"'$ac_val'"'"'" ++ done | sort ++ echo ++ ++ if test -n "$ac_subst_files"; then ++ cat <<\_ASBOX ++## ------------- ## ++## Output files. ## ++## ------------- ## ++_ASBOX ++ echo ++ for ac_var in $ac_subst_files ++ do ++ eval ac_val=$`echo $ac_var` ++ echo "$ac_var='"'"'$ac_val'"'"'" ++ done | sort ++ echo ++ fi ++ ++ if test -s confdefs.h; then ++ cat <<\_ASBOX ++## ----------- ## ++## confdefs.h. ## ++## ----------- ## ++_ASBOX ++ echo ++ sed "/^$/d" confdefs.h | sort ++ echo ++ fi ++ test "$ac_signal" != 0 && ++ echo "$as_me: caught signal $ac_signal" ++ echo "$as_me: exit $exit_status" ++ } >&5 ++ rm -f core *.core && ++ rm -rf conftest* confdefs* conf$$* $ac_clean_files && ++ exit $exit_status ++ ' 0 ++for ac_signal in 1 2 13 15; do ++ trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal ++done ++ac_signal=0 ++ ++# confdefs.h avoids OS command line length limits that DEFS can exceed. ++rm -rf conftest* confdefs.h ++# AIX cpp loses on an empty file, so make sure it contains at least a newline. ++echo >confdefs.h ++ ++# Predefined preprocessor variables. ++ ++cat >>confdefs.h <<_ACEOF ++#define PACKAGE_NAME "$PACKAGE_NAME" ++_ACEOF ++ ++ ++cat >>confdefs.h <<_ACEOF ++#define PACKAGE_TARNAME "$PACKAGE_TARNAME" ++_ACEOF ++ ++ ++cat >>confdefs.h <<_ACEOF ++#define PACKAGE_VERSION "$PACKAGE_VERSION" ++_ACEOF ++ ++ ++cat >>confdefs.h <<_ACEOF ++#define PACKAGE_STRING "$PACKAGE_STRING" ++_ACEOF ++ ++ ++cat >>confdefs.h <<_ACEOF ++#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" ++_ACEOF ++ ++ ++# Let the site file select an alternate cache file if it wants to. ++# Prefer explicitly selected file to automatically selected ones. ++if test -z "$CONFIG_SITE"; then ++ if test "x$prefix" != xNONE; then ++ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" ++ else ++ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" ++ fi ++fi ++for ac_site_file in $CONFIG_SITE; do ++ if test -r "$ac_site_file"; then ++ { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 ++echo "$as_me: loading site script $ac_site_file" >&6;} ++ sed 's/^/| /' "$ac_site_file" >&5 ++ . "$ac_site_file" ++ fi ++done ++ ++if test -r "$cache_file"; then ++ # Some versions of bash will fail to source /dev/null (special ++ # files actually), so we avoid doing that. ++ if test -f "$cache_file"; then ++ { echo "$as_me:$LINENO: loading cache $cache_file" >&5 ++echo "$as_me: loading cache $cache_file" >&6;} ++ case $cache_file in ++ [\\/]* | ?:[\\/]* ) . $cache_file;; ++ *) . ./$cache_file;; ++ esac ++ fi ++else ++ { echo "$as_me:$LINENO: creating cache $cache_file" >&5 ++echo "$as_me: creating cache $cache_file" >&6;} ++ >$cache_file ++fi ++ ++# Check that the precious variables saved in the cache have kept the same ++# value. ++ac_cache_corrupted=false ++for ac_var in `(set) 2>&1 | ++ sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do ++ eval ac_old_set=\$ac_cv_env_${ac_var}_set ++ eval ac_new_set=\$ac_env_${ac_var}_set ++ eval ac_old_val="\$ac_cv_env_${ac_var}_value" ++ eval ac_new_val="\$ac_env_${ac_var}_value" ++ case $ac_old_set,$ac_new_set in ++ set,) ++ { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 ++echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ++ ac_cache_corrupted=: ;; ++ ,set) ++ { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 ++echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ++ ac_cache_corrupted=: ;; ++ ,);; ++ *) ++ if test "x$ac_old_val" != "x$ac_new_val"; then ++ { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 ++echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ++ { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 ++echo "$as_me: former value: $ac_old_val" >&2;} ++ { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 ++echo "$as_me: current value: $ac_new_val" >&2;} ++ ac_cache_corrupted=: ++ fi;; ++ esac ++ # Pass precious variables to config.status. ++ if test "$ac_new_set" = set; then ++ case $ac_new_val in ++ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) ++ ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; ++ *) ac_arg=$ac_var=$ac_new_val ;; ++ esac ++ case " $ac_configure_args " in ++ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. ++ *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; ++ esac ++ fi ++done ++if $ac_cache_corrupted; then ++ { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 ++echo "$as_me: error: changes in the environment can compromise the build" >&2;} ++ { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 ++echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} ++ { (exit 1); exit 1; }; } ++fi ++ ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++am__api_version="1.9" ++ac_aux_dir= ++for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do ++ if test -f $ac_dir/install-sh; then ++ ac_aux_dir=$ac_dir ++ ac_install_sh="$ac_aux_dir/install-sh -c" ++ break ++ elif test -f $ac_dir/install.sh; then ++ ac_aux_dir=$ac_dir ++ ac_install_sh="$ac_aux_dir/install.sh -c" ++ break ++ elif test -f $ac_dir/shtool; then ++ ac_aux_dir=$ac_dir ++ ac_install_sh="$ac_aux_dir/shtool install -c" ++ break ++ fi ++done ++if test -z "$ac_aux_dir"; then ++ { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 ++echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} ++ { (exit 1); exit 1; }; } ++fi ++ac_config_guess="$SHELL $ac_aux_dir/config.guess" ++ac_config_sub="$SHELL $ac_aux_dir/config.sub" ++ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. ++ ++# Find a good install program. We prefer a C program (faster), ++# so one script is as good as another. But avoid the broken or ++# incompatible versions: ++# SysV /etc/install, /usr/sbin/install ++# SunOS /usr/etc/install ++# IRIX /sbin/install ++# AIX /bin/install ++# AmigaOS /C/install, which installs bootblocks on floppy discs ++# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag ++# AFS /usr/afsws/bin/install, which mishandles nonexistent args ++# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" ++# OS/2's system install, which has a completely different semantic ++# ./install, which can be erroneously created by make from ./install.sh. ++echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 ++echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 ++if test -z "$INSTALL"; then ++if test "${ac_cv_path_install+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ # Account for people who put trailing slashes in PATH elements. ++case $as_dir/ in ++ ./ | .// | /cC/* | \ ++ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ++ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ ++ /usr/ucb/* ) ;; ++ *) ++ # OSF1 and SCO ODT 3.0 have their own names for install. ++ # Don't use installbsd from OSF since it installs stuff as root ++ # by default. ++ for ac_prog in ginstall scoinst install; do ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then ++ if test $ac_prog = install && ++ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then ++ # AIX install. It has an incompatible calling convention. ++ : ++ elif test $ac_prog = install && ++ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then ++ # program-specific install script used by HP pwplus--don't use. ++ : ++ else ++ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" ++ break 3 ++ fi ++ fi ++ done ++ done ++ ;; ++esac ++done ++ ++ ++fi ++ if test "${ac_cv_path_install+set}" = set; then ++ INSTALL=$ac_cv_path_install ++ else ++ # As a last resort, use the slow shell script. We don't cache a ++ # path for INSTALL within a source directory, because that will ++ # break other packages using the cache if that directory is ++ # removed, or if the path is relative. ++ INSTALL=$ac_install_sh ++ fi ++fi ++echo "$as_me:$LINENO: result: $INSTALL" >&5 ++echo "${ECHO_T}$INSTALL" >&6 ++ ++# Use test -z because SunOS4 sh mishandles braces in ${var-val}. ++# It thinks the first close brace ends the variable substitution. ++test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' ++ ++test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' ++ ++test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' ++ ++echo "$as_me:$LINENO: checking whether build environment is sane" >&5 ++echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6 ++# Just in case ++sleep 1 ++echo timestamp > conftest.file ++# Do `set' in a subshell so we don't clobber the current shell's ++# arguments. Must try -L first in case configure is actually a ++# symlink; some systems play weird games with the mod time of symlinks ++# (eg FreeBSD returns the mod time of the symlink's containing ++# directory). ++if ( ++ set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` ++ if test "$*" = "X"; then ++ # -L didn't work. ++ set X `ls -t $srcdir/configure conftest.file` ++ fi ++ rm -f conftest.file ++ if test "$*" != "X $srcdir/configure conftest.file" \ ++ && test "$*" != "X conftest.file $srcdir/configure"; then ++ ++ # If neither matched, then we have a broken ls. This can happen ++ # if, for instance, CONFIG_SHELL is bash and it inherits a ++ # broken ls alias from the environment. This has actually ++ # happened. Such a system could not be considered "sane". ++ { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken ++alias in your environment" >&5 ++echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken ++alias in your environment" >&2;} ++ { (exit 1); exit 1; }; } ++ fi ++ ++ test "$2" = conftest.file ++ ) ++then ++ # Ok. ++ : ++else ++ { { echo "$as_me:$LINENO: error: newly created file is older than distributed files! ++Check your system clock" >&5 ++echo "$as_me: error: newly created file is older than distributed files! ++Check your system clock" >&2;} ++ { (exit 1); exit 1; }; } ++fi ++echo "$as_me:$LINENO: result: yes" >&5 ++echo "${ECHO_T}yes" >&6 ++test "$program_prefix" != NONE && ++ program_transform_name="s,^,$program_prefix,;$program_transform_name" ++# Use a double $ so make ignores it. ++test "$program_suffix" != NONE && ++ program_transform_name="s,\$,$program_suffix,;$program_transform_name" ++# Double any \ or $. echo might interpret backslashes. ++# By default was `s,x,x', remove it if useless. ++cat <<\_ACEOF >conftest.sed ++s/[\\$]/&&/g;s/;s,x,x,$// ++_ACEOF ++program_transform_name=`echo $program_transform_name | sed -f conftest.sed` ++rm conftest.sed ++ ++# expand $ac_aux_dir to an absolute path ++am_aux_dir=`cd $ac_aux_dir && pwd` ++ ++test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" ++# Use eval to expand $SHELL ++if eval "$MISSING --run true"; then ++ am_missing_run="$MISSING --run " ++else ++ am_missing_run= ++ { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 ++echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} ++fi ++ ++if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then ++ # We used to keeping the `.' as first argument, in order to ++ # allow $(mkdir_p) to be used without argument. As in ++ # $(mkdir_p) $(somedir) ++ # where $(somedir) is conditionally defined. However this is wrong ++ # for two reasons: ++ # 1. if the package is installed by a user who cannot write `.' ++ # make install will fail, ++ # 2. the above comment should most certainly read ++ # $(mkdir_p) $(DESTDIR)$(somedir) ++ # so it does not work when $(somedir) is undefined and ++ # $(DESTDIR) is not. ++ # To support the latter case, we have to write ++ # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), ++ # so the `.' trick is pointless. ++ mkdir_p='mkdir -p --' ++else ++ # On NextStep and OpenStep, the `mkdir' command does not ++ # recognize any option. It will interpret all options as ++ # directories to create, and then abort because `.' already ++ # exists. ++ for d in ./-p ./--version; ++ do ++ test -d $d && rmdir $d ++ done ++ # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. ++ if test -f "$ac_aux_dir/mkinstalldirs"; then ++ mkdir_p='$(mkinstalldirs)' ++ else ++ mkdir_p='$(install_sh) -d' ++ fi ++fi ++ ++for ac_prog in gawk mawk nawk awk ++do ++ # Extract the first word of "$ac_prog", so it can be a program name with args. ++set dummy $ac_prog; ac_word=$2 ++echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 ++if test "${ac_cv_prog_AWK+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -n "$AWK"; then ++ ac_cv_prog_AWK="$AWK" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_AWK="$ac_prog" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++ ++fi ++fi ++AWK=$ac_cv_prog_AWK ++if test -n "$AWK"; then ++ echo "$as_me:$LINENO: result: $AWK" >&5 ++echo "${ECHO_T}$AWK" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++ test -n "$AWK" && break ++done ++ ++echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 ++echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6 ++set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'` ++if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ cat >conftest.make <<\_ACEOF ++all: ++ @echo 'ac_maketemp="$(MAKE)"' ++_ACEOF ++# GNU make sometimes prints "make[1]: Entering...", which would confuse us. ++eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=` ++if test -n "$ac_maketemp"; then ++ eval ac_cv_prog_make_${ac_make}_set=yes ++else ++ eval ac_cv_prog_make_${ac_make}_set=no ++fi ++rm -f conftest.make ++fi ++if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then ++ echo "$as_me:$LINENO: result: yes" >&5 ++echo "${ECHO_T}yes" >&6 ++ SET_MAKE= ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++ SET_MAKE="MAKE=${MAKE-make}" ++fi ++ ++rm -rf .tst 2>/dev/null ++mkdir .tst 2>/dev/null ++if test -d .tst; then ++ am__leading_dot=. ++else ++ am__leading_dot=_ ++fi ++rmdir .tst 2>/dev/null ++ ++# test to see if srcdir already configured ++if test "`cd $srcdir && pwd`" != "`pwd`" && ++ test -f $srcdir/config.status; then ++ { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 ++echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} ++ { (exit 1); exit 1; }; } ++fi ++ ++# test whether we have cygpath ++if test -z "$CYGPATH_W"; then ++ if (cygpath --version) >/dev/null 2>/dev/null; then ++ CYGPATH_W='cygpath -w' ++ else ++ CYGPATH_W=echo ++ fi ++fi ++ ++ ++# Define the identity of the package. ++ PACKAGE=$PACKAGE ++ VERSION=$VERSION ++ ++ ++cat >>confdefs.h <<_ACEOF ++#define PACKAGE "$PACKAGE" ++_ACEOF ++ ++ ++cat >>confdefs.h <<_ACEOF ++#define VERSION "$VERSION" ++_ACEOF ++ ++# Some tools Automake needs. ++ ++ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} ++ ++ ++AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} ++ ++ ++AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} ++ ++ ++AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} ++ ++ ++MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} ++ ++install_sh=${install_sh-"$am_aux_dir/install-sh"} ++ ++# Installed binaries are usually stripped using `strip' when the user ++# run `make install-strip'. However `strip' might not be the right ++# tool to use in cross-compilation environments, therefore Automake ++# will honor the `STRIP' environment variable to overrule this program. ++if test "$cross_compiling" != no; then ++ if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. ++set dummy ${ac_tool_prefix}strip; ac_word=$2 ++echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 ++if test "${ac_cv_prog_STRIP+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -n "$STRIP"; then ++ ac_cv_prog_STRIP="$STRIP" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_STRIP="${ac_tool_prefix}strip" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++ ++fi ++fi ++STRIP=$ac_cv_prog_STRIP ++if test -n "$STRIP"; then ++ echo "$as_me:$LINENO: result: $STRIP" >&5 ++echo "${ECHO_T}$STRIP" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++fi ++if test -z "$ac_cv_prog_STRIP"; then ++ ac_ct_STRIP=$STRIP ++ # Extract the first word of "strip", so it can be a program name with args. ++set dummy strip; ac_word=$2 ++echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 ++if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -n "$ac_ct_STRIP"; then ++ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_ac_ct_STRIP="strip" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++ ++ test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":" ++fi ++fi ++ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP ++if test -n "$ac_ct_STRIP"; then ++ echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 ++echo "${ECHO_T}$ac_ct_STRIP" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++ STRIP=$ac_ct_STRIP ++else ++ STRIP="$ac_cv_prog_STRIP" ++fi ++ ++fi ++INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" ++ ++# We need awk for the "check" target. The system "awk" is bad on ++# some platforms. ++# Always define AMTAR for backward compatibility. ++ ++AMTAR=${AMTAR-"${am_missing_run}tar"} ++ ++am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' ++ ++ ++ ++ ++ ++ ac_config_headers="$ac_config_headers config.h" ++ ++for ac_prog in bash ++do ++ # Extract the first word of "$ac_prog", so it can be a program name with args. ++set dummy $ac_prog; ac_word=$2 ++echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 ++if test "${ac_cv_path_BASH+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ case $BASH in ++ [\\/]* | ?:[\\/]*) ++ ac_cv_path_BASH="$BASH" # Let the user override the test with a path. ++ ;; ++ *) ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_path_BASH="$as_dir/$ac_word$ac_exec_ext" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++ ++ ;; ++esac ++fi ++BASH=$ac_cv_path_BASH ++ ++if test -n "$BASH"; then ++ echo "$as_me:$LINENO: result: $BASH" >&5 ++echo "${ECHO_T}$BASH" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++ test -n "$BASH" && break ++done ++ ++ ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. ++set dummy ${ac_tool_prefix}gcc; ac_word=$2 ++echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 ++if test "${ac_cv_prog_CC+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -n "$CC"; then ++ ac_cv_prog_CC="$CC" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_CC="${ac_tool_prefix}gcc" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++ ++fi ++fi ++CC=$ac_cv_prog_CC ++if test -n "$CC"; then ++ echo "$as_me:$LINENO: result: $CC" >&5 ++echo "${ECHO_T}$CC" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++fi ++if test -z "$ac_cv_prog_CC"; then ++ ac_ct_CC=$CC ++ # Extract the first word of "gcc", so it can be a program name with args. ++set dummy gcc; ac_word=$2 ++echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 ++if test "${ac_cv_prog_ac_ct_CC+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -n "$ac_ct_CC"; then ++ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_ac_ct_CC="gcc" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++ ++fi ++fi ++ac_ct_CC=$ac_cv_prog_ac_ct_CC ++if test -n "$ac_ct_CC"; then ++ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 ++echo "${ECHO_T}$ac_ct_CC" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++ CC=$ac_ct_CC ++else ++ CC="$ac_cv_prog_CC" ++fi ++ ++if test -z "$CC"; then ++ if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. ++set dummy ${ac_tool_prefix}cc; ac_word=$2 ++echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 ++if test "${ac_cv_prog_CC+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -n "$CC"; then ++ ac_cv_prog_CC="$CC" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_CC="${ac_tool_prefix}cc" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++ ++fi ++fi ++CC=$ac_cv_prog_CC ++if test -n "$CC"; then ++ echo "$as_me:$LINENO: result: $CC" >&5 ++echo "${ECHO_T}$CC" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++fi ++if test -z "$ac_cv_prog_CC"; then ++ ac_ct_CC=$CC ++ # Extract the first word of "cc", so it can be a program name with args. ++set dummy cc; ac_word=$2 ++echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 ++if test "${ac_cv_prog_ac_ct_CC+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -n "$ac_ct_CC"; then ++ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_ac_ct_CC="cc" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++ ++fi ++fi ++ac_ct_CC=$ac_cv_prog_ac_ct_CC ++if test -n "$ac_ct_CC"; then ++ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 ++echo "${ECHO_T}$ac_ct_CC" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++ CC=$ac_ct_CC ++else ++ CC="$ac_cv_prog_CC" ++fi ++ ++fi ++if test -z "$CC"; then ++ # Extract the first word of "cc", so it can be a program name with args. ++set dummy cc; ac_word=$2 ++echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 ++if test "${ac_cv_prog_CC+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -n "$CC"; then ++ ac_cv_prog_CC="$CC" # Let the user override the test. ++else ++ ac_prog_rejected=no ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ++ ac_prog_rejected=yes ++ continue ++ fi ++ ac_cv_prog_CC="cc" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++ ++if test $ac_prog_rejected = yes; then ++ # We found a bogon in the path, so make sure we never use it. ++ set dummy $ac_cv_prog_CC ++ shift ++ if test $# != 0; then ++ # We chose a different compiler from the bogus one. ++ # However, it has the same basename, so the bogon will be chosen ++ # first if we set CC to just the basename; use the full file name. ++ shift ++ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" ++ fi ++fi ++fi ++fi ++CC=$ac_cv_prog_CC ++if test -n "$CC"; then ++ echo "$as_me:$LINENO: result: $CC" >&5 ++echo "${ECHO_T}$CC" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++fi ++if test -z "$CC"; then ++ if test -n "$ac_tool_prefix"; then ++ for ac_prog in cl ++ do ++ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. ++set dummy $ac_tool_prefix$ac_prog; ac_word=$2 ++echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 ++if test "${ac_cv_prog_CC+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -n "$CC"; then ++ ac_cv_prog_CC="$CC" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_CC="$ac_tool_prefix$ac_prog" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++ ++fi ++fi ++CC=$ac_cv_prog_CC ++if test -n "$CC"; then ++ echo "$as_me:$LINENO: result: $CC" >&5 ++echo "${ECHO_T}$CC" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++ test -n "$CC" && break ++ done ++fi ++if test -z "$CC"; then ++ ac_ct_CC=$CC ++ for ac_prog in cl ++do ++ # Extract the first word of "$ac_prog", so it can be a program name with args. ++set dummy $ac_prog; ac_word=$2 ++echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 ++if test "${ac_cv_prog_ac_ct_CC+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -n "$ac_ct_CC"; then ++ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_ac_ct_CC="$ac_prog" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++ ++fi ++fi ++ac_ct_CC=$ac_cv_prog_ac_ct_CC ++if test -n "$ac_ct_CC"; then ++ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 ++echo "${ECHO_T}$ac_ct_CC" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++ test -n "$ac_ct_CC" && break ++done ++ ++ CC=$ac_ct_CC ++fi ++ ++fi ++ ++ ++test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH ++See \`config.log' for more details." >&5 ++echo "$as_me: error: no acceptable C compiler found in \$PATH ++See \`config.log' for more details." >&2;} ++ { (exit 1); exit 1; }; } ++ ++# Provide some information about the compiler. ++echo "$as_me:$LINENO:" \ ++ "checking for C compiler version" >&5 ++ac_compiler=`set X $ac_compile; echo $2` ++{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 ++ (eval $ac_compiler --version &5) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } ++{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 ++ (eval $ac_compiler -v &5) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } ++{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 ++ (eval $ac_compiler -V &5) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } ++ ++cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++ac_clean_files_save=$ac_clean_files ++ac_clean_files="$ac_clean_files a.out a.exe b.out" ++# Try to create an executable without -o first, disregard a.out. ++# It will help us diagnose broken compilers, and finding out an intuition ++# of exeext. ++echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 ++echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6 ++ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` ++if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 ++ (eval $ac_link_default) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; then ++ # Find the output, starting from the most likely. This scheme is ++# not robust to junk in `.', hence go to wildcards (a.*) only as a last ++# resort. ++ ++# Be careful to initialize this variable, since it used to be cached. ++# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. ++ac_cv_exeext= ++# b.out is created by i960 compilers. ++for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out ++do ++ test -f "$ac_file" || continue ++ case $ac_file in ++ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ++ ;; ++ conftest.$ac_ext ) ++ # This is the source file. ++ ;; ++ [ab].out ) ++ # We found the default executable, but exeext='' is most ++ # certainly right. ++ break;; ++ *.* ) ++ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` ++ # FIXME: I believe we export ac_cv_exeext for Libtool, ++ # but it would be cool to find out if it's true. Does anybody ++ # maintain Libtool? --akim. ++ export ac_cv_exeext ++ break;; ++ * ) ++ break;; ++ esac ++done ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++{ { echo "$as_me:$LINENO: error: C compiler cannot create executables ++See \`config.log' for more details." >&5 ++echo "$as_me: error: C compiler cannot create executables ++See \`config.log' for more details." >&2;} ++ { (exit 77); exit 77; }; } ++fi ++ ++ac_exeext=$ac_cv_exeext ++echo "$as_me:$LINENO: result: $ac_file" >&5 ++echo "${ECHO_T}$ac_file" >&6 ++ ++# Check the compiler produces executables we can run. If not, either ++# the compiler is broken, or we cross compile. ++echo "$as_me:$LINENO: checking whether the C compiler works" >&5 ++echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 ++# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 ++# If not cross compiling, check that we can run a simple program. ++if test "$cross_compiling" != yes; then ++ if { ac_try='./$ac_file' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ cross_compiling=no ++ else ++ if test "$cross_compiling" = maybe; then ++ cross_compiling=yes ++ else ++ { { echo "$as_me:$LINENO: error: cannot run C compiled programs. ++If you meant to cross compile, use \`--host'. ++See \`config.log' for more details." >&5 ++echo "$as_me: error: cannot run C compiled programs. ++If you meant to cross compile, use \`--host'. ++See \`config.log' for more details." >&2;} ++ { (exit 1); exit 1; }; } ++ fi ++ fi ++fi ++echo "$as_me:$LINENO: result: yes" >&5 ++echo "${ECHO_T}yes" >&6 ++ ++rm -f a.out a.exe conftest$ac_cv_exeext b.out ++ac_clean_files=$ac_clean_files_save ++# Check the compiler produces executables we can run. If not, either ++# the compiler is broken, or we cross compile. ++echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 ++echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 ++echo "$as_me:$LINENO: result: $cross_compiling" >&5 ++echo "${ECHO_T}$cross_compiling" >&6 ++ ++echo "$as_me:$LINENO: checking for suffix of executables" >&5 ++echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 ++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 ++ (eval $ac_link) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; then ++ # If both `conftest.exe' and `conftest' are `present' (well, observable) ++# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will ++# work properly (i.e., refer to `conftest.exe'), while it won't with ++# `rm'. ++for ac_file in conftest.exe conftest conftest.*; do ++ test -f "$ac_file" || continue ++ case $ac_file in ++ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; ++ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` ++ export ac_cv_exeext ++ break;; ++ * ) break;; ++ esac ++done ++else ++ { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link ++See \`config.log' for more details." >&5 ++echo "$as_me: error: cannot compute suffix of executables: cannot compile and link ++See \`config.log' for more details." >&2;} ++ { (exit 1); exit 1; }; } ++fi ++ ++rm -f conftest$ac_cv_exeext ++echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 ++echo "${ECHO_T}$ac_cv_exeext" >&6 ++ ++rm -f conftest.$ac_ext ++EXEEXT=$ac_cv_exeext ++ac_exeext=$EXEEXT ++echo "$as_me:$LINENO: checking for suffix of object files" >&5 ++echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 ++if test "${ac_cv_objext+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.o conftest.obj ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; then ++ for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do ++ case $ac_file in ++ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; ++ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` ++ break;; ++ esac ++done ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile ++See \`config.log' for more details." >&5 ++echo "$as_me: error: cannot compute suffix of object files: cannot compile ++See \`config.log' for more details." >&2;} ++ { (exit 1); exit 1; }; } ++fi ++ ++rm -f conftest.$ac_cv_objext conftest.$ac_ext ++fi ++echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 ++echo "${ECHO_T}$ac_cv_objext" >&6 ++OBJEXT=$ac_cv_objext ++ac_objext=$OBJEXT ++echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 ++echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 ++if test "${ac_cv_c_compiler_gnu+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++#ifndef __GNUC__ ++ choke me ++#endif ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_compiler_gnu=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_compiler_gnu=no ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++ac_cv_c_compiler_gnu=$ac_compiler_gnu ++ ++fi ++echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 ++echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 ++GCC=`test $ac_compiler_gnu = yes && echo yes` ++ac_test_CFLAGS=${CFLAGS+set} ++ac_save_CFLAGS=$CFLAGS ++CFLAGS="-g" ++echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 ++echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 ++if test "${ac_cv_prog_cc_g+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_prog_cc_g=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_cv_prog_cc_g=no ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 ++echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 ++if test "$ac_test_CFLAGS" = set; then ++ CFLAGS=$ac_save_CFLAGS ++elif test $ac_cv_prog_cc_g = yes; then ++ if test "$GCC" = yes; then ++ CFLAGS="-g -O2" ++ else ++ CFLAGS="-g" ++ fi ++else ++ if test "$GCC" = yes; then ++ CFLAGS="-O2" ++ else ++ CFLAGS= ++ fi ++fi ++echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 ++echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 ++if test "${ac_cv_prog_cc_stdc+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ ac_cv_prog_cc_stdc=no ++ac_save_CC=$CC ++cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++#include ++#include ++#include ++#include ++/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ ++struct buf { int x; }; ++FILE * (*rcsopen) (struct buf *, struct stat *, int); ++static char *e (p, i) ++ char **p; ++ int i; ++{ ++ return p[i]; ++} ++static char *f (char * (*g) (char **, int), char **p, ...) ++{ ++ char *s; ++ va_list v; ++ va_start (v,p); ++ s = g (p, va_arg (v,int)); ++ va_end (v); ++ return s; ++} ++ ++/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has ++ function prototypes and stuff, but not '\xHH' hex character constants. ++ These don't provoke an error unfortunately, instead are silently treated ++ as 'x'. The following induces an error, until -std1 is added to get ++ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an ++ array size at least. It's necessary to write '\x00'==0 to get something ++ that's true only with -std1. */ ++int osf4_cc_array ['\x00' == 0 ? 1 : -1]; ++ ++int test (int i, double x); ++struct s1 {int (*f) (int a);}; ++struct s2 {int (*f) (double a);}; ++int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); ++int argc; ++char **argv; ++int ++main () ++{ ++return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ++ ; ++ return 0; ++} ++_ACEOF ++# Don't try gcc -ansi; that turns off useful extensions and ++# breaks some systems' header files. ++# AIX -qlanglvl=ansi ++# Ultrix and OSF/1 -std1 ++# HP-UX 10.20 and later -Ae ++# HP-UX older versions -Aa -D_HPUX_SOURCE ++# SVR4 -Xc -D__EXTENSIONS__ ++for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" ++do ++ CC="$ac_save_CC $ac_arg" ++ rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_prog_cc_stdc=$ac_arg ++break ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++fi ++rm -f conftest.err conftest.$ac_objext ++done ++rm -f conftest.$ac_ext conftest.$ac_objext ++CC=$ac_save_CC ++ ++fi ++ ++case "x$ac_cv_prog_cc_stdc" in ++ x|xno) ++ echo "$as_me:$LINENO: result: none needed" >&5 ++echo "${ECHO_T}none needed" >&6 ;; ++ *) ++ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 ++echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 ++ CC="$CC $ac_cv_prog_cc_stdc" ;; ++esac ++ ++# Some people use a C++ compiler to compile C. Since we use `exit', ++# in C++ we need to declare it. In case someone uses the same compiler ++# for both compiling C and C++ we need to have the C++ compiler decide ++# the declaration of exit, since it's the most demanding environment. ++cat >conftest.$ac_ext <<_ACEOF ++#ifndef __cplusplus ++ choke me ++#endif ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ for ac_declaration in \ ++ '' \ ++ 'extern "C" void std::exit (int) throw (); using std::exit;' \ ++ 'extern "C" void std::exit (int); using std::exit;' \ ++ 'extern "C" void exit (int) throw ();' \ ++ 'extern "C" void exit (int);' \ ++ 'void exit (int);' ++do ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_declaration ++#include ++int ++main () ++{ ++exit (42); ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ : ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++continue ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_declaration ++int ++main () ++{ ++exit (42); ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ break ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++done ++rm -f conftest* ++if test -n "$ac_declaration"; then ++ echo '#ifdef __cplusplus' >>confdefs.h ++ echo $ac_declaration >>confdefs.h ++ echo '#endif' >>confdefs.h ++fi ++ ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++DEPDIR="${am__leading_dot}deps" ++ ++ ac_config_commands="$ac_config_commands depfiles" ++ ++ ++am_make=${MAKE-make} ++cat > confinc << 'END' ++am__doit: ++ @echo done ++.PHONY: am__doit ++END ++# If we don't find an include directive, just comment out the code. ++echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 ++echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6 ++am__include="#" ++am__quote= ++_am_result=none ++# First try GNU make style include. ++echo "include confinc" > confmf ++# We grep out `Entering directory' and `Leaving directory' ++# messages which can occur if `w' ends up in MAKEFLAGS. ++# In particular we don't look at `^make:' because GNU make might ++# be invoked under some other name (usually "gmake"), in which ++# case it prints its new name instead of `make'. ++if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then ++ am__include=include ++ am__quote= ++ _am_result=GNU ++fi ++# Now try BSD make style include. ++if test "$am__include" = "#"; then ++ echo '.include "confinc"' > confmf ++ if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then ++ am__include=.include ++ am__quote="\"" ++ _am_result=BSD ++ fi ++fi ++ ++ ++echo "$as_me:$LINENO: result: $_am_result" >&5 ++echo "${ECHO_T}$_am_result" >&6 ++rm -f confinc confmf ++ ++# Check whether --enable-dependency-tracking or --disable-dependency-tracking was given. ++if test "${enable_dependency_tracking+set}" = set; then ++ enableval="$enable_dependency_tracking" ++ ++fi; ++if test "x$enable_dependency_tracking" != xno; then ++ am_depcomp="$ac_aux_dir/depcomp" ++ AMDEPBACKSLASH='\' ++fi ++ ++ ++if test "x$enable_dependency_tracking" != xno; then ++ AMDEP_TRUE= ++ AMDEP_FALSE='#' ++else ++ AMDEP_TRUE='#' ++ AMDEP_FALSE= ++fi ++ ++ ++ ++ ++depcc="$CC" am_compiler_list= ++ ++echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 ++echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6 ++if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then ++ # We make a subdir and do the tests there. Otherwise we can end up ++ # making bogus files that we don't know about and never remove. For ++ # instance it was reported that on HP-UX the gcc test will end up ++ # making a dummy file named `D' -- because `-MD' means `put the output ++ # in D'. ++ mkdir conftest.dir ++ # Copy depcomp to subdir because otherwise we won't find it if we're ++ # using a relative directory. ++ cp "$am_depcomp" conftest.dir ++ cd conftest.dir ++ # We will build objects and dependencies in a subdirectory because ++ # it helps to detect inapplicable dependency modes. For instance ++ # both Tru64's cc and ICC support -MD to output dependencies as a ++ # side effect of compilation, but ICC will put the dependencies in ++ # the current directory while Tru64 will put them in the object ++ # directory. ++ mkdir sub ++ ++ am_cv_CC_dependencies_compiler_type=none ++ if test "$am_compiler_list" = ""; then ++ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` ++ fi ++ for depmode in $am_compiler_list; do ++ # Setup a source with many dependencies, because some compilers ++ # like to wrap large dependency lists on column 80 (with \), and ++ # we should not choose a depcomp mode which is confused by this. ++ # ++ # We need to recreate these files for each test, as the compiler may ++ # overwrite some of them when testing with obscure command lines. ++ # This happens at least with the AIX C compiler. ++ : > sub/conftest.c ++ for i in 1 2 3 4 5 6; do ++ echo '#include "conftst'$i'.h"' >> sub/conftest.c ++ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with ++ # Solaris 8's {/usr,}/bin/sh. ++ touch sub/conftst$i.h ++ done ++ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf ++ ++ case $depmode in ++ nosideeffect) ++ # after this tag, mechanisms are not by side-effect, so they'll ++ # only be used when explicitly requested ++ if test "x$enable_dependency_tracking" = xyes; then ++ continue ++ else ++ break ++ fi ++ ;; ++ none) break ;; ++ esac ++ # We check with `-c' and `-o' for the sake of the "dashmstdout" ++ # mode. It turns out that the SunPro C++ compiler does not properly ++ # handle `-M -o', and we need to detect this. ++ if depmode=$depmode \ ++ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ ++ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ ++ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ ++ >/dev/null 2>conftest.err && ++ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && ++ grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && ++ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then ++ # icc doesn't choke on unknown options, it will just issue warnings ++ # or remarks (even with -Werror). So we grep stderr for any message ++ # that says an option was ignored or not supported. ++ # When given -MP, icc 7.0 and 7.1 complain thusly: ++ # icc: Command line warning: ignoring option '-M'; no argument required ++ # The diagnosis changed in icc 8.0: ++ # icc: Command line remark: option '-MP' not supported ++ if (grep 'ignoring option' conftest.err || ++ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else ++ am_cv_CC_dependencies_compiler_type=$depmode ++ break ++ fi ++ fi ++ done ++ ++ cd .. ++ rm -rf conftest.dir ++else ++ am_cv_CC_dependencies_compiler_type=none ++fi ++ ++fi ++echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 ++echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6 ++CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type ++ ++ ++ ++if ++ test "x$enable_dependency_tracking" != xno \ ++ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then ++ am__fastdepCC_TRUE= ++ am__fastdepCC_FALSE='#' ++else ++ am__fastdepCC_TRUE='#' ++ am__fastdepCC_FALSE= ++fi ++ ++ ++if test "x$CC" != xcc; then ++ echo "$as_me:$LINENO: checking whether $CC and cc understand -c and -o together" >&5 ++echo $ECHO_N "checking whether $CC and cc understand -c and -o together... $ECHO_C" >&6 ++else ++ echo "$as_me:$LINENO: checking whether cc understands -c and -o together" >&5 ++echo $ECHO_N "checking whether cc understands -c and -o together... $ECHO_C" >&6 ++fi ++set dummy $CC; ac_cc=`echo $2 | ++ sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` ++if eval "test \"\${ac_cv_prog_cc_${ac_cc}_c_o+set}\" = set"; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++# Make sure it works both with $CC and with simple cc. ++# We do the test twice because some compilers refuse to overwrite an ++# existing .o file with -o, though they will create one. ++ac_try='$CC -c conftest.$ac_ext -o conftest.$ac_objext >&5' ++if { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ test -f conftest.$ac_objext && { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; ++then ++ eval ac_cv_prog_cc_${ac_cc}_c_o=yes ++ if test "x$CC" != xcc; then ++ # Test first that cc exists at all. ++ if { ac_try='cc -c conftest.$ac_ext >&5' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_try='cc -c conftest.$ac_ext -o conftest.$ac_objext >&5' ++ if { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ test -f conftest.$ac_objext && { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; ++ then ++ # cc works too. ++ : ++ else ++ # cc exists but doesn't like -o. ++ eval ac_cv_prog_cc_${ac_cc}_c_o=no ++ fi ++ fi ++ fi ++else ++ eval ac_cv_prog_cc_${ac_cc}_c_o=no ++fi ++rm -f conftest* ++ ++fi ++if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" = yes"; then ++ echo "$as_me:$LINENO: result: yes" >&5 ++echo "${ECHO_T}yes" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++ ++cat >>confdefs.h <<\_ACEOF ++#define NO_MINUS_C_MINUS_O 1 ++_ACEOF ++ ++fi ++ ++# FIXME: we rely on the cache variable name because ++# there is no other way. ++set dummy $CC ++ac_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` ++if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" != yes"; then ++ # Losing compiler, so override with the script. ++ # FIXME: It is wrong to rewrite CC. ++ # But if we don't then we get into trouble of one sort or another. ++ # A longer-term fix would be to have automake use am__CC in this case, ++ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" ++ CC="$am_aux_dir/compile $CC" ++fi ++ ++ ++if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. ++set dummy ${ac_tool_prefix}ranlib; ac_word=$2 ++echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 ++if test "${ac_cv_prog_RANLIB+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -n "$RANLIB"; then ++ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++ ++fi ++fi ++RANLIB=$ac_cv_prog_RANLIB ++if test -n "$RANLIB"; then ++ echo "$as_me:$LINENO: result: $RANLIB" >&5 ++echo "${ECHO_T}$RANLIB" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++fi ++if test -z "$ac_cv_prog_RANLIB"; then ++ ac_ct_RANLIB=$RANLIB ++ # Extract the first word of "ranlib", so it can be a program name with args. ++set dummy ranlib; ac_word=$2 ++echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 ++if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -n "$ac_ct_RANLIB"; then ++ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_ac_ct_RANLIB="ranlib" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++ ++ test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":" ++fi ++fi ++ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB ++if test -n "$ac_ct_RANLIB"; then ++ echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 ++echo "${ECHO_T}$ac_ct_RANLIB" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++ RANLIB=$ac_ct_RANLIB ++else ++ RANLIB="$ac_cv_prog_RANLIB" ++fi ++ ++ ++ ++cat >>confdefs.h <<\_ACEOF ++#define _GNU_SOURCE 1 ++_ACEOF ++ ++ ++# Find a good install program. We prefer a C program (faster), ++# so one script is as good as another. But avoid the broken or ++# incompatible versions: ++# SysV /etc/install, /usr/sbin/install ++# SunOS /usr/etc/install ++# IRIX /sbin/install ++# AIX /bin/install ++# AmigaOS /C/install, which installs bootblocks on floppy discs ++# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag ++# AFS /usr/afsws/bin/install, which mishandles nonexistent args ++# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" ++# OS/2's system install, which has a completely different semantic ++# ./install, which can be erroneously created by make from ./install.sh. ++echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 ++echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 ++if test -z "$INSTALL"; then ++if test "${ac_cv_path_install+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ # Account for people who put trailing slashes in PATH elements. ++case $as_dir/ in ++ ./ | .// | /cC/* | \ ++ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ++ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ ++ /usr/ucb/* ) ;; ++ *) ++ # OSF1 and SCO ODT 3.0 have their own names for install. ++ # Don't use installbsd from OSF since it installs stuff as root ++ # by default. ++ for ac_prog in ginstall scoinst install; do ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then ++ if test $ac_prog = install && ++ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then ++ # AIX install. It has an incompatible calling convention. ++ : ++ elif test $ac_prog = install && ++ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then ++ # program-specific install script used by HP pwplus--don't use. ++ : ++ else ++ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" ++ break 3 ++ fi ++ fi ++ done ++ done ++ ;; ++esac ++done ++ ++ ++fi ++ if test "${ac_cv_path_install+set}" = set; then ++ INSTALL=$ac_cv_path_install ++ else ++ # As a last resort, use the slow shell script. We don't cache a ++ # path for INSTALL within a source directory, because that will ++ # break other packages using the cache if that directory is ++ # removed, or if the path is relative. ++ INSTALL=$ac_install_sh ++ fi ++fi ++echo "$as_me:$LINENO: result: $INSTALL" >&5 ++echo "${ECHO_T}$INSTALL" >&6 ++ ++# Use test -z because SunOS4 sh mishandles braces in ${var-val}. ++# It thinks the first close brace ends the variable substitution. ++test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' ++ ++test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' ++ ++test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' ++ ++ ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 ++echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 ++# On Suns, sometimes $CPP names a directory. ++if test -n "$CPP" && test -d "$CPP"; then ++ CPP= ++fi ++if test -z "$CPP"; then ++ if test "${ac_cv_prog_CPP+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ # Double quotes because CPP needs to be expanded ++ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" ++ do ++ ac_preproc_ok=false ++for ac_c_preproc_warn_flag in '' yes ++do ++ # Use a header file that comes with gcc, so configuring glibc ++ # with a fresh cross-compiler works. ++ # Prefer to if __STDC__ is defined, since ++ # exists even on freestanding compilers. ++ # On the NeXT, cc -E runs the code through the compiler's parser, ++ # not just through cpp. "Syntax error" is here to catch this case. ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++#ifdef __STDC__ ++# include ++#else ++# include ++#endif ++ Syntax error ++_ACEOF ++if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 ++ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } >/dev/null; then ++ if test -s conftest.err; then ++ ac_cpp_err=$ac_c_preproc_warn_flag ++ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag ++ else ++ ac_cpp_err= ++ fi ++else ++ ac_cpp_err=yes ++fi ++if test -z "$ac_cpp_err"; then ++ : ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ # Broken: fails on valid input. ++continue ++fi ++rm -f conftest.err conftest.$ac_ext ++ ++ # OK, works on sane cases. Now check whether non-existent headers ++ # can be detected and how. ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++#include ++_ACEOF ++if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 ++ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } >/dev/null; then ++ if test -s conftest.err; then ++ ac_cpp_err=$ac_c_preproc_warn_flag ++ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag ++ else ++ ac_cpp_err= ++ fi ++else ++ ac_cpp_err=yes ++fi ++if test -z "$ac_cpp_err"; then ++ # Broken: success on invalid input. ++continue ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ # Passes both tests. ++ac_preproc_ok=: ++break ++fi ++rm -f conftest.err conftest.$ac_ext ++ ++done ++# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. ++rm -f conftest.err conftest.$ac_ext ++if $ac_preproc_ok; then ++ break ++fi ++ ++ done ++ ac_cv_prog_CPP=$CPP ++ ++fi ++ CPP=$ac_cv_prog_CPP ++else ++ ac_cv_prog_CPP=$CPP ++fi ++echo "$as_me:$LINENO: result: $CPP" >&5 ++echo "${ECHO_T}$CPP" >&6 ++ac_preproc_ok=false ++for ac_c_preproc_warn_flag in '' yes ++do ++ # Use a header file that comes with gcc, so configuring glibc ++ # with a fresh cross-compiler works. ++ # Prefer to if __STDC__ is defined, since ++ # exists even on freestanding compilers. ++ # On the NeXT, cc -E runs the code through the compiler's parser, ++ # not just through cpp. "Syntax error" is here to catch this case. ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++#ifdef __STDC__ ++# include ++#else ++# include ++#endif ++ Syntax error ++_ACEOF ++if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 ++ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } >/dev/null; then ++ if test -s conftest.err; then ++ ac_cpp_err=$ac_c_preproc_warn_flag ++ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag ++ else ++ ac_cpp_err= ++ fi ++else ++ ac_cpp_err=yes ++fi ++if test -z "$ac_cpp_err"; then ++ : ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ # Broken: fails on valid input. ++continue ++fi ++rm -f conftest.err conftest.$ac_ext ++ ++ # OK, works on sane cases. Now check whether non-existent headers ++ # can be detected and how. ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++#include ++_ACEOF ++if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 ++ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } >/dev/null; then ++ if test -s conftest.err; then ++ ac_cpp_err=$ac_c_preproc_warn_flag ++ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag ++ else ++ ac_cpp_err= ++ fi ++else ++ ac_cpp_err=yes ++fi ++if test -z "$ac_cpp_err"; then ++ # Broken: success on invalid input. ++continue ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ # Passes both tests. ++ac_preproc_ok=: ++break ++fi ++rm -f conftest.err conftest.$ac_ext ++ ++done ++# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. ++rm -f conftest.err conftest.$ac_ext ++if $ac_preproc_ok; then ++ : ++else ++ { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check ++See \`config.log' for more details." >&5 ++echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check ++See \`config.log' for more details." >&2;} ++ { (exit 1); exit 1; }; } ++fi ++ ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++ ++echo "$as_me:$LINENO: checking for egrep" >&5 ++echo $ECHO_N "checking for egrep... $ECHO_C" >&6 ++if test "${ac_cv_prog_egrep+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if echo a | (grep -E '(a|b)') >/dev/null 2>&1 ++ then ac_cv_prog_egrep='grep -E' ++ else ac_cv_prog_egrep='egrep' ++ fi ++fi ++echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 ++echo "${ECHO_T}$ac_cv_prog_egrep" >&6 ++ EGREP=$ac_cv_prog_egrep ++ ++ ++if test $ac_cv_c_compiler_gnu = yes; then ++ echo "$as_me:$LINENO: checking whether $CC needs -traditional" >&5 ++echo $ECHO_N "checking whether $CC needs -traditional... $ECHO_C" >&6 ++if test "${ac_cv_prog_gcc_traditional+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ ac_pattern="Autoconf.*'x'" ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++#include ++Autoconf TIOCGETP ++_ACEOF ++if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | ++ $EGREP "$ac_pattern" >/dev/null 2>&1; then ++ ac_cv_prog_gcc_traditional=yes ++else ++ ac_cv_prog_gcc_traditional=no ++fi ++rm -f conftest* ++ ++ ++ if test $ac_cv_prog_gcc_traditional = no; then ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++#include ++Autoconf TCGETA ++_ACEOF ++if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | ++ $EGREP "$ac_pattern" >/dev/null 2>&1; then ++ ac_cv_prog_gcc_traditional=yes ++fi ++rm -f conftest* ++ ++ fi ++fi ++echo "$as_me:$LINENO: result: $ac_cv_prog_gcc_traditional" >&5 ++echo "${ECHO_T}$ac_cv_prog_gcc_traditional" >&6 ++ if test $ac_cv_prog_gcc_traditional = yes; then ++ CC="$CC -traditional" ++ fi ++fi ++ ++ ++# Checks for typedefs, structures, and compiler characteristics. ++echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 ++echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6 ++if test "${ac_cv_c_const+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++/* FIXME: Include the comments suggested by Paul. */ ++#ifndef __cplusplus ++ /* Ultrix mips cc rejects this. */ ++ typedef int charset[2]; ++ const charset x; ++ /* SunOS 4.1.1 cc rejects this. */ ++ char const *const *ccp; ++ char **p; ++ /* NEC SVR4.0.2 mips cc rejects this. */ ++ struct point {int x, y;}; ++ static struct point const zero = {0,0}; ++ /* AIX XL C 1.02.0.0 rejects this. ++ It does not let you subtract one const X* pointer from another in ++ an arm of an if-expression whose if-part is not a constant ++ expression */ ++ const char *g = "string"; ++ ccp = &g + (g ? g-g : 0); ++ /* HPUX 7.0 cc rejects these. */ ++ ++ccp; ++ p = (char**) ccp; ++ ccp = (char const *const *) p; ++ { /* SCO 3.2v4 cc rejects this. */ ++ char *t; ++ char const *s = 0 ? (char *) 0 : (char const *) 0; ++ ++ *t++ = 0; ++ } ++ { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ ++ int x[] = {25, 17}; ++ const int *foo = &x[0]; ++ ++foo; ++ } ++ { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ ++ typedef const int *iptr; ++ iptr p = 0; ++ ++p; ++ } ++ { /* AIX XL C 1.02.0.0 rejects this saying ++ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ ++ struct s { int j; const int *ap[3]; }; ++ struct s *b; b->j = 5; ++ } ++ { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ ++ const int foo = 10; ++ } ++#endif ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_c_const=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_cv_c_const=no ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 ++echo "${ECHO_T}$ac_cv_c_const" >&6 ++if test $ac_cv_c_const = no; then ++ ++cat >>confdefs.h <<\_ACEOF ++#define const ++_ACEOF ++ ++fi ++ ++echo "$as_me:$LINENO: checking for inline" >&5 ++echo $ECHO_N "checking for inline... $ECHO_C" >&6 ++if test "${ac_cv_c_inline+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ ac_cv_c_inline=no ++for ac_kw in inline __inline__ __inline; do ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++#ifndef __cplusplus ++typedef int foo_t; ++static $ac_kw foo_t static_foo () {return 0; } ++$ac_kw foo_t foo () {return 0; } ++#endif ++ ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_c_inline=$ac_kw; break ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++done ++ ++fi ++echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5 ++echo "${ECHO_T}$ac_cv_c_inline" >&6 ++ ++ ++case $ac_cv_c_inline in ++ inline | yes) ;; ++ *) ++ case $ac_cv_c_inline in ++ no) ac_val=;; ++ *) ac_val=$ac_cv_c_inline;; ++ esac ++ cat >>confdefs.h <<_ACEOF ++#ifndef __cplusplus ++#define inline $ac_val ++#endif ++_ACEOF ++ ;; ++esac ++ ++echo "$as_me:$LINENO: checking for ANSI C header files" >&5 ++echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 ++if test "${ac_cv_header_stdc+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++#include ++#include ++#include ++#include ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_header_stdc=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_cv_header_stdc=no ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++ ++if test $ac_cv_header_stdc = yes; then ++ # SunOS 4.x string.h does not declare mem*, contrary to ANSI. ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++#include ++ ++_ACEOF ++if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | ++ $EGREP "memchr" >/dev/null 2>&1; then ++ : ++else ++ ac_cv_header_stdc=no ++fi ++rm -f conftest* ++ ++fi ++ ++if test $ac_cv_header_stdc = yes; then ++ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++#include ++ ++_ACEOF ++if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | ++ $EGREP "free" >/dev/null 2>&1; then ++ : ++else ++ ac_cv_header_stdc=no ++fi ++rm -f conftest* ++ ++fi ++ ++if test $ac_cv_header_stdc = yes; then ++ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. ++ if test "$cross_compiling" = yes; then ++ : ++else ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++#include ++#if ((' ' & 0x0FF) == 0x020) ++# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') ++# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) ++#else ++# define ISLOWER(c) \ ++ (('a' <= (c) && (c) <= 'i') \ ++ || ('j' <= (c) && (c) <= 'r') \ ++ || ('s' <= (c) && (c) <= 'z')) ++# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) ++#endif ++ ++#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) ++int ++main () ++{ ++ int i; ++ for (i = 0; i < 256; i++) ++ if (XOR (islower (i), ISLOWER (i)) ++ || toupper (i) != TOUPPER (i)) ++ exit(2); ++ exit (0); ++} ++_ACEOF ++rm -f conftest$ac_exeext ++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 ++ (eval $ac_link) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && { ac_try='./conftest$ac_exeext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ : ++else ++ echo "$as_me: program exited with status $ac_status" >&5 ++echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++( exit $ac_status ) ++ac_cv_header_stdc=no ++fi ++rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext ++fi ++fi ++fi ++echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 ++echo "${ECHO_T}$ac_cv_header_stdc" >&6 ++if test $ac_cv_header_stdc = yes; then ++ ++cat >>confdefs.h <<\_ACEOF ++#define STDC_HEADERS 1 ++_ACEOF ++ ++fi ++ ++# On IRIX 5.3, sys/types and inttypes.h are conflicting. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ ++ inttypes.h stdint.h unistd.h ++do ++as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` ++echo "$as_me:$LINENO: checking for $ac_header" >&5 ++echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 ++if eval "test \"\${$as_ac_Header+set}\" = set"; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_includes_default ++ ++#include <$ac_header> ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ eval "$as_ac_Header=yes" ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++eval "$as_ac_Header=no" ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 ++echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 ++if test `eval echo '${'$as_ac_Header'}'` = yes; then ++ cat >>confdefs.h <<_ACEOF ++#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 ++_ACEOF ++ ++fi ++ ++done ++ ++ ++echo "$as_me:$LINENO: checking for off_t" >&5 ++echo $ECHO_N "checking for off_t... $ECHO_C" >&6 ++if test "${ac_cv_type_off_t+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_includes_default ++int ++main () ++{ ++if ((off_t *) 0) ++ return 0; ++if (sizeof (off_t)) ++ return 0; ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_type_off_t=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_cv_type_off_t=no ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++echo "$as_me:$LINENO: result: $ac_cv_type_off_t" >&5 ++echo "${ECHO_T}$ac_cv_type_off_t" >&6 ++if test $ac_cv_type_off_t = yes; then ++ : ++else ++ ++cat >>confdefs.h <<_ACEOF ++#define off_t long ++_ACEOF ++ ++fi ++ ++echo "$as_me:$LINENO: checking for size_t" >&5 ++echo $ECHO_N "checking for size_t... $ECHO_C" >&6 ++if test "${ac_cv_type_size_t+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_includes_default ++int ++main () ++{ ++if ((size_t *) 0) ++ return 0; ++if (sizeof (size_t)) ++ return 0; ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_type_size_t=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_cv_type_size_t=no ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 ++echo "${ECHO_T}$ac_cv_type_size_t" >&6 ++if test $ac_cv_type_size_t = yes; then ++ : ++else ++ ++cat >>confdefs.h <<_ACEOF ++#define size_t unsigned ++_ACEOF ++ ++fi ++ ++echo "$as_me:$LINENO: checking for int8_t" >&5 ++echo $ECHO_N "checking for int8_t... $ECHO_C" >&6 ++if test "${ac_cv_type_int8_t+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_includes_default ++int ++main () ++{ ++if ((int8_t *) 0) ++ return 0; ++if (sizeof (int8_t)) ++ return 0; ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_type_int8_t=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_cv_type_int8_t=no ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++echo "$as_me:$LINENO: result: $ac_cv_type_int8_t" >&5 ++echo "${ECHO_T}$ac_cv_type_int8_t" >&6 ++if test $ac_cv_type_int8_t = yes; then ++ ++cat >>confdefs.h <<_ACEOF ++#define HAVE_INT8_T 1 ++_ACEOF ++ ++ ++fi ++ ++echo "$as_me:$LINENO: checking for uint8_t" >&5 ++echo $ECHO_N "checking for uint8_t... $ECHO_C" >&6 ++if test "${ac_cv_type_uint8_t+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_includes_default ++int ++main () ++{ ++if ((uint8_t *) 0) ++ return 0; ++if (sizeof (uint8_t)) ++ return 0; ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_type_uint8_t=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_cv_type_uint8_t=no ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++echo "$as_me:$LINENO: result: $ac_cv_type_uint8_t" >&5 ++echo "${ECHO_T}$ac_cv_type_uint8_t" >&6 ++if test $ac_cv_type_uint8_t = yes; then ++ ++cat >>confdefs.h <<_ACEOF ++#define HAVE_UINT8_T 1 ++_ACEOF ++ ++ ++fi ++ ++echo "$as_me:$LINENO: checking for int16_t" >&5 ++echo $ECHO_N "checking for int16_t... $ECHO_C" >&6 ++if test "${ac_cv_type_int16_t+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_includes_default ++int ++main () ++{ ++if ((int16_t *) 0) ++ return 0; ++if (sizeof (int16_t)) ++ return 0; ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_type_int16_t=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_cv_type_int16_t=no ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++echo "$as_me:$LINENO: result: $ac_cv_type_int16_t" >&5 ++echo "${ECHO_T}$ac_cv_type_int16_t" >&6 ++if test $ac_cv_type_int16_t = yes; then ++ ++cat >>confdefs.h <<_ACEOF ++#define HAVE_INT16_T 1 ++_ACEOF ++ ++ ++fi ++ ++echo "$as_me:$LINENO: checking for uint16_t" >&5 ++echo $ECHO_N "checking for uint16_t... $ECHO_C" >&6 ++if test "${ac_cv_type_uint16_t+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_includes_default ++int ++main () ++{ ++if ((uint16_t *) 0) ++ return 0; ++if (sizeof (uint16_t)) ++ return 0; ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_type_uint16_t=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_cv_type_uint16_t=no ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++echo "$as_me:$LINENO: result: $ac_cv_type_uint16_t" >&5 ++echo "${ECHO_T}$ac_cv_type_uint16_t" >&6 ++if test $ac_cv_type_uint16_t = yes; then ++ ++cat >>confdefs.h <<_ACEOF ++#define HAVE_UINT16_T 1 ++_ACEOF ++ ++ ++fi ++ ++echo "$as_me:$LINENO: checking for int32_t" >&5 ++echo $ECHO_N "checking for int32_t... $ECHO_C" >&6 ++if test "${ac_cv_type_int32_t+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_includes_default ++int ++main () ++{ ++if ((int32_t *) 0) ++ return 0; ++if (sizeof (int32_t)) ++ return 0; ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_type_int32_t=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_cv_type_int32_t=no ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++echo "$as_me:$LINENO: result: $ac_cv_type_int32_t" >&5 ++echo "${ECHO_T}$ac_cv_type_int32_t" >&6 ++if test $ac_cv_type_int32_t = yes; then ++ ++cat >>confdefs.h <<_ACEOF ++#define HAVE_INT32_T 1 ++_ACEOF ++ ++ ++fi ++ ++echo "$as_me:$LINENO: checking for uint32_t" >&5 ++echo $ECHO_N "checking for uint32_t... $ECHO_C" >&6 ++if test "${ac_cv_type_uint32_t+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_includes_default ++int ++main () ++{ ++if ((uint32_t *) 0) ++ return 0; ++if (sizeof (uint32_t)) ++ return 0; ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_type_uint32_t=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_cv_type_uint32_t=no ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++echo "$as_me:$LINENO: result: $ac_cv_type_uint32_t" >&5 ++echo "${ECHO_T}$ac_cv_type_uint32_t" >&6 ++if test $ac_cv_type_uint32_t = yes; then ++ ++cat >>confdefs.h <<_ACEOF ++#define HAVE_UINT32_T 1 ++_ACEOF ++ ++ ++fi ++ ++echo "$as_me:$LINENO: checking for int64_t" >&5 ++echo $ECHO_N "checking for int64_t... $ECHO_C" >&6 ++if test "${ac_cv_type_int64_t+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_includes_default ++int ++main () ++{ ++if ((int64_t *) 0) ++ return 0; ++if (sizeof (int64_t)) ++ return 0; ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_type_int64_t=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_cv_type_int64_t=no ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++echo "$as_me:$LINENO: result: $ac_cv_type_int64_t" >&5 ++echo "${ECHO_T}$ac_cv_type_int64_t" >&6 ++if test $ac_cv_type_int64_t = yes; then ++ ++cat >>confdefs.h <<_ACEOF ++#define HAVE_INT64_T 1 ++_ACEOF ++ ++ ++fi ++ ++echo "$as_me:$LINENO: checking for uint64_t" >&5 ++echo $ECHO_N "checking for uint64_t... $ECHO_C" >&6 ++if test "${ac_cv_type_uint64_t+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_includes_default ++int ++main () ++{ ++if ((uint64_t *) 0) ++ return 0; ++if (sizeof (uint64_t)) ++ return 0; ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_type_uint64_t=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_cv_type_uint64_t=no ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++echo "$as_me:$LINENO: result: $ac_cv_type_uint64_t" >&5 ++echo "${ECHO_T}$ac_cv_type_uint64_t" >&6 ++if test $ac_cv_type_uint64_t = yes; then ++ ++cat >>confdefs.h <<_ACEOF ++#define HAVE_UINT64_T 1 ++_ACEOF ++ ++ ++fi ++ ++echo "$as_me:$LINENO: checking for short" >&5 ++echo $ECHO_N "checking for short... $ECHO_C" >&6 ++if test "${ac_cv_type_short+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_includes_default ++int ++main () ++{ ++if ((short *) 0) ++ return 0; ++if (sizeof (short)) ++ return 0; ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_type_short=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_cv_type_short=no ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++echo "$as_me:$LINENO: result: $ac_cv_type_short" >&5 ++echo "${ECHO_T}$ac_cv_type_short" >&6 ++ ++echo "$as_me:$LINENO: checking size of short" >&5 ++echo $ECHO_N "checking size of short... $ECHO_C" >&6 ++if test "${ac_cv_sizeof_short+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test "$ac_cv_type_short" = yes; then ++ # The cast to unsigned long works around a bug in the HP C Compiler ++ # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects ++ # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. ++ # This bug is HP SR number 8606223364. ++ if test "$cross_compiling" = yes; then ++ # Depending upon the size, compute the lo and hi bounds. ++cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_includes_default ++int ++main () ++{ ++static int test_array [1 - 2 * !(((long) (sizeof (short))) >= 0)]; ++test_array [0] = 0 ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_lo=0 ac_mid=0 ++ while :; do ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_includes_default ++int ++main () ++{ ++static int test_array [1 - 2 * !(((long) (sizeof (short))) <= $ac_mid)]; ++test_array [0] = 0 ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_hi=$ac_mid; break ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_lo=`expr $ac_mid + 1` ++ if test $ac_lo -le $ac_mid; then ++ ac_lo= ac_hi= ++ break ++ fi ++ ac_mid=`expr 2 '*' $ac_mid + 1` ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++ done ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_includes_default ++int ++main () ++{ ++static int test_array [1 - 2 * !(((long) (sizeof (short))) < 0)]; ++test_array [0] = 0 ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_hi=-1 ac_mid=-1 ++ while :; do ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_includes_default ++int ++main () ++{ ++static int test_array [1 - 2 * !(((long) (sizeof (short))) >= $ac_mid)]; ++test_array [0] = 0 ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_lo=$ac_mid; break ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_hi=`expr '(' $ac_mid ')' - 1` ++ if test $ac_mid -le $ac_hi; then ++ ac_lo= ac_hi= ++ break ++ fi ++ ac_mid=`expr 2 '*' $ac_mid` ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++ done ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_lo= ac_hi= ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++# Binary search between lo and hi bounds. ++while test "x$ac_lo" != "x$ac_hi"; do ++ ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_includes_default ++int ++main () ++{ ++static int test_array [1 - 2 * !(((long) (sizeof (short))) <= $ac_mid)]; ++test_array [0] = 0 ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_hi=$ac_mid ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_lo=`expr '(' $ac_mid ')' + 1` ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++done ++case $ac_lo in ++?*) ac_cv_sizeof_short=$ac_lo;; ++'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (short), 77 ++See \`config.log' for more details." >&5 ++echo "$as_me: error: cannot compute sizeof (short), 77 ++See \`config.log' for more details." >&2;} ++ { (exit 1); exit 1; }; } ;; ++esac ++else ++ if test "$cross_compiling" = yes; then ++ { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling ++See \`config.log' for more details." >&5 ++echo "$as_me: error: cannot run test program while cross compiling ++See \`config.log' for more details." >&2;} ++ { (exit 1); exit 1; }; } ++else ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_includes_default ++long longval () { return (long) (sizeof (short)); } ++unsigned long ulongval () { return (long) (sizeof (short)); } ++#include ++#include ++int ++main () ++{ ++ ++ FILE *f = fopen ("conftest.val", "w"); ++ if (! f) ++ exit (1); ++ if (((long) (sizeof (short))) < 0) ++ { ++ long i = longval (); ++ if (i != ((long) (sizeof (short)))) ++ exit (1); ++ fprintf (f, "%ld\n", i); ++ } ++ else ++ { ++ unsigned long i = ulongval (); ++ if (i != ((long) (sizeof (short)))) ++ exit (1); ++ fprintf (f, "%lu\n", i); ++ } ++ exit (ferror (f) || fclose (f) != 0); ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest$ac_exeext ++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 ++ (eval $ac_link) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && { ac_try='./conftest$ac_exeext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_sizeof_short=`cat conftest.val` ++else ++ echo "$as_me: program exited with status $ac_status" >&5 ++echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++( exit $ac_status ) ++{ { echo "$as_me:$LINENO: error: cannot compute sizeof (short), 77 ++See \`config.log' for more details." >&5 ++echo "$as_me: error: cannot compute sizeof (short), 77 ++See \`config.log' for more details." >&2;} ++ { (exit 1); exit 1; }; } ++fi ++rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext ++fi ++fi ++rm -f conftest.val ++else ++ ac_cv_sizeof_short=0 ++fi ++fi ++echo "$as_me:$LINENO: result: $ac_cv_sizeof_short" >&5 ++echo "${ECHO_T}$ac_cv_sizeof_short" >&6 ++cat >>confdefs.h <<_ACEOF ++#define SIZEOF_SHORT $ac_cv_sizeof_short ++_ACEOF ++ ++ ++echo "$as_me:$LINENO: checking for int" >&5 ++echo $ECHO_N "checking for int... $ECHO_C" >&6 ++if test "${ac_cv_type_int+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_includes_default ++int ++main () ++{ ++if ((int *) 0) ++ return 0; ++if (sizeof (int)) ++ return 0; ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_type_int=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_cv_type_int=no ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++echo "$as_me:$LINENO: result: $ac_cv_type_int" >&5 ++echo "${ECHO_T}$ac_cv_type_int" >&6 ++ ++echo "$as_me:$LINENO: checking size of int" >&5 ++echo $ECHO_N "checking size of int... $ECHO_C" >&6 ++if test "${ac_cv_sizeof_int+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test "$ac_cv_type_int" = yes; then ++ # The cast to unsigned long works around a bug in the HP C Compiler ++ # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects ++ # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. ++ # This bug is HP SR number 8606223364. ++ if test "$cross_compiling" = yes; then ++ # Depending upon the size, compute the lo and hi bounds. ++cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_includes_default ++int ++main () ++{ ++static int test_array [1 - 2 * !(((long) (sizeof (int))) >= 0)]; ++test_array [0] = 0 ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_lo=0 ac_mid=0 ++ while :; do ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_includes_default ++int ++main () ++{ ++static int test_array [1 - 2 * !(((long) (sizeof (int))) <= $ac_mid)]; ++test_array [0] = 0 ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_hi=$ac_mid; break ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_lo=`expr $ac_mid + 1` ++ if test $ac_lo -le $ac_mid; then ++ ac_lo= ac_hi= ++ break ++ fi ++ ac_mid=`expr 2 '*' $ac_mid + 1` ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++ done ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_includes_default ++int ++main () ++{ ++static int test_array [1 - 2 * !(((long) (sizeof (int))) < 0)]; ++test_array [0] = 0 ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_hi=-1 ac_mid=-1 ++ while :; do ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_includes_default ++int ++main () ++{ ++static int test_array [1 - 2 * !(((long) (sizeof (int))) >= $ac_mid)]; ++test_array [0] = 0 ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_lo=$ac_mid; break ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_hi=`expr '(' $ac_mid ')' - 1` ++ if test $ac_mid -le $ac_hi; then ++ ac_lo= ac_hi= ++ break ++ fi ++ ac_mid=`expr 2 '*' $ac_mid` ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++ done ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_lo= ac_hi= ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++# Binary search between lo and hi bounds. ++while test "x$ac_lo" != "x$ac_hi"; do ++ ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_includes_default ++int ++main () ++{ ++static int test_array [1 - 2 * !(((long) (sizeof (int))) <= $ac_mid)]; ++test_array [0] = 0 ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_hi=$ac_mid ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_lo=`expr '(' $ac_mid ')' + 1` ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++done ++case $ac_lo in ++?*) ac_cv_sizeof_int=$ac_lo;; ++'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (int), 77 ++See \`config.log' for more details." >&5 ++echo "$as_me: error: cannot compute sizeof (int), 77 ++See \`config.log' for more details." >&2;} ++ { (exit 1); exit 1; }; } ;; ++esac ++else ++ if test "$cross_compiling" = yes; then ++ { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling ++See \`config.log' for more details." >&5 ++echo "$as_me: error: cannot run test program while cross compiling ++See \`config.log' for more details." >&2;} ++ { (exit 1); exit 1; }; } ++else ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_includes_default ++long longval () { return (long) (sizeof (int)); } ++unsigned long ulongval () { return (long) (sizeof (int)); } ++#include ++#include ++int ++main () ++{ ++ ++ FILE *f = fopen ("conftest.val", "w"); ++ if (! f) ++ exit (1); ++ if (((long) (sizeof (int))) < 0) ++ { ++ long i = longval (); ++ if (i != ((long) (sizeof (int)))) ++ exit (1); ++ fprintf (f, "%ld\n", i); ++ } ++ else ++ { ++ unsigned long i = ulongval (); ++ if (i != ((long) (sizeof (int)))) ++ exit (1); ++ fprintf (f, "%lu\n", i); ++ } ++ exit (ferror (f) || fclose (f) != 0); ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest$ac_exeext ++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 ++ (eval $ac_link) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && { ac_try='./conftest$ac_exeext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_sizeof_int=`cat conftest.val` ++else ++ echo "$as_me: program exited with status $ac_status" >&5 ++echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++( exit $ac_status ) ++{ { echo "$as_me:$LINENO: error: cannot compute sizeof (int), 77 ++See \`config.log' for more details." >&5 ++echo "$as_me: error: cannot compute sizeof (int), 77 ++See \`config.log' for more details." >&2;} ++ { (exit 1); exit 1; }; } ++fi ++rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext ++fi ++fi ++rm -f conftest.val ++else ++ ac_cv_sizeof_int=0 ++fi ++fi ++echo "$as_me:$LINENO: result: $ac_cv_sizeof_int" >&5 ++echo "${ECHO_T}$ac_cv_sizeof_int" >&6 ++cat >>confdefs.h <<_ACEOF ++#define SIZEOF_INT $ac_cv_sizeof_int ++_ACEOF ++ ++ ++echo "$as_me:$LINENO: checking for long" >&5 ++echo $ECHO_N "checking for long... $ECHO_C" >&6 ++if test "${ac_cv_type_long+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_includes_default ++int ++main () ++{ ++if ((long *) 0) ++ return 0; ++if (sizeof (long)) ++ return 0; ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_type_long=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_cv_type_long=no ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++echo "$as_me:$LINENO: result: $ac_cv_type_long" >&5 ++echo "${ECHO_T}$ac_cv_type_long" >&6 ++ ++echo "$as_me:$LINENO: checking size of long" >&5 ++echo $ECHO_N "checking size of long... $ECHO_C" >&6 ++if test "${ac_cv_sizeof_long+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test "$ac_cv_type_long" = yes; then ++ # The cast to unsigned long works around a bug in the HP C Compiler ++ # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects ++ # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. ++ # This bug is HP SR number 8606223364. ++ if test "$cross_compiling" = yes; then ++ # Depending upon the size, compute the lo and hi bounds. ++cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_includes_default ++int ++main () ++{ ++static int test_array [1 - 2 * !(((long) (sizeof (long))) >= 0)]; ++test_array [0] = 0 ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_lo=0 ac_mid=0 ++ while :; do ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_includes_default ++int ++main () ++{ ++static int test_array [1 - 2 * !(((long) (sizeof (long))) <= $ac_mid)]; ++test_array [0] = 0 ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_hi=$ac_mid; break ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_lo=`expr $ac_mid + 1` ++ if test $ac_lo -le $ac_mid; then ++ ac_lo= ac_hi= ++ break ++ fi ++ ac_mid=`expr 2 '*' $ac_mid + 1` ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++ done ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_includes_default ++int ++main () ++{ ++static int test_array [1 - 2 * !(((long) (sizeof (long))) < 0)]; ++test_array [0] = 0 ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_hi=-1 ac_mid=-1 ++ while :; do ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_includes_default ++int ++main () ++{ ++static int test_array [1 - 2 * !(((long) (sizeof (long))) >= $ac_mid)]; ++test_array [0] = 0 ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_lo=$ac_mid; break ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_hi=`expr '(' $ac_mid ')' - 1` ++ if test $ac_mid -le $ac_hi; then ++ ac_lo= ac_hi= ++ break ++ fi ++ ac_mid=`expr 2 '*' $ac_mid` ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++ done ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_lo= ac_hi= ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++# Binary search between lo and hi bounds. ++while test "x$ac_lo" != "x$ac_hi"; do ++ ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_includes_default ++int ++main () ++{ ++static int test_array [1 - 2 * !(((long) (sizeof (long))) <= $ac_mid)]; ++test_array [0] = 0 ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_hi=$ac_mid ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_lo=`expr '(' $ac_mid ')' + 1` ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++done ++case $ac_lo in ++?*) ac_cv_sizeof_long=$ac_lo;; ++'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (long), 77 ++See \`config.log' for more details." >&5 ++echo "$as_me: error: cannot compute sizeof (long), 77 ++See \`config.log' for more details." >&2;} ++ { (exit 1); exit 1; }; } ;; ++esac ++else ++ if test "$cross_compiling" = yes; then ++ { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling ++See \`config.log' for more details." >&5 ++echo "$as_me: error: cannot run test program while cross compiling ++See \`config.log' for more details." >&2;} ++ { (exit 1); exit 1; }; } ++else ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_includes_default ++long longval () { return (long) (sizeof (long)); } ++unsigned long ulongval () { return (long) (sizeof (long)); } ++#include ++#include ++int ++main () ++{ ++ ++ FILE *f = fopen ("conftest.val", "w"); ++ if (! f) ++ exit (1); ++ if (((long) (sizeof (long))) < 0) ++ { ++ long i = longval (); ++ if (i != ((long) (sizeof (long)))) ++ exit (1); ++ fprintf (f, "%ld\n", i); ++ } ++ else ++ { ++ unsigned long i = ulongval (); ++ if (i != ((long) (sizeof (long)))) ++ exit (1); ++ fprintf (f, "%lu\n", i); ++ } ++ exit (ferror (f) || fclose (f) != 0); ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest$ac_exeext ++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 ++ (eval $ac_link) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && { ac_try='./conftest$ac_exeext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_sizeof_long=`cat conftest.val` ++else ++ echo "$as_me: program exited with status $ac_status" >&5 ++echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++( exit $ac_status ) ++{ { echo "$as_me:$LINENO: error: cannot compute sizeof (long), 77 ++See \`config.log' for more details." >&5 ++echo "$as_me: error: cannot compute sizeof (long), 77 ++See \`config.log' for more details." >&2;} ++ { (exit 1); exit 1; }; } ++fi ++rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext ++fi ++fi ++rm -f conftest.val ++else ++ ac_cv_sizeof_long=0 ++fi ++fi ++echo "$as_me:$LINENO: result: $ac_cv_sizeof_long" >&5 ++echo "${ECHO_T}$ac_cv_sizeof_long" >&6 ++cat >>confdefs.h <<_ACEOF ++#define SIZEOF_LONG $ac_cv_sizeof_long ++_ACEOF ++ ++ ++ ++echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5 ++echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6 ++if test "${ac_cv_c_bigendian+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ # See if sys/param.h defines the BYTE_ORDER macro. ++cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++#include ++#include ++ ++int ++main () ++{ ++#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN ++ bogus endian macros ++#endif ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ # It does; now see whether it defined to BIG_ENDIAN or not. ++cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++#include ++#include ++ ++int ++main () ++{ ++#if BYTE_ORDER != BIG_ENDIAN ++ not big endian ++#endif ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_c_bigendian=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_cv_c_bigendian=no ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++# It does not; compile a test program. ++if test "$cross_compiling" = yes; then ++ # try to guess the endianness by grepping values into an object file ++ ac_cv_c_bigendian=unknown ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; ++short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; ++void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; } ++short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; ++short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; ++void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; } ++int ++main () ++{ ++ _ascii (); _ebcdic (); ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then ++ ac_cv_c_bigendian=yes ++fi ++if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then ++ if test "$ac_cv_c_bigendian" = unknown; then ++ ac_cv_c_bigendian=no ++ else ++ # finding both strings is unlikely to happen, but who knows? ++ ac_cv_c_bigendian=unknown ++ fi ++fi ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++else ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++int ++main () ++{ ++ /* Are we little or big endian? From Harbison&Steele. */ ++ union ++ { ++ long l; ++ char c[sizeof (long)]; ++ } u; ++ u.l = 1; ++ exit (u.c[sizeof (long) - 1] == 1); ++} ++_ACEOF ++rm -f conftest$ac_exeext ++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 ++ (eval $ac_link) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && { ac_try='./conftest$ac_exeext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_c_bigendian=no ++else ++ echo "$as_me: program exited with status $ac_status" >&5 ++echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++( exit $ac_status ) ++ac_cv_c_bigendian=yes ++fi ++rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext ++fi ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5 ++echo "${ECHO_T}$ac_cv_c_bigendian" >&6 ++case $ac_cv_c_bigendian in ++ yes) ++ ENDIAN=BIG ++ ;; ++ no) ++ ENDIAN=LITTLE ++ ;; ++ *) ++ { { echo "$as_me:$LINENO: error: unknown endianness ++presetting ac_cv_c_bigendian=no (or yes) will help" >&5 ++echo "$as_me: error: unknown endianness ++presetting ac_cv_c_bigendian=no (or yes) will help" >&2;} ++ { (exit 1); exit 1; }; } ;; ++esac ++ ++ ++ ++ ++ ++# libtool stuff ++# Check whether --enable-shared or --disable-shared was given. ++if test "${enable_shared+set}" = set; then ++ enableval="$enable_shared" ++ p=${PACKAGE-default} ++ case $enableval in ++ yes) enable_shared=yes ;; ++ no) enable_shared=no ;; ++ *) ++ enable_shared=no ++ # Look at the argument we got. We use all the common list separators. ++ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," ++ for pkg in $enableval; do ++ IFS="$lt_save_ifs" ++ if test "X$pkg" = "X$p"; then ++ enable_shared=yes ++ fi ++ done ++ IFS="$lt_save_ifs" ++ ;; ++ esac ++else ++ enable_shared=yes ++fi; ++ ++# Check whether --enable-static or --disable-static was given. ++if test "${enable_static+set}" = set; then ++ enableval="$enable_static" ++ p=${PACKAGE-default} ++ case $enableval in ++ yes) enable_static=yes ;; ++ no) enable_static=no ;; ++ *) ++ enable_static=no ++ # Look at the argument we got. We use all the common list separators. ++ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," ++ for pkg in $enableval; do ++ IFS="$lt_save_ifs" ++ if test "X$pkg" = "X$p"; then ++ enable_static=yes ++ fi ++ done ++ IFS="$lt_save_ifs" ++ ;; ++ esac ++else ++ enable_static=yes ++fi; ++ ++# Check whether --enable-fast-install or --disable-fast-install was given. ++if test "${enable_fast_install+set}" = set; then ++ enableval="$enable_fast_install" ++ p=${PACKAGE-default} ++ case $enableval in ++ yes) enable_fast_install=yes ;; ++ no) enable_fast_install=no ;; ++ *) ++ enable_fast_install=no ++ # Look at the argument we got. We use all the common list separators. ++ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," ++ for pkg in $enableval; do ++ IFS="$lt_save_ifs" ++ if test "X$pkg" = "X$p"; then ++ enable_fast_install=yes ++ fi ++ done ++ IFS="$lt_save_ifs" ++ ;; ++ esac ++else ++ enable_fast_install=yes ++fi; ++ ++# Make sure we can run config.sub. ++$ac_config_sub sun4 >/dev/null 2>&1 || ++ { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5 ++echo "$as_me: error: cannot run $ac_config_sub" >&2;} ++ { (exit 1); exit 1; }; } ++ ++echo "$as_me:$LINENO: checking build system type" >&5 ++echo $ECHO_N "checking build system type... $ECHO_C" >&6 ++if test "${ac_cv_build+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ ac_cv_build_alias=$build_alias ++test -z "$ac_cv_build_alias" && ++ ac_cv_build_alias=`$ac_config_guess` ++test -z "$ac_cv_build_alias" && ++ { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 ++echo "$as_me: error: cannot guess build type; you must specify one" >&2;} ++ { (exit 1); exit 1; }; } ++ac_cv_build=`$ac_config_sub $ac_cv_build_alias` || ++ { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5 ++echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;} ++ { (exit 1); exit 1; }; } ++ ++fi ++echo "$as_me:$LINENO: result: $ac_cv_build" >&5 ++echo "${ECHO_T}$ac_cv_build" >&6 ++build=$ac_cv_build ++build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` ++build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` ++build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` ++ ++ ++echo "$as_me:$LINENO: checking host system type" >&5 ++echo $ECHO_N "checking host system type... $ECHO_C" >&6 ++if test "${ac_cv_host+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ ac_cv_host_alias=$host_alias ++test -z "$ac_cv_host_alias" && ++ ac_cv_host_alias=$ac_cv_build_alias ++ac_cv_host=`$ac_config_sub $ac_cv_host_alias` || ++ { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5 ++echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;} ++ { (exit 1); exit 1; }; } ++ ++fi ++echo "$as_me:$LINENO: result: $ac_cv_host" >&5 ++echo "${ECHO_T}$ac_cv_host" >&6 ++host=$ac_cv_host ++host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` ++host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` ++host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` ++ ++ ++echo "$as_me:$LINENO: checking for a sed that does not truncate output" >&5 ++echo $ECHO_N "checking for a sed that does not truncate output... $ECHO_C" >&6 ++if test "${lt_cv_path_SED+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ # Loop through the user's path and test for sed and gsed. ++# Then use that list of sed's as ones to test for truncation. ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for lt_ac_prog in sed gsed; do ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then ++ lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" ++ fi ++ done ++ done ++done ++IFS=$as_save_IFS ++lt_ac_max=0 ++lt_ac_count=0 ++# Add /usr/xpg4/bin/sed as it is typically found on Solaris ++# along with /bin/sed that truncates output. ++for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do ++ test ! -f $lt_ac_sed && continue ++ cat /dev/null > conftest.in ++ lt_ac_count=0 ++ echo $ECHO_N "0123456789$ECHO_C" >conftest.in ++ # Check for GNU sed and select it if it is found. ++ if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then ++ lt_cv_path_SED=$lt_ac_sed ++ break ++ fi ++ while true; do ++ cat conftest.in conftest.in >conftest.tmp ++ mv conftest.tmp conftest.in ++ cp conftest.in conftest.nl ++ echo >>conftest.nl ++ $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break ++ cmp -s conftest.out conftest.nl || break ++ # 10000 chars as input seems more than enough ++ test $lt_ac_count -gt 10 && break ++ lt_ac_count=`expr $lt_ac_count + 1` ++ if test $lt_ac_count -gt $lt_ac_max; then ++ lt_ac_max=$lt_ac_count ++ lt_cv_path_SED=$lt_ac_sed ++ fi ++ done ++done ++ ++fi ++ ++SED=$lt_cv_path_SED ++ ++echo "$as_me:$LINENO: result: $SED" >&5 ++echo "${ECHO_T}$SED" >&6 ++ ++ ++# Check whether --with-gnu-ld or --without-gnu-ld was given. ++if test "${with_gnu_ld+set}" = set; then ++ withval="$with_gnu_ld" ++ test "$withval" = no || with_gnu_ld=yes ++else ++ with_gnu_ld=no ++fi; ++ac_prog=ld ++if test "$GCC" = yes; then ++ # Check if gcc -print-prog-name=ld gives a path. ++ echo "$as_me:$LINENO: checking for ld used by $CC" >&5 ++echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6 ++ case $host in ++ *-*-mingw*) ++ # gcc leaves a trailing carriage return which upsets mingw ++ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; ++ *) ++ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; ++ esac ++ case $ac_prog in ++ # Accept absolute paths. ++ [\\/]* | ?:[\\/]*) ++ re_direlt='/[^/][^/]*/\.\./' ++ # Canonicalize the pathname of ld ++ ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'` ++ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do ++ ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"` ++ done ++ test -z "$LD" && LD="$ac_prog" ++ ;; ++ "") ++ # If it fails, then pretend we aren't using GCC. ++ ac_prog=ld ++ ;; ++ *) ++ # If it is relative, then search for the first ld in PATH. ++ with_gnu_ld=unknown ++ ;; ++ esac ++elif test "$with_gnu_ld" = yes; then ++ echo "$as_me:$LINENO: checking for GNU ld" >&5 ++echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6 ++else ++ echo "$as_me:$LINENO: checking for non-GNU ld" >&5 ++echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6 ++fi ++if test "${lt_cv_path_LD+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -z "$LD"; then ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++ for ac_dir in $PATH; do ++ IFS="$lt_save_ifs" ++ test -z "$ac_dir" && ac_dir=. ++ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then ++ lt_cv_path_LD="$ac_dir/$ac_prog" ++ # Check to see if the program is GNU ld. I'd rather use --version, ++ # but apparently some variants of GNU ld only accept -v. ++ # Break only if it was the GNU/non-GNU ld that we prefer. ++ case `"$lt_cv_path_LD" -v 2>&1 &5 ++echo "${ECHO_T}$LD" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5 ++echo "$as_me: error: no acceptable ld found in \$PATH" >&2;} ++ { (exit 1); exit 1; }; } ++echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5 ++echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6 ++if test "${lt_cv_prog_gnu_ld+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ # I'd rather use --version here, but apparently some GNU lds only accept -v. ++case `$LD -v 2>&1 &5 ++echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6 ++with_gnu_ld=$lt_cv_prog_gnu_ld ++ ++ ++echo "$as_me:$LINENO: checking for $LD option to reload object files" >&5 ++echo $ECHO_N "checking for $LD option to reload object files... $ECHO_C" >&6 ++if test "${lt_cv_ld_reload_flag+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ lt_cv_ld_reload_flag='-r' ++fi ++echo "$as_me:$LINENO: result: $lt_cv_ld_reload_flag" >&5 ++echo "${ECHO_T}$lt_cv_ld_reload_flag" >&6 ++reload_flag=$lt_cv_ld_reload_flag ++case $reload_flag in ++"" | " "*) ;; ++*) reload_flag=" $reload_flag" ;; ++esac ++reload_cmds='$LD$reload_flag -o $output$reload_objs' ++case $host_os in ++ darwin*) ++ if test "$GCC" = yes; then ++ reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' ++ else ++ reload_cmds='$LD$reload_flag -o $output$reload_objs' ++ fi ++ ;; ++esac ++ ++echo "$as_me:$LINENO: checking for BSD-compatible nm" >&5 ++echo $ECHO_N "checking for BSD-compatible nm... $ECHO_C" >&6 ++if test "${lt_cv_path_NM+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -n "$NM"; then ++ # Let the user override the test. ++ lt_cv_path_NM="$NM" ++else ++ lt_nm_to_check="${ac_tool_prefix}nm" ++ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then ++ lt_nm_to_check="$lt_nm_to_check nm" ++ fi ++ for lt_tmp_nm in $lt_nm_to_check; do ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do ++ IFS="$lt_save_ifs" ++ test -z "$ac_dir" && ac_dir=. ++ tmp_nm="$ac_dir/$lt_tmp_nm" ++ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then ++ # Check to see if the nm accepts a BSD-compat flag. ++ # Adding the `sed 1q' prevents false positives on HP-UX, which says: ++ # nm: unknown option "B" ignored ++ # Tru64's nm complains that /dev/null is an invalid object file ++ case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in ++ */dev/null* | *'Invalid file or object type'*) ++ lt_cv_path_NM="$tmp_nm -B" ++ break ++ ;; ++ *) ++ case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in ++ */dev/null*) ++ lt_cv_path_NM="$tmp_nm -p" ++ break ++ ;; ++ *) ++ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but ++ continue # so that we can try to find one that supports BSD flags ++ ;; ++ esac ++ ;; ++ esac ++ fi ++ done ++ IFS="$lt_save_ifs" ++ done ++ test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm ++fi ++fi ++echo "$as_me:$LINENO: result: $lt_cv_path_NM" >&5 ++echo "${ECHO_T}$lt_cv_path_NM" >&6 ++NM="$lt_cv_path_NM" ++ ++echo "$as_me:$LINENO: checking whether ln -s works" >&5 ++echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6 ++LN_S=$as_ln_s ++if test "$LN_S" = "ln -s"; then ++ echo "$as_me:$LINENO: result: yes" >&5 ++echo "${ECHO_T}yes" >&6 ++else ++ echo "$as_me:$LINENO: result: no, using $LN_S" >&5 ++echo "${ECHO_T}no, using $LN_S" >&6 ++fi ++ ++echo "$as_me:$LINENO: checking how to recognise dependent libraries" >&5 ++echo $ECHO_N "checking how to recognise dependent libraries... $ECHO_C" >&6 ++if test "${lt_cv_deplibs_check_method+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ lt_cv_file_magic_cmd='$MAGIC_CMD' ++lt_cv_file_magic_test_file= ++lt_cv_deplibs_check_method='unknown' ++# Need to set the preceding variable on all platforms that support ++# interlibrary dependencies. ++# 'none' -- dependencies not supported. ++# `unknown' -- same as none, but documents that we really don't know. ++# 'pass_all' -- all dependencies passed with no checks. ++# 'test_compile' -- check by making test program. ++# 'file_magic [[regex]]' -- check by looking for files in library path ++# which responds to the $file_magic_cmd with a given extended regex. ++# If you have `file' or equivalent on your system and you're not sure ++# whether `pass_all' will *always* work, you probably want this one. ++ ++case $host_os in ++aix4* | aix5*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++beos*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++bsdi[45]*) ++ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' ++ lt_cv_file_magic_cmd='/usr/bin/file -L' ++ lt_cv_file_magic_test_file=/shlib/libc.so ++ ;; ++ ++cygwin*) ++ # func_win32_libid is a shell function defined in ltmain.sh ++ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' ++ lt_cv_file_magic_cmd='func_win32_libid' ++ ;; ++ ++mingw* | pw32*) ++ # Base MSYS/MinGW do not provide the 'file' command needed by ++ # func_win32_libid shell function, so use a weaker test based on 'objdump'. ++ lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' ++ lt_cv_file_magic_cmd='$OBJDUMP -f' ++ ;; ++ ++darwin* | rhapsody*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++freebsd* | kfreebsd*-gnu | dragonfly*) ++ if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then ++ case $host_cpu in ++ i*86 ) ++ # Not sure whether the presence of OpenBSD here was a mistake. ++ # Let's accept both of them until this is cleared up. ++ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' ++ lt_cv_file_magic_cmd=/usr/bin/file ++ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ++ ;; ++ esac ++ else ++ lt_cv_deplibs_check_method=pass_all ++ fi ++ ;; ++ ++gnu*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++hpux10.20* | hpux11*) ++ lt_cv_file_magic_cmd=/usr/bin/file ++ case $host_cpu in ++ ia64*) ++ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' ++ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ++ ;; ++ hppa*64*) ++ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]' ++ lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ++ ;; ++ *) ++ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library' ++ lt_cv_file_magic_test_file=/usr/lib/libc.sl ++ ;; ++ esac ++ ;; ++ ++interix3*) ++ # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here ++ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' ++ ;; ++ ++irix5* | irix6* | nonstopux*) ++ case $LD in ++ *-32|*"-32 ") libmagic=32-bit;; ++ *-n32|*"-n32 ") libmagic=N32;; ++ *-64|*"-64 ") libmagic=64-bit;; ++ *) libmagic=never-match;; ++ esac ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++# This must be Linux ELF. ++linux*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++netbsd*) ++ if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then ++ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' ++ else ++ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' ++ fi ++ ;; ++ ++newos6*) ++ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' ++ lt_cv_file_magic_cmd=/usr/bin/file ++ lt_cv_file_magic_test_file=/usr/lib/libnls.so ++ ;; ++ ++nto-qnx*) ++ lt_cv_deplibs_check_method=unknown ++ ;; ++ ++openbsd*) ++ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then ++ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' ++ else ++ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' ++ fi ++ ;; ++ ++osf3* | osf4* | osf5*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++solaris*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++sysv4 | sysv4.3*) ++ case $host_vendor in ++ motorola) ++ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' ++ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ++ ;; ++ ncr) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ sequent) ++ lt_cv_file_magic_cmd='/bin/file' ++ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ++ ;; ++ sni) ++ lt_cv_file_magic_cmd='/bin/file' ++ lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" ++ lt_cv_file_magic_test_file=/lib/libc.so ++ ;; ++ siemens) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ pc) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ esac ++ ;; ++ ++sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++esac ++ ++fi ++echo "$as_me:$LINENO: result: $lt_cv_deplibs_check_method" >&5 ++echo "${ECHO_T}$lt_cv_deplibs_check_method" >&6 ++file_magic_cmd=$lt_cv_file_magic_cmd ++deplibs_check_method=$lt_cv_deplibs_check_method ++test -z "$deplibs_check_method" && deplibs_check_method=unknown ++ ++ ++ ++ ++# If no C compiler was specified, use CC. ++LTCC=${LTCC-"$CC"} ++ ++# If no C compiler flags were specified, use CFLAGS. ++LTCFLAGS=${LTCFLAGS-"$CFLAGS"} ++ ++# Allow CC to be a program name with arguments. ++compiler=$CC ++ ++# Check whether --enable-libtool-lock or --disable-libtool-lock was given. ++if test "${enable_libtool_lock+set}" = set; then ++ enableval="$enable_libtool_lock" ++ ++fi; ++test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes ++ ++# Some flags need to be propagated to the compiler or linker for good ++# libtool support. ++case $host in ++ia64-*-hpux*) ++ # Find out which ABI we are using. ++ echo 'int i;' > conftest.$ac_ext ++ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; then ++ case `/usr/bin/file conftest.$ac_objext` in ++ *ELF-32*) ++ HPUX_IA64_MODE="32" ++ ;; ++ *ELF-64*) ++ HPUX_IA64_MODE="64" ++ ;; ++ esac ++ fi ++ rm -rf conftest* ++ ;; ++*-*-irix6*) ++ # Find out which ABI we are using. ++ echo '#line 6826 "configure"' > conftest.$ac_ext ++ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; then ++ if test "$lt_cv_prog_gnu_ld" = yes; then ++ case `/usr/bin/file conftest.$ac_objext` in ++ *32-bit*) ++ LD="${LD-ld} -melf32bsmip" ++ ;; ++ *N32*) ++ LD="${LD-ld} -melf32bmipn32" ++ ;; ++ *64-bit*) ++ LD="${LD-ld} -melf64bmip" ++ ;; ++ esac ++ else ++ case `/usr/bin/file conftest.$ac_objext` in ++ *32-bit*) ++ LD="${LD-ld} -32" ++ ;; ++ *N32*) ++ LD="${LD-ld} -n32" ++ ;; ++ *64-bit*) ++ LD="${LD-ld} -64" ++ ;; ++ esac ++ fi ++ fi ++ rm -rf conftest* ++ ;; ++ ++x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) ++ # Find out which ABI we are using. ++ echo 'int i;' > conftest.$ac_ext ++ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; then ++ case `/usr/bin/file conftest.o` in ++ *32-bit*) ++ case $host in ++ x86_64-*linux*) ++ LD="${LD-ld} -m elf_i386" ++ ;; ++ ppc64-*linux*|powerpc64-*linux*) ++ LD="${LD-ld} -m elf32ppclinux" ++ ;; ++ s390x-*linux*) ++ LD="${LD-ld} -m elf_s390" ++ ;; ++ sparc64-*linux*) ++ LD="${LD-ld} -m elf32_sparc" ++ ;; ++ esac ++ ;; ++ *64-bit*) ++ case $host in ++ x86_64-*linux*) ++ LD="${LD-ld} -m elf_x86_64" ++ ;; ++ ppc*-*linux*|powerpc*-*linux*) ++ LD="${LD-ld} -m elf64ppc" ++ ;; ++ s390*-*linux*) ++ LD="${LD-ld} -m elf64_s390" ++ ;; ++ sparc*-*linux*) ++ LD="${LD-ld} -m elf64_sparc" ++ ;; ++ esac ++ ;; ++ esac ++ fi ++ rm -rf conftest* ++ ;; ++ ++*-*-sco3.2v5*) ++ # On SCO OpenServer 5, we need -belf to get full-featured binaries. ++ SAVE_CFLAGS="$CFLAGS" ++ CFLAGS="$CFLAGS -belf" ++ echo "$as_me:$LINENO: checking whether the C compiler needs -belf" >&5 ++echo $ECHO_N "checking whether the C compiler needs -belf... $ECHO_C" >&6 ++if test "${lt_cv_cc_needs_belf+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext conftest$ac_exeext ++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 ++ (eval $ac_link) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest$ac_exeext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ lt_cv_cc_needs_belf=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++lt_cv_cc_needs_belf=no ++fi ++rm -f conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++ ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++fi ++echo "$as_me:$LINENO: result: $lt_cv_cc_needs_belf" >&5 ++echo "${ECHO_T}$lt_cv_cc_needs_belf" >&6 ++ if test x"$lt_cv_cc_needs_belf" != x"yes"; then ++ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf ++ CFLAGS="$SAVE_CFLAGS" ++ fi ++ ;; ++sparc*-*solaris*) ++ # Find out which ABI we are using. ++ echo 'int i;' > conftest.$ac_ext ++ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; then ++ case `/usr/bin/file conftest.o` in ++ *64-bit*) ++ case $lt_cv_prog_gnu_ld in ++ yes*) LD="${LD-ld} -m elf64_sparc" ;; ++ *) LD="${LD-ld} -64" ;; ++ esac ++ ;; ++ esac ++ fi ++ rm -rf conftest* ++ ;; ++ ++ ++esac ++ ++need_locks="$enable_libtool_lock" ++ ++ ++ ++for ac_header in dlfcn.h ++do ++as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` ++if eval "test \"\${$as_ac_Header+set}\" = set"; then ++ echo "$as_me:$LINENO: checking for $ac_header" >&5 ++echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 ++if eval "test \"\${$as_ac_Header+set}\" = set"; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++fi ++echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 ++echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 ++else ++ # Is the header compilable? ++echo "$as_me:$LINENO: checking $ac_header usability" >&5 ++echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 ++cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_includes_default ++#include <$ac_header> ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_header_compiler=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_header_compiler=no ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 ++echo "${ECHO_T}$ac_header_compiler" >&6 ++ ++# Is the header present? ++echo "$as_me:$LINENO: checking $ac_header presence" >&5 ++echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 ++cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++#include <$ac_header> ++_ACEOF ++if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 ++ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } >/dev/null; then ++ if test -s conftest.err; then ++ ac_cpp_err=$ac_c_preproc_warn_flag ++ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag ++ else ++ ac_cpp_err= ++ fi ++else ++ ac_cpp_err=yes ++fi ++if test -z "$ac_cpp_err"; then ++ ac_header_preproc=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ ac_header_preproc=no ++fi ++rm -f conftest.err conftest.$ac_ext ++echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 ++echo "${ECHO_T}$ac_header_preproc" >&6 ++ ++# So? What about this header? ++case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in ++ yes:no: ) ++ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 ++echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} ++ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 ++echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ++ ac_header_preproc=yes ++ ;; ++ no:yes:* ) ++ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 ++echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} ++ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 ++echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} ++ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 ++echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} ++ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 ++echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} ++ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 ++echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} ++ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 ++echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ++ ( ++ cat <<\_ASBOX ++## ------------------------------------- ## ++## Report this to eddie.wai@broadcom.com ## ++## ------------------------------------- ## ++_ASBOX ++ ) | ++ sed "s/^/$as_me: WARNING: /" >&2 ++ ;; ++esac ++echo "$as_me:$LINENO: checking for $ac_header" >&5 ++echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 ++if eval "test \"\${$as_ac_Header+set}\" = set"; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ eval "$as_ac_Header=\$ac_header_preproc" ++fi ++echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 ++echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 ++ ++fi ++if test `eval echo '${'$as_ac_Header'}'` = yes; then ++ cat >>confdefs.h <<_ACEOF ++#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 ++_ACEOF ++ ++fi ++ ++done ++ ++ac_ext=cc ++ac_cpp='$CXXCPP $CPPFLAGS' ++ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ++if test -n "$ac_tool_prefix"; then ++ for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC ++ do ++ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. ++set dummy $ac_tool_prefix$ac_prog; ac_word=$2 ++echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 ++if test "${ac_cv_prog_CXX+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -n "$CXX"; then ++ ac_cv_prog_CXX="$CXX" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++ ++fi ++fi ++CXX=$ac_cv_prog_CXX ++if test -n "$CXX"; then ++ echo "$as_me:$LINENO: result: $CXX" >&5 ++echo "${ECHO_T}$CXX" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++ test -n "$CXX" && break ++ done ++fi ++if test -z "$CXX"; then ++ ac_ct_CXX=$CXX ++ for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC ++do ++ # Extract the first word of "$ac_prog", so it can be a program name with args. ++set dummy $ac_prog; ac_word=$2 ++echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 ++if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -n "$ac_ct_CXX"; then ++ ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_ac_ct_CXX="$ac_prog" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++ ++fi ++fi ++ac_ct_CXX=$ac_cv_prog_ac_ct_CXX ++if test -n "$ac_ct_CXX"; then ++ echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 ++echo "${ECHO_T}$ac_ct_CXX" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++ test -n "$ac_ct_CXX" && break ++done ++test -n "$ac_ct_CXX" || ac_ct_CXX="g++" ++ ++ CXX=$ac_ct_CXX ++fi ++ ++ ++# Provide some information about the compiler. ++echo "$as_me:$LINENO:" \ ++ "checking for C++ compiler version" >&5 ++ac_compiler=`set X $ac_compile; echo $2` ++{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 ++ (eval $ac_compiler --version &5) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } ++{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 ++ (eval $ac_compiler -v &5) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } ++{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 ++ (eval $ac_compiler -V &5) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } ++ ++echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 ++echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6 ++if test "${ac_cv_cxx_compiler_gnu+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++#ifndef __GNUC__ ++ choke me ++#endif ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_cxx_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_compiler_gnu=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_compiler_gnu=no ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++ac_cv_cxx_compiler_gnu=$ac_compiler_gnu ++ ++fi ++echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 ++echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6 ++GXX=`test $ac_compiler_gnu = yes && echo yes` ++ac_test_CXXFLAGS=${CXXFLAGS+set} ++ac_save_CXXFLAGS=$CXXFLAGS ++CXXFLAGS="-g" ++echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 ++echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6 ++if test "${ac_cv_prog_cxx_g+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_cxx_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_prog_cxx_g=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_cv_prog_cxx_g=no ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 ++echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6 ++if test "$ac_test_CXXFLAGS" = set; then ++ CXXFLAGS=$ac_save_CXXFLAGS ++elif test $ac_cv_prog_cxx_g = yes; then ++ if test "$GXX" = yes; then ++ CXXFLAGS="-g -O2" ++ else ++ CXXFLAGS="-g" ++ fi ++else ++ if test "$GXX" = yes; then ++ CXXFLAGS="-O2" ++ else ++ CXXFLAGS= ++ fi ++fi ++for ac_declaration in \ ++ '' \ ++ 'extern "C" void std::exit (int) throw (); using std::exit;' \ ++ 'extern "C" void std::exit (int); using std::exit;' \ ++ 'extern "C" void exit (int) throw ();' \ ++ 'extern "C" void exit (int);' \ ++ 'void exit (int);' ++do ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_declaration ++#include ++int ++main () ++{ ++exit (42); ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_cxx_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ : ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++continue ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_declaration ++int ++main () ++{ ++exit (42); ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_cxx_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ break ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++done ++rm -f conftest* ++if test -n "$ac_declaration"; then ++ echo '#ifdef __cplusplus' >>confdefs.h ++ echo $ac_declaration >>confdefs.h ++ echo '#endif' >>confdefs.h ++fi ++ ++ac_ext=cc ++ac_cpp='$CXXCPP $CPPFLAGS' ++ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ++ ++depcc="$CXX" am_compiler_list= ++ ++echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 ++echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6 ++if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then ++ # We make a subdir and do the tests there. Otherwise we can end up ++ # making bogus files that we don't know about and never remove. For ++ # instance it was reported that on HP-UX the gcc test will end up ++ # making a dummy file named `D' -- because `-MD' means `put the output ++ # in D'. ++ mkdir conftest.dir ++ # Copy depcomp to subdir because otherwise we won't find it if we're ++ # using a relative directory. ++ cp "$am_depcomp" conftest.dir ++ cd conftest.dir ++ # We will build objects and dependencies in a subdirectory because ++ # it helps to detect inapplicable dependency modes. For instance ++ # both Tru64's cc and ICC support -MD to output dependencies as a ++ # side effect of compilation, but ICC will put the dependencies in ++ # the current directory while Tru64 will put them in the object ++ # directory. ++ mkdir sub ++ ++ am_cv_CXX_dependencies_compiler_type=none ++ if test "$am_compiler_list" = ""; then ++ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` ++ fi ++ for depmode in $am_compiler_list; do ++ # Setup a source with many dependencies, because some compilers ++ # like to wrap large dependency lists on column 80 (with \), and ++ # we should not choose a depcomp mode which is confused by this. ++ # ++ # We need to recreate these files for each test, as the compiler may ++ # overwrite some of them when testing with obscure command lines. ++ # This happens at least with the AIX C compiler. ++ : > sub/conftest.c ++ for i in 1 2 3 4 5 6; do ++ echo '#include "conftst'$i'.h"' >> sub/conftest.c ++ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with ++ # Solaris 8's {/usr,}/bin/sh. ++ touch sub/conftst$i.h ++ done ++ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf ++ ++ case $depmode in ++ nosideeffect) ++ # after this tag, mechanisms are not by side-effect, so they'll ++ # only be used when explicitly requested ++ if test "x$enable_dependency_tracking" = xyes; then ++ continue ++ else ++ break ++ fi ++ ;; ++ none) break ;; ++ esac ++ # We check with `-c' and `-o' for the sake of the "dashmstdout" ++ # mode. It turns out that the SunPro C++ compiler does not properly ++ # handle `-M -o', and we need to detect this. ++ if depmode=$depmode \ ++ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ ++ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ ++ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ ++ >/dev/null 2>conftest.err && ++ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && ++ grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && ++ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then ++ # icc doesn't choke on unknown options, it will just issue warnings ++ # or remarks (even with -Werror). So we grep stderr for any message ++ # that says an option was ignored or not supported. ++ # When given -MP, icc 7.0 and 7.1 complain thusly: ++ # icc: Command line warning: ignoring option '-M'; no argument required ++ # The diagnosis changed in icc 8.0: ++ # icc: Command line remark: option '-MP' not supported ++ if (grep 'ignoring option' conftest.err || ++ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else ++ am_cv_CXX_dependencies_compiler_type=$depmode ++ break ++ fi ++ fi ++ done ++ ++ cd .. ++ rm -rf conftest.dir ++else ++ am_cv_CXX_dependencies_compiler_type=none ++fi ++ ++fi ++echo "$as_me:$LINENO: result: $am_cv_CXX_dependencies_compiler_type" >&5 ++echo "${ECHO_T}$am_cv_CXX_dependencies_compiler_type" >&6 ++CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type ++ ++ ++ ++if ++ test "x$enable_dependency_tracking" != xno \ ++ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then ++ am__fastdepCXX_TRUE= ++ am__fastdepCXX_FALSE='#' ++else ++ am__fastdepCXX_TRUE='#' ++ am__fastdepCXX_FALSE= ++fi ++ ++ ++ ++ ++if test -n "$CXX" && ( test "X$CXX" != "Xno" && ++ ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || ++ (test "X$CXX" != "Xg++"))) ; then ++ ac_ext=cc ++ac_cpp='$CXXCPP $CPPFLAGS' ++ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ++echo "$as_me:$LINENO: checking how to run the C++ preprocessor" >&5 ++echo $ECHO_N "checking how to run the C++ preprocessor... $ECHO_C" >&6 ++if test -z "$CXXCPP"; then ++ if test "${ac_cv_prog_CXXCPP+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ # Double quotes because CXXCPP needs to be expanded ++ for CXXCPP in "$CXX -E" "/lib/cpp" ++ do ++ ac_preproc_ok=false ++for ac_cxx_preproc_warn_flag in '' yes ++do ++ # Use a header file that comes with gcc, so configuring glibc ++ # with a fresh cross-compiler works. ++ # Prefer to if __STDC__ is defined, since ++ # exists even on freestanding compilers. ++ # On the NeXT, cc -E runs the code through the compiler's parser, ++ # not just through cpp. "Syntax error" is here to catch this case. ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++#ifdef __STDC__ ++# include ++#else ++# include ++#endif ++ Syntax error ++_ACEOF ++if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 ++ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } >/dev/null; then ++ if test -s conftest.err; then ++ ac_cpp_err=$ac_cxx_preproc_warn_flag ++ ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag ++ else ++ ac_cpp_err= ++ fi ++else ++ ac_cpp_err=yes ++fi ++if test -z "$ac_cpp_err"; then ++ : ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ # Broken: fails on valid input. ++continue ++fi ++rm -f conftest.err conftest.$ac_ext ++ ++ # OK, works on sane cases. Now check whether non-existent headers ++ # can be detected and how. ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++#include ++_ACEOF ++if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 ++ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } >/dev/null; then ++ if test -s conftest.err; then ++ ac_cpp_err=$ac_cxx_preproc_warn_flag ++ ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag ++ else ++ ac_cpp_err= ++ fi ++else ++ ac_cpp_err=yes ++fi ++if test -z "$ac_cpp_err"; then ++ # Broken: success on invalid input. ++continue ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ # Passes both tests. ++ac_preproc_ok=: ++break ++fi ++rm -f conftest.err conftest.$ac_ext ++ ++done ++# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. ++rm -f conftest.err conftest.$ac_ext ++if $ac_preproc_ok; then ++ break ++fi ++ ++ done ++ ac_cv_prog_CXXCPP=$CXXCPP ++ ++fi ++ CXXCPP=$ac_cv_prog_CXXCPP ++else ++ ac_cv_prog_CXXCPP=$CXXCPP ++fi ++echo "$as_me:$LINENO: result: $CXXCPP" >&5 ++echo "${ECHO_T}$CXXCPP" >&6 ++ac_preproc_ok=false ++for ac_cxx_preproc_warn_flag in '' yes ++do ++ # Use a header file that comes with gcc, so configuring glibc ++ # with a fresh cross-compiler works. ++ # Prefer to if __STDC__ is defined, since ++ # exists even on freestanding compilers. ++ # On the NeXT, cc -E runs the code through the compiler's parser, ++ # not just through cpp. "Syntax error" is here to catch this case. ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++#ifdef __STDC__ ++# include ++#else ++# include ++#endif ++ Syntax error ++_ACEOF ++if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 ++ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } >/dev/null; then ++ if test -s conftest.err; then ++ ac_cpp_err=$ac_cxx_preproc_warn_flag ++ ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag ++ else ++ ac_cpp_err= ++ fi ++else ++ ac_cpp_err=yes ++fi ++if test -z "$ac_cpp_err"; then ++ : ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ # Broken: fails on valid input. ++continue ++fi ++rm -f conftest.err conftest.$ac_ext ++ ++ # OK, works on sane cases. Now check whether non-existent headers ++ # can be detected and how. ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++#include ++_ACEOF ++if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 ++ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } >/dev/null; then ++ if test -s conftest.err; then ++ ac_cpp_err=$ac_cxx_preproc_warn_flag ++ ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag ++ else ++ ac_cpp_err= ++ fi ++else ++ ac_cpp_err=yes ++fi ++if test -z "$ac_cpp_err"; then ++ # Broken: success on invalid input. ++continue ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ # Passes both tests. ++ac_preproc_ok=: ++break ++fi ++rm -f conftest.err conftest.$ac_ext ++ ++done ++# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. ++rm -f conftest.err conftest.$ac_ext ++if $ac_preproc_ok; then ++ : ++else ++ { { echo "$as_me:$LINENO: error: C++ preprocessor \"$CXXCPP\" fails sanity check ++See \`config.log' for more details." >&5 ++echo "$as_me: error: C++ preprocessor \"$CXXCPP\" fails sanity check ++See \`config.log' for more details." >&2;} ++ { (exit 1); exit 1; }; } ++fi ++ ++ac_ext=cc ++ac_cpp='$CXXCPP $CPPFLAGS' ++ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ++ ++fi ++ ++ ++ac_ext=f ++ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5' ++ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_f77_compiler_gnu ++if test -n "$ac_tool_prefix"; then ++ for ac_prog in g77 f77 xlf frt pgf77 fort77 fl32 af77 f90 xlf90 pgf90 epcf90 f95 fort xlf95 ifc efc pgf95 lf95 gfortran ++ do ++ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. ++set dummy $ac_tool_prefix$ac_prog; ac_word=$2 ++echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 ++if test "${ac_cv_prog_F77+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -n "$F77"; then ++ ac_cv_prog_F77="$F77" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_F77="$ac_tool_prefix$ac_prog" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++ ++fi ++fi ++F77=$ac_cv_prog_F77 ++if test -n "$F77"; then ++ echo "$as_me:$LINENO: result: $F77" >&5 ++echo "${ECHO_T}$F77" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++ test -n "$F77" && break ++ done ++fi ++if test -z "$F77"; then ++ ac_ct_F77=$F77 ++ for ac_prog in g77 f77 xlf frt pgf77 fort77 fl32 af77 f90 xlf90 pgf90 epcf90 f95 fort xlf95 ifc efc pgf95 lf95 gfortran ++do ++ # Extract the first word of "$ac_prog", so it can be a program name with args. ++set dummy $ac_prog; ac_word=$2 ++echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 ++if test "${ac_cv_prog_ac_ct_F77+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -n "$ac_ct_F77"; then ++ ac_cv_prog_ac_ct_F77="$ac_ct_F77" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_ac_ct_F77="$ac_prog" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++ ++fi ++fi ++ac_ct_F77=$ac_cv_prog_ac_ct_F77 ++if test -n "$ac_ct_F77"; then ++ echo "$as_me:$LINENO: result: $ac_ct_F77" >&5 ++echo "${ECHO_T}$ac_ct_F77" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++ test -n "$ac_ct_F77" && break ++done ++ ++ F77=$ac_ct_F77 ++fi ++ ++ ++# Provide some information about the compiler. ++echo "$as_me:7952:" \ ++ "checking for Fortran 77 compiler version" >&5 ++ac_compiler=`set X $ac_compile; echo $2` ++{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 ++ (eval $ac_compiler --version &5) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } ++{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 ++ (eval $ac_compiler -v &5) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } ++{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 ++ (eval $ac_compiler -V &5) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } ++rm -f a.out ++ ++# If we don't use `.F' as extension, the preprocessor is not run on the ++# input file. (Note that this only needs to work for GNU compilers.) ++ac_save_ext=$ac_ext ++ac_ext=F ++echo "$as_me:$LINENO: checking whether we are using the GNU Fortran 77 compiler" >&5 ++echo $ECHO_N "checking whether we are using the GNU Fortran 77 compiler... $ECHO_C" >&6 ++if test "${ac_cv_f77_compiler_gnu+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ cat >conftest.$ac_ext <<_ACEOF ++ program main ++#ifndef __GNUC__ ++ choke me ++#endif ++ ++ end ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_f77_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_compiler_gnu=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_compiler_gnu=no ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++ac_cv_f77_compiler_gnu=$ac_compiler_gnu ++ ++fi ++echo "$as_me:$LINENO: result: $ac_cv_f77_compiler_gnu" >&5 ++echo "${ECHO_T}$ac_cv_f77_compiler_gnu" >&6 ++ac_ext=$ac_save_ext ++ac_test_FFLAGS=${FFLAGS+set} ++ac_save_FFLAGS=$FFLAGS ++FFLAGS= ++echo "$as_me:$LINENO: checking whether $F77 accepts -g" >&5 ++echo $ECHO_N "checking whether $F77 accepts -g... $ECHO_C" >&6 ++if test "${ac_cv_prog_f77_g+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ FFLAGS=-g ++cat >conftest.$ac_ext <<_ACEOF ++ program main ++ ++ end ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_f77_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_prog_f77_g=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_cv_prog_f77_g=no ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++ ++fi ++echo "$as_me:$LINENO: result: $ac_cv_prog_f77_g" >&5 ++echo "${ECHO_T}$ac_cv_prog_f77_g" >&6 ++if test "$ac_test_FFLAGS" = set; then ++ FFLAGS=$ac_save_FFLAGS ++elif test $ac_cv_prog_f77_g = yes; then ++ if test "x$ac_cv_f77_compiler_gnu" = xyes; then ++ FFLAGS="-g -O2" ++ else ++ FFLAGS="-g" ++ fi ++else ++ if test "x$ac_cv_f77_compiler_gnu" = xyes; then ++ FFLAGS="-O2" ++ else ++ FFLAGS= ++ fi ++fi ++ ++G77=`test $ac_compiler_gnu = yes && echo yes` ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++ ++ ++# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers! ++ ++# find the maximum length of command line arguments ++echo "$as_me:$LINENO: checking the maximum length of command line arguments" >&5 ++echo $ECHO_N "checking the maximum length of command line arguments... $ECHO_C" >&6 ++if test "${lt_cv_sys_max_cmd_len+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ i=0 ++ teststring="ABCD" ++ ++ case $build_os in ++ msdosdjgpp*) ++ # On DJGPP, this test can blow up pretty badly due to problems in libc ++ # (any single argument exceeding 2000 bytes causes a buffer overrun ++ # during glob expansion). Even if it were fixed, the result of this ++ # check would be larger than it should be. ++ lt_cv_sys_max_cmd_len=12288; # 12K is about right ++ ;; ++ ++ gnu*) ++ # Under GNU Hurd, this test is not required because there is ++ # no limit to the length of command line arguments. ++ # Libtool will interpret -1 as no limit whatsoever ++ lt_cv_sys_max_cmd_len=-1; ++ ;; ++ ++ cygwin* | mingw*) ++ # On Win9x/ME, this test blows up -- it succeeds, but takes ++ # about 5 minutes as the teststring grows exponentially. ++ # Worse, since 9x/ME are not pre-emptively multitasking, ++ # you end up with a "frozen" computer, even though with patience ++ # the test eventually succeeds (with a max line length of 256k). ++ # Instead, let's just punt: use the minimum linelength reported by ++ # all of the supported platforms: 8192 (on NT/2K/XP). ++ lt_cv_sys_max_cmd_len=8192; ++ ;; ++ ++ amigaos*) ++ # On AmigaOS with pdksh, this test takes hours, literally. ++ # So we just punt and use a minimum line length of 8192. ++ lt_cv_sys_max_cmd_len=8192; ++ ;; ++ ++ netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) ++ # This has been around since 386BSD, at least. Likely further. ++ if test -x /sbin/sysctl; then ++ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` ++ elif test -x /usr/sbin/sysctl; then ++ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` ++ else ++ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs ++ fi ++ # And add a safety zone ++ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` ++ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ++ ;; ++ ++ interix*) ++ # We know the value 262144 and hardcode it with a safety zone (like BSD) ++ lt_cv_sys_max_cmd_len=196608 ++ ;; ++ ++ osf*) ++ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure ++ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not ++ # nice to cause kernel panics so lets avoid the loop below. ++ # First set a reasonable default. ++ lt_cv_sys_max_cmd_len=16384 ++ # ++ if test -x /sbin/sysconfig; then ++ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in ++ *1*) lt_cv_sys_max_cmd_len=-1 ;; ++ esac ++ fi ++ ;; ++ sco3.2v5*) ++ lt_cv_sys_max_cmd_len=102400 ++ ;; ++ sysv5* | sco5v6* | sysv4.2uw2*) ++ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` ++ if test -n "$kargmax"; then ++ lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` ++ else ++ lt_cv_sys_max_cmd_len=32768 ++ fi ++ ;; ++ *) ++ # If test is not a shell built-in, we'll probably end up computing a ++ # maximum length that is only half of the actual maximum length, but ++ # we can't tell. ++ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} ++ while (test "X"`$SHELL $0 --fallback-echo "X$teststring" 2>/dev/null` \ ++ = "XX$teststring") >/dev/null 2>&1 && ++ new_result=`expr "X$teststring" : ".*" 2>&1` && ++ lt_cv_sys_max_cmd_len=$new_result && ++ test $i != 17 # 1/2 MB should be enough ++ do ++ i=`expr $i + 1` ++ teststring=$teststring$teststring ++ done ++ teststring= ++ # Add a significant safety factor because C++ compilers can tack on massive ++ # amounts of additional arguments before passing them to the linker. ++ # It appears as though 1/2 is a usable value. ++ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` ++ ;; ++ esac ++ ++fi ++ ++if test -n $lt_cv_sys_max_cmd_len ; then ++ echo "$as_me:$LINENO: result: $lt_cv_sys_max_cmd_len" >&5 ++echo "${ECHO_T}$lt_cv_sys_max_cmd_len" >&6 ++else ++ echo "$as_me:$LINENO: result: none" >&5 ++echo "${ECHO_T}none" >&6 ++fi ++ ++ ++ ++ ++# Check for command to grab the raw symbol name followed by C symbol from nm. ++echo "$as_me:$LINENO: checking command to parse $NM output from $compiler object" >&5 ++echo $ECHO_N "checking command to parse $NM output from $compiler object... $ECHO_C" >&6 ++if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ ++# These are sane defaults that work on at least a few old systems. ++# [They come from Ultrix. What could be older than Ultrix?!! ;)] ++ ++# Character class describing NM global symbol codes. ++symcode='[BCDEGRST]' ++ ++# Regexp to match symbols that can be accessed directly from C. ++sympat='\([_A-Za-z][_A-Za-z0-9]*\)' ++ ++# Transform an extracted symbol line into a proper C declaration ++lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'" ++ ++# Transform an extracted symbol line into symbol name and symbol address ++lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" ++ ++# Define system-specific variables. ++case $host_os in ++aix*) ++ symcode='[BCDT]' ++ ;; ++cygwin* | mingw* | pw32*) ++ symcode='[ABCDGISTW]' ++ ;; ++hpux*) # Its linker distinguishes data from code symbols ++ if test "$host_cpu" = ia64; then ++ symcode='[ABCDEGRST]' ++ fi ++ lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" ++ lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" ++ ;; ++linux*) ++ if test "$host_cpu" = ia64; then ++ symcode='[ABCDGIRSTW]' ++ lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" ++ lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" ++ fi ++ ;; ++irix* | nonstopux*) ++ symcode='[BCDEGRST]' ++ ;; ++osf*) ++ symcode='[BCDEGQRST]' ++ ;; ++solaris*) ++ symcode='[BDRT]' ++ ;; ++sco3.2v5*) ++ symcode='[DT]' ++ ;; ++sysv4.2uw2*) ++ symcode='[DT]' ++ ;; ++sysv5* | sco5v6* | unixware* | OpenUNIX*) ++ symcode='[ABDT]' ++ ;; ++sysv4) ++ symcode='[DFNSTU]' ++ ;; ++esac ++ ++# Handle CRLF in mingw tool chain ++opt_cr= ++case $build_os in ++mingw*) ++ opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp ++ ;; ++esac ++ ++# If we're using GNU nm, then use its standard symbol codes. ++case `$NM -V 2>&1` in ++*GNU* | *'with BFD'*) ++ symcode='[ABCDGIRSTW]' ;; ++esac ++ ++# Try without a prefix undercore, then with it. ++for ac_symprfx in "" "_"; do ++ ++ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. ++ symxfrm="\\1 $ac_symprfx\\2 \\2" ++ ++ # Write the raw and C identifiers. ++ lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" ++ ++ # Check to see that the pipe works correctly. ++ pipe_works=no ++ ++ rm -f conftest* ++ cat > conftest.$ac_ext <&5 ++ (eval $ac_compile) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; then ++ # Now try to grab the symbols. ++ nlist=conftest.nm ++ if { (eval echo "$as_me:$LINENO: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\"") >&5 ++ (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && test -s "$nlist"; then ++ # Try sorting and uniquifying the output. ++ if sort "$nlist" | uniq > "$nlist"T; then ++ mv -f "$nlist"T "$nlist" ++ else ++ rm -f "$nlist"T ++ fi ++ ++ # Make sure that we snagged all the symbols we need. ++ if grep ' nm_test_var$' "$nlist" >/dev/null; then ++ if grep ' nm_test_func$' "$nlist" >/dev/null; then ++ cat < conftest.$ac_ext ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++EOF ++ # Now generate the symbol file. ++ eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext' ++ ++ cat <> conftest.$ac_ext ++#if defined (__STDC__) && __STDC__ ++# define lt_ptr_t void * ++#else ++# define lt_ptr_t char * ++# define const ++#endif ++ ++/* The mapping between symbol names and symbols. */ ++const struct { ++ const char *name; ++ lt_ptr_t address; ++} ++lt_preloaded_symbols[] = ++{ ++EOF ++ $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext ++ cat <<\EOF >> conftest.$ac_ext ++ {0, (lt_ptr_t) 0} ++}; ++ ++#ifdef __cplusplus ++} ++#endif ++EOF ++ # Now try linking the two files. ++ mv conftest.$ac_objext conftstm.$ac_objext ++ lt_save_LIBS="$LIBS" ++ lt_save_CFLAGS="$CFLAGS" ++ LIBS="conftstm.$ac_objext" ++ CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" ++ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 ++ (eval $ac_link) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && test -s conftest${ac_exeext}; then ++ pipe_works=yes ++ fi ++ LIBS="$lt_save_LIBS" ++ CFLAGS="$lt_save_CFLAGS" ++ else ++ echo "cannot find nm_test_func in $nlist" >&5 ++ fi ++ else ++ echo "cannot find nm_test_var in $nlist" >&5 ++ fi ++ else ++ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 ++ fi ++ else ++ echo "$progname: failed program was:" >&5 ++ cat conftest.$ac_ext >&5 ++ fi ++ rm -f conftest* conftst* ++ ++ # Do not use the global_symbol_pipe unless it works. ++ if test "$pipe_works" = yes; then ++ break ++ else ++ lt_cv_sys_global_symbol_pipe= ++ fi ++done ++ ++fi ++ ++if test -z "$lt_cv_sys_global_symbol_pipe"; then ++ lt_cv_sys_global_symbol_to_cdecl= ++fi ++if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then ++ echo "$as_me:$LINENO: result: failed" >&5 ++echo "${ECHO_T}failed" >&6 ++else ++ echo "$as_me:$LINENO: result: ok" >&5 ++echo "${ECHO_T}ok" >&6 ++fi ++ ++echo "$as_me:$LINENO: checking for objdir" >&5 ++echo $ECHO_N "checking for objdir... $ECHO_C" >&6 ++if test "${lt_cv_objdir+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ rm -f .libs 2>/dev/null ++mkdir .libs 2>/dev/null ++if test -d .libs; then ++ lt_cv_objdir=.libs ++else ++ # MS-DOS does not allow filenames that begin with a dot. ++ lt_cv_objdir=_libs ++fi ++rmdir .libs 2>/dev/null ++fi ++echo "$as_me:$LINENO: result: $lt_cv_objdir" >&5 ++echo "${ECHO_T}$lt_cv_objdir" >&6 ++objdir=$lt_cv_objdir ++ ++ ++ ++ ++ ++case $host_os in ++aix3*) ++ # AIX sometimes has problems with the GCC collect2 program. For some ++ # reason, if we set the COLLECT_NAMES environment variable, the problems ++ # vanish in a puff of smoke. ++ if test "X${COLLECT_NAMES+set}" != Xset; then ++ COLLECT_NAMES= ++ export COLLECT_NAMES ++ fi ++ ;; ++esac ++ ++# Sed substitution that helps us do robust quoting. It backslashifies ++# metacharacters that are still active within double-quoted strings. ++Xsed='sed -e 1s/^X//' ++sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g' ++ ++# Same as above, but do not quote variable references. ++double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g' ++ ++# Sed substitution to delay expansion of an escaped shell variable in a ++# double_quote_subst'ed string. ++delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' ++ ++# Sed substitution to avoid accidental globbing in evaled expressions ++no_glob_subst='s/\*/\\\*/g' ++ ++# Constants: ++rm="rm -f" ++ ++# Global variables: ++default_ofile=libtool ++can_build_shared=yes ++ ++# All known linkers require a `.a' archive for static linking (except MSVC, ++# which needs '.lib'). ++libext=a ++ltmain="$ac_aux_dir/ltmain.sh" ++ofile="$default_ofile" ++with_gnu_ld="$lt_cv_prog_gnu_ld" ++ ++if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. ++set dummy ${ac_tool_prefix}ar; ac_word=$2 ++echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 ++if test "${ac_cv_prog_AR+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -n "$AR"; then ++ ac_cv_prog_AR="$AR" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_AR="${ac_tool_prefix}ar" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++ ++fi ++fi ++AR=$ac_cv_prog_AR ++if test -n "$AR"; then ++ echo "$as_me:$LINENO: result: $AR" >&5 ++echo "${ECHO_T}$AR" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++fi ++if test -z "$ac_cv_prog_AR"; then ++ ac_ct_AR=$AR ++ # Extract the first word of "ar", so it can be a program name with args. ++set dummy ar; ac_word=$2 ++echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 ++if test "${ac_cv_prog_ac_ct_AR+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -n "$ac_ct_AR"; then ++ ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_ac_ct_AR="ar" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++ ++ test -z "$ac_cv_prog_ac_ct_AR" && ac_cv_prog_ac_ct_AR="false" ++fi ++fi ++ac_ct_AR=$ac_cv_prog_ac_ct_AR ++if test -n "$ac_ct_AR"; then ++ echo "$as_me:$LINENO: result: $ac_ct_AR" >&5 ++echo "${ECHO_T}$ac_ct_AR" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++ AR=$ac_ct_AR ++else ++ AR="$ac_cv_prog_AR" ++fi ++ ++if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. ++set dummy ${ac_tool_prefix}ranlib; ac_word=$2 ++echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 ++if test "${ac_cv_prog_RANLIB+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -n "$RANLIB"; then ++ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++ ++fi ++fi ++RANLIB=$ac_cv_prog_RANLIB ++if test -n "$RANLIB"; then ++ echo "$as_me:$LINENO: result: $RANLIB" >&5 ++echo "${ECHO_T}$RANLIB" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++fi ++if test -z "$ac_cv_prog_RANLIB"; then ++ ac_ct_RANLIB=$RANLIB ++ # Extract the first word of "ranlib", so it can be a program name with args. ++set dummy ranlib; ac_word=$2 ++echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 ++if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -n "$ac_ct_RANLIB"; then ++ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_ac_ct_RANLIB="ranlib" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++ ++ test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":" ++fi ++fi ++ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB ++if test -n "$ac_ct_RANLIB"; then ++ echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 ++echo "${ECHO_T}$ac_ct_RANLIB" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++ RANLIB=$ac_ct_RANLIB ++else ++ RANLIB="$ac_cv_prog_RANLIB" ++fi ++ ++if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. ++set dummy ${ac_tool_prefix}strip; ac_word=$2 ++echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 ++if test "${ac_cv_prog_STRIP+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -n "$STRIP"; then ++ ac_cv_prog_STRIP="$STRIP" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_STRIP="${ac_tool_prefix}strip" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++ ++fi ++fi ++STRIP=$ac_cv_prog_STRIP ++if test -n "$STRIP"; then ++ echo "$as_me:$LINENO: result: $STRIP" >&5 ++echo "${ECHO_T}$STRIP" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++fi ++if test -z "$ac_cv_prog_STRIP"; then ++ ac_ct_STRIP=$STRIP ++ # Extract the first word of "strip", so it can be a program name with args. ++set dummy strip; ac_word=$2 ++echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 ++if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -n "$ac_ct_STRIP"; then ++ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_ac_ct_STRIP="strip" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++ ++ test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":" ++fi ++fi ++ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP ++if test -n "$ac_ct_STRIP"; then ++ echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 ++echo "${ECHO_T}$ac_ct_STRIP" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++ STRIP=$ac_ct_STRIP ++else ++ STRIP="$ac_cv_prog_STRIP" ++fi ++ ++ ++old_CC="$CC" ++old_CFLAGS="$CFLAGS" ++ ++# Set sane defaults for various variables ++test -z "$AR" && AR=ar ++test -z "$AR_FLAGS" && AR_FLAGS=cru ++test -z "$AS" && AS=as ++test -z "$CC" && CC=cc ++test -z "$LTCC" && LTCC=$CC ++test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS ++test -z "$DLLTOOL" && DLLTOOL=dlltool ++test -z "$LD" && LD=ld ++test -z "$LN_S" && LN_S="ln -s" ++test -z "$MAGIC_CMD" && MAGIC_CMD=file ++test -z "$NM" && NM=nm ++test -z "$SED" && SED=sed ++test -z "$OBJDUMP" && OBJDUMP=objdump ++test -z "$RANLIB" && RANLIB=: ++test -z "$STRIP" && STRIP=: ++test -z "$ac_objext" && ac_objext=o ++ ++# Determine commands to create old-style static archives. ++old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs' ++old_postinstall_cmds='chmod 644 $oldlib' ++old_postuninstall_cmds= ++ ++if test -n "$RANLIB"; then ++ case $host_os in ++ openbsd*) ++ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" ++ ;; ++ *) ++ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" ++ ;; ++ esac ++ old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" ++fi ++ ++for cc_temp in $compiler""; do ++ case $cc_temp in ++ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; ++ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; ++ \-*) ;; ++ *) break;; ++ esac ++done ++cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` ++ ++ ++# Only perform the check for file, if the check method requires it ++case $deplibs_check_method in ++file_magic*) ++ if test "$file_magic_cmd" = '$MAGIC_CMD'; then ++ echo "$as_me:$LINENO: checking for ${ac_tool_prefix}file" >&5 ++echo $ECHO_N "checking for ${ac_tool_prefix}file... $ECHO_C" >&6 ++if test "${lt_cv_path_MAGIC_CMD+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ case $MAGIC_CMD in ++[\\/*] | ?:[\\/]*) ++ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ++ ;; ++*) ++ lt_save_MAGIC_CMD="$MAGIC_CMD" ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" ++ for ac_dir in $ac_dummy; do ++ IFS="$lt_save_ifs" ++ test -z "$ac_dir" && ac_dir=. ++ if test -f $ac_dir/${ac_tool_prefix}file; then ++ lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" ++ if test -n "$file_magic_test_file"; then ++ case $deplibs_check_method in ++ "file_magic "*) ++ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` ++ MAGIC_CMD="$lt_cv_path_MAGIC_CMD" ++ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | ++ $EGREP "$file_magic_regex" > /dev/null; then ++ : ++ else ++ cat <&2 ++ ++*** Warning: the command libtool uses to detect shared libraries, ++*** $file_magic_cmd, produces output that libtool cannot recognize. ++*** The result is that libtool may fail to recognize shared libraries ++*** as such. This will affect the creation of libtool libraries that ++*** depend on shared libraries, but programs linked with such libtool ++*** libraries will work regardless of this problem. Nevertheless, you ++*** may want to report the problem to your system manager and/or to ++*** bug-libtool@gnu.org ++ ++EOF ++ fi ;; ++ esac ++ fi ++ break ++ fi ++ done ++ IFS="$lt_save_ifs" ++ MAGIC_CMD="$lt_save_MAGIC_CMD" ++ ;; ++esac ++fi ++ ++MAGIC_CMD="$lt_cv_path_MAGIC_CMD" ++if test -n "$MAGIC_CMD"; then ++ echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5 ++echo "${ECHO_T}$MAGIC_CMD" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++if test -z "$lt_cv_path_MAGIC_CMD"; then ++ if test -n "$ac_tool_prefix"; then ++ echo "$as_me:$LINENO: checking for file" >&5 ++echo $ECHO_N "checking for file... $ECHO_C" >&6 ++if test "${lt_cv_path_MAGIC_CMD+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ case $MAGIC_CMD in ++[\\/*] | ?:[\\/]*) ++ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ++ ;; ++*) ++ lt_save_MAGIC_CMD="$MAGIC_CMD" ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" ++ for ac_dir in $ac_dummy; do ++ IFS="$lt_save_ifs" ++ test -z "$ac_dir" && ac_dir=. ++ if test -f $ac_dir/file; then ++ lt_cv_path_MAGIC_CMD="$ac_dir/file" ++ if test -n "$file_magic_test_file"; then ++ case $deplibs_check_method in ++ "file_magic "*) ++ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` ++ MAGIC_CMD="$lt_cv_path_MAGIC_CMD" ++ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | ++ $EGREP "$file_magic_regex" > /dev/null; then ++ : ++ else ++ cat <&2 ++ ++*** Warning: the command libtool uses to detect shared libraries, ++*** $file_magic_cmd, produces output that libtool cannot recognize. ++*** The result is that libtool may fail to recognize shared libraries ++*** as such. This will affect the creation of libtool libraries that ++*** depend on shared libraries, but programs linked with such libtool ++*** libraries will work regardless of this problem. Nevertheless, you ++*** may want to report the problem to your system manager and/or to ++*** bug-libtool@gnu.org ++ ++EOF ++ fi ;; ++ esac ++ fi ++ break ++ fi ++ done ++ IFS="$lt_save_ifs" ++ MAGIC_CMD="$lt_save_MAGIC_CMD" ++ ;; ++esac ++fi ++ ++MAGIC_CMD="$lt_cv_path_MAGIC_CMD" ++if test -n "$MAGIC_CMD"; then ++ echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5 ++echo "${ECHO_T}$MAGIC_CMD" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++ else ++ MAGIC_CMD=: ++ fi ++fi ++ ++ fi ++ ;; ++esac ++ ++enable_dlopen=yes ++enable_win32_dll=no ++ ++# Check whether --enable-libtool-lock or --disable-libtool-lock was given. ++if test "${enable_libtool_lock+set}" = set; then ++ enableval="$enable_libtool_lock" ++ ++fi; ++test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes ++ ++ ++# Check whether --with-pic or --without-pic was given. ++if test "${with_pic+set}" = set; then ++ withval="$with_pic" ++ pic_mode="$withval" ++else ++ pic_mode=default ++fi; ++test -z "$pic_mode" && pic_mode=default ++ ++# Use C for the default configuration in the libtool script ++tagname= ++lt_save_CC="$CC" ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++ ++# Source file extension for C test sources. ++ac_ext=c ++ ++# Object file extension for compiled C test sources. ++objext=o ++objext=$objext ++ ++# Code to be used in simple compile tests ++lt_simple_compile_test_code="int some_variable = 0;\n" ++ ++# Code to be used in simple link tests ++lt_simple_link_test_code='int main(){return(0);}\n' ++ ++ ++# If no C compiler was specified, use CC. ++LTCC=${LTCC-"$CC"} ++ ++# If no C compiler flags were specified, use CFLAGS. ++LTCFLAGS=${LTCFLAGS-"$CFLAGS"} ++ ++# Allow CC to be a program name with arguments. ++compiler=$CC ++ ++ ++# save warnings/boilerplate of simple test code ++ac_outfile=conftest.$ac_objext ++printf "$lt_simple_compile_test_code" >conftest.$ac_ext ++eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err ++_lt_compiler_boilerplate=`cat conftest.err` ++$rm conftest* ++ ++ac_outfile=conftest.$ac_objext ++printf "$lt_simple_link_test_code" >conftest.$ac_ext ++eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err ++_lt_linker_boilerplate=`cat conftest.err` ++$rm conftest* ++ ++ ++ ++lt_prog_compiler_no_builtin_flag= ++ ++if test "$GCC" = yes; then ++ lt_prog_compiler_no_builtin_flag=' -fno-builtin' ++ ++ ++echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 ++echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6 ++if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ lt_cv_prog_compiler_rtti_exceptions=no ++ ac_outfile=conftest.$ac_objext ++ printf "$lt_simple_compile_test_code" > conftest.$ac_ext ++ lt_compiler_flag="-fno-rtti -fno-exceptions" ++ # Insert the option either (1) after the last *FLAGS variable, or ++ # (2) before a word containing "conftest.", or (3) at the end. ++ # Note that $ac_compile itself does not contain backslashes and begins ++ # with a dollar sign (not a hyphen), so the echo should work correctly. ++ # The option is referenced via a variable to avoid confusing sed. ++ lt_compile=`echo "$ac_compile" | $SED \ ++ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ ++ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ ++ -e 's:$: $lt_compiler_flag:'` ++ (eval echo "\"\$as_me:9015: $lt_compile\"" >&5) ++ (eval "$lt_compile" 2>conftest.err) ++ ac_status=$? ++ cat conftest.err >&5 ++ echo "$as_me:9019: \$? = $ac_status" >&5 ++ if (exit $ac_status) && test -s "$ac_outfile"; then ++ # The compiler can only warn and ignore the option if not recognized ++ # So say no if there are warnings other than the usual output. ++ $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp ++ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 ++ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then ++ lt_cv_prog_compiler_rtti_exceptions=yes ++ fi ++ fi ++ $rm conftest* ++ ++fi ++echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 ++echo "${ECHO_T}$lt_cv_prog_compiler_rtti_exceptions" >&6 ++ ++if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then ++ lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" ++else ++ : ++fi ++ ++fi ++ ++lt_prog_compiler_wl= ++lt_prog_compiler_pic= ++lt_prog_compiler_static= ++ ++echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 ++echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 ++ ++ if test "$GCC" = yes; then ++ lt_prog_compiler_wl='-Wl,' ++ lt_prog_compiler_static='-static' ++ ++ case $host_os in ++ aix*) ++ # All AIX code is PIC. ++ if test "$host_cpu" = ia64; then ++ # AIX 5 now supports IA64 processor ++ lt_prog_compiler_static='-Bstatic' ++ fi ++ ;; ++ ++ amigaos*) ++ # FIXME: we need at least 68020 code to build shared libraries, but ++ # adding the `-m68020' flag to GCC prevents building anything better, ++ # like `-m68040'. ++ lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' ++ ;; ++ ++ beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) ++ # PIC is the default for these OSes. ++ ;; ++ ++ mingw* | pw32* | os2*) ++ # This hack is so that the source file can tell whether it is being ++ # built for inclusion in a dll (and should export symbols for example). ++ lt_prog_compiler_pic='-DDLL_EXPORT' ++ ;; ++ ++ darwin* | rhapsody*) ++ # PIC is the default on this platform ++ # Common symbols not allowed in MH_DYLIB files ++ lt_prog_compiler_pic='-fno-common' ++ ;; ++ ++ interix3*) ++ # Interix 3.x gcc -fpic/-fPIC options generate broken code. ++ # Instead, we relocate shared libraries at runtime. ++ ;; ++ ++ msdosdjgpp*) ++ # Just because we use GCC doesn't mean we suddenly get shared libraries ++ # on systems that don't support them. ++ lt_prog_compiler_can_build_shared=no ++ enable_shared=no ++ ;; ++ ++ sysv4*MP*) ++ if test -d /usr/nec; then ++ lt_prog_compiler_pic=-Kconform_pic ++ fi ++ ;; ++ ++ hpux*) ++ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but ++ # not for PA HP-UX. ++ case $host_cpu in ++ hppa*64*|ia64*) ++ # +Z the default ++ ;; ++ *) ++ lt_prog_compiler_pic='-fPIC' ++ ;; ++ esac ++ ;; ++ ++ *) ++ lt_prog_compiler_pic='-fPIC' ++ ;; ++ esac ++ else ++ # PORTME Check for flag to pass linker flags through the system compiler. ++ case $host_os in ++ aix*) ++ lt_prog_compiler_wl='-Wl,' ++ if test "$host_cpu" = ia64; then ++ # AIX 5 now supports IA64 processor ++ lt_prog_compiler_static='-Bstatic' ++ else ++ lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' ++ fi ++ ;; ++ darwin*) ++ # PIC is the default on this platform ++ # Common symbols not allowed in MH_DYLIB files ++ case $cc_basename in ++ xlc*) ++ lt_prog_compiler_pic='-qnocommon' ++ lt_prog_compiler_wl='-Wl,' ++ ;; ++ esac ++ ;; ++ ++ mingw* | pw32* | os2*) ++ # This hack is so that the source file can tell whether it is being ++ # built for inclusion in a dll (and should export symbols for example). ++ lt_prog_compiler_pic='-DDLL_EXPORT' ++ ;; ++ ++ hpux9* | hpux10* | hpux11*) ++ lt_prog_compiler_wl='-Wl,' ++ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but ++ # not for PA HP-UX. ++ case $host_cpu in ++ hppa*64*|ia64*) ++ # +Z the default ++ ;; ++ *) ++ lt_prog_compiler_pic='+Z' ++ ;; ++ esac ++ # Is there a better lt_prog_compiler_static that works with the bundled CC? ++ lt_prog_compiler_static='${wl}-a ${wl}archive' ++ ;; ++ ++ irix5* | irix6* | nonstopux*) ++ lt_prog_compiler_wl='-Wl,' ++ # PIC (with -KPIC) is the default. ++ lt_prog_compiler_static='-non_shared' ++ ;; ++ ++ newsos6) ++ lt_prog_compiler_pic='-KPIC' ++ lt_prog_compiler_static='-Bstatic' ++ ;; ++ ++ linux*) ++ case $cc_basename in ++ icc* | ecc*) ++ lt_prog_compiler_wl='-Wl,' ++ lt_prog_compiler_pic='-KPIC' ++ lt_prog_compiler_static='-static' ++ ;; ++ pgcc* | pgf77* | pgf90* | pgf95*) ++ # Portland Group compilers (*not* the Pentium gcc compiler, ++ # which looks to be a dead project) ++ lt_prog_compiler_wl='-Wl,' ++ lt_prog_compiler_pic='-fpic' ++ lt_prog_compiler_static='-Bstatic' ++ ;; ++ ccc*) ++ lt_prog_compiler_wl='-Wl,' ++ # All Alpha code is PIC. ++ lt_prog_compiler_static='-non_shared' ++ ;; ++ esac ++ ;; ++ ++ osf3* | osf4* | osf5*) ++ lt_prog_compiler_wl='-Wl,' ++ # All OSF/1 code is PIC. ++ lt_prog_compiler_static='-non_shared' ++ ;; ++ ++ solaris*) ++ lt_prog_compiler_pic='-KPIC' ++ lt_prog_compiler_static='-Bstatic' ++ case $cc_basename in ++ f77* | f90* | f95*) ++ lt_prog_compiler_wl='-Qoption ld ';; ++ *) ++ lt_prog_compiler_wl='-Wl,';; ++ esac ++ ;; ++ ++ sunos4*) ++ lt_prog_compiler_wl='-Qoption ld ' ++ lt_prog_compiler_pic='-PIC' ++ lt_prog_compiler_static='-Bstatic' ++ ;; ++ ++ sysv4 | sysv4.2uw2* | sysv4.3*) ++ lt_prog_compiler_wl='-Wl,' ++ lt_prog_compiler_pic='-KPIC' ++ lt_prog_compiler_static='-Bstatic' ++ ;; ++ ++ sysv4*MP*) ++ if test -d /usr/nec ;then ++ lt_prog_compiler_pic='-Kconform_pic' ++ lt_prog_compiler_static='-Bstatic' ++ fi ++ ;; ++ ++ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) ++ lt_prog_compiler_wl='-Wl,' ++ lt_prog_compiler_pic='-KPIC' ++ lt_prog_compiler_static='-Bstatic' ++ ;; ++ ++ unicos*) ++ lt_prog_compiler_wl='-Wl,' ++ lt_prog_compiler_can_build_shared=no ++ ;; ++ ++ uts4*) ++ lt_prog_compiler_pic='-pic' ++ lt_prog_compiler_static='-Bstatic' ++ ;; ++ ++ *) ++ lt_prog_compiler_can_build_shared=no ++ ;; ++ esac ++ fi ++ ++echo "$as_me:$LINENO: result: $lt_prog_compiler_pic" >&5 ++echo "${ECHO_T}$lt_prog_compiler_pic" >&6 ++ ++# ++# Check to make sure the PIC flag actually works. ++# ++if test -n "$lt_prog_compiler_pic"; then ++ ++echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 ++echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic works... $ECHO_C" >&6 ++if test "${lt_prog_compiler_pic_works+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ lt_prog_compiler_pic_works=no ++ ac_outfile=conftest.$ac_objext ++ printf "$lt_simple_compile_test_code" > conftest.$ac_ext ++ lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ++ # Insert the option either (1) after the last *FLAGS variable, or ++ # (2) before a word containing "conftest.", or (3) at the end. ++ # Note that $ac_compile itself does not contain backslashes and begins ++ # with a dollar sign (not a hyphen), so the echo should work correctly. ++ # The option is referenced via a variable to avoid confusing sed. ++ lt_compile=`echo "$ac_compile" | $SED \ ++ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ ++ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ ++ -e 's:$: $lt_compiler_flag:'` ++ (eval echo "\"\$as_me:9283: $lt_compile\"" >&5) ++ (eval "$lt_compile" 2>conftest.err) ++ ac_status=$? ++ cat conftest.err >&5 ++ echo "$as_me:9287: \$? = $ac_status" >&5 ++ if (exit $ac_status) && test -s "$ac_outfile"; then ++ # The compiler can only warn and ignore the option if not recognized ++ # So say no if there are warnings other than the usual output. ++ $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp ++ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 ++ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then ++ lt_prog_compiler_pic_works=yes ++ fi ++ fi ++ $rm conftest* ++ ++fi ++echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works" >&5 ++echo "${ECHO_T}$lt_prog_compiler_pic_works" >&6 ++ ++if test x"$lt_prog_compiler_pic_works" = xyes; then ++ case $lt_prog_compiler_pic in ++ "" | " "*) ;; ++ *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; ++ esac ++else ++ lt_prog_compiler_pic= ++ lt_prog_compiler_can_build_shared=no ++fi ++ ++fi ++case $host_os in ++ # For platforms which do not support PIC, -DPIC is meaningless: ++ *djgpp*) ++ lt_prog_compiler_pic= ++ ;; ++ *) ++ lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" ++ ;; ++esac ++ ++# ++# Check to make sure the static flag actually works. ++# ++wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" ++echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 ++echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6 ++if test "${lt_prog_compiler_static_works+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ lt_prog_compiler_static_works=no ++ save_LDFLAGS="$LDFLAGS" ++ LDFLAGS="$LDFLAGS $lt_tmp_static_flag" ++ printf "$lt_simple_link_test_code" > conftest.$ac_ext ++ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then ++ # The linker can only warn and ignore the option if not recognized ++ # So say no if there are warnings ++ if test -s conftest.err; then ++ # Append any errors to the config.log. ++ cat conftest.err 1>&5 ++ $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp ++ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 ++ if diff conftest.exp conftest.er2 >/dev/null; then ++ lt_prog_compiler_static_works=yes ++ fi ++ else ++ lt_prog_compiler_static_works=yes ++ fi ++ fi ++ $rm conftest* ++ LDFLAGS="$save_LDFLAGS" ++ ++fi ++echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works" >&5 ++echo "${ECHO_T}$lt_prog_compiler_static_works" >&6 ++ ++if test x"$lt_prog_compiler_static_works" = xyes; then ++ : ++else ++ lt_prog_compiler_static= ++fi ++ ++ ++echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 ++echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6 ++if test "${lt_cv_prog_compiler_c_o+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ lt_cv_prog_compiler_c_o=no ++ $rm -r conftest 2>/dev/null ++ mkdir conftest ++ cd conftest ++ mkdir out ++ printf "$lt_simple_compile_test_code" > conftest.$ac_ext ++ ++ lt_compiler_flag="-o out/conftest2.$ac_objext" ++ # Insert the option either (1) after the last *FLAGS variable, or ++ # (2) before a word containing "conftest.", or (3) at the end. ++ # Note that $ac_compile itself does not contain backslashes and begins ++ # with a dollar sign (not a hyphen), so the echo should work correctly. ++ lt_compile=`echo "$ac_compile" | $SED \ ++ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ ++ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ ++ -e 's:$: $lt_compiler_flag:'` ++ (eval echo "\"\$as_me:9387: $lt_compile\"" >&5) ++ (eval "$lt_compile" 2>out/conftest.err) ++ ac_status=$? ++ cat out/conftest.err >&5 ++ echo "$as_me:9391: \$? = $ac_status" >&5 ++ if (exit $ac_status) && test -s out/conftest2.$ac_objext ++ then ++ # The compiler can only warn and ignore the option if not recognized ++ # So say no if there are warnings ++ $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp ++ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 ++ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then ++ lt_cv_prog_compiler_c_o=yes ++ fi ++ fi ++ chmod u+w . 2>&5 ++ $rm conftest* ++ # SGI C++ compiler will create directory out/ii_files/ for ++ # template instantiation ++ test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files ++ $rm out/* && rmdir out ++ cd .. ++ rmdir conftest ++ $rm conftest* ++ ++fi ++echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o" >&5 ++echo "${ECHO_T}$lt_cv_prog_compiler_c_o" >&6 ++ ++ ++hard_links="nottested" ++if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then ++ # do not overwrite the value of need_locks provided by the user ++ echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 ++echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6 ++ hard_links=yes ++ $rm conftest* ++ ln conftest.a conftest.b 2>/dev/null && hard_links=no ++ touch conftest.a ++ ln conftest.a conftest.b 2>&5 || hard_links=no ++ ln conftest.a conftest.b 2>/dev/null && hard_links=no ++ echo "$as_me:$LINENO: result: $hard_links" >&5 ++echo "${ECHO_T}$hard_links" >&6 ++ if test "$hard_links" = no; then ++ { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 ++echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} ++ need_locks=warn ++ fi ++else ++ need_locks=no ++fi ++ ++echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 ++echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6 ++ ++ runpath_var= ++ allow_undefined_flag= ++ enable_shared_with_static_runtimes=no ++ archive_cmds= ++ archive_expsym_cmds= ++ old_archive_From_new_cmds= ++ old_archive_from_expsyms_cmds= ++ export_dynamic_flag_spec= ++ whole_archive_flag_spec= ++ thread_safe_flag_spec= ++ hardcode_libdir_flag_spec= ++ hardcode_libdir_flag_spec_ld= ++ hardcode_libdir_separator= ++ hardcode_direct=no ++ hardcode_minus_L=no ++ hardcode_shlibpath_var=unsupported ++ link_all_deplibs=unknown ++ hardcode_automatic=no ++ module_cmds= ++ module_expsym_cmds= ++ always_export_symbols=no ++ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ++ # include_expsyms should be a list of space-separated symbols to be *always* ++ # included in the symbol list ++ include_expsyms= ++ # exclude_expsyms can be an extended regexp of symbols to exclude ++ # it will be wrapped by ` (' and `)$', so one must not match beginning or ++ # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', ++ # as well as any symbol that contains `d'. ++ exclude_expsyms="_GLOBAL_OFFSET_TABLE_" ++ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out ++ # platforms (ab)use it in PIC code, but their linkers get confused if ++ # the symbol is explicitly referenced. Since portable code cannot ++ # rely on this symbol name, it's probably fine to never include it in ++ # preloaded symbol tables. ++ extract_expsyms_cmds= ++ # Just being paranoid about ensuring that cc_basename is set. ++ for cc_temp in $compiler""; do ++ case $cc_temp in ++ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; ++ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; ++ \-*) ;; ++ *) break;; ++ esac ++done ++cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` ++ ++ case $host_os in ++ cygwin* | mingw* | pw32*) ++ # FIXME: the MSVC++ port hasn't been tested in a loooong time ++ # When not using gcc, we currently assume that we are using ++ # Microsoft Visual C++. ++ if test "$GCC" != yes; then ++ with_gnu_ld=no ++ fi ++ ;; ++ interix*) ++ # we just hope/assume this is gcc and not c89 (= MSVC++) ++ with_gnu_ld=yes ++ ;; ++ openbsd*) ++ with_gnu_ld=no ++ ;; ++ esac ++ ++ ld_shlibs=yes ++ if test "$with_gnu_ld" = yes; then ++ # If archive_cmds runs LD, not CC, wlarc should be empty ++ wlarc='${wl}' ++ ++ # Set some defaults for GNU ld with shared library support. These ++ # are reset later if shared libraries are not supported. Putting them ++ # here allows them to be overridden if necessary. ++ runpath_var=LD_RUN_PATH ++ hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir' ++ export_dynamic_flag_spec='${wl}--export-dynamic' ++ # ancient GNU ld didn't support --whole-archive et. al. ++ if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then ++ whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' ++ else ++ whole_archive_flag_spec= ++ fi ++ supports_anon_versioning=no ++ case `$LD -v 2>/dev/null` in ++ *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 ++ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... ++ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... ++ *\ 2.11.*) ;; # other 2.11 versions ++ *) supports_anon_versioning=yes ;; ++ esac ++ ++ # See if GNU ld supports shared libraries. ++ case $host_os in ++ aix3* | aix4* | aix5*) ++ # On AIX/PPC, the GNU linker is very broken ++ if test "$host_cpu" != ia64; then ++ ld_shlibs=no ++ cat <&2 ++ ++*** Warning: the GNU linker, at least up to release 2.9.1, is reported ++*** to be unable to reliably create shared libraries on AIX. ++*** Therefore, libtool is disabling shared libraries support. If you ++*** really care for shared libraries, you may want to modify your PATH ++*** so that a non-GNU linker is found, and then restart. ++ ++EOF ++ fi ++ ;; ++ ++ amigaos*) ++ archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' ++ hardcode_libdir_flag_spec='-L$libdir' ++ hardcode_minus_L=yes ++ ++ # Samuel A. Falvo II reports ++ # that the semantics of dynamic libraries on AmigaOS, at least up ++ # to version 4, is to share data among multiple programs linked ++ # with the same dynamic library. Since this doesn't match the ++ # behavior of shared libraries on other platforms, we can't use ++ # them. ++ ld_shlibs=no ++ ;; ++ ++ beos*) ++ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then ++ allow_undefined_flag=unsupported ++ # Joseph Beckenbach says some releases of gcc ++ # support --undefined. This deserves some investigation. FIXME ++ archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ else ++ ld_shlibs=no ++ fi ++ ;; ++ ++ cygwin* | mingw* | pw32*) ++ # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, ++ # as there is no search path for DLLs. ++ hardcode_libdir_flag_spec='-L$libdir' ++ allow_undefined_flag=unsupported ++ always_export_symbols=no ++ enable_shared_with_static_runtimes=yes ++ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' ++ ++ if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' ++ # If the export-symbols file already is a .def file (1st line ++ # is EXPORTS), use it as is; otherwise, prepend... ++ archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then ++ cp $export_symbols $output_objdir/$soname.def; ++ else ++ echo EXPORTS > $output_objdir/$soname.def; ++ cat $export_symbols >> $output_objdir/$soname.def; ++ fi~ ++ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' ++ else ++ ld_shlibs=no ++ fi ++ ;; ++ ++ interix3*) ++ hardcode_direct=no ++ hardcode_shlibpath_var=no ++ hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ++ export_dynamic_flag_spec='${wl}-E' ++ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. ++ # Instead, shared libraries are loaded at an image base (0x10000000 by ++ # default) and relocated if they conflict, which is a slow very memory ++ # consuming and fragmenting process. To avoid this, we pick a random, ++ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link ++ # time. Moving up from 0x10000000 also allows more sbrk(2) space. ++ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ++ archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ++ ;; ++ ++ linux*) ++ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then ++ tmp_addflag= ++ case $cc_basename,$host_cpu in ++ pgcc*) # Portland Group C compiler ++ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' ++ tmp_addflag=' $pic_flag' ++ ;; ++ pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers ++ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' ++ tmp_addflag=' $pic_flag -Mnomain' ;; ++ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 ++ tmp_addflag=' -i_dynamic' ;; ++ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 ++ tmp_addflag=' -i_dynamic -nofor_main' ;; ++ ifc* | ifort*) # Intel Fortran compiler ++ tmp_addflag=' -nofor_main' ;; ++ esac ++ archive_cmds='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ ++ if test $supports_anon_versioning = yes; then ++ archive_expsym_cmds='$echo "{ global:" > $output_objdir/$libname.ver~ ++ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ ++ $echo "local: *; };" >> $output_objdir/$libname.ver~ ++ $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' ++ fi ++ else ++ ld_shlibs=no ++ fi ++ ;; ++ ++ netbsd*) ++ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then ++ archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' ++ wlarc= ++ else ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ fi ++ ;; ++ ++ solaris*) ++ if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then ++ ld_shlibs=no ++ cat <&2 ++ ++*** Warning: The releases 2.8.* of the GNU linker cannot reliably ++*** create shared libraries on Solaris systems. Therefore, libtool ++*** is disabling shared libraries support. We urge you to upgrade GNU ++*** binutils to release 2.9.1 or newer. Another option is to modify ++*** your PATH or compiler configuration so that the native linker is ++*** used, and then restart. ++ ++EOF ++ elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ else ++ ld_shlibs=no ++ fi ++ ;; ++ ++ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) ++ case `$LD -v 2>&1` in ++ *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ++ ld_shlibs=no ++ cat <<_LT_EOF 1>&2 ++ ++*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not ++*** reliably create shared libraries on SCO systems. Therefore, libtool ++*** is disabling shared libraries support. We urge you to upgrade GNU ++*** binutils to release 2.16.91.0.3 or newer. Another option is to modify ++*** your PATH or compiler configuration so that the native linker is ++*** used, and then restart. ++ ++_LT_EOF ++ ;; ++ *) ++ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then ++ hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib' ++ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' ++ else ++ ld_shlibs=no ++ fi ++ ;; ++ esac ++ ;; ++ ++ sunos4*) ++ archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' ++ wlarc= ++ hardcode_direct=yes ++ hardcode_shlibpath_var=no ++ ;; ++ ++ *) ++ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ else ++ ld_shlibs=no ++ fi ++ ;; ++ esac ++ ++ if test "$ld_shlibs" = no; then ++ runpath_var= ++ hardcode_libdir_flag_spec= ++ export_dynamic_flag_spec= ++ whole_archive_flag_spec= ++ fi ++ else ++ # PORTME fill in a description of your system's linker (not GNU ld) ++ case $host_os in ++ aix3*) ++ allow_undefined_flag=unsupported ++ always_export_symbols=yes ++ archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' ++ # Note: this linker hardcodes the directories in LIBPATH if there ++ # are no directories specified by -L. ++ hardcode_minus_L=yes ++ if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then ++ # Neither direct hardcoding nor static linking is supported with a ++ # broken collect2. ++ hardcode_direct=unsupported ++ fi ++ ;; ++ ++ aix4* | aix5*) ++ if test "$host_cpu" = ia64; then ++ # On IA64, the linker does run time linking by default, so we don't ++ # have to do anything special. ++ aix_use_runtimelinking=no ++ exp_sym_flag='-Bexport' ++ no_entry_flag="" ++ else ++ # If we're using GNU nm, then we don't want the "-C" option. ++ # -C means demangle to AIX nm, but means don't demangle with GNU nm ++ if $NM -V 2>&1 | grep 'GNU' > /dev/null; then ++ export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' ++ else ++ export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' ++ fi ++ aix_use_runtimelinking=no ++ ++ # Test if we are trying to use run time linking or normal ++ # AIX style linking. If -brtl is somewhere in LDFLAGS, we ++ # need to do runtime linking. ++ case $host_os in aix4.[23]|aix4.[23].*|aix5*) ++ for ld_flag in $LDFLAGS; do ++ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then ++ aix_use_runtimelinking=yes ++ break ++ fi ++ done ++ ;; ++ esac ++ ++ exp_sym_flag='-bexport' ++ no_entry_flag='-bnoentry' ++ fi ++ ++ # When large executables or shared objects are built, AIX ld can ++ # have problems creating the table of contents. If linking a library ++ # or program results in "error TOC overflow" add -mminimal-toc to ++ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not ++ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. ++ ++ archive_cmds='' ++ hardcode_direct=yes ++ hardcode_libdir_separator=':' ++ link_all_deplibs=yes ++ ++ if test "$GCC" = yes; then ++ case $host_os in aix4.[012]|aix4.[012].*) ++ # We only want to do this on AIX 4.2 and lower, the check ++ # below for broken collect2 doesn't work under 4.3+ ++ collect2name=`${CC} -print-prog-name=collect2` ++ if test -f "$collect2name" && \ ++ strings "$collect2name" | grep resolve_lib_name >/dev/null ++ then ++ # We have reworked collect2 ++ hardcode_direct=yes ++ else ++ # We have old collect2 ++ hardcode_direct=unsupported ++ # It fails to find uninstalled libraries when the uninstalled ++ # path is not listed in the libpath. Setting hardcode_minus_L ++ # to unsupported forces relinking ++ hardcode_minus_L=yes ++ hardcode_libdir_flag_spec='-L$libdir' ++ hardcode_libdir_separator= ++ fi ++ ;; ++ esac ++ shared_flag='-shared' ++ if test "$aix_use_runtimelinking" = yes; then ++ shared_flag="$shared_flag "'${wl}-G' ++ fi ++ else ++ # not using gcc ++ if test "$host_cpu" = ia64; then ++ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release ++ # chokes on -Wl,-G. The following line is correct: ++ shared_flag='-G' ++ else ++ if test "$aix_use_runtimelinking" = yes; then ++ shared_flag='${wl}-G' ++ else ++ shared_flag='${wl}-bM:SRE' ++ fi ++ fi ++ fi ++ ++ # It seems that -bexpall does not export symbols beginning with ++ # underscore (_), so it is better to generate a list of symbols to export. ++ always_export_symbols=yes ++ if test "$aix_use_runtimelinking" = yes; then ++ # Warning - without using the other runtime loading flags (-brtl), ++ # -berok will link without error, but may produce a broken library. ++ allow_undefined_flag='-berok' ++ # Determine the default libpath from the value encoded in an empty executable. ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext conftest$ac_exeext ++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 ++ (eval $ac_link) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest$ac_exeext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ++aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } ++}'` ++# Check for a 64-bit object if we didn't find anything. ++if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } ++}'`; fi ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++fi ++rm -f conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ++ ++ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" ++ archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" ++ else ++ if test "$host_cpu" = ia64; then ++ hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' ++ allow_undefined_flag="-z nodefs" ++ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" ++ else ++ # Determine the default libpath from the value encoded in an empty executable. ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext conftest$ac_exeext ++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 ++ (eval $ac_link) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest$ac_exeext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ++aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } ++}'` ++# Check for a 64-bit object if we didn't find anything. ++if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } ++}'`; fi ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++fi ++rm -f conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ++ ++ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" ++ # Warning - without using the other run time loading flags, ++ # -berok will link without error, but may produce a broken library. ++ no_undefined_flag=' ${wl}-bernotok' ++ allow_undefined_flag=' ${wl}-berok' ++ # Exported symbols can be pulled into shared objects from archives ++ whole_archive_flag_spec='$convenience' ++ archive_cmds_need_lc=yes ++ # This is similar to how AIX traditionally builds its shared libraries. ++ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' ++ fi ++ fi ++ ;; ++ ++ amigaos*) ++ archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' ++ hardcode_libdir_flag_spec='-L$libdir' ++ hardcode_minus_L=yes ++ # see comment about different semantics on the GNU ld section ++ ld_shlibs=no ++ ;; ++ ++ bsdi[45]*) ++ export_dynamic_flag_spec=-rdynamic ++ ;; ++ ++ cygwin* | mingw* | pw32*) ++ # When not using gcc, we currently assume that we are using ++ # Microsoft Visual C++. ++ # hardcode_libdir_flag_spec is actually meaningless, as there is ++ # no search path for DLLs. ++ hardcode_libdir_flag_spec=' ' ++ allow_undefined_flag=unsupported ++ # Tell ltmain to make .lib files, not .a files. ++ libext=lib ++ # Tell ltmain to make .dll files, not .so files. ++ shrext_cmds=".dll" ++ # FIXME: Setting linknames here is a bad hack. ++ archive_cmds='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' ++ # The linker will automatically build a .lib file if we build a DLL. ++ old_archive_From_new_cmds='true' ++ # FIXME: Should let the user specify the lib program. ++ old_archive_cmds='lib /OUT:$oldlib$oldobjs$old_deplibs' ++ fix_srcfile_path='`cygpath -w "$srcfile"`' ++ enable_shared_with_static_runtimes=yes ++ ;; ++ ++ darwin* | rhapsody*) ++ case $host_os in ++ rhapsody* | darwin1.[012]) ++ allow_undefined_flag='${wl}-undefined ${wl}suppress' ++ ;; ++ *) # Darwin 1.3 on ++ if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then ++ allow_undefined_flag='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ++ else ++ case ${MACOSX_DEPLOYMENT_TARGET} in ++ 10.[012]) ++ allow_undefined_flag='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ++ ;; ++ 10.*) ++ allow_undefined_flag='${wl}-undefined ${wl}dynamic_lookup' ++ ;; ++ esac ++ fi ++ ;; ++ esac ++ archive_cmds_need_lc=no ++ hardcode_direct=no ++ hardcode_automatic=yes ++ hardcode_shlibpath_var=unsupported ++ whole_archive_flag_spec='' ++ link_all_deplibs=yes ++ if test "$GCC" = yes ; then ++ output_verbose_link_cmd='echo' ++ archive_cmds='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' ++ module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' ++ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds ++ archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ module_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ else ++ case $cc_basename in ++ xlc*) ++ output_verbose_link_cmd='echo' ++ archive_cmds='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' ++ module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' ++ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds ++ archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ module_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ ;; ++ *) ++ ld_shlibs=no ++ ;; ++ esac ++ fi ++ ;; ++ ++ dgux*) ++ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_libdir_flag_spec='-L$libdir' ++ hardcode_shlibpath_var=no ++ ;; ++ ++ freebsd1*) ++ ld_shlibs=no ++ ;; ++ ++ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor ++ # support. Future versions do this automatically, but an explicit c++rt0.o ++ # does not break anything, and helps significantly (at the cost of a little ++ # extra space). ++ freebsd2.2*) ++ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' ++ hardcode_libdir_flag_spec='-R$libdir' ++ hardcode_direct=yes ++ hardcode_shlibpath_var=no ++ ;; ++ ++ # Unfortunately, older versions of FreeBSD 2 do not have this feature. ++ freebsd2*) ++ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_direct=yes ++ hardcode_minus_L=yes ++ hardcode_shlibpath_var=no ++ ;; ++ ++ # FreeBSD 3 and greater uses gcc -shared to do shared libraries. ++ freebsd* | kfreebsd*-gnu | dragonfly*) ++ archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' ++ hardcode_libdir_flag_spec='-R$libdir' ++ hardcode_direct=yes ++ hardcode_shlibpath_var=no ++ ;; ++ ++ hpux9*) ++ if test "$GCC" = yes; then ++ archive_cmds='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ++ else ++ archive_cmds='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ++ fi ++ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' ++ hardcode_libdir_separator=: ++ hardcode_direct=yes ++ ++ # hardcode_minus_L: Not really in the search PATH, ++ # but as the default location of the library. ++ hardcode_minus_L=yes ++ export_dynamic_flag_spec='${wl}-E' ++ ;; ++ ++ hpux10*) ++ if test "$GCC" = yes -a "$with_gnu_ld" = no; then ++ archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' ++ fi ++ if test "$with_gnu_ld" = no; then ++ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' ++ hardcode_libdir_separator=: ++ ++ hardcode_direct=yes ++ export_dynamic_flag_spec='${wl}-E' ++ ++ # hardcode_minus_L: Not really in the search PATH, ++ # but as the default location of the library. ++ hardcode_minus_L=yes ++ fi ++ ;; ++ ++ hpux11*) ++ if test "$GCC" = yes -a "$with_gnu_ld" = no; then ++ case $host_cpu in ++ hppa*64*) ++ archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ ia64*) ++ archive_cmds='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ *) ++ archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ esac ++ else ++ case $host_cpu in ++ hppa*64*) ++ archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ ia64*) ++ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ *) ++ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ esac ++ fi ++ if test "$with_gnu_ld" = no; then ++ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' ++ hardcode_libdir_separator=: ++ ++ case $host_cpu in ++ hppa*64*|ia64*) ++ hardcode_libdir_flag_spec_ld='+b $libdir' ++ hardcode_direct=no ++ hardcode_shlibpath_var=no ++ ;; ++ *) ++ hardcode_direct=yes ++ export_dynamic_flag_spec='${wl}-E' ++ ++ # hardcode_minus_L: Not really in the search PATH, ++ # but as the default location of the library. ++ hardcode_minus_L=yes ++ ;; ++ esac ++ fi ++ ;; ++ ++ irix5* | irix6* | nonstopux*) ++ if test "$GCC" = yes; then ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ else ++ archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' ++ hardcode_libdir_flag_spec_ld='-rpath $libdir' ++ fi ++ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' ++ hardcode_libdir_separator=: ++ link_all_deplibs=yes ++ ;; ++ ++ netbsd*) ++ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then ++ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out ++ else ++ archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF ++ fi ++ hardcode_libdir_flag_spec='-R$libdir' ++ hardcode_direct=yes ++ hardcode_shlibpath_var=no ++ ;; ++ ++ newsos6) ++ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_direct=yes ++ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' ++ hardcode_libdir_separator=: ++ hardcode_shlibpath_var=no ++ ;; ++ ++ openbsd*) ++ hardcode_direct=yes ++ hardcode_shlibpath_var=no ++ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then ++ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' ++ hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ++ export_dynamic_flag_spec='${wl}-E' ++ else ++ case $host_os in ++ openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) ++ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_libdir_flag_spec='-R$libdir' ++ ;; ++ *) ++ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ++ hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ++ ;; ++ esac ++ fi ++ ;; ++ ++ os2*) ++ hardcode_libdir_flag_spec='-L$libdir' ++ hardcode_minus_L=yes ++ allow_undefined_flag=unsupported ++ archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' ++ old_archive_From_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ++ ;; ++ ++ osf3*) ++ if test "$GCC" = yes; then ++ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' ++ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ else ++ allow_undefined_flag=' -expect_unresolved \*' ++ archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' ++ fi ++ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' ++ hardcode_libdir_separator=: ++ ;; ++ ++ osf4* | osf5*) # as osf3* with the addition of -msym flag ++ if test "$GCC" = yes; then ++ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' ++ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' ++ else ++ allow_undefined_flag=' -expect_unresolved \*' ++ archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' ++ archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ ++ $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' ++ ++ # Both c and cxx compiler support -rpath directly ++ hardcode_libdir_flag_spec='-rpath $libdir' ++ fi ++ hardcode_libdir_separator=: ++ ;; ++ ++ solaris*) ++ no_undefined_flag=' -z text' ++ if test "$GCC" = yes; then ++ wlarc='${wl}' ++ archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ ++ $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' ++ else ++ wlarc='' ++ archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ ++ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' ++ fi ++ hardcode_libdir_flag_spec='-R$libdir' ++ hardcode_shlibpath_var=no ++ case $host_os in ++ solaris2.[0-5] | solaris2.[0-5].*) ;; ++ *) ++ # The compiler driver will combine linker options so we ++ # cannot just pass the convience library names through ++ # without $wl, iff we do not link with $LD. ++ # Luckily, gcc supports the same syntax we need for Sun Studio. ++ # Supported since Solaris 2.6 (maybe 2.5.1?) ++ case $wlarc in ++ '') ++ whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;; ++ *) ++ whole_archive_flag_spec='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;; ++ esac ;; ++ esac ++ link_all_deplibs=yes ++ ;; ++ ++ sunos4*) ++ if test "x$host_vendor" = xsequent; then ++ # Use $CC to link under sequent, because it throws in some extra .o ++ # files that make .init and .fini sections work. ++ archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' ++ fi ++ hardcode_libdir_flag_spec='-L$libdir' ++ hardcode_direct=yes ++ hardcode_minus_L=yes ++ hardcode_shlibpath_var=no ++ ;; ++ ++ sysv4) ++ case $host_vendor in ++ sni) ++ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_direct=yes # is this really true??? ++ ;; ++ siemens) ++ ## LD is ld it makes a PLAMLIB ++ ## CC just makes a GrossModule. ++ archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' ++ reload_cmds='$CC -r -o $output$reload_objs' ++ hardcode_direct=no ++ ;; ++ motorola) ++ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_direct=no #Motorola manual says yes, but my tests say they lie ++ ;; ++ esac ++ runpath_var='LD_RUN_PATH' ++ hardcode_shlibpath_var=no ++ ;; ++ ++ sysv4.3*) ++ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_shlibpath_var=no ++ export_dynamic_flag_spec='-Bexport' ++ ;; ++ ++ sysv4*MP*) ++ if test -d /usr/nec; then ++ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_shlibpath_var=no ++ runpath_var=LD_RUN_PATH ++ hardcode_runpath_var=yes ++ ld_shlibs=yes ++ fi ++ ;; ++ ++ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*) ++ no_undefined_flag='${wl}-z,text' ++ archive_cmds_need_lc=no ++ hardcode_shlibpath_var=no ++ runpath_var='LD_RUN_PATH' ++ ++ if test "$GCC" = yes; then ++ archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ fi ++ ;; ++ ++ sysv5* | sco3.2v5* | sco5v6*) ++ # Note: We can NOT use -z defs as we might desire, because we do not ++ # link with -lc, and that would cause any symbols used from libc to ++ # always be unresolved, which means just about no library would ++ # ever link correctly. If we're not using GNU ld we use -z text ++ # though, which does catch some bad symbols but isn't as heavy-handed ++ # as -z defs. ++ no_undefined_flag='${wl}-z,text' ++ allow_undefined_flag='${wl}-z,nodefs' ++ archive_cmds_need_lc=no ++ hardcode_shlibpath_var=no ++ hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' ++ hardcode_libdir_separator=':' ++ link_all_deplibs=yes ++ export_dynamic_flag_spec='${wl}-Bexport' ++ runpath_var='LD_RUN_PATH' ++ ++ if test "$GCC" = yes; then ++ archive_cmds='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ archive_cmds='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ fi ++ ;; ++ ++ uts4*) ++ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_libdir_flag_spec='-L$libdir' ++ hardcode_shlibpath_var=no ++ ;; ++ ++ *) ++ ld_shlibs=no ++ ;; ++ esac ++ fi ++ ++echo "$as_me:$LINENO: result: $ld_shlibs" >&5 ++echo "${ECHO_T}$ld_shlibs" >&6 ++test "$ld_shlibs" = no && can_build_shared=no ++ ++# ++# Do we need to explicitly link libc? ++# ++case "x$archive_cmds_need_lc" in ++x|xyes) ++ # Assume -lc should be added ++ archive_cmds_need_lc=yes ++ ++ if test "$enable_shared" = yes && test "$GCC" = yes; then ++ case $archive_cmds in ++ *'~'*) ++ # FIXME: we may have to deal with multi-command sequences. ++ ;; ++ '$CC '*) ++ # Test whether the compiler implicitly links with -lc since on some ++ # systems, -lgcc has to come before -lc. If gcc already passes -lc ++ # to ld, don't add -lc before -lgcc. ++ echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 ++echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6 ++ $rm conftest* ++ printf "$lt_simple_compile_test_code" > conftest.$ac_ext ++ ++ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } 2>conftest.err; then ++ soname=conftest ++ lib=conftest ++ libobjs=conftest.$ac_objext ++ deplibs= ++ wl=$lt_prog_compiler_wl ++ pic_flag=$lt_prog_compiler_pic ++ compiler_flags=-v ++ linker_flags=-v ++ verstring= ++ output_objdir=. ++ libname=conftest ++ lt_save_allow_undefined_flag=$allow_undefined_flag ++ allow_undefined_flag= ++ if { (eval echo "$as_me:$LINENO: \"$archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 ++ (eval $archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } ++ then ++ archive_cmds_need_lc=no ++ else ++ archive_cmds_need_lc=yes ++ fi ++ allow_undefined_flag=$lt_save_allow_undefined_flag ++ else ++ cat conftest.err 1>&5 ++ fi ++ $rm conftest* ++ echo "$as_me:$LINENO: result: $archive_cmds_need_lc" >&5 ++echo "${ECHO_T}$archive_cmds_need_lc" >&6 ++ ;; ++ esac ++ fi ++ ;; ++esac ++ ++echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 ++echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6 ++library_names_spec= ++libname_spec='lib$name' ++soname_spec= ++shrext_cmds=".so" ++postinstall_cmds= ++postuninstall_cmds= ++finish_cmds= ++finish_eval= ++shlibpath_var= ++shlibpath_overrides_runpath=unknown ++version_type=none ++dynamic_linker="$host_os ld.so" ++sys_lib_dlsearch_path_spec="/lib /usr/lib" ++if test "$GCC" = yes; then ++ sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` ++ if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then ++ # if the path contains ";" then we assume it to be the separator ++ # otherwise default to the standard path separator (i.e. ":") - it is ++ # assumed that no part of a normal pathname contains ";" but that should ++ # okay in the real world where ";" in dirpaths is itself problematic. ++ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` ++ else ++ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ++ fi ++else ++ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" ++fi ++need_lib_prefix=unknown ++hardcode_into_libs=no ++ ++# when you set need_version to no, make sure it does not cause -set_version ++# flags to be left without arguments ++need_version=unknown ++ ++case $host_os in ++aix3*) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' ++ shlibpath_var=LIBPATH ++ ++ # AIX 3 has no versioning support, so we append a major version to the name. ++ soname_spec='${libname}${release}${shared_ext}$major' ++ ;; ++ ++aix4* | aix5*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ hardcode_into_libs=yes ++ if test "$host_cpu" = ia64; then ++ # AIX 5 supports IA64 ++ library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' ++ shlibpath_var=LD_LIBRARY_PATH ++ else ++ # With GCC up to 2.95.x, collect2 would create an import file ++ # for dependence libraries. The import file would start with ++ # the line `#! .'. This would cause the generated library to ++ # depend on `.', always an invalid library. This was fixed in ++ # development snapshots of GCC prior to 3.0. ++ case $host_os in ++ aix4 | aix4.[01] | aix4.[01].*) ++ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' ++ echo ' yes ' ++ echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then ++ : ++ else ++ can_build_shared=no ++ fi ++ ;; ++ esac ++ # AIX (on Power*) has no versioning support, so currently we can not hardcode correct ++ # soname into executable. Probably we can add versioning support to ++ # collect2, so additional links can be useful in future. ++ if test "$aix_use_runtimelinking" = yes; then ++ # If using run time linking (on AIX 4.2 or later) use lib.so ++ # instead of lib.a to let people know that these are not ++ # typical AIX shared libraries. ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ else ++ # We preserve .a as extension for shared libraries through AIX4.2 ++ # and later when we are not doing run time linking. ++ library_names_spec='${libname}${release}.a $libname.a' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ fi ++ shlibpath_var=LIBPATH ++ fi ++ ;; ++ ++amigaos*) ++ library_names_spec='$libname.ixlibrary $libname.a' ++ # Create ${libname}_ixlibrary.a entries in /sys/libs. ++ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ++ ;; ++ ++beos*) ++ library_names_spec='${libname}${shared_ext}' ++ dynamic_linker="$host_os ld.so" ++ shlibpath_var=LIBRARY_PATH ++ ;; ++ ++bsdi[45]*) ++ version_type=linux ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" ++ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" ++ # the default ld.so.conf also contains /usr/contrib/lib and ++ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow ++ # libtool to hard-code these into programs ++ ;; ++ ++cygwin* | mingw* | pw32*) ++ version_type=windows ++ shrext_cmds=".dll" ++ need_version=no ++ need_lib_prefix=no ++ ++ case $GCC,$host_os in ++ yes,cygwin* | yes,mingw* | yes,pw32*) ++ library_names_spec='$libname.dll.a' ++ # DLL is installed to $(libdir)/../bin by postinstall_cmds ++ postinstall_cmds='base_file=`basename \${file}`~ ++ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ ++ dldir=$destdir/`dirname \$dlpath`~ ++ test -d \$dldir || mkdir -p \$dldir~ ++ $install_prog $dir/$dlname \$dldir/$dlname~ ++ chmod a+x \$dldir/$dlname' ++ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ ++ dlpath=$dir/\$dldll~ ++ $rm \$dlpath' ++ shlibpath_overrides_runpath=yes ++ ++ case $host_os in ++ cygwin*) ++ # Cygwin DLLs use 'cyg' prefix rather than 'lib' ++ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ++ sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" ++ ;; ++ mingw*) ++ # MinGW DLLs use traditional 'lib' prefix ++ soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ++ sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` ++ if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then ++ # It is most probably a Windows format PATH printed by ++ # mingw gcc, but we are running on Cygwin. Gcc prints its search ++ # path with ; separators, and with drive letters. We can handle the ++ # drive letters (cygwin fileutils understands them), so leave them, ++ # especially as we might pass files found there to a mingw objdump, ++ # which wouldn't understand a cygwinified path. Ahh. ++ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` ++ else ++ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ++ fi ++ ;; ++ pw32*) ++ # pw32 DLLs use 'pw' prefix rather than 'lib' ++ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ++ ;; ++ esac ++ ;; ++ ++ *) ++ library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' ++ ;; ++ esac ++ dynamic_linker='Win32 ld.exe' ++ # FIXME: first we should search . and the directory the executable is in ++ shlibpath_var=PATH ++ ;; ++ ++darwin* | rhapsody*) ++ dynamic_linker="$host_os dyld" ++ version_type=darwin ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' ++ soname_spec='${libname}${release}${major}$shared_ext' ++ shlibpath_overrides_runpath=yes ++ shlibpath_var=DYLD_LIBRARY_PATH ++ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' ++ # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. ++ if test "$GCC" = yes; then ++ sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` ++ else ++ sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' ++ fi ++ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ++ ;; ++ ++dgux*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ ;; ++ ++freebsd1*) ++ dynamic_linker=no ++ ;; ++ ++kfreebsd*-gnu) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ dynamic_linker='GNU ld.so' ++ ;; ++ ++freebsd* | dragonfly*) ++ # DragonFly does not have aout. When/if they implement a new ++ # versioning mechanism, adjust this. ++ if test -x /usr/bin/objformat; then ++ objformat=`/usr/bin/objformat` ++ else ++ case $host_os in ++ freebsd[123]*) objformat=aout ;; ++ *) objformat=elf ;; ++ esac ++ fi ++ version_type=freebsd-$objformat ++ case $version_type in ++ freebsd-elf*) ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' ++ need_version=no ++ need_lib_prefix=no ++ ;; ++ freebsd-*) ++ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' ++ need_version=yes ++ ;; ++ esac ++ shlibpath_var=LD_LIBRARY_PATH ++ case $host_os in ++ freebsd2*) ++ shlibpath_overrides_runpath=yes ++ ;; ++ freebsd3.[01]* | freebsdelf3.[01]*) ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ ++ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ ;; ++ freebsd*) # from 4.6 on ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ esac ++ ;; ++ ++gnu*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ hardcode_into_libs=yes ++ ;; ++ ++hpux9* | hpux10* | hpux11*) ++ # Give a soname corresponding to the major version so that dld.sl refuses to ++ # link against other versions. ++ version_type=sunos ++ need_lib_prefix=no ++ need_version=no ++ case $host_cpu in ++ ia64*) ++ shrext_cmds='.so' ++ hardcode_into_libs=yes ++ dynamic_linker="$host_os dld.so" ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ if test "X$HPUX_IA64_MODE" = X32; then ++ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" ++ else ++ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" ++ fi ++ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ++ ;; ++ hppa*64*) ++ shrext_cmds='.sl' ++ hardcode_into_libs=yes ++ dynamic_linker="$host_os dld.sl" ++ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH ++ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" ++ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ++ ;; ++ *) ++ shrext_cmds='.sl' ++ dynamic_linker="$host_os dld.sl" ++ shlibpath_var=SHLIB_PATH ++ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ ;; ++ esac ++ # HP-UX runs *really* slowly unless shared libraries are mode 555. ++ postinstall_cmds='chmod 555 $lib' ++ ;; ++ ++interix3*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ ;; ++ ++irix5* | irix6* | nonstopux*) ++ case $host_os in ++ nonstopux*) version_type=nonstopux ;; ++ *) ++ if test "$lt_cv_prog_gnu_ld" = yes; then ++ version_type=linux ++ else ++ version_type=irix ++ fi ;; ++ esac ++ need_lib_prefix=no ++ need_version=no ++ soname_spec='${libname}${release}${shared_ext}$major' ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' ++ case $host_os in ++ irix5* | nonstopux*) ++ libsuff= shlibsuff= ++ ;; ++ *) ++ case $LD in # libtool.m4 will add one of these switches to LD ++ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") ++ libsuff= shlibsuff= libmagic=32-bit;; ++ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") ++ libsuff=32 shlibsuff=N32 libmagic=N32;; ++ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") ++ libsuff=64 shlibsuff=64 libmagic=64-bit;; ++ *) libsuff= shlibsuff= libmagic=never-match;; ++ esac ++ ;; ++ esac ++ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH ++ shlibpath_overrides_runpath=no ++ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" ++ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" ++ hardcode_into_libs=yes ++ ;; ++ ++# No shared lib support for Linux oldld, aout, or coff. ++linux*oldld* | linux*aout* | linux*coff*) ++ dynamic_linker=no ++ ;; ++ ++# This must be Linux ELF. ++linux*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ # This implies no fast_install, which is unacceptable. ++ # Some rework will be needed to allow for fast_install ++ # before this can be enabled. ++ hardcode_into_libs=yes ++ ++ # find out which ABI we are using ++ libsuff= ++ case "$host_cpu" in ++ x86_64*|s390x*|powerpc64*) ++ echo '#line 10856 "configure"' > conftest.$ac_ext ++ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; then ++ case `/usr/bin/file conftest.$ac_objext` in ++ *64-bit*) ++ libsuff=64 ++ sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}" ++ ;; ++ esac ++ fi ++ rm -rf conftest* ++ ;; ++ esac ++ ++ # Append ld.so.conf contents to the search path ++ if test -f /etc/ld.so.conf; then ++ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` ++ sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff} $lt_ld_extra" ++ fi ++ ++ # We used to test for /lib/ld.so.1 and disable shared libraries on ++ # powerpc, because MkLinux only supported shared libraries with the ++ # GNU dynamic linker. Since this was broken with cross compilers, ++ # most powerpc-linux boxes support dynamic linking these days and ++ # people can always --disable-shared, the test was removed, and we ++ # assume the GNU/Linux dynamic linker is in use. ++ dynamic_linker='GNU/Linux ld.so' ++ ;; ++ ++knetbsd*-gnu) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ dynamic_linker='GNU ld.so' ++ ;; ++ ++netbsd*) ++ version_type=sunos ++ need_lib_prefix=no ++ need_version=no ++ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' ++ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' ++ dynamic_linker='NetBSD (a.out) ld.so' ++ else ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ dynamic_linker='NetBSD ld.elf_so' ++ fi ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ ++newsos6) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ ;; ++ ++nto-qnx*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ ;; ++ ++openbsd*) ++ version_type=sunos ++ sys_lib_dlsearch_path_spec="/usr/lib" ++ need_lib_prefix=no ++ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. ++ case $host_os in ++ openbsd3.3 | openbsd3.3.*) need_version=yes ;; ++ *) need_version=no ;; ++ esac ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' ++ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then ++ case $host_os in ++ openbsd2.[89] | openbsd2.[89].*) ++ shlibpath_overrides_runpath=no ++ ;; ++ *) ++ shlibpath_overrides_runpath=yes ++ ;; ++ esac ++ else ++ shlibpath_overrides_runpath=yes ++ fi ++ ;; ++ ++os2*) ++ libname_spec='$name' ++ shrext_cmds=".dll" ++ need_lib_prefix=no ++ library_names_spec='$libname${shared_ext} $libname.a' ++ dynamic_linker='OS/2 ld.exe' ++ shlibpath_var=LIBPATH ++ ;; ++ ++osf3* | osf4* | osf5*) ++ version_type=osf ++ need_lib_prefix=no ++ need_version=no ++ soname_spec='${libname}${release}${shared_ext}$major' ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ shlibpath_var=LD_LIBRARY_PATH ++ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" ++ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ++ ;; ++ ++solaris*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ # ldd complains unless libraries are executable ++ postinstall_cmds='chmod +x $lib' ++ ;; ++ ++sunos4*) ++ version_type=sunos ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' ++ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ if test "$with_gnu_ld" = yes; then ++ need_lib_prefix=no ++ fi ++ need_version=yes ++ ;; ++ ++sysv4 | sysv4.3*) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ case $host_vendor in ++ sni) ++ shlibpath_overrides_runpath=no ++ need_lib_prefix=no ++ export_dynamic_flag_spec='${wl}-Blargedynsym' ++ runpath_var=LD_RUN_PATH ++ ;; ++ siemens) ++ need_lib_prefix=no ++ ;; ++ motorola) ++ need_lib_prefix=no ++ need_version=no ++ shlibpath_overrides_runpath=no ++ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ++ ;; ++ esac ++ ;; ++ ++sysv4*MP*) ++ if test -d /usr/nec ;then ++ version_type=linux ++ library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' ++ soname_spec='$libname${shared_ext}.$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ fi ++ ;; ++ ++sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) ++ version_type=freebsd-elf ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ hardcode_into_libs=yes ++ if test "$with_gnu_ld" = yes; then ++ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' ++ shlibpath_overrides_runpath=no ++ else ++ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' ++ shlibpath_overrides_runpath=yes ++ case $host_os in ++ sco3.2v5*) ++ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ++ ;; ++ esac ++ fi ++ sys_lib_dlsearch_path_spec='/usr/lib' ++ ;; ++ ++uts4*) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ ;; ++ ++*) ++ dynamic_linker=no ++ ;; ++esac ++echo "$as_me:$LINENO: result: $dynamic_linker" >&5 ++echo "${ECHO_T}$dynamic_linker" >&6 ++test "$dynamic_linker" = no && can_build_shared=no ++ ++variables_saved_for_relink="PATH $shlibpath_var $runpath_var" ++if test "$GCC" = yes; then ++ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" ++fi ++ ++echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 ++echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6 ++hardcode_action= ++if test -n "$hardcode_libdir_flag_spec" || \ ++ test -n "$runpath_var" || \ ++ test "X$hardcode_automatic" = "Xyes" ; then ++ ++ # We can hardcode non-existant directories. ++ if test "$hardcode_direct" != no && ++ # If the only mechanism to avoid hardcoding is shlibpath_var, we ++ # have to relink, otherwise we might link with an installed library ++ # when we should be linking with a yet-to-be-installed one ++ ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, )" != no && ++ test "$hardcode_minus_L" != no; then ++ # Linking always hardcodes the temporary library directory. ++ hardcode_action=relink ++ else ++ # We can link without hardcoding, and we can hardcode nonexisting dirs. ++ hardcode_action=immediate ++ fi ++else ++ # We cannot hardcode anything, or else we can only hardcode existing ++ # directories. ++ hardcode_action=unsupported ++fi ++echo "$as_me:$LINENO: result: $hardcode_action" >&5 ++echo "${ECHO_T}$hardcode_action" >&6 ++ ++if test "$hardcode_action" = relink; then ++ # Fast installation is not supported ++ enable_fast_install=no ++elif test "$shlibpath_overrides_runpath" = yes || ++ test "$enable_shared" = no; then ++ # Fast installation is not necessary ++ enable_fast_install=needless ++fi ++ ++striplib= ++old_striplib= ++echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5 ++echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6 ++if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then ++ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" ++ test -z "$striplib" && striplib="$STRIP --strip-unneeded" ++ echo "$as_me:$LINENO: result: yes" >&5 ++echo "${ECHO_T}yes" >&6 ++else ++# FIXME - insert some real tests, host_os isn't really good enough ++ case $host_os in ++ darwin*) ++ if test -n "$STRIP" ; then ++ striplib="$STRIP -x" ++ echo "$as_me:$LINENO: result: yes" >&5 ++echo "${ECHO_T}yes" >&6 ++ else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ;; ++ *) ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++ ;; ++ esac ++fi ++ ++if test "x$enable_dlopen" != xyes; then ++ enable_dlopen=unknown ++ enable_dlopen_self=unknown ++ enable_dlopen_self_static=unknown ++else ++ lt_cv_dlopen=no ++ lt_cv_dlopen_libs= ++ ++ case $host_os in ++ beos*) ++ lt_cv_dlopen="load_add_on" ++ lt_cv_dlopen_libs= ++ lt_cv_dlopen_self=yes ++ ;; ++ ++ mingw* | pw32*) ++ lt_cv_dlopen="LoadLibrary" ++ lt_cv_dlopen_libs= ++ ;; ++ ++ cygwin*) ++ lt_cv_dlopen="dlopen" ++ lt_cv_dlopen_libs= ++ ;; ++ ++ darwin*) ++ # if libdl is installed we need to link against it ++ echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 ++echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 ++if test "${ac_cv_lib_dl_dlopen+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ ac_check_lib_save_LIBS=$LIBS ++LIBS="-ldl $LIBS" ++cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++ ++/* Override any gcc2 internal prototype to avoid an error. */ ++#ifdef __cplusplus ++extern "C" ++#endif ++/* We use char because int might match the return type of a gcc2 ++ builtin and then its argument prototype would still apply. */ ++char dlopen (); ++int ++main () ++{ ++dlopen (); ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext conftest$ac_exeext ++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 ++ (eval $ac_link) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest$ac_exeext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_lib_dl_dlopen=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_cv_lib_dl_dlopen=no ++fi ++rm -f conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++LIBS=$ac_check_lib_save_LIBS ++fi ++echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 ++echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 ++if test $ac_cv_lib_dl_dlopen = yes; then ++ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" ++else ++ ++ lt_cv_dlopen="dyld" ++ lt_cv_dlopen_libs= ++ lt_cv_dlopen_self=yes ++ ++fi ++ ++ ;; ++ ++ *) ++ echo "$as_me:$LINENO: checking for shl_load" >&5 ++echo $ECHO_N "checking for shl_load... $ECHO_C" >&6 ++if test "${ac_cv_func_shl_load+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++/* Define shl_load to an innocuous variant, in case declares shl_load. ++ For example, HP-UX 11i declares gettimeofday. */ ++#define shl_load innocuous_shl_load ++ ++/* System header to define __stub macros and hopefully few prototypes, ++ which can conflict with char shl_load (); below. ++ Prefer to if __STDC__ is defined, since ++ exists even on freestanding compilers. */ ++ ++#ifdef __STDC__ ++# include ++#else ++# include ++#endif ++ ++#undef shl_load ++ ++/* Override any gcc2 internal prototype to avoid an error. */ ++#ifdef __cplusplus ++extern "C" ++{ ++#endif ++/* We use char because int might match the return type of a gcc2 ++ builtin and then its argument prototype would still apply. */ ++char shl_load (); ++/* The GNU C library defines this for functions which it implements ++ to always fail with ENOSYS. Some functions are actually named ++ something starting with __ and the normal name is an alias. */ ++#if defined (__stub_shl_load) || defined (__stub___shl_load) ++choke me ++#else ++char (*f) () = shl_load; ++#endif ++#ifdef __cplusplus ++} ++#endif ++ ++int ++main () ++{ ++return f != shl_load; ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext conftest$ac_exeext ++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 ++ (eval $ac_link) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest$ac_exeext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_func_shl_load=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_cv_func_shl_load=no ++fi ++rm -f conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++fi ++echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5 ++echo "${ECHO_T}$ac_cv_func_shl_load" >&6 ++if test $ac_cv_func_shl_load = yes; then ++ lt_cv_dlopen="shl_load" ++else ++ echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 ++echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6 ++if test "${ac_cv_lib_dld_shl_load+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ ac_check_lib_save_LIBS=$LIBS ++LIBS="-ldld $LIBS" ++cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++ ++/* Override any gcc2 internal prototype to avoid an error. */ ++#ifdef __cplusplus ++extern "C" ++#endif ++/* We use char because int might match the return type of a gcc2 ++ builtin and then its argument prototype would still apply. */ ++char shl_load (); ++int ++main () ++{ ++shl_load (); ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext conftest$ac_exeext ++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 ++ (eval $ac_link) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest$ac_exeext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_lib_dld_shl_load=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_cv_lib_dld_shl_load=no ++fi ++rm -f conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++LIBS=$ac_check_lib_save_LIBS ++fi ++echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 ++echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6 ++if test $ac_cv_lib_dld_shl_load = yes; then ++ lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld" ++else ++ echo "$as_me:$LINENO: checking for dlopen" >&5 ++echo $ECHO_N "checking for dlopen... $ECHO_C" >&6 ++if test "${ac_cv_func_dlopen+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++/* Define dlopen to an innocuous variant, in case declares dlopen. ++ For example, HP-UX 11i declares gettimeofday. */ ++#define dlopen innocuous_dlopen ++ ++/* System header to define __stub macros and hopefully few prototypes, ++ which can conflict with char dlopen (); below. ++ Prefer to if __STDC__ is defined, since ++ exists even on freestanding compilers. */ ++ ++#ifdef __STDC__ ++# include ++#else ++# include ++#endif ++ ++#undef dlopen ++ ++/* Override any gcc2 internal prototype to avoid an error. */ ++#ifdef __cplusplus ++extern "C" ++{ ++#endif ++/* We use char because int might match the return type of a gcc2 ++ builtin and then its argument prototype would still apply. */ ++char dlopen (); ++/* The GNU C library defines this for functions which it implements ++ to always fail with ENOSYS. Some functions are actually named ++ something starting with __ and the normal name is an alias. */ ++#if defined (__stub_dlopen) || defined (__stub___dlopen) ++choke me ++#else ++char (*f) () = dlopen; ++#endif ++#ifdef __cplusplus ++} ++#endif ++ ++int ++main () ++{ ++return f != dlopen; ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext conftest$ac_exeext ++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 ++ (eval $ac_link) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest$ac_exeext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_func_dlopen=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_cv_func_dlopen=no ++fi ++rm -f conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++fi ++echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5 ++echo "${ECHO_T}$ac_cv_func_dlopen" >&6 ++if test $ac_cv_func_dlopen = yes; then ++ lt_cv_dlopen="dlopen" ++else ++ echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 ++echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 ++if test "${ac_cv_lib_dl_dlopen+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ ac_check_lib_save_LIBS=$LIBS ++LIBS="-ldl $LIBS" ++cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++ ++/* Override any gcc2 internal prototype to avoid an error. */ ++#ifdef __cplusplus ++extern "C" ++#endif ++/* We use char because int might match the return type of a gcc2 ++ builtin and then its argument prototype would still apply. */ ++char dlopen (); ++int ++main () ++{ ++dlopen (); ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext conftest$ac_exeext ++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 ++ (eval $ac_link) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest$ac_exeext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_lib_dl_dlopen=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_cv_lib_dl_dlopen=no ++fi ++rm -f conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++LIBS=$ac_check_lib_save_LIBS ++fi ++echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 ++echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 ++if test $ac_cv_lib_dl_dlopen = yes; then ++ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" ++else ++ echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5 ++echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6 ++if test "${ac_cv_lib_svld_dlopen+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ ac_check_lib_save_LIBS=$LIBS ++LIBS="-lsvld $LIBS" ++cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++ ++/* Override any gcc2 internal prototype to avoid an error. */ ++#ifdef __cplusplus ++extern "C" ++#endif ++/* We use char because int might match the return type of a gcc2 ++ builtin and then its argument prototype would still apply. */ ++char dlopen (); ++int ++main () ++{ ++dlopen (); ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext conftest$ac_exeext ++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 ++ (eval $ac_link) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest$ac_exeext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_lib_svld_dlopen=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_cv_lib_svld_dlopen=no ++fi ++rm -f conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++LIBS=$ac_check_lib_save_LIBS ++fi ++echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5 ++echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6 ++if test $ac_cv_lib_svld_dlopen = yes; then ++ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" ++else ++ echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5 ++echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6 ++if test "${ac_cv_lib_dld_dld_link+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ ac_check_lib_save_LIBS=$LIBS ++LIBS="-ldld $LIBS" ++cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++ ++/* Override any gcc2 internal prototype to avoid an error. */ ++#ifdef __cplusplus ++extern "C" ++#endif ++/* We use char because int might match the return type of a gcc2 ++ builtin and then its argument prototype would still apply. */ ++char dld_link (); ++int ++main () ++{ ++dld_link (); ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext conftest$ac_exeext ++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 ++ (eval $ac_link) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest$ac_exeext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_lib_dld_dld_link=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_cv_lib_dld_dld_link=no ++fi ++rm -f conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++LIBS=$ac_check_lib_save_LIBS ++fi ++echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5 ++echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6 ++if test $ac_cv_lib_dld_dld_link = yes; then ++ lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld" ++fi ++ ++ ++fi ++ ++ ++fi ++ ++ ++fi ++ ++ ++fi ++ ++ ++fi ++ ++ ;; ++ esac ++ ++ if test "x$lt_cv_dlopen" != xno; then ++ enable_dlopen=yes ++ else ++ enable_dlopen=no ++ fi ++ ++ case $lt_cv_dlopen in ++ dlopen) ++ save_CPPFLAGS="$CPPFLAGS" ++ test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" ++ ++ save_LDFLAGS="$LDFLAGS" ++ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" ++ ++ save_LIBS="$LIBS" ++ LIBS="$lt_cv_dlopen_libs $LIBS" ++ ++ echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5 ++echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6 ++if test "${lt_cv_dlopen_self+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test "$cross_compiling" = yes; then : ++ lt_cv_dlopen_self=cross ++else ++ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 ++ lt_status=$lt_dlunknown ++ cat > conftest.$ac_ext < ++#endif ++ ++#include ++ ++#ifdef RTLD_GLOBAL ++# define LT_DLGLOBAL RTLD_GLOBAL ++#else ++# ifdef DL_GLOBAL ++# define LT_DLGLOBAL DL_GLOBAL ++# else ++# define LT_DLGLOBAL 0 ++# endif ++#endif ++ ++/* We may have to define LT_DLLAZY_OR_NOW in the command line if we ++ find out it does not work in some platform. */ ++#ifndef LT_DLLAZY_OR_NOW ++# ifdef RTLD_LAZY ++# define LT_DLLAZY_OR_NOW RTLD_LAZY ++# else ++# ifdef DL_LAZY ++# define LT_DLLAZY_OR_NOW DL_LAZY ++# else ++# ifdef RTLD_NOW ++# define LT_DLLAZY_OR_NOW RTLD_NOW ++# else ++# ifdef DL_NOW ++# define LT_DLLAZY_OR_NOW DL_NOW ++# else ++# define LT_DLLAZY_OR_NOW 0 ++# endif ++# endif ++# endif ++# endif ++#endif ++ ++#ifdef __cplusplus ++extern "C" void exit (int); ++#endif ++ ++void fnord() { int i=42;} ++int main () ++{ ++ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); ++ int status = $lt_dlunknown; ++ ++ if (self) ++ { ++ if (dlsym (self,"fnord")) status = $lt_dlno_uscore; ++ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; ++ /* dlclose (self); */ ++ } ++ else ++ puts (dlerror ()); ++ ++ exit (status); ++} ++EOF ++ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 ++ (eval $ac_link) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then ++ (./conftest; exit; ) >&5 2>/dev/null ++ lt_status=$? ++ case x$lt_status in ++ x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; ++ x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; ++ x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; ++ esac ++ else : ++ # compilation failed ++ lt_cv_dlopen_self=no ++ fi ++fi ++rm -fr conftest* ++ ++ ++fi ++echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5 ++echo "${ECHO_T}$lt_cv_dlopen_self" >&6 ++ ++ if test "x$lt_cv_dlopen_self" = xyes; then ++ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" ++ echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5 ++echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6 ++if test "${lt_cv_dlopen_self_static+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test "$cross_compiling" = yes; then : ++ lt_cv_dlopen_self_static=cross ++else ++ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 ++ lt_status=$lt_dlunknown ++ cat > conftest.$ac_ext < ++#endif ++ ++#include ++ ++#ifdef RTLD_GLOBAL ++# define LT_DLGLOBAL RTLD_GLOBAL ++#else ++# ifdef DL_GLOBAL ++# define LT_DLGLOBAL DL_GLOBAL ++# else ++# define LT_DLGLOBAL 0 ++# endif ++#endif ++ ++/* We may have to define LT_DLLAZY_OR_NOW in the command line if we ++ find out it does not work in some platform. */ ++#ifndef LT_DLLAZY_OR_NOW ++# ifdef RTLD_LAZY ++# define LT_DLLAZY_OR_NOW RTLD_LAZY ++# else ++# ifdef DL_LAZY ++# define LT_DLLAZY_OR_NOW DL_LAZY ++# else ++# ifdef RTLD_NOW ++# define LT_DLLAZY_OR_NOW RTLD_NOW ++# else ++# ifdef DL_NOW ++# define LT_DLLAZY_OR_NOW DL_NOW ++# else ++# define LT_DLLAZY_OR_NOW 0 ++# endif ++# endif ++# endif ++# endif ++#endif ++ ++#ifdef __cplusplus ++extern "C" void exit (int); ++#endif ++ ++void fnord() { int i=42;} ++int main () ++{ ++ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); ++ int status = $lt_dlunknown; ++ ++ if (self) ++ { ++ if (dlsym (self,"fnord")) status = $lt_dlno_uscore; ++ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; ++ /* dlclose (self); */ ++ } ++ else ++ puts (dlerror ()); ++ ++ exit (status); ++} ++EOF ++ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 ++ (eval $ac_link) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then ++ (./conftest; exit; ) >&5 2>/dev/null ++ lt_status=$? ++ case x$lt_status in ++ x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; ++ x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; ++ x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; ++ esac ++ else : ++ # compilation failed ++ lt_cv_dlopen_self_static=no ++ fi ++fi ++rm -fr conftest* ++ ++ ++fi ++echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5 ++echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6 ++ fi ++ ++ CPPFLAGS="$save_CPPFLAGS" ++ LDFLAGS="$save_LDFLAGS" ++ LIBS="$save_LIBS" ++ ;; ++ esac ++ ++ case $lt_cv_dlopen_self in ++ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; ++ *) enable_dlopen_self=unknown ;; ++ esac ++ ++ case $lt_cv_dlopen_self_static in ++ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; ++ *) enable_dlopen_self_static=unknown ;; ++ esac ++fi ++ ++ ++# Report which library types will actually be built ++echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5 ++echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6 ++echo "$as_me:$LINENO: result: $can_build_shared" >&5 ++echo "${ECHO_T}$can_build_shared" >&6 ++ ++echo "$as_me:$LINENO: checking whether to build shared libraries" >&5 ++echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6 ++test "$can_build_shared" = "no" && enable_shared=no ++ ++# On AIX, shared libraries and static libraries use the same namespace, and ++# are all built from PIC. ++case $host_os in ++aix3*) ++ test "$enable_shared" = yes && enable_static=no ++ if test -n "$RANLIB"; then ++ archive_cmds="$archive_cmds~\$RANLIB \$lib" ++ postinstall_cmds='$RANLIB $lib' ++ fi ++ ;; ++ ++aix4* | aix5*) ++ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then ++ test "$enable_shared" = yes && enable_static=no ++ fi ++ ;; ++esac ++echo "$as_me:$LINENO: result: $enable_shared" >&5 ++echo "${ECHO_T}$enable_shared" >&6 ++ ++echo "$as_me:$LINENO: checking whether to build static libraries" >&5 ++echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6 ++# Make sure either enable_shared or enable_static is yes. ++test "$enable_shared" = yes || enable_static=yes ++echo "$as_me:$LINENO: result: $enable_static" >&5 ++echo "${ECHO_T}$enable_static" >&6 ++ ++# The else clause should only fire when bootstrapping the ++# libtool distribution, otherwise you forgot to ship ltmain.sh ++# with your package, and you will get complaints that there are ++# no rules to generate ltmain.sh. ++if test -f "$ltmain"; then ++ # See if we are running on zsh, and set the options which allow our commands through ++ # without removal of \ escapes. ++ if test -n "${ZSH_VERSION+set}" ; then ++ setopt NO_GLOB_SUBST ++ fi ++ # Now quote all the things that may contain metacharacters while being ++ # careful not to overquote the AC_SUBSTed values. We take copies of the ++ # variables and quote the copies for generation of the libtool script. ++ for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ ++ SED SHELL STRIP \ ++ libname_spec library_names_spec soname_spec extract_expsyms_cmds \ ++ old_striplib striplib file_magic_cmd finish_cmds finish_eval \ ++ deplibs_check_method reload_flag reload_cmds need_locks \ ++ lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ ++ lt_cv_sys_global_symbol_to_c_name_address \ ++ sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ ++ old_postinstall_cmds old_postuninstall_cmds \ ++ compiler \ ++ CC \ ++ LD \ ++ lt_prog_compiler_wl \ ++ lt_prog_compiler_pic \ ++ lt_prog_compiler_static \ ++ lt_prog_compiler_no_builtin_flag \ ++ export_dynamic_flag_spec \ ++ thread_safe_flag_spec \ ++ whole_archive_flag_spec \ ++ enable_shared_with_static_runtimes \ ++ old_archive_cmds \ ++ old_archive_from_new_cmds \ ++ predep_objects \ ++ postdep_objects \ ++ predeps \ ++ postdeps \ ++ compiler_lib_search_path \ ++ archive_cmds \ ++ archive_expsym_cmds \ ++ postinstall_cmds \ ++ postuninstall_cmds \ ++ old_archive_from_expsyms_cmds \ ++ allow_undefined_flag \ ++ no_undefined_flag \ ++ export_symbols_cmds \ ++ hardcode_libdir_flag_spec \ ++ hardcode_libdir_flag_spec_ld \ ++ hardcode_libdir_separator \ ++ hardcode_automatic \ ++ module_cmds \ ++ module_expsym_cmds \ ++ lt_cv_prog_compiler_c_o \ ++ exclude_expsyms \ ++ include_expsyms; do ++ ++ case $var in ++ old_archive_cmds | \ ++ old_archive_from_new_cmds | \ ++ archive_cmds | \ ++ archive_expsym_cmds | \ ++ module_cmds | \ ++ module_expsym_cmds | \ ++ old_archive_from_expsyms_cmds | \ ++ export_symbols_cmds | \ ++ extract_expsyms_cmds | reload_cmds | finish_cmds | \ ++ postinstall_cmds | postuninstall_cmds | \ ++ old_postinstall_cmds | old_postuninstall_cmds | \ ++ sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) ++ # Double-quote double-evaled strings. ++ eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" ++ ;; ++ *) ++ eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" ++ ;; ++ esac ++ done ++ ++ case $lt_echo in ++ *'\$0 --fallback-echo"') ++ lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` ++ ;; ++ esac ++ ++cfgfile="${ofile}T" ++ trap "$rm \"$cfgfile\"; exit 1" 1 2 15 ++ $rm -f "$cfgfile" ++ { echo "$as_me:$LINENO: creating $ofile" >&5 ++echo "$as_me: creating $ofile" >&6;} ++ ++ cat <<__EOF__ >> "$cfgfile" ++#! $SHELL ++ ++# `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services. ++# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) ++# NOTE: Changes made to this file will be lost: look at ltmain.sh. ++# ++# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 ++# Free Software Foundation, Inc. ++# ++# This file is part of GNU Libtool: ++# Originally by Gordon Matzigkeit , 1996 ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++# ++# As a special exception to the GNU General Public License, if you ++# distribute this file as part of a program that contains a ++# configuration script generated by Autoconf, you may include it under ++# the same distribution terms that you use for the rest of that program. ++ ++# A sed program that does not truncate output. ++SED=$lt_SED ++ ++# Sed that helps us avoid accidentally triggering echo(1) options like -n. ++Xsed="$SED -e 1s/^X//" ++ ++# The HP-UX ksh and POSIX shell print the target directory to stdout ++# if CDPATH is set. ++(unset CDPATH) >/dev/null 2>&1 && unset CDPATH ++ ++# The names of the tagged configurations supported by this script. ++available_tags= ++ ++# ### BEGIN LIBTOOL CONFIG ++ ++# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: ++ ++# Shell to use when invoking shell scripts. ++SHELL=$lt_SHELL ++ ++# Whether or not to build shared libraries. ++build_libtool_libs=$enable_shared ++ ++# Whether or not to build static libraries. ++build_old_libs=$enable_static ++ ++# Whether or not to add -lc for building shared libraries. ++build_libtool_need_lc=$archive_cmds_need_lc ++ ++# Whether or not to disallow shared libs when runtime libs are static ++allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes ++ ++# Whether or not to optimize for fast installation. ++fast_install=$enable_fast_install ++ ++# The host system. ++host_alias=$host_alias ++host=$host ++host_os=$host_os ++ ++# The build system. ++build_alias=$build_alias ++build=$build ++build_os=$build_os ++ ++# An echo program that does not interpret backslashes. ++echo=$lt_echo ++ ++# The archiver. ++AR=$lt_AR ++AR_FLAGS=$lt_AR_FLAGS ++ ++# A C compiler. ++LTCC=$lt_LTCC ++ ++# LTCC compiler flags. ++LTCFLAGS=$lt_LTCFLAGS ++ ++# A language-specific compiler. ++CC=$lt_compiler ++ ++# Is the compiler the GNU C compiler? ++with_gcc=$GCC ++ ++gcc_dir=\`gcc -print-file-name=. | $SED 's,/\.$,,'\` ++gcc_ver=\`gcc -dumpversion\` ++ ++# An ERE matcher. ++EGREP=$lt_EGREP ++ ++# The linker used to build libraries. ++LD=$lt_LD ++ ++# Whether we need hard or soft links. ++LN_S=$lt_LN_S ++ ++# A BSD-compatible nm program. ++NM=$lt_NM ++ ++# A symbol stripping program ++STRIP=$lt_STRIP ++ ++# Used to examine libraries when file_magic_cmd begins "file" ++MAGIC_CMD=$MAGIC_CMD ++ ++# Used on cygwin: DLL creation program. ++DLLTOOL="$DLLTOOL" ++ ++# Used on cygwin: object dumper. ++OBJDUMP="$OBJDUMP" ++ ++# Used on cygwin: assembler. ++AS="$AS" ++ ++# The name of the directory that contains temporary libtool files. ++objdir=$objdir ++ ++# How to create reloadable object files. ++reload_flag=$lt_reload_flag ++reload_cmds=$lt_reload_cmds ++ ++# How to pass a linker flag through the compiler. ++wl=$lt_lt_prog_compiler_wl ++ ++# Object file suffix (normally "o"). ++objext="$ac_objext" ++ ++# Old archive suffix (normally "a"). ++libext="$libext" ++ ++# Shared library suffix (normally ".so"). ++shrext_cmds='$shrext_cmds' ++ ++# Executable file suffix (normally ""). ++exeext="$exeext" ++ ++# Additional compiler flags for building library objects. ++pic_flag=$lt_lt_prog_compiler_pic ++pic_mode=$pic_mode ++ ++# What is the maximum length of a command? ++max_cmd_len=$lt_cv_sys_max_cmd_len ++ ++# Does compiler simultaneously support -c and -o options? ++compiler_c_o=$lt_lt_cv_prog_compiler_c_o ++ ++# Must we lock files when doing compilation? ++need_locks=$lt_need_locks ++ ++# Do we need the lib prefix for modules? ++need_lib_prefix=$need_lib_prefix ++ ++# Do we need a version for libraries? ++need_version=$need_version ++ ++# Whether dlopen is supported. ++dlopen_support=$enable_dlopen ++ ++# Whether dlopen of programs is supported. ++dlopen_self=$enable_dlopen_self ++ ++# Whether dlopen of statically linked programs is supported. ++dlopen_self_static=$enable_dlopen_self_static ++ ++# Compiler flag to prevent dynamic linking. ++link_static_flag=$lt_lt_prog_compiler_static ++ ++# Compiler flag to turn off builtin functions. ++no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag ++ ++# Compiler flag to allow reflexive dlopens. ++export_dynamic_flag_spec=$lt_export_dynamic_flag_spec ++ ++# Compiler flag to generate shared objects directly from archives. ++whole_archive_flag_spec=$lt_whole_archive_flag_spec ++ ++# Compiler flag to generate thread-safe objects. ++thread_safe_flag_spec=$lt_thread_safe_flag_spec ++ ++# Library versioning type. ++version_type=$version_type ++ ++# Format of library name prefix. ++libname_spec=$lt_libname_spec ++ ++# List of archive names. First name is the real one, the rest are links. ++# The last name is the one that the linker finds with -lNAME. ++library_names_spec=$lt_library_names_spec ++ ++# The coded name of the library, if different from the real name. ++soname_spec=$lt_soname_spec ++ ++# Commands used to build and install an old-style archive. ++RANLIB=$lt_RANLIB ++old_archive_cmds=$lt_old_archive_cmds ++old_postinstall_cmds=$lt_old_postinstall_cmds ++old_postuninstall_cmds=$lt_old_postuninstall_cmds ++ ++# Create an old-style archive from a shared archive. ++old_archive_from_new_cmds=$lt_old_archive_from_new_cmds ++ ++# Create a temporary old-style archive to link instead of a shared archive. ++old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds ++ ++# Commands used to build and install a shared archive. ++archive_cmds=$lt_archive_cmds ++archive_expsym_cmds=$lt_archive_expsym_cmds ++postinstall_cmds=$lt_postinstall_cmds ++postuninstall_cmds=$lt_postuninstall_cmds ++ ++# Commands used to build a loadable module (assumed same as above if empty) ++module_cmds=$lt_module_cmds ++module_expsym_cmds=$lt_module_expsym_cmds ++ ++# Commands to strip libraries. ++old_striplib=$lt_old_striplib ++striplib=$lt_striplib ++ ++# Dependencies to place before the objects being linked to create a ++# shared library. ++predep_objects=\`echo $lt_predep_objects | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` ++ ++# Dependencies to place after the objects being linked to create a ++# shared library. ++postdep_objects=\`echo $lt_postdep_objects | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` ++ ++# Dependencies to place before the objects being linked to create a ++# shared library. ++predeps=$lt_predeps ++ ++# Dependencies to place after the objects being linked to create a ++# shared library. ++postdeps=$lt_postdeps ++ ++# The library search path used internally by the compiler when linking ++# a shared library. ++compiler_lib_search_path=\`echo $lt_compiler_lib_search_path | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` ++ ++# Method to check whether dependent libraries are shared objects. ++deplibs_check_method=$lt_deplibs_check_method ++ ++# Command to use when deplibs_check_method == file_magic. ++file_magic_cmd=$lt_file_magic_cmd ++ ++# Flag that allows shared libraries with undefined symbols to be built. ++allow_undefined_flag=$lt_allow_undefined_flag ++ ++# Flag that forces no undefined symbols. ++no_undefined_flag=$lt_no_undefined_flag ++ ++# Commands used to finish a libtool library installation in a directory. ++finish_cmds=$lt_finish_cmds ++ ++# Same as above, but a single script fragment to be evaled but not shown. ++finish_eval=$lt_finish_eval ++ ++# Take the output of nm and produce a listing of raw symbols and C names. ++global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe ++ ++# Transform the output of nm in a proper C declaration ++global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl ++ ++# Transform the output of nm in a C name address pair ++global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address ++ ++# This is the shared library runtime path variable. ++runpath_var=$runpath_var ++ ++# This is the shared library path variable. ++shlibpath_var=$shlibpath_var ++ ++# Is shlibpath searched before the hard-coded library search path? ++shlibpath_overrides_runpath=$shlibpath_overrides_runpath ++ ++# How to hardcode a shared library path into an executable. ++hardcode_action=$hardcode_action ++ ++# Whether we should hardcode library paths into libraries. ++hardcode_into_libs=$hardcode_into_libs ++ ++# Flag to hardcode \$libdir into a binary during linking. ++# This must work even if \$libdir does not exist. ++hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec ++ ++# If ld is used when linking, flag to hardcode \$libdir into ++# a binary during linking. This must work even if \$libdir does ++# not exist. ++hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld ++ ++# Whether we need a single -rpath flag with a separated argument. ++hardcode_libdir_separator=$lt_hardcode_libdir_separator ++ ++# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the ++# resulting binary. ++hardcode_direct=$hardcode_direct ++ ++# Set to yes if using the -LDIR flag during linking hardcodes DIR into the ++# resulting binary. ++hardcode_minus_L=$hardcode_minus_L ++ ++# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into ++# the resulting binary. ++hardcode_shlibpath_var=$hardcode_shlibpath_var ++ ++# Set to yes if building a shared library automatically hardcodes DIR into the library ++# and all subsequent libraries and executables linked against it. ++hardcode_automatic=$hardcode_automatic ++ ++# Variables whose values should be saved in libtool wrapper scripts and ++# restored at relink time. ++variables_saved_for_relink="$variables_saved_for_relink" ++ ++# Whether libtool must link a program against all its dependency libraries. ++link_all_deplibs=$link_all_deplibs ++ ++# Compile-time system search path for libraries ++sys_lib_search_path_spec=\`echo $lt_sys_lib_search_path_spec | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` ++ ++# Run-time system search path for libraries ++sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec ++ ++# Fix the shell variable \$srcfile for the compiler. ++fix_srcfile_path="$fix_srcfile_path" ++ ++# Set to yes if exported symbols are required. ++always_export_symbols=$always_export_symbols ++ ++# The commands to list exported symbols. ++export_symbols_cmds=$lt_export_symbols_cmds ++ ++# The commands to extract the exported symbol list from a shared archive. ++extract_expsyms_cmds=$lt_extract_expsyms_cmds ++ ++# Symbols that should not be listed in the preloaded symbols. ++exclude_expsyms=$lt_exclude_expsyms ++ ++# Symbols that must always be exported. ++include_expsyms=$lt_include_expsyms ++ ++# ### END LIBTOOL CONFIG ++ ++__EOF__ ++ ++ ++ case $host_os in ++ aix3*) ++ cat <<\EOF >> "$cfgfile" ++ ++# AIX sometimes has problems with the GCC collect2 program. For some ++# reason, if we set the COLLECT_NAMES environment variable, the problems ++# vanish in a puff of smoke. ++if test "X${COLLECT_NAMES+set}" != Xset; then ++ COLLECT_NAMES= ++ export COLLECT_NAMES ++fi ++EOF ++ ;; ++ esac ++ ++ # We use sed instead of cat because bash on DJGPP gets confused if ++ # if finds mixed CR/LF and LF-only lines. Since sed operates in ++ # text mode, it properly converts lines to CR/LF. This bash problem ++ # is reportedly fixed, but why not run on old versions too? ++ sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1) ++ ++ mv -f "$cfgfile" "$ofile" || \ ++ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") ++ chmod +x "$ofile" ++ ++else ++ # If there is no Makefile yet, we rely on a make rule to execute ++ # `config.status --recheck' to rerun these tests and create the ++ # libtool script then. ++ ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` ++ if test -f "$ltmain_in"; then ++ test -f Makefile && make "$ltmain" ++ fi ++fi ++ ++ ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++CC="$lt_save_CC" ++ ++ ++# Check whether --with-tags or --without-tags was given. ++if test "${with_tags+set}" = set; then ++ withval="$with_tags" ++ tagnames="$withval" ++fi; ++ ++if test -f "$ltmain" && test -n "$tagnames"; then ++ if test ! -f "${ofile}"; then ++ { echo "$as_me:$LINENO: WARNING: output file \`$ofile' does not exist" >&5 ++echo "$as_me: WARNING: output file \`$ofile' does not exist" >&2;} ++ fi ++ ++ if test -z "$LTCC"; then ++ eval "`$SHELL ${ofile} --config | grep '^LTCC='`" ++ if test -z "$LTCC"; then ++ { echo "$as_me:$LINENO: WARNING: output file \`$ofile' does not look like a libtool script" >&5 ++echo "$as_me: WARNING: output file \`$ofile' does not look like a libtool script" >&2;} ++ else ++ { echo "$as_me:$LINENO: WARNING: using \`LTCC=$LTCC', extracted from \`$ofile'" >&5 ++echo "$as_me: WARNING: using \`LTCC=$LTCC', extracted from \`$ofile'" >&2;} ++ fi ++ fi ++ if test -z "$LTCFLAGS"; then ++ eval "`$SHELL ${ofile} --config | grep '^LTCFLAGS='`" ++ fi ++ ++ # Extract list of available tagged configurations in $ofile. ++ # Note that this assumes the entire list is on one line. ++ available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'` ++ ++ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," ++ for tagname in $tagnames; do ++ IFS="$lt_save_ifs" ++ # Check whether tagname contains only valid characters ++ case `$echo "X$tagname" | $Xsed -e 's:[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]::g'` in ++ "") ;; ++ *) { { echo "$as_me:$LINENO: error: invalid tag name: $tagname" >&5 ++echo "$as_me: error: invalid tag name: $tagname" >&2;} ++ { (exit 1); exit 1; }; } ++ ;; ++ esac ++ ++ if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null ++ then ++ { { echo "$as_me:$LINENO: error: tag name \"$tagname\" already exists" >&5 ++echo "$as_me: error: tag name \"$tagname\" already exists" >&2;} ++ { (exit 1); exit 1; }; } ++ fi ++ ++ # Update the list of available tags. ++ if test -n "$tagname"; then ++ echo appending configuration tag \"$tagname\" to $ofile ++ ++ case $tagname in ++ CXX) ++ if test -n "$CXX" && ( test "X$CXX" != "Xno" && ++ ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || ++ (test "X$CXX" != "Xg++"))) ; then ++ ac_ext=cc ++ac_cpp='$CXXCPP $CPPFLAGS' ++ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ++ ++ ++ ++ ++archive_cmds_need_lc_CXX=no ++allow_undefined_flag_CXX= ++always_export_symbols_CXX=no ++archive_expsym_cmds_CXX= ++export_dynamic_flag_spec_CXX= ++hardcode_direct_CXX=no ++hardcode_libdir_flag_spec_CXX= ++hardcode_libdir_flag_spec_ld_CXX= ++hardcode_libdir_separator_CXX= ++hardcode_minus_L_CXX=no ++hardcode_shlibpath_var_CXX=unsupported ++hardcode_automatic_CXX=no ++module_cmds_CXX= ++module_expsym_cmds_CXX= ++link_all_deplibs_CXX=unknown ++old_archive_cmds_CXX=$old_archive_cmds ++no_undefined_flag_CXX= ++whole_archive_flag_spec_CXX= ++enable_shared_with_static_runtimes_CXX=no ++ ++# Dependencies to place before and after the object being linked: ++predep_objects_CXX= ++postdep_objects_CXX= ++predeps_CXX= ++postdeps_CXX= ++compiler_lib_search_path_CXX= ++ ++# Source file extension for C++ test sources. ++ac_ext=cpp ++ ++# Object file extension for compiled C++ test sources. ++objext=o ++objext_CXX=$objext ++ ++# Code to be used in simple compile tests ++lt_simple_compile_test_code="int some_variable = 0;\n" ++ ++# Code to be used in simple link tests ++lt_simple_link_test_code='int main(int, char *[]) { return(0); }\n' ++ ++# ltmain only uses $CC for tagged configurations so make sure $CC is set. ++ ++# If no C compiler was specified, use CC. ++LTCC=${LTCC-"$CC"} ++ ++# If no C compiler flags were specified, use CFLAGS. ++LTCFLAGS=${LTCFLAGS-"$CFLAGS"} ++ ++# Allow CC to be a program name with arguments. ++compiler=$CC ++ ++ ++# save warnings/boilerplate of simple test code ++ac_outfile=conftest.$ac_objext ++printf "$lt_simple_compile_test_code" >conftest.$ac_ext ++eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err ++_lt_compiler_boilerplate=`cat conftest.err` ++$rm conftest* ++ ++ac_outfile=conftest.$ac_objext ++printf "$lt_simple_link_test_code" >conftest.$ac_ext ++eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err ++_lt_linker_boilerplate=`cat conftest.err` ++$rm conftest* ++ ++ ++# Allow CC to be a program name with arguments. ++lt_save_CC=$CC ++lt_save_LD=$LD ++lt_save_GCC=$GCC ++GCC=$GXX ++lt_save_with_gnu_ld=$with_gnu_ld ++lt_save_path_LD=$lt_cv_path_LD ++if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then ++ lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx ++else ++ $as_unset lt_cv_prog_gnu_ld ++fi ++if test -n "${lt_cv_path_LDCXX+set}"; then ++ lt_cv_path_LD=$lt_cv_path_LDCXX ++else ++ $as_unset lt_cv_path_LD ++fi ++test -z "${LDCXX+set}" || LD=$LDCXX ++CC=${CXX-"c++"} ++compiler=$CC ++compiler_CXX=$CC ++for cc_temp in $compiler""; do ++ case $cc_temp in ++ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; ++ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; ++ \-*) ;; ++ *) break;; ++ esac ++done ++cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` ++ ++ ++# We don't want -fno-exception wen compiling C++ code, so set the ++# no_builtin_flag separately ++if test "$GXX" = yes; then ++ lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' ++else ++ lt_prog_compiler_no_builtin_flag_CXX= ++fi ++ ++if test "$GXX" = yes; then ++ # Set up default GNU C++ configuration ++ ++ ++# Check whether --with-gnu-ld or --without-gnu-ld was given. ++if test "${with_gnu_ld+set}" = set; then ++ withval="$with_gnu_ld" ++ test "$withval" = no || with_gnu_ld=yes ++else ++ with_gnu_ld=no ++fi; ++ac_prog=ld ++if test "$GCC" = yes; then ++ # Check if gcc -print-prog-name=ld gives a path. ++ echo "$as_me:$LINENO: checking for ld used by $CC" >&5 ++echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6 ++ case $host in ++ *-*-mingw*) ++ # gcc leaves a trailing carriage return which upsets mingw ++ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; ++ *) ++ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; ++ esac ++ case $ac_prog in ++ # Accept absolute paths. ++ [\\/]* | ?:[\\/]*) ++ re_direlt='/[^/][^/]*/\.\./' ++ # Canonicalize the pathname of ld ++ ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'` ++ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do ++ ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"` ++ done ++ test -z "$LD" && LD="$ac_prog" ++ ;; ++ "") ++ # If it fails, then pretend we aren't using GCC. ++ ac_prog=ld ++ ;; ++ *) ++ # If it is relative, then search for the first ld in PATH. ++ with_gnu_ld=unknown ++ ;; ++ esac ++elif test "$with_gnu_ld" = yes; then ++ echo "$as_me:$LINENO: checking for GNU ld" >&5 ++echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6 ++else ++ echo "$as_me:$LINENO: checking for non-GNU ld" >&5 ++echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6 ++fi ++if test "${lt_cv_path_LD+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -z "$LD"; then ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++ for ac_dir in $PATH; do ++ IFS="$lt_save_ifs" ++ test -z "$ac_dir" && ac_dir=. ++ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then ++ lt_cv_path_LD="$ac_dir/$ac_prog" ++ # Check to see if the program is GNU ld. I'd rather use --version, ++ # but apparently some variants of GNU ld only accept -v. ++ # Break only if it was the GNU/non-GNU ld that we prefer. ++ case `"$lt_cv_path_LD" -v 2>&1 &5 ++echo "${ECHO_T}$LD" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5 ++echo "$as_me: error: no acceptable ld found in \$PATH" >&2;} ++ { (exit 1); exit 1; }; } ++echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5 ++echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6 ++if test "${lt_cv_prog_gnu_ld+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ # I'd rather use --version here, but apparently some GNU lds only accept -v. ++case `$LD -v 2>&1 &5 ++echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6 ++with_gnu_ld=$lt_cv_prog_gnu_ld ++ ++ ++ ++ # Check if GNU C++ uses GNU ld as the underlying linker, since the ++ # archiving commands below assume that GNU ld is being used. ++ if test "$with_gnu_ld" = yes; then ++ archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ archive_expsym_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ ++ hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' ++ export_dynamic_flag_spec_CXX='${wl}--export-dynamic' ++ ++ # If archive_cmds runs LD, not CC, wlarc should be empty ++ # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to ++ # investigate it a little bit more. (MM) ++ wlarc='${wl}' ++ ++ # ancient GNU ld didn't support --whole-archive et. al. ++ if eval "`$CC -print-prog-name=ld` --help 2>&1" | \ ++ grep 'no-whole-archive' > /dev/null; then ++ whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' ++ else ++ whole_archive_flag_spec_CXX= ++ fi ++ else ++ with_gnu_ld=no ++ wlarc= ++ ++ # A generic and very simple default shared library creation ++ # command for GNU C++ for the case where it uses the native ++ # linker, instead of GNU ld. If possible, this setting should ++ # overridden to take advantage of the native linker features on ++ # the platform it is being used on. ++ archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' ++ fi ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' ++ ++else ++ GXX=no ++ with_gnu_ld=no ++ wlarc= ++fi ++ ++# PORTME: fill in a description of your system's C++ link characteristics ++echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 ++echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6 ++ld_shlibs_CXX=yes ++case $host_os in ++ aix3*) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ aix4* | aix5*) ++ if test "$host_cpu" = ia64; then ++ # On IA64, the linker does run time linking by default, so we don't ++ # have to do anything special. ++ aix_use_runtimelinking=no ++ exp_sym_flag='-Bexport' ++ no_entry_flag="" ++ else ++ aix_use_runtimelinking=no ++ ++ # Test if we are trying to use run time linking or normal ++ # AIX style linking. If -brtl is somewhere in LDFLAGS, we ++ # need to do runtime linking. ++ case $host_os in aix4.[23]|aix4.[23].*|aix5*) ++ for ld_flag in $LDFLAGS; do ++ case $ld_flag in ++ *-brtl*) ++ aix_use_runtimelinking=yes ++ break ++ ;; ++ esac ++ done ++ ;; ++ esac ++ ++ exp_sym_flag='-bexport' ++ no_entry_flag='-bnoentry' ++ fi ++ ++ # When large executables or shared objects are built, AIX ld can ++ # have problems creating the table of contents. If linking a library ++ # or program results in "error TOC overflow" add -mminimal-toc to ++ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not ++ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. ++ ++ archive_cmds_CXX='' ++ hardcode_direct_CXX=yes ++ hardcode_libdir_separator_CXX=':' ++ link_all_deplibs_CXX=yes ++ ++ if test "$GXX" = yes; then ++ case $host_os in aix4.[012]|aix4.[012].*) ++ # We only want to do this on AIX 4.2 and lower, the check ++ # below for broken collect2 doesn't work under 4.3+ ++ collect2name=`${CC} -print-prog-name=collect2` ++ if test -f "$collect2name" && \ ++ strings "$collect2name" | grep resolve_lib_name >/dev/null ++ then ++ # We have reworked collect2 ++ hardcode_direct_CXX=yes ++ else ++ # We have old collect2 ++ hardcode_direct_CXX=unsupported ++ # It fails to find uninstalled libraries when the uninstalled ++ # path is not listed in the libpath. Setting hardcode_minus_L ++ # to unsupported forces relinking ++ hardcode_minus_L_CXX=yes ++ hardcode_libdir_flag_spec_CXX='-L$libdir' ++ hardcode_libdir_separator_CXX= ++ fi ++ ;; ++ esac ++ shared_flag='-shared' ++ if test "$aix_use_runtimelinking" = yes; then ++ shared_flag="$shared_flag "'${wl}-G' ++ fi ++ else ++ # not using gcc ++ if test "$host_cpu" = ia64; then ++ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release ++ # chokes on -Wl,-G. The following line is correct: ++ shared_flag='-G' ++ else ++ if test "$aix_use_runtimelinking" = yes; then ++ shared_flag='${wl}-G' ++ else ++ shared_flag='${wl}-bM:SRE' ++ fi ++ fi ++ fi ++ ++ # It seems that -bexpall does not export symbols beginning with ++ # underscore (_), so it is better to generate a list of symbols to export. ++ always_export_symbols_CXX=yes ++ if test "$aix_use_runtimelinking" = yes; then ++ # Warning - without using the other runtime loading flags (-brtl), ++ # -berok will link without error, but may produce a broken library. ++ allow_undefined_flag_CXX='-berok' ++ # Determine the default libpath from the value encoded in an empty executable. ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext conftest$ac_exeext ++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 ++ (eval $ac_link) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_cxx_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest$ac_exeext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ++aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } ++}'` ++# Check for a 64-bit object if we didn't find anything. ++if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } ++}'`; fi ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++fi ++rm -f conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ++ ++ hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" ++ ++ archive_expsym_cmds_CXX="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" ++ else ++ if test "$host_cpu" = ia64; then ++ hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib' ++ allow_undefined_flag_CXX="-z nodefs" ++ archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" ++ else ++ # Determine the default libpath from the value encoded in an empty executable. ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext conftest$ac_exeext ++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 ++ (eval $ac_link) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_cxx_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest$ac_exeext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ++aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } ++}'` ++# Check for a 64-bit object if we didn't find anything. ++if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } ++}'`; fi ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++fi ++rm -f conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ++ ++ hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" ++ # Warning - without using the other run time loading flags, ++ # -berok will link without error, but may produce a broken library. ++ no_undefined_flag_CXX=' ${wl}-bernotok' ++ allow_undefined_flag_CXX=' ${wl}-berok' ++ # Exported symbols can be pulled into shared objects from archives ++ whole_archive_flag_spec_CXX='$convenience' ++ archive_cmds_need_lc_CXX=yes ++ # This is similar to how AIX traditionally builds its shared libraries. ++ archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' ++ fi ++ fi ++ ;; ++ ++ beos*) ++ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then ++ allow_undefined_flag_CXX=unsupported ++ # Joseph Beckenbach says some releases of gcc ++ # support --undefined. This deserves some investigation. FIXME ++ archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ else ++ ld_shlibs_CXX=no ++ fi ++ ;; ++ ++ chorus*) ++ case $cc_basename in ++ *) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ esac ++ ;; ++ ++ cygwin* | mingw* | pw32*) ++ # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, ++ # as there is no search path for DLLs. ++ hardcode_libdir_flag_spec_CXX='-L$libdir' ++ allow_undefined_flag_CXX=unsupported ++ always_export_symbols_CXX=no ++ enable_shared_with_static_runtimes_CXX=yes ++ ++ if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then ++ archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' ++ # If the export-symbols file already is a .def file (1st line ++ # is EXPORTS), use it as is; otherwise, prepend... ++ archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then ++ cp $export_symbols $output_objdir/$soname.def; ++ else ++ echo EXPORTS > $output_objdir/$soname.def; ++ cat $export_symbols >> $output_objdir/$soname.def; ++ fi~ ++ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' ++ else ++ ld_shlibs_CXX=no ++ fi ++ ;; ++ darwin* | rhapsody*) ++ case $host_os in ++ rhapsody* | darwin1.[012]) ++ allow_undefined_flag_CXX='${wl}-undefined ${wl}suppress' ++ ;; ++ *) # Darwin 1.3 on ++ if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then ++ allow_undefined_flag_CXX='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ++ else ++ case ${MACOSX_DEPLOYMENT_TARGET} in ++ 10.[012]) ++ allow_undefined_flag_CXX='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ++ ;; ++ 10.*) ++ allow_undefined_flag_CXX='${wl}-undefined ${wl}dynamic_lookup' ++ ;; ++ esac ++ fi ++ ;; ++ esac ++ archive_cmds_need_lc_CXX=no ++ hardcode_direct_CXX=no ++ hardcode_automatic_CXX=yes ++ hardcode_shlibpath_var_CXX=unsupported ++ whole_archive_flag_spec_CXX='' ++ link_all_deplibs_CXX=yes ++ ++ if test "$GXX" = yes ; then ++ lt_int_apple_cc_single_mod=no ++ output_verbose_link_cmd='echo' ++ if $CC -dumpspecs 2>&1 | $EGREP 'single_module' >/dev/null ; then ++ lt_int_apple_cc_single_mod=yes ++ fi ++ if test "X$lt_int_apple_cc_single_mod" = Xyes ; then ++ archive_cmds_CXX='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' ++ else ++ archive_cmds_CXX='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' ++ fi ++ module_cmds_CXX='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' ++ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds ++ if test "X$lt_int_apple_cc_single_mod" = Xyes ; then ++ archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ else ++ archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ fi ++ module_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ else ++ case $cc_basename in ++ xlc*) ++ output_verbose_link_cmd='echo' ++ archive_cmds_CXX='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' ++ module_cmds_CXX='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' ++ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds ++ archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ module_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ ;; ++ *) ++ ld_shlibs_CXX=no ++ ;; ++ esac ++ fi ++ ;; ++ ++ dgux*) ++ case $cc_basename in ++ ec++*) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ ghcx*) ++ # Green Hills C++ Compiler ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ *) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ esac ++ ;; ++ freebsd[12]*) ++ # C++ shared libraries reported to be fairly broken before switch to ELF ++ ld_shlibs_CXX=no ++ ;; ++ freebsd-elf*) ++ archive_cmds_need_lc_CXX=no ++ ;; ++ freebsd* | kfreebsd*-gnu | dragonfly*) ++ # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF ++ # conventions ++ ld_shlibs_CXX=yes ++ ;; ++ gnu*) ++ ;; ++ hpux9*) ++ hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' ++ hardcode_libdir_separator_CXX=: ++ export_dynamic_flag_spec_CXX='${wl}-E' ++ hardcode_direct_CXX=yes ++ hardcode_minus_L_CXX=yes # Not in the search PATH, ++ # but as the default ++ # location of the library. ++ ++ case $cc_basename in ++ CC*) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ aCC*) ++ archive_cmds_CXX='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ # ++ # There doesn't appear to be a way to prevent this compiler from ++ # explicitly linking system object files so we need to strip them ++ # from the output so that they don't get included in the library ++ # dependencies. ++ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "[-]L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ++ ;; ++ *) ++ if test "$GXX" = yes; then ++ archive_cmds_CXX='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ++ else ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ fi ++ ;; ++ esac ++ ;; ++ hpux10*|hpux11*) ++ if test $with_gnu_ld = no; then ++ hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' ++ hardcode_libdir_separator_CXX=: ++ ++ case $host_cpu in ++ hppa*64*|ia64*) ++ hardcode_libdir_flag_spec_ld_CXX='+b $libdir' ++ ;; ++ *) ++ export_dynamic_flag_spec_CXX='${wl}-E' ++ ;; ++ esac ++ fi ++ case $host_cpu in ++ hppa*64*|ia64*) ++ hardcode_direct_CXX=no ++ hardcode_shlibpath_var_CXX=no ++ ;; ++ *) ++ hardcode_direct_CXX=yes ++ hardcode_minus_L_CXX=yes # Not in the search PATH, ++ # but as the default ++ # location of the library. ++ ;; ++ esac ++ ++ case $cc_basename in ++ CC*) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ aCC*) ++ case $host_cpu in ++ hppa*64*) ++ archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ ;; ++ ia64*) ++ archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ ;; ++ *) ++ archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ ;; ++ esac ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ # ++ # There doesn't appear to be a way to prevent this compiler from ++ # explicitly linking system object files so we need to strip them ++ # from the output so that they don't get included in the library ++ # dependencies. ++ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ++ ;; ++ *) ++ if test "$GXX" = yes; then ++ if test $with_gnu_ld = no; then ++ case $host_cpu in ++ hppa*64*) ++ archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ ;; ++ ia64*) ++ archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ ;; ++ *) ++ archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ ;; ++ esac ++ fi ++ else ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ fi ++ ;; ++ esac ++ ;; ++ interix3*) ++ hardcode_direct_CXX=no ++ hardcode_shlibpath_var_CXX=no ++ hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' ++ export_dynamic_flag_spec_CXX='${wl}-E' ++ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. ++ # Instead, shared libraries are loaded at an image base (0x10000000 by ++ # default) and relocated if they conflict, which is a slow very memory ++ # consuming and fragmenting process. To avoid this, we pick a random, ++ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link ++ # time. Moving up from 0x10000000 also allows more sbrk(2) space. ++ archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ++ archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ++ ;; ++ irix5* | irix6*) ++ case $cc_basename in ++ CC*) ++ # SGI C++ ++ archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' ++ ++ # Archives containing C++ object files must be created using ++ # "CC -ar", where "CC" is the IRIX C++ compiler. This is ++ # necessary to make sure instantiated templates are included ++ # in the archive. ++ old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' ++ ;; ++ *) ++ if test "$GXX" = yes; then ++ if test "$with_gnu_ld" = no; then ++ archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ else ++ archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib' ++ fi ++ fi ++ link_all_deplibs_CXX=yes ++ ;; ++ esac ++ hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' ++ hardcode_libdir_separator_CXX=: ++ ;; ++ linux*) ++ case $cc_basename in ++ KCC*) ++ # Kuck and Associates, Inc. (KAI) C++ Compiler ++ ++ # KCC will only create a shared library if the output file ++ # ends with ".so" (or ".sl" for HP-UX), so rename the library ++ # to its proper name (with version) after linking. ++ archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' ++ archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ # ++ # There doesn't appear to be a way to prevent this compiler from ++ # explicitly linking system object files so we need to strip them ++ # from the output so that they don't get included in the library ++ # dependencies. ++ output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ++ ++ hardcode_libdir_flag_spec_CXX='${wl}--rpath,$libdir' ++ export_dynamic_flag_spec_CXX='${wl}--export-dynamic' ++ ++ # Archives containing C++ object files must be created using ++ # "CC -Bstatic", where "CC" is the KAI C++ compiler. ++ old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ++ ;; ++ icpc*) ++ # Intel C++ ++ with_gnu_ld=yes ++ # version 8.0 and above of icpc choke on multiply defined symbols ++ # if we add $predep_objects and $postdep_objects, however 7.1 and ++ # earlier do not add the objects themselves. ++ case `$CC -V 2>&1` in ++ *"Version 7."*) ++ archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ ;; ++ *) # Version 8.0 or newer ++ tmp_idyn= ++ case $host_cpu in ++ ia64*) tmp_idyn=' -i_dynamic';; ++ esac ++ archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ ;; ++ esac ++ archive_cmds_need_lc_CXX=no ++ hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' ++ export_dynamic_flag_spec_CXX='${wl}--export-dynamic' ++ whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' ++ ;; ++ pgCC*) ++ # Portland Group C++ compiler ++ archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' ++ archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ++ ++ hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' ++ export_dynamic_flag_spec_CXX='${wl}--export-dynamic' ++ whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' ++ ;; ++ cxx*) ++ # Compaq C++ ++ archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' ++ ++ runpath_var=LD_RUN_PATH ++ hardcode_libdir_flag_spec_CXX='-rpath $libdir' ++ hardcode_libdir_separator_CXX=: ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ # ++ # There doesn't appear to be a way to prevent this compiler from ++ # explicitly linking system object files so we need to strip them ++ # from the output so that they don't get included in the library ++ # dependencies. ++ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ++ ;; ++ esac ++ ;; ++ lynxos*) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ m88k*) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ mvs*) ++ case $cc_basename in ++ cxx*) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ *) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ esac ++ ;; ++ netbsd*) ++ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then ++ archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' ++ wlarc= ++ hardcode_libdir_flag_spec_CXX='-R$libdir' ++ hardcode_direct_CXX=yes ++ hardcode_shlibpath_var_CXX=no ++ fi ++ # Workaround some broken pre-1.5 toolchains ++ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ++ ;; ++ openbsd2*) ++ # C++ shared libraries are fairly broken ++ ld_shlibs_CXX=no ++ ;; ++ openbsd*) ++ hardcode_direct_CXX=yes ++ hardcode_shlibpath_var_CXX=no ++ archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' ++ hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' ++ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then ++ archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' ++ export_dynamic_flag_spec_CXX='${wl}-E' ++ whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' ++ fi ++ output_verbose_link_cmd='echo' ++ ;; ++ osf3*) ++ case $cc_basename in ++ KCC*) ++ # Kuck and Associates, Inc. (KAI) C++ Compiler ++ ++ # KCC will only create a shared library if the output file ++ # ends with ".so" (or ".sl" for HP-UX), so rename the library ++ # to its proper name (with version) after linking. ++ archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' ++ ++ hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' ++ hardcode_libdir_separator_CXX=: ++ ++ # Archives containing C++ object files must be created using ++ # "CC -Bstatic", where "CC" is the KAI C++ compiler. ++ old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ++ ++ ;; ++ RCC*) ++ # Rational C++ 2.4.1 ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ cxx*) ++ allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' ++ archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' ++ ++ hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' ++ hardcode_libdir_separator_CXX=: ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ # ++ # There doesn't appear to be a way to prevent this compiler from ++ # explicitly linking system object files so we need to strip them ++ # from the output so that they don't get included in the library ++ # dependencies. ++ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ++ ;; ++ *) ++ if test "$GXX" = yes && test "$with_gnu_ld" = no; then ++ allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' ++ archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ ++ hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' ++ hardcode_libdir_separator_CXX=: ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' ++ ++ else ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ fi ++ ;; ++ esac ++ ;; ++ osf4* | osf5*) ++ case $cc_basename in ++ KCC*) ++ # Kuck and Associates, Inc. (KAI) C++ Compiler ++ ++ # KCC will only create a shared library if the output file ++ # ends with ".so" (or ".sl" for HP-UX), so rename the library ++ # to its proper name (with version) after linking. ++ archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' ++ ++ hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' ++ hardcode_libdir_separator_CXX=: ++ ++ # Archives containing C++ object files must be created using ++ # the KAI C++ compiler. ++ old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ++ ;; ++ RCC*) ++ # Rational C++ 2.4.1 ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ cxx*) ++ allow_undefined_flag_CXX=' -expect_unresolved \*' ++ archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' ++ archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ ++ echo "-hidden">> $lib.exp~ ++ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~ ++ $rm $lib.exp' ++ ++ hardcode_libdir_flag_spec_CXX='-rpath $libdir' ++ hardcode_libdir_separator_CXX=: ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ # ++ # There doesn't appear to be a way to prevent this compiler from ++ # explicitly linking system object files so we need to strip them ++ # from the output so that they don't get included in the library ++ # dependencies. ++ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ++ ;; ++ *) ++ if test "$GXX" = yes && test "$with_gnu_ld" = no; then ++ allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' ++ archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ ++ hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' ++ hardcode_libdir_separator_CXX=: ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' ++ ++ else ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ fi ++ ;; ++ esac ++ ;; ++ psos*) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ sunos4*) ++ case $cc_basename in ++ CC*) ++ # Sun C++ 4.x ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ lcc*) ++ # Lucid ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ *) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ esac ++ ;; ++ solaris*) ++ case $cc_basename in ++ CC*) ++ # Sun C++ 4.2, 5.x and Centerline C++ ++ archive_cmds_need_lc_CXX=yes ++ no_undefined_flag_CXX=' -zdefs' ++ archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ ++ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' ++ ++ hardcode_libdir_flag_spec_CXX='-R$libdir' ++ hardcode_shlibpath_var_CXX=no ++ case $host_os in ++ solaris2.[0-5] | solaris2.[0-5].*) ;; ++ *) ++ # The C++ compiler is used as linker so we must use $wl ++ # flag to pass the commands to the underlying system ++ # linker. We must also pass each convience library through ++ # to the system linker between allextract/defaultextract. ++ # The C++ compiler will combine linker options so we ++ # cannot just pass the convience library names through ++ # without $wl. ++ # Supported since Solaris 2.6 (maybe 2.5.1?) ++ whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ++ ;; ++ esac ++ link_all_deplibs_CXX=yes ++ ++ output_verbose_link_cmd='echo' ++ ++ # Archives containing C++ object files must be created using ++ # "CC -xar", where "CC" is the Sun C++ compiler. This is ++ # necessary to make sure instantiated templates are included ++ # in the archive. ++ old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' ++ ;; ++ gcx*) ++ # Green Hills C++ Compiler ++ archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' ++ ++ # The C++ compiler must be used to create the archive. ++ old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ++ ;; ++ *) ++ # GNU C++ compiler with Solaris linker ++ if test "$GXX" = yes && test "$with_gnu_ld" = no; then ++ no_undefined_flag_CXX=' ${wl}-z ${wl}defs' ++ if $CC --version | grep -v '^2\.7' > /dev/null; then ++ archive_cmds_CXX='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' ++ archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ ++ $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" ++ else ++ # g++ 2.7 appears to require `-G' NOT `-shared' on this ++ # platform. ++ archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' ++ archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ ++ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" ++ fi ++ ++ hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir' ++ fi ++ ;; ++ esac ++ ;; ++ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) ++ no_undefined_flag_CXX='${wl}-z,text' ++ archive_cmds_need_lc_CXX=no ++ hardcode_shlibpath_var_CXX=no ++ runpath_var='LD_RUN_PATH' ++ ++ case $cc_basename in ++ CC*) ++ archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ *) ++ archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ esac ++ ;; ++ sysv5* | sco3.2v5* | sco5v6*) ++ # Note: We can NOT use -z defs as we might desire, because we do not ++ # link with -lc, and that would cause any symbols used from libc to ++ # always be unresolved, which means just about no library would ++ # ever link correctly. If we're not using GNU ld we use -z text ++ # though, which does catch some bad symbols but isn't as heavy-handed ++ # as -z defs. ++ # For security reasons, it is highly recommended that you always ++ # use absolute paths for naming shared libraries, and exclude the ++ # DT_RUNPATH tag from executables and libraries. But doing so ++ # requires that you compile everything twice, which is a pain. ++ # So that behaviour is only enabled if SCOABSPATH is set to a ++ # non-empty value in the environment. Most likely only useful for ++ # creating official distributions of packages. ++ # This is a hack until libtool officially supports absolute path ++ # names for shared libraries. ++ no_undefined_flag_CXX='${wl}-z,text' ++ allow_undefined_flag_CXX='${wl}-z,nodefs' ++ archive_cmds_need_lc_CXX=no ++ hardcode_shlibpath_var_CXX=no ++ hardcode_libdir_flag_spec_CXX='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' ++ hardcode_libdir_separator_CXX=':' ++ link_all_deplibs_CXX=yes ++ export_dynamic_flag_spec_CXX='${wl}-Bexport' ++ runpath_var='LD_RUN_PATH' ++ ++ case $cc_basename in ++ CC*) ++ archive_cmds_CXX='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ *) ++ archive_cmds_CXX='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ esac ++ ;; ++ tandem*) ++ case $cc_basename in ++ NCC*) ++ # NonStop-UX NCC 3.20 ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ *) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ esac ++ ;; ++ vxworks*) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ *) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++esac ++echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5 ++echo "${ECHO_T}$ld_shlibs_CXX" >&6 ++test "$ld_shlibs_CXX" = no && can_build_shared=no ++ ++GCC_CXX="$GXX" ++LD_CXX="$LD" ++ ++ ++cat > conftest.$ac_ext <&5 ++ (eval $ac_compile) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; then ++ # Parse the compiler output and extract the necessary ++ # objects, libraries and library flags. ++ ++ # Sentinel used to keep track of whether or not we are before ++ # the conftest object file. ++ pre_test_object_deps_done=no ++ ++ # The `*' in the case matches for architectures that use `case' in ++ # $output_verbose_cmd can trigger glob expansion during the loop ++ # eval without this substitution. ++ output_verbose_link_cmd=`$echo "X$output_verbose_link_cmd" | $Xsed -e "$no_glob_subst"` ++ ++ for p in `eval $output_verbose_link_cmd`; do ++ case $p in ++ ++ -L* | -R* | -l*) ++ # Some compilers place space between "-{L,R}" and the path. ++ # Remove the space. ++ if test $p = "-L" \ ++ || test $p = "-R"; then ++ prev=$p ++ continue ++ else ++ prev= ++ fi ++ ++ if test "$pre_test_object_deps_done" = no; then ++ case $p in ++ -L* | -R*) ++ # Internal compiler library paths should come after those ++ # provided the user. The postdeps already come after the ++ # user supplied libs so there is no need to process them. ++ if test -z "$compiler_lib_search_path_CXX"; then ++ compiler_lib_search_path_CXX="${prev}${p}" ++ else ++ compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}" ++ fi ++ ;; ++ # The "-l" case would never come before the object being ++ # linked, so don't bother handling this case. ++ esac ++ else ++ if test -z "$postdeps_CXX"; then ++ postdeps_CXX="${prev}${p}" ++ else ++ postdeps_CXX="${postdeps_CXX} ${prev}${p}" ++ fi ++ fi ++ ;; ++ ++ *.$objext) ++ # This assumes that the test object file only shows up ++ # once in the compiler output. ++ if test "$p" = "conftest.$objext"; then ++ pre_test_object_deps_done=yes ++ continue ++ fi ++ ++ if test "$pre_test_object_deps_done" = no; then ++ if test -z "$predep_objects_CXX"; then ++ predep_objects_CXX="$p" ++ else ++ predep_objects_CXX="$predep_objects_CXX $p" ++ fi ++ else ++ if test -z "$postdep_objects_CXX"; then ++ postdep_objects_CXX="$p" ++ else ++ postdep_objects_CXX="$postdep_objects_CXX $p" ++ fi ++ fi ++ ;; ++ ++ *) ;; # Ignore the rest. ++ ++ esac ++ done ++ ++ # Clean up. ++ rm -f a.out a.exe ++else ++ echo "libtool.m4: error: problem compiling CXX test program" ++fi ++ ++$rm -f confest.$objext ++ ++# PORTME: override above test on systems where it is broken ++case $host_os in ++interix3*) ++ # Interix 3.5 installs completely hosed .la files for C++, so rather than ++ # hack all around it, let's just trust "g++" to DTRT. ++ predep_objects_CXX= ++ postdep_objects_CXX= ++ postdeps_CXX= ++ ;; ++ ++solaris*) ++ case $cc_basename in ++ CC*) ++ # Adding this requires a known-good setup of shared libraries for ++ # Sun compiler versions before 5.6, else PIC objects from an old ++ # archive will be linked into the output, leading to subtle bugs. ++ postdeps_CXX='-lCstd -lCrun' ++ ;; ++ esac ++ ;; ++esac ++ ++ ++case " $postdeps_CXX " in ++*" -lc "*) archive_cmds_need_lc_CXX=no ;; ++esac ++ ++lt_prog_compiler_wl_CXX= ++lt_prog_compiler_pic_CXX= ++lt_prog_compiler_static_CXX= ++ ++echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 ++echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 ++ ++ # C++ specific cases for pic, static, wl, etc. ++ if test "$GXX" = yes; then ++ lt_prog_compiler_wl_CXX='-Wl,' ++ lt_prog_compiler_static_CXX='-static' ++ ++ case $host_os in ++ aix*) ++ # All AIX code is PIC. ++ if test "$host_cpu" = ia64; then ++ # AIX 5 now supports IA64 processor ++ lt_prog_compiler_static_CXX='-Bstatic' ++ fi ++ ;; ++ amigaos*) ++ # FIXME: we need at least 68020 code to build shared libraries, but ++ # adding the `-m68020' flag to GCC prevents building anything better, ++ # like `-m68040'. ++ lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' ++ ;; ++ beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) ++ # PIC is the default for these OSes. ++ ;; ++ mingw* | os2* | pw32*) ++ # This hack is so that the source file can tell whether it is being ++ # built for inclusion in a dll (and should export symbols for example). ++ lt_prog_compiler_pic_CXX='-DDLL_EXPORT' ++ ;; ++ darwin* | rhapsody*) ++ # PIC is the default on this platform ++ # Common symbols not allowed in MH_DYLIB files ++ lt_prog_compiler_pic_CXX='-fno-common' ++ ;; ++ *djgpp*) ++ # DJGPP does not support shared libraries at all ++ lt_prog_compiler_pic_CXX= ++ ;; ++ interix3*) ++ # Interix 3.x gcc -fpic/-fPIC options generate broken code. ++ # Instead, we relocate shared libraries at runtime. ++ ;; ++ sysv4*MP*) ++ if test -d /usr/nec; then ++ lt_prog_compiler_pic_CXX=-Kconform_pic ++ fi ++ ;; ++ hpux*) ++ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but ++ # not for PA HP-UX. ++ case $host_cpu in ++ hppa*64*|ia64*) ++ ;; ++ *) ++ lt_prog_compiler_pic_CXX='-fPIC' ++ ;; ++ esac ++ ;; ++ *) ++ lt_prog_compiler_pic_CXX='-fPIC' ++ ;; ++ esac ++ else ++ case $host_os in ++ aix4* | aix5*) ++ # All AIX code is PIC. ++ if test "$host_cpu" = ia64; then ++ # AIX 5 now supports IA64 processor ++ lt_prog_compiler_static_CXX='-Bstatic' ++ else ++ lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' ++ fi ++ ;; ++ chorus*) ++ case $cc_basename in ++ cxch68*) ++ # Green Hills C++ Compiler ++ # _LT_AC_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ++ ;; ++ esac ++ ;; ++ darwin*) ++ # PIC is the default on this platform ++ # Common symbols not allowed in MH_DYLIB files ++ case $cc_basename in ++ xlc*) ++ lt_prog_compiler_pic_CXX='-qnocommon' ++ lt_prog_compiler_wl_CXX='-Wl,' ++ ;; ++ esac ++ ;; ++ dgux*) ++ case $cc_basename in ++ ec++*) ++ lt_prog_compiler_pic_CXX='-KPIC' ++ ;; ++ ghcx*) ++ # Green Hills C++ Compiler ++ lt_prog_compiler_pic_CXX='-pic' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ freebsd* | kfreebsd*-gnu | dragonfly*) ++ # FreeBSD uses GNU C++ ++ ;; ++ hpux9* | hpux10* | hpux11*) ++ case $cc_basename in ++ CC*) ++ lt_prog_compiler_wl_CXX='-Wl,' ++ lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' ++ if test "$host_cpu" != ia64; then ++ lt_prog_compiler_pic_CXX='+Z' ++ fi ++ ;; ++ aCC*) ++ lt_prog_compiler_wl_CXX='-Wl,' ++ lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' ++ case $host_cpu in ++ hppa*64*|ia64*) ++ # +Z the default ++ ;; ++ *) ++ lt_prog_compiler_pic_CXX='+Z' ++ ;; ++ esac ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ interix*) ++ # This is c89, which is MS Visual C++ (no shared libs) ++ # Anyone wants to do a port? ++ ;; ++ irix5* | irix6* | nonstopux*) ++ case $cc_basename in ++ CC*) ++ lt_prog_compiler_wl_CXX='-Wl,' ++ lt_prog_compiler_static_CXX='-non_shared' ++ # CC pic flag -KPIC is the default. ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ linux*) ++ case $cc_basename in ++ KCC*) ++ # KAI C++ Compiler ++ lt_prog_compiler_wl_CXX='--backend -Wl,' ++ lt_prog_compiler_pic_CXX='-fPIC' ++ ;; ++ icpc* | ecpc*) ++ # Intel C++ ++ lt_prog_compiler_wl_CXX='-Wl,' ++ lt_prog_compiler_pic_CXX='-KPIC' ++ lt_prog_compiler_static_CXX='-static' ++ ;; ++ pgCC*) ++ # Portland Group C++ compiler. ++ lt_prog_compiler_wl_CXX='-Wl,' ++ lt_prog_compiler_pic_CXX='-fpic' ++ lt_prog_compiler_static_CXX='-Bstatic' ++ ;; ++ cxx*) ++ # Compaq C++ ++ # Make sure the PIC flag is empty. It appears that all Alpha ++ # Linux and Compaq Tru64 Unix objects are PIC. ++ lt_prog_compiler_pic_CXX= ++ lt_prog_compiler_static_CXX='-non_shared' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ lynxos*) ++ ;; ++ m88k*) ++ ;; ++ mvs*) ++ case $cc_basename in ++ cxx*) ++ lt_prog_compiler_pic_CXX='-W c,exportall' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ netbsd*) ++ ;; ++ osf3* | osf4* | osf5*) ++ case $cc_basename in ++ KCC*) ++ lt_prog_compiler_wl_CXX='--backend -Wl,' ++ ;; ++ RCC*) ++ # Rational C++ 2.4.1 ++ lt_prog_compiler_pic_CXX='-pic' ++ ;; ++ cxx*) ++ # Digital/Compaq C++ ++ lt_prog_compiler_wl_CXX='-Wl,' ++ # Make sure the PIC flag is empty. It appears that all Alpha ++ # Linux and Compaq Tru64 Unix objects are PIC. ++ lt_prog_compiler_pic_CXX= ++ lt_prog_compiler_static_CXX='-non_shared' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ psos*) ++ ;; ++ solaris*) ++ case $cc_basename in ++ CC*) ++ # Sun C++ 4.2, 5.x and Centerline C++ ++ lt_prog_compiler_pic_CXX='-KPIC' ++ lt_prog_compiler_static_CXX='-Bstatic' ++ lt_prog_compiler_wl_CXX='-Qoption ld ' ++ ;; ++ gcx*) ++ # Green Hills C++ Compiler ++ lt_prog_compiler_pic_CXX='-PIC' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ sunos4*) ++ case $cc_basename in ++ CC*) ++ # Sun C++ 4.x ++ lt_prog_compiler_pic_CXX='-pic' ++ lt_prog_compiler_static_CXX='-Bstatic' ++ ;; ++ lcc*) ++ # Lucid ++ lt_prog_compiler_pic_CXX='-pic' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ tandem*) ++ case $cc_basename in ++ NCC*) ++ # NonStop-UX NCC 3.20 ++ lt_prog_compiler_pic_CXX='-KPIC' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) ++ case $cc_basename in ++ CC*) ++ lt_prog_compiler_wl_CXX='-Wl,' ++ lt_prog_compiler_pic_CXX='-KPIC' ++ lt_prog_compiler_static_CXX='-Bstatic' ++ ;; ++ esac ++ ;; ++ vxworks*) ++ ;; ++ *) ++ lt_prog_compiler_can_build_shared_CXX=no ++ ;; ++ esac ++ fi ++ ++echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_CXX" >&5 ++echo "${ECHO_T}$lt_prog_compiler_pic_CXX" >&6 ++ ++# ++# Check to make sure the PIC flag actually works. ++# ++if test -n "$lt_prog_compiler_pic_CXX"; then ++ ++echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 ++echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... $ECHO_C" >&6 ++if test "${lt_prog_compiler_pic_works_CXX+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ lt_prog_compiler_pic_works_CXX=no ++ ac_outfile=conftest.$ac_objext ++ printf "$lt_simple_compile_test_code" > conftest.$ac_ext ++ lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" ++ # Insert the option either (1) after the last *FLAGS variable, or ++ # (2) before a word containing "conftest.", or (3) at the end. ++ # Note that $ac_compile itself does not contain backslashes and begins ++ # with a dollar sign (not a hyphen), so the echo should work correctly. ++ # The option is referenced via a variable to avoid confusing sed. ++ lt_compile=`echo "$ac_compile" | $SED \ ++ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ ++ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ ++ -e 's:$: $lt_compiler_flag:'` ++ (eval echo "\"\$as_me:14196: $lt_compile\"" >&5) ++ (eval "$lt_compile" 2>conftest.err) ++ ac_status=$? ++ cat conftest.err >&5 ++ echo "$as_me:14200: \$? = $ac_status" >&5 ++ if (exit $ac_status) && test -s "$ac_outfile"; then ++ # The compiler can only warn and ignore the option if not recognized ++ # So say no if there are warnings other than the usual output. ++ $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp ++ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 ++ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then ++ lt_prog_compiler_pic_works_CXX=yes ++ fi ++ fi ++ $rm conftest* ++ ++fi ++echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_CXX" >&5 ++echo "${ECHO_T}$lt_prog_compiler_pic_works_CXX" >&6 ++ ++if test x"$lt_prog_compiler_pic_works_CXX" = xyes; then ++ case $lt_prog_compiler_pic_CXX in ++ "" | " "*) ;; ++ *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; ++ esac ++else ++ lt_prog_compiler_pic_CXX= ++ lt_prog_compiler_can_build_shared_CXX=no ++fi ++ ++fi ++case $host_os in ++ # For platforms which do not support PIC, -DPIC is meaningless: ++ *djgpp*) ++ lt_prog_compiler_pic_CXX= ++ ;; ++ *) ++ lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" ++ ;; ++esac ++ ++# ++# Check to make sure the static flag actually works. ++# ++wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" ++echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 ++echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6 ++if test "${lt_prog_compiler_static_works_CXX+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ lt_prog_compiler_static_works_CXX=no ++ save_LDFLAGS="$LDFLAGS" ++ LDFLAGS="$LDFLAGS $lt_tmp_static_flag" ++ printf "$lt_simple_link_test_code" > conftest.$ac_ext ++ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then ++ # The linker can only warn and ignore the option if not recognized ++ # So say no if there are warnings ++ if test -s conftest.err; then ++ # Append any errors to the config.log. ++ cat conftest.err 1>&5 ++ $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp ++ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 ++ if diff conftest.exp conftest.er2 >/dev/null; then ++ lt_prog_compiler_static_works_CXX=yes ++ fi ++ else ++ lt_prog_compiler_static_works_CXX=yes ++ fi ++ fi ++ $rm conftest* ++ LDFLAGS="$save_LDFLAGS" ++ ++fi ++echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works_CXX" >&5 ++echo "${ECHO_T}$lt_prog_compiler_static_works_CXX" >&6 ++ ++if test x"$lt_prog_compiler_static_works_CXX" = xyes; then ++ : ++else ++ lt_prog_compiler_static_CXX= ++fi ++ ++ ++echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 ++echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6 ++if test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ lt_cv_prog_compiler_c_o_CXX=no ++ $rm -r conftest 2>/dev/null ++ mkdir conftest ++ cd conftest ++ mkdir out ++ printf "$lt_simple_compile_test_code" > conftest.$ac_ext ++ ++ lt_compiler_flag="-o out/conftest2.$ac_objext" ++ # Insert the option either (1) after the last *FLAGS variable, or ++ # (2) before a word containing "conftest.", or (3) at the end. ++ # Note that $ac_compile itself does not contain backslashes and begins ++ # with a dollar sign (not a hyphen), so the echo should work correctly. ++ lt_compile=`echo "$ac_compile" | $SED \ ++ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ ++ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ ++ -e 's:$: $lt_compiler_flag:'` ++ (eval echo "\"\$as_me:14300: $lt_compile\"" >&5) ++ (eval "$lt_compile" 2>out/conftest.err) ++ ac_status=$? ++ cat out/conftest.err >&5 ++ echo "$as_me:14304: \$? = $ac_status" >&5 ++ if (exit $ac_status) && test -s out/conftest2.$ac_objext ++ then ++ # The compiler can only warn and ignore the option if not recognized ++ # So say no if there are warnings ++ $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp ++ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 ++ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then ++ lt_cv_prog_compiler_c_o_CXX=yes ++ fi ++ fi ++ chmod u+w . 2>&5 ++ $rm conftest* ++ # SGI C++ compiler will create directory out/ii_files/ for ++ # template instantiation ++ test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files ++ $rm out/* && rmdir out ++ cd .. ++ rmdir conftest ++ $rm conftest* ++ ++fi ++echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_CXX" >&5 ++echo "${ECHO_T}$lt_cv_prog_compiler_c_o_CXX" >&6 ++ ++ ++hard_links="nottested" ++if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then ++ # do not overwrite the value of need_locks provided by the user ++ echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 ++echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6 ++ hard_links=yes ++ $rm conftest* ++ ln conftest.a conftest.b 2>/dev/null && hard_links=no ++ touch conftest.a ++ ln conftest.a conftest.b 2>&5 || hard_links=no ++ ln conftest.a conftest.b 2>/dev/null && hard_links=no ++ echo "$as_me:$LINENO: result: $hard_links" >&5 ++echo "${ECHO_T}$hard_links" >&6 ++ if test "$hard_links" = no; then ++ { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 ++echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} ++ need_locks=warn ++ fi ++else ++ need_locks=no ++fi ++ ++echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 ++echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6 ++ ++ export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ++ case $host_os in ++ aix4* | aix5*) ++ # If we're using GNU nm, then we don't want the "-C" option. ++ # -C means demangle to AIX nm, but means don't demangle with GNU nm ++ if $NM -V 2>&1 | grep 'GNU' > /dev/null; then ++ export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' ++ else ++ export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' ++ fi ++ ;; ++ pw32*) ++ export_symbols_cmds_CXX="$ltdll_cmds" ++ ;; ++ cygwin* | mingw*) ++ export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/;/^.* __nm__/s/^.* __nm__\([^ ]*\) [^ ]*/\1 DATA/;/^I /d;/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' ++ ;; ++ *) ++ export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ++ ;; ++ esac ++ ++echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5 ++echo "${ECHO_T}$ld_shlibs_CXX" >&6 ++test "$ld_shlibs_CXX" = no && can_build_shared=no ++ ++# ++# Do we need to explicitly link libc? ++# ++case "x$archive_cmds_need_lc_CXX" in ++x|xyes) ++ # Assume -lc should be added ++ archive_cmds_need_lc_CXX=yes ++ ++ if test "$enable_shared" = yes && test "$GCC" = yes; then ++ case $archive_cmds_CXX in ++ *'~'*) ++ # FIXME: we may have to deal with multi-command sequences. ++ ;; ++ '$CC '*) ++ # Test whether the compiler implicitly links with -lc since on some ++ # systems, -lgcc has to come before -lc. If gcc already passes -lc ++ # to ld, don't add -lc before -lgcc. ++ echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 ++echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6 ++ $rm conftest* ++ printf "$lt_simple_compile_test_code" > conftest.$ac_ext ++ ++ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } 2>conftest.err; then ++ soname=conftest ++ lib=conftest ++ libobjs=conftest.$ac_objext ++ deplibs= ++ wl=$lt_prog_compiler_wl_CXX ++ pic_flag=$lt_prog_compiler_pic_CXX ++ compiler_flags=-v ++ linker_flags=-v ++ verstring= ++ output_objdir=. ++ libname=conftest ++ lt_save_allow_undefined_flag=$allow_undefined_flag_CXX ++ allow_undefined_flag_CXX= ++ if { (eval echo "$as_me:$LINENO: \"$archive_cmds_CXX 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 ++ (eval $archive_cmds_CXX 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } ++ then ++ archive_cmds_need_lc_CXX=no ++ else ++ archive_cmds_need_lc_CXX=yes ++ fi ++ allow_undefined_flag_CXX=$lt_save_allow_undefined_flag ++ else ++ cat conftest.err 1>&5 ++ fi ++ $rm conftest* ++ echo "$as_me:$LINENO: result: $archive_cmds_need_lc_CXX" >&5 ++echo "${ECHO_T}$archive_cmds_need_lc_CXX" >&6 ++ ;; ++ esac ++ fi ++ ;; ++esac ++ ++echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 ++echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6 ++library_names_spec= ++libname_spec='lib$name' ++soname_spec= ++shrext_cmds=".so" ++postinstall_cmds= ++postuninstall_cmds= ++finish_cmds= ++finish_eval= ++shlibpath_var= ++shlibpath_overrides_runpath=unknown ++version_type=none ++dynamic_linker="$host_os ld.so" ++sys_lib_dlsearch_path_spec="/lib /usr/lib" ++if test "$GCC" = yes; then ++ sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` ++ if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then ++ # if the path contains ";" then we assume it to be the separator ++ # otherwise default to the standard path separator (i.e. ":") - it is ++ # assumed that no part of a normal pathname contains ";" but that should ++ # okay in the real world where ";" in dirpaths is itself problematic. ++ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` ++ else ++ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ++ fi ++else ++ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" ++fi ++need_lib_prefix=unknown ++hardcode_into_libs=no ++ ++# when you set need_version to no, make sure it does not cause -set_version ++# flags to be left without arguments ++need_version=unknown ++ ++case $host_os in ++aix3*) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' ++ shlibpath_var=LIBPATH ++ ++ # AIX 3 has no versioning support, so we append a major version to the name. ++ soname_spec='${libname}${release}${shared_ext}$major' ++ ;; ++ ++aix4* | aix5*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ hardcode_into_libs=yes ++ if test "$host_cpu" = ia64; then ++ # AIX 5 supports IA64 ++ library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' ++ shlibpath_var=LD_LIBRARY_PATH ++ else ++ # With GCC up to 2.95.x, collect2 would create an import file ++ # for dependence libraries. The import file would start with ++ # the line `#! .'. This would cause the generated library to ++ # depend on `.', always an invalid library. This was fixed in ++ # development snapshots of GCC prior to 3.0. ++ case $host_os in ++ aix4 | aix4.[01] | aix4.[01].*) ++ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' ++ echo ' yes ' ++ echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then ++ : ++ else ++ can_build_shared=no ++ fi ++ ;; ++ esac ++ # AIX (on Power*) has no versioning support, so currently we can not hardcode correct ++ # soname into executable. Probably we can add versioning support to ++ # collect2, so additional links can be useful in future. ++ if test "$aix_use_runtimelinking" = yes; then ++ # If using run time linking (on AIX 4.2 or later) use lib.so ++ # instead of lib.a to let people know that these are not ++ # typical AIX shared libraries. ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ else ++ # We preserve .a as extension for shared libraries through AIX4.2 ++ # and later when we are not doing run time linking. ++ library_names_spec='${libname}${release}.a $libname.a' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ fi ++ shlibpath_var=LIBPATH ++ fi ++ ;; ++ ++amigaos*) ++ library_names_spec='$libname.ixlibrary $libname.a' ++ # Create ${libname}_ixlibrary.a entries in /sys/libs. ++ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ++ ;; ++ ++beos*) ++ library_names_spec='${libname}${shared_ext}' ++ dynamic_linker="$host_os ld.so" ++ shlibpath_var=LIBRARY_PATH ++ ;; ++ ++bsdi[45]*) ++ version_type=linux ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" ++ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" ++ # the default ld.so.conf also contains /usr/contrib/lib and ++ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow ++ # libtool to hard-code these into programs ++ ;; ++ ++cygwin* | mingw* | pw32*) ++ version_type=windows ++ shrext_cmds=".dll" ++ need_version=no ++ need_lib_prefix=no ++ ++ case $GCC,$host_os in ++ yes,cygwin* | yes,mingw* | yes,pw32*) ++ library_names_spec='$libname.dll.a' ++ # DLL is installed to $(libdir)/../bin by postinstall_cmds ++ postinstall_cmds='base_file=`basename \${file}`~ ++ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ ++ dldir=$destdir/`dirname \$dlpath`~ ++ test -d \$dldir || mkdir -p \$dldir~ ++ $install_prog $dir/$dlname \$dldir/$dlname~ ++ chmod a+x \$dldir/$dlname' ++ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ ++ dlpath=$dir/\$dldll~ ++ $rm \$dlpath' ++ shlibpath_overrides_runpath=yes ++ ++ case $host_os in ++ cygwin*) ++ # Cygwin DLLs use 'cyg' prefix rather than 'lib' ++ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ++ sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" ++ ;; ++ mingw*) ++ # MinGW DLLs use traditional 'lib' prefix ++ soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ++ sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` ++ if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then ++ # It is most probably a Windows format PATH printed by ++ # mingw gcc, but we are running on Cygwin. Gcc prints its search ++ # path with ; separators, and with drive letters. We can handle the ++ # drive letters (cygwin fileutils understands them), so leave them, ++ # especially as we might pass files found there to a mingw objdump, ++ # which wouldn't understand a cygwinified path. Ahh. ++ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` ++ else ++ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ++ fi ++ ;; ++ pw32*) ++ # pw32 DLLs use 'pw' prefix rather than 'lib' ++ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ++ ;; ++ esac ++ ;; ++ ++ *) ++ library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' ++ ;; ++ esac ++ dynamic_linker='Win32 ld.exe' ++ # FIXME: first we should search . and the directory the executable is in ++ shlibpath_var=PATH ++ ;; ++ ++darwin* | rhapsody*) ++ dynamic_linker="$host_os dyld" ++ version_type=darwin ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' ++ soname_spec='${libname}${release}${major}$shared_ext' ++ shlibpath_overrides_runpath=yes ++ shlibpath_var=DYLD_LIBRARY_PATH ++ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' ++ # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. ++ if test "$GCC" = yes; then ++ sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` ++ else ++ sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' ++ fi ++ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ++ ;; ++ ++dgux*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ ;; ++ ++freebsd1*) ++ dynamic_linker=no ++ ;; ++ ++kfreebsd*-gnu) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ dynamic_linker='GNU ld.so' ++ ;; ++ ++freebsd* | dragonfly*) ++ # DragonFly does not have aout. When/if they implement a new ++ # versioning mechanism, adjust this. ++ if test -x /usr/bin/objformat; then ++ objformat=`/usr/bin/objformat` ++ else ++ case $host_os in ++ freebsd[123]*) objformat=aout ;; ++ *) objformat=elf ;; ++ esac ++ fi ++ version_type=freebsd-$objformat ++ case $version_type in ++ freebsd-elf*) ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' ++ need_version=no ++ need_lib_prefix=no ++ ;; ++ freebsd-*) ++ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' ++ need_version=yes ++ ;; ++ esac ++ shlibpath_var=LD_LIBRARY_PATH ++ case $host_os in ++ freebsd2*) ++ shlibpath_overrides_runpath=yes ++ ;; ++ freebsd3.[01]* | freebsdelf3.[01]*) ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ ++ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ ;; ++ freebsd*) # from 4.6 on ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ esac ++ ;; ++ ++gnu*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ hardcode_into_libs=yes ++ ;; ++ ++hpux9* | hpux10* | hpux11*) ++ # Give a soname corresponding to the major version so that dld.sl refuses to ++ # link against other versions. ++ version_type=sunos ++ need_lib_prefix=no ++ need_version=no ++ case $host_cpu in ++ ia64*) ++ shrext_cmds='.so' ++ hardcode_into_libs=yes ++ dynamic_linker="$host_os dld.so" ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ if test "X$HPUX_IA64_MODE" = X32; then ++ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" ++ else ++ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" ++ fi ++ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ++ ;; ++ hppa*64*) ++ shrext_cmds='.sl' ++ hardcode_into_libs=yes ++ dynamic_linker="$host_os dld.sl" ++ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH ++ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" ++ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ++ ;; ++ *) ++ shrext_cmds='.sl' ++ dynamic_linker="$host_os dld.sl" ++ shlibpath_var=SHLIB_PATH ++ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ ;; ++ esac ++ # HP-UX runs *really* slowly unless shared libraries are mode 555. ++ postinstall_cmds='chmod 555 $lib' ++ ;; ++ ++interix3*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ ;; ++ ++irix5* | irix6* | nonstopux*) ++ case $host_os in ++ nonstopux*) version_type=nonstopux ;; ++ *) ++ if test "$lt_cv_prog_gnu_ld" = yes; then ++ version_type=linux ++ else ++ version_type=irix ++ fi ;; ++ esac ++ need_lib_prefix=no ++ need_version=no ++ soname_spec='${libname}${release}${shared_ext}$major' ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' ++ case $host_os in ++ irix5* | nonstopux*) ++ libsuff= shlibsuff= ++ ;; ++ *) ++ case $LD in # libtool.m4 will add one of these switches to LD ++ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") ++ libsuff= shlibsuff= libmagic=32-bit;; ++ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") ++ libsuff=32 shlibsuff=N32 libmagic=N32;; ++ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") ++ libsuff=64 shlibsuff=64 libmagic=64-bit;; ++ *) libsuff= shlibsuff= libmagic=never-match;; ++ esac ++ ;; ++ esac ++ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH ++ shlibpath_overrides_runpath=no ++ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" ++ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" ++ hardcode_into_libs=yes ++ ;; ++ ++# No shared lib support for Linux oldld, aout, or coff. ++linux*oldld* | linux*aout* | linux*coff*) ++ dynamic_linker=no ++ ;; ++ ++# This must be Linux ELF. ++linux*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ # This implies no fast_install, which is unacceptable. ++ # Some rework will be needed to allow for fast_install ++ # before this can be enabled. ++ hardcode_into_libs=yes ++ ++ # find out which ABI we are using ++ libsuff= ++ case "$host_cpu" in ++ x86_64*|s390x*|powerpc64*) ++ echo '#line 14836 "configure"' > conftest.$ac_ext ++ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; then ++ case `/usr/bin/file conftest.$ac_objext` in ++ *64-bit*) ++ libsuff=64 ++ sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}" ++ ;; ++ esac ++ fi ++ rm -rf conftest* ++ ;; ++ esac ++ ++ # Append ld.so.conf contents to the search path ++ if test -f /etc/ld.so.conf; then ++ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` ++ sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff} $lt_ld_extra" ++ fi ++ ++ # We used to test for /lib/ld.so.1 and disable shared libraries on ++ # powerpc, because MkLinux only supported shared libraries with the ++ # GNU dynamic linker. Since this was broken with cross compilers, ++ # most powerpc-linux boxes support dynamic linking these days and ++ # people can always --disable-shared, the test was removed, and we ++ # assume the GNU/Linux dynamic linker is in use. ++ dynamic_linker='GNU/Linux ld.so' ++ ;; ++ ++knetbsd*-gnu) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ dynamic_linker='GNU ld.so' ++ ;; ++ ++netbsd*) ++ version_type=sunos ++ need_lib_prefix=no ++ need_version=no ++ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' ++ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' ++ dynamic_linker='NetBSD (a.out) ld.so' ++ else ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ dynamic_linker='NetBSD ld.elf_so' ++ fi ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ ++newsos6) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ ;; ++ ++nto-qnx*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ ;; ++ ++openbsd*) ++ version_type=sunos ++ sys_lib_dlsearch_path_spec="/usr/lib" ++ need_lib_prefix=no ++ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. ++ case $host_os in ++ openbsd3.3 | openbsd3.3.*) need_version=yes ;; ++ *) need_version=no ;; ++ esac ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' ++ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then ++ case $host_os in ++ openbsd2.[89] | openbsd2.[89].*) ++ shlibpath_overrides_runpath=no ++ ;; ++ *) ++ shlibpath_overrides_runpath=yes ++ ;; ++ esac ++ else ++ shlibpath_overrides_runpath=yes ++ fi ++ ;; ++ ++os2*) ++ libname_spec='$name' ++ shrext_cmds=".dll" ++ need_lib_prefix=no ++ library_names_spec='$libname${shared_ext} $libname.a' ++ dynamic_linker='OS/2 ld.exe' ++ shlibpath_var=LIBPATH ++ ;; ++ ++osf3* | osf4* | osf5*) ++ version_type=osf ++ need_lib_prefix=no ++ need_version=no ++ soname_spec='${libname}${release}${shared_ext}$major' ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ shlibpath_var=LD_LIBRARY_PATH ++ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" ++ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ++ ;; ++ ++solaris*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ # ldd complains unless libraries are executable ++ postinstall_cmds='chmod +x $lib' ++ ;; ++ ++sunos4*) ++ version_type=sunos ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' ++ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ if test "$with_gnu_ld" = yes; then ++ need_lib_prefix=no ++ fi ++ need_version=yes ++ ;; ++ ++sysv4 | sysv4.3*) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ case $host_vendor in ++ sni) ++ shlibpath_overrides_runpath=no ++ need_lib_prefix=no ++ export_dynamic_flag_spec='${wl}-Blargedynsym' ++ runpath_var=LD_RUN_PATH ++ ;; ++ siemens) ++ need_lib_prefix=no ++ ;; ++ motorola) ++ need_lib_prefix=no ++ need_version=no ++ shlibpath_overrides_runpath=no ++ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ++ ;; ++ esac ++ ;; ++ ++sysv4*MP*) ++ if test -d /usr/nec ;then ++ version_type=linux ++ library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' ++ soname_spec='$libname${shared_ext}.$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ fi ++ ;; ++ ++sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) ++ version_type=freebsd-elf ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ hardcode_into_libs=yes ++ if test "$with_gnu_ld" = yes; then ++ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' ++ shlibpath_overrides_runpath=no ++ else ++ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' ++ shlibpath_overrides_runpath=yes ++ case $host_os in ++ sco3.2v5*) ++ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ++ ;; ++ esac ++ fi ++ sys_lib_dlsearch_path_spec='/usr/lib' ++ ;; ++ ++uts4*) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ ;; ++ ++*) ++ dynamic_linker=no ++ ;; ++esac ++echo "$as_me:$LINENO: result: $dynamic_linker" >&5 ++echo "${ECHO_T}$dynamic_linker" >&6 ++test "$dynamic_linker" = no && can_build_shared=no ++ ++variables_saved_for_relink="PATH $shlibpath_var $runpath_var" ++if test "$GCC" = yes; then ++ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" ++fi ++ ++echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 ++echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6 ++hardcode_action_CXX= ++if test -n "$hardcode_libdir_flag_spec_CXX" || \ ++ test -n "$runpath_var_CXX" || \ ++ test "X$hardcode_automatic_CXX" = "Xyes" ; then ++ ++ # We can hardcode non-existant directories. ++ if test "$hardcode_direct_CXX" != no && ++ # If the only mechanism to avoid hardcoding is shlibpath_var, we ++ # have to relink, otherwise we might link with an installed library ++ # when we should be linking with a yet-to-be-installed one ++ ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, CXX)" != no && ++ test "$hardcode_minus_L_CXX" != no; then ++ # Linking always hardcodes the temporary library directory. ++ hardcode_action_CXX=relink ++ else ++ # We can link without hardcoding, and we can hardcode nonexisting dirs. ++ hardcode_action_CXX=immediate ++ fi ++else ++ # We cannot hardcode anything, or else we can only hardcode existing ++ # directories. ++ hardcode_action_CXX=unsupported ++fi ++echo "$as_me:$LINENO: result: $hardcode_action_CXX" >&5 ++echo "${ECHO_T}$hardcode_action_CXX" >&6 ++ ++if test "$hardcode_action_CXX" = relink; then ++ # Fast installation is not supported ++ enable_fast_install=no ++elif test "$shlibpath_overrides_runpath" = yes || ++ test "$enable_shared" = no; then ++ # Fast installation is not necessary ++ enable_fast_install=needless ++fi ++ ++ ++# The else clause should only fire when bootstrapping the ++# libtool distribution, otherwise you forgot to ship ltmain.sh ++# with your package, and you will get complaints that there are ++# no rules to generate ltmain.sh. ++if test -f "$ltmain"; then ++ # See if we are running on zsh, and set the options which allow our commands through ++ # without removal of \ escapes. ++ if test -n "${ZSH_VERSION+set}" ; then ++ setopt NO_GLOB_SUBST ++ fi ++ # Now quote all the things that may contain metacharacters while being ++ # careful not to overquote the AC_SUBSTed values. We take copies of the ++ # variables and quote the copies for generation of the libtool script. ++ for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ ++ SED SHELL STRIP \ ++ libname_spec library_names_spec soname_spec extract_expsyms_cmds \ ++ old_striplib striplib file_magic_cmd finish_cmds finish_eval \ ++ deplibs_check_method reload_flag reload_cmds need_locks \ ++ lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ ++ lt_cv_sys_global_symbol_to_c_name_address \ ++ sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ ++ old_postinstall_cmds old_postuninstall_cmds \ ++ compiler_CXX \ ++ CC_CXX \ ++ LD_CXX \ ++ lt_prog_compiler_wl_CXX \ ++ lt_prog_compiler_pic_CXX \ ++ lt_prog_compiler_static_CXX \ ++ lt_prog_compiler_no_builtin_flag_CXX \ ++ export_dynamic_flag_spec_CXX \ ++ thread_safe_flag_spec_CXX \ ++ whole_archive_flag_spec_CXX \ ++ enable_shared_with_static_runtimes_CXX \ ++ old_archive_cmds_CXX \ ++ old_archive_from_new_cmds_CXX \ ++ predep_objects_CXX \ ++ postdep_objects_CXX \ ++ predeps_CXX \ ++ postdeps_CXX \ ++ compiler_lib_search_path_CXX \ ++ archive_cmds_CXX \ ++ archive_expsym_cmds_CXX \ ++ postinstall_cmds_CXX \ ++ postuninstall_cmds_CXX \ ++ old_archive_from_expsyms_cmds_CXX \ ++ allow_undefined_flag_CXX \ ++ no_undefined_flag_CXX \ ++ export_symbols_cmds_CXX \ ++ hardcode_libdir_flag_spec_CXX \ ++ hardcode_libdir_flag_spec_ld_CXX \ ++ hardcode_libdir_separator_CXX \ ++ hardcode_automatic_CXX \ ++ module_cmds_CXX \ ++ module_expsym_cmds_CXX \ ++ lt_cv_prog_compiler_c_o_CXX \ ++ exclude_expsyms_CXX \ ++ include_expsyms_CXX; do ++ ++ case $var in ++ old_archive_cmds_CXX | \ ++ old_archive_from_new_cmds_CXX | \ ++ archive_cmds_CXX | \ ++ archive_expsym_cmds_CXX | \ ++ module_cmds_CXX | \ ++ module_expsym_cmds_CXX | \ ++ old_archive_from_expsyms_cmds_CXX | \ ++ export_symbols_cmds_CXX | \ ++ extract_expsyms_cmds | reload_cmds | finish_cmds | \ ++ postinstall_cmds | postuninstall_cmds | \ ++ old_postinstall_cmds | old_postuninstall_cmds | \ ++ sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) ++ # Double-quote double-evaled strings. ++ eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" ++ ;; ++ *) ++ eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" ++ ;; ++ esac ++ done ++ ++ case $lt_echo in ++ *'\$0 --fallback-echo"') ++ lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` ++ ;; ++ esac ++ ++cfgfile="$ofile" ++ ++ cat <<__EOF__ >> "$cfgfile" ++# ### BEGIN LIBTOOL TAG CONFIG: $tagname ++ ++# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: ++ ++# Shell to use when invoking shell scripts. ++SHELL=$lt_SHELL ++ ++# Whether or not to build shared libraries. ++build_libtool_libs=$enable_shared ++ ++# Whether or not to build static libraries. ++build_old_libs=$enable_static ++ ++# Whether or not to add -lc for building shared libraries. ++build_libtool_need_lc=$archive_cmds_need_lc_CXX ++ ++# Whether or not to disallow shared libs when runtime libs are static ++allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX ++ ++# Whether or not to optimize for fast installation. ++fast_install=$enable_fast_install ++ ++# The host system. ++host_alias=$host_alias ++host=$host ++host_os=$host_os ++ ++# The build system. ++build_alias=$build_alias ++build=$build ++build_os=$build_os ++ ++# An echo program that does not interpret backslashes. ++echo=$lt_echo ++ ++# The archiver. ++AR=$lt_AR ++AR_FLAGS=$lt_AR_FLAGS ++ ++# A C compiler. ++LTCC=$lt_LTCC ++ ++# LTCC compiler flags. ++LTCFLAGS=$lt_LTCFLAGS ++ ++# A language-specific compiler. ++CC=$lt_compiler_CXX ++ ++# Is the compiler the GNU C compiler? ++with_gcc=$GCC_CXX ++ ++gcc_dir=\`gcc -print-file-name=. | $SED 's,/\.$,,'\` ++gcc_ver=\`gcc -dumpversion\` ++ ++# An ERE matcher. ++EGREP=$lt_EGREP ++ ++# The linker used to build libraries. ++LD=$lt_LD_CXX ++ ++# Whether we need hard or soft links. ++LN_S=$lt_LN_S ++ ++# A BSD-compatible nm program. ++NM=$lt_NM ++ ++# A symbol stripping program ++STRIP=$lt_STRIP ++ ++# Used to examine libraries when file_magic_cmd begins "file" ++MAGIC_CMD=$MAGIC_CMD ++ ++# Used on cygwin: DLL creation program. ++DLLTOOL="$DLLTOOL" ++ ++# Used on cygwin: object dumper. ++OBJDUMP="$OBJDUMP" ++ ++# Used on cygwin: assembler. ++AS="$AS" ++ ++# The name of the directory that contains temporary libtool files. ++objdir=$objdir ++ ++# How to create reloadable object files. ++reload_flag=$lt_reload_flag ++reload_cmds=$lt_reload_cmds ++ ++# How to pass a linker flag through the compiler. ++wl=$lt_lt_prog_compiler_wl_CXX ++ ++# Object file suffix (normally "o"). ++objext="$ac_objext" ++ ++# Old archive suffix (normally "a"). ++libext="$libext" ++ ++# Shared library suffix (normally ".so"). ++shrext_cmds='$shrext_cmds' ++ ++# Executable file suffix (normally ""). ++exeext="$exeext" ++ ++# Additional compiler flags for building library objects. ++pic_flag=$lt_lt_prog_compiler_pic_CXX ++pic_mode=$pic_mode ++ ++# What is the maximum length of a command? ++max_cmd_len=$lt_cv_sys_max_cmd_len ++ ++# Does compiler simultaneously support -c and -o options? ++compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX ++ ++# Must we lock files when doing compilation? ++need_locks=$lt_need_locks ++ ++# Do we need the lib prefix for modules? ++need_lib_prefix=$need_lib_prefix ++ ++# Do we need a version for libraries? ++need_version=$need_version ++ ++# Whether dlopen is supported. ++dlopen_support=$enable_dlopen ++ ++# Whether dlopen of programs is supported. ++dlopen_self=$enable_dlopen_self ++ ++# Whether dlopen of statically linked programs is supported. ++dlopen_self_static=$enable_dlopen_self_static ++ ++# Compiler flag to prevent dynamic linking. ++link_static_flag=$lt_lt_prog_compiler_static_CXX ++ ++# Compiler flag to turn off builtin functions. ++no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX ++ ++# Compiler flag to allow reflexive dlopens. ++export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX ++ ++# Compiler flag to generate shared objects directly from archives. ++whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX ++ ++# Compiler flag to generate thread-safe objects. ++thread_safe_flag_spec=$lt_thread_safe_flag_spec_CXX ++ ++# Library versioning type. ++version_type=$version_type ++ ++# Format of library name prefix. ++libname_spec=$lt_libname_spec ++ ++# List of archive names. First name is the real one, the rest are links. ++# The last name is the one that the linker finds with -lNAME. ++library_names_spec=$lt_library_names_spec ++ ++# The coded name of the library, if different from the real name. ++soname_spec=$lt_soname_spec ++ ++# Commands used to build and install an old-style archive. ++RANLIB=$lt_RANLIB ++old_archive_cmds=$lt_old_archive_cmds_CXX ++old_postinstall_cmds=$lt_old_postinstall_cmds ++old_postuninstall_cmds=$lt_old_postuninstall_cmds ++ ++# Create an old-style archive from a shared archive. ++old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX ++ ++# Create a temporary old-style archive to link instead of a shared archive. ++old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX ++ ++# Commands used to build and install a shared archive. ++archive_cmds=$lt_archive_cmds_CXX ++archive_expsym_cmds=$lt_archive_expsym_cmds_CXX ++postinstall_cmds=$lt_postinstall_cmds ++postuninstall_cmds=$lt_postuninstall_cmds ++ ++# Commands used to build a loadable module (assumed same as above if empty) ++module_cmds=$lt_module_cmds_CXX ++module_expsym_cmds=$lt_module_expsym_cmds_CXX ++ ++# Commands to strip libraries. ++old_striplib=$lt_old_striplib ++striplib=$lt_striplib ++ ++# Dependencies to place before the objects being linked to create a ++# shared library. ++predep_objects=\`echo $lt_predep_objects_CXX | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` ++ ++# Dependencies to place after the objects being linked to create a ++# shared library. ++postdep_objects=\`echo $lt_postdep_objects_CXX | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` ++ ++# Dependencies to place before the objects being linked to create a ++# shared library. ++predeps=$lt_predeps_CXX ++ ++# Dependencies to place after the objects being linked to create a ++# shared library. ++postdeps=$lt_postdeps_CXX ++ ++# The library search path used internally by the compiler when linking ++# a shared library. ++compiler_lib_search_path=\`echo $lt_compiler_lib_search_path_CXX | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` ++ ++# Method to check whether dependent libraries are shared objects. ++deplibs_check_method=$lt_deplibs_check_method ++ ++# Command to use when deplibs_check_method == file_magic. ++file_magic_cmd=$lt_file_magic_cmd ++ ++# Flag that allows shared libraries with undefined symbols to be built. ++allow_undefined_flag=$lt_allow_undefined_flag_CXX ++ ++# Flag that forces no undefined symbols. ++no_undefined_flag=$lt_no_undefined_flag_CXX ++ ++# Commands used to finish a libtool library installation in a directory. ++finish_cmds=$lt_finish_cmds ++ ++# Same as above, but a single script fragment to be evaled but not shown. ++finish_eval=$lt_finish_eval ++ ++# Take the output of nm and produce a listing of raw symbols and C names. ++global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe ++ ++# Transform the output of nm in a proper C declaration ++global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl ++ ++# Transform the output of nm in a C name address pair ++global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address ++ ++# This is the shared library runtime path variable. ++runpath_var=$runpath_var ++ ++# This is the shared library path variable. ++shlibpath_var=$shlibpath_var ++ ++# Is shlibpath searched before the hard-coded library search path? ++shlibpath_overrides_runpath=$shlibpath_overrides_runpath ++ ++# How to hardcode a shared library path into an executable. ++hardcode_action=$hardcode_action_CXX ++ ++# Whether we should hardcode library paths into libraries. ++hardcode_into_libs=$hardcode_into_libs ++ ++# Flag to hardcode \$libdir into a binary during linking. ++# This must work even if \$libdir does not exist. ++hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX ++ ++# If ld is used when linking, flag to hardcode \$libdir into ++# a binary during linking. This must work even if \$libdir does ++# not exist. ++hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_CXX ++ ++# Whether we need a single -rpath flag with a separated argument. ++hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX ++ ++# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the ++# resulting binary. ++hardcode_direct=$hardcode_direct_CXX ++ ++# Set to yes if using the -LDIR flag during linking hardcodes DIR into the ++# resulting binary. ++hardcode_minus_L=$hardcode_minus_L_CXX ++ ++# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into ++# the resulting binary. ++hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX ++ ++# Set to yes if building a shared library automatically hardcodes DIR into the library ++# and all subsequent libraries and executables linked against it. ++hardcode_automatic=$hardcode_automatic_CXX ++ ++# Variables whose values should be saved in libtool wrapper scripts and ++# restored at relink time. ++variables_saved_for_relink="$variables_saved_for_relink" ++ ++# Whether libtool must link a program against all its dependency libraries. ++link_all_deplibs=$link_all_deplibs_CXX ++ ++# Compile-time system search path for libraries ++sys_lib_search_path_spec=\`echo $lt_sys_lib_search_path_spec | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` ++ ++# Run-time system search path for libraries ++sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec ++ ++# Fix the shell variable \$srcfile for the compiler. ++fix_srcfile_path="$fix_srcfile_path_CXX" ++ ++# Set to yes if exported symbols are required. ++always_export_symbols=$always_export_symbols_CXX ++ ++# The commands to list exported symbols. ++export_symbols_cmds=$lt_export_symbols_cmds_CXX ++ ++# The commands to extract the exported symbol list from a shared archive. ++extract_expsyms_cmds=$lt_extract_expsyms_cmds ++ ++# Symbols that should not be listed in the preloaded symbols. ++exclude_expsyms=$lt_exclude_expsyms_CXX ++ ++# Symbols that must always be exported. ++include_expsyms=$lt_include_expsyms_CXX ++ ++# ### END LIBTOOL TAG CONFIG: $tagname ++ ++__EOF__ ++ ++ ++else ++ # If there is no Makefile yet, we rely on a make rule to execute ++ # `config.status --recheck' to rerun these tests and create the ++ # libtool script then. ++ ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` ++ if test -f "$ltmain_in"; then ++ test -f Makefile && make "$ltmain" ++ fi ++fi ++ ++ ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++CC=$lt_save_CC ++LDCXX=$LD ++LD=$lt_save_LD ++GCC=$lt_save_GCC ++with_gnu_ldcxx=$with_gnu_ld ++with_gnu_ld=$lt_save_with_gnu_ld ++lt_cv_path_LDCXX=$lt_cv_path_LD ++lt_cv_path_LD=$lt_save_path_LD ++lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld ++lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld ++ ++ else ++ tagname="" ++ fi ++ ;; ++ ++ F77) ++ if test -n "$F77" && test "X$F77" != "Xno"; then ++ ++ac_ext=f ++ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5' ++ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_f77_compiler_gnu ++ ++ ++archive_cmds_need_lc_F77=no ++allow_undefined_flag_F77= ++always_export_symbols_F77=no ++archive_expsym_cmds_F77= ++export_dynamic_flag_spec_F77= ++hardcode_direct_F77=no ++hardcode_libdir_flag_spec_F77= ++hardcode_libdir_flag_spec_ld_F77= ++hardcode_libdir_separator_F77= ++hardcode_minus_L_F77=no ++hardcode_automatic_F77=no ++module_cmds_F77= ++module_expsym_cmds_F77= ++link_all_deplibs_F77=unknown ++old_archive_cmds_F77=$old_archive_cmds ++no_undefined_flag_F77= ++whole_archive_flag_spec_F77= ++enable_shared_with_static_runtimes_F77=no ++ ++# Source file extension for f77 test sources. ++ac_ext=f ++ ++# Object file extension for compiled f77 test sources. ++objext=o ++objext_F77=$objext ++ ++# Code to be used in simple compile tests ++lt_simple_compile_test_code=" subroutine t\n return\n end\n" ++ ++# Code to be used in simple link tests ++lt_simple_link_test_code=" program t\n end\n" ++ ++# ltmain only uses $CC for tagged configurations so make sure $CC is set. ++ ++# If no C compiler was specified, use CC. ++LTCC=${LTCC-"$CC"} ++ ++# If no C compiler flags were specified, use CFLAGS. ++LTCFLAGS=${LTCFLAGS-"$CFLAGS"} ++ ++# Allow CC to be a program name with arguments. ++compiler=$CC ++ ++ ++# save warnings/boilerplate of simple test code ++ac_outfile=conftest.$ac_objext ++printf "$lt_simple_compile_test_code" >conftest.$ac_ext ++eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err ++_lt_compiler_boilerplate=`cat conftest.err` ++$rm conftest* ++ ++ac_outfile=conftest.$ac_objext ++printf "$lt_simple_link_test_code" >conftest.$ac_ext ++eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err ++_lt_linker_boilerplate=`cat conftest.err` ++$rm conftest* ++ ++ ++# Allow CC to be a program name with arguments. ++lt_save_CC="$CC" ++CC=${F77-"f77"} ++compiler=$CC ++compiler_F77=$CC ++for cc_temp in $compiler""; do ++ case $cc_temp in ++ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; ++ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; ++ \-*) ;; ++ *) break;; ++ esac ++done ++cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` ++ ++ ++echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5 ++echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6 ++echo "$as_me:$LINENO: result: $can_build_shared" >&5 ++echo "${ECHO_T}$can_build_shared" >&6 ++ ++echo "$as_me:$LINENO: checking whether to build shared libraries" >&5 ++echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6 ++test "$can_build_shared" = "no" && enable_shared=no ++ ++# On AIX, shared libraries and static libraries use the same namespace, and ++# are all built from PIC. ++case $host_os in ++aix3*) ++ test "$enable_shared" = yes && enable_static=no ++ if test -n "$RANLIB"; then ++ archive_cmds="$archive_cmds~\$RANLIB \$lib" ++ postinstall_cmds='$RANLIB $lib' ++ fi ++ ;; ++aix4* | aix5*) ++ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then ++ test "$enable_shared" = yes && enable_static=no ++ fi ++ ;; ++esac ++echo "$as_me:$LINENO: result: $enable_shared" >&5 ++echo "${ECHO_T}$enable_shared" >&6 ++ ++echo "$as_me:$LINENO: checking whether to build static libraries" >&5 ++echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6 ++# Make sure either enable_shared or enable_static is yes. ++test "$enable_shared" = yes || enable_static=yes ++echo "$as_me:$LINENO: result: $enable_static" >&5 ++echo "${ECHO_T}$enable_static" >&6 ++ ++GCC_F77="$G77" ++LD_F77="$LD" ++ ++lt_prog_compiler_wl_F77= ++lt_prog_compiler_pic_F77= ++lt_prog_compiler_static_F77= ++ ++echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 ++echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 ++ ++ if test "$GCC" = yes; then ++ lt_prog_compiler_wl_F77='-Wl,' ++ lt_prog_compiler_static_F77='-static' ++ ++ case $host_os in ++ aix*) ++ # All AIX code is PIC. ++ if test "$host_cpu" = ia64; then ++ # AIX 5 now supports IA64 processor ++ lt_prog_compiler_static_F77='-Bstatic' ++ fi ++ ;; ++ ++ amigaos*) ++ # FIXME: we need at least 68020 code to build shared libraries, but ++ # adding the `-m68020' flag to GCC prevents building anything better, ++ # like `-m68040'. ++ lt_prog_compiler_pic_F77='-m68020 -resident32 -malways-restore-a4' ++ ;; ++ ++ beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) ++ # PIC is the default for these OSes. ++ ;; ++ ++ mingw* | pw32* | os2*) ++ # This hack is so that the source file can tell whether it is being ++ # built for inclusion in a dll (and should export symbols for example). ++ lt_prog_compiler_pic_F77='-DDLL_EXPORT' ++ ;; ++ ++ darwin* | rhapsody*) ++ # PIC is the default on this platform ++ # Common symbols not allowed in MH_DYLIB files ++ lt_prog_compiler_pic_F77='-fno-common' ++ ;; ++ ++ interix3*) ++ # Interix 3.x gcc -fpic/-fPIC options generate broken code. ++ # Instead, we relocate shared libraries at runtime. ++ ;; ++ ++ msdosdjgpp*) ++ # Just because we use GCC doesn't mean we suddenly get shared libraries ++ # on systems that don't support them. ++ lt_prog_compiler_can_build_shared_F77=no ++ enable_shared=no ++ ;; ++ ++ sysv4*MP*) ++ if test -d /usr/nec; then ++ lt_prog_compiler_pic_F77=-Kconform_pic ++ fi ++ ;; ++ ++ hpux*) ++ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but ++ # not for PA HP-UX. ++ case $host_cpu in ++ hppa*64*|ia64*) ++ # +Z the default ++ ;; ++ *) ++ lt_prog_compiler_pic_F77='-fPIC' ++ ;; ++ esac ++ ;; ++ ++ *) ++ lt_prog_compiler_pic_F77='-fPIC' ++ ;; ++ esac ++ else ++ # PORTME Check for flag to pass linker flags through the system compiler. ++ case $host_os in ++ aix*) ++ lt_prog_compiler_wl_F77='-Wl,' ++ if test "$host_cpu" = ia64; then ++ # AIX 5 now supports IA64 processor ++ lt_prog_compiler_static_F77='-Bstatic' ++ else ++ lt_prog_compiler_static_F77='-bnso -bI:/lib/syscalls.exp' ++ fi ++ ;; ++ darwin*) ++ # PIC is the default on this platform ++ # Common symbols not allowed in MH_DYLIB files ++ case $cc_basename in ++ xlc*) ++ lt_prog_compiler_pic_F77='-qnocommon' ++ lt_prog_compiler_wl_F77='-Wl,' ++ ;; ++ esac ++ ;; ++ ++ mingw* | pw32* | os2*) ++ # This hack is so that the source file can tell whether it is being ++ # built for inclusion in a dll (and should export symbols for example). ++ lt_prog_compiler_pic_F77='-DDLL_EXPORT' ++ ;; ++ ++ hpux9* | hpux10* | hpux11*) ++ lt_prog_compiler_wl_F77='-Wl,' ++ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but ++ # not for PA HP-UX. ++ case $host_cpu in ++ hppa*64*|ia64*) ++ # +Z the default ++ ;; ++ *) ++ lt_prog_compiler_pic_F77='+Z' ++ ;; ++ esac ++ # Is there a better lt_prog_compiler_static that works with the bundled CC? ++ lt_prog_compiler_static_F77='${wl}-a ${wl}archive' ++ ;; ++ ++ irix5* | irix6* | nonstopux*) ++ lt_prog_compiler_wl_F77='-Wl,' ++ # PIC (with -KPIC) is the default. ++ lt_prog_compiler_static_F77='-non_shared' ++ ;; ++ ++ newsos6) ++ lt_prog_compiler_pic_F77='-KPIC' ++ lt_prog_compiler_static_F77='-Bstatic' ++ ;; ++ ++ linux*) ++ case $cc_basename in ++ icc* | ecc*) ++ lt_prog_compiler_wl_F77='-Wl,' ++ lt_prog_compiler_pic_F77='-KPIC' ++ lt_prog_compiler_static_F77='-static' ++ ;; ++ pgcc* | pgf77* | pgf90* | pgf95*) ++ # Portland Group compilers (*not* the Pentium gcc compiler, ++ # which looks to be a dead project) ++ lt_prog_compiler_wl_F77='-Wl,' ++ lt_prog_compiler_pic_F77='-fpic' ++ lt_prog_compiler_static_F77='-Bstatic' ++ ;; ++ ccc*) ++ lt_prog_compiler_wl_F77='-Wl,' ++ # All Alpha code is PIC. ++ lt_prog_compiler_static_F77='-non_shared' ++ ;; ++ esac ++ ;; ++ ++ osf3* | osf4* | osf5*) ++ lt_prog_compiler_wl_F77='-Wl,' ++ # All OSF/1 code is PIC. ++ lt_prog_compiler_static_F77='-non_shared' ++ ;; ++ ++ solaris*) ++ lt_prog_compiler_pic_F77='-KPIC' ++ lt_prog_compiler_static_F77='-Bstatic' ++ case $cc_basename in ++ f77* | f90* | f95*) ++ lt_prog_compiler_wl_F77='-Qoption ld ';; ++ *) ++ lt_prog_compiler_wl_F77='-Wl,';; ++ esac ++ ;; ++ ++ sunos4*) ++ lt_prog_compiler_wl_F77='-Qoption ld ' ++ lt_prog_compiler_pic_F77='-PIC' ++ lt_prog_compiler_static_F77='-Bstatic' ++ ;; ++ ++ sysv4 | sysv4.2uw2* | sysv4.3*) ++ lt_prog_compiler_wl_F77='-Wl,' ++ lt_prog_compiler_pic_F77='-KPIC' ++ lt_prog_compiler_static_F77='-Bstatic' ++ ;; ++ ++ sysv4*MP*) ++ if test -d /usr/nec ;then ++ lt_prog_compiler_pic_F77='-Kconform_pic' ++ lt_prog_compiler_static_F77='-Bstatic' ++ fi ++ ;; ++ ++ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) ++ lt_prog_compiler_wl_F77='-Wl,' ++ lt_prog_compiler_pic_F77='-KPIC' ++ lt_prog_compiler_static_F77='-Bstatic' ++ ;; ++ ++ unicos*) ++ lt_prog_compiler_wl_F77='-Wl,' ++ lt_prog_compiler_can_build_shared_F77=no ++ ;; ++ ++ uts4*) ++ lt_prog_compiler_pic_F77='-pic' ++ lt_prog_compiler_static_F77='-Bstatic' ++ ;; ++ ++ *) ++ lt_prog_compiler_can_build_shared_F77=no ++ ;; ++ esac ++ fi ++ ++echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_F77" >&5 ++echo "${ECHO_T}$lt_prog_compiler_pic_F77" >&6 ++ ++# ++# Check to make sure the PIC flag actually works. ++# ++if test -n "$lt_prog_compiler_pic_F77"; then ++ ++echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works" >&5 ++echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works... $ECHO_C" >&6 ++if test "${lt_prog_compiler_pic_works_F77+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ lt_prog_compiler_pic_works_F77=no ++ ac_outfile=conftest.$ac_objext ++ printf "$lt_simple_compile_test_code" > conftest.$ac_ext ++ lt_compiler_flag="$lt_prog_compiler_pic_F77" ++ # Insert the option either (1) after the last *FLAGS variable, or ++ # (2) before a word containing "conftest.", or (3) at the end. ++ # Note that $ac_compile itself does not contain backslashes and begins ++ # with a dollar sign (not a hyphen), so the echo should work correctly. ++ # The option is referenced via a variable to avoid confusing sed. ++ lt_compile=`echo "$ac_compile" | $SED \ ++ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ ++ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ ++ -e 's:$: $lt_compiler_flag:'` ++ (eval echo "\"\$as_me:15894: $lt_compile\"" >&5) ++ (eval "$lt_compile" 2>conftest.err) ++ ac_status=$? ++ cat conftest.err >&5 ++ echo "$as_me:15898: \$? = $ac_status" >&5 ++ if (exit $ac_status) && test -s "$ac_outfile"; then ++ # The compiler can only warn and ignore the option if not recognized ++ # So say no if there are warnings other than the usual output. ++ $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp ++ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 ++ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then ++ lt_prog_compiler_pic_works_F77=yes ++ fi ++ fi ++ $rm conftest* ++ ++fi ++echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_F77" >&5 ++echo "${ECHO_T}$lt_prog_compiler_pic_works_F77" >&6 ++ ++if test x"$lt_prog_compiler_pic_works_F77" = xyes; then ++ case $lt_prog_compiler_pic_F77 in ++ "" | " "*) ;; ++ *) lt_prog_compiler_pic_F77=" $lt_prog_compiler_pic_F77" ;; ++ esac ++else ++ lt_prog_compiler_pic_F77= ++ lt_prog_compiler_can_build_shared_F77=no ++fi ++ ++fi ++case $host_os in ++ # For platforms which do not support PIC, -DPIC is meaningless: ++ *djgpp*) ++ lt_prog_compiler_pic_F77= ++ ;; ++ *) ++ lt_prog_compiler_pic_F77="$lt_prog_compiler_pic_F77" ++ ;; ++esac ++ ++# ++# Check to make sure the static flag actually works. ++# ++wl=$lt_prog_compiler_wl_F77 eval lt_tmp_static_flag=\"$lt_prog_compiler_static_F77\" ++echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 ++echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6 ++if test "${lt_prog_compiler_static_works_F77+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ lt_prog_compiler_static_works_F77=no ++ save_LDFLAGS="$LDFLAGS" ++ LDFLAGS="$LDFLAGS $lt_tmp_static_flag" ++ printf "$lt_simple_link_test_code" > conftest.$ac_ext ++ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then ++ # The linker can only warn and ignore the option if not recognized ++ # So say no if there are warnings ++ if test -s conftest.err; then ++ # Append any errors to the config.log. ++ cat conftest.err 1>&5 ++ $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp ++ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 ++ if diff conftest.exp conftest.er2 >/dev/null; then ++ lt_prog_compiler_static_works_F77=yes ++ fi ++ else ++ lt_prog_compiler_static_works_F77=yes ++ fi ++ fi ++ $rm conftest* ++ LDFLAGS="$save_LDFLAGS" ++ ++fi ++echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works_F77" >&5 ++echo "${ECHO_T}$lt_prog_compiler_static_works_F77" >&6 ++ ++if test x"$lt_prog_compiler_static_works_F77" = xyes; then ++ : ++else ++ lt_prog_compiler_static_F77= ++fi ++ ++ ++echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 ++echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6 ++if test "${lt_cv_prog_compiler_c_o_F77+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ lt_cv_prog_compiler_c_o_F77=no ++ $rm -r conftest 2>/dev/null ++ mkdir conftest ++ cd conftest ++ mkdir out ++ printf "$lt_simple_compile_test_code" > conftest.$ac_ext ++ ++ lt_compiler_flag="-o out/conftest2.$ac_objext" ++ # Insert the option either (1) after the last *FLAGS variable, or ++ # (2) before a word containing "conftest.", or (3) at the end. ++ # Note that $ac_compile itself does not contain backslashes and begins ++ # with a dollar sign (not a hyphen), so the echo should work correctly. ++ lt_compile=`echo "$ac_compile" | $SED \ ++ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ ++ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ ++ -e 's:$: $lt_compiler_flag:'` ++ (eval echo "\"\$as_me:15998: $lt_compile\"" >&5) ++ (eval "$lt_compile" 2>out/conftest.err) ++ ac_status=$? ++ cat out/conftest.err >&5 ++ echo "$as_me:16002: \$? = $ac_status" >&5 ++ if (exit $ac_status) && test -s out/conftest2.$ac_objext ++ then ++ # The compiler can only warn and ignore the option if not recognized ++ # So say no if there are warnings ++ $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp ++ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 ++ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then ++ lt_cv_prog_compiler_c_o_F77=yes ++ fi ++ fi ++ chmod u+w . 2>&5 ++ $rm conftest* ++ # SGI C++ compiler will create directory out/ii_files/ for ++ # template instantiation ++ test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files ++ $rm out/* && rmdir out ++ cd .. ++ rmdir conftest ++ $rm conftest* ++ ++fi ++echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_F77" >&5 ++echo "${ECHO_T}$lt_cv_prog_compiler_c_o_F77" >&6 ++ ++ ++hard_links="nottested" ++if test "$lt_cv_prog_compiler_c_o_F77" = no && test "$need_locks" != no; then ++ # do not overwrite the value of need_locks provided by the user ++ echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 ++echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6 ++ hard_links=yes ++ $rm conftest* ++ ln conftest.a conftest.b 2>/dev/null && hard_links=no ++ touch conftest.a ++ ln conftest.a conftest.b 2>&5 || hard_links=no ++ ln conftest.a conftest.b 2>/dev/null && hard_links=no ++ echo "$as_me:$LINENO: result: $hard_links" >&5 ++echo "${ECHO_T}$hard_links" >&6 ++ if test "$hard_links" = no; then ++ { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 ++echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} ++ need_locks=warn ++ fi ++else ++ need_locks=no ++fi ++ ++echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 ++echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6 ++ ++ runpath_var= ++ allow_undefined_flag_F77= ++ enable_shared_with_static_runtimes_F77=no ++ archive_cmds_F77= ++ archive_expsym_cmds_F77= ++ old_archive_From_new_cmds_F77= ++ old_archive_from_expsyms_cmds_F77= ++ export_dynamic_flag_spec_F77= ++ whole_archive_flag_spec_F77= ++ thread_safe_flag_spec_F77= ++ hardcode_libdir_flag_spec_F77= ++ hardcode_libdir_flag_spec_ld_F77= ++ hardcode_libdir_separator_F77= ++ hardcode_direct_F77=no ++ hardcode_minus_L_F77=no ++ hardcode_shlibpath_var_F77=unsupported ++ link_all_deplibs_F77=unknown ++ hardcode_automatic_F77=no ++ module_cmds_F77= ++ module_expsym_cmds_F77= ++ always_export_symbols_F77=no ++ export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ++ # include_expsyms should be a list of space-separated symbols to be *always* ++ # included in the symbol list ++ include_expsyms_F77= ++ # exclude_expsyms can be an extended regexp of symbols to exclude ++ # it will be wrapped by ` (' and `)$', so one must not match beginning or ++ # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', ++ # as well as any symbol that contains `d'. ++ exclude_expsyms_F77="_GLOBAL_OFFSET_TABLE_" ++ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out ++ # platforms (ab)use it in PIC code, but their linkers get confused if ++ # the symbol is explicitly referenced. Since portable code cannot ++ # rely on this symbol name, it's probably fine to never include it in ++ # preloaded symbol tables. ++ extract_expsyms_cmds= ++ # Just being paranoid about ensuring that cc_basename is set. ++ for cc_temp in $compiler""; do ++ case $cc_temp in ++ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; ++ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; ++ \-*) ;; ++ *) break;; ++ esac ++done ++cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` ++ ++ case $host_os in ++ cygwin* | mingw* | pw32*) ++ # FIXME: the MSVC++ port hasn't been tested in a loooong time ++ # When not using gcc, we currently assume that we are using ++ # Microsoft Visual C++. ++ if test "$GCC" != yes; then ++ with_gnu_ld=no ++ fi ++ ;; ++ interix*) ++ # we just hope/assume this is gcc and not c89 (= MSVC++) ++ with_gnu_ld=yes ++ ;; ++ openbsd*) ++ with_gnu_ld=no ++ ;; ++ esac ++ ++ ld_shlibs_F77=yes ++ if test "$with_gnu_ld" = yes; then ++ # If archive_cmds runs LD, not CC, wlarc should be empty ++ wlarc='${wl}' ++ ++ # Set some defaults for GNU ld with shared library support. These ++ # are reset later if shared libraries are not supported. Putting them ++ # here allows them to be overridden if necessary. ++ runpath_var=LD_RUN_PATH ++ hardcode_libdir_flag_spec_F77='${wl}--rpath ${wl}$libdir' ++ export_dynamic_flag_spec_F77='${wl}--export-dynamic' ++ # ancient GNU ld didn't support --whole-archive et. al. ++ if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then ++ whole_archive_flag_spec_F77="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' ++ else ++ whole_archive_flag_spec_F77= ++ fi ++ supports_anon_versioning=no ++ case `$LD -v 2>/dev/null` in ++ *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 ++ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... ++ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... ++ *\ 2.11.*) ;; # other 2.11 versions ++ *) supports_anon_versioning=yes ;; ++ esac ++ ++ # See if GNU ld supports shared libraries. ++ case $host_os in ++ aix3* | aix4* | aix5*) ++ # On AIX/PPC, the GNU linker is very broken ++ if test "$host_cpu" != ia64; then ++ ld_shlibs_F77=no ++ cat <&2 ++ ++*** Warning: the GNU linker, at least up to release 2.9.1, is reported ++*** to be unable to reliably create shared libraries on AIX. ++*** Therefore, libtool is disabling shared libraries support. If you ++*** really care for shared libraries, you may want to modify your PATH ++*** so that a non-GNU linker is found, and then restart. ++ ++EOF ++ fi ++ ;; ++ ++ amigaos*) ++ archive_cmds_F77='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' ++ hardcode_libdir_flag_spec_F77='-L$libdir' ++ hardcode_minus_L_F77=yes ++ ++ # Samuel A. Falvo II reports ++ # that the semantics of dynamic libraries on AmigaOS, at least up ++ # to version 4, is to share data among multiple programs linked ++ # with the same dynamic library. Since this doesn't match the ++ # behavior of shared libraries on other platforms, we can't use ++ # them. ++ ld_shlibs_F77=no ++ ;; ++ ++ beos*) ++ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then ++ allow_undefined_flag_F77=unsupported ++ # Joseph Beckenbach says some releases of gcc ++ # support --undefined. This deserves some investigation. FIXME ++ archive_cmds_F77='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ else ++ ld_shlibs_F77=no ++ fi ++ ;; ++ ++ cygwin* | mingw* | pw32*) ++ # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, F77) is actually meaningless, ++ # as there is no search path for DLLs. ++ hardcode_libdir_flag_spec_F77='-L$libdir' ++ allow_undefined_flag_F77=unsupported ++ always_export_symbols_F77=no ++ enable_shared_with_static_runtimes_F77=yes ++ export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' ++ ++ if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then ++ archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' ++ # If the export-symbols file already is a .def file (1st line ++ # is EXPORTS), use it as is; otherwise, prepend... ++ archive_expsym_cmds_F77='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then ++ cp $export_symbols $output_objdir/$soname.def; ++ else ++ echo EXPORTS > $output_objdir/$soname.def; ++ cat $export_symbols >> $output_objdir/$soname.def; ++ fi~ ++ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' ++ else ++ ld_shlibs_F77=no ++ fi ++ ;; ++ ++ interix3*) ++ hardcode_direct_F77=no ++ hardcode_shlibpath_var_F77=no ++ hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir' ++ export_dynamic_flag_spec_F77='${wl}-E' ++ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. ++ # Instead, shared libraries are loaded at an image base (0x10000000 by ++ # default) and relocated if they conflict, which is a slow very memory ++ # consuming and fragmenting process. To avoid this, we pick a random, ++ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link ++ # time. Moving up from 0x10000000 also allows more sbrk(2) space. ++ archive_cmds_F77='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ++ archive_expsym_cmds_F77='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ++ ;; ++ ++ linux*) ++ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then ++ tmp_addflag= ++ case $cc_basename,$host_cpu in ++ pgcc*) # Portland Group C compiler ++ whole_archive_flag_spec_F77='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' ++ tmp_addflag=' $pic_flag' ++ ;; ++ pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers ++ whole_archive_flag_spec_F77='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' ++ tmp_addflag=' $pic_flag -Mnomain' ;; ++ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 ++ tmp_addflag=' -i_dynamic' ;; ++ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 ++ tmp_addflag=' -i_dynamic -nofor_main' ;; ++ ifc* | ifort*) # Intel Fortran compiler ++ tmp_addflag=' -nofor_main' ;; ++ esac ++ archive_cmds_F77='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ ++ if test $supports_anon_versioning = yes; then ++ archive_expsym_cmds_F77='$echo "{ global:" > $output_objdir/$libname.ver~ ++ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ ++ $echo "local: *; };" >> $output_objdir/$libname.ver~ ++ $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' ++ fi ++ else ++ ld_shlibs_F77=no ++ fi ++ ;; ++ ++ netbsd*) ++ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then ++ archive_cmds_F77='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' ++ wlarc= ++ else ++ archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ fi ++ ;; ++ ++ solaris*) ++ if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then ++ ld_shlibs_F77=no ++ cat <&2 ++ ++*** Warning: The releases 2.8.* of the GNU linker cannot reliably ++*** create shared libraries on Solaris systems. Therefore, libtool ++*** is disabling shared libraries support. We urge you to upgrade GNU ++*** binutils to release 2.9.1 or newer. Another option is to modify ++*** your PATH or compiler configuration so that the native linker is ++*** used, and then restart. ++ ++EOF ++ elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then ++ archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ else ++ ld_shlibs_F77=no ++ fi ++ ;; ++ ++ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) ++ case `$LD -v 2>&1` in ++ *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ++ ld_shlibs_F77=no ++ cat <<_LT_EOF 1>&2 ++ ++*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not ++*** reliably create shared libraries on SCO systems. Therefore, libtool ++*** is disabling shared libraries support. We urge you to upgrade GNU ++*** binutils to release 2.16.91.0.3 or newer. Another option is to modify ++*** your PATH or compiler configuration so that the native linker is ++*** used, and then restart. ++ ++_LT_EOF ++ ;; ++ *) ++ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then ++ hardcode_libdir_flag_spec_F77='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' ++ archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib' ++ archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' ++ else ++ ld_shlibs_F77=no ++ fi ++ ;; ++ esac ++ ;; ++ ++ sunos4*) ++ archive_cmds_F77='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' ++ wlarc= ++ hardcode_direct_F77=yes ++ hardcode_shlibpath_var_F77=no ++ ;; ++ ++ *) ++ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then ++ archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ else ++ ld_shlibs_F77=no ++ fi ++ ;; ++ esac ++ ++ if test "$ld_shlibs_F77" = no; then ++ runpath_var= ++ hardcode_libdir_flag_spec_F77= ++ export_dynamic_flag_spec_F77= ++ whole_archive_flag_spec_F77= ++ fi ++ else ++ # PORTME fill in a description of your system's linker (not GNU ld) ++ case $host_os in ++ aix3*) ++ allow_undefined_flag_F77=unsupported ++ always_export_symbols_F77=yes ++ archive_expsym_cmds_F77='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' ++ # Note: this linker hardcodes the directories in LIBPATH if there ++ # are no directories specified by -L. ++ hardcode_minus_L_F77=yes ++ if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then ++ # Neither direct hardcoding nor static linking is supported with a ++ # broken collect2. ++ hardcode_direct_F77=unsupported ++ fi ++ ;; ++ ++ aix4* | aix5*) ++ if test "$host_cpu" = ia64; then ++ # On IA64, the linker does run time linking by default, so we don't ++ # have to do anything special. ++ aix_use_runtimelinking=no ++ exp_sym_flag='-Bexport' ++ no_entry_flag="" ++ else ++ # If we're using GNU nm, then we don't want the "-C" option. ++ # -C means demangle to AIX nm, but means don't demangle with GNU nm ++ if $NM -V 2>&1 | grep 'GNU' > /dev/null; then ++ export_symbols_cmds_F77='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' ++ else ++ export_symbols_cmds_F77='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' ++ fi ++ aix_use_runtimelinking=no ++ ++ # Test if we are trying to use run time linking or normal ++ # AIX style linking. If -brtl is somewhere in LDFLAGS, we ++ # need to do runtime linking. ++ case $host_os in aix4.[23]|aix4.[23].*|aix5*) ++ for ld_flag in $LDFLAGS; do ++ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then ++ aix_use_runtimelinking=yes ++ break ++ fi ++ done ++ ;; ++ esac ++ ++ exp_sym_flag='-bexport' ++ no_entry_flag='-bnoentry' ++ fi ++ ++ # When large executables or shared objects are built, AIX ld can ++ # have problems creating the table of contents. If linking a library ++ # or program results in "error TOC overflow" add -mminimal-toc to ++ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not ++ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. ++ ++ archive_cmds_F77='' ++ hardcode_direct_F77=yes ++ hardcode_libdir_separator_F77=':' ++ link_all_deplibs_F77=yes ++ ++ if test "$GCC" = yes; then ++ case $host_os in aix4.[012]|aix4.[012].*) ++ # We only want to do this on AIX 4.2 and lower, the check ++ # below for broken collect2 doesn't work under 4.3+ ++ collect2name=`${CC} -print-prog-name=collect2` ++ if test -f "$collect2name" && \ ++ strings "$collect2name" | grep resolve_lib_name >/dev/null ++ then ++ # We have reworked collect2 ++ hardcode_direct_F77=yes ++ else ++ # We have old collect2 ++ hardcode_direct_F77=unsupported ++ # It fails to find uninstalled libraries when the uninstalled ++ # path is not listed in the libpath. Setting hardcode_minus_L ++ # to unsupported forces relinking ++ hardcode_minus_L_F77=yes ++ hardcode_libdir_flag_spec_F77='-L$libdir' ++ hardcode_libdir_separator_F77= ++ fi ++ ;; ++ esac ++ shared_flag='-shared' ++ if test "$aix_use_runtimelinking" = yes; then ++ shared_flag="$shared_flag "'${wl}-G' ++ fi ++ else ++ # not using gcc ++ if test "$host_cpu" = ia64; then ++ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release ++ # chokes on -Wl,-G. The following line is correct: ++ shared_flag='-G' ++ else ++ if test "$aix_use_runtimelinking" = yes; then ++ shared_flag='${wl}-G' ++ else ++ shared_flag='${wl}-bM:SRE' ++ fi ++ fi ++ fi ++ ++ # It seems that -bexpall does not export symbols beginning with ++ # underscore (_), so it is better to generate a list of symbols to export. ++ always_export_symbols_F77=yes ++ if test "$aix_use_runtimelinking" = yes; then ++ # Warning - without using the other runtime loading flags (-brtl), ++ # -berok will link without error, but may produce a broken library. ++ allow_undefined_flag_F77='-berok' ++ # Determine the default libpath from the value encoded in an empty executable. ++ cat >conftest.$ac_ext <<_ACEOF ++ program main ++ ++ end ++_ACEOF ++rm -f conftest.$ac_objext conftest$ac_exeext ++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 ++ (eval $ac_link) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_f77_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest$ac_exeext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ++aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } ++}'` ++# Check for a 64-bit object if we didn't find anything. ++if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } ++}'`; fi ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++fi ++rm -f conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ++ ++ hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath" ++ archive_expsym_cmds_F77="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" ++ else ++ if test "$host_cpu" = ia64; then ++ hardcode_libdir_flag_spec_F77='${wl}-R $libdir:/usr/lib:/lib' ++ allow_undefined_flag_F77="-z nodefs" ++ archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" ++ else ++ # Determine the default libpath from the value encoded in an empty executable. ++ cat >conftest.$ac_ext <<_ACEOF ++ program main ++ ++ end ++_ACEOF ++rm -f conftest.$ac_objext conftest$ac_exeext ++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 ++ (eval $ac_link) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_f77_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest$ac_exeext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ++aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } ++}'` ++# Check for a 64-bit object if we didn't find anything. ++if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } ++}'`; fi ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++fi ++rm -f conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ++ ++ hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath" ++ # Warning - without using the other run time loading flags, ++ # -berok will link without error, but may produce a broken library. ++ no_undefined_flag_F77=' ${wl}-bernotok' ++ allow_undefined_flag_F77=' ${wl}-berok' ++ # Exported symbols can be pulled into shared objects from archives ++ whole_archive_flag_spec_F77='$convenience' ++ archive_cmds_need_lc_F77=yes ++ # This is similar to how AIX traditionally builds its shared libraries. ++ archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' ++ fi ++ fi ++ ;; ++ ++ amigaos*) ++ archive_cmds_F77='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' ++ hardcode_libdir_flag_spec_F77='-L$libdir' ++ hardcode_minus_L_F77=yes ++ # see comment about different semantics on the GNU ld section ++ ld_shlibs_F77=no ++ ;; ++ ++ bsdi[45]*) ++ export_dynamic_flag_spec_F77=-rdynamic ++ ;; ++ ++ cygwin* | mingw* | pw32*) ++ # When not using gcc, we currently assume that we are using ++ # Microsoft Visual C++. ++ # hardcode_libdir_flag_spec is actually meaningless, as there is ++ # no search path for DLLs. ++ hardcode_libdir_flag_spec_F77=' ' ++ allow_undefined_flag_F77=unsupported ++ # Tell ltmain to make .lib files, not .a files. ++ libext=lib ++ # Tell ltmain to make .dll files, not .so files. ++ shrext_cmds=".dll" ++ # FIXME: Setting linknames here is a bad hack. ++ archive_cmds_F77='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' ++ # The linker will automatically build a .lib file if we build a DLL. ++ old_archive_From_new_cmds_F77='true' ++ # FIXME: Should let the user specify the lib program. ++ old_archive_cmds_F77='lib /OUT:$oldlib$oldobjs$old_deplibs' ++ fix_srcfile_path_F77='`cygpath -w "$srcfile"`' ++ enable_shared_with_static_runtimes_F77=yes ++ ;; ++ ++ darwin* | rhapsody*) ++ case $host_os in ++ rhapsody* | darwin1.[012]) ++ allow_undefined_flag_F77='${wl}-undefined ${wl}suppress' ++ ;; ++ *) # Darwin 1.3 on ++ if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then ++ allow_undefined_flag_F77='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ++ else ++ case ${MACOSX_DEPLOYMENT_TARGET} in ++ 10.[012]) ++ allow_undefined_flag_F77='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ++ ;; ++ 10.*) ++ allow_undefined_flag_F77='${wl}-undefined ${wl}dynamic_lookup' ++ ;; ++ esac ++ fi ++ ;; ++ esac ++ archive_cmds_need_lc_F77=no ++ hardcode_direct_F77=no ++ hardcode_automatic_F77=yes ++ hardcode_shlibpath_var_F77=unsupported ++ whole_archive_flag_spec_F77='' ++ link_all_deplibs_F77=yes ++ if test "$GCC" = yes ; then ++ output_verbose_link_cmd='echo' ++ archive_cmds_F77='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' ++ module_cmds_F77='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' ++ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds ++ archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ module_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ else ++ case $cc_basename in ++ xlc*) ++ output_verbose_link_cmd='echo' ++ archive_cmds_F77='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' ++ module_cmds_F77='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' ++ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds ++ archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ module_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ ;; ++ *) ++ ld_shlibs_F77=no ++ ;; ++ esac ++ fi ++ ;; ++ ++ dgux*) ++ archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_libdir_flag_spec_F77='-L$libdir' ++ hardcode_shlibpath_var_F77=no ++ ;; ++ ++ freebsd1*) ++ ld_shlibs_F77=no ++ ;; ++ ++ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor ++ # support. Future versions do this automatically, but an explicit c++rt0.o ++ # does not break anything, and helps significantly (at the cost of a little ++ # extra space). ++ freebsd2.2*) ++ archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' ++ hardcode_libdir_flag_spec_F77='-R$libdir' ++ hardcode_direct_F77=yes ++ hardcode_shlibpath_var_F77=no ++ ;; ++ ++ # Unfortunately, older versions of FreeBSD 2 do not have this feature. ++ freebsd2*) ++ archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_direct_F77=yes ++ hardcode_minus_L_F77=yes ++ hardcode_shlibpath_var_F77=no ++ ;; ++ ++ # FreeBSD 3 and greater uses gcc -shared to do shared libraries. ++ freebsd* | kfreebsd*-gnu | dragonfly*) ++ archive_cmds_F77='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' ++ hardcode_libdir_flag_spec_F77='-R$libdir' ++ hardcode_direct_F77=yes ++ hardcode_shlibpath_var_F77=no ++ ;; ++ ++ hpux9*) ++ if test "$GCC" = yes; then ++ archive_cmds_F77='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ++ else ++ archive_cmds_F77='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ++ fi ++ hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' ++ hardcode_libdir_separator_F77=: ++ hardcode_direct_F77=yes ++ ++ # hardcode_minus_L: Not really in the search PATH, ++ # but as the default location of the library. ++ hardcode_minus_L_F77=yes ++ export_dynamic_flag_spec_F77='${wl}-E' ++ ;; ++ ++ hpux10*) ++ if test "$GCC" = yes -a "$with_gnu_ld" = no; then ++ archive_cmds_F77='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ archive_cmds_F77='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' ++ fi ++ if test "$with_gnu_ld" = no; then ++ hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' ++ hardcode_libdir_separator_F77=: ++ ++ hardcode_direct_F77=yes ++ export_dynamic_flag_spec_F77='${wl}-E' ++ ++ # hardcode_minus_L: Not really in the search PATH, ++ # but as the default location of the library. ++ hardcode_minus_L_F77=yes ++ fi ++ ;; ++ ++ hpux11*) ++ if test "$GCC" = yes -a "$with_gnu_ld" = no; then ++ case $host_cpu in ++ hppa*64*) ++ archive_cmds_F77='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ ia64*) ++ archive_cmds_F77='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ *) ++ archive_cmds_F77='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ esac ++ else ++ case $host_cpu in ++ hppa*64*) ++ archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ ia64*) ++ archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ *) ++ archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ esac ++ fi ++ if test "$with_gnu_ld" = no; then ++ hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' ++ hardcode_libdir_separator_F77=: ++ ++ case $host_cpu in ++ hppa*64*|ia64*) ++ hardcode_libdir_flag_spec_ld_F77='+b $libdir' ++ hardcode_direct_F77=no ++ hardcode_shlibpath_var_F77=no ++ ;; ++ *) ++ hardcode_direct_F77=yes ++ export_dynamic_flag_spec_F77='${wl}-E' ++ ++ # hardcode_minus_L: Not really in the search PATH, ++ # but as the default location of the library. ++ hardcode_minus_L_F77=yes ++ ;; ++ esac ++ fi ++ ;; ++ ++ irix5* | irix6* | nonstopux*) ++ if test "$GCC" = yes; then ++ archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ else ++ archive_cmds_F77='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' ++ hardcode_libdir_flag_spec_ld_F77='-rpath $libdir' ++ fi ++ hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' ++ hardcode_libdir_separator_F77=: ++ link_all_deplibs_F77=yes ++ ;; ++ ++ netbsd*) ++ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then ++ archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out ++ else ++ archive_cmds_F77='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF ++ fi ++ hardcode_libdir_flag_spec_F77='-R$libdir' ++ hardcode_direct_F77=yes ++ hardcode_shlibpath_var_F77=no ++ ;; ++ ++ newsos6) ++ archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_direct_F77=yes ++ hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' ++ hardcode_libdir_separator_F77=: ++ hardcode_shlibpath_var_F77=no ++ ;; ++ ++ openbsd*) ++ hardcode_direct_F77=yes ++ hardcode_shlibpath_var_F77=no ++ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then ++ archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' ++ hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir' ++ export_dynamic_flag_spec_F77='${wl}-E' ++ else ++ case $host_os in ++ openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) ++ archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_libdir_flag_spec_F77='-R$libdir' ++ ;; ++ *) ++ archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ++ hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir' ++ ;; ++ esac ++ fi ++ ;; ++ ++ os2*) ++ hardcode_libdir_flag_spec_F77='-L$libdir' ++ hardcode_minus_L_F77=yes ++ allow_undefined_flag_F77=unsupported ++ archive_cmds_F77='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' ++ old_archive_From_new_cmds_F77='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ++ ;; ++ ++ osf3*) ++ if test "$GCC" = yes; then ++ allow_undefined_flag_F77=' ${wl}-expect_unresolved ${wl}\*' ++ archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ else ++ allow_undefined_flag_F77=' -expect_unresolved \*' ++ archive_cmds_F77='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' ++ fi ++ hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' ++ hardcode_libdir_separator_F77=: ++ ;; ++ ++ osf4* | osf5*) # as osf3* with the addition of -msym flag ++ if test "$GCC" = yes; then ++ allow_undefined_flag_F77=' ${wl}-expect_unresolved ${wl}\*' ++ archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' ++ else ++ allow_undefined_flag_F77=' -expect_unresolved \*' ++ archive_cmds_F77='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' ++ archive_expsym_cmds_F77='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ ++ $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' ++ ++ # Both c and cxx compiler support -rpath directly ++ hardcode_libdir_flag_spec_F77='-rpath $libdir' ++ fi ++ hardcode_libdir_separator_F77=: ++ ;; ++ ++ solaris*) ++ no_undefined_flag_F77=' -z text' ++ if test "$GCC" = yes; then ++ wlarc='${wl}' ++ archive_cmds_F77='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ ++ $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' ++ else ++ wlarc='' ++ archive_cmds_F77='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ ++ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' ++ fi ++ hardcode_libdir_flag_spec_F77='-R$libdir' ++ hardcode_shlibpath_var_F77=no ++ case $host_os in ++ solaris2.[0-5] | solaris2.[0-5].*) ;; ++ *) ++ # The compiler driver will combine linker options so we ++ # cannot just pass the convience library names through ++ # without $wl, iff we do not link with $LD. ++ # Luckily, gcc supports the same syntax we need for Sun Studio. ++ # Supported since Solaris 2.6 (maybe 2.5.1?) ++ case $wlarc in ++ '') ++ whole_archive_flag_spec_F77='-z allextract$convenience -z defaultextract' ;; ++ *) ++ whole_archive_flag_spec_F77='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;; ++ esac ;; ++ esac ++ link_all_deplibs_F77=yes ++ ;; ++ ++ sunos4*) ++ if test "x$host_vendor" = xsequent; then ++ # Use $CC to link under sequent, because it throws in some extra .o ++ # files that make .init and .fini sections work. ++ archive_cmds_F77='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ archive_cmds_F77='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' ++ fi ++ hardcode_libdir_flag_spec_F77='-L$libdir' ++ hardcode_direct_F77=yes ++ hardcode_minus_L_F77=yes ++ hardcode_shlibpath_var_F77=no ++ ;; ++ ++ sysv4) ++ case $host_vendor in ++ sni) ++ archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_direct_F77=yes # is this really true??? ++ ;; ++ siemens) ++ ## LD is ld it makes a PLAMLIB ++ ## CC just makes a GrossModule. ++ archive_cmds_F77='$LD -G -o $lib $libobjs $deplibs $linker_flags' ++ reload_cmds_F77='$CC -r -o $output$reload_objs' ++ hardcode_direct_F77=no ++ ;; ++ motorola) ++ archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_direct_F77=no #Motorola manual says yes, but my tests say they lie ++ ;; ++ esac ++ runpath_var='LD_RUN_PATH' ++ hardcode_shlibpath_var_F77=no ++ ;; ++ ++ sysv4.3*) ++ archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_shlibpath_var_F77=no ++ export_dynamic_flag_spec_F77='-Bexport' ++ ;; ++ ++ sysv4*MP*) ++ if test -d /usr/nec; then ++ archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_shlibpath_var_F77=no ++ runpath_var=LD_RUN_PATH ++ hardcode_runpath_var=yes ++ ld_shlibs_F77=yes ++ fi ++ ;; ++ ++ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*) ++ no_undefined_flag_F77='${wl}-z,text' ++ archive_cmds_need_lc_F77=no ++ hardcode_shlibpath_var_F77=no ++ runpath_var='LD_RUN_PATH' ++ ++ if test "$GCC" = yes; then ++ archive_cmds_F77='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds_F77='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ archive_cmds_F77='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds_F77='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ fi ++ ;; ++ ++ sysv5* | sco3.2v5* | sco5v6*) ++ # Note: We can NOT use -z defs as we might desire, because we do not ++ # link with -lc, and that would cause any symbols used from libc to ++ # always be unresolved, which means just about no library would ++ # ever link correctly. If we're not using GNU ld we use -z text ++ # though, which does catch some bad symbols but isn't as heavy-handed ++ # as -z defs. ++ no_undefined_flag_F77='${wl}-z,text' ++ allow_undefined_flag_F77='${wl}-z,nodefs' ++ archive_cmds_need_lc_F77=no ++ hardcode_shlibpath_var_F77=no ++ hardcode_libdir_flag_spec_F77='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' ++ hardcode_libdir_separator_F77=':' ++ link_all_deplibs_F77=yes ++ export_dynamic_flag_spec_F77='${wl}-Bexport' ++ runpath_var='LD_RUN_PATH' ++ ++ if test "$GCC" = yes; then ++ archive_cmds_F77='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds_F77='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ archive_cmds_F77='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds_F77='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ fi ++ ;; ++ ++ uts4*) ++ archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_libdir_flag_spec_F77='-L$libdir' ++ hardcode_shlibpath_var_F77=no ++ ;; ++ ++ *) ++ ld_shlibs_F77=no ++ ;; ++ esac ++ fi ++ ++echo "$as_me:$LINENO: result: $ld_shlibs_F77" >&5 ++echo "${ECHO_T}$ld_shlibs_F77" >&6 ++test "$ld_shlibs_F77" = no && can_build_shared=no ++ ++# ++# Do we need to explicitly link libc? ++# ++case "x$archive_cmds_need_lc_F77" in ++x|xyes) ++ # Assume -lc should be added ++ archive_cmds_need_lc_F77=yes ++ ++ if test "$enable_shared" = yes && test "$GCC" = yes; then ++ case $archive_cmds_F77 in ++ *'~'*) ++ # FIXME: we may have to deal with multi-command sequences. ++ ;; ++ '$CC '*) ++ # Test whether the compiler implicitly links with -lc since on some ++ # systems, -lgcc has to come before -lc. If gcc already passes -lc ++ # to ld, don't add -lc before -lgcc. ++ echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 ++echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6 ++ $rm conftest* ++ printf "$lt_simple_compile_test_code" > conftest.$ac_ext ++ ++ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } 2>conftest.err; then ++ soname=conftest ++ lib=conftest ++ libobjs=conftest.$ac_objext ++ deplibs= ++ wl=$lt_prog_compiler_wl_F77 ++ pic_flag=$lt_prog_compiler_pic_F77 ++ compiler_flags=-v ++ linker_flags=-v ++ verstring= ++ output_objdir=. ++ libname=conftest ++ lt_save_allow_undefined_flag=$allow_undefined_flag_F77 ++ allow_undefined_flag_F77= ++ if { (eval echo "$as_me:$LINENO: \"$archive_cmds_F77 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 ++ (eval $archive_cmds_F77 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } ++ then ++ archive_cmds_need_lc_F77=no ++ else ++ archive_cmds_need_lc_F77=yes ++ fi ++ allow_undefined_flag_F77=$lt_save_allow_undefined_flag ++ else ++ cat conftest.err 1>&5 ++ fi ++ $rm conftest* ++ echo "$as_me:$LINENO: result: $archive_cmds_need_lc_F77" >&5 ++echo "${ECHO_T}$archive_cmds_need_lc_F77" >&6 ++ ;; ++ esac ++ fi ++ ;; ++esac ++ ++echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 ++echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6 ++library_names_spec= ++libname_spec='lib$name' ++soname_spec= ++shrext_cmds=".so" ++postinstall_cmds= ++postuninstall_cmds= ++finish_cmds= ++finish_eval= ++shlibpath_var= ++shlibpath_overrides_runpath=unknown ++version_type=none ++dynamic_linker="$host_os ld.so" ++sys_lib_dlsearch_path_spec="/lib /usr/lib" ++if test "$GCC" = yes; then ++ sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` ++ if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then ++ # if the path contains ";" then we assume it to be the separator ++ # otherwise default to the standard path separator (i.e. ":") - it is ++ # assumed that no part of a normal pathname contains ";" but that should ++ # okay in the real world where ";" in dirpaths is itself problematic. ++ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` ++ else ++ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ++ fi ++else ++ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" ++fi ++need_lib_prefix=unknown ++hardcode_into_libs=no ++ ++# when you set need_version to no, make sure it does not cause -set_version ++# flags to be left without arguments ++need_version=unknown ++ ++case $host_os in ++aix3*) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' ++ shlibpath_var=LIBPATH ++ ++ # AIX 3 has no versioning support, so we append a major version to the name. ++ soname_spec='${libname}${release}${shared_ext}$major' ++ ;; ++ ++aix4* | aix5*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ hardcode_into_libs=yes ++ if test "$host_cpu" = ia64; then ++ # AIX 5 supports IA64 ++ library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' ++ shlibpath_var=LD_LIBRARY_PATH ++ else ++ # With GCC up to 2.95.x, collect2 would create an import file ++ # for dependence libraries. The import file would start with ++ # the line `#! .'. This would cause the generated library to ++ # depend on `.', always an invalid library. This was fixed in ++ # development snapshots of GCC prior to 3.0. ++ case $host_os in ++ aix4 | aix4.[01] | aix4.[01].*) ++ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' ++ echo ' yes ' ++ echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then ++ : ++ else ++ can_build_shared=no ++ fi ++ ;; ++ esac ++ # AIX (on Power*) has no versioning support, so currently we can not hardcode correct ++ # soname into executable. Probably we can add versioning support to ++ # collect2, so additional links can be useful in future. ++ if test "$aix_use_runtimelinking" = yes; then ++ # If using run time linking (on AIX 4.2 or later) use lib.so ++ # instead of lib.a to let people know that these are not ++ # typical AIX shared libraries. ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ else ++ # We preserve .a as extension for shared libraries through AIX4.2 ++ # and later when we are not doing run time linking. ++ library_names_spec='${libname}${release}.a $libname.a' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ fi ++ shlibpath_var=LIBPATH ++ fi ++ ;; ++ ++amigaos*) ++ library_names_spec='$libname.ixlibrary $libname.a' ++ # Create ${libname}_ixlibrary.a entries in /sys/libs. ++ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ++ ;; ++ ++beos*) ++ library_names_spec='${libname}${shared_ext}' ++ dynamic_linker="$host_os ld.so" ++ shlibpath_var=LIBRARY_PATH ++ ;; ++ ++bsdi[45]*) ++ version_type=linux ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" ++ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" ++ # the default ld.so.conf also contains /usr/contrib/lib and ++ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow ++ # libtool to hard-code these into programs ++ ;; ++ ++cygwin* | mingw* | pw32*) ++ version_type=windows ++ shrext_cmds=".dll" ++ need_version=no ++ need_lib_prefix=no ++ ++ case $GCC,$host_os in ++ yes,cygwin* | yes,mingw* | yes,pw32*) ++ library_names_spec='$libname.dll.a' ++ # DLL is installed to $(libdir)/../bin by postinstall_cmds ++ postinstall_cmds='base_file=`basename \${file}`~ ++ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ ++ dldir=$destdir/`dirname \$dlpath`~ ++ test -d \$dldir || mkdir -p \$dldir~ ++ $install_prog $dir/$dlname \$dldir/$dlname~ ++ chmod a+x \$dldir/$dlname' ++ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ ++ dlpath=$dir/\$dldll~ ++ $rm \$dlpath' ++ shlibpath_overrides_runpath=yes ++ ++ case $host_os in ++ cygwin*) ++ # Cygwin DLLs use 'cyg' prefix rather than 'lib' ++ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ++ sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" ++ ;; ++ mingw*) ++ # MinGW DLLs use traditional 'lib' prefix ++ soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ++ sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` ++ if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then ++ # It is most probably a Windows format PATH printed by ++ # mingw gcc, but we are running on Cygwin. Gcc prints its search ++ # path with ; separators, and with drive letters. We can handle the ++ # drive letters (cygwin fileutils understands them), so leave them, ++ # especially as we might pass files found there to a mingw objdump, ++ # which wouldn't understand a cygwinified path. Ahh. ++ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` ++ else ++ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ++ fi ++ ;; ++ pw32*) ++ # pw32 DLLs use 'pw' prefix rather than 'lib' ++ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ++ ;; ++ esac ++ ;; ++ ++ *) ++ library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' ++ ;; ++ esac ++ dynamic_linker='Win32 ld.exe' ++ # FIXME: first we should search . and the directory the executable is in ++ shlibpath_var=PATH ++ ;; ++ ++darwin* | rhapsody*) ++ dynamic_linker="$host_os dyld" ++ version_type=darwin ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' ++ soname_spec='${libname}${release}${major}$shared_ext' ++ shlibpath_overrides_runpath=yes ++ shlibpath_var=DYLD_LIBRARY_PATH ++ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' ++ # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. ++ if test "$GCC" = yes; then ++ sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` ++ else ++ sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' ++ fi ++ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ++ ;; ++ ++dgux*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ ;; ++ ++freebsd1*) ++ dynamic_linker=no ++ ;; ++ ++kfreebsd*-gnu) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ dynamic_linker='GNU ld.so' ++ ;; ++ ++freebsd* | dragonfly*) ++ # DragonFly does not have aout. When/if they implement a new ++ # versioning mechanism, adjust this. ++ if test -x /usr/bin/objformat; then ++ objformat=`/usr/bin/objformat` ++ else ++ case $host_os in ++ freebsd[123]*) objformat=aout ;; ++ *) objformat=elf ;; ++ esac ++ fi ++ version_type=freebsd-$objformat ++ case $version_type in ++ freebsd-elf*) ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' ++ need_version=no ++ need_lib_prefix=no ++ ;; ++ freebsd-*) ++ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' ++ need_version=yes ++ ;; ++ esac ++ shlibpath_var=LD_LIBRARY_PATH ++ case $host_os in ++ freebsd2*) ++ shlibpath_overrides_runpath=yes ++ ;; ++ freebsd3.[01]* | freebsdelf3.[01]*) ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ ++ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ ;; ++ freebsd*) # from 4.6 on ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ esac ++ ;; ++ ++gnu*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ hardcode_into_libs=yes ++ ;; ++ ++hpux9* | hpux10* | hpux11*) ++ # Give a soname corresponding to the major version so that dld.sl refuses to ++ # link against other versions. ++ version_type=sunos ++ need_lib_prefix=no ++ need_version=no ++ case $host_cpu in ++ ia64*) ++ shrext_cmds='.so' ++ hardcode_into_libs=yes ++ dynamic_linker="$host_os dld.so" ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ if test "X$HPUX_IA64_MODE" = X32; then ++ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" ++ else ++ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" ++ fi ++ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ++ ;; ++ hppa*64*) ++ shrext_cmds='.sl' ++ hardcode_into_libs=yes ++ dynamic_linker="$host_os dld.sl" ++ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH ++ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" ++ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ++ ;; ++ *) ++ shrext_cmds='.sl' ++ dynamic_linker="$host_os dld.sl" ++ shlibpath_var=SHLIB_PATH ++ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ ;; ++ esac ++ # HP-UX runs *really* slowly unless shared libraries are mode 555. ++ postinstall_cmds='chmod 555 $lib' ++ ;; ++ ++interix3*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ ;; ++ ++irix5* | irix6* | nonstopux*) ++ case $host_os in ++ nonstopux*) version_type=nonstopux ;; ++ *) ++ if test "$lt_cv_prog_gnu_ld" = yes; then ++ version_type=linux ++ else ++ version_type=irix ++ fi ;; ++ esac ++ need_lib_prefix=no ++ need_version=no ++ soname_spec='${libname}${release}${shared_ext}$major' ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' ++ case $host_os in ++ irix5* | nonstopux*) ++ libsuff= shlibsuff= ++ ;; ++ *) ++ case $LD in # libtool.m4 will add one of these switches to LD ++ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") ++ libsuff= shlibsuff= libmagic=32-bit;; ++ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") ++ libsuff=32 shlibsuff=N32 libmagic=N32;; ++ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") ++ libsuff=64 shlibsuff=64 libmagic=64-bit;; ++ *) libsuff= shlibsuff= libmagic=never-match;; ++ esac ++ ;; ++ esac ++ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH ++ shlibpath_overrides_runpath=no ++ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" ++ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" ++ hardcode_into_libs=yes ++ ;; ++ ++# No shared lib support for Linux oldld, aout, or coff. ++linux*oldld* | linux*aout* | linux*coff*) ++ dynamic_linker=no ++ ;; ++ ++# This must be Linux ELF. ++linux*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ # This implies no fast_install, which is unacceptable. ++ # Some rework will be needed to allow for fast_install ++ # before this can be enabled. ++ hardcode_into_libs=yes ++ ++ # find out which ABI we are using ++ libsuff= ++ case "$host_cpu" in ++ x86_64*|s390x*|powerpc64*) ++ echo '#line 17447 "configure"' > conftest.$ac_ext ++ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; then ++ case `/usr/bin/file conftest.$ac_objext` in ++ *64-bit*) ++ libsuff=64 ++ sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}" ++ ;; ++ esac ++ fi ++ rm -rf conftest* ++ ;; ++ esac ++ ++ # Append ld.so.conf contents to the search path ++ if test -f /etc/ld.so.conf; then ++ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` ++ sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff} $lt_ld_extra" ++ fi ++ ++ # We used to test for /lib/ld.so.1 and disable shared libraries on ++ # powerpc, because MkLinux only supported shared libraries with the ++ # GNU dynamic linker. Since this was broken with cross compilers, ++ # most powerpc-linux boxes support dynamic linking these days and ++ # people can always --disable-shared, the test was removed, and we ++ # assume the GNU/Linux dynamic linker is in use. ++ dynamic_linker='GNU/Linux ld.so' ++ ;; ++ ++knetbsd*-gnu) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ dynamic_linker='GNU ld.so' ++ ;; ++ ++netbsd*) ++ version_type=sunos ++ need_lib_prefix=no ++ need_version=no ++ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' ++ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' ++ dynamic_linker='NetBSD (a.out) ld.so' ++ else ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ dynamic_linker='NetBSD ld.elf_so' ++ fi ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ ++newsos6) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ ;; ++ ++nto-qnx*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ ;; ++ ++openbsd*) ++ version_type=sunos ++ sys_lib_dlsearch_path_spec="/usr/lib" ++ need_lib_prefix=no ++ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. ++ case $host_os in ++ openbsd3.3 | openbsd3.3.*) need_version=yes ;; ++ *) need_version=no ;; ++ esac ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' ++ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then ++ case $host_os in ++ openbsd2.[89] | openbsd2.[89].*) ++ shlibpath_overrides_runpath=no ++ ;; ++ *) ++ shlibpath_overrides_runpath=yes ++ ;; ++ esac ++ else ++ shlibpath_overrides_runpath=yes ++ fi ++ ;; ++ ++os2*) ++ libname_spec='$name' ++ shrext_cmds=".dll" ++ need_lib_prefix=no ++ library_names_spec='$libname${shared_ext} $libname.a' ++ dynamic_linker='OS/2 ld.exe' ++ shlibpath_var=LIBPATH ++ ;; ++ ++osf3* | osf4* | osf5*) ++ version_type=osf ++ need_lib_prefix=no ++ need_version=no ++ soname_spec='${libname}${release}${shared_ext}$major' ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ shlibpath_var=LD_LIBRARY_PATH ++ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" ++ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ++ ;; ++ ++solaris*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ # ldd complains unless libraries are executable ++ postinstall_cmds='chmod +x $lib' ++ ;; ++ ++sunos4*) ++ version_type=sunos ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' ++ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ if test "$with_gnu_ld" = yes; then ++ need_lib_prefix=no ++ fi ++ need_version=yes ++ ;; ++ ++sysv4 | sysv4.3*) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ case $host_vendor in ++ sni) ++ shlibpath_overrides_runpath=no ++ need_lib_prefix=no ++ export_dynamic_flag_spec='${wl}-Blargedynsym' ++ runpath_var=LD_RUN_PATH ++ ;; ++ siemens) ++ need_lib_prefix=no ++ ;; ++ motorola) ++ need_lib_prefix=no ++ need_version=no ++ shlibpath_overrides_runpath=no ++ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ++ ;; ++ esac ++ ;; ++ ++sysv4*MP*) ++ if test -d /usr/nec ;then ++ version_type=linux ++ library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' ++ soname_spec='$libname${shared_ext}.$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ fi ++ ;; ++ ++sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) ++ version_type=freebsd-elf ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ hardcode_into_libs=yes ++ if test "$with_gnu_ld" = yes; then ++ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' ++ shlibpath_overrides_runpath=no ++ else ++ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' ++ shlibpath_overrides_runpath=yes ++ case $host_os in ++ sco3.2v5*) ++ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ++ ;; ++ esac ++ fi ++ sys_lib_dlsearch_path_spec='/usr/lib' ++ ;; ++ ++uts4*) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ ;; ++ ++*) ++ dynamic_linker=no ++ ;; ++esac ++echo "$as_me:$LINENO: result: $dynamic_linker" >&5 ++echo "${ECHO_T}$dynamic_linker" >&6 ++test "$dynamic_linker" = no && can_build_shared=no ++ ++variables_saved_for_relink="PATH $shlibpath_var $runpath_var" ++if test "$GCC" = yes; then ++ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" ++fi ++ ++echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 ++echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6 ++hardcode_action_F77= ++if test -n "$hardcode_libdir_flag_spec_F77" || \ ++ test -n "$runpath_var_F77" || \ ++ test "X$hardcode_automatic_F77" = "Xyes" ; then ++ ++ # We can hardcode non-existant directories. ++ if test "$hardcode_direct_F77" != no && ++ # If the only mechanism to avoid hardcoding is shlibpath_var, we ++ # have to relink, otherwise we might link with an installed library ++ # when we should be linking with a yet-to-be-installed one ++ ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, F77)" != no && ++ test "$hardcode_minus_L_F77" != no; then ++ # Linking always hardcodes the temporary library directory. ++ hardcode_action_F77=relink ++ else ++ # We can link without hardcoding, and we can hardcode nonexisting dirs. ++ hardcode_action_F77=immediate ++ fi ++else ++ # We cannot hardcode anything, or else we can only hardcode existing ++ # directories. ++ hardcode_action_F77=unsupported ++fi ++echo "$as_me:$LINENO: result: $hardcode_action_F77" >&5 ++echo "${ECHO_T}$hardcode_action_F77" >&6 ++ ++if test "$hardcode_action_F77" = relink; then ++ # Fast installation is not supported ++ enable_fast_install=no ++elif test "$shlibpath_overrides_runpath" = yes || ++ test "$enable_shared" = no; then ++ # Fast installation is not necessary ++ enable_fast_install=needless ++fi ++ ++ ++# The else clause should only fire when bootstrapping the ++# libtool distribution, otherwise you forgot to ship ltmain.sh ++# with your package, and you will get complaints that there are ++# no rules to generate ltmain.sh. ++if test -f "$ltmain"; then ++ # See if we are running on zsh, and set the options which allow our commands through ++ # without removal of \ escapes. ++ if test -n "${ZSH_VERSION+set}" ; then ++ setopt NO_GLOB_SUBST ++ fi ++ # Now quote all the things that may contain metacharacters while being ++ # careful not to overquote the AC_SUBSTed values. We take copies of the ++ # variables and quote the copies for generation of the libtool script. ++ for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ ++ SED SHELL STRIP \ ++ libname_spec library_names_spec soname_spec extract_expsyms_cmds \ ++ old_striplib striplib file_magic_cmd finish_cmds finish_eval \ ++ deplibs_check_method reload_flag reload_cmds need_locks \ ++ lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ ++ lt_cv_sys_global_symbol_to_c_name_address \ ++ sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ ++ old_postinstall_cmds old_postuninstall_cmds \ ++ compiler_F77 \ ++ CC_F77 \ ++ LD_F77 \ ++ lt_prog_compiler_wl_F77 \ ++ lt_prog_compiler_pic_F77 \ ++ lt_prog_compiler_static_F77 \ ++ lt_prog_compiler_no_builtin_flag_F77 \ ++ export_dynamic_flag_spec_F77 \ ++ thread_safe_flag_spec_F77 \ ++ whole_archive_flag_spec_F77 \ ++ enable_shared_with_static_runtimes_F77 \ ++ old_archive_cmds_F77 \ ++ old_archive_from_new_cmds_F77 \ ++ predep_objects_F77 \ ++ postdep_objects_F77 \ ++ predeps_F77 \ ++ postdeps_F77 \ ++ compiler_lib_search_path_F77 \ ++ archive_cmds_F77 \ ++ archive_expsym_cmds_F77 \ ++ postinstall_cmds_F77 \ ++ postuninstall_cmds_F77 \ ++ old_archive_from_expsyms_cmds_F77 \ ++ allow_undefined_flag_F77 \ ++ no_undefined_flag_F77 \ ++ export_symbols_cmds_F77 \ ++ hardcode_libdir_flag_spec_F77 \ ++ hardcode_libdir_flag_spec_ld_F77 \ ++ hardcode_libdir_separator_F77 \ ++ hardcode_automatic_F77 \ ++ module_cmds_F77 \ ++ module_expsym_cmds_F77 \ ++ lt_cv_prog_compiler_c_o_F77 \ ++ exclude_expsyms_F77 \ ++ include_expsyms_F77; do ++ ++ case $var in ++ old_archive_cmds_F77 | \ ++ old_archive_from_new_cmds_F77 | \ ++ archive_cmds_F77 | \ ++ archive_expsym_cmds_F77 | \ ++ module_cmds_F77 | \ ++ module_expsym_cmds_F77 | \ ++ old_archive_from_expsyms_cmds_F77 | \ ++ export_symbols_cmds_F77 | \ ++ extract_expsyms_cmds | reload_cmds | finish_cmds | \ ++ postinstall_cmds | postuninstall_cmds | \ ++ old_postinstall_cmds | old_postuninstall_cmds | \ ++ sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) ++ # Double-quote double-evaled strings. ++ eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" ++ ;; ++ *) ++ eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" ++ ;; ++ esac ++ done ++ ++ case $lt_echo in ++ *'\$0 --fallback-echo"') ++ lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` ++ ;; ++ esac ++ ++cfgfile="$ofile" ++ ++ cat <<__EOF__ >> "$cfgfile" ++# ### BEGIN LIBTOOL TAG CONFIG: $tagname ++ ++# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: ++ ++# Shell to use when invoking shell scripts. ++SHELL=$lt_SHELL ++ ++# Whether or not to build shared libraries. ++build_libtool_libs=$enable_shared ++ ++# Whether or not to build static libraries. ++build_old_libs=$enable_static ++ ++# Whether or not to add -lc for building shared libraries. ++build_libtool_need_lc=$archive_cmds_need_lc_F77 ++ ++# Whether or not to disallow shared libs when runtime libs are static ++allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_F77 ++ ++# Whether or not to optimize for fast installation. ++fast_install=$enable_fast_install ++ ++# The host system. ++host_alias=$host_alias ++host=$host ++host_os=$host_os ++ ++# The build system. ++build_alias=$build_alias ++build=$build ++build_os=$build_os ++ ++# An echo program that does not interpret backslashes. ++echo=$lt_echo ++ ++# The archiver. ++AR=$lt_AR ++AR_FLAGS=$lt_AR_FLAGS ++ ++# A C compiler. ++LTCC=$lt_LTCC ++ ++# LTCC compiler flags. ++LTCFLAGS=$lt_LTCFLAGS ++ ++# A language-specific compiler. ++CC=$lt_compiler_F77 ++ ++# Is the compiler the GNU C compiler? ++with_gcc=$GCC_F77 ++ ++gcc_dir=\`gcc -print-file-name=. | $SED 's,/\.$,,'\` ++gcc_ver=\`gcc -dumpversion\` ++ ++# An ERE matcher. ++EGREP=$lt_EGREP ++ ++# The linker used to build libraries. ++LD=$lt_LD_F77 ++ ++# Whether we need hard or soft links. ++LN_S=$lt_LN_S ++ ++# A BSD-compatible nm program. ++NM=$lt_NM ++ ++# A symbol stripping program ++STRIP=$lt_STRIP ++ ++# Used to examine libraries when file_magic_cmd begins "file" ++MAGIC_CMD=$MAGIC_CMD ++ ++# Used on cygwin: DLL creation program. ++DLLTOOL="$DLLTOOL" ++ ++# Used on cygwin: object dumper. ++OBJDUMP="$OBJDUMP" ++ ++# Used on cygwin: assembler. ++AS="$AS" ++ ++# The name of the directory that contains temporary libtool files. ++objdir=$objdir ++ ++# How to create reloadable object files. ++reload_flag=$lt_reload_flag ++reload_cmds=$lt_reload_cmds ++ ++# How to pass a linker flag through the compiler. ++wl=$lt_lt_prog_compiler_wl_F77 ++ ++# Object file suffix (normally "o"). ++objext="$ac_objext" ++ ++# Old archive suffix (normally "a"). ++libext="$libext" ++ ++# Shared library suffix (normally ".so"). ++shrext_cmds='$shrext_cmds' ++ ++# Executable file suffix (normally ""). ++exeext="$exeext" ++ ++# Additional compiler flags for building library objects. ++pic_flag=$lt_lt_prog_compiler_pic_F77 ++pic_mode=$pic_mode ++ ++# What is the maximum length of a command? ++max_cmd_len=$lt_cv_sys_max_cmd_len ++ ++# Does compiler simultaneously support -c and -o options? ++compiler_c_o=$lt_lt_cv_prog_compiler_c_o_F77 ++ ++# Must we lock files when doing compilation? ++need_locks=$lt_need_locks ++ ++# Do we need the lib prefix for modules? ++need_lib_prefix=$need_lib_prefix ++ ++# Do we need a version for libraries? ++need_version=$need_version ++ ++# Whether dlopen is supported. ++dlopen_support=$enable_dlopen ++ ++# Whether dlopen of programs is supported. ++dlopen_self=$enable_dlopen_self ++ ++# Whether dlopen of statically linked programs is supported. ++dlopen_self_static=$enable_dlopen_self_static ++ ++# Compiler flag to prevent dynamic linking. ++link_static_flag=$lt_lt_prog_compiler_static_F77 ++ ++# Compiler flag to turn off builtin functions. ++no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_F77 ++ ++# Compiler flag to allow reflexive dlopens. ++export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_F77 ++ ++# Compiler flag to generate shared objects directly from archives. ++whole_archive_flag_spec=$lt_whole_archive_flag_spec_F77 ++ ++# Compiler flag to generate thread-safe objects. ++thread_safe_flag_spec=$lt_thread_safe_flag_spec_F77 ++ ++# Library versioning type. ++version_type=$version_type ++ ++# Format of library name prefix. ++libname_spec=$lt_libname_spec ++ ++# List of archive names. First name is the real one, the rest are links. ++# The last name is the one that the linker finds with -lNAME. ++library_names_spec=$lt_library_names_spec ++ ++# The coded name of the library, if different from the real name. ++soname_spec=$lt_soname_spec ++ ++# Commands used to build and install an old-style archive. ++RANLIB=$lt_RANLIB ++old_archive_cmds=$lt_old_archive_cmds_F77 ++old_postinstall_cmds=$lt_old_postinstall_cmds ++old_postuninstall_cmds=$lt_old_postuninstall_cmds ++ ++# Create an old-style archive from a shared archive. ++old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_F77 ++ ++# Create a temporary old-style archive to link instead of a shared archive. ++old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_F77 ++ ++# Commands used to build and install a shared archive. ++archive_cmds=$lt_archive_cmds_F77 ++archive_expsym_cmds=$lt_archive_expsym_cmds_F77 ++postinstall_cmds=$lt_postinstall_cmds ++postuninstall_cmds=$lt_postuninstall_cmds ++ ++# Commands used to build a loadable module (assumed same as above if empty) ++module_cmds=$lt_module_cmds_F77 ++module_expsym_cmds=$lt_module_expsym_cmds_F77 ++ ++# Commands to strip libraries. ++old_striplib=$lt_old_striplib ++striplib=$lt_striplib ++ ++# Dependencies to place before the objects being linked to create a ++# shared library. ++predep_objects=\`echo $lt_predep_objects_F77 | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` ++ ++# Dependencies to place after the objects being linked to create a ++# shared library. ++postdep_objects=\`echo $lt_postdep_objects_F77 | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` ++ ++# Dependencies to place before the objects being linked to create a ++# shared library. ++predeps=$lt_predeps_F77 ++ ++# Dependencies to place after the objects being linked to create a ++# shared library. ++postdeps=$lt_postdeps_F77 ++ ++# The library search path used internally by the compiler when linking ++# a shared library. ++compiler_lib_search_path=\`echo $lt_compiler_lib_search_path_F77 | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` ++ ++# Method to check whether dependent libraries are shared objects. ++deplibs_check_method=$lt_deplibs_check_method ++ ++# Command to use when deplibs_check_method == file_magic. ++file_magic_cmd=$lt_file_magic_cmd ++ ++# Flag that allows shared libraries with undefined symbols to be built. ++allow_undefined_flag=$lt_allow_undefined_flag_F77 ++ ++# Flag that forces no undefined symbols. ++no_undefined_flag=$lt_no_undefined_flag_F77 ++ ++# Commands used to finish a libtool library installation in a directory. ++finish_cmds=$lt_finish_cmds ++ ++# Same as above, but a single script fragment to be evaled but not shown. ++finish_eval=$lt_finish_eval ++ ++# Take the output of nm and produce a listing of raw symbols and C names. ++global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe ++ ++# Transform the output of nm in a proper C declaration ++global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl ++ ++# Transform the output of nm in a C name address pair ++global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address ++ ++# This is the shared library runtime path variable. ++runpath_var=$runpath_var ++ ++# This is the shared library path variable. ++shlibpath_var=$shlibpath_var ++ ++# Is shlibpath searched before the hard-coded library search path? ++shlibpath_overrides_runpath=$shlibpath_overrides_runpath ++ ++# How to hardcode a shared library path into an executable. ++hardcode_action=$hardcode_action_F77 ++ ++# Whether we should hardcode library paths into libraries. ++hardcode_into_libs=$hardcode_into_libs ++ ++# Flag to hardcode \$libdir into a binary during linking. ++# This must work even if \$libdir does not exist. ++hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_F77 ++ ++# If ld is used when linking, flag to hardcode \$libdir into ++# a binary during linking. This must work even if \$libdir does ++# not exist. ++hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_F77 ++ ++# Whether we need a single -rpath flag with a separated argument. ++hardcode_libdir_separator=$lt_hardcode_libdir_separator_F77 ++ ++# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the ++# resulting binary. ++hardcode_direct=$hardcode_direct_F77 ++ ++# Set to yes if using the -LDIR flag during linking hardcodes DIR into the ++# resulting binary. ++hardcode_minus_L=$hardcode_minus_L_F77 ++ ++# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into ++# the resulting binary. ++hardcode_shlibpath_var=$hardcode_shlibpath_var_F77 ++ ++# Set to yes if building a shared library automatically hardcodes DIR into the library ++# and all subsequent libraries and executables linked against it. ++hardcode_automatic=$hardcode_automatic_F77 ++ ++# Variables whose values should be saved in libtool wrapper scripts and ++# restored at relink time. ++variables_saved_for_relink="$variables_saved_for_relink" ++ ++# Whether libtool must link a program against all its dependency libraries. ++link_all_deplibs=$link_all_deplibs_F77 ++ ++# Compile-time system search path for libraries ++sys_lib_search_path_spec=\`echo $lt_sys_lib_search_path_spec | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` ++ ++# Run-time system search path for libraries ++sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec ++ ++# Fix the shell variable \$srcfile for the compiler. ++fix_srcfile_path="$fix_srcfile_path_F77" ++ ++# Set to yes if exported symbols are required. ++always_export_symbols=$always_export_symbols_F77 ++ ++# The commands to list exported symbols. ++export_symbols_cmds=$lt_export_symbols_cmds_F77 ++ ++# The commands to extract the exported symbol list from a shared archive. ++extract_expsyms_cmds=$lt_extract_expsyms_cmds ++ ++# Symbols that should not be listed in the preloaded symbols. ++exclude_expsyms=$lt_exclude_expsyms_F77 ++ ++# Symbols that must always be exported. ++include_expsyms=$lt_include_expsyms_F77 ++ ++# ### END LIBTOOL TAG CONFIG: $tagname ++ ++__EOF__ ++ ++ ++else ++ # If there is no Makefile yet, we rely on a make rule to execute ++ # `config.status --recheck' to rerun these tests and create the ++ # libtool script then. ++ ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` ++ if test -f "$ltmain_in"; then ++ test -f Makefile && make "$ltmain" ++ fi ++fi ++ ++ ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++CC="$lt_save_CC" ++ ++ else ++ tagname="" ++ fi ++ ;; ++ ++ GCJ) ++ if test -n "$GCJ" && test "X$GCJ" != "Xno"; then ++ ++ ++ ++# Source file extension for Java test sources. ++ac_ext=java ++ ++# Object file extension for compiled Java test sources. ++objext=o ++objext_GCJ=$objext ++ ++# Code to be used in simple compile tests ++lt_simple_compile_test_code="class foo {}\n" ++ ++# Code to be used in simple link tests ++lt_simple_link_test_code='public class conftest { public static void main(String[] argv) {}; }\n' ++ ++# ltmain only uses $CC for tagged configurations so make sure $CC is set. ++ ++# If no C compiler was specified, use CC. ++LTCC=${LTCC-"$CC"} ++ ++# If no C compiler flags were specified, use CFLAGS. ++LTCFLAGS=${LTCFLAGS-"$CFLAGS"} ++ ++# Allow CC to be a program name with arguments. ++compiler=$CC ++ ++ ++# save warnings/boilerplate of simple test code ++ac_outfile=conftest.$ac_objext ++printf "$lt_simple_compile_test_code" >conftest.$ac_ext ++eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err ++_lt_compiler_boilerplate=`cat conftest.err` ++$rm conftest* ++ ++ac_outfile=conftest.$ac_objext ++printf "$lt_simple_link_test_code" >conftest.$ac_ext ++eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err ++_lt_linker_boilerplate=`cat conftest.err` ++$rm conftest* ++ ++ ++# Allow CC to be a program name with arguments. ++lt_save_CC="$CC" ++CC=${GCJ-"gcj"} ++compiler=$CC ++compiler_GCJ=$CC ++for cc_temp in $compiler""; do ++ case $cc_temp in ++ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; ++ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; ++ \-*) ;; ++ *) break;; ++ esac ++done ++cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` ++ ++ ++# GCJ did not exist at the time GCC didn't implicitly link libc in. ++archive_cmds_need_lc_GCJ=no ++ ++old_archive_cmds_GCJ=$old_archive_cmds ++ ++ ++lt_prog_compiler_no_builtin_flag_GCJ= ++ ++if test "$GCC" = yes; then ++ lt_prog_compiler_no_builtin_flag_GCJ=' -fno-builtin' ++ ++ ++echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 ++echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6 ++if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ lt_cv_prog_compiler_rtti_exceptions=no ++ ac_outfile=conftest.$ac_objext ++ printf "$lt_simple_compile_test_code" > conftest.$ac_ext ++ lt_compiler_flag="-fno-rtti -fno-exceptions" ++ # Insert the option either (1) after the last *FLAGS variable, or ++ # (2) before a word containing "conftest.", or (3) at the end. ++ # Note that $ac_compile itself does not contain backslashes and begins ++ # with a dollar sign (not a hyphen), so the echo should work correctly. ++ # The option is referenced via a variable to avoid confusing sed. ++ lt_compile=`echo "$ac_compile" | $SED \ ++ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ ++ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ ++ -e 's:$: $lt_compiler_flag:'` ++ (eval echo "\"\$as_me:18225: $lt_compile\"" >&5) ++ (eval "$lt_compile" 2>conftest.err) ++ ac_status=$? ++ cat conftest.err >&5 ++ echo "$as_me:18229: \$? = $ac_status" >&5 ++ if (exit $ac_status) && test -s "$ac_outfile"; then ++ # The compiler can only warn and ignore the option if not recognized ++ # So say no if there are warnings other than the usual output. ++ $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp ++ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 ++ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then ++ lt_cv_prog_compiler_rtti_exceptions=yes ++ fi ++ fi ++ $rm conftest* ++ ++fi ++echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 ++echo "${ECHO_T}$lt_cv_prog_compiler_rtti_exceptions" >&6 ++ ++if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then ++ lt_prog_compiler_no_builtin_flag_GCJ="$lt_prog_compiler_no_builtin_flag_GCJ -fno-rtti -fno-exceptions" ++else ++ : ++fi ++ ++fi ++ ++lt_prog_compiler_wl_GCJ= ++lt_prog_compiler_pic_GCJ= ++lt_prog_compiler_static_GCJ= ++ ++echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 ++echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 ++ ++ if test "$GCC" = yes; then ++ lt_prog_compiler_wl_GCJ='-Wl,' ++ lt_prog_compiler_static_GCJ='-static' ++ ++ case $host_os in ++ aix*) ++ # All AIX code is PIC. ++ if test "$host_cpu" = ia64; then ++ # AIX 5 now supports IA64 processor ++ lt_prog_compiler_static_GCJ='-Bstatic' ++ fi ++ ;; ++ ++ amigaos*) ++ # FIXME: we need at least 68020 code to build shared libraries, but ++ # adding the `-m68020' flag to GCC prevents building anything better, ++ # like `-m68040'. ++ lt_prog_compiler_pic_GCJ='-m68020 -resident32 -malways-restore-a4' ++ ;; ++ ++ beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) ++ # PIC is the default for these OSes. ++ ;; ++ ++ mingw* | pw32* | os2*) ++ # This hack is so that the source file can tell whether it is being ++ # built for inclusion in a dll (and should export symbols for example). ++ lt_prog_compiler_pic_GCJ='-DDLL_EXPORT' ++ ;; ++ ++ darwin* | rhapsody*) ++ # PIC is the default on this platform ++ # Common symbols not allowed in MH_DYLIB files ++ lt_prog_compiler_pic_GCJ='-fno-common' ++ ;; ++ ++ interix3*) ++ # Interix 3.x gcc -fpic/-fPIC options generate broken code. ++ # Instead, we relocate shared libraries at runtime. ++ ;; ++ ++ msdosdjgpp*) ++ # Just because we use GCC doesn't mean we suddenly get shared libraries ++ # on systems that don't support them. ++ lt_prog_compiler_can_build_shared_GCJ=no ++ enable_shared=no ++ ;; ++ ++ sysv4*MP*) ++ if test -d /usr/nec; then ++ lt_prog_compiler_pic_GCJ=-Kconform_pic ++ fi ++ ;; ++ ++ hpux*) ++ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but ++ # not for PA HP-UX. ++ case $host_cpu in ++ hppa*64*|ia64*) ++ # +Z the default ++ ;; ++ *) ++ lt_prog_compiler_pic_GCJ='-fPIC' ++ ;; ++ esac ++ ;; ++ ++ *) ++ lt_prog_compiler_pic_GCJ='-fPIC' ++ ;; ++ esac ++ else ++ # PORTME Check for flag to pass linker flags through the system compiler. ++ case $host_os in ++ aix*) ++ lt_prog_compiler_wl_GCJ='-Wl,' ++ if test "$host_cpu" = ia64; then ++ # AIX 5 now supports IA64 processor ++ lt_prog_compiler_static_GCJ='-Bstatic' ++ else ++ lt_prog_compiler_static_GCJ='-bnso -bI:/lib/syscalls.exp' ++ fi ++ ;; ++ darwin*) ++ # PIC is the default on this platform ++ # Common symbols not allowed in MH_DYLIB files ++ case $cc_basename in ++ xlc*) ++ lt_prog_compiler_pic_GCJ='-qnocommon' ++ lt_prog_compiler_wl_GCJ='-Wl,' ++ ;; ++ esac ++ ;; ++ ++ mingw* | pw32* | os2*) ++ # This hack is so that the source file can tell whether it is being ++ # built for inclusion in a dll (and should export symbols for example). ++ lt_prog_compiler_pic_GCJ='-DDLL_EXPORT' ++ ;; ++ ++ hpux9* | hpux10* | hpux11*) ++ lt_prog_compiler_wl_GCJ='-Wl,' ++ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but ++ # not for PA HP-UX. ++ case $host_cpu in ++ hppa*64*|ia64*) ++ # +Z the default ++ ;; ++ *) ++ lt_prog_compiler_pic_GCJ='+Z' ++ ;; ++ esac ++ # Is there a better lt_prog_compiler_static that works with the bundled CC? ++ lt_prog_compiler_static_GCJ='${wl}-a ${wl}archive' ++ ;; ++ ++ irix5* | irix6* | nonstopux*) ++ lt_prog_compiler_wl_GCJ='-Wl,' ++ # PIC (with -KPIC) is the default. ++ lt_prog_compiler_static_GCJ='-non_shared' ++ ;; ++ ++ newsos6) ++ lt_prog_compiler_pic_GCJ='-KPIC' ++ lt_prog_compiler_static_GCJ='-Bstatic' ++ ;; ++ ++ linux*) ++ case $cc_basename in ++ icc* | ecc*) ++ lt_prog_compiler_wl_GCJ='-Wl,' ++ lt_prog_compiler_pic_GCJ='-KPIC' ++ lt_prog_compiler_static_GCJ='-static' ++ ;; ++ pgcc* | pgf77* | pgf90* | pgf95*) ++ # Portland Group compilers (*not* the Pentium gcc compiler, ++ # which looks to be a dead project) ++ lt_prog_compiler_wl_GCJ='-Wl,' ++ lt_prog_compiler_pic_GCJ='-fpic' ++ lt_prog_compiler_static_GCJ='-Bstatic' ++ ;; ++ ccc*) ++ lt_prog_compiler_wl_GCJ='-Wl,' ++ # All Alpha code is PIC. ++ lt_prog_compiler_static_GCJ='-non_shared' ++ ;; ++ esac ++ ;; ++ ++ osf3* | osf4* | osf5*) ++ lt_prog_compiler_wl_GCJ='-Wl,' ++ # All OSF/1 code is PIC. ++ lt_prog_compiler_static_GCJ='-non_shared' ++ ;; ++ ++ solaris*) ++ lt_prog_compiler_pic_GCJ='-KPIC' ++ lt_prog_compiler_static_GCJ='-Bstatic' ++ case $cc_basename in ++ f77* | f90* | f95*) ++ lt_prog_compiler_wl_GCJ='-Qoption ld ';; ++ *) ++ lt_prog_compiler_wl_GCJ='-Wl,';; ++ esac ++ ;; ++ ++ sunos4*) ++ lt_prog_compiler_wl_GCJ='-Qoption ld ' ++ lt_prog_compiler_pic_GCJ='-PIC' ++ lt_prog_compiler_static_GCJ='-Bstatic' ++ ;; ++ ++ sysv4 | sysv4.2uw2* | sysv4.3*) ++ lt_prog_compiler_wl_GCJ='-Wl,' ++ lt_prog_compiler_pic_GCJ='-KPIC' ++ lt_prog_compiler_static_GCJ='-Bstatic' ++ ;; ++ ++ sysv4*MP*) ++ if test -d /usr/nec ;then ++ lt_prog_compiler_pic_GCJ='-Kconform_pic' ++ lt_prog_compiler_static_GCJ='-Bstatic' ++ fi ++ ;; ++ ++ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) ++ lt_prog_compiler_wl_GCJ='-Wl,' ++ lt_prog_compiler_pic_GCJ='-KPIC' ++ lt_prog_compiler_static_GCJ='-Bstatic' ++ ;; ++ ++ unicos*) ++ lt_prog_compiler_wl_GCJ='-Wl,' ++ lt_prog_compiler_can_build_shared_GCJ=no ++ ;; ++ ++ uts4*) ++ lt_prog_compiler_pic_GCJ='-pic' ++ lt_prog_compiler_static_GCJ='-Bstatic' ++ ;; ++ ++ *) ++ lt_prog_compiler_can_build_shared_GCJ=no ++ ;; ++ esac ++ fi ++ ++echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_GCJ" >&5 ++echo "${ECHO_T}$lt_prog_compiler_pic_GCJ" >&6 ++ ++# ++# Check to make sure the PIC flag actually works. ++# ++if test -n "$lt_prog_compiler_pic_GCJ"; then ++ ++echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works" >&5 ++echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works... $ECHO_C" >&6 ++if test "${lt_prog_compiler_pic_works_GCJ+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ lt_prog_compiler_pic_works_GCJ=no ++ ac_outfile=conftest.$ac_objext ++ printf "$lt_simple_compile_test_code" > conftest.$ac_ext ++ lt_compiler_flag="$lt_prog_compiler_pic_GCJ" ++ # Insert the option either (1) after the last *FLAGS variable, or ++ # (2) before a word containing "conftest.", or (3) at the end. ++ # Note that $ac_compile itself does not contain backslashes and begins ++ # with a dollar sign (not a hyphen), so the echo should work correctly. ++ # The option is referenced via a variable to avoid confusing sed. ++ lt_compile=`echo "$ac_compile" | $SED \ ++ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ ++ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ ++ -e 's:$: $lt_compiler_flag:'` ++ (eval echo "\"\$as_me:18493: $lt_compile\"" >&5) ++ (eval "$lt_compile" 2>conftest.err) ++ ac_status=$? ++ cat conftest.err >&5 ++ echo "$as_me:18497: \$? = $ac_status" >&5 ++ if (exit $ac_status) && test -s "$ac_outfile"; then ++ # The compiler can only warn and ignore the option if not recognized ++ # So say no if there are warnings other than the usual output. ++ $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp ++ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 ++ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then ++ lt_prog_compiler_pic_works_GCJ=yes ++ fi ++ fi ++ $rm conftest* ++ ++fi ++echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_GCJ" >&5 ++echo "${ECHO_T}$lt_prog_compiler_pic_works_GCJ" >&6 ++ ++if test x"$lt_prog_compiler_pic_works_GCJ" = xyes; then ++ case $lt_prog_compiler_pic_GCJ in ++ "" | " "*) ;; ++ *) lt_prog_compiler_pic_GCJ=" $lt_prog_compiler_pic_GCJ" ;; ++ esac ++else ++ lt_prog_compiler_pic_GCJ= ++ lt_prog_compiler_can_build_shared_GCJ=no ++fi ++ ++fi ++case $host_os in ++ # For platforms which do not support PIC, -DPIC is meaningless: ++ *djgpp*) ++ lt_prog_compiler_pic_GCJ= ++ ;; ++ *) ++ lt_prog_compiler_pic_GCJ="$lt_prog_compiler_pic_GCJ" ++ ;; ++esac ++ ++# ++# Check to make sure the static flag actually works. ++# ++wl=$lt_prog_compiler_wl_GCJ eval lt_tmp_static_flag=\"$lt_prog_compiler_static_GCJ\" ++echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 ++echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6 ++if test "${lt_prog_compiler_static_works_GCJ+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ lt_prog_compiler_static_works_GCJ=no ++ save_LDFLAGS="$LDFLAGS" ++ LDFLAGS="$LDFLAGS $lt_tmp_static_flag" ++ printf "$lt_simple_link_test_code" > conftest.$ac_ext ++ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then ++ # The linker can only warn and ignore the option if not recognized ++ # So say no if there are warnings ++ if test -s conftest.err; then ++ # Append any errors to the config.log. ++ cat conftest.err 1>&5 ++ $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp ++ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 ++ if diff conftest.exp conftest.er2 >/dev/null; then ++ lt_prog_compiler_static_works_GCJ=yes ++ fi ++ else ++ lt_prog_compiler_static_works_GCJ=yes ++ fi ++ fi ++ $rm conftest* ++ LDFLAGS="$save_LDFLAGS" ++ ++fi ++echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works_GCJ" >&5 ++echo "${ECHO_T}$lt_prog_compiler_static_works_GCJ" >&6 ++ ++if test x"$lt_prog_compiler_static_works_GCJ" = xyes; then ++ : ++else ++ lt_prog_compiler_static_GCJ= ++fi ++ ++ ++echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 ++echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6 ++if test "${lt_cv_prog_compiler_c_o_GCJ+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ lt_cv_prog_compiler_c_o_GCJ=no ++ $rm -r conftest 2>/dev/null ++ mkdir conftest ++ cd conftest ++ mkdir out ++ printf "$lt_simple_compile_test_code" > conftest.$ac_ext ++ ++ lt_compiler_flag="-o out/conftest2.$ac_objext" ++ # Insert the option either (1) after the last *FLAGS variable, or ++ # (2) before a word containing "conftest.", or (3) at the end. ++ # Note that $ac_compile itself does not contain backslashes and begins ++ # with a dollar sign (not a hyphen), so the echo should work correctly. ++ lt_compile=`echo "$ac_compile" | $SED \ ++ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ ++ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ ++ -e 's:$: $lt_compiler_flag:'` ++ (eval echo "\"\$as_me:18597: $lt_compile\"" >&5) ++ (eval "$lt_compile" 2>out/conftest.err) ++ ac_status=$? ++ cat out/conftest.err >&5 ++ echo "$as_me:18601: \$? = $ac_status" >&5 ++ if (exit $ac_status) && test -s out/conftest2.$ac_objext ++ then ++ # The compiler can only warn and ignore the option if not recognized ++ # So say no if there are warnings ++ $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp ++ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 ++ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then ++ lt_cv_prog_compiler_c_o_GCJ=yes ++ fi ++ fi ++ chmod u+w . 2>&5 ++ $rm conftest* ++ # SGI C++ compiler will create directory out/ii_files/ for ++ # template instantiation ++ test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files ++ $rm out/* && rmdir out ++ cd .. ++ rmdir conftest ++ $rm conftest* ++ ++fi ++echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_GCJ" >&5 ++echo "${ECHO_T}$lt_cv_prog_compiler_c_o_GCJ" >&6 ++ ++ ++hard_links="nottested" ++if test "$lt_cv_prog_compiler_c_o_GCJ" = no && test "$need_locks" != no; then ++ # do not overwrite the value of need_locks provided by the user ++ echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 ++echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6 ++ hard_links=yes ++ $rm conftest* ++ ln conftest.a conftest.b 2>/dev/null && hard_links=no ++ touch conftest.a ++ ln conftest.a conftest.b 2>&5 || hard_links=no ++ ln conftest.a conftest.b 2>/dev/null && hard_links=no ++ echo "$as_me:$LINENO: result: $hard_links" >&5 ++echo "${ECHO_T}$hard_links" >&6 ++ if test "$hard_links" = no; then ++ { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 ++echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} ++ need_locks=warn ++ fi ++else ++ need_locks=no ++fi ++ ++echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 ++echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6 ++ ++ runpath_var= ++ allow_undefined_flag_GCJ= ++ enable_shared_with_static_runtimes_GCJ=no ++ archive_cmds_GCJ= ++ archive_expsym_cmds_GCJ= ++ old_archive_From_new_cmds_GCJ= ++ old_archive_from_expsyms_cmds_GCJ= ++ export_dynamic_flag_spec_GCJ= ++ whole_archive_flag_spec_GCJ= ++ thread_safe_flag_spec_GCJ= ++ hardcode_libdir_flag_spec_GCJ= ++ hardcode_libdir_flag_spec_ld_GCJ= ++ hardcode_libdir_separator_GCJ= ++ hardcode_direct_GCJ=no ++ hardcode_minus_L_GCJ=no ++ hardcode_shlibpath_var_GCJ=unsupported ++ link_all_deplibs_GCJ=unknown ++ hardcode_automatic_GCJ=no ++ module_cmds_GCJ= ++ module_expsym_cmds_GCJ= ++ always_export_symbols_GCJ=no ++ export_symbols_cmds_GCJ='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ++ # include_expsyms should be a list of space-separated symbols to be *always* ++ # included in the symbol list ++ include_expsyms_GCJ= ++ # exclude_expsyms can be an extended regexp of symbols to exclude ++ # it will be wrapped by ` (' and `)$', so one must not match beginning or ++ # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', ++ # as well as any symbol that contains `d'. ++ exclude_expsyms_GCJ="_GLOBAL_OFFSET_TABLE_" ++ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out ++ # platforms (ab)use it in PIC code, but their linkers get confused if ++ # the symbol is explicitly referenced. Since portable code cannot ++ # rely on this symbol name, it's probably fine to never include it in ++ # preloaded symbol tables. ++ extract_expsyms_cmds= ++ # Just being paranoid about ensuring that cc_basename is set. ++ for cc_temp in $compiler""; do ++ case $cc_temp in ++ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; ++ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; ++ \-*) ;; ++ *) break;; ++ esac ++done ++cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` ++ ++ case $host_os in ++ cygwin* | mingw* | pw32*) ++ # FIXME: the MSVC++ port hasn't been tested in a loooong time ++ # When not using gcc, we currently assume that we are using ++ # Microsoft Visual C++. ++ if test "$GCC" != yes; then ++ with_gnu_ld=no ++ fi ++ ;; ++ interix*) ++ # we just hope/assume this is gcc and not c89 (= MSVC++) ++ with_gnu_ld=yes ++ ;; ++ openbsd*) ++ with_gnu_ld=no ++ ;; ++ esac ++ ++ ld_shlibs_GCJ=yes ++ if test "$with_gnu_ld" = yes; then ++ # If archive_cmds runs LD, not CC, wlarc should be empty ++ wlarc='${wl}' ++ ++ # Set some defaults for GNU ld with shared library support. These ++ # are reset later if shared libraries are not supported. Putting them ++ # here allows them to be overridden if necessary. ++ runpath_var=LD_RUN_PATH ++ hardcode_libdir_flag_spec_GCJ='${wl}--rpath ${wl}$libdir' ++ export_dynamic_flag_spec_GCJ='${wl}--export-dynamic' ++ # ancient GNU ld didn't support --whole-archive et. al. ++ if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then ++ whole_archive_flag_spec_GCJ="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' ++ else ++ whole_archive_flag_spec_GCJ= ++ fi ++ supports_anon_versioning=no ++ case `$LD -v 2>/dev/null` in ++ *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 ++ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... ++ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... ++ *\ 2.11.*) ;; # other 2.11 versions ++ *) supports_anon_versioning=yes ;; ++ esac ++ ++ # See if GNU ld supports shared libraries. ++ case $host_os in ++ aix3* | aix4* | aix5*) ++ # On AIX/PPC, the GNU linker is very broken ++ if test "$host_cpu" != ia64; then ++ ld_shlibs_GCJ=no ++ cat <&2 ++ ++*** Warning: the GNU linker, at least up to release 2.9.1, is reported ++*** to be unable to reliably create shared libraries on AIX. ++*** Therefore, libtool is disabling shared libraries support. If you ++*** really care for shared libraries, you may want to modify your PATH ++*** so that a non-GNU linker is found, and then restart. ++ ++EOF ++ fi ++ ;; ++ ++ amigaos*) ++ archive_cmds_GCJ='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' ++ hardcode_libdir_flag_spec_GCJ='-L$libdir' ++ hardcode_minus_L_GCJ=yes ++ ++ # Samuel A. Falvo II reports ++ # that the semantics of dynamic libraries on AmigaOS, at least up ++ # to version 4, is to share data among multiple programs linked ++ # with the same dynamic library. Since this doesn't match the ++ # behavior of shared libraries on other platforms, we can't use ++ # them. ++ ld_shlibs_GCJ=no ++ ;; ++ ++ beos*) ++ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then ++ allow_undefined_flag_GCJ=unsupported ++ # Joseph Beckenbach says some releases of gcc ++ # support --undefined. This deserves some investigation. FIXME ++ archive_cmds_GCJ='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ else ++ ld_shlibs_GCJ=no ++ fi ++ ;; ++ ++ cygwin* | mingw* | pw32*) ++ # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, GCJ) is actually meaningless, ++ # as there is no search path for DLLs. ++ hardcode_libdir_flag_spec_GCJ='-L$libdir' ++ allow_undefined_flag_GCJ=unsupported ++ always_export_symbols_GCJ=no ++ enable_shared_with_static_runtimes_GCJ=yes ++ export_symbols_cmds_GCJ='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' ++ ++ if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then ++ archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' ++ # If the export-symbols file already is a .def file (1st line ++ # is EXPORTS), use it as is; otherwise, prepend... ++ archive_expsym_cmds_GCJ='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then ++ cp $export_symbols $output_objdir/$soname.def; ++ else ++ echo EXPORTS > $output_objdir/$soname.def; ++ cat $export_symbols >> $output_objdir/$soname.def; ++ fi~ ++ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' ++ else ++ ld_shlibs_GCJ=no ++ fi ++ ;; ++ ++ interix3*) ++ hardcode_direct_GCJ=no ++ hardcode_shlibpath_var_GCJ=no ++ hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir' ++ export_dynamic_flag_spec_GCJ='${wl}-E' ++ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. ++ # Instead, shared libraries are loaded at an image base (0x10000000 by ++ # default) and relocated if they conflict, which is a slow very memory ++ # consuming and fragmenting process. To avoid this, we pick a random, ++ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link ++ # time. Moving up from 0x10000000 also allows more sbrk(2) space. ++ archive_cmds_GCJ='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ++ archive_expsym_cmds_GCJ='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ++ ;; ++ ++ linux*) ++ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then ++ tmp_addflag= ++ case $cc_basename,$host_cpu in ++ pgcc*) # Portland Group C compiler ++ whole_archive_flag_spec_GCJ='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' ++ tmp_addflag=' $pic_flag' ++ ;; ++ pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers ++ whole_archive_flag_spec_GCJ='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' ++ tmp_addflag=' $pic_flag -Mnomain' ;; ++ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 ++ tmp_addflag=' -i_dynamic' ;; ++ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 ++ tmp_addflag=' -i_dynamic -nofor_main' ;; ++ ifc* | ifort*) # Intel Fortran compiler ++ tmp_addflag=' -nofor_main' ;; ++ esac ++ archive_cmds_GCJ='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ ++ if test $supports_anon_versioning = yes; then ++ archive_expsym_cmds_GCJ='$echo "{ global:" > $output_objdir/$libname.ver~ ++ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ ++ $echo "local: *; };" >> $output_objdir/$libname.ver~ ++ $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' ++ fi ++ else ++ ld_shlibs_GCJ=no ++ fi ++ ;; ++ ++ netbsd*) ++ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then ++ archive_cmds_GCJ='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' ++ wlarc= ++ else ++ archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ fi ++ ;; ++ ++ solaris*) ++ if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then ++ ld_shlibs_GCJ=no ++ cat <&2 ++ ++*** Warning: The releases 2.8.* of the GNU linker cannot reliably ++*** create shared libraries on Solaris systems. Therefore, libtool ++*** is disabling shared libraries support. We urge you to upgrade GNU ++*** binutils to release 2.9.1 or newer. Another option is to modify ++*** your PATH or compiler configuration so that the native linker is ++*** used, and then restart. ++ ++EOF ++ elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then ++ archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ else ++ ld_shlibs_GCJ=no ++ fi ++ ;; ++ ++ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) ++ case `$LD -v 2>&1` in ++ *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ++ ld_shlibs_GCJ=no ++ cat <<_LT_EOF 1>&2 ++ ++*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not ++*** reliably create shared libraries on SCO systems. Therefore, libtool ++*** is disabling shared libraries support. We urge you to upgrade GNU ++*** binutils to release 2.16.91.0.3 or newer. Another option is to modify ++*** your PATH or compiler configuration so that the native linker is ++*** used, and then restart. ++ ++_LT_EOF ++ ;; ++ *) ++ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then ++ hardcode_libdir_flag_spec_GCJ='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' ++ archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib' ++ archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' ++ else ++ ld_shlibs_GCJ=no ++ fi ++ ;; ++ esac ++ ;; ++ ++ sunos4*) ++ archive_cmds_GCJ='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' ++ wlarc= ++ hardcode_direct_GCJ=yes ++ hardcode_shlibpath_var_GCJ=no ++ ;; ++ ++ *) ++ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then ++ archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ else ++ ld_shlibs_GCJ=no ++ fi ++ ;; ++ esac ++ ++ if test "$ld_shlibs_GCJ" = no; then ++ runpath_var= ++ hardcode_libdir_flag_spec_GCJ= ++ export_dynamic_flag_spec_GCJ= ++ whole_archive_flag_spec_GCJ= ++ fi ++ else ++ # PORTME fill in a description of your system's linker (not GNU ld) ++ case $host_os in ++ aix3*) ++ allow_undefined_flag_GCJ=unsupported ++ always_export_symbols_GCJ=yes ++ archive_expsym_cmds_GCJ='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' ++ # Note: this linker hardcodes the directories in LIBPATH if there ++ # are no directories specified by -L. ++ hardcode_minus_L_GCJ=yes ++ if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then ++ # Neither direct hardcoding nor static linking is supported with a ++ # broken collect2. ++ hardcode_direct_GCJ=unsupported ++ fi ++ ;; ++ ++ aix4* | aix5*) ++ if test "$host_cpu" = ia64; then ++ # On IA64, the linker does run time linking by default, so we don't ++ # have to do anything special. ++ aix_use_runtimelinking=no ++ exp_sym_flag='-Bexport' ++ no_entry_flag="" ++ else ++ # If we're using GNU nm, then we don't want the "-C" option. ++ # -C means demangle to AIX nm, but means don't demangle with GNU nm ++ if $NM -V 2>&1 | grep 'GNU' > /dev/null; then ++ export_symbols_cmds_GCJ='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' ++ else ++ export_symbols_cmds_GCJ='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' ++ fi ++ aix_use_runtimelinking=no ++ ++ # Test if we are trying to use run time linking or normal ++ # AIX style linking. If -brtl is somewhere in LDFLAGS, we ++ # need to do runtime linking. ++ case $host_os in aix4.[23]|aix4.[23].*|aix5*) ++ for ld_flag in $LDFLAGS; do ++ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then ++ aix_use_runtimelinking=yes ++ break ++ fi ++ done ++ ;; ++ esac ++ ++ exp_sym_flag='-bexport' ++ no_entry_flag='-bnoentry' ++ fi ++ ++ # When large executables or shared objects are built, AIX ld can ++ # have problems creating the table of contents. If linking a library ++ # or program results in "error TOC overflow" add -mminimal-toc to ++ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not ++ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. ++ ++ archive_cmds_GCJ='' ++ hardcode_direct_GCJ=yes ++ hardcode_libdir_separator_GCJ=':' ++ link_all_deplibs_GCJ=yes ++ ++ if test "$GCC" = yes; then ++ case $host_os in aix4.[012]|aix4.[012].*) ++ # We only want to do this on AIX 4.2 and lower, the check ++ # below for broken collect2 doesn't work under 4.3+ ++ collect2name=`${CC} -print-prog-name=collect2` ++ if test -f "$collect2name" && \ ++ strings "$collect2name" | grep resolve_lib_name >/dev/null ++ then ++ # We have reworked collect2 ++ hardcode_direct_GCJ=yes ++ else ++ # We have old collect2 ++ hardcode_direct_GCJ=unsupported ++ # It fails to find uninstalled libraries when the uninstalled ++ # path is not listed in the libpath. Setting hardcode_minus_L ++ # to unsupported forces relinking ++ hardcode_minus_L_GCJ=yes ++ hardcode_libdir_flag_spec_GCJ='-L$libdir' ++ hardcode_libdir_separator_GCJ= ++ fi ++ ;; ++ esac ++ shared_flag='-shared' ++ if test "$aix_use_runtimelinking" = yes; then ++ shared_flag="$shared_flag "'${wl}-G' ++ fi ++ else ++ # not using gcc ++ if test "$host_cpu" = ia64; then ++ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release ++ # chokes on -Wl,-G. The following line is correct: ++ shared_flag='-G' ++ else ++ if test "$aix_use_runtimelinking" = yes; then ++ shared_flag='${wl}-G' ++ else ++ shared_flag='${wl}-bM:SRE' ++ fi ++ fi ++ fi ++ ++ # It seems that -bexpall does not export symbols beginning with ++ # underscore (_), so it is better to generate a list of symbols to export. ++ always_export_symbols_GCJ=yes ++ if test "$aix_use_runtimelinking" = yes; then ++ # Warning - without using the other runtime loading flags (-brtl), ++ # -berok will link without error, but may produce a broken library. ++ allow_undefined_flag_GCJ='-berok' ++ # Determine the default libpath from the value encoded in an empty executable. ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext conftest$ac_exeext ++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 ++ (eval $ac_link) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest$ac_exeext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ++aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } ++}'` ++# Check for a 64-bit object if we didn't find anything. ++if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } ++}'`; fi ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++fi ++rm -f conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ++ ++ hardcode_libdir_flag_spec_GCJ='${wl}-blibpath:$libdir:'"$aix_libpath" ++ archive_expsym_cmds_GCJ="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" ++ else ++ if test "$host_cpu" = ia64; then ++ hardcode_libdir_flag_spec_GCJ='${wl}-R $libdir:/usr/lib:/lib' ++ allow_undefined_flag_GCJ="-z nodefs" ++ archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" ++ else ++ # Determine the default libpath from the value encoded in an empty executable. ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext conftest$ac_exeext ++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 ++ (eval $ac_link) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest$ac_exeext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ++aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } ++}'` ++# Check for a 64-bit object if we didn't find anything. ++if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } ++}'`; fi ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++fi ++rm -f conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ++ ++ hardcode_libdir_flag_spec_GCJ='${wl}-blibpath:$libdir:'"$aix_libpath" ++ # Warning - without using the other run time loading flags, ++ # -berok will link without error, but may produce a broken library. ++ no_undefined_flag_GCJ=' ${wl}-bernotok' ++ allow_undefined_flag_GCJ=' ${wl}-berok' ++ # Exported symbols can be pulled into shared objects from archives ++ whole_archive_flag_spec_GCJ='$convenience' ++ archive_cmds_need_lc_GCJ=yes ++ # This is similar to how AIX traditionally builds its shared libraries. ++ archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' ++ fi ++ fi ++ ;; ++ ++ amigaos*) ++ archive_cmds_GCJ='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' ++ hardcode_libdir_flag_spec_GCJ='-L$libdir' ++ hardcode_minus_L_GCJ=yes ++ # see comment about different semantics on the GNU ld section ++ ld_shlibs_GCJ=no ++ ;; ++ ++ bsdi[45]*) ++ export_dynamic_flag_spec_GCJ=-rdynamic ++ ;; ++ ++ cygwin* | mingw* | pw32*) ++ # When not using gcc, we currently assume that we are using ++ # Microsoft Visual C++. ++ # hardcode_libdir_flag_spec is actually meaningless, as there is ++ # no search path for DLLs. ++ hardcode_libdir_flag_spec_GCJ=' ' ++ allow_undefined_flag_GCJ=unsupported ++ # Tell ltmain to make .lib files, not .a files. ++ libext=lib ++ # Tell ltmain to make .dll files, not .so files. ++ shrext_cmds=".dll" ++ # FIXME: Setting linknames here is a bad hack. ++ archive_cmds_GCJ='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' ++ # The linker will automatically build a .lib file if we build a DLL. ++ old_archive_From_new_cmds_GCJ='true' ++ # FIXME: Should let the user specify the lib program. ++ old_archive_cmds_GCJ='lib /OUT:$oldlib$oldobjs$old_deplibs' ++ fix_srcfile_path_GCJ='`cygpath -w "$srcfile"`' ++ enable_shared_with_static_runtimes_GCJ=yes ++ ;; ++ ++ darwin* | rhapsody*) ++ case $host_os in ++ rhapsody* | darwin1.[012]) ++ allow_undefined_flag_GCJ='${wl}-undefined ${wl}suppress' ++ ;; ++ *) # Darwin 1.3 on ++ if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then ++ allow_undefined_flag_GCJ='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ++ else ++ case ${MACOSX_DEPLOYMENT_TARGET} in ++ 10.[012]) ++ allow_undefined_flag_GCJ='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ++ ;; ++ 10.*) ++ allow_undefined_flag_GCJ='${wl}-undefined ${wl}dynamic_lookup' ++ ;; ++ esac ++ fi ++ ;; ++ esac ++ archive_cmds_need_lc_GCJ=no ++ hardcode_direct_GCJ=no ++ hardcode_automatic_GCJ=yes ++ hardcode_shlibpath_var_GCJ=unsupported ++ whole_archive_flag_spec_GCJ='' ++ link_all_deplibs_GCJ=yes ++ if test "$GCC" = yes ; then ++ output_verbose_link_cmd='echo' ++ archive_cmds_GCJ='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' ++ module_cmds_GCJ='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' ++ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds ++ archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ module_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ else ++ case $cc_basename in ++ xlc*) ++ output_verbose_link_cmd='echo' ++ archive_cmds_GCJ='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' ++ module_cmds_GCJ='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' ++ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds ++ archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ module_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ ;; ++ *) ++ ld_shlibs_GCJ=no ++ ;; ++ esac ++ fi ++ ;; ++ ++ dgux*) ++ archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_libdir_flag_spec_GCJ='-L$libdir' ++ hardcode_shlibpath_var_GCJ=no ++ ;; ++ ++ freebsd1*) ++ ld_shlibs_GCJ=no ++ ;; ++ ++ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor ++ # support. Future versions do this automatically, but an explicit c++rt0.o ++ # does not break anything, and helps significantly (at the cost of a little ++ # extra space). ++ freebsd2.2*) ++ archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' ++ hardcode_libdir_flag_spec_GCJ='-R$libdir' ++ hardcode_direct_GCJ=yes ++ hardcode_shlibpath_var_GCJ=no ++ ;; ++ ++ # Unfortunately, older versions of FreeBSD 2 do not have this feature. ++ freebsd2*) ++ archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_direct_GCJ=yes ++ hardcode_minus_L_GCJ=yes ++ hardcode_shlibpath_var_GCJ=no ++ ;; ++ ++ # FreeBSD 3 and greater uses gcc -shared to do shared libraries. ++ freebsd* | kfreebsd*-gnu | dragonfly*) ++ archive_cmds_GCJ='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' ++ hardcode_libdir_flag_spec_GCJ='-R$libdir' ++ hardcode_direct_GCJ=yes ++ hardcode_shlibpath_var_GCJ=no ++ ;; ++ ++ hpux9*) ++ if test "$GCC" = yes; then ++ archive_cmds_GCJ='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ++ else ++ archive_cmds_GCJ='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ++ fi ++ hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir' ++ hardcode_libdir_separator_GCJ=: ++ hardcode_direct_GCJ=yes ++ ++ # hardcode_minus_L: Not really in the search PATH, ++ # but as the default location of the library. ++ hardcode_minus_L_GCJ=yes ++ export_dynamic_flag_spec_GCJ='${wl}-E' ++ ;; ++ ++ hpux10*) ++ if test "$GCC" = yes -a "$with_gnu_ld" = no; then ++ archive_cmds_GCJ='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ archive_cmds_GCJ='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' ++ fi ++ if test "$with_gnu_ld" = no; then ++ hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir' ++ hardcode_libdir_separator_GCJ=: ++ ++ hardcode_direct_GCJ=yes ++ export_dynamic_flag_spec_GCJ='${wl}-E' ++ ++ # hardcode_minus_L: Not really in the search PATH, ++ # but as the default location of the library. ++ hardcode_minus_L_GCJ=yes ++ fi ++ ;; ++ ++ hpux11*) ++ if test "$GCC" = yes -a "$with_gnu_ld" = no; then ++ case $host_cpu in ++ hppa*64*) ++ archive_cmds_GCJ='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ ia64*) ++ archive_cmds_GCJ='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ *) ++ archive_cmds_GCJ='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ esac ++ else ++ case $host_cpu in ++ hppa*64*) ++ archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ ia64*) ++ archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ *) ++ archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ esac ++ fi ++ if test "$with_gnu_ld" = no; then ++ hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir' ++ hardcode_libdir_separator_GCJ=: ++ ++ case $host_cpu in ++ hppa*64*|ia64*) ++ hardcode_libdir_flag_spec_ld_GCJ='+b $libdir' ++ hardcode_direct_GCJ=no ++ hardcode_shlibpath_var_GCJ=no ++ ;; ++ *) ++ hardcode_direct_GCJ=yes ++ export_dynamic_flag_spec_GCJ='${wl}-E' ++ ++ # hardcode_minus_L: Not really in the search PATH, ++ # but as the default location of the library. ++ hardcode_minus_L_GCJ=yes ++ ;; ++ esac ++ fi ++ ;; ++ ++ irix5* | irix6* | nonstopux*) ++ if test "$GCC" = yes; then ++ archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ else ++ archive_cmds_GCJ='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' ++ hardcode_libdir_flag_spec_ld_GCJ='-rpath $libdir' ++ fi ++ hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' ++ hardcode_libdir_separator_GCJ=: ++ link_all_deplibs_GCJ=yes ++ ;; ++ ++ netbsd*) ++ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then ++ archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out ++ else ++ archive_cmds_GCJ='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF ++ fi ++ hardcode_libdir_flag_spec_GCJ='-R$libdir' ++ hardcode_direct_GCJ=yes ++ hardcode_shlibpath_var_GCJ=no ++ ;; ++ ++ newsos6) ++ archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_direct_GCJ=yes ++ hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' ++ hardcode_libdir_separator_GCJ=: ++ hardcode_shlibpath_var_GCJ=no ++ ;; ++ ++ openbsd*) ++ hardcode_direct_GCJ=yes ++ hardcode_shlibpath_var_GCJ=no ++ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then ++ archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' ++ hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir' ++ export_dynamic_flag_spec_GCJ='${wl}-E' ++ else ++ case $host_os in ++ openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) ++ archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_libdir_flag_spec_GCJ='-R$libdir' ++ ;; ++ *) ++ archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ++ hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir' ++ ;; ++ esac ++ fi ++ ;; ++ ++ os2*) ++ hardcode_libdir_flag_spec_GCJ='-L$libdir' ++ hardcode_minus_L_GCJ=yes ++ allow_undefined_flag_GCJ=unsupported ++ archive_cmds_GCJ='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' ++ old_archive_From_new_cmds_GCJ='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ++ ;; ++ ++ osf3*) ++ if test "$GCC" = yes; then ++ allow_undefined_flag_GCJ=' ${wl}-expect_unresolved ${wl}\*' ++ archive_cmds_GCJ='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ else ++ allow_undefined_flag_GCJ=' -expect_unresolved \*' ++ archive_cmds_GCJ='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' ++ fi ++ hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' ++ hardcode_libdir_separator_GCJ=: ++ ;; ++ ++ osf4* | osf5*) # as osf3* with the addition of -msym flag ++ if test "$GCC" = yes; then ++ allow_undefined_flag_GCJ=' ${wl}-expect_unresolved ${wl}\*' ++ archive_cmds_GCJ='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' ++ else ++ allow_undefined_flag_GCJ=' -expect_unresolved \*' ++ archive_cmds_GCJ='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' ++ archive_expsym_cmds_GCJ='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ ++ $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' ++ ++ # Both c and cxx compiler support -rpath directly ++ hardcode_libdir_flag_spec_GCJ='-rpath $libdir' ++ fi ++ hardcode_libdir_separator_GCJ=: ++ ;; ++ ++ solaris*) ++ no_undefined_flag_GCJ=' -z text' ++ if test "$GCC" = yes; then ++ wlarc='${wl}' ++ archive_cmds_GCJ='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ ++ $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' ++ else ++ wlarc='' ++ archive_cmds_GCJ='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ ++ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' ++ fi ++ hardcode_libdir_flag_spec_GCJ='-R$libdir' ++ hardcode_shlibpath_var_GCJ=no ++ case $host_os in ++ solaris2.[0-5] | solaris2.[0-5].*) ;; ++ *) ++ # The compiler driver will combine linker options so we ++ # cannot just pass the convience library names through ++ # without $wl, iff we do not link with $LD. ++ # Luckily, gcc supports the same syntax we need for Sun Studio. ++ # Supported since Solaris 2.6 (maybe 2.5.1?) ++ case $wlarc in ++ '') ++ whole_archive_flag_spec_GCJ='-z allextract$convenience -z defaultextract' ;; ++ *) ++ whole_archive_flag_spec_GCJ='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;; ++ esac ;; ++ esac ++ link_all_deplibs_GCJ=yes ++ ;; ++ ++ sunos4*) ++ if test "x$host_vendor" = xsequent; then ++ # Use $CC to link under sequent, because it throws in some extra .o ++ # files that make .init and .fini sections work. ++ archive_cmds_GCJ='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ archive_cmds_GCJ='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' ++ fi ++ hardcode_libdir_flag_spec_GCJ='-L$libdir' ++ hardcode_direct_GCJ=yes ++ hardcode_minus_L_GCJ=yes ++ hardcode_shlibpath_var_GCJ=no ++ ;; ++ ++ sysv4) ++ case $host_vendor in ++ sni) ++ archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_direct_GCJ=yes # is this really true??? ++ ;; ++ siemens) ++ ## LD is ld it makes a PLAMLIB ++ ## CC just makes a GrossModule. ++ archive_cmds_GCJ='$LD -G -o $lib $libobjs $deplibs $linker_flags' ++ reload_cmds_GCJ='$CC -r -o $output$reload_objs' ++ hardcode_direct_GCJ=no ++ ;; ++ motorola) ++ archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_direct_GCJ=no #Motorola manual says yes, but my tests say they lie ++ ;; ++ esac ++ runpath_var='LD_RUN_PATH' ++ hardcode_shlibpath_var_GCJ=no ++ ;; ++ ++ sysv4.3*) ++ archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_shlibpath_var_GCJ=no ++ export_dynamic_flag_spec_GCJ='-Bexport' ++ ;; ++ ++ sysv4*MP*) ++ if test -d /usr/nec; then ++ archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_shlibpath_var_GCJ=no ++ runpath_var=LD_RUN_PATH ++ hardcode_runpath_var=yes ++ ld_shlibs_GCJ=yes ++ fi ++ ;; ++ ++ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*) ++ no_undefined_flag_GCJ='${wl}-z,text' ++ archive_cmds_need_lc_GCJ=no ++ hardcode_shlibpath_var_GCJ=no ++ runpath_var='LD_RUN_PATH' ++ ++ if test "$GCC" = yes; then ++ archive_cmds_GCJ='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds_GCJ='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ archive_cmds_GCJ='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds_GCJ='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ fi ++ ;; ++ ++ sysv5* | sco3.2v5* | sco5v6*) ++ # Note: We can NOT use -z defs as we might desire, because we do not ++ # link with -lc, and that would cause any symbols used from libc to ++ # always be unresolved, which means just about no library would ++ # ever link correctly. If we're not using GNU ld we use -z text ++ # though, which does catch some bad symbols but isn't as heavy-handed ++ # as -z defs. ++ no_undefined_flag_GCJ='${wl}-z,text' ++ allow_undefined_flag_GCJ='${wl}-z,nodefs' ++ archive_cmds_need_lc_GCJ=no ++ hardcode_shlibpath_var_GCJ=no ++ hardcode_libdir_flag_spec_GCJ='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' ++ hardcode_libdir_separator_GCJ=':' ++ link_all_deplibs_GCJ=yes ++ export_dynamic_flag_spec_GCJ='${wl}-Bexport' ++ runpath_var='LD_RUN_PATH' ++ ++ if test "$GCC" = yes; then ++ archive_cmds_GCJ='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds_GCJ='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ archive_cmds_GCJ='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds_GCJ='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ fi ++ ;; ++ ++ uts4*) ++ archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_libdir_flag_spec_GCJ='-L$libdir' ++ hardcode_shlibpath_var_GCJ=no ++ ;; ++ ++ *) ++ ld_shlibs_GCJ=no ++ ;; ++ esac ++ fi ++ ++echo "$as_me:$LINENO: result: $ld_shlibs_GCJ" >&5 ++echo "${ECHO_T}$ld_shlibs_GCJ" >&6 ++test "$ld_shlibs_GCJ" = no && can_build_shared=no ++ ++# ++# Do we need to explicitly link libc? ++# ++case "x$archive_cmds_need_lc_GCJ" in ++x|xyes) ++ # Assume -lc should be added ++ archive_cmds_need_lc_GCJ=yes ++ ++ if test "$enable_shared" = yes && test "$GCC" = yes; then ++ case $archive_cmds_GCJ in ++ *'~'*) ++ # FIXME: we may have to deal with multi-command sequences. ++ ;; ++ '$CC '*) ++ # Test whether the compiler implicitly links with -lc since on some ++ # systems, -lgcc has to come before -lc. If gcc already passes -lc ++ # to ld, don't add -lc before -lgcc. ++ echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 ++echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6 ++ $rm conftest* ++ printf "$lt_simple_compile_test_code" > conftest.$ac_ext ++ ++ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } 2>conftest.err; then ++ soname=conftest ++ lib=conftest ++ libobjs=conftest.$ac_objext ++ deplibs= ++ wl=$lt_prog_compiler_wl_GCJ ++ pic_flag=$lt_prog_compiler_pic_GCJ ++ compiler_flags=-v ++ linker_flags=-v ++ verstring= ++ output_objdir=. ++ libname=conftest ++ lt_save_allow_undefined_flag=$allow_undefined_flag_GCJ ++ allow_undefined_flag_GCJ= ++ if { (eval echo "$as_me:$LINENO: \"$archive_cmds_GCJ 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 ++ (eval $archive_cmds_GCJ 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } ++ then ++ archive_cmds_need_lc_GCJ=no ++ else ++ archive_cmds_need_lc_GCJ=yes ++ fi ++ allow_undefined_flag_GCJ=$lt_save_allow_undefined_flag ++ else ++ cat conftest.err 1>&5 ++ fi ++ $rm conftest* ++ echo "$as_me:$LINENO: result: $archive_cmds_need_lc_GCJ" >&5 ++echo "${ECHO_T}$archive_cmds_need_lc_GCJ" >&6 ++ ;; ++ esac ++ fi ++ ;; ++esac ++ ++echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 ++echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6 ++library_names_spec= ++libname_spec='lib$name' ++soname_spec= ++shrext_cmds=".so" ++postinstall_cmds= ++postuninstall_cmds= ++finish_cmds= ++finish_eval= ++shlibpath_var= ++shlibpath_overrides_runpath=unknown ++version_type=none ++dynamic_linker="$host_os ld.so" ++sys_lib_dlsearch_path_spec="/lib /usr/lib" ++if test "$GCC" = yes; then ++ sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` ++ if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then ++ # if the path contains ";" then we assume it to be the separator ++ # otherwise default to the standard path separator (i.e. ":") - it is ++ # assumed that no part of a normal pathname contains ";" but that should ++ # okay in the real world where ";" in dirpaths is itself problematic. ++ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` ++ else ++ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ++ fi ++else ++ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" ++fi ++need_lib_prefix=unknown ++hardcode_into_libs=no ++ ++# when you set need_version to no, make sure it does not cause -set_version ++# flags to be left without arguments ++need_version=unknown ++ ++case $host_os in ++aix3*) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' ++ shlibpath_var=LIBPATH ++ ++ # AIX 3 has no versioning support, so we append a major version to the name. ++ soname_spec='${libname}${release}${shared_ext}$major' ++ ;; ++ ++aix4* | aix5*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ hardcode_into_libs=yes ++ if test "$host_cpu" = ia64; then ++ # AIX 5 supports IA64 ++ library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' ++ shlibpath_var=LD_LIBRARY_PATH ++ else ++ # With GCC up to 2.95.x, collect2 would create an import file ++ # for dependence libraries. The import file would start with ++ # the line `#! .'. This would cause the generated library to ++ # depend on `.', always an invalid library. This was fixed in ++ # development snapshots of GCC prior to 3.0. ++ case $host_os in ++ aix4 | aix4.[01] | aix4.[01].*) ++ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' ++ echo ' yes ' ++ echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then ++ : ++ else ++ can_build_shared=no ++ fi ++ ;; ++ esac ++ # AIX (on Power*) has no versioning support, so currently we can not hardcode correct ++ # soname into executable. Probably we can add versioning support to ++ # collect2, so additional links can be useful in future. ++ if test "$aix_use_runtimelinking" = yes; then ++ # If using run time linking (on AIX 4.2 or later) use lib.so ++ # instead of lib.a to let people know that these are not ++ # typical AIX shared libraries. ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ else ++ # We preserve .a as extension for shared libraries through AIX4.2 ++ # and later when we are not doing run time linking. ++ library_names_spec='${libname}${release}.a $libname.a' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ fi ++ shlibpath_var=LIBPATH ++ fi ++ ;; ++ ++amigaos*) ++ library_names_spec='$libname.ixlibrary $libname.a' ++ # Create ${libname}_ixlibrary.a entries in /sys/libs. ++ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ++ ;; ++ ++beos*) ++ library_names_spec='${libname}${shared_ext}' ++ dynamic_linker="$host_os ld.so" ++ shlibpath_var=LIBRARY_PATH ++ ;; ++ ++bsdi[45]*) ++ version_type=linux ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" ++ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" ++ # the default ld.so.conf also contains /usr/contrib/lib and ++ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow ++ # libtool to hard-code these into programs ++ ;; ++ ++cygwin* | mingw* | pw32*) ++ version_type=windows ++ shrext_cmds=".dll" ++ need_version=no ++ need_lib_prefix=no ++ ++ case $GCC,$host_os in ++ yes,cygwin* | yes,mingw* | yes,pw32*) ++ library_names_spec='$libname.dll.a' ++ # DLL is installed to $(libdir)/../bin by postinstall_cmds ++ postinstall_cmds='base_file=`basename \${file}`~ ++ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ ++ dldir=$destdir/`dirname \$dlpath`~ ++ test -d \$dldir || mkdir -p \$dldir~ ++ $install_prog $dir/$dlname \$dldir/$dlname~ ++ chmod a+x \$dldir/$dlname' ++ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ ++ dlpath=$dir/\$dldll~ ++ $rm \$dlpath' ++ shlibpath_overrides_runpath=yes ++ ++ case $host_os in ++ cygwin*) ++ # Cygwin DLLs use 'cyg' prefix rather than 'lib' ++ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ++ sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" ++ ;; ++ mingw*) ++ # MinGW DLLs use traditional 'lib' prefix ++ soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ++ sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` ++ if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then ++ # It is most probably a Windows format PATH printed by ++ # mingw gcc, but we are running on Cygwin. Gcc prints its search ++ # path with ; separators, and with drive letters. We can handle the ++ # drive letters (cygwin fileutils understands them), so leave them, ++ # especially as we might pass files found there to a mingw objdump, ++ # which wouldn't understand a cygwinified path. Ahh. ++ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` ++ else ++ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ++ fi ++ ;; ++ pw32*) ++ # pw32 DLLs use 'pw' prefix rather than 'lib' ++ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ++ ;; ++ esac ++ ;; ++ ++ *) ++ library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' ++ ;; ++ esac ++ dynamic_linker='Win32 ld.exe' ++ # FIXME: first we should search . and the directory the executable is in ++ shlibpath_var=PATH ++ ;; ++ ++darwin* | rhapsody*) ++ dynamic_linker="$host_os dyld" ++ version_type=darwin ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' ++ soname_spec='${libname}${release}${major}$shared_ext' ++ shlibpath_overrides_runpath=yes ++ shlibpath_var=DYLD_LIBRARY_PATH ++ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' ++ # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. ++ if test "$GCC" = yes; then ++ sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` ++ else ++ sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' ++ fi ++ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ++ ;; ++ ++dgux*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ ;; ++ ++freebsd1*) ++ dynamic_linker=no ++ ;; ++ ++kfreebsd*-gnu) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ dynamic_linker='GNU ld.so' ++ ;; ++ ++freebsd* | dragonfly*) ++ # DragonFly does not have aout. When/if they implement a new ++ # versioning mechanism, adjust this. ++ if test -x /usr/bin/objformat; then ++ objformat=`/usr/bin/objformat` ++ else ++ case $host_os in ++ freebsd[123]*) objformat=aout ;; ++ *) objformat=elf ;; ++ esac ++ fi ++ version_type=freebsd-$objformat ++ case $version_type in ++ freebsd-elf*) ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' ++ need_version=no ++ need_lib_prefix=no ++ ;; ++ freebsd-*) ++ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' ++ need_version=yes ++ ;; ++ esac ++ shlibpath_var=LD_LIBRARY_PATH ++ case $host_os in ++ freebsd2*) ++ shlibpath_overrides_runpath=yes ++ ;; ++ freebsd3.[01]* | freebsdelf3.[01]*) ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ ++ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ ;; ++ freebsd*) # from 4.6 on ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ esac ++ ;; ++ ++gnu*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ hardcode_into_libs=yes ++ ;; ++ ++hpux9* | hpux10* | hpux11*) ++ # Give a soname corresponding to the major version so that dld.sl refuses to ++ # link against other versions. ++ version_type=sunos ++ need_lib_prefix=no ++ need_version=no ++ case $host_cpu in ++ ia64*) ++ shrext_cmds='.so' ++ hardcode_into_libs=yes ++ dynamic_linker="$host_os dld.so" ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ if test "X$HPUX_IA64_MODE" = X32; then ++ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" ++ else ++ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" ++ fi ++ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ++ ;; ++ hppa*64*) ++ shrext_cmds='.sl' ++ hardcode_into_libs=yes ++ dynamic_linker="$host_os dld.sl" ++ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH ++ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" ++ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ++ ;; ++ *) ++ shrext_cmds='.sl' ++ dynamic_linker="$host_os dld.sl" ++ shlibpath_var=SHLIB_PATH ++ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ ;; ++ esac ++ # HP-UX runs *really* slowly unless shared libraries are mode 555. ++ postinstall_cmds='chmod 555 $lib' ++ ;; ++ ++interix3*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ ;; ++ ++irix5* | irix6* | nonstopux*) ++ case $host_os in ++ nonstopux*) version_type=nonstopux ;; ++ *) ++ if test "$lt_cv_prog_gnu_ld" = yes; then ++ version_type=linux ++ else ++ version_type=irix ++ fi ;; ++ esac ++ need_lib_prefix=no ++ need_version=no ++ soname_spec='${libname}${release}${shared_ext}$major' ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' ++ case $host_os in ++ irix5* | nonstopux*) ++ libsuff= shlibsuff= ++ ;; ++ *) ++ case $LD in # libtool.m4 will add one of these switches to LD ++ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") ++ libsuff= shlibsuff= libmagic=32-bit;; ++ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") ++ libsuff=32 shlibsuff=N32 libmagic=N32;; ++ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") ++ libsuff=64 shlibsuff=64 libmagic=64-bit;; ++ *) libsuff= shlibsuff= libmagic=never-match;; ++ esac ++ ;; ++ esac ++ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH ++ shlibpath_overrides_runpath=no ++ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" ++ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" ++ hardcode_into_libs=yes ++ ;; ++ ++# No shared lib support for Linux oldld, aout, or coff. ++linux*oldld* | linux*aout* | linux*coff*) ++ dynamic_linker=no ++ ;; ++ ++# This must be Linux ELF. ++linux*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ # This implies no fast_install, which is unacceptable. ++ # Some rework will be needed to allow for fast_install ++ # before this can be enabled. ++ hardcode_into_libs=yes ++ ++ # find out which ABI we are using ++ libsuff= ++ case "$host_cpu" in ++ x86_64*|s390x*|powerpc64*) ++ echo '#line 20066 "configure"' > conftest.$ac_ext ++ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; then ++ case `/usr/bin/file conftest.$ac_objext` in ++ *64-bit*) ++ libsuff=64 ++ sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}" ++ ;; ++ esac ++ fi ++ rm -rf conftest* ++ ;; ++ esac ++ ++ # Append ld.so.conf contents to the search path ++ if test -f /etc/ld.so.conf; then ++ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` ++ sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff} $lt_ld_extra" ++ fi ++ ++ # We used to test for /lib/ld.so.1 and disable shared libraries on ++ # powerpc, because MkLinux only supported shared libraries with the ++ # GNU dynamic linker. Since this was broken with cross compilers, ++ # most powerpc-linux boxes support dynamic linking these days and ++ # people can always --disable-shared, the test was removed, and we ++ # assume the GNU/Linux dynamic linker is in use. ++ dynamic_linker='GNU/Linux ld.so' ++ ;; ++ ++knetbsd*-gnu) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ dynamic_linker='GNU ld.so' ++ ;; ++ ++netbsd*) ++ version_type=sunos ++ need_lib_prefix=no ++ need_version=no ++ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' ++ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' ++ dynamic_linker='NetBSD (a.out) ld.so' ++ else ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ dynamic_linker='NetBSD ld.elf_so' ++ fi ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ ++newsos6) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ ;; ++ ++nto-qnx*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ ;; ++ ++openbsd*) ++ version_type=sunos ++ sys_lib_dlsearch_path_spec="/usr/lib" ++ need_lib_prefix=no ++ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. ++ case $host_os in ++ openbsd3.3 | openbsd3.3.*) need_version=yes ;; ++ *) need_version=no ;; ++ esac ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' ++ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then ++ case $host_os in ++ openbsd2.[89] | openbsd2.[89].*) ++ shlibpath_overrides_runpath=no ++ ;; ++ *) ++ shlibpath_overrides_runpath=yes ++ ;; ++ esac ++ else ++ shlibpath_overrides_runpath=yes ++ fi ++ ;; ++ ++os2*) ++ libname_spec='$name' ++ shrext_cmds=".dll" ++ need_lib_prefix=no ++ library_names_spec='$libname${shared_ext} $libname.a' ++ dynamic_linker='OS/2 ld.exe' ++ shlibpath_var=LIBPATH ++ ;; ++ ++osf3* | osf4* | osf5*) ++ version_type=osf ++ need_lib_prefix=no ++ need_version=no ++ soname_spec='${libname}${release}${shared_ext}$major' ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ shlibpath_var=LD_LIBRARY_PATH ++ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" ++ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ++ ;; ++ ++solaris*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ # ldd complains unless libraries are executable ++ postinstall_cmds='chmod +x $lib' ++ ;; ++ ++sunos4*) ++ version_type=sunos ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' ++ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ if test "$with_gnu_ld" = yes; then ++ need_lib_prefix=no ++ fi ++ need_version=yes ++ ;; ++ ++sysv4 | sysv4.3*) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ case $host_vendor in ++ sni) ++ shlibpath_overrides_runpath=no ++ need_lib_prefix=no ++ export_dynamic_flag_spec='${wl}-Blargedynsym' ++ runpath_var=LD_RUN_PATH ++ ;; ++ siemens) ++ need_lib_prefix=no ++ ;; ++ motorola) ++ need_lib_prefix=no ++ need_version=no ++ shlibpath_overrides_runpath=no ++ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ++ ;; ++ esac ++ ;; ++ ++sysv4*MP*) ++ if test -d /usr/nec ;then ++ version_type=linux ++ library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' ++ soname_spec='$libname${shared_ext}.$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ fi ++ ;; ++ ++sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) ++ version_type=freebsd-elf ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ hardcode_into_libs=yes ++ if test "$with_gnu_ld" = yes; then ++ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' ++ shlibpath_overrides_runpath=no ++ else ++ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' ++ shlibpath_overrides_runpath=yes ++ case $host_os in ++ sco3.2v5*) ++ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ++ ;; ++ esac ++ fi ++ sys_lib_dlsearch_path_spec='/usr/lib' ++ ;; ++ ++uts4*) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ ;; ++ ++*) ++ dynamic_linker=no ++ ;; ++esac ++echo "$as_me:$LINENO: result: $dynamic_linker" >&5 ++echo "${ECHO_T}$dynamic_linker" >&6 ++test "$dynamic_linker" = no && can_build_shared=no ++ ++variables_saved_for_relink="PATH $shlibpath_var $runpath_var" ++if test "$GCC" = yes; then ++ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" ++fi ++ ++echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 ++echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6 ++hardcode_action_GCJ= ++if test -n "$hardcode_libdir_flag_spec_GCJ" || \ ++ test -n "$runpath_var_GCJ" || \ ++ test "X$hardcode_automatic_GCJ" = "Xyes" ; then ++ ++ # We can hardcode non-existant directories. ++ if test "$hardcode_direct_GCJ" != no && ++ # If the only mechanism to avoid hardcoding is shlibpath_var, we ++ # have to relink, otherwise we might link with an installed library ++ # when we should be linking with a yet-to-be-installed one ++ ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, GCJ)" != no && ++ test "$hardcode_minus_L_GCJ" != no; then ++ # Linking always hardcodes the temporary library directory. ++ hardcode_action_GCJ=relink ++ else ++ # We can link without hardcoding, and we can hardcode nonexisting dirs. ++ hardcode_action_GCJ=immediate ++ fi ++else ++ # We cannot hardcode anything, or else we can only hardcode existing ++ # directories. ++ hardcode_action_GCJ=unsupported ++fi ++echo "$as_me:$LINENO: result: $hardcode_action_GCJ" >&5 ++echo "${ECHO_T}$hardcode_action_GCJ" >&6 ++ ++if test "$hardcode_action_GCJ" = relink; then ++ # Fast installation is not supported ++ enable_fast_install=no ++elif test "$shlibpath_overrides_runpath" = yes || ++ test "$enable_shared" = no; then ++ # Fast installation is not necessary ++ enable_fast_install=needless ++fi ++ ++ ++# The else clause should only fire when bootstrapping the ++# libtool distribution, otherwise you forgot to ship ltmain.sh ++# with your package, and you will get complaints that there are ++# no rules to generate ltmain.sh. ++if test -f "$ltmain"; then ++ # See if we are running on zsh, and set the options which allow our commands through ++ # without removal of \ escapes. ++ if test -n "${ZSH_VERSION+set}" ; then ++ setopt NO_GLOB_SUBST ++ fi ++ # Now quote all the things that may contain metacharacters while being ++ # careful not to overquote the AC_SUBSTed values. We take copies of the ++ # variables and quote the copies for generation of the libtool script. ++ for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ ++ SED SHELL STRIP \ ++ libname_spec library_names_spec soname_spec extract_expsyms_cmds \ ++ old_striplib striplib file_magic_cmd finish_cmds finish_eval \ ++ deplibs_check_method reload_flag reload_cmds need_locks \ ++ lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ ++ lt_cv_sys_global_symbol_to_c_name_address \ ++ sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ ++ old_postinstall_cmds old_postuninstall_cmds \ ++ compiler_GCJ \ ++ CC_GCJ \ ++ LD_GCJ \ ++ lt_prog_compiler_wl_GCJ \ ++ lt_prog_compiler_pic_GCJ \ ++ lt_prog_compiler_static_GCJ \ ++ lt_prog_compiler_no_builtin_flag_GCJ \ ++ export_dynamic_flag_spec_GCJ \ ++ thread_safe_flag_spec_GCJ \ ++ whole_archive_flag_spec_GCJ \ ++ enable_shared_with_static_runtimes_GCJ \ ++ old_archive_cmds_GCJ \ ++ old_archive_from_new_cmds_GCJ \ ++ predep_objects_GCJ \ ++ postdep_objects_GCJ \ ++ predeps_GCJ \ ++ postdeps_GCJ \ ++ compiler_lib_search_path_GCJ \ ++ archive_cmds_GCJ \ ++ archive_expsym_cmds_GCJ \ ++ postinstall_cmds_GCJ \ ++ postuninstall_cmds_GCJ \ ++ old_archive_from_expsyms_cmds_GCJ \ ++ allow_undefined_flag_GCJ \ ++ no_undefined_flag_GCJ \ ++ export_symbols_cmds_GCJ \ ++ hardcode_libdir_flag_spec_GCJ \ ++ hardcode_libdir_flag_spec_ld_GCJ \ ++ hardcode_libdir_separator_GCJ \ ++ hardcode_automatic_GCJ \ ++ module_cmds_GCJ \ ++ module_expsym_cmds_GCJ \ ++ lt_cv_prog_compiler_c_o_GCJ \ ++ exclude_expsyms_GCJ \ ++ include_expsyms_GCJ; do ++ ++ case $var in ++ old_archive_cmds_GCJ | \ ++ old_archive_from_new_cmds_GCJ | \ ++ archive_cmds_GCJ | \ ++ archive_expsym_cmds_GCJ | \ ++ module_cmds_GCJ | \ ++ module_expsym_cmds_GCJ | \ ++ old_archive_from_expsyms_cmds_GCJ | \ ++ export_symbols_cmds_GCJ | \ ++ extract_expsyms_cmds | reload_cmds | finish_cmds | \ ++ postinstall_cmds | postuninstall_cmds | \ ++ old_postinstall_cmds | old_postuninstall_cmds | \ ++ sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) ++ # Double-quote double-evaled strings. ++ eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" ++ ;; ++ *) ++ eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" ++ ;; ++ esac ++ done ++ ++ case $lt_echo in ++ *'\$0 --fallback-echo"') ++ lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` ++ ;; ++ esac ++ ++cfgfile="$ofile" ++ ++ cat <<__EOF__ >> "$cfgfile" ++# ### BEGIN LIBTOOL TAG CONFIG: $tagname ++ ++# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: ++ ++# Shell to use when invoking shell scripts. ++SHELL=$lt_SHELL ++ ++# Whether or not to build shared libraries. ++build_libtool_libs=$enable_shared ++ ++# Whether or not to build static libraries. ++build_old_libs=$enable_static ++ ++# Whether or not to add -lc for building shared libraries. ++build_libtool_need_lc=$archive_cmds_need_lc_GCJ ++ ++# Whether or not to disallow shared libs when runtime libs are static ++allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_GCJ ++ ++# Whether or not to optimize for fast installation. ++fast_install=$enable_fast_install ++ ++# The host system. ++host_alias=$host_alias ++host=$host ++host_os=$host_os ++ ++# The build system. ++build_alias=$build_alias ++build=$build ++build_os=$build_os ++ ++# An echo program that does not interpret backslashes. ++echo=$lt_echo ++ ++# The archiver. ++AR=$lt_AR ++AR_FLAGS=$lt_AR_FLAGS ++ ++# A C compiler. ++LTCC=$lt_LTCC ++ ++# LTCC compiler flags. ++LTCFLAGS=$lt_LTCFLAGS ++ ++# A language-specific compiler. ++CC=$lt_compiler_GCJ ++ ++# Is the compiler the GNU C compiler? ++with_gcc=$GCC_GCJ ++ ++gcc_dir=\`gcc -print-file-name=. | $SED 's,/\.$,,'\` ++gcc_ver=\`gcc -dumpversion\` ++ ++# An ERE matcher. ++EGREP=$lt_EGREP ++ ++# The linker used to build libraries. ++LD=$lt_LD_GCJ ++ ++# Whether we need hard or soft links. ++LN_S=$lt_LN_S ++ ++# A BSD-compatible nm program. ++NM=$lt_NM ++ ++# A symbol stripping program ++STRIP=$lt_STRIP ++ ++# Used to examine libraries when file_magic_cmd begins "file" ++MAGIC_CMD=$MAGIC_CMD ++ ++# Used on cygwin: DLL creation program. ++DLLTOOL="$DLLTOOL" ++ ++# Used on cygwin: object dumper. ++OBJDUMP="$OBJDUMP" ++ ++# Used on cygwin: assembler. ++AS="$AS" ++ ++# The name of the directory that contains temporary libtool files. ++objdir=$objdir ++ ++# How to create reloadable object files. ++reload_flag=$lt_reload_flag ++reload_cmds=$lt_reload_cmds ++ ++# How to pass a linker flag through the compiler. ++wl=$lt_lt_prog_compiler_wl_GCJ ++ ++# Object file suffix (normally "o"). ++objext="$ac_objext" ++ ++# Old archive suffix (normally "a"). ++libext="$libext" ++ ++# Shared library suffix (normally ".so"). ++shrext_cmds='$shrext_cmds' ++ ++# Executable file suffix (normally ""). ++exeext="$exeext" ++ ++# Additional compiler flags for building library objects. ++pic_flag=$lt_lt_prog_compiler_pic_GCJ ++pic_mode=$pic_mode ++ ++# What is the maximum length of a command? ++max_cmd_len=$lt_cv_sys_max_cmd_len ++ ++# Does compiler simultaneously support -c and -o options? ++compiler_c_o=$lt_lt_cv_prog_compiler_c_o_GCJ ++ ++# Must we lock files when doing compilation? ++need_locks=$lt_need_locks ++ ++# Do we need the lib prefix for modules? ++need_lib_prefix=$need_lib_prefix ++ ++# Do we need a version for libraries? ++need_version=$need_version ++ ++# Whether dlopen is supported. ++dlopen_support=$enable_dlopen ++ ++# Whether dlopen of programs is supported. ++dlopen_self=$enable_dlopen_self ++ ++# Whether dlopen of statically linked programs is supported. ++dlopen_self_static=$enable_dlopen_self_static ++ ++# Compiler flag to prevent dynamic linking. ++link_static_flag=$lt_lt_prog_compiler_static_GCJ ++ ++# Compiler flag to turn off builtin functions. ++no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_GCJ ++ ++# Compiler flag to allow reflexive dlopens. ++export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_GCJ ++ ++# Compiler flag to generate shared objects directly from archives. ++whole_archive_flag_spec=$lt_whole_archive_flag_spec_GCJ ++ ++# Compiler flag to generate thread-safe objects. ++thread_safe_flag_spec=$lt_thread_safe_flag_spec_GCJ ++ ++# Library versioning type. ++version_type=$version_type ++ ++# Format of library name prefix. ++libname_spec=$lt_libname_spec ++ ++# List of archive names. First name is the real one, the rest are links. ++# The last name is the one that the linker finds with -lNAME. ++library_names_spec=$lt_library_names_spec ++ ++# The coded name of the library, if different from the real name. ++soname_spec=$lt_soname_spec ++ ++# Commands used to build and install an old-style archive. ++RANLIB=$lt_RANLIB ++old_archive_cmds=$lt_old_archive_cmds_GCJ ++old_postinstall_cmds=$lt_old_postinstall_cmds ++old_postuninstall_cmds=$lt_old_postuninstall_cmds ++ ++# Create an old-style archive from a shared archive. ++old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_GCJ ++ ++# Create a temporary old-style archive to link instead of a shared archive. ++old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_GCJ ++ ++# Commands used to build and install a shared archive. ++archive_cmds=$lt_archive_cmds_GCJ ++archive_expsym_cmds=$lt_archive_expsym_cmds_GCJ ++postinstall_cmds=$lt_postinstall_cmds ++postuninstall_cmds=$lt_postuninstall_cmds ++ ++# Commands used to build a loadable module (assumed same as above if empty) ++module_cmds=$lt_module_cmds_GCJ ++module_expsym_cmds=$lt_module_expsym_cmds_GCJ ++ ++# Commands to strip libraries. ++old_striplib=$lt_old_striplib ++striplib=$lt_striplib ++ ++# Dependencies to place before the objects being linked to create a ++# shared library. ++predep_objects=\`echo $lt_predep_objects_GCJ | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` ++ ++# Dependencies to place after the objects being linked to create a ++# shared library. ++postdep_objects=\`echo $lt_postdep_objects_GCJ | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` ++ ++# Dependencies to place before the objects being linked to create a ++# shared library. ++predeps=$lt_predeps_GCJ ++ ++# Dependencies to place after the objects being linked to create a ++# shared library. ++postdeps=$lt_postdeps_GCJ ++ ++# The library search path used internally by the compiler when linking ++# a shared library. ++compiler_lib_search_path=\`echo $lt_compiler_lib_search_path_GCJ | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` ++ ++# Method to check whether dependent libraries are shared objects. ++deplibs_check_method=$lt_deplibs_check_method ++ ++# Command to use when deplibs_check_method == file_magic. ++file_magic_cmd=$lt_file_magic_cmd ++ ++# Flag that allows shared libraries with undefined symbols to be built. ++allow_undefined_flag=$lt_allow_undefined_flag_GCJ ++ ++# Flag that forces no undefined symbols. ++no_undefined_flag=$lt_no_undefined_flag_GCJ ++ ++# Commands used to finish a libtool library installation in a directory. ++finish_cmds=$lt_finish_cmds ++ ++# Same as above, but a single script fragment to be evaled but not shown. ++finish_eval=$lt_finish_eval ++ ++# Take the output of nm and produce a listing of raw symbols and C names. ++global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe ++ ++# Transform the output of nm in a proper C declaration ++global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl ++ ++# Transform the output of nm in a C name address pair ++global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address ++ ++# This is the shared library runtime path variable. ++runpath_var=$runpath_var ++ ++# This is the shared library path variable. ++shlibpath_var=$shlibpath_var ++ ++# Is shlibpath searched before the hard-coded library search path? ++shlibpath_overrides_runpath=$shlibpath_overrides_runpath ++ ++# How to hardcode a shared library path into an executable. ++hardcode_action=$hardcode_action_GCJ ++ ++# Whether we should hardcode library paths into libraries. ++hardcode_into_libs=$hardcode_into_libs ++ ++# Flag to hardcode \$libdir into a binary during linking. ++# This must work even if \$libdir does not exist. ++hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_GCJ ++ ++# If ld is used when linking, flag to hardcode \$libdir into ++# a binary during linking. This must work even if \$libdir does ++# not exist. ++hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_GCJ ++ ++# Whether we need a single -rpath flag with a separated argument. ++hardcode_libdir_separator=$lt_hardcode_libdir_separator_GCJ ++ ++# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the ++# resulting binary. ++hardcode_direct=$hardcode_direct_GCJ ++ ++# Set to yes if using the -LDIR flag during linking hardcodes DIR into the ++# resulting binary. ++hardcode_minus_L=$hardcode_minus_L_GCJ ++ ++# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into ++# the resulting binary. ++hardcode_shlibpath_var=$hardcode_shlibpath_var_GCJ ++ ++# Set to yes if building a shared library automatically hardcodes DIR into the library ++# and all subsequent libraries and executables linked against it. ++hardcode_automatic=$hardcode_automatic_GCJ ++ ++# Variables whose values should be saved in libtool wrapper scripts and ++# restored at relink time. ++variables_saved_for_relink="$variables_saved_for_relink" ++ ++# Whether libtool must link a program against all its dependency libraries. ++link_all_deplibs=$link_all_deplibs_GCJ ++ ++# Compile-time system search path for libraries ++sys_lib_search_path_spec=\`echo $lt_sys_lib_search_path_spec | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` ++ ++# Run-time system search path for libraries ++sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec ++ ++# Fix the shell variable \$srcfile for the compiler. ++fix_srcfile_path="$fix_srcfile_path_GCJ" ++ ++# Set to yes if exported symbols are required. ++always_export_symbols=$always_export_symbols_GCJ ++ ++# The commands to list exported symbols. ++export_symbols_cmds=$lt_export_symbols_cmds_GCJ ++ ++# The commands to extract the exported symbol list from a shared archive. ++extract_expsyms_cmds=$lt_extract_expsyms_cmds ++ ++# Symbols that should not be listed in the preloaded symbols. ++exclude_expsyms=$lt_exclude_expsyms_GCJ ++ ++# Symbols that must always be exported. ++include_expsyms=$lt_include_expsyms_GCJ ++ ++# ### END LIBTOOL TAG CONFIG: $tagname ++ ++__EOF__ ++ ++ ++else ++ # If there is no Makefile yet, we rely on a make rule to execute ++ # `config.status --recheck' to rerun these tests and create the ++ # libtool script then. ++ ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` ++ if test -f "$ltmain_in"; then ++ test -f Makefile && make "$ltmain" ++ fi ++fi ++ ++ ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++CC="$lt_save_CC" ++ ++ else ++ tagname="" ++ fi ++ ;; ++ ++ RC) ++ ++ ++ ++# Source file extension for RC test sources. ++ac_ext=rc ++ ++# Object file extension for compiled RC test sources. ++objext=o ++objext_RC=$objext ++ ++# Code to be used in simple compile tests ++lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }\n' ++ ++# Code to be used in simple link tests ++lt_simple_link_test_code="$lt_simple_compile_test_code" ++ ++# ltmain only uses $CC for tagged configurations so make sure $CC is set. ++ ++# If no C compiler was specified, use CC. ++LTCC=${LTCC-"$CC"} ++ ++# If no C compiler flags were specified, use CFLAGS. ++LTCFLAGS=${LTCFLAGS-"$CFLAGS"} ++ ++# Allow CC to be a program name with arguments. ++compiler=$CC ++ ++ ++# save warnings/boilerplate of simple test code ++ac_outfile=conftest.$ac_objext ++printf "$lt_simple_compile_test_code" >conftest.$ac_ext ++eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err ++_lt_compiler_boilerplate=`cat conftest.err` ++$rm conftest* ++ ++ac_outfile=conftest.$ac_objext ++printf "$lt_simple_link_test_code" >conftest.$ac_ext ++eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err ++_lt_linker_boilerplate=`cat conftest.err` ++$rm conftest* ++ ++ ++# Allow CC to be a program name with arguments. ++lt_save_CC="$CC" ++CC=${RC-"windres"} ++compiler=$CC ++compiler_RC=$CC ++for cc_temp in $compiler""; do ++ case $cc_temp in ++ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; ++ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; ++ \-*) ;; ++ *) break;; ++ esac ++done ++cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` ++ ++lt_cv_prog_compiler_c_o_RC=yes ++ ++# The else clause should only fire when bootstrapping the ++# libtool distribution, otherwise you forgot to ship ltmain.sh ++# with your package, and you will get complaints that there are ++# no rules to generate ltmain.sh. ++if test -f "$ltmain"; then ++ # See if we are running on zsh, and set the options which allow our commands through ++ # without removal of \ escapes. ++ if test -n "${ZSH_VERSION+set}" ; then ++ setopt NO_GLOB_SUBST ++ fi ++ # Now quote all the things that may contain metacharacters while being ++ # careful not to overquote the AC_SUBSTed values. We take copies of the ++ # variables and quote the copies for generation of the libtool script. ++ for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ ++ SED SHELL STRIP \ ++ libname_spec library_names_spec soname_spec extract_expsyms_cmds \ ++ old_striplib striplib file_magic_cmd finish_cmds finish_eval \ ++ deplibs_check_method reload_flag reload_cmds need_locks \ ++ lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ ++ lt_cv_sys_global_symbol_to_c_name_address \ ++ sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ ++ old_postinstall_cmds old_postuninstall_cmds \ ++ compiler_RC \ ++ CC_RC \ ++ LD_RC \ ++ lt_prog_compiler_wl_RC \ ++ lt_prog_compiler_pic_RC \ ++ lt_prog_compiler_static_RC \ ++ lt_prog_compiler_no_builtin_flag_RC \ ++ export_dynamic_flag_spec_RC \ ++ thread_safe_flag_spec_RC \ ++ whole_archive_flag_spec_RC \ ++ enable_shared_with_static_runtimes_RC \ ++ old_archive_cmds_RC \ ++ old_archive_from_new_cmds_RC \ ++ predep_objects_RC \ ++ postdep_objects_RC \ ++ predeps_RC \ ++ postdeps_RC \ ++ compiler_lib_search_path_RC \ ++ archive_cmds_RC \ ++ archive_expsym_cmds_RC \ ++ postinstall_cmds_RC \ ++ postuninstall_cmds_RC \ ++ old_archive_from_expsyms_cmds_RC \ ++ allow_undefined_flag_RC \ ++ no_undefined_flag_RC \ ++ export_symbols_cmds_RC \ ++ hardcode_libdir_flag_spec_RC \ ++ hardcode_libdir_flag_spec_ld_RC \ ++ hardcode_libdir_separator_RC \ ++ hardcode_automatic_RC \ ++ module_cmds_RC \ ++ module_expsym_cmds_RC \ ++ lt_cv_prog_compiler_c_o_RC \ ++ exclude_expsyms_RC \ ++ include_expsyms_RC; do ++ ++ case $var in ++ old_archive_cmds_RC | \ ++ old_archive_from_new_cmds_RC | \ ++ archive_cmds_RC | \ ++ archive_expsym_cmds_RC | \ ++ module_cmds_RC | \ ++ module_expsym_cmds_RC | \ ++ old_archive_from_expsyms_cmds_RC | \ ++ export_symbols_cmds_RC | \ ++ extract_expsyms_cmds | reload_cmds | finish_cmds | \ ++ postinstall_cmds | postuninstall_cmds | \ ++ old_postinstall_cmds | old_postuninstall_cmds | \ ++ sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) ++ # Double-quote double-evaled strings. ++ eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" ++ ;; ++ *) ++ eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" ++ ;; ++ esac ++ done ++ ++ case $lt_echo in ++ *'\$0 --fallback-echo"') ++ lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` ++ ;; ++ esac ++ ++cfgfile="$ofile" ++ ++ cat <<__EOF__ >> "$cfgfile" ++# ### BEGIN LIBTOOL TAG CONFIG: $tagname ++ ++# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: ++ ++# Shell to use when invoking shell scripts. ++SHELL=$lt_SHELL ++ ++# Whether or not to build shared libraries. ++build_libtool_libs=$enable_shared ++ ++# Whether or not to build static libraries. ++build_old_libs=$enable_static ++ ++# Whether or not to add -lc for building shared libraries. ++build_libtool_need_lc=$archive_cmds_need_lc_RC ++ ++# Whether or not to disallow shared libs when runtime libs are static ++allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_RC ++ ++# Whether or not to optimize for fast installation. ++fast_install=$enable_fast_install ++ ++# The host system. ++host_alias=$host_alias ++host=$host ++host_os=$host_os ++ ++# The build system. ++build_alias=$build_alias ++build=$build ++build_os=$build_os ++ ++# An echo program that does not interpret backslashes. ++echo=$lt_echo ++ ++# The archiver. ++AR=$lt_AR ++AR_FLAGS=$lt_AR_FLAGS ++ ++# A C compiler. ++LTCC=$lt_LTCC ++ ++# LTCC compiler flags. ++LTCFLAGS=$lt_LTCFLAGS ++ ++# A language-specific compiler. ++CC=$lt_compiler_RC ++ ++# Is the compiler the GNU C compiler? ++with_gcc=$GCC_RC ++ ++gcc_dir=\`gcc -print-file-name=. | $SED 's,/\.$,,'\` ++gcc_ver=\`gcc -dumpversion\` ++ ++# An ERE matcher. ++EGREP=$lt_EGREP ++ ++# The linker used to build libraries. ++LD=$lt_LD_RC ++ ++# Whether we need hard or soft links. ++LN_S=$lt_LN_S ++ ++# A BSD-compatible nm program. ++NM=$lt_NM ++ ++# A symbol stripping program ++STRIP=$lt_STRIP ++ ++# Used to examine libraries when file_magic_cmd begins "file" ++MAGIC_CMD=$MAGIC_CMD ++ ++# Used on cygwin: DLL creation program. ++DLLTOOL="$DLLTOOL" ++ ++# Used on cygwin: object dumper. ++OBJDUMP="$OBJDUMP" ++ ++# Used on cygwin: assembler. ++AS="$AS" ++ ++# The name of the directory that contains temporary libtool files. ++objdir=$objdir ++ ++# How to create reloadable object files. ++reload_flag=$lt_reload_flag ++reload_cmds=$lt_reload_cmds ++ ++# How to pass a linker flag through the compiler. ++wl=$lt_lt_prog_compiler_wl_RC ++ ++# Object file suffix (normally "o"). ++objext="$ac_objext" ++ ++# Old archive suffix (normally "a"). ++libext="$libext" ++ ++# Shared library suffix (normally ".so"). ++shrext_cmds='$shrext_cmds' ++ ++# Executable file suffix (normally ""). ++exeext="$exeext" ++ ++# Additional compiler flags for building library objects. ++pic_flag=$lt_lt_prog_compiler_pic_RC ++pic_mode=$pic_mode ++ ++# What is the maximum length of a command? ++max_cmd_len=$lt_cv_sys_max_cmd_len ++ ++# Does compiler simultaneously support -c and -o options? ++compiler_c_o=$lt_lt_cv_prog_compiler_c_o_RC ++ ++# Must we lock files when doing compilation? ++need_locks=$lt_need_locks ++ ++# Do we need the lib prefix for modules? ++need_lib_prefix=$need_lib_prefix ++ ++# Do we need a version for libraries? ++need_version=$need_version ++ ++# Whether dlopen is supported. ++dlopen_support=$enable_dlopen ++ ++# Whether dlopen of programs is supported. ++dlopen_self=$enable_dlopen_self ++ ++# Whether dlopen of statically linked programs is supported. ++dlopen_self_static=$enable_dlopen_self_static ++ ++# Compiler flag to prevent dynamic linking. ++link_static_flag=$lt_lt_prog_compiler_static_RC ++ ++# Compiler flag to turn off builtin functions. ++no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_RC ++ ++# Compiler flag to allow reflexive dlopens. ++export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_RC ++ ++# Compiler flag to generate shared objects directly from archives. ++whole_archive_flag_spec=$lt_whole_archive_flag_spec_RC ++ ++# Compiler flag to generate thread-safe objects. ++thread_safe_flag_spec=$lt_thread_safe_flag_spec_RC ++ ++# Library versioning type. ++version_type=$version_type ++ ++# Format of library name prefix. ++libname_spec=$lt_libname_spec ++ ++# List of archive names. First name is the real one, the rest are links. ++# The last name is the one that the linker finds with -lNAME. ++library_names_spec=$lt_library_names_spec ++ ++# The coded name of the library, if different from the real name. ++soname_spec=$lt_soname_spec ++ ++# Commands used to build and install an old-style archive. ++RANLIB=$lt_RANLIB ++old_archive_cmds=$lt_old_archive_cmds_RC ++old_postinstall_cmds=$lt_old_postinstall_cmds ++old_postuninstall_cmds=$lt_old_postuninstall_cmds ++ ++# Create an old-style archive from a shared archive. ++old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_RC ++ ++# Create a temporary old-style archive to link instead of a shared archive. ++old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_RC ++ ++# Commands used to build and install a shared archive. ++archive_cmds=$lt_archive_cmds_RC ++archive_expsym_cmds=$lt_archive_expsym_cmds_RC ++postinstall_cmds=$lt_postinstall_cmds ++postuninstall_cmds=$lt_postuninstall_cmds ++ ++# Commands used to build a loadable module (assumed same as above if empty) ++module_cmds=$lt_module_cmds_RC ++module_expsym_cmds=$lt_module_expsym_cmds_RC ++ ++# Commands to strip libraries. ++old_striplib=$lt_old_striplib ++striplib=$lt_striplib ++ ++# Dependencies to place before the objects being linked to create a ++# shared library. ++predep_objects=\`echo $lt_predep_objects_RC | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` ++ ++# Dependencies to place after the objects being linked to create a ++# shared library. ++postdep_objects=\`echo $lt_postdep_objects_RC | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` ++ ++# Dependencies to place before the objects being linked to create a ++# shared library. ++predeps=$lt_predeps_RC ++ ++# Dependencies to place after the objects being linked to create a ++# shared library. ++postdeps=$lt_postdeps_RC ++ ++# The library search path used internally by the compiler when linking ++# a shared library. ++compiler_lib_search_path=\`echo $lt_compiler_lib_search_path_RC | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` ++ ++# Method to check whether dependent libraries are shared objects. ++deplibs_check_method=$lt_deplibs_check_method ++ ++# Command to use when deplibs_check_method == file_magic. ++file_magic_cmd=$lt_file_magic_cmd ++ ++# Flag that allows shared libraries with undefined symbols to be built. ++allow_undefined_flag=$lt_allow_undefined_flag_RC ++ ++# Flag that forces no undefined symbols. ++no_undefined_flag=$lt_no_undefined_flag_RC ++ ++# Commands used to finish a libtool library installation in a directory. ++finish_cmds=$lt_finish_cmds ++ ++# Same as above, but a single script fragment to be evaled but not shown. ++finish_eval=$lt_finish_eval ++ ++# Take the output of nm and produce a listing of raw symbols and C names. ++global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe ++ ++# Transform the output of nm in a proper C declaration ++global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl ++ ++# Transform the output of nm in a C name address pair ++global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address ++ ++# This is the shared library runtime path variable. ++runpath_var=$runpath_var ++ ++# This is the shared library path variable. ++shlibpath_var=$shlibpath_var ++ ++# Is shlibpath searched before the hard-coded library search path? ++shlibpath_overrides_runpath=$shlibpath_overrides_runpath ++ ++# How to hardcode a shared library path into an executable. ++hardcode_action=$hardcode_action_RC ++ ++# Whether we should hardcode library paths into libraries. ++hardcode_into_libs=$hardcode_into_libs ++ ++# Flag to hardcode \$libdir into a binary during linking. ++# This must work even if \$libdir does not exist. ++hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_RC ++ ++# If ld is used when linking, flag to hardcode \$libdir into ++# a binary during linking. This must work even if \$libdir does ++# not exist. ++hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_RC ++ ++# Whether we need a single -rpath flag with a separated argument. ++hardcode_libdir_separator=$lt_hardcode_libdir_separator_RC ++ ++# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the ++# resulting binary. ++hardcode_direct=$hardcode_direct_RC ++ ++# Set to yes if using the -LDIR flag during linking hardcodes DIR into the ++# resulting binary. ++hardcode_minus_L=$hardcode_minus_L_RC ++ ++# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into ++# the resulting binary. ++hardcode_shlibpath_var=$hardcode_shlibpath_var_RC ++ ++# Set to yes if building a shared library automatically hardcodes DIR into the library ++# and all subsequent libraries and executables linked against it. ++hardcode_automatic=$hardcode_automatic_RC ++ ++# Variables whose values should be saved in libtool wrapper scripts and ++# restored at relink time. ++variables_saved_for_relink="$variables_saved_for_relink" ++ ++# Whether libtool must link a program against all its dependency libraries. ++link_all_deplibs=$link_all_deplibs_RC ++ ++# Compile-time system search path for libraries ++sys_lib_search_path_spec=\`echo $lt_sys_lib_search_path_spec | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` ++ ++# Run-time system search path for libraries ++sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec ++ ++# Fix the shell variable \$srcfile for the compiler. ++fix_srcfile_path="$fix_srcfile_path_RC" ++ ++# Set to yes if exported symbols are required. ++always_export_symbols=$always_export_symbols_RC ++ ++# The commands to list exported symbols. ++export_symbols_cmds=$lt_export_symbols_cmds_RC ++ ++# The commands to extract the exported symbol list from a shared archive. ++extract_expsyms_cmds=$lt_extract_expsyms_cmds ++ ++# Symbols that should not be listed in the preloaded symbols. ++exclude_expsyms=$lt_exclude_expsyms_RC ++ ++# Symbols that must always be exported. ++include_expsyms=$lt_include_expsyms_RC ++ ++# ### END LIBTOOL TAG CONFIG: $tagname ++ ++__EOF__ ++ ++ ++else ++ # If there is no Makefile yet, we rely on a make rule to execute ++ # `config.status --recheck' to rerun these tests and create the ++ # libtool script then. ++ ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` ++ if test -f "$ltmain_in"; then ++ test -f Makefile && make "$ltmain" ++ fi ++fi ++ ++ ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++CC="$lt_save_CC" ++ ++ ;; ++ ++ *) ++ { { echo "$as_me:$LINENO: error: Unsupported tag name: $tagname" >&5 ++echo "$as_me: error: Unsupported tag name: $tagname" >&2;} ++ { (exit 1); exit 1; }; } ++ ;; ++ esac ++ ++ # Append the new tag name to the list of available tags. ++ if test -n "$tagname" ; then ++ available_tags="$available_tags $tagname" ++ fi ++ fi ++ done ++ IFS="$lt_save_ifs" ++ ++ # Now substitute the updated list of available tags. ++ if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then ++ mv "${ofile}T" "$ofile" ++ chmod +x "$ofile" ++ else ++ rm -f "${ofile}T" ++ { { echo "$as_me:$LINENO: error: unable to update list of available tagged configurations." >&5 ++echo "$as_me: error: unable to update list of available tagged configurations." >&2;} ++ { (exit 1); exit 1; }; } ++ fi ++fi ++ ++ ++ ++# This can be used to rebuild libtool when needed ++LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh" ++ ++# Always use our own libtool. ++LIBTOOL='$(SHELL) $(top_builddir)/libtool' ++ ++# Prevent multiple expansion ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++CFLAGS="-O2 -Wall" ++## check for --enable-debug first before checking CFLAGS before ++## so that we don't mix -O and -g ++# Check whether --enable-debug or --disable-debug was given. ++if test "${enable_debug+set}" = set; then ++ enableval="$enable_debug" ++ if eval "test x$enable_debug = xyes"; then ++ CFLAGS="${CFLAGS} -g -O0" ++ fi ++fi; ++ ++ ++if test x$debug = xtrue; then ++ DEBUG_TRUE= ++ DEBUG_FALSE='#' ++else ++ DEBUG_TRUE='#' ++ DEBUG_FALSE= ++fi ++ ++ ++ISCSID_VERSION_DEFAULT="871" ++ISCSID_VERSION=$ISCSID_VERSION_DEFAULT ++which iscsid 2>&1 > /dev/null ++if test $? -eq 0 ; then ++ ISCSID_VERSION=`iscsid -v | awk '{ print $3 }' | awk -F- '{ print $2 }'` ++ echo "Detected iscsid version $ISCSID_VERSION" ++fi ++ ++ ++# Check whether --with-iscsid-version or --without-iscsid-version was given. ++if test "${with_iscsid_version+set}" = set; then ++ withval="$with_iscsid_version" ++ ISCSID_VERSION=$withval ++fi; ++ ++echo "ISCSID_VERSION: $ISCSID_VERSION" ++CFLAGS="${CFLAGS} -DISCSID_VERSION=$ISCSID_VERSION" ++CFLAGS=${CFLAGS} ++ ++ ++ ac_config_commands="$ac_config_commands default" ++ ++ ++ ++ ++ ac_config_files="$ac_config_files 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" ++cat >confcache <<\_ACEOF ++# This file is a shell script that caches the results of configure ++# tests run on this system so they can be shared between configure ++# scripts and configure runs, see configure's option --config-cache. ++# It is not useful on other systems. If it contains results you don't ++# want to keep, you may remove or edit it. ++# ++# config.status only pays attention to the cache file if you give it ++# the --recheck option to rerun configure. ++# ++# `ac_cv_env_foo' variables (set or unset) will be overridden when ++# loading this file, other *unset* `ac_cv_foo' will be assigned the ++# following values. ++ ++_ACEOF ++ ++# The following way of writing the cache mishandles newlines in values, ++# but we know of no workaround that is simple, portable, and efficient. ++# So, don't put newlines in cache variables' values. ++# Ultrix sh set writes to stderr and can't be redirected directly, ++# and sets the high bit in the cache file unless we assign to the vars. ++{ ++ (set) 2>&1 | ++ case `(ac_space=' '; set | grep ac_space) 2>&1` in ++ *ac_space=\ *) ++ # `set' does not quote correctly, so add quotes (double-quote ++ # substitution turns \\\\ into \\, and sed turns \\ into \). ++ sed -n \ ++ "s/'/'\\\\''/g; ++ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ++ ;; ++ *) ++ # `set' quotes correctly as required by POSIX, so do not add quotes. ++ sed -n \ ++ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" ++ ;; ++ esac; ++} | ++ sed ' ++ t clear ++ : clear ++ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ ++ t end ++ /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ ++ : end' >>confcache ++if diff $cache_file confcache >/dev/null 2>&1; then :; else ++ if test -w $cache_file; then ++ test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" ++ cat confcache >$cache_file ++ else ++ echo "not updating unwritable cache $cache_file" ++ fi ++fi ++rm -f confcache ++ ++test "x$prefix" = xNONE && prefix=$ac_default_prefix ++# Let make expand exec_prefix. ++test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' ++ ++# VPATH may cause trouble with some makes, so we remove $(srcdir), ++# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and ++# trailing colons and then remove the whole line if VPATH becomes empty ++# (actually we leave an empty line to preserve line numbers). ++if test "x$srcdir" = x.; then ++ ac_vpsub='/^[ ]*VPATH[ ]*=/{ ++s/:*\$(srcdir):*/:/; ++s/:*\${srcdir}:*/:/; ++s/:*@srcdir@:*/:/; ++s/^\([^=]*=[ ]*\):*/\1/; ++s/:*$//; ++s/^[^=]*=[ ]*$//; ++}' ++fi ++ ++DEFS=-DHAVE_CONFIG_H ++ ++ac_libobjs= ++ac_ltlibobjs= ++for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue ++ # 1. Remove the extension, and $U if already installed. ++ ac_i=`echo "$ac_i" | ++ sed 's/\$U\././;s/\.o$//;s/\.obj$//'` ++ # 2. Add them. ++ ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" ++ ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' ++done ++LIBOBJS=$ac_libobjs ++ ++LTLIBOBJS=$ac_ltlibobjs ++ ++ ++if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then ++ { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined. ++Usually this means the macro was only invoked conditionally." >&5 ++echo "$as_me: error: conditional \"AMDEP\" was never defined. ++Usually this means the macro was only invoked conditionally." >&2;} ++ { (exit 1); exit 1; }; } ++fi ++if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then ++ { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. ++Usually this means the macro was only invoked conditionally." >&5 ++echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. ++Usually this means the macro was only invoked conditionally." >&2;} ++ { (exit 1); exit 1; }; } ++fi ++if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then ++ { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCXX\" was never defined. ++Usually this means the macro was only invoked conditionally." >&5 ++echo "$as_me: error: conditional \"am__fastdepCXX\" was never defined. ++Usually this means the macro was only invoked conditionally." >&2;} ++ { (exit 1); exit 1; }; } ++fi ++if test -z "${DEBUG_TRUE}" && test -z "${DEBUG_FALSE}"; then ++ { { echo "$as_me:$LINENO: error: conditional \"DEBUG\" was never defined. ++Usually this means the macro was only invoked conditionally." >&5 ++echo "$as_me: error: conditional \"DEBUG\" was never defined. ++Usually this means the macro was only invoked conditionally." >&2;} ++ { (exit 1); exit 1; }; } ++fi ++ ++: ${CONFIG_STATUS=./config.status} ++ac_clean_files_save=$ac_clean_files ++ac_clean_files="$ac_clean_files $CONFIG_STATUS" ++{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 ++echo "$as_me: creating $CONFIG_STATUS" >&6;} ++cat >$CONFIG_STATUS <<_ACEOF ++#! $SHELL ++# Generated by $as_me. ++# Run this file to recreate the current configuration. ++# Compiler output produced by configure, useful for debugging ++# configure, is in config.log if it exists. ++ ++debug=false ++ac_cs_recheck=false ++ac_cs_silent=false ++SHELL=\${CONFIG_SHELL-$SHELL} ++_ACEOF ++ ++cat >>$CONFIG_STATUS <<\_ACEOF ++## --------------------- ## ++## M4sh Initialization. ## ++## --------------------- ## ++ ++# Be Bourne compatible ++if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then ++ emulate sh ++ NULLCMD=: ++ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which ++ # is contrary to our usage. Disable this feature. ++ alias -g '${1+"$@"}'='"$@"' ++elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then ++ set -o posix ++fi ++DUALCASE=1; export DUALCASE # for MKS sh ++ ++# Support unset when possible. ++if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then ++ as_unset=unset ++else ++ as_unset=false ++fi ++ ++ ++# Work around bugs in pre-3.0 UWIN ksh. ++$as_unset ENV MAIL MAILPATH ++PS1='$ ' ++PS2='> ' ++PS4='+ ' ++ ++# NLS nuisances. ++for as_var in \ ++ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ ++ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ ++ LC_TELEPHONE LC_TIME ++do ++ if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then ++ eval $as_var=C; export $as_var ++ else ++ $as_unset $as_var ++ fi ++done ++ ++# Required to use basename. ++if expr a : '\(a\)' >/dev/null 2>&1; then ++ as_expr=expr ++else ++ as_expr=false ++fi ++ ++if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then ++ as_basename=basename ++else ++ as_basename=false ++fi ++ ++ ++# Name of the executable. ++as_me=`$as_basename "$0" || ++$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ ++ X"$0" : 'X\(//\)$' \| \ ++ X"$0" : 'X\(/\)$' \| \ ++ . : '\(.\)' 2>/dev/null || ++echo X/"$0" | ++ sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } ++ /^X\/\(\/\/\)$/{ s//\1/; q; } ++ /^X\/\(\/\).*/{ s//\1/; q; } ++ s/.*/./; q'` ++ ++ ++# PATH needs CR, and LINENO needs CR and PATH. ++# Avoid depending upon Character Ranges. ++as_cr_letters='abcdefghijklmnopqrstuvwxyz' ++as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' ++as_cr_Letters=$as_cr_letters$as_cr_LETTERS ++as_cr_digits='0123456789' ++as_cr_alnum=$as_cr_Letters$as_cr_digits ++ ++# The user is always right. ++if test "${PATH_SEPARATOR+set}" != set; then ++ echo "#! /bin/sh" >conf$$.sh ++ echo "exit 0" >>conf$$.sh ++ chmod +x conf$$.sh ++ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then ++ PATH_SEPARATOR=';' ++ else ++ PATH_SEPARATOR=: ++ fi ++ rm -f conf$$.sh ++fi ++ ++ ++ as_lineno_1=$LINENO ++ as_lineno_2=$LINENO ++ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` ++ test "x$as_lineno_1" != "x$as_lineno_2" && ++ test "x$as_lineno_3" = "x$as_lineno_2" || { ++ # Find who we are. Look in the path if we contain no path at all ++ # relative or not. ++ case $0 in ++ *[\\/]* ) as_myself=$0 ;; ++ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break ++done ++ ++ ;; ++ esac ++ # We did not find ourselves, most probably we were run as `sh COMMAND' ++ # in which case we are not to be found in the path. ++ if test "x$as_myself" = x; then ++ as_myself=$0 ++ fi ++ if test ! -f "$as_myself"; then ++ { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 ++echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} ++ { (exit 1); exit 1; }; } ++ fi ++ case $CONFIG_SHELL in ++ '') ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for as_base in sh bash ksh sh5; do ++ case $as_dir in ++ /*) ++ if ("$as_dir/$as_base" -c ' ++ as_lineno_1=$LINENO ++ as_lineno_2=$LINENO ++ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` ++ test "x$as_lineno_1" != "x$as_lineno_2" && ++ test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then ++ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } ++ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } ++ CONFIG_SHELL=$as_dir/$as_base ++ export CONFIG_SHELL ++ exec "$CONFIG_SHELL" "$0" ${1+"$@"} ++ fi;; ++ esac ++ done ++done ++;; ++ esac ++ ++ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO ++ # uniformly replaced by the line number. The first 'sed' inserts a ++ # line-number line before each line; the second 'sed' does the real ++ # work. The second script uses 'N' to pair each line-number line ++ # with the numbered line, and appends trailing '-' during ++ # substitution so that $LINENO is not a special case at line end. ++ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the ++ # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) ++ sed '=' <$as_myself | ++ sed ' ++ N ++ s,$,-, ++ : loop ++ s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, ++ t loop ++ s,-$,, ++ s,^['$as_cr_digits']*\n,, ++ ' >$as_me.lineno && ++ chmod +x $as_me.lineno || ++ { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 ++echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} ++ { (exit 1); exit 1; }; } ++ ++ # Don't try to exec as it changes $[0], causing all sort of problems ++ # (the dirname of $[0] is not the place where we might find the ++ # original and so on. Autoconf is especially sensible to this). ++ . ./$as_me.lineno ++ # Exit status is that of the last command. ++ exit ++} ++ ++ ++case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in ++ *c*,-n*) ECHO_N= ECHO_C=' ++' ECHO_T=' ' ;; ++ *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; ++ *) ECHO_N= ECHO_C='\c' ECHO_T= ;; ++esac ++ ++if expr a : '\(a\)' >/dev/null 2>&1; then ++ as_expr=expr ++else ++ as_expr=false ++fi ++ ++rm -f conf$$ conf$$.exe conf$$.file ++echo >conf$$.file ++if ln -s conf$$.file conf$$ 2>/dev/null; then ++ # We could just check for DJGPP; but this test a) works b) is more generic ++ # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). ++ if test -f conf$$.exe; then ++ # Don't use ln at all; we don't have any links ++ as_ln_s='cp -p' ++ else ++ as_ln_s='ln -s' ++ fi ++elif ln conf$$.file conf$$ 2>/dev/null; then ++ as_ln_s=ln ++else ++ as_ln_s='cp -p' ++fi ++rm -f conf$$ conf$$.exe conf$$.file ++ ++if mkdir -p . 2>/dev/null; then ++ as_mkdir_p=: ++else ++ test -d ./-p && rmdir ./-p ++ as_mkdir_p=false ++fi ++ ++as_executable_p="test -f" ++ ++# Sed expression to map a string onto a valid CPP name. ++as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" ++ ++# Sed expression to map a string onto a valid variable name. ++as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" ++ ++ ++# IFS ++# We need space, tab and new line, in precisely that order. ++as_nl=' ++' ++IFS=" $as_nl" ++ ++# CDPATH. ++$as_unset CDPATH ++ ++exec 6>&1 ++ ++# Open the log real soon, to keep \$[0] and so on meaningful, and to ++# report actual input values of CONFIG_FILES etc. instead of their ++# values after options handling. Logging --version etc. is OK. ++exec 5>>config.log ++{ ++ echo ++ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ++## Running $as_me. ## ++_ASBOX ++} >&5 ++cat >&5 <<_CSEOF ++ ++This file was extended by iscsiuio $as_me 0.7.2.1, which was ++generated by GNU Autoconf 2.59. Invocation command line was ++ ++ CONFIG_FILES = $CONFIG_FILES ++ CONFIG_HEADERS = $CONFIG_HEADERS ++ CONFIG_LINKS = $CONFIG_LINKS ++ CONFIG_COMMANDS = $CONFIG_COMMANDS ++ $ $0 $@ ++ ++_CSEOF ++echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 ++echo >&5 ++_ACEOF ++ ++# Files that config.status was made for. ++if test -n "$ac_config_files"; then ++ echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS ++fi ++ ++if test -n "$ac_config_headers"; then ++ echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS ++fi ++ ++if test -n "$ac_config_links"; then ++ echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS ++fi ++ ++if test -n "$ac_config_commands"; then ++ echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS ++fi ++ ++cat >>$CONFIG_STATUS <<\_ACEOF ++ ++ac_cs_usage="\ ++\`$as_me' instantiates files from templates according to the ++current configuration. ++ ++Usage: $0 [OPTIONS] [FILE]... ++ ++ -h, --help print this help, then exit ++ -V, --version print version number, then exit ++ -q, --quiet do not print progress messages ++ -d, --debug don't remove temporary files ++ --recheck update $as_me by reconfiguring in the same conditions ++ --file=FILE[:TEMPLATE] ++ instantiate the configuration file FILE ++ --header=FILE[:TEMPLATE] ++ instantiate the configuration header FILE ++ ++Configuration files: ++$config_files ++ ++Configuration headers: ++$config_headers ++ ++Configuration commands: ++$config_commands ++ ++Report bugs to ." ++_ACEOF ++ ++cat >>$CONFIG_STATUS <<_ACEOF ++ac_cs_version="\\ ++iscsiuio config.status 0.7.2.1 ++configured by $0, generated by GNU Autoconf 2.59, ++ with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" ++ ++Copyright (C) 2003 Free Software Foundation, Inc. ++This config.status script is free software; the Free Software Foundation ++gives unlimited permission to copy, distribute and modify it." ++srcdir=$srcdir ++INSTALL="$INSTALL" ++_ACEOF ++ ++cat >>$CONFIG_STATUS <<\_ACEOF ++# If no file are specified by the user, then we need to provide default ++# value. By we need to know if files were specified by the user. ++ac_need_defaults=: ++while test $# != 0 ++do ++ case $1 in ++ --*=*) ++ ac_option=`expr "x$1" : 'x\([^=]*\)='` ++ ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` ++ ac_shift=: ++ ;; ++ -*) ++ ac_option=$1 ++ ac_optarg=$2 ++ ac_shift=shift ++ ;; ++ *) # This is not an option, so the user has probably given explicit ++ # arguments. ++ ac_option=$1 ++ ac_need_defaults=false;; ++ esac ++ ++ case $ac_option in ++ # Handling of the options. ++_ACEOF ++cat >>$CONFIG_STATUS <<\_ACEOF ++ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ++ ac_cs_recheck=: ;; ++ --version | --vers* | -V ) ++ echo "$ac_cs_version"; exit 0 ;; ++ --he | --h) ++ # Conflict between --help and --header ++ { { echo "$as_me:$LINENO: error: ambiguous option: $1 ++Try \`$0 --help' for more information." >&5 ++echo "$as_me: error: ambiguous option: $1 ++Try \`$0 --help' for more information." >&2;} ++ { (exit 1); exit 1; }; };; ++ --help | --hel | -h ) ++ echo "$ac_cs_usage"; exit 0 ;; ++ --debug | --d* | -d ) ++ debug=: ;; ++ --file | --fil | --fi | --f ) ++ $ac_shift ++ CONFIG_FILES="$CONFIG_FILES $ac_optarg" ++ ac_need_defaults=false;; ++ --header | --heade | --head | --hea ) ++ $ac_shift ++ CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" ++ ac_need_defaults=false;; ++ -q | -quiet | --quiet | --quie | --qui | --qu | --q \ ++ | -silent | --silent | --silen | --sile | --sil | --si | --s) ++ ac_cs_silent=: ;; ++ ++ # This is an error. ++ -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 ++Try \`$0 --help' for more information." >&5 ++echo "$as_me: error: unrecognized option: $1 ++Try \`$0 --help' for more information." >&2;} ++ { (exit 1); exit 1; }; } ;; ++ ++ *) ac_config_targets="$ac_config_targets $1" ;; ++ ++ esac ++ shift ++done ++ ++ac_configure_extra_args= ++ ++if $ac_cs_silent; then ++ exec 6>/dev/null ++ ac_configure_extra_args="$ac_configure_extra_args --silent" ++fi ++ ++_ACEOF ++cat >>$CONFIG_STATUS <<_ACEOF ++if \$ac_cs_recheck; then ++ echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 ++ exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion ++fi ++ ++_ACEOF ++ ++cat >>$CONFIG_STATUS <<_ACEOF ++# ++# INIT-COMMANDS section. ++# ++ ++AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" ++ ++ ++_ACEOF ++ ++ ++ ++cat >>$CONFIG_STATUS <<\_ACEOF ++for ac_config_target in $ac_config_targets ++do ++ case "$ac_config_target" in ++ # Handling of arguments. ++ "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; ++ "src/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; ++ "src/apps/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/apps/Makefile" ;; ++ "src/apps/dhcpc/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/apps/dhcpc/Makefile" ;; ++ "src/apps/brcm-iscsi/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/apps/brcm-iscsi/Makefile" ;; ++ "src/uip/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/uip/Makefile" ;; ++ "src/unix/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/unix/Makefile" ;; ++ "src/unix/libs/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/unix/libs/Makefile" ;; ++ "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; ++ "default" ) CONFIG_COMMANDS="$CONFIG_COMMANDS default" ;; ++ "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; ++ *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 ++echo "$as_me: error: invalid argument: $ac_config_target" >&2;} ++ { (exit 1); exit 1; }; };; ++ esac ++done ++ ++# If the user did not use the arguments to specify the items to instantiate, ++# then the envvar interface is used. Set only those that are not. ++# We use the long form for the default assignment because of an extremely ++# bizarre bug on SunOS 4.1.3. ++if $ac_need_defaults; then ++ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files ++ test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers ++ test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands ++fi ++ ++# Have a temporary directory for convenience. Make it in the build tree ++# simply because there is no reason to put it here, and in addition, ++# creating and moving files from /tmp can sometimes cause problems. ++# Create a temporary directory, and hook for its removal unless debugging. ++$debug || ++{ ++ trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 ++ trap '{ (exit 1); exit 1; }' 1 2 13 15 ++} ++ ++# Create a (secure) tmp directory for tmp files. ++ ++{ ++ tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && ++ test -n "$tmp" && test -d "$tmp" ++} || ++{ ++ tmp=./confstat$$-$RANDOM ++ (umask 077 && mkdir $tmp) ++} || ++{ ++ echo "$me: cannot create a temporary directory in ." >&2 ++ { (exit 1); exit 1; } ++} ++ ++_ACEOF ++ ++cat >>$CONFIG_STATUS <<_ACEOF ++ ++# ++# CONFIG_FILES section. ++# ++ ++# No need to generate the scripts if there are no CONFIG_FILES. ++# This happens for instance when ./config.status config.h ++if test -n "\$CONFIG_FILES"; then ++ # Protect against being on the right side of a sed subst in config.status. ++ sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; ++ s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF ++s,@SHELL@,$SHELL,;t t ++s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t ++s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t ++s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t ++s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t ++s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t ++s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t ++s,@exec_prefix@,$exec_prefix,;t t ++s,@prefix@,$prefix,;t t ++s,@program_transform_name@,$program_transform_name,;t t ++s,@bindir@,$bindir,;t t ++s,@sbindir@,$sbindir,;t t ++s,@libexecdir@,$libexecdir,;t t ++s,@datadir@,$datadir,;t t ++s,@sysconfdir@,$sysconfdir,;t t ++s,@sharedstatedir@,$sharedstatedir,;t t ++s,@localstatedir@,$localstatedir,;t t ++s,@libdir@,$libdir,;t t ++s,@includedir@,$includedir,;t t ++s,@oldincludedir@,$oldincludedir,;t t ++s,@infodir@,$infodir,;t t ++s,@mandir@,$mandir,;t t ++s,@build_alias@,$build_alias,;t t ++s,@host_alias@,$host_alias,;t t ++s,@target_alias@,$target_alias,;t t ++s,@DEFS@,$DEFS,;t t ++s,@ECHO_C@,$ECHO_C,;t t ++s,@ECHO_N@,$ECHO_N,;t t ++s,@ECHO_T@,$ECHO_T,;t t ++s,@LIBS@,$LIBS,;t t ++s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t ++s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t ++s,@INSTALL_DATA@,$INSTALL_DATA,;t t ++s,@CYGPATH_W@,$CYGPATH_W,;t t ++s,@PACKAGE@,$PACKAGE,;t t ++s,@VERSION@,$VERSION,;t t ++s,@ACLOCAL@,$ACLOCAL,;t t ++s,@AUTOCONF@,$AUTOCONF,;t t ++s,@AUTOMAKE@,$AUTOMAKE,;t t ++s,@AUTOHEADER@,$AUTOHEADER,;t t ++s,@MAKEINFO@,$MAKEINFO,;t t ++s,@install_sh@,$install_sh,;t t ++s,@STRIP@,$STRIP,;t t ++s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t ++s,@INSTALL_STRIP_PROGRAM@,$INSTALL_STRIP_PROGRAM,;t t ++s,@mkdir_p@,$mkdir_p,;t t ++s,@AWK@,$AWK,;t t ++s,@SET_MAKE@,$SET_MAKE,;t t ++s,@am__leading_dot@,$am__leading_dot,;t t ++s,@AMTAR@,$AMTAR,;t t ++s,@am__tar@,$am__tar,;t t ++s,@am__untar@,$am__untar,;t t ++s,@BASH@,$BASH,;t t ++s,@CC@,$CC,;t t ++s,@CFLAGS@,$CFLAGS,;t t ++s,@LDFLAGS@,$LDFLAGS,;t t ++s,@CPPFLAGS@,$CPPFLAGS,;t t ++s,@ac_ct_CC@,$ac_ct_CC,;t t ++s,@EXEEXT@,$EXEEXT,;t t ++s,@OBJEXT@,$OBJEXT,;t t ++s,@DEPDIR@,$DEPDIR,;t t ++s,@am__include@,$am__include,;t t ++s,@am__quote@,$am__quote,;t t ++s,@AMDEP_TRUE@,$AMDEP_TRUE,;t t ++s,@AMDEP_FALSE@,$AMDEP_FALSE,;t t ++s,@AMDEPBACKSLASH@,$AMDEPBACKSLASH,;t t ++s,@CCDEPMODE@,$CCDEPMODE,;t t ++s,@am__fastdepCC_TRUE@,$am__fastdepCC_TRUE,;t t ++s,@am__fastdepCC_FALSE@,$am__fastdepCC_FALSE,;t t ++s,@RANLIB@,$RANLIB,;t t ++s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t ++s,@CPP@,$CPP,;t t ++s,@EGREP@,$EGREP,;t t ++s,@ENDIAN@,$ENDIAN,;t t ++s,@build@,$build,;t t ++s,@build_cpu@,$build_cpu,;t t ++s,@build_vendor@,$build_vendor,;t t ++s,@build_os@,$build_os,;t t ++s,@host@,$host,;t t ++s,@host_cpu@,$host_cpu,;t t ++s,@host_vendor@,$host_vendor,;t t ++s,@host_os@,$host_os,;t t ++s,@SED@,$SED,;t t ++s,@LN_S@,$LN_S,;t t ++s,@ECHO@,$ECHO,;t t ++s,@AR@,$AR,;t t ++s,@ac_ct_AR@,$ac_ct_AR,;t t ++s,@CXX@,$CXX,;t t ++s,@CXXFLAGS@,$CXXFLAGS,;t t ++s,@ac_ct_CXX@,$ac_ct_CXX,;t t ++s,@CXXDEPMODE@,$CXXDEPMODE,;t t ++s,@am__fastdepCXX_TRUE@,$am__fastdepCXX_TRUE,;t t ++s,@am__fastdepCXX_FALSE@,$am__fastdepCXX_FALSE,;t t ++s,@CXXCPP@,$CXXCPP,;t t ++s,@F77@,$F77,;t t ++s,@FFLAGS@,$FFLAGS,;t t ++s,@ac_ct_F77@,$ac_ct_F77,;t t ++s,@LIBTOOL@,$LIBTOOL,;t t ++s,@DEBUG_TRUE@,$DEBUG_TRUE,;t t ++s,@DEBUG_FALSE@,$DEBUG_FALSE,;t t ++s,@LIBOBJS@,$LIBOBJS,;t t ++s,@LTLIBOBJS@,$LTLIBOBJS,;t t ++CEOF ++ ++_ACEOF ++ ++ cat >>$CONFIG_STATUS <<\_ACEOF ++ # Split the substitutions into bite-sized pieces for seds with ++ # small command number limits, like on Digital OSF/1 and HP-UX. ++ ac_max_sed_lines=48 ++ ac_sed_frag=1 # Number of current file. ++ ac_beg=1 # First line for current file. ++ ac_end=$ac_max_sed_lines # Line after last line for current file. ++ ac_more_lines=: ++ ac_sed_cmds= ++ while $ac_more_lines; do ++ if test $ac_beg -gt 1; then ++ sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag ++ else ++ sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag ++ fi ++ if test ! -s $tmp/subs.frag; then ++ ac_more_lines=false ++ else ++ # The purpose of the label and of the branching condition is to ++ # speed up the sed processing (if there are no `@' at all, there ++ # is no need to browse any of the substitutions). ++ # These are the two extra sed commands mentioned above. ++ (echo ':t ++ /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed ++ if test -z "$ac_sed_cmds"; then ++ ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" ++ else ++ ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" ++ fi ++ ac_sed_frag=`expr $ac_sed_frag + 1` ++ ac_beg=$ac_end ++ ac_end=`expr $ac_end + $ac_max_sed_lines` ++ fi ++ done ++ if test -z "$ac_sed_cmds"; then ++ ac_sed_cmds=cat ++ fi ++fi # test -n "$CONFIG_FILES" ++ ++_ACEOF ++cat >>$CONFIG_STATUS <<\_ACEOF ++for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue ++ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". ++ case $ac_file in ++ - | *:- | *:-:* ) # input from stdin ++ cat >$tmp/stdin ++ ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ++ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; ++ *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ++ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; ++ * ) ac_file_in=$ac_file.in ;; ++ esac ++ ++ # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. ++ ac_dir=`(dirname "$ac_file") 2>/dev/null || ++$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ ++ X"$ac_file" : 'X\(//\)[^/]' \| \ ++ X"$ac_file" : 'X\(//\)$' \| \ ++ X"$ac_file" : 'X\(/\)' \| \ ++ . : '\(.\)' 2>/dev/null || ++echo X"$ac_file" | ++ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } ++ /^X\(\/\/\)[^/].*/{ s//\1/; q; } ++ /^X\(\/\/\)$/{ s//\1/; q; } ++ /^X\(\/\).*/{ s//\1/; q; } ++ s/.*/./; q'` ++ { if $as_mkdir_p; then ++ mkdir -p "$ac_dir" ++ else ++ as_dir="$ac_dir" ++ as_dirs= ++ while test ! -d "$as_dir"; do ++ as_dirs="$as_dir $as_dirs" ++ as_dir=`(dirname "$as_dir") 2>/dev/null || ++$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ ++ X"$as_dir" : 'X\(//\)[^/]' \| \ ++ X"$as_dir" : 'X\(//\)$' \| \ ++ X"$as_dir" : 'X\(/\)' \| \ ++ . : '\(.\)' 2>/dev/null || ++echo X"$as_dir" | ++ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } ++ /^X\(\/\/\)[^/].*/{ s//\1/; q; } ++ /^X\(\/\/\)$/{ s//\1/; q; } ++ /^X\(\/\).*/{ s//\1/; q; } ++ s/.*/./; q'` ++ done ++ test ! -n "$as_dirs" || mkdir $as_dirs ++ fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 ++echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} ++ { (exit 1); exit 1; }; }; } ++ ++ ac_builddir=. ++ ++if test "$ac_dir" != .; then ++ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` ++ # A "../" for each directory in $ac_dir_suffix. ++ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` ++else ++ ac_dir_suffix= ac_top_builddir= ++fi ++ ++case $srcdir in ++ .) # No --srcdir option. We are building in place. ++ ac_srcdir=. ++ if test -z "$ac_top_builddir"; then ++ ac_top_srcdir=. ++ else ++ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` ++ fi ;; ++ [\\/]* | ?:[\\/]* ) # Absolute path. ++ ac_srcdir=$srcdir$ac_dir_suffix; ++ ac_top_srcdir=$srcdir ;; ++ *) # Relative path. ++ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ++ ac_top_srcdir=$ac_top_builddir$srcdir ;; ++esac ++ ++# Do not use `cd foo && pwd` to compute absolute paths, because ++# the directories may not exist. ++case `pwd` in ++.) ac_abs_builddir="$ac_dir";; ++*) ++ case "$ac_dir" in ++ .) ac_abs_builddir=`pwd`;; ++ [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; ++ *) ac_abs_builddir=`pwd`/"$ac_dir";; ++ esac;; ++esac ++case $ac_abs_builddir in ++.) ac_abs_top_builddir=${ac_top_builddir}.;; ++*) ++ case ${ac_top_builddir}. in ++ .) ac_abs_top_builddir=$ac_abs_builddir;; ++ [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; ++ *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; ++ esac;; ++esac ++case $ac_abs_builddir in ++.) ac_abs_srcdir=$ac_srcdir;; ++*) ++ case $ac_srcdir in ++ .) ac_abs_srcdir=$ac_abs_builddir;; ++ [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; ++ *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; ++ esac;; ++esac ++case $ac_abs_builddir in ++.) ac_abs_top_srcdir=$ac_top_srcdir;; ++*) ++ case $ac_top_srcdir in ++ .) ac_abs_top_srcdir=$ac_abs_builddir;; ++ [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; ++ *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; ++ esac;; ++esac ++ ++ ++ case $INSTALL in ++ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; ++ *) ac_INSTALL=$ac_top_builddir$INSTALL ;; ++ esac ++ ++ if test x"$ac_file" != x-; then ++ { echo "$as_me:$LINENO: creating $ac_file" >&5 ++echo "$as_me: creating $ac_file" >&6;} ++ rm -f "$ac_file" ++ fi ++ # Let's still pretend it is `configure' which instantiates (i.e., don't ++ # use $as_me), people would be surprised to read: ++ # /* config.h. Generated by config.status. */ ++ if test x"$ac_file" = x-; then ++ configure_input= ++ else ++ configure_input="$ac_file. " ++ fi ++ configure_input=$configure_input"Generated from `echo $ac_file_in | ++ sed 's,.*/,,'` by configure." ++ ++ # First look for the input files in the build tree, otherwise in the ++ # src tree. ++ ac_file_inputs=`IFS=: ++ for f in $ac_file_in; do ++ case $f in ++ -) echo $tmp/stdin ;; ++ [\\/$]*) ++ # Absolute (can't be DOS-style, as IFS=:) ++ test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 ++echo "$as_me: error: cannot find input file: $f" >&2;} ++ { (exit 1); exit 1; }; } ++ echo "$f";; ++ *) # Relative ++ if test -f "$f"; then ++ # Build tree ++ echo "$f" ++ elif test -f "$srcdir/$f"; then ++ # Source tree ++ echo "$srcdir/$f" ++ else ++ # /dev/null tree ++ { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 ++echo "$as_me: error: cannot find input file: $f" >&2;} ++ { (exit 1); exit 1; }; } ++ fi;; ++ esac ++ done` || { (exit 1); exit 1; } ++_ACEOF ++cat >>$CONFIG_STATUS <<_ACEOF ++ sed "$ac_vpsub ++$extrasub ++_ACEOF ++cat >>$CONFIG_STATUS <<\_ACEOF ++:t ++/@[a-zA-Z_][a-zA-Z_0-9]*@/!b ++s,@configure_input@,$configure_input,;t t ++s,@srcdir@,$ac_srcdir,;t t ++s,@abs_srcdir@,$ac_abs_srcdir,;t t ++s,@top_srcdir@,$ac_top_srcdir,;t t ++s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t ++s,@builddir@,$ac_builddir,;t t ++s,@abs_builddir@,$ac_abs_builddir,;t t ++s,@top_builddir@,$ac_top_builddir,;t t ++s,@abs_top_builddir@,$ac_abs_top_builddir,;t t ++s,@INSTALL@,$ac_INSTALL,;t t ++" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out ++ rm -f $tmp/stdin ++ if test x"$ac_file" != x-; then ++ mv $tmp/out $ac_file ++ else ++ cat $tmp/out ++ rm -f $tmp/out ++ fi ++ ++done ++_ACEOF ++cat >>$CONFIG_STATUS <<\_ACEOF ++ ++# ++# CONFIG_HEADER section. ++# ++ ++# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where ++# NAME is the cpp macro being defined and VALUE is the value it is being given. ++# ++# ac_d sets the value in "#define NAME VALUE" lines. ++ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)' ++ac_dB='[ ].*$,\1#\2' ++ac_dC=' ' ++ac_dD=',;t' ++# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE". ++ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ++ac_uB='$,\1#\2define\3' ++ac_uC=' ' ++ac_uD=',;t' ++ ++for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue ++ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". ++ case $ac_file in ++ - | *:- | *:-:* ) # input from stdin ++ cat >$tmp/stdin ++ ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ++ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; ++ *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ++ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; ++ * ) ac_file_in=$ac_file.in ;; ++ esac ++ ++ test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5 ++echo "$as_me: creating $ac_file" >&6;} ++ ++ # First look for the input files in the build tree, otherwise in the ++ # src tree. ++ ac_file_inputs=`IFS=: ++ for f in $ac_file_in; do ++ case $f in ++ -) echo $tmp/stdin ;; ++ [\\/$]*) ++ # Absolute (can't be DOS-style, as IFS=:) ++ test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 ++echo "$as_me: error: cannot find input file: $f" >&2;} ++ { (exit 1); exit 1; }; } ++ # Do quote $f, to prevent DOS paths from being IFS'd. ++ echo "$f";; ++ *) # Relative ++ if test -f "$f"; then ++ # Build tree ++ echo "$f" ++ elif test -f "$srcdir/$f"; then ++ # Source tree ++ echo "$srcdir/$f" ++ else ++ # /dev/null tree ++ { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 ++echo "$as_me: error: cannot find input file: $f" >&2;} ++ { (exit 1); exit 1; }; } ++ fi;; ++ esac ++ done` || { (exit 1); exit 1; } ++ # Remove the trailing spaces. ++ sed 's/[ ]*$//' $ac_file_inputs >$tmp/in ++ ++_ACEOF ++ ++# Transform confdefs.h into two sed scripts, `conftest.defines' and ++# `conftest.undefs', that substitutes the proper values into ++# config.h.in to produce config.h. The first handles `#define' ++# templates, and the second `#undef' templates. ++# And first: Protect against being on the right side of a sed subst in ++# config.status. Protect against being in an unquoted here document ++# in config.status. ++rm -f conftest.defines conftest.undefs ++# Using a here document instead of a string reduces the quoting nightmare. ++# Putting comments in sed scripts is not portable. ++# ++# `end' is used to avoid that the second main sed command (meant for ++# 0-ary CPP macros) applies to n-ary macro definitions. ++# See the Autoconf documentation for `clear'. ++cat >confdef2sed.sed <<\_ACEOF ++s/[\\&,]/\\&/g ++s,[\\$`],\\&,g ++t clear ++: clear ++s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp ++t end ++s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp ++: end ++_ACEOF ++# If some macros were called several times there might be several times ++# the same #defines, which is useless. Nevertheless, we may not want to ++# sort them, since we want the *last* AC-DEFINE to be honored. ++uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines ++sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs ++rm -f confdef2sed.sed ++ ++# This sed command replaces #undef with comments. This is necessary, for ++# example, in the case of _POSIX_SOURCE, which is predefined and required ++# on some systems where configure will not decide to define it. ++cat >>conftest.undefs <<\_ACEOF ++s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */, ++_ACEOF ++ ++# Break up conftest.defines because some shells have a limit on the size ++# of here documents, and old seds have small limits too (100 cmds). ++echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS ++echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS ++echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS ++echo ' :' >>$CONFIG_STATUS ++rm -f conftest.tail ++while grep . conftest.defines >/dev/null ++do ++ # Write a limited-size here document to $tmp/defines.sed. ++ echo ' cat >$tmp/defines.sed <>$CONFIG_STATUS ++ # Speed up: don't consider the non `#define' lines. ++ echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS ++ # Work around the forget-to-reset-the-flag bug. ++ echo 't clr' >>$CONFIG_STATUS ++ echo ': clr' >>$CONFIG_STATUS ++ sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS ++ echo 'CEOF ++ sed -f $tmp/defines.sed $tmp/in >$tmp/out ++ rm -f $tmp/in ++ mv $tmp/out $tmp/in ++' >>$CONFIG_STATUS ++ sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail ++ rm -f conftest.defines ++ mv conftest.tail conftest.defines ++done ++rm -f conftest.defines ++echo ' fi # grep' >>$CONFIG_STATUS ++echo >>$CONFIG_STATUS ++ ++# Break up conftest.undefs because some shells have a limit on the size ++# of here documents, and old seds have small limits too (100 cmds). ++echo ' # Handle all the #undef templates' >>$CONFIG_STATUS ++rm -f conftest.tail ++while grep . conftest.undefs >/dev/null ++do ++ # Write a limited-size here document to $tmp/undefs.sed. ++ echo ' cat >$tmp/undefs.sed <>$CONFIG_STATUS ++ # Speed up: don't consider the non `#undef' ++ echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS ++ # Work around the forget-to-reset-the-flag bug. ++ echo 't clr' >>$CONFIG_STATUS ++ echo ': clr' >>$CONFIG_STATUS ++ sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS ++ echo 'CEOF ++ sed -f $tmp/undefs.sed $tmp/in >$tmp/out ++ rm -f $tmp/in ++ mv $tmp/out $tmp/in ++' >>$CONFIG_STATUS ++ sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail ++ rm -f conftest.undefs ++ mv conftest.tail conftest.undefs ++done ++rm -f conftest.undefs ++ ++cat >>$CONFIG_STATUS <<\_ACEOF ++ # Let's still pretend it is `configure' which instantiates (i.e., don't ++ # use $as_me), people would be surprised to read: ++ # /* config.h. Generated by config.status. */ ++ if test x"$ac_file" = x-; then ++ echo "/* Generated by configure. */" >$tmp/config.h ++ else ++ echo "/* $ac_file. Generated by configure. */" >$tmp/config.h ++ fi ++ cat $tmp/in >>$tmp/config.h ++ rm -f $tmp/in ++ if test x"$ac_file" != x-; then ++ if diff $ac_file $tmp/config.h >/dev/null 2>&1; then ++ { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 ++echo "$as_me: $ac_file is unchanged" >&6;} ++ else ++ ac_dir=`(dirname "$ac_file") 2>/dev/null || ++$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ ++ X"$ac_file" : 'X\(//\)[^/]' \| \ ++ X"$ac_file" : 'X\(//\)$' \| \ ++ X"$ac_file" : 'X\(/\)' \| \ ++ . : '\(.\)' 2>/dev/null || ++echo X"$ac_file" | ++ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } ++ /^X\(\/\/\)[^/].*/{ s//\1/; q; } ++ /^X\(\/\/\)$/{ s//\1/; q; } ++ /^X\(\/\).*/{ s//\1/; q; } ++ s/.*/./; q'` ++ { if $as_mkdir_p; then ++ mkdir -p "$ac_dir" ++ else ++ as_dir="$ac_dir" ++ as_dirs= ++ while test ! -d "$as_dir"; do ++ as_dirs="$as_dir $as_dirs" ++ as_dir=`(dirname "$as_dir") 2>/dev/null || ++$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ ++ X"$as_dir" : 'X\(//\)[^/]' \| \ ++ X"$as_dir" : 'X\(//\)$' \| \ ++ X"$as_dir" : 'X\(/\)' \| \ ++ . : '\(.\)' 2>/dev/null || ++echo X"$as_dir" | ++ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } ++ /^X\(\/\/\)[^/].*/{ s//\1/; q; } ++ /^X\(\/\/\)$/{ s//\1/; q; } ++ /^X\(\/\).*/{ s//\1/; q; } ++ s/.*/./; q'` ++ done ++ test ! -n "$as_dirs" || mkdir $as_dirs ++ fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 ++echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} ++ { (exit 1); exit 1; }; }; } ++ ++ rm -f $ac_file ++ mv $tmp/config.h $ac_file ++ fi ++ else ++ cat $tmp/config.h ++ rm -f $tmp/config.h ++ fi ++# Compute $ac_file's index in $config_headers. ++_am_stamp_count=1 ++for _am_header in $config_headers :; do ++ case $_am_header in ++ $ac_file | $ac_file:* ) ++ break ;; ++ * ) ++ _am_stamp_count=`expr $_am_stamp_count + 1` ;; ++ esac ++done ++echo "timestamp for $ac_file" >`(dirname $ac_file) 2>/dev/null || ++$as_expr X$ac_file : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ ++ X$ac_file : 'X\(//\)[^/]' \| \ ++ X$ac_file : 'X\(//\)$' \| \ ++ X$ac_file : 'X\(/\)' \| \ ++ . : '\(.\)' 2>/dev/null || ++echo X$ac_file | ++ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } ++ /^X\(\/\/\)[^/].*/{ s//\1/; q; } ++ /^X\(\/\/\)$/{ s//\1/; q; } ++ /^X\(\/\).*/{ s//\1/; q; } ++ s/.*/./; q'`/stamp-h$_am_stamp_count ++done ++_ACEOF ++cat >>$CONFIG_STATUS <<\_ACEOF ++ ++# ++# CONFIG_COMMANDS section. ++# ++for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue ++ ac_dest=`echo "$ac_file" | sed 's,:.*,,'` ++ ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'` ++ ac_dir=`(dirname "$ac_dest") 2>/dev/null || ++$as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ ++ X"$ac_dest" : 'X\(//\)[^/]' \| \ ++ X"$ac_dest" : 'X\(//\)$' \| \ ++ X"$ac_dest" : 'X\(/\)' \| \ ++ . : '\(.\)' 2>/dev/null || ++echo X"$ac_dest" | ++ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } ++ /^X\(\/\/\)[^/].*/{ s//\1/; q; } ++ /^X\(\/\/\)$/{ s//\1/; q; } ++ /^X\(\/\).*/{ s//\1/; q; } ++ s/.*/./; q'` ++ { if $as_mkdir_p; then ++ mkdir -p "$ac_dir" ++ else ++ as_dir="$ac_dir" ++ as_dirs= ++ while test ! -d "$as_dir"; do ++ as_dirs="$as_dir $as_dirs" ++ as_dir=`(dirname "$as_dir") 2>/dev/null || ++$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ ++ X"$as_dir" : 'X\(//\)[^/]' \| \ ++ X"$as_dir" : 'X\(//\)$' \| \ ++ X"$as_dir" : 'X\(/\)' \| \ ++ . : '\(.\)' 2>/dev/null || ++echo X"$as_dir" | ++ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } ++ /^X\(\/\/\)[^/].*/{ s//\1/; q; } ++ /^X\(\/\/\)$/{ s//\1/; q; } ++ /^X\(\/\).*/{ s//\1/; q; } ++ s/.*/./; q'` ++ done ++ test ! -n "$as_dirs" || mkdir $as_dirs ++ fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 ++echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} ++ { (exit 1); exit 1; }; }; } ++ ++ ac_builddir=. ++ ++if test "$ac_dir" != .; then ++ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` ++ # A "../" for each directory in $ac_dir_suffix. ++ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` ++else ++ ac_dir_suffix= ac_top_builddir= ++fi ++ ++case $srcdir in ++ .) # No --srcdir option. We are building in place. ++ ac_srcdir=. ++ if test -z "$ac_top_builddir"; then ++ ac_top_srcdir=. ++ else ++ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` ++ fi ;; ++ [\\/]* | ?:[\\/]* ) # Absolute path. ++ ac_srcdir=$srcdir$ac_dir_suffix; ++ ac_top_srcdir=$srcdir ;; ++ *) # Relative path. ++ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ++ ac_top_srcdir=$ac_top_builddir$srcdir ;; ++esac ++ ++# Do not use `cd foo && pwd` to compute absolute paths, because ++# the directories may not exist. ++case `pwd` in ++.) ac_abs_builddir="$ac_dir";; ++*) ++ case "$ac_dir" in ++ .) ac_abs_builddir=`pwd`;; ++ [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; ++ *) ac_abs_builddir=`pwd`/"$ac_dir";; ++ esac;; ++esac ++case $ac_abs_builddir in ++.) ac_abs_top_builddir=${ac_top_builddir}.;; ++*) ++ case ${ac_top_builddir}. in ++ .) ac_abs_top_builddir=$ac_abs_builddir;; ++ [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; ++ *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; ++ esac;; ++esac ++case $ac_abs_builddir in ++.) ac_abs_srcdir=$ac_srcdir;; ++*) ++ case $ac_srcdir in ++ .) ac_abs_srcdir=$ac_abs_builddir;; ++ [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; ++ *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; ++ esac;; ++esac ++case $ac_abs_builddir in ++.) ac_abs_top_srcdir=$ac_top_srcdir;; ++*) ++ case $ac_top_srcdir in ++ .) ac_abs_top_srcdir=$ac_abs_builddir;; ++ [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; ++ *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; ++ esac;; ++esac ++ ++ ++ { echo "$as_me:$LINENO: executing $ac_dest commands" >&5 ++echo "$as_me: executing $ac_dest commands" >&6;} ++ case $ac_dest in ++ depfiles ) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do ++ # Strip MF so we end up with the name of the file. ++ mf=`echo "$mf" | sed -e 's/:.*$//'` ++ # Check whether this is an Automake generated Makefile or not. ++ # We used to match only the files named `Makefile.in', but ++ # some people rename them; so instead we look at the file content. ++ # Grep'ing the first line is not enough: some people post-process ++ # each Makefile.in and add a new line on top of each file to say so. ++ # So let's grep whole file. ++ if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then ++ dirpart=`(dirname "$mf") 2>/dev/null || ++$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ ++ X"$mf" : 'X\(//\)[^/]' \| \ ++ X"$mf" : 'X\(//\)$' \| \ ++ X"$mf" : 'X\(/\)' \| \ ++ . : '\(.\)' 2>/dev/null || ++echo X"$mf" | ++ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } ++ /^X\(\/\/\)[^/].*/{ s//\1/; q; } ++ /^X\(\/\/\)$/{ s//\1/; q; } ++ /^X\(\/\).*/{ s//\1/; q; } ++ s/.*/./; q'` ++ else ++ continue ++ fi ++ # Extract the definition of DEPDIR, am__include, and am__quote ++ # from the Makefile without running `make'. ++ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` ++ test -z "$DEPDIR" && continue ++ am__include=`sed -n 's/^am__include = //p' < "$mf"` ++ test -z "am__include" && continue ++ am__quote=`sed -n 's/^am__quote = //p' < "$mf"` ++ # When using ansi2knr, U may be empty or an underscore; expand it ++ U=`sed -n 's/^U = //p' < "$mf"` ++ # Find all dependency output files, they are included files with ++ # $(DEPDIR) in their names. We invoke sed twice because it is the ++ # simplest approach to changing $(DEPDIR) to its actual value in the ++ # expansion. ++ for file in `sed -n " ++ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ ++ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do ++ # Make sure the directory exists. ++ test -f "$dirpart/$file" && continue ++ fdir=`(dirname "$file") 2>/dev/null || ++$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ ++ X"$file" : 'X\(//\)[^/]' \| \ ++ X"$file" : 'X\(//\)$' \| \ ++ X"$file" : 'X\(/\)' \| \ ++ . : '\(.\)' 2>/dev/null || ++echo X"$file" | ++ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } ++ /^X\(\/\/\)[^/].*/{ s//\1/; q; } ++ /^X\(\/\/\)$/{ s//\1/; q; } ++ /^X\(\/\).*/{ s//\1/; q; } ++ s/.*/./; q'` ++ { if $as_mkdir_p; then ++ mkdir -p $dirpart/$fdir ++ else ++ as_dir=$dirpart/$fdir ++ as_dirs= ++ while test ! -d "$as_dir"; do ++ as_dirs="$as_dir $as_dirs" ++ as_dir=`(dirname "$as_dir") 2>/dev/null || ++$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ ++ X"$as_dir" : 'X\(//\)[^/]' \| \ ++ X"$as_dir" : 'X\(//\)$' \| \ ++ X"$as_dir" : 'X\(/\)' \| \ ++ . : '\(.\)' 2>/dev/null || ++echo X"$as_dir" | ++ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } ++ /^X\(\/\/\)[^/].*/{ s//\1/; q; } ++ /^X\(\/\/\)$/{ s//\1/; q; } ++ /^X\(\/\).*/{ s//\1/; q; } ++ s/.*/./; q'` ++ done ++ test ! -n "$as_dirs" || mkdir $as_dirs ++ fi || { { echo "$as_me:$LINENO: error: cannot create directory $dirpart/$fdir" >&5 ++echo "$as_me: error: cannot create directory $dirpart/$fdir" >&2;} ++ { (exit 1); exit 1; }; }; } ++ ++ # echo "creating $dirpart/$file" ++ echo '# dummy' > "$dirpart/$file" ++ done ++done ++ ;; ++ default ) echo 'char *build_date ="'`date`'";' > src/unix/build_date.c && echo 'char *build_date; '> src/unix/build_date.h ;; ++ esac ++done ++_ACEOF ++ ++cat >>$CONFIG_STATUS <<\_ACEOF ++ ++{ (exit 0); exit 0; } ++_ACEOF ++chmod +x $CONFIG_STATUS ++ac_clean_files=$ac_clean_files_save ++ ++ ++# configure is writing to config.log, and then calls config.status. ++# config.status does its own redirection, appending to config.log. ++# Unfortunately, on DOS this fails, as config.log is still kept open ++# by configure, so config.status won't be able to write to it; its ++# output is simply discarded. So we exec the FD to /dev/null, ++# effectively closing config.log, so it can be properly (re)opened and ++# appended to by config.status. When coming back to configure, we ++# need to make the FD available again. ++if test "$no_create" != yes; then ++ ac_cs_success=: ++ ac_config_status_args= ++ test "$silent" = yes && ++ ac_config_status_args="$ac_config_status_args --quiet" ++ exec 5>/dev/null ++ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false ++ exec 5>>config.log ++ # Use ||, not &&, to avoid exiting from the if with $? = 1, which ++ # would make configure fail if this is the last instruction. ++ $ac_cs_success || { (exit 1); exit 1; } ++fi ++ +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/configure.ac open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/configure.ac +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/configure.ac 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/configure.ac 2012-04-09 21:52:14.000000000 -0500 +@@ -0,0 +1,92 @@ ++dnl iscsiuio uIP user space stack configure.ac file ++dnl ++dnl Copyright (c) 2004-2011 Broadcom Corporation ++dnl ++dnl This program is free software; you can redistribute it and/or modify ++dnl it under the terms of the GNU General Public License as published by ++dnl the Free Software Foundation. ++dnl ++dnl Written by: Benjamin Li (benli@broadcom.com) ++dnl Maintained by: Eddie Wai (eddie.wai@broadcom.com) ++dnl ++ ++PACKAGE=iscsiuio ++VERSION=0.7.2.1 ++ ++AC_INIT(iscsiuio, 0.7.2.1, eddie.wai@broadcom.com) ++ ++AM_INIT_AUTOMAKE($PACKAGE, $VERSION) ++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 -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]) ++ ++ISCSID_VERSION_DEFAULT="871" ++ISCSID_VERSION=$ISCSID_VERSION_DEFAULT ++which iscsid 2>&1 > /dev/null ++if [ test $? -eq 0 ]; then ++ ISCSID_VERSION=`iscsid -v | awk '{ print $3 }' | awk -F- '{ print $2 }'` ++ echo "Detected iscsid version $ISCSID_VERSION" ++fi ++ ++AC_ARG_WITH(iscsid-version, ++[ --with-iscsid-version Compile against a certain version of iscsid (default="$ISCSID_VERSION_DEFAULT")], ++ ISCSID_VERSION=$withval) ++ ++echo "ISCSID_VERSION: $ISCSID_VERSION" ++CFLAGS="${CFLAGS} -DISCSID_VERSION=$ISCSID_VERSION" ++AC_SUBST(CFLAGS, ${CFLAGS}) ++ ++AC_CONFIG_COMMANDS([default],[[ echo 'char *build_date ="'`date`'";' > src/unix/build_date.c && echo '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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/COPYING open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/COPYING +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/COPYING 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/COPYING 2012-04-09 21:52:14.000000000 -0500 +@@ -0,0 +1,674 @@ ++ GNU GENERAL PUBLIC LICENSE ++ Version 3, 29 June 2007 ++ ++ Copyright (C) 2007 Free Software Foundation, Inc. ++ Everyone is permitted to copy and distribute verbatim copies ++ of this license document, but changing it is not allowed. ++ ++ Preamble ++ ++ The GNU General Public License is a free, copyleft license for ++software and other kinds of works. ++ ++ The licenses for most software and other practical works are designed ++to take away your freedom to share and change the works. By contrast, ++the GNU General Public License is intended to guarantee your freedom to ++share and change all versions of a program--to make sure it remains free ++software for all its users. We, the Free Software Foundation, use the ++GNU General Public License for most of our software; it applies also to ++any other work released this way by its authors. You can apply it to ++your programs, too. ++ ++ When we speak of free software, we are referring to freedom, not ++price. Our General Public Licenses are designed to make sure that you ++have the freedom to distribute copies of free software (and charge for ++them if you wish), that you receive source code or can get it if you ++want it, that you can change the software or use pieces of it in new ++free programs, and that you know you can do these things. ++ ++ To protect your rights, we need to prevent others from denying you ++these rights or asking you to surrender the rights. Therefore, you have ++certain responsibilities if you distribute copies of the software, or if ++you modify it: responsibilities to respect the freedom of others. ++ ++ For example, if you distribute copies of such a program, whether ++gratis or for a fee, you must pass on to the recipients the same ++freedoms that you received. You must make sure that they, too, receive ++or can get the source code. And you must show them these terms so they ++know their rights. ++ ++ Developers that use the GNU GPL protect your rights with two steps: ++(1) assert copyright on the software, and (2) offer you this License ++giving you legal permission to copy, distribute and/or modify it. ++ ++ For the developers' and authors' protection, the GPL clearly explains ++that there is no warranty for this free software. For both users' and ++authors' sake, the GPL requires that modified versions be marked as ++changed, so that their problems will not be attributed erroneously to ++authors of previous versions. ++ ++ Some devices are designed to deny users access to install or run ++modified versions of the software inside them, although the manufacturer ++can do so. This is fundamentally incompatible with the aim of ++protecting users' freedom to change the software. The systematic ++pattern of such abuse occurs in the area of products for individuals to ++use, which is precisely where it is most unacceptable. Therefore, we ++have designed this version of the GPL to prohibit the practice for those ++products. If such problems arise substantially in other domains, we ++stand ready to extend this provision to those domains in future versions ++of the GPL, as needed to protect the freedom of users. ++ ++ Finally, every program is threatened constantly by software patents. ++States should not allow patents to restrict development and use of ++software on general-purpose computers, but in those that do, we wish to ++avoid the special danger that patents applied to a free program could ++make it effectively proprietary. To prevent this, the GPL assures that ++patents cannot be used to render the program non-free. ++ ++ The precise terms and conditions for copying, distribution and ++modification follow. ++ ++ TERMS AND CONDITIONS ++ ++ 0. Definitions. ++ ++ "This License" refers to version 3 of the GNU General Public License. ++ ++ "Copyright" also means copyright-like laws that apply to other kinds of ++works, such as semiconductor masks. ++ ++ "The Program" refers to any copyrightable work licensed under this ++License. Each licensee is addressed as "you". "Licensees" and ++"recipients" may be individuals or organizations. ++ ++ To "modify" a work means to copy from or adapt all or part of the work ++in a fashion requiring copyright permission, other than the making of an ++exact copy. The resulting work is called a "modified version" of the ++earlier work or a work "based on" the earlier work. ++ ++ A "covered work" means either the unmodified Program or a work based ++on the Program. ++ ++ To "propagate" a work means to do anything with it that, without ++permission, would make you directly or secondarily liable for ++infringement under applicable copyright law, except executing it on a ++computer or modifying a private copy. Propagation includes copying, ++distribution (with or without modification), making available to the ++public, and in some countries other activities as well. ++ ++ To "convey" a work means any kind of propagation that enables other ++parties to make or receive copies. Mere interaction with a user through ++a computer network, with no transfer of a copy, is not conveying. ++ ++ An interactive user interface displays "Appropriate Legal Notices" ++to the extent that it includes a convenient and prominently visible ++feature that (1) displays an appropriate copyright notice, and (2) ++tells the user that there is no warranty for the work (except to the ++extent that warranties are provided), that licensees may convey the ++work under this License, and how to view a copy of this License. If ++the interface presents a list of user commands or options, such as a ++menu, a prominent item in the list meets this criterion. ++ ++ 1. Source Code. ++ ++ The "source code" for a work means the preferred form of the work ++for making modifications to it. "Object code" means any non-source ++form of a work. ++ ++ A "Standard Interface" means an interface that either is an official ++standard defined by a recognized standards body, or, in the case of ++interfaces specified for a particular programming language, one that ++is widely used among developers working in that language. ++ ++ The "System Libraries" of an executable work include anything, other ++than the work as a whole, that (a) is included in the normal form of ++packaging a Major Component, but which is not part of that Major ++Component, and (b) serves only to enable use of the work with that ++Major Component, or to implement a Standard Interface for which an ++implementation is available to the public in source code form. A ++"Major Component", in this context, means a major essential component ++(kernel, window system, and so on) of the specific operating system ++(if any) on which the executable work runs, or a compiler used to ++produce the work, or an object code interpreter used to run it. ++ ++ The "Corresponding Source" for a work in object code form means all ++the source code needed to generate, install, and (for an executable ++work) run the object code and to modify the work, including scripts to ++control those activities. However, it does not include the work's ++System Libraries, or general-purpose tools or generally available free ++programs which are used unmodified in performing those activities but ++which are not part of the work. For example, Corresponding Source ++includes interface definition files associated with source files for ++the work, and the source code for shared libraries and dynamically ++linked subprograms that the work is specifically designed to require, ++such as by intimate data communication or control flow between those ++subprograms and other parts of the work. ++ ++ The Corresponding Source need not include anything that users ++can regenerate automatically from other parts of the Corresponding ++Source. ++ ++ The Corresponding Source for a work in source code form is that ++same work. ++ ++ 2. Basic Permissions. ++ ++ All rights granted under this License are granted for the term of ++copyright on the Program, and are irrevocable provided the stated ++conditions are met. This License explicitly affirms your unlimited ++permission to run the unmodified Program. The output from running a ++covered work is covered by this License only if the output, given its ++content, constitutes a covered work. This License acknowledges your ++rights of fair use or other equivalent, as provided by copyright law. ++ ++ You may make, run and propagate covered works that you do not ++convey, without conditions so long as your license otherwise remains ++in force. You may convey covered works to others for the sole purpose ++of having them make modifications exclusively for you, or provide you ++with facilities for running those works, provided that you comply with ++the terms of this License in conveying all material for which you do ++not control copyright. Those thus making or running the covered works ++for you must do so exclusively on your behalf, under your direction ++and control, on terms that prohibit them from making any copies of ++your copyrighted material outside their relationship with you. ++ ++ Conveying under any other circumstances is permitted solely under ++the conditions stated below. Sublicensing is not allowed; section 10 ++makes it unnecessary. ++ ++ 3. Protecting Users' Legal Rights From Anti-Circumvention Law. ++ ++ No covered work shall be deemed part of an effective technological ++measure under any applicable law fulfilling obligations under article ++11 of the WIPO copyright treaty adopted on 20 December 1996, or ++similar laws prohibiting or restricting circumvention of such ++measures. ++ ++ When you convey a covered work, you waive any legal power to forbid ++circumvention of technological measures to the extent such circumvention ++is effected by exercising rights under this License with respect to ++the covered work, and you disclaim any intention to limit operation or ++modification of the work as a means of enforcing, against the work's ++users, your or third parties' legal rights to forbid circumvention of ++technological measures. ++ ++ 4. Conveying Verbatim Copies. ++ ++ You may convey verbatim copies of the Program's source code as you ++receive it, in any medium, provided that you conspicuously and ++appropriately publish on each copy an appropriate copyright notice; ++keep intact all notices stating that this License and any ++non-permissive terms added in accord with section 7 apply to the code; ++keep intact all notices of the absence of any warranty; and give all ++recipients a copy of this License along with the Program. ++ ++ You may charge any price or no price for each copy that you convey, ++and you may offer support or warranty protection for a fee. ++ ++ 5. Conveying Modified Source Versions. ++ ++ You may convey a work based on the Program, or the modifications to ++produce it from the Program, in the form of source code under the ++terms of section 4, provided that you also meet all of these conditions: ++ ++ a) The work must carry prominent notices stating that you modified ++ it, and giving a relevant date. ++ ++ b) The work must carry prominent notices stating that it is ++ released under this License and any conditions added under section ++ 7. This requirement modifies the requirement in section 4 to ++ "keep intact all notices". ++ ++ c) You must license the entire work, as a whole, under this ++ License to anyone who comes into possession of a copy. This ++ License will therefore apply, along with any applicable section 7 ++ additional terms, to the whole of the work, and all its parts, ++ regardless of how they are packaged. This License gives no ++ permission to license the work in any other way, but it does not ++ invalidate such permission if you have separately received it. ++ ++ d) If the work has interactive user interfaces, each must display ++ Appropriate Legal Notices; however, if the Program has interactive ++ interfaces that do not display Appropriate Legal Notices, your ++ work need not make them do so. ++ ++ A compilation of a covered work with other separate and independent ++works, which are not by their nature extensions of the covered work, ++and which are not combined with it such as to form a larger program, ++in or on a volume of a storage or distribution medium, is called an ++"aggregate" if the compilation and its resulting copyright are not ++used to limit the access or legal rights of the compilation's users ++beyond what the individual works permit. Inclusion of a covered work ++in an aggregate does not cause this License to apply to the other ++parts of the aggregate. ++ ++ 6. Conveying Non-Source Forms. ++ ++ You may convey a covered work in object code form under the terms ++of sections 4 and 5, provided that you also convey the ++machine-readable Corresponding Source under the terms of this License, ++in one of these ways: ++ ++ a) Convey the object code in, or embodied in, a physical product ++ (including a physical distribution medium), accompanied by the ++ Corresponding Source fixed on a durable physical medium ++ customarily used for software interchange. ++ ++ b) Convey the object code in, or embodied in, a physical product ++ (including a physical distribution medium), accompanied by a ++ written offer, valid for at least three years and valid for as ++ long as you offer spare parts or customer support for that product ++ model, to give anyone who possesses the object code either (1) a ++ copy of the Corresponding Source for all the software in the ++ product that is covered by this License, on a durable physical ++ medium customarily used for software interchange, for a price no ++ more than your reasonable cost of physically performing this ++ conveying of source, or (2) access to copy the ++ Corresponding Source from a network server at no charge. ++ ++ c) Convey individual copies of the object code with a copy of the ++ written offer to provide the Corresponding Source. This ++ alternative is allowed only occasionally and noncommercially, and ++ only if you received the object code with such an offer, in accord ++ with subsection 6b. ++ ++ d) Convey the object code by offering access from a designated ++ place (gratis or for a charge), and offer equivalent access to the ++ Corresponding Source in the same way through the same place at no ++ further charge. You need not require recipients to copy the ++ Corresponding Source along with the object code. If the place to ++ copy the object code is a network server, the Corresponding Source ++ may be on a different server (operated by you or a third party) ++ that supports equivalent copying facilities, provided you maintain ++ clear directions next to the object code saying where to find the ++ Corresponding Source. Regardless of what server hosts the ++ Corresponding Source, you remain obligated to ensure that it is ++ available for as long as needed to satisfy these requirements. ++ ++ e) Convey the object code using peer-to-peer transmission, provided ++ you inform other peers where the object code and Corresponding ++ Source of the work are being offered to the general public at no ++ charge under subsection 6d. ++ ++ A separable portion of the object code, whose source code is excluded ++from the Corresponding Source as a System Library, need not be ++included in conveying the object code work. ++ ++ A "User Product" is either (1) a "consumer product", which means any ++tangible personal property which is normally used for personal, family, ++or household purposes, or (2) anything designed or sold for incorporation ++into a dwelling. In determining whether a product is a consumer product, ++doubtful cases shall be resolved in favor of coverage. For a particular ++product received by a particular user, "normally used" refers to a ++typical or common use of that class of product, regardless of the status ++of the particular user or of the way in which the particular user ++actually uses, or expects or is expected to use, the product. A product ++is a consumer product regardless of whether the product has substantial ++commercial, industrial or non-consumer uses, unless such uses represent ++the only significant mode of use of the product. ++ ++ "Installation Information" for a User Product means any methods, ++procedures, authorization keys, or other information required to install ++and execute modified versions of a covered work in that User Product from ++a modified version of its Corresponding Source. The information must ++suffice to ensure that the continued functioning of the modified object ++code is in no case prevented or interfered with solely because ++modification has been made. ++ ++ If you convey an object code work under this section in, or with, or ++specifically for use in, a User Product, and the conveying occurs as ++part of a transaction in which the right of possession and use of the ++User Product is transferred to the recipient in perpetuity or for a ++fixed term (regardless of how the transaction is characterized), the ++Corresponding Source conveyed under this section must be accompanied ++by the Installation Information. But this requirement does not apply ++if neither you nor any third party retains the ability to install ++modified object code on the User Product (for example, the work has ++been installed in ROM). ++ ++ The requirement to provide Installation Information does not include a ++requirement to continue to provide support service, warranty, or updates ++for a work that has been modified or installed by the recipient, or for ++the User Product in which it has been modified or installed. Access to a ++network may be denied when the modification itself materially and ++adversely affects the operation of the network or violates the rules and ++protocols for communication across the network. ++ ++ Corresponding Source conveyed, and Installation Information provided, ++in accord with this section must be in a format that is publicly ++documented (and with an implementation available to the public in ++source code form), and must require no special password or key for ++unpacking, reading or copying. ++ ++ 7. Additional Terms. ++ ++ "Additional permissions" are terms that supplement the terms of this ++License by making exceptions from one or more of its conditions. ++Additional permissions that are applicable to the entire Program shall ++be treated as though they were included in this License, to the extent ++that they are valid under applicable law. If additional permissions ++apply only to part of the Program, that part may be used separately ++under those permissions, but the entire Program remains governed by ++this License without regard to the additional permissions. ++ ++ When you convey a copy of a covered work, you may at your option ++remove any additional permissions from that copy, or from any part of ++it. (Additional permissions may be written to require their own ++removal in certain cases when you modify the work.) You may place ++additional permissions on material, added by you to a covered work, ++for which you have or can give appropriate copyright permission. ++ ++ Notwithstanding any other provision of this License, for material you ++add to a covered work, you may (if authorized by the copyright holders of ++that material) supplement the terms of this License with terms: ++ ++ a) Disclaiming warranty or limiting liability differently from the ++ terms of sections 15 and 16 of this License; or ++ ++ b) Requiring preservation of specified reasonable legal notices or ++ author attributions in that material or in the Appropriate Legal ++ Notices displayed by works containing it; or ++ ++ c) Prohibiting misrepresentation of the origin of that material, or ++ requiring that modified versions of such material be marked in ++ reasonable ways as different from the original version; or ++ ++ d) Limiting the use for publicity purposes of names of licensors or ++ authors of the material; or ++ ++ e) Declining to grant rights under trademark law for use of some ++ trade names, trademarks, or service marks; or ++ ++ f) Requiring indemnification of licensors and authors of that ++ material by anyone who conveys the material (or modified versions of ++ it) with contractual assumptions of liability to the recipient, for ++ any liability that these contractual assumptions directly impose on ++ those licensors and authors. ++ ++ All other non-permissive additional terms are considered "further ++restrictions" within the meaning of section 10. If the Program as you ++received it, or any part of it, contains a notice stating that it is ++governed by this License along with a term that is a further ++restriction, you may remove that term. If a license document contains ++a further restriction but permits relicensing or conveying under this ++License, you may add to a covered work material governed by the terms ++of that license document, provided that the further restriction does ++not survive such relicensing or conveying. ++ ++ If you add terms to a covered work in accord with this section, you ++must place, in the relevant source files, a statement of the ++additional terms that apply to those files, or a notice indicating ++where to find the applicable terms. ++ ++ Additional terms, permissive or non-permissive, may be stated in the ++form of a separately written license, or stated as exceptions; ++the above requirements apply either way. ++ ++ 8. Termination. ++ ++ You may not propagate or modify a covered work except as expressly ++provided under this License. Any attempt otherwise to propagate or ++modify it is void, and will automatically terminate your rights under ++this License (including any patent licenses granted under the third ++paragraph of section 11). ++ ++ However, if you cease all violation of this License, then your ++license from a particular copyright holder is reinstated (a) ++provisionally, unless and until the copyright holder explicitly and ++finally terminates your license, and (b) permanently, if the copyright ++holder fails to notify you of the violation by some reasonable means ++prior to 60 days after the cessation. ++ ++ Moreover, your license from a particular copyright holder is ++reinstated permanently if the copyright holder notifies you of the ++violation by some reasonable means, this is the first time you have ++received notice of violation of this License (for any work) from that ++copyright holder, and you cure the violation prior to 30 days after ++your receipt of the notice. ++ ++ Termination of your rights under this section does not terminate the ++licenses of parties who have received copies or rights from you under ++this License. If your rights have been terminated and not permanently ++reinstated, you do not qualify to receive new licenses for the same ++material under section 10. ++ ++ 9. Acceptance Not Required for Having Copies. ++ ++ You are not required to accept this License in order to receive or ++run a copy of the Program. Ancillary propagation of a covered work ++occurring solely as a consequence of using peer-to-peer transmission ++to receive a copy likewise does not require acceptance. However, ++nothing other than this License grants you permission to propagate or ++modify any covered work. These actions infringe copyright if you do ++not accept this License. Therefore, by modifying or propagating a ++covered work, you indicate your acceptance of this License to do so. ++ ++ 10. Automatic Licensing of Downstream Recipients. ++ ++ Each time you convey a covered work, the recipient automatically ++receives a license from the original licensors, to run, modify and ++propagate that work, subject to this License. You are not responsible ++for enforcing compliance by third parties with this License. ++ ++ An "entity transaction" is a transaction transferring control of an ++organization, or substantially all assets of one, or subdividing an ++organization, or merging organizations. If propagation of a covered ++work results from an entity transaction, each party to that ++transaction who receives a copy of the work also receives whatever ++licenses to the work the party's predecessor in interest had or could ++give under the previous paragraph, plus a right to possession of the ++Corresponding Source of the work from the predecessor in interest, if ++the predecessor has it or can get it with reasonable efforts. ++ ++ You may not impose any further restrictions on the exercise of the ++rights granted or affirmed under this License. For example, you may ++not impose a license fee, royalty, or other charge for exercise of ++rights granted under this License, and you may not initiate litigation ++(including a cross-claim or counterclaim in a lawsuit) alleging that ++any patent claim is infringed by making, using, selling, offering for ++sale, or importing the Program or any portion of it. ++ ++ 11. Patents. ++ ++ A "contributor" is a copyright holder who authorizes use under this ++License of the Program or a work on which the Program is based. The ++work thus licensed is called the contributor's "contributor version". ++ ++ A contributor's "essential patent claims" are all patent claims ++owned or controlled by the contributor, whether already acquired or ++hereafter acquired, that would be infringed by some manner, permitted ++by this License, of making, using, or selling its contributor version, ++but do not include claims that would be infringed only as a ++consequence of further modification of the contributor version. For ++purposes of this definition, "control" includes the right to grant ++patent sublicenses in a manner consistent with the requirements of ++this License. ++ ++ Each contributor grants you a non-exclusive, worldwide, royalty-free ++patent license under the contributor's essential patent claims, to ++make, use, sell, offer for sale, import and otherwise run, modify and ++propagate the contents of its contributor version. ++ ++ In the following three paragraphs, a "patent license" is any express ++agreement or commitment, however denominated, not to enforce a patent ++(such as an express permission to practice a patent or covenant not to ++sue for patent infringement). To "grant" such a patent license to a ++party means to make such an agreement or commitment not to enforce a ++patent against the party. ++ ++ If you convey a covered work, knowingly relying on a patent license, ++and the Corresponding Source of the work is not available for anyone ++to copy, free of charge and under the terms of this License, through a ++publicly available network server or other readily accessible means, ++then you must either (1) cause the Corresponding Source to be so ++available, or (2) arrange to deprive yourself of the benefit of the ++patent license for this particular work, or (3) arrange, in a manner ++consistent with the requirements of this License, to extend the patent ++license to downstream recipients. "Knowingly relying" means you have ++actual knowledge that, but for the patent license, your conveying the ++covered work in a country, or your recipient's use of the covered work ++in a country, would infringe one or more identifiable patents in that ++country that you have reason to believe are valid. ++ ++ If, pursuant to or in connection with a single transaction or ++arrangement, you convey, or propagate by procuring conveyance of, a ++covered work, and grant a patent license to some of the parties ++receiving the covered work authorizing them to use, propagate, modify ++or convey a specific copy of the covered work, then the patent license ++you grant is automatically extended to all recipients of the covered ++work and works based on it. ++ ++ A patent license is "discriminatory" if it does not include within ++the scope of its coverage, prohibits the exercise of, or is ++conditioned on the non-exercise of one or more of the rights that are ++specifically granted under this License. You may not convey a covered ++work if you are a party to an arrangement with a third party that is ++in the business of distributing software, under which you make payment ++to the third party based on the extent of your activity of conveying ++the work, and under which the third party grants, to any of the ++parties who would receive the covered work from you, a discriminatory ++patent license (a) in connection with copies of the covered work ++conveyed by you (or copies made from those copies), or (b) primarily ++for and in connection with specific products or compilations that ++contain the covered work, unless you entered into that arrangement, ++or that patent license was granted, prior to 28 March 2007. ++ ++ Nothing in this License shall be construed as excluding or limiting ++any implied license or other defenses to infringement that may ++otherwise be available to you under applicable patent law. ++ ++ 12. No Surrender of Others' Freedom. ++ ++ If conditions are imposed on you (whether by court order, agreement or ++otherwise) that contradict the conditions of this License, they do not ++excuse you from the conditions of this License. If you cannot convey a ++covered work so as to satisfy simultaneously your obligations under this ++License and any other pertinent obligations, then as a consequence you may ++not convey it at all. For example, if you agree to terms that obligate you ++to collect a royalty for further conveying from those to whom you convey ++the Program, the only way you could satisfy both those terms and this ++License would be to refrain entirely from conveying the Program. ++ ++ 13. Use with the GNU Affero General Public License. ++ ++ Notwithstanding any other provision of this License, you have ++permission to link or combine any covered work with a work licensed ++under version 3 of the GNU Affero General Public License into a single ++combined work, and to convey the resulting work. The terms of this ++License will continue to apply to the part which is the covered work, ++but the special requirements of the GNU Affero General Public License, ++section 13, concerning interaction through a network will apply to the ++combination as such. ++ ++ 14. Revised Versions of this License. ++ ++ The Free Software Foundation may publish revised and/or new versions of ++the GNU General Public License from time to time. Such new versions will ++be similar in spirit to the present version, but may differ in detail to ++address new problems or concerns. ++ ++ Each version is given a distinguishing version number. If the ++Program specifies that a certain numbered version of the GNU General ++Public License "or any later version" applies to it, you have the ++option of following the terms and conditions either of that numbered ++version or of any later version published by the Free Software ++Foundation. If the Program does not specify a version number of the ++GNU General Public License, you may choose any version ever published ++by the Free Software Foundation. ++ ++ If the Program specifies that a proxy can decide which future ++versions of the GNU General Public License can be used, that proxy's ++public statement of acceptance of a version permanently authorizes you ++to choose that version for the Program. ++ ++ Later license versions may give you additional or different ++permissions. However, no additional obligations are imposed on any ++author or copyright holder as a result of your choosing to follow a ++later version. ++ ++ 15. Disclaimer of Warranty. ++ ++ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY ++APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT ++HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY ++OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, ++THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM ++IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ++ALL NECESSARY SERVICING, REPAIR OR CORRECTION. ++ ++ 16. Limitation of Liability. ++ ++ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING ++WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS ++THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY ++GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE ++USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF ++DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD ++PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), ++EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF ++SUCH DAMAGES. ++ ++ 17. Interpretation of Sections 15 and 16. ++ ++ If the disclaimer of warranty and limitation of liability provided ++above cannot be given local legal effect according to their terms, ++reviewing courts shall apply local law that most closely approximates ++an absolute waiver of all civil liability in connection with the ++Program, unless a warranty or assumption of liability accompanies a ++copy of the Program in return for a fee. ++ ++ END OF TERMS AND CONDITIONS ++ ++ How to Apply These Terms to Your New Programs ++ ++ If you develop a new program, and you want it to be of the greatest ++possible use to the public, the best way to achieve this is to make it ++free software which everyone can redistribute and change under these terms. ++ ++ To do so, attach the following notices to the program. It is safest ++to attach them to the start of each source file to most effectively ++state the exclusion of warranty; and each file should have at least ++the "copyright" line and a pointer to where the full notice is found. ++ ++ ++ Copyright (C) ++ ++ This program is free software: you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation, either version 3 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see . ++ ++Also add information on how to contact you by electronic and paper mail. ++ ++ If the program does terminal interaction, make it output a short ++notice like this when it starts in an interactive mode: ++ ++ Copyright (C) ++ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. ++ This is free software, and you are welcome to redistribute it ++ under certain conditions; type `show c' for details. ++ ++The hypothetical commands `show w' and `show c' should show the appropriate ++parts of the General Public License. Of course, your program's commands ++might be different; for a GUI interface, you would use an "about box". ++ ++ You should also get your employer (if you work as a programmer) or school, ++if any, to sign a "copyright disclaimer" for the program, if necessary. ++For more information on this, and how to apply and follow the GNU GPL, see ++. ++ ++ The GNU General Public License does not permit incorporating your program ++into proprietary programs. If your program is a subroutine library, you ++may consider it more useful to permit linking proprietary applications with ++the library. If this is what you want to do, use the GNU Lesser General ++Public License instead of this License. But first, please read ++. +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/depcomp open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/depcomp +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/depcomp 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/depcomp 2012-04-09 21:52:14.000000000 -0500 +@@ -0,0 +1,589 @@ ++#! /bin/sh ++# depcomp - compile a program generating dependencies as side-effects ++ ++scriptversion=2007-03-29.01 ++ ++# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007 Free Software ++# Foundation, Inc. ++ ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2, or (at your option) ++# any later version. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++ ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++# 02110-1301, USA. ++ ++# As a special exception to the GNU General Public License, if you ++# distribute this file as part of a program that contains a ++# configuration script generated by Autoconf, you may include it under ++# the same distribution terms that you use for the rest of that program. ++ ++# Originally written by Alexandre Oliva . ++ ++case $1 in ++ '') ++ echo "$0: No command. Try \`$0 --help' for more information." 1>&2 ++ exit 1; ++ ;; ++ -h | --h*) ++ cat <<\EOF ++Usage: depcomp [--help] [--version] PROGRAM [ARGS] ++ ++Run PROGRAMS ARGS to compile a file, generating dependencies ++as side-effects. ++ ++Environment variables: ++ depmode Dependency tracking mode. ++ source Source file read by `PROGRAMS ARGS'. ++ object Object file output by `PROGRAMS ARGS'. ++ DEPDIR directory where to store dependencies. ++ depfile Dependency file to output. ++ tmpdepfile Temporary file to use when outputing dependencies. ++ libtool Whether libtool is used (yes/no). ++ ++Report bugs to . ++EOF ++ exit $? ++ ;; ++ -v | --v*) ++ echo "depcomp $scriptversion" ++ exit $? ++ ;; ++esac ++ ++if test -z "$depmode" || test -z "$source" || test -z "$object"; then ++ echo "depcomp: Variables source, object and depmode must be set" 1>&2 ++ exit 1 ++fi ++ ++# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. ++depfile=${depfile-`echo "$object" | ++ sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} ++tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} ++ ++rm -f "$tmpdepfile" ++ ++# Some modes work just like other modes, but use different flags. We ++# parameterize here, but still list the modes in the big case below, ++# to make depend.m4 easier to write. Note that we *cannot* use a case ++# here, because this file can only contain one case statement. ++if test "$depmode" = hp; then ++ # HP compiler uses -M and no extra arg. ++ gccflag=-M ++ depmode=gcc ++fi ++ ++if test "$depmode" = dashXmstdout; then ++ # This is just like dashmstdout with a different argument. ++ dashmflag=-xM ++ depmode=dashmstdout ++fi ++ ++case "$depmode" in ++gcc3) ++## gcc 3 implements dependency tracking that does exactly what ++## we want. Yay! Note: for some reason libtool 1.4 doesn't like ++## it if -MD -MP comes after the -MF stuff. Hmm. ++## Unfortunately, FreeBSD c89 acceptance of flags depends upon ++## the command line argument order; so add the flags where they ++## appear in depend2.am. Note that the slowdown incurred here ++## affects only configure: in makefiles, %FASTDEP% shortcuts this. ++ for arg ++ do ++ case $arg in ++ -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; ++ *) set fnord "$@" "$arg" ;; ++ esac ++ shift # fnord ++ shift # $arg ++ done ++ "$@" ++ stat=$? ++ if test $stat -eq 0; then : ++ else ++ rm -f "$tmpdepfile" ++ exit $stat ++ fi ++ mv "$tmpdepfile" "$depfile" ++ ;; ++ ++gcc) ++## There are various ways to get dependency output from gcc. Here's ++## why we pick this rather obscure method: ++## - Don't want to use -MD because we'd like the dependencies to end ++## up in a subdir. Having to rename by hand is ugly. ++## (We might end up doing this anyway to support other compilers.) ++## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ++## -MM, not -M (despite what the docs say). ++## - Using -M directly means running the compiler twice (even worse ++## than renaming). ++ if test -z "$gccflag"; then ++ gccflag=-MD, ++ fi ++ "$@" -Wp,"$gccflag$tmpdepfile" ++ stat=$? ++ if test $stat -eq 0; then : ++ else ++ rm -f "$tmpdepfile" ++ exit $stat ++ fi ++ rm -f "$depfile" ++ echo "$object : \\" > "$depfile" ++ alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ++## The second -e expression handles DOS-style file names with drive letters. ++ sed -e 's/^[^:]*: / /' \ ++ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ++## This next piece of magic avoids the `deleted header file' problem. ++## The problem is that when a header file which appears in a .P file ++## is deleted, the dependency causes make to die (because there is ++## typically no way to rebuild the header). We avoid this by adding ++## dummy dependencies for each header file. Too bad gcc doesn't do ++## this for us directly. ++ tr ' ' ' ++' < "$tmpdepfile" | ++## Some versions of gcc put a space before the `:'. On the theory ++## that the space means something, we add a space to the output as ++## well. ++## Some versions of the HPUX 10.20 sed can't process this invocation ++## correctly. Breaking it into two sed invocations is a workaround. ++ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" ++ rm -f "$tmpdepfile" ++ ;; ++ ++hp) ++ # This case exists only to let depend.m4 do its work. It works by ++ # looking at the text of this script. This case will never be run, ++ # since it is checked for above. ++ exit 1 ++ ;; ++ ++sgi) ++ if test "$libtool" = yes; then ++ "$@" "-Wp,-MDupdate,$tmpdepfile" ++ else ++ "$@" -MDupdate "$tmpdepfile" ++ fi ++ stat=$? ++ if test $stat -eq 0; then : ++ else ++ rm -f "$tmpdepfile" ++ exit $stat ++ fi ++ rm -f "$depfile" ++ ++ if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files ++ echo "$object : \\" > "$depfile" ++ ++ # Clip off the initial element (the dependent). Don't try to be ++ # clever and replace this with sed code, as IRIX sed won't handle ++ # lines with more than a fixed number of characters (4096 in ++ # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; ++ # the IRIX cc adds comments like `#:fec' to the end of the ++ # dependency line. ++ tr ' ' ' ++' < "$tmpdepfile" \ ++ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ ++ tr ' ++' ' ' >> $depfile ++ echo >> $depfile ++ ++ # The second pass generates a dummy entry for each header file. ++ tr ' ' ' ++' < "$tmpdepfile" \ ++ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ ++ >> $depfile ++ else ++ # The sourcefile does not contain any dependencies, so just ++ # store a dummy comment line, to avoid errors with the Makefile ++ # "include basename.Plo" scheme. ++ echo "#dummy" > "$depfile" ++ fi ++ rm -f "$tmpdepfile" ++ ;; ++ ++aix) ++ # The C for AIX Compiler uses -M and outputs the dependencies ++ # in a .u file. In older versions, this file always lives in the ++ # current directory. Also, the AIX compiler puts `$object:' at the ++ # start of each line; $object doesn't have directory information. ++ # Version 6 uses the directory in both cases. ++ dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` ++ test "x$dir" = "x$object" && dir= ++ base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` ++ if test "$libtool" = yes; then ++ tmpdepfile1=$dir$base.u ++ tmpdepfile2=$base.u ++ tmpdepfile3=$dir.libs/$base.u ++ "$@" -Wc,-M ++ else ++ tmpdepfile1=$dir$base.u ++ tmpdepfile2=$dir$base.u ++ tmpdepfile3=$dir$base.u ++ "$@" -M ++ fi ++ stat=$? ++ ++ if test $stat -eq 0; then : ++ else ++ rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" ++ exit $stat ++ fi ++ ++ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" ++ do ++ test -f "$tmpdepfile" && break ++ done ++ if test -f "$tmpdepfile"; then ++ # Each line is of the form `foo.o: dependent.h'. ++ # Do two passes, one to just change these to ++ # `$object: dependent.h' and one to simply `dependent.h:'. ++ sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" ++ # That's a tab and a space in the []. ++ sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" ++ else ++ # The sourcefile does not contain any dependencies, so just ++ # store a dummy comment line, to avoid errors with the Makefile ++ # "include basename.Plo" scheme. ++ echo "#dummy" > "$depfile" ++ fi ++ rm -f "$tmpdepfile" ++ ;; ++ ++icc) ++ # Intel's C compiler understands `-MD -MF file'. However on ++ # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c ++ # ICC 7.0 will fill foo.d with something like ++ # foo.o: sub/foo.c ++ # foo.o: sub/foo.h ++ # which is wrong. We want: ++ # sub/foo.o: sub/foo.c ++ # sub/foo.o: sub/foo.h ++ # sub/foo.c: ++ # sub/foo.h: ++ # ICC 7.1 will output ++ # foo.o: sub/foo.c sub/foo.h ++ # and will wrap long lines using \ : ++ # foo.o: sub/foo.c ... \ ++ # sub/foo.h ... \ ++ # ... ++ ++ "$@" -MD -MF "$tmpdepfile" ++ stat=$? ++ if test $stat -eq 0; then : ++ else ++ rm -f "$tmpdepfile" ++ exit $stat ++ fi ++ rm -f "$depfile" ++ # Each line is of the form `foo.o: dependent.h', ++ # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. ++ # Do two passes, one to just change these to ++ # `$object: dependent.h' and one to simply `dependent.h:'. ++ sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" ++ # Some versions of the HPUX 10.20 sed can't process this invocation ++ # correctly. Breaking it into two sed invocations is a workaround. ++ sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | ++ sed -e 's/$/ :/' >> "$depfile" ++ rm -f "$tmpdepfile" ++ ;; ++ ++hp2) ++ # The "hp" stanza above does not work with aCC (C++) and HP's ia64 ++ # compilers, which have integrated preprocessors. The correct option ++ # to use with these is +Maked; it writes dependencies to a file named ++ # 'foo.d', which lands next to the object file, wherever that ++ # happens to be. ++ # Much of this is similar to the tru64 case; see comments there. ++ dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` ++ test "x$dir" = "x$object" && dir= ++ base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` ++ if test "$libtool" = yes; then ++ tmpdepfile1=$dir$base.d ++ tmpdepfile2=$dir.libs/$base.d ++ "$@" -Wc,+Maked ++ else ++ tmpdepfile1=$dir$base.d ++ tmpdepfile2=$dir$base.d ++ "$@" +Maked ++ fi ++ stat=$? ++ if test $stat -eq 0; then : ++ else ++ rm -f "$tmpdepfile1" "$tmpdepfile2" ++ exit $stat ++ fi ++ ++ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" ++ do ++ test -f "$tmpdepfile" && break ++ done ++ if test -f "$tmpdepfile"; then ++ sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" ++ # Add `dependent.h:' lines. ++ sed -ne '2,${; s/^ *//; s/ \\*$//; s/$/:/; p;}' "$tmpdepfile" >> "$depfile" ++ else ++ echo "#dummy" > "$depfile" ++ fi ++ rm -f "$tmpdepfile" "$tmpdepfile2" ++ ;; ++ ++tru64) ++ # The Tru64 compiler uses -MD to generate dependencies as a side ++ # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. ++ # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put ++ # dependencies in `foo.d' instead, so we check for that too. ++ # Subdirectories are respected. ++ dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` ++ test "x$dir" = "x$object" && dir= ++ base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` ++ ++ if test "$libtool" = yes; then ++ # With Tru64 cc, shared objects can also be used to make a ++ # static library. This mechanism is used in libtool 1.4 series to ++ # handle both shared and static libraries in a single compilation. ++ # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. ++ # ++ # With libtool 1.5 this exception was removed, and libtool now ++ # generates 2 separate objects for the 2 libraries. These two ++ # compilations output dependencies in $dir.libs/$base.o.d and ++ # in $dir$base.o.d. We have to check for both files, because ++ # one of the two compilations can be disabled. We should prefer ++ # $dir$base.o.d over $dir.libs/$base.o.d because the latter is ++ # automatically cleaned when .libs/ is deleted, while ignoring ++ # the former would cause a distcleancheck panic. ++ tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 ++ tmpdepfile2=$dir$base.o.d # libtool 1.5 ++ tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 ++ tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 ++ "$@" -Wc,-MD ++ else ++ tmpdepfile1=$dir$base.o.d ++ tmpdepfile2=$dir$base.d ++ tmpdepfile3=$dir$base.d ++ tmpdepfile4=$dir$base.d ++ "$@" -MD ++ fi ++ ++ stat=$? ++ if test $stat -eq 0; then : ++ else ++ rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" ++ exit $stat ++ fi ++ ++ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" ++ do ++ test -f "$tmpdepfile" && break ++ done ++ if test -f "$tmpdepfile"; then ++ sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" ++ # That's a tab and a space in the []. ++ sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" ++ else ++ echo "#dummy" > "$depfile" ++ fi ++ rm -f "$tmpdepfile" ++ ;; ++ ++#nosideeffect) ++ # This comment above is used by automake to tell side-effect ++ # dependency tracking mechanisms from slower ones. ++ ++dashmstdout) ++ # Important note: in order to support this mode, a compiler *must* ++ # always write the preprocessed file to stdout, regardless of -o. ++ "$@" || exit $? ++ ++ # Remove the call to Libtool. ++ if test "$libtool" = yes; then ++ while test $1 != '--mode=compile'; do ++ shift ++ done ++ shift ++ fi ++ ++ # Remove `-o $object'. ++ IFS=" " ++ for arg ++ do ++ case $arg in ++ -o) ++ shift ++ ;; ++ $object) ++ shift ++ ;; ++ *) ++ set fnord "$@" "$arg" ++ shift # fnord ++ shift # $arg ++ ;; ++ esac ++ done ++ ++ test -z "$dashmflag" && dashmflag=-M ++ # Require at least two characters before searching for `:' ++ # in the target name. This is to cope with DOS-style filenames: ++ # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. ++ "$@" $dashmflag | ++ sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" ++ rm -f "$depfile" ++ cat < "$tmpdepfile" > "$depfile" ++ tr ' ' ' ++' < "$tmpdepfile" | \ ++## Some versions of the HPUX 10.20 sed can't process this invocation ++## correctly. Breaking it into two sed invocations is a workaround. ++ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" ++ rm -f "$tmpdepfile" ++ ;; ++ ++dashXmstdout) ++ # This case only exists to satisfy depend.m4. It is never actually ++ # run, as this mode is specially recognized in the preamble. ++ exit 1 ++ ;; ++ ++makedepend) ++ "$@" || exit $? ++ # Remove any Libtool call ++ if test "$libtool" = yes; then ++ while test $1 != '--mode=compile'; do ++ shift ++ done ++ shift ++ fi ++ # X makedepend ++ shift ++ cleared=no ++ for arg in "$@"; do ++ case $cleared in ++ no) ++ set ""; shift ++ cleared=yes ;; ++ esac ++ case "$arg" in ++ -D*|-I*) ++ set fnord "$@" "$arg"; shift ;; ++ # Strip any option that makedepend may not understand. Remove ++ # the object too, otherwise makedepend will parse it as a source file. ++ -*|$object) ++ ;; ++ *) ++ set fnord "$@" "$arg"; shift ;; ++ esac ++ done ++ obj_suffix="`echo $object | sed 's/^.*\././'`" ++ touch "$tmpdepfile" ++ ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" ++ rm -f "$depfile" ++ cat < "$tmpdepfile" > "$depfile" ++ sed '1,2d' "$tmpdepfile" | tr ' ' ' ++' | \ ++## Some versions of the HPUX 10.20 sed can't process this invocation ++## correctly. Breaking it into two sed invocations is a workaround. ++ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" ++ rm -f "$tmpdepfile" "$tmpdepfile".bak ++ ;; ++ ++cpp) ++ # Important note: in order to support this mode, a compiler *must* ++ # always write the preprocessed file to stdout. ++ "$@" || exit $? ++ ++ # Remove the call to Libtool. ++ if test "$libtool" = yes; then ++ while test $1 != '--mode=compile'; do ++ shift ++ done ++ shift ++ fi ++ ++ # Remove `-o $object'. ++ IFS=" " ++ for arg ++ do ++ case $arg in ++ -o) ++ shift ++ ;; ++ $object) ++ shift ++ ;; ++ *) ++ set fnord "$@" "$arg" ++ shift # fnord ++ shift # $arg ++ ;; ++ esac ++ done ++ ++ "$@" -E | ++ sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ ++ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | ++ sed '$ s: \\$::' > "$tmpdepfile" ++ rm -f "$depfile" ++ echo "$object : \\" > "$depfile" ++ cat < "$tmpdepfile" >> "$depfile" ++ sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" ++ rm -f "$tmpdepfile" ++ ;; ++ ++msvisualcpp) ++ # Important note: in order to support this mode, a compiler *must* ++ # always write the preprocessed file to stdout, regardless of -o, ++ # because we must use -o when running libtool. ++ "$@" || exit $? ++ IFS=" " ++ for arg ++ do ++ case "$arg" in ++ "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") ++ set fnord "$@" ++ shift ++ shift ++ ;; ++ *) ++ set fnord "$@" "$arg" ++ shift ++ shift ++ ;; ++ esac ++ done ++ "$@" -E | ++ sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" ++ rm -f "$depfile" ++ echo "$object : \\" > "$depfile" ++ . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" ++ echo " " >> "$depfile" ++ . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" ++ rm -f "$tmpdepfile" ++ ;; ++ ++none) ++ exec "$@" ++ ;; ++ ++*) ++ echo "Unknown depmode $depmode" 1>&2 ++ exit 1 ++ ;; ++esac ++ ++exit 0 ++ ++# Local Variables: ++# mode: shell-script ++# sh-indentation: 2 ++# eval: (add-hook 'write-file-hooks 'time-stamp) ++# time-stamp-start: "scriptversion=" ++# time-stamp-format: "%:y-%02m-%02d.%02H" ++# time-stamp-end: "$" ++# End: +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/docs/iscsiuio.8 open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/docs/iscsiuio.8 +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/docs/iscsiuio.8 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/docs/iscsiuio.8 2012-04-09 21:52:14.000000000 -0500 +@@ -0,0 +1,77 @@ ++.\" Copyright (c) 2010-2012 Broadcom 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.2.1 ++.\" ++.TH iscsiuio 8 "03/05/2012" "Broadcom 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 Broadcom NetXtreme II ++BCM5706/5708/5709 series PCI/PCI-X Gigabit Ethernet Network Interface Card ++(NIC) and for the Broadcom 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 ++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 ++This is to enable forground mode so that this application doesn't get sent ++into the background. ++.PP ++.TP ++.BI -v ++This is to print the version. ++ ++.\" ++.\" AUTHOR part ++.\" ++.SH AUTHOR ++Benjamin Li \- benli@broadcom.com ++.P ++Eddie Wai \- eddie.wai@broadcom.com +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/include/config.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/include/config.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/include/config.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/include/config.h 2012-04-09 21:52:14.000000000 -0500 +@@ -0,0 +1,76 @@ ++/* ++ * iSCSI Configuration ++ * ++ * Copyright (C) 2002 Cisco Systems, Inc. ++ * maintained by linux-iscsi-devel@lists.sourceforge.net ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published ++ * by the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * See the file COPYING included with this distribution for more details. ++ */ ++ ++#ifndef CONFIG_H ++#define CONFIG_H ++ ++#include ++#include "list.h" ++#include "iscsi_net_util.h" ++ ++/* ISIDs now have a typed naming authority in them. We use an OUI */ ++#define DRIVER_ISID_0 0x00 ++#define DRIVER_ISID_1 0x02 ++#define DRIVER_ISID_2 0x3D ++ ++/* max len of interface */ ++#define ISCSI_MAX_IFACE_LEN 65 ++ ++#define ISCSI_HWADDRESS_BUF_SIZE 18 ++#define ISCSI_TRANSPORT_NAME_MAXLEN 16 ++#define ISCSI_MAX_STR_LEN 80 ++ ++typedef struct iface_rec { ++ struct list_head list; ++ /* iscsi iface record name */ ++ char name[ISCSI_MAX_IFACE_LEN]; ++ uint32_t iface_num; ++ /* network layer iface name (eth0) */ ++ char netdev[IFNAMSIZ]; ++ char ipaddress[NI_MAXHOST]; ++ char subnet_mask[NI_MAXHOST]; ++ char gateway[NI_MAXHOST]; ++ char bootproto[ISCSI_MAX_STR_LEN]; ++ char ipv6_linklocal[NI_MAXHOST]; ++ char ipv6_router[NI_MAXHOST]; ++ char ipv6_autocfg[NI_MAXHOST]; ++ char linklocal_autocfg[NI_MAXHOST]; ++ char router_autocfg[NI_MAXHOST]; ++ uint16_t vlan_id; ++ uint8_t vlan_priority; ++ char vlan_state[ISCSI_MAX_STR_LEN]; ++ char state[ISCSI_MAX_STR_LEN]; /* 0 = disable, ++ * 1 = enable */ ++ uint16_t mtu; ++ uint16_t port; ++ /* ++ * TODO: we may have to make this bigger and interconnect ++ * specific for infinniband ++ */ ++ char hwaddress[ISCSI_HWADDRESS_BUF_SIZE]; ++ char transport_name[ISCSI_TRANSPORT_NAME_MAXLEN]; ++ /* ++ * This is only used for boot now, but the iser guys ++ * can use this for their virtualization idea. ++ */ ++ char alias[TARGET_NAME_MAXLEN + 1]; ++ char iname[TARGET_NAME_MAXLEN + 1]; ++} iface_rec_t; ++ ++#endif /* CONFIG_H */ +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/include/fw_context.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/include/fw_context.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/include/fw_context.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/include/fw_context.h 2012-04-09 21:52:14.000000000 -0500 +@@ -0,0 +1,64 @@ ++/* ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA ++ * ++ * Copyright (C) IBM Corporation. 2007 ++ * Author: Doug Maxey ++ * "Prasanna Mumbai" ++ * ++ */ ++#ifndef FWPARAM_CONTEXT_H_ ++#define FWPARAM_CONTEXT_H_ ++ ++#include ++ ++#include "iscsi_proto.h" ++#include "list.h" ++#include "auth.h" ++ ++struct boot_context { ++ struct list_head list; ++ ++ /* target settings */ ++ int target_port; ++ char targetname[TARGET_NAME_MAXLEN + 1]; ++ char target_ipaddr[32]; ++ char chap_name[AUTH_STR_MAX_LEN]; ++ char chap_password[AUTH_STR_MAX_LEN]; ++ char chap_name_in[AUTH_STR_MAX_LEN]; ++ char chap_password_in[AUTH_STR_MAX_LEN]; ++ ++ /* initiator settings */ ++ char isid[10]; ++ char initiatorname[TARGET_NAME_MAXLEN + 1]; ++ ++ /* network settings */ ++ char dhcp[18]; ++ char iface[IF_NAMESIZE]; ++ char mac[18]; ++ char ipaddr[18]; ++ char gateway[18]; ++ char primary_dns[18]; ++ char secondary_dns[18]; ++ char mask[18]; ++ char lun[17]; ++ char vlan[15]; ++}; ++ ++extern int fw_get_entry(struct boot_context *context); ++extern void fw_print_entry(struct boot_context *context); ++extern int fw_get_targets(struct list_head *list); ++extern void fw_free_targets(struct list_head *list); ++ ++#endif /* FWPARAM_CONTEXT_H_ */ +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/include/iscsi_if.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/include/iscsi_if.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/include/iscsi_if.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/include/iscsi_if.h 2012-04-09 21:52:14.000000000 -0500 +@@ -0,0 +1,473 @@ ++/* ++ * iSCSI User/Kernel Shares (Defines, Constants, Protocol definitions, etc) ++ * ++ * Copyright (C) 2005 Dmitry Yusupov ++ * Copyright (C) 2005 Alex Aizman ++ * maintained by open-iscsi@googlegroups.com ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published ++ * by the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * See the file COPYING included with this distribution for more details. ++ */ ++ ++#ifndef ISCSI_IF_H ++#define ISCSI_IF_H ++ ++#include "iscsi_proto.h" ++#include ++//#include ++ ++#define ISCSI_NL_GRP_ISCSID 1 ++#define ISCSI_NL_GRP_UIP 2 ++ ++#define UEVENT_BASE 10 ++#define KEVENT_BASE 100 ++#define ISCSI_ERR_BASE 1000 ++ ++enum iscsi_uevent_e { ++ ISCSI_UEVENT_UNKNOWN = 0, ++ ++ /* down events */ ++ ISCSI_UEVENT_CREATE_SESSION = UEVENT_BASE + 1, ++ ISCSI_UEVENT_DESTROY_SESSION = UEVENT_BASE + 2, ++ ISCSI_UEVENT_CREATE_CONN = UEVENT_BASE + 3, ++ ISCSI_UEVENT_DESTROY_CONN = UEVENT_BASE + 4, ++ ISCSI_UEVENT_BIND_CONN = UEVENT_BASE + 5, ++ ISCSI_UEVENT_SET_PARAM = UEVENT_BASE + 6, ++ ISCSI_UEVENT_START_CONN = UEVENT_BASE + 7, ++ ISCSI_UEVENT_STOP_CONN = UEVENT_BASE + 8, ++ ISCSI_UEVENT_SEND_PDU = UEVENT_BASE + 9, ++ ISCSI_UEVENT_GET_STATS = UEVENT_BASE + 10, ++ ISCSI_UEVENT_GET_PARAM = UEVENT_BASE + 11, ++ ++ ISCSI_UEVENT_TRANSPORT_EP_CONNECT = UEVENT_BASE + 12, ++ ISCSI_UEVENT_TRANSPORT_EP_POLL = UEVENT_BASE + 13, ++ ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT = UEVENT_BASE + 14, ++ ++ ISCSI_UEVENT_TGT_DSCVR = UEVENT_BASE + 15, ++ ISCSI_UEVENT_SET_HOST_PARAM = UEVENT_BASE + 16, ++ ISCSI_UEVENT_UNBIND_SESSION = UEVENT_BASE + 17, ++ ISCSI_UEVENT_CREATE_BOUND_SESSION = UEVENT_BASE + 18, ++ ISCSI_UEVENT_TRANSPORT_EP_CONNECT_THROUGH_HOST = UEVENT_BASE + 19, ++ ++ ISCSI_UEVENT_PATH_UPDATE = UEVENT_BASE + 20, ++ ++ /* up events */ ++ ISCSI_KEVENT_RECV_PDU = KEVENT_BASE + 1, ++ ISCSI_KEVENT_CONN_ERROR = KEVENT_BASE + 2, ++ ISCSI_KEVENT_IF_ERROR = KEVENT_BASE + 3, ++ ISCSI_KEVENT_DESTROY_SESSION = KEVENT_BASE + 4, ++ ISCSI_KEVENT_UNBIND_SESSION = KEVENT_BASE + 5, ++ ISCSI_KEVENT_CREATE_SESSION = KEVENT_BASE + 6, ++ ++ ISCSI_KEVENT_PATH_REQ = KEVENT_BASE + 7, ++ ISCSI_KEVENT_IF_DOWN = KEVENT_BASE + 8, ++}; ++ ++enum iscsi_tgt_dscvr { ++ ISCSI_TGT_DSCVR_SEND_TARGETS = 1, ++ ISCSI_TGT_DSCVR_ISNS = 2, ++ ISCSI_TGT_DSCVR_SLP = 3, ++}; ++ ++struct iscsi_uevent { ++ uint32_t type; /* k/u events type */ ++ uint32_t iferror; /* carries interface or resource errors */ ++ uint64_t transport_handle; ++ ++ union { ++ /* messages u -> k */ ++ struct msg_create_session { ++ uint32_t initial_cmdsn; ++ uint16_t cmds_max; ++ uint16_t queue_depth; ++ } c_session; ++ struct msg_create_bound_session { ++ uint64_t ep_handle; ++ uint32_t initial_cmdsn; ++ uint16_t cmds_max; ++ uint16_t queue_depth; ++ } c_bound_session; ++ struct msg_destroy_session { ++ uint32_t sid; ++ } d_session; ++ struct msg_create_conn { ++ uint32_t sid; ++ uint32_t cid; ++ } c_conn; ++ struct msg_bind_conn { ++ uint32_t sid; ++ uint32_t cid; ++ uint64_t transport_eph; ++ uint32_t is_leading; ++ } b_conn; ++ struct msg_destroy_conn { ++ uint32_t sid; ++ uint32_t cid; ++ } d_conn; ++ struct msg_send_pdu { ++ uint32_t sid; ++ uint32_t cid; ++ uint32_t hdr_size; ++ uint32_t data_size; ++ } send_pdu; ++ struct msg_set_param { ++ uint32_t sid; ++ uint32_t cid; ++ uint32_t param; /* enum iscsi_param */ ++ uint32_t len; ++ } set_param; ++ struct msg_start_conn { ++ uint32_t sid; ++ uint32_t cid; ++ } start_conn; ++ struct msg_stop_conn { ++ uint32_t sid; ++ uint32_t cid; ++ uint64_t conn_handle; ++ uint32_t flag; ++ } stop_conn; ++ struct msg_get_stats { ++ uint32_t sid; ++ uint32_t cid; ++ } get_stats; ++ struct msg_transport_connect { ++ uint32_t non_blocking; ++ } ep_connect; ++ struct msg_transport_connect_through_host { ++ uint32_t host_no; ++ uint32_t non_blocking; ++ } ep_connect_through_host; ++ struct msg_transport_poll { ++ uint64_t ep_handle; ++ uint32_t timeout_ms; ++ } ep_poll; ++ struct msg_transport_disconnect { ++ uint64_t ep_handle; ++ } ep_disconnect; ++ struct msg_tgt_dscvr { ++ enum iscsi_tgt_dscvr type; ++ uint32_t host_no; ++ /* ++ * enable = 1 to establish a new connection ++ * with the server. enable = 0 to disconnect ++ * from the server. Used primarily to switch ++ * from one iSNS server to another. ++ */ ++ uint32_t enable; ++ } tgt_dscvr; ++ struct msg_set_host_param { ++ uint32_t host_no; ++ uint32_t param; /* enum iscsi_host_param */ ++ uint32_t len; ++ } set_host_param; ++ struct msg_set_path { ++ uint32_t host_no; ++ } set_path; ++ } u; ++ union { ++ /* messages k -> u */ ++ int retcode; ++ struct msg_create_session_ret { ++ uint32_t sid; ++ uint32_t host_no; ++ } c_session_ret; ++ struct msg_create_conn_ret { ++ uint32_t sid; ++ uint32_t cid; ++ } c_conn_ret; ++ struct msg_unbind_session { ++ uint32_t sid; ++ uint32_t host_no; ++ } unbind_session; ++ struct msg_recv_req { ++ uint32_t sid; ++ uint32_t cid; ++ uint64_t recv_handle; ++ } recv_req; ++ struct msg_conn_error { ++ uint32_t sid; ++ uint32_t cid; ++ uint32_t error; /* enum iscsi_err */ ++ } connerror; ++ struct msg_session_destroyed { ++ uint32_t host_no; ++ uint32_t sid; ++ } d_session; ++ struct msg_transport_connect_ret { ++ uint64_t handle; ++ } ep_connect_ret; ++ struct msg_req_path { ++ uint32_t host_no; ++ } req_path; ++ struct msg_notify_if_down { ++ uint32_t host_no; ++ } notify_if_down; ++ } r; ++} __attribute__ ((aligned (sizeof(uint64_t)))); ++ ++/* ++ * To keep the struct iscsi_uevent size the same for userspace code ++ * compatibility, the main structure for ISCSI_UEVENT_PATH_UPDATE and ++ * ISCSI_KEVENT_PATH_REQ is defined separately and comes after the ++ * struct iscsi_uevent in the NETLINK_ISCSI message. ++ */ ++struct iscsi_path { ++ uint64_t handle; ++ uint8_t mac_addr[6]; ++ uint8_t mac_addr_old[6]; ++ uint32_t ip_addr_len; /* 4 or 16 */ ++ union { ++ struct in_addr v4_addr; ++ struct in6_addr v6_addr; ++ } src; ++ union { ++ struct in_addr v4_addr; ++ struct in6_addr v6_addr; ++ } dst; ++ uint16_t vlan_id; ++ uint16_t pmtu; ++} __attribute__ ((aligned (sizeof(uint64_t)))); ++ ++ ++/* ++ * Common error codes ++ */ ++enum iscsi_err { ++ ISCSI_OK = 0, ++ ++ ISCSI_ERR_DATASN = ISCSI_ERR_BASE + 1, ++ ISCSI_ERR_DATA_OFFSET = ISCSI_ERR_BASE + 2, ++ ISCSI_ERR_MAX_CMDSN = ISCSI_ERR_BASE + 3, ++ ISCSI_ERR_EXP_CMDSN = ISCSI_ERR_BASE + 4, ++ ISCSI_ERR_BAD_OPCODE = ISCSI_ERR_BASE + 5, ++ ISCSI_ERR_DATALEN = ISCSI_ERR_BASE + 6, ++ ISCSI_ERR_AHSLEN = ISCSI_ERR_BASE + 7, ++ ISCSI_ERR_PROTO = ISCSI_ERR_BASE + 8, ++ ISCSI_ERR_LUN = ISCSI_ERR_BASE + 9, ++ ISCSI_ERR_BAD_ITT = ISCSI_ERR_BASE + 10, ++ ISCSI_ERR_CONN_FAILED = ISCSI_ERR_BASE + 11, ++ ISCSI_ERR_R2TSN = ISCSI_ERR_BASE + 12, ++ ISCSI_ERR_SESSION_FAILED = ISCSI_ERR_BASE + 13, ++ ISCSI_ERR_HDR_DGST = ISCSI_ERR_BASE + 14, ++ ISCSI_ERR_DATA_DGST = ISCSI_ERR_BASE + 15, ++ ISCSI_ERR_PARAM_NOT_FOUND = ISCSI_ERR_BASE + 16, ++ ISCSI_ERR_NO_SCSI_CMD = ISCSI_ERR_BASE + 17, ++ ISCSI_ERR_INVALID_HOST = ISCSI_ERR_BASE + 18, ++ ISCSI_ERR_XMIT_FAILED = ISCSI_ERR_BASE + 19, ++}; ++ ++/* ++ * iSCSI Parameters (RFC3720) ++ */ ++enum iscsi_param { ++ /* passed in using netlink set param */ ++ ISCSI_PARAM_MAX_RECV_DLENGTH, ++ ISCSI_PARAM_MAX_XMIT_DLENGTH, ++ ISCSI_PARAM_HDRDGST_EN, ++ ISCSI_PARAM_DATADGST_EN, ++ ISCSI_PARAM_INITIAL_R2T_EN, ++ ISCSI_PARAM_MAX_R2T, ++ ISCSI_PARAM_IMM_DATA_EN, ++ ISCSI_PARAM_FIRST_BURST, ++ ISCSI_PARAM_MAX_BURST, ++ ISCSI_PARAM_PDU_INORDER_EN, ++ ISCSI_PARAM_DATASEQ_INORDER_EN, ++ ISCSI_PARAM_ERL, ++ ISCSI_PARAM_IFMARKER_EN, ++ ISCSI_PARAM_OFMARKER_EN, ++ ISCSI_PARAM_EXP_STATSN, ++ ISCSI_PARAM_TARGET_NAME, ++ ISCSI_PARAM_TPGT, ++ ISCSI_PARAM_PERSISTENT_ADDRESS, ++ ISCSI_PARAM_PERSISTENT_PORT, ++ ISCSI_PARAM_SESS_RECOVERY_TMO, ++ ++ /* pased in through bind conn using transport_fd */ ++ ISCSI_PARAM_CONN_PORT, ++ ISCSI_PARAM_CONN_ADDRESS, ++ ++ ISCSI_PARAM_USERNAME, ++ ISCSI_PARAM_USERNAME_IN, ++ ISCSI_PARAM_PASSWORD, ++ ISCSI_PARAM_PASSWORD_IN, ++ ++ ISCSI_PARAM_FAST_ABORT, ++ ISCSI_PARAM_ABORT_TMO, ++ ISCSI_PARAM_LU_RESET_TMO, ++ ISCSI_PARAM_HOST_RESET_TMO, ++ ++ ISCSI_PARAM_PING_TMO, ++ ISCSI_PARAM_RECV_TMO, ++ ++ ISCSI_PARAM_IFACE_NAME, ++ ISCSI_PARAM_ISID, ++ ISCSI_PARAM_INITIATOR_NAME, ++ /* must always be last */ ++ ISCSI_PARAM_MAX, ++}; ++ ++#define ISCSI_MAX_RECV_DLENGTH (1ULL << ISCSI_PARAM_MAX_RECV_DLENGTH) ++#define ISCSI_MAX_XMIT_DLENGTH (1ULL << ISCSI_PARAM_MAX_XMIT_DLENGTH) ++#define ISCSI_HDRDGST_EN (1ULL << ISCSI_PARAM_HDRDGST_EN) ++#define ISCSI_DATADGST_EN (1ULL << ISCSI_PARAM_DATADGST_EN) ++#define ISCSI_INITIAL_R2T_EN (1ULL << ISCSI_PARAM_INITIAL_R2T_EN) ++#define ISCSI_MAX_R2T (1ULL << ISCSI_PARAM_MAX_R2T) ++#define ISCSI_IMM_DATA_EN (1ULL << ISCSI_PARAM_IMM_DATA_EN) ++#define ISCSI_FIRST_BURST (1ULL << ISCSI_PARAM_FIRST_BURST) ++#define ISCSI_MAX_BURST (1ULL << ISCSI_PARAM_MAX_BURST) ++#define ISCSI_PDU_INORDER_EN (1ULL << ISCSI_PARAM_PDU_INORDER_EN) ++#define ISCSI_DATASEQ_INORDER_EN (1ULL << ISCSI_PARAM_DATASEQ_INORDER_EN) ++#define ISCSI_ERL (1ULL << ISCSI_PARAM_ERL) ++#define ISCSI_IFMARKER_EN (1ULL << ISCSI_PARAM_IFMARKER_EN) ++#define ISCSI_OFMARKER_EN (1ULL << ISCSI_PARAM_OFMARKER_EN) ++#define ISCSI_EXP_STATSN (1ULL << ISCSI_PARAM_EXP_STATSN) ++#define ISCSI_TARGET_NAME (1ULL << ISCSI_PARAM_TARGET_NAME) ++#define ISCSI_TPGT (1ULL << ISCSI_PARAM_TPGT) ++#define ISCSI_PERSISTENT_ADDRESS (1ULL << ISCSI_PARAM_PERSISTENT_ADDRESS) ++#define ISCSI_PERSISTENT_PORT (1ULL << ISCSI_PARAM_PERSISTENT_PORT) ++#define ISCSI_SESS_RECOVERY_TMO (1ULL << ISCSI_PARAM_SESS_RECOVERY_TMO) ++#define ISCSI_CONN_PORT (1ULL << ISCSI_PARAM_CONN_PORT) ++#define ISCSI_CONN_ADDRESS (1ULL << ISCSI_PARAM_CONN_ADDRESS) ++#define ISCSI_USERNAME (1ULL << ISCSI_PARAM_USERNAME) ++#define ISCSI_USERNAME_IN (1ULL << ISCSI_PARAM_USERNAME_IN) ++#define ISCSI_PASSWORD (1ULL << ISCSI_PARAM_PASSWORD) ++#define ISCSI_PASSWORD_IN (1ULL << ISCSI_PARAM_PASSWORD_IN) ++#define ISCSI_FAST_ABORT (1ULL << ISCSI_PARAM_FAST_ABORT) ++#define ISCSI_ABORT_TMO (1ULL << ISCSI_PARAM_ABORT_TMO) ++#define ISCSI_LU_RESET_TMO (1ULL << ISCSI_PARAM_LU_RESET_TMO) ++#define ISCSI_HOST_RESET_TMO (1ULL << ISCSI_PARAM_HOST_RESET_TMO) ++#define ISCSI_PING_TMO (1ULL << ISCSI_PARAM_PING_TMO) ++#define ISCSI_RECV_TMO (1ULL << ISCSI_PARAM_RECV_TMO) ++#define ISCSI_IFACE_NAME (1ULL << ISCSI_PARAM_IFACE_NAME) ++#define ISCSI_ISID (1ULL << ISCSI_PARAM_ISID) ++#define ISCSI_INITIATOR_NAME (1ULL << ISCSI_PARAM_INITIATOR_NAME) ++ ++/* iSCSI HBA params */ ++enum iscsi_host_param { ++ ISCSI_HOST_PARAM_HWADDRESS, ++ ISCSI_HOST_PARAM_INITIATOR_NAME, ++ ISCSI_HOST_PARAM_NETDEV_NAME, ++ ISCSI_HOST_PARAM_IPADDRESS, ++ ISCSI_HOST_PARAM_MAX, ++}; ++ ++#define ISCSI_HOST_HWADDRESS (1ULL << ISCSI_HOST_PARAM_HWADDRESS) ++#define ISCSI_HOST_INITIATOR_NAME (1ULL << ISCSI_HOST_PARAM_INITIATOR_NAME) ++#define ISCSI_HOST_NETDEV_NAME (1ULL << ISCSI_HOST_PARAM_NETDEV_NAME) ++#define ISCSI_HOST_IPADDRESS (1ULL << ISCSI_HOST_PARAM_IPADDRESS) ++ ++#define iscsi_ptr(_handle) ((void*)(unsigned long)_handle) ++#define iscsi_handle(_ptr) ((uint64_t)(unsigned long)_ptr) ++ ++/* ++ * These flags presents iSCSI Data-Path capabilities. ++ */ ++#define CAP_RECOVERY_L0 0x1 ++#define CAP_RECOVERY_L1 0x2 ++#define CAP_RECOVERY_L2 0x4 ++#define CAP_MULTI_R2T 0x8 ++#define CAP_HDRDGST 0x10 ++#define CAP_DATADGST 0x20 ++#define CAP_MULTI_CONN 0x40 ++#define CAP_TEXT_NEGO 0x80 ++#define CAP_MARKERS 0x100 ++#define CAP_FW_DB 0x200 ++#define CAP_SENDTARGETS_OFFLOAD 0x400 /* offload discovery process */ ++#define CAP_DATA_PATH_OFFLOAD 0x800 /* offload entire IO path */ ++#define CAP_DIGEST_OFFLOAD 0x1000 /* offload hdr and data digests */ ++#define CAP_PADDING_OFFLOAD 0x2000 /* offload padding insertion, removal, ++ and verification */ ++ ++/* ++ * These flags describes reason of stop_conn() call ++ */ ++#define STOP_CONN_TERM 0x1 ++#define STOP_CONN_SUSPEND 0x2 ++#define STOP_CONN_RECOVER 0x3 ++ ++#define ISCSI_STATS_CUSTOM_MAX 32 ++#define ISCSI_STATS_CUSTOM_DESC_MAX 64 ++struct iscsi_stats_custom { ++ char desc[ISCSI_STATS_CUSTOM_DESC_MAX]; ++ uint64_t value; ++}; ++ ++/* ++ * struct iscsi_stats - iSCSI Statistics (iSCSI MIB) ++ * ++ * Note: this structure contains counters collected on per-connection basis. ++ */ ++struct iscsi_stats { ++ /* octets */ ++ uint64_t txdata_octets; ++ uint64_t rxdata_octets; ++ ++ /* xmit pdus */ ++ uint32_t noptx_pdus; ++ uint32_t scsicmd_pdus; ++ uint32_t tmfcmd_pdus; ++ uint32_t login_pdus; ++ uint32_t text_pdus; ++ uint32_t dataout_pdus; ++ uint32_t logout_pdus; ++ uint32_t snack_pdus; ++ ++ /* recv pdus */ ++ uint32_t noprx_pdus; ++ uint32_t scsirsp_pdus; ++ uint32_t tmfrsp_pdus; ++ uint32_t textrsp_pdus; ++ uint32_t datain_pdus; ++ uint32_t logoutrsp_pdus; ++ uint32_t r2t_pdus; ++ uint32_t async_pdus; ++ uint32_t rjt_pdus; ++ ++ /* errors */ ++ uint32_t digest_err; ++ uint32_t timeout_err; ++ ++ /* ++ * iSCSI Custom Statistics support, i.e. Transport could ++ * extend existing MIB statistics with its own specific statistics ++ * up to ISCSI_STATS_CUSTOM_MAX ++ */ ++ uint32_t custom_length; ++ struct iscsi_stats_custom custom[0] ++ __attribute__ ((aligned (sizeof(uint64_t)))); ++}; ++ ++/* ++ * Network interface configuration ++ */ ++enum iscsi_net_param { ++ ISCSI_NET_PARAM_UNKNOWN = 0x00, ++ ISCSI_NET_PARAM_MAC_ADDR = ISCSI_NET_PARAM_UNKNOWN + 1, ++ ISCSI_NET_PARAM_IPV4_ADDR = ISCSI_NET_PARAM_UNKNOWN + 2, ++ ISCSI_NET_PARAM_IPV6_ADDR = ISCSI_NET_PARAM_UNKNOWN + 3, ++ ISCSI_NET_PARAM_IPV4_NETMASK = ISCSI_NET_PARAM_UNKNOWN + 4, ++ ISCSI_NET_PARAM_IPV6_NETMASK = ISCSI_NET_PARAM_UNKNOWN + 5, ++ ISCSI_NET_PARAM_IPV4_GATEWAY = ISCSI_NET_PARAM_UNKNOWN + 6, ++ ISCSI_NET_PARAM_IPV6_GATEWAY = ISCSI_NET_PARAM_UNKNOWN + 7, ++ ISCSI_NET_PARAM_BOOTPROTO = ISCSI_NET_PARAM_UNKNOWN + 8, ++ ISCSI_NET_PARAM_IPV6_AUTO_PARAM = ISCSI_NET_PARAM_UNKNOWN + 9, ++ ISCSI_NET_PARAM_MTU = ISCSI_NET_PARAM_UNKNOWN + 10, ++ ISCSI_NET_PARAM_VLAN = ISCSI_NET_PARAM_UNKNOWN + 11, ++}; ++ ++struct iscsi_net_config { ++ uint32_t param; ++ uint32_t length; ++ uint8_t value[1]; ++}; ++ ++#endif +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/include/iscsi_net_util.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/include/iscsi_net_util.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/include/iscsi_net_util.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/include/iscsi_net_util.h 2012-04-09 21:52:14.000000000 -0500 +@@ -0,0 +1,11 @@ ++#ifndef __ISCSI_NET_UTIL_h__ ++#define __ISCSI_NET_UTIL_h__ ++ ++#define ISCSI_HWADDRESS_BUF_SIZE 18 ++ ++extern int net_get_transport_name_from_netdev(char *netdev, char *transport); ++extern int net_get_netdev_from_hwaddress(char *hwaddress, char *netdev); ++extern int net_setup_netdev(char *netdev, char *local_ip, char *mask, ++ char *gateway, char *remote_ip, int needs_bringup); ++ ++#endif +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/include/iscsi_proto.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/include/iscsi_proto.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/include/iscsi_proto.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/include/iscsi_proto.h 2012-04-09 21:52:14.000000000 -0500 +@@ -0,0 +1,637 @@ ++/* ++ * RFC 3720 (iSCSI) protocol data types ++ * ++ * Copyright (C) 2005 Dmitry Yusupov ++ * Copyright (C) 2005 Alex Aizman ++ * maintained by open-iscsi@googlegroups.com ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published ++ * by the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * See the file COPYING included with this distribution for more details. ++ */ ++ ++#ifndef ISCSI_PROTO_H ++#define ISCSI_PROTO_H ++ ++#ifndef __KERNEL__ ++#include ++#endif ++#include ++ ++#define ISCSI_DRAFT20_VERSION 0x00 ++ ++/* default iSCSI listen port for incoming connections */ ++#define ISCSI_LISTEN_PORT 3260 ++ ++/* Padding word length */ ++#define ISCSI_PAD_LEN 4 ++ ++/* ++ * useful common(control and data pathes) macro ++ */ ++#define ntoh24(p) (((p)[0] << 16) | ((p)[1] << 8) | ((p)[2])) ++#define hton24(p, v) { \ ++ p[0] = (((v) >> 16) & 0xFF); \ ++ p[1] = (((v) >> 8) & 0xFF); \ ++ p[2] = ((v) & 0xFF); \ ++} ++#define zero_data(p) {p[0]=0;p[1]=0;p[2]=0;} ++ ++/* ++ * If running svn modules we may need to define these. ++ * This should not go upstream since this is already properly defined there ++ */ ++#ifdef __CHECKER__ ++#define __bitwise__ __attribute__((bitwise)) ++#else ++#define __bitwise__ ++#endif ++#ifdef __CHECK_ENDIAN__ ++#define __bitwise __bitwise__ ++#else ++#define __bitwise ++#endif ++ ++/* initiator tags; opaque for target */ ++typedef uint32_t __bitwise__ itt_t; ++/* below makes sense only for initiator that created this tag */ ++#define build_itt(itt, age) ((__force itt_t)\ ++ ((itt) | ((age) << ISCSI_AGE_SHIFT))) ++#define get_itt(itt) ((__force uint32_t)(itt_t)(itt) & ISCSI_ITT_MASK) ++#define RESERVED_ITT ((__force itt_t)0xffffffff) ++ ++/* ++ * iSCSI Template Message Header ++ */ ++struct iscsi_hdr { ++ uint8_t opcode; ++ uint8_t flags; /* Final bit */ ++ uint8_t rsvd2[2]; ++ uint8_t hlength; /* AHSs total length */ ++ uint8_t dlength[3]; /* Data length */ ++ uint8_t lun[8]; ++ itt_t itt; /* Initiator Task Tag, opaque for target */ ++ __be32 ttt; /* Target Task Tag */ ++ __be32 statsn; ++ __be32 exp_statsn; ++ __be32 max_statsn; ++ uint8_t other[12]; ++}; ++ ++/************************* RFC 3720 Begin *****************************/ ++ ++#define ISCSI_RESERVED_TAG 0xffffffff ++ ++/* Opcode encoding bits */ ++#define ISCSI_OP_RETRY 0x80 ++#define ISCSI_OP_IMMEDIATE 0x40 ++#define ISCSI_OPCODE_MASK 0x3F ++ ++/* Initiator Opcode values */ ++#define ISCSI_OP_NOOP_OUT 0x00 ++#define ISCSI_OP_SCSI_CMD 0x01 ++#define ISCSI_OP_SCSI_TMFUNC 0x02 ++#define ISCSI_OP_LOGIN 0x03 ++#define ISCSI_OP_TEXT 0x04 ++#define ISCSI_OP_SCSI_DATA_OUT 0x05 ++#define ISCSI_OP_LOGOUT 0x06 ++#define ISCSI_OP_SNACK 0x10 ++ ++#define ISCSI_OP_VENDOR1_CMD 0x1c ++#define ISCSI_OP_VENDOR2_CMD 0x1d ++#define ISCSI_OP_VENDOR3_CMD 0x1e ++#define ISCSI_OP_VENDOR4_CMD 0x1f ++ ++/* Target Opcode values */ ++#define ISCSI_OP_NOOP_IN 0x20 ++#define ISCSI_OP_SCSI_CMD_RSP 0x21 ++#define ISCSI_OP_SCSI_TMFUNC_RSP 0x22 ++#define ISCSI_OP_LOGIN_RSP 0x23 ++#define ISCSI_OP_TEXT_RSP 0x24 ++#define ISCSI_OP_SCSI_DATA_IN 0x25 ++#define ISCSI_OP_LOGOUT_RSP 0x26 ++#define ISCSI_OP_R2T 0x31 ++#define ISCSI_OP_ASYNC_EVENT 0x32 ++#define ISCSI_OP_REJECT 0x3f ++ ++struct iscsi_ahs_hdr { ++ __be16 ahslength; ++ uint8_t ahstype; ++ uint8_t ahspec[5]; ++}; ++ ++#define ISCSI_AHSTYPE_CDB 1 ++#define ISCSI_AHSTYPE_RLENGTH 2 ++#define ISCSI_CDB_SIZE 16 ++ ++/* iSCSI PDU Header */ ++struct iscsi_cmd { ++ uint8_t opcode; ++ uint8_t flags; ++ __be16 rsvd2; ++ uint8_t hlength; ++ uint8_t dlength[3]; ++ uint8_t lun[8]; ++ itt_t itt; /* Initiator Task Tag */ ++ __be32 data_length; ++ __be32 cmdsn; ++ __be32 exp_statsn; ++ uint8_t cdb[ISCSI_CDB_SIZE]; /* SCSI Command Block */ ++ /* Additional Data (Command Dependent) */ ++}; ++ ++/* Command PDU flags */ ++#define ISCSI_FLAG_CMD_FINAL 0x80 ++#define ISCSI_FLAG_CMD_READ 0x40 ++#define ISCSI_FLAG_CMD_WRITE 0x20 ++#define ISCSI_FLAG_CMD_ATTR_MASK 0x07 /* 3 bits */ ++ ++/* SCSI Command Attribute values */ ++#define ISCSI_ATTR_UNTAGGED 0 ++#define ISCSI_ATTR_SIMPLE 1 ++#define ISCSI_ATTR_ORDERED 2 ++#define ISCSI_ATTR_HEAD_OF_QUEUE 3 ++#define ISCSI_ATTR_ACA 4 ++ ++struct iscsi_rlength_ahdr { ++ __be16 ahslength; ++ uint8_t ahstype; ++ uint8_t reserved; ++ __be32 read_length; ++}; ++ ++/* Extended CDB AHS */ ++struct iscsi_ecdb_ahdr { ++ __be16 ahslength; /* CDB length - 15, including reserved byte */ ++ uint8_t ahstype; ++ uint8_t reserved; ++ /* 4-byte aligned extended CDB spillover */ ++ uint8_t ecdb[260 - ISCSI_CDB_SIZE]; ++}; ++ ++/* SCSI Response Header */ ++struct iscsi_cmd_rsp { ++ uint8_t opcode; ++ uint8_t flags; ++ uint8_t response; ++ uint8_t cmd_status; ++ uint8_t hlength; ++ uint8_t dlength[3]; ++ uint8_t rsvd[8]; ++ itt_t itt; /* Initiator Task Tag */ ++ __be32 rsvd1; ++ __be32 statsn; ++ __be32 exp_cmdsn; ++ __be32 max_cmdsn; ++ __be32 exp_datasn; ++ __be32 bi_residual_count; ++ __be32 residual_count; ++ /* Response or Sense Data (optional) */ ++}; ++ ++/* Command Response PDU flags */ ++#define ISCSI_FLAG_CMD_BIDI_OVERFLOW 0x10 ++#define ISCSI_FLAG_CMD_BIDI_UNDERFLOW 0x08 ++#define ISCSI_FLAG_CMD_OVERFLOW 0x04 ++#define ISCSI_FLAG_CMD_UNDERFLOW 0x02 ++ ++/* iSCSI Status values. Valid if Rsp Selector bit is not set */ ++#define ISCSI_STATUS_CMD_COMPLETED 0 ++#define ISCSI_STATUS_TARGET_FAILURE 1 ++#define ISCSI_STATUS_SUBSYS_FAILURE 2 ++ ++/* Asynchronous Event Header */ ++struct iscsi_async { ++ uint8_t opcode; ++ uint8_t flags; ++ uint8_t rsvd2[2]; ++ uint8_t rsvd3; ++ uint8_t dlength[3]; ++ uint8_t lun[8]; ++ uint8_t rsvd4[8]; ++ __be32 statsn; ++ __be32 exp_cmdsn; ++ __be32 max_cmdsn; ++ uint8_t async_event; ++ uint8_t async_vcode; ++ __be16 param1; ++ __be16 param2; ++ __be16 param3; ++ uint8_t rsvd5[4]; ++}; ++ ++/* iSCSI Event Codes */ ++#define ISCSI_ASYNC_MSG_SCSI_EVENT 0 ++#define ISCSI_ASYNC_MSG_REQUEST_LOGOUT 1 ++#define ISCSI_ASYNC_MSG_DROPPING_CONNECTION 2 ++#define ISCSI_ASYNC_MSG_DROPPING_ALL_CONNECTIONS 3 ++#define ISCSI_ASYNC_MSG_PARAM_NEGOTIATION 4 ++#define ISCSI_ASYNC_MSG_VENDOR_SPECIFIC 255 ++ ++/* NOP-Out Message */ ++struct iscsi_nopout { ++ uint8_t opcode; ++ uint8_t flags; ++ __be16 rsvd2; ++ uint8_t rsvd3; ++ uint8_t dlength[3]; ++ uint8_t lun[8]; ++ itt_t itt; /* Initiator Task Tag */ ++ __be32 ttt; /* Target Transfer Tag */ ++ __be32 cmdsn; ++ __be32 exp_statsn; ++ uint8_t rsvd4[16]; ++}; ++ ++/* NOP-In Message */ ++struct iscsi_nopin { ++ uint8_t opcode; ++ uint8_t flags; ++ __be16 rsvd2; ++ uint8_t rsvd3; ++ uint8_t dlength[3]; ++ uint8_t lun[8]; ++ itt_t itt; /* Initiator Task Tag */ ++ __be32 ttt; /* Target Transfer Tag */ ++ __be32 statsn; ++ __be32 exp_cmdsn; ++ __be32 max_cmdsn; ++ uint8_t rsvd4[12]; ++}; ++ ++/* SCSI Task Management Message Header */ ++struct iscsi_tm { ++ uint8_t opcode; ++ uint8_t flags; ++ uint8_t rsvd1[2]; ++ uint8_t hlength; ++ uint8_t dlength[3]; ++ uint8_t lun[8]; ++ itt_t itt; /* Initiator Task Tag */ ++ itt_t rtt; /* Reference Task Tag */ ++ __be32 cmdsn; ++ __be32 exp_statsn; ++ __be32 refcmdsn; ++ __be32 exp_datasn; ++ uint8_t rsvd2[8]; ++}; ++ ++#define ISCSI_FLAG_TM_FUNC_MASK 0x7F ++ ++/* Function values */ ++#define ISCSI_TM_FUNC_ABORT_TASK 1 ++#define ISCSI_TM_FUNC_ABORT_TASK_SET 2 ++#define ISCSI_TM_FUNC_CLEAR_ACA 3 ++#define ISCSI_TM_FUNC_CLEAR_TASK_SET 4 ++#define ISCSI_TM_FUNC_LOGICAL_UNIT_RESET 5 ++#define ISCSI_TM_FUNC_TARGET_WARM_RESET 6 ++#define ISCSI_TM_FUNC_TARGET_COLD_RESET 7 ++#define ISCSI_TM_FUNC_TASK_REASSIGN 8 ++ ++/* SCSI Task Management Response Header */ ++struct iscsi_tm_rsp { ++ uint8_t opcode; ++ uint8_t flags; ++ uint8_t response; /* see Response values below */ ++ uint8_t qualifier; ++ uint8_t hlength; ++ uint8_t dlength[3]; ++ uint8_t rsvd2[8]; ++ itt_t itt; /* Initiator Task Tag */ ++ itt_t rtt; /* Reference Task Tag */ ++ __be32 statsn; ++ __be32 exp_cmdsn; ++ __be32 max_cmdsn; ++ uint8_t rsvd3[12]; ++}; ++ ++/* Response values */ ++#define ISCSI_TMF_RSP_COMPLETE 0x00 ++#define ISCSI_TMF_RSP_NO_TASK 0x01 ++#define ISCSI_TMF_RSP_NO_LUN 0x02 ++#define ISCSI_TMF_RSP_TASK_ALLEGIANT 0x03 ++#define ISCSI_TMF_RSP_NO_FAILOVER 0x04 ++#define ISCSI_TMF_RSP_NOT_SUPPORTED 0x05 ++#define ISCSI_TMF_RSP_AUTH_FAILED 0x06 ++#define ISCSI_TMF_RSP_REJECTED 0xff ++ ++/* Ready To Transfer Header */ ++struct iscsi_r2t_rsp { ++ uint8_t opcode; ++ uint8_t flags; ++ uint8_t rsvd2[2]; ++ uint8_t hlength; ++ uint8_t dlength[3]; ++ uint8_t lun[8]; ++ itt_t itt; /* Initiator Task Tag */ ++ __be32 ttt; /* Target Transfer Tag */ ++ __be32 statsn; ++ __be32 exp_cmdsn; ++ __be32 max_cmdsn; ++ __be32 r2tsn; ++ __be32 data_offset; ++ __be32 data_length; ++}; ++ ++/* SCSI Data Hdr */ ++struct iscsi_data { ++ uint8_t opcode; ++ uint8_t flags; ++ uint8_t rsvd2[2]; ++ uint8_t rsvd3; ++ uint8_t dlength[3]; ++ uint8_t lun[8]; ++ itt_t itt; ++ __be32 ttt; ++ __be32 rsvd4; ++ __be32 exp_statsn; ++ __be32 rsvd5; ++ __be32 datasn; ++ __be32 offset; ++ __be32 rsvd6; ++ /* Payload */ ++}; ++ ++/* SCSI Data Response Hdr */ ++struct iscsi_data_rsp { ++ uint8_t opcode; ++ uint8_t flags; ++ uint8_t rsvd2; ++ uint8_t cmd_status; ++ uint8_t hlength; ++ uint8_t dlength[3]; ++ uint8_t lun[8]; ++ itt_t itt; ++ __be32 ttt; ++ __be32 statsn; ++ __be32 exp_cmdsn; ++ __be32 max_cmdsn; ++ __be32 datasn; ++ __be32 offset; ++ __be32 residual_count; ++}; ++ ++/* Data Response PDU flags */ ++#define ISCSI_FLAG_DATA_ACK 0x40 ++#define ISCSI_FLAG_DATA_OVERFLOW 0x04 ++#define ISCSI_FLAG_DATA_UNDERFLOW 0x02 ++#define ISCSI_FLAG_DATA_STATUS 0x01 ++ ++/* Text Header */ ++struct iscsi_text { ++ uint8_t opcode; ++ uint8_t flags; ++ uint8_t rsvd2[2]; ++ uint8_t hlength; ++ uint8_t dlength[3]; ++ uint8_t rsvd4[8]; ++ itt_t itt; ++ __be32 ttt; ++ __be32 cmdsn; ++ __be32 exp_statsn; ++ uint8_t rsvd5[16]; ++ /* Text - key=value pairs */ ++}; ++ ++#define ISCSI_FLAG_TEXT_CONTINUE 0x40 ++ ++/* Text Response Header */ ++struct iscsi_text_rsp { ++ uint8_t opcode; ++ uint8_t flags; ++ uint8_t rsvd2[2]; ++ uint8_t hlength; ++ uint8_t dlength[3]; ++ uint8_t rsvd4[8]; ++ itt_t itt; ++ __be32 ttt; ++ __be32 statsn; ++ __be32 exp_cmdsn; ++ __be32 max_cmdsn; ++ uint8_t rsvd5[12]; ++ /* Text Response - key:value pairs */ ++}; ++ ++/* Login Header */ ++struct iscsi_login { ++ uint8_t opcode; ++ uint8_t flags; ++ uint8_t max_version; /* Max. version supported */ ++ uint8_t min_version; /* Min. version supported */ ++ uint8_t hlength; ++ uint8_t dlength[3]; ++ uint8_t isid[6]; /* Initiator Session ID */ ++ __be16 tsih; /* Target Session Handle */ ++ itt_t itt; /* Initiator Task Tag */ ++ __be16 cid; ++ __be16 rsvd3; ++ __be32 cmdsn; ++ __be32 exp_statsn; ++ uint8_t rsvd5[16]; ++}; ++ ++/* Login PDU flags */ ++#define ISCSI_FLAG_LOGIN_TRANSIT 0x80 ++#define ISCSI_FLAG_LOGIN_CONTINUE 0x40 ++#define ISCSI_FLAG_LOGIN_CURRENT_STAGE_MASK 0x0C /* 2 bits */ ++#define ISCSI_FLAG_LOGIN_NEXT_STAGE_MASK 0x03 /* 2 bits */ ++ ++#define ISCSI_LOGIN_CURRENT_STAGE(flags) \ ++ ((flags & ISCSI_FLAG_LOGIN_CURRENT_STAGE_MASK) >> 2) ++#define ISCSI_LOGIN_NEXT_STAGE(flags) \ ++ (flags & ISCSI_FLAG_LOGIN_NEXT_STAGE_MASK) ++ ++/* Login Response Header */ ++struct iscsi_login_rsp { ++ uint8_t opcode; ++ uint8_t flags; ++ uint8_t max_version; /* Max. version supported */ ++ uint8_t active_version; /* Active version */ ++ uint8_t hlength; ++ uint8_t dlength[3]; ++ uint8_t isid[6]; /* Initiator Session ID */ ++ __be16 tsih; /* Target Session Handle */ ++ itt_t itt; /* Initiator Task Tag */ ++ __be32 rsvd3; ++ __be32 statsn; ++ __be32 exp_cmdsn; ++ __be32 max_cmdsn; ++ uint8_t status_class; /* see Login RSP ststus classes below */ ++ uint8_t status_detail; /* see Login RSP Status details below */ ++ uint8_t rsvd4[10]; ++}; ++ ++/* Login stage (phase) codes for CSG, NSG */ ++#define ISCSI_INITIAL_LOGIN_STAGE -1 ++#define ISCSI_SECURITY_NEGOTIATION_STAGE 0 ++#define ISCSI_OP_PARMS_NEGOTIATION_STAGE 1 ++#define ISCSI_FULL_FEATURE_PHASE 3 ++ ++/* Login Status response classes */ ++#define ISCSI_STATUS_CLS_SUCCESS 0x00 ++#define ISCSI_STATUS_CLS_REDIRECT 0x01 ++#define ISCSI_STATUS_CLS_INITIATOR_ERR 0x02 ++#define ISCSI_STATUS_CLS_TARGET_ERR 0x03 ++ ++/* Login Status response detail codes */ ++/* Class-0 (Success) */ ++#define ISCSI_LOGIN_STATUS_ACCEPT 0x00 ++ ++/* Class-1 (Redirection) */ ++#define ISCSI_LOGIN_STATUS_TGT_MOVED_TEMP 0x01 ++#define ISCSI_LOGIN_STATUS_TGT_MOVED_PERM 0x02 ++ ++/* Class-2 (Initiator Error) */ ++#define ISCSI_LOGIN_STATUS_INIT_ERR 0x00 ++#define ISCSI_LOGIN_STATUS_AUTH_FAILED 0x01 ++#define ISCSI_LOGIN_STATUS_TGT_FORBIDDEN 0x02 ++#define ISCSI_LOGIN_STATUS_TGT_NOT_FOUND 0x03 ++#define ISCSI_LOGIN_STATUS_TGT_REMOVED 0x04 ++#define ISCSI_LOGIN_STATUS_NO_VERSION 0x05 ++#define ISCSI_LOGIN_STATUS_ISID_ERROR 0x06 ++#define ISCSI_LOGIN_STATUS_MISSING_FIELDS 0x07 ++#define ISCSI_LOGIN_STATUS_CONN_ADD_FAILED 0x08 ++#define ISCSI_LOGIN_STATUS_NO_SESSION_TYPE 0x09 ++#define ISCSI_LOGIN_STATUS_NO_SESSION 0x0a ++#define ISCSI_LOGIN_STATUS_INVALID_REQUEST 0x0b ++ ++/* Class-3 (Target Error) */ ++#define ISCSI_LOGIN_STATUS_TARGET_ERROR 0x00 ++#define ISCSI_LOGIN_STATUS_SVC_UNAVAILABLE 0x01 ++#define ISCSI_LOGIN_STATUS_NO_RESOURCES 0x02 ++ ++/* Logout Header */ ++struct iscsi_logout { ++ uint8_t opcode; ++ uint8_t flags; ++ uint8_t rsvd1[2]; ++ uint8_t hlength; ++ uint8_t dlength[3]; ++ uint8_t rsvd2[8]; ++ itt_t itt; /* Initiator Task Tag */ ++ __be16 cid; ++ uint8_t rsvd3[2]; ++ __be32 cmdsn; ++ __be32 exp_statsn; ++ uint8_t rsvd4[16]; ++}; ++ ++/* Logout PDU flags */ ++#define ISCSI_FLAG_LOGOUT_REASON_MASK 0x7F ++ ++/* logout reason_code values */ ++ ++#define ISCSI_LOGOUT_REASON_CLOSE_SESSION 0 ++#define ISCSI_LOGOUT_REASON_CLOSE_CONNECTION 1 ++#define ISCSI_LOGOUT_REASON_RECOVERY 2 ++#define ISCSI_LOGOUT_REASON_AEN_REQUEST 3 ++ ++/* Logout Response Header */ ++struct iscsi_logout_rsp { ++ uint8_t opcode; ++ uint8_t flags; ++ uint8_t response; /* see Logout response values below */ ++ uint8_t rsvd2; ++ uint8_t hlength; ++ uint8_t dlength[3]; ++ uint8_t rsvd3[8]; ++ itt_t itt; /* Initiator Task Tag */ ++ __be32 rsvd4; ++ __be32 statsn; ++ __be32 exp_cmdsn; ++ __be32 max_cmdsn; ++ __be32 rsvd5; ++ __be16 t2wait; ++ __be16 t2retain; ++ __be32 rsvd6; ++}; ++ ++/* logout response status values */ ++ ++#define ISCSI_LOGOUT_SUCCESS 0 ++#define ISCSI_LOGOUT_CID_NOT_FOUND 1 ++#define ISCSI_LOGOUT_RECOVERY_UNSUPPORTED 2 ++#define ISCSI_LOGOUT_CLEANUP_FAILED 3 ++ ++/* SNACK Header */ ++struct iscsi_snack { ++ uint8_t opcode; ++ uint8_t flags; ++ uint8_t rsvd2[14]; ++ itt_t itt; ++ __be32 begrun; ++ __be32 runlength; ++ __be32 exp_statsn; ++ __be32 rsvd3; ++ __be32 exp_datasn; ++ uint8_t rsvd6[8]; ++}; ++ ++/* SNACK PDU flags */ ++#define ISCSI_FLAG_SNACK_TYPE_MASK 0x0F /* 4 bits */ ++ ++/* Reject Message Header */ ++struct iscsi_reject { ++ uint8_t opcode; ++ uint8_t flags; ++ uint8_t reason; ++ uint8_t rsvd2; ++ uint8_t hlength; ++ uint8_t dlength[3]; ++ uint8_t rsvd3[8]; ++ __be32 ffffffff; ++ uint8_t rsvd4[4]; ++ __be32 statsn; ++ __be32 exp_cmdsn; ++ __be32 max_cmdsn; ++ __be32 datasn; ++ uint8_t rsvd5[8]; ++ /* Text - Rejected hdr */ ++}; ++ ++/* Reason for Reject */ ++#define ISCSI_REASON_CMD_BEFORE_LOGIN 1 ++#define ISCSI_REASON_DATA_DIGEST_ERROR 2 ++#define ISCSI_REASON_DATA_SNACK_REJECT 3 ++#define ISCSI_REASON_PROTOCOL_ERROR 4 ++#define ISCSI_REASON_CMD_NOT_SUPPORTED 5 ++#define ISCSI_REASON_IMM_CMD_REJECT 6 ++#define ISCSI_REASON_TASK_IN_PROGRESS 7 ++#define ISCSI_REASON_INVALID_SNACK 8 ++#define ISCSI_REASON_BOOKMARK_INVALID 9 ++#define ISCSI_REASON_BOOKMARK_NO_RESOURCES 10 ++#define ISCSI_REASON_NEGOTIATION_RESET 11 ++ ++/* Max. number of Key=Value pairs in a text message */ ++#define MAX_KEY_VALUE_PAIRS 8192 ++ ++/* maximum length for text keys/values */ ++#define KEY_MAXLEN 64 ++#define VALUE_MAXLEN 255 ++#define TARGET_NAME_MAXLEN VALUE_MAXLEN ++ ++#define ISCSI_DEF_MAX_RECV_SEG_LEN 8192 ++#define ISCSI_MIN_MAX_RECV_SEG_LEN 512 ++#define ISCSI_MAX_MAX_RECV_SEG_LEN 16777215 ++ ++#define ISCSI_DEF_FIRST_BURST_LEN 65536 ++#define ISCSI_MIN_FIRST_BURST_LEN 512 ++#define ISCSI_MAX_FIRST_BURST_LEN 16777215 ++ ++#define ISCSI_DEF_MAX_BURST_LEN 262144 ++#define ISCSI_MIN_MAX_BURST_LEN 512 ++#define ISCSI_MAX_MAX_BURST_LEN 16777215 ++ ++#define ISCSI_DEF_TIME2WAIT 2 ++ ++/************************* RFC 3720 End *****************************/ ++ ++#endif /* ISCSI_PROTO_H */ +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/include/list.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/include/list.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/include/list.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/include/list.h 2012-04-09 21:52:14.000000000 -0500 +@@ -0,0 +1,93 @@ ++#ifndef __LIST_H__ ++#define __LIST_H__ ++ ++#include ++/* taken from linux kernel */ ++ ++#undef offsetof ++#ifdef __compiler_offsetof ++#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER) ++#else ++#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) ++#endif ++ ++#define container_of(ptr, type, member) ({ \ ++ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ ++ (type *)( (char *)__mptr - offsetof(type,member) );}) ++ ++struct list_head { ++ struct list_head *next, *prev; ++}; ++ ++#define LIST_HEAD_INIT(name) { &(name), &(name) } ++ ++#define LIST_HEAD(name) \ ++ struct list_head name = LIST_HEAD_INIT(name) ++ ++static inline void INIT_LIST_HEAD(struct list_head *list) ++{ ++ list->next = list; ++ list->prev = list; ++} ++ ++static inline int list_empty(const struct list_head *head) ++{ ++ return head->next == head; ++} ++ ++#define list_entry(ptr, type, member) \ ++ container_of(ptr, type, member) ++ ++#define list_for_each(pos, head) \ ++ for (pos = (head)->next; pos != (head); pos = pos->next) ++ ++#define list_for_each_entry(pos, head, member) \ ++ for (pos = list_entry((head)->next, typeof(*pos), member); \ ++ &pos->member != (head); \ ++ pos = list_entry(pos->member.next, typeof(*pos), member)) ++ ++#define list_for_each_entry_safe(pos, n, head, member) \ ++ for (pos = list_entry((head)->next, typeof(*pos), member), \ ++ n = list_entry(pos->member.next, typeof(*pos), member); \ ++ &pos->member != (head); \ ++ pos = n, n = list_entry(n->member.next, typeof(*n), member)) ++ ++static inline void __list_add(struct list_head *new, ++ struct list_head *prev, ++ struct list_head *next) ++{ ++ next->prev = new; ++ new->next = next; ++ new->prev = prev; ++ prev->next = new; ++} ++ ++static inline void list_add(struct list_head *new, struct list_head *head) ++{ ++ __list_add(new, head, head->next); ++} ++ ++static inline void list_add_tail(struct list_head *new, struct list_head *head) ++{ ++ __list_add(new, head->prev, head); ++} ++ ++static inline void __list_del(struct list_head * prev, struct list_head * next) ++{ ++ next->prev = prev; ++ prev->next = next; ++} ++ ++static inline void list_del(struct list_head *entry) ++{ ++ __list_del(entry->prev, entry->next); ++ entry->next = entry->prev = NULL; ++} ++ ++static inline void list_del_init(struct list_head *entry) ++{ ++ __list_del(entry->prev, entry->next); ++ INIT_LIST_HEAD(entry); ++} ++ ++#endif +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/include/mgmt_ipc.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/include/mgmt_ipc.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/include/mgmt_ipc.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/include/mgmt_ipc.h 2012-04-09 21:52:14.000000000 -0500 +@@ -0,0 +1,147 @@ ++/* ++ * iSCSI Daemon/Admin Management IPC ++ * ++ * Copyright (C) 2004 Dmitry Yusupov, Alex Aizman ++ * maintained by open-iscsi@googlegroups.com ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published ++ * by the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * See the file COPYING included with this distribution for more details. ++ */ ++#ifndef MGMT_IPC_H ++#define MGMT_IPC_H ++ ++//#include "types.h" ++#include "iscsi_if.h" ++#include "config.h" ++ ++#define ISCSIADM_NAMESPACE "ISCSIADM_ABSTRACT_NAMESPACE" ++#define PEERUSER_MAX 64 ++ ++typedef enum mgmt_ipc_err { ++ MGMT_IPC_OK = 0, ++ MGMT_IPC_ERR = 1, ++ MGMT_IPC_ERR_NOT_FOUND = 2, ++ MGMT_IPC_ERR_NOMEM = 3, ++ MGMT_IPC_ERR_TRANS_FAILURE = 4, ++ MGMT_IPC_ERR_LOGIN_FAILURE = 5, ++ MGMT_IPC_ERR_IDBM_FAILURE = 6, ++ MGMT_IPC_ERR_INVAL = 7, ++ MGMT_IPC_ERR_TRANS_TIMEOUT = 8, ++ MGMT_IPC_ERR_INTERNAL = 9, ++ MGMT_IPC_ERR_LOGOUT_FAILURE = 10, ++ MGMT_IPC_ERR_PDU_TIMEOUT = 11, ++ MGMT_IPC_ERR_TRANS_NOT_FOUND = 12, ++ MGMT_IPC_ERR_ACCESS = 13, ++ MGMT_IPC_ERR_TRANS_CAPS = 14, ++ MGMT_IPC_ERR_EXISTS = 15, ++ MGMT_IPC_ERR_INVALID_REQ = 16, ++ MGMT_IPC_ERR_ISNS_UNAVAILABLE = 17, ++ MGMT_IPC_ERR_ISCSID_COMM_ERR = 18, ++ MGMT_IPC_ERR_FATAL_LOGIN_FAILURE = 19, ++ MGMT_IPC_ERR_ISCSID_NOTCONN = 20, ++} mgmt_ipc_err_e; ++ ++typedef enum iscsiadm_cmd { ++ MGMT_IPC_UNKNOWN = 0, ++ MGMT_IPC_SESSION_LOGIN = 1, ++ MGMT_IPC_SESSION_LOGOUT = 2, ++ MGMT_IPC_SESSION_ACTIVESTAT = 4, ++ MGMT_IPC_CONN_ADD = 5, ++ MGMT_IPC_CONN_REMOVE = 6, ++ MGMT_IPC_SESSION_STATS = 7, ++ MGMT_IPC_CONFIG_INAME = 8, ++ MGMT_IPC_CONFIG_IALIAS = 9, ++ MGMT_IPC_CONFIG_FILE = 10, ++ MGMT_IPC_IMMEDIATE_STOP = 11, ++ MGMT_IPC_SESSION_SYNC = 12, ++ MGMT_IPC_SESSION_INFO = 13, ++ MGMT_IPC_ISNS_DEV_ATTR_QUERY = 14, ++ MGMT_IPC_SEND_TARGETS = 15, ++ MGMT_IPC_SET_HOST_PARAM = 16, ++ MGMT_IPC_NOTIFY_ADD_NODE = 17, ++ MGMT_IPC_NOTIFY_DEL_NODE = 18, ++ MGMT_IPC_NOTIFY_ADD_PORTAL = 19, ++ MGMT_IPC_NOTIFY_DEL_PORTAL = 20, ++ MGMT_IPC_GET_IPADDR = 21, ++ ++ __MGMT_IPC_MAX_COMMAND ++} iscsiadm_cmd_e; ++ ++/* IPC Request */ ++typedef struct iscsiadm_req { ++ iscsiadm_cmd_e command; ++ uint32_t payload_len; ++ ++ union { ++ /* messages */ ++ struct ipc_msg_session { ++ int sid; ++// node_rec_t rec; ++ } session; ++ struct ipc_msg_conn { ++ int sid; ++ int cid; ++ } conn; ++ struct ipc_msg_send_targets { ++ int host_no; ++ int do_login; ++ struct sockaddr_storage ss; ++ } st; ++ struct ipc_msg_set_host_param { ++ int host_no; ++ int param; ++ /* TODO: make this variable len to support */ ++ char value[IFNAMSIZ + 1]; ++ ++ } set_host_param; ++ } u; ++} iscsiadm_req_t; ++ ++/* IPC Response */ ++typedef struct iscsiadm_rsp { ++ iscsiadm_cmd_e command; ++ mgmt_ipc_err_e err; ++ ++ union { ++#define MGMT_IPC_GETSTATS_BUF_MAX (sizeof(struct iscsi_uevent) + \ ++ sizeof(struct iscsi_stats) + \ ++ sizeof(struct iscsi_stats_custom) * \ ++ ISCSI_STATS_CUSTOM_MAX) ++ struct ipc_msg_getstats { ++ struct iscsi_uevent ev; ++ struct iscsi_stats stats; ++ char custom[sizeof(struct iscsi_stats_custom) * ++ ISCSI_STATS_CUSTOM_MAX]; ++ } getstats; ++ struct ipc_msg_config { ++ char var[VALUE_MAXLEN]; ++ } config; ++ struct ipc_msg_session_state { ++ int session_state; ++ int conn_state; ++ } session_state; ++ struct ipc_msg_get_ipaddr { ++ int addr; ++ } get_ipaddr; ++ } u; ++} iscsiadm_rsp_t; ++ ++struct queue_task; ++typedef mgmt_ipc_err_e mgmt_ipc_fn_t(struct queue_task *); ++ ++struct queue_task; ++void mgmt_ipc_write_rsp(struct queue_task *qtask, mgmt_ipc_err_e err); ++int mgmt_ipc_listen(void); ++void mgmt_ipc_close(int fd); ++void mgmt_ipc_handle(int accept_fd); ++ ++#endif /* MGMT_IPC_H */ +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/include/sysdeps.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/include/sysdeps.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/include/sysdeps.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/include/sysdeps.h 2012-04-09 21:52:14.000000000 -0500 +@@ -0,0 +1,27 @@ ++/* ++ * wrapping of libc features and kernel interfaces ++ * ++ * Copyright (C) 2005-2006 Kay Sievers ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation version 2 of the License. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ * ++ */ ++ ++#ifndef _SYSDEPS_H_ ++#define _SYSDEPS_H_ ++ ++extern size_t strlcpy(char *dst, const char *src, size_t size); ++extern size_t strlcat(char *dst, const char *src, size_t size); ++ ++#endif +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/include/uip_mgmt_ipc.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/include/uip_mgmt_ipc.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/include/uip_mgmt_ipc.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/include/uip_mgmt_ipc.h 2012-04-09 21:52:14.000000000 -0500 +@@ -0,0 +1,66 @@ ++/* ++ * uIP iSCSI Daemon/Admin Management IPC ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published ++ * by the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * See the file COPYING included with this distribution for more details. ++ */ ++#ifndef UIP_MGMT_IPC_H ++#define UIP_MGMT_IPC_H ++ ++//#include "types.h" ++#include "iscsi_if.h" ++#include "config.h" ++#include "mgmt_ipc.h" ++ ++#define ISCSID_UIP_NAMESPACE "ISCSID_UIP_ABSTRACT_NAMESPACE" ++ ++typedef enum iscsid_uip_cmd { ++ ISCSID_UIP_IPC_UNKNOWN = 0, ++ ISCSID_UIP_IPC_GET_IFACE = 1, ++ ++ __ISCSID_UIP_IPC_MAX_COMMAND ++} iscsid_uip_cmd_e; ++ ++ ++typedef struct iscsid_uip_broadcast_header { ++ iscsid_uip_cmd_e command; ++ uint32_t payload_len; ++} iscsid_uip_broadcast_header_t; ++ ++/* IPC Request */ ++typedef struct iscsid_uip_broadcast { ++ struct iscsid_uip_broadcast_header header; ++ ++ union { ++ /* messages */ ++ struct ipc_broadcast_iface_rec { ++ struct iface_rec rec; ++ } iface_rec; ++ } u; ++} iscsid_uip_broadcast_t; ++ ++typedef enum iscsid_uip_mgmt_ipc_err { ++ ISCSID_UIP_MGMT_IPC_OK = 0, ++ ISCSID_UIP_MGMT_IPC_ERR = 1, ++ ISCSID_UIP_MGMT_IPC_ERR_NOT_FOUND = 2, ++ ISCSID_UIP_MGMT_IPC_ERR_NOMEM = 3, ++ ISCSID_UIP_MGMT_IPC_DEVICE_UP = 4, ++ ISCSID_UIP_MGMT_IPC_DEVICE_INITIALIZING = 5, ++} iscsid_uip_mgmt_ipc_err_e; ++ ++/* IPC Response */ ++typedef struct iscsid_uip_mgmt_rsp { ++ iscsid_uip_cmd_e command; ++ iscsid_uip_mgmt_ipc_err_e err; ++} iscsid_uip_rsp_t; ++ ++#endif /* UIP_MGMT_IPC_H */ +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/INSTALL open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/INSTALL +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/INSTALL 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/INSTALL 2012-04-09 21:52:14.000000000 -0500 +@@ -0,0 +1,291 @@ ++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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/install-sh open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/install-sh +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/install-sh 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/install-sh 2012-04-09 21:52:14.000000000 -0500 +@@ -0,0 +1,519 @@ ++#!/bin/sh ++# install - install a program, script, or datafile ++ ++scriptversion=2006-12-25.00 ++ ++# This originates from X11R5 (mit/util/scripts/install.sh), which was ++# later released in X11R6 (xc/config/util/install.sh) with the ++# following copyright and license. ++# ++# Copyright (C) 1994 X Consortium ++# ++# Permission is hereby granted, free of charge, to any person obtaining a copy ++# of this software and associated documentation files (the "Software"), to ++# deal in the Software without restriction, including without limitation the ++# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or ++# sell copies of the Software, and to permit persons to whom the Software is ++# furnished to do so, subject to the following conditions: ++# ++# The above copyright notice and this permission notice shall be included in ++# all copies or substantial portions of the Software. ++# ++# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN ++# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- ++# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++# ++# Except as contained in this notice, the name of the X Consortium shall not ++# be used in advertising or otherwise to promote the sale, use or other deal- ++# ings in this Software without prior written authorization from the X Consor- ++# tium. ++# ++# ++# FSF changes to this file are in the public domain. ++# ++# Calling this script install-sh is preferred over install.sh, to prevent ++# `make' implicit rules from creating a file called install from it ++# when there is no Makefile. ++# ++# This script is compatible with the BSD install script, but was written ++# from scratch. ++ ++nl=' ++' ++IFS=" "" $nl" ++ ++# set DOITPROG to echo to test this script ++ ++# Don't use :- since 4.3BSD and earlier shells don't like it. ++doit=${DOITPROG-} ++if test -z "$doit"; then ++ doit_exec=exec ++else ++ doit_exec=$doit ++fi ++ ++# Put in absolute file names if you don't have them in your path; ++# or use environment vars. ++ ++chgrpprog=${CHGRPPROG-chgrp} ++chmodprog=${CHMODPROG-chmod} ++chownprog=${CHOWNPROG-chown} ++cmpprog=${CMPPROG-cmp} ++cpprog=${CPPROG-cp} ++mkdirprog=${MKDIRPROG-mkdir} ++mvprog=${MVPROG-mv} ++rmprog=${RMPROG-rm} ++stripprog=${STRIPPROG-strip} ++ ++posix_glob='?' ++initialize_posix_glob=' ++ test "$posix_glob" != "?" || { ++ if (set -f) 2>/dev/null; then ++ posix_glob= ++ else ++ posix_glob=: ++ fi ++ } ++' ++ ++posix_mkdir= ++ ++# Desired mode of installed file. ++mode=0755 ++ ++chgrpcmd= ++chmodcmd=$chmodprog ++chowncmd= ++mvcmd=$mvprog ++rmcmd="$rmprog -f" ++stripcmd= ++ ++src= ++dst= ++dir_arg= ++dst_arg= ++ ++copy_on_change=false ++no_target_directory= ++ ++usage="\ ++Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE ++ or: $0 [OPTION]... SRCFILES... DIRECTORY ++ or: $0 [OPTION]... -t DIRECTORY SRCFILES... ++ or: $0 [OPTION]... -d DIRECTORIES... ++ ++In the 1st form, copy SRCFILE to DSTFILE. ++In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. ++In the 4th, create DIRECTORIES. ++ ++Options: ++ --help display this help and exit. ++ --version display version info and exit. ++ ++ -c (ignored) ++ -C install only if different (preserve the last data modification time) ++ -d create directories instead of installing files. ++ -g GROUP $chgrpprog installed files to GROUP. ++ -m MODE $chmodprog installed files to MODE. ++ -o USER $chownprog installed files to USER. ++ -s $stripprog installed files. ++ -t DIRECTORY install into DIRECTORY. ++ -T report an error if DSTFILE is a directory. ++ ++Environment variables override the default commands: ++ CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG ++ RMPROG STRIPPROG ++" ++ ++while test $# -ne 0; do ++ case $1 in ++ -c) ;; ++ ++ -C) copy_on_change=true;; ++ ++ -d) dir_arg=true;; ++ ++ -g) chgrpcmd="$chgrpprog $2" ++ shift;; ++ ++ --help) echo "$usage"; exit $?;; ++ ++ -m) mode=$2 ++ case $mode in ++ *' '* | *' '* | *' ++'* | *'*'* | *'?'* | *'['*) ++ echo "$0: invalid mode: $mode" >&2 ++ exit 1;; ++ esac ++ shift;; ++ ++ -o) chowncmd="$chownprog $2" ++ shift;; ++ ++ -s) stripcmd=$stripprog;; ++ ++ -t) dst_arg=$2 ++ shift;; ++ ++ -T) no_target_directory=true;; ++ ++ --version) echo "$0 $scriptversion"; exit $?;; ++ ++ --) shift ++ break;; ++ ++ -*) echo "$0: invalid option: $1" >&2 ++ exit 1;; ++ ++ *) break;; ++ esac ++ shift ++done ++ ++if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then ++ # When -d is used, all remaining arguments are directories to create. ++ # When -t is used, the destination is already specified. ++ # Otherwise, the last argument is the destination. Remove it from $@. ++ for arg ++ do ++ if test -n "$dst_arg"; then ++ # $@ is not empty: it contains at least $arg. ++ set fnord "$@" "$dst_arg" ++ shift # fnord ++ fi ++ shift # arg ++ dst_arg=$arg ++ done ++fi ++ ++if test $# -eq 0; then ++ if test -z "$dir_arg"; then ++ echo "$0: no input file specified." >&2 ++ exit 1 ++ fi ++ # It's OK to call `install-sh -d' without argument. ++ # This can happen when creating conditional directories. ++ exit 0 ++fi ++ ++if test -z "$dir_arg"; then ++ trap '(exit $?); exit' 1 2 13 15 ++ ++ # Set umask so as not to create temps with too-generous modes. ++ # However, 'strip' requires both read and write access to temps. ++ case $mode in ++ # Optimize common cases. ++ *644) cp_umask=133;; ++ *755) cp_umask=22;; ++ ++ *[0-7]) ++ if test -z "$stripcmd"; then ++ u_plus_rw= ++ else ++ u_plus_rw='% 200' ++ fi ++ cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; ++ *) ++ if test -z "$stripcmd"; then ++ u_plus_rw= ++ else ++ u_plus_rw=,u+rw ++ fi ++ cp_umask=$mode$u_plus_rw;; ++ esac ++fi ++ ++for src ++do ++ # Protect names starting with `-'. ++ case $src in ++ -*) src=./$src;; ++ esac ++ ++ if test -n "$dir_arg"; then ++ dst=$src ++ dstdir=$dst ++ test -d "$dstdir" ++ dstdir_status=$? ++ else ++ ++ # Waiting for this to be detected by the "$cpprog $src $dsttmp" command ++ # might cause directories to be created, which would be especially bad ++ # if $src (and thus $dsttmp) contains '*'. ++ if test ! -f "$src" && test ! -d "$src"; then ++ echo "$0: $src does not exist." >&2 ++ exit 1 ++ fi ++ ++ if test -z "$dst_arg"; then ++ echo "$0: no destination specified." >&2 ++ exit 1 ++ fi ++ ++ dst=$dst_arg ++ # Protect names starting with `-'. ++ case $dst in ++ -*) dst=./$dst;; ++ esac ++ ++ # If destination is a directory, append the input filename; won't work ++ # if double slashes aren't ignored. ++ if test -d "$dst"; then ++ if test -n "$no_target_directory"; then ++ echo "$0: $dst_arg: Is a directory" >&2 ++ exit 1 ++ fi ++ dstdir=$dst ++ dst=$dstdir/`basename "$src"` ++ dstdir_status=0 ++ else ++ # Prefer dirname, but fall back on a substitute if dirname fails. ++ dstdir=` ++ (dirname "$dst") 2>/dev/null || ++ expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ ++ X"$dst" : 'X\(//\)[^/]' \| \ ++ X"$dst" : 'X\(//\)$' \| \ ++ X"$dst" : 'X\(/\)' \| . 2>/dev/null || ++ echo X"$dst" | ++ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\/\)[^/].*/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\/\)$/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\).*/{ ++ s//\1/ ++ q ++ } ++ s/.*/./; q' ++ ` ++ ++ test -d "$dstdir" ++ dstdir_status=$? ++ fi ++ fi ++ ++ obsolete_mkdir_used=false ++ ++ if test $dstdir_status != 0; then ++ case $posix_mkdir in ++ '') ++ # Create intermediate dirs using mode 755 as modified by the umask. ++ # This is like FreeBSD 'install' as of 1997-10-28. ++ umask=`umask` ++ case $stripcmd.$umask in ++ # Optimize common cases. ++ *[2367][2367]) mkdir_umask=$umask;; ++ .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; ++ ++ *[0-7]) ++ mkdir_umask=`expr $umask + 22 \ ++ - $umask % 100 % 40 + $umask % 20 \ ++ - $umask % 10 % 4 + $umask % 2 ++ `;; ++ *) mkdir_umask=$umask,go-w;; ++ esac ++ ++ # With -d, create the new directory with the user-specified mode. ++ # Otherwise, rely on $mkdir_umask. ++ if test -n "$dir_arg"; then ++ mkdir_mode=-m$mode ++ else ++ mkdir_mode= ++ fi ++ ++ posix_mkdir=false ++ case $umask in ++ *[123567][0-7][0-7]) ++ # POSIX mkdir -p sets u+wx bits regardless of umask, which ++ # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ++ ;; ++ *) ++ tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ ++ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 ++ ++ if (umask $mkdir_umask && ++ exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 ++ then ++ if test -z "$dir_arg" || { ++ # Check for POSIX incompatibilities with -m. ++ # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or ++ # other-writeable bit of parent directory when it shouldn't. ++ # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ++ ls_ld_tmpdir=`ls -ld "$tmpdir"` ++ case $ls_ld_tmpdir in ++ d????-?r-*) different_mode=700;; ++ d????-?--*) different_mode=755;; ++ *) false;; ++ esac && ++ $mkdirprog -m$different_mode -p -- "$tmpdir" && { ++ ls_ld_tmpdir_1=`ls -ld "$tmpdir"` ++ test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" ++ } ++ } ++ then posix_mkdir=: ++ fi ++ rmdir "$tmpdir/d" "$tmpdir" ++ else ++ # Remove any dirs left behind by ancient mkdir implementations. ++ rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null ++ fi ++ trap '' 0;; ++ esac;; ++ esac ++ ++ if ++ $posix_mkdir && ( ++ umask $mkdir_umask && ++ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ++ ) ++ then : ++ else ++ ++ # The umask is ridiculous, or mkdir does not conform to POSIX, ++ # or it failed possibly due to a race condition. Create the ++ # directory the slow way, step by step, checking for races as we go. ++ ++ case $dstdir in ++ /*) prefix='/';; ++ -*) prefix='./';; ++ *) prefix='';; ++ esac ++ ++ eval "$initialize_posix_glob" ++ ++ oIFS=$IFS ++ IFS=/ ++ $posix_glob set -f ++ set fnord $dstdir ++ shift ++ $posix_glob set +f ++ IFS=$oIFS ++ ++ prefixes= ++ ++ for d ++ do ++ test -z "$d" && continue ++ ++ prefix=$prefix$d ++ if test -d "$prefix"; then ++ prefixes= ++ else ++ if $posix_mkdir; then ++ (umask=$mkdir_umask && ++ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break ++ # Don't fail if two instances are running concurrently. ++ test -d "$prefix" || exit 1 ++ else ++ case $prefix in ++ *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; ++ *) qprefix=$prefix;; ++ esac ++ prefixes="$prefixes '$qprefix'" ++ fi ++ fi ++ prefix=$prefix/ ++ done ++ ++ if test -n "$prefixes"; then ++ # Don't fail if two instances are running concurrently. ++ (umask $mkdir_umask && ++ eval "\$doit_exec \$mkdirprog $prefixes") || ++ test -d "$dstdir" || exit 1 ++ obsolete_mkdir_used=true ++ fi ++ fi ++ fi ++ ++ if test -n "$dir_arg"; then ++ { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && ++ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && ++ { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || ++ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 ++ else ++ ++ # Make a couple of temp file names in the proper directory. ++ dsttmp=$dstdir/_inst.$$_ ++ rmtmp=$dstdir/_rm.$$_ ++ ++ # Trap to clean up those temp files at exit. ++ trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 ++ ++ # Copy the file name to the temp name. ++ (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && ++ ++ # and set any options; do chmod last to preserve setuid bits. ++ # ++ # If any of these fail, we abort the whole thing. If we want to ++ # ignore errors from any of these, just make sure not to ignore ++ # errors from the above "$doit $cpprog $src $dsttmp" command. ++ # ++ { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && ++ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && ++ { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && ++ { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && ++ ++ # If -C, don't bother to copy if it wouldn't change the file. ++ if $copy_on_change && ++ old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && ++ new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && ++ ++ eval "$initialize_posix_glob" && ++ $posix_glob set -f && ++ set X $old && old=:$2:$4:$5:$6 && ++ set X $new && new=:$2:$4:$5:$6 && ++ $posix_glob set +f && ++ ++ test "$old" = "$new" && ++ $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 ++ then ++ rm -f "$dsttmp" ++ else ++ # Rename the file to the real destination. ++ $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || ++ ++ # The rename failed, perhaps because mv can't rename something else ++ # to itself, or perhaps because mv is so ancient that it does not ++ # support -f. ++ { ++ # Now remove or move aside any old file at destination location. ++ # We try this two ways since rm can't unlink itself on some ++ # systems and the destination file might be busy for other ++ # reasons. In this case, the final cleanup might fail but the new ++ # file should still install successfully. ++ { ++ test ! -f "$dst" || ++ $doit $rmcmd -f "$dst" 2>/dev/null || ++ { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && ++ { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } ++ } || ++ { echo "$0: cannot unlink or rename $dst" >&2 ++ (exit 1); exit 1 ++ } ++ } && ++ ++ # Now rename the file to the real destination. ++ $doit $mvcmd "$dsttmp" "$dst" ++ } ++ fi || exit 1 ++ ++ trap '' 0 ++ fi ++done ++ ++# Local variables: ++# eval: (add-hook 'write-file-hooks 'time-stamp) ++# time-stamp-start: "scriptversion=" ++# time-stamp-format: "%:y-%02m-%02d.%02H" ++# time-stamp-end: "$" ++# End: +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/iscsiuiolog open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/iscsiuiolog +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/iscsiuiolog 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/iscsiuiolog 2012-04-09 21:52:14.000000000 -0500 +@@ -0,0 +1,11 @@ ++/var/log/iscsiuio.log { ++ weekly ++ missingok ++ notifempty ++ rotate 4 ++ sharedscripts ++ postrotate ++ pkill -USR1 iscsiuio 2> /dev/null || true ++ endscript ++} ++ +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/ltmain.sh open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/ltmain.sh +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/ltmain.sh 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/ltmain.sh 2012-04-09 21:52:14.000000000 -0500 +@@ -0,0 +1,6911 @@ ++# ltmain.sh - Provide generalized library-building support services. ++# NOTE: Changing this file will not affect anything until you rerun configure. ++# ++# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005 ++# Free Software Foundation, Inc. ++# Originally by Gordon Matzigkeit , 1996 ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++# ++# As a special exception to the GNU General Public License, if you ++# distribute this file as part of a program that contains a ++# configuration script generated by Autoconf, you may include it under ++# the same distribution terms that you use for the rest of that program. ++ ++basename="s,^.*/,,g" ++ ++# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh ++# is ksh but when the shell is invoked as "sh" and the current value of ++# the _XPG environment variable is not equal to 1 (one), the special ++# positional parameter $0, within a function call, is the name of the ++# function. ++progpath="$0" ++ ++# The name of this program: ++progname=`echo "$progpath" | $SED $basename` ++modename="$progname" ++ ++# Global variables: ++EXIT_SUCCESS=0 ++EXIT_FAILURE=1 ++ ++PROGRAM=ltmain.sh ++PACKAGE=libtool ++VERSION=1.5.22 ++TIMESTAMP=" (1.1220.2.365 2005/12/18 22:14:06)" ++ ++# Be Bourne compatible (taken from Autoconf:_AS_BOURNE_COMPATIBLE). ++if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then ++ emulate sh ++ NULLCMD=: ++ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which ++ # is contrary to our usage. Disable this feature. ++ alias -g '${1+"$@"}'='"$@"' ++ setopt NO_GLOB_SUBST ++else ++ case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac ++fi ++ ++# Check that we have a working $echo. ++if test "X$1" = X--no-reexec; then ++ # Discard the --no-reexec flag, and continue. ++ shift ++elif test "X$1" = X--fallback-echo; then ++ # Avoid inline document here, it may be left over ++ : ++elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then ++ # Yippee, $echo works! ++ : ++else ++ # Restart under the correct shell, and then maybe $echo will work. ++ exec $SHELL "$progpath" --no-reexec ${1+"$@"} ++fi ++ ++if test "X$1" = X--fallback-echo; then ++ # used as fallback echo ++ shift ++ cat <&2 ++ $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 ++ exit $EXIT_FAILURE ++fi ++ ++# Global variables. ++mode=$default_mode ++nonopt= ++prev= ++prevopt= ++run= ++show="$echo" ++show_help= ++execute_dlfiles= ++duplicate_deps=no ++preserve_args= ++lo2o="s/\\.lo\$/.${objext}/" ++o2lo="s/\\.${objext}\$/.lo/" ++extracted_archives= ++extracted_serial=0 ++ ++##################################### ++# Shell function definitions: ++# This seems to be the best place for them ++ ++# func_mktempdir [string] ++# Make a temporary directory that won't clash with other running ++# libtool processes, and avoids race conditions if possible. If ++# given, STRING is the basename for that directory. ++func_mktempdir () ++{ ++ my_template="${TMPDIR-/tmp}/${1-$progname}" ++ ++ if test "$run" = ":"; then ++ # Return a directory name, but don't create it in dry-run mode ++ my_tmpdir="${my_template}-$$" ++ else ++ ++ # If mktemp works, use that first and foremost ++ my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` ++ ++ if test ! -d "$my_tmpdir"; then ++ # Failing that, at least try and use $RANDOM to avoid a race ++ my_tmpdir="${my_template}-${RANDOM-0}$$" ++ ++ save_mktempdir_umask=`umask` ++ umask 0077 ++ $mkdir "$my_tmpdir" ++ umask $save_mktempdir_umask ++ fi ++ ++ # If we're not in dry-run mode, bomb out on failure ++ test -d "$my_tmpdir" || { ++ $echo "cannot create temporary directory \`$my_tmpdir'" 1>&2 ++ exit $EXIT_FAILURE ++ } ++ fi ++ ++ $echo "X$my_tmpdir" | $Xsed ++} ++ ++ ++# func_win32_libid arg ++# return the library type of file 'arg' ++# ++# Need a lot of goo to handle *both* DLLs and import libs ++# Has to be a shell function in order to 'eat' the argument ++# that is supplied when $file_magic_command is called. ++func_win32_libid () ++{ ++ win32_libid_type="unknown" ++ win32_fileres=`file -L $1 2>/dev/null` ++ case $win32_fileres in ++ *ar\ archive\ import\ library*) # definitely import ++ win32_libid_type="x86 archive import" ++ ;; ++ *ar\ archive*) # could be an import, or static ++ if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | \ ++ $EGREP -e 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then ++ win32_nmres=`eval $NM -f posix -A $1 | \ ++ $SED -n -e '1,100{/ I /{s,.*,import,;p;q;};}'` ++ case $win32_nmres in ++ import*) win32_libid_type="x86 archive import";; ++ *) win32_libid_type="x86 archive static";; ++ esac ++ fi ++ ;; ++ *DLL*) ++ win32_libid_type="x86 DLL" ++ ;; ++ *executable*) # but shell scripts are "executable" too... ++ case $win32_fileres in ++ *MS\ Windows\ PE\ Intel*) ++ win32_libid_type="x86 DLL" ++ ;; ++ esac ++ ;; ++ esac ++ $echo $win32_libid_type ++} ++ ++ ++# func_infer_tag arg ++# Infer tagged configuration to use if any are available and ++# if one wasn't chosen via the "--tag" command line option. ++# Only attempt this if the compiler in the base compile ++# command doesn't match the default compiler. ++# arg is usually of the form 'gcc ...' ++func_infer_tag () ++{ ++ if test -n "$available_tags" && test -z "$tagname"; then ++ CC_quoted= ++ for arg in $CC; do ++ case $arg in ++ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") ++ arg="\"$arg\"" ++ ;; ++ esac ++ CC_quoted="$CC_quoted $arg" ++ done ++ case $@ in ++ # Blanks in the command may have been stripped by the calling shell, ++ # but not from the CC environment variable when configure was run. ++ " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) ;; ++ # Blanks at the start of $base_compile will cause this to fail ++ # if we don't check for them as well. ++ *) ++ for z in $available_tags; do ++ if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then ++ # Evaluate the configuration. ++ eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" ++ CC_quoted= ++ for arg in $CC; do ++ # Double-quote args containing other shell metacharacters. ++ case $arg in ++ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") ++ arg="\"$arg\"" ++ ;; ++ esac ++ CC_quoted="$CC_quoted $arg" ++ done ++ case "$@ " in ++ " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) ++ # The compiler in the base compile command matches ++ # the one in the tagged configuration. ++ # Assume this is the tagged configuration we want. ++ tagname=$z ++ break ++ ;; ++ esac ++ fi ++ done ++ # If $tagname still isn't set, then no tagged configuration ++ # was found and let the user know that the "--tag" command ++ # line option must be used. ++ if test -z "$tagname"; then ++ $echo "$modename: unable to infer tagged configuration" ++ $echo "$modename: specify a tag with \`--tag'" 1>&2 ++ exit $EXIT_FAILURE ++# else ++# $echo "$modename: using $tagname tagged configuration" ++ fi ++ ;; ++ esac ++ fi ++} ++ ++ ++# func_extract_an_archive dir oldlib ++func_extract_an_archive () ++{ ++ f_ex_an_ar_dir="$1"; shift ++ f_ex_an_ar_oldlib="$1" ++ ++ $show "(cd $f_ex_an_ar_dir && $AR x $f_ex_an_ar_oldlib)" ++ $run eval "(cd \$f_ex_an_ar_dir && $AR x \$f_ex_an_ar_oldlib)" || exit $? ++ if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then ++ : ++ else ++ $echo "$modename: ERROR: object name conflicts: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++} ++ ++# func_extract_archives gentop oldlib ... ++func_extract_archives () ++{ ++ my_gentop="$1"; shift ++ my_oldlibs=${1+"$@"} ++ my_oldobjs="" ++ my_xlib="" ++ my_xabs="" ++ my_xdir="" ++ my_status="" ++ ++ $show "${rm}r $my_gentop" ++ $run ${rm}r "$my_gentop" ++ $show "$mkdir $my_gentop" ++ $run $mkdir "$my_gentop" ++ my_status=$? ++ if test "$my_status" -ne 0 && test ! -d "$my_gentop"; then ++ exit $my_status ++ fi ++ ++ for my_xlib in $my_oldlibs; do ++ # Extract the objects. ++ case $my_xlib in ++ [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; ++ *) my_xabs=`pwd`"/$my_xlib" ;; ++ esac ++ my_xlib=`$echo "X$my_xlib" | $Xsed -e 's%^.*/%%'` ++ my_xlib_u=$my_xlib ++ while :; do ++ case " $extracted_archives " in ++ *" $my_xlib_u "*) ++ extracted_serial=`expr $extracted_serial + 1` ++ my_xlib_u=lt$extracted_serial-$my_xlib ;; ++ *) break ;; ++ esac ++ done ++ extracted_archives="$extracted_archives $my_xlib_u" ++ my_xdir="$my_gentop/$my_xlib_u" ++ ++ $show "${rm}r $my_xdir" ++ $run ${rm}r "$my_xdir" ++ $show "$mkdir $my_xdir" ++ $run $mkdir "$my_xdir" ++ exit_status=$? ++ if test "$exit_status" -ne 0 && test ! -d "$my_xdir"; then ++ exit $exit_status ++ fi ++ case $host in ++ *-darwin*) ++ $show "Extracting $my_xabs" ++ # Do not bother doing anything if just a dry run ++ if test -z "$run"; then ++ darwin_orig_dir=`pwd` ++ cd $my_xdir || exit $? ++ darwin_archive=$my_xabs ++ darwin_curdir=`pwd` ++ darwin_base_archive=`$echo "X$darwin_archive" | $Xsed -e 's%^.*/%%'` ++ darwin_arches=`lipo -info "$darwin_archive" 2>/dev/null | $EGREP Architectures 2>/dev/null` ++ if test -n "$darwin_arches"; then ++ darwin_arches=`echo "$darwin_arches" | $SED -e 's/.*are://'` ++ darwin_arch= ++ $show "$darwin_base_archive has multiple architectures $darwin_arches" ++ for darwin_arch in $darwin_arches ; do ++ mkdir -p "unfat-$$/${darwin_base_archive}-${darwin_arch}" ++ lipo -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" ++ cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" ++ func_extract_an_archive "`pwd`" "${darwin_base_archive}" ++ cd "$darwin_curdir" ++ $rm "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" ++ done # $darwin_arches ++ ## Okay now we have a bunch of thin objects, gotta fatten them up :) ++ darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print| xargs basename | sort -u | $NL2SP` ++ darwin_file= ++ darwin_files= ++ for darwin_file in $darwin_filelist; do ++ darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP` ++ lipo -create -output "$darwin_file" $darwin_files ++ done # $darwin_filelist ++ ${rm}r unfat-$$ ++ cd "$darwin_orig_dir" ++ else ++ cd "$darwin_orig_dir" ++ func_extract_an_archive "$my_xdir" "$my_xabs" ++ fi # $darwin_arches ++ fi # $run ++ ;; ++ *) ++ func_extract_an_archive "$my_xdir" "$my_xabs" ++ ;; ++ esac ++ my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP` ++ done ++ func_extract_archives_result="$my_oldobjs" ++} ++# End of Shell function definitions ++##################################### ++ ++# Darwin sucks ++eval std_shrext=\"$shrext_cmds\" ++ ++disable_libs=no ++ ++# Parse our command line options once, thoroughly. ++while test "$#" -gt 0 ++do ++ arg="$1" ++ shift ++ ++ case $arg in ++ -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;; ++ *) optarg= ;; ++ esac ++ ++ # If the previous option needs an argument, assign it. ++ if test -n "$prev"; then ++ case $prev in ++ execute_dlfiles) ++ execute_dlfiles="$execute_dlfiles $arg" ++ ;; ++ tag) ++ tagname="$arg" ++ preserve_args="${preserve_args}=$arg" ++ ++ # Check whether tagname contains only valid characters ++ case $tagname in ++ *[!-_A-Za-z0-9,/]*) ++ $echo "$progname: invalid tag name: $tagname" 1>&2 ++ exit $EXIT_FAILURE ++ ;; ++ esac ++ ++ case $tagname in ++ CC) ++ # Don't test for the "default" C tag, as we know, it's there, but ++ # not specially marked. ++ ;; ++ *) ++ if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "$progpath" > /dev/null; then ++ taglist="$taglist $tagname" ++ # Evaluate the configuration. ++ eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$tagname'$/,/^# ### END LIBTOOL TAG CONFIG: '$tagname'$/p' < $progpath`" ++ else ++ $echo "$progname: ignoring unknown tag $tagname" 1>&2 ++ fi ++ ;; ++ esac ++ ;; ++ *) ++ eval "$prev=\$arg" ++ ;; ++ esac ++ ++ prev= ++ prevopt= ++ continue ++ fi ++ ++ # Have we seen a non-optional argument yet? ++ case $arg in ++ --help) ++ show_help=yes ++ ;; ++ ++ --version) ++ $echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP" ++ $echo ++ $echo "Copyright (C) 2005 Free Software Foundation, Inc." ++ $echo "This is free software; see the source for copying conditions. There is NO" ++ $echo "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." ++ exit $? ++ ;; ++ ++ --config) ++ ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $progpath ++ # Now print the configurations for the tags. ++ for tagname in $taglist; do ++ ${SED} -n -e "/^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$/,/^# ### END LIBTOOL TAG CONFIG: $tagname$/p" < "$progpath" ++ done ++ exit $? ++ ;; ++ ++ --debug) ++ $echo "$progname: enabling shell trace mode" ++ set -x ++ preserve_args="$preserve_args $arg" ++ ;; ++ ++ --dry-run | -n) ++ run=: ++ ;; ++ ++ --features) ++ $echo "host: $host" ++ if test "$build_libtool_libs" = yes; then ++ $echo "enable shared libraries" ++ else ++ $echo "disable shared libraries" ++ fi ++ if test "$build_old_libs" = yes; then ++ $echo "enable static libraries" ++ else ++ $echo "disable static libraries" ++ fi ++ exit $? ++ ;; ++ ++ --finish) mode="finish" ;; ++ ++ --mode) prevopt="--mode" prev=mode ;; ++ --mode=*) mode="$optarg" ;; ++ ++ --preserve-dup-deps) duplicate_deps="yes" ;; ++ ++ --quiet | --silent) ++ show=: ++ preserve_args="$preserve_args $arg" ++ ;; ++ ++ --tag) ++ prevopt="--tag" ++ prev=tag ++ preserve_args="$preserve_args --tag" ++ ;; ++ --tag=*) ++ set tag "$optarg" ${1+"$@"} ++ shift ++ prev=tag ++ preserve_args="$preserve_args --tag" ++ ;; ++ ++ -dlopen) ++ prevopt="-dlopen" ++ prev=execute_dlfiles ++ ;; ++ ++ -*) ++ $echo "$modename: unrecognized option \`$arg'" 1>&2 ++ $echo "$help" 1>&2 ++ exit $EXIT_FAILURE ++ ;; ++ ++ *) ++ nonopt="$arg" ++ break ++ ;; ++ esac ++done ++ ++if test -n "$prevopt"; then ++ $echo "$modename: option \`$prevopt' requires an argument" 1>&2 ++ $echo "$help" 1>&2 ++ exit $EXIT_FAILURE ++fi ++ ++case $disable_libs in ++no) ++ ;; ++shared) ++ build_libtool_libs=no ++ build_old_libs=yes ++ ;; ++static) ++ build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` ++ ;; ++esac ++ ++# If this variable is set in any of the actions, the command in it ++# will be execed at the end. This prevents here-documents from being ++# left over by shells. ++exec_cmd= ++ ++if test -z "$show_help"; then ++ ++ # Infer the operation mode. ++ if test -z "$mode"; then ++ $echo "*** Warning: inferring the mode of operation is deprecated." 1>&2 ++ $echo "*** Future versions of Libtool will require --mode=MODE be specified." 1>&2 ++ case $nonopt in ++ *cc | cc* | *++ | gcc* | *-gcc* | g++* | xlc*) ++ mode=link ++ for arg ++ do ++ case $arg in ++ -c) ++ mode=compile ++ break ++ ;; ++ esac ++ done ++ ;; ++ *db | *dbx | *strace | *truss) ++ mode=execute ++ ;; ++ *install*|cp|mv) ++ mode=install ++ ;; ++ *rm) ++ mode=uninstall ++ ;; ++ *) ++ # If we have no mode, but dlfiles were specified, then do execute mode. ++ test -n "$execute_dlfiles" && mode=execute ++ ++ # Just use the default operation mode. ++ if test -z "$mode"; then ++ if test -n "$nonopt"; then ++ $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2 ++ else ++ $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2 ++ fi ++ fi ++ ;; ++ esac ++ fi ++ ++ # Only execute mode is allowed to have -dlopen flags. ++ if test -n "$execute_dlfiles" && test "$mode" != execute; then ++ $echo "$modename: unrecognized option \`-dlopen'" 1>&2 ++ $echo "$help" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ ++ # Change the help message to a mode-specific one. ++ generic_help="$help" ++ help="Try \`$modename --help --mode=$mode' for more information." ++ ++ # These modes are in order of execution frequency so that they run quickly. ++ case $mode in ++ # libtool compile mode ++ compile) ++ modename="$modename: compile" ++ # Get the compilation command and the source file. ++ base_compile= ++ srcfile="$nonopt" # always keep a non-empty value in "srcfile" ++ suppress_opt=yes ++ suppress_output= ++ arg_mode=normal ++ libobj= ++ later= ++ ++ for arg ++ do ++ case $arg_mode in ++ arg ) ++ # do not "continue". Instead, add this to base_compile ++ lastarg="$arg" ++ arg_mode=normal ++ ;; ++ ++ target ) ++ libobj="$arg" ++ arg_mode=normal ++ continue ++ ;; ++ ++ normal ) ++ # Accept any command-line options. ++ case $arg in ++ -o) ++ if test -n "$libobj" ; then ++ $echo "$modename: you cannot specify \`-o' more than once" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ arg_mode=target ++ continue ++ ;; ++ ++ -static | -prefer-pic | -prefer-non-pic) ++ later="$later $arg" ++ continue ++ ;; ++ ++ -no-suppress) ++ suppress_opt=no ++ continue ++ ;; ++ ++ -Xcompiler) ++ arg_mode=arg # the next one goes into the "base_compile" arg list ++ continue # The current "srcfile" will either be retained or ++ ;; # replaced later. I would guess that would be a bug. ++ ++ -Wc,*) ++ args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"` ++ lastarg= ++ save_ifs="$IFS"; IFS=',' ++ for arg in $args; do ++ IFS="$save_ifs" ++ ++ # Double-quote args containing other shell metacharacters. ++ # Many Bourne shells cannot handle close brackets correctly ++ # in scan sets, so we specify it separately. ++ case $arg in ++ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") ++ arg="\"$arg\"" ++ ;; ++ esac ++ lastarg="$lastarg $arg" ++ done ++ IFS="$save_ifs" ++ lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"` ++ ++ # Add the arguments to base_compile. ++ base_compile="$base_compile $lastarg" ++ continue ++ ;; ++ ++ * ) ++ # Accept the current argument as the source file. ++ # The previous "srcfile" becomes the current argument. ++ # ++ lastarg="$srcfile" ++ srcfile="$arg" ++ ;; ++ esac # case $arg ++ ;; ++ esac # case $arg_mode ++ ++ # Aesthetically quote the previous argument. ++ lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"` ++ ++ case $lastarg in ++ # Double-quote args containing other shell metacharacters. ++ # Many Bourne shells cannot handle close brackets correctly ++ # in scan sets, and some SunOS ksh mistreat backslash-escaping ++ # in scan sets (worked around with variable expansion), ++ # and furthermore cannot handle '|' '&' '(' ')' in scan sets ++ # at all, so we specify them separately. ++ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") ++ lastarg="\"$lastarg\"" ++ ;; ++ esac ++ ++ base_compile="$base_compile $lastarg" ++ done # for arg ++ ++ case $arg_mode in ++ arg) ++ $echo "$modename: you must specify an argument for -Xcompile" ++ exit $EXIT_FAILURE ++ ;; ++ target) ++ $echo "$modename: you must specify a target with \`-o'" 1>&2 ++ exit $EXIT_FAILURE ++ ;; ++ *) ++ # Get the name of the library object. ++ [ -z "$libobj" ] && libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'` ++ ;; ++ esac ++ ++ # Recognize several different file suffixes. ++ # If the user specifies -o file.o, it is replaced with file.lo ++ xform='[cCFSifmso]' ++ case $libobj in ++ *.ada) xform=ada ;; ++ *.adb) xform=adb ;; ++ *.ads) xform=ads ;; ++ *.asm) xform=asm ;; ++ *.c++) xform=c++ ;; ++ *.cc) xform=cc ;; ++ *.ii) xform=ii ;; ++ *.class) xform=class ;; ++ *.cpp) xform=cpp ;; ++ *.cxx) xform=cxx ;; ++ *.f90) xform=f90 ;; ++ *.for) xform=for ;; ++ *.java) xform=java ;; ++ *.obj) xform=obj ;; ++ esac ++ ++ libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"` ++ ++ case $libobj in ++ *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;; ++ *) ++ $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2 ++ exit $EXIT_FAILURE ++ ;; ++ esac ++ ++ func_infer_tag $base_compile ++ ++ for arg in $later; do ++ case $arg in ++ -static) ++ build_old_libs=yes ++ continue ++ ;; ++ ++ -prefer-pic) ++ pic_mode=yes ++ continue ++ ;; ++ ++ -prefer-non-pic) ++ pic_mode=no ++ continue ++ ;; ++ esac ++ done ++ ++ qlibobj=`$echo "X$libobj" | $Xsed -e "$sed_quote_subst"` ++ case $qlibobj in ++ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") ++ qlibobj="\"$qlibobj\"" ;; ++ esac ++ test "X$libobj" != "X$qlibobj" \ ++ && $echo "X$libobj" | grep '[]~#^*{};<>?"'"'"' &()|`$[]' \ ++ && $echo "$modename: libobj name \`$libobj' may not contain shell special characters." ++ objname=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` ++ xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` ++ if test "X$xdir" = "X$obj"; then ++ xdir= ++ else ++ xdir=$xdir/ ++ fi ++ lobj=${xdir}$objdir/$objname ++ ++ if test -z "$base_compile"; then ++ $echo "$modename: you must specify a compilation command" 1>&2 ++ $echo "$help" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ ++ # Delete any leftover library objects. ++ if test "$build_old_libs" = yes; then ++ removelist="$obj $lobj $libobj ${libobj}T" ++ else ++ removelist="$lobj $libobj ${libobj}T" ++ fi ++ ++ $run $rm $removelist ++ trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15 ++ ++ # On Cygwin there's no "real" PIC flag so we must build both object types ++ case $host_os in ++ cygwin* | mingw* | pw32* | os2*) ++ pic_mode=default ++ ;; ++ esac ++ if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then ++ # non-PIC code in shared libraries is not supported ++ pic_mode=default ++ fi ++ ++ # Calculate the filename of the output object if compiler does ++ # not support -o with -c ++ if test "$compiler_c_o" = no; then ++ output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} ++ lockfile="$output_obj.lock" ++ removelist="$removelist $output_obj $lockfile" ++ trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15 ++ else ++ output_obj= ++ need_locks=no ++ lockfile= ++ fi ++ ++ # Lock this critical section if it is needed ++ # We use this script file to make the link, it avoids creating a new file ++ if test "$need_locks" = yes; then ++ until $run ln "$progpath" "$lockfile" 2>/dev/null; do ++ $show "Waiting for $lockfile to be removed" ++ sleep 2 ++ done ++ elif test "$need_locks" = warn; then ++ if test -f "$lockfile"; then ++ $echo "\ ++*** ERROR, $lockfile exists and contains: ++`cat $lockfile 2>/dev/null` ++ ++This indicates that another process is trying to use the same ++temporary object file, and libtool could not work around it because ++your compiler does not support \`-c' and \`-o' together. If you ++repeat this compilation, it may succeed, by chance, but you had better ++avoid parallel builds (make -j) in this platform, or get a better ++compiler." ++ ++ $run $rm $removelist ++ exit $EXIT_FAILURE ++ fi ++ $echo "$srcfile" > "$lockfile" ++ fi ++ ++ if test -n "$fix_srcfile_path"; then ++ eval srcfile=\"$fix_srcfile_path\" ++ fi ++ qsrcfile=`$echo "X$srcfile" | $Xsed -e "$sed_quote_subst"` ++ case $qsrcfile in ++ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") ++ qsrcfile="\"$qsrcfile\"" ;; ++ esac ++ ++ $run $rm "$libobj" "${libobj}T" ++ ++ # Create a libtool object file (analogous to a ".la" file), ++ # but don't create it if we're doing a dry run. ++ test -z "$run" && cat > ${libobj}T </dev/null`" != "X$srcfile"; then ++ $echo "\ ++*** ERROR, $lockfile contains: ++`cat $lockfile 2>/dev/null` ++ ++but it should contain: ++$srcfile ++ ++This indicates that another process is trying to use the same ++temporary object file, and libtool could not work around it because ++your compiler does not support \`-c' and \`-o' together. If you ++repeat this compilation, it may succeed, by chance, but you had better ++avoid parallel builds (make -j) in this platform, or get a better ++compiler." ++ ++ $run $rm $removelist ++ exit $EXIT_FAILURE ++ fi ++ ++ # Just move the object if needed, then go on to compile the next one ++ if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then ++ $show "$mv $output_obj $lobj" ++ if $run $mv $output_obj $lobj; then : ++ else ++ error=$? ++ $run $rm $removelist ++ exit $error ++ fi ++ fi ++ ++ # Append the name of the PIC object to the libtool object file. ++ test -z "$run" && cat >> ${libobj}T <> ${libobj}T </dev/null`" != "X$srcfile"; then ++ $echo "\ ++*** ERROR, $lockfile contains: ++`cat $lockfile 2>/dev/null` ++ ++but it should contain: ++$srcfile ++ ++This indicates that another process is trying to use the same ++temporary object file, and libtool could not work around it because ++your compiler does not support \`-c' and \`-o' together. If you ++repeat this compilation, it may succeed, by chance, but you had better ++avoid parallel builds (make -j) in this platform, or get a better ++compiler." ++ ++ $run $rm $removelist ++ exit $EXIT_FAILURE ++ fi ++ ++ # Just move the object if needed ++ if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then ++ $show "$mv $output_obj $obj" ++ if $run $mv $output_obj $obj; then : ++ else ++ error=$? ++ $run $rm $removelist ++ exit $error ++ fi ++ fi ++ ++ # Append the name of the non-PIC object the libtool object file. ++ # Only append if the libtool object file exists. ++ test -z "$run" && cat >> ${libobj}T <> ${libobj}T <&2 ++ fi ++ if test -n "$link_static_flag"; then ++ dlopen_self=$dlopen_self_static ++ fi ++ prefer_static_libs=yes ++ ;; ++ -static) ++ if test -z "$pic_flag" && test -n "$link_static_flag"; then ++ dlopen_self=$dlopen_self_static ++ fi ++ prefer_static_libs=built ++ ;; ++ -static-libtool-libs) ++ if test -z "$pic_flag" && test -n "$link_static_flag"; then ++ dlopen_self=$dlopen_self_static ++ fi ++ prefer_static_libs=yes ++ ;; ++ esac ++ build_libtool_libs=no ++ build_old_libs=yes ++ break ++ ;; ++ esac ++ done ++ ++ # See if our shared archives depend on static archives. ++ test -n "$old_archive_from_new_cmds" && build_old_libs=yes ++ ++ # Go through the arguments, transforming them on the way. ++ while test "$#" -gt 0; do ++ arg="$1" ++ shift ++ case $arg in ++ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") ++ qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test ++ ;; ++ *) qarg=$arg ;; ++ esac ++ libtool_args="$libtool_args $qarg" ++ ++ # If the previous option needs an argument, assign it. ++ if test -n "$prev"; then ++ case $prev in ++ output) ++ compile_command="$compile_command @OUTPUT@" ++ finalize_command="$finalize_command @OUTPUT@" ++ ;; ++ esac ++ ++ case $prev in ++ dlfiles|dlprefiles) ++ if test "$preload" = no; then ++ # Add the symbol object into the linking commands. ++ compile_command="$compile_command @SYMFILE@" ++ finalize_command="$finalize_command @SYMFILE@" ++ preload=yes ++ fi ++ case $arg in ++ *.la | *.lo) ;; # We handle these cases below. ++ force) ++ if test "$dlself" = no; then ++ dlself=needless ++ export_dynamic=yes ++ fi ++ prev= ++ continue ++ ;; ++ self) ++ if test "$prev" = dlprefiles; then ++ dlself=yes ++ elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then ++ dlself=yes ++ else ++ dlself=needless ++ export_dynamic=yes ++ fi ++ prev= ++ continue ++ ;; ++ *) ++ if test "$prev" = dlfiles; then ++ dlfiles="$dlfiles $arg" ++ else ++ dlprefiles="$dlprefiles $arg" ++ fi ++ prev= ++ continue ++ ;; ++ esac ++ ;; ++ expsyms) ++ export_symbols="$arg" ++ if test ! -f "$arg"; then ++ $echo "$modename: symbol file \`$arg' does not exist" ++ exit $EXIT_FAILURE ++ fi ++ prev= ++ continue ++ ;; ++ expsyms_regex) ++ export_symbols_regex="$arg" ++ prev= ++ continue ++ ;; ++ inst_prefix) ++ inst_prefix_dir="$arg" ++ prev= ++ continue ++ ;; ++ precious_regex) ++ precious_files_regex="$arg" ++ prev= ++ continue ++ ;; ++ release) ++ release="-$arg" ++ prev= ++ continue ++ ;; ++ objectlist) ++ if test -f "$arg"; then ++ save_arg=$arg ++ moreargs= ++ for fil in `cat $save_arg` ++ do ++# moreargs="$moreargs $fil" ++ arg=$fil ++ # A libtool-controlled object. ++ ++ # Check to see that this really is a libtool object. ++ if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then ++ pic_object= ++ non_pic_object= ++ ++ # Read the .lo file ++ # If there is no directory component, then add one. ++ case $arg in ++ */* | *\\*) . $arg ;; ++ *) . ./$arg ;; ++ esac ++ ++ if test -z "$pic_object" || \ ++ test -z "$non_pic_object" || ++ test "$pic_object" = none && \ ++ test "$non_pic_object" = none; then ++ $echo "$modename: cannot find name of object for \`$arg'" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ ++ # Extract subdirectory from the argument. ++ xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` ++ if test "X$xdir" = "X$arg"; then ++ xdir= ++ else ++ xdir="$xdir/" ++ fi ++ ++ if test "$pic_object" != none; then ++ # Prepend the subdirectory the object is found in. ++ pic_object="$xdir$pic_object" ++ ++ if test "$prev" = dlfiles; then ++ if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then ++ dlfiles="$dlfiles $pic_object" ++ prev= ++ continue ++ else ++ # If libtool objects are unsupported, then we need to preload. ++ prev=dlprefiles ++ fi ++ fi ++ ++ # CHECK ME: I think I busted this. -Ossama ++ if test "$prev" = dlprefiles; then ++ # Preload the old-style object. ++ dlprefiles="$dlprefiles $pic_object" ++ prev= ++ fi ++ ++ # A PIC object. ++ libobjs="$libobjs $pic_object" ++ arg="$pic_object" ++ fi ++ ++ # Non-PIC object. ++ if test "$non_pic_object" != none; then ++ # Prepend the subdirectory the object is found in. ++ non_pic_object="$xdir$non_pic_object" ++ ++ # A standard non-PIC object ++ non_pic_objects="$non_pic_objects $non_pic_object" ++ if test -z "$pic_object" || test "$pic_object" = none ; then ++ arg="$non_pic_object" ++ fi ++ else ++ # If the PIC object exists, use it instead. ++ # $xdir was prepended to $pic_object above. ++ non_pic_object="$pic_object" ++ non_pic_objects="$non_pic_objects $non_pic_object" ++ fi ++ else ++ # Only an error if not doing a dry-run. ++ if test -z "$run"; then ++ $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 ++ exit $EXIT_FAILURE ++ else ++ # Dry-run case. ++ ++ # Extract subdirectory from the argument. ++ xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` ++ if test "X$xdir" = "X$arg"; then ++ xdir= ++ else ++ xdir="$xdir/" ++ fi ++ ++ pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` ++ non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` ++ libobjs="$libobjs $pic_object" ++ non_pic_objects="$non_pic_objects $non_pic_object" ++ fi ++ fi ++ done ++ else ++ $echo "$modename: link input file \`$save_arg' does not exist" ++ exit $EXIT_FAILURE ++ fi ++ arg=$save_arg ++ prev= ++ continue ++ ;; ++ rpath | xrpath) ++ # We need an absolute path. ++ case $arg in ++ [\\/]* | [A-Za-z]:[\\/]*) ;; ++ *) ++ $echo "$modename: only absolute run-paths are allowed" 1>&2 ++ exit $EXIT_FAILURE ++ ;; ++ esac ++ if test "$prev" = rpath; then ++ case "$rpath " in ++ *" $arg "*) ;; ++ *) rpath="$rpath $arg" ;; ++ esac ++ else ++ case "$xrpath " in ++ *" $arg "*) ;; ++ *) xrpath="$xrpath $arg" ;; ++ esac ++ fi ++ prev= ++ continue ++ ;; ++ xcompiler) ++ compiler_flags="$compiler_flags $qarg" ++ prev= ++ compile_command="$compile_command $qarg" ++ finalize_command="$finalize_command $qarg" ++ continue ++ ;; ++ xlinker) ++ linker_flags="$linker_flags $qarg" ++ compiler_flags="$compiler_flags $wl$qarg" ++ prev= ++ compile_command="$compile_command $wl$qarg" ++ finalize_command="$finalize_command $wl$qarg" ++ continue ++ ;; ++ xcclinker) ++ linker_flags="$linker_flags $qarg" ++ compiler_flags="$compiler_flags $qarg" ++ prev= ++ compile_command="$compile_command $qarg" ++ finalize_command="$finalize_command $qarg" ++ continue ++ ;; ++ shrext) ++ shrext_cmds="$arg" ++ prev= ++ continue ++ ;; ++ darwin_framework|darwin_framework_skip) ++ test "$prev" = "darwin_framework" && compiler_flags="$compiler_flags $arg" ++ compile_command="$compile_command $arg" ++ finalize_command="$finalize_command $arg" ++ prev= ++ continue ++ ;; ++ *) ++ eval "$prev=\"\$arg\"" ++ prev= ++ continue ++ ;; ++ esac ++ fi # test -n "$prev" ++ ++ prevarg="$arg" ++ ++ case $arg in ++ -all-static) ++ if test -n "$link_static_flag"; then ++ compile_command="$compile_command $link_static_flag" ++ finalize_command="$finalize_command $link_static_flag" ++ fi ++ continue ++ ;; ++ ++ -allow-undefined) ++ # FIXME: remove this flag sometime in the future. ++ $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2 ++ continue ++ ;; ++ ++ -avoid-version) ++ avoid_version=yes ++ continue ++ ;; ++ ++ -dlopen) ++ prev=dlfiles ++ continue ++ ;; ++ ++ -dlpreopen) ++ prev=dlprefiles ++ continue ++ ;; ++ ++ -export-dynamic) ++ export_dynamic=yes ++ continue ++ ;; ++ ++ -export-symbols | -export-symbols-regex) ++ if test -n "$export_symbols" || test -n "$export_symbols_regex"; then ++ $echo "$modename: more than one -exported-symbols argument is not allowed" ++ exit $EXIT_FAILURE ++ fi ++ if test "X$arg" = "X-export-symbols"; then ++ prev=expsyms ++ else ++ prev=expsyms_regex ++ fi ++ continue ++ ;; ++ ++ -framework|-arch|-isysroot) ++ case " $CC " in ++ *" ${arg} ${1} "* | *" ${arg} ${1} "*) ++ prev=darwin_framework_skip ;; ++ *) compiler_flags="$compiler_flags $arg" ++ prev=darwin_framework ;; ++ esac ++ compile_command="$compile_command $arg" ++ finalize_command="$finalize_command $arg" ++ continue ++ ;; ++ ++ -inst-prefix-dir) ++ prev=inst_prefix ++ continue ++ ;; ++ ++ # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* ++ # so, if we see these flags be careful not to treat them like -L ++ -L[A-Z][A-Z]*:*) ++ case $with_gcc/$host in ++ no/*-*-irix* | /*-*-irix*) ++ compile_command="$compile_command $arg" ++ finalize_command="$finalize_command $arg" ++ ;; ++ esac ++ continue ++ ;; ++ ++ -L*) ++ dir=`$echo "X$arg" | $Xsed -e 's/^-L//'` ++ # We need an absolute path. ++ case $dir in ++ [\\/]* | [A-Za-z]:[\\/]*) ;; ++ *) ++ absdir=`cd "$dir" && pwd` ++ if test -z "$absdir"; then ++ $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2 ++ absdir="$dir" ++ notinst_path="$notinst_path $dir" ++ fi ++ dir="$absdir" ++ ;; ++ esac ++ case "$deplibs " in ++ *" -L$dir "*) ;; ++ *) ++ deplibs="$deplibs -L$dir" ++ lib_search_path="$lib_search_path $dir" ++ ;; ++ esac ++ case $host in ++ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) ++ testbindir=`$echo "X$dir" | $Xsed -e 's*/lib$*/bin*'` ++ case :$dllsearchpath: in ++ *":$dir:"*) ;; ++ *) dllsearchpath="$dllsearchpath:$dir";; ++ esac ++ case :$dllsearchpath: in ++ *":$testbindir:"*) ;; ++ *) dllsearchpath="$dllsearchpath:$testbindir";; ++ esac ++ ;; ++ esac ++ continue ++ ;; ++ ++ -l*) ++ if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then ++ case $host in ++ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos*) ++ # These systems don't actually have a C or math library (as such) ++ continue ++ ;; ++ *-*-os2*) ++ # These systems don't actually have a C library (as such) ++ test "X$arg" = "X-lc" && continue ++ ;; ++ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) ++ # Do not include libc due to us having libc/libc_r. ++ test "X$arg" = "X-lc" && continue ++ ;; ++ *-*-rhapsody* | *-*-darwin1.[012]) ++ # Rhapsody C and math libraries are in the System framework ++ deplibs="$deplibs -framework System" ++ continue ++ ;; ++ *-*-sco3.2v5* | *-*-sco5v6*) ++ # Causes problems with __ctype ++ test "X$arg" = "X-lc" && continue ++ ;; ++ *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) ++ # Compiler inserts libc in the correct place for threads to work ++ test "X$arg" = "X-lc" && continue ++ ;; ++ esac ++ elif test "X$arg" = "X-lc_r"; then ++ case $host in ++ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) ++ # Do not include libc_r directly, use -pthread flag. ++ continue ++ ;; ++ esac ++ fi ++ deplibs="$deplibs $arg" ++ continue ++ ;; ++ ++ # Tru64 UNIX uses -model [arg] to determine the layout of C++ ++ # classes, name mangling, and exception handling. ++ -model) ++ compile_command="$compile_command $arg" ++ compiler_flags="$compiler_flags $arg" ++ finalize_command="$finalize_command $arg" ++ prev=xcompiler ++ continue ++ ;; ++ ++ -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe) ++ compiler_flags="$compiler_flags $arg" ++ compile_command="$compile_command $arg" ++ finalize_command="$finalize_command $arg" ++ continue ++ ;; ++ ++ -module) ++ module=yes ++ continue ++ ;; ++ ++ # -64, -mips[0-9] enable 64-bit mode on the SGI compiler ++ # -r[0-9][0-9]* specifies the processor on the SGI compiler ++ # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler ++ # +DA*, +DD* enable 64-bit mode on the HP compiler ++ # -q* pass through compiler args for the IBM compiler ++ # -m* pass through architecture-specific compiler args for GCC ++ # -m*, -t[45]*, -txscale* pass through architecture-specific ++ # compiler args for GCC ++ # -pg pass through profiling flag for GCC ++ # @file GCC response files ++ -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*|-pg| \ ++ -t[45]*|-txscale*|@*) ++ ++ # Unknown arguments in both finalize_command and compile_command need ++ # to be aesthetically quoted because they are evaled later. ++ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` ++ case $arg in ++ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") ++ arg="\"$arg\"" ++ ;; ++ esac ++ compile_command="$compile_command $arg" ++ finalize_command="$finalize_command $arg" ++ compiler_flags="$compiler_flags $arg" ++ continue ++ ;; ++ ++ -shrext) ++ prev=shrext ++ continue ++ ;; ++ ++ -no-fast-install) ++ fast_install=no ++ continue ++ ;; ++ ++ -no-install) ++ case $host in ++ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) ++ # The PATH hackery in wrapper scripts is required on Windows ++ # in order for the loader to find any dlls it needs. ++ $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2 ++ $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2 ++ fast_install=no ++ ;; ++ *) no_install=yes ;; ++ esac ++ continue ++ ;; ++ ++ -no-undefined) ++ allow_undefined=no ++ continue ++ ;; ++ ++ -objectlist) ++ prev=objectlist ++ continue ++ ;; ++ ++ -o) prev=output ;; ++ ++ -precious-files-regex) ++ prev=precious_regex ++ continue ++ ;; ++ ++ -release) ++ prev=release ++ continue ++ ;; ++ ++ -rpath) ++ prev=rpath ++ continue ++ ;; ++ ++ -R) ++ prev=xrpath ++ continue ++ ;; ++ ++ -R*) ++ dir=`$echo "X$arg" | $Xsed -e 's/^-R//'` ++ # We need an absolute path. ++ case $dir in ++ [\\/]* | [A-Za-z]:[\\/]*) ;; ++ *) ++ $echo "$modename: only absolute run-paths are allowed" 1>&2 ++ exit $EXIT_FAILURE ++ ;; ++ esac ++ case "$xrpath " in ++ *" $dir "*) ;; ++ *) xrpath="$xrpath $dir" ;; ++ esac ++ continue ++ ;; ++ ++ -static | -static-libtool-libs) ++ # The effects of -static are defined in a previous loop. ++ # We used to do the same as -all-static on platforms that ++ # didn't have a PIC flag, but the assumption that the effects ++ # would be equivalent was wrong. It would break on at least ++ # Digital Unix and AIX. ++ continue ++ ;; ++ ++ -thread-safe) ++ thread_safe=yes ++ continue ++ ;; ++ ++ -version-info) ++ prev=vinfo ++ continue ++ ;; ++ -version-number) ++ prev=vinfo ++ vinfo_number=yes ++ continue ++ ;; ++ ++ -Wc,*) ++ args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'` ++ arg= ++ save_ifs="$IFS"; IFS=',' ++ for flag in $args; do ++ IFS="$save_ifs" ++ case $flag in ++ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") ++ flag="\"$flag\"" ++ ;; ++ esac ++ arg="$arg $wl$flag" ++ compiler_flags="$compiler_flags $flag" ++ done ++ IFS="$save_ifs" ++ arg=`$echo "X$arg" | $Xsed -e "s/^ //"` ++ ;; ++ ++ -Wl,*) ++ args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'` ++ arg= ++ save_ifs="$IFS"; IFS=',' ++ for flag in $args; do ++ IFS="$save_ifs" ++ case $flag in ++ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") ++ flag="\"$flag\"" ++ ;; ++ esac ++ arg="$arg $wl$flag" ++ compiler_flags="$compiler_flags $wl$flag" ++ linker_flags="$linker_flags $flag" ++ done ++ IFS="$save_ifs" ++ arg=`$echo "X$arg" | $Xsed -e "s/^ //"` ++ ;; ++ ++ -Xcompiler) ++ prev=xcompiler ++ continue ++ ;; ++ ++ -Xlinker) ++ prev=xlinker ++ continue ++ ;; ++ ++ -XCClinker) ++ prev=xcclinker ++ continue ++ ;; ++ ++ # Some other compiler flag. ++ -* | +*) ++ # Unknown arguments in both finalize_command and compile_command need ++ # to be aesthetically quoted because they are evaled later. ++ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` ++ case $arg in ++ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") ++ arg="\"$arg\"" ++ ;; ++ esac ++ ;; ++ ++ *.$objext) ++ # A standard object. ++ objs="$objs $arg" ++ ;; ++ ++ *.lo) ++ # A libtool-controlled object. ++ ++ # Check to see that this really is a libtool object. ++ if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then ++ pic_object= ++ non_pic_object= ++ ++ # Read the .lo file ++ # If there is no directory component, then add one. ++ case $arg in ++ */* | *\\*) . $arg ;; ++ *) . ./$arg ;; ++ esac ++ ++ if test -z "$pic_object" || \ ++ test -z "$non_pic_object" || ++ test "$pic_object" = none && \ ++ test "$non_pic_object" = none; then ++ $echo "$modename: cannot find name of object for \`$arg'" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ ++ # Extract subdirectory from the argument. ++ xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` ++ if test "X$xdir" = "X$arg"; then ++ xdir= ++ else ++ xdir="$xdir/" ++ fi ++ ++ if test "$pic_object" != none; then ++ # Prepend the subdirectory the object is found in. ++ pic_object="$xdir$pic_object" ++ ++ if test "$prev" = dlfiles; then ++ if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then ++ dlfiles="$dlfiles $pic_object" ++ prev= ++ continue ++ else ++ # If libtool objects are unsupported, then we need to preload. ++ prev=dlprefiles ++ fi ++ fi ++ ++ # CHECK ME: I think I busted this. -Ossama ++ if test "$prev" = dlprefiles; then ++ # Preload the old-style object. ++ dlprefiles="$dlprefiles $pic_object" ++ prev= ++ fi ++ ++ # A PIC object. ++ libobjs="$libobjs $pic_object" ++ arg="$pic_object" ++ fi ++ ++ # Non-PIC object. ++ if test "$non_pic_object" != none; then ++ # Prepend the subdirectory the object is found in. ++ non_pic_object="$xdir$non_pic_object" ++ ++ # A standard non-PIC object ++ non_pic_objects="$non_pic_objects $non_pic_object" ++ if test -z "$pic_object" || test "$pic_object" = none ; then ++ arg="$non_pic_object" ++ fi ++ else ++ # If the PIC object exists, use it instead. ++ # $xdir was prepended to $pic_object above. ++ non_pic_object="$pic_object" ++ non_pic_objects="$non_pic_objects $non_pic_object" ++ fi ++ else ++ # Only an error if not doing a dry-run. ++ if test -z "$run"; then ++ $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 ++ exit $EXIT_FAILURE ++ else ++ # Dry-run case. ++ ++ # Extract subdirectory from the argument. ++ xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` ++ if test "X$xdir" = "X$arg"; then ++ xdir= ++ else ++ xdir="$xdir/" ++ fi ++ ++ pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` ++ non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` ++ libobjs="$libobjs $pic_object" ++ non_pic_objects="$non_pic_objects $non_pic_object" ++ fi ++ fi ++ ;; ++ ++ *.$libext) ++ # An archive. ++ deplibs="$deplibs $arg" ++ old_deplibs="$old_deplibs $arg" ++ continue ++ ;; ++ ++ *.la) ++ # A libtool-controlled library. ++ ++ if test "$prev" = dlfiles; then ++ # This library was specified with -dlopen. ++ dlfiles="$dlfiles $arg" ++ prev= ++ elif test "$prev" = dlprefiles; then ++ # The library was specified with -dlpreopen. ++ dlprefiles="$dlprefiles $arg" ++ prev= ++ else ++ deplibs="$deplibs $arg" ++ fi ++ continue ++ ;; ++ ++ # Some other compiler argument. ++ *) ++ # Unknown arguments in both finalize_command and compile_command need ++ # to be aesthetically quoted because they are evaled later. ++ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` ++ case $arg in ++ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") ++ arg="\"$arg\"" ++ ;; ++ esac ++ ;; ++ esac # arg ++ ++ # Now actually substitute the argument into the commands. ++ if test -n "$arg"; then ++ compile_command="$compile_command $arg" ++ finalize_command="$finalize_command $arg" ++ fi ++ done # argument parsing loop ++ ++ if test -n "$prev"; then ++ $echo "$modename: the \`$prevarg' option requires an argument" 1>&2 ++ $echo "$help" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ ++ if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then ++ eval arg=\"$export_dynamic_flag_spec\" ++ compile_command="$compile_command $arg" ++ finalize_command="$finalize_command $arg" ++ fi ++ ++ oldlibs= ++ # calculate the name of the file, without its directory ++ outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'` ++ libobjs_save="$libobjs" ++ ++ if test -n "$shlibpath_var"; then ++ # get the directories listed in $shlibpath_var ++ eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` ++ else ++ shlib_search_path= ++ fi ++ eval sys_lib_search_path=\"$sys_lib_search_path_spec\" ++ eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" ++ ++ output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` ++ if test "X$output_objdir" = "X$output"; then ++ output_objdir="$objdir" ++ else ++ output_objdir="$output_objdir/$objdir" ++ fi ++ # Create the object directory. ++ if test ! -d "$output_objdir"; then ++ $show "$mkdir $output_objdir" ++ $run $mkdir $output_objdir ++ exit_status=$? ++ if test "$exit_status" -ne 0 && test ! -d "$output_objdir"; then ++ exit $exit_status ++ fi ++ fi ++ ++ # Determine the type of output ++ case $output in ++ "") ++ $echo "$modename: you must specify an output file" 1>&2 ++ $echo "$help" 1>&2 ++ exit $EXIT_FAILURE ++ ;; ++ *.$libext) linkmode=oldlib ;; ++ *.lo | *.$objext) linkmode=obj ;; ++ *.la) linkmode=lib ;; ++ *) linkmode=prog ;; # Anything else should be a program. ++ esac ++ ++ case $host in ++ *cygwin* | *mingw* | *pw32*) ++ # don't eliminate duplications in $postdeps and $predeps ++ duplicate_compiler_generated_deps=yes ++ ;; ++ *) ++ duplicate_compiler_generated_deps=$duplicate_deps ++ ;; ++ esac ++ specialdeplibs= ++ ++ libs= ++ # Find all interdependent deplibs by searching for libraries ++ # that are linked more than once (e.g. -la -lb -la) ++ for deplib in $deplibs; do ++ if test "X$duplicate_deps" = "Xyes" ; then ++ case "$libs " in ++ *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; ++ esac ++ fi ++ libs="$libs $deplib" ++ done ++ ++ if test "$linkmode" = lib; then ++ libs="$predeps $libs $compiler_lib_search_path $postdeps" ++ ++ # Compute libraries that are listed more than once in $predeps ++ # $postdeps and mark them as special (i.e., whose duplicates are ++ # not to be eliminated). ++ pre_post_deps= ++ if test "X$duplicate_compiler_generated_deps" = "Xyes" ; then ++ for pre_post_dep in $predeps $postdeps; do ++ case "$pre_post_deps " in ++ *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;; ++ esac ++ pre_post_deps="$pre_post_deps $pre_post_dep" ++ done ++ fi ++ pre_post_deps= ++ fi ++ ++ deplibs= ++ newdependency_libs= ++ newlib_search_path= ++ need_relink=no # whether we're linking any uninstalled libtool libraries ++ notinst_deplibs= # not-installed libtool libraries ++ case $linkmode in ++ lib) ++ passes="conv link" ++ for file in $dlfiles $dlprefiles; do ++ case $file in ++ *.la) ;; ++ *) ++ $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2 ++ exit $EXIT_FAILURE ++ ;; ++ esac ++ done ++ ;; ++ prog) ++ compile_deplibs= ++ finalize_deplibs= ++ alldeplibs=no ++ newdlfiles= ++ newdlprefiles= ++ passes="conv scan dlopen dlpreopen link" ++ ;; ++ *) passes="conv" ++ ;; ++ esac ++ for pass in $passes; do ++ if test "$linkmode,$pass" = "lib,link" || ++ test "$linkmode,$pass" = "prog,scan"; then ++ libs="$deplibs" ++ deplibs= ++ fi ++ if test "$linkmode" = prog; then ++ case $pass in ++ dlopen) libs="$dlfiles" ;; ++ dlpreopen) libs="$dlprefiles" ;; ++ link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; ++ esac ++ fi ++ if test "$pass" = dlopen; then ++ # Collect dlpreopened libraries ++ save_deplibs="$deplibs" ++ deplibs= ++ fi ++ for deplib in $libs; do ++ lib= ++ found=no ++ case $deplib in ++ -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe) ++ if test "$linkmode,$pass" = "prog,link"; then ++ compile_deplibs="$deplib $compile_deplibs" ++ finalize_deplibs="$deplib $finalize_deplibs" ++ else ++ compiler_flags="$compiler_flags $deplib" ++ fi ++ continue ++ ;; ++ -l*) ++ if test "$linkmode" != lib && test "$linkmode" != prog; then ++ $echo "$modename: warning: \`-l' is ignored for archives/objects" 1>&2 ++ continue ++ fi ++ name=`$echo "X$deplib" | $Xsed -e 's/^-l//'` ++ for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do ++ for search_ext in .la $std_shrext .so .a; do ++ # Search the libtool library ++ lib="$searchdir/lib${name}${search_ext}" ++ if test -f "$lib"; then ++ if test "$search_ext" = ".la"; then ++ found=yes ++ else ++ found=no ++ fi ++ break 2 ++ fi ++ done ++ done ++ if test "$found" != yes; then ++ # deplib doesn't seem to be a libtool library ++ if test "$linkmode,$pass" = "prog,link"; then ++ compile_deplibs="$deplib $compile_deplibs" ++ finalize_deplibs="$deplib $finalize_deplibs" ++ else ++ deplibs="$deplib $deplibs" ++ test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" ++ fi ++ continue ++ else # deplib is a libtool library ++ # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, ++ # We need to do some special things here, and not later. ++ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then ++ case " $predeps $postdeps " in ++ *" $deplib "*) ++ if (${SED} -e '2q' $lib | ++ grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then ++ library_names= ++ old_library= ++ case $lib in ++ */* | *\\*) . $lib ;; ++ *) . ./$lib ;; ++ esac ++ for l in $old_library $library_names; do ++ ll="$l" ++ done ++ if test "X$ll" = "X$old_library" ; then # only static version available ++ found=no ++ ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` ++ test "X$ladir" = "X$lib" && ladir="." ++ lib=$ladir/$old_library ++ if test "$linkmode,$pass" = "prog,link"; then ++ compile_deplibs="$deplib $compile_deplibs" ++ finalize_deplibs="$deplib $finalize_deplibs" ++ else ++ deplibs="$deplib $deplibs" ++ test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" ++ fi ++ continue ++ fi ++ fi ++ ;; ++ *) ;; ++ esac ++ fi ++ fi ++ ;; # -l ++ -L*) ++ case $linkmode in ++ lib) ++ deplibs="$deplib $deplibs" ++ test "$pass" = conv && continue ++ newdependency_libs="$deplib $newdependency_libs" ++ newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` ++ ;; ++ prog) ++ if test "$pass" = conv; then ++ deplibs="$deplib $deplibs" ++ continue ++ fi ++ if test "$pass" = scan; then ++ deplibs="$deplib $deplibs" ++ else ++ compile_deplibs="$deplib $compile_deplibs" ++ finalize_deplibs="$deplib $finalize_deplibs" ++ fi ++ newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` ++ ;; ++ *) ++ $echo "$modename: warning: \`-L' is ignored for archives/objects" 1>&2 ++ ;; ++ esac # linkmode ++ continue ++ ;; # -L ++ -R*) ++ if test "$pass" = link; then ++ dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'` ++ # Make sure the xrpath contains only unique directories. ++ case "$xrpath " in ++ *" $dir "*) ;; ++ *) xrpath="$xrpath $dir" ;; ++ esac ++ fi ++ deplibs="$deplib $deplibs" ++ continue ++ ;; ++ *.la) lib="$deplib" ;; ++ *.$libext) ++ if test "$pass" = conv; then ++ deplibs="$deplib $deplibs" ++ continue ++ fi ++ case $linkmode in ++ lib) ++ valid_a_lib=no ++ case $deplibs_check_method in ++ match_pattern*) ++ set dummy $deplibs_check_method ++ match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` ++ if eval $echo \"$deplib\" 2>/dev/null \ ++ | $SED 10q \ ++ | $EGREP "$match_pattern_regex" > /dev/null; then ++ valid_a_lib=yes ++ fi ++ ;; ++ pass_all) ++ valid_a_lib=yes ++ ;; ++ esac ++ if test "$valid_a_lib" != yes; then ++ $echo ++ $echo "*** Warning: Trying to link with static lib archive $deplib." ++ $echo "*** I have the capability to make that library automatically link in when" ++ $echo "*** you link to this library. But I can only do this if you have a" ++ $echo "*** shared version of the library, which you do not appear to have" ++ $echo "*** because the file extensions .$libext of this argument makes me believe" ++ $echo "*** that it is just a static archive that I should not used here." ++ else ++ $echo ++ $echo "*** Warning: Linking the shared library $output against the" ++ $echo "*** static library $deplib is not portable!" ++ deplibs="$deplib $deplibs" ++ fi ++ continue ++ ;; ++ prog) ++ if test "$pass" != link; then ++ deplibs="$deplib $deplibs" ++ else ++ compile_deplibs="$deplib $compile_deplibs" ++ finalize_deplibs="$deplib $finalize_deplibs" ++ fi ++ continue ++ ;; ++ esac # linkmode ++ ;; # *.$libext ++ *.lo | *.$objext) ++ if test "$pass" = conv; then ++ deplibs="$deplib $deplibs" ++ elif test "$linkmode" = prog; then ++ if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then ++ # If there is no dlopen support or we're linking statically, ++ # we need to preload. ++ newdlprefiles="$newdlprefiles $deplib" ++ compile_deplibs="$deplib $compile_deplibs" ++ finalize_deplibs="$deplib $finalize_deplibs" ++ else ++ newdlfiles="$newdlfiles $deplib" ++ fi ++ fi ++ continue ++ ;; ++ %DEPLIBS%) ++ alldeplibs=yes ++ continue ++ ;; ++ esac # case $deplib ++ if test "$found" = yes || test -f "$lib"; then : ++ else ++ $echo "$modename: cannot find the library \`$lib' or unhandled argument \`$deplib'" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ ++ # Check to see that this really is a libtool archive. ++ if (${SED} -e '2q' $lib | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : ++ else ++ $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ ++ ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` ++ test "X$ladir" = "X$lib" && ladir="." ++ ++ dlname= ++ dlopen= ++ dlpreopen= ++ libdir= ++ library_names= ++ old_library= ++ # If the library was installed with an old release of libtool, ++ # it will not redefine variables installed, or shouldnotlink ++ installed=yes ++ shouldnotlink=no ++ avoidtemprpath= ++ ++ ++ # Read the .la file ++ case $lib in ++ */* | *\\*) . $lib ;; ++ *) . ./$lib ;; ++ esac ++ ++ if test "$linkmode,$pass" = "lib,link" || ++ test "$linkmode,$pass" = "prog,scan" || ++ { test "$linkmode" != prog && test "$linkmode" != lib; }; then ++ test -n "$dlopen" && dlfiles="$dlfiles $dlopen" ++ test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" ++ fi ++ ++ if test "$pass" = conv; then ++ # Only check for convenience libraries ++ deplibs="$lib $deplibs" ++ if test -z "$libdir"; then ++ if test -z "$old_library"; then ++ $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ # It is a libtool convenience library, so add in its objects. ++ convenience="$convenience $ladir/$objdir/$old_library" ++ old_convenience="$old_convenience $ladir/$objdir/$old_library" ++ tmp_libs= ++ for deplib in $dependency_libs; do ++ deplibs="$deplib $deplibs" ++ if test "X$duplicate_deps" = "Xyes" ; then ++ case "$tmp_libs " in ++ *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; ++ esac ++ fi ++ tmp_libs="$tmp_libs $deplib" ++ done ++ elif test "$linkmode" != prog && test "$linkmode" != lib; then ++ $echo "$modename: \`$lib' is not a convenience library" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ continue ++ fi # $pass = conv ++ ++ ++ # Get the name of the library we link against. ++ linklib= ++ for l in $old_library $library_names; do ++ linklib="$l" ++ done ++ if test -z "$linklib"; then ++ $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ ++ # This library was specified with -dlopen. ++ if test "$pass" = dlopen; then ++ if test -z "$libdir"; then ++ $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ if test -z "$dlname" || ++ test "$dlopen_support" != yes || ++ test "$build_libtool_libs" = no; then ++ # If there is no dlname, no dlopen support or we're linking ++ # statically, we need to preload. We also need to preload any ++ # dependent libraries so libltdl's deplib preloader doesn't ++ # bomb out in the load deplibs phase. ++ dlprefiles="$dlprefiles $lib $dependency_libs" ++ else ++ newdlfiles="$newdlfiles $lib" ++ fi ++ continue ++ fi # $pass = dlopen ++ ++ # We need an absolute path. ++ case $ladir in ++ [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; ++ *) ++ abs_ladir=`cd "$ladir" && pwd` ++ if test -z "$abs_ladir"; then ++ $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2 ++ $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 ++ abs_ladir="$ladir" ++ fi ++ ;; ++ esac ++ laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` ++ ++ # Find the relevant object directory and library name. ++ if test "X$installed" = Xyes; then ++ if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then ++ $echo "$modename: warning: library \`$lib' was moved." 1>&2 ++ dir="$ladir" ++ absdir="$abs_ladir" ++ libdir="$abs_ladir" ++ else ++ dir="$libdir" ++ absdir="$libdir" ++ fi ++ test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes ++ else ++ if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then ++ dir="$ladir" ++ absdir="$abs_ladir" ++ # Remove this search path later ++ notinst_path="$notinst_path $abs_ladir" ++ else ++ dir="$ladir/$objdir" ++ absdir="$abs_ladir/$objdir" ++ # Remove this search path later ++ notinst_path="$notinst_path $abs_ladir" ++ fi ++ fi # $installed = yes ++ name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` ++ ++ # This library was specified with -dlpreopen. ++ if test "$pass" = dlpreopen; then ++ if test -z "$libdir"; then ++ $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ # Prefer using a static library (so that no silly _DYNAMIC symbols ++ # are required to link). ++ if test -n "$old_library"; then ++ newdlprefiles="$newdlprefiles $dir/$old_library" ++ # Otherwise, use the dlname, so that lt_dlopen finds it. ++ elif test -n "$dlname"; then ++ newdlprefiles="$newdlprefiles $dir/$dlname" ++ else ++ newdlprefiles="$newdlprefiles $dir/$linklib" ++ fi ++ fi # $pass = dlpreopen ++ ++ if test -z "$libdir"; then ++ # Link the convenience library ++ if test "$linkmode" = lib; then ++ deplibs="$dir/$old_library $deplibs" ++ elif test "$linkmode,$pass" = "prog,link"; then ++ compile_deplibs="$dir/$old_library $compile_deplibs" ++ finalize_deplibs="$dir/$old_library $finalize_deplibs" ++ else ++ deplibs="$lib $deplibs" # used for prog,scan pass ++ fi ++ continue ++ fi ++ ++ ++ if test "$linkmode" = prog && test "$pass" != link; then ++ newlib_search_path="$newlib_search_path $ladir" ++ deplibs="$lib $deplibs" ++ ++ linkalldeplibs=no ++ if test "$link_all_deplibs" != no || test -z "$library_names" || ++ test "$build_libtool_libs" = no; then ++ linkalldeplibs=yes ++ fi ++ ++ tmp_libs= ++ for deplib in $dependency_libs; do ++ case $deplib in ++ -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test ++ esac ++ # Need to link against all dependency_libs? ++ if test "$linkalldeplibs" = yes; then ++ deplibs="$deplib $deplibs" ++ else ++ # Need to hardcode shared library paths ++ # or/and link against static libraries ++ newdependency_libs="$deplib $newdependency_libs" ++ fi ++ if test "X$duplicate_deps" = "Xyes" ; then ++ case "$tmp_libs " in ++ *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; ++ esac ++ fi ++ tmp_libs="$tmp_libs $deplib" ++ done # for deplib ++ continue ++ fi # $linkmode = prog... ++ ++ if test "$linkmode,$pass" = "prog,link"; then ++ if test -n "$library_names" && ++ { { test "$prefer_static_libs" = no || ++ test "$prefer_static_libs,$installed" = "built,yes"; } || ++ test -z "$old_library"; }; then ++ # We need to hardcode the library path ++ if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then ++ # Make sure the rpath contains only unique directories. ++ case "$temp_rpath " in ++ *" $dir "*) ;; ++ *" $absdir "*) ;; ++ *) temp_rpath="$temp_rpath $absdir" ;; ++ esac ++ fi ++ ++ # Hardcode the library path. ++ # Skip directories that are in the system default run-time ++ # search path. ++ case " $sys_lib_dlsearch_path " in ++ *" $absdir "*) ;; ++ *) ++ case "$compile_rpath " in ++ *" $absdir "*) ;; ++ *) compile_rpath="$compile_rpath $absdir" ++ esac ++ ;; ++ esac ++ case " $sys_lib_dlsearch_path " in ++ *" $libdir "*) ;; ++ *) ++ case "$finalize_rpath " in ++ *" $libdir "*) ;; ++ *) finalize_rpath="$finalize_rpath $libdir" ++ esac ++ ;; ++ esac ++ fi # $linkmode,$pass = prog,link... ++ ++ if test "$alldeplibs" = yes && ++ { test "$deplibs_check_method" = pass_all || ++ { test "$build_libtool_libs" = yes && ++ test -n "$library_names"; }; }; then ++ # We only need to search for static libraries ++ continue ++ fi ++ fi ++ ++ link_static=no # Whether the deplib will be linked statically ++ use_static_libs=$prefer_static_libs ++ if test "$use_static_libs" = built && test "$installed" = yes ; then ++ use_static_libs=no ++ fi ++ if test -n "$library_names" && ++ { test "$use_static_libs" = no || test -z "$old_library"; }; then ++ if test "$installed" = no; then ++ notinst_deplibs="$notinst_deplibs $lib" ++ need_relink=yes ++ fi ++ # This is a shared library ++ ++ # Warn about portability, can't link against -module's on ++ # some systems (darwin) ++ if test "$shouldnotlink" = yes && test "$pass" = link ; then ++ $echo ++ if test "$linkmode" = prog; then ++ $echo "*** Warning: Linking the executable $output against the loadable module" ++ else ++ $echo "*** Warning: Linking the shared library $output against the loadable module" ++ fi ++ $echo "*** $linklib is not portable!" ++ fi ++ if test "$linkmode" = lib && ++ test "$hardcode_into_libs" = yes; then ++ # Hardcode the library path. ++ # Skip directories that are in the system default run-time ++ # search path. ++ case " $sys_lib_dlsearch_path " in ++ *" $absdir "*) ;; ++ *) ++ case "$compile_rpath " in ++ *" $absdir "*) ;; ++ *) compile_rpath="$compile_rpath $absdir" ++ esac ++ ;; ++ esac ++ case " $sys_lib_dlsearch_path " in ++ *" $libdir "*) ;; ++ *) ++ case "$finalize_rpath " in ++ *" $libdir "*) ;; ++ *) finalize_rpath="$finalize_rpath $libdir" ++ esac ++ ;; ++ esac ++ fi ++ ++ if test -n "$old_archive_from_expsyms_cmds"; then ++ # figure out the soname ++ set dummy $library_names ++ realname="$2" ++ shift; shift ++ libname=`eval \\$echo \"$libname_spec\"` ++ # use dlname if we got it. it's perfectly good, no? ++ if test -n "$dlname"; then ++ soname="$dlname" ++ elif test -n "$soname_spec"; then ++ # bleh windows ++ case $host in ++ *cygwin* | mingw*) ++ major=`expr $current - $age` ++ versuffix="-$major" ++ ;; ++ esac ++ eval soname=\"$soname_spec\" ++ else ++ soname="$realname" ++ fi ++ ++ # Make a new name for the extract_expsyms_cmds to use ++ soroot="$soname" ++ soname=`$echo $soroot | ${SED} -e 's/^.*\///'` ++ newlib="libimp-`$echo $soname | ${SED} 's/^lib//;s/\.dll$//'`.a" ++ ++ # If the library has no export list, then create one now ++ if test -f "$output_objdir/$soname-def"; then : ++ else ++ $show "extracting exported symbol list from \`$soname'" ++ save_ifs="$IFS"; IFS='~' ++ cmds=$extract_expsyms_cmds ++ for cmd in $cmds; do ++ IFS="$save_ifs" ++ eval cmd=\"$cmd\" ++ $show "$cmd" ++ $run eval "$cmd" || exit $? ++ done ++ IFS="$save_ifs" ++ fi ++ ++ # Create $newlib ++ if test -f "$output_objdir/$newlib"; then :; else ++ $show "generating import library for \`$soname'" ++ save_ifs="$IFS"; IFS='~' ++ cmds=$old_archive_from_expsyms_cmds ++ for cmd in $cmds; do ++ IFS="$save_ifs" ++ eval cmd=\"$cmd\" ++ $show "$cmd" ++ $run eval "$cmd" || exit $? ++ done ++ IFS="$save_ifs" ++ fi ++ # make sure the library variables are pointing to the new library ++ dir=$output_objdir ++ linklib=$newlib ++ fi # test -n "$old_archive_from_expsyms_cmds" ++ ++ if test "$linkmode" = prog || test "$mode" != relink; then ++ add_shlibpath= ++ add_dir= ++ add= ++ lib_linked=yes ++ case $hardcode_action in ++ immediate | unsupported) ++ if test "$hardcode_direct" = no; then ++ add="$dir/$linklib" ++ case $host in ++ *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; ++ *-*-sysv4*uw2*) add_dir="-L$dir" ;; ++ *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ ++ *-*-unixware7*) add_dir="-L$dir" ;; ++ *-*-darwin* ) ++ # if the lib is a module then we can not link against ++ # it, someone is ignoring the new warnings I added ++ if /usr/bin/file -L $add 2> /dev/null | ++ $EGREP ": [^:]* bundle" >/dev/null ; then ++ $echo "** Warning, lib $linklib is a module, not a shared library" ++ if test -z "$old_library" ; then ++ $echo ++ $echo "** And there doesn't seem to be a static archive available" ++ $echo "** The link will probably fail, sorry" ++ else ++ add="$dir/$old_library" ++ fi ++ fi ++ esac ++ elif test "$hardcode_minus_L" = no; then ++ case $host in ++ *-*-sunos*) add_shlibpath="$dir" ;; ++ esac ++ add_dir="-L$dir" ++ add="-l$name" ++ elif test "$hardcode_shlibpath_var" = no; then ++ add_shlibpath="$dir" ++ add="-l$name" ++ else ++ lib_linked=no ++ fi ++ ;; ++ relink) ++ if test "$hardcode_direct" = yes; then ++ add="$dir/$linklib" ++ elif test "$hardcode_minus_L" = yes; then ++ add_dir="-L$dir" ++ # Try looking first in the location we're being installed to. ++ if test -n "$inst_prefix_dir"; then ++ case $libdir in ++ [\\/]*) ++ add_dir="$add_dir -L$inst_prefix_dir$libdir" ++ ;; ++ esac ++ fi ++ add="-l$name" ++ elif test "$hardcode_shlibpath_var" = yes; then ++ add_shlibpath="$dir" ++ add="-l$name" ++ else ++ lib_linked=no ++ fi ++ ;; ++ *) lib_linked=no ;; ++ esac ++ ++ if test "$lib_linked" != yes; then ++ $echo "$modename: configuration error: unsupported hardcode properties" ++ exit $EXIT_FAILURE ++ fi ++ ++ if test -n "$add_shlibpath"; then ++ case :$compile_shlibpath: in ++ *":$add_shlibpath:"*) ;; ++ *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; ++ esac ++ fi ++ if test "$linkmode" = prog; then ++ test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" ++ test -n "$add" && compile_deplibs="$add $compile_deplibs" ++ else ++ test -n "$add_dir" && deplibs="$add_dir $deplibs" ++ test -n "$add" && deplibs="$add $deplibs" ++ if test "$hardcode_direct" != yes && \ ++ test "$hardcode_minus_L" != yes && \ ++ test "$hardcode_shlibpath_var" = yes; then ++ case :$finalize_shlibpath: in ++ *":$libdir:"*) ;; ++ *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; ++ esac ++ fi ++ fi ++ fi ++ ++ if test "$linkmode" = prog || test "$mode" = relink; then ++ add_shlibpath= ++ add_dir= ++ add= ++ # Finalize command for both is simple: just hardcode it. ++ if test "$hardcode_direct" = yes; then ++ add="$libdir/$linklib" ++ elif test "$hardcode_minus_L" = yes; then ++ add_dir="-L$libdir" ++ add="-l$name" ++ elif test "$hardcode_shlibpath_var" = yes; then ++ case :$finalize_shlibpath: in ++ *":$libdir:"*) ;; ++ *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; ++ esac ++ add="-l$name" ++ elif test "$hardcode_automatic" = yes; then ++ if test -n "$inst_prefix_dir" && ++ test -f "$inst_prefix_dir$libdir/$linklib" ; then ++ add="$inst_prefix_dir$libdir/$linklib" ++ else ++ add="$libdir/$linklib" ++ fi ++ else ++ # We cannot seem to hardcode it, guess we'll fake it. ++ add_dir="-L$libdir" ++ # Try looking first in the location we're being installed to. ++ if test -n "$inst_prefix_dir"; then ++ case $libdir in ++ [\\/]*) ++ add_dir="$add_dir -L$inst_prefix_dir$libdir" ++ ;; ++ esac ++ fi ++ add="-l$name" ++ fi ++ ++ if test "$linkmode" = prog; then ++ test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" ++ test -n "$add" && finalize_deplibs="$add $finalize_deplibs" ++ else ++ test -n "$add_dir" && deplibs="$add_dir $deplibs" ++ test -n "$add" && deplibs="$add $deplibs" ++ fi ++ fi ++ elif test "$linkmode" = prog; then ++ # Here we assume that one of hardcode_direct or hardcode_minus_L ++ # is not unsupported. This is valid on all known static and ++ # shared platforms. ++ if test "$hardcode_direct" != unsupported; then ++ test -n "$old_library" && linklib="$old_library" ++ compile_deplibs="$dir/$linklib $compile_deplibs" ++ finalize_deplibs="$dir/$linklib $finalize_deplibs" ++ else ++ compile_deplibs="-l$name -L$dir $compile_deplibs" ++ finalize_deplibs="-l$name -L$dir $finalize_deplibs" ++ fi ++ elif test "$build_libtool_libs" = yes; then ++ # Not a shared library ++ if test "$deplibs_check_method" != pass_all; then ++ # We're trying link a shared library against a static one ++ # but the system doesn't support it. ++ ++ # Just print a warning and add the library to dependency_libs so ++ # that the program can be linked against the static library. ++ $echo ++ $echo "*** Warning: This system can not link to static lib archive $lib." ++ $echo "*** I have the capability to make that library automatically link in when" ++ $echo "*** you link to this library. But I can only do this if you have a" ++ $echo "*** shared version of the library, which you do not appear to have." ++ if test "$module" = yes; then ++ $echo "*** But as you try to build a module library, libtool will still create " ++ $echo "*** a static module, that should work as long as the dlopening application" ++ $echo "*** is linked with the -dlopen flag to resolve symbols at runtime." ++ if test -z "$global_symbol_pipe"; then ++ $echo ++ $echo "*** However, this would only work if libtool was able to extract symbol" ++ $echo "*** lists from a program, using \`nm' or equivalent, but libtool could" ++ $echo "*** not find such a program. So, this module is probably useless." ++ $echo "*** \`nm' from GNU binutils and a full rebuild may help." ++ fi ++ if test "$build_old_libs" = no; then ++ build_libtool_libs=module ++ build_old_libs=yes ++ else ++ build_libtool_libs=no ++ fi ++ fi ++ else ++ deplibs="$dir/$old_library $deplibs" ++ link_static=yes ++ fi ++ fi # link shared/static library? ++ ++ if test "$linkmode" = lib; then ++ if test -n "$dependency_libs" && ++ { test "$hardcode_into_libs" != yes || ++ test "$build_old_libs" = yes || ++ test "$link_static" = yes; }; then ++ # Extract -R from dependency_libs ++ temp_deplibs= ++ for libdir in $dependency_libs; do ++ case $libdir in ++ -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'` ++ case " $xrpath " in ++ *" $temp_xrpath "*) ;; ++ *) xrpath="$xrpath $temp_xrpath";; ++ esac;; ++ *) temp_deplibs="$temp_deplibs $libdir";; ++ esac ++ done ++ dependency_libs="$temp_deplibs" ++ fi ++ ++ newlib_search_path="$newlib_search_path $absdir" ++ # Link against this library ++ test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" ++ # ... and its dependency_libs ++ tmp_libs= ++ for deplib in $dependency_libs; do ++ newdependency_libs="$deplib $newdependency_libs" ++ if test "X$duplicate_deps" = "Xyes" ; then ++ case "$tmp_libs " in ++ *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; ++ esac ++ fi ++ tmp_libs="$tmp_libs $deplib" ++ done ++ ++ if test "$link_all_deplibs" != no; then ++ # Add the search paths of all dependency libraries ++ for deplib in $dependency_libs; do ++ case $deplib in ++ -L*) path="$deplib" ;; ++ *.la) ++ dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'` ++ test "X$dir" = "X$deplib" && dir="." ++ # We need an absolute path. ++ case $dir in ++ [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; ++ *) ++ absdir=`cd "$dir" && pwd` ++ if test -z "$absdir"; then ++ $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2 ++ absdir="$dir" ++ fi ++ ;; ++ esac ++ if grep "^installed=no" $deplib > /dev/null; then ++ path="$absdir/$objdir" ++ else ++ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` ++ if test -z "$libdir"; then ++ $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ if test "$absdir" != "$libdir"; then ++ $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2 ++ fi ++ path="$absdir" ++ fi ++ depdepl= ++ case $host in ++ *-*-darwin*) ++ # we do not want to link against static libs, ++ # but need to link against shared ++ eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` ++ if test -n "$deplibrary_names" ; then ++ for tmp in $deplibrary_names ; do ++ depdepl=$tmp ++ done ++ if test -f "$path/$depdepl" ; then ++ depdepl="$path/$depdepl" ++ fi ++ # do not add paths which are already there ++ case " $newlib_search_path " in ++ *" $path "*) ;; ++ *) newlib_search_path="$newlib_search_path $path";; ++ esac ++ fi ++ path="" ++ ;; ++ *) ++ path="-L$path" ++ ;; ++ esac ++ ;; ++ -l*) ++ case $host in ++ *-*-darwin*) ++ # Again, we only want to link against shared libraries ++ eval tmp_libs=`$echo "X$deplib" | $Xsed -e "s,^\-l,,"` ++ for tmp in $newlib_search_path ; do ++ if test -f "$tmp/lib$tmp_libs.dylib" ; then ++ eval depdepl="$tmp/lib$tmp_libs.dylib" ++ break ++ fi ++ done ++ path="" ++ ;; ++ *) continue ;; ++ esac ++ ;; ++ *) continue ;; ++ esac ++ case " $deplibs " in ++ *" $path "*) ;; ++ *) deplibs="$path $deplibs" ;; ++ esac ++ case " $deplibs " in ++ *" $depdepl "*) ;; ++ *) deplibs="$depdepl $deplibs" ;; ++ esac ++ done ++ fi # link_all_deplibs != no ++ fi # linkmode = lib ++ done # for deplib in $libs ++ dependency_libs="$newdependency_libs" ++ if test "$pass" = dlpreopen; then ++ # Link the dlpreopened libraries before other libraries ++ for deplib in $save_deplibs; do ++ deplibs="$deplib $deplibs" ++ done ++ fi ++ if test "$pass" != dlopen; then ++ if test "$pass" != conv; then ++ # Make sure lib_search_path contains only unique directories. ++ lib_search_path= ++ for dir in $newlib_search_path; do ++ case "$lib_search_path " in ++ *" $dir "*) ;; ++ *) lib_search_path="$lib_search_path $dir" ;; ++ esac ++ done ++ newlib_search_path= ++ fi ++ ++ if test "$linkmode,$pass" != "prog,link"; then ++ vars="deplibs" ++ else ++ vars="compile_deplibs finalize_deplibs" ++ fi ++ for var in $vars dependency_libs; do ++ # Add libraries to $var in reverse order ++ eval tmp_libs=\"\$$var\" ++ new_libs= ++ for deplib in $tmp_libs; do ++ # FIXME: Pedantically, this is the right thing to do, so ++ # that some nasty dependency loop isn't accidentally ++ # broken: ++ #new_libs="$deplib $new_libs" ++ # Pragmatically, this seems to cause very few problems in ++ # practice: ++ case $deplib in ++ -L*) new_libs="$deplib $new_libs" ;; ++ -R*) ;; ++ *) ++ # And here is the reason: when a library appears more ++ # than once as an explicit dependence of a library, or ++ # is implicitly linked in more than once by the ++ # compiler, it is considered special, and multiple ++ # occurrences thereof are not removed. Compare this ++ # with having the same library being listed as a ++ # dependency of multiple other libraries: in this case, ++ # we know (pedantically, we assume) the library does not ++ # need to be listed more than once, so we keep only the ++ # last copy. This is not always right, but it is rare ++ # enough that we require users that really mean to play ++ # such unportable linking tricks to link the library ++ # using -Wl,-lname, so that libtool does not consider it ++ # for duplicate removal. ++ case " $specialdeplibs " in ++ *" $deplib "*) new_libs="$deplib $new_libs" ;; ++ *) ++ case " $new_libs " in ++ *" $deplib "*) ;; ++ *) new_libs="$deplib $new_libs" ;; ++ esac ++ ;; ++ esac ++ ;; ++ esac ++ done ++ tmp_libs= ++ for deplib in $new_libs; do ++ case $deplib in ++ -L*) ++ case " $tmp_libs " in ++ *" $deplib "*) ;; ++ *) tmp_libs="$tmp_libs $deplib" ;; ++ esac ++ ;; ++ *) tmp_libs="$tmp_libs $deplib" ;; ++ esac ++ done ++ eval $var=\"$tmp_libs\" ++ done # for var ++ fi ++ # Last step: remove runtime libs from dependency_libs ++ # (they stay in deplibs) ++ tmp_libs= ++ for i in $dependency_libs ; do ++ case " $predeps $postdeps $compiler_lib_search_path " in ++ *" $i "*) ++ i="" ++ ;; ++ esac ++ if test -n "$i" ; then ++ tmp_libs="$tmp_libs $i" ++ fi ++ done ++ dependency_libs=$tmp_libs ++ done # for pass ++ if test "$linkmode" = prog; then ++ dlfiles="$newdlfiles" ++ dlprefiles="$newdlprefiles" ++ fi ++ ++ case $linkmode in ++ oldlib) ++ if test -n "$deplibs"; then ++ $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2 ++ fi ++ ++ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then ++ $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2 ++ fi ++ ++ if test -n "$rpath"; then ++ $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2 ++ fi ++ ++ if test -n "$xrpath"; then ++ $echo "$modename: warning: \`-R' is ignored for archives" 1>&2 ++ fi ++ ++ if test -n "$vinfo"; then ++ $echo "$modename: warning: \`-version-info/-version-number' is ignored for archives" 1>&2 ++ fi ++ ++ if test -n "$release"; then ++ $echo "$modename: warning: \`-release' is ignored for archives" 1>&2 ++ fi ++ ++ if test -n "$export_symbols" || test -n "$export_symbols_regex"; then ++ $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2 ++ fi ++ ++ # Now set the variables for building old libraries. ++ build_libtool_libs=no ++ oldlibs="$output" ++ objs="$objs$old_deplibs" ++ ;; ++ ++ lib) ++ # Make sure we only generate libraries of the form `libNAME.la'. ++ case $outputname in ++ lib*) ++ name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` ++ eval shared_ext=\"$shrext_cmds\" ++ eval libname=\"$libname_spec\" ++ ;; ++ *) ++ if test "$module" = no; then ++ $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2 ++ $echo "$help" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ if test "$need_lib_prefix" != no; then ++ # Add the "lib" prefix for modules if required ++ name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` ++ eval shared_ext=\"$shrext_cmds\" ++ eval libname=\"$libname_spec\" ++ else ++ libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` ++ fi ++ ;; ++ esac ++ ++ if test -n "$objs"; then ++ if test "$deplibs_check_method" != pass_all; then ++ $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1 ++ exit $EXIT_FAILURE ++ else ++ $echo ++ $echo "*** Warning: Linking the shared library $output against the non-libtool" ++ $echo "*** objects $objs is not portable!" ++ libobjs="$libobjs $objs" ++ fi ++ fi ++ ++ if test "$dlself" != no; then ++ $echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2 ++ fi ++ ++ set dummy $rpath ++ if test "$#" -gt 2; then ++ $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2 ++ fi ++ install_libdir="$2" ++ ++ oldlibs= ++ if test -z "$rpath"; then ++ if test "$build_libtool_libs" = yes; then ++ # Building a libtool convenience library. ++ # Some compilers have problems with a `.al' extension so ++ # convenience libraries should have the same extension an ++ # archive normally would. ++ oldlibs="$output_objdir/$libname.$libext $oldlibs" ++ build_libtool_libs=convenience ++ build_old_libs=yes ++ fi ++ ++ if test -n "$vinfo"; then ++ $echo "$modename: warning: \`-version-info/-version-number' is ignored for convenience libraries" 1>&2 ++ fi ++ ++ if test -n "$release"; then ++ $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2 ++ fi ++ else ++ ++ # Parse the version information argument. ++ save_ifs="$IFS"; IFS=':' ++ set dummy $vinfo 0 0 0 ++ IFS="$save_ifs" ++ ++ if test -n "$8"; then ++ $echo "$modename: too many parameters to \`-version-info'" 1>&2 ++ $echo "$help" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ ++ # convert absolute version numbers to libtool ages ++ # this retains compatibility with .la files and attempts ++ # to make the code below a bit more comprehensible ++ ++ case $vinfo_number in ++ yes) ++ number_major="$2" ++ number_minor="$3" ++ number_revision="$4" ++ # ++ # There are really only two kinds -- those that ++ # use the current revision as the major version ++ # and those that subtract age and use age as ++ # a minor version. But, then there is irix ++ # which has an extra 1 added just for fun ++ # ++ case $version_type in ++ darwin|linux|osf|windows|none) ++ current=`expr $number_major + $number_minor` ++ age="$number_minor" ++ revision="$number_revision" ++ ;; ++ freebsd-aout|freebsd-elf|sunos) ++ current="$number_major" ++ revision="$number_minor" ++ age="0" ++ ;; ++ irix|nonstopux) ++ current=`expr $number_major + $number_minor - 1` ++ age="$number_minor" ++ revision="$number_minor" ++ ;; ++ esac ++ ;; ++ no) ++ current="$2" ++ revision="$3" ++ age="$4" ++ ;; ++ esac ++ ++ # Check that each of the things are valid numbers. ++ case $current in ++ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; ++ *) ++ $echo "$modename: CURRENT \`$current' must be a nonnegative integer" 1>&2 ++ $echo "$modename: \`$vinfo' is not valid version information" 1>&2 ++ exit $EXIT_FAILURE ++ ;; ++ esac ++ ++ case $revision in ++ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; ++ *) ++ $echo "$modename: REVISION \`$revision' must be a nonnegative integer" 1>&2 ++ $echo "$modename: \`$vinfo' is not valid version information" 1>&2 ++ exit $EXIT_FAILURE ++ ;; ++ esac ++ ++ case $age in ++ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; ++ *) ++ $echo "$modename: AGE \`$age' must be a nonnegative integer" 1>&2 ++ $echo "$modename: \`$vinfo' is not valid version information" 1>&2 ++ exit $EXIT_FAILURE ++ ;; ++ esac ++ ++ if test "$age" -gt "$current"; then ++ $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2 ++ $echo "$modename: \`$vinfo' is not valid version information" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ ++ # Calculate the version variables. ++ major= ++ versuffix= ++ verstring= ++ case $version_type in ++ none) ;; ++ ++ darwin) ++ # Like Linux, but with the current version available in ++ # verstring for coding it into the library header ++ major=.`expr $current - $age` ++ versuffix="$major.$age.$revision" ++ # Darwin ld doesn't like 0 for these options... ++ minor_current=`expr $current + 1` ++ verstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" ++ ;; ++ ++ freebsd-aout) ++ major=".$current" ++ versuffix=".$current.$revision"; ++ ;; ++ ++ freebsd-elf) ++ major=".$current" ++ versuffix=".$current"; ++ ;; ++ ++ irix | nonstopux) ++ major=`expr $current - $age + 1` ++ ++ case $version_type in ++ nonstopux) verstring_prefix=nonstopux ;; ++ *) verstring_prefix=sgi ;; ++ esac ++ verstring="$verstring_prefix$major.$revision" ++ ++ # Add in all the interfaces that we are compatible with. ++ loop=$revision ++ while test "$loop" -ne 0; do ++ iface=`expr $revision - $loop` ++ loop=`expr $loop - 1` ++ verstring="$verstring_prefix$major.$iface:$verstring" ++ done ++ ++ # Before this point, $major must not contain `.'. ++ major=.$major ++ versuffix="$major.$revision" ++ ;; ++ ++ linux) ++ major=.`expr $current - $age` ++ versuffix="$major.$age.$revision" ++ ;; ++ ++ osf) ++ major=.`expr $current - $age` ++ versuffix=".$current.$age.$revision" ++ verstring="$current.$age.$revision" ++ ++ # Add in all the interfaces that we are compatible with. ++ loop=$age ++ while test "$loop" -ne 0; do ++ iface=`expr $current - $loop` ++ loop=`expr $loop - 1` ++ verstring="$verstring:${iface}.0" ++ done ++ ++ # Make executables depend on our current version. ++ verstring="$verstring:${current}.0" ++ ;; ++ ++ sunos) ++ major=".$current" ++ versuffix=".$current.$revision" ++ ;; ++ ++ windows) ++ # Use '-' rather than '.', since we only want one ++ # extension on DOS 8.3 filesystems. ++ major=`expr $current - $age` ++ versuffix="-$major" ++ ;; ++ ++ *) ++ $echo "$modename: unknown library version type \`$version_type'" 1>&2 ++ $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 ++ exit $EXIT_FAILURE ++ ;; ++ esac ++ ++ # Clear the version info if we defaulted, and they specified a release. ++ if test -z "$vinfo" && test -n "$release"; then ++ major= ++ case $version_type in ++ darwin) ++ # we can't check for "0.0" in archive_cmds due to quoting ++ # problems, so we reset it completely ++ verstring= ++ ;; ++ *) ++ verstring="0.0" ++ ;; ++ esac ++ if test "$need_version" = no; then ++ versuffix= ++ else ++ versuffix=".0.0" ++ fi ++ fi ++ ++ # Remove version info from name if versioning should be avoided ++ if test "$avoid_version" = yes && test "$need_version" = no; then ++ major= ++ versuffix= ++ verstring="" ++ fi ++ ++ # Check to see if the archive will have undefined symbols. ++ if test "$allow_undefined" = yes; then ++ if test "$allow_undefined_flag" = unsupported; then ++ $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2 ++ build_libtool_libs=no ++ build_old_libs=yes ++ fi ++ else ++ # Don't allow undefined symbols. ++ allow_undefined_flag="$no_undefined_flag" ++ fi ++ fi ++ ++ if test "$mode" != relink; then ++ # Remove our outputs, but don't remove object files since they ++ # may have been created when compiling PIC objects. ++ removelist= ++ tempremovelist=`$echo "$output_objdir/*"` ++ for p in $tempremovelist; do ++ case $p in ++ *.$objext) ++ ;; ++ $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) ++ if test "X$precious_files_regex" != "X"; then ++ if echo $p | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 ++ then ++ continue ++ fi ++ fi ++ removelist="$removelist $p" ++ ;; ++ *) ;; ++ esac ++ done ++ if test -n "$removelist"; then ++ $show "${rm}r $removelist" ++ $run ${rm}r $removelist ++ fi ++ fi ++ ++ # Now set the variables for building old libraries. ++ if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then ++ oldlibs="$oldlibs $output_objdir/$libname.$libext" ++ ++ # Transform .lo files to .o files. ++ oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` ++ fi ++ ++ # Eliminate all temporary directories. ++# for path in $notinst_path; do ++# lib_search_path=`$echo "$lib_search_path " | ${SED} -e "s% $path % %g"` ++# deplibs=`$echo "$deplibs " | ${SED} -e "s% -L$path % %g"` ++# dependency_libs=`$echo "$dependency_libs " | ${SED} -e "s% -L$path % %g"` ++# done ++ ++ if test -n "$xrpath"; then ++ # If the user specified any rpath flags, then add them. ++ temp_xrpath= ++ for libdir in $xrpath; do ++ temp_xrpath="$temp_xrpath -R$libdir" ++ case "$finalize_rpath " in ++ *" $libdir "*) ;; ++ *) finalize_rpath="$finalize_rpath $libdir" ;; ++ esac ++ done ++ if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then ++ dependency_libs="$temp_xrpath $dependency_libs" ++ fi ++ fi ++ ++ # Make sure dlfiles contains only unique files that won't be dlpreopened ++ old_dlfiles="$dlfiles" ++ dlfiles= ++ for lib in $old_dlfiles; do ++ case " $dlprefiles $dlfiles " in ++ *" $lib "*) ;; ++ *) dlfiles="$dlfiles $lib" ;; ++ esac ++ done ++ ++ # Make sure dlprefiles contains only unique files ++ old_dlprefiles="$dlprefiles" ++ dlprefiles= ++ for lib in $old_dlprefiles; do ++ case "$dlprefiles " in ++ *" $lib "*) ;; ++ *) dlprefiles="$dlprefiles $lib" ;; ++ esac ++ done ++ ++ if test "$build_libtool_libs" = yes; then ++ if test -n "$rpath"; then ++ case $host in ++ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*) ++ # these systems don't actually have a c library (as such)! ++ ;; ++ *-*-rhapsody* | *-*-darwin1.[012]) ++ # Rhapsody C library is in the System framework ++ deplibs="$deplibs -framework System" ++ ;; ++ *-*-netbsd*) ++ # Don't link with libc until the a.out ld.so is fixed. ++ ;; ++ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) ++ # Do not include libc due to us having libc/libc_r. ++ ;; ++ *-*-sco3.2v5* | *-*-sco5v6*) ++ # Causes problems with __ctype ++ ;; ++ *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) ++ # Compiler inserts libc in the correct place for threads to work ++ ;; ++ *) ++ # Add libc to deplibs on all other systems if necessary. ++ if test "$build_libtool_need_lc" = "yes"; then ++ deplibs="$deplibs -lc" ++ fi ++ ;; ++ esac ++ fi ++ ++ # Transform deplibs into only deplibs that can be linked in shared. ++ name_save=$name ++ libname_save=$libname ++ release_save=$release ++ versuffix_save=$versuffix ++ major_save=$major ++ # I'm not sure if I'm treating the release correctly. I think ++ # release should show up in the -l (ie -lgmp5) so we don't want to ++ # add it in twice. Is that correct? ++ release="" ++ versuffix="" ++ major="" ++ newdeplibs= ++ droppeddeps=no ++ case $deplibs_check_method in ++ pass_all) ++ # Don't check for shared/static. Everything works. ++ # This might be a little naive. We might want to check ++ # whether the library exists or not. But this is on ++ # osf3 & osf4 and I'm not really sure... Just ++ # implementing what was already the behavior. ++ newdeplibs=$deplibs ++ ;; ++ test_compile) ++ # This code stresses the "libraries are programs" paradigm to its ++ # limits. Maybe even breaks it. We compile a program, linking it ++ # against the deplibs as a proxy for the library. Then we can check ++ # whether they linked in statically or dynamically with ldd. ++ $rm conftest.c ++ cat > conftest.c </dev/null` ++ for potent_lib in $potential_libs; do ++ # Follow soft links. ++ if ls -lLd "$potent_lib" 2>/dev/null \ ++ | grep " -> " >/dev/null; then ++ continue ++ fi ++ # The statement above tries to avoid entering an ++ # endless loop below, in case of cyclic links. ++ # We might still enter an endless loop, since a link ++ # loop can be closed while we follow links, ++ # but so what? ++ potlib="$potent_lib" ++ while test -h "$potlib" 2>/dev/null; do ++ potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` ++ case $potliblink in ++ [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; ++ *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; ++ esac ++ done ++ if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \ ++ | ${SED} 10q \ ++ | $EGREP "$file_magic_regex" > /dev/null; then ++ newdeplibs="$newdeplibs $a_deplib" ++ a_deplib="" ++ break 2 ++ fi ++ done ++ done ++ fi ++ if test -n "$a_deplib" ; then ++ droppeddeps=yes ++ $echo ++ $echo "*** Warning: linker path does not have real file for library $a_deplib." ++ $echo "*** I have the capability to make that library automatically link in when" ++ $echo "*** you link to this library. But I can only do this if you have a" ++ $echo "*** shared version of the library, which you do not appear to have" ++ $echo "*** because I did check the linker path looking for a file starting" ++ if test -z "$potlib" ; then ++ $echo "*** with $libname but no candidates were found. (...for file magic test)" ++ else ++ $echo "*** with $libname and none of the candidates passed a file format test" ++ $echo "*** using a file magic. Last file checked: $potlib" ++ fi ++ fi ++ else ++ # Add a -L argument. ++ newdeplibs="$newdeplibs $a_deplib" ++ fi ++ done # Gone through all deplibs. ++ ;; ++ match_pattern*) ++ set dummy $deplibs_check_method ++ match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` ++ for a_deplib in $deplibs; do ++ name=`expr $a_deplib : '-l\(.*\)'` ++ # If $name is empty we are operating on a -L argument. ++ if test -n "$name" && test "$name" != "0"; then ++ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then ++ case " $predeps $postdeps " in ++ *" $a_deplib "*) ++ newdeplibs="$newdeplibs $a_deplib" ++ a_deplib="" ++ ;; ++ esac ++ fi ++ if test -n "$a_deplib" ; then ++ libname=`eval \\$echo \"$libname_spec\"` ++ for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do ++ potential_libs=`ls $i/$libname[.-]* 2>/dev/null` ++ for potent_lib in $potential_libs; do ++ potlib="$potent_lib" # see symlink-check above in file_magic test ++ if eval $echo \"$potent_lib\" 2>/dev/null \ ++ | ${SED} 10q \ ++ | $EGREP "$match_pattern_regex" > /dev/null; then ++ newdeplibs="$newdeplibs $a_deplib" ++ a_deplib="" ++ break 2 ++ fi ++ done ++ done ++ fi ++ if test -n "$a_deplib" ; then ++ droppeddeps=yes ++ $echo ++ $echo "*** Warning: linker path does not have real file for library $a_deplib." ++ $echo "*** I have the capability to make that library automatically link in when" ++ $echo "*** you link to this library. But I can only do this if you have a" ++ $echo "*** shared version of the library, which you do not appear to have" ++ $echo "*** because I did check the linker path looking for a file starting" ++ if test -z "$potlib" ; then ++ $echo "*** with $libname but no candidates were found. (...for regex pattern test)" ++ else ++ $echo "*** with $libname and none of the candidates passed a file format test" ++ $echo "*** using a regex pattern. Last file checked: $potlib" ++ fi ++ fi ++ else ++ # Add a -L argument. ++ newdeplibs="$newdeplibs $a_deplib" ++ fi ++ done # Gone through all deplibs. ++ ;; ++ none | unknown | *) ++ newdeplibs="" ++ tmp_deplibs=`$echo "X $deplibs" | $Xsed -e 's/ -lc$//' \ ++ -e 's/ -[LR][^ ]*//g'` ++ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then ++ for i in $predeps $postdeps ; do ++ # can't use Xsed below, because $i might contain '/' ++ tmp_deplibs=`$echo "X $tmp_deplibs" | ${SED} -e "1s,^X,," -e "s,$i,,"` ++ done ++ fi ++ if $echo "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' \ ++ | grep . >/dev/null; then ++ $echo ++ if test "X$deplibs_check_method" = "Xnone"; then ++ $echo "*** Warning: inter-library dependencies are not supported in this platform." ++ else ++ $echo "*** Warning: inter-library dependencies are not known to be supported." ++ fi ++ $echo "*** All declared inter-library dependencies are being dropped." ++ droppeddeps=yes ++ fi ++ ;; ++ esac ++ versuffix=$versuffix_save ++ major=$major_save ++ release=$release_save ++ libname=$libname_save ++ name=$name_save ++ ++ case $host in ++ *-*-rhapsody* | *-*-darwin1.[012]) ++ # On Rhapsody replace the C library is the System framework ++ newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'` ++ ;; ++ esac ++ ++ if test "$droppeddeps" = yes; then ++ if test "$module" = yes; then ++ $echo ++ $echo "*** Warning: libtool could not satisfy all declared inter-library" ++ $echo "*** dependencies of module $libname. Therefore, libtool will create" ++ $echo "*** a static module, that should work as long as the dlopening" ++ $echo "*** application is linked with the -dlopen flag." ++ if test -z "$global_symbol_pipe"; then ++ $echo ++ $echo "*** However, this would only work if libtool was able to extract symbol" ++ $echo "*** lists from a program, using \`nm' or equivalent, but libtool could" ++ $echo "*** not find such a program. So, this module is probably useless." ++ $echo "*** \`nm' from GNU binutils and a full rebuild may help." ++ fi ++ if test "$build_old_libs" = no; then ++ oldlibs="$output_objdir/$libname.$libext" ++ build_libtool_libs=module ++ build_old_libs=yes ++ else ++ build_libtool_libs=no ++ fi ++ else ++ $echo "*** The inter-library dependencies that have been dropped here will be" ++ $echo "*** automatically added whenever a program is linked with this library" ++ $echo "*** or is declared to -dlopen it." ++ ++ if test "$allow_undefined" = no; then ++ $echo ++ $echo "*** Since this library must not contain undefined symbols," ++ $echo "*** because either the platform does not support them or" ++ $echo "*** it was explicitly requested with -no-undefined," ++ $echo "*** libtool will only create a static version of it." ++ if test "$build_old_libs" = no; then ++ oldlibs="$output_objdir/$libname.$libext" ++ build_libtool_libs=module ++ build_old_libs=yes ++ else ++ build_libtool_libs=no ++ fi ++ fi ++ fi ++ fi ++ # Done checking deplibs! ++ deplibs=$newdeplibs ++ fi ++ ++ ++ # move library search paths that coincide with paths to not yet ++ # installed libraries to the beginning of the library search list ++ new_libs= ++ for path in $notinst_path; do ++ case " $new_libs " in ++ *" -L$path/$objdir "*) ;; ++ *) ++ case " $deplibs " in ++ *" -L$path/$objdir "*) ++ new_libs="$new_libs -L$path/$objdir" ;; ++ esac ++ ;; ++ esac ++ done ++ for deplib in $deplibs; do ++ case $deplib in ++ -L*) ++ case " $new_libs " in ++ *" $deplib "*) ;; ++ *) new_libs="$new_libs $deplib" ;; ++ esac ++ ;; ++ *) new_libs="$new_libs $deplib" ;; ++ esac ++ done ++ deplibs="$new_libs" ++ ++ ++ # All the library-specific variables (install_libdir is set above). ++ library_names= ++ old_library= ++ dlname= ++ ++ # Test again, we may have decided not to build it any more ++ if test "$build_libtool_libs" = yes; then ++ if test "$hardcode_into_libs" = yes; then ++ # Hardcode the library paths ++ hardcode_libdirs= ++ dep_rpath= ++ rpath="$finalize_rpath" ++ test "$mode" != relink && rpath="$compile_rpath$rpath" ++ for libdir in $rpath; do ++ if test -n "$hardcode_libdir_flag_spec"; then ++ if test -n "$hardcode_libdir_separator"; then ++ if test -z "$hardcode_libdirs"; then ++ hardcode_libdirs="$libdir" ++ else ++ # Just accumulate the unique libdirs. ++ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in ++ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ++ ;; ++ *) ++ hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" ++ ;; ++ esac ++ fi ++ else ++ eval flag=\"$hardcode_libdir_flag_spec\" ++ dep_rpath="$dep_rpath $flag" ++ fi ++ elif test -n "$runpath_var"; then ++ case "$perm_rpath " in ++ *" $libdir "*) ;; ++ *) perm_rpath="$perm_rpath $libdir" ;; ++ esac ++ fi ++ done ++ # Substitute the hardcoded libdirs into the rpath. ++ if test -n "$hardcode_libdir_separator" && ++ test -n "$hardcode_libdirs"; then ++ libdir="$hardcode_libdirs" ++ if test -n "$hardcode_libdir_flag_spec_ld"; then ++ eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" ++ else ++ eval dep_rpath=\"$hardcode_libdir_flag_spec\" ++ fi ++ fi ++ if test -n "$runpath_var" && test -n "$perm_rpath"; then ++ # We should set the runpath_var. ++ rpath= ++ for dir in $perm_rpath; do ++ rpath="$rpath$dir:" ++ done ++ eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" ++ fi ++ test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" ++ fi ++ ++ shlibpath="$finalize_shlibpath" ++ test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" ++ if test -n "$shlibpath"; then ++ eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" ++ fi ++ ++ # Get the real and link names of the library. ++ eval shared_ext=\"$shrext_cmds\" ++ eval library_names=\"$library_names_spec\" ++ set dummy $library_names ++ realname="$2" ++ shift; shift ++ ++ if test -n "$soname_spec"; then ++ eval soname=\"$soname_spec\" ++ else ++ soname="$realname" ++ fi ++ if test -z "$dlname"; then ++ dlname=$soname ++ fi ++ ++ lib="$output_objdir/$realname" ++ linknames= ++ for link ++ do ++ linknames="$linknames $link" ++ done ++ ++ # Use standard objects if they are pic ++ test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` ++ ++ # Prepare the list of exported symbols ++ if test -z "$export_symbols"; then ++ if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then ++ $show "generating symbol list for \`$libname.la'" ++ export_symbols="$output_objdir/$libname.exp" ++ $run $rm $export_symbols ++ cmds=$export_symbols_cmds ++ save_ifs="$IFS"; IFS='~' ++ for cmd in $cmds; do ++ IFS="$save_ifs" ++ eval cmd=\"$cmd\" ++ if len=`expr "X$cmd" : ".*"` && ++ test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then ++ $show "$cmd" ++ $run eval "$cmd" || exit $? ++ skipped_export=false ++ else ++ # The command line is too long to execute in one step. ++ $show "using reloadable object file for export list..." ++ skipped_export=: ++ # Break out early, otherwise skipped_export may be ++ # set to false by a later but shorter cmd. ++ break ++ fi ++ done ++ IFS="$save_ifs" ++ if test -n "$export_symbols_regex"; then ++ $show "$EGREP -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\"" ++ $run eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' ++ $show "$mv \"${export_symbols}T\" \"$export_symbols\"" ++ $run eval '$mv "${export_symbols}T" "$export_symbols"' ++ fi ++ fi ++ fi ++ ++ if test -n "$export_symbols" && test -n "$include_expsyms"; then ++ $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"' ++ fi ++ ++ tmp_deplibs= ++ for test_deplib in $deplibs; do ++ case " $convenience " in ++ *" $test_deplib "*) ;; ++ *) ++ tmp_deplibs="$tmp_deplibs $test_deplib" ++ ;; ++ esac ++ done ++ deplibs="$tmp_deplibs" ++ ++ if test -n "$convenience"; then ++ if test -n "$whole_archive_flag_spec"; then ++ save_libobjs=$libobjs ++ eval libobjs=\"\$libobjs $whole_archive_flag_spec\" ++ else ++ gentop="$output_objdir/${outputname}x" ++ generated="$generated $gentop" ++ ++ func_extract_archives $gentop $convenience ++ libobjs="$libobjs $func_extract_archives_result" ++ fi ++ fi ++ ++ if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then ++ eval flag=\"$thread_safe_flag_spec\" ++ linker_flags="$linker_flags $flag" ++ fi ++ ++ # Make a backup of the uninstalled library when relinking ++ if test "$mode" = relink; then ++ $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $? ++ fi ++ ++ # Do each of the archive commands. ++ if test "$module" = yes && test -n "$module_cmds" ; then ++ if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then ++ eval test_cmds=\"$module_expsym_cmds\" ++ cmds=$module_expsym_cmds ++ else ++ eval test_cmds=\"$module_cmds\" ++ cmds=$module_cmds ++ fi ++ else ++ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then ++ eval test_cmds=\"$archive_expsym_cmds\" ++ cmds=$archive_expsym_cmds ++ else ++ eval test_cmds=\"$archive_cmds\" ++ cmds=$archive_cmds ++ fi ++ fi ++ ++ if test "X$skipped_export" != "X:" && ++ len=`expr "X$test_cmds" : ".*" 2>/dev/null` && ++ test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then ++ : ++ else ++ # The command line is too long to link in one step, link piecewise. ++ $echo "creating reloadable object files..." ++ ++ # Save the value of $output and $libobjs because we want to ++ # use them later. If we have whole_archive_flag_spec, we ++ # want to use save_libobjs as it was before ++ # whole_archive_flag_spec was expanded, because we can't ++ # assume the linker understands whole_archive_flag_spec. ++ # This may have to be revisited, in case too many ++ # convenience libraries get linked in and end up exceeding ++ # the spec. ++ if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then ++ save_libobjs=$libobjs ++ fi ++ save_output=$output ++ output_la=`$echo "X$output" | $Xsed -e "$basename"` ++ ++ # Clear the reloadable object creation command queue and ++ # initialize k to one. ++ test_cmds= ++ concat_cmds= ++ objlist= ++ delfiles= ++ last_robj= ++ k=1 ++ output=$output_objdir/$output_la-${k}.$objext ++ # Loop over the list of objects to be linked. ++ for obj in $save_libobjs ++ do ++ eval test_cmds=\"$reload_cmds $objlist $last_robj\" ++ if test "X$objlist" = X || ++ { len=`expr "X$test_cmds" : ".*" 2>/dev/null` && ++ test "$len" -le "$max_cmd_len"; }; then ++ objlist="$objlist $obj" ++ else ++ # The command $test_cmds is almost too long, add a ++ # command to the queue. ++ if test "$k" -eq 1 ; then ++ # The first file doesn't have a previous command to add. ++ eval concat_cmds=\"$reload_cmds $objlist $last_robj\" ++ else ++ # All subsequent reloadable object files will link in ++ # the last one created. ++ eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj\" ++ fi ++ last_robj=$output_objdir/$output_la-${k}.$objext ++ k=`expr $k + 1` ++ output=$output_objdir/$output_la-${k}.$objext ++ objlist=$obj ++ len=1 ++ fi ++ done ++ # Handle the remaining objects by creating one last ++ # reloadable object file. All subsequent reloadable object ++ # files will link in the last one created. ++ test -z "$concat_cmds" || concat_cmds=$concat_cmds~ ++ eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\" ++ ++ if ${skipped_export-false}; then ++ $show "generating symbol list for \`$libname.la'" ++ export_symbols="$output_objdir/$libname.exp" ++ $run $rm $export_symbols ++ libobjs=$output ++ # Append the command to create the export file. ++ eval concat_cmds=\"\$concat_cmds~$export_symbols_cmds\" ++ fi ++ ++ # Set up a command to remove the reloadable object files ++ # after they are used. ++ i=0 ++ while test "$i" -lt "$k" ++ do ++ i=`expr $i + 1` ++ delfiles="$delfiles $output_objdir/$output_la-${i}.$objext" ++ done ++ ++ $echo "creating a temporary reloadable object file: $output" ++ ++ # Loop through the commands generated above and execute them. ++ save_ifs="$IFS"; IFS='~' ++ for cmd in $concat_cmds; do ++ IFS="$save_ifs" ++ $show "$cmd" ++ $run eval "$cmd" || exit $? ++ done ++ IFS="$save_ifs" ++ ++ libobjs=$output ++ # Restore the value of output. ++ output=$save_output ++ ++ if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then ++ eval libobjs=\"\$libobjs $whole_archive_flag_spec\" ++ fi ++ # Expand the library linking commands again to reset the ++ # value of $libobjs for piecewise linking. ++ ++ # Do each of the archive commands. ++ if test "$module" = yes && test -n "$module_cmds" ; then ++ if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then ++ cmds=$module_expsym_cmds ++ else ++ cmds=$module_cmds ++ fi ++ else ++ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then ++ cmds=$archive_expsym_cmds ++ else ++ cmds=$archive_cmds ++ fi ++ fi ++ ++ # Append the command to remove the reloadable object files ++ # to the just-reset $cmds. ++ eval cmds=\"\$cmds~\$rm $delfiles\" ++ fi ++ save_ifs="$IFS"; IFS='~' ++ for cmd in $cmds; do ++ IFS="$save_ifs" ++ eval cmd=\"$cmd\" ++ $show "$cmd" ++ $run eval "$cmd" || { ++ lt_exit=$? ++ ++ # Restore the uninstalled library and exit ++ if test "$mode" = relink; then ++ $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)' ++ fi ++ ++ exit $lt_exit ++ } ++ done ++ IFS="$save_ifs" ++ ++ # Restore the uninstalled library and exit ++ if test "$mode" = relink; then ++ $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $? ++ ++ if test -n "$convenience"; then ++ if test -z "$whole_archive_flag_spec"; then ++ $show "${rm}r $gentop" ++ $run ${rm}r "$gentop" ++ fi ++ fi ++ ++ exit $EXIT_SUCCESS ++ fi ++ ++ # Create links to the real library. ++ for linkname in $linknames; do ++ if test "$realname" != "$linkname"; then ++ $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)" ++ $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $? ++ fi ++ done ++ ++ # If -module or -export-dynamic was specified, set the dlname. ++ if test "$module" = yes || test "$export_dynamic" = yes; then ++ # On all known operating systems, these are identical. ++ dlname="$soname" ++ fi ++ fi ++ ;; ++ ++ obj) ++ if test -n "$deplibs"; then ++ $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 ++ fi ++ ++ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then ++ $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2 ++ fi ++ ++ if test -n "$rpath"; then ++ $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2 ++ fi ++ ++ if test -n "$xrpath"; then ++ $echo "$modename: warning: \`-R' is ignored for objects" 1>&2 ++ fi ++ ++ if test -n "$vinfo"; then ++ $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2 ++ fi ++ ++ if test -n "$release"; then ++ $echo "$modename: warning: \`-release' is ignored for objects" 1>&2 ++ fi ++ ++ case $output in ++ *.lo) ++ if test -n "$objs$old_deplibs"; then ++ $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ libobj="$output" ++ obj=`$echo "X$output" | $Xsed -e "$lo2o"` ++ ;; ++ *) ++ libobj= ++ obj="$output" ++ ;; ++ esac ++ ++ # Delete the old objects. ++ $run $rm $obj $libobj ++ ++ # Objects from convenience libraries. This assumes ++ # single-version convenience libraries. Whenever we create ++ # different ones for PIC/non-PIC, this we'll have to duplicate ++ # the extraction. ++ reload_conv_objs= ++ gentop= ++ # reload_cmds runs $LD directly, so let us get rid of ++ # -Wl from whole_archive_flag_spec and hope we can get by with ++ # turning comma into space.. ++ wl= ++ ++ if test -n "$convenience"; then ++ if test -n "$whole_archive_flag_spec"; then ++ eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" ++ reload_conv_objs=$reload_objs\ `$echo "X$tmp_whole_archive_flags" | $Xsed -e 's|,| |g'` ++ else ++ gentop="$output_objdir/${obj}x" ++ generated="$generated $gentop" ++ ++ func_extract_archives $gentop $convenience ++ reload_conv_objs="$reload_objs $func_extract_archives_result" ++ fi ++ fi ++ ++ # Create the old-style object. ++ reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test ++ ++ output="$obj" ++ cmds=$reload_cmds ++ save_ifs="$IFS"; IFS='~' ++ for cmd in $cmds; do ++ IFS="$save_ifs" ++ eval cmd=\"$cmd\" ++ $show "$cmd" ++ $run eval "$cmd" || exit $? ++ done ++ IFS="$save_ifs" ++ ++ # Exit if we aren't doing a library object file. ++ if test -z "$libobj"; then ++ if test -n "$gentop"; then ++ $show "${rm}r $gentop" ++ $run ${rm}r $gentop ++ fi ++ ++ exit $EXIT_SUCCESS ++ fi ++ ++ if test "$build_libtool_libs" != yes; then ++ if test -n "$gentop"; then ++ $show "${rm}r $gentop" ++ $run ${rm}r $gentop ++ fi ++ ++ # Create an invalid libtool object if no PIC, so that we don't ++ # accidentally link it into a program. ++ # $show "echo timestamp > $libobj" ++ # $run eval "echo timestamp > $libobj" || exit $? ++ exit $EXIT_SUCCESS ++ fi ++ ++ if test -n "$pic_flag" || test "$pic_mode" != default; then ++ # Only do commands if we really have different PIC objects. ++ reload_objs="$libobjs $reload_conv_objs" ++ output="$libobj" ++ cmds=$reload_cmds ++ save_ifs="$IFS"; IFS='~' ++ for cmd in $cmds; do ++ IFS="$save_ifs" ++ eval cmd=\"$cmd\" ++ $show "$cmd" ++ $run eval "$cmd" || exit $? ++ done ++ IFS="$save_ifs" ++ fi ++ ++ if test -n "$gentop"; then ++ $show "${rm}r $gentop" ++ $run ${rm}r $gentop ++ fi ++ ++ exit $EXIT_SUCCESS ++ ;; ++ ++ prog) ++ case $host in ++ *cygwin*) output=`$echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;; ++ esac ++ if test -n "$vinfo"; then ++ $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2 ++ fi ++ ++ if test -n "$release"; then ++ $echo "$modename: warning: \`-release' is ignored for programs" 1>&2 ++ fi ++ ++ if test "$preload" = yes; then ++ if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown && ++ test "$dlopen_self_static" = unknown; then ++ $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support." ++ fi ++ fi ++ ++ case $host in ++ *-*-rhapsody* | *-*-darwin1.[012]) ++ # On Rhapsody replace the C library is the System framework ++ compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'` ++ finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'` ++ ;; ++ esac ++ ++ case $host in ++ *darwin*) ++ # Don't allow lazy linking, it breaks C++ global constructors ++ if test "$tagname" = CXX ; then ++ compile_command="$compile_command ${wl}-bind_at_load" ++ finalize_command="$finalize_command ${wl}-bind_at_load" ++ fi ++ ;; ++ esac ++ ++ ++ # move library search paths that coincide with paths to not yet ++ # installed libraries to the beginning of the library search list ++ new_libs= ++ for path in $notinst_path; do ++ case " $new_libs " in ++ *" -L$path/$objdir "*) ;; ++ *) ++ case " $compile_deplibs " in ++ *" -L$path/$objdir "*) ++ new_libs="$new_libs -L$path/$objdir" ;; ++ esac ++ ;; ++ esac ++ done ++ for deplib in $compile_deplibs; do ++ case $deplib in ++ -L*) ++ case " $new_libs " in ++ *" $deplib "*) ;; ++ *) new_libs="$new_libs $deplib" ;; ++ esac ++ ;; ++ *) new_libs="$new_libs $deplib" ;; ++ esac ++ done ++ compile_deplibs="$new_libs" ++ ++ ++ compile_command="$compile_command $compile_deplibs" ++ finalize_command="$finalize_command $finalize_deplibs" ++ ++ if test -n "$rpath$xrpath"; then ++ # If the user specified any rpath flags, then add them. ++ for libdir in $rpath $xrpath; do ++ # This is the magic to use -rpath. ++ case "$finalize_rpath " in ++ *" $libdir "*) ;; ++ *) finalize_rpath="$finalize_rpath $libdir" ;; ++ esac ++ done ++ fi ++ ++ # Now hardcode the library paths ++ rpath= ++ hardcode_libdirs= ++ for libdir in $compile_rpath $finalize_rpath; do ++ if test -n "$hardcode_libdir_flag_spec"; then ++ if test -n "$hardcode_libdir_separator"; then ++ if test -z "$hardcode_libdirs"; then ++ hardcode_libdirs="$libdir" ++ else ++ # Just accumulate the unique libdirs. ++ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in ++ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ++ ;; ++ *) ++ hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" ++ ;; ++ esac ++ fi ++ else ++ eval flag=\"$hardcode_libdir_flag_spec\" ++ rpath="$rpath $flag" ++ fi ++ elif test -n "$runpath_var"; then ++ case "$perm_rpath " in ++ *" $libdir "*) ;; ++ *) perm_rpath="$perm_rpath $libdir" ;; ++ esac ++ fi ++ case $host in ++ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) ++ testbindir=`$echo "X$libdir" | $Xsed -e 's*/lib$*/bin*'` ++ case :$dllsearchpath: in ++ *":$libdir:"*) ;; ++ *) dllsearchpath="$dllsearchpath:$libdir";; ++ esac ++ case :$dllsearchpath: in ++ *":$testbindir:"*) ;; ++ *) dllsearchpath="$dllsearchpath:$testbindir";; ++ esac ++ ;; ++ esac ++ done ++ # Substitute the hardcoded libdirs into the rpath. ++ if test -n "$hardcode_libdir_separator" && ++ test -n "$hardcode_libdirs"; then ++ libdir="$hardcode_libdirs" ++ eval rpath=\" $hardcode_libdir_flag_spec\" ++ fi ++ compile_rpath="$rpath" ++ ++ rpath= ++ hardcode_libdirs= ++ for libdir in $finalize_rpath; do ++ if test -n "$hardcode_libdir_flag_spec"; then ++ if test -n "$hardcode_libdir_separator"; then ++ if test -z "$hardcode_libdirs"; then ++ hardcode_libdirs="$libdir" ++ else ++ # Just accumulate the unique libdirs. ++ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in ++ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ++ ;; ++ *) ++ hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" ++ ;; ++ esac ++ fi ++ else ++ eval flag=\"$hardcode_libdir_flag_spec\" ++ rpath="$rpath $flag" ++ fi ++ elif test -n "$runpath_var"; then ++ case "$finalize_perm_rpath " in ++ *" $libdir "*) ;; ++ *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; ++ esac ++ fi ++ done ++ # Substitute the hardcoded libdirs into the rpath. ++ if test -n "$hardcode_libdir_separator" && ++ test -n "$hardcode_libdirs"; then ++ libdir="$hardcode_libdirs" ++ eval rpath=\" $hardcode_libdir_flag_spec\" ++ fi ++ finalize_rpath="$rpath" ++ ++ if test -n "$libobjs" && test "$build_old_libs" = yes; then ++ # Transform all the library objects into standard objects. ++ compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` ++ finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` ++ fi ++ ++ dlsyms= ++ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then ++ if test -n "$NM" && test -n "$global_symbol_pipe"; then ++ dlsyms="${outputname}S.c" ++ else ++ $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2 ++ fi ++ fi ++ ++ if test -n "$dlsyms"; then ++ case $dlsyms in ++ "") ;; ++ *.c) ++ # Discover the nlist of each of the dlfiles. ++ nlist="$output_objdir/${outputname}.nm" ++ ++ $show "$rm $nlist ${nlist}S ${nlist}T" ++ $run $rm "$nlist" "${nlist}S" "${nlist}T" ++ ++ # Parse the name list into a source file. ++ $show "creating $output_objdir/$dlsyms" ++ ++ test -z "$run" && $echo > "$output_objdir/$dlsyms" "\ ++/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */ ++/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */ ++ ++#ifdef __cplusplus ++extern \"C\" { ++#endif ++ ++/* Prevent the only kind of declaration conflicts we can make. */ ++#define lt_preloaded_symbols some_other_symbol ++ ++/* External symbol declarations for the compiler. */\ ++" ++ ++ if test "$dlself" = yes; then ++ $show "generating symbol list for \`$output'" ++ ++ test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist" ++ ++ # Add our own program objects to the symbol list. ++ progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` ++ for arg in $progfiles; do ++ $show "extracting global C symbols from \`$arg'" ++ $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" ++ done ++ ++ if test -n "$exclude_expsyms"; then ++ $run eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' ++ $run eval '$mv "$nlist"T "$nlist"' ++ fi ++ ++ if test -n "$export_symbols_regex"; then ++ $run eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' ++ $run eval '$mv "$nlist"T "$nlist"' ++ fi ++ ++ # Prepare the list of exported symbols ++ if test -z "$export_symbols"; then ++ export_symbols="$output_objdir/$outputname.exp" ++ $run $rm $export_symbols ++ $run eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' ++ case $host in ++ *cygwin* | *mingw* ) ++ $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' ++ $run eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' ++ ;; ++ esac ++ else ++ $run eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' ++ $run eval 'grep -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' ++ $run eval 'mv "$nlist"T "$nlist"' ++ case $host in ++ *cygwin* | *mingw* ) ++ $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' ++ $run eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' ++ ;; ++ esac ++ fi ++ fi ++ ++ for arg in $dlprefiles; do ++ $show "extracting global C symbols from \`$arg'" ++ name=`$echo "$arg" | ${SED} -e 's%^.*/%%'` ++ $run eval '$echo ": $name " >> "$nlist"' ++ $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" ++ done ++ ++ if test -z "$run"; then ++ # Make sure we have at least an empty file. ++ test -f "$nlist" || : > "$nlist" ++ ++ if test -n "$exclude_expsyms"; then ++ $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T ++ $mv "$nlist"T "$nlist" ++ fi ++ ++ # Try sorting and uniquifying the output. ++ if grep -v "^: " < "$nlist" | ++ if sort -k 3 /dev/null 2>&1; then ++ sort -k 3 ++ else ++ sort +2 ++ fi | ++ uniq > "$nlist"S; then ++ : ++ else ++ grep -v "^: " < "$nlist" > "$nlist"S ++ fi ++ ++ if test -f "$nlist"S; then ++ eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"' ++ else ++ $echo '/* NONE */' >> "$output_objdir/$dlsyms" ++ fi ++ ++ $echo >> "$output_objdir/$dlsyms" "\ ++ ++#undef lt_preloaded_symbols ++ ++#if defined (__STDC__) && __STDC__ ++# define lt_ptr void * ++#else ++# define lt_ptr char * ++# define const ++#endif ++ ++/* The mapping between symbol names and symbols. */ ++" ++ ++ case $host in ++ *cygwin* | *mingw* ) ++ $echo >> "$output_objdir/$dlsyms" "\ ++/* DATA imports from DLLs on WIN32 can't be const, because ++ runtime relocations are performed -- see ld's documentation ++ on pseudo-relocs */ ++struct { ++" ++ ;; ++ * ) ++ $echo >> "$output_objdir/$dlsyms" "\ ++const struct { ++" ++ ;; ++ esac ++ ++ ++ $echo >> "$output_objdir/$dlsyms" "\ ++ const char *name; ++ lt_ptr address; ++} ++lt_preloaded_symbols[] = ++{\ ++" ++ ++ eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms" ++ ++ $echo >> "$output_objdir/$dlsyms" "\ ++ {0, (lt_ptr) 0} ++}; ++ ++/* This works around a problem in FreeBSD linker */ ++#ifdef FREEBSD_WORKAROUND ++static const void *lt_preloaded_setup() { ++ return lt_preloaded_symbols; ++} ++#endif ++ ++#ifdef __cplusplus ++} ++#endif\ ++" ++ fi ++ ++ pic_flag_for_symtable= ++ case $host in ++ # compiling the symbol table file with pic_flag works around ++ # a FreeBSD bug that causes programs to crash when -lm is ++ # linked before any other PIC object. But we must not use ++ # pic_flag when linking with -static. The problem exists in ++ # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. ++ *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) ++ case "$compile_command " in ++ *" -static "*) ;; ++ *) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND";; ++ esac;; ++ *-*-hpux*) ++ case "$compile_command " in ++ *" -static "*) ;; ++ *) pic_flag_for_symtable=" $pic_flag";; ++ esac ++ esac ++ ++ # Now compile the dynamic symbol file. ++ $show "(cd $output_objdir && $LTCC $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")" ++ $run eval '(cd $output_objdir && $LTCC $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $? ++ ++ # Clean up the generated files. ++ $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T" ++ $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T" ++ ++ # Transform the symbol file into the correct name. ++ case $host in ++ *cygwin* | *mingw* ) ++ if test -f "$output_objdir/${outputname}.def" ; then ++ compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%" | $NL2SP` ++ finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%" | $NL2SP` ++ else ++ compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP` ++ finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP` ++ fi ++ ;; ++ * ) ++ compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP` ++ finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP` ++ ;; ++ esac ++ ;; ++ *) ++ $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2 ++ exit $EXIT_FAILURE ++ ;; ++ esac ++ else ++ # We keep going just in case the user didn't refer to ++ # lt_preloaded_symbols. The linker will fail if global_symbol_pipe ++ # really was required. ++ ++ # Nullify the symbol file. ++ compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s% @SYMFILE@%%" | $NL2SP` ++ finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s% @SYMFILE@%%" | $NL2SP` ++ fi ++ ++ if test "$need_relink" = no || test "$build_libtool_libs" != yes; then ++ # Replace the output file specification. ++ compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e 's%@OUTPUT@%'"$output"'%g' | $NL2SP` ++ link_command="$compile_command$compile_rpath" ++ ++ # We have no uninstalled library dependencies, so finalize right now. ++ $show "$link_command" ++ $run eval "$link_command" ++ exit_status=$? ++ ++ # Delete the generated files. ++ if test -n "$dlsyms"; then ++ $show "$rm $output_objdir/${outputname}S.${objext}" ++ $run $rm "$output_objdir/${outputname}S.${objext}" ++ fi ++ ++ exit $exit_status ++ fi ++ ++ if test -n "$shlibpath_var"; then ++ # We should set the shlibpath_var ++ rpath= ++ for dir in $temp_rpath; do ++ case $dir in ++ [\\/]* | [A-Za-z]:[\\/]*) ++ # Absolute path. ++ rpath="$rpath$dir:" ++ ;; ++ *) ++ # Relative path: add a thisdir entry. ++ rpath="$rpath\$thisdir/$dir:" ++ ;; ++ esac ++ done ++ temp_rpath="$rpath" ++ fi ++ ++ if test -n "$compile_shlibpath$finalize_shlibpath"; then ++ compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" ++ fi ++ if test -n "$finalize_shlibpath"; then ++ finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" ++ fi ++ ++ compile_var= ++ finalize_var= ++ if test -n "$runpath_var"; then ++ if test -n "$perm_rpath"; then ++ # We should set the runpath_var. ++ rpath= ++ for dir in $perm_rpath; do ++ rpath="$rpath$dir:" ++ done ++ compile_var="$runpath_var=\"$rpath\$$runpath_var\" " ++ fi ++ if test -n "$finalize_perm_rpath"; then ++ # We should set the runpath_var. ++ rpath= ++ for dir in $finalize_perm_rpath; do ++ rpath="$rpath$dir:" ++ done ++ finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " ++ fi ++ fi ++ ++ if test "$no_install" = yes; then ++ # We don't need to create a wrapper script. ++ link_command="$compile_var$compile_command$compile_rpath" ++ # Replace the output file specification. ++ link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` ++ # Delete the old output file. ++ $run $rm $output ++ # Link the executable and exit ++ $show "$link_command" ++ $run eval "$link_command" || exit $? ++ exit $EXIT_SUCCESS ++ fi ++ ++ if test "$hardcode_action" = relink; then ++ # Fast installation is not supported ++ link_command="$compile_var$compile_command$compile_rpath" ++ relink_command="$finalize_var$finalize_command$finalize_rpath" ++ ++ $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2 ++ $echo "$modename: \`$output' will be relinked during installation" 1>&2 ++ else ++ if test "$fast_install" != no; then ++ link_command="$finalize_var$compile_command$finalize_rpath" ++ if test "$fast_install" = yes; then ++ relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $SP2NL | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g' | $NL2SP` ++ else ++ # fast_install is set to needless ++ relink_command= ++ fi ++ else ++ link_command="$compile_var$compile_command$compile_rpath" ++ relink_command="$finalize_var$finalize_command$finalize_rpath" ++ fi ++ fi ++ ++ # Replace the output file specification. ++ link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` ++ ++ # Delete the old output files. ++ $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname ++ ++ $show "$link_command" ++ $run eval "$link_command" || exit $? ++ ++ # Now create the wrapper script. ++ $show "creating $output" ++ ++ # Quote the relink command for shipping. ++ if test -n "$relink_command"; then ++ # Preserve any variables that may affect compiler behavior ++ for var in $variables_saved_for_relink; do ++ if eval test -z \"\${$var+set}\"; then ++ relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" ++ elif eval var_value=\$$var; test -z "$var_value"; then ++ relink_command="$var=; export $var; $relink_command" ++ else ++ var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` ++ relink_command="$var=\"$var_value\"; export $var; $relink_command" ++ fi ++ done ++ relink_command="(cd `pwd`; $relink_command)" ++ relink_command=`$echo "X$relink_command" | $SP2NL | $Xsed -e "$sed_quote_subst" | $NL2SP` ++ fi ++ ++ # Quote $echo for shipping. ++ if test "X$echo" = "X$SHELL $progpath --fallback-echo"; then ++ case $progpath in ++ [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";; ++ *) qecho="$SHELL `pwd`/$progpath --fallback-echo";; ++ esac ++ qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"` ++ else ++ qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"` ++ fi ++ ++ # Only actually do things if our run command is non-null. ++ if test -z "$run"; then ++ # win32 will think the script is a binary if it has ++ # a .exe suffix, so we strip it off here. ++ case $output in ++ *.exe) output=`$echo $output|${SED} 's,.exe$,,'` ;; ++ esac ++ # test for cygwin because mv fails w/o .exe extensions ++ case $host in ++ *cygwin*) ++ exeext=.exe ++ outputname=`$echo $outputname|${SED} 's,.exe$,,'` ;; ++ *) exeext= ;; ++ esac ++ case $host in ++ *cygwin* | *mingw* ) ++ output_name=`basename $output` ++ output_path=`dirname $output` ++ cwrappersource="$output_path/$objdir/lt-$output_name.c" ++ cwrapper="$output_path/$output_name.exe" ++ $rm $cwrappersource $cwrapper ++ trap "$rm $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 ++ ++ cat > $cwrappersource <> $cwrappersource<<"EOF" ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#if defined(PATH_MAX) ++# define LT_PATHMAX PATH_MAX ++#elif defined(MAXPATHLEN) ++# define LT_PATHMAX MAXPATHLEN ++#else ++# define LT_PATHMAX 1024 ++#endif ++ ++#ifndef DIR_SEPARATOR ++# define DIR_SEPARATOR '/' ++# define PATH_SEPARATOR ':' ++#endif ++ ++#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ ++ defined (__OS2__) ++# define HAVE_DOS_BASED_FILE_SYSTEM ++# ifndef DIR_SEPARATOR_2 ++# define DIR_SEPARATOR_2 '\\' ++# endif ++# ifndef PATH_SEPARATOR_2 ++# define PATH_SEPARATOR_2 ';' ++# endif ++#endif ++ ++#ifndef DIR_SEPARATOR_2 ++# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) ++#else /* DIR_SEPARATOR_2 */ ++# define IS_DIR_SEPARATOR(ch) \ ++ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) ++#endif /* DIR_SEPARATOR_2 */ ++ ++#ifndef PATH_SEPARATOR_2 ++# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) ++#else /* PATH_SEPARATOR_2 */ ++# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) ++#endif /* PATH_SEPARATOR_2 */ ++ ++#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) ++#define XFREE(stale) do { \ ++ if (stale) { free ((void *) stale); stale = 0; } \ ++} while (0) ++ ++/* -DDEBUG is fairly common in CFLAGS. */ ++#undef DEBUG ++#if defined DEBUGWRAPPER ++# define DEBUG(format, ...) fprintf(stderr, format, __VA_ARGS__) ++#else ++# define DEBUG(format, ...) ++#endif ++ ++const char *program_name = NULL; ++ ++void * xmalloc (size_t num); ++char * xstrdup (const char *string); ++const char * base_name (const char *name); ++char * find_executable(const char *wrapper); ++int check_executable(const char *path); ++char * strendzap(char *str, const char *pat); ++void lt_fatal (const char *message, ...); ++ ++int ++main (int argc, char *argv[]) ++{ ++ char **newargz; ++ int i; ++ ++ program_name = (char *) xstrdup (base_name (argv[0])); ++ DEBUG("(main) argv[0] : %s\n",argv[0]); ++ DEBUG("(main) program_name : %s\n",program_name); ++ newargz = XMALLOC(char *, argc+2); ++EOF ++ ++ cat >> $cwrappersource <> $cwrappersource <<"EOF" ++ newargz[1] = find_executable(argv[0]); ++ if (newargz[1] == NULL) ++ lt_fatal("Couldn't find %s", argv[0]); ++ DEBUG("(main) found exe at : %s\n",newargz[1]); ++ /* we know the script has the same name, without the .exe */ ++ /* so make sure newargz[1] doesn't end in .exe */ ++ strendzap(newargz[1],".exe"); ++ for (i = 1; i < argc; i++) ++ newargz[i+1] = xstrdup(argv[i]); ++ newargz[argc+1] = NULL; ++ ++ for (i=0; i> $cwrappersource <> $cwrappersource <> $cwrappersource <<"EOF" ++ return 127; ++} ++ ++void * ++xmalloc (size_t num) ++{ ++ void * p = (void *) malloc (num); ++ if (!p) ++ lt_fatal ("Memory exhausted"); ++ ++ return p; ++} ++ ++char * ++xstrdup (const char *string) ++{ ++ return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL ++; ++} ++ ++const char * ++base_name (const char *name) ++{ ++ const char *base; ++ ++#if defined (HAVE_DOS_BASED_FILE_SYSTEM) ++ /* Skip over the disk name in MSDOS pathnames. */ ++ if (isalpha ((unsigned char)name[0]) && name[1] == ':') ++ name += 2; ++#endif ++ ++ for (base = name; *name; name++) ++ if (IS_DIR_SEPARATOR (*name)) ++ base = name + 1; ++ return base; ++} ++ ++int ++check_executable(const char * path) ++{ ++ struct stat st; ++ ++ DEBUG("(check_executable) : %s\n", path ? (*path ? path : "EMPTY!") : "NULL!"); ++ if ((!path) || (!*path)) ++ return 0; ++ ++ if ((stat (path, &st) >= 0) && ++ ( ++ /* MinGW & native WIN32 do not support S_IXOTH or S_IXGRP */ ++#if defined (S_IXOTH) ++ ((st.st_mode & S_IXOTH) == S_IXOTH) || ++#endif ++#if defined (S_IXGRP) ++ ((st.st_mode & S_IXGRP) == S_IXGRP) || ++#endif ++ ((st.st_mode & S_IXUSR) == S_IXUSR)) ++ ) ++ return 1; ++ else ++ return 0; ++} ++ ++/* Searches for the full path of the wrapper. Returns ++ newly allocated full path name if found, NULL otherwise */ ++char * ++find_executable (const char* wrapper) ++{ ++ int has_slash = 0; ++ const char* p; ++ const char* p_next; ++ /* static buffer for getcwd */ ++ char tmp[LT_PATHMAX + 1]; ++ int tmp_len; ++ char* concat_name; ++ ++ DEBUG("(find_executable) : %s\n", wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!"); ++ ++ if ((wrapper == NULL) || (*wrapper == '\0')) ++ return NULL; ++ ++ /* Absolute path? */ ++#if defined (HAVE_DOS_BASED_FILE_SYSTEM) ++ if (isalpha ((unsigned char)wrapper[0]) && wrapper[1] == ':') ++ { ++ concat_name = xstrdup (wrapper); ++ if (check_executable(concat_name)) ++ return concat_name; ++ XFREE(concat_name); ++ } ++ else ++ { ++#endif ++ if (IS_DIR_SEPARATOR (wrapper[0])) ++ { ++ concat_name = xstrdup (wrapper); ++ if (check_executable(concat_name)) ++ return concat_name; ++ XFREE(concat_name); ++ } ++#if defined (HAVE_DOS_BASED_FILE_SYSTEM) ++ } ++#endif ++ ++ for (p = wrapper; *p; p++) ++ if (*p == '/') ++ { ++ has_slash = 1; ++ break; ++ } ++ if (!has_slash) ++ { ++ /* no slashes; search PATH */ ++ const char* path = getenv ("PATH"); ++ if (path != NULL) ++ { ++ for (p = path; *p; p = p_next) ++ { ++ const char* q; ++ size_t p_len; ++ for (q = p; *q; q++) ++ if (IS_PATH_SEPARATOR(*q)) ++ break; ++ p_len = q - p; ++ p_next = (*q == '\0' ? q : q + 1); ++ if (p_len == 0) ++ { ++ /* empty path: current directory */ ++ if (getcwd (tmp, LT_PATHMAX) == NULL) ++ lt_fatal ("getcwd failed"); ++ tmp_len = strlen(tmp); ++ concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1); ++ memcpy (concat_name, tmp, tmp_len); ++ concat_name[tmp_len] = '/'; ++ strcpy (concat_name + tmp_len + 1, wrapper); ++ } ++ else ++ { ++ concat_name = XMALLOC(char, p_len + 1 + strlen(wrapper) + 1); ++ memcpy (concat_name, p, p_len); ++ concat_name[p_len] = '/'; ++ strcpy (concat_name + p_len + 1, wrapper); ++ } ++ if (check_executable(concat_name)) ++ return concat_name; ++ XFREE(concat_name); ++ } ++ } ++ /* not found in PATH; assume curdir */ ++ } ++ /* Relative path | not found in path: prepend cwd */ ++ if (getcwd (tmp, LT_PATHMAX) == NULL) ++ lt_fatal ("getcwd failed"); ++ tmp_len = strlen(tmp); ++ concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1); ++ memcpy (concat_name, tmp, tmp_len); ++ concat_name[tmp_len] = '/'; ++ strcpy (concat_name + tmp_len + 1, wrapper); ++ ++ if (check_executable(concat_name)) ++ return concat_name; ++ XFREE(concat_name); ++ return NULL; ++} ++ ++char * ++strendzap(char *str, const char *pat) ++{ ++ size_t len, patlen; ++ ++ assert(str != NULL); ++ assert(pat != NULL); ++ ++ len = strlen(str); ++ patlen = strlen(pat); ++ ++ if (patlen <= len) ++ { ++ str += len - patlen; ++ if (strcmp(str, pat) == 0) ++ *str = '\0'; ++ } ++ return str; ++} ++ ++static void ++lt_error_core (int exit_status, const char * mode, ++ const char * message, va_list ap) ++{ ++ fprintf (stderr, "%s: %s: ", program_name, mode); ++ vfprintf (stderr, message, ap); ++ fprintf (stderr, ".\n"); ++ ++ if (exit_status >= 0) ++ exit (exit_status); ++} ++ ++void ++lt_fatal (const char *message, ...) ++{ ++ va_list ap; ++ va_start (ap, message); ++ lt_error_core (EXIT_FAILURE, "FATAL", message, ap); ++ va_end (ap); ++} ++EOF ++ # we should really use a build-platform specific compiler ++ # here, but OTOH, the wrappers (shell script and this C one) ++ # are only useful if you want to execute the "real" binary. ++ # Since the "real" binary is built for $host, then this ++ # wrapper might as well be built for $host, too. ++ $run $LTCC $LTCFLAGS -s -o $cwrapper $cwrappersource ++ ;; ++ esac ++ $rm $output ++ trap "$rm $output; exit $EXIT_FAILURE" 1 2 15 ++ ++ $echo > $output "\ ++#! $SHELL ++ ++# $output - temporary wrapper script for $objdir/$outputname ++# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP ++# ++# The $output program cannot be directly executed until all the libtool ++# libraries that it depends on are installed. ++# ++# This wrapper script should never be moved out of the build directory. ++# If it is, it will not operate correctly. ++ ++# Sed substitution that helps us do robust quoting. It backslashifies ++# metacharacters that are still active within double-quoted strings. ++Xsed='${SED} -e 1s/^X//' ++sed_quote_subst='$sed_quote_subst' ++ ++# Be Bourne compatible (taken from Autoconf:_AS_BOURNE_COMPATIBLE). ++if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then ++ emulate sh ++ NULLCMD=: ++ # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which ++ # is contrary to our usage. Disable this feature. ++ alias -g '\${1+\"\$@\"}'='\"\$@\"' ++ setopt NO_GLOB_SUBST ++else ++ case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac ++fi ++ ++# The HP-UX ksh and POSIX shell print the target directory to stdout ++# if CDPATH is set. ++(unset CDPATH) >/dev/null 2>&1 && unset CDPATH ++ ++relink_command=\"$relink_command\" ++ ++# This environment variable determines our operation mode. ++if test \"\$libtool_install_magic\" = \"$magic\"; then ++ # install mode needs the following variable: ++ notinst_deplibs='$notinst_deplibs' ++else ++ # When we are sourced in execute mode, \$file and \$echo are already set. ++ if test \"\$libtool_execute_magic\" != \"$magic\"; then ++ echo=\"$qecho\" ++ file=\"\$0\" ++ # Make sure echo works. ++ if test \"X\$1\" = X--no-reexec; then ++ # Discard the --no-reexec flag, and continue. ++ shift ++ elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then ++ # Yippee, \$echo works! ++ : ++ else ++ # Restart under the correct shell, and then maybe \$echo will work. ++ exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} ++ fi ++ fi\ ++" ++ $echo >> $output "\ ++ ++ # Find the directory that this script lives in. ++ thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` ++ test \"x\$thisdir\" = \"x\$file\" && thisdir=. ++ ++ # Follow symbolic links until we get to the real thisdir. ++ file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\` ++ while test -n \"\$file\"; do ++ destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` ++ ++ # If there was a directory component, then change thisdir. ++ if test \"x\$destdir\" != \"x\$file\"; then ++ case \"\$destdir\" in ++ [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; ++ *) thisdir=\"\$thisdir/\$destdir\" ;; ++ esac ++ fi ++ ++ file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\` ++ file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\` ++ done ++ ++ # Try to get the absolute directory name. ++ absdir=\`cd \"\$thisdir\" && pwd\` ++ test -n \"\$absdir\" && thisdir=\"\$absdir\" ++" ++ ++ if test "$fast_install" = yes; then ++ $echo >> $output "\ ++ program=lt-'$outputname'$exeext ++ progdir=\"\$thisdir/$objdir\" ++ ++ if test ! -f \"\$progdir/\$program\" || \\ ++ { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ ++ test \"X\$file\" != \"X\$progdir/\$program\"; }; then ++ ++ file=\"\$\$-\$program\" ++ ++ if test ! -d \"\$progdir\"; then ++ $mkdir \"\$progdir\" ++ else ++ $rm \"\$progdir/\$file\" ++ fi" ++ ++ $echo >> $output "\ ++ ++ # relink executable if necessary ++ if test -n \"\$relink_command\"; then ++ if relink_command_output=\`eval \$relink_command 2>&1\`; then : ++ else ++ $echo \"\$relink_command_output\" >&2 ++ $rm \"\$progdir/\$file\" ++ exit $EXIT_FAILURE ++ fi ++ fi ++ ++ $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || ++ { $rm \"\$progdir/\$program\"; ++ $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; } ++ $rm \"\$progdir/\$file\" ++ fi" ++ else ++ $echo >> $output "\ ++ program='$outputname' ++ progdir=\"\$thisdir/$objdir\" ++" ++ fi ++ ++ $echo >> $output "\ ++ ++ if test -f \"\$progdir/\$program\"; then" ++ ++ # Export our shlibpath_var if we have one. ++ if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then ++ $echo >> $output "\ ++ # Add our own library path to $shlibpath_var ++ $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" ++ ++ # Some systems cannot cope with colon-terminated $shlibpath_var ++ # The second colon is a workaround for a bug in BeOS R4 sed ++ $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` ++ ++ export $shlibpath_var ++" ++ fi ++ ++ # fixup the dll searchpath if we need to. ++ if test -n "$dllsearchpath"; then ++ $echo >> $output "\ ++ # Add the dll search path components to the executable PATH ++ PATH=$dllsearchpath:\$PATH ++" ++ fi ++ ++ $echo >> $output "\ ++ if test \"\$libtool_execute_magic\" != \"$magic\"; then ++ # Run the actual program with our arguments. ++" ++ case $host in ++ # Backslashes separate directories on plain windows ++ *-*-mingw | *-*-os2*) ++ $echo >> $output "\ ++ exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} ++" ++ ;; ++ ++ *) ++ $echo >> $output "\ ++ exec \"\$progdir/\$program\" \${1+\"\$@\"} ++" ++ ;; ++ esac ++ $echo >> $output "\ ++ \$echo \"\$0: cannot exec \$program \$*\" ++ exit $EXIT_FAILURE ++ fi ++ else ++ # The program doesn't exist. ++ \$echo \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 ++ \$echo \"This script is just a wrapper for \$program.\" 1>&2 ++ $echo \"See the $PACKAGE documentation for more information.\" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++fi\ ++" ++ chmod +x $output ++ fi ++ exit $EXIT_SUCCESS ++ ;; ++ esac ++ ++ # See if we need to build an old-fashioned archive. ++ for oldlib in $oldlibs; do ++ ++ if test "$build_libtool_libs" = convenience; then ++ oldobjs="$libobjs_save" ++ addlibs="$convenience" ++ build_libtool_libs=no ++ else ++ if test "$build_libtool_libs" = module; then ++ oldobjs="$libobjs_save" ++ build_libtool_libs=no ++ else ++ oldobjs="$old_deplibs $non_pic_objects" ++ fi ++ addlibs="$old_convenience" ++ fi ++ ++ if test -n "$addlibs"; then ++ gentop="$output_objdir/${outputname}x" ++ generated="$generated $gentop" ++ ++ func_extract_archives $gentop $addlibs ++ oldobjs="$oldobjs $func_extract_archives_result" ++ fi ++ ++ # Do each command in the archive commands. ++ if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then ++ cmds=$old_archive_from_new_cmds ++ else ++ # POSIX demands no paths to be encoded in archives. We have ++ # to avoid creating archives with duplicate basenames if we ++ # might have to extract them afterwards, e.g., when creating a ++ # static archive out of a convenience library, or when linking ++ # the entirety of a libtool archive into another (currently ++ # not supported by libtool). ++ if (for obj in $oldobjs ++ do ++ $echo "X$obj" | $Xsed -e 's%^.*/%%' ++ done | sort | sort -uc >/dev/null 2>&1); then ++ : ++ else ++ $echo "copying selected object files to avoid basename conflicts..." ++ ++ if test -z "$gentop"; then ++ gentop="$output_objdir/${outputname}x" ++ generated="$generated $gentop" ++ ++ $show "${rm}r $gentop" ++ $run ${rm}r "$gentop" ++ $show "$mkdir $gentop" ++ $run $mkdir "$gentop" ++ exit_status=$? ++ if test "$exit_status" -ne 0 && test ! -d "$gentop"; then ++ exit $exit_status ++ fi ++ fi ++ ++ save_oldobjs=$oldobjs ++ oldobjs= ++ counter=1 ++ for obj in $save_oldobjs ++ do ++ objbase=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` ++ case " $oldobjs " in ++ " ") oldobjs=$obj ;; ++ *[\ /]"$objbase "*) ++ while :; do ++ # Make sure we don't pick an alternate name that also ++ # overlaps. ++ newobj=lt$counter-$objbase ++ counter=`expr $counter + 1` ++ case " $oldobjs " in ++ *[\ /]"$newobj "*) ;; ++ *) if test ! -f "$gentop/$newobj"; then break; fi ;; ++ esac ++ done ++ $show "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" ++ $run ln "$obj" "$gentop/$newobj" || ++ $run cp "$obj" "$gentop/$newobj" ++ oldobjs="$oldobjs $gentop/$newobj" ++ ;; ++ *) oldobjs="$oldobjs $obj" ;; ++ esac ++ done ++ fi ++ ++ eval cmds=\"$old_archive_cmds\" ++ ++ if len=`expr "X$cmds" : ".*"` && ++ test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then ++ cmds=$old_archive_cmds ++ else ++ # the command line is too long to link in one step, link in parts ++ $echo "using piecewise archive linking..." ++ save_RANLIB=$RANLIB ++ RANLIB=: ++ objlist= ++ concat_cmds= ++ save_oldobjs=$oldobjs ++ ++ # Is there a better way of finding the last object in the list? ++ for obj in $save_oldobjs ++ do ++ last_oldobj=$obj ++ done ++ for obj in $save_oldobjs ++ do ++ oldobjs="$objlist $obj" ++ objlist="$objlist $obj" ++ eval test_cmds=\"$old_archive_cmds\" ++ if len=`expr "X$test_cmds" : ".*" 2>/dev/null` && ++ test "$len" -le "$max_cmd_len"; then ++ : ++ else ++ # the above command should be used before it gets too long ++ oldobjs=$objlist ++ if test "$obj" = "$last_oldobj" ; then ++ RANLIB=$save_RANLIB ++ fi ++ test -z "$concat_cmds" || concat_cmds=$concat_cmds~ ++ eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" ++ objlist= ++ fi ++ done ++ RANLIB=$save_RANLIB ++ oldobjs=$objlist ++ if test "X$oldobjs" = "X" ; then ++ eval cmds=\"\$concat_cmds\" ++ else ++ eval cmds=\"\$concat_cmds~\$old_archive_cmds\" ++ fi ++ fi ++ fi ++ save_ifs="$IFS"; IFS='~' ++ for cmd in $cmds; do ++ eval cmd=\"$cmd\" ++ IFS="$save_ifs" ++ $show "$cmd" ++ $run eval "$cmd" || exit $? ++ done ++ IFS="$save_ifs" ++ done ++ ++ if test -n "$generated"; then ++ $show "${rm}r$generated" ++ $run ${rm}r$generated ++ fi ++ ++ # Now create the libtool archive. ++ case $output in ++ *.la) ++ old_library= ++ test "$build_old_libs" = yes && old_library="$libname.$libext" ++ $show "creating $output" ++ ++ # Preserve any variables that may affect compiler behavior ++ for var in $variables_saved_for_relink; do ++ if eval test -z \"\${$var+set}\"; then ++ relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" ++ elif eval var_value=\$$var; test -z "$var_value"; then ++ relink_command="$var=; export $var; $relink_command" ++ else ++ var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` ++ relink_command="$var=\"$var_value\"; export $var; $relink_command" ++ fi ++ done ++ # Quote the link command for shipping. ++ relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" ++ relink_command=`$echo "X$relink_command" | $SP2NL | $Xsed -e "$sed_quote_subst" | $NL2SP` ++ if test "$hardcode_automatic" = yes ; then ++ relink_command= ++ fi ++ ++ ++ # Only create the output if not a dry run. ++ if test -z "$run"; then ++ for installed in no yes; do ++ if test "$installed" = yes; then ++ if test -z "$install_libdir"; then ++ break ++ fi ++ output="$output_objdir/$outputname"i ++ # Replace all uninstalled libtool libraries with the installed ones ++ newdependency_libs= ++ for deplib in $dependency_libs; do ++ case $deplib in ++ *.la) ++ name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'` ++ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` ++ if test -z "$libdir"; then ++ $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ newdependency_libs="$newdependency_libs $libdir/$name" ++ ;; ++ *) newdependency_libs="$newdependency_libs $deplib" ;; ++ esac ++ done ++ dependency_libs="$newdependency_libs" ++ newdlfiles= ++ for lib in $dlfiles; do ++ name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` ++ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` ++ if test -z "$libdir"; then ++ $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ newdlfiles="$newdlfiles $libdir/$name" ++ done ++ dlfiles="$newdlfiles" ++ newdlprefiles= ++ for lib in $dlprefiles; do ++ name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` ++ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` ++ if test -z "$libdir"; then ++ $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ newdlprefiles="$newdlprefiles $libdir/$name" ++ done ++ dlprefiles="$newdlprefiles" ++ else ++ newdlfiles= ++ for lib in $dlfiles; do ++ case $lib in ++ [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; ++ *) abs=`pwd`"/$lib" ;; ++ esac ++ newdlfiles="$newdlfiles $abs" ++ done ++ dlfiles="$newdlfiles" ++ newdlprefiles= ++ for lib in $dlprefiles; do ++ case $lib in ++ [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; ++ *) abs=`pwd`"/$lib" ;; ++ esac ++ newdlprefiles="$newdlprefiles $abs" ++ done ++ dlprefiles="$newdlprefiles" ++ fi ++ $rm $output ++ # place dlname in correct position for cygwin ++ tdlname=$dlname ++ case $host,$output,$installed,$module,$dlname in ++ *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; ++ esac ++ $echo > $output "\ ++# $outputname - a libtool library file ++# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP ++# ++# Please DO NOT delete this file! ++# It is necessary for linking the library. ++ ++# The name that we can dlopen(3). ++dlname='$tdlname' ++ ++# Names of this library. ++library_names='$library_names' ++ ++# The name of the static archive. ++old_library='$old_library' ++ ++# Libraries that this one depends upon. ++dependency_libs='$dependency_libs' ++ ++# Version information for $libname. ++current=$current ++age=$age ++revision=$revision ++ ++# Is this an already installed library? ++installed=$installed ++ ++# Should we warn about portability when linking against -modules? ++shouldnotlink=$module ++ ++# Files to dlopen/dlpreopen ++dlopen='$dlfiles' ++dlpreopen='$dlprefiles' ++ ++# Directory that this library needs to be installed in: ++libdir='$install_libdir'" ++ if test "$installed" = no && test "$need_relink" = yes; then ++ $echo >> $output "\ ++relink_command=\"$relink_command\"" ++ fi ++ done ++ fi ++ ++ # Do a symbolic link so that the libtool archive can be found in ++ # LD_LIBRARY_PATH before the program is installed. ++ $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" ++ $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $? ++ ;; ++ esac ++ exit $EXIT_SUCCESS ++ ;; ++ ++ # libtool install mode ++ install) ++ modename="$modename: install" ++ ++ # There may be an optional sh(1) argument at the beginning of ++ # install_prog (especially on Windows NT). ++ if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || ++ # Allow the use of GNU shtool's install command. ++ $echo "X$nonopt" | grep shtool > /dev/null; then ++ # Aesthetically quote it. ++ arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"` ++ case $arg in ++ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") ++ arg="\"$arg\"" ++ ;; ++ esac ++ install_prog="$arg " ++ arg="$1" ++ shift ++ else ++ install_prog= ++ arg=$nonopt ++ fi ++ ++ # The real first argument should be the name of the installation program. ++ # Aesthetically quote it. ++ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` ++ case $arg in ++ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") ++ arg="\"$arg\"" ++ ;; ++ esac ++ install_prog="$install_prog$arg" ++ ++ # We need to accept at least all the BSD install flags. ++ dest= ++ files= ++ opts= ++ prev= ++ install_type= ++ isdir=no ++ stripme= ++ for arg ++ do ++ if test -n "$dest"; then ++ files="$files $dest" ++ dest=$arg ++ continue ++ fi ++ ++ case $arg in ++ -d) isdir=yes ;; ++ -f) ++ case " $install_prog " in ++ *[\\\ /]cp\ *) ;; ++ *) prev=$arg ;; ++ esac ++ ;; ++ -g | -m | -o) prev=$arg ;; ++ -s) ++ stripme=" -s" ++ continue ++ ;; ++ -*) ++ ;; ++ *) ++ # If the previous option needed an argument, then skip it. ++ if test -n "$prev"; then ++ prev= ++ else ++ dest=$arg ++ continue ++ fi ++ ;; ++ esac ++ ++ # Aesthetically quote the argument. ++ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` ++ case $arg in ++ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") ++ arg="\"$arg\"" ++ ;; ++ esac ++ install_prog="$install_prog $arg" ++ done ++ ++ if test -z "$install_prog"; then ++ $echo "$modename: you must specify an install program" 1>&2 ++ $echo "$help" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ ++ if test -n "$prev"; then ++ $echo "$modename: the \`$prev' option requires an argument" 1>&2 ++ $echo "$help" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ ++ if test -z "$files"; then ++ if test -z "$dest"; then ++ $echo "$modename: no file or destination specified" 1>&2 ++ else ++ $echo "$modename: you must specify a destination" 1>&2 ++ fi ++ $echo "$help" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ ++ # Strip any trailing slash from the destination. ++ dest=`$echo "X$dest" | $Xsed -e 's%/$%%'` ++ ++ # Check to see that the destination is a directory. ++ test -d "$dest" && isdir=yes ++ if test "$isdir" = yes; then ++ destdir="$dest" ++ destname= ++ else ++ destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'` ++ test "X$destdir" = "X$dest" && destdir=. ++ destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'` ++ ++ # Not a directory, so check to see that there is only one file specified. ++ set dummy $files ++ if test "$#" -gt 2; then ++ $echo "$modename: \`$dest' is not a directory" 1>&2 ++ $echo "$help" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ fi ++ case $destdir in ++ [\\/]* | [A-Za-z]:[\\/]*) ;; ++ *) ++ for file in $files; do ++ case $file in ++ *.lo) ;; ++ *) ++ $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2 ++ $echo "$help" 1>&2 ++ exit $EXIT_FAILURE ++ ;; ++ esac ++ done ++ ;; ++ esac ++ ++ # This variable tells wrapper scripts just to set variables rather ++ # than running their programs. ++ libtool_install_magic="$magic" ++ ++ staticlibs= ++ future_libdirs= ++ current_libdirs= ++ for file in $files; do ++ ++ # Do each installation. ++ case $file in ++ *.$libext) ++ # Do the static libraries later. ++ staticlibs="$staticlibs $file" ++ ;; ++ ++ *.la) ++ # Check to see that this really is a libtool archive. ++ if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : ++ else ++ $echo "$modename: \`$file' is not a valid libtool archive" 1>&2 ++ $echo "$help" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ ++ library_names= ++ old_library= ++ relink_command= ++ # If there is no directory component, then add one. ++ case $file in ++ */* | *\\*) . $file ;; ++ *) . ./$file ;; ++ esac ++ ++ # Add the libdir to current_libdirs if it is the destination. ++ if test "X$destdir" = "X$libdir"; then ++ case "$current_libdirs " in ++ *" $libdir "*) ;; ++ *) current_libdirs="$current_libdirs $libdir" ;; ++ esac ++ else ++ # Note the libdir as a future libdir. ++ case "$future_libdirs " in ++ *" $libdir "*) ;; ++ *) future_libdirs="$future_libdirs $libdir" ;; ++ esac ++ fi ++ ++ dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/ ++ test "X$dir" = "X$file/" && dir= ++ dir="$dir$objdir" ++ ++ if test -n "$relink_command"; then ++ # Determine the prefix the user has applied to our future dir. ++ inst_prefix_dir=`$echo "$destdir" | $SED "s%$libdir\$%%"` ++ ++ # Don't allow the user to place us outside of our expected ++ # location b/c this prevents finding dependent libraries that ++ # are installed to the same prefix. ++ # At present, this check doesn't affect windows .dll's that ++ # are installed into $libdir/../bin (currently, that works fine) ++ # but it's something to keep an eye on. ++ if test "$inst_prefix_dir" = "$destdir"; then ++ $echo "$modename: error: cannot install \`$file' to a directory not ending in $libdir" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ ++ if test -n "$inst_prefix_dir"; then ++ # Stick the inst_prefix_dir data into the link command. ++ relink_command=`$echo "$relink_command" | $SP2NL | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%" | $NL2SP` ++ else ++ relink_command=`$echo "$relink_command" | $SP2NL | $SED "s%@inst_prefix_dir@%%" | $NL2SP` ++ fi ++ ++ $echo "$modename: warning: relinking \`$file'" 1>&2 ++ $show "$relink_command" ++ if $run eval "$relink_command"; then : ++ else ++ $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ fi ++ ++ # See the names of the shared library. ++ set dummy $library_names ++ if test -n "$2"; then ++ realname="$2" ++ shift ++ shift ++ ++ srcname="$realname" ++ test -n "$relink_command" && srcname="$realname"T ++ ++ # Install the shared library and build the symlinks. ++ $show "$install_prog $dir/$srcname $destdir/$realname" ++ $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $? ++ if test -n "$stripme" && test -n "$striplib"; then ++ $show "$striplib $destdir/$realname" ++ $run eval "$striplib $destdir/$realname" || exit $? ++ fi ++ ++ if test "$#" -gt 0; then ++ # Delete the old symlinks, and create new ones. ++ # Try `ln -sf' first, because the `ln' binary might depend on ++ # the symlink we replace! Solaris /bin/ln does not understand -f, ++ # so we also need to try rm && ln -s. ++ for linkname ++ do ++ if test "$linkname" != "$realname"; then ++ $show "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })" ++ $run eval "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })" ++ fi ++ done ++ fi ++ ++ # Do each command in the postinstall commands. ++ lib="$destdir/$realname" ++ cmds=$postinstall_cmds ++ save_ifs="$IFS"; IFS='~' ++ for cmd in $cmds; do ++ IFS="$save_ifs" ++ eval cmd=\"$cmd\" ++ $show "$cmd" ++ $run eval "$cmd" || { ++ lt_exit=$? ++ ++ # Restore the uninstalled library and exit ++ if test "$mode" = relink; then ++ $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)' ++ fi ++ ++ exit $lt_exit ++ } ++ done ++ IFS="$save_ifs" ++ fi ++ ++ # Install the pseudo-library for information purposes. ++ name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` ++ instname="$dir/$name"i ++ $show "$install_prog $instname $destdir/$name" ++ $run eval "$install_prog $instname $destdir/$name" || exit $? ++ ++ # Maybe install the static library, too. ++ test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" ++ ;; ++ ++ *.lo) ++ # Install (i.e. copy) a libtool object. ++ ++ # Figure out destination file name, if it wasn't already specified. ++ if test -n "$destname"; then ++ destfile="$destdir/$destname" ++ else ++ destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` ++ destfile="$destdir/$destfile" ++ fi ++ ++ # Deduce the name of the destination old-style object file. ++ case $destfile in ++ *.lo) ++ staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"` ++ ;; ++ *.$objext) ++ staticdest="$destfile" ++ destfile= ++ ;; ++ *) ++ $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2 ++ $echo "$help" 1>&2 ++ exit $EXIT_FAILURE ++ ;; ++ esac ++ ++ # Install the libtool object if requested. ++ if test -n "$destfile"; then ++ $show "$install_prog $file $destfile" ++ $run eval "$install_prog $file $destfile" || exit $? ++ fi ++ ++ # Install the old object if enabled. ++ if test "$build_old_libs" = yes; then ++ # Deduce the name of the old-style object file. ++ staticobj=`$echo "X$file" | $Xsed -e "$lo2o"` ++ ++ $show "$install_prog $staticobj $staticdest" ++ $run eval "$install_prog \$staticobj \$staticdest" || exit $? ++ fi ++ exit $EXIT_SUCCESS ++ ;; ++ ++ *) ++ # Figure out destination file name, if it wasn't already specified. ++ if test -n "$destname"; then ++ destfile="$destdir/$destname" ++ else ++ destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` ++ destfile="$destdir/$destfile" ++ fi ++ ++ # If the file is missing, and there is a .exe on the end, strip it ++ # because it is most likely a libtool script we actually want to ++ # install ++ stripped_ext="" ++ case $file in ++ *.exe) ++ if test ! -f "$file"; then ++ file=`$echo $file|${SED} 's,.exe$,,'` ++ stripped_ext=".exe" ++ fi ++ ;; ++ esac ++ ++ # Do a test to see if this is really a libtool program. ++ case $host in ++ *cygwin*|*mingw*) ++ wrapper=`$echo $file | ${SED} -e 's,.exe$,,'` ++ ;; ++ *) ++ wrapper=$file ++ ;; ++ esac ++ if (${SED} -e '4q' $wrapper | grep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then ++ notinst_deplibs= ++ relink_command= ++ ++ # Note that it is not necessary on cygwin/mingw to append a dot to ++ # foo even if both foo and FILE.exe exist: automatic-append-.exe ++ # behavior happens only for exec(3), not for open(2)! Also, sourcing ++ # `FILE.' does not work on cygwin managed mounts. ++ # ++ # If there is no directory component, then add one. ++ case $wrapper in ++ */* | *\\*) . ${wrapper} ;; ++ *) . ./${wrapper} ;; ++ esac ++ ++ # Check the variables that should have been set. ++ if test -z "$notinst_deplibs"; then ++ $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ ++ finalize=yes ++ for lib in $notinst_deplibs; do ++ # Check to see that each library is installed. ++ libdir= ++ if test -f "$lib"; then ++ # If there is no directory component, then add one. ++ case $lib in ++ */* | *\\*) . $lib ;; ++ *) . ./$lib ;; ++ esac ++ fi ++ libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test ++ if test -n "$libdir" && test ! -f "$libfile"; then ++ $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2 ++ finalize=no ++ fi ++ done ++ ++ relink_command= ++ # Note that it is not necessary on cygwin/mingw to append a dot to ++ # foo even if both foo and FILE.exe exist: automatic-append-.exe ++ # behavior happens only for exec(3), not for open(2)! Also, sourcing ++ # `FILE.' does not work on cygwin managed mounts. ++ # ++ # If there is no directory component, then add one. ++ case $wrapper in ++ */* | *\\*) . ${wrapper} ;; ++ *) . ./${wrapper} ;; ++ esac ++ ++ outputname= ++ if test "$fast_install" = no && test -n "$relink_command"; then ++ if test "$finalize" = yes && test -z "$run"; then ++ tmpdir=`func_mktempdir` ++ file=`$echo "X$file$stripped_ext" | $Xsed -e 's%^.*/%%'` ++ outputname="$tmpdir/$file" ++ # Replace the output file specification. ++ relink_command=`$echo "X$relink_command" | $SP2NL | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g' | $NL2SP` ++ ++ $show "$relink_command" ++ if $run eval "$relink_command"; then : ++ else ++ $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 ++ ${rm}r "$tmpdir" ++ continue ++ fi ++ file="$outputname" ++ else ++ $echo "$modename: warning: cannot relink \`$file'" 1>&2 ++ fi ++ else ++ # Install the binary that we compiled earlier. ++ file=`$echo "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` ++ fi ++ fi ++ ++ # remove .exe since cygwin /usr/bin/install will append another ++ # one anyway ++ case $install_prog,$host in ++ */usr/bin/install*,*cygwin*) ++ case $file:$destfile in ++ *.exe:*.exe) ++ # this is ok ++ ;; ++ *.exe:*) ++ destfile=$destfile.exe ++ ;; ++ *:*.exe) ++ destfile=`$echo $destfile | ${SED} -e 's,.exe$,,'` ++ ;; ++ esac ++ ;; ++ esac ++ $show "$install_prog$stripme $file $destfile" ++ $run eval "$install_prog\$stripme \$file \$destfile" || exit $? ++ test -n "$outputname" && ${rm}r "$tmpdir" ++ ;; ++ esac ++ done ++ ++ for file in $staticlibs; do ++ name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` ++ ++ # Set up the ranlib parameters. ++ oldlib="$destdir/$name" ++ ++ $show "$install_prog $file $oldlib" ++ $run eval "$install_prog \$file \$oldlib" || exit $? ++ ++ if test -n "$stripme" && test -n "$old_striplib"; then ++ $show "$old_striplib $oldlib" ++ $run eval "$old_striplib $oldlib" || exit $? ++ fi ++ ++ # Do each command in the postinstall commands. ++ cmds=$old_postinstall_cmds ++ save_ifs="$IFS"; IFS='~' ++ for cmd in $cmds; do ++ IFS="$save_ifs" ++ eval cmd=\"$cmd\" ++ $show "$cmd" ++ $run eval "$cmd" || exit $? ++ done ++ IFS="$save_ifs" ++ done ++ ++ if test -n "$future_libdirs"; then ++ $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2 ++ fi ++ ++ if test -n "$current_libdirs"; then ++ # Maybe just do a dry run. ++ test -n "$run" && current_libdirs=" -n$current_libdirs" ++ exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' ++ else ++ exit $EXIT_SUCCESS ++ fi ++ ;; ++ ++ # libtool finish mode ++ finish) ++ modename="$modename: finish" ++ libdirs="$nonopt" ++ admincmds= ++ ++ if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then ++ for dir ++ do ++ libdirs="$libdirs $dir" ++ done ++ ++ for libdir in $libdirs; do ++ if test -n "$finish_cmds"; then ++ # Do each command in the finish commands. ++ cmds=$finish_cmds ++ save_ifs="$IFS"; IFS='~' ++ for cmd in $cmds; do ++ IFS="$save_ifs" ++ eval cmd=\"$cmd\" ++ $show "$cmd" ++ $run eval "$cmd" || admincmds="$admincmds ++ $cmd" ++ done ++ IFS="$save_ifs" ++ fi ++ if test -n "$finish_eval"; then ++ # Do the single finish_eval. ++ eval cmds=\"$finish_eval\" ++ $run eval "$cmds" || admincmds="$admincmds ++ $cmds" ++ fi ++ done ++ fi ++ ++ # Exit here if they wanted silent mode. ++ test "$show" = : && exit $EXIT_SUCCESS ++ ++ $echo "X----------------------------------------------------------------------" | $Xsed ++ $echo "Libraries have been installed in:" ++ for libdir in $libdirs; do ++ $echo " $libdir" ++ done ++ $echo ++ $echo "If you ever happen to want to link against installed libraries" ++ $echo "in a given directory, LIBDIR, you must either use libtool, and" ++ $echo "specify the full pathname of the library, or use the \`-LLIBDIR'" ++ $echo "flag during linking and do at least one of the following:" ++ if test -n "$shlibpath_var"; then ++ $echo " - add LIBDIR to the \`$shlibpath_var' environment variable" ++ $echo " during execution" ++ fi ++ if test -n "$runpath_var"; then ++ $echo " - add LIBDIR to the \`$runpath_var' environment variable" ++ $echo " during linking" ++ fi ++ if test -n "$hardcode_libdir_flag_spec"; then ++ libdir=LIBDIR ++ eval flag=\"$hardcode_libdir_flag_spec\" ++ ++ $echo " - use the \`$flag' linker flag" ++ fi ++ if test -n "$admincmds"; then ++ $echo " - have your system administrator run these commands:$admincmds" ++ fi ++ if test -f /etc/ld.so.conf; then ++ $echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" ++ fi ++ $echo ++ $echo "See any operating system documentation about shared libraries for" ++ $echo "more information, such as the ld(1) and ld.so(8) manual pages." ++ $echo "X----------------------------------------------------------------------" | $Xsed ++ exit $EXIT_SUCCESS ++ ;; ++ ++ # libtool execute mode ++ execute) ++ modename="$modename: execute" ++ ++ # The first argument is the command name. ++ cmd="$nonopt" ++ if test -z "$cmd"; then ++ $echo "$modename: you must specify a COMMAND" 1>&2 ++ $echo "$help" ++ exit $EXIT_FAILURE ++ fi ++ ++ # Handle -dlopen flags immediately. ++ for file in $execute_dlfiles; do ++ if test ! -f "$file"; then ++ $echo "$modename: \`$file' is not a file" 1>&2 ++ $echo "$help" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ ++ dir= ++ case $file in ++ *.la) ++ # Check to see that this really is a libtool archive. ++ if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : ++ else ++ $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 ++ $echo "$help" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ ++ # Read the libtool library. ++ dlname= ++ library_names= ++ ++ # If there is no directory component, then add one. ++ case $file in ++ */* | *\\*) . $file ;; ++ *) . ./$file ;; ++ esac ++ ++ # Skip this library if it cannot be dlopened. ++ if test -z "$dlname"; then ++ # Warn if it was a shared library. ++ test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'" ++ continue ++ fi ++ ++ dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` ++ test "X$dir" = "X$file" && dir=. ++ ++ if test -f "$dir/$objdir/$dlname"; then ++ dir="$dir/$objdir" ++ else ++ $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ ;; ++ ++ *.lo) ++ # Just add the directory containing the .lo file. ++ dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` ++ test "X$dir" = "X$file" && dir=. ++ ;; ++ ++ *) ++ $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2 ++ continue ++ ;; ++ esac ++ ++ # Get the absolute pathname. ++ absdir=`cd "$dir" && pwd` ++ test -n "$absdir" && dir="$absdir" ++ ++ # Now add the directory to shlibpath_var. ++ if eval "test -z \"\$$shlibpath_var\""; then ++ eval "$shlibpath_var=\"\$dir\"" ++ else ++ eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" ++ fi ++ done ++ ++ # This variable tells wrapper scripts just to set shlibpath_var ++ # rather than running their programs. ++ libtool_execute_magic="$magic" ++ ++ # Check if any of the arguments is a wrapper script. ++ args= ++ for file ++ do ++ case $file in ++ -*) ;; ++ *) ++ # Do a test to see if this is really a libtool program. ++ if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then ++ # If there is no directory component, then add one. ++ case $file in ++ */* | *\\*) . $file ;; ++ *) . ./$file ;; ++ esac ++ ++ # Transform arg to wrapped name. ++ file="$progdir/$program" ++ fi ++ ;; ++ esac ++ # Quote arguments (to preserve shell metacharacters). ++ file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"` ++ args="$args \"$file\"" ++ done ++ ++ if test -z "$run"; then ++ if test -n "$shlibpath_var"; then ++ # Export the shlibpath_var. ++ eval "export $shlibpath_var" ++ fi ++ ++ # Restore saved environment variables ++ for lt_var in LANG LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES ++ do ++ eval "if test \"\${save_$lt_var+set}\" = set; then ++ $lt_var=\$save_$lt_var; export $lt_var ++ else ++ $lt_unset $lt_var ++ fi" ++ done ++ ++ ++ # Now prepare to actually exec the command. ++ exec_cmd="\$cmd$args" ++ else ++ # Display what would be done. ++ if test -n "$shlibpath_var"; then ++ eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\"" ++ $echo "export $shlibpath_var" ++ fi ++ $echo "$cmd$args" ++ exit $EXIT_SUCCESS ++ fi ++ ;; ++ ++ # libtool clean and uninstall mode ++ clean | uninstall) ++ modename="$modename: $mode" ++ rm="$nonopt" ++ files= ++ rmforce= ++ exit_status=0 ++ ++ # This variable tells wrapper scripts just to set variables rather ++ # than running their programs. ++ libtool_install_magic="$magic" ++ ++ for arg ++ do ++ case $arg in ++ -f) rm="$rm $arg"; rmforce=yes ;; ++ -*) rm="$rm $arg" ;; ++ *) files="$files $arg" ;; ++ esac ++ done ++ ++ if test -z "$rm"; then ++ $echo "$modename: you must specify an RM program" 1>&2 ++ $echo "$help" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ ++ rmdirs= ++ ++ origobjdir="$objdir" ++ for file in $files; do ++ dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` ++ if test "X$dir" = "X$file"; then ++ dir=. ++ objdir="$origobjdir" ++ else ++ objdir="$dir/$origobjdir" ++ fi ++ name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` ++ test "$mode" = uninstall && objdir="$dir" ++ ++ # Remember objdir for removal later, being careful to avoid duplicates ++ if test "$mode" = clean; then ++ case " $rmdirs " in ++ *" $objdir "*) ;; ++ *) rmdirs="$rmdirs $objdir" ;; ++ esac ++ fi ++ ++ # Don't error if the file doesn't exist and rm -f was used. ++ if (test -L "$file") >/dev/null 2>&1 \ ++ || (test -h "$file") >/dev/null 2>&1 \ ++ || test -f "$file"; then ++ : ++ elif test -d "$file"; then ++ exit_status=1 ++ continue ++ elif test "$rmforce" = yes; then ++ continue ++ fi ++ ++ rmfiles="$file" ++ ++ case $name in ++ *.la) ++ # Possibly a libtool archive, so verify it. ++ if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then ++ . $dir/$name ++ ++ # Delete the libtool libraries and symlinks. ++ for n in $library_names; do ++ rmfiles="$rmfiles $objdir/$n" ++ done ++ test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" ++ ++ case "$mode" in ++ clean) ++ case " $library_names " in ++ # " " in the beginning catches empty $dlname ++ *" $dlname "*) ;; ++ *) rmfiles="$rmfiles $objdir/$dlname" ;; ++ esac ++ test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" ++ ;; ++ uninstall) ++ if test -n "$library_names"; then ++ # Do each command in the postuninstall commands. ++ cmds=$postuninstall_cmds ++ save_ifs="$IFS"; IFS='~' ++ for cmd in $cmds; do ++ IFS="$save_ifs" ++ eval cmd=\"$cmd\" ++ $show "$cmd" ++ $run eval "$cmd" ++ if test "$?" -ne 0 && test "$rmforce" != yes; then ++ exit_status=1 ++ fi ++ done ++ IFS="$save_ifs" ++ fi ++ ++ if test -n "$old_library"; then ++ # Do each command in the old_postuninstall commands. ++ cmds=$old_postuninstall_cmds ++ save_ifs="$IFS"; IFS='~' ++ for cmd in $cmds; do ++ IFS="$save_ifs" ++ eval cmd=\"$cmd\" ++ $show "$cmd" ++ $run eval "$cmd" ++ if test "$?" -ne 0 && test "$rmforce" != yes; then ++ exit_status=1 ++ fi ++ done ++ IFS="$save_ifs" ++ fi ++ # FIXME: should reinstall the best remaining shared library. ++ ;; ++ esac ++ fi ++ ;; ++ ++ *.lo) ++ # Possibly a libtool object, so verify it. ++ if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then ++ ++ # Read the .lo file ++ . $dir/$name ++ ++ # Add PIC object to the list of files to remove. ++ if test -n "$pic_object" \ ++ && test "$pic_object" != none; then ++ rmfiles="$rmfiles $dir/$pic_object" ++ fi ++ ++ # Add non-PIC object to the list of files to remove. ++ if test -n "$non_pic_object" \ ++ && test "$non_pic_object" != none; then ++ rmfiles="$rmfiles $dir/$non_pic_object" ++ fi ++ fi ++ ;; ++ ++ *) ++ if test "$mode" = clean ; then ++ noexename=$name ++ case $file in ++ *.exe) ++ file=`$echo $file|${SED} 's,.exe$,,'` ++ noexename=`$echo $name|${SED} 's,.exe$,,'` ++ # $file with .exe has already been added to rmfiles, ++ # add $file without .exe ++ rmfiles="$rmfiles $file" ++ ;; ++ esac ++ # Do a test to see if this is a libtool program. ++ if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then ++ relink_command= ++ . $dir/$noexename ++ ++ # note $name still contains .exe if it was in $file originally ++ # as does the version of $file that was added into $rmfiles ++ rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" ++ if test "$fast_install" = yes && test -n "$relink_command"; then ++ rmfiles="$rmfiles $objdir/lt-$name" ++ fi ++ if test "X$noexename" != "X$name" ; then ++ rmfiles="$rmfiles $objdir/lt-${noexename}.c" ++ fi ++ fi ++ fi ++ ;; ++ esac ++ $show "$rm $rmfiles" ++ $run $rm $rmfiles || exit_status=1 ++ done ++ objdir="$origobjdir" ++ ++ # Try to remove the ${objdir}s in the directories where we deleted files ++ for dir in $rmdirs; do ++ if test -d "$dir"; then ++ $show "rmdir $dir" ++ $run rmdir $dir >/dev/null 2>&1 ++ fi ++ done ++ ++ exit $exit_status ++ ;; ++ ++ "") ++ $echo "$modename: you must specify a MODE" 1>&2 ++ $echo "$generic_help" 1>&2 ++ exit $EXIT_FAILURE ++ ;; ++ esac ++ ++ if test -z "$exec_cmd"; then ++ $echo "$modename: invalid operation mode \`$mode'" 1>&2 ++ $echo "$generic_help" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++fi # test -z "$show_help" ++ ++if test -n "$exec_cmd"; then ++ eval exec $exec_cmd ++ exit $EXIT_FAILURE ++fi ++ ++# We need to display help for each of the modes. ++case $mode in ++"") $echo \ ++"Usage: $modename [OPTION]... [MODE-ARG]... ++ ++Provide generalized library-building support services. ++ ++ --config show all configuration variables ++ --debug enable verbose shell tracing ++-n, --dry-run display commands without modifying any files ++ --features display basic configuration information and exit ++ --finish same as \`--mode=finish' ++ --help display this help message and exit ++ --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS] ++ --quiet same as \`--silent' ++ --silent don't print informational messages ++ --tag=TAG use configuration variables from tag TAG ++ --version print version information ++ ++MODE must be one of the following: ++ ++ clean remove files from the build directory ++ compile compile a source file into a libtool object ++ execute automatically set library path, then run a program ++ finish complete the installation of libtool libraries ++ install install libraries or executables ++ link create a library or an executable ++ uninstall remove libraries from an installed directory ++ ++MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for ++a more detailed description of MODE. ++ ++Report bugs to ." ++ exit $EXIT_SUCCESS ++ ;; ++ ++clean) ++ $echo \ ++"Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE... ++ ++Remove files from the build directory. ++ ++RM is the name of the program to use to delete files associated with each FILE ++(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed ++to RM. ++ ++If FILE is a libtool library, object or program, all the files associated ++with it are deleted. Otherwise, only FILE itself is deleted using RM." ++ ;; ++ ++compile) ++ $echo \ ++"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE ++ ++Compile a source file into a libtool library object. ++ ++This mode accepts the following additional options: ++ ++ -o OUTPUT-FILE set the output file name to OUTPUT-FILE ++ -prefer-pic try to building PIC objects only ++ -prefer-non-pic try to building non-PIC objects only ++ -static always build a \`.o' file suitable for static linking ++ ++COMPILE-COMMAND is a command to be used in creating a \`standard' object file ++from the given SOURCEFILE. ++ ++The output file name is determined by removing the directory component from ++SOURCEFILE, then substituting the C source code suffix \`.c' with the ++library object suffix, \`.lo'." ++ ;; ++ ++execute) ++ $echo \ ++"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]... ++ ++Automatically set library path, then run a program. ++ ++This mode accepts the following additional options: ++ ++ -dlopen FILE add the directory containing FILE to the library path ++ ++This mode sets the library path environment variable according to \`-dlopen' ++flags. ++ ++If any of the ARGS are libtool executable wrappers, then they are translated ++into their corresponding uninstalled binary, and any of their required library ++directories are added to the library path. ++ ++Then, COMMAND is executed, with ARGS as arguments." ++ ;; ++ ++finish) ++ $echo \ ++"Usage: $modename [OPTION]... --mode=finish [LIBDIR]... ++ ++Complete the installation of libtool libraries. ++ ++Each LIBDIR is a directory that contains libtool libraries. ++ ++The commands that this mode executes may require superuser privileges. Use ++the \`--dry-run' option if you just want to see what would be executed." ++ ;; ++ ++install) ++ $echo \ ++"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND... ++ ++Install executables or libraries. ++ ++INSTALL-COMMAND is the installation command. The first component should be ++either the \`install' or \`cp' program. ++ ++The rest of the components are interpreted as arguments to that command (only ++BSD-compatible install options are recognized)." ++ ;; ++ ++link) ++ $echo \ ++"Usage: $modename [OPTION]... --mode=link LINK-COMMAND... ++ ++Link object files or libraries together to form another library, or to ++create an executable program. ++ ++LINK-COMMAND is a command using the C compiler that you would use to create ++a program from several object files. ++ ++The following components of LINK-COMMAND are treated specially: ++ ++ -all-static do not do any dynamic linking at all ++ -avoid-version do not add a version suffix if possible ++ -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime ++ -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols ++ -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) ++ -export-symbols SYMFILE ++ try to export only the symbols listed in SYMFILE ++ -export-symbols-regex REGEX ++ try to export only the symbols matching REGEX ++ -LLIBDIR search LIBDIR for required installed libraries ++ -lNAME OUTPUT-FILE requires the installed library libNAME ++ -module build a library that can dlopened ++ -no-fast-install disable the fast-install mode ++ -no-install link a not-installable executable ++ -no-undefined declare that a library does not refer to external symbols ++ -o OUTPUT-FILE create OUTPUT-FILE from the specified objects ++ -objectlist FILE Use a list of object files found in FILE to specify objects ++ -precious-files-regex REGEX ++ don't remove output files matching REGEX ++ -release RELEASE specify package release information ++ -rpath LIBDIR the created library will eventually be installed in LIBDIR ++ -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries ++ -static do not do any dynamic linking of uninstalled libtool libraries ++ -static-libtool-libs ++ do not do any dynamic linking of libtool libraries ++ -version-info CURRENT[:REVISION[:AGE]] ++ specify library version info [each variable defaults to 0] ++ ++All other options (arguments beginning with \`-') are ignored. ++ ++Every other argument is treated as a filename. Files ending in \`.la' are ++treated as uninstalled libtool libraries, other files are standard or library ++object files. ++ ++If the OUTPUT-FILE ends in \`.la', then a libtool library is created, ++only library objects (\`.lo' files) may be specified, and \`-rpath' is ++required, except when creating a convenience library. ++ ++If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created ++using \`ar' and \`ranlib', or on Windows using \`lib'. ++ ++If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file ++is created, otherwise an executable program is created." ++ ;; ++ ++uninstall) ++ $echo \ ++"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... ++ ++Remove libraries from an installation directory. ++ ++RM is the name of the program to use to delete files associated with each FILE ++(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed ++to RM. ++ ++If FILE is a libtool library, all the files associated with it are deleted. ++Otherwise, only FILE itself is deleted using RM." ++ ;; ++ ++*) ++ $echo "$modename: invalid operation mode \`$mode'" 1>&2 ++ $echo "$help" 1>&2 ++ exit $EXIT_FAILURE ++ ;; ++esac ++ ++$echo ++$echo "Try \`$modename --help' for more information about other modes." ++ ++exit $? ++ ++# The TAGs below are defined such that we never get into a situation ++# in which we disable both kinds of libraries. Given conflicting ++# choices, we go for a static library, that is the most portable, ++# since we can't tell whether shared libraries were disabled because ++# the user asked for that or because the platform doesn't support ++# them. This is particularly important on AIX, because we don't ++# support having both static and shared libraries enabled at the same ++# time on that platform, so we default to a shared-only configuration. ++# If a disable-shared tag is given, we'll fallback to a static-only ++# configuration. But we'll never go from static-only to shared-only. ++ ++# ### BEGIN LIBTOOL TAG CONFIG: disable-shared ++disable_libs=shared ++# ### END LIBTOOL TAG CONFIG: disable-shared ++ ++# ### BEGIN LIBTOOL TAG CONFIG: disable-static ++disable_libs=static ++# ### END LIBTOOL TAG CONFIG: disable-static ++ ++# Local Variables: ++# mode:shell-script ++# sh-indentation:2 ++# End: +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/Makefile.am open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/Makefile.am +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/Makefile.am 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/Makefile.am 2012-04-09 21:52:14.000000000 -0500 +@@ -0,0 +1,25 @@ ++SUBDIRS= src ++ ++EXTRA_DIST = build_date ++ ++build_date: ++ echo 'char *build_date ="'`date`'";' > build_date.c ++ 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_PROGRAM) iscsiuio.8.gz $(mandir)/man8 ++ ++install-log: ++ $(INSTALL_PROGRAM) iscsiuiolog $(logdir) ++ ++install-brcm: ++ -rm -f $(sbindir)/brcm_iscsiuio ++ -ln -s $(sbindir)/iscsiuio $(sbindir)/brcm_iscsiuio +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/Makefile.in open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/Makefile.in +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/Makefile.in 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/Makefile.in 2012-04-09 21:52:14.000000000 -0500 +@@ -0,0 +1,629 @@ ++# Makefile.in generated by automake 1.9.6 from Makefile.am. ++# @configure_input@ ++ ++# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, ++# 2003, 2004, 2005 Free Software Foundation, Inc. ++# This Makefile.in is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY, to the extent permitted by law; without ++# even the implied warranty of MERCHANTABILITY or FITNESS FOR A ++# PARTICULAR PURPOSE. ++ ++@SET_MAKE@ ++srcdir = @srcdir@ ++top_srcdir = @top_srcdir@ ++VPATH = @srcdir@ ++pkgdatadir = $(datadir)/@PACKAGE@ ++pkglibdir = $(libdir)/@PACKAGE@ ++pkgincludedir = $(includedir)/@PACKAGE@ ++top_builddir = . ++am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd ++INSTALL = @INSTALL@ ++install_sh_DATA = $(install_sh) -c -m 644 ++install_sh_PROGRAM = $(install_sh) -c ++install_sh_SCRIPT = $(install_sh) -c ++INSTALL_HEADER = $(INSTALL_DATA) ++transform = $(program_transform_name) ++NORMAL_INSTALL = : ++PRE_INSTALL = : ++POST_INSTALL = : ++NORMAL_UNINSTALL = : ++PRE_UNINSTALL = : ++POST_UNINSTALL = : ++build_triplet = @build@ ++host_triplet = @host@ ++DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ ++ $(srcdir)/Makefile.in $(srcdir)/config.h.in \ ++ $(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \ ++ TODO compile config.guess config.sub depcomp install-sh \ ++ ltmain.sh missing ++subdir = . ++ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 ++am__aclocal_m4_deps = $(top_srcdir)/configure.ac ++am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ ++ $(ACLOCAL_M4) ++am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ ++ configure.lineno configure.status.lineno ++mkinstalldirs = $(install_sh) -d ++CONFIG_HEADER = config.h ++CONFIG_CLEAN_FILES = ++SOURCES = ++DIST_SOURCES = ++RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ ++ html-recursive info-recursive install-data-recursive \ ++ install-exec-recursive install-info-recursive \ ++ install-recursive installcheck-recursive installdirs-recursive \ ++ pdf-recursive ps-recursive uninstall-info-recursive \ ++ uninstall-recursive ++ETAGS = etags ++CTAGS = ctags ++DIST_SUBDIRS = $(SUBDIRS) ++DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ++distdir = $(PACKAGE)-$(VERSION) ++top_distdir = $(distdir) ++am__remove_distdir = \ ++ { test ! -d $(distdir) \ ++ || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ ++ && rm -fr $(distdir); }; } ++DIST_ARCHIVES = $(distdir).tar.gz ++GZIP_ENV = --best ++distuninstallcheck_listfiles = find . -type f -print ++distcleancheck_listfiles = find . -type f -print ++ACLOCAL = @ACLOCAL@ ++AMDEP_FALSE = @AMDEP_FALSE@ ++AMDEP_TRUE = @AMDEP_TRUE@ ++AMTAR = @AMTAR@ ++AR = @AR@ ++AUTOCONF = @AUTOCONF@ ++AUTOHEADER = @AUTOHEADER@ ++AUTOMAKE = @AUTOMAKE@ ++AWK = @AWK@ ++BASH = @BASH@ ++CC = @CC@ ++CCDEPMODE = @CCDEPMODE@ ++CFLAGS = @CFLAGS@ ++CPP = @CPP@ ++CPPFLAGS = @CPPFLAGS@ ++CXX = @CXX@ ++CXXCPP = @CXXCPP@ ++CXXDEPMODE = @CXXDEPMODE@ ++CXXFLAGS = @CXXFLAGS@ ++CYGPATH_W = @CYGPATH_W@ ++DEBUG_FALSE = @DEBUG_FALSE@ ++DEBUG_TRUE = @DEBUG_TRUE@ ++DEFS = @DEFS@ ++DEPDIR = @DEPDIR@ ++ECHO = @ECHO@ ++ECHO_C = @ECHO_C@ ++ECHO_N = @ECHO_N@ ++ECHO_T = @ECHO_T@ ++EGREP = @EGREP@ ++ENDIAN = @ENDIAN@ ++EXEEXT = @EXEEXT@ ++F77 = @F77@ ++FFLAGS = @FFLAGS@ ++INSTALL_DATA = @INSTALL_DATA@ ++INSTALL_PROGRAM = @INSTALL_PROGRAM@ ++INSTALL_SCRIPT = @INSTALL_SCRIPT@ ++INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ ++LDFLAGS = @LDFLAGS@ ++LIBOBJS = @LIBOBJS@ ++LIBS = @LIBS@ ++LIBTOOL = @LIBTOOL@ ++LN_S = @LN_S@ ++LTLIBOBJS = @LTLIBOBJS@ ++MAKEINFO = @MAKEINFO@ ++OBJEXT = @OBJEXT@ ++PACKAGE = @PACKAGE@ ++PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ ++PACKAGE_NAME = @PACKAGE_NAME@ ++PACKAGE_STRING = @PACKAGE_STRING@ ++PACKAGE_TARNAME = @PACKAGE_TARNAME@ ++PACKAGE_VERSION = @PACKAGE_VERSION@ ++PATH_SEPARATOR = @PATH_SEPARATOR@ ++RANLIB = @RANLIB@ ++SED = @SED@ ++SET_MAKE = @SET_MAKE@ ++SHELL = @SHELL@ ++STRIP = @STRIP@ ++VERSION = @VERSION@ ++ac_ct_AR = @ac_ct_AR@ ++ac_ct_CC = @ac_ct_CC@ ++ac_ct_CXX = @ac_ct_CXX@ ++ac_ct_F77 = @ac_ct_F77@ ++ac_ct_RANLIB = @ac_ct_RANLIB@ ++ac_ct_STRIP = @ac_ct_STRIP@ ++am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ ++am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ ++am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ ++am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ ++am__include = @am__include@ ++am__leading_dot = @am__leading_dot@ ++am__quote = @am__quote@ ++am__tar = @am__tar@ ++am__untar = @am__untar@ ++bindir = @bindir@ ++build = @build@ ++build_alias = @build_alias@ ++build_cpu = @build_cpu@ ++build_os = @build_os@ ++build_vendor = @build_vendor@ ++datadir = @datadir@ ++exec_prefix = @exec_prefix@ ++host = @host@ ++host_alias = @host_alias@ ++host_cpu = @host_cpu@ ++host_os = @host_os@ ++host_vendor = @host_vendor@ ++includedir = @includedir@ ++infodir = @infodir@ ++install_sh = @install_sh@ ++libdir = @libdir@ ++libexecdir = @libexecdir@ ++localstatedir = @localstatedir@ ++mandir = ${manprefix}/man ++mkdir_p = @mkdir_p@ ++oldincludedir = @oldincludedir@ ++prefix = @prefix@ ++program_transform_name = @program_transform_name@ ++sbindir = @sbindir@ ++sharedstatedir = @sharedstatedir@ ++sysconfdir = @sysconfdir@ ++target_alias = @target_alias@ ++SUBDIRS = src ++EXTRA_DIST = build_date ++manprefix = /usr/share ++logdir = /etc/logrotate.d ++all: config.h ++ $(MAKE) $(AM_MAKEFLAGS) all-recursive ++ ++.SUFFIXES: ++am--refresh: ++ @: ++$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) ++ @for dep in $?; do \ ++ case '$(am__configure_deps)' in \ ++ *$$dep*) \ ++ echo ' cd $(srcdir) && $(AUTOMAKE) --gnu '; \ ++ cd $(srcdir) && $(AUTOMAKE) --gnu \ ++ && exit 0; \ ++ exit 1;; \ ++ esac; \ ++ done; \ ++ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ ++ cd $(top_srcdir) && \ ++ $(AUTOMAKE) --gnu Makefile ++.PRECIOUS: Makefile ++Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status ++ @case '$?' in \ ++ *config.status*) \ ++ echo ' $(SHELL) ./config.status'; \ ++ $(SHELL) ./config.status;; \ ++ *) \ ++ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ ++ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ ++ esac; ++ ++$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) ++ $(SHELL) ./config.status --recheck ++ ++$(top_srcdir)/configure: $(am__configure_deps) ++ cd $(srcdir) && $(AUTOCONF) ++$(ACLOCAL_M4): $(am__aclocal_m4_deps) ++ cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) ++ ++config.h: stamp-h1 ++ @if test ! -f $@; then \ ++ rm -f stamp-h1; \ ++ $(MAKE) stamp-h1; \ ++ else :; fi ++ ++stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status ++ @rm -f stamp-h1 ++ cd $(top_builddir) && $(SHELL) ./config.status config.h ++$(srcdir)/config.h.in: $(am__configure_deps) ++ cd $(top_srcdir) && $(AUTOHEADER) ++ rm -f stamp-h1 ++ touch $@ ++ ++distclean-hdr: ++ -rm -f config.h stamp-h1 ++ ++mostlyclean-libtool: ++ -rm -f *.lo ++ ++clean-libtool: ++ -rm -rf .libs _libs ++ ++distclean-libtool: ++ -rm -f libtool ++uninstall-info-am: ++ ++# This directory's subdirectories are mostly independent; you can cd ++# into them and run `make' without going through this Makefile. ++# To change the values of `make' variables: instead of editing Makefiles, ++# (1) if the variable is set in `config.status', edit `config.status' ++# (which will cause the Makefiles to be regenerated when you run `make'); ++# (2) otherwise, pass the desired values on the `make' command line. ++$(RECURSIVE_TARGETS): ++ @failcom='exit 1'; \ ++ for f in x $$MAKEFLAGS; do \ ++ case $$f in \ ++ *=* | --[!k]*);; \ ++ *k*) failcom='fail=yes';; \ ++ esac; \ ++ done; \ ++ dot_seen=no; \ ++ target=`echo $@ | sed s/-recursive//`; \ ++ list='$(SUBDIRS)'; for subdir in $$list; do \ ++ echo "Making $$target in $$subdir"; \ ++ if test "$$subdir" = "."; then \ ++ dot_seen=yes; \ ++ local_target="$$target-am"; \ ++ else \ ++ local_target="$$target"; \ ++ fi; \ ++ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ ++ || eval $$failcom; \ ++ done; \ ++ if test "$$dot_seen" = "no"; then \ ++ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ ++ fi; test -z "$$fail" ++ ++mostlyclean-recursive clean-recursive distclean-recursive \ ++maintainer-clean-recursive: ++ @failcom='exit 1'; \ ++ for f in x $$MAKEFLAGS; do \ ++ case $$f in \ ++ *=* | --[!k]*);; \ ++ *k*) failcom='fail=yes';; \ ++ esac; \ ++ done; \ ++ dot_seen=no; \ ++ case "$@" in \ ++ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ ++ *) list='$(SUBDIRS)' ;; \ ++ esac; \ ++ rev=''; for subdir in $$list; do \ ++ if test "$$subdir" = "."; then :; else \ ++ rev="$$subdir $$rev"; \ ++ fi; \ ++ done; \ ++ rev="$$rev ."; \ ++ target=`echo $@ | sed s/-recursive//`; \ ++ for subdir in $$rev; do \ ++ echo "Making $$target in $$subdir"; \ ++ if test "$$subdir" = "."; then \ ++ local_target="$$target-am"; \ ++ else \ ++ local_target="$$target"; \ ++ fi; \ ++ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ ++ || eval $$failcom; \ ++ done && test -z "$$fail" ++tags-recursive: ++ list='$(SUBDIRS)'; for subdir in $$list; do \ ++ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ ++ done ++ctags-recursive: ++ list='$(SUBDIRS)'; for subdir in $$list; do \ ++ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ ++ done ++ ++ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) ++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) ' { files[$$0] = 1; } \ ++ END { for (i in files) print i; }'`; \ ++ mkid -fID $$unique ++tags: TAGS ++ ++TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ ++ $(TAGS_FILES) $(LISP) ++ tags=; \ ++ here=`pwd`; \ ++ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ ++ include_option=--etags-include; \ ++ empty_fix=.; \ ++ else \ ++ include_option=--include; \ ++ empty_fix=; \ ++ fi; \ ++ list='$(SUBDIRS)'; for subdir in $$list; do \ ++ if test "$$subdir" = .; then :; else \ ++ test ! -f $$subdir/TAGS || \ ++ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ ++ fi; \ ++ done; \ ++ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) ' { files[$$0] = 1; } \ ++ END { for (i in files) print i; }'`; \ ++ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ ++ test -n "$$unique" || unique=$$empty_fix; \ ++ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ ++ $$tags $$unique; \ ++ fi ++ctags: CTAGS ++CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ ++ $(TAGS_FILES) $(LISP) ++ tags=; \ ++ here=`pwd`; \ ++ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) ' { files[$$0] = 1; } \ ++ END { for (i in files) print i; }'`; \ ++ test -z "$(CTAGS_ARGS)$$tags$$unique" \ ++ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ ++ $$tags $$unique ++ ++GTAGS: ++ here=`$(am__cd) $(top_builddir) && pwd` \ ++ && cd $(top_srcdir) \ ++ && gtags -i $(GTAGS_ARGS) $$here ++ ++distclean-tags: ++ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags ++ ++distdir: $(DISTFILES) ++ $(am__remove_distdir) ++ mkdir $(distdir) ++ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ ++ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ ++ list='$(DISTFILES)'; for file in $$list; do \ ++ case $$file in \ ++ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ ++ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ ++ esac; \ ++ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ ++ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ ++ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ ++ dir="/$$dir"; \ ++ $(mkdir_p) "$(distdir)$$dir"; \ ++ else \ ++ dir=''; \ ++ fi; \ ++ if test -d $$d/$$file; then \ ++ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ ++ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ ++ fi; \ ++ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ ++ else \ ++ test -f $(distdir)/$$file \ ++ || cp -p $$d/$$file $(distdir)/$$file \ ++ || exit 1; \ ++ fi; \ ++ done ++ list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ ++ if test "$$subdir" = .; then :; else \ ++ test -d "$(distdir)/$$subdir" \ ++ || $(mkdir_p) "$(distdir)/$$subdir" \ ++ || exit 1; \ ++ distdir=`$(am__cd) $(distdir) && pwd`; \ ++ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ ++ (cd $$subdir && \ ++ $(MAKE) $(AM_MAKEFLAGS) \ ++ top_distdir="$$top_distdir" \ ++ distdir="$$distdir/$$subdir" \ ++ distdir) \ ++ || exit 1; \ ++ fi; \ ++ done ++ -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ ++ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ++ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ++ ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \ ++ || chmod -R a+r $(distdir) ++dist-gzip: distdir ++ tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz ++ $(am__remove_distdir) ++ ++dist-bzip2: distdir ++ tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 ++ $(am__remove_distdir) ++ ++dist-tarZ: distdir ++ tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z ++ $(am__remove_distdir) ++ ++dist-shar: distdir ++ shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz ++ $(am__remove_distdir) ++ ++dist-zip: distdir ++ -rm -f $(distdir).zip ++ zip -rq $(distdir).zip $(distdir) ++ $(am__remove_distdir) ++ ++dist dist-all: distdir ++ tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz ++ $(am__remove_distdir) ++ ++# This target untars the dist file and tries a VPATH configuration. Then ++# it guarantees that the distribution is self-contained by making another ++# tarfile. ++distcheck: dist ++ case '$(DIST_ARCHIVES)' in \ ++ *.tar.gz*) \ ++ GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\ ++ *.tar.bz2*) \ ++ bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\ ++ *.tar.Z*) \ ++ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ ++ *.shar.gz*) \ ++ GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\ ++ *.zip*) \ ++ unzip $(distdir).zip ;;\ ++ esac ++ chmod -R a-w $(distdir); chmod a+w $(distdir) ++ mkdir $(distdir)/_build ++ mkdir $(distdir)/_inst ++ chmod a-w $(distdir) ++ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ ++ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ ++ && cd $(distdir)/_build \ ++ && ../configure --srcdir=.. --prefix="$$dc_install_base" \ ++ $(DISTCHECK_CONFIGURE_FLAGS) \ ++ && $(MAKE) $(AM_MAKEFLAGS) \ ++ && $(MAKE) $(AM_MAKEFLAGS) dvi \ ++ && $(MAKE) $(AM_MAKEFLAGS) check \ ++ && $(MAKE) $(AM_MAKEFLAGS) install \ ++ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ ++ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ ++ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ ++ distuninstallcheck \ ++ && chmod -R a-w "$$dc_install_base" \ ++ && ({ \ ++ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ ++ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ ++ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ ++ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ ++ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ ++ } || { rm -rf "$$dc_destdir"; exit 1; }) \ ++ && rm -rf "$$dc_destdir" \ ++ && $(MAKE) $(AM_MAKEFLAGS) dist \ ++ && rm -rf $(DIST_ARCHIVES) \ ++ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck ++ $(am__remove_distdir) ++ @(echo "$(distdir) archives ready for distribution: "; \ ++ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ ++ sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}' ++distuninstallcheck: ++ @cd $(distuninstallcheck_dir) \ ++ && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ ++ || { echo "ERROR: files left after uninstall:" ; \ ++ if test -n "$(DESTDIR)"; then \ ++ echo " (check DESTDIR support)"; \ ++ fi ; \ ++ $(distuninstallcheck_listfiles) ; \ ++ exit 1; } >&2 ++distcleancheck: distclean ++ @if test '$(srcdir)' = . ; then \ ++ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ ++ exit 1 ; \ ++ fi ++ @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ ++ || { echo "ERROR: files left in build directory after distclean:" ; \ ++ $(distcleancheck_listfiles) ; \ ++ exit 1; } >&2 ++check-am: all-am ++check: check-recursive ++all-am: Makefile config.h ++installdirs: installdirs-recursive ++installdirs-am: ++install: install-recursive ++install-exec: install-exec-recursive ++install-data: install-data-recursive ++uninstall: uninstall-recursive ++ ++installcheck: installcheck-recursive ++install-strip: ++ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ ++ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ ++ `test -z '$(STRIP)' || \ ++ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install ++mostlyclean-generic: ++ ++clean-generic: ++ ++distclean-generic: ++ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) ++ ++maintainer-clean-generic: ++ @echo "This command is intended for maintainers to use" ++ @echo "it deletes files that may require special tools to rebuild." ++clean: clean-recursive ++ ++clean-am: clean-generic clean-libtool mostlyclean-am ++ ++distclean: distclean-recursive ++ -rm -f $(am__CONFIG_DISTCLEAN_FILES) ++ -rm -f Makefile ++distclean-am: clean-am distclean-generic distclean-hdr \ ++ distclean-libtool distclean-tags ++ ++dvi: dvi-recursive ++ ++dvi-am: ++ ++html: html-recursive ++ ++info: info-recursive ++ ++info-am: ++ ++install-data-am: ++ ++install-exec-am: ++ ++install-info: install-info-recursive ++ ++installcheck-am: ++ ++maintainer-clean: maintainer-clean-recursive ++ -rm -f $(am__CONFIG_DISTCLEAN_FILES) ++ -rm -rf $(top_srcdir)/autom4te.cache ++ -rm -f Makefile ++maintainer-clean-am: distclean-am maintainer-clean-generic ++ ++mostlyclean: mostlyclean-recursive ++ ++mostlyclean-am: mostlyclean-generic mostlyclean-libtool ++ ++pdf: pdf-recursive ++ ++pdf-am: ++ ++ps: ps-recursive ++ ++ps-am: ++ ++uninstall-am: uninstall-info-am ++ ++uninstall-info: uninstall-info-recursive ++ ++.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am am--refresh check \ ++ check-am clean clean-generic clean-libtool clean-recursive \ ++ ctags ctags-recursive dist dist-all dist-bzip2 dist-gzip \ ++ dist-shar dist-tarZ dist-zip distcheck distclean \ ++ distclean-generic distclean-hdr distclean-libtool \ ++ distclean-recursive distclean-tags distcleancheck distdir \ ++ distuninstallcheck dvi dvi-am html html-am info info-am \ ++ install install-am install-data install-data-am install-exec \ ++ install-exec-am install-info install-info-am install-man \ ++ install-strip installcheck installcheck-am installdirs \ ++ installdirs-am maintainer-clean maintainer-clean-generic \ ++ maintainer-clean-recursive mostlyclean mostlyclean-generic \ ++ mostlyclean-libtool mostlyclean-recursive pdf pdf-am ps ps-am \ ++ tags tags-recursive uninstall uninstall-am uninstall-info-am ++ ++ ++build_date: ++ echo 'char *build_date ="'`date`'";' > build_date.c ++ echo 'char *build_date; '> build_date.h ++ ++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_PROGRAM) iscsiuio.8.gz $(mandir)/man8 ++ ++install-log: ++ $(INSTALL_PROGRAM) iscsiuiolog $(logdir) ++ ++install-brcm: ++ -rm -f $(sbindir)/brcm_iscsiuio ++ -ln -s $(sbindir)/iscsiuio $(sbindir)/brcm_iscsiuio ++# Tell versions [3.59,3.63) of GNU make to not export all variables. ++# Otherwise a system limit (for SysV at least) may be exceeded. ++.NOEXPORT: +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/missing open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/missing +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/missing 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/missing 2012-04-09 21:52:14.000000000 -0500 +@@ -0,0 +1,367 @@ ++#! /bin/sh ++# Common stub for a few missing GNU programs while installing. ++ ++scriptversion=2006-05-10.23 ++ ++# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006 ++# Free Software Foundation, Inc. ++# Originally by Fran,cois Pinard , 1996. ++ ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2, or (at your option) ++# any later version. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++ ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++# 02110-1301, USA. ++ ++# As a special exception to the GNU General Public License, if you ++# distribute this file as part of a program that contains a ++# configuration script generated by Autoconf, you may include it under ++# the same distribution terms that you use for the rest of that program. ++ ++if test $# -eq 0; then ++ echo 1>&2 "Try \`$0 --help' for more information" ++ exit 1 ++fi ++ ++run=: ++sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' ++sed_minuso='s/.* -o \([^ ]*\).*/\1/p' ++ ++# In the cases where this matters, `missing' is being run in the ++# srcdir already. ++if test -f configure.ac; then ++ configure_ac=configure.ac ++else ++ configure_ac=configure.in ++fi ++ ++msg="missing on your system" ++ ++case $1 in ++--run) ++ # Try to run requested program, and just exit if it succeeds. ++ run= ++ shift ++ "$@" && exit 0 ++ # Exit code 63 means version mismatch. This often happens ++ # when the user try to use an ancient version of a tool on ++ # a file that requires a minimum version. In this case we ++ # we should proceed has if the program had been absent, or ++ # if --run hadn't been passed. ++ if test $? = 63; then ++ run=: ++ msg="probably too old" ++ fi ++ ;; ++ ++ -h|--h|--he|--hel|--help) ++ echo "\ ++$0 [OPTION]... PROGRAM [ARGUMENT]... ++ ++Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an ++error status if there is no known handling for PROGRAM. ++ ++Options: ++ -h, --help display this help and exit ++ -v, --version output version information and exit ++ --run try to run the given command, and emulate it if it fails ++ ++Supported PROGRAM values: ++ aclocal touch file \`aclocal.m4' ++ autoconf touch file \`configure' ++ autoheader touch file \`config.h.in' ++ autom4te touch the output file, or create a stub one ++ automake touch all \`Makefile.in' files ++ bison create \`y.tab.[ch]', if possible, from existing .[ch] ++ flex create \`lex.yy.c', if possible, from existing .c ++ help2man touch the output file ++ lex create \`lex.yy.c', if possible, from existing .c ++ makeinfo touch the output file ++ tar try tar, gnutar, gtar, then tar without non-portable flags ++ yacc create \`y.tab.[ch]', if possible, from existing .[ch] ++ ++Send bug reports to ." ++ exit $? ++ ;; ++ ++ -v|--v|--ve|--ver|--vers|--versi|--versio|--version) ++ echo "missing $scriptversion (GNU Automake)" ++ exit $? ++ ;; ++ ++ -*) ++ echo 1>&2 "$0: Unknown \`$1' option" ++ echo 1>&2 "Try \`$0 --help' for more information" ++ exit 1 ++ ;; ++ ++esac ++ ++# Now exit if we have it, but it failed. Also exit now if we ++# don't have it and --version was passed (most likely to detect ++# the program). ++case $1 in ++ lex|yacc) ++ # Not GNU programs, they don't have --version. ++ ;; ++ ++ tar) ++ if test -n "$run"; then ++ echo 1>&2 "ERROR: \`tar' requires --run" ++ exit 1 ++ elif test "x$2" = "x--version" || test "x$2" = "x--help"; then ++ exit 1 ++ fi ++ ;; ++ ++ *) ++ if test -z "$run" && ($1 --version) > /dev/null 2>&1; then ++ # We have it, but it failed. ++ exit 1 ++ elif test "x$2" = "x--version" || test "x$2" = "x--help"; then ++ # Could not run --version or --help. This is probably someone ++ # running `$TOOL --version' or `$TOOL --help' to check whether ++ # $TOOL exists and not knowing $TOOL uses missing. ++ exit 1 ++ fi ++ ;; ++esac ++ ++# If it does not exist, or fails to run (possibly an outdated version), ++# try to emulate it. ++case $1 in ++ aclocal*) ++ echo 1>&2 "\ ++WARNING: \`$1' is $msg. You should only need it if ++ you modified \`acinclude.m4' or \`${configure_ac}'. You might want ++ to install the \`Automake' and \`Perl' packages. Grab them from ++ any GNU archive site." ++ touch aclocal.m4 ++ ;; ++ ++ autoconf) ++ echo 1>&2 "\ ++WARNING: \`$1' is $msg. You should only need it if ++ you modified \`${configure_ac}'. You might want to install the ++ \`Autoconf' and \`GNU m4' packages. Grab them from any GNU ++ archive site." ++ touch configure ++ ;; ++ ++ autoheader) ++ echo 1>&2 "\ ++WARNING: \`$1' is $msg. You should only need it if ++ you modified \`acconfig.h' or \`${configure_ac}'. You might want ++ to install the \`Autoconf' and \`GNU m4' packages. Grab them ++ from any GNU archive site." ++ files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` ++ test -z "$files" && files="config.h" ++ touch_files= ++ for f in $files; do ++ case $f in ++ *:*) touch_files="$touch_files "`echo "$f" | ++ sed -e 's/^[^:]*://' -e 's/:.*//'`;; ++ *) touch_files="$touch_files $f.in";; ++ esac ++ done ++ touch $touch_files ++ ;; ++ ++ automake*) ++ echo 1>&2 "\ ++WARNING: \`$1' is $msg. You should only need it if ++ you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. ++ You might want to install the \`Automake' and \`Perl' packages. ++ Grab them from any GNU archive site." ++ find . -type f -name Makefile.am -print | ++ sed 's/\.am$/.in/' | ++ while read f; do touch "$f"; done ++ ;; ++ ++ autom4te) ++ echo 1>&2 "\ ++WARNING: \`$1' is needed, but is $msg. ++ You might have modified some files without having the ++ proper tools for further handling them. ++ You can get \`$1' as part of \`Autoconf' from any GNU ++ archive site." ++ ++ file=`echo "$*" | sed -n "$sed_output"` ++ test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` ++ if test -f "$file"; then ++ touch $file ++ else ++ test -z "$file" || exec >$file ++ echo "#! /bin/sh" ++ echo "# Created by GNU Automake missing as a replacement of" ++ echo "# $ $@" ++ echo "exit 0" ++ chmod +x $file ++ exit 1 ++ fi ++ ;; ++ ++ bison|yacc) ++ echo 1>&2 "\ ++WARNING: \`$1' $msg. You should only need it if ++ you modified a \`.y' file. You may need the \`Bison' package ++ in order for those modifications to take effect. You can get ++ \`Bison' from any GNU archive site." ++ rm -f y.tab.c y.tab.h ++ if test $# -ne 1; then ++ eval LASTARG="\${$#}" ++ case $LASTARG in ++ *.y) ++ SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` ++ if test -f "$SRCFILE"; then ++ cp "$SRCFILE" y.tab.c ++ fi ++ SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` ++ if test -f "$SRCFILE"; then ++ cp "$SRCFILE" y.tab.h ++ fi ++ ;; ++ esac ++ fi ++ if test ! -f y.tab.h; then ++ echo >y.tab.h ++ fi ++ if test ! -f y.tab.c; then ++ echo 'main() { return 0; }' >y.tab.c ++ fi ++ ;; ++ ++ lex|flex) ++ echo 1>&2 "\ ++WARNING: \`$1' is $msg. You should only need it if ++ you modified a \`.l' file. You may need the \`Flex' package ++ in order for those modifications to take effect. You can get ++ \`Flex' from any GNU archive site." ++ rm -f lex.yy.c ++ if test $# -ne 1; then ++ eval LASTARG="\${$#}" ++ case $LASTARG in ++ *.l) ++ SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` ++ if test -f "$SRCFILE"; then ++ cp "$SRCFILE" lex.yy.c ++ fi ++ ;; ++ esac ++ fi ++ if test ! -f lex.yy.c; then ++ echo 'main() { return 0; }' >lex.yy.c ++ fi ++ ;; ++ ++ help2man) ++ echo 1>&2 "\ ++WARNING: \`$1' is $msg. You should only need it if ++ you modified a dependency of a manual page. You may need the ++ \`Help2man' package in order for those modifications to take ++ effect. You can get \`Help2man' from any GNU archive site." ++ ++ file=`echo "$*" | sed -n "$sed_output"` ++ test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` ++ if test -f "$file"; then ++ touch $file ++ else ++ test -z "$file" || exec >$file ++ echo ".ab help2man is required to generate this page" ++ exit 1 ++ fi ++ ;; ++ ++ makeinfo) ++ echo 1>&2 "\ ++WARNING: \`$1' is $msg. You should only need it if ++ you modified a \`.texi' or \`.texinfo' file, or any other file ++ indirectly affecting the aspect of the manual. The spurious ++ call might also be the consequence of using a buggy \`make' (AIX, ++ DU, IRIX). You might want to install the \`Texinfo' package or ++ the \`GNU make' package. Grab either from any GNU archive site." ++ # The file to touch is that specified with -o ... ++ file=`echo "$*" | sed -n "$sed_output"` ++ test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` ++ if test -z "$file"; then ++ # ... or it is the one specified with @setfilename ... ++ infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` ++ file=`sed -n ' ++ /^@setfilename/{ ++ s/.* \([^ ]*\) *$/\1/ ++ p ++ q ++ }' $infile` ++ # ... or it is derived from the source name (dir/f.texi becomes f.info) ++ test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info ++ fi ++ # If the file does not exist, the user really needs makeinfo; ++ # let's fail without touching anything. ++ test -f $file || exit 1 ++ touch $file ++ ;; ++ ++ tar) ++ shift ++ ++ # We have already tried tar in the generic part. ++ # Look for gnutar/gtar before invocation to avoid ugly error ++ # messages. ++ if (gnutar --version > /dev/null 2>&1); then ++ gnutar "$@" && exit 0 ++ fi ++ if (gtar --version > /dev/null 2>&1); then ++ gtar "$@" && exit 0 ++ fi ++ firstarg="$1" ++ if shift; then ++ case $firstarg in ++ *o*) ++ firstarg=`echo "$firstarg" | sed s/o//` ++ tar "$firstarg" "$@" && exit 0 ++ ;; ++ esac ++ case $firstarg in ++ *h*) ++ firstarg=`echo "$firstarg" | sed s/h//` ++ tar "$firstarg" "$@" && exit 0 ++ ;; ++ esac ++ fi ++ ++ echo 1>&2 "\ ++WARNING: I can't seem to be able to run \`tar' with the given arguments. ++ You may want to install GNU tar or Free paxutils, or check the ++ command line arguments." ++ exit 1 ++ ;; ++ ++ *) ++ echo 1>&2 "\ ++WARNING: \`$1' is needed, and is $msg. ++ You might have modified some files without having the ++ proper tools for further handling them. Check the \`README' file, ++ it often tells you about the needed prerequisites for installing ++ this package. You may also peek at any GNU archive site, in case ++ some other package would contain this missing \`$1' program." ++ exit 1 ++ ;; ++esac ++ ++exit 0 ++ ++# Local variables: ++# eval: (add-hook 'write-file-hooks 'time-stamp) ++# time-stamp-start: "scriptversion=" ++# time-stamp-format: "%:y-%02m-%02d.%02H" ++# time-stamp-end: "$" ++# End: +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/README open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/README +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/README 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/README 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,224 @@ ++Iscsiuio Userspace Tool ++Version 0.7.2.1 ++Mar 05, 2012 ++------------------------------------------------------ ++ ++This tool is to be used in conjunction with the Broadcom NetXtreme II Linux ++driver (Kernel module name: 'bnx2' and 'bnx2x'), Broadcom CNIC driver, ++and the Broadcom iSCSI driver (Kernel module name: 'bnx2i'). ++This user space tool is used in conjunction with the following ++Broadcom 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. Broadcom CNIC driver (cnic) ++1. Broadcom 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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/RELEASE.TXT open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/RELEASE.TXT +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/RELEASE.TXT 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/RELEASE.TXT 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,1545 @@ ++ Release Notes ++ Broadcom uIP Linux Driver ++ Version 0.7.2.1 ++ 03/05/2012 ++ ++ Broadcom Corporation ++ 5300 California Avenue, ++ Irvine, CA 92617 ++ ++ Copyright (c) 2004 - 2012 Broadcom Corporation ++ All rights reserved ++ ++uIP v0.7.2.1 (Mar 05, 2012) ++======================================================= ++ 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 ++ ++ 2. 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 ++ ++ 3. Problem: Cont00061459 - MC assert observed when logging into ++ iSCSI target (NPAR BW change) ++ Cause: The if_down message from one NIC was flushed upon ++ the reception of another if_down message from another ++ NIC ++ Change: Fixed the if_down handling on the global netlink queue ++ flush. ++ Impact: All ++ ++ 4. 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 ++ ++ Enhancements ++ ------------ ++ 1. Change: Default iscsiuio logging to off. Use the '-d' ++ option to enable ++ 2. Change: Disable HP SD mode ++ 3. Change: Updated README ++ ++ ++uIP v0.7.0.14 (Oct 25, 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. ++ ++ 2. Problem: Cont00058256 - Sessions fail after loginstress to via ++ simultaneous ipv4 and ipv6 dhcp ++ Cause: Switching between DHCPv4/v6 coupled with VLAN exposed ++ a drawback in our nic_iface architecture design where ++ VLAN is not specified by iscsid. ++ Change: The code was optimized and improved the performance when ++ switching between DHCPv4/v6+VLAN. However, the ultimate ++ fix is to make use of the net config parameters introduced ++ in the newer open-iscsi util which will identify the ++ specific VLAN nic_iface to use. ++ ++ 3. Problem: Cont00058602 - Can't iboot using IPv6 offload path ++ Cause: The bug was exposed by a fix in 0.7.0.14c where the ++ IPv6 router solicitation timeout exceeded the nic ++ enable thread timeout. ++ Change: The IPv6 router solicitation timeout has been adjusted ++ ++ 4. Problem: Cont00058678 - Can not iboot target from ipv6 path ++ using VLAN ++ Cause: A bug was found in the path request path where the vlan ++ iface's protocol family was not used correctly in the ++ iface search ++ Change: This has been corrected ++ ++ 5. Problem: Cont00058994 - DOS vulnerability in uip during UDP flood ++ Cause: The warning messages from the UDP handler was logging ++ at a rate faster than the log file logrotate rate ++ Therefore, the system's OOM eventually got kicked in to ++ start terminating running processes which includes iscsiuio ++ Change: Moved several UDP warning messages from the default log ++ level to the debug log level ++ Impact: All (minor) ++ ++ 6. Problem: Cont00059288 - Show segfault w/ Xen kernel ++ Cause: The bnx2x chip_id was not read correctly from the PCIe BAR1 ++ under the Xen kernel. The error was in the mmap area. ++ Change: Corrected the mmapping of the PCI MMIO space. ++ Impact: Xen kernels ++ ++ Enhancements ++ ------------ ++ 1. Change: Added support for RHEL6.2 for out-of-box release ++ 2. Change: Updated the man page with -h and -p info ++ 3. Change: Updated the -h info ++ 4. Change: Added support for bnx2x-1.71.00 ++ 5. Change: Changed the log file open error to a warning and let ++ the daemon progress ++ 6. Change: Added oom_adjust call to prevent OOM Killer from killing ++ iscsiuio when memory is low ++ 7. Change: Added mlockall setting to prevent page swap ++ ++ ++uIP v0.7.0.13 (Aug 10, 2011) ++======================================================= ++ 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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/apps/brcm-iscsi/brcm_iscsi.c open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/apps/brcm-iscsi/brcm_iscsi.c +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/apps/brcm-iscsi/brcm_iscsi.c 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/apps/brcm-iscsi/brcm_iscsi.c 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,88 @@ ++/* ++ * Copyright (c) 2009-2011, Broadcom 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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/apps/brcm-iscsi/brcm_iscsi.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/apps/brcm-iscsi/brcm_iscsi.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/apps/brcm-iscsi/brcm_iscsi.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/apps/brcm-iscsi/brcm_iscsi.h 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,90 @@ ++/* ++ * Copyright (c) 2009-2011, Broadcom 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 uip_tcp_appstate_t datatype. 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. */ ++typedef struct hello_world_state { ++ struct psock p; ++ u8_t inputbuffer[32]; ++ u8_t name[40]; ++ ++ struct uip_udp_conn *conn; ++} uip_tcp_appstate_t; ++ ++/* 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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/apps/brcm-iscsi/Makefile.am open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/apps/brcm-iscsi/Makefile.am +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/apps/brcm-iscsi/Makefile.am 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/apps/brcm-iscsi/Makefile.am 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,12 @@ ++INCLUDES = -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 ++ ++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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/apps/brcm-iscsi/Makefile.brcm-iscsi open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/apps/brcm-iscsi/Makefile.brcm-iscsi +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/apps/brcm-iscsi/Makefile.brcm-iscsi 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/apps/brcm-iscsi/Makefile.brcm-iscsi 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1 @@ ++APP_SOURCES += brcm-iscsi.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/apps/brcm-iscsi/Makefile.in open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/apps/brcm-iscsi/Makefile.in +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/apps/brcm-iscsi/Makefile.in 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/apps/brcm-iscsi/Makefile.in 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,445 @@ ++# Makefile.in generated by automake 1.9.6 from Makefile.am. ++# @configure_input@ ++ ++# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, ++# 2003, 2004, 2005 Free Software Foundation, Inc. ++# This Makefile.in is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY, to the extent permitted by law; without ++# even the implied warranty of MERCHANTABILITY or FITNESS FOR A ++# PARTICULAR PURPOSE. ++ ++@SET_MAKE@ ++ ++srcdir = @srcdir@ ++top_srcdir = @top_srcdir@ ++VPATH = @srcdir@ ++pkgdatadir = $(datadir)/@PACKAGE@ ++pkglibdir = $(libdir)/@PACKAGE@ ++pkgincludedir = $(includedir)/@PACKAGE@ ++top_builddir = ../../.. ++am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd ++INSTALL = @INSTALL@ ++install_sh_DATA = $(install_sh) -c -m 644 ++install_sh_PROGRAM = $(install_sh) -c ++install_sh_SCRIPT = $(install_sh) -c ++INSTALL_HEADER = $(INSTALL_DATA) ++transform = $(program_transform_name) ++NORMAL_INSTALL = : ++PRE_INSTALL = : ++POST_INSTALL = : ++NORMAL_UNINSTALL = : ++PRE_UNINSTALL = : ++POST_UNINSTALL = : ++build_triplet = @build@ ++host_triplet = @host@ ++subdir = src/apps/brcm-iscsi ++DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ++ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 ++am__aclocal_m4_deps = $(top_srcdir)/configure.ac ++am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ ++ $(ACLOCAL_M4) ++mkinstalldirs = $(install_sh) -d ++CONFIG_HEADER = $(top_builddir)/config.h ++CONFIG_CLEAN_FILES = ++LIBRARIES = $(noinst_LIBRARIES) ++ARFLAGS = cru ++lib_apps_brcm_iscsi_a_AR = $(AR) $(ARFLAGS) ++lib_apps_brcm_iscsi_a_LIBADD = ++am_lib_apps_brcm_iscsi_a_OBJECTS = \ ++ lib_apps_brcm_iscsi_a-brcm_iscsi.$(OBJEXT) ++lib_apps_brcm_iscsi_a_OBJECTS = $(am_lib_apps_brcm_iscsi_a_OBJECTS) ++DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) ++depcomp = $(SHELL) $(top_srcdir)/depcomp ++am__depfiles_maybe = depfiles ++COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ ++ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) ++LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ ++ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ ++ $(AM_CFLAGS) $(CFLAGS) ++CCLD = $(CC) ++LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ ++ $(AM_LDFLAGS) $(LDFLAGS) -o $@ ++SOURCES = $(lib_apps_brcm_iscsi_a_SOURCES) ++DIST_SOURCES = $(lib_apps_brcm_iscsi_a_SOURCES) ++ETAGS = etags ++CTAGS = ctags ++DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ++ACLOCAL = @ACLOCAL@ ++AMDEP_FALSE = @AMDEP_FALSE@ ++AMDEP_TRUE = @AMDEP_TRUE@ ++AMTAR = @AMTAR@ ++AR = @AR@ ++AUTOCONF = @AUTOCONF@ ++AUTOHEADER = @AUTOHEADER@ ++AUTOMAKE = @AUTOMAKE@ ++AWK = @AWK@ ++BASH = @BASH@ ++CC = @CC@ ++CCDEPMODE = @CCDEPMODE@ ++CFLAGS = @CFLAGS@ ++CPP = @CPP@ ++CPPFLAGS = @CPPFLAGS@ ++CXX = @CXX@ ++CXXCPP = @CXXCPP@ ++CXXDEPMODE = @CXXDEPMODE@ ++CXXFLAGS = @CXXFLAGS@ ++CYGPATH_W = @CYGPATH_W@ ++DEBUG_FALSE = @DEBUG_FALSE@ ++DEBUG_TRUE = @DEBUG_TRUE@ ++DEFS = @DEFS@ ++DEPDIR = @DEPDIR@ ++ECHO = @ECHO@ ++ECHO_C = @ECHO_C@ ++ECHO_N = @ECHO_N@ ++ECHO_T = @ECHO_T@ ++EGREP = @EGREP@ ++ENDIAN = @ENDIAN@ ++EXEEXT = @EXEEXT@ ++F77 = @F77@ ++FFLAGS = @FFLAGS@ ++INSTALL_DATA = @INSTALL_DATA@ ++INSTALL_PROGRAM = @INSTALL_PROGRAM@ ++INSTALL_SCRIPT = @INSTALL_SCRIPT@ ++INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ ++LDFLAGS = @LDFLAGS@ ++LIBOBJS = @LIBOBJS@ ++LIBS = @LIBS@ ++LIBTOOL = @LIBTOOL@ ++LN_S = @LN_S@ ++LTLIBOBJS = @LTLIBOBJS@ ++MAKEINFO = @MAKEINFO@ ++OBJEXT = @OBJEXT@ ++PACKAGE = @PACKAGE@ ++PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ ++PACKAGE_NAME = @PACKAGE_NAME@ ++PACKAGE_STRING = @PACKAGE_STRING@ ++PACKAGE_TARNAME = @PACKAGE_TARNAME@ ++PACKAGE_VERSION = @PACKAGE_VERSION@ ++PATH_SEPARATOR = @PATH_SEPARATOR@ ++RANLIB = @RANLIB@ ++SED = @SED@ ++SET_MAKE = @SET_MAKE@ ++SHELL = @SHELL@ ++STRIP = @STRIP@ ++VERSION = @VERSION@ ++ac_ct_AR = @ac_ct_AR@ ++ac_ct_CC = @ac_ct_CC@ ++ac_ct_CXX = @ac_ct_CXX@ ++ac_ct_F77 = @ac_ct_F77@ ++ac_ct_RANLIB = @ac_ct_RANLIB@ ++ac_ct_STRIP = @ac_ct_STRIP@ ++am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ ++am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ ++am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ ++am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ ++am__include = @am__include@ ++am__leading_dot = @am__leading_dot@ ++am__quote = @am__quote@ ++am__tar = @am__tar@ ++am__untar = @am__untar@ ++bindir = @bindir@ ++build = @build@ ++build_alias = @build_alias@ ++build_cpu = @build_cpu@ ++build_os = @build_os@ ++build_vendor = @build_vendor@ ++datadir = @datadir@ ++exec_prefix = @exec_prefix@ ++host = @host@ ++host_alias = @host_alias@ ++host_cpu = @host_cpu@ ++host_os = @host_os@ ++host_vendor = @host_vendor@ ++includedir = @includedir@ ++infodir = @infodir@ ++install_sh = @install_sh@ ++libdir = @libdir@ ++libexecdir = @libexecdir@ ++localstatedir = @localstatedir@ ++mandir = @mandir@ ++mkdir_p = @mkdir_p@ ++oldincludedir = @oldincludedir@ ++prefix = @prefix@ ++program_transform_name = @program_transform_name@ ++sbindir = @sbindir@ ++sharedstatedir = @sharedstatedir@ ++sysconfdir = @sysconfdir@ ++target_alias = @target_alias@ ++INCLUDES = -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 ++ ++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@ ++ ++all: all-am ++ ++.SUFFIXES: ++.SUFFIXES: .c .lo .o .obj ++$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) ++ @for dep in $?; do \ ++ case '$(am__configure_deps)' in \ ++ *$$dep*) \ ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ ++ && exit 0; \ ++ exit 1;; \ ++ esac; \ ++ done; \ ++ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/apps/brcm-iscsi/Makefile'; \ ++ cd $(top_srcdir) && \ ++ $(AUTOMAKE) --gnu src/apps/brcm-iscsi/Makefile ++.PRECIOUS: Makefile ++Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status ++ @case '$?' in \ ++ *config.status*) \ ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ ++ *) \ ++ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ ++ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ ++ esac; ++ ++$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++ ++$(top_srcdir)/configure: $(am__configure_deps) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++$(ACLOCAL_M4): $(am__aclocal_m4_deps) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++ ++clean-noinstLIBRARIES: ++ -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) ++lib_apps_brcm_iscsi.a: $(lib_apps_brcm_iscsi_a_OBJECTS) $(lib_apps_brcm_iscsi_a_DEPENDENCIES) ++ -rm -f lib_apps_brcm_iscsi.a ++ $(lib_apps_brcm_iscsi_a_AR) lib_apps_brcm_iscsi.a $(lib_apps_brcm_iscsi_a_OBJECTS) $(lib_apps_brcm_iscsi_a_LIBADD) ++ $(RANLIB) lib_apps_brcm_iscsi.a ++ ++mostlyclean-compile: ++ -rm -f *.$(OBJEXT) ++ ++distclean-compile: ++ -rm -f *.tab.c ++ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib_apps_brcm_iscsi_a-brcm_iscsi.Po@am__quote@ ++ ++.c.o: ++@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(COMPILE) -c $< ++ ++.c.obj: ++@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` ++ ++.c.lo: ++@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< ++ ++lib_apps_brcm_iscsi_a-brcm_iscsi.o: brcm_iscsi.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_apps_brcm_iscsi_a_CFLAGS) $(CFLAGS) -MT lib_apps_brcm_iscsi_a-brcm_iscsi.o -MD -MP -MF "$(DEPDIR)/lib_apps_brcm_iscsi_a-brcm_iscsi.Tpo" -c -o lib_apps_brcm_iscsi_a-brcm_iscsi.o `test -f 'brcm_iscsi.c' || echo '$(srcdir)/'`brcm_iscsi.c; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lib_apps_brcm_iscsi_a-brcm_iscsi.Tpo" "$(DEPDIR)/lib_apps_brcm_iscsi_a-brcm_iscsi.Po"; else rm -f "$(DEPDIR)/lib_apps_brcm_iscsi_a-brcm_iscsi.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='brcm_iscsi.c' object='lib_apps_brcm_iscsi_a-brcm_iscsi.o' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_apps_brcm_iscsi_a_CFLAGS) $(CFLAGS) -c -o lib_apps_brcm_iscsi_a-brcm_iscsi.o `test -f 'brcm_iscsi.c' || echo '$(srcdir)/'`brcm_iscsi.c ++ ++lib_apps_brcm_iscsi_a-brcm_iscsi.obj: brcm_iscsi.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_apps_brcm_iscsi_a_CFLAGS) $(CFLAGS) -MT lib_apps_brcm_iscsi_a-brcm_iscsi.obj -MD -MP -MF "$(DEPDIR)/lib_apps_brcm_iscsi_a-brcm_iscsi.Tpo" -c -o lib_apps_brcm_iscsi_a-brcm_iscsi.obj `if test -f 'brcm_iscsi.c'; then $(CYGPATH_W) 'brcm_iscsi.c'; else $(CYGPATH_W) '$(srcdir)/brcm_iscsi.c'; fi`; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lib_apps_brcm_iscsi_a-brcm_iscsi.Tpo" "$(DEPDIR)/lib_apps_brcm_iscsi_a-brcm_iscsi.Po"; else rm -f "$(DEPDIR)/lib_apps_brcm_iscsi_a-brcm_iscsi.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='brcm_iscsi.c' object='lib_apps_brcm_iscsi_a-brcm_iscsi.obj' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_apps_brcm_iscsi_a_CFLAGS) $(CFLAGS) -c -o lib_apps_brcm_iscsi_a-brcm_iscsi.obj `if test -f 'brcm_iscsi.c'; then $(CYGPATH_W) 'brcm_iscsi.c'; else $(CYGPATH_W) '$(srcdir)/brcm_iscsi.c'; fi` ++ ++mostlyclean-libtool: ++ -rm -f *.lo ++ ++clean-libtool: ++ -rm -rf .libs _libs ++ ++distclean-libtool: ++ -rm -f libtool ++uninstall-info-am: ++ ++ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) ++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) ' { files[$$0] = 1; } \ ++ END { for (i in files) print i; }'`; \ ++ mkid -fID $$unique ++tags: TAGS ++ ++TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ ++ $(TAGS_FILES) $(LISP) ++ tags=; \ ++ here=`pwd`; \ ++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) ' { files[$$0] = 1; } \ ++ END { for (i in files) print i; }'`; \ ++ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ ++ test -n "$$unique" || unique=$$empty_fix; \ ++ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ ++ $$tags $$unique; \ ++ fi ++ctags: CTAGS ++CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ ++ $(TAGS_FILES) $(LISP) ++ tags=; \ ++ here=`pwd`; \ ++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) ' { files[$$0] = 1; } \ ++ END { for (i in files) print i; }'`; \ ++ test -z "$(CTAGS_ARGS)$$tags$$unique" \ ++ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ ++ $$tags $$unique ++ ++GTAGS: ++ here=`$(am__cd) $(top_builddir) && pwd` \ ++ && cd $(top_srcdir) \ ++ && gtags -i $(GTAGS_ARGS) $$here ++ ++distclean-tags: ++ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags ++ ++distdir: $(DISTFILES) ++ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ ++ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ ++ list='$(DISTFILES)'; for file in $$list; do \ ++ case $$file in \ ++ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ ++ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ ++ esac; \ ++ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ ++ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ ++ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ ++ dir="/$$dir"; \ ++ $(mkdir_p) "$(distdir)$$dir"; \ ++ else \ ++ dir=''; \ ++ fi; \ ++ if test -d $$d/$$file; then \ ++ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ ++ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ ++ fi; \ ++ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ ++ else \ ++ test -f $(distdir)/$$file \ ++ || cp -p $$d/$$file $(distdir)/$$file \ ++ || exit 1; \ ++ fi; \ ++ done ++check-am: all-am ++check: check-am ++all-am: Makefile $(LIBRARIES) ++installdirs: ++install: install-am ++install-exec: install-exec-am ++install-data: install-data-am ++uninstall: uninstall-am ++ ++install-am: all-am ++ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am ++ ++installcheck: installcheck-am ++install-strip: ++ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ ++ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ ++ `test -z '$(STRIP)' || \ ++ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install ++mostlyclean-generic: ++ ++clean-generic: ++ ++distclean-generic: ++ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) ++ ++maintainer-clean-generic: ++ @echo "This command is intended for maintainers to use" ++ @echo "it deletes files that may require special tools to rebuild." ++clean: clean-am ++ ++clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ ++ mostlyclean-am ++ ++distclean: distclean-am ++ -rm -rf ./$(DEPDIR) ++ -rm -f Makefile ++distclean-am: clean-am distclean-compile distclean-generic \ ++ distclean-libtool distclean-tags ++ ++dvi: dvi-am ++ ++dvi-am: ++ ++html: html-am ++ ++info: info-am ++ ++info-am: ++ ++install-data-am: ++ ++install-exec-am: ++ ++install-info: install-info-am ++ ++install-man: ++ ++installcheck-am: ++ ++maintainer-clean: maintainer-clean-am ++ -rm -rf ./$(DEPDIR) ++ -rm -f Makefile ++maintainer-clean-am: distclean-am maintainer-clean-generic ++ ++mostlyclean: mostlyclean-am ++ ++mostlyclean-am: mostlyclean-compile mostlyclean-generic \ ++ mostlyclean-libtool ++ ++pdf: pdf-am ++ ++pdf-am: ++ ++ps: ps-am ++ ++ps-am: ++ ++uninstall-am: uninstall-info-am ++ ++.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ ++ clean-libtool clean-noinstLIBRARIES ctags distclean \ ++ distclean-compile distclean-generic distclean-libtool \ ++ distclean-tags distdir dvi dvi-am html html-am info info-am \ ++ install install-am install-data install-data-am install-exec \ ++ install-exec-am install-info install-info-am install-man \ ++ install-strip installcheck installcheck-am installdirs \ ++ maintainer-clean maintainer-clean-generic mostlyclean \ ++ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ ++ pdf pdf-am ps ps-am tags uninstall uninstall-am \ ++ uninstall-info-am ++ ++# Tell versions [3.59,3.63) of GNU make to not export all variables. ++# Otherwise a system limit (for SysV at least) may be exceeded. ++.NOEXPORT: +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/apps/dhcpc/dhcpc.c open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/apps/dhcpc/dhcpc.c +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/apps/dhcpc/dhcpc.c 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/apps/dhcpc/dhcpc.c 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,423 @@ ++/* ++ * 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 ++ * ++ * @(#)$Id: dhcpc.c,v 1.2 2006/06/11 21:46:37 adam Exp $ ++ */ ++ ++#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->state |= 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->state &= ~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->state &= ~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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/apps/dhcpc/dhcpc.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/apps/dhcpc/dhcpc.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/apps/dhcpc/dhcpc.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/apps/dhcpc/dhcpc.h 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,88 @@ ++/* ++ * 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 ++ * ++ * @(#)$Id: dhcpc.h,v 1.3 2006/06/11 21:46:37 adam Exp $ ++ */ ++#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); ++ ++typedef struct dhcpc_state uip_udp_appstate_t; ++#define UIP_UDP_APPCALL dhcpc_appcall ++ ++#endif /* __DHCPC_H__ */ +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/apps/dhcpc/dhcpv6.c open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/apps/dhcpc/dhcpv6.c +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/apps/dhcpc/dhcpv6.c 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/apps/dhcpc/dhcpv6.c 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,515 @@ ++/* ++ * Copyright (c) 2011, Broadcom 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(pDHCPV6_CONTEXT dhcpv6_context); ++STATIC int dhcpv6_send_request_packet(pDHCPV6_CONTEXT dhcpv6_context); ++STATIC u16_t dhcpv6_init_packet(pDHCPV6_CONTEXT dhcpv6_context, u8_t type); ++STATIC void dhcpv6_init_dhcpv6_server_addr(pIPV6_ADDR addr); ++//STATIC int dhcpv6_wait_for_dhcp_done(pPACKET_IPV6 pkt,int timeout); ++STATIC void dhcpv6_handle_advertise(pDHCPV6_CONTEXT dhcpv6_context, ++ u16_t dhcpv6_len); ++STATIC void dhcpv6_handle_reply(pDHCPV6_CONTEXT dhcpv6_context, ++ u16_t dhcpv6_len); ++STATIC int dhcpv6_process_opt_ia_na(pDHCPV6_CONTEXT dhcpv6_context, ++ pDHCPV6_OPT_HDR opt_hdr); ++STATIC void dhcpv6_process_opt_dns_servers(pDHCPV6_CONTEXT dhcpv6_context, ++ pDHCPV6_OPT_HDR opt_hdr); ++STATIC void dhcpv6_parse_vendor_option(pDHCPV6_CONTEXT dhcpv6_context, ++ u8_t * option, int len); ++ ++void dhcpv6_init(pDHCPV6_CONTEXT dhcpv6_context) ++{ ++ dhcpv6_context->seconds = 0; ++ dhcpv6_context->our_mac_addr = ++ ipv6_get_link_addr(dhcpv6_context->ipv6_context); ++ ++ /* Use the last four bytes of MAC address as base of the transaction ++ ID */ ++ dhcpv6_context->dhcpv6_transaction_id = ++ *((u32_t *) & dhcpv6_context->our_mac_addr->addr[2]) & 0xffffffL; ++ ++ dhcpv6_context->dhcpv6_done = FALSE; ++ strcpy(dhcpv6_context->dhcp_vendor_id, "BRCM ISAN"); ++} ++ ++int dhcpv6_do_discovery(pDHCPV6_CONTEXT dhcpv6_context) ++{ ++ int retc = ISCSI_FAILURE; ++ ++ dhcpv6_context->eth = ++ (pETH_HDR) dhcpv6_context->ipv6_context->ustack->data_link_layer; ++ dhcpv6_context->ipv6 = ++ (pIPV6_HDR) dhcpv6_context->ipv6_context->ustack->network_layer; ++ dhcpv6_context->udp = ++ (pUDP_HDR) ((u8_t *) dhcpv6_context->ipv6 + sizeof(IPV6_HDR)); ++ LOG_INFO("dhcpv6: ipv6c=%p, ustack=%p eth=%p ipv6=%p udp=%p", ++ dhcpv6_context->ipv6_context, ++ dhcpv6_context->ipv6_context->ustack, dhcpv6_context->eth, ++ dhcpv6_context->ipv6, dhcpv6_context->udp); ++ ++ /* Send out DHCPv6 Solicit packet. */ ++ dhcpv6_send_solicit_packet(dhcpv6_context); ++ ++ return retc; ++} ++ ++STATIC int dhcpv6_send_solicit_packet(pDHCPV6_CONTEXT dhcpv6_context) ++{ ++ u16_t packet_len; ++ ++ LOG_DEBUG("DHCPV6: Send solicit"); ++ packet_len = dhcpv6_init_packet(dhcpv6_context, DHCPV6_SOLICIT); ++ dhcpv6_context->dhcpv6_state = DHCPV6_STATE_SOLICIT_SENT; ++ ipv6_send_udp_packet(dhcpv6_context->ipv6_context, packet_len); ++ ++ return 0; ++} ++ ++STATIC int dhcpv6_send_request_packet(pDHCPV6_CONTEXT dhcpv6_context) ++{ ++ u16_t packet_len; ++ ++ LOG_DEBUG("DHCPV6: Send request"); ++ packet_len = dhcpv6_init_packet(dhcpv6_context, DHCPV6_REQUEST); ++ ++ dhcpv6_context->dhcpv6_state = DHCPV6_STATE_REQ_SENT; ++ ipv6_send_udp_packet(dhcpv6_context->ipv6_context, packet_len); ++ ++ return 0; ++} ++ ++STATIC u16_t dhcpv6_init_packet(pDHCPV6_CONTEXT dhcpv6_context, u8_t type) ++{ ++ u16_t pkt_len; ++ UDP_HDR *udp = dhcpv6_context->udp; ++ pDHCPV6_HDR dhcpv6; ++ pDHCPV6_OPTION opt; ++ u16_t len; ++ ++ /* Initialize dest IP with well-known DHCP server address */ ++ dhcpv6_init_dhcpv6_server_addr(&dhcpv6_context->ipv6->ipv6_dst); ++ /* Initialize dest MAC based on MC dest IP */ ++ ipv6_mc_init_dest_mac(dhcpv6_context->eth, dhcpv6_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 = (pDHCPV6_HDR) ((u8_t *) udp + sizeof(UDP_HDR)); ++ ++ if (dhcpv6->dhcpv6_type != type) { ++ dhcpv6_context->dhcpv6_transaction_id++; ++ } ++ ++ dhcpv6->dhcpv6_trans_id = dhcpv6_context->dhcpv6_transaction_id; ++ dhcpv6->dhcpv6_type = type; ++ ++ /* Keep track of length of all DHCP options. */ ++ pkt_len = sizeof(DHCPV6_HDR); ++ ++ if (dhcpv6->dhcpv6_type == DHCPV6_REQUEST) { ++ /* We will send back whatever DHCPv6 sent us */ ++ return ((u8_t *) udp - (u8_t *) dhcpv6_context->eth + ++ NET_TO_HOST16(udp->length)); ++ } ++ ++ opt = (pDHCPV6_OPTION) ((u8_t *) dhcpv6 + sizeof(DHCPV6_HDR)); ++ /* Add client ID option */ ++ opt->hdr.type = HOST_TO_NET16(DHCPV6_OPT_CLIENTID); ++ opt->hdr.length = HOST_TO_NET16(sizeof(DHCPV6_OPT_CLIENT_ID)); ++ opt->type.client_id.duid_type = ++ HOST_TO_NET16(DHCPV6_DUID_TYPE_LINK_LAYER); ++ opt->type.client_id.hw_type = HOST_TO_NET16(DHCPV6_HW_TYPE_ETHERNET); ++ memcpy((char __FAR__ *)&opt->type.client_id.link_layer_addr, ++ (char __FAR__ *)dhcpv6_context->our_mac_addr, sizeof(MAC_ADDR)); ++ pkt_len += sizeof(DHCPV6_OPT_CLIENT_ID) + sizeof(DHCPV6_OPT_HDR); ++ opt = (pDHCPV6_OPTION) ((u8_t *) opt + sizeof(DHCPV6_OPT_CLIENT_ID) + ++ sizeof(DHCPV6_OPT_HDR)); ++ ++ /* Add Vendor Class option if it's configured */ ++ if ((len = strlen(dhcpv6_context->dhcp_vendor_id)) > 0) { ++ opt->hdr.type = HOST_TO_NET16(DHCPV6_OPT_VENDOR_CLASS); ++ opt->hdr.length = HOST_TO_NET16(sizeof(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 __FAR__ *)&opt->type.vendor_class. ++ vendor_class_data[0], ++ (char __FAR__ *)dhcpv6_context->dhcp_vendor_id, len); ++ pkt_len += ++ sizeof(DHCPV6_VENDOR_CLASS) - 1 + len + ++ sizeof(DHCPV6_OPT_HDR); ++ opt = ++ (pDHCPV6_OPTION) ((u8_t *) opt + ++ sizeof(DHCPV6_VENDOR_CLASS) - 1 + len + ++ sizeof(DHCPV6_OPT_HDR)); ++ } ++ ++ /* Add IA_NA option */ ++ opt->hdr.type = HOST_TO_NET16(DHCPV6_OPT_IA_NA); ++ opt->hdr.length = HOST_TO_NET16(sizeof(DHCPV6_OPT_ID_ASSOC_NA)); ++ opt->type.ida_na.iaid = ++ htonl(*((u32_t *) & dhcpv6_context->our_mac_addr->addr[2])); ++ opt->type.ida_na.t1 = 0; ++ opt->type.ida_na.t2 = 0; ++ pkt_len += sizeof(DHCPV6_OPT_ID_ASSOC_NA) + sizeof(DHCPV6_OPT_HDR); ++ opt = (pDHCPV6_OPTION) ((u8_t *) opt + sizeof(DHCPV6_OPT_ID_ASSOC_NA) + ++ sizeof(DHCPV6_OPT_HDR)); ++ /* Add Elapsed Time option */ ++ opt->hdr.type = HOST_TO_NET16(DHCPV6_OPT_ELAPSED_TIME); ++ opt->hdr.length = HOST_TO_NET16(sizeof(DHCPV6_OPT_ELAPSE_TIME)); ++ opt->type.elapsed_time.time = HOST_TO_NET16(dhcpv6_context->seconds); ++ pkt_len += sizeof(DHCPV6_OPT_ELAPSE_TIME) + sizeof(DHCPV6_OPT_HDR); ++ ++ /* Add Option Request List */ ++ opt = (pDHCPV6_OPTION) ((u8_t *) opt + sizeof(DHCPV6_OPT_ELAPSE_TIME) + ++ sizeof(DHCPV6_OPT_HDR)); ++ opt->hdr.type = HOST_TO_NET16(DHCPV6_OPT_ORO); ++ opt->hdr.length = HOST_TO_NET16(3 * sizeof(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(DHCPV6_OPT_REQUEST_LIST) + sizeof(DHCPV6_OPT_HDR); ++ ++ udp->length = HOST_TO_NET16(sizeof(UDP_HDR) + pkt_len); ++ ++ pkt_len += ++ ((u8_t *) udp - (u8_t *) dhcpv6_context->eth) + sizeof(UDP_HDR); ++ ++ return pkt_len; ++} ++ ++STATIC void dhcpv6_init_dhcpv6_server_addr(pIPV6_ADDR addr) ++{ ++ /* Well-known DHCPv6 server address is ff02::1:2 */ ++ memset((char __FAR__ *)addr, 0, sizeof(IPV6_ADDR)); ++ addr->addr8[0] = 0xff; ++ addr->addr8[1] = 0x02; ++ addr->addr8[13] = 0x01; ++ addr->addr8[15] = 0x02; ++} ++ ++void ipv6_udp_handle_dhcp(pDHCPV6_CONTEXT dhcpv6_context) ++{ ++ pDHCPV6_HDR dhcpv6; ++ u16_t dhcpv6_len; ++ ++ if (dhcpv6_context->dhcpv6_done == TRUE) ++ return; ++ ++ dhcpv6 = (pDHCPV6_HDR) ((u8_t *) dhcpv6_context->udp + sizeof(UDP_HDR)); ++ ++ if (dhcpv6->dhcpv6_trans_id != dhcpv6_context->dhcpv6_transaction_id) ++ return; ++ ++ dhcpv6_len = ++ NET_TO_HOST16(dhcpv6_context->udp->length) - sizeof(UDP_HDR); ++ ++ switch (dhcpv6->dhcpv6_type) { ++ case DHCPV6_ADVERTISE: ++ dhcpv6_handle_advertise(dhcpv6_context, dhcpv6_len); ++ break; ++ ++ case DHCPV6_REPLY: ++ dhcpv6_handle_reply(dhcpv6_context, dhcpv6_len); ++ break; ++ ++ default: ++ break; ++ } ++} ++ ++STATIC void dhcpv6_handle_advertise(pDHCPV6_CONTEXT dhcpv6_context, ++ u16_t dhcpv6_len) ++{ ++ pDHCPV6_HDR dhcpv6 = ++ (pDHCPV6_HDR) ((u8_t *) dhcpv6_context->udp + sizeof(UDP_HDR)); ++ pDHCPV6_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 (dhcpv6_context->dhcpv6_state != DHCPV6_STATE_SOLICIT_SENT) ++ return; ++ ++ LOG_DEBUG("DHCPV6: handle advertise"); ++ dhcpv6_context->dhcpv6_state = DHCPV6_STATE_ADV_RCVD; ++ ++ i = 0; ++ while (i < (dhcpv6_len - sizeof(DHCPV6_HDR))) { ++ opt = ++ (pDHCPV6_OPT_HDR) ((u8_t *) dhcpv6 + sizeof(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 (dhcpv6_context-> ++ dhcpv6_task & DHCPV6_TASK_GET_IP_ADDRESS) { ++ addr_cnt += ++ dhcpv6_process_opt_ia_na(dhcpv6_context, ++ opt); ++ } ++ break; ++ ++ case DHCPV6_OPT_VENDOR_CLASS: ++ vendor_id_len = ++ NET_TO_HOST16(((pDHCPV6_OPTION) opt)->type. ++ vendor_class.vendor_class_length); ++ vendor_id = ++ &((pDHCPV6_OPTION) opt)->type.vendor_class. ++ vendor_class_data[0]; ++ break; ++ ++ case DHCPV6_OPT_VENDOR_OPTS: ++ vendor_opt_len = opt_len - 4; ++ vendor_opt_data = ++ &((pDHCPV6_OPTION) opt)->type.vendor_opts. ++ vendor_opt_data[0]; ++ break; ++ ++ case DHCPV6_OPT_DNS_SERVERS: ++ if (dhcpv6_context-> ++ dhcpv6_task & DHCPV6_TASK_GET_OTHER_PARAMS) ++ dhcpv6_process_opt_dns_servers(dhcpv6_context, ++ opt); ++ break; ++ ++ default: ++ break; ++ } ++ ++ i += NET_TO_HOST16(opt->length) + sizeof(DHCPV6_OPT_HDR); ++ } ++ ++ if (dhcpv6_context->dhcpv6_task & DHCPV6_TASK_GET_OTHER_PARAMS) { ++ if ((vendor_id_len > 0) && ++ (strncmp((char __FAR__ *)vendor_id, ++ (char __FAR__ *)dhcpv6_context->dhcp_vendor_id, ++ vendor_id_len) == 0)) { ++ dhcpv6_parse_vendor_option(dhcpv6_context, ++ vendor_opt_data, ++ vendor_opt_len); ++ dhcpv6_context->dhcpv6_done = TRUE; ++ } ++ } ++ ++ if (dhcpv6_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(dhcpv6_context); ++ dhcpv6_context->dhcpv6_done = TRUE; ++ } ++ } ++ ++ if (dhcpv6_context->dhcpv6_done) { ++ /* Keep track of IPv6 address of DHCHv6 server */ ++ memcpy((char __FAR__ *)&dhcpv6_context->dhcp_server, ++ (char __FAR__ *)&dhcpv6_context->ipv6->ipv6_src, ++ sizeof(IPV6_ADDR)); ++ } ++} ++ ++STATIC int dhcpv6_process_opt_ia_na(pDHCPV6_CONTEXT dhcpv6_context, ++ pDHCPV6_OPT_HDR opt_hdr) ++{ ++ int i; ++ int opt_len; ++ pDHCPV6_OPTION opt; ++ int len; ++ int addr_cnt; ++ opt_len = ++ NET_TO_HOST16(opt_hdr->length) - sizeof(DHCPV6_OPT_ID_ASSOC_NA); ++ ++ i = 0; ++ addr_cnt = 0; ++ while (i < opt_len) { ++ opt = ++ (pDHCPV6_OPTION) ((u8_t *) opt_hdr + ++ sizeof(DHCPV6_OPT_HDR) + ++ sizeof(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(DHCPV6_OPT_HDR) + ++ sizeof(DHCPV6_OPT_IAA_ADDR))) { ++ pDHCPV6_OPTION in_opt; ++ ++ in_opt = ++ (pDHCPV6_OPTION) ((u8_t *) opt + ++ sizeof(DHCPV6_OPT_HDR) + ++ sizeof ++ (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(dhcpv6_context->ipv6_context, ++ &opt->type.iaa_addr.addr, 64); ++ ++ /* Add multicast address for this address */ ++ ipv6_add_solit_node_address(dhcpv6_context-> ++ ipv6_context, ++ &opt->type.iaa_addr.addr); ++ addr_cnt++; ++ break; ++ ++ default: ++ break; ++ } ++ ++ i += len + sizeof(DHCPV6_OPT_HDR); ++ } ++ ++ return addr_cnt; ++} ++ ++STATIC void dhcpv6_process_opt_dns_servers(pDHCPV6_CONTEXT dhcpv6_context, ++ pDHCPV6_OPT_HDR opt_hdr) ++{ ++ int opt_len; ++ ++ opt_len = NET_TO_HOST16(opt_hdr->length); ++ ++ if (opt_len >= sizeof(IPV6_ADDR)) { ++ memcpy((char __FAR__ *)&dhcpv6_context->primary_dns_server, ++ (char __FAR__ *)&((pDHCPV6_OPTION) opt_hdr)->type.dns. ++ primary_addr, sizeof(IPV6_ADDR)); ++ } ++ ++ if (opt_len >= 2 * sizeof(IPV6_ADDR)) { ++ memcpy((char __FAR__ *)&dhcpv6_context->secondary_dns_server, ++ (char __FAR__ *)&((pDHCPV6_OPTION) opt_hdr)->type.dns. ++ secondary_addr, sizeof(IPV6_ADDR)); ++ } ++} ++ ++STATIC void dhcpv6_handle_reply(pDHCPV6_CONTEXT dhcpv6_context, ++ u16_t dhcpv6_len) ++{ ++ if (dhcpv6_context->dhcpv6_state != DHCPV6_STATE_REQ_SENT) ++ return; ++ ++ dhcpv6_context->dhcpv6_done = TRUE; ++} ++ ++STATIC void dhcpv6_parse_vendor_option(pDHCPV6_CONTEXT dhcpv6_context, ++ u8_t * option, int len) ++{ ++ pDHCPV6_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(DHCPV6_OPT_HDR)) { ++ opt = (pDHCPV6_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 */ ++// iscsiAddiScsiTargetInfo(data,0); ++ break; ++ ++ case 202: ++ /* iSCSI target 2 */ ++// iscsiAddiScsiTargetInfo(data,1); ++ break; ++ ++ case 203: ++ if (data_len > ISCSI_MAX_ISCSI_NAME_LENGTH) ++ data_len = ISCSI_MAX_ISCSI_NAME_LENGTH; ++ data[data_len] = '\0'; ++ strcpy(dhcpv6_context->initiatorName, (char *)data); ++// itolowerstr(dhcpv6_context->initiatorName); ++ break; ++ ++ default: ++ break; ++ } ++ } ++} +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/apps/dhcpc/dhcpv6.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/apps/dhcpc/dhcpv6.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/apps/dhcpc/dhcpv6.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/apps/dhcpc/dhcpv6.h 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,263 @@ ++/* ++ * Copyright (c) 2011, Broadcom 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" ++ ++#ifdef PACK_DATA_STRUCTURE ++#pragma pack(push,1) ++#endif ++ ++#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. */ ++ ++typedef struct DHCPV6_CONTEXT { ++#define DHCP_VENDOR_ID_LEN 128 ++ char dhcp_vendor_id[DHCP_VENDOR_ID_LEN]; ++ 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; ++ pIPV6_CONTEXT ipv6_context; ++ pETH_HDR eth; ++ pIPV6_HDR ipv6; ++ pUDP_HDR udp; ++ ++ char initiatorName[ISCSI_MAX_ISCSI_NAME_LENGTH]; ++ IPV6_ADDR dhcp_server; ++ IPV6_ADDR primary_dns_server; ++ IPV6_ADDR secondary_dns_server; ++ ++} DHCPV6_CONTEXT, *pDHCPV6_CONTEXT; ++ ++typedef union DHCPV6_HDR { ++ struct { ++ u32_t type:8; ++ u32_t trans_id:24; ++ } field; ++ ++ u32_t type_transaction; ++} DHCPV6_HDR, *pDHCPV6_HDR; ++ ++#define dhcpv6_type field.type ++#define dhcpv6_trans_id field.trans_id ++ ++typedef struct DHCPV6_OPT_HDR { ++ u16_t type; ++ u16_t length; ++} DHCPV6_OPT_HDR, *pDHCPV6_OPT_HDR; ++ ++typedef 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; ++ MAC_ADDR link_layer_addr; ++} DHCPV6_OPT_CLIENT_ID, *pDHCPV6_OPT_CLIENT_ID; ++ ++typedef struct DHCPV6_OPT_ID_ASSOC_NA { ++ u32_t iaid; ++#define DHCPV6_OPT_IA_NA_IAID 0x306373L ++ u32_t t1; ++ u32_t t2; ++} DHCPV6_OPT_ID_ASSOC_NA, *pDHCPV6_OPT_ID_ASSOC_NA; ++ ++typedef struct DHCPV6_OPT_ELAPSE_TIME { ++ u16_t time; ++} DHCPV6_OPT_ELAPSE_TIME, *pDHCPV6_OPT_ELAPSE_TIME; ++ ++typedef struct DHCPV6_OPT_IAA_ADDR { ++ IPV6_ADDR addr; ++ u32_t preferred_lifetime; ++ u32_t valid_lifetime; ++} DHCPV6_OPT_IAA_ADDR, *pDHCPV6_OPT_IAA_ADDR; ++ ++typedef struct DHCPV6_OPT_STATUS { ++ u16_t status; ++} DHCPV6_OPT_STATUS, *pDHCPV6_OPT_STATUS; ++ ++typedef struct DHCPV6_OPT_REQUEST_LIST { ++ u16_t request_code[1]; ++} DHCPV6_OPT_REQUEST_LIST, *pDHCPV6_OPT_REQUEST_LIST; ++ ++typedef struct DHCPV6_OPT_DNS { ++ IPV6_ADDR primary_addr; ++ IPV6_ADDR secondary_addr; ++} DHCPV6_OPT_DNS, *pDHCPV6_OPT_DNS; ++ ++typedef struct DHCPV6_VENDOR_CLASS { ++ u32_t enterprise_number; ++ u16_t vendor_class_length; ++ u8_t vendor_class_data[1]; ++} DHCPV6_VENDOR_CLASS, *pDHCPV6_VENDOR_CLASS; ++ ++typedef struct DHCPV6_VENDOR_OPTS { ++ u32_t enterprise_number; ++ u8_t vendor_opt_data[1]; ++} DHCPV6_VENDOR_OPTS, *pDHCPV6_VENDOR_OPTS; ++ ++typedef struct DHCPV6_OPTION { ++ DHCPV6_OPT_HDR hdr; ++ union { ++ DHCPV6_VENDOR_OPTS vendor_opts; ++ DHCPV6_VENDOR_CLASS vendor_class; ++ DHCPV6_OPT_CLIENT_ID client_id; ++ DHCPV6_OPT_ID_ASSOC_NA ida_na; ++ DHCPV6_OPT_ELAPSE_TIME elapsed_time; ++ DHCPV6_OPT_IAA_ADDR iaa_addr; ++ DHCPV6_OPT_STATUS sts; ++ DHCPV6_OPT_REQUEST_LIST list; ++ DHCPV6_OPT_DNS dns; ++ u8_t data[1]; ++ } type; ++ ++} DHCPV6_OPTION, *pDHCPV6_OPTION; ++ ++#ifdef PACK_DATA_STRUCTURE ++#pragma pack(pop) ++#endif ++ ++#define DHCPV6_NUM_OF_RETRY 4 ++ ++#define DHCPV6_ACK_TIMEOUT 2 ++ ++#define IANA_ENTERPRISE_NUM_BROADCOM 0x113d ++ ++/* Broadcom 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 ++}; ++ ++//const int dhcpv6_retry_timeout[DHCPV6_NUM_OF_RETRY] = {1,2,4,8}; ++ ++/* Function prototypes */ ++int dhcpv6_do_discovery(pDHCPV6_CONTEXT dhcpv6_context); ++void ipv6_udp_handle_dhcp(pDHCPV6_CONTEXT dhcpv6_context); ++void dhcpv6_init(pDHCPV6_CONTEXT dhcpv6_context); ++ ++#endif /* __IDHCPV6_H__ */ +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/apps/dhcpc/Makefile.am open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/apps/dhcpc/Makefile.am +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/apps/dhcpc/Makefile.am 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/apps/dhcpc/Makefile.am 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,14 @@ ++INCLUDES = -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 ++ ++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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/apps/dhcpc/Makefile.dhcpc open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/apps/dhcpc/Makefile.dhcpc +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/apps/dhcpc/Makefile.dhcpc 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/apps/dhcpc/Makefile.dhcpc 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1 @@ ++APP_SOURCES += dhcpc.c timer.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/apps/dhcpc/Makefile.in open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/apps/dhcpc/Makefile.in +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/apps/dhcpc/Makefile.in 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/apps/dhcpc/Makefile.in 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,460 @@ ++# Makefile.in generated by automake 1.9.6 from Makefile.am. ++# @configure_input@ ++ ++# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, ++# 2003, 2004, 2005 Free Software Foundation, Inc. ++# This Makefile.in is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY, to the extent permitted by law; without ++# even the implied warranty of MERCHANTABILITY or FITNESS FOR A ++# PARTICULAR PURPOSE. ++ ++@SET_MAKE@ ++ ++srcdir = @srcdir@ ++top_srcdir = @top_srcdir@ ++VPATH = @srcdir@ ++pkgdatadir = $(datadir)/@PACKAGE@ ++pkglibdir = $(libdir)/@PACKAGE@ ++pkgincludedir = $(includedir)/@PACKAGE@ ++top_builddir = ../../.. ++am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd ++INSTALL = @INSTALL@ ++install_sh_DATA = $(install_sh) -c -m 644 ++install_sh_PROGRAM = $(install_sh) -c ++install_sh_SCRIPT = $(install_sh) -c ++INSTALL_HEADER = $(INSTALL_DATA) ++transform = $(program_transform_name) ++NORMAL_INSTALL = : ++PRE_INSTALL = : ++POST_INSTALL = : ++NORMAL_UNINSTALL = : ++PRE_UNINSTALL = : ++POST_UNINSTALL = : ++build_triplet = @build@ ++host_triplet = @host@ ++subdir = src/apps/dhcpc ++DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ++ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 ++am__aclocal_m4_deps = $(top_srcdir)/configure.ac ++am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ ++ $(ACLOCAL_M4) ++mkinstalldirs = $(install_sh) -d ++CONFIG_HEADER = $(top_builddir)/config.h ++CONFIG_CLEAN_FILES = ++LIBRARIES = $(noinst_LIBRARIES) ++ARFLAGS = cru ++lib_apps_dhcpc_a_AR = $(AR) $(ARFLAGS) ++lib_apps_dhcpc_a_LIBADD = ++am_lib_apps_dhcpc_a_OBJECTS = lib_apps_dhcpc_a-dhcpc.$(OBJEXT) \ ++ lib_apps_dhcpc_a-dhcpv6.$(OBJEXT) ++lib_apps_dhcpc_a_OBJECTS = $(am_lib_apps_dhcpc_a_OBJECTS) ++DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) ++depcomp = $(SHELL) $(top_srcdir)/depcomp ++am__depfiles_maybe = depfiles ++COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ ++ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) ++LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ ++ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ ++ $(AM_CFLAGS) $(CFLAGS) ++CCLD = $(CC) ++LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ ++ $(AM_LDFLAGS) $(LDFLAGS) -o $@ ++SOURCES = $(lib_apps_dhcpc_a_SOURCES) ++DIST_SOURCES = $(lib_apps_dhcpc_a_SOURCES) ++ETAGS = etags ++CTAGS = ctags ++DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ++ACLOCAL = @ACLOCAL@ ++AMDEP_FALSE = @AMDEP_FALSE@ ++AMDEP_TRUE = @AMDEP_TRUE@ ++AMTAR = @AMTAR@ ++AR = @AR@ ++AUTOCONF = @AUTOCONF@ ++AUTOHEADER = @AUTOHEADER@ ++AUTOMAKE = @AUTOMAKE@ ++AWK = @AWK@ ++BASH = @BASH@ ++CC = @CC@ ++CCDEPMODE = @CCDEPMODE@ ++CFLAGS = @CFLAGS@ ++CPP = @CPP@ ++CPPFLAGS = @CPPFLAGS@ ++CXX = @CXX@ ++CXXCPP = @CXXCPP@ ++CXXDEPMODE = @CXXDEPMODE@ ++CXXFLAGS = @CXXFLAGS@ ++CYGPATH_W = @CYGPATH_W@ ++DEBUG_FALSE = @DEBUG_FALSE@ ++DEBUG_TRUE = @DEBUG_TRUE@ ++DEFS = @DEFS@ ++DEPDIR = @DEPDIR@ ++ECHO = @ECHO@ ++ECHO_C = @ECHO_C@ ++ECHO_N = @ECHO_N@ ++ECHO_T = @ECHO_T@ ++EGREP = @EGREP@ ++ENDIAN = @ENDIAN@ ++EXEEXT = @EXEEXT@ ++F77 = @F77@ ++FFLAGS = @FFLAGS@ ++INSTALL_DATA = @INSTALL_DATA@ ++INSTALL_PROGRAM = @INSTALL_PROGRAM@ ++INSTALL_SCRIPT = @INSTALL_SCRIPT@ ++INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ ++LDFLAGS = @LDFLAGS@ ++LIBOBJS = @LIBOBJS@ ++LIBS = @LIBS@ ++LIBTOOL = @LIBTOOL@ ++LN_S = @LN_S@ ++LTLIBOBJS = @LTLIBOBJS@ ++MAKEINFO = @MAKEINFO@ ++OBJEXT = @OBJEXT@ ++PACKAGE = @PACKAGE@ ++PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ ++PACKAGE_NAME = @PACKAGE_NAME@ ++PACKAGE_STRING = @PACKAGE_STRING@ ++PACKAGE_TARNAME = @PACKAGE_TARNAME@ ++PACKAGE_VERSION = @PACKAGE_VERSION@ ++PATH_SEPARATOR = @PATH_SEPARATOR@ ++RANLIB = @RANLIB@ ++SED = @SED@ ++SET_MAKE = @SET_MAKE@ ++SHELL = @SHELL@ ++STRIP = @STRIP@ ++VERSION = @VERSION@ ++ac_ct_AR = @ac_ct_AR@ ++ac_ct_CC = @ac_ct_CC@ ++ac_ct_CXX = @ac_ct_CXX@ ++ac_ct_F77 = @ac_ct_F77@ ++ac_ct_RANLIB = @ac_ct_RANLIB@ ++ac_ct_STRIP = @ac_ct_STRIP@ ++am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ ++am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ ++am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ ++am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ ++am__include = @am__include@ ++am__leading_dot = @am__leading_dot@ ++am__quote = @am__quote@ ++am__tar = @am__tar@ ++am__untar = @am__untar@ ++bindir = @bindir@ ++build = @build@ ++build_alias = @build_alias@ ++build_cpu = @build_cpu@ ++build_os = @build_os@ ++build_vendor = @build_vendor@ ++datadir = @datadir@ ++exec_prefix = @exec_prefix@ ++host = @host@ ++host_alias = @host_alias@ ++host_cpu = @host_cpu@ ++host_os = @host_os@ ++host_vendor = @host_vendor@ ++includedir = @includedir@ ++infodir = @infodir@ ++install_sh = @install_sh@ ++libdir = @libdir@ ++libexecdir = @libexecdir@ ++localstatedir = @localstatedir@ ++mandir = @mandir@ ++mkdir_p = @mkdir_p@ ++oldincludedir = @oldincludedir@ ++prefix = @prefix@ ++program_transform_name = @program_transform_name@ ++sbindir = @sbindir@ ++sharedstatedir = @sharedstatedir@ ++sysconfdir = @sysconfdir@ ++target_alias = @target_alias@ ++INCLUDES = -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 ++ ++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@ ++ ++all: all-am ++ ++.SUFFIXES: ++.SUFFIXES: .c .lo .o .obj ++$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) ++ @for dep in $?; do \ ++ case '$(am__configure_deps)' in \ ++ *$$dep*) \ ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ ++ && exit 0; \ ++ exit 1;; \ ++ esac; \ ++ done; \ ++ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/apps/dhcpc/Makefile'; \ ++ cd $(top_srcdir) && \ ++ $(AUTOMAKE) --gnu src/apps/dhcpc/Makefile ++.PRECIOUS: Makefile ++Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status ++ @case '$?' in \ ++ *config.status*) \ ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ ++ *) \ ++ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ ++ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ ++ esac; ++ ++$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++ ++$(top_srcdir)/configure: $(am__configure_deps) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++$(ACLOCAL_M4): $(am__aclocal_m4_deps) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++ ++clean-noinstLIBRARIES: ++ -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) ++lib_apps_dhcpc.a: $(lib_apps_dhcpc_a_OBJECTS) $(lib_apps_dhcpc_a_DEPENDENCIES) ++ -rm -f lib_apps_dhcpc.a ++ $(lib_apps_dhcpc_a_AR) lib_apps_dhcpc.a $(lib_apps_dhcpc_a_OBJECTS) $(lib_apps_dhcpc_a_LIBADD) ++ $(RANLIB) lib_apps_dhcpc.a ++ ++mostlyclean-compile: ++ -rm -f *.$(OBJEXT) ++ ++distclean-compile: ++ -rm -f *.tab.c ++ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib_apps_dhcpc_a-dhcpc.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib_apps_dhcpc_a-dhcpv6.Po@am__quote@ ++ ++.c.o: ++@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(COMPILE) -c $< ++ ++.c.obj: ++@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` ++ ++.c.lo: ++@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< ++ ++lib_apps_dhcpc_a-dhcpc.o: dhcpc.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_apps_dhcpc_a_CFLAGS) $(CFLAGS) -MT lib_apps_dhcpc_a-dhcpc.o -MD -MP -MF "$(DEPDIR)/lib_apps_dhcpc_a-dhcpc.Tpo" -c -o lib_apps_dhcpc_a-dhcpc.o `test -f 'dhcpc.c' || echo '$(srcdir)/'`dhcpc.c; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lib_apps_dhcpc_a-dhcpc.Tpo" "$(DEPDIR)/lib_apps_dhcpc_a-dhcpc.Po"; else rm -f "$(DEPDIR)/lib_apps_dhcpc_a-dhcpc.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dhcpc.c' object='lib_apps_dhcpc_a-dhcpc.o' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_apps_dhcpc_a_CFLAGS) $(CFLAGS) -c -o lib_apps_dhcpc_a-dhcpc.o `test -f 'dhcpc.c' || echo '$(srcdir)/'`dhcpc.c ++ ++lib_apps_dhcpc_a-dhcpc.obj: dhcpc.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_apps_dhcpc_a_CFLAGS) $(CFLAGS) -MT lib_apps_dhcpc_a-dhcpc.obj -MD -MP -MF "$(DEPDIR)/lib_apps_dhcpc_a-dhcpc.Tpo" -c -o lib_apps_dhcpc_a-dhcpc.obj `if test -f 'dhcpc.c'; then $(CYGPATH_W) 'dhcpc.c'; else $(CYGPATH_W) '$(srcdir)/dhcpc.c'; fi`; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lib_apps_dhcpc_a-dhcpc.Tpo" "$(DEPDIR)/lib_apps_dhcpc_a-dhcpc.Po"; else rm -f "$(DEPDIR)/lib_apps_dhcpc_a-dhcpc.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dhcpc.c' object='lib_apps_dhcpc_a-dhcpc.obj' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_apps_dhcpc_a_CFLAGS) $(CFLAGS) -c -o lib_apps_dhcpc_a-dhcpc.obj `if test -f 'dhcpc.c'; then $(CYGPATH_W) 'dhcpc.c'; else $(CYGPATH_W) '$(srcdir)/dhcpc.c'; fi` ++ ++lib_apps_dhcpc_a-dhcpv6.o: dhcpv6.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_apps_dhcpc_a_CFLAGS) $(CFLAGS) -MT lib_apps_dhcpc_a-dhcpv6.o -MD -MP -MF "$(DEPDIR)/lib_apps_dhcpc_a-dhcpv6.Tpo" -c -o lib_apps_dhcpc_a-dhcpv6.o `test -f 'dhcpv6.c' || echo '$(srcdir)/'`dhcpv6.c; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lib_apps_dhcpc_a-dhcpv6.Tpo" "$(DEPDIR)/lib_apps_dhcpc_a-dhcpv6.Po"; else rm -f "$(DEPDIR)/lib_apps_dhcpc_a-dhcpv6.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dhcpv6.c' object='lib_apps_dhcpc_a-dhcpv6.o' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_apps_dhcpc_a_CFLAGS) $(CFLAGS) -c -o lib_apps_dhcpc_a-dhcpv6.o `test -f 'dhcpv6.c' || echo '$(srcdir)/'`dhcpv6.c ++ ++lib_apps_dhcpc_a-dhcpv6.obj: dhcpv6.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_apps_dhcpc_a_CFLAGS) $(CFLAGS) -MT lib_apps_dhcpc_a-dhcpv6.obj -MD -MP -MF "$(DEPDIR)/lib_apps_dhcpc_a-dhcpv6.Tpo" -c -o lib_apps_dhcpc_a-dhcpv6.obj `if test -f 'dhcpv6.c'; then $(CYGPATH_W) 'dhcpv6.c'; else $(CYGPATH_W) '$(srcdir)/dhcpv6.c'; fi`; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lib_apps_dhcpc_a-dhcpv6.Tpo" "$(DEPDIR)/lib_apps_dhcpc_a-dhcpv6.Po"; else rm -f "$(DEPDIR)/lib_apps_dhcpc_a-dhcpv6.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dhcpv6.c' object='lib_apps_dhcpc_a-dhcpv6.obj' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_apps_dhcpc_a_CFLAGS) $(CFLAGS) -c -o lib_apps_dhcpc_a-dhcpv6.obj `if test -f 'dhcpv6.c'; then $(CYGPATH_W) 'dhcpv6.c'; else $(CYGPATH_W) '$(srcdir)/dhcpv6.c'; fi` ++ ++mostlyclean-libtool: ++ -rm -f *.lo ++ ++clean-libtool: ++ -rm -rf .libs _libs ++ ++distclean-libtool: ++ -rm -f libtool ++uninstall-info-am: ++ ++ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) ++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) ' { files[$$0] = 1; } \ ++ END { for (i in files) print i; }'`; \ ++ mkid -fID $$unique ++tags: TAGS ++ ++TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ ++ $(TAGS_FILES) $(LISP) ++ tags=; \ ++ here=`pwd`; \ ++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) ' { files[$$0] = 1; } \ ++ END { for (i in files) print i; }'`; \ ++ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ ++ test -n "$$unique" || unique=$$empty_fix; \ ++ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ ++ $$tags $$unique; \ ++ fi ++ctags: CTAGS ++CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ ++ $(TAGS_FILES) $(LISP) ++ tags=; \ ++ here=`pwd`; \ ++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) ' { files[$$0] = 1; } \ ++ END { for (i in files) print i; }'`; \ ++ test -z "$(CTAGS_ARGS)$$tags$$unique" \ ++ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ ++ $$tags $$unique ++ ++GTAGS: ++ here=`$(am__cd) $(top_builddir) && pwd` \ ++ && cd $(top_srcdir) \ ++ && gtags -i $(GTAGS_ARGS) $$here ++ ++distclean-tags: ++ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags ++ ++distdir: $(DISTFILES) ++ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ ++ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ ++ list='$(DISTFILES)'; for file in $$list; do \ ++ case $$file in \ ++ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ ++ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ ++ esac; \ ++ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ ++ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ ++ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ ++ dir="/$$dir"; \ ++ $(mkdir_p) "$(distdir)$$dir"; \ ++ else \ ++ dir=''; \ ++ fi; \ ++ if test -d $$d/$$file; then \ ++ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ ++ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ ++ fi; \ ++ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ ++ else \ ++ test -f $(distdir)/$$file \ ++ || cp -p $$d/$$file $(distdir)/$$file \ ++ || exit 1; \ ++ fi; \ ++ done ++check-am: all-am ++check: check-am ++all-am: Makefile $(LIBRARIES) ++installdirs: ++install: install-am ++install-exec: install-exec-am ++install-data: install-data-am ++uninstall: uninstall-am ++ ++install-am: all-am ++ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am ++ ++installcheck: installcheck-am ++install-strip: ++ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ ++ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ ++ `test -z '$(STRIP)' || \ ++ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install ++mostlyclean-generic: ++ ++clean-generic: ++ ++distclean-generic: ++ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) ++ ++maintainer-clean-generic: ++ @echo "This command is intended for maintainers to use" ++ @echo "it deletes files that may require special tools to rebuild." ++clean: clean-am ++ ++clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ ++ mostlyclean-am ++ ++distclean: distclean-am ++ -rm -rf ./$(DEPDIR) ++ -rm -f Makefile ++distclean-am: clean-am distclean-compile distclean-generic \ ++ distclean-libtool distclean-tags ++ ++dvi: dvi-am ++ ++dvi-am: ++ ++html: html-am ++ ++info: info-am ++ ++info-am: ++ ++install-data-am: ++ ++install-exec-am: ++ ++install-info: install-info-am ++ ++install-man: ++ ++installcheck-am: ++ ++maintainer-clean: maintainer-clean-am ++ -rm -rf ./$(DEPDIR) ++ -rm -f Makefile ++maintainer-clean-am: distclean-am maintainer-clean-generic ++ ++mostlyclean: mostlyclean-am ++ ++mostlyclean-am: mostlyclean-compile mostlyclean-generic \ ++ mostlyclean-libtool ++ ++pdf: pdf-am ++ ++pdf-am: ++ ++ps: ps-am ++ ++ps-am: ++ ++uninstall-am: uninstall-info-am ++ ++.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ ++ clean-libtool clean-noinstLIBRARIES ctags distclean \ ++ distclean-compile distclean-generic distclean-libtool \ ++ distclean-tags distdir dvi dvi-am html html-am info info-am \ ++ install install-am install-data install-data-am install-exec \ ++ install-exec-am install-info install-info-am install-man \ ++ install-strip installcheck installcheck-am installdirs \ ++ maintainer-clean maintainer-clean-generic mostlyclean \ ++ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ ++ pdf pdf-am ps ps-am tags uninstall uninstall-am \ ++ uninstall-info-am ++ ++# Tell versions [3.59,3.63) of GNU make to not export all variables. ++# Otherwise a system limit (for SysV at least) may be exceeded. ++.NOEXPORT: +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/apps/Makefile.am open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/apps/Makefile.am +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/apps/Makefile.am 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/apps/Makefile.am 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1 @@ ++SUBDIRS = dhcpc brcm-iscsi +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/apps/Makefile.in open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/apps/Makefile.in +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/apps/Makefile.in 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/apps/Makefile.in 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,471 @@ ++# Makefile.in generated by automake 1.9.6 from Makefile.am. ++# @configure_input@ ++ ++# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, ++# 2003, 2004, 2005 Free Software Foundation, Inc. ++# This Makefile.in is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY, to the extent permitted by law; without ++# even the implied warranty of MERCHANTABILITY or FITNESS FOR A ++# PARTICULAR PURPOSE. ++ ++@SET_MAKE@ ++srcdir = @srcdir@ ++top_srcdir = @top_srcdir@ ++VPATH = @srcdir@ ++pkgdatadir = $(datadir)/@PACKAGE@ ++pkglibdir = $(libdir)/@PACKAGE@ ++pkgincludedir = $(includedir)/@PACKAGE@ ++top_builddir = ../.. ++am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd ++INSTALL = @INSTALL@ ++install_sh_DATA = $(install_sh) -c -m 644 ++install_sh_PROGRAM = $(install_sh) -c ++install_sh_SCRIPT = $(install_sh) -c ++INSTALL_HEADER = $(INSTALL_DATA) ++transform = $(program_transform_name) ++NORMAL_INSTALL = : ++PRE_INSTALL = : ++POST_INSTALL = : ++NORMAL_UNINSTALL = : ++PRE_UNINSTALL = : ++POST_UNINSTALL = : ++build_triplet = @build@ ++host_triplet = @host@ ++subdir = src/apps ++DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in ++ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 ++am__aclocal_m4_deps = $(top_srcdir)/configure.ac ++am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ ++ $(ACLOCAL_M4) ++mkinstalldirs = $(install_sh) -d ++CONFIG_HEADER = $(top_builddir)/config.h ++CONFIG_CLEAN_FILES = ++SOURCES = ++DIST_SOURCES = ++RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ ++ html-recursive info-recursive install-data-recursive \ ++ install-exec-recursive install-info-recursive \ ++ install-recursive installcheck-recursive installdirs-recursive \ ++ pdf-recursive ps-recursive uninstall-info-recursive \ ++ uninstall-recursive ++ETAGS = etags ++CTAGS = ctags ++DIST_SUBDIRS = $(SUBDIRS) ++DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ++ACLOCAL = @ACLOCAL@ ++AMDEP_FALSE = @AMDEP_FALSE@ ++AMDEP_TRUE = @AMDEP_TRUE@ ++AMTAR = @AMTAR@ ++AR = @AR@ ++AUTOCONF = @AUTOCONF@ ++AUTOHEADER = @AUTOHEADER@ ++AUTOMAKE = @AUTOMAKE@ ++AWK = @AWK@ ++BASH = @BASH@ ++CC = @CC@ ++CCDEPMODE = @CCDEPMODE@ ++CFLAGS = @CFLAGS@ ++CPP = @CPP@ ++CPPFLAGS = @CPPFLAGS@ ++CXX = @CXX@ ++CXXCPP = @CXXCPP@ ++CXXDEPMODE = @CXXDEPMODE@ ++CXXFLAGS = @CXXFLAGS@ ++CYGPATH_W = @CYGPATH_W@ ++DEBUG_FALSE = @DEBUG_FALSE@ ++DEBUG_TRUE = @DEBUG_TRUE@ ++DEFS = @DEFS@ ++DEPDIR = @DEPDIR@ ++ECHO = @ECHO@ ++ECHO_C = @ECHO_C@ ++ECHO_N = @ECHO_N@ ++ECHO_T = @ECHO_T@ ++EGREP = @EGREP@ ++ENDIAN = @ENDIAN@ ++EXEEXT = @EXEEXT@ ++F77 = @F77@ ++FFLAGS = @FFLAGS@ ++INSTALL_DATA = @INSTALL_DATA@ ++INSTALL_PROGRAM = @INSTALL_PROGRAM@ ++INSTALL_SCRIPT = @INSTALL_SCRIPT@ ++INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ ++LDFLAGS = @LDFLAGS@ ++LIBOBJS = @LIBOBJS@ ++LIBS = @LIBS@ ++LIBTOOL = @LIBTOOL@ ++LN_S = @LN_S@ ++LTLIBOBJS = @LTLIBOBJS@ ++MAKEINFO = @MAKEINFO@ ++OBJEXT = @OBJEXT@ ++PACKAGE = @PACKAGE@ ++PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ ++PACKAGE_NAME = @PACKAGE_NAME@ ++PACKAGE_STRING = @PACKAGE_STRING@ ++PACKAGE_TARNAME = @PACKAGE_TARNAME@ ++PACKAGE_VERSION = @PACKAGE_VERSION@ ++PATH_SEPARATOR = @PATH_SEPARATOR@ ++RANLIB = @RANLIB@ ++SED = @SED@ ++SET_MAKE = @SET_MAKE@ ++SHELL = @SHELL@ ++STRIP = @STRIP@ ++VERSION = @VERSION@ ++ac_ct_AR = @ac_ct_AR@ ++ac_ct_CC = @ac_ct_CC@ ++ac_ct_CXX = @ac_ct_CXX@ ++ac_ct_F77 = @ac_ct_F77@ ++ac_ct_RANLIB = @ac_ct_RANLIB@ ++ac_ct_STRIP = @ac_ct_STRIP@ ++am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ ++am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ ++am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ ++am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ ++am__include = @am__include@ ++am__leading_dot = @am__leading_dot@ ++am__quote = @am__quote@ ++am__tar = @am__tar@ ++am__untar = @am__untar@ ++bindir = @bindir@ ++build = @build@ ++build_alias = @build_alias@ ++build_cpu = @build_cpu@ ++build_os = @build_os@ ++build_vendor = @build_vendor@ ++datadir = @datadir@ ++exec_prefix = @exec_prefix@ ++host = @host@ ++host_alias = @host_alias@ ++host_cpu = @host_cpu@ ++host_os = @host_os@ ++host_vendor = @host_vendor@ ++includedir = @includedir@ ++infodir = @infodir@ ++install_sh = @install_sh@ ++libdir = @libdir@ ++libexecdir = @libexecdir@ ++localstatedir = @localstatedir@ ++mandir = @mandir@ ++mkdir_p = @mkdir_p@ ++oldincludedir = @oldincludedir@ ++prefix = @prefix@ ++program_transform_name = @program_transform_name@ ++sbindir = @sbindir@ ++sharedstatedir = @sharedstatedir@ ++sysconfdir = @sysconfdir@ ++target_alias = @target_alias@ ++SUBDIRS = dhcpc brcm-iscsi ++all: all-recursive ++ ++.SUFFIXES: ++$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) ++ @for dep in $?; do \ ++ case '$(am__configure_deps)' in \ ++ *$$dep*) \ ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ ++ && exit 0; \ ++ exit 1;; \ ++ esac; \ ++ done; \ ++ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/apps/Makefile'; \ ++ cd $(top_srcdir) && \ ++ $(AUTOMAKE) --gnu src/apps/Makefile ++.PRECIOUS: Makefile ++Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status ++ @case '$?' in \ ++ *config.status*) \ ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ ++ *) \ ++ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ ++ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ ++ esac; ++ ++$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++ ++$(top_srcdir)/configure: $(am__configure_deps) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++$(ACLOCAL_M4): $(am__aclocal_m4_deps) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++ ++mostlyclean-libtool: ++ -rm -f *.lo ++ ++clean-libtool: ++ -rm -rf .libs _libs ++ ++distclean-libtool: ++ -rm -f libtool ++uninstall-info-am: ++ ++# This directory's subdirectories are mostly independent; you can cd ++# into them and run `make' without going through this Makefile. ++# To change the values of `make' variables: instead of editing Makefiles, ++# (1) if the variable is set in `config.status', edit `config.status' ++# (which will cause the Makefiles to be regenerated when you run `make'); ++# (2) otherwise, pass the desired values on the `make' command line. ++$(RECURSIVE_TARGETS): ++ @failcom='exit 1'; \ ++ for f in x $$MAKEFLAGS; do \ ++ case $$f in \ ++ *=* | --[!k]*);; \ ++ *k*) failcom='fail=yes';; \ ++ esac; \ ++ done; \ ++ dot_seen=no; \ ++ target=`echo $@ | sed s/-recursive//`; \ ++ list='$(SUBDIRS)'; for subdir in $$list; do \ ++ echo "Making $$target in $$subdir"; \ ++ if test "$$subdir" = "."; then \ ++ dot_seen=yes; \ ++ local_target="$$target-am"; \ ++ else \ ++ local_target="$$target"; \ ++ fi; \ ++ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ ++ || eval $$failcom; \ ++ done; \ ++ if test "$$dot_seen" = "no"; then \ ++ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ ++ fi; test -z "$$fail" ++ ++mostlyclean-recursive clean-recursive distclean-recursive \ ++maintainer-clean-recursive: ++ @failcom='exit 1'; \ ++ for f in x $$MAKEFLAGS; do \ ++ case $$f in \ ++ *=* | --[!k]*);; \ ++ *k*) failcom='fail=yes';; \ ++ esac; \ ++ done; \ ++ dot_seen=no; \ ++ case "$@" in \ ++ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ ++ *) list='$(SUBDIRS)' ;; \ ++ esac; \ ++ rev=''; for subdir in $$list; do \ ++ if test "$$subdir" = "."; then :; else \ ++ rev="$$subdir $$rev"; \ ++ fi; \ ++ done; \ ++ rev="$$rev ."; \ ++ target=`echo $@ | sed s/-recursive//`; \ ++ for subdir in $$rev; do \ ++ echo "Making $$target in $$subdir"; \ ++ if test "$$subdir" = "."; then \ ++ local_target="$$target-am"; \ ++ else \ ++ local_target="$$target"; \ ++ fi; \ ++ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ ++ || eval $$failcom; \ ++ done && test -z "$$fail" ++tags-recursive: ++ list='$(SUBDIRS)'; for subdir in $$list; do \ ++ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ ++ done ++ctags-recursive: ++ list='$(SUBDIRS)'; for subdir in $$list; do \ ++ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ ++ done ++ ++ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) ++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) ' { files[$$0] = 1; } \ ++ END { for (i in files) print i; }'`; \ ++ mkid -fID $$unique ++tags: TAGS ++ ++TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ ++ $(TAGS_FILES) $(LISP) ++ tags=; \ ++ here=`pwd`; \ ++ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ ++ include_option=--etags-include; \ ++ empty_fix=.; \ ++ else \ ++ include_option=--include; \ ++ empty_fix=; \ ++ fi; \ ++ list='$(SUBDIRS)'; for subdir in $$list; do \ ++ if test "$$subdir" = .; then :; else \ ++ test ! -f $$subdir/TAGS || \ ++ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ ++ fi; \ ++ done; \ ++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) ' { files[$$0] = 1; } \ ++ END { for (i in files) print i; }'`; \ ++ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ ++ test -n "$$unique" || unique=$$empty_fix; \ ++ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ ++ $$tags $$unique; \ ++ fi ++ctags: CTAGS ++CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ ++ $(TAGS_FILES) $(LISP) ++ tags=; \ ++ here=`pwd`; \ ++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) ' { files[$$0] = 1; } \ ++ END { for (i in files) print i; }'`; \ ++ test -z "$(CTAGS_ARGS)$$tags$$unique" \ ++ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ ++ $$tags $$unique ++ ++GTAGS: ++ here=`$(am__cd) $(top_builddir) && pwd` \ ++ && cd $(top_srcdir) \ ++ && gtags -i $(GTAGS_ARGS) $$here ++ ++distclean-tags: ++ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags ++ ++distdir: $(DISTFILES) ++ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ ++ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ ++ list='$(DISTFILES)'; for file in $$list; do \ ++ case $$file in \ ++ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ ++ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ ++ esac; \ ++ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ ++ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ ++ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ ++ dir="/$$dir"; \ ++ $(mkdir_p) "$(distdir)$$dir"; \ ++ else \ ++ dir=''; \ ++ fi; \ ++ if test -d $$d/$$file; then \ ++ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ ++ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ ++ fi; \ ++ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ ++ else \ ++ test -f $(distdir)/$$file \ ++ || cp -p $$d/$$file $(distdir)/$$file \ ++ || exit 1; \ ++ fi; \ ++ done ++ list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ ++ if test "$$subdir" = .; then :; else \ ++ test -d "$(distdir)/$$subdir" \ ++ || $(mkdir_p) "$(distdir)/$$subdir" \ ++ || exit 1; \ ++ distdir=`$(am__cd) $(distdir) && pwd`; \ ++ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ ++ (cd $$subdir && \ ++ $(MAKE) $(AM_MAKEFLAGS) \ ++ top_distdir="$$top_distdir" \ ++ distdir="$$distdir/$$subdir" \ ++ distdir) \ ++ || exit 1; \ ++ fi; \ ++ done ++check-am: all-am ++check: check-recursive ++all-am: Makefile ++installdirs: installdirs-recursive ++installdirs-am: ++install: install-recursive ++install-exec: install-exec-recursive ++install-data: install-data-recursive ++uninstall: uninstall-recursive ++ ++install-am: all-am ++ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am ++ ++installcheck: installcheck-recursive ++install-strip: ++ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ ++ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ ++ `test -z '$(STRIP)' || \ ++ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install ++mostlyclean-generic: ++ ++clean-generic: ++ ++distclean-generic: ++ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) ++ ++maintainer-clean-generic: ++ @echo "This command is intended for maintainers to use" ++ @echo "it deletes files that may require special tools to rebuild." ++clean: clean-recursive ++ ++clean-am: clean-generic clean-libtool mostlyclean-am ++ ++distclean: distclean-recursive ++ -rm -f Makefile ++distclean-am: clean-am distclean-generic distclean-libtool \ ++ distclean-tags ++ ++dvi: dvi-recursive ++ ++dvi-am: ++ ++html: html-recursive ++ ++info: info-recursive ++ ++info-am: ++ ++install-data-am: ++ ++install-exec-am: ++ ++install-info: install-info-recursive ++ ++install-man: ++ ++installcheck-am: ++ ++maintainer-clean: maintainer-clean-recursive ++ -rm -f Makefile ++maintainer-clean-am: distclean-am maintainer-clean-generic ++ ++mostlyclean: mostlyclean-recursive ++ ++mostlyclean-am: mostlyclean-generic mostlyclean-libtool ++ ++pdf: pdf-recursive ++ ++pdf-am: ++ ++ps: ps-recursive ++ ++ps-am: ++ ++uninstall-am: uninstall-info-am ++ ++uninstall-info: uninstall-info-recursive ++ ++.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am \ ++ clean clean-generic clean-libtool clean-recursive ctags \ ++ ctags-recursive distclean distclean-generic distclean-libtool \ ++ distclean-recursive distclean-tags distdir dvi dvi-am html \ ++ html-am info info-am install install-am install-data \ ++ install-data-am install-exec install-exec-am install-info \ ++ install-info-am install-man install-strip installcheck \ ++ installcheck-am installdirs installdirs-am maintainer-clean \ ++ maintainer-clean-generic maintainer-clean-recursive \ ++ mostlyclean mostlyclean-generic mostlyclean-libtool \ ++ mostlyclean-recursive pdf pdf-am ps ps-am tags tags-recursive \ ++ uninstall uninstall-am uninstall-info-am ++ ++# Tell versions [3.59,3.63) of GNU make to not export all variables. ++# Otherwise a system limit (for SysV at least) may be exceeded. ++.NOEXPORT: +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/apps/README open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/apps/README +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/apps/README 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/apps/README 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,2 @@ ++This directory contains a few example applications. They are not all ++heavily tested, however. +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/Makefile.am open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/Makefile.am +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/Makefile.am 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/Makefile.am 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1 @@ ++SUBDIRS = apps uip unix +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/Makefile.in open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/Makefile.in +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/Makefile.in 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/Makefile.in 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,471 @@ ++# Makefile.in generated by automake 1.9.6 from Makefile.am. ++# @configure_input@ ++ ++# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, ++# 2003, 2004, 2005 Free Software Foundation, Inc. ++# This Makefile.in is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY, to the extent permitted by law; without ++# even the implied warranty of MERCHANTABILITY or FITNESS FOR A ++# PARTICULAR PURPOSE. ++ ++@SET_MAKE@ ++srcdir = @srcdir@ ++top_srcdir = @top_srcdir@ ++VPATH = @srcdir@ ++pkgdatadir = $(datadir)/@PACKAGE@ ++pkglibdir = $(libdir)/@PACKAGE@ ++pkgincludedir = $(includedir)/@PACKAGE@ ++top_builddir = .. ++am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd ++INSTALL = @INSTALL@ ++install_sh_DATA = $(install_sh) -c -m 644 ++install_sh_PROGRAM = $(install_sh) -c ++install_sh_SCRIPT = $(install_sh) -c ++INSTALL_HEADER = $(INSTALL_DATA) ++transform = $(program_transform_name) ++NORMAL_INSTALL = : ++PRE_INSTALL = : ++POST_INSTALL = : ++NORMAL_UNINSTALL = : ++PRE_UNINSTALL = : ++POST_UNINSTALL = : ++build_triplet = @build@ ++host_triplet = @host@ ++subdir = src ++DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in ++ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 ++am__aclocal_m4_deps = $(top_srcdir)/configure.ac ++am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ ++ $(ACLOCAL_M4) ++mkinstalldirs = $(install_sh) -d ++CONFIG_HEADER = $(top_builddir)/config.h ++CONFIG_CLEAN_FILES = ++SOURCES = ++DIST_SOURCES = ++RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ ++ html-recursive info-recursive install-data-recursive \ ++ install-exec-recursive install-info-recursive \ ++ install-recursive installcheck-recursive installdirs-recursive \ ++ pdf-recursive ps-recursive uninstall-info-recursive \ ++ uninstall-recursive ++ETAGS = etags ++CTAGS = ctags ++DIST_SUBDIRS = $(SUBDIRS) ++DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ++ACLOCAL = @ACLOCAL@ ++AMDEP_FALSE = @AMDEP_FALSE@ ++AMDEP_TRUE = @AMDEP_TRUE@ ++AMTAR = @AMTAR@ ++AR = @AR@ ++AUTOCONF = @AUTOCONF@ ++AUTOHEADER = @AUTOHEADER@ ++AUTOMAKE = @AUTOMAKE@ ++AWK = @AWK@ ++BASH = @BASH@ ++CC = @CC@ ++CCDEPMODE = @CCDEPMODE@ ++CFLAGS = @CFLAGS@ ++CPP = @CPP@ ++CPPFLAGS = @CPPFLAGS@ ++CXX = @CXX@ ++CXXCPP = @CXXCPP@ ++CXXDEPMODE = @CXXDEPMODE@ ++CXXFLAGS = @CXXFLAGS@ ++CYGPATH_W = @CYGPATH_W@ ++DEBUG_FALSE = @DEBUG_FALSE@ ++DEBUG_TRUE = @DEBUG_TRUE@ ++DEFS = @DEFS@ ++DEPDIR = @DEPDIR@ ++ECHO = @ECHO@ ++ECHO_C = @ECHO_C@ ++ECHO_N = @ECHO_N@ ++ECHO_T = @ECHO_T@ ++EGREP = @EGREP@ ++ENDIAN = @ENDIAN@ ++EXEEXT = @EXEEXT@ ++F77 = @F77@ ++FFLAGS = @FFLAGS@ ++INSTALL_DATA = @INSTALL_DATA@ ++INSTALL_PROGRAM = @INSTALL_PROGRAM@ ++INSTALL_SCRIPT = @INSTALL_SCRIPT@ ++INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ ++LDFLAGS = @LDFLAGS@ ++LIBOBJS = @LIBOBJS@ ++LIBS = @LIBS@ ++LIBTOOL = @LIBTOOL@ ++LN_S = @LN_S@ ++LTLIBOBJS = @LTLIBOBJS@ ++MAKEINFO = @MAKEINFO@ ++OBJEXT = @OBJEXT@ ++PACKAGE = @PACKAGE@ ++PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ ++PACKAGE_NAME = @PACKAGE_NAME@ ++PACKAGE_STRING = @PACKAGE_STRING@ ++PACKAGE_TARNAME = @PACKAGE_TARNAME@ ++PACKAGE_VERSION = @PACKAGE_VERSION@ ++PATH_SEPARATOR = @PATH_SEPARATOR@ ++RANLIB = @RANLIB@ ++SED = @SED@ ++SET_MAKE = @SET_MAKE@ ++SHELL = @SHELL@ ++STRIP = @STRIP@ ++VERSION = @VERSION@ ++ac_ct_AR = @ac_ct_AR@ ++ac_ct_CC = @ac_ct_CC@ ++ac_ct_CXX = @ac_ct_CXX@ ++ac_ct_F77 = @ac_ct_F77@ ++ac_ct_RANLIB = @ac_ct_RANLIB@ ++ac_ct_STRIP = @ac_ct_STRIP@ ++am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ ++am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ ++am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ ++am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ ++am__include = @am__include@ ++am__leading_dot = @am__leading_dot@ ++am__quote = @am__quote@ ++am__tar = @am__tar@ ++am__untar = @am__untar@ ++bindir = @bindir@ ++build = @build@ ++build_alias = @build_alias@ ++build_cpu = @build_cpu@ ++build_os = @build_os@ ++build_vendor = @build_vendor@ ++datadir = @datadir@ ++exec_prefix = @exec_prefix@ ++host = @host@ ++host_alias = @host_alias@ ++host_cpu = @host_cpu@ ++host_os = @host_os@ ++host_vendor = @host_vendor@ ++includedir = @includedir@ ++infodir = @infodir@ ++install_sh = @install_sh@ ++libdir = @libdir@ ++libexecdir = @libexecdir@ ++localstatedir = @localstatedir@ ++mandir = @mandir@ ++mkdir_p = @mkdir_p@ ++oldincludedir = @oldincludedir@ ++prefix = @prefix@ ++program_transform_name = @program_transform_name@ ++sbindir = @sbindir@ ++sharedstatedir = @sharedstatedir@ ++sysconfdir = @sysconfdir@ ++target_alias = @target_alias@ ++SUBDIRS = apps uip unix ++all: all-recursive ++ ++.SUFFIXES: ++$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) ++ @for dep in $?; do \ ++ case '$(am__configure_deps)' in \ ++ *$$dep*) \ ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ ++ && exit 0; \ ++ exit 1;; \ ++ esac; \ ++ done; \ ++ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ ++ cd $(top_srcdir) && \ ++ $(AUTOMAKE) --gnu src/Makefile ++.PRECIOUS: Makefile ++Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status ++ @case '$?' in \ ++ *config.status*) \ ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ ++ *) \ ++ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ ++ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ ++ esac; ++ ++$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++ ++$(top_srcdir)/configure: $(am__configure_deps) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++$(ACLOCAL_M4): $(am__aclocal_m4_deps) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++ ++mostlyclean-libtool: ++ -rm -f *.lo ++ ++clean-libtool: ++ -rm -rf .libs _libs ++ ++distclean-libtool: ++ -rm -f libtool ++uninstall-info-am: ++ ++# This directory's subdirectories are mostly independent; you can cd ++# into them and run `make' without going through this Makefile. ++# To change the values of `make' variables: instead of editing Makefiles, ++# (1) if the variable is set in `config.status', edit `config.status' ++# (which will cause the Makefiles to be regenerated when you run `make'); ++# (2) otherwise, pass the desired values on the `make' command line. ++$(RECURSIVE_TARGETS): ++ @failcom='exit 1'; \ ++ for f in x $$MAKEFLAGS; do \ ++ case $$f in \ ++ *=* | --[!k]*);; \ ++ *k*) failcom='fail=yes';; \ ++ esac; \ ++ done; \ ++ dot_seen=no; \ ++ target=`echo $@ | sed s/-recursive//`; \ ++ list='$(SUBDIRS)'; for subdir in $$list; do \ ++ echo "Making $$target in $$subdir"; \ ++ if test "$$subdir" = "."; then \ ++ dot_seen=yes; \ ++ local_target="$$target-am"; \ ++ else \ ++ local_target="$$target"; \ ++ fi; \ ++ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ ++ || eval $$failcom; \ ++ done; \ ++ if test "$$dot_seen" = "no"; then \ ++ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ ++ fi; test -z "$$fail" ++ ++mostlyclean-recursive clean-recursive distclean-recursive \ ++maintainer-clean-recursive: ++ @failcom='exit 1'; \ ++ for f in x $$MAKEFLAGS; do \ ++ case $$f in \ ++ *=* | --[!k]*);; \ ++ *k*) failcom='fail=yes';; \ ++ esac; \ ++ done; \ ++ dot_seen=no; \ ++ case "$@" in \ ++ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ ++ *) list='$(SUBDIRS)' ;; \ ++ esac; \ ++ rev=''; for subdir in $$list; do \ ++ if test "$$subdir" = "."; then :; else \ ++ rev="$$subdir $$rev"; \ ++ fi; \ ++ done; \ ++ rev="$$rev ."; \ ++ target=`echo $@ | sed s/-recursive//`; \ ++ for subdir in $$rev; do \ ++ echo "Making $$target in $$subdir"; \ ++ if test "$$subdir" = "."; then \ ++ local_target="$$target-am"; \ ++ else \ ++ local_target="$$target"; \ ++ fi; \ ++ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ ++ || eval $$failcom; \ ++ done && test -z "$$fail" ++tags-recursive: ++ list='$(SUBDIRS)'; for subdir in $$list; do \ ++ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ ++ done ++ctags-recursive: ++ list='$(SUBDIRS)'; for subdir in $$list; do \ ++ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ ++ done ++ ++ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) ++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) ' { files[$$0] = 1; } \ ++ END { for (i in files) print i; }'`; \ ++ mkid -fID $$unique ++tags: TAGS ++ ++TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ ++ $(TAGS_FILES) $(LISP) ++ tags=; \ ++ here=`pwd`; \ ++ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ ++ include_option=--etags-include; \ ++ empty_fix=.; \ ++ else \ ++ include_option=--include; \ ++ empty_fix=; \ ++ fi; \ ++ list='$(SUBDIRS)'; for subdir in $$list; do \ ++ if test "$$subdir" = .; then :; else \ ++ test ! -f $$subdir/TAGS || \ ++ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ ++ fi; \ ++ done; \ ++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) ' { files[$$0] = 1; } \ ++ END { for (i in files) print i; }'`; \ ++ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ ++ test -n "$$unique" || unique=$$empty_fix; \ ++ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ ++ $$tags $$unique; \ ++ fi ++ctags: CTAGS ++CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ ++ $(TAGS_FILES) $(LISP) ++ tags=; \ ++ here=`pwd`; \ ++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) ' { files[$$0] = 1; } \ ++ END { for (i in files) print i; }'`; \ ++ test -z "$(CTAGS_ARGS)$$tags$$unique" \ ++ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ ++ $$tags $$unique ++ ++GTAGS: ++ here=`$(am__cd) $(top_builddir) && pwd` \ ++ && cd $(top_srcdir) \ ++ && gtags -i $(GTAGS_ARGS) $$here ++ ++distclean-tags: ++ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags ++ ++distdir: $(DISTFILES) ++ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ ++ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ ++ list='$(DISTFILES)'; for file in $$list; do \ ++ case $$file in \ ++ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ ++ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ ++ esac; \ ++ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ ++ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ ++ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ ++ dir="/$$dir"; \ ++ $(mkdir_p) "$(distdir)$$dir"; \ ++ else \ ++ dir=''; \ ++ fi; \ ++ if test -d $$d/$$file; then \ ++ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ ++ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ ++ fi; \ ++ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ ++ else \ ++ test -f $(distdir)/$$file \ ++ || cp -p $$d/$$file $(distdir)/$$file \ ++ || exit 1; \ ++ fi; \ ++ done ++ list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ ++ if test "$$subdir" = .; then :; else \ ++ test -d "$(distdir)/$$subdir" \ ++ || $(mkdir_p) "$(distdir)/$$subdir" \ ++ || exit 1; \ ++ distdir=`$(am__cd) $(distdir) && pwd`; \ ++ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ ++ (cd $$subdir && \ ++ $(MAKE) $(AM_MAKEFLAGS) \ ++ top_distdir="$$top_distdir" \ ++ distdir="$$distdir/$$subdir" \ ++ distdir) \ ++ || exit 1; \ ++ fi; \ ++ done ++check-am: all-am ++check: check-recursive ++all-am: Makefile ++installdirs: installdirs-recursive ++installdirs-am: ++install: install-recursive ++install-exec: install-exec-recursive ++install-data: install-data-recursive ++uninstall: uninstall-recursive ++ ++install-am: all-am ++ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am ++ ++installcheck: installcheck-recursive ++install-strip: ++ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ ++ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ ++ `test -z '$(STRIP)' || \ ++ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install ++mostlyclean-generic: ++ ++clean-generic: ++ ++distclean-generic: ++ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) ++ ++maintainer-clean-generic: ++ @echo "This command is intended for maintainers to use" ++ @echo "it deletes files that may require special tools to rebuild." ++clean: clean-recursive ++ ++clean-am: clean-generic clean-libtool mostlyclean-am ++ ++distclean: distclean-recursive ++ -rm -f Makefile ++distclean-am: clean-am distclean-generic distclean-libtool \ ++ distclean-tags ++ ++dvi: dvi-recursive ++ ++dvi-am: ++ ++html: html-recursive ++ ++info: info-recursive ++ ++info-am: ++ ++install-data-am: ++ ++install-exec-am: ++ ++install-info: install-info-recursive ++ ++install-man: ++ ++installcheck-am: ++ ++maintainer-clean: maintainer-clean-recursive ++ -rm -f Makefile ++maintainer-clean-am: distclean-am maintainer-clean-generic ++ ++mostlyclean: mostlyclean-recursive ++ ++mostlyclean-am: mostlyclean-generic mostlyclean-libtool ++ ++pdf: pdf-recursive ++ ++pdf-am: ++ ++ps: ps-recursive ++ ++ps-am: ++ ++uninstall-am: uninstall-info-am ++ ++uninstall-info: uninstall-info-recursive ++ ++.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am \ ++ clean clean-generic clean-libtool clean-recursive ctags \ ++ ctags-recursive distclean distclean-generic distclean-libtool \ ++ distclean-recursive distclean-tags distdir dvi dvi-am html \ ++ html-am info info-am install install-am install-data \ ++ install-data-am install-exec install-exec-am install-info \ ++ install-info-am install-man install-strip installcheck \ ++ installcheck-am installdirs installdirs-am maintainer-clean \ ++ maintainer-clean-generic maintainer-clean-recursive \ ++ mostlyclean mostlyclean-generic mostlyclean-libtool \ ++ mostlyclean-recursive pdf pdf-am ps ps-am tags tags-recursive \ ++ uninstall uninstall-am uninstall-info-am ++ ++# Tell versions [3.59,3.63) of GNU make to not export all variables. ++# Otherwise a system limit (for SysV at least) may be exceeded. ++.NOEXPORT: +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/README open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/README +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/README 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/README 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,13 @@ ++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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/clock.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/clock.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/clock.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/clock.h 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,88 @@ ++/** ++ * \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 ++ * ++ * $Id: clock.h,v 1.3 2006/06/11 21:46:39 adam Exp $ ++ */ ++#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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/debug.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/debug.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/debug.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/debug.h 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,9 @@ ++#ifndef __DEBUG_H__ ++#define __DEBUG_H__ ++ ++#ifdef DEBUG ++#define UIP_DEBUG(args...) fprintf(stdout, args); fflush(stdout) ++#else ++#endif ++ ++#endif +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/icmpv6.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/icmpv6.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/icmpv6.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/icmpv6.h 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,312 @@ ++/* ++ * Copyright (c) 2011, Broadcom 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__ ++ ++#define __FAR__ ++ ++#ifdef PACK_DATA_STRUCTURE ++#pragma pack(push,1) ++#endif ++ ++/* 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 */ ++typedef 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; ++} ICMPV6_HDR, __FAR__ * pICMPV6_HDR; ++ ++#define icmpv6_data data.icmpv6_un_data32[0] ++ ++typedef struct ICMPV6_OPT_HDR { ++ u8_t type; ++ u8_t len; ++} ICMPV6_OPT_HDR, __FAR__ * pICMPV6_OPT_HDR; ++ ++typedef struct ICMPV6_OPT_LINK_ADDR { ++ ICMPV6_OPT_HDR hdr; ++ u8_t link_addr[6]; ++} ICMPV6_OPT_LINK_ADDR, *pICMPV6_OPT_LINK_ADDR; ++ ++typedef struct ICMPV6_OPT_PREFIX { ++ 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; ++ IPV6_ADDR prefix; ++} ICMPV6_OPT_PREFIX, __FAR__ * pICMPV6_OPT_PREFIX; ++ ++/* Neighbor Solicitation */ ++typedef struct ICMPV6_ND_SOLICIT { ++ ICMPV6_HDR nd_ns_hdr; ++ //struct id_struct nd_ns_target; /*target address */ ++} ICMPV6_ND_SOLICIT, *pICMPV6_ND_SOLICIT; ++ ++/* Router Advertisement */ ++typedef struct ICMPV6_ROUTER_ADVERT { ++ ICMPV6_HDR header; ++ u32_t reachable_time; ++ u32_t retransmit_timer; ++} ICMPV6_ROUTER_ADVERT, __FAR__ * pICMPV6_ROUTER_ADVERT; ++ ++#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] ++ ++#ifdef PACK_DATA_STRUCTURE ++#pragma pack(pop) ++#endif ++ ++#endif /* __ICMPV6_H__ */ +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/ipv6.c open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/ipv6.c +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/ipv6.c 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/ipv6.c 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,1269 @@ ++/* ++ * Copyright (c) 2011, Broadcom 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 "logger.h" ++#include "uip.h" ++#include "ipv6.h" ++#include "ipv6_pkt.h" ++#include "icmpv6.h" ++#include "uipopt.h" ++#include "dhcpv6.h" ++ ++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(pIPV6_CONTEXT ipv6_context, ++ IPV6_ADDR __FAR__ * ipv6_addr); ++STATIC void ipv6_insert_protocol_chksum(pIPV6_HDR ipv6); ++STATIC void ipv6_update_arp_table(pIPV6_CONTEXT ipv6_context, ++ IPV6_ADDR __FAR__ * ip_addr, ++ MAC_ADDR __FAR__ * mac_addr); ++STATIC void ipv6_icmp_init_link_option(pIPV6_CONTEXT ipv6_context, ++ pICMPV6_OPT_LINK_ADDR link_opt, ++ u8_t type); ++STATIC void ipv6_icmp_rx(pIPV6_CONTEXT ipv6_context); ++STATIC void ipv6_icmp_handle_nd_adv(pIPV6_CONTEXT ipv6_context); ++STATIC void ipv6_icmp_handle_nd_sol(pIPV6_CONTEXT ipv6_context); ++STATIC void ipv6_icmp_handle_echo_request(pIPV6_CONTEXT ipv6_context); ++STATIC void ipv6_icmp_handle_router_adv(pIPV6_CONTEXT ipv6_context); ++STATIC void ipv6_icmp_process_prefix(pIPV6_CONTEXT ipv6_context, ++ pICMPV6_OPT_PREFIX icmp_prefix); ++STATIC void ipv6_udp_rx(pIPV6_CONTEXT ipv6_context); ++ ++int iscsiL2Send(pIPV6_CONTEXT ipv6_context, int pkt_len) ++{ ++ LOG_DEBUG("IPV6: iscsiL2Send"); ++ uip_send(ipv6_context->ustack, ++ (void *)ipv6_context->ustack->data_link_layer, pkt_len); ++ ++ return pkt_len; ++} ++ ++int iscsiL2AddMcAddr(pIPV6_CONTEXT ipv6_context, MAC_ADDR * new_mc_addr) ++{ ++ int i; ++ MAC_ADDR *mc_addr; ++ const MAC_ADDR all_zeroes_mc = { 0, 0, 0, 0, 0, 0 }; ++ ++ mc_addr = ipv6_context->mc_addr; ++ for (i = 0; i < MAX_MCADDR_TABLE; i++, mc_addr++) ++ if (!memcmp((char __FAR__ *)mc_addr, ++ (char __FAR__ *)new_mc_addr, sizeof(MAC_ADDR))) ++ return TRUE; /* Already in the mc table */ ++ ++ mc_addr = ipv6_context->mc_addr; ++ for (i = 0; i < MAX_MCADDR_TABLE; i++, mc_addr++) ++ if (!memcmp((char __FAR__ *)mc_addr, ++ (char __FAR__ *)&all_zeroes_mc, sizeof(MAC_ADDR))) { ++ memcpy((char __FAR__ *)mc_addr, ++ (char __FAR__ *)new_mc_addr, sizeof(MAC_ADDR)); ++ LOG_DEBUG("IPV6: mc_addr added %x:%x:%x:%x:%x:%x", ++ *(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(pIPV6_CONTEXT ipv6_context, pMAC_ADDRESS dest_mac) ++{ ++ int i; ++ MAC_ADDR *mc_addr; ++ ++ mc_addr = ipv6_context->mc_addr; ++ for (i = 0; i < MAX_MCADDR_TABLE; i++, mc_addr++) ++ if (!memcmp((char __FAR__ *)mc_addr, ++ (char __FAR__ *)dest_mac->addr, sizeof(MAC_ADDR))) ++ return TRUE; ++ return FALSE; ++} ++ ++void ipv6_init(struct ndpc_state *ndp, int cfg) ++{ ++ int i; ++ pIPV6_CONTEXT ipv6_context = (pIPV6_CONTEXT) ndp->ipv6_context; ++ u8_t *mac_addr = (u8_t *) ndp->mac_addr; ++ pIPV6_ARP_ENTRY ipv6_arp_table; ++ pIPV6_PREFIX_ENTRY ipv6_prefix_table; ++ MAC_ADDR mc_addr; ++ ++ if (ipv6_context == NULL) { ++ LOG_ERR("IPV6: INIT ipv6_context is NULL"); ++ return; ++ } ++ ++ memset((char __FAR__ *)ipv6_context, 0, sizeof(IPV6_CONTEXT)); ++ ++ /* Associate the nic_iface's ustack to this ipv6_context */ ++ ipv6_context->ustack = ndp->ustack; ++ ++ ipv6_arp_table = &ipv6_context->ipv6_arp_table[0]; ++ ipv6_prefix_table = &ipv6_context->ipv6_prefix_table[0]; ++ ++ memset((char __FAR__ *)ipv6_arp_table, 0, sizeof(ipv6_arp_table)); ++ memset((char __FAR__ *)ipv6_prefix_table, 0, sizeof(ipv6_prefix_table)); ++ memcpy((char __FAR__ *)&ipv6_context->mac_addr, ++ (char __FAR__ *)mac_addr, sizeof(MAC_ADDR)); ++ /* ++ * 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 | ++ * +----------+-------------------------+----------------------------+ ++ */ ++ ipv6_context->link_local_addr.addr8[0] = 0xfe; ++ ipv6_context->link_local_addr.addr8[1] = 0x80; ++ /* Bit 1 is 1 to indicate universal scope. */ ++ ipv6_context->link_local_addr.addr8[8] = mac_addr[0] | 0x2; ++ ipv6_context->link_local_addr.addr8[9] = mac_addr[1]; ++ ipv6_context->link_local_addr.addr8[10] = mac_addr[2]; ++ ipv6_context->link_local_addr.addr8[11] = 0xff; ++ ipv6_context->link_local_addr.addr8[12] = 0xfe; ++ ipv6_context->link_local_addr.addr8[13] = mac_addr[3]; ++ ipv6_context->link_local_addr.addr8[14] = mac_addr[4]; ++ ipv6_context->link_local_addr.addr8[15] = mac_addr[5]; ++ ++ ipv6_context->link_local_multi.addr8[0] = 0xff; ++ ipv6_context->link_local_multi.addr8[1] = 0x02; ++ ipv6_context->link_local_multi.addr8[11] = 0x01; ++ ipv6_context->link_local_multi.addr8[12] = 0xff; ++ ipv6_context->link_local_multi.addr8[13] |= ++ ipv6_context->link_local_addr.addr8[13]; ++ ipv6_context->link_local_multi.addr16[7] = ++ ipv6_context->link_local_addr.addr16[7]; ++ ++ /* Default Prefix length is 64 */ ++ /* Add Link local address to the head of the ipv6 address ++ list */ ++ ipv6_add_prefix_entry(ipv6_context, ++ &ipv6_context->link_local_addr, 64); ++ ++ /* ++ * Convert Multicast IP address to Multicast MAC adress per ++ * RFC 2464: Transmission of IPv6 Packets over Ethernet Networks ++ * ++ * 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[0] = 0x33; ++ mc_addr[1] = 0x33; ++ mc_addr[2] = 0x0; ++ mc_addr[3] = 0x0; ++ mc_addr[4] = 0x0; ++ ++ switch (i) { ++ case 0: ++ /* All Nodes Multicast IPv6 address : ff02::1 */ ++ mc_addr[5] = 0x1; ++ break; ++ ++ case 1: ++ /* All Host Multicast IPv6 address : ff02::3 */ ++ mc_addr[5] = 0x3; ++ break; ++ ++ case 2: ++ /* Solicited Node Multicast Address: ff02::01:ffxx:yyzz ++ */ ++ mc_addr[2] = 0xff; ++ mc_addr[3] = mac_addr[3]; ++ mc_addr[4] = mac_addr[4]; ++ mc_addr[5] = mac_addr[5]; ++ break; ++ ++ default: ++ break; ++ } ++ iscsiL2AddMcAddr(ipv6_context, &mc_addr); ++ } ++ ++ /* Default HOP number */ ++ ipv6_context->hop_limit = IPV6_HOP_LIMIT; ++} ++ ++int ipv6_add_prefix_entry(pIPV6_CONTEXT ipv6_context, ++ IPV6_ADDR * ipv6_addr, u8_t prefix_len) ++{ ++ int i; ++ pIPV6_PREFIX_ENTRY prefix_entry; ++ pIPV6_PREFIX_ENTRY ipv6_prefix_table = ipv6_context->ipv6_prefix_table; ++ ++ /* 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 __FAR__ *)&prefix_entry->address, ++ (char __FAR__ *)ipv6_addr, ++ sizeof(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 __FAR__ *)&prefix_entry->address, ++ (char __FAR__ *)ipv6_addr, sizeof(IPV6_ADDR)); ++ ++ ++ LOG_DEBUG("IPV6: add prefix ip addr " ++ "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x " ++ "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", ++ prefix_entry->address.addr8[0], prefix_entry->address.addr8[1], ++ prefix_entry->address.addr8[2], prefix_entry->address.addr8[3], ++ prefix_entry->address.addr8[4], prefix_entry->address.addr8[5], ++ prefix_entry->address.addr8[6], prefix_entry->address.addr8[7], ++ prefix_entry->address.addr8[8], prefix_entry->address.addr8[9], ++ prefix_entry->address.addr8[10], prefix_entry->address.addr8[11], ++ prefix_entry->address.addr8[12], prefix_entry->address.addr8[13], ++ prefix_entry->address.addr8[14], prefix_entry->address.addr8[15]); ++ ++ /* Put it on the list on head of the list. */ ++ if (ipv6_context->addr_list != NULL) { ++ prefix_entry->next = ipv6_context->addr_list; ++ } else { ++ prefix_entry->next = NULL; ++ } ++ ++ ipv6_context->addr_list = prefix_entry; ++ ++ return 0; ++} ++ ++void ipv6_rx_packet(pIPV6_CONTEXT ipv6_context, u16_t len) ++{ ++ pIPV6_HDR ipv6; ++ u16_t protocol; ++ ++ if (!ipv6_context->ustack) { ++ LOG_WARN("ipv6 rx pkt ipv6_context=%p ustack=%p", ipv6_context, ++ ipv6_context->ustack); ++ return; ++ } ++ ipv6 = (pIPV6_HDR) ipv6_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(ipv6_context); ++ break; ++ ++ case IPPROTO_UDP: ++ /* Indicate to UDP processing code */ ++ ipv6_udp_rx(ipv6_context); ++ break; ++ ++ default: ++ break; ++ } ++} ++ ++void ipv6_mc_init_dest_mac(pETH_HDR eth, pIPV6_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[0] = 0x33; ++ eth->dest_mac[1] = 0x33; ++ for (i = 0; i < 4; i++) ++ eth->dest_mac[2 + i] = ipv6->ipv6_dst.addr8[12 + i]; ++} ++ ++int ipv6_autoconfig(pIPV6_CONTEXT ipv6_context) ++{ ++ return ipv6_discover_address(ipv6_context); ++} ++ ++int ipv6_discover_address(pIPV6_CONTEXT ipv6_context) ++{ ++ pETH_HDR eth = (pETH_HDR) ipv6_context->ustack->data_link_layer; ++ pIPV6_HDR ipv6 = (pIPV6_HDR) ipv6_context->ustack->network_layer; ++ pICMPV6_HDR icmp = (pICMPV6_HDR) ((u8_t *) ipv6 + sizeof(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 __FAR__ *)&ipv6->ipv6_dst, 0, sizeof(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(ipv6_context, ++ (pICMPV6_OPT_LINK_ADDR) ((u8_t *) icmp + ++ sizeof(ICMPV6_HDR)), ++ IPV6_ICMP_OPTION_SRC_ADDR); ++ ipv6->ipv6_plen = ++ HOST_TO_NET16((sizeof(ICMPV6_HDR) + sizeof(ICMPV6_OPT_LINK_ADDR))); ++ memcpy((char __FAR__ *)&ipv6->ipv6_src, ++ (char __FAR__ *)&ipv6_context->link_local_addr, ++ sizeof(IPV6_ADDR)); ++ ++ icmp->icmpv6_cksum = 0; ++ LOG_DEBUG("IPV6: Send rtr sol"); ++ ipv6_send(ipv6_context, (u8_t *) icmp - (u8_t *) eth + ++ sizeof(ICMPV6_HDR) + sizeof(ICMPV6_OPT_LINK_ADDR)); ++ return rc; ++} ++ ++u16_t ipv6_process_rx(pIPV6_HDR ipv6) ++{ ++ return ipv6->ipv6_nxt_hdr; ++} ++ ++int ipv6_send(pIPV6_CONTEXT ipv6_context, u16_t packet_len) ++{ ++ pETH_HDR eth = (pETH_HDR) ipv6_context->ustack->data_link_layer; ++ pIPV6_HDR ipv6 = (pIPV6_HDR) ipv6_context->ustack->network_layer; ++ ++ ipv6_setup_hdrs(ipv6_context, eth, ipv6, packet_len); ++ ++ return iscsiL2Send(ipv6_context, packet_len); ++} ++ ++void ipv6_send_udp_packet(pIPV6_CONTEXT ipv6_context, u16_t packet_len) ++{ ++ pETH_HDR eth = (pETH_HDR) ipv6_context->ustack->data_link_layer; ++ pIPV6_HDR ipv6 = (pIPV6_HDR) ipv6_context->ustack->network_layer; ++ pUDP_HDR udp = (pUDP_HDR) ((u8_t *) ipv6 + sizeof(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(ipv6_context, packet_len); ++} ++ ++void ipv6_setup_hdrs(pIPV6_CONTEXT ipv6_context, pETH_HDR eth, pIPV6_HDR ipv6, ++ u16_t packet_len) ++{ ++ pIPV6_ADDR our_address; ++ ++ /* VLAN will be taken cared of in the nic layer */ ++ eth->len_type = HOST_TO_NET16(LAYER2_TYPE_IPV6); ++ memcpy((char __FAR__ *)ð->src_mac, ++ (char __FAR__ *)&ipv6_context->mac_addr, sizeof(MAC_ADDR)); ++ ++ /* 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 = ipv6_context->hop_limit; ++ ++ if (ipv6->ipv6_src.addr[0] == 0) { ++ /* Need to initialize source IP address. */ ++ if ((our_address = ipv6_our_address(ipv6_context)) != NULL) { ++ /* Assume that caller has filled in the destination ++ IP address */ ++ memcpy((char __FAR__ *)&ipv6->ipv6_src, ++ (char __FAR__ *)our_address, sizeof(IPV6_ADDR)); ++ } ++ } ++ ++ ipv6_insert_protocol_chksum(ipv6); ++} ++ ++STATIC void ipv6_insert_protocol_chksum(pIPV6_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; ++ ++ for (i = 0; i < sizeof(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 */ ++ ((pICMPV6_HDR) (protocol_data_ptr))->icmpv6_cksum = checksum; ++ break; ++ case IPPROTO_UDP: ++ /* Insert correct UDP checksum */ ++ ((pUDP_HDR) protocol_data_ptr)->chksum = checksum; ++ break; ++ default: ++ break; ++ } ++} ++ ++int ipv6_is_it_our_link_local_address(pIPV6_CONTEXT ipv6_context, ++ IPV6_ADDR __FAR__ * ipv6_addr) ++{ ++ u8_t *test_adddr = (u8_t *) ipv6_addr->addr8; ++ u8_t test_remainder; ++ ++ if (test_adddr[0] != ipv6_context->link_local_addr.addr8[0]) ++ return FALSE; ++ ++ test_remainder = (test_adddr[1] & 0xC0) >> 6; ++ if (test_remainder != 2) ++ return FALSE; ++ ++ return TRUE; ++} ++ ++STATIC int ipv6_is_it_our_address(pIPV6_CONTEXT ipv6_context, ++ IPV6_ADDR __FAR__ * ipv6_addr) ++{ ++ pIPV6_PREFIX_ENTRY ipv6_prefix; ++ ++ for (ipv6_prefix = ipv6_context->addr_list; ipv6_prefix != NULL; ++ ipv6_prefix = ipv6_prefix->next) { ++ if (IPV6_ARE_ADDR_EQUAL(&ipv6_prefix->address, ipv6_addr)) ++ return TRUE; ++ } ++ ++ return FALSE; ++} ++ ++pIPV6_ADDR ipv6_our_address(pIPV6_CONTEXT ipv6_context) ++{ ++ return &ipv6_context->link_local_addr; ++} ++ ++int ipv6_ip_in_arp_table(pIPV6_CONTEXT ipv6_context, pIPV6_ADDR ipv6_addr, ++ MAC_ADDR * mac_addr) ++{ ++ pIPV6_ARP_ENTRY arp_entry; ++ int i; ++ ++ for (i = 0; i < UIP_ARPTAB_SIZE; i++) { ++ arp_entry = &ipv6_context->ipv6_arp_table[i]; ++ ++ if (IPV6_ARE_ADDR_EQUAL(&arp_entry->ip_addr, ipv6_addr)) { ++ memcpy((char *)mac_addr, &arp_entry->mac_addr, ++ sizeof(MAC_ADDR)); ++ return 1; ++ } ++ } ++ return 0; ++} ++ ++pIPV6_ADDR ipv6_find_longest_match(pIPV6_CONTEXT ipv6_context, ++ pIPV6_ADDR ip_addr) ++{ ++ pIPV6_PREFIX_ENTRY ipv6_prefix; ++ pIPV6_PREFIX_ENTRY best_match = NULL; ++ int longest_len = -1; ++ int len; ++ ++ for (ipv6_prefix = ipv6_context->addr_list; ipv6_prefix != NULL; ++ ipv6_prefix = ipv6_prefix->next) { ++ if (!IPV6_IS_ADDR_LINKLOCAL(&ipv6_prefix->address)) { ++ len = best_match_bufcmp((u8_t *) & ipv6_prefix->address, ++ (u8_t *) ip_addr, ++ sizeof(IPV6_ADDR)); ++ if (len > longest_len) { ++ best_match = ipv6_prefix; ++ longest_len = len; ++ } ++ } ++ } ++ ++ if (best_match) ++ return &best_match->address; ++ ++ return NULL; ++} ++ ++void ipv6_arp_out(pIPV6_CONTEXT ipv6_context, int *uip_len) ++{ ++ /* Empty routine */ ++} ++ ++ ++STATIC void ipv6_update_arp_table(pIPV6_CONTEXT ipv6_context, ++ IPV6_ADDR __FAR__ * ip_addr, ++ MAC_ADDR __FAR__ * mac_addr) ++{ ++ pIPV6_ARP_ENTRY arp_entry; ++ int i; ++ pIPV6_ARP_ENTRY ipv6_arp_table = ipv6_context->ipv6_arp_table; ++ ++ LOG_DEBUG("IPV6: ARP 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 __FAR__ *)&arp_entry->mac_addr, ++ (char __FAR__ *)mac_addr, ++ sizeof(MAC_ADDR)); ++ arp_entry->time = ipv6_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 __FAR__ *)&arp_entry->ip_addr, (char __FAR__ *)ip_addr, ++ sizeof(IPV6_ADDR)); ++ memcpy((char __FAR__ *)&arp_entry->mac_addr, ++ (char __FAR__ *)mac_addr, sizeof(MAC_ADDR)); ++ ++ arp_entry->time = ipv6_context->arptime; ++} ++ ++/* DestIP is intact */ ++int ipv6_send_nd_solicited_packet(pIPV6_CONTEXT ipv6_context, pETH_HDR eth, ++ pIPV6_HDR ipv6) ++{ ++ pICMPV6_HDR icmp; ++ int pkt_len = 0; ++ pIPV6_ADDR longest_match_addr; ++ ++ 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(ipv6_context, &ipv6->ipv6_dst) == ++ TRUE) { ++ LOG_DEBUG("IPV6: NS using link local"); ++ memcpy((char __FAR__ *)&ipv6->ipv6_src, ++ (char __FAR__ *)&ipv6_context->link_local_addr, ++ sizeof(IPV6_ADDR)); ++ } else { ++ longest_match_addr = ++ ipv6_find_longest_match(ipv6_context, &ipv6->ipv6_dst); ++ if (longest_match_addr) { ++ LOG_DEBUG("IPV6: NS using longest match addr"); ++ memcpy((char __FAR__ *)&ipv6->ipv6_src, ++ (char __FAR__ *)longest_match_addr, ++ sizeof(IPV6_ADDR)); ++ } else { ++ LOG_DEBUG("IPV6: NS using link local instead"); ++ memcpy((char __FAR__ *)&ipv6->ipv6_src, ++ (char __FAR__ *)&ipv6_context->link_local_addr, ++ sizeof(IPV6_ADDR)); ++ } ++ } ++ icmp = (pICMPV6_HDR) ((u8_t *) ipv6 + sizeof(IPV6_HDR)); ++ ++ LOG_DEBUG ++ ("IPV6: NS host ip addr %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x" ++ " %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", ++ ipv6->ipv6_src.addr8[0], ipv6->ipv6_src.addr8[1], ++ ipv6->ipv6_src.addr8[2], ipv6->ipv6_src.addr8[3], ++ ipv6->ipv6_src.addr8[4], ipv6->ipv6_src.addr8[5], ++ ipv6->ipv6_src.addr8[6], ipv6->ipv6_src.addr8[7], ++ ipv6->ipv6_src.addr8[8], ipv6->ipv6_src.addr8[9], ++ ipv6->ipv6_src.addr8[10], ipv6->ipv6_src.addr8[11], ++ ipv6->ipv6_src.addr8[12], ipv6->ipv6_src.addr8[13], ++ ipv6->ipv6_src.addr8[14], ipv6->ipv6_src.addr8[15]); ++ /* ++ * Destination IP address to be resolved is after the ICMPv6 ++ * header. ++ */ ++ memcpy((char __FAR__ *)((u8_t *) icmp + sizeof(ICMPV6_HDR)), ++ (char __FAR__ *)&ipv6->ipv6_dst, sizeof(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 __FAR__ *)&ipv6->ipv6_dst, 0, sizeof(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(ipv6_context, ++ (pICMPV6_OPT_LINK_ADDR) ((u8_t *) icmp + ++ sizeof(ICMPV6_HDR) + ++ sizeof(IPV6_ADDR)), ++ IPV6_ICMP_OPTION_SRC_ADDR); ++ ipv6->ipv6_plen = ++ HOST_TO_NET16((sizeof(ICMPV6_HDR) + sizeof(ICMPV6_OPT_LINK_ADDR) + ++ sizeof(IPV6_ADDR))); ++ /* Total packet size */ ++ pkt_len = (u8_t *) icmp - (u8_t *) eth + ++ sizeof(ICMPV6_HDR) + ++ sizeof(ICMPV6_OPT_LINK_ADDR) + sizeof(IPV6_ADDR); ++ ipv6_setup_hdrs(ipv6_context, eth, ipv6, pkt_len); ++ return pkt_len; ++} ++ ++STATIC void ipv6_icmp_init_link_option(pIPV6_CONTEXT ipv6_context, ++ pICMPV6_OPT_LINK_ADDR link_opt, ++ u8_t type) ++{ ++ link_opt->hdr.type = type; ++ link_opt->hdr.len = sizeof(ICMPV6_OPT_LINK_ADDR) / 8; ++ memcpy((char __FAR__ *)&link_opt->link_addr, ++ (char __FAR__ *)&ipv6_context->mac_addr, sizeof(MAC_ADDRESS)); ++} ++ ++STATIC void ipv6_icmp_rx(pIPV6_CONTEXT ipv6_context) ++{ ++ pIPV6_HDR ipv6 = (pIPV6_HDR) ipv6_context->ustack->network_layer; ++ pICMPV6_HDR icmp = (pICMPV6_HDR) ((u8_t *) ipv6 + sizeof(IPV6_HDR)); ++ ++ switch (icmp->icmpv6_type) { ++ case ICMPV6_RTR_ADV: ++ ipv6_icmp_handle_router_adv(ipv6_context); ++ break; ++ ++ case ICMPV6_NEIGH_SOL: ++ ipv6_icmp_handle_nd_sol(ipv6_context); ++ break; ++ ++ case ICMPV6_NEIGH_ADV: ++ ipv6_icmp_handle_nd_adv(ipv6_context); ++ break; ++ ++ case ICMPV6_ECHO_REQUEST: ++ /* Response with ICMP reply */ ++ ipv6_icmp_handle_echo_request(ipv6_context); ++ break; ++ ++ default: ++ break; ++ } ++} ++ ++STATIC void ipv6_icmp_handle_router_adv(pIPV6_CONTEXT ipv6_context) ++{ ++ pIPV6_HDR ipv6 = (pIPV6_HDR) ipv6_context->ustack->network_layer; ++ pICMPV6_ROUTER_ADVERT icmp = ++ (pICMPV6_ROUTER_ADVERT) ((u8_t *) ipv6 + sizeof(IPV6_HDR)); ++ pICMPV6_OPT_HDR icmp_opt; ++ u16_t opt_len; ++ u16_t len; ++ ++ if (ipv6_context->flags & IPV6_FLAGS_ROUTER_ADV_RECEIVED) ++ return; ++ ++ opt_len = HOST_TO_NET16(ipv6->ipv6_plen) - sizeof(ICMPV6_ROUTER_ADVERT); ++ ++ icmp_opt = (pICMPV6_OPT_HDR) ((u8_t __FAR__ *) icmp + ++ sizeof(ICMPV6_ROUTER_ADVERT)); ++ len = 0; ++ while (len < opt_len) { ++ icmp_opt = (pICMPV6_OPT_HDR) ((u8_t __FAR__ *) icmp + ++ sizeof(ICMPV6_ROUTER_ADVERT) + ++ len); ++ ++ switch (icmp_opt->type) { ++ case IPV6_ICMP_OPTION_PREFIX: ++ ipv6_icmp_process_prefix(ipv6_context, ++ (pICMPV6_OPT_PREFIX) icmp_opt); ++ ipv6_context->flags |= IPV6_FLAGS_ROUTER_ADV_RECEIVED; ++ break; ++ ++ default: ++ break; ++ } ++ ++ len += icmp_opt->len * 8; ++ } ++ ++ if (ipv6_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) ++ ipv6_context->hop_limit = icmp->nd_ra_curhoplimit; ++ ++ if (icmp->nd_ra_flags_reserved & IPV6_RA_MANAGED_FLAG) ++ ipv6_context->flags |= IPV6_FLAGS_MANAGED_ADDR_CONFIG; ++ ++ if (icmp->nd_ra_flags_reserved & IPV6_RA_CONFIG_FLAG) ++ ipv6_context->flags |= IPV6_FLAGS_OTHER_STATEFUL_CONFIG; ++ ++ if (icmp->nd_ra_router_lifetime != 0) { ++ /* This is a default router. */ ++ memcpy((char __FAR__ *)&ipv6_context->default_router, ++ (char __FAR__ *)&ipv6->ipv6_src, ++ sizeof(IPV6_ADDR)); ++ LOG_DEBUG("IPV6: def router " ++ "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x " ++ "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", ++ ipv6->ipv6_src.addr8[0], ipv6->ipv6_src.addr8[1], ++ ipv6->ipv6_src.addr8[2], ipv6->ipv6_src.addr8[3], ++ ipv6->ipv6_src.addr8[4], ipv6->ipv6_src.addr8[5], ++ ipv6->ipv6_src.addr8[6], ipv6->ipv6_src.addr8[7], ++ ipv6->ipv6_src.addr8[8], ipv6->ipv6_src.addr8[9], ++ ipv6->ipv6_src.addr8[10], ipv6->ipv6_src.addr8[11], ++ ipv6->ipv6_src.addr8[12], ipv6->ipv6_src.addr8[13], ++ ipv6->ipv6_src.addr8[14], ipv6->ipv6_src.addr8[15]); ++ } ++ } ++} ++ ++STATIC void ipv6_icmp_process_prefix(pIPV6_CONTEXT ipv6_context, ++ pICMPV6_OPT_PREFIX icmp_prefix) ++{ ++ IPV6_ADDR addr; ++ ++ /* 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 __FAR__ *)&addr, ++ (char __FAR__ *)&icmp_prefix->prefix, 8); ++ memcpy((char __FAR__ *)&addr.addr8[8], ++ &ipv6_context->link_local_addr.addr8[8], 8); ++ ipv6_add_prefix_entry(ipv6_context, &addr, 64); ++ } ++} ++ ++STATIC void ipv6_icmp_handle_nd_adv(pIPV6_CONTEXT ipv6_context) ++{ ++ pETH_HDR eth = (pETH_HDR) ipv6_context->ustack->data_link_layer; ++ pIPV6_HDR ipv6 = (pIPV6_HDR) ipv6_context->ustack->network_layer; ++ pICMPV6_HDR icmp = (pICMPV6_HDR) ((u8_t *) ipv6 + sizeof(IPV6_HDR)); ++ pICMPV6_OPT_LINK_ADDR link_opt = (pICMPV6_OPT_LINK_ADDR)((u8_t *)icmp + ++ sizeof(ICMPV6_HDR) + sizeof(IPV6_ADDR)); ++ pIPV6_ADDR tar_addr6; ++ ++ /* 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(ipv6_context, &ipv6->ipv6_dst) == TRUE) || ++ (memcmp((char __FAR__ *)&ipv6_context->link_local_multi, ++ (char __FAR__ *)&ipv6->ipv6_dst, sizeof(IPV6_ADDR)) == 0) || ++ (memcmp((char __FAR__ *)&ipv6_context->multi, ++ (char __FAR__ *)&ipv6->ipv6_dst, sizeof(IPV6_ADDR)) == 0)) { ++ /* ++ * This is an ARP reply for our addresses. Let's update the ++ * ARP table. ++ */ ++ ipv6_update_arp_table(ipv6_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 = (pIPV6_ADDR)((u8_t *)icmp + ++ sizeof(ICMPV6_HDR)); ++ LOG_DEBUG("IPV6: tar mac %x:%x:%x:%x:%x:%x", ++ link_opt->link_addr[0], link_opt->link_addr[1], ++ link_opt->link_addr[2], link_opt->link_addr[3], ++ link_opt->link_addr[4], link_opt->link_addr[5]); ++ LOG_DEBUG("IPV6: tar addr " ++ "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x " ++ "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", ++ tar_addr6->addr8[0], tar_addr6->addr8[1], ++ tar_addr6->addr8[2], tar_addr6->addr8[3], ++ tar_addr6->addr8[4], tar_addr6->addr8[5], ++ tar_addr6->addr8[6], tar_addr6->addr8[7], ++ tar_addr6->addr8[8], tar_addr6->addr8[9], ++ tar_addr6->addr8[10], tar_addr6->addr8[11], ++ tar_addr6->addr8[12], tar_addr6->addr8[13], ++ tar_addr6->addr8[14], tar_addr6->addr8[15]); ++ ipv6_update_arp_table(ipv6_context, tar_addr6, ++ (MAC_ADDR *)link_opt->link_addr); ++ } ++ ++ } ++} ++ ++STATIC void ipv6_icmp_handle_nd_sol(pIPV6_CONTEXT ipv6_context) ++{ ++ pETH_HDR eth = (pETH_HDR) ipv6_context->ustack->data_link_layer; ++ pIPV6_HDR ipv6 = (pIPV6_HDR) ipv6_context->ustack->network_layer; ++ pICMPV6_HDR icmp = (pICMPV6_HDR) ((u8_t *) ipv6 + sizeof(IPV6_HDR)); ++ pICMPV6_OPT_LINK_ADDR link_opt = (pICMPV6_OPT_LINK_ADDR)((u8_t *)icmp + ++ sizeof(ICMPV6_HDR) + sizeof(IPV6_ADDR)); ++ int icmpv6_opt_len = 0; ++ IPV6_ADDR tmp; ++ pIPV6_ADDR longest_match_addr; ++ pIPV6_ADDR tar_addr6; ++ ++ LOG_DEBUG("IPV6: Handle nd sol"); ++ ++ if ((memcmp((char __FAR__ *)&ipv6_context->mac_addr, ++ (char __FAR__ *)eth->dest_mac, sizeof(MAC_ADDR)) != 0) && ++ (iscsiL2IsOurMcAddr(ipv6_context, (pMAC_ADDRESS) & eth->dest_mac) == ++ FALSE)) { ++ /* This packet is not for us to handle */ ++ LOG_DEBUG("IPV6: MAC not addressed to us %x:%x:%x:%x:%x:%x", ++ eth->dest_mac[0], eth->dest_mac[1], ++ eth->dest_mac[2], eth->dest_mac[3], ++ eth->dest_mac[4], eth->dest_mac[5]); ++ return; ++ } ++ ++ /* Also check for the icmpv6_data before generating the reply */ ++ if (ipv6_is_it_our_address(ipv6_context, ++ (IPV6_ADDR *) ((u8_t *) icmp + ++ sizeof(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 __FAR__ *)ð->dest_mac, ++ (char __FAR__ *)ð->src_mac, sizeof(MAC_ADDR)); ++ ++ /* Dest IP contains source IP */ ++ memcpy((char __FAR__ *)&tmp, ++ (char __FAR__ *)&ipv6->ipv6_dst, sizeof(IPV6_ADDR)); ++ memcpy((char __FAR__ *)&ipv6->ipv6_dst, ++ (char __FAR__ *)&ipv6->ipv6_src, sizeof(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 = (pIPV6_ADDR)((u8_t *)icmp + sizeof(ICMPV6_HDR)); ++ if (ipv6_is_it_our_link_local_address(ipv6_context, tar_addr6) ++ == TRUE) { ++ LOG_DEBUG("IPV6: NA using link local"); ++ memcpy((char __FAR__ *)&ipv6->ipv6_src, ++ (char __FAR__ *)&ipv6_context->link_local_addr, ++ sizeof(IPV6_ADDR)); ++ } else { ++ longest_match_addr = ++ ipv6_find_longest_match(ipv6_context, tar_addr6); ++ if (longest_match_addr) { ++ LOG_DEBUG("IPV6: NA using longest match addr"); ++ memcpy((char __FAR__ *)&ipv6->ipv6_src, ++ (char __FAR__ *)longest_match_addr, ++ sizeof(IPV6_ADDR)); ++ } else { ++ LOG_DEBUG("IPV6: NA using link local instead"); ++ memcpy((char __FAR__ *)&ipv6->ipv6_src, ++ (char __FAR__ *)&ipv6_context->link_local_addr, ++ sizeof(IPV6_ADDR)); ++ } ++ } ++ } else { ++ /* No target link address, just use whatever it sent to us */ ++ LOG_DEBUG("IPV6: NA use dst addr"); ++ memcpy((char __FAR__ *)&ipv6->ipv6_src, ++ (char __FAR__ *)&tmp, ++ sizeof(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 __FAR__ *)((u8_t *) icmp + sizeof(ICMPV6_HDR)), ++ (char __FAR__ *)&ipv6->ipv6_src, ++ sizeof(IPV6_ADDR)); ++ ++ /* Add the target link address option only for all solicitation */ ++/* ++ if ((memcmp((char __FAR__ *)&ipv6_context->multi_dest, ++ (char __FAR__ *)&tmp, sizeof(IPV6_ADDR)) == 0) || ++ (memcmp((char __FAR__ *)&ipv6_context->link_local_multi, ++ (char __FAR__ *)&tmp, sizeof(IPV6_ADDR)) == 0)) { ++*/ ++ ipv6_icmp_init_link_option(ipv6_context, ++ (pICMPV6_OPT_LINK_ADDR) ((u8_t *) ++ icmp + ++ sizeof ++ (ICMPV6_HDR) ++ + ++ sizeof ++ (IPV6_ADDR)), ++ IPV6_ICMP_OPTION_TAR_ADDR); ++ icmpv6_opt_len = sizeof(ICMPV6_OPT_LINK_ADDR); ++/* ++ } ++*/ ++ ipv6->ipv6_plen = HOST_TO_NET16((sizeof(ICMPV6_HDR) + ++ icmpv6_opt_len + sizeof(IPV6_ADDR))); ++ LOG_DEBUG("IPV6: Send nd adv"); ++ ipv6_send(ipv6_context, ++ (u8_t *) icmp - (u8_t *) eth + ++ sizeof(ICMPV6_HDR) + ++ sizeof(ICMPV6_OPT_LINK_ADDR) + sizeof(IPV6_ADDR)); ++ return; ++} ++ ++STATIC void ipv6_icmp_handle_echo_request(pIPV6_CONTEXT ipv6_context) ++{ ++ pETH_HDR eth = (pETH_HDR) ipv6_context->ustack->data_link_layer; ++ pIPV6_HDR ipv6 = (pIPV6_HDR) ipv6_context->ustack->network_layer; ++ pICMPV6_HDR icmp = (pICMPV6_HDR) ((u8_t *) ipv6 + sizeof(IPV6_HDR)); ++ IPV6_ADDR temp; ++ ++ /* Copy source MAC to Destination MAC */ ++ memcpy((char __FAR__ *)ð->dest_mac, ++ (char __FAR__ *)ð->src_mac, sizeof(MAC_ADDR)); ++ ++ memcpy((char __FAR__ *)&temp, ++ (char __FAR__ *)&ipv6->ipv6_dst, sizeof(IPV6_ADDR)); ++ ++ /* Dest IP contains source IP */ ++ memcpy((char __FAR__ *)&ipv6->ipv6_dst, ++ (char __FAR__ *)&ipv6->ipv6_src, sizeof(IPV6_ADDR)); ++ /* Use Link-local as source address */ ++ memcpy((char __FAR__ *)&ipv6->ipv6_src, ++ (char __FAR__ *)&temp, sizeof(IPV6_ADDR)); ++ ++ ipv6->ipv6_hop_limit = ipv6_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(ipv6_context, (u8_t *) icmp - (u8_t *) eth + ++ sizeof(IPV6_HDR) + HOST_TO_NET16(ipv6->ipv6_plen)); ++ return; ++} ++ ++void ipv6_set_ip_params(pIPV6_CONTEXT ipv6_context, ++ pIPV6_ADDR src_ip, u8_t prefix_len, ++ pIPV6_ADDR default_gateway) ++{ ++ if (!(IPV6_IS_ADDR_UNSPECIFIED(src_ip))) { ++ ipv6_add_prefix_entry(ipv6_context, src_ip, prefix_len); ++ /* Create the multi_dest address */ ++ memset(&ipv6_context->multi_dest, 0, sizeof(IPV6_ADDR)); ++ ipv6_context->multi_dest.addr8[0] = 0xff; ++ ipv6_context->multi_dest.addr8[1] = 0x02; ++ ipv6_context->multi_dest.addr8[11] = 0x01; ++ ipv6_context->multi_dest.addr8[12] = 0xff; ++ ipv6_context->multi_dest.addr8[13] = src_ip->addr8[13]; ++ ipv6_context->multi_dest.addr16[7] = src_ip->addr16[7]; ++ /* Create the multi address */ ++ memset(&ipv6_context->multi, 0, sizeof(IPV6_ADDR)); ++ ipv6_context->multi.addr8[0] = 0xfc; ++ ipv6_context->multi.addr8[2] = 0x02; ++ ipv6_context->multi.addr16[7] = src_ip->addr16[7]; ++ } ++ ++ if (!(IPV6_IS_ADDR_UNSPECIFIED(default_gateway))) { ++ /* This is a default router. */ ++ memcpy((char __FAR__ *)&ipv6_context->default_router, ++ (char __FAR__ *)default_gateway, sizeof(IPV6_ADDR)); ++ } ++} ++ ++int ipv6_get_source_ip_addrs(pIPV6_CONTEXT ipv6_context, ++ pIPV6_ADDR_ENTRY addr_list) ++{ ++ pIPV6_PREFIX_ENTRY ipv6_prefix; ++ int i; ++ ++ for (i = 0, ipv6_prefix = ipv6_context->addr_list; ipv6_prefix != NULL; ++ ipv6_prefix = ipv6_prefix->next) { ++ memcpy((char __FAR__ *)&addr_list->address, ++ (char __FAR__ *)&ipv6_prefix->address, ++ sizeof(IPV6_ADDR)); ++ addr_list->prefix_len = ipv6_prefix->prefix_len * 8; ++ ++ i++; ++ addr_list++; ++ } ++ ++ return i; ++} ++ ++int ipv6_get_default_router_ip_addrs(pIPV6_CONTEXT ipv6_context, ++ pIPV6_ADDR ip_addr) ++{ ++ /* This is a default router. */ ++ memcpy((char __FAR__ *)ip_addr, ++ (char __FAR__ *)&ipv6_context->default_router, ++ sizeof(IPV6_ADDR)); ++ ++ return 1; ++} ++ ++STATIC void ipv6_udp_rx(pIPV6_CONTEXT ipv6_context) ++{ ++ pETH_HDR eth = (pETH_HDR) ipv6_context->ustack->data_link_layer; ++ pIPV6_HDR ipv6 = (pIPV6_HDR) ipv6_context->ustack->network_layer; ++ UDP_HDR __FAR__ *udp = (pUDP_HDR) ((u8_t *) ipv6 + sizeof(IPV6_HDR)); ++ pDHCPV6_CONTEXT dhcpv6c; ++ ++ /* ++ * We only care about DHCPv6 packets from the DHCPv6 server. We drop ++ * all others. ++ */ ++ if (!(ipv6_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 = ipv6_context->dhcpv6_context; ++ dhcpv6c->eth = eth; ++ dhcpv6c->ipv6 = ipv6; ++ dhcpv6c->udp = udp; ++ ipv6_udp_handle_dhcp(dhcpv6c); ++ } ++ } ++} ++ ++MAC_ADDRESS *ipv6_get_link_addr(pIPV6_CONTEXT ipv6_context) ++{ ++ return &ipv6_context->mac_addr; ++} ++ ++u16_t ipv6_do_stateful_dhcpv6(pIPV6_CONTEXT ipv6_context, u32_t flags) ++{ ++ u16_t task = 0; ++ u16_t ra_flags; ++ ++ ra_flags = ipv6_context->flags & ++ (IPV6_FLAGS_MANAGED_ADDR_CONFIG | IPV6_FLAGS_OTHER_STATEFUL_CONFIG); ++ ++ if (!(ipv6_context->flags & IPV6_FLAGS_ROUTER_ADV_RECEIVED)) { ++ LOG_DEBUG("IPV6: There is no IPv6 router on the network"); ++ 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(pIPV6_CONTEXT ipv6_context, pIPV6_ADDR ip_addr) ++{ ++ 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(ipv6_context, (MAC_ADDR *) & mac_addr); ++} ++ ++void ipv6_cfg_link_local_addr(pIPV6_CONTEXT ipv6_context, pIPV6_ADDR ip_addr) ++{ ++ memcpy((char __FAR__ *)&ipv6_context->link_local_addr, ++ (char __FAR__ *)ip_addr, sizeof(IPV6_ADDR)); ++} ++ ++void ipv6_disable_dhcpv6(pIPV6_CONTEXT ipv6_context) ++{ ++ ipv6_context->flags |= IPV6_FLAGS_DISABLE_DHCPV6; ++} +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/ipv6.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/ipv6.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/ipv6.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/ipv6.h 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,366 @@ ++/* ++ * Copyright (c) 2011, Broadcom 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 PACK_DATA_STRUCTURE 1 ++ ++#ifdef PACK_DATA_STRUCTURE ++#pragma pack(push,1) ++#endif ++ ++#define STATIC static ++ ++#define __FAR__ ++#define FALSE 0 ++#define TRUE 1 ++ ++#ifdef ROM_DRIVER ++#define memcpy imemcpy ++#define memset imemset ++#define memcmp istrncmp ++#define system_get_ticks iscsiGetTicks ++#endif ++ ++#define LINK_LOCAL_PREFIX_LENGTH 2 ++#define LAYER2_HEADER_LENGTH 14 ++#define LAYER2_VLAN_HEADER_LENGTH 16 ++#define LAYER2_TYPE_IPV6 0x86dd ++ ++typedef struct IPV6_ADDR { ++ union { ++ u8_t addr8[16]; ++ u16_t addr16[8]; ++ u32_t addr[4]; ++ }; ++} IPV6_ADDR, *pIPV6_ADDR; ++ ++typedef struct UDP_HDR { ++ u16_t src_port; ++ u16_t dest_port; ++ u16_t length; ++ u16_t chksum; ++} UDP_HDR, *pUDP_HDR; ++ ++typedef struct MAC_ADDRESS { ++ u8_t addr[6]; ++} MAC_ADDRESS, *pMAC_ADDRESS; ++ ++typedef u8_t MAC_ADDR[6]; ++ ++#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 __FAR__ *)a,(char __FAR__ *)b,sizeof(IPV6_ADDR)) == 0) ++ ++/* Unspecified IPv6 address */ ++#define IPV6_IS_ADDR_UNSPECIFIED(a) \ ++ ((*(u32_t *)(&(a)->addr8[0]) == 0) && \ ++ (*(u32_t *)(&(a)->addr8[4]) == 0) && \ ++ (*(u32_t *)(&(a)->addr8[8]) == 0) && \ ++ (*(u32_t *)(&(a)->addr8[12]) == 0)) ++ ++/* Loopback IPv6 address */ ++#define IPV6_IS_ADDR_LOOPBACK(a) \ ++ ((*(u32_t *)(&(a)->addr8[0]) == 0) && \ ++ (*(u32_t *)(&(a)->addr8[4]) == 0) && \ ++ (*(u32_t *)(&(a)->addr8[8]) == 0) && \ ++ (*(u32_t *)(&(a)->addr8[12]) == 0x1)) ++ ++/* IPv4 compatible */ ++#define IPV6_IS_ADDR_IPV4_COMPAT(a) \ ++ ((*(u32_t *)(&(a)->addr8[0]) == 0) && \ ++ (*(u32_t *)(&(a)->addr8[4]) == 0) && \ ++ (*(u32_t *)(&(a)->addr8[8]) == 0) && \ ++ (*(u32_t *)(&(a)->addr8[12]) != 0) && \ ++ (*(u32_t *)(&(a)->addr8[12]) != 0x1)) ++ ++/* Mapped IPv4-IPv6 address */ ++#define IPV6_IS_ADDR_IPV4_MAPPED(a) \ ++ ((*(u32_t *)(&(a)->addr8[0]) == 0) && \ ++ (*(u32_t *)(&(a)->addr8[4]) == 0) && \ ++ (*(u32_t *)(&(a)->addr8[8]) == ntohl(0x0000ffff))) ++ ++/* 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 */ ++ ++typedef struct ETH_HDR { ++ MAC_ADDR dest_mac; ++ MAC_ADDR src_mac; ++ u16_t len_type; ++} ETH_HDR, *pETH_HDR; ++ ++typedef 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; ++ ++ IPV6_ADDR ipv6_src; /* Source address */ ++ IPV6_ADDR ipv6_dst; /* Destination address */ ++} IPV6_HDR, *pIPV6_HDR; ++ ++#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(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 ++ ++typedef struct PACKET_IPV6 { ++ MAC_ADDR dest_mac; ++ MAC_ADDR src_mac; ++ u16_t len_type; ++ IPV6_HDR ip; ++ union { ++ UDP_HDR udp; ++ } layer4_prot; ++} PACKET_IPV6, *pPACKET_IPV6; ++ ++typedef struct PACKET_IPV6_VLAN { ++ MAC_ADDR dest_mac; ++ MAC_ADDR src_mac; ++ u16_t len_type; ++ u16_t vlan_id; ++ IPV6_HDR ip; ++ union { ++ UDP_HDR udp; ++ } layer4_prot; ++} PACKET_IPV6_VLAN, *pPACKET_IPV6_VLAN; ++ ++#ifdef PACK_DATA_STRUCTURE ++#pragma pack(pop) ++#endif ++ ++typedef struct IPV6_ARP_ENTRY { ++ IPV6_ADDR ip_addr; ++ MAC_ADDR mac_addr; ++ u8_t time; ++} IPV6_ARP_ENTRY, *pIPV6_ARP_ENTRY; ++ ++#define IPV6_NUM_OF_ADDRESS_ENTRY 4 ++ ++typedef struct _IPV6_PREFIX_ENTRY { ++ struct _IPV6_PREFIX_ENTRY *next; ++ IPV6_ADDR address; ++ u8_t prefix_len; ++} IPV6_PREFIX_ENTRY, *pIPV6_PREFIX_ENTRY; ++ ++typedef struct IPV6_ADDR_ENTRY { ++ IPV6_ADDR address; ++ u8_t prefix_len; ++} IPV6_ADDR_ENTRY, *pIPV6_ADDR_ENTRY; ++ ++typedef 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) ++ ++ MAC_ADDRESS mac_addr; ++ IPV6_ADDR link_local_addr; ++ IPV6_ADDR link_local_multi; ++ IPV6_ADDR multi; /* For Static IPv6 only */ ++ IPV6_ADDR multi_dest; /* For Static IPv6 only */ ++ IPV6_ADDR default_router; ++ pIPV6_PREFIX_ENTRY addr_list; ++ u8_t hop_limit; ++#define UIP_ARPTAB_SIZE 8 ++ ++ struct uip_stack *ustack; ++#define MAX_MCADDR_TABLE 5 ++ MAC_ADDR mc_addr[MAX_MCADDR_TABLE]; ++ u8_t arptime; ++ IPV6_ARP_ENTRY ipv6_arp_table[UIP_ARPTAB_SIZE]; ++ IPV6_PREFIX_ENTRY ipv6_prefix_table[IPV6_NUM_OF_ADDRESS_ENTRY]; ++ ++ /* VLAN support */ ++ ++ void *dhcpv6_context; ++ ++} IPV6_CONTEXT, *pIPV6_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(pIPV6_CONTEXT ipv6_context); ++int ipv6_discover_address(pIPV6_CONTEXT ipv6_context); ++pIPV6_ADDR ipv6_our_address(pIPV6_CONTEXT ipv6_context); ++int ipv6_ip_in_arp_table(pIPV6_CONTEXT ipv6_context, pIPV6_ADDR ipv6_addr, ++ MAC_ADDR * mac_addr); ++void ipv6_arp_timer(pIPV6_CONTEXT ipv6_context); ++void ipv6_arp_out(pIPV6_CONTEXT ipv6_context, int *uip_len); ++int ipv6_add_prefix_entry(pIPV6_CONTEXT ipv6_context, ++ IPV6_ADDR * ipv6_addr, u8_t prefix_len); ++void ipv6_set_ip_params(pIPV6_CONTEXT ipv6_context, ++ pIPV6_ADDR src_ip, u8_t prefix_len, ++ pIPV6_ADDR default_gateway); ++void ipv6_set_host_addr(pIPV6_CONTEXT ipv6_context, pIPV6_ADDR src_ip); ++int ipv6_get_default_router_ip_addrs(pIPV6_CONTEXT ipv6_context, ++ pIPV6_ADDR ip_addr); ++MAC_ADDRESS *ipv6_get_link_addr(pIPV6_CONTEXT ipv6_context); ++u16_t ipv6_do_stateful_dhcpv6(pIPV6_CONTEXT ipv6_context, u32_t flags); ++void ipv6_add_solit_node_address(pIPV6_CONTEXT ipv6_context, ++ pIPV6_ADDR ip_addr); ++int ipv6_get_source_ip_addrs(pIPV6_CONTEXT ipv6_context, ++ pIPV6_ADDR_ENTRY addr_list); ++void ipv6_cfg_link_local_addr(pIPV6_CONTEXT ipv6_context, pIPV6_ADDR ip_addr); ++void ipv6_disable_dhcpv6(pIPV6_CONTEXT ipv6_context); ++int ipv6_send_nd_solicited_packet(pIPV6_CONTEXT ipv6_context, pETH_HDR eth, ++ pIPV6_HDR ipv6); ++int ipv6_is_it_our_link_local_address(pIPV6_CONTEXT ipv6_context, ++ IPV6_ADDR __FAR__ * ipv6_addr); ++void ipv6_mc_init_dest_mac(pETH_HDR eth, pIPV6_HDR ipv6); ++pIPV6_ADDR ipv6_find_longest_match(pIPV6_CONTEXT ipv6_context, ++ pIPV6_ADDR ip_addr); ++ ++#endif /* __IPV6_H__ */ +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/ipv6_ndpc.c open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/ipv6_ndpc.c +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/ipv6_ndpc.c 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/ipv6_ndpc.c 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,408 @@ ++/* ++ * Copyright (c) 2011, Broadcom 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; ++ pIPV6_CONTEXT ipv6c; ++ pDHCPV6_CONTEXT dhcpv6c = NULL; ++ u16_t task = 0; ++ ++ 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; ++ ++ 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); ++ ++no_rtr_adv: ++ s->state = NDPC_STATE_RTR_ADV; ++ ++rtr_adv: ++ /* Both Static IPv6 and DHCPv6 comes here */ ++ ++ task = ipv6_do_stateful_dhcpv6(ipv6c, ISCSI_FLAGS_DHCP_TCPIP_CONFIG); ++ if (task && (ustack->ip_config == IPV6_CONFIG_DHCP)) { ++ /* 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 */ ++ //PT_RESTART(&s->pt); ++ 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) { ++ LOG_DEBUG("%s: ndpc_handle DHCP failed", ++ s->nic->log_name); ++ PT_RESTART(&s->pt); ++ } ++ IPV6_ADDR tmp, tmp2; ++ char buf[INET6_ADDRSTRLEN]; ++ ++ ipv6_disable_dhcpv6(ipv6c); ++ memcpy(&tmp.addr8, &ustack->hostaddr6, sizeof(IPV6_ADDR)); ++ LOG_DEBUG("%s: host ip addr %02x:%02x:%02x:%02x:%02x:%02x:" ++ "%02x:%02x", s->nic->log_name, ++ ustack->hostaddr6[0], ustack->hostaddr6[1], ++ ustack->hostaddr6[2], ustack->hostaddr6[3], ++ ustack->hostaddr6[4], ustack->hostaddr6[5], ++ ustack->hostaddr6[6], ustack->hostaddr6[7]); ++ memset(&tmp2, 0, sizeof(tmp2)); ++ ipv6_set_ip_params(ipv6c, &tmp, ++ ustack->prefix_len, &tmp2); ++ ++ ipv6_add_solit_node_address(ipv6c, &tmp); ++ ++ inet_ntop(AF_INET6, &tmp.addr8, buf, sizeof(buf)); ++ LOG_INFO("%s: Static hostaddr IP: %s", s->nic->log_name, ++ buf); ++ ++ } ++ ++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) ++{ ++ pIPV6_CONTEXT ipv6c; ++ pDHCPV6_CONTEXT dhcpv6c; ++ struct ndpc_state *s = ustack->ndpc; ++ ++ 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(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(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 */ ++ } else { ++ /* Static v6 specific */ ++ } ++ ++ 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; ++ pIPV6_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; ++ } ++ //LOG_DEBUG("%s: NDP - Request %d", s->nic->log_name, request); ++ ++ while (s->state != NDPC_STATE_BACKGROUND_LOOP) { ++ LOG_DEBUG("%s: ndpc state not in background loop, run handler", ++ s->nic->log_name); ++ handle_ndp(ustack, 1); ++ } ++ ++ ipv6c = s->ipv6_context; ++ switch (request) { ++ case NEIGHBOR_SOLICIT: ++ LOG_DEBUG("nd sol: in=%p in->eth=%p in->ipv6=%p", in, in, ++ (u8_t *) in + 4); ++ *(int *)out = ipv6_send_nd_solicited_packet(ipv6c, ++ (pETH_HDR) ((pNDPC_REQPTR)in)->eth, ++ (pIPV6_HDR) ((pNDPC_REQPTR)in)->ipv6); ++ break; ++ case CHECK_LINK_LOCAL_ADDR: ++ *(int *)out = ipv6_is_it_our_link_local_address(ipv6c, ++ (pIPV6_ADDR)in); ++ break; ++ case GET_LINK_LOCAL_ADDR: ++ *(pIPV6_ADDR *) out = &ipv6c->link_local_addr; ++ break; ++ case GET_DEFAULT_ROUTER_ADDR: ++ *(pIPV6_ADDR *)out = &ipv6c->default_router; ++ break; ++ case CHECK_ARP_TABLE: ++ *(int *)out = ipv6_ip_in_arp_table(ipv6c, ++ (pIPV6_ADDR) ((pNDPC_REQPTR)in)->ipv6, ++ (MAC_ADDR *) ((pNDPC_REQPTR)in)->eth); ++ break; ++ case GET_HOST_ADDR: ++ *(pIPV6_ADDR *)out = ipv6_find_longest_match(ipv6c, ++ (pIPV6_ADDR)in); ++ default: ++ break; ++ } ++ return ret; ++} ++ ++/*---------------------------------------------------------------------------*/ +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/ipv6_ndpc.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/ipv6_ndpc.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/ipv6_ndpc.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/ipv6_ndpc.h 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,97 @@ ++/* ++ * Copyright (c) 2011, Broadcom 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" ++ ++typedef struct NDPC_REQPTR { ++ void *eth; ++ void *ipv6; ++} NDPC_REQPTR, *pNDPC_REQPTR; ++ ++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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/ipv6_pkt.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/ipv6_pkt.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/ipv6_pkt.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/ipv6_pkt.h 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,49 @@ ++/* ++ * Copyright (c) 2011, Broadcom 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(pIPV6_HDR ipv6); ++void ipv6_rx_packet(pIPV6_CONTEXT ipv6_context, u16_t len); ++void ipv6_setup_hdrs(pIPV6_CONTEXT ipv6_context, pETH_HDR eth, pIPV6_HDR ipv6, ++ u16_t packet_len); ++int ipv6_send(pIPV6_CONTEXT ipv6_context, u16_t packet_len); ++void ipv6_send_udp_packet(pIPV6_CONTEXT ipv6_context, u16_t packet_len); ++ ++#endif /* __IPV6_PKT_H__ */ +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/lc-addrlabels.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/lc-addrlabels.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/lc-addrlabels.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/lc-addrlabels.h 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,82 @@ ++/* ++ * 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 ++ * ++ * $Id: lc-addrlabels.h,v 1.3 2006/06/12 08:00:30 adam Exp $ ++ */ ++ ++/** ++ * \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 */ ++typedef void *lc_t; ++ ++#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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/lc.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/lc.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/lc.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/lc.h 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,131 @@ ++/* ++ * 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 ++ * ++ * $Id: lc.h,v 1.2 2006/06/12 08:00:30 adam Exp $ ++ */ ++ ++/** ++ * \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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/lc-switch.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/lc-switch.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/lc-switch.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/lc-switch.h 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,76 @@ ++/* ++ * 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 ++ * ++ * $Id: lc-switch.h,v 1.2 2006/06/12 08:00:30 adam Exp $ ++ */ ++ ++/** ++ * \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 */ ++typedef unsigned short lc_t; ++ ++#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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/Makefile.am open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/Makefile.am +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/Makefile.am 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/Makefile.am 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,17 @@ ++INCLUDES = -I${top_srcdir}/src/unix \ ++ -I${top_srcdir}/src/apps/dhcpc \ ++ -I${top_srcdir}/src/apps/brcm-iscsi \ ++ -I${top_srcdir}/include ++ ++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@ +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/Makefile.in open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/Makefile.in +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/Makefile.in 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/Makefile.in 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,561 @@ ++# Makefile.in generated by automake 1.9.6 from Makefile.am. ++# @configure_input@ ++ ++# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, ++# 2003, 2004, 2005 Free Software Foundation, Inc. ++# This Makefile.in is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY, to the extent permitted by law; without ++# even the implied warranty of MERCHANTABILITY or FITNESS FOR A ++# PARTICULAR PURPOSE. ++ ++@SET_MAKE@ ++ ++srcdir = @srcdir@ ++top_srcdir = @top_srcdir@ ++VPATH = @srcdir@ ++pkgdatadir = $(datadir)/@PACKAGE@ ++pkglibdir = $(libdir)/@PACKAGE@ ++pkgincludedir = $(includedir)/@PACKAGE@ ++top_builddir = ../.. ++am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd ++INSTALL = @INSTALL@ ++install_sh_DATA = $(install_sh) -c -m 644 ++install_sh_PROGRAM = $(install_sh) -c ++install_sh_SCRIPT = $(install_sh) -c ++INSTALL_HEADER = $(INSTALL_DATA) ++transform = $(program_transform_name) ++NORMAL_INSTALL = : ++PRE_INSTALL = : ++POST_INSTALL = : ++NORMAL_UNINSTALL = : ++PRE_UNINSTALL = : ++POST_UNINSTALL = : ++build_triplet = @build@ ++host_triplet = @host@ ++subdir = src/uip ++DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ++ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 ++am__aclocal_m4_deps = $(top_srcdir)/configure.ac ++am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ ++ $(ACLOCAL_M4) ++mkinstalldirs = $(install_sh) -d ++CONFIG_HEADER = $(top_builddir)/config.h ++CONFIG_CLEAN_FILES = ++LIBRARIES = $(noinst_LIBRARIES) ++ARFLAGS = cru ++lib_iscsi_uip_a_AR = $(AR) $(ARFLAGS) ++lib_iscsi_uip_a_LIBADD = ++am_lib_iscsi_uip_a_OBJECTS = lib_iscsi_uip_a-uip.$(OBJEXT) \ ++ lib_iscsi_uip_a-uip_arp.$(OBJEXT) \ ++ lib_iscsi_uip_a-psock.$(OBJEXT) \ ++ lib_iscsi_uip_a-timer.$(OBJEXT) \ ++ lib_iscsi_uip_a-uip-neighbor.$(OBJEXT) \ ++ lib_iscsi_uip_a-uip_eth.$(OBJEXT) \ ++ lib_iscsi_uip_a-ipv6_ndpc.$(OBJEXT) \ ++ lib_iscsi_uip_a-ipv6.$(OBJEXT) ++lib_iscsi_uip_a_OBJECTS = $(am_lib_iscsi_uip_a_OBJECTS) ++DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) ++depcomp = $(SHELL) $(top_srcdir)/depcomp ++am__depfiles_maybe = depfiles ++COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ ++ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) ++LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ ++ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ ++ $(AM_CFLAGS) $(CFLAGS) ++CCLD = $(CC) ++LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ ++ $(AM_LDFLAGS) $(LDFLAGS) -o $@ ++SOURCES = $(lib_iscsi_uip_a_SOURCES) ++DIST_SOURCES = $(lib_iscsi_uip_a_SOURCES) ++ETAGS = etags ++CTAGS = ctags ++DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ++ACLOCAL = @ACLOCAL@ ++AMDEP_FALSE = @AMDEP_FALSE@ ++AMDEP_TRUE = @AMDEP_TRUE@ ++AMTAR = @AMTAR@ ++AR = @AR@ ++AUTOCONF = @AUTOCONF@ ++AUTOHEADER = @AUTOHEADER@ ++AUTOMAKE = @AUTOMAKE@ ++AWK = @AWK@ ++BASH = @BASH@ ++CC = @CC@ ++CCDEPMODE = @CCDEPMODE@ ++CFLAGS = @CFLAGS@ ++CPP = @CPP@ ++CPPFLAGS = @CPPFLAGS@ ++CXX = @CXX@ ++CXXCPP = @CXXCPP@ ++CXXDEPMODE = @CXXDEPMODE@ ++CXXFLAGS = @CXXFLAGS@ ++CYGPATH_W = @CYGPATH_W@ ++DEBUG_FALSE = @DEBUG_FALSE@ ++DEBUG_TRUE = @DEBUG_TRUE@ ++DEFS = @DEFS@ ++DEPDIR = @DEPDIR@ ++ECHO = @ECHO@ ++ECHO_C = @ECHO_C@ ++ECHO_N = @ECHO_N@ ++ECHO_T = @ECHO_T@ ++EGREP = @EGREP@ ++ENDIAN = @ENDIAN@ ++EXEEXT = @EXEEXT@ ++F77 = @F77@ ++FFLAGS = @FFLAGS@ ++INSTALL_DATA = @INSTALL_DATA@ ++INSTALL_PROGRAM = @INSTALL_PROGRAM@ ++INSTALL_SCRIPT = @INSTALL_SCRIPT@ ++INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ ++LDFLAGS = @LDFLAGS@ ++LIBOBJS = @LIBOBJS@ ++LIBS = @LIBS@ ++LIBTOOL = @LIBTOOL@ ++LN_S = @LN_S@ ++LTLIBOBJS = @LTLIBOBJS@ ++MAKEINFO = @MAKEINFO@ ++OBJEXT = @OBJEXT@ ++PACKAGE = @PACKAGE@ ++PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ ++PACKAGE_NAME = @PACKAGE_NAME@ ++PACKAGE_STRING = @PACKAGE_STRING@ ++PACKAGE_TARNAME = @PACKAGE_TARNAME@ ++PACKAGE_VERSION = @PACKAGE_VERSION@ ++PATH_SEPARATOR = @PATH_SEPARATOR@ ++RANLIB = @RANLIB@ ++SED = @SED@ ++SET_MAKE = @SET_MAKE@ ++SHELL = @SHELL@ ++STRIP = @STRIP@ ++VERSION = @VERSION@ ++ac_ct_AR = @ac_ct_AR@ ++ac_ct_CC = @ac_ct_CC@ ++ac_ct_CXX = @ac_ct_CXX@ ++ac_ct_F77 = @ac_ct_F77@ ++ac_ct_RANLIB = @ac_ct_RANLIB@ ++ac_ct_STRIP = @ac_ct_STRIP@ ++am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ ++am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ ++am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ ++am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ ++am__include = @am__include@ ++am__leading_dot = @am__leading_dot@ ++am__quote = @am__quote@ ++am__tar = @am__tar@ ++am__untar = @am__untar@ ++bindir = @bindir@ ++build = @build@ ++build_alias = @build_alias@ ++build_cpu = @build_cpu@ ++build_os = @build_os@ ++build_vendor = @build_vendor@ ++datadir = @datadir@ ++exec_prefix = @exec_prefix@ ++host = @host@ ++host_alias = @host_alias@ ++host_cpu = @host_cpu@ ++host_os = @host_os@ ++host_vendor = @host_vendor@ ++includedir = @includedir@ ++infodir = @infodir@ ++install_sh = @install_sh@ ++libdir = @libdir@ ++libexecdir = @libexecdir@ ++localstatedir = @localstatedir@ ++mandir = @mandir@ ++mkdir_p = @mkdir_p@ ++oldincludedir = @oldincludedir@ ++prefix = @prefix@ ++program_transform_name = @program_transform_name@ ++sbindir = @sbindir@ ++sharedstatedir = @sharedstatedir@ ++sysconfdir = @sysconfdir@ ++target_alias = @target_alias@ ++INCLUDES = -I${top_srcdir}/src/unix \ ++ -I${top_srcdir}/src/apps/dhcpc \ ++ -I${top_srcdir}/src/apps/brcm-iscsi \ ++ -I${top_srcdir}/include ++ ++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@ ++all: all-am ++ ++.SUFFIXES: ++.SUFFIXES: .c .lo .o .obj ++$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) ++ @for dep in $?; do \ ++ case '$(am__configure_deps)' in \ ++ *$$dep*) \ ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ ++ && exit 0; \ ++ exit 1;; \ ++ esac; \ ++ done; \ ++ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/uip/Makefile'; \ ++ cd $(top_srcdir) && \ ++ $(AUTOMAKE) --gnu src/uip/Makefile ++.PRECIOUS: Makefile ++Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status ++ @case '$?' in \ ++ *config.status*) \ ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ ++ *) \ ++ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ ++ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ ++ esac; ++ ++$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++ ++$(top_srcdir)/configure: $(am__configure_deps) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++$(ACLOCAL_M4): $(am__aclocal_m4_deps) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++ ++clean-noinstLIBRARIES: ++ -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) ++lib_iscsi_uip.a: $(lib_iscsi_uip_a_OBJECTS) $(lib_iscsi_uip_a_DEPENDENCIES) ++ -rm -f lib_iscsi_uip.a ++ $(lib_iscsi_uip_a_AR) lib_iscsi_uip.a $(lib_iscsi_uip_a_OBJECTS) $(lib_iscsi_uip_a_LIBADD) ++ $(RANLIB) lib_iscsi_uip.a ++ ++mostlyclean-compile: ++ -rm -f *.$(OBJEXT) ++ ++distclean-compile: ++ -rm -f *.tab.c ++ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib_iscsi_uip_a-ipv6.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib_iscsi_uip_a-ipv6_ndpc.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib_iscsi_uip_a-psock.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib_iscsi_uip_a-timer.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib_iscsi_uip_a-uip-neighbor.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib_iscsi_uip_a-uip.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib_iscsi_uip_a-uip_arp.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib_iscsi_uip_a-uip_eth.Po@am__quote@ ++ ++.c.o: ++@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(COMPILE) -c $< ++ ++.c.obj: ++@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` ++ ++.c.lo: ++@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< ++ ++lib_iscsi_uip_a-uip.o: uip.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_iscsi_uip_a_CFLAGS) $(CFLAGS) -MT lib_iscsi_uip_a-uip.o -MD -MP -MF "$(DEPDIR)/lib_iscsi_uip_a-uip.Tpo" -c -o lib_iscsi_uip_a-uip.o `test -f 'uip.c' || echo '$(srcdir)/'`uip.c; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lib_iscsi_uip_a-uip.Tpo" "$(DEPDIR)/lib_iscsi_uip_a-uip.Po"; else rm -f "$(DEPDIR)/lib_iscsi_uip_a-uip.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='uip.c' object='lib_iscsi_uip_a-uip.o' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_iscsi_uip_a_CFLAGS) $(CFLAGS) -c -o lib_iscsi_uip_a-uip.o `test -f 'uip.c' || echo '$(srcdir)/'`uip.c ++ ++lib_iscsi_uip_a-uip.obj: uip.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_iscsi_uip_a_CFLAGS) $(CFLAGS) -MT lib_iscsi_uip_a-uip.obj -MD -MP -MF "$(DEPDIR)/lib_iscsi_uip_a-uip.Tpo" -c -o lib_iscsi_uip_a-uip.obj `if test -f 'uip.c'; then $(CYGPATH_W) 'uip.c'; else $(CYGPATH_W) '$(srcdir)/uip.c'; fi`; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lib_iscsi_uip_a-uip.Tpo" "$(DEPDIR)/lib_iscsi_uip_a-uip.Po"; else rm -f "$(DEPDIR)/lib_iscsi_uip_a-uip.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='uip.c' object='lib_iscsi_uip_a-uip.obj' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_iscsi_uip_a_CFLAGS) $(CFLAGS) -c -o lib_iscsi_uip_a-uip.obj `if test -f 'uip.c'; then $(CYGPATH_W) 'uip.c'; else $(CYGPATH_W) '$(srcdir)/uip.c'; fi` ++ ++lib_iscsi_uip_a-uip_arp.o: uip_arp.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_iscsi_uip_a_CFLAGS) $(CFLAGS) -MT lib_iscsi_uip_a-uip_arp.o -MD -MP -MF "$(DEPDIR)/lib_iscsi_uip_a-uip_arp.Tpo" -c -o lib_iscsi_uip_a-uip_arp.o `test -f 'uip_arp.c' || echo '$(srcdir)/'`uip_arp.c; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lib_iscsi_uip_a-uip_arp.Tpo" "$(DEPDIR)/lib_iscsi_uip_a-uip_arp.Po"; else rm -f "$(DEPDIR)/lib_iscsi_uip_a-uip_arp.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='uip_arp.c' object='lib_iscsi_uip_a-uip_arp.o' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_iscsi_uip_a_CFLAGS) $(CFLAGS) -c -o lib_iscsi_uip_a-uip_arp.o `test -f 'uip_arp.c' || echo '$(srcdir)/'`uip_arp.c ++ ++lib_iscsi_uip_a-uip_arp.obj: uip_arp.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_iscsi_uip_a_CFLAGS) $(CFLAGS) -MT lib_iscsi_uip_a-uip_arp.obj -MD -MP -MF "$(DEPDIR)/lib_iscsi_uip_a-uip_arp.Tpo" -c -o lib_iscsi_uip_a-uip_arp.obj `if test -f 'uip_arp.c'; then $(CYGPATH_W) 'uip_arp.c'; else $(CYGPATH_W) '$(srcdir)/uip_arp.c'; fi`; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lib_iscsi_uip_a-uip_arp.Tpo" "$(DEPDIR)/lib_iscsi_uip_a-uip_arp.Po"; else rm -f "$(DEPDIR)/lib_iscsi_uip_a-uip_arp.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='uip_arp.c' object='lib_iscsi_uip_a-uip_arp.obj' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_iscsi_uip_a_CFLAGS) $(CFLAGS) -c -o lib_iscsi_uip_a-uip_arp.obj `if test -f 'uip_arp.c'; then $(CYGPATH_W) 'uip_arp.c'; else $(CYGPATH_W) '$(srcdir)/uip_arp.c'; fi` ++ ++lib_iscsi_uip_a-psock.o: psock.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_iscsi_uip_a_CFLAGS) $(CFLAGS) -MT lib_iscsi_uip_a-psock.o -MD -MP -MF "$(DEPDIR)/lib_iscsi_uip_a-psock.Tpo" -c -o lib_iscsi_uip_a-psock.o `test -f 'psock.c' || echo '$(srcdir)/'`psock.c; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lib_iscsi_uip_a-psock.Tpo" "$(DEPDIR)/lib_iscsi_uip_a-psock.Po"; else rm -f "$(DEPDIR)/lib_iscsi_uip_a-psock.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='psock.c' object='lib_iscsi_uip_a-psock.o' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_iscsi_uip_a_CFLAGS) $(CFLAGS) -c -o lib_iscsi_uip_a-psock.o `test -f 'psock.c' || echo '$(srcdir)/'`psock.c ++ ++lib_iscsi_uip_a-psock.obj: psock.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_iscsi_uip_a_CFLAGS) $(CFLAGS) -MT lib_iscsi_uip_a-psock.obj -MD -MP -MF "$(DEPDIR)/lib_iscsi_uip_a-psock.Tpo" -c -o lib_iscsi_uip_a-psock.obj `if test -f 'psock.c'; then $(CYGPATH_W) 'psock.c'; else $(CYGPATH_W) '$(srcdir)/psock.c'; fi`; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lib_iscsi_uip_a-psock.Tpo" "$(DEPDIR)/lib_iscsi_uip_a-psock.Po"; else rm -f "$(DEPDIR)/lib_iscsi_uip_a-psock.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='psock.c' object='lib_iscsi_uip_a-psock.obj' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_iscsi_uip_a_CFLAGS) $(CFLAGS) -c -o lib_iscsi_uip_a-psock.obj `if test -f 'psock.c'; then $(CYGPATH_W) 'psock.c'; else $(CYGPATH_W) '$(srcdir)/psock.c'; fi` ++ ++lib_iscsi_uip_a-timer.o: timer.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_iscsi_uip_a_CFLAGS) $(CFLAGS) -MT lib_iscsi_uip_a-timer.o -MD -MP -MF "$(DEPDIR)/lib_iscsi_uip_a-timer.Tpo" -c -o lib_iscsi_uip_a-timer.o `test -f 'timer.c' || echo '$(srcdir)/'`timer.c; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lib_iscsi_uip_a-timer.Tpo" "$(DEPDIR)/lib_iscsi_uip_a-timer.Po"; else rm -f "$(DEPDIR)/lib_iscsi_uip_a-timer.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='timer.c' object='lib_iscsi_uip_a-timer.o' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_iscsi_uip_a_CFLAGS) $(CFLAGS) -c -o lib_iscsi_uip_a-timer.o `test -f 'timer.c' || echo '$(srcdir)/'`timer.c ++ ++lib_iscsi_uip_a-timer.obj: timer.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_iscsi_uip_a_CFLAGS) $(CFLAGS) -MT lib_iscsi_uip_a-timer.obj -MD -MP -MF "$(DEPDIR)/lib_iscsi_uip_a-timer.Tpo" -c -o lib_iscsi_uip_a-timer.obj `if test -f 'timer.c'; then $(CYGPATH_W) 'timer.c'; else $(CYGPATH_W) '$(srcdir)/timer.c'; fi`; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lib_iscsi_uip_a-timer.Tpo" "$(DEPDIR)/lib_iscsi_uip_a-timer.Po"; else rm -f "$(DEPDIR)/lib_iscsi_uip_a-timer.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='timer.c' object='lib_iscsi_uip_a-timer.obj' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_iscsi_uip_a_CFLAGS) $(CFLAGS) -c -o lib_iscsi_uip_a-timer.obj `if test -f 'timer.c'; then $(CYGPATH_W) 'timer.c'; else $(CYGPATH_W) '$(srcdir)/timer.c'; fi` ++ ++lib_iscsi_uip_a-uip-neighbor.o: uip-neighbor.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_iscsi_uip_a_CFLAGS) $(CFLAGS) -MT lib_iscsi_uip_a-uip-neighbor.o -MD -MP -MF "$(DEPDIR)/lib_iscsi_uip_a-uip-neighbor.Tpo" -c -o lib_iscsi_uip_a-uip-neighbor.o `test -f 'uip-neighbor.c' || echo '$(srcdir)/'`uip-neighbor.c; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lib_iscsi_uip_a-uip-neighbor.Tpo" "$(DEPDIR)/lib_iscsi_uip_a-uip-neighbor.Po"; else rm -f "$(DEPDIR)/lib_iscsi_uip_a-uip-neighbor.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='uip-neighbor.c' object='lib_iscsi_uip_a-uip-neighbor.o' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_iscsi_uip_a_CFLAGS) $(CFLAGS) -c -o lib_iscsi_uip_a-uip-neighbor.o `test -f 'uip-neighbor.c' || echo '$(srcdir)/'`uip-neighbor.c ++ ++lib_iscsi_uip_a-uip-neighbor.obj: uip-neighbor.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_iscsi_uip_a_CFLAGS) $(CFLAGS) -MT lib_iscsi_uip_a-uip-neighbor.obj -MD -MP -MF "$(DEPDIR)/lib_iscsi_uip_a-uip-neighbor.Tpo" -c -o lib_iscsi_uip_a-uip-neighbor.obj `if test -f 'uip-neighbor.c'; then $(CYGPATH_W) 'uip-neighbor.c'; else $(CYGPATH_W) '$(srcdir)/uip-neighbor.c'; fi`; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lib_iscsi_uip_a-uip-neighbor.Tpo" "$(DEPDIR)/lib_iscsi_uip_a-uip-neighbor.Po"; else rm -f "$(DEPDIR)/lib_iscsi_uip_a-uip-neighbor.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='uip-neighbor.c' object='lib_iscsi_uip_a-uip-neighbor.obj' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_iscsi_uip_a_CFLAGS) $(CFLAGS) -c -o lib_iscsi_uip_a-uip-neighbor.obj `if test -f 'uip-neighbor.c'; then $(CYGPATH_W) 'uip-neighbor.c'; else $(CYGPATH_W) '$(srcdir)/uip-neighbor.c'; fi` ++ ++lib_iscsi_uip_a-uip_eth.o: uip_eth.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_iscsi_uip_a_CFLAGS) $(CFLAGS) -MT lib_iscsi_uip_a-uip_eth.o -MD -MP -MF "$(DEPDIR)/lib_iscsi_uip_a-uip_eth.Tpo" -c -o lib_iscsi_uip_a-uip_eth.o `test -f 'uip_eth.c' || echo '$(srcdir)/'`uip_eth.c; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lib_iscsi_uip_a-uip_eth.Tpo" "$(DEPDIR)/lib_iscsi_uip_a-uip_eth.Po"; else rm -f "$(DEPDIR)/lib_iscsi_uip_a-uip_eth.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='uip_eth.c' object='lib_iscsi_uip_a-uip_eth.o' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_iscsi_uip_a_CFLAGS) $(CFLAGS) -c -o lib_iscsi_uip_a-uip_eth.o `test -f 'uip_eth.c' || echo '$(srcdir)/'`uip_eth.c ++ ++lib_iscsi_uip_a-uip_eth.obj: uip_eth.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_iscsi_uip_a_CFLAGS) $(CFLAGS) -MT lib_iscsi_uip_a-uip_eth.obj -MD -MP -MF "$(DEPDIR)/lib_iscsi_uip_a-uip_eth.Tpo" -c -o lib_iscsi_uip_a-uip_eth.obj `if test -f 'uip_eth.c'; then $(CYGPATH_W) 'uip_eth.c'; else $(CYGPATH_W) '$(srcdir)/uip_eth.c'; fi`; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lib_iscsi_uip_a-uip_eth.Tpo" "$(DEPDIR)/lib_iscsi_uip_a-uip_eth.Po"; else rm -f "$(DEPDIR)/lib_iscsi_uip_a-uip_eth.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='uip_eth.c' object='lib_iscsi_uip_a-uip_eth.obj' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_iscsi_uip_a_CFLAGS) $(CFLAGS) -c -o lib_iscsi_uip_a-uip_eth.obj `if test -f 'uip_eth.c'; then $(CYGPATH_W) 'uip_eth.c'; else $(CYGPATH_W) '$(srcdir)/uip_eth.c'; fi` ++ ++lib_iscsi_uip_a-ipv6_ndpc.o: ipv6_ndpc.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_iscsi_uip_a_CFLAGS) $(CFLAGS) -MT lib_iscsi_uip_a-ipv6_ndpc.o -MD -MP -MF "$(DEPDIR)/lib_iscsi_uip_a-ipv6_ndpc.Tpo" -c -o lib_iscsi_uip_a-ipv6_ndpc.o `test -f 'ipv6_ndpc.c' || echo '$(srcdir)/'`ipv6_ndpc.c; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lib_iscsi_uip_a-ipv6_ndpc.Tpo" "$(DEPDIR)/lib_iscsi_uip_a-ipv6_ndpc.Po"; else rm -f "$(DEPDIR)/lib_iscsi_uip_a-ipv6_ndpc.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ipv6_ndpc.c' object='lib_iscsi_uip_a-ipv6_ndpc.o' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_iscsi_uip_a_CFLAGS) $(CFLAGS) -c -o lib_iscsi_uip_a-ipv6_ndpc.o `test -f 'ipv6_ndpc.c' || echo '$(srcdir)/'`ipv6_ndpc.c ++ ++lib_iscsi_uip_a-ipv6_ndpc.obj: ipv6_ndpc.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_iscsi_uip_a_CFLAGS) $(CFLAGS) -MT lib_iscsi_uip_a-ipv6_ndpc.obj -MD -MP -MF "$(DEPDIR)/lib_iscsi_uip_a-ipv6_ndpc.Tpo" -c -o lib_iscsi_uip_a-ipv6_ndpc.obj `if test -f 'ipv6_ndpc.c'; then $(CYGPATH_W) 'ipv6_ndpc.c'; else $(CYGPATH_W) '$(srcdir)/ipv6_ndpc.c'; fi`; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lib_iscsi_uip_a-ipv6_ndpc.Tpo" "$(DEPDIR)/lib_iscsi_uip_a-ipv6_ndpc.Po"; else rm -f "$(DEPDIR)/lib_iscsi_uip_a-ipv6_ndpc.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ipv6_ndpc.c' object='lib_iscsi_uip_a-ipv6_ndpc.obj' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_iscsi_uip_a_CFLAGS) $(CFLAGS) -c -o lib_iscsi_uip_a-ipv6_ndpc.obj `if test -f 'ipv6_ndpc.c'; then $(CYGPATH_W) 'ipv6_ndpc.c'; else $(CYGPATH_W) '$(srcdir)/ipv6_ndpc.c'; fi` ++ ++lib_iscsi_uip_a-ipv6.o: ipv6.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_iscsi_uip_a_CFLAGS) $(CFLAGS) -MT lib_iscsi_uip_a-ipv6.o -MD -MP -MF "$(DEPDIR)/lib_iscsi_uip_a-ipv6.Tpo" -c -o lib_iscsi_uip_a-ipv6.o `test -f 'ipv6.c' || echo '$(srcdir)/'`ipv6.c; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lib_iscsi_uip_a-ipv6.Tpo" "$(DEPDIR)/lib_iscsi_uip_a-ipv6.Po"; else rm -f "$(DEPDIR)/lib_iscsi_uip_a-ipv6.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ipv6.c' object='lib_iscsi_uip_a-ipv6.o' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_iscsi_uip_a_CFLAGS) $(CFLAGS) -c -o lib_iscsi_uip_a-ipv6.o `test -f 'ipv6.c' || echo '$(srcdir)/'`ipv6.c ++ ++lib_iscsi_uip_a-ipv6.obj: ipv6.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_iscsi_uip_a_CFLAGS) $(CFLAGS) -MT lib_iscsi_uip_a-ipv6.obj -MD -MP -MF "$(DEPDIR)/lib_iscsi_uip_a-ipv6.Tpo" -c -o lib_iscsi_uip_a-ipv6.obj `if test -f 'ipv6.c'; then $(CYGPATH_W) 'ipv6.c'; else $(CYGPATH_W) '$(srcdir)/ipv6.c'; fi`; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lib_iscsi_uip_a-ipv6.Tpo" "$(DEPDIR)/lib_iscsi_uip_a-ipv6.Po"; else rm -f "$(DEPDIR)/lib_iscsi_uip_a-ipv6.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ipv6.c' object='lib_iscsi_uip_a-ipv6.obj' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_iscsi_uip_a_CFLAGS) $(CFLAGS) -c -o lib_iscsi_uip_a-ipv6.obj `if test -f 'ipv6.c'; then $(CYGPATH_W) 'ipv6.c'; else $(CYGPATH_W) '$(srcdir)/ipv6.c'; fi` ++ ++mostlyclean-libtool: ++ -rm -f *.lo ++ ++clean-libtool: ++ -rm -rf .libs _libs ++ ++distclean-libtool: ++ -rm -f libtool ++uninstall-info-am: ++ ++ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) ++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) ' { files[$$0] = 1; } \ ++ END { for (i in files) print i; }'`; \ ++ mkid -fID $$unique ++tags: TAGS ++ ++TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ ++ $(TAGS_FILES) $(LISP) ++ tags=; \ ++ here=`pwd`; \ ++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) ' { files[$$0] = 1; } \ ++ END { for (i in files) print i; }'`; \ ++ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ ++ test -n "$$unique" || unique=$$empty_fix; \ ++ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ ++ $$tags $$unique; \ ++ fi ++ctags: CTAGS ++CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ ++ $(TAGS_FILES) $(LISP) ++ tags=; \ ++ here=`pwd`; \ ++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) ' { files[$$0] = 1; } \ ++ END { for (i in files) print i; }'`; \ ++ test -z "$(CTAGS_ARGS)$$tags$$unique" \ ++ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ ++ $$tags $$unique ++ ++GTAGS: ++ here=`$(am__cd) $(top_builddir) && pwd` \ ++ && cd $(top_srcdir) \ ++ && gtags -i $(GTAGS_ARGS) $$here ++ ++distclean-tags: ++ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags ++ ++distdir: $(DISTFILES) ++ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ ++ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ ++ list='$(DISTFILES)'; for file in $$list; do \ ++ case $$file in \ ++ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ ++ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ ++ esac; \ ++ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ ++ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ ++ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ ++ dir="/$$dir"; \ ++ $(mkdir_p) "$(distdir)$$dir"; \ ++ else \ ++ dir=''; \ ++ fi; \ ++ if test -d $$d/$$file; then \ ++ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ ++ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ ++ fi; \ ++ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ ++ else \ ++ test -f $(distdir)/$$file \ ++ || cp -p $$d/$$file $(distdir)/$$file \ ++ || exit 1; \ ++ fi; \ ++ done ++check-am: all-am ++check: check-am ++all-am: Makefile $(LIBRARIES) ++installdirs: ++install: install-am ++install-exec: install-exec-am ++install-data: install-data-am ++uninstall: uninstall-am ++ ++install-am: all-am ++ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am ++ ++installcheck: installcheck-am ++install-strip: ++ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ ++ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ ++ `test -z '$(STRIP)' || \ ++ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install ++mostlyclean-generic: ++ ++clean-generic: ++ ++distclean-generic: ++ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) ++ ++maintainer-clean-generic: ++ @echo "This command is intended for maintainers to use" ++ @echo "it deletes files that may require special tools to rebuild." ++clean: clean-am ++ ++clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ ++ mostlyclean-am ++ ++distclean: distclean-am ++ -rm -rf ./$(DEPDIR) ++ -rm -f Makefile ++distclean-am: clean-am distclean-compile distclean-generic \ ++ distclean-libtool distclean-tags ++ ++dvi: dvi-am ++ ++dvi-am: ++ ++html: html-am ++ ++info: info-am ++ ++info-am: ++ ++install-data-am: ++ ++install-exec-am: ++ ++install-info: install-info-am ++ ++install-man: ++ ++installcheck-am: ++ ++maintainer-clean: maintainer-clean-am ++ -rm -rf ./$(DEPDIR) ++ -rm -f Makefile ++maintainer-clean-am: distclean-am maintainer-clean-generic ++ ++mostlyclean: mostlyclean-am ++ ++mostlyclean-am: mostlyclean-compile mostlyclean-generic \ ++ mostlyclean-libtool ++ ++pdf: pdf-am ++ ++pdf-am: ++ ++ps: ps-am ++ ++ps-am: ++ ++uninstall-am: uninstall-info-am ++ ++.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ ++ clean-libtool clean-noinstLIBRARIES ctags distclean \ ++ distclean-compile distclean-generic distclean-libtool \ ++ distclean-tags distdir dvi dvi-am html html-am info info-am \ ++ install install-am install-data install-data-am install-exec \ ++ install-exec-am install-info install-info-am install-man \ ++ install-strip installcheck installcheck-am installdirs \ ++ maintainer-clean maintainer-clean-generic mostlyclean \ ++ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ ++ pdf pdf-am ps ps-am tags uninstall uninstall-am \ ++ uninstall-info-am ++ ++# Tell versions [3.59,3.63) of GNU make to not export all variables. ++# Otherwise a system limit (for SysV at least) may be exceeded. ++.NOEXPORT: +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/Makefile.include open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/Makefile.include +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/Makefile.include 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/Makefile.include 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,47 @@ ++ ++ ++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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/psock.c open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/psock.c +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/psock.c 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/psock.c 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,345 @@ ++/* ++ * 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 ++ * ++ * $Id: psock.c,v 1.2 2006/06/12 08:00:30 adam Exp $ ++ */ ++ ++#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 acknowledged ++ * (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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/psock.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/psock.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/psock.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/psock.h 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,384 @@ ++/* ++ * 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 ++ * ++ * $Id: psock.h,v 1.3 2006/06/12 08:00:30 adam Exp $ ++ */ ++ ++/** ++ * \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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/pt.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/pt.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/pt.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/pt.h 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,323 @@ ++/* ++ * 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 ++ * ++ * $Id: pt.h,v 1.2 2006/06/12 08:00:30 adam Exp $ ++ */ ++ ++/** ++ * \addtogroup pt ++ * @{ ++ */ ++ ++/** ++ * \file ++ * Protothreads implementation. ++ * \author ++ * Adam Dunkels ++ * ++ */ ++ ++#ifndef __PT_H__ ++#define __PT_H__ ++ ++#include "lc.h" ++ ++struct pt { ++ lc_t 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 = 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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/timer.c open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/timer.c +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/timer.c 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/timer.c 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,128 @@ ++/** ++ * \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 ++ * ++ * $Id: timer.c,v 1.2 2006/06/12 08:00:30 adam Exp $ ++ */ ++ ++#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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/timer.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/timer.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/timer.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/timer.h 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,85 @@ ++/** ++ * \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 ++ * ++ * $Id: timer.h,v 1.3 2006/06/11 21:46:39 adam Exp $ ++ */ ++#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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/uip_arch.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/uip_arch.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/uip_arch.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/uip_arch.h 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,138 @@ ++/** ++ * \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. ++ * ++ * $Id: uip_arch.h,v 1.2 2006/06/07 09:15:19 adam Exp $ ++ * ++ */ ++ ++#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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/uip_arp.c open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/uip_arp.c +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/uip_arp.c 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/uip_arp.c 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,485 @@ ++#include ++//#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. ++ * ++ * $Id: uip_arp.c,v 1.8 2006/06/02 23:36:21 adam Exp $ ++ * ++ */ ++ ++#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 && ++ 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 (arptime - tabptr->time > tmpage) { ++ tmpage = 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); ++ else ++ eth->type = htons(UIP_ETHTYPE_8021Q); ++ pkt->buf_size = sizeof(*arp) + sizeof(*eth); ++ } ++ 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 arp_hdr *arp; ++ struct uip_eth_hdr *eth; ++ struct ip_hdr *ip_buf; ++ ++ arp = (struct arp_hdr *)ustack->network_layer; ++ 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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/uip_arp.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/uip_arp.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/uip_arp.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/uip_arp.h 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,196 @@ ++/** ++ * \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. ++ * ++ * $Id: uip_arp.h,v 1.5 2006/06/11 21:46:39 adam Exp $ ++ * ++ */ ++ ++#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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/uip.c open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/uip.c +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/uip.c 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/uip.c 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,2450 @@ ++#include ++#include ++#include ++#include ++#include ++#include "uip.h" ++#include "dhcpc.h" ++#include "ipv6_ndpc.h" ++#include "brcm_iscsi.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. ++ * ++ * $Id: uip.c,v 1.65 2006/06/11 21:46:39 adam Exp $ ++ * ++ */ ++ ++/* ++ * 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_ip6addr_t all_ones_addr6 = ++ { 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff }; ++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) ++{ ++ uip_sethostaddr4(ustack, ip); ++ uip_setnetmask4(ustack, netmask); ++ uip_setdraddr4(ustack, default_route); ++ 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]) - 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; ++} ++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 = 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) { ++ } else { ++ 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)) { ++ } else { ++ /* 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. */ ++ LOG_DEBUG(PFX "icmp6_input: length %d", ustack->uip_len); ++ ++ if (ipv6_hdr->ip6_nxt != UIP_PROTO_ICMP6) { ++ /* We only allow ICMPv6 packets from here. */ ++ ++ustack->stats.ip.drop; ++ ++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; ++ ++ /* 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; ++ } ++ 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 acknowledges any outstanding ++ data. If so, we update the sequence number, reset the length of ++ the outstanding data, calculate 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; ++ } ++ 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 */ ++ ustack->uip_appdata = ++ ((char *)ustack->uip_appdata) + ++ ((tcp_hdr->urgp[0] << 8) | tcp_hdr->urgp[1]); ++ ustack->uip_len -= ++ (tcp_hdr->urgp[0] << 8) | tcp_hdr->urgp[1]; ++#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->ripaddr); ++ } 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)) { ++ } else { ++ 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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/uip_eth.c open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/uip_eth.c +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/uip_eth.c 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/uip_eth.c 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,50 @@ ++/* ++ * 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. ++ * ++ * 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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/uip_eth.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/uip_eth.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/uip_eth.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/uip_eth.h 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,43 @@ ++#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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/uip.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/uip.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/uip.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/uip.h 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,1611 @@ ++ ++/** ++ * \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. ++ * ++ * $Id: uip.h,v 1.40 2006/06/08 07:12:07 adam Exp $ ++ * ++ */ ++ ++#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]; ++ ++const uip_ip6addr_t all_zeroes_addr6; ++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 ++ ++#if 0 ++/** ++ * 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 ++ */ ++#define uip_udp_periodic(conn) do { uip_udp_conn = &uip_udp_conns[conn]; \ ++ uip_process(UIP_UDP_TIMER); } while (0) ++ ++/** ++ * Periodic processing for a UDP connection identified by a pointer to ++ * its structure. ++ * ++ * Same as uip_udp_periodic() but takes a pointer to the actual ++ * uip_conn struct instead of an integer as its argument. This ++ * function can be used to force periodic processing of a specific ++ * connection. ++ * ++ * \param conn A pointer to the uip_udp_conn struct for the connection ++ * to be processed. ++ * ++ * \hideinitializer ++ */ ++#define uip_udp_periodic_conn(conn) do { uip_udp_conn = conn; \ ++ uip_process(UIP_UDP_TIMER); } while (0) ++ ++#endif ++ ++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; ++ /**< 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. */ ++ ++ /** The application state. */ ++/* BWL */ ++// uip_tcp_appstate_t appstate; ++}; ++ ++/** ++ * \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; ++// u8_t len[2]; ++ 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; ++}; ++ ++/* 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 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; ++ int prefix_len; ++ ++#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; ++}; ++ ++/******************************************************************************* ++ * 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); ++ ++#endif /* __UIP_H__ */ ++ ++/** @} */ +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/uip-neighbor.c open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/uip-neighbor.c +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/uip-neighbor.c 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/uip-neighbor.c 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,221 @@ ++/* ++ * 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 ++ * ++ * $Id: uip-neighbor.c,v 1.2 2006/06/12 08:00:30 adam Exp $ ++ */ ++ ++/** ++ * \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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/uip-neighbor.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/uip-neighbor.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/uip-neighbor.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/uip-neighbor.h 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,106 @@ ++/* ++ * 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 ++ * ++ * $Id: uip-neighbor.h,v 1.2 2006/06/12 08:00:30 adam Exp $ ++ */ ++ ++/** ++ * \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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/uipopt.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/uipopt.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip/uipopt.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip/uipopt.h 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,537 @@ ++/** ++ * \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. ++ * ++ * $Id: uipopt.h,v 1.4 2006/06/12 08:00:31 adam Exp $ ++ * ++ */ ++ ++#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 8 ++#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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip-1.0-changelog.txt open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip-1.0-changelog.txt +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/uip-1.0-changelog.txt 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/uip-1.0-changelog.txt 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,98 @@ ++* 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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/build_date.c open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/build_date.c +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/build_date.c 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/build_date.c 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1 @@ ++char *build_date ="Thu May 5 12:17:42 PDT 2011"; +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/build_date.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/build_date.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/build_date.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/build_date.h 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1 @@ ++char *build_date; +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/clock-arch.c open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/clock-arch.c +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/clock-arch.c 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/clock-arch.c 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,55 @@ ++/* ++ * 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 ++ * ++ * $Id: clock-arch.c,v 1.2 2006/06/12 08:00:31 adam Exp $ ++ */ ++ ++/** ++ * \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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/clock-arch.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/clock-arch.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/clock-arch.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/clock-arch.h 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,40 @@ ++/* ++ * 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 ++ * ++ * $Id: clock-arch.h,v 1.2 2006/06/12 08:00:31 adam Exp $ ++ */ ++ ++#ifndef __CLOCK_ARCH_H__ ++#define __CLOCK_ARCH_H__ ++ ++typedef int clock_time_t; ++#define CLOCK_CONF_SECOND 1000 ++ ++#endif /* __CLOCK_ARCH_H__ */ +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/iscsid_ipc.c open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/iscsid_ipc.c +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/iscsid_ipc.c 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/iscsid_ipc.c 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,868 @@ ++/* ++ * 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. ++ * ++ * iscsi_ipc.c - Generic NIC management/utility functions ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define PFX "iscsi_ipc " ++ ++/* TODO fix me */ ++#define IFNAMSIZ 15 ++ ++#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 "logger.h" ++#include "uip.h" ++ ++/* private iscsid options stucture */ ++struct iscsid_options { ++ int fd; ++ pthread_t thread; ++}; ++ ++struct ip_addr_mask { ++ int ip_type; ++ union { ++ struct in_addr addr4; ++ struct in6_addr addr6; ++ } addr; ++ union { ++ struct in_addr nm4; ++ struct in6_addr nm6; ++ } netmask; ++#define addr4 addr.addr4 ++#define addr6 addr.addr6 ++#define nm4 netmask.nm4 ++#define nm6 netmask.nm6 ++}; ++ ++/****************************************************************************** ++ * iscsid_ipc Constants ++ *****************************************************************************/ ++static const char uio_udev_path_template[] = "/dev/uio%d"; ++ ++/****************************************************************************** ++ * 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 ip_addr_mask *ipam, ++ int *prefix_len) ++{ ++ int rc = 0, i; ++ char *tmp, *tok; ++ char ipaddr_str[NI_MAXHOST]; ++ char str[INET6_ADDRSTRLEN]; ++ int keepbits = 0; ++ struct in_addr ia; ++ struct in6_addr ia6; ++ ++ memset(ipam, 0, sizeof(struct ip_addr_mask)); ++ if (strlen(in_ipaddr_str) > NI_MAXHOST) ++ strncpy(ipaddr_str, in_ipaddr_str, NI_MAXHOST); ++ else ++ strcpy(ipaddr_str, in_ipaddr_str); ++ ++ /* 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 = atoi(tmp); ++ strcpy(ipaddr_str, tok); ++ } ++ ++ /* Determine if the IP address passed from the iface file is ++ * an IPv4 or IPv6 address */ ++ rc = inet_pton(AF_INET, ipaddr_str, &ipam->addr6); ++ if (rc == 0) { ++ /* Test to determine if the addres is an IPv6 address */ ++ rc = inet_pton(AF_INET6, ipaddr_str, &ipam->addr6); ++ if (rc == 0) { ++ LOG_ERR(PFX "Could not parse IP address: '%s'", ++ ipaddr_str); ++ goto out; ++ } ++ ipam->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(&ipam->nm6.s6_addr, all_zeroes_addr6, ++ sizeof(struct in6_addr)); ++ for (i = 0; i < 2; i++) ++ ipam->nm6.s6_addr32[i] = 0xffffffff; ++ goto out; ++ } ++ *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; ++ break; ++ } else ++ ia6.s6_addr32[i] = 0xFFFFFFFF; ++ keepbits -= 32; ++ } ++ ipam->nm6 = ia6; ++ if (inet_ntop(AF_INET6, &ia6, str, sizeof(str))) ++ LOG_INFO(PFX "Using netmask: %s", str); ++ } else { ++ ipam->ip_type = AF_INET; ++ rc = inet_pton(AF_INET, ipaddr_str, &ipam->addr4); ++ ++ 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; ++ ipam->nm4.s_addr = htonl(ia.s_addr); ++ LOG_INFO(PFX "Using netmask: %s", inet_ntoa(ipam->nm4)); ++ } ++out: ++ return rc; ++} ++ ++static int parse_iface(void *arg) ++{ ++ int rc; ++ nic_t *nic = NULL; ++ nic_interface_t *nic_iface, *vlan_iface, *base_nic_iface; ++ char *transport_name; ++ size_t transport_name_size; ++ nic_lib_handle_t *handle; ++ iscsid_uip_broadcast_t *data; ++ short int vlan; ++ char ipv6_buf_str[INET6_ADDRSTRLEN]; ++ int request_type = 0; ++ struct in_addr netmask; ++ int i, prefix_len = 64; ++ struct ip_addr_mask ipam; ++ struct iface_rec *rec; ++ void *res; ++ ++ data = (iscsid_uip_broadcast_t *) arg; ++ ++ rec = &data->u.iface_rec.rec; ++ LOG_INFO(PFX "Received request for '%s' to set IP address: '%s' " ++ "VLAN: '%d'", rec->netdev, rec->ipaddress, rec->vlan_id); ++ ++ vlan = rec->vlan_id; ++ if (vlan && valid_vlan(vlan) == 0) { ++ LOG_ERR(PFX "Invalid VLAN tag: %d", rec->vlan_id); ++ rc = -EIO; ++ goto early_exit; ++ } ++ ++ /* Detect for CIDR notation and strip off the netmask if present */ ++ rc = decode_cidr(rec->ipaddress, &ipam, &prefix_len); ++ if (rc && !ipam.ip_type) { ++ LOG_ERR(PFX "decode_cidr: rc=%d, ipam.ip_type=%d", ++ rc, ipam.ip_type) ++ goto early_exit; ++ } ++ if (ipam.ip_type == AF_INET6) ++ inet_ntop(AF_INET6, &ipam.addr6, ipv6_buf_str, ++ sizeof(ipv6_buf_str)); ++ ++ 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 aquire nic_list_mutex lock"); ++ rc = -EIO; ++ goto early_exit; ++ } ++ ++ /* 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); ++ } ++ ++ if (nic->flags & NIC_GOING_DOWN) { ++ rc = -EIO; ++ LOG_INFO(PFX "nic->flags GOING DOWN"); ++ goto done; ++ } ++ ++ /* If we retry too many times allow iscsid to to timeout */ ++ if (nic->pending_count > 1000) { ++ LOG_WARN(PFX "%s: pending count excceded 1000", nic->log_name); ++ ++ pthread_mutex_lock(&nic->nic_mutex); ++ nic->pending_count = 0; ++ nic->flags &= ~NIC_ENABLED_PENDING; ++ pthread_mutex_unlock(&nic->nic_mutex); ++ ++ rc = 0; ++ goto done; ++ } ++ ++ if (nic->flags & NIC_ENABLED_PENDING) { ++ struct timespec sleep_req, sleep_rem; ++ ++ sleep_req.tv_sec = 0; ++ sleep_req.tv_nsec = 100000; ++ nanosleep(&sleep_req, &sleep_rem); ++ ++ pthread_mutex_lock(&nic->nic_mutex); ++ nic->pending_count++; ++ pthread_mutex_unlock(&nic->nic_mutex); ++ ++ LOG_INFO(PFX "%s: enabled pending", nic->log_name); ++ rc = -EAGAIN; ++ goto done; ++ } ++ ++ 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); ++ ++ /* Create the base network interface if it doesn't exist */ ++ nic_iface = nic_find_nic_iface_protocol(nic, 0, ipam.ip_type); ++ if (nic_iface == NULL) { ++ LOG_INFO(PFX "%s couldn't find interface with " ++ "ip_type: 0x%x creating it", ++ nic->log_name, ipam.ip_type); ++ ++ /* Create the nic interface */ ++ nic_iface = nic_iface_init(); ++ ++ if (nic_iface == NULL) { ++ LOG_ERR(PFX "Couldn't allocate nic_iface", nic_iface); ++ goto done; ++ } ++ ++ nic_iface->protocol = ipam.ip_type; ++ nic_add_nic_iface(nic, nic_iface); ++ ++ persist_all_nic_iface(nic); ++ ++ LOG_INFO(PFX "%s: created network interface", nic->log_name); ++ } else { ++ LOG_INFO(PFX "%s: using existing network interface", ++ nic->log_name); ++ } ++ ++ set_nic_iface(nic, nic_iface); ++ ++ /* Find the vlan nic_interface */ ++ if (vlan) { ++ vlan_iface = nic_find_vlan_iface_protocol(nic, nic_iface, vlan, ++ ipam.ip_type); ++ if (vlan_iface == NULL) { ++ LOG_INFO(PFX "%s couldn't find interface with VLAN = %d" ++ "ip_type: 0x%x creating it", ++ nic->log_name, vlan, ipam.ip_type); ++ ++ /* Create the nic interface */ ++ vlan_iface = nic_iface_init(); ++ ++ if (vlan_iface == NULL) { ++ LOG_ERR(PFX "Couldn't allocate nic_iface for " ++ "VLAN: %d", vlan_iface, vlan); ++ goto done; ++ } ++ ++ vlan_iface->protocol = ipam.ip_type; ++ vlan_iface->vlan_id = vlan; ++ nic_add_vlan_iface(nic, nic_iface, vlan_iface); ++ } else { ++ LOG_INFO(PFX "%s: using existing vlan interface", ++ nic->log_name); ++ } ++ base_nic_iface = nic_iface; ++ nic_iface = vlan_iface; ++ } ++ ++ /* Determine how to configure the IP address */ ++ if (ipam.ip_type == AF_INET) { ++ if (memcmp(&ipam.addr4, ++ 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 (ipam.ip_type == AF_INET6) { ++ if (memcmp(&ipam.addr6, ++ all_zeroes_addr6, sizeof(uip_ip6addr_t)) == 0) { ++ LOG_INFO(PFX ++ "%s: requesting configuration using DHCPv6", ++ nic->log_name); ++ request_type = IPV6_CONFIG_DHCP; ++ } else { ++ LOG_INFO(PFX "%s: request configuration using static " ++ "IPv6 address: '%s'", ++ nic->log_name, ipv6_buf_str); ++ request_type = IPV6_CONFIG_STATIC; ++ } ++ } else { ++ LOG_ERR(PFX "%s: unknown ip_type to configure: 0x%x", ++ nic->log_name, ipam.ip_type); ++ ++ rc = -EIO; ++ goto done; ++ } ++ ++ if (nic_iface->ustack.ip_config == request_type) { ++ if (request_type == IPV4_CONFIG_STATIC) { ++ if (memcmp(nic_iface->ustack.hostaddr, &ipam.addr4, ++ sizeof(struct in_addr))) ++ goto diff; ++ } else if (request_type == IPV6_CONFIG_STATIC) { ++ if (memcmp(nic_iface->ustack.hostaddr6, &ipam.addr6, ++ sizeof(struct in6_addr))) ++ goto diff; ++ } ++ LOG_INFO(PFX "%s: IP configuration didn't change using 0x%x", ++ nic->log_name, nic_iface->ustack.ip_config); ++ goto enable_nic; ++diff: ++ /* Disable the NIC */ ++ nic_disable(nic, 0); ++ } else { ++ if (request_type == IPV4_CONFIG_DHCP ++ || request_type == IPV6_CONFIG_DHCP) ++ nic->flags |= NIC_RESET_UIP; ++ ++ /* Disable the NIC */ ++ 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, &ipam.addr4, ++ sizeof(struct in_addr)); ++ LOG_INFO(PFX "%s: configuring using static IP " ++ "IPv4 address :%s ", ++ nic->log_name, inet_ntoa(ipam.addr4)); ++ netmask.s_addr = ipam.nm4.s_addr; ++ if (!netmask.s_addr) ++ netmask.s_addr = ++ calculate_default_netmask(ipam.addr4.s_addr); ++ memcpy(nic_iface->ustack.netmask, ++ &netmask, sizeof(netmask.s_addr)); ++ LOG_INFO(PFX " netmask :%s", inet_ntoa(netmask)); ++ ++ nic_iface->ustack.ip_config = IPV4_CONFIG_STATIC; ++ break; ++ case IPV6_CONFIG_DHCP: ++ memset(nic_iface->ustack.hostaddr6, 0, ++ sizeof(struct in6_addr)); ++ nic_iface->ustack.prefix_len = prefix_len; ++ if (ipam.nm6.s6_addr[0] | ipam.nm6.s6_addr[1] | ++ ipam.nm6.s6_addr[2] | ipam.nm6.s6_addr[3] | ++ ipam.nm6.s6_addr[4] | ipam.nm6.s6_addr[5] | ++ ipam.nm6.s6_addr[6] | ipam.nm6.s6_addr[7]) ++ memcpy(nic_iface->ustack.netmask6, ++ &ipam.nm6, sizeof(struct in6_addr)); ++ LOG_INFO(PFX "%s: configuring using DHCPv6", ++ nic->log_name); ++ nic_iface->ustack.ip_config = IPV6_CONFIG_DHCP; ++ break; ++ case IPV6_CONFIG_STATIC: ++ memcpy(nic_iface->ustack.hostaddr6, &ipam.addr6, ++ sizeof(struct in6_addr)); ++ ++ nic_iface->ustack.prefix_len = prefix_len; ++ if (ipam.nm6.s6_addr[0] | ipam.nm6.s6_addr[1] | ++ ipam.nm6.s6_addr[2] | ipam.nm6.s6_addr[3] | ++ ipam.nm6.s6_addr[4] | ipam.nm6.s6_addr[5] | ++ ipam.nm6.s6_addr[6] | ipam.nm6.s6_addr[7]) ++ memcpy(nic_iface->ustack.netmask6, ++ &ipam.nm6, sizeof(struct in6_addr)); ++ ++ LOG_INFO(PFX "%s: configuring using static IP " ++ "IPv6 address: '%s'", nic->log_name, ipv6_buf_str); ++ ++ nic_iface->ustack.ip_config = IPV6_CONFIG_STATIC; ++ break; ++ default: ++ LOG_INFO(PFX "%s: Unknown request type: 0x%x", ++ nic->log_name, request_type); ++ ++ } ++ ++ /* Configuration changed, do VLAN WA */ ++ vlan_iface = nic_iface->vlan_next; ++ while (vlan_iface) { ++ /* TODO: When VLAN support is placed in the iface file ++ * revisit this code */ ++ if (vlan_iface->ustack.ip_config) { ++ vlan_iface->ustack.ip_config = ++ nic_iface->ustack.ip_config; ++ memcpy(vlan_iface->ustack.hostaddr, ++ nic_iface->ustack.hostaddr, ++ sizeof(nic_iface->ustack.hostaddr)); ++ memcpy(vlan_iface->ustack.netmask, ++ nic_iface->ustack.netmask, ++ sizeof(nic_iface->ustack.netmask)); ++ memcpy(vlan_iface->ustack.hostaddr6, ++ nic_iface->ustack.hostaddr6, ++ sizeof(nic_iface->ustack.hostaddr6)); ++ memcpy(vlan_iface->ustack.netmask6, ++ nic_iface->ustack.netmask6, ++ sizeof(nic_iface->ustack.netmask6)); ++ } ++ vlan_iface = vlan_iface->vlan_next; ++ } ++ ++enable_nic: ++ if (nic->state & NIC_STOPPED) { ++ pthread_mutex_lock(&nic->nic_mutex); ++ if (nic->flags & NIC_ENABLED_PENDING) { ++ /* Still waiting */ ++ pthread_mutex_unlock(&nic->nic_mutex); ++ rc = 0; ++ goto enable_out; ++ } ++ nic->flags |= NIC_ENABLED_PENDING; ++ pthread_mutex_unlock(&nic->nic_mutex); ++ ++ /* This thread will be thrown away when completed */ ++ if (nic->enable_thread != INVALID_THREAD) { ++ rc = pthread_join(nic->enable_thread, &res); ++ if (rc != 0) { ++ LOG_INFO(PFX "%s: failed joining enable NIC " ++ "thread\n", nic->log_name); ++ goto eagain; ++ } ++ } ++ rc = pthread_create(&nic->enable_thread, NULL, ++ enable_nic_thread, (void *)nic); ++ if (rc != 0) ++ LOG_WARN(PFX "%s: failed starting enable NIC thread\n", ++ nic->log_name); ++eagain: ++ rc = -EAGAIN; ++ } else { ++ LOG_INFO(PFX "%s: NIC already enabled " ++ "flags: 0x%x state: 0x%x\n", ++ nic->log_name, nic->flags, nic->state); ++ rc = 0; ++ } ++enable_out: ++ LOG_INFO(PFX "ISCSID_UIP_IPC_GET_IFACE: command: %x " ++ "name: %s, netdev: %s ipaddr: %s vlan: %d transport_name:%s", ++ data->header.command, rec->name, rec->netdev, ++ (ipam.ip_type == AF_INET) ? inet_ntoa(ipam.addr4) : ++ ipv6_buf_str, ++ vlan, rec->transport_name); ++ ++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 ++ */ ++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)); ++ 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"); ++ return -ENOMEM; ++ } ++ memset(data, 0, sizeof(*data)); ++ ++ size = fread(data, sizeof(iscsid_uip_broadcast_header_t), 1, fd); ++ if (size == -1) { ++ 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; ++ ++ LOG_DEBUG(PFX "recv iscsid request: cmd: %d, payload_len: %d", ++ cmd, payload_len); ++ ++ size = fread(&data->u.iface_rec, payload_len, 1, fd); ++ if (size == -1) { ++ LOG_ERR(PFX "Could not read data: %d(%s)", ++ errno, strerror(errno)); ++ goto error; ++ } ++ ++ switch (cmd) { ++ case ISCSID_UIP_IPC_GET_IFACE: ++ rc = parse_iface(data); ++ 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; ++ 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: ++ free(data); ++ fclose(fd); ++ ++ return rc; ++} ++ ++static void iscsid_loop_close(void *arg) ++{ ++ close(iscsid_opts.fd); ++ ++ LOG_INFO(PFX "iSCSI daemon socket closed"); ++} ++ ++/** ++ * 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; ++ ++ 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; ++ } ++ ++ process_iscsid_broadcast(s2); ++ close(s2); ++ } ++ ++ pthread_cleanup_pop(0); ++ ++ LOG_ERR(PFX "exit iscsid listening thread"); ++ ++ pthread_exit(NULL); ++} ++ ++/****************************************************************************** ++ * 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; ++ struct sockaddr_un addr; ++ ++ 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; ++ } ++ ++ 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, sizeof(addr)); ++ 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() ++{ ++ int rc; ++ ++ rc = pthread_create(&iscsid_opts.thread, NULL, 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; ++ void *res; ++ ++ if (iscsid_opts.fd != INVALID_FD) { ++ rc = pthread_cancel(iscsid_opts.thread); ++ if (rc != 0) { ++ LOG_ERR("Could not cancel iscsid listening thread: %s", ++ strerror(rc)); ++ } ++ ++ rc = pthread_join(iscsid_opts.thread, &res); ++ if (rc != 0) { ++ LOG_ERR("Could not wait for the iscsid listening " ++ "thread: %s", strerror(rc)); ++ } ++ } ++ ++ LOG_INFO(PFX "iscsid listening thread has shutdown"); ++} +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/iscsid_ipc.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/iscsid_ipc.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/iscsid_ipc.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/iscsid_ipc.h 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,51 @@ ++/* ++ * 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. ++ * ++ * iscsid_ipc.h: Generic NIC management/utility functions ++ * ++ */ ++#ifndef __ISCSID_IPC_H__ ++#define __ISCSID_IPC_H__ ++ ++#include "uip.h" ++#include "mgmt_ipc.h" ++ ++mgmt_ipc_err_e 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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/libs/bnx2.c open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/libs/bnx2.c +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/libs/bnx2.c 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/libs/bnx2.c 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,1148 @@ ++/* ++ * 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. ++ * ++ * bnx2.c - bnx2 user space driver ++ * ++ */ ++#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 brcm_5706C[] = "Broadcom NetXtreme II BCM5706 1000Base-T"; ++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[] = "Broadcom NetXtreme II BCM5706 1000Base-SX"; ++static const char hp_NC370F[] = ++ "HP NC370F Multifunction Gigabit Server Adapter"; ++static const char brcm_5708C[] = "Broadcom NetXtreme II BCM5708 1000Base-T"; ++static const char brcm_5708S[] = "Broadcom NetXtreme II BCM5708 1000Base-SX"; ++static const char brcm_5709C[] = "Broadcom NetXtreme II BCM5709 1000Base-T"; ++static const char brcm_5709S[] = "Broadcom NetXtreme II BCM5709 1000Base-SX"; ++static const char brcm_5716C[] = "Broadcom NetXtreme II BCM5716 1000Base-T"; ++static const char brcm_5716S[] = "Broadcom 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 */ ++ sleep(1); ++ } ++ } ++ if (fstat(nic->fd, &uio_stat) < 0) { ++ LOG_ERR(PFX "%s: Could not fstat device", nic->log_name); ++ rc = -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); ++ rc = -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); ++ 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); ++ 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 (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) getpagesize()); ++ 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 * getpagesize(), ++ PROT_READ | PROT_WRITE, MAP_SHARED, nic->fd, ++ (off_t) 2 * getpagesize()); ++ 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 * getpagesize()); ++ 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 (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) ++ 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 * getpagesize()); ++ ++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: ++ 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 * getpagesize()); ++ 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) + getpagesize()); ++ ++ if ((rxbd->rx_bd_haddr_hi == 0) && (rxbd->rx_bd_haddr_lo == 0)) { ++ LOG_DEBUG(PFX "%s: trying to transmit when device is closed", ++ nic->log_name); ++ 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_DEBUG(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 = (bnx2_t *) nic->priv; ++ struct uip_stack *uip = &nic_iface->ustack; ++ ++ /* 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; ++ } ++ ++ 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_DEBUG(PFX "%s: Dropped previous transmitted packet", ++ nic->log_name); ++ return -EINVAL; ++ } ++ ++ bnx2_prepare_xmit_packet(nic, nic_iface, pkt); ++ bnx2_start_xmit(nic, pkt->buf_size, nic_iface->vlan_id); ++ ++ /* bump the bnx2 dev send statistics */ ++ nic->stats.tx.packets++; ++ nic->stats.tx.bytes += uip->uip_len; ++ ++ LOG_DEBUG(PFX "%s: transmitted %d bytes " ++ "dev->tx_cons: %d, dev->tx_prod: %d, dev->tx_bseq:%d", ++ nic->log_name, pkt->buf_size, ++ bp->tx_cons, bp->tx_prod, bp->tx_bseq); ++ ++ 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 = (bnx2_t *) nic->priv; ++ 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; ++ } ++ ++ 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_DEBUG(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_DEBUG(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 " ++ "recieve ", 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 = (bnx2_t *) nic->priv; ++ uint16_t hw_cons = bp->get_tx_cons(bp); ++ ++ /* Sanity check: ensure the parameters passed in are valid */ ++ if (unlikely(nic == NULL)) { ++ LOG_ERR(PFX "bnx2_read() nic == NULL"); ++ return -EINVAL; ++ } ++ ++ if (bp->flags & BNX2_UIO_TX_HAS_SENT) { ++ bp->flags &= ~BNX2_UIO_TX_HAS_SENT; ++ } ++ ++ LOG_DEBUG(PFX "%s: clearing tx interrupt [%d %d]", ++ nic->log_name, bp->tx_cons, hw_cons); ++ ++ 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_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 != NULL) { ++ bnx2_prepare_xmit_packet(nic, pkt->nic_iface, pkt); ++ ++ bnx2_start_xmit(nic, pkt->buf_size, ++ pkt->nic_iface->vlan_id); ++ ++ LOG_DEBUG(PFX "%s: transmitted queued packet %d bytes " ++ "dev->tx_cons: %d, dev->tx_prod: %d, " ++ "dev->tx_bseq:%d", ++ nic->log_name, pkt->buf_size, ++ bp->tx_cons, bp->tx_prod, bp->tx_bseq); ++ ++ 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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/libs/bnx2.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/libs/bnx2.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/libs/bnx2.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/libs/bnx2.h 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,303 @@ ++/* ++ * 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. ++ * ++ * 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 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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/libs/bnx2x.c open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/libs/bnx2x.c +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/libs/bnx2x.c 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/libs/bnx2x.c 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,1554 @@ ++/* ++ * 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.c - bnx2x user space driver ++ * ++ */ ++#include ++#include ++#include ++#include ++#include /* Needed for linux/ethtool.h on RHEL 5.x */ ++#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.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[] = "Broadcom NetXtreme II BCM57710 10-Gigabit"; ++static const char brcm_57711[] = "Broadcom NetXtreme II BCM57711 10-Gigabit"; ++static const char brcm_57711e[] = "Broadcom NetXtreme II BCM57711E 10-Gigabit"; ++static const char brcm_57712[] = "Broadcom NetXtreme II BCM57712 10-Gigabit"; ++static const char brcm_57712_MF[] = "Broadcom NetXtreme II BCM57712 MF " ++ "10-Gigabit"; ++static const char brcm_57712_VF[] = "Broadcom NetXtreme II BCM57712 VF " ++ "10-Gigabit"; ++static const char brcm_57800[] = "Broadcom NetXtreme II BCM57800 10-Gigabit"; ++static const char brcm_57800_MF[] = "Broadcom NetXtreme II BCM57800 MF " ++ "10-Gigabit"; ++static const char brcm_57800_VF[] = "Broadcom NetXtreme II BCM57800 VF " ++ "10-Gigabit"; ++static const char brcm_57810[] = "Broadcom NetXtreme II BCM57810 10-Gigabit"; ++static const char brcm_57810_MF[] = "Broadcom NetXtreme II BCM57810 MF " ++ "10-Gigabit"; ++static const char brcm_57810_VF[] = "Broadcom NetXtreme II BCM57810 VF " ++ "10-Gigabit"; ++static const char brcm_57840[] = "Broadcom NetXtreme II BCM57840 10-Gigabit"; ++static const char brcm_57840_MF[] = "Broadcom NetXtreme II BCM57840 MF " ++ "10-Gigabit"; ++static const char brcm_57840_VF[] = "Broadcom NetXtreme II BCM57840 VF " ++ "10-Gigabit"; ++ ++/******************************************************************************* ++ * PCI ID constants ++ ******************************************************************************/ ++#define PCI_VENDOR_ID_BROADCOM 0x14e4 ++#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_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_57840 0x168d ++#define PCI_DEVICE_ID_NX2_57840_MF 0x16ab ++#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_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_57840, ++ PCI_ANY_ID, PCI_ANY_ID, brcm_57840}, ++ {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}, ++}; ++ ++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; ++} ++ ++static int bnx2x_is_drv_version_unknown(struct bnx2x_driver_version *version) ++{ ++ if ((version->major == BNX2X_UNKNOWN_MAJOR_VERSION) && ++ (version->minor == BNX2X_UNKNOWN_MINOR_VERSION) && ++ (version->sub_minor == BNX2X_UNKNOWN_SUB_MINOR_VERSION)) { ++ return 1; ++ } ++ ++ return 0; ++} ++ ++/** ++ * 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; ++ } ++ ++ 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: bnx2x driver using 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; ++ ++ 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; ++ ++ /* 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)) ++ bnx2x_get_drv_version(bp); ++ else { ++ 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 */ ++ sleep(1); ++ ++ 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 */ ++ sleep(1); ++ ++ count++; ++ } ++ } ++ 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) getpagesize()); ++ 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 * getpagesize(), ++ PROT_READ | PROT_WRITE, ++ MAP_SHARED | MAP_LOCKED, ++ nic->fd, (off_t) 2 * getpagesize()); ++ 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 * getpagesize()); ++ ++ 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 * getpagesize()); ++ 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; ++ } ++ ++ 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->reserved0) ++ bp->cid = data->reserved0; ++ } ++ ++ 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)); ++ ++ 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 * getpagesize() + 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 */ ++ val = bnx2x_rd32(bp, bp->shmem_base + 0x354); ++ /* SI mode */ ++ if ((val & 0x700) == 0x300) { ++ 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; ++ } ++ } else if ((val & 0x700) == 0) { ++ __u32 proto_offset = 0x24 + (bp->func * 0x18); ++ __u32 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) ++ goto open_error; ++ ++ /* 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); ++ ++ } ++ } ++ ++ 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 * getpagesize()); ++ 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; ++ } ++ 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 * getpagesize()); ++ 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 || nic->priv == NULL) { ++ LOG_ERR(PFX "bnx2x_close(): nic == %p, bp == %p", nic, ++ nic->priv); ++ 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) + getpagesize()); ++ ++ if ((rx_bd->addr_hi == 0) && (rx_bd->addr_lo == 0)) { ++ LOG_DEBUG(PFX "%s: trying to transmit when device is closed", ++ nic->log_name); ++ pthread_mutex_unlock(&nic->xmit_mutex); ++ 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 (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 { ++ /* If the doorbell is not rung, the packet will not ++ get sent. Hence, the xmit_mutex lock will not ++ get freed. ++ */ ++ pthread_mutex_unlock(&nic->xmit_mutex); ++ } ++ LOG_DEBUG(PFX "%s: sent %d bytes using bp->tx_prod: %d", ++ nic->log_name, len, bp->tx_prod); ++} ++ ++/** ++ * 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 = (bnx2x_t *) nic->priv; ++ struct uip_stack *uip = &nic_iface->ustack; ++ 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; ++ } ++ ++ 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_DEBUG(PFX "%s: Dropped previous transmitted packet", ++ nic->log_name); ++ return -EINVAL; ++ } ++ ++ bnx2x_prepare_xmit_packet(nic, nic_iface, pkt); ++ bnx2x_start_xmit(nic, pkt->buf_size, nic_iface->vlan_id); ++ ++ /* bump the cnic dev send statistics */ ++ nic->stats.tx.packets++; ++ nic->stats.tx.bytes += uip->uip_len; ++ ++ LOG_DEBUG(PFX "%s: transmitted %d bytes " ++ "dev->tx_cons: %d, dev->tx_prod: %d, dev->tx_bd_prod:%d", ++ nic->log_name, pkt->buf_size, ++ bp->tx_cons, bp->tx_prod, bp->tx_bd_prod); ++ ++ 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 = (bnx2x_t *) nic->priv; ++ 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; ++ } ++ ++ 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; ++ 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_DEBUG(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 */ ++ if (len > pkt->max_buf_size) ++ LOG_DEBUG(PFX "%s: bad BD length: %d", ++ nic->log_name, len); ++ ++ 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_DEBUG(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 = (bnx2x_t *) nic->priv; ++ uint16_t hw_cons = bp->get_tx_cons(bp); ++ ++ /* Sanity check: ensure the parameters passed in are valid */ ++ if (unlikely(nic == NULL)) { ++ LOG_ERR(PFX "bnx2x_read() nic == NULL"); ++ return -EINVAL; ++ } ++ ++ if (bp->tx_cons == hw_cons) { ++ if (bp->tx_cons == bp->tx_prod) { ++ /* Make sure the xmit_mutex lock is unlock */ ++ if (pthread_mutex_trylock(&nic->xmit_mutex)) ++ LOG_ERR(PFX "bnx2x tx lock with prod == cons"); ++ ++ pthread_mutex_unlock(&nic->xmit_mutex); ++ } ++ return -EAGAIN; ++ } ++ ++ 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 != NULL) { ++ 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 != NULL) { ++ bnx2x_prepare_xmit_packet(nic, pkt->nic_iface, pkt); ++ ++ bnx2x_start_xmit(nic, pkt->buf_size, ++ 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); ++ ++ 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_DEBUG(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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/libs/bnx2x.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/libs/bnx2x.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/libs/bnx2x.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/libs/bnx2x.h 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,646 @@ ++/* ++ * 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 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; ++ __u32 reserved0; ++}; ++ ++/****************************************************************************** ++ * 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 ++ ++#define BNX2X_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_57712E 0x1663 ++#define CHIP_NUM_57800 0x168a ++#define CHIP_NUM_57810 0x168e ++#define CHIP_NUM_57840 0x168d ++ ++#define CHIP_IS_E1(bp) (BNX2X_CHIP_NUM(bp) == CHIP_NUM_57710) ++#define CHIP_IS_57711(bp) (BNX2X_CHIP_NUM(bp) == CHIP_NUM_57711) ++#define CHIP_IS_57711E(bp) (BNX2X_CHIP_NUM(bp) == CHIP_NUM_57711E) ++#define CHIP_IS_57712(bp) (BNX2X_CHIP_NUM(bp) == CHIP_NUM_57712) ++#define CHIP_IS_57712E(bp) (BNX2X_CHIP_NUM(bp) == CHIP_NUM_57712E) ++#define CHIP_IS_57800(bp) (BNX2X_CHIP_NUM(bp) == CHIP_NUM_57800) ++#define CHIP_IS_57810(bp) (BNX2X_CHIP_NUM(bp) == CHIP_NUM_57810) ++#define CHIP_IS_57840(bp) (BNX2X_CHIP_NUM(bp) == CHIP_NUM_57840) ++#define CHIP_IS_E1H(bp) (CHIP_IS_57711(bp) || \ ++ CHIP_IS_57711E(bp)) ++#define CHIP_IS_E2(bp) (CHIP_IS_57712(bp) || \ ++ CHIP_IS_57712E(bp)) ++#define CHIP_IS_E3(bp) (CHIP_IS_57800(bp) || \ ++ CHIP_IS_57810(bp) || \ ++ CHIP_IS_57840(bp)) ++#define CHIP_IS_E2_PLUS(bp) (CHIP_IS_E2(bp) || CHIP_IS_E3(bp)) ++#define IS_E1H_OFFSET CHIP_IS_E1H(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 USTORM_RX_PRODS_OFFSET(port, client_id) \ ++ (IS_E1H_OFFSET ? (0x1000 + (port * 0x680) + (client_id * 0x40)) \ ++ : (0x4000 + (port * 0x360) + (client_id * 0x30))) ++ ++struct iro { ++ __u32 base; ++ __u16 m1; ++ __u16 m2; ++ __u16 m3; ++ __u16 size; ++}; ++ ++#define IRO_ENT bp->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_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_interface * bnx2x_find_nic_iface(nic_t * nic, ++// uint16_t vlan_id); ++ ++struct nic_ops *bnx2x_get_ops(); ++#endif /* __BNX2X_H__ */ +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/libs/cnic.c open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/libs/cnic.c +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/libs/cnic.c 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/libs/cnic.c 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,788 @@ ++/* ++ * 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. ++ * ++ * 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 "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" ++ ++/******************************************************************************* ++ * Constants ++ ******************************************************************************/ ++#define PFX "CNIC " ++ ++static const uip_ip6addr_t all_ones_addr6 = ++ { 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff }; ++ ++/******************************************************************************* ++ * 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); ++ ++/****************************************************************************** ++ * 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 }; ++ ++ 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); ++ 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_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); ++ ++ 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]; ++ 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)); ++ ++ LOG_DEBUG(PFX "dst ip addr %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", ++ ipv6_hdr->ip6_dst.s6_addr16[0], ++ ipv6_hdr->ip6_dst.s6_addr16[1], ++ ipv6_hdr->ip6_dst.s6_addr16[2], ++ ipv6_hdr->ip6_dst.s6_addr16[3], ++ ipv6_hdr->ip6_dst.s6_addr16[4], ++ ipv6_hdr->ip6_dst.s6_addr16[5], ++ ipv6_hdr->ip6_dst.s6_addr16[6], ++ ipv6_hdr->ip6_dst.s6_addr16[7]); ++ nic_fill_ethernet_header(nic_iface, eth, nic->mac_addr, nic->mac_addr, ++ &pkt_size, (void *)&ipv6_hdr, ETHERTYPE_IPV6); ++ req_ptr.eth = (void *)eth; ++ 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_id); ++ ++ LOG_DEBUG(PFX "%s: Sent cnic ICMPv6 neighbor request %s", ++ nic->log_name, addr_str); ++ ++ 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 */ ++ if (ndpc_request(&nic_iface->ustack, NULL, ++ &src_ipv6, GET_LINK_LOCAL_ADDR)) { ++ src_ipv6 = (u8_t *)all_zeroes_addr6; ++ LOG_DEBUG(PFX "RSP Get LL failed"); ++ goto src_done; ++ } ++ } 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 = path_req->vlan_id; ++ path_rsp->pmtu = 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", ++ addr_dst_str, ++ mac_addr[0], mac_addr[1], ++ mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); ++ ++ } else { ++ LOG_ERR(PFX "send neighbor reply failed: %d", rc); ++ } ++ ++ free(ret_buf); ++ ++ return rc; ++} ++ ++const static 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, *vlan_iface; ++ struct in_addr src_addr, dst_addr, ++ src_matching_addr, dst_matching_addr, netmask; ++ __u8 mac_addr[6]; ++ int rc; ++ uint16_t arp_retry; ++ int status = 0; ++ ++ memset(mac_addr, 0, sizeof(mac_addr)); ++ ++ pthread_mutex_lock(&nic_list_mutex); ++ ++ /* Find the proper interface via VLAN id */ ++ nic_iface = nic_find_nic_iface_protocol(nic, 0, AF_INET); ++ if (nic_iface == NULL) { ++ pthread_mutex_unlock(&nic_list_mutex); ++ LOG_ERR(PFX "%s: Couldn't find net_iface vlan_id: %d", ++ nic->log_name, path->vlan_id); ++ return -EINVAL; ++ } ++ if (path->vlan_id) { ++ vlan_iface = nic_find_vlan_iface_protocol(nic, nic_iface, ++ path->vlan_id, ++ AF_INET); ++ if (vlan_iface == NULL) { ++ LOG_INFO(PFX "%s couldn't find interface with VLAN = %d" ++ "ip_type: 0x%x creating it", ++ nic->log_name, path->vlan_id, AF_INET); ++ ++ /* Create the nic interface */ ++ vlan_iface = nic_iface_init(); ++ ++ if (vlan_iface == NULL) { ++ LOG_ERR(PFX "Couldn't allocate nic_iface for " ++ "VLAN: %d", vlan_iface, ++ path->vlan_id); ++ return -EINVAL; ++ } ++ ++ vlan_iface->protocol = nic_iface->protocol; ++ vlan_iface->vlan_id = path->vlan_id; ++ vlan_iface->ustack.ip_config = ++ nic_iface->ustack.ip_config; ++ memcpy(vlan_iface->ustack.hostaddr, ++ nic_iface->ustack.hostaddr, ++ sizeof(nic_iface->ustack.hostaddr)); ++ memcpy(vlan_iface->ustack.netmask, ++ nic_iface->ustack.netmask, ++ sizeof(nic_iface->ustack.netmask)); ++ nic_add_vlan_iface(nic, nic_iface, vlan_iface); ++ } else { ++ LOG_INFO(PFX "%s: using existing vlan interface", ++ nic->log_name); ++ } ++ nic_iface = vlan_iface; ++ } ++ ++#define MAX_ARP_RETRY 4 ++ ++ 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 { ++ arp_retry = MAX_ARP_RETRY; ++ LOG_DEBUG(PFX "%s: no default", nic->log_name); ++ goto done; ++ } ++ } ++ 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; ++ ++ pthread_mutex_unlock(&nic_list_mutex); ++ rc = pthread_cond_timedwait ++ (&nl_process_if_down_cond, ++ &nl_process_mutex, &ts); ++ ++ if (rc == ETIMEDOUT) { ++ pthread_mutex_unlock(&nl_process_mutex); ++ ++ if (pthread_mutex_trylock ++ (&nic_list_mutex) != 0) { ++ arp_retry = MAX_ARP_RETRY; ++ goto done; ++ ++ } ++ ++ rc = uip_lookup_arp_entry(dst_addr. ++ s_addr, ++ mac_addr); ++ if (rc == 0) ++ goto done; ++ } else { ++ nl_process_if_down = 0; ++ pthread_mutex_unlock(&nl_process_mutex); ++ ++ arp_retry = MAX_ARP_RETRY; ++ goto done; ++ ++ } ++ } ++ ++ arp_retry++; ++ } ++ } ++ ++done: ++ ++ if (arp_retry >= MAX_ARP_RETRY) { ++ status = -EIO; ++ rc = -EIO; ++ } ++ ++ if (status != 0 || rc != 0) ++ pthread_mutex_unlock(&nic->xmit_mutex); ++ ++ cnic_nl_neigh_rsp(nic, fd, ev, path, mac_addr, ++ nic_iface, status, AF_INET); ++ ++ pthread_mutex_unlock(&nic_list_mutex); ++ ++ 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, *vlan_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; ++ 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)); ++ ++ pthread_mutex_lock(&nic_list_mutex); ++ ++ /* Find the proper interface via VLAN id */ ++ nic_iface = nic_find_nic_iface_protocol(nic, 0, AF_INET6); ++ if (nic_iface == NULL) { ++ pthread_mutex_unlock(&nic_list_mutex); ++ LOG_ERR(PFX "%s: Couldn't find net_iface vlan_id: %d", ++ nic->log_name, path->vlan_id); ++ return -EINVAL; ++ } ++ if (path->vlan_id) { ++ vlan_iface = nic_find_vlan_iface_protocol(nic, nic_iface, ++ path->vlan_id, ++ AF_INET6); ++ if (vlan_iface == NULL) { ++ LOG_INFO(PFX "%s couldn't find interface with VLAN = %d" ++ "ip_type: 0x%x creating it", ++ nic->log_name, path->vlan_id, AF_INET6); ++ ++ /* Create the nic interface */ ++ vlan_iface = nic_iface_init(); ++ ++ if (vlan_iface == NULL) { ++ LOG_ERR(PFX "Couldn't allocate nic_iface for " ++ "VLAN: %d", vlan_iface, ++ path->vlan_id); ++ return -EINVAL; ++ } ++ vlan_iface->protocol = nic_iface->protocol; ++ vlan_iface->vlan_id = path->vlan_id; ++ vlan_iface->ustack.ip_config = ++ nic_iface->ustack.ip_config; ++ memcpy(vlan_iface->ustack.hostaddr6, ++ nic_iface->ustack.hostaddr6, ++ sizeof(nic_iface->ustack.hostaddr6)); ++ memcpy(vlan_iface->ustack.netmask6, ++ nic_iface->ustack.netmask6, ++ sizeof(nic_iface->ustack.netmask6)); ++ nic_add_vlan_iface(nic, nic_iface, vlan_iface); ++ } else { ++ LOG_INFO(PFX "%s: using existing vlan interface", ++ nic->log_name); ++ } ++ nic_iface = vlan_iface; ++ } ++ ++ /* Depending on the IPv6 address of the target we will need to ++ * determine whether we use the assigned IPv6 address or the ++ * link local IPv6 address */ ++ 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 */ ++ if (ndpc_request(&nic_iface->ustack, NULL, ++ &addr, GET_LINK_LOCAL_ADDR)) { ++ neighbor_retry = MAX_ARP_RETRY; ++ LOG_DEBUG(PFX "Use LL failed"); ++ goto done; ++ } ++ } 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)); ++ ++ LOG_DEBUG(PFX "src addr %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", ++ src_addr.s6_addr16[0], src_addr.s6_addr16[1], ++ src_addr.s6_addr16[2], src_addr.s6_addr16[3], ++ src_addr.s6_addr16[4], src_addr.s6_addr16[5], ++ src_addr.s6_addr16[6], src_addr.s6_addr16[7]); ++ LOG_DEBUG(PFX "dst addr %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", ++ dst_addr.s6_addr16[0], dst_addr.s6_addr16[1], ++ dst_addr.s6_addr16[2], dst_addr.s6_addr16[3], ++ dst_addr.s6_addr16[4], dst_addr.s6_addr16[5], ++ dst_addr.s6_addr16[6], dst_addr.s6_addr16[7]); ++ LOG_DEBUG(PFX "nm addr %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", ++ netmask.s6_addr16[0], netmask.s6_addr16[1], ++ netmask.s6_addr16[2], netmask.s6_addr16[3], ++ netmask.s6_addr16[4], netmask.s6_addr16[5], ++ netmask.s6_addr16[6], netmask.s6_addr16[7]); ++ ++ 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 (ndpc_request(&nic_iface->ustack, NULL, &addr, ++ GET_DEFAULT_ROUTER_ADDR)) { ++ neighbor_retry = MAX_ARP_RETRY; ++ goto done; ++ } ++ if (memcmp(addr, all_zeroes_addr6, sizeof(*addr))) ++ memcpy(&dst_addr, addr, sizeof(dst_addr)); ++ else { ++ neighbor_retry = MAX_ARP_RETRY; ++ goto done; ++ } ++ } ++ } ++ LOG_DEBUG(PFX "dst addr %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", ++ dst_addr.s6_addr16[0], dst_addr.s6_addr16[1], ++ dst_addr.s6_addr16[2], dst_addr.s6_addr16[3], ++ dst_addr.s6_addr16[4], dst_addr.s6_addr16[5], ++ dst_addr.s6_addr16[6], dst_addr.s6_addr16[7]); ++ ++#define MAX_ARP_RETRY 4 ++ neighbor_retry = 0; ++ ++ 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) { ++ 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_unlock(&nic_list_mutex); ++ rc = pthread_cond_timedwait ++ (&nl_process_if_down_cond, ++ &nl_process_mutex, &ts); ++ ++ if (rc == ETIMEDOUT) { ++ pthread_mutex_unlock(&nl_process_mutex); ++ ++ if (pthread_mutex_trylock ++ (&nic_list_mutex) != 0) { ++ neighbor_retry = MAX_ARP_RETRY; ++ goto done; ++ ++ } ++ ++ 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 { ++ nl_process_if_down = 0; ++ pthread_mutex_unlock(&nl_process_mutex); ++ ++ neighbor_retry = MAX_ARP_RETRY; ++ goto done; ++ } ++ } ++ neighbor_retry++; ++ } ++ } ++ ++done: ++ if (neighbor_retry >= MAX_ARP_RETRY) { ++ status = -EIO; ++ rc = -EIO; ++ } ++ ++ if (status != 0 || rc != 0) ++ pthread_mutex_unlock(&nic->xmit_mutex); ++ ++ cnic_nl_neigh_rsp(nic, fd, ev, path, mac_addr, ++ nic_iface, status, AF_INET6); ++ ++ pthread_mutex_unlock(&nic_list_mutex); ++ ++ 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 buf - The private message buffer ++ * @param buf_len - The private message buffer length ++ */ ++int cnic_handle_iscsi_path_req(nic_t * nic, int fd, struct iscsi_uevent *ev, ++ struct iscsi_path *path) ++{ ++ ++ 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); ++ else if (path->ip_addr_len == 16) ++ return cnic_handle_ipv6_iscsi_path_req(nic, fd, ev, path); ++ else { ++ LOG_DEBUG(PFX "%s: unknown ip_addr_len: %d size dropping ", ++ nic->log_name, path->ip_addr_len); ++ return -EIO; ++ } ++} +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/libs/cnic.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/libs/cnic.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/libs/cnic.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/libs/cnic.h 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,53 @@ ++/* ++ * 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. ++ * ++ * 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; ++ ++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); ++ ++#endif /* __CNIC_NL_H__ */ +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/libs/Makefile.am open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/libs/Makefile.am +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/libs/Makefile.am 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/libs/Makefile.am 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,12 @@ ++INCLUDES = -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 ++ ++noinst_LIBRARIES = lib_iscsiuio_hw_cnic.a ++ ++lib_iscsiuio_hw_cnic_a_SOURCES = ../build_date.c \ ++ cnic.c \ ++ bnx2.c \ ++ bnx2x.c +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/libs/Makefile.in open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/libs/Makefile.in +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/libs/Makefile.in 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/libs/Makefile.in 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,449 @@ ++# Makefile.in generated by automake 1.9.6 from Makefile.am. ++# @configure_input@ ++ ++# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, ++# 2003, 2004, 2005 Free Software Foundation, Inc. ++# This Makefile.in is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY, to the extent permitted by law; without ++# even the implied warranty of MERCHANTABILITY or FITNESS FOR A ++# PARTICULAR PURPOSE. ++ ++@SET_MAKE@ ++ ++srcdir = @srcdir@ ++top_srcdir = @top_srcdir@ ++VPATH = @srcdir@ ++pkgdatadir = $(datadir)/@PACKAGE@ ++pkglibdir = $(libdir)/@PACKAGE@ ++pkgincludedir = $(includedir)/@PACKAGE@ ++top_builddir = ../../.. ++am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd ++INSTALL = @INSTALL@ ++install_sh_DATA = $(install_sh) -c -m 644 ++install_sh_PROGRAM = $(install_sh) -c ++install_sh_SCRIPT = $(install_sh) -c ++INSTALL_HEADER = $(INSTALL_DATA) ++transform = $(program_transform_name) ++NORMAL_INSTALL = : ++PRE_INSTALL = : ++POST_INSTALL = : ++NORMAL_UNINSTALL = : ++PRE_UNINSTALL = : ++POST_UNINSTALL = : ++build_triplet = @build@ ++host_triplet = @host@ ++subdir = src/unix/libs ++DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ++ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 ++am__aclocal_m4_deps = $(top_srcdir)/configure.ac ++am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ ++ $(ACLOCAL_M4) ++mkinstalldirs = $(install_sh) -d ++CONFIG_HEADER = $(top_builddir)/config.h ++CONFIG_CLEAN_FILES = ++LIBRARIES = $(noinst_LIBRARIES) ++ARFLAGS = cru ++lib_iscsiuio_hw_cnic_a_AR = $(AR) $(ARFLAGS) ++lib_iscsiuio_hw_cnic_a_LIBADD = ++am_lib_iscsiuio_hw_cnic_a_OBJECTS = build_date.$(OBJEXT) \ ++ cnic.$(OBJEXT) bnx2.$(OBJEXT) bnx2x.$(OBJEXT) ++lib_iscsiuio_hw_cnic_a_OBJECTS = $(am_lib_iscsiuio_hw_cnic_a_OBJECTS) ++DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) ++depcomp = $(SHELL) $(top_srcdir)/depcomp ++am__depfiles_maybe = depfiles ++COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ ++ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) ++LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ ++ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ ++ $(AM_CFLAGS) $(CFLAGS) ++CCLD = $(CC) ++LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ ++ $(AM_LDFLAGS) $(LDFLAGS) -o $@ ++SOURCES = $(lib_iscsiuio_hw_cnic_a_SOURCES) ++DIST_SOURCES = $(lib_iscsiuio_hw_cnic_a_SOURCES) ++ETAGS = etags ++CTAGS = ctags ++DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ++ACLOCAL = @ACLOCAL@ ++AMDEP_FALSE = @AMDEP_FALSE@ ++AMDEP_TRUE = @AMDEP_TRUE@ ++AMTAR = @AMTAR@ ++AR = @AR@ ++AUTOCONF = @AUTOCONF@ ++AUTOHEADER = @AUTOHEADER@ ++AUTOMAKE = @AUTOMAKE@ ++AWK = @AWK@ ++BASH = @BASH@ ++CC = @CC@ ++CCDEPMODE = @CCDEPMODE@ ++CFLAGS = @CFLAGS@ ++CPP = @CPP@ ++CPPFLAGS = @CPPFLAGS@ ++CXX = @CXX@ ++CXXCPP = @CXXCPP@ ++CXXDEPMODE = @CXXDEPMODE@ ++CXXFLAGS = @CXXFLAGS@ ++CYGPATH_W = @CYGPATH_W@ ++DEBUG_FALSE = @DEBUG_FALSE@ ++DEBUG_TRUE = @DEBUG_TRUE@ ++DEFS = @DEFS@ ++DEPDIR = @DEPDIR@ ++ECHO = @ECHO@ ++ECHO_C = @ECHO_C@ ++ECHO_N = @ECHO_N@ ++ECHO_T = @ECHO_T@ ++EGREP = @EGREP@ ++ENDIAN = @ENDIAN@ ++EXEEXT = @EXEEXT@ ++F77 = @F77@ ++FFLAGS = @FFLAGS@ ++INSTALL_DATA = @INSTALL_DATA@ ++INSTALL_PROGRAM = @INSTALL_PROGRAM@ ++INSTALL_SCRIPT = @INSTALL_SCRIPT@ ++INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ ++LDFLAGS = @LDFLAGS@ ++LIBOBJS = @LIBOBJS@ ++LIBS = @LIBS@ ++LIBTOOL = @LIBTOOL@ ++LN_S = @LN_S@ ++LTLIBOBJS = @LTLIBOBJS@ ++MAKEINFO = @MAKEINFO@ ++OBJEXT = @OBJEXT@ ++PACKAGE = @PACKAGE@ ++PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ ++PACKAGE_NAME = @PACKAGE_NAME@ ++PACKAGE_STRING = @PACKAGE_STRING@ ++PACKAGE_TARNAME = @PACKAGE_TARNAME@ ++PACKAGE_VERSION = @PACKAGE_VERSION@ ++PATH_SEPARATOR = @PATH_SEPARATOR@ ++RANLIB = @RANLIB@ ++SED = @SED@ ++SET_MAKE = @SET_MAKE@ ++SHELL = @SHELL@ ++STRIP = @STRIP@ ++VERSION = @VERSION@ ++ac_ct_AR = @ac_ct_AR@ ++ac_ct_CC = @ac_ct_CC@ ++ac_ct_CXX = @ac_ct_CXX@ ++ac_ct_F77 = @ac_ct_F77@ ++ac_ct_RANLIB = @ac_ct_RANLIB@ ++ac_ct_STRIP = @ac_ct_STRIP@ ++am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ ++am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ ++am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ ++am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ ++am__include = @am__include@ ++am__leading_dot = @am__leading_dot@ ++am__quote = @am__quote@ ++am__tar = @am__tar@ ++am__untar = @am__untar@ ++bindir = @bindir@ ++build = @build@ ++build_alias = @build_alias@ ++build_cpu = @build_cpu@ ++build_os = @build_os@ ++build_vendor = @build_vendor@ ++datadir = @datadir@ ++exec_prefix = @exec_prefix@ ++host = @host@ ++host_alias = @host_alias@ ++host_cpu = @host_cpu@ ++host_os = @host_os@ ++host_vendor = @host_vendor@ ++includedir = @includedir@ ++infodir = @infodir@ ++install_sh = @install_sh@ ++libdir = @libdir@ ++libexecdir = @libexecdir@ ++localstatedir = @localstatedir@ ++mandir = @mandir@ ++mkdir_p = @mkdir_p@ ++oldincludedir = @oldincludedir@ ++prefix = @prefix@ ++program_transform_name = @program_transform_name@ ++sbindir = @sbindir@ ++sharedstatedir = @sharedstatedir@ ++sysconfdir = @sysconfdir@ ++target_alias = @target_alias@ ++INCLUDES = -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 ++ ++noinst_LIBRARIES = lib_iscsiuio_hw_cnic.a ++lib_iscsiuio_hw_cnic_a_SOURCES = ../build_date.c \ ++ cnic.c \ ++ bnx2.c \ ++ bnx2x.c ++ ++all: all-am ++ ++.SUFFIXES: ++.SUFFIXES: .c .lo .o .obj ++$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) ++ @for dep in $?; do \ ++ case '$(am__configure_deps)' in \ ++ *$$dep*) \ ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ ++ && exit 0; \ ++ exit 1;; \ ++ esac; \ ++ done; \ ++ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/unix/libs/Makefile'; \ ++ cd $(top_srcdir) && \ ++ $(AUTOMAKE) --gnu src/unix/libs/Makefile ++.PRECIOUS: Makefile ++Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status ++ @case '$?' in \ ++ *config.status*) \ ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ ++ *) \ ++ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ ++ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ ++ esac; ++ ++$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++ ++$(top_srcdir)/configure: $(am__configure_deps) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++$(ACLOCAL_M4): $(am__aclocal_m4_deps) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++ ++clean-noinstLIBRARIES: ++ -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) ++lib_iscsiuio_hw_cnic.a: $(lib_iscsiuio_hw_cnic_a_OBJECTS) $(lib_iscsiuio_hw_cnic_a_DEPENDENCIES) ++ -rm -f lib_iscsiuio_hw_cnic.a ++ $(lib_iscsiuio_hw_cnic_a_AR) lib_iscsiuio_hw_cnic.a $(lib_iscsiuio_hw_cnic_a_OBJECTS) $(lib_iscsiuio_hw_cnic_a_LIBADD) ++ $(RANLIB) lib_iscsiuio_hw_cnic.a ++ ++mostlyclean-compile: ++ -rm -f *.$(OBJEXT) ++ ++distclean-compile: ++ -rm -f *.tab.c ++ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bnx2.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bnx2x.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/build_date.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cnic.Po@am__quote@ ++ ++.c.o: ++@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(COMPILE) -c $< ++ ++.c.obj: ++@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` ++ ++.c.lo: ++@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< ++ ++build_date.o: ../build_date.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT build_date.o -MD -MP -MF "$(DEPDIR)/build_date.Tpo" -c -o build_date.o `test -f '../build_date.c' || echo '$(srcdir)/'`../build_date.c; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/build_date.Tpo" "$(DEPDIR)/build_date.Po"; else rm -f "$(DEPDIR)/build_date.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='../build_date.c' object='build_date.o' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o build_date.o `test -f '../build_date.c' || echo '$(srcdir)/'`../build_date.c ++ ++build_date.obj: ../build_date.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT build_date.obj -MD -MP -MF "$(DEPDIR)/build_date.Tpo" -c -o build_date.obj `if test -f '../build_date.c'; then $(CYGPATH_W) '../build_date.c'; else $(CYGPATH_W) '$(srcdir)/../build_date.c'; fi`; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/build_date.Tpo" "$(DEPDIR)/build_date.Po"; else rm -f "$(DEPDIR)/build_date.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='../build_date.c' object='build_date.obj' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o build_date.obj `if test -f '../build_date.c'; then $(CYGPATH_W) '../build_date.c'; else $(CYGPATH_W) '$(srcdir)/../build_date.c'; fi` ++ ++mostlyclean-libtool: ++ -rm -f *.lo ++ ++clean-libtool: ++ -rm -rf .libs _libs ++ ++distclean-libtool: ++ -rm -f libtool ++uninstall-info-am: ++ ++ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) ++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) ' { files[$$0] = 1; } \ ++ END { for (i in files) print i; }'`; \ ++ mkid -fID $$unique ++tags: TAGS ++ ++TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ ++ $(TAGS_FILES) $(LISP) ++ tags=; \ ++ here=`pwd`; \ ++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) ' { files[$$0] = 1; } \ ++ END { for (i in files) print i; }'`; \ ++ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ ++ test -n "$$unique" || unique=$$empty_fix; \ ++ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ ++ $$tags $$unique; \ ++ fi ++ctags: CTAGS ++CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ ++ $(TAGS_FILES) $(LISP) ++ tags=; \ ++ here=`pwd`; \ ++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) ' { files[$$0] = 1; } \ ++ END { for (i in files) print i; }'`; \ ++ test -z "$(CTAGS_ARGS)$$tags$$unique" \ ++ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ ++ $$tags $$unique ++ ++GTAGS: ++ here=`$(am__cd) $(top_builddir) && pwd` \ ++ && cd $(top_srcdir) \ ++ && gtags -i $(GTAGS_ARGS) $$here ++ ++distclean-tags: ++ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags ++ ++distdir: $(DISTFILES) ++ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ ++ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ ++ list='$(DISTFILES)'; for file in $$list; do \ ++ case $$file in \ ++ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ ++ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ ++ esac; \ ++ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ ++ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ ++ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ ++ dir="/$$dir"; \ ++ $(mkdir_p) "$(distdir)$$dir"; \ ++ else \ ++ dir=''; \ ++ fi; \ ++ if test -d $$d/$$file; then \ ++ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ ++ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ ++ fi; \ ++ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ ++ else \ ++ test -f $(distdir)/$$file \ ++ || cp -p $$d/$$file $(distdir)/$$file \ ++ || exit 1; \ ++ fi; \ ++ done ++check-am: all-am ++check: check-am ++all-am: Makefile $(LIBRARIES) ++installdirs: ++install: install-am ++install-exec: install-exec-am ++install-data: install-data-am ++uninstall: uninstall-am ++ ++install-am: all-am ++ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am ++ ++installcheck: installcheck-am ++install-strip: ++ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ ++ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ ++ `test -z '$(STRIP)' || \ ++ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install ++mostlyclean-generic: ++ ++clean-generic: ++ ++distclean-generic: ++ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) ++ ++maintainer-clean-generic: ++ @echo "This command is intended for maintainers to use" ++ @echo "it deletes files that may require special tools to rebuild." ++clean: clean-am ++ ++clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ ++ mostlyclean-am ++ ++distclean: distclean-am ++ -rm -rf ./$(DEPDIR) ++ -rm -f Makefile ++distclean-am: clean-am distclean-compile distclean-generic \ ++ distclean-libtool distclean-tags ++ ++dvi: dvi-am ++ ++dvi-am: ++ ++html: html-am ++ ++info: info-am ++ ++info-am: ++ ++install-data-am: ++ ++install-exec-am: ++ ++install-info: install-info-am ++ ++install-man: ++ ++installcheck-am: ++ ++maintainer-clean: maintainer-clean-am ++ -rm -rf ./$(DEPDIR) ++ -rm -f Makefile ++maintainer-clean-am: distclean-am maintainer-clean-generic ++ ++mostlyclean: mostlyclean-am ++ ++mostlyclean-am: mostlyclean-compile mostlyclean-generic \ ++ mostlyclean-libtool ++ ++pdf: pdf-am ++ ++pdf-am: ++ ++ps: ps-am ++ ++ps-am: ++ ++uninstall-am: uninstall-info-am ++ ++.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ ++ clean-libtool clean-noinstLIBRARIES ctags distclean \ ++ distclean-compile distclean-generic distclean-libtool \ ++ distclean-tags distdir dvi dvi-am html html-am info info-am \ ++ install install-am install-data install-data-am install-exec \ ++ install-exec-am install-info install-info-am install-man \ ++ install-strip installcheck installcheck-am installdirs \ ++ maintainer-clean maintainer-clean-generic mostlyclean \ ++ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ ++ pdf pdf-am ps ps-am tags uninstall uninstall-am \ ++ uninstall-info-am ++ ++# Tell versions [3.59,3.63) of GNU make to not export all variables. ++# Otherwise a system limit (for SysV at least) may be exceeded. ++.NOEXPORT: +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/logger.c open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/logger.c +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/logger.c 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/logger.c 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,181 @@ ++/* ++ * 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. ++ * ++ * 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) { ++ printf("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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/logger.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/logger.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/logger.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/logger.h 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,128 @@ ++/* ++ * 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. ++ * ++ * 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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/main.c open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/main.c +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/main.c 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/main.c 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,402 @@ ++/* ++ * 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. ++ * ++ * $Id: main.c,v 1.16 2006/06/11 21:55:03 adam Exp $ ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#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 char default_pid_filepath[] = "/var/run/iscsiuio.pid"; ++ ++/******************************************************************************* ++ * Global Variables ++ ******************************************************************************/ ++static const struct option long_options[] = { ++ {"debug", 0, 0, 0}, ++ {"version", 0, 0, 0}, ++ {"help", 0, 0, 0}, ++ {0, 0, 0, 0} ++}; ++ ++struct options opt = { ++ .debug = DEBUG_OFF, ++}; ++ ++int event_loop_stop = 0; ++ ++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"); ++retry: ++ fini_logger(SHUTDOWN_LOGGER); ++ rc = init_logger(main_log.log_file); ++ if (rc != 0) ++ printf("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 rc; ++ ++ fd = open("/dev/null", O_RDWR); ++ if (fd == -1) { ++ exit(-1); ++ } ++ ++ dup2(fd, 0); ++ dup2(fd, 1); ++ dup2(fd, 2); ++ setsid(); ++ rc = chdir("/"); ++} ++ ++#define ISCSI_OOM_PATH_LEN 48 ++ ++int oom_adjust(void) ++{ ++ int fd; ++ char path[ISCSI_OOM_PATH_LEN]; ++ struct stat statb; ++ ++ if (nice(-10) < 0) ++ LOG_DEBUG("Could not increase process priority: %s", ++ strerror(errno)); ++ ++ snprintf(path, ISCSI_OOM_PATH_LEN, "/proc/%d/oom_score_adj", getpid()); ++ if (stat(path, &statb)) { ++ /* older kernel so use old oom_adj file */ ++ snprintf(path, ISCSI_OOM_PATH_LEN, "/proc/%d/oom_adj", ++ getpid()); ++ } ++ fd = open(path, O_WRONLY); ++ if (fd < 0) ++ return -1; ++ if (write(fd, "-16", 3) < 0) /* for 2.6.11 */ ++ LOG_DEBUG("Could not set oom score to -16: %s", ++ strerror(errno)); ++ if (write(fd, "-17", 3) < 0) /* for Andrea's patch */ ++ LOG_DEBUG("Could not set oom score to -17: %s", ++ strerror(errno)); ++ close(fd); ++ return 0; ++} ++ ++ ++/******************************************************************************* ++ * Main routine ++ ******************************************************************************/ ++int main(int argc, char *argv[]) ++{ ++ int rc; ++ sigset_t set; ++ char *pid_file = default_pid_filepath; ++ int fd; ++ int foreground = 0; ++ pid_t pid; ++ ++ /* 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) ++ printf("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"); ++ } ++ ++ /* 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) { ++ printf("Unable to create pid file: %s", pid_file); ++ exit(1); ++ } ++ ++ pid = fork(); ++ if (pid < 0) { ++ printf("Starting daemon failed"); ++ exit(1); ++ } else if (pid) { ++ exit(0); ++ } ++ ++ rc = chdir("/"); ++ if (rc == -1) ++ printf("Unable to chdir(\") [%s]", strerror(errno)); ++ ++ if (lockf(fd, F_TLOCK, 0) < 0) { ++ printf("Unable to lock pid file: %s [%s]", ++ pid_file, strerror(errno)); ++ exit(1); ++ } ++ ++ rc = ftruncate(fd, 0); ++ if (rc == -1) ++ printf("ftruncate(%d, 0) failed [%s]", ++ fd, strerror(errno)); ++ ++ sprintf(buf, "%d\n", getpid()); ++ written_bytes = write(fd, buf, strlen(buf)); ++ if (written_bytes == -1) ++ printf("Could not write lock file [%s]", ++ strerror(errno)); ++ ++ 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 */ ++ rc = pthread_create(&signal_thread, NULL, 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; ++ } ++ ++ /* NetLink connection to listen to NETLINK_ISCSI private messages */ ++ nic_nl_open(); ++ ++error: ++ cleanup(); ++ exit(EXIT_FAILURE); ++} +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/Makefile.am open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/Makefile.am +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/Makefile.am 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/Makefile.am 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,38 @@ ++SUBDIRS= libs ++ ++INCLUDES = -I${top_srcdir}/src/uip \ ++ -I${top_srcdir}/src/apps/brcm-iscsi \ ++ -I${top_srcdir}/src/apps/dhcpc \ ++ -I${top_srcdir}/include \ ++ -I${top_srcdir}/src/unix/libs/ ++ ++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 ++ ++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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/Makefile.in open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/Makefile.in +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/Makefile.in 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/Makefile.in 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,766 @@ ++# Makefile.in generated by automake 1.9.6 from Makefile.am. ++# @configure_input@ ++ ++# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, ++# 2003, 2004, 2005 Free Software Foundation, Inc. ++# This Makefile.in is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY, to the extent permitted by law; without ++# even the implied warranty of MERCHANTABILITY or FITNESS FOR A ++# PARTICULAR PURPOSE. ++ ++@SET_MAKE@ ++ ++srcdir = @srcdir@ ++top_srcdir = @top_srcdir@ ++VPATH = @srcdir@ ++pkgdatadir = $(datadir)/@PACKAGE@ ++pkglibdir = $(libdir)/@PACKAGE@ ++pkgincludedir = $(includedir)/@PACKAGE@ ++top_builddir = ../.. ++am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd ++INSTALL = @INSTALL@ ++install_sh_DATA = $(install_sh) -c -m 644 ++install_sh_PROGRAM = $(install_sh) -c ++install_sh_SCRIPT = $(install_sh) -c ++INSTALL_HEADER = $(INSTALL_DATA) ++transform = $(program_transform_name) ++NORMAL_INSTALL = : ++PRE_INSTALL = : ++POST_INSTALL = : ++NORMAL_UNINSTALL = : ++PRE_UNINSTALL = : ++POST_UNINSTALL = : ++build_triplet = @build@ ++host_triplet = @host@ ++sbin_PROGRAMS = iscsiuio$(EXEEXT) ++subdir = src/unix ++DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ++ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 ++am__aclocal_m4_deps = $(top_srcdir)/configure.ac ++am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ ++ $(ACLOCAL_M4) ++mkinstalldirs = $(install_sh) -d ++CONFIG_HEADER = $(top_builddir)/config.h ++CONFIG_CLEAN_FILES = ++am__installdirs = "$(DESTDIR)$(sbindir)" ++sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM) ++PROGRAMS = $(sbin_PROGRAMS) ++am_iscsiuio_OBJECTS = iscsiuio-build_date.$(OBJEXT) \ ++ iscsiuio-main.$(OBJEXT) iscsiuio-clock-arch.$(OBJEXT) \ ++ iscsiuio-logger.$(OBJEXT) iscsiuio-nic.$(OBJEXT) \ ++ iscsiuio-nic_id.$(OBJEXT) iscsiuio-nic_vlan.$(OBJEXT) \ ++ iscsiuio-nic_nl.$(OBJEXT) iscsiuio-nic_utils.$(OBJEXT) \ ++ iscsiuio-packet.$(OBJEXT) iscsiuio-iscsid_ipc.$(OBJEXT) ++iscsiuio_OBJECTS = $(am_iscsiuio_OBJECTS) ++iscsiuio_DEPENDENCIES = ${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 ++DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) ++depcomp = $(SHELL) $(top_srcdir)/depcomp ++am__depfiles_maybe = depfiles ++COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ ++ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) ++LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ ++ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ ++ $(AM_CFLAGS) $(CFLAGS) ++CCLD = $(CC) ++LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ ++ $(AM_LDFLAGS) $(LDFLAGS) -o $@ ++SOURCES = $(iscsiuio_SOURCES) ++DIST_SOURCES = $(iscsiuio_SOURCES) ++RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ ++ html-recursive info-recursive install-data-recursive \ ++ install-exec-recursive install-info-recursive \ ++ install-recursive installcheck-recursive installdirs-recursive \ ++ pdf-recursive ps-recursive uninstall-info-recursive \ ++ uninstall-recursive ++ETAGS = etags ++CTAGS = ctags ++DIST_SUBDIRS = $(SUBDIRS) ++DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ++ACLOCAL = @ACLOCAL@ ++AMDEP_FALSE = @AMDEP_FALSE@ ++AMDEP_TRUE = @AMDEP_TRUE@ ++AMTAR = @AMTAR@ ++AR = @AR@ ++AUTOCONF = @AUTOCONF@ ++AUTOHEADER = @AUTOHEADER@ ++AUTOMAKE = @AUTOMAKE@ ++AWK = @AWK@ ++BASH = @BASH@ ++CC = @CC@ ++CCDEPMODE = @CCDEPMODE@ ++CFLAGS = @CFLAGS@ ++CPP = @CPP@ ++CPPFLAGS = @CPPFLAGS@ ++CXX = @CXX@ ++CXXCPP = @CXXCPP@ ++CXXDEPMODE = @CXXDEPMODE@ ++CXXFLAGS = @CXXFLAGS@ ++CYGPATH_W = @CYGPATH_W@ ++DEBUG_FALSE = @DEBUG_FALSE@ ++DEBUG_TRUE = @DEBUG_TRUE@ ++DEFS = @DEFS@ ++DEPDIR = @DEPDIR@ ++ECHO = @ECHO@ ++ECHO_C = @ECHO_C@ ++ECHO_N = @ECHO_N@ ++ECHO_T = @ECHO_T@ ++EGREP = @EGREP@ ++ENDIAN = @ENDIAN@ ++EXEEXT = @EXEEXT@ ++F77 = @F77@ ++FFLAGS = @FFLAGS@ ++INSTALL_DATA = @INSTALL_DATA@ ++INSTALL_PROGRAM = @INSTALL_PROGRAM@ ++INSTALL_SCRIPT = @INSTALL_SCRIPT@ ++INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ ++LDFLAGS = @LDFLAGS@ ++LIBOBJS = @LIBOBJS@ ++LIBS = @LIBS@ ++LIBTOOL = @LIBTOOL@ ++LN_S = @LN_S@ ++LTLIBOBJS = @LTLIBOBJS@ ++MAKEINFO = @MAKEINFO@ ++OBJEXT = @OBJEXT@ ++PACKAGE = @PACKAGE@ ++PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ ++PACKAGE_NAME = @PACKAGE_NAME@ ++PACKAGE_STRING = @PACKAGE_STRING@ ++PACKAGE_TARNAME = @PACKAGE_TARNAME@ ++PACKAGE_VERSION = @PACKAGE_VERSION@ ++PATH_SEPARATOR = @PATH_SEPARATOR@ ++RANLIB = @RANLIB@ ++SED = @SED@ ++SET_MAKE = @SET_MAKE@ ++SHELL = @SHELL@ ++STRIP = @STRIP@ ++VERSION = @VERSION@ ++ac_ct_AR = @ac_ct_AR@ ++ac_ct_CC = @ac_ct_CC@ ++ac_ct_CXX = @ac_ct_CXX@ ++ac_ct_F77 = @ac_ct_F77@ ++ac_ct_RANLIB = @ac_ct_RANLIB@ ++ac_ct_STRIP = @ac_ct_STRIP@ ++am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ ++am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ ++am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ ++am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ ++am__include = @am__include@ ++am__leading_dot = @am__leading_dot@ ++am__quote = @am__quote@ ++am__tar = @am__tar@ ++am__untar = @am__untar@ ++bindir = @bindir@ ++build = @build@ ++build_alias = @build_alias@ ++build_cpu = @build_cpu@ ++build_os = @build_os@ ++build_vendor = @build_vendor@ ++datadir = @datadir@ ++exec_prefix = @exec_prefix@ ++host = @host@ ++host_alias = @host_alias@ ++host_cpu = @host_cpu@ ++host_os = @host_os@ ++host_vendor = @host_vendor@ ++includedir = @includedir@ ++infodir = @infodir@ ++install_sh = @install_sh@ ++libdir = @libdir@ ++libexecdir = @libexecdir@ ++localstatedir = @localstatedir@ ++mandir = @mandir@ ++mkdir_p = @mkdir_p@ ++oldincludedir = @oldincludedir@ ++prefix = @prefix@ ++program_transform_name = @program_transform_name@ ++sbindir = @sbindir@ ++sharedstatedir = @sharedstatedir@ ++sysconfdir = @sysconfdir@ ++target_alias = @target_alias@ ++SUBDIRS = libs ++INCLUDES = -I${top_srcdir}/src/uip \ ++ -I${top_srcdir}/src/apps/brcm-iscsi \ ++ -I${top_srcdir}/src/apps/dhcpc \ ++ -I${top_srcdir}/include \ ++ -I${top_srcdir}/src/unix/libs/ ++ ++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 ++ ++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 ++all: all-recursive ++ ++.SUFFIXES: ++.SUFFIXES: .c .lo .o .obj ++$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) ++ @for dep in $?; do \ ++ case '$(am__configure_deps)' in \ ++ *$$dep*) \ ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ ++ && exit 0; \ ++ exit 1;; \ ++ esac; \ ++ done; \ ++ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/unix/Makefile'; \ ++ cd $(top_srcdir) && \ ++ $(AUTOMAKE) --gnu src/unix/Makefile ++.PRECIOUS: Makefile ++Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status ++ @case '$?' in \ ++ *config.status*) \ ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ ++ *) \ ++ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ ++ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ ++ esac; ++ ++$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++ ++$(top_srcdir)/configure: $(am__configure_deps) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++$(ACLOCAL_M4): $(am__aclocal_m4_deps) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++install-sbinPROGRAMS: $(sbin_PROGRAMS) ++ @$(NORMAL_INSTALL) ++ test -z "$(sbindir)" || $(mkdir_p) "$(DESTDIR)$(sbindir)" ++ @list='$(sbin_PROGRAMS)'; for p in $$list; do \ ++ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ ++ if test -f $$p \ ++ || test -f $$p1 \ ++ ; then \ ++ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ ++ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \ ++ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \ ++ else :; fi; \ ++ done ++ ++uninstall-sbinPROGRAMS: ++ @$(NORMAL_UNINSTALL) ++ @list='$(sbin_PROGRAMS)'; for p in $$list; do \ ++ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ ++ echo " rm -f '$(DESTDIR)$(sbindir)/$$f'"; \ ++ rm -f "$(DESTDIR)$(sbindir)/$$f"; \ ++ done ++ ++clean-sbinPROGRAMS: ++ @list='$(sbin_PROGRAMS)'; for p in $$list; do \ ++ f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ ++ echo " rm -f $$p $$f"; \ ++ rm -f $$p $$f ; \ ++ done ++iscsiuio$(EXEEXT): $(iscsiuio_OBJECTS) $(iscsiuio_DEPENDENCIES) ++ @rm -f iscsiuio$(EXEEXT) ++ $(LINK) $(iscsiuio_LDFLAGS) $(iscsiuio_OBJECTS) $(iscsiuio_LDADD) $(LIBS) ++ ++mostlyclean-compile: ++ -rm -f *.$(OBJEXT) ++ ++distclean-compile: ++ -rm -f *.tab.c ++ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iscsiuio-build_date.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iscsiuio-clock-arch.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iscsiuio-iscsid_ipc.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iscsiuio-logger.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iscsiuio-main.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iscsiuio-nic.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iscsiuio-nic_id.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iscsiuio-nic_nl.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iscsiuio-nic_utils.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iscsiuio-nic_vlan.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iscsiuio-packet.Po@am__quote@ ++ ++.c.o: ++@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(COMPILE) -c $< ++ ++.c.obj: ++@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` ++ ++.c.lo: ++@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< ++ ++iscsiuio-build_date.o: build_date.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iscsiuio_CFLAGS) $(CFLAGS) -MT iscsiuio-build_date.o -MD -MP -MF "$(DEPDIR)/iscsiuio-build_date.Tpo" -c -o iscsiuio-build_date.o `test -f 'build_date.c' || echo '$(srcdir)/'`build_date.c; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/iscsiuio-build_date.Tpo" "$(DEPDIR)/iscsiuio-build_date.Po"; else rm -f "$(DEPDIR)/iscsiuio-build_date.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='build_date.c' object='iscsiuio-build_date.o' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iscsiuio_CFLAGS) $(CFLAGS) -c -o iscsiuio-build_date.o `test -f 'build_date.c' || echo '$(srcdir)/'`build_date.c ++ ++iscsiuio-build_date.obj: build_date.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iscsiuio_CFLAGS) $(CFLAGS) -MT iscsiuio-build_date.obj -MD -MP -MF "$(DEPDIR)/iscsiuio-build_date.Tpo" -c -o iscsiuio-build_date.obj `if test -f 'build_date.c'; then $(CYGPATH_W) 'build_date.c'; else $(CYGPATH_W) '$(srcdir)/build_date.c'; fi`; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/iscsiuio-build_date.Tpo" "$(DEPDIR)/iscsiuio-build_date.Po"; else rm -f "$(DEPDIR)/iscsiuio-build_date.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='build_date.c' object='iscsiuio-build_date.obj' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iscsiuio_CFLAGS) $(CFLAGS) -c -o iscsiuio-build_date.obj `if test -f 'build_date.c'; then $(CYGPATH_W) 'build_date.c'; else $(CYGPATH_W) '$(srcdir)/build_date.c'; fi` ++ ++iscsiuio-main.o: main.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iscsiuio_CFLAGS) $(CFLAGS) -MT iscsiuio-main.o -MD -MP -MF "$(DEPDIR)/iscsiuio-main.Tpo" -c -o iscsiuio-main.o `test -f 'main.c' || echo '$(srcdir)/'`main.c; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/iscsiuio-main.Tpo" "$(DEPDIR)/iscsiuio-main.Po"; else rm -f "$(DEPDIR)/iscsiuio-main.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='main.c' object='iscsiuio-main.o' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iscsiuio_CFLAGS) $(CFLAGS) -c -o iscsiuio-main.o `test -f 'main.c' || echo '$(srcdir)/'`main.c ++ ++iscsiuio-main.obj: main.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iscsiuio_CFLAGS) $(CFLAGS) -MT iscsiuio-main.obj -MD -MP -MF "$(DEPDIR)/iscsiuio-main.Tpo" -c -o iscsiuio-main.obj `if test -f 'main.c'; then $(CYGPATH_W) 'main.c'; else $(CYGPATH_W) '$(srcdir)/main.c'; fi`; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/iscsiuio-main.Tpo" "$(DEPDIR)/iscsiuio-main.Po"; else rm -f "$(DEPDIR)/iscsiuio-main.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='main.c' object='iscsiuio-main.obj' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iscsiuio_CFLAGS) $(CFLAGS) -c -o iscsiuio-main.obj `if test -f 'main.c'; then $(CYGPATH_W) 'main.c'; else $(CYGPATH_W) '$(srcdir)/main.c'; fi` ++ ++iscsiuio-clock-arch.o: clock-arch.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iscsiuio_CFLAGS) $(CFLAGS) -MT iscsiuio-clock-arch.o -MD -MP -MF "$(DEPDIR)/iscsiuio-clock-arch.Tpo" -c -o iscsiuio-clock-arch.o `test -f 'clock-arch.c' || echo '$(srcdir)/'`clock-arch.c; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/iscsiuio-clock-arch.Tpo" "$(DEPDIR)/iscsiuio-clock-arch.Po"; else rm -f "$(DEPDIR)/iscsiuio-clock-arch.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='clock-arch.c' object='iscsiuio-clock-arch.o' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iscsiuio_CFLAGS) $(CFLAGS) -c -o iscsiuio-clock-arch.o `test -f 'clock-arch.c' || echo '$(srcdir)/'`clock-arch.c ++ ++iscsiuio-clock-arch.obj: clock-arch.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iscsiuio_CFLAGS) $(CFLAGS) -MT iscsiuio-clock-arch.obj -MD -MP -MF "$(DEPDIR)/iscsiuio-clock-arch.Tpo" -c -o iscsiuio-clock-arch.obj `if test -f 'clock-arch.c'; then $(CYGPATH_W) 'clock-arch.c'; else $(CYGPATH_W) '$(srcdir)/clock-arch.c'; fi`; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/iscsiuio-clock-arch.Tpo" "$(DEPDIR)/iscsiuio-clock-arch.Po"; else rm -f "$(DEPDIR)/iscsiuio-clock-arch.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='clock-arch.c' object='iscsiuio-clock-arch.obj' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iscsiuio_CFLAGS) $(CFLAGS) -c -o iscsiuio-clock-arch.obj `if test -f 'clock-arch.c'; then $(CYGPATH_W) 'clock-arch.c'; else $(CYGPATH_W) '$(srcdir)/clock-arch.c'; fi` ++ ++iscsiuio-logger.o: logger.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iscsiuio_CFLAGS) $(CFLAGS) -MT iscsiuio-logger.o -MD -MP -MF "$(DEPDIR)/iscsiuio-logger.Tpo" -c -o iscsiuio-logger.o `test -f 'logger.c' || echo '$(srcdir)/'`logger.c; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/iscsiuio-logger.Tpo" "$(DEPDIR)/iscsiuio-logger.Po"; else rm -f "$(DEPDIR)/iscsiuio-logger.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='logger.c' object='iscsiuio-logger.o' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iscsiuio_CFLAGS) $(CFLAGS) -c -o iscsiuio-logger.o `test -f 'logger.c' || echo '$(srcdir)/'`logger.c ++ ++iscsiuio-logger.obj: logger.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iscsiuio_CFLAGS) $(CFLAGS) -MT iscsiuio-logger.obj -MD -MP -MF "$(DEPDIR)/iscsiuio-logger.Tpo" -c -o iscsiuio-logger.obj `if test -f 'logger.c'; then $(CYGPATH_W) 'logger.c'; else $(CYGPATH_W) '$(srcdir)/logger.c'; fi`; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/iscsiuio-logger.Tpo" "$(DEPDIR)/iscsiuio-logger.Po"; else rm -f "$(DEPDIR)/iscsiuio-logger.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='logger.c' object='iscsiuio-logger.obj' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iscsiuio_CFLAGS) $(CFLAGS) -c -o iscsiuio-logger.obj `if test -f 'logger.c'; then $(CYGPATH_W) 'logger.c'; else $(CYGPATH_W) '$(srcdir)/logger.c'; fi` ++ ++iscsiuio-nic.o: nic.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iscsiuio_CFLAGS) $(CFLAGS) -MT iscsiuio-nic.o -MD -MP -MF "$(DEPDIR)/iscsiuio-nic.Tpo" -c -o iscsiuio-nic.o `test -f 'nic.c' || echo '$(srcdir)/'`nic.c; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/iscsiuio-nic.Tpo" "$(DEPDIR)/iscsiuio-nic.Po"; else rm -f "$(DEPDIR)/iscsiuio-nic.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nic.c' object='iscsiuio-nic.o' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iscsiuio_CFLAGS) $(CFLAGS) -c -o iscsiuio-nic.o `test -f 'nic.c' || echo '$(srcdir)/'`nic.c ++ ++iscsiuio-nic.obj: nic.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iscsiuio_CFLAGS) $(CFLAGS) -MT iscsiuio-nic.obj -MD -MP -MF "$(DEPDIR)/iscsiuio-nic.Tpo" -c -o iscsiuio-nic.obj `if test -f 'nic.c'; then $(CYGPATH_W) 'nic.c'; else $(CYGPATH_W) '$(srcdir)/nic.c'; fi`; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/iscsiuio-nic.Tpo" "$(DEPDIR)/iscsiuio-nic.Po"; else rm -f "$(DEPDIR)/iscsiuio-nic.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nic.c' object='iscsiuio-nic.obj' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iscsiuio_CFLAGS) $(CFLAGS) -c -o iscsiuio-nic.obj `if test -f 'nic.c'; then $(CYGPATH_W) 'nic.c'; else $(CYGPATH_W) '$(srcdir)/nic.c'; fi` ++ ++iscsiuio-nic_id.o: nic_id.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iscsiuio_CFLAGS) $(CFLAGS) -MT iscsiuio-nic_id.o -MD -MP -MF "$(DEPDIR)/iscsiuio-nic_id.Tpo" -c -o iscsiuio-nic_id.o `test -f 'nic_id.c' || echo '$(srcdir)/'`nic_id.c; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/iscsiuio-nic_id.Tpo" "$(DEPDIR)/iscsiuio-nic_id.Po"; else rm -f "$(DEPDIR)/iscsiuio-nic_id.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nic_id.c' object='iscsiuio-nic_id.o' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iscsiuio_CFLAGS) $(CFLAGS) -c -o iscsiuio-nic_id.o `test -f 'nic_id.c' || echo '$(srcdir)/'`nic_id.c ++ ++iscsiuio-nic_id.obj: nic_id.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iscsiuio_CFLAGS) $(CFLAGS) -MT iscsiuio-nic_id.obj -MD -MP -MF "$(DEPDIR)/iscsiuio-nic_id.Tpo" -c -o iscsiuio-nic_id.obj `if test -f 'nic_id.c'; then $(CYGPATH_W) 'nic_id.c'; else $(CYGPATH_W) '$(srcdir)/nic_id.c'; fi`; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/iscsiuio-nic_id.Tpo" "$(DEPDIR)/iscsiuio-nic_id.Po"; else rm -f "$(DEPDIR)/iscsiuio-nic_id.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nic_id.c' object='iscsiuio-nic_id.obj' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iscsiuio_CFLAGS) $(CFLAGS) -c -o iscsiuio-nic_id.obj `if test -f 'nic_id.c'; then $(CYGPATH_W) 'nic_id.c'; else $(CYGPATH_W) '$(srcdir)/nic_id.c'; fi` ++ ++iscsiuio-nic_vlan.o: nic_vlan.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iscsiuio_CFLAGS) $(CFLAGS) -MT iscsiuio-nic_vlan.o -MD -MP -MF "$(DEPDIR)/iscsiuio-nic_vlan.Tpo" -c -o iscsiuio-nic_vlan.o `test -f 'nic_vlan.c' || echo '$(srcdir)/'`nic_vlan.c; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/iscsiuio-nic_vlan.Tpo" "$(DEPDIR)/iscsiuio-nic_vlan.Po"; else rm -f "$(DEPDIR)/iscsiuio-nic_vlan.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nic_vlan.c' object='iscsiuio-nic_vlan.o' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iscsiuio_CFLAGS) $(CFLAGS) -c -o iscsiuio-nic_vlan.o `test -f 'nic_vlan.c' || echo '$(srcdir)/'`nic_vlan.c ++ ++iscsiuio-nic_vlan.obj: nic_vlan.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iscsiuio_CFLAGS) $(CFLAGS) -MT iscsiuio-nic_vlan.obj -MD -MP -MF "$(DEPDIR)/iscsiuio-nic_vlan.Tpo" -c -o iscsiuio-nic_vlan.obj `if test -f 'nic_vlan.c'; then $(CYGPATH_W) 'nic_vlan.c'; else $(CYGPATH_W) '$(srcdir)/nic_vlan.c'; fi`; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/iscsiuio-nic_vlan.Tpo" "$(DEPDIR)/iscsiuio-nic_vlan.Po"; else rm -f "$(DEPDIR)/iscsiuio-nic_vlan.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nic_vlan.c' object='iscsiuio-nic_vlan.obj' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iscsiuio_CFLAGS) $(CFLAGS) -c -o iscsiuio-nic_vlan.obj `if test -f 'nic_vlan.c'; then $(CYGPATH_W) 'nic_vlan.c'; else $(CYGPATH_W) '$(srcdir)/nic_vlan.c'; fi` ++ ++iscsiuio-nic_nl.o: nic_nl.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iscsiuio_CFLAGS) $(CFLAGS) -MT iscsiuio-nic_nl.o -MD -MP -MF "$(DEPDIR)/iscsiuio-nic_nl.Tpo" -c -o iscsiuio-nic_nl.o `test -f 'nic_nl.c' || echo '$(srcdir)/'`nic_nl.c; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/iscsiuio-nic_nl.Tpo" "$(DEPDIR)/iscsiuio-nic_nl.Po"; else rm -f "$(DEPDIR)/iscsiuio-nic_nl.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nic_nl.c' object='iscsiuio-nic_nl.o' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iscsiuio_CFLAGS) $(CFLAGS) -c -o iscsiuio-nic_nl.o `test -f 'nic_nl.c' || echo '$(srcdir)/'`nic_nl.c ++ ++iscsiuio-nic_nl.obj: nic_nl.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iscsiuio_CFLAGS) $(CFLAGS) -MT iscsiuio-nic_nl.obj -MD -MP -MF "$(DEPDIR)/iscsiuio-nic_nl.Tpo" -c -o iscsiuio-nic_nl.obj `if test -f 'nic_nl.c'; then $(CYGPATH_W) 'nic_nl.c'; else $(CYGPATH_W) '$(srcdir)/nic_nl.c'; fi`; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/iscsiuio-nic_nl.Tpo" "$(DEPDIR)/iscsiuio-nic_nl.Po"; else rm -f "$(DEPDIR)/iscsiuio-nic_nl.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nic_nl.c' object='iscsiuio-nic_nl.obj' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iscsiuio_CFLAGS) $(CFLAGS) -c -o iscsiuio-nic_nl.obj `if test -f 'nic_nl.c'; then $(CYGPATH_W) 'nic_nl.c'; else $(CYGPATH_W) '$(srcdir)/nic_nl.c'; fi` ++ ++iscsiuio-nic_utils.o: nic_utils.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iscsiuio_CFLAGS) $(CFLAGS) -MT iscsiuio-nic_utils.o -MD -MP -MF "$(DEPDIR)/iscsiuio-nic_utils.Tpo" -c -o iscsiuio-nic_utils.o `test -f 'nic_utils.c' || echo '$(srcdir)/'`nic_utils.c; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/iscsiuio-nic_utils.Tpo" "$(DEPDIR)/iscsiuio-nic_utils.Po"; else rm -f "$(DEPDIR)/iscsiuio-nic_utils.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nic_utils.c' object='iscsiuio-nic_utils.o' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iscsiuio_CFLAGS) $(CFLAGS) -c -o iscsiuio-nic_utils.o `test -f 'nic_utils.c' || echo '$(srcdir)/'`nic_utils.c ++ ++iscsiuio-nic_utils.obj: nic_utils.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iscsiuio_CFLAGS) $(CFLAGS) -MT iscsiuio-nic_utils.obj -MD -MP -MF "$(DEPDIR)/iscsiuio-nic_utils.Tpo" -c -o iscsiuio-nic_utils.obj `if test -f 'nic_utils.c'; then $(CYGPATH_W) 'nic_utils.c'; else $(CYGPATH_W) '$(srcdir)/nic_utils.c'; fi`; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/iscsiuio-nic_utils.Tpo" "$(DEPDIR)/iscsiuio-nic_utils.Po"; else rm -f "$(DEPDIR)/iscsiuio-nic_utils.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nic_utils.c' object='iscsiuio-nic_utils.obj' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iscsiuio_CFLAGS) $(CFLAGS) -c -o iscsiuio-nic_utils.obj `if test -f 'nic_utils.c'; then $(CYGPATH_W) 'nic_utils.c'; else $(CYGPATH_W) '$(srcdir)/nic_utils.c'; fi` ++ ++iscsiuio-packet.o: packet.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iscsiuio_CFLAGS) $(CFLAGS) -MT iscsiuio-packet.o -MD -MP -MF "$(DEPDIR)/iscsiuio-packet.Tpo" -c -o iscsiuio-packet.o `test -f 'packet.c' || echo '$(srcdir)/'`packet.c; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/iscsiuio-packet.Tpo" "$(DEPDIR)/iscsiuio-packet.Po"; else rm -f "$(DEPDIR)/iscsiuio-packet.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='packet.c' object='iscsiuio-packet.o' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iscsiuio_CFLAGS) $(CFLAGS) -c -o iscsiuio-packet.o `test -f 'packet.c' || echo '$(srcdir)/'`packet.c ++ ++iscsiuio-packet.obj: packet.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iscsiuio_CFLAGS) $(CFLAGS) -MT iscsiuio-packet.obj -MD -MP -MF "$(DEPDIR)/iscsiuio-packet.Tpo" -c -o iscsiuio-packet.obj `if test -f 'packet.c'; then $(CYGPATH_W) 'packet.c'; else $(CYGPATH_W) '$(srcdir)/packet.c'; fi`; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/iscsiuio-packet.Tpo" "$(DEPDIR)/iscsiuio-packet.Po"; else rm -f "$(DEPDIR)/iscsiuio-packet.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='packet.c' object='iscsiuio-packet.obj' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iscsiuio_CFLAGS) $(CFLAGS) -c -o iscsiuio-packet.obj `if test -f 'packet.c'; then $(CYGPATH_W) 'packet.c'; else $(CYGPATH_W) '$(srcdir)/packet.c'; fi` ++ ++iscsiuio-iscsid_ipc.o: iscsid_ipc.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iscsiuio_CFLAGS) $(CFLAGS) -MT iscsiuio-iscsid_ipc.o -MD -MP -MF "$(DEPDIR)/iscsiuio-iscsid_ipc.Tpo" -c -o iscsiuio-iscsid_ipc.o `test -f 'iscsid_ipc.c' || echo '$(srcdir)/'`iscsid_ipc.c; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/iscsiuio-iscsid_ipc.Tpo" "$(DEPDIR)/iscsiuio-iscsid_ipc.Po"; else rm -f "$(DEPDIR)/iscsiuio-iscsid_ipc.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='iscsid_ipc.c' object='iscsiuio-iscsid_ipc.o' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iscsiuio_CFLAGS) $(CFLAGS) -c -o iscsiuio-iscsid_ipc.o `test -f 'iscsid_ipc.c' || echo '$(srcdir)/'`iscsid_ipc.c ++ ++iscsiuio-iscsid_ipc.obj: iscsid_ipc.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iscsiuio_CFLAGS) $(CFLAGS) -MT iscsiuio-iscsid_ipc.obj -MD -MP -MF "$(DEPDIR)/iscsiuio-iscsid_ipc.Tpo" -c -o iscsiuio-iscsid_ipc.obj `if test -f 'iscsid_ipc.c'; then $(CYGPATH_W) 'iscsid_ipc.c'; else $(CYGPATH_W) '$(srcdir)/iscsid_ipc.c'; fi`; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/iscsiuio-iscsid_ipc.Tpo" "$(DEPDIR)/iscsiuio-iscsid_ipc.Po"; else rm -f "$(DEPDIR)/iscsiuio-iscsid_ipc.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='iscsid_ipc.c' object='iscsiuio-iscsid_ipc.obj' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iscsiuio_CFLAGS) $(CFLAGS) -c -o iscsiuio-iscsid_ipc.obj `if test -f 'iscsid_ipc.c'; then $(CYGPATH_W) 'iscsid_ipc.c'; else $(CYGPATH_W) '$(srcdir)/iscsid_ipc.c'; fi` ++ ++mostlyclean-libtool: ++ -rm -f *.lo ++ ++clean-libtool: ++ -rm -rf .libs _libs ++ ++distclean-libtool: ++ -rm -f libtool ++uninstall-info-am: ++ ++# This directory's subdirectories are mostly independent; you can cd ++# into them and run `make' without going through this Makefile. ++# To change the values of `make' variables: instead of editing Makefiles, ++# (1) if the variable is set in `config.status', edit `config.status' ++# (which will cause the Makefiles to be regenerated when you run `make'); ++# (2) otherwise, pass the desired values on the `make' command line. ++$(RECURSIVE_TARGETS): ++ @failcom='exit 1'; \ ++ for f in x $$MAKEFLAGS; do \ ++ case $$f in \ ++ *=* | --[!k]*);; \ ++ *k*) failcom='fail=yes';; \ ++ esac; \ ++ done; \ ++ dot_seen=no; \ ++ target=`echo $@ | sed s/-recursive//`; \ ++ list='$(SUBDIRS)'; for subdir in $$list; do \ ++ echo "Making $$target in $$subdir"; \ ++ if test "$$subdir" = "."; then \ ++ dot_seen=yes; \ ++ local_target="$$target-am"; \ ++ else \ ++ local_target="$$target"; \ ++ fi; \ ++ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ ++ || eval $$failcom; \ ++ done; \ ++ if test "$$dot_seen" = "no"; then \ ++ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ ++ fi; test -z "$$fail" ++ ++mostlyclean-recursive clean-recursive distclean-recursive \ ++maintainer-clean-recursive: ++ @failcom='exit 1'; \ ++ for f in x $$MAKEFLAGS; do \ ++ case $$f in \ ++ *=* | --[!k]*);; \ ++ *k*) failcom='fail=yes';; \ ++ esac; \ ++ done; \ ++ dot_seen=no; \ ++ case "$@" in \ ++ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ ++ *) list='$(SUBDIRS)' ;; \ ++ esac; \ ++ rev=''; for subdir in $$list; do \ ++ if test "$$subdir" = "."; then :; else \ ++ rev="$$subdir $$rev"; \ ++ fi; \ ++ done; \ ++ rev="$$rev ."; \ ++ target=`echo $@ | sed s/-recursive//`; \ ++ for subdir in $$rev; do \ ++ echo "Making $$target in $$subdir"; \ ++ if test "$$subdir" = "."; then \ ++ local_target="$$target-am"; \ ++ else \ ++ local_target="$$target"; \ ++ fi; \ ++ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ ++ || eval $$failcom; \ ++ done && test -z "$$fail" ++tags-recursive: ++ list='$(SUBDIRS)'; for subdir in $$list; do \ ++ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ ++ done ++ctags-recursive: ++ list='$(SUBDIRS)'; for subdir in $$list; do \ ++ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ ++ done ++ ++ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) ++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) ' { files[$$0] = 1; } \ ++ END { for (i in files) print i; }'`; \ ++ mkid -fID $$unique ++tags: TAGS ++ ++TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ ++ $(TAGS_FILES) $(LISP) ++ tags=; \ ++ here=`pwd`; \ ++ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ ++ include_option=--etags-include; \ ++ empty_fix=.; \ ++ else \ ++ include_option=--include; \ ++ empty_fix=; \ ++ fi; \ ++ list='$(SUBDIRS)'; for subdir in $$list; do \ ++ if test "$$subdir" = .; then :; else \ ++ test ! -f $$subdir/TAGS || \ ++ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ ++ fi; \ ++ done; \ ++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) ' { files[$$0] = 1; } \ ++ END { for (i in files) print i; }'`; \ ++ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ ++ test -n "$$unique" || unique=$$empty_fix; \ ++ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ ++ $$tags $$unique; \ ++ fi ++ctags: CTAGS ++CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ ++ $(TAGS_FILES) $(LISP) ++ tags=; \ ++ here=`pwd`; \ ++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) ' { files[$$0] = 1; } \ ++ END { for (i in files) print i; }'`; \ ++ test -z "$(CTAGS_ARGS)$$tags$$unique" \ ++ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ ++ $$tags $$unique ++ ++GTAGS: ++ here=`$(am__cd) $(top_builddir) && pwd` \ ++ && cd $(top_srcdir) \ ++ && gtags -i $(GTAGS_ARGS) $$here ++ ++distclean-tags: ++ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags ++ ++distdir: $(DISTFILES) ++ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ ++ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ ++ list='$(DISTFILES)'; for file in $$list; do \ ++ case $$file in \ ++ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ ++ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ ++ esac; \ ++ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ ++ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ ++ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ ++ dir="/$$dir"; \ ++ $(mkdir_p) "$(distdir)$$dir"; \ ++ else \ ++ dir=''; \ ++ fi; \ ++ if test -d $$d/$$file; then \ ++ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ ++ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ ++ fi; \ ++ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ ++ else \ ++ test -f $(distdir)/$$file \ ++ || cp -p $$d/$$file $(distdir)/$$file \ ++ || exit 1; \ ++ fi; \ ++ done ++ list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ ++ if test "$$subdir" = .; then :; else \ ++ test -d "$(distdir)/$$subdir" \ ++ || $(mkdir_p) "$(distdir)/$$subdir" \ ++ || exit 1; \ ++ distdir=`$(am__cd) $(distdir) && pwd`; \ ++ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ ++ (cd $$subdir && \ ++ $(MAKE) $(AM_MAKEFLAGS) \ ++ top_distdir="$$top_distdir" \ ++ distdir="$$distdir/$$subdir" \ ++ distdir) \ ++ || exit 1; \ ++ fi; \ ++ done ++check-am: all-am ++check: check-recursive ++all-am: Makefile $(PROGRAMS) ++installdirs: installdirs-recursive ++installdirs-am: ++ for dir in "$(DESTDIR)$(sbindir)"; do \ ++ test -z "$$dir" || $(mkdir_p) "$$dir"; \ ++ done ++install: install-recursive ++install-exec: install-exec-recursive ++install-data: install-data-recursive ++uninstall: uninstall-recursive ++ ++install-am: all-am ++ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am ++ ++installcheck: installcheck-recursive ++install-strip: ++ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ ++ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ ++ `test -z '$(STRIP)' || \ ++ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install ++mostlyclean-generic: ++ ++clean-generic: ++ ++distclean-generic: ++ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) ++ ++maintainer-clean-generic: ++ @echo "This command is intended for maintainers to use" ++ @echo "it deletes files that may require special tools to rebuild." ++clean: clean-recursive ++ ++clean-am: clean-generic clean-libtool clean-sbinPROGRAMS \ ++ mostlyclean-am ++ ++distclean: distclean-recursive ++ -rm -rf ./$(DEPDIR) ++ -rm -f Makefile ++distclean-am: clean-am distclean-compile distclean-generic \ ++ distclean-libtool distclean-tags ++ ++dvi: dvi-recursive ++ ++dvi-am: ++ ++html: html-recursive ++ ++info: info-recursive ++ ++info-am: ++ ++install-data-am: ++ ++install-exec-am: install-sbinPROGRAMS ++ ++install-info: install-info-recursive ++ ++install-man: ++ ++installcheck-am: ++ ++maintainer-clean: maintainer-clean-recursive ++ -rm -rf ./$(DEPDIR) ++ -rm -f Makefile ++maintainer-clean-am: distclean-am maintainer-clean-generic ++ ++mostlyclean: mostlyclean-recursive ++ ++mostlyclean-am: mostlyclean-compile mostlyclean-generic \ ++ mostlyclean-libtool ++ ++pdf: pdf-recursive ++ ++pdf-am: ++ ++ps: ps-recursive ++ ++ps-am: ++ ++uninstall-am: uninstall-info-am uninstall-sbinPROGRAMS ++ ++uninstall-info: uninstall-info-recursive ++ ++.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am \ ++ clean clean-generic clean-libtool clean-recursive \ ++ clean-sbinPROGRAMS ctags ctags-recursive distclean \ ++ distclean-compile distclean-generic distclean-libtool \ ++ distclean-recursive distclean-tags distdir dvi dvi-am html \ ++ html-am info info-am install install-am install-data \ ++ install-data-am install-exec install-exec-am install-info \ ++ install-info-am install-man install-sbinPROGRAMS install-strip \ ++ installcheck installcheck-am installdirs installdirs-am \ ++ maintainer-clean maintainer-clean-generic \ ++ maintainer-clean-recursive mostlyclean mostlyclean-compile \ ++ mostlyclean-generic mostlyclean-libtool mostlyclean-recursive \ ++ pdf pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \ ++ uninstall-info-am uninstall-sbinPROGRAMS ++ ++# Tell versions [3.59,3.63) of GNU make to not export all variables. ++# Otherwise a system limit (for SysV at least) may be exceeded. ++.NOEXPORT: +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/nic.c open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/nic.c +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/nic.c 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/nic.c 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,1653 @@ ++/* ++ * 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. ++ * ++ * 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" ++ ++/****************************************************************************** ++ * 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 = NULL; ++ ++/****************************************************************************** ++ * 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_pci_table == 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,}; ++ ++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) ++ 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_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) { ++ 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_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) { ++ 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; ++ ++ current->ops->lib_ops.get_pci_table(&pci_table, &entries); ++ ++ /* 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->next = NULL; ++ nic->thread = INVALID_THREAD; ++ nic->enable_thread = INVALID_THREAD; ++ nic->flags |= NIC_UNITIALIZED | NIC_DISABLED; ++ nic->state |= NIC_STOPPED; ++ nic->free_packet_queue = NULL; ++ nic->tx_packet_queue = NULL; ++ nic->nic_library = NULL; ++ nic->pci_id = NULL; ++ ++ 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; ++ ++ 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 ++ nic_list_mutex must be taken ++ * @param nic - the nic to remove ++ */ ++int nic_remove(nic_t * nic) ++{ ++ int rc; ++ nic_t *prev, *current; ++ struct stat file_stat; ++ void *res; ++ nic_interface_t *nic_iface, *next_nic_iface, *vlan_iface; ++ ++ pthread_mutex_lock(&nic->nic_mutex); ++ ++ /* Check if the file node exists before closing */ ++ rc = stat(nic->uio_device_name, &file_stat); ++ if ((rc == 0) && (nic->ops)) ++ nic->ops->close(nic, 0); ++ ++ nic->state = NIC_EXIT; ++ pthread_mutex_unlock(&nic->nic_mutex); ++ ++ if (nic->enable_thread != INVALID_THREAD) { ++ LOG_ERR(PFX "%s: Canceling nic enable thread", nic->log_name); ++ ++ rc = pthread_cancel(nic->enable_thread); ++ if (rc != 0) ++ LOG_ERR(PFX "%s: Couldn't send cancel to nic enable " ++ "thread", nic->log_name); ++ ++ LOG_ERR(PFX "%s: Waiting to join nic enable thread", ++ nic->log_name); ++ rc = pthread_join(nic->enable_thread, &res); ++ if (rc != 0) ++ LOG_ERR(PFX "%s: Couldn't join to canceled enable nic " ++ "thread", nic->log_name); ++ nic->enable_thread = INVALID_THREAD; ++ } ++ if (nic->thread != INVALID_THREAD) { ++ LOG_ERR(PFX "%s: Canceling nic thread", nic->log_name); ++ ++ rc = pthread_cancel(nic->thread); ++ if (rc != 0) ++ LOG_ERR(PFX "%s: Couldn't send cancel to nic", ++ nic->log_name); ++ ++ LOG_ERR(PFX "%s: Waiting to join nic thread", nic->log_name); ++ rc = pthread_join(nic->thread, &res); ++ if (rc != 0) ++ LOG_ERR(PFX "%s: Couldn't join to canceled nic thread", ++ nic->log_name); ++ ++ nic->thread = INVALID_THREAD; ++ } else { ++ LOG_ERR(PFX "%s: NIC 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 = nic->nic_iface; ++ while (nic_iface != NULL) { ++ vlan_iface = nic_iface->vlan_next; ++ while (vlan_iface != NULL) { ++ next_nic_iface = vlan_iface->vlan_next; ++ free(vlan_iface); ++ vlan_iface = next_nic_iface; ++ } ++ next_nic_iface = nic_iface->next; ++ free(nic_iface); ++ nic_iface = next_nic_iface; ++ } ++ 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; ++} ++ ++/** ++ * net_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; ++ ++ return nic_iface; ++} ++ ++/** ++ * nic_add_nic_iface() - This function is used to add an interface to the ++ * nic structure ++ * @param nic - struct nic device to add the interface to ++ * @param nic_iface - network interface used to add to the nic ++ * @return 0 on success, <0 on failure ++ */ ++int nic_add_nic_iface(nic_t * nic, nic_interface_t * nic_iface) ++{ ++ ++ pthread_mutex_lock(&nic->nic_mutex); ++ ++ /* Add the nic_interface */ ++ if (nic->nic_iface == NULL) { ++ nic->nic_iface = nic_iface; ++ } else { ++ nic_interface_t *current = nic->nic_iface; ++ ++ /* Check to see if this interface already exists via 2 ++ * conditions: 1) VLAN 2) protocol */ ++ while (current != NULL) { ++ if ((current->protocol == nic_iface->protocol) && ++ (current->vlan_id == nic_iface->vlan_id)) { ++ LOG_WARN(PFX "%s: nic interface alread exists" ++ "for VLAN: %d, protocol: %d", ++ nic->log_name, current->vlan_id, ++ current->protocol); ++ goto error; ++ } ++ current = current->next; ++ } ++ ++ /* This interface doesn't exists, we can safely add ++ * this nic interface */ ++ current = nic->nic_iface; ++ while (current->next != NULL) { ++ current = current->next; ++ } ++ ++ current->next = nic_iface; ++ } ++ ++ /* Set nic_interface common fields */ ++ nic_iface->parent = nic; ++ nic->num_of_nic_iface++; ++ ++ LOG_INFO(PFX "%s: Added nic interface for VLAN: %d, protocol: %d", ++ nic->log_name, nic_iface->vlan_id, nic_iface->protocol); ++ ++error: ++ pthread_mutex_unlock(&nic->nic_mutex); ++ ++ return 0; ++} ++ ++/** ++ * nic_add_vlan_iface() - This function is used to add a vlan interface to the ++ * nic structure ++ * @param nic - struct nic device to add the interface to ++ * @param nic_iface - network interface to be added to ++ * @param vlan_iface - vlan interface used to add to the nic_iface ++ * @return 0 on success, <0 on failure ++ */ ++int nic_add_vlan_iface(nic_t *nic, nic_interface_t *nic_iface, ++ nic_interface_t *vlan_iface) ++{ ++ pthread_mutex_lock(&nic->nic_mutex); ++ ++ /* Add the nic_interface */ ++ if (nic_iface == NULL) ++ goto error; ++ else { ++ nic_interface_t *current = nic_iface->vlan_next; ++ ++ /* Check to see if this interface already exists via 2 ++ * conditions: 1) VLAN 2) protocol */ ++ while (current != NULL) { ++ if ((current->protocol == vlan_iface->protocol) && ++ (current->vlan_id == vlan_iface->vlan_id)) { ++ LOG_WARN(PFX "%s: vlan interface already exists" ++ "for VLAN: %d, protocol: %d", ++ nic->log_name, current->vlan_id, ++ current->protocol); ++ goto error; ++ } ++ current = current->vlan_next; ++ } ++ ++ /* This interface doesn't exists, we can safely add ++ * this nic interface */ ++ current = nic_iface; ++ while (current->vlan_next != NULL) ++ current = current->vlan_next; ++ ++ current->vlan_next = vlan_iface; ++ } ++ ++ /* Set nic_interface common fields */ ++ vlan_iface->parent = nic; ++ nic->num_of_nic_iface++; ++ ++ LOG_INFO(PFX "%s: Added vlan interface for VLAN: %d, protocol: %d", ++ nic->log_name, vlan_iface->vlan_id, vlan_iface->protocol); ++ ++error: ++ pthread_mutex_unlock(&nic->nic_mutex); ++ ++ return 0; ++} ++/****************************************************************************** ++ * Routine to process interrupts from the NIC device ++ ******************************************************************************/ ++/** ++ * 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) != NIC_RUNNING) { ++ LOG_ERR(PFX "%s: Couldn't process interupt NIC not running", ++ nic->log_name); ++ return -EBUSY; ++ } ++ ++ if ((discard_check != 1) && (nic->fd == INVALID_FD)) { ++ 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; ++ if (nic->state & NIC_LONG_SLEEP) { ++ tv.tv_usec = 1000; ++ } else { ++ tv.tv_usec = nic->rx_poll_usec; ++ } ++ ++ /* 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_DEBUG(PFX "%s: interrupt count: %d prev: %d", ++ nic->log_name, count, nic->intr_count); ++ ++ if (count == nic->intr_count) { ++ LOG_WARN(PFX "%s: got interrupt but count still the " ++ "same", nic->log_name, count); ++ } ++ ++ /* Check if we missed an interrupt. With UIO, ++ * the count should be incremental */ ++ if (count != nic->intr_count + 1) { ++ nic->stats.missed_interrupts++; ++ LOG_DEBUG(PFX "%s: Missed interrupt! on %d not %d", ++ nic->log_name, count, nic->intr_count); ++ } ++ ++ nic->intr_count = count; ++ ++ (*nic->ops->clear_tx_intr) (nic); ++ ret = 1; ++ } ++ pthread_mutex_unlock(&nic->nic_mutex); ++ ++ return ret; ++} ++ ++static 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 (nic_iface->vlan_id && !(NIC_VLAN_STRIP_ENABLED & nic->flags)) ++ vlan_id = nic_iface->vlan_id; ++ ++ 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); ++ uip_build_arp_request(ustack, ipaddr); ++ break; ++ default: ++ LOG_ERR("Unknown arp state"); ++ break; ++ } ++} ++ ++static 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 (nic_iface->vlan_id && !(NIC_VLAN_STRIP_ENABLED & nic->flags)) ++ vlan_id = nic_iface->vlan_id; ++ ++ 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); ++ } ++} ++ ++static 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 */ ++ if ((nic_iface->vlan_id == 0) || (NIC_VLAN_STRIP_ENABLED & nic->flags)) { ++ ustack->network_layer = ustack->data_link_layer + ++ sizeof(struct uip_eth_hdr); ++ } else { ++ ustack->network_layer = ustack->data_link_layer + ++ sizeof(struct uip_vlan_eth_hdr); ++ } ++ /* Init buffer to be IPv6 */ ++ if (nic_iface->ustack.ip_config == IPV6_CONFIG_DHCP || ++ nic_iface->ustack.ip_config == IPV6_CONFIG_STATIC) { ++ eth = (struct ether_header *)ustack->data_link_layer; ++ eth->ether_type = UIP_ETHTYPE_IPv6; ++ } ++} ++ ++static int check_timers(nic_t * nic, ++ struct timer *periodic_timer, struct timer *arp_timer) ++{ ++ if (timer_expired(periodic_timer)) { ++ int i; ++ nic_interface_t *current; ++ ++ timer_reset(periodic_timer); ++ ++ pthread_mutex_lock(&nic->nic_mutex); ++ ++ current = nic->nic_iface; ++ while (current != NULL) { ++ packet_t *pkt; ++ struct uip_stack *ustack = ¤t->ustack; ++ ++ pkt = get_next_free_packet(nic); ++ if (pkt == NULL) { ++ current = current->next; ++ continue; ++ } ++ ++ for (i = 0; i < UIP_UDP_CONNS; i++) { ++ prepare_ustack(nic, current, ustack, pkt); ++ ++ uip_udp_periodic(ustack, i); ++ /* If the above function invocation resulted ++ * in data that should be sent out on the ++ * network, the global variable uip_len is ++ * set to a value > 0. */ ++ if (ustack->uip_len > 0) { ++ pkt->buf_size = ustack->uip_len; ++ ++ prepare_ipv4_packet(nic, ++ current, ++ ustack, pkt); ++ ++ (*nic->ops->write) (nic, current, pkt); ++ ustack->uip_len = 0; ++ } ++ } ++ ++ /* Added periodic poll for IPv6 NDP engine */ ++ if (ustack->ndpc != NULL) { /* If engine is active */ ++ prepare_ustack(nic, current, ustack, pkt); ++ ++ uip_ndp_periodic(ustack); ++ /* If the above function invocation resulted ++ * in data that should be sent out on the ++ * network, the global variable uip_len is ++ * set to a value > 0. */ ++ if (ustack->uip_len > 0) { ++ pkt->buf_size = ustack->uip_len; ++ prepare_ipv6_packet(nic, ++ current, ++ ustack, pkt); ++ (*nic->ops->write) (nic, current, pkt); ++ ustack->uip_len = 0; ++ } ++ } ++ ++ /* 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); ++ ++ current = current->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; ++ nic_interface_t *vlan_iface; ++ ++ if ((pkt->vlan_tag == 0) || ++ (NIC_VLAN_STRIP_ENABLED & nic->flags)) { ++ type = ntohs(ETH_BUF(pkt->buf)->type); ++ } else { ++ type = ntohs(VLAN_ETH_BUF(pkt->buf)->type); ++ } ++ ++ switch (type) { ++ case UIP_ETHTYPE_IPv6: ++ af_type = AF_INET6; ++ break; ++ case UIP_ETHTYPE_IPv4: ++ af_type = AF_INET; ++ break; ++ case UIP_ETHTYPE_ARP: ++ af_type = AF_INET; ++ break; ++ default: ++ LOG_DEBUG(PFX "%s: Ignoring vlan:0x%x ethertype:0x%x", ++ nic->log_name, pkt->vlan_tag, type); ++ goto done; ++ } ++ ++ /* check if we have the given VLAN interface */ ++ if (nic_iface == NULL) { ++ nic_iface = nic_find_nic_iface_protocol(nic, 0, ++ af_type); ++ if (nic_iface == NULL) { ++ LOG_INFO(PFX "%s: Couldn't find interface for " ++ "VLAN: %d af_type %d creating it", ++ nic->log_name, pkt->vlan_tag, af_type); ++ ++ /* Create the vlan interface */ ++ nic_iface = nic_iface_init(); ++ ++ if (nic_iface == NULL) { ++ LOG_WARN(PFX "%s: Couldn't " ++ "allocate " ++ "nic_iface for " ++ "VLAN: %d af_type %d", ++ nic->log_name, pkt->vlan_tag, ++ af_type); ++ rc = 0; ++ goto done; ++ } ++ ++ nic_iface->protocol = af_type; ++ nic_iface->vlan_id = 0; ++ nic_add_nic_iface(nic, nic_iface); ++ ++ persist_all_nic_iface(nic); ++ } ++ if (pkt->vlan_tag) { ++ vlan_iface = nic_find_vlan_iface_protocol(nic, ++ nic_iface, pkt->vlan_tag, ++ af_type); ++ if (vlan_iface == NULL) { ++ LOG_INFO(PFX "%s couldn't find " ++ "interface with VLAN =" ++ " %d ip_type: 0x%x " ++ "creating it", ++ nic->log_name, pkt->vlan_tag, ++ af_type); ++ ++ /* Create the nic interface */ ++ vlan_iface = nic_iface_init(); ++ ++ if (vlan_iface == NULL) { ++ LOG_ERR(PFX "Couldn't allocate " ++ "nic_iface for VLAN: %d", ++ vlan_iface, ++ pkt->vlan_tag); ++ rc = 0; ++ goto done; ++ } ++ vlan_iface->protocol = af_type; ++ vlan_iface->vlan_id = pkt->vlan_tag; ++ nic_add_vlan_iface(nic, nic_iface, ++ vlan_iface); ++ /* TODO: When VLAN support is placed */ ++ /* in the iface file revisit this */ ++ /* code */ ++ memcpy(vlan_iface->ustack.hostaddr, ++ nic_iface->ustack.hostaddr, ++ sizeof(nic_iface->ustack.hostaddr)); ++ memcpy(vlan_iface->ustack.netmask, ++ nic_iface->ustack.netmask, ++ sizeof(nic_iface->ustack.netmask)); ++ memcpy(vlan_iface->ustack.netmask6, ++ nic_iface->ustack.netmask6, ++ sizeof(nic_iface->ustack.netmask6)); ++ memcpy(vlan_iface->ustack.hostaddr6, ++ nic_iface->ustack.hostaddr6, ++ sizeof(nic_iface->ustack.hostaddr6)); ++ ++ persist_all_nic_iface(nic); ++ } ++ nic_iface = vlan_iface; ++ } ++ } ++ ++ pkt->nic_iface = nic_iface; ++ ++ ustack = &nic_iface->ustack; ++ ++ ustack->uip_buf = pkt->buf; ++ ustack->uip_len = pkt->buf_size; ++ ustack->data_link_layer = pkt->buf; ++ ++ pkt->data_link_layer = pkt->buf; ++ ++ /* Adjust the network layer pointer depending if there is a ++ * VLAN tag or not, or if the hardware has stripped out the ++ * VLAN tag */ ++ if ((pkt->vlan_tag == 0) || ++ (NIC_VLAN_STRIP_ENABLED & nic->flags)) { ++ ustack->network_layer = ustack->data_link_layer + ++ sizeof(struct uip_eth_hdr); ++ pkt->network_layer = pkt->data_link_layer + ++ sizeof(struct uip_eth_hdr); ++ type = ntohs(ETH_BUF(pkt->buf)->type); ++ } else { ++ ustack->network_layer = ustack->data_link_layer + ++ sizeof(struct uip_vlan_eth_hdr); ++ pkt->network_layer = pkt->data_link_layer + ++ sizeof(struct uip_vlan_eth_hdr); ++ type = ntohs(VLAN_ETH_BUF(pkt->buf)->type); ++ } ++ ++ pthread_mutex_lock(&nic->nic_mutex); ++ /* determine how we should process this packet based on the ++ * ethernet type */ ++ switch (type) { ++ 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) { ++ prepare_ipv4_packet(nic, nic_iface, ++ ustack, pkt); ++ ++ (*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) { ++ (*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", ++ nic->log_name); ++ return -EIO; ++ } ++ } ++ ++ if (nic->flags & NIC_GOING_DOWN) ++ return -EIO; ++ else ++ return 0; ++} ++ ++void *nic_loop(void *arg) ++{ ++ nic_t *nic = (nic_t *) arg; ++ int rc = -1; ++ struct timer periodic_timer, arp_timer; ++ sigset_t set; ++ void *res; ++ ++ 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); ++ ++ while ((event_loop_stop == 0) && ++ !(nic->flags & NIC_EXIT_MAIN_LOOP) && ++ !(nic->flags & NIC_GOING_DOWN)) { ++ nic_interface_t *nic_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); ++ } ++ pthread_mutex_unlock(&nic->nic_mutex); ++ ++ /* 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); ++ ++ 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); ++ pthread_mutex_unlock(&nic->nic_mutex); ++ goto dev_close; ++ } ++ } ++ /* Indication for the nic_disable routine that the nic ++ has started running */ ++ nic->state |= NIC_STARTED_RUNNING; ++ ++ /* 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); ++ ++ nic_iface = nic->nic_iface; ++ while (nic_iface != NULL) { ++ uip_init(&nic_iface->ustack, ++ nic->flags & NIC_IPv6_ENABLED); ++ memcpy(&nic_iface->ustack.uip_ethaddr.addr, ++ nic->mac_addr, 6); ++ ++ LOG_INFO(PFX "%s: Initialized ip stack: VLAN: %d", ++ nic->log_name, nic_iface->vlan_id); ++ ++ LOG_INFO(PFX "%s: mac: %02x:%02x:%02x:%02x:%02x:%02x", ++ nic->log_name, ++ nic_iface->mac_addr[0], ++ nic_iface->mac_addr[1], ++ nic_iface->mac_addr[2], ++ nic_iface->mac_addr[3], ++ nic_iface->mac_addr[4], ++ nic_iface->mac_addr[5]); ++ ++ if (nic_iface->ustack.ip_config == IPV4_CONFIG_STATIC) { ++ struct in_addr addr; ++ uip_ip4addr_t tmp = { 0, 0 }; ++ ++ memcpy(&addr.s_addr, nic_iface->ustack.hostaddr, ++ sizeof(addr.s_addr)); ++ ++ LOG_INFO(PFX "%s: Using IP address: %s", ++ nic->log_name, inet_ntoa(addr)); ++ ++ memcpy(&addr.s_addr, nic_iface->ustack.netmask, ++ sizeof(addr.s_addr)); ++ ++ LOG_INFO(PFX "%s: Using netmask: %s", ++ nic->log_name, inet_ntoa(addr)); ++ ++ set_uip_stack(&nic_iface->ustack, ++ &nic_iface->ustack.hostaddr, ++ &nic_iface->ustack.netmask, ++ &tmp, nic_iface->mac_addr); ++ ++ } else if (nic_iface->ustack.ip_config == ++ IPV4_CONFIG_DHCP) { ++ struct uip_stack *ustack = &nic_iface->ustack; ++ uip_ip4addr_t tmp = { 0, 0 }; ++ ++ set_uip_stack(&nic_iface->ustack, ++ &nic_iface->ustack.hostaddr, ++ &nic_iface->ustack.netmask, ++ &tmp, nic_iface->mac_addr); ++ if (dhcpc_init(nic, ustack, ++ nic_iface->mac_addr, ETH_ALEN)) { ++ if (ustack->dhcpc) { ++ LOG_DEBUG(PFX "%s: DHCPv4 " ++ "engine already " ++ "initialized!", ++ nic->log_name); ++ goto skip; ++ } else { ++ LOG_DEBUG(PFX "%s: DHCPv4 " ++ "engine failed " ++ "initialization!", ++ nic->log_name); ++ goto dev_close_free; ++ } ++ } ++ pthread_mutex_unlock(&nic->nic_mutex); ++ rc = process_dhcp_loop(nic, nic_iface, ++ &periodic_timer, ++ &arp_timer); ++ pthread_mutex_lock(&nic->nic_mutex); ++ ++ if (rc) { ++ LOG_ERR(PFX "%s: DHCP failed", ++ nic->log_name); ++ nic->flags |= NIC_DISABLED | ++ NIC_RESET_UIP; ++ nic->flags &= ~NIC_ENABLED; ++ /* Signal that the device enable is ++ done */ ++ pthread_cond_broadcast( ++ &nic->enable_done_cond); ++ ++ pthread_mutex_unlock(&nic->nic_mutex); ++ ++ if (nic->enable_thread == ++ INVALID_THREAD) ++ goto dev_close_free; ++ ++ rc = pthread_join(nic->enable_thread, ++ &res); ++ if (rc != 0) ++ LOG_ERR(PFX "%s: Couldn't join " ++ "to canceled enable nic" ++ " thread", ++ nic->log_name); ++ ++ goto dev_close_free; ++ } ++ ++ if (nic->flags & NIC_DISABLED) { ++ pthread_mutex_unlock(&nic->nic_mutex); ++ break; ++ } ++ ++ LOG_INFO(PFX "%s: Initialized dhcp client", ++ nic->log_name); ++ } else if (nic_iface->ustack.ip_config == ++ IPV6_CONFIG_DHCP || ++ nic_iface->ustack.ip_config == ++ IPV6_CONFIG_STATIC) { ++ struct in6_addr addr6; ++ char buf[INET6_ADDRSTRLEN]; ++ ++ /* Do router solicitation for both STATIC and ++ DHCP - all NDP handling will take place in ++ the DHCP loop ++ STATIC - router advertisement will be handled ++ in the uip background loop ++ */ ++ if (ndpc_init(nic, &nic_iface->ustack, ++ nic_iface->mac_addr, ETH_ALEN)) { ++ LOG_DEBUG(PFX "%s: IPv6 engine already" ++ "initialized!", ++ nic->log_name); ++ goto skip; ++ } ++ if (nic_iface->ustack.ip_config == ++ IPV6_CONFIG_DHCP) { ++ pthread_mutex_unlock(&nic->nic_mutex); ++ rc = process_dhcp_loop(nic, nic_iface, ++ &periodic_timer, ++ &arp_timer); ++ pthread_mutex_lock(&nic->nic_mutex); ++ if (rc) { ++ /* Don't reset and allow to ++ use RA and LL */ ++ LOG_ERR(PFX "%s: DHCPv6 failed", ++ nic->log_name); ++ } ++ if (nic->flags & NIC_DISABLED) { ++ pthread_mutex_unlock(&nic-> ++ nic_mutex); ++ break; ++ } ++ } else { ++ pthread_mutex_unlock(&nic->nic_mutex); ++ rc = process_dhcp_loop(nic, nic_iface, ++ &periodic_timer, ++ &arp_timer); ++ pthread_mutex_lock(&nic->nic_mutex); ++ if (rc) { ++ LOG_ERR(PFX "%s: IPv6 rtr " ++ "failed", ++ nic->log_name); ++ } ++ memcpy(&addr6.s6_addr, ++ nic_iface->ustack.hostaddr6, ++ sizeof(addr6.s6_addr)); ++ inet_ntop(AF_INET6, ++ addr6.s6_addr, ++ buf, sizeof(buf)); ++ LOG_INFO(PFX "%s: hostaddr IP: %s", ++ nic->log_name, buf); ++ ++ memcpy(&addr6.s6_addr, ++ nic_iface->ustack.netmask6, ++ sizeof(addr6.s6_addr)); ++ inet_ntop(AF_INET6, ++ addr6.s6_addr, ++ buf, sizeof(buf)); ++ LOG_INFO(PFX "%s: netmask IP: %s", ++ nic->log_name, buf); ++ } ++ } else { ++ LOG_INFO(PFX "%s: ipconfig = %d?", ++ nic->log_name, ++ nic_iface->ustack.ip_config); ++ } ++skip: ++ LOG_INFO(PFX "%s: enabled vlan %d protocol: %d", ++ nic->log_name, ++ nic_iface->vlan_id, nic_iface->protocol); ++ ++ nic_iface = nic_iface->vlan_next; ++ } ++ ++ 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->flags &= ~NIC_UNITIALIZED; ++ nic->flags |= NIC_INITIALIZED; ++ nic->state &= ~NIC_STOPPED; ++ nic->state |= NIC_RUNNING; ++ ++ nic->flags &= ~NIC_ENABLED_PENDING; ++ ++ /* Signal that the device enable is done */ ++ pthread_cond_broadcast(&nic->enable_done_cond); ++ pthread_mutex_unlock(&nic->nic_mutex); ++ ++ 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)) { ++ /* 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); ++ } ++ } ++ ++ LOG_INFO(PFX "%s: exited main processing loop", nic->log_name); ++ ++dev_close_free: ++ free_free_queue(nic); ++dev_close: ++ pthread_mutex_lock(&nic->nic_mutex); ++ ++ 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); ++ ++ if (nic->flags & NIC_RESET_UIP) { ++ nic_interface_t *nic_iface = nic->nic_iface; ++ nic_interface_t *vlan_iface; ++ while (nic_iface != NULL) { ++ LOG_INFO(PFX "%s: resetting uIP stack", ++ nic->log_name); ++ uip_reset(&nic_iface->ustack); ++ vlan_iface = nic_iface->vlan_next; ++ while (vlan_iface != NULL) { ++ LOG_INFO(PFX "%s: resetting " ++ "vlan uIP stack", ++ nic->log_name); ++ uip_reset(&vlan_iface->ustack); ++ vlan_iface = ++ vlan_iface->vlan_next; ++ } ++ nic_iface = nic_iface->next; ++ } ++ nic->flags &= ~NIC_RESET_UIP; ++ } ++ } ++ ++ nic->flags |= NIC_UNITIALIZED; ++ nic->flags &= ~NIC_INITIALIZED; ++ nic->flags &= ~NIC_ENABLED_PENDING; ++ ++ nic->pending_count = 0; ++ ++ if (!(nic->flags & NIC_EXIT_MAIN_LOOP)) { ++ /* Signal we are done closing CNIC/UIO device */ ++ pthread_cond_broadcast(&nic->disable_wait_cond); ++ } ++ } ++ 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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/nic.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/nic.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/nic.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/nic.h 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,359 @@ ++/* ++ * 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. ++ * ++ * 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 "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; ++ ++/******************************************************************************* ++ * 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 *next; ++ struct nic *parent; ++ ++ uint16_t protocol; ++ uint16_t flags; ++#define NIC_IFACE_PERSIST 0x0001 ++ uint8_t mac_addr[ETH_ALEN]; ++ uint8_t vlan_priority; ++ uint16_t vlan_id; ++ ++ time_t start_time; ++ ++ struct uip_stack ustack; ++ struct nic_interface *vlan_next; ++} 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); ++} 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_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_LONG_SLEEP 0x0008 ++#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 */ ++ ++ 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; ++ ++#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; ++} 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_add_vlan_iface(nic_t *nic, nic_interface_t *nic_iface, ++ nic_interface_t *vlan_iface); ++int nic_process_intr(nic_t *nic, int discard_check); ++ ++nic_interface_t *nic_iface_init(); ++ ++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_LIBRARY_EXIST_T does_nic_library_exist(char *name); ++ ++/******************************************************************************* ++ * 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); ++struct nic_interface *nic_find_nic_iface(nic_t * nic, uint16_t vlan_id); ++struct nic_interface *nic_find_nic_iface_protocol(nic_t * nic, ++ uint16_t vlan_id, ++ uint16_t protocol); ++struct nic_interface *nic_find_vlan_iface_protocol(nic_t *nic, ++ nic_interface_t *nic_iface, ++ uint16_t vlan_id, ++ uint16_t protocol); ++int find_nic_lib_using_pci_id(uint32_t vendor, uint32_t device, ++ uint32_t subvendor, uint32_t subdevice, ++ nic_lib_handle_t ** handle, ++ struct pci_device_id **pci_entry); ++ ++void *nic_loop(void *arg); ++ ++int nic_packet_capture(struct nic *, struct packet *pkt); ++ ++#endif /* __NIC_H__ */ +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/nic_id.c open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/nic_id.c +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/nic_id.c 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/nic_id.c 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,364 @@ ++/* ++ * 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. ++ * ++ * nic_id.c - Using sysfs to determine the PCI vendor, device, subvendor and ++ * subdevice ID's ++ * ++ */ ++#include ++#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; ++ ++ 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; ++ ++ return 0; ++} +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/nic_id.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/nic_id.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/nic_id.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/nic_id.h 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,46 @@ ++/* ++ * 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. ++ * ++ * 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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/nic_nl.c open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/nic_nl.c +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/nic_nl.c 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/nic_nl.c 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,627 @@ ++/* ++ * 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. ++ * ++ * 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; ++ ++const static 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; ++ ++/* Items used to handle the thread used to send/process ARP's */ ++static pthread_t nl_process_thread; ++static pthread_cond_t nl_process_cond; ++pthread_cond_t nl_process_if_down_cond; ++pthread_mutex_t nl_process_mutex; ++int nl_process_if_down = 0; ++ ++#define NL_PROCESS_MAX_RING_SIZE 128 ++#define NL_PROCESS_LAST_ENTRY NL_PROCESS_MAX_RING_SIZE - 1 ++#define NL_PROCESS_NEXT_ENTRY(x) ((x + 1) & NL_PROCESS_MAX_RING_SIZE) ++static int nl_process_head; ++static int nl_process_tail; ++static void *nl_process_ring[NL_PROCESS_MAX_RING_SIZE]; ++ ++#define MAX_TX_DESC_CNT (TX_DESC_CNT - 1) ++ ++#define NEXT_TX_BD(x) (((x) & (MAX_TX_DESC_CNT - 1)) == \ ++ (MAX_TX_DESC_CNT - 1)) ? ++ ++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; ++ char nlm_ev[NLMSG_SPACE(sizeof(struct iscsi_uevent))]; ++ struct nlmsghdr *nlh; ++ char *data = NULL; ++ ++ /* 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; ++ } ++ ++ data = (char *)malloc(nlh->nlmsg_len); ++ if (unlikely(data == NULL)) { ++ LOG_ERR(PFX "Couldn't allocate %d bytes for Netlink " ++ "iSCSI message", nlh->nlmsg_len); ++ return -ENOMEM; ++ } ++ ++ memset(data, 0, nlh->nlmsg_len); ++ ev_size = nlh->nlmsg_len - NLMSG_ALIGN(sizeof(struct nlmsghdr)); ++ rc = nl_read(nl_sock, data, (int)nlh->nlmsg_len, MSG_WAITALL); ++ if (rc <= 0) { ++ 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; ++} ++ ++const static struct timespec ctldev_sleep_req = { ++ .tv_sec = 0, ++ .tv_nsec = 250000000, ++}; ++ ++static int ctldev_handle(char *data) ++{ ++ nic_t *nic = NULL; ++ int rc; ++ struct iscsi_uevent *ev; ++ uint8_t *payload; ++ struct iscsi_path *path; ++ char *msg_type_str; ++ uint32_t host_no; ++ int i; ++ ++ ev = (struct iscsi_uevent *)NLMSG_DATA(data); ++ switch (ev->type) { ++ case ISCSI_KEVENT_PATH_REQ: ++ msg_type_str = "path_req"; ++ ++ host_no = ev->r.req_path.host_no; ++ break; ++ case ISCSI_KEVENT_IF_DOWN: ++ msg_type_str = "if_down"; ++ ++ host_no = ev->r.notify_if_down.host_no; ++ break; ++ default: ++ /* We don't care about other iSCSI Netlink messages */ ++ 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("Received: '%s': host_no: %d", msg_type_str, host_no); ++ ++ rc = from_host_no_find_associated_eth_device(host_no, &nic); ++ if (rc != 0) { ++ LOG_ERR(PFX "Dropping msg, couldn't find nic with host no:%d", ++ host_no); ++ goto error; ++ } ++ ++ payload = (uint8_t *) ((uint8_t *) ev) + sizeof(*ev); ++ path = (struct iscsi_path *)payload; ++ ++ if (ev->type == ISCSI_KEVENT_PATH_REQ) { ++ struct timespec sleep_rem; ++ nic_interface_t *nic_iface, *vlan_iface; ++ uint16_t ip_type; ++ ++ 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; ++ ++ /* Find the parent nic_iface */ ++ nic_iface = nic_find_nic_iface_protocol(nic, 0, ip_type); ++ if (nic_iface == NULL) { ++ LOG_ERR(PFX "%s: Couldn't find nic iface " ++ "vlan: %d ip_type: %d " ++ "ip_addr_len: %d to clone", ++ nic->log_name, path->vlan_id, ip_type, ++ path->ip_addr_len); ++ goto error; ++ } ++ if (path->vlan_id) { ++ vlan_iface = nic_find_vlan_iface_protocol(nic, ++ nic_iface, path->vlan_id, ip_type); ++ if (vlan_iface == NULL) { ++ /* Create a vlan_iface */ ++ vlan_iface = nic_iface_init(); ++ if (vlan_iface == NULL) { ++ LOG_ERR(PFX "%s: Couldn't allocate " ++ "space for vlan: %d ip_type: " ++ "%d ip_addr_len: %d", ++ nic->log_name, path->vlan_id, ++ ip_type, path->ip_addr_len); ++ goto error; ++ } ++ ++ vlan_iface->protocol = ip_type; ++ vlan_iface->vlan_id = path->vlan_id; ++ nic_add_vlan_iface(nic, nic_iface, vlan_iface); ++ ++ /* TODO: When VLAN support is placed in */ ++ /* the iface file revisit this code */ ++ vlan_iface->ustack.ip_config = ++ nic_iface->ustack.ip_config; ++ memcpy(vlan_iface->ustack.hostaddr, ++ nic_iface->ustack.hostaddr, ++ sizeof(nic_iface->ustack.hostaddr)); ++ memcpy(vlan_iface->ustack.netmask, ++ nic_iface->ustack.netmask, ++ sizeof(nic_iface->ustack.netmask)); ++ memcpy(vlan_iface->ustack.netmask6, ++ nic_iface->ustack.netmask6, ++ sizeof(nic_iface->ustack.netmask6)); ++ memcpy(vlan_iface->ustack.hostaddr6, ++ nic_iface->ustack.hostaddr6, ++ sizeof(nic_iface->ustack.hostaddr6)); ++ ++ persist_all_nic_iface(nic); ++ nic_disable(nic, 0); ++ nic_iface = vlan_iface; ++ } ++ } ++ ++ /* Force enable the NIC */ ++ if ((nic->state & NIC_STOPPED) && ++ !(nic->flags & NIC_ENABLED_PENDING)) ++ nic_enable(nic); ++ ++ /* Ensure that the NIC is RUNNING */ ++ rc = -EIO; ++ for (i = 0; i < 10; i++) { ++ if ((nic->state & NIC_RUNNING) == 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) { ++ char eth_device_name[IFNAMSIZ]; ++ ++ switch (ev->type) { ++ case ISCSI_KEVENT_PATH_REQ: ++ /* pass the request up to the user space ++ * library driver */ ++ if (nic->ops->handle_iscsi_path_req) { ++ nic->ops->handle_iscsi_path_req(nic, ++ nl_sock, ev, ++ path); ++ } ++ ++ LOG_INFO(PFX "%s: 'path_req' operation finished", ++ nic->log_name); ++ ++ rc = 0; ++ break; ++ case ISCSI_KEVENT_IF_DOWN: ++ memcpy(eth_device_name, nic->eth_device_name, ++ sizeof(eth_device_name)); ++ ++ pthread_mutex_lock(&nic_list_mutex); ++ ++ pthread_mutex_lock(&nic->nic_mutex); ++ nic->flags |= NIC_EXIT_MAIN_LOOP; ++ pthread_mutex_unlock(&nic->nic_mutex); ++ ++ pthread_cond_broadcast(&nic->enable_done_cond); ++ ++ nic_disable(nic, 1); ++ ++ nic_remove(nic); ++ pthread_mutex_unlock(&nic_list_mutex); ++ ++ pthread_mutex_lock(&nl_process_mutex); ++ nl_process_if_down = 0; ++ pthread_mutex_unlock(&nl_process_mutex); ++ ++ rc = 0; ++ ++ LOG_INFO(PFX "%s: 'if_down' operation finished", ++ eth_device_name); ++ ++ break; ++ default: ++ rc = -EAGAIN; ++ break; ++ } ++ } ++ ++ error: ++ ++ return rc; ++} ++ ++static void *nl_process_handle_thread(void *arg) ++{ ++ int rc; ++ ++ while (!event_loop_stop) { ++ char *data = NULL; ++ ++ rc = pthread_cond_wait(&nl_process_cond, &nl_process_mutex); ++ if (rc != 0) { ++ LOG_ERR("Fatal error in NL processing thread " ++ "during wait[%s]", strerror(rc)); ++ break; ++ } ++ ++ data = nl_process_ring[nl_process_head]; ++ nl_process_ring[nl_process_head] = NULL; ++ nl_process_tail = NL_PROCESS_NEXT_ENTRY(nl_process_tail); ++ ++ pthread_mutex_unlock(&nl_process_mutex); ++ ++ if (data) { ++ ctldev_handle(data); ++ free(data); ++ } ++ } ++ ++ return NULL; ++} ++ ++static void flush_nl_process_ring() ++{ ++ int i; ++ ++ for (i = 0; i < NL_PROCESS_MAX_RING_SIZE; i++) { ++ if (nl_process_ring[i] != NULL) { ++ free(nl_process_ring[i]); ++ nl_process_ring[i] = NULL; ++ } ++ } ++ ++ nl_process_head = 0; ++ nl_process_tail = 0; ++ ++ LOG_DEBUG(PFX "Flushed NL ring"); ++} ++ ++/** ++ * 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; ++ ++ /* Prepare the thread to issue the ARP's */ ++ nl_process_head = 0; ++ nl_process_tail = 0; ++ nl_process_if_down = 0; ++ memset(&nl_process_ring, 0, sizeof(nl_process_ring)); ++ ++ pthread_mutex_init(&nl_process_mutex, NULL); ++ pthread_cond_init(&nl_process_cond, NULL); ++ pthread_cond_init(&nl_process_if_down_cond, NULL); ++ ++ rc = pthread_create(&nl_process_thread, NULL, ++ nl_process_handle_thread, NULL); ++ if (rc != 0) { ++ LOG_ERR("Could not create NL processing thread [%s]", ++ strerror(rc)); ++ return -EIO; ++ } ++ ++ 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; ++ ++ rc = pull_from_nl(&buf); ++ if (rc != 0) ++ continue; ++ ++ /* Try to abort ARP'ing if a if_down was recieved */ ++ ev = (struct iscsi_uevent *)NLMSG_DATA(buf); ++ if (ev->type == ISCSI_KEVENT_IF_DOWN) { ++ LOG_INFO(PFX "Received if_down event"); ++ ++ pthread_mutex_lock(&nl_process_mutex); ++ /* Don't flush the nl ring if another if_down ++ is in progress */ ++ if (!nl_process_if_down) { ++ nl_process_if_down = 1; ++ ++ flush_nl_process_ring(); ++ } ++ pthread_mutex_unlock(&nl_process_mutex); ++ } ++ ++ if ((nl_process_head + 1 == nl_process_tail) || ++ (nl_process_tail == 0 && ++ nl_process_head == NL_PROCESS_LAST_ENTRY)) { ++ LOG_WARN(PFX "No space on Netlink ring"); ++ continue; ++ } ++ ++ pthread_mutex_lock(&nl_process_mutex); ++ nl_process_ring[nl_process_head] = buf; ++ nl_process_head = NL_PROCESS_NEXT_ENTRY(nl_process_head); ++ ++ pthread_cond_signal(&nl_process_cond); ++ pthread_mutex_unlock(&nl_process_mutex); ++ ++ LOG_DEBUG(PFX "Pulled nl event"); ++ } ++ ++ LOG_INFO(PFX "Netlink thread exit'ing"); ++ rc = 0; ++ ++error: ++ return 0; ++} +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/nic_nl.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/nic_nl.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/nic_nl.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/nic_nl.h 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,53 @@ ++/* ++ * 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. ++ * ++ * 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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/nic_utils.c open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/nic_utils.c +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/nic_utils.c 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/nic_utils.c 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,1657 @@ ++/* ++ * 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. ++ * ++ * 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_template[] = "/sys/class/iscsi_host/host%d"; ++static const char iscsi_host_path_netdev_template[] = ++ "/sys/class/iscsi_host/host%d/netdev"; ++static const char cnic_uio_sysfs_resc_template[] = ++ "/sys/class/uio/uio%i/device/resource%i"; ++ ++/** ++ * manually_trigger_uio_event() - If the uio file node doesn't exist then ++ * 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 */ ++ 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); ++ ++ 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; ++ ++ 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); ++ } ++ ++ /* 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(nic->eth_device_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 ++ * @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; ++ ++ pthread_mutex_lock(&nic_list_mutex); ++ 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; ++ } ++ pthread_mutex_unlock(&nic_list_mutex); ++ ++ 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; ++} ++ ++/** ++ * 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; ++ } ++ ++ 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; ++ ++ /* 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 library name */ ++ if (nic->nic_library == NULL) { ++ NIC_LIBRARY_EXIST_T exist; ++ ++ exist = does_nic_uio_name_exist(raw); ++ if (exist == NIC_LIBRARY_DOESNT_EXIST) { ++ LOG_ERR(PFX "%s: could not find library: %s ", ++ nic->log_name, raw); ++ rc = -EIO; ++ } ++ } else { ++ char *library_name; ++ size_t library_name_size; ++ ++ /* Get the string name from the NIC library */ ++ (*nic->ops->lib_ops.get_library_name) (&library_name, ++ &library_name_size); ++ ++ if (strcmp(raw, library_name) != 0) { ++ LOG_ERR(PFX "%s: uio names not equal: " ++ "expecting %s got %s from %s", ++ nic->log_name, library_name, raw, temp_path); ++ rc = -EIO; ++ } ++ } ++ ++ free(raw); ++ ++ LOG_INFO(PFX "%s: Verified is a cnic_uio device", nic->log_name); ++ ++error: ++ 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_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); ++ if (exist == NIC_LIBRARY_DOESNT_EXIST) { ++ LOG_ERR(PFX "NIC library doesn't exists: %s", ++ nic->library_name); ++ goto error; ++ } ++ } ++ ++ /* 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 '%s'", nic->log_name, nic->pci_id->device_name); ++error: ++ return; ++} ++ ++void prepare_nic_thread(nic_t * nic) ++{ ++ 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 */ ++ rc = pthread_create(&nic->thread, NULL, 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 += 10; ++ ++ /* Wait for the device to be enabled */ ++ rc = pthread_cond_timedwait(&nic->enable_done_cond, ++ &nic->nic_mutex, &ts); ++#if 0 ++ if (rc || !nic->flags & NIC_ENABLED) { ++ /* Give it one more shout */ ++ pthread_cond_broadcast(&nic->enable_wait_cond); ++ rc = gettimeofday(&tp, NULL); ++ ts.tv_sec = tp.tv_sec; ++ ts.tv_nsec = tp.tv_usec * 1000; ++ ts.tv_sec += 5; ++ rc = pthread_cond_timedwait(&nic->enable_done_cond, ++ &nic->nic_mutex, &ts); ++ } ++#endif ++ nic->flags &= ~NIC_ENABLED_PENDING; ++ ++ if (rc == 0 && nic->flags & NIC_ENABLED) { ++ LOG_DEBUG(PFX "%s: device enabled", nic->log_name); ++ } else { ++ LOG_ERR(PFX "%s: waiting to finish nic_enable err:%s", ++ nic->log_name, strerror(rc)); ++ /* Must clean up the ustack */ ++ nic_interface_t *nic_iface = nic->nic_iface; ++ nic_interface_t *vlan_iface; ++ while (nic_iface != NULL) { ++ LOG_INFO(PFX "%s: resetting uIP stack", ++ nic->log_name); ++ uip_reset(&nic_iface->ustack); ++ vlan_iface = nic_iface->vlan_next; ++ while (vlan_iface != NULL) { ++ LOG_INFO(PFX "%s: resetting " ++ "vlan uIP stack", ++ nic->log_name); ++ uip_reset(&vlan_iface->ustack); ++ vlan_iface = ++ vlan_iface->vlan_next; ++ } ++ nic_iface = nic_iface->next; ++ } ++ } ++ pthread_mutex_unlock(&nic->nic_mutex); ++ ++ 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 0 on success, <0 on failure ++ */ ++int nic_disable(nic_t * nic, int going_down) ++{ ++ if (nic->state & (NIC_STARTED_RUNNING | 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_RUNNING; ++ nic->state |= NIC_STOPPED; ++ ++ if (going_down) ++ nic->flags |= NIC_GOING_DOWN; ++ ++ /* 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 device to be disabled */ ++ rc = pthread_cond_timedwait(&nic->disable_wait_cond, ++ &nic->nic_mutex, &ts); ++ pthread_mutex_unlock(&nic->nic_mutex); ++ ++ LOG_DEBUG(PFX "%s: device disabled", nic->log_name); ++ ++ return 0; ++ } else { ++ LOG_WARN(PFX "%s: device already disabled: " ++ "flag: 0x%x state: 0x%x", ++ nic->log_name, nic->flags, nic->state); ++ return -EALREADY; ++ } ++} ++ ++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; ++ nic_close(nic, 1, FREE_ALL_STRINGS); ++ 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 != 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 ++ * @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; ++ ++ pthread_mutex_lock(&nic->nic_mutex); ++ ++ 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; ++ } ++ ++ pthread_mutex_unlock(&nic->nic_mutex); ++} ++ ++/******************************************************************************* ++ * 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 ++ * @return nic_iface - if found network interface with the given VLAN ID ++ * if not found a NULL is returned ++ */ ++nic_interface_t *nic_find_nic_iface(nic_t * nic, uint16_t vlan_id) ++{ ++ nic_interface_t *current; ++ ++ pthread_mutex_lock(&nic->nic_mutex); ++ ++ current = nic->nic_iface; ++ while (current != NULL) { ++ if (current->vlan_id == vlan_id) { ++ pthread_mutex_unlock(&nic->nic_mutex); ++ return current; ++ } ++ ++ current = current->next; ++ } ++ ++ pthread_mutex_unlock(&nic->nic_mutex); ++ ++ return NULL; ++} ++ ++/** ++ * nic_find_nic_iface_protocol() - This function is used to find an interface ++ * from the NIC ++ * @param nic - NIC to look for network interfaces ++ * @param vlan_id - VLAN id to look for ++ * @param protocol - either AF_INET or AF_INET6 ++ * @return nic_iface - if found network interface with the given VLAN ID ++ * if not found a NULL is returned ++ */ ++nic_interface_t *nic_find_nic_iface_protocol(nic_t * nic, ++ uint16_t vlan_id, ++ uint16_t protocol) ++{ ++ nic_interface_t *current; ++ ++ pthread_mutex_lock(&nic->nic_mutex); ++ ++ current = nic->nic_iface; ++ while (current != NULL) { ++ if ((current->vlan_id == vlan_id) && ++ (current->protocol == protocol)) { ++ pthread_mutex_unlock(&nic->nic_mutex); ++ return current; ++ } ++ ++ current = current->next; ++ } ++ ++ pthread_mutex_unlock(&nic->nic_mutex); ++ ++ return NULL; ++} ++ ++void persist_all_nic_iface(nic_t * nic) ++{ ++ nic_interface_t *current, *vlan_iface; ++ ++ pthread_mutex_lock(&nic->nic_mutex); ++ ++ current = nic->nic_iface; ++ while (current != NULL) { ++ current->flags |= NIC_IFACE_PERSIST; ++ vlan_iface = current->vlan_next; ++ while (vlan_iface != NULL) { ++ vlan_iface->flags |= NIC_IFACE_PERSIST; ++ vlan_iface = vlan_iface->vlan_next; ++ } ++ current = current->next; ++ } ++ ++ pthread_mutex_unlock(&nic->nic_mutex); ++} ++ ++/** ++ * nic_find_vlan_iface_protocol() - This function is used to find an interface ++ * from the NIC ++ * @param nic_iface - Base NIC to look for the vlan interfaces ++ * @param vlan_id - VLAN id to look for ++ * @param protocol - either AF_INET or AF_INET6 ++ * @return nic_iface - if found network interface with the given VLAN ID ++ * if not found a NULL is returned ++ */ ++nic_interface_t *nic_find_vlan_iface_protocol(nic_t *nic, ++ nic_interface_t *nic_iface, ++ uint16_t vlan_id, ++ uint16_t protocol) ++{ ++ nic_interface_t *current; ++ ++ pthread_mutex_lock(&nic->nic_mutex); ++ ++ current = nic_iface->vlan_next; ++ while (current != NULL) { ++ if ((current->vlan_id == vlan_id) && ++ (current->protocol == protocol)) { ++ pthread_mutex_unlock(&nic->nic_mutex); ++ return current; ++ } ++ current = current->vlan_next; ++ } ++ ++ pthread_mutex_unlock(&nic->nic_mutex); ++ return NULL; ++} ++ ++void set_nic_iface(nic_t *nic, nic_interface_t *nic_iface) ++{ ++ nic_interface_t *current, *prev; ++ ++ pthread_mutex_lock(&nic->nic_mutex); ++ ++ if (nic->nic_iface == nic_iface) ++ goto done; ++ ++ prev = nic->nic_iface; ++ current = nic->nic_iface->next; ++ while (current != NULL) { ++ if (current == nic_iface) { ++ prev->next = current->next; ++ current->next = nic->nic_iface; ++ nic->nic_iface = current; ++ goto done; ++ } ++ prev = current; ++ current = current->next; ++ } ++done: ++ pthread_mutex_unlock(&nic->nic_mutex); ++} ++/******************************************************************************* ++ * Packet management utility functions ++ ******************************************************************************/ ++/** ++ * 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 < 0) { ++ 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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/nic_utils.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/nic_utils.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/nic_utils.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/nic_utils.h 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,99 @@ ++/* ++ * 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. ++ * ++ * 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); ++ ++nic_interface_t *nic_find_nic_iface(nic_t * nic, uint16_t vlan_id); ++void set_nic_iface(nic_t *nic, nic_interface_t *nic_iface); ++ ++void persist_all_nic_iface(nic_t * nic); ++ ++int add_vlan_interfaces(nic_t * nic); ++ ++int nic_verify_uio_sysfs_name(nic_t * nic); ++void cnic_get_sysfs_pci_resource_path(nic_t *nic, int resc_no, ++ char *sys_path, size_t size); ++void nic_close_all(); ++void nic_remove_all(); ++ ++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); ++int 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); ++ ++#endif /* __NIC_UTILS_H__ */ +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/nic_vlan.c open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/nic_vlan.c +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/nic_vlan.c 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/nic_vlan.c 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,339 @@ ++/* ++ * 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. ++ * ++ * 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 ++ ++#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) ++{ ++ if (vlan > 1 && vlan < 4095) ++ return 1; ++ ++ return 0; ++} +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/nic_vlan.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/nic_vlan.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/nic_vlan.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/nic_vlan.h 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,88 @@ ++/* ++ * 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. ++ * ++ * 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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/options.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/options.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/options.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/options.h 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,116 @@ ++/* ++ * 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. ++ * ++ * 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 ++ ++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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/packet.c open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/packet.c +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/packet.c 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/packet.c 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,146 @@ ++/* ++ * 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. ++ * ++ * packet.c - packet management ++ * ++ */ ++#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; ++ } ++ ++ priv = malloc(priv_size); ++ if (priv == NULL) { ++ LOG_ERR("Could not allocate any memory for private structure"); ++ goto free_pkt; ++ } ++ ++ 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 rc, i; ++ ++ pthread_mutex_lock(&nic->free_packet_queue_mutex); ++ for (i = 0; i < num_of_packets; i++) { ++ packet_t *pkt; ++ ++ pkt = alloc_packet(1500, 1500); ++ if (pkt == NULL) { ++ rc = i; ++ goto done; ++ } ++ ++ reset_packet(pkt); ++ ++ pkt->next = nic->free_packet_queue; ++ nic->free_packet_queue = pkt; ++ } ++ ++ rc = num_of_packets; ++ ++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 -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/packet.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/packet.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/packet.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/packet.h 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,75 @@ ++/* ++ * 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. ++ * ++ * packet.h - packet definitions ++ * ++ */ ++#include ++ ++#ifndef __PACKET_H__ ++#define __PACKET_H__ ++ ++#include "nic.h" ++ ++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 *nic); ++void reset_packet(packet_t * pkt); ++ ++#endif /* __PACKET_H__ */ +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/uip-conf.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/uip-conf.h +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/src/unix/uip-conf.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/src/unix/uip-conf.h 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1,161 @@ ++/** ++ * \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 ++ * ++ * $Id: uip-conf.h,v 1.6 2006/06/12 08:00:31 adam Exp $ ++ */ ++ ++/** ++ * \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__ */ ++ ++/** @} */ ++/** @} */ +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/stamp-h1 open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/stamp-h1 +--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/stamp-h1 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/stamp-h1 2012-04-09 21:52:15.000000000 -0500 +@@ -0,0 +1 @@ ++timestamp for config.h diff --git a/iscsi-initiator-utils-sync-uio-0.7.4.3.patch b/iscsi-initiator-utils-sync-uio-0.7.4.3.patch new file mode 100644 index 0000000..f612d27 --- /dev/null +++ b/iscsi-initiator-utils-sync-uio-0.7.4.3.patch @@ -0,0 +1,5690 @@ +diff --git a/iscsiuio/README b/iscsiuio/README +index 5c36dec..a716263 100644 +--- a/iscsiuio/README ++++ b/iscsiuio/README +@@ -1,6 +1,6 @@ +-Iscsiuio Userspace Tool +-Version 0.7.2.1 +-Mar 05, 2012 ++iscsiuio Userspace Tool ++Version 0.7.4.3 ++Aug 16, 2012 + ------------------------------------------------------ + + This tool is to be used in conjunction with the Broadcom NetXtreme II Linux +@@ -189,10 +189,11 @@ To run the daemon in debug mode please pass the parameter '-d ' + + where the following debug levels are defined: + +-DEBUG 4 - Print all messages +-INFO 3 - Print messages needed to follow the uIP code (default) +-WARN 2 - Print warning messages +-ERROR 1 - Only print critical errors ++PACKET 5 - Print all messages ++DEBUG 4 - Print debug messages ++INFO 3 - Print messages needed to follow the uIP code (default) ++WARN 2 - Print warning messages ++ERROR 1 - Only print critical errors + + A sample banner message: + +diff --git a/iscsiuio/RELEASE.TXT b/iscsiuio/RELEASE.TXT +index d4a00b6..cb1d470 100644 +--- a/iscsiuio/RELEASE.TXT ++++ b/iscsiuio/RELEASE.TXT +@@ -1,7 +1,7 @@ + Release Notes + Broadcom uIP Linux Driver +- Version 0.7.2.1 +- 03/05/2012 ++ Version 0.7.4.3 ++ 08/16/2012 + + Broadcom Corporation + 5300 California Avenue, +@@ -10,6 +10,228 @@ + Copyright (c) 2004 - 2012 Broadcom Corporation + All rights reserved + ++ ++uIP v0.7.4.3 (Aug 16, 2012) ++======================================================= ++ Fixes ++ ----- ++ 1. Problem: Cont00049383 - No mechanism in iface file to support ++ gateway/routing ++ Change: Added support for the additional network parameters ++ as passed from the newer iscsi-util. ++ These parameters include: ++ IPv4: subnet_mask, gateway ++ IPv6: ipv6_linklocal, ipv6_router, ++ ipv6_autocfg, linklocal_autocfg, router_autocfg ++ VLAN: vlan_id, vlan_priority, vlan_state ++ Other: mtu, port ++ Impact: All ++ ++ 2. Problem: Cont00060806 - Unable to connect target using DHCP over ++ tagged VLAN ++ Change: DHCP+VLAN is a new feature enhancement that was added ++ alongside all other new iface parameters. ++ Impact: All ++ ++ 3. Problem: Cont00061513 - Unable to connect to target over VLAN ++ interface ++ Cause: The VLAN id was not properly passed back to the CNIC ++ driver for the offload request ++ Change: Fixed the VLAN id being passed back to the CNIC driver ++ Impact: All ++ ++ 4. Problem: Cont00061529 - Unable to connect to target after an ++ initial failed login attempt until iscsi service is ++ restarted ++ Cause: Upon a failed DHCPv4 acquisition due to the wrong VLAN ++ tag in the initial iface setup, any iscsid connect request ++ from the same NIC will get dropped due to a bug. ++ Change: Fixed the bug which prevented new iscsid connect requests ++ from getting honored ++ Impact: All ++ ++ 5. Problem: Cont00061978 - Load/unload stress test fails ++ Cause: The bnx2x open request was failing due to the module ++ request procedure. However, the open failure was ++ not being handled correctly. ++ Change: Fixed the device open error handling ++ Impact: 5771X/578XX ++ ++ 6. Problem: Cont00062170 - IPv6 login/logout stress fails ++ Cause: The packet buffer routine for IPv6 did not take ++ network order <-> host order into consideration ++ Change: Added a htons call to compensate for the ntohs pair ++ Impact: All ++ ++ 7. Problem: Cont00061869 - Unable to setup an offload iSCSI ++ connection with FLR/NPAR under ESX5.0:PDA ++ Cause: The physical function ID was previously extracted ++ from the sysfs of the VM which might not be consistent ++ to the actual physical setup due to the function ++ remapping in the hypervisor ++ Change: Read the physical function ID directly from the BAR0 ++ ME register ++ Impact: All ++ ++ 8. Problem: Cont00062170 - IPv6 login/logout stress fails ++ Cause: The packet interrupt was lost after running the test ++ for a much longer period of time. A bug in the ++ packet processing routine was found to exit prematurely ++ Change: Fixed the packet processing routine to process all ++ packets before exiting ++ Impact: All ++ ++ 9. Problem: Cont00062660 - Unable to login with VLAN iscsiuio ++ on RHEL6.2 ++ Cause: The open-iscsi util in RHEL6.2 has a bug which ++ does not pass the correct iface_num to iscsiuio ++ Change: Added workaround to fall back to do the legacy ++ VLAN support if iface_num and vlan_id = 0 ++ Impact: RHEL6.2 ++ ++ 10. Problem: Cont00062805 - Cannot login to iSCSI targets on RHEL6.3 ++ Cause: The problem was caused by a change made to the iface_rec ++ structure in the RHEL6.3 inbox open-iscsi util ++ Change: The new changes is now incorporated ++ Impact: All ++ ++ 11. Problem: Cont00062993 - IPv6 DHCP with VLAN specification in ++ iface file gets wrong address ++ Cause: The DHCPv6 request was using the same DUID as always ++ so the non-VLAN DHCP server responded to our broadcast ++ instead ++ Change: Changed the DHCPv6 request DUID to link address + time ++ instead of link address alone ++ Impact: DHCPv6 operation ++ ++ 12. Problem: RHEL BZ 734010/804580 - issues found by the Coverity ++ scan ++ Cause: 10 code issues were flagged for revision ++ Change: Fixed all area of concern ++ Impact: All ++ ++ 13. Problem: Cont00063177 - IPv4 DHCP with VLAN specification in ++ iface file gets wrong address ++ Cause: The DHCPv4 handler was not discriminating the VLAN tag ++ associated with the DHCP offers from multiple DHCP ++ servers ++ Change: Changed the DHCPv4 handler to drop DHCP offer packets ++ that doesn't match the VLAN tag of the intended DHCP ++ discovery packet ++ Impact: DHCPv4 operation ++ ++ 14. Problem: Cont00063421 - Static IPv6 cannot connect via RA/LL ++ Cause: The router advertise and the linklocal address ++ were corrupted due to the override capabilities ++ added for the newer open-iscsi util ++ Change: Fixed the address override code ++ Impact: Static IPv6 ++ ++ 15. Problem: Cont00063443 - Compilation error on SLES11sp1 ++ Cause: The iface_num field was not defined ++ Change: Fixed all references to iface_num ++ Impact: SLES11sp1 ++ ++ 16. Problem: Cont00063518 - HBA fails to connect across router ++ using iface.gateway address ++ Cause: The gateway override code did not populate the ++ address into the lower level engine ++ Change: Fixed the gateway override code ++ Impact: IPv4 Static IP operation ++ ++ 17. Problem: Cont00063567 - IPv6 LL and RA override does not work ++ Cause: The IPv6 LL/RA override addresses were overwritten ++ by the NDP engine ++ Change: Fixed the LL/RA override code ++ Impact: IPv6 operation ++ ++ 18. Problem: Cont00063626 - Static IPv6 does not connect when ++ the prefix len is not set explicitly ++ Cause: The IPv6 prefix length was not set correctly ++ for Static IPv6 operation when CIDR notation is ++ not specified ++ Change: Fixed the default prefix length ++ Impact: Static IPv6 ++ ++ 19. Problem: Cont00063651 - Cannot connect to iSCSI targets ++ HP PTM/SF ++ Cause: Switch-Dependent mode + invalid Outer VLAN was ++ not supported ++ Change: Allow SD+invalid OV to fallback to SF operation mode ++ Impact: 5771X/578XX ++ ++ 20. Problem: Cont00063816 - The initiator is not able to connect ++ to the iSCSI targets over VLAN ++ Cause: The process packet routine did not consider the PCP ++ of the VLAN tag to be non-zero. This created a ++ mismatch when this VLAN tag was compared against the ++ nic_iface->vlan_id which doesn't include the PCP. ++ Change: Added the consideration of non-zero PCP ++ Impact: All ++ ++ 21. Problem: Cont00063863 - can't boot into offload image ++ when VLAN is enabled ++ Cause: During the iSCSI login exchange, certain iSCSI targets ++ will send an ARP request even though the TCP connection ++ has been made. The bug was in this ARP reply where ++ the local MAC was corrupted when VLAN is enabled. ++ Change: Fixed the ARP reply packet ++ Impact: All ++ ++ 22. Problem: Cont00063863 - can't boot into offload image ++ when VLAN is enabled ++ Cause: During the iSCSI login exchange, certain iSCSI targets ++ will send an ARP request even though the TCP connection ++ has been made. The bug was in this ARP reply where ++ the local MAC was corrupted when VLAN is enabled. ++ Change: Fixed the ARP reply packet ++ Impact: All ++ ++ 23. Problem: Cont00064604 - Fails to connect to routed IPv6 target ++ via RA ++ Cause: The default router IPv6 address was not being retrieved ++ correctly. ++ Change: Fixed the default router IPv6 address read ++ Impact: All ++ ++ 24. Problem: Cont00064665 - Linux iSCSI connects via gateway address ++ on the wrong subnet ++ Cause: The gateway address used was not checked against the ++ subnet mask specified before the ARP requests. Since ++ this behavior deters from how L2 operates, therefore, ++ a change was made to correct this. ++ Change: Added check of the gateway specified against the subnet ++ specified. ++ Impact: Static IPv4 operation ++ ++ 25. Problem: Cont00064722 - Linux iSCSI unable to force IPv6 LL ++ override (advanced iface parameters) ++ Cause: The override LL address was not being populated to the ++ IPv6 address database correctly ++ Change: Added this correctly to the IPv6 initialization ++ Impact: Static/DHCP IPv6 LL address override only ++ ++ Enhancements ++ ------------ ++ 1. Lock iscsid's connect request with path_req so connect requests ++ with DHCP/Static will no longer override each other ++ ++ 2. Fixed the if_down handler from global to nic specific ++ ++ 3. Fixed various synchronization issues ++ ++ 4. Updated README ++ ++ 5. Added support for the new iface_num field in the iscsi_uevent ++ path ++ ++ 6. Fixed bug in the nic_iface search engine based on iface_num ++ ++ 7. Allow VLAN tag = 1 (router management) to connect offload ++ ++ 8. Added support for jumbo MTU (independent from the L2 MTU) ++ ++ + uIP v0.7.2.1 (Mar 05, 2012) + ======================================================= + Fixes +@@ -47,7 +269,7 @@ uIP v0.7.2.1 (Mar 05, 2012) + ------------ + 1. Change: Default iscsiuio logging to off. Use the '-d' + option to enable +- 2. Change: Disable HP SD mode ++ 2. Change: Disable HP SD mode (NOT) + 3. Change: Updated README + + +diff --git a/iscsiuio/configure b/iscsiuio/configure +index 4879fb9..6ff2e68 100644 +--- a/iscsiuio/configure ++++ b/iscsiuio/configure +@@ -1,6 +1,6 @@ + #! /bin/sh + # Guess values for system-dependent variables and create Makefiles. +-# Generated by GNU Autoconf 2.59 for iscsiuio 0.7.2.1. ++# Generated by GNU Autoconf 2.59 for iscsiuio 0.7.4.3. + # + # Report bugs to . + # +@@ -423,8 +423,8 @@ SHELL=${CONFIG_SHELL-/bin/sh} + # Identity of this package. + PACKAGE_NAME='iscsiuio' + PACKAGE_TARNAME='iscsiuio' +-PACKAGE_VERSION='0.7.2.1' +-PACKAGE_STRING='iscsiuio 0.7.2.1' ++PACKAGE_VERSION='0.7.4.3' ++PACKAGE_STRING='iscsiuio 0.7.4.3' + PACKAGE_BUGREPORT='eddie.wai@broadcom.com' + + # Factoring default headers for most tests. +@@ -954,7 +954,7 @@ if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +-\`configure' configures iscsiuio 0.7.2.1 to adapt to many kinds of systems. ++\`configure' configures iscsiuio 0.7.4.3 to adapt to many kinds of systems. + + Usage: $0 [OPTION]... [VAR=VALUE]... + +@@ -1020,7 +1020,7 @@ fi + + if test -n "$ac_init_help"; then + case $ac_init_help in +- short | recursive ) echo "Configuration of iscsiuio 0.7.2.1:";; ++ short | recursive ) echo "Configuration of iscsiuio 0.7.4.3:";; + esac + cat <<\_ACEOF + +@@ -1161,7 +1161,7 @@ fi + test -n "$ac_init_help" && exit 0 + if $ac_init_version; then + cat <<\_ACEOF +-iscsiuio configure 0.7.2.1 ++iscsiuio configure 0.7.4.3 + generated by GNU Autoconf 2.59 + + Copyright (C) 2003 Free Software Foundation, Inc. +@@ -1175,7 +1175,7 @@ cat >&5 <<_ACEOF + This file contains any messages produced by compilers while + running configure, to aid debugging if configure makes a mistake. + +-It was created by iscsiuio $as_me 0.7.2.1, which was ++It was created by iscsiuio $as_me 0.7.4.3, which was + generated by GNU Autoconf 2.59. Invocation command line was + + $ $0 $@ +@@ -21726,7 +21726,7 @@ _ASBOX + } >&5 + cat >&5 <<_CSEOF + +-This file was extended by iscsiuio $as_me 0.7.2.1, which was ++This file was extended by iscsiuio $as_me 0.7.4.3, which was + generated by GNU Autoconf 2.59. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES +@@ -21789,7 +21789,7 @@ _ACEOF + + cat >>$CONFIG_STATUS <<_ACEOF + ac_cs_version="\\ +-iscsiuio config.status 0.7.2.1 ++iscsiuio config.status 0.7.4.3 + configured by $0, generated by GNU Autoconf 2.59, + with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" + +diff --git a/iscsiuio/configure.ac b/iscsiuio/configure.ac +index 3b7a880..0b1e7f1 100644 +--- a/iscsiuio/configure.ac ++++ b/iscsiuio/configure.ac +@@ -1,6 +1,6 @@ + dnl iscsiuio uIP user space stack configure.ac file + dnl +-dnl Copyright (c) 2004-2011 Broadcom Corporation ++dnl Copyright (c) 2004-2012 Broadcom Corporation + dnl + dnl This program is free software; you can redistribute it and/or modify + dnl it under the terms of the GNU General Public License as published by +@@ -11,9 +11,9 @@ dnl Maintained by: Eddie Wai (eddie.wai@broadcom.com) + dnl + + PACKAGE=iscsiuio +-VERSION=0.7.2.1 ++VERSION=0.7.4.3 + +-AC_INIT(iscsiuio, 0.7.2.1, eddie.wai@broadcom.com) ++AC_INIT(iscsiuio, 0.7.4.3, eddie.wai@broadcom.com) + + AM_INIT_AUTOMAKE($PACKAGE, $VERSION) + AC_CONFIG_HEADER(config.h) +diff --git a/iscsiuio/docs/iscsiuio.8 b/iscsiuio/docs/iscsiuio.8 +index 3307b1e..4bf26df 100644 +--- a/iscsiuio/docs/iscsiuio.8 ++++ b/iscsiuio/docs/iscsiuio.8 +@@ -3,9 +3,9 @@ + .\" modify it under the terms of the GNU General Public License as + .\" published by the Free Software Foundation. + .\" +-.\" bnx2.4,v 0.7.2.1 ++.\" bnx2.4,v 0.7.4.3 + .\" +-.TH iscsiuio 8 "03/05/2012" "Broadcom Corporation" ++.TH iscsiuio 8 "08/16/2012" "Broadcom Corporation" + .\" + .\" NAME part + .\" +diff --git a/iscsiuio/include/iscsi_if.h b/iscsiuio/include/iscsi_if.h +index a9ac145..1944abd 100644 +--- a/iscsiuio/include/iscsi_if.h ++++ b/iscsiuio/include/iscsi_if.h +@@ -207,6 +207,7 @@ struct iscsi_uevent { + } ep_connect_ret; + struct msg_req_path { + uint32_t host_no; ++ uint32_t iface_num; + } req_path; + struct msg_notify_if_down { + uint32_t host_no; +@@ -234,6 +235,8 @@ struct iscsi_path { + struct in6_addr v6_addr; + } dst; + uint16_t vlan_id; ++#define IFACE_NUM_PRESENT (1<<0) ++#define IFACE_NUM_INVALID -1 + uint16_t pmtu; + } __attribute__ ((aligned (sizeof(uint64_t)))); + +diff --git a/iscsiuio/src/apps/dhcpc/dhcpc.c b/iscsiuio/src/apps/dhcpc/dhcpc.c +index 88d75c3..afec601 100644 +--- a/iscsiuio/src/apps/dhcpc/dhcpc.c ++++ b/iscsiuio/src/apps/dhcpc/dhcpc.c +@@ -334,7 +334,7 @@ static PT_THREAD(handle_dhcp(struct uip_stack *ustack)) + (uint8_t *) s->mac_addr); + + /* Put the stack thread back into a long sleep */ +- s->nic->state |= NIC_LONG_SLEEP; ++ s->nic->flags |= NIC_LONG_SLEEP; + + /* timer_stop(&s.timer); */ + +@@ -343,7 +343,7 @@ static PT_THREAD(handle_dhcp(struct uip_stack *ustack)) + timer_set(&s->timer, s->ticks); + PT_WAIT_UNTIL(&s->pt, timer_expired(&s->timer)); + LOG_INFO("Lease expired, re-acquire IP address"); +- s->nic->state &= ~NIC_LONG_SLEEP; ++ s->nic->flags &= ~NIC_LONG_SLEEP; + PT_RESTART(&s->pt); + + /* +@@ -397,7 +397,7 @@ int dhcpc_init(nic_t * nic, struct uip_stack *ustack, + ustack->dhcpc = s; + + /* Let the RX poll value take over */ +- nic->state &= ~NIC_LONG_SLEEP; ++ nic->flags &= ~NIC_LONG_SLEEP; + + PT_INIT(&s->pt); + +diff --git a/iscsiuio/src/apps/dhcpc/dhcpv6.c b/iscsiuio/src/apps/dhcpc/dhcpv6.c +index b7ae631..273cce0 100644 +--- a/iscsiuio/src/apps/dhcpc/dhcpv6.c ++++ b/iscsiuio/src/apps/dhcpc/dhcpv6.c +@@ -86,10 +86,6 @@ int dhcpv6_do_discovery(pDHCPV6_CONTEXT dhcpv6_context) + (pIPV6_HDR) dhcpv6_context->ipv6_context->ustack->network_layer; + dhcpv6_context->udp = + (pUDP_HDR) ((u8_t *) dhcpv6_context->ipv6 + sizeof(IPV6_HDR)); +- LOG_INFO("dhcpv6: ipv6c=%p, ustack=%p eth=%p ipv6=%p udp=%p", +- dhcpv6_context->ipv6_context, +- dhcpv6_context->ipv6_context->ustack, dhcpv6_context->eth, +- dhcpv6_context->ipv6, dhcpv6_context->udp); + + /* Send out DHCPv6 Solicit packet. */ + dhcpv6_send_solicit_packet(dhcpv6_context); +@@ -176,8 +172,10 @@ STATIC u16_t dhcpv6_init_packet(pDHCPV6_CONTEXT dhcpv6_context, u8_t type) + opt->hdr.type = HOST_TO_NET16(DHCPV6_OPT_CLIENTID); + opt->hdr.length = HOST_TO_NET16(sizeof(DHCPV6_OPT_CLIENT_ID)); + opt->type.client_id.duid_type = +- HOST_TO_NET16(DHCPV6_DUID_TYPE_LINK_LAYER); ++ HOST_TO_NET16(DHCPV6_DUID_TYPE_LINK_LAYER_AND_TIME); + opt->type.client_id.hw_type = HOST_TO_NET16(DHCPV6_HW_TYPE_ETHERNET); ++ opt->type.client_id.time = HOST_TO_NET32(clock_time()/1000 - ++ 0x3A4FC880); + memcpy((char __FAR__ *)&opt->type.client_id.link_layer_addr, + (char __FAR__ *)dhcpv6_context->our_mac_addr, sizeof(MAC_ADDR)); + pkt_len += sizeof(DHCPV6_OPT_CLIENT_ID) + sizeof(DHCPV6_OPT_HDR); +diff --git a/iscsiuio/src/apps/dhcpc/dhcpv6.h b/iscsiuio/src/apps/dhcpc/dhcpv6.h +index 917cf35..d8e03e5 100644 +--- a/iscsiuio/src/apps/dhcpc/dhcpv6.h ++++ b/iscsiuio/src/apps/dhcpc/dhcpv6.h +@@ -164,7 +164,7 @@ typedef struct DHCPV6_OPT_CLIENT_ID { + #define DHCPV6_DUID_TYPE_LINK_LAYER 3 + u16_t hw_type; + #define DHCPV6_HW_TYPE_ETHERNET 1 +-// u32_t time; ++ u32_t time; + MAC_ADDR link_layer_addr; + } DHCPV6_OPT_CLIENT_ID, *pDHCPV6_OPT_CLIENT_ID; + +diff --git a/iscsiuio/src/uip/ipv6.c b/iscsiuio/src/uip/ipv6.c +index 594495a..a8eed71 100644 +--- a/iscsiuio/src/uip/ipv6.c ++++ b/iscsiuio/src/uip/ipv6.c +@@ -38,6 +38,7 @@ + */ + #include + #include ++#include + #include "logger.h" + #include "uip.h" + #include "ipv6.h" +@@ -78,7 +79,7 @@ STATIC void ipv6_udp_rx(pIPV6_CONTEXT ipv6_context); + + int iscsiL2Send(pIPV6_CONTEXT ipv6_context, int pkt_len) + { +- LOG_DEBUG("IPV6: iscsiL2Send"); ++ LOG_DEBUG("IPv6: iscsiL2Send"); + uip_send(ipv6_context->ustack, + (void *)ipv6_context->ustack->data_link_layer, pkt_len); + +@@ -103,7 +104,8 @@ int iscsiL2AddMcAddr(pIPV6_CONTEXT ipv6_context, MAC_ADDR * new_mc_addr) + (char __FAR__ *)&all_zeroes_mc, sizeof(MAC_ADDR))) { + memcpy((char __FAR__ *)mc_addr, + (char __FAR__ *)new_mc_addr, sizeof(MAC_ADDR)); +- LOG_DEBUG("IPV6: mc_addr added %x:%x:%x:%x:%x:%x", ++ LOG_DEBUG("IPv6: mc_addr added " ++ "%02x:%02x:%02x:%02x:%02x:%02x", + *(u8_t *) new_mc_addr, + *((u8_t *) new_mc_addr + 1), + *((u8_t *) new_mc_addr + 2), +@@ -150,10 +152,11 @@ void ipv6_init(struct ndpc_state *ndp, int cfg) + ipv6_arp_table = &ipv6_context->ipv6_arp_table[0]; + ipv6_prefix_table = &ipv6_context->ipv6_prefix_table[0]; + +- memset((char __FAR__ *)ipv6_arp_table, 0, sizeof(ipv6_arp_table)); +- memset((char __FAR__ *)ipv6_prefix_table, 0, sizeof(ipv6_prefix_table)); +- memcpy((char __FAR__ *)&ipv6_context->mac_addr, +- (char __FAR__ *)mac_addr, sizeof(MAC_ADDR)); ++ memset((char __FAR__*)ipv6_arp_table, 0, sizeof(*ipv6_arp_table)); ++ memset((char __FAR__*)ipv6_prefix_table, 0, ++ sizeof(*ipv6_prefix_table)); ++ memcpy((char __FAR__*)&ipv6_context->mac_addr, ++ (char __FAR__*)mac_addr, sizeof(MAC_ADDR)); + /* + * Per RFC 2373. + * There are two types of local-use unicast addresses defined. These +@@ -167,33 +170,34 @@ void ipv6_init(struct ndpc_state *ndp, int cfg) + * |1111111010| 0 | interface ID | + * +----------+-------------------------+----------------------------+ + */ +- ipv6_context->link_local_addr.addr8[0] = 0xfe; +- ipv6_context->link_local_addr.addr8[1] = 0x80; +- /* Bit 1 is 1 to indicate universal scope. */ +- ipv6_context->link_local_addr.addr8[8] = mac_addr[0] | 0x2; +- ipv6_context->link_local_addr.addr8[9] = mac_addr[1]; +- ipv6_context->link_local_addr.addr8[10] = mac_addr[2]; +- ipv6_context->link_local_addr.addr8[11] = 0xff; +- ipv6_context->link_local_addr.addr8[12] = 0xfe; +- ipv6_context->link_local_addr.addr8[13] = mac_addr[3]; +- ipv6_context->link_local_addr.addr8[14] = mac_addr[4]; +- ipv6_context->link_local_addr.addr8[15] = mac_addr[5]; +- +- ipv6_context->link_local_multi.addr8[0] = 0xff; +- ipv6_context->link_local_multi.addr8[1] = 0x02; +- ipv6_context->link_local_multi.addr8[11] = 0x01; +- ipv6_context->link_local_multi.addr8[12] = 0xff; +- ipv6_context->link_local_multi.addr8[13] |= +- ipv6_context->link_local_addr.addr8[13]; +- ipv6_context->link_local_multi.addr16[7] = +- ipv6_context->link_local_addr.addr16[7]; +- +- /* Default Prefix length is 64 */ +- /* Add Link local address to the head of the ipv6 address +- list */ +- ipv6_add_prefix_entry(ipv6_context, +- &ipv6_context->link_local_addr, 64); +- ++ if (ipv6_context->ustack->linklocal_autocfg != IPV6_LL_AUTOCFG_OFF) { ++ ipv6_context->link_local_addr.addr8[0] = 0xfe; ++ ipv6_context->link_local_addr.addr8[1] = 0x80; ++ /* Bit 1 is 1 to indicate universal scope. */ ++ ipv6_context->link_local_addr.addr8[8] = mac_addr[0] | 0x2; ++ ipv6_context->link_local_addr.addr8[9] = mac_addr[1]; ++ ipv6_context->link_local_addr.addr8[10] = mac_addr[2]; ++ ipv6_context->link_local_addr.addr8[11] = 0xff; ++ ipv6_context->link_local_addr.addr8[12] = 0xfe; ++ ipv6_context->link_local_addr.addr8[13] = mac_addr[3]; ++ ipv6_context->link_local_addr.addr8[14] = mac_addr[4]; ++ ipv6_context->link_local_addr.addr8[15] = mac_addr[5]; ++ ++ ipv6_context->link_local_multi.addr8[0] = 0xff; ++ ipv6_context->link_local_multi.addr8[1] = 0x02; ++ ipv6_context->link_local_multi.addr8[11] = 0x01; ++ ipv6_context->link_local_multi.addr8[12] = 0xff; ++ ipv6_context->link_local_multi.addr8[13] |= ++ ipv6_context->link_local_addr.addr8[13]; ++ ipv6_context->link_local_multi.addr16[7] = ++ ipv6_context->link_local_addr.addr16[7]; ++ ++ /* Default Prefix length is 64 */ ++ /* Add Link local address to the head of the ipv6 address ++ list */ ++ ipv6_add_prefix_entry(ipv6_context, ++ &ipv6_context->link_local_addr, 64); ++ } + /* + * Convert Multicast IP address to Multicast MAC adress per + * RFC 2464: Transmission of IPv6 Packets over Ethernet Networks +@@ -257,6 +261,7 @@ int ipv6_add_prefix_entry(pIPV6_CONTEXT ipv6_context, + int i; + pIPV6_PREFIX_ENTRY prefix_entry; + pIPV6_PREFIX_ENTRY ipv6_prefix_table = ipv6_context->ipv6_prefix_table; ++ char addr_str[INET6_ADDRSTRLEN]; + + /* Check if there is an valid entry already. */ + for (i = 0; i < IPV6_NUM_OF_ADDRESS_ENTRY; i++) { +@@ -287,21 +292,13 @@ int ipv6_add_prefix_entry(pIPV6_CONTEXT ipv6_context, + + prefix_entry->prefix_len = prefix_len / 8; + +- memcpy((char __FAR__ *)&prefix_entry->address, +- (char __FAR__ *)ipv6_addr, sizeof(IPV6_ADDR)); +- +- +- LOG_DEBUG("IPV6: add prefix ip addr " +- "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x " +- "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", +- prefix_entry->address.addr8[0], prefix_entry->address.addr8[1], +- prefix_entry->address.addr8[2], prefix_entry->address.addr8[3], +- prefix_entry->address.addr8[4], prefix_entry->address.addr8[5], +- prefix_entry->address.addr8[6], prefix_entry->address.addr8[7], +- prefix_entry->address.addr8[8], prefix_entry->address.addr8[9], +- prefix_entry->address.addr8[10], prefix_entry->address.addr8[11], +- prefix_entry->address.addr8[12], prefix_entry->address.addr8[13], +- prefix_entry->address.addr8[14], prefix_entry->address.addr8[15]); ++ memcpy((char __FAR__*)&prefix_entry->address, ++ (char __FAR__*)ipv6_addr, sizeof(IPV6_ADDR)); ++ ++ inet_ntop(AF_INET6, &prefix_entry->address.addr8, addr_str, ++ sizeof(addr_str)); ++ ++ LOG_DEBUG("IPv6: add prefix IP addr %s", addr_str); + + /* Put it on the list on head of the list. */ + if (ipv6_context->addr_list != NULL) { +@@ -419,7 +416,7 @@ int ipv6_discover_address(pIPV6_CONTEXT ipv6_context) + sizeof(IPV6_ADDR)); + + icmp->icmpv6_cksum = 0; +- LOG_DEBUG("IPV6: Send rtr sol"); ++ LOG_DEBUG("IPv6: Send rtr sol"); + ipv6_send(ipv6_context, (u8_t *) icmp - (u8_t *) eth + + sizeof(ICMPV6_HDR) + sizeof(ICMPV6_OPT_LINK_ADDR)); + return rc; +@@ -650,7 +647,7 @@ STATIC void ipv6_update_arp_table(pIPV6_CONTEXT ipv6_context, + int i; + pIPV6_ARP_ENTRY ipv6_arp_table = ipv6_context->ipv6_arp_table; + +- LOG_DEBUG("IPV6: ARP update"); ++ LOG_DEBUG("IPv6: Neighbor update"); + /* + * Walk through the ARP mapping table and try to find an entry to + * update. If none is found, the IP -> MAC address mapping is +@@ -710,6 +707,7 @@ int ipv6_send_nd_solicited_packet(pIPV6_CONTEXT ipv6_context, pETH_HDR eth, + pICMPV6_HDR icmp; + int pkt_len = 0; + pIPV6_ADDR longest_match_addr; ++ char addr_str[INET6_ADDRSTRLEN]; + + ipv6->ipv6_nxt_hdr = IPPROTO_ICMPV6; + +@@ -719,7 +717,7 @@ int ipv6_send_nd_solicited_packet(pIPV6_CONTEXT ipv6_context, pETH_HDR eth, + /* Use Link-local as source address */ + if (ipv6_is_it_our_link_local_address(ipv6_context, &ipv6->ipv6_dst) == + TRUE) { +- LOG_DEBUG("IPV6: NS using link local"); ++ LOG_DEBUG("IPv6: NS using link local"); + memcpy((char __FAR__ *)&ipv6->ipv6_src, + (char __FAR__ *)&ipv6_context->link_local_addr, + sizeof(IPV6_ADDR)); +@@ -727,12 +725,12 @@ int ipv6_send_nd_solicited_packet(pIPV6_CONTEXT ipv6_context, pETH_HDR eth, + longest_match_addr = + ipv6_find_longest_match(ipv6_context, &ipv6->ipv6_dst); + if (longest_match_addr) { +- LOG_DEBUG("IPV6: NS using longest match addr"); ++ LOG_DEBUG("IPv6: NS using longest match addr"); + memcpy((char __FAR__ *)&ipv6->ipv6_src, + (char __FAR__ *)longest_match_addr, + sizeof(IPV6_ADDR)); + } else { +- LOG_DEBUG("IPV6: NS using link local instead"); ++ LOG_DEBUG("IPv6: NS using link local instead"); + memcpy((char __FAR__ *)&ipv6->ipv6_src, + (char __FAR__ *)&ipv6_context->link_local_addr, + sizeof(IPV6_ADDR)); +@@ -740,17 +738,8 @@ int ipv6_send_nd_solicited_packet(pIPV6_CONTEXT ipv6_context, pETH_HDR eth, + } + icmp = (pICMPV6_HDR) ((u8_t *) ipv6 + sizeof(IPV6_HDR)); + +- LOG_DEBUG +- ("IPV6: NS host ip addr %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x" +- " %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", +- ipv6->ipv6_src.addr8[0], ipv6->ipv6_src.addr8[1], +- ipv6->ipv6_src.addr8[2], ipv6->ipv6_src.addr8[3], +- ipv6->ipv6_src.addr8[4], ipv6->ipv6_src.addr8[5], +- ipv6->ipv6_src.addr8[6], ipv6->ipv6_src.addr8[7], +- ipv6->ipv6_src.addr8[8], ipv6->ipv6_src.addr8[9], +- ipv6->ipv6_src.addr8[10], ipv6->ipv6_src.addr8[11], +- ipv6->ipv6_src.addr8[12], ipv6->ipv6_src.addr8[13], +- ipv6->ipv6_src.addr8[14], ipv6->ipv6_src.addr8[15]); ++ inet_ntop(AF_INET6, &ipv6->ipv6_src.addr8, addr_str, sizeof(addr_str)); ++ LOG_DEBUG("IPv6: NS host IP addr: %s", addr_str); + /* + * Destination IP address to be resolved is after the ICMPv6 + * header. +@@ -839,6 +828,7 @@ STATIC void ipv6_icmp_handle_router_adv(pIPV6_CONTEXT ipv6_context) + pICMPV6_OPT_HDR icmp_opt; + u16_t opt_len; + u16_t len; ++ char addr_str[INET6_ADDRSTRLEN]; + + if (ipv6_context->flags & IPV6_FLAGS_ROUTER_ADV_RECEIVED) + return; +@@ -868,7 +858,7 @@ STATIC void ipv6_icmp_handle_router_adv(pIPV6_CONTEXT ipv6_context) + } + + if (ipv6_context->flags & IPV6_FLAGS_ROUTER_ADV_RECEIVED) { +- LOG_DEBUG("IPV6: RTR ADV nd_ra_flags=0x%x", ++ LOG_DEBUG("IPv6: RTR ADV nd_ra_flags = 0x%x", + icmp->nd_ra_flags_reserved); + if (icmp->nd_ra_curhoplimit > 0) + ipv6_context->hop_limit = icmp->nd_ra_curhoplimit; +@@ -880,21 +870,17 @@ STATIC void ipv6_icmp_handle_router_adv(pIPV6_CONTEXT ipv6_context) + ipv6_context->flags |= IPV6_FLAGS_OTHER_STATEFUL_CONFIG; + + if (icmp->nd_ra_router_lifetime != 0) { +- /* This is a default router. */ +- memcpy((char __FAR__ *)&ipv6_context->default_router, +- (char __FAR__ *)&ipv6->ipv6_src, +- sizeof(IPV6_ADDR)); +- LOG_DEBUG("IPV6: def router " +- "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x " +- "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", +- ipv6->ipv6_src.addr8[0], ipv6->ipv6_src.addr8[1], +- ipv6->ipv6_src.addr8[2], ipv6->ipv6_src.addr8[3], +- ipv6->ipv6_src.addr8[4], ipv6->ipv6_src.addr8[5], +- ipv6->ipv6_src.addr8[6], ipv6->ipv6_src.addr8[7], +- ipv6->ipv6_src.addr8[8], ipv6->ipv6_src.addr8[9], +- ipv6->ipv6_src.addr8[10], ipv6->ipv6_src.addr8[11], +- ipv6->ipv6_src.addr8[12], ipv6->ipv6_src.addr8[13], +- ipv6->ipv6_src.addr8[14], ipv6->ipv6_src.addr8[15]); ++ /* There is a default router. */ ++ if (ipv6_context->ustack->router_autocfg != ++ IPV6_RTR_AUTOCFG_OFF) ++ memcpy( ++ (char __FAR__*)&ipv6_context->default_router, ++ (char __FAR__*)&ipv6->ipv6_src, ++ sizeof(IPV6_ADDR)); ++ inet_ntop(AF_INET6, &ipv6_context->default_router, ++ addr_str, sizeof(addr_str)); ++ LOG_DEBUG("IPV6: Got default router IP addr: %s", ++ addr_str); + } + } + } +@@ -903,6 +889,7 @@ STATIC void ipv6_icmp_process_prefix(pIPV6_CONTEXT ipv6_context, + pICMPV6_OPT_PREFIX icmp_prefix) + { + IPV6_ADDR addr; ++ char addr_str[INET6_ADDRSTRLEN]; + + /* we only process on-link address info */ + if (!(icmp_prefix->flags & ICMPV6_OPT_PREFIX_FLAG_ON_LINK)) +@@ -917,6 +904,8 @@ STATIC void ipv6_icmp_process_prefix(pIPV6_CONTEXT ipv6_context, + (char __FAR__ *)&icmp_prefix->prefix, 8); + memcpy((char __FAR__ *)&addr.addr8[8], + &ipv6_context->link_local_addr.addr8[8], 8); ++ inet_ntop(AF_INET6, &addr, addr_str, sizeof(addr_str)); ++ LOG_DEBUG("IPv6: Got RA ICMP option IP addr: %s", addr_str); + ipv6_add_prefix_entry(ipv6_context, &addr, 64); + } + } +@@ -929,11 +918,12 @@ STATIC void ipv6_icmp_handle_nd_adv(pIPV6_CONTEXT ipv6_context) + pICMPV6_OPT_LINK_ADDR link_opt = (pICMPV6_OPT_LINK_ADDR)((u8_t *)icmp + + sizeof(ICMPV6_HDR) + sizeof(IPV6_ADDR)); + pIPV6_ADDR tar_addr6; ++ char addr_str[INET6_ADDRSTRLEN]; + + /* Added the multicast check for ARP table update */ + /* Should we qualify for only our host's multicast and our + link_local_multicast?? */ +- LOG_DEBUG("IPV6: Handle nd adv"); ++ LOG_DEBUG("IPv6: Handle nd adv"); + if ((ipv6_is_it_our_address(ipv6_context, &ipv6->ipv6_dst) == TRUE) || + (memcmp((char __FAR__ *)&ipv6_context->link_local_multi, + (char __FAR__ *)&ipv6->ipv6_dst, sizeof(IPV6_ADDR)) == 0) || +@@ -951,21 +941,14 @@ STATIC void ipv6_icmp_handle_nd_adv(pIPV6_CONTEXT ipv6_context) + if (link_opt->hdr.type == IPV6_ICMP_OPTION_TAR_ADDR) { + tar_addr6 = (pIPV6_ADDR)((u8_t *)icmp + + sizeof(ICMPV6_HDR)); +- LOG_DEBUG("IPV6: tar mac %x:%x:%x:%x:%x:%x", ++ LOG_DEBUG("IPV6: Target MAC " ++ "%02x:%02x:%02x:%02x:%02x:%02x", + link_opt->link_addr[0], link_opt->link_addr[1], + link_opt->link_addr[2], link_opt->link_addr[3], + link_opt->link_addr[4], link_opt->link_addr[5]); +- LOG_DEBUG("IPV6: tar addr " +- "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x " +- "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", +- tar_addr6->addr8[0], tar_addr6->addr8[1], +- tar_addr6->addr8[2], tar_addr6->addr8[3], +- tar_addr6->addr8[4], tar_addr6->addr8[5], +- tar_addr6->addr8[6], tar_addr6->addr8[7], +- tar_addr6->addr8[8], tar_addr6->addr8[9], +- tar_addr6->addr8[10], tar_addr6->addr8[11], +- tar_addr6->addr8[12], tar_addr6->addr8[13], +- tar_addr6->addr8[14], tar_addr6->addr8[15]); ++ inet_ntop(AF_INET6, &tar_addr6->addr8, addr_str, ++ sizeof(addr_str)); ++ LOG_DEBUG("IPv6: Target IP addr %s", addr_str); + ipv6_update_arp_table(ipv6_context, tar_addr6, + (MAC_ADDR *)link_opt->link_addr); + } +@@ -985,14 +968,15 @@ STATIC void ipv6_icmp_handle_nd_sol(pIPV6_CONTEXT ipv6_context) + pIPV6_ADDR longest_match_addr; + pIPV6_ADDR tar_addr6; + +- LOG_DEBUG("IPV6: Handle nd sol"); ++ LOG_DEBUG("IPv6: Handle nd sol"); + + if ((memcmp((char __FAR__ *)&ipv6_context->mac_addr, + (char __FAR__ *)eth->dest_mac, sizeof(MAC_ADDR)) != 0) && + (iscsiL2IsOurMcAddr(ipv6_context, (pMAC_ADDRESS) & eth->dest_mac) == + FALSE)) { + /* This packet is not for us to handle */ +- LOG_DEBUG("IPV6: MAC not addressed to us %x:%x:%x:%x:%x:%x", ++ LOG_DEBUG("IPv6: MAC not addressed to us " ++ "%02x:%02x:%02x:%02x:%02x:%02x", + eth->dest_mac[0], eth->dest_mac[1], + eth->dest_mac[2], eth->dest_mac[3], + eth->dest_mac[4], eth->dest_mac[5]); +@@ -1005,7 +989,7 @@ STATIC void ipv6_icmp_handle_nd_sol(pIPV6_CONTEXT ipv6_context) + sizeof(ICMPV6_HDR))) + == FALSE) { + /* This packet is not for us to handle */ +- LOG_DEBUG("IPV6: IP not addressed to us"); ++ LOG_DEBUG("IPv6: IP not addressed to us"); + return; + } + +@@ -1026,7 +1010,7 @@ STATIC void ipv6_icmp_handle_nd_sol(pIPV6_CONTEXT ipv6_context) + tar_addr6 = (pIPV6_ADDR)((u8_t *)icmp + sizeof(ICMPV6_HDR)); + if (ipv6_is_it_our_link_local_address(ipv6_context, tar_addr6) + == TRUE) { +- LOG_DEBUG("IPV6: NA using link local"); ++ LOG_DEBUG("IPv6: NA using link local"); + memcpy((char __FAR__ *)&ipv6->ipv6_src, + (char __FAR__ *)&ipv6_context->link_local_addr, + sizeof(IPV6_ADDR)); +@@ -1034,12 +1018,12 @@ STATIC void ipv6_icmp_handle_nd_sol(pIPV6_CONTEXT ipv6_context) + longest_match_addr = + ipv6_find_longest_match(ipv6_context, tar_addr6); + if (longest_match_addr) { +- LOG_DEBUG("IPV6: NA using longest match addr"); ++ LOG_DEBUG("IPv6: NA using longest match addr"); + memcpy((char __FAR__ *)&ipv6->ipv6_src, + (char __FAR__ *)longest_match_addr, + sizeof(IPV6_ADDR)); + } else { +- LOG_DEBUG("IPV6: NA using link local instead"); ++ LOG_DEBUG("IPv6: NA using link local instead"); + memcpy((char __FAR__ *)&ipv6->ipv6_src, + (char __FAR__ *)&ipv6_context->link_local_addr, + sizeof(IPV6_ADDR)); +@@ -1047,7 +1031,7 @@ STATIC void ipv6_icmp_handle_nd_sol(pIPV6_CONTEXT ipv6_context) + } + } else { + /* No target link address, just use whatever it sent to us */ +- LOG_DEBUG("IPV6: NA use dst addr"); ++ LOG_DEBUG("IPv6: NA use dst addr"); + memcpy((char __FAR__ *)&ipv6->ipv6_src, + (char __FAR__ *)&tmp, + sizeof(IPV6_ADDR)); +@@ -1085,7 +1069,7 @@ STATIC void ipv6_icmp_handle_nd_sol(pIPV6_CONTEXT ipv6_context) + */ + ipv6->ipv6_plen = HOST_TO_NET16((sizeof(ICMPV6_HDR) + + icmpv6_opt_len + sizeof(IPV6_ADDR))); +- LOG_DEBUG("IPV6: Send nd adv"); ++ LOG_DEBUG("IPv6: Send nd adv"); + ipv6_send(ipv6_context, + (u8_t *) icmp - (u8_t *) eth + + sizeof(ICMPV6_HDR) + +@@ -1118,7 +1102,7 @@ STATIC void ipv6_icmp_handle_echo_request(pIPV6_CONTEXT ipv6_context) + icmp->icmpv6_type = ICMPV6_ECHO_REPLY; + icmp->icmpv6_code = 0; + icmp->icmpv6_cksum = 0; +- LOG_DEBUG("IPV6: Send echo reply"); ++ LOG_DEBUG("IPv6: Send echo reply"); + ipv6_send(ipv6_context, (u8_t *) icmp - (u8_t *) eth + + sizeof(IPV6_HDR) + HOST_TO_NET16(ipv6->ipv6_plen)); + return; +@@ -1126,7 +1110,8 @@ STATIC void ipv6_icmp_handle_echo_request(pIPV6_CONTEXT ipv6_context) + + void ipv6_set_ip_params(pIPV6_CONTEXT ipv6_context, + pIPV6_ADDR src_ip, u8_t prefix_len, +- pIPV6_ADDR default_gateway) ++ pIPV6_ADDR default_gateway, ++ pIPV6_ADDR linklocal) + { + if (!(IPV6_IS_ADDR_UNSPECIFIED(src_ip))) { + ipv6_add_prefix_entry(ipv6_context, src_ip, prefix_len); +@@ -1146,9 +1131,30 @@ void ipv6_set_ip_params(pIPV6_CONTEXT ipv6_context, + } + + if (!(IPV6_IS_ADDR_UNSPECIFIED(default_gateway))) { +- /* This is a default router. */ +- memcpy((char __FAR__ *)&ipv6_context->default_router, +- (char __FAR__ *)default_gateway, sizeof(IPV6_ADDR)); ++ /* Override the default gateway addr */ ++ memcpy((char __FAR__*)&ipv6_context->default_router, ++ (char __FAR__*)default_gateway, sizeof(IPV6_ADDR)); ++ ipv6_add_prefix_entry(ipv6_context, default_gateway, ++ prefix_len); ++ } ++ if (!(IPV6_IS_ADDR_UNSPECIFIED(linklocal))) { ++ /* Override the linklocal addr */ ++ memcpy((char __FAR__*)&ipv6_context->link_local_addr, ++ (char __FAR__*)linklocal, sizeof(IPV6_ADDR)); ++ ipv6_context->link_local_multi.addr8[0] = 0xff; ++ ipv6_context->link_local_multi.addr8[1] = 0x02; ++ ipv6_context->link_local_multi.addr8[11] = 0x01; ++ ipv6_context->link_local_multi.addr8[12] = 0xff; ++ ipv6_context->link_local_multi.addr8[13] |= ++ ipv6_context->link_local_addr.addr8[13]; ++ ipv6_context->link_local_multi.addr16[7] = ++ ipv6_context->link_local_addr.addr16[7]; ++ ++ /* Default Prefix length is 64 */ ++ /* Add Link local address to the head of the ipv6 address ++ list */ ++ ipv6_add_prefix_entry(ipv6_context, ++ &ipv6_context->link_local_addr, 64); + } + } + +@@ -1220,7 +1226,7 @@ u16_t ipv6_do_stateful_dhcpv6(pIPV6_CONTEXT ipv6_context, u32_t flags) + (IPV6_FLAGS_MANAGED_ADDR_CONFIG | IPV6_FLAGS_OTHER_STATEFUL_CONFIG); + + if (!(ipv6_context->flags & IPV6_FLAGS_ROUTER_ADV_RECEIVED)) { +- LOG_DEBUG("IPV6: There is no IPv6 router on the network"); ++ LOG_DEBUG("IPv6: There is no IPv6 router on the network"); + ra_flags |= + (IPV6_FLAGS_MANAGED_ADDR_CONFIG | + IPV6_FLAGS_OTHER_STATEFUL_CONFIG); +@@ -1234,7 +1240,7 @@ u16_t ipv6_do_stateful_dhcpv6(pIPV6_CONTEXT ipv6_context, u32_t flags) + (ra_flags & IPV6_FLAGS_OTHER_STATEFUL_CONFIG)) + task |= DHCPV6_TASK_GET_OTHER_PARAMS; + +- LOG_DEBUG("IPV6: Stateful flags=0x%x, ra_flags=0x%x, task=0x%x", flags, ++ LOG_DEBUG("IPv6: Stateful flags=0x%x, ra_flags=0x%x, task=0x%x", flags, + ra_flags, task); + + return task; +diff --git a/iscsiuio/src/uip/ipv6.h b/iscsiuio/src/uip/ipv6.h +index 167f5f6..ed2f3a4 100644 +--- a/iscsiuio/src/uip/ipv6.h ++++ b/iscsiuio/src/uip/ipv6.h +@@ -343,7 +343,8 @@ int ipv6_add_prefix_entry(pIPV6_CONTEXT ipv6_context, + IPV6_ADDR * ipv6_addr, u8_t prefix_len); + void ipv6_set_ip_params(pIPV6_CONTEXT ipv6_context, + pIPV6_ADDR src_ip, u8_t prefix_len, +- pIPV6_ADDR default_gateway); ++ pIPV6_ADDR default_gateway, ++ pIPV6_ADDR linklocal); + void ipv6_set_host_addr(pIPV6_CONTEXT ipv6_context, pIPV6_ADDR src_ip); + int ipv6_get_default_router_ip_addrs(pIPV6_CONTEXT ipv6_context, + pIPV6_ADDR ip_addr); +diff --git a/iscsiuio/src/uip/ipv6_ndpc.c b/iscsiuio/src/uip/ipv6_ndpc.c +index 6d101ce..89dbd5e 100644 +--- a/iscsiuio/src/uip/ipv6_ndpc.c ++++ b/iscsiuio/src/uip/ipv6_ndpc.c +@@ -65,6 +65,7 @@ static PT_THREAD(handle_ndp(struct uip_stack *ustack, int force)) + pIPV6_CONTEXT ipv6c; + pDHCPV6_CONTEXT dhcpv6c = NULL; + u16_t task = 0; ++ char buf[INET6_ADDRSTRLEN]; + + s = ustack->ndpc; + if (s == NULL) { +@@ -86,6 +87,9 @@ static PT_THREAD(handle_ndp(struct uip_stack *ustack, int force)) + if (s->state == NDPC_STATE_RTR_ADV) + goto rtr_adv; + ++ /* For AUTOCFG == DHCPv6, do all ++ For == ND, skip DHCP only and do RTR ++ For == UNUSED/UNSPEC, do all as according to DHCP or not */ + s->state = NDPC_STATE_RTR_SOL; + /* try_again: */ + s->ticks = CLOCK_SECOND * IPV6_MAX_ROUTER_SOL_DELAY; +@@ -97,7 +101,7 @@ static PT_THREAD(handle_ndp(struct uip_stack *ustack, int force)) + ipv6_autoconfig(s->ipv6_context); + + timer_set(&s->timer, s->ticks); +- wait_rtr: ++wait_rtr: + s->ustack->uip_flags &= ~UIP_NEWDATA; + LOG_DEBUG("%s: ndpc_handle wait for rtr adv flags=0x%x", + s->nic->log_name, ipv6c->flags); +@@ -134,10 +138,12 @@ no_rtr_adv: + s->state = NDPC_STATE_RTR_ADV; + + rtr_adv: +- /* Both Static IPv6 and DHCPv6 comes here */ ++ if (!(ustack->ip_config & IPV6_CONFIG_DHCP)) ++ goto staticv6; + ++ /* Only DHCPv6 comes here */ + task = ipv6_do_stateful_dhcpv6(ipv6c, ISCSI_FLAGS_DHCP_TCPIP_CONFIG); +- if (task && (ustack->ip_config == IPV6_CONFIG_DHCP)) { ++ if (task) { + /* Run the DHCPv6 engine */ + + if (!dhcpv6c) +@@ -187,6 +193,7 @@ wait_dhcp: + } + } while (dhcpv6c->dhcpv6_done == FALSE); + s->state = NDPC_STATE_DHCPV6_DONE; ++ + LOG_DEBUG("%s: ndpc_handle got dhcpv6", s->nic->log_name); + + /* End of DHCPv6 engine */ +@@ -197,28 +204,25 @@ wait_dhcp: + s->nic->log_name); + PT_RESTART(&s->pt); + } +- IPV6_ADDR tmp, tmp2; +- char buf[INET6_ADDRSTRLEN]; +- ++staticv6: + ipv6_disable_dhcpv6(ipv6c); +- memcpy(&tmp.addr8, &ustack->hostaddr6, sizeof(IPV6_ADDR)); +- LOG_DEBUG("%s: host ip addr %02x:%02x:%02x:%02x:%02x:%02x:" +- "%02x:%02x", s->nic->log_name, +- ustack->hostaddr6[0], ustack->hostaddr6[1], +- ustack->hostaddr6[2], ustack->hostaddr6[3], +- ustack->hostaddr6[4], ustack->hostaddr6[5], +- ustack->hostaddr6[6], ustack->hostaddr6[7]); +- memset(&tmp2, 0, sizeof(tmp2)); +- ipv6_set_ip_params(ipv6c, &tmp, +- ustack->prefix_len, &tmp2); +- +- ipv6_add_solit_node_address(ipv6c, &tmp); +- +- inet_ntop(AF_INET6, &tmp.addr8, buf, sizeof(buf)); +- LOG_INFO("%s: Static hostaddr IP: %s", s->nic->log_name, +- buf); +- + } ++ /* Copy out the default_router_addr6 and ll */ ++ if (ustack->router_autocfg != IPV6_RTR_AUTOCFG_OFF) ++ memcpy(&ustack->default_route_addr6, ++ &ipv6c->default_router, sizeof(IPV6_ADDR)); ++ inet_ntop(AF_INET6, &ustack->default_route_addr6, ++ buf, sizeof(buf)); ++ LOG_INFO("%s: Default router IP: %s", s->nic->log_name, ++ buf); ++ ++ if (ustack->linklocal_autocfg != IPV6_LL_AUTOCFG_OFF) ++ memcpy(&ustack->linklocal6, &ipv6c->link_local_addr, ++ sizeof(IPV6_ADDR)); ++ inet_ntop(AF_INET6, &ustack->linklocal6, ++ buf, sizeof(buf)); ++ LOG_INFO("%s: Linklocal IP: %s", s->nic->log_name, ++ buf); + + ipv6_loop: + s->state = NDPC_STATE_BACKGROUND_LOOP; +@@ -249,6 +253,8 @@ int ndpc_init(nic_t * nic, struct uip_stack *ustack, + pIPV6_CONTEXT ipv6c; + pDHCPV6_CONTEXT dhcpv6c; + struct ndpc_state *s = ustack->ndpc; ++ IPV6_ADDR src, gw, ll; ++ char buf[INET6_ADDRSTRLEN]; + + if (s) { + LOG_DEBUG("NDP: NDP context already allocated"); +@@ -315,9 +321,30 @@ init2: + + if (ustack->ip_config == IPV6_CONFIG_DHCP) { + /* DHCPv6 specific */ ++ memset(&src, 0, sizeof(src)); + } else { + /* Static v6 specific */ ++ memcpy(&src.addr8, &ustack->hostaddr6, sizeof(IPV6_ADDR)); ++ ipv6_add_solit_node_address(ipv6c, &src); ++ ++ inet_ntop(AF_INET6, &src.addr8, buf, sizeof(buf)); ++ LOG_INFO("%s: Static hostaddr IP: %s", s->nic->log_name, ++ buf); + } ++ /* Copy out the default_router_addr6 and ll */ ++ if (ustack->router_autocfg == IPV6_RTR_AUTOCFG_OFF) ++ memcpy(&gw.addr8, &ustack->default_route_addr6, ++ sizeof(IPV6_ADDR)); ++ else ++ memset(&gw, 0, sizeof(gw)); ++ ++ if (ustack->linklocal_autocfg == IPV6_LL_AUTOCFG_OFF) ++ memcpy(&ll.addr8, &ustack->linklocal6, ++ sizeof(IPV6_ADDR)); ++ else ++ memset(&ll, 0, sizeof(ll)); ++ ipv6_set_ip_params(ipv6c, &src, ++ ustack->prefix_len, &gw, &ll); + + return 0; + error2: +@@ -367,16 +394,14 @@ int ndpc_request(struct uip_stack *ustack, void *in, void *out, int request) + //LOG_DEBUG("%s: NDP - Request %d", s->nic->log_name, request); + + while (s->state != NDPC_STATE_BACKGROUND_LOOP) { +- LOG_DEBUG("%s: ndpc state not in background loop, run handler", +- s->nic->log_name); ++ LOG_DEBUG("%s: ndpc state not in background loop, run handler ", ++ "request = %d", s->nic->log_name, request); + handle_ndp(ustack, 1); + } + + ipv6c = s->ipv6_context; + switch (request) { + case NEIGHBOR_SOLICIT: +- LOG_DEBUG("nd sol: in=%p in->eth=%p in->ipv6=%p", in, in, +- (u8_t *) in + 4); + *(int *)out = ipv6_send_nd_solicited_packet(ipv6c, + (pETH_HDR) ((pNDPC_REQPTR)in)->eth, + (pIPV6_HDR) ((pNDPC_REQPTR)in)->ipv6); +@@ -385,12 +410,6 @@ int ndpc_request(struct uip_stack *ustack, void *in, void *out, int request) + *(int *)out = ipv6_is_it_our_link_local_address(ipv6c, + (pIPV6_ADDR)in); + break; +- case GET_LINK_LOCAL_ADDR: +- *(pIPV6_ADDR *) out = &ipv6c->link_local_addr; +- break; +- case GET_DEFAULT_ROUTER_ADDR: +- *(pIPV6_ADDR *)out = &ipv6c->default_router; +- break; + case CHECK_ARP_TABLE: + *(int *)out = ipv6_ip_in_arp_table(ipv6c, + (pIPV6_ADDR) ((pNDPC_REQPTR)in)->ipv6, +@@ -399,7 +418,9 @@ int ndpc_request(struct uip_stack *ustack, void *in, void *out, int request) + case GET_HOST_ADDR: + *(pIPV6_ADDR *)out = ipv6_find_longest_match(ipv6c, + (pIPV6_ADDR)in); ++ break; + default: ++ ret = -EINVAL; + break; + } + return ret; +diff --git a/iscsiuio/src/uip/uip.c b/iscsiuio/src/uip/uip.c +index 9c79e07..d03b92e 100644 +--- a/iscsiuio/src/uip/uip.c ++++ b/iscsiuio/src/uip/uip.c +@@ -1403,8 +1403,6 @@ void uip_process(struct uip_stack *ustack, u8_t flag) + #endif /* UIP_UDP */ + + /* This is IPv6 ICMPv6 processing code. */ +- LOG_DEBUG(PFX "icmp6_input: length %d", ustack->uip_len); +- + if (ipv6_hdr->ip6_nxt != UIP_PROTO_ICMP6) { + /* We only allow ICMPv6 packets from here. */ + ++ustack->stats.ip.drop; +@@ -2344,7 +2342,7 @@ tcp_send: + uip_ip6addr_copy(IPv6_BUF(ustack)->srcipaddr, + ustack->hostaddr6); + uip_ip6addr_copy(IPv6_BUF(ustack)->destipaddr, +- uip_connr->ripaddr); ++ uip_connr->ripaddr6); + } else { + tcp_ipv4_hdr->proto = UIP_PROTO_TCP; + uip_ip4addr_copy(tcp_ipv4_hdr->srcipaddr, ustack->hostaddr); +diff --git a/iscsiuio/src/uip/uip.h b/iscsiuio/src/uip/uip.h +index 2b5f88c..ccac680 100644 +--- a/iscsiuio/src/uip/uip.h ++++ b/iscsiuio/src/uip/uip.h +@@ -1031,6 +1031,7 @@ extern u16_t uip_urglen, uip_surglen; + */ + struct __attribute__ ((__packed__)) uip_conn { + uip_ip4addr_t ripaddr; ++ uip_ip6addr_t ripaddr6; + /**< The IP address of the remote host. */ + + u16_t lport; /**< The local TCP port, in network byte order. */ +@@ -1564,6 +1565,7 @@ struct uip_stack { + a new connection. */ + #endif /* UIP_ACTIVE_OPEN */ + ++#define IP_CONFIG_OFF 0x00 + #define IPV4_CONFIG_OFF 0x01 + #define IPV4_CONFIG_STATIC 0x02 + #define IPV4_CONFIG_DHCP 0x04 +@@ -1573,8 +1575,24 @@ struct uip_stack { + u8_t ip_config; + + uip_ip4addr_t hostaddr, netmask, default_route_addr; +- uip_ip6addr_t hostaddr6, netmask6, default_route_addr6; ++ uip_ip6addr_t hostaddr6, netmask6, default_route_addr6, ++ linklocal6; + int prefix_len; ++ u8_t ipv6_autocfg; ++#define IPV6_AUTOCFG_DHCPV6 (1<<0) ++#define IPV6_AUTOCFG_ND (1<<1) ++#define IPV6_AUTOCFG_NOTSPEC (1<<6) ++#define IPV6_AUTOCFG_NOTUSED (1<<7) ++ u8_t linklocal_autocfg; ++#define IPV6_LL_AUTOCFG_ON (1<<0) ++#define IPV6_LL_AUTOCFG_OFF (1<<1) ++#define IPV6_LL_AUTOCFG_NOTSPEC (1<<6) ++#define IPV6_LL_AUTOCFG_NOTUSED (1<<7) ++ u8_t router_autocfg; ++#define IPV6_RTR_AUTOCFG_ON (1<<0) ++#define IPV6_RTR_AUTOCFG_OFF (1<<1) ++#define IPV6_RTR_AUTOCFG_NOTSPEC (1<<6) ++#define IPV6_RTR_AUTOCFG_NOTUSED (1<<7) + + #define UIP_NEIGHBOR_ENTRIES 8 + struct neighbor_entry neighbor_entries[UIP_NEIGHBOR_ENTRIES]; +@@ -1586,7 +1604,6 @@ struct uip_stack { + pthread_mutex_t lock; + + /* IPv6 support */ +- + #define UIP_SUPPORT_IPv6_ENABLED 0x01 + #define UIP_SUPPORT_IPv6_DISABLED 0x02 + u8_t enable_IPv6; +diff --git a/iscsiuio/src/uip/uip_arp.c b/iscsiuio/src/uip/uip_arp.c +index 321281c..3ef3b07 100644 +--- a/iscsiuio/src/uip/uip_arp.c ++++ b/iscsiuio/src/uip/uip_arp.c +@@ -265,10 +265,14 @@ uip_arp_arpin(nic_interface_t * nic_iface, + arp->sipaddr[0] = ustack->hostaddr[0]; + arp->sipaddr[1] = ustack->hostaddr[1]; + +- if (nic_iface->vlan_id == 0) ++ if (nic_iface->vlan_id == 0) { + eth->type = htons(UIP_ETHTYPE_ARP); +- else ++ pkt->buf_size = sizeof(*arp) + sizeof(*eth); ++ } else { + eth->type = htons(UIP_ETHTYPE_8021Q); ++ pkt->buf_size = sizeof(*arp) + ++ sizeof(struct uip_vlan_eth_hdr); ++ } + pkt->buf_size = sizeof(*arp) + sizeof(*eth); + } + break; +diff --git a/iscsiuio/src/unix/iscsid_ipc.c b/iscsiuio/src/unix/iscsid_ipc.c +index 6bc5c11..d7372fc 100644 +--- a/iscsiuio/src/unix/iscsid_ipc.c ++++ b/iscsiuio/src/unix/iscsid_ipc.c +@@ -70,20 +70,34 @@ struct iscsid_options { + pthread_t thread; + }; + +-struct ip_addr_mask { +- int ip_type; +- union { +- struct in_addr addr4; +- struct in6_addr addr6; +- } addr; +- union { +- struct in_addr nm4; +- struct in6_addr nm6; +- } netmask; +-#define addr4 addr.addr4 +-#define addr6 addr.addr6 +-#define nm4 netmask.nm4 +-#define nm6 netmask.nm6 ++struct iface_rec_decode { ++ /* General */ ++ int32_t iface_num; ++ uint32_t ip_type; ++ ++ /* IPv4 */ ++ struct in_addr ipv4_addr; ++ struct in_addr ipv4_subnet_mask; ++ struct in_addr ipv4_gateway; ++ ++ /* IPv6 */ ++ struct in6_addr ipv6_addr; ++ struct in6_addr ipv6_subnet_mask; ++ uint32_t prefix_len; ++ struct in6_addr ipv6_linklocal; ++ struct in6_addr ipv6_router; ++ ++ uint8_t ipv6_autocfg; ++ uint8_t linklocal_autocfg; ++ uint8_t router_autocfg; ++ ++ uint8_t vlan_state; ++ uint8_t vlan_priority; ++ uint16_t vlan_id; ++ ++#define MIN_MTU_SUPPORT 46 ++#define MAX_MTU_SUPPORT 9000 ++ uint16_t mtu; + }; + + /****************************************************************************** +@@ -119,8 +133,7 @@ static void *enable_nic_thread(void *data) + pthread_exit(NULL); + } + +-static int decode_cidr(char *in_ipaddr_str, struct ip_addr_mask *ipam, +- int *prefix_len) ++static int decode_cidr(char *in_ipaddr_str, struct iface_rec_decode *ird) + { + int rc = 0, i; + char *tmp, *tok; +@@ -130,7 +143,6 @@ static int decode_cidr(char *in_ipaddr_str, struct ip_addr_mask *ipam, + struct in_addr ia; + struct in6_addr ia6; + +- memset(ipam, 0, sizeof(struct ip_addr_mask)); + if (strlen(in_ipaddr_str) > NI_MAXHOST) + strncpy(ipaddr_str, in_ipaddr_str, NI_MAXHOST); + else +@@ -149,16 +161,16 @@ static int decode_cidr(char *in_ipaddr_str, struct ip_addr_mask *ipam, + + /* Determine if the IP address passed from the iface file is + * an IPv4 or IPv6 address */ +- rc = inet_pton(AF_INET, ipaddr_str, &ipam->addr6); ++ rc = inet_pton(AF_INET, ipaddr_str, &ird->ipv6_addr); + if (rc == 0) { + /* Test to determine if the addres is an IPv6 address */ +- rc = inet_pton(AF_INET6, ipaddr_str, &ipam->addr6); ++ rc = inet_pton(AF_INET6, ipaddr_str, &ird->ipv6_addr); + if (rc == 0) { + LOG_ERR(PFX "Could not parse IP address: '%s'", + ipaddr_str); + goto out; + } +- ipam->ip_type = AF_INET6; ++ ird->ip_type = AF_INET6; + if (keepbits > 128) { + LOG_ERR(PFX "CIDR netmask > 128 for IPv6: %d(%s)", + keepbits, tmp); +@@ -166,15 +178,15 @@ static int decode_cidr(char *in_ipaddr_str, struct ip_addr_mask *ipam, + } + if (!keepbits) { + /* Default prefix mask to 64 */ +- memcpy(&ipam->nm6.s6_addr, all_zeroes_addr6, ++ memcpy(&ird->ipv6_subnet_mask.s6_addr, all_zeroes_addr6, + sizeof(struct in6_addr)); ++ ird->prefix_len = 64; + for (i = 0; i < 2; i++) +- ipam->nm6.s6_addr32[i] = 0xffffffff; ++ ird->ipv6_subnet_mask.s6_addr32[i] = 0xffffffff; + goto out; + } +- *prefix_len = keepbits; +- memcpy(&ia6.s6_addr, all_zeroes_addr6, +- sizeof(struct in6_addr)); ++ ird->prefix_len = keepbits; ++ memcpy(&ia6.s6_addr, all_zeroes_addr6, sizeof(struct in6_addr)); + for (i = 0; i < 4; i++) { + if (keepbits < 32) { + ia6.s6_addr32[i] = keepbits > 0 ? +@@ -184,12 +196,12 @@ static int decode_cidr(char *in_ipaddr_str, struct ip_addr_mask *ipam, + ia6.s6_addr32[i] = 0xFFFFFFFF; + keepbits -= 32; + } +- ipam->nm6 = ia6; ++ ird->ipv6_subnet_mask = ia6; + if (inet_ntop(AF_INET6, &ia6, str, sizeof(str))) + LOG_INFO(PFX "Using netmask: %s", str); + } else { +- ipam->ip_type = AF_INET; +- rc = inet_pton(AF_INET, ipaddr_str, &ipam->addr4); ++ ird->ip_type = AF_INET; ++ rc = inet_pton(AF_INET, ipaddr_str, &ird->ipv4_addr); + + if (keepbits > 32) { + LOG_ERR(PFX "CIDR netmask > 32 for IPv4: %d(%s)", +@@ -197,54 +209,153 @@ static int decode_cidr(char *in_ipaddr_str, struct ip_addr_mask *ipam, + goto out; + } + ia.s_addr = keepbits > 0 ? 0x00 - (1 << (32 - keepbits)) : 0; +- ipam->nm4.s_addr = htonl(ia.s_addr); +- LOG_INFO(PFX "Using netmask: %s", inet_ntoa(ipam->nm4)); ++ ird->ipv4_subnet_mask.s_addr = htonl(ia.s_addr); ++ LOG_INFO(PFX "Using netmask: %s", ++ inet_ntoa(ird->ipv4_subnet_mask)); + } + out: + return rc; + } + ++static int decode_iface(struct iface_rec_decode *ird, struct iface_rec *rec) ++{ ++ int rc = 0; ++ char ipaddr_str[NI_MAXHOST]; ++ ++ /* Decodes the rec contents */ ++ memset(ird, 0, sizeof(struct iface_rec_decode)); ++ ++ /* Detect for CIDR notation and strip off the netmask if present */ ++ rc = decode_cidr(rec->ipaddress, ird); ++ if (rc && !ird->ip_type) { ++ LOG_ERR(PFX "cidr decode err: rc=%d, ip_type=%d", ++ rc, ird->ip_type); ++ /* Can't decode address, just exit */ ++ return rc; ++ } ++ rc = 0; ++ ++ ird->iface_num = rec->iface_num; ++ ird->vlan_id = rec->vlan_id; ++ if (rec->iface_num != IFACE_NUM_INVALID) { ++ ird->mtu = rec->mtu; ++ if (rec->vlan_id && strcmp(rec->vlan_state, "disable")) { ++ ird->vlan_state = 1; ++ ird->vlan_priority = rec->vlan_priority; ++ ird->vlan_id = rec->vlan_id; ++ } ++ if (ird->ip_type == AF_INET6) { ++ if (!strcmp(rec->ipv6_autocfg, "dhcpv6")) ++ ird->ipv6_autocfg = IPV6_AUTOCFG_DHCPV6; ++ else if (!strcmp(rec->ipv6_autocfg, "nd")) ++ ird->ipv6_autocfg = IPV6_AUTOCFG_ND; ++ else ++ ird->ipv6_autocfg = IPV6_AUTOCFG_NOTSPEC; ++ ++ if (!strcmp(rec->linklocal_autocfg, "auto")) ++ ird->linklocal_autocfg = IPV6_LL_AUTOCFG_ON; ++ else if (!strcmp(rec->linklocal_autocfg, "off")) ++ ird->linklocal_autocfg = IPV6_LL_AUTOCFG_OFF; ++ else /* default */ ++ ird->linklocal_autocfg = IPV6_LL_AUTOCFG_ON; ++ ++ if (!strcmp(rec->router_autocfg, "auto")) ++ ird->router_autocfg = IPV6_RTR_AUTOCFG_ON; ++ else if (!strcmp(rec->router_autocfg, "off")) ++ ird->router_autocfg = IPV6_RTR_AUTOCFG_OFF; ++ else /* default */ ++ ird->router_autocfg = IPV6_RTR_AUTOCFG_ON; ++ ++ /* Decode the addresses based on the control flags */ ++ /* For DHCP, ignore the IPv6 addr in the iface */ ++ if (ird->ipv6_autocfg == IPV6_AUTOCFG_DHCPV6) ++ memcpy(&ird->ipv6_addr, all_zeroes_addr6, ++ sizeof(struct in6_addr)); ++ /* Subnet mask priority: CIDR, then rec */ ++ if (!ird->ipv6_subnet_mask.s6_addr) ++ inet_pton(AF_INET, rec->subnet_mask, ++ &ird->ipv6_subnet_mask); ++ ++ /* For LL on, ignore the IPv6 addr in the iface */ ++ if (ird->linklocal_autocfg == IPV6_LL_AUTOCFG_OFF) { ++ if (strlen(rec->ipv6_linklocal) > NI_MAXHOST) ++ strncpy(ipaddr_str, rec->ipv6_linklocal, ++ NI_MAXHOST); ++ else ++ strcpy(ipaddr_str, rec->ipv6_linklocal); ++ inet_pton(AF_INET6, ipaddr_str, ++ &ird->ipv6_linklocal); ++ } ++ ++ /* For RTR on, ignore the IPv6 addr in the iface */ ++ if (ird->router_autocfg == IPV6_RTR_AUTOCFG_OFF) { ++ if (strlen(rec->ipv6_router) > NI_MAXHOST) ++ strncpy(ipaddr_str, rec->ipv6_router, ++ NI_MAXHOST); ++ else ++ strcpy(ipaddr_str, rec->ipv6_router); ++ inet_pton(AF_INET6, ipaddr_str, ++ &ird->ipv6_router); ++ } ++ } else { ++ /* Subnet mask priority: CIDR, rec, default */ ++ if (!ird->ipv4_subnet_mask.s_addr) ++ inet_pton(AF_INET, rec->subnet_mask, ++ &ird->ipv4_subnet_mask); ++ if (!ird->ipv4_subnet_mask.s_addr) ++ ird->ipv4_subnet_mask.s_addr = ++ calculate_default_netmask( ++ ird->ipv4_addr.s_addr); ++ ++ if (strlen(rec->gateway) > NI_MAXHOST) ++ strncpy(ipaddr_str, rec->gateway, NI_MAXHOST); ++ else ++ strcpy(ipaddr_str, rec->gateway); ++ inet_pton(AF_INET, ipaddr_str, &ird->ipv4_gateway); ++ } ++ } else { ++ ird->ipv6_autocfg = IPV6_AUTOCFG_NOTUSED; ++ ird->linklocal_autocfg = IPV6_LL_AUTOCFG_NOTUSED; ++ ird->router_autocfg = IPV6_RTR_AUTOCFG_NOTUSED; ++ } ++ return rc; ++} ++ + static int parse_iface(void *arg) + { +- int rc; ++ int rc, i; + nic_t *nic = NULL; +- nic_interface_t *nic_iface, *vlan_iface, *base_nic_iface; ++ nic_interface_t *nic_iface; + char *transport_name; + size_t transport_name_size; + nic_lib_handle_t *handle; + iscsid_uip_broadcast_t *data; +- short int vlan; + char ipv6_buf_str[INET6_ADDRSTRLEN]; + int request_type = 0; +- struct in_addr netmask; +- int i, prefix_len = 64; +- struct ip_addr_mask ipam; + struct iface_rec *rec; + void *res; ++ struct iface_rec_decode ird; ++ struct in_addr src_match, dst_match; + + data = (iscsid_uip_broadcast_t *) arg; + + rec = &data->u.iface_rec.rec; + LOG_INFO(PFX "Received request for '%s' to set IP address: '%s' " +- "VLAN: '%d'", rec->netdev, rec->ipaddress, rec->vlan_id); +- +- vlan = rec->vlan_id; +- if (vlan && valid_vlan(vlan) == 0) { +- LOG_ERR(PFX "Invalid VLAN tag: %d", rec->vlan_id); ++ "VLAN: '%d'", ++ rec->netdev, ++ rec->ipaddress, ++ rec->vlan_id); ++ ++ rc = decode_iface(&ird, rec); ++ if (ird.vlan_id && valid_vlan(ird.vlan_id) == 0) { ++ LOG_ERR(PFX "Invalid VLAN tag: %d", ird.vlan_id); + rc = -EIO; + goto early_exit; + } +- +- /* Detect for CIDR notation and strip off the netmask if present */ +- rc = decode_cidr(rec->ipaddress, &ipam, &prefix_len); +- if (rc && !ipam.ip_type) { +- LOG_ERR(PFX "decode_cidr: rc=%d, ipam.ip_type=%d", +- rc, ipam.ip_type) +- goto early_exit; +- } +- if (ipam.ip_type == AF_INET6) +- inet_ntop(AF_INET6, &ipam.addr6, ipv6_buf_str, +- sizeof(ipv6_buf_str)); ++ if (rc && !ird.ip_type) { ++ LOG_ERR(PFX "iface err: rc=%d, ip_type=%d", rc, ird.ip_type); ++ goto early_exit; ++ } + + for (i = 0; i < 10; i++) { + struct timespec sleep_req, sleep_rem; +@@ -258,11 +369,13 @@ static int parse_iface(void *arg) + } + + if (i >= 10) { +- LOG_WARN(PFX "Could not aquire nic_list_mutex lock"); ++ LOG_WARN(PFX "Could not acquire nic_list_mutex lock"); + rc = -EIO; + goto early_exit; + } + ++ /* nic_list_mutex locked */ ++ + /* Check if we can find the NIC device using the netdev + * name */ + rc = from_netdev_name_find_nic(rec->netdev, &nic); +@@ -298,21 +411,22 @@ static int parse_iface(void *arg) + rec->netdev); + } + ++ pthread_mutex_lock(&nic->nic_mutex); + if (nic->flags & NIC_GOING_DOWN) { ++ pthread_mutex_unlock(&nic->nic_mutex); + rc = -EIO; + LOG_INFO(PFX "nic->flags GOING DOWN"); + goto done; + } + +- /* If we retry too many times allow iscsid to to timeout */ ++ /* If we retry too many times allow iscsid to timeout */ + if (nic->pending_count > 1000) { +- LOG_WARN(PFX "%s: pending count excceded 1000", nic->log_name); +- +- pthread_mutex_lock(&nic->nic_mutex); + nic->pending_count = 0; + nic->flags &= ~NIC_ENABLED_PENDING; + pthread_mutex_unlock(&nic->nic_mutex); + ++ LOG_WARN(PFX "%s: pending count exceeded 1000", nic->log_name); ++ + rc = 0; + goto done; + } +@@ -320,18 +434,19 @@ static int parse_iface(void *arg) + if (nic->flags & NIC_ENABLED_PENDING) { + struct timespec sleep_req, sleep_rem; + ++ nic->pending_count++; ++ pthread_mutex_unlock(&nic->nic_mutex); ++ + sleep_req.tv_sec = 0; + sleep_req.tv_nsec = 100000; + nanosleep(&sleep_req, &sleep_rem); + +- pthread_mutex_lock(&nic->nic_mutex); +- nic->pending_count++; +- pthread_mutex_unlock(&nic->nic_mutex); +- + LOG_INFO(PFX "%s: enabled pending", nic->log_name); ++ + rc = -EAGAIN; + goto done; + } ++ pthread_mutex_unlock(&nic->nic_mutex); + + prepare_library(nic); + +@@ -359,66 +474,9 @@ static int parse_iface(void *arg) + LOG_INFO(PFX "%s library set using transport_name %s", + nic->log_name, transport_name); + +- /* Create the base network interface if it doesn't exist */ +- nic_iface = nic_find_nic_iface_protocol(nic, 0, ipam.ip_type); +- if (nic_iface == NULL) { +- LOG_INFO(PFX "%s couldn't find interface with " +- "ip_type: 0x%x creating it", +- nic->log_name, ipam.ip_type); +- +- /* Create the nic interface */ +- nic_iface = nic_iface_init(); +- +- if (nic_iface == NULL) { +- LOG_ERR(PFX "Couldn't allocate nic_iface", nic_iface); +- goto done; +- } +- +- nic_iface->protocol = ipam.ip_type; +- nic_add_nic_iface(nic, nic_iface); +- +- persist_all_nic_iface(nic); +- +- LOG_INFO(PFX "%s: created network interface", nic->log_name); +- } else { +- LOG_INFO(PFX "%s: using existing network interface", +- nic->log_name); +- } +- +- set_nic_iface(nic, nic_iface); +- +- /* Find the vlan nic_interface */ +- if (vlan) { +- vlan_iface = nic_find_vlan_iface_protocol(nic, nic_iface, vlan, +- ipam.ip_type); +- if (vlan_iface == NULL) { +- LOG_INFO(PFX "%s couldn't find interface with VLAN = %d" +- "ip_type: 0x%x creating it", +- nic->log_name, vlan, ipam.ip_type); +- +- /* Create the nic interface */ +- vlan_iface = nic_iface_init(); +- +- if (vlan_iface == NULL) { +- LOG_ERR(PFX "Couldn't allocate nic_iface for " +- "VLAN: %d", vlan_iface, vlan); +- goto done; +- } +- +- vlan_iface->protocol = ipam.ip_type; +- vlan_iface->vlan_id = vlan; +- nic_add_vlan_iface(nic, nic_iface, vlan_iface); +- } else { +- LOG_INFO(PFX "%s: using existing vlan interface", +- nic->log_name); +- } +- base_nic_iface = nic_iface; +- nic_iface = vlan_iface; +- } +- + /* Determine how to configure the IP address */ +- if (ipam.ip_type == AF_INET) { +- if (memcmp(&ipam.addr4, ++ if (ird.ip_type == AF_INET) { ++ if (memcmp(&ird.ipv4_addr, + all_zeroes_addr4, sizeof(uip_ip4addr_t)) == 0) { + LOG_INFO(PFX "%s: requesting configuration using DHCP", + nic->log_name); +@@ -428,51 +486,161 @@ static int parse_iface(void *arg) + "static IP address", nic->log_name); + request_type = IPV4_CONFIG_STATIC; + } +- } else if (ipam.ip_type == AF_INET6) { +- if (memcmp(&ipam.addr6, +- all_zeroes_addr6, sizeof(uip_ip6addr_t)) == 0) { +- LOG_INFO(PFX +- "%s: requesting configuration using DHCPv6", +- nic->log_name); ++ } else if (ird.ip_type == AF_INET6) { ++ /* For the new 872_22, check ipv6_autocfg for DHCPv6 instead */ ++ switch (ird.ipv6_autocfg) { ++ case IPV6_AUTOCFG_DHCPV6: + request_type = IPV6_CONFIG_DHCP; +- } else { +- LOG_INFO(PFX "%s: request configuration using static " +- "IPv6 address: '%s'", +- nic->log_name, ipv6_buf_str); ++ break; ++ case IPV6_AUTOCFG_ND: + request_type = IPV6_CONFIG_STATIC; ++ break; ++ case IPV6_AUTOCFG_NOTSPEC: ++ /* Treat NOTSPEC the same as NOTUSED for now */ ++ case IPV6_AUTOCFG_NOTUSED: ++ /* For 871 */ ++ default: ++ /* Just the IP address to determine */ ++ if (memcmp(&ird.ipv6_addr, ++ all_zeroes_addr6, ++ sizeof(struct in6_addr)) == 0) ++ request_type = IPV6_CONFIG_DHCP; ++ else ++ request_type = IPV6_CONFIG_STATIC; + } + } else { + LOG_ERR(PFX "%s: unknown ip_type to configure: 0x%x", +- nic->log_name, ipam.ip_type); ++ nic->log_name, ird.ip_type); + + rc = -EIO; + goto done; + } + ++ pthread_mutex_lock(&nic->nic_mutex); ++ ++ nic_iface = nic_find_nic_iface(nic, ird.ip_type, ird.vlan_id, ++ ird.iface_num, request_type); ++ ++ if (nic->flags & NIC_PATHREQ_WAIT) { ++ if (!nic_iface || ++ !(nic_iface->flags & NIC_IFACE_PATHREQ_WAIT)) { ++ int pathreq_wait; ++ ++ if (nic_iface && ++ (nic_iface->flags & NIC_IFACE_PATHREQ_WAIT2)) ++ pathreq_wait = 12; ++ else ++ pathreq_wait = 10; ++ ++ if (nic->pathreq_pending_count < pathreq_wait) { ++ struct timespec sleep_req, sleep_rem; ++ ++ pthread_mutex_unlock(&nic->nic_mutex); ++ ++ nic->pathreq_pending_count++; ++ sleep_req.tv_sec = 0; ++ sleep_req.tv_nsec = 100000; ++ nanosleep(&sleep_req, &sleep_rem); ++ /* Somebody else is waiting for PATH_REQ */ ++ LOG_INFO(PFX "%s: path req pending cnt=%d", ++ nic->log_name, ++ nic->pathreq_pending_count); ++ rc = -EAGAIN; ++ goto done; ++ } else { ++ nic->pathreq_pending_count = 0; ++ LOG_DEBUG(PFX "%s: path req pending cnt " ++ "exceeded!", nic->log_name); ++ /* Allow to fall thru */ ++ } ++ } ++ } ++ ++ nic->flags |= NIC_PATHREQ_WAIT; ++ ++ /* Create the network interface if it doesn't exist */ ++ if (nic_iface == NULL) { ++ LOG_DEBUG(PFX "%s couldn't find interface with " ++ "ip_type: 0x%x creating it", ++ nic->log_name, ird.ip_type); ++ nic_iface = nic_iface_init(); ++ ++ if (nic_iface == NULL) { ++ pthread_mutex_unlock(&nic->nic_mutex); ++ LOG_ERR(PFX "%s Couldn't allocate " ++ "interface with ip_type: 0x%x", ++ nic->log_name, ird.ip_type); ++ goto done; ++ } ++ nic_iface->protocol = ird.ip_type; ++ nic_iface->vlan_id = ird.vlan_id; ++ nic_iface->vlan_priority = ird.vlan_priority; ++ if (ird.mtu >= MIN_MTU_SUPPORT && ird.mtu <= MAX_MTU_SUPPORT) ++ nic_iface->mtu = ird.mtu; ++ nic_iface->iface_num = ird.iface_num; ++ nic_iface->request_type = request_type; ++ nic_add_nic_iface(nic, nic_iface); ++ ++ persist_all_nic_iface(nic); ++ ++ LOG_INFO(PFX "%s: created network interface", ++ nic->log_name); ++ } else { ++ /* Move the nic_iface to the front */ ++ set_nic_iface(nic, nic_iface); ++ LOG_INFO(PFX "%s: using existing network interface", ++ nic->log_name); ++ } ++ ++ nic_iface->flags |= NIC_IFACE_PATHREQ_WAIT1; ++ if (nic->nl_process_thread == INVALID_THREAD) { ++ rc = pthread_create(&nic->nl_process_thread, NULL, ++ nl_process_handle_thread, nic); ++ if (rc != 0) { ++ LOG_ERR(PFX "%s: Could not create NIC NL " ++ "processing thread [%s]", nic->log_name, ++ strerror(rc)); ++ nic->nl_process_thread = INVALID_THREAD; ++ /* Reset both WAIT flags */ ++ nic_iface->flags &= ~NIC_IFACE_PATHREQ_WAIT; ++ nic->flags &= ~NIC_PATHREQ_WAIT; ++ } ++ } ++ ++ pthread_mutex_unlock(&nic->nic_mutex); ++ + if (nic_iface->ustack.ip_config == request_type) { ++ /* Same request_type, check for STATIC address change */ + if (request_type == IPV4_CONFIG_STATIC) { +- if (memcmp(nic_iface->ustack.hostaddr, &ipam.addr4, ++ if (memcmp(nic_iface->ustack.hostaddr, &ird.ipv4_addr, + sizeof(struct in_addr))) +- goto diff; ++ goto reacquire; + } else if (request_type == IPV6_CONFIG_STATIC) { +- if (memcmp(nic_iface->ustack.hostaddr6, &ipam.addr6, ++ if (memcmp(nic_iface->ustack.hostaddr6, &ird.ipv6_addr, + sizeof(struct in6_addr))) +- goto diff; ++ goto reacquire; ++ else ++ inet_ntop(AF_INET6, &ird.ipv6_addr, ++ ipv6_buf_str, ++ sizeof(ipv6_buf_str)); + } + LOG_INFO(PFX "%s: IP configuration didn't change using 0x%x", + nic->log_name, nic_iface->ustack.ip_config); +- goto enable_nic; +-diff: +- /* Disable the NIC */ +- nic_disable(nic, 0); +- } else { +- if (request_type == IPV4_CONFIG_DHCP +- || request_type == IPV6_CONFIG_DHCP) +- nic->flags |= NIC_RESET_UIP; ++ /* No need to acquire the IP address */ ++ inet_ntop(AF_INET6, &ird.ipv6_addr, ipv6_buf_str, ++ sizeof(ipv6_buf_str)); + +- /* Disable the NIC */ +- nic_disable(nic, 0); ++ goto enable_nic; + } ++reacquire: ++ /* Config needs to re-acquire for this nic_iface */ ++ pthread_mutex_lock(&nic->nic_mutex); ++ nic_iface->flags |= NIC_IFACE_ACQUIRE; ++ pthread_mutex_unlock(&nic->nic_mutex); ++ ++ /* Disable the nic loop from further processing, upon returned, ++ the nic_iface should be cleared */ ++ nic_disable(nic, 0); + + /* Check to see if this is using DHCP or if this is + * a static IPv4 address. This is done by checking +@@ -485,97 +653,96 @@ diff: + memset(nic_iface->ustack.hostaddr, 0, sizeof(struct in_addr)); + LOG_INFO(PFX "%s: configuring using DHCP", nic->log_name); + nic_iface->ustack.ip_config = IPV4_CONFIG_DHCP; +- + break; ++ + case IPV4_CONFIG_STATIC: +- memcpy(nic_iface->ustack.hostaddr, &ipam.addr4, ++ memcpy(nic_iface->ustack.hostaddr, &ird.ipv4_addr, + sizeof(struct in_addr)); + LOG_INFO(PFX "%s: configuring using static IP " + "IPv4 address :%s ", +- nic->log_name, inet_ntoa(ipam.addr4)); +- netmask.s_addr = ipam.nm4.s_addr; +- if (!netmask.s_addr) +- netmask.s_addr = +- calculate_default_netmask(ipam.addr4.s_addr); +- memcpy(nic_iface->ustack.netmask, +- &netmask, sizeof(netmask.s_addr)); +- LOG_INFO(PFX " netmask :%s", inet_ntoa(netmask)); +- ++ nic->log_name, inet_ntoa(ird.ipv4_addr)); ++ ++ if (ird.ipv4_subnet_mask.s_addr) ++ memcpy(nic_iface->ustack.netmask, ++ &ird.ipv4_subnet_mask, sizeof(struct in_addr)); ++ LOG_INFO(PFX " netmask: %s", inet_ntoa(ird.ipv4_subnet_mask)); ++ ++ /* Default route */ ++ if (ird.ipv4_gateway.s_addr) { ++ /* Check for validity */ ++ src_match.s_addr = ird.ipv4_addr.s_addr & ++ ird.ipv4_subnet_mask.s_addr; ++ dst_match.s_addr = ird.ipv4_gateway.s_addr & ++ ird.ipv4_subnet_mask.s_addr; ++ if (src_match.s_addr == dst_match.s_addr) ++ memcpy(nic_iface->ustack.default_route_addr, ++ &ird.ipv4_gateway, ++ sizeof(struct in_addr)); ++ } + nic_iface->ustack.ip_config = IPV4_CONFIG_STATIC; + break; ++ + case IPV6_CONFIG_DHCP: + memset(nic_iface->ustack.hostaddr6, 0, + sizeof(struct in6_addr)); +- nic_iface->ustack.prefix_len = prefix_len; +- if (ipam.nm6.s6_addr[0] | ipam.nm6.s6_addr[1] | +- ipam.nm6.s6_addr[2] | ipam.nm6.s6_addr[3] | +- ipam.nm6.s6_addr[4] | ipam.nm6.s6_addr[5] | +- ipam.nm6.s6_addr[6] | ipam.nm6.s6_addr[7]) ++ nic_iface->ustack.prefix_len = ird.prefix_len; ++ nic_iface->ustack.ipv6_autocfg = ird.ipv6_autocfg; ++ nic_iface->ustack.linklocal_autocfg = ird.linklocal_autocfg; ++ nic_iface->ustack.router_autocfg = ird.router_autocfg; ++ ++ if (memcmp(&ird.ipv6_subnet_mask, all_zeroes_addr6, ++ sizeof(struct in6_addr))) + memcpy(nic_iface->ustack.netmask6, +- &ipam.nm6, sizeof(struct in6_addr)); ++ &ird.ipv6_subnet_mask, sizeof(struct in6_addr)); ++ if (ird.linklocal_autocfg == IPV6_LL_AUTOCFG_OFF) ++ memcpy(nic_iface->ustack.linklocal6, ++ &ird.ipv6_linklocal, sizeof(struct in6_addr)); ++ if (ird.router_autocfg == IPV6_RTR_AUTOCFG_OFF) ++ memcpy(nic_iface->ustack.default_route_addr6, ++ &ird.ipv6_router, sizeof(struct in6_addr)); ++ inet_ntop(AF_INET6, &ird.ipv6_addr, ipv6_buf_str, ++ sizeof(ipv6_buf_str)); + LOG_INFO(PFX "%s: configuring using DHCPv6", + nic->log_name); + nic_iface->ustack.ip_config = IPV6_CONFIG_DHCP; + break; ++ + case IPV6_CONFIG_STATIC: +- memcpy(nic_iface->ustack.hostaddr6, &ipam.addr6, ++ memcpy(nic_iface->ustack.hostaddr6, &ird.ipv6_addr, + sizeof(struct in6_addr)); ++ nic_iface->ustack.prefix_len = ird.prefix_len; ++ nic_iface->ustack.ipv6_autocfg = ird.ipv6_autocfg; ++ nic_iface->ustack.linklocal_autocfg = ird.linklocal_autocfg; ++ nic_iface->ustack.router_autocfg = ird.router_autocfg; + +- nic_iface->ustack.prefix_len = prefix_len; +- if (ipam.nm6.s6_addr[0] | ipam.nm6.s6_addr[1] | +- ipam.nm6.s6_addr[2] | ipam.nm6.s6_addr[3] | +- ipam.nm6.s6_addr[4] | ipam.nm6.s6_addr[5] | +- ipam.nm6.s6_addr[6] | ipam.nm6.s6_addr[7]) ++ if (memcmp(&ird.ipv6_subnet_mask, all_zeroes_addr6, ++ sizeof(struct in6_addr))) + memcpy(nic_iface->ustack.netmask6, +- &ipam.nm6, sizeof(struct in6_addr)); +- ++ &ird.ipv6_subnet_mask, sizeof(struct in6_addr)); ++ if (ird.linklocal_autocfg == IPV6_LL_AUTOCFG_OFF) ++ memcpy(nic_iface->ustack.linklocal6, ++ &ird.ipv6_linklocal, sizeof(struct in6_addr)); ++ if (ird.router_autocfg == IPV6_RTR_AUTOCFG_OFF) ++ memcpy(nic_iface->ustack.default_route_addr6, ++ &ird.ipv6_router, sizeof(struct in6_addr)); ++ ++ inet_ntop(AF_INET6, &ird.ipv6_addr, ipv6_buf_str, ++ sizeof(ipv6_buf_str)); + LOG_INFO(PFX "%s: configuring using static IP " + "IPv6 address: '%s'", nic->log_name, ipv6_buf_str); + + nic_iface->ustack.ip_config = IPV6_CONFIG_STATIC; + break; ++ + default: + LOG_INFO(PFX "%s: Unknown request type: 0x%x", + nic->log_name, request_type); + + } + +- /* Configuration changed, do VLAN WA */ +- vlan_iface = nic_iface->vlan_next; +- while (vlan_iface) { +- /* TODO: When VLAN support is placed in the iface file +- * revisit this code */ +- if (vlan_iface->ustack.ip_config) { +- vlan_iface->ustack.ip_config = +- nic_iface->ustack.ip_config; +- memcpy(vlan_iface->ustack.hostaddr, +- nic_iface->ustack.hostaddr, +- sizeof(nic_iface->ustack.hostaddr)); +- memcpy(vlan_iface->ustack.netmask, +- nic_iface->ustack.netmask, +- sizeof(nic_iface->ustack.netmask)); +- memcpy(vlan_iface->ustack.hostaddr6, +- nic_iface->ustack.hostaddr6, +- sizeof(nic_iface->ustack.hostaddr6)); +- memcpy(vlan_iface->ustack.netmask6, +- nic_iface->ustack.netmask6, +- sizeof(nic_iface->ustack.netmask6)); +- } +- vlan_iface = vlan_iface->vlan_next; +- } +- + enable_nic: +- if (nic->state & NIC_STOPPED) { +- pthread_mutex_lock(&nic->nic_mutex); +- if (nic->flags & NIC_ENABLED_PENDING) { +- /* Still waiting */ +- pthread_mutex_unlock(&nic->nic_mutex); +- rc = 0; +- goto enable_out; +- } +- nic->flags |= NIC_ENABLED_PENDING; +- pthread_mutex_unlock(&nic->nic_mutex); +- ++ switch (nic->state) { ++ case NIC_STOPPED: + /* This thread will be thrown away when completed */ + if (nic->enable_thread != INVALID_THREAD) { + rc = pthread_join(nic->enable_thread, &res); +@@ -592,19 +759,27 @@ enable_nic: + nic->log_name); + eagain: + rc = -EAGAIN; +- } else { ++ break; ++ ++ case NIC_RUNNING: + LOG_INFO(PFX "%s: NIC already enabled " + "flags: 0x%x state: 0x%x\n", + nic->log_name, nic->flags, nic->state); + rc = 0; ++ break; ++ default: ++ LOG_INFO(PFX "%s: NIC enable still in progress " ++ "flags: 0x%x state: 0x%x\n", ++ nic->log_name, nic->flags, nic->state); ++ rc = -EAGAIN; + } +-enable_out: ++ + LOG_INFO(PFX "ISCSID_UIP_IPC_GET_IFACE: command: %x " + "name: %s, netdev: %s ipaddr: %s vlan: %d transport_name:%s", + data->header.command, rec->name, rec->netdev, +- (ipam.ip_type == AF_INET) ? inet_ntoa(ipam.addr4) : ++ (ird.ip_type == AF_INET) ? inet_ntoa(ird.ipv4_addr) : + ipv6_buf_str, +- vlan, rec->transport_name); ++ ird.vlan_id, rec->transport_name); + + done: + pthread_mutex_unlock(&nic_list_mutex); +@@ -638,12 +813,13 @@ int process_iscsid_broadcast(int s2) + data = (iscsid_uip_broadcast_t *) calloc(1, sizeof(*data)); + if (data == NULL) { + LOG_ERR(PFX "Couldn't allocate memory for iface data"); +- return -ENOMEM; ++ rc = -ENOMEM; ++ goto error; + } + memset(data, 0, sizeof(*data)); + + size = fread(data, sizeof(iscsid_uip_broadcast_header_t), 1, fd); +- if (size == -1) { ++ if (!size) { + LOG_ERR(PFX "Could not read request: %d(%s)", + errno, strerror(errno)); + rc = ferror(fd); +@@ -657,7 +833,7 @@ int process_iscsid_broadcast(int s2) + cmd, payload_len); + + size = fread(&data->u.iface_rec, payload_len, 1, fd); +- if (size == -1) { ++ if (!size) { + LOG_ERR(PFX "Could not read data: %d(%s)", + errno, strerror(errno)); + goto error; +diff --git a/iscsiuio/src/unix/libs/bnx2.c b/iscsiuio/src/unix/libs/bnx2.c +index 112d570..a8300c2 100644 +--- a/iscsiuio/src/unix/libs/bnx2.c ++++ b/iscsiuio/src/unix/libs/bnx2.c +@@ -295,7 +295,7 @@ static int bnx2_uio_verify(nic_t * nic) + + LOG_INFO(PFX "%s: Verified is a cnic_uio device", nic->log_name); + +- error: ++error: + return rc; + } + +@@ -395,7 +395,7 @@ static void bnx2_free(nic_t *nic) + /** + * bnx2_alloc() - Used to allocate a bnx2 structure + */ +-static bnx2_t *bnx2_alloc(nic_t * nic) ++static bnx2_t *bnx2_alloc(nic_t *nic) + { + bnx2_t *bp = malloc(sizeof(*bp)); + if (bp == NULL) { +@@ -468,12 +468,14 @@ static int bnx2_open(nic_t * nic) + manually_trigger_uio_event(nic, nic->uio_minor); + + /* udev might not have created the file yet */ ++ pthread_mutex_unlock(&nic->nic_mutex); + sleep(1); ++ pthread_mutex_lock(&nic->nic_mutex); + } + } + if (fstat(nic->fd, &uio_stat) < 0) { + LOG_ERR(PFX "%s: Could not fstat device", nic->log_name); +- rc = -ENODEV; ++ errno = -ENODEV; + goto error_alloc_rx_ring; + } + nic->uio_minor = minor(uio_stat.st_rdev); +@@ -483,7 +485,7 @@ static int bnx2_open(nic_t * nic) + if (bp->bar0_fd < 0) { + LOG_ERR(PFX "%s: Could not open %s", nic->log_name, + sysfs_resc_path); +- rc = -ENODEV; ++ errno = -ENODEV; + goto error_alloc_rx_ring; + } + +@@ -506,6 +508,7 @@ static int bnx2_open(nic_t * nic) + if (bp->rx_ring == NULL) { + LOG_ERR(PFX "%s: Could not allocate space for rx_ring", + nic->log_name); ++ errno = -ENOMEM; + goto error_alloc_rx_ring; + } + mlock(bp->rx_ring, sizeof(struct l2_fhdr *) * bp->rx_ring_size); +@@ -515,6 +518,7 @@ static int bnx2_open(nic_t * nic) + if (bp->rx_pkt_ring == NULL) { + LOG_ERR(PFX "%s: Could not allocate space for rx_pkt_ring", + nic->log_name); ++ errno = -ENOMEM; + goto error_alloc_rx_pkt_ring; + } + mlock(bp->rx_pkt_ring, sizeof(void *) * bp->rx_ring_size); +@@ -677,9 +681,10 @@ static int bnx2_open(nic_t * nic) + bnx2_wr32(bp, BNX2_RPM_SORT_USER2, val | BNX2_RPM_SORT_USER2_ENA); + + rc = enable_multicast(nic); +- if (rc != 0) ++ if (rc != 0) { ++ errno = rc; + goto error_bufs; +- ++ } + msync(bp->reg, 0x12800, MS_SYNC); + LOG_INFO("%s: bnx2 uio initialized", nic->log_name); + +@@ -707,6 +712,10 @@ error_alloc_rx_pkt_ring: + bp->rx_ring = NULL; + + error_alloc_rx_ring: ++ if (nic->fd != INVALID_FD) { ++ close(nic->fd); ++ nic->fd = INVALID_FD; ++ } + bnx2_free(nic); + + return errno; +@@ -878,8 +887,8 @@ void bnx2_start_xmit(nic_t * nic, size_t len, u16_t vlan_id) + rxbd = (struct rx_bd *)(((__u8 *) bp->tx_ring) + getpagesize()); + + if ((rxbd->rx_bd_haddr_hi == 0) && (rxbd->rx_bd_haddr_lo == 0)) { +- LOG_DEBUG(PFX "%s: trying to transmit when device is closed", +- nic->log_name); ++ LOG_PACKET(PFX "%s: trying to transmit when device is closed", ++ nic->log_name); + pthread_mutex_unlock(&nic->xmit_mutex); + return; + } +@@ -905,8 +914,8 @@ void bnx2_start_xmit(nic_t * nic, size_t len, u16_t vlan_id) + bnx2_reg_sync(bp, bp->tx_bidx_io, sizeof(__u16)); + bnx2_reg_sync(bp, bp->tx_bseq_io, sizeof(__u32)); + +- LOG_DEBUG(PFX "%s: sent %d bytes using dev->tx_prod: %d", +- nic->log_name, len, bp->tx_prod); ++ LOG_PACKET(PFX "%s: sent %d bytes using dev->tx_prod: %d", ++ nic->log_name, len, bp->tx_prod); + } + + /** +@@ -917,8 +926,8 @@ void bnx2_start_xmit(nic_t * nic, size_t len, u16_t vlan_id) + */ + int bnx2_write(nic_t * nic, nic_interface_t * nic_iface, packet_t * pkt) + { +- bnx2_t *bp = (bnx2_t *) nic->priv; +- struct uip_stack *uip = &nic_iface->ustack; ++ bnx2_t *bp; ++ struct uip_stack *uip; + + /* Sanity Check: validate the parameters */ + if (nic == NULL || nic_iface == NULL || pkt == NULL) { +@@ -927,6 +936,8 @@ int bnx2_write(nic_t * nic, nic_interface_t * nic_iface, packet_t * pkt) + " pkt == 0x%x", nic, nic_iface, pkt); + return -EINVAL; + } ++ bp = (bnx2_t *)nic->priv; ++ uip = &nic_iface->ustack; + + if (pkt->buf_size == 0) { + LOG_ERR(PFX "%s: Trying to transmitted 0 sized packet", +@@ -935,22 +946,24 @@ int bnx2_write(nic_t * nic, nic_interface_t * nic_iface, packet_t * pkt) + } + + if (pthread_mutex_trylock(&nic->xmit_mutex) != 0) { +- LOG_DEBUG(PFX "%s: Dropped previous transmitted packet", +- nic->log_name); ++ LOG_PACKET(PFX "%s: Dropped previous transmitted packet", ++ nic->log_name); + return -EINVAL; + } + + bnx2_prepare_xmit_packet(nic, nic_iface, pkt); +- bnx2_start_xmit(nic, pkt->buf_size, nic_iface->vlan_id); ++ bnx2_start_xmit(nic, pkt->buf_size, ++ (nic_iface->vlan_priority << 12) | ++ nic_iface->vlan_id); + + /* bump the bnx2 dev send statistics */ + nic->stats.tx.packets++; + nic->stats.tx.bytes += uip->uip_len; + +- LOG_DEBUG(PFX "%s: transmitted %d bytes " +- "dev->tx_cons: %d, dev->tx_prod: %d, dev->tx_bseq:%d", +- nic->log_name, pkt->buf_size, +- bp->tx_cons, bp->tx_prod, bp->tx_bseq); ++ LOG_PACKET(PFX "%s: transmitted %d bytes " ++ "dev->tx_cons: %d, dev->tx_prod: %d, dev->tx_bseq:%d", ++ nic->log_name, pkt->buf_size, ++ bp->tx_cons, bp->tx_prod, bp->tx_bseq); + + return 0; + } +@@ -963,7 +976,7 @@ int bnx2_write(nic_t * nic, nic_interface_t * nic_iface, packet_t * pkt) + */ + static int bnx2_read(nic_t * nic, packet_t * pkt) + { +- bnx2_t *bp = (bnx2_t *) nic->priv; ++ bnx2_t *bp; + int rc = 0; + uint16_t hw_cons, sw_cons; + +@@ -973,6 +986,7 @@ static int bnx2_read(nic_t * nic, packet_t * pkt) + " pkt == 0x%x", nic, pkt); + return -EINVAL; + } ++ bp = (bnx2_t *)nic->priv; + + hw_cons = bp->get_rx_cons(bp); + sw_cons = bp->rx_cons; +@@ -984,8 +998,8 @@ static int bnx2_read(nic_t * nic, packet_t * pkt) + int len; + uint16_t errors; + +- LOG_DEBUG(PFX "%s: clearing rx interrupt: %d %d %d", +- nic->log_name, sw_cons, hw_cons, rx_index); ++ LOG_PACKET(PFX "%s: clearing rx interrupt: %d %d %d", ++ nic->log_name, sw_cons, hw_cons, rx_index); + + msync(rx_hdr, sizeof(struct l2_fhdr), MS_SYNC); + errors = ((rx_hdr->l2_fhdr_status & 0xffff0000) >> 16); +@@ -1033,8 +1047,8 @@ static int bnx2_read(nic_t * nic, packet_t * pkt) + + rc = 1; + +- LOG_DEBUG(PFX "%s: processing packet " +- "length: %d", nic->log_name, len); ++ LOG_PACKET(PFX "%s: processing packet " ++ "length: %d", nic->log_name, len); + } else { + /* If the NIC passes up a packet bigger + * then the RX buffer, flag it */ +@@ -1073,21 +1087,23 @@ static int bnx2_read(nic_t * nic, packet_t * pkt) + */ + static int bnx2_clear_tx_intr(nic_t * nic) + { +- bnx2_t *bp = (bnx2_t *) nic->priv; +- uint16_t hw_cons = bp->get_tx_cons(bp); ++ bnx2_t *bp; ++ uint16_t hw_cons; + + /* Sanity check: ensure the parameters passed in are valid */ + if (unlikely(nic == NULL)) { + LOG_ERR(PFX "bnx2_read() nic == NULL"); + return -EINVAL; + } ++ bp = (bnx2_t *) nic->priv; ++ hw_cons = bp->get_tx_cons(bp); + + if (bp->flags & BNX2_UIO_TX_HAS_SENT) { + bp->flags &= ~BNX2_UIO_TX_HAS_SENT; + } + +- LOG_DEBUG(PFX "%s: clearing tx interrupt [%d %d]", +- nic->log_name, bp->tx_cons, hw_cons); ++ LOG_PACKET(PFX "%s: clearing tx interrupt [%d %d]", ++ nic->log_name, bp->tx_cons, hw_cons); + + bp->tx_cons = hw_cons; + +@@ -1097,7 +1113,7 @@ static int bnx2_clear_tx_intr(nic_t * nic) + if (nic->tx_packet_queue != NULL) { + packet_t *pkt; + +- LOG_DEBUG(PFX "%s: sending queued tx packet", nic->log_name); ++ LOG_PACKET(PFX "%s: sending queued tx packet", nic->log_name); + pkt = nic_dequeue_tx_packet(nic); + + /* Got a TX packet buffer of the TX queue and put it onto +@@ -1106,13 +1122,14 @@ static int bnx2_clear_tx_intr(nic_t * nic) + bnx2_prepare_xmit_packet(nic, pkt->nic_iface, pkt); + + bnx2_start_xmit(nic, pkt->buf_size, ++ (pkt->nic_iface->vlan_priority << 12) | + pkt->nic_iface->vlan_id); + +- LOG_DEBUG(PFX "%s: transmitted queued packet %d bytes " +- "dev->tx_cons: %d, dev->tx_prod: %d, " +- "dev->tx_bseq:%d", +- nic->log_name, pkt->buf_size, +- bp->tx_cons, bp->tx_prod, bp->tx_bseq); ++ LOG_PACKET(PFX "%s: transmitted queued packet %d bytes " ++ "dev->tx_cons: %d, dev->tx_prod: %d, " ++ "dev->tx_bseq:%d", ++ nic->log_name, pkt->buf_size, ++ bp->tx_cons, bp->tx_prod, bp->tx_bseq); + + return -EAGAIN; + } +diff --git a/iscsiuio/src/unix/libs/bnx2x.c b/iscsiuio/src/unix/libs/bnx2x.c +index fa32fbc..5e33420 100644 +--- a/iscsiuio/src/unix/libs/bnx2x.c ++++ b/iscsiuio/src/unix/libs/bnx2x.c +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2009-2011, Broadcom Corporation ++ * Copyright (c) 2009-2012, Broadcom Corporation + * + * Written by: Benjamin Li (benli@broadcom.com) + * +@@ -288,11 +288,12 @@ static void bnx2x_set_drv_version_unknown(bnx2x_t * bp) + bp->version.sub_minor = BNX2X_UNKNOWN_SUB_MINOR_VERSION; + } + ++/* Return: 1 = Unknown, 0 = Known */ + static int bnx2x_is_drv_version_unknown(struct bnx2x_driver_version *version) + { +- if ((version->major == BNX2X_UNKNOWN_MAJOR_VERSION) && +- (version->minor == BNX2X_UNKNOWN_MINOR_VERSION) && +- (version->sub_minor == BNX2X_UNKNOWN_SUB_MINOR_VERSION)) { ++ if ((version->major == (uint16_t)BNX2X_UNKNOWN_MAJOR_VERSION) && ++ (version->minor == (uint16_t)BNX2X_UNKNOWN_MINOR_VERSION) && ++ (version->sub_minor == (uint16_t)BNX2X_UNKNOWN_SUB_MINOR_VERSION)) { + return 1; + } + +@@ -595,7 +596,7 @@ static void bnx2x_free(nic_t *nic) + /** + * bnx2x_alloc() - Used to allocate a bnx2x structure + */ +-static bnx2x_t *bnx2x_alloc(nic_t * nic) ++static bnx2x_t *bnx2x_alloc(nic_t *nic) + { + bnx2x_t *bp = malloc(sizeof(*bp)); + +@@ -652,9 +653,13 @@ static int bnx2x_open(nic_t * nic) + if (bp == NULL) + return -ENOMEM; + +- if (!bnx2x_is_drv_version_unknown(&bnx2x_version)) +- bnx2x_get_drv_version(bp); +- else { ++ if (bnx2x_is_drv_version_unknown(&bnx2x_version)) { ++ /* If version is unknown, go read from ethtool */ ++ rc = bnx2x_get_drv_version(bp); ++ if (rc) ++ goto open_error; ++ } else { ++ /* Version is not unknown, jsut use it */ + bnx2x_version.major = bp->version.major; + bnx2x_version.minor = bp->version.minor; + bnx2x_version.sub_minor = bp->version.sub_minor; +@@ -663,7 +668,9 @@ static int bnx2x_open(nic_t * nic) + count = 0; + while ((nic->fd < 0) && count < 15) { + /* udev might not have created the file yet */ ++ pthread_mutex_unlock(&nic->nic_mutex); + sleep(1); ++ pthread_mutex_lock(&nic->nic_mutex); + + nic->fd = open(nic->uio_device_name, O_RDWR | O_NONBLOCK); + if (nic->fd != INVALID_FD) { +@@ -684,7 +691,9 @@ static int bnx2x_open(nic_t * nic) + manually_trigger_uio_event(nic, nic->uio_minor); + + /* udev might not have created the file yet */ ++ pthread_mutex_unlock(&nic->nic_mutex); + sleep(1); ++ pthread_mutex_lock(&nic->nic_mutex); + + count++; + } +@@ -820,7 +829,15 @@ static int bnx2x_open(nic_t * nic) + nic->log_name); + goto open_error; + } +- ++ /* In E1/E1H use pci device function as read from sysfs. ++ * In E2/E3 read physical function from ME register since these chips ++ * support Physical Device Assignment where kernel BDF maybe arbitrary ++ * (depending on hypervisor). ++ */ ++ if (CHIP_IS_E2_PLUS(bp)) { ++ func = (bnx2x_rd32(bp, BAR_ME_REGISTER) & ME_REG_ABS_PF_NUM) >> ++ ME_REG_ABS_PF_NUM_SHIFT; ++ } + bp->func = func; + bp->port = bp->func % PORT_MAX; + +@@ -976,9 +993,12 @@ static int bnx2x_open(nic_t * nic) + val = bnx2x_rd32(bp, mf_cfg_addr + ovtag_offset); + val &= 0xffff; + /* SD mode, check for valid outer VLAN */ +- if (val == 0xffff) +- goto open_error; +- ++ if (val == 0xffff) { ++ LOG_ERR(PFX "%s: Invalid OV detected for SD, " ++ " fallback to SF mode!\n", ++ nic->log_name); ++ goto SF; ++ } + /* Check for iSCSI protocol */ + val = bnx2x_rd32(bp, mf_cfg_addr + proto_offset); + if ((val & 6) != 6) +@@ -995,10 +1015,9 @@ static int bnx2x_open(nic_t * nic) + mac[4] = (__u8) (val >> 8); + mac[5] = (__u8) val; + memcpy(nic->mac_addr, mac, 6); +- + } + } +- ++SF: + LOG_INFO(PFX "%s: Using mac address: %02x:%02x:%02x:%02x:%02x:%02x", + nic->log_name, + nic->mac_addr[0], nic->mac_addr[1], nic->mac_addr[2], +@@ -1053,6 +1072,10 @@ open_error: + close(bp->bar0_fd); + bp->bar0_fd = INVALID_FD; + } ++ if (nic->fd != INVALID_FD) { ++ close(nic->fd); ++ nic->fd = INVALID_FD; ++ } + bnx2x_free(nic); + + return rc; +@@ -1165,9 +1188,12 @@ static int bnx2x_uio_close_resources(nic_t * nic, NIC_SHUTDOWN_T graceful) + static int bnx2x_close(nic_t * nic, NIC_SHUTDOWN_T graceful) + { + /* Sanity Check: validate the parameters */ +- if (nic == NULL || nic->priv == NULL) { +- LOG_ERR(PFX "bnx2x_close(): nic == %p, bp == %p", nic, +- nic->priv); ++ if (nic == NULL) { ++ LOG_ERR(PFX "bnx2x_close(): nic == NULL"); ++ return -EINVAL; ++ } ++ if (nic->priv == NULL) { ++ LOG_ERR(PFX "bnx2x_close(): nic->priv == NULL"); + return -EINVAL; + } + +@@ -1227,8 +1253,8 @@ void bnx2x_start_xmit(nic_t * nic, size_t len, u16_t vlan_id) + rx_bd = (struct eth_rx_bd *)(((__u8 *) bp->tx_ring) + getpagesize()); + + if ((rx_bd->addr_hi == 0) && (rx_bd->addr_lo == 0)) { +- LOG_DEBUG(PFX "%s: trying to transmit when device is closed", +- nic->log_name); ++ LOG_PACKET(PFX "%s: trying to transmit when device is closed", ++ nic->log_name); + pthread_mutex_unlock(&nic->xmit_mutex); + return; + } +@@ -1251,7 +1277,7 @@ void bnx2x_start_xmit(nic_t * nic, size_t len, u16_t vlan_id) + bp->tx_bd_prod = BNX2X_NEXT_TX_BD(bp->tx_bd_prod); + + barrier(); +- if (nl_process_if_down == 0) { ++ if (nic->nl_process_if_down == 0) { + bnx2x_doorbell(bp, bp->tx_doorbell, 0x02 | + (bp->tx_bd_prod << 16)); + bnx2x_flush_doorbell(bp, bp->tx_doorbell); +@@ -1262,8 +1288,8 @@ void bnx2x_start_xmit(nic_t * nic, size_t len, u16_t vlan_id) + */ + pthread_mutex_unlock(&nic->xmit_mutex); + } +- LOG_DEBUG(PFX "%s: sent %d bytes using bp->tx_prod: %d", +- nic->log_name, len, bp->tx_prod); ++ LOG_PACKET(PFX "%s: sent %d bytes using bp->tx_prod: %d", ++ nic->log_name, len, bp->tx_prod); + } + + /** +@@ -1274,8 +1300,8 @@ void bnx2x_start_xmit(nic_t * nic, size_t len, u16_t vlan_id) + */ + int bnx2x_write(nic_t * nic, nic_interface_t * nic_iface, packet_t * pkt) + { +- bnx2x_t *bp = (bnx2x_t *) nic->priv; +- struct uip_stack *uip = &nic_iface->ustack; ++ bnx2x_t *bp; ++ struct uip_stack *uip; + int i = 0; + + /* Sanity Check: validate the parameters */ +@@ -1285,6 +1311,8 @@ int bnx2x_write(nic_t * nic, nic_interface_t * nic_iface, packet_t * pkt) + " pkt == 0x%x", nic, nic_iface, pkt); + return -EINVAL; + } ++ bp = (bnx2x_t *) nic->priv; ++ uip = &nic_iface->ustack; + + if (pkt->buf_size == 0) { + LOG_ERR(PFX "%s: Trying to transmitted 0 sized packet", +@@ -1304,22 +1332,24 @@ int bnx2x_write(nic_t * nic, nic_interface_t * nic_iface, packet_t * pkt) + } + + if (pthread_mutex_trylock(&nic->xmit_mutex) != 0) { +- LOG_DEBUG(PFX "%s: Dropped previous transmitted packet", +- nic->log_name); ++ LOG_PACKET(PFX "%s: Dropped previous transmitted packet", ++ nic->log_name); + return -EINVAL; + } + + bnx2x_prepare_xmit_packet(nic, nic_iface, pkt); +- bnx2x_start_xmit(nic, pkt->buf_size, nic_iface->vlan_id); ++ bnx2x_start_xmit(nic, pkt->buf_size, ++ (nic_iface->vlan_priority << 12) | ++ nic_iface->vlan_id); + + /* bump the cnic dev send statistics */ + nic->stats.tx.packets++; + nic->stats.tx.bytes += uip->uip_len; + +- LOG_DEBUG(PFX "%s: transmitted %d bytes " +- "dev->tx_cons: %d, dev->tx_prod: %d, dev->tx_bd_prod:%d", +- nic->log_name, pkt->buf_size, +- bp->tx_cons, bp->tx_prod, bp->tx_bd_prod); ++ LOG_PACKET(PFX "%s: transmitted %d bytes " ++ "dev->tx_cons: %d, dev->tx_prod: %d, dev->tx_bd_prod:%d", ++ nic->log_name, pkt->buf_size, ++ bp->tx_cons, bp->tx_prod, bp->tx_bd_prod); + + return 0; + } +@@ -1348,7 +1378,7 @@ static inline int bnx2x_get_rx_pad(bnx2x_t * bp, union eth_rx_cqe *cqe) + */ + static int bnx2x_read(nic_t * nic, packet_t * pkt) + { +- bnx2x_t *bp = (bnx2x_t *) nic->priv; ++ bnx2x_t *bp; + int rc = 0; + uint16_t hw_cons, sw_cons, bd_cons, bd_prod; + +@@ -1358,6 +1388,7 @@ static int bnx2x_read(nic_t * nic, packet_t * pkt) + " pkt == 0x%x", nic, pkt); + return -EINVAL; + } ++ bp = (bnx2x_t *) nic->priv; + + hw_cons = bp->get_rx_cons(bp); + sw_cons = bp->rx_cons; +@@ -1383,8 +1414,8 @@ static int bnx2x_read(nic_t * nic, packet_t * pkt) + } + cqe_fp_flags = cqe->fast_path_cqe.type_error_flags; + +- LOG_DEBUG(PFX "%s: clearing rx interrupt: %d %d", +- nic->log_name, sw_cons, hw_cons); ++ LOG_PACKET(PFX "%s: clearing rx interrupt: %d %d", ++ nic->log_name, sw_cons, hw_cons); + + msync(cqe, cqe_size, MS_SYNC); + +@@ -1416,9 +1447,9 @@ static int bnx2x_read(nic_t * nic, packet_t * pkt) + pkt->vlan_tag = 0; + } + +- LOG_DEBUG(PFX +- "%s: processing packet length: %d", +- nic->log_name, len); ++ LOG_PACKET(PFX ++ "%s: processing packet length: %d", ++ nic->log_name, len); + + /* bump the cnic dev recv statistics */ + nic->stats.rx.packets++; +@@ -1453,14 +1484,16 @@ static int bnx2x_read(nic_t * nic, packet_t * pkt) + */ + static int bnx2x_clear_tx_intr(nic_t * nic) + { +- bnx2x_t *bp = (bnx2x_t *) nic->priv; +- uint16_t hw_cons = bp->get_tx_cons(bp); ++ bnx2x_t *bp; ++ uint16_t hw_cons; + + /* Sanity check: ensure the parameters passed in are valid */ + if (unlikely(nic == NULL)) { + LOG_ERR(PFX "bnx2x_read() nic == NULL"); + return -EINVAL; + } ++ bp = (bnx2x_t *) nic->priv; ++ hw_cons = bp->get_tx_cons(bp); + + if (bp->tx_cons == hw_cons) { + if (bp->tx_cons == bp->tx_prod) { +@@ -1473,8 +1506,8 @@ static int bnx2x_clear_tx_intr(nic_t * nic) + return -EAGAIN; + } + +- LOG_DEBUG(PFX "%s: clearing tx interrupt [%d %d]", +- nic->log_name, bp->tx_cons, hw_cons); ++ LOG_PACKET(PFX "%s: clearing tx interrupt [%d %d]", ++ nic->log_name, bp->tx_cons, hw_cons); + bp->tx_cons = hw_cons; + + /* There is a queued TX packet that needs to be sent out. The usual +@@ -1484,7 +1517,7 @@ static int bnx2x_clear_tx_intr(nic_t * nic) + packet_t *pkt; + int i; + +- LOG_DEBUG(PFX "%s: sending queued tx packet", nic->log_name); ++ LOG_PACKET(PFX "%s: sending queued tx packet", nic->log_name); + pkt = nic_dequeue_tx_packet(nic); + + /* Got a TX packet buffer of the TX queue and put it onto +@@ -1493,13 +1526,14 @@ static int bnx2x_clear_tx_intr(nic_t * nic) + bnx2x_prepare_xmit_packet(nic, pkt->nic_iface, pkt); + + bnx2x_start_xmit(nic, pkt->buf_size, ++ (pkt->nic_iface->vlan_priority << 12) | + pkt->nic_iface->vlan_id); + +- LOG_DEBUG(PFX "%s: transmitted queued packet %d bytes " +- "dev->tx_cons: %d, dev->tx_prod: %d, " +- "dev->tx_bd_prod:%d", +- nic->log_name, pkt->buf_size, +- bp->tx_cons, bp->tx_prod, bp->tx_bd_prod); ++ LOG_PACKET(PFX "%s: transmitted queued packet %d bytes " ++ "dev->tx_cons: %d, dev->tx_prod: %d, " ++ "dev->tx_bd_prod:%d", ++ nic->log_name, pkt->buf_size, ++ bp->tx_cons, bp->tx_prod, bp->tx_bd_prod); + + return 0; + } +@@ -1512,9 +1546,9 @@ static int bnx2x_clear_tx_intr(nic_t * nic) + + hw_cons = bp->get_tx_cons(bp); + if (bp->tx_cons != hw_cons) { +- LOG_DEBUG(PFX +- "%s: clearing tx interrupt [%d %d]", +- nic->log_name, bp->tx_cons, hw_cons); ++ LOG_PACKET(PFX ++ "%s: clearing tx interrupt [%d %d]", ++ nic->log_name, bp->tx_cons, hw_cons); + bp->tx_cons = hw_cons; + + break; +diff --git a/iscsiuio/src/unix/libs/bnx2x.h b/iscsiuio/src/unix/libs/bnx2x.h +index 8e923b9..b758179 100644 +--- a/iscsiuio/src/unix/libs/bnx2x.h ++++ b/iscsiuio/src/unix/libs/bnx2x.h +@@ -467,6 +467,18 @@ struct client_init_general_data { + #define BAR_XSTRORM_INTMEM 0x420000 + #define BAR_TSTRORM_INTMEM 0x430000 + ++#define BAR_ME_REGISTER 0x450000 ++#define ME_REG_PF_NUM_SHIFT 0 ++#define ME_REG_PF_NUM\ ++ (7L<arp_tpa, &dst_ip, 4); + + (*nic->nic_library->ops->start_xmit) (nic, pkt_size, ++ (nic_iface->vlan_priority << 12) | + nic_iface->vlan_id); + + memcpy(&addr.s_addr, &dst_ip, sizeof(addr.s_addr)); +@@ -166,15 +167,6 @@ static int cnic_neigh_soliciation_send(nic_t * nic, + memcpy(ipv6_hdr->ip6_dst.s6_addr, addr6_dst->s6_addr, + sizeof(struct in6_addr)); + +- LOG_DEBUG(PFX "dst ip addr %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", +- ipv6_hdr->ip6_dst.s6_addr16[0], +- ipv6_hdr->ip6_dst.s6_addr16[1], +- ipv6_hdr->ip6_dst.s6_addr16[2], +- ipv6_hdr->ip6_dst.s6_addr16[3], +- ipv6_hdr->ip6_dst.s6_addr16[4], +- ipv6_hdr->ip6_dst.s6_addr16[5], +- ipv6_hdr->ip6_dst.s6_addr16[6], +- ipv6_hdr->ip6_dst.s6_addr16[7]); + nic_fill_ethernet_header(nic_iface, eth, nic->mac_addr, nic->mac_addr, + &pkt_size, (void *)&ipv6_hdr, ETHERTYPE_IPV6); + req_ptr.eth = (void *)eth; +@@ -196,6 +188,7 @@ static int cnic_neigh_soliciation_send(nic_t * nic, + eth->ether_shost[2], eth->ether_shost[3], + eth->ether_shost[4], eth->ether_shost[5]); + (*nic->nic_library->ops->start_xmit) (nic, pkt_size, ++ (nic_iface->vlan_priority << 12) | + nic_iface->vlan_id); + + LOG_DEBUG(PFX "%s: Sent cnic ICMPv6 neighbor request %s", +@@ -261,12 +254,7 @@ static int cnic_nl_neigh_rsp(nic_t * nic, int fd, + } + if (ret) { + /* Get link local IPv6 address */ +- if (ndpc_request(&nic_iface->ustack, NULL, +- &src_ipv6, GET_LINK_LOCAL_ADDR)) { +- src_ipv6 = (u8_t *)all_zeroes_addr6; +- LOG_DEBUG(PFX "RSP Get LL failed"); +- goto src_done; +- } ++ src_ipv6 = (u8_t *)&nic_iface->ustack.linklocal6; + } else { + if (ndpc_request(&nic_iface->ustack, + &path_req->dst.v6_addr, +@@ -288,16 +276,18 @@ src_done: + addr_dst_str, sizeof(addr_dst_str)); + } + memcpy(path_rsp->mac_addr, mac_addr, 6); +- path_rsp->vlan_id = path_req->vlan_id; +- path_rsp->pmtu = path_req->pmtu; ++ path_rsp->vlan_id = (nic_iface->vlan_priority << 12) | ++ nic_iface->vlan_id; ++ path_rsp->pmtu = nic_iface->mtu ? nic_iface->mtu : path_req->pmtu; + + rc = __kipc_call(fd, ret_ev, sizeof(*ret_ev) + sizeof(*path_rsp)); + if (rc > 0) { + LOG_DEBUG(PFX "neighbor reply sent back to kernel " +- "%s at %02x:%02x:%02x:%02x:%02x:%02x", ++ "%s at %02x:%02x:%02x:%02x:%02x:%02x with vlan %d", + addr_dst_str, + mac_addr[0], mac_addr[1], +- mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); ++ mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5], ++ nic_iface->vlan_id); + + } else { + LOG_ERR(PFX "send neighbor reply failed: %d", rc); +@@ -323,67 +313,18 @@ const static struct timeval tp_wait = { + */ + int cnic_handle_ipv4_iscsi_path_req(nic_t * nic, int fd, + struct iscsi_uevent *ev, +- struct iscsi_path *path) ++ struct iscsi_path *path, ++ nic_interface_t *nic_iface) + { +- nic_interface_t *nic_iface, *vlan_iface; + struct in_addr src_addr, dst_addr, + src_matching_addr, dst_matching_addr, netmask; + __u8 mac_addr[6]; + int rc; + uint16_t arp_retry; + int status = 0; +- +- memset(mac_addr, 0, sizeof(mac_addr)); +- +- pthread_mutex_lock(&nic_list_mutex); +- +- /* Find the proper interface via VLAN id */ +- nic_iface = nic_find_nic_iface_protocol(nic, 0, AF_INET); +- if (nic_iface == NULL) { +- pthread_mutex_unlock(&nic_list_mutex); +- LOG_ERR(PFX "%s: Couldn't find net_iface vlan_id: %d", +- nic->log_name, path->vlan_id); +- return -EINVAL; +- } +- if (path->vlan_id) { +- vlan_iface = nic_find_vlan_iface_protocol(nic, nic_iface, +- path->vlan_id, +- AF_INET); +- if (vlan_iface == NULL) { +- LOG_INFO(PFX "%s couldn't find interface with VLAN = %d" +- "ip_type: 0x%x creating it", +- nic->log_name, path->vlan_id, AF_INET); +- +- /* Create the nic interface */ +- vlan_iface = nic_iface_init(); +- +- if (vlan_iface == NULL) { +- LOG_ERR(PFX "Couldn't allocate nic_iface for " +- "VLAN: %d", vlan_iface, +- path->vlan_id); +- return -EINVAL; +- } +- +- vlan_iface->protocol = nic_iface->protocol; +- vlan_iface->vlan_id = path->vlan_id; +- vlan_iface->ustack.ip_config = +- nic_iface->ustack.ip_config; +- memcpy(vlan_iface->ustack.hostaddr, +- nic_iface->ustack.hostaddr, +- sizeof(nic_iface->ustack.hostaddr)); +- memcpy(vlan_iface->ustack.netmask, +- nic_iface->ustack.netmask, +- sizeof(nic_iface->ustack.netmask)); +- nic_add_vlan_iface(nic, nic_iface, vlan_iface); +- } else { +- LOG_INFO(PFX "%s: using existing vlan interface", +- nic->log_name); +- } +- nic_iface = vlan_iface; +- } +- + #define MAX_ARP_RETRY 4 + ++ memset(mac_addr, 0, sizeof(mac_addr)); + memcpy(&dst_addr, &path->dst.v4_addr, sizeof(dst_addr)); + memcpy(&src_addr, nic_iface->ustack.hostaddr, sizeof(src_addr)); + +@@ -445,20 +386,15 @@ int cnic_handle_ipv4_iscsi_path_req(nic_t * nic, int fd, + ts.tv_sec = tp_abs.tv_sec; + ts.tv_nsec = tp_abs.tv_usec * 1000; + +- pthread_mutex_unlock(&nic_list_mutex); ++ /* Wait 1s for if_down */ ++ pthread_mutex_lock(&nic->nl_process_mutex); + rc = pthread_cond_timedwait +- (&nl_process_if_down_cond, +- &nl_process_mutex, &ts); ++ (&nic->nl_process_if_down_cond, ++ &nic->nl_process_mutex, &ts); + + if (rc == ETIMEDOUT) { +- pthread_mutex_unlock(&nl_process_mutex); +- +- if (pthread_mutex_trylock +- (&nic_list_mutex) != 0) { +- arp_retry = MAX_ARP_RETRY; +- goto done; +- +- } ++ pthread_mutex_unlock ++ (&nic->nl_process_mutex); + + rc = uip_lookup_arp_entry(dst_addr. + s_addr, +@@ -466,8 +402,9 @@ int cnic_handle_ipv4_iscsi_path_req(nic_t * nic, int fd, + if (rc == 0) + goto done; + } else { +- nl_process_if_down = 0; +- pthread_mutex_unlock(&nl_process_mutex); ++ nic->nl_process_if_down = 0; ++ pthread_mutex_unlock ++ (&nic->nl_process_mutex); + + arp_retry = MAX_ARP_RETRY; + goto done; +@@ -491,9 +428,6 @@ done: + + cnic_nl_neigh_rsp(nic, fd, ev, path, mac_addr, + nic_iface, status, AF_INET); +- +- pthread_mutex_unlock(&nic_list_mutex); +- + return rc; + } + +@@ -507,9 +441,9 @@ done: + */ + int cnic_handle_ipv6_iscsi_path_req(nic_t * nic, int fd, + struct iscsi_uevent *ev, +- struct iscsi_path *path) ++ struct iscsi_path *path, ++ nic_interface_t *nic_iface) + { +- nic_interface_t *nic_iface, *vlan_iface; + __u8 mac_addr[6]; + int rc, i; + uint16_t neighbor_retry; +@@ -525,52 +459,6 @@ int cnic_handle_ipv6_iscsi_path_req(nic_t * nic, int fd, + inet_ntop(AF_INET6, &path->dst.v6_addr, + addr_dst_str, sizeof(addr_dst_str)); + +- pthread_mutex_lock(&nic_list_mutex); +- +- /* Find the proper interface via VLAN id */ +- nic_iface = nic_find_nic_iface_protocol(nic, 0, AF_INET6); +- if (nic_iface == NULL) { +- pthread_mutex_unlock(&nic_list_mutex); +- LOG_ERR(PFX "%s: Couldn't find net_iface vlan_id: %d", +- nic->log_name, path->vlan_id); +- return -EINVAL; +- } +- if (path->vlan_id) { +- vlan_iface = nic_find_vlan_iface_protocol(nic, nic_iface, +- path->vlan_id, +- AF_INET6); +- if (vlan_iface == NULL) { +- LOG_INFO(PFX "%s couldn't find interface with VLAN = %d" +- "ip_type: 0x%x creating it", +- nic->log_name, path->vlan_id, AF_INET6); +- +- /* Create the nic interface */ +- vlan_iface = nic_iface_init(); +- +- if (vlan_iface == NULL) { +- LOG_ERR(PFX "Couldn't allocate nic_iface for " +- "VLAN: %d", vlan_iface, +- path->vlan_id); +- return -EINVAL; +- } +- vlan_iface->protocol = nic_iface->protocol; +- vlan_iface->vlan_id = path->vlan_id; +- vlan_iface->ustack.ip_config = +- nic_iface->ustack.ip_config; +- memcpy(vlan_iface->ustack.hostaddr6, +- nic_iface->ustack.hostaddr6, +- sizeof(nic_iface->ustack.hostaddr6)); +- memcpy(vlan_iface->ustack.netmask6, +- nic_iface->ustack.netmask6, +- sizeof(nic_iface->ustack.netmask6)); +- nic_add_vlan_iface(nic, nic_iface, vlan_iface); +- } else { +- LOG_INFO(PFX "%s: using existing vlan interface", +- nic->log_name); +- } +- nic_iface = vlan_iface; +- } +- + /* Depending on the IPv6 address of the target we will need to + * determine whether we use the assigned IPv6 address or the + * link local IPv6 address */ +@@ -584,12 +472,7 @@ int cnic_handle_ipv6_iscsi_path_req(nic_t * nic, int fd, + if (rc) { + LOG_DEBUG(PFX "Use LL"); + /* Get link local IPv6 address */ +- if (ndpc_request(&nic_iface->ustack, NULL, +- &addr, GET_LINK_LOCAL_ADDR)) { +- neighbor_retry = MAX_ARP_RETRY; +- LOG_DEBUG(PFX "Use LL failed"); +- goto done; +- } ++ addr = (struct in6_addr *)&nic_iface->ustack.linklocal6; + } else { + LOG_DEBUG(PFX "Use Best matched"); + if (ndpc_request(&nic_iface->ustack, +@@ -618,21 +501,15 @@ int cnic_handle_ipv6_iscsi_path_req(nic_t * nic, int fd, + memcpy(&netmask.s6_addr, all_zeroes_addr6, + sizeof(struct in6_addr)); + +- LOG_DEBUG(PFX "src addr %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", +- src_addr.s6_addr16[0], src_addr.s6_addr16[1], +- src_addr.s6_addr16[2], src_addr.s6_addr16[3], +- src_addr.s6_addr16[4], src_addr.s6_addr16[5], +- src_addr.s6_addr16[6], src_addr.s6_addr16[7]); +- LOG_DEBUG(PFX "dst addr %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", +- dst_addr.s6_addr16[0], dst_addr.s6_addr16[1], +- dst_addr.s6_addr16[2], dst_addr.s6_addr16[3], +- dst_addr.s6_addr16[4], dst_addr.s6_addr16[5], +- dst_addr.s6_addr16[6], dst_addr.s6_addr16[7]); +- LOG_DEBUG(PFX "nm addr %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", +- netmask.s6_addr16[0], netmask.s6_addr16[1], +- netmask.s6_addr16[2], netmask.s6_addr16[3], +- netmask.s6_addr16[4], netmask.s6_addr16[5], +- netmask.s6_addr16[6], netmask.s6_addr16[7]); ++ inet_ntop(AF_INET6, &src_addr.s6_addr16, addr_dst_str, ++ sizeof(addr_dst_str)); ++ LOG_DEBUG(PFX "src IP addr %s", addr_dst_str); ++ inet_ntop(AF_INET6, &dst_addr.s6_addr16, addr_dst_str, ++ sizeof(addr_dst_str)); ++ LOG_DEBUG(PFX "dst IP addr %s", addr_dst_str); ++ inet_ntop(AF_INET6, &netmask.s6_addr16, addr_dst_str, ++ sizeof(addr_dst_str)); ++ LOG_DEBUG(PFX "prefix mask %s", addr_dst_str); + + for (i = 0; i < 4; i++) { + src_matching_addr.s6_addr32[i] = src_addr.s6_addr32[i] & +@@ -642,24 +519,22 @@ int cnic_handle_ipv6_iscsi_path_req(nic_t * nic, int fd, + if (src_matching_addr.s6_addr32[i] != + dst_matching_addr.s6_addr32[i]) { + /* No match with the prefix mask, use default route */ +- if (ndpc_request(&nic_iface->ustack, NULL, &addr, +- GET_DEFAULT_ROUTER_ADDR)) { +- neighbor_retry = MAX_ARP_RETRY; +- goto done; +- } +- if (memcmp(addr, all_zeroes_addr6, sizeof(*addr))) +- memcpy(&dst_addr, addr, sizeof(dst_addr)); +- else { ++ if (memcmp(nic_iface->ustack.default_route_addr6, ++ all_zeroes_addr6, sizeof(*addr))) { ++ memcpy(&dst_addr, ++ nic_iface->ustack.default_route_addr6, ++ sizeof(dst_addr)); ++ inet_ntop(AF_INET6, &dst_addr.s6_addr16, ++ addr_dst_str, sizeof(addr_dst_str)); ++ LOG_DEBUG(PFX "Use default router IP addr %s", ++ addr_dst_str); ++ break; ++ } else { + neighbor_retry = MAX_ARP_RETRY; + goto done; + } + } + } +- LOG_DEBUG(PFX "dst addr %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", +- dst_addr.s6_addr16[0], dst_addr.s6_addr16[1], +- dst_addr.s6_addr16[2], dst_addr.s6_addr16[3], +- dst_addr.s6_addr16[4], dst_addr.s6_addr16[5], +- dst_addr.s6_addr16[6], dst_addr.s6_addr16[7]); + + #define MAX_ARP_RETRY 4 + neighbor_retry = 0; +@@ -672,6 +547,8 @@ int cnic_handle_ipv6_iscsi_path_req(nic_t * nic, int fd, + goto done; + } + if (!rc) { ++ inet_ntop(AF_INET6, &dst_addr.s6_addr16, ++ addr_dst_str, sizeof(addr_dst_str)); + LOG_DEBUG(PFX + "%s: Preparing to send IPv6 neighbor solicitation " + "to dst: '%s'", nic->log_name, addr_dst_str); +@@ -703,20 +580,14 @@ int cnic_handle_ipv6_iscsi_path_req(nic_t * nic, int fd, + ts.tv_sec = tp_abs.tv_sec; + ts.tv_nsec = tp_abs.tv_usec * 1000; + +- pthread_mutex_unlock(&nic_list_mutex); ++ pthread_mutex_lock(&nic->nl_process_mutex); + rc = pthread_cond_timedwait +- (&nl_process_if_down_cond, +- &nl_process_mutex, &ts); ++ (&nic->nl_process_if_down_cond, ++ &nic->nl_process_mutex, &ts); + + if (rc == ETIMEDOUT) { +- pthread_mutex_unlock(&nl_process_mutex); +- +- if (pthread_mutex_trylock +- (&nic_list_mutex) != 0) { +- neighbor_retry = MAX_ARP_RETRY; +- goto done; +- +- } ++ pthread_mutex_unlock ++ (&nic->nl_process_mutex); + + req_ptr.eth = (void *)mac_addr; + req_ptr.ipv6 = (void *)&dst_addr; +@@ -730,8 +601,9 @@ int cnic_handle_ipv6_iscsi_path_req(nic_t * nic, int fd, + if (rc) + goto done; + } else { +- nl_process_if_down = 0; +- pthread_mutex_unlock(&nl_process_mutex); ++ nic->nl_process_if_down = 0; ++ pthread_mutex_unlock ++ (&nic->nl_process_mutex); + + neighbor_retry = MAX_ARP_RETRY; + goto done; +@@ -752,9 +624,6 @@ done: + + cnic_nl_neigh_rsp(nic, fd, ev, path, mac_addr, + nic_iface, status, AF_INET6); +- +- pthread_mutex_unlock(&nic_list_mutex); +- + return rc; + } + +@@ -764,11 +633,12 @@ done: + * @param nic - The nic the message is directed towards + * @param fd - The file descriptor to be used to extract the private data + * @param ev - The iscsi_uevent +- * @param buf - The private message buffer +- * @param buf_len - The private message buffer length ++ * @param path - The private message buffer ++ * @param nic_iface - The nic_iface to use for this connection request + */ + int cnic_handle_iscsi_path_req(nic_t * nic, int fd, struct iscsi_uevent *ev, +- struct iscsi_path *path) ++ struct iscsi_path *path, ++ nic_interface_t *nic_iface) + { + + LOG_DEBUG(PFX "%s: Netlink message with VLAN ID: %d, path MTU: %d " +@@ -777,9 +647,11 @@ int cnic_handle_iscsi_path_req(nic_t * nic, int fd, struct iscsi_uevent *ev, + path->ip_addr_len); + + if (path->ip_addr_len == 4) +- return cnic_handle_ipv4_iscsi_path_req(nic, fd, ev, path); ++ return cnic_handle_ipv4_iscsi_path_req(nic, fd, ev, path, ++ nic_iface); + else if (path->ip_addr_len == 16) +- return cnic_handle_ipv6_iscsi_path_req(nic, fd, ev, path); ++ return cnic_handle_ipv6_iscsi_path_req(nic, fd, ev, path, ++ nic_iface); + else { + LOG_DEBUG(PFX "%s: unknown ip_addr_len: %d size dropping ", + nic->log_name, path->ip_addr_len); +diff --git a/iscsiuio/src/unix/libs/cnic.h b/iscsiuio/src/unix/libs/cnic.h +index 738deb8..679dab8 100644 +--- a/iscsiuio/src/unix/libs/cnic.h ++++ b/iscsiuio/src/unix/libs/cnic.h +@@ -48,6 +48,7 @@ int cnic_nl_open(); + void cnic_nl_close(); + + int cnic_handle_iscsi_path_req(nic_t * nic, int, struct iscsi_uevent *, +- struct iscsi_path *path); ++ struct iscsi_path *path, ++ nic_interface_t *nic_iface); + + #endif /* __CNIC_NL_H__ */ +diff --git a/iscsiuio/src/unix/main.c b/iscsiuio/src/unix/main.c +index 4f548e9..2008913 100644 +--- a/iscsiuio/src/unix/main.c ++++ b/iscsiuio/src/unix/main.c +@@ -141,7 +141,6 @@ signal_wait: + break; + case SIGUSR1: + LOG_INFO("Caught SIGUSR1 signal, rotate log"); +-retry: + fini_logger(SHUTDOWN_LOGGER); + rc = init_logger(main_log.log_file); + if (rc != 0) +diff --git a/iscsiuio/src/unix/nic.c b/iscsiuio/src/unix/nic.c +index 0934b56..0b3c538 100644 +--- a/iscsiuio/src/unix/nic.c ++++ b/iscsiuio/src/unix/nic.c +@@ -64,6 +64,7 @@ + + #include "bnx2.h" + #include "bnx2x.h" ++#include "ipv6.h" + + /****************************************************************************** + * Constants +@@ -118,7 +119,7 @@ static void free_nic_library_handle(nic_lib_handle_t * handle) + * @param handle - This is the library handle to load + * @return 0 = Success; <0 = failure + */ +-static int load_nic_library(nic_lib_handle_t * handle) ++static int load_nic_library(nic_lib_handle_t *handle) + { + int rc; + char *library_name; +@@ -172,7 +173,7 @@ static int load_nic_library(nic_lib_handle_t * handle) + + return 0; + +- error: ++error: + pthread_mutex_unlock(&handle->mutex); + + return rc; +@@ -197,9 +198,10 @@ int load_all_nic_libraries() + handle->ops = (*nic_get_ops[i]) (); + + rc = load_nic_library(handle); +- if (rc != 0) ++ if (rc != 0) { ++ free_nic_library_handle(handle); + return rc; +- ++ } + /* Add the CNIC library to the list of library handles */ + pthread_mutex_lock(&nic_lib_list_mutex); + +@@ -270,7 +272,7 @@ NIC_LIBRARY_EXIST_T does_nic_uio_name_exist(char *name) + + rc = NIC_LIBRARY_DOESNT_EXIST; + +- done: ++done: + pthread_mutex_unlock(&nic_lib_list_mutex); + return rc; + } +@@ -300,7 +302,7 @@ NIC_LIBRARY_EXIST_T does_nic_library_exist(char *name) + + rc = NIC_LIBRARY_DOESNT_EXIST; + +- done: ++done: + pthread_mutex_unlock(&nic_lib_list_mutex); + return rc; + } +@@ -366,7 +368,7 @@ int find_nic_lib_using_pci_id(uint32_t vendor, uint32_t device, + } + rc = -EINVAL; + +- done: ++done: + pthread_mutex_unlock(&nic_lib_list_mutex); + + return rc; +@@ -393,13 +395,14 @@ nic_t *nic_init() + nic->next = NULL; + nic->thread = INVALID_THREAD; + nic->enable_thread = INVALID_THREAD; +- nic->flags |= NIC_UNITIALIZED | NIC_DISABLED; +- nic->state |= NIC_STOPPED; ++ nic->flags |= NIC_DISABLED; ++ nic->state = NIC_STOPPED; + nic->free_packet_queue = NULL; + nic->tx_packet_queue = NULL; + nic->nic_library = NULL; + nic->pci_id = NULL; + ++ /* nic_mutex is used to protect nic_ops */ + pthread_mutex_init(&nic->nic_mutex, NULL); + pthread_mutex_init(&nic->xmit_mutex, NULL); + pthread_mutex_init(&nic->free_packet_queue_mutex, NULL); +@@ -411,6 +414,15 @@ nic_t *nic_init() + + nic->rx_poll_usec = DEFAULT_RX_POLL_USEC; + ++ pthread_mutex_init(&nic->nl_process_mutex, NULL); ++ pthread_cond_init(&nic->nl_process_if_down_cond, NULL); ++ pthread_cond_init(&nic->nl_process_cond, NULL); ++ nic->nl_process_thread = INVALID_THREAD; ++ nic->nl_process_if_down = 0; ++ nic->nl_process_head = 0; ++ nic->nl_process_tail = 0; ++ memset(&nic->nl_process_ring, 0, sizeof(nic->nl_process_ring)); ++ + return nic; + } + +@@ -432,7 +444,6 @@ void nic_add(nic_t * nic) + + /** + * nic_remove() - Used to remove the NIC for the nic list +- nic_list_mutex must be taken + * @param nic - the nic to remove + */ + int nic_remove(nic_t * nic) +@@ -451,41 +462,66 @@ int nic_remove(nic_t * nic) + nic->ops->close(nic, 0); + + nic->state = NIC_EXIT; +- pthread_mutex_unlock(&nic->nic_mutex); + + if (nic->enable_thread != INVALID_THREAD) { +- LOG_ERR(PFX "%s: Canceling nic enable thread", nic->log_name); ++ LOG_DEBUG(PFX "%s: Canceling nic enable thread", nic->log_name); + + rc = pthread_cancel(nic->enable_thread); + if (rc != 0) +- LOG_ERR(PFX "%s: Couldn't send cancel to nic enable " +- "thread", nic->log_name); ++ LOG_DEBUG(PFX "%s: Couldn't send cancel to nic enable " ++ "thread", nic->log_name); + +- LOG_ERR(PFX "%s: Waiting to join nic enable thread", +- nic->log_name); ++ LOG_DEBUG(PFX "%s: Waiting to join nic enable thread", ++ nic->log_name); + rc = pthread_join(nic->enable_thread, &res); + if (rc != 0) +- LOG_ERR(PFX "%s: Couldn't join to canceled enable nic " +- "thread", nic->log_name); ++ LOG_DEBUG(PFX "%s: Couldn't join to canceled enable " ++ "nic thread", nic->log_name); + nic->enable_thread = INVALID_THREAD; ++ LOG_DEBUG(PFX "%s: nic enable thread cleaned", nic->log_name); ++ } else { ++ LOG_DEBUG(PFX "%s: NIC enable thread already canceled", ++ nic->log_name); + } ++ + if (nic->thread != INVALID_THREAD) { +- LOG_ERR(PFX "%s: Canceling nic thread", nic->log_name); ++ LOG_DEBUG(PFX "%s: Canceling nic thread", nic->log_name); + + rc = pthread_cancel(nic->thread); + if (rc != 0) +- LOG_ERR(PFX "%s: Couldn't send cancel to nic", +- nic->log_name); ++ LOG_DEBUG(PFX "%s: Couldn't send cancel to nic", ++ nic->log_name); + +- LOG_ERR(PFX "%s: Waiting to join nic thread", nic->log_name); ++ LOG_DEBUG(PFX "%s: Waiting to join nic thread", nic->log_name); + rc = pthread_join(nic->thread, &res); + if (rc != 0) +- LOG_ERR(PFX "%s: Couldn't join to canceled nic thread", +- nic->log_name); +- ++ LOG_DEBUG(PFX "%s: Couldn't join to canceled nic " ++ "thread", nic->log_name); + nic->thread = INVALID_THREAD; ++ LOG_DEBUG(PFX "%s: nic thread cleaned", nic->log_name); ++ } else { ++ LOG_DEBUG(PFX "%s: NIC thread already canceled", nic->log_name); ++ } ++ ++ if (nic->nl_process_thread != INVALID_THREAD) { ++ LOG_DEBUG(PFX "%s: Canceling nic nl thread", nic->log_name); ++ ++ rc = pthread_cancel(nic->nl_process_thread); ++ if (rc != 0) ++ LOG_DEBUG(PFX "%s: Couldn't send cancel to nic nl " ++ "thread", nic->log_name); ++ ++ LOG_DEBUG(PFX "%s: Waiting to join nic nl thread", ++ nic->log_name); ++ rc = pthread_join(nic->nl_process_thread, &res); ++ if (rc != 0) ++ LOG_DEBUG(PFX "%s: Couldn't join to canceled nic nl " ++ "thread", nic->log_name); ++ nic->nl_process_thread = INVALID_THREAD; ++ LOG_DEBUG(PFX "%s: nic nl thread cleaned", nic->log_name); + } else { +- LOG_ERR(PFX "%s: NIC thread already canceled", nic->log_name); ++ LOG_DEBUG(PFX "%s: NIC nl thread already canceled", ++ nic->log_name); + } + + current = prev = nic_list; +@@ -505,7 +541,7 @@ int nic_remove(nic_t * nic) + + /* Before freeing the nic, must free all the associated + nic_iface */ +- nic_iface = nic->nic_iface; ++ nic_iface = current->nic_iface; + while (nic_iface != NULL) { + vlan_iface = nic_iface->vlan_next; + while (vlan_iface != NULL) { +@@ -608,7 +644,7 @@ error: + } + + /** +- * net_iface_init() - This function is used to add an interface to the ++ * nic_iface_init() - This function is used to add an interface to the + * structure cnic_uio + * @return 0 on success, <0 on failure + */ +@@ -623,6 +659,8 @@ nic_interface_t *nic_iface_init() + memset(nic_iface, 0, sizeof(*nic_iface)); + nic_iface->next = NULL; + nic_iface->vlan_next = NULL; ++ nic_iface->iface_num = IFACE_NUM_INVALID; ++ nic_iface->request_type = IP_CONFIG_OFF; + + return nic_iface; + } +@@ -630,112 +668,57 @@ nic_interface_t *nic_iface_init() + /** + * nic_add_nic_iface() - This function is used to add an interface to the + * nic structure ++ * Called with nic_mutex held + * @param nic - struct nic device to add the interface to + * @param nic_iface - network interface used to add to the nic + * @return 0 on success, <0 on failure + */ +-int nic_add_nic_iface(nic_t * nic, nic_interface_t * nic_iface) ++int nic_add_nic_iface(nic_t *nic, nic_interface_t *nic_iface) + { ++ nic_interface_t *current, *prev; ++ ++ /* Make sure it doesn't already exist */ ++ current = nic_find_nic_iface(nic, nic_iface->protocol, ++ nic_iface->vlan_id, nic_iface->iface_num, ++ nic_iface->request_type); ++ if (current) { ++ LOG_DEBUG(PFX "%s: nic interface for VLAN: %d, protocol: %d" ++ " already exist", nic->log_name, nic_iface->vlan_id, ++ nic_iface->protocol); ++ return 0; ++ } + +- pthread_mutex_lock(&nic->nic_mutex); +- +- /* Add the nic_interface */ +- if (nic->nic_iface == NULL) { +- nic->nic_iface = nic_iface; +- } else { +- nic_interface_t *current = nic->nic_iface; +- +- /* Check to see if this interface already exists via 2 +- * conditions: 1) VLAN 2) protocol */ +- while (current != NULL) { +- if ((current->protocol == nic_iface->protocol) && +- (current->vlan_id == nic_iface->vlan_id)) { +- LOG_WARN(PFX "%s: nic interface alread exists" +- "for VLAN: %d, protocol: %d", +- nic->log_name, current->vlan_id, +- current->protocol); +- goto error; +- } +- current = current->next; +- } +- +- /* This interface doesn't exists, we can safely add +- * this nic interface */ +- current = nic->nic_iface; +- while (current->next != NULL) { +- current = current->next; ++ prev = NULL; ++ current = nic->nic_iface; ++ while (current != NULL) { ++ if (current->protocol == nic_iface->protocol) { ++ /* Replace parent */ ++ nic_iface->vlan_next = current; ++ nic_iface->next = current->next; ++ current->next = NULL; ++ if (prev) ++ prev->next = nic_iface; ++ else ++ nic->nic_iface = nic_iface; ++ goto done; + } +- +- current->next = nic_iface; ++ prev = current; ++ current = current->next; + } +- ++ nic_iface->next = nic->nic_iface; ++ nic->nic_iface = nic_iface; ++done: + /* Set nic_interface common fields */ + nic_iface->parent = nic; ++ memcpy(&nic_iface->ustack.uip_ethaddr.addr, nic->mac_addr, ETH_ALEN); + nic->num_of_nic_iface++; + + LOG_INFO(PFX "%s: Added nic interface for VLAN: %d, protocol: %d", + nic->log_name, nic_iface->vlan_id, nic_iface->protocol); + +-error: +- pthread_mutex_unlock(&nic->nic_mutex); +- + return 0; + } + +-/** +- * nic_add_vlan_iface() - This function is used to add a vlan interface to the +- * nic structure +- * @param nic - struct nic device to add the interface to +- * @param nic_iface - network interface to be added to +- * @param vlan_iface - vlan interface used to add to the nic_iface +- * @return 0 on success, <0 on failure +- */ +-int nic_add_vlan_iface(nic_t *nic, nic_interface_t *nic_iface, +- nic_interface_t *vlan_iface) +-{ +- pthread_mutex_lock(&nic->nic_mutex); +- +- /* Add the nic_interface */ +- if (nic_iface == NULL) +- goto error; +- else { +- nic_interface_t *current = nic_iface->vlan_next; +- +- /* Check to see if this interface already exists via 2 +- * conditions: 1) VLAN 2) protocol */ +- while (current != NULL) { +- if ((current->protocol == vlan_iface->protocol) && +- (current->vlan_id == vlan_iface->vlan_id)) { +- LOG_WARN(PFX "%s: vlan interface already exists" +- "for VLAN: %d, protocol: %d", +- nic->log_name, current->vlan_id, +- current->protocol); +- goto error; +- } +- current = current->vlan_next; +- } +- +- /* This interface doesn't exists, we can safely add +- * this nic interface */ +- current = nic_iface; +- while (current->vlan_next != NULL) +- current = current->vlan_next; +- +- current->vlan_next = vlan_iface; +- } +- +- /* Set nic_interface common fields */ +- vlan_iface->parent = nic; +- nic->num_of_nic_iface++; +- +- LOG_INFO(PFX "%s: Added vlan interface for VLAN: %d, protocol: %d", +- nic->log_name, vlan_iface->vlan_id, vlan_iface->protocol); +- +-error: +- pthread_mutex_unlock(&nic->nic_mutex); +- +- return 0; +-} + /****************************************************************************** + * Routine to process interrupts from the NIC device + ******************************************************************************/ +@@ -752,13 +735,13 @@ int nic_process_intr(nic_t * nic, int discard_check) + struct timeval tv; + + /* Simple sanity checks */ +- if ((discard_check != 1) && (nic->state & NIC_RUNNING) != NIC_RUNNING) { ++ if (discard_check != 1 && nic->state != NIC_RUNNING) { + LOG_ERR(PFX "%s: Couldn't process interupt NIC not running", + nic->log_name); + return -EBUSY; + } + +- if ((discard_check != 1) && (nic->fd == INVALID_FD)) { ++ if (discard_check != 1 && nic->fd == INVALID_FD) { + LOG_ERR(PFX "%s: NIC fd not valid", nic->log_name); + return -EIO; + } +@@ -767,11 +750,12 @@ int nic_process_intr(nic_t * nic, int discard_check) + FD_SET(nic->fd, &fdset); + + tv.tv_sec = 0; +- if (nic->state & NIC_LONG_SLEEP) { ++ pthread_mutex_lock(&nic->nic_mutex); ++ if (nic->flags & NIC_LONG_SLEEP) + tv.tv_usec = 1000; +- } else { ++ else + tv.tv_usec = nic->rx_poll_usec; +- } ++ pthread_mutex_unlock(&nic->nic_mutex); + + /* Wait for an interrupt to come in or timeout */ + ret = select(nic->fd + 1, &fdset, NULL, NULL, &tv); +@@ -796,20 +780,20 @@ int nic_process_intr(nic_t * nic, int discard_check) + pthread_mutex_lock(&nic->nic_mutex); + if (ret > 0) { + nic->stats.interrupts++; +- LOG_DEBUG(PFX "%s: interrupt count: %d prev: %d", +- nic->log_name, count, nic->intr_count); ++ LOG_PACKET(PFX "%s: interrupt count: %d prev: %d", ++ nic->log_name, count, nic->intr_count); + + if (count == nic->intr_count) { +- LOG_WARN(PFX "%s: got interrupt but count still the " +- "same", nic->log_name, count); ++ LOG_PACKET(PFX "%s: got interrupt but count still the " ++ "same", nic->log_name, count); + } + + /* Check if we missed an interrupt. With UIO, + * the count should be incremental */ + if (count != nic->intr_count + 1) { + nic->stats.missed_interrupts++; +- LOG_DEBUG(PFX "%s: Missed interrupt! on %d not %d", +- nic->log_name, count, nic->intr_count); ++ LOG_PACKET(PFX "%s: Missed interrupt! on %d not %d", ++ nic->log_name, count, nic->intr_count); + } + + nic->intr_count = count; +@@ -833,9 +817,14 @@ static void prepare_ipv4_packet(nic_t * nic, + int queue_rc; + int vlan_id = 0; + +- if (nic_iface->vlan_id && !(NIC_VLAN_STRIP_ENABLED & nic->flags)) +- vlan_id = nic_iface->vlan_id; +- ++ /* If the rx vlan tag is not stripped and vlan is present in the pkt, ++ manual stripping is required because tx is using hw vlan tag! */ ++ if (pkt->network_layer == pkt->data_link_layer + ++ sizeof(struct uip_vlan_eth_hdr)) { ++ /* VLAN is detected in the pkt buf */ ++ memcpy(pkt->data_link_layer + 12, pkt->network_layer - 2, ++ pkt->buf_size - sizeof(struct uip_vlan_eth_hdr) + 2); ++ } + dest_ipv4_addr = uip_determine_dest_ipv4_addr(ustack, ipaddr); + if (dest_ipv4_addr == LOCAL_BROADCAST) { + uip_build_eth_header(ustack, ipaddr, NULL, pkt, vlan_id); +@@ -867,9 +856,12 @@ static void prepare_ipv6_packet(nic_t * nic, + struct uip_vlan_eth_hdr *eth_vlan; + int vlan_id = 0; + +- if (nic_iface->vlan_id && !(NIC_VLAN_STRIP_ENABLED & nic->flags)) +- vlan_id = nic_iface->vlan_id; +- ++ if (pkt->network_layer == pkt->data_link_layer + ++ sizeof(struct uip_vlan_eth_hdr)) { ++ /* VLAN is detected in the pkt buf */ ++ memcpy(pkt->data_link_layer + 12, pkt->network_layer - 2, ++ pkt->buf_size - sizeof(struct uip_vlan_eth_hdr) + 2); ++ } + eth = (struct uip_eth_hdr *)ustack->data_link_layer; + eth_vlan = (struct uip_vlan_eth_hdr *)ustack->data_link_layer; + if (vlan_id == 0) { +@@ -897,96 +889,96 @@ static void prepare_ustack(nic_t * nic, + * there is a VLAN tag or not, or if the hardware + * has stripped out the + * VLAN tag */ +- if ((nic_iface->vlan_id == 0) || (NIC_VLAN_STRIP_ENABLED & nic->flags)) { +- ustack->network_layer = ustack->data_link_layer + +- sizeof(struct uip_eth_hdr); +- } else { +- ustack->network_layer = ustack->data_link_layer + +- sizeof(struct uip_vlan_eth_hdr); +- } ++ ustack->network_layer = ustack->data_link_layer + ++ sizeof(struct uip_eth_hdr); + /* Init buffer to be IPv6 */ + if (nic_iface->ustack.ip_config == IPV6_CONFIG_DHCP || + nic_iface->ustack.ip_config == IPV6_CONFIG_STATIC) { + eth = (struct ether_header *)ustack->data_link_layer; +- eth->ether_type = UIP_ETHTYPE_IPv6; ++ eth->ether_type = htons(UIP_ETHTYPE_IPv6); + } + } + +-static int check_timers(nic_t * nic, +- struct timer *periodic_timer, struct timer *arp_timer) ++int do_timers_per_nic_iface(nic_t *nic, nic_interface_t *nic_iface, ++ struct timer *arp_timer) + { +- if (timer_expired(periodic_timer)) { +- int i; +- nic_interface_t *current; +- +- timer_reset(periodic_timer); ++ packet_t *pkt; ++ struct uip_stack *ustack = &nic_iface->ustack; ++ int i; + +- pthread_mutex_lock(&nic->nic_mutex); ++ pkt = get_next_free_packet(nic); ++ if (pkt == NULL) ++ return -EIO; + +- current = nic->nic_iface; +- while (current != NULL) { +- packet_t *pkt; +- struct uip_stack *ustack = ¤t->ustack; ++ if (nic_iface->ustack.ip_config == AF_INET) { ++ for (i = 0; i < UIP_UDP_CONNS; i++) { ++ prepare_ustack(nic, nic_iface, ustack, pkt); + +- pkt = get_next_free_packet(nic); +- if (pkt == NULL) { +- current = current->next; +- continue; ++ uip_udp_periodic(ustack, i); ++ /* If the above function invocation resulted ++ * in data that should be sent out on the ++ * network, the global variable uip_len is ++ * set to a value > 0. */ ++ if (ustack->uip_len > 0) { ++ pkt->buf_size = ustack->uip_len; ++ prepare_ipv4_packet(nic, nic_iface, ustack, ++ pkt); ++ (*nic->ops->write) (nic, nic_iface, pkt); ++ ustack->uip_len = 0; + } +- +- for (i = 0; i < UIP_UDP_CONNS; i++) { +- prepare_ustack(nic, current, ustack, pkt); +- +- uip_udp_periodic(ustack, i); +- /* If the above function invocation resulted +- * in data that should be sent out on the +- * network, the global variable uip_len is +- * set to a value > 0. */ +- if (ustack->uip_len > 0) { +- pkt->buf_size = ustack->uip_len; +- +- prepare_ipv4_packet(nic, +- current, +- ustack, pkt); +- +- (*nic->ops->write) (nic, current, pkt); +- ustack->uip_len = 0; +- } ++ } ++ } else { ++ /* Added periodic poll for IPv6 NDP engine */ ++ if (ustack->ndpc != NULL) { /* If engine is active */ ++ prepare_ustack(nic, nic_iface, ustack, pkt); ++ ++ uip_ndp_periodic(ustack); ++ /* If the above function invocation resulted ++ * in data that should be sent out on the ++ * network, the global variable uip_len is ++ * set to a value > 0. */ ++ if (ustack->uip_len > 0) { ++ pkt->buf_size = ustack->uip_len; ++ prepare_ipv6_packet(nic, nic_iface, ustack, ++ pkt); ++ (*nic->ops->write) (nic, nic_iface, pkt); ++ ustack->uip_len = 0; + } ++ } ++ } ++ /* Call the ARP timer function every 10 seconds. */ ++ if (timer_expired(arp_timer)) { ++ timer_reset(arp_timer); ++ uip_arp_timer(); ++ } ++ put_packet_in_free_queue(pkt, nic); ++ return 0; ++} + +- /* Added periodic poll for IPv6 NDP engine */ +- if (ustack->ndpc != NULL) { /* If engine is active */ +- prepare_ustack(nic, current, ustack, pkt); +- +- uip_ndp_periodic(ustack); +- /* If the above function invocation resulted +- * in data that should be sent out on the +- * network, the global variable uip_len is +- * set to a value > 0. */ +- if (ustack->uip_len > 0) { +- pkt->buf_size = ustack->uip_len; +- prepare_ipv6_packet(nic, +- current, +- ustack, pkt); +- (*nic->ops->write) (nic, current, pkt); +- ustack->uip_len = 0; +- } +- } ++static int check_timers(nic_t *nic, ++ struct timer *periodic_timer, struct timer *arp_timer) ++{ ++ if (timer_expired(periodic_timer)) { ++ nic_interface_t *nic_iface, *vlan_iface; + +- /* Call the ARP timer function every 10 seconds. */ +- if (timer_expired(arp_timer)) { +- timer_reset(arp_timer); +- uip_arp_timer(); +- } ++ timer_reset(periodic_timer); + +- put_packet_in_free_queue(pkt, nic); ++ pthread_mutex_lock(&nic->nic_mutex); + +- current = current->next; ++ nic_iface = nic->nic_iface; ++ while (nic_iface != NULL) { ++ do_timers_per_nic_iface(nic, nic_iface, arp_timer); ++ vlan_iface = nic_iface->vlan_next; ++ while (vlan_iface != NULL) { ++ do_timers_per_nic_iface(nic, vlan_iface, ++ arp_timer); ++ vlan_iface = vlan_iface->vlan_next; ++ } ++ nic_iface = nic_iface->next; + } + + pthread_mutex_unlock(&nic->nic_mutex); + } +- + return 0; + } + +@@ -1012,109 +1004,71 @@ int process_packets(nic_t * nic, + uint16_t type = 0; + int af_type = 0; + struct uip_stack *ustack; +- nic_interface_t *vlan_iface; ++ struct ip_hdr *ip; ++ pIPV6_HDR ip6; ++ void *dst_ip; ++ uint16_t vlan_id; + +- if ((pkt->vlan_tag == 0) || ++ pkt->data_link_layer = pkt->buf; ++ ++ vlan_id = pkt->vlan_tag & 0xFFF; ++ if ((vlan_id == 0) || + (NIC_VLAN_STRIP_ENABLED & nic->flags)) { + type = ntohs(ETH_BUF(pkt->buf)->type); ++ pkt->network_layer = pkt->data_link_layer + ++ sizeof(struct uip_eth_hdr); + } else { + type = ntohs(VLAN_ETH_BUF(pkt->buf)->type); ++ pkt->network_layer = pkt->data_link_layer + ++ sizeof(struct uip_vlan_eth_hdr); + } + + switch (type) { + case UIP_ETHTYPE_IPv6: + af_type = AF_INET6; ++ ip6 = (pIPV6_HDR) pkt->network_layer; ++ dst_ip = (void *)&ip6->ipv6_dst; + break; + case UIP_ETHTYPE_IPv4: +- af_type = AF_INET; +- break; + case UIP_ETHTYPE_ARP: + af_type = AF_INET; ++ ip = (struct ip_hdr *) pkt->network_layer; ++ dst_ip = (void *)&ip->destipaddr; + break; + default: +- LOG_DEBUG(PFX "%s: Ignoring vlan:0x%x ethertype:0x%x", +- nic->log_name, pkt->vlan_tag, type); ++ LOG_PACKET(PFX "%s: Ignoring vlan:0x%x ethertype:0x%x", ++ nic->log_name, vlan_id, type); + goto done; + } + +- /* check if we have the given VLAN interface */ +- if (nic_iface == NULL) { +- nic_iface = nic_find_nic_iface_protocol(nic, 0, +- af_type); +- if (nic_iface == NULL) { +- LOG_INFO(PFX "%s: Couldn't find interface for " +- "VLAN: %d af_type %d creating it", +- nic->log_name, pkt->vlan_tag, af_type); +- +- /* Create the vlan interface */ +- nic_iface = nic_iface_init(); +- +- if (nic_iface == NULL) { +- LOG_WARN(PFX "%s: Couldn't " +- "allocate " +- "nic_iface for " +- "VLAN: %d af_type %d", +- nic->log_name, pkt->vlan_tag, +- af_type); +- rc = 0; +- goto done; +- } +- +- nic_iface->protocol = af_type; +- nic_iface->vlan_id = 0; +- nic_add_nic_iface(nic, nic_iface); ++ pthread_mutex_lock(&nic->nic_mutex); + +- persist_all_nic_iface(nic); +- } +- if (pkt->vlan_tag) { +- vlan_iface = nic_find_vlan_iface_protocol(nic, +- nic_iface, pkt->vlan_tag, +- af_type); +- if (vlan_iface == NULL) { +- LOG_INFO(PFX "%s couldn't find " +- "interface with VLAN =" +- " %d ip_type: 0x%x " +- "creating it", +- nic->log_name, pkt->vlan_tag, +- af_type); +- +- /* Create the nic interface */ +- vlan_iface = nic_iface_init(); +- +- if (vlan_iface == NULL) { +- LOG_ERR(PFX "Couldn't allocate " +- "nic_iface for VLAN: %d", +- vlan_iface, +- pkt->vlan_tag); +- rc = 0; +- goto done; +- } +- vlan_iface->protocol = af_type; +- vlan_iface->vlan_id = pkt->vlan_tag; +- nic_add_vlan_iface(nic, nic_iface, +- vlan_iface); +- /* TODO: When VLAN support is placed */ +- /* in the iface file revisit this */ +- /* code */ +- memcpy(vlan_iface->ustack.hostaddr, +- nic_iface->ustack.hostaddr, +- sizeof(nic_iface->ustack.hostaddr)); +- memcpy(vlan_iface->ustack.netmask, +- nic_iface->ustack.netmask, +- sizeof(nic_iface->ustack.netmask)); +- memcpy(vlan_iface->ustack.netmask6, +- nic_iface->ustack.netmask6, +- sizeof(nic_iface->ustack.netmask6)); +- memcpy(vlan_iface->ustack.hostaddr6, +- nic_iface->ustack.hostaddr6, +- sizeof(nic_iface->ustack.hostaddr6)); +- +- persist_all_nic_iface(nic); +- } +- nic_iface = vlan_iface; ++ /* check if we have the given VLAN interface */ ++ if (nic_iface != NULL) { ++ if (vlan_id != nic_iface->vlan_id) { ++ /* Matching nic_iface not found, drop */ ++ pthread_mutex_unlock(&nic->nic_mutex); ++ rc = EINVAL; /* Return the +error code */ ++ goto done; + } ++ goto nic_iface_present; + } + ++ /* Best effort to find the correct instance ++ Input: protocol and vlan_tag */ ++ nic_iface = nic_find_nic_iface(nic, af_type, vlan_id, ++ IFACE_NUM_INVALID, ++ IP_CONFIG_OFF); ++ if (nic_iface == NULL) { ++ /* Matching nic_iface not found */ ++ pthread_mutex_unlock(&nic->nic_mutex); ++ LOG_PACKET(PFX "%s: Couldn't find interface for " ++ "VLAN: %d af_type %d", ++ nic->log_name, vlan_id, af_type); ++ rc = EINVAL; /* Return the +error code */ ++ goto done; ++ } ++nic_iface_present: + pkt->nic_iface = nic_iface; + + ustack = &nic_iface->ustack; +@@ -1123,27 +1077,17 @@ int process_packets(nic_t * nic, + ustack->uip_len = pkt->buf_size; + ustack->data_link_layer = pkt->buf; + +- pkt->data_link_layer = pkt->buf; +- + /* Adjust the network layer pointer depending if there is a + * VLAN tag or not, or if the hardware has stripped out the + * VLAN tag */ +- if ((pkt->vlan_tag == 0) || +- (NIC_VLAN_STRIP_ENABLED & nic->flags)) { ++ if ((vlan_id == 0) || ++ (NIC_VLAN_STRIP_ENABLED & nic->flags)) + ustack->network_layer = ustack->data_link_layer + + sizeof(struct uip_eth_hdr); +- pkt->network_layer = pkt->data_link_layer + +- sizeof(struct uip_eth_hdr); +- type = ntohs(ETH_BUF(pkt->buf)->type); +- } else { ++ else + ustack->network_layer = ustack->data_link_layer + + sizeof(struct uip_vlan_eth_hdr); +- pkt->network_layer = pkt->data_link_layer + +- sizeof(struct uip_vlan_eth_hdr); +- type = ntohs(VLAN_ETH_BUF(pkt->buf)->type); +- } + +- pthread_mutex_lock(&nic->nic_mutex); + /* determine how we should process this packet based on the + * ethernet type */ + switch (type) { +@@ -1270,25 +1214,174 @@ static int process_dhcp_loop(nic_t * nic, + } + + if (timercmp(&total_time, ¤t_time, <)) { +- LOG_ERR(PFX "%s: timeout waiting for DHCP", ++ LOG_ERR(PFX "%s: timeout waiting for DHCP/NDP", + nic->log_name); ++ if (nic_iface->ustack.ip_config == IPV6_CONFIG_DHCP || ++ nic_iface->ustack.ip_config == IPV6_CONFIG_STATIC) ++ n->retry_count = IPV6_MAX_ROUTER_SOL_RETRY; + return -EIO; + } + } + + if (nic->flags & NIC_GOING_DOWN) + return -EIO; ++ else if (nic->flags & NIC_DISABLED) ++ return -EINVAL; + else + return 0; + } + ++/* Called with nic_mutex locked */ ++static int do_acquisition(nic_t *nic, nic_interface_t *nic_iface, ++ struct timer *periodic_timer, struct timer *arp_timer) ++{ ++ struct in_addr addr; ++ struct in6_addr addr6; ++ void *res; ++ char buf[INET6_ADDRSTRLEN]; ++ int rc = -1; ++ ++ /* New acquisition */ ++ uip_init(&nic_iface->ustack, nic->flags & NIC_IPv6_ENABLED); ++ memcpy(&nic_iface->ustack.uip_ethaddr.addr, nic->mac_addr, ETH_ALEN); ++ ++ LOG_INFO(PFX "%s: Initialized ip stack: VLAN: %d", ++ nic->log_name, nic_iface->vlan_id); ++ ++ LOG_INFO(PFX "%s: mac: %02x:%02x:%02x:%02x:%02x:%02x", ++ nic->log_name, ++ nic_iface->mac_addr[0], ++ nic_iface->mac_addr[1], ++ nic_iface->mac_addr[2], ++ nic_iface->mac_addr[3], ++ nic_iface->mac_addr[4], ++ nic_iface->mac_addr[5]); ++ ++ switch (nic_iface->ustack.ip_config) { ++ case IPV4_CONFIG_STATIC: ++ memcpy(&addr.s_addr, nic_iface->ustack.hostaddr, ++ sizeof(addr.s_addr)); ++ ++ LOG_INFO(PFX "%s: Using IP address: %s", ++ nic->log_name, inet_ntoa(addr)); ++ ++ memcpy(&addr.s_addr, nic_iface->ustack.netmask, ++ sizeof(addr.s_addr)); ++ ++ LOG_INFO(PFX "%s: Using netmask: %s", ++ nic->log_name, inet_ntoa(addr)); ++ ++ set_uip_stack(&nic_iface->ustack, ++ &nic_iface->ustack.hostaddr, ++ &nic_iface->ustack.netmask, ++ &nic_iface->ustack.default_route_addr, ++ nic_iface->mac_addr); ++ break; ++ ++ case IPV4_CONFIG_DHCP: ++ set_uip_stack(&nic_iface->ustack, ++ &nic_iface->ustack.hostaddr, ++ &nic_iface->ustack.netmask, ++ &nic_iface->ustack.default_route_addr, ++ nic_iface->mac_addr); ++ if (dhcpc_init(nic, &nic_iface->ustack, ++ nic_iface->mac_addr, ETH_ALEN)) { ++ if (nic_iface->ustack.dhcpc) { ++ LOG_DEBUG(PFX "%s: DHCPv4 engine already " ++ "initialized!", nic->log_name); ++ goto skip; ++ } else { ++ LOG_DEBUG(PFX "%s: DHCPv4 engine failed " ++ "initialization!", nic->log_name); ++ goto error; ++ } ++ } ++ pthread_mutex_unlock(&nic->nic_mutex); ++ rc = process_dhcp_loop(nic, nic_iface, periodic_timer, ++ arp_timer); ++ pthread_mutex_lock(&nic->nic_mutex); ++ ++ if (rc) { ++ LOG_ERR(PFX "%s: DHCP failed", nic->log_name); ++ /* For DHCPv4 failure, the ustack must be cleaned so ++ it can re-acquire on the next iscsid request */ ++ uip_reset(&nic_iface->ustack); ++ ++ /* Signal that the device enable is ++ done */ ++ pthread_cond_broadcast(&nic->enable_done_cond); ++ pthread_mutex_unlock(&nic->nic_mutex); ++ ++ if (nic->enable_thread == INVALID_THREAD) ++ goto dhcp_err; ++ ++ rc = pthread_join(nic->enable_thread, &res); ++ if (rc != 0) ++ LOG_ERR(PFX "%s: Couldn't join to canceled " ++ "enable nic thread", nic->log_name); ++dhcp_err: ++ pthread_mutex_lock(&nic->nic_mutex); ++ goto error; ++ } ++ ++ if (nic->flags & NIC_DISABLED) { ++ /* Break out of this loop */ ++ break; ++ } ++ ++ LOG_INFO(PFX "%s: Initialized dhcp client", nic->log_name); ++ break; ++ ++ case IPV6_CONFIG_DHCP: ++ case IPV6_CONFIG_STATIC: ++ if (ndpc_init(nic, &nic_iface->ustack, nic_iface->mac_addr, ++ ETH_ALEN)) { ++ LOG_DEBUG(PFX "%s: IPv6 engine already initialized!", ++ nic->log_name); ++ goto skip; ++ } ++ pthread_mutex_unlock(&nic->nic_mutex); ++ rc = process_dhcp_loop(nic, nic_iface, periodic_timer, ++ arp_timer); ++ pthread_mutex_lock(&nic->nic_mutex); ++ if (rc) { ++ /* Don't reset and allow to use RA and LL */ ++ LOG_ERR(PFX "%s: IPv6 DHCP/NDP failed", nic->log_name); ++ } ++ if (nic_iface->ustack.ip_config == IPV6_CONFIG_STATIC) { ++ memcpy(&addr6.s6_addr, nic_iface->ustack.hostaddr6, ++ sizeof(addr6.s6_addr)); ++ inet_ntop(AF_INET6, addr6.s6_addr, buf, sizeof(buf)); ++ LOG_INFO(PFX "%s: hostaddr IP: %s", nic->log_name, buf); ++ memcpy(&addr6.s6_addr, nic_iface->ustack.netmask6, ++ sizeof(addr6.s6_addr)); ++ inet_ntop(AF_INET6, addr6.s6_addr, buf, sizeof(buf)); ++ LOG_INFO(PFX "%s: netmask IP: %s", nic->log_name, buf); ++ } ++ break; ++ ++ default: ++ LOG_INFO(PFX "%s: ipconfig = %d?", nic->log_name, ++ nic_iface->ustack.ip_config); ++ } ++skip: ++ /* Mark acquisition done for this nic iface */ ++ nic_iface->flags &= ~NIC_IFACE_ACQUIRE; ++ ++ LOG_INFO(PFX "%s: enabled vlan %d protocol: %d", nic->log_name, ++ nic_iface->vlan_id, nic_iface->protocol); ++ return 0; ++ ++error: ++ return -EIO; ++} ++ + void *nic_loop(void *arg) + { + nic_t *nic = (nic_t *) arg; + int rc = -1; +- struct timer periodic_timer, arp_timer; + sigset_t set; +- void *res; ++ struct timer periodic_timer, arp_timer; + + sigfillset(&set); + rc = pthread_sigmask(SIG_BLOCK, &set, NULL); +@@ -1302,10 +1395,11 @@ void *nic_loop(void *arg) + pthread_mutex_lock(&nic->nic_mutex); + pthread_cond_signal(&nic->nic_loop_started_cond); + ++ /* nic_mutex must be locked */ + while ((event_loop_stop == 0) && + !(nic->flags & NIC_EXIT_MAIN_LOOP) && + !(nic->flags & NIC_GOING_DOWN)) { +- nic_interface_t *nic_iface; ++ nic_interface_t *nic_iface, *vlan_iface; + + if (nic->flags & NIC_DISABLED) { + LOG_DEBUG(PFX "%s: Waiting to be enabled", +@@ -1322,8 +1416,6 @@ void *nic_loop(void *arg) + } + LOG_DEBUG(PFX "%s: is now enabled", nic->log_name); + } +- pthread_mutex_unlock(&nic->nic_mutex); +- + /* initialize the device to send/rec data */ + rc = (*nic->ops->open) (nic); + if (rc != 0) { +@@ -1331,18 +1423,17 @@ void *nic_loop(void *arg) + nic->log_name); + + if (rc == -ENOTSUP) +- nic->flags &= NIC_EXIT_MAIN_LOOP; ++ nic->flags |= NIC_EXIT_MAIN_LOOP; + else + nic->flags &= ~NIC_ENABLED; + + /* Signal that the device enable is done */ + pthread_cond_broadcast(&nic->enable_done_cond); + pthread_mutex_unlock(&nic->nic_mutex); +- + goto dev_close; + } +- + nic_set_all_nic_iface_mac_to_parent(nic); ++ pthread_mutex_unlock(&nic->nic_mutex); + + rc = alloc_free_queue(nic, 5); + if (rc != 5) { +@@ -1354,13 +1445,12 @@ void *nic_loop(void *arg) + "instead of %d", nic->log_name, 5); + /* Signal that the device enable is done */ + pthread_cond_broadcast(&nic->enable_done_cond); +- pthread_mutex_unlock(&nic->nic_mutex); + goto dev_close; + } + } + /* Indication for the nic_disable routine that the nic + has started running */ +- nic->state |= NIC_STARTED_RUNNING; ++ nic->state = NIC_STARTED_RUNNING; + + /* Initialize the system clocks */ + timer_set(&periodic_timer, CLOCK_SECOND / 2); +@@ -1369,192 +1459,25 @@ void *nic_loop(void *arg) + /* Prepare the stack for each of the VLAN interfaces */ + pthread_mutex_lock(&nic->nic_mutex); + ++ /* If DHCP fails, exit loop and restart the engine */ + nic_iface = nic->nic_iface; + while (nic_iface != NULL) { +- uip_init(&nic_iface->ustack, +- nic->flags & NIC_IPv6_ENABLED); +- memcpy(&nic_iface->ustack.uip_ethaddr.addr, +- nic->mac_addr, 6); +- +- LOG_INFO(PFX "%s: Initialized ip stack: VLAN: %d", +- nic->log_name, nic_iface->vlan_id); +- +- LOG_INFO(PFX "%s: mac: %02x:%02x:%02x:%02x:%02x:%02x", +- nic->log_name, +- nic_iface->mac_addr[0], +- nic_iface->mac_addr[1], +- nic_iface->mac_addr[2], +- nic_iface->mac_addr[3], +- nic_iface->mac_addr[4], +- nic_iface->mac_addr[5]); +- +- if (nic_iface->ustack.ip_config == IPV4_CONFIG_STATIC) { +- struct in_addr addr; +- uip_ip4addr_t tmp = { 0, 0 }; +- +- memcpy(&addr.s_addr, nic_iface->ustack.hostaddr, +- sizeof(addr.s_addr)); +- +- LOG_INFO(PFX "%s: Using IP address: %s", +- nic->log_name, inet_ntoa(addr)); +- +- memcpy(&addr.s_addr, nic_iface->ustack.netmask, +- sizeof(addr.s_addr)); +- +- LOG_INFO(PFX "%s: Using netmask: %s", +- nic->log_name, inet_ntoa(addr)); +- +- set_uip_stack(&nic_iface->ustack, +- &nic_iface->ustack.hostaddr, +- &nic_iface->ustack.netmask, +- &tmp, nic_iface->mac_addr); +- +- } else if (nic_iface->ustack.ip_config == +- IPV4_CONFIG_DHCP) { +- struct uip_stack *ustack = &nic_iface->ustack; +- uip_ip4addr_t tmp = { 0, 0 }; +- +- set_uip_stack(&nic_iface->ustack, +- &nic_iface->ustack.hostaddr, +- &nic_iface->ustack.netmask, +- &tmp, nic_iface->mac_addr); +- if (dhcpc_init(nic, ustack, +- nic_iface->mac_addr, ETH_ALEN)) { +- if (ustack->dhcpc) { +- LOG_DEBUG(PFX "%s: DHCPv4 " +- "engine already " +- "initialized!", +- nic->log_name); +- goto skip; +- } else { +- LOG_DEBUG(PFX "%s: DHCPv4 " +- "engine failed " +- "initialization!", +- nic->log_name); +- goto dev_close_free; +- } +- } +- pthread_mutex_unlock(&nic->nic_mutex); +- rc = process_dhcp_loop(nic, nic_iface, ++ if (nic_iface->flags & NIC_IFACE_ACQUIRE) { ++ do_acquisition(nic, nic_iface, ++ &periodic_timer, ++ &arp_timer); ++ } ++ vlan_iface = nic_iface->vlan_next; ++ while (vlan_iface != NULL) { ++ if (vlan_iface->flags & NIC_IFACE_ACQUIRE) { ++ do_acquisition(nic, vlan_iface, + &periodic_timer, + &arp_timer); +- pthread_mutex_lock(&nic->nic_mutex); +- +- if (rc) { +- LOG_ERR(PFX "%s: DHCP failed", +- nic->log_name); +- nic->flags |= NIC_DISABLED | +- NIC_RESET_UIP; +- nic->flags &= ~NIC_ENABLED; +- /* Signal that the device enable is +- done */ +- pthread_cond_broadcast( +- &nic->enable_done_cond); +- +- pthread_mutex_unlock(&nic->nic_mutex); +- +- if (nic->enable_thread == +- INVALID_THREAD) +- goto dev_close_free; +- +- rc = pthread_join(nic->enable_thread, +- &res); +- if (rc != 0) +- LOG_ERR(PFX "%s: Couldn't join " +- "to canceled enable nic" +- " thread", +- nic->log_name); +- +- goto dev_close_free; + } +- +- if (nic->flags & NIC_DISABLED) { +- pthread_mutex_unlock(&nic->nic_mutex); +- break; +- } +- +- LOG_INFO(PFX "%s: Initialized dhcp client", +- nic->log_name); +- } else if (nic_iface->ustack.ip_config == +- IPV6_CONFIG_DHCP || +- nic_iface->ustack.ip_config == +- IPV6_CONFIG_STATIC) { +- struct in6_addr addr6; +- char buf[INET6_ADDRSTRLEN]; +- +- /* Do router solicitation for both STATIC and +- DHCP - all NDP handling will take place in +- the DHCP loop +- STATIC - router advertisement will be handled +- in the uip background loop +- */ +- if (ndpc_init(nic, &nic_iface->ustack, +- nic_iface->mac_addr, ETH_ALEN)) { +- LOG_DEBUG(PFX "%s: IPv6 engine already" +- "initialized!", +- nic->log_name); +- goto skip; +- } +- if (nic_iface->ustack.ip_config == +- IPV6_CONFIG_DHCP) { +- pthread_mutex_unlock(&nic->nic_mutex); +- rc = process_dhcp_loop(nic, nic_iface, +- &periodic_timer, +- &arp_timer); +- pthread_mutex_lock(&nic->nic_mutex); +- if (rc) { +- /* Don't reset and allow to +- use RA and LL */ +- LOG_ERR(PFX "%s: DHCPv6 failed", +- nic->log_name); +- } +- if (nic->flags & NIC_DISABLED) { +- pthread_mutex_unlock(&nic-> +- nic_mutex); +- break; +- } +- } else { +- pthread_mutex_unlock(&nic->nic_mutex); +- rc = process_dhcp_loop(nic, nic_iface, +- &periodic_timer, +- &arp_timer); +- pthread_mutex_lock(&nic->nic_mutex); +- if (rc) { +- LOG_ERR(PFX "%s: IPv6 rtr " +- "failed", +- nic->log_name); +- } +- memcpy(&addr6.s6_addr, +- nic_iface->ustack.hostaddr6, +- sizeof(addr6.s6_addr)); +- inet_ntop(AF_INET6, +- addr6.s6_addr, +- buf, sizeof(buf)); +- LOG_INFO(PFX "%s: hostaddr IP: %s", +- nic->log_name, buf); +- +- memcpy(&addr6.s6_addr, +- nic_iface->ustack.netmask6, +- sizeof(addr6.s6_addr)); +- inet_ntop(AF_INET6, +- addr6.s6_addr, +- buf, sizeof(buf)); +- LOG_INFO(PFX "%s: netmask IP: %s", +- nic->log_name, buf); +- } +- } else { +- LOG_INFO(PFX "%s: ipconfig = %d?", +- nic->log_name, +- nic_iface->ustack.ip_config); ++ vlan_iface = vlan_iface->next; + } +-skip: +- LOG_INFO(PFX "%s: enabled vlan %d protocol: %d", +- nic->log_name, +- nic_iface->vlan_id, nic_iface->protocol); +- +- nic_iface = nic_iface->vlan_next; ++ nic_iface = nic_iface->next; + } +- + if (nic->flags & NIC_DISABLED) { + LOG_WARN(PFX "%s: nic was disabled during nic loop, " + "closing flag 0x%x", +@@ -1567,10 +1490,7 @@ skip: + + /* This is when we start the processing of packets */ + nic->start_time = time(NULL); +- nic->flags &= ~NIC_UNITIALIZED; +- nic->flags |= NIC_INITIALIZED; +- nic->state &= ~NIC_STOPPED; +- nic->state |= NIC_RUNNING; ++ nic->state = NIC_RUNNING; + + nic->flags &= ~NIC_ENABLED_PENDING; + +@@ -1580,14 +1500,14 @@ skip: + + LOG_INFO(PFX "%s: entering main nic loop", nic->log_name); + +- while ((nic->state & NIC_RUNNING) && ++ while ((nic->state == NIC_RUNNING) && + (event_loop_stop == 0) && + !(nic->flags & NIC_GOING_DOWN)) { + /* Check the periodic and ARP timer */ + check_timers(nic, &periodic_timer, &arp_timer); + rc = nic_process_intr(nic, 0); + while ((rc > 0) && +- (nic->state & NIC_RUNNING) && ++ (nic->state == NIC_RUNNING) && + !(nic->flags & NIC_GOING_DOWN)) { + rc = process_packets(nic, + &periodic_timer, +@@ -1609,33 +1529,7 @@ dev_close: + } else { + pthread_mutex_destroy(&nic->xmit_mutex); + pthread_mutex_init(&nic->xmit_mutex, NULL); +- +- if (nic->flags & NIC_RESET_UIP) { +- nic_interface_t *nic_iface = nic->nic_iface; +- nic_interface_t *vlan_iface; +- while (nic_iface != NULL) { +- LOG_INFO(PFX "%s: resetting uIP stack", +- nic->log_name); +- uip_reset(&nic_iface->ustack); +- vlan_iface = nic_iface->vlan_next; +- while (vlan_iface != NULL) { +- LOG_INFO(PFX "%s: resetting " +- "vlan uIP stack", +- nic->log_name); +- uip_reset(&vlan_iface->ustack); +- vlan_iface = +- vlan_iface->vlan_next; +- } +- nic_iface = nic_iface->next; +- } +- nic->flags &= ~NIC_RESET_UIP; +- } + } +- +- nic->flags |= NIC_UNITIALIZED; +- nic->flags &= ~NIC_INITIALIZED; +- nic->flags &= ~NIC_ENABLED_PENDING; +- + nic->pending_count = 0; + + if (!(nic->flags & NIC_EXIT_MAIN_LOOP)) { +@@ -1643,6 +1537,9 @@ dev_close: + pthread_cond_broadcast(&nic->disable_wait_cond); + } + } ++ /* clean up the nic flags */ ++ nic->flags &= ~NIC_ENABLED_PENDING; ++ + pthread_mutex_unlock(&nic->nic_mutex); + + LOG_INFO(PFX "%s: nic loop thread exited", nic->log_name); +diff --git a/iscsiuio/src/unix/nic.h b/iscsiuio/src/unix/nic.h +index 57d89b4..da900c5 100644 +--- a/iscsiuio/src/unix/nic.h ++++ b/iscsiuio/src/unix/nic.h +@@ -67,6 +67,8 @@ extern struct nic_lib_handle *nic_lib_list; + extern pthread_mutex_t nic_list_mutex; + extern struct nic *nic_list; + ++extern void *nl_process_handle_thread(void *arg); ++ + /******************************************************************************* + * Constants + ******************************************************************************/ +@@ -117,20 +119,30 @@ struct nic_stats { + * NIC interface structure + ******************************************************************************/ + typedef struct nic_interface { ++ struct nic_interface *vlan_next; + struct nic_interface *next; + struct nic *parent; + + uint16_t protocol; + uint16_t flags; +-#define NIC_IFACE_PERSIST 0x0001 ++#define NIC_IFACE_PERSIST (1<<0) ++#define NIC_IFACE_ACQUIRE (1<<1) ++#define NIC_IFACE_PATHREQ_WAIT1 (1<<2) ++#define NIC_IFACE_PATHREQ_WAIT2 (1<<3) ++#define NIC_IFACE_PATHREQ_WAIT (NIC_IFACE_PATHREQ_WAIT1 | \ ++ NIC_IFACE_PATHREQ_WAIT2) + uint8_t mac_addr[ETH_ALEN]; + uint8_t vlan_priority; + uint16_t vlan_id; ++#define NO_VLAN 0x8000 + ++ uint16_t mtu; + time_t start_time; + + struct uip_stack ustack; +- struct nic_interface *vlan_next; ++ ++ int iface_num; ++ int request_type; + } nic_interface_t; + + /****************************************************************************** +@@ -178,8 +190,9 @@ typedef struct nic_ops { + int (*clear_tx_intr) (struct nic *); + int (*handle_iscsi_path_req) (struct nic *, + int, +- struct iscsi_uevent * ev, +- struct iscsi_path * path); ++ struct iscsi_uevent *ev, ++ struct iscsi_path *path, ++ nic_interface_t *nic_iface); + } net_ops_t; + + typedef struct nic_lib_handle { +@@ -199,6 +212,9 @@ typedef struct nic { + #define NIC_DISABLED 0x0008 + #define NIC_IPv6_ENABLED 0x0010 + #define NIC_ADDED_MULICAST 0x0020 ++#define NIC_LONG_SLEEP 0x0040 ++#define NIC_PATHREQ_WAIT 0x0080 ++ + #define NIC_VLAN_STRIP_ENABLED 0x0100 + #define NIC_MSIX_ENABLED 0x0200 + #define NIC_TX_HAS_SENT 0x0400 +@@ -214,7 +230,6 @@ typedef struct nic { + #define NIC_STOPPED 0x0001 + #define NIC_STARTED_RUNNING 0x0002 + #define NIC_RUNNING 0x0004 +-#define NIC_LONG_SLEEP 0x0008 + #define NIC_EXIT 0x0010 + + int fd; /* Holds the file descriptor to UIO */ +@@ -232,6 +247,7 @@ typedef struct nic { + + uint32_t intr_count; /* Total UIO interrupt count */ + ++ /* Held for nic ops manipulation */ + pthread_mutex_t nic_mutex; + + /* iSCSI ring ethernet MAC address */ +@@ -268,6 +284,7 @@ typedef struct nic { + + /* Number of retrys from iscsid */ + uint32_t pending_count; ++ uint32_t pathreq_pending_count; + + #define DEFAULT_RX_POLL_USEC 100 /* usec */ + /* options enabled by the user */ +@@ -295,6 +312,19 @@ typedef struct nic { + int (*process_intr) (struct nic * nic); + + struct nic_ops *ops; ++ ++ /* NL processing parameters */ ++ pthread_t nl_process_thread; ++ pthread_cond_t nl_process_cond; ++ pthread_cond_t nl_process_if_down_cond; ++ pthread_mutex_t nl_process_mutex; ++ int nl_process_if_down; ++ int nl_process_head; ++ int nl_process_tail; ++#define NIC_NL_PROCESS_MAX_RING_SIZE 128 ++#define NIC_NL_PROCESS_LAST_ENTRY (NIC_NL_PROCESS_MAX_RING_SIZE - 1) ++#define NIC_NL_PROCESS_NEXT_ENTRY(x) ((x + 1) & NIC_NL_PROCESS_MAX_RING_SIZE) ++ void *nl_process_ring[NIC_NL_PROCESS_MAX_RING_SIZE]; + } nic_t; + + /****************************************************************************** +@@ -307,8 +337,6 @@ void nic_add(nic_t *nic); + int nic_remove(nic_t *nic); + + int nic_add_nic_iface(nic_t *nic, nic_interface_t *nic_iface); +-int nic_add_vlan_iface(nic_t *nic, nic_interface_t *nic_iface, +- nic_interface_t *vlan_iface); + int nic_process_intr(nic_t *nic, int discard_check); + + nic_interface_t *nic_iface_init(); +@@ -339,14 +367,6 @@ int enable_multicast(nic_t * nic); + int disable_multicast(nic_t * nic); + + void nic_set_all_nic_iface_mac_to_parent(nic_t * nic); +-struct nic_interface *nic_find_nic_iface(nic_t * nic, uint16_t vlan_id); +-struct nic_interface *nic_find_nic_iface_protocol(nic_t * nic, +- uint16_t vlan_id, +- uint16_t protocol); +-struct nic_interface *nic_find_vlan_iface_protocol(nic_t *nic, +- nic_interface_t *nic_iface, +- uint16_t vlan_id, +- uint16_t protocol); + int find_nic_lib_using_pci_id(uint32_t vendor, uint32_t device, + uint32_t subvendor, uint32_t subdevice, + nic_lib_handle_t ** handle, +diff --git a/iscsiuio/src/unix/nic_nl.c b/iscsiuio/src/unix/nic_nl.c +index 971f350..34e2062 100644 +--- a/iscsiuio/src/unix/nic_nl.c ++++ b/iscsiuio/src/unix/nic_nl.c +@@ -83,20 +83,6 @@ const static struct sockaddr_nl dest_addr = { + /* Netlink */ + int nl_sock = INVALID_FD; + +-/* Items used to handle the thread used to send/process ARP's */ +-static pthread_t nl_process_thread; +-static pthread_cond_t nl_process_cond; +-pthread_cond_t nl_process_if_down_cond; +-pthread_mutex_t nl_process_mutex; +-int nl_process_if_down = 0; +- +-#define NL_PROCESS_MAX_RING_SIZE 128 +-#define NL_PROCESS_LAST_ENTRY NL_PROCESS_MAX_RING_SIZE - 1 +-#define NL_PROCESS_NEXT_ENTRY(x) ((x + 1) & NL_PROCESS_MAX_RING_SIZE) +-static int nl_process_head; +-static int nl_process_tail; +-static void *nl_process_ring[NL_PROCESS_MAX_RING_SIZE]; +- + #define MAX_TX_DESC_CNT (TX_DESC_CNT - 1) + + #define NEXT_TX_BD(x) (((x) & (MAX_TX_DESC_CNT - 1)) == \ +@@ -222,10 +208,11 @@ int __kipc_call(int fd, void *iov_base, int iov_len) + static int pull_from_nl(char **buf) + { + int rc; +- size_t ev_size; ++ size_t ev_size, payload_size, alloc_size; + char nlm_ev[NLMSG_SPACE(sizeof(struct iscsi_uevent))]; + struct nlmsghdr *nlh; + char *data = NULL; ++ struct iscsi_uevent *ev; + + /* Take a quick peek at what how much uIP will need to read */ + rc = nl_read(nl_sock, nlm_ev, +@@ -249,14 +236,26 @@ static int pull_from_nl(char **buf) + return -EINVAL; + } + +- data = (char *)malloc(nlh->nlmsg_len); ++ ev = (struct iscsi_uevent *)NLMSG_DATA(nlh); ++ if (ev->type == ISCSI_KEVENT_PATH_REQ) { ++ ev_size = nlh->nlmsg_len - NLMSG_ALIGN(sizeof(struct nlmsghdr)); ++ payload_size = ev_size - sizeof(struct iscsi_uevent); ++ if (payload_size < sizeof(struct iscsi_path)) ++ alloc_size = nlh->nlmsg_len + (payload_size - ++ sizeof(struct iscsi_path)); ++ else ++ alloc_size = nlh->nlmsg_len; ++ } else { ++ alloc_size = nlh->nlmsg_len; ++ } ++ data = (char *)malloc(alloc_size); + if (unlikely(data == NULL)) { + LOG_ERR(PFX "Couldn't allocate %d bytes for Netlink " +- "iSCSI message", nlh->nlmsg_len); ++ "iSCSI message", alloc_size); + return -ENOMEM; + } + +- memset(data, 0, nlh->nlmsg_len); ++ memset(data, 0, alloc_size); + ev_size = nlh->nlmsg_len - NLMSG_ALIGN(sizeof(struct nlmsghdr)); + rc = nl_read(nl_sock, data, (int)nlh->nlmsg_len, MSG_WAITALL); + if (rc <= 0) { +@@ -269,10 +268,9 @@ static int pull_from_nl(char **buf) + + goto error; + } +- + *buf = data; + return 0; +- error: ++error: + if (data != NULL) + free(data); + +@@ -284,9 +282,8 @@ const static struct timespec ctldev_sleep_req = { + .tv_nsec = 250000000, + }; + +-static int ctldev_handle(char *data) ++static int ctldev_handle(char *data, nic_t *nic) + { +- nic_t *nic = NULL; + int rc; + struct iscsi_uevent *ev; + uint8_t *payload; +@@ -294,18 +291,12 @@ static int ctldev_handle(char *data) + char *msg_type_str; + uint32_t host_no; + int i; ++ nic_interface_t *nic_iface = NULL; + + ev = (struct iscsi_uevent *)NLMSG_DATA(data); + switch (ev->type) { + case ISCSI_KEVENT_PATH_REQ: + msg_type_str = "path_req"; +- +- host_no = ev->r.req_path.host_no; +- break; +- case ISCSI_KEVENT_IF_DOWN: +- msg_type_str = "if_down"; +- +- host_no = ev->r.notify_if_down.host_no; + break; + default: + /* We don't care about other iSCSI Netlink messages */ +@@ -315,22 +306,16 @@ static int ctldev_handle(char *data) + } + + /* This is a message that drivers should be interested in */ +- LOG_INFO("Received: '%s': host_no: %d", msg_type_str, host_no); +- +- rc = from_host_no_find_associated_eth_device(host_no, &nic); +- if (rc != 0) { +- LOG_ERR(PFX "Dropping msg, couldn't find nic with host no:%d", +- host_no); +- goto error; +- } ++ LOG_INFO(PFX "%s: Processing '%s'", nic->log_name, msg_type_str); + + payload = (uint8_t *) ((uint8_t *) ev) + sizeof(*ev); + path = (struct iscsi_path *)payload; + + if (ev->type == ISCSI_KEVENT_PATH_REQ) { + struct timespec sleep_rem; +- nic_interface_t *nic_iface, *vlan_iface; ++ nic_interface_t *vlan_iface; + uint16_t ip_type; ++ int iface_num, vlan_id; + + if (path->ip_addr_len == 4) + ip_type = AF_INET; +@@ -339,67 +324,107 @@ static int ctldev_handle(char *data) + else + ip_type = 0; + +- /* Find the parent nic_iface */ +- nic_iface = nic_find_nic_iface_protocol(nic, 0, ip_type); ++ /* Find the nic_iface to use */ ++ iface_num = ev->r.req_path.iface_num ? ++ ev->r.req_path.iface_num : IFACE_NUM_INVALID; ++ vlan_id = path->vlan_id ? path->vlan_id : NO_VLAN; ++ ++ LOG_DEBUG(PFX "%s: PATH_REQ with iface_num %d VLAN %d", ++ nic->log_name, iface_num, vlan_id); ++ ++ pthread_mutex_lock(&nic->nic_mutex); ++ ++ nic_iface = nic_find_nic_iface(nic, ip_type, vlan_id, ++ iface_num, IP_CONFIG_OFF); + if (nic_iface == NULL) { +- LOG_ERR(PFX "%s: Couldn't find nic iface " +- "vlan: %d ip_type: %d " +- "ip_addr_len: %d to clone", +- nic->log_name, path->vlan_id, ip_type, +- path->ip_addr_len); +- goto error; +- } +- if (path->vlan_id) { +- vlan_iface = nic_find_vlan_iface_protocol(nic, +- nic_iface, path->vlan_id, ip_type); +- if (vlan_iface == NULL) { +- /* Create a vlan_iface */ +- vlan_iface = nic_iface_init(); +- if (vlan_iface == NULL) { +- LOG_ERR(PFX "%s: Couldn't allocate " +- "space for vlan: %d ip_type: " +- "%d ip_addr_len: %d", +- nic->log_name, path->vlan_id, +- ip_type, path->ip_addr_len); +- goto error; ++ nic_iface = nic_find_nic_iface(nic, ip_type, ++ NO_VLAN, ++ IFACE_NUM_INVALID, ++ IP_CONFIG_OFF); ++ if (nic_iface == NULL) { ++ pthread_mutex_unlock(&nic->nic_mutex); ++ LOG_ERR(PFX "%s: Couldn't find nic iface parent" ++ " vlan: %d ip_type: %d " ++ "ip_addr_len: %d to clone", ++ nic->log_name, path->vlan_id, ip_type, ++ path->ip_addr_len); ++ goto error; ++ } ++ if (nic_iface->iface_num != IFACE_NUM_INVALID) { ++ /* New VLAN support: ++ Use the nic_iface found from the top ++ of the protocol family and ignore ++ the VLAN id from the path_req */ ++ if (!(nic_iface->iface_num == 0 && ++ nic_iface->vlan_id == 0 && ++ path->vlan_id)) { ++ pthread_mutex_unlock(&nic->nic_mutex); ++ goto nic_iface_done; + } +- +- vlan_iface->protocol = ip_type; +- vlan_iface->vlan_id = path->vlan_id; +- nic_add_vlan_iface(nic, nic_iface, vlan_iface); +- +- /* TODO: When VLAN support is placed in */ +- /* the iface file revisit this code */ +- vlan_iface->ustack.ip_config = +- nic_iface->ustack.ip_config; +- memcpy(vlan_iface->ustack.hostaddr, +- nic_iface->ustack.hostaddr, +- sizeof(nic_iface->ustack.hostaddr)); +- memcpy(vlan_iface->ustack.netmask, +- nic_iface->ustack.netmask, +- sizeof(nic_iface->ustack.netmask)); +- memcpy(vlan_iface->ustack.netmask6, +- nic_iface->ustack.netmask6, +- sizeof(nic_iface->ustack.netmask6)); +- memcpy(vlan_iface->ustack.hostaddr6, +- nic_iface->ustack.hostaddr6, +- sizeof(nic_iface->ustack.hostaddr6)); +- +- persist_all_nic_iface(nic); +- nic_disable(nic, 0); +- nic_iface = vlan_iface; ++ /* If iface_num == 0 and vlan_id == 0 but ++ the vlan_id from path_req is > 0, ++ then fallthru to the legacy support since ++ this is most likely from an older iscsid ++ (RHEL6.2/6.3 but has iface_num support) ++ */ + } +- } ++ /* Legacy VLAN support: ++ This newly created nic_iface must inherit the ++ network parameters from the parent nic_iface ++ */ ++ LOG_DEBUG(PFX "%s: Created the nic_iface for vlan: %d " ++ "ip_type: %d", nic->log_name, path->vlan_id, ++ ip_type); ++ vlan_iface = nic_iface_init(); ++ if (vlan_iface == NULL) { ++ pthread_mutex_unlock(&nic->nic_mutex); ++ LOG_ERR(PFX "%s: Couldn't allocate " ++ "space for vlan: %d ip_type: " ++ "%d", nic->log_name, path->vlan_id, ++ ip_type); ++ goto error; ++ } ++ vlan_iface->protocol = ip_type; ++ vlan_iface->vlan_id = path->vlan_id; ++ nic_add_nic_iface(nic, vlan_iface); ++ ++ vlan_iface->ustack.ip_config = ++ nic_iface->ustack.ip_config; ++ memcpy(vlan_iface->ustack.hostaddr, ++ nic_iface->ustack.hostaddr, ++ sizeof(nic_iface->ustack.hostaddr)); ++ memcpy(vlan_iface->ustack.netmask, ++ nic_iface->ustack.netmask, ++ sizeof(nic_iface->ustack.netmask)); ++ memcpy(vlan_iface->ustack.netmask6, ++ nic_iface->ustack.netmask6, ++ sizeof(nic_iface->ustack.netmask6)); ++ memcpy(vlan_iface->ustack.hostaddr6, ++ nic_iface->ustack.hostaddr6, ++ sizeof(nic_iface->ustack.hostaddr6)); ++ ++ /* Persist so when nic_close won't call uip_reset ++ to nullify nic_iface->ustack */ ++ persist_all_nic_iface(nic); ++ ++ nic_iface = vlan_iface; ++ ++ pthread_mutex_unlock(&nic->nic_mutex); + ++ /* nic_disable but not going down */ ++ nic_disable(nic, 0); ++ } else { ++ pthread_mutex_unlock(&nic->nic_mutex); ++ } ++nic_iface_done: + /* Force enable the NIC */ +- if ((nic->state & NIC_STOPPED) && +- !(nic->flags & NIC_ENABLED_PENDING)) ++ if (nic->state == NIC_STOPPED) + nic_enable(nic); + + /* Ensure that the NIC is RUNNING */ + rc = -EIO; + for (i = 0; i < 10; i++) { +- if ((nic->state & NIC_RUNNING) == NIC_RUNNING) { ++ if (nic->state == NIC_RUNNING) { + rc = 0; + break; + } +@@ -418,49 +443,25 @@ static int ctldev_handle(char *data) + } + + if (nic->ops) { +- char eth_device_name[IFNAMSIZ]; +- + switch (ev->type) { + case ISCSI_KEVENT_PATH_REQ: + /* pass the request up to the user space + * library driver */ +- if (nic->ops->handle_iscsi_path_req) { ++ nic_iface->flags |= NIC_IFACE_PATHREQ_WAIT2; ++ nic_iface->flags &= ~NIC_IFACE_PATHREQ_WAIT1; ++ if (nic->ops->handle_iscsi_path_req) + nic->ops->handle_iscsi_path_req(nic, + nl_sock, ev, +- path); +- } +- +- LOG_INFO(PFX "%s: 'path_req' operation finished", +- nic->log_name); +- +- rc = 0; +- break; +- case ISCSI_KEVENT_IF_DOWN: +- memcpy(eth_device_name, nic->eth_device_name, +- sizeof(eth_device_name)); +- +- pthread_mutex_lock(&nic_list_mutex); +- ++ path, ++ nic_iface); ++ nic_iface->flags &= ~NIC_IFACE_PATHREQ_WAIT; + pthread_mutex_lock(&nic->nic_mutex); +- nic->flags |= NIC_EXIT_MAIN_LOOP; ++ nic->flags &= ~NIC_PATHREQ_WAIT; + pthread_mutex_unlock(&nic->nic_mutex); +- +- pthread_cond_broadcast(&nic->enable_done_cond); +- +- nic_disable(nic, 1); +- +- nic_remove(nic); +- pthread_mutex_unlock(&nic_list_mutex); +- +- pthread_mutex_lock(&nl_process_mutex); +- nl_process_if_down = 0; +- pthread_mutex_unlock(&nl_process_mutex); ++ LOG_INFO(PFX "%s: 'path_req' operation finished", ++ nic->log_name); + + rc = 0; +- +- LOG_INFO(PFX "%s: 'if_down' operation finished", +- eth_device_name); +- + break; + default: + rc = -EAGAIN; +@@ -468,55 +469,62 @@ static int ctldev_handle(char *data) + } + } + +- error: ++error: + + return rc; + } + +-static void *nl_process_handle_thread(void *arg) ++/* NIC specific nl processing thread */ ++void *nl_process_handle_thread(void *arg) + { + int rc; ++ nic_t *nic = (nic_t *)arg; ++ ++ if (nic == NULL) ++ goto error; + + while (!event_loop_stop) { + char *data = NULL; + +- rc = pthread_cond_wait(&nl_process_cond, &nl_process_mutex); ++ rc = pthread_cond_wait(&nic->nl_process_cond, ++ &nic->nl_process_mutex); + if (rc != 0) { + LOG_ERR("Fatal error in NL processing thread " + "during wait[%s]", strerror(rc)); + break; + } + +- data = nl_process_ring[nl_process_head]; +- nl_process_ring[nl_process_head] = NULL; +- nl_process_tail = NL_PROCESS_NEXT_ENTRY(nl_process_tail); ++ data = nic->nl_process_ring[nic->nl_process_head]; ++ nic->nl_process_ring[nic->nl_process_head] = NULL; ++ nic->nl_process_tail = ++ NIC_NL_PROCESS_NEXT_ENTRY(nic->nl_process_tail); + +- pthread_mutex_unlock(&nl_process_mutex); ++ pthread_mutex_unlock(&nic->nl_process_mutex); + + if (data) { +- ctldev_handle(data); ++ ctldev_handle(data, nic); + free(data); + } + } +- ++error: + return NULL; + } + +-static void flush_nl_process_ring() ++static void flush_nic_nl_process_ring(nic_t *nic) + { + int i; + +- for (i = 0; i < NL_PROCESS_MAX_RING_SIZE; i++) { +- if (nl_process_ring[i] != NULL) { +- free(nl_process_ring[i]); +- nl_process_ring[i] = NULL; ++ for (i = 0; i < NIC_NL_PROCESS_MAX_RING_SIZE; i++) { ++ if (nic->nl_process_ring[i] != NULL) { ++ free(nic->nl_process_ring[i]); ++ nic->nl_process_ring[i] = NULL; + } + } + +- nl_process_head = 0; +- nl_process_tail = 0; ++ nic->nl_process_head = 0; ++ nic->nl_process_tail = 0; + +- LOG_DEBUG(PFX "Flushed NL ring"); ++ LOG_DEBUG(PFX "%s: Flushed NIC NL ring", nic->log_name); + } + + /** +@@ -528,25 +536,9 @@ static void flush_nl_process_ring() + int nic_nl_open() + { + int rc; ++ char *msg_type_str; + +- /* Prepare the thread to issue the ARP's */ +- nl_process_head = 0; +- nl_process_tail = 0; +- nl_process_if_down = 0; +- memset(&nl_process_ring, 0, sizeof(nl_process_ring)); +- +- pthread_mutex_init(&nl_process_mutex, NULL); +- pthread_cond_init(&nl_process_cond, NULL); +- pthread_cond_init(&nl_process_if_down_cond, NULL); +- +- rc = pthread_create(&nl_process_thread, NULL, +- nl_process_handle_thread, NULL); +- if (rc != 0) { +- LOG_ERR("Could not create NL processing thread [%s]", +- strerror(rc)); +- return -EIO; +- } +- ++ /* Prepare the thread to issue the ARP's */ + nl_sock = socket(PF_NETLINK, SOCK_RAW, NETLINK_ISCSI); + if (nl_sock < 0) { + LOG_ERR(PFX "can not create NETLINK_ISCSI socket [%s]", +@@ -581,6 +573,8 @@ int nic_nl_open() + while (!event_loop_stop) { + struct iscsi_uevent *ev; + char *buf = NULL; ++ uint32_t host_no; ++ nic_t *nic; + + rc = pull_from_nl(&buf); + if (rc != 0) +@@ -588,33 +582,91 @@ int nic_nl_open() + + /* Try to abort ARP'ing if a if_down was recieved */ + ev = (struct iscsi_uevent *)NLMSG_DATA(buf); +- if (ev->type == ISCSI_KEVENT_IF_DOWN) { +- LOG_INFO(PFX "Received if_down event"); ++ switch (ev->type) { ++ case ISCSI_KEVENT_IF_DOWN: ++ host_no = ev->r.notify_if_down.host_no; ++ msg_type_str = "if_down"; ++ break; ++ case ISCSI_KEVENT_PATH_REQ: ++ host_no = ev->r.req_path.host_no; ++ msg_type_str = "path_req"; ++ break; ++ default: ++ /* We don't care about other iSCSI Netlink messages */ ++ continue; ++ } ++ LOG_INFO(PFX "Received %s for host %d", msg_type_str, host_no); + +- pthread_mutex_lock(&nl_process_mutex); +- /* Don't flush the nl ring if another if_down +- is in progress */ +- if (!nl_process_if_down) { +- nl_process_if_down = 1; ++ /* Make sure the nic list doesn't get yanked */ ++ pthread_mutex_lock(&nic_list_mutex); + +- flush_nl_process_ring(); +- } +- pthread_mutex_unlock(&nl_process_mutex); ++ rc = from_host_no_find_associated_eth_device(host_no, &nic); ++ if (rc != 0) { ++ pthread_mutex_unlock(&nic_list_mutex); ++ LOG_ERR(PFX "Dropping msg, couldn't find nic with host " ++ "no: %d", host_no); ++ continue; ++ } ++ ++ /* Found the nic */ ++ if (nic->nl_process_thread == INVALID_THREAD) { ++ /* If thread is not valid, just drop it */ ++ pthread_mutex_unlock(&nic_list_mutex); ++ LOG_ERR(PFX "Dropping msg, nic nl process thread " ++ "not ready for host no: %d", host_no); ++ continue; + } + +- if ((nl_process_head + 1 == nl_process_tail) || +- (nl_process_tail == 0 && +- nl_process_head == NL_PROCESS_LAST_ENTRY)) { +- LOG_WARN(PFX "No space on Netlink ring"); ++ if (ev->type == ISCSI_KEVENT_IF_DOWN) { ++ char eth_device_name[IFNAMSIZ]; ++ ++ pthread_mutex_lock(&nic->nl_process_mutex); ++ nic->nl_process_if_down = 1; ++ flush_nic_nl_process_ring(nic); ++ pthread_cond_broadcast(&nic->nl_process_if_down_cond); ++ pthread_mutex_unlock(&nic->nl_process_mutex); ++ ++ memcpy(eth_device_name, nic->eth_device_name, ++ sizeof(eth_device_name)); ++ ++ pthread_mutex_lock(&nic->nic_mutex); ++ nic->flags &= ~NIC_PATHREQ_WAIT; ++ nic->flags |= NIC_EXIT_MAIN_LOOP; ++ pthread_cond_broadcast(&nic->enable_done_cond); ++ pthread_mutex_unlock(&nic->nic_mutex); ++ ++ pthread_mutex_lock(&nic->nl_process_mutex); ++ nic->nl_process_if_down = 0; ++ pthread_mutex_unlock(&nic->nl_process_mutex); ++ ++ nic_disable(nic, 1); ++ ++ nic_remove(nic); ++ pthread_mutex_unlock(&nic_list_mutex); ++ ++ LOG_INFO(PFX "%s: 'if_down' operation finished", ++ eth_device_name); ++ continue; ++ } ++ /* Place msg into the nic specific queue */ ++ pthread_mutex_lock(&nic->nl_process_mutex); ++ if ((nic->nl_process_head + 1 == nic->nl_process_tail) || ++ (nic->nl_process_tail == 0 && ++ nic->nl_process_head == NIC_NL_PROCESS_LAST_ENTRY)) { ++ pthread_mutex_unlock(&nic->nl_process_mutex); ++ pthread_mutex_unlock(&nic_list_mutex); ++ LOG_WARN(PFX "%s: No space on Netlink ring", ++ nic->log_name); + continue; + } ++ nic->nl_process_ring[nic->nl_process_head] = buf; ++ nic->nl_process_head = ++ NIC_NL_PROCESS_NEXT_ENTRY(nic->nl_process_head); ++ pthread_cond_signal(&nic->nl_process_cond); + +- pthread_mutex_lock(&nl_process_mutex); +- nl_process_ring[nl_process_head] = buf; +- nl_process_head = NL_PROCESS_NEXT_ENTRY(nl_process_head); ++ pthread_mutex_unlock(&nic->nl_process_mutex); + +- pthread_cond_signal(&nl_process_cond); +- pthread_mutex_unlock(&nl_process_mutex); ++ pthread_mutex_unlock(&nic_list_mutex); + + LOG_DEBUG(PFX "Pulled nl event"); + } +diff --git a/iscsiuio/src/unix/nic_utils.c b/iscsiuio/src/unix/nic_utils.c +index fe58df8..a1d3e72 100644 +--- a/iscsiuio/src/unix/nic_utils.c ++++ b/iscsiuio/src/unix/nic_utils.c +@@ -65,7 +65,7 @@ + *****************************************************************************/ + static const char nic_uio_sysfs_name_tempate[] = "/sys/class/uio/uio%i/name"; + static const char cnic_sysfs_uio_event_template[] = +- "/sys/class/uio/uio%d/event"; ++ "/sys/class/uio/uio%d/event"; + static const char base_uio_sysfs_name[] = "/sys/class/uio/"; + static const char uio_name[] = "uio"; + +@@ -77,7 +77,7 @@ static const char base_iscsi_host_name[] = "/sys/class/iscsi_host/"; + static const char host_template[] = "host%d"; + static const char iscsi_host_path_template[] = "/sys/class/iscsi_host/host%d"; + static const char iscsi_host_path_netdev_template[] = +- "/sys/class/iscsi_host/host%d/netdev"; ++ "/sys/class/iscsi_host/host%d/netdev"; + static const char cnic_uio_sysfs_resc_template[] = + "/sys/class/uio/uio%i/device/resource%i"; + +@@ -208,6 +208,7 @@ int nic_discover_iscsi_hosts() + + default: + /* There are iSCSI hosts */ ++ pthread_mutex_lock(&nic_list_mutex); + for (i = 0; i < count; i++) { + int host_no; + char *raw = NULL; +@@ -267,6 +268,7 @@ int nic_discover_iscsi_hosts() + + free(raw); + } ++ pthread_mutex_unlock(&nic_list_mutex); + + /* Cleanup the scandir() call */ + for (i = 0; i < count; i++) +@@ -402,6 +404,7 @@ static char *extract_none(struct dirent **files) + /** + * from_host_no_find_nic() - Given the host number + * this function will try to find the assoicated nic interface ++ * Must be called with nic_list_mutex lock + * @param host_no - minor number of the UIO device + * @param nic - pointer to the NIC will set if successful + * @return 0 on success, <0 on error +@@ -431,7 +434,6 @@ int from_host_no_find_associated_eth_device(int host_no, nic_t ** nic) + + rc = -EIO; + +- pthread_mutex_lock(&nic_list_mutex); + current_nic = nic_list; + while (current_nic != NULL) { + if (strcmp(raw, current_nic->eth_device_name) == 0) { +@@ -442,7 +444,6 @@ int from_host_no_find_associated_eth_device(int host_no, nic_t ** nic) + + current_nic = current_nic->next; + } +- pthread_mutex_unlock(&nic_list_mutex); + + free(raw); + +@@ -923,7 +924,7 @@ int nic_enable(nic_t * nic) + nic->log_name, nic->flags, nic->state); + return -EINVAL; + } +- if (nic->state & NIC_STOPPED) { ++ if (nic->state == NIC_STOPPED) { + struct timespec ts; + struct timeval tp; + int rc; +@@ -940,48 +941,20 @@ int nic_enable(nic_t * nic) + rc = gettimeofday(&tp, NULL); + ts.tv_sec = tp.tv_sec; + ts.tv_nsec = tp.tv_usec * 1000; +- ts.tv_sec += 10; ++ ts.tv_sec += 100; + + /* Wait for the device to be enabled */ + rc = pthread_cond_timedwait(&nic->enable_done_cond, + &nic->nic_mutex, &ts); +-#if 0 +- if (rc || !nic->flags & NIC_ENABLED) { +- /* Give it one more shout */ +- pthread_cond_broadcast(&nic->enable_wait_cond); +- rc = gettimeofday(&tp, NULL); +- ts.tv_sec = tp.tv_sec; +- ts.tv_nsec = tp.tv_usec * 1000; +- ts.tv_sec += 5; +- rc = pthread_cond_timedwait(&nic->enable_done_cond, +- &nic->nic_mutex, &ts); +- } +-#endif +- nic->flags &= ~NIC_ENABLED_PENDING; +- + if (rc == 0 && nic->flags & NIC_ENABLED) { + LOG_DEBUG(PFX "%s: device enabled", nic->log_name); + } else { +- LOG_ERR(PFX "%s: waiting to finish nic_enable err:%s", ++ nic->flags &= ~NIC_ENABLED; ++ nic->flags |= NIC_DISABLED; ++ nic->flags &= ~NIC_ENABLED_PENDING; ++ ++ LOG_ERR(PFX "%s: waiting to finish nic_enable err: %s", + nic->log_name, strerror(rc)); +- /* Must clean up the ustack */ +- nic_interface_t *nic_iface = nic->nic_iface; +- nic_interface_t *vlan_iface; +- while (nic_iface != NULL) { +- LOG_INFO(PFX "%s: resetting uIP stack", +- nic->log_name); +- uip_reset(&nic_iface->ustack); +- vlan_iface = nic_iface->vlan_next; +- while (vlan_iface != NULL) { +- LOG_INFO(PFX "%s: resetting " +- "vlan uIP stack", +- nic->log_name); +- uip_reset(&vlan_iface->ustack); +- vlan_iface = +- vlan_iface->vlan_next; +- } +- nic_iface = nic_iface->next; +- } + } + pthread_mutex_unlock(&nic->nic_mutex); + +@@ -1001,7 +974,8 @@ int nic_enable(nic_t * nic) + */ + int nic_disable(nic_t * nic, int going_down) + { +- if (nic->state & (NIC_STARTED_RUNNING | NIC_RUNNING)) { ++ if (nic->state == NIC_STARTED_RUNNING || ++ nic->state == NIC_RUNNING) { + struct timespec ts; + struct timeval tp; + int rc; +@@ -1012,8 +986,7 @@ int nic_disable(nic_t * nic, int going_down) + nic->flags &= ~NIC_ENABLED; + nic->flags |= NIC_DISABLED; + nic->flags &= ~NIC_STARTED_RUNNING; +- nic->state &= ~NIC_RUNNING; +- nic->state |= NIC_STOPPED; ++ nic->state = NIC_STOPPED; + + if (going_down) + nic->flags |= NIC_GOING_DOWN; +@@ -1070,7 +1043,9 @@ void nic_remove_all() + nic = nic_list; + while (nic != NULL) { + nic_next = nic->next; ++ pthread_mutex_lock(&nic->nic_mutex); + nic_close(nic, 1, FREE_ALL_STRINGS); ++ pthread_mutex_unlock(&nic->nic_mutex); + nic_remove(nic); + nic = nic_next; + } +@@ -1127,14 +1102,13 @@ error: + * nic_set_all_nic_iface_mac_to_parent() - This is a utility function used to + * intialize all the MAC addresses of the network interfaces for a given + * CNIC UIO device ++ * Call with nic mutex held + * @param dev - CNIC UIO device to initialize + */ +-void nic_set_all_nic_iface_mac_to_parent(nic_t * nic) ++void nic_set_all_nic_iface_mac_to_parent(nic_t *nic) + { + nic_interface_t *current, *vlan_current; + +- pthread_mutex_lock(&nic->nic_mutex); +- + current = nic->nic_iface; + while (current != NULL) { + /* Set the initial MAC address of this interface to the parent +@@ -1148,8 +1122,6 @@ void nic_set_all_nic_iface_mac_to_parent(nic_t * nic) + } + current = current->next; + } +- +- pthread_mutex_unlock(&nic->nic_mutex); + } + + /******************************************************************************* +@@ -1272,143 +1244,144 @@ void nic_fill_ethernet_header(nic_interface_t * nic_iface, + * NIC interface management utility functions + ******************************************************************************/ + /** +- * nic_find_nic_iface() - This function is used to find an interface from the +- * NIC +- * @param nic - NIC to look for network interfaces +- * @param vlan_id - VLAN id to look for +- * @return nic_iface - if found network interface with the given VLAN ID +- * if not found a NULL is returned +- */ +-nic_interface_t *nic_find_nic_iface(nic_t * nic, uint16_t vlan_id) +-{ +- nic_interface_t *current; +- +- pthread_mutex_lock(&nic->nic_mutex); +- +- current = nic->nic_iface; +- while (current != NULL) { +- if (current->vlan_id == vlan_id) { +- pthread_mutex_unlock(&nic->nic_mutex); +- return current; +- } +- +- current = current->next; +- } +- +- pthread_mutex_unlock(&nic->nic_mutex); +- +- return NULL; +-} +- +-/** +- * nic_find_nic_iface_protocol() - This function is used to find an interface +- * from the NIC ++ * nic_find_nic_iface() - This function is used to find an interface ++ * from the NIC + * @param nic - NIC to look for network interfaces + * @param vlan_id - VLAN id to look for + * @param protocol - either AF_INET or AF_INET6 ++ * @param iface_num - iface num to use if present ++ * @param request_type - IPV4/6 DHCP/STATIC + * @return nic_iface - if found network interface with the given VLAN ID + * if not found a NULL is returned + */ +-nic_interface_t *nic_find_nic_iface_protocol(nic_t * nic, +- uint16_t vlan_id, +- uint16_t protocol) ++nic_interface_t *nic_find_nic_iface(nic_t *nic, ++ uint16_t protocol, ++ uint16_t vlan_id, ++ int iface_num, ++ int request_type) + { +- nic_interface_t *current; ++ nic_interface_t *current = nic->nic_iface; ++ nic_interface_t *current_vlan = NULL; + +- pthread_mutex_lock(&nic->nic_mutex); +- +- current = nic->nic_iface; + while (current != NULL) { +- if ((current->vlan_id == vlan_id) && +- (current->protocol == protocol)) { +- pthread_mutex_unlock(&nic->nic_mutex); +- return current; ++ if (current->protocol != protocol) ++ goto next; ++ ++ /* Check for iface_num first */ ++ if (iface_num != IFACE_NUM_INVALID) { ++ if (current->iface_num == iface_num) { ++ /* Exception is when iface_num == 0, need to ++ check for request_type also if != ++ IP_CONFIG_OFF */ ++ if (!iface_num && request_type != ++ IP_CONFIG_OFF) { ++ if (current->request_type == ++ request_type) ++ goto found; ++ } else { ++ goto found; ++ } ++ } ++ } else if (vlan_id == NO_VLAN) { ++ /* Just return the top of the family */ ++ goto found; ++ } else { ++ if ((current->vlan_id == vlan_id) && ++ ((request_type == IP_CONFIG_OFF) || ++ (current->request_type == request_type))) ++ goto found; + } ++ /* vlan_next loop */ ++ current_vlan = current->vlan_next; ++ while (current_vlan != NULL) { ++ if (iface_num != IFACE_NUM_INVALID) { ++ if (current_vlan->iface_num == iface_num) { ++ if (!iface_num && request_type != ++ IP_CONFIG_OFF) { ++ if (current_vlan->request_type ++ == request_type) ++ goto vlan_found; ++ } else { ++ goto vlan_found; ++ } ++ } ++ } ++ if ((current_vlan->vlan_id == vlan_id) && ++ ((request_type == IP_CONFIG_OFF) || ++ (current_vlan->request_type == request_type))) ++ goto vlan_found; + ++ current_vlan = current_vlan->vlan_next; ++ } ++next: + current = current->next; + } +- +- pthread_mutex_unlock(&nic->nic_mutex); +- +- return NULL; ++vlan_found: ++ current = current_vlan; ++found: ++ return current; + } + ++/* Called with nic mutex held */ + void persist_all_nic_iface(nic_t * nic) + { +- nic_interface_t *current, *vlan_iface; +- +- pthread_mutex_lock(&nic->nic_mutex); ++ nic_interface_t *current_vlan, *current; + + current = nic->nic_iface; + while (current != NULL) { + current->flags |= NIC_IFACE_PERSIST; +- vlan_iface = current->vlan_next; +- while (vlan_iface != NULL) { +- vlan_iface->flags |= NIC_IFACE_PERSIST; +- vlan_iface = vlan_iface->vlan_next; ++ current_vlan = current->vlan_next; ++ while (current_vlan != NULL) { ++ current_vlan->flags |= NIC_IFACE_PERSIST; ++ current_vlan = current_vlan->vlan_next; + } + current = current->next; + } +- +- pthread_mutex_unlock(&nic->nic_mutex); +-} +- +-/** +- * nic_find_vlan_iface_protocol() - This function is used to find an interface +- * from the NIC +- * @param nic_iface - Base NIC to look for the vlan interfaces +- * @param vlan_id - VLAN id to look for +- * @param protocol - either AF_INET or AF_INET6 +- * @return nic_iface - if found network interface with the given VLAN ID +- * if not found a NULL is returned +- */ +-nic_interface_t *nic_find_vlan_iface_protocol(nic_t *nic, +- nic_interface_t *nic_iface, +- uint16_t vlan_id, +- uint16_t protocol) +-{ +- nic_interface_t *current; +- +- pthread_mutex_lock(&nic->nic_mutex); +- +- current = nic_iface->vlan_next; +- while (current != NULL) { +- if ((current->vlan_id == vlan_id) && +- (current->protocol == protocol)) { +- pthread_mutex_unlock(&nic->nic_mutex); +- return current; +- } +- current = current->vlan_next; +- } +- +- pthread_mutex_unlock(&nic->nic_mutex); +- return NULL; + } + ++/* Sets the nic_iface to the front of the AF */ + void set_nic_iface(nic_t *nic, nic_interface_t *nic_iface) + { + nic_interface_t *current, *prev; ++ nic_interface_t *current_vlan, *prev_vlan; + +- pthread_mutex_lock(&nic->nic_mutex); +- +- if (nic->nic_iface == nic_iface) +- goto done; +- +- prev = nic->nic_iface; +- current = nic->nic_iface->next; ++ prev = NULL; ++ current = nic->nic_iface; + while (current != NULL) { +- if (current == nic_iface) { +- prev->next = current->next; +- current->next = nic->nic_iface; +- nic->nic_iface = current; ++ if (current->protocol != nic_iface->protocol) ++ goto next; ++ /* If its already on top of the list, exit */ ++ if (current == nic_iface) + goto done; ++ ++ prev_vlan = current; ++ current_vlan = current->vlan_next; ++ ++ while (current_vlan != NULL) { ++ if (current_vlan == nic_iface) { ++ /* Found inside the vlan list */ ++ /* For vlan == 0, place on top of ++ the AF list */ ++ prev_vlan->vlan_next = ++ current_vlan->vlan_next; ++ current_vlan->vlan_next = current; ++ if (prev) ++ prev->next = current_vlan; ++ else ++ nic->nic_iface = current_vlan; ++ goto done; ++ } ++ prev_vlan = current_vlan; ++ current_vlan = current_vlan->vlan_next; + } ++next: + prev = current; + current = current->next; + } + done: +- pthread_mutex_unlock(&nic->nic_mutex); ++ return; + } ++ + /******************************************************************************* + * Packet management utility functions + ******************************************************************************/ +@@ -1639,7 +1612,7 @@ int capture_file(char **raw, uint32_t * raw_size, const char *path) + } + + read_size = fread(*raw, file_size, 1, fp); +- if (read_size < 0) { ++ if (!read_size) { + LOG_ERR("Could not read capture, path: %s len: %d [%s]", + path, file_size, strerror(ferror(fp))); + free(*raw); +diff --git a/iscsiuio/src/unix/nic_utils.h b/iscsiuio/src/unix/nic_utils.h +index ff76f6b..6c57701 100644 +--- a/iscsiuio/src/unix/nic_utils.h ++++ b/iscsiuio/src/unix/nic_utils.h +@@ -67,7 +67,9 @@ void nic_fill_ethernet_header(nic_interface_t * nic_iface, + int *pkt_size, void **start_addr, + uint16_t ether_type); + +-nic_interface_t *nic_find_nic_iface(nic_t * nic, uint16_t vlan_id); ++struct nic_interface *nic_find_nic_iface(nic_t *nic, uint16_t protocol, ++ uint16_t vlan_id, int iface_num, ++ int request_type); + void set_nic_iface(nic_t *nic, nic_interface_t *nic_iface); + + void persist_all_nic_iface(nic_t * nic); +diff --git a/iscsiuio/src/unix/nic_vlan.c b/iscsiuio/src/unix/nic_vlan.c +index 4f8f551..90a6244 100644 +--- a/iscsiuio/src/unix/nic_vlan.c ++++ b/iscsiuio/src/unix/nic_vlan.c +@@ -332,7 +332,8 @@ int find_vlans_using_phy_interface(struct vlan_handle *handle, + */ + int valid_vlan(short int vlan) + { +- if (vlan > 1 && vlan < 4095) ++ /* Allow vlan 1 to connect */ ++ if (vlan > 0 && vlan < 4095) + return 1; + + return 0; +diff --git a/iscsiuio/src/unix/packet.c b/iscsiuio/src/unix/packet.c +index 4d8bf55..5047030 100644 +--- a/iscsiuio/src/unix/packet.c ++++ b/iscsiuio/src/unix/packet.c +@@ -88,7 +88,7 @@ void free_packet(struct packet *pkt) + * reset_packet() - This will reset the packet fields to default values + * @param pkt - the packet to reset + */ +-void reset_packet(packet_t * pkt) ++void reset_packet(packet_t *pkt) + { + pkt->next = NULL; + +@@ -101,7 +101,7 @@ void reset_packet(packet_t * pkt) + pkt->network_layer = NULL; + } + +-int alloc_free_queue(nic_t * nic, size_t num_of_packets) ++int alloc_free_queue(nic_t *nic, size_t num_of_packets) + { + int rc, i; + diff --git a/iscsi-initiator-utils-sync-uio-0.7.6.1.patch b/iscsi-initiator-utils-sync-uio-0.7.6.1.patch new file mode 100644 index 0000000..fcac09e --- /dev/null +++ b/iscsi-initiator-utils-sync-uio-0.7.6.1.patch @@ -0,0 +1,327 @@ +From b15710a9b96c15e8cdcf3dcfda7b40559d565b3c Mon Sep 17 00:00:00 2001 +From: Eddie Wai +Date: Mon, 15 Oct 2012 14:47:54 -0700 +Subject: [PATCH] ISCSIUIO: Updated to 0.7.6.1 + +Signed-off-by: Eddie Wai +--- + iscsiuio/README | 4 ++-- + iscsiuio/RELEASE.TXT | 34 ++++++++++++++++++++++++++++++++-- + iscsiuio/configure | 18 +++++++++--------- + iscsiuio/configure.ac | 4 ++-- + iscsiuio/docs/iscsiuio.8 | 4 ++-- + iscsiuio/src/uip/uip_arp.c | 1 - + iscsiuio/src/unix/libs/bnx2x.c | 19 ++++++++++++++++--- + iscsiuio/src/unix/libs/bnx2x.h | 8 +++++++- + iscsiuio/src/unix/nic.c | 3 ++- + iscsiuio/src/unix/nic_nl.c | 2 +- + 10 files changed, 73 insertions(+), 24 deletions(-) + +diff --git a/iscsiuio/README b/iscsiuio/README +index a716263..e5ee23f 100644 +--- a/iscsiuio/README ++++ b/iscsiuio/README +@@ -1,6 +1,6 @@ + iscsiuio Userspace Tool +-Version 0.7.4.3 +-Aug 16, 2012 ++Version 0.7.6.1 ++Oct 09, 2012 + ------------------------------------------------------ + + This tool is to be used in conjunction with the Broadcom NetXtreme II Linux +diff --git a/iscsiuio/RELEASE.TXT b/iscsiuio/RELEASE.TXT +index cb1d470..0e7665c 100644 +--- a/iscsiuio/RELEASE.TXT ++++ b/iscsiuio/RELEASE.TXT +@@ -1,7 +1,7 @@ + Release Notes + Broadcom uIP Linux Driver +- Version 0.7.4.3 +- 08/16/2012 ++ Version 0.7.6.1 ++ 10/15/2012 + + Broadcom Corporation + 5300 California Avenue, +@@ -11,6 +11,36 @@ + All rights reserved + + ++uIP v0.7.6.1 (Oct 15, 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: Added support for 10G 57840 4x10 and 2x20 ++ Impact: 10G 57840 ++ ++ + uIP v0.7.4.3 (Aug 16, 2012) + ======================================================= + Fixes +diff --git a/iscsiuio/configure b/iscsiuio/configure +index 6ff2e68..0b2abc4 100644 +--- a/iscsiuio/configure ++++ b/iscsiuio/configure +@@ -1,6 +1,6 @@ + #! /bin/sh + # Guess values for system-dependent variables and create Makefiles. +-# Generated by GNU Autoconf 2.59 for iscsiuio 0.7.4.3. ++# Generated by GNU Autoconf 2.59 for iscsiuio 0.7.6.1. + # + # Report bugs to . + # +@@ -423,8 +423,8 @@ SHELL=${CONFIG_SHELL-/bin/sh} + # Identity of this package. + PACKAGE_NAME='iscsiuio' + PACKAGE_TARNAME='iscsiuio' +-PACKAGE_VERSION='0.7.4.3' +-PACKAGE_STRING='iscsiuio 0.7.4.3' ++PACKAGE_VERSION='0.7.6.1' ++PACKAGE_STRING='iscsiuio 0.7.6.1' + PACKAGE_BUGREPORT='eddie.wai@broadcom.com' + + # Factoring default headers for most tests. +@@ -954,7 +954,7 @@ if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +-\`configure' configures iscsiuio 0.7.4.3 to adapt to many kinds of systems. ++\`configure' configures iscsiuio 0.7.6.1 to adapt to many kinds of systems. + + Usage: $0 [OPTION]... [VAR=VALUE]... + +@@ -1020,7 +1020,7 @@ fi + + if test -n "$ac_init_help"; then + case $ac_init_help in +- short | recursive ) echo "Configuration of iscsiuio 0.7.4.3:";; ++ short | recursive ) echo "Configuration of iscsiuio 0.7.6.1:";; + esac + cat <<\_ACEOF + +@@ -1161,7 +1161,7 @@ fi + test -n "$ac_init_help" && exit 0 + if $ac_init_version; then + cat <<\_ACEOF +-iscsiuio configure 0.7.4.3 ++iscsiuio configure 0.7.6.1 + generated by GNU Autoconf 2.59 + + Copyright (C) 2003 Free Software Foundation, Inc. +@@ -1175,7 +1175,7 @@ cat >&5 <<_ACEOF + This file contains any messages produced by compilers while + running configure, to aid debugging if configure makes a mistake. + +-It was created by iscsiuio $as_me 0.7.4.3, which was ++It was created by iscsiuio $as_me 0.7.6.1, which was + generated by GNU Autoconf 2.59. Invocation command line was + + $ $0 $@ +@@ -21726,7 +21726,7 @@ _ASBOX + } >&5 + cat >&5 <<_CSEOF + +-This file was extended by iscsiuio $as_me 0.7.4.3, which was ++This file was extended by iscsiuio $as_me 0.7.6.1, which was + generated by GNU Autoconf 2.59. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES +@@ -21789,7 +21789,7 @@ _ACEOF + + cat >>$CONFIG_STATUS <<_ACEOF + ac_cs_version="\\ +-iscsiuio config.status 0.7.4.3 ++iscsiuio config.status 0.7.6.1 + configured by $0, generated by GNU Autoconf 2.59, + with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" + +diff --git a/iscsiuio/configure.ac b/iscsiuio/configure.ac +index 0b1e7f1..1045a80 100644 +--- a/iscsiuio/configure.ac ++++ b/iscsiuio/configure.ac +@@ -11,9 +11,9 @@ dnl Maintained by: Eddie Wai (eddie.wai@broadcom.com) + dnl + + PACKAGE=iscsiuio +-VERSION=0.7.4.3 ++VERSION=0.7.6.1 + +-AC_INIT(iscsiuio, 0.7.4.3, eddie.wai@broadcom.com) ++AC_INIT(iscsiuio, 0.7.6.1, eddie.wai@broadcom.com) + + AM_INIT_AUTOMAKE($PACKAGE, $VERSION) + AC_CONFIG_HEADER(config.h) +diff --git a/iscsiuio/docs/iscsiuio.8 b/iscsiuio/docs/iscsiuio.8 +index 4bf26df..d107327 100644 +--- a/iscsiuio/docs/iscsiuio.8 ++++ b/iscsiuio/docs/iscsiuio.8 +@@ -3,9 +3,9 @@ + .\" modify it under the terms of the GNU General Public License as + .\" published by the Free Software Foundation. + .\" +-.\" bnx2.4,v 0.7.4.3 ++.\" bnx2.4,v 0.7.6.1 + .\" +-.TH iscsiuio 8 "08/16/2012" "Broadcom Corporation" ++.TH iscsiuio 8 "10/09/2012" "Broadcom Corporation" + .\" + .\" NAME part + .\" +diff --git a/iscsiuio/src/uip/uip_arp.c b/iscsiuio/src/uip/uip_arp.c +index 3ef3b07..9dd02a1 100644 +--- a/iscsiuio/src/uip/uip_arp.c ++++ b/iscsiuio/src/uip/uip_arp.c +@@ -273,7 +273,6 @@ uip_arp_arpin(nic_interface_t * nic_iface, + pkt->buf_size = sizeof(*arp) + + sizeof(struct uip_vlan_eth_hdr); + } +- pkt->buf_size = sizeof(*arp) + sizeof(*eth); + } + break; + case const_htons(ARP_REPLY): +diff --git a/iscsiuio/src/unix/libs/bnx2x.c b/iscsiuio/src/unix/libs/bnx2x.c +index 5e33420..70e85c0 100644 +--- a/iscsiuio/src/unix/libs/bnx2x.c ++++ b/iscsiuio/src/unix/libs/bnx2x.c +@@ -103,6 +103,10 @@ static const char brcm_57840_MF[] = "Broadcom NetXtreme II BCM57840 MF " + "10-Gigabit"; + static const char brcm_57840_VF[] = "Broadcom NetXtreme II BCM57840 VF " + "10-Gigabit"; ++static const char brcm_57840_4_10[] = "Broadcom NetXtreme II BCM57840 4x" ++ "10-Gigabit"; ++static const char brcm_57840_2_20[] = "Broadcom NetXtreme II BCM57840 2x" ++ "20-Gigabit"; + + /******************************************************************************* + * PCI ID constants +@@ -123,6 +127,8 @@ static const char brcm_57840_VF[] = "Broadcom NetXtreme II BCM57840 VF " + #define PCI_DEVICE_ID_NX2_57840 0x168d + #define PCI_DEVICE_ID_NX2_57840_MF 0x16ab + #define PCI_DEVICE_ID_NX2_57840_VF 0x16ad ++#define PCI_DEVICE_ID_NX2_57840_4_10 0x16a1 ++#define PCI_DEVICE_ID_NX2_57840_2_20 0x16a2 + #define PCI_ANY_ID (~0) + + /* This is the table used to match PCI vendor and device ID's to the +@@ -158,6 +164,10 @@ static const struct pci_device_id bnx2x_pci_tbl[] = { + 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_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}, + }; + + static struct iro e1_iro[2] = { +@@ -1401,7 +1411,7 @@ static int bnx2x_read(nic_t * nic, packet_t * pkt) + union eth_rx_cqe *cqe; + __u8 cqe_fp_flags; + void *rx_pkt; +- int len, pad, cqe_size; ++ int len, pad, cqe_size, max_len; + rc = 1; + + if (bnx2x_is_ver70(bp)) { +@@ -1427,10 +1437,13 @@ static int bnx2x_read(nic_t * nic, packet_t * pkt) + + /* Doto query MTU size of physical device */ + /* Ensure len is valid */ +- if (len > pkt->max_buf_size) ++ max_len = pkt->max_buf_size < bp->rx_buffer_size ? ++ pkt->max_buf_size : bp->rx_buffer_size; ++ if (len > max_len) { + LOG_DEBUG(PFX "%s: bad BD length: %d", + nic->log_name, len); +- ++ len = max_len; ++ } + if (len > 0) { + msync(rx_pkt, len, MS_SYNC); + /* Copy the data */ +diff --git a/iscsiuio/src/unix/libs/bnx2x.h b/iscsiuio/src/unix/libs/bnx2x.h +index b758179..1f47011 100644 +--- a/iscsiuio/src/unix/libs/bnx2x.h ++++ b/iscsiuio/src/unix/libs/bnx2x.h +@@ -430,6 +430,8 @@ struct client_init_general_data { + #define CHIP_NUM_57800 0x168a + #define CHIP_NUM_57810 0x168e + #define CHIP_NUM_57840 0x168d ++#define CHIP_NUM_57840_4_10 0x16a1 ++#define CHIP_NUM_57840_2_20 0x16a2 + + #define CHIP_IS_E1(bp) (BNX2X_CHIP_NUM(bp) == CHIP_NUM_57710) + #define CHIP_IS_57711(bp) (BNX2X_CHIP_NUM(bp) == CHIP_NUM_57711) +@@ -438,7 +440,11 @@ struct client_init_general_data { + #define CHIP_IS_57712E(bp) (BNX2X_CHIP_NUM(bp) == CHIP_NUM_57712E) + #define CHIP_IS_57800(bp) (BNX2X_CHIP_NUM(bp) == CHIP_NUM_57800) + #define CHIP_IS_57810(bp) (BNX2X_CHIP_NUM(bp) == CHIP_NUM_57810) +-#define CHIP_IS_57840(bp) (BNX2X_CHIP_NUM(bp) == CHIP_NUM_57840) ++#define CHIP_IS_57840_4_10(bp) (BNX2X_CHIP_NUM(bp) == CHIP_NUM_57840_4_10) ++#define CHIP_IS_57840_2_20(bp) (BNX2X_CHIP_NUM(bp) == CHIP_NUM_57840_2_20) ++#define CHIP_IS_57840(bp) (BNX2X_CHIP_NUM(bp) == CHIP_NUM_57840 || \ ++ CHIP_IS_57840_4_10(bp) || \ ++ CHIP_IS_57840_2_20(bp)) + #define CHIP_IS_E1H(bp) (CHIP_IS_57711(bp) || \ + CHIP_IS_57711E(bp)) + #define CHIP_IS_E2(bp) (CHIP_IS_57712(bp) || \ +diff --git a/iscsiuio/src/unix/nic.c b/iscsiuio/src/unix/nic.c +index 0b3c538..72afff0 100644 +--- a/iscsiuio/src/unix/nic.c ++++ b/iscsiuio/src/unix/nic.c +@@ -460,6 +460,7 @@ int nic_remove(nic_t * nic) + 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; + +@@ -910,7 +911,7 @@ int do_timers_per_nic_iface(nic_t *nic, nic_interface_t *nic_iface, + if (pkt == NULL) + return -EIO; + +- if (nic_iface->ustack.ip_config == AF_INET) { ++ if (nic_iface->protocol == AF_INET) { + for (i = 0; i < UIP_UDP_CONNS; i++) { + prepare_ustack(nic, nic_iface, ustack, pkt); + +diff --git a/iscsiuio/src/unix/nic_nl.c b/iscsiuio/src/unix/nic_nl.c +index 34e2062..8afd9ae 100644 +--- a/iscsiuio/src/unix/nic_nl.c ++++ b/iscsiuio/src/unix/nic_nl.c +@@ -408,7 +408,7 @@ static int ctldev_handle(char *data, nic_t *nic) + 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 */ +-- +1.7.7.4 + diff --git a/iscsi-initiator-utils-uip-mgmt.patch b/iscsi-initiator-utils-uip-mgmt.patch index 8f81b16..1a03a31 100644 --- a/iscsi-initiator-utils-uip-mgmt.patch +++ b/iscsi-initiator-utils-uip-mgmt.patch @@ -1,6 +1,6 @@ -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/include/iscsi_err.h open-iscsi-2.0-872-rc4-bnx2i.build/include/iscsi_err.h ---- open-iscsi-2.0-872-rc4-bnx2i.base/include/iscsi_err.h 2011-08-14 16:49:44.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.build/include/iscsi_err.h 2011-08-14 16:56:54.000000000 -0500 +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/include/iscsi_err.h open-iscsi-2.0-872-rc4-bnx2i.work/include/iscsi_err.h +--- open-iscsi-2.0-872-rc4-bnx2i/include/iscsi_err.h 2012-03-05 23:36:21.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/include/iscsi_err.h 2012-03-05 23:36:29.000000000 -0600 @@ -58,6 +58,8 @@ enum { ISCSI_ERR_ISNS_QUERY = 25, /* iSNS registration/deregistration failed */ @@ -10,21 +10,21 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/include/iscsi_err.h open-iscsi-2.0 /* Always last. Indicates end of error code space */ ISCSI_MAX_ERR_VAL, -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/Makefile open-iscsi-2.0-872-rc4-bnx2i.build/libiscsi/Makefile ---- open-iscsi-2.0-872-rc4-bnx2i.base/libiscsi/Makefile 2011-08-14 16:55:23.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.build/libiscsi/Makefile 2011-08-14 16:56:54.000000000 -0500 +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/libiscsi/Makefile open-iscsi-2.0-872-rc4-bnx2i.work/libiscsi/Makefile +--- open-iscsi-2.0-872-rc4-bnx2i/libiscsi/Makefile 2012-03-05 23:36:21.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/libiscsi/Makefile 2012-03-05 23:37:25.000000000 -0600 @@ -13,7 +13,7 @@ TESTS += tests/test_set_auth tests/test_ COMMON_SRCS = sysdeps.o # sources shared between iscsid, iscsiadm and iscsistart --ISCSI_LIB_SRCS = netlink.o transport.o cxgbi.o be2iscsi.o iscsi_timer.o initiator_common.o iscsi_err.o session_info.o iscsi_util.o dcb_app.o io.o auth.o discovery.o login.o log.o md5.o sha1.o iface.o idbm.o sysfs.o iscsi_sysfs.o iscsi_net_util.o iscsid_req.o -+ISCSI_LIB_SRCS = netlink.o uip_mgmt_ipc.o transport.o cxgbi.o be2iscsi.o iscsi_timer.o initiator_common.o iscsi_err.o session_info.o iscsi_util.o dcb_app.o io.o auth.o discovery.o login.o log.o md5.o sha1.o iface.o idbm.o sysfs.o iscsi_sysfs.o iscsi_net_util.o iscsid_req.o +-ISCSI_LIB_SRCS = netlink.o transport.o iser.o cxgbi.o be2iscsi.o iscsi_timer.o initiator_common.o iscsi_err.o session_info.o iscsi_util.o dcb_app.o io.o auth.o discovery.o login.o log.o md5.o sha1.o iface.o idbm.o sysfs.o iscsi_sysfs.o iscsi_net_util.o iscsid_req.o ++ISCSI_LIB_SRCS = netlink.o uip_mgmt_ipc.o transport.o iser.o cxgbi.o be2iscsi.o iscsi_timer.o initiator_common.o iscsi_err.o session_info.o iscsi_util.o dcb_app.o io.o auth.o discovery.o login.o log.o md5.o sha1.o iface.o idbm.o sysfs.o iscsi_sysfs.o iscsi_net_util.o iscsid_req.o FW_PARAM_SRCS = fw_entry.o prom_lex.o prom_parse.tab.o fwparam_ppc.o fwparam_sysfs.o # sources shared with the userspace utils, note we build these separately -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/usr/initiator.c open-iscsi-2.0-872-rc4-bnx2i.build/usr/initiator.c ---- open-iscsi-2.0-872-rc4-bnx2i.base/usr/initiator.c 2011-08-14 16:49:44.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.build/usr/initiator.c 2011-08-14 16:56:54.000000000 -0500 +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/initiator.c +--- open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c 2012-03-05 23:36:21.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/initiator.c 2012-03-05 23:36:29.000000000 -0600 @@ -45,6 +45,7 @@ #include "iscsi_sysfs.h" #include "iscsi_settings.h" @@ -32,7 +32,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/usr/initiator.c open-iscsi-2.0-872 +#include "host.h" #include "sysdeps.h" #include "iscsi_err.h" - + #include "kern_err_table.h" @@ -557,6 +558,48 @@ static int iscsi_conn_connect(struct isc return 0; } @@ -94,7 +94,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/usr/initiator.c open-iscsi-2.0-872 if (iscsi_conn_connect(conn, qtask)) { delay = ISCSI_CONN_ERR_REOPEN_DELAY; goto queue_reopen; -@@ -1659,6 +1707,53 @@ failed_login: +@@ -1667,6 +1715,53 @@ failed_login: } @@ -148,7 +148,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/usr/initiator.c open-iscsi-2.0-872 static int iscsi_sched_ev_context(struct iscsi_ev_context *ev_context, struct iscsi_conn *conn, unsigned long tmo, int event) -@@ -1700,6 +1795,11 @@ static int iscsi_sched_ev_context(struct +@@ -1708,6 +1803,11 @@ static int iscsi_sched_ev_context(struct ev_context); actor_schedule(&ev_context->actor); break; @@ -160,7 +160,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/usr/initiator.c open-iscsi-2.0-872 case EV_CONN_LOGOUT_TIMER: actor_timer(&ev_context->actor, tmo * 1000, iscsi_logout_timedout, ev_context); -@@ -1833,7 +1933,17 @@ session_login_task(node_rec_t *rec, queu +@@ -1841,7 +1941,17 @@ session_login_task(node_rec_t *rec, queu conn = &session->conn[0]; qtask->conn = conn; @@ -179,7 +179,7 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/usr/initiator.c open-iscsi-2.0-872 __session_destroy(session); return ISCSI_ERR_LOGIN; } -@@ -1990,6 +2100,7 @@ iscsi_host_send_targets(queue_task_t *qt +@@ -1998,6 +2108,7 @@ iscsi_host_send_targets(queue_task_t *qt struct sockaddr_storage *ss) { struct iscsi_transport *t; @@ -187,9 +187,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/usr/initiator.c open-iscsi-2.0-872 t = iscsi_sysfs_get_transport_by_hba(host_no); if (!t) { -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/usr/initiator_common.c open-iscsi-2.0-872-rc4-bnx2i.build/usr/initiator_common.c ---- open-iscsi-2.0-872-rc4-bnx2i.base/usr/initiator_common.c 2011-08-14 16:49:44.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.build/usr/initiator_common.c 2011-08-14 16:56:54.000000000 -0500 +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator_common.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/initiator_common.c +--- open-iscsi-2.0-872-rc4-bnx2i/usr/initiator_common.c 2012-03-05 23:36:21.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/initiator_common.c 2012-03-05 23:36:29.000000000 -0600 @@ -561,6 +561,36 @@ TODO handle this return 0; } @@ -238,9 +238,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/usr/initiator_common.c open-iscsi- rc = host_set_param(t, session->hostno, ISCSI_HOST_PARAM_IPADDRESS, iface->ipaddress, ISCSI_STRING); -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/usr/initiator.h open-iscsi-2.0-872-rc4-bnx2i.build/usr/initiator.h ---- open-iscsi-2.0-872-rc4-bnx2i.base/usr/initiator.h 2011-08-14 16:49:44.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.build/usr/initiator.h 2011-08-14 16:58:14.000000000 -0500 +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/initiator.h +--- open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.h 2012-03-05 23:36:21.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/initiator.h 2012-03-05 23:36:29.000000000 -0600 @@ -83,6 +83,7 @@ typedef enum iscsi_event_e { EV_CONN_LOGOUT_TIMER, EV_CONN_STOP, @@ -258,9 +258,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/usr/initiator.h open-iscsi-2.0-872 + struct iface_rec *iface); #endif /* INITIATOR_H */ -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/usr/iscsid_req.c open-iscsi-2.0-872-rc4-bnx2i.build/usr/iscsid_req.c ---- open-iscsi-2.0-872-rc4-bnx2i.base/usr/iscsid_req.c 2011-08-14 16:49:44.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.build/usr/iscsid_req.c 2011-08-14 16:56:54.000000000 -0500 +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsid_req.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsid_req.c +--- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsid_req.c 2012-03-05 23:36:21.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsid_req.c 2012-03-05 23:36:29.000000000 -0600 @@ -22,6 +22,7 @@ #include #include @@ -391,9 +391,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/usr/iscsid_req.c open-iscsi-2.0-87 + close(fd); + return err; +} -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/usr/iscsid_req.h open-iscsi-2.0-872-rc4-bnx2i.build/usr/iscsid_req.h ---- open-iscsi-2.0-872-rc4-bnx2i.base/usr/iscsid_req.h 2011-08-14 16:49:44.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.build/usr/iscsid_req.h 2011-08-14 16:56:54.000000000 -0500 +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsid_req.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsid_req.h +--- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsid_req.h 2012-03-05 23:36:21.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsid_req.h 2012-03-05 23:36:29.000000000 -0600 @@ -33,4 +33,6 @@ extern int iscsid_req_by_rec(int cmd, st extern int iscsid_req_by_sid_async(int cmd, int sid, int *fd); extern int iscsid_req_by_sid(int cmd, int sid); @@ -401,9 +401,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/usr/iscsid_req.h open-iscsi-2.0-87 +extern int uip_broadcast(void *buf, size_t buf_len); + #endif -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/usr/iscsi_err.c open-iscsi-2.0-872-rc4-bnx2i.build/usr/iscsi_err.c ---- open-iscsi-2.0-872-rc4-bnx2i.base/usr/iscsi_err.c 2011-08-14 16:49:44.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.build/usr/iscsi_err.c 2011-08-14 16:56:54.000000000 -0500 +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_err.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_err.c +--- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_err.c 2012-03-05 23:36:21.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_err.c 2012-03-05 23:36:29.000000000 -0600 @@ -49,6 +49,7 @@ static char *iscsi_err_msgs[] = { /* 24 */ "iSCSI login failed due to authorization failure", /* 25 */ "iSNS query failed", @@ -412,22 +412,22 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/usr/iscsi_err.c open-iscsi-2.0-872 }; char *iscsi_err_to_str(int err) -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/usr/Makefile open-iscsi-2.0-872-rc4-bnx2i.build/usr/Makefile ---- open-iscsi-2.0-872-rc4-bnx2i.base/usr/Makefile 2011-08-14 16:55:23.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.build/usr/Makefile 2011-08-14 16:58:57.000000000 -0500 +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/Makefile open-iscsi-2.0-872-rc4-bnx2i.work/usr/Makefile +--- open-iscsi-2.0-872-rc4-bnx2i/usr/Makefile 2012-03-05 23:36:21.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/Makefile 2012-03-05 23:38:00.000000000 -0600 @@ -42,7 +42,8 @@ SYSDEPS_SRCS = $(wildcard ../utils/sysde ISCSI_LIB_SRCS = iscsi_util.o io.o auth.o iscsi_timer.o login.o log.o md5.o \ sha1.o iface.o idbm.o sysfs.o host.o session_info.o iscsi_sysfs.o \ - iscsi_net_util.o iscsid_req.o transport.o cxgbi.o be2iscsi.o \ + iscsi_net_util.o iscsid_req.o transport.o iser.o cxgbi.o be2iscsi.o \ - initiator_common.o iscsi_err.o $(IPC_OBJ) $(SYSDEPS_SRCS) $(DCB_OBJ) + initiator_common.o iscsi_err.o uip_mgmt_ipc.o \ + $(IPC_OBJ) $(SYSDEPS_SRCS) $(DCB_OBJ) # core initiator files - INITIATOR_SRCS = initiator.o scsi.o actor.o event_poll.o mgmt_ipc.o + INITIATOR_SRCS = initiator.o scsi.o actor.o event_poll.o mgmt_ipc.o kern_err_table.o -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/usr/transport.c open-iscsi-2.0-872-rc4-bnx2i.build/usr/transport.c ---- open-iscsi-2.0-872-rc4-bnx2i.base/usr/transport.c 2011-08-14 16:49:44.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.build/usr/transport.c 2011-08-14 16:56:54.000000000 -0500 +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/transport.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/transport.c +--- open-iscsi-2.0-872-rc4-bnx2i/usr/transport.c 2012-03-05 23:36:21.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/transport.c 2012-03-05 23:36:29.000000000 -0600 @@ -25,6 +25,7 @@ #include "log.h" #include "iscsi_util.h" @@ -435,8 +435,8 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/usr/transport.c open-iscsi-2.0-872 +#include "uip_mgmt_ipc.h" #include "cxgbi.h" #include "be2iscsi.h" - -@@ -67,6 +68,7 @@ struct iscsi_transport_template bnx2i = + #include "iser.h" +@@ -69,6 +70,7 @@ struct iscsi_transport_template bnx2i = .ep_connect = ktransport_ep_connect, .ep_poll = ktransport_ep_poll, .ep_disconnect = ktransport_ep_disconnect, @@ -444,9 +444,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/usr/transport.c open-iscsi-2.0-872 }; struct iscsi_transport_template be2iscsi = { -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/usr/transport.h open-iscsi-2.0-872-rc4-bnx2i.build/usr/transport.h ---- open-iscsi-2.0-872-rc4-bnx2i.base/usr/transport.h 2011-08-14 16:49:34.000000000 -0500 -+++ open-iscsi-2.0-872-rc4-bnx2i.build/usr/transport.h 2011-08-14 16:56:54.000000000 -0500 +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/transport.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/transport.h +--- open-iscsi-2.0-872-rc4-bnx2i/usr/transport.h 2012-03-05 23:36:21.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/transport.h 2012-03-05 23:36:29.000000000 -0600 @@ -35,6 +35,9 @@ struct iscsi_transport_template { int (*ep_poll) (struct iscsi_conn *conn, int timeout_ms); void (*ep_disconnect) (struct iscsi_conn *conn); @@ -457,9 +457,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/usr/transport.h open-iscsi-2.0-872 }; /* represents data path provider */ -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/usr/uip_mgmt_ipc.c open-iscsi-2.0-872-rc4-bnx2i.build/usr/uip_mgmt_ipc.c ---- open-iscsi-2.0-872-rc4-bnx2i.base/usr/uip_mgmt_ipc.c 1969-12-31 18:00:00.000000000 -0600 -+++ open-iscsi-2.0-872-rc4-bnx2i.build/usr/uip_mgmt_ipc.c 2011-08-14 16:56:54.000000000 -0500 +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/uip_mgmt_ipc.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/uip_mgmt_ipc.c +--- open-iscsi-2.0-872-rc4-bnx2i/usr/uip_mgmt_ipc.c 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/uip_mgmt_ipc.c 2012-03-05 23:36:29.000000000 -0600 @@ -0,0 +1,41 @@ +/* + * uIP iSCSI Daemon/Admin Management IPC @@ -502,9 +502,9 @@ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/usr/uip_mgmt_ipc.c open-iscsi-2.0- + sizeof(iscsid_uip_broadcast_header_t) + + sizeof(*iface)); +} -diff -Naurp open-iscsi-2.0-872-rc4-bnx2i.base/usr/uip_mgmt_ipc.h open-iscsi-2.0-872-rc4-bnx2i.build/usr/uip_mgmt_ipc.h ---- open-iscsi-2.0-872-rc4-bnx2i.base/usr/uip_mgmt_ipc.h 1969-12-31 18:00:00.000000000 -0600 -+++ open-iscsi-2.0-872-rc4-bnx2i.build/usr/uip_mgmt_ipc.h 2011-08-14 16:56:54.000000000 -0500 +diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/uip_mgmt_ipc.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/uip_mgmt_ipc.h +--- open-iscsi-2.0-872-rc4-bnx2i/usr/uip_mgmt_ipc.h 1969-12-31 18:00:00.000000000 -0600 ++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/uip_mgmt_ipc.h 2012-03-05 23:36:29.000000000 -0600 @@ -0,0 +1,73 @@ +/* + * uIP iSCSI Daemon/Admin Management IPC diff --git a/iscsi-initiator-utils.spec b/iscsi-initiator-utils.spec index 3cb86be..60353cb 100644 --- a/iscsi-initiator-utils.spec +++ b/iscsi-initiator-utils.spec @@ -1,16 +1,18 @@ -%{!?python_sitearch: %global python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib(1)")} +%{!?python_sitearch: %define python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib(1)")} Summary: iSCSI daemon and utility programs Name: iscsi-initiator-utils -Version: 6.2.0.872 -Release: 19%{?dist} +Version: 6.2.0.873 +Release: 2%{?dist} Source0: http://people.redhat.com/mchristi/iscsi/rhel6.0/source/open-iscsi-2.0-872-rc4-bnx2i.tar.gz Source1: iscsid.init Source2: iscsidevs.init Source3: 04-iscsi -# sync brcm to 0.7.0.12 -Patch0: iscsi-initiator-utils-sync-uio-0.7.0.8.patch -# sync iscsi tools to upstream commit e8c5b1d34ee5ce0a755ff54518829156dfa5fabe + +# sync brcm to 0.7.2.1 +Patch0: iscsi-initiator-utils-sync-uio-0.7.2.1.patch +# sync iscsi tools to upstream commit 2e342633db5ac211947ffad1d8da718f6f065d3e +# (iscsi tools: update iscsi_if.h for host event) Patch1: iscsi-initiator-utils-sync-iscsi.patch # Add Red Hat specific info to docs. Patch2: iscsi-initiator-utils-update-initscripts-and-docs.patch @@ -26,35 +28,36 @@ Patch6: iscsi-initiator-utils-uip-mgmt.patch Patch7: iscsi-initiator-utils-dont-use-static.patch # Remove the OFFLOAD_BOOT_SUPPORTED #ifdef. Patch8: iscsi-initiator-utils-remove-the-offload-boot-supported-ifdef.patch -# brcm uio: handle the different iface_rec structures in iscsid and brcm. -Patch9: iscsi-initiator-utils-uio-handle-different-iface_rec.patch -# Document missing brcm arguments -Patch10: iscsi-initiator-utils-brcm-man.patch -# setup default ifaces for all ifaces in kernel -Patch11: iscsi-initiator-utils-fix-default-bindings.patch -# fix iscsiadm return value/msg when login fails -Patch12: iscsi-initiator-utils-fix-iscsiadm-return.patch -# don't use openssl-devel -Patch13: iscsi-initiator-utils-dont-use-openssl.patch -# sync uio to 0.7.0.14 -Patch14: iscsi-initiator-utils-sync-uio-0.7.0.14.patch -# fix nl msglen -Patch15: iscsi-initiator-utils-fix-nlmsglen.patch -# fixes for offload iface support -Patch16: iscsi-initiator-utils-ofl-iface-fixes.patch # fix ipv6 ibft/firmware boot -Patch17: iscsi-initiator-utils-fix-ipv6-boot.patch +Patch9: iscsi-initiator-utils-fix-ipv6-boot.patch +# netconfig libiscsi support +Patch10: iscsi-initiator-utils-Add-Netconfig-support-through-libiscsi.patch +# libiscsi offload support +Patch11: iscsi-initiator-utils-libiscsi-to-support-offload.patch +# sync to upstream commit f9f627fbf0fc96545931ae65aa2b6214841bfd4e to +# add iscsiadm ping and host chap support and fix default iface handling +Patch12: iscsi-initiator-utils-ping-and-chap.patch +# sync to upstream 6676a1cf6f2d23961e9db70155b5d0e5ce511989 +Patch13: iscsi-initiator-utils-mod-iface-andport-fixes.patch +# sync brcm to 0.7.4.3 +Patch14: iscsi-initiator-utils-sync-uio-0.7.4.3.patch +# upstream Changelog, README and version sync for 2.0.873 +Patch15: iscsi-initiator-utils-Prep-for-open-iscsi-2.0.873-release.patch +# upstream 71cd021b74a7094b5186a42bfe59a35e2fa66018 +Patch16: iscsi-initiator-utils-iscsid-fix-iscsid-segfault-during-qla4xxx-login.patch +# upstream f0a8c95426d21413d9980d31740e193208e3280e +Patch17: iscsi-initiator-utils-ISCSISTART-Bring-up-the-corresponding-network-interf.patch +# sync brcm to 0.7.6.1 +Patch18: iscsi-initiator-utils-sync-uio-0.7.6.1.patch # add rhel version info to iscsi tools -Patch18: iscsi-initiator-utils-add-rh-ver.patch - +Patch90: iscsi-initiator-utils-add-rh-ver.patch Group: System Environment/Daemons License: GPLv2+ URL: http://www.open-iscsi.org Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) -BuildRequires: openssl-devel flex bison python-devel doxygen glibc-static -# For dir ownership -Requires: initscripts +BuildRequires: flex bison python-devel doxygen kernel-headers + Requires(post): chkconfig Requires(preun): chkconfig /sbin/service @@ -75,7 +78,7 @@ developing applications that use %{name}. %prep %setup -q -n open-iscsi-2.0-872-rc4-bnx2i -%patch0 -p1 -b .sync-uio-0.7.0.8 +%patch0 -p1 -b .sync-uio-0.7.2.1 %patch1 -p1 -b .sync-iscsi %patch2 -p1 -b .update-initscripts-and-docs %patch3 -p1 -b .use-var-for-config @@ -84,20 +87,21 @@ developing applications that use %{name}. %patch6 -p1 -b .uip-mgmt %patch7 -p1 -b .dont-use-static %patch8 -p1 -b .remove-the-offload-boot-supported-ifdef -%patch9 -p1 -b .uio-handle-different-iface_rec -%patch10 -p1 -b .brcm-man -%patch11 -p1 -b .fix-default-bindings -%patch12 -p1 -b .fix-iscsiadm-return -%patch13 -p1 -b .dont-use-openssl -%patch14 -p1 -b .sync-uio-0.7.0.14 -%patch15 -p1 -b .fix-nlmsglen -%patch16 -p1 -b .ofl-iface-fixes -%patch17 -p1 -b .fix-ipv6-boot -%patch18 -p1 -b .add-rh-ver +%patch9 -p1 -b .fix-ipv6-boot +%patch10 -p1 -b .Add-Netconfig-support-through-libiscsi +%patch11 -p1 -b .libiscsi-to-support-offload +%patch12 -p1 -b .ping-and-chap +%patch13 -p1 -b .mod-iface-andport-fixes +%patch14 -p1 -b .sync-uio-0.7.4.3 +%patch15 -p1 -b .sync-2.0.873 +%patch16 -p1 -b .segfault-qla4xxx-login +%patch17 -p1 -b .boot-netif-up +%patch18 -p1 -b .sync-uio-0.7.6.1 +%patch90 -p1 -b .add-rh-ver %build cd utils/open-isns -./configure --with-security=no +./configure --with-security=no --with-slp=no make OPTFLAGS="%{optflags}" cd ../../ make OPTFLAGS="%{optflags}" -C utils/sysdeps @@ -114,10 +118,8 @@ cd .. pushd libiscsi python setup.py build -touch -r libiscsi.doxy html/* popd - %install rm -rf $RPM_BUILD_ROOT mkdir -p $RPM_BUILD_ROOT/sbin @@ -141,14 +143,14 @@ mkdir -p $RPM_BUILD_ROOT%{python_sitearch} install -p -m 755 usr/iscsid usr/iscsiadm utils/iscsi-iname usr/iscsistart $RPM_BUILD_ROOT/sbin +install -m 755 iscsiuio/src/unix/iscsiuio $RPM_BUILD_ROOT/sbin install -p -m 644 doc/iscsiadm.8 $RPM_BUILD_ROOT/%{_mandir}/man8 install -p -m 644 doc/iscsid.8 $RPM_BUILD_ROOT/%{_mandir}/man8 -install -p -m 644 etc/iscsid.conf $RPM_BUILD_ROOT%{_sysconfdir}/iscsi install -p -m 644 doc/iscsistart.8 $RPM_BUILD_ROOT/%{_mandir}/man8 install -p -m 644 doc/iscsi-iname.8 $RPM_BUILD_ROOT/%{_mandir}/man8 install -p -m 644 iscsiuio/docs/iscsiuio.8 $RPM_BUILD_ROOT/%{_mandir}/man8 install -p -m 644 iscsiuio/iscsiuiolog $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d -install -p -m 755 iscsiuio/src/unix/iscsiuio $RPM_BUILD_ROOT/sbin +install -p -m 644 etc/iscsid.conf $RPM_BUILD_ROOT%{_sysconfdir}/iscsi install -p -m 755 %{SOURCE1} $RPM_BUILD_ROOT%{_initrddir}/iscsid install -p -m 755 %{SOURCE2} $RPM_BUILD_ROOT%{_initrddir}/iscsi @@ -160,9 +162,8 @@ install -p -m 644 libiscsi/libiscsi.h $RPM_BUILD_ROOT%{_includedir} install -p -m 755 libiscsi/build/lib.linux-*/libiscsimodule.so \ $RPM_BUILD_ROOT%{python_sitearch} - -# for %%ghost -touch $RPM_BUILD_ROOT/var/lock/iscsi/lock +#compat support for older tools that are not aware of the name change +ln -s iscsiuio $RPM_BUILD_ROOT/sbin/brcm_iscsiuio %clean @@ -170,6 +171,7 @@ rm -rf $RPM_BUILD_ROOT %post /sbin/ldconfig + if [ "$1" -eq "1" ]; then if [ ! -f %{_sysconfdir}/iscsi/initiatorname.iscsi ]; then echo "InitiatorName=`/sbin/iscsi-iname`" > %{_sysconfdir}/iscsi/initiatorname.iscsi @@ -177,13 +179,6 @@ if [ "$1" -eq "1" ]; then /sbin/chkconfig --add iscsid /sbin/chkconfig --add iscsi fi -# To make sure iscsid autostart works when upgrading from a version which -# did not have this in its config file -if ! grep -q 'iscsid\.startup' %{_sysconfdir}/iscsi/iscsid.conf; then - echo -e "\n\n# For iscsid autostart" \ - "\niscsid.startup = /etc/rc.d/init.d/iscsid force-start" >> \ - %{_sysconfdir}/iscsi/iscsid.conf -fi %postun -p /sbin/ldconfig @@ -202,6 +197,7 @@ fi %files %defattr(-,root,root) %doc README +%dir /etc/iscsi %dir %{_var}/lib/iscsi %dir %{_var}/lib/iscsi/nodes %dir %{_var}/lib/iscsi/isns @@ -209,18 +205,16 @@ fi %dir %{_var}/lib/iscsi/slp %dir %{_var}/lib/iscsi/ifaces %dir %{_var}/lib/iscsi/send_targets -%ghost %{_var}/lock/iscsi -%ghost %{_var}/lock/iscsi/lock +%dir %{_var}/lock/iscsi %{_initrddir}/iscsi %{_initrddir}/iscsid -%{_sysconfdir}/NetworkManager/dispatcher.d/04-iscsi -%dir %{_sysconfdir}/iscsi +%{_sysconfdir}/NetworkManager %attr(0600,root,root) %config(noreplace) %{_sysconfdir}/iscsi/iscsid.conf /sbin/* %{_libdir}/libiscsi.so.0 %{python_sitearch}/libiscsimodule.so %{_mandir}/man8/* -%{_sysconfdir}/logrotate.d/iscsiuiolog +/etc/logrotate.d/iscsiuiolog %files devel %defattr(-,root,root,-) @@ -229,66 +223,176 @@ fi %{_includedir}/libiscsi.h %changelog -* Thu Jul 19 2012 Fedora Release Engineering - 6.2.0.872-19 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild +* Mon Oct 22 2012 Chris Leech - 6.2.0.873-2 +- 868305 sync iscsiuio to 0.7.6.1 -* Mon Feb 14 2012 Mike Christie 6.2.0.872.18 -- 789683 Fix boot slow down when the iscsi service is started - (regression added in 6.2.0.872.16 when the nm wait was added). +* Thu Oct 11 2012 Chris Leech - 6.2.0.873-1 +- Sync with upstream 2.0.873 +- 854776 Bring up network interface for iSCSI boot with bnx2i +- 811428 make version string reported by iscsiadm match RPM version +- fix iscsid segfault during qla4xxx login -* Mon Feb 5 2012 Mike Christie 6.2.0.872.17 -- 786174 Change iscsid/iscsi service startup, so it always starts - when called. +* Wed Oct 10 2012 Chris Leech - 6.2.0.872-42 +- 826300 sync iscsiuio to 0.7.4.3 -* Sat Feb 4 2012 Mike Christie 6.2.0.872.16 -- 747479 Fix iscsidevs handling of network requirement +* Thu Apr 5 2012 Mike Christie 6.2.0.872.41 +- 810197 Coverity fixes. +- 740054 fix iscsiuio version string -* Fri Jan 13 2012 Fedora Release Engineering - 6.2.0.872-15 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild +* Wed Apr 4 2012 Mike Christie 6.2.0.872.40 +- 738192 Fix regression added when handling 738192 where unknown params + messages got logged by mistake. -* Wed Nov 30 2011 Mike Christie 6.2.0.872.14 -- Fix version string to reflect fedora and not rhel. +* Wed Mar 28 2012 Mike Christie 6.2.0.872.39 +- 738192 Fix invalid param handling. +- 790609 Fix --interval iscsiadm handling. -* Tue Oct 18 2011 Mike Christie 6.2.0.872.13 -- Update iscsi tools. +* Thu Mar 22 2012 Mike Christie 6.2.0.872.38 +- Fix regressions caused by 796574 and 805467. -* Sat Apr 30 2011 Hans de Goede - 6.2.0.872-12 -- Change iscsi init scripts to check for networking being actually up, rather - then for NetworkManager being started (#692230) +* Thu Mar 22 2012 Mike Christie 6.2.0.872.37 +- 805467 Have iscsistart/iscsiadm bring up offload net interface. +- 796574 Fix port handling when hostnames are used for portals. +- 739843 Fix default iface setup handling. -* Tue Apr 26 2011 Hans de Goede - 6.2.0.872-11 -- Fix iscsid autostarting when upgrading from an older version - (add iscsid.startup key to iscsid.conf on upgrade) -- Fix printing of [ OK ] when successfully stopping iscsid -- systemd related fixes: - - Add Should-Start/Stop tgtd to iscsi init script to fix (re)boot from - hanging when using locally hosted targets - - %%ghost /var/lock/iscsi and contents (#656605) +* Mon Mar 5 2012 Mike Christie 6.2.0.872.36 +- 740054 sync iscsiuio to 0.7.2.1 +- 790609 Add ping and host chap support to iscsiadm +- 636013 scalability testing. -* Mon Apr 25 2011 Mike Christie 6.2.0.872-10 -- Fix iscsi init scripts check for networking being up (#692230) +* Sun Feb 26 2012 Mike Christie 6.2.0.872.35 +- 738192 Allow iscsistart to take any parameter. +- 739049 Fix -i use in README. -* Wed Feb 09 2011 Fedora Release Engineering - 6.2.0.872-9 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild +* Tue Nov 1 2011 Mike Christie 6.2.0.872.34 +- 750714 Do not build with SLP. -* Wed Jul 21 2010 David Malcolm - 6.2.0.872-8 -- Rebuilt for https://fedoraproject.org/wiki/Features/Python_2.7/MassRebuild +* Tue Nov 1 2011 Mike Christie 6.2.0.872.33 +- 749051 More offload boot fixups. -* Fri Jul 12 2010 Mike Christie 6.2.0.872.7 -- Sync to upstream open-iscsi-2.0-872-rc4 which fixes: - iscsiadm discovery port handling, add discoveryd init script - support, move from iscsid.conf to discovery db discoveryd settings, - and add discoverydb mode support. +* Tue Oct 25 2011 Mike Christie 6.2.0.872.31 +- 749051 Sync iscsiuio to iscsiuio-0.7.0.14g to fix boot hang + when connection is lost during startup. -* Thu Jun 10 2010 Mike Christie 6.2.0.872.6 -- Fix last patch. +* Tue Oct 18 2011 Mike Christie 6.2.0.872.30 +- 602959 rotate iscsiuio/brcm_iscsiuio log. -* Wed Jun 9 2010 Mike Christie 6.2.0.872.5 -- Fix iscsiadm handling of port argument when it is not the default 3260. +* Tue Oct 11 2011 Mike Christie 6.2.0.872.28 +- 736116 (again) fix aligment for iface nl msgs. +- Fix iscsid restart issue when using qla4xxx boot. +- Fix ipv6 boot when using ibft. -* Thu May 6 2010 Mike Christie 6.2.0.872.4 -- Fix iscsi script operations to check for offload drivers in rh_status -- Fix iscsiadm logging to not trigger iscsi script error detection +* Thu Sep 20 2011 Mike Christie 6.2.0.872.27 +- 736116 Fix netlink msg len + +* Thu Sep 8 2011 Mike Christie 6.2.0.872.26 +- Fix offload removal patch + +* Thu Sep 1 2011 Mike Christie 6.2.0.872.25 +- 732912 Fix return value/msg when iscsiadm fails to log into target +- 696808 Update iscsiuio to v0.7.0.14. + +* Sun Aug 14 2011 Mike Christie 6.2.0.872.24 +- 696808 Fix brcm_iscsiuio naming from change in 696808 + +* Sun Aug 14 2011 Mike Christie 6.2.0.872.23 +- 696808 Sync brcm/uio to v0.7.0.8. +- 715434 Fix iscsiadm command line help discoverydb/discovery2 description. + +* Tue Apr 19 2011 Mike Christie 6.2.0.872.21 +- 593269 iscsi was built against libcrypto, but was not using the code +so this disabled the building of that code [patch from .14 got dropped +due to mismerge]. + +* Mon Apr 18 2011 Mike Christie 6.2.0.872.20 +- 696267 Create a offloaded session if the iscsi_host MAC and ibft +MAC match. This enables support for Broadcoms hba boot mode. + +* Tue Apr 5 2011 Mike Christie 6.2.0.872.19 +- 624437 support hostnames in node mode. [patch merged in .14 got + dropped by accident] + +* Thu Feb 24 2011 Mike Christie 6.2.0.872.18 +- fix iscsiadm exit code when iscsid is not running and the +discovery command is run. +- 689359 Fix uIP when using DCB for FCoE +- 691902 Fix iscsiadm SendTargets offload support when the PDU's data len +is 8K. + +* Sat Feb 19 2011 Mike Christie 6.2.0.872.17 +- 634021 Fix in .14 added regression during iscsi startup that prevented +sessions from getting created. + +* Wed Feb 9 2011 Ales Kozumplik 6.2.0.872.16 +- 529443 fwparam_sysfs: fix pathname manipulation error in + fwparam_sysfs_boot_info. +- 529443 Make libiscsi nodes remember the interface they connect through. + +* Thu Feb 3 2011 Mike Christie 6.2.0.872.15 +- 640340 fix iscsiadm exit codes. +- 523492 iSCSI DCB support + +* Mon Jan 31 2011 Mike Christie 6.2.0.872.14 +- 593269 iscsi was built against libcrypto, but was not using the code +so this disabled the building of that code. +- 599539 document brcm_iscsiuio options in man page. +- 599542 document iscsiadm host mode hostno argument. +- 631821 iscsi discovery was not incrementing ITT when multiple text +commands were sent. This prevented discovery from finding all targets. +- 634021 iscsi init script did not shutdown all sessions during system +shutdown/reboot causing the host to hang. +- 658428 iscsi init script should not shutdown sessions when root is +using them and should not fail startup on all iscsiadm login failures. +- 635899 sync brcm_iscsiuio to 0.6.2.13 to add support for IPv6, VLAN, +57711E, and 57712 hardware. +- 640115 fix hang caused due to race in ISCSI_ERR_INVALID_HOST handling. +- 640340 fix iscsiadm exit codes. +- 624437 support hostnames in node mode. + +* Fri Dec 3 2010 Ales Kozumplik 6.2.0.872.13 +- 442980 libiscsi: reimplement fw discovery so partial devices are used properly. + +* Tue Nov 30 2010 Ales Kozumplik 6.2.0.872.12 +- 442980 partial offload boot: Remove the OFFLOAD_BOOT_SUPPORTED ifdef. This + effectively makes OFFLOAD_BOOT_SUPPORTED always enabled. + +* Mon Nov 29 2010 Ales Kozumplik 6.2.0.872.11 +- 442980 brcm uio: handle the different iface_rec structures in iscsid and brcm. + +* Wed Aug 18 2010 Mike Christie 6.2.0.872.10 +- 605663 Log message when iface binding, and doc rp_filter settings + needed for iface binding. + +p* Mon Aug 5 2010 Mike Christie 6.2.0.872.9 +- 614035 Make iscsi status print session info. +- Fix uip vlan and 10 gig bugs. + +* Mon Jul 26 2010 Mike Christie 6.2.0.872.8 +- 589256 Re-fix iface update/delete return value. + +* Mon Jul 12 2010 Mike Christie 6.2.0.872.7 +- 595591 Fix nic state bug in brcm_iscsiuio. + +* Thu Jul 8 2010 Mike Christie 6.2.0.872.6 +- 602899 Add discovery db support. +- 595591 Sync brcm_iscsiuio to 0.5.15. +- 589256 Do not log success message and return ENODEV +- 601434 Fix iscsiadm handling of non-default port + +* Fri Jun 18 2010 Mike Christie 6.2.0.872.5 +- 602286 No need to compile iscsistart as static. This also fixes + the segfault when hostnames are passed in for the portal ip. + +* Tue May 18 2010 Mike Christie 6.2.0.872.4 +- 590580 libiscsi get_firmware_foo does not work without first creating a + libiscsi context +- 588931 Fix uip and iscsid initialization race +- 570664 Add basic vlan support for bnx2i's brcm uip daemon +- 589761 Fix multiple init script bugs: rh_status does not detect offload, + start/stop does not work due to iscsiadm output being directed to stderr, + discovery daemon does not get auto started/stopped, iscsid restart does + not restart daemon if force-start was used. +- 585649 Fix iscsid "-eq: unary operator expected" bug. * Wed May 5 2010 Mike Christie 6.2.0.872.3 - 578455 Fix initial R2T=0 handling for be2iscsi @@ -303,10 +407,6 @@ fi - 516444 Add iSNS SCN handling (rebased to open-iscsi-2.0-872-rc1-) - Update brcm to 0.5.7 -* Sun Feb 14 2010 Hans de Goede 6.2.0.870-13 -- Preserve timestamps on doxygen generated files -- Fix FTBFS (#565038) - * Mon Feb 8 2010 Mike Christie 6.2.0.871.1.1-3 - Add spec patch comments. @@ -320,15 +420,6 @@ fi - 529324 Add iscsi-iname and iscsistart man page - 463582 OF/iBFT support -* Thu Jan 7 2010 Hans de Goede 6.2.0.870-12 -- Change python_sitelib macro to use %%global as the new rpm will break - using %%define here, see: - https://www.redhat.com/archives/fedora-devel-list/2010-January/msg00093.html - -* Tue Dec 1 2009 Hans de Goede 6.2.0.870-11 -- Own /etc/iscsi (#542849) -- Do not own /etc/NetworkManager/dispatcher.d (#533700) - * Fri Jul 24 2009 Fedora Release Engineering - 6.2.0.870-10.1 - Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild diff --git a/iscsid.init b/iscsid.init index 92912f2..c208ccc 100755 --- a/iscsid.init +++ b/iscsid.init @@ -74,8 +74,15 @@ start() { [ -x $exec ] || exit 5 [ -f $config ] || exit 6 - start_iscsid - return $? + # only start if nodes are setup to startup automatically, root is iscsi, + # or if iscsid is managing the sessions. + grep -qrs "node.startup = automatic" /var/lib/iscsi/nodes + if [ $? -eq 0 ] || root_is_iscsi || use_discoveryd ; then + start_iscsid + return $? + fi + + return 0 } stop() { diff --git a/iscsidevs.init b/iscsidevs.init index 60498c4..ebb0b8b 100755 --- a/iscsidevs.init +++ b/iscsidevs.init @@ -5,12 +5,17 @@ # chkconfig: 345 13 89 # description: Logs into iSCSI targets needed at system startup +# Note we should have $network in Required-Start/Stop but we don't because if +# we would require network chkconfig will put us directly after NetworkManager +# when using NM, which will make our see if the network is up test succeed +# while NM is actually still configuring the network. By not requiring network +# chkconfig will use the chkconfig header to determine our start prio, starting +# us after the old network service, but before NM (netfs does this the same). + ### BEGIN INIT INFO # Provides: iscsi -# Required-Start: iscsid network -# Should-Start: tgtd +# Required-Start: iscsid # Required-Stop: iscsid -# Should-Stop: tgtd # Default-Start: 3 4 5 # Default-Stop: 0 1 2 6 # Short-Description: Starts and stops login and scanning of iSCSI devices. @@ -34,7 +39,11 @@ start() { # if the network isn't up yet exit cleanly, NetworkManager will call us # again when the network is up - [ ! -f /var/lock/subsys/network ] && ! nm-online -x >/dev/null 2>&1 && exit 3 + [ ! -f /var/lock/subsys/network -a ! -f /var/lock/subsys/NetworkManager ] && exit 0 + + # if no nodes are setup to startup automatically exit cleanly + grep -qrs "node.startup = automatic" /var/lib/iscsi/nodes + [ $? -eq 0 ] || exit 0 # this script is normally called from startup so log into # nodes marked node.startup=automatic