/* NHRP shortcut related functions
 * 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 "nhrpd.h"
#include "table.h"
#include "memory.h"
#include "thread.h"
#include "log.h"
#include "nhrp_protocol.h"

static struct route_table *shortcut_rib[AFI_MAX];

static int nhrp_shortcut_do_purge(struct thread *t);
static void nhrp_shortcut_delete(struct nhrp_shortcut *s);
static void nhrp_shortcut_send_resolution_req(struct nhrp_shortcut *s);

static void nhrp_shortcut_check_use(struct nhrp_shortcut *s)
{
	char buf[PREFIX_STRLEN];

	if (s->expiring && s->cache && s->cache->used) {
		debugf(NHRP_DEBUG_ROUTE, "Shortcut %s used and expiring",
			prefix2str(s->p, buf, sizeof buf));
		nhrp_shortcut_send_resolution_req(s);
	}
}

static int nhrp_shortcut_do_expire(struct thread *t)
{
	struct nhrp_shortcut *s = THREAD_ARG(t);

	s->t_timer = NULL;
	THREAD_TIMER_ON(master, s->t_timer, nhrp_shortcut_do_purge, s, s->holding_time/3);
	s->expiring = 1;
	nhrp_shortcut_check_use(s);

	return 0;
}

static void nhrp_shortcut_cache_notify(struct notifier_block *n, unsigned long cmd)
{
	struct nhrp_shortcut *s = container_of(n, struct nhrp_shortcut, cache_notifier);

	switch (cmd) {
	case NOTIFY_CACHE_UP:
		if (!s->route_installed) {
			nhrp_route_announce(1, s->type, s->p, NULL, &s->cache->remote_addr, 0);
			s->route_installed = 1;
		}
		break;
	case NOTIFY_CACHE_USED:
		nhrp_shortcut_check_use(s);
		break;
	case NOTIFY_CACHE_DOWN:
	case NOTIFY_CACHE_DELETE:
		if (s->route_installed) {
			nhrp_route_announce(0, NHRP_CACHE_INVALID, s->p, NULL, NULL, 0);
			s->route_installed = 0;
		}
		if (cmd == NOTIFY_CACHE_DELETE)
			nhrp_shortcut_delete(s);
		break;
	}
}

static void nhrp_shortcut_update_binding(struct nhrp_shortcut *s, enum nhrp_cache_type type, struct nhrp_cache *c, int holding_time)
{
	s->type = type;
	if (c != s->cache) {
		if (s->cache) {
			nhrp_cache_notify_del(s->cache, &s->cache_notifier);
			s->cache = NULL;
		}
		s->cache = c;
		if (s->cache) {
			nhrp_cache_notify_add(s->cache, &s->cache_notifier, nhrp_shortcut_cache_notify);
			if (s->cache->route_installed) {
				/* Force renewal of Zebra announce on prefix change */
				s->route_installed = 0;
				nhrp_shortcut_cache_notify(&s->cache_notifier, NOTIFY_CACHE_UP);
			}
		}
		if (!s->cache || !s->cache->route_installed)
			nhrp_shortcut_cache_notify(&s->cache_notifier, NOTIFY_CACHE_DOWN);
	}
	if (s->type == NHRP_CACHE_NEGATIVE && !s->route_installed) {
		nhrp_route_announce(1, s->type, s->p, NULL, NULL, 0);
		s->route_installed = 1;
	} else if (s->type == NHRP_CACHE_INVALID && s->route_installed) {
		nhrp_route_announce(0, NHRP_CACHE_INVALID, s->p, NULL, NULL, 0);
		s->route_installed = 0;
	}

	THREAD_OFF(s->t_timer);
	if (holding_time) {
		s->expiring = 0;
		s->holding_time = holding_time;
		THREAD_TIMER_ON(master, s->t_timer, nhrp_shortcut_do_expire, s, 2*holding_time/3);
	}
}

