Пример #1
0
static void add_path(osm_opensm_t * p_osm,
		     osm_switch_t * p_sw, uint16_t lid, uint8_t port_num,
		     ib_net64_t port_guid)
{
	uint16_t new_lid;
	uint8_t old_port;

	new_lid = port_guid ? remap_lid(p_osm, lid, port_guid) : lid;
	old_port = osm_switch_get_port_by_lid(p_sw, new_lid);
	if (old_port != OSM_NO_PATH && old_port != port_num) {
		OSM_LOG(&p_osm->log, OSM_LOG_VERBOSE,
			"LID collision is detected on switch "
			"0x016%" PRIx64 ", will overwrite LID %u entry\n",
			cl_ntoh64(osm_node_get_node_guid(p_sw->p_node)),
			new_lid);
	}

	p_sw->new_lft[new_lid] = port_num;
	if (!(p_osm->subn.opt.port_profile_switch_nodes && port_guid &&
	      osm_get_switch_by_guid(&p_osm->subn, port_guid)))
		osm_switch_count_path(p_sw, port_num);

	OSM_LOG(&p_osm->log, OSM_LOG_DEBUG,
		"route 0x%04x(was 0x%04x) %u 0x%016" PRIx64
		" is added to switch 0x%016" PRIx64 "\n",
		new_lid, lid, port_num, cl_ntoh64(port_guid),
		cl_ntoh64(osm_node_get_node_guid(p_sw->p_node)));
}
Пример #2
0
static int update_id(void *cxt, uint64_t guid, char *p)
{
	osm_opensm_t *osm = cxt;
	osm_switch_t *sw;
	uint64_t id;
	char *e;

	sw = osm_get_switch_by_guid(&osm->subn, cl_hton64(guid));
	if (!sw) {
		OSM_LOG(&osm->log, OSM_LOG_VERBOSE,
			"switch with guid 0x%" PRIx64 " is not found\n", guid);
		return 0;
	}

	id = strtoull(p, &e, 0);
	if (*e && !isspace(*e)) {
		OSM_LOG(&osm->log, OSM_LOG_ERROR,
			"ERR AA05: cannot parse node id \'%s\'", p);
		return -1;
	}

	OSM_LOG(&osm->log, OSM_LOG_DEBUG,
		"update node 0x%" PRIx64 " id to 0x%" PRIx64 "\n", guid, id);

	((struct updn_node *)sw->priv)->id = id;

	return 0;
}
Пример #3
0
void osm_lft_rcv_process(IN void *context, IN void *data)
{
	osm_sm_t *sm = context;
	osm_madw_t *p_madw = data;
	ib_smp_t *p_smp;
	uint32_t block_num;
	osm_switch_t *p_sw;
	osm_lft_context_t *p_lft_context;
	uint8_t *p_block;
	ib_net64_t node_guid;
	ib_api_status_t status;

	CL_ASSERT(sm);

	OSM_LOG_ENTER(sm->p_log);

	CL_ASSERT(p_madw);

	p_smp = osm_madw_get_smp_ptr(p_madw);
	p_block = ib_smp_get_payload_ptr(p_smp);
	block_num = cl_ntoh32(p_smp->attr_mod);

	/*
	   Acquire the switch object for this switch.
	 */
	p_lft_context = osm_madw_get_lft_context_ptr(p_madw);
	node_guid = p_lft_context->node_guid;

	CL_PLOCK_EXCL_ACQUIRE(sm->p_lock);
	p_sw = osm_get_switch_by_guid(sm->p_subn, node_guid);

	if (!p_sw) {
		OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0401: "
			"LFT received for nonexistent node "
			"0x%" PRIx64 "\n", cl_ntoh64(node_guid));
	} else {
		status = osm_switch_set_lft_block(p_sw, p_block, block_num);
		if (status != IB_SUCCESS) {
			OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0402: "
				"Setting forwarding table block failed (%s)"
				", Switch 0x%" PRIx64 " %s\n",
				ib_get_err_str(status), cl_ntoh64(node_guid),
				p_sw->p_node->print_desc);
		}
	}

	CL_PLOCK_RELEASE(sm->p_lock);
	OSM_LOG_EXIT(sm->p_log);
}
Пример #4
0
static int rank_root_node(void *cxt, uint64_t guid, char *p)
{
	updn_t *updn = cxt;
	osm_switch_t *sw;

	sw = osm_get_switch_by_guid(&updn->p_osm->subn, cl_hton64(guid));
	if (!sw) {
		OSM_LOG(&updn->p_osm->log, OSM_LOG_VERBOSE,
			"switch with guid 0x%" PRIx64 " is not found\n", guid);
		return 0;
	}

	OSM_LOG(&updn->p_osm->log, OSM_LOG_DEBUG,
		"Ranking root port GUID 0x%" PRIx64 "\n", guid);

	((struct updn_node *)sw->priv)->rank = 0;
	updn->num_roots++;

	return 0;
}
Пример #5
0
static int do_lid_matrix_file_load(void *context)
{
	char line[1024];
	uint8_t hops[256];
	char *file_name;
	FILE *file;
	ib_net64_t guid;
	osm_opensm_t *p_osm = context;
	osm_switch_t *p_sw;
	unsigned lineno;
	uint16_t lid;

	file_name = p_osm->subn.opt.lid_matrix_dump_file;
	if (!file_name) {
		OSM_LOG(&p_osm->log, OSM_LOG_VERBOSE,
			"lid matrix file name is not given; "
			"using default lid matrix generation algorithm\n");
		return 1;
	}

	file = fopen(file_name, "r");
	if (!file) {
		OSM_LOG(&p_osm->log, OSM_LOG_ERROR | OSM_LOG_SYS, "ERR 6305: "
			"cannot open lid matrix file \'%s\': %m\n", file_name);
		return -1;
	}

	lineno = 0;
	p_sw = NULL;

	while (fgets(line, sizeof(line) - 1, file) != NULL) {
		char *p, *q;
		lineno++;

		p = line;
		while (isspace(*p))
			p++;

		if (*p == '#')
			continue;

		if (!strncmp(p, "Switch", 6)) {
			q = strstr(p, " guid 0x");
			if (!q) {
				OSM_LOG(&p_osm->log, OSM_LOG_ERROR,
					"PARSE ERROR: %s:%u: "
					"cannot parse switch definition\n",
					file_name, lineno);
				return -1;
			}
			p = q + 8;
			guid = strtoull(p, &q, 16);
			if (q == p || !isspace(*q)) {
				OSM_LOG(&p_osm->log, OSM_LOG_ERROR,
					"PARSE ERROR: %s:%u: "
					"cannot parse switch guid: \'%s\'\n",
					file_name, lineno, p);
				return -1;
			}
			guid = cl_hton64(guid);

			p_sw = osm_get_switch_by_guid(&p_osm->subn, guid);
			if (!p_sw) {
				OSM_LOG(&p_osm->log, OSM_LOG_VERBOSE,
					"cannot find switch %016" PRIx64 "\n",
					cl_ntoh64(guid));
				continue;
			}
		} else if (p_sw && !strncmp(p, "0x", 2)) {
			unsigned long num;
			unsigned len = 0;

			memset(hops, 0xff, sizeof(hops));

			p += 2;
			num = strtoul(p, &q, 16);
			if (num > 0xffff || q == p ||
			    (*q != ':' && !isspace(*q))) {
				OSM_LOG(&p_osm->log, OSM_LOG_ERROR,
					"PARSE ERROR: %s:%u: "
					"cannot parse lid: \'%s\'\n",
					file_name, lineno, p);
				return -1;
			}
			/* Just checked the range, so casting is safe */
			lid = (uint16_t) num;
			p = q;
			while (isspace(*p) || *p == ':')
				p++;
			while (len < 256 && *p && *p != '#') {
				num = strtoul(p, &q, 16);
				if (num > 0xff || q == p) {
					OSM_LOG(&p_osm->log, OSM_LOG_ERROR,
						"PARSE ERROR: %s:%u: "
						"cannot parse hops number: \'%s\'\n",
						file_name, lineno, p);
					return -1;
				}
				/* Just checked the range, so casting is safe */
				hops[len++] = (uint8_t) num;
				p = q;
				while (isspace(*p))
					p++;
			}
			/* additionally try to extract guid */
			q = strstr(p, " portguid 0x");
			if (!q) {
				OSM_LOG(&p_osm->log, OSM_LOG_VERBOSE,
					"PARSE WARNING: %s:%u: "
					"cannot find port guid "
					"(maybe broken dump): \'%s\'\n",
					file_name, lineno, p);
				guid = 0;
			} else {
				p = q + 12;
				guid = strtoull(p, &q, 16);
				if (q == p || !isspace(*q)) {
					OSM_LOG(&p_osm->log, OSM_LOG_VERBOSE,
						"PARSE WARNING: %s:%u: "
						"cannot parse port guid "
						"(maybe broken dump): \'%s\'\n",
						file_name, lineno, p);
					guid = 0;
				}
			}
			guid = cl_hton64(guid);
			add_lid_hops(p_osm, p_sw, lid, guid, hops, len);
		}
	}

	fclose(file);
	return 0;
}
Пример #6
0
static int do_ucast_file_load(void *context)
{
	char line[1024];
	char *file_name;
	FILE *file;
	ib_net64_t sw_guid, port_guid;
	osm_opensm_t *p_osm = context;
	osm_switch_t *p_sw;
	uint16_t lid;
	uint8_t port_num;
	unsigned lineno;

	file_name = p_osm->subn.opt.lfts_file;
	if (!file_name) {
		OSM_LOG(&p_osm->log, OSM_LOG_VERBOSE,
			"LFTs file name is not given; "
			"using default routing algorithm\n");
		return 1;
	}

	file = fopen(file_name, "r");
	if (!file) {
		OSM_LOG(&p_osm->log, OSM_LOG_ERROR | OSM_LOG_SYS, "ERR 6302: "
			"cannot open ucast dump file \'%s\': %m\n", file_name);
		return -1;
	}

	lineno = 0;
	p_sw = NULL;

	while (fgets(line, sizeof(line) - 1, file) != NULL) {
		char *p, *q;
		lineno++;

		p = line;
		while (isspace(*p))
			p++;

		if (*p == '#')
			continue;

		if (!strncmp(p, "Multicast mlids", 15)) {
			OSM_LOG(&p_osm->log, OSM_LOG_ERROR | OSM_LOG_SYS,
				"ERR 6303: "
				"Multicast dump file detected; "
				"skipping parsing. Using default "
				"routing algorithm\n");
		} else if (!strncmp(p, "Unicast lids", 12)) {
			if (p_sw)
				osm_ucast_mgr_set_fwd_table(&p_osm->sm.
							    ucast_mgr, p_sw);
			q = strstr(p, " guid 0x");
			if (!q) {
				OSM_LOG(&p_osm->log, OSM_LOG_ERROR,
					"PARSE ERROR: %s:%u: "
					"cannot parse switch definition\n",
					file_name, lineno);
				return -1;
			}
			p = q + 8;
			sw_guid = strtoull(p, &q, 16);
			if (q == p || !isspace(*q)) {
				OSM_LOG(&p_osm->log, OSM_LOG_ERROR,
					"PARSE ERROR: %s:%u: "
					"cannot parse switch guid: \'%s\'\n",
					file_name, lineno, p);
				return -1;
			}
			sw_guid = cl_hton64(sw_guid);

			p_sw = osm_get_switch_by_guid(&p_osm->subn, sw_guid);
			if (!p_sw) {
				OSM_LOG(&p_osm->log, OSM_LOG_VERBOSE,
					"cannot find switch %016" PRIx64 "\n",
					cl_ntoh64(sw_guid));
				continue;
			}
			memset(p_sw->new_lft, OSM_NO_PATH,
			       IB_LID_UCAST_END_HO + 1);
		} else if (p_sw && !strncmp(p, "0x", 2)) {
			p += 2;
			lid = (uint16_t) strtoul(p, &q, 16);
			if (q == p || !isspace(*q)) {
				OSM_LOG(&p_osm->log, OSM_LOG_ERROR,
					"PARSE ERROR: %s:%u: "
					"cannot parse lid: \'%s\'\n",
					file_name, lineno, p);
				return -1;
			}
			p = q;
			while (isspace(*p))
				p++;
			port_num = (uint8_t) strtoul(p, &q, 10);
			if (q == p || !isspace(*q)) {
				OSM_LOG(&p_osm->log, OSM_LOG_ERROR,
					"PARSE ERROR: %s:%u: "
					"cannot parse port: \'%s\'\n",
					file_name, lineno, p);
				return -1;
			}
			p = q;
			/* additionally try to exract guid */
			q = strstr(p, " portguid 0x");
			if (!q) {
				OSM_LOG(&p_osm->log, OSM_LOG_VERBOSE,
					"PARSE WARNING: %s:%u: "
					"cannot find port guid "
					"(maybe broken dump): \'%s\'\n",
					file_name, lineno, p);
				port_guid = 0;
			} else {
				p = q + 12;
				port_guid = strtoull(p, &q, 16);
				if (q == p || (!isspace(*q) && *q != ':')) {
					OSM_LOG(&p_osm->log, OSM_LOG_VERBOSE,
						"PARSE WARNING: %s:%u: "
						"cannot parse port guid "
						"(maybe broken dump): \'%s\'\n",
						file_name, lineno, p);
					port_guid = 0;
				}
			}
			port_guid = cl_hton64(port_guid);
			add_path(p_osm, p_sw, lid, port_num, port_guid);
		}
	}

	if (p_sw)
		osm_ucast_mgr_set_fwd_table(&p_osm->sm.ucast_mgr, p_sw);

	fclose(file);
	return 0;
}