]> git.openfabrics.org - ~shefty/ibacm.git/commitdiff
ibacm: rework socket interface messages
authorSean Hefty <sean.hefty@intel.com>
Thu, 29 Oct 2009 21:02:22 +0000 (13:02 -0800)
committerSean Hefty <sean.hefty@intel.com>
Thu, 29 Oct 2009 21:02:22 +0000 (13:02 -0800)
Rather than indicating the src/dst address type in the acm message
header, indicate the type in the acm_ep_addr structure directly.
This adds more flexibility and will permit additional acm_ep_addr
structures to be carried in a single message request or response.

Allow multiple addresses in a request or response message.  This
is needed to support a wider range of fabric topologies, where the
inbound and outbound paths may differ, plus support failover.

Add path records to the resolve message, rather than as a separate
operation.  Return path records directly from the lookup.

Signed-off-by: Sean Hefty <sean.hefty@intel.com>
15 files changed:
Makefile.am
include/infiniband/acm.h
include/infiniband/ib_acm.h
linux/libibacm.map
man/ib_acm.7
man/ib_acm_convert_to_path.3 [deleted file]
man/ib_acm_query_path.3 [deleted file]
man/ib_acm_resolve_ip.3
man/ib_acm_resolve_name.3
man/ib_acm_resolve_path.3
src/acm.c
src/acm_mad.h
src/acme.c
src/libacm.c
windows/library/libacm_exports.src

index eacece806d436481b8b5210bfd92840dd5c91ac2..7ae23c089e42b8debe67b94415075f0bf27b3308 100644 (file)
@@ -32,8 +32,6 @@ man_MANS = \
        man/ib_acm_resolve_name.3 \
        man/ib_acm_resolve_ip.3 \
        man/ib_acm_resolve_path.3 \
-       man/ib_acm_query_path.3 \
-       man/ib_acm_convert_to_path.3 \
        man/ib_acme.1 \
        man/ib_acm.1 \
        man/ib_acm.7
index 56e6553eb8777c499d7aff8263e2effc5dcda6ad..debcdfc9ccc7741e354bb1344fe6b0603fafb9ca 100644 (file)
 \r
 #include <infiniband/ib_acm.h>\r
 \r
-#define ACM_VERSION 1\r
-\r
-#define ACM_OP_MASK     0x0F\r
-#define ACM_OP_RESOLVE  0x01\r
-#define ACM_OP_QUERY    0x02\r
-//#define ACM_OP_CM       0x03\r
-//#define ACM_OP_ACK_REQ  0x40 /* optional ack is required */\r
-#define ACM_OP_ACK      0x80\r
-\r
-#define ACM_STATUS_SUCCESS         0\r
-#define ACM_STATUS_ENOMEM          1\r
-#define ACM_STATUS_EINVAL          2\r
-#define ACM_STATUS_ENODATA         3\r
-#define ACM_STATUS_ENOTCONN        5\r
-#define ACM_STATUS_ETIMEDOUT       6\r
-#define ACM_STATUS_ESRCADDR        7\r
-#define ACM_STATUS_ESRCTYPE        8\r
-#define ACM_STATUS_EDESTADDR       9\r
-#define ACM_STATUS_EDESTTYPE      10\r
+#define ACM_VERSION             1\r
+\r
+#define ACM_OP_MASK             0x0F\r
+#define ACM_OP_RESOLVE          0x01\r
+#define ACM_OP_ACK              0x80\r
+\r
+#define ACM_STATUS_SUCCESS      0\r
+#define ACM_STATUS_ENOMEM       1\r
+#define ACM_STATUS_EINVAL       2\r
+#define ACM_STATUS_ENODATA      3\r
+#define ACM_STATUS_ENOTCONN     5\r
+#define ACM_STATUS_ETIMEDOUT    6\r
+#define ACM_STATUS_ESRCADDR     7\r
+#define ACM_STATUS_ESRCTYPE     8\r
+#define ACM_STATUS_EDESTADDR    9\r
+#define ACM_STATUS_EDESTTYPE    10\r
+\r
+#define ACM_FLAGS_QUERY_SA      (1<<31)\r
+\r
+#define ACM_MSG_HDR_LENGTH      16\r
+#define ACM_MAX_ADDRESS         64\r
+#define ACM_MSG_EP_LENGTH       72\r
+/*\r
+ * Support up to 6 path records (primary and alternate CM paths,\r
+ * inbound and outbound primary and alternate data paths), plus CM data.\r
+ */\r
+#define ACM_MSG_DATA_LENGTH     (ACM_MSG_EP_LENGTH * 8)\r
 \r
 struct acm_hdr\r
 {\r
-       uint8_t  version;\r
-       uint8_t  opcode;\r
-       uint8_t  status;\r
-       uint8_t  param;\r
-       uint8_t  dest_type;\r
-       uint8_t  src_type;\r
-       uint8_t  reserved[2];\r
-       uint64_t tid;\r
+       uint8_t                 version;\r
+       uint8_t                 opcode;\r
+       uint8_t                 status;\r
+       uint8_t                 reserved[3];\r
+       uint16_t                length;\r
+       uint64_t                tid;\r
 };\r
 \r
-#define ACM_EP_TYPE_NAME        0x01\r
-#define ACM_EP_TYPE_ADDRESS_IP  0x02\r
-#define ACM_EP_TYPE_ADDRESS_IP6 0x03\r
-#define ACM_EP_TYPE_DEVICE      0x10\r
-#define ACM_EP_TYPE_AV          0x20\r
-\r
-#define ACM_MAX_ADDRESS  32\r
+#define ACM_EP_INFO_NAME        0x0001\r
+#define ACM_EP_INFO_ADDRESS_IP  0x0002\r
+#define ACM_EP_INFO_ADDRESS_IP6 0x0003\r
+#define ACM_EP_INFO_PATH        0x0010\r
+#define ACM_EP_INFO_CM          0x0100\r
 \r
-union acm_ep_addr\r
+struct acm_cm_data\r
 {\r
-       uint8_t                addr[ACM_MAX_ADDRESS];\r
-       uint8_t                name[ACM_MAX_ADDRESS];\r
-       struct ib_acm_dev_addr dev;\r
-       struct ibv_ah_attr     av;\r
+       uint8_t                 init_depth;\r
+       uint8_t                 resp_resources;\r
+       uint8_t                 reserved2[62];\r
 };\r
 \r
-struct acm_resolve_msg\r
+union acm_ep_info\r
 {\r
-       struct acm_hdr             hdr;\r
-       union  acm_ep_addr         src;\r
-       union  acm_ep_addr         dest;\r
-       struct ib_acm_resolve_data data;\r
+       uint8_t                 addr[ACM_MAX_ADDRESS];\r
+       uint8_t                 name[ACM_MAX_ADDRESS];\r
+       struct acm_cm_data      cm;\r
+       struct ib_path_record   path;\r
 };\r
 \r
-//struct acm_cm_param\r
-//{\r
-//     uint32_t qpn;\r
-//     uint8_t  init_depth;\r
-//     uint8_t  resp_resources;\r
-//     uint8_t  retry_cnt;\r
-//     uint8_t  rnr_retry_cnt;\r
-//     uint16_t src_port;\r
-//     uint16_t dest_port;\r
-//     uint8_t  reserved[4];\r
-//};\r
-\r
-//struct acm_cm_msg\r
-//{\r
-//     struct acm_hdr      hdr;\r
-//     union  acm_ep_addr  src;\r
-//     union  acm_ep_addr  dest;\r
-//     struct acm_cm_param param;\r
-//};\r
-\r
-#define ACM_QUERY_PATH_RECORD  0x01\r
-#define ACM_QUERY_SA           0x80\r
-\r
-#define ACM_EP_TYPE_LID        0x01\r
-#define ACM_EP_TYPE_GID        0x02\r
-\r
-union acm_query_data\r
+struct acm_ep_addr_data\r
 {\r
-       struct ib_path_record  path;\r
+       uint32_t                flags;\r
+       uint16_t                type;\r
+       uint16_t                reserved;\r
+       union acm_ep_info       info;\r
 };\r
 \r
-struct acm_query_msg\r
+struct acm_resolve_msg\r
 {\r
-       struct acm_hdr         hdr;\r
-       union acm_query_data   data;\r
-       uint8_t                reserved[16];\r
+       struct acm_hdr          hdr;\r
+       struct acm_ep_addr_data data[0];\r
 };\r
 \r
-#define ACM_MSG_DATA_SIZE  80\r
-\r
 struct acm_msg\r
 {\r
-       struct acm_hdr     hdr;\r
-       uint8_t            data[ACM_MSG_DATA_SIZE];\r
+       struct acm_hdr          hdr;\r
+       uint8_t                 data[ACM_MSG_DATA_LENGTH];\r
 };\r
 \r
 #endif /* ACM_H */\r
