/*
 * Copyright (c) 2009-2014 Intel Corporation. All rights reserved.
 * Copyright (c) 2013 Mellanox Technologies LTD. All rights reserved.
 *
 * This software is available to you under the OpenIB.org BSD license
 * below:
 *
 *     Redistribution and use in source and binary forms, with or
 *     without modification, are permitted provided that the following
 *     conditions are met:
 *
 *      - Redistributions of source code must retain the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer.
 *
 *      - Redistributions in binary form must reproduce the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer in the documentation and/or other materials
 *        provided with the distribution.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AWV
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#define _GNU_SOURCE

#include <config.h>

#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <osd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/time.h>
#include <fcntl.h>
#include <dirent.h>
#include <infiniband/acm.h>
#include <infiniband/acm_prov.h>
#include <infiniband/umad.h>
#include <infiniband/verbs.h>
#include <infiniband/umad_types.h>
#include <infiniband/umad_sa.h>
#include <dlfcn.h>
#include <search.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <net/if_arp.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <rdma/rdma_netlink.h>
#include <rdma/ib_user_sa.h>
#include <poll.h>
#include <inttypes.h>
#include <getopt.h>
#include <systemd/sd-daemon.h>
#include <ccan/list.h>
#include <util/util.h>
#include "acm_mad.h"
#include "acm_util.h"

#define NL_MSG_BUF_SIZE 4096
#define ACM_PROV_NAME_SIZE 64
#define NL_CLIENT_INDEX 0

struct acmc_subnet {
	struct list_node       entry;
	__be64                 subnet_prefix;
};

struct acmc_prov {
	struct acm_provider    *prov;
	void                   *handle;
	struct list_node       entry;
	struct list_head       subnet_list;
};

struct acmc_prov_context {
	struct list_node        entry;
	atomic_t                refcnt;
	struct acm_provider     *prov;
	void                    *context;
};

struct acmc_device;

struct acmc_port {
	struct acmc_device  *dev;
	struct acm_port     port;
	struct acm_provider *prov; /* limit to 1 provider per port for now */
	void                *prov_port_context;
	int		    mad_portid;
	int		    mad_agentid;
	struct ib_mad_addr  sa_addr;
	struct list_head    sa_pending;
	struct list_head    sa_wait;
	int		    sa_credits;
	pthread_mutex_t     lock;
	struct list_head    ep_list;
	enum ibv_port_state state;
	int                 gid_cnt;
	union ibv_gid       *gid_tbl;
	uint16_t            lid;
	uint16_t            lid_mask;
	int                 sa_pkey_index;
	bool		    pending_rereg;
	uint16_t            def_acm_pkey;
};

struct acmc_device {
	struct acm_device       device;
	struct list_node        entry;
	struct list_head        prov_dev_context_list;
	int                     port_cnt;
	struct acmc_port        port[0];
};

struct acmc_addr {
	struct acm_address    addr;
	void                  *prov_addr_context;
	char		      string_buf[ACM_MAX_ADDRESS];
};

struct acmc_ep {
	struct acmc_port      *port;
	struct acm_endpoint   endpoint;
	void                  *prov_ep_context;
	/* Although the below two entries are used for dynamic allocations,
	 * they are accessed by a single thread, so no locking is required.
	 */
	int                   nmbr_ep_addrs;
	struct acmc_addr      *addr_info;
	struct list_node      entry;
};

struct acmc_client {
	pthread_mutex_t lock;   /* acquire ep lock first */
	int      sock;
	int      index;
	atomic_t refcnt;
};

union socket_addr {
	struct sockaddr     sa;
	struct sockaddr_in  sin;
	struct sockaddr_in6 sin6;
};

struct acmc_sa_req {
	struct list_node	entry;
	struct acmc_ep		*ep;
	void			(*resp_handler)(struct acm_sa_mad *);
	struct acm_sa_mad	mad;
};

struct acm_nl_path {
	struct nlattr			attr_hdr;
	struct ib_path_rec_data		rec;
};

struct acm_nl_msg {
	struct nlmsghdr				nlmsg_header;
	union {
		uint8_t				data[ACM_MSG_DATA_LENGTH];
		struct rdma_ls_resolve_header	resolve_header;
		struct nlattr			attr[0];
		struct acm_nl_path		path[0];
	};
};

static char def_prov_name[ACM_PROV_NAME_SIZE] = "ibacmp";
static LIST_HEAD(provider_list);
static struct acmc_prov *def_provider = NULL;

static LIST_HEAD(dev_list);

static int listen_socket;
static int ip_mon_socket;
static struct acmc_client client_array[FD_SETSIZE - 1];

static FILE *flog;
static pthread_mutex_t log_lock;
static __thread char log_data[ACM_MAX_ADDRESS];
static atomic_t counter[ACM_MAX_COUNTER];

static struct acmc_device *
acm_get_device_from_gid(union ibv_gid *sgid, uint8_t *port);
static struct acmc_ep *acm_find_ep(struct acmc_port *port, uint16_t pkey);
static int acm_ep_insert_addr(struct acmc_ep *ep, const char *name, uint8_t *addr,
			      uint8_t addr_type);
static void acm_event_handler(struct acmc_device *dev);
static int acm_nl_send(int sock, struct acm_msg *msg);

static struct sa_data {
	int		timeout;
	int		retries;
	int		depth;
	pthread_t	thread_id;
	struct pollfd	*fds;
	struct acmc_port **ports;
	int		nfds;
} sa = { 2000, 2, 1, 0, NULL, NULL, 0};

/*
 * Service options - may be set through ibacm_opts.cfg file.
 */
static const char *acme = IBACM_BIN_PATH "/ib_acme -A";
static const char *opts_file = ACM_CONF_DIR "/" ACM_OPTS_FILE;
static const char *addr_file = ACM_CONF_DIR "/" ACM_ADDR_FILE;
static char log_file[128] = IBACM_LOG_FILE;
static int log_level = 0;
static int umad_debug_level;
static char lock_file[128] = IBACM_PID_FILE;
static short server_port = 6125;
static int server_mode = IBACM_SERVER_MODE_DEFAULT;
static int acme_plus_kernel_only = IBACM_ACME_PLUS_KERNEL_ONLY_DEFAULT;
static int support_ips_in_addr_cfg = 0;
static char prov_lib_path[256] = IBACM_LIB_PATH;

void acm_write(int level, const char *format, ...)
{
	va_list args;
	struct timeval tv;
	struct tm tmtime;
	char buffer[20];

	if (level > log_level)
		return;

	gettimeofday(&tv, NULL);
	localtime_r(&tv.tv_sec, &tmtime);
	strftime(buffer, 20, "%Y-%m-%dT%H:%M:%S", &tmtime);
	va_start(args, format);
	pthread_mutex_lock(&log_lock);
	fprintf(flog, "%s.%03u: ", buffer, (unsigned) (tv.tv_usec / 1000));
	vfprintf(flog, format, args);
	fflush(flog);
	pthread_mutex_unlock(&log_lock);
	va_end(args);
}

void acm_format_name(int level, char *name, size_t name_size,
		     uint8_t addr_type, const uint8_t *addr, size_t addr_size)
{
	struct ibv_path_record *path;

	if (level > log_level)
		return;

	switch (addr_type) {
	case ACM_EP_INFO_NAME:
		memcpy(name, addr, addr_size);
		break;
	case ACM_EP_INFO_ADDRESS_IP:
		inet_ntop(AF_INET, addr, name, name_size);
		break;
	case ACM_EP_INFO_ADDRESS_IP6:
	case ACM_ADDRESS_GID:
		inet_ntop(AF_INET6, addr, name, name_size);
		break;
	case ACM_EP_INFO_PATH:
		path = (struct ibv_path_record *) addr;
		if (path->dlid) {
			snprintf(name, name_size, "SLID(%u) DLID(%u)",
				be16toh(path->slid), be16toh(path->dlid));
		} else {
			acm_format_name(level, name, name_size, ACM_ADDRESS_GID,
					path->dgid.raw, sizeof path->dgid);
		}
		break;
	case ACM_ADDRESS_LID:
		snprintf(name, name_size, "LID(%u)", be16toh(*((__be16 *) addr)));
		break;
	default:
		strcpy(name, "Unknown");
		break;
	}
}

int ib_any_gid(union ibv_gid *gid)
{
	return ((gid->global.subnet_prefix | gid->global.interface_id) == 0);
}

const char *acm_get_opts_file(void)
{
	return opts_file;
}

void acm_increment_counter(int type)
{
	if (type >= 0 && type < ACM_MAX_COUNTER)
		atomic_inc(&counter[type]);
}

static struct acmc_prov_context *
acm_alloc_prov_context(struct acm_provider *prov)
{
	struct acmc_prov_context *ctx;

	ctx = calloc(1, sizeof(*ctx));
	if (!ctx) {
		acm_log(0, "Error: failed to allocate prov context\n");
		return NULL;
	}
	atomic_set(&ctx->refcnt, 1);
	ctx->prov = prov;
	return ctx;
}

static struct acmc_prov_context *
acm_get_prov_context(struct list_head *list, struct acm_provider *prov)
{
	struct acmc_prov_context *ctx;

	list_for_each(list, ctx, entry) {
		if (ctx->prov == prov) {
			return ctx;
		}
	}

	return NULL;
}

static struct acmc_prov_context *
acm_acquire_prov_context(struct list_head *list, struct acm_provider *prov)
{
	struct acmc_prov_context *ctx;

	ctx = acm_get_prov_context(list, prov);
	if (!ctx) {
		ctx = acm_alloc_prov_context(prov);
		if (!ctx) {
			acm_log(0, "Error -- failed to allocate provider context\n");
			return NULL;
		}
		list_add_tail(list, &ctx->entry);
	} else {
		atomic_inc(&ctx->refcnt);
	}

	return ctx;
}

static void
acm_release_prov_context(struct acmc_prov_context *ctx)
{
	if (atomic_dec(&ctx->refcnt) <= 0) {
		list_del(&ctx->entry);
		free(ctx);
	}
}

uint8_t acm_gid_index(struct acm_port *port, union ibv_gid *gid)
{
	uint8_t i;
	struct acmc_port *cport;

	cport = container_of(port, struct acmc_port, port);
	for (i = 0; i < cport->gid_cnt; i++) {
		if (!memcmp(&cport->gid_tbl[i], gid, sizeof (*gid)))
			break;
	}
	return i;
}

int acm_get_gid(struct acm_port *port, int index, union ibv_gid *gid)
{
	struct acmc_port *cport;

	cport = container_of(port, struct acmc_port, port);
	if (index >= 0 && index < cport->gid_cnt) {
		*gid = cport->gid_tbl[index];
		return 0;
	} else {
		return -1;
	}
}

static size_t acm_addr_len(uint8_t addr_type)
{
	switch (addr_type) {
	case ACM_ADDRESS_NAME:
		return ACM_MAX_ADDRESS;
	case ACM_ADDRESS_IP:
		return sizeof(struct in_addr);
	case ACM_ADDRESS_IP6:
		return sizeof(struct in6_addr);
	case ACM_ADDRESS_GID:
		return sizeof(union ibv_gid);
	case ACM_ADDRESS_LID:
		return sizeof(uint16_t);
	default:
		acm_log(2, "illegal address type %d\n", addr_type);
	}
	return 0;
}

static int acm_addr_cmp(struct acm_address *acm_addr, uint8_t *addr, uint8_t addr_type)
{
	if (acm_addr->type != addr_type)
		return -2;

	if (acm_addr->type == ACM_ADDRESS_NAME)
		return strncasecmp((char *) acm_addr->info.name,
				   (char *) addr, acm_addr_len(acm_addr->type));
	return memcmp(acm_addr->info.addr, addr, acm_addr_len(acm_addr->type));
}

static void acm_mark_addr_invalid(struct acmc_ep *ep,
				  struct acm_ep_addr_data *data)
{
	int i;

	for (i = 0; i < ep->nmbr_ep_addrs; i++) {
		if (!acm_addr_cmp(&ep->addr_info[i].addr, data->info.addr, data->type)) {
			ep->addr_info[i].addr.type = ACM_ADDRESS_INVALID;
			ep->port->prov->remove_address(ep->addr_info[i].prov_addr_context);
			break;
		}
	}
}

static struct acm_address *
acm_addr_lookup(const struct acm_endpoint *endpoint, uint8_t *addr, uint8_t addr_type)
{
	struct acmc_ep *ep;
	int i;

	ep = container_of(endpoint, struct acmc_ep, endpoint);
	for (i = 0; i < ep->nmbr_ep_addrs; i++)
		if (!acm_addr_cmp(&ep->addr_info[i].addr, addr, addr_type))
			return &ep->addr_info[i].addr;

	return NULL;
}

__be64 acm_path_comp_mask(struct ibv_path_record *path)
{
	uint32_t fl_hop;
	uint16_t qos_sl;
	__be64 comp_mask = 0;

	acm_log(2, "\n");
	if (path->service_id)
		comp_mask |= IB_COMP_MASK_PR_SERVICE_ID;
	if (!ib_any_gid(&path->dgid))
		comp_mask |= IB_COMP_MASK_PR_DGID;
	if (!ib_any_gid(&path->sgid))
		comp_mask |= IB_COMP_MASK_PR_SGID;
	if (path->dlid)
		comp_mask |= IB_COMP_MASK_PR_DLID;
	if (path->slid)
		comp_mask |= IB_COMP_MASK_PR_SLID;

	fl_hop = be32toh(path->flowlabel_hoplimit);
	if (fl_hop >> 8)
		comp_mask |= IB_COMP_MASK_PR_FLOW_LABEL;
	if (fl_hop & 0xFF)
		comp_mask |= IB_COMP_MASK_PR_HOP_LIMIT;

	if (path->tclass)
		comp_mask |= IB_COMP_MASK_PR_TCLASS;
	if (path->reversible_numpath & 0x80)
		comp_mask |= IB_COMP_MASK_PR_REVERSIBLE;
	if (path->pkey)
		comp_mask |= IB_COMP_MASK_PR_PKEY;

	qos_sl = be16toh(path->qosclass_sl);
	if (qos_sl >> 4)
		comp_mask |= IB_COMP_MASK_PR_QOS_CLASS;
	if (qos_sl & 0xF)
		comp_mask |= IB_COMP_MASK_PR_SL;

	if (path->mtu & 0xC0)
		comp_mask |= IB_COMP_MASK_PR_MTU_SELECTOR;
	if (path->mtu & 0x3F)
		comp_mask |= IB_COMP_MASK_PR_MTU;
	if (path->rate & 0xC0)
		comp_mask |= IB_COMP_MASK_PR_RATE_SELECTOR;
	if (path->rate & 0x3F)
		comp_mask |= IB_COMP_MASK_PR_RATE;
	if (path->packetlifetime & 0xC0)
		comp_mask |= IB_COMP_MASK_PR_PACKET_LIFETIME_SELECTOR;
	if (path->packetlifetime & 0x3F)
		comp_mask |= IB_COMP_MASK_PR_PACKET_LIFETIME;

	return comp_mask;
}