static void nhrp_shortcut_delete(struct nhrp_shortcut *s)
{
	struct route_node *rn;
	afi_t afi = family2afi(PREFIX_FAMILY(s->p));
	char buf[PREFIX_STRLEN];

	THREAD_OFF(s->t_timer);
	nhrp_reqid_free(&nhrp_packet_reqid, &s->reqid);

	debugf(NHRP_DEBUG_ROUTE, "Shortcut %s purged",
		prefix2str(s->p, buf, sizeof buf));

	nhrp_shortcut_update_binding(s, NHRP_CACHE_INVALID, NULL, 0);

	/* Delete node */
	rn = route_node_lookup(shortcut_rib[afi], s->p);
	if (rn) {
		XFREE(MTYPE_NHRP_SHORTCUT, rn->info);
		rn->info = NULL;
		route_unlock_node(rn);
		route_unlock_node(rn);
	}
}

static int nhrp_shortcut_do_purge(struct thread *t)
{
	struct nhrp_shortcut *s = THREAD_ARG(t);
	s->t_timer = NULL;
	nhrp_shortcut_delete(s);
	return 0;
}

static struct nhrp_shortcut *nhrp_shortcut_get(struct prefix *p)
{
	struct nhrp_shortcut *s;
	struct route_node *rn;
	char buf[PREFIX_STRLEN];
	afi_t afi = family2afi(PREFIX_FAMILY(p));

	if (!shortcut_rib[afi])
		return 0;

	rn = route_node_get(shortcut_rib[afi], p);
	if (!rn->info) {
		s = rn->info = XCALLOC(MTYPE_NHRP_SHORTCUT, sizeof(struct nhrp_shortcut));
		s->type = NHRP_CACHE_INVALID;
		s->p = &rn->p;

		debugf(NHRP_DEBUG_ROUTE, "Shortcut %s created",
			prefix2str(s->p, buf, sizeof buf));
	} else {
		s = rn->info;
		route_unlock_node(rn);
	}
	return s;
}

