/* SPDX-License-Identifier: LGPL-2.1-only */
/*
 * Copyright (c) 2013 Cong Wang <xiyou.wangcong@gmail.com>
 */

/**
 * @ingroup link
 * @defgroup veth VETH
 * Virtual Ethernet
 *
 * @details
 * \b Link Type Name: "veth"
 *
 * @route_doc{link_veth, VETH Documentation}
 *
 * @{
 */

#include "nl-default.h"

#include <linux/if_link.h>
#include <linux/veth.h>

#include <netlink/netlink.h>
#include <netlink/attr.h>
#include <netlink/utils.h>
#include <netlink/object.h>
#include <netlink/route/rtnl.h>
#include <netlink/route/link/veth.h>

#include "nl-route.h"
#include "link-api.h"

static struct nla_policy veth_policy[VETH_INFO_MAX+1] = {
	[VETH_INFO_PEER]	= { .minlen = sizeof(struct ifinfomsg) },
};

static int veth_parse(struct rtnl_link *link, struct nlattr *data,
		      struct nlattr *xstats)
{
	struct nlattr *tb[VETH_INFO_MAX+1];
	struct nlattr *peer_tb[IFLA_MAX + 1];
	struct rtnl_link *peer = link->l_info;
	int err;

	NL_DBG(3, "Parsing veth link info\n");

	if ((err = nla_parse_nested(tb, VETH_INFO_MAX, data, veth_policy)) < 0)
		goto errout;

	if (tb[VETH_INFO_PEER]) {
		struct nlattr *nla_peer;
		struct ifinfomsg *ifi;

		nla_peer = tb[VETH_INFO_PEER];
		ifi = nla_data(nla_peer);

		peer->l_family = ifi->ifi_family;
		peer->l_arptype = ifi->ifi_type;
		peer->l_index = ifi->ifi_index;
		peer->l_flags = ifi->ifi_flags;
		peer->l_change = ifi->ifi_change;
		err = nla_parse(peer_tb, IFLA_MAX, (struct nlattr *)
		                ((char *) nla_data(nla_peer) + sizeof(struct ifinfomsg)),
				nla_len(nla_peer) - sizeof(struct ifinfomsg),
				rtln_link_policy);
		if (err < 0)
			goto errout;

		err = rtnl_link_info_parse(peer, peer_tb);
		if (err < 0)
			goto errout;
	}

	err = 0;

errout:
	return err;
}

static void veth_dump_line(struct rtnl_link *link, struct nl_dump_params *p)
{
}

static void veth_dump_details(struct rtnl_link *link, struct nl_dump_params *p)
{
	struct rtnl_link *peer = link->l_info;
	char *name;
	name = rtnl_link_get_name(peer);
	nl_dump(p, "      peer ");
	if (name)
		nl_dump_line(p, "%s\n", name);
	else
		nl_dump_line(p, "%u\n", peer->l_index);
}

static int veth_clone(struct rtnl_link *dst, struct rtnl_link *src)
{
	struct rtnl_link *dst_peer = NULL, *src_peer = src->l_info;

	/* we are calling nl_object_clone() recursively, this should
	 * happen only once */
	if (src_peer) {
		src_peer->l_info = NULL;
		dst_peer = (struct rtnl_link *)nl_object_clone(OBJ_CAST(src_peer));
		if (!dst_peer)
			return -NLE_NOMEM;
		src_peer->l_info = src;
		dst_peer->l_info = dst;
	}
	dst->l_info = dst_peer;
	return 0;
}

static int veth_put_attrs(struct nl_msg *msg, struct rtnl_link *link)
{
	struct rtnl_link *peer = link->l_info;
	struct ifinfomsg ifi;
	struct nlattr *data, *info_peer;

	memset(&ifi, 0, sizeof ifi);
	ifi.ifi_family = peer->l_family;
	ifi.ifi_type = peer->l_arptype;
	ifi.ifi_index = peer->l_index;
	ifi.ifi_flags = peer->l_flags;
	ifi.ifi_change = peer->l_change;

	if (!(data = nla_nest_start(msg, IFLA_INFO_DATA)))
		return -NLE_MSGSIZE;
	if (!(info_peer = nla_nest_start(msg, VETH_INFO_PEER)))
		return -NLE_MSGSIZE;
	if (nlmsg_append(msg, &ifi, sizeof(ifi), NLMSG_ALIGNTO) < 0)
		return -NLE_MSGSIZE;
	rtnl_link_fill_info(msg, peer);
	nla_nest_end(msg, info_peer);
	nla_nest_end(msg, data);

	return 0;
}