int acm_resolve_response(uint64_t id, struct acm_msg *msg)
{
	struct acmc_client *client = &client_array[id];
	int ret;

	acm_log(2, "client %d, status 0x%x\n", client->index, msg->hdr.status);

	if (msg->hdr.status == ACM_STATUS_ENODATA)
		atomic_inc(&counter[ACM_CNTR_NODATA]);
	else if (msg->hdr.status)
		atomic_inc(&counter[ACM_CNTR_ERROR]);

	pthread_mutex_lock(&client->lock);
	if (client->sock == -1) {
		acm_log(0, "ERROR - connection lost\n");
		ret = ACM_STATUS_ENOTCONN;
		goto release;
	}

	if (id == NL_CLIENT_INDEX)
		ret = acm_nl_send(client->sock, msg);
	else
		ret = send(client->sock, (char *) msg, msg->hdr.length, 0);

	if (ret != msg->hdr.length)
		acm_log(0, "ERROR - failed to send response\n");
	else
		ret = 0;

release:
	pthread_mutex_unlock(&client->lock);
	(void) atomic_dec(&client->refcnt);
	return ret;
}

static int
acmc_resolve_response(uint64_t id, struct acm_msg *req_msg, uint8_t status)
{
	req_msg->hdr.opcode |= ACM_OP_ACK;
	req_msg->hdr.status = status;
	if (status != ACM_STATUS_SUCCESS)
		req_msg->hdr.length = ACM_MSG_HDR_LENGTH;
	memset(req_msg->hdr.data, 0, sizeof(req_msg->hdr.data));

	return acm_resolve_response(id, req_msg);
}

int acm_query_response(uint64_t id, struct acm_msg *msg)
{
	struct acmc_client *client = &client_array[id];
	int ret;

	acm_log(2, "status 0x%x\n", msg->hdr.status);
	pthread_mutex_lock(&client->lock);
	if (client->sock == -1) {
		acm_log(0, "ERROR - connection lost\n");
		ret = ACM_STATUS_ENOTCONN;
		goto release;
	}

	ret = send(client->sock, (char *) msg, msg->hdr.length, 0);
	if (ret != msg->hdr.length)
		acm_log(0, "ERROR - failed to send response\n");
	else
		ret = 0;

release:
	pthread_mutex_unlock(&client->lock);
	(void) atomic_dec(&client->refcnt);
	return ret;
}

static int acmc_query_response(uint64_t id, struct acm_msg *msg, uint8_t status)
{
	acm_log(2, "status 0x%x\n", status);
	msg->hdr.opcode |= ACM_OP_ACK;
	msg->hdr.status = status;
	return acm_query_response(id, msg);
}

static void acm_init_server(void)
{
	FILE *f;
	int i;

	for (i = 0; i < FD_SETSIZE - 1; i++) {
		pthread_mutex_init(&client_array[i].lock, NULL);
		client_array[i].index = i;
		client_array[i].sock = -1;
		atomic_init(&client_array[i].refcnt);
	}

	if (server_mode != IBACM_SERVER_MODE_UNIX) {
		f = fopen(IBACM_IBACME_PORT_FILE, "w");
		if (f) {
			fprintf(f, "%hu\n", server_port);
			fclose(f);
		} else
			acm_log(0,
				"notice - cannot publish ibacm port number\n");

		unlink(IBACM_PORT_FILE);
		if (!acme_plus_kernel_only) {
			if (symlink(IBACM_PORT_BASE, IBACM_PORT_FILE) != 0)
				acm_log(0,
					"notice - can't create port symlink\n");
		}
	} else {
		unlink(IBACM_IBACME_PORT_FILE);
		unlink(IBACM_PORT_FILE);
	}
}

static int acm_listen(void)
{
	union {
		struct sockaddr any;
		struct sockaddr_in inet;
		struct sockaddr_un unx;
	} addr;
	mode_t saved_mask;
	int ret, saved_errno;

	acm_log(2, "\n");

	memset(&addr, 0, sizeof(addr));

	if (server_mode == IBACM_SERVER_MODE_UNIX) {
		addr.any.sa_family = AF_UNIX;
		BUILD_ASSERT(sizeof(IBACM_IBACME_SERVER_PATH) <=
			     sizeof(addr.unx.sun_path));
		strcpy(addr.unx.sun_path, IBACM_IBACME_SERVER_PATH);

		listen_socket = socket(AF_UNIX, SOCK_STREAM, 0);
		if (listen_socket < 0) {
			acm_log(0,
				"ERROR - unable to allocate unix socket\n");
			return errno;
		}

		unlink(addr.unx.sun_path);
		saved_mask = umask(0);
		ret = bind(listen_socket, &addr.any, sizeof(addr.unx));
		saved_errno = errno;
		umask(saved_mask);

		if (ret) {
			acm_log(0,
				"ERROR - unable to bind listen socket '%s'\n",
				addr.unx.sun_path);
			return saved_errno;
		}

		unlink(IBACM_SERVER_PATH);
		if (!acme_plus_kernel_only) {
			if (symlink(IBACM_SERVER_BASE,
				    IBACM_SERVER_PATH) != 0) {
				saved_errno = errno;
				acm_log(0,
					"notice - can't create symlink\n");
				return saved_errno;
			}
		}
	} else {
		unlink(IBACM_IBACME_SERVER_PATH);
		unlink(IBACM_SERVER_PATH);

		listen_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
		if (listen_socket == -1) {
			acm_log(0,
				"ERROR - unable to allocate TCP socket\n");
			return errno;
		}

		addr.any.sa_family = AF_INET;
		addr.inet.sin_port = htobe16(server_port);
		if (server_mode == IBACM_SERVER_MODE_LOOP)
			addr.inet.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
		ret = bind(listen_socket, &addr.any, sizeof(addr.inet));
		if (ret == -1) {
			acm_log(0, "ERROR - unable to bind listen socket\n");
			return errno;
		}
	}

	ret = listen(listen_socket, 0);
	if (ret == -1) {
		acm_log(0, "ERROR - unable to start listen\n");
		return errno;
	}

	acm_log(2, "listen active\n");
	return 0;
}

/* Retrieve the listening socket from systemd. */
static int acm_listen_systemd(void)
{
	int fd;

	int rc = sd_listen_fds(1);
	if (rc == -1) {
		fprintf(stderr, "sd_listen_fds failed %d\n", rc);
		return rc;
	}

	if (rc > 2) {
		fprintf(stderr,
			"sd_listen_fds returned %d fds, expected <= 2\n", rc);
		return -1;
	}

	for (fd = SD_LISTEN_FDS_START; fd != SD_LISTEN_FDS_START + rc; fd++) {
		if (sd_is_socket(fd, AF_NETLINK, SOCK_RAW, 0)) {
			/* ListenNetlink for RDMA_NL_GROUP_LS multicast
			 * messages from the kernel
			 */
			if (client_array[NL_CLIENT_INDEX].sock != -1) {
				fprintf(stderr,
					"sd_listen_fds returned more than one netlink socket\n");
				return -1;
			}
			client_array[NL_CLIENT_INDEX].sock = fd;

			/* systemd sets NONBLOCK on the netlink socket, while
			 * we want blocking send to the kernel.
			 */
			if (set_fd_nonblock(fd, false)) {
				fprintf(stderr,
					"Unable to drop O_NOBLOCK on netlink socket");
				return -1;
			}
		} else if (sd_is_socket(SD_LISTEN_FDS_START, AF_UNSPEC,
					SOCK_STREAM, 1)) {
			/* Socket for user space client communication */
			if (listen_socket != -1) {
				fprintf(stderr,
					"sd_listen_fds returned more than one listening socket\n");
				return -1;
			}
			listen_socket = fd;
		} else {
			fprintf(stderr,
				"sd_listen_fds socket is not a SOCK_STREAM/SOCK_NETLINK listening socket\n");
			return -1;
		}
	}

	return 0;
}

static void acm_disconnect_client(struct acmc_client *client)
{
	pthread_mutex_lock(&client->lock);
	shutdown(client->sock, SHUT_RDWR);
	close(client->sock);
	client->sock = -1;
	pthread_mutex_unlock(&client->lock);
	(void) atomic_dec(&client->refcnt);
}

static void acm_svr_accept(void)
{
	int s;
	int i;

	acm_log(2, "\n");
	s = accept(listen_socket, NULL, NULL);
	if (s == -1) {
		acm_log(0, "ERROR - failed to accept connection\n");
		return;
	}

	for (i = 0; i < FD_SETSIZE - 1; i++) {
		if (i == NL_CLIENT_INDEX)
			continue;
		if (!atomic_get(&client_array[i].refcnt))
			break;
	}

	if (i == FD_SETSIZE - 1) {
		acm_log(0, "ERROR - all connections busy - rejecting\n");
		close(s);
		return;
	}

	client_array[i].sock = s;
	atomic_set(&client_array[i].refcnt, 1);
	acm_log(2, "assigned client %d\n", i);
}

static int
acm_is_path_from_port(struct acmc_port *port, struct ibv_path_record *path)
{
	uint8_t i;

	if (!ib_any_gid(&path->sgid)) {
		return (acm_gid_index(&port->port, &path->sgid) <
			port->gid_cnt);
	}

	if (path->slid) {
		return (port->lid == (be16toh(path->slid) & port->lid_mask));
	}

	if (ib_any_gid(&path->dgid)) {
		return 1;
	}

	if (acm_gid_index(&port->port, &path->dgid) < port->gid_cnt) {
		return 1;
	}

	for (i = 0; i < port->gid_cnt; i++) {
		if (port->gid_tbl[i].global.subnet_prefix ==
		    path->dgid.global.subnet_prefix) {
			return 1;
		}
	}

	return 0;
}

static bool acm_same_partition(uint16_t pkey_a, uint16_t pkey_b)
{

	acm_log(2, "pkey_a: 0x%04x pkey_b: 0x%04x\n", pkey_a, pkey_b);

	return ((pkey_a | IB_PKEY_FULL_MEMBER) == (pkey_b | IB_PKEY_FULL_MEMBER));
}

static struct acmc_addr *
acm_get_port_ep_address(struct acmc_port *port, struct acm_ep_addr_data *data)
{
	struct acmc_ep *ep;
	struct acm_address *addr;
	int i;

	if (port->state != IBV_PORT_ACTIVE)
		return NULL;

	if (data->type == ACM_EP_INFO_PATH &&
	    !acm_is_path_from_port(port, &data->info.path))
		return NULL;

	list_for_each(&port->ep_list, ep, entry) {
		if ((data->type == ACM_EP_INFO_PATH) &&
		    (!data->info.path.pkey ||
		     acm_same_partition(be16toh(data->info.path.pkey), ep->endpoint.pkey))) {
			for (i = 0; i < ep->nmbr_ep_addrs; i++) {
				if (ep->addr_info[i].addr.type)
					return &ep->addr_info[i];
			}
			return NULL;
		}

		if ((addr = acm_addr_lookup(&ep->endpoint, data->info.addr,
					    (uint8_t) data->type)))
			return container_of(addr, struct acmc_addr, addr);
	}

	return NULL;
}

static struct acmc_addr *acm_get_ep_address(struct acm_ep_addr_data *data)
{
	struct acmc_device *dev;
	struct acmc_addr *addr;
	int i;

	acm_format_name(2, log_data, sizeof log_data,
			data->type, data->info.addr, sizeof data->info.addr);
	acm_log(2, "%s\n", log_data);
	list_for_each(&dev_list, dev, entry) {
		for (i = 0; i < dev->port_cnt; i++) {
			addr = acm_get_port_ep_address(&dev->port[i], data);
			if (addr)
				return addr;
		}
	}

	acm_format_name(0, log_data, sizeof log_data,
			data->type, data->info.addr, sizeof data->info.addr);
	acm_log(1, "notice - could not find %s\n", log_data);
	return NULL;
}

/* If port_num is zero, iterate through all ports, otherwise consider
 * only the specific port_num */
static struct acmc_ep *acm_get_ep(int index, uint8_t port_num)
{
	struct acmc_device *dev;
	struct acmc_ep *ep;
	int i, inx = 0;

	acm_log(2, "ep index %d\n", index);
	list_for_each(&dev_list, dev, entry) {
		for (i = 0; i < dev->port_cnt; i++) {
			if (port_num && port_num != (i + 1))
				continue;
			if (dev->port[i].state != IBV_PORT_ACTIVE)
				continue;
			list_for_each(&dev->port[i].ep_list, ep, entry) {
				if (index == inx)
					return ep;
				++inx;
			}
		}
	}

	acm_log(1, "notice - could not find ep %d\n", index);
	return NULL;
}