static void nhrp_shortcut_recv_resolution_rep(struct nhrp_reqid *reqid, void *arg)
{
	struct nhrp_packet_parser *pp = arg;
	struct nhrp_shortcut *s = container_of(reqid, struct nhrp_shortcut, reqid);
	struct nhrp_shortcut *ps;
	struct nhrp_extension_header *ext;
	struct nhrp_cie_header *cie;
	struct nhrp_cache *c = NULL;
	union sockunion *proto, cie_proto, *nbma, *nbma_natoa, cie_nbma, nat_nbma;
	struct prefix prefix, route_prefix;
	struct zbuf extpl;
	char bufp[PREFIX_STRLEN], buf[3][SU_ADDRSTRLEN];
	int holding_time = pp->if_ad->holdtime;

	nhrp_reqid_free(&nhrp_packet_reqid, &s->reqid);
	THREAD_OFF(s->t_timer);
	THREAD_TIMER_ON(master, s->t_timer, nhrp_shortcut_do_purge, s, 1);

	if (pp->hdr->type != NHRP_PACKET_RESOLUTION_REPLY) {
		if (pp->hdr->type == NHRP_PACKET_ERROR_INDICATION &&
		    pp->hdr->u.error.code == NHRP_ERROR_PROTOCOL_ADDRESS_UNREACHABLE) {
			debugf(NHRP_DEBUG_COMMON, "Shortcut: Resolution: Protocol address unreachable");
			nhrp_shortcut_update_binding(s, NHRP_CACHE_NEGATIVE, NULL, holding_time);
		} else {
			debugf(NHRP_DEBUG_COMMON, "Shortcut: Resolution failed");
		}
		return;
	}

	/* Parse extensions */
	memset(&nat_nbma, 0, sizeof nat_nbma);
	while ((ext = nhrp_ext_pull(&pp->extensions, &extpl)) != NULL) {
		switch (htons(ext->type) & ~NHRP_EXTENSION_FLAG_COMPULSORY) {
		case NHRP_EXTENSION_NAT_ADDRESS:
			nhrp_cie_pull(&extpl, pp->hdr, &nat_nbma, &cie_proto);
			break;
		}
	}

	/* Minor sanity check */
	prefix2sockunion(s->p, &cie_proto);
	if (!sockunion_same(&cie_proto, &pp->dst_proto)) {
		debugf(NHRP_DEBUG_COMMON, "Shortcut: Warning dst_proto altered from %s to %s",
			sockunion2str(&cie_proto, buf[0], sizeof buf[0]),
			sockunion2str(&pp->dst_proto, buf[1], sizeof buf[1]));
	}

	/* One or more CIEs should be given as reply, we support only one */
	cie = nhrp_cie_pull(&pp->payload, pp->hdr, &cie_nbma, &cie_proto);
	if (!cie || cie->code != NHRP_CODE_SUCCESS) {
		debugf(NHRP_DEBUG_COMMON, "Shortcut: CIE code %d", cie ? cie->code : -1);
		return;
	}

	proto = sockunion_family(&cie_proto) != AF_UNSPEC ? &cie_proto : &pp->dst_proto;
	if (cie->holding_time)
		holding_time = htons(cie->holding_time);

	prefix = *s->p;
	prefix.prefixlen = cie->prefix_length;

	/* Sanity check prefix length */
	if (prefix.prefixlen >= 8*prefix_blen(&prefix)) {
		prefix.prefixlen = 8*prefix_blen(&prefix);
	} else if (nhrp_route_address(NULL, &pp->dst_proto, &route_prefix, NULL) == NHRP_ROUTE_NBMA_NEXTHOP) {
		if (prefix.prefixlen < route_prefix.prefixlen)
			prefix.prefixlen = route_prefix.prefixlen;
	}

	debugf(NHRP_DEBUG_COMMON, "Shortcut: %s is at proto %s cie-nbma %s nat-nbma %s cie-holdtime %d",
		prefix2str(&prefix, bufp, sizeof bufp),
		sockunion2str(proto, buf[0], sizeof buf[0]),
		sockunion2str(&cie_nbma, buf[1], sizeof buf[1]),
		sockunion2str(&nat_nbma, buf[2], sizeof buf[2]),
		htons(cie->holding_time));

	/* Update cache entry for the protocol to nbma binding */
	if (sockunion_family(&nat_nbma) != AF_UNSPEC) {
		nbma = &nat_nbma;
		nbma_natoa = &cie_nbma;
	} else {
		nbma = &cie_nbma;
		nbma_natoa = NULL;
	}
	if (sockunion_family(nbma)) {
		c = nhrp_cache_get(pp->ifp, proto, 1);
		if (c) {
			nhrp_cache_update_binding(
					c, NHRP_CACHE_CACHED, holding_time,
					nhrp_peer_get(pp->ifp, nbma),
					htons(cie->mtu), nbma_natoa);
		}
	}

	/* Update shortcut entry for subnet to protocol gw binding */
	if (c && !sockunion_same(proto, &pp->dst_proto)) {
		ps = nhrp_shortcut_get(&prefix);
		if (ps) {
			ps->addr = s->addr;
			nhrp_shortcut_update_binding(ps, NHRP_CACHE_CACHED, c, holding_time);
		}
	}

	debugf(NHRP_DEBUG_COMMON, "Shortcut: Resolution reply handled");
}

static void nhrp_shortcut_send_resolution_req(struct nhrp_shortcut *s)
{
	struct zbuf *zb;
	struct nhrp_packet_header *hdr;
	struct interface *ifp;
	struct nhrp_interface *nifp;
	struct nhrp_peer *peer;

	if (nhrp_route_address(NULL, &s->addr, NULL, &peer) != NHRP_ROUTE_NBMA_NEXTHOP)
		return;

	if (s->type == NHRP_CACHE_INVALID || s->type == NHRP_CACHE_NEGATIVE)
		s->type = NHRP_CACHE_INCOMPLETE;

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

	/* Create request */
	zb = zbuf_alloc(1500);
	hdr = nhrp_packet_push(zb, NHRP_PACKET_RESOLUTION_REQUEST,
		&nifp->nbma, &nifp->afi[family2afi(sockunion_family(&s->addr))].addr, &s->addr);
	hdr->u.request_id = htonl(nhrp_reqid_alloc(&nhrp_packet_reqid, &s->reqid, nhrp_shortcut_recv_resolution_rep));
	hdr->flags = htons(NHRP_FLAG_RESOLUTION_SOURCE_IS_ROUTER |
			   NHRP_FLAG_RESOLUTION_AUTHORATIVE |
			   NHRP_FLAG_RESOLUTION_SOURCE_STABLE);

	/* RFC2332 - One or zero CIEs, if CIE is present contains:
	 *  - Prefix length: widest acceptable prefix we accept (if U set, 0xff)
	 *  - MTU: MTU of the source station
	 *  - Holding Time: Max time to cache the source information
	 * */
	/* FIXME: Send holding time, and MTU */

	nhrp_ext_request(zb, hdr, ifp);

	/* Cisco NAT detection extension */
	hdr->flags |= htons(NHRP_FLAG_RESOLUTION_NAT);
	nhrp_ext_push(zb, hdr, NHRP_EXTENSION_NAT_ADDRESS);

	nhrp_packet_complete(zb, hdr);

	nhrp_peer_send(peer, zb);
	nhrp_peer_unref(peer);
	zbuf_free(zb);
}

