/* SPDX-License-Identifier: LGPL-2.1-only */
/*
 * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
 */

/**
 * @ingroup route_obj
 * @defgroup nexthop Nexthop
 * @{
 */

#include "nl-default.h"

#include <netlink/netlink.h>
#include <netlink/utils.h>
#include <netlink/route/rtnl.h>
#include <netlink/route/route.h>

#include "nexthop-encap.h"
#include "nl-route.h"
#include "nl-priv-dynamic-core/nl-core.h"

/** @cond SKIP */
#define NH_ATTR_FLAGS   0x000001
#define NH_ATTR_WEIGHT  0x000002
#define NH_ATTR_IFINDEX 0x000004
#define NH_ATTR_GATEWAY 0x000008
#define NH_ATTR_REALMS  0x000010
#define NH_ATTR_NEWDST  0x000020
#define NH_ATTR_VIA     0x000040
#define NH_ATTR_ENCAP   0x000080
/** @endcond */

/**
 * @name Allocation/Freeing
 * @{
 */

struct rtnl_nexthop *rtnl_route_nh_alloc(void)
{
	struct rtnl_nexthop *nh;

	nh = calloc(1, sizeof(*nh));
	if (!nh)
		return NULL;

	nl_init_list_head(&nh->rtnh_list);

	return nh;
}

struct rtnl_nexthop *rtnl_route_nh_clone(struct rtnl_nexthop *src)
{
	struct rtnl_nexthop *nh;

	nh = rtnl_route_nh_alloc();
	if (!nh)
		return NULL;

	nh->rtnh_flags = src->rtnh_flags;
	nh->rtnh_flag_mask = src->rtnh_flag_mask;
	nh->rtnh_weight = src->rtnh_weight;
	nh->rtnh_ifindex = src->rtnh_ifindex;
	nh->ce_mask = src->ce_mask;

	if (src->rtnh_gateway) {
		nh->rtnh_gateway = nl_addr_clone(src->rtnh_gateway);
		if (!nh->rtnh_gateway) {
			free(nh);
			return NULL;
		}
	}

	if (src->rtnh_newdst) {
		nh->rtnh_newdst = nl_addr_clone(src->rtnh_newdst);
		if (!nh->rtnh_newdst) {
			nl_addr_put(nh->rtnh_gateway);
			free(nh);
			return NULL;
		}
	}

	if (src->rtnh_via) {
		nh->rtnh_via = nl_addr_clone(src->rtnh_via);
		if (!nh->rtnh_via) {
			nl_addr_put(nh->rtnh_gateway);
			nl_addr_put(nh->rtnh_newdst);
			free(nh);
			return NULL;
		}
	}

	return nh;
}

void rtnl_route_nh_free(struct rtnl_nexthop *nh)
{
	nl_addr_put(nh->rtnh_gateway);
	nl_addr_put(nh->rtnh_newdst);
	nl_addr_put(nh->rtnh_via);
	if (nh->rtnh_encap) {
		if (nh->rtnh_encap->ops && nh->rtnh_encap->ops->destructor)
			nh->rtnh_encap->ops->destructor(nh->rtnh_encap->priv);
		free(nh->rtnh_encap->priv);
		free(nh->rtnh_encap);
	}
	free(nh);
}

/** @} */

int rtnl_route_nh_compare(struct rtnl_nexthop *a, struct rtnl_nexthop *b,
			  uint32_t attrs, int loose)
{
	uint32_t diff = 0;

#define _DIFF(ATTR, EXPR) ATTR_DIFF(attrs, ATTR, a, b, EXPR)
	diff |= _DIFF(NH_ATTR_IFINDEX, a->rtnh_ifindex != b->rtnh_ifindex);
	diff |= _DIFF(NH_ATTR_WEIGHT, a->rtnh_weight != b->rtnh_weight);
	diff |= _DIFF(NH_ATTR_REALMS, a->rtnh_realms != b->rtnh_realms);
	diff |= _DIFF(NH_ATTR_GATEWAY,
		      nl_addr_cmp(a->rtnh_gateway, b->rtnh_gateway));
	diff |= _DIFF(NH_ATTR_NEWDST,
		      nl_addr_cmp(a->rtnh_newdst, b->rtnh_newdst));
	diff |= _DIFF(NH_ATTR_VIA, nl_addr_cmp(a->rtnh_via, b->rtnh_via));
	diff |= _DIFF(NH_ATTR_ENCAP,
		      nh_encap_compare(a->rtnh_encap, b->rtnh_encap));

	if (loose)
		diff |= _DIFF(NH_ATTR_FLAGS, (a->rtnh_flags ^ b->rtnh_flags) &
						     b->rtnh_flag_mask);
	else
		diff |= _DIFF(NH_ATTR_FLAGS, a->rtnh_flags != b->rtnh_flags);
#undef _DIFF

	return diff;
}

static void nh_dump_line(struct rtnl_nexthop *nh, struct nl_dump_params *dp)
{
	struct nl_cache *link_cache;
	char buf[128];

	link_cache = nl_cache_mngt_require_safe("route/link");

	if (nh->ce_mask & NH_ATTR_ENCAP)
		nh_encap_dump(nh->rtnh_encap, dp);

	if (nh->ce_mask & NH_ATTR_NEWDST)
		nl_dump(dp, "as to %s ",
			nl_addr2str(nh->rtnh_newdst, buf, sizeof(buf)));

	nl_dump(dp, "via");

	if (nh->ce_mask & NH_ATTR_VIA)
		nl_dump(dp, " %s",
			nl_addr2str(nh->rtnh_via, buf, sizeof(buf)));

	if (nh->ce_mask & NH_ATTR_GATEWAY)
		nl_dump(dp, " %s", nl_addr2str(nh->rtnh_gateway,
						   buf, sizeof(buf)));

	if(nh->ce_mask & NH_ATTR_IFINDEX) {
		if (link_cache) {
			nl_dump(dp, " dev %s",
				rtnl_link_i2name(link_cache,
						 nh->rtnh_ifindex,
						 buf, sizeof(buf)));
		} else
			nl_dump(dp, " dev %d", nh->rtnh_ifindex);
	}

	nl_dump(dp, " ");

	if (link_cache)
		nl_cache_put(link_cache);
}

static void nh_dump_details(struct rtnl_nexthop *nh, struct nl_dump_params *dp)
{
	struct nl_cache *link_cache;
	char buf[128];

	link_cache = nl_cache_mngt_require_safe("route/link");

	nl_dump(dp, "nexthop");

	if (nh->ce_mask & NH_ATTR_ENCAP)
		nh_encap_dump(nh->rtnh_encap, dp);

	if (nh->ce_mask & NH_ATTR_NEWDST)
		nl_dump(dp, " as to %s",
			nl_addr2str(nh->rtnh_newdst, buf, sizeof(buf)));

	if (nh->ce_mask & NH_ATTR_VIA)
		nl_dump(dp, " via %s",
			nl_addr2str(nh->rtnh_via, buf, sizeof(buf)));

	if (nh->ce_mask & NH_ATTR_GATEWAY)
		nl_dump(dp, " via %s", nl_addr2str(nh->rtnh_gateway,
						   buf, sizeof(buf)));

	if(nh->ce_mask & NH_ATTR_IFINDEX) {
		if (link_cache) {
			nl_dump(dp, " dev %s",
				rtnl_link_i2name(link_cache,
						 nh->rtnh_ifindex,
						 buf, sizeof(buf)));
		} else
			nl_dump(dp, " dev %d", nh->rtnh_ifindex);
	}

	if (nh->ce_mask & NH_ATTR_WEIGHT)
		nl_dump(dp, " weight %u", nh->rtnh_weight);

	if (nh->ce_mask & NH_ATTR_REALMS)
		nl_dump(dp, " realm %04x:%04x",
			RTNL_REALM_FROM(nh->rtnh_realms),
			RTNL_REALM_TO(nh->rtnh_realms));

	if (nh->ce_mask & NH_ATTR_FLAGS)
		nl_dump(dp, " <%s>", rtnl_route_nh_flags2str(nh->rtnh_flags,
							buf, sizeof(buf)));

	if (link_cache)
		nl_cache_put(link_cache);
}

void rtnl_route_nh_dump(struct rtnl_nexthop *nh, struct nl_dump_params *dp)
{
	switch (dp->dp_type) {
	case NL_DUMP_LINE:
		nh_dump_line(nh, dp);
		break;

	case NL_DUMP_DETAILS:
	case NL_DUMP_STATS:
		if (dp->dp_ivar == NH_DUMP_FROM_DETAILS)
			nh_dump_details(nh, dp);
		break;

	default:
		break;
	}
}

void nh_set_encap(struct rtnl_nexthop *nh, struct rtnl_nh_encap *rtnh_encap)
{
	if (nh->rtnh_encap) {
		if (nh->rtnh_encap->ops && nh->rtnh_encap->ops->destructor)
			nh->rtnh_encap->ops->destructor(nh->rtnh_encap->priv);
		free(nh->rtnh_encap->priv);
		free(nh->rtnh_encap);
	}

	if (rtnh_encap) {
		nh->rtnh_encap = rtnh_encap;
		nh->ce_mask |= NH_ATTR_ENCAP;
	} else {
		nh->rtnh_encap = NULL;
		nh->ce_mask &= ~NH_ATTR_ENCAP;
	}
}

/**
 * @name Attributes
 * @{
 */

void rtnl_route_nh_set_weight(struct rtnl_nexthop *nh, uint8_t weight)
{
	nh->rtnh_weight = weight;
	nh->ce_mask |= NH_ATTR_WEIGHT;
}

uint8_t rtnl_route_nh_get_weight(struct rtnl_nexthop *nh)
{
	return nh->rtnh_weight;
}

void rtnl_route_nh_set_ifindex(struct rtnl_nexthop *nh, int ifindex)
{
	nh->rtnh_ifindex = ifindex;
	nh->ce_mask |= NH_ATTR_IFINDEX;
}

int rtnl_route_nh_get_ifindex(struct rtnl_nexthop *nh)
{
	return nh->rtnh_ifindex;
}	

/* FIXME: Convert to return an int */
void rtnl_route_nh_set_gateway(struct rtnl_nexthop *nh, struct nl_addr *addr)
{
	struct nl_addr *old = nh->rtnh_gateway;

	if (addr) {
		nh->rtnh_gateway = nl_addr_get(addr);
		nh->ce_mask |= NH_ATTR_GATEWAY;
	} else {
		nh->ce_mask &= ~NH_ATTR_GATEWAY;
		nh->rtnh_gateway = NULL;
	}

	if (old)
		nl_addr_put(old);
}

struct nl_addr *rtnl_route_nh_get_gateway(struct rtnl_nexthop *nh)
{
	return nh->rtnh_gateway;
}

void rtnl_route_nh_set_flags(struct rtnl_nexthop *nh, unsigned int flags)
{
	nh->rtnh_flag_mask |= flags;
	nh->rtnh_flags |= flags;
	nh->ce_mask |= NH_ATTR_FLAGS;
}

void rtnl_route_nh_unset_flags(struct rtnl_nexthop *nh, unsigned int flags)
{
	nh->rtnh_flag_mask |= flags;
	nh->rtnh_flags &= ~flags;
	nh->ce_mask |= NH_ATTR_FLAGS;
}

unsigned int rtnl_route_nh_get_flags(struct rtnl_nexthop *nh)
{
	return nh->rtnh_flags;
}

void rtnl_route_nh_set_realms(struct rtnl_nexthop *nh, uint32_t realms)
{
	nh->rtnh_realms = realms;
	nh->ce_mask |= NH_ATTR_REALMS;
}

uint32_t rtnl_route_nh_get_realms(struct rtnl_nexthop *nh)
{
	return nh->rtnh_realms;
}

int rtnl_route_nh_set_newdst(struct rtnl_nexthop *nh, struct nl_addr *addr)
{
	struct nl_addr *old = nh->rtnh_newdst;

	if (addr) {
		nh->rtnh_newdst = nl_addr_get(addr);
		nh->ce_mask |= NH_ATTR_NEWDST;
	} else {
		nh->ce_mask &= ~NH_ATTR_NEWDST;
		nh->rtnh_newdst = NULL;
	}

	if (old)
		nl_addr_put(old);

	return 0;
}

struct nl_addr *rtnl_route_nh_get_newdst(struct rtnl_nexthop *nh)
{
	return nh->rtnh_newdst;
}

int rtnl_route_nh_set_via(struct rtnl_nexthop *nh, struct nl_addr *addr)
{
	struct nl_addr *old = nh->rtnh_via;

	if (addr) {
		nh->rtnh_via = nl_addr_get(addr);
		nh->ce_mask |= NH_ATTR_VIA;
	} else {
		nh->ce_mask &= ~NH_ATTR_VIA;
		nh->rtnh_via= NULL;
	}

	if (old)
		nl_addr_put(old);

	return 0;
}

struct nl_addr *rtnl_route_nh_get_via(struct rtnl_nexthop *nh)
{
	return nh->rtnh_via;
}

/** @} */

/**
 * @name Nexthop Flags Translations
 * @{
 */

static const struct trans_tbl nh_flags[] = {
	__ADD(RTNH_F_DEAD, dead),
	__ADD(RTNH_F_PERVASIVE, pervasive),
	__ADD(RTNH_F_ONLINK, onlink),
};

char *rtnl_route_nh_flags2str(int flags, char *buf, size_t len)
{
	return __flags2str(flags, buf, len, nh_flags, ARRAY_SIZE(nh_flags));
}

int rtnl_route_nh_str2flags(const char *name)
{
	return __str2flags(name, nh_flags, ARRAY_SIZE(nh_flags));
}

/** @} */

/** @} */