index 6618e845bb0507b83ab3e6338943b14d559d1b77..09b86c21d2a0fe335b69da9187195dbad30f008e 100644 (file)
 extern "C" {\r
 #endif\r
 \r
-struct ib_acm_dev_addr\r
+#define IB_PATH_RECORD_REVERSIBLE 0x80\r
+\r
+struct ib_path_record\r
+{\r
+       uint64_t        service_id;\r
+       union ibv_gid   dgid;\r
+       union ibv_gid   sgid;\r
+       uint16_t        dlid;\r
+       uint16_t        slid;\r
+       uint32_t        flowlabel_hoplimit; /* resv-31:28 flow label-27:8 hop limit-7:0*/\r
+       uint8_t         tclass;\r
+       uint8_t         reversible_numpath; /* reversible-7:7 num path-6:0 */\r
+       uint16_t        pkey;\r
+       uint16_t        qosclass_sl;        /* qos class-15:4 sl-3:0 */\r
+       uint8_t         mtu;                /* mtu selector-7:6 mtu-5:0 */\r
+       uint8_t         rate;               /* rate selector-7:6 rate-5:0 */\r
+       uint8_t         packetlifetime;     /* lifetime selector-7:6 lifetime-5:0 */\r
+       uint8_t         preference;\r
+       uint8_t         reserved[6];\r
+};\r
+\r
+#define IB_ACM_FLAGS_CM              (1<<0)\r
+#define IB_ACM_FLAGS_PRIMARY         (1<<1)\r
+#define IB_ACM_FLAGS_ALTERNATE       (1<<2)\r
+#define IB_ACM_FLAGS_OUTBOUND        (1<<3)\r
+#define IB_ACM_FLAGS_INBOUND         (1<<4)\r
+#define IB_ACM_FLAGS_INBOUND_REVERSE (1<<5)\r
+#define IB_ACM_FLAGS_BIDIRECTIONAL   (IB_ACM_FLAGS_OUTBOUND | IB_ACM_FLAGS_INBOUND_REVERSE)\r
+\r
+struct ib_acm_path_data\r
 {\r
-       uint64_t guid;\r
-       uint16_t pkey_index;\r
-       uint8_t  port_num;\r
-       uint8_t  reserved[5];\r
+       uint32_t              flags;\r
+       uint32_t              reserved;\r
+       struct ib_path_record path;\r
 };\r
 \r
-struct ib_acm_resolve_data\r
+struct ib_acm_cm_data\r
 {\r
-       uint32_t reserved1;\r
        uint8_t  init_depth;\r
        uint8_t  resp_resources;\r
-       uint8_t  packet_lifetime;\r
-       uint8_t  mtu;\r
-       uint8_t  reserved2[8];\r
+       uint8_t  reserved2;\r
+       uint8_t  cm_data_length;\r
+       uint32_t cm_data[15];\r
 };\r
 \r
 /**\r
@@ -73,8 +100,8 @@ struct ib_acm_resolve_data
  */\r
 LIB_EXPORT\r
 int ib_acm_resolve_name(char *src, char *dest,\r
-       struct ib_acm_dev_addr *dev_addr, struct ibv_ah_attr *ah,\r
-       struct ib_acm_resolve_data *data);\r
+       struct ib_acm_path_data **paths, int *count,\r
+       struct ib_acm_cm_data *data);\r
 \r
 /**\r
  * ib_acm_resolve_ip - Resolve path data between the specified addresses.\r
@@ -89,30 +116,12 @@ int ib_acm_resolve_name(char *src, char *dest,
  */\r
 LIB_EXPORT\r
 int ib_acm_resolve_ip(struct sockaddr *src, struct sockaddr *dest,\r
-       struct ib_acm_dev_addr *dev_addr, struct ibv_ah_attr *ah,\r
-       struct ib_acm_resolve_data *data);\r
+       struct ib_acm_path_data **paths, int *count,\r
+       struct ib_acm_cm_data *data);\r
 \r
+#define ib_acm_free_paths(paths) free(paths)\r
 \r
-#define IB_PATH_RECORD_REVERSIBLE 0x80\r
-\r
-struct ib_path_record\r
-{\r
-       uint64_t        service_id;\r
-       union ibv_gid   dgid;\r
-       union ibv_gid   sgid;\r
-       uint16_t        dlid;\r
-       uint16_t        slid;\r
-       uint32_t        flowlabel_hoplimit; /* resv-31:28 flow label-27:8 hop limit-7:0*/\r
-       uint8_t         tclass;\r
-       uint8_t         reversible_numpath; /* reversible-7:7 num path-6:0 */\r
-       uint16_t        pkey;\r
-       uint16_t        qosclass_sl;        /* qos class-15:4 sl-3:0 */\r
-       uint8_t         mtu;                /* mtu selector-7:6 mtu-5:0 */\r
-       uint8_t         rate;               /* rate selector-7:6 rate-5:0 */\r
-       uint8_t         packetlifetime;     /* lifetime selector-7:6 lifetime-5:0 */\r
-       uint8_t         preference;\r
-       uint8_t         reserved[6];\r
-};\r
+#define IB_ACM_FLAGS_QUERY_SA   (1<<31)\r
 \r
 /**\r
  * ib_acm_resolve_path - Resolve path data meeting specified restrictions\r
@@ -125,32 +134,7 @@ struct ib_path_record
  *   caller must provide at least the source and destination LIDs as input.\r
  */\r
 LIB_EXPORT\r
-int ib_acm_resolve_path(struct ib_path_record *path);\r
-\r
-/**\r
- * ib_acm_query_path - Resolve path data meeting specified restrictions\r
- * Description:\r
- *   Queries the IB SA for a path record using the provided path record to\r
- *   restrict the query.\r
- * Notes:\r
- *   Uses the provided path record as input into an SA query for path\r
- *   information.  If successful, fills in any missing information.  The\r
- *   caller must provide at least the source and destination LIDs as input.\r
- *   Use of this call always results in sending a query to the IB SA.\r
- */\r
-LIB_EXPORT\r
-int ib_acm_query_path(struct ib_path_record *path);\r
-\r
-/**\r
- * ib_acm_convert_to_path - Convert resolved path data to a path record\r
- * Description:\r
- *   Converts path information returned from resolving a host name or address\r
- *   to the format of an IB path record.\r
- */\r
-LIB_EXPORT\r
-int ib_acm_convert_to_path(struct ib_acm_dev_addr *dev_addr,\r
-       struct ibv_ah_attr *ah, struct ib_acm_resolve_data *data,\r
-       struct ib_path_record *path);\r
+int ib_acm_resolve_path(struct ib_path_record *path, uint32_t flags);\r
 \r
 #ifdef __cplusplus\r
 }\r
index 4aae477999f6e39cf471b90365cce6a89a5ab7d7..1b0aab07dc865cdda4dedbd20fbe1189bc6a4907 100644 (file)
@@ -1,9 +1,7 @@
 IBACM_1.0 {
        global:
-               ib_acm_resolve_ip;
                ib_acm_resolve_name;
+               ib_acm_resolve_ip;
                ib_acm_resolve_path;
-               ib_acm_query_path;
-               ib_acm_convert_to_path;
        local: *;
 };
index 77df9c8fce7c134b7de3a77bf037a91c57798044..750c5795622f09b537b9128c51610729e59d783f 100644 (file)
@@ -30,5 +30,5 @@ success
 .IP "!= 0"\r
 error\r
 .SH "SEE ALSO"\r
-ib_acm_resolve_ip(3), ib_acm_resolve_name(3), ib_acm_resolve_path(3),\r
-ib_acm_query_path(3), ib_acm_convert_to_path(3), ib_acme(1), ib_acm(1)\r
+ib_acm_resolve_name(3), ib_acm_resolve_ip(3), ib_acm_resolve_path(3)\r
+ib_acme(1), ib_acm(1)\r
diff --git a/man/ib_acm_convert_to_path.3 b/man/ib_acm_convert_to_path.3
deleted file mode 100644 (file)
index da56324..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-.TH "IB_ACM_CONVERT_TO_PATH" 3 "2009-09-09" "libibacm" "Libibacm Programmer's Manual" libibacm
-.SH NAME
-ib_acm_convert_to_path \- Convert resolved path data to a path record.
-.SH SYNOPSIS
-.B "#include <infiniband/ib_acm.h>"
-.P
-.B "int" ib_acm_convert_to_path
-.BI "(struct ib_acm_dev_addr *" dev_addr ","\r
-.BI "struct ibv_ah_attr *" ah ","\r
-.BI    "struct ib_acm_resolve_data *" data ","\r
-.BI "struct ib_path_record *" path ");"\r
-.SH ARGUMENTS
-.IP "dev_addr" 12
-Local IB device address information.
-.IP "ah" 12
-Address handle attributes to send to the destination.
-.IP "data" 12
-Additional route and endpoint information.
-.SH "DESCRIPTION"
-Converts path information obtained from ib_acm_resolve_ip or ib_acm_resolve_name\r
-to the format of an IB path record.\r
-.SH "SEE ALSO"
-ib_acm_resolve_name(3), ib_acm_resolve_ip(3), ib_acm_resolve_path(3),
-ib_acm_query_path(3), ib_acm(7)
-
diff --git a/man/ib_acm_query_path.3 b/man/ib_acm_query_path.3
deleted file mode 100644 (file)
index 986ca41..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-.TH "IB_ACM_QUERY_PATH" 3 "2009-09-09" "libibacm" "Libibacm Programmer's Manual" libibacm
-.SH NAME
-ib_acm_query_path \- Resolve path data meeting specified restrictions.
-.SH SYNOPSIS
-.B "#include <infiniband/ib_acm.h>"
-.P
-.B "int" ib_acm_resolve_name
-.BI "(struct ib_path_record *" path ");"\r
-.SH ARGUMENTS
-.IP "path" 12
-On input, provides path information used to restrict path resolution.  On
-output, contains the full path record.
-.SH "DESCRIPTION"
-Queries the IB SA for a path record using the provided path record to\r
-restrict the query.
-.SH "NOTES"
-Uses the provided path record as input into an SA query for path\r
-information.  If successful, fills in any missing information.  The\r
-caller must provide at least the source and destination LIDs as input.\r
-Use of this call always results in sending a query to the IB SA.\r
-.SH "SEE ALSO"
-ib_acm_resolve_name(3), ib_acm_resolve_ip(3), ib_acm_resolve_path(3),
-ib_acm_convert_to_path(3), ib_acm(7)
-
index 62db005c74404f829991426d1edc32bb1c0d7ead..43e7478406221d7f9aa4c2eb2a5a185cccaec6a1 100644 (file)
@@ -5,36 +5,30 @@ ib_acm_resolve_ip \- Resolve path data between the specified addresses.
 .B "#include <infiniband/ib_acm.h>"
 .P
 .B "int" ib_acm_resolve_ip
