/* NHRP NHC nexthop server functions (registration)
 * 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 "zebra.h"
#include "zbuf.h"
#include "memory.h"
#include "thread.h"
#include "nhrpd.h"
#include "nhrp_protocol.h"

static int nhrp_nhs_resolve(struct thread *t);

struct nhrp_registration {
	struct list_head reglist_entry;
	struct thread *t_register;
	struct nhrp_nhs *nhs;
	struct nhrp_reqid reqid;
	unsigned int timeout;
	unsigned mark : 1;
	union sockunion proto_addr;
	struct nhrp_peer *peer;
	struct notifier_block peer_notifier;
};

static int nhrp_reg_send_req(struct thread *t);

static void nhrp_reg_reply(struct nhrp_reqid *reqid, void *arg)
{
	struct nhrp_packet_parser *p = arg;
	struct nhrp_registration *r = container_of(reqid, struct nhrp_registration, reqid);
	struct nhrp_nhs *nhs = r->nhs;
	struct interface *ifp = nhs->ifp;
	struct nhrp_interface *nifp = ifp->info;
	struct nhrp_extension_header *ext;
	struct nhrp_cie_header *cie;
	struct nhrp_cache *c;
	struct zbuf extpl;
	union sockunion cie_nbma, cie_proto, *proto;
	char buf[64];
	int ok = 0, holdtime;

	nhrp_reqid_free(&nhrp_packet_reqid, &r->reqid);

	if (p->hdr->type != NHRP_PACKET_REGISTRATION_REPLY) {
		debugf(NHRP_DEBUG_COMMON, "NHS: Registration failed");
		return;
	}

	debugf(NHRP_DEBUG_COMMON, "NHS: Reg.reply received");

	ok = 1;
	while ((cie = nhrp_cie_pull(&p->payload, p->hdr, &cie_nbma, &cie_proto)) != NULL) {
		proto = sockunion_family(&cie_proto) != AF_UNSPEC ? &cie_proto : &p->src_proto;
		debugf(NHRP_DEBUG_COMMON, "NHS: CIE registration: %s: %d",
			sockunion2str(proto, buf, sizeof(buf)),
			cie->code);
		if (!((cie->code == NHRP_CODE_SUCCESS) ||
                      (cie->code == NHRP_CODE_ADMINISTRATIVELY_PROHIBITED && nhs->hub)))
			ok = 0;
	}

	if (!ok)
		return;

	/* Parse extensions */
	sockunion_family(&nifp->nat_nbma) = AF_UNSPEC;
	while ((ext = nhrp_ext_pull(&p->extensions, &extpl)) != NULL) {
		switch (htons(ext->type) & ~NHRP_EXTENSION_FLAG_COMPULSORY) {
		case NHRP_EXTENSION_NAT_ADDRESS:
			/* NHS adds second CIE if NAT is detected */
			if (nhrp_cie_pull(&extpl, p->hdr, &cie_nbma, &cie_proto) &&
			    nhrp_cie_pull(&extpl, p->hdr, &cie_nbma, &cie_proto)) {
				nifp->nat_nbma = cie_nbma;
				debugf(NHRP_DEBUG_IF, "%s: NAT detected, real NBMA address: %s",
					ifp->name, sockunion2str(&nifp->nbma, buf, sizeof(buf)));
			}
			break;
		}
	}

	/* Success - schedule next registration, and route NHS */
	r->timeout = 2;
	holdtime = nifp->afi[nhs->afi].holdtime;
	THREAD_OFF(r->t_register);

	/* RFC 2332 5.2.3 - Registration is recommend to be renewed
	 * every one third of holdtime */
	THREAD_TIMER_ON(master, r->t_register, nhrp_reg_send_req, r, holdtime / 3);

	r->proto_addr = p->dst_proto;
	c = nhrp_cache_get(ifp, &p->dst_proto, 1);
	if (c) nhrp_cache_update_binding(c, NHRP_CACHE_NHS, holdtime, nhrp_peer_ref(r->peer), 0, NULL);
}

