// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
#include <errno.h>
#include <poll.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <linux/types.h>
#include <linux/genetlink.h>
#include <sys/socket.h>

#include "ynl.h"

#define ARRAY_SIZE(arr)		(sizeof(arr) / sizeof(*arr))

#define __yerr_msg(yse, _msg...)					\
	({								\
		struct ynl_error *_yse = (yse);				\
									\
		if (_yse) {						\
			snprintf(_yse->msg, sizeof(_yse->msg) - 1,  _msg); \
			_yse->msg[sizeof(_yse->msg) - 1] = 0;		\
		}							\
	})

#define __yerr_code(yse, _code...)		\
	({					\
		struct ynl_error *_yse = (yse);	\
						\
		if (_yse) {			\
			_yse->code = _code;	\
		}				\
	})

#define __yerr(yse, _code, _msg...)		\
	({					\
		__yerr_msg(yse, _msg);		\
		__yerr_code(yse, _code);	\
	})

#define __perr(yse, _msg)		__yerr(yse, errno, _msg)

#define yerr_msg(_ys, _msg...)		__yerr_msg(&(_ys)->err, _msg)
#define yerr(_ys, _code, _msg...)	__yerr(&(_ys)->err, _code, _msg)
#define perr(_ys, _msg)			__yerr(&(_ys)->err, errno, _msg)

/* -- Netlink boiler plate */
static int
ynl_err_walk_report_one(struct ynl_policy_nest *policy, unsigned int type,
			char *str, int str_sz, int *n)
{
	if (!policy) {
		if (*n < str_sz)
			*n += snprintf(str, str_sz, "!policy");
		return 1;
	}

	if (type > policy->max_attr) {
		if (*n < str_sz)
			*n += snprintf(str, str_sz, "!oob");
		return 1;
	}

	if (!policy->table[type].name) {
		if (*n < str_sz)
			*n += snprintf(str, str_sz, "!name");
		return 1;
	}

	if (*n < str_sz)
		*n += snprintf(str, str_sz - *n,
			       ".%s", policy->table[type].name);
	return 0;
}

static int
ynl_err_walk(struct ynl_sock *ys, void *start, void *end, unsigned int off,
	     struct ynl_policy_nest *policy, char *str, int str_sz,
	     struct ynl_policy_nest **nest_pol)
{
	unsigned int astart_off, aend_off;
	const struct nlattr *attr;
	unsigned int data_len;
	unsigned int type;
	bool found = false;
	int n = 0;

	if (!policy) {
		if (n < str_sz)
			n += snprintf(str, str_sz, "!policy");
		return n;
	}

	data_len = end - start;

	ynl_attr_for_each_payload(start, data_len, attr) {
		astart_off = (char *)attr - (char *)start;
		aend_off = astart_off + ynl_attr_data_len(attr);
		if (aend_off <= off)
			continue;

		found = true;
		break;
	}
	if (!found)
		return 0;

	off -= astart_off;

	type = ynl_attr_type(attr);

	if (ynl_err_walk_report_one(policy, type, str, str_sz, &n))
		return n;

	if (!off) {
		if (nest_pol)
			*nest_pol = policy->table[type].nest;
		return n;
	}

	if (!policy->table[type].nest) {
		if (n < str_sz)
			n += snprintf(str, str_sz, "!nest");
		return n;
	}

	off -= sizeof(struct nlattr);
	start =  ynl_attr_data(attr);
	end = start + ynl_attr_data_len(attr);

	return n + ynl_err_walk(ys, start, end, off, policy->table[type].nest,
				&str[n], str_sz - n, nest_pol);
}

#define NLMSGERR_ATTR_MISS_TYPE (NLMSGERR_ATTR_POLICY + 1)
#define NLMSGERR_ATTR_MISS_NEST (NLMSGERR_ATTR_POLICY + 2)
#define NLMSGERR_ATTR_MAX (NLMSGERR_ATTR_MAX + 2)

