[openib-general] [PATCH] osm_sa_mcmember_record : MCMember Get/GetTable Trusted mode

Ofer Gigi oferg at mellanox.co.il
Thu Mar 23 02:01:39 PST 2006


Hi Hal,

The fix below fixes the retrieve of the mcmember records according to the 
Errata MGTWG3280.

Quoting from MGTWG3280:

SA can be queried for multicast groups by sending a SubnAdmGet() or a
 SubnAdmGetTable() request to it using the SA query mechanism (see
15.4.4 Administration Query Subsystem on page 923).

What SA returns in response to a query of multicast groups depends
strongly on whether the request is or is not a trusted request; the
degree of trust affects both the data returned in each attribute and
the set of attributes that are returned. See <ref to C15-0.2.2:>.

o15-0.2.5 is made obsolete.

So we need to implement the following descriptive text:

SA can be queried for multicast groups by sending a SubnAdmGet() or a
SubnAdmGetTable() request to it using the SA query mechanism (see
15.4.4 Administration Query Subsystem on page 923). SA will return one
MCMemberRecord per multicast group matching the query, except in
cases where trust is specified as indicated in 15.4.1.2 Access Restrictions
For Other Attributes on page 922; in that case all the MCMemberRecords
associated with the multicast group are returned. The MCMemberRecord
will be returned with the PortGID, ProxyJoin, and the JoinState components
set to 0, except where trust is specified as indicated above, in that
case the actual contents for the above components will be provided.
Thanks

Ofer G.

Signed-off-by:  Ofer Gigi <oferg at mellanox.co.il>
Index: osm_sa_mcmember_record.c
===================================================================
--- osm_sa_mcmember_record.c	(revision 5919)
+++ osm_sa_mcmember_record.c	(working copy)
@@ -91,6 +91,7 @@ typedef  struct   osm_sa_mcmr_search_ctx
   cl_qlist_t      *p_list; /*  hold results */
   ib_net64_t      comp_mask;
   const osm_physp_t*    p_req_physp;
+  boolean_t       trusted_req;
 } osm_sa_mcmr_search_ctxt_t;
 
 /**********************************************************************
@@ -1918,6 +1919,9 @@ __osm_sa_mcm_by_comp_mask_cb(
   /* will be used for group or port info */
   uint8_t scope_state; 
   uint8_t scope_state_mask = 0;
+  cl_map_item_t *p_item;
+  ib_gid_t	port_gid;
+  boolean_t proxy_join;
 
   OSM_LOG_ENTER( p_rcv->p_log, __osm_sa_mcm_by_comp_mask_cb );
 