static int
acm_svr_query_path(struct acmc_client *client, struct acm_msg *msg)
{
	struct acmc_addr *addr;
	struct acmc_ep *ep;

	acm_log(2, "client %d\n", client->index);
	if (msg->hdr.length != ACM_MSG_HDR_LENGTH + ACM_MSG_EP_LENGTH) {
		acm_log(0, "ERROR - invalid length: 0x%x\n", msg->hdr.length);
		return acmc_query_response(client->index, msg, ACM_STATUS_EINVAL);
	}

	addr = acm_get_ep_address(&msg->resolve_data[0]);
	if (!addr) {
		acm_log(1, "notice - could not find local end point address\n");
		return acmc_query_response(client->index, msg, ACM_STATUS_ESRCADDR);
	}

	ep = container_of(addr->addr.endpoint, struct acmc_ep, endpoint);
	return ep->port->prov->query(addr->prov_addr_context, msg, client->index);
}

static int acm_svr_select_src(struct acm_ep_addr_data *src, struct acm_ep_addr_data *dst)
{
	union socket_addr addr;
	socklen_t len;
	int ret;
	int s;

	acm_log(2, "selecting source address\n");
	memset(&addr, 0, sizeof addr);
	switch (dst->type) {
	case ACM_EP_INFO_ADDRESS_IP:
		addr.sin.sin_family = AF_INET;
		memcpy(&addr.sin.sin_addr, dst->info.addr, 4);
		len = sizeof(struct sockaddr_in);
		break;
	case ACM_EP_INFO_ADDRESS_IP6:
		addr.sin6.sin6_family = AF_INET6;
		memcpy(&addr.sin6.sin6_addr, dst->info.addr, 16);
		len = sizeof(struct sockaddr_in6);
		break;
	default:
		acm_log(1, "notice - bad destination type, cannot lookup source\n");
		return ACM_STATUS_EDESTTYPE;
	}

	s = socket(addr.sa.sa_family, SOCK_DGRAM, IPPROTO_UDP);
	if (s == -1) {
		acm_log(0, "ERROR - unable to allocate socket\n");
		return errno;
	}

	ret = connect(s, &addr.sa, len);
	if (ret) {
		acm_log(0, "ERROR - unable to connect socket\n");
		ret = errno;
		goto out;
	}

	ret = getsockname(s, &addr.sa, &len);
	if (ret) {
		acm_log(0, "ERROR - failed to get socket address\n");
		ret = errno;
		goto out;
	}

	src->type = dst->type;
	src->flags = ACM_EP_FLAG_SOURCE;
	if (dst->type == ACM_EP_INFO_ADDRESS_IP) {
		memcpy(&src->info.addr, &addr.sin.sin_addr, 4);
	} else {
		memcpy(&src->info.addr, &addr.sin6.sin6_addr, 16);
	}
out:
	close(s);
	return ret;
}

/*
 * Verify the resolve message from the client and return
 * references to the source and destination addresses.
 * The message buffer contains extra address data buffers.  If a
 * source address is not given, reference an empty address buffer,
 * and we'll resolve a source address later.  Record the location of
 * the source and destination addresses in the message header data
 * to avoid further searches.
 */
static uint8_t acm_svr_verify_resolve(struct acm_msg *msg)
{
	int i, cnt, have_dst = 0;

	if (msg->hdr.length < ACM_MSG_HDR_LENGTH) {
		acm_log(0, "ERROR - invalid msg hdr length %d\n", msg->hdr.length);
		return ACM_STATUS_EINVAL;
	}

	msg->hdr.src_out = 1;
	cnt = (msg->hdr.length - ACM_MSG_HDR_LENGTH) / ACM_MSG_EP_LENGTH;
	for (i = 0; i < cnt; i++) {
		if (msg->resolve_data[i].flags & ACM_EP_FLAG_SOURCE) {
			if (!msg->hdr.src_out) {
				acm_log(0, "ERROR - multiple sources specified\n");
				return ACM_STATUS_ESRCADDR;
			}
			if (!msg->resolve_data[i].type ||
			    (msg->resolve_data[i].type >= ACM_ADDRESS_RESERVED)) {
				acm_log(0, "ERROR - unsupported source address type\n");
				return ACM_STATUS_ESRCTYPE;
			}
			msg->hdr.src_out = 0;
			msg->hdr.src_index = i;
		}
		if (msg->resolve_data[i].flags & ACM_EP_FLAG_DEST) {
			if (have_dst) {
				acm_log(0, "ERROR - multiple destinations specified\n");
				return ACM_STATUS_EDESTADDR;
			}
			if (!msg->resolve_data[i].type ||
			    (msg->resolve_data[i].type >= ACM_ADDRESS_RESERVED)) {
				acm_log(0, "ERROR - unsupported destination address type\n");
				return ACM_STATUS_EDESTTYPE;
			}
			have_dst = 1;
			msg->hdr.dst_index = i;
		}
	}

	if (!have_dst) {
		acm_log(0, "ERROR - destination address required\n");
		return ACM_STATUS_EDESTTYPE;
	}

	if (msg->hdr.src_out) {
		msg->hdr.src_index = i;
		memset(&msg->resolve_data[i], 0, sizeof(struct acm_ep_addr_data));
	}
	return ACM_STATUS_SUCCESS;
}

static int
acm_svr_resolve_dest(struct acmc_client *client, struct acm_msg *msg)
{
	struct acmc_addr *addr;
	struct acmc_ep *ep;
	struct acm_ep_addr_data *saddr, *daddr;
	uint8_t status;

	acm_log(2, "client %d\n", client->index);
	status = acm_svr_verify_resolve(msg);
	if (status) {
		acm_log(0, "notice - misformatted or unsupported request\n");
		return acmc_resolve_response(client->index, msg, status);
	}

	saddr = &msg->resolve_data[msg->hdr.src_index];
	daddr = &msg->resolve_data[msg->hdr.dst_index];
	if (msg->hdr.src_out) {
		status = acm_svr_select_src(saddr, daddr);
		if (status) {
			acm_log(0, "notice - unable to select suitable source address\n");
			return acmc_resolve_response(client->index, msg, status);
		}
	}

	acm_format_name(2, log_data, sizeof log_data,
			saddr->type, saddr->info.addr, sizeof saddr->info.addr);
	acm_log(2, "src  %s\n", log_data);
	addr = acm_get_ep_address(saddr);
	if (!addr) {
		acm_log(0, "notice - unknown local end point address\n");
		return acmc_resolve_response(client->index, msg, ACM_STATUS_ESRCADDR);
	}

	ep = container_of(addr->addr.endpoint, struct acmc_ep, endpoint);
	return ep->port->prov->resolve(addr->prov_addr_context, msg, client->index);
}

/*
 * The message buffer contains extra address data buffers.  We extract the
 * destination address from the path record into an extra buffer, so we can
 * lookup the destination by either LID or GID.
 */
static int
acm_svr_resolve_path(struct acmc_client *client, struct acm_msg *msg)
{
	struct acmc_addr *addr;
	struct acmc_ep *ep;
	struct ibv_path_record *path;

	acm_log(2, "client %d\n", client->index);
	if (msg->hdr.length < (ACM_MSG_HDR_LENGTH + ACM_MSG_EP_LENGTH)) {
		acm_log(0, "notice - invalid msg hdr length %d\n", msg->hdr.length);
		return acmc_resolve_response(client->index, msg, ACM_STATUS_EINVAL);
	}

	path = &msg->resolve_data[0].info.path;
	if (!path->dlid && ib_any_gid(&path->dgid)) {
		acm_log(0, "notice - no destination specified\n");
		return acmc_resolve_response(client->index, msg,
					     ACM_STATUS_EDESTADDR);
	}

	acm_format_name(2, log_data, sizeof log_data, ACM_EP_INFO_PATH,
		msg->resolve_data[0].info.addr, sizeof *path);
	acm_log(2, "path %s\n", log_data);
	addr = acm_get_ep_address(&msg->resolve_data[0]);
	if (!addr) {
		acm_log(0, "notice - unknown local end point address\n");
		return acmc_resolve_response(client->index, msg,
					     ACM_STATUS_ESRCADDR);
	}

	ep = container_of(addr->addr.endpoint, struct acmc_ep, endpoint);
	return ep->port->prov->resolve(addr->prov_addr_context, msg,
				       client->index);
}

static int acm_svr_resolve(struct acmc_client *client, struct acm_msg *msg)
{
	(void) atomic_inc(&client->refcnt);

	if (msg->resolve_data[0].type == ACM_EP_INFO_PATH) {
		if (msg->resolve_data[0].flags & ACM_FLAGS_QUERY_SA) {
			return acm_svr_query_path(client, msg);
		} else {
			return acm_svr_resolve_path(client, msg);
		}
	} else {
		return acm_svr_resolve_dest(client, msg);
	}
}

static int acm_svr_perf_query(struct acmc_client *client, struct acm_msg *msg)
{
	int ret, i;
	uint16_t len;
	struct acmc_addr *addr;
	struct acmc_ep *ep = NULL;
	int index;

	acm_log(2, "client %d\n", client->index);
	index = msg->hdr.src_index;
	msg->hdr.opcode |= ACM_OP_ACK;
	msg->hdr.status = ACM_STATUS_SUCCESS;
	msg->hdr.dst_index = 0;

	if ((be16toh(msg->hdr.length) < (ACM_MSG_HDR_LENGTH + ACM_MSG_EP_LENGTH)
	    && index < 1) ||
	    ((be16toh(msg->hdr.length) >= (ACM_MSG_HDR_LENGTH + ACM_MSG_EP_LENGTH)
	    && !(msg->resolve_data[0].flags & ACM_EP_FLAG_SOURCE)))) {
		for (i = 0; i < ACM_MAX_COUNTER; i++)
			msg->perf_data[i] = htobe64((uint64_t) atomic_get(&counter[i]));

		msg->hdr.src_out = ACM_MAX_COUNTER;
		len = ACM_MSG_HDR_LENGTH + (ACM_MAX_COUNTER * sizeof(uint64_t));
	} else {
		if (index >= 1) {
			ep = acm_get_ep(index - 1, msg->hdr.src_index);
		} else {
			addr = acm_get_ep_address(&msg->resolve_data[0]);
			if (addr)
				ep = container_of(addr->addr.endpoint,
						  struct acmc_ep, endpoint);
		}

		if (ep) {
			ep->port->prov->query_perf(ep->prov_ep_context,
						   msg->perf_data, &msg->hdr.src_out);
			len = ACM_MSG_HDR_LENGTH + (msg->hdr.src_out * sizeof(uint64_t));
		} else {
			msg->hdr.status = ACM_STATUS_ESRCADDR;
			len = ACM_MSG_HDR_LENGTH;
		}
	}
	msg->hdr.length = htobe16(len);

	ret = send(client->sock, (char *) msg, len, 0);
	if (ret != len)
		acm_log(0, "ERROR - failed to send response\n");
	else
		ret = 0;

	return ret;
}

static int may_be_realloc(struct acm_msg **msg_ptr,
			  int len,
			  int cnt,
			  int *cur_msg_siz_ptr,
			  int max_msg_siz)
{

	/* Check if a new address exceeds the protocol constrained max size */
	if (len + (cnt + 1) * ACM_MAX_ADDRESS > max_msg_siz) {
		acm_log(0, "ERROR - unable to amend more addresses to acm_msg due to protocol constraints\n");
			return ENOMEM;
	}

	/* Check if a new address exceeds current size of msg */
	if (len + (cnt + 1) * ACM_MAX_ADDRESS > *cur_msg_siz_ptr) {
		const size_t chunk_size = 16 * ACM_MAX_ADDRESS;
		struct acm_msg *new_msg = realloc(*msg_ptr, *cur_msg_siz_ptr + chunk_size);

		if (!new_msg) {
			acm_log(0, "ERROR - failed to allocate longer acm_msg\n");
			return ENOMEM;
		}

		*msg_ptr = new_msg;
		*cur_msg_siz_ptr += chunk_size;
	}

	return 0;
}

static int acm_svr_ep_query(struct acmc_client *client, struct acm_msg **_msg)
{
	int sts;
	int ret, i;
	uint16_t len;
	struct acmc_ep *ep;
	int index, cnt = 0;
	struct acm_msg *msg = *_msg;
	int cur_msg_siz = sizeof(*msg);
	int max_msg_siz = USHRT_MAX;

	acm_log(2, "client %d\n", client->index);
	index = msg->hdr.src_out;
	ep = acm_get_ep(index - 1, msg->hdr.src_index);
	if (ep) {
		msg->hdr.status = ACM_STATUS_SUCCESS;
		msg->ep_data.dev_guid = ep->port->dev->device.dev_guid;
		msg->ep_data.port_num = ep->port->port.port_num;
		msg->ep_data.phys_port_cnt = ep->port->dev->port_cnt;
		msg->ep_data.pkey = htobe16(ep->endpoint.pkey);
		strncpy((char *)msg->ep_data.prov_name, ep->port->prov->name,
			ACM_MAX_PROV_NAME - 1);
		msg->ep_data.prov_name[ACM_MAX_PROV_NAME - 1] = '\0';
		len = ACM_MSG_HDR_LENGTH + sizeof(struct acm_ep_config_data);
		for (i = 0; i < ep->nmbr_ep_addrs; i++) {
			if (ep->addr_info[i].addr.type != ACM_ADDRESS_INVALID) {
				sts = may_be_realloc(_msg, len, cnt, &cur_msg_siz, max_msg_siz);
				msg = *_msg;
				if (sts)
					break;
				memcpy(msg->ep_data.addrs[cnt++].name,
				       ep->addr_info[i].string_buf,
				       ACM_MAX_ADDRESS);
			}
		}
		msg->ep_data.addr_cnt = htobe16(cnt);
		len += cnt * ACM_MAX_ADDRESS;
	} else {
		msg->hdr.status = ACM_STATUS_EINVAL;
		len = ACM_MSG_HDR_LENGTH;
	}
	msg->hdr.opcode |= ACM_OP_ACK;
	msg->hdr.src_index = 0;
	msg->hdr.dst_index = 0;
	msg->hdr.length = htobe16(len);

	ret = send(client->sock, (char *) msg, len, 0);
	if (ret != len)
		acm_log(0, "ERROR - failed to send response\n");
	else
		ret = 0;

	return ret;
}

