/*
 * iwpm_add_mapping - Send a netlink add mapping message
 *                    to the port mapper
 * nlmsg attributes:
 *	[IWPM_NLA_MANAGE_MAPPING_SEQ]
 *	[IWPM_NLA_MANAGE_ADDR]
 */
int iwpm_add_mapping(struct iwpm_sa_data *pm_msg, u8 nl_client)
{
	struct sk_buff *skb = NULL;
	struct iwpm_nlmsg_request *nlmsg_request = NULL;
	struct nlmsghdr *nlh;
	u32 msg_seq;
	const char *err_str = "";
	int ret = -EINVAL;

	if (!iwpm_valid_client(nl_client)) {
		err_str = "Invalid port mapper client";
		goto add_mapping_error;
	}
	if (!iwpm_valid_pid())
		return 0;
	if (!iwpm_check_registration(nl_client, IWPM_REG_VALID)) {
		err_str = "Unregistered port mapper client";
		goto add_mapping_error;
	}
	skb = iwpm_create_nlmsg(RDMA_NL_IWPM_ADD_MAPPING, &nlh, nl_client);
	if (!skb) {
		err_str = "Unable to create a nlmsg";
		goto add_mapping_error;
	}
	nlh->nlmsg_seq = iwpm_get_nlmsg_seq();
	nlmsg_request = iwpm_get_nlmsg_request(nlh->nlmsg_seq, nl_client, GFP_KERNEL);
	if (!nlmsg_request) {
		err_str = "Unable to allocate netlink request";
		goto add_mapping_error;
	}
	msg_seq = atomic_read(&echo_nlmsg_seq);
	/* fill in the add mapping message */
	err_str = "Unable to put attribute of the nlmsg";
	ret = ibnl_put_attr(skb, nlh, sizeof(u32), &msg_seq,
				IWPM_NLA_MANAGE_MAPPING_SEQ);
	if (ret)
		goto add_mapping_error;
	ret = ibnl_put_attr(skb, nlh, sizeof(struct sockaddr_storage),
				&pm_msg->loc_addr, IWPM_NLA_MANAGE_ADDR);
	if (ret)
		goto add_mapping_error;
	nlmsg_request->req_buffer = pm_msg;

	ret = ibnl_unicast(skb, nlh, iwpm_user_pid);
	if (ret) {
		skb = NULL; /* skb is freed in the netlink send-op handling */
		iwpm_user_pid = IWPM_PID_UNDEFINED;
		err_str = "Unable to send a nlmsg";
		goto add_mapping_error;
	}
	ret = iwpm_wait_complete_req(nlmsg_request);
	return ret;
add_mapping_error:
	pr_info("%s: %s (client = %d)\n", __func__, err_str, nl_client);
	if (skb)
		dev_kfree_skb(skb);
	if (nlmsg_request)
		iwpm_free_nlmsg_request(&nlmsg_request->kref);
	return ret;
}
Example #2
0
/*
 * iwpm_remove_mapping - Send a netlink remove mapping message
 *                       to the port mapper
 * nlmsg attributes:
 *	[IWPM_NLA_MANAGE_MAPPING_SEQ]
 *	[IWPM_NLA_MANAGE_ADDR]
 */
int iwpm_remove_mapping(struct sockaddr_storage *local_addr, u8 nl_client)
{
	struct sk_buff *skb = NULL;
	struct nlmsghdr *nlh;
	u32 msg_seq;
	const char *err_str = "";
	int ret = -EINVAL;

	if (!iwpm_valid_client(nl_client)) {
		err_str = "Invalid port mapper client";
		goto remove_mapping_error;
	}
	if (!iwpm_valid_pid())
		return 0;
	if (iwpm_check_registration(nl_client, IWPM_REG_UNDEF)) {
		err_str = "Unregistered port mapper client";
		goto remove_mapping_error;
	}
	skb = iwpm_create_nlmsg(RDMA_NL_IWPM_REMOVE_MAPPING, &nlh, nl_client);
	if (!skb) {
		ret = -ENOMEM;
		err_str = "Unable to create a nlmsg";
		goto remove_mapping_error;
	}
	msg_seq = atomic_read(&echo_nlmsg_seq);
	nlh->nlmsg_seq = iwpm_get_nlmsg_seq();
	err_str = "Unable to put attribute of the nlmsg";
	ret = ibnl_put_attr(skb, nlh, sizeof(u32), &msg_seq,
				IWPM_NLA_MANAGE_MAPPING_SEQ);
	if (ret)
		goto remove_mapping_error;
	ret = ibnl_put_attr(skb, nlh, sizeof(struct sockaddr_storage),
				local_addr, IWPM_NLA_MANAGE_ADDR);
	if (ret)
		goto remove_mapping_error;

	nlmsg_end(skb, nlh);

	ret = rdma_nl_unicast_wait(skb, iwpm_user_pid);
	if (ret) {
		skb = NULL; /* skb is freed in the netlink send-op handling */
		iwpm_user_pid = IWPM_PID_UNDEFINED;
		err_str = "Unable to send a nlmsg";
		goto remove_mapping_error;
	}
	iwpm_print_sockaddr(local_addr,
			"remove_mapping: Local sockaddr:");
	return 0;
remove_mapping_error:
	pr_info("%s: %s (client = %d)\n", __func__, err_str, nl_client);
	if (skb)
		dev_kfree_skb_any(skb);
	return ret;
}
/*
 * iwpm_register_pid - Send a netlink query to user space
 *                     for the iwarp port mapper pid
 *
 * nlmsg attributes:
 *	[IWPM_NLA_REG_PID_SEQ]
 *	[IWPM_NLA_REG_IF_NAME]
 *	[IWPM_NLA_REG_IBDEV_NAME]
 *	[IWPM_NLA_REG_ULIB_NAME]
 */
