[openib-general] [PATCH 3/4] New routing module which loads LFT tables from dump file.

Eitan Zahavi eitan at mellanox.co.il
Tue Jun 13 04:30:37 PDT 2006


Hi Sasha,

Please see my comments inside

Sasha Khapyorsky wrote:
> This patch implements trivial routing module which able to load LFT
> tables from dump file. Main features:
> - support for unicast LFTs only, support for multicast can be added later
> - this will run after min hop matrix calculation
> - this will load switch LFTs according to the path entries introduced in
>   the dump file
> - no additional checks will be performed (like is port connected, etc)
> - in case when fabric LIDs were changed this will try to reconstruct LFTs
>   correctly if endport GUIDs are represented in the dump file (in order
>   to disable this GUIDs may be removed from the dump file or zeroed)
I think you cold use the concept of directed routes for storing the LIDs too.
So in case of new LID assignments you can extract the old -> new mapping by
scanning the LIDs of end ports by their DR path.
Anyway, I think it is required that you also perform topology matching such that
if someone changed the topology you are able to figure it out and stop.
THIS IS A SERIOUS LIMITATION OF YOUR PROPOSAL.
> 
> The dump file format is compatible with output of 'ibroute' util and for
> whole fabric may be generated with script like this:
> 
>   for sw_lid in `ibswitches | awk '{print $NF}'` ; do
> 	ibroute $sw_lid
>   done > /path/to/dump_file
> 
> , or using DR paths:
> 
> 
>   for sw_dr in `ibnetdiscover -v \
> 		| sed -ne '/^DR path .* switch /s/^DR path \[\(.*\)\].*$/\1/p' \
> 		| sed -e 's/\]\[/,/g' \
> 		| sort -u` ; do
> 	ibroute -D ${sw_dr}
>   done > /path/to/dump_file
WE SHOULD ALSO PROVIDE A DUMP FILE VIA:
1. OpenSM should dump its routes using this format (like it does today using osm.fdbs)
2. ibdiagnet
> 
> 
> 
> diff --git a/osm/include/opensm/osm_subnet.h b/osm/include/opensm/osm_subnet.h
> index a637367..ec1d056 100644
> --- a/osm/include/opensm/osm_subnet.h
> +++ b/osm/include/opensm/osm_subnet.h
> @@ -423,6 +424,10 @@ typedef struct _osm_subn_opt
>  *  routing_engine_name
>  *     Name of used routing engine (other than default Min Hop Algorithm)
>  *
> +*  ucast_dump_file
> +*     Name of the unicast routing dump file from where switch
> +*     forwearding tables will be loaded
          ^^^^^^^^^^^
          forwarding
