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
\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
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
*/\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
*/\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
* 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
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: *;
};
.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
+++ /dev/null
-.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)
-
+++ /dev/null
-.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)
-
.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)
.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)
.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)
\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
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
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
\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
}\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
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
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
\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
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
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
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
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
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
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
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
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
\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
}\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
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
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
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
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
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
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
\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
\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
\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
}\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
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
{\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
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
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
}\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
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
\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
\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
EXPORTS\r
ib_acm_resolve_name\r
ib_acm_resolve_ip\r
+ib_acm_resolve_path\r
#endif\r