diff mbox

[RFC] opensm: compress IPV6 SNM groups to use a single MLID

Message ID 20091113204041.GU7192@me (mailing list archive)
State Not Applicable, archived
Headers show

Commit Message

Sasha Khapyorsky Nov. 13, 2009, 8:40 p.m. UTC
None
diff mbox

Patch

diff --git a/opensm/opensm/osm_sa_mcmember_record.c b/opensm/opensm/osm_sa_mcmember_record.c
index 27675b6..58c5736 100644
--- a/opensm/opensm/osm_sa_mcmember_record.c
+++ b/opensm/opensm/osm_sa_mcmember_record.c
@@ -114,6 +114,35 @@  static void free_mlid(IN osm_sa_t * sa, IN uint16_t mlid)
 /*********************************************************************
  Get a new unused mlid by scanning all the used ones in the subnet.
 **********************************************************************/
+/* Special Case IPv6 Solicited Node Multicast (SNM) addresses */
+/* 0xff1Z601bXXXX0000 : 0x00000001ffYYYYYY */
+/* Where Z is the scope, XXXX is the P_Key, and
+ * YYYYYY is the last 24 bits of the port guid */
+#define PREFIX_MASK CL_HTON64(0xff10ffff0000ffffULL)
+#define PREFIX_SIGNATURE CL_HTON64(0xff10601b00000000ULL)
+#define INT_ID_MASK CL_HTON64(0xfffffff1ff000000ULL)
+#define INT_ID_SIGNATURE CL_HTON64(0x00000001ff000000ULL)
+
+static int compare_ipv6_snm_mgids(const void *m1, const void *m2)
+{
+	return memcmp(m1, m2, sizeof(ib_gid_t) - 6);
+}
+
+static ib_net16_t find_ipv6_snm_mlid(osm_subn_t *subn, ib_gid_t *mgid)
+{
+	osm_mgrp_t *m = (osm_mgrp_t *)cl_fmap_match(&subn->mgrp_mgid_tbl, mgid,
+						    compare_ipv6_snm_mgids);
+	if (m != (osm_mgrp_t *)cl_fmap_end(&subn->mgrp_mgid_tbl))
+		return m->mlid;
+	return 0;
+}
+
+static unsigned match_ipv6_snm_mgid(ib_gid_t * mgid)
+{
+	return ((mgid->unicast.prefix & PREFIX_MASK) == PREFIX_SIGNATURE &&
+		(mgid->unicast.interface_id & INT_ID_MASK) == INT_ID_SIGNATURE);
+}
+
 static ib_net16_t get_new_mlid(osm_sa_t * sa, ib_member_rec_t * mcmr)
 {
 	osm_subn_t *p_subn = sa->p_subn;
@@ -125,6 +154,16 @@  static ib_net16_t get_new_mlid(osm_sa_t * sa, ib_member_rec_t * mcmr)
 	    && !osm_get_mbox_by_mlid(p_subn, requested_mlid))
 		return requested_mlid;
 
+	if (sa->p_subn->opt.consolidate_ipv6_snm_req
+	    && match_ipv6_snm_mgid(&mcmr->mgid)
+	    && (requested_mlid = find_ipv6_snm_mlid(sa->p_subn, &mcmr->mgid))) {
+		char str[INET6_ADDRSTRLEN];
+		OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
+			"Special Case Solicited Node Mcast Join for MGID %s\n",
+			inet_ntop(AF_INET6, mcmr->mgid.raw, str, sizeof(str)));
+		return requested_mlid;
+	}
+
 	max = p_subn->max_mcast_lid_ho - IB_LID_MCAST_START_HO + 1;
 	for (i = 0; i < max; i++)
 		if (!sa->p_subn->mboxes[i])
@@ -829,39 +868,10 @@  Exit:
 	return status;
 }
 
-#define PREFIX_MASK CL_HTON64(0xff10ffff0000ffffULL)
-#define PREFIX_SIGNATURE CL_HTON64(0xff10601b00000000ULL)
-#define INT_ID_MASK CL_HTON64(0xfffffff1ff000000ULL)
-#define INT_ID_SIGNATURE CL_HTON64(0x00000001ff000000ULL)
-
-/* Special Case IPv6 Solicited Node Multicast (SNM) addresses */
-/* 0xff1Z601bXXXX0000 : 0x00000001ffYYYYYY */
-/* Where Z is the scope, XXXX is the P_Key, and
- * YYYYYY is the last 24 bits of the port guid */
-static unsigned match_and_update_ipv6_snm_mgid(ib_gid_t * mgid)
-{
-	if ((mgid->unicast.prefix & PREFIX_MASK) == PREFIX_SIGNATURE &&
-	    (mgid->unicast.interface_id & INT_ID_MASK) == INT_ID_SIGNATURE) {
-		mgid->unicast.prefix &= PREFIX_MASK;
-		mgid->unicast.interface_id &= INT_ID_MASK;
-		return 1;
-	}
-	return 0;
-}
-
 osm_mgrp_t *osm_get_mgrp_by_mgid(IN osm_sa_t * sa, IN ib_gid_t * p_mgid)
 {
 	osm_mgrp_t *mg;
 
-	if (sa->p_subn->opt.consolidate_ipv6_snm_req &&
-	    match_and_update_ipv6_snm_mgid(p_mgid)) {
-		char gid_str[INET6_ADDRSTRLEN];
-		OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
-			"Special Case Solicited Node Mcast Join for MGID %s\n",
-			inet_ntop(AF_INET6, p_mgid->raw, gid_str,
-				  sizeof gid_str));
-	}
-
 	mg = (osm_mgrp_t *)cl_fmap_get(&sa->p_subn->mgrp_mgid_tbl, p_mgid);
 	if (mg != (osm_mgrp_t *)cl_fmap_end(&sa->p_subn->mgrp_mgid_tbl))
 		return mg;