#define ACM_STATUS_EDESTTYPE 10
#define ACM_FLAGS_QUERY_SA (1<<31)
+#define ACM_FLAGS_NODELAY (1<<30)
#define ACM_MSG_HDR_LENGTH 16
#define ACM_MAX_ADDRESS 64
active IB SA. Use of the -v option provides a sanity check that\r
resolved path information is usable given the current cluster configuration.\r
.TP\r
+\-c\r
+Instructs the ACM service to only returned information that currently resides\r
+in its local cache.\r
+.TP\r
\-A\r
With this option, the ib_acme utility automatically generates the address\r
configuration file acm_addr.cfg. The generated file is\r
cnt = (msg->hdr.length - ACM_MSG_HDR_LENGTH) / ACM_MSG_EP_LENGTH;
for (i = 0; i < cnt; i++) {
- switch (msg->data[i].flags) {
- case ACM_EP_FLAG_SOURCE:
+ if (msg->data[i].flags & ACM_EP_FLAG_SOURCE) {
if (src) {
acm_log(0, "ERROR - multiple sources specified\n");
return ACM_STATUS_ESRCADDR;
return ACM_STATUS_ESRCTYPE;
}
src = &msg->data[i];
- break;
- case ACM_EP_FLAG_DEST:
+ }
+ if (msg->data[i].flags & ACM_EP_FLAG_DEST) {
if (dst) {
acm_log(0, "ERROR - multiple destinations specified\n");
return ACM_STATUS_EDESTADDR;
return ACM_STATUS_EDESTTYPE;
}
dst = &msg->data[i];
- break;
- default:
- acm_log(0, "ERROR - unexpected endpoint flags 0x%x\n",
- msg->data[i].flags);
- return ACM_STATUS_EINVAL;
}
}
/* fall through */
default:
queue:
+ if (daddr->flags & ACM_FLAGS_NODELAY) {
+ acm_log(2, "lookup initiated, but client wants no delay\n");
+ status = ACM_STATUS_ENODATA;
+ break;
+ }
status = acm_svr_queue_req(dest, client, msg);
if (status) {
break;
static char *src_addr;
static char addr_type = 'i';
static int verify;
+static int nodelay;
static int make_addr;
static int make_opts;
int verbose;
printf(" -s src_addr - format defined by -f option\n");
printf(" -d dest_addr - format defined by -f option\n");
printf(" [-v] - verify ACM response against SA query response\n");
+ printf(" [-c] - read ACM cached data only\n");
printf("usage 2: %s\n", program);
printf(" -A [addr_file] - generate local address configuration file\n");
printf(" (default is %s)\n", ACM_ADDR_FILE);
printf(" packet lifetime: %d\n", path->packetlifetime & 0x1F);
}
+static uint32_t get_resolve_flags()
+{
+ uint32_t flags = 0;
+
+ if (nodelay)
+ flags |= ACM_FLAGS_NODELAY;
+
+ return flags;
+}
+
static int resolve_ip(struct ibv_path_record *path)
{
struct ibv_path_data *paths;
}
ret = ib_acm_resolve_ip((struct sockaddr *) &src, (struct sockaddr *) &dest,
- &paths, &count);
+ &paths, &count, get_resolve_flags());
if (ret) {
printf("ib_acm_resolve_ip failed: 0x%x\n", ret);
return ret;
struct ibv_path_data *paths;
int ret, count;
- ret = ib_acm_resolve_name(src_addr, dest_addr, &paths, &count);
+ ret = ib_acm_resolve_name(src_addr, dest_addr, &paths, &count, get_resolve_flags());
if (ret) {
printf("ib_acm_resolve_name failed: 0x%x\n", ret);
return ret;
if (ret)
goto out;
- while ((op = getopt(argc, argv, "f:s:d:vA::O::D:V")) != -1) {
+ while ((op = getopt(argc, argv, "f:s:d:vcA::O::D:V")) != -1) {
switch (op) {
case 'f':
addr_type = optarg[0];
case 'v':
verify = 1;
break;
+ case 'c':
+ nodelay = 1;
+ break;
case 'A':
make_addr = 1;
if (opt_arg(argc, argv))
}
static int acm_resolve(uint8_t *src, uint8_t *dest, uint8_t type,
- struct ibv_path_data **paths, int *count)
+ struct ibv_path_data **paths, int *count, uint32_t flags)
{
struct acm_msg msg;
struct acm_resolve_msg *resolve_msg = (struct acm_resolve_msg *) &msg;
src_data->type = type;
src_data->flags = ACM_EP_FLAG_SOURCE;
dest_data->type = type;
- dest_data->flags = ACM_EP_FLAG_DEST;
+ dest_data->flags = ACM_EP_FLAG_DEST | flags;
switch (type) {
case ACM_EP_INFO_NAME:
}
int ib_acm_resolve_name(char *src, char *dest,
- struct ibv_path_data **paths, int *count)
+ struct ibv_path_data **paths, int *count, uint32_t flags)
{
return acm_resolve((uint8_t *) src, (uint8_t *) dest,
- ACM_EP_INFO_NAME, paths, count);
+ ACM_EP_INFO_NAME, paths, count, flags);
}
int ib_acm_resolve_ip(struct sockaddr *src, struct sockaddr *dest,
- struct ibv_path_data **paths, int *count)
+ struct ibv_path_data **paths, int *count, uint32_t flags)
{
if (((struct sockaddr *) dest)->sa_family == AF_INET) {
return acm_resolve((uint8_t *) src, (uint8_t *) dest,
- ACM_EP_INFO_ADDRESS_IP, paths, count);
+ ACM_EP_INFO_ADDRESS_IP, paths, count, flags);
} else {
return acm_resolve((uint8_t *) src, (uint8_t *) dest,
- ACM_EP_INFO_ADDRESS_IP6, paths, count);
+ ACM_EP_INFO_ADDRESS_IP6, paths, count, flags);
}
}
void libacm_cleanup();
int ib_acm_resolve_name(char *src, char *dest,
- struct ibv_path_data **paths, int *count);
+ struct ibv_path_data **paths, int *count, uint32_t flags);
int ib_acm_resolve_ip(struct sockaddr *src, struct sockaddr *dest,
- struct ibv_path_data **paths, int *count);
+ struct ibv_path_data **paths, int *count, uint32_t flags);
int ib_acm_resolve_path(struct ibv_path_record *path, uint32_t flags);
#define ib_acm_free_paths(paths) free(paths)