|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
|
|
Packit Service |
54dbc3 |
* Copyright (c) 2002-2015 Mellanox Technologies LTD. All rights reserved.
|
|
Packit Service |
54dbc3 |
* Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
|
|
Packit Service |
54dbc3 |
* Copyright (c) 2009 HNR Consulting. All rights reserved.
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* This software is available to you under a choice of one of two
|
|
Packit Service |
54dbc3 |
* licenses. You may choose to be licensed under the terms of the GNU
|
|
Packit Service |
54dbc3 |
* General Public License (GPL) Version 2, available from the file
|
|
Packit Service |
54dbc3 |
* COPYING in the main directory of this source tree, or the
|
|
Packit Service |
54dbc3 |
* OpenIB.org BSD license below:
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* Redistribution and use in source and binary forms, with or
|
|
Packit Service |
54dbc3 |
* without modification, are permitted provided that the following
|
|
Packit Service |
54dbc3 |
* conditions are met:
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* - Redistributions of source code must retain the above
|
|
Packit Service |
54dbc3 |
* copyright notice, this list of conditions and the following
|
|
Packit Service |
54dbc3 |
* disclaimer.
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* - Redistributions in binary form must reproduce the above
|
|
Packit Service |
54dbc3 |
* copyright notice, this list of conditions and the following
|
|
Packit Service |
54dbc3 |
* disclaimer in the documentation and/or other materials
|
|
Packit Service |
54dbc3 |
* provided with the distribution.
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
Packit Service |
54dbc3 |
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
Packit Service |
54dbc3 |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
Packit Service |
54dbc3 |
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
Packit Service |
54dbc3 |
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
Packit Service |
54dbc3 |
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
Packit Service |
54dbc3 |
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
Packit Service |
54dbc3 |
* SOFTWARE.
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* Abstract:
|
|
Packit Service |
54dbc3 |
* Implementation of osm_ni_rcv_t.
|
|
Packit Service |
54dbc3 |
* This object represents the NodeInfo Receiver object.
|
|
Packit Service |
54dbc3 |
* This object is part of the opensm family of objects.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
#if HAVE_CONFIG_H
|
|
Packit Service |
54dbc3 |
# include <config.h>
|
|
Packit Service |
54dbc3 |
#endif /* HAVE_CONFIG_H */
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
#include <stdlib.h>
|
|
Packit Service |
54dbc3 |
#include <string.h>
|
|
Packit Service |
54dbc3 |
#include <iba/ib_types.h>
|
|
Packit Service |
54dbc3 |
#include <complib/cl_qmap.h>
|
|
Packit Service |
54dbc3 |
#include <complib/cl_passivelock.h>
|
|
Packit Service |
54dbc3 |
#include <complib/cl_debug.h>
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_file_ids.h>
|
|
Packit Service |
54dbc3 |
#define FILE_ID OSM_FILE_NODE_INFO_RCV_C
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_madw.h>
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_log.h>
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_node.h>
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_subnet.h>
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_router.h>
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_mad_pool.h>
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_helper.h>
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_msgdef.h>
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_opensm.h>
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_ucast_mgr.h>
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_db_pack.h>
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
static void report_duplicated_guid(IN osm_sm_t * sm, osm_physp_t * p_physp,
|
|
Packit Service |
54dbc3 |
osm_node_t * p_neighbor_node,
|
|
Packit Service |
54dbc3 |
const uint8_t port_num)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_physp_t *p_old, *p_new;
|
|
Packit Service |
54dbc3 |
osm_dr_path_t path;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_old = p_physp->p_remote_physp;
|
|
Packit Service |
54dbc3 |
p_new = osm_node_get_physp_ptr(p_neighbor_node, port_num);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_SYS | OSM_LOG_ERROR, "ERR 0D01: "
|
|
Packit Service |
54dbc3 |
"Found duplicated node GUID.\n"
|
|
Packit Service |
54dbc3 |
"Node 0x%" PRIx64 " port %u is reachable from remote node "
|
|
Packit Service |
54dbc3 |
"0x%" PRIx64 " port %u and remote node 0x%" PRIx64 " port %u.\n"
|
|
Packit Service |
54dbc3 |
"Paths are:\n",
|
|
Packit Service |
54dbc3 |
cl_ntoh64(p_physp->p_node->node_info.node_guid),
|
|
Packit Service |
54dbc3 |
p_physp->port_num,
|
|
Packit Service |
54dbc3 |
p_old ? cl_ntoh64(p_old->p_node->node_info.node_guid) : 0,
|
|
Packit Service |
54dbc3 |
p_old ? p_old->port_num : 0,
|
|
Packit Service |
54dbc3 |
p_new ? cl_ntoh64(p_new->p_node->node_info.node_guid) : 0,
|
|
Packit Service |
54dbc3 |
p_new ? p_new->port_num : 0);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
osm_dump_dr_path_v2(sm->p_log, osm_physp_get_dr_path_ptr(p_physp),
|
|
Packit Service |
54dbc3 |
FILE_ID, OSM_LOG_ERROR);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
path = *osm_physp_get_dr_path_ptr(p_new);
|
|
Packit Service |
54dbc3 |
if (osm_dr_path_extend(&path, port_num))
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0D05: "
|
|
Packit Service |
54dbc3 |
"DR path with hop count %d couldn't be extended\n",
|
|
Packit Service |
54dbc3 |
path.hop_count);
|
|
Packit Service |
54dbc3 |
osm_dump_dr_path_v2(sm->p_log, &path, FILE_ID, OSM_LOG_ERROR);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
static void requery_dup_node_info(IN osm_sm_t * sm, osm_physp_t * p_physp,
|
|
Packit Service |
54dbc3 |
unsigned count)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_madw_context_t context;
|
|
Packit Service |
54dbc3 |
osm_dr_path_t path;
|
|
Packit Service |
54dbc3 |
cl_status_t status;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (!p_physp->p_remote_physp) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0D0D: "
|
|
Packit Service |
54dbc3 |
"DR path couldn't be extended due to NULL remote physp\n");
|
|
Packit Service |
54dbc3 |
return;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
path = *osm_physp_get_dr_path_ptr(p_physp->p_remote_physp);
|
|
Packit Service |
54dbc3 |
if (osm_dr_path_extend(&path, p_physp->p_remote_physp->port_num)) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0D08: "
|
|
Packit Service |
54dbc3 |
"DR path with hop count %d couldn't be extended\n",
|
|
Packit Service |
54dbc3 |
path.hop_count);
|
|
Packit Service |
54dbc3 |
return;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
context.ni_context.node_guid =
|
|
Packit Service |
54dbc3 |
p_physp->p_remote_physp->p_node->node_info.port_guid;
|
|
Packit Service |
54dbc3 |
context.ni_context.port_num = p_physp->p_remote_physp->port_num;
|
|
Packit Service |
54dbc3 |
context.ni_context.dup_node_guid = p_physp->p_node->node_info.node_guid;
|
|
Packit Service |
54dbc3 |
context.ni_context.dup_port_num = p_physp->port_num;
|
|
Packit Service |
54dbc3 |
context.ni_context.dup_count = count;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
status = osm_req_get(sm, &path, IB_MAD_ATTR_NODE_INFO, 0,
|
|
Packit Service |
54dbc3 |
TRUE, 0, 0, CL_DISP_MSGID_NONE, &context);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (status != IB_SUCCESS)
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0D02: "
|
|
Packit Service |
54dbc3 |
"Failure initiating NodeInfo request (%s)\n",
|
|
Packit Service |
54dbc3 |
ib_get_err_str(status));
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/**********************************************************************
|
|
Packit Service |
54dbc3 |
The plock must be held before calling this function.
|
|
Packit Service |
54dbc3 |
**********************************************************************/
|
|
Packit Service |
54dbc3 |
static void ni_rcv_set_links(IN osm_sm_t * sm, osm_node_t * p_node,
|
|
Packit Service |
54dbc3 |
const uint8_t port_num,
|
|
Packit Service |
54dbc3 |
const osm_ni_context_t * p_ni_context)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_node_t *p_neighbor_node;
|
|
Packit Service |
54dbc3 |
osm_physp_t *p_physp, *p_remote_physp;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(sm->p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
A special case exists in which the node we're trying to
|
|
Packit Service |
54dbc3 |
link is our own node. In this case, the guid value in
|
|
Packit Service |
54dbc3 |
the ni_context will be zero.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
if (p_ni_context->node_guid == 0) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
|
|
Packit Service |
54dbc3 |
"Nothing to link for our own node 0x%" PRIx64 "\n",
|
|
Packit Service |
54dbc3 |
cl_ntoh64(osm_node_get_node_guid(p_node)));
|
|
Packit Service |
54dbc3 |
goto _exit;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_neighbor_node = osm_get_node_by_guid(sm->p_subn,
|
|
Packit Service |
54dbc3 |
p_ni_context->node_guid);
|
|
Packit Service |
54dbc3 |
if (PF(!p_neighbor_node)) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0D10: "
|
|
Packit Service |
54dbc3 |
"Unexpected removal of neighbor node 0x%" PRIx64 "\n",
|
|
Packit Service |
54dbc3 |
cl_ntoh64(p_ni_context->node_guid));
|
|
Packit Service |
54dbc3 |
goto _exit;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* When setting the link, ports on both
|
|
Packit Service |
54dbc3 |
sides of the link should be initialized */
|
|
Packit Service |
54dbc3 |
CL_ASSERT(osm_node_link_has_valid_ports(p_node, port_num,
|
|
Packit Service |
54dbc3 |
p_neighbor_node,
|
|
Packit Service |
54dbc3 |
p_ni_context->port_num));
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (osm_node_link_exists(p_node, port_num,
|
|
Packit Service |
54dbc3 |
p_neighbor_node, p_ni_context->port_num)) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_DEBUG, "Link already exists\n");
|
|
Packit Service |
54dbc3 |
goto _exit;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_physp = osm_node_get_physp_ptr(p_node, port_num);
|
|
Packit Service |
54dbc3 |
if (!p_physp) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR OD0E: "
|
|
Packit Service |
54dbc3 |
"Failed to find physp for port %d of Node GUID 0x%"
|
|
Packit Service |
54dbc3 |
PRIx64 "\n", port_num,
|
|
Packit Service |
54dbc3 |
cl_ntoh64(osm_node_get_node_guid(p_node)));
|
|
Packit Service |
54dbc3 |
goto _exit;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* If the link went UP, after we already discovered it, we shouldn't
|
|
Packit Service |
54dbc3 |
* set the link between the ports and resweep.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
if (osm_physp_get_port_state(p_physp) == IB_LINK_DOWN &&
|
|
Packit Service |
54dbc3 |
p_node->physp_discovered[port_num]) {
|
|
Packit Service |
54dbc3 |
/* Link down on another side. Don't create a link*/
|
|
Packit Service |
54dbc3 |
p_node->physp_discovered[port_num] = 0;
|
|
Packit Service |
54dbc3 |
sm->p_subn->force_heavy_sweep = TRUE;
|
|
Packit Service |
54dbc3 |
goto _exit;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (osm_node_has_any_link(p_node, port_num) &&
|
|
Packit Service |
54dbc3 |
sm->p_subn->force_heavy_sweep == FALSE &&
|
|
Packit Service |
54dbc3 |
(!p_ni_context->dup_count ||
|
|
Packit Service |
54dbc3 |
(p_ni_context->dup_node_guid == osm_node_get_node_guid(p_node) &&
|
|
Packit Service |
54dbc3 |
p_ni_context->dup_port_num == port_num))) {
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
Uh oh...
|
|
Packit Service |
54dbc3 |
This could be reconnected ports, but also duplicated GUID
|
|
Packit Service |
54dbc3 |
(2 nodes have the same guid) or a 12x link with lane reversal
|
|
Packit Service |
54dbc3 |
that is not configured correctly.
|
|
Packit Service |
54dbc3 |
We will try to recover by querying NodeInfo again.
|
|
Packit Service |
54dbc3 |
In order to catch even fast port moving to new location(s)
|
|
Packit Service |
54dbc3 |
and back we will count up to 5.
|
|
Packit Service |
54dbc3 |
Some crazy reconnections (newly created switch loop right
|
|
Packit Service |
54dbc3 |
before targeted CA) will not be catched this way. So in worst
|
|
Packit Service |
54dbc3 |
case - report GUID duplication and request new discovery.
|
|
Packit Service |
54dbc3 |
When switch node is targeted NodeInfo querying will be done
|
|
Packit Service |
54dbc3 |
in opposite order, this is much stronger check, unfortunately
|
|
Packit Service |
54dbc3 |
it is impossible with CAs.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
p_physp = osm_node_get_physp_ptr(p_node, port_num);
|
|
Packit Service |
54dbc3 |
if (!p_physp) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR OD0F: "
|
|
Packit Service |
54dbc3 |
"Failed to find physp for port %d of Node GUID 0x%"
|
|
Packit Service |
54dbc3 |
PRIx64 "\n", port_num,
|
|
Packit Service |
54dbc3 |
cl_ntoh64(osm_node_get_node_guid(p_node)));
|
|
Packit Service |
54dbc3 |
goto _exit;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (p_ni_context->dup_count > 5) {
|
|
Packit Service |
54dbc3 |
report_duplicated_guid(sm, p_physp, p_neighbor_node,
|
|
Packit Service |
54dbc3 |
p_ni_context->port_num);
|
|
Packit Service |
54dbc3 |
sm->p_subn->force_heavy_sweep = TRUE;
|
|
Packit Service |
54dbc3 |
} else if (p_node->sw)
|
|
Packit Service |
54dbc3 |
requery_dup_node_info(sm, p_physp->p_remote_physp,
|
|
Packit Service |
54dbc3 |
p_ni_context->dup_count + 1);
|
|
Packit Service |
54dbc3 |
else
|
|
Packit Service |
54dbc3 |
requery_dup_node_info(sm, p_physp,
|
|
Packit Service |
54dbc3 |
p_ni_context->dup_count + 1);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
When there are only two nodes with exact same guids (connected back
|
|
Packit Service |
54dbc3 |
to back) - the previous check for duplicated guid will not catch
|
|
Packit Service |
54dbc3 |
them. But the link will be from the port to itself...
|
|
Packit Service |
54dbc3 |
Enhanced Port 0 is an exception to this
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
if (osm_node_get_node_guid(p_node) == p_ni_context->node_guid &&
|
|
Packit Service |
54dbc3 |
port_num == p_ni_context->port_num &&
|
|
Packit Service |
54dbc3 |
port_num != 0 && cl_qmap_count(&sm->p_subn->sw_guid_tbl) == 0) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_VERBOSE,
|
|
Packit Service |
54dbc3 |
"Duplicate GUID found by link from a port to itself:"
|
|
Packit Service |
54dbc3 |
"node 0x%" PRIx64 ", port number %u\n",
|
|
Packit Service |
54dbc3 |
cl_ntoh64(osm_node_get_node_guid(p_node)), port_num);
|
|
Packit Service |
54dbc3 |
p_physp = osm_node_get_physp_ptr(p_node, port_num);
|
|
Packit Service |
54dbc3 |
if (!p_physp) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR OD1D: "
|
|
Packit Service |
54dbc3 |
"Failed to find physp for port %d of Node GUID 0x%"
|
|
Packit Service |
54dbc3 |
PRIx64 "\n", port_num,
|
|
Packit Service |
54dbc3 |
cl_ntoh64(osm_node_get_node_guid(p_node)));
|
|
Packit Service |
54dbc3 |
goto _exit;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
osm_dump_dr_path_v2(sm->p_log, osm_physp_get_dr_path_ptr(p_physp),
|
|
Packit Service |
54dbc3 |
FILE_ID, OSM_LOG_VERBOSE);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (sm->p_subn->opt.exit_on_fatal == TRUE) {
|
|
Packit Service |
54dbc3 |
osm_log_v2(sm->p_log, OSM_LOG_SYS, FILE_ID,
|
|
Packit Service |
54dbc3 |
"Errors on subnet. Duplicate GUID found "
|
|
Packit Service |
54dbc3 |
"by link from a port to itself. "
|
|
Packit Service |
54dbc3 |
"See verbose opensm.log for more details\n");
|
|
Packit Service |
54dbc3 |
exit(1);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
|
|
Packit Service |
54dbc3 |
"Creating new link between:\n\t\t\t\tnode 0x%" PRIx64
|
|
Packit Service |
54dbc3 |
", port number %u and\n\t\t\t\tnode 0x%" PRIx64
|
|
Packit Service |
54dbc3 |
", port number %u\n",
|
|
Packit Service |
54dbc3 |
cl_ntoh64(osm_node_get_node_guid(p_node)), port_num,
|
|
Packit Service |
54dbc3 |
cl_ntoh64(p_ni_context->node_guid), p_ni_context->port_num);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (sm->ucast_mgr.cache_valid)
|
|
Packit Service |
54dbc3 |
osm_ucast_cache_check_new_link(&sm->ucast_mgr, p_node, port_num,
|
|
Packit Service |
54dbc3 |
p_neighbor_node,
|
|
Packit Service |
54dbc3 |
p_ni_context->port_num);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_physp = osm_node_get_physp_ptr(p_node, port_num);
|
|
Packit Service |
54dbc3 |
p_remote_physp = osm_node_get_physp_ptr(p_neighbor_node,
|
|
Packit Service |
54dbc3 |
p_ni_context->port_num);
|
|
Packit Service |
54dbc3 |
if (!p_physp || !p_remote_physp)
|
|
Packit Service |
54dbc3 |
goto _exit;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
osm_node_link(p_node, port_num, p_neighbor_node, p_ni_context->port_num);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
osm_db_neighbor_set(sm->p_subn->p_neighbor,
|
|
Packit Service |
54dbc3 |
cl_ntoh64(osm_physp_get_port_guid(p_physp)),
|
|
Packit Service |
54dbc3 |
port_num,
|
|
Packit Service |
54dbc3 |
cl_ntoh64(osm_physp_get_port_guid(p_remote_physp)),
|
|
Packit Service |
54dbc3 |
p_ni_context->port_num);
|
|
Packit Service |
54dbc3 |
osm_db_neighbor_set(sm->p_subn->p_neighbor,
|
|
Packit Service |
54dbc3 |
cl_ntoh64(osm_physp_get_port_guid(p_remote_physp)),
|
|
Packit Service |
54dbc3 |
p_ni_context->port_num,
|
|
Packit Service |
54dbc3 |
cl_ntoh64(osm_physp_get_port_guid(p_physp)),
|
|
Packit Service |
54dbc3 |
port_num);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
_exit:
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(sm->p_log);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
static void ni_rcv_get_port_info(IN osm_sm_t * sm, IN osm_node_t * node,
|
|
Packit Service |
54dbc3 |
IN const osm_madw_t * madw)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_madw_context_t context;
|
|
Packit Service |
54dbc3 |
osm_physp_t *physp;
|
|
Packit Service |
54dbc3 |
ib_node_info_t *ni;
|
|
Packit Service |
54dbc3 |
unsigned port;
|
|
Packit Service |
54dbc3 |
ib_api_status_t status;
|
|
Packit Service |
54dbc3 |
int mlnx_epi_supported = 0;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
ni = ib_smp_get_payload_ptr(osm_madw_get_smp_ptr(madw));
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
port = ib_node_info_get_local_port_num(ni);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (sm->p_subn->opt.fdr10)
|
|
Packit Service |
54dbc3 |
mlnx_epi_supported = is_mlnx_ext_port_info_supported(
|
|
Packit Service |
54dbc3 |
ib_node_info_get_vendor_id(ni),
|
|
Packit Service |
54dbc3 |
ni->device_id);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
physp = osm_node_get_physp_ptr(node, port);
|
|
Packit Service |
54dbc3 |
if (!physp) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR OD1E: "
|
|
Packit Service |
54dbc3 |
"Failed to find physp for port %d of Node GUID 0x%"
|
|
Packit Service |
54dbc3 |
PRIx64 "\n", port,
|
|
Packit Service |
54dbc3 |
cl_ntoh64(osm_node_get_node_guid(node)));
|
|
Packit Service |
54dbc3 |
return;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
context.pi_context.node_guid = osm_node_get_node_guid(node);
|
|
Packit Service |
54dbc3 |
context.pi_context.port_guid = osm_physp_get_port_guid(physp);
|
|
Packit Service |
54dbc3 |
context.pi_context.set_method = FALSE;
|
|
Packit Service |
54dbc3 |
context.pi_context.light_sweep = FALSE;
|
|
Packit Service |
54dbc3 |
context.pi_context.active_transition = FALSE;
|
|
Packit Service |
54dbc3 |
context.pi_context.client_rereg = FALSE;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
status = osm_req_get(sm, osm_physp_get_dr_path_ptr(physp),
|
|
Packit Service |
54dbc3 |
IB_MAD_ATTR_PORT_INFO, cl_hton32(port),
|
|
Packit Service |
54dbc3 |
TRUE, 0, 0, CL_DISP_MSGID_NONE, &context);
|
|
Packit Service |
54dbc3 |
if (status != IB_SUCCESS)
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR OD02: "
|
|
Packit Service |
54dbc3 |
"Failure initiating PortInfo request (%s)\n",
|
|
Packit Service |
54dbc3 |
ib_get_err_str(status));
|
|
Packit Service |
54dbc3 |
if (mlnx_epi_supported) {
|
|
Packit Service |
54dbc3 |
status = osm_req_get(sm,
|
|
Packit Service |
54dbc3 |
osm_physp_get_dr_path_ptr(physp),
|
|
Packit Service |
54dbc3 |
IB_MAD_ATTR_MLNX_EXTENDED_PORT_INFO,
|
|
Packit Service |
54dbc3 |
cl_hton32(port),
|
|
Packit Service |
54dbc3 |
TRUE, 0, 0, CL_DISP_MSGID_NONE, &context);
|
|
Packit Service |
54dbc3 |
if (status != IB_SUCCESS)
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0D0B: "
|
|
Packit Service |
54dbc3 |
"Failure initiating MLNX ExtPortInfo request (%s)\n",
|
|
Packit Service |
54dbc3 |
ib_get_err_str(status));
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/**********************************************************************
|
|
Packit Service |
54dbc3 |
The plock must be held before calling this function.
|
|
Packit Service |
54dbc3 |
**********************************************************************/
|
|
Packit Service |
54dbc3 |
void osm_req_get_node_desc(IN osm_sm_t * sm, osm_physp_t * p_physp)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
ib_api_status_t status = IB_SUCCESS;
|
|
Packit Service |
54dbc3 |
osm_madw_context_t context;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(sm->p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
context.nd_context.node_guid =
|
|
Packit Service |
54dbc3 |
osm_node_get_node_guid(osm_physp_get_node_ptr(p_physp));
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
status = osm_req_get(sm, osm_physp_get_dr_path_ptr(p_physp),
|
|
Packit Service |
54dbc3 |
IB_MAD_ATTR_NODE_DESC, 0, TRUE, 0,
|
|
Packit Service |
54dbc3 |
0, CL_DISP_MSGID_NONE, &context);
|
|
Packit Service |
54dbc3 |
if (status != IB_SUCCESS)
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0D03: "
|
|
Packit Service |
54dbc3 |
"Failure initiating NodeDescription request (%s)\n",
|
|
Packit Service |
54dbc3 |
ib_get_err_str(status));
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(sm->p_log);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/**********************************************************************
|
|
Packit Service |
54dbc3 |
The plock must be held before calling this function.
|
|
Packit Service |
54dbc3 |
**********************************************************************/
|
|
Packit Service |
54dbc3 |
static void ni_rcv_get_node_desc(IN osm_sm_t * sm, IN osm_node_t * p_node,
|
|
Packit Service |
54dbc3 |
IN const osm_madw_t * p_madw)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
ib_node_info_t *p_ni;
|
|
Packit Service |
54dbc3 |
ib_smp_t *p_smp;
|
|
Packit Service |
54dbc3 |
uint8_t port_num;
|
|
Packit Service |
54dbc3 |
osm_physp_t *p_physp = NULL;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(sm->p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_smp = osm_madw_get_smp_ptr(p_madw);
|
|
Packit Service |
54dbc3 |
p_ni = ib_smp_get_payload_ptr(p_smp);
|
|
Packit Service |
54dbc3 |
port_num = ib_node_info_get_local_port_num(p_ni);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
Request PortInfo & NodeDescription attributes for the port
|
|
Packit Service |
54dbc3 |
that responded to the NodeInfo attribute.
|
|
Packit Service |
54dbc3 |
Because this is a channel adapter or router, we are
|
|
Packit Service |
54dbc3 |
not allowed to request PortInfo for the other ports.
|
|
Packit Service |
54dbc3 |
Set the context union properly, so the recipient
|
|
Packit Service |
54dbc3 |
knows which node & port are relevant.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
p_physp = osm_node_get_physp_ptr(p_node, port_num);
|
|
Packit Service |
54dbc3 |
if (!p_physp) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR OD1F: "
|
|
Packit Service |
54dbc3 |
"Failed to find physp for port %d of Node GUID 0x%"
|
|
Packit Service |
54dbc3 |
PRIx64 "\n", port_num,
|
|
Packit Service |
54dbc3 |
cl_ntoh64(osm_node_get_node_guid(p_node)));
|
|
Packit Service |
54dbc3 |
return;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
osm_req_get_node_desc(sm, p_physp);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(sm->p_log);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/**********************************************************************
|
|
Packit Service |
54dbc3 |
The plock must be held before calling this function.
|
|
Packit Service |
54dbc3 |
**********************************************************************/
|
|
Packit Service |
54dbc3 |
static void ni_rcv_process_new_ca_or_router(IN osm_sm_t * sm,
|
|
Packit Service |
54dbc3 |
IN osm_node_t * p_node,
|
|
Packit Service |
54dbc3 |
IN const osm_madw_t * p_madw)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(sm->p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
ni_rcv_get_port_info(sm, p_node, p_madw);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
A node guid of 0 is the corner case that indicates
|
|
Packit Service |
54dbc3 |
we discovered our own node. Initialize the subnet
|
|
Packit Service |
54dbc3 |
object with the SM's own port guid.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
if (osm_madw_get_ni_context_ptr(p_madw)->node_guid == 0)
|
|
Packit Service |
54dbc3 |
sm->p_subn->sm_port_guid = p_node->node_info.port_guid;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(sm->p_log);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/**********************************************************************
|
|
Packit Service |
54dbc3 |
The plock must be held before calling this function.
|
|
Packit Service |
54dbc3 |
**********************************************************************/
|
|
Packit Service |
54dbc3 |
static void ni_rcv_process_existing_ca_or_router(IN osm_sm_t * sm,
|
|
Packit Service |
54dbc3 |
IN osm_node_t * p_node,
|
|
Packit Service |
54dbc3 |
IN const osm_madw_t * p_madw)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
ib_node_info_t *p_ni;
|
|
Packit Service |
54dbc3 |
ib_smp_t *p_smp;
|
|
Packit Service |
54dbc3 |
osm_port_t *p_port;
|
|
Packit Service |
54dbc3 |
osm_port_t *p_port_check;
|
|
Packit Service |
54dbc3 |
uint8_t port_num;
|
|
Packit Service |
54dbc3 |
osm_dr_path_t *p_dr_path;
|
|
Packit Service |
54dbc3 |
osm_alias_guid_t *p_alias_guid, *p_alias_guid_check;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(sm->p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_smp = osm_madw_get_smp_ptr(p_madw);
|
|
Packit Service |
54dbc3 |
p_ni = ib_smp_get_payload_ptr(p_smp);
|
|
Packit Service |
54dbc3 |
port_num = ib_node_info_get_local_port_num(p_ni);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
Determine if we have encountered this node through a
|
|
Packit Service |
54dbc3 |
previously undiscovered port. If so, build the new
|
|
Packit Service |
54dbc3 |
port object.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
p_port = osm_get_port_by_guid(sm->p_subn, p_ni->port_guid);
|
|
Packit Service |
54dbc3 |
if (!p_port) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_VERBOSE,
|
|
Packit Service |
54dbc3 |
"Creating new port object with GUID 0x%" PRIx64 "\n",
|
|
Packit Service |
54dbc3 |
cl_ntoh64(p_ni->port_guid));
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
osm_node_init_physp(p_node, port_num, p_madw);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_port = osm_port_new(p_ni, p_node);
|
|
Packit Service |
54dbc3 |
if (PF(p_port == NULL)) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0D04: "
|
|
Packit Service |
54dbc3 |
"Unable to create new port object\n");
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
Add the new port object to the database.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
p_port_check =
|
|
Packit Service |
54dbc3 |
(osm_port_t *) cl_qmap_insert(&sm->p_subn->port_guid_tbl,
|
|
Packit Service |
54dbc3 |
p_ni->port_guid,
|
|
Packit Service |
54dbc3 |
&p_port->map_item);
|
|
Packit Service |
54dbc3 |
if (PF(p_port_check != p_port)) {
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
We should never be here!
|
|
Packit Service |
54dbc3 |
Somehow, this port GUID already exists in the table.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0D12: "
|
|
Packit Service |
54dbc3 |
"Port 0x%" PRIx64 " already in the database!\n",
|
|
Packit Service |
54dbc3 |
cl_ntoh64(p_ni->port_guid));
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
osm_port_delete(&p_port);
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_alias_guid = osm_alias_guid_new(p_ni->port_guid,
|
|
Packit Service |
54dbc3 |
p_port);
|
|
Packit Service |
54dbc3 |
if (PF(!p_alias_guid)) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0D11: "
|
|
Packit Service |
54dbc3 |
"alias guid memory allocation failed"
|
|
Packit Service |
54dbc3 |
" for port GUID 0x%" PRIx64 "\n",
|
|
Packit Service |
54dbc3 |
cl_ntoh64(p_ni->port_guid));
|
|
Packit Service |
54dbc3 |
goto alias_done;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* insert into alias guid table */
|
|
Packit Service |
54dbc3 |
p_alias_guid_check =
|
|
Packit Service |
54dbc3 |
(osm_alias_guid_t *) cl_qmap_insert(&sm->p_subn->alias_port_guid_tbl,
|
|
Packit Service |
54dbc3 |
p_alias_guid->alias_guid,
|
|
Packit Service |
54dbc3 |
&p_alias_guid->map_item);
|
|
Packit Service |
54dbc3 |
if (p_alias_guid_check != p_alias_guid) {
|
|
Packit Service |
54dbc3 |
/* alias GUID is a duplicate */
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0D13: "
|
|
Packit Service |
54dbc3 |
"Duplicate alias port GUID 0x%" PRIx64 "\n",
|
|
Packit Service |
54dbc3 |
cl_ntoh64(p_ni->port_guid));
|
|
Packit Service |
54dbc3 |
osm_alias_guid_delete(&p_alias_guid);
|
|
Packit Service |
54dbc3 |
osm_port_delete(&p_port);
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
alias_done:
|
|
Packit Service |
54dbc3 |
/* If we are a master, then this means the port is new on the subnet.
|
|
Packit Service |
54dbc3 |
Mark it as new - need to send trap 64 for these ports.
|
|
Packit Service |
54dbc3 |
The condition that we are master is true, since if we are in discovering
|
|
Packit Service |
54dbc3 |
state (meaning we woke up from standby or we are just initializing),
|
|
Packit Service |
54dbc3 |
then these ports may be new to us, but are not new on the subnet.
|
|
Packit Service |
54dbc3 |
If we are master, then the subnet as we know it is the updated one,
|
|
Packit Service |
54dbc3 |
and any new ports we encounter should cause trap 64. C14-72.1.1 */
|
|
Packit Service |
54dbc3 |
if (sm->p_subn->sm_state == IB_SMINFO_STATE_MASTER)
|
|
Packit Service |
54dbc3 |
p_port->is_new = 1;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
} else {
|
|
Packit Service |
54dbc3 |
osm_physp_t *p_physp = osm_node_get_physp_ptr(p_node, port_num);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (PF(p_physp == NULL)) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0D1C: "
|
|
Packit Service |
54dbc3 |
"No physical port found for node GUID 0x%"
|
|
Packit Service |
54dbc3 |
PRIx64 " port %u. Might be duplicate port GUID\n",
|
|
Packit Service |
54dbc3 |
cl_ntoh64(p_node->node_info.node_guid),
|
|
Packit Service |
54dbc3 |
port_num);
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
Update the DR Path to the port,
|
|
Packit Service |
54dbc3 |
in case the old one is no longer available.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
p_dr_path = osm_physp_get_dr_path_ptr(p_physp);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
osm_dr_path_init(p_dr_path, p_smp->hop_count,
|
|
Packit Service |
54dbc3 |
p_smp->initial_path);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
ni_rcv_get_port_info(sm, p_node, p_madw);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
Exit:
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(sm->p_log);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
static void ni_rcv_process_switch(IN osm_sm_t * sm, IN osm_node_t * p_node,
|
|
Packit Service |
54dbc3 |
IN const osm_madw_t * p_madw)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
ib_api_status_t status = IB_SUCCESS;
|
|
Packit Service |
54dbc3 |
osm_physp_t *p_physp;
|
|
Packit Service |
54dbc3 |
osm_madw_context_t context;
|
|
Packit Service |
54dbc3 |
osm_dr_path_t *path;
|
|
Packit Service |
54dbc3 |
ib_smp_t *p_smp;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(sm->p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_smp = osm_madw_get_smp_ptr(p_madw);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_physp = osm_node_get_physp_ptr(p_node, 0);
|
|
Packit Service |
54dbc3 |
/* update DR path of already initialized switch port 0 */
|
|
Packit Service |
54dbc3 |
path = osm_physp_get_dr_path_ptr(p_physp);
|
|
Packit Service |
54dbc3 |
osm_dr_path_init(path, p_smp->hop_count, p_smp->initial_path);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
context.si_context.node_guid = osm_node_get_node_guid(p_node);
|
|
Packit Service |
54dbc3 |
context.si_context.set_method = FALSE;
|
|
Packit Service |
54dbc3 |
context.si_context.light_sweep = FALSE;
|
|
Packit Service |
54dbc3 |
context.si_context.lft_top_change = FALSE;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* Request a SwitchInfo attribute */
|
|
Packit Service |
54dbc3 |
status = osm_req_get(sm, path, IB_MAD_ATTR_SWITCH_INFO, 0, TRUE, 0,
|
|
Packit Service |
54dbc3 |
0, CL_DISP_MSGID_NONE, &context);
|
|
Packit Service |
54dbc3 |
if (status != IB_SUCCESS)
|
|
Packit Service |
54dbc3 |
/* continue despite error */
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0D06: "
|
|
Packit Service |
54dbc3 |
"Failure initiating SwitchInfo request (%s)\n",
|
|
Packit Service |
54dbc3 |
ib_get_err_str(status));
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(sm->p_log);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/**********************************************************************
|
|
Packit Service |
54dbc3 |
The plock must be held before calling this function.
|
|
Packit Service |
54dbc3 |
**********************************************************************/
|
|
Packit Service |
54dbc3 |
static void ni_rcv_process_existing_switch(IN osm_sm_t * sm,
|
|
Packit Service |
54dbc3 |
IN osm_node_t * p_node,
|
|
Packit Service |
54dbc3 |
IN const osm_madw_t * p_madw)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(sm->p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
If this switch has already been probed during this sweep,
|
|
Packit Service |
54dbc3 |
then don't bother reprobing it.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
if (p_node->discovery_count == 1)
|
|
Packit Service |
54dbc3 |
ni_rcv_process_switch(sm, p_node, p_madw);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(sm->p_log);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/**********************************************************************
|
|
Packit Service |
54dbc3 |
The plock must be held before calling this function.
|
|
Packit Service |
54dbc3 |
**********************************************************************/
|
|
Packit Service |
54dbc3 |
static void ni_rcv_process_new_switch(IN osm_sm_t * sm, IN osm_node_t * p_node,
|
|
Packit Service |
54dbc3 |
IN const osm_madw_t * p_madw)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(sm->p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
ni_rcv_process_switch(sm, p_node, p_madw);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
A node guid of 0 is the corner case that indicates
|
|
Packit Service |
54dbc3 |
we discovered our own node. Initialize the subnet
|
|
Packit Service |
54dbc3 |
object with the SM's own port guid.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
if (osm_madw_get_ni_context_ptr(p_madw)->node_guid == 0)
|
|
Packit Service |
54dbc3 |
sm->p_subn->sm_port_guid = p_node->node_info.port_guid;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(sm->p_log);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/**********************************************************************
|
|
Packit Service |
54dbc3 |
The plock must NOT be held before calling this function.
|
|
Packit Service |
54dbc3 |
**********************************************************************/
|
|
Packit Service |
54dbc3 |
static void ni_rcv_process_new(IN osm_sm_t * sm, IN const osm_madw_t * p_madw)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_node_t *p_node;
|
|
Packit Service |
54dbc3 |
osm_node_t *p_node_check;
|
|
Packit Service |
54dbc3 |
osm_port_t *p_port;
|
|
Packit Service |
54dbc3 |
osm_port_t *p_port_check;
|
|
Packit Service |
54dbc3 |
osm_router_t *p_rtr = NULL;
|
|
Packit Service |
54dbc3 |
osm_router_t *p_rtr_check;
|
|
Packit Service |
54dbc3 |
cl_qmap_t *p_rtr_guid_tbl;
|
|
Packit Service |
54dbc3 |
ib_node_info_t *p_ni;
|
|
Packit Service |
54dbc3 |
ib_smp_t *p_smp;
|
|
Packit Service |
54dbc3 |
osm_ni_context_t *p_ni_context;
|
|
Packit Service |
54dbc3 |
osm_alias_guid_t *p_alias_guid, *p_alias_guid_check;
|
|
Packit Service |
54dbc3 |
uint8_t port_num;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(sm->p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_smp = osm_madw_get_smp_ptr(p_madw);
|
|
Packit Service |
54dbc3 |
p_ni = ib_smp_get_payload_ptr(p_smp);
|
|
Packit Service |
54dbc3 |
p_ni_context = osm_madw_get_ni_context_ptr(p_madw);
|
|
Packit Service |
54dbc3 |
port_num = ib_node_info_get_local_port_num(p_ni);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
osm_dump_smp_dr_path_v2(sm->p_log, p_smp, FILE_ID, OSM_LOG_VERBOSE);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_VERBOSE,
|
|
Packit Service |
54dbc3 |
"Discovered new %s node,"
|
|
Packit Service |
54dbc3 |
"\n\t\t\t\tGUID 0x%" PRIx64 ", TID 0x%" PRIx64 "\n",
|
|
Packit Service |
54dbc3 |
ib_get_node_type_str(p_ni->node_type),
|
|
Packit Service |
54dbc3 |
cl_ntoh64(p_ni->node_guid), cl_ntoh64(p_smp->trans_id));
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (PF(port_num > p_ni->num_ports)) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0D0A: "
|
|
Packit Service |
54dbc3 |
"New %s node GUID 0x%" PRIx64 "is non-compliant and "
|
|
Packit Service |
54dbc3 |
"is being ignored since the "
|
|
Packit Service |
54dbc3 |
"local port num %u > num ports %u\n",
|
|
Packit Service |
54dbc3 |
ib_get_node_type_str(p_ni->node_type),
|
|
Packit Service |
54dbc3 |
cl_ntoh64(p_ni->node_guid), port_num,
|
|
Packit Service |
54dbc3 |
p_ni->num_ports);
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_node = osm_node_new(p_madw);
|
|
Packit Service |
54dbc3 |
if (PF(p_node == NULL)) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0D07: "
|
|
Packit Service |
54dbc3 |
"Unable to create new node object\n");
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
Create a new port object to represent this node's physical
|
|
Packit Service |
54dbc3 |
ports in the port table.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
p_port = osm_port_new(p_ni, p_node);
|
|
Packit Service |
54dbc3 |
if (PF(p_port == NULL)) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0D14: "
|
|
Packit Service |
54dbc3 |
"Unable to create new port object\n");
|
|
Packit Service |
54dbc3 |
osm_node_delete(&p_node);
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
Add the new port object to the database.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
p_port_check =
|
|
Packit Service |
54dbc3 |
(osm_port_t *) cl_qmap_insert(&sm->p_subn->port_guid_tbl,
|
|
Packit Service |
54dbc3 |
p_ni->port_guid, &p_port->map_item);
|
|
Packit Service |
54dbc3 |
if (PF(p_port_check != p_port)) {
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
We should never be here!
|
|
Packit Service |
54dbc3 |
Somehow, this port GUID already exists in the table.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0D15: "
|
|
Packit Service |
54dbc3 |
"Duplicate Port GUID 0x%" PRIx64
|
|
Packit Service |
54dbc3 |
"! Found by the two directed routes:\n",
|
|
Packit Service |
54dbc3 |
cl_ntoh64(p_ni->port_guid));
|
|
Packit Service |
54dbc3 |
osm_dump_dr_path_v2(sm->p_log,
|
|
Packit Service |
54dbc3 |
osm_physp_get_dr_path_ptr(p_port->p_physp),
|
|
Packit Service |
54dbc3 |
FILE_ID, OSM_LOG_ERROR);
|
|
Packit Service |
54dbc3 |
osm_dump_dr_path_v2(sm->p_log,
|
|
Packit Service |
54dbc3 |
osm_physp_get_dr_path_ptr(p_port_check->
|
|
Packit Service |
54dbc3 |
p_physp),
|
|
Packit Service |
54dbc3 |
FILE_ID, OSM_LOG_ERROR);
|
|
Packit Service |
54dbc3 |
osm_port_delete(&p_port);
|
|
Packit Service |
54dbc3 |
osm_node_delete(&p_node);
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_alias_guid = osm_alias_guid_new(p_ni->port_guid,
|
|
Packit Service |
54dbc3 |
p_port);
|
|
Packit Service |
54dbc3 |
if (PF(!p_alias_guid)) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0D18: "
|
|
Packit Service |
54dbc3 |
"alias guid memory allocation failed"
|
|
Packit Service |
54dbc3 |
" for port GUID 0x%" PRIx64 "\n",
|
|
Packit Service |
54dbc3 |
cl_ntoh64(p_ni->port_guid));
|
|
Packit Service |
54dbc3 |
goto alias_done2;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* insert into alias guid table */
|
|
Packit Service |
54dbc3 |
p_alias_guid_check =
|
|
Packit Service |
54dbc3 |
(osm_alias_guid_t *) cl_qmap_insert(&sm->p_subn->alias_port_guid_tbl,
|
|
Packit Service |
54dbc3 |
p_alias_guid->alias_guid,
|
|
Packit Service |
54dbc3 |
&p_alias_guid->map_item);
|
|
Packit Service |
54dbc3 |
if (p_alias_guid_check != p_alias_guid) {
|
|
Packit Service |
54dbc3 |
/* alias GUID is a duplicate */
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0D19: "
|
|
Packit Service |
54dbc3 |
"Duplicate alias port GUID 0x%" PRIx64 "\n",
|
|
Packit Service |
54dbc3 |
cl_ntoh64(p_ni->port_guid));
|
|
Packit Service |
54dbc3 |
osm_alias_guid_delete(&p_alias_guid);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
alias_done2:
|
|
Packit Service |
54dbc3 |
/* If we are a master, then this means the port is new on the subnet.
|
|
Packit Service |
54dbc3 |
Mark it as new - need to send trap 64 on these ports.
|
|
Packit Service |
54dbc3 |
The condition that we are master is true, since if we are in discovering
|
|
Packit Service |
54dbc3 |
state (meaning we woke up from standby or we are just initializing),
|
|
Packit Service |
54dbc3 |
then these ports may be new to us, but are not new on the subnet.
|
|
Packit Service |
54dbc3 |
If we are master, then the subnet as we know it is the updated one,
|
|
Packit Service |
54dbc3 |
and any new ports we encounter should cause trap 64. C14-72.1.1 */
|
|
Packit Service |
54dbc3 |
if (sm->p_subn->sm_state == IB_SMINFO_STATE_MASTER)
|
|
Packit Service |
54dbc3 |
p_port->is_new = 1;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* If there were RouterInfo or other router attribute,
|
|
Packit Service |
54dbc3 |
this would be elsewhere */
|
|
Packit Service |
54dbc3 |
if (p_ni->node_type == IB_NODE_TYPE_ROUTER) {
|
|
Packit Service |
54dbc3 |
if (PF((p_rtr = osm_router_new(p_port)) == NULL))
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0D1A: "
|
|
Packit Service |
54dbc3 |
"Unable to create new router object\n");
|
|
Packit Service |
54dbc3 |
else {
|
|
Packit Service |
54dbc3 |
p_rtr_guid_tbl = &sm->p_subn->rtr_guid_tbl;
|
|
Packit Service |
54dbc3 |
p_rtr_check =
|
|
Packit Service |
54dbc3 |
(osm_router_t *) cl_qmap_insert(p_rtr_guid_tbl,
|
|
Packit Service |
54dbc3 |
p_ni->port_guid,
|
|
Packit Service |
54dbc3 |
&p_rtr->map_item);
|
|
Packit Service |
54dbc3 |
if (PF(p_rtr_check != p_rtr))
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0D1B: "
|
|
Packit Service |
54dbc3 |
"Unable to add port GUID:0x%016" PRIx64
|
|
Packit Service |
54dbc3 |
" to router table\n",
|
|
Packit Service |
54dbc3 |
cl_ntoh64(p_ni->port_guid));
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_node_check =
|
|
Packit Service |
54dbc3 |
(osm_node_t *) cl_qmap_insert(&sm->p_subn->node_guid_tbl,
|
|
Packit Service |
54dbc3 |
p_ni->node_guid, &p_node->map_item);
|
|
Packit Service |
54dbc3 |
if (PF(p_node_check != p_node)) {
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
This node must have been inserted by another thread.
|
|
Packit Service |
54dbc3 |
This is unexpected, but is not an error.
|
|
Packit Service |
54dbc3 |
We can simply clean-up, since the other thread will
|
|
Packit Service |
54dbc3 |
see this processing through to completion.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_VERBOSE,
|
|
Packit Service |
54dbc3 |
"Discovery race detected at node 0x%" PRIx64 "\n",
|
|
Packit Service |
54dbc3 |
cl_ntoh64(p_ni->node_guid));
|
|
Packit Service |
54dbc3 |
osm_node_delete(&p_node);
|
|
Packit Service |
54dbc3 |
p_node = p_node_check;
|
|
Packit Service |
54dbc3 |
ni_rcv_set_links(sm, p_node, port_num, p_ni_context);
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
} else
|
|
Packit Service |
54dbc3 |
ni_rcv_set_links(sm, p_node, port_num, p_ni_context);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_node->discovery_count++;
|
|
Packit Service |
54dbc3 |
ni_rcv_get_node_desc(sm, p_node, p_madw);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
switch (p_ni->node_type) {
|
|
Packit Service |
54dbc3 |
case IB_NODE_TYPE_CA:
|
|
Packit Service |
54dbc3 |
case IB_NODE_TYPE_ROUTER:
|
|
Packit Service |
54dbc3 |
ni_rcv_process_new_ca_or_router(sm, p_node, p_madw);
|
|
Packit Service |
54dbc3 |
break;
|
|
Packit Service |
54dbc3 |
case IB_NODE_TYPE_SWITCH:
|
|
Packit Service |
54dbc3 |
ni_rcv_process_new_switch(sm, p_node, p_madw);
|
|
Packit Service |
54dbc3 |
break;
|
|
Packit Service |
54dbc3 |
default:
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0D16: "
|
|
Packit Service |
54dbc3 |
"Unknown node type %u with GUID 0x%" PRIx64 "\n",
|
|
Packit Service |
54dbc3 |
p_ni->node_type, cl_ntoh64(p_ni->node_guid));
|
|
Packit Service |
54dbc3 |
break;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
Exit:
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(sm->p_log);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/**********************************************************************
|
|
Packit Service |
54dbc3 |
The plock must be held before calling this function.
|
|
Packit Service |
54dbc3 |
**********************************************************************/
|
|
Packit Service |
54dbc3 |
static void ni_rcv_process_existing(IN osm_sm_t * sm, IN osm_node_t * p_node,
|
|
Packit Service |
54dbc3 |
IN const osm_madw_t * p_madw)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
ib_node_info_t *p_ni;
|
|
Packit Service |
54dbc3 |
ib_smp_t *p_smp;
|
|
Packit Service |
54dbc3 |
osm_ni_context_t *p_ni_context;
|
|
Packit Service |
54dbc3 |
uint8_t port_num;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(sm->p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_smp = osm_madw_get_smp_ptr(p_madw);
|
|
Packit Service |
54dbc3 |
p_ni = ib_smp_get_payload_ptr(p_smp);
|
|
Packit Service |
54dbc3 |
p_ni_context = osm_madw_get_ni_context_ptr(p_madw);
|
|
Packit Service |
54dbc3 |
port_num = ib_node_info_get_local_port_num(p_ni);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_VERBOSE,
|
|
Packit Service |
54dbc3 |
"Rediscovered %s node 0x%" PRIx64 " TID 0x%" PRIx64
|
|
Packit Service |
54dbc3 |
", discovered %u times already\n",
|
|
Packit Service |
54dbc3 |
ib_get_node_type_str(p_ni->node_type),
|
|
Packit Service |
54dbc3 |
cl_ntoh64(p_ni->node_guid),
|
|
Packit Service |
54dbc3 |
cl_ntoh64(p_smp->trans_id), p_node->discovery_count);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (PF(port_num > p_ni->num_ports)) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0D0C: "
|
|
Packit Service |
54dbc3 |
"Existing %s node GUID 0x%" PRIx64 "is non-compliant "
|
|
Packit Service |
54dbc3 |
"and is being ignored since the "
|
|
Packit Service |
54dbc3 |
"local port num %u > num ports %u\n",
|
|
Packit Service |
54dbc3 |
ib_get_node_type_str(p_ni->node_type),
|
|
Packit Service |
54dbc3 |
cl_ntoh64(p_ni->node_guid), port_num,
|
|
Packit Service |
54dbc3 |
p_ni->num_ports);
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
If we haven't already encountered this existing node
|
|
Packit Service |
54dbc3 |
on this particular sweep, then process further.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
p_node->discovery_count++;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
switch (p_ni->node_type) {
|
|
Packit Service |
54dbc3 |
case IB_NODE_TYPE_CA:
|
|
Packit Service |
54dbc3 |
case IB_NODE_TYPE_ROUTER:
|
|
Packit Service |
54dbc3 |
ni_rcv_process_existing_ca_or_router(sm, p_node, p_madw);
|
|
Packit Service |
54dbc3 |
break;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
case IB_NODE_TYPE_SWITCH:
|
|
Packit Service |
54dbc3 |
ni_rcv_process_existing_switch(sm, p_node, p_madw);
|
|
Packit Service |
54dbc3 |
break;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
default:
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0D09: "
|
|
Packit Service |
54dbc3 |
"Unknown node type %u with GUID 0x%" PRIx64 "\n",
|
|
Packit Service |
54dbc3 |
p_ni->node_type, cl_ntoh64(p_ni->node_guid));
|
|
Packit Service |
54dbc3 |
break;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if ( p_ni->sys_guid != p_node->node_info.sys_guid) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_DEBUG, "Updated SysImageGUID: 0x%"
|
|
Packit Service |
54dbc3 |
PRIx64 " for node 0x%" PRIx64 "\n",
|
|
Packit Service |
54dbc3 |
cl_ntoh64(p_ni->sys_guid),
|
|
Packit Service |
54dbc3 |
cl_ntoh64(p_ni->node_guid));
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
ni_rcv_set_links(sm, p_node, port_num, p_ni_context);
|
|
Packit Service |
54dbc3 |
p_node->node_info = *p_ni;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
Exit:
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(sm->p_log);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
void osm_ni_rcv_process(IN void *context, IN void *data)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_sm_t *sm = context;
|
|
Packit Service |
54dbc3 |
osm_madw_t *p_madw = data;
|
|
Packit Service |
54dbc3 |
ib_node_info_t *p_ni;
|
|
Packit Service |
54dbc3 |
ib_smp_t *p_smp;
|
|
Packit Service |
54dbc3 |
osm_node_t *p_node;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
CL_ASSERT(sm);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(sm->p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
CL_ASSERT(p_madw);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_smp = osm_madw_get_smp_ptr(p_madw);
|
|
Packit Service |
54dbc3 |
p_ni = ib_smp_get_payload_ptr(p_smp);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
CL_ASSERT(p_smp->attr_id == IB_MAD_ATTR_NODE_INFO);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (PF(p_ni->node_guid == 0)) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0D16: "
|
|
Packit Service |
54dbc3 |
"Got Zero Node GUID! Found on the directed route:\n");
|
|
Packit Service |
54dbc3 |
osm_dump_smp_dr_path_v2(sm->p_log, p_smp, FILE_ID, OSM_LOG_ERROR);
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (PF(p_ni->port_guid == 0)) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0D17: "
|
|
Packit Service |
54dbc3 |
"Got Zero Port GUID! Found on the directed route:\n");
|
|
Packit Service |
54dbc3 |
osm_dump_smp_dr_path_v2(sm->p_log, p_smp, FILE_ID, OSM_LOG_ERROR);
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (ib_smp_get_status(p_smp)) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
|
|
Packit Service |
54dbc3 |
"MAD status 0x%x received\n",
|
|
Packit Service |
54dbc3 |
cl_ntoh16(ib_smp_get_status(p_smp)));
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
Determine if this node has already been discovered,
|
|
Packit Service |
54dbc3 |
and process accordingly.
|
|
Packit Service |
54dbc3 |
During processing of this node, hold the shared lock.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
CL_PLOCK_EXCL_ACQUIRE(sm->p_lock);
|
|
Packit Service |
54dbc3 |
p_node = osm_get_node_by_guid(sm->p_subn, p_ni->node_guid);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
osm_dump_node_info_v2(sm->p_log, p_ni, FILE_ID, OSM_LOG_DEBUG);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (!p_node)
|
|
Packit Service |
54dbc3 |
ni_rcv_process_new(sm, p_madw);
|
|
Packit Service |
54dbc3 |
else
|
|
Packit Service |
54dbc3 |
ni_rcv_process_existing(sm, p_node, p_madw);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
CL_PLOCK_RELEASE(sm->p_lock);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
Exit:
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(sm->p_log);
|
|
Packit Service |
54dbc3 |
}
|