static int acm_msg_length(struct acm_msg *msg)
{
	return (msg->hdr.opcode == ACM_OP_RESOLVE) ?
		msg->hdr.length : be16toh(msg->hdr.length);
}

static void acm_svr_receive(struct acmc_client *client)
{
	struct acm_msg *msg = malloc(sizeof(*msg));
	int ret;

	if (!msg) {
		acm_log(0, "ERROR - Unable to alloc acm_msg\n");
		ret = ENOMEM;
		goto out;
	}

	acm_log(2, "client %d\n", client->index);
	ret = recv(client->sock, (char *)msg, sizeof(*msg), 0);
	if (ret <= 0 || ret != acm_msg_length(msg)) {
		acm_log(2, "client disconnected\n");
		ret = ACM_STATUS_ENOTCONN;
		goto out;
	}

	if (msg->hdr.version != ACM_VERSION) {
		acm_log(0, "ERROR - unsupported version %d\n", msg->hdr.version);
		goto out;
	}

	switch (msg->hdr.opcode & ACM_OP_MASK) {
	case ACM_OP_RESOLVE:
		atomic_inc(&counter[ACM_CNTR_RESOLVE]);
		ret = acm_svr_resolve(client, msg);
		break;
	case ACM_OP_PERF_QUERY:
		ret = acm_svr_perf_query(client, msg);
		break;
	case ACM_OP_EP_QUERY:
		ret = acm_svr_ep_query(client, &msg);
		break;
	default:
		acm_log(0, "ERROR - unknown opcode 0x%x\n", msg->hdr.opcode);
		break;
	}

out:
	free(msg);
	if (ret)
		acm_disconnect_client(client);
}

static int acm_nl_to_addr_data(struct acm_ep_addr_data *ad,
				  int af_family, uint8_t *addr, size_t addr_len)
{
	if (addr_len > ACM_MAX_ADDRESS)
		return EINVAL;

	/* find the ep associated with this address "if any" */
	switch (af_family) {
	case AF_INET:
		ad->type = ACM_ADDRESS_IP;
		break;
	case AF_INET6:
		ad->type = ACM_ADDRESS_IP6;
		break;
	default:
		return EINVAL;
	}
	memcpy(&ad->info.addr, addr, addr_len);
	return 0;
}

static void acm_add_ep_ip(char *ifname, struct acm_ep_addr_data *data, char *ip_str)
{
	struct acmc_ep *ep;
	struct acmc_device *dev;
	uint8_t port_num;
	uint16_t pkey;
	union ibv_gid sgid;
	struct acmc_addr *addr;

	addr = acm_get_ep_address(data);
	if (addr) {
		acm_log(1, "Address '%s' already available\n", ip_str);
		return;
	}

	if (acm_if_get_sgid(ifname, &sgid))
		return;

	dev = acm_get_device_from_gid(&sgid, &port_num);
	if (!dev)
		return;

	if (acm_if_get_pkey(ifname, &pkey))
		return;

	acm_log(0, " %s\n", ip_str);

	ep = acm_find_ep(&dev->port[port_num - 1], pkey);
	if (ep) {
		if (acm_ep_insert_addr(ep, ip_str, data->info.addr,
				       data->type))
			acm_log(0, "Failed to add '%s' to EP\n", ip_str);
	} else {
		acm_log(0, "Failed to add '%s' no EP for pkey\n", ip_str);
	}
}

static void acm_rm_ep_ip(struct acm_ep_addr_data *data)
{
	struct acmc_ep *ep;
	struct acmc_addr *addr;

	addr = acm_get_ep_address(data);
	if (addr) {
		ep = container_of(addr->addr.endpoint, struct acmc_ep, endpoint);
		acm_format_name(0, log_data, sizeof log_data,
				data->type, data->info.addr, sizeof data->info.addr);
		acm_log(0, " %s\n", log_data);
		acm_mark_addr_invalid(ep, data);
	}
}