> +*
>  *  updn_guid_file
>  *     Pointer to name of the UPDN guid file given by User
>  *
>  
> diff --git a/osm/opensm/osm_ucast_file.c b/osm/opensm/osm_ucast_file.c
> new file mode 100644
> index 0000000..a68d9ec
> --- /dev/null
> +++ b/osm/opensm/osm_ucast_file.c
> @@ -0,0 +1,258 @@
> +/*
> + * Copyright (c) 2006 Voltaire, Inc. All rights reserved.
> + *
> + * This software is available to you under a choice of one of two
> + * licenses.  You may choose to be licensed under the terms of the GNU
> + * General Public License (GPL) Version 2, available from the file
> + * COPYING in the main directory of this source tree, or the
> + * OpenIB.org BSD license below:
> + *
> + *     Redistribution and use in source and binary forms, with or
> + *     without modification, are permitted provided that the following
> + *     conditions are met:
> + *
> + *      - Redistributions of source code must retain the above
> + *        copyright notice, this list of conditions and the following
> + *        disclaimer.
> + *
> + *      - Redistributions in binary form must reproduce the above
> + *        copyright notice, this list of conditions and the following
> + *        disclaimer in the documentation and/or other materials
> + *        provided with the distribution.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
> + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
> + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
> + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
> + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> + * SOFTWARE.
> + *
> + * $Id$
> + */
> +
> +/*
> + * Abstract:
> + *    Implementation of OpenSM unicast routing module which loads
> + *    routes from the dump file
> + *
> + * Environment:
> + *    Linux User Mode
> + *
> + */
> +
> +#if HAVE_CONFIG_H
> +#  include <config.h>
> +#endif				/* HAVE_CONFIG_H */
> +
> +#include <stdlib.h>
> +#include <string.h>
> +#include <ctype.h>
> +
> +#include <iba/ib_types.h>
> +#include <complib/cl_qmap.h>
> +#include <opensm/osm_opensm.h>
> +#include <opensm/osm_switch.h>
> +#include <opensm/osm_log.h>
> +
> +#define PARSEERR(log, file_name, lineno, fmt, arg...) \
> +		osm_log(log, OSM_LOG_ERROR, "PARSE ERROR: %s:%u: " fmt , \
> +			file_name, lineno, ##arg )
> +
> +#define PARSEWARN(log, file_name, lineno, fmt, arg...) \
> +		osm_log(log, OSM_LOG_VERBOSE, "PARSE WARN: %s:%u: " fmt , \
> +			file_name, lineno, ##arg )
> +
> +static uint16_t remap_lid(osm_opensm_t *p_osm, uint16_t lid, ib_net64_t guid)
> +{
> +	osm_port_t *p_port;
> +	uint16_t min_lid, max_lid;
> +	uint8_t lmc;
> +
> +	p_port = (osm_port_t *)cl_qmap_get(&p_osm->subn.port_guid_tbl, guid);
> +	if (!p_port ||
> +	    p_port == (osm_port_t *)cl_qmap_end(&p_osm->subn.port_guid_tbl)) {
> +		osm_log(&p_osm->log, OSM_LOG_VERBOSE,
> +			"remap_lid: cannot find port guid 0x%016" PRIx64
> +			" , will use the same lid.\n", cl_ntoh64(guid));
> +		return lid;
> +	}
> +
> +	osm_port_get_lid_range_ho(p_port, &min_lid, &max_lid);
> +	if (min_lid <= lid && lid <= max_lid)
> +		return lid;
> +
> +	lmc = osm_port_get_lmc(p_port);
> +	return min_lid + (lid & ((1 << lmc) - 1));
> +}
> +
> +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_fwd_tbl_get(osm_switch_get_fwd_tbl_ptr(p_sw), new_lid);
> +	if (old_port != OSM_NO_PATH && old_port != port_num) {
> +		osm_log(&p_osm->log, OSM_LOG_VERBOSE,
> +			"add_path: LID collision is detected on switch "
> +			"0x016%" PRIx64 ", will overwrite LID 0x%x entry.\n",
> +			cl_ntoh64(osm_node_get_node_guid
> +				  (osm_switch_get_node_ptr(p_sw))), new_lid);
> +	}
> +
> +	osm_switch_set_path(p_sw, new_lid, port_num, TRUE);
> +
> +	osm_log(&p_osm->log, OSM_LOG_DEBUG,
> +		"add_path: 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
> +			  (osm_switch_get_node_ptr(p_sw))));
> +}
> +
> +static void clean_sw_fwd_table(void *arg, void *context)
> +{
> +	osm_switch_t *p_sw = arg;
> +	uint16_t lid, max_lid;
> +
> +	max_lid = osm_switch_get_max_lid_ho(p_sw);
> +	for (lid = 1 ; lid <= max_lid ; lid++)
> +		osm_switch_set_path(p_sw, lid, OSM_NO_PATH, TRUE);
> +}
> +
> +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.ucast_dump_file;
> +
> +	if (!file_name) {
> +		osm_log(&p_osm->log, OSM_LOG_ERROR,
> +			"do_ucast_file_load: "
> +			"ucast dump file name is not defined.\n");
> +		return -1;
> +	}
> +
> +	file = fopen(file_name, "r");
> +	if (!file) {
> +		osm_log(&p_osm->log, OSM_LOG_ERROR,
> +			"do_ucast_file_load: "
> +			"cannot open ucast dump file \'%s\'\n", file_name);
> +		return -1;
> +	}
> +
> +	cl_qmap_apply_func(&p_osm->subn.sw_guid_tbl, clean_sw_fwd_table, NULL);
> +
> +	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,
> +				"do_ucast_file_load: "
> +				"Multicast dump file is detected. "
> +				"Skip parsing.\n");
> +		}
> +		else if (!strncmp(p, "Unicast lids", 12)) {
> +			q = strstr(p, " guid 0x");
> +			if (!q) {
> +				PARSEERR(&p_osm->log, file_name, lineno,
> +					 "cannot parse switch definition\n");
> +				return -1;
> +			}
> +			p = q + 6;
> +			sw_guid = strtoll(p, &q, 16);
> +			if (q && !isspace(*q)) {
> +				PARSEERR(&p_osm->log, file_name, lineno,
> +					 "cannot parse switch guid: \'%s\'\n",
> +					 p);
> +				return -1;
> +			}
> +			sw_guid = cl_hton64(sw_guid);
> +
> +			p_sw = (osm_switch_t *)cl_qmap_get(&p_osm->subn.sw_guid_tbl,
> +							   sw_guid);
> +			if (!p_sw ||
> +			    p_sw == (osm_switch_t *)cl_qmap_end(&p_osm->subn.sw_guid_tbl)) {
> +				p_sw = NULL;
> +				osm_log(&p_osm->log, OSM_LOG_VERBOSE,
> +					"do_ucast_file_load: "
> +					"cannot find switch %016" PRIx64 ".\n",
> +					cl_ntoh64(sw_guid));
> +				continue;
> +			}
> +		}
> +		else if (p_sw && !strncmp(p, "0x", 2)) {
> +			lid = strtoul(p, &q, 16);
> +			if (q && !isspace(*q)) {
> +				PARSEERR(&p_osm->log, file_name, lineno,
> +					 "cannot parse lid: \'%s\'\n", p);
> +				return -1;
> +			}
> +			p = q;
> +			while (isspace(*p))
> +				p++;
> +			port_num = strtoul(p, &q, 10);
> +			if (q && !isspace(*q)) {
> +				PARSEERR(&p_osm->log, file_name, lineno,
> +					 "cannot parse port: \'%s\'\n", p);
> +				return -1;
> +			}
> +			p = q;
> +			/* additionally try to exract guid */
> +			q = strstr(p, " portguid 0x");
> +			if (!q) {
> +				PARSEWARN(&p_osm->log, file_name, lineno,
> +					  "cannot find port guid "
> +					  "(maybe broken dump): \'%s\'\n", p);
> +				port_guid = 0;
> +			}
> +			else {
> +				p = q + 10;
> +				port_guid = strtoll(p, &q, 16);
> +				if (!q && !isspace(*q) && *q != ':') {
> +					PARSEWARN(&p_osm->log, file_name,
> +						  lineno,
> +						  "cannot parse port guid "
> +						  "(maybe broken dump): "
> +						  "\'%s\'\n", p);
> +					port_guid = 0;
> +				}
> +			}
> +			port_guid = cl_hton64(port_guid);
> +			add_path(p_osm, p_sw, lid, port_num, port_guid);
> +		}
> +	}
> +
> +	fclose(file);
> +	return 0;
> +}
In OpenSM we write with style:
if () {
}
else if ()
{
}
else
{
}

Not any other combination
> +
> +int osm_ucast_file_setup(osm_opensm_t * p_osm)
> +{
> +	p_osm->routing_engine.context = (void *)p_osm;
> +	p_osm->routing_engine.ucast_build_fwd_tables = do_ucast_file_load;
> +	return 0;
> +}





More information about the general mailing list