/* SPDX-License-Identifier: GPL-2.0 */
#include <unistd.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>

#include <netinet/ip.h>
#include <netinet/ip6.h>

#include <linux/if.h>
#include <linux/if_tun.h>
#include <sys/ioctl.h>

#include <linux/netlink.h>
#include <netlink/socket.h>
#include <netlink/route/link.h>
#include <netlink/route/addr.h>
#include <netlink/route/route.h>
#include <netlink/route/nexthop.h>

#include <osmocom/core/utils.h>

/***********************************************************************
 * netlink helper functions
 ***********************************************************************/

static int _netdev_addr(struct nl_sock *nlsk, int ifindex, const struct sockaddr_storage *ss, bool add)
{
	const struct sockaddr_in6 *sin6;
	const struct sockaddr_in *sin;
	struct nl_addr *local = NULL;
	struct rtnl_addr *addr;
	int rc;

	switch (ss->ss_family) {
	case AF_INET:
		sin = (struct sockaddr_in *) ss;
		local = nl_addr_build(AF_INET, &sin->sin_addr, 4);
		break;
	case AF_INET6:
		sin6 = (struct sockaddr_in6 *) ss;
		local = nl_addr_build(AF_INET6, &sin6->sin6_addr, 16);
		break;
	}
	OSMO_ASSERT(local);

	addr = rtnl_addr_alloc();
	OSMO_ASSERT(addr);
	rtnl_addr_set_ifindex(addr, ifindex);
	OSMO_ASSERT(rtnl_addr_set_local(addr, local) == 0);

	if (add)
		rc = rtnl_addr_add(nlsk, addr, 0);
	else
		rc = rtnl_addr_delete(nlsk, addr, 0);

	rtnl_addr_put(addr);

	return rc;
}

int netdev_add_addr(struct nl_sock *nlsk, int ifindex, const struct sockaddr_storage *ss)
{
	return _netdev_addr(nlsk, ifindex, ss, true);
}

int netdev_del_addr(struct nl_sock *nlsk, int ifindex, const struct sockaddr_storage *ss)
{
	return _netdev_addr(nlsk, ifindex, ss, false);
}

int netdev_set_link(struct nl_sock *nlsk, int ifindex, bool up)
{
	struct rtnl_link *link, *change;
	int rc;

	rc = rtnl_link_get_kernel(nlsk, ifindex, NULL, &link);
	if (rc < 0)
		return rc;

	change = rtnl_link_alloc();
	OSMO_ASSERT(change);

	if (up)
		rtnl_link_set_flags(change, IFF_UP);
	else
		rtnl_link_unset_flags(change, IFF_UP);

	rc = rtnl_link_change(nlsk, link, change, 0);

	rtnl_link_put(change);
	rtnl_link_put(link);

	return rc;
}

int netdev_add_defaultroute(struct nl_sock *nlsk, int ifindex, uint8_t family)
{
	struct rtnl_route *route = rtnl_route_alloc();
	struct rtnl_nexthop *nhop = rtnl_route_nh_alloc();
	struct nl_addr *dst, *gw;
	uint8_t buf[16];
	int rc;

	OSMO_ASSERT(route);
	OSMO_ASSERT(nhop);

	/* destination address of route: all-zero */
	memset(buf, 0, sizeof(buf));
	dst = nl_addr_build(family, buf, family == AF_INET ? 4 : 16);
	OSMO_ASSERT(dst);
	nl_addr_set_prefixlen(dst, 0);

	/* gateway address of route: also all-zero */
	gw = nl_addr_clone(dst);
	OSMO_ASSERT(gw);

	/* nexthop for route */
	rtnl_route_nh_set_ifindex(nhop, ifindex);
	rtnl_route_nh_set_gateway(nhop, gw);

	/* tie everything together in the route */
	rtnl_route_set_dst(route, dst);
	rtnl_route_set_family(route, family);
	rtnl_route_add_nexthop(route, nhop);

	rc = rtnl_route_add(nlsk, route, NLM_F_CREATE);

	//rtnl_route_nh_free(nhop);
	nl_addr_put(gw);
	nl_addr_put(dst);
	rtnl_route_put(route);

	return rc;
}