static int
ynl_ext_ack_check(struct ynl_sock *ys, const struct nlmsghdr *nlh,
		  unsigned int hlen)
{
	const struct nlattr *tb[NLMSGERR_ATTR_MAX + 1] = {};
	char miss_attr[sizeof(ys->err.msg)];
	char bad_attr[sizeof(ys->err.msg)];
	const struct nlattr *attr;
	const char *str = NULL;

	if (!(nlh->nlmsg_flags & NLM_F_ACK_TLVS)) {
		yerr_msg(ys, "%s", strerror(ys->err.code));
		return YNL_PARSE_CB_OK;
	}

	ynl_attr_for_each(attr, nlh, hlen) {
		unsigned int len, type;

		len = ynl_attr_data_len(attr);
		type = ynl_attr_type(attr);

		if (type > NLMSGERR_ATTR_MAX)
			continue;

		tb[type] = attr;

		switch (type) {
		case NLMSGERR_ATTR_OFFS:
		case NLMSGERR_ATTR_MISS_TYPE:
		case NLMSGERR_ATTR_MISS_NEST:
			if (len != sizeof(__u32))
				return YNL_PARSE_CB_ERROR;
			break;
		case NLMSGERR_ATTR_MSG:
			str = ynl_attr_get_str(attr);
			if (str[len - 1])
				return YNL_PARSE_CB_ERROR;
			break;
		default:
			break;
		}
	}

	bad_attr[0] = '\0';
	miss_attr[0] = '\0';

	if (tb[NLMSGERR_ATTR_OFFS]) {
		unsigned int n, off;
		void *start, *end;

		ys->err.attr_offs = ynl_attr_get_u32(tb[NLMSGERR_ATTR_OFFS]);

		n = snprintf(bad_attr, sizeof(bad_attr), "%sbad attribute: ",
			     str ? " (" : "");

		start = ynl_nlmsg_data_offset(ys->nlh, ys->family->hdr_len);
		end = ynl_nlmsg_end_addr(ys->nlh);

		off = ys->err.attr_offs;
		off -= sizeof(struct nlmsghdr);
		off -= ys->family->hdr_len;

		n += ynl_err_walk(ys, start, end, off, ys->req_policy,
				  &bad_attr[n], sizeof(bad_attr) - n, NULL);

		if (n >= sizeof(bad_attr))
			n = sizeof(bad_attr) - 1;
		bad_attr[n] = '\0';
	}
	if (tb[NLMSGERR_ATTR_MISS_TYPE]) {
		struct ynl_policy_nest *nest_pol = NULL;
		unsigned int n, off, type;
		void *start, *end;
		int n2;

		type = ynl_attr_get_u32(tb[NLMSGERR_ATTR_MISS_TYPE]);

		n = snprintf(miss_attr, sizeof(miss_attr), "%smissing attribute: ",
			     bad_attr[0] ? ", " : (str ? " (" : ""));

		start = ynl_nlmsg_data_offset(ys->nlh, ys->family->hdr_len);
		end = ynl_nlmsg_end_addr(ys->nlh);

		nest_pol = ys->req_policy;
		if (tb[NLMSGERR_ATTR_MISS_NEST]) {
			off = ynl_attr_get_u32(tb[NLMSGERR_ATTR_MISS_NEST]);
			off -= sizeof(struct nlmsghdr);
			off -= ys->family->hdr_len;

			n += ynl_err_walk(ys, start, end, off, ys->req_policy,
					  &miss_attr[n], sizeof(miss_attr) - n,
					  &nest_pol);
		}

		n2 = 0;
		ynl_err_walk_report_one(nest_pol, type, &miss_attr[n],
					sizeof(miss_attr) - n, &n2);
		n += n2;

		if (n >= sizeof(miss_attr))
			n = sizeof(miss_attr) - 1;
		miss_attr[n] = '\0';
	}

	/* Implicitly depend on ys->err.code already set */
	if (str)
		yerr_msg(ys, "Kernel %s: '%s'%s%s%s",
			 ys->err.code ? "error" : "warning",
			 str, bad_attr, miss_attr,
			 bad_attr[0] || miss_attr[0] ? ")" : "");
	else if (bad_attr[0] || miss_attr[0])
		yerr_msg(ys, "Kernel %s: %s%s",
			 ys->err.code ? "error" : "warning",
			 bad_attr, miss_attr);
	else
		yerr_msg(ys, "%s", strerror(ys->err.code));

	return YNL_PARSE_CB_OK;
}