static int nhrp_reg_timeout(struct thread *t)
{
	struct nhrp_registration *r = THREAD_ARG(t);
	struct nhrp_cache *c;

	r->t_register = NULL;

	if (r->timeout >= 16 && sockunion_family(&r->proto_addr) != AF_UNSPEC) {
		nhrp_reqid_free(&nhrp_packet_reqid, &r->reqid);
		c = nhrp_cache_get(r->nhs->ifp, &r->proto_addr, 0);
		if (c) nhrp_cache_update_binding(c, NHRP_CACHE_NHS, -1, NULL, 0, NULL);
		sockunion_family(&r->proto_addr) = AF_UNSPEC;
	}

	r->timeout <<= 1;
	if (r->timeout > 64) r->timeout = 2;
	THREAD_TIMER_MSEC_ON(master, r->t_register, nhrp_reg_send_req, r, 10);

	return 0;
}

static void nhrp_reg_peer_notify(struct notifier_block *n, unsigned long cmd)
{
	struct nhrp_registration *r = container_of(n, struct nhrp_registration, peer_notifier);
	char buf[SU_ADDRSTRLEN];

	switch (cmd) {
	case NOTIFY_PEER_UP:
	case NOTIFY_PEER_DOWN:
	case NOTIFY_PEER_IFCONFIG_CHANGED:
	case NOTIFY_PEER_MTU_CHANGED:
		debugf(NHRP_DEBUG_COMMON, "NHS: Flush timer for %s",
			sockunion2str(&r->peer->vc->remote.nbma, buf, sizeof buf));
		THREAD_TIMER_OFF(r->t_register);
		THREAD_TIMER_MSEC_ON(master, r->t_register, nhrp_reg_send_req, r, 10);
		break;
	}
}

static int nhrp_reg_send_req(struct thread *t)
{
	struct nhrp_registration *r = THREAD_ARG(t);
	struct nhrp_nhs *nhs = r->nhs;
	char buf1[SU_ADDRSTRLEN], buf2[SU_ADDRSTRLEN];
	struct interface *ifp = nhs->ifp;
	struct nhrp_interface *nifp = ifp->info;
	struct nhrp_afi_data *if_ad = &nifp->afi[nhs->afi];
	union sockunion *dst_proto;
	struct zbuf *zb;
	struct nhrp_packet_header *hdr;
	struct nhrp_extension_header *ext;
	struct nhrp_cie_header *cie;

	r->t_register = NULL;
	if (!nhrp_peer_check(r->peer, 2)) {
		debugf(NHRP_DEBUG_COMMON, "NHS: Waiting link for %s",
			sockunion2str(&r->peer->vc->remote.nbma, buf1, sizeof buf1));
		THREAD_TIMER_ON(master, r->t_register, nhrp_reg_send_req, r, 120);
		return 0;
	}

	THREAD_TIMER_ON(master, r->t_register, nhrp_reg_timeout, r, r->timeout);

	/* RFC2332 5.2.3 NHC uses it's own address as dst if NHS is unknown */
	dst_proto = &nhs->proto_addr;
	if (sockunion_family(dst_proto) == AF_UNSPEC)
		dst_proto = &if_ad->addr;

	sockunion2str(&if_ad->addr, buf1, sizeof(buf1));
	sockunion2str(dst_proto, buf2, sizeof(buf2));
	debugf(NHRP_DEBUG_COMMON, "NHS: Register %s -> %s (timeout %d)", buf1, buf2, r->timeout);

	/* No protocol address configured for tunnel interface */
	if (sockunion_family(&if_ad->addr) == AF_UNSPEC)
		return 0;

	zb = zbuf_alloc(1400);
	hdr = nhrp_packet_push(zb, NHRP_PACKET_REGISTRATION_REQUEST, &nifp->nbma, &if_ad->addr, dst_proto);
	hdr->hop_count = 0;
	if (!(if_ad->flags & NHRP_IFF_REG_NO_UNIQUE))
		hdr->flags |= htons(NHRP_FLAG_REGISTRATION_UNIQUE);

	hdr->u.request_id = htonl(nhrp_reqid_alloc(&nhrp_packet_reqid, &r->reqid, nhrp_reg_reply));

	/* FIXME: push CIE for each local protocol address */
	cie = nhrp_cie_push(zb, NHRP_CODE_SUCCESS, NULL, NULL);
	cie->prefix_length = 0xff;
	cie->holding_time = htons(if_ad->holdtime);
	cie->mtu = htons(if_ad->mtu);

	nhrp_ext_request(zb, hdr, ifp);

	/* Cisco NAT detection extension */
	hdr->flags |= htons(NHRP_FLAG_REGISTRATION_NAT);
	ext = nhrp_ext_push(zb, hdr, NHRP_EXTENSION_NAT_ADDRESS);
	cie = nhrp_cie_push(zb, NHRP_CODE_SUCCESS, &nifp->nbma, &if_ad->addr);
	cie->prefix_length = 8 * sockunion_get_addrlen(&nifp->nbma);
	nhrp_ext_complete(zb, ext);

	nhrp_packet_complete(zb, hdr);
	nhrp_peer_send(r->peer, zb);
	zbuf_free(zb);

	return 0;
}

