Beispiel #1
0
/*
	This function called for every Voltaire node in fabric
	It could be optimized so, but time overhead is very small
	and its only diag.util
*/
static void fill_chassis_record(Node *node)
{
	Port *port;
	Node *remnode = 0;
	ChassisRecord *ch = 0;

	if (node->chrecord) /* somehow this node has already been passed */
		return;

	if (!(node->chrecord = calloc(1, sizeof(ChassisRecord))))
		IBPANIC("out of mem");

	ch = node->chrecord;

	/* node is router only in case of using unique lid */
	/* (which is lid of chassis router port) */
	/* in such case node->ports is actually a requested port... */
	if (is_router(node) && is_spine(node->ports->remoteport->node))
		get_router_slot(node, node->ports->remoteport);
	else if (is_spine(node)) {
		for (port = node->ports; port; port = port->next) {
			if (!port->remoteport)
				continue;
			remnode = port->remoteport->node;
			if (remnode->type != SWITCH_NODE) {
				if (!remnode->chrecord)
					get_router_slot(remnode, port);
				continue;
			}
			if (!ch->chassistype)
				/* we assume here that remoteport belongs to line */
				get_sfb_slot(node, port->remoteport);

				/* we could break here, but need to find if more routers connected */
		}

	} else if (is_line(node)) {
		for (port = node->ports; port; port = port->next) {
			if (port->portnum > 12)
				continue;
			if (!port->remoteport)
				continue;
			/* we assume here that remoteport belongs to spine */
			get_slb_slot(ch, port->remoteport);
			break;
		}
	}

	return;
}
Beispiel #2
0
/*
	This function called for every Voltaire node in fabric
	It could be optimized so, but time overhead is very small
	and its only diag.util
*/
static int fill_voltaire_chassis_record(ibnd_node_t * node)
{
	int p = 0;
	ibnd_port_t *port;
	ibnd_node_t *remnode = 0;

	if (node->ch_found)	/* somehow this node has already been passed */
		return 0;
	node->ch_found = 1;

	/* node is router only in case of using unique lid */
	/* (which is lid of chassis router port) */
	/* in such case node->ports is actually a requested port... */
	if (is_router(node))
		/* find the remote node */
		for (p = 1; p <= node->numports; p++) {
			port = node->ports[p];
			if (port && is_spine(port->remoteport->node))
				get_router_slot(node, port->remoteport);
		}
	else if (is_spine(node)) {
		int is_4700x2 = is_spine_4700x2(node);

		for (p = 1; p <= node->numports; p++) {
			port = node->ports[p];
			if (!port || !port->remoteport)
				continue;

			/*
			 * Skip ISR4700 double density fabric boards ports 19-36
			 * as they are chassis external ports
			 */
			if (is_4700x2 && (port->portnum > 18))
				continue;

			remnode = port->remoteport->node;
			if (remnode->type != IB_NODE_SWITCH) {
				if (!remnode->ch_found)
					get_router_slot(remnode, port);
				continue;
			}
			if (!node->ch_type)
				/* we assume here that remoteport belongs to line */
				get_sfb_slot(node, port->remoteport);

			/* we could break here, but need to find if more routers connected */
		}

	} else if (is_line(node)) {
		int is_4700_line = is_line_4700(node);

		for (p = 1; p <= node->numports; p++) {
			port = node->ports[p];
			if (!port || !port->remoteport)
				continue;

			if ((is_4700_line && (port->portnum > 18)) ||
			    (!is_4700_line && (port->portnum > 12)))
				continue;

			/* we assume here that remoteport belongs to spine */
			get_slb_slot(node, port->remoteport);
			break;
		}
	}

	/* for each port of this node, map external ports */
	for (p = 1; p <= node->numports; p++) {
		port = node->ports[p];
		if (!port)
			continue;
		voltaire_portmap(port);
	}

	return 0;
}
Beispiel #3
0
int is_chassis_switch(ibnd_node_t * n)
{
	return (is_spine(n) || is_line(n));
}
Beispiel #4
0
/*
	Main grouping function
	Algorithm:
	1. pass on every Voltaire node
	2. catch spine chip for every Voltaire node
		2.1 build/interpolate chassis around this chip
		2.2 go to 1.
	3. pass on non Voltaire nodes (SystemImageGUID based grouping)
	4. now group non Voltaire nodes by SystemImageGUID
	Returns:
	0 on success, -1 on failure
*/
int group_nodes(ibnd_fabric_t * fabric)
{
	ibnd_node_t *node;
	int chassisnum = 0;
	ibnd_chassis_t *chassis;
	ibnd_chassis_t *ch, *ch_next;
	chassis_scan_t chassis_scan;
	int vendor_id;

	chassis_scan.first_chassis = NULL;
	chassis_scan.current_chassis = NULL;
	chassis_scan.last_chassis = NULL;

	/* first pass on switches and build for every Voltaire node */
	/* an appropriate chassis record (slotnum and position) */
	/* according to internal connectivity */
	/* not very efficient but clear code so... */
	for (node = fabric->switches; node; node = node->type_next) {

		vendor_id = mad_get_field(node->info, 0,IB_NODE_VENDORID_F);

		if (vendor_id == VTR_VENDOR_ID
		    && fill_voltaire_chassis_record(node))
			goto cleanup;
		else if (vendor_id == MLX_VENDOR_ID
			&& fill_mellanox_chassis_record(node))
			goto cleanup;

	}

	/* separate every Voltaire chassis from each other and build linked list of them */
	/* algorithm: catch spine and find all surrounding nodes */
	for (node = fabric->switches; node; node = node->type_next) {
		if (mad_get_field(node->info, 0,
				  IB_NODE_VENDORID_F) != VTR_VENDOR_ID)
			continue;
		if (!node->ch_found
		    || (node->chassis && node->chassis->chassisnum)
		    || !is_spine(node))
			continue;
		if (add_chassis(&chassis_scan))
			goto cleanup;
		chassis_scan.current_chassis->chassisnum = ++chassisnum;
		if (build_chassis(node, chassis_scan.current_chassis))
			goto cleanup;
	}

	/* now make pass on nodes for chassis which are not Voltaire */
	/* grouped by common SystemImageGUID */
	for (node = fabric->nodes; node; node = node->next) {
		if (mad_get_field(node->info, 0,
				  IB_NODE_VENDORID_F) == VTR_VENDOR_ID)
			continue;
		if (mad_get_field64(node->info, 0, IB_NODE_SYSTEM_GUID_F)) {
			chassis = find_chassisguid(fabric, node);
			if (chassis)
				chassis->nodecount++;
			else {
				/* Possible new chassis */
				if (add_chassis(&chassis_scan))
					goto cleanup;
				chassis_scan.current_chassis->chassisguid =
				    get_chassisguid(node);
				chassis_scan.current_chassis->nodecount = 1;
				if (!fabric->chassis)
					fabric->chassis = chassis_scan.first_chassis;
			}
		}
	}

	/* now, make another pass to see which nodes are part of chassis */
	/* (defined as chassis->nodecount > 1) */
	for (node = fabric->nodes; node; node = node->next) {

		vendor_id = mad_get_field(node->info, 0,IB_NODE_VENDORID_F);

		if (vendor_id == VTR_VENDOR_ID)
			continue;
		if (mad_get_field64(node->info, 0, IB_NODE_SYSTEM_GUID_F)) {
			chassis = find_chassisguid(fabric, node);
			if (chassis && chassis->nodecount > 1) {
				if (!chassis->chassisnum)
					chassis->chassisnum = ++chassisnum;
				if (!node->ch_found) {
					node->ch_found = 1;
					add_node_to_chassis(chassis, node);
				}
				else if (vendor_id == MLX_VENDOR_ID){
					insert_mellanox_line_and_spine(node, chassis);
				}
			}
		}
	}

	fabric->chassis = chassis_scan.first_chassis;
	return 0;

cleanup:
	ch = chassis_scan.first_chassis;
	while (ch) {
		ch_next = ch->next;
		free(ch);
		ch = ch_next;
	}
	fabric->chassis = NULL;
	return -1;
}
Beispiel #5
0
/*
	Main grouping function
	Algorithm:
	1. pass on every Voltaire node
	2. catch spine chip for every Voltaire node
		2.1 build/interpolate chassis around this chip
		2.2 go to 1.
	3. pass on non Voltaire nodes (SystemImageGUID based grouping)
	4. now group non Voltaire nodes by SystemImageGUID
*/
ChassisList *group_nodes()
{
	Node *node;
	int dist;
	int chassisnum = 0;
	struct ChassisList *chassis;

	mylist.first = NULL;
	mylist.current = NULL;
	mylist.last = NULL;

	/* first pass on switches and build for every Voltaire node */
	/* an appropriate chassis record (slotnum and position) */
	/* according to internal connectivity */
	/* not very efficient but clear code so... */
	for (dist = 0; dist <= maxhops_discovered; dist++) {
		for (node = nodesdist[dist]; node; node = node->dnext) {
			if (node->vendid == VTR_VENDOR_ID)
				fill_chassis_record(node);
		}
	}

	/* separate every Voltaire chassis from each other and build linked list of them */
	/* algorithm: catch spine and find all surrounding nodes */
	for (dist = 0; dist <= maxhops_discovered; dist++) {
		for (node = nodesdist[dist]; node; node = node->dnext) {
			if (node->vendid != VTR_VENDOR_ID)
				continue;
			if (!node->chrecord || node->chrecord->chassisnum || !is_spine(node))
				continue;
			add_chassislist();
			mylist.current->chassisnum = ++chassisnum;
			build_chassis(node, mylist.current);
		}
	}

	/* now make pass on nodes for chassis which are not Voltaire */
	/* grouped by common SystemImageGUID */
	for (dist = 0; dist <= maxhops_discovered; dist++) {
		for (node = nodesdist[dist]; node; node = node->dnext) {
			if (node->vendid == VTR_VENDOR_ID)
				continue;
			if (node->sysimgguid) {
				chassis = find_chassisguid(node);
				if (chassis)
					chassis->nodecount++;
				else {
					/* Possible new chassis */
					add_chassislist();
					mylist.current->chassisguid = get_chassisguid(node);
					mylist.current->nodecount = 1;
				}
			}
		}
	}

	/* now, make another pass to see which nodes are part of chassis */
	/* (defined as chassis->nodecount > 1) */
	for (dist = 0; dist <= MAXHOPS; ) {
		for (node = nodesdist[dist]; node; node = node->dnext) {
			if (node->vendid == VTR_VENDOR_ID)
				continue;
			if (node->sysimgguid) {
				chassis = find_chassisguid(node);
				if (chassis && chassis->nodecount > 1) {
					if (!chassis->chassisnum)
						chassis->chassisnum = ++chassisnum;
					if (!node->chrecord) {
						if (!(node->chrecord = calloc(1, sizeof(ChassisRecord))))
							IBPANIC("out of mem");
						node->chrecord->chassisnum = chassis->chassisnum;
					}
				}
			}
		}
		if (dist == maxhops_discovered)
			dist = MAXHOPS;	/* skip to CAs */
		else
			dist++;
	}

	return (mylist.first);
}
Beispiel #6
0
int is_chassis_switch(Node *node)
{
    return (is_spine(node) || is_line(node));
}