static int
ynl_cb_error(const struct nlmsghdr *nlh, struct ynl_parse_arg *yarg)
{
	const struct nlmsgerr *err = ynl_nlmsg_data(nlh);
	unsigned int hlen;
	int code;

	code = err->error >= 0 ? err->error : -err->error;
	yarg->ys->err.code = code;
	errno = code;

	hlen = sizeof(*err);
	if (!(nlh->nlmsg_flags & NLM_F_CAPPED))
		hlen += ynl_nlmsg_data_len(&err->msg);

	ynl_ext_ack_check(yarg->ys, nlh, hlen);

	return code ? YNL_PARSE_CB_ERROR : YNL_PARSE_CB_STOP;
}

static int ynl_cb_done(const struct nlmsghdr *nlh, struct ynl_parse_arg *yarg)
{
	int err;

	err = *(int *)NLMSG_DATA(nlh);
	if (err < 0) {
		yarg->ys->err.code = -err;
		errno = -err;

		ynl_ext_ack_check(yarg->ys, nlh, sizeof(int));

		return YNL_PARSE_CB_ERROR;
	}
	return YNL_PARSE_CB_STOP;
}

/* Attribute validation */

int ynl_attr_validate(struct ynl_parse_arg *yarg, const struct nlattr *attr)
{
	struct ynl_policy_attr *policy;
	unsigned int type, len;
	unsigned char *data;

	data = ynl_attr_data(attr);
	len = ynl_attr_data_len(attr);
	type = ynl_attr_type(attr);
	if (type > yarg->rsp_policy->max_attr) {
		yerr(yarg->ys, YNL_ERROR_INTERNAL,
		     "Internal error, validating unknown attribute");
		return -1;
	}

	policy = &yarg->rsp_policy->table[type];

	switch (policy->type) {
	case YNL_PT_REJECT:
		yerr(yarg->ys, YNL_ERROR_ATTR_INVALID,
		     "Rejected attribute (%s)", policy->name);
		return -1;
	case YNL_PT_IGNORE:
		break;
	case YNL_PT_U8:
		if (len == sizeof(__u8))
			break;
		yerr(yarg->ys, YNL_ERROR_ATTR_INVALID,
		     "Invalid attribute (u8 %s)", policy->name);
		return -1;
	case YNL_PT_U16:
		if (len == sizeof(__u16))
			break;
		yerr(yarg->ys, YNL_ERROR_ATTR_INVALID,
		     "Invalid attribute (u16 %s)", policy->name);
		return -1;
	case YNL_PT_U32:
		if (len == sizeof(__u32))
			break;
		yerr(yarg->ys, YNL_ERROR_ATTR_INVALID,
		     "Invalid attribute (u32 %s)", policy->name);
		return -1;
	case YNL_PT_U64:
		if (len == sizeof(__u64))
			break;
		yerr(yarg->ys, YNL_ERROR_ATTR_INVALID,
		     "Invalid attribute (u64 %s)", policy->name);
		return -1;
	case YNL_PT_UINT:
		if (len == sizeof(__u32) || len == sizeof(__u64))
			break;
		yerr(yarg->ys, YNL_ERROR_ATTR_INVALID,
		     "Invalid attribute (uint %s)", policy->name);
		return -1;
	case YNL_PT_FLAG:
		/* Let flags grow into real attrs, why not.. */
		break;
	case YNL_PT_NEST:
		if (!len || len >= sizeof(*attr))
			break;
		yerr(yarg->ys, YNL_ERROR_ATTR_INVALID,
		     "Invalid attribute (nest %s)", policy->name);
		return -1;
	case YNL_PT_BINARY:
		if (!policy->len || len == policy->len)
			break;
		yerr(yarg->ys, YNL_ERROR_ATTR_INVALID,
		     "Invalid attribute (binary %s)", policy->name);
		return -1;
	case YNL_PT_NUL_STR:
		if ((!policy->len || len <= policy->len) && !data[len - 1])
			break;
		yerr(yarg->ys, YNL_ERROR_ATTR_INVALID,
		     "Invalid attribute (string %s)", policy->name);
		return -1;
	case YNL_PT_BITFIELD32:
		if (len == sizeof(struct nla_bitfield32))
			break;
		yerr(yarg->ys, YNL_ERROR_ATTR_INVALID,
		     "Invalid attribute (bitfield32 %s)", policy->name);
		return -1;
	default:
		yerr(yarg->ys, YNL_ERROR_ATTR_INVALID,
		     "Invalid attribute (unknown %s)", policy->name);
		return -1;
	}

	return 0;
}