static void nhrp_reg_delete(struct nhrp_registration *r)
{
	nhrp_peer_notify_del(r->peer, &r->peer_notifier);
	nhrp_peer_unref(r->peer);
	list_del(&r->reglist_entry);
	THREAD_OFF(r->t_register);
	XFREE(MTYPE_NHRP_REGISTRATION, r);
}

static struct nhrp_registration *nhrp_reg_by_nbma(struct nhrp_nhs *nhs, const union sockunion *nbma_addr)
{
	struct nhrp_registration *r;

	list_for_each_entry(r, &nhs->reglist_head, reglist_entry)
		if (sockunion_same(&r->peer->vc->remote.nbma, nbma_addr))
			return r;
	return NULL;
}

static void nhrp_nhs_resolve_cb(struct resolver_query *q, int n, union sockunion *addrs)
{
	struct nhrp_nhs *nhs = container_of(q, struct nhrp_nhs, dns_resolve);
	struct nhrp_interface *nifp = nhs->ifp->info;
	struct nhrp_registration *reg, *regn;
	int i;

	nhs->t_resolve = NULL;
	if (n < 0) {
		/* Failed, retry in a moment */
		THREAD_TIMER_ON(master, nhs->t_resolve, nhrp_nhs_resolve, nhs, 5);
		return;
	}

	THREAD_TIMER_ON(master, nhs->t_resolve, nhrp_nhs_resolve, nhs, 2*60*60);

	list_for_each_entry(reg, &nhs->reglist_head, reglist_entry)
		reg->mark = 1;

	nhs->hub = 0;
	for (i = 0; i < n; i++) {
		if (sockunion_same(&addrs[i], &nifp->nbma)) {
			nhs->hub = 1;
			continue;
		}

		reg = nhrp_reg_by_nbma(nhs, &addrs[i]);
		if (reg) {
			reg->mark = 0;
			continue;
		}

		reg = XCALLOC(MTYPE_NHRP_REGISTRATION, sizeof(*reg));
		reg->peer = nhrp_peer_get(nhs->ifp, &addrs[i]);
		reg->nhs = nhs;
		reg->timeout = 1;
		list_init(&reg->reglist_entry);
		list_add_tail(&reg->reglist_entry, &nhs->reglist_head);
		nhrp_peer_notify_add(reg->peer, &reg->peer_notifier, nhrp_reg_peer_notify);
		THREAD_TIMER_MSEC_ON(master, reg->t_register, nhrp_reg_send_req, reg, 50);
	}

	list_for_each_entry_safe(reg, regn, &nhs->reglist_head, reglist_entry) {
		if (reg->mark)
			nhrp_reg_delete(reg);
	}
}

