[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