-.BI "(struct sockaddr *" src ","\r
-.BI "struct sockaddr *" dest ","\r
-.BI    "struct ib_acm_dev_addr *" dev_addr ","\r
-.BI "struct ibv_ah_attr *" ah ","\r
-.BI    "struct ib_acm_resolve_data *" data ");"\r
+.BI "(struct sockaddr *" src ","
+.BI "struct sockaddr *" dest ","
+.BI "struct ib_acm_path_data *" paths ","
+.BI "int *" count ","
+.BI "struct ib_acm_cm_data *" data ");"
 .SH ARGUMENTS
 .IP "src" 12
 Source address.
 .IP "dest" 12
 Destination address.
-.IP "dev_addr" 12
-On success, local IB device address information.  This includes the
-local device GUID, port number, and pkey index to use for communication.
-.IP "ah" 12
-On success, address handle attributes to send to the destination.  The
-address handle attributes may be used to configure a connected QP or
-create an address handle for datagram traffic.
+.IP "paths" 12
+On success, returns path record information for the connection.
+.IP "count" 12
+On success, indicates the number of paths returned.
 .IP "data" 12
-On success, additional route and endpoint information.  This includes
-the MTU, packet lifetime, and maximum initiator depth and responder
-resources information usable between the end points.
+On success, additional information required for IB CM communication.
 .SH "DESCRIPTION"
-Discover path information, including identifying the local device,\r
+Discover path information, including identifying the local device,
 between the given the source and destination addresses.
 .SH "NOTES"
-The source and destination addresses should match entries in acm_addr.cfg\r
-configuration files on their respective systems.  Typically, the\r
-source and destination addresses will refer to IP addresses assigned\r
-to an IPoIB instance.\r
+The source and destination addresses should match entries in acm_addr.cfg
+configuration files on their respective systems.  Typically, the
+source and destination addresses will refer to IP addresses assigned
+to an IPoIB instance.  The caller must free the returned paths array.
 .SH "SEE ALSO"
-ib_acm_resolve_name(3), ib_acm_resolve_path(3), ib_acm_query_path(3),
-ib_acm_convert_to_path(3), ib_acm(7)
+ib_acm_resolve_name(3), ib_acm_resolve_path(3), ib_acm(7)
 
index d7bf9fb973bd40dc54e66d9b2313321b20f8f7d9..4b3ccf3e61436d9bea2294cf3400c5f92db04a7e 100644 (file)
@@ -5,36 +5,31 @@ ib_acm_resolve_name \- Resolve path data between the specified names.
 .B "#include <infiniband/ib_acm.h>"
 .P
 .B "int" ib_acm_resolve_name
-.BI "(char *" src ","\r
-.BI "char *" dest ","\r
-.BI    "struct ib_acm_dev_addr *" dev_addr ","\r
-.BI "struct ibv_ah_attr *" ah ","\r
-.BI    "struct ib_acm_resolve_data *" data ");"\r
+.BI "(char *" src ","
+.BI "char *" dest ","
+.BI "struct ib_acm_path_data *" paths ","
+.BI "int *" count ","
+.BI "struct ib_acm_cm_data *" data ");"
 .SH ARGUMENTS
 .IP "src" 12
 Source system network name or host name.
 .IP "dest" 12
 Destination system network name or host name.
-.IP "dev_addr" 12
-On success, local IB device address information.  This includes the
-local device GUID, port number, and pkey index to use for communication.
-.IP "ah" 12
-On success, address handle attributes to send to the destination.  The
-address handle attributes may be used to configure a connected QP or
-create an address handle for datagram traffic.
+.IP "paths" 12
+On success, returns path record information for the connection.
+.IP "count" 12
+On success, indicates the number of paths returned.
 .IP "data" 12
-On success, additional route and endpoint information.  This includes
-the MTU, packet lifetime, and maximum initiator depth and responder
-resources information usable between the end points.
+On success, additional information required for IB CM communication.
 .SH "DESCRIPTION"
-Discover path information, including identifying the local device,\r
+Discover path information, including identifying the local device,
 between the given the source and destination names.
 .SH "NOTES"
-The source and destination names should match entries in acm_addr.cfg\r
-configuration files on their respective systems.  Typically, the\r
-source and destination names will refer to system host names\r
-assigned to an Infiniband port.\r
+The source and destination names should match entries in acm_addr.cfg
+configuration files on their respective systems.  Typically, the
+source and destination names will refer to system host names
+assigned to an Infiniband port.  The caller must free the returned
+paths array.
 .SH "SEE ALSO"
-ib_acm_resolve_ip(3), ib_acm_resolve_path(3), ib_acm_query_path(3),
-ib_acm_convert_to_path(3), ib_acm(7)
+ib_acm_resolve_ip(3), ib_acm_resolve_path(3), ib_acm(7)
 
index 11ada6bbad0c9296253450d62afe47aafd4ae3d2..fd1319085bdb1db6785c49655f230573bc7c0efc 100644 (file)
@@ -4,21 +4,24 @@ ib_acm_resolve_path \- Resolve path data meeting specified restrictions.
 .SH SYNOPSIS
 .B "#include <infiniband/ib_acm.h>"
 .P
-.B "int" ib_acm_resolve_name
-.BI "(struct ib_path_record *" path ");"\r
+.B "int" ib_acm_resolve_path
+.BI "(struct ib_path_record *" path ","
+.BI "uint32_t " flags ");"
 .SH ARGUMENTS
 .IP "path" 12
 On input, provides path information used to restrict path resolution.  On
 output, contains the full path record.
+.IP "flags" 12
+If set to IB_ACM_FLAGS_QUERY_SA, the requested path data will be obtained
+by querying the SA directly.  Otherwise, cached data may be provided.
 .SH "DESCRIPTION"
-Discover path information using the provided path record to\r
-restrict the discovery.\r
+Discover path information using the provided path record to
+restrict the discovery.
 .SH "NOTES"
-Uses the provided path record as input into an query for path\r
-information.  If successful, fills in any missing information.  The\r
-caller must provide at least the source and destination LIDs as input.\r
-The returned path record may come from cached data.\r
+Uses the provided path record as input into an query for path
+information.  If successful, fills in any missing information.  The
+caller must provide at least the source and destination LIDs as input.
+The returned path record may come from cached data.
 .SH "SEE ALSO"
-ib_acm_resolve_name(3), ib_acm_resolve_ip(3), ib_acm_query_path(3),
-ib_acm_convert_to_path(3), ib_acm(7)
+ib_acm_resolve_name(3), ib_acm_resolve_ip(3), ib_acm(7)
 
index f4e086e32f590bc34fb0e1baeee426d8cfd5fccb..0311b52199ceab3aef3ed78914641aea41d1c730 100644 (file)
--- a/src/acm.c
+++ b/src/acm.c
 \r
 struct acm_dest\r
 {\r
-       uint8_t            address[ACM_MAX_ADDRESS]; /* keep first */\r
-       struct ibv_ah      *ah;\r
-       struct ibv_ah_attr av;\r
-       union ibv_gid      mgid;\r
-       DLIST_ENTRY        req_queue;\r
-       uint32_t           remote_qpn;\r
-       uint8_t            init_depth;\r
-       uint8_t            resp_resources;\r
-       uint8_t            mtu;\r
-       uint8_t            packet_lifetime;\r
+       uint8_t               address[ACM_MAX_ADDRESS]; /* keep first */\r
+       struct ibv_ah         *ah;\r
+       struct ibv_ah_attr    av;\r
+       struct ib_path_record path;\r
+       union ibv_gid         mgid;\r
+       DLIST_ENTRY           req_queue;\r
+       uint32_t              remote_qpn;\r
+       uint8_t               init_depth;\r
+       uint8_t               resp_resources;\r
 };\r
 \r
 struct acm_port\r
@@ -95,7 +94,7 @@ struct acm_ep
        struct ibv_mr      *mr;\r
        uint8_t            *recv_bufs;\r
        DLIST_ENTRY        entry;\r
-       union acm_ep_addr  addr[MAX_EP_ADDR];\r
+       union acm_ep_info  addr[MAX_EP_ADDR];\r
        uint8_t            addr_type[MAX_EP_ADDR];\r
        void               *dest_map[ACM_ADDRESS_RESERVED - 1];\r
        struct acm_dest    mc_dest[MAX_EP_MC];\r
@@ -176,9 +175,9 @@ static void acm_write(int level, const char *format, ...)
        va_end(args);\r
 }\r
 \r