static int nhrp_nhs_resolve(struct thread *t)
{
	struct nhrp_nhs *nhs = THREAD_ARG(t);

	resolver_resolve(&nhs->dns_resolve, AF_INET, nhs->nbma_fqdn, nhrp_nhs_resolve_cb);

	return 0;
}

int nhrp_nhs_add(struct interface *ifp, afi_t afi, union sockunion *proto_addr, const char *nbma_fqdn)
{
	struct nhrp_interface *nifp = ifp->info;
	struct nhrp_nhs *nhs;

	if (sockunion_family(proto_addr) != AF_UNSPEC &&
	    sockunion_family(proto_addr) != afi2family(afi))
		return NHRP_ERR_PROTOCOL_ADDRESS_MISMATCH;

	list_for_each_entry(nhs, &nifp->afi[afi].nhslist_head, nhslist_entry) {
		if (sockunion_family(&nhs->proto_addr) != AF_UNSPEC &&
		    sockunion_family(proto_addr) != AF_UNSPEC &&
		    sockunion_same(&nhs->proto_addr, proto_addr))
			return NHRP_ERR_ENTRY_EXISTS;

		if (strcmp(nhs->nbma_fqdn, nbma_fqdn) == 0)
			return NHRP_ERR_ENTRY_EXISTS;
	}

	nhs = XMALLOC(MTYPE_NHRP_NHS, sizeof(struct nhrp_nhs));
	if (!nhs) return NHRP_ERR_NO_MEMORY;

	*nhs = (struct nhrp_nhs) {
		.afi = afi,
		.ifp = ifp,
		.proto_addr = *proto_addr,
		.nbma_fqdn = strdup(nbma_fqdn),
		.reglist_head = LIST_INITIALIZER(nhs->reglist_head),
	};
	list_add_tail(&nhs->nhslist_entry, &nifp->afi[afi].nhslist_head);
	THREAD_TIMER_MSEC_ON(master, nhs->t_resolve, nhrp_nhs_resolve, nhs, 1000);

	return NHRP_OK;
}

int nhrp_nhs_del(struct interface *ifp, afi_t afi, union sockunion *proto_addr, const char *nbma_fqdn)
{
	struct nhrp_interface *nifp = ifp->info;
	struct nhrp_nhs *nhs, *nnhs;
	int ret = NHRP_ERR_ENTRY_NOT_FOUND;

	if (sockunion_family(proto_addr) != AF_UNSPEC &&
	    sockunion_family(proto_addr) != afi2family(afi))
		return NHRP_ERR_PROTOCOL_ADDRESS_MISMATCH;

	list_for_each_entry_safe(nhs, nnhs, &nifp->afi[afi].nhslist_head, nhslist_entry) {
		if (!sockunion_same(&nhs->proto_addr, proto_addr))
			continue;
		if (strcmp(nhs->nbma_fqdn, nbma_fqdn) != 0)
			continue;

		nhrp_nhs_free(nhs);
		ret = NHRP_OK;
	}

	return ret;
}

int nhrp_nhs_free(struct nhrp_nhs *nhs)
{
	struct nhrp_registration *r, *rn;

	list_for_each_entry_safe(r, rn, &nhs->reglist_head, reglist_entry)
		nhrp_reg_delete(r);
	THREAD_OFF(nhs->t_resolve);
	list_del(&nhs->nhslist_entry);
	free((void*) nhs->nbma_fqdn);
	XFREE(MTYPE_NHRP_NHS, nhs);
	return 0;
}

void nhrp_nhs_terminate(void)
{
	struct interface *ifp;
	struct nhrp_interface *nifp;
	struct nhrp_nhs *nhs, *tmp;
	struct listnode *node;
	afi_t afi;

	for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
		nifp = ifp->info;
		for (afi = 0; afi < AFI_MAX; afi++) {
			list_for_each_entry_safe(nhs, tmp, &nifp->afi[afi].nhslist_head, nhslist_entry)
				nhrp_nhs_free(nhs);
		}
	}
}