@@ -1938,39 +1942,28 @@ __osm_sa_mcm_by_comp_mask_cb(
 
   /* first try to eliminate the group by MGID, MLID, or P_Key */
   if ((IB_MCR_COMPMASK_MGID & comp_mask) &&
-      cl_memcmp(&p_rcvd_rec->mgid, &p_mgrp->mcmember_rec.mgid, sizeof(ib_gid_t))) {
+      cl_memcmp(&p_rcvd_rec->mgid, 
+                &p_mgrp->mcmember_rec.mgid, 
+                sizeof(ib_gid_t)))
+  {
     goto Exit;
   }
 
   if ((IB_MCR_COMPMASK_MLID & comp_mask) &&
-      cl_memcmp(&p_rcvd_rec->mlid, &p_mgrp->mcmember_rec.mlid, sizeof(uint16_t))) {
+      cl_memcmp(&p_rcvd_rec->mlid, 
+      &p_mgrp->mcmember_rec.mlid, 
+      sizeof(uint16_t))) 
+  {
     goto Exit;
   }
 
-  /* if the requester physical port doesn't have the pkey that is defined for the
-     group - exit. */
-  if (! osm_physp_has_pkey( p_rcv->p_log, p_mgrp->mcmember_rec.pkey, p_req_physp ))
+  /* if the requester physical port doesn't have the pkey that is defined for
+     the group - exit. */
+  if (! osm_physp_has_pkey( p_rcv->p_log, 
+                            p_mgrp->mcmember_rec.pkey, 
+                            p_req_physp ))
     goto Exit;
 
-  /* so did we get the PortGUID mask */
-  if (IB_MCR_COMPMASK_PORT_GID & comp_mask)
-  {
-    /* try to find this port */
-    if (osm_mgrp_is_port_present(p_mgrp, portguid, &p_mcm_port))
-    {
-      scope_state = p_mcm_port->scope_state;
-    }
-    else
-    {
-      /* port not in group */
-      goto Exit;
-    }
-  }
-  else
-  {
-    /* point to the group information */
-    scope_state = p_mgrp->mcmember_rec.scope_state;
-  }
 
   /* now do the rest of the match */
   if ((IB_MCR_COMPMASK_QKEY & comp_mask) &&
@@ -2004,17 +1997,15 @@ __osm_sa_mcm_by_comp_mask_cb(
       if (query_hop != mgrp_hop) goto Exit;
   }
 
+  if ((IB_MCR_COMPMASK_PROXY & comp_mask) &&
+      (p_rcvd_rec->proxy_join != p_mgrp->mcmember_rec.proxy_join)) goto Exit;
+
   if (IB_MCR_COMPMASK_SCOPE & comp_mask)
     scope_state_mask = 0xF0;
 
   if (IB_MCR_COMPMASK_JOIN_STATE & comp_mask)
     scope_state_mask = scope_state_mask | 0x0F;
 
-  if ((scope_state_mask & p_rcvd_rec->scope_state) !=
-      (scope_state_mask & scope_state)) goto Exit;
-
-  if ((IB_MCR_COMPMASK_PROXY & comp_mask) &&
-      (p_rcvd_rec->proxy_join != p_mgrp->mcmember_rec.proxy_join)) goto Exit;
 
   /* need to validate mtu, rate, and pkt_lifetime fields. */
   if (__validate_more_comp_fields( p_rcv->p_log,
@@ -2022,11 +2013,84 @@ __osm_sa_mcm_by_comp_mask_cb(
                                    p_rcvd_rec,
                                    comp_mask ) == FALSE) goto Exit;
 
+
+  /* Port specific fields */
+  /* so did we got the PortGUID mask */
+  if (IB_MCR_COMPMASK_PORT_GID & comp_mask)
+  {
+     /* try to find this port */
+     if (osm_mgrp_is_port_present(p_mgrp, portguid, &p_mcm_port))
+     {
+       scope_state = p_mcm_port->scope_state;
+	   cl_memcpy(&port_gid, &(p_mcm_port->port_gid), sizeof(ib_gid_t));
+	   proxy_join=p_mcm_port->proxy_join;
+     }
+     else
+     {
+       /* port not in group */
+       goto Exit;
+     }
+  }
+  else
+  {
+     /* point to the group information */
+     scope_state = p_mgrp->mcmember_rec.scope_state;
+  }
+
+
+  /* Many MC record returned */
+  if ( (p_ctxt->trusted_req==TRUE) && !(IB_MCR_COMPMASK_PORT_GID & comp_mask) )
+  {
+     osm_log(p_rcv->p_log, OSM_LOG_DEBUG,
+			  "__osm_sa_mcm_by_comp_mask_cb: "
+			  "trusted req is TRUE and no specific port defined\n");
+
+	  /* return all the ports the match in this MC group */
+     p_item = cl_qmap_head(&(p_mgrp->mcm_port_tbl));
+     while( p_item != cl_qmap_end(&(p_mgrp->mcm_port_tbl)) )
+     {
+        p_mcm_port=(osm_mcm_port_t *)p_item;
+
+        if ((scope_state_mask & p_rcvd_rec->scope_state) ==
+            (scope_state_mask & p_mcm_port->scope_state)) 
+		  {
+           /* add to the list */
+           match_rec = p_mgrp->mcmember_rec;
+           match_rec.scope_state = p_mcm_port->scope_state;
+			  cl_memcpy( &(match_rec.port_gid), 
+                      &(p_mcm_port->port_gid), 
+                      sizeof(ib_gid_t));
+			  osm_log(p_rcv->p_log, OSM_LOG_DEBUG,
+					 "__osm_sa_mcm_by_comp_mask_cb: "
+					 "record of port_gid: 0x%016" PRIx64 "0x%016" PRIx64 
+					 " in multicast_lid: 0x%X is returned\n",
+					 cl_ntoh64(match_rec.port_gid.unicast.prefix),
+					 cl_ntoh64(match_rec.port_gid.unicast.interface_id),	
+					 cl_ntoh16(p_mgrp->mlid)
+					 );
+
+			   match_rec.proxy_join = (uint8_t)(p_mcm_port->proxy_join);
+
+			   __osm_mcmr_rcv_new_mcmr(p_rcv, &match_rec, p_ctxt->p_list);
+		   }
+         p_item = cl_qmap_next(p_item);
+      }
+  }
+  /* One MC record returned */
+  else
+  {
+     if ((scope_state_mask & p_rcvd_rec->scope_state) !=
+         (scope_state_mask & scope_state)) goto Exit;
+
   /* add to the list */
   match_rec = p_mgrp->mcmember_rec;
   match_rec.scope_state = scope_state;
+      cl_memcpy(&(match_rec.port_gid), &port_gid, sizeof(ib_gid_t));
+      match_rec.proxy_join = (uint8_t)proxy_join;
 
   __osm_mcmr_rcv_new_mcmr(p_rcv, &match_rec, p_ctxt->p_list);
+  }
+
  Exit:
   OSM_LOG_EXIT( p_rcv->p_log );
 }
@@ -2053,7 +2117,7 @@ osm_mcmr_query_mgrp(IN osm_mcmr_recv_t* 
   ib_api_status_t       status;
   ib_net64_t               comp_mask;
   osm_physp_t*             p_req_physp;
-  boolean_t                trusted_req = TRUE;
+  boolean_t                trusted_req;
 
   CL_ASSERT( p_rcv );
 
@@ -2067,6 +2131,12 @@ osm_mcmr_query_mgrp(IN osm_mcmr_recv_t* 
 
   CL_ASSERT( p_rcvd_mad->attr_id == IB_MAD_ATTR_MCMEMBER_RECORD );
 
+  /* 
+	if sm_key is not zero and does not match we never get here 
+    see main SA receiver
+   */  
+  trusted_req = (p_rcvd_mad->sm_key != 0);
+  
   /* update the requester physical port. */
   p_req_physp = osm_get_physp_by_mad_addr(p_rcv->p_log,
                                           p_rcv->p_subn,
@@ -2086,6 +2156,7 @@ osm_mcmr_query_mgrp(IN osm_mcmr_recv_t* 
   context.comp_mask = p_rcvd_mad->comp_mask;
   context.p_rcv = p_rcv;
   context.p_req_physp = p_req_physp;
+  context.trusted_req = trusted_req;
 
   CL_PLOCK_ACQUIRE( p_rcv->p_lock );
 
@@ -2212,8 +2283,7 @@ osm_mcmr_query_mgrp(IN osm_mcmr_recv_t* 
     the mad is valid. Meaning - is either zero or equal to the local
     sm_key.
   */
-  if (p_rcvd_mad->sm_key == 0)
-    trusted_req = FALSE;
+
 
   for ( i = 0; i < pre_trim_num_rec; i++ )
   {





More information about the general mailing list