static int acm_ipnl_create(void)
{
	struct sockaddr_nl addr;

	if ((ip_mon_socket = socket(PF_NETLINK, SOCK_RAW | SOCK_NONBLOCK, NETLINK_ROUTE)) == -1) {
		acm_log(0, "Failed to open NETLINK_ROUTE socket");
		return EIO;
	}

	memset(&addr, 0, sizeof(addr));
	addr.nl_family = AF_NETLINK;
	addr.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR;

	if (bind(ip_mon_socket, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
		acm_log(0, "Failed to bind NETLINK_ROUTE socket");
		return EIO;
	}

	return 0;
}

static void acm_ip_iter_cb(char *ifname, union ibv_gid *gid, uint16_t pkey,
		uint8_t addr_type, uint8_t *addr,
		char *ip_str, void *ctx)
{
	int ret = EINVAL;
	struct acmc_device *dev;
	struct acmc_ep *ep;
	uint8_t port_num;
	char gid_str[INET6_ADDRSTRLEN];

	dev = acm_get_device_from_gid(gid, &port_num);
	if (dev) {
		ep = acm_find_ep(&dev->port[port_num - 1], pkey);
		if (ep)
			ret = acm_ep_insert_addr(ep, ip_str, addr, addr_type);
	}

	if (ret) {
		inet_ntop(AF_INET6, gid->raw, gid_str, sizeof(gid_str));
		acm_log(0, "Failed to add '%s' (gid %s; pkey 0x%x)\n",
			ip_str, gid_str, pkey);
	}
}

/* Netlink updates have indicated a failure which means we are no longer in
 * sync.  This should be a rare condition so we handle this with a "big
 * hammer" by clearing and re-reading all the system IP's.
 */
static int resync_system_ips(void)
{
	struct acmc_device *dev;
	struct acmc_port *port;
	struct acmc_ep *ep;
	int i, cnt;

	acm_log(0, "Resyncing all IP's\n");

	/* mark all IP's invalid */
	list_for_each(&dev_list, dev, entry) {
		for (cnt = 0; cnt < dev->port_cnt; cnt++) {
			port = &dev->port[cnt];

			list_for_each(&port->ep_list, ep, entry) {
				for (i = 0; i < ep->nmbr_ep_addrs; i++) {
					if (ep->addr_info[i].addr.type == ACM_ADDRESS_IP ||
					    ep->addr_info[i].addr.type == ACM_ADDRESS_IP6)
						ep->addr_info[i].addr.type = ACM_ADDRESS_INVALID;
				}
			}
		}
	}

	return acm_if_iter_sys(acm_ip_iter_cb, NULL);
}

static void acm_ipnl_handler(void)
{
	int len;
	char buffer[NL_MSG_BUF_SIZE];
	struct nlmsghdr *nlh;
	char ifname[IFNAMSIZ];
	char ip_str[INET6_ADDRSTRLEN];
	struct acm_ep_addr_data ad;

	while ((len = recv(ip_mon_socket, buffer, NL_MSG_BUF_SIZE, 0)) > 0) {
		nlh = (struct nlmsghdr *)buffer;
		while ((NLMSG_OK(nlh, len)) && (nlh->nlmsg_type != NLMSG_DONE)) {
			struct ifaddrmsg *ifa = (struct ifaddrmsg *) NLMSG_DATA(nlh);
			struct ifinfomsg *ifi = (struct ifinfomsg *) NLMSG_DATA(nlh);
			struct rtattr *rth = IFA_RTA(ifa);
			int rtl = IFA_PAYLOAD(nlh);

			switch (nlh->nlmsg_type) {
			case RTM_NEWADDR:
				if_indextoname(ifa->ifa_index, ifname);
				while (rtl && RTA_OK(rth, rtl)) {
					if (rth->rta_type == IFA_LOCAL) {
						acm_log(1, "New system address available %s : %s\n",
						        ifname, inet_ntop(ifa->ifa_family, RTA_DATA(rth),
							ip_str, sizeof(ip_str)));
						if (!acm_nl_to_addr_data(&ad, ifa->ifa_family,
								      RTA_DATA(rth),
								      RTA_PAYLOAD(rth))) {
							acm_add_ep_ip(ifname, &ad, ip_str);
						}
					}
					rth = RTA_NEXT(rth, rtl);
				}
				break;
			case RTM_DELADDR:
				if_indextoname(ifa->ifa_index, ifname);
				while (rtl && RTA_OK(rth, rtl)) {
					if (rth->rta_type == IFA_LOCAL) {
						acm_log(1, "System address removed %s : %s\n",
						        ifname, inet_ntop(ifa->ifa_family, RTA_DATA(rth),
							ip_str, sizeof(ip_str)));
						if (!acm_nl_to_addr_data(&ad, ifa->ifa_family,
								      RTA_DATA(rth),
								      RTA_PAYLOAD(rth))) {
							acm_rm_ep_ip(&ad);
						}
					}
					rth = RTA_NEXT(rth, rtl);
				}
				break;
			case RTM_NEWLINK:
				acm_log(2, "Link added : %s\n",
					if_indextoname(ifi->ifi_index, ifname));
				break;
			case RTM_DELLINK:
				acm_log(2, "Link removed : %s\n",
					if_indextoname(ifi->ifi_index, ifname));
				break;
			default:
				acm_log(2, "unknown netlink message\n");
				break;
			}
			nlh = NLMSG_NEXT(nlh, len);
		}
	}

	if (len < 0 && errno == ENOBUFS) {
		acm_log(0, "ENOBUFS returned from netlink...\n");
		resync_system_ips();
	}
}

static int acm_nl_send(int sock, struct acm_msg *msg)
{
	struct sockaddr_nl dst_addr;
	struct acm_nl_msg acmnlmsg;
	struct acm_nl_msg *orig;
	int ret;
	int datalen;

	orig = (struct acm_nl_msg *)(uintptr_t)msg->hdr.tid;

	memset(&dst_addr, 0, sizeof(dst_addr));
	dst_addr.nl_family = AF_NETLINK;
	dst_addr.nl_groups = (1 << (RDMA_NL_GROUP_LS - 1));

	memset(&acmnlmsg, 0, sizeof(acmnlmsg));
	acmnlmsg.nlmsg_header.nlmsg_len = NLMSG_HDRLEN;
	acmnlmsg.nlmsg_header.nlmsg_pid = getpid();
	acmnlmsg.nlmsg_header.nlmsg_type = orig->nlmsg_header.nlmsg_type;
	acmnlmsg.nlmsg_header.nlmsg_seq = orig->nlmsg_header.nlmsg_seq;

	if (msg->hdr.status != ACM_STATUS_SUCCESS) {
		acm_log(2, "acm status no success = %d\n", msg->hdr.status);
		acmnlmsg.nlmsg_header.nlmsg_flags |= RDMA_NL_LS_F_ERR;
	} else {
		acm_log(2, "acm status success\n");
		acmnlmsg.nlmsg_header.nlmsg_len +=
			NLA_ALIGN(sizeof(struct acm_nl_path));
		acmnlmsg.path[0].attr_hdr.nla_type = LS_NLA_TYPE_PATH_RECORD;
		acmnlmsg.path[0].attr_hdr.nla_len = sizeof(struct acm_nl_path);
		if (orig->resolve_header.path_use ==
		    LS_RESOLVE_PATH_USE_UNIDIRECTIONAL)
			acmnlmsg.path[0].rec.flags = IB_PATH_PRIMARY |
				IB_PATH_OUTBOUND;
		else
			acmnlmsg.path[0].rec.flags = IB_PATH_PRIMARY |
				IB_PATH_GMP | IB_PATH_BIDIRECTIONAL;
		memcpy(acmnlmsg.path[0].rec.path_rec,
		       &msg->resolve_data[0].info.path,
		       sizeof(struct ibv_path_record));
	}

	datalen = NLMSG_ALIGN(acmnlmsg.nlmsg_header.nlmsg_len);
	ret = sendto(sock, &acmnlmsg, datalen, 0,
		     (const struct sockaddr *)&dst_addr,
		     (socklen_t)sizeof(dst_addr));
	if (ret != datalen) {
		acm_log(0, "ERROR - sendto = %d errno = %d\n", ret, errno);
		ret = -1;
	} else {
		ret = msg->hdr.length;
	}

	free(orig);

	return ret;
}

#define NLA_LEN(nla)	((nla)->nla_len - NLA_HDRLEN)
#define NLA_DATA(nla)	((char *)(nla) + NLA_HDRLEN)

static int acm_nl_parse_path_attr(struct nlattr *attr,
				   struct acm_ep_addr_data *data)
{
	struct ibv_path_record *path;
	uint64_t  *sid;
	struct rdma_nla_ls_gid *gid;
	uint8_t *tcl;
	uint16_t *pkey;
	uint16_t *qos;
	uint16_t val;
	int ret = 0;

#define IBV_PATH_RECORD_QOS_MASK 0xfff0

	path = &data->info.path;
	switch (attr->nla_type & RDMA_NLA_TYPE_MASK) {
	case LS_NLA_TYPE_SERVICE_ID:
		sid = (uint64_t *) NLA_DATA(attr);
		if (NLA_LEN(attr) == sizeof(*sid)) {
			acm_log(2, "service_id 0x%" PRIx64 "\n", *sid);
			path->service_id = htobe64(*sid);
		} else {
			ret = -1;
		}
		break;

	case LS_NLA_TYPE_DGID:
		gid = (struct rdma_nla_ls_gid *) NLA_DATA(attr);
		if (NLA_LEN(attr) == sizeof(gid->gid)) {
			acm_format_name(2, log_data, sizeof(log_data),
					ACM_ADDRESS_GID, gid->gid,
					sizeof(union ibv_gid));
			acm_log(2, "path dgid %s\n", log_data);
			memcpy(path->dgid.raw, gid->gid, sizeof(path->dgid));
			data->flags |= ACM_EP_FLAG_DEST;
		} else {
			ret = -1;
		}
		break;

	case LS_NLA_TYPE_SGID:
		gid = (struct rdma_nla_ls_gid *) NLA_DATA(attr);
		if (NLA_LEN(attr) == sizeof(gid->gid)) {
			acm_format_name(2, log_data, sizeof(log_data),
					ACM_ADDRESS_GID, gid->gid,
					sizeof(union ibv_gid));
			acm_log(2, "path sgid %s\n", log_data);
			memcpy(path->sgid.raw, gid->gid, sizeof(path->sgid));
			data->flags |= ACM_EP_FLAG_SOURCE;
		} else {
			ret = -1;
		}
		break;

	case LS_NLA_TYPE_TCLASS:
		tcl = (uint8_t *) NLA_DATA(attr);
		if (NLA_LEN(attr) == sizeof(*tcl)) {
			acm_log(2, "tclass 0x%x\n", *tcl);
			path->tclass = *tcl;
		} else {
			ret = -1;
		}
		break;

	case LS_NLA_TYPE_PKEY:
		pkey = (uint16_t *) NLA_DATA(attr);
		if (NLA_LEN(attr) == sizeof(*pkey)) {
			acm_log(2, "pkey 0x%x\n", *pkey);
			path->pkey = htobe16(*pkey);
		} else {
			ret = -1;
		}
		break;

	case LS_NLA_TYPE_QOS_CLASS:
		qos = (uint16_t *) NLA_DATA(attr);
		if (NLA_LEN(attr) == sizeof(*qos)) {
			acm_log(2, "qos_class 0x%x\n", *qos);
			val = be16toh(path->qosclass_sl);
			val &= ~IBV_PATH_RECORD_QOS_MASK;
			val |= (*qos & IBV_PATH_RECORD_QOS_MASK);
			path->qosclass_sl = htobe16(val);
		} else {
			ret = -1;
		}
		break;

	default:
		acm_log(1, "WARN: unknown attr %x\n", attr->nla_type);
		/* We can not ignore a mandatory attribute */
		if (attr->nla_type & RDMA_NLA_F_MANDATORY)
			ret = -1;
		break;
	}

	return ret;
}

static void acm_nl_process_invalid_request(struct acmc_client *client,
					   struct acm_nl_msg *acmnlmsg)
{
	struct acm_msg msg;

	memset(&msg, 0, sizeof(msg));
	msg.hdr.opcode = ACM_OP_RESOLVE;
	msg.hdr.version = ACM_VERSION;
	msg.hdr.length = ACM_MSG_HDR_LENGTH;
	msg.hdr.status = ACM_STATUS_EINVAL;
	msg.hdr.tid = (uintptr_t) acmnlmsg;

	acm_nl_send(client->sock, &msg);
}

static void acm_nl_process_resolve(struct acmc_client *client,
				   struct acm_nl_msg *acmnlmsg)
{
	struct acm_msg msg;
	struct nlattr *attr;
	int payload_len;
	int resolve_hdr_len;
	int rem;
	int total_attr_len;
	int status;
	unsigned char *data;

	memset(&msg, 0, sizeof(msg));
	msg.hdr.opcode = ACM_OP_RESOLVE;
	msg.hdr.version = ACM_VERSION;
	msg.hdr.length = ACM_MSG_HDR_LENGTH + ACM_MSG_EP_LENGTH;
	msg.hdr.status = ACM_STATUS_SUCCESS;
	msg.hdr.tid = (uintptr_t) acmnlmsg;
	msg.resolve_data[0].type = ACM_EP_INFO_PATH;

	/* We support only one pathrecord */
	acm_log(2, "path use 0x%x\n", acmnlmsg->resolve_header.path_use);
	if (acmnlmsg->resolve_header.path_use ==
	    LS_RESOLVE_PATH_USE_UNIDIRECTIONAL)
		msg.resolve_data[0].info.path.reversible_numpath = 1;
	else
		msg.resolve_data[0].info.path.reversible_numpath =
			IBV_PATH_RECORD_REVERSIBLE | 1;

	data = (unsigned char *) &acmnlmsg->nlmsg_header + NLMSG_HDRLEN;
	resolve_hdr_len = NLMSG_ALIGN(sizeof(struct rdma_ls_resolve_header));
	attr = (struct nlattr *) (data + resolve_hdr_len);
	payload_len = acmnlmsg->nlmsg_header.nlmsg_len - NLMSG_HDRLEN -
		resolve_hdr_len;
	rem = payload_len;
	while (1) {
		if (rem < (int) sizeof(*attr) ||
		    attr->nla_len < sizeof(*attr) ||
		    attr->nla_len > rem)
			break;

		status = acm_nl_parse_path_attr(attr, &msg.resolve_data[0]);
		if (status) {
			acm_nl_process_invalid_request(client, acmnlmsg);
			return;
		}

		/* Next attribute */
		total_attr_len = NLA_ALIGN(attr->nla_len);
		rem -= total_attr_len;
		attr = (struct nlattr *) ((char *) attr + total_attr_len);
	}

	atomic_inc(&counter[ACM_CNTR_RESOLVE]);
	acm_svr_resolve(client, &msg);
}

static int acm_nl_is_valid_resolve_request(struct acm_nl_msg *acmnlmsg)
{
	int payload_len;

	payload_len = acmnlmsg->nlmsg_header.nlmsg_len - NLMSG_HDRLEN;
	if (payload_len < (sizeof(struct rdma_ls_resolve_header) +
			   sizeof(struct nlattr)))
		return 0;

	return 1;
}

static void acm_nl_receive(struct acmc_client *client)
{
	struct acm_nl_msg *acmnlmsg;
	int datalen = sizeof(*acmnlmsg);
	int ret;
	uint16_t client_inx, op;

	acmnlmsg = calloc(1, sizeof(*acmnlmsg));
	if (!acmnlmsg) {
		acm_log(0, "Out of memory for recving nl msg.\n");
		return;
	}
	ret = recv(client->sock, acmnlmsg, datalen, 0);
	if (!NLMSG_OK(&acmnlmsg->nlmsg_header, ret)) {
		acm_log(0, "Netlink receive error: %d.\n", ret);
		goto rcv_cleanup;
	}

	acm_log(2, "nlmsg: len %d type 0x%x flags 0x%x seq %d pid %d\n",
		acmnlmsg->nlmsg_header.nlmsg_len,
		acmnlmsg->nlmsg_header.nlmsg_type,
		acmnlmsg->nlmsg_header.nlmsg_flags,
		acmnlmsg->nlmsg_header.nlmsg_seq,
		acmnlmsg->nlmsg_header.nlmsg_pid);

	/* Currently we handle only request from the local service client */
	client_inx = RDMA_NL_GET_CLIENT(acmnlmsg->nlmsg_header.nlmsg_type);
	op = RDMA_NL_GET_OP(acmnlmsg->nlmsg_header.nlmsg_type);
	if (client_inx != RDMA_NL_LS) {
		acm_log_once(0, "ERROR - Unknown NL client ID (%d)\n", client_inx);
		goto rcv_cleanup;
	}

	switch (op) {
	case RDMA_NL_LS_OP_RESOLVE:
		if (acm_nl_is_valid_resolve_request(acmnlmsg))
			acm_nl_process_resolve(client, acmnlmsg);
		else
			acm_nl_process_invalid_request(client, acmnlmsg);
		break;
	default:
		/* Not supported*/
		acm_log_once(0, "WARN - invalid opcode %x\n", op);
		acm_nl_process_invalid_request(client, acmnlmsg);
		break;
	}

	return;
rcv_cleanup:
	free(acmnlmsg);
}

static int acm_init_nl(void)
{
	struct sockaddr_nl src_addr;
	int ret;
	int nl_rcv_socket;

	nl_rcv_socket = socket(PF_NETLINK, SOCK_RAW, NETLINK_RDMA);
	if (nl_rcv_socket == -1) {
		acm_log(0, "ERROR - unable to allocate netlink recv socket\n");
		return errno;
	}

	memset(&src_addr, 0, sizeof(src_addr));
	src_addr.nl_family = AF_NETLINK;
	src_addr.nl_pid = getpid();
	src_addr.nl_groups = (1 << (RDMA_NL_GROUP_LS - 1));

	ret = bind(nl_rcv_socket, (struct sockaddr *)&src_addr,
		   sizeof(src_addr));
	if (ret == -1) {
		acm_log(0, "ERROR - unable to bind netlink socket\n");
		close(nl_rcv_socket);
		return errno;
	}

	/* init nl client structure */
	client_array[NL_CLIENT_INDEX].sock = nl_rcv_socket;
	return 0;
}

static void acm_server(bool systemd)
{
	fd_set readfds;
	int i, n, ret;
	struct acmc_device *dev;

	acm_log(0, "started\n");
	acm_init_server();

	client_array[NL_CLIENT_INDEX].sock = -1;
	listen_socket = -1;
	if (systemd) {
		ret = acm_listen_systemd();
		if (ret) {
			acm_log(0, "ERROR - systemd server listen failed\n");
			return;
		}
	}

	if (listen_socket == -1) {
		ret = acm_listen();
		if (ret) {
			acm_log(0, "ERROR - server listen failed\n");
			return;
		}
	}

	if (client_array[NL_CLIENT_INDEX].sock == -1) {
		ret = acm_init_nl();
		if (ret)
			acm_log(1, "Warn - Netlink init failed\n");
	}

	if (systemd)
		sd_notify(0, "READY=1");

	while (1) {
		n = (int) listen_socket;
		FD_ZERO(&readfds);
		FD_SET(listen_socket, &readfds);
		n = max(n, (int) ip_mon_socket);
		FD_SET(ip_mon_socket, &readfds);

		for (i = 0; i < FD_SETSIZE - 1; i++) {
			if (client_array[i].sock != -1) {
				FD_SET(client_array[i].sock, &readfds);
				n = max(n, (int) client_array[i].sock);
			}
		}

		list_for_each(&dev_list, dev, entry) {
			FD_SET(dev->device.verbs->async_fd, &readfds);
			n = max(n, (int) dev->device.verbs->async_fd);
		}

		ret = select(n + 1, &readfds, NULL, NULL, NULL);
		if (ret == -1) {
			acm_log(0, "ERROR - server select error\n");
			continue;
		}

		if (FD_ISSET(listen_socket, &readfds))
			acm_svr_accept();

		if (FD_ISSET(ip_mon_socket, &readfds))
			acm_ipnl_handler();

		for (i = 0; i < FD_SETSIZE - 1; i++) {
			if (client_array[i].sock != -1 &&
				FD_ISSET(client_array[i].sock, &readfds)) {
				acm_log(2, "receiving from client %d\n", i);
				if (i == NL_CLIENT_INDEX)
					acm_nl_receive(&client_array[i]);
				else
					acm_svr_receive(&client_array[i]);
			}
		}

		list_for_each(&dev_list, dev, entry) {
			if (FD_ISSET(dev->device.verbs->async_fd, &readfds)) {
				acm_log(2, "handling event from %s\n",
					dev->device.verbs->device->name);
				acm_event_handler(dev);
			}
		}
	}
}

enum ibv_rate acm_get_rate(uint8_t width, uint8_t speed)
{
	switch (width) {
	case 1: /* 1x */
		switch (speed) {
		case 1: return IBV_RATE_2_5_GBPS;
		case 2: return IBV_RATE_5_GBPS;
		case 4: /* fall through */
		case 8: return IBV_RATE_10_GBPS;
		case 16: return IBV_RATE_14_GBPS;
		case 32: return IBV_RATE_25_GBPS;
		default: return IBV_RATE_MAX;
		}
	case 2: /* 4x */
		switch (speed) {
		case 1: return IBV_RATE_10_GBPS;
		case 2: return IBV_RATE_20_GBPS;
		case 4: /* fall through */
		case 8: return IBV_RATE_40_GBPS;
		case 16: return IBV_RATE_56_GBPS;
		case 32: return IBV_RATE_100_GBPS;
		default: return IBV_RATE_MAX;
		}
	case 4: /* 8x */
		switch (speed) {
		case 1: return IBV_RATE_20_GBPS;
		case 2: return IBV_RATE_40_GBPS;
		case 4: /* fall through */
		case 8: return IBV_RATE_80_GBPS;
		case 16: return IBV_RATE_112_GBPS;
		case 32: return IBV_RATE_200_GBPS;
		default: return IBV_RATE_MAX;
		}
	case 8: /* 12x */
		switch (speed) {
		case 1: return IBV_RATE_30_GBPS;
		case 2: return IBV_RATE_60_GBPS;
		case 4: /* fall through */
		case 8: return IBV_RATE_120_GBPS;
		case 16: return IBV_RATE_168_GBPS;
		case 32: return IBV_RATE_300_GBPS;
		default: return IBV_RATE_MAX;
		}
	default:
		acm_log(0, "ERROR - unknown link width 0x%x\n", width);
		return IBV_RATE_MAX;
	}
}

enum ibv_mtu acm_convert_mtu(int mtu)
{
	switch (mtu) {
	case 256:  return IBV_MTU_256;
	case 512:  return IBV_MTU_512;
	case 1024: return IBV_MTU_1024;
	case 2048: return IBV_MTU_2048;
	case 4096: return IBV_MTU_4096;
	default:   return IBV_MTU_2048;
	}
}

enum ibv_rate acm_convert_rate(int rate)
{
	switch (rate) {
	case 2:   return IBV_RATE_2_5_GBPS;
	case 5:   return IBV_RATE_5_GBPS;
	case 10:  return IBV_RATE_10_GBPS;
	case 20:  return IBV_RATE_20_GBPS;
	case 30:  return IBV_RATE_30_GBPS;
	case 40:  return IBV_RATE_40_GBPS;
	case 60:  return IBV_RATE_60_GBPS;
	case 80:  return IBV_RATE_80_GBPS;
	case 120: return IBV_RATE_120_GBPS;
	case 14:  return IBV_RATE_14_GBPS;
	case 56:  return IBV_RATE_56_GBPS;
	case 112: return IBV_RATE_112_GBPS;
	case 168: return IBV_RATE_168_GBPS;
	case 25:  return IBV_RATE_25_GBPS;
	case 100: return IBV_RATE_100_GBPS;
	case 200: return IBV_RATE_200_GBPS;
	case 300: return IBV_RATE_300_GBPS;
	default:  return IBV_RATE_10_GBPS;
	}
}

static FILE *acm_open_addr_file(void)
{
	FILE *f;

	if ((f = fopen(addr_file, "r")))
		return f;

	acm_log(0, "notice - generating %s file\n", addr_file);
	if (!(f = popen(acme, "r"))) {
		acm_log(0, "ERROR - cannot generate %s\n", addr_file);
		return NULL;
	}
	pclose(f);
	return fopen(addr_file, "r");
}

static int
__acm_ep_insert_addr(struct acmc_ep *ep, const char *name, uint8_t *addr,
		   uint8_t addr_type)
{
	int i;
	int ret;
	uint8_t tmp[ACM_MAX_ADDRESS] = {};

	memcpy(tmp, addr, acm_addr_len(addr_type));

	for (i = 0; (i < ep->nmbr_ep_addrs) &&
		     (ep->addr_info[i].addr.type != ACM_ADDRESS_INVALID); i++)
		;
	if (i == ep->nmbr_ep_addrs) {
		struct acmc_addr *new_info;
		int j;

		new_info = realloc(ep->addr_info, (i + 1) * sizeof(*ep->addr_info));
		if (!new_info) {
			ret = ENOMEM;
			goto out;
		}

		/* id_string needs to point to the reallocated string_buf */
		for (j = 0; (j < ep->nmbr_ep_addrs); j++) {
			new_info[j].addr.id_string = new_info[j].string_buf;
		}

		ep->addr_info = new_info;

		/* Added memory is not initialized */
		memset(ep->addr_info + i, 0, sizeof(*ep->addr_info));
		ep->addr_info[i].addr.endpoint = &ep->endpoint;
		ep->addr_info[i].addr.id_string = ep->addr_info[i].string_buf;
		++ep->nmbr_ep_addrs;
	}

	/* Open the provider endpoint only if at least a name or
	   address is found */
	if (!ep->prov_ep_context) {
		ret = ep->port->prov->open_endpoint(&ep->endpoint,
						    ep->port->prov_port_context,
						    &ep->prov_ep_context);
		if (ret) {
			acm_log(0, "Error: failed to open prov ep\n");
			goto out;
		}
	}
	ep->addr_info[i].addr.type = addr_type;
	if (!check_snprintf(ep->addr_info[i].string_buf,
			    sizeof(ep->addr_info[i].string_buf), "%s", name))
		return EINVAL;
	memcpy(ep->addr_info[i].addr.info.addr, tmp, ACM_MAX_ADDRESS);
	ret = ep->port->prov->add_address(&ep->addr_info[i].addr,
					  ep->prov_ep_context,
					  &ep->addr_info[i].prov_addr_context);
	if (ret) {
		acm_log(0, "Error: failed to add addr to provider\n");
		ep->addr_info[i].addr.type = ACM_ADDRESS_INVALID;
	}

out:
	return ret;
}

static int
acm_ep_insert_addr(struct acmc_ep *ep, const char *name, uint8_t *addr,
		   uint8_t addr_type)
{
	int ret = -1;

	if (!acm_addr_lookup(&ep->endpoint, addr, addr_type)) {
		ret = __acm_ep_insert_addr(ep, name, addr, addr_type);
	}

	return ret;
}

static struct acmc_device *
acm_get_device_from_gid(union ibv_gid *sgid, uint8_t *port)
{
	struct acmc_device *dev;
	int i;

	list_for_each(&dev_list, dev, entry) {
		for (*port = 1; *port <= dev->port_cnt; (*port)++) {

			for (i = 0; i < dev->port[*port - 1].gid_cnt; i++) {

				if (!memcmp(sgid->raw,
					    dev->port[*port - 1].gid_tbl[i].raw,
					    sizeof(*sgid)))
					return dev;
			}
		}
	}
	return NULL;
}

static void acm_ep_ip_iter_cb(char *ifname, union ibv_gid *gid, uint16_t pkey,
		uint8_t addr_type, uint8_t *addr,
		char *ip_str, void *ctx)
{
	uint8_t port_num;
	struct acmc_device *dev;
	struct acmc_ep *ep = ctx;

	dev = acm_get_device_from_gid(gid, &port_num);
	if (dev && ep->port->dev == dev
	    && ep->port->port.port_num == port_num &&
		/* pkey retrieved from ipoib has always full mmbr bit set */
		(ep->endpoint.pkey | IB_PKEY_FULL_MEMBER) == pkey) {
		if (!acm_ep_insert_addr(ep, ip_str, addr, addr_type)) {
			acm_log(0, "Added %s %s %d 0x%x from %s\n", ip_str,
				dev->device.verbs->device->name, port_num, ep->endpoint.pkey,
				ifname);
		}
	}
}

static int acm_get_system_ips(struct acmc_ep *ep)
{
	return acm_if_iter_sys(acm_ep_ip_iter_cb, ep);
}

static int acm_assign_ep_names(struct acmc_ep *ep)
{
	FILE *faddr;
	char *dev_name;
	char s[120];
	char dev[32], name[ACM_MAX_ADDRESS], pkey_str[8];
	uint16_t pkey;
	uint8_t addr[ACM_MAX_ADDRESS], type;
	int port;

	dev_name = ep->port->dev->device.verbs->device->name;
	acm_log(1, "device %s, port %d, pkey 0x%x\n",
		dev_name, ep->port->port.port_num, ep->endpoint.pkey);

	acm_get_system_ips(ep);

	if (!(faddr = acm_open_addr_file())) {
		acm_log(0, "ERROR - address file not found\n");
		goto out;
	}

	while (fgets(s, sizeof s, faddr)) {
		if (s[0] == '#')
			continue;

		if (sscanf(s, "%46s%31s%d%7s", name, dev, &port, pkey_str) != 4)
			continue;

		acm_log(2, "%s", s);
		if (inet_pton(AF_INET, name, addr) > 0) {
			if (!support_ips_in_addr_cfg) {
				acm_log(0, "ERROR - IP's are not configured to be read from ibacm_addr.cfg\n");
				continue;
			}
			type = ACM_ADDRESS_IP;
		} else if (inet_pton(AF_INET6, name, addr) > 0) {
			if (!support_ips_in_addr_cfg) {
				acm_log(0, "ERROR - IP's are not configured to be read from ibacm_addr.cfg\n");
				continue;
			}
			type = ACM_ADDRESS_IP6;
		} else {
			type = ACM_ADDRESS_NAME;
			strncpy((char *)addr, name, sizeof(addr));
		}

		if (strcasecmp(pkey_str, "default")) {
			if (sscanf(pkey_str, "%hx", &pkey) != 1) {
				acm_log(0, "ERROR - bad pkey format %s\n", pkey_str);
				continue;
			}
		} else {
			pkey = ep->port->def_acm_pkey;
		}

		if (!strcasecmp(dev_name, dev) &&
		    (ep->port->port.port_num == (uint8_t) port) &&
		    acm_same_partition(ep->endpoint.pkey, pkey)) {
			acm_log(1, "assigning %s\n", name);
			if (acm_ep_insert_addr(ep, name, addr, type)) {
				acm_log(1, "maximum number of names assigned to EP\n");
				break;
			}
		}
	}
	fclose(faddr);

out:
	return (!ep->nmbr_ep_addrs || ep->addr_info[0].addr.type == ACM_ADDRESS_INVALID);
}

static struct acmc_ep *acm_find_ep(struct acmc_port *port, uint16_t pkey)
{
	struct acmc_ep *ep, *res = NULL;

	acm_log(2, "pkey 0x%x\n", pkey);

	list_for_each(&port->ep_list, ep, entry) {
		if (acm_same_partition(ep->endpoint.pkey, pkey)) {
			res = ep;
			break;
		}
	}
	return res;
}

static void acm_ep_down(struct acmc_ep *ep)
{
	int i;

	acm_log(1, "%s %d pkey 0x%04x\n",
		ep->port->dev->device.verbs->device->name,
		ep->port->port.port_num, ep->endpoint.pkey);

	for (i = 0; i < ep->nmbr_ep_addrs; i++) {
		if (ep->addr_info[i].addr.type &&
		    ep->addr_info[i].prov_addr_context)
			ep->port->prov->remove_address(ep->addr_info[i].
						       prov_addr_context);
	}

	if (ep->prov_ep_context)
		ep->port->prov->close_endpoint(ep->prov_ep_context);

	free(ep);
}

static struct acmc_ep *
acm_alloc_ep(struct acmc_port *port, uint16_t pkey)
{
	struct acmc_ep *ep;

	acm_log(1, "\n");
	ep = calloc(1, sizeof *ep);
	if (!ep)
		return NULL;

	ep->port = port;
	ep->endpoint.port = &port->port;
	ep->endpoint.pkey = pkey;
	ep->addr_info = NULL;
	ep->nmbr_ep_addrs = 0;

	return ep;
}

static void acm_ep_up(struct acmc_port *port, uint16_t pkey)
{
	struct acmc_ep *ep;
	int ret;

	acm_log(1, "\n");
	if (acm_find_ep(port, pkey)) {
		acm_log(2, "endpoint for pkey 0x%x already exists\n", pkey);
		return;
	}

	acm_log(2, "creating endpoint for pkey 0x%x\n", pkey);
	ep = acm_alloc_ep(port, pkey);
	if (!ep)
		return;

	ret = acm_assign_ep_names(ep);
	if (ret) {
		acm_log(1, "unable to assign EP name for pkey 0x%x\n", pkey);
		goto ep_close;
	}

	list_add(&port->ep_list, &ep->entry);
	return;

ep_close:
	if (ep->prov_ep_context)
		port->prov->close_endpoint(ep->prov_ep_context);

	free(ep);
}

static void acm_assign_provider(struct acmc_port *port)
{
	struct acmc_prov *prov;
	struct acmc_subnet *subnet;

	acm_log(2, "port %s/%d\n", port->port.dev->verbs->device->name,
		port->port.port_num);
	list_for_each(&provider_list, prov, entry) {
		list_for_each(&prov->subnet_list, subnet, entry) {
			if (subnet->subnet_prefix ==
			    port->gid_tbl[0].global.subnet_prefix) {
				acm_log(2, "Found provider %s for port %s/%d\n",
					prov->prov->name,
					port->port.dev->verbs->device->name,
					port->port.port_num);
				port->prov = prov->prov;
				return;
			}
		}
	}

	/* If no provider is found, assign the default provider*/
	if (!port->prov) {
		acm_log(2, "No prov found, assign default prov %s to %s/%d\n",
			def_provider ? def_provider->prov->name: "NULL",
			port->port.dev->verbs->device->name,
			port->port.port_num);
		port->prov = def_provider ? def_provider->prov : NULL;
	}
}

static void acm_port_get_gid_tbl(struct acmc_port *port)
{
	union ibv_gid gid;
	int i, j, ret;

	for (i = 0;; i++) {
		ret = ibv_query_gid(port->port.dev->verbs, port->port.port_num,
				    i, &gid);
		if (ret || !gid.global.interface_id)
			break;
	}

	if (i > 0) {
		port->gid_tbl = calloc(i, sizeof(union ibv_gid));
		if (!port->gid_tbl) {
			acm_log(0, "Error: failed to allocate gid table\n");
			port->gid_cnt = 0;
			return;
		}

		for (j = 0; j < i; j++) {
			ret = ibv_query_gid(port->port.dev->verbs,
					    port->port.port_num, j,
					    &port->gid_tbl[j]);
			if (ret || !port->gid_tbl[j].global.interface_id)
				break;
			acm_log(2, "guid %d: 0x%" PRIx64 " %" PRIx64 "\n", j,
				be64toh(port->gid_tbl[j].global.subnet_prefix),
				be64toh(port->gid_tbl[j].global.interface_id));
		}
		port->gid_cnt = j;
	}
	acm_log(2, "port %d gid_cnt %d\n", port->port.port_num,
		port->gid_cnt);
}

static void acm_port_up(struct acmc_port *port)
{
	struct ibv_port_attr attr;
	uint16_t pkey;
	__be16 pkey_be;
	int i, ret;
	struct acmc_prov_context *dev_ctx;
	int index = -1;
	uint16_t first_pkey = 0;

	acm_log(1, "%s %d\n", port->dev->device.verbs->device->name,
		port->port.port_num);
	ret = ibv_query_port(port->dev->device.verbs, port->port.port_num,
			     &attr);
	if (ret) {
		acm_log(0, "ERROR - unable to get port state\n");
		return;
	}
	if (attr.state != IBV_PORT_ACTIVE) {
		acm_log(1, "port not active\n");
		return;
	}

	acm_port_get_gid_tbl(port);
	port->lid = attr.lid;
	port->lid_mask = 0xffff - ((1 << attr.lmc) - 1);
	port->sa_addr.lid = htobe16(attr.sm_lid);
	port->sa_addr.sl = attr.sm_sl;
	port->state = IBV_PORT_ACTIVE;
	acm_assign_provider(port);
	if (!port->prov) {
		acm_log(1, "no provider assigned to port\n");
		return;
	}
	dev_ctx = acm_acquire_prov_context(&port->dev->prov_dev_context_list,
					   port->prov);
	if (!dev_ctx) {
		acm_log(0, "Error -- failed to acquire dev context\n");
		return;
	}

	if (atomic_get(&dev_ctx->refcnt) == 1) {
		if (port->prov->open_device(&port->dev->device, &dev_ctx->context)) {
			acm_log(0, "Error -- failed to open the prov device\n");
			goto err1;
		}
	}

	if (port->prov->open_port(&port->port, dev_ctx->context,
				  &port->prov_port_context)) {
		acm_log(0, "Error -- failed to open the prov port\n");
		goto err1;
	}

	/* Determine the default pkey for SA access first.
	 *     Order of preference: 0xffff, 0x7fff
	 * Use the first pkey as the default pkey for parsing address file.
	 */
	for (i = 0; i < attr.pkey_tbl_len; i++) {
		ret = ibv_query_pkey(port->dev->device.verbs,
				     port->port.port_num, i, &pkey_be);
		if (ret)
			continue;
		pkey = be16toh(pkey_be);
		if (i == 0)
			first_pkey = pkey;
		if (pkey == 0xffff) {
			index = i;
			break;
		}
		else if (pkey == 0x7fff) {
			index = i;
		}
	}
	port->sa_pkey_index = index < 0 ? 0 : index;
	port->def_acm_pkey = first_pkey;

	for (i = 0; i < attr.pkey_tbl_len; i++) {
		ret = ibv_query_pkey(port->dev->device.verbs,
				     port->port.port_num, i, &pkey_be);
		if (ret)
			continue;
		pkey = be16toh(pkey_be);
		if (!(pkey & 0x7fff))
			continue;

		acm_ep_up(port, pkey);
	}
	return;
err1:
	acm_release_prov_context(dev_ctx);
}

static void acm_shutdown_port(struct acmc_port *port)
{
	struct acmc_ep *ep;
	struct acmc_prov_context *dev_ctx;

	while ((ep = list_pop(&port->ep_list, struct acmc_ep, entry)))
		acm_ep_down(ep);

	if (port->prov_port_context) {
		port->prov->close_port(port->prov_port_context);
		port->prov_port_context = NULL;
		dev_ctx = acm_get_prov_context(&port->dev->prov_dev_context_list,
					       port->prov);
		if (dev_ctx) {
			if (atomic_get(&dev_ctx->refcnt) == 1)
				port->prov->close_device(dev_ctx->context);
			acm_release_prov_context(dev_ctx);
		}
	}
	port->prov = NULL;
	if (port->gid_tbl) {
		free(port->gid_tbl);
		port->gid_tbl = NULL;
	}
	port->gid_cnt = 0;
}

static void acm_port_down(struct acmc_port *port)
{
	struct ibv_port_attr attr;
	int ret;

	acm_log(1, "%s %d\n", port->port.dev->verbs->device->name, port->port.port_num);
	ret = ibv_query_port(port->port.dev->verbs, port->port.port_num, &attr);
	if (!ret && attr.state == IBV_PORT_ACTIVE) {
		acm_log(1, "port active\n");
		return;
	}

	port->state = attr.state;
	acm_shutdown_port(port);

	acm_log(1, "%s %d is down\n", port->dev->device.verbs->device->name,
		port->port.port_num);
}

static void acm_port_change(struct acmc_port *port)
{
	struct ibv_port_attr attr;
	int ret;

	acm_log(1, "%s %d\n", port->port.dev->verbs->device->name, port->port.port_num);
	ret = ibv_query_port(port->port.dev->verbs, port->port.port_num, &attr);
	if (ret || attr.state != IBV_PORT_ACTIVE) {
		acm_log(1, "port not active: don't care\n");
		return;
	}

	port->state = attr.state;
	acm_shutdown_port(port);
	acm_port_up(port);
}

static void acm_event_handler(struct acmc_device *dev)
{
	struct ibv_async_event event;
	int i, ret;

	ret = ibv_get_async_event(dev->device.verbs, &event);
	if (ret)
		return;

	acm_log(2, "processing async event %s for %s\n",
		ibv_event_type_str(event.event_type),
		dev->device.verbs->device->name);
	i = event.element.port_num - 1;

	switch (event.event_type) {
	case IBV_EVENT_PORT_ACTIVE:
		if (dev->port[i].state != IBV_PORT_ACTIVE)
			acm_port_up(&dev->port[i]);
		if (dev->port[i].pending_rereg && dev->port[i].prov_port_context) {
			dev->port[i].prov->handle_event(dev->port[i].prov_port_context,
							IBV_EVENT_CLIENT_REREGISTER);
			dev->port[i].pending_rereg = false;
			acm_log(1, "%s %d delayed reregistration\n",
				dev->device.verbs->device->name, i + 1);
		}

		break;
	case IBV_EVENT_PORT_ERR:
		if (dev->port[i].state == IBV_PORT_ACTIVE)
			acm_port_down(&dev->port[i]);
		break;
	case IBV_EVENT_CLIENT_REREGISTER:
		if ((dev->port[i].state == IBV_PORT_ACTIVE) &&
		    dev->port[i].prov_port_context) {
			dev->port[i].prov->handle_event(dev->port[i].prov_port_context,
							event.event_type);
			acm_log(1, "%s %d has reregistered\n",
				dev->device.verbs->device->name, i + 1);
		} else {
			acm_log(2, "%s %d rereg on inactive port, postpone handling\n",
				dev->device.verbs->device->name, i + 1);
			dev->port[i].pending_rereg = true;
		}

		break;
	case IBV_EVENT_LID_CHANGE:
	case IBV_EVENT_GID_CHANGE:
	case IBV_EVENT_PKEY_CHANGE:
		acm_port_change(&dev->port[i]);
		break;
	default:
		break;
	}

	ibv_ack_async_event(&event);
}

static void acm_activate_devices(void)
{
	struct acmc_device *dev;
	int i;

	acm_log(1, "\n");
	list_for_each(&dev_list, dev, entry) {
		for (i = 0; i < dev->port_cnt; i++) {
			acm_port_up(&dev->port[i]);
		}
	}
}

static void
acm_open_port(struct acmc_port *port, struct acmc_device *dev, uint8_t port_num)
{
	acm_log(1, "%s %d\n", dev->device.verbs->device->name, port_num);
	port->dev = dev;
	port->port.dev = &dev->device;
	port->port.port_num = port_num;
	pthread_mutex_init(&port->lock, NULL);
	list_head_init(&port->ep_list);
	list_head_init(&port->sa_pending);
	list_head_init(&port->sa_wait);
	port->sa_credits = sa.depth;
	port->sa_addr.qpn = htobe32(1);
	port->sa_addr.qkey = htobe32(ACM_QKEY);

	port->mad_portid = umad_open_port(dev->device.verbs->device->name, port_num);
	if (port->mad_portid < 0)
		acm_log(0, "ERROR - unable to open MAD port\n");

	port->mad_agentid = umad_register(port->mad_portid,
					  IB_MGMT_CLASS_SA, 1, 1, NULL);
	if (port->mad_agentid < 0) {
		umad_close_port(port->mad_portid);
		acm_log(0, "ERROR - unable to register MAD client\n");
	}

	port->prov = NULL;
	port->state = IBV_PORT_DOWN;
}

static void acm_open_dev(struct ibv_device *ibdev)
{
	struct acmc_device *dev;
	struct ibv_device_attr attr;
	struct ibv_port_attr port_attr;
	struct ibv_context *verbs;
	size_t size;
	int i, ret;
	bool has_ib_port = false;

	acm_log(1, "%s\n", ibdev->name);
	verbs = ibv_open_device(ibdev);
	if (verbs == NULL) {
		acm_log(0, "ERROR - opening device %s\n", ibdev->name);
		return;
	}

	ret = ibv_query_device(verbs, &attr);
	if (ret) {
		acm_log(0, "ERROR - ibv_query_device (%d) %s\n", ret, ibdev->name);
		goto err1;
	}

	for (i = 0; i < attr.phys_port_cnt; i++) {
		ret = ibv_query_port(verbs, i + 1, &port_attr);
		if (ret) {
			acm_log(0, "ERROR - ibv_query_port (%s, %d) return (%d)\n",
				ibdev->name, i + 1, ret);
			continue;
		}

		if (port_attr.link_layer == IBV_LINK_LAYER_INFINIBAND) {
			acm_log(1, "%s port %d is an InfiniBand port\n", ibdev->name, i + 1);
			has_ib_port = true;
		} else {
			acm_log(1, "%s port %d is not an InfiniBand port\n", ibdev->name, i + 1);
		}
	}

	if (!has_ib_port) {
		acm_log(1, "%s does not support InfiniBand.\n", ibdev->name);
		goto err1;
	}

	size = sizeof(*dev) + sizeof(struct acmc_port) * attr.phys_port_cnt;
	dev = (struct acmc_device *) calloc(1, size);
	if (!dev)
		goto err1;

	dev->device.verbs = verbs;
	dev->device.dev_guid = ibv_get_device_guid(ibdev);
	dev->port_cnt = attr.phys_port_cnt;
	list_head_init(&dev->prov_dev_context_list);

	for (i = 0; i < dev->port_cnt; i++) {
		acm_open_port(&dev->port[i], dev, i + 1);
	}

	list_add(&dev_list, &dev->entry);

	acm_log(1, "%s opened\n", ibdev->name);
	return;

err1:
	ibv_close_device(verbs);
}

static int acm_open_devices(void)
{
	struct ibv_device **ibdev;
	int dev_cnt;
	int i;

	acm_log(1, "\n");
	ibdev = ibv_get_device_list(&dev_cnt);
	if (!ibdev) {
		acm_log(0, "ERROR - unable to get device list\n");
		return -1;
	}

	for (i = 0; i < dev_cnt; i++)
		acm_open_dev(ibdev[i]);

	ibv_free_device_list(ibdev);
	if (list_empty(&dev_list)) {
		acm_log(0, "ERROR - no devices\n");
		return -1;
	}

	return 0;
}

static void acm_load_prov_config(void)
{
	FILE *fd;
	char s[128];
	char *p, *ptr;
	char prov_name[ACM_PROV_NAME_SIZE];
	uint64_t prefix;
	struct acmc_prov *prov;
	struct acmc_subnet *subnet;

	if (!(fd = fopen(opts_file, "r")))
		return;

	while (fgets(s, sizeof s, fd)) {
		if (s[0] == '#')
			continue;

		/* Ignore blank lines */
		if (!(p = strtok_r(s, " \n", &ptr)))
			continue;

		if (strncasecmp(p, "provider", sizeof("provider") - 1))
			continue;

		p = strtok_r(NULL, " ", &ptr);
		if (!p)
			continue;

		strncpy(prov_name, p, sizeof(prov_name));
		prov_name[sizeof(prov_name) -1] = '\0';

		p = strtok_r(NULL, " ", &ptr);
		if (!p)
			continue;
		if (!strncasecmp(p, "default", sizeof("default") - 1)) {
			strncpy(def_prov_name, prov_name, sizeof(def_prov_name));
			def_prov_name[sizeof(def_prov_name) -1] = '\0';
			acm_log(2, "default provider: %s\n", def_prov_name);
			continue;
		}
		prefix = strtoull(p, NULL, 0);
		acm_log(2, "provider %s subnet_prefix 0x%" PRIx64 "\n",
			prov_name, prefix);

		list_for_each(&provider_list, prov, entry) {
			if (!strcasecmp(prov->prov->name, prov_name)) {
				subnet = calloc(1, sizeof (*subnet));
				if (!subnet) {
					acm_log(0, "Error: out of memory\n");
					fclose(fd);
					return;
				}
				subnet->subnet_prefix = htobe64(prefix);
				list_add_tail(&prov->subnet_list,
					      &subnet->entry);
			}
		}
	}

	fclose(fd);

	list_for_each(&provider_list, prov, entry) {
		if (!strcasecmp(prov->prov->name, def_prov_name)) {
			def_provider = prov;
			break;
		}
	}
}

static int acm_string_end_compare(const char *s1, const char *s2)
{
	size_t s1_len = strlen(s1);
	size_t s2_len = strlen(s2);

	if (s1_len < s2_len)
		return -1;

	return strcmp(s1 + s1_len - s2_len, s2);
}

static int acm_open_providers(void)
{
	DIR *shlib_dir;
	struct dirent *dent;
	char file_name[256];
	struct stat buf;
	void *handle;
	struct acmc_prov *prov;
	struct acm_provider *provider;
	uint32_t version;
	char *err_str;
	int (*query)(struct acm_provider **, uint32_t *);

	acm_log(1, "\n");
	shlib_dir = opendir(prov_lib_path);
	if (!shlib_dir) {
		acm_log(0, "ERROR - could not open provider lib dir: %s\n",
			prov_lib_path);
		return -1;
	}

	while ((dent = readdir(shlib_dir))) {
		if (acm_string_end_compare(dent->d_name, ".so"))
			continue;

		if (!check_snprintf(file_name, sizeof(file_name), "%s/%s",
				    prov_lib_path, dent->d_name))
			continue;

		if (lstat(file_name, &buf)) {
			acm_log(0, "Error - could not stat: %s\n", file_name);
			continue;
		}
		if (!S_ISREG(buf.st_mode))
			continue;

		acm_log(2, "Loading provider %s...\n", file_name);
		if (!(handle = dlopen(file_name, RTLD_LAZY))) {
			acm_log(0, "Error - could not load provider %s (%s)\n",
				file_name, dlerror());
			continue;
		}

		query = dlsym(handle, "provider_query");
		if ((err_str = dlerror()) != NULL) {
			acm_log(0, "Error - provider_query not found in %s (%s)\n",
				file_name, err_str);
			dlclose(handle);
			continue;
		}

		if (query(&provider, &version)) {
			acm_log(0, "Error - provider_query failed to %s\n", file_name);
			dlclose(handle);
			continue;
		}

		if (version != ACM_PROV_VERSION ||
		    provider->size != sizeof(struct acm_provider)) {
			acm_log(0, "Error -unmatched provider version 0x%08x (size %zd)"
				" core 0x%08x (size %zd)\n", version, provider->size,
				ACM_PROV_VERSION, sizeof(struct acm_provider));
			dlclose(handle);
			continue;
		}

		acm_log(1, "Provider %s (%s) loaded\n", provider->name, file_name);

		prov = calloc(1, sizeof(*prov));
		if (!prov) {
			acm_log(0, "Error -failed to allocate provider %s\n", file_name);
			dlclose(handle);
			continue;
		}

		prov->prov = provider;
		prov->handle = handle;
		list_head_init(&prov->subnet_list);
		list_add_tail(&provider_list, &prov->entry);
		if (!strcasecmp(provider->name, def_prov_name))
			def_provider = prov;
	}

	closedir(shlib_dir);
	acm_load_prov_config();
	return 0;
}

static void acm_close_providers(void)
{
	struct acmc_prov *prov;
	struct acmc_subnet *subnet;

	acm_log(1, "\n");
	def_provider = NULL;

	while ((prov = list_pop(&provider_list, struct acmc_prov, entry))) {
		while ((subnet = list_pop(&prov->subnet_list,
				struct acmc_subnet, entry)))
			free(subnet);
		dlclose(prov->handle);
		free(prov);
	}
}

static int acmc_init_sa_fds(void)
{
	struct acmc_device *dev;
	int ret, p, i = 0;

	list_for_each(&dev_list, dev, entry)
		sa.nfds += dev->port_cnt;

	sa.fds = calloc(sa.nfds, sizeof(*sa.fds));
	sa.ports = calloc(sa.nfds, sizeof(*sa.ports));
	if (!sa.fds || !sa.ports)
		return -ENOMEM;

	list_for_each(&dev_list, dev, entry) {
		for (p = 0; p < dev->port_cnt; p++) {
			sa.fds[i].fd = umad_get_fd(dev->port[p].mad_portid);
			sa.fds[i].events = POLLIN;
			ret = set_fd_nonblock(sa.fds[i].fd, true);
			if (ret)
				acm_log(0, "WARNING - umad fd is blocking\n");

			sa.ports[i++] = &dev->port[p];
		}
	}

	return 0;
}

struct acm_sa_mad *
acm_alloc_sa_mad(const struct acm_endpoint *endpoint, void *context,
		 void (*handler)(struct acm_sa_mad *))
{
	struct acmc_sa_req *req;

	if (!endpoint) {
		acm_log(0, "Error: NULL endpoint\n");
		return NULL;
	}
	req = calloc(1, sizeof (*req));
	if (!req) {
		acm_log(0, "Error: failed to allocate sa request\n");
		return NULL;
	}

	req->ep = container_of(endpoint, struct acmc_ep, endpoint);
	req->mad.context = context;
	req->resp_handler = handler;

	acm_log(2, "%p\n", req);
	return &req->mad;
}

void acm_free_sa_mad(struct acm_sa_mad *mad)
{
	struct acmc_sa_req *req;
	req = container_of(mad, struct acmc_sa_req, mad);
	acm_log(2, "%p\n", req);
	free(req);
}

int acm_send_sa_mad(struct acm_sa_mad *mad)
{
	struct acmc_port *port;
	struct acmc_sa_req *req;
	int ret;

	req = container_of(mad, struct acmc_sa_req, mad);
	acm_log(2, "%p from %s\n", req, req->ep->addr_info[0].addr.id_string);

	port = req->ep->port;
	mad->umad.addr.qpn = port->sa_addr.qpn;
	mad->umad.addr.qkey = port->sa_addr.qkey;
	mad->umad.addr.lid = port->sa_addr.lid;
	mad->umad.addr.sl = port->sa_addr.sl;
	mad->umad.addr.pkey_index = req->ep->port->sa_pkey_index;

	pthread_mutex_lock(&port->lock);
	if (port->sa_credits && list_empty(&port->sa_wait)) {
		ret = umad_send(port->mad_portid, port->mad_agentid, &mad->umad,
				sizeof mad->sa_mad, sa.timeout, sa.retries);
		if (!ret) {
			port->sa_credits--;
			list_add_tail(&port->sa_pending, &req->entry);
		}
	} else {
		ret = 0;
		list_add_tail(&port->sa_wait, &req->entry);
	}
	pthread_mutex_unlock(&port->lock);
	return ret;
}

static void acmc_send_queued_req(struct acmc_port *port)
{
	struct acmc_sa_req *req;
	int ret;

	pthread_mutex_lock(&port->lock);
	if (list_empty(&port->sa_wait) || !port->sa_credits) {
		pthread_mutex_unlock(&port->lock);
		return;
	}

	req = list_pop(&port->sa_wait, struct acmc_sa_req, entry);

	ret = umad_send(port->mad_portid, port->mad_agentid, &req->mad.umad,
			sizeof req->mad.sa_mad, sa.timeout, sa.retries);
	if (!ret) {
		port->sa_credits--;
		list_add_tail(&port->sa_pending, &req->entry);
	}
	pthread_mutex_unlock(&port->lock);

	if (ret) {
		req->mad.umad.status = -ret;
		req->resp_handler(&req->mad);
	}
}

static void acmc_recv_mad(struct acmc_port *port)
{
	struct acmc_sa_req *req;
	struct acm_sa_mad resp;
	int ret, len, found;
	struct umad_hdr *hdr;

	if (!port->prov) {
		acm_log(1, "no provider assigned to port\n");
		return;
	}

	acm_log(2, "\n");
	len = sizeof(resp.sa_mad);
	ret = umad_recv(port->mad_portid, &resp.umad, &len, 0);
	if (ret < 0) {
		acm_log(1, "umad_recv error %d\n", ret);
		return;
	}

	hdr = &resp.sa_mad.mad_hdr;
	acm_log(2, "bv %x cls %x cv %x mtd %x st %d tid %" PRIx64 " at %x atm %x\n",
		hdr->base_version, hdr->mgmt_class, hdr->class_version,
		hdr->method, be16toh(hdr->status), be64toh(hdr->tid),
		be16toh(hdr->attr_id), be32toh(hdr->attr_mod));
	found = 0;
	pthread_mutex_lock(&port->lock);
	list_for_each(&port->sa_pending, req, entry) {
		/* The upper 32-bit of the tid is used for agentid in umad */
		if (req->mad.sa_mad.mad_hdr.tid == (hdr->tid & htobe64(0xFFFFFFFF))) {
			found = 1;
			list_del(&req->entry);
			port->sa_credits++;
			break;
		}
	}
	pthread_mutex_unlock(&port->lock);

	if (found) {
		memcpy(&req->mad.umad, &resp.umad, sizeof(resp.umad) + len);
		req->resp_handler(&req->mad);
	}
}

static void *acm_sa_handler(void *context)
{
	int i, ret;

	acm_log(0, "started\n");
	ret = acmc_init_sa_fds();
	if (ret) {
		acm_log(0, "ERROR - failed to init fds\n");
		return NULL;
	}

	if (pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL)) {
		acm_log(0, "Error: failed to set cancel type \n");
		return NULL;
	}

	if (pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL)) {
		acm_log(0, "Error: failed to set cancel state\n");
		return NULL;
	}

	for (;;) {
		pthread_testcancel();
		ret = poll(sa.fds, sa.nfds, -1);
		if (ret < 0) {
			acm_log(0, "ERROR - sa poll error: %d\n", errno);
			continue;
		}

		for (i = 0; i < sa.nfds; i++) {
			if (!sa.fds[i].revents)
				continue;

			if (sa.fds[i].revents & POLLIN) {
				acmc_recv_mad(sa.ports[i]);
				acmc_send_queued_req(sa.ports[i]);
			}
			sa.fds[i].revents = 0;
		}
	}
	return NULL;
}