int iwpm_register_pid(struct iwpm_dev_data *pm_msg, u8 nl_client)
{
	struct sk_buff *skb = NULL;
	struct iwpm_nlmsg_request *nlmsg_request = NULL;
	struct nlmsghdr *nlh;
	u32 msg_seq;
	const char *err_str = "";
	int ret = -EINVAL;

	if (!iwpm_valid_client(nl_client)) {
		err_str = "Invalid port mapper client";
		goto pid_query_error;
	}
	if (iwpm_check_registration(nl_client, IWPM_REG_VALID) ||
			iwpm_user_pid == IWPM_PID_UNAVAILABLE)
		return 0;
	skb = iwpm_create_nlmsg(RDMA_NL_IWPM_REG_PID, &nlh, nl_client);
	if (!skb) {
		err_str = "Unable to create a nlmsg";
		goto pid_query_error;
	}
	nlh->nlmsg_seq = iwpm_get_nlmsg_seq();
	nlmsg_request = iwpm_get_nlmsg_request(nlh->nlmsg_seq, nl_client, GFP_KERNEL);
	if (!nlmsg_request) {
		err_str = "Unable to allocate netlink request";
		goto pid_query_error;
	}
	msg_seq = atomic_read(&echo_nlmsg_seq);

	/* fill in the pid request message */
	err_str = "Unable to put attribute of the nlmsg";
	ret = ibnl_put_attr(skb, nlh, sizeof(u32), &msg_seq, IWPM_NLA_REG_PID_SEQ);
	if (ret)
		goto pid_query_error;
	ret = ibnl_put_attr(skb, nlh, IWPM_IFNAME_SIZE,
				pm_msg->if_name, IWPM_NLA_REG_IF_NAME);
	if (ret)
		goto pid_query_error;
	ret = ibnl_put_attr(skb, nlh, IWPM_DEVNAME_SIZE,
				pm_msg->dev_name, IWPM_NLA_REG_IBDEV_NAME);
	if (ret)
		goto pid_query_error;
	ret = ibnl_put_attr(skb, nlh, IWPM_ULIBNAME_SIZE,
				(char *)iwpm_ulib_name, IWPM_NLA_REG_ULIB_NAME);
	if (ret)
		goto pid_query_error;

	pr_debug("%s: Multicasting a nlmsg (dev = %s ifname = %s iwpm = %s)\n",
		__func__, pm_msg->dev_name, pm_msg->if_name, iwpm_ulib_name);

	ret = ibnl_multicast(skb, nlh, RDMA_NL_GROUP_IWPM, GFP_KERNEL);
	if (ret) {
		skb = NULL; /* skb is freed in the netlink send-op handling */
		iwpm_user_pid = IWPM_PID_UNAVAILABLE;
		err_str = "Unable to send a nlmsg";
		goto pid_query_error;
	}
	nlmsg_request->req_buffer = pm_msg;
	ret = iwpm_wait_complete_req(nlmsg_request);
	return ret;
pid_query_error:
	pr_info("%s: %s (client = %d)\n", __func__, err_str, nl_client);
	if (skb)
		dev_kfree_skb(skb);
	if (nlmsg_request)
		iwpm_free_nlmsg_request(&nlmsg_request->kref);
	return ret;
}