void nhrp_shortcut_initiate(union sockunion *addr)
{
	struct prefix p;
	struct nhrp_shortcut *s;

	sockunion2hostprefix(addr, &p);
	s = nhrp_shortcut_get(&p);
	if (s && s->type != NHRP_CACHE_INCOMPLETE) {
		s->addr = *addr;
		THREAD_OFF(s->t_timer);
		THREAD_TIMER_ON(master, s->t_timer, nhrp_shortcut_do_purge, s, 30);
		nhrp_shortcut_send_resolution_req(s);
	}
}

void nhrp_shortcut_init(void)
{
	shortcut_rib[AFI_IP] = route_table_init();
	shortcut_rib[AFI_IP6] = route_table_init();
}

void nhrp_shortcut_terminate(void)
{
	route_table_finish(shortcut_rib[AFI_IP]);
	route_table_finish(shortcut_rib[AFI_IP6]);
}

void nhrp_shortcut_foreach(afi_t afi, void (*cb)(struct nhrp_shortcut *, void *), void *ctx)
{
	struct route_table *rt = shortcut_rib[afi];
	struct route_node *rn;
	route_table_iter_t iter;

	if (!rt) return;

	route_table_iter_init(&iter, rt);
	while ((rn = route_table_iter_next(&iter)) != NULL) {
		if (rn->info) cb(rn->info, ctx);
	}
	route_table_iter_cleanup(&iter);
}

struct purge_ctx {
	const struct prefix *p;
	int deleted;
};

void nhrp_shortcut_purge(struct nhrp_shortcut *s, int force)
{
	THREAD_OFF(s->t_timer);
	nhrp_reqid_free(&nhrp_packet_reqid, &s->reqid);

	if (force) {
		/* Immediate purge on route with draw or pending shortcut */
		THREAD_TIMER_MSEC_ON(master, s->t_timer, nhrp_shortcut_do_purge, s, 5);
	} else {
		/* Soft expire - force immediate renewal, but purge
		 * in few seconds to make sure stale route is not
		 * used too long. In practice most purges are caused
		 * by hub bgp change, but target usually stays same.
		 * This allows to keep nhrp route up, and to not
		 * cause temporary rerouting via hubs causing latency
		 * jitter. */
		THREAD_TIMER_MSEC_ON(master, s->t_timer, nhrp_shortcut_do_purge, s, 3000);
		s->expiring = 1;
		nhrp_shortcut_check_use(s);
	}
}

static void nhrp_shortcut_purge_prefix(struct nhrp_shortcut *s, void *ctx)
{
	struct purge_ctx *pctx = ctx;

	if (prefix_match(pctx->p, s->p))
		nhrp_shortcut_purge(s, pctx->deleted || !s->cache);
}

void nhrp_shortcut_prefix_change(const struct prefix *p, int deleted)
{
	struct purge_ctx pctx = {
		.p = p,
		.deleted = deleted,
	};
	nhrp_shortcut_foreach(family2afi(PREFIX_FAMILY(p)), nhrp_shortcut_purge_prefix, &pctx);
}