static void acm_stop_sa_handler(void)
{
	if (pthread_cancel(sa.thread_id)) {
		acm_log(0, "Error: failed to cancel sa resp thread \n");
		return;
	}

	if (pthread_join(sa.thread_id, NULL)) {
		acm_log(0, "Error: failed to join sa resp thread\n");
		return;
	}
}

static void acm_set_options(void)
{
	FILE *f;
	char s[120];
	char opt[32], value[256];

	if (!(f = fopen(opts_file, "r")))
		return;

	while (fgets(s, sizeof s, f)) {
		if (s[0] == '#')
			continue;

		if (sscanf(s, "%31s%255s", opt, value) != 2)
			continue;

		if (!strcasecmp("log_file", opt))
			strcpy(log_file, value);
		else if (!strcasecmp("log_level", opt))
			log_level = atoi(value);
		else if (!strcasecmp("umad_debug_level", opt)) {
			umad_debug_level = atoi(value);
			if (umad_debug_level > 0)
				umad_debug(umad_debug_level);
		}
		else if (!strcasecmp("lock_file", opt))
			strcpy(lock_file, value);
		else if (!strcasecmp("server_port", opt))
			server_port = (short) atoi(value);
		else if (!strcasecmp("server_mode", opt)) {
			if (!strcasecmp(value, "open"))
				server_mode = IBACM_SERVER_MODE_OPEN;
			else if (!strcasecmp(value, "loop"))
				server_mode = IBACM_SERVER_MODE_LOOP;
			else
				server_mode = IBACM_SERVER_MODE_UNIX;
		} else if (!strcasecmp("acme_plus_kernel_only", opt))
			acme_plus_kernel_only =
				!strcasecmp(value, "true") ||
				!strcasecmp(value, "yes") ||
				strtol(value, NULL, 0);
		else if (!strcasecmp("provider_lib_path", opt))
			strcpy(prov_lib_path, value);
		else if (!strcasecmp("support_ips_in_addr_cfg", opt))
			support_ips_in_addr_cfg = atoi(value);
		else if (!strcasecmp("timeout", opt))
			sa.timeout = atoi(value);
		else if (!strcasecmp("retries", opt))
			sa.retries = atoi(value);
		else if (!strcasecmp("sa_depth", opt))
			sa.depth = atoi(value);
	}

	fclose(f);
}