/* Generic code */

static void ynl_err_reset(struct ynl_sock *ys)
{
	ys->err.code = 0;
	ys->err.attr_offs = 0;
	ys->err.msg[0] = 0;
}

struct nlmsghdr *ynl_msg_start(struct ynl_sock *ys, __u32 id, __u16 flags)
{
	struct nlmsghdr *nlh;

	ynl_err_reset(ys);

	nlh = ys->nlh = ynl_nlmsg_put_header(ys->tx_buf);
	nlh->nlmsg_type	= id;
	nlh->nlmsg_flags = flags;
	nlh->nlmsg_seq = ++ys->seq;

	/* This is a local YNL hack for length checking, we put the buffer
	 * length in nlmsg_pid, since messages sent to the kernel always use
	 * PID 0. Message needs to be terminated with ynl_msg_end().
	 */
	nlh->nlmsg_pid = YNL_SOCKET_BUFFER_SIZE;

	return nlh;
}

static int ynl_msg_end(struct ynl_sock *ys, struct nlmsghdr *nlh)
{
	/* We stash buffer length in nlmsg_pid. */
	if (nlh->nlmsg_pid == 0) {
		yerr(ys, YNL_ERROR_INPUT_INVALID,
		     "Unknown input buffer length");
		return -EINVAL;
	}
	if (nlh->nlmsg_pid == YNL_MSG_OVERFLOW) {
		yerr(ys, YNL_ERROR_INPUT_TOO_BIG,
		     "Constructed message longer than internal buffer");
		return -EMSGSIZE;
	}

	nlh->nlmsg_pid = 0;
	return 0;
}

struct nlmsghdr *
ynl_gemsg_start(struct ynl_sock *ys, __u32 id, __u16 flags,
		__u8 cmd, __u8 version)
{
	struct genlmsghdr gehdr;
	struct nlmsghdr *nlh;
	void *data;

	nlh = ynl_msg_start(ys, id, flags);

	memset(&gehdr, 0, sizeof(gehdr));
	gehdr.cmd = cmd;
	gehdr.version = version;

	data = ynl_nlmsg_put_extra_header(nlh, sizeof(gehdr));
	memcpy(data, &gehdr, sizeof(gehdr));

	return nlh;
}

void ynl_msg_start_req(struct ynl_sock *ys, __u32 id)
{
	ynl_msg_start(ys, id, NLM_F_REQUEST | NLM_F_ACK);
}

void ynl_msg_start_dump(struct ynl_sock *ys, __u32 id)
{
	ynl_msg_start(ys, id, NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP);
}

struct nlmsghdr *
ynl_gemsg_start_req(struct ynl_sock *ys, __u32 id, __u8 cmd, __u8 version)
{
	return ynl_gemsg_start(ys, id, NLM_F_REQUEST | NLM_F_ACK, cmd, version);
}

struct nlmsghdr *
ynl_gemsg_start_dump(struct ynl_sock *ys, __u32 id, __u8 cmd, __u8 version)
{
	return ynl_gemsg_start(ys, id, NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP,
			       cmd, version);
}

