osmt_multicast.c revision 267654
1/*
2 * Copyright (c) 2006-2008 Voltaire, Inc. All rights reserved.
3 * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
4 * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
5 *
6 * This software is available to you under a choice of one of two
7 * licenses.  You may choose to be licensed under the terms of the GNU
8 * General Public License (GPL) Version 2, available from the file
9 * COPYING in the main directory of this source tree, or the
10 * OpenIB.org BSD license below:
11 *
12 *     Redistribution and use in source and binary forms, with or
13 *     without modification, are permitted provided that the following
14 *     conditions are met:
15 *
16 *      - Redistributions of source code must retain the above
17 *        copyright notice, this list of conditions and the following
18 *        disclaimer.
19 *
20 *      - Redistributions in binary form must reproduce the above
21 *        copyright notice, this list of conditions and the following
22 *        disclaimer in the documentation and/or other materials
23 *        provided with the distribution.
24 *
25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32 * SOFTWARE.
33 *
34 */
35
36/*
37 * Abstract:
38 * 	Implementation of Multicast Member testing flow..
39 *
40 */
41
42#ifndef __WIN__
43#include <unistd.h>
44#endif
45#include <stdio.h>
46#include <stdlib.h>
47#include <string.h>
48#include <arpa/inet.h>
49#include <complib/cl_debug.h>
50#include <complib/cl_map.h>
51#include <complib/cl_list.h>
52#include "osmtest.h"
53
54/**********************************************************************
55 **********************************************************************/
56
57static void __osmt_print_all_multicast_records(IN osmtest_t * const p_osmt)
58{
59	uint32_t i;
60	ib_api_status_t status;
61	osmv_query_req_t req;
62	osmv_user_query_t user;
63	osmtest_req_context_t context;
64	ib_member_rec_t *mcast_record;
65
66	memset(&context, 0, sizeof(context));
67	memset(&req, 0, sizeof(req));
68	memset(&user, 0, sizeof(user));
69
70	user.attr_id = IB_MAD_ATTR_MCMEMBER_RECORD;
71	user.attr_offset = ib_get_attr_offset(sizeof(*mcast_record));
72
73	req.query_type = OSMV_QUERY_USER_DEFINED;
74	req.timeout_ms = p_osmt->opt.transaction_timeout;
75	req.retry_cnt = 1;
76	req.flags = OSM_SA_FLAGS_SYNC;
77	context.p_osmt = p_osmt;
78	req.query_context = &context;
79	req.pfn_query_cb = osmtest_query_res_cb;
80	req.p_query_input = &user;
81
82	/* UnTrusted (SMKey of 0)  - get the multicast groups */
83	status = osmv_query_sa(p_osmt->h_bind, &req);
84
85	if (status != IB_SUCCESS || context.result.status != IB_SUCCESS) {
86		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02B5: "
87			"Failed getting the multicast groups records - %s/%s\n",
88			ib_get_err_str(status),
89			ib_get_err_str(context.result.status));
90		return;
91	}
92
93	osm_log(&p_osmt->log, OSM_LOG_INFO,
94		"\n                    |------------------------------------------|"
95		"\n                    |        Remaining Multicast Groups        |"
96		"\n                    |------------------------------------------|\n");
97
98	for (i = 0; i < context.result.result_cnt; i++) {
99		mcast_record =
100		    osmv_get_query_mc_rec(context.result.p_result_madw, i);
101		osm_dump_mc_record(&p_osmt->log, mcast_record, OSM_LOG_INFO);
102	}
103
104	/* Trusted - now get the multicast group members */
105	req.sm_key = OSM_DEFAULT_SM_KEY;
106	status = osmv_query_sa(p_osmt->h_bind, &req);
107
108	if (status != IB_SUCCESS || context.result.status != IB_SUCCESS) {
109		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02B6: "
110			"Failed getting the multicast group members records - %s/%s\n",
111			ib_get_err_str(status),
112			ib_get_err_str(context.result.status));
113		return;
114	}
115
116	osm_log(&p_osmt->log, OSM_LOG_INFO,
117		"\n                    |--------------------------------------------------|"
118		"\n                    |        Remaining Multicast Group Members        |"
119		"\n                    |--------------------------------------------------|\n");
120
121	for (i = 0; i < context.result.result_cnt; i++) {
122		mcast_record =
123		    osmv_get_query_mc_rec(context.result.p_result_madw, i);
124		osm_dump_mc_record(&p_osmt->log, mcast_record, OSM_LOG_INFO);
125	}
126
127}
128
129/**********************************************************************
130 **********************************************************************/
131
132static cl_status_t
133__match_mgids(IN const void *const p_object, IN void *context)
134{
135	ib_gid_t *p_mgid_context = (ib_gid_t *) context;
136	ib_gid_t *p_mgid_list_item = (ib_gid_t *) p_object;
137	int32_t count;
138
139	count = memcmp(p_mgid_context, p_mgid_list_item, sizeof(ib_gid_t));
140	if (count == 0)
141		return CL_SUCCESS;
142	else
143		return CL_NOT_FOUND;
144}
145
146/**********************************************************************
147 **********************************************************************/
148
149ib_api_status_t osmt_query_mcast(IN osmtest_t * const p_osmt)
150{
151	ib_api_status_t status = IB_SUCCESS;
152	osmv_user_query_t user;
153	osmv_query_req_t req;
154	osmtest_req_context_t context;
155	ib_member_rec_t *p_rec;
156	uint32_t i, num_recs = 0;
157	cl_list_t mgids_list;
158	cl_list_t *p_mgids_list;
159	cl_list_iterator_t p_mgids_res;
160	cl_status_t cl_status;
161	cl_map_item_t *p_item, *p_next_item;
162	osmtest_mgrp_t *p_mgrp;
163
164	OSM_LOG_ENTER(&p_osmt->log);
165
166	/*
167	 * Do a blocking query for all Multicast Records in the subnet.
168	 * The result is returned in the result field of the caller's
169	 * context structure.
170	 *
171	 * The query structures are locals.
172	 */
173
174	memset(&req, 0, sizeof(req));
175	memset(&user, 0, sizeof(user));
176
177	context.p_osmt = p_osmt;
178	user.attr_id = IB_MAD_ATTR_MCMEMBER_RECORD;
179	user.attr_offset = ib_get_attr_offset(sizeof(ib_member_rec_t));
180
181	req.query_type = OSMV_QUERY_USER_DEFINED;
182	req.timeout_ms = p_osmt->opt.transaction_timeout;
183	req.retry_cnt = p_osmt->opt.retry_count;
184	req.flags = OSM_SA_FLAGS_SYNC;
185	req.query_context = &context;
186	req.pfn_query_cb = osmtest_query_res_cb;
187	req.p_query_input = &user;
188
189	status = osmv_query_sa(p_osmt->h_bind, &req);
190
191	if (status != IB_SUCCESS) {
192		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0203: "
193			"ib_query failed (%s)\n", ib_get_err_str(status));
194		goto Exit;
195	}
196
197	status = context.result.status;
198
199	if (status != IB_SUCCESS) {
200		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0264: "
201			"ib_query failed (%s)\n", ib_get_err_str(status));
202		if (status == IB_REMOTE_ERROR) {
203			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
204				"Remote error = %s.\n",
205				ib_get_mad_status_str(osm_madw_get_mad_ptr
206						      (context.result.
207						       p_result_madw)));
208		}
209		goto Exit;
210	}
211
212	/* ok we have got something */
213	/* First Delete the old MGID Table */
214	p_next_item = cl_qmap_head(&p_osmt->exp_subn.mgrp_mlid_tbl);
215	while (p_next_item != cl_qmap_end(&p_osmt->exp_subn.mgrp_mlid_tbl)) {
216		p_item = p_next_item;
217		p_next_item = cl_qmap_next(p_item);
218		cl_qmap_remove_item(&p_osmt->exp_subn.mgrp_mlid_tbl, p_item);
219		free(p_item);
220
221	}
222
223	cl_list_construct(&mgids_list);
224	cl_list_init(&mgids_list, num_recs);
225	p_mgids_list = &mgids_list;
226	num_recs = context.result.result_cnt;
227	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "Received %u records\n",
228		num_recs);
229
230	for (i = 0; i < num_recs; i++) {
231		p_rec = osmv_get_query_result(context.result.p_result_madw, i);
232		p_mgids_res =
233		    cl_list_find_from_head(p_mgids_list, __match_mgids,
234					   &(p_rec->mgid));
235		/* If returns iterator other than end of list, same mgid exists already */
236		if (p_mgids_res != cl_list_end(p_mgids_list)) {
237			char gid_str[INET6_ADDRSTRLEN];
238			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0265: "
239				"MCG MGIDs are the same - invalid MGID : %s\n",
240				inet_ntop(AF_INET6, p_rec->mgid.raw, gid_str,
241					  sizeof gid_str));
242			status = IB_ERROR;
243			goto Exit;
244
245		}
246		osm_dump_mc_record(&p_osmt->log, p_rec, OSM_LOG_VERBOSE);
247		cl_status = cl_list_insert_head(p_mgids_list, &(p_rec->mgid));
248		if (cl_status) {
249			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0205: "
250				"Could not add MGID to cl_list\n");
251			status = IB_ERROR;
252			goto Exit;
253		}
254		p_mgrp = (osmtest_mgrp_t *) malloc(sizeof(*p_mgrp));
255		if (!p_mgrp) {
256			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0204: "
257				"Could not allocate new MCG\n");
258			status = IB_ERROR;
259			goto Exit;
260		}
261		memcpy(&p_mgrp->mcmember_rec, p_rec,
262		       sizeof(p_mgrp->mcmember_rec));
263		cl_qmap_insert(&p_osmt->exp_subn.mgrp_mlid_tbl,
264			       cl_ntoh16(p_rec->mlid), &p_mgrp->map_item);
265	}
266
267Exit:
268	if (context.result.p_result_madw != NULL) {
269		osm_mad_pool_put(&p_osmt->mad_pool,
270				 context.result.p_result_madw);
271		context.result.p_result_madw = NULL;
272	}
273
274	OSM_LOG_EXIT(&p_osmt->log);
275	return (status);
276}
277
278/**********************************************************************
279 **********************************************************************/
280
281/* given a multicast request send and wait for response. */
282ib_api_status_t
283osmt_send_mcast_request(IN osmtest_t * const p_osmt,
284			IN uint8_t is_set,
285			IN ib_member_rec_t * p_mc_req,
286			IN uint64_t comp_mask, OUT ib_sa_mad_t * p_res)
287{
288	osmtest_req_context_t context;
289	ib_api_status_t status = IB_SUCCESS;
290	osmv_user_query_t user;
291	osmv_query_req_t req;
292
293	OSM_LOG_ENTER(&p_osmt->log);
294
295	/*
296	 * Do a blocking query for this record in the subnet.
297	 *
298	 * The query structures are locals.
299	 */
300	memset(&req, 0, sizeof(req));
301	memset(&user, 0, sizeof(user));
302	memset(&context, 0, sizeof(context));
303	memset(p_res, 0, sizeof(ib_sa_mad_t));
304
305	context.p_osmt = p_osmt;
306
307	user.p_attr = p_mc_req;
308	user.comp_mask = comp_mask;
309
310	if (is_set == 1) {
311		req.query_type = OSMV_QUERY_UD_MULTICAST_SET;
312	} else if (is_set == 0) {
313		req.query_type = OSMV_QUERY_UD_MULTICAST_DELETE;
314	} else if (is_set == 0xee) {
315		OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
316			"Set USER DEFINED QUERY\n");
317		req.query_type = OSMV_QUERY_USER_DEFINED;
318		user.method = IB_MAD_METHOD_GET;
319		user.attr_id = IB_MAD_ATTR_MCMEMBER_RECORD;
320		user.attr_offset = ib_get_attr_offset(sizeof(ib_member_rec_t));
321	} else if (is_set == 0xff) {
322		OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
323			"Set USER DEFINED QUERY\n");
324		req.query_type = OSMV_QUERY_USER_DEFINED;
325		user.method = IB_MAD_METHOD_SET;
326		user.attr_id = IB_MAD_ATTR_MCMEMBER_RECORD;
327		user.attr_offset = ib_get_attr_offset(sizeof(ib_member_rec_t));
328	}
329
330	/* TODO : Check the validity of all user fields in order to use
331	   OSMV_QUERY_USER_DEFINED
332	   p_user_query = ( osmv_user_query_t * ) p_query_req->p_query_input;
333	   if (p_user_query->method) sa_mad_data.method = p_user_query->method;
334	   sa_mad_data.attr_offset = p_user_query->attr_offset;
335	   sa_mad_data.attr_id = p_user_query->attr_id;
336	   sa_mad_data.comp_mask = p_user_query->comp_mask;
337	   sa_mad_data.p_attr = p_user_query->p_attr;
338	 */
339
340	req.timeout_ms = p_osmt->opt.transaction_timeout;
341	req.retry_cnt = p_osmt->opt.retry_count;
342	req.flags = OSM_SA_FLAGS_SYNC;
343	req.query_context = &context;
344	req.pfn_query_cb = osmtest_query_res_cb;
345	req.p_query_input = &user;
346
347	status = osmv_query_sa(p_osmt->h_bind, &req);
348
349	if (status != IB_SUCCESS) {
350		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0206: "
351			"ib_query failed (%s)\n", ib_get_err_str(status));
352		goto Exit;
353	}
354
355	/* ok it worked */
356	memcpy(p_res,
357	       osm_madw_get_mad_ptr(context.result.p_result_madw),
358	       sizeof(ib_sa_mad_t));
359
360	status = context.result.status;
361
362	if (status != IB_SUCCESS) {
363		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0224: "
364			"ib_query failed (%s)\n", ib_get_err_str(status));
365		if (status == IB_REMOTE_ERROR) {
366			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
367				"Remote error = %s\n",
368				ib_get_mad_status_str(osm_madw_get_mad_ptr
369						      (context.result.
370						       p_result_madw)));
371		}
372	}
373
374Exit:
375	/*
376	 * Return the IB query MAD to the pool as necessary.
377	 */
378	if (context.result.p_result_madw != NULL) {
379		osm_mad_pool_put(&p_osmt->mad_pool,
380				 context.result.p_result_madw);
381		context.result.p_result_madw = NULL;
382	}
383
384	OSM_LOG_EXIT(&p_osmt->log);
385	return (status);
386}
387
388/**********************************************************************
389 **********************************************************************/
390
391void
392osmt_init_mc_query_rec(IN osmtest_t * const p_osmt,
393		       IN OUT ib_member_rec_t * p_mc_req)
394{
395	/* use default values so we can change only what we want later */
396	memset(p_mc_req, 0, sizeof(ib_member_rec_t));
397
398	/* we leave the MGID to the user */
399	memcpy(&p_mc_req->port_gid.unicast.interface_id,
400	       &p_osmt->local_port.port_guid,
401	       sizeof(p_osmt->local_port.port_guid)
402	    );
403
404	/*  use our own subnet prefix: */
405	p_mc_req->port_gid.unicast.prefix = CL_HTON64(0xFE80000000000000ULL);
406
407	/*  ib_net32_t  qkey; */
408	/*  ib_net16_t  mlid; - we keep it zero for upper level to decide. */
409	/*  uint8_t     mtu; - keep it zero means - anything you have please. */
410	/*  uint8_t     tclass; can leave as zero for now (between subnets) */
411	/*  ib_net16_t  pkey; leave as zero */
412	p_mc_req->rate = IB_LINK_WIDTH_ACTIVE_4X;
413	/*  uint8_t     pkt_life; zero means greater than zero ... */
414	/*  ib_net32_t  sl_flow_hop; keep it all zeros */
415	/*  we want to use a link local scope: 0x02 */
416	p_mc_req->scope_state = ib_member_set_scope_state(0x02, 0);
417}
418
419/***********************************************************************
420 * UD Multicast testing flow:
421 * o15.0.1.3:
422 * - Request new MCG with not enough components in comp_mask :
423 *   ERR_INSUFFICIENT_COMPONENTS
424 * o15.0.1.8:
425 * - Request a join with irrelevant RATE and get a ERR_INVALID_REQ
426 * o15.0.1.4:
427 * - Create an MGID by asking for a join with MGID = 0
428 *   providing P_Key, Q_Key, SL, FlowLabel, Tclass.
429 * o15.0.1.5:
430 * - Check the returned MGID is valid. (p 804)
431 * o15.0.1.6:
432 * - Create a new MCG with valid requested MGID.
433 * - Try to create a new MCG with invalid MGID : get back ERR_REQ_INVALID
434 * - Try again with MGID prefix = 0xA01B (maybe 0x1BA0 little or big ?)
435 * - Try to create again the already created group: ERR_REQ_INVALID
436 * o15.0.1.7 - implicitlly checked during the prev steps.
437 * o15.0.1.9
438 * - Create MCG with Invalid JoinState.FullMember != 1 : get ERR_REQ_INVALID
439 * o15.0.1.10 - can't check on a single client .
440 * o15.0.1.11:
441 * - Try to join into a MGID that exists with JoinState=SendOnlyMember -
442 *   see that it updates JoinState. What is the routing change?
443 * - We can not check simple join since we have only one tester (for now)
444 * o15.0.1.12:
445 * - The last join should have a special treatment in the SA (sender only)
446 *   but what is it ?
447 * o15.0.1.13:
448 * - Try joining with wrong rate - ERR_REQ_INVALID
449 * o15.0.1.14:
450 * - Try partial delete - actually updating the join state. check it.
451 * - Register by InformInfo flow to receive trap 67 on MCG delete.
452 * - Try full delete (JoinState and should be 0)
453 * - Wait for trap 67.
454 * - Try joining (not full mem) again to see the group was deleted.
455 *   (should fail - o15.0.1.13)
456 * o15.0.1.15:
457 * - Try deletion of the IPoIB MCG and get: ERR_REQ_INVALID
458 * o15.0.1.16:
459 * - Try GetTable with PortGUID wildcarded and get back some groups.
460 ***********************************************************************/
461
462/* The following macro can be used only within the osmt_run_mcast_flow() function */
463#define IS_IPOIB_MGID(p_mgid) \
464           ( !memcmp(&osm_ipoib_good_mgid,    (p_mgid), sizeof(osm_ipoib_good_mgid)) || \
465             !memcmp(&osm_ts_ipoib_good_mgid, (p_mgid), sizeof(osm_ts_ipoib_good_mgid)) )
466
467ib_api_status_t osmt_run_mcast_flow(IN osmtest_t * const p_osmt)
468{
469	char gid_str[INET6_ADDRSTRLEN];
470	char gid_str2[INET6_ADDRSTRLEN];
471	ib_api_status_t status;
472	ib_member_rec_t mc_req_rec;
473	ib_member_rec_t *p_mc_res;
474	ib_sa_mad_t res_sa_mad;
475	uint64_t comp_mask = 0;
476	ib_net64_t remote_port_guid = 0x0;
477	cl_qmap_t *p_mgrp_mlid_tbl;
478	osmtest_mgrp_t *p_mgrp;
479	ib_gid_t special_mgid, tmp_mgid, proxy_mgid;
480	ib_net16_t invalid_mlid = 0x0;
481	ib_net16_t max_mlid = cl_hton16(0xFFFE), tmp_mlid;
482	boolean_t ReachedMlidLimit = FALSE;
483	int start_cnt = 0, cnt, middle_cnt = 0, end_cnt = 0;
484	int start_ipoib_cnt = 0, end_ipoib_cnt = 0;
485	int mcg_outside_test_cnt = 0, fail_to_delete_mcg = 0;
486	osmtest_req_context_t context;
487	ib_node_record_t *p_rec;
488	uint32_t num_recs = 0, i;
489	uint8_t mtu_phys = 0, rate_phys = 0;
490	cl_map_t test_created_mlids;	/* List of all mlids created in this test */
491	ib_member_rec_t *p_recvd_rec;
492	boolean_t got_error = FALSE;
493
494	static ib_gid_t good_mgid = {
495		{
496		 0xFF, 0x12, 0xA0, 0x1C,
497		 0xFE, 0x80, 0x00, 0x00,
498		 0x00, 0x00, 0x00, 0x00,
499		 0x12, 0x34, 0x56, 0x78}
500	};
501	static ib_gid_t osm_ipoib_mgid = {
502		{
503		 0xff,		/* multicast field */
504		 0x12,		/* scope */
505		 0x40, 0x1b,	/* IPv4 signature */
506		 0xff, 0xff,	/* 16 bits of P_Key (to be filled in) */
507		 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* 48 bits of zeros */
508		 0xff, 0xff, 0xff, 0xee,	/* 32 bit IPv4 broadcast address */
509		 },
510	};
511	static ib_gid_t osm_ts_ipoib_good_mgid = {
512		{
513		 0xff,		/* multicast field */
514		 0x12,		/* non-permanent bit,scope */
515		 0x40, 0x1b,	/* IPv4 signature */
516		 0xff, 0xff,	/* 16 bits of P_Key (to be filled in) */
517		 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* 48 bits of zeros */
518		 0x00, 0x00, 0x00, 0x01,	/* 32 bit IPv4 broadcast address */
519		 },
520	};
521	static ib_gid_t osm_ipoib_good_mgid = {
522		{
523		 0xff,		/* multicast field */
524		 0x12,		/* non-permanent bit,scope */
525		 0x40, 0x1b,	/* IPv4 signature */
526		 0xff, 0xff,	/* 16 bits of P_Key (to be filled in) */
527		 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* 48 bits of zeros */
528		 0xff, 0xff, 0xff, 0xff,	/* 32 bit IPv4 broadcast address */
529		 },
530	};
531	static ib_gid_t osm_link_local_mgid = {
532		{
533		 0xFF, 0x02, 0x00, 0x00,
534		 0x00, 0x00, 0x00, 0x00,
535		 0x00, 0x00, 0x00, 0x00,
536		 0x00, 0x00, 0x00, 0x01},
537	};
538
539	OSM_LOG_ENTER(&p_osmt->log);
540
541	OSM_LOG(&p_osmt->log, OSM_LOG_INFO, "GetTable of all current MCGs...\n");
542	status = osmt_query_mcast(p_osmt);
543	if (status != IB_SUCCESS) {
544		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 2FF "
545			"GetTable of all records has failed!\n");
546		goto Exit;
547	}
548
549	/* Initialize the test_created_mgrps map */
550	cl_map_construct(&test_created_mlids);
551	cl_map_init(&test_created_mlids, 1000);
552
553	p_mgrp_mlid_tbl = &p_osmt->exp_subn.mgrp_mlid_tbl;
554	osmt_init_mc_query_rec(p_osmt, &mc_req_rec);
555
556	p_mc_res = ib_sa_mad_get_payload_ptr(&res_sa_mad);
557
558	/* Only when we are on single mode check flow - do the count comparison, otherwise skip */
559	if (p_osmt->opt.mmode == 1 || p_osmt->opt.mmode == 3) {
560		start_cnt = cl_qmap_count(p_mgrp_mlid_tbl);
561		OSM_LOG(&p_osmt->log, OSM_LOG_INFO, "(start): "
562			"Number of MC Records found in SA DB is %d\n",
563			start_cnt);
564	}
565
566	/* This flow is being added due to bug discovered using SilverStorm stack -
567	   The bug was initializing MCast with MTU & RATE min values that do
568	   not match the subnet capability, even though that OpenSM
569	   reponds with the correct value it does not store it in the MCG.
570	   We want the check a join request to already existing group (ipoib)
571	   without using MTU or RATE then getting response from OpenSM with
572	   the correct values then join again with them and get IB_SUCCESS
573	   all the way
574	 */
575
576	/* First validate IPoIB exist in the SA DB */
577	p_mgrp = (osmtest_mgrp_t *) cl_qmap_head(p_mgrp_mlid_tbl);
578	/* scan all available multicast groups in the DB and fill in the table */
579	while (p_mgrp != (osmtest_mgrp_t *) cl_qmap_end(p_mgrp_mlid_tbl)) {
580		/* search for ipoib mgid */
581		if (IS_IPOIB_MGID(&p_mgrp->mcmember_rec.mgid)) {
582			start_ipoib_cnt++;
583		} else {
584			OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
585				"Non-IPoIB MC Groups exist: mgid=%s\n",
586				inet_ntop(AF_INET6,
587					  p_mgrp->mcmember_rec.mgid.raw,
588					  gid_str, sizeof gid_str));
589			mcg_outside_test_cnt++;
590		}
591
592		p_mgrp = (osmtest_mgrp_t *) cl_qmap_next(&p_mgrp->map_item);
593	}
594
595	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
596		"Found %d non-IPoIB MC Groups\n", mcg_outside_test_cnt);
597
598	if (start_ipoib_cnt) {
599		/* o15-0.2.4 - Check a join request to already created MCG */
600		OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
601			"Found IPoIB MC Group, so we run SilverStorm Bug Flow...\n");
602		/* Try to join first like IPoIB of SilverStorm */
603		memcpy(&mc_req_rec.mgid, &osm_ipoib_good_mgid,
604		       sizeof(ib_gid_t));
605		/* Request Join */
606		ib_member_set_join_state(&mc_req_rec,
607					 IB_MC_REC_STATE_FULL_MEMBER);
608		comp_mask =
609		    IB_MCR_COMPMASK_MGID | IB_MCR_COMPMASK_PORT_GID |
610		    IB_MCR_COMPMASK_JOIN_STATE;
611
612		status = osmt_send_mcast_request(p_osmt, 0xff,	/* User Defined query Set */
613						 &mc_req_rec,
614						 comp_mask, &res_sa_mad);
615
616		OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
617			"Joining an existing IPoIB multicast group\n");
618		OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
619			"Sent Join request with :\n\t\tport_gid=%s, mgid=%s\n"
620			"\t\tjoin state= 0x%x, response is : %s\n",
621			inet_ntop(AF_INET6, mc_req_rec.port_gid.raw,
622				  gid_str, sizeof gid_str),
623			inet_ntop(AF_INET6, mc_req_rec.mgid.raw,
624				  gid_str2, sizeof gid_str2),
625			(mc_req_rec.scope_state & 0x0F),
626			ib_get_err_str(status));
627		if (status != IB_SUCCESS) {
628			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02B3: "
629				"Failed joining existing IPoIB MCGroup - got %s\n",
630				ib_get_err_str(status));
631			goto Exit;
632		}
633		/* Check MTU & Rate Value and resend with SA suggested values */
634		p_mc_res = ib_sa_mad_get_payload_ptr(&res_sa_mad);
635
636		/* Prepare the mc_req_rec for the rest of the flow */
637		osmt_init_mc_query_rec(p_osmt, &mc_req_rec);
638		/*
639		   We simulate the same situation as in SilverStorm - a response with the
640		   exact RATE & MTU as the SA responded with. Actually the query
641		   has included some more fields but we know that problem was
642		   genereated by the RATE
643		 */
644		OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
645			"Received attributes of MCG : \n\t\tMTU=0x%02X, RATE=0x%02X\n",
646			p_mc_res->mtu, p_mc_res->rate);
647
648		mc_req_rec.mtu = p_mc_res->mtu;
649		mc_req_rec.rate = p_mc_res->rate;
650		/* Set feasible mtu & rate that will allow check the
651		   exact statement of OpenSM */
652		mtu_phys = p_mc_res->mtu;
653		rate_phys = p_mc_res->rate;
654
655		memcpy(&mc_req_rec.mgid, &osm_ipoib_good_mgid,
656		       sizeof(ib_gid_t));
657		/* Request Join */
658		ib_member_set_join_state(&mc_req_rec,
659					 IB_MC_REC_STATE_FULL_MEMBER);
660		comp_mask =
661		    IB_MCR_COMPMASK_MGID | IB_MCR_COMPMASK_PORT_GID |
662		    IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_MTU_SEL |
663		    IB_MCR_COMPMASK_MTU | IB_MCR_COMPMASK_RATE_SEL |
664		    IB_MCR_COMPMASK_RATE;
665
666		OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
667			"Sending attributes of MCG : \n\t\tMTU=0x%02X, RATE=0x%02X\n",
668			mc_req_rec.mtu, mc_req_rec.rate);
669		status = osmt_send_mcast_request(p_osmt, 0xff,	/* User Defined query */
670						 &mc_req_rec,
671						 comp_mask, &res_sa_mad);
672		OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
673			"Sent Join request using response values, response is : %s\n",
674			ib_get_err_str(status));
675		if (status != IB_SUCCESS) {
676			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02EF: "
677				"Query as Full Member of already existing "
678				"ipoib group gid %s has failed\n",
679				inet_ntop(AF_INET6, mc_req_rec.mgid.raw,
680					  gid_str, sizeof gid_str));
681			goto Exit;
682		}
683		/* We do not want to leave the MCG since its IPoIB */
684	}
685
686  /**************************************************************************/
687	/* Check Get with invalid mlid */
688
689	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
690		"Checking Get with invalid mlid...\n");
691	/* Request Get */
692	ib_member_set_join_state(&mc_req_rec, IB_MC_REC_STATE_FULL_MEMBER);
693	mc_req_rec.mlid = invalid_mlid;
694	comp_mask = IB_MCR_COMPMASK_MLID;
695
696	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
697	status = osmt_send_mcast_request(p_osmt, 0xee,	/* User Defined query Get */
698					 &mc_req_rec, comp_mask, &res_sa_mad);
699	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
700
701	if (status == IB_SUCCESS) {
702		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 2E0 "
703			"SubnAdmGet with invalid mlid 0x%x succeeded\n",
704			cl_ntoh16(mc_req_rec.mlid));
705		status = IB_ERROR;
706		goto Exit;
707	}
708
709	/* Prepare the mc_req_rec for the rest of the flow */
710	osmt_init_mc_query_rec(p_osmt, &mc_req_rec);
711  /**************************************************************************/
712	/* Check Get with invalid port guid */
713
714	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
715		"Checking Get with invalid port guid (0x0) but valid interface ID : 0x%"
716		PRIx64 "...\n",
717		cl_ntoh64(mc_req_rec.port_gid.unicast.interface_id));
718
719	/* Request Get */
720	ib_member_set_join_state(&mc_req_rec, IB_MC_REC_STATE_FULL_MEMBER);
721	memset(&mc_req_rec.port_gid.unicast.interface_id, 0,
722	       sizeof(ib_net64_t));
723	comp_mask = IB_MCR_COMPMASK_GID;
724
725	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
726	status = osmt_send_mcast_request(p_osmt, 0xee,	/* User Defined query Get */
727					 &mc_req_rec, comp_mask, &res_sa_mad);
728	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
729
730	if (status == IB_SUCCESS) {
731		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 2E4 "
732			"SubnAdmGet with invalid port guid succeeded\n");
733		status = IB_ERROR;
734		goto Exit;
735	}
736
737	/* Prepare the mc_req_rec for the rest of the flow */
738	osmt_init_mc_query_rec(p_osmt, &mc_req_rec);
739  /**************************************************************************/
740
741	/* o15.0.1.3:  */
742	/* - Request Join with insufficient comp_mask */
743
744	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
745		"Checking Join with insufficient comp mask qkey & pkey (o15.0.1.3)...\n");
746
747	/* no MGID */
748	memset(&mc_req_rec.mgid, 0, sizeof(ib_gid_t));
749	/* Request Join */
750	ib_member_set_join_state(&mc_req_rec, IB_MC_REC_STATE_FULL_MEMBER);
751
752	comp_mask = IB_MCR_COMPMASK_MGID | IB_MCR_COMPMASK_PORT_GID |
753	    /* IB_MCR_COMPMASK_QKEY |  */
754	    /* IB_MCR_COMPMASK_PKEY | intentionaly missed to raise the error */
755	    IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
756	    IB_MCR_COMPMASK_RATE_SEL | IB_MCR_COMPMASK_RATE;
757
758	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
759	status = osmt_send_mcast_request(p_osmt, 1,
760					 &mc_req_rec, comp_mask, &res_sa_mad);
761	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
762
763	if (status != IB_REMOTE_ERROR ||
764	    ((ib_net16_t) (res_sa_mad.status & IB_SMP_STATUS_MASK)) !=
765	    IB_SA_MAD_STATUS_INSUF_COMPS) {
766		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02EE: "
767			"Expectedd REMOTE ERROR IB_SA_MAD_STATUS_INSUF_COMPS got:%s/%s\n",
768			ib_get_err_str(status),
769			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
770		status = IB_ERROR;
771		goto Exit;
772	}
773
774	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
775		"Checking Join with insufficient comp mask - sl (15.0.1.3)...\n");
776
777	/* no MGID */
778	memset(&mc_req_rec.mgid, 0, sizeof(ib_gid_t));
779	/* Request Join */
780	ib_member_set_join_state(&mc_req_rec, IB_MC_REC_STATE_FULL_MEMBER);
781
782	comp_mask =
783	    IB_MCR_COMPMASK_MGID |
784	    IB_MCR_COMPMASK_PORT_GID |
785	    IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY |
786	    /* IB_MCR_COMPMASK_SL |  */
787	    IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
788	    IB_MCR_COMPMASK_RATE_SEL | IB_MCR_COMPMASK_RATE;
789
790	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
791	status = osmt_send_mcast_request(p_osmt, 1,
792					 &mc_req_rec, comp_mask, &res_sa_mad);
793	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
794
795	if (status != IB_REMOTE_ERROR ||
796	    ((ib_net16_t) (res_sa_mad.status & IB_SMP_STATUS_MASK)) !=
797	    IB_SA_MAD_STATUS_INSUF_COMPS) {
798		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02ED: "
799			"Expectedd REMOTE ERROR IB_SA_MAD_STATUS_INSUF_COMPS got:%s/%s\n",
800			ib_get_err_str(status),
801			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
802		status = IB_ERROR;
803		goto Exit;
804	}
805
806	osmt_init_mc_query_rec(p_osmt, &mc_req_rec);
807	/* no MGID */
808	memset(&mc_req_rec.mgid, 0, sizeof(ib_gid_t));
809
810	mc_req_rec.mgid.raw[15] = 0x01;
811
812	p_mc_res = ib_sa_mad_get_payload_ptr(&res_sa_mad);
813
814	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
815		"Checking Join with insufficient comp mask - flow label (o15.0.1.3)...\n");
816
817	/* Request Join */
818	ib_member_set_join_state(&mc_req_rec, IB_MC_REC_STATE_FULL_MEMBER);
819
820	comp_mask =
821	    IB_MCR_COMPMASK_MGID |
822	    IB_MCR_COMPMASK_PORT_GID |
823	    IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL |
824	    /* IB_MCR_COMPMASK_FLOW | intentionaly missed to raise the error */
825	    IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
826	    IB_MCR_COMPMASK_RATE_SEL | IB_MCR_COMPMASK_RATE;
827
828	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
829	status = osmt_send_mcast_request(p_osmt, 1,
830					 &mc_req_rec, comp_mask, &res_sa_mad);
831	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
832
833	if (status != IB_REMOTE_ERROR ||
834	    ((ib_net16_t) (res_sa_mad.status & IB_SMP_STATUS_MASK)) !=
835	    IB_SA_MAD_STATUS_INSUF_COMPS) {
836		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02EC: "
837			"Expected REMOTE ERROR IB_SA_MAD_STATUS_INSUF_COMPS got:%s/%s\n",
838			ib_get_err_str(status),
839			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
840		status = IB_ERROR;
841		goto Exit;
842	}
843
844	osmt_init_mc_query_rec(p_osmt, &mc_req_rec);
845
846	p_mc_res = ib_sa_mad_get_payload_ptr(&res_sa_mad);
847
848	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
849		"Checking Join with insufficient comp mask - tclass (o15.0.1.3)...\n");
850
851	/* Request Join */
852	ib_member_set_join_state(&mc_req_rec, IB_MC_REC_STATE_FULL_MEMBER);
853
854	comp_mask =
855	    IB_MCR_COMPMASK_MGID |
856	    IB_MCR_COMPMASK_PORT_GID |
857	    IB_MCR_COMPMASK_QKEY |
858	    IB_MCR_COMPMASK_PKEY |
859	    IB_MCR_COMPMASK_SL |
860	    IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE |
861	    /* IB_MCR_COMPMASK_TCLASS |  Intentionally missed to raise an error */
862	    IB_MCR_COMPMASK_RATE_SEL | IB_MCR_COMPMASK_RATE;
863
864	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
865	status = osmt_send_mcast_request(p_osmt, 1,
866					 &mc_req_rec, comp_mask, &res_sa_mad);
867	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
868
869	if (status != IB_REMOTE_ERROR ||
870	    ((ib_net16_t) (res_sa_mad.status & IB_SMP_STATUS_MASK)) !=
871	    IB_SA_MAD_STATUS_INSUF_COMPS) {
872		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02EA: "
873			"Expected REMOTE ERROR IB_SA_MAD_STATUS_INSUF_COMPS got:%s/%s\n",
874			ib_get_err_str(status),
875			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
876		status = IB_ERROR;
877		goto Exit;
878	}
879
880	osmt_init_mc_query_rec(p_osmt, &mc_req_rec);
881
882	p_mc_res = ib_sa_mad_get_payload_ptr(&res_sa_mad);
883
884	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
885		"Checking Join with insufficient comp mask - tclass qkey (o15.0.1.3)...\n");
886
887	/* no MGID */
888	/* memset(&mc_req_rec.mgid, 0, sizeof(ib_gid_t)); */
889	/* Request Join */
890	ib_member_set_join_state(&mc_req_rec, IB_MC_REC_STATE_FULL_MEMBER);
891
892	comp_mask = IB_MCR_COMPMASK_MGID | IB_MCR_COMPMASK_PORT_GID |
893	    /* IB_MCR_COMPMASK_QKEY | intentionaly missed to raise the error */
894	    IB_MCR_COMPMASK_PKEY |
895	    IB_MCR_COMPMASK_SL |
896	    IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE |
897	    /* IB_MCR_COMPMASK_TCLASS |  intentionaly missed to raise the error */
898	    IB_MCR_COMPMASK_RATE_SEL | IB_MCR_COMPMASK_RATE;
899
900	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
901	status = osmt_send_mcast_request(p_osmt, 1,
902					 &mc_req_rec, comp_mask, &res_sa_mad);
903	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
904
905	if (status != IB_REMOTE_ERROR ||
906	    ((ib_net16_t) (res_sa_mad.status & IB_SMP_STATUS_MASK)) !=
907	    IB_SA_MAD_STATUS_INSUF_COMPS) {
908		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02E9: "
909			"Expected REMOTE ERROR IB_SA_MAD_STATUS_INSUF_COMPS got:%s/%s\n",
910			ib_get_err_str(status),
911			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
912		status = IB_ERROR;
913		goto Exit;
914	}
915
916	/* o15.0.1.8: */
917	/* - Request join with irrelevant RATE : get a ERR_INSUFFICIENT_COMPONENTS */
918	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
919		"Checking Join with unrealistic rate (o15.0.1.8)...\n");
920
921	/* impossible requested rate */
922	mc_req_rec.rate =
923	    IB_LINK_WIDTH_ACTIVE_12X | IB_PATH_SELECTOR_GREATER_THAN << 6;
924
925	comp_mask = IB_MCR_COMPMASK_GID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
926	    IB_MCR_COMPMASK_RATE_SEL | IB_MCR_COMPMASK_RATE;
927
928	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
929	status = osmt_send_mcast_request(p_osmt, 1,
930					 &mc_req_rec, comp_mask, &res_sa_mad);
931	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
932
933	if (status != IB_REMOTE_ERROR ||
934	    res_sa_mad.status != IB_SA_MAD_STATUS_REQ_INVALID) {
935		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0207: "
936			"Expected REMOTE ERROR IB_SA_MAD_STATUS_REQ_INVALID got:%s/%s\n",
937			ib_get_err_str(status),
938			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
939		status = IB_ERROR;
940		goto Exit;
941	}
942
943	/* Check Valid value which is unreasonable now */
944	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
945		"Checking Join with unrealistic rate 120GB (o15.0.1.8)...\n");
946
947	/* impossible requested rate */
948	mc_req_rec.rate =
949	    IB_PATH_RECORD_RATE_120_GBS | IB_PATH_SELECTOR_GREATER_THAN << 6;
950
951	comp_mask = IB_MCR_COMPMASK_GID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
952	    IB_MCR_COMPMASK_RATE_SEL | IB_MCR_COMPMASK_RATE;
953
954	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
955	status = osmt_send_mcast_request(p_osmt, 1,
956					 &mc_req_rec, comp_mask, &res_sa_mad);
957	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
958
959	if (status != IB_REMOTE_ERROR ||
960	    res_sa_mad.status != IB_SA_MAD_STATUS_REQ_INVALID) {
961		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0208: "
962			"Expected REMOTE ERROR IB_SA_MAD_STATUS_REQ_INVALID got:%s/%s\n",
963			ib_get_err_str(status),
964			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
965		status = IB_ERROR;
966		goto Exit;
967	}
968
969	/* Check Valid value which is unreasonable now */
970	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
971		"Checking Join with less than min rate 2.5GB (o15.0.1.8)...\n");
972
973	/* impossible requested rate */
974	mc_req_rec.rate =
975	    IB_PATH_RECORD_RATE_2_5_GBS | IB_PATH_SELECTOR_LESS_THAN << 6;
976
977	comp_mask = IB_MCR_COMPMASK_GID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
978	    IB_MCR_COMPMASK_RATE_SEL | IB_MCR_COMPMASK_RATE;
979
980	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
981	status = osmt_send_mcast_request(p_osmt, 1,
982					 &mc_req_rec, comp_mask, &res_sa_mad);
983	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
984
985	if (status != IB_REMOTE_ERROR ||
986	    res_sa_mad.status != IB_SA_MAD_STATUS_REQ_INVALID) {
987		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02AB: "
988			"Expected REMOTE ERROR IB_SA_MAD_STATUS_REQ_INVALID got:%s/%s\n",
989			ib_get_err_str(status),
990			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
991		status = IB_ERROR;
992		goto Exit;
993	}
994
995	/* Checking above max value of MTU which is impossible */
996	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
997		"Checking Join with unrealistic mtu : \n\t\tmore than 4096 -"
998		" max (o15.0.1.8)...\n");
999
1000	/* impossible requested mtu */
1001	mc_req_rec.mtu = IB_MTU_LEN_4096 | IB_PATH_SELECTOR_GREATER_THAN << 6;
1002
1003	comp_mask = IB_MCR_COMPMASK_GID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
1004	    IB_MCR_COMPMASK_MTU_SEL | IB_MCR_COMPMASK_MTU;
1005
1006	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
1007	status = osmt_send_mcast_request(p_osmt, 1,
1008					 &mc_req_rec, comp_mask, &res_sa_mad);
1009	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
1010
1011	if (status != IB_REMOTE_ERROR ||
1012	    res_sa_mad.status != IB_SA_MAD_STATUS_REQ_INVALID) {
1013		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02AC: "
1014			"Expected REMOTE ERROR IB_SA_MAD_STATUS_REQ_INVALID got:%s/%s\n",
1015			ib_get_err_str(status),
1016			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad))
1017		    );
1018		status = IB_ERROR;
1019		goto Exit;
1020	}
1021
1022	/* Checking below min value of MTU which is impossible */
1023	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1024		"Checking Join with unrealistic mtu : \n\t\tless than 256 -"
1025		" min (o15.0.1.8)...\n");
1026
1027	/* impossible requested mtu */
1028	mc_req_rec.mtu = IB_MTU_LEN_256 | IB_PATH_SELECTOR_LESS_THAN << 6;
1029
1030	comp_mask = IB_MCR_COMPMASK_GID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
1031	    IB_MCR_COMPMASK_MTU_SEL | IB_MCR_COMPMASK_MTU;
1032
1033	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
1034	status = osmt_send_mcast_request(p_osmt, 1,
1035					 &mc_req_rec, comp_mask, &res_sa_mad);
1036	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
1037
1038	if (status != IB_REMOTE_ERROR ||
1039	    res_sa_mad.status != IB_SA_MAD_STATUS_REQ_INVALID) {
1040		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02AD: "
1041			"Expected REMOTE ERROR IB_SA_MAD_STATUS_REQ_INVALID got:%s/%s\n",
1042			ib_get_err_str(status),
1043			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1044		status = IB_ERROR;
1045		goto Exit;
1046	}
1047
1048	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1049		"Checking Join with unrealistic mtu (o15.0.1.8)...\n");
1050
1051	/* impossible requested mtu */
1052	mc_req_rec.mtu = 0x6 | IB_PATH_SELECTOR_GREATER_THAN << 6;
1053
1054	comp_mask = IB_MCR_COMPMASK_GID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
1055	    IB_MCR_COMPMASK_MTU_SEL | IB_MCR_COMPMASK_MTU;
1056
1057	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
1058	status = osmt_send_mcast_request(p_osmt, 1,
1059					 &mc_req_rec, comp_mask, &res_sa_mad);
1060	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
1061
1062	if (status != IB_REMOTE_ERROR ||
1063	    res_sa_mad.status != IB_SA_MAD_STATUS_REQ_INVALID) {
1064		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02AE: "
1065			"Expected REMOTE ERROR IB_SA_MAD_STATUS_REQ_INVALID got:%s/%s\n",
1066			ib_get_err_str(status),
1067			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1068		status = IB_ERROR;
1069		goto Exit;
1070	}
1071#if 0
1072	/* Currently PacketLifeTime isn't checked in opensm */
1073	/* Check PacketLifeTime as 0 */
1074	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1075		"Checking Create with unrealistic packet life value less than 0 (o15.0.1.8)...\n");
1076
1077	/* impossible requested packet life */
1078	mc_req_rec.pkt_life = 0 | IB_PATH_SELECTOR_LESS_THAN << 6;
1079
1080	comp_mask = IB_MCR_COMPMASK_GID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
1081	    IB_MCR_COMPMASK_LIFE | IB_MCR_COMPMASK_LIFE_SEL;
1082
1083	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
1084	status = osmt_send_mcast_request(p_osmt, 1,
1085					 &mc_req_rec, comp_mask, &res_sa_mad);
1086	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
1087
1088	if (status != IB_REMOTE_ERROR ||
1089	    res_sa_mad.status != IB_SA_MAD_STATUS_REQ_INVALID) {
1090		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02AF: "
1091			"Expected REMOTE ERROR IB_SA_MAD_STATUS_REQ_INVALID got:%s/%s\n",
1092			ib_get_err_str(status),
1093			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1094		status = IB_ERROR;
1095		goto Exit;
1096	}
1097#endif
1098
1099	/* o15.0.1.4:  */
1100	/* - Create an MGID by asking for a join with MGID = 0 */
1101	/*   providing P_Key, Q_Key, SL, FlowLabel, Tclass. */
1102
1103	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1104		"Checking Create given MGID=0 skip service level (o15.0.1.4)...\n");
1105
1106	osmt_init_mc_query_rec(p_osmt, &mc_req_rec);
1107
1108	p_mc_res = ib_sa_mad_get_payload_ptr(&res_sa_mad);
1109
1110	/* no MGID */
1111	memset(&mc_req_rec.mgid, 0, sizeof(ib_gid_t));
1112	/* Request Join */
1113	ib_member_set_join_state(&mc_req_rec, IB_MC_REC_STATE_FULL_MEMBER);
1114
1115	comp_mask =
1116	    IB_MCR_COMPMASK_MGID |
1117	    IB_MCR_COMPMASK_PORT_GID |
1118	    IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY |
1119	    /* IB_MCR_COMPMASK_SL | Intentionally missed */
1120	    IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
1121	    IB_MCR_COMPMASK_RATE_SEL | IB_MCR_COMPMASK_RATE;
1122
1123	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
1124	status = osmt_send_mcast_request(p_osmt, 1,
1125					 &mc_req_rec, comp_mask, &res_sa_mad);
1126	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
1127
1128	if (status != IB_REMOTE_ERROR ||
1129	    ((ib_net16_t) (res_sa_mad.status & IB_SMP_STATUS_MASK)) !=
1130	    IB_SA_MAD_STATUS_INSUF_COMPS) {
1131		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02A8: "
1132			"Expected REMOTE ERROR IB_SA_MAD_STATUS_INSUF_COMPS got:%s/%s\n",
1133			ib_get_err_str(status),
1134			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1135		status = IB_ERROR;
1136		goto Exit;
1137	}
1138
1139	/* Check that no same MCG in the SMDB */
1140	status = osmt_query_mcast(p_osmt);
1141
1142	if (status != IB_SUCCESS) {
1143		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02AA: "
1144			"Could not get all MC Records in subnet, got:%s/%s\n",
1145			ib_get_err_str(status),
1146			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1147		goto Exit;
1148	}
1149
1150	/* Only when we are on single mode check flow - do the count comparison, otherwise skip */
1151	if (p_osmt->opt.mmode == 1 || p_osmt->opt.mmode == 3) {
1152		middle_cnt = cl_qmap_count(&p_osmt->exp_subn.mgrp_mlid_tbl);
1153		OSM_LOG(&p_osmt->log, OSM_LOG_INFO, "(post false create): "
1154			"Number of MC Records found in SA DB is %d\n",
1155			middle_cnt);
1156		if (middle_cnt != start_cnt) {
1157			OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1158				"Got different number of records stored in SA DB (before any creation)\n"
1159				"Instead of %d got %d\n", start_cnt,
1160				middle_cnt);
1161		}
1162	}
1163
1164	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1165		"Checking Create given MGID=0 skip Qkey and Pkey (o15.0.1.4)...\n");
1166
1167	osmt_init_mc_query_rec(p_osmt, &mc_req_rec);
1168
1169	p_mc_res = ib_sa_mad_get_payload_ptr(&res_sa_mad);
1170
1171	/* no MGID */
1172	memset(&mc_req_rec.mgid, 0, sizeof(ib_gid_t));
1173	/* Request Join */
1174	ib_member_set_join_state(&mc_req_rec, IB_MC_REC_STATE_FULL_MEMBER);
1175
1176	comp_mask = IB_MCR_COMPMASK_MGID | IB_MCR_COMPMASK_PORT_GID |
1177	    /* IB_MCR_COMPMASK_QKEY | */
1178	    /* IB_MCR_COMPMASK_PKEY | Intentionally missed */
1179	    IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
1180	    IB_MCR_COMPMASK_RATE_SEL | IB_MCR_COMPMASK_RATE;
1181
1182	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
1183	status = osmt_send_mcast_request(p_osmt, 1,
1184					 &mc_req_rec, comp_mask, &res_sa_mad);
1185	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
1186
1187	if (status != IB_REMOTE_ERROR ||
1188	    ((ib_net16_t) (res_sa_mad.status & IB_SMP_STATUS_MASK)) !=
1189	    IB_SA_MAD_STATUS_INSUF_COMPS) {
1190		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02A7: "
1191			"Expected REMOTE ERROR IB_SA_MAD_STATUS_INSUF_COMPS got:%s/%s\n",
1192			ib_get_err_str(status),
1193			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1194		status = IB_ERROR;
1195		goto Exit;
1196	}
1197
1198	/* Bad Query o15.0.1.4 */
1199
1200	status = osmt_query_mcast(p_osmt);
1201
1202	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1203		"Checking Create given MGID=0 skip TClass (o15.0.1.4)...\n");
1204
1205	osmt_init_mc_query_rec(p_osmt, &mc_req_rec);
1206
1207	p_mc_res = ib_sa_mad_get_payload_ptr(&res_sa_mad);
1208
1209	/* no MGID */
1210	memset(&mc_req_rec.mgid, 0, sizeof(ib_gid_t));
1211	/* Request Join */
1212	ib_member_set_join_state(&mc_req_rec, IB_MC_REC_STATE_FULL_MEMBER);
1213
1214	comp_mask =
1215	    IB_MCR_COMPMASK_MGID |
1216	    IB_MCR_COMPMASK_PORT_GID |
1217	    IB_MCR_COMPMASK_QKEY |
1218	    IB_MCR_COMPMASK_PKEY |
1219	    IB_MCR_COMPMASK_SL |
1220	    IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE |
1221	    /* IB_MCR_COMPMASK_TCLASS |  Intentionally missed */
1222	    /* all above are required */
1223	    IB_MCR_COMPMASK_RATE_SEL | IB_MCR_COMPMASK_RATE;
1224
1225	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
1226	status = osmt_send_mcast_request(p_osmt, 1,
1227					 &mc_req_rec, comp_mask, &res_sa_mad);
1228	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
1229
1230	if (status != IB_REMOTE_ERROR ||
1231	    ((ib_net16_t) (res_sa_mad.status & IB_SMP_STATUS_MASK)) !=
1232	    IB_SA_MAD_STATUS_INSUF_COMPS) {
1233		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02A6: "
1234			"Expected REMOTE ERROR IB_SA_MAD_STATUS_INSUF_COMPS got:%s/%s\n",
1235			ib_get_err_str(status),
1236			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1237		status = IB_ERROR;
1238		goto Exit;
1239	}
1240
1241	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1242		"Checking Create given MGID=0 valid Set several options :\n\t\t"
1243		"First above min RATE, Second less than max RATE\n\t\t"
1244		"Third above min MTU, Second less than max MTU\n\t\t"
1245		"Fifth exact MTU & RATE feasible, Sixth exact RATE feasible\n\t\t"
1246		"Seventh exact MTU feasible (o15.0.1.4)...\n");
1247
1248	/* Good Flow - mgid is 0 while giving all required fields for join : P_Key, Q_Key, SL, FlowLabel, Tclass */
1249
1250	mc_req_rec.rate =
1251	    IB_LINK_WIDTH_ACTIVE_1X | IB_PATH_SELECTOR_GREATER_THAN << 6;
1252
1253	comp_mask = IB_MCR_COMPMASK_MGID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
1254	    IB_MCR_COMPMASK_RATE_SEL | IB_MCR_COMPMASK_RATE;
1255
1256	status = osmt_send_mcast_request(p_osmt, 1,
1257					 &mc_req_rec, comp_mask, &res_sa_mad);
1258	if (status != IB_SUCCESS) {
1259		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02A5: "
1260			"Failed to create MCG for MGID=0 with higher than minimum RATE - got %s/%s\n",
1261			ib_get_err_str(status),
1262			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1263		goto Exit;
1264	}
1265
1266	/* Save the mlid created in test_created_mlids map */
1267	p_recvd_rec =
1268	    (ib_member_rec_t *) ib_sa_mad_get_payload_ptr(&res_sa_mad);
1269	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "created MGID:%s MLID:0x%04X\n",
1270		inet_ntop(AF_INET6, p_recvd_rec->mgid.raw, gid_str,
1271			  sizeof gid_str), cl_ntoh16(p_recvd_rec->mlid));
1272	cl_map_insert(&test_created_mlids, cl_ntoh16(p_recvd_rec->mlid),
1273		      p_recvd_rec);
1274
1275	/* Good Flow - mgid is 0 while giving all required fields for join : P_Key, Q_Key, SL, FlowLabel, Tclass */
1276
1277	mc_req_rec.rate =
1278	    IB_LINK_WIDTH_ACTIVE_12X | IB_PATH_SELECTOR_LESS_THAN << 6;
1279
1280	comp_mask = IB_MCR_COMPMASK_MGID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
1281	    IB_MCR_COMPMASK_RATE_SEL | IB_MCR_COMPMASK_RATE;
1282
1283	status = osmt_send_mcast_request(p_osmt, 1,
1284					 &mc_req_rec, comp_mask, &res_sa_mad);
1285	if (status != IB_SUCCESS) {
1286		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0211: "
1287			"Failed to create MCG for MGID=0 with less than highest RATE - got %s/%s\n",
1288			ib_get_err_str(status),
1289			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1290		goto Exit;
1291	}
1292
1293	/* Save the mlid created in test_created_mlids map */
1294	p_recvd_rec =
1295	    (ib_member_rec_t *) ib_sa_mad_get_payload_ptr(&res_sa_mad);
1296	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "Created MGID:%s MLID:0x%04X\n",
1297		inet_ntop(AF_INET6, p_recvd_rec->mgid.raw, gid_str,
1298			  sizeof gid_str), cl_ntoh16(p_recvd_rec->mlid));
1299	cl_map_insert(&test_created_mlids, cl_ntoh16(p_recvd_rec->mlid),
1300		      p_recvd_rec);
1301
1302	/* Good Flow - mgid is 0 while giving all required fields for join : P_Key, Q_Key, SL, FlowLabel, Tclass */
1303
1304	mc_req_rec.mtu = IB_MTU_LEN_4096 | IB_PATH_SELECTOR_LESS_THAN << 6;
1305
1306	comp_mask = IB_MCR_COMPMASK_MGID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
1307	    IB_MCR_COMPMASK_MTU_SEL | IB_MCR_COMPMASK_MTU;
1308
1309	status = osmt_send_mcast_request(p_osmt, 1,
1310					 &mc_req_rec, comp_mask, &res_sa_mad);
1311	if (status != IB_SUCCESS) {
1312		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0238: "
1313			"Failed to create MCG for MGID=0 with less than highest MTU - got %s/%s\n",
1314			ib_get_err_str(status),
1315			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1316		goto Exit;
1317	}
1318
1319	/* Save the mlid created in test_created_mlids map */
1320	p_recvd_rec =
1321	    (ib_member_rec_t *) ib_sa_mad_get_payload_ptr(&res_sa_mad);
1322	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "Created MGID:%s MLID:0x%04X\n",
1323		inet_ntop(AF_INET6, p_recvd_rec->mgid.raw, gid_str,
1324			  sizeof gid_str), cl_ntoh16(p_recvd_rec->mlid));
1325	cl_map_insert(&test_created_mlids, cl_ntoh16(p_recvd_rec->mlid),
1326		      p_recvd_rec);
1327
1328	/* Good Flow - mgid is 0 while giving all required fields for join : P_Key, Q_Key, SL, FlowLabel, Tclass */
1329	mc_req_rec.mtu = IB_MTU_LEN_256 | IB_PATH_SELECTOR_GREATER_THAN << 6;
1330
1331	comp_mask = IB_MCR_COMPMASK_MGID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
1332	    IB_MCR_COMPMASK_MTU_SEL | IB_MCR_COMPMASK_MTU;
1333
1334	status = osmt_send_mcast_request(p_osmt, 1,
1335					 &mc_req_rec, comp_mask, &res_sa_mad);
1336	if (status != IB_SUCCESS) {
1337		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0239: "
1338			"Failed to create MCG for MGID=0 with higher than lowest MTU - got %s/%s\n",
1339			ib_get_err_str(status),
1340			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1341		goto Exit;
1342	}
1343
1344	/* Save the mlid created in test_created_mlids map */
1345	p_recvd_rec =
1346	    (ib_member_rec_t *) ib_sa_mad_get_payload_ptr(&res_sa_mad);
1347	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "Created MGID:%s MLID:0x%04X\n",
1348		inet_ntop(AF_INET6, p_recvd_rec->mgid.raw, gid_str,
1349			  sizeof gid_str), cl_ntoh16(p_recvd_rec->mlid));
1350	cl_map_insert(&test_created_mlids, cl_ntoh16(p_recvd_rec->mlid),
1351		      p_recvd_rec);
1352
1353	/* Good Flow - mgid is 0 while giving all required fields for join : P_Key, Q_Key, SL, FlowLabel, Tclass */
1354	/* Using Exact feasible MTU & RATE */
1355
1356	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
1357		"Using Exact feasible MTU & RATE: "
1358		"MTU = 0x%02X, RATE = 0x%02X\n", mtu_phys, rate_phys);
1359
1360	mc_req_rec.mtu = mtu_phys;
1361	mc_req_rec.rate = rate_phys;
1362
1363	comp_mask = IB_MCR_COMPMASK_MGID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
1364	    IB_MCR_COMPMASK_MTU_SEL |
1365	    IB_MCR_COMPMASK_MTU |
1366	    IB_MCR_COMPMASK_RATE_SEL | IB_MCR_COMPMASK_RATE;
1367
1368	status = osmt_send_mcast_request(p_osmt, 1,
1369					 &mc_req_rec, comp_mask, &res_sa_mad);
1370
1371	if (status != IB_SUCCESS) {
1372		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0240: "
1373			"Failed to create MCG for MGID=0 with exact MTU & RATE - got %s/%s\n",
1374			ib_get_err_str(status),
1375			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1376		goto Exit;
1377	}
1378
1379	/* Save the mlid created in test_created_mlids map */
1380	p_recvd_rec =
1381	    (ib_member_rec_t *) ib_sa_mad_get_payload_ptr(&res_sa_mad);
1382	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "Created MGID:%s MLID:0x%04X\n",
1383		inet_ntop(AF_INET6, p_recvd_rec->mgid.raw, gid_str,
1384			  sizeof gid_str), cl_ntoh16(p_recvd_rec->mlid));
1385	cl_map_insert(&test_created_mlids, cl_ntoh16(p_recvd_rec->mlid),
1386		      p_recvd_rec);
1387
1388	/* Good Flow - mgid is 0 while giving all required fields for join : P_Key, Q_Key, SL, FlowLabel, Tclass */
1389	/* Using Exact feasible RATE */
1390
1391	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
1392		"Using Exact feasible RATE: 0x%02X\n", rate_phys);
1393
1394	mc_req_rec.rate = rate_phys;
1395
1396	comp_mask = IB_MCR_COMPMASK_MGID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
1397	    IB_MCR_COMPMASK_RATE_SEL | IB_MCR_COMPMASK_RATE;
1398
1399	status = osmt_send_mcast_request(p_osmt, 1,
1400					 &mc_req_rec, comp_mask, &res_sa_mad);
1401	if (status != IB_SUCCESS) {
1402		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0241: "
1403			"Failed to create MCG for MGID=0 with exact RATE - got %s/%s\n",
1404			ib_get_err_str(status),
1405			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1406		goto Exit;
1407	}
1408
1409	/* Save the mlid created in test_created_mlids map */
1410	p_recvd_rec =
1411	    (ib_member_rec_t *) ib_sa_mad_get_payload_ptr(&res_sa_mad);
1412	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "Created MGID:%s MLID:0x%04X\n",
1413		inet_ntop(AF_INET6, p_recvd_rec->mgid.raw, gid_str,
1414			  sizeof gid_str), cl_ntoh16(p_recvd_rec->mlid));
1415	cl_map_insert(&test_created_mlids, cl_ntoh16(p_recvd_rec->mlid),
1416		      p_recvd_rec);
1417
1418	/* Good Flow - mgid is 0 while giving all required fields for join : P_Key, Q_Key, SL, FlowLabel, Tclass */
1419	/* Using Exact feasible MTU */
1420
1421	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
1422		"Using Exact feasible MTU: 0x%02X\n", mtu_phys);
1423
1424	mc_req_rec.mtu = mtu_phys;
1425
1426	comp_mask = IB_MCR_COMPMASK_MGID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
1427	    IB_MCR_COMPMASK_MTU_SEL | IB_MCR_COMPMASK_MTU;
1428
1429	status = osmt_send_mcast_request(p_osmt, 1,
1430					 &mc_req_rec, comp_mask, &res_sa_mad);
1431	if (status != IB_SUCCESS) {
1432		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0242: "
1433			"Failed to create MCG for MGID=0 with exact MTU - got %s/%s\n",
1434			ib_get_err_str(status),
1435			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1436		goto Exit;
1437	}
1438
1439	/* Save the mlid created in test_created_mlids map */
1440	p_recvd_rec =
1441	    (ib_member_rec_t *) ib_sa_mad_get_payload_ptr(&res_sa_mad);
1442	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "Created MGID:%s MLID:0x%04X\n",
1443		inet_ntop(AF_INET6, p_recvd_rec->mgid.raw, gid_str,
1444			  sizeof gid_str), cl_ntoh16(p_recvd_rec->mlid));
1445	cl_map_insert(&test_created_mlids, cl_ntoh16(p_recvd_rec->mlid),
1446		      p_recvd_rec);
1447
1448	/* o15.0.1.5: */
1449	/* - Check the returned MGID is valid. (p 804) */
1450	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1451		"Validating resulting MGID (o15.0.1.5)...\n");
1452	/* prefix 0xFF1 Scope 0xA01B */
1453	/* Since we did not directly specified SCOPE in comp mask
1454	   we should get the comp mask that is link-local scope */
1455	if ((p_mc_res->mgid.multicast.header[0] != 0xFF) ||
1456	    (p_mc_res->mgid.multicast.header[1] != 0x12) ||
1457	    (p_mc_res->mgid.multicast.raw_group_id[0] != 0xA0) ||
1458	    (p_mc_res->mgid.multicast.raw_group_id[1] != 0x1B)) {
1459		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0209: "
1460			"Validating MGID failed. MGID:%s\n",
1461			inet_ntop(AF_INET6, p_mc_res->mgid.raw, gid_str,
1462				  sizeof gid_str));
1463		status = IB_ERROR;
1464		goto Exit;
1465	}
1466
1467	/* Good Flow - mgid is 0 while giving all required fields for join : P_Key, Q_Key, SL, FlowLabel, Tclass */
1468	/* Using feasible GREATER_THAN 0 packet lifitime */
1469	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1470		"Checking Create given MGID=0 (o15.0.1.4)...\n");
1471
1472	status = osmt_query_mcast(p_osmt);
1473
1474	osmt_init_mc_query_rec(p_osmt, &mc_req_rec);
1475
1476	p_mc_res = ib_sa_mad_get_payload_ptr(&res_sa_mad);
1477
1478	/* no MGID */
1479	memset(&mc_req_rec.mgid, 0, sizeof(ib_gid_t));
1480	/* Request Join */
1481	ib_member_set_join_state(&mc_req_rec, IB_MC_REC_STATE_FULL_MEMBER);
1482
1483	mc_req_rec.pkt_life = 0 | IB_PATH_SELECTOR_GREATER_THAN << 6;
1484
1485	comp_mask = IB_MCR_COMPMASK_MGID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
1486	    IB_MCR_COMPMASK_LIFE | IB_MCR_COMPMASK_LIFE_SEL;
1487
1488	status = osmt_send_mcast_request(p_osmt, 1,
1489					 &mc_req_rec, comp_mask, &res_sa_mad);
1490	if (status != IB_SUCCESS) {
1491		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0210: "
1492			"Failed to create MCG for MGID=0 - got %s/%s\n",
1493			ib_get_err_str(status),
1494			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1495		goto Exit;
1496	}
1497
1498	/* Save the mlid created in test_created_mlids map */
1499	p_recvd_rec =
1500	    (ib_member_rec_t *) ib_sa_mad_get_payload_ptr(&res_sa_mad);
1501	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "Created MGID:%s MLID:0x%04X\n",
1502		inet_ntop(AF_INET6, p_recvd_rec->mgid.raw, gid_str,
1503			  sizeof gid_str), cl_ntoh16(p_recvd_rec->mlid));
1504	cl_map_insert(&test_created_mlids, cl_ntoh16(p_recvd_rec->mlid),
1505		      p_recvd_rec);
1506
1507	/* o15.0.1.6: */
1508	/* - Create a new MCG with valid requested MGID. */
1509	osmt_init_mc_query_rec(p_osmt, &mc_req_rec);
1510	mc_req_rec.mgid = good_mgid;
1511
1512	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1513		"Checking Create given valid MGID=%s (o15.0.1.6)...\n",
1514		inet_ntop(AF_INET6, mc_req_rec.mgid.raw, gid_str,
1515			  sizeof gid_str));
1516
1517	/* Before creation, need to check that this group doesn't exist */
1518	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1519		"Verifying that MCGroup with this MGID doesn't exist by trying to Join it (o15.0.1.13)...\n");
1520
1521	ib_member_set_join_state(&mc_req_rec, IB_MC_REC_STATE_NON_MEMBER);
1522
1523	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
1524	status = osmt_send_mcast_request(p_osmt, 1,	/* join */
1525					 &mc_req_rec, comp_mask, &res_sa_mad);
1526	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
1527
1528	if ((status != IB_REMOTE_ERROR) ||
1529	    (res_sa_mad.status != IB_SA_MAD_STATUS_REQ_INVALID)) {
1530		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0301: "
1531			"Tried joining group that shouldn't have existed - got %s/%s\n",
1532			ib_get_err_str(status),
1533			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1534		status = IB_ERROR;
1535		goto Exit;
1536	}
1537
1538	/* Set State to full member to allow group creation */
1539	ib_member_set_join_state(&mc_req_rec, IB_MC_REC_STATE_FULL_MEMBER);
1540
1541	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1542		"Now creating group with given valid MGID=%s (o15.0.1.6)...\n",
1543		inet_ntop(AF_INET6, mc_req_rec.mgid.raw, gid_str,
1544			  sizeof gid_str));
1545
1546	status = osmt_send_mcast_request(p_osmt, 1,
1547					 &mc_req_rec, comp_mask, &res_sa_mad);
1548	if (status != IB_SUCCESS) {
1549		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0211: "
1550			"Failed to create MCG for MGID=%s (o15.0.1.6) - got %s/%s\n",
1551			inet_ntop(AF_INET6, good_mgid.raw, gid_str,
1552				  sizeof gid_str), ib_get_err_str(status),
1553			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1554		goto Exit;
1555	}
1556
1557	/* Save the mlid created in test_created_mlids map */
1558	p_recvd_rec =
1559	    (ib_member_rec_t *) ib_sa_mad_get_payload_ptr(&res_sa_mad);
1560	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "Created MGID:%s MLID:0x%04X\n",
1561		inet_ntop(AF_INET6, p_recvd_rec->mgid.raw, gid_str,
1562			  sizeof gid_str), cl_ntoh16(p_recvd_rec->mlid));
1563	cl_map_insert(&test_created_mlids, cl_ntoh16(p_recvd_rec->mlid),
1564		      p_recvd_rec);
1565
1566	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1567		"Validating resulting MGID (o15.0.1.6)...\n");
1568	/* prefix 0xFF1 Scope 0xA01B */
1569	if ((p_mc_res->mgid.multicast.header[0] != 0xFF) || (p_mc_res->mgid.multicast.header[1] != 0x12) ||	/* HACK hardcoded scope = 0x02 */
1570	    (p_mc_res->mgid.multicast.raw_group_id[0] != 0xA0) ||
1571	    (p_mc_res->mgid.multicast.raw_group_id[1] != 0x1C)) {
1572		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0212: "
1573			"Validating MGID failed. MGID:%s\n",
1574			inet_ntop(AF_INET6, p_mc_res->mgid.raw, gid_str,
1575				  sizeof gid_str));
1576		status = IB_ERROR;
1577		goto Exit;
1578	}
1579
1580	/* - Try to create a new MCG with invalid MGID : get back ERR_REQ_INVALID */
1581	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1582		"Checking BAD MGID=0xFA..... (o15.0.1.6)...\n");
1583
1584	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
1585
1586	mc_req_rec.mgid.raw[0] = 0xFA;
1587	status = osmt_send_mcast_request(p_osmt, 1,
1588					 &mc_req_rec, comp_mask, &res_sa_mad);
1589	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
1590
1591	if ((status != IB_REMOTE_ERROR) ||
1592	    (res_sa_mad.status != IB_SA_MAD_STATUS_REQ_INVALID)) {
1593		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0213: "
1594			"Failed to recognize MGID error for MGID=0xFA - got %s/%s\n",
1595			ib_get_err_str(status),
1596			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1597		status = IB_ERROR;
1598		goto Exit;
1599	}
1600
1601	/* - Try again with MGID prefix = 0xA01B (maybe 0x1BA0 little or big ?) */
1602	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1603		"Checking BAD MGID=0xFF12A01B..... with link-local scope (o15.0.1.6)...\n");
1604
1605	mc_req_rec.mgid.raw[0] = 0xFF;
1606	mc_req_rec.mgid.raw[3] = 0x1B;
1607	comp_mask = comp_mask | IB_MCR_COMPMASK_SCOPE;
1608	mc_req_rec.scope_state = mc_req_rec.scope_state & 0x2F;	/* local scope */
1609	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
1610	status = osmt_send_mcast_request(p_osmt, 1,
1611					 &mc_req_rec, comp_mask, &res_sa_mad);
1612	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
1613
1614	if ((status != IB_REMOTE_ERROR) ||
1615	    (res_sa_mad.status != IB_SA_MAD_STATUS_REQ_INVALID)) {
1616		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0214: "
1617			"Failed to recognize MGID error for A01B with link-local bit (status %s) (rem status %s)\n",
1618			ib_get_err_str(status),
1619			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1620		status = IB_ERROR;
1621		goto Exit;
1622	}
1623
1624	/* Change the mgid prefix - get back ERR_REQ_INVALID */
1625
1626	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1627		"Checking BAD MGID PREFIX=0xEF... (o15.0.1.6)...\n");
1628
1629	mc_req_rec.mgid = good_mgid;
1630
1631	mc_req_rec.mgid.raw[0] = 0xEF;
1632
1633	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
1634	status = osmt_send_mcast_request(p_osmt, 1,
1635					 &mc_req_rec, comp_mask, &res_sa_mad);
1636	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
1637
1638	if ((status != IB_REMOTE_ERROR) ||
1639	    (res_sa_mad.status != IB_SA_MAD_STATUS_REQ_INVALID)) {
1640		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0215: "
1641			"Failed to recognize MGID PREFIX error for MGID=0xEF - got %s/%s\n",
1642			ib_get_err_str(status),
1643			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1644		status = IB_ERROR;
1645		goto Exit;
1646	}
1647
1648	/* Change the scope to reserved - get back VALID REQ */
1649
1650	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1651		"Checking local scope with full member \n\t\tand valid mgid %s"
1652		"  ... (o15.0.1.6)...\n",
1653		inet_ntop(AF_INET6, mc_req_rec.mgid.raw, gid_str,
1654			  sizeof gid_str));
1655
1656	mc_req_rec.mgid = good_mgid;
1657
1658	mc_req_rec.mgid.raw[1] = 0x1F;
1659
1660	status = osmt_send_mcast_request(p_osmt, 1,
1661					 &mc_req_rec, comp_mask, &res_sa_mad);
1662	if (status != IB_SUCCESS) {
1663		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0216: "
1664			"Failed to create MCG for MGID=%s - got %s/%s\n",
1665			inet_ntop(AF_INET6, good_mgid.raw, gid_str,
1666				  sizeof gid_str), ib_get_err_str(status),
1667			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1668		goto Exit;
1669	}
1670
1671	/* Save the mlid created in test_created_mlids map */
1672	p_recvd_rec =
1673	    (ib_member_rec_t *) ib_sa_mad_get_payload_ptr(&res_sa_mad);
1674	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "Created MGID:%s MLID:0x%04X\n",
1675		inet_ntop(AF_INET6, p_recvd_rec->mgid.raw, gid_str,
1676			  sizeof gid_str), cl_ntoh16(p_recvd_rec->mlid));
1677	cl_map_insert(&test_created_mlids, cl_ntoh16(p_recvd_rec->mlid),
1678		      p_recvd_rec);
1679
1680	/* Change the flags to invalid value 0x2 - get back INVALID REQ */
1681
1682	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1683		"Checking invalid flags=0xFF 22  ... (o15.0.1.6)...\n");
1684
1685	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
1686
1687	mc_req_rec.mgid = good_mgid;
1688
1689	mc_req_rec.mgid.raw[1] = 0x22;
1690
1691	status = osmt_send_mcast_request(p_osmt, 1,
1692					 &mc_req_rec, comp_mask, &res_sa_mad);
1693
1694	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
1695
1696	if ((status != IB_REMOTE_ERROR) ||
1697	    (res_sa_mad.status != IB_SA_MAD_STATUS_REQ_INVALID)) {
1698		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0217: "
1699			"Failed to recognize create with invalid flags value 0x2 - got %s/%s\n",
1700			ib_get_err_str(status),
1701			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1702		status = IB_ERROR;
1703		goto Exit;
1704	}
1705
1706	/* Change the MGID to link local MGID  - get back VALID REQ */
1707
1708	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1709		"Checking link local MGID 0xFF02:0:0:0:0:0:0:1 (o15.0.1.6)...\n");
1710
1711	mc_req_rec.mgid = osm_link_local_mgid;
1712
1713	status = osmt_send_mcast_request(p_osmt, 1,
1714					 &mc_req_rec, comp_mask, &res_sa_mad);
1715	if (status != IB_SUCCESS) {
1716		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0218: "
1717			"Failed to create MCG for MGID=0xFF02:0:0:0:0:0:0:1 - got %s/%s\n",
1718			ib_get_err_str(status),
1719			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1720		goto Exit;
1721	}
1722
1723	/* Save the mlid created in test_created_mlids map */
1724	p_recvd_rec =
1725	    (ib_member_rec_t *) ib_sa_mad_get_payload_ptr(&res_sa_mad);
1726	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "Created MGID:%s MLID:0x%04X\n",
1727		inet_ntop(AF_INET6, p_recvd_rec->mgid.raw, gid_str,
1728			  sizeof gid_str), cl_ntoh16(p_recvd_rec->mlid));
1729	cl_map_insert(&test_created_mlids, cl_ntoh16(p_recvd_rec->mlid),
1730		      p_recvd_rec);
1731
1732	/* o15.0.1.7 - implicitlly checked during the prev steps. */
1733	/* o15.0.1.8 - implicitlly checked during the prev steps. */
1734
1735	/* o15.0.1.9 */
1736	/* - Create MCG with Invalid JoinState.FullMember != 1 : get ERR_REQ_INVALID */
1737
1738	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1739		"Checking new MGID with invalid join state (o15.0.1.9)...\n");
1740
1741	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
1742
1743	mc_req_rec.mgid = good_mgid;
1744	mc_req_rec.mgid.raw[12] = 0xFF;
1745	mc_req_rec.scope_state = 0x22;	/* link-local scope, non-member state */
1746
1747	status = osmt_send_mcast_request(p_osmt, 1,
1748					 &mc_req_rec, comp_mask, &res_sa_mad);
1749	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
1750
1751	if ((status != IB_REMOTE_ERROR) ||
1752	    (res_sa_mad.status != IB_SA_MAD_STATUS_REQ_INVALID)) {
1753		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0219: "
1754			"Failed to recognize create with JoinState != FullMember - got %s/%s\n",
1755			ib_get_err_str(status),
1756			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1757		status = IB_ERROR;
1758		goto Exit;
1759	}
1760
1761	/* Lets try a valid join scope state */
1762	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1763		"Checking new MGID with valid join state (o15.0.1.9)...\n");
1764
1765	mc_req_rec.mgid = good_mgid;
1766	mc_req_rec.scope_state = 0x23;	/* link-local scope, non member and full member */
1767
1768	status = osmt_send_mcast_request(p_osmt, 1,
1769					 &mc_req_rec, comp_mask, &res_sa_mad);
1770
1771	if (status != IB_SUCCESS) {
1772		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0220: "
1773			"Failed to create MCG with valid join state 0x3 - got %s/%s\n",
1774			ib_get_err_str(status),
1775			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1776		goto Exit;
1777	}
1778
1779	/* Save the mlid created in test_created_mlids map */
1780	p_recvd_rec =
1781	    (ib_member_rec_t *) ib_sa_mad_get_payload_ptr(&res_sa_mad);
1782	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "Created MGID:%s MLID:0x%04X\n",
1783		inet_ntop(AF_INET6, p_recvd_rec->mgid.raw, gid_str,
1784			  sizeof gid_str), cl_ntoh16(p_recvd_rec->mlid));
1785	cl_map_insert(&test_created_mlids, cl_ntoh16(p_recvd_rec->mlid),
1786		      p_recvd_rec);
1787
1788	/* Lets try another invalid join scope state */
1789	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1790		"Checking new MGID with invalid join state (o15.0.1.9)...\n");
1791
1792	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
1793
1794	/* We have created a new MCG so now we need different mgid when cresting group otherwise it will be counted as join request . */
1795	mc_req_rec.mgid = good_mgid;
1796	mc_req_rec.mgid.raw[12] = 0xFC;
1797
1798	mc_req_rec.scope_state = 0x24;	/* link-local scope, send only member */
1799
1800	status = osmt_send_mcast_request(p_osmt, 1,
1801					 &mc_req_rec, comp_mask, &res_sa_mad);
1802	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
1803
1804	if ((status != IB_REMOTE_ERROR) ||
1805	    (res_sa_mad.status != IB_SA_MAD_STATUS_REQ_INVALID)) {
1806		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0221: "
1807			"Failed to recognize create with JoinState != FullMember - got %s/%s\n",
1808			ib_get_err_str(status),
1809			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1810		status = IB_ERROR;
1811		goto Exit;
1812	}
1813
1814	/* Lets try another valid join scope state */
1815	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1816		"Checking new MGID creation with valid join state (o15.0.2.3)...\n");
1817
1818	mc_req_rec.mgid = good_mgid;
1819	mc_req_rec.mgid.raw[12] = 0xFB;
1820	memcpy(&special_mgid, &mc_req_rec.mgid, sizeof(ib_gid_t));
1821	mc_req_rec.scope_state = 0x2F;	/* link-local scope, Full member with all other bits turned on */
1822
1823	status = osmt_send_mcast_request(p_osmt, 1,
1824					 &mc_req_rec, comp_mask, &res_sa_mad);
1825
1826	if (status != IB_SUCCESS) {
1827		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0222: "
1828			"Failed to create MCG with valid join state 0xF - got %s/%s\n",
1829			ib_get_err_str(status),
1830			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1831		goto Exit;
1832	}
1833
1834	/* Save the mlid created in test_created_mlids map */
1835	p_recvd_rec =
1836	    (ib_member_rec_t *) ib_sa_mad_get_payload_ptr(&res_sa_mad);
1837	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "Created MGID:%s MLID:0x%04X\n",
1838		inet_ntop(AF_INET6, p_recvd_rec->mgid.raw, gid_str,
1839			  sizeof gid_str), cl_ntoh16(p_recvd_rec->mlid));
1840	cl_map_insert(&test_created_mlids, cl_ntoh16(p_recvd_rec->mlid),
1841		      p_recvd_rec);
1842
1843	/* o15.0.1.10 - can't check on a single client .-- obsolete -
1844	   checked by SilverStorm bug o15-0.2.4, never the less recheck */
1845	/* o15-0.2.4 - Check a join request to already created MCG */
1846	p_mc_res = ib_sa_mad_get_payload_ptr(&res_sa_mad);
1847	OSM_LOG(&p_osmt->log, OSM_LOG_INFO, "Check o15-0.2.4 statement...\n");
1848	/* Try to join */
1849	memcpy(&mc_req_rec.mgid, &p_mc_res->mgid, sizeof(ib_gid_t));
1850	/* Request Join */
1851	ib_member_set_join_state(&mc_req_rec, IB_MC_REC_STATE_NON_MEMBER);
1852	comp_mask =
1853	    IB_MCR_COMPMASK_MGID |
1854	    IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_JOIN_STATE;
1855
1856	status = osmt_send_mcast_request(p_osmt, 0x1,	/* SubnAdmSet */
1857					 &mc_req_rec, comp_mask, &res_sa_mad);
1858	if (status != IB_SUCCESS) {
1859		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02CC: "
1860			"Failed to join MCG with valid req, returned status = %s\n",
1861			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1862		goto Exit;
1863	}
1864
1865	p_mc_res = ib_sa_mad_get_payload_ptr(&res_sa_mad);
1866	if ((p_mc_res->scope_state & 0x7) != 0x7) {
1867		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02D0: "
1868			"Validating JoinState update failed. "
1869			"Expected 0x27 got 0x%02X\n",
1870			p_mc_res->scope_state);
1871		status = IB_ERROR;
1872		goto Exit;
1873	}
1874
1875	/* o15.0.1.11: */
1876	/* - Try to join into a MGID that exists with JoinState=SendOnlyMember -  */
1877	/*   see that it updates JoinState. What is the routing change? */
1878	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1879		"Checking Retry of existing MGID - See JoinState update (o15.0.1.11)...\n");
1880
1881	mc_req_rec.mgid = good_mgid;
1882
1883	/* first, make sure  that the group exists */
1884	mc_req_rec.scope_state = 0x21;
1885	status = osmt_send_mcast_request(p_osmt, 1,
1886					 &mc_req_rec, comp_mask, &res_sa_mad);
1887	if (status != IB_SUCCESS) {
1888		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02CD: "
1889			"Failed to create/join as full member - got %s/%s\n",
1890			ib_get_err_str(status),
1891			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1892		goto Exit;
1893	}
1894
1895	mc_req_rec.scope_state = 0x22;	/* link-local scope, non-member */
1896	status = osmt_send_mcast_request(p_osmt, 1,
1897					 &mc_req_rec, comp_mask, &res_sa_mad);
1898	if (status != IB_SUCCESS) {
1899		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02D1: "
1900			"Failed to update existing MGID - got %s/%s\n",
1901			ib_get_err_str(status),
1902			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1903		goto Exit;
1904	}
1905
1906	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1907		"Validating Join State update with NonMember (o15.0.1.11)...\n");
1908
1909	if (p_mc_res->scope_state != 0x23) {	/* scope is LSB */
1910		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02CE: "
1911			"Validating JoinState update failed. Expected 0x23 got: 0x%02X\n",
1912			p_mc_res->scope_state);
1913		status = IB_ERROR;
1914		goto Exit;
1915	}
1916
1917	/* Try delete current join state then update it with another value  */
1918	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1919		"Checking JoinState update request should return 0x22 (o15.0.1.11)...\n");
1920
1921	mc_req_rec.rate =
1922	    IB_LINK_WIDTH_ACTIVE_1X | IB_PATH_SELECTOR_GREATER_THAN << 6;
1923	mc_req_rec.mgid = good_mgid;
1924
1925	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1926		"Checking Partially delete JoinState (o15.0.1.14)...\n");
1927
1928	/* link-local scope, both non-member bits,
1929	   so we should not be able to delete) */
1930	mc_req_rec.scope_state = 0x26;
1931	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
1932	status = osmt_send_mcast_request(p_osmt, 0,
1933					 &mc_req_rec, comp_mask, &res_sa_mad);
1934	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
1935
1936	if (status != IB_REMOTE_ERROR) {
1937		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02CF: "
1938			"Expected to fail partially update JoinState, "
1939			"but got %s\n",
1940			ib_get_err_str(status));
1941		status = IB_ERROR;
1942		goto Exit;
1943	}
1944
1945	/* link-local scope, NonMember bit, the FullMember bit should stay */
1946	mc_req_rec.scope_state = 0x22;
1947	status = osmt_send_mcast_request(p_osmt, 0,
1948					 &mc_req_rec, comp_mask, &res_sa_mad);
1949	if (status != IB_SUCCESS) {
1950		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02D3: "
1951			"Failed to partially update JoinState : %s/%s\n",
1952			ib_get_err_str(status),
1953			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1954		status = IB_ERROR;
1955		goto Exit;
1956	}
1957
1958	p_mc_res = ib_sa_mad_get_payload_ptr(&res_sa_mad);
1959	if (p_mc_res->scope_state != 0x21) {
1960		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02D4: "
1961			"Failed to partially update JoinState : "
1962			"JoinState = 0x%02X, expected 0x%02X\n",
1963			p_mc_res->scope_state, 0x21);
1964		status = IB_ERROR;
1965		goto Exit;
1966	}
1967
1968	/* So far successfully delete state - Now change it */
1969	mc_req_rec.mgid = good_mgid;
1970	mc_req_rec.scope_state = 0x24;	/* link-local scope, send only  member */
1971
1972	status = osmt_send_mcast_request(p_osmt, 1,
1973					 &mc_req_rec, comp_mask, &res_sa_mad);
1974	if (status != IB_SUCCESS) {
1975		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02C0: "
1976			"Failed to update existing MCG - got %s/%s\n",
1977			ib_get_err_str(status),
1978			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1979		goto Exit;
1980	}
1981
1982	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1983		"Validating Join State update with Send Only Member (o15.0.1.11)...\n");
1984
1985	if (p_mc_res->scope_state != 0x25) {	/* scope is MSB */
1986		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02C1: "
1987			"Validating JoinState update failed. Expected 0x25 got: 0x%02X\n",
1988			p_mc_res->scope_state);
1989		status = IB_ERROR;
1990		goto Exit;
1991	}
1992	/* Now try to update value of join state */
1993	mc_req_rec.scope_state = 0x21;	/* link-local scope, full member */
1994
1995	status = osmt_send_mcast_request(p_osmt, 1,
1996					 &mc_req_rec, comp_mask, &res_sa_mad);
1997	if (status != IB_SUCCESS) {
1998		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02C2: "
1999			"Failed to update existing MGID - got %s/%s\n",
2000			ib_get_err_str(status),
2001			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
2002		goto Exit;
2003	}
2004
2005	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
2006		"Validating Join State update with Full Member\n\t\t"
2007		"to an existing 0x5 state MCG (o15.0.1.11)...\n");
2008
2009	if (p_mc_res->scope_state != 0x25) {	/* scope is LSB */
2010		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02C3: "
2011			"Validating JoinState update failed. Expected 0x25 got: 0x%02X\n",
2012			p_mc_res->scope_state);
2013		status = IB_ERROR;
2014		goto Exit;
2015	}
2016
2017	/* Now try to update value of join state */
2018	mc_req_rec.scope_state = 0x22;	/* link-local scope,non member */
2019
2020	status = osmt_send_mcast_request(p_osmt, 1,
2021					 &mc_req_rec, comp_mask, &res_sa_mad);
2022	if (status != IB_SUCCESS) {
2023		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02C4: "
2024			"Failed to update existing MGID - got %s/%s\n",
2025			ib_get_err_str(status),
2026			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
2027		goto Exit;
2028	}
2029	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
2030		"Validating Join State update with Non Member\n\t\t"
2031		"to an existing 0x5 state MCG (o15.0.1.11)...\n");
2032
2033	if (p_mc_res->scope_state != 0x27) {	/* scope is LSB */
2034		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02C5: "
2035			"Validating JoinState update failed. Expected 0x27 got: 0x%02X\n",
2036			p_mc_res->scope_state);
2037		status = IB_ERROR;
2038		goto Exit;
2039	}
2040
2041	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
2042		"DEBUG - Current scope_state value : 0x%02X...\n",
2043		p_mc_res->scope_state);
2044
2045	/* - We can not check simple join since we have only one tester (for now) */
2046
2047	/* o15.0.1.12: Not Supported */
2048	/* - The SendOnlyNonMem join should have a special treatment in the
2049	   SA but what is it ? */
2050
2051	/* o15.0.1.13: */
2052	/* - Try joining with rate that does not exist in any MCG -
2053	   ERR_REQ_INVALID */
2054
2055	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
2056		"Checking BAD RATE when connecting to existing MGID (o15.0.1.13)...\n");
2057	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
2058
2059	mc_req_rec.mgid = good_mgid;
2060	mc_req_rec.rate =
2061	    IB_LINK_WIDTH_ACTIVE_1X | IB_PATH_SELECTOR_LESS_THAN << 6;
2062	comp_mask = IB_MCR_COMPMASK_GID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
2063	    IB_MCR_COMPMASK_RATE_SEL | IB_MCR_COMPMASK_RATE;
2064
2065	status = osmt_send_mcast_request(p_osmt, 1,
2066					 &mc_req_rec, comp_mask, &res_sa_mad);
2067	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
2068
2069	if ((status != IB_REMOTE_ERROR) ||
2070	    (res_sa_mad.status != IB_SA_MAD_STATUS_REQ_INVALID)) {
2071		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02C6: "
2072			"Failed to catch BAD RATE joining an exiting MGID: %s/%s\n",
2073			ib_get_err_str(status),
2074			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
2075		status = IB_ERROR;
2076		goto Exit;
2077	}
2078
2079	/* Try MTU that does not exist in any MCG */
2080	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
2081		"Checking BAD MTU (higher them max) when connecting to "
2082		"existing MGID (o15.0.1.13)...\n");
2083	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
2084
2085	mc_req_rec.mgid = osm_ipoib_mgid;
2086	mc_req_rec.mtu = IB_MTU_LEN_4096 | IB_PATH_SELECTOR_GREATER_THAN << 6;
2087	comp_mask = IB_MCR_COMPMASK_GID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
2088	    IB_MCR_COMPMASK_MTU_SEL | IB_MCR_COMPMASK_MTU;
2089
2090	status = osmt_send_mcast_request(p_osmt, 1,
2091					 &mc_req_rec, comp_mask, &res_sa_mad);
2092	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
2093
2094	if ((status != IB_REMOTE_ERROR) ||
2095	    (res_sa_mad.status != IB_SA_MAD_STATUS_REQ_INVALID)) {
2096		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02C7: "
2097			"Failed to catch BAD RATE (higher them max) joining an exiting MGID: %s/%s\n",
2098			ib_get_err_str(status),
2099			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
2100		status = IB_ERROR;
2101		goto Exit;
2102	}
2103
2104	/* Try another MTU that does not exist in any MCG */
2105	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
2106		"Checking BAD MTU (less than min) when connecting "
2107		"to existing MGID (o15.0.1.13)...\n");
2108	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
2109
2110	mc_req_rec.mgid = osm_ipoib_mgid;
2111	mc_req_rec.mtu = IB_MTU_LEN_256 | IB_PATH_SELECTOR_LESS_THAN << 6;
2112	comp_mask = IB_MCR_COMPMASK_GID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
2113	    IB_MCR_COMPMASK_MTU_SEL | IB_MCR_COMPMASK_MTU;
2114
2115	status = osmt_send_mcast_request(p_osmt, 1,
2116					 &mc_req_rec, comp_mask, &res_sa_mad);
2117	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
2118
2119	if ((status != IB_REMOTE_ERROR) ||
2120	    (res_sa_mad.status != IB_SA_MAD_STATUS_REQ_INVALID)) {
2121		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02C8: "
2122			"Failed to catch BAD RATE (less them min) joining an exiting MGID: %s/%s\n",
2123			ib_get_err_str(status),
2124			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
2125		status = IB_ERROR;
2126		goto Exit;
2127	}
2128
2129	/* o15.0.1.14: */
2130	/* - Try partial delete - actually updating the join state. check it. */
2131
2132	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
2133		"Checking partial JoinState delete request - removing NonMember (o15.0.1.14)...\n");
2134
2135	mc_req_rec.rate =
2136	    IB_LINK_WIDTH_ACTIVE_1X | IB_PATH_SELECTOR_GREATER_THAN << 6;
2137	mc_req_rec.mgid = good_mgid;
2138	comp_mask = IB_MCR_COMPMASK_GID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
2139	    IB_MCR_COMPMASK_RATE_SEL | IB_MCR_COMPMASK_RATE;
2140	/* link-local scope, non member (so we should not be able to delete) */
2141	/* but the NonMember bit should be gone */
2142	mc_req_rec.scope_state = 0x22;
2143
2144	status = osmt_send_mcast_request(p_osmt, 0,
2145					 &mc_req_rec, comp_mask, &res_sa_mad);
2146
2147	if (status != IB_SUCCESS) {
2148		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02C9: "
2149			"Fail to partially update JoinState during delete: %s/%s\n",
2150			ib_get_err_str(status),
2151			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
2152		status = IB_ERROR;
2153		goto Exit;
2154	}
2155
2156	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
2157		"Validating Join State removal of Non Member bit (o15.0.1.14)...\n");
2158	if (p_mc_res->scope_state != 0x25) {	/* scope is MSB - now only the full member & send only member have left */
2159		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02CA: "
2160			"Validating JoinState update failed. Expected 0x25 got: 0x%02X\n",
2161			p_mc_res->scope_state);
2162		status = IB_ERROR;
2163		goto Exit;
2164	}
2165
2166	/* Now use the same scope_state and delete all JoinState - leave multicast group since state is 0x0 */
2167
2168	mc_req_rec.scope_state = 0x25;
2169	status = osmt_send_mcast_request(p_osmt, 0,
2170					 &mc_req_rec, comp_mask, &res_sa_mad);
2171
2172	if (status != IB_SUCCESS) {
2173		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02CB: "
2174			"Failed to update JoinState during delete: %s/%s\n",
2175			ib_get_err_str(status),
2176			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
2177		status = IB_ERROR;
2178		goto Exit;
2179	}
2180
2181	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
2182		"Validating Join State update remove (o15.0.1.14)...\n");
2183
2184	if (p_mc_res->scope_state != 0x25) {	/* scope is MSB - now only 0x0 so port is removed from MCG */
2185		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02BF: "
2186			"Validating JoinState update failed. Expected 0x25 got: 0x%02X\n",
2187			p_mc_res->scope_state);
2188		status = IB_ERROR;
2189		goto Exit;
2190	}
2191
2192	/* - Try joining (not full mem) again to see the group was deleted. (should fail) */
2193	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
2194		"Checking Delete by trying to Join deleted group (o15.0.1.13)...\n");
2195
2196	mc_req_rec.scope_state = 0x22;	/* use non member - so if no group fail */
2197
2198	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
2199	status = osmt_send_mcast_request(p_osmt, 1,	/* join */
2200					 &mc_req_rec, comp_mask, &res_sa_mad);
2201	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
2202
2203	if (status != IB_REMOTE_ERROR) {
2204		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02BC: "
2205			"Succeeded Joining Deleted Group: %s/%s\n",
2206			ib_get_err_str(status),
2207			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
2208		status = IB_ERROR;
2209		goto Exit;
2210	}
2211
2212	/* - Try deletion of the IPoIB MCG and get: ERR_REQ_INVALID */
2213	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
2214		"Checking BAD Delete of Mgid membership (no prev join) (o15.0.1.15)...\n");
2215	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
2216
2217	mc_req_rec.mgid = osm_ipoib_mgid;
2218	mc_req_rec.rate =
2219	    IB_LINK_WIDTH_ACTIVE_1X | IB_PATH_SELECTOR_GREATER_THAN << 6;
2220	mc_req_rec.scope_state = 0x21;	/* delete full member */
2221
2222	status = osmt_send_mcast_request(p_osmt, 0,	/* delete flag */
2223					 &mc_req_rec, comp_mask, &res_sa_mad);
2224	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
2225
2226	if ((status != IB_REMOTE_ERROR) ||
2227	    (res_sa_mad.status != IB_SA_MAD_STATUS_REQ_INVALID)) {
2228		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02BD: "
2229			"Failed to catch BAD delete from IPoIB: %s/%s\n",
2230			ib_get_err_str(status),
2231			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
2232		status = IB_ERROR;
2233		goto Exit;
2234	}
2235
2236	/* Prepare another MCG for the following tests : */
2237	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
2238		"Checking Create given MGID=%s\n\t\t(o15.0.1.4)...\n",
2239		inet_ntop(AF_INET6, osm_ipoib_mgid.raw, gid_str,
2240			  sizeof gid_str));
2241
2242	mc_req_rec.mgid = good_mgid;
2243	mc_req_rec.mgid.raw[12] = 0xAA;
2244	mc_req_rec.pkt_life = 0 | IB_PATH_SELECTOR_GREATER_THAN << 6;
2245	mc_req_rec.scope_state = 0x21;	/* Full memeber */
2246	comp_mask = IB_MCR_COMPMASK_GID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
2247	    IB_MCR_COMPMASK_LIFE | IB_MCR_COMPMASK_LIFE_SEL;
2248
2249	status = osmt_send_mcast_request(p_osmt, 1,
2250					 &mc_req_rec, comp_mask, &res_sa_mad);
2251	if (status != IB_SUCCESS) {
2252		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02BE: "
2253			"Failed to create MCG for %s - got %s/%s\n",
2254			inet_ntop(AF_INET6, good_mgid.raw, gid_str,
2255				  sizeof gid_str), ib_get_err_str(status),
2256			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
2257		goto Exit;
2258	}
2259
2260	/* - Try delete with valid join state */
2261	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
2262		"Checking Full Delete of a group (o15.0.1.14)...\n");
2263	mc_req_rec.scope_state = 0x21;	/* the FullMember is the current JoinState */
2264	status = osmt_send_mcast_request(p_osmt, 0,
2265					 &mc_req_rec, comp_mask, &res_sa_mad);
2266
2267	if (status != IB_SUCCESS) {
2268		goto Exit;
2269	}
2270
2271	/* o15.0.1.15: */
2272	/* - Try deletion of the IPoIB MCG and get: ERR_REQ_INVALID */
2273	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
2274		"Checking BAD Delete of IPoIB membership (no prev join) (o15.0.1.15)...\n");
2275	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
2276
2277	mc_req_rec.mgid = osm_ipoib_mgid;
2278	mc_req_rec.rate =
2279	    IB_LINK_WIDTH_ACTIVE_1X | IB_PATH_SELECTOR_GREATER_THAN << 6;
2280	mc_req_rec.scope_state = 0x21;	/* delete full member */
2281
2282	status = osmt_send_mcast_request(p_osmt, 0,	/* delete flag */
2283					 &mc_req_rec, comp_mask, &res_sa_mad);
2284
2285	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
2286
2287	if ((status != IB_REMOTE_ERROR) ||
2288	    (res_sa_mad.status != IB_SA_MAD_STATUS_REQ_INVALID)) {
2289		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0223: "
2290			"Failed to catch BAD delete from IPoIB: %s/%s\n",
2291			ib_get_err_str(status),
2292			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
2293		status = IB_ERROR;
2294		goto Exit;
2295	}
2296
2297  /**************************************************************************/
2298	/* Checking join with invalid MTU */
2299	osmt_init_mc_query_rec(p_osmt, &mc_req_rec);
2300	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
2301		"Checking Join with unrealistic mtu : \n"
2302		"\t\tFirst create new MCG than try to join it \n"
2303		"\t\twith unrealistic MTU greater than 4096 (o15.0.1.8)...\n");
2304
2305	/* First create new mgrp */
2306	ib_member_set_join_state(&mc_req_rec, IB_MC_REC_STATE_FULL_MEMBER);
2307	mc_req_rec.mtu = IB_MTU_LEN_1024 | IB_PATH_SELECTOR_EXACTLY << 6;
2308	memset(&mc_req_rec.mgid, 0, sizeof(ib_gid_t));
2309	comp_mask = IB_MCR_COMPMASK_MGID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
2310	    IB_MCR_COMPMASK_MTU_SEL | IB_MCR_COMPMASK_MTU;
2311
2312	status = osmt_send_mcast_request(p_osmt, 1,
2313					 &mc_req_rec, comp_mask, &res_sa_mad);
2314	p_mc_res = ib_sa_mad_get_payload_ptr(&res_sa_mad);
2315	if (status != IB_SUCCESS) {
2316		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02EB: "
2317			"Failed to create new mgrp\n");
2318		goto Exit;
2319	}
2320	memcpy(&tmp_mgid, &p_mc_res->mgid, sizeof(ib_gid_t));
2321	osm_dump_mc_record(&p_osmt->log, p_mc_res, OSM_LOG_INFO);
2322	/* tmp_mtu = p_mc_res->mtu & 0x3F; */
2323
2324	/* impossible requested mtu always greater than exist in MCG */
2325	mc_req_rec.mtu = IB_MTU_LEN_4096 | IB_PATH_SELECTOR_GREATER_THAN << 6;
2326	memcpy(&mc_req_rec.mgid, &tmp_mgid, sizeof(ib_gid_t));
2327	ib_member_set_join_state(&mc_req_rec, IB_MC_REC_STATE_FULL_MEMBER);
2328	comp_mask =
2329	    IB_MCR_COMPMASK_GID |
2330	    IB_MCR_COMPMASK_PORT_GID |
2331	    IB_MCR_COMPMASK_JOIN_STATE |
2332	    IB_MCR_COMPMASK_MTU_SEL | IB_MCR_COMPMASK_MTU;
2333
2334	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
2335	status = osmt_send_mcast_request(p_osmt, 1,
2336					 &mc_req_rec, comp_mask, &res_sa_mad);
2337	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
2338
2339	if (status == IB_SUCCESS) {
2340		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02E4: "
2341			"Expected REMOTE ERROR got:%s/%s\n",
2342			ib_get_err_str(status),
2343			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
2344		status = IB_ERROR;
2345		goto Exit;
2346	}
2347
2348	/* - Try GetTable with PortGUID wildcarded and get back some groups. */
2349	status = osmt_query_mcast(p_osmt);
2350	cnt = cl_qmap_count(&p_osmt->exp_subn.mgrp_mlid_tbl);
2351	OSM_LOG(&p_osmt->log, OSM_LOG_INFO, "(Before checking Max MCG creation): "
2352		"Number of MC Records found in SA DB is %d\n", cnt);
2353
2354  /**************************************************************************/
2355	/* Checking join on behalf of remote port gid */
2356	OSM_LOG(&p_osmt->log, OSM_LOG_INFO, "Checking Proxy Join...\n");
2357	osmt_init_mc_query_rec(p_osmt, &mc_req_rec);
2358	memset(&context, 0, sizeof(context));
2359
2360	/*
2361	 * Do a blocking query for all NodeRecords in the subnet.
2362	 */
2363	status = osmtest_get_all_recs(p_osmt, IB_MAD_ATTR_NODE_RECORD,
2364				      sizeof(*p_rec), &context);
2365
2366	if (status != IB_SUCCESS) {
2367		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02E5: "
2368			"osmtest_get_all_recs failed on getting all node records(%s)\n",
2369			ib_get_err_str(status));
2370		goto Exit;
2371	}
2372
2373	/*
2374	 * Populate the database with the received records.
2375	 */
2376	num_recs = context.result.result_cnt;
2377	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "Received %u records\n", num_recs);
2378
2379	for (i = 0; i < num_recs; i++) {
2380		p_rec =
2381		    osmv_get_query_node_rec(context.result.p_result_madw, i);
2382		if (p_rec->node_info.port_guid != p_osmt->local_port.port_guid
2383		    && p_rec->node_info.node_type == IB_NODE_TYPE_CA) {
2384			OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
2385				"remote port_guid = 0x%" PRIx64 "\n",
2386				cl_ntoh64(p_rec->node_info.port_guid));
2387
2388			remote_port_guid = p_rec->node_info.port_guid;
2389			i = num_recs;
2390			break;
2391		}
2392	}
2393
2394	if (remote_port_guid != 0x0) {
2395		ib_member_set_join_state(&mc_req_rec,
2396					 IB_MC_REC_STATE_FULL_MEMBER);
2397		memset(&mc_req_rec.mgid, 0, sizeof(ib_gid_t));
2398		mc_req_rec.port_gid.unicast.interface_id = remote_port_guid;
2399		comp_mask = IB_MCR_COMPMASK_MGID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS;	/* all above are required */
2400
2401		status = osmt_send_mcast_request(p_osmt, 1,
2402						 &mc_req_rec,
2403						 comp_mask, &res_sa_mad);
2404
2405		if (status != IB_SUCCESS) {
2406			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02B4: "
2407				"Could not join on behalf of remote port 0x%016"
2408				PRIx64 " remote status: %s\n",
2409				cl_ntoh64(remote_port_guid),
2410				ib_get_mad_status_str((ib_mad_t
2411						       *) (&res_sa_mad)));
2412			status = IB_ERROR;
2413			goto Exit;
2414		}
2415
2416		p_mc_res = ib_sa_mad_get_payload_ptr(&res_sa_mad);
2417		memcpy(&proxy_mgid, &p_mc_res->mgid, sizeof(ib_gid_t));
2418
2419		/* First try a bad deletion then good one */
2420
2421		OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
2422			"Trying deletion of remote port with local port guid\n");
2423
2424		osmt_init_mc_query_rec(p_osmt, &mc_req_rec);
2425		ib_member_set_join_state(&mc_req_rec,
2426					 IB_MC_REC_STATE_FULL_MEMBER);
2427		comp_mask =
2428		    IB_MCR_COMPMASK_MGID | IB_MCR_COMPMASK_PORT_GID |
2429		    IB_MCR_COMPMASK_JOIN_STATE;
2430
2431		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
2432
2433		status = osmt_send_mcast_request(p_osmt, 0,	/* delete flag */
2434						 &mc_req_rec,
2435						 comp_mask, &res_sa_mad);
2436
2437		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
2438
2439		if (status == IB_SUCCESS) {
2440			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02A9: "
2441				"Successful deletion of remote port guid with local one MGID : "
2442				"%s, Got : %s/%s\n",
2443				inet_ntop(AF_INET6,
2444					p_mgrp->mcmember_rec.mgid.raw,
2445					gid_str, sizeof gid_str),
2446				ib_get_err_str(status),
2447				ib_get_mad_status_str((ib_mad_t
2448						       *) (&res_sa_mad)));
2449			status = IB_ERROR;
2450			goto Exit;
2451		}
2452
2453		OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
2454			"Trying deletion of remote port with the right port guid\n");
2455
2456		osmt_init_mc_query_rec(p_osmt, &mc_req_rec);
2457		ib_member_set_join_state(&mc_req_rec,
2458					 IB_MC_REC_STATE_FULL_MEMBER);
2459		mc_req_rec.mgid = proxy_mgid;
2460		mc_req_rec.port_gid.unicast.interface_id = remote_port_guid;
2461		comp_mask =
2462		    IB_MCR_COMPMASK_MGID |
2463		    IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_JOIN_STATE;
2464		status = osmt_send_mcast_request(p_osmt, 0,	/* delete flag */
2465						 &mc_req_rec,
2466						 comp_mask, &res_sa_mad);
2467		if (status != IB_SUCCESS) {
2468			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02B0: "
2469				"Failed to delete mgid with remote port guid MGID : "
2470				"%s, Got : %s/%s\n",
2471				inet_ntop(AF_INET6,
2472					p_mgrp->mcmember_rec.mgid.raw,
2473					gid_str, sizeof gid_str),
2474				ib_get_err_str(status),
2475				ib_get_mad_status_str((ib_mad_t
2476						       *) (&res_sa_mad)));
2477			goto Exit;
2478		}
2479	} else {
2480		OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
2481			"Could not check proxy join since could not found remote port, different from local port\n");
2482	}
2483
2484	/* prepare init for next check */
2485	osmt_init_mc_query_rec(p_osmt, &mc_req_rec);
2486
2487  /**************************************************************************/
2488	if (p_osmt->opt.mmode > 2) {
2489		/* Check invalid Join with max mlid which is more than the
2490		   Mellanox switches support 0xC000+0x1000 = 0xd000 */
2491		OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
2492			"Checking Creation of Maximum avaliable Groups (MulticastFDBCap)...\n");
2493		tmp_mlid = cl_ntoh16(max_mlid) - cnt;
2494
2495		while (tmp_mlid > 0 && !ReachedMlidLimit) {
2496			uint16_t cur_mlid = 0;
2497
2498			/* Request Set */
2499			ib_member_set_join_state(&mc_req_rec,
2500						 IB_MC_REC_STATE_FULL_MEMBER);
2501			/* Good Flow - mgid is 0 while giving all required fields for
2502			   join : P_Key, Q_Key, SL, FlowLabel, Tclass */
2503
2504			mc_req_rec.rate =
2505			    IB_LINK_WIDTH_ACTIVE_1X |
2506			    IB_PATH_SELECTOR_GREATER_THAN << 6;
2507			mc_req_rec.mlid = max_mlid;
2508			memset(&mc_req_rec.mgid, 0, sizeof(ib_gid_t));
2509			comp_mask = IB_MCR_COMPMASK_MGID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
2510			    IB_MCR_COMPMASK_MLID;
2511			status = osmt_send_mcast_request(p_osmt, 1,
2512							 &mc_req_rec,
2513							 comp_mask,
2514							 &res_sa_mad);
2515
2516			p_mc_res = ib_sa_mad_get_payload_ptr(&res_sa_mad);
2517			if (status != IB_SUCCESS) {
2518
2519				if (cur_mlid > cl_ntoh16(max_mlid)) {
2520
2521					OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
2522						"ERR 2E1 "
2523						"Successful Join with greater mlid than switches support (MulticastFDBCap) 0x%04X\n",
2524						cur_mlid);
2525					status = IB_ERROR;
2526					osm_dump_mc_record(&p_osmt->log,
2527							   p_mc_res,
2528							   OSM_LOG_VERBOSE);
2529					goto Exit;
2530				} else
2531				    if ((res_sa_mad.
2532					 status & IB_SMP_STATUS_MASK) ==
2533					IB_SA_MAD_STATUS_NO_RESOURCES) {
2534					/* You can quitly exit the loop since no available mlid in SA DB
2535					   i.e. reached the maximum valiad avalable mlid */
2536					ReachedMlidLimit = TRUE;
2537				}
2538			} else {
2539				cur_mlid = cl_ntoh16(p_mc_res->mlid);
2540				/* Save the mlid created in test_created_mlids map */
2541				p_recvd_rec =
2542				    (ib_member_rec_t *)
2543				    ib_sa_mad_get_payload_ptr(&res_sa_mad);
2544				OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
2545					"Created MGID:%s MLID:0x%04X\n",
2546					inet_ntop(AF_INET6,
2547						  p_recvd_rec->mgid.raw,
2548						  gid_str, sizeof gid_str),
2549					cl_ntoh16(p_recvd_rec->mlid));
2550				cl_map_insert(&test_created_mlids,
2551					      cl_ntoh16(p_recvd_rec->mlid),
2552					      p_recvd_rec);
2553			}
2554			tmp_mlid--;
2555		}
2556	}
2557
2558	/* Prepare the mc_req_rec for the rest of the flow */
2559	osmt_init_mc_query_rec(p_osmt, &mc_req_rec);
2560
2561  /**************************************************************************/
2562	/* o15.0.1.16: */
2563	/* - Try GetTable with PortGUID wildcarded and get back some groups. */
2564
2565	status = osmt_query_mcast(p_osmt);
2566	if (status != IB_SUCCESS) {
2567		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02B1: "
2568			"Failed to query multicast groups: %s\n",
2569			ib_get_err_str(status));
2570		goto Exit;
2571	}
2572
2573	cnt = cl_qmap_count(&p_osmt->exp_subn.mgrp_mlid_tbl);
2574	OSM_LOG(&p_osmt->log, OSM_LOG_INFO, "(Before Deletion of all MCG): "
2575		"Number of MC Records found in SA DB is %d\n", cnt);
2576
2577	/* Delete all MCG that are not of IPoIB */
2578	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
2579		"Cleanup all MCG that are not IPoIB...\n");
2580
2581	p_mgrp_mlid_tbl = &p_osmt->exp_subn.mgrp_mlid_tbl;
2582	p_mgrp = (osmtest_mgrp_t *) cl_qmap_head(p_mgrp_mlid_tbl);
2583	/* scan all available multicast groups in the DB and fill in the table */
2584	while (p_mgrp != (osmtest_mgrp_t *) cl_qmap_end(p_mgrp_mlid_tbl)) {
2585		/* Only if different from IPoIB Mgid try to delete */
2586		if (!IS_IPOIB_MGID(&p_mgrp->mcmember_rec.mgid)) {
2587			osmt_init_mc_query_rec(p_osmt, &mc_req_rec);
2588			mc_req_rec.mgid = p_mgrp->mcmember_rec.mgid;
2589
2590			/* o15-0.1.4 - need to specify the oppsite state for a valid delete */
2591			if (!memcmp
2592			    (&special_mgid, &p_mgrp->mcmember_rec.mgid,
2593			     sizeof(special_mgid))) {
2594				mc_req_rec.scope_state = 0x2F;
2595			} else {
2596				mc_req_rec.scope_state = 0x21;
2597			}
2598			comp_mask =
2599			    IB_MCR_COMPMASK_MGID |
2600			    IB_MCR_COMPMASK_PORT_GID |
2601			    IB_MCR_COMPMASK_JOIN_STATE;
2602
2603			OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
2604				"Sending request to delete MGID : %s"
2605				", scope_state : 0x%02X\n",
2606				inet_ntop(AF_INET6, mc_req_rec.mgid.raw,
2607					  gid_str, sizeof gid_str),
2608				mc_req_rec.scope_state);
2609			status = osmt_send_mcast_request(p_osmt, 0,	/* delete flag */
2610							 &mc_req_rec,
2611							 comp_mask,
2612							 &res_sa_mad);
2613			if (status != IB_SUCCESS) {
2614				OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
2615					"ERR 02FF: Failed to delete MGID : %s"
2616					" ,\n\t\t it is not our MCG, Status : %s/%s\n",
2617					inet_ntop(AF_INET6,
2618						  p_mgrp->mcmember_rec.mgid.raw,
2619						  gid_str, sizeof gid_str),
2620					ib_get_err_str(status),
2621					ib_get_mad_status_str((ib_mad_t *)
2622							      (&res_sa_mad)));
2623				fail_to_delete_mcg++;
2624			}
2625		} else {
2626			end_ipoib_cnt++;
2627		}
2628		p_mgrp = (osmtest_mgrp_t *) cl_qmap_next(&p_mgrp->map_item);
2629	}
2630
2631	status = osmt_query_mcast(p_osmt);
2632
2633	if (status != IB_SUCCESS) {
2634		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02B2 "
2635			"GetTable of all records has failed - got %s\n",
2636			ib_get_err_str(status));
2637		goto Exit;
2638	}
2639
2640	/* If we are in single mode check flow - need to make sure all the multicast groups
2641	   that are left are not ones created during the flow.
2642	 */
2643	if (p_osmt->opt.mmode == 1 || p_osmt->opt.mmode == 3) {
2644		end_cnt = cl_qmap_count(&p_osmt->exp_subn.mgrp_mlid_tbl);
2645
2646		OSM_LOG(&p_osmt->log, OSM_LOG_INFO, "Status of MC Records in SA DB during the test flow:\n" "  Beginning of test\n" "       Unrelated to the test: %d\n" "       IPoIB MC Records     : %d\n" "       Total                : %d\n" "  End of test\n" "       Failed to delete     : %d\n" "       IPoIB MC Records     : %d\n" "       Total                : %d\n", mcg_outside_test_cnt,	/* Non-IPoIB that existed at the beginning */
2647			start_ipoib_cnt,	/* IPoIB records */
2648			start_cnt,	/* Total: IPoIB and MC Records unrelated to the test */
2649			fail_to_delete_mcg,	/* Failed to delete at the end */
2650			end_ipoib_cnt,	/* IPoIB records */
2651			end_cnt);	/* Total MC Records at the end */
2652
2653		/* when we compare num of MCG we should consider an outside source which create other MCGs */
2654		if ((end_cnt - fail_to_delete_mcg - end_ipoib_cnt) !=
2655		    (start_cnt - mcg_outside_test_cnt - start_ipoib_cnt)) {
2656			OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
2657				"Got different number of non-IPoIB records stored in SA DB\n\t\t"
2658				"at Start got %d, at End got %d (IPoIB groups only)\n",
2659				(start_cnt - mcg_outside_test_cnt -
2660				 start_ipoib_cnt),
2661				(end_cnt - fail_to_delete_mcg - end_ipoib_cnt));
2662		}
2663
2664		p_mgrp_mlid_tbl = &p_osmt->exp_subn.mgrp_mlid_tbl;
2665		p_mgrp = (osmtest_mgrp_t *) cl_qmap_head(p_mgrp_mlid_tbl);
2666		while (p_mgrp !=
2667		       (osmtest_mgrp_t *) cl_qmap_end(p_mgrp_mlid_tbl)) {
2668			uint16_t mlid =
2669			    (uint16_t) cl_qmap_key((cl_map_item_t *) p_mgrp);
2670
2671			OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
2672				"Found MLID:0x%04X\n", mlid);
2673			/* Check if the mlid is in the test_created_mlids. If TRUE, then we
2674			   didn't delete a MCgroup that was created in this flow. */
2675			if (cl_map_get(&test_created_mlids, mlid) != NULL) {
2676				/* This means that we still have an mgrp that we created!! */
2677				OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02FE: "
2678					"Wasn't able to erase mgrp with MGID:%s"
2679					" MLID:0x%04X\n",
2680					inet_ntop(AF_INET6,
2681						  p_mgrp->mcmember_rec.mgid.raw,
2682						  gid_str, sizeof gid_str),
2683					mlid);
2684				got_error = TRUE;
2685			} else {
2686				OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
2687					"Still exists %s MGID:%s\n",
2688					(IS_IPOIB_MGID
2689					 (&p_mgrp->mcmember_rec.
2690					  mgid)) ? "IPoIB" : "non-IPoIB",
2691					inet_ntop(AF_INET6,
2692						p_mgrp->mcmember_rec.mgid.raw,
2693						gid_str, sizeof gid_str));
2694			}
2695			p_mgrp =
2696			    (osmtest_mgrp_t *) cl_qmap_next(&p_mgrp->map_item);
2697		}
2698
2699		if (got_error) {
2700			__osmt_print_all_multicast_records(p_osmt);
2701			status = IB_ERROR;
2702		}
2703	}
2704Exit:
2705	OSM_LOG_EXIT(&p_osmt->log);
2706	return status;
2707}
2708