static void acm_log_options(void)
{
	static const char * const server_mode_names[] = {
		[IBACM_SERVER_MODE_UNIX] = "unix",
		[IBACM_SERVER_MODE_LOOP] = "loop",
		[IBACM_SERVER_MODE_OPEN] = "open",
	};

	acm_log(0, "log file %s\n", log_file);
	acm_log(0, "log level %d\n", log_level);
	acm_log(0, "umad debug level %d\n", umad_debug_level);
	acm_log(0, "lock file %s\n", lock_file);
	acm_log(0, "server_port %d\n", server_port);
	acm_log(0, "server_mode %s\n", server_mode_names[server_mode]);
	acm_log(0, "acme_plus_kernel_only %s\n",
		acme_plus_kernel_only ? "yes" : "no");
	acm_log(0, "timeout %d ms\n", sa.timeout);
	acm_log(0, "retries %d\n", sa.retries);
	acm_log(0, "sa depth %d\n", sa.depth);
	acm_log(0, "options file %s\n", opts_file);
	acm_log(0, "addr file %s\n", addr_file);
	acm_log(0, "provider lib path %s\n", prov_lib_path);
	acm_log(0, "support IP's in ibacm_addr.cfg %d\n", support_ips_in_addr_cfg);
}

static FILE *acm_open_log(void)
{
	FILE *f;

	if (!strcasecmp(log_file, "stdout"))
		return stdout;

	if (!strcasecmp(log_file, "stderr"))
		return stderr;

	if (!(f = fopen(log_file, "w")))
		f = stdout;

	return f;
}