static int ynl_cb_null(const struct nlmsghdr *nlh, struct ynl_parse_arg *yarg)
{
	yerr(yarg->ys, YNL_ERROR_UNEXPECT_MSG,
	     "Received a message when none were expected");

	return YNL_PARSE_CB_ERROR;
}

static int
__ynl_sock_read_msgs(struct ynl_parse_arg *yarg, ynl_parse_cb_t cb, int flags)
{
	struct ynl_sock *ys = yarg->ys;
	const struct nlmsghdr *nlh;
	ssize_t len, rem;
	int ret;

	len = recv(ys->socket, ys->rx_buf, YNL_SOCKET_BUFFER_SIZE, flags);
	if (len < 0) {
		if (flags & MSG_DONTWAIT && errno == EAGAIN)
			return YNL_PARSE_CB_STOP;
		return len;
	}

	ret = YNL_PARSE_CB_STOP;
	for (rem = len; rem > 0; NLMSG_NEXT(nlh, rem)) {
		nlh = (struct nlmsghdr *)&ys->rx_buf[len - rem];
		if (!NLMSG_OK(nlh, rem)) {
			yerr(yarg->ys, YNL_ERROR_INV_RESP,
			     "Invalid message or trailing data in the response.");
			return YNL_PARSE_CB_ERROR;
		}

		if (nlh->nlmsg_flags & NLM_F_DUMP_INTR) {
			/* TODO: handle this better */
			yerr(yarg->ys, YNL_ERROR_DUMP_INTER,
			     "Dump interrupted / inconsistent, please retry.");
			return YNL_PARSE_CB_ERROR;
		}

		switch (nlh->nlmsg_type) {
		case 0:
			yerr(yarg->ys, YNL_ERROR_INV_RESP,
			     "Invalid message type in the response.");
			return YNL_PARSE_CB_ERROR;
		case NLMSG_NOOP:
		case NLMSG_OVERRUN ... NLMSG_MIN_TYPE - 1:
			ret = YNL_PARSE_CB_OK;
			break;
		case NLMSG_ERROR:
			ret = ynl_cb_error(nlh, yarg);
			break;
		case NLMSG_DONE:
			ret = ynl_cb_done(nlh, yarg);
			break;
		default:
			ret = cb(nlh, yarg);
			break;
		}
	}

	return ret;
}

static int ynl_sock_read_msgs(struct ynl_parse_arg *yarg, ynl_parse_cb_t cb)
{
	return __ynl_sock_read_msgs(yarg, cb, 0);
}

static int ynl_recv_ack(struct ynl_sock *ys, int ret)
{
	struct ynl_parse_arg yarg = { .ys = ys, };

	if (!ret) {
		yerr(ys, YNL_ERROR_EXPECT_ACK,
		     "Expecting an ACK but nothing received");
		return -1;
	}

	return ynl_sock_read_msgs(&yarg, ynl_cb_null);
}

/* Init/fini and genetlink boiler plate */
static int
ynl_get_family_info_mcast(struct ynl_sock *ys, const struct nlattr *mcasts)
{
	const struct nlattr *entry, *attr;
	unsigned int i;

	ynl_attr_for_each_nested(attr, mcasts)
		ys->n_mcast_groups++;

	if (!ys->n_mcast_groups)
		return 0;

	ys->mcast_groups = calloc(ys->n_mcast_groups,
				  sizeof(*ys->mcast_groups));
	if (!ys->mcast_groups)
		return YNL_PARSE_CB_ERROR;

	i = 0;
	ynl_attr_for_each_nested(entry, mcasts) {
		ynl_attr_for_each_nested(attr, entry) {
			if (ynl_attr_type(attr) == CTRL_ATTR_MCAST_GRP_ID)
				ys->mcast_groups[i].id = ynl_attr_get_u32(attr);
			if (ynl_attr_type(attr) == CTRL_ATTR_MCAST_GRP_NAME) {
				strncpy(ys->mcast_groups[i].name,
					ynl_attr_get_str(attr),
					GENL_NAMSIZ - 1);
				ys->mcast_groups[i].name[GENL_NAMSIZ - 1] = 0;
			}
		}
		i++;
	}

	return 0;
}

