[Pkg-ofed-commits] [opensm] 01/06: New upstream version 3.3.20

Ana Beatriz Guerrero López ana at moszumanska.debian.org
Wed Sep 7 21:31:47 UTC 2016


This is an automated email from the git hooks/post-receive script.

ana pushed a commit to branch master
in repository opensm.

commit a84d4ec69a06b52d83d89734b87f30c712a210be
Author: Ana Beatriz Guerrero Lopez <ana at debian.org>
Date:   Wed Sep 7 23:10:55 2016 +0200

    New upstream version 3.3.20
---
 ChangeLog                           | 612 ++++++++++++++++++++++++++++++++++++
 complib/libosmcomp.ver              |   2 +-
 configure                           |  20 +-
 configure.in                        |   2 +-
 doc/QoS_management_in_OpenSM.txt    |   6 +-
 doc/current-routing.txt             |   4 +-
 doc/opensm_release_notes-3.3.txt    | 142 ++++++++-
 doc/partition-config.txt            |   6 +-
 include/iba/ib_types.h              |  70 ++---
 include/opensm/osm_base.h           |   3 +-
 include/opensm/osm_node.h           |   2 +-
 include/opensm/osm_opensm.h         |   8 +
 include/opensm/osm_pkey.h           |  54 +++-
 include/opensm/osm_port.h           |  86 +++++
 include/opensm/osm_sa.h             |  12 +
 include/opensm/osm_sa_mad_ctrl.h    |  14 +-
 include/opensm/osm_subnet.h         |  26 +-
 include/opensm/osm_switch.h         |  34 +-
 include/opensm/osm_version.h        |   2 +-
 libvendor/libosmvendor.ver          |   2 +-
 libvendor/osm_vendor_ibumad_sa.c    |  15 +-
 man/opensm.8                        |  12 +-
 man/opensm.8.in                     |  12 +-
 man/osmtest.8                       |   4 +-
 opensm.spec                         |   6 +-
 opensm/libopensm.ver                |   2 +-
 opensm/main.c                       |   2 +-
 opensm/osm_congestion_control.c     |  13 +-
 opensm/osm_console.c                |  52 +--
 opensm/osm_drop_mgr.c               |  25 +-
 opensm/osm_dump.c                   |  12 +-
 opensm/osm_helper.c                 |  63 ++--
 opensm/osm_inform.c                 |  79 ++---
 opensm/osm_mcast_mgr.c              |   5 +-
 opensm/osm_mcast_tbl.c              |   3 +-
 opensm/osm_multicast.c              |  11 +-
 opensm/osm_node.c                   |   5 +-
 opensm/osm_node_info_rcv.c          |  60 +++-
 opensm/osm_opensm.c                 |  29 +-
 opensm/osm_pkey.c                   |  11 +
 opensm/osm_pkey_mgr.c               | 125 ++++++--
 opensm/osm_port.c                   |   5 +-
 opensm/osm_port_info_rcv.c          | 160 +++++-----
 opensm/osm_prtn.c                   |  23 +-
 opensm/osm_prtn_config.c            |  77 ++++-
 opensm/osm_qos.c                    |  24 +-
 opensm/osm_req.c                    |  14 +-
 opensm/osm_sa.c                     |  54 +++-
 opensm/osm_sa_guidinfo_record.c     |   2 +-
 opensm/osm_sa_mad_ctrl.c            |  61 +++-
 opensm/osm_sa_mcmember_record.c     | 236 +++++++++++---
 opensm/osm_sa_path_record.c         |  58 +++-
 opensm/osm_service.c                |   2 +-
 opensm/osm_sm_mad_ctrl.c            |   2 +-
 opensm/osm_state_mgr.c              | 152 +++++++--
 opensm/osm_subnet.c                 |  56 +++-
 opensm/osm_switch.c                 |  14 +-
 opensm/osm_ucast_cache.c            |   9 +-
 opensm/osm_ucast_dfsssp.c           |  89 +++++-
 opensm/osm_ucast_file.c             |   2 +-
 opensm/osm_ucast_ftree.c            | 406 +++++++++++++-----------
 opensm/osm_ucast_lash.c             |   4 +-
 opensm/osm_ucast_mgr.c              |  16 +-
 osmeventplugin/src/osmeventplugin.c |   8 +-
 osmtest/osmt_multicast.c            |  13 +-
 osmtest/osmt_service.c              |  35 ++-
 66 files changed, 2448 insertions(+), 727 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index cf775b3..986ebd4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,616 @@
 
+** Version: HEAD
+
+Thu Jun 9 19:10:28 2016 +0300 Hal Rosenstock
+9bf9def273a832780e36c4ff448e515847795b3e
+
+	* Update opensm_release_notes-3.3.txt
+
+Thu Jun 9 18:21:12 2016 +0300 Hal Rosenstock
+ed5b8fe0080a6e88675b474500ea6b7fd33a6bff
+
+	* Update package number for OpenSM to 3.3.20 for release
+
+Thu Jun 9 18:19:23 2016 +0300 Hal Rosenstock
+da90f1cfa0c2925fba398b824ab0e199e8324470
+
+	* Update (internal) shared library versions
+
+Tue Jun 7 12:08:35 2016 +0300 Daniel Klein
+bb15d2f4af15fdfe6289284e9243aec82fec2967
+
+	* osm_service.c: Fix missing endian conversion in log message
+
+Tue May 24 13:27:44 2016 +0300 Shlomi Nimrodi
+c0e81418cddb44f1332cb018ddae2eee418fd6a2
+
+	* Fix various coverity issues
+
+Wed Sep 19 15:42:26 2012 +0300 Alex Netes
+a0d915733f5cbbde8082fe8f0aeafd9dec928605
+
+	* osm_subnet.c: Add guid_routing_order_no_scatter option to opensm.conf
+
+Mon May 23 12:49:37 2016 +0300 Hal Rosenstock
+5d521c14c14f4889c4280f99f49614c75561040f
+
+	* osm_state_mgr.c: Update comment in state_mgr_check_tbl_consistency
+
+Thu May 19 18:17:33 2016 +0300 Shlomi Nimrodi
+62ea61a15e1b90ce8b8bc864791275edb1527d42
+
+	* osm_state_mgr.c: Fix bug in handling of PortInfo Set timeout
+
+Sun May 1 13:14:10 2016 +0300 Shlomi Nimrodi
+ccefa3d737d2f50918ba54504ead52d02740e06a
+
+	* osm_sm_mad_ctrl.c: Add ':' to "ERR 3120" error message
+
+Tue Nov 24 16:56:12 2015 +0200 Shlomi Nimrodi
+fbe51070dee095ee10c588526fc763275640ded7
+
+	* osm_subnet.c: Add support for Switch-IB2 in is_mlnx_ext_port_info_supported
+
+Tue Mar 1 20:46:35 2016 +0200 Hal Rosenstock
+dc45fca09b86fe365e58df787b050a8d83e6bcf9
+
+	* ib_types.h: Comment change to indicate 1.3.1 rather than 1.2 IBA spec
+
+Tue Mar 1 20:45:22 2016 +0200 Hal Rosenstock
+37e1246eb05b9371419ad84a2aa1006653daaf7b
+
+	* ib_types.h: Cosmetic formatting changes
+
+Mon Dec 28 13:34:10 2015 +0200 Vladimir Koushnir
+6eb8b964f1a2563b20e750b2253eff2a9881f709
+
+	* ftree: Additional ftree indexing algorithm
+
+Fri Feb 26 12:05:21 2016 +0200 Hal Rosenstock
+73fd8ee8df2c82910b8ca0c11bd1d92dd46ff73b
+
+	* man/opensm.8.in: Fix typo (missing close parenthesis)
+
+Fri Feb 26 11:59:38 2016 +0200 Hal Rosenstock
+c32b8139a154626722d9b18bfaadf53502fe3d74
+
+	* doc/current-routing.txt: Fix typo
+
+Wed Feb 24 14:55:48 2016 +0200 Hal Rosenstock
+c4691e795e892c9b427dadb335445373d10973fa
+
+	* ib_types.h: Cosmetic commentary fix
+
+Thu Feb 11 16:48:47 2016 +0200 Shlomi Nimrodi
+85e2214dd8005fbd2225c5ea5fbe6795b6e94823
+
+	* osm_sa_mcmember_record.c: Prevent log errors swamp in MC query scenario
+
+Mon Jan 11 14:00:43 2016 +0200 Tomer Cohen
+34e81dffaa1ce1b909733432a8c013f539cf4245
+
+	* Change precedence in pkey manager with indx0 feature
+
+Tue Mar 24 10:34:11 2015 +0200 Shlomi Nimrodi
+aa905e299715c79d3bce38c7f3cf7a0b3b76d294
+
+	* osm_pkey.[h c], osm_prtn.c: Create method to set pkey at indx0
+
+Wed Jan 13 10:44:12 2016 +0200 Shlomi Nimrodi
+8a696eb25930d6414dbe9eb6003c6875463dd2a1
+
+	* osm_base.h: Fix OSM_CAP2_IS_PORT_INFO_CAPMASK2_MATCH_SUPPORTED definition
+
+Tue Dec 18 13:43:28 2012 +0200 Hal Rosenstock
+70a364f7c4da48328ccd3ceda48c9dd7dde31353
+
+	* opensm/osm_pkey_mgr.c: Fix pkey index wraparound/reuse
+
+Tue Sep 9 15:28:09 2014 +0300 Tomer Cohen
+c1f7ffd24c762fa30f802d7ba5626e8fc80fa674
+
+	* Support configuration for index 0 in pkey table
+
+Fri Nov 20 17:56:22 2015 +0200 Hal Rosenstock
+88626f4bb4b4f6a4444ae8b44393fbc18b0abbcd
+
+	* osm_sa_mcmember_record.c: Updated Mellanox copyright years
+
+Fri Nov 20 17:54:55 2015 +0200 Hal Rosenstock
+432727b8a0e7d73a966e0d573e4fed079ae5f311
+
+	* osm_sa_mcmember_record.c: Cosmetic formatting change to mcmr_rcv_create_new_mgrp
+
+Fri Nov 20 17:47:12 2015 +0200 Hal Rosenstock
+b85c31e230b831d4411cc2f875c017e01f32db69
+
+	* osm_prtn_config.c: Cosmetic formatting changes in manage_membership_change
+
+Fri Nov 20 17:43:26 2015 +0200 Hal Rosenstock
+1a2a6d762dc25948be2efc9715b18e048ef58d76
+
+	* osm_prtn_config.c: Updated Mellanox copyright years
+
+Fri Nov 20 17:30:05 2015 +0200 Hal Rosenstock
+8b288b88501468a5dcbf13561967d4dd70f94601
+
+	* osm_mcast_mgr.c: Cosmetic formatting change in create_mgrp_switch_map
+
+Sun Nov 1 16:50:56 2015 +0200 Rafi Wiener
+4772806964efe9cc2e6934ab29f6a4bb28305ed3
+
+	* osm_state_mgr.c: Fix uninitialized area of SMInfo SET mad
+
+Mon Jul 27 22:08:32 2015 +0300 Daniel Klein
+6e27bbabbdcb7b74e37b77ff650c51b25b9aa409
+
+	* osm_multicast.c: Dump sa after deleting well known mc group
+
+Tue Sep 3 15:17:20 2013 +0300 Daniel Klein
+df212a6e197401943a740701bc58c50efa44b5f9
+
+	* osm_multicast.c: Fix not dumping empty predefined mc groups
+
+Wed Nov 4 17:07:45 2015 +0200 Hal Rosenstock
+175de416b6c4c00779c00ca8fbcbe21fa5610e7f
+
+	* osm_prtn.c: Cosmetic formatting change
+
+Mon Nov 2 10:13:47 2015 +0200 Daniel Klein
+1007810297d7f115a5d72dd095937246a415b0bd
+
+	* osm_sa_guidinfo_record.c: Fix memory leak in set_guidinfo
+
+Thu Oct 1 18:07:59 2015 +0300 Hal Rosenstock
+1b73efd8176e9d3ee6c7c0ab79d86695642a9f5e
+
+	* osm_sa_mcmember_record.c: Conditionalize multicast join parameter validation on new mcgroup_join_validation option
+
+Wed Sep 30 14:25:15 2015 +0300 Hal Rosenstock
+4cd7ec3c6617b944ef5d23ec0a07eaf00728825c
+
+	* osm_sa_mcmember_record.c: Validate IPoIB non broadcast group parameters on group creation
+
+Thu Oct 15 16:55:22 2015 +0300 Hal Rosenstock
+6272a56ca5c7db89a299e8b68380fe3d7f2a85ae
+
+	* osm_ucast_dfsssp.c: In dfsssp_do_mcast_routing, update adj_list first
+
+Thu Oct 15 16:48:38 2015 +0300 Hal Rosenstock
+870b21a8ae67e24d957151f7298f737e9b8c9bc4
+
+	* osm_ucast_dfsssp.c: Fix some commentary typos
+
+Tue Oct 13 15:25:50 2015 +0200 Jens Domke
+44b4edcb336d90dfef352cdfd63f417ccfff2324
+
+	* osm_ucast_mgr.c: LFT update breaks if IB_SMP_DATA_SIZE changes
+
+Tue Oct 13 17:19:06 2015 +0300 Hal Rosenstock
+d5c51e9c0c2be63ccc47b3dffa2b046f00ca5561
+
+	* osm_ucast_mgr.c: Cosmetic formatting change
+
+Thu Oct 1 10:33:23 2015 +0200 Daniel Klein
+f234d8300b88113b5e54d9abe27a4a6a35fc96a8
+
+	* osm_inform.c: Cosmetic code refactoring in match_inf_rec
+
+Thu Oct 1 20:08:51 2015 +0300 Hal Rosenstock
+fdd1a68d3364082d7c7fc34634df463cedffc2e6
+
+	* Updated some Mellanox copyrights
+
+Thu Oct 1 22:55:11 2015 +0300 Hal Rosenstock
+ecf07ebe7b525a8faefc4fdd6eb61ef950d61d24
+
+	* Set Type field in Notice attribute using IB_NOTICE_TYPE_SUBN_MGMT define
+
+Thu Oct 1 20:04:34 2015 +0300 Hal Rosenstock
+022e6af863cc558b9ef9b9d8cda14f217404788e
+
+	* Use SM trap defines from ib_types.h rather than hard coded values
+
+Thu Oct 1 20:00:01 2015 +0300 Hal Rosenstock
+d111a2c1553e1ae175493cef57a0eaba301b2f46
+
+	* ib_types.h: Cosmetic formatting change
+
+Thu Oct 1 18:19:00 2015 +0300 Hal Rosenstock
+1cbea4b653018e5e3d7059a8681232e0f4aa7dd0
+
+	* osmtest/osmt_multicast.c: Cosmetic changes
+
+Fri Oct 2 17:10:59 2015 +0300 Hal Rosenstock
+c52a1b2ff9f38e944cc5265581c0a6b96e765e3c
+
+	* osm_drop_mgr.c: Eliminated redundant check for switch node type
+
+Mon Oct 5 19:59:58 2015 +0200 Jens Domke
+2c4771ff8eeb4c10df5550d1f992d47a2b5baffa
+
+	* osm_ucast_dfsssp.c: Minor change to setting dropped when switch exists
+
+Thu Oct 1 17:24:59 2015 +0200 Jens Domke
+19dbb679d80d5997363ded11cc59576f19605d84
+
+	* osm_ucast_dfsssp.c: Fix dangling pointer when dfsssp used with ucast cache
+
+Thu Oct 1 16:08:22 2015 +0200 Jens Domke
+e94fc29c515d3d00ceb4d9dea97a147407ce2416
+
+	* osm_subnet.[h c]: Fix wrong function documentation and parameter list
+
+Thu Sep 10 22:36:11 2015 +0300 Hal Rosenstock
+76bd8cd45ab58a66da9dae83a7e5d09b1aedaff8
+
+	* osm_sa_mcmember_record.c: Add error logging for mismatches to validate_other_comp_fields
+
+Wed Sep 9 20:04:51 2015 +0300 Hal Rosenstock
+122cad3ccf8e3bc84a5da80527bf9f5c30a82f18
+
+	* osm_sa_mcmember_record.c: When joining MC group and MC group already exists, validate other components if supplied
+
+Wed Sep 23 17:20:41 2015 +0300 Hal Rosenstock
+098259eafa55e8b05054342204f6f93c8c3eb3d1
+
+	* Updated Mellanox copyrights in some recently changed files
+
+Sun Feb 3 16:46:03 2013 +0200 Alex Netes
+909976db07885439c77d9a353601048d8d3b58bc
+
+	* Add more checks for physp validity
+
+Sun Feb 3 16:46:03 2013 +0200 Alex Netes
+b37560b1519511ff91cfb322f906becec5df39b4
+
+	* osm_mcast_mgr.c: Add check for physp validity to create_mgrp_switch_map
+
+Thu Sep 10 21:45:18 2015 +0300 Hal Rosenstock
+1f3dcb4434cdca002f80263eb8fdd9d49d31da8d
+
+	* osm_ucast_ftree.c: Cosmetic formatting changes in fabric_construct_hca_ports
+
+Wed Sep 9 13:52:28 2015 +0300 Hal Rosenstock
+e92cfe5650a69b4932f3c25875d50ad342dba813
+
+	* iba/ib_types.h: Fix commentary typo
+
+Tue Sep 8 16:36:03 2015 +0300 Hal Rosenstock
+5109f44c5a8d34d3b084e76c3f299b6900c6a2a7
+
+	* osm_ucast_ftree.c: Cosmetic formatting change
+
+Tue Sep 8 16:27:20 2015 +0300 Hal Rosenstock
+0bc858e6f9cff0c102da7f186125bcc165ac0ea5
+
+	* osm_ucast_ftree.c: Cosmetic variable name changes in ftree_port_group_t struct
+
+Tue Sep 1 16:20:33 2015 +0300 Daniel Klein
+08e8a9aa4be53ace4d91f59c460ca7cf5f85e7dc
+
+	* osm_sa_path_record.c: Refactored PR [D/S] GID and LID validation
+
+Thu Sep 3 13:13:21 2015 +0300 Vladimir Koushnir
+e4e449e67c02a26b4941cb5024a986aea495d433
+
+	* osm_ucast_ftree.c: Fix wrong is_io assignment to the second HCA port
+
+Wed Sep 2 16:34:59 2015 +0300 Vladimir Koushnir
+e9bbf4434f2b0adc71e11588841c86e9681a3101
+
+	* osm_ucast_ftree.c: Fix wrong handling of dual port HCA
+
+Sun Aug 30 11:23:22 2015 +0300 Vladimir Koushnir
+ccab3b83f463cde7e9a538a2ba6e5dfb01ad6977
+
+	* osm_ucast_ftree.c: ftree calculates wrong number of compute nodes per leaf
+
+Thu Sep 3 15:32:31 2015 +0300 Hal Rosenstock
+7777987fe792d4a40c8c12c97d42a9aa4759543c
+
+	* osm_sa_path_record.c: Cosmetic formatting change
+
+Thu Aug 20 18:34:00 2015 +0300 Shlomi Nimrodi
+a7ac5fc190fa2fd1386cd23ebac2087a2a8c550d
+
+	* osm_prtn_config.c: Handle valgrind warning in osm_prtn_config_parse_file
+
+Mon Aug 31 23:28:49 2015 +0300 Hal Rosenstock
+609b7775f1e3040edb3b8240f32d3b89de8e0f63
+
+	* osm_ucast_ftree.c: Cosmetic formatting change
+
+Mon Aug 17 19:19:05 2015 +0300 Daniel Klein
+06ae3ad6cb2d4839453a39e751f054bd3e3108d3
+
+	* osm_sa.c: Fix osm_db_file_dump
+
+Sun Jul 26 11:18:45 2015 +0300 Tomer Cohen
+f1ab545af5965a8894a6a1c2a41fea99869645aa
+
+	* osm_drop_mgr.c: Do not set SM port discovery count to 0 when switch remote port is nonresponsive
+
+Wed Aug 26 18:41:14 2015 +0300 Vladimir Koushnir
+cd12dcdda09ef10ba8f79ed96ef8cc6d5e344cce
+
+	* osm_port_info_rcv.c: Fix calculation of minimum data VLs
+
+Sun Jun 14 11:33:42 2015 +0300 Daniel Klein
+cb20b11e7ca3c3fd6ff7d5e6b6f452ee99d4b9b4
+
+	* osm_ucast_ftree.c: Fail routing if max rank is 0 and more than one root
+
+Sun Jun 14 11:04:59 2015 +0300 Daniel Klein
+d9a601b044188d3194ee7ac74306bf802243cbad
+
+	* osm_ucast_ftree.c: Remove no longer needed code in remove_depended_hca
+
+Thu Jun 11 14:47:01 2015 +0300 Daniel Klein
+c633e05067018a2ac35c557f78039afbb9177bdf
+
+	* osm_ucast_ftree.c: Mark HCA ports connected to unranked switches
+
+Sun Aug 16 16:09:06 2015 +0300 Rafi Wiener
+f004819d8ff7b77f9e8317ce69a79aa235c82d3c
+
+	* osm_sa.c: Fix race condition when writing SA DB file
+
+Mon Aug 17 17:11:28 2015 +0300 Hal Rosenstock
+1f6cd87e948a9f6027618a235cec5ceb9947a5ce
+
+	* osm_state_mgr.c: Cosmetic formatting changes
+
+Wed Jun 24 17:59:57 2015 +0300 Vladimir Koushnir
+a64de2e4ed6c53e004f3e7bc7c74b0c8dc799e22
+
+	* osm_prtn_config.c: Fix wrong pkey table calculation in allow_both_pkeys mode
+
+Mon Jun 22 14:03:35 2015 +0300 Daniel Klein
+0b6d8ea015b7ef506105ae996e5ca1d2124ce997
+
+	* osm_sa_mcmember_record.c: Validate port's neighbor_mtu when joining MC group
+
+Thu Aug 6 17:37:48 2015 +0300 Hal Rosenstock
+7f2f902543086baeb72f504fcfcb9ec551856532
+
+	* libvendor/osm_vendor_ibumad_sa.c: Cosmetic formatting change to ERR 5501 log message
+
+Thu Aug 6 17:31:56 2015 +0300 Hal Rosenstock
+80ca401092da7f6ae6edc72fd5289f85451d723e
+
+	* osm_sa_path_record.c: When both [D S] GID and LID are supplied, validate that underlying ports are the same
+
+Thu Aug 6 15:13:10 2015 +0300 Hal Rosenstock
+1fa8089fdad0932cef9b11f24327f9914440dbfb
+
+	* osm_sa_path_record.c: Handle path query by DGID and SLID
+
+Mon Aug 3 22:36:24 2015 +0300 Hal Rosenstock
+e527ec68f229ce1753ea39208dd13e4e1ccc3684
+
+	* libvendor/osm_vendor_ibumad_sa.c: Cosmetic formatting changes to osmv_query_sa
+
+Thu Jun 25 17:48:39 2015 +0300 Daniel Klein
+141293d07872d2f9214621dd3f3d42bf85a9afde
+
+	* osmtest/osmt_multicast.c: Fix MC join with unrealistic rate test
+
+Thu Jul 9 18:34:16 2015 +0300 Shlomi Nimrodi
+ec2e2bf56ed4832e00ecc030d4462e0dd9c3c232
+
+	* osm_pkey.h: Fix osm_physp_has_pkey method description
+
+Wed Jul 8 10:29:21 2015 +0300 Vladimir Koushnir
+fd754d25d60eed63bbd2811b5dece3f6a6423985
+
+	* Support another new MLNX OUI
+
+Sun Jul 5 14:49:34 2015 +0300 Vladimir Koushnir
+f4715713eebaf7ece5f9305d5eba50a9d488272e
+
+	* osm_subnet.c: Remove support for changing allow_both_pkeys on the fly
+
+Sun May 17 11:46:03 2015 +0300 Daniel Klein
+cd31ff6275f4d1212757bf6228c031b346db72b8
+
+	* osm_port_info_rcv.c: Sending MEPI(Get) to local switch ports on hop 0
+
+Sun Jun 21 17:46:46 2015 +0300 Daniel Klein
+4c3d782a82fc1c7dd3bbe0c8add503a0585fa666
+
+	* osm_state_mgr.c: Mark port as undiscovered when removed by drop_mgr
+
+Wed Jun 24 13:58:04 2015 +0300 Shlomi Nimrodi
+bf3818b8d1a6fb662100ee55afbb28f2862156c1
+
+	* partition_config.txt: Small correction in doc file
+
+Thu Jun 4 16:16:00 2015 +0200 Vangelis Tasoulas
+9fa761cc637558dd6ee1d345198079cca759dfef
+
+	* osm_ucast_ftree.c: Removed *p_ftree parameter from sw_destroy function
+
+Thu Jun 4 14:12:51 2015 +0200 Vangelis Tasoulas
+652b0633f347dadd856b259941745c6549e09eff
+
+	* osm_ucast_ftree.c: Removed *p_ftree parameter from sw_create function
+
+Mon May 11 10:36:46 2015 +0300 Daniel Klein
+953b70d4febe6cd87a6fe34a2d7c1320de9ba99f
+
+	* osm_opensm.c: Fix race condition between traps handling and SA shutdown
+
+Tue May 26 14:38:21 2015 +0300 Daniel Klein
+a1c4bc253770cb25d65a1388f4e1ecb3be28304c
+
+	* osm_console.c: Fix display of negative counters in console
+
+Sun Aug 19 18:39:44 2012 +0300 Alex Netes
+a6c2bf83af5822b0f455d01fa58b2f46e52a09b9
+
+	* Add cleanup of SA cache after handover
+
+Mon Jan 28 13:53:38 2013 +0200 Ilya Nelkenbaum
+075ff44d89c0066df44d8e6f163054f00e55fdbd
+
+	* osm_mcast_tbl.c: Wrong assert placement in osm_mcast_tbl_get_block
+
+Mon Apr 13 18:52:35 2015 +0300 Hal Rosenstock
+d504e7634512ea8f2a49b1be6b61d4389bce3596
+
+	* doc/QoS_management_in_OpenSM.txt: Cosmetic changes
+
+Fri Mar 27 10:00:52 2015 +0100 Jens Domke
+a28d63ee74bc7390c0dc3bde165946f96e9249de
+
+	* Fix documentation on ignore-guids command line option
+
+Sat Mar 21 15:18:31 2015 +0200 Hal Rosenstock
+df326446b93657db68652ecf54ce6e62f47c866b
+
+	* osm_subnet.c: Minor clarification to SwitchCongestionSetting Control Map description in generated option file
+
+Wed Mar 18 14:14:23 2015 +0200 Hal Rosenstock
+483ff006a87d66c8b4f73e6684b3844dd05a4cff
+
+	* man/osmtest.8: Minor tweaks to inventory option description
+
+Tue Feb 10 19:06:32 2015 +0200 Daniel Klein
+5e50a3c4e7fcdbf205a0d444d378b5304511aea0
+
+	* osm_sa_mcmember_record.c: Extend P_Pkey validation on MCMemberRecord(Join)
+
+Fri Mar 13 14:30:13 2015 +0200 Hal Rosenstock
+8d3c6f85347a7ffc6627c0205033983124ff75f7
+
+	* osm_sa_mcmember_record.c: Change to log messages for PKey consistency
+
+Mon Mar 2 22:01:13 2015 +0200 Hal Rosenstock
+3fcb121dde4b4b9c5c5e00da6cbaa7cee593bbd4
+
+	* osm_subnet.c: Improved m_key_lookup description in generated conf file
+
+Mon Mar 2 21:54:44 2015 +0200 Hal Rosenstock
+b4d20d75ed8479a387ece69cb09f65d050290414
+
+	* osm_port_info_rcv.c: In pi_rcv_process_switch_port0, store port 0's PortInfo before querying switch external ports
+
+Fri Feb 27 16:44:10 2015 +0200 Hal Rosenstock
+504e43f8f1b61238542ad8a938a7fc86ba834178
+
+	* osm_req.c: Cosmetic formatting change
+
+Thu Feb 26 16:56:44 2015 +0200 Hal Rosenstock
+062d35de9d51458303052f7ed0945c5147172540
+
+	* osm_port_info_rcv.c: In pi_rcv_process_switch_port0, determine mkey
+
+Tue Feb 24 01:14:47 2015 +0200 Hal Rosenstock
+a5e484b834e63bc77ec1161a3f44df1919a93868
+
+	* osm_node.h: Fix commentary typo
+
+Thu Feb 19 16:24:01 2015 +0200 Hal Rosenstock
+6ceb0ce7d1d4cd7ce904cb015083a5313d2fa8cd
+
+	* osm_sa_mcmember_record.c: Removed redundancy in comment
+
+Mon Feb 9 23:36:44 2015 +0200 Vladimir Koushnir
+899664d9f866aac2ffb7647bf8d995eb3e5cc10f
+
+	* osm_ucast_mgr.c: Support diverse paths for LMC > 0 when scatter_ports is enabled
+
+Tue Feb 3 20:14:49 2015 +0200 Hal Rosenstock
+9e0cba39f0fcfba258192f7335809ef532103798
+
+	* osm_prtn_config.c: Cosmetic formatting change
+
+Sun Feb 1 13:30:06 2015 +0200 Daniel Klein
+6dc0b8088a717c225c908b47351ff5d1136e0f67
+
+	* osm_opensm.c: Call cl_disp_shutdown for SA SET dispatcher
+
+Tue Jan 27 18:40:02 2015 +0200 Ilya Nelkenbaum
+3199d3441448e2d614a22b8c06c265c43ea1a9f6
+
+	* osmeventplugin.c: Modify osm_event_plugin_t initialization
+
+Sat Jan 24 14:46:16 2015 +0200 Hal Rosenstock
+0eb5117bd188f8d386ca1eb4c75041d52e68adee
+
+	* osm_sa_mcmember_record.c: Cosmetic formatting change
+
+Thu Jan 15 18:15:01 2015 +0200 Daniel Klein
+94c2d74d96f7f8ddda264b3ee5926697fa18eb86
+
+	* Revert "osm_ucast_mgr.c: Force unicast routing to fail when lft allocations fail" patch
+
+Mon Jan 12 20:19:36 2015 +0200 Hal Rosenstock
+66301d8225586d47b17698aa9c9deee13fd7aa3c
+
+	* osm_subnet.c: Add more supported device IDs
+
+Sun Aug 3 14:26:48 2014 +0300 Daniel Klein
+1d205bc99eab68c8063c7164bedfe68fdc234a2b
+
+	* osm_ucast_mgr.c: Select exit ports for lid offset > 0 using new_lft
+
+Wed Oct 1 17:09:10 2014 +0200 Daniel Klein
+2a320950556522a18a959e58905daef4eed3d06e
+
+	* osm_ucast_cache.c: Rewrite p_sw->lft allocation in osm_ucast_cache_process
+
+Sun Aug 3 12:27:51 2014 +0300 Daniel Klein
+e2ee83ee4a1322b0ce2b9c16ec6a1aed21087679
+
+	* Use routing engine calculated LFT for SA queries
+
+Wed Jul 30 18:52:46 2014 +0300 Daniel Klein
+1413d64ba610edf8e950673f80bbaf6fec4e681b
+
+	* osm_state_mgr.c: Remove new_lft buffers cleanup
+
+Sun Dec 14 18:00:28 2014 +0200 Daniel Klein
+f2b96de26867d5e1c69ff2c9d60947030a14e0a1
+
+	* osm_ucast_mgr.c: Force unicast routing to fail when lft allocations fail
+
+Tue Jan 6 18:12:19 2015 +0200 Hal Rosenstock
+2541ed94869edc5a389f8e873887a739e2140a63
+
+	* osm_ucast_mgr.c: Cosmetic formatting change
+
+Sun Sep 28 16:41:03 2014 +0200 Daniel Klein
+948e2b1b08788e4be8e2fd34f876fa493a469ca3
+
+	* Add separate dispatcher for SA set and delete requests
+
+Mon Dec 22 15:32:21 2014 -0800 Albert Chu
+8ea4e0609f022c1458164c4e775d4afab020862d
+
+	* osm_congestion_control.c: Reset cc_timeout_count when count threshold passed
+
+Mon Dec 22 15:32:14 2014 -0800 Albert Chu
+0b7c80ce97306a4dde18784ba6e32093ed965463
+
+	* osm_congestion_control.c: Consistently set cc_unavailable_flag
+
+Mon Dec 22 15:32:12 2014 -0800 Albert Chu
+e590ebcf35139faf351f93316a3e3d5b6c7203cd
+
+	* osm_congestion_control.c: Add additional header status check in cc_rcv_mad
+
+Mon Jan 5 11:28:10 2015 -0800 Albert Chu
+f130d5a4cf798e2bda9a625278ee00f61d8fbdf3
+
+	* osm_subnet.c: Correct output error with congestion control table entries
+
+Sat Dec 20 19:10:33 2014 +0100 Vangelis Tasoulas
+0a695aeeb01ed8056cae66e4fe18fb047c75526c
+
+	* osm_switch.c: Fix wrong assertion failed in osm_switch_get_lft_block()
+
 ** Version: opensm-3.3.19
 
 Wed Dec 17 20:01:21 2014 +0200 Hal Rosenstock
diff --git a/complib/libosmcomp.ver b/complib/libosmcomp.ver
index 3ff0471..753ed84 100644
--- a/complib/libosmcomp.ver
+++ b/complib/libosmcomp.ver
@@ -6,4 +6,4 @@
 # API_REV - advance on any added API
 # RUNNING_REV - advance any change to the vendor files
 # AGE - number of backward versions the API still supports
-LIBVERSION=3:9:0
+LIBVERSION=3:10:0
diff --git a/configure b/configure
index f5f8949..6ad2d13 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for opensm 3.3.19.
+# Generated by GNU Autoconf 2.69 for opensm 3.3.20.
 #
 # Report bugs to <linux-rdma at vger.kernel.org>.
 #
@@ -729,8 +729,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='opensm'
 PACKAGE_TARNAME='opensm'
-PACKAGE_VERSION='3.3.19'
-PACKAGE_STRING='opensm 3.3.19'
+PACKAGE_VERSION='3.3.20'
+PACKAGE_STRING='opensm 3.3.20'
 PACKAGE_BUGREPORT='linux-rdma at vger.kernel.org'
 PACKAGE_URL=''
 
