2 * Copyright (c) 2007-2008 Intel Corporation. All rights reserved.
\r
3 * Copyright (c) 2002, Network Appliance, Inc. All rights reserved.
\r
5 * This Software is licensed under one of the following licenses:
\r
7 * 1) under the terms of the "Common Public License 1.0" a copy of which is
\r
8 * in the file LICENSE.txt in the root directory. The license is also
\r
9 * available from the Open Source Initiative, see
\r
10 * http://www.opensource.org/licenses/cpl.php.
\r
12 * 2) under the terms of the "The BSD License" a copy of which is in the file
\r
13 * LICENSE2.txt in the root directory. The license is also available from
\r
14 * the Open Source Initiative, see
\r
15 * http://www.opensource.org/licenses/bsd-license.php.
\r
17 * 3) under the terms of the "GNU General Public License (GPL) Version 2" a
\r
18 * copy of which is in the file LICENSE3.txt in the root directory. The
\r
19 * license is also available from the Open Source Initiative, see
\r
20 * http://www.opensource.org/licenses/gpl-license.php.
\r
22 * Licensee has the right to choose one of the above licenses.
\r
24 * Redistributions of source code must retain the above copyright
\r
25 * notice and one of the license notices.
\r
27 * Redistributions in binary form must reproduce both the above copyright
\r
28 * notice, one of the license notices in the documentation
\r
29 * and/or other materials provided with the distribution.
\r
32 /**********************************************************************
\r
34 * MODULE: dapl_ibal_name_service.c
\r
36 * PURPOSE: IP Name service
\r
40 **********************************************************************/
\r
43 #include "dapl_adapter_util.h"
\r
44 #include "dapl_evd_util.h"
\r
45 #include "dapl_cr_util.h"
\r
46 #include "dapl_sp_util.h"
\r
47 #include "dapl_ep_util.h"
\r
48 #include "dapl_ia_util.h"
\r
49 #include "dapl_ibal_util.h"
\r
50 #include "dapl_name_service.h"
\r
52 #define IB_INFINITE_SERVICE_LEASE 0xFFFFFFFF
\r
53 #define DAPL_ATS_SERVICE_ID ATS_SERVICE_ID //0x10000CE100415453
\r
54 #define DAPL_ATS_NAME ATS_NAME
\r
55 #define HCA_IPV6_ADDRESS_LENGTH 16
\r
57 extern dapl_ibal_root_t dapl_ibal_root;
\r
61 dapli_get_ip_addr_str(DAT_SOCK_ADDR6 *ipa, char *buf)
\r
64 static char lbuf[24];
\r
65 char *str = (buf ? buf : lbuf);
\r
67 rval = ((struct sockaddr_in *)ipa)->sin_addr.s_addr;
\r
69 sprintf(str, "%d.%d.%d.%d",
\r
72 (rval >> 16) & 0xff,
\r
73 (rval >> 24) & 0xff);
\r
80 dapli_ib_sa_query_cb (IN ib_query_rec_t *p_query_rec )
\r
82 ib_api_status_t ib_status;
\r
84 if (IB_SUCCESS != p_query_rec->status)
\r
86 dapl_dbg_log ( DAPL_DBG_TYPE_ERR,"%s: SA query callback failed %s\n",
\r
87 __FUNCTION__, ib_get_err_str(p_query_rec->status));
\r
91 if (!p_query_rec->p_result_mad)
\r
93 dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
\r
94 "%s: SA query callback [no mad] @line %d\n",
\r
95 __FUNCTION__, __LINE__);
\r
99 switch (p_query_rec->query_type)
\r
101 case IB_QUERY_PATH_REC_BY_GIDS:
\r
103 ib_path_rec_t *p_path_rec;
\r
105 p_path_rec = ib_get_query_path_rec (p_query_rec->p_result_mad, 0);
\r
108 dapl_os_memcpy ((void * __ptr64) p_query_rec->query_context,
\r
109 (void *) p_path_rec,
\r
110 sizeof (ib_path_rec_t));
\r
112 DAPL_DBG_TYPE_CM | DAPL_DBG_TYPE_CALLBACK,
\r
113 "sa_query_cb: path {slid: 0x%x, dlid: 0x%x}\n",
\r
114 p_path_rec->slid, p_path_rec->dlid);
\r
118 dapl_dbg_log ( DAPL_DBG_TYPE_ERR,"%s: return NULL? @line %d\n",
\r
119 __FUNCTION__, __LINE__);
\r
125 case IB_QUERY_SVC_REC_BY_ID:
\r
127 ib_service_record_t *p_svc_rec;
\r
129 p_svc_rec = ib_get_query_svc_rec (p_query_rec->p_result_mad, 0);
\r
132 dapl_os_memcpy ((void * __ptr64) p_query_rec->query_context,
\r
133 (void *) p_svc_rec,
\r
134 sizeof (ib_service_record_t));
\r
136 DAPL_DBG_TYPE_CM | DAPL_DBG_TYPE_CALLBACK,
\r
137 "%s: SER{0x%I64x, 0x%I64x}\n", __FUNCTION__,
\r
138 cl_hton64 (p_svc_rec->service_gid.unicast.prefix),
\r
139 cl_hton64 (p_svc_rec->service_gid.unicast.interface_id));
\r
143 dapl_dbg_log ( DAPL_DBG_TYPE_ERR,"%s: return NULL? @line %d\n",
\r
144 __FUNCTION__, __LINE__);
\r
151 case IB_QUERY_USER_DEFINED:
\r
153 ib_user_query_t *p_user_query;
\r
155 p_user_query=(ib_user_query_t * __ptr64) p_query_rec->query_context;
\r
159 switch (p_user_query->attr_id)
\r
161 case IB_MAD_ATTR_SERVICE_RECORD:
\r
163 ib_service_record_t *p_svc_rec;
\r
165 p_svc_rec = ib_get_query_svc_rec (
\r
166 p_query_rec->p_result_mad, 0);
\r
169 dapl_os_memcpy ((void *) p_user_query->p_attr,
\r
170 (void *) p_svc_rec,
\r
171 sizeof (ib_service_record_t));
\r
173 DAPL_DBG_TYPE_CM | DAPL_DBG_TYPE_CALLBACK,
\r
174 "%s: GID{0x" F64x ", 0x" F64x "} record count %d\n",
\r
176 cl_hton64(p_svc_rec->service_gid.unicast.prefix),
\r
177 cl_hton64(p_svc_rec->service_gid.unicast.interface_id),
\r
178 p_query_rec->result_cnt);
\r
182 dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
\r
183 "%s: return NULL? @line %d\n",
\r
184 __FUNCTION__, __LINE__);
\r
192 dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
\r
193 "%s: USER_DEFINED %d\n",
\r
194 p_user_query->attr_id );
\r
201 dapl_dbg_log ( DAPL_DBG_TYPE_ERR,"%s: return NULL? @line %d\n",
\r
202 __FUNCTION__, __LINE__);
\r
210 dapl_dbg_log ( DAPL_DBG_TYPE_ERR,"%s: unsupportedTYPE %d\n",
\r
211 __FUNCTION__, p_query_rec->query_type);
\r
217 if ((ib_status = ib_put_mad (p_query_rec->p_result_mad)) != IB_SUCCESS)
\r
219 dapl_dbg_log ( DAPL_DBG_TYPE_ERR,"%s: can not free MAD %s\n",
\r
220 __FUNCTION__, ib_get_err_str(ib_status));
\r
225 #ifndef NO_NAME_SERVICE
\r
228 dapls_ib_ns_map_gid (
\r
229 IN DAPL_HCA *hca_ptr,
\r
230 IN DAT_IA_ADDRESS_PTR p_ia_address,
\r
233 ib_user_query_t user_query;
\r
234 dapl_ibal_ca_t *p_ca;
\r
235 dapl_ibal_port_t *p_active_port;
\r
236 ib_service_record_t service_rec;
\r
237 ib_api_status_t ib_status;
\r
238 ib_query_req_t query_req;
\r
239 DAT_SOCK_ADDR6 ipv6_addr;
\r
241 p_ca = (dapl_ibal_ca_t *) hca_ptr->ib_hca_handle;
\r
245 dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
\r
246 "--> DsNMG: There is no HCA = %d\n", __LINE__);
\r
247 return (DAT_INVALID_HANDLE);
\r
251 * We are using the first active port in the list for
\r
252 * communication. We have to get back here when we decide to support
\r
253 * fail-over and high-availability.
\r
255 p_active_port = dapli_ibal_get_port ( p_ca, (uint8_t)hca_ptr->port_num );
\r
257 if (NULL == p_active_port)
\r
259 dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
\r
260 "--> DsNMG: Port %d is not available = %d\n",
\r
261 hca_ptr->port_num, __LINE__);
\r
262 return (DAT_INVALID_STATE);
\r
265 if (p_active_port->p_attr->lid == 0)
\r
267 dapl_dbg_log ( DAPL_DBG_TYPE_ERR, "--> DsNMG: Port %d has no LID "
\r
268 "assigned; can not operate\n",
\r
269 p_active_port->p_attr->port_num);
\r
270 return (DAT_INVALID_STATE);
\r
273 if (!dapl_os_memcmp (p_ia_address,
\r
274 &hca_ptr->hca_address,
\r
275 HCA_IPV6_ADDRESS_LENGTH))
\r
277 /* We are operating in the LOOPBACK mode */
\r
278 p_gid->guid =p_active_port->p_attr->p_gid_table[0].unicast.interface_id;
\r
279 p_gid->gid_prefix =p_active_port->p_attr->p_gid_table[0].unicast.prefix;
\r
280 return DAT_SUCCESS;
\r
283 if (p_active_port->p_attr->link_state != IB_LINK_ACTIVE)
\r
286 * Port is DOWN; can not send or recv messages
\r
288 dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
\r
289 "--> DsNMG: Port %d is DOWN; can not send to fabric\n",
\r
290 p_active_port->p_attr->port_num);
\r
291 return (DAT_INVALID_STATE);
\r
294 dapl_os_memzero (&user_query, sizeof (ib_user_query_t));
\r
295 dapl_os_memzero (&service_rec, sizeof (ib_service_record_t));
\r
296 dapl_os_memzero (&query_req, sizeof (ib_query_req_t));
\r
297 dapl_os_memzero (&ipv6_addr, sizeof (DAT_SOCK_ADDR6));
\r
299 if (p_ia_address->sa_family == AF_INET)
\r
301 dapl_os_memcpy (&ipv6_addr.sin6_addr.s6_addr[12],
\r
302 &((struct sockaddr_in *)p_ia_address)->sin_addr.s_addr,
\r
304 #if defined(DAPL_DBG) || 1 // XXX
\r
308 dapl_dbg_log (DAPL_DBG_TYPE_CM, "--> DsNMG: Remote ia_address %s\n",
\r
309 dapli_get_ip_addr_str(
\r
310 (DAT_SOCK_ADDR6*)p_ia_address, ipa));
\r
318 * Assume IPv6 address
\r
320 dapl_os_assert (p_ia_address->sa_family == AF_INET6);
\r
321 dapl_os_memcpy (ipv6_addr.sin6_addr.s6_addr,
\r
322 ((DAT_SOCK_ADDR6 *)p_ia_address)->sin6_addr.s6_addr,
\r
323 HCA_IPV6_ADDRESS_LENGTH);
\r
324 #if defined(DAPL_DBG) || 1 // XXX
\r
327 uint8_t *tmp = ipv6_addr.sin6_addr.s6_addr;
\r
329 dapl_dbg_log ( DAPL_DBG_TYPE_CM,
\r
330 "--> DsNMG: Remote ia_address - ");
\r
332 for ( i = 1; i < HCA_IPV6_ADDRESS_LENGTH; i++)
\r
334 dapl_dbg_log ( DAPL_DBG_TYPE_CM, "%x:",
\r
337 dapl_dbg_log ( DAPL_DBG_TYPE_CM, "%x\n",
\r
347 //service_rec.service_id = CL_HTON64 (DAPL_ATS_SERVICE_ID);
\r
348 dapl_os_memcpy ( service_rec.service_name,
\r
350 __min(sizeof(ATS_NAME),sizeof(ib_svc_name_t)) );
\r
351 dapl_os_memcpy (&service_rec.service_data8[0],
\r
352 ipv6_addr.sin6_addr.s6_addr,
\r
353 HCA_IPV6_ADDRESS_LENGTH);
\r
354 service_rec.service_lease = IB_INFINITE_SERVICE_LEASE;
\r
355 service_rec.service_pkey = IB_DEFAULT_PKEY;
\r
357 user_query.method = IB_MAD_METHOD_GETTABLE;
\r
358 user_query.attr_id = IB_MAD_ATTR_SERVICE_RECORD;
\r
359 user_query.comp_mask = IB_SR_COMPMASK_SPKEY |
\r
360 IB_SR_COMPMASK_SLEASE |
\r
361 IB_SR_COMPMASK_SNAME |
\r
362 IB_SR_COMPMASK_SDATA8_0 |
\r
363 IB_SR_COMPMASK_SDATA8_1 |
\r
364 IB_SR_COMPMASK_SDATA8_2 |
\r
365 IB_SR_COMPMASK_SDATA8_3 |
\r
366 IB_SR_COMPMASK_SDATA8_4 |
\r
367 IB_SR_COMPMASK_SDATA8_5 |
\r
368 IB_SR_COMPMASK_SDATA8_6 |
\r
369 IB_SR_COMPMASK_SDATA8_7 |
\r
370 IB_SR_COMPMASK_SDATA8_8 |
\r
371 IB_SR_COMPMASK_SDATA8_9 |
\r
372 IB_SR_COMPMASK_SDATA8_10 |
\r
373 IB_SR_COMPMASK_SDATA8_11 |
\r
374 IB_SR_COMPMASK_SDATA8_12 |
\r
375 IB_SR_COMPMASK_SDATA8_13 |
\r
376 IB_SR_COMPMASK_SDATA8_14 |
\r
377 IB_SR_COMPMASK_SDATA8_15;
\r
379 user_query.attr_size = sizeof (ib_service_record_t);
\r
380 user_query.p_attr = (void *)&service_rec;
\r
382 query_req.query_type = IB_QUERY_USER_DEFINED;
\r
383 query_req.p_query_input = (void *)&user_query;
\r
384 query_req.flags = IB_FLAGS_SYNC; /* this is a blocking call */
\r
385 query_req.timeout_ms = 1 * 1000; /* 1 second */
\r
386 query_req.retry_cnt = 5;
\r
387 /* query SA using this port */
\r
388 query_req.port_guid = p_active_port->p_attr->port_guid;
\r
389 query_req.query_context = (void *) &user_query;
\r
390 query_req.pfn_query_cb = dapli_ib_sa_query_cb;
\r
392 ib_status = ib_query (dapl_ibal_root.h_al, &query_req, NULL);
\r
394 if (ib_status != IB_SUCCESS)
\r
396 dapl_dbg_log ( DAPL_DBG_TYPE_ERR,"ns_map_gid: status %s @line = %d\n",
\r
397 ib_get_err_str(ib_status), __LINE__);
\r
398 return (dapl_ib_status_convert (ib_status));
\r
400 else if (service_rec.service_gid.unicast.interface_id == 0)
\r
402 dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
\r
403 "--> %s: query SA found no record\n",__FUNCTION__);
\r
404 return DAT_INVALID_PARAMETER;
\r
410 p_gid->guid = service_rec.service_gid.unicast.interface_id;
\r
411 p_gid->gid_prefix = service_rec.service_gid.unicast.prefix;
\r
413 return DAT_SUCCESS;
\r
419 dapls_ib_ns_map_ipaddr (
\r
420 IN DAPL_HCA *hca_ptr,
\r
422 OUT DAT_IA_ADDRESS_PTR p_ia_address)
\r
424 ib_user_query_t user_query;
\r
425 dapl_ibal_ca_t *p_ca;
\r
426 dapl_ibal_port_t *p_active_port;
\r
427 ib_service_record_t service_rec;
\r
428 ib_api_status_t ib_status;
\r
429 ib_query_req_t query_req;
\r
431 p_ca = (dapl_ibal_ca_t *) hca_ptr->ib_hca_handle;
\r
435 dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
\r
436 "--> DsNMI: There is no HCA = %d\n", __LINE__);
\r
437 return (DAT_INVALID_HANDLE);
\r
441 * We are using the first active port in the list for
\r
442 * communication. We have to get back here when we decide to support
\r
443 * fail-over and high-availability.
\r
445 p_active_port = dapli_ibal_get_port ( p_ca, (uint8_t)hca_ptr->port_num );
\r
447 if (NULL == p_active_port)
\r
449 dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
\r
450 "--> DsNMI: Port %d is not available = %d\n",
\r
451 hca_ptr->port_num, __LINE__);
\r
452 return (DAT_INVALID_STATE);
\r
455 if (p_active_port->p_attr->lid == 0)
\r
457 dapl_dbg_log ( DAPL_DBG_TYPE_ERR, "--> DsNMI: Port %d has no LID "
\r
458 "assigned; can not operate\n",
\r
459 p_active_port->p_attr->port_num);
\r
460 return (DAT_INVALID_STATE);
\r
465 // We are operating in the LOOPBACK mode
\r
467 if ((gid.gid_prefix ==
\r
468 p_active_port->p_attr->p_gid_table[0].unicast.prefix) &&
\r
470 p_active_port->p_attr->p_gid_table[0].unicast.interface_id))
\r
472 dapl_os_memcpy (((DAT_SOCK_ADDR6 *)p_ia_address)->sin6_addr.s6_addr,
\r
473 hca_ptr->hca_address.sin6_addr.s6_addr,
\r
474 HCA_IPV6_ADDRESS_LENGTH);
\r
475 return DAT_SUCCESS;
\r
480 if (p_active_port->p_attr->link_state != IB_LINK_ACTIVE)
\r
483 * Port is DOWN; can not send or recv messages
\r
485 dapl_dbg_log ( DAPL_DBG_TYPE_ERR,"--> DsNMI: Port %d is DOWN; "
\r
486 "can not send/recv to/from fabric\n",
\r
487 p_active_port->p_attr->port_num);
\r
488 return (DAT_INVALID_STATE);
\r
491 dapl_os_memzero (&user_query, sizeof (ib_user_query_t));
\r
492 dapl_os_memzero (&service_rec, sizeof (ib_service_record_t));
\r
493 dapl_os_memzero (&query_req, sizeof (ib_query_req_t));
\r
496 * query SA for IPAddress
\r
498 //service_rec.service_id = CL_HTON64 (DAPL_ATS_SERVICE_ID);
\r
499 dapl_os_memcpy( service_rec.service_name,
\r
501 __min (sizeof(ATS_NAME), sizeof(ib_svc_name_t)));
\r
502 service_rec.service_gid.unicast.interface_id = gid.guid;
\r
503 service_rec.service_gid.unicast.prefix = gid.gid_prefix;
\r
504 service_rec.service_pkey = IB_DEFAULT_PKEY;
\r
505 service_rec.service_lease = IB_INFINITE_SERVICE_LEASE;
\r
507 user_query.method = IB_MAD_METHOD_GETTABLE;
\r
508 user_query.attr_id = IB_MAD_ATTR_SERVICE_RECORD;
\r
510 user_query.comp_mask = IB_SR_COMPMASK_SGID |
\r
511 IB_SR_COMPMASK_SPKEY |
\r
512 IB_SR_COMPMASK_SLEASE |
\r
513 IB_SR_COMPMASK_SNAME;
\r
515 user_query.attr_size = sizeof (ib_service_record_t);
\r
516 user_query.p_attr = (void *)&service_rec;
\r
518 query_req.query_type = IB_QUERY_USER_DEFINED;
\r
519 query_req.p_query_input = (void *)&user_query;
\r
520 query_req.flags = IB_FLAGS_SYNC; /* this is a blocking call */
\r
521 query_req.timeout_ms = 1 * 1000; /* 1 second */
\r
522 query_req.retry_cnt = 5;
\r
523 /* query SA using this port */
\r
524 query_req.port_guid = p_active_port->p_attr->port_guid;
\r
525 query_req.query_context = (void *) &user_query;
\r
526 query_req.pfn_query_cb = dapli_ib_sa_query_cb;
\r
528 ib_status = ib_query (dapl_ibal_root.h_al, &query_req, NULL);
\r
530 if (ib_status != IB_SUCCESS)
\r
532 dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
\r
533 "ns_map_ipaddr: exits status %s @line = %d\n",
\r
534 ib_get_err_str(ib_status), __LINE__);
\r
535 return (dapl_ib_status_convert (ib_status));
\r
538 /* ***********************
\r
539 * return the IP_address
\r
540 *************************/
\r
542 (void *) &((struct sockaddr_in *)p_ia_address)->sin_addr.s_net,
\r
543 (const void *)&service_rec.service_data8[ATS_IPV4_OFFSET], 4);
\r
544 //HCA_IPV6_ADDRESS_LENGTH);
\r
545 ((DAT_SOCK_ADDR6 *)p_ia_address)->sin6_family = AF_INET;
\r
547 return (DAT_SUCCESS);
\r
552 * dapls_ib_ns_create_gid_map()
\r
554 * Register a ServiceRecord containing uDAPL_svc_id, IP address and GID to SA
\r
555 * Other nodes can look it up by quering the SA
\r
558 * hca_ptr HCA device pointer
\r
565 * DAT_INVALID_PARAMETER
\r
568 dapls_ib_ns_create_gid_map (
\r
569 IN DAPL_HCA *hca_ptr)
\r
571 UNUSED_PARAM( hca_ptr );
\r
572 return (DAT_SUCCESS);
\r
577 dapls_ib_ns_remove_gid_map (
\r
578 IN DAPL_HCA *hca_ptr)
\r
580 UNUSED_PARAM( hca_ptr );
\r
581 return (DAT_SUCCESS);
\r
584 #endif /* NO_NAME_SERVICE */
\r