static int
ynl_get_family_info_cb(const struct nlmsghdr *nlh, struct ynl_parse_arg *yarg)
{
	struct ynl_sock *ys = yarg->ys;
	const struct nlattr *attr;
	bool found_id = true;

	ynl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
		if (ynl_attr_type(attr) == CTRL_ATTR_MCAST_GROUPS)
			if (ynl_get_family_info_mcast(ys, attr))
				return YNL_PARSE_CB_ERROR;

		if (ynl_attr_type(attr) != CTRL_ATTR_FAMILY_ID)
			continue;

		if (ynl_attr_data_len(attr) != sizeof(__u16)) {
			yerr(ys, YNL_ERROR_ATTR_INVALID, "Invalid family ID");
			return YNL_PARSE_CB_ERROR;
		}

		ys->family_id = ynl_attr_get_u16(attr);
		found_id = true;
	}

	if (!found_id) {
		yerr(ys, YNL_ERROR_ATTR_MISSING, "Family ID missing");
		return YNL_PARSE_CB_ERROR;
	}
	return YNL_PARSE_CB_OK;
}

static int ynl_sock_read_family(struct ynl_sock *ys, const char *family_name)
{
	struct ynl_parse_arg yarg = { .ys = ys, };
	struct nlmsghdr *nlh;
	int err;

	nlh = ynl_gemsg_start_req(ys, GENL_ID_CTRL, CTRL_CMD_GETFAMILY, 1);
	ynl_attr_put_str(nlh, CTRL_ATTR_FAMILY_NAME, family_name);

	err = ynl_msg_end(ys, nlh);
	if (err < 0)
		return err;

	err = send(ys->socket, nlh, nlh->nlmsg_len, 0);
	if (err < 0) {
		perr(ys, "failed to request socket family info");
		return err;
	}

	err = ynl_sock_read_msgs(&yarg, ynl_get_family_info_cb);
	if (err < 0) {
		free(ys->mcast_groups);
		perr(ys, "failed to receive the socket family info - no such family?");
		return err;
	}

	err = ynl_recv_ack(ys, err);
	if (err < 0) {
		free(ys->mcast_groups);
		return err;
	}

	return 0;
}