@@ -1498,7 +1498,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 opensm 3.3.19 to adapt to many kinds of systems.
+\`configure' configures opensm 3.3.20 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1568,7 +1568,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of opensm 3.3.19:";;
+     short | recursive ) echo "Configuration of opensm 3.3.20:";;
    esac
   cat <<\_ACEOF
 
@@ -1715,7 +1715,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-opensm configure 3.3.19
+opensm configure 3.3.20
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2138,7 +2138,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by opensm $as_me 3.3.19, which was
+It was created by opensm $as_me 3.3.20, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2957,7 +2957,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='opensm'
- VERSION='3.3.19'
+ VERSION='3.3.20'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -12689,7 +12689,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by opensm $as_me 3.3.19, which was
+This file was extended by opensm $as_me 3.3.20, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -12755,7 +12755,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-opensm config.status 3.3.19
+opensm config.status 3.3.20
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
diff --git a/configure.in b/configure.in
index 0555b90..b4dc3c4 100644
--- a/configure.in
+++ b/configure.in
@@ -1,7 +1,7 @@
 dnl Process this file with autoconf to produce a configure script.
 
 AC_PREREQ(2.57)
-AC_INIT(opensm, 3.3.19, linux-rdma at vger.kernel.org)
+AC_INIT(opensm, 3.3.20, linux-rdma at vger.kernel.org)
 AC_CONFIG_SRCDIR([opensm/osm_opensm.c])
 AC_CONFIG_AUX_DIR(config)
 AC_CONFIG_MACRO_DIR(config)
diff --git a/doc/QoS_management_in_OpenSM.txt b/doc/QoS_management_in_OpenSM.txt
index c104c1d..b2ce146 100644
--- a/doc/QoS_management_in_OpenSM.txt
+++ b/doc/QoS_management_in_OpenSM.txt
@@ -496,6 +496,6 @@ Below is an example of SL2VL and VL Arbitration configuration on subnet:
 
 In this example, there are 8 VLs configured on subnet: VL0 to VL7. VL0 is
 defined as a high priority VL, and it is limited to 6 x 4KB = 24KB in a single
-transmission burst. Such configuration would suilt VL that needs low latency
-and uses small MTU when transmitting packets. Rest of VLs are defined as low
-priority VLs with different weights, while VL4 is effectively turned off.
+transmission burst. Such configuration would suit a VL that needs low latency
+and uses a small MTU when transmitting packets. Rest of the VLs are defined as
+low priority VLs with different weights, while VL4 is effectively turned off.
diff --git a/doc/current-routing.txt b/doc/current-routing.txt
index d23ae0d..62e78b8 100644
--- a/doc/current-routing.txt
+++ b/doc/current-routing.txt
@@ -127,7 +127,7 @@ subscription is also equalized with the ability to override based on
 port GUID. The latter is supplied by:
 
 -i <equalize-ignore-guids-file>
--ignore-guids <equalize-ignore-guids-file>
+--ignore_guids <equalize-ignore-guids-file>
           This option provides the means to define a set of ports
           (by guids) that will be ignored by the link load
           equalization algorithm.
@@ -694,7 +694,7 @@ a branch that crosses a dateline.  However, again this cannot contribute
 to credit loops as it occurs on a 1D ring (the ring for x=3) that is
 broken by a failure, as in the above example.
 
-Torus Topolgy Discovery:
+Torus Topology Discovery:
 
 The algorithm used by torus-2QoS to construct the torus topology from the
 undirected graph representing the fabric requires that the radix of each
diff --git a/doc/opensm_release_notes-3.3.txt b/doc/opensm_release_notes-3.3.txt
index 708ae50..a799d90 100644
--- a/doc/opensm_release_notes-3.3.txt
+++ b/doc/opensm_release_notes-3.3.txt
@@ -3,14 +3,14 @@
 
 Version: OpenSM 3.3.x
 Repo:    git://git.openfabrics.org/~halr/opensm.git
-Date:    December 2014
+Date:    June 2016
 
 1 Overview
 ----------
 This document describes the contents of the OpenSM 3.3 release.
 OpenSM is an InfiniBand compliant Subnet Manager and Administration,
 and runs on top of OpenIB. The OpenSM version for this release
-is opensm-3.3.19.
+is opensm-3.3.20.
 
 This document includes the following sections:
 1 This Overview section (describing new features and software
@@ -95,6 +95,16 @@ This document includes the following sections:
 
 1.2 Minor New Features:
 
+fbe5107 osm_subnet.c: Add support for Switch-IB2 in is_mlnx_ext_port_info_supported
+6eb8b96 ftree: Additional ftree indexing algorithm
+c1f7ffd Support configuration for index 0 in pkey table
+1b73efd osm_sa_mcmember_record.c: Conditionalize multicast join parameter
+validation on new mcgroup_join_validation option
+4cd7ec3 osm_sa_mcmember_record.c: Validate IPoIB non broadcast group
+parameters on group creation
+fd754d2 Support another new MLNX OUI
+66301d8 osm_subnet.c: Add more supported device IDs
+948e2b1 Add separate dispatcher for SA set and delete requests
 672de65 perfmgr: Add xmit_wait to event plugin error counters data structure
 d86e7e3 perfmgr: Add xmit_wait support
 7e6bdef opensm/man/opensm.8.in: Add section for MKey support
@@ -512,6 +522,74 @@ information regarding each compliance statement.
 
 4.1 Major Bug Fixes
 
+62ea61a osm_state_mgr.c: Fix bug in handling of PortInfo Set timeout
+34e81df Change precedence in pkey manager with indx0 feature
+aa905e2 osm_pkey.[h c], osm_prtn.c: Create method to set pkey at indx0
+8a696eb osm_base.h: Fix OSM_CAP2_IS_PORT_INFO_CAPMASK2_MATCH_SUPPORTED
+definition
+70a364f opensm/osm_pkey_mgr.c: Fix pkey index wraparound/reuse
+6e27bba osm_multicast.c: Dump sa after deleting well known mc group
+df212a6 osm_multicast.c: Fix not dumping empty predefined mc groups
+1007810 osm_sa_guidinfo_record.c: Fix memory leak in set_guidinfo
+6272a56 osm_ucast_dfsssp.c: In dfsssp_do_mcast_routing, update adj_list first
+44b4edc osm_ucast_mgr.c: LFT update breaks if IB_SMP_DATA_SIZE changes
+19dbb67 osm_ucast_dfsssp.c: Fix dangling pointer when dfsssp used with ucast
+cache
+76bd8cd osm_sa_mcmember_record.c: Add error logging for mismatches to
+validate_other_comp_fields
+122cad3 osm_sa_mcmember_record.c: When joining MC group and MC group already
+exists, validate other components if supplied
+909976d Add more checks for physp validity
+b37560b osm_mcast_mgr.c: Add check for physp validity to create_mgrp_switch_map
+e4e449e osm_ucast_ftree.c: Fix wrong is_io assignment to the second HCA port
+e9bbf44 osm_ucast_ftree.c: Fix wrong handling of dual port HCA
+ccab3b8 osm_ucast_ftree.c: ftree calculates wrong number of compute nodes per
+leaf
+06ae3ad osm_sa.c: Fix osm_db_file_dump
+f1ab545 osm_drop_mgr.c: Do not set SM port discovery count to 0 when switch
+remote port is nonresponsive
+cd12dcd osm_port_info_rcv.c: Fix calculation of minimum data VLs
+cb20b11 osm_ucast_ftree.c: Fail routing if max rank is 0 and more than one
+root
+c633e05 osm_ucast_ftree.c: Mark HCA ports connected to unranked switches
+f004819 osm_sa.c: Fix race condition when writing SA DB file
+a64de2e osm_prtn_config.c: Fix wrong pkey table calculation in
+allow_both_pkeys mode
+0b6d8ea osm_sa_mcmember_record.c: Validate port's neighbor_mtu when joining MC
+group
+80ca401 osm_sa_path_record.c: When both [D S] GID and LID are supplied,
+validate that underlying ports are the same
+1fa8089 osm_sa_path_record.c: Handle path query by DGID and SLID
+141293d osmtest/osmt_multicast.c: Fix MC join with unrealistic rate test
+f471571 osm_subnet.c: Remove support for changing allow_both_pkeys on the fly
+cd31ff6 osm_port_info_rcv.c: Sending MEPI(Get) to local switch ports on hop 0
+4c3d782 osm_state_mgr.c: Mark port as undiscovered when removed by drop_mgr
+a1c4bc2 osm_console.c: Fix display of negative counters in console
+a6c2bf8 Add cleanup of SA cache after handover
+075ff44 osm_mcast_tbl.c: Wrong assert placement in osm_mcast_tbl_get_block
+953b70d osm_opensm.c: Fix race condition between traps handling and SA
+shutdown
+5e50a3c osm_sa_mcmember_record.c: Extend P_Pkey validation on MCMemberRecord(Join)
+3fcb121 osm_subnet.c: Improved m_key_lookup description in generated conf file
+b4d20d7 osm_port_info_rcv.c: In pi_rcv_process_switch_port0, store port 0's
+PortInfo before querying switch external ports
+062d35d osm_port_info_rcv.c: In pi_rcv_process_switch_port0, determine mkey
+899664d osm_ucast_mgr.c: Support diverse paths for LMC > 0 when scatter_ports
+is enabled
+6dc0b80 osm_opensm.c: Call cl_disp_shutdown for SA SET dispatcher
+3199d34 osmeventplugin.c: Modify osm_event_plugin_t initialization
+94c2d74 Revert "osm_ucast_mgr.c: Force unicast routing to fail when lft
+allocations fail" patch
+1d205bc osm_ucast_mgr.c: Select exit ports for lid offset > 0 using new_lft
+2a32095 osm_ucast_cache.c: Rewrite p_sw->lft allocation in osm_ucast_cache_process
+e2ee83e Use routing engine calculated LFT for SA queries
+1413d64 osm_state_mgr.c: Remove new_lft buffers cleanup
+f2b96de osm_ucast_mgr.c: Force unicast routing to fail when lft allocations fail
+8ea4e06 osm_congestion_control.c: Reset cc_timeout_count when count threshold passed
+0b7c80c osm_congestion_control.c: Consistently set cc_unavailable_flag
+e590ebc osm_congestion_control.c: Add additional header status check in cc_rcv_mad
+f130d5a osm_subnet.c: Correct output error with congestion control table entries
+0a695ae osm_switch.c: Fix wrong assertion failed in osm_switch_get_lft_block()
 5077198 osm_perfmgr.c: Reset physp_discovered before discovery
 8d51ae5 osm_state_mgr.c: Avoid continuing discovery when SM port is
 unresponsive
@@ -715,6 +793,66 @@ f37bf3c opensm/perfmgr: skip data counters when only printing errors
 
 4.2 Other Bug Fixes
 
+bb15d2f osm_service.c: Fix missing endian conversion in log message
+c0e8141 Fix various coverity issues
+a0d9157 osm_subnet.c: Add guid_routing_order_no_scatter option to opensm.conf
+5d521c1 osm_state_mgr.c: Update comment in state_mgr_check_tbl_consistency
+ccefa3d osm_sm_mad_ctrl.c: Add ':' to "ERR 3120" error message
+dc45fca ib_types.h: Comment change to indicate 1.3.1 rather than 1.2 IBA spec
+37e1246 ib_types.h: Cosmetic formatting changes
+73fd8ee man/opensm.8.in: Fix typo (missing close parenthesis)
+c32b813 doc/current-routing.txt: Fix typo
+c4691e7 ib_types.h: Cosmetic commentary fix
+85e2214 osm_sa_mcmember_record.c: Prevent log errors swamp in MC query scenario
+88626f4 osm_sa_mcmember_record.c: Updated Mellanox copyright years
+432727b osm_sa_mcmember_record.c: Cosmetic formatting change to mcmr_rcv_create_new_mgrp
+b85c31e osm_prtn_config.c: Cosmetic formatting changes in manage_membership_change
+1a2a6d7 osm_prtn_config.c: Updated Mellanox copyright years
+8b288b8 osm_mcast_mgr.c: Cosmetic formatting change in create_mgrp_switch_map
+4772806 osm_state_mgr.c: Fix uninitialized area of SMInfo SET mad
+175de41 osm_prtn.c: Cosmetic formatting change
+870b21a osm_ucast_dfsssp.c: Fix some commentary typos
+d5c51e9 osm_ucast_mgr.c: Cosmetic formatting change
+f234d83 osm_inform.c: Cosmetic code refactoring in match_inf_rec
+fdd1a68 Updated some Mellanox copyrights
+ecf07eb Set Type field in Notice attribute using IB_NOTICE_TYPE_SUBN_MGMT define
+022e6af Use SM trap defines from ib_types.h rather than hard coded values
+d111a2c ib_types.h: Cosmetic formatting change
+1cbea4b osmtest/osmt_multicast.c: Cosmetic changes
+c52a1b2 osm_drop_mgr.c: Eliminated redundant check for switch node type
+2c4771f osm_ucast_dfsssp.c: Minor change to setting dropped when switch exists
+e94fc29 osm_subnet.[h c]: Fix wrong function documentation and parameter list
+098259e Updated Mellanox copyrights in some recently changed files
+1f3dcb4 osm_ucast_ftree.c: Cosmetic formatting changes in fabric_construct_hca_ports
+e92cfe5 iba/ib_types.h: Fix commentary typo
+5109f44 osm_ucast_ftree.c: Cosmetic formatting change
+0bc858e osm_ucast_ftree.c: Cosmetic variable name changes in ftree_port_group_t struct
+08e8a9a osm_sa_path_record.c: Refactored PR [D/S] GID and LID validation
+7777987 osm_sa_path_record.c: Cosmetic formatting change
+a7ac5fc osm_prtn_config.c: Handle valgrind warning in osm_prtn_config_parse_file
+609b777 osm_ucast_ftree.c: Cosmetic formatting change
+d9a601b osm_ucast_ftree.c: Remove no longer needed code in remove_depended_hca
+1f6cd87 osm_state_mgr.c: Cosmetic formatting changes
+7f2f902 libvendor/osm_vendor_ibumad_sa.c: Cosmetic formatting change to ERR
+5501 log message
+e527ec6 libvendor/osm_vendor_ibumad_sa.c: Cosmetic formatting changes to
+osmv_query_sa
+ec2e2bf osm_pkey.h: Fix osm_physp_has_pkey method description
+bf3818b partition_config.txt: Small correction in doc file
+9fa761c osm_ucast_ftree.c: Removed *p_ftree parameter from sw_destroy function
+652b063 osm_ucast_ftree.c: Removed *p_ftree parameter from sw_create function
+d504e76 doc/QoS_management_in_OpenSM.txt: Cosmetic changes
+a28d63e Fix documentation on ignore-guids command line option
+df32644 osm_subnet.c: Minor clarification to SwitchCongestionSetting Control
+Map description in generated option file
+483ff00 man/osmtest.8: Minor tweaks to inventory option description
+8d3c6f8 osm_sa_mcmember_record.c: Change to log messages for PKey consistency
+504e43f osm_req.c: Cosmetic formatting change
+a5e484b osm_node.h: Fix commentary typo
+6ceb0ce osm_sa_mcmember_record.c: Removed redundancy in comment
+9e0cba3 osm_prtn_config.c: Cosmetic formatting change
+0eb5117 osm_sa_mcmember_record.c: Cosmetic formatting change
+2541ed9 osm_ucast_mgr.c: Cosmetic formatting change
 28fd4ee osm_[subnet congestion_control].c: Cosmetic commentary change
 391c244 osm_congestion_control.c: Added Mellanox copyright
 7e08621 osm_congestion_control.c: In cc_rcv_mad, add attribute ID and modifier
diff --git a/doc/partition-config.txt b/doc/partition-config.txt
index 6dba596..3bdb957 100644
--- a/doc/partition-config.txt
+++ b/doc/partition-config.txt
@@ -36,13 +36,15 @@ General file format:
 <Partition Definition>:[<newline>]<Partition Properties>;
 
      Partition Definition:
-       [PartitionName][=PKey][,ipoib_bc_flags][,defmember=full|limited|both]
+       [PartitionName][=PKey][,indx0][,ipoib_bc_flags][,defmember=full|limited|both]
 
         PartitionName  - string, will be used with logging. When
                          omitted, empty string will be used.
         PKey           - P_Key value for this partition. Only low 15
                          bits will be used. When omitted will be
                          autogenerated.
+	indx0          - indicates that this pkey should be inserted in
+			 block 0 index 0.
         ipoib_bc_flags - used to indicate/specify IPoIB capability of
                          this partition.
 
@@ -159,7 +161,7 @@ Examples:
  # 0x123453, 0x123454 will be limited
  ShareIO = 0x80 : 0x123453, 0x123454, 0x123455=full;
  # 0x123456, 0x123457 will be limited
- ShareIO = 0x80 : defmember=limited : 0x123456, 0x123457, 0x123458=full;
+ ShareIO = 0x80 , defmember=limited : 0x123456, 0x123457, 0x123458=full;
  ShareIO = 0x80 , defmember=full : 0x123459, 0x12345a;
  ShareIO = 0x80 , defmember=full : 0x12345b, 0x12345c=limited, 0x12345d;
 
diff --git a/include/iba/ib_types.h b/include/iba/ib_types.h
index 93c706e..7284095 100644
--- a/include/iba/ib_types.h
+++ b/include/iba/ib_types.h
@@ -72,7 +72,7 @@ BEGIN_C_DECLS
 * DESCRIPTION
 *	The following constants are used throughout the IBA code base.
 *
-*	Definitions are from the InfiniBand Architecture Specification v1.2
+*	Definitions are from the InfiniBand Architecture Specification v1.3.1
 *
 *********/
 /****d* IBA Base: Constants/MAD_BLOCK_SIZE
@@ -152,8 +152,8 @@ BEGIN_C_DECLS
 */
 #define IB_QP1_WELL_KNOWN_Q_KEY				CL_HTON32(0x80010000)
 /*********/
-#define IB_QP0								0
-#define IB_QP1								CL_HTON32(1)
+#define IB_QP0						0
+#define IB_QP1						CL_HTON32(1)
 #define IB_QP_PRIVILEGED_Q_KEY				CL_HTON32(0x80000000)
 /****d* IBA Base: Constants/IB_LID_UCAST_START
 * NAME
@@ -165,7 +165,7 @@ BEGIN_C_DECLS
 * SOURCE
 */
 #define IB_LID_UCAST_START_HO				0x0001
-#define IB_LID_UCAST_START					(CL_HTON16(IB_LID_UCAST_START_HO))
+#define IB_LID_UCAST_START				(CL_HTON16(IB_LID_UCAST_START_HO))
 /**********/
 /****d* IBA Base: Constants/IB_LID_UCAST_END
 * NAME
@@ -176,8 +176,8 @@ BEGIN_C_DECLS
 *
 * SOURCE
 */
-#define IB_LID_UCAST_END_HO					0xBFFF
-#define IB_LID_UCAST_END					(CL_HTON16(IB_LID_UCAST_END_HO))
+#define IB_LID_UCAST_END_HO				0xBFFF
+#define IB_LID_UCAST_END				(CL_HTON16(IB_LID_UCAST_END_HO))
 /**********/
 /****d* IBA Base: Constants/IB_LID_MCAST_START
 * NAME
@@ -189,7 +189,7 @@ BEGIN_C_DECLS
 * SOURCE
 */
 #define IB_LID_MCAST_START_HO				0xC000
-#define IB_LID_MCAST_START					(CL_HTON16(IB_LID_MCAST_START_HO))
+#define IB_LID_MCAST_START				(CL_HTON16(IB_LID_MCAST_START_HO))
 /**********/
 /****d* IBA Base: Constants/IB_LID_MCAST_END
 * NAME
@@ -200,8 +200,8 @@ BEGIN_C_DECLS
 *
 * SOURCE
 */
-#define IB_LID_MCAST_END_HO					0xFFFE
-#define IB_LID_MCAST_END					(CL_HTON16(IB_LID_MCAST_END_HO))
+#define IB_LID_MCAST_END_HO				0xFFFE
+#define IB_LID_MCAST_END				(CL_HTON16(IB_LID_MCAST_END_HO))
 /**********/
 /****d* IBA Base: Constants/IB_DEFAULT_SUBNET_PREFIX
 * NAME
@@ -234,7 +234,7 @@ BEGIN_C_DECLS
 *
 * SOURCE
 */
-#define IB_INVALID_PORT_NUM					0xFF
+#define IB_INVALID_PORT_NUM				0xFF
 /*********/
 /****d* IBA Base: Constants/IB_SUBNET_PATH_HOPS_MAX
 * NAME
@@ -279,7 +279,7 @@ BEGIN_C_DECLS
 *
 * SOURCE
 */
-#define IB_PKEY_MAX_BLOCKS					2048
+#define IB_PKEY_MAX_BLOCKS				2048
 /*********/
 /****d* IBA Base: Constants/IB_MCAST_MAX_BLOCK_ID
 * NAME
@@ -312,7 +312,7 @@ BEGIN_C_DECLS
 *
 * SOURCE
 */
-#define IB_MCAST_BLOCK_SIZE					32
+#define IB_MCAST_BLOCK_SIZE				32
 /*********/
 /****d* IBA Base: Constants/IB_MCAST_MASK_SIZE
 * NAME
@@ -323,7 +323,7 @@ BEGIN_C_DECLS
 *
 * SOURCE
 */
-#define IB_MCAST_MASK_SIZE					16
+#define IB_MCAST_MASK_SIZE				16
 /*********/
 /****d* IBA Base: Constants/IB_MCAST_POSITION_MASK_HO
 * NAME
@@ -334,7 +334,7 @@ BEGIN_C_DECLS
 *
 * SOURCE
 */
-#define IB_MCAST_POSITION_MASK_HO				0xF0000000
+#define IB_MCAST_POSITION_MASK_HO			0xF0000000
 /*********/
 /****d* IBA Base: Constants/IB_MCAST_POSITION_MAX
 * NAME
@@ -378,7 +378,7 @@ BEGIN_C_DECLS
 *
 * SOURCE
 */
-#define IB_PKEY_BASE_MASK					(CL_HTON16(0x7FFF))
+#define IB_PKEY_BASE_MASK				(CL_HTON16(0x7FFF))
 /*********/
 /****d* IBA Base: Constants/IB_PKEY_TYPE_MASK
 * NAME
@@ -389,7 +389,7 @@ BEGIN_C_DECLS
 *
 * SOURCE
 */
-#define IB_PKEY_TYPE_MASK					(CL_HTON16(0x8000))
+#define IB_PKEY_TYPE_MASK				(CL_HTON16(0x8000))
 /*********/
 /****d* IBA Base: Constants/IB_DEFAULT_PARTIAL_PKEY
 * NAME
@@ -400,7 +400,7 @@ BEGIN_C_DECLS
 *
 * SOURCE
 */
-#define IB_DEFAULT_PARTIAL_PKEY				       (CL_HTON16(0x7FFF))
+#define IB_DEFAULT_PARTIAL_PKEY				(CL_HTON16(0x7FFF))
 /**********/
 /****d* IBA Base: Constants/IB_MCLASS_SUBN_LID
 * NAME
@@ -411,7 +411,7 @@ BEGIN_C_DECLS
 *
 * SOURCE
 */
-#define IB_MCLASS_SUBN_LID					0x01
+#define IB_MCLASS_SUBN_LID				0x01
 /**********/
 /****d* IBA Base: Constants/IB_MCLASS_SUBN_DIR
 * NAME
@@ -422,7 +422,7 @@ BEGIN_C_DECLS
 *
 * SOURCE
 */
-#define IB_MCLASS_SUBN_DIR					0x81
+#define IB_MCLASS_SUBN_DIR				0x81
 /**********/
 /****d* IBA Base: Constants/IB_MCLASS_SUBN_ADM
 * NAME
@@ -433,7 +433,7 @@ BEGIN_C_DECLS
 *
 * SOURCE
 */
-#define IB_MCLASS_SUBN_ADM					0x03
+#define IB_MCLASS_SUBN_ADM				0x03
 /**********/
 /****d* IBA Base: Constants/IB_MCLASS_PERF
 * NAME
@@ -444,7 +444,7 @@ BEGIN_C_DECLS
 *
 * SOURCE
 */
-#define IB_MCLASS_PERF						0x04
+#define IB_MCLASS_PERF					0x04
 /**********/
 /****d* IBA Base: Constants/IB_MCLASS_BM
 * NAME
@@ -455,7 +455,7 @@ BEGIN_C_DECLS
 *
 * SOURCE
 */
-#define IB_MCLASS_BM						0x05
+#define IB_MCLASS_BM					0x05
 /**********/
 /****d* IBA Base: Constants/IB_MCLASS_DEV_MGMT
 * NAME
@@ -466,7 +466,7 @@ BEGIN_C_DECLS
 *
 * SOURCE
 */
-#define IB_MCLASS_DEV_MGMT					0x06
+#define IB_MCLASS_DEV_MGMT				0x06
 /**********/
 /****d* IBA Base: Constants/IB_MCLASS_COMM_MGMT
 * NAME
@@ -477,7 +477,7 @@ BEGIN_C_DECLS
 *
 * SOURCE
 */
-#define IB_MCLASS_COMM_MGMT					0x07
+#define IB_MCLASS_COMM_MGMT				0x07
 /**********/
 /****d* IBA Base: Constants/IB_MCLASS_SNMP
 * NAME
@@ -488,7 +488,7 @@ BEGIN_C_DECLS
 *
 * SOURCE
 */
-#define IB_MCLASS_SNMP						0x08
+#define IB_MCLASS_SNMP					0x08
 /**********/
 /****d* IBA Base: Constants/IB_MCLASS_VENDOR_LOW_RANGE_MIN
 * NAME
@@ -499,7 +499,7 @@ BEGIN_C_DECLS
 *
 * SOURCE
 */
-#define IB_MCLASS_VENDOR_LOW_RANGE_MIN 0x09
+#define IB_MCLASS_VENDOR_LOW_RANGE_MIN			0x09
 /**********/
 /****d* IBA Base: Constants/IB_MCLASS_VENDOR_LOW_RANGE_MAX
 * NAME
@@ -510,7 +510,7 @@ BEGIN_C_DECLS
 *
 * SOURCE
 */
-#define IB_MCLASS_VENDOR_LOW_RANGE_MAX 0x0f
+#define IB_MCLASS_VENDOR_LOW_RANGE_MAX			0x0F
 /**********/
 /****d* IBA Base: Constants/IB_MCLASS_DEV_ADM
 * NAME
@@ -521,7 +521,7 @@ BEGIN_C_DECLS
 *
 * SOURCE
 */
-#define IB_MCLASS_DEV_ADM 0x10
+#define IB_MCLASS_DEV_ADM				0x10
 /**********/
 /****d* IBA Base: Constants/IB_MCLASS_BIS
 * NAME
@@ -532,7 +532,7 @@ BEGIN_C_DECLS
 *
 * SOURCE
 */
-#define IB_MCLASS_BIS 0x12
+#define IB_MCLASS_BIS					0x12
 /**********/
 /****d* IBA Base: Constants/IB_MCLASS_CC
 * NAME
@@ -543,7 +543,7 @@ BEGIN_C_DECLS
 *
 * SOURCE
 */
-#define IB_MCLASS_CC 0x21
+#define IB_MCLASS_CC					0x21
 /**********/
 /****d* IBA Base: Constants/IB_MCLASS_VENDOR_HIGH_RANGE_MIN
 * NAME
@@ -554,7 +554,7 @@ BEGIN_C_DECLS
 *
 * SOURCE
 */
-#define IB_MCLASS_VENDOR_HIGH_RANGE_MIN 0x30
+#define IB_MCLASS_VENDOR_HIGH_RANGE_MIN			0x30
 /**********/
 /****d* IBA Base: Constants/IB_MCLASS_VENDOR_HIGH_RANGE_MAX
 * NAME
@@ -565,7 +565,7 @@ BEGIN_C_DECLS
 *
 * SOURCE
 */
-#define IB_MCLASS_VENDOR_HIGH_RANGE_MAX 0x4f
+#define IB_MCLASS_VENDOR_HIGH_RANGE_MAX			0x4F
 /**********/
 /****f* IBA Base: Types/ib_class_is_vendor_specific_low
 * NAME
@@ -1723,7 +1723,7 @@ static inline boolean_t OSM_API ib_class_is_rmpp(IN const uint8_t class_code)
 *
 * SOURCE
 */
-#define IB_NOTICE_PRODUCER_TYPE_CLASS_MGR			(CL_HTON32(0x000004))
+#define IB_NOTICE_PRODUCER_TYPE_CLASS_MGR		(CL_HTON32(0x000004))
 /**********/
 
 /****d* IBA Base: Constants/IB_MTU_LEN_TYPE
@@ -1832,7 +1832,7 @@ static inline boolean_t OSM_API ib_class_is_rmpp(IN const uint8_t class_code)
 
 /****d* IBA Base: Constants/IB_MULTIPATH_REC_SL_MASK
 * NAME
-*	IB_MILTIPATH_REC_SL_MASK
+*	IB_MULTIPATH_REC_SL_MASK
 *
 * DESCRIPTION
 *	Mask for the sl field for MultiPath record
@@ -2194,7 +2194,7 @@ static inline ib_net16_t OSM_API ib_pkey_get_base(IN const ib_net16_t pkey)
 *	ib_pkey_is_full_member
 *
 * DESCRIPTION
-*	Indicates if the port is a full member of the parition.
+*	Indicates if the port is a full member of the partition.
 *
 * SYNOPSIS
 */
diff --git a/include/opensm/osm_base.h b/include/opensm/osm_base.h
index e2425bf..2c60c7b 100644
--- a/include/opensm/osm_base.h
+++ b/include/opensm/osm_base.h
@@ -905,7 +905,7 @@ typedef enum _osm_thread_state {
  *
  * SYNOPSIS
  */
-#define OSM_CAP2_IS_PORT_INFO_CAPMASK2_MATCH_SUPPORTED (1 << 9)
+#define OSM_CAP2_IS_PORT_INFO_CAPMASK2_MATCH_SUPPORTED (1 << 10)
 
 /****d* OpenSM: Base/osm_signal_t
 * NAME
@@ -1010,6 +1010,7 @@ typedef enum _osm_sm_signal {
 #define OSM_VENDOR_ID_MELLANOX2     0xF45214
 #define OSM_VENDOR_ID_MELLANOX3     0x00258B
 #define OSM_VENDOR_ID_MELLANOX4     0xE41D2D
+#define OSM_VENDOR_ID_MELLANOX5     0x7CFE90
 
 /* IPoIB Broadcast Defaults */
 #define OSM_IPOIB_BROADCAST_MGRP_QKEY 0x0b1b
diff --git a/include/opensm/osm_node.h b/include/opensm/osm_node.h
index b07a455..1d34904 100644
--- a/include/opensm/osm_node.h
+++ b/include/opensm/osm_node.h
@@ -139,7 +139,7 @@ typedef struct osm_node {
 *		Each object indiactes whether the port has been discovered
 *		during the sweep or not. 1 means that the port had been discovered.
 *
-*	phsyp_table
+*	physp_table
 *		Array of physical port objects belonging to this node.
 *		Index is contiguous by local port number.
 *		For switches, port 0 is the always the management port (14.2.5.6).
diff --git a/include/opensm/osm_opensm.h b/include/opensm/osm_opensm.h
index 4750505..7768881 100644
--- a/include/opensm/osm_opensm.h
+++ b/include/opensm/osm_opensm.h
@@ -226,6 +226,8 @@ typedef struct osm_opensm {
 	osm_vl15_t vl15;
 	osm_log_t log;
 	cl_dispatcher_t disp;
+	cl_dispatcher_t sa_set_disp;
+	boolean_t sa_set_disp_initialized;
 	cl_plock_t lock;
 	struct osm_routing_engine *routing_engine_list;
 	struct osm_routing_engine *routing_engine_used;
@@ -269,6 +271,12 @@ typedef struct osm_opensm {
 *	disp
 *		Central dispatcher containing the OpenSM worker threads.
 *
+*	sa_set_disp
+*		Dispatcher for SA Set and Delete requests.
+*
+*	sa_set_disp_initialized.
+*		Indicator that sa_set_disp dispatcher was initialized.
+*
 *	lock
 *		Shared lock guarding most OpenSM structures.
 *
diff --git a/include/opensm/osm_pkey.h b/include/opensm/osm_pkey.h
index 090a8be..de4f2f9 100644
--- a/include/opensm/osm_pkey.h
+++ b/include/opensm/osm_pkey.h
@@ -91,6 +91,7 @@ typedef struct osm_pkeybl {
 	uint16_t used_blocks;
 	uint16_t max_blocks;
 	uint16_t rcv_blocks_cnt;
+	uint16_t indx0_pkey;
 } osm_pkey_tbl_t;
 /*
 * FIELDS
@@ -125,6 +126,10 @@ typedef struct osm_pkeybl {
 *		For every GetPKeyTable mad we send, increase the counter,
 *		and for every GetRespPKeyTable we decrease the counter.
 *
+*	indx0_pkey
+*		stores the pkey to be inserted at block 0 index 0.
+*		if this field is 0, the default pkey will be inserted.
+*
 * NOTES
 * 'blocks' vector should be used to store pkey values obtained from
 * the port and SM pkey manager should not change it directly, for this
@@ -664,22 +669,7 @@ boolean_t osm_port_share_pkey(IN osm_log_t * p_log,
 *  osm_physp_has_pkey
 *
 * DESCRIPTION
-*  Checks if the given lids and port_numbers share a pkey.
-*  The meaning P_Key matching:
-*  10.9.3 :
-*   In the following, let M_P_Key(Message P_Key) be the P_Key in the incoming
-*   packet and E_P_Key(Endnode P_Key) be the P_Key it is being compared against
-*   in the packet's destination endnode.
-*
-*    If:
-*    * neither M_P_Key nor E_P_Key are the invalid P_Key
-*    * and the low-order 15 bits of the M_P_Key match the low order 15
-*      bits of the E_P_Key
-*    * and the high order bit(membership type) of both the M_P_Key and
-*      E_P_Key are not both 0 (i.e., both are not Limited members of
-*      the partition)
-*
-*    then the P_Keys are said to match.
+*	Given a physp and a pkey, check if pkey exists in physp pkey table
 *
 * SYNOPSIS
 */
@@ -704,5 +694,37 @@ boolean_t osm_physp_has_pkey(IN osm_log_t * p_log, IN ib_net16_t pkey,
 *
 *********/
 
+/****f* OpenSM: osm_pkey_tbl_set_indx0_pkey
+* NAME
+*  osm_pkey_tbl_set_indx0_pkey
+*
+* DESCRIPTION
+*  Sets given pkey at index0 in given pkey_tbl.
+*
+* SYNOPSIS
+*/
+void osm_pkey_tbl_set_indx0_pkey(IN osm_log_t * p_log, IN ib_net16_t pkey,
+				 IN boolean_t full,
+				 OUT osm_pkey_tbl_t * p_pkey_tbl);
+/*
+* PARAMETERS
+*  p_log
+*     [in] Pointer to a log object.
+*
+*  pkey
+*     [in] P_Key.
+*
+*  full
+*     [in] Indication if this is a full/limited membership pkey.
+*
+*  p_pkey_tbl
+*     [out] Pointer to osm_pkey_tbl_t object in which to set indx0 pkey.
+*
+* RETURN VALUES
+*  None
+*
+* NOTES
+*
+*********/
 END_C_DECLS
 #endif				/* _OSM_PKEY_H_ */
diff --git a/include/opensm/osm_port.h b/include/opensm/osm_port.h
index 206c4a9..5ef4453 100644
--- a/include/opensm/osm_port.h
+++ b/include/opensm/osm_port.h
@@ -1611,5 +1611,91 @@ void osm_alias_guid_delete(IN OUT osm_alias_guid_t ** pp_alias_guid);
 *	Port
 *********/
 
+/****f* OpenSM: Port/osm_alias_guid_get_alias_guid
+* NAME
+*	osm_alias_guid_get_alias_guid
+*
+* DESCRIPTION
+*	This function retrieves alias guid from alias guid object.
+*
+* SYNOPSIS
+*/
+static inline ib_net64_t osm_alias_guid_get_alias_guid(IN osm_alias_guid_t *p_alias_guid)
+{
+	CL_ASSERT(p_alias_guid);
+	return p_alias_guid->alias_guid;
+}
+/*
+* PARAMETERS
+*	p_alias_guid
+*		[in] Pointer to a pointer to an alias guid object.
+*
+* RETURN VALUE
+*	This function returns the alias guid or NULL if fails.
+*
+* NOTES
+*
+* SEE ALSO
+*	Port
+*********/
+
+/****f* OpenSM: Port/osm_alias_guid_get_base_guid
+* NAME
+*	osm_alias_guid_get_base_guid
+*
+* DESCRIPTION
+*	This function retrieves base guid from alias guid object.
+*
+* SYNOPSIS
+*/
+static inline ib_net64_t osm_alias_guid_get_base_guid(IN osm_alias_guid_t *p_alias_guid)
+{
+	CL_ASSERT(p_alias_guid);
+	return osm_port_get_guid(p_alias_guid->p_base_port);
+}
+/*
+* PARAMETERS
+*	p_alias_guid
+*		[in] Pointer to a pointer to an alias guid object.
+*
+* RETURN VALUE
+*	This function returns the base guid or NULL if fails.
+*
+* NOTES
+*
+* SEE ALSO
+*	Port
+*********/
+
+/****f* OpenSM: Port/osm_port_clear_base_lid
+* NAME
+*	osm_port_clear_base_lid
+*
+* DESCRIPTION
+*	Clear the base lid of a given port.
+*
+* SYNOPSIS
+*/
+static inline void osm_port_clear_base_lid(OUT osm_port_t * p_port)
+{
+	CL_ASSERT(p_port);
+	p_port->lid = 0;
+	osm_physp_set_base_lid(p_port->p_physp, 0);
+}
+
+/*
+* PARAMETERS
+*	p_port
+*		[out] Pointer to a Port object.
+*
+* RETURN VALUE
+*	None
+*
+* NOTES
+*
+* SEE ALSO
+*	Port
+*********/
+
 END_C_DECLS
 #endif				/* _OSM_PORT_H_ */
diff --git a/include/opensm/osm_sa.h b/include/opensm/osm_sa.h
index f9f334e..aeeaa02 100644
--- a/include/opensm/osm_sa.h
+++ b/include/opensm/osm_sa.h
@@ -186,6 +186,7 @@ typedef struct osm_sa {
 	osm_log_t *p_log;
 	osm_mad_pool_t *p_mad_pool;
 	cl_dispatcher_t *p_disp;
+	cl_dispatcher_t *p_set_disp;
 	cl_plock_t *p_lock;
 	atomic32_t sa_trans_id;
 	osm_sa_mad_ctrl_t mad_ctrl;
@@ -211,6 +212,10 @@ typedef struct osm_sa {
 	cl_disp_reg_handle_t lft_disp_h;
 	cl_disp_reg_handle_t sir_disp_h;
 	cl_disp_reg_handle_t mft_disp_h;
+	cl_disp_reg_handle_t infr_set_disp_h;
+	cl_disp_reg_handle_t gir_set_disp_h;
+	cl_disp_reg_handle_t mcmr_set_disp_h;
+	cl_disp_reg_handle_t sr_set_disp_h;
 } osm_sa_t;
 /*
 * FIELDS
@@ -235,6 +240,9 @@ typedef struct osm_sa {
 *	p_disp
 *		Pointer to dispatcher
 *
+*	p_set_disp
+*		Pointer to dispatcher for Set requests.
+*
 *	p_lock
 *		Pointer to Lock for serialization
 *
@@ -346,6 +354,7 @@ ib_api_status_t osm_sa_init(IN osm_sm_t * p_sm, IN osm_sa_t * p_sa,
 			    IN osm_mad_pool_t * p_mad_pool,
 			    IN osm_log_t * p_log, IN osm_stats_t * p_stats,
 			    IN cl_dispatcher_t * p_disp,
+			    IN cl_dispatcher_t * p_set_disp,
 			    IN cl_plock_t * p_lock);
 /*
 * PARAMETERS
@@ -370,6 +379,9 @@ ib_api_status_t osm_sa_init(IN osm_sm_t * p_sm, IN osm_sa_t * p_sa,
 *	p_disp
 *		[in] Pointer to the OpenSM central Dispatcher.
 *
+*	p_set_disp
+*		[in] Pointer to the OpenSM Dispatcher for Set requests.
+*
 *	p_lock
 *		[in] Pointer to the OpenSM serializing lock.
 *
diff --git a/include/opensm/osm_sa_mad_ctrl.h b/include/opensm/osm_sa_mad_ctrl.h
index 00ccbf6..2c2513b 100644
--- a/include/opensm/osm_sa_mad_ctrl.h
+++ b/include/opensm/osm_sa_mad_ctrl.h
@@ -98,7 +98,9 @@ typedef struct osm_sa_mad_ctrl {
 	osm_vendor_t *p_vendor;
 	osm_bind_handle_t h_bind;
 	cl_dispatcher_t *p_disp;
+	cl_dispatcher_t *p_set_disp;
 	cl_disp_reg_handle_t h_disp;
+	cl_disp_reg_handle_t h_set_disp;
 	osm_stats_t *p_stats;
 	osm_subn_t *p_subn;
 } osm_sa_mad_ctrl_t;
@@ -122,9 +124,15 @@ typedef struct osm_sa_mad_ctrl {
 *	p_disp
 *		Pointer to the Dispatcher.
 *
+*	p_set_disp
+*		Pointer to the Dispatcher for Set requests.
+*
 *	h_disp
 *		Handle returned from dispatcher registration.
 *
+*	h_set_disp
+*		Handle returned from Set requests dispatcher registration.
+*
 *	p_stats
 *		Pointer to the OpenSM statistics block.
 *
@@ -211,7 +219,8 @@ ib_api_status_t osm_sa_mad_ctrl_init(IN osm_sa_mad_ctrl_t * p_ctrl,
 				     IN osm_subn_t * p_subn,
 				     IN osm_log_t * p_log,
 				     IN osm_stats_t * p_stats,
-				     IN cl_dispatcher_t * p_disp);
+				     IN cl_dispatcher_t * p_disp,
+				     IN cl_dispatcher_t * p_set_disp);
 /*
 * PARAMETERS
 *	p_ctrl
@@ -235,6 +244,9 @@ ib_api_status_t osm_sa_mad_ctrl_init(IN osm_sa_mad_ctrl_t * p_ctrl,
 *	p_disp
 *		[in] Pointer to the OpenSM central Dispatcher.
 *
+*	p_set_disp
+*		[in] Pointer to the OpenSM Dispatcher for Set requests.
+*
 * RETURN VALUES
 *	IB_SUCCESS if the SA MAD Controller object was initialized
 *	successfully.
diff --git a/include/opensm/osm_subnet.h b/include/opensm/osm_subnet.h
index 585295d..17df725 100644
--- a/include/opensm/osm_subnet.h
+++ b/include/opensm/osm_subnet.h
@@ -1,11 +1,12 @@
 /*
  * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
- * Copyright (c) 2002-2011 Mellanox Technologies LTD. All rights reserved.
+ * Copyright (c) 2002-2015 Mellanox Technologies LTD. All rights reserved.
  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
  * Copyright (c) 2008 Xsigo Systems Inc.  All rights reserved.
  * Copyright (c) 2009 System Fabric Works, Inc. All rights reserved.
  * Copyright (c) 2009 HNR Consulting. All rights reserved.
  * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009-2015 ZIH, TU Dresden, Federal Republic of Germany. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -329,6 +330,8 @@ typedef struct osm_subn_opt {
 	boolean_t sm_inactive;
 	boolean_t babbling_port_policy;
 	boolean_t drop_event_subscriptions;
+	boolean_t ipoib_mcgroup_creation_validation;
+	boolean_t mcgroup_join_validation;
 	boolean_t use_optimized_slvl;
 	boolean_t fsync_high_avail_files;
 	osm_qos_options_t qos_options;
@@ -376,6 +379,7 @@ typedef struct osm_subn_opt {
 	uint8_t lash_start_vl;			/* starting vl to use in lash */
 	uint8_t sm_sl;			/* which SL to use for SM/SA communication */
 	char *per_module_logging_file;
+	boolean_t quasi_ftree_indexing;
 } osm_subn_opt_t;
 /*
 * FIELDS
@@ -605,6 +609,14 @@ typedef struct osm_subn_opt {
 *	drop_event_subscriptions
 *		OpenSM will drop event subscriptions if the port goes away.
 *
+*	ipoib_mcgroup_creation_validation
+*		OpenSM will validate IPoIB non-broadcast group parameters
+*		against IPoIB broadcast group.
+*
+*	mcgroup_join_validation
+*		OpenSM will validate multicast join parameters against
+*		multicast group parameters when MC group already exists.
+*
 *	use_optimized_slvl
 *		Use optimized SLtoVLMappingTable programming if
 *		device indicates it supports this.
@@ -786,7 +798,7 @@ typedef struct osm_subn {
 *
 *	port_guid_tbl
 *		Container of pointers to all Port objects in the subnet.
-*		Indexed by port GUID - network order!
+*		Indexed by port GUID.
 *
 *	rtr_guid_tbl
 *		Container of pointers to all Router objects in the subnet.
@@ -1169,14 +1181,14 @@ struct osm_port *osm_get_port_by_mad_addr(IN struct osm_log *p_log,
 * SYNOPSIS
 */
 struct osm_switch *osm_get_switch_by_guid(IN const osm_subn_t * p_subn,
-					  IN uint64_t guid);
+					  IN ib_net64_t guid);
 /*
 * PARAMETERS
 *	p_subn
 *		[in] Pointer to an osm_subn_t object
 *
 *	guid
-*		[in] The node guid in host order
+*		[in] The node guid in network byte order
 *
 * RETURN VALUES
 *	The switch structure pointer if found. NULL otherwise.
@@ -1198,14 +1210,14 @@ struct osm_switch *osm_get_switch_by_guid(IN const osm_subn_t * p_subn,
 * SYNOPSIS
 */
 struct osm_node *osm_get_node_by_guid(IN osm_subn_t const *p_subn,
-				      IN uint64_t guid);
+				      IN ib_net64_t guid);
 /*
 * PARAMETERS
 *	p_subn
 *		[in] Pointer to an osm_subn_t object
 *
 *	guid
-*		[in] The node guid in host order
+*		[in] The node guid in network byte order
 *
 * RETURN VALUES
 *	The node structure pointer if found. NULL otherwise.
@@ -1260,7 +1272,7 @@ struct osm_port *osm_get_port_by_lid_ho(const osm_subn_t * subn, uint16_t lid);
 *		[in] Pointer to the subnet data structure.
 *
 *	lid
-*		[in] LID requested in hot byte order.
+*		[in] LID requested in host byte order.
 *
 * RETURN VALUES
 *	The port structure pointer if found. NULL otherwise.
diff --git a/include/opensm/osm_switch.h b/include/opensm/osm_switch.h
index 41ac959..5047b86 100644
--- a/include/opensm/osm_switch.h
+++ b/include/opensm/osm_switch.h
@@ -407,6 +407,21 @@ uint8_t osm_switch_get_port_least_hops(IN const osm_switch_t * p_sw,
 *	Switch object
 *********/
 
+/****d* OpenSM: osm_lft_type_enum
+* NAME
+*	osm_lft_type_enum
+*
+* DESCRIPTION
+*	Enumerates LFT sets types of a switch.
+*
+* SYNOPSIS
+*/
+typedef enum osm_lft_type_enum {
+	OSM_LFT = 0,
+	OSM_NEW_LFT
+} osm_lft_type_enum;
+/***********/
+
 /****f* OpenSM: Switch/osm_switch_get_port_by_lid
 * NAME
 *	osm_switch_get_port_by_lid
@@ -417,11 +432,12 @@ uint8_t osm_switch_get_port_least_hops(IN const osm_switch_t * p_sw,
 * SYNOPSIS
 */
 static inline uint8_t osm_switch_get_port_by_lid(IN const osm_switch_t * p_sw,
-						 IN uint16_t lid_ho)
+						 IN uint16_t lid_ho,
+						 IN osm_lft_type_enum lft_enum)
 {
 	if (lid_ho == 0 || lid_ho > p_sw->max_lid_ho)
 		return OSM_NO_PATH;
-	return p_sw->lft[lid_ho];
+	return lft_enum == OSM_LFT ? p_sw->lft[lid_ho] : p_sw->new_lft[lid_ho];
 }
 /*
 * PARAMETERS
@@ -431,6 +447,10 @@ static inline uint8_t osm_switch_get_port_by_lid(IN const osm_switch_t * p_sw,
 *	lid_ho
 *		[in] LID (host order) for which to retrieve the shortest hop count.
 *
+*	lft_enum
+*		[in] Use LFT that was calculated by routing engine, or
+*		current LFT on the switch.
+*
 * RETURN VALUES
 *	Returns the switch port on which the specified LID is routed.
 *
@@ -457,7 +477,8 @@ static inline osm_physp_t *osm_switch_get_route_by_lid(IN const osm_switch_t *
 	CL_ASSERT(p_sw);
 	CL_ASSERT(lid);
 
-	port_num = osm_switch_get_port_by_lid(p_sw, cl_ntoh16(lid));
+	port_num = osm_switch_get_port_by_lid(p_sw, cl_ntoh16(lid),
+					      OSM_NEW_LFT);
 
 	/*
 	   In order to avoid holes in the subnet (usually happens when
@@ -921,7 +942,8 @@ uint8_t osm_switch_recommend_path(IN const osm_switch_t * p_sw,
 				  IN boolean_t routing_for_lmc,
 				  IN boolean_t dor,
 				  IN boolean_t port_shifting,
-				  IN uint32_t scatter_ports);
+				  IN uint32_t scatter_ports,
+				  IN osm_lft_type_enum lft_enum);
 /*
 * PARAMETERS
 *	p_sw
@@ -963,6 +985,10 @@ uint8_t osm_switch_recommend_path(IN const osm_switch_t * p_sw,
 * 	scatter_ports
 * 		[in] If not zero, randomize the selection of the best ports.
 *
+* 	lft_enum
+*		[in] Use LFT that was calculated by routing engine, or
+*		current LFT on the switch.
+*
 * RETURN VALUE
 *	Returns the recommended port on which to route this LID.
 *
diff --git a/include/opensm/osm_version.h b/include/opensm/osm_version.h
index c5d4a78..8a27a00 100644
--- a/include/opensm/osm_version.h
+++ b/include/opensm/osm_version.h
@@ -45,7 +45,7 @@
 *
 * SYNOPSIS
 */
-#define OSM_VERSION "OpenSM 3.3.19"
+#define OSM_VERSION "OpenSM 3.3.20"
 /********/
 
 #endif				/* _OSM_VERSION_H_ */
diff --git a/libvendor/libosmvendor.ver b/libvendor/libosmvendor.ver
index 1b8a6cf..0455aa3 100644
--- a/libvendor/libosmvendor.ver
+++ b/libvendor/libosmvendor.ver
@@ -6,4 +6,4 @@
 # API_REV - advance on any added API
 # RUNNING_REV - advance any change to the vendor files
 # AGE - number of backward versions the API still supports
-LIBVERSION=4:1:0
+LIBVERSION=4:2:0
diff --git a/libvendor/osm_vendor_ibumad_sa.c b/libvendor/osm_vendor_ibumad_sa.c
index 615c58c..30a8864 100644
--- a/libvendor/osm_vendor_ibumad_sa.c
+++ b/libvendor/osm_vendor_ibumad_sa.c
@@ -100,7 +100,7 @@ __osmv_sa_mad_rcv_cb(IN osm_madw_t * p_madw,
 	mad_status = (ib_net16_t) (p_sa_mad->status & IB_SMP_STATUS_MASK);
 	if (mad_status != IB_SUCCESS) {
 		OSM_LOG(p_bind->p_log, OSM_LOG_ERROR, "ERR 5501: "
-			"Remote error:0x%04X\n", cl_ntoh16(mad_status));
+			"Remote error: 0x%04X\n", cl_ntoh16(mad_status));
 		query_res.status = IB_REMOTE_ERROR;
 	} else
 		query_res.status = IB_SUCCESS;
@@ -615,11 +615,11 @@ osmv_query_sa(IN osm_bind_handle_t h_bind,
 		ib_gid_set_default(&u.path_rec.dgid,
 				   ((osmv_guid_pair_t *) (p_query_req->
 							  p_query_input))->
-				   dest_guid);
+							  dest_guid);
 		ib_gid_set_default(&u.path_rec.sgid,
 				   ((osmv_guid_pair_t *) (p_query_req->
 							  p_query_input))->
-				   src_guid);
+							  src_guid);
 		break;
 
 	case OSMV_QUERY_PATH_REC_BY_GIDS:
@@ -632,10 +632,12 @@ osmv_query_sa(IN osm_bind_handle_t h_bind,
 		sa_mad_data.p_attr = &u.path_rec;
 		memcpy(&u.path_rec.dgid,
 		       &((osmv_gid_pair_t *) (p_query_req->p_query_input))->
-		       dest_gid, sizeof(ib_gid_t));
+					      dest_gid,
+		       sizeof(ib_gid_t));
 		memcpy(&u.path_rec.sgid,
 		       &((osmv_gid_pair_t *) (p_query_req->p_query_input))->
-		       src_gid, sizeof(ib_gid_t));
+					      src_gid,
+		       sizeof(ib_gid_t));
 		break;
 
 	case OSMV_QUERY_PATH_REC_BY_LIDS:
@@ -647,8 +649,7 @@ osmv_query_sa(IN osm_bind_handle_t h_bind,
 		    (IB_PR_COMPMASK_DLID | IB_PR_COMPMASK_SLID);
 		sa_mad_data.p_attr = &u.path_rec;
 		u.path_rec.dlid =
-		    ((osmv_lid_pair_t *) (p_query_req->p_query_input))->
-		    dest_lid;
+		    ((osmv_lid_pair_t *) (p_query_req->p_query_input))->dest_lid;
 		u.path_rec.slid =
 		    ((osmv_lid_pair_t *) (p_query_req->p_query_input))->src_lid;
 		break;
diff --git a/man/opensm.8 b/man/opensm.8
index 1618d79..7538d4d 100644
--- a/man/opensm.8
+++ b/man/opensm.8
@@ -37,7 +37,7 @@ opensm \- InfiniBand subnet manager and administration (SM/SA)
 [\-\-maxsmps <number>]
 [\-\-console [off | local | socket | loopback]]
 [\-\-console-port <port>]
-[\-i(gnore-guids) <equalize-ignore-guids-file>]
+[\-i | \-\-ignore_guids <equalize-ignore-guids-file>]
 [\-w | \-\-hop_weights_file <path to file>]
 [\-O | \-\-port_search_ordering_file <path to file>]
 [\-O | \-\-dimn_ports_file <path to file>] (DEPRECATED)
@@ -192,7 +192,7 @@ violate "pure" deadlock free algorithm, so use it carefully.
 .TP
 \fB\-M\fR, \fB\-\-lid_matrix_file\fR <file name>
 This option specifies the name of the lid matrix dump file
-from where switch lid matrices (min hops tables will be
+from where switch lid matrices (min hops tables) will be
 loaded.
 .TP
 \fB\-U\fR, \fB\-\-lfts_file\fR <file name>
@@ -298,7 +298,7 @@ Specify an alternate telnet port for the socket console (default 10000).
 Note that this option only appears if OpenSM was built with
 --enable-console-socket.
 .TP
-\fB\-i\fR, \fB\-\-ignore-guids\fR <equalize-ignore-guids-file>
+\fB\-i\fR, \fB\-\-ignore_guids\fR <equalize-ignore-guids-file>
 This option provides the means to define a set of ports
 (by node guid and port number) that will be ignored by the link load
 equalization algorithm.
@@ -572,13 +572,15 @@ General file format:
 <Partition Definition>:[<newline>]<Partition Properties>;
 
      Partition Definition:
-       [PartitionName][=PKey][,ipoib_bc_flags][,defmember=full|limited]
+       [PartitionName][=PKey][,indx0][,ipoib_bc_flags][,defmember=full|limited]
 
         PartitionName  - string, will be used with logging. When
                          omitted, empty string will be used.
         PKey           - P_Key value for this partition. Only low 15
                          bits will be used. When omitted will be
                          autogenerated.
+        indx0          - indicates that this pkey should be inserted in
+                         block 0 index 0.
         ipoib_bc_flags - used to indicate/specify IPoIB capability of
                          this partition.
 
@@ -987,7 +989,7 @@ port GUID. The latter is supplied by:
 
 -i <equalize-ignore-guids-file>
 .br
-\-\-ignore-guids <equalize-ignore-guids-file>
+\-\-ignore_guids <equalize-ignore-guids-file>
           This option provides the means to define a set of ports
           (by guid) that will be ignored by the link load
           equalization algorithm. Note that only endports (CA,
diff --git a/man/opensm.8.in b/man/opensm.8.in
index c1092cc..e6e5431 100644
--- a/man/opensm.8.in
+++ b/man/opensm.8.in
@@ -37,7 +37,7 @@ opensm \- InfiniBand subnet manager and administration (SM/SA)
 [\-\-maxsmps <number>]
 [\-\-console [off | local | socket | loopback]]
 [\-\-console-port <port>]
-[\-i(gnore-guids) <equalize-ignore-guids-file>]
+[\-i | \-\-ignore_guids <equalize-ignore-guids-file>]
 [\-w | \-\-hop_weights_file <path to file>]
 [\-O | \-\-port_search_ordering_file <path to file>]
 [\-O | \-\-dimn_ports_file <path to file>] (DEPRECATED)
@@ -192,7 +192,7 @@ violate "pure" deadlock free algorithm, so use it carefully.
 .TP
 \fB\-M\fR, \fB\-\-lid_matrix_file\fR <file name>
 This option specifies the name of the lid matrix dump file
-from where switch lid matrices (min hops tables will be
+from where switch lid matrices (min hops tables) will be
 loaded.
 .TP
 \fB\-U\fR, \fB\-\-lfts_file\fR <file name>
@@ -298,7 +298,7 @@ Specify an alternate telnet port for the socket console (default 10000).
 Note that this option only appears if OpenSM was built with
 --enable-console-socket.
 .TP
-\fB\-i\fR, \fB\-\-ignore-guids\fR <equalize-ignore-guids-file>
+\fB\-i\fR, \fB\-\-ignore_guids\fR <equalize-ignore-guids-file>
 This option provides the means to define a set of ports
 (by node guid and port number) that will be ignored by the link load
 equalization algorithm.
@@ -572,13 +572,15 @@ General file format:
 <Partition Definition>:[<newline>]<Partition Properties>;
 
      Partition Definition:
-       [PartitionName][=PKey][,ipoib_bc_flags][,defmember=full|limited]
+       [PartitionName][=PKey][,indx0][,ipoib_bc_flags][,defmember=full|limited]
 
         PartitionName  - string, will be used with logging. When
                          omitted, empty string will be used.
         PKey           - P_Key value for this partition. Only low 15
                          bits will be used. When omitted will be
                          autogenerated.
+        indx0          - indicates that this pkey should be inserted in
+                         block 0 index 0.
         ipoib_bc_flags - used to indicate/specify IPoIB capability of
                          this partition.
 
@@ -987,7 +989,7 @@ port GUID. The latter is supplied by:
 
 -i <equalize-ignore-guids-file>
 .br
-\-\-ignore-guids <equalize-ignore-guids-file>
+\-\-ignore_guids <equalize-ignore-guids-file>
           This option provides the means to define a set of ports
           (by guid) that will be ignored by the link load
           equalization algorithm. Note that only endports (CA,
diff --git a/man/osmtest.8 b/man/osmtest.8
index c999739..ed848b8 100644
--- a/man/osmtest.8
+++ b/man/osmtest.8
@@ -94,13 +94,13 @@ This option displays a menu of possible local port GUID values
 with which osmtest could bind
 .TP
 \fB\-i\fR, \fB\-\-inventory\fR
-This option specifies the name of the inventory file
+This option specifies the name of the inventory file.
 Normally, osmtest expects to find an inventory file,
 which osmtest uses to validate real-time information
 received from the SA during testing
 If -i is not specified, osmtest defaults to the file
 \'osmtest.dat\'
-See -c option for related information
+See -f c option for related information
 .TP
 \fB\-s\fR, \fB\-\-stress\fR
 This option runs the specified stress test instead
diff --git a/opensm.spec b/opensm.spec
index 1f7042d..c010a72 100644
--- a/opensm.spec
+++ b/opensm.spec
@@ -1,4 +1,4 @@
-%define RELEASE 3.3.19
+%define RELEASE 3.3.20
 %define rel %{?CUSTOM_RELEASE}%{!?CUSTOM_RELEASE:%RELEASE}
 %if %{?_with_console_socket:1}%{!?_with_console_socket:0}
 %define _enable_console_socket --enable-console-socket
@@ -27,12 +27,12 @@
 
 Summary: InfiniBand subnet manager and administration
 Name: opensm
-Version: 3.3.19
+Version: 3.3.20
 Release: %rel%{?dist}
 License: GPLv2 or BSD
 Group: System Environment/Daemons
 URL: http://openfabrics.org/
-Source: http://www.openfabrics.org/downloads/management/opensm-3.3.19.tar.gz
+Source: http://www.openfabrics.org/downloads/management/opensm-3.3.20.tar.gz
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 BuildRequires: libibumad-devel, libtool
 Requires: %{name}-libs = %{version}-%{release}, logrotate
diff --git a/opensm/libopensm.ver b/opensm/libopensm.ver
index bf36a78..b456ab5 100644
--- a/opensm/libopensm.ver
+++ b/opensm/libopensm.ver
@@ -6,4 +6,4 @@
 # API_REV - advance on any added API
 # RUNNING_REV - advance any change to the vendor files
 # AGE - number of backward versions the API still supports
-LIBVERSION=7:2:2
+LIBVERSION=7:3:2
diff --git a/opensm/main.c b/opensm/main.c
index 6551a37..8419e68 100644
--- a/opensm/main.c
+++ b/opensm/main.c
@@ -289,7 +289,7 @@ static void show_usage(void)
 	       "          Specify an alternate telnet port for the console (default %d).\n\n",
 	       OSM_DEFAULT_CONSOLE_PORT);
 #endif
-	printf("--ignore-guids, -i <equalize-ignore-guids-file>\n"
+	printf("--ignore_guids, -i <equalize-ignore-guids-file>\n"
 	       "          This option provides the means to define a set of ports\n"
 	       "          (by guid) that will be ignored by the link load\n"
 	       "          equalization algorithm.\n\n");
diff --git a/opensm/osm_congestion_control.c b/opensm/osm_congestion_control.c
index ead1888..bfcd8a5 100644
--- a/opensm/osm_congestion_control.c
+++ b/opensm/osm_congestion_control.c
@@ -479,14 +479,15 @@ static void cc_rcv_mad(void *context, void *data)
 	p_port->cc_timeout_count = 0;
 
 	if (p_cc_mad->header.status) {
-		if (p_cc_mad->header.status & IB_MAD_STATUS_UNSUP_METHOD
+		if (p_cc_mad->header.status & IB_MAD_STATUS_UNSUP_CLASS_VER
+		    || p_cc_mad->header.status & IB_MAD_STATUS_UNSUP_METHOD
 		    || p_cc_mad->header.status & IB_MAD_STATUS_UNSUP_METHOD_ATTR)
-			p_port->cc_unavailable_flag = 1;
+			p_port->cc_unavailable_flag = TRUE;
 		cl_plock_release(&p_osm->lock);
 		goto Exit;
 	}
 	else
-		p_port->cc_unavailable_flag = 0;
+		p_port->cc_unavailable_flag = FALSE;
 
 	if (p_cc_mad->header.attr_id == IB_MAD_ATTR_SW_CONG_SETTING) {
 		ib_sw_cong_setting_t *p_sw_cong_setting;
@@ -704,8 +705,10 @@ static void cc_mad_send_err_callback(void *bind_context,
 	if (p_madw->status == IB_TIMEOUT) {
 		p_port->cc_timeout_count++;
 		if (p_port->cc_timeout_count > OSM_CC_TIMEOUT_COUNT_THRESHOLD
-		    && !p_port->cc_unavailable_flag)
-			p_port->cc_unavailable_flag++;
+		    && !p_port->cc_unavailable_flag) {
+			p_port->cc_unavailable_flag = TRUE;
+			p_port->cc_timeout_count = 0;
+		}
 	} else
 		p_cc->subn->subnet_initialization_error = TRUE;
 
diff --git a/opensm/osm_console.c b/opensm/osm_console.c
index b2bd9d6..0f68afe 100644
--- a/opensm/osm_console.c
+++ b/opensm/osm_console.c
@@ -482,32 +482,32 @@ static void print_status(osm_opensm_t * p_osm, FILE * out)
 #endif
 		fprintf(out, "\n   MAD stats\n"
 			"   ---------\n"
-			"   QP0 MADs outstanding           : %d\n"
-			"   QP0 MADs outstanding (on wire) : %d\n"
-			"   QP0 MADs rcvd                  : %d\n"
-			"   QP0 MADs sent                  : %d\n"
-			"   QP0 unicasts sent              : %d\n"
-			"   QP0 unknown MADs rcvd          : %d\n"
-			"   SA MADs outstanding            : %d\n"
-			"   SA MADs rcvd                   : %d\n"
-			"   SA MADs sent                   : %d\n"
-			"   SA unknown MADs rcvd           : %d\n"
-			"   SA MADs ignored                : %d\n",
-			p_osm->stats.qp0_mads_outstanding,
-			p_osm->stats.qp0_mads_outstanding_on_wire,
-			p_osm->stats.qp0_mads_rcvd,
-			p_osm->stats.qp0_mads_sent,
-			p_osm->stats.qp0_unicasts_sent,
-			p_osm->stats.qp0_mads_rcvd_unknown,
-			p_osm->stats.sa_mads_outstanding,
-			p_osm->stats.sa_mads_rcvd,
-			p_osm->stats.sa_mads_sent,
-			p_osm->stats.sa_mads_rcvd_unknown,
-			p_osm->stats.sa_mads_ignored);
+			"   QP0 MADs outstanding           : %u\n"
+			"   QP0 MADs outstanding (on wire) : %u\n"
+			"   QP0 MADs rcvd                  : %u\n"
+			"   QP0 MADs sent                  : %u\n"
+			"   QP0 unicasts sent              : %u\n"
+			"   QP0 unknown MADs rcvd          : %u\n"
+			"   SA MADs outstanding            : %u\n"
+			"   SA MADs rcvd                   : %u\n"
+			"   SA MADs sent                   : %u\n"
+			"   SA unknown MADs rcvd           : %u\n"
+			"   SA MADs ignored                : %u\n",
+			(uint32_t)p_osm->stats.qp0_mads_outstanding,
+			(uint32_t)p_osm->stats.qp0_mads_outstanding_on_wire,
+			(uint32_t)p_osm->stats.qp0_mads_rcvd,
+			(uint32_t)p_osm->stats.qp0_mads_sent,
+			(uint32_t)p_osm->stats.qp0_unicasts_sent,
+			(uint32_t)p_osm->stats.qp0_mads_rcvd_unknown,
+			(uint32_t)p_osm->stats.sa_mads_outstanding,
+			(uint32_t)p_osm->stats.sa_mads_rcvd,
+			(uint32_t)p_osm->stats.sa_mads_sent,
+			(uint32_t)p_osm->stats.sa_mads_rcvd_unknown,
+			(uint32_t)p_osm->stats.sa_mads_ignored);
 		fprintf(out, "\n   Subnet flags\n"
 			"   ------------\n"
 			"   Sweeping enabled               : %d\n"
-			"   Sweep interval (seconds)       : %d\n"
+			"   Sweep interval (seconds)       : %u\n"
 			"   Ignore existing lfts           : %d\n"
 			"   Subnet Init errors             : %d\n"
 			"   In sweep hop 0                 : %d\n"
@@ -1069,7 +1069,8 @@ static void switchbalance_check(osm_opensm_t * p_osm,
 			continue;
 
 		for (lid_ho = min_lid_ho; lid_ho <= max_lid_ho; lid_ho++) {
-			port_num = osm_switch_get_port_by_lid(p_sw, lid_ho);
+			port_num = osm_switch_get_port_by_lid(p_sw, lid_ho,
+							      OSM_NEW_LFT);
 			if (port_num == OSM_NO_PATH)
 				continue;
 
@@ -1219,7 +1220,8 @@ static void lidbalance_check(osm_opensm_t * p_osm,
 			boolean_t rem_node_found = FALSE;
 			unsigned int indx = 0;
 
-			port_num = osm_switch_get_port_by_lid(p_sw, lid_ho);
+			port_num = osm_switch_get_port_by_lid(p_sw, lid_ho,
+							      OSM_NEW_LFT);
 			if (port_num == OSM_NO_PATH)
 				continue;
 
diff --git a/opensm/osm_drop_mgr.c b/opensm/osm_drop_mgr.c
index 8441f89..f7ff0c1 100644
--- a/opensm/osm_drop_mgr.c
+++ b/opensm/osm_drop_mgr.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
- * Copyright (c) 2002-2012 Mellanox Technologies LTD. All rights reserved.
+ * Copyright (c) 2002-2015 Mellanox Technologies LTD. All rights reserved.
  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
  * Copyright (c) 2008 Xsigo Systems Inc.  All rights reserved.
  * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
@@ -115,7 +115,8 @@ static void drop_mgr_clean_physp(osm_sm_t * sm, IN osm_physp_t * p_physp)
 			   the remote port, since it is no longer reachable.
 			   This can be done if we reset the discovery count
 			   of the remote port. */
-			if (!p_remote_physp->p_node->sw) {
+			if (!p_remote_physp->p_node->sw &&
+                            p_remote_physp->port_guid != sm->p_subn->sm_port_guid) {
 				p_remote_port->discovery_count = 0;
 				OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
 					"Resetting discovery count of node: "
@@ -144,6 +145,9 @@ static void drop_mgr_clean_physp(osm_sm_t * sm, IN osm_physp_t * p_physp)
 
 	}
 
+	/* Make port as undiscovered */
+	p_physp->p_node->physp_discovered[p_physp->port_num] = 0;
+
 	OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
 		"Clearing node 0x%016" PRIx64 " physical port number %u\n",
 		cl_ntoh64(osm_node_get_node_guid(p_physp->p_node)),
@@ -187,12 +191,12 @@ static void drop_mgr_remove_port(osm_sm_t * sm, IN osm_port_t * p_port)
 		goto Exit;
 	}
 
-	/* issue a notice - trap 65 */
+	/* issue a notice - trap 65 (SM_GID_OUT_OF_SERVICE_TRAP) */
 	/* details of the notice */
-	notice.generic_type = 0x83;	/* is generic subn mgt type */
+	notice.generic_type = 0x80 | IB_NOTICE_TYPE_SUBN_MGMT;	/* is generic subn mgt type */
 	ib_notice_set_prod_type_ho(&notice, 4);	/* A class manager generator */
 	/* endport ceases to be reachable */
-	notice.g_or_v.generic.trap_num = CL_HTON16(65);
+	notice.g_or_v.generic.trap_num = CL_HTON16(SM_GID_OUT_OF_SERVICE_TRAP); /* 65 */
 	/* The sm_base_lid is saved in network order already. */
 	notice.issuer_lid = sm->p_subn->sm_base_lid;
 	/* following C14-72.1.2 and table 119 p725 */
@@ -382,7 +386,7 @@ static boolean_t drop_mgr_process_node(osm_sm_t * sm, IN osm_node_t * p_node)
 	return return_val;
 }
 
-static void drop_mgr_check_node(osm_sm_t * sm, IN osm_node_t * p_node)
+static void drop_mgr_check_switch_node(osm_sm_t * sm, IN osm_node_t * p_node)
 {
 	ib_net64_t node_guid;
 	osm_physp_t *p_physp, *p_remote_physp;
@@ -395,13 +399,6 @@ static void drop_mgr_check_node(osm_sm_t * sm, IN osm_node_t * p_node)
 
 	node_guid = osm_node_get_node_guid(p_node);
 
-	if (osm_node_get_type(p_node) != IB_NODE_TYPE_SWITCH) {
-		OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0107: "
-			"Node 0x%016" PRIx64 " is not a switch node\n",
-			cl_ntoh64(node_guid));
-		goto Exit;
-	}
-
 	/* Make sure we have a switch object for this node */
 	if (!p_node->sw) {
 		/* We do not have switch info for this node */
@@ -586,7 +583,7 @@ void osm_drop_mgr_process(osm_sm_t * sm)
 			continue;
 
 		/* We are handling a switch node */
-		drop_mgr_check_node(sm, p_node);
+		drop_mgr_check_switch_node(sm, p_node);
 	}
 
 	p_next_port = (osm_port_t *) cl_qmap_head(p_port_guid_tbl);
diff --git a/opensm/osm_dump.c b/opensm/osm_dump.c
index 8da4279..84334bc 100644
--- a/opensm/osm_dump.c
+++ b/opensm/osm_dump.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2009 Sun Microsystems, Inc. All rights reserved.
  * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
- * Copyright (c) 2002-2011 Mellanox Technologies LTD. All rights reserved.
+ * Copyright (c) 2002-2015 Mellanox Technologies LTD. All rights reserved.
  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
  *
  * This software is available to you under a choice of one of two
@@ -149,7 +149,8 @@ static void dump_ucast_routes(cl_map_item_t * item, FILE * file, void *cxt)
 			continue;
 		}
 
-		port_num = osm_switch_get_port_by_lid(p_sw, lid_ho);
+		port_num = osm_switch_get_port_by_lid(p_sw, lid_ho,
+						      OSM_NEW_LFT);
 		if (port_num == OSM_NO_PATH) {
 			/*
 			   This may occur if there are 'holes' in the existing
@@ -225,7 +226,8 @@ static void dump_ucast_routes(cl_map_item_t * item, FILE * file, void *cxt)
 							      lid_ho, 1, TRUE,
 							      FALSE, dor,
 							      p_osm->subn.opt.port_shifting,
-							      p_osm->subn.opt.scatter_ports);
+							      p_osm->subn.opt.scatter_ports,
+							      OSM_NEW_LFT);
 			fprintf(file, "No %u hop path possible via port %u!",
 				best_hops, best_port);
 		}
@@ -342,7 +344,7 @@ static void dump_ucast_lfts(cl_map_item_t * item, FILE * file, void *cxt)
 		cl_ntoh64(osm_node_get_node_guid(p_node)), p_node->print_desc);
 	for (lid = 0; lid <= max_lid; lid++) {
 		osm_port_t *p_port;
-		port = osm_switch_get_port_by_lid(p_sw, lid);
+		port = osm_switch_get_port_by_lid(p_sw, lid, OSM_NEW_LFT);
 
 		if (port >= max_port)
 			continue;
@@ -511,7 +513,7 @@ static void dump_sl2vl_tbl(cl_map_item_t * item, FILE * file, void *cxt)
 			p_physp = osm_node_get_physp_ptr(p_node, out_port);
 
 			/* no need to print SL2VL table for port that is down */
-			if (!p_physp->p_remote_physp)
+			if (!p_physp || !p_physp->p_remote_physp)
 				continue;
 
 			for (in_port = 0; in_port <= num_ports; in_port++) {
diff --git a/opensm/osm_helper.c b/opensm/osm_helper.c
index 8e6f525..9f63aaf 100644
--- a/opensm/osm_helper.c
+++ b/opensm/osm_helper.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
- * Copyright (c) 2002-2011 Mellanox Technologies LTD. All rights reserved.
+ * Copyright (c) 2002-2015 Mellanox Technologies LTD. All rights reserved.
  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
  * Copyright (c) 2009 HNR Consulting. All rights reserved.
  * Copyright (c) 2009 Sun Microsystems, Inc. All rights reserved.
@@ -526,38 +526,38 @@ const char *ib_get_sa_attr_str(IN ib_net16_t attr)
 const char *ib_get_trap_str(ib_net16_t trap_num)
 {
 	switch (cl_ntoh16(trap_num)) {
-	case 64:
+	case SM_GID_IN_SERVICE_TRAP:	/* 64 */
 		return "GID in service";
-	case 65:
+	case SM_GID_OUT_OF_SERVICE_TRAP: /* 65 */
 		return "GID out of service";
-	case 66:
+	case SM_MGID_CREATED_TRAP:	/* 66 */
 		return "New mcast group created";
-	case 67:
+	case SM_MGID_DESTROYED_TRAP:	/* 67 */
 		return "Mcast group deleted";
-	case 68:
+	case SM_UNPATH_TRAP:		/* 68 */
 		return "UnPath, Path no longer valid";
-	case 69:
+	case SM_REPATH_TRAP:		/* 69 */
 		return "RePath, Path recomputed";
-	case 128:
+	case SM_LINK_STATE_CHANGED_TRAP: /* 128 */
 		return "Link state change";
-	case 129:
+	case SM_LINK_INTEGRITY_THRESHOLD_TRAP: /* 129 */
 		return "Local Link integrity threshold reached";
-	case 130:
+	case SM_BUFFER_OVERRUN_THRESHOLD_TRAP: /* 130 */
 		return "Excessive Buffer Overrun Threshold reached";
-	case 131:
+	case SM_WATCHDOG_TIMER_EXPIRED_TRAP:   /* 131 */
 		return "Flow Control Update watchdog timer expired";
-	case 144:
+	case SM_LOCAL_CHANGES_TRAP:	/* 144 */
 		return
 		    "CapabilityMask, NodeDescription, Link [Width|Speed] Enabled, SM priority changed";
-	case 145:
+	case SM_SYS_IMG_GUID_CHANGED_TRAP: /* 145 */
 		return "System Image GUID changed";
-	case 256:
+	case SM_BAD_MKEY_TRAP:		/* 256 */
 		return "Bad M_Key";
-	case 257:
+	case SM_BAD_PKEY_TRAP:		/* 257 */
 		return "Bad P_Key";
-	case 258:
+	case SM_BAD_QKEY_TRAP:		/* 258 */
 		return "Bad Q_Key";
-	case 259:
+	case SM_BAD_SWITCH_PKEY_TRAP:	/* 259 */
 		return "Bad P_Key (switch external port)";
 	default:
 		break;
@@ -2369,24 +2369,24 @@ static void osm_dump_notice_to_buf_generic(IN const ib_mad_notice_attr_t * p_ntc
 
 		/* immediate data based on the trap */
 		switch (cl_ntoh16(p_ntci->g_or_v.generic.trap_num)) {
-		case 64:
-		case 65:
-		case 66:
-		case 67:
+		case SM_GID_IN_SERVICE_TRAP:	/* 64 */
+		case SM_GID_OUT_OF_SERVICE_TRAP: /* 65 */
+		case SM_MGID_CREATED_TRAP:	/* 66 */
+		case SM_MGID_DESTROYED_TRAP:	/* 67 */
 			sprintf(buff,
 				"\t\t\t\tsrc_gid..................%s\n",
 				inet_ntop(AF_INET6, p_ntci->data_details.
 					  ntc_64_67.gid.raw, gid_str,
 					  sizeof gid_str));
 			break;
-		case 128:
+		case SM_LINK_STATE_CHANGED_TRAP: /* 128 */
 			sprintf(buff,
 				"\t\t\t\tsw_lid...................%u\n",
 				cl_ntoh16(p_ntci->data_details.ntc_128.sw_lid));
 			break;
-		case 129:
-		case 130:
-		case 131:
+		case SM_LINK_INTEGRITY_THRESHOLD_TRAP: /* 129 */
+		case SM_BUFFER_OVERRUN_THRESHOLD_TRAP: /* 130 */
+		case SM_WATCHDOG_TIMER_EXPIRED_TRAP:   /* 131 */
 			sprintf(buff,
 				"\t\t\t\tlid......................%u\n"
 				"\t\t\t\tport_num.................%u\n",
@@ -2394,7 +2394,7 @@ static void osm_dump_notice_to_buf_generic(IN const ib_mad_notice_attr_t * p_ntc
 					  ntc_129_131.lid),
 				p_ntci->data_details.ntc_129_131.port_num);
 			break;
-		case 144:
+		case SM_LOCAL_CHANGES_TRAP:	/* 144 */
 			sprintf(buff,
 				"\t\t\t\tlid......................%u\n"
 				"\t\t\t\tlocal_changes............%u\n"
@@ -2410,7 +2410,7 @@ static void osm_dump_notice_to_buf_generic(IN const ib_mad_notice_attr_t * p_ntc
 				cl_ntoh16(p_ntci->data_details.ntc_144.
 					  cap_mask2));
 			break;
-		case 145:
+		case SM_SYS_IMG_GUID_CHANGED_TRAP: /* 145 */
 			sprintf(buff,
 				"\t\t\t\tlid......................%u\n"
 				"\t\t\t\tnew_sys_guid.............0x%016"
@@ -2420,7 +2420,7 @@ static void osm_dump_notice_to_buf_generic(IN const ib_mad_notice_attr_t * p_ntc
 				cl_ntoh64(p_ntci->data_details.ntc_145.
 					  new_sys_guid));
 			break;
-		case 256:
+		case SM_BAD_MKEY_TRAP:	/* 256 */
 			n = sprintf(buff,
 				    "\t\t\t\tlid......................%u\n"
 				    "\t\t\t\tdrslid...................%u\n"
@@ -2464,8 +2464,8 @@ static void osm_dump_notice_to_buf_generic(IN const ib_mad_notice_attr_t * p_ntc
 			}
 			snprintf(buff + n, sizeof(buff) - n, "\n");
 			break;
-		case 257:
-		case 258:
+		case SM_BAD_PKEY_TRAP:	/* 257 */
+		case SM_BAD_QKEY_TRAP:	/* 258 */
 			sprintf(buff,
 				"\t\t\t\tlid1.....................%u\n"
 				"\t\t\t\tlid2.....................%u\n"
@@ -2493,7 +2493,7 @@ static void osm_dump_notice_to_buf_generic(IN const ib_mad_notice_attr_t * p_ntc
 					  ntc_257_258.gid2.raw, gid_str2,
 					  sizeof gid_str2));
 			break;
-		case 259:
+		case SM_BAD_SWITCH_PKEY_TRAP:	/* 259 */
 			sprintf(buff,
 				"\t\t\t\tdata_valid...............0x%x\n"
 				"\t\t\t\tlid1.....................%u\n"
@@ -3013,6 +3013,7 @@ const char *osm_get_manufacturer_str(IN uint64_t guid_ho)
 	case OSM_VENDOR_ID_MELLANOX2:
 	case OSM_VENDOR_ID_MELLANOX3:
 	case OSM_VENDOR_ID_MELLANOX4:
+	case OSM_VENDOR_ID_MELLANOX5:
 		return mellanox_str;
 	case OSM_VENDOR_ID_REDSWITCH:
 		return redswitch_str;
diff --git a/opensm/osm_inform.c b/opensm/osm_inform.c
index c6c180a..3b293b9 100644
--- a/opensm/osm_inform.c
+++ b/opensm/osm_inform.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
- * Copyright (c) 2002-2006 Mellanox Technologies LTD. All rights reserved.
+ * Copyright (c) 2002-2015 Mellanox Technologies LTD. All rights reserved.
  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
  * Copyright (c) 2009 HNR Consulting. All rights reserved.
  * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
@@ -104,6 +104,8 @@ static cl_status_t match_inf_rec(IN const cl_list_item_t * p_list_item,
 {
 	osm_infr_t *p_infr_rec = (osm_infr_t *) context;
 	osm_infr_t *p_infr = (osm_infr_t *) p_list_item;
+	ib_inform_info_t *p_ii_rec = &p_infr_rec->inform_record.inform_info;
+	ib_inform_info_t *p_ii = &p_infr->inform_record.inform_info;
 	osm_log_t *p_log = p_infr_rec->sa->p_log;
 	cl_status_t status = CL_NOT_FOUND;
 
@@ -116,86 +118,66 @@ static cl_status_t match_inf_rec(IN const cl_list_item_t * p_list_item,
 	}
 
 	/* if inform_info.gid is not zero, ignore lid range */
-	if (ib_gid_is_notzero(&p_infr_rec->inform_record.inform_info.gid)) {
-		if (memcmp(&p_infr->inform_record.inform_info.gid,
-			   &p_infr_rec->inform_record.inform_info.gid,
-			   sizeof(p_infr->inform_record.inform_info.gid))) {
+	if (ib_gid_is_notzero(&p_ii_rec->gid)) {
+		if (memcmp(&p_ii->gid, &p_ii_rec->gid, sizeof(p_ii->gid))) {
 			OSM_LOG(p_log, OSM_LOG_DEBUG,
 				"Differ by InformInfo.gid\n");
 			goto Exit;
 		}
 	} else {
-		if ((p_infr->inform_record.inform_info.lid_range_begin !=
-		     p_infr_rec->inform_record.inform_info.lid_range_begin) ||
-		    (p_infr->inform_record.inform_info.lid_range_end !=
-		     p_infr_rec->inform_record.inform_info.lid_range_end)) {
+		if ((p_ii->lid_range_begin != p_ii_rec->lid_range_begin) ||
+		    (p_ii->lid_range_end != p_ii_rec->lid_range_end)) {
 			OSM_LOG(p_log, OSM_LOG_DEBUG,
 				"Differ by InformInfo.LIDRange\n");
 			goto Exit;
 		}
 	}
 
-	if (p_infr->inform_record.inform_info.trap_type !=
-	    p_infr_rec->inform_record.inform_info.trap_type) {
+	if (p_ii->trap_type != p_ii_rec->trap_type) {
 		OSM_LOG(p_log, OSM_LOG_DEBUG,
 			"Differ by InformInfo.TrapType\n");
 		goto Exit;
 	}
 
-	if (p_infr->inform_record.inform_info.is_generic !=
-	    p_infr_rec->inform_record.inform_info.is_generic) {
+	if (p_ii->is_generic != p_ii_rec->is_generic) {
 		OSM_LOG(p_log, OSM_LOG_DEBUG,
 			"Differ by InformInfo.IsGeneric\n");
 		goto Exit;
 	}
 
-	if (p_infr->inform_record.inform_info.is_generic) {
-		if (p_infr->inform_record.inform_info.g_or_v.generic.trap_num !=
-		    p_infr_rec->inform_record.inform_info.g_or_v.generic.
-		    trap_num)
+	if (p_ii->is_generic) {
+		if (p_ii->g_or_v.generic.trap_num !=
+		    p_ii_rec->g_or_v.generic.trap_num)
 			OSM_LOG(p_log, OSM_LOG_DEBUG,
 				"Differ by InformInfo.Generic.TrapNumber\n");
-		else if (p_infr->inform_record.inform_info.g_or_v.generic.
-			 qpn_resp_time_val !=
-			 p_infr_rec->inform_record.inform_info.g_or_v.generic.
-			 qpn_resp_time_val)
+		else if (p_ii->g_or_v.generic.qpn_resp_time_val !=
+			 p_ii_rec->g_or_v.generic.qpn_resp_time_val)
 			OSM_LOG(p_log, OSM_LOG_DEBUG,
 				"Differ by InformInfo.Generic.QPNRespTimeVal\n");
-		else if (p_infr->inform_record.inform_info.g_or_v.generic.
-			 node_type_msb !=
-			 p_infr_rec->inform_record.inform_info.g_or_v.generic.
-			 node_type_msb)
+		else if (p_ii->g_or_v.generic.node_type_msb !=
+			 p_ii_rec->g_or_v.generic.node_type_msb)
 			OSM_LOG(p_log, OSM_LOG_DEBUG,
 				"Differ by InformInfo.Generic.NodeTypeMSB\n");
-		else if (p_infr->inform_record.inform_info.g_or_v.generic.
-			 node_type_lsb !=
-			 p_infr_rec->inform_record.inform_info.g_or_v.generic.
-			 node_type_lsb)
+		else if (p_ii->g_or_v.generic.node_type_lsb !=
+			 p_ii_rec->g_or_v.generic.node_type_lsb)
 			OSM_LOG(p_log, OSM_LOG_DEBUG,
 				"Differ by InformInfo.Generic.NodeTypeLSB\n");
 		else
 			status = CL_SUCCESS;
 	} else {
-		if (p_infr->inform_record.inform_info.g_or_v.vend.dev_id !=
-		    p_infr_rec->inform_record.inform_info.g_or_v.vend.dev_id)
+		if (p_ii->g_or_v.vend.dev_id != p_ii_rec->g_or_v.vend.dev_id)
 			OSM_LOG(p_log, OSM_LOG_DEBUG,
 				"Differ by InformInfo.Vendor.DeviceID\n");
-		else if (p_infr->inform_record.inform_info.g_or_v.vend.
-			 qpn_resp_time_val !=
-			 p_infr_rec->inform_record.inform_info.g_or_v.vend.
-			 qpn_resp_time_val)
+		else if (p_ii->g_or_v.vend.qpn_resp_time_val !=
+			 p_ii_rec->g_or_v.vend.qpn_resp_time_val)
 			OSM_LOG(p_log, OSM_LOG_DEBUG,
 				"Differ by InformInfo.Vendor.QPNRespTimeVal\n");
-		else if (p_infr->inform_record.inform_info.g_or_v.vend.
-			 vendor_id_msb !=
-			 p_infr_rec->inform_record.inform_info.g_or_v.vend.
-			 vendor_id_msb)
+		else if (p_ii->g_or_v.vend.vendor_id_msb !=
+			 p_ii_rec->g_or_v.vend.vendor_id_msb)
 			OSM_LOG(p_log, OSM_LOG_DEBUG,
 				"Differ by InformInfo.Vendor.VendorIdMSB\n");
-		else if (p_infr->inform_record.inform_info.g_or_v.vend.
-			 vendor_id_lsb !=
-			 p_infr_rec->inform_record.inform_info.g_or_v.vend.
-			 vendor_id_lsb)
+		else if (p_ii->g_or_v.vend.vendor_id_lsb !=
+			 p_ii_rec->g_or_v.vend.vendor_id_lsb)
 			OSM_LOG(p_log, OSM_LOG_DEBUG,
 				"Differ by InformInfo.Vendor.VendorIdLSB\n");
 		else
@@ -397,11 +379,12 @@ static int is_access_permitted(osm_infr_t *p_infr_rec,
 	osm_port_t *p_src_port;
 	osm_port_t *p_dest_port;
 
-	/* In case of GID_IN(64) or GID_OUT(65) traps the source gid
-	   comparison should be done on the trap source (saved as the gid in the
-	   data details field).
-	   For traps MC_CREATE(66) or MC_DELETE(67) the data details gid is
-	   the MGID. We need to check whether the subscriber has a compatible
+	/* In case of SM_GID_IN_SERVICE_TRAP(64) or SM_GID_OUT_OF_SERVICE_TRAP(65) traps
+	   the source gid comparison should be done on the trap source (saved
+	   as the gid in the data details field).
+	   For traps SM_MGID_CREATED_TRAP(66) or SM_MGID_DESTROYED_TRAP(67)
+	   the data details gid is the MGID.
+	   We need to check whether the subscriber has a compatible
 	   pkey with MC group.
 	   In all other cases the issuer gid is the trap source.
 	*/
diff --git a/opensm/osm_mcast_mgr.c b/opensm/osm_mcast_mgr.c
index 8ed2d8f..be8edb4 100644
--- a/opensm/osm_mcast_mgr.c
+++ b/opensm/osm_mcast_mgr.c
@@ -155,10 +155,11 @@ static void create_mgrp_switch_map(cl_qmap_t * m, cl_qlist_t * port_list)
 		if (port->p_node->sw) {
 			sw = port->p_node->sw;
 			sw->is_mc_member = 1;
-		} else {
+		} else if (port->p_physp->p_remote_physp) {
 			sw = port->p_physp->p_remote_physp->p_node->sw;
 			sw->num_of_mcm++;
-		}
+		} else
+			continue;
 		guid = osm_node_get_node_guid(sw->p_node);
 		if (cl_qmap_get(m, guid) == cl_qmap_end(m))
 			cl_qmap_insert(m, guid, &sw->mgrp_item);
diff --git a/opensm/osm_mcast_tbl.c b/opensm/osm_mcast_tbl.c
index c4a64e2..617fd50 100644
--- a/opensm/osm_mcast_tbl.c
+++ b/opensm/osm_mcast_tbl.c
@@ -242,7 +242,6 @@ boolean_t osm_mcast_tbl_get_block(IN osm_mcast_tbl_t * p_tbl,
 
 	CL_ASSERT(p_tbl);
 	CL_ASSERT(p_block);
-	CL_ASSERT(block_num * IB_MCAST_BLOCK_SIZE <= p_tbl->mft_depth);
 
 	if (block_num > p_tbl->max_block_in_use)
 		return FALSE;
@@ -255,6 +254,8 @@ boolean_t osm_mcast_tbl_get_block(IN osm_mcast_tbl_t * p_tbl,
 		return TRUE;
 	}
 
+	CL_ASSERT(block_num * IB_MCAST_BLOCK_SIZE <= p_tbl->mft_depth);
+
 	mlid_start_ho = (uint16_t) (block_num * IB_MCAST_BLOCK_SIZE);
 
 	for (i = 0; i < IB_MCAST_BLOCK_SIZE; i++)
diff --git a/opensm/osm_multicast.c b/opensm/osm_multicast.c
index 55476ab..f6e3e7d 100644
--- a/opensm/osm_multicast.c
+++ b/opensm/osm_multicast.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
- * Copyright (c) 2002-2012 Mellanox Technologies LTD. All rights reserved.
+ * Copyright (c) 2002-2015 Mellanox Technologies LTD. All rights reserved.
  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
  * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
  *
@@ -143,6 +143,7 @@ osm_mgrp_t *osm_mgrp_new(IN osm_subn_t * subn, IN ib_net16_t mlid,
 	cl_fmap_insert(&subn->mgrp_mgid_tbl, &p_mgrp->mcmember_rec.mgid,
 		       &p_mgrp->map_item);
 
+	subn->p_osm->sa.dirty = TRUE;
 	return p_mgrp;
 }
 
@@ -181,6 +182,8 @@ void osm_mgrp_cleanup(osm_subn_t * subn, osm_mgrp_t * mgrp)
 		mgrp_box_delete(mbox);
 	}
 	free(mgrp);
+
+	subn->p_osm->sa.dirty = TRUE;
 }
 
 static void mgrp_send_notice(osm_subn_t * subn, osm_log_t * log,
@@ -189,7 +192,7 @@ static void mgrp_send_notice(osm_subn_t * subn, osm_log_t * log,
 	ib_mad_notice_attr_t notice;
 	ib_api_status_t status;
 
-	notice.generic_type = 0x83;	/* generic SubnMgt type */
+	notice.generic_type = 0x80 | IB_NOTICE_TYPE_SUBN_MGMT;	/* is generic subn mgt type */
 	ib_notice_set_prod_type_ho(&notice, 4);	/* A Class Manager generator */
 	notice.g_or_v.generic.trap_num = CL_HTON16(num);
 	/* The sm_base_lid is saved in network order already. */
@@ -333,7 +336,7 @@ osm_mcm_port_t *osm_mgrp_add_port(IN osm_subn_t * subn, osm_log_t * log,
 	if ((join_state & IB_JOIN_STATE_FULL) &&
 	    !(prev_join_state & IB_JOIN_STATE_FULL) &&
 	    ++mgrp->full_members == 1)
-		mgrp_send_notice(subn, log, mgrp, 66);
+		mgrp_send_notice(subn, log, mgrp, SM_MGID_CREATED_TRAP); /* 66 */
 
 	subn->p_osm->sa.dirty = TRUE;
 	return mcm_port;
@@ -406,7 +409,7 @@ boolean_t osm_mgrp_remove_port(osm_subn_t * subn, osm_log_t * log, osm_mgrp_t *
 	if ((port_join_state & IB_JOIN_STATE_FULL) &&
 	    !(new_join_state & IB_JOIN_STATE_FULL) &&
 	    --mgrp->full_members == 0) {
-		mgrp_send_notice(subn, log, mgrp, 67);
+		mgrp_send_notice(subn, log, mgrp, SM_MGID_DESTROYED_TRAP); /* 67 */
 		osm_mgrp_cleanup(subn, mgrp);
 		mgrp_deleted = TRUE;
 	}
diff --git a/opensm/osm_node.c b/opensm/osm_node.c
index c2ee7a4..fff5936 100644
--- a/opensm/osm_node.c
+++ b/opensm/osm_node.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
- * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
+ * Copyright (c) 2002-2015 Mellanox Technologies LTD. All rights reserved.
  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
  *
  * This software is available to you under a choice of one of two
@@ -161,9 +161,6 @@ void osm_node_link(IN osm_node_t * p_node, IN uint8_t port_num,
 	osm_physp_t *p_physp;
 	osm_physp_t *p_remote_physp;
 
-	CL_ASSERT(port_num < p_node->physp_tbl_size);
-	CL_ASSERT(remote_port_num < p_remote_node->physp_tbl_size);
-
 	p_physp = osm_node_get_physp_ptr(p_node, port_num);
 	p_remote_physp = osm_node_get_physp_ptr(p_remote_node, remote_port_num);
 
diff --git a/opensm/osm_node_info_rcv.c b/opensm/osm_node_info_rcv.c
index 68f3913..64c9f3d 100644
--- a/opensm/osm_node_info_rcv.c
+++ b/opensm/osm_node_info_rcv.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
- * Copyright (c) 2002-2012 Mellanox Technologies LTD. All rights reserved.
+ * Copyright (c) 2002-2015 Mellanox Technologies LTD. All rights reserved.
  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
  * Copyright (c) 2009 HNR Consulting. All rights reserved.
  *
@@ -82,8 +82,10 @@ static void report_duplicated_guid(IN osm_sm_t * sm, osm_physp_t * p_physp,
 		"Paths are:\n",
 		cl_ntoh64(p_physp->p_node->node_info.node_guid),
 		p_physp->port_num,
-		cl_ntoh64(p_old->p_node->node_info.node_guid), p_old->port_num,
-		cl_ntoh64(p_new->p_node->node_info.node_guid), p_new->port_num);
+		p_old ? cl_ntoh64(p_old->p_node->node_info.node_guid) : 0,
+		p_old ? p_old->port_num : 0,
+		p_new ? cl_ntoh64(p_new->p_node->node_info.node_guid) : 0,
+		p_new ? p_new->port_num : 0);
 
 	osm_dump_dr_path_v2(sm->p_log, osm_physp_get_dr_path_ptr(p_physp),
 			    FILE_ID, OSM_LOG_ERROR);
@@ -103,6 +105,12 @@ static void requery_dup_node_info(IN osm_sm_t * sm, osm_physp_t * p_physp,
 	osm_dr_path_t path;
 	cl_status_t status;
 
+	if (!p_physp->p_remote_physp) {
+		OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0D0D: "
+			"DR path couldn't be extended due to NULL remote physp\n");
+		return;
+	}
+
 	path = *osm_physp_get_dr_path_ptr(p_physp->p_remote_physp);
 	if (osm_dr_path_extend(&path, p_physp->p_remote_physp->port_num)) {
 		OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0D08: "
@@ -173,6 +181,14 @@ static void ni_rcv_set_links(IN osm_sm_t * sm, osm_node_t * p_node,
 	}
 
 	p_physp = osm_node_get_physp_ptr(p_node, port_num);
+	if (!p_physp) {
+		OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR OD0E: "
+			"Failed to find physp for port %d of Node GUID 0x%"
+			PRIx64 "\n", port_num,
+			cl_ntoh64(osm_node_get_node_guid(p_node)));
+		goto _exit;
+	}
+
 	/*
 	 * If the link went UP, after we already discovered it, we shouldn't
 	 * set the link between the ports and resweep.
@@ -206,6 +222,14 @@ static void ni_rcv_set_links(IN osm_sm_t * sm, osm_node_t * p_node,
 		   it is impossible with CAs.
 		 */
 		p_physp = osm_node_get_physp_ptr(p_node, port_num);
+		if (!p_physp) {
+			OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR OD0F: "
+				"Failed to find physp for port %d of Node GUID 0x%"
+				PRIx64 "\n", port_num,
+				cl_ntoh64(osm_node_get_node_guid(p_node)));
+			goto _exit;
+		}
+
 		if (p_ni_context->dup_count > 5) {
 			report_duplicated_guid(sm, p_physp, p_neighbor_node,
 					       p_ni_context->port_num);
@@ -232,6 +256,14 @@ static void ni_rcv_set_links(IN osm_sm_t * sm, osm_node_t * p_node,
 			"node 0x%" PRIx64 ", port number %u\n",
 			cl_ntoh64(osm_node_get_node_guid(p_node)), port_num);
 		p_physp = osm_node_get_physp_ptr(p_node, port_num);
+		if (!p_physp) {
+			OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR OD1D: "
+				"Failed to find physp for port %d of Node GUID 0x%"
+				PRIx64 "\n", port_num,
+				cl_ntoh64(osm_node_get_node_guid(p_node)));
+			goto _exit;
+		}
+
 		osm_dump_dr_path_v2(sm->p_log, osm_physp_get_dr_path_ptr(p_physp),
 				    FILE_ID, OSM_LOG_VERBOSE);
 
@@ -256,12 +288,14 @@ static void ni_rcv_set_links(IN osm_sm_t * sm, osm_node_t * p_node,
 					       p_neighbor_node,
 					       p_ni_context->port_num);
 
-	osm_node_link(p_node, port_num, p_neighbor_node,
-		      p_ni_context->port_num);
-
 	p_physp = osm_node_get_physp_ptr(p_node, port_num);
 	p_remote_physp = osm_node_get_physp_ptr(p_neighbor_node,
 						p_ni_context->port_num);
+	if (!p_physp || !p_remote_physp)
+		goto _exit;
+
+	osm_node_link(p_node, port_num, p_neighbor_node, p_ni_context->port_num);
+
 	osm_db_neighbor_set(sm->p_subn->p_neighbor,
 			    cl_ntoh64(osm_physp_get_port_guid(p_physp)),
 			    port_num,
@@ -295,6 +329,13 @@ static void ni_rcv_get_port_info(IN osm_sm_t * sm, IN osm_node_t * node,
 		mlnx_epi_supported = is_mlnx_ext_port_info_supported(ni->device_id);
 
 	physp = osm_node_get_physp_ptr(node, port);
+	if (!physp) {
+		OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR OD1E: "
+			"Failed to find physp for port %d of Node GUID 0x%"
+			PRIx64 "\n", port,
+			cl_ntoh64(osm_node_get_node_guid(node)));
+		return;
+	}
 
 	context.pi_context.node_guid = osm_node_get_node_guid(node);
 	context.pi_context.port_guid = osm_physp_get_port_guid(physp);
@@ -373,6 +414,13 @@ static void ni_rcv_get_node_desc(IN osm_sm_t * sm, IN osm_node_t * p_node,
 	   knows which node & port are relevant.
 	 */
 	p_physp = osm_node_get_physp_ptr(p_node, port_num);
+	if (!p_physp) {
+		OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR OD1F: "
+			"Failed to find physp for port %d of Node GUID 0x%"
+			PRIx64 "\n", port_num,
+			cl_ntoh64(osm_node_get_node_guid(p_node)));
+		return;
+	}
 
 	osm_req_get_node_desc(sm, p_physp);
 
diff --git a/opensm/osm_opensm.c b/opensm/osm_opensm.c
index 69d2ba6..668cfc3 100644
--- a/opensm/osm_opensm.c
+++ b/opensm/osm_opensm.c
@@ -300,22 +300,24 @@ void osm_opensm_destroy(IN osm_opensm_t * p_osm)
 
 	osm_congestion_control_shutdown(&p_osm->cc);
 
-	/* shut down the SA
-	 * - unbind from QP1 messages
-	 */
-	osm_sa_shutdown(&p_osm->sa);
-
 	/* shut down the SM
 	 * - make sure the SM sweeper thread exited
 	 * - unbind from QP0 messages
 	 */
 	osm_sm_shutdown(&p_osm->sm);
 
+	/* shut down the SA
+	 * - unbind from QP1 messages
+	 */
+	osm_sa_shutdown(&p_osm->sa);
+
 	/* cleanup all messages on VL15 fifo that were not sent yet */
 	osm_vl15_shutdown(&p_osm->vl15, &p_osm->mad_pool);
 
 	/* shut down the dispatcher - so no new messages cross */
 	cl_disp_shutdown(&p_osm->disp);
+	if (p_osm->sa_set_disp_initialized)
+		cl_disp_shutdown(&p_osm->sa_set_disp);
 
 	/* dump SA DB */
 	if ((p_osm->sm.p_subn->sm_state == IB_SMINFO_STATE_MASTER) &&
@@ -345,6 +347,8 @@ void osm_opensm_destroy_finish(IN osm_opensm_t * p_osm)
 	osm_vendor_delete(&p_osm->p_vendor);
 	osm_subn_destroy(&p_osm->subn);
 	cl_disp_destroy(&p_osm->disp);
+	if (p_osm->sa_set_disp_initialized)
+		cl_disp_destroy(&p_osm->sa_set_disp);
 #ifdef HAVE_LIBPTHREAD
 	pthread_cond_destroy(&p_osm->stats.cond);
 	pthread_mutex_destroy(&p_osm->stats.mutex);
@@ -432,6 +436,17 @@ ib_api_status_t osm_opensm_init(IN osm_opensm_t * p_osm,
 	if (status != IB_SUCCESS)
 		goto Exit;
 
+	/* Unless OpenSM runs in single threaded mode, we create new single
+	 * threaded dispatcher for SA Set and Delete requets.
+	 */
+	p_osm->sa_set_disp_initialized = FALSE;
+	if (!p_opt->single_thread) {
+		status = cl_disp_init(&p_osm->sa_set_disp, 1, "subnadmin_set");
+		if (status != IB_SUCCESS)
+			goto Exit;
+		p_osm->sa_set_disp_initialized = TRUE;
+	}
+
 	/* the DB is in use by subn so init before */
 	status = osm_db_init(&p_osm->db, &p_osm->log);
 	if (status != IB_SUCCESS)
@@ -480,7 +495,9 @@ ib_api_status_t osm_opensm_init_finish(IN osm_opensm_t * p_osm,
 
 	status = osm_sa_init(&p_osm->sm, &p_osm->sa, &p_osm->subn,
 			     p_osm->p_vendor, &p_osm->mad_pool, &p_osm->log,
-			     &p_osm->stats, &p_osm->disp, &p_osm->lock);
+			     &p_osm->stats, &p_osm->disp,
+			     p_opt->single_thread ? NULL : &p_osm->sa_set_disp,
+			     &p_osm->lock);
 	if (status != IB_SUCCESS)
 		goto Exit;
 
diff --git a/opensm/osm_pkey.c b/opensm/osm_pkey.c
index 6b6eefe..ba27194 100644
--- a/opensm/osm_pkey.c
+++ b/opensm/osm_pkey.c
@@ -100,6 +100,7 @@ ib_api_status_t osm_pkey_tbl_init(IN osm_pkey_tbl_t * p_pkey_tbl)
 	p_pkey_tbl->used_blocks = 0;
 	p_pkey_tbl->max_blocks = 0;
 	p_pkey_tbl->rcv_blocks_cnt = 0;
+	p_pkey_tbl->indx0_pkey = 0;
 	return IB_SUCCESS;
 }
 
@@ -573,3 +574,13 @@ Exit:
 	OSM_LOG_EXIT(p_log);
 	return res;
 }
+
+void osm_pkey_tbl_set_indx0_pkey(IN osm_log_t * p_log, IN ib_net16_t pkey,
+				 IN boolean_t full,
+				 OUT osm_pkey_tbl_t * p_pkey_tbl)
+{
+	p_pkey_tbl->indx0_pkey = (full == TRUE) ?
+				 pkey | cl_hton16(0x8000) : pkey;
+	OSM_LOG(p_log, OSM_LOG_DEBUG, "pkey 0x%04x set at indx0\n",
+		cl_ntoh16(p_pkey_tbl->indx0_pkey));
+}
diff --git a/opensm/osm_pkey_mgr.c b/opensm/osm_pkey_mgr.c
index 223b379..4e7ae3e 100644
--- a/opensm/osm_pkey_mgr.c
+++ b/opensm/osm_pkey_mgr.c
@@ -55,6 +55,9 @@
 #include <opensm/osm_partition.h>
 #include <opensm/osm_opensm.h>
 
+static void clear_accum_pkey_index(osm_pkey_tbl_t * p_pkey_tbl,
+				   uint16_t pkey_index);
+
 /*
   The max number of pkeys/pkey blocks for a physical port is located
   in a different place for switch external ports (SwitchInfo) and the
@@ -92,7 +95,6 @@ pkey_mgr_process_physical_port(IN osm_log_t * p_log,
 	osm_node_t *p_node = osm_physp_get_node_ptr(p_physp);
 	osm_pkey_tbl_t *p_pkey_tbl;
 	ib_net16_t *p_orig_pkey;
-	const char *stat = NULL;
 	osm_pending_pkey_t *p_pending;
 
 	p_pkey_tbl = &p_physp->pkeys;
@@ -111,11 +113,9 @@ pkey_mgr_process_physical_port(IN osm_log_t * p_log,
 	else
 		p_orig_pkey = cl_map_get(&p_pkey_tbl->keys,
 					 ib_pkey_get_base(pkey));
+
 	if (!p_orig_pkey) {
 		p_pending->is_new = TRUE;
-		cl_qlist_insert_tail(&p_pkey_tbl->pending,
-				     (cl_list_item_t *) p_pending);
-		stat = "inserted";
 	} else {
 		CL_ASSERT(ib_pkey_get_base(*p_orig_pkey) ==
 			  ib_pkey_get_base(pkey));
@@ -133,14 +133,64 @@ pkey_mgr_process_physical_port(IN osm_log_t * p_log,
 			free(p_pending);
 			return;
 		}
+		if (p_physp->pkeys.indx0_pkey) {
+			/*
+			 * Remove the pkey that should be at index 0 from
+			 * accum pkey if current position is not index 0
+			 */
+			if (((sm->p_subn->opt.allow_both_pkeys &&
+			      pkey == p_physp->pkeys.indx0_pkey) ||
+			     (!sm->p_subn->opt.allow_both_pkeys &&
+			      ib_pkey_get_base(pkey) == ib_pkey_get_base(p_physp->pkeys.indx0_pkey))) &&
+			    (p_pending->block != 0 || p_pending->index != 0)) {
+					p_pending->is_new = TRUE;
+					clear_accum_pkey_index(p_pkey_tbl,
+							       p_pending->block *
+							       IB_NUM_PKEY_ELEMENTS_IN_BLOCK +
+							       p_pending->index);
+			}
+
+			if (p_pending->block == 0 && p_pending->index == 0) {
+				/* Move the pkey away from index 0 */
+				if ((sm->p_subn->opt.allow_both_pkeys &&
+				     pkey != p_physp->pkeys.indx0_pkey) ||
+				    (!sm->p_subn->opt.allow_both_pkeys &&
+				     ib_pkey_get_base(pkey) != ib_pkey_get_base(p_physp->pkeys.indx0_pkey))) {
+					p_pending->is_new = TRUE;
+					clear_accum_pkey_index(p_pkey_tbl, 0);
+				}
+			}
+		 } else {
+			/* If index 0 is occupied by non-default, it should reoccupied by pkey 0x7FFF */
+			if (p_pending->block == 0 && p_pending->index == 0) {
+				if (ib_pkey_get_base(pkey) != IB_DEFAULT_PARTIAL_PKEY) {
+					p_pending->is_new = TRUE;
+					clear_accum_pkey_index(p_pkey_tbl, 0);
+				}
+			/* Need to move default pkey to index 0 */
+			} else if ((sm->p_subn->opt.allow_both_pkeys &&
+				    pkey == IB_DEFAULT_PKEY) ||
+				   (!sm->p_subn->opt.allow_both_pkeys &&
+				    ib_pkey_get_base(pkey) == IB_DEFAULT_PARTIAL_PKEY)) {
+					p_pending->is_new = TRUE;
+					clear_accum_pkey_index(p_pkey_tbl,
+							       p_pending->block *
+							       IB_NUM_PKEY_ELEMENTS_IN_BLOCK +
+							       p_pending->index);
+			}
+		}
+
+	}
+	if (p_pending->is_new == TRUE)
+		 cl_qlist_insert_tail(&p_pkey_tbl->pending,
+				      (cl_list_item_t *) p_pending);
+	else
 		cl_qlist_insert_head(&p_pkey_tbl->pending,
 				     (cl_list_item_t *) p_pending);
-		stat = "updated";
-	}
 
 	OSM_LOG(p_log, OSM_LOG_DEBUG,
 		"pkey 0x%04x was %s for node 0x%016" PRIx64 " port %u\n",
-		cl_ntoh16(pkey), stat,
+		cl_ntoh16(pkey), p_pending->is_new ? "inserted" : "updated",
 		cl_ntoh64(osm_node_get_node_guid(p_node)),
 		osm_physp_get_port_num(p_physp));
 }
@@ -390,27 +440,62 @@ static int pkey_mgr_update_port(osm_log_t * p_log, osm_sm_t * sm,
 				pkey_idx--; /* adjust pkey index for bias */
 				block_index = pkey_idx / IB_NUM_PKEY_ELEMENTS_IN_BLOCK;
 				pkey_index = pkey_idx % IB_NUM_PKEY_ELEMENTS_IN_BLOCK;
-				found = TRUE;
+
+				if (((sm->p_subn->opt.allow_both_pkeys &&
+				      p_pending->pkey == p_physp->pkeys.indx0_pkey) ||
+				     (!sm->p_subn->opt.allow_both_pkeys &&
+				      ib_pkey_get_base(p_pending->pkey) == ib_pkey_get_base(p_physp->pkeys.indx0_pkey))) ||
+				    ((p_pending->pkey != p_physp->pkeys.indx0_pkey &&
+				      pkey_idx == 0))) {
+					clear_accum_pkey_index(p_pkey_tbl, pkey_idx);
+					cl_qlist_insert_tail(&p_pkey_tbl->pending,
+							     (cl_list_item_t *)p_pending);
+					p_pending =
+                                            (osm_pending_pkey_t *) cl_qlist_remove_head(&p_pkey_tbl->pending);
+					continue;
+				} else
+					found = TRUE;
 			}
 
 			if (!found) {
-				if (last_accum_pkey_index(p_pkey_tbl,
-						      &last_free_block_index,
-						      &last_free_pkey_index)) {
+				if (!p_pkey_tbl->indx0_pkey &&
+				    ((sm->p_subn->opt.allow_both_pkeys &&
+				      p_pending->pkey == IB_DEFAULT_PKEY) ||
+				     (!sm->p_subn->opt.allow_both_pkeys &&
+				      ib_pkey_get_base(p_pending->pkey) == IB_DEFAULT_PARTIAL_PKEY))) {
+					block_index = 0;
+					pkey_index = 0;
+				} else if ((sm->p_subn->opt.allow_both_pkeys &&
+					    p_pending->pkey == p_pkey_tbl->indx0_pkey) ||
+					   (!sm->p_subn->opt.allow_both_pkeys &&
+					    ib_pkey_get_base(p_pending->pkey) ==
+					    ib_pkey_get_base(p_pkey_tbl->indx0_pkey))) {
+					block_index = 0;
+					pkey_index = 0;
+				} else if (last_accum_pkey_index(p_pkey_tbl,
+								 &last_free_block_index,
+								 &last_free_pkey_index)) {
 					block_index = last_free_block_index;
 					pkey_index = last_free_pkey_index + 1;
+					if (pkey_index >= IB_NUM_PKEY_ELEMENTS_IN_BLOCK) {
+						block_index++;
+						pkey_index -= IB_NUM_PKEY_ELEMENTS_IN_BLOCK;
+					}
 				} else {
 					block_index = 0;
-					pkey_index = 0;
-				}
-				if (pkey_index >= IB_NUM_PKEY_ELEMENTS_IN_BLOCK) {
-					block_index++;
-					pkey_index -= IB_NUM_PKEY_ELEMENTS_IN_BLOCK;
+					pkey_index = 1;
 				}
+
 				if (block_index * IB_NUM_PKEY_ELEMENTS_IN_BLOCK + pkey_index >= pkey_mgr_get_physp_max_pkeys(p_physp)) {
-					last_free_block_index = 0;
-					last_free_pkey_index = 0;
-					found = osm_pkey_find_next_free_entry(p_pkey_tbl, &last_free_block_index, &last_free_pkey_index);
+					if ((sm->p_subn->opt.allow_both_pkeys &&
+					     p_pending->pkey != IB_DEFAULT_PKEY) ||
+					    (!sm->p_subn->opt.allow_both_pkeys &&
+					     ib_pkey_get_base(p_pending->pkey) != IB_DEFAULT_PARTIAL_PKEY)) {
+						last_free_block_index = 0;
+						last_free_pkey_index = 1;
+						found = osm_pkey_find_next_free_entry(p_pkey_tbl, &last_free_block_index, &last_free_pkey_index);
+					} else
+						found = FALSE;
 					if (!found)
 						full = 1;
 					else {
@@ -478,13 +563,13 @@ static int pkey_mgr_update_port(osm_log_t * p_log, osm_sm_t * sm,
 					p_physp->p_node->print_desc);
 			}
 		}
-
 		free(p_pending);
 		p_pending =
 		    (osm_pending_pkey_t *) cl_qlist_remove_head(&p_pkey_tbl->
 								pending);
 	}
 
+	p_pkey_tbl->indx0_pkey = 0;
 	/* now look for changes and store */
 	for (block_index = 0; block_index < num_of_blocks; block_index++) {
 		block = osm_pkey_tbl_block_get(p_pkey_tbl, block_index);
diff --git a/opensm/osm_port.c b/opensm/osm_port.c
index ae74ba6..35010e3 100644
--- a/opensm/osm_port.c
+++ b/opensm/osm_port.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
- * Copyright (c) 2002-2010 Mellanox Technologies LTD. All rights reserved.
+ * Copyright (c) 2002-2015 Mellanox Technologies LTD. All rights reserved.
  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
  *
  * This software is available to you under a choice of one of two
@@ -161,6 +161,9 @@ osm_port_t *osm_port_new(IN const ib_node_info_t * p_ni,
 	   only the singular part that has this GUID is owned.
 	 */
 	p_physp = osm_node_get_physp_ptr(p_parent_node, port_num);
+	if (!p_physp)
+		return NULL;
+
 	CL_ASSERT(port_guid == osm_physp_get_port_guid(p_physp));
 	p_port->p_physp = p_physp;
 
diff --git a/opensm/osm_port_info_rcv.c b/opensm/osm_port_info_rcv.c
index 934a543..94f53eb 100644
--- a/opensm/osm_port_info_rcv.c
+++ b/opensm/osm_port_info_rcv.c
@@ -117,8 +117,8 @@ static void pi_rcv_process_endport(IN osm_sm_t * sm, IN osm_physp_t * p_physp,
 		}
 
 		data_vls = 1U << (ib_port_info_get_vl_cap(p_pi) - 1);
-		if (data_vls > sm->p_subn->opt.max_op_vls)
-			data_vls = sm->p_subn->opt.max_op_vls;
+		if (data_vls > 1U << (sm->p_subn->opt.max_op_vls - 1))
+			data_vls = 1U << (sm->p_subn->opt.max_op_vls - 1);
 		if (data_vls >= IB_MAX_NUM_VLS)
 			data_vls = IB_MAX_NUM_VLS - 1;
 		if ((uint8_t)data_vls < sm->p_subn->min_data_vls) {
@@ -213,6 +213,21 @@ static void pi_rcv_process_switch_port0(IN osm_sm_t * sm,
 
 	OSM_LOG_ENTER(sm->p_log);
 
+	if (p_physp->need_update)
+		sm->p_subn->ignore_existing_lfts = TRUE;
+
+	pi_rcv_check_and_fix_lid(sm->p_log, p_pi, p_physp);
+
+	/* Update the PortInfo attribute */
+	osm_physp_set_port_info(p_physp, p_pi, sm);
+
+	/* Determine if base switch port 0 */
+	if (p_node->sw &&
+	    !ib_switch_info_is_enhanced_port0(&p_node->sw->switch_info))
+		/* PortState is not used on BSP0 but just in case it is DOWN */
+		p_physp->port_info = *p_pi;
+
+	/* Now, query PortInfo for the switch external ports */
 	num_ports = osm_node_get_num_physp(p_node);
 
 	context.pi_context.node_guid = osm_node_get_node_guid(p_node);
@@ -234,21 +249,6 @@ static void pi_rcv_process_switch_port0(IN osm_sm_t * sm,
 				ib_get_err_str(status));
 	}
 
-	if (p_physp->need_update)
-		sm->p_subn->ignore_existing_lfts = TRUE;
-
-	pi_rcv_check_and_fix_lid(sm->p_log, p_pi, p_physp);
-
-	/*
-	   Update the PortInfo attribute.
-	 */
-	osm_physp_set_port_info(p_physp, p_pi, sm);
-
-	/* Determine if base switch port 0 */
-	if (p_node->sw &&
-	    !ib_switch_info_is_enhanced_port0(&p_node->sw->switch_info))
-		/* PortState is not used on BSP0 but just in case it is DOWN */
-		p_physp->port_info = *p_pi;
 	pi_rcv_process_endport(sm, p_physp, p_pi);
 	OSM_LOG_EXIT(sm->p_log);
 }
@@ -287,62 +287,62 @@ static void pi_rcv_process_switch_ext_port(IN osm_sm_t * sm,
 	/* if in_sweep_hop_0 is TRUE, then this means the SM is on the switch,
 	   and we got switchInfo of our local switch. Do not continue
 	   probing through the switch. */
-	if (sm->p_subn->in_sweep_hop_0 == FALSE) {
-		switch (ib_port_info_get_port_state(p_pi)) {
-		case IB_LINK_DOWN:
-			p_remote_physp = osm_physp_get_remote(p_physp);
-			if (p_remote_physp) {
-				p_remote_node =
-				    osm_physp_get_node_ptr(p_remote_physp);
-				remote_port_num =
-				    osm_physp_get_port_num(p_remote_physp);
+	switch (ib_port_info_get_port_state(p_pi)) {
+	case IB_LINK_DOWN:
+		p_remote_physp = osm_physp_get_remote(p_physp);
+		if (p_remote_physp) {
+			p_remote_node =
+			    osm_physp_get_node_ptr(p_remote_physp);
+			remote_port_num =
+			    osm_physp_get_port_num(p_remote_physp);
 
-				OSM_LOG(sm->p_log, OSM_LOG_VERBOSE,
-					"Unlinking local node 0x%" PRIx64
-					", port %u"
-					"\n\t\t\t\tand remote node 0x%" PRIx64
-					", port %u\n",
-					cl_ntoh64(osm_node_get_node_guid
-						  (p_node)), port_num,
-					cl_ntoh64(osm_node_get_node_guid
-						  (p_remote_node)),
-					remote_port_num);
-
-				if (sm->ucast_mgr.cache_valid)
-					osm_ucast_cache_add_link(&sm->ucast_mgr,
-								 p_physp,
-								 p_remote_physp);
-
-				osm_node_unlink(p_node, (uint8_t) port_num,
-						p_remote_node,
-						(uint8_t) remote_port_num);
+			OSM_LOG(sm->p_log, OSM_LOG_VERBOSE,
+				"Unlinking local node 0x%" PRIx64
+				", port %u"
+				"\n\t\t\t\tand remote node 0x%" PRIx64
+				", port %u\n",
+				cl_ntoh64(osm_node_get_node_guid
+					  (p_node)), port_num,
+				cl_ntoh64(osm_node_get_node_guid
+					  (p_remote_node)),
+				remote_port_num);
+
+			if (sm->ucast_mgr.cache_valid)
+				osm_ucast_cache_add_link(&sm->ucast_mgr,
+							 p_physp,
+							 p_remote_physp);
+
+			osm_node_unlink(p_node, (uint8_t) port_num,
+					p_remote_node,
+					(uint8_t) remote_port_num);
 
-			}
-			break;
+		}
+		break;
 
-		case IB_LINK_INIT:
-		case IB_LINK_ARMED:
-		case IB_LINK_ACTIVE:
-			physp0 = osm_node_get_physp_ptr(p_node, 0);
-			if (mlnx_epi_supported) {
-				m_key = ib_port_info_get_m_key(&physp0->port_info);
-
-				context.pi_context.node_guid = osm_node_get_node_guid(p_node);
-				context.pi_context.port_guid = osm_physp_get_port_guid(p_physp);
-				context.pi_context.set_method = FALSE;
-				context.pi_context.light_sweep = FALSE;
-				context.pi_context.active_transition = FALSE;
-				context.pi_context.client_rereg = FALSE;
-				status = osm_req_get(sm,
-						     osm_physp_get_dr_path_ptr(p_physp),
-						     IB_MAD_ATTR_MLNX_EXTENDED_PORT_INFO,
-						     cl_hton32(port_num), FALSE, m_key,
-						     CL_DISP_MSGID_NONE, &context);
-				if (status != IB_SUCCESS)
-					OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0F11: "
-						"Failure initiating MLNX ExtPortInfo request (%s)\n",
-						ib_get_err_str(status));
-		        }
+	case IB_LINK_INIT:
+	case IB_LINK_ARMED:
+	case IB_LINK_ACTIVE:
+		physp0 = osm_node_get_physp_ptr(p_node, 0);
+		if (mlnx_epi_supported) {
+			m_key = ib_port_info_get_m_key(&physp0->port_info);
+
+			context.pi_context.node_guid = osm_node_get_node_guid(p_node);
+			context.pi_context.port_guid = osm_physp_get_port_guid(p_physp);
+			context.pi_context.set_method = FALSE;
+			context.pi_context.light_sweep = FALSE;
+			context.pi_context.active_transition = FALSE;
+			context.pi_context.client_rereg = FALSE;
+			status = osm_req_get(sm,
+					     osm_physp_get_dr_path_ptr(p_physp),
+					     IB_MAD_ATTR_MLNX_EXTENDED_PORT_INFO,
+					     cl_hton32(port_num), FALSE, m_key,
+					     CL_DISP_MSGID_NONE, &context);
+			if (status != IB_SUCCESS)
+				OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0F11: "
+					"Failure initiating MLNX ExtPortInfo request (%s)\n",
+					ib_get_err_str(status));
+		}
+		if (sm->p_subn->in_sweep_hop_0 == FALSE) {
 			/*
 			   To avoid looping forever, only probe the port if it
 			   is NOT the port that responded to the SMP.
@@ -388,15 +388,15 @@ static void pi_rcv_process_switch_ext_port(IN osm_sm_t * sm,
 				OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
 					"Skipping SMP responder port %u\n",
 					p_pi->local_port_num);
-			break;
-
-		default:
-			OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0F03: "
-				"Unknown link state = %u, port = %u\n",
-				ib_port_info_get_port_state(p_pi),
-				p_pi->local_port_num);
-			break;
 		}
+		break;
+
+	default:
+		OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0F03: "
+			"Unknown link state = %u, port = %u\n",
+			ib_port_info_get_port_state(p_pi),
+			p_pi->local_port_num);
+		break;
 	}
 
 	if (ib_port_info_get_port_state(p_pi) > IB_LINK_INIT && p_node->sw &&
@@ -420,8 +420,8 @@ static void pi_rcv_process_switch_ext_port(IN osm_sm_t * sm,
 		p_remote_node = osm_physp_get_node_ptr(p_remote_physp);
 		if (p_remote_node->sw) {
 			data_vls = 1U << (ib_port_info_get_vl_cap(p_pi) - 1);
-			if (data_vls > sm->p_subn->opt.max_op_vls)
-				data_vls = sm->p_subn->opt.max_op_vls;
+			if (data_vls > 1U << (sm->p_subn->opt.max_op_vls - 1))
+				data_vls = 1U << (sm->p_subn->opt.max_op_vls - 1);
 			if (data_vls >= IB_MAX_NUM_VLS)
 				data_vls = IB_MAX_NUM_VLS - 1;
 			if ((uint8_t)data_vls < sm->p_subn->min_sw_data_vls) {
diff --git a/opensm/osm_prtn.c b/opensm/osm_prtn.c
index 3d47ac0..bc1814d 100644
--- a/opensm/osm_prtn.c
+++ b/opensm/osm_prtn.c
@@ -123,7 +123,7 @@ void osm_prtn_delete(IN osm_subn_t * p_subn, IN OUT osm_prtn_t ** pp_prtn)
 
 ib_api_status_t osm_prtn_add_port(osm_log_t * p_log, osm_subn_t * p_subn,
 				  osm_prtn_t * p, ib_net64_t guid,
-				  boolean_t full)
+				  boolean_t full, boolean_t indx0)
 {
 	ib_api_status_t status = IB_SUCCESS;
 	cl_map_t *p_tbl;
@@ -144,6 +144,16 @@ ib_api_status_t osm_prtn_add_port(osm_log_t * p_log, osm_subn_t * p_subn,
 			cl_ntoh64(guid));
 		return status;
 	}
+	/* Set the pkey to be inserted to block 0 index 0 */
+	if (indx0) {
+		OSM_LOG(p_log, OSM_LOG_VERBOSE, "Setting pkey 0x%04x at indx0 "
+			"for port 0x%" PRIx64 "\n",
+			cl_ntoh16(p->pkey), cl_ntoh64(guid));
+		osm_pkey_tbl_set_indx0_pkey(p_log, p->pkey, full,
+					    &p_physp->pkeys);
+	} else if (ib_pkey_get_base(p_physp->pkeys.indx0_pkey) ==
+		   ib_pkey_get_base(p->pkey))
+		p_physp->pkeys.indx0_pkey = 0;
 
 	p_tbl = (full == TRUE) ? &p->full_guid_tbl : &p->part_guid_tbl;
 
@@ -170,7 +180,8 @@ ib_api_status_t osm_prtn_add_port(osm_log_t * p_log, osm_subn_t * p_subn,
 }
 
 ib_api_status_t osm_prtn_add_all(osm_log_t * p_log, osm_subn_t * p_subn,
-				 osm_prtn_t * p, unsigned type, boolean_t full)
+				 osm_prtn_t * p, unsigned type,
+				 boolean_t full, boolean_t indx0)
 {
 	cl_qmap_t *p_port_tbl = &p_subn->port_guid_tbl;
 	cl_map_item_t *p_item;
@@ -184,7 +195,7 @@ ib_api_status_t osm_prtn_add_all(osm_log_t * p_log, osm_subn_t * p_subn,
 		if (!type || osm_node_get_type(p_port->p_node) == type) {
 			status = osm_prtn_add_port(p_log, p_subn, p,
 						   osm_port_get_guid(p_port),
-						   full);
+						   full, indx0);
 			if (status != IB_SUCCESS)
 				goto _err;
 		}
@@ -204,7 +215,7 @@ track_mgrp_w_partition(osm_log_t *p_log, osm_prtn_t *p, osm_mgrp_t *mgrp,
 	int i = 0;
 
 	/* check if we are already tracking this group */
-	for (i = 0; i< p->nmgrps; i++)
+	for (i = 0; i < p->nmgrps; i++)
 		if (p->mgrps[i] == mgrp)
 			return (IB_SUCCESS);
 
@@ -353,12 +364,12 @@ static ib_api_status_t prtn_make_default(osm_log_t * p_log, osm_subn_t * p_subn,
 			      IB_DEFAULT_PARTIAL_PKEY);
 	if (!p)
 		goto _err;
-	status = osm_prtn_add_all(p_log, p_subn, p, 0, no_config);
+	status = osm_prtn_add_all(p_log, p_subn, p, 0, no_config, FALSE);
 	if (status != IB_SUCCESS)
 		goto _err;
 	cl_map_remove(&p->part_guid_tbl, p_subn->sm_port_guid);
 	status =
-	    osm_prtn_add_port(p_log, p_subn, p, p_subn->sm_port_guid, TRUE);
+	    osm_prtn_add_port(p_log, p_subn, p, p_subn->sm_port_guid, TRUE, FALSE);
 
 	/* ipv4 broadcast group */
 	if (no_config)
diff --git a/opensm/osm_prtn_config.c b/opensm/osm_prtn_config.c
index 100282a..b08da02 100644
--- a/opensm/osm_prtn_config.c
+++ b/opensm/osm_prtn_config.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2006-2008 Voltaire, Inc. All rights reserved.
- * Copyright (c) 2012 Mellanox Technologies LTD. All rights reserved.
+ * Copyright (c) 2012-2015 Mellanox Technologies LTD. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -92,16 +92,18 @@ struct part_conf {
 	unsigned is_ipoib;
 	struct group_flags flags;
 	membership_t membership;
+	boolean_t indx0;
 };
 
 extern osm_prtn_t *osm_prtn_make_new(osm_log_t * p_log, osm_subn_t * p_subn,
 				     const char *name, uint16_t pkey);
 extern ib_api_status_t osm_prtn_add_all(osm_log_t * p_log, osm_subn_t * p_subn,
 					osm_prtn_t * p, unsigned type,
-					boolean_t full);
+					boolean_t full, boolean_t indx0);
 extern ib_api_status_t osm_prtn_add_port(osm_log_t * p_log,
 					 osm_subn_t * p_subn, osm_prtn_t * p,
-					 ib_net64_t guid, boolean_t full);
+					 ib_net64_t guid, boolean_t full,
+					 boolean_t indx0);
 
 ib_api_status_t osm_prtn_add_mcgroup(osm_log_t * p_log, osm_subn_t * p_subn,
 				     osm_prtn_t * p, uint8_t rate, uint8_t mtu,
@@ -123,7 +125,7 @@ static inline boolean_t mgid_is_ip(const ib_gid_t *mgid)
 }
 
 static inline boolean_t ip_mgroup_pkey_ok(struct part_conf *conf,
-				struct precreate_mgroup *group)
+					  struct precreate_mgroup *group)
 {
 	ib_net16_t mpkey = *(ib_net16_t *)&group->mgid.raw[4];
 	char gid_str[INET6_ADDRSTRLEN];
@@ -369,7 +371,9 @@ static int partition_add_flag(unsigned lineno, struct part_conf *conf,
 			else
 				conf->membership = LIMITED;
 		}
-	} else {
+	} else if (!strcmp(flag, "indx0"))
+		conf->indx0 = TRUE;
+	else {
 		OSM_LOG(conf->p_log, OSM_LOG_VERBOSE,
 			"PARSE WARN: line %d: "
 			"unrecognized partition flag \'%s\'"
@@ -377,16 +381,68 @@ static int partition_add_flag(unsigned lineno, struct part_conf *conf,
 	}
 	return 0;
 }
+static void manage_membership_change(struct part_conf *conf, osm_prtn_t * p,
+				     unsigned type, membership_t membership,
+				     ib_net64_t guid)
+{
+	cl_map_t *p_tbl;
+	cl_map_iterator_t p_next, p_item;
+	osm_physp_t *p_physp;
+
+	/* In allow_both_pkeys mode */
+	/* if membership of the PKEY is set to FULL */
+	/* need to clean up the part_guid_tbl table entry for this guid */
+	/* if membership of the PKEY is set to LIMITED */
+	/* need to clean up the full_guid_tbl table entry for this guid */
+	/* as it could be populated because of previous definitions */
+
+	if (!conf->p_subn->opt.allow_both_pkeys || membership == BOTH)
+		return;
+
+	switch (type){
+	/* ALL = 0 */
+	case 0:
+		cl_map_remove_all(membership == LIMITED ?
+				  &p->full_guid_tbl : &p->part_guid_tbl);
+		break;
+	/* specific GUID */
+	case 0xFF:
+		cl_map_remove(membership == LIMITED ?
+			      &p->full_guid_tbl : &p->part_guid_tbl,
+			      cl_hton64(guid));
+		break;
+
+	case IB_NODE_TYPE_CA:
+	case IB_NODE_TYPE_SWITCH:
+	case IB_NODE_TYPE_ROUTER:
+		p_tbl = (membership == LIMITED) ?
+			 &p->full_guid_tbl : &p->part_guid_tbl;
+
+		p_next = cl_map_head(p_tbl);
+		while (p_next != cl_map_end(p_tbl)) {
+			p_item = p_next;
+			p_next = cl_map_next(p_item);
+			p_physp = (osm_physp_t *) cl_map_obj(p_item);
+			if (osm_node_get_type(p_physp->p_node) == type)
+				cl_map_remove_item(p_tbl, p_item);
+		}
+		break;
+	default:
+		break;
 
+	}
+}
 static int partition_add_all(struct part_conf *conf, osm_prtn_t * p,
 			     unsigned type, membership_t membership)
 {
+	manage_membership_change(conf, p, type, membership, 0);
+
 	if (membership != LIMITED &&
-	    osm_prtn_add_all(conf->p_log, conf->p_subn, p, type, TRUE) != IB_SUCCESS)
+	    osm_prtn_add_all(conf->p_log, conf->p_subn, p, type, TRUE, conf->indx0) != IB_SUCCESS)
 		return -1;
 	if ((membership == LIMITED ||
 	     (membership == BOTH && conf->p_subn->opt.allow_both_pkeys)) &&
-	    osm_prtn_add_all(conf->p_log, conf->p_subn, p, type, FALSE) != IB_SUCCESS)
+	    osm_prtn_add_all(conf->p_log, conf->p_subn, p, type, FALSE, conf->indx0) != IB_SUCCESS)
 		return -1;
 	return 0;
 }
@@ -435,14 +491,15 @@ static int partition_add_port(unsigned lineno, struct part_conf *conf,
 			return -1;
 	}
 
+	manage_membership_change(conf, p, 0xFF, membership, guid);
 	if (membership != LIMITED &&
 	    osm_prtn_add_port(conf->p_log, conf->p_subn, p,
-			      cl_hton64(guid), TRUE) != IB_SUCCESS)
+			      cl_hton64(guid), TRUE, conf->indx0) != IB_SUCCESS)
 		return -1;
 	if ((membership == LIMITED ||
 	    (membership == BOTH && conf->p_subn->opt.allow_both_pkeys)) &&
 	    osm_prtn_add_port(conf->p_log, conf->p_subn, p,
-			      cl_hton64(guid), FALSE) != IB_SUCCESS)
+			      cl_hton64(guid), FALSE, conf->indx0) != IB_SUCCESS)
 		return -1;
 	return 0;
 }
@@ -592,6 +649,7 @@ static struct part_conf *new_part_conf(osm_log_t * p_log, osm_subn_t * p_subn)
 	conf->flags.rate = OSM_DEFAULT_MGRP_RATE;
 	conf->flags.mtu = OSM_DEFAULT_MGRP_MTU;
 	conf->membership = LIMITED;
+	conf->indx0 = FALSE;
 	return conf;
 }
 
@@ -708,6 +766,7 @@ int osm_prtn_config_parse_file(osm_log_t * p_log, osm_subn_t * p_subn,
 	int lineno;
 	int is_parse_success;
 
+	line[0] = '\0';
 	file = fopen(file_name, "r");
 	if (!file) {
 		OSM_LOG(p_log, OSM_LOG_VERBOSE,
diff --git a/opensm/osm_qos.c b/opensm/osm_qos.c
index da5638a..b4f6041 100644
--- a/opensm/osm_qos.c
+++ b/opensm/osm_qos.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2006-2009 Voltaire, Inc. All rights reserved.
+ * Copyright (c) 2010-2015 Mellanox Technologies LTD. All rights reserved.
  * Copyright (c) 2009 HNR Consulting. All rights reserved.
  *
  * This software is available to you under a choice of one of two
@@ -312,6 +313,8 @@ static int qos_extports_setup(osm_sm_t * sm, osm_node_t *node,
 
 	for (out = 1; out < num_ports; out++) {
 		p = osm_node_get_physp_ptr(node, out);
+		if (!p)
+			continue;
 		if (ib_port_info_get_port_state(&p->port_info) == IB_LINK_DOWN)
 			continue;
 		force_update = p->need_update || sm->p_subn->need_update;
@@ -334,6 +337,8 @@ static int qos_extports_setup(osm_sm_t * sm, osm_node_t *node,
 
 		for (out = 1; out < num_ports; out++) {
 			p = osm_node_get_physp_ptr(node, out);
+			if (!p)
+				continue;
 			if (ib_port_info_get_port_state(&p->port_info) ==
 			    IB_LINK_DOWN)
 				continue;
@@ -347,6 +352,8 @@ static int qos_extports_setup(osm_sm_t * sm, osm_node_t *node,
 			}
 
 		}
+		if (!p0)
+			return -1;
 		force_update = node->sw->need_update || sm->p_subn->need_update;
 		if (sl2vl_update_table(sm, p0, p0->port_num, 0x30000, force_update,
 					&qcfg->sl2vl, port_mad_list))
@@ -357,6 +364,8 @@ static int qos_extports_setup(osm_sm_t * sm, osm_node_t *node,
 		 */
 		for (out = 1; out < num_ports; out++) {
 			p = osm_node_get_physp_ptr(node, out);
+			if (!p)
+				continue;
 			if (ib_port_info_get_port_state(&p->port_info) ==
 			    IB_LINK_DOWN)
 				continue;
@@ -376,6 +385,8 @@ static int qos_extports_setup(osm_sm_t * sm, osm_node_t *node,
 	out = ib_switch_info_is_enhanced_port0(&node->sw->switch_info) ? 0 : 1;
 	for (; out < num_ports; out++) {
 		p = osm_node_get_physp_ptr(node, out);
+		if (!p)
+			continue;
 		if (ib_port_info_get_port_state(&p->port_info) == IB_LINK_DOWN)
 			continue;
 		force_update = p->need_update || sm->p_subn->need_update;
@@ -472,8 +483,10 @@ int osm_qos_setup(osm_opensm_t * p_osm)
 		p_next = cl_qmap_next(p_next);
 
 		p_list = (qos_mad_list_t *) malloc(sizeof(*p_list));
-		if (!p_list)
+		if (!p_list) {
+			cl_plock_release(&p_osm->lock);
 			return -1;
+		}
 
 		memset(p_list, 0, sizeof(*p_list));
 
@@ -482,8 +495,10 @@ int osm_qos_setup(osm_opensm_t * p_osm)
 		p_node = p_port->p_node;
 		if (p_node->sw) {
 			if (qos_extports_setup(&p_osm->sm, p_node, &swe_config,
-					       &p_list->port_mad_list))
+					       &p_list->port_mad_list)) {
+				cl_plock_release(&p_osm->lock);
 				ret = -1;
+			}
 
 			/* skip base port 0 */
 			if (!ib_switch_info_is_enhanced_port0
@@ -503,9 +518,10 @@ int osm_qos_setup(osm_opensm_t * p_osm)
 			cfg = &ca_config;
 
 		if (qos_endport_setup(&p_osm->sm, p_port->p_physp, cfg,
-				      vlarb_only, &p_list->port_mad_list))
-
+				      vlarb_only, &p_list->port_mad_list)) {
+			cl_plock_release(&p_osm->lock);
 			ret = -1;
+		}
 Continue:
 		/* if MAD list is not empty, add it to the global MAD list */
 		if (cl_qlist_count(&p_list->port_mad_list)) {
diff --git a/opensm/osm_req.c b/opensm/osm_req.c
index 85d1c0f..7c04465 100644
--- a/opensm/osm_req.c
+++ b/opensm/osm_req.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
- * Copyright (c) 2002-2005,2009 Mellanox Technologies LTD. All rights reserved.
+ * Copyright (c) 2002-2015 Mellanox Technologies LTD. All rights reserved.
  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
  * Copyright (c) 2009 HNR Consulting. All rights reserved.
  *
@@ -327,12 +327,12 @@ void osm_send_req_mad(IN osm_sm_t * sm, IN osm_madw_t *p_madw)
   The plock MAY or MAY NOT be held before calling this function.
 **********************************************************************/
 ib_api_status_t osm_req_set(IN osm_sm_t * sm, IN const osm_dr_path_t * p_path,
-                            IN const uint8_t * p_payload,
-                            IN size_t payload_size,
-                            IN ib_net16_t attr_id, IN ib_net32_t attr_mod,
+			    IN const uint8_t * p_payload,
+			    IN size_t payload_size,
+			    IN ib_net16_t attr_id, IN ib_net32_t attr_mod,
 			    IN boolean_t find_mkey, IN ib_net64_t m_key,
-                            IN cl_disp_msgid_t err_msg,
-                            IN const osm_madw_context_t * p_context)
+			    IN cl_disp_msgid_t err_msg,
+			    IN const osm_madw_context_t * p_context)
 {
 	osm_madw_t *p_madw;
 	ib_api_status_t status = IB_SUCCESS;
@@ -411,7 +411,7 @@ int osm_send_trap144(osm_sm_t * sm, ib_net16_t local)
 
 	ntc->generic_type = 0x80 | IB_NOTICE_TYPE_INFO;
 	ib_notice_set_prod_type_ho(ntc, osm_node_get_type(port->p_node));
-	ntc->g_or_v.generic.trap_num = cl_hton16(144);
+	ntc->g_or_v.generic.trap_num = cl_hton16(SM_LOCAL_CHANGES_TRAP); /* 144 */
 	ntc->issuer_lid = pi->base_lid;
 	ntc->data_details.ntc_144.lid = pi->base_lid;
 	ntc->data_details.ntc_144.local_changes = local ?
diff --git a/opensm/osm_sa.c b/opensm/osm_sa.c
index 06a09a9..f5b0cda 100644
--- a/opensm/osm_sa.c
+++ b/opensm/osm_sa.c
@@ -132,6 +132,14 @@ void osm_sa_shutdown(IN osm_sa_t * p_sa)
 	cl_disp_unregister(p_sa->lft_disp_h);
 	cl_disp_unregister(p_sa->sir_disp_h);
 	cl_disp_unregister(p_sa->mft_disp_h);
+
+	if (p_sa->p_set_disp) {
+		cl_disp_unregister(p_sa->mcmr_set_disp_h);
+		cl_disp_unregister(p_sa->infr_set_disp_h);
+		cl_disp_unregister(p_sa->sr_set_disp_h);
+		cl_disp_unregister(p_sa->gir_set_disp_h);
+	}
+
 	osm_sa_mad_ctrl_destroy(&p_sa->mad_ctrl);
 
 	OSM_LOG_EXIT(p_sa->p_log);
@@ -152,7 +160,9 @@ ib_api_status_t osm_sa_init(IN osm_sm_t * p_sm, IN osm_sa_t * p_sa,
 			    IN osm_subn_t * p_subn, IN osm_vendor_t * p_vendor,
 			    IN osm_mad_pool_t * p_mad_pool,
 			    IN osm_log_t * p_log, IN osm_stats_t * p_stats,
-			    IN cl_dispatcher_t * p_disp, IN cl_plock_t * p_lock)
+			    IN cl_dispatcher_t * p_disp,
+			    IN cl_dispatcher_t * p_set_disp,
+			    IN cl_plock_t * p_lock)
 {
 	ib_api_status_t status;
 
@@ -164,13 +174,14 @@ ib_api_status_t osm_sa_init(IN osm_sm_t * p_sm, IN osm_sa_t * p_sa,
 	p_sa->p_mad_pool = p_mad_pool;
 	p_sa->p_log = p_log;
 	p_sa->p_disp = p_disp;
+	p_sa->p_set_disp = p_set_disp;
 	p_sa->p_lock = p_lock;
 
 	p_sa->state = OSM_SA_STATE_READY;
 
 	status = osm_sa_mad_ctrl_init(&p_sa->mad_ctrl, p_sa, p_sa->p_mad_pool,
 				      p_sa->p_vendor, p_subn, p_log, p_stats,
-				      p_disp);
+				      p_disp, p_set_disp);
 	if (status != IB_SUCCESS)
 		goto Exit;
 
@@ -277,6 +288,36 @@ ib_api_status_t osm_sa_init(IN osm_sm_t * p_sm, IN osm_sa_t * p_sa,
 	if (p_sa->mft_disp_h == CL_DISP_INVALID_HANDLE)
 		goto Exit;
 
+	/*
+	 * When p_set_disp is defined, it means that we use different dispatcher
+	 * for SA Set requests, and we need to register handlers for it.
+	 */
+	if (p_set_disp) {
+		p_sa->gir_set_disp_h =
+		    cl_disp_register(p_set_disp, OSM_MSG_MAD_GUIDINFO_RECORD,
+				     osm_gir_rcv_process, p_sa);
+		if (p_sa->gir_set_disp_h == CL_DISP_INVALID_HANDLE)
+			goto Exit;
+
+		p_sa->mcmr_set_disp_h =
+		    cl_disp_register(p_set_disp, OSM_MSG_MAD_MCMEMBER_RECORD,
+				     osm_mcmr_rcv_process, p_sa);
+		if (p_sa->mcmr_set_disp_h == CL_DISP_INVALID_HANDLE)
+			goto Exit;
+
+		p_sa->sr_set_disp_h =
+		    cl_disp_register(p_set_disp, OSM_MSG_MAD_SERVICE_RECORD,
+				     osm_sr_rcv_process, p_sa);
+		if (p_sa->sr_set_disp_h == CL_DISP_INVALID_HANDLE)
+			goto Exit;
+
+		p_sa->infr_set_disp_h =
+		    cl_disp_register(p_set_disp, OSM_MSG_MAD_INFORM_INFO,
+				     osm_infr_rcv_process, p_sa);
+		if (p_sa->infr_set_disp_h == CL_DISP_INVALID_HANDLE)
+			goto Exit;
+	}
+
 	status = IB_SUCCESS;
 Exit:
 	OSM_LOG_EXIT(p_log);
@@ -759,7 +800,6 @@ static void sa_dump_all_sa(osm_opensm_t * p_osm, FILE * file)
 	dump_context.p_osm = p_osm;
 	dump_context.file = file;
 	OSM_LOG(&p_osm->log, OSM_LOG_DEBUG, "Dump guidinfo\n");
-	cl_plock_acquire(&p_osm->lock);
 	cl_qmap_apply_func(&p_osm->subn.port_guid_tbl,
 			   sa_dump_one_port_guidinfo, &dump_context);
 	OSM_LOG(&p_osm->log, OSM_LOG_DEBUG, "Dump multicast\n");
@@ -773,17 +813,21 @@ static void sa_dump_all_sa(osm_opensm_t * p_osm, FILE * file)
 	OSM_LOG(&p_osm->log, OSM_LOG_DEBUG, "Dump services\n");
 	cl_qlist_apply_func(&p_osm->subn.sa_sr_list,
 			    sa_dump_one_service, &dump_context);
-	cl_plock_release(&p_osm->lock);
 }
 
 int osm_sa_db_file_dump(osm_opensm_t * p_osm)
 {
 	int res = 1;
+
+	cl_plock_acquire(&p_osm->lock);
 	if (p_osm->sa.dirty) {
 		res = opensm_dump_to_file(
 			p_osm, "opensm-sa.dump", sa_dump_all_sa);
-		p_osm->sa.dirty = FALSE;
+		if (!res)
+			p_osm->sa.dirty = FALSE;
 	}
+	cl_plock_release(&p_osm->lock);
+
 	return res;
 }
 
diff --git a/opensm/osm_sa_guidinfo_record.c b/opensm/osm_sa_guidinfo_record.c
index d96db54..e548924 100644
--- a/opensm/osm_sa_guidinfo_record.c
+++ b/opensm/osm_sa_guidinfo_record.c
@@ -674,10 +674,10 @@ add_alias_guid:
 					cl_ntoh64(p_alias_guid->alias_guid), i,
 					cl_ntoh64(p_alias_guid->p_base_port->guid),
 					cl_ntoh64(p_alias_guid_check->p_base_port->guid));
-				osm_alias_guid_delete(&p_alias_guid);
 				/* clear response guid at index to indicate duplicate */
 				p_rcvd_rec->guid_info.guid[i % 8] = 0;
 			}
+			osm_alias_guid_delete(&p_alias_guid);
 		} else {
 			del_alias_guid = (*p_port->p_physp->p_guids)[i];
 			if (del_alias_guid) {
diff --git a/opensm/osm_sa_mad_ctrl.c b/opensm/osm_sa_mad_ctrl.c
index c21f7d1..30f3c9d 100644
--- a/opensm/osm_sa_mad_ctrl.c
+++ b/opensm/osm_sa_mad_ctrl.c
@@ -93,9 +93,11 @@ static void sa_mad_ctrl_disp_done_callback(IN void *context, IN void *p_data)
  * SYNOPSIS
  */
 static void sa_mad_ctrl_process(IN osm_sa_mad_ctrl_t * p_ctrl,
-				IN osm_madw_t * p_madw)
+				IN osm_madw_t * p_madw,
+				IN boolean_t is_get_request)
 {
 	ib_sa_mad_t *p_sa_mad;
+	cl_disp_reg_handle_t h_disp;
 	cl_status_t status;
 	cl_disp_msgid_t msg_id = CL_DISP_MSGID_NONE;
 	uint64_t last_dispatched_msg_queue_time_msec;
@@ -103,6 +105,8 @@ static void sa_mad_ctrl_process(IN osm_sa_mad_ctrl_t * p_ctrl,
 
 	OSM_LOG_ENTER(p_ctrl->p_log);
 
+	p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw);
+
 	/*
 	   If the dispatcher is showing us that it is overloaded
 	   there is no point in placing the request in. We should instead
@@ -113,8 +117,16 @@ static void sa_mad_ctrl_process(IN osm_sa_mad_ctrl_t * p_ctrl,
 	   HACK: Actually, we cannot send a mad from within the receive callback;
 	   thus - we will just drop it.
 	 */
-	cl_disp_get_queue_status(p_ctrl->h_disp, &num_messages,
+
+	if (!is_get_request && p_ctrl->p_set_disp) {
+		h_disp = p_ctrl->h_set_disp;
+		goto SKIP_QUEUE_CHECK;
+	}
+
+	h_disp = p_ctrl->h_disp;
+	cl_disp_get_queue_status(h_disp, &num_messages,
 				 &last_dispatched_msg_queue_time_msec);
+
 	if (num_messages > 1 && p_ctrl->p_subn->opt.max_msg_fifo_timeout &&
 	    last_dispatched_msg_queue_time_msec >
 	    p_ctrl->p_subn->opt.max_msg_fifo_timeout) {
@@ -134,8 +146,7 @@ static void sa_mad_ctrl_process(IN osm_sa_mad_ctrl_t * p_ctrl,
 		goto Exit;
 	}
 
-	p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw);
-
+SKIP_QUEUE_CHECK:
 	/*
 	   Note that attr_id (like the rest of the MAD) is in
 	   network byte order.
@@ -233,7 +244,7 @@ static void sa_mad_ctrl_process(IN osm_sa_mad_ctrl_t * p_ctrl,
 			"Posting Dispatcher message %s\n",
 			osm_get_disp_msg_str(msg_id));
 
-		status = cl_disp_post(p_ctrl->h_disp, msg_id, p_madw,
+		status = cl_disp_post(h_disp, msg_id, p_madw,
 				      sa_mad_ctrl_disp_done_callback, p_ctrl);
 
 		if (status != CL_SUCCESS) {
@@ -283,6 +294,7 @@ static void sa_mad_ctrl_rcv_callback(IN osm_madw_t * p_madw, IN void *context,
 {
 	osm_sa_mad_ctrl_t *p_ctrl = context;
 	ib_sa_mad_t *p_sa_mad;
+	boolean_t is_get_request = FALSE;
 
 	OSM_LOG_ENTER(p_ctrl->p_log);
 
@@ -360,13 +372,14 @@ static void sa_mad_ctrl_rcv_callback(IN osm_madw_t * p_madw, IN void *context,
 #if defined (VENDOR_RMPP_SUPPORT) && defined (DUAL_SIDED_RMPP)
 	case IB_MAD_METHOD_GETMULTI:
 #endif
+		is_get_request = TRUE;
 	case IB_MAD_METHOD_SET:
 	case IB_MAD_METHOD_DELETE:
 		/* if we are closing down simply do nothing */
 		if (osm_exit_flag)
 			osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
 		else
-			sa_mad_ctrl_process(p_ctrl, p_madw);
+			sa_mad_ctrl_process(p_ctrl, p_madw, is_get_request);
 		break;
 
 	default:
@@ -439,9 +452,20 @@ static void sa_mad_ctrl_send_err_callback(IN void *context,
 			"Posting Dispatcher message %s\n",
 			osm_get_disp_msg_str(osm_madw_get_err_msg(p_madw)));
 
-		status = cl_disp_post(p_ctrl->h_disp,
-				      osm_madw_get_err_msg(p_madw), p_madw,
-				      sa_mad_ctrl_disp_done_callback, p_ctrl);
+		if (p_ctrl->p_set_disp &&
+		    (p_madw->p_mad->method == IB_MAD_METHOD_SET ||
+		     p_madw->p_mad->method == IB_MAD_METHOD_DELETE))
+			status = cl_disp_post(p_ctrl->h_set_disp,
+					      osm_madw_get_err_msg(p_madw),
+					      p_madw,
+					      sa_mad_ctrl_disp_done_callback,
+					      p_ctrl);
+		else
+			status = cl_disp_post(p_ctrl->h_disp,
+					      osm_madw_get_err_msg(p_madw),
+					      p_madw,
+					      sa_mad_ctrl_disp_done_callback,
+					      p_ctrl);
 		if (status != CL_SUCCESS) {
 			OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 1A07: "
 				"Dispatcher post message failed (%s)\n",
@@ -468,12 +492,14 @@ void osm_sa_mad_ctrl_construct(IN osm_sa_mad_ctrl_t * p_ctrl)
 	CL_ASSERT(p_ctrl);
 	memset(p_ctrl, 0, sizeof(*p_ctrl));
 	p_ctrl->h_disp = CL_DISP_INVALID_HANDLE;
+	p_ctrl->h_set_disp = CL_DISP_INVALID_HANDLE;
 }
 
 void osm_sa_mad_ctrl_destroy(IN osm_sa_mad_ctrl_t * p_ctrl)
 {
 	CL_ASSERT(p_ctrl);
 	cl_disp_unregister(p_ctrl->h_disp);
+	cl_disp_unregister(p_ctrl->h_set_disp);
 }
 
 ib_api_status_t osm_sa_mad_ctrl_init(IN osm_sa_mad_ctrl_t * p_ctrl,
@@ -483,7 +509,8 @@ ib_api_status_t osm_sa_mad_ctrl_init(IN osm_sa_mad_ctrl_t * p_ctrl,
 				     IN osm_subn_t * p_subn,
 				     IN osm_log_t * p_log,
 				     IN osm_stats_t * p_stats,
-				     IN cl_dispatcher_t * p_disp)
+				     IN cl_dispatcher_t * p_disp,
+				     IN cl_dispatcher_t * p_set_disp)
 {
 	ib_api_status_t status = IB_SUCCESS;
 
@@ -494,6 +521,7 @@ ib_api_status_t osm_sa_mad_ctrl_init(IN osm_sa_mad_ctrl_t * p_ctrl,
 	p_ctrl->sa = sa;
 	p_ctrl->p_log = p_log;
 	p_ctrl->p_disp = p_disp;
+	p_ctrl->p_set_disp = p_set_disp;
 	p_ctrl->p_mad_pool = p_mad_pool;
 	p_ctrl->p_vendor = p_vendor;
 	p_ctrl->p_stats = p_stats;
@@ -509,6 +537,19 @@ ib_api_status_t osm_sa_mad_ctrl_init(IN osm_sa_mad_ctrl_t * p_ctrl,
 		goto Exit;
 	}
 
+	if (p_set_disp) {
+		p_ctrl->h_set_disp =
+		    cl_disp_register(p_set_disp, CL_DISP_MSGID_NONE, NULL,
+				     p_ctrl);
+
+		if (p_ctrl->h_set_disp == CL_DISP_INVALID_HANDLE) {
+			OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 1A0A: "
+				"SA set dispatcher registration failed\n");
+			status = IB_INSUFFICIENT_RESOURCES;
+			goto Exit;
+		}
+	}
+
 Exit:
 	OSM_LOG_EXIT(p_log);
 	return status;
diff --git a/opensm/osm_sa_mcmember_record.c b/opensm/osm_sa_mcmember_record.c
index 7e18e46..084904e 100644
--- a/opensm/osm_sa_mcmember_record.c
+++ b/opensm/osm_sa_mcmember_record.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
- * Copyright (c) 2002-2011 Mellanox Technologies LTD. All rights reserved.
+ * Copyright (c) 2002-2015 Mellanox Technologies LTD. All rights reserved.
  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
  * Copyright (c) 2008 Xsigo Systems Inc.  All rights reserved.
  * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
@@ -82,6 +82,14 @@
 					IB_MCR_COMPMASK_FLOW | \
 					IB_MCR_COMPMASK_SL)
 
+#define IPV4_BCAST_MGID_PREFIX CL_HTON64(0xff10401b00000000ULL)
+#define IPV4_BCAST_MGID_INT_ID CL_HTON64(0x00000000ffffffffULL)
+
+static int validate_other_comp_fields(osm_log_t * p_log, ib_net64_t comp_mask,
+				      const ib_member_rec_t * p_mcmr,
+				      osm_mgrp_t * p_mgrp,
+				      osm_log_level_t log_level);
+
 /*********************************************************************
  Copy certain fields between two mcmember records
  used during the process of join request to copy data from the mgrp
@@ -336,7 +344,7 @@ static boolean_t validate_port_caps(osm_log_t * p_log,
 	uint8_t rate_mgrp;
 	int extended;
 
-	mtu_required = ib_port_info_get_mtu_cap(&p_physp->port_info);
+	mtu_required = ib_port_info_get_neighbor_mtu(&p_physp->port_info);
 	mtu_mgrp = (uint8_t) (p_mgrp->mcmember_rec.mtu & 0x3F);
 	if (mtu_required < mtu_mgrp) {
 		OSM_LOG(p_log, OSM_LOG_VERBOSE,
@@ -436,7 +444,7 @@ static boolean_t validate_modify(IN osm_sa_t * sa, IN osm_mgrp_t * p_mgrp,
 					p_request_physp)) {
 			/* the request port is not part of the partition for this mgrp */
 			OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
-				"Requesting port 0x%016" PRIx64 " has no P_Key 0x%04x\n",
+				"Requesting port 0x%016" PRIx64 " has no PKey 0x%04x\n",
 				cl_ntoh64(p_request_physp->port_guid),
 				cl_ntoh16(p_mgrp->mcmember_rec.pkey));
 			return FALSE;
@@ -530,7 +538,7 @@ static boolean_t validate_delete(IN osm_sa_t * sa, IN osm_mgrp_t * p_mgrp,
  *     Sc  4bit = Scope (c)
  *     Si 16bit = Signature (2)
  *     P  64bit = GID Prefix (should be a subnet unique ID - normally Subnet Prefix)
- *     Id 32bit = Unique ID in the Subnet (might be MLID or Pkey ?)
+ *     Id 32bit = Unique ID in the Subnet (might be MLID or P_Key ?)
  *
  *  a) 8-bits of 11111111 at the start of the GID identifies this as being a
  *     multicast GID.
@@ -810,22 +818,23 @@ static unsigned build_new_mgid(osm_sa_t * sa, ib_net64_t comp_mask,
 **********************************************************************/
 static ib_api_status_t mcmr_rcv_create_new_mgrp(IN osm_sa_t * sa,
 						IN ib_net64_t comp_mask,
-						IN const ib_member_rec_t *
-						p_recvd_mcmember_rec,
+						IN const ib_member_rec_t * p_recvd_mcmember_rec,
 						IN const osm_physp_t * p_physp,
 						OUT osm_mgrp_t ** pp_mgrp)
 {
 	ib_net16_t mlid;
+	uint16_t signature;
 	ib_api_status_t status = IB_SUCCESS;
+	osm_mgrp_t *bcast_mgrp;
+	ib_gid_t bcast_mgid;
 	ib_member_rec_t mcm_rec = *p_recvd_mcmember_rec;	/* copy for modifications */
+	char gid_str[INET6_ADDRSTRLEN];
 
 	OSM_LOG_ENTER(sa->p_log);
 
 	/* we need to create the new MGID if it was not defined */
 	if (!ib_gid_is_notzero(&p_recvd_mcmember_rec->mgid)) {
 		/* create a new MGID */
-		char gid_str[INET6_ADDRSTRLEN];
-
 		if (!build_new_mgid(sa, comp_mask, &mcm_rec)) {
 			OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1B23: "
 				"cannot allocate unique MGID value\n");
@@ -835,10 +844,51 @@ static ib_api_status_t mcmr_rcv_create_new_mgrp(IN osm_sa_t * sa,
 		OSM_LOG(sa->p_log, OSM_LOG_DEBUG, "Allocated new MGID:%s\n",
 			inet_ntop(AF_INET6, mcm_rec.mgid.raw, gid_str,
 				  sizeof gid_str));
-	} else if (!validate_requested_mgid(sa, &mcm_rec)) {
+	} else if (sa->p_subn->opt.ipoib_mcgroup_creation_validation) {
 		/* a specific MGID was requested so validate the resulting MGID */
-		status = IB_SA_MAD_STATUS_REQ_INVALID;
-		goto Exit;
+		if (validate_requested_mgid(sa, &mcm_rec)) {
+			memcpy(&signature, &(mcm_rec.mgid.multicast.raw_group_id),
+			       sizeof(signature));
+			signature = cl_ntoh16(signature);
+			/* Check for IPoIB signature in MGID */
+			if (signature == 0x401B || signature == 0x601B) {
+				/* Derive IPoIB broadcast MGID */
+				bcast_mgid.unicast.prefix = IPV4_BCAST_MGID_PREFIX;
+				bcast_mgid.unicast.interface_id = IPV4_BCAST_MGID_INT_ID;
+				/* Set scope in IPoIB broadcast MGID */
+				bcast_mgid.multicast.header[1] =
+					(bcast_mgid.multicast.header[1] & 0xF0) |
+					(mcm_rec.mgid.multicast.header[1] & 0x0F);
+				/* Set P_Key in IPoIB broadcast MGID */
+				bcast_mgid.multicast.raw_group_id[2] =
+					mcm_rec.mgid.multicast.raw_group_id[2];
+				bcast_mgid.multicast.raw_group_id[3] =
+					mcm_rec.mgid.multicast.raw_group_id[3];
+				/* Check MC group for the IPoIB broadcast group */
+				if (signature != 0x401B ||
+				    memcmp(&bcast_mgid, &(mcm_rec.mgid), sizeof(ib_gid_t))) {
+					bcast_mgrp = osm_get_mgrp_by_mgid(sa->p_subn,
+									  &bcast_mgid);
+					if (!bcast_mgrp) {
+						OSM_LOG(sa->p_log, OSM_LOG_ERROR,
+							"ERR 1B1B: Broadcast group %s not found, sending IB_SA_MAD_STATUS_REQ_INVALID\n",
+							inet_ntop(AF_INET6, bcast_mgid.raw, gid_str, sizeof gid_str));
+						status = IB_SA_MAD_STATUS_REQ_INVALID;
+						goto Exit;
+					}
+					if (!validate_other_comp_fields(sa->p_log, comp_mask, p_recvd_mcmember_rec, bcast_mgrp, OSM_LOG_ERROR)) {
+						OSM_LOG(sa->p_log, OSM_LOG_ERROR,
+							"ERR 1B1C: validate_other_comp_fields failed for MGID: %s, sending IB_SA_MAD_STATUS_REQ_INVALID\n",
+							inet_ntop(AF_INET6, &p_recvd_mcmember_rec->mgid, gid_str, sizeof gid_str));
+						status = IB_SA_MAD_STATUS_REQ_INVALID;
+						goto Exit;
+					}
+				}
+			}
+		} else {
+			status = IB_SA_MAD_STATUS_REQ_INVALID;
+			goto Exit;
+		}
 	}
 
 	/* check the requested parameters are realizable */
@@ -995,6 +1045,89 @@ Exit:
 	OSM_LOG_EXIT(sa->p_log);
 }
 
+static int validate_other_comp_fields(osm_log_t * p_log, ib_net64_t comp_mask,
+				      const ib_member_rec_t * p_mcmr,
+				      osm_mgrp_t * p_mgrp,
+				      osm_log_level_t log_level)
+{
+	int ret = 0;
+
+	if ((IB_MCR_COMPMASK_QKEY & comp_mask) &&
+	    p_mcmr->qkey != p_mgrp->mcmember_rec.qkey) {
+		OSM_LOG(p_log, log_level, "ERR 1B30: "
+			"Q_Key mismatch: query 0x%x group 0x%x\n",
+			cl_ntoh32(p_mcmr->qkey),
+			cl_ntoh32(p_mgrp->mcmember_rec.qkey));
+		goto Exit;
+	}
+
+	if (IB_MCR_COMPMASK_PKEY & comp_mask) {
+		if (!(ib_pkey_is_full_member(p_mcmr->pkey) ||
+		      ib_pkey_is_full_member(p_mgrp->mcmember_rec.pkey))) {
+			OSM_LOG(p_log, log_level, "ERR 1B31: "
+				"Both limited P_Keys: query 0x%x group 0x%x\n",
+				cl_ntoh16(p_mcmr->pkey),
+				cl_ntoh16(p_mgrp->mcmember_rec.pkey));
+			goto Exit;
+		}
+		if (ib_pkey_get_base(p_mcmr->pkey) !=
+		    ib_pkey_get_base(p_mgrp->mcmember_rec.pkey)) {
+			OSM_LOG(p_log, log_level, "ERR 1B32: "
+				"P_Key base mismatch: query 0x%x group 0x%x\n",
+				cl_ntoh16(p_mcmr->pkey),
+				cl_ntoh16(p_mgrp->mcmember_rec.pkey));
+			goto Exit;
+		}
+	}
+
+	if ((IB_MCR_COMPMASK_TCLASS & comp_mask) &&
+	    p_mcmr->tclass != p_mgrp->mcmember_rec.tclass) {
+		OSM_LOG(p_log, log_level, "ERR 1B33: "
+			"TClass mismatch: query %d group %d\n",
+			p_mcmr->tclass, p_mgrp->mcmember_rec.tclass);
+		goto Exit;
+	}
+
+	/* check SL, Flow, and Hop limit */
+	{
+		uint32_t mgrp_flow, query_flow;
+		uint8_t mgrp_sl, query_sl;
+		uint8_t mgrp_hop, query_hop;
+
+		ib_member_get_sl_flow_hop(p_mcmr->sl_flow_hop,
+					  &query_sl, &query_flow, &query_hop);
+
+		ib_member_get_sl_flow_hop(p_mgrp->mcmember_rec.sl_flow_hop,
+					  &mgrp_sl, &mgrp_flow, &mgrp_hop);
+
+		if ((IB_MCR_COMPMASK_SL & comp_mask) && query_sl != mgrp_sl) {
+			OSM_LOG(p_log, log_level, "ERR 1B34: "
+				"SL mismatch: query %d group %d\n",
+				query_sl, mgrp_sl);
+			goto Exit;
+		}
+
+		if ((IB_MCR_COMPMASK_FLOW & comp_mask) &&
+		    query_flow != mgrp_flow) {
+			OSM_LOG(p_log, log_level, "ERR 1B35: "
+				"FlowLabel mismatch: query 0x%x group 0x%x\n",
+				query_flow, mgrp_flow);
+			goto Exit;
+		}
+
+		if ((IB_MCR_COMPMASK_HOP & comp_mask) && query_hop != mgrp_hop) {
+			OSM_LOG(p_log, log_level, "ERR 1B36: "
+				"Hop mismatch: query %d group %d\n",
+				query_hop, mgrp_hop);
+			goto Exit;
+		}
+	}
+
+	ret = 1;
+Exit:
+	return ret;
+}
+
 /**********************************************************************
  Handle a join (or create) request
 **********************************************************************/
@@ -1024,7 +1157,7 @@ static void mcmr_rcv_join_mgrp(IN osm_sa_t * sa, IN osm_madw_t * p_madw)
 
 	mcmember_rec = *p_recvd_mcmember_rec;
 
-        /* Validate the subnet prefix in the PortGID */
+	/* Validate the subnet prefix in the PortGID */
 	if (p_recvd_mcmember_rec->port_gid.unicast.prefix !=
 	    sa->p_subn->opt.subnet_prefix) {
 		OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
@@ -1083,7 +1216,7 @@ static void mcmr_rcv_join_mgrp(IN osm_sa_t * sa, IN osm_madw_t * p_madw)
 					   sa->p_subn->opt.allow_both_pkeys)) {
 		CL_PLOCK_RELEASE(sa->p_lock);
 		OSM_LOG(sa->p_log, OSM_LOG_VERBOSE,
-			"Port and requester don't share pkey\n");
+			"Port and requester don't share PKey\n");
 		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_REQ_INVALID);
 		goto Exit;
 	}
@@ -1152,9 +1285,29 @@ static void mcmr_rcv_join_mgrp(IN osm_sa_t * sa, IN osm_madw_t * p_madw)
 		/* copy the MGID to the result */
 		mcmember_rec.mgid = p_mgrp->mcmember_rec.mgid;
 		is_new_group = 1;
-	} else
+	} else {
 		/* no need for a new group */
 		is_new_group = 0;
+		if (sa->p_subn->opt.mcgroup_join_validation &&
+		    !validate_other_comp_fields(sa->p_log, p_sa_mad->comp_mask,
+						p_recvd_mcmember_rec, p_mgrp,
+						OSM_LOG_ERROR)) {
+			char gid_str[INET6_ADDRSTRLEN];
+			CL_PLOCK_RELEASE(sa->p_lock);
+			OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1B1A: "
+				"validate_other_comp_fields failed for "
+				"MGID: %s port 0x%016" PRIx64
+				" (%s), sending IB_SA_MAD_STATUS_REQ_INVALID\n",
+				inet_ntop(AF_INET6,
+					  p_mgrp->mcmember_rec.mgid.raw,
+					  gid_str, sizeof gid_str),
+				cl_ntoh64(portguid),
+				p_port->p_node->print_desc);
+			osm_sa_send_error(sa, p_madw,
+					  IB_SA_MAD_STATUS_REQ_INVALID);
+			goto Exit;
+		}
+	}
 
 	CL_ASSERT(p_mgrp);
 
@@ -1197,6 +1350,24 @@ static void mcmr_rcv_join_mgrp(IN osm_sa_t * sa, IN osm_madw_t * p_madw)
 		goto Exit;
 	}
 
+	/* verify that the joining port is in the partition of the group */
+	if (!osm_physp_has_pkey(sa->p_log, p_mgrp->mcmember_rec.pkey, p_physp)) {
+		char gid_str[INET6_ADDRSTRLEN];
+		if (is_new_group)
+			osm_mgrp_cleanup(sa->p_subn, p_mgrp);
+		CL_PLOCK_RELEASE(sa->p_lock);
+		memset(gid_str, 0, sizeof(gid_str));
+		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1B14: "
+			"Cannot join port 0x%016" PRIx64 " to MGID %s - "
+			"Port is not in partition of this MC group\n",
+			cl_ntoh64(portguid),
+			inet_ntop(AF_INET6,
+				  p_mgrp->mcmember_rec.mgid.raw,
+				  gid_str, sizeof(gid_str)));
+		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_REQ_INVALID);
+		goto Exit;
+	}
+
 	/*
 	 * o15-0.2.1 requires validation of the requesting port
 	 * in the case of modification:
@@ -1213,7 +1384,7 @@ static void mcmr_rcv_join_mgrp(IN osm_sa_t * sa, IN osm_madw_t * p_madw)
 		goto Exit;
 	}
 
-	/* copy qkey mlid tclass pkey sl_flow_hop mtu rate pkt_life sl_flow_hop */
+	/* copy qkey mlid tclass pkey sl_flow_hop mtu rate pkt_life */
 	copy_from_create_mc_rec(&mcmember_rec, &p_mgrp->mcmember_rec);
 
 	/* create or update existing port (join-state will be updated) */
@@ -1316,41 +1487,10 @@ static void mcmr_by_comp_mask(osm_sa_t * sa, const ib_member_rec_t * p_rcvd_rec,
 		goto Exit;
 
 	/* now do the rest of the match */
-	if ((IB_MCR_COMPMASK_QKEY & comp_mask) &&
-	    p_rcvd_rec->qkey != p_mgrp->mcmember_rec.qkey)
-		goto Exit;
-
-	if ((IB_MCR_COMPMASK_PKEY & comp_mask) &&
-	    p_rcvd_rec->pkey != p_mgrp->mcmember_rec.pkey)
+	if (!validate_other_comp_fields(sa->p_log, comp_mask, p_rcvd_rec, p_mgrp,
+					OSM_LOG_NONE))
 		goto Exit;
 
-	if ((IB_MCR_COMPMASK_TCLASS & comp_mask) &&
-	    p_rcvd_rec->tclass != p_mgrp->mcmember_rec.tclass)
-		goto Exit;
-
-	/* check SL, Flow, and Hop limit */
-	{
-		uint8_t mgrp_sl, query_sl;
-		uint32_t mgrp_flow, query_flow;
-		uint8_t mgrp_hop, query_hop;
-
-		ib_member_get_sl_flow_hop(p_rcvd_rec->sl_flow_hop,
-					  &query_sl, &query_flow, &query_hop);
-
-		ib_member_get_sl_flow_hop(p_mgrp->mcmember_rec.sl_flow_hop,
-					  &mgrp_sl, &mgrp_flow, &mgrp_hop);
-
-		if ((IB_MCR_COMPMASK_SL & comp_mask) && query_sl != mgrp_sl)
-			goto Exit;
-
-		if ((IB_MCR_COMPMASK_FLOW & comp_mask) &&
-		    query_flow != mgrp_flow)
-			goto Exit;
-
-		if ((IB_MCR_COMPMASK_HOP & comp_mask) && query_hop != mgrp_hop)
-			goto Exit;
-	}
-
 	if ((IB_MCR_COMPMASK_PROXY & comp_mask) &&
 	    p_rcvd_rec->proxy_join != p_mgrp->mcmember_rec.proxy_join)
 		goto Exit;
diff --git a/opensm/osm_sa_path_record.c b/opensm/osm_sa_path_record.c
index b7509ec..4ae6d32 100644
--- a/opensm/osm_sa_path_record.c
+++ b/opensm/osm_sa_path_record.c
@@ -1329,7 +1329,9 @@ ib_net16_t osm_pr_get_end_points(IN osm_sa_t * sa,
 		}
 		if (pp_sgid)
 			*pp_sgid = &p_pr->sgid;
-	} else if (comp_mask & IB_PR_COMPMASK_SLID) {
+	}
+
+	if (comp_mask & IB_PR_COMPMASK_SLID) {
 		*pp_src_port = osm_get_port_by_lid(sa->p_subn, p_pr->slid);
 		if (!*pp_src_port) {
 			/*
@@ -1381,7 +1383,9 @@ ib_net16_t osm_pr_get_end_points(IN osm_sa_t * sa,
 			sa_status = IB_SA_MAD_STATUS_INVALID_GID;
 			goto Exit;
 		}
-	} else if (comp_mask & IB_PR_COMPMASK_DLID) {
+	}
+
+	if (comp_mask & IB_PR_COMPMASK_DLID) {
 		*pp_dest_port = osm_get_port_by_lid(sa->p_subn, p_pr->dlid);
 		if (!*pp_dest_port) {
 			/*
@@ -1793,6 +1797,33 @@ void osm_pr_rcv_process(IN void *context, IN void *data)
 				  &p_src_port, &p_dest_port,
 				  &p_sgid, &p_dgid) != IB_SA_MAD_STATUS_SUCCESS)
 		goto Unlock;
+
+	if (p_src_alias_guid && p_src_port &&
+	    p_src_alias_guid->p_base_port != p_src_port) {
+		cl_plock_release(sa->p_lock);
+		OSM_LOG(sa->p_log, OSM_LOG_VERBOSE,
+			"Requester port GUID 0x%" PRIx64 ": Port for SGUID "
+			"0x%" PRIx64 " not same as port for SLID %u\n",
+			cl_ntoh64(osm_port_get_guid(requester_port)),
+			cl_ntoh64(p_pr->sgid.unicast.interface_id),
+			cl_ntoh16(p_pr->slid));
+		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_REQ_INVALID);
+		goto Exit;
+	}
+
+	if (p_dest_alias_guid && p_dest_port &&
+	    p_dest_alias_guid->p_base_port != p_dest_port) {
+		cl_plock_release(sa->p_lock);
+		OSM_LOG(sa->p_log, OSM_LOG_VERBOSE,
+			"Requester port GUID 0x%" PRIx64 ": Port for DGUID "
+			"0x%" PRIx64 " not same as port for DLID %u\n",
+			cl_ntoh64(osm_port_get_guid(requester_port)),
+			cl_ntoh64(p_pr->dgid.unicast.interface_id),
+			cl_ntoh16(p_pr->dlid));
+		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_REQ_INVALID);
+		goto Exit;
+	}
+
 	/*
 	   What happens next depends on the type of endpoint information
 	   that was specified....
@@ -1827,7 +1858,7 @@ void osm_pr_rcv_process(IN void *context, IN void *data)
 			}
 		}
 	} else {
-		if (p_dest_alias_guid)
+		if (p_dest_alias_guid && !p_src_port)
 			osm_pr_process_half(sa, p_sa_mad, requester_port,
 					    NULL, p_dest_alias_guid, p_sgid,
 					    p_dgid, &pr_list);
@@ -1837,7 +1868,26 @@ void osm_pr_rcv_process(IN void *context, IN void *data)
 			 */
 			pr_rcv_process_world(sa, p_sa_mad, requester_port,
 					     p_sgid, p_dgid, &pr_list);
-		else if (p_src_port && !p_dest_port) {
+		else if (p_dest_alias_guid && p_src_port) {
+			/* Get all alias GUIDs for the src port */
+			p_src_alias_guid = (osm_alias_guid_t *) cl_qmap_head(&sa->p_subn->alias_port_guid_tbl);
+			while (p_src_alias_guid !=
+			       (osm_alias_guid_t *) cl_qmap_end(&sa->p_subn->alias_port_guid_tbl)) {
+				if (osm_get_port_by_alias_guid(sa->p_subn,
+							       p_src_alias_guid->alias_guid) ==
+				    p_src_port)
+					osm_pr_process_pair(sa, p_sa_mad,
+							    requester_port,
+							    p_src_alias_guid,
+							    p_dest_alias_guid,
+							    p_sgid, p_dgid,
+							    &pr_list);
+				if (p_sa_mad->method == IB_MAD_METHOD_GET &&
+				    cl_qlist_count(&pr_list) > 0)
+					break;
+				p_src_alias_guid = (osm_alias_guid_t *) cl_qmap_next(&p_src_alias_guid->map_item);
+			}
+		} else if (p_src_port && !p_dest_port) {
 			/* Get all alias GUIDs for the src port */
 			p_src_alias_guid = (osm_alias_guid_t *) cl_qmap_head(&sa->p_subn->alias_port_guid_tbl);
 			while (p_src_alias_guid !=
diff --git a/opensm/osm_service.c b/opensm/osm_service.c
index f4644d5..ba5a982 100644
--- a/opensm/osm_service.c
+++ b/opensm/osm_service.c
@@ -138,7 +138,7 @@ void osm_svcr_remove_from_db(IN osm_subn_t * p_subn, IN osm_log_t * p_log,
 	OSM_LOG(p_log, OSM_LOG_DEBUG,
 		"Removing Service Record Name:%s ID:0x%016" PRIx64
 		" from Database\n", p_svcr->service_record.service_name,
-		p_svcr->service_record.service_id);
+		cl_ntoh64(p_svcr->service_record.service_id));
 
 	cl_qlist_remove_item(&p_subn->sa_sr_list, &p_svcr->list_item);
 	p_subn->p_osm->sa.dirty = TRUE;
diff --git a/opensm/osm_sm_mad_ctrl.c b/opensm/osm_sm_mad_ctrl.c
index fd2cd17..ebac558 100644
--- a/opensm/osm_sm_mad_ctrl.c
+++ b/opensm/osm_sm_mad_ctrl.c
@@ -750,7 +750,7 @@ static void sm_mad_ctrl_send_err_cb(IN void *context, IN osm_madw_t * p_madw)
 		p_ctrl->p_subn->subnet_initialization_error = TRUE;
 	} else if (p_madw->status == IB_TIMEOUT &&
 		   p_smp->method == IB_MAD_METHOD_GET) {
-		OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 3120 "
+		OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 3120: "
 			"Timeout while getting attribute 0x%X (%s); "
 			"Possible mis-set mkey?\n",
 			cl_ntoh16(p_smp->attr_id),
diff --git a/opensm/osm_state_mgr.c b/opensm/osm_state_mgr.c
index 1fda3f6..b62d6b7 100644
--- a/opensm/osm_state_mgr.c
+++ b/opensm/osm_state_mgr.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2009 Sun Microsystems, Inc. All rights reserved.
  * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
- * Copyright (c) 2002-2009 Mellanox Technologies LTD. All rights reserved.
+ * Copyright (c) 2002-2015 Mellanox Technologies LTD. All rights reserved.
  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
  * Copyright (c) 2009 HNR Consulting. All rights reserved.
  * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
@@ -69,6 +69,8 @@
 #include <opensm/osm_opensm.h>
 #include <opensm/osm_congestion_control.h>
 #include <opensm/osm_db.h>
+#include <opensm/osm_service.h>
+#include <opensm/osm_guid.h>
 
 extern void osm_drop_mgr_process(IN osm_sm_t * sm);
 extern int osm_qos_setup(IN osm_opensm_t * p_osm);
@@ -291,6 +293,105 @@ static ib_api_status_t state_mgr_clean_known_lids(IN osm_sm_t * sm)
 }
 
 /**********************************************************************
+ Clear SA cache
+**********************************************************************/
+static ib_api_status_t state_mgr_sa_clean(IN osm_sm_t * sm)
+{
+	ib_api_status_t status = IB_SUCCESS;
+	cl_qmap_t *p_port_guid_tbl;
+	osm_assigned_guids_t *p_assigned_guids, *p_next_assigned_guids;
+	osm_alias_guid_t *p_alias_guid, *p_next_alias_guid;
+	osm_mcm_port_t *mcm_port;
+	osm_subn_t * p_subn;
+	osm_port_t *p_port;
+	osm_infr_t *p_infr;
+	osm_svcr_t *p_svcr;
+
+	OSM_LOG_ENTER(sm->p_log);
+
+	p_subn = sm->p_subn;
+
+	/* we need a lock here! */
+	CL_PLOCK_EXCL_ACQUIRE(sm->p_lock);
+
+	if (p_subn->opt.drop_event_subscriptions) {
+		/* Clean InformInfo records */
+		p_infr = (osm_infr_t *) cl_qlist_remove_head(&p_subn->sa_infr_list);
+		while (p_infr !=
+		       (osm_infr_t *) cl_qlist_end(&p_subn->sa_infr_list)) {
+			osm_infr_delete(p_infr);
+			p_infr = (osm_infr_t *) cl_qlist_remove_head(&p_subn->sa_infr_list);
+		}
+
+		/* For now, treat Service Records in same category as InformInfos */
+		/* Clean Service records */
+		p_svcr = (osm_svcr_t *) cl_qlist_remove_head(&p_subn->sa_sr_list);
+		while (p_svcr !=
+		       (osm_svcr_t *) cl_qlist_end(&p_subn->sa_sr_list)) {
+			osm_svcr_delete(p_svcr);
+			p_svcr = (osm_svcr_t *) cl_qlist_remove_head(&p_subn->sa_sr_list);
+		}
+	}
+
+	/* Clean Multicast member list on each port */
+	p_port_guid_tbl = &p_subn->port_guid_tbl;
+	for (p_port = (osm_port_t *) cl_qmap_head(p_port_guid_tbl);
+	     p_port != (osm_port_t *) cl_qmap_end(p_port_guid_tbl);
+	     p_port = (osm_port_t *) cl_qmap_next(&p_port->map_item)) {
+		while (!cl_is_qlist_empty(&p_port->mcm_list)) {
+			mcm_port = cl_item_obj(cl_qlist_head(&p_port->mcm_list),
+					       mcm_port, list_item);
+			osm_mgrp_delete_port(p_subn, sm->p_log, mcm_port->mgrp,
+					     p_port);
+		}
+		/* Hack - clean alias guid table from physp */
+		free(p_port->p_physp->p_guids);
+		p_port->p_physp->p_guids = NULL;
+	}
+
+	/* Clean Alias Guid work objects */
+	while (cl_qlist_count(&p_subn->alias_guid_list))
+		osm_guid_work_obj_delete((osm_guidinfo_work_obj_t *)
+			cl_qlist_remove_head(&p_subn->alias_guid_list));
+
+	/* Clean Assigned GUIDs table */
+	p_next_assigned_guids = (osm_assigned_guids_t *)
+				cl_qmap_head(&p_subn->assigned_guids_tbl);
+	while (p_next_assigned_guids !=
+	       (osm_assigned_guids_t *) cl_qmap_end(&p_subn->assigned_guids_tbl)) {
+		p_assigned_guids = p_next_assigned_guids;
+		p_next_assigned_guids = (osm_assigned_guids_t *)
+					cl_qmap_next(&p_assigned_guids->map_item);
+		cl_qmap_remove_item(&p_subn->assigned_guids_tbl,
+				    &p_assigned_guids->map_item);
+		osm_assigned_guids_delete(&p_assigned_guids);
+        }
+
+	/* Clean Alias GUIDs table */
+	p_next_alias_guid = (osm_alias_guid_t *)
+			    cl_qmap_head(&p_subn->alias_port_guid_tbl);
+	while (p_next_alias_guid !=
+	       (osm_alias_guid_t *) cl_qmap_end(&p_subn->alias_port_guid_tbl)) {
+		p_alias_guid = p_next_alias_guid;
+		p_next_alias_guid = (osm_alias_guid_t *)
+				    cl_qmap_next(&p_alias_guid->map_item);
+		if (osm_alias_guid_get_alias_guid(p_alias_guid) !=
+		    osm_alias_guid_get_base_guid(p_alias_guid)) {
+			/* Clean if it's not base port GUID */
+			cl_qmap_remove_item(&p_subn->alias_port_guid_tbl,
+					    &p_alias_guid->map_item);
+			osm_alias_guid_delete(&p_alias_guid);
+		}
+	}
+
+	p_subn->p_osm->sa.dirty = TRUE;
+
+	CL_PLOCK_RELEASE(sm->p_lock);
+	OSM_LOG_EXIT(sm->p_log);
+	return status;
+}
+
+/**********************************************************************
  Notifies the transport layer that the local LID has changed,
  which give it a chance to update address vectors, etc..
 **********************************************************************/
@@ -892,6 +993,7 @@ static void state_mgr_send_handover(IN osm_sm_t * sm, IN osm_remote_sm_t * p_sm)
 	context.smi_context.port_guid = p_port->guid;
 	context.smi_context.set_method = TRUE;
 
+	memset(payload, 0, sizeof(payload));
 	p_smi->guid = sm->p_subn->sm_port_guid;
 	p_smi->act_count = cl_hton32(sm->p_subn->p_osm->stats.qp0_mads_sent);
 	p_smi->pri_state = (uint8_t) (sm->p_subn->sm_state |
@@ -956,13 +1058,13 @@ static void state_mgr_report_new_ports(IN osm_sm_t * sm)
 			continue;
 
 		port_guid = osm_port_get_guid(p_port);
-		/* issue a notice - trap 64 */
+		/* issue a notice - trap 64 (SM_GID_IN_SERVICE_TRAP) */
 
 		/* details of the notice */
-		notice.generic_type = 0x83;	/* is generic subn mgt type */
+		notice.generic_type = 0x80 | IB_NOTICE_TYPE_SUBN_MGMT;	/* is generic subn mgt type */
 		ib_notice_set_prod_type_ho(&notice, 4);	/* A Class Manager generator */
 		/* endport becomes reachable */
-		notice.g_or_v.generic.trap_num = CL_HTON16(64);
+		notice.g_or_v.generic.trap_num = CL_HTON16(SM_GID_IN_SERVICE_TRAP); /* 64 */
 		/* The sm_base_lid is saved in network order already. */
 		notice.issuer_lid = sm->p_subn->sm_base_lid;
 		/* following C14-72.1.1 and table 119 p739 */
@@ -1076,9 +1178,8 @@ static void state_mgr_check_tbl_consistency(IN osm_sm_t * sm)
 			 * a certain port with some lid (different than the one
 			 * pre-assigned to it), and the port didn't get the
 			 * PortInfo Set request. Due to this, the port is
-			 * updated with its original lid in our database, but
-			 * with the new lid we wanted to give it in our
-			 * port_lid_tbl. */
+			 * updated with its original lid in our database
+			 * rather than the new lid we wanted to give it. */
 			OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 3322: "
 				"lid %zu is wrongly assigned to port 0x%016"
 				PRIx64 " (\'%s\' port %u) in port_lid_tbl\n",
@@ -1086,7 +1187,6 @@ static void state_mgr_check_tbl_consistency(IN osm_sm_t * sm)
 				cl_ntoh64(osm_port_get_guid(p_port_stored)),
 				p_port_stored->p_node->print_desc,
 				p_port_stored->p_physp->port_num);
-			cl_ptr_vector_set(p_port_lid_tbl, lid, NULL);
 		} else if (p_port_stored == NULL)
 			/* There is an object in the new database, but no
 			 * object in our subnet database. This is the matching
@@ -1115,8 +1215,20 @@ static void state_mgr_check_tbl_consistency(IN osm_sm_t * sm)
 				cl_ntoh64(osm_port_get_guid(p_port_stored)),
 				p_port_stored->p_node->print_desc,
 				p_port_stored->p_physp->port_num);
+		}
+
+		/*
+		 * Clear the lid of the port in order to ignore it
+		 *  in routing phase
+		 */
+		if (p_port_stored) {
+			OSM_LOG(sm->p_log, OSM_LOG_INFO, "Clearing Lid for "
+				"port 0x%016" PRIx64 "\n",
+				cl_ntoh64(osm_port_get_guid(p_port_stored)));
+			osm_port_clear_base_lid(p_port_stored);
 			cl_ptr_vector_set(p_port_lid_tbl, lid, NULL);
 		}
+
 		/* Make sure we'll do another heavy sweep. */
 		sm->p_subn->subnet_initialization_error = TRUE;
 	}
@@ -1127,7 +1239,7 @@ Exit:
 	OSM_LOG_EXIT(sm->p_log);
 }
 
-static void cleanup_switch(cl_map_item_t * item, void *log)
+static void check_switch_lft(cl_map_item_t * item, void *log)
 {
 	osm_switch_t *sw = (osm_switch_t *) item;
 
@@ -1139,10 +1251,6 @@ static void cleanup_switch(cl_map_item_t * item, void *log)
 			   "LFT of switch 0x%016" PRIx64 " (%s) is not up to date\n",
 			   cl_ntoh64(sw->p_node->node_info.node_guid),
 			   sw->p_node->print_desc);
-	else {
-		free(sw->new_lft);
-		sw->new_lft = NULL;
-	}
 }
 
 int wait_for_pending_transactions(osm_stats_t * stats)
@@ -1201,6 +1309,12 @@ static void do_sweep(osm_sm_t * sm)
 		state_mgr_clean_known_lids(sm);
 
 		/*
+		 * Need to clean SA cache when state changes to STANDBY
+		 * after handover.
+		 */
+		state_mgr_sa_clean(sm);
+
+		/*
 		 * Need to reconfigure LFTs, PKEYs, and QoS on all switches
 		 * when coming out of STANDBY
 		 */
@@ -1280,7 +1394,7 @@ static void do_sweep(osm_sm_t * sm)
 
 		osm_congestion_control_setup(sm->p_subn->p_osm);
 
-		if (osm_congestion_control_wait_pending_transactions (sm->p_subn->p_osm))
+		if (osm_congestion_control_wait_pending_transactions(sm->p_subn->p_osm))
 			return;
 
 		if (!sm->p_subn->subnet_initialization_error) {
@@ -1327,6 +1441,7 @@ repeat_discovery:
 	if (state_mgr_is_sm_port_down(sm) == TRUE) {
 		if (sm->p_subn->last_sm_port_state) {
 			sm->p_subn->last_sm_port_state = 0;
+			state_mgr_sa_clean(sm);
 			osm_log_v2(sm->p_log, OSM_LOG_SYS, FILE_ID,
 				   "SM port is down\n");
 			OSM_LOG_MSG_BOX(sm->p_log, OSM_LOG_VERBOSE,
@@ -1490,9 +1605,6 @@ repeat_discovery:
 	if (wait_for_pending_transactions(&sm->p_subn->p_osm->stats))
 		return;
 
-	/* cleanup switch lft buffers */
-	cl_qmap_apply_func(&sm->p_subn->sw_guid_tbl, cleanup_switch, sm->p_log);
-
 	/* We are done setting all LFTs so clear the ignore existing.
 	 * From now on, as long as we are still master, we want to
 	 * take into account these lfts. */
@@ -1551,7 +1663,7 @@ repeat_discovery:
 
 	osm_congestion_control_setup(sm->p_subn->p_osm);
 
-	if (osm_congestion_control_wait_pending_transactions (sm->p_subn->p_osm))
+	if (osm_congestion_control_wait_pending_transactions(sm->p_subn->p_osm))
 		return;
 
 	/*
@@ -1559,6 +1671,10 @@ repeat_discovery:
 	 */
 	state_mgr_report_new_ports(sm);
 
+	/* check switch lft buffers assignments */
+	cl_qmap_apply_func(&sm->p_subn->sw_guid_tbl, check_switch_lft,
+			   sm->p_log);
+
 	/* in any case we zero this flag */
 	sm->p_subn->coming_out_of_standby = FALSE;
 	sm->p_subn->first_time_master_sweep = FALSE;
diff --git a/opensm/osm_subnet.c b/opensm/osm_subnet.c
index d577a69..530ebe7 100644
--- a/opensm/osm_subnet.c
+++ b/opensm/osm_subnet.c
@@ -5,7 +5,7 @@
  * Copyright (c) 2008 Xsigo Systems Inc.  All rights reserved.
  * Copyright (c) 2009 System Fabric Works, Inc. All rights reserved.
  * Copyright (c) 2009 HNR Consulting. All rights reserved.
- * Copyright (c) 2009-2011 ZIH, TU Dresden, Federal Republic of Germany. All rights reserved.
+ * Copyright (c) 2009-2015 ZIH, TU Dresden, Federal Republic of Germany. All rights reserved.
  * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
  *
  * This software is available to you under a choice of one of two
@@ -815,7 +815,7 @@ static const opt_rec_t opt_tbl[] = {
 	{ "partition_config_file", OPT_OFFSET(partition_config_file), opts_parse_charp, NULL, 0 },
 	{ "no_partition_enforcement", OPT_OFFSET(no_partition_enforcement), opts_parse_boolean, NULL, 1 },
 	{ "part_enforce", OPT_OFFSET(part_enforce), opts_parse_charp, NULL, 1 },
-	{ "allow_both_pkeys", OPT_OFFSET(allow_both_pkeys), opts_parse_boolean, NULL, 1 },
+	{ "allow_both_pkeys", OPT_OFFSET(allow_both_pkeys), opts_parse_boolean, NULL, 0 },
 	{ "sm_assigned_guid", OPT_OFFSET(sm_assigned_guid), opts_parse_uint8, NULL, 1 },
 	{ "qos", OPT_OFFSET(qos), opts_parse_boolean, NULL, 1 },
 	{ "qos_policy_file", OPT_OFFSET(qos_policy_file), opts_parse_charp, NULL, 0 },
@@ -842,6 +842,8 @@ static const opt_rec_t opt_tbl[] = {
 	{ "sm_inactive", OPT_OFFSET(sm_inactive), opts_parse_boolean, NULL, 1 },
 	{ "babbling_port_policy", OPT_OFFSET(babbling_port_policy), opts_parse_boolean, NULL, 1 },
 	{ "drop_event_subscriptions", OPT_OFFSET(drop_event_subscriptions), opts_parse_boolean, NULL, 1 },
+	{ "ipoib_mcgroup_creation_validation", OPT_OFFSET(ipoib_mcgroup_creation_validation), opts_parse_boolean, NULL, 1 },
+	{ "mcgroup_join_validation", OPT_OFFSET(mcgroup_join_validation), opts_parse_boolean, NULL, 1 },
 	{ "use_optimized_slvl", OPT_OFFSET(use_optimized_slvl), opts_parse_boolean, NULL, 1 },
 	{ "fsync_high_avail_files", OPT_OFFSET(fsync_high_avail_files), opts_parse_boolean, NULL, 1 },
 #ifdef ENABLE_OSM_PERF_MGR
@@ -911,6 +913,7 @@ static const opt_rec_t opt_tbl[] = {
 	{ "sm_sl", OPT_OFFSET(sm_sl), opts_parse_uint8, NULL, 1 },
 	{ "log_prefix", OPT_OFFSET(log_prefix), opts_parse_charp, NULL, 1 },
 	{ "per_module_logging_file", OPT_OFFSET(per_module_logging_file), opts_parse_charp, NULL, 0 },
+	{ "quasi_ftree_indexing", OPT_OFFSET(quasi_ftree_indexing), opts_parse_boolean, NULL, 1 },
 	{0}
 };
 
@@ -1371,7 +1374,7 @@ osm_physp_t *osm_get_physp_by_mad_addr(IN osm_log_t * p_log,
 }
 
 osm_switch_t *osm_get_switch_by_guid(IN const osm_subn_t * p_subn,
-				     IN uint64_t guid)
+				     IN ib_net64_t guid)
 {
 	osm_switch_t *p_switch;
 
@@ -1381,7 +1384,7 @@ osm_switch_t *osm_get_switch_by_guid(IN const osm_subn_t * p_subn,
 	return p_switch;
 }
 
-osm_node_t *osm_get_node_by_guid(IN osm_subn_t const *p_subn, IN uint64_t guid)
+osm_node_t *osm_get_node_by_guid(IN osm_subn_t const *p_subn, IN ib_net64_t guid)
 {
 	osm_node_t *p_node;
 
@@ -1474,9 +1477,10 @@ int is_mlnx_ext_port_info_supported(ib_net16_t devid)
 	uint16_t devid_ho;
 
 	devid_ho = cl_ntoh16(devid);
-	if ((devid_ho >= 0xc738 && devid_ho <= 0xc73b) || devid_ho == 0xcb20)
+	if ((devid_ho >= 0xc738 && devid_ho <= 0xc73b) || devid_ho == 0xcb20 ||
+	    devid_ho == 0xcf08)
 		return 1;
-	if (devid_ho >= 0x1003 && devid_ho <= 0x1013)
+	if (devid_ho >= 0x1003 && devid_ho <= 0x1016)
 		return 1;
 	return 0;
 }
@@ -1552,6 +1556,8 @@ void osm_subn_set_default_opt(IN osm_subn_opt_t * p_opt)
 	p_opt->sm_inactive = FALSE;
 	p_opt->babbling_port_policy = FALSE;
 	p_opt->drop_event_subscriptions = FALSE;
+	p_opt->ipoib_mcgroup_creation_validation = TRUE;
+	p_opt->mcgroup_join_validation = TRUE;
 	p_opt->use_optimized_slvl = FALSE;
 	p_opt->fsync_high_avail_files = TRUE;
 #ifdef ENABLE_OSM_PERF_MGR
@@ -1631,6 +1637,7 @@ void osm_subn_set_default_opt(IN osm_subn_opt_t * p_opt)
 	subn_init_qos_options(&p_opt->qos_rtr_options, NULL);
 	p_opt->cc_cct.entries_len = 0;
 	p_opt->cc_cct.input_str = NULL;
+	p_opt->quasi_ftree_indexing = FALSE;
 }
 
 static char *clean_val(char *val)
@@ -2289,7 +2296,9 @@ void osm_subn_output_conf(FILE *out, IN osm_subn_opt_t * p_opts)
 		"m_key_lease_period %u\n\n"
 		"# The protection level used for the M_Key on this subnet\n"
 		"m_key_protection_level %u\n\n"
-		"# If FALSE, SM won't try to determine the m_key of unknown ports\n"
+		"# If TRUE, SM tries to determine the m_key of unknown ports from guid2mkey file\n"
+		"# If FALSE, SM won't try to determine the m_key of unknown ports.\n"
+		"# Preconfigured m_key will be used instead\n"
 		"m_key_lookup %s\n\n"
 		"# SM_Key value of the SM used for SM authentication\n"
 		"sm_key 0x%016" PRIx64 "\n\n"
@@ -2503,6 +2512,15 @@ void osm_subn_output_conf(FILE *out, IN osm_subn_opt_t * p_opts)
 		"io_guid_file %s\n\n",
 		p_opts->io_guid_file ? p_opts->io_guid_file : null_str);
 
+        fprintf(out,
+		"# If TRUE enables alternative indexing policy for ftree routing\n"
+		"# in quasi-ftree topologies that can improve shift-pattern support.\n"
+		"# The switch indexing starts from root switch and leaf switches\n"
+		"# are termination points of BFS algorithm\n"
+		"# If FALSE, the indexing starts from leaf switch (default)\n"
+		"quasi_ftree_indexing %s\n\n",
+		p_opts->quasi_ftree_indexing ? "TRUE" : "FALSE");
+
 	fprintf(out,
 		"# Number of reverse hops allowed for I/O nodes\n"
 		"# Used for connectivity between I/O nodes connected to Top Switches\nmax_reverse_hops %d\n\n",
@@ -2541,6 +2559,12 @@ void osm_subn_output_conf(FILE *out, IN osm_subn_opt_t * p_opts)
 		p_opts->scatter_ports);
 
 	fprintf(out,
+		"# Don't use scatter for ports defined in\n"
+		"# guid_routing_order file\n"
+		"guid_routing_order_no_scatter %s\n\n",
+		p_opts->guid_routing_order_no_scatter ? "TRUE" : "FALSE");
+
+	fprintf(out,
 		"# SA database file name\nsa_db_file %s\n\n",
 		p_opts->sa_db_file ? p_opts->sa_db_file : null_str);
 
@@ -2611,8 +2635,14 @@ void osm_subn_output_conf(FILE *out, IN osm_subn_opt_t * p_opts)
 		"sm_inactive %s\n\n"
 		"# Babbling Port Policy\n"
 		"babbling_port_policy %s\n\n"
-		"# Drop event subscriptions (InformInfo) if the port goes away\n"
+		"# Drop event subscriptions (InformInfo and ServiceRecord) on port removal and SM coming out of STANDBY\n"
 		"drop_event_subscriptions %s\n\n"
+		"# Validate IPoIB non-broadcast group creation parameters against\n"
+		"# broadcast group parameters per IETF RFC 4391 (default TRUE)\n"
+		"ipoib_mcgroup_creation_validation %s\n\n"
+		"# Validate multicast join parameters against multicast group\n"
+		"# parameters when MC group already exists\n"
+		"mcgroup_join_validation %s\n\n"
 		"# Use Optimized SLtoVLMapping programming if supported by device\n"
 		"use_optimized_slvl %s\n\n"
 		"# Sync in memory files used for high availability with storage\n"
@@ -2621,6 +2651,8 @@ void osm_subn_output_conf(FILE *out, IN osm_subn_opt_t * p_opts)
 		p_opts->sm_inactive ? "TRUE" : "FALSE",
 		p_opts->babbling_port_policy ? "TRUE" : "FALSE",
 		p_opts->drop_event_subscriptions ? "TRUE" : "FALSE",
+		p_opts->ipoib_mcgroup_creation_validation ? "TRUE" : "FALSE",
+		p_opts->mcgroup_join_validation ? "TRUE" : "FALSE",
 		p_opts->use_optimized_slvl ? "TRUE" : "FALSE",
 		p_opts->fsync_high_avail_files ? "TRUE" : "FALSE");
 
@@ -2792,7 +2824,7 @@ void osm_subn_output_conf(FILE *out, IN osm_subn_opt_t * p_opts)
 
 	fprintf(out,
 		"#\n# Congestion Control SwitchCongestionSetting options\n#\n"
-		"# Control Map - bitmask indicating which of the following attributes are to be used\n"
+		"# Control Map - bitmask indicating which of the following are to be used\n"
 		"# bit 0 - victim mask\n"
 		"# bit 1 - credit mask\n"
 		"# bit 2 - threshold + packet size\n"
@@ -2926,10 +2958,10 @@ void osm_subn_output_conf(FILE *out, IN osm_subn_opt_t * p_opts)
 		fprintf(out, "%u:%u",
 			p_opts->cc_cct.entries[0].shift,
 			p_opts->cc_cct.entries[0].multiplier);
-		for (i = 0; i < p_opts->cc_cct.entries_len; i++) {
+		for (i = 1; i < p_opts->cc_cct.entries_len; i++) {
 			fprintf(out, ",%u:%u",
-				p_opts->cc_cct.entries[0].shift,
-				p_opts->cc_cct.entries[0].multiplier);
+				p_opts->cc_cct.entries[i].shift,
+				p_opts->cc_cct.entries[i].multiplier);
 		}
 		fprintf(out, "\n");
 	}
diff --git a/opensm/osm_switch.c b/opensm/osm_switch.c
index 11efd54..134c783 100644
--- a/opensm/osm_switch.c
+++ b/opensm/osm_switch.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
- * Copyright (c) 2002-2011 Mellanox Technologies LTD. All rights reserved.
+ * Copyright (c) 2002-2015 Mellanox Technologies LTD. All rights reserved.
  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
  * Copyright (c) 2009 HNR Consulting. All rights reserved.
  *
@@ -168,8 +168,8 @@ boolean_t osm_switch_get_lft_block(IN const osm_switch_t * p_sw,
 	if (base_lid_ho > p_sw->max_lid_ho)
 		return FALSE;
 
-	CL_ASSERT(base_lid_ho + IB_SMP_DATA_SIZE <= IB_LID_UCAST_END_HO);
-	memcpy(p_block, &(p_sw->lft[base_lid_ho]), IB_SMP_DATA_SIZE);
+	CL_ASSERT(base_lid_ho + IB_SMP_DATA_SIZE - 1 <= IB_LID_UCAST_END_HO);
+	memcpy(p_block, &(p_sw->new_lft[base_lid_ho]), IB_SMP_DATA_SIZE);
 	return TRUE;
 }
 
@@ -193,6 +193,9 @@ switch_find_guid_common(IN const osm_switch_t * p_sw,
 		goto out;
 
 	p_physp = osm_node_get_physp_ptr(p_sw->p_node, port_num);
+	if (!p_physp)
+		goto out;
+
 	p_rem_physp = osm_physp_get_remote(p_physp);
 	p_rem_node = osm_physp_get_node_ptr(p_rem_physp);
 	sys_guid = p_rem_node->node_info.sys_guid;
@@ -235,7 +238,8 @@ uint8_t osm_switch_recommend_path(IN const osm_switch_t * p_sw,
 				  IN boolean_t routing_for_lmc,
 				  IN boolean_t dor,
 				  IN boolean_t port_shifting,
-				  IN uint32_t scatter_ports)
+				  IN uint32_t scatter_ports,
+				  IN osm_lft_type_enum lft_enum)
 {
 	/*
 	   We support an enhanced LMC aware routing mode:
@@ -319,7 +323,7 @@ uint8_t osm_switch_recommend_path(IN const osm_switch_t * p_sw,
 	   4. the port has min-hops to the target (avoid loops)
 	 */
 	if (!ignore_existing) {
-		port_num = osm_switch_get_port_by_lid(p_sw, lid_ho);
+		port_num = osm_switch_get_port_by_lid(p_sw, lid_ho, lft_enum);
 
 		if (port_num != OSM_NO_PATH) {
 			CL_ASSERT(port_num < num_ports);
diff --git a/opensm/osm_ucast_cache.c b/opensm/osm_ucast_cache.c
index 2fab643..3caf318 100644
--- a/opensm/osm_ucast_cache.c
+++ b/opensm/osm_ucast_cache.c
@@ -1040,13 +1040,8 @@ int osm_ucast_cache_process(osm_ucast_mgr_t * p_mgr)
 	for (item = cl_qmap_head(tbl); item != cl_qmap_end(tbl);
 	     item = cl_qmap_next(item)) {
 		p_sw = (osm_switch_t *) item;
-
-		if (p_sw->need_update) {
-			if (!p_sw->new_lft)
-				/* no new routing was recently calculated for this
-				   switch, but the LFT needs to be updated anyway */
-				p_sw->new_lft = p_sw->lft;
-
+		CL_ASSERT(p_sw->new_lft);
+		if (!p_sw->lft) {
 			lft_size = (p_sw->max_lid_ho / IB_SMP_DATA_SIZE + 1)
 				   * IB_SMP_DATA_SIZE;
 			p_sw->lft = malloc(lft_size);
diff --git a/opensm/osm_ucast_dfsssp.c b/opensm/osm_ucast_dfsssp.c
index 76a91e6..4fb0334 100644
--- a/opensm/osm_ucast_dfsssp.c
+++ b/opensm/osm_ucast_dfsssp.c
@@ -1,8 +1,8 @@
 /*
  * Copyright (c) 2004-2008 Voltaire, Inc. All rights reserved.
- * Copyright (c) 2002-2009 Mellanox Technologies LTD. All rights reserved.
+ * Copyright (c) 2002-2015 Mellanox Technologies LTD. All rights reserved.
  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
- * Copyright (c) 2009-2011 ZIH, TU Dresden, Federal Republic of Germany. All rights reserved.
+ * Copyright (c) 2009-2015 ZIH, TU Dresden, Federal Republic of Germany. All rights reserved.
  * Copyright (C) 2012-2013 Tokyo Institute of Technology. All rights reserved.
  *
  * This software is available to you under a choice of one of two
@@ -95,6 +95,7 @@ typedef struct vertex {
 	uint32_t heap_id;
 	/* for LFT writing and debug */
 	osm_switch_t *sw;	/* selfpointer */
+	boolean_t dropped;	/* indicate dropped switches (w/ ucast cache) */
 } vertex_t;
 
 typedef struct binary_heap {
@@ -161,6 +162,7 @@ static inline void set_default_vertex(vertex_t * vertex)
 	vertex->state = UNDISCOVERED;
 	vertex->heap_id = 0;
 	vertex->sw = NULL;
+	vertex->dropped = FALSE;
 }
 
 static inline void set_default_cdg_node(cdg_node_t * node)
@@ -338,7 +340,7 @@ static void heap_free(binary_heap_t * heap)
 /**********************************************************************
  **********************************************************************/
 
-/************ helper functions to save src/dest X vl kombination ******
+/************ helper functions to save src/dest X vl combination ******
  **********************************************************************/
 /* compare function of two lids for stdlib qsort */
 static int cmp_lids(const void *l1, const void *l2)
@@ -375,7 +377,7 @@ static inline int64_t vltable_get_lidindex(ib_net16_t * key, vltable_t * vltable
 		return -1;
 }
 
-/* get virtual lane from src lid X dest lid kombination;
+/* get virtual lane from src lid X dest lid combination;
    return -1 for invalid lids
 */
 static int32_t vltable_get_vl(vltable_t * vltable, ib_net16_t slid, ib_net16_t dlid)
@@ -1258,7 +1260,7 @@ static int dfsssp_build_graph(void *context)
 		head = link;
 		head->next = NULL;
 
-		/* add SP0 to number of CA conneted to a switch */
+		/* add SP0 to number of CA connected to a switch */
 		lmc = osm_node_get_lmc(sw->p_node, 0);
 		adj_list[i].num_hca += (1 << lmc);
 
@@ -1558,6 +1560,13 @@ static int update_lft(osm_ucast_mgr_t * p_mgr, vertex_t * adj_list,
 					  (p_sw->p_node)));
 
 			p = osm_node_get_physp_ptr(p_sw->p_node, port);
+			if (!p) {
+				OSM_LOG(p_mgr->p_log, OSM_LOG_ERROR,
+					"ERR AD0A: Physical port %d of Node GUID 0x%"
+					PRIx64 "not found\n", port,
+					cl_ntoh64(osm_node_get_node_guid(p_sw->p_node)));
+				return 1;
+			}
 
 			/* we would like to optionally ignore this port in equalization
 			   as in the case of the Mellanox Anafa Internal PCI TCA port
@@ -1574,7 +1583,7 @@ static int update_lft(osm_ucast_mgr_t * p_mgr, vertex_t * adj_list,
 		}
 
 		/* to support lmc > 0 the functions alloc_ports_priv, free_ports_priv, find_and_add_remote_sys
-		   from minhop aren't needed cause osm_switch_recommend_path is implicit calulated
+		   from minhop aren't needed cause osm_switch_recommend_path is implicitly calculated
 		   for each LID pair thru dijkstra;
 		   for each port the dijkstra algorithm calculates (max_lid_ho - min_lid_ho)-times maybe
 		   disjoint routes to spread the bandwidth -> diffent routes for one port and lmc>0
@@ -1586,7 +1595,7 @@ static int update_lft(osm_ucast_mgr_t * p_mgr, vertex_t * adj_list,
 			/* update the number of path routing thru this port */
 			osm_switch_count_path(p_sw, port);
 		}
-		/* set te hop count from this switch to the lid */
+		/* set the hop count from this switch to the lid */
 		ret = osm_switch_set_hops(p_sw, lid, port, hops);
 		if (ret != CL_SUCCESS)
 			OSM_LOG(p_mgr->p_log, OSM_LOG_ERROR,
@@ -1632,6 +1641,9 @@ static void reset_mgrp_membership(vertex_t * adj_list, uint32_t adj_list_size)
 	uint32_t i = 0;
 
 	for (i = 1; i < adj_list_size; i++) {
+		if (adj_list[i].dropped)
+			continue;
+
 		adj_list[i].sw->is_mc_member = 0;
 		adj_list[i].sw->num_of_mcm = 0;
 	}
@@ -1657,6 +1669,9 @@ static int update_mcft(osm_sm_t * p_sm, vertex_t * adj_list,
 	OSM_LOG_ENTER(p_sm->p_log);
 
 	for (i = 1; i < adj_list_size; i++) {
+		if (adj_list[i].dropped)
+			continue;
+
 		p_sw = adj_list[i].sw;
 		OSM_LOG(p_sm->p_log, OSM_LOG_VERBOSE,
 			"Processing switch 0x%016" PRIx64
@@ -1759,7 +1774,7 @@ static void update_weights(osm_ucast_mgr_t * p_mgr, vertex_t * adj_list,
 	OSM_LOG_EXIT(p_mgr->p_log);
 }
 
-/* get the larges number of virtual lanes which is supported by all switches
+/* get the largest number of virtual lanes which is supported by all switches
    in the subnet
 */
 static uint8_t get_avail_vl_in_subn(osm_ucast_mgr_t * p_mgr)
@@ -1956,7 +1971,7 @@ static int dfsssp_remove_deadlocks(dfsssp_context_t * dfsssp_ctx)
 								"ERR AD14: cannot allocate memory for cdg node or link in update_channel_dep_graph(...)\n");
 							goto ERROR;
 						}
-						/* add the <s,d> kombination / coresponding virtual lane to the VL table */
+						/* add the <s,d> combination / corresponding virtual lane to the VL table */
 						vltable_insert
 						    (srcdest2vl_table,
 						     cl_hton16(slid),
@@ -2517,24 +2532,68 @@ static ib_api_status_t dfsssp_do_mcast_routing(void * context,
 	uint32_t adj_list_size = dfsssp_ctx->adj_list_size;
 	cl_qlist_t mcastgrp_port_list;
 	cl_qmap_t mcastgrp_port_map;
-	osm_switch_t *root_sw = NULL;
+	osm_switch_t *root_sw = NULL, *p_sw = NULL;
 	osm_port_t *port = NULL;
 	ib_net16_t lid = 0;
-	uint32_t err = 0, num_ports = 0;
+	uint32_t err = 0, num_ports = 0, i = 0;
+	ib_net64_t guid = 0;
 	ib_api_status_t status = IB_SUCCESS;
 
 	OSM_LOG_ENTER(sm->p_log);
 
+	/* using the ucast cache feature with dfsssp might mean that a leaf sw
+	   got removed (and got back) without calling dfsssp_build_graph
+	   and therefore the adj_list (and pointers to osm's internal switches)
+	   could be outdated (here we have no knowledge if it has happened, so
+	   unfortunately a check is necessary... still better than rebuilding
+	   adj_list every time we arrive here)
+	 */
+	if (p_mgr->p_subn->opt.use_ucast_cache && p_mgr->cache_valid) {
+		for (i = 1; i < adj_list_size; i++) {
+			guid = cl_hton64(adj_list[i].guid);
+			p_sw = osm_get_switch_by_guid(p_mgr->p_subn, guid);
+			if (p_sw) {
+				/* check if switch came back from the dead */
+				if (adj_list[i].dropped)
+					adj_list[i].dropped = FALSE;
+
+				/* verify that sw object has not been moved
+				   (this can happen for a leaf switch, if it
+				   was dropped and came back later without a
+				   rerouting), otherwise we have to update
+				   dfsssp's internal switch list with the new
+				   sw pointer
+				 */
+				if (p_sw == adj_list[i].sw)
+					continue;
+				else
+					adj_list[i].sw = p_sw;
+			} else {
+				/* if a switch from adj_list is not in the
+				   sw_guid_tbl anymore, then the only reason is
+				   that it was a leaf switch and opensm dropped
+				   it without calling a rerouting
+				   -> calling dijkstra is no problem, since it
+				      is a leaf and different from root_sw
+				   -> only update_mcft and reset_mgrp_membership
+				      need to be aware of these dropped switches
+				 */
+				if (!adj_list[i].dropped)
+					adj_list[i].dropped = TRUE;
+			}
+		}
+	}
+
 	/* create a map and a list of all ports which are member in the mcast
 	   group; map for searching elements and list for iteration
 	 */
 	if (osm_mcast_make_port_list_and_map(&mcastgrp_port_list,
 					     &mcastgrp_port_map, mbox)) {
 		OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR AD50: "
-                        "Insufficient memory to make port list\n");
-                status = IB_ERROR;
-                goto Exit;
-        }
+			"Insufficient memory to make port list\n");
+		status = IB_ERROR;
+		goto Exit;
+	}
 
 	num_ports = cl_qlist_count(&mcastgrp_port_list);
 	if (num_ports < 2) {
diff --git a/opensm/osm_ucast_file.c b/opensm/osm_ucast_file.c
index 730ce80..f891281 100644
--- a/opensm/osm_ucast_file.c
+++ b/opensm/osm_ucast_file.c
@@ -85,7 +85,7 @@ static void add_path(osm_opensm_t * p_osm,
 	uint8_t old_port;
 
 	new_lid = port_guid ? remap_lid(p_osm, lid, port_guid) : lid;
-	old_port = osm_switch_get_port_by_lid(p_sw, new_lid);
+	old_port = osm_switch_get_port_by_lid(p_sw, new_lid, OSM_LFT);
 	if (old_port != OSM_NO_PATH && old_port != port_num) {
 		OSM_LOG(&p_osm->log, OSM_LOG_VERBOSE,
 			"LID collision is detected on switch "
diff --git a/opensm/osm_ucast_ftree.c b/opensm/osm_ucast_ftree.c
index f646bd0..dc978a6 100644
--- a/opensm/osm_ucast_ftree.c
+++ b/opensm/osm_ucast_ftree.c
@@ -141,8 +141,8 @@ typedef union ftree_hca_or_sw_ {
 
 typedef struct ftree_port_group_t_ {
 	cl_map_item_t map_item;
-	uint16_t base_lid;	/* base lid of the current node */
-	uint16_t remote_base_lid;	/* base lid of the remote node */
+	uint16_t lid;	/* lid of the current node */
+	uint16_t remote_lid;	/* lid of the remote node */
 	ib_net64_t port_guid;	/* port guid of this port */
 	ib_net64_t node_guid;	/* this node's guid */
 	uint8_t node_type;	/* this node's type */
@@ -169,7 +169,7 @@ typedef struct ftree_sw_t_ {
 	osm_switch_t *p_osm_sw;
 	uint32_t rank;
 	ftree_tuple_t tuple;
-	uint16_t base_lid;
+	uint16_t lid;
 	ftree_port_group_t **down_port_groups;
 	uint8_t down_port_groups_num;
 	ftree_port_group_t **sibling_port_groups;
@@ -193,6 +193,7 @@ typedef struct ftree_hca_t_ {
 	cl_map_item_t map_item;
 	osm_node_t *p_osm_node;
 	ftree_port_group_t **up_port_groups;
+	uint8_t *disconnected_ports;
 	uint16_t up_port_groups_num;
 	unsigned cn_num;
 } ftree_hca_t;
@@ -205,6 +206,7 @@ typedef struct ftree_hca_t_ {
 
 typedef struct ftree_fabric_t_ {
 	osm_opensm_t *p_osm;
+	osm_subn_t *p_subn;
 	cl_qmap_t hca_tbl;
 	cl_qmap_t sw_tbl;
 	cl_qmap_t sw_by_tuple_tbl;
@@ -221,6 +223,11 @@ typedef struct ftree_fabric_t_ {
 	boolean_t fabric_built;
 } ftree_fabric_t;
 
+static inline osm_subn_t *ftree_get_subnet(IN ftree_fabric_t * p_ftree)
+{
+	return p_ftree->p_subn;
+}
+
 /***************************************************
  **
  ** comparators
@@ -377,8 +384,8 @@ static void port_destroy(IN ftree_port_t * p_port)
  **
  ***************************************************/
 
-static ftree_port_group_t *port_group_create(IN uint16_t base_lid,
-					     IN uint16_t remote_base_lid,
+static ftree_port_group_t *port_group_create(IN uint16_t lid,
+					     IN uint16_t remote_lid,
 					     IN ib_net64_t port_guid,
 					     IN ib_net64_t node_guid,
 					     IN uint8_t node_type,
@@ -396,8 +403,8 @@ static ftree_port_group_t *port_group_create(IN uint16_t base_lid,
 		return NULL;
 	memset(p_group, 0, sizeof(ftree_port_group_t));
 
-	p_group->base_lid = base_lid;
-	p_group->remote_base_lid = remote_base_lid;
+	p_group->lid = lid;
+	p_group->remote_lid = remote_lid;
 	memcpy(&p_group->port_guid, &port_guid, sizeof(ib_net64_t));
 	memcpy(&p_group->node_guid, &node_guid, sizeof(ib_net64_t));
 	memcpy(&p_group->remote_port_guid, &remote_port_guid,
@@ -470,7 +477,7 @@ static void port_group_dump(IN ftree_fabric_t * p_ftree,
 	ftree_port_t *p_port;
 	uint32_t size;
 	uint32_t i;
-	char buff[10 * 1024];
+	char *buff;
 
 	if (!p_group)
 		return;
@@ -479,7 +486,13 @@ static void port_group_dump(IN ftree_fabric_t * p_ftree,
 		return;
 
 	size = cl_ptr_vector_get_size(&p_group->ports);
-	buff[0] = '\0';
+
+	buff = calloc(10, 1024);
+	if (!buff) {
+		OSM_LOG(&p_ftree->p_osm->log, OSM_LOG_ERROR, "ERR AB33: "
+			"Failed to allocate buffer\n");
+		return;
+	}
 
 	for (i = 0; i < size; i++) {
 		cl_ptr_vector_at(&p_group->ports, i, (void *)&p_port);
@@ -498,8 +511,10 @@ static void port_group_dump(IN ftree_fabric_t * p_ftree,
 		(direction == FTREE_DIRECTION_DOWN) ? "DOWN" : (direction ==
 								FTREE_DIRECTION_SAME)
 		? "SIBLING" : "UP", cl_ntoh64(p_group->port_guid),
-		p_group->base_lid, cl_ntoh64(p_group->remote_port_guid),
-		p_group->remote_base_lid);
+		p_group->lid, cl_ntoh64(p_group->remote_port_guid),
+		p_group->remote_lid);
+
+	free(buff);
 
 }				/* port_group_dump() */
 
@@ -528,8 +543,7 @@ static void port_group_add_port(IN ftree_port_group_t * p_group,
  **
  ***************************************************/
 
-static ftree_sw_t *sw_create(IN ftree_fabric_t * p_ftree,
-			     IN osm_switch_t * p_osm_sw)
+static ftree_sw_t *sw_create(IN osm_switch_t * p_osm_sw)
 {
 	ftree_sw_t *p_sw;
 	uint8_t ports_num;
@@ -547,7 +561,7 @@ static ftree_sw_t *sw_create(IN ftree_fabric_t * p_ftree,
 	p_sw->rank = 0xFFFFFFFF;
 	tuple_init(p_sw->tuple);
 
-	p_sw->base_lid =
+	p_sw->lid =
 	    cl_ntoh16(osm_node_get_base_lid(p_sw->p_osm_sw->p_node, 0));
 
 	ports_num = osm_node_get_num_physp(p_sw->p_osm_sw->p_node);
@@ -595,7 +609,7 @@ FREE_P_SW:
 
 /***************************************************/
 
-static void sw_destroy(IN ftree_fabric_t * p_ftree, IN ftree_sw_t * p_sw)
+static void sw_destroy(IN ftree_sw_t * p_sw)
 {
 	uint8_t i;
 
@@ -674,7 +688,7 @@ static boolean_t sw_ranked(IN ftree_sw_t * p_sw)
 
 static ftree_port_group_t *sw_get_port_group_by_remote_lid(IN ftree_sw_t * p_sw,
 							   IN uint16_t
-							   remote_base_lid,
+							   remote_lid,
 							   IN ftree_direction_t
 							   direction)
 {
@@ -694,7 +708,7 @@ static ftree_port_group_t *sw_get_port_group_by_remote_lid(IN ftree_sw_t * p_sw,
 	}
 
 	for (i = 0; i < size; i++)
-		if (remote_base_lid == port_groups[i]->remote_base_lid)
+		if (remote_lid == port_groups[i]->remote_lid)
 			return port_groups[i];
 
 	return NULL;
@@ -703,8 +717,8 @@ static ftree_port_group_t *sw_get_port_group_by_remote_lid(IN ftree_sw_t * p_sw,
 /***************************************************/
 
 static void sw_add_port(IN ftree_sw_t * p_sw, IN uint8_t port_num,
-			IN uint8_t remote_port_num, IN uint16_t base_lid,
-			IN uint16_t remote_base_lid, IN ib_net64_t port_guid,
+			IN uint8_t remote_port_num, IN uint16_t lid,
+			IN uint16_t remote_lid, IN ib_net64_t port_guid,
 			IN ib_net64_t remote_port_guid,
 			IN ib_net64_t remote_node_guid,
 			IN uint8_t remote_node_type,
@@ -712,10 +726,10 @@ static void sw_add_port(IN ftree_sw_t * p_sw, IN uint8_t port_num,
 			IN ftree_direction_t direction)
 {
 	ftree_port_group_t *p_group =
-	    sw_get_port_group_by_remote_lid(p_sw, remote_base_lid, direction);
+	    sw_get_port_group_by_remote_lid(p_sw, remote_lid, direction);
 
 	if (!p_group) {
-		p_group = port_group_create(base_lid, remote_base_lid,
+		p_group = port_group_create(lid, remote_lid,
 					    port_guid, sw_get_guid_no(p_sw),
 					    IB_NODE_TYPE_SWITCH, p_sw,
 					    remote_port_guid, remote_node_guid,
@@ -812,6 +826,14 @@ static ftree_hca_t *hca_create(IN osm_node_t * p_osm_node)
 	}
 	memset(p_hca->up_port_groups, 0, osm_node_get_num_physp(p_hca->p_osm_node) *
 	       sizeof(ftree_port_group_t *));
+
+	p_hca->disconnected_ports = (uint8_t *)
+	    calloc(osm_node_get_num_physp(p_hca->p_osm_node) + 1, sizeof(uint8_t));
+	if (!p_hca->disconnected_ports) {
+		free(p_hca->up_port_groups);
+		free(p_hca);
+		return NULL;
+	}
 	p_hca->up_port_groups_num = 0;
 	return p_hca;
 }
@@ -829,6 +851,7 @@ static void hca_destroy(IN ftree_hca_t * p_hca)
 		port_group_destroy(p_hca->up_port_groups[i]);
 
 	free(p_hca->up_port_groups);
+	free(p_hca->disconnected_ports);
 
 	free(p_hca);
 }
@@ -870,42 +893,25 @@ static void hca_dump(IN ftree_fabric_t * p_ftree, IN ftree_hca_t * p_hca)
 				FTREE_DIRECTION_UP);
 }
 
-/***************************************************/
-
-static ftree_port_group_t *hca_get_port_group_by_remote_lid(IN ftree_hca_t *
-							    p_hca,
-							    IN uint16_t
-							    remote_base_lid)
-{
-	uint32_t i;
-	for (i = 0; i < p_hca->up_port_groups_num; i++)
-		if (remote_base_lid ==
-		    p_hca->up_port_groups[i]->remote_base_lid)
-			return p_hca->up_port_groups[i];
-
-	return NULL;
-}
-
 static ftree_port_group_t *hca_get_port_group_by_lid(IN ftree_hca_t *
 						     p_hca,
 						     IN uint16_t
-						     base_lid)
+						     lid)
 {
 	uint32_t i;
 	for (i = 0; i < p_hca->up_port_groups_num; i++)
-		if (base_lid ==
-		    p_hca->up_port_groups[i]->base_lid)
+		if (lid ==
+		    p_hca->up_port_groups[i]->lid)
 			return p_hca->up_port_groups[i];
 
 	return NULL;
-
 }
 /***************************************************/
 
 static void hca_add_port(IN ftree_fabric_t * p_ftree,
 			 IN ftree_hca_t * p_hca, IN uint8_t port_num,
-			 IN uint8_t remote_port_num, IN uint16_t base_lid,
-			 IN uint16_t remote_base_lid, IN ib_net64_t port_guid,
+			 IN uint8_t remote_port_num, IN uint16_t lid,
+			 IN uint16_t remote_lid, IN ib_net64_t port_guid,
 			 IN ib_net64_t remote_port_guid,
 			 IN ib_net64_t remote_node_guid,
 			 IN uint8_t remote_node_type,
@@ -918,10 +924,10 @@ static void hca_add_port(IN ftree_fabric_t * p_ftree,
 	   in hca's that lead to switches */
 	CL_ASSERT(remote_node_type == IB_NODE_TYPE_SWITCH);
 
-	p_group = hca_get_port_group_by_lid(p_hca, base_lid);
+	p_group = hca_get_port_group_by_lid(p_hca, lid);
 
 	if (!p_group) {
-		p_group = port_group_create(base_lid, remote_base_lid,
+		p_group = port_group_create(lid, remote_lid,
 					    port_guid, hca_get_guid_no(p_hca),
 					    IB_NODE_TYPE_CA, p_hca,
 					    remote_port_guid, remote_node_guid,
@@ -991,7 +997,7 @@ static void fabric_clear(ftree_fabric_t * p_ftree)
 	while (p_next_sw != (ftree_sw_t *) cl_qmap_end(&p_ftree->sw_tbl)) {
 		p_sw = p_next_sw;
 		p_next_sw = (ftree_sw_t *) cl_qmap_next(&p_sw->map_item);
-		sw_destroy(p_ftree, p_sw);
+		sw_destroy(p_sw);
 	}
 	cl_qmap_remove_all(&p_ftree->sw_tbl);
 
@@ -1089,7 +1095,7 @@ static void fabric_add_sw(ftree_fabric_t * p_ftree, osm_switch_t * p_osm_sw)
 
 	CL_ASSERT(osm_node_get_type(p_osm_sw->p_node) == IB_NODE_TYPE_SWITCH);
 
-	p_sw = sw_create(p_ftree, p_osm_sw);
+	p_sw = sw_create(p_osm_sw);
 	if (!p_sw)
 		return;
 
@@ -1097,8 +1103,8 @@ static void fabric_add_sw(ftree_fabric_t * p_ftree, osm_switch_t * p_osm_sw)
 		       &p_sw->map_item);
 
 	/* track the max lid (in host order) that exists in the fabric */
-	if (p_sw->base_lid > p_ftree->lft_max_lid)
-		p_ftree->lft_max_lid = p_sw->base_lid;
+	if (p_sw->lid > p_ftree->lft_max_lid)
+		p_ftree->lft_max_lid = p_sw->lid;
 }
 
 /***************************************************/
@@ -1255,7 +1261,7 @@ static void fabric_dump_general_info(IN ftree_fabric_t * p_ftree)
 					"      GUID: 0x%016" PRIx64
 					", LID: %u, Index %s\n",
 					sw_get_guid_ho(p_sw),
-					p_sw->base_lid,
+					p_sw->lid,
 					tuple_to_str(p_sw->tuple));
 		}
 
@@ -1266,7 +1272,7 @@ static void fabric_dump_general_info(IN ftree_fabric_t * p_ftree)
 				"      GUID: 0x%016" PRIx64
 				", LID: %u, Index %s\n",
 				sw_get_guid_ho(p_ftree->leaf_switches[i]),
-				p_ftree->leaf_switches[i]->base_lid,
+				p_ftree->leaf_switches[i]->lid,
 				tuple_to_str(p_ftree->leaf_switches[i]->tuple));
 		}
 	}
@@ -1312,16 +1318,16 @@ static void fabric_dump_hca_ordering(IN ftree_fabric_t * p_ftree)
 
 			p_hca = p_group_on_sw->remote_hca_or_sw.p_hca;
 			p_group_on_hca =
-			    hca_get_port_group_by_remote_lid(p_hca,
-							     p_group_on_sw->
-							     base_lid);
+			    hca_get_port_group_by_lid(p_hca,
+						      p_group_on_sw->
+						      remote_lid);
 
 			/* treat non-compute nodes as dummies */
 			if (!p_group_on_hca->is_cn)
 				continue;
 
 			fprintf(p_hca_ordering_file, "0x%04x\t%s\n",
-				p_group_on_hca->base_lid,
+				p_group_on_hca->lid,
 				p_hca->p_osm_node->print_desc);
 
 			printed_hcas_on_leaf++;
@@ -1351,16 +1357,35 @@ static void fabric_assign_tuple(IN ftree_fabric_t * p_ftree,
 /***************************************************/
 
 static void fabric_assign_first_tuple(IN ftree_fabric_t * p_ftree,
-				      IN ftree_sw_t * p_sw)
+				      IN ftree_sw_t * p_sw,
+				      IN unsigned int subtree)
 {
 	uint8_t i;
 	ftree_tuple_t new_tuple;
 
+	if (p_ftree->leaf_switch_rank >= FTREE_TUPLE_LEN)
+		return;
+
 	tuple_init(new_tuple);
 	new_tuple[0] = (uint8_t) p_sw->rank;
-	for (i = 1; i <= p_sw->rank; i++)
+
+	for (i = 1; i <= p_ftree->leaf_switch_rank; i++)
 		new_tuple[i] = 0;
 
+	if (p_sw->rank == 0) {
+		if (p_ftree->leaf_switch_rank > 1)
+			new_tuple[p_ftree->leaf_switch_rank] = subtree;
+
+		for (i = 0; i < 0xFF; i++) {
+			new_tuple[1] = i;
+			if (fabric_get_sw_by_tuple(p_ftree, new_tuple) == NULL)
+				break;
+		}
+		if (i == 0xFF) {
+			/* new tuple not found - there are more than 255 ports in one direction */
+			return;
+		}
+	}
 	fabric_assign_tuple(p_ftree, p_sw, new_tuple);
 }
 
@@ -1487,46 +1512,17 @@ Exit:
 }				/* fabric_mark_leaf_switches() */
 
 /***************************************************/
-
-static void fabric_make_indexing(IN ftree_fabric_t * p_ftree)
+static void bfs_fabric_indexing(IN ftree_fabric_t * p_ftree,
+				IN ftree_sw_t *p_first_sw)
 {
 	ftree_sw_t *p_remote_sw;
 	ftree_sw_t *p_sw = NULL;
-	ftree_sw_t *p_next_sw;
 	ftree_tuple_t new_tuple;
 	uint32_t i;
 	cl_list_t bfs_list;
 
 	OSM_LOG_ENTER(&p_ftree->p_osm->log);
-
-	OSM_LOG(&p_ftree->p_osm->log, OSM_LOG_VERBOSE,
-		"Starting FatTree indexing\n");
-
-	/* using the first leaf switch as a starting point for indexing algorithm. */
-	p_next_sw = (ftree_sw_t *) cl_qmap_head(&p_ftree->sw_tbl);
-	while (p_next_sw != (ftree_sw_t *) cl_qmap_end(&p_ftree->sw_tbl)) {
-		p_sw = p_next_sw;
-		if (p_sw->is_leaf)
-			break;
-		p_next_sw = (ftree_sw_t *) cl_qmap_next(&p_sw->map_item);
-	}
-
-	CL_ASSERT(p_next_sw != (ftree_sw_t *) cl_qmap_end(&p_ftree->sw_tbl));
-
-	/* Assign the first tuple to the switch that is used as BFS starting point.
-	   The tuple will be as follows: [rank].0.0.0...
-	   This fuction also adds the switch it into the switch_by_tuple table. */
-	fabric_assign_first_tuple(p_ftree, p_sw);
-
-	OSM_LOG(&p_ftree->p_osm->log, OSM_LOG_VERBOSE,
-		"Indexing starting point:\n"
-		"                                            - Switch rank  : %u\n"
-		"                                            - Switch index : %s\n"
-		"                                            - Node LID     : %u\n"
-		"                                            - Node GUID    : 0x%016"
-		PRIx64 "\n", p_sw->rank, tuple_to_str(p_sw->tuple),
-		p_sw->base_lid, sw_get_guid_ho(p_sw));
-
+	cl_list_init(&bfs_list, cl_qmap_count(&p_ftree->sw_tbl));
 	/*
 	 * Now run BFS and assign indexes to all switches
 	 * Pseudo code of the algorithm is as follows:
@@ -1541,8 +1537,7 @@ static void fabric_make_indexing(IN ftree_fabric_t * p_ftree)
 	 *          + Add remote switch to the BFS queue
 	 */
 
-	cl_list_init(&bfs_list, cl_qmap_count(&p_ftree->sw_tbl));
-	cl_list_insert_tail(&bfs_list, p_sw);
+	cl_list_insert_tail(&bfs_list, p_first_sw);
 
 	while (!cl_is_list_empty(&bfs_list)) {
 		p_sw = (ftree_sw_t *) cl_list_remove_head(&bfs_list);
@@ -1592,9 +1587,10 @@ static void fabric_make_indexing(IN ftree_fabric_t * p_ftree)
 		}
 
 		/* Done indexing switches from ports that go down.
-		   Now do the same with ports that are pointing up. */
+		   Now do the same with ports that are pointing up.
+		   if we started from root (rank == 0), the leaf is bsf termination point */
 
-		if (p_sw->rank != 0) {
+		if (p_sw->rank != 0 && (p_first_sw->rank != 0 || !p_sw->is_leaf)) {
 			/* This is not the root switch, which means that all the ports
 			   that are pointing up are taking us to another switches. */
 			for (i = 0; i < p_sw->up_port_groups_num; i++) {
@@ -1629,8 +1625,65 @@ static void fabric_make_indexing(IN ftree_fabric_t * p_ftree)
 	cl_list_destroy(&bfs_list);
 
 	OSM_LOG_EXIT(&p_ftree->p_osm->log);
-}				/* fabric_make_indexing() */
+}
+
+static void fabric_make_indexing(IN ftree_fabric_t * p_ftree)
+{
+	ftree_sw_t *p_sw = NULL;
+	unsigned int subtree = 0;
+	OSM_LOG_ENTER(&p_ftree->p_osm->log);
 
+	OSM_LOG(&p_ftree->p_osm->log, OSM_LOG_VERBOSE,
+		"Starting FatTree indexing\n");
+
+	/* using the first switch as a starting point for indexing algorithm. */
+	for (p_sw = (ftree_sw_t *) cl_qmap_head(&p_ftree->sw_tbl);
+	     p_sw != (ftree_sw_t *) cl_qmap_end(&p_ftree->sw_tbl);
+	     p_sw = (ftree_sw_t *) cl_qmap_next(&p_sw->map_item)) {
+		if (ftree_get_subnet(p_ftree)->opt.quasi_ftree_indexing) {
+			/* find first root switch */
+			if (p_sw->rank != 0)
+				continue;
+		} else {
+			/* find first leaf switch */
+			if (!p_sw->is_leaf)
+				continue;
+		}
+		/* Assign the first tuple to the switch that is used as BFS starting point
+		   in the subtree.
+		   The tuple will be as follows: [rank].0...0.subtree
+		   This fuction also adds the switch it into the switch_by_tuple table. */
+		if (!tuple_assigned(p_sw->tuple)) {
+			fabric_assign_first_tuple(p_ftree, p_sw, subtree++);
+			OSM_LOG(&p_ftree->p_osm->log, OSM_LOG_VERBOSE,
+			"Indexing starting point:\n"
+			"                                            - Switch rank  : %u\n"
+			"                                            - Switch index : %s\n"
+			"                                            - Node LID     : %u\n"
+			"                                            - Node GUID    : 0x%016"
+			PRIx64 "\n", p_sw->rank, tuple_to_str(p_sw->tuple),
+			p_sw->lid, sw_get_guid_ho(p_sw));
+		}
+
+		bfs_fabric_indexing(p_ftree, p_sw);
+
+		if (ftree_get_subnet(p_ftree)->opt.quasi_ftree_indexing == FALSE)
+			goto Exit;
+	}
+	p_sw = (ftree_sw_t *) cl_qmap_head(&p_ftree->sw_tbl);
+	while (p_sw != (ftree_sw_t *) cl_qmap_end(&p_ftree->sw_tbl)) {
+		if (p_sw->is_leaf) {
+			qsort(p_sw->up_port_groups,	/* array */
+			      p_sw->up_port_groups_num,	/* number of elements */
+			      sizeof(ftree_port_group_t *),	/* size of each element */
+			      compare_port_groups_by_remote_switch_index);	/* comparator */
+		}
+		p_sw = (ftree_sw_t *) cl_qmap_next(&p_sw->map_item);
+
+	}
+Exit:
+	OSM_LOG_EXIT(&p_ftree->p_osm->log);
+}				/* fabric_make_indexing() */
 /***************************************************/
 
 static int fabric_create_leaf_switch_array(IN ftree_fabric_t * p_ftree)
@@ -1737,7 +1790,8 @@ static void fabric_set_max_cn_per_leaf(IN ftree_fabric_t * p_ftree)
 	unsigned j;
 	unsigned cns_on_this_leaf;
 	ftree_sw_t *p_sw;
-	ftree_port_group_t *p_group;
+	ftree_port_group_t *p_group, *p_up_group;
+	ftree_hca_t *p_hca;
 
 	for (i = 0; i < p_ftree->leaf_switches_num; i++) {
 		p_sw = p_ftree->leaf_switches[i];
@@ -1746,8 +1800,18 @@ static void fabric_set_max_cn_per_leaf(IN ftree_fabric_t * p_ftree)
 			p_group = p_sw->down_port_groups[j];
 			if (p_group->remote_node_type != IB_NODE_TYPE_CA)
 				continue;
-			cns_on_this_leaf +=
-			    p_group->remote_hca_or_sw.p_hca->cn_num;
+			p_hca = p_group->remote_hca_or_sw.p_hca;
+			/*
+			 * Get the hca port group corresponding
+			 * to the LID of remote HCA port
+			 */
+			p_up_group = hca_get_port_group_by_lid(p_hca,
+				     p_group->remote_lid);
+
+			CL_ASSERT(p_up_group);
+
+			if (p_up_group->is_cn)
+				cns_on_this_leaf++;
 		}
 		if (cns_on_this_leaf > p_ftree->max_cn_per_leaf)
 			p_ftree->max_cn_per_leaf = cns_on_this_leaf;
@@ -1803,13 +1867,13 @@ static boolean_t fabric_validate_topology(IN ftree_fabric_t * p_ftree)
 					", LID %u, Index %s - %u groups\n",
 					sw_get_guid_ho
 					(reference_sw_arr[p_sw->rank]),
-					reference_sw_arr[p_sw->rank]->base_lid,
+					reference_sw_arr[p_sw->rank]->lid,
 					tuple_to_str
 					(reference_sw_arr[p_sw->rank]->tuple),
 					reference_sw_arr[p_sw->
 							 rank]->
 					up_port_groups_num,
-					sw_get_guid_ho(p_sw), p_sw->base_lid,
+					sw_get_guid_ho(p_sw), p_sw->lid,
 					tuple_to_str(p_sw->tuple),
 					p_sw->up_port_groups_num);
 				res = FALSE;
@@ -1829,13 +1893,13 @@ static boolean_t fabric_validate_topology(IN ftree_fabric_t * p_ftree)
 					", LID %u, Index %s - %u port groups\n",
 					sw_get_guid_ho
 					(reference_sw_arr[p_sw->rank]),
-					reference_sw_arr[p_sw->rank]->base_lid,
+					reference_sw_arr[p_sw->rank]->lid,
 					tuple_to_str
 					(reference_sw_arr[p_sw->rank]->tuple),
 					reference_sw_arr[p_sw->
 							 rank]->
 					down_port_groups_num,
-					sw_get_guid_ho(p_sw), p_sw->base_lid,
+					sw_get_guid_ho(p_sw), p_sw->lid,
 					tuple_to_str(p_sw->tuple),
 					p_sw->down_port_groups_num);
 				res = FALSE;
@@ -1867,14 +1931,14 @@ static boolean_t fabric_validate_topology(IN ftree_fabric_t * p_ftree)
 							 [p_sw->rank]),
 							reference_sw_arr[p_sw->
 									 rank]->
-							base_lid,
+							lid,
 							tuple_to_str
 							(reference_sw_arr
 							 [p_sw->rank]->tuple),
 							cl_ptr_vector_get_size
 							(&p_ref_group->ports),
 							sw_get_guid_ho(p_sw),
-							p_sw->base_lid,
+							p_sw->lid,
 							tuple_to_str(p_sw->
 								     tuple),
 							cl_ptr_vector_get_size
@@ -1910,14 +1974,14 @@ static boolean_t fabric_validate_topology(IN ftree_fabric_t * p_ftree)
 							 [p_sw->rank]),
 							reference_sw_arr[p_sw->
 									 rank]->
-							base_lid,
+							lid,
 							tuple_to_str
 							(reference_sw_arr
 							 [p_sw->rank]->tuple),
 							cl_ptr_vector_get_size
 							(&p_ref_group->ports),
 							sw_get_guid_ho(p_sw),
-							p_sw->base_lid,
+							p_sw->lid,
 							tuple_to_str(p_sw->
 								     tuple),
 							cl_ptr_vector_get_size
@@ -2213,7 +2277,7 @@ fabric_route_upgoing_by_going_down(IN ftree_fabric_t * p_ftree,
 		}
 
 		if (p_prev_sw
-		    && p_group->remote_base_lid == p_prev_sw->base_lid) {
+		    && p_group->remote_lid == p_prev_sw->lid) {
 			/* This port group has a port that was used when we entered this switch,
 			   which means that the current group points to the switch where we were
 			   at the previous step of the algorithm (before going up).
@@ -2250,9 +2314,9 @@ fabric_route_upgoing_by_going_down(IN ftree_fabric_t * p_ftree,
 				"Switch %s (LID %u) closes loop through switch %s (LID %u)\n",
 				current_hops,
 				tuple_to_str(p_remote_sw->tuple),
-				p_group->base_lid,
+				p_group->lid,
 				tuple_to_str(p_sw->tuple),
-				p_group->remote_base_lid);
+				p_group->remote_lid);
 			/* We skip only if we have come through a longer path */
 			if (current_hops + 1 >= least_hops)
 				continue;
@@ -2756,9 +2820,9 @@ static void fabric_route_to_cns(IN ftree_fabric_t * p_ftree)
 				continue;
 
 			p_hca_port_group =
-			    hca_get_port_group_by_remote_lid(p_hca,
-							     p_leaf_port_group->
-							     base_lid);
+			    hca_get_port_group_by_lid(p_hca,
+						      p_leaf_port_group->
+						      remote_lid);
 			CL_ASSERT(p_hca_port_group);
 
 			/* work with this port group only if remote port is CN */
@@ -2766,7 +2830,7 @@ static void fabric_route_to_cns(IN ftree_fabric_t * p_ftree)
 				continue;
 
 			/* obtain the LID of HCA port */
-			hca_lid = p_leaf_port_group->remote_base_lid;
+			hca_lid = p_leaf_port_group->remote_lid;
 
 			/* set local LFT(LID) to the port that is connected to HCA */
 			cl_ptr_vector_at(&p_leaf_port_group->ports, 0,
@@ -2809,6 +2873,7 @@ static void fabric_route_to_cns(IN ftree_fabric_t * p_ftree)
 			     p_ftree->max_cn_per_leaf - routed_targets_on_leaf;
 			     j++) {
 				ftree_sw_t *p_next_sw, *p_ftree_sw;
+				sw_set_hops(p_sw, 0, 0xFF, 1, FALSE);
 				/* assign downgoing ports by stepping up */
 				fabric_route_downgoing_by_going_up(p_ftree, p_sw,	/* local switch - used as a route-downgoing alg. start point */
 								   NULL,	/* prev. position switch */
@@ -2885,7 +2950,7 @@ static void fabric_route_to_non_cns(IN ftree_fabric_t * p_ftree)
 				continue;
 
 			p_sw = p_hca_port_group->remote_hca_or_sw.p_sw;
-			hca_lid = p_hca_port_group->base_lid;
+			hca_lid = p_hca_port_group->lid;
 
 			/* set switches  LFT(LID) to the port that is connected to HCA */
 			cl_ptr_vector_at(&p_hca_port_group->ports, 0,
@@ -2948,19 +3013,19 @@ static void fabric_route_to_switches(IN ftree_fabric_t * p_ftree)
 		p_next_sw = (ftree_sw_t *) cl_qmap_next(&p_sw->map_item);
 
 		/* set local LFT(LID) to 0 (route to itself) */
-		p_sw->p_osm_sw->new_lft[p_sw->base_lid] = 0;
+		p_sw->p_osm_sw->new_lft[p_sw->lid] = 0;
 
 		OSM_LOG(&p_ftree->p_osm->log, OSM_LOG_DEBUG,
 			"Switch %s (LID %u): routing switch-to-switch paths\n",
-			tuple_to_str(p_sw->tuple), p_sw->base_lid);
+			tuple_to_str(p_sw->tuple), p_sw->lid);
 
 		/* set min hop table of the switch to itself */
-		sw_set_hops(p_sw, p_sw->base_lid, 0,	/* port_num */
+		sw_set_hops(p_sw, p_sw->lid, 0,	/* port_num */
 			    0, TRUE);	/* hops     */
 
 		fabric_route_downgoing_by_going_up(p_ftree, p_sw,	/* local switch - used as a route-downgoing alg. start point */
 						   NULL,	/* prev. position switch */
-						   p_sw->base_lid,	/* LID that we're routing to */
+						   p_sw->lid,	/* LID that we're routing to */
 						   FALSE,	/* whether this path to HCA should by tracked by counters */
 						   TRUE,	/* Whether the target LID is a switch or not */
 						   0,	/* Number of reverse hops allowed */
@@ -3030,7 +3095,7 @@ static void fabric_route_roots(IN ftree_fabric_t * p_ftree)
 			 * the missing LID will be routed through the same
 			 * port that routes to the selected leaf switch
 			 */
-			port_num = p_sw->p_osm_sw->new_lft[p_leaf_sw->base_lid];
+			port_num = p_sw->p_osm_sw->new_lft[p_leaf_sw->lid];
 
 			OSM_LOG(&p_ftree->p_osm->log, OSM_LOG_DEBUG,
 				"Switch %s: setting path to LID %u "
@@ -3047,7 +3112,7 @@ static void fabric_route_roots(IN ftree_fabric_t * p_ftree)
 			 * from the leaf to the target LID.
 			 */
 			sw_set_hops(p_sw, lid, port_num,
-				p_sw->hops[p_leaf_sw->base_lid] +
+				p_sw->hops[p_leaf_sw->lid] +
 				p_leaf_sw->hops[lid], TRUE);
 		}
 	}
@@ -3240,7 +3305,7 @@ static int rank_leaf_switches(IN ftree_fabric_t * p_ftree,
 			PRIx64 "\n"
 			"                                            - Switch LID : %u\n",
 			hca_get_guid_ho(p_hca),
-			sw_get_guid_ho(p_sw), p_sw->base_lid);
+			sw_get_guid_ho(p_sw), p_sw->lid);
 		cl_list_insert_tail(p_ranking_bfs_list, p_sw);
 	}
 
@@ -3274,18 +3339,25 @@ fabric_construct_hca_ports(IN ftree_fabric_t * p_ftree, IN ftree_hca_t * p_hca)
 	osm_physp_t *p_remote_osm_port;
 	uint8_t i;
 	uint8_t remote_port_num;
-	boolean_t is_cn = TRUE;
-	boolean_t is_in_cn_file = FALSE;
-	boolean_t is_io = FALSE;
+	boolean_t is_cn;
+	boolean_t is_in_cn_file;
+	boolean_t is_io;
 	boolean_t is_cns_file_provided = fabric_cns_provided(p_ftree);
 	boolean_t is_ios_file_provided = fabric_ios_provided(p_ftree);
 	int res = 0;
 
 	for (i = 0; i < osm_node_get_num_physp(p_node); i++) {
 		osm_physp_t *p_osm_port = osm_node_get_physp_ptr(p_node, i);
+		is_io = FALSE;
+		is_cn = TRUE;
+		is_in_cn_file = FALSE;
+
 		if (!p_osm_port || !osm_link_is_healthy(p_osm_port))
 			continue;
 
+		if (p_hca->disconnected_ports[i])
+			continue;
+
 		p_remote_osm_port = osm_physp_get_remote(p_osm_port);
 		p_remote_node =
 		    osm_node_get_remote_node(p_node, i, &remote_port_num);
@@ -3364,18 +3436,13 @@ fabric_construct_hca_ports(IN ftree_fabric_t * p_ftree, IN ftree_hca_t * p_hca)
 				"Marking CN port GUID 0x%016" PRIx64 "\n",
 				cl_ntoh64(osm_physp_get_port_guid(p_osm_port)));
 		} else if (is_io) {
-				OSM_LOG(&p_ftree->p_osm->log, OSM_LOG_DEBUG,
-					"Marking I/O port GUID 0x%016" PRIx64
-					"\n",
-					cl_ntoh64(osm_physp_get_port_guid
-						 (p_osm_port)));
-
+			OSM_LOG(&p_ftree->p_osm->log, OSM_LOG_DEBUG,
+				"Marking I/O port GUID 0x%016" PRIx64 "\n",
+				cl_ntoh64(osm_physp_get_port_guid(p_osm_port)));
 		} else {
-				OSM_LOG(&p_ftree->p_osm->log, OSM_LOG_DEBUG,
-					"Marking non-CN port GUID 0x%016" PRIx64
-					"\n",
-					cl_ntoh64(osm_physp_get_port_guid
-						 (p_osm_port)));
+			OSM_LOG(&p_ftree->p_osm->log, OSM_LOG_DEBUG,
+				"Marking non-CN port GUID 0x%016" PRIx64 "\n",
+				cl_ntoh64(osm_physp_get_port_guid(p_osm_port)));
 		}
 		p_ftree->ca_ports++;
 
@@ -3407,7 +3474,7 @@ static int fabric_construct_sw_ports(IN ftree_fabric_t * p_ftree,
 	ftree_sw_t *p_remote_sw;
 	osm_node_t *p_node = p_sw->p_osm_sw->p_node;
 	osm_node_t *p_remote_node;
-	uint16_t remote_base_lid;
+	uint16_t remote_lid;
 	uint8_t remote_node_type;
 	ib_net64_t remote_node_guid;
 	osm_physp_t *p_remote_osm_port;
@@ -3439,7 +3506,7 @@ static int fabric_construct_sw_ports(IN ftree_fabric_t * p_ftree,
 				"Ignoring loopback on switch GUID 0x%016" PRIx64
 				", LID %u, rank %u\n",
 				sw_get_guid_ho(p_sw),
-				p_sw->base_lid, p_sw->rank);
+				p_sw->lid, p_sw->rank);
 			continue;
 		}
 
@@ -3461,9 +3528,8 @@ static int fabric_construct_sw_ports(IN ftree_fabric_t * p_ftree,
 			p_remote_hca_or_sw = (void *)p_remote_hca;
 			direction = FTREE_DIRECTION_DOWN;
 
-			remote_base_lid =
-			    cl_ntoh16(osm_physp_get_base_lid
-				      (p_remote_osm_port));
+			remote_lid =
+			    cl_ntoh16(osm_physp_get_base_lid(p_remote_osm_port));
 			break;
 
 		case IB_NODE_TYPE_SWITCH:
@@ -3483,7 +3549,7 @@ static int fabric_construct_sw_ports(IN ftree_fabric_t * p_ftree,
 				direction = FTREE_DIRECTION_DOWN;
 
 			/* switch LID is only in port 0 port_info structure */
-			remote_base_lid =
+			remote_lid =
 			    cl_ntoh16(osm_node_get_base_lid(p_remote_node, 0));
 
 			break;
@@ -3500,8 +3566,8 @@ static int fabric_construct_sw_ports(IN ftree_fabric_t * p_ftree,
 		sw_add_port(p_sw,	/* local ftree_sw object */
 			    i,	/* local port number */
 			    remote_port_num,	/* remote port number */
-			    p_sw->base_lid,	/* local lid */
-			    remote_base_lid,	/* remote lid */
+			    p_sw->lid,	/* local lid */
+			    remote_lid,	/* remote lid */
 			    osm_physp_get_port_guid(p_osm_port),	/* local port guid */
 			    osm_physp_get_port_guid(p_remote_osm_port),	/* remote port guid */
 			    remote_node_guid,	/* remote node guid */
@@ -3510,8 +3576,8 @@ static int fabric_construct_sw_ports(IN ftree_fabric_t * p_ftree,
 			    direction);	/* port direction (up or down) */
 
 		/* Track the max lid (in host order) that exists in the fabric */
-		if (remote_base_lid > p_ftree->lft_max_lid)
-			p_ftree->lft_max_lid = remote_base_lid;
+		if (remote_lid > p_ftree->lft_max_lid)
+			p_ftree->lft_max_lid = remote_lid;
 	}
 
 Exit:
@@ -3920,34 +3986,6 @@ Exit:
 
 /***************************************************
  ***************************************************/
-/* Get HCA and switch node, check if this node is the
- * Only switch that this HCA is connected to */
-static boolean_t has_one_remote_switch(IN ftree_fabric_t *p_ftree,
-				       IN ftree_hca_t *p_hca,
-				       IN osm_node_t* p_node)
-{
-	boolean_t found_other_sw = FALSE;
-	osm_physp_t *p_physp, *p_remote_physp;
-	int i = 1;
-	int ports_num;
-
-	ports_num = osm_node_get_num_physp(p_hca->p_osm_node);
-	while (!found_other_sw && (i < ports_num)) {
-		p_physp = osm_node_get_physp_ptr(p_hca->p_osm_node, i);
-		if (p_physp){
-			p_remote_physp = p_physp->p_remote_physp;
-			if (p_remote_physp && (p_remote_physp->p_node!=p_node))
-				/* Found connection to sw that is not p_node */
-				found_other_sw = TRUE;
-		}
-		i++;
-	}
-
-	return (!found_other_sw);
-}
-
-/***************************************************
- ***************************************************/
 /* Get a Sw and remove all depended HCA's, meaning all
  * HCA's which this is the only switch they are connected
  * to	*/
@@ -3956,6 +3994,7 @@ static int remove_depended_hca(IN ftree_fabric_t *p_ftree, IN ftree_sw_t *p_sw)
 	ftree_hca_t *p_hca;
 	int counter = 0;
 	int port_num;
+	uint8_t remote_port_num;
 	osm_physp_t* physp;
 	osm_node_t* sw_node;
 	uint64_t remote_hca_guid;
@@ -3968,11 +4007,12 @@ static int remove_depended_hca(IN ftree_fabric_t *p_ftree, IN ftree_sw_t *p_sw)
 				remote_hca_guid =
 				    osm_node_get_node_guid(physp->p_remote_physp->p_node);
 				p_hca = fabric_get_hca_by_guid(p_ftree, remote_hca_guid);
-				if (p_hca && has_one_remote_switch(p_ftree, p_hca, sw_node)) {
-					cl_qmap_remove_item(&p_ftree->hca_tbl, &p_hca->map_item);
-					hca_destroy(p_hca);
-					counter++;
-				}
+				if (!p_hca)
+					continue;
+
+				remote_port_num =
+				    osm_physp_get_port_num(physp->p_remote_physp);
+				p_hca->disconnected_ports[remote_port_num] = 1;
 			}
 		}
 	}
@@ -3997,7 +4037,7 @@ static void fabric_remove_unranked_sw(IN ftree_fabric_t *p_ftree)
 			OSM_LOG(&p_ftree->p_osm->log, OSM_LOG_VERBOSE,
 				"Removing Unranked sw 0x%" PRIx64 " (with %d dependent hca's)\n",
 				sw_get_guid_ho(p_sw),removed_hca);
-			sw_destroy(p_ftree, p_sw);
+			sw_destroy(p_sw);
 			count++;
 		}
 	}
@@ -4090,6 +4130,15 @@ static int construct_fabric(IN void *context)
 	}
 	fabric_remove_unranked_sw(p_ftree);
 
+	if (p_ftree->max_switch_rank == 0 &&
+	    cl_qmap_count(&p_ftree->sw_tbl) > 1) {
+		OSM_LOG(&p_ftree->p_osm->log, OSM_LOG_ERROR,
+			"ERR AB2B: Found more than one root on fabric with "
+			"maximum rank 0\n");
+		status = -1;
+		goto Exit;
+	}
+
 	/* For each hca and switch, construct array of ports.
 	   This is done after the whole FatTree data structure is ready,
 	   because we want the ports to have pointers to ftree_{sw,hca}_t
@@ -4267,6 +4316,7 @@ int osm_ucast_ftree_setup(struct osm_routing_engine *r, osm_opensm_t * p_osm)
 		return -1;
 
 	p_ftree->p_osm = p_osm;
+	p_ftree->p_subn = p_osm->sm.ucast_mgr.p_subn;
 
 	r->context = (void *)p_ftree;
 	r->build_lid_matrices = construct_fabric;
diff --git a/opensm/osm_ucast_lash.c b/opensm/osm_ucast_lash.c
index 9575e84..b0d9fbc 100644
--- a/opensm/osm_ucast_lash.c
+++ b/opensm/osm_ucast_lash.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
- * Copyright (c) 2002-2009 Mellanox Technologies LTD. All rights reserved.
+ * Copyright (c) 2002-2015 Mellanox Technologies LTD. All rights reserved.
  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
  * Copyright (c) 2007      Simula Research Laboratory. All rights reserved.
  * Copyright (c) 2007      Silicon Graphics Inc. All rights reserved.
@@ -121,7 +121,7 @@ static osm_switch_t *get_osm_switch_from_port(const osm_port_t * port)
 	osm_physp_t *p = port->p_physp;
 	if (p->p_node->sw)
 		return p->p_node->sw;
-	else if (p->p_remote_physp->p_node->sw)
+	else if (p->p_remote_physp && p->p_remote_physp->p_node->sw)
 		return p->p_remote_physp->p_node->sw;
 	return NULL;
 }
diff --git a/opensm/osm_ucast_mgr.c b/opensm/osm_ucast_mgr.c
index 43f053c..e55d2e0 100644
--- a/opensm/osm_ucast_mgr.c
+++ b/opensm/osm_ucast_mgr.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
- * Copyright (c) 2002-2009 Mellanox Technologies LTD. All rights reserved.
+ * Copyright (c) 2002-2015 Mellanox Technologies LTD. All rights reserved.
  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
  *
  * This software is available to you under a choice of one of two
@@ -219,7 +219,7 @@ static void ucast_mgr_process_port(IN osm_ucast_mgr_t * p_mgr,
 	 * the initialization. Don't handle this port. */
 	if (min_lid_ho == 0 || max_lid_ho == 0) {
 		OSM_LOG(p_mgr->p_log, OSM_LOG_ERROR, "ERR 3A04: "
-			"Port 0x%"PRIx64" (%s port %d) has LID 0. An "
+			"Port 0x%" PRIx64 " (%s port %d) has LID 0. An "
 			"initialization error occurred. Ignoring port\n",
 			cl_ntoh64(osm_port_get_guid(p_port)),
 			p_port->p_node->print_desc,
@@ -234,7 +234,8 @@ static void ucast_mgr_process_port(IN osm_ucast_mgr_t * p_mgr,
 
 	if (lid_offset && !p_mgr->is_dor)
 		/* ignore potential overflow - it is handled in osm_switch.c */
-		start_from = osm_switch_get_port_by_lid(p_sw, lid_ho - 1) + 1;
+		start_from =
+		    osm_switch_get_port_by_lid(p_sw, lid_ho - 1, OSM_NEW_LFT) + 1;
 
 	OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG,
 		"Processing port 0x%" PRIx64
@@ -259,7 +260,8 @@ static void ucast_mgr_process_port(IN osm_ucast_mgr_t * p_mgr,
 					 p_mgr->p_subn->opt.lmc,
 					 p_mgr->is_dor,
 					 p_mgr->p_subn->opt.port_shifting,
-					 p_port->use_scatter);
+					 !lid_offset && p_port->use_scatter,
+					 OSM_LFT);
 
 	if (port == OSM_NO_PATH) {
 		/* do not try to overwrite the ppro of non existing port ... */
@@ -270,6 +272,8 @@ static void ucast_mgr_process_port(IN osm_ucast_mgr_t * p_mgr,
 			lid_ho, cl_ntoh64(node_guid));
 	} else {
 		osm_physp_t *p = osm_node_get_physp_ptr(p_sw->p_node, port);
+		if (!p)
+			goto Exit;
 
 		OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG,
 			"Routing LID %u to port %u for switch 0x%" PRIx64 "\n",
@@ -1034,7 +1038,7 @@ static void ucast_mgr_pipeline_fwd_tbl(osm_ucast_mgr_t * p_mgr)
 {
 	cl_qmap_t *tbl;
 	cl_map_item_t *item;
-	unsigned i, max_block = p_mgr->max_lid / 64 + 1;
+	unsigned i, max_block = p_mgr->max_lid / IB_SMP_DATA_SIZE + 1;
 
 	tbl = &p_mgr->p_subn->sw_guid_tbl;
 	for (i = 0; i < max_block; i++)
@@ -1061,7 +1065,7 @@ static int ucast_mgr_route(struct osm_routing_engine *r, osm_opensm_t * osm)
 		"building routing with \'%s\' routing algorithm...\n", r->name);
 
 	/* Set the before each lft build to keep the routes in place between sweeps */
-	if(osm->subn.opt.scatter_ports)
+	if (osm->subn.opt.scatter_ports)
 		srandom(osm->subn.opt.scatter_ports);
 
 	if (!r->build_lid_matrices ||
diff --git a/osmeventplugin/src/osmeventplugin.c b/osmeventplugin/src/osmeventplugin.c
index d7975a3..cba69ea 100644
--- a/osmeventplugin/src/osmeventplugin.c
+++ b/osmeventplugin/src/osmeventplugin.c
@@ -227,8 +227,8 @@ static void report(void *_log, osm_epi_event_id_t event_id, void *event_data)
 #endif
 
 osm_event_plugin_t osm_event_plugin = {
-      osm_version:OSM_VERSION,
-      create:construct,
-      delete:destroy,
-      report:report
+      OSM_VERSION,
+      construct,
+      destroy,
+      report
 };
diff --git a/osmtest/osmt_multicast.c b/osmtest/osmt_multicast.c
index 9e2f74b..e453e15 100644
--- a/osmtest/osmt_multicast.c
+++ b/osmtest/osmt_multicast.c
@@ -423,7 +423,7 @@ void osmt_init_mc_query_rec(IN osmtest_t * const p_osmt,
  * - Try to create a new MCG with invalid MGID : get back ERR_REQ_INVALID
  * - Try again with MGID prefix = 0xA01B (maybe 0x1BA0 little or big ?)
  * - Try to create again the already created group: ERR_REQ_INVALID
- * o15.0.1.7 - implicitlly checked during the prev steps.
+ * o15.0.1.7 - implicitly checked during the prev steps.
  * o15.0.1.9
  * - Create MCG with Invalid JoinState.FullMember != 1 : get ERR_REQ_INVALID
  * o15.0.1.10 - can't check on a single client .
@@ -929,7 +929,7 @@ ib_api_status_t osmt_run_mcast_flow(IN osmtest_t * const p_osmt)
 
 	/* impossible requested rate */
 	mc_req_rec.rate =
-	    IB_PATH_RECORD_RATE_56_GBS | IB_PATH_SELECTOR_GREATER_THAN << 6;
+	    IB_MAX_RATE | IB_PATH_SELECTOR_GREATER_THAN << 6;
 
 	comp_mask = IB_MCR_COMPMASK_GID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
 	    IB_MCR_COMPMASK_RATE_SEL | IB_MCR_COMPMASK_RATE;
@@ -1692,8 +1692,8 @@ ib_api_status_t osmt_run_mcast_flow(IN osmtest_t * const p_osmt)
 			  sizeof gid_str), cl_ntoh16(p_mc_res->mlid));
 	cl_map_insert(&test_created_mlids, cl_ntoh16(p_mc_res->mlid), p_mc_res);
 
-	/* o15.0.1.7 - implicitlly checked during the prev steps. */
-	/* o15.0.1.8 - implicitlly checked during the prev steps. */
+	/* o15.0.1.7 - implicitly checked during the prev steps */
+	/* o15.0.1.8 - implicitly checked during the prev steps */
 
 	/* o15.0.1.9 */
 	/* - Create MCG with Invalid JoinState.FullMember != 1 : get ERR_REQ_INVALID */
@@ -1750,7 +1750,7 @@ ib_api_status_t osmt_run_mcast_flow(IN osmtest_t * const p_osmt)
 
 	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
 
-	/* We have created a new MCG so now we need different mgid when cresting group otherwise it will be counted as join request . */
+	/* We have created a new MCG so now we need different mgid when creating group otherwise it will be counted as join request */
 	mc_req_rec.mgid = good_mgid;
 	mc_req_rec.mgid.raw[12] = 0xFC;
 	mc_req_rec.scope_state = 0x24;	/* link-local scope, send only member */
@@ -1964,7 +1964,7 @@ ib_api_status_t osmt_run_mcast_flow(IN osmtest_t * const p_osmt)
 	}
 
 	/* Now try to update value of join state */
-	mc_req_rec.scope_state = 0x22;	/* link-local scope,non member */
+	mc_req_rec.scope_state = 0x22;	/* link-local scope, non member */
 
 	status = osmt_send_mcast_request(p_osmt, 1, &mc_req_rec, comp_mask,
 					 sa_mad);
@@ -2109,7 +2109,6 @@ ib_api_status_t osmt_run_mcast_flow(IN osmtest_t * const p_osmt)
 	}
 
 	/* Now use the same scope_state and delete all JoinState - leave multicast group since state is 0x0 */
-
 	mc_req_rec.scope_state = 0x25;
 	status = osmt_send_mcast_request(p_osmt, 0, &mc_req_rec, comp_mask,
 					 sa_mad);
diff --git a/osmtest/osmt_service.c b/osmtest/osmt_service.c
index ae30beb..5ca2eca 100644
--- a/osmtest/osmt_service.c
+++ b/osmtest/osmt_service.c
@@ -459,6 +459,8 @@ osmt_get_service_by_id_and_name(IN osmtest_t * const p_osmt,
 	ib_service_record_t svc_rec, *p_rec;
 	uint32_t num_recs = 0;
 	osmv_user_query_t user;
+	const uint16_t ERR_SIZE = 512;
+	char mad_stat_err[ERR_SIZE];
 
 	OSM_LOG_ENTER(&p_osmt->log);
 
@@ -517,17 +519,21 @@ osmt_get_service_by_id_and_name(IN osmtest_t * const p_osmt,
 	num_recs = context.result.result_cnt;
 
 	if (status != IB_SUCCESS) {
-		char mad_stat_err[256];
 
 		/* If the failure is due to IB_SA_MAD_STATUS_NO_RECORDS and rec_num is 0,
 		   then this is fine */
 		if (status == IB_REMOTE_ERROR)
-			strcpy(mad_stat_err,
-			       ib_get_mad_status_str(osm_madw_get_mad_ptr
-						     (context.result.
-						      p_result_madw)));
+			strncpy(mad_stat_err,
+			        ib_get_mad_status_str(osm_madw_get_mad_ptr
+						      (context.result.
+						       p_result_madw)),
+				ERR_SIZE -1);
 		else
-			strcpy(mad_stat_err, ib_get_err_str(status));
+			strncpy(mad_stat_err, ib_get_err_str(status),
+				ERR_SIZE -1);
+
+		mad_stat_err[ERR_SIZE -1] = '\0';
+
 		if (status == IB_REMOTE_ERROR &&
 		    !strcmp(mad_stat_err, "IB_SA_MAD_STATUS_NO_RECORDS") &&
 		    rec_num == 0) {
@@ -715,6 +721,8 @@ osmt_get_service_by_name_and_key(IN osmtest_t * const p_osmt,
 	ib_service_record_t svc_rec, *p_rec;
 	uint32_t num_recs = 0, i;
 	osmv_user_query_t user;
+	const uint16_t ERR_SIZE = 512;
+	char mad_stat_err[ERR_SIZE];
 
 	OSM_LOG_ENTER(&p_osmt->log);
 
@@ -778,17 +786,20 @@ osmt_get_service_by_name_and_key(IN osmtest_t * const p_osmt,
 	num_recs = context.result.result_cnt;
 
 	if (status != IB_SUCCESS) {
-		char mad_stat_err[256];
 
 		/* If the failure is due to IB_SA_MAD_STATUS_NO_RECORDS and rec_num is 0,
 		   then this is fine */
 		if (status == IB_REMOTE_ERROR)
-			strcpy(mad_stat_err,
-			       ib_get_mad_status_str(osm_madw_get_mad_ptr
-						     (context.result.
-						      p_result_madw)));
+			strncpy(mad_stat_err,
+			        ib_get_mad_status_str(osm_madw_get_mad_ptr
+						      (context.result.
+						      p_result_madw)),
+				ERR_SIZE -1);
 		else
-			strcpy(mad_stat_err, ib_get_err_str(status));
+			strncpy(mad_stat_err, ib_get_err_str(status),
+				ERR_SIZE -1);
+
+		mad_stat_err[ERR_SIZE -1] = '\0';
 
 		if (status == IB_REMOTE_ERROR &&
 		    !strcmp(mad_stat_err, "IB_SA_MAD_STATUS_NO_RECORDS") &&

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ofed/opensm.git



More information about the Pkg-ofed-commits mailing list