static int acm_open_lock_file(void)
{
	int lock_fd;
	char pid[16];

	lock_fd = open(lock_file, O_RDWR | O_CREAT, 0640);
	if (lock_fd < 0)
		return lock_fd;

	if (lockf(lock_fd, F_TLOCK, 0)) {
		close(lock_fd);
		return -1;
	}

	snprintf(pid, sizeof pid, "%d\n", getpid());
	if (write(lock_fd, pid, strlen(pid)) != strlen(pid)){
		close(lock_fd);
		return -1;
	}
	return 0;
}

static void show_usage(char *program)
{
	printf("usage: %s\n", program);
	printf("   [-D]             - run as a daemon (default)\n");
	printf("   [-P]             - run as a standard process\n");
	printf("   [-A addr_file]   - address configuration file\n");
	printf("                      (default %s/%s)\n", ACM_CONF_DIR, ACM_ADDR_FILE);
	printf("   [-O option_file] - option configuration file\n");
	printf("                      (default %s/%s)\n", ACM_CONF_DIR, ACM_OPTS_FILE);
}

int main(int argc, char **argv)
{
	int i, op, as_daemon = 1;
	bool systemd = false;

	static const struct option long_opts[] = {
		{"systemd", 0, NULL, 's'},
		{}
	};

	while ((op = getopt_long(argc, argv, "DPA:O:", long_opts, NULL)) !=
	       -1) {
		switch (op) {
		case 'D':
			/* option no longer required */
			break;
		case 'P':
			as_daemon = 0;
			break;
		case 'A':
			addr_file = optarg;
			break;
		case 'O':
			opts_file = optarg;
			break;
		case 's':
			systemd = true;
			break;
		default:
			show_usage(argv[0]);
			exit(1);
		}
	}

	if (as_daemon && !systemd) {
		if (daemon(0, 0))
			return EXIT_FAILURE;
	}

	acm_set_options();

	/* usage of systemd implies unix-domain communication */
	if (systemd)
		server_mode = IBACM_SERVER_MODE_UNIX;

	if (acm_open_lock_file())
		return -1;

	pthread_mutex_init(&log_lock, NULL);
	flog = acm_open_log();

	acm_log(0, "Assistant to the InfiniBand Communication Manager\n");
	acm_log_options();

	for (i = 0; i < ACM_MAX_COUNTER; i++)
		atomic_init(&counter[i]);

	if (umad_init() != 0) {
		acm_log(0, "ERROR - fail to initialize umad\n");
		return -1;
	}

	if (acm_open_providers()) {
		acm_log(0, "ERROR - unable to open any providers\n");
		return -1;
	}

	if (acm_open_devices()) {
		acm_log(0, "ERROR - unable to open any devices\n");
		return -1;
	}

	acm_log(1, "creating IP Netlink socket\n");
	acm_ipnl_create();

	acm_log(1, "starting sa response receiving thread\n");
	if (pthread_create(&sa.thread_id, NULL, acm_sa_handler, NULL)) {
		acm_log(0, "Error: failed to create sa resp rcving thread");
		return -1;
	}

	if (acm_init_if_iter_sys()) {
		acm_log(0, "Error: unable to initialize acm_if_iter_sys");
		return -1;
	}

	acm_activate_devices();
	acm_log(1, "starting server\n");
	acm_server(systemd);

	acm_log(0, "shutting down\n");
	if (client_array[NL_CLIENT_INDEX].sock != -1)
		close(client_array[NL_CLIENT_INDEX].sock);
	acm_close_providers();
	acm_stop_sa_handler();
	umad_done();
	acm_fini_if_iter_sys();
	fclose(flog);
	return 0;
}
