[openib-general] [PATCH] OpenSM/osm_sa_path_record.c: Initial support for off subnet PathRecords
Hal Rosenstock
halr at voltaire.com
Fri Jan 12 08:50:54 PST 2007
OpenSM/osm_sa_path_record.c: Initial support for off subnet PathRecords
Off subnet PathRecords for both the unicast and multicast DGID cases are
supported. HopLimit is set to maximum (0xFF). In the case of a unicast
DGID request, the LID of the "first" router found on the subnet is used
for the DLID. I think this is sufficient to get started.
Signed-off-by: Hal Rosenstock <halr at voltaire.com>
diff --git a/osm/opensm/osm_sa_path_record.c b/osm/opensm/osm_sa_path_record.c
index 0c5d4a9..c43ad31 100644
--- a/osm/opensm/osm_sa_path_record.c
+++ b/osm/opensm/osm_sa_path_record.c
@@ -66,6 +66,10 @@
#include <opensm/osm_pkey.h>
#include <opensm/osm_multicast.h>
#include <opensm/osm_partition.h>
+#ifdef ROUTER_EXP
+#include <opensm/osm_router.h>
+#include <opensm/osm_sa_mcmember_record.h>
+#endif
#define OSM_PR_RCV_POOL_MIN_SIZE 64
#define OSM_PR_RCV_POOL_GROW_SIZE 64
@@ -93,6 +97,11 @@ typedef struct osm_sa_pr_mcmr_search_
osm_pr_rcv_t *p_rcv;
} osm_sa_pr_mcmr_search_ctxt_t;
+static const ib_gid_t zero_gid = { { 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00 }, };
+
/**********************************************************************
**********************************************************************/
void
@@ -712,6 +721,7 @@ __osm_pr_rcv_build_pr(
IN osm_pr_rcv_t* const p_rcv,
IN const osm_port_t* const p_src_port,
IN const osm_port_t* const p_dest_port,
+ IN const ib_gid_t* const p_dgid,
IN const uint16_t src_lid_ho,
IN const uint16_t dest_lid_ho,
IN const uint8_t preference,
@@ -720,14 +730,33 @@ __osm_pr_rcv_build_pr(
{
const osm_physp_t* p_src_physp;
const osm_physp_t* p_dest_physp;
+ boolean_t is_nonzero_gid = 0;
OSM_LOG_ENTER( p_rcv->p_log, __osm_pr_rcv_build_pr );
p_src_physp = osm_port_get_default_phys_ptr( p_src_port );
+#ifndef ROUTER_EXP
p_dest_physp = osm_port_get_default_phys_ptr( p_dest_port );
p_pr->dgid.unicast.prefix = osm_physp_get_subnet_prefix( p_dest_physp );
p_pr->dgid.unicast.interface_id = osm_physp_get_port_guid( p_dest_physp );
+#else
+ if ( p_dgid)
+ {
+ if ( memcmp( p_dgid, &zero_gid, sizeof(*p_dgid) ) )
+ is_nonzero_gid = 1;
+ }
+
+ if ( is_nonzero_gid )
+ p_pr->dgid = *p_dgid;
+ else
+ {
+ p_dest_physp = osm_port_get_default_phys_ptr( p_dest_port );
+
+ p_pr->dgid.unicast.prefix = osm_physp_get_subnet_prefix( p_dest_physp );
+ p_pr->dgid.unicast.interface_id = osm_physp_get_port_guid( p_dest_physp );
+ }
+#endif
p_pr->sgid.unicast.prefix = osm_physp_get_subnet_prefix( p_src_physp );
p_pr->sgid.unicast.interface_id = osm_physp_get_port_guid( p_src_physp );
@@ -736,6 +765,11 @@ __osm_pr_rcv_build_pr(
p_pr->slid = cl_hton16( src_lid_ho );
p_pr->hop_flow_raw &= cl_hton32(1<<31);
+#ifdef ROUTER_EXP
+ /* Only set HopLimit if going through a router */
+ if ( is_nonzero_gid )
+ p_pr->hop_flow_raw |= cl_hton32(IB_HOPLIMIT_MAX);
+#endif
p_pr->pkey = p_parms->pkey;
p_pr->sl = cl_hton16(p_parms->sl);
@@ -766,6 +800,7 @@ __osm_pr_rcv_get_lid_pair_path(
IN const ib_path_rec_t* const p_pr,
IN const osm_port_t* const p_src_port,
IN const osm_port_t* const p_dest_port,
+ IN const ib_gid_t* const p_dgid,
IN const uint16_t src_lid_ho,
IN const uint16_t dest_lid_ho,
IN const ib_net64_t comp_mask,
@@ -832,7 +867,7 @@ __osm_pr_rcv_get_lid_pair_path(
}
}
- __osm_pr_rcv_build_pr( p_rcv, p_src_port, p_dest_port,
+ __osm_pr_rcv_build_pr( p_rcv, p_src_port, p_dest_port, p_dgid,
src_lid_ho, dest_lid_ho, preference, &path_parms,
&p_pr_item->path_rec );
@@ -850,6 +885,7 @@ __osm_pr_rcv_get_port_pair_paths(
IN const osm_port_t* const p_req_port,
IN const osm_port_t* const p_src_port,
IN const osm_port_t* const p_dest_port,
+ IN const ib_gid_t* const p_dgid,
IN const ib_net64_t comp_mask,
IN cl_qlist_t* const p_list )
{
@@ -1016,6 +1052,7 @@ __osm_pr_rcv_get_port_pair_paths(
p_pr_item = __osm_pr_rcv_get_lid_pair_path( p_rcv, p_pr,
p_src_port, p_dest_port,
+ p_dgid,
src_lid_ho, dest_lid_ho,
comp_mask, preference );
@@ -1083,6 +1120,7 @@ __osm_pr_rcv_get_port_pair_paths(
p_pr_item = __osm_pr_rcv_get_lid_pair_path( p_rcv, p_pr,
p_src_port, p_dest_port,
+ p_dgid,
src_lid_ho, dest_lid_ho,
comp_mask, preference );
@@ -1105,13 +1143,19 @@ __osm_pr_rcv_get_end_points(
IN osm_pr_rcv_t* const p_rcv,
IN const osm_madw_t* const p_madw,
OUT const osm_port_t** const pp_src_port,
- OUT const osm_port_t** const pp_dest_port )
+ OUT const osm_port_t** const pp_dest_port,
+ OUT ib_gid_t* const p_dgid )
{
const ib_path_rec_t* p_pr;
const ib_sa_mad_t* p_sa_mad;
ib_net64_t comp_mask;
+ ib_net64_t dest_guid;
ib_api_status_t status;
ib_net16_t sa_status = IB_SA_MAD_STATUS_SUCCESS;
+#ifdef ROUTER_EXP
+ osm_router_t* p_rtr;
+ osm_port_t* p_rtr_port;
+#endif
OSM_LOG_ENTER( p_rcv->p_log, __osm_pr_rcv_get_end_points );
@@ -1198,31 +1242,52 @@ __osm_pr_rcv_get_end_points(
}
}
+ if ( p_dgid )
+ memset( p_dgid, 0, sizeof(*p_dgid));
+
if( comp_mask & IB_PR_COMPMASK_DGID )
{
+ dest_guid = p_pr->dgid.unicast.interface_id;
if ( ! ib_gid_is_link_local( &p_pr->dgid ) )
{
if ( ! ib_gid_is_multicast( &p_pr->dgid ) &&
ib_gid_get_subnet_prefix( &p_pr->dgid ) != p_rcv->p_subn->opt.subnet_prefix )
{
+ osm_log( p_rcv->p_log, OSM_LOG_VERBOSE,
+ "__osm_pr_rcv_get_end_points: "
+ "Non local DGID subnet prefix 0x%016" PRIx64 "\n",
+ cl_ntoh64( p_pr->dgid.unicast.prefix ) );
+#ifndef ROUTER_EXP
/*
This 'error' is the client's fault (bad gid) so
don't enter it as an error in our own log.
Return an error response to the client.
*/
- osm_log( p_rcv->p_log, OSM_LOG_VERBOSE,
- "__osm_pr_rcv_get_end_points: "
- "Non local DGID subnet prefix 0x%016" PRIx64 "\n",
- cl_ntoh64( p_pr->dgid.unicast.prefix ) );
-
sa_status = IB_SA_MAD_STATUS_INVALID_GID;
goto Exit;
+#else
+ /* Just use "first" router (if it exists) for now */
+ p_rtr = (osm_router_t*)cl_qmap_head( &p_rcv->p_subn->rtr_guid_tbl );
+ if ( p_rtr == (osm_router_t*)cl_qmap_end( &p_rcv->p_subn->rtr_guid_tbl ) )
+ {
+ osm_log( p_rcv->p_log, OSM_LOG_ERROR,
+ "__osm_pr_rcv_get_end_points: ERR 1F22: "
+ "Off subnet DGID but no routers found\n" );
+ sa_status = IB_SA_MAD_STATUS_INVALID_GID;
+ goto Exit;
+ }
+
+ p_rtr_port = osm_router_get_port_ptr( p_rtr );
+ dest_guid = osm_port_get_guid( p_rtr_port );
+ if ( p_dgid )
+ *p_dgid = p_pr->dgid;
+#endif
}
}
*pp_dest_port = (osm_port_t*)cl_qmap_get(
&p_rcv->p_subn->port_guid_tbl,
- p_pr->dgid.unicast.interface_id );
+ dest_guid );
if( *pp_dest_port == (osm_port_t*)cl_qmap_end(
&p_rcv->p_subn->port_guid_tbl ) )
@@ -1235,7 +1300,7 @@ __osm_pr_rcv_get_end_points(
osm_log( p_rcv->p_log, OSM_LOG_VERBOSE,
"__osm_pr_rcv_get_end_points: "
"No dest port with GUID 0x%016" PRIx64 "\n",
- cl_ntoh64( p_pr->dgid.unicast.interface_id) );
+ cl_ntoh64( dest_guid ) );
sa_status = IB_SA_MAD_STATUS_INVALID_GID;
goto Exit;
@@ -1279,6 +1344,7 @@ __osm_pr_rcv_process_world(
IN osm_pr_rcv_t* const p_rcv,
IN const osm_madw_t* const p_madw,
IN const osm_port_t* const requester_port,
+ IN const ib_gid_t* const p_dgid,
IN const ib_net64_t comp_mask,
IN cl_qlist_t* const p_list )
{
@@ -1305,7 +1371,7 @@ __osm_pr_rcv_process_world(
while( p_src_port != (osm_port_t*)cl_qmap_end( p_tbl ) )
{
__osm_pr_rcv_get_port_pair_paths( p_rcv, p_madw, requester_port, p_src_port,
- p_dest_port, comp_mask, p_list );
+ p_dest_port, p_dgid, comp_mask, p_list );
p_src_port = (osm_port_t*)cl_qmap_next( &p_src_port->map_item );
}
@@ -1325,6 +1391,7 @@ __osm_pr_rcv_process_half(
IN const osm_port_t* const requester_port,
IN const osm_port_t* const p_src_port,
IN const osm_port_t* const p_dest_port,
+ IN const ib_gid_t* const p_dgid,
IN const ib_net64_t comp_mask,
IN cl_qlist_t* const p_list )
{
@@ -1349,7 +1416,7 @@ __osm_pr_rcv_process_half(
while( p_port != (osm_port_t*)cl_qmap_end( p_tbl ) )
{
__osm_pr_rcv_get_port_pair_paths( p_rcv, p_madw, requester_port,
- p_src_port, p_port,
+ p_src_port, p_port, p_dgid,
comp_mask, p_list );
p_port = (osm_port_t*)cl_qmap_next( &p_port->map_item );
}
@@ -1363,7 +1430,7 @@ __osm_pr_rcv_process_half(
while( p_port != (osm_port_t*)cl_qmap_end( p_tbl ) )
{
__osm_pr_rcv_get_port_pair_paths( p_rcv, p_madw, requester_port,
- p_port, p_dest_port,
+ p_port, p_dest_port, p_dgid,
comp_mask, p_list );
p_port = (osm_port_t*)cl_qmap_next( &p_port->map_item );
}
@@ -1381,13 +1448,14 @@ __osm_pr_rcv_process_pair(
IN const osm_port_t* const requester_port,
IN const osm_port_t* const p_src_port,
IN const osm_port_t* const p_dest_port,
+ IN const ib_gid_t* const p_dgid,
IN const ib_net64_t comp_mask,
IN cl_qlist_t* const p_list )
{
OSM_LOG_ENTER( p_rcv->p_log, __osm_pr_rcv_process_pair );
__osm_pr_rcv_get_port_pair_paths( p_rcv, p_madw, requester_port, p_src_port,
- p_dest_port, comp_mask, p_list );
+ p_dest_port, p_dgid, comp_mask, p_list );
OSM_LOG_EXIT( p_rcv->p_log );
}
@@ -1831,6 +1899,7 @@ osm_pr_rcv_process(
const osm_port_t* p_src_port;
const osm_port_t* p_dest_port;
cl_qlist_t pr_list;
+ ib_gid_t dgid;
ib_net16_t sa_status;
osm_port_t* requester_port;
int ret;
@@ -1894,7 +1963,8 @@ osm_pr_rcv_process(
"Unicast destination requested\n" );
sa_status = __osm_pr_rcv_get_end_points( p_rcv, p_madw,
- &p_src_port, &p_dest_port );
+ &p_src_port, &p_dest_port,
+ &dgid );
if( sa_status == IB_SA_MAD_STATUS_SUCCESS )
{
@@ -1906,25 +1976,25 @@ osm_pr_rcv_process(
{
if( p_dest_port )
__osm_pr_rcv_process_pair( p_rcv, p_madw, requester_port,
- p_src_port, p_dest_port,
+ p_src_port, p_dest_port, &dgid,
p_sa_mad->comp_mask, &pr_list );
else
__osm_pr_rcv_process_half( p_rcv, p_madw, requester_port,
- p_src_port, NULL,
+ p_src_port, NULL, &dgid,
p_sa_mad->comp_mask, &pr_list );
}
else
{
if( p_dest_port )
__osm_pr_rcv_process_half( p_rcv, p_madw, requester_port,
- NULL, p_dest_port,
+ NULL, p_dest_port, &dgid,
p_sa_mad->comp_mask, &pr_list );
else
/*
Katie, bar the door!
*/
__osm_pr_rcv_process_world( p_rcv, p_madw, requester_port,
- p_sa_mad->comp_mask, &pr_list );
+ &dgid, p_sa_mad->comp_mask, &pr_list );
}
}
goto Unlock;
@@ -1980,8 +2050,19 @@ osm_pr_rcv_process(
ib_member_get_sl_flow_hop( p_mgrp->mcmember_rec.sl_flow_hop,
&sl, &flow_label, &hop_limit );
p_pr_item->path_rec.sl = cl_hton16( sl );
+#ifndef ROUTER_EXP
p_pr_item->path_rec.hop_flow_raw = (uint32_t)(hop_limit) |
(flow_label << 8);
+#else
+ /* HopLimit is not yet set in non link local MC groups */
+ /* If it were, this would not be needed */
+ if ( ib_mgid_get_scope( &p_mgrp->mcmember_rec.mgid ) == MC_SCOPE_LINK_LOCAL )
+ p_pr_item->path_rec.hop_flow_raw = (uint32_t)(hop_limit) |
+ (flow_label << 8);
+ else
+ p_pr_item->path_rec.hop_flow_raw = cl_hton32(IB_HOPLIMIT_MAX) |
+ (flow_label << 8);
+#endif
cl_qlist_insert_tail( &pr_list,
(cl_list_item_t*)&p_pr_item->pool_item );
More information about the general
mailing list