-static void acm_log_ep_addr(int level, const char *msg,\r
-       union acm_ep_addr *addr, uint8_t ep_type)\r
+static void acm_log_ep_addr(int level, const char *msg, uint16_t type, uint8_t *data)\r
 {\r
+       struct ib_path_record *path;\r
        char ip_addr[ACM_MAX_ADDRESS];\r
 \r
        if (level > log_level)\r
@@ -186,27 +185,28 @@ static void acm_log_ep_addr(int level, const char *msg,
 \r
        lock_acquire(&log_lock);\r
        fprintf(flog, msg);\r
-       switch (ep_type) {\r
-       case ACM_EP_TYPE_NAME:\r
-               fprintf(flog, "%s\n", addr->name);\r
+       switch (type) {\r
+       case ACM_EP_INFO_NAME:\r
+               fprintf(flog, "%s\n", data);\r
                break;\r
-       case ACM_EP_TYPE_ADDRESS_IP:\r
-               inet_ntop(AF_INET, addr->addr, ip_addr, ACM_MAX_ADDRESS);\r
+       case ACM_EP_INFO_ADDRESS_IP:\r
+               inet_ntop(AF_INET, data, ip_addr, ACM_MAX_ADDRESS);\r
                fprintf(flog, "%s\n", ip_addr);\r
                break;\r
-       case ACM_EP_TYPE_ADDRESS_IP6:\r
-               inet_ntop(AF_INET6, addr->addr, ip_addr, ACM_MAX_ADDRESS);\r
+       case ACM_EP_INFO_ADDRESS_IP6:\r
+               inet_ntop(AF_INET6, data, ip_addr, ACM_MAX_ADDRESS);\r
                fprintf(flog, "%s\n", ip_addr);\r
                break;\r
-       case ACM_EP_TYPE_DEVICE:\r
-               fprintf(flog, "device guid 0x%llx, pkey index %d, port %d\n",\r
-                       addr->dev.guid, addr->dev.pkey_index, addr->dev.port_num);\r
+       case ACM_EP_INFO_CM:\r
+               fprintf(flog, "cm data not displayed\n");\r
                break;\r
-       case ACM_EP_TYPE_AV:\r
-               fprintf(flog, "endpoint specified using address vector\n");\r
+       case ACM_EP_INFO_PATH:\r
+               path = (struct ib_path_record *) data;\r
+               fprintf(flog, "path record, SLID 0x%x, DLID 0x%x\n",\r
+                       ntohs(path->slid), ntohs(path->dlid));\r
                break;\r
        default:\r
-               fprintf(flog, "unknown endpoint address 0x%x\n", ep_type);\r
+               fprintf(flog, "unknown endpoint address 0x%x\n", type);\r
        }\r
        lock_release(&log_lock);\r
 }\r
@@ -390,25 +390,38 @@ static int acm_mc_index(struct acm_ep *ep, union ibv_gid *gid)
 }\r
 \r
 static void\r
-acm_init_mc_av(struct acm_port *port, struct ib_mc_member_rec *mc_rec,\r
-       struct ibv_ah_attr *av)\r
+acm_record_mc_av(struct acm_port *port, struct ib_mc_member_rec *mc_rec,\r
+       struct acm_dest *dest)\r
 {\r
        uint32_t sl_flow_hop;\r
 \r
        sl_flow_hop = ntohl(mc_rec->sl_flow_hop);\r
 \r
-       av->dlid = ntohs(mc_rec->mlid);\r
-       av->sl = (uint8_t) (sl_flow_hop >> 28);\r
-       av->src_path_bits = port->sa_dest.av.src_path_bits;\r
-       av->static_rate = mc_rec->rate & 0x3F;\r
-       av->port_num = port->port_num;\r
-\r
-       av->is_global = 1;\r
-       av->grh.dgid = mc_rec->mgid;\r
-       av->grh.flow_label = (sl_flow_hop >> 8) & 0xFFFFF;\r
-       av->grh.sgid_index = acm_gid_index(port, &mc_rec->port_gid);\r
-       av->grh.hop_limit = (uint8_t) sl_flow_hop;\r
-       av->grh.traffic_class = mc_rec->tclass;\r
+       dest->av.dlid = ntohs(mc_rec->mlid);\r
+       dest->av.sl = (uint8_t) (sl_flow_hop >> 28);\r
+       dest->av.src_path_bits = port->sa_dest.av.src_path_bits;\r
+       dest->av.static_rate = mc_rec->rate & 0x3F;\r
+       dest->av.port_num = port->port_num;\r
+\r
+       dest->av.is_global = 1;\r
+       dest->av.grh.dgid = mc_rec->mgid;\r
+       dest->av.grh.flow_label = (sl_flow_hop >> 8) & 0xFFFFF;\r
+       dest->av.grh.sgid_index = acm_gid_index(port, &mc_rec->port_gid);\r
+       dest->av.grh.hop_limit = (uint8_t) sl_flow_hop;\r
+       dest->av.grh.traffic_class = mc_rec->tclass;\r
+\r
+       dest->path.dgid = mc_rec->mgid;\r
+       dest->path.sgid = mc_rec->port_gid;\r
+       dest->path.dlid = mc_rec->mlid;\r
+       dest->path.slid = htons(port->lid) | port->sa_dest.av.src_path_bits;\r
+       dest->path.flowlabel_hoplimit = htonl(sl_flow_hop & 0xFFFFFFF);\r
+       dest->path.tclass = mc_rec->tclass;\r
+       dest->path.reversible_numpath = IB_PATH_RECORD_REVERSIBLE | 1;\r
+       dest->path.pkey = mc_rec->pkey;\r
+       dest->path.qosclass_sl = htons((uint16_t) (sl_flow_hop >> 28));\r
+       dest->path.mtu = mc_rec->mtu;\r
+       dest->path.rate = mc_rec->rate;\r
+       dest->path.packetlifetime = mc_rec->packet_lifetime;\r
 }\r
 \r
 static void acm_process_join_resp(struct acm_ep *ep, struct ib_user_mad *umad)\r
@@ -437,9 +450,7 @@ static void acm_process_join_resp(struct acm_ep *ep, struct ib_user_mad *umad)
                dest = &ep->mc_dest[index];\r
                dest->remote_qpn = IB_MC_QPN;\r
                dest->mgid = mc_rec->mgid;\r
-               acm_init_mc_av(ep->port, mc_rec, &dest->av);\r
-               dest->mtu = mc_rec->mtu & 0x3F;\r
-               dest->packet_lifetime = mc_rec->packet_lifetime & 0x3F;\r
+               acm_record_mc_av(ep->port, mc_rec, dest);\r
                dest->ah = ibv_create_ah(ep->port->dev->pd, &dest->av);\r
                ret = ibv_attach_mcast(ep->qp, &mc_rec->mgid, mc_rec->mlid);\r
                if (ret) {\r
@@ -493,8 +504,10 @@ acm_record_av(struct acm_dest *dest, struct acm_ep *ep,
                        dest->av.grh.dgid = ((struct ibv_grh *) (uintptr_t) wc->wr_id)->sgid;\r
                        \r
                        dest->mgid = ep->mc_dest[index].mgid;\r
-                       dest->mtu = ep->mc_dest[index].mtu;\r
-                       dest->packet_lifetime = ep->mc_dest[index].packet_lifetime;\r
+\r
+                       dest->path = ep->mc_dest[index].path;\r
+                       dest->path.dgid = dest->av.grh.dgid;\r
+                       dest->path.dlid = htons(dest->av.dlid);\r
                        return ACM_STATUS_SUCCESS;\r
                }\r
        }\r
@@ -651,11 +664,15 @@ acm_process_resolve_req(struct acm_ep *ep, struct ibv_wc *wc, struct acm_mad *ma
 \r
 static int\r
 acm_client_resolve_resp(struct acm_ep *ep, struct acm_client *client,\r
-       struct acm_resolve_msg *msg, struct acm_dest *dest, uint8_t status)\r
+       struct acm_resolve_msg *req_msg, struct acm_dest *dest, uint8_t status)\r
 {\r
+       struct acm_msg msg;\r
+       struct acm_resolve_msg *resp_msg = (struct acm_resolve_msg *) &msg;\r
        int ret;\r
 \r
        acm_log(1, "status 0x%x\n", status);\r
+       memset(&msg, 0, sizeof msg);\r
+\r
        lock_acquire(&client->lock);\r
        if (client->sock == INVALID_SOCKET) {\r
                acm_log(0, "ERROR - connection lost\n");\r
@@ -663,29 +680,27 @@ acm_client_resolve_resp(struct acm_ep *ep, struct acm_client *client,
                goto release;\r
        }\r
 \r
-       msg->hdr.opcode |= ACM_OP_ACK;\r
-       msg->hdr.status = status;\r
-       msg->hdr.param = 0;\r
+       resp_msg->hdr = req_msg->hdr;\r
+       resp_msg->hdr.opcode |= ACM_OP_ACK;\r
+       resp_msg->hdr.status = status;\r
+       resp_msg->hdr.length = ACM_MSG_HDR_LENGTH;\r
 \r
        if (!status) {\r
-               msg->hdr.src_type = ACM_EP_TYPE_DEVICE;\r
-               msg->src.dev.guid = ep->port->dev->guid;\r
-               msg->src.dev.pkey_index = ep->pkey_index;\r
-               msg->src.dev.port_num = ep->port->port_num;\r
-\r
-               if (dest) {\r
-                       acm_log(2, "destination found\n");\r
-                       msg->hdr.dest_type = ACM_EP_TYPE_AV;\r
-                       msg->dest.av = dest->av;\r
-                       msg->data.init_depth = min(ep->port->dev->init_depth, dest->resp_resources);\r
-                       msg->data.resp_resources = min(ep->port->dev->resp_resources, dest->init_depth);\r
-                       msg->data.packet_lifetime = dest->packet_lifetime;\r
-                       msg->data.mtu = dest->mtu;\r
-               }\r
+               resp_msg->hdr.length += ACM_MSG_EP_LENGTH;\r
+               resp_msg->data[0].flags = IB_ACM_FLAGS_CM |\r
+                       IB_ACM_FLAGS_PRIMARY | IB_ACM_FLAGS_BIDIRECTIONAL;\r
+               resp_msg->data[0].type = ACM_EP_INFO_PATH;\r
+               resp_msg->data[0].info.path = dest->path;\r
+\r
+               resp_msg->hdr.length += ACM_MSG_EP_LENGTH;\r
+               resp_msg->data[1].flags = IB_ACM_FLAGS_CM | IB_ACM_FLAGS_BIDIRECTIONAL;\r
+               resp_msg->data[1].type = ACM_EP_INFO_CM;\r
+               resp_msg->data[1].info.cm.init_depth = dest->init_depth;\r
+               resp_msg->data[1].info.cm.resp_resources = dest->resp_resources;\r
        }\r
 \r
-       ret = send(client->sock, (char *) msg, sizeof *msg, 0);\r
-       if (ret != sizeof(*msg))\r
+       ret = send(client->sock, (char *) resp_msg, resp_msg->hdr.length, 0);\r
+       if (ret != resp_msg->hdr.length)\r
                acm_log(0, "failed to send response\n");\r
        else\r
                ret = 0;\r
@@ -1118,8 +1133,7 @@ static void acm_process_timeouts(void)
                rec = (struct acm_resolve_rec *) mad->data;\r
                ep = msg->ep;\r
 \r
-               acm_log_ep_addr(0, "acm_process_timeouts: dest ",\r
-                       (union acm_ep_addr *) &rec->dest, rec->dest_type);\r
+               acm_log_ep_addr(0, "acm_process_timeouts: dest ", rec->dest_type, rec->dest);\r
                lock_acquire(&ep->lock);\r
                tdest = tfind(rec->dest, &ep->dest_map[rec->dest_type - 1], acm_compare_dest);\r
                if (!tdest) {\r
@@ -1300,18 +1314,9 @@ static void acm_svr_accept(void)
        acm_log(2, "assigned client id %d\n", i);\r
 }\r
 \r
-static uint8_t acm_get_addr_type(uint8_t ep_type)\r
-{\r
-       if (ep_type >= ACM_ADDRESS_RESERVED) {\r
-               acm_log(0, "ERROR - invalid ep type %d\n", ep_type);\r
-               return ACM_ADDRESS_INVALID;\r
-       }\r
-       return ep_type;\r
-}\r
-\r
 static int\r
 acm_client_query_resp(struct acm_ep *ep, struct acm_client *client,\r
-       struct acm_query_msg *msg, uint8_t status)\r
+       struct acm_resolve_msg *msg, uint8_t status)\r
 {\r
        int ret;\r
 \r
@@ -1326,8 +1331,8 @@ acm_client_query_resp(struct acm_ep *ep, struct acm_client *client,
        msg->hdr.opcode |= ACM_OP_ACK;\r
        msg->hdr.status = status;\r
 \r
-       ret = send(client->sock, (char *) msg, sizeof *msg, 0);\r
-       if (ret != sizeof(*msg))\r
+       ret = send(client->sock, (char *) msg, msg->hdr.length, 0);\r
+       if (ret != msg->hdr.length)\r
                acm_log(0, "failed to send response\n");\r
        else\r
                ret = 0;\r
@@ -1338,48 +1343,13 @@ release:
        return ret;\r
 }\r
 \r
-static struct acm_ep *\r
-acm_get_ep_by_path(struct ib_path_record *path)\r
-{\r
-       struct acm_device *dev;\r
-       struct acm_port *port;\r
-       struct acm_ep *ep;\r
-       DLIST_ENTRY *dev_entry, *ep_entry;\r
-       int i;\r
-\r
-       for (dev_entry = dev_list.Next; dev_entry != &dev_list;\r
-                dev_entry = dev_entry->Next) {\r
-\r
-               dev = container_of(dev_entry, struct acm_device, entry);\r
-               for (i = 0; i < dev->port_cnt; i++) {\r
-                       port = &dev->port[i];\r
-\r
-                       // requires slid\r
-                       if (port->lid != ntohs(path->slid))\r
-                               continue;\r
-\r
-                       for (ep_entry = port->ep_list.Next; ep_entry != &port->ep_list;\r
-                                ep_entry = ep_entry->Next) {\r
-\r
-                               // ignores pkey\r
-                               ep = container_of(ep_entry, struct acm_ep, entry);\r
-                               return ep;\r
-                       }\r
-               }\r
-       }\r
-\r
-       acm_log(0, "could not find endpoint\n");\r
-       return NULL;\r
-}\r
-\r
 // TODO: process send/recv asynchronously\r
-static uint8_t acm_query_sa(struct acm_ep *ep, uint8_t query, union acm_query_data *data)\r
+static uint8_t acm_query_sa(struct acm_ep *ep, struct ib_path_record *path)\r
 {\r
        struct acm_port *port;\r
        struct ib_sa_mad *mad;\r
        struct ib_user_mad *umad;\r
        int ret, len;\r
-       size_t size;\r
 \r
        acm_log(2, "\n");\r
        len = sizeof(*umad) + sizeof(*mad);\r
@@ -1398,16 +1368,7 @@ static uint8_t acm_query_sa(struct acm_ep *ep, uint8_t query, union acm_query_da
        umad->addr.path_bits = port->sa_dest.av.src_path_bits;\r
 \r
        mad = (struct ib_sa_mad *) umad->data;\r
-       switch (query) {\r
-       case ACM_QUERY_PATH_RECORD:\r
-               acm_init_path_query(mad, &data->path);\r
-               size = sizeof(data->path);\r
-               break;\r
-       default:\r
-               acm_log(0, "ERROR - unknown attribute id\n");\r
-               ret = ACM_STATUS_EINVAL;\r
-               goto out;\r
-       }\r
+       acm_init_path_query(mad, path);\r
 \r
        ret = umad_send(port->mad_portid, port->mad_agentid, (void *) umad,\r
                sizeof(*mad), timeout, retries);\r
@@ -1423,7 +1384,7 @@ static uint8_t acm_query_sa(struct acm_ep *ep, uint8_t query, union acm_query_da
                goto out;\r
        }\r
 \r
-       memcpy(data, mad->data, size);\r
+       memcpy(path, mad->data, sizeof *path);\r
        ret = umad->status ? umad->status : mad->status;\r
        if (ret) {\r
                acm_log(0, "SA query response error: 0x%x\n", ret);\r
@@ -1434,14 +1395,65 @@ out:
        return (uint8_t) ret;\r
 }\r
 \r
+static struct acm_ep *\r
+acm_get_ep(struct acm_ep_addr_data *data)\r
+{\r
+       struct acm_device *dev;\r
+       struct acm_port *port;\r
+       struct acm_ep *ep;\r
+       DLIST_ENTRY *dev_entry, *ep_entry;\r
+       int i;\r
+\r
+       acm_log_ep_addr(2, "acm_get_ep: ", data->type, data->info.addr);\r
+       for (dev_entry = dev_list.Next; dev_entry != &dev_list;\r
+                dev_entry = dev_entry->Next) {\r
+\r
+               dev = container_of(dev_entry, struct acm_device, entry);\r
+               for (i = 0; i < dev->port_cnt; i++) {\r
+                       port = &dev->port[i];\r
+\r
+                       if (data->type == ACM_EP_INFO_PATH &&\r
+                           port->lid != ntohs(data->info.path.slid))\r
+                               continue;\r
+\r
+                       for (ep_entry = port->ep_list.Next; ep_entry != &port->ep_list;\r
+                                ep_entry = ep_entry->Next) {\r
+\r
+                               ep = container_of(ep_entry, struct acm_ep, entry);\r
+                               if (data->type == ACM_EP_INFO_PATH)\r
+                                       return ep; // TODO: check pkey\r
+\r
+                               if (acm_addr_index(ep, data->info.addr,\r
+                                   (uint8_t) data->type) >= 0)\r
+                                       return ep;\r
+                       }\r
+               }\r
+       }\r
+\r
+       acm_log_ep_addr(0, "acm_get_ep: could not find ", data->type, data->info.addr);\r
+       return NULL;\r
+}\r
+\r
 static int\r
-acm_svr_query(struct acm_client *client, struct acm_query_msg *msg)\r
+acm_svr_query(struct acm_client *client, struct acm_resolve_msg *msg)\r
 {\r
        struct acm_ep *ep;\r
        uint8_t status;\r
 \r
        acm_log(2, "processing client query\n");\r
-       ep = acm_get_ep_by_path(&msg->data.path);\r
+       if (msg->hdr.length != ACM_MSG_HDR_LENGTH + ACM_MSG_EP_LENGTH) {\r
+               acm_log(0, "ERROR - invalid length: 0x%x\n", msg->hdr.length);\r
+               status = ACM_STATUS_EINVAL;\r
+               goto resp;\r
+       }\r
+\r
+       if (msg->data[0].type != ACM_EP_INFO_PATH) {\r
+               acm_log(0, "ERROR - unsupported type: 0x%x\n", msg->data[0].type);\r
+               status = ACM_STATUS_EINVAL;\r
+               goto resp;\r
+       }\r
+\r
+       ep = acm_get_ep(&msg->data[0]);\r
        if (!ep) {\r
                acm_log(0, "could not find local end point\n");\r
                status = ACM_STATUS_ESRCADDR;\r
@@ -1450,7 +1462,7 @@ acm_svr_query(struct acm_client *client, struct acm_query_msg *msg)
 \r
        (void) atomic_inc(&client->refcnt);\r
        lock_acquire(&ep->lock);\r
-       status = acm_query_sa(ep, msg->hdr.param & ~ACM_QUERY_SA, &msg->data);\r
+       status = acm_query_sa(ep, &msg->data[0].info.path);\r
        lock_release(&ep->lock);\r
 \r
 resp:\r
@@ -1458,8 +1470,8 @@ resp:
 }\r
 \r
 static uint8_t\r
-acm_send_resolve(struct acm_ep *ep, union acm_ep_addr *src, uint8_t src_type,\r
-       struct acm_dest *dest, uint8_t dest_type)\r
+acm_send_resolve(struct acm_ep *ep, struct acm_ep_addr_data *saddr,\r
+       struct acm_ep_addr_data *daddr)\r
 {\r
        struct acm_send_msg *msg;\r
        struct acm_mad *mad;\r
@@ -1488,12 +1500,12 @@ acm_send_resolve(struct acm_ep *ep, union acm_ep_addr *src, uint8_t src_type,
        mad->tid = (uint64_t) atomic_inc(&tid);\r
 \r
        rec = (struct acm_resolve_rec *) mad->data;\r
-       rec->src_type = src_type;\r
+       rec->src_type = (uint8_t) saddr->type;\r
        rec->src_length = ACM_MAX_ADDRESS;\r
-       memcpy(rec->src, src->addr, ACM_MAX_ADDRESS);\r
-       rec->dest_type = dest_type;\r
+       memcpy(rec->src, saddr->info.addr, ACM_MAX_ADDRESS);\r
+       rec->dest_type = (uint8_t) daddr->type;\r
        rec->dest_length = ACM_MAX_ADDRESS;\r
-       memcpy(rec->dest, dest->address, ACM_MAX_ADDRESS);\r
+       memcpy(rec->dest, daddr->info.addr, ACM_MAX_ADDRESS);\r
        rec->resp_resources = ep->port->dev->resp_resources;\r
        rec->init_depth = ep->port->dev->init_depth;\r
 \r
@@ -1505,35 +1517,27 @@ acm_send_resolve(struct acm_ep *ep, union acm_ep_addr *src, uint8_t src_type,
        return 0;\r
 }\r
 \r
-static struct acm_ep *\r
-acm_get_ep_by_addr(union acm_ep_addr *addr, uint8_t src_type)\r
+static uint8_t\r
+acm_svr_verify_resolve(struct acm_resolve_msg *msg)\r
 {\r
-       struct acm_device *dev;\r
-       struct acm_port *port;\r
-       struct acm_ep *ep;\r
-       DLIST_ENTRY *dev_entry, *ep_entry;\r
-       int i;\r
-\r
-       acm_log_ep_addr(2, "acm_get_ep_by_addr: ", addr, src_type);\r
-       for (dev_entry = dev_list.Next; dev_entry != &dev_list;\r
-                dev_entry = dev_entry->Next) {\r
-\r
-               dev = container_of(dev_entry, struct acm_device, entry);\r
-               for (i = 0; i < dev->port_cnt; i++) {\r
-                       port = &dev->port[i];\r
+       if (msg->hdr.length != ACM_MSG_HDR_LENGTH + 2 * ACM_MSG_EP_LENGTH) {\r
+               acm_log(0, "ERROR - invalid msg hdr length %d\n", msg->hdr.length);\r
+               return ACM_STATUS_EINVAL;\r
+       }\r
 \r
-                       for (ep_entry = port->ep_list.Next; ep_entry != &port->ep_list;\r
-                                ep_entry = ep_entry->Next) {\r
+       if ((msg->data[0].flags != IB_ACM_FLAGS_INBOUND) ||\r
+           !msg->data[0].type || (msg->data[0].type >= ACM_ADDRESS_RESERVED)) {\r
+               acm_log(0, "ERROR - source address required first\n");\r
+               return ACM_STATUS_ESRCTYPE;\r
+       }\r
 \r
-                               ep = container_of(ep_entry, struct acm_ep, entry);\r
-                               if (acm_addr_index(ep, addr->addr, src_type) >= 0)\r
-                                       return ep;\r
-                       }\r
-               }\r
+       if ((msg->data[1].flags != IB_ACM_FLAGS_OUTBOUND) ||\r
+           !msg->data[1].type || (msg->data[1].type >= ACM_ADDRESS_RESERVED)) {\r
+               acm_log(0, "ERROR - destination address required second\n");\r
+               return ACM_STATUS_EDESTTYPE;\r
        }\r
 \r
-       acm_log_ep_addr(0, "acm_get_ep_by_addr: could not find ", addr, src_type);\r
-       return NULL;\r
+       return ACM_STATUS_SUCCESS;\r
 }\r
 \r
 static int\r
@@ -1542,28 +1546,30 @@ acm_svr_resolve(struct acm_client *client, struct acm_resolve_msg *msg)
        struct acm_ep *ep;\r
        struct acm_dest *dest, **tdest;\r
        struct acm_request *req;\r
-       uint8_t dest_type, src_type;\r
+       struct acm_ep_addr_data *saddr, *daddr;\r
        uint8_t status;\r
 \r
-       acm_log_ep_addr(2, "acm_svr_resolve: source ", &msg->src, msg->hdr.src_type);\r
-       ep = acm_get_ep_by_addr(&msg->src, msg->hdr.src_type);\r
-       if (!ep) {\r
-               acm_log(0, "unknown local end point\n");\r
-               status = ACM_STATUS_ESRCADDR;\r
+       status = acm_svr_verify_resolve(msg);\r
+       if (status) {\r
+               acm_log(0, "misformatted or unsupported request\n");\r
                goto resp;\r
        }\r
 \r
-       dest_type = acm_get_addr_type(msg->hdr.dest_type);\r
-       if (dest_type == ACM_ADDRESS_INVALID) {\r
-               acm_log(0, "ERROR - unknown destination type\n");\r
-               status = ACM_STATUS_EDESTTYPE;\r
+       saddr = &msg->data[0];\r
+       daddr = &msg->data[1];\r
+\r
+       acm_log_ep_addr(2, "acm_svr_resolve: source ", saddr->type, saddr->info.addr);\r
+       ep = acm_get_ep(saddr);\r
+       if (!ep) {\r
+               acm_log(0, "unknown local end point\n");\r
+               status = ACM_STATUS_ESRCADDR;\r
                goto resp;\r
        }\r
 \r
-       acm_log_ep_addr(2, "acm_svr_resolve: dest ", &msg->dest, msg->hdr.dest_type);\r
+       acm_log_ep_addr(2, "acm_svr_resolve: dest ", daddr->type, daddr->info.addr);\r
        (void) atomic_inc(&client->refcnt);\r
        lock_acquire(&ep->lock);\r
-       tdest = tfind(msg->dest.addr, &ep->dest_map[dest_type - 1], acm_compare_dest);\r
+       tdest = tfind(&daddr->info.addr, &ep->dest_map[daddr->type - 1], acm_compare_dest);\r
        dest = tdest ? *tdest : NULL;\r
        if (dest && dest->ah) {\r
                acm_log(2, "request satisfied from local cache\n");\r
@@ -1587,17 +1593,16 @@ acm_svr_resolve(struct acm_client *client, struct acm_resolve_msg *msg)
                        goto free_req;\r
                }\r
 \r
-               memcpy(dest->address, msg->dest.addr, ACM_MAX_ADDRESS);\r
-               src_type = acm_get_addr_type(msg->hdr.src_type);\r
+               memcpy(dest->address, &daddr->info.addr, ACM_MAX_ADDRESS);\r
                acm_log(2, "sending resolve msg to dest\n");\r
-               status = acm_send_resolve(ep, &msg->src, src_type, dest, dest_type);\r
+               status = acm_send_resolve(ep, saddr, daddr);\r
                if (status) {\r
                        acm_log(0, "ERROR - failure sending resolve request 0x%x\n", status);\r
                        goto free_dest;\r
                }\r
 \r
                DListInit(&dest->req_queue);\r
-               tsearch(dest, &ep->dest_map[dest_type - 1], acm_compare_dest);\r
+               tsearch(dest, &ep->dest_map[daddr->type - 1], acm_compare_dest);\r
        }\r
 \r
        acm_log(2, "queuing client request\n");\r
@@ -1621,11 +1626,12 @@ resp:
 static void acm_svr_receive(struct acm_client *client)\r
 {\r
        struct acm_msg msg;\r
+       struct acm_resolve_msg *resolve_msg = (struct acm_resolve_msg *) &msg;\r
        int ret;\r
 \r
        acm_log(2, "\n");\r
        ret = recv(client->sock, (char *) &msg, sizeof msg, 0);\r
-       if (ret != sizeof msg) {\r
+       if (ret != msg.hdr.length) {\r
                acm_log(2, "client disconnected\n");\r
                ret = ACM_STATUS_ENOTCONN;\r
                goto out;\r
@@ -1636,17 +1642,15 @@ static void acm_svr_receive(struct acm_client *client)
                goto out;\r
        }\r
 \r
-       switch (msg.hdr.opcode & ACM_OP_MASK) {\r
-       case ACM_OP_RESOLVE:\r
-               ret = acm_svr_resolve(client, (struct acm_resolve_msg *) &msg);\r
-               break;\r
-       case ACM_OP_QUERY:\r
-               ret = acm_svr_query(client, (struct acm_query_msg *) &msg);\r
-               break;\r
-       default:\r
+       if ((msg.hdr.opcode & ACM_OP_MASK) != ACM_OP_RESOLVE) {\r
                acm_log(0, "ERROR - unknown opcode 0x%x\n", msg.hdr.opcode);\r
-               ret = -1;\r
-               break;\r
+               goto out;\r
+       }\r
+\r
+       if (resolve_msg->data[0].type == ACM_EP_INFO_PATH) {\r
+               ret = acm_svr_query(client, resolve_msg);\r
+       } else {\r
+               ret = acm_svr_resolve(client, resolve_msg);\r
        }\r
 \r
 out:\r
index bd1d9802c85398bdd650597fe5eef7cba1d94fa4..f18e25c6daa913d4b411315d3b4ee33524ac2303 100644 (file)
@@ -48,7 +48,6 @@
 \r
 #define ACM_CTRL_ACK     htons(0x8000)\r
 #define ACM_CTRL_RESOLVE htons(0x0001)\r
-#define ACM_CTRL_CM      htons(0x0002)\r
 \r
 struct acm_mad\r
 {\r
@@ -67,6 +66,7 @@ struct acm_mad
 \r
 #define ACM_QKEY 0x80010000\r
 \r
+/* Map to ACM_EP_INFO_* */\r
 #define ACM_ADDRESS_INVALID    0x00\r
 #define ACM_ADDRESS_NAME       0x01\r
 #define ACM_ADDRESS_IP         0x02\r
index 68f4b804b57435d1cdbdc1aef658275dda467095..5cf0c36f5bc0437450bc8dc36e555ed3082e54c5 100644 (file)
@@ -347,11 +347,10 @@ static void show_path(struct ib_path_record *path)
 \r
 static int resolve_ip(struct ib_path_record *path)\r
 {\r
-       struct ib_acm_dev_addr dev_addr;\r
-       struct ibv_ah_attr ah;\r
-       struct ib_acm_resolve_data data;\r
+       struct ib_acm_path_data *paths;\r
+       struct ib_acm_cm_data data;\r
        struct sockaddr_in src, dest;\r
-       int ret;\r
+       int ret, count;\r
 \r
        src.sin_family = AF_INET;\r
        ret = inet_pton(AF_INET, src_addr, &src.sin_addr);\r
@@ -368,37 +367,32 @@ static int resolve_ip(struct ib_path_record *path)
        }\r
 \r
        ret = ib_acm_resolve_ip((struct sockaddr *) &src, (struct sockaddr *) &dest,\r
-               &dev_addr, &ah, &data);\r
+               &paths, &count, &data);\r
        if (ret) {\r
                printf("ib_acm_resolve_ip failed: 0x%x\n", ret);\r
                return ret;\r
        }\r
 \r
-       ret = ib_acm_convert_to_path(&dev_addr, &ah, &data, path);\r
-       if (ret)\r
-               printf("ib_acm_convert_to_path failed: 0x%x\n", ret);\r
-\r
-       return ret;\r
+       *path = paths[0].path;\r
+       ib_acm_free_paths(paths);\r
+       return 0;\r
 }\r
 \r
 static int resolve_name(struct ib_path_record *path)\r
 {\r
-       struct ib_acm_dev_addr dev_addr;\r
-       struct ibv_ah_attr ah;\r
-       struct ib_acm_resolve_data data;\r
-       int ret;\r
+       struct ib_acm_path_data *paths;\r
+       struct ib_acm_cm_data data;\r
+       int ret, count;\r
 \r
-       ret = ib_acm_resolve_name(src_addr, dest_addr, &dev_addr, &ah, &data);\r
+       ret = ib_acm_resolve_name(src_addr, dest_addr, &paths, &count, &data);\r
        if (ret) {\r
                printf("ib_acm_resolve_name failed: 0x%x\n", ret);\r
                return ret;\r
        }\r
 \r
-       ret = ib_acm_convert_to_path(&dev_addr, &ah, &data, path);\r
-       if (ret)\r
-               printf("ib_acm_convert_to_path failed: 0x%x\n", ret);\r
-\r
-       return ret;\r
+       *path = paths[0].path;\r
+       ib_acm_free_paths(paths);\r
+       return 0;\r
 }\r
 \r
 static int resolve_lid(struct ib_path_record *path)\r
@@ -409,7 +403,7 @@ static int resolve_lid(struct ib_path_record *path)
        path->dlid = htons((uint16_t) atoi(dest_addr));\r
        path->reversible_numpath = IB_PATH_RECORD_REVERSIBLE | 1;\r
 \r
-       ret = ib_acm_resolve_path(path);\r
+       ret = ib_acm_resolve_path(path, 0);\r
        if (ret)\r
                printf("ib_acm_resolve_path failed: 0x%x\n", ret);\r
 \r
@@ -420,7 +414,7 @@ static int verify_resolve(struct ib_path_record *path)
 {\r
        int ret;\r
 \r
-       ret = ib_acm_query_path(path);\r
+       ret = ib_acm_resolve_path(path, IB_ACM_FLAGS_QUERY_SA);\r
        if (ret)\r
                printf("SA verification: failed 0x%x\n", ret);\r
        else\r
index fe853aecf72559019e25aba011a29942936228a9..b018e202615d39d2d9440d930f8c3f8663df4c09 100644 (file)
@@ -54,91 +54,6 @@ static SOCKET sock = INVALID_SOCKET;
 static short server_port = 6125;\r
 static int ready;\r
 \r
-static struct acm_device *dev_array;\r
-static int dev_cnt;\r
-\r
-\r
-static int acm_init_port(struct acm_device *dev, int index)\r
-{\r
-       struct acm_port *port;\r
-       struct ibv_port_attr attr;\r
-       int ret;\r
-\r
-       port = &dev->ports[index];\r
-       port->port_num = index + 1;\r
-       ret = ibv_query_gid(dev->verbs, port->port_num, 0, &port->gid);\r
-       if (ret)\r
-               return -1;\r
-\r
-       ret = ibv_query_port(dev->verbs, port->port_num, &attr);\r
-       if (ret)\r
-               return -1;\r
-\r
-       port->lid = attr.lid;\r
-       for (port->pkey_cnt = 0; !ret && port->pkey_cnt < 4; port->pkey_cnt++) {\r
-               ret = ibv_query_pkey(dev->verbs, port->port_num,\r
-                       port->pkey_cnt, &port->pkey[port->pkey_cnt]);\r
-       }\r
-\r
-       return port->pkey_cnt ? 0 : ret;\r
-}\r
-\r
-static int acm_open_devices(void)\r
-{\r
-       struct ibv_device **dev_list;\r
-       struct acm_device *dev;\r
-       struct ibv_device_attr attr;\r
-       int i, p, cnt, ret;\r
-\r
-       dev_list = ibv_get_device_list(&cnt);\r
-       if (!dev_list)\r
-               return -1;\r
-\r
-       dev_array = (struct acm_device *) zalloc(sizeof(struct acm_device) * cnt);\r
-       if (!dev_array)\r
-               goto err1;\r
-\r
-       for (i = 0; dev_list[i];) {\r
-               dev = &dev_array[i];\r
-\r
-               dev->guid = ibv_get_device_guid(dev_list[i]);\r
-               dev->verbs = ibv_open_device(dev_list[i]);\r
-               if (dev->verbs == NULL)\r
-                       goto err2;\r
-\r
-               ++i;\r
-               ret = ibv_query_device(dev->verbs, &attr);\r
-               if (ret)\r
-                       goto err2;\r
-\r
-               dev->port_cnt = attr.phys_port_cnt;\r
-               dev->ports = zalloc(sizeof(struct acm_port) * dev->port_cnt);\r
-               if (!dev->ports)\r
-                       goto err2;\r
-\r
-               for (p = 0; p < dev->port_cnt; p++) {\r
-                       ret = acm_init_port(dev, p);\r
-                       if (ret)\r
-                               goto err2;\r
-               }\r
-       }\r
-\r
-       ibv_free_device_list(dev_list);\r
-       dev_cnt = cnt;\r
-       return 0;\r
-\r
-err2:\r
-       while (i--) {\r
-               ibv_close_device(dev_array[i].verbs);\r
-               if (dev_array[i].ports)\r
-                       free(dev_array[i].ports);\r
-       }\r
-       free(dev_array);\r
-err1:\r
-       ibv_free_device_list(dev_list);\r
-       return -1;\r
-}\r
-\r
 static int acm_init(void)\r
 {\r
        struct sockaddr_in addr;\r
@@ -162,10 +77,6 @@ static int acm_init(void)
        if (ret)\r
                goto err2;\r
 \r
-       ret = acm_open_devices();\r
-       if (ret)\r
-               goto err2;\r
-\r
        ready = 1;\r
        return 0;\r
 \r
@@ -185,11 +96,51 @@ void LIB_DESTRUCTOR acm_cleanup(void)
        }\r
 }\r
 \r
+static int acm_format_resp(struct acm_resolve_msg *msg,\r
+       struct ib_acm_path_data **paths, int *count, struct ib_acm_cm_data *data)\r
+{\r
+       struct ib_acm_path_data *path_data;\r
+       int i, addr_cnt;\r
+\r
+       *count = 0;\r
+       addr_cnt = (msg->hdr.length - ACM_MSG_HDR_LENGTH) /\r
+               sizeof(struct acm_ep_addr_data);\r
+       path_data = (struct ib_acm_path_data *)\r
+               zalloc(addr_cnt * sizeof(struct ib_acm_path_data));\r
+       if (!path_data)\r
+               return -1;\r
+\r
+       memset(data, 0, sizeof *data);\r
+       for (i = 0; i < addr_cnt; i++) {\r
+               switch (msg->data[i].type) {\r
+               case ACM_EP_INFO_PATH:\r
+                       path_data[i].flags = msg->data[i].flags;\r
+                       path_data[i].path  = msg->data[i].info.path;\r
+                       (*count)++;\r
+                       break;\r
+               case ACM_EP_INFO_CM:\r
+                       data->init_depth = msg->data[i].info.cm.init_depth;\r
+                       data->resp_resources = msg->data[i].info.cm.resp_resources;\r
+                       break;\r
+               default:\r
+                       goto err;\r
+               }\r
+       }\r
+\r
+       *paths = path_data;\r
+       return 0;\r
+err:\r
+       free(path_data);\r
+       return -1;\r
+}\r
+\r
 static int acm_resolve(uint8_t *src, uint8_t *dest, uint8_t type,\r
-       struct ib_acm_dev_addr *dev_addr, struct ibv_ah_attr *ah,\r
-       struct ib_acm_resolve_data *data)\r
+       struct ib_acm_path_data **paths, int *count,\r
+       struct ib_acm_cm_data *data)\r
 {\r
-       struct acm_resolve_msg msg;\r
+       struct acm_msg msg;\r
+       struct acm_resolve_msg *resolve_msg = (struct acm_resolve_msg *) &msg;\r
+       struct acm_ep_addr_data *src_data, *dest_data;\r
        int ret;\r
 \r
        lock_acquire(&lock);\r
@@ -199,44 +150,48 @@ static int acm_resolve(uint8_t *src, uint8_t *dest, uint8_t type,
        memset(&msg, 0, sizeof msg);\r
        msg.hdr.version = ACM_VERSION;\r
        msg.hdr.opcode = ACM_OP_RESOLVE;\r
-       msg.hdr.dest_type = type;\r
-       msg.hdr.src_type = type;\r
+       msg.hdr.length = ACM_MSG_HDR_LENGTH + (2 * ACM_MSG_EP_LENGTH);\r
+\r
+       src_data  = &resolve_msg->data[0];\r
+       dest_data = &resolve_msg->data[1];\r
+\r
+       src_data->type   = type;\r
+       src_data->flags  = IB_ACM_FLAGS_INBOUND;\r
+       dest_data->type  = type;\r
+       dest_data->flags = IB_ACM_FLAGS_OUTBOUND;\r
 \r
        switch (type) {\r
-       case ACM_EP_TYPE_NAME:\r
-               strncpy((char *) msg.src.name, (char *) src, ACM_MAX_ADDRESS);\r
-               strncpy((char *) msg.dest.name, (char *) dest, ACM_MAX_ADDRESS);\r
-               break;\r
-       case ACM_EP_TYPE_ADDRESS_IP:\r
-               memcpy(msg.src.addr, &((struct sockaddr_in *) src)->sin_addr, 4);\r
-               memcpy(msg.dest.addr, &((struct sockaddr_in *) dest)->sin_addr, 4);\r
+       case ACM_EP_INFO_NAME:\r
+               strncpy((char *) src_data->info.name,  (char *) src,  ACM_MAX_ADDRESS);\r
+               strncpy((char *) dest_data->info.name, (char *) dest, ACM_MAX_ADDRESS);\r
                break;\r
-       case ACM_EP_TYPE_ADDRESS_IP6:\r
-               memcpy(msg.src.addr, &((struct sockaddr_in6 *) src)->sin6_addr, 16);\r
-               memcpy(msg.dest.addr, &((struct sockaddr_in *) dest)->sin_addr, 16);\r
+       case ACM_EP_INFO_ADDRESS_IP:\r
+               memcpy(src_data->info.addr,  &((struct sockaddr_in *) src)->sin_addr,  4);\r
+               memcpy(dest_data->info.addr, &((struct sockaddr_in *) dest)->sin_addr, 4);\r
                break;\r
-       case ACM_EP_TYPE_AV:\r
-               memcpy(&msg.src.av, src, sizeof(msg.src.av));\r
-               memcpy(&msg.dest.av, dest, sizeof(msg.dest.av));\r
+       case ACM_EP_INFO_ADDRESS_IP6:\r
+               memcpy(src_data->info.addr,  &((struct sockaddr_in6 *) src)->sin6_addr,  16);\r
+               memcpy(dest_data->info.addr, &((struct sockaddr_in6 *) dest)->sin6_addr, 16);\r
                break;\r
        default:\r
                ret = -1;\r
                goto out;\r
        }\r
        \r
-       ret = send(sock, (char *) &msg, sizeof msg, 0);\r
-       if (ret != sizeof msg)\r
+       ret = send(sock, (char *) &msg, msg.hdr.length, 0);\r
+       if (ret != msg.hdr.length)\r
                goto out;\r
 \r
        ret = recv(sock, (char *) &msg, sizeof msg, 0);\r
-       if (ret != sizeof msg)\r
+       if (ret < ACM_MSG_HDR_LENGTH || ret != msg.hdr.length)\r
                goto out;\r
 \r
-       memcpy(dev_addr, &msg.src.dev, sizeof(*dev_addr));\r
-       *ah = msg.dest.av;\r
-       memcpy(data, &msg.data, sizeof(*data));\r
-       ret = 0;\r
+       if (msg.hdr.status) {\r
+               ret = msg.hdr.status;\r
+               goto out;\r
+       }\r
 \r
+       ret = acm_format_resp(resolve_msg, paths, count, data);\r
 out:\r
        lock_release(&lock);\r
        return ret;\r
@@ -244,30 +199,32 @@ out:
 \r
 LIB_EXPORT\r
 int ib_acm_resolve_name(char *src, char *dest,\r
-       struct ib_acm_dev_addr *dev_addr, struct ibv_ah_attr *ah,\r
-       struct ib_acm_resolve_data *data)\r
+       struct ib_acm_path_data **paths, int *count,\r
+       struct ib_acm_cm_data *data)\r
 {\r
        return acm_resolve((uint8_t *) src, (uint8_t *) dest,\r
-               ACM_EP_TYPE_NAME, dev_addr, ah, data);\r
+               ACM_EP_INFO_NAME, paths, count, data);\r
 }\r
 \r
 LIB_EXPORT\r
 int ib_acm_resolve_ip(struct sockaddr *src, struct sockaddr *dest,\r
-       struct ib_acm_dev_addr *dev_addr, struct ibv_ah_attr *ah,\r
-       struct ib_acm_resolve_data *data)\r
+       struct ib_acm_path_data **paths, int *count,\r
+       struct ib_acm_cm_data *data)\r
 {\r
        if (((struct sockaddr *) dest)->sa_family == AF_INET) {\r
                return acm_resolve((uint8_t *) src, (uint8_t *) dest,\r
-                       ACM_EP_TYPE_ADDRESS_IP, dev_addr, ah, data);\r
+                       ACM_EP_INFO_ADDRESS_IP, paths, count, data);\r
        } else {\r
                return acm_resolve((uint8_t *) src, (uint8_t *) dest,\r
-                       ACM_EP_TYPE_ADDRESS_IP6, dev_addr, ah, data);\r
+                       ACM_EP_INFO_ADDRESS_IP6, paths, count, data);\r
        }\r
 }\r
 \r
-static int acm_query_path(struct ib_path_record *path, uint8_t query_sa)\r
+LIB_EXPORT\r
+int ib_acm_resolve_path(struct ib_path_record *path, uint32_t flags)\r
 {\r
-       struct acm_query_msg msg;\r
+       struct acm_msg msg;\r
+       struct acm_ep_addr_data *data;\r
        int ret;\r
 \r
        lock_acquire(&lock);\r
@@ -276,100 +233,27 @@ static int acm_query_path(struct ib_path_record *path, uint8_t query_sa)
 \r
        memset(&msg, 0, sizeof msg);\r
        msg.hdr.version = ACM_VERSION;\r
-       msg.hdr.opcode = ACM_OP_QUERY;\r
-       msg.hdr.param = ACM_QUERY_PATH_RECORD | query_sa;\r
-\r
-       if (path->dgid.global.interface_id || path->dgid.global.subnet_prefix) {\r
-               msg.hdr.dest_type = ACM_EP_TYPE_GID;\r
-       } else if (path->dlid) {\r
-               msg.hdr.dest_type = ACM_EP_TYPE_LID;\r
-       } else {\r
-               ret = -1;\r
-               goto out;\r
-       }\r
-\r
-       if (path->sgid.global.interface_id || path->sgid.global.subnet_prefix) {\r
-               msg.hdr.src_type = ACM_EP_TYPE_GID;\r
-       } else if (path->slid) {\r
-               msg.hdr.src_type = ACM_EP_TYPE_LID;\r
-       } else {\r
-               ret = -1;\r
-               goto out;\r
-       }\r
+       msg.hdr.opcode = ACM_OP_RESOLVE;\r
+       msg.hdr.length = ACM_MSG_HDR_LENGTH + ACM_MSG_EP_LENGTH;\r
 \r
-       msg.data.path = *path;\r
+       data = &((struct acm_resolve_msg *) &msg)->data[0];\r
+       data->flags = flags;\r
+       data->type = ACM_EP_INFO_PATH;\r
+       data->info.path = *path;\r
        \r
-       ret = send(sock, (char *) &msg, sizeof msg, 0);\r
-       if (ret != sizeof msg)\r
+       ret = send(sock, (char *) &msg, msg.hdr.length, 0);\r
+       if (ret != msg.hdr.length)\r
                goto out;\r
 \r
        ret = recv(sock, (char *) &msg, sizeof msg, 0);\r
-       if (ret != sizeof msg)\r
+       if (ret < ACM_MSG_HDR_LENGTH || ret != msg.hdr.length)\r
                goto out;\r
 \r
-       *path = msg.data.path;\r
        ret = msg.hdr.status;\r
+       if (!ret)\r
+               *path = data->info.path;\r
 \r
 out:\r
        lock_release(&lock);\r
        return ret;\r
 }\r
-\r
-LIB_EXPORT\r
-int ib_acm_query_path(struct ib_path_record *path)\r
-{\r
-       return acm_query_path(path, ACM_QUERY_SA);\r
-}\r
-\r
-LIB_EXPORT\r
-int ib_acm_resolve_path(struct ib_path_record *path)\r
-{\r
-       return acm_query_path(path, 0);\r
-}\r
-\r
-static struct acm_device *acm_get_device(uint64_t guid)\r
-{\r
-       int i;\r
-\r
-       for (i = 0; i < dev_cnt; i++) {\r
-               if (dev_array[i].guid == guid)\r
-                       return &dev_array[i];\r
-       }\r
-\r
-       return NULL;\r
-}\r
-\r
-LIB_EXPORT\r
-int ib_acm_convert_to_path(struct ib_acm_dev_addr *dev_addr,\r
-       struct ibv_ah_attr *ah, struct ib_acm_resolve_data *data,\r
-       struct ib_path_record *path)\r
-{\r
-       struct acm_device *dev;\r
-       int p = dev_addr->port_num - 1;\r
-\r
-       dev = acm_get_device(dev_addr->guid);\r
-       if (!dev)\r
-               return -1;\r
-\r
-       if (ah->grh.sgid_index || dev_addr->pkey_index > 4)\r
-               return -1;\r
-\r
-       if (ah->is_global) {\r
-               path->dgid = ah->grh.dgid;\r
-               path->sgid = dev->ports[p].gid;\r
-               path->flowlabel_hoplimit =\r
-                       htonl(ah->grh.flow_label << 8 | (uint32_t) ah->grh.hop_limit);\r
-               path->tclass = ah->grh.traffic_class;\r
-       }\r
-\r
-       path->dlid = htons(ah->dlid);\r
-       path->slid = htons(dev->ports[p].lid | ah->src_path_bits);\r
-       path->reversible_numpath = IB_PATH_RECORD_REVERSIBLE | 1;\r
-       path->pkey = htons(dev->ports[p].pkey[dev_addr->pkey_index]);\r
-       path->qosclass_sl = htons((uint16_t) ah->sl);\r
-       path->mtu = (2 << 6) | data->mtu;\r
-       path->rate = (2 << 6) | ah->static_rate;\r
-       path->packetlifetime = (2 << 6) | data->packet_lifetime;\r
-\r
-       return 0;\r
-}\r
index 0b6b1df34a901ffaa6a4782929f7801120648be8..edf39344b9006b694f26adea9b2f8d5cb42cd652 100644 (file)
@@ -8,4 +8,5 @@ LIBRARY libibacm.dll
 EXPORTS\r
 ib_acm_resolve_name\r
 ib_acm_resolve_ip\r
+ib_acm_resolve_path\r
 #endif\r