struct ynl_sock *
ynl_sock_create(const struct ynl_family *yf, struct ynl_error *yse)
{
	struct sockaddr_nl addr;
	struct ynl_sock *ys;
	socklen_t addrlen;
	int one = 1;

	ys = malloc(sizeof(*ys) + 2 * YNL_SOCKET_BUFFER_SIZE);
	if (!ys)
		return NULL;
	memset(ys, 0, sizeof(*ys));

	ys->family = yf;
	ys->tx_buf = &ys->raw_buf[0];
	ys->rx_buf = &ys->raw_buf[YNL_SOCKET_BUFFER_SIZE];
	ys->ntf_last_next = &ys->ntf_first;

	ys->socket = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
	if (ys->socket < 0) {
		__perr(yse, "failed to create a netlink socket");
		goto err_free_sock;
	}

	if (setsockopt(ys->socket, SOL_NETLINK, NETLINK_CAP_ACK,
		       &one, sizeof(one))) {
		__perr(yse, "failed to enable netlink ACK");
		goto err_close_sock;
	}
	if (setsockopt(ys->socket, SOL_NETLINK, NETLINK_EXT_ACK,
		       &one, sizeof(one))) {
		__perr(yse, "failed to enable netlink ext ACK");
		goto err_close_sock;
	}

	memset(&addr, 0, sizeof(addr));
	addr.nl_family = AF_NETLINK;
	if (bind(ys->socket, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
		__perr(yse, "unable to bind to a socket address");
		goto err_close_sock;;
	}

	memset(&addr, 0, sizeof(addr));
	addrlen = sizeof(addr);
	if (getsockname(ys->socket, (struct sockaddr *)&addr, &addrlen) < 0) {
		__perr(yse, "unable to read socket address");
		goto err_close_sock;;
	}
	ys->portid = addr.nl_pid;
	ys->seq = random();


	if (ynl_sock_read_family(ys, yf->name)) {
		if (yse)
			memcpy(yse, &ys->err, sizeof(*yse));
		goto err_close_sock;
	}

	return ys;

err_close_sock:
	close(ys->socket);
err_free_sock:
	free(ys);
	return NULL;
}

void ynl_sock_destroy(struct ynl_sock *ys)
{
	struct ynl_ntf_base_type *ntf;

	close(ys->socket);
	while ((ntf = ynl_ntf_dequeue(ys)))
		ynl_ntf_free(ntf);
	free(ys->mcast_groups);
	free(ys);
}

/* YNL multicast handling */

void ynl_ntf_free(struct ynl_ntf_base_type *ntf)
{
	ntf->free(ntf);
}

int ynl_subscribe(struct ynl_sock *ys, const char *grp_name)
{
	unsigned int i;
	int err;

	for (i = 0; i < ys->n_mcast_groups; i++)
		if (!strcmp(ys->mcast_groups[i].name, grp_name))
			break;
	if (i == ys->n_mcast_groups) {
		yerr(ys, ENOENT, "Multicast group '%s' not found", grp_name);
		return -1;
	}

	err = setsockopt(ys->socket, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP,
			 &ys->mcast_groups[i].id,
			 sizeof(ys->mcast_groups[i].id));
	if (err < 0) {
		perr(ys, "Subscribing to multicast group failed");
		return -1;
	}

	return 0;
}

int ynl_socket_get_fd(struct ynl_sock *ys)
{
	return ys->socket;
}

struct ynl_ntf_base_type *ynl_ntf_dequeue(struct ynl_sock *ys)
{
	struct ynl_ntf_base_type *ntf;

	if (!ynl_has_ntf(ys))
		return NULL;

	ntf = ys->ntf_first;
	ys->ntf_first = ntf->next;
	if (ys->ntf_last_next == &ntf->next)
		ys->ntf_last_next = &ys->ntf_first;

	return ntf;
}

static int ynl_ntf_parse(struct ynl_sock *ys, const struct nlmsghdr *nlh)
{
	struct ynl_parse_arg yarg = { .ys = ys, };
	const struct ynl_ntf_info *info;
	struct ynl_ntf_base_type *rsp;
	struct genlmsghdr *gehdr;
	int ret;

	gehdr = ynl_nlmsg_data(nlh);
	if (gehdr->cmd >= ys->family->ntf_info_size)
		return YNL_PARSE_CB_ERROR;
	info = &ys->family->ntf_info[gehdr->cmd];
	if (!info->cb)
		return YNL_PARSE_CB_ERROR;

	rsp = calloc(1, info->alloc_sz);
	rsp->free = info->free;
	yarg.data = rsp->data;
	yarg.rsp_policy = info->policy;

	ret = info->cb(nlh, &yarg);
	if (ret <= YNL_PARSE_CB_STOP)
		goto err_free;

	rsp->family = nlh->nlmsg_type;
	rsp->cmd = gehdr->cmd;

	*ys->ntf_last_next = rsp;
	ys->ntf_last_next = &rsp->next;

	return YNL_PARSE_CB_OK;

err_free:
	info->free(rsp);
	return YNL_PARSE_CB_ERROR;
}

static int
ynl_ntf_trampoline(const struct nlmsghdr *nlh, struct ynl_parse_arg *yarg)
{
	return ynl_ntf_parse(yarg->ys, nlh);
}

int ynl_ntf_check(struct ynl_sock *ys)
{
	struct ynl_parse_arg yarg = { .ys = ys, };
	int err;

	do {
		err = __ynl_sock_read_msgs(&yarg, ynl_ntf_trampoline,
					   MSG_DONTWAIT);
		if (err < 0)
			return err;
	} while (err > 0);

	return 0;
}

/* YNL specific helpers used by the auto-generated code */

struct ynl_dump_list_type *YNL_LIST_END = (void *)(0xb4d123);

void ynl_error_unknown_notification(struct ynl_sock *ys, __u8 cmd)
{
	yerr(ys, YNL_ERROR_UNKNOWN_NTF,
	     "Unknown notification message type '%d'", cmd);
}

int ynl_error_parse(struct ynl_parse_arg *yarg, const char *msg)
{
	yerr(yarg->ys, YNL_ERROR_INV_RESP, "Error parsing response: %s", msg);
	return YNL_PARSE_CB_ERROR;
}

static int
ynl_check_alien(struct ynl_sock *ys, const struct nlmsghdr *nlh, __u32 rsp_cmd)
{
	struct genlmsghdr *gehdr;

	if (ynl_nlmsg_data_len(nlh) < sizeof(*gehdr)) {
		yerr(ys, YNL_ERROR_INV_RESP,
		     "Kernel responded with truncated message");
		return -1;
	}

	gehdr = ynl_nlmsg_data(nlh);
	if (gehdr->cmd != rsp_cmd)
		return ynl_ntf_parse(ys, nlh);

	return 0;
}

static
int ynl_req_trampoline(const struct nlmsghdr *nlh, struct ynl_parse_arg *yarg)
{
	struct ynl_req_state *yrs = (void *)yarg;
	int ret;

	ret = ynl_check_alien(yrs->yarg.ys, nlh, yrs->rsp_cmd);
	if (ret)
		return ret < 0 ? YNL_PARSE_CB_ERROR : YNL_PARSE_CB_OK;

	return yrs->cb(nlh, &yrs->yarg);
}

int ynl_exec(struct ynl_sock *ys, struct nlmsghdr *req_nlh,
	     struct ynl_req_state *yrs)
{
	int err;

	err = ynl_msg_end(ys, req_nlh);
	if (err < 0)
		return err;

	err = send(ys->socket, req_nlh, req_nlh->nlmsg_len, 0);
	if (err < 0)
		return err;

	do {
		err = ynl_sock_read_msgs(&yrs->yarg, ynl_req_trampoline);
	} while (err > 0);

	return err;
}

static int
ynl_dump_trampoline(const struct nlmsghdr *nlh, struct ynl_parse_arg *data)
{
	struct ynl_dump_state *ds = (void *)data;
	struct ynl_dump_list_type *obj;
	struct ynl_parse_arg yarg = {};
	int ret;

	ret = ynl_check_alien(ds->yarg.ys, nlh, ds->rsp_cmd);
	if (ret)
		return ret < 0 ? YNL_PARSE_CB_ERROR : YNL_PARSE_CB_OK;

	obj = calloc(1, ds->alloc_sz);
	if (!obj)
		return YNL_PARSE_CB_ERROR;

	if (!ds->first)
		ds->first = obj;
	if (ds->last)
		ds->last->next = obj;
	ds->last = obj;

	yarg = ds->yarg;
	yarg.data = &obj->data;

	return ds->cb(nlh, &yarg);
}

static void *ynl_dump_end(struct ynl_dump_state *ds)
{
	if (!ds->first)
		return YNL_LIST_END;

	ds->last->next = YNL_LIST_END;
	return ds->first;
}

int ynl_exec_dump(struct ynl_sock *ys, struct nlmsghdr *req_nlh,
		  struct ynl_dump_state *yds)
{
	int err;

	err = ynl_msg_end(ys, req_nlh);
	if (err < 0)
		return err;

	err = send(ys->socket, req_nlh, req_nlh->nlmsg_len, 0);
	if (err < 0)
		return err;

	do {
		err = ynl_sock_read_msgs(&yds->yarg, ynl_dump_trampoline);
		if (err < 0)
			goto err_close_list;
	} while (err > 0);

	yds->first = ynl_dump_end(yds);
	return 0;

err_close_list:
	yds->first = ynl_dump_end(yds);
	return -1;
}
