/* NHRP interface
 * Copyright (c) 2014-2015 Timo Teräs
 *
 * This file is free software: you may copy, redistribute and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 */

#include <net/if_arp.h>
#include "zebra.h"
#include "linklist.h"
#include "memory.h"
#include "thread.h"

#include "nhrpd.h"
#include "os.h"
#include "netlink.h"

static int nhrp_if_new_hook(struct interface *ifp)
{
	struct nhrp_interface *nifp;
	afi_t afi;

	nifp = XCALLOC(MTYPE_NHRP_IF, sizeof(struct nhrp_interface));
	if (!nifp) return 0;

	ifp->info = nifp;
	nifp->ifp = ifp;

	notifier_init(&nifp->notifier_list);
	for (afi = 0; afi < AFI_MAX; afi++) {
		struct nhrp_afi_data *ad = &nifp->afi[afi];
		ad->holdtime = NHRPD_DEFAULT_HOLDTIME;
		list_init(&ad->nhslist_head);
	}

	return 0;
}

static int nhrp_if_delete_hook(struct interface *ifp)
{
	XFREE(MTYPE_NHRP_IF, ifp->info);
	return 0;
}

void nhrp_interface_init(void)
{
	if_add_hook(IF_NEW_HOOK,    nhrp_if_new_hook);
	if_add_hook(IF_DELETE_HOOK, nhrp_if_delete_hook);
}

void nhrp_interface_update_mtu(struct interface *ifp, afi_t afi)
{
	struct nhrp_interface *nifp = ifp->info;
	struct nhrp_afi_data *if_ad = &nifp->afi[afi];
	unsigned short new_mtu;

	if (if_ad->configured_mtu < 0)
		new_mtu = nifp->nbmaifp ? nifp->nbmaifp->mtu : 0;
	else
		new_mtu = if_ad->configured_mtu;
	if (new_mtu >= 1500)
		new_mtu = 0;

	if (new_mtu != if_ad->mtu) {
		debugf(NHRP_DEBUG_IF, "%s: MTU changed to %d", ifp->name, new_mtu);
		if_ad->mtu = new_mtu;
		notifier_call(&nifp->notifier_list, NOTIFY_INTERFACE_MTU_CHANGED);
	}
}

static void nhrp_interface_update_source(struct interface *ifp)
{
	struct nhrp_interface *nifp = ifp->info;

	if (!nifp->source || !nifp->nbmaifp ||
	    nifp->linkidx == nifp->nbmaifp->ifindex)
		return;

	nifp->linkidx = nifp->nbmaifp->ifindex;
	debugf(NHRP_DEBUG_IF, "%s: bound device index changed to %d", ifp->name, nifp->linkidx);
	netlink_gre_set_link(ifp->ifindex, nifp->linkidx);
}

static void nhrp_interface_interface_notifier(struct notifier_block *n, unsigned long cmd)
{
	struct nhrp_interface *nifp = container_of(n, struct nhrp_interface, nbmanifp_notifier);
	struct interface *nbmaifp = nifp->nbmaifp;
	struct nhrp_interface *nbmanifp = nbmaifp->info;
	char buf[SU_ADDRSTRLEN];

	switch (cmd) {
	case NOTIFY_INTERFACE_CHANGED:
		nhrp_interface_update_mtu(nifp->ifp, AFI_IP);
		nhrp_interface_update_source(nifp->ifp);
		break;
	case NOTIFY_INTERFACE_ADDRESS_CHANGED:
		nifp->nbma = nbmanifp->afi[AFI_IP].addr;
		nhrp_interface_update(nifp->ifp);
		notifier_call(&nifp->notifier_list, NOTIFY_INTERFACE_NBMA_CHANGED);
		debugf(NHRP_DEBUG_IF, "%s: NBMA change: address %s",
			nifp->ifp->name,
			sockunion2str(&nifp->nbma, buf, sizeof buf));
		break;
	}
}

