#if HAVE_CONFIG_H
# include <config.h>
-#endif /* HAVE_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
#define _GNU_SOURCE
#include <stdio.h>
#include "internal.h"
#include "chassis.h"
-static int timeout_ms = 2000;
static int show_progress = 0;
int ibdebug;
-void
-decode_port_info(ibnd_port_t *port)
+void decode_port_info(ibnd_port_t * port)
{
port->base_lid = (uint16_t) mad_get_field(port->info, 0, IB_PORT_LID_F);
port->lmc = (uint8_t) mad_get_field(port->info, 0, IB_PORT_LMC_F);
}
-static int
-get_port_info(struct ibnd_fabric *fabric, struct ibnd_port *port,
- int portnum, ib_portid_t *portid)
+static int get_port_info(struct ibmad_port *ibmad_port,
+ ibnd_fabric_t * fabric, ibnd_port_t * port,
+ int portnum, ib_portid_t * portid)
{
char width[64], speed[64];
int iwidth;
int ispeed;
- port->port.portnum = portnum;
- iwidth = mad_get_field(port->port.info, 0, IB_PORT_LINK_WIDTH_ACTIVE_F);
- ispeed = mad_get_field(port->port.info, 0, IB_PORT_LINK_SPEED_ACTIVE_F);
+ port->portnum = portnum;
+ iwidth = mad_get_field(port->info, 0, IB_PORT_LINK_WIDTH_ACTIVE_F);
+ ispeed = mad_get_field(port->info, 0, IB_PORT_LINK_SPEED_ACTIVE_F);
- if (!smp_query_via(port->port.info, portid, IB_ATTR_PORT_INFO, portnum, timeout_ms,
- fabric->fabric.ibmad_port))
+ if (!smp_query_via(port->info, portid, IB_ATTR_PORT_INFO,
+ portnum, 0, ibmad_port))
return -1;
- decode_port_info(&(port->port));
+ decode_port_info(port);
- IBND_DEBUG("portid %s portnum %d: base lid %d state %d physstate %d %s %s\n",
- portid2str(portid), portnum, port->port.base_lid,
- mad_get_field(port->port.info, 0, IB_PORT_STATE_F),
- mad_get_field(port->port.info, 0, IB_PORT_PHYS_STATE_F),
- mad_dump_val(IB_PORT_LINK_WIDTH_ACTIVE_F, width, 64, &iwidth),
- mad_dump_val(IB_PORT_LINK_SPEED_ACTIVE_F, speed, 64, &ispeed));
+ IBND_DEBUG
+ ("portid %s portnum %d: base lid %d state %d physstate %d %s %s\n",
+ portid2str(portid), portnum, port->base_lid,
+ mad_get_field(port->info, 0, IB_PORT_STATE_F),
+ mad_get_field(port->info, 0, IB_PORT_PHYS_STATE_F),
+ mad_dump_val(IB_PORT_LINK_WIDTH_ACTIVE_F, width, 64, &iwidth),
+ mad_dump_val(IB_PORT_LINK_SPEED_ACTIVE_F, speed, 64, &ispeed));
return 0;
}
/*
* Returns -1 if error.
*/
-static int
-query_node_info(struct ibnd_fabric *fabric, struct ibnd_node *node, ib_portid_t *portid)
+static int query_node_info(struct ibmad_port *ibmad_port,
+ ibnd_fabric_t * fabric, ibnd_node_t * node,
+ ib_portid_t * portid)
{
- if (!smp_query_via(&(node->node.info), portid, IB_ATTR_NODE_INFO, 0, timeout_ms,
- fabric->fabric.ibmad_port))
+ if (!smp_query_via(&(node->info), portid, IB_ATTR_NODE_INFO, 0, 0,
+ ibmad_port))
return -1;
/* decode just a couple of fields for quicker reference. */
- mad_decode_field(node->node.info, IB_NODE_GUID_F, &(node->node.guid));
- mad_decode_field(node->node.info, IB_NODE_TYPE_F, &(node->node.type));
- mad_decode_field(node->node.info, IB_NODE_NPORTS_F,
- &(node->node.numports));
+ mad_decode_field(node->info, IB_NODE_GUID_F, &(node->guid));
+ mad_decode_field(node->info, IB_NODE_TYPE_F, &(node->type));
+ mad_decode_field(node->info, IB_NODE_NPORTS_F, &(node->numports));
return (0);
}
/*
* Returns 0 if non switch node is found, 1 if switch is found, -1 if error.
*/
-static int
-query_node(struct ibnd_fabric *fabric, struct ibnd_node *inode,
- struct ibnd_port *iport, ib_portid_t *portid)
+static int query_node(struct ibmad_port *ibmad_port, ibnd_fabric_t * fabric,
+ ibnd_node_t * node, ibnd_port_t * port,
+ ib_portid_t * portid)
{
- ibnd_node_t *node = &(inode->node);
- ibnd_port_t *port = &(iport->port);
- void *nd = inode->node.nodedesc;
+ int rc = 0;
+ void *nd = node->nodedesc;
- if (query_node_info(fabric, inode, portid))
- return -1;
+ if ((rc = query_node_info(ibmad_port, fabric, node, portid)) != 0)
+ return rc;
port->portnum = mad_get_field(node->info, 0, IB_NODE_LOCAL_PORT_F);
port->guid = mad_get_field64(node->info, 0, IB_NODE_PORT_GUID_F);
- if (!smp_query_via(nd, portid, IB_ATTR_NODE_DESC, 0, timeout_ms,
- fabric->fabric.ibmad_port))
+ if (!smp_query_via(nd, portid, IB_ATTR_NODE_DESC, 0, 0, ibmad_port))
return -1;
- if (!smp_query_via(port->info, portid, IB_ATTR_PORT_INFO, 0, timeout_ms,
- fabric->fabric.ibmad_port))
+ if (!smp_query_via(port->info, portid, IB_ATTR_PORT_INFO, 0, 0,
+ ibmad_port))
return -1;
decode_port_info(port);
node->smalmc = port->lmc;
/* after we have the sma information find out the real PortInfo for this port */
- if (!smp_query_via(port->info, portid, IB_ATTR_PORT_INFO, port->portnum, timeout_ms,
- fabric->fabric.ibmad_port))
+ if (!smp_query_via(port->info, portid, IB_ATTR_PORT_INFO,
+ port->portnum, 0, ibmad_port))
return -1;
decode_port_info(port);
- port->base_lid = (uint16_t) node->smalid; /* LID is still defined by port 0 */
+ port->base_lid = (uint16_t) node->smalid; /* LID is still defined by port 0 */
port->lmc = (uint8_t) node->smalmc;
- if (!smp_query_via(node->switchinfo, portid, IB_ATTR_SWITCH_INFO, 0, timeout_ms,
- fabric->fabric.ibmad_port))
+ if (!smp_query_via(node->switchinfo, portid, IB_ATTR_SWITCH_INFO, 0, 0,
+ ibmad_port))
node->smaenhsp0 = 0; /* assume base SP0 */
else
- mad_decode_field(node->switchinfo, IB_SW_ENHANCED_PORT0_F, &node->smaenhsp0);
+ mad_decode_field(node->switchinfo, IB_SW_ENHANCED_PORT0_F,
+ &node->smaenhsp0);
IBND_DEBUG("portid %s: got switch node %" PRIx64 " '%s'\n",
- portid2str(portid), node->guid, node->nodedesc);
+ portid2str(portid), node->guid, node->nodedesc);
return 0;
}
-static int
-add_port_to_dpath(ib_dr_path_t *path, int nextport)
+static int add_port_to_dpath(ib_dr_path_t * path, int nextport)
{
- if (path->cnt+2 >= sizeof(path->p))
+ if (path->cnt + 2 >= sizeof(path->p)) {
+ IBND_ERROR("DR path has grown too long\n");
return -1;
+ }
++path->cnt;
path->p[path->cnt] = (uint8_t) nextport;
return path->cnt;
}
-static int
-extend_dpath(struct ibnd_fabric *f, ib_portid_t *portid, int nextport)
+static void retract_dpath(ib_portid_t * path)
+{
+ path->drpath.cnt--; /* restore path */
+ if (path->drpath.cnt == 0 && path->lid) {
+ /* return to lid based routing on this path */
+ path->drpath.drslid = 0;
+ path->drpath.drdlid = 0;
+ }
+}
+
+static int extend_dpath(struct ibmad_port *ibmad_port, ibnd_fabric_t * fabric,
+ ib_portid_t * portid, int nextport)
{
int rc = 0;
if (portid->lid) {
/* If we were LID routed we need to set up the drslid */
- if (!f->selfportid.lid)
- if (ib_resolve_self_via(&f->selfportid, NULL, NULL,
- f->fabric.ibmad_port) < 0)
+ if (!fabric->selfportid.lid)
+ if (ib_resolve_self_via(&fabric->selfportid, NULL, NULL,
+ ibmad_port) < 0) {
+ IBND_ERROR("Failed to resolve self\n");
return -1;
+ }
- portid->drpath.drslid = (uint16_t) f->selfportid.lid;
+ portid->drpath.drslid = (uint16_t) fabric->selfportid.lid;
portid->drpath.drdlid = 0xFFFF;
}
rc = add_port_to_dpath(&portid->drpath, nextport);
- if ((rc != -1) && (portid->drpath.cnt > f->fabric.maxhops_discovered))
- f->fabric.maxhops_discovered = portid->drpath.cnt;
+ if ((rc != -1) && (portid->drpath.cnt > fabric->maxhops_discovered))
+ fabric->maxhops_discovered = portid->drpath.cnt;
return (rc);
}
-static void
-dump_endnode(ib_portid_t *path, char *prompt,
- struct ibnd_node *node, struct ibnd_port *port)
+static void dump_endnode(ib_portid_t * path, char *prompt,
+ ibnd_node_t * node, ibnd_port_t * port)
{
char type[64];
if (!show_progress)
return;
- mad_dump_node_type(type, 64, &(node->node.type), sizeof(int)),
-
+ mad_dump_node_type(type, 64, &(node->type), sizeof(int));
printf("%s -> %s %s {%016" PRIx64 "} portnum %d base lid %d-%d\"%s\"\n",
- portid2str(path), prompt, type,
- node->node.guid,
- node->node.type == IB_NODE_SWITCH ? 0 : port->port.portnum,
- port->port.base_lid, port->port.base_lid + (1 << port->port.lmc) - 1,
- node->node.nodedesc);
+ portid2str(path), prompt, type, node->guid,
+ node->type == IB_NODE_SWITCH ? 0 : port->portnum,
+ port->base_lid,
+ port->base_lid + (1 << port->lmc) - 1, node->nodedesc);
}
-static struct ibnd_node *
-find_existing_node(struct ibnd_fabric *fabric, struct ibnd_node *new)
+static ibnd_node_t *find_existing_node(ibnd_fabric_t * fabric,
+ ibnd_node_t * new)
{
- int hash = HASHGUID(new->node.guid) % HTSZ;
- struct ibnd_node *node;
+ int hash = HASHGUID(new->guid) % HTSZ;
+ ibnd_node_t *node;
for (node = fabric->nodestbl[hash]; node; node = node->htnext)
- if (node->node.guid == new->node.guid)
+ if (node->guid == new->guid)
return node;
return NULL;
}
-ibnd_node_t *
-ibnd_find_node_guid(ibnd_fabric_t *fabric, uint64_t guid)
+ibnd_node_t *ibnd_find_node_guid(ibnd_fabric_t * fabric, uint64_t guid)
{
- struct ibnd_fabric *f = CONV_FABRIC_INTERNAL(fabric);
int hash = HASHGUID(guid) % HTSZ;
- struct ibnd_node *node;
+ ibnd_node_t *node;
- for (node = f->nodestbl[hash]; node; node = node->htnext)
- if (node->node.guid == guid)
- return (ibnd_node_t *)node;
+ if (!fabric) {
+ IBND_DEBUG("fabric parameter NULL\n");
+ return (NULL);
+ }
+
+ for (node = fabric->nodestbl[hash]; node; node = node->htnext)
+ if (node->guid == guid)
+ return (ibnd_node_t *) node;
return NULL;
}
-ibnd_node_t *
-ibnd_update_node(ibnd_node_t *node)
+static int _check_ibmad_port(struct ibmad_port *ibmad_port)
+{
+ if (!ibmad_port) {
+ IBND_DEBUG("ibmad_port must be specified\n");
+ return (-1);
+ }
+ if (mad_rpc_class_agent(ibmad_port, IB_SMI_CLASS) == -1
+ || mad_rpc_class_agent(ibmad_port, IB_SMI_DIRECT_CLASS) == -1) {
+ IBND_DEBUG("ibmad_port must be opened with "
+ "IB_SMI_CLASS && IB_SMI_DIRECT_CLASS\n");
+ return (-1);
+ }
+ return (0);
+}
+
+ibnd_node_t *ibnd_update_node(struct ibmad_port * ibmad_port,
+ ibnd_fabric_t * fabric, ibnd_node_t * node)
{
char portinfo_port0[IB_SMP_DATA_SIZE];
void *nd = node->nodedesc;
int p = 0;
- struct ibnd_fabric *f = CONV_FABRIC_INTERNAL(node->fabric);
- struct ibnd_node *n = CONV_NODE_INTERNAL(node);
- if (query_node_info(f, n, &(n->node.path_portid)))
+ if (_check_ibmad_port(ibmad_port) < 0)
return (NULL);
- if (!smp_query_via(nd, &(n->node.path_portid), IB_ATTR_NODE_DESC, 0, timeout_ms,
- f->fabric.ibmad_port))
+ if (!fabric) {
+ IBND_DEBUG("fabric parameter NULL\n");
+ return (NULL);
+ }
+
+ if (!node) {
+ IBND_DEBUG("node parameter NULL\n");
+ return (NULL);
+ }
+
+ if (query_node_info(ibmad_port, fabric, node, &(node->path_portid)))
+ return (NULL);
+
+ if (!smp_query_via(nd, &(node->path_portid), IB_ATTR_NODE_DESC, 0, 0,
+ ibmad_port))
return (NULL);
/* update all the port info's */
- for (p = 1; p >= n->node.numports; p++) {
- get_port_info(f, CONV_PORT_INTERNAL(n->node.ports[p]), p, &(n->node.path_portid));
+ for (p = 1; p >= node->numports; p++) {
+ get_port_info(ibmad_port, fabric, node->ports[p],
+ p, &(node->path_portid));
}
- if (n->node.type != IB_NODE_SWITCH)
+ if (node->type != IB_NODE_SWITCH)
goto done;
- if (!smp_query_via(portinfo_port0, &(n->node.path_portid), IB_ATTR_PORT_INFO, 0, timeout_ms,
- f->fabric.ibmad_port))
+ if (!smp_query_via
+ (portinfo_port0, &(node->path_portid), IB_ATTR_PORT_INFO, 0, 0,
+ ibmad_port))
return (NULL);
- n->node.smalid = mad_get_field(portinfo_port0, 0, IB_PORT_LID_F);
- n->node.smalmc = mad_get_field(portinfo_port0, 0, IB_PORT_LMC_F);
+ node->smalid = mad_get_field(portinfo_port0, 0, IB_PORT_LID_F);
+ node->smalmc = mad_get_field(portinfo_port0, 0, IB_PORT_LMC_F);
- if (!smp_query_via(node->switchinfo, &(n->node.path_portid), IB_ATTR_SWITCH_INFO, 0, timeout_ms,
- f->fabric.ibmad_port))
- node->smaenhsp0 = 0; /* assume base SP0 */
+ if (!smp_query_via(node->switchinfo, &(node->path_portid),
+ IB_ATTR_SWITCH_INFO, 0, 0, ibmad_port))
+ node->smaenhsp0 = 0; /* assume base SP0 */
else
- mad_decode_field(node->switchinfo, IB_SW_ENHANCED_PORT0_F, &n->node.smaenhsp0);
+ mad_decode_field(node->switchinfo, IB_SW_ENHANCED_PORT0_F,
+ &node->smaenhsp0);
done:
return (node);
}
-ibnd_node_t *
-ibnd_find_node_dr(ibnd_fabric_t *fabric, char *dr_str)
+ibnd_node_t *ibnd_find_node_dr(ibnd_fabric_t * fabric, char *dr_str)
{
- struct ibnd_fabric *f = CONV_FABRIC_INTERNAL(fabric);
int i = 0;
- ibnd_node_t *rc = f->fabric.from_node;
+ ibnd_node_t *rc;
ib_dr_path_t path;
+ if (!fabric) {
+ IBND_DEBUG("fabric parameter NULL\n");
+ return (NULL);
+ }
+
+ rc = fabric->from_node;
+
if (str2drpath(&path, dr_str, 0, 0) == -1) {
return (NULL);
}
return (rc);
}
-static void
-add_to_nodeguid_hash(struct ibnd_node *node, struct ibnd_node *hash[])
+static void add_to_nodeguid_hash(ibnd_node_t * node, ibnd_node_t * hash[])
{
- int hash_idx = HASHGUID(node->node.guid) % HTSZ;
+ int hash_idx = HASHGUID(node->guid) % HTSZ;
node->htnext = hash[hash_idx];
hash[hash_idx] = node;
}
-static void
-add_to_portguid_hash(struct ibnd_port *port, struct ibnd_port *hash[])
+static void add_to_portguid_hash(ibnd_port_t * port, ibnd_port_t * hash[])
{
- int hash_idx = HASHGUID(port->port.guid) % HTSZ;
+ int hash_idx = HASHGUID(port->guid) % HTSZ;
port->htnext = hash[hash_idx];
hash[hash_idx] = port;
}
-static void
-add_to_type_list(struct ibnd_node*node, struct ibnd_fabric *fabric)
+static void add_to_type_list(ibnd_node_t * node, ibnd_fabric_t * fabric)
{
- switch (node->node.type) {
- case IB_NODE_CA:
- node->type_next = fabric->ch_adapters;
- fabric->ch_adapters = node;
- break;
- case IB_NODE_SWITCH:
- node->type_next = fabric->switches;
- fabric->switches = node;
- break;
- case IB_NODE_ROUTER:
- node->type_next = fabric->routers;
- fabric->routers = node;
- break;
+ switch (node->type) {
+ case IB_NODE_CA:
+ node->type_next = fabric->ch_adapters;
+ fabric->ch_adapters = node;
+ break;
+ case IB_NODE_SWITCH:
+ node->type_next = fabric->switches;
+ fabric->switches = node;
+ break;
+ case IB_NODE_ROUTER:
+ node->type_next = fabric->routers;
+ fabric->routers = node;
+ break;
}
}
-static void
-add_to_nodedist(struct ibnd_node *node, struct ibnd_fabric *fabric)
+static void add_to_nodedist(ibnd_node_t * node, ibnd_fabric_t * fabric)
{
- int dist = node->node.dist;
- if (node->node.type != IB_NODE_SWITCH)
- dist = MAXHOPS; /* special Ca list */
+ int dist = node->dist;
+ if (node->type != IB_NODE_SWITCH)
+ dist = MAXHOPS; /* special Ca list */
node->dnext = fabric->nodesdist[dist];
fabric->nodesdist[dist] = node;
}
-
-static struct ibnd_node *
-create_node(struct ibnd_fabric *fabric, struct ibnd_node *temp, ib_portid_t *path, int dist)
+static ibnd_node_t *create_node(ibnd_fabric_t * fabric,
+ ibnd_node_t * temp, ib_portid_t * path,
+ int dist)
{
- struct ibnd_node *node;
+ ibnd_node_t *node;
node = malloc(sizeof(*node));
if (!node) {
- IBPANIC("OOM: node creation failed\n");
- return NULL;
+ IBND_ERROR("OOM: node creation failed\n");
+ return (NULL);
}
memcpy(node, temp, sizeof(*node));
- node->node.dist = dist;
- node->node.path_portid = *path;
- node->node.fabric = (ibnd_fabric_t *)fabric;
+ node->dist = dist;
+ node->path_portid = *path;
add_to_nodeguid_hash(node, fabric->nodestbl);
/* add this to the all nodes list */
- node->node.next = fabric->fabric.nodes;
- fabric->fabric.nodes = (ibnd_node_t *)node;
+ node->next = fabric->nodes;
+ fabric->nodes = (ibnd_node_t *) node;
add_to_type_list(node, fabric);
add_to_nodedist(node, fabric);
return node;
}
-static struct ibnd_port *
-find_existing_port_node(struct ibnd_node *node, struct ibnd_port *port)
+static struct ibnd_port *find_existing_port_node(ibnd_node_t * node,
+ ibnd_port_t * port)
{
- if (port->port.portnum > node->node.numports || node->node.ports == NULL )
+ if (port->portnum > node->numports || node->ports == NULL)
return (NULL);
- return (CONV_PORT_INTERNAL(node->node.ports[port->port.portnum]));
+ return (node->ports[port->portnum]);
}
-static struct ibnd_port *
-add_port_to_node(struct ibnd_fabric *fabric, struct ibnd_node *node, struct ibnd_port *temp)
+static struct ibnd_port *add_port_to_node(ibnd_fabric_t * fabric,
+ ibnd_node_t * node,
+ ibnd_port_t * temp)
{
- struct ibnd_port *port;
-
- port = malloc(sizeof(*port));
- if (!port)
- return NULL;
+ ibnd_port_t *port;
- memcpy(port, temp, sizeof(*port));
- port->port.node = (ibnd_node_t *)node;
- port->port.ext_portnum = 0;
-
- if (node->node.ports == NULL) {
- node->node.ports = calloc(sizeof(*node->node.ports), node->node.numports + 1);
- if (!node->node.ports) {
+ if (node->ports == NULL) {
+ node->ports = calloc(sizeof(*node->ports), node->numports + 1);
+ if (!node->ports) {
IBND_ERROR("Failed to allocate the ports array\n");
return (NULL);
}
}
- node->node.ports[temp->port.portnum] = (ibnd_port_t *)port;
+ port = malloc(sizeof(*port));
+ if (!port) {
+ IBND_ERROR("Failed to allocate port\n");
+ return NULL;
+ }
+
+ memcpy(port, temp, sizeof(*port));
+ port->node = (ibnd_node_t *) node;
+ port->ext_portnum = 0;
+
+ node->ports[temp->portnum] = (ibnd_port_t *) port;
add_to_portguid_hash(port, fabric->portstbl);
return port;
}
-static void
-link_ports(struct ibnd_node *node, struct ibnd_port *port,
- struct ibnd_node *remotenode, struct ibnd_port *remoteport)
+static void link_ports(ibnd_node_t * node, ibnd_port_t * port,
+ ibnd_node_t * remotenode, ibnd_port_t * remoteport)
{
- IBND_DEBUG("linking: 0x%" PRIx64 " %p->%p:%u and 0x%" PRIx64 " %p->%p:%u\n",
- node->node.guid, node, port, port->port.portnum,
- remotenode->node.guid, remotenode,
- remoteport, remoteport->port.portnum);
- if (port->port.remoteport)
- port->port.remoteport->remoteport = NULL;
- if (remoteport->port.remoteport)
- remoteport->port.remoteport->remoteport = NULL;
- port->port.remoteport = (ibnd_port_t *)remoteport;
- remoteport->port.remoteport = (ibnd_port_t *)port;
+ IBND_DEBUG("linking: 0x%" PRIx64 " %p->%p:%u and 0x%" PRIx64
+ " %p->%p:%u\n", node->guid, node, port, port->portnum,
+ remotenode->guid, remotenode, remoteport,
+ remoteport->portnum);
+ if (port->remoteport)
+ port->remoteport->remoteport = NULL;
+ if (remoteport->remoteport)
+ remoteport->remoteport->remoteport = NULL;
+ port->remoteport = (ibnd_port_t *) remoteport;
+ remoteport->remoteport = (ibnd_port_t *) port;
}
-static int
-get_remote_node(struct ibnd_fabric *fabric, struct ibnd_node *node, struct ibnd_port *port, ib_portid_t *path,
- int portnum, int dist)
+static int get_remote_node(struct ibmad_port *ibmad_port,
+ ibnd_fabric_t * fabric, ibnd_node_t * node,
+ ibnd_port_t * port, ib_portid_t * path,
+ int portnum, int dist)
{
- struct ibnd_node node_buf;
- struct ibnd_port port_buf;
- struct ibnd_node *remotenode, *oldnode;
- struct ibnd_port *remoteport, *oldport;
+ int rc = 0;
+ ibnd_node_t node_buf;
+ ibnd_port_t port_buf;
+ ibnd_node_t *remotenode, *oldnode;
+ ibnd_port_t *remoteport, *oldport;
memset(&node_buf, 0, sizeof(node_buf));
memset(&port_buf, 0, sizeof(port_buf));
- IBND_DEBUG("handle node %p port %p:%d dist %d\n", node, port, portnum, dist);
+ IBND_DEBUG("handle node %p port %p:%d dist %d\n", node, port, portnum,
+ dist);
- if (mad_get_field(port->port.info, 0, IB_PORT_PHYS_STATE_F)
- != IB_PORT_PHYS_STATE_LINKUP)
- return -1;
+ if (mad_get_field(port->info, 0, IB_PORT_PHYS_STATE_F)
+ != IB_PORT_PHYS_STATE_LINKUP)
+ return 1; /* positive == non-fatal error */
- if (extend_dpath(fabric, path, portnum) < 0)
+ if (extend_dpath(ibmad_port, fabric, path, portnum) < 0)
return -1;
- if (query_node(fabric, &node_buf, &port_buf, path)) {
- IBWARN("NodeInfo on %s failed, skipping port",
- portid2str(path));
- path->drpath.cnt--; /* restore path */
- return -1;
+ if (query_node(ibmad_port, fabric, &node_buf, &port_buf, path)) {
+ IBND_ERROR("Query remote node (%s) failed, skipping port\n",
+ portid2str(path));
+ retract_dpath(path);
+ return 1; /* positive == non-fatal error */
}
oldnode = find_existing_node(fabric, &node_buf);
if (oldnode)
remotenode = oldnode;
- else if (!(remotenode = create_node(fabric, &node_buf, path, dist + 1)))
- IBPANIC("no memory");
+ else if (!(remotenode = create_node(fabric, &node_buf, path, dist + 1))) {
+ rc = -1;
+ goto error;
+ }
oldport = find_existing_port_node(remotenode, &port_buf);
if (oldport) {
remoteport = oldport;
- } else if (!(remoteport = add_port_to_node(fabric, remotenode, &port_buf)))
- IBPANIC("no memory");
+ } else if (!(remoteport = add_port_to_node(fabric, remotenode,
+ &port_buf))) {
+ IBND_ERROR("OOM failed to add port to node\n");
+ rc = -1;
+ goto error;
+ }
dump_endnode(path, oldnode ? "known remote" : "new remote",
- remotenode, remoteport);
+ remotenode, remoteport);
link_ports(node, port, remotenode, remoteport);
- path->drpath.cnt--; /* restore path */
- return 0;
+error:
+ retract_dpath(path);
+ return (rc);
}
-ibnd_fabric_t *
-ibnd_discover_fabric(struct ibmad_port *ibmad_port, int timeout_ms,
- ib_portid_t *from, int hops)
+ibnd_fabric_t *ibnd_discover_fabric(struct ibmad_port * ibmad_port,
+ ib_portid_t * from, int hops)
{
- struct ibnd_fabric *fabric = NULL;
- ib_portid_t my_portid = {0};
- struct ibnd_node node_buf;
- struct ibnd_port port_buf;
- struct ibnd_node *node;
- struct ibnd_port *port;
+ int rc = 0;
+ ibnd_fabric_t *fabric = NULL;
+ ib_portid_t my_portid = { 0 };
+ ibnd_node_t node_buf;
+ ibnd_port_t port_buf;
+ ibnd_node_t *node;
+ ibnd_port_t *port;
int i;
int dist = 0;
ib_portid_t *path;
- int max_hops = MAXHOPS-1; /* default find everything */
+ int max_hops = MAXHOPS - 1; /* default find everything */
- if (!ibmad_port) {
- IBPANIC("ibmad_port must be specified to "
- "ibnd_discover_fabric\n");
- return (NULL);
- }
- if (mad_rpc_class_agent(ibmad_port, IB_SMI_CLASS) == -1
- ||
- mad_rpc_class_agent(ibmad_port, IB_SMI_DIRECT_CLASS) == -1) {
- IBPANIC("ibmad_port must be opened with "
- "IB_SMI_CLASS && IB_SMI_DIRECT_CLASS\n");
+ if (_check_ibmad_port(ibmad_port) < 0)
return (NULL);
- }
/* if not everything how much? */
if (hops >= 0) {
fabric = malloc(sizeof(*fabric));
if (!fabric) {
- IBPANIC("OOM: failed to malloc ibnd_fabric_t\n");
+ IBND_ERROR("OOM: failed to malloc ibnd_fabric_t\n");
return (NULL);
}
memset(fabric, 0, sizeof(*fabric));
- fabric->fabric.ibmad_port = ibmad_port;
-
IBND_DEBUG("from %s\n", portid2str(from));
memset(&node_buf, 0, sizeof(node_buf));
memset(&port_buf, 0, sizeof(port_buf));
- if (query_node(fabric, &node_buf, &port_buf, from)) {
- IBWARN("can't reach node %s\n", portid2str(from));
+ if (query_node(ibmad_port, fabric, &node_buf, &port_buf, from)) {
+ IBND_DEBUG("can't reach node %s\n", portid2str(from));
goto error;
}
if (!node)
goto error;
- fabric->fabric.from_node = (ibnd_node_t *)node;
+ fabric->from_node = (ibnd_node_t *) node;
port = add_port_to_node(fabric, node, &port_buf);
if (!port)
- IBPANIC("out of memory");
+ goto error;
- if(get_remote_node(fabric, node, port, from,
- mad_get_field(node->node.info, 0, IB_NODE_LOCAL_PORT_F),
- 0) < 0)
- return ((ibnd_fabric_t *)fabric);
+ if (node->type != IB_NODE_SWITCH) {
+ rc = get_remote_node(ibmad_port, fabric, node, port, from,
+ mad_get_field(node->info, 0,
+ IB_NODE_LOCAL_PORT_F), 0);
+ if (rc < 0)
+ goto error;
+ if (rc > 0) /* non-fatal error, nothing more to be done */
+ return ((ibnd_fabric_t *) fabric);
+ }
for (dist = 0; dist <= max_hops; dist++) {
for (node = fabric->nodesdist[dist]; node; node = node->dnext) {
- path = &node->node.path_portid;
+ path = &node->path_portid;
IBND_DEBUG("dist %d node %p\n", dist, node);
dump_endnode(path, "processing", node, port);
- for (i = 1; i <= node->node.numports; i++) {
- if (i == mad_get_field(node->node.info, 0,
- IB_NODE_LOCAL_PORT_F))
+ for (i = 1; i <= node->numports; i++) {
+ if (i == mad_get_field(node->info, 0,
+ IB_NODE_LOCAL_PORT_F))
continue;
- if (get_port_info(fabric, &port_buf, i, path)) {
- IBWARN("can't reach node %s port %d", portid2str(path), i);
+ if (get_port_info(ibmad_port, fabric,
+ &port_buf, i, path)) {
+ IBND_ERROR
+ ("can't reach node %s port %d\n",
+ portid2str(path), i);
continue;
}
if (port)
continue;
- port = add_port_to_node(fabric, node, &port_buf);
+ port =
+ add_port_to_node(fabric, node, &port_buf);
if (!port)
- IBPANIC("out of memory");
+ goto error;
/* If switch, set port GUID to node port GUID */
- if (node->node.type == IB_NODE_SWITCH) {
- port->port.guid = mad_get_field64(node->node.info,
- 0, IB_NODE_PORT_GUID_F);
+ if (node->type == IB_NODE_SWITCH) {
+ port->guid =
+ mad_get_field64(node->info, 0,
+ IB_NODE_PORT_GUID_F);
}
- get_remote_node(fabric, node, port, path, i, dist);
+ if (get_remote_node(ibmad_port, fabric, node,
+ port, path, i, dist) < 0)
+ goto error;
}
}
}
- fabric->fabric.chassis = group_nodes(fabric);
+ if (group_nodes(fabric))
+ goto error;
- return ((ibnd_fabric_t *)fabric);
+ return ((ibnd_fabric_t *) fabric);
error:
- free(fabric);
+ ibnd_destroy_fabric((ibnd_fabric_t *) fabric);
return (NULL);
}
-static void
-destroy_node(struct ibnd_node *node)
+static void destroy_node(ibnd_node_t * node)
{
int p = 0;
- for (p = 0; p <= node->node.numports; p++) {
- free(node->node.ports[p]);
+ for (p = 0; p <= node->numports; p++) {
+ free(node->ports[p]);
}
- free(node->node.ports);
+ free(node->ports);
free(node);
}
-void
-ibnd_destroy_fabric(ibnd_fabric_t *fabric)
+void ibnd_destroy_fabric(ibnd_fabric_t * fabric)
{
- struct ibnd_fabric *f = CONV_FABRIC_INTERNAL(fabric);
int dist = 0;
- struct ibnd_node *node = NULL;
- struct ibnd_node *next = NULL;
+ ibnd_node_t *node = NULL;
+ ibnd_node_t *next = NULL;
ibnd_chassis_t *ch, *ch_next;
- ch = f->first_chassis;
+ if (!fabric)
+ return;
+
+ ch = fabric->first_chassis;
while (ch) {
ch_next = ch->next;
free(ch);
ch = ch_next;
}
for (dist = 0; dist <= MAXHOPS; dist++) {
- node = f->nodesdist[dist];
+ node = fabric->nodesdist[dist];
while (node) {
next = node->dnext;
destroy_node(node);
node = next;
}
}
- free(f);
+ free(fabric);
}
-void
-ibnd_debug(int i)
+void ibnd_debug(int i)
{
if (i) {
ibdebug++;
}
}
-void
-ibnd_show_progress(int i)
+void ibnd_show_progress(int i)
{
show_progress = i;
}
-void
-ibnd_iter_nodes(ibnd_fabric_t *fabric,
- ibnd_iter_node_func_t func,
- void *user_data)
+void ibnd_iter_nodes(ibnd_fabric_t * fabric, ibnd_iter_node_func_t func,
+ void *user_data)
{
ibnd_node_t *cur = NULL;
+ if (!fabric) {
+ IBND_DEBUG("fabric parameter NULL\n");
+ return;
+ }
+
+ if (!func) {
+ IBND_DEBUG("func parameter NULL\n");
+ return;
+ }
+
for (cur = fabric->nodes; cur; cur = cur->next) {
func(cur, user_data);
}
}
-
-void
-ibnd_iter_nodes_type(ibnd_fabric_t *fabric,
- ibnd_iter_node_func_t func,
- int node_type,
- void *user_data)
+void ibnd_iter_nodes_type(ibnd_fabric_t * fabric, ibnd_iter_node_func_t func,
+ int node_type, void *user_data)
{
- struct ibnd_fabric *f = CONV_FABRIC_INTERNAL(fabric);
- struct ibnd_node *list = NULL;
- struct ibnd_node *cur = NULL;
+ ibnd_node_t *list = NULL;
+ ibnd_node_t *cur = NULL;
+
+ if (!fabric) {
+ IBND_DEBUG("fabric parameter NULL\n");
+ return;
+ }
+
+ if (!func) {
+ IBND_DEBUG("func parameter NULL\n");
+ return;
+ }
switch (node_type) {
- case IB_NODE_SWITCH:
- list = f->switches;
- break;
- case IB_NODE_CA:
- list = f->ch_adapters;
- break;
- case IB_NODE_ROUTER:
- list = f->routers;
- break;
- default:
- IBND_DEBUG("Invalid node_type specified %d\n", node_type);
- break;
+ case IB_NODE_SWITCH:
+ list = fabric->switches;
+ break;
+ case IB_NODE_CA:
+ list = fabric->ch_adapters;
+ break;
+ case IB_NODE_ROUTER:
+ list = fabric->routers;
+ break;
+ default:
+ IBND_DEBUG("Invalid node_type specified %d\n", node_type);
+ break;
}
for (cur = list; cur; cur = cur->type_next) {
- func((ibnd_node_t *)cur, user_data);
+ func((ibnd_node_t *) cur, user_data);
}
}
-