1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #pragma ident "%Z%%M% %I% %E% SMI"
27
28 #include <sys/types.h>
29 #include <sys/kmem.h>
30 #include <sys/sunddi.h>
31 #include <sys/ib/mgt/ibmf/ibmf_saa_impl.h>
32 #include <sys/ib/mgt/ibmf/ibmf_saa_utils.h>
33
34 #define IBMF_SAA_HDR_SIZE 20
35 #define IBMF_SAA_DEFAULT_RID_SIZE 4
36 #define IBMF_SAA_PARTITION_RID_SIZE 5
37 #define IBMF_SAA_INFORMINFO_RID_SIZE 18
38
39 #define IB_MAD_NOTICE_SIZE 80
40 #define IB_MAD_CLASSPORTINFO_SIZE 72
41 #define IB_MAD_INFORMINFO_SIZE 36
42
43 #define SM_TRAP_DATA_DETAILS_SIZE 54
44 #define SM_NODEINFO_SIZE 40
45 #define SM_NODEDESC_SIZE 64
46 #define SM_PORTINFO_SIZE 54
47 #define SM_SLTOVL_SIZE 8
48 #define SM_SWITCHINFO_SIZE 17
49 #define SM_LINEARFDB_SIZE 64
50 #define SM_RANDOMFDB_SIZE 64
51 #define SM_MULTICASTFDB_SIZE 64
52 #define SM_SMINFO_SIZE 21
53 #define SM_GUIDINFO_SIZE 64
54 #define SM_PARTITION_SIZE 64
55 #define SM_VLARB_SIZE 64
56
57 #define IBMF_SAA_NODE_RECORD_SIZE 108
58 #define IBMF_SAA_PORTINFO_RECORD_SIZE 58
59 #define IBMF_SAA_SLTOVL_RECORD_SIZE 16
60 #define IBMF_SAA_SWITCHINFO_RECORD_SIZE 21
61 #define IBMF_SAA_LINEARFDB_RECORD_SIZE 72
62 #define IBMF_SAA_RANDOMFDB_RECORD_SIZE 72
63 #define IBMF_SAA_MULTICASTFDB_RECORD_SIZE 72
64 #define IBMF_SAA_SMINFO_RECORD_SIZE 25
65 #define IBMF_SAA_INFORMINFO_RECORD_SIZE 60
66 #define IBMF_SAA_LINK_RECORD_SIZE 6
67 #define IBMF_SAA_GUIDINFO_RECORD_SIZE 72
68 #define IBMF_SAA_SERVICE_RECORD_SIZE 176
69 #define IBMF_SAA_PARTITION_RECORD_SIZE 72
70 #define IBMF_SAA_PATH_RECORD_SIZE 64
71 #define IBMF_SAA_VLARB_RECORD_SIZE 72
72 #define IBMF_SAA_MCMEMBER_RECORD_SIZE 52
73 #define IBMF_SAA_TRACE_RECORD_SIZE 46
74 #define IBMF_SAA_MULTIPATH_RECORD_SIZE 24
75 #define IBMF_SAA_SERVICEASSN_RECORD_SIZE 80
76
77 extern int ibmf_trace_level;
78
79 /* These functions have only been tested on a big-endian system */
80 static void ibmf_saa_classportinfo_parse_buffer(uchar_t *buffer, void *record);
81 static void ibmf_saa_notice_parse_buffer(uchar_t *buffer, void *record);
82 static void ibmf_saa_informinfo_parse_buffer(uchar_t *buffer, void *record);
83 static void ibmf_saa_node_record_parse_buffer(uchar_t *buffer, void *record);
84 static void ibmf_saa_portinfo_record_parse_buffer(uchar_t *buffer,
85 void *record);
86 static void ibmf_saa_SLtoVLmapping_record_parse_buffer(uchar_t *buffer,
87 void *record);
88 static void ibmf_saa_switchinfo_record_parse_buffer(uchar_t *buffer,
89 void *record);
90 static void ibmf_saa_linearft_record_parse_buffer(uchar_t *buffer,
91 void *record);
92 static void ibmf_saa_randomft_record_parse_buffer(uchar_t *buffer,
93 void *record);
94 static void ibmf_saa_multicastft_record_parse_buffer(uchar_t *buffer,
95 void *record);
96 static void ibmf_saa_sminfo_record_parse_buffer(uchar_t *buffer, void *record);
97 static void ibmf_saa_informinfo_record_parse_buffer(uchar_t *buffer,
98 void *record);
99 static void ibmf_saa_link_record_parse_buffer(uchar_t *buffer, void *record);
100 static void ibmf_saa_guidinfo_record_parse_buffer(uchar_t *buffer,
101 void *record);
102 static void ibmf_saa_service_record_parse_buffer(uchar_t *buffer, void *record);
103 static void ibmf_saa_partition_record_parse_buffer(uchar_t *buffer,
104 void *record);
105 static void ibmf_saa_path_record_parse_buffer(uchar_t *buffer, void *record);
106 static void ibmf_saa_vlarb_record_parse_buffer(uchar_t *buffer, void *record);
107 static void ibmf_saa_mcmember_record_parse_buffer(uchar_t *buffer,
108 void *record);
109 static void ibmf_saa_trace_record_parse_buffer(uchar_t *buffer, void *record);
110 static void ibmf_saa_multipath_record_parse_buffer(uchar_t *buffer,
111 void *record);
112 static void ibmf_saa_service_assn_record_parse_buffer(uchar_t *buffer,
113 void *record);
114
115 static void ibmf_saa_classportinfo_to_buf(void *record, uchar_t *buffer);
116 static void ibmf_saa_notice_to_buf(void *record, uchar_t *buffer);
117 static void ibmf_saa_informinfo_to_buf(void *record, uchar_t *buffer);
118 static void ibmf_saa_node_record_to_buf(void *record, uchar_t *buffer);
119 static void ibmf_saa_portinfo_record_to_buf(void *record, uchar_t *buffer);
120 static void ibmf_saa_SLtoVLmapping_record_to_buf(void *record, uchar_t *buffer);
121 static void ibmf_saa_switchinfo_record_to_buf(void *record, uchar_t *buffer);
122 static void ibmf_saa_linearft_record_to_buf(void *record, uchar_t *buffer);
123 static void ibmf_saa_randomft_record_to_buf(void *record, uchar_t *buffer);
124 static void ibmf_saa_multicastft_record_to_buf(void *record, uchar_t *buffer);
125 static void ibmf_saa_sminfo_record_to_buf(void *record, uchar_t *buffer);
126 static void ibmf_saa_informinfo_record_to_buf(void *record, uchar_t *buffer);
127 static void ibmf_saa_link_record_to_buf(void *record, uchar_t *buffer);
128 static void ibmf_saa_guidinfo_record_to_buf(void *record, uchar_t *buffer);
129 static void ibmf_saa_service_record_to_buf(void *record, uchar_t *buffer);
130 static void ibmf_saa_partition_record_to_buf(void *record, uchar_t *buffer);
131 static void ibmf_saa_path_record_to_buf(void *record, uchar_t *buffer);
132 static void ibmf_saa_vlarb_record_to_buf(void *record, uchar_t *buffer);
133 static void ibmf_saa_mcmember_record_to_buf(void *record, uchar_t *buffer);
134 static void ibmf_saa_multipath_record_to_buf(void *record, uchar_t *buffer);
135 static void ibmf_saa_service_assn_record_to_buf(void *record, uchar_t *buffer);
136
137 /*
138 * *_record_parse_buffer functions:
139 *
140 * Each of these functions parses a buffer containing a single SA record.
141 * The function copies the buffer into a structure taking care of any padding
142 * and byte-endianness issues. There is one function for each of the 22
143 * attributes (Table 155).
144 *
145 * ibmf_utils_unpack_data() must be called for each structure in the structure
146 * since Solaris will align the internal structure on a 64-bit boundary, even if
147 * the first element is a 32-bit value.
148 *
149 * Input Arguments
150 * buffer pointer character array containing raw data
151 *
152 * Output Arguments
153 * record pointer to the SA attribute structure
154 *
155 * Returns void
156 */
157
158 static void
ibmf_saa_classportinfo_parse_buffer(uchar_t * buffer,void * record)159 ibmf_saa_classportinfo_parse_buffer(uchar_t *buffer, void *record)
160 {
161 ib_mad_classportinfo_t *cpi = (ib_mad_classportinfo_t *)record;
162
163 ibmf_utils_unpack_data("2csl2Ll2s2l2Ll2s2l", buffer,
164 IB_MAD_CLASSPORTINFO_SIZE, cpi, sizeof (ib_mad_classportinfo_t));
165 }
166
167 static void
ibmf_saa_notice_parse_buffer(uchar_t * buffer,void * record)168 ibmf_saa_notice_parse_buffer(uchar_t *buffer, void *record)
169 {
170 ib_mad_notice_t *notice = (ib_mad_notice_t *)record;
171
172 ibmf_utils_unpack_data("4c3s54c2L", buffer, IB_MAD_NOTICE_SIZE,
173 notice, sizeof (ib_mad_notice_t));
174 }
175
176 static void
ibmf_saa_informinfo_parse_buffer(uchar_t * buffer,void * record)177 ibmf_saa_informinfo_parse_buffer(uchar_t *buffer, void *record)
178 {
179 ib_mad_informinfo_t *informinfo = (ib_mad_informinfo_t *)record;
180
181 ibmf_utils_unpack_data("2L3s2c2s2l", buffer, IB_MAD_INFORMINFO_SIZE,
182 informinfo, sizeof (ib_mad_informinfo_t));
183 }
184
185 static void
ibmf_saa_node_record_parse_buffer(uchar_t * buffer,void * record)186 ibmf_saa_node_record_parse_buffer(uchar_t *buffer, void *record)
187 {
188 sa_node_record_t *node_record = (sa_node_record_t *)record;
189
190 /* first get record identifier information */
191 ibmf_utils_unpack_data("2s", buffer, IBMF_SAA_DEFAULT_RID_SIZE,
192 node_record, 4);
193
194 buffer += IBMF_SAA_DEFAULT_RID_SIZE;
195
196 /* next get node info */
197 ibmf_utils_unpack_data("4c3L2s2l", buffer, SM_NODEINFO_SIZE,
198 &node_record->NodeInfo, sizeof (sm_nodeinfo_t));
199
200 buffer += SM_NODEINFO_SIZE;
201
202 ibmf_utils_unpack_data("64c", buffer, SM_NODEDESC_SIZE,
203 &node_record->NodeDescription, sizeof (sm_nodedesc_t));
204 }
205
206 static void
ibmf_saa_portinfo_record_parse_buffer(uchar_t * buffer,void * record)207 ibmf_saa_portinfo_record_parse_buffer(uchar_t *buffer, void *record)
208 {
209
210 sa_portinfo_record_t *portinfo_record =
211 (sa_portinfo_record_t *)record;
212
213 /* first get record identifier information */
214 ibmf_utils_unpack_data("s2c", buffer, IBMF_SAA_DEFAULT_RID_SIZE,
215 portinfo_record, 4);
216
217 buffer += IBMF_SAA_DEFAULT_RID_SIZE;
218
219 /* next get portinfo info */
220 ibmf_utils_unpack_data("LLsslss16c3s4c", buffer, SM_PORTINFO_SIZE,
221 &portinfo_record->PortInfo, sizeof (sm_portinfo_t));
222 }
223
224 static void
ibmf_saa_SLtoVLmapping_record_parse_buffer(uchar_t * buffer,void * record)225 ibmf_saa_SLtoVLmapping_record_parse_buffer(uchar_t *buffer, void *record)
226 {
227
228 sa_SLtoVLmapping_record_t *SLtoVLmapping_record =
229 (sa_SLtoVLmapping_record_t *)record;
230
231 /* first get record identifier information (plus 4 bytes reserved) */
232 ibmf_utils_unpack_data("s2cl", buffer, IBMF_SAA_DEFAULT_RID_SIZE + 4,
233 SLtoVLmapping_record, 8);
234
235 /* SLtoVL mapping has 4 reserved bytes between RID and attribute */
236 buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4;
237
238 /* next get SLtoVLmapping info */
239 ibmf_utils_unpack_data("8c", buffer, SM_SLTOVL_SIZE,
240 &SLtoVLmapping_record->SLtoVLMappingTable,
241 sizeof (sm_SLtoVL_mapping_table_t));
242 }
243
244 static void
ibmf_saa_switchinfo_record_parse_buffer(uchar_t * buffer,void * record)245 ibmf_saa_switchinfo_record_parse_buffer(uchar_t *buffer, void *record)
246 {
247
248 sa_switchinfo_record_t *switchinfo_record =
249 (sa_switchinfo_record_t *)record;
250
251 /* first get record identifier information */
252 ibmf_utils_unpack_data("2s", buffer, IBMF_SAA_DEFAULT_RID_SIZE,
253 switchinfo_record, 4);
254
255 buffer += IBMF_SAA_DEFAULT_RID_SIZE;
256
257 /* next get switchinfo info */
258 ibmf_utils_unpack_data("4s4c2sc", buffer, SM_SWITCHINFO_SIZE,
259 &switchinfo_record->SwitchInfo, sizeof (sm_switchinfo_t));
260
261 }
262
263 static void
ibmf_saa_linearft_record_parse_buffer(uchar_t * buffer,void * record)264 ibmf_saa_linearft_record_parse_buffer(uchar_t *buffer, void *record)
265 {
266
267 sa_linearft_record_t *linearft_record =
268 (sa_linearft_record_t *)record;
269
270 /* first get record identifier information (plus 4 bytes reserved) */
271 ibmf_utils_unpack_data("2sl", buffer, IBMF_SAA_DEFAULT_RID_SIZE + 4,
272 linearft_record, 8);
273
274 /* LFT has 4 reserved bytes between RID and attribute */
275 buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4;
276
277 /* next get linearft info */
278 ibmf_utils_unpack_data("64c", buffer, SM_LINEARFDB_SIZE,
279 &linearft_record->LinearFT, sizeof (sm_linear_forwarding_table_t));
280 }
281
282 static void
ibmf_saa_randomft_record_parse_buffer(uchar_t * buffer,void * record)283 ibmf_saa_randomft_record_parse_buffer(uchar_t *buffer, void *record)
284 {
285
286 sa_randomft_record_t *randomft_record =
287 (sa_randomft_record_t *)record;
288
289 /* first get record identifier information (plus 4 bytes reserved) */
290 ibmf_utils_unpack_data("2sl", buffer, IBMF_SAA_DEFAULT_RID_SIZE + 4,
291 randomft_record, 8);
292
293 /* RFT has 4 reserved bytes between RID and attribute */
294 buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4;
295
296 /* next get randomft info */
297 ibmf_utils_unpack_data("64c", buffer, SM_RANDOMFDB_SIZE,
298 &randomft_record->RandomFT, sizeof (sm_random_forwarding_table_t));
299 }
300
301 static void
ibmf_saa_multicastft_record_parse_buffer(uchar_t * buffer,void * record)302 ibmf_saa_multicastft_record_parse_buffer(uchar_t *buffer, void *record)
303 {
304
305 sa_multicastft_record_t *multicastft_record =
306 (sa_multicastft_record_t *)record;
307
308 /* first get record identifier information (plus 4 bytes reserved) */
309 ibmf_utils_unpack_data("2sl", buffer, IBMF_SAA_DEFAULT_RID_SIZE + 4,
310 multicastft_record, 8);
311
312 /* MFT has 4 reserved bytes between RID and attribute */
313 buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4;
314
315 /* next get multicastft info */
316 ibmf_utils_unpack_data("32s", buffer, SM_MULTICASTFDB_SIZE,
317 &multicastft_record->MulticastFT,
318 sizeof (sm_multicast_forwarding_table_t));
319 }
320
321 static void
ibmf_saa_sminfo_record_parse_buffer(uchar_t * buffer,void * record)322 ibmf_saa_sminfo_record_parse_buffer(uchar_t *buffer, void *record)
323 {
324
325 sa_sminfo_record_t *sminfo_record =
326 (sa_sminfo_record_t *)record;
327
328 /* first get record identifier information */
329 ibmf_utils_unpack_data("2s", buffer, IBMF_SAA_DEFAULT_RID_SIZE,
330 sminfo_record, 4);
331
332 buffer += IBMF_SAA_DEFAULT_RID_SIZE;
333
334 /* next get sminfo info */
335 ibmf_utils_unpack_data("2Llc", buffer, SM_SMINFO_SIZE,
336 &sminfo_record->SMInfo,
337 sizeof (sm_sminfo_t));
338 }
339
340 static void
ibmf_saa_informinfo_record_parse_buffer(uchar_t * buffer,void * record)341 ibmf_saa_informinfo_record_parse_buffer(uchar_t *buffer, void *record)
342 {
343
344 sa_informinfo_record_t *informinfo_record =
345 (sa_informinfo_record_t *)record;
346
347 /* first get record identifier information */
348 ibmf_utils_unpack_data("2Ls", buffer, IBMF_SAA_INFORMINFO_RID_SIZE,
349 informinfo_record, 18);
350
351 /* InformInfo has 6 reserved bytes between RID and attribute */
352 buffer += IBMF_SAA_INFORMINFO_RID_SIZE + 6;
353
354 /* next get informinfo info */
355 ibmf_utils_unpack_data("2L3s2c2s2l", buffer, IB_MAD_INFORMINFO_SIZE,
356 &informinfo_record->InformInfo,
357 sizeof (ib_mad_informinfo_t));
358 }
359
360 static void
ibmf_saa_link_record_parse_buffer(uchar_t * buffer,void * record)361 ibmf_saa_link_record_parse_buffer(uchar_t *buffer, void *record)
362 {
363
364 sa_link_record_t *link_record = (sa_link_record_t *)record;
365
366 ibmf_utils_unpack_data("s2cs", buffer, IBMF_SAA_LINK_RECORD_SIZE,
367 link_record, sizeof (sa_link_record_t));
368 }
369
370 static void
ibmf_saa_guidinfo_record_parse_buffer(uchar_t * buffer,void * record)371 ibmf_saa_guidinfo_record_parse_buffer(uchar_t *buffer, void *record)
372 {
373
374 sa_guidinfo_record_t *guidinfo_record =
375 (sa_guidinfo_record_t *)record;
376
377 /* first get record identifier information (plus 4 bytes reserved) */
378 ibmf_utils_unpack_data("s2cl", buffer, IBMF_SAA_DEFAULT_RID_SIZE + 4,
379 guidinfo_record, 8);
380
381 /* GUIDInfo has 4 reserved bytes between RID and attribute */
382 buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4;
383
384 /* next get guidinfo info */
385 ibmf_utils_unpack_data("8L", buffer, SM_GUIDINFO_SIZE,
386 &guidinfo_record->GUIDInfo, sizeof (sm_guidinfo_t));
387 }
388
389 static void
ibmf_saa_service_record_parse_buffer(uchar_t * buffer,void * record)390 ibmf_saa_service_record_parse_buffer(uchar_t *buffer, void *record)
391 {
392
393 sa_service_record_t *service_record = (sa_service_record_t *)record;
394
395 ibmf_utils_unpack_data("3L2sl2L64c16c8s4l2L", buffer,
396 IBMF_SAA_SERVICE_RECORD_SIZE, service_record,
397 sizeof (sa_service_record_t));
398 }
399
400 static void
ibmf_saa_partition_record_parse_buffer(uchar_t * buffer,void * record)401 ibmf_saa_partition_record_parse_buffer(uchar_t *buffer, void *record)
402 {
403
404 sa_pkey_table_record_t *partition_record =
405 (sa_pkey_table_record_t *)record;
406
407 /* first get record identifier information (plus 4 bytes reserved) */
408 ibmf_utils_unpack_data("2s4c", buffer, IBMF_SAA_PARTITION_RID_SIZE + 3,
409 partition_record, 8);
410
411 /* Partition record has 3 reserved bytes between RID and attribute */
412 buffer += IBMF_SAA_PARTITION_RID_SIZE + 3;
413
414 /* next get partition info */
415 ibmf_utils_unpack_data("32s", buffer, SM_PARTITION_SIZE,
416 &partition_record->P_KeyTable, sizeof (sm_pkey_table_t));
417 }
418
419 static void
ibmf_saa_path_record_parse_buffer(uchar_t * buffer,void * record)420 ibmf_saa_path_record_parse_buffer(uchar_t *buffer, void *record)
421 {
422
423 sa_path_record_t *path_record = (sa_path_record_t *)record;
424
425 ibmf_utils_unpack_data("2l4L2sl2c2s4c", buffer,
426 IBMF_SAA_PATH_RECORD_SIZE, path_record, sizeof (sa_path_record_t));
427 }
428
429 static void
ibmf_saa_vlarb_record_parse_buffer(uchar_t * buffer,void * record)430 ibmf_saa_vlarb_record_parse_buffer(uchar_t *buffer, void *record)
431 {
432
433 sa_VLarb_table_record_t *VLarb_table_record =
434 (sa_VLarb_table_record_t *)record;
435
436 /* first get record identifier information (plus 4 bytes reserved) */
437 ibmf_utils_unpack_data("s2c", buffer, IBMF_SAA_DEFAULT_RID_SIZE + 4,
438 VLarb_table_record, 8);
439
440 /* VLarb record has 4 reserved bytes between RID and attribute */
441 buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4;
442
443 /* next get VLarb_table info */
444 ibmf_utils_unpack_data("64c", buffer, SM_VLARB_SIZE,
445 &VLarb_table_record->VLArbTable,
446 sizeof (sm_VLarb_table_t));
447 }
448
449 static void
ibmf_saa_mcmember_record_parse_buffer(uchar_t * buffer,void * record)450 ibmf_saa_mcmember_record_parse_buffer(uchar_t *buffer, void *record)
451 {
452
453 sa_mcmember_record_t *mcmember_record =
454 (sa_mcmember_record_t *)record;
455
456 ibmf_utils_unpack_data("4Lls2cs2c2l", buffer,
457 IBMF_SAA_MCMEMBER_RECORD_SIZE,
458 mcmember_record, sizeof (sa_mcmember_record_t));
459 }
460
461 static void
ibmf_saa_trace_record_parse_buffer(uchar_t * buffer,void * record)462 ibmf_saa_trace_record_parse_buffer(uchar_t *buffer, void *record)
463 {
464
465 sa_trace_record_t *trace_record =
466 (sa_trace_record_t *)record;
467
468 ibmf_utils_unpack_data("Ls2c4L2c", buffer,
469 IBMF_SAA_TRACE_RECORD_SIZE,
470 trace_record, sizeof (sa_trace_record_t));
471 }
472
473 /*
474 * ibmf_saa_multipath_record_parse_buffer:
475 *
476 * First unpack the standard part of the multipath record. Then find the number
477 * of gids and unpack those. This function will probably never be called as the
478 * ibmf_saa should not receive any multipath records. It's in here for
479 * completeness.
480 */
ibmf_saa_multipath_record_parse_buffer(uchar_t * buffer,void * record)481 static void ibmf_saa_multipath_record_parse_buffer(uchar_t *buffer,
482 void *record)
483 {
484 char gid_str[20];
485 uint16_t num_gids;
486
487 sa_multipath_record_t *multipath_record =
488 (sa_multipath_record_t *)record;
489
490 ibmf_utils_unpack_data("l2c2s14c", buffer,
491 IBMF_SAA_MULTIPATH_RECORD_SIZE, multipath_record,
492 sizeof (sa_multipath_record_t));
493
494 num_gids = multipath_record->SGIDCount + multipath_record->DGIDCount;
495
496 (void) sprintf(gid_str, "%dL", 2 * num_gids);
497
498 ibmf_utils_unpack_data(gid_str, buffer + IBMF_SAA_MULTIPATH_RECORD_SIZE,
499 sizeof (ib_gid_t) * num_gids,
500 multipath_record + sizeof (sa_multipath_record_t),
501 sizeof (ib_gid_t) * num_gids);
502
503 }
504
505 static void
ibmf_saa_service_assn_record_parse_buffer(uchar_t * buffer,void * record)506 ibmf_saa_service_assn_record_parse_buffer(uchar_t *buffer, void *record)
507 {
508
509 sa_service_assn_record_t *service_assn_record =
510 (sa_service_assn_record_t *)record;
511
512 ibmf_utils_unpack_data("2L64c", buffer,
513 IBMF_SAA_SERVICEASSN_RECORD_SIZE,
514 service_assn_record, sizeof (sa_service_assn_record_t));
515 }
516
517 void
ibmf_saa_gid_trap_parse_buffer(uchar_t * buffer,sm_trap_64_t * sm_trap_64)518 ibmf_saa_gid_trap_parse_buffer(uchar_t *buffer, sm_trap_64_t *sm_trap_64)
519 {
520
521 ibmf_utils_unpack_data("6c2L32c", buffer, SM_TRAP_DATA_DETAILS_SIZE,
522 sm_trap_64, sizeof (sm_trap_64_t));
523 }
524
525 void
ibmf_saa_capmask_chg_trap_parse_buffer(uchar_t * buffer,sm_trap_144_t * sm_trap_144)526 ibmf_saa_capmask_chg_trap_parse_buffer(uchar_t *buffer,
527 sm_trap_144_t *sm_trap_144)
528 {
529
530 ibmf_utils_unpack_data("2cs2cl44c", buffer, SM_TRAP_DATA_DETAILS_SIZE,
531 sm_trap_144, sizeof (sm_trap_144_t));
532 }
533
534 void
ibmf_saa_sysimg_guid_chg_trap_parse_buffer(uchar_t * buffer,sm_trap_145_t * sm_trap_145)535 ibmf_saa_sysimg_guid_chg_trap_parse_buffer(uchar_t *buffer,
536 sm_trap_145_t *sm_trap_145)
537 {
538
539 ibmf_utils_unpack_data("2cs2cL44c", buffer, SM_TRAP_DATA_DETAILS_SIZE,
540 sm_trap_145, sizeof (sm_trap_145_t));
541 }
542
543 /*
544 * *_record_to_buf functions:
545 *
546 * Each of these functions copies a single SA record out of a structure and into
547 * a buffer for sending on the wire. The function will take care of any padding
548 * and byte-endianness isues. There is one function for each of the 22
549 * attributes (Table 155).
550 *
551 * ibmf_utils_pack_data() must be called for each structure in the structure
552 * since Solaris will align the internal structure on a 64-bit boundary, even if
553 * the first element is a 32-bit value.
554 *
555 * Input Arguments
556 * record pointer to the structure to be parsed
557 *
558 * Output Arguments
559 * buffer pointer to array to place the data in (allocated by caller)
560 *
561 * Returns void
562 */
563
564 static void
ibmf_saa_classportinfo_to_buf(void * record,uchar_t * buffer)565 ibmf_saa_classportinfo_to_buf(void *record, uchar_t *buffer)
566 {
567 ib_mad_classportinfo_t *cpi = (ib_mad_classportinfo_t *)record;
568
569 ibmf_utils_pack_data("2csl2Ll2s2l2Ll2s2l",
570 cpi, sizeof (ib_mad_classportinfo_t),
571 buffer, IB_MAD_CLASSPORTINFO_SIZE);
572 }
573
574 static void
ibmf_saa_notice_to_buf(void * record,uchar_t * buffer)575 ibmf_saa_notice_to_buf(void *record, uchar_t *buffer)
576 {
577 ib_mad_notice_t *notice = (ib_mad_notice_t *)record;
578
579 ibmf_utils_pack_data("4c3s54c2L", notice, sizeof (ib_mad_notice_t),
580 buffer, IB_MAD_NOTICE_SIZE);
581 }
582
583 static void
ibmf_saa_informinfo_to_buf(void * record,uchar_t * buffer)584 ibmf_saa_informinfo_to_buf(void *record, uchar_t *buffer)
585 {
586 ib_mad_informinfo_t *informinfo = (ib_mad_informinfo_t *)record;
587
588 ibmf_utils_pack_data("2L3s2c2s2l", informinfo,
589 sizeof (ib_mad_informinfo_t), buffer, IB_MAD_INFORMINFO_SIZE);
590 }
591
592 static void
ibmf_saa_node_record_to_buf(void * record,uchar_t * buffer)593 ibmf_saa_node_record_to_buf(void *record, uchar_t *buffer)
594 {
595
596 sa_node_record_t *node_record = (sa_node_record_t *)record;
597
598 /* first get record identifier information */
599 ibmf_utils_pack_data("2s", node_record, 4, buffer,
600 IBMF_SAA_DEFAULT_RID_SIZE);
601
602 buffer += IBMF_SAA_DEFAULT_RID_SIZE;
603
604 /* next get node info */
605 ibmf_utils_pack_data("4c3L2s2l", &node_record->NodeInfo,
606 sizeof (sm_nodeinfo_t), buffer, SM_NODEINFO_SIZE);
607
608 buffer += SM_NODEINFO_SIZE;
609
610 /* next get node description */
611 ibmf_utils_pack_data("64c", &node_record->NodeDescription,
612 sizeof (sm_nodedesc_t), buffer, SM_NODEDESC_SIZE);
613
614 }
615
616 static void
ibmf_saa_portinfo_record_to_buf(void * record,uchar_t * buffer)617 ibmf_saa_portinfo_record_to_buf(void *record, uchar_t *buffer)
618 {
619
620 sa_portinfo_record_t *portinfo_record =
621 (sa_portinfo_record_t *)record;
622
623 /* first get record identifier information */
624 ibmf_utils_pack_data("s2c", portinfo_record, 4, buffer,
625 IBMF_SAA_DEFAULT_RID_SIZE);
626
627 buffer += IBMF_SAA_DEFAULT_RID_SIZE;
628
629 /* next get portinfo info */
630 ibmf_utils_pack_data("LLsslss16c3s4c",
631 &portinfo_record->PortInfo, sizeof (sm_portinfo_t), buffer,
632 SM_PORTINFO_SIZE);
633
634 }
635
636 static void
ibmf_saa_SLtoVLmapping_record_to_buf(void * record,uchar_t * buffer)637 ibmf_saa_SLtoVLmapping_record_to_buf(void *record, uchar_t *buffer)
638 {
639
640 sa_SLtoVLmapping_record_t *SLtoVLmapping_record =
641 (sa_SLtoVLmapping_record_t *)record;
642
643 /* first get record identifier information (plus 4 bytes reserved) */
644 ibmf_utils_pack_data("s2cl", SLtoVLmapping_record, 8, buffer,
645 IBMF_SAA_DEFAULT_RID_SIZE + 4);
646
647 /* SLtoVL mapping has 4 reserved bytes between RID and attribute */
648 buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4;
649
650 /* next get SLtoVLmapping info */
651 ibmf_utils_pack_data("8c", &SLtoVLmapping_record->SLtoVLMappingTable,
652 sizeof (sm_SLtoVL_mapping_table_t), buffer, SM_SLTOVL_SIZE);
653 }
654
655 static void
ibmf_saa_switchinfo_record_to_buf(void * record,uchar_t * buffer)656 ibmf_saa_switchinfo_record_to_buf(void *record, uchar_t *buffer)
657 {
658
659 sa_switchinfo_record_t *switchinfo_record =
660 (sa_switchinfo_record_t *)record;
661
662 /* first get record identifier information */
663 ibmf_utils_pack_data("2s", switchinfo_record, 4, buffer,
664 IBMF_SAA_DEFAULT_RID_SIZE);
665
666 buffer += IBMF_SAA_DEFAULT_RID_SIZE;
667
668 /* next get switchinfo info */
669 ibmf_utils_pack_data("4s4c2sc", &switchinfo_record->SwitchInfo,
670 sizeof (sm_switchinfo_t), buffer, SM_SWITCHINFO_SIZE);
671
672 }
673
674 static void
ibmf_saa_linearft_record_to_buf(void * record,uchar_t * buffer)675 ibmf_saa_linearft_record_to_buf(void *record, uchar_t *buffer)
676 {
677
678 sa_linearft_record_t *linearft_record =
679 (sa_linearft_record_t *)record;
680
681 /* first get record identifier information (plus 4 bytes reserved) */
682 ibmf_utils_pack_data("2sl", linearft_record, 8, buffer,
683 IBMF_SAA_DEFAULT_RID_SIZE + 4);
684
685 /* LFT has 4 reserved bytes between RID and attribute */
686 buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4;
687
688 /* next get linearft info */
689 ibmf_utils_pack_data("64c", &linearft_record->LinearFT,
690 sizeof (sm_linear_forwarding_table_t), buffer, SM_LINEARFDB_SIZE);
691 }
692
693 static void
ibmf_saa_randomft_record_to_buf(void * record,uchar_t * buffer)694 ibmf_saa_randomft_record_to_buf(void *record, uchar_t *buffer)
695 {
696
697 sa_randomft_record_t *randomft_record =
698 (sa_randomft_record_t *)record;
699
700 /* first get record identifier information (plus 4 bytes reserved) */
701 ibmf_utils_pack_data("2sl", randomft_record, 8, buffer,
702 IBMF_SAA_DEFAULT_RID_SIZE + 4);
703
704 /* RFT has 4 reserved bytes between RID and attribute */
705 buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4;
706
707 /* next get randomft info */
708 ibmf_utils_pack_data("64c", &randomft_record->RandomFT,
709 sizeof (sm_random_forwarding_table_t), buffer, SM_RANDOMFDB_SIZE);
710 }
711
712 static void
ibmf_saa_multicastft_record_to_buf(void * record,uchar_t * buffer)713 ibmf_saa_multicastft_record_to_buf(void *record, uchar_t *buffer)
714 {
715
716 sa_multicastft_record_t *multicastft_record =
717 (sa_multicastft_record_t *)record;
718
719 /* first get record identifier information (plus 4 bytes reserved) */
720 ibmf_utils_pack_data("2sl", multicastft_record, 8, buffer,
721 IBMF_SAA_DEFAULT_RID_SIZE + 4);
722
723 /* MFT has 4 reserved bytes between RID and attribute */
724 buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4;
725
726 /* next get multicastft info */
727 ibmf_utils_pack_data("32s", &multicastft_record->MulticastFT,
728 sizeof (sm_multicast_forwarding_table_t), buffer,
729 SM_MULTICASTFDB_SIZE);
730 }
731
732 static void
ibmf_saa_sminfo_record_to_buf(void * record,uchar_t * buffer)733 ibmf_saa_sminfo_record_to_buf(void *record, uchar_t *buffer)
734 {
735
736 sa_sminfo_record_t *sminfo_record =
737 (sa_sminfo_record_t *)record;
738
739 /* first get record identifier information */
740 ibmf_utils_pack_data("2s", sminfo_record, 4, buffer,
741 IBMF_SAA_DEFAULT_RID_SIZE);
742
743 buffer += IBMF_SAA_DEFAULT_RID_SIZE;
744
745 /* next get sminfo info */
746 ibmf_utils_pack_data("2Llc", &sminfo_record->SMInfo,
747 sizeof (sm_sminfo_t), buffer, SM_SMINFO_SIZE);
748 }
749
750 static void
ibmf_saa_informinfo_record_to_buf(void * record,uchar_t * buffer)751 ibmf_saa_informinfo_record_to_buf(void *record, uchar_t *buffer)
752 {
753
754 sa_informinfo_record_t *informinfo_record =
755 (sa_informinfo_record_t *)record;
756
757 /* first get record identifier information */
758 ibmf_utils_pack_data("2Ls", informinfo_record, 18, buffer,
759 IBMF_SAA_INFORMINFO_RID_SIZE);
760
761 /* InformInfo has 6 reserved bytes between RID and attribute */
762 buffer += IBMF_SAA_INFORMINFO_RID_SIZE + 6;
763
764 /* next get informinfo info */
765 ibmf_utils_pack_data("2L3s2c2s2l", &informinfo_record->InformInfo,
766 sizeof (ib_mad_informinfo_t), buffer, IB_MAD_INFORMINFO_SIZE);
767 }
768
769 static void
ibmf_saa_link_record_to_buf(void * record,uchar_t * buffer)770 ibmf_saa_link_record_to_buf(void *record, uchar_t *buffer)
771 {
772
773 sa_link_record_t *link_record = (sa_link_record_t *)record;
774
775 ibmf_utils_pack_data("s2cs", link_record,
776 sizeof (sa_link_record_t), buffer, IBMF_SAA_LINK_RECORD_SIZE);
777 }
778
779 static void
ibmf_saa_guidinfo_record_to_buf(void * record,uchar_t * buffer)780 ibmf_saa_guidinfo_record_to_buf(void *record, uchar_t *buffer)
781 {
782
783 sa_guidinfo_record_t *guidinfo_record =
784 (sa_guidinfo_record_t *)record;
785
786 /* first get record identifier information (plus 4 bytes reserved) */
787 ibmf_utils_pack_data("s2cl", guidinfo_record,
788 8, buffer, IBMF_SAA_DEFAULT_RID_SIZE + 4);
789
790 /* GUIDInfo has 4 reserved bytes between RID and attribute */
791 buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4;
792
793 /* next get guidinfo info */
794 ibmf_utils_pack_data("8L", &guidinfo_record->GUIDInfo,
795 sizeof (sm_guidinfo_t), buffer, SM_GUIDINFO_SIZE);
796 }
797
798 static void
ibmf_saa_service_record_to_buf(void * record,uchar_t * buffer)799 ibmf_saa_service_record_to_buf(void *record, uchar_t *buffer)
800 {
801
802 sa_service_record_t *service_record = (sa_service_record_t *)record;
803
804 ibmf_utils_pack_data("3L2sl2L64c16c8s4l2L", service_record,
805 sizeof (sa_service_record_t), buffer, IBMF_SAA_SERVICE_RECORD_SIZE);
806 }
807
808 static void
ibmf_saa_partition_record_to_buf(void * record,uchar_t * buffer)809 ibmf_saa_partition_record_to_buf(void *record, uchar_t *buffer)
810 {
811
812 sa_pkey_table_record_t *partition_record =
813 (sa_pkey_table_record_t *)record;
814
815 /* first get record identifier information (plus 4 bytes reserved) */
816 ibmf_utils_pack_data("2s4c", partition_record, 8, buffer,
817 IBMF_SAA_PARTITION_RID_SIZE + 3);
818
819 /* Partition record has 3 reserved bytes between RID and attribute */
820 buffer += IBMF_SAA_PARTITION_RID_SIZE + 3;
821
822 /* next get partition info */
823 ibmf_utils_pack_data("32s", &partition_record->P_KeyTable,
824 sizeof (sm_pkey_table_t), buffer, SM_PARTITION_SIZE);
825 }
826
827 static void
ibmf_saa_path_record_to_buf(void * record,uchar_t * buffer)828 ibmf_saa_path_record_to_buf(void *record, uchar_t *buffer)
829 {
830
831 sa_path_record_t *path_record = (sa_path_record_t *)record;
832
833 ibmf_utils_pack_data("2l4L2sl2c2s4c", path_record,
834 sizeof (sa_path_record_t), buffer, IBMF_SAA_PATH_RECORD_SIZE);
835 }
836
837 static void
ibmf_saa_vlarb_record_to_buf(void * record,uchar_t * buffer)838 ibmf_saa_vlarb_record_to_buf(void *record, uchar_t *buffer)
839 {
840
841 sa_VLarb_table_record_t *VLarb_table_record =
842 (sa_VLarb_table_record_t *)record;
843
844 /* first get record identifier information (plus 4 bytes reserved) */
845 ibmf_utils_pack_data("s2c", VLarb_table_record, 8, buffer,
846 IBMF_SAA_DEFAULT_RID_SIZE + 4);
847
848 /* VLarb record has 4 reserved bytes between RID and attribute */
849 buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4;
850
851 /* next get VLarb_table info */
852 ibmf_utils_pack_data("64c", &VLarb_table_record->VLArbTable,
853 sizeof (sm_VLarb_table_t), buffer, SM_VLARB_SIZE);
854 }
855
856
857 static void
ibmf_saa_mcmember_record_to_buf(void * record,uchar_t * buffer)858 ibmf_saa_mcmember_record_to_buf(void *record, uchar_t *buffer)
859 {
860
861 sa_mcmember_record_t *mcmember_record =
862 (sa_mcmember_record_t *)record;
863
864 ibmf_utils_pack_data("4Lls2cs2c2l", mcmember_record,
865 sizeof (sa_mcmember_record_t),
866 buffer, IBMF_SAA_MCMEMBER_RECORD_SIZE);
867 }
868
ibmf_saa_multipath_record_to_buf(void * record,uchar_t * buffer)869 static void ibmf_saa_multipath_record_to_buf(void *record, uchar_t *buffer)
870 {
871 char gid_str[20];
872 uint16_t num_gids;
873 sa_multipath_record_t *multipath_record =
874 (sa_multipath_record_t *)record;
875
876 num_gids = multipath_record->SGIDCount + multipath_record->DGIDCount;
877
878 (void) sprintf(gid_str, "l2c2s14c%dL", 2 * num_gids);
879
880 ibmf_utils_pack_data(gid_str, multipath_record,
881 sizeof (sa_multipath_record_t) + sizeof (ib_gid_t) * num_gids,
882 buffer,
883 IBMF_SAA_MULTIPATH_RECORD_SIZE + sizeof (ib_gid_t) * num_gids);
884 }
885
886 static void
ibmf_saa_service_assn_record_to_buf(void * record,uchar_t * buffer)887 ibmf_saa_service_assn_record_to_buf(void *record, uchar_t *buffer)
888 {
889
890 sa_service_assn_record_t *service_assn_record =
891 (sa_service_assn_record_t *)record;
892
893 ibmf_utils_pack_data("2L64c", service_assn_record,
894 sizeof (sa_service_assn_record_t),
895 buffer, IBMF_SAA_SERVICEASSN_RECORD_SIZE);
896 }
897
898 int
ibmf_saa_utils_pack_sa_hdr(ib_sa_hdr_t * sa_hdr,void ** packed_class_hdr,size_t * packed_class_hdr_len,int km_sleep_flag)899 ibmf_saa_utils_pack_sa_hdr(ib_sa_hdr_t *sa_hdr, void **packed_class_hdr,
900 size_t *packed_class_hdr_len, int km_sleep_flag)
901 {
902
903 *packed_class_hdr = kmem_zalloc(IBMF_SAA_HDR_SIZE, km_sleep_flag);
904 if (*packed_class_hdr == NULL) {
905
906 IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L1,
907 ibmf_saa_utils_pack_sa_hdr_err,
908 IBMF_TNF_ERROR, "", "ibmf_saa_utils_pack_sa_hdr: "
909 "could not allocate memory for header\n");
910
911 return (IBMF_NO_MEMORY);
912 }
913
914 ibmf_utils_pack_data("LssL", sa_hdr, sizeof (ib_sa_hdr_t),
915 (uchar_t *)*packed_class_hdr, IBMF_SAA_HDR_SIZE);
916
917 *packed_class_hdr_len = IBMF_SAA_HDR_SIZE;
918
919 return (IBMF_SUCCESS);
920 }
921
922 int
ibmf_saa_utils_unpack_sa_hdr(void * packed_class_hdr,size_t packed_class_hdr_len,ib_sa_hdr_t ** sa_hdr,int km_sleep_flag)923 ibmf_saa_utils_unpack_sa_hdr(void *packed_class_hdr,
924 size_t packed_class_hdr_len, ib_sa_hdr_t **sa_hdr, int km_sleep_flag)
925 {
926 if (packed_class_hdr_len != IBMF_SAA_HDR_SIZE) {
927
928 IBMF_TRACE_3(IBMF_TNF_DEBUG, DPRINT_L1,
929 ibmf_saa_utils_unpack_sa_hdr_err,
930 IBMF_TNF_ERROR, "", "ibmf_saa_utils_unpack_sa_hdr: %s,"
931 " sa_class_hdr_len = %d, pkt_class_hdr_len = %d\n",
932 tnf_string, msg, "invalid class hdr length for SA packet",
933 tnf_int, sa_class_hdr_len, IBMF_SAA_HDR_SIZE,
934 tnf_int, pkt_class_hdr_len, packed_class_hdr_len);
935
936 return (IBMF_REQ_INVALID);
937 }
938
939 *sa_hdr = kmem_zalloc(sizeof (ib_sa_hdr_t), km_sleep_flag);
940 if (*sa_hdr == NULL) {
941
942 IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L1,
943 ibmf_saa_utils_unpack_sa_hdr_err,
944 IBMF_TNF_ERROR, "", "ibmf_saa_utils_unpack_sa_hdr: "
945 "could not allocate memory for header\n");
946
947 return (IBMF_NO_MEMORY);
948 }
949
950 ibmf_utils_unpack_data("LssL", (uchar_t *)packed_class_hdr,
951 IBMF_SAA_HDR_SIZE, *sa_hdr, sizeof (ib_sa_hdr_t));
952
953 return (IBMF_SUCCESS);
954 }
955
956 /*
957 * ibmf_saa_utils_pack_payload:
958 *
959 * Takes a pointer to an array of sa record structures. For each element packs
960 * the structure into a character buffer removing any padding and account for
961 * endianness issues.
962 *
963 */
964 int
ibmf_saa_utils_pack_payload(uchar_t * structs_payload,size_t structs_payload_length,uint16_t attr_id,void ** buf_payloadp,size_t * buf_payload_lengthp,int km_sleep_flag)965 ibmf_saa_utils_pack_payload(uchar_t *structs_payload, size_t
966 structs_payload_length, uint16_t attr_id, void **buf_payloadp,
967 size_t *buf_payload_lengthp, int km_sleep_flag)
968 {
969
970 int i;
971 int struct_size, buf_size;
972 int num_records;
973 void (*pack_data_fn)(void *, uchar_t *);
974
975 if (structs_payload_length == 0) {
976
977 *buf_payload_lengthp = NULL;
978 *buf_payloadp = NULL;
979
980 return (IBMF_SUCCESS);
981 }
982
983 ASSERT(structs_payload != NULL);
984
985 /* trace records should never be sent (or packed) by ibmf_saa */
986 ASSERT(attr_id != SA_TRACERECORD_ATTRID);
987
988 switch (attr_id) {
989 case SA_CLASSPORTINFO_ATTRID:
990 struct_size = sizeof (ib_mad_classportinfo_t);
991 buf_size = IB_MAD_CLASSPORTINFO_SIZE;
992 pack_data_fn = ibmf_saa_classportinfo_to_buf;
993 break;
994 case SA_NOTICE_ATTRID:
995 struct_size = sizeof (ib_mad_notice_t);
996 buf_size = IB_MAD_NOTICE_SIZE;
997 pack_data_fn = ibmf_saa_notice_to_buf;
998 break;
999 case SA_INFORMINFO_ATTRID:
1000 struct_size = sizeof (ib_mad_informinfo_t);
1001 buf_size = IB_MAD_INFORMINFO_SIZE;
1002 pack_data_fn = ibmf_saa_informinfo_to_buf;
1003 break;
1004 case SA_NODERECORD_ATTRID:
1005 struct_size = sizeof (sa_node_record_t);
1006 buf_size = IBMF_SAA_NODE_RECORD_SIZE;
1007 pack_data_fn = ibmf_saa_node_record_to_buf;
1008 break;
1009 case SA_PORTINFORECORD_ATTRID:
1010 struct_size = sizeof (sa_portinfo_record_t);
1011 buf_size = IBMF_SAA_PORTINFO_RECORD_SIZE;
1012 pack_data_fn = ibmf_saa_portinfo_record_to_buf;
1013 break;
1014 case SA_SLTOVLRECORD_ATTRID:
1015 struct_size = sizeof (sa_SLtoVLmapping_record_t);
1016 buf_size = IBMF_SAA_SLTOVL_RECORD_SIZE;
1017 pack_data_fn = ibmf_saa_SLtoVLmapping_record_to_buf;
1018 break;
1019 case SA_SWITCHINFORECORD_ATTRID:
1020 struct_size = sizeof (sa_switchinfo_record_t);
1021 buf_size = IBMF_SAA_SWITCHINFO_RECORD_SIZE;
1022 pack_data_fn = ibmf_saa_switchinfo_record_to_buf;
1023 break;
1024 case SA_LINEARFDBRECORD_ATTRID:
1025 struct_size = sizeof (sa_linearft_record_t);
1026 buf_size = IBMF_SAA_LINEARFDB_RECORD_SIZE;
1027 pack_data_fn = ibmf_saa_linearft_record_to_buf;
1028 break;
1029 case SA_RANDOMFDBRECORD_ATTRID:
1030 struct_size = sizeof (sa_randomft_record_t);
1031 buf_size = IBMF_SAA_RANDOMFDB_RECORD_SIZE;
1032 pack_data_fn = ibmf_saa_randomft_record_to_buf;
1033 break;
1034 case SA_MULTICASTFDBRECORD_ATTRID:
1035 struct_size = sizeof (sa_multicastft_record_t);
1036 buf_size = IBMF_SAA_MULTICASTFDB_RECORD_SIZE;
1037 pack_data_fn = ibmf_saa_multicastft_record_to_buf;
1038 break;
1039 case SA_SMINFORECORD_ATTRID:
1040 struct_size = sizeof (sa_sminfo_record_t);
1041 buf_size = IBMF_SAA_SMINFO_RECORD_SIZE;
1042 pack_data_fn = ibmf_saa_sminfo_record_to_buf;
1043 break;
1044 case SA_INFORMINFORECORD_ATTRID:
1045 struct_size = sizeof (sa_informinfo_record_t);
1046 buf_size = IBMF_SAA_INFORMINFO_RECORD_SIZE;
1047 pack_data_fn = ibmf_saa_informinfo_record_to_buf;
1048 break;
1049 case SA_LINKRECORD_ATTRID:
1050 struct_size = sizeof (sa_link_record_t);
1051 buf_size = IBMF_SAA_LINK_RECORD_SIZE;
1052 pack_data_fn = ibmf_saa_link_record_to_buf;
1053 break;
1054 case SA_GUIDINFORECORD_ATTRID:
1055 struct_size = sizeof (sa_guidinfo_record_t);
1056 buf_size = IBMF_SAA_GUIDINFO_RECORD_SIZE;
1057 pack_data_fn = ibmf_saa_guidinfo_record_to_buf;
1058 break;
1059 case SA_SERVICERECORD_ATTRID:
1060 struct_size = sizeof (sa_service_record_t);
1061 buf_size = IBMF_SAA_SERVICE_RECORD_SIZE;
1062 pack_data_fn = ibmf_saa_service_record_to_buf;
1063 break;
1064 case SA_PARTITIONRECORD_ATTRID:
1065 struct_size = sizeof (sa_pkey_table_record_t);
1066 buf_size = IBMF_SAA_PARTITION_RECORD_SIZE;
1067 pack_data_fn = ibmf_saa_partition_record_to_buf;
1068 break;
1069 case SA_PATHRECORD_ATTRID:
1070 struct_size = sizeof (sa_path_record_t);
1071 buf_size = IBMF_SAA_PATH_RECORD_SIZE;
1072 pack_data_fn = ibmf_saa_path_record_to_buf;
1073 break;
1074 case SA_VLARBRECORD_ATTRID:
1075 struct_size = sizeof (sa_VLarb_table_record_t);
1076 buf_size = IBMF_SAA_VLARB_RECORD_SIZE;
1077 pack_data_fn = ibmf_saa_vlarb_record_to_buf;
1078 break;
1079 case SA_MCMEMBERRECORD_ATTRID:
1080 struct_size = sizeof (sa_mcmember_record_t);
1081 buf_size = IBMF_SAA_MCMEMBER_RECORD_SIZE;
1082 pack_data_fn = ibmf_saa_mcmember_record_to_buf;
1083 break;
1084 case SA_MULTIPATHRECORD_ATTRID:
1085 /*
1086 * array is of size 1 since multipath can be request
1087 * only; data size greater than multipath_record_t
1088 * size is due to gids at the end
1089 */
1090 struct_size = structs_payload_length;
1091 buf_size = IBMF_SAA_MULTIPATH_RECORD_SIZE +
1092 struct_size - sizeof (sa_multipath_record_t);
1093 pack_data_fn = ibmf_saa_multipath_record_to_buf;
1094 break;
1095 case SA_SERVICEASSNRECORD_ATTRID:
1096 struct_size = sizeof (sa_service_assn_record_t);
1097 buf_size = IBMF_SAA_SERVICEASSN_RECORD_SIZE;
1098 pack_data_fn = ibmf_saa_service_assn_record_to_buf;
1099 break;
1100 default:
1101
1102 /* don't know about structure; do bcopy */
1103 *buf_payload_lengthp = structs_payload_length;
1104 *buf_payloadp = kmem_zalloc(*buf_payload_lengthp,
1105 km_sleep_flag);
1106 if (*buf_payloadp == NULL) {
1107
1108 *buf_payload_lengthp = 0;
1109 return (IBMF_NO_MEMORY);
1110 }
1111
1112 bcopy(structs_payload, *buf_payloadp,
1113 *buf_payload_lengthp);
1114
1115 return (IBMF_SUCCESS);
1116 }
1117
1118 *buf_payload_lengthp = structs_payload_length / struct_size * buf_size;
1119 num_records = structs_payload_length / struct_size;
1120 *buf_payloadp = kmem_zalloc(*buf_payload_lengthp, km_sleep_flag);
1121 if (*buf_payloadp == NULL) {
1122
1123 IBMF_TRACE_2(IBMF_TNF_DEBUG, DPRINT_L1,
1124 ibmf_saa_utils_pack_payload_err,
1125 IBMF_TNF_ERROR, "", "ibmf_saa_utils_pack_payload: %s,"
1126 " size = %d\n",
1127 tnf_string, msg, "could not allocate memory for payload",
1128 tnf_int, size, *buf_payload_lengthp);
1129
1130 *buf_payload_lengthp = 0;
1131 return (IBMF_NO_MEMORY);
1132 }
1133
1134 for (i = 0; i < num_records; i++) {
1135
1136 pack_data_fn(
1137 (void *)((uchar_t *)structs_payload + i * struct_size),
1138 ((uchar_t *)*buf_payloadp + i * buf_size));
1139 }
1140
1141 return (IBMF_SUCCESS);
1142 }
1143
1144
1145 /*
1146 * ibmf_saa_utils_unpack_payload:
1147 *
1148 * Unpacks a buffer of data received over the wire and places into an array of
1149 * structure in host format.
1150 *
1151 * for getResp() ibmf always reports payload length as 200 bytes
1152 * (MAD_SIZE - headers). To keep the client from having to determine the actual
1153 * length of the one attribute (since we do it here) the is_get_resp parameter
1154 * indicates that there is one attribute in the buffer.
1155 */
1156 int
ibmf_saa_utils_unpack_payload(uchar_t * buf_payload,size_t buf_payload_length,uint16_t attr_id,void ** structs_payloadp,size_t * structs_payload_lengthp,uint16_t attr_offset,boolean_t is_get_resp,int km_sleep_flag)1157 ibmf_saa_utils_unpack_payload(uchar_t *buf_payload, size_t buf_payload_length,
1158 uint16_t attr_id, void **structs_payloadp, size_t *structs_payload_lengthp,
1159 uint16_t attr_offset, boolean_t is_get_resp, int km_sleep_flag)
1160 {
1161
1162 int i;
1163 int struct_size, buf_size;
1164 int num_records;
1165 void (*unpack_data_fn)(uchar_t *, void *);
1166 int bytes_between_recs;
1167
1168 if (buf_payload_length == 0) {
1169
1170 *structs_payload_lengthp = 0;
1171 *structs_payloadp = NULL;
1172
1173 return (IBMF_SUCCESS);
1174 }
1175
1176 switch (attr_id) {
1177 case SA_CLASSPORTINFO_ATTRID:
1178 struct_size = sizeof (ib_mad_classportinfo_t);
1179 buf_size = IB_MAD_CLASSPORTINFO_SIZE;
1180 unpack_data_fn = ibmf_saa_classportinfo_parse_buffer;
1181 break;
1182 case SA_NOTICE_ATTRID:
1183 struct_size = sizeof (ib_mad_notice_t);
1184 buf_size = IB_MAD_NOTICE_SIZE;
1185 unpack_data_fn = ibmf_saa_notice_parse_buffer;
1186 break;
1187 case SA_INFORMINFO_ATTRID:
1188 struct_size = sizeof (ib_mad_informinfo_t);
1189 buf_size = IB_MAD_INFORMINFO_SIZE;
1190 unpack_data_fn = ibmf_saa_informinfo_parse_buffer;
1191 break;
1192 case SA_NODERECORD_ATTRID:
1193 struct_size = sizeof (sa_node_record_t);
1194 buf_size = IBMF_SAA_NODE_RECORD_SIZE;
1195 unpack_data_fn = ibmf_saa_node_record_parse_buffer;
1196 break;
1197 case SA_PORTINFORECORD_ATTRID:
1198 struct_size = sizeof (sa_portinfo_record_t);
1199 buf_size = IBMF_SAA_PORTINFO_RECORD_SIZE;
1200 unpack_data_fn = ibmf_saa_portinfo_record_parse_buffer;
1201 break;
1202 case SA_SLTOVLRECORD_ATTRID:
1203 struct_size = sizeof (sa_SLtoVLmapping_record_t);
1204 buf_size = IBMF_SAA_SLTOVL_RECORD_SIZE;
1205 unpack_data_fn =
1206 ibmf_saa_SLtoVLmapping_record_parse_buffer;
1207 break;
1208 case SA_SWITCHINFORECORD_ATTRID:
1209 struct_size = sizeof (sa_switchinfo_record_t);
1210 buf_size = IBMF_SAA_SWITCHINFO_RECORD_SIZE;
1211 unpack_data_fn =
1212 ibmf_saa_switchinfo_record_parse_buffer;
1213 break;
1214 case SA_LINEARFDBRECORD_ATTRID:
1215 struct_size = sizeof (sa_linearft_record_t);
1216 buf_size = IBMF_SAA_LINEARFDB_RECORD_SIZE;
1217 unpack_data_fn = ibmf_saa_linearft_record_parse_buffer;
1218 break;
1219 case SA_RANDOMFDBRECORD_ATTRID:
1220 struct_size = sizeof (sa_randomft_record_t);
1221 buf_size = IBMF_SAA_RANDOMFDB_RECORD_SIZE;
1222 unpack_data_fn = ibmf_saa_randomft_record_parse_buffer;
1223 break;
1224 case SA_MULTICASTFDBRECORD_ATTRID:
1225 struct_size = sizeof (sa_multicastft_record_t);
1226 buf_size = IBMF_SAA_MULTICASTFDB_RECORD_SIZE;
1227 unpack_data_fn =
1228 ibmf_saa_multicastft_record_parse_buffer;
1229 break;
1230 case SA_SMINFORECORD_ATTRID:
1231 struct_size = sizeof (sa_sminfo_record_t);
1232 buf_size = IBMF_SAA_SMINFO_RECORD_SIZE;
1233 unpack_data_fn = ibmf_saa_sminfo_record_parse_buffer;
1234 break;
1235 case SA_INFORMINFORECORD_ATTRID:
1236 struct_size = sizeof (sa_informinfo_record_t);
1237 buf_size = IBMF_SAA_INFORMINFO_RECORD_SIZE;
1238 unpack_data_fn =
1239 ibmf_saa_informinfo_record_parse_buffer;
1240 break;
1241 case SA_LINKRECORD_ATTRID:
1242 struct_size = sizeof (sa_link_record_t);
1243 buf_size = IBMF_SAA_LINK_RECORD_SIZE;
1244 unpack_data_fn = ibmf_saa_link_record_parse_buffer;
1245 break;
1246 case SA_GUIDINFORECORD_ATTRID:
1247 struct_size = sizeof (sa_guidinfo_record_t);
1248 buf_size = IBMF_SAA_GUIDINFO_RECORD_SIZE;
1249 unpack_data_fn = ibmf_saa_guidinfo_record_parse_buffer;
1250 break;
1251 case SA_SERVICERECORD_ATTRID:
1252 struct_size = sizeof (sa_service_record_t);
1253 buf_size = IBMF_SAA_SERVICE_RECORD_SIZE;
1254 unpack_data_fn = ibmf_saa_service_record_parse_buffer;
1255 break;
1256 case SA_PARTITIONRECORD_ATTRID:
1257 struct_size = sizeof (sa_pkey_table_record_t);
1258 buf_size = IBMF_SAA_PARTITION_RECORD_SIZE;
1259 unpack_data_fn =
1260 ibmf_saa_partition_record_parse_buffer;
1261 break;
1262 case SA_PATHRECORD_ATTRID:
1263 struct_size = sizeof (sa_path_record_t);
1264 buf_size = IBMF_SAA_PATH_RECORD_SIZE;
1265 unpack_data_fn = ibmf_saa_path_record_parse_buffer;
1266 break;
1267 case SA_VLARBRECORD_ATTRID:
1268 struct_size = sizeof (sa_VLarb_table_record_t);
1269 buf_size = IBMF_SAA_VLARB_RECORD_SIZE;
1270 unpack_data_fn = ibmf_saa_vlarb_record_parse_buffer;
1271 break;
1272 case SA_MCMEMBERRECORD_ATTRID:
1273 struct_size = sizeof (sa_mcmember_record_t);
1274 buf_size = IBMF_SAA_MCMEMBER_RECORD_SIZE;
1275 unpack_data_fn = ibmf_saa_mcmember_record_parse_buffer;
1276 break;
1277 case SA_TRACERECORD_ATTRID:
1278 struct_size = sizeof (sa_trace_record_t);
1279 buf_size = IBMF_SAA_TRACE_RECORD_SIZE;
1280 unpack_data_fn = ibmf_saa_trace_record_parse_buffer;
1281 break;
1282 case SA_MULTIPATHRECORD_ATTRID:
1283 /*
1284 * array is of size 1 since multipath can be request
1285 * only; data size greater than multipath_record_t
1286 * size is due to gids at the end
1287 */
1288 buf_size = buf_payload_length;
1289 struct_size = sizeof (sa_multipath_record_t) +
1290 buf_size - IBMF_SAA_MULTIPATH_RECORD_SIZE;
1291 unpack_data_fn = ibmf_saa_multipath_record_parse_buffer;
1292 break;
1293 case SA_SERVICEASSNRECORD_ATTRID:
1294 struct_size = sizeof (sa_service_assn_record_t);
1295 buf_size = IBMF_SAA_SERVICEASSN_RECORD_SIZE;
1296 unpack_data_fn =
1297 ibmf_saa_service_assn_record_parse_buffer;
1298 break;
1299 default:
1300 /* don't know about structure; do bcopy */
1301
1302 *structs_payload_lengthp = buf_payload_length;
1303 *structs_payloadp = kmem_zalloc(
1304 *structs_payload_lengthp, km_sleep_flag);
1305 if (*structs_payloadp == NULL) {
1306
1307 *structs_payload_lengthp = 0;
1308 return (IBMF_NO_MEMORY);
1309 }
1310
1311 bcopy(buf_payload, *structs_payloadp,
1312 *structs_payload_lengthp);
1313
1314 return (IBMF_SUCCESS);
1315 }
1316
1317 /* compute distance between successive records */
1318 if (attr_offset > 0) {
1319
1320 if ((attr_offset * 8) < buf_size) {
1321
1322 IBMF_TRACE_3(IBMF_TNF_DEBUG, DPRINT_L1,
1323 ibmf_saa_utils_unpack_payload, IBMF_TNF_ERROR, "",
1324 "ibmf_saa_utils_unpack_payload: %s, attr_offset = "
1325 "%d, attr_size = %d\n",
1326 tnf_string, msg, "attribute offset times 8 is less"
1327 " than attribute size",
1328 tnf_int, attr_offset, attr_offset,
1329 tnf_int, attr_size, buf_size);
1330
1331 return (IBMF_TRANS_FAILURE);
1332 }
1333
1334 bytes_between_recs = attr_offset * 8;
1335 } else {
1336 bytes_between_recs = buf_size;
1337 }
1338
1339 if (is_get_resp == B_TRUE) {
1340
1341 buf_payload_length = buf_size;
1342 num_records = 1;
1343 } else {
1344
1345 num_records = buf_payload_length / bytes_between_recs;
1346 }
1347
1348 *structs_payload_lengthp = num_records * struct_size;
1349
1350 *structs_payloadp = kmem_zalloc(*structs_payload_lengthp,
1351 km_sleep_flag);
1352 if (*structs_payloadp == NULL) {
1353
1354 IBMF_TRACE_2(IBMF_TNF_DEBUG, DPRINT_L1,
1355 ibmf_saa_utils_unpack_payload_err,
1356 IBMF_TNF_ERROR, "", "ibmf_saa_utils_unpack_payload: %s,"
1357 " size = %d\n",
1358 tnf_string, msg, "could not allocate memory for payload",
1359 tnf_int, size, *structs_payload_lengthp);
1360
1361 *structs_payload_lengthp = 0;
1362 return (IBMF_NO_MEMORY);
1363 }
1364
1365
1366 for (i = 0; i < num_records; i++) {
1367
1368 unpack_data_fn(
1369 (uchar_t *)buf_payload + (i * bytes_between_recs),
1370 (void *)((uchar_t *)*structs_payloadp + i *
1371 struct_size));
1372 }
1373
1374 return (IBMF_SUCCESS);
1375 }
1376