static void nhrp_interface_update_nbma(struct interface *ifp)
{
	struct nhrp_interface *nifp = ifp->info, *nbmanifp = NULL;
	struct interface *nbmaifp = NULL;
	union sockunion nbma;

	sockunion_family(&nbma) = AF_UNSPEC;

	if (nifp->source)
		nbmaifp = if_lookup_by_name(nifp->source);

	switch (ifp->ll_type) {
	case ZEBRA_LLT_IPGRE: {
			struct in_addr saddr = {0};
			netlink_gre_get_info(ifp->ifindex, &nifp->grekey, &nifp->linkidx, &saddr);
			debugf(NHRP_DEBUG_IF, "%s: GRE: %x %x %x", ifp->name, nifp->grekey, nifp->linkidx, saddr.s_addr);
			if (saddr.s_addr)
				sockunion_set(&nbma, AF_INET, (u_char *) &saddr.s_addr, sizeof(saddr.s_addr));
			else if (!nbmaifp && nifp->linkidx != IFINDEX_INTERNAL)
				nbmaifp = if_lookup_by_index(nifp->linkidx);
		}
		break;
	default:
		break;
	}

	if (nbmaifp)
		nbmanifp = nbmaifp->info;

	if (nbmaifp != nifp->nbmaifp) {
		if (nifp->nbmaifp)
			notifier_del(&nifp->nbmanifp_notifier);
		nifp->nbmaifp = nbmaifp;
		if (nbmaifp) {
			notifier_add(&nifp->nbmanifp_notifier, &nbmanifp->notifier_list, nhrp_interface_interface_notifier);
			debugf(NHRP_DEBUG_IF, "%s: bound to %s", ifp->name, nbmaifp->name);
		}
	}

	if (nbmaifp) {
		if (sockunion_family(&nbma) == AF_UNSPEC)
			nbma = nbmanifp->afi[AFI_IP].addr;
		nhrp_interface_update_mtu(ifp, AFI_IP);
		nhrp_interface_update_source(ifp);
	}

	if (!sockunion_same(&nbma, &nifp->nbma)) {
		nifp->nbma = nbma;
		nhrp_interface_update(nifp->ifp);
		debugf(NHRP_DEBUG_IF, "%s: NBMA address changed", ifp->name);
		notifier_call(&nifp->notifier_list, NOTIFY_INTERFACE_NBMA_CHANGED);
	}

	nhrp_interface_update(ifp);
}

static void nhrp_interface_update_address(struct interface *ifp, afi_t afi, int force)
{
	const int family = afi2family(afi);
	struct nhrp_interface *nifp = ifp->info;
	struct nhrp_afi_data *if_ad = &nifp->afi[afi];
	struct nhrp_cache *nc;
	struct connected *c, *best;
	struct listnode *cnode;
	union sockunion addr;
	char buf[PREFIX_STRLEN];

	/* Select new best match preferring primary address */
	best = NULL;
	for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, c)) {
		if (PREFIX_FAMILY(c->address) != family)
			continue;
		if (best == NULL) {
			best = c;
			continue;
		}
		if ((best->flags & ZEBRA_IFA_SECONDARY) && !(c->flags & ZEBRA_IFA_SECONDARY)) {
			best = c;
			continue;
		}
		if (!(best->flags & ZEBRA_IFA_SECONDARY) && (c->flags & ZEBRA_IFA_SECONDARY))
			continue;
		if (best->address->prefixlen > c->address->prefixlen) {
			best = c;
			continue;
		}
		if (best->address->prefixlen < c->address->prefixlen)
			continue;
	}

	/* On NHRP interfaces a host prefix is required */
	if (best && if_ad->configured && best->address->prefixlen != 8 * prefix_blen(best->address)) {
		zlog_notice("%s: %s is not a host prefix", ifp->name,
			prefix2str(best->address, buf, sizeof buf));
		best = NULL;
	}

	/* Update address if it changed */
	if (best)
		prefix2sockunion(best->address, &addr);
	else
		memset(&addr, 0, sizeof(addr));

	if (!force && sockunion_same(&if_ad->addr, &addr))
		return;

	if (sockunion_family(&if_ad->addr) != AF_UNSPEC) {
		nc = nhrp_cache_get(ifp, &if_ad->addr, 0);
		if (nc) nhrp_cache_update_binding(nc, NHRP_CACHE_LOCAL, -1, NULL, 0, NULL);
	}

	debugf(NHRP_DEBUG_KERNEL, "%s: IPv%d address changed to %s",
		ifp->name, afi == AFI_IP ? 4 : 6,
		best ? prefix2str(best->address, buf, sizeof buf) : "(none)");
	if_ad->addr = addr;

	if (if_ad->configured && sockunion_family(&if_ad->addr) != AF_UNSPEC) {
		nc = nhrp_cache_get(ifp, &addr, 1);
		if (nc) nhrp_cache_update_binding(nc, NHRP_CACHE_LOCAL, 0, NULL, 0, NULL);
	}

	notifier_call(&nifp->notifier_list, NOTIFY_INTERFACE_ADDRESS_CHANGED);
}

void nhrp_interface_update(struct interface *ifp)
{
	struct nhrp_interface *nifp = ifp->info;
	struct nhrp_afi_data *if_ad;
	afi_t afi;
	int enabled = 0;

	notifier_call(&nifp->notifier_list, NOTIFY_INTERFACE_CHANGED);

	for (afi = 0; afi < AFI_MAX; afi++) {
		if_ad = &nifp->afi[afi];

		if (sockunion_family(&nifp->nbma) == AF_UNSPEC ||
		    ifp->ifindex == IFINDEX_INTERNAL || !if_is_up(ifp) ||
		    !if_ad->network_id) {
			if (if_ad->configured) {
				if_ad->configured = 0;
				nhrp_interface_update_address(ifp, afi, 1);
			}
			continue;
		}

		if (!if_ad->configured) {
			os_configure_dmvpn(ifp->ifindex, ifp->name, afi2family(afi));
			if_ad->configured = 1;
			nhrp_interface_update_address(ifp, afi, 1);
		}

		enabled = 1;
	}

	if (enabled != nifp->enabled) {
		nifp->enabled = enabled;
		notifier_call(&nifp->notifier_list, enabled ? NOTIFY_INTERFACE_UP : NOTIFY_INTERFACE_DOWN);
	}
}

int nhrp_interface_add(int cmd, struct zclient *client, zebra_size_t length, vrf_id_t vrf_id)
{
	struct interface *ifp;

	/* read and add the interface in the iflist. */
	ifp = zebra_interface_add_read(client->ibuf, vrf_id);
	if (ifp == NULL)
		return 0;

	debugf(NHRP_DEBUG_IF, "if-add: %s, ifindex: %u, hw_type: %d %s",
		ifp->name, ifp->ifindex,
		ifp->ll_type, if_link_type_str(ifp->ll_type));

	nhrp_interface_update_nbma(ifp);

	return 0;
}

int nhrp_interface_delete(int cmd, struct zclient *client,
			  zebra_size_t length, vrf_id_t vrf_id)
{
	struct interface *ifp;
	struct stream *s;

	s = client->ibuf;
	ifp = zebra_interface_state_read(s, vrf_id);
	if (ifp == NULL)
		return 0;

	debugf(NHRP_DEBUG_IF, "if-delete: %s", ifp->name);
	ifp->ifindex = IFINDEX_INTERNAL;
	nhrp_interface_update(ifp);
	/* if_delete(ifp); */
	return 0;
}

int nhrp_interface_up(int cmd, struct zclient *client,
		      zebra_size_t length, vrf_id_t vrf_id)
{
	struct interface *ifp;

	ifp = zebra_interface_state_read(client->ibuf, vrf_id);
	if (ifp == NULL)
		return 0;

	debugf(NHRP_DEBUG_IF, "if-up: %s", ifp->name);
	nhrp_interface_update_nbma(ifp);

	return 0;
}

int nhrp_interface_down(int cmd, struct zclient *client,
			zebra_size_t length, vrf_id_t vrf_id)
{
	struct interface *ifp;

	ifp = zebra_interface_state_read(client->ibuf, vrf_id);
	if (ifp == NULL)
		return 0;

	debugf(NHRP_DEBUG_IF, "if-down: %s", ifp->name);
	nhrp_interface_update(ifp);
	return 0;
}

int nhrp_interface_address_add(int cmd, struct zclient *client,
			       zebra_size_t length, vrf_id_t vrf_id)
{
	struct connected *ifc;
	char buf[PREFIX_STRLEN];

	ifc = zebra_interface_address_read(cmd, client->ibuf, vrf_id);
	if (ifc == NULL)
		return 0;

	debugf(NHRP_DEBUG_IF, "if-addr-add: %s: %s",
		ifc->ifp->name,
		prefix2str(ifc->address, buf, sizeof buf));

	nhrp_interface_update_address(ifc->ifp, family2afi(PREFIX_FAMILY(ifc->address)), 0);

	return 0;
}

int nhrp_interface_address_delete(int cmd, struct zclient *client,
				  zebra_size_t length, vrf_id_t vrf_id)
{
	struct connected *ifc;
	char buf[PREFIX_STRLEN];

	ifc = zebra_interface_address_read(cmd, client->ibuf, vrf_id);
	if (ifc == NULL)
		return 0;

	debugf(NHRP_DEBUG_IF, "if-addr-del: %s: %s",
		ifc->ifp->name,
		prefix2str(ifc->address, buf, sizeof buf));

	nhrp_interface_update_address(ifc->ifp, family2afi(PREFIX_FAMILY(ifc->address)), 0);
	connected_free(ifc);

	return 0;
}

void nhrp_interface_notify_add(struct interface *ifp, struct notifier_block *n, notifier_fn_t fn)
{
	struct nhrp_interface *nifp = ifp->info;
	notifier_add(n, &nifp->notifier_list, fn);
}

void nhrp_interface_notify_del(struct interface *ifp, struct notifier_block *n)
{
	notifier_del(n);
}

void nhrp_interface_set_protection(struct interface *ifp, const char *profile, const char *fallback_profile)
{
	struct nhrp_interface *nifp = ifp->info;

	if (nifp->ipsec_profile) free(nifp->ipsec_profile);
	nifp->ipsec_profile = profile ? strdup(profile) : NULL;

	if (nifp->ipsec_fallback_profile) free(nifp->ipsec_fallback_profile);
	nifp->ipsec_fallback_profile = fallback_profile ? strdup(fallback_profile) : NULL;
}

void nhrp_interface_set_source(struct interface *ifp, const char *ifname)
{
	struct nhrp_interface *nifp = ifp->info;

	if (nifp->source) free(nifp->source);
	nifp->source = ifname ? strdup(ifname) : NULL;

	nhrp_interface_update_nbma(ifp);
}