static int veth_alloc(struct rtnl_link *link)
{
	struct rtnl_link *peer;
	int err;

	/* return early if we are in recursion */
	if (link->l_info)
		return 0;

	if (!(peer = rtnl_link_alloc()))
		return -NLE_NOMEM;

	/* We don't need to hold a reference here, as link and
	 * its peer should always be freed together.
	 */
	peer->l_info = link;
	if ((err = rtnl_link_set_type(peer, "veth")) < 0) {
		rtnl_link_put(peer);
		return err;
	}

	link->l_info = peer;
	return 0;
}

static void veth_free(struct rtnl_link *link)
{
	struct rtnl_link *peer = link->l_info;
	if (peer) {
		link->l_info = NULL;
		/* avoid calling this recursively */
		peer->l_info = NULL;
		rtnl_link_put(peer);
	}
	/* the caller should finally free link */
}

static struct rtnl_link_info_ops veth_info_ops = {
	.io_name		= "veth",
	.io_parse		= veth_parse,
	.io_dump = {
	    [NL_DUMP_LINE]	= veth_dump_line,
	    [NL_DUMP_DETAILS]	= veth_dump_details,
	},
	.io_alloc		= veth_alloc,
	.io_clone		= veth_clone,
	.io_put_attrs		= veth_put_attrs,
	.io_free		= veth_free,
};

/** @cond SKIP */

#define IS_VETH_LINK_ASSERT(link) \
	if ((link)->l_info_ops != &veth_info_ops) { \
		APPBUG("Link is not a veth link. set type \"veth\" first."); \
		return NULL; \
	}
/** @endcond */

/**
 * @name VETH Object
 * @{
 */

/**
 * Allocate link object of type veth
 *
 * @return Allocated link object or NULL.
 */
struct rtnl_link *rtnl_link_veth_alloc(void)
{
	struct rtnl_link *link;

	if (!(link = rtnl_link_alloc()))
		return NULL;
	if (rtnl_link_set_type(link, "veth") < 0) {
		rtnl_link_put(link);
		return NULL;
	}

	return link;
}

/**
 * Get the peer link of a veth link
 *
 * @return the peer link object.
 */
struct rtnl_link *rtnl_link_veth_get_peer(struct rtnl_link *link)
{
	IS_VETH_LINK_ASSERT(link);
	nl_object_get(OBJ_CAST(link->l_info));
	return link->l_info;
}

/**
 * Release a veth link and its peer
 *
 */
void rtnl_link_veth_release(struct rtnl_link *link)
{
	veth_free(link);
	rtnl_link_put(link);
}

/**
 * Check if link is a veth link
 * @arg link		Link object
 *
 * @return True if link is a veth link, otherwise false is returned.
 */
int rtnl_link_is_veth(struct rtnl_link *link)
{
	return link->l_info_ops && !strcmp(link->l_info_ops->io_name, "veth");
}

/**
 * Create a new kernel veth device
 * @arg sock		netlink socket
 * @arg name		name of the veth device or NULL
 * @arg peer_name	name of its peer or NULL
 * @arg pid		pid of the process in the new netns
 *
 * Creates a new veth device pair in the kernel and move the peer
 * to the network namespace where the process is. If no name is
 * provided, the kernel will automatically pick a name of the
 * form "veth%d" (e.g. veth0, veth1, etc.)
 *
 * @return 0 on success or a negative error code
 */
int rtnl_link_veth_add(struct nl_sock *sock, const char *name,
                       const char *peer_name, pid_t pid)
{
	struct rtnl_link *link, *peer;
	int err = -NLE_NOMEM;

	if (!(link = rtnl_link_veth_alloc()))
		return -NLE_NOMEM;
	peer = link->l_info;

	if (name)
		rtnl_link_set_name(link, name);
	if (peer_name)
		rtnl_link_set_name(peer, peer_name);

	rtnl_link_set_ns_pid(peer, pid);
	err = rtnl_link_add(sock, link, NLM_F_CREATE | NLM_F_EXCL);

	rtnl_link_put(link);
	return err;
}

/** @} */

static void _nl_init veth_init(void)
{
	rtnl_link_register_info(&veth_info_ops);
}

static void _nl_exit veth_exit(void)
{
	rtnl_link_unregister_info(&veth_info_ops);
}

/** @} */
