/* Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
 * Portions Copyright © 1997-1999 Vita Nuova Limited
 * Portions Copyright © 2000-2007 Vita Nuova Holdings Limited
 *                                (www.vitanuova.com)
 * Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
 *
 * Modified for the Akaros operating system:
 * Copyright (c) 2013-2014 The Regents of the University of California
 * Copyright (c) 2013-2015 Google Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE. */

#include <vfs.h>
#include <kfs.h>
#include <slab.h>
#include <kmalloc.h>
#include <kref.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <error.h>
#include <cpio.h>
#include <pmap.h>
#include <smp.h>
#include <ip.h>

/*
 *  address resolution tables
 */

enum {
	NHASH = (1 << 6),
	NCACHE = 256,

	AOK = 1,
	AWAIT = 2,
};

char *arpstate[] = {
	"UNUSED",
	"OK",
	"WAIT",
};

/*
 *  one per Fs
 */
struct arp {
	qlock_t qlock;
	struct Fs *f;
	struct arpent *hash[NHASH];
	struct arpent cache[NCACHE];
	struct arpent *rxmt;
	struct proc *rxmitp;		/* neib sol re-transmit proc */
	struct rendez rxmtq;
	struct block *dropf, *dropl;
};

#define haship(s) ((s)[IPaddrlen-1]%NHASH)

int ReTransTimer = RETRANS_TIMER;
static void rxmitproc(void *v);

void arpinit(struct Fs *f)
{
	f->arp = kzmalloc(sizeof(struct arp), MEM_WAIT);
	qlock_init(&f->arp->qlock);
	rendez_init(&f->arp->rxmtq);
	f->arp->f = f;
	f->arp->rxmt = NULL;
	f->arp->dropf = f->arp->dropl = NULL;
	ktask("rxmitproc", rxmitproc, f->arp);
}

/*
 *  create a new arp entry for an ip address.
 */
static struct arpent *newarp6(struct arp *arp, uint8_t *ip, struct Ipifc *ifc,
                              int addrxt)
{
	unsigned int t;
	struct block *next, *xp;
	struct arpent *a, *e, *f, **l;
	struct medium *m = ifc->m;
	int empty;

	/* find oldest entry */
	e = &arp->cache[NCACHE];
	a = arp->cache;
	t = a->utime;
	for (f = a; f < e; f++) {
		if (f->utime < t) {
			t = f->utime;
			a = f;
		}
	}

	/* dump waiting packets */
	xp = a->hold;
	a->hold = NULL;

	if (isv4(a->ip)) {
		while (xp) {
			next = xp->list;
			freeblist(xp);
			xp = next;
		}
	} else {
		/* queue icmp unreachable for rxmitproc later, w/o arp lock */
		if (xp) {
			if (arp->dropl == NULL)
				arp->dropf = xp;
			else
				arp->dropl->list = xp;

			for (next = xp->list; next; next = next->list)
				xp = next;
			arp->dropl = xp;
			rendez_wakeup(&arp->rxmtq);
		}
	}

	/* take out of current chain */
	l = &arp->hash[haship(a->ip)];
	for (f = *l; f; f = f->hash) {
		if (f == a) {
			*l = a->hash;
			break;
		}
		l = &f->hash;
	}

	/* insert into new chain */
	l = &arp->hash[haship(ip)];
	a->hash = *l;
	*l = a;

	memmove(a->ip, ip, sizeof(a->ip));
	a->utime = NOW;
	a->ctime = 0;	/* somewhat of a "last sent time".  0, to trigger a send. */
	a->type = m;

	a->rtime = NOW + ReTransTimer;
	a->rxtsrem = MAX_MULTICAST_SOLICIT;
	a->ifc = ifc;
	a->ifcid = ifc->ifcid;

	/* put to the end of re-transmit chain; addrxt is 0 when isv4(a->ip) */
	if (!ipismulticast(a->ip) && addrxt) {
		l = &arp->rxmt;
		empty = (*l == NULL);

		for (f = *l; f; f = f->nextrxt) {
			if (f == a) {
				*l = a->nextrxt;
				break;
			}
			l = &f->nextrxt;
		}
		for (f = *l; f; f = f->nextrxt) {
			l = &f->nextrxt;
		}
		*l = a;
		if (empty)
			rendez_wakeup(&arp->rxmtq);
	}

	a->nextrxt = NULL;

	return a;
}

/* called with arp qlocked */

void cleanarpent(struct arp *arp, struct arpent *a)
{
	struct arpent *f, **l;

	a->utime = 0;
	a->ctime = 0;
	a->type = 0;
	a->state = 0;

	/* take out of current chain */
	l = &arp->hash[haship(a->ip)];
	for (f = *l; f; f = f->hash) {
		if (f == a) {
			*l = a->hash;
			break;
		}
		l = &f->hash;
	}

	/* take out of re-transmit chain */
	l = &arp->rxmt;
	for (f = *l; f; f = f->nextrxt) {
		if (f == a) {
			*l = a->nextrxt;
			break;
		}
		l = &f->nextrxt;
	}
	a->nextrxt = NULL;
	a->hash = NULL;
	a->hold = NULL;
	a->last = NULL;
	a->ifc = NULL;
}

/*
 *  fill in the media address if we have it.  Otherwise return an
 *  arpent that represents the state of the address resolution FSM
 *  for ip.  Add the packet to be sent onto the list of packets
 *  waiting for ip->mac to be resolved.
 */
struct arpent *arpget(struct arp *arp, struct block *bp, int version,
                      struct Ipifc *ifc, uint8_t *ip, uint8_t *mac)
{
	int hash, len;
	struct arpent *a;
	struct medium *type = ifc->m;
	uint8_t v6ip[IPaddrlen];
	uint16_t *s, *d;

	if (version == V4) {
		v4tov6(v6ip, ip);
		ip = v6ip;
	}

	qlock(&arp->qlock);
	hash = haship(ip);
	for (a = arp->hash[hash]; a; a = a->hash) {
		if (ipcmp(ip, a->ip) == 0)
			if (type == a->type)
				break;
	}

	if (a == NULL) {
		a = newarp6(arp, ip, ifc, (version != V4));
		a->state = AWAIT;
	}
	a->utime = NOW;
	if (a->state == AWAIT) {
		if (bp != NULL) {
			if (a->hold)
				a->last->list = bp;
			else
				a->hold = bp;
			a->last = bp;
			bp->list = NULL;
		}
		return a;	/* return with arp qlocked */
	}

	s = (uint16_t *)a->mac;
	d = (uint16_t *)mac;
	len = a->type->maclen / 2;
	while (len) {
		*d++ = *s++;
		len--;
	}

	/* remove old entries */
	if (NOW - a->ctime > 15 * 60 * 1000)
		cleanarpent(arp, a);

	qunlock(&arp->qlock);
	return NULL;
}

/*
 * called with arp locked
 */
void arprelease(struct arp *arp, struct arpent *a)
{
	qunlock(&arp->qlock);
}

/*
 * Copy out the mac address from the arpent.  Return the
 * block waiting to get sent to this mac address.
 *
 * called with arp locked
 */
struct block *arpresolve(struct arp *arp, struct arpent *a, struct medium *type,
                         uint8_t *mac)
{
	struct block *bp;
	struct arpent *f, **l;

	if (!isv4(a->ip)) {
		l = &arp->rxmt;
		for (f = *l; f; f = f->nextrxt) {
			if (f == a) {
				*l = a->nextrxt;
				break;
			}
			l = &f->nextrxt;
		}
	}

	memmove(a->mac, mac, type->maclen);
	a->type = type;
	a->state = AOK;
	a->utime = NOW;
	bp = a->hold;
	a->hold = NULL;
	/* brho: it looks like we return the entire hold list, though it might be
	 * purged by now via some other crazy arp list management.  our callers
	 * can't handle the arp's b->list stuff. */
	assert(!bp->list);
	qunlock(&arp->qlock);

	return bp;
}

void arpenter(struct Fs *fs, int version, uint8_t *ip, uint8_t *mac, int n,
              int refresh)
{
	ERRSTACK(1);
	struct arp *arp;
	struct route *r;
	struct arpent *a, *f, **l;
	struct Ipifc *ifc;
	struct medium *type;
	struct block *bp, *next;
	uint8_t v6ip[IPaddrlen];

	arp = fs->arp;

	if (n != 6) {
		return;
	}

	switch (version) {
		case V4:
			r = v4lookup(fs, ip, NULL);
			v4tov6(v6ip, ip);
			ip = v6ip;
			break;
		case V6:
			r = v6lookup(fs, ip, NULL);
			break;
		default:
			panic("arpenter: version %d", version);
			return;	/* to supress warnings */
	}

	if (r == NULL) {
		return;
	}

	ifc = r->rt.ifc;
	type = ifc->m;

	qlock(&arp->qlock);
	for (a = arp->hash[haship(ip)]; a; a = a->hash) {
		if (a->type != type || (a->state != AWAIT && a->state != AOK))
			continue;

		if (ipcmp(a->ip, ip) == 0) {
			a->state = AOK;
			memmove(a->mac, mac, type->maclen);

			if (version == V6) {
				/* take out of re-transmit chain */
				l = &arp->rxmt;
				for (f = *l; f; f = f->nextrxt) {
					if (f == a) {
						*l = a->nextrxt;
						break;
					}
					l = &f->nextrxt;
				}
			}

			a->ifc = ifc;
			a->ifcid = ifc->ifcid;
			bp = a->hold;
			a->hold = NULL;
			if (version == V4)
				ip += IPv4off;
			a->utime = NOW;
			a->ctime = a->utime;
			qunlock(&arp->qlock);

			while (bp) {
				next = bp->list;
				if (ifc != NULL) {
					rlock(&ifc->rwlock);
					if (waserror()) {
						runlock(&ifc->rwlock);
						nexterror();
					}
					if (ifc->m != NULL)
						ifc->m->bwrite(ifc, bp, version, ip);
					else
						freeb(bp);
					runlock(&ifc->rwlock);
					poperror();
				} else
					freeb(bp);
				bp = next;
			}
			return;
		}
	}

	if (refresh == 0) {
		a = newarp6(arp, ip, ifc, 0);
		a->state = AOK;
		a->type = type;
		a->ctime = NOW;
		memmove(a->mac, mac, type->maclen);
	}

	qunlock(&arp->qlock);
}

int arpwrite(struct Fs *fs, char *s, long len)
{
	int n;
	struct route *r;
	struct arp *arp;
	struct block *bp;
	struct arpent *a, *fl, **l;
	struct medium *m;
	char *f[4], buf[256];
	uint8_t ip[IPaddrlen], mac[MAClen];

	arp = fs->arp;

	if (len <= 0)
		error(EINVAL, ERROR_FIXME);
	if (len > sizeof(buf))
		len = sizeof(buf);
	strlcpy(buf, s, sizeof(buf));
	if (len > 0 && buf[len - 2] == '\n')
		buf[len - 2] = 0;

	n = getfields(buf, f, 4, 1, " ");
	if (strcmp(f[0], "flush") == 0) {
		qlock(&arp->qlock);
		for (a = arp->cache; a < &arp->cache[NCACHE]; a++) {
			memset(a->ip, 0, sizeof(a->ip));
			memset(a->mac, 0, sizeof(a->mac));
			a->hash = NULL;
			a->state = 0;
			a->utime = 0;
			while (a->hold != NULL) {
				bp = a->hold->list;
				freeblist(a->hold);
				a->hold = bp;
			}
		}
		memset(arp->hash, 0, sizeof(arp->hash));
		/* clear all pkts on these lists (rxmt, dropf/l) */
		arp->rxmt = NULL;
		arp->dropf = NULL;
		arp->dropl = NULL;
		qunlock(&arp->qlock);
	} else if (strcmp(f[0], "add") == 0) {
		switch (n) {
			default:
				error(EINVAL, ERROR_FIXME);
			case 3:
				parseip(ip, f[1]);
				if (isv4(ip))
					r = v4lookup(fs, ip + IPv4off, NULL);
				else
					r = v6lookup(fs, ip, NULL);
				if (r == NULL)
					error(EHOSTUNREACH, "Destination unreachable");
				m = r->rt.ifc->m;
				n = parsemac(mac, f[2], m->maclen);
				break;
			case 4:
				m = ipfindmedium(f[1]);
				if (m == NULL)
					error(EINVAL, ERROR_FIXME);
				parseip(ip, f[2]);
				n = parsemac(mac, f[3], m->maclen);
				break;
		}

		if (m->ares == NULL)
			error(EINVAL, ERROR_FIXME);

		m->ares(fs, V6, ip, mac, n, 0);
	} else if (strcmp(f[0], "del") == 0) {
		if (n != 2)
			error(EINVAL, ERROR_FIXME);

		parseip(ip, f[1]);
		qlock(&arp->qlock);

		l = &arp->hash[haship(ip)];
		for (a = *l; a; a = a->hash) {
			if (memcmp(ip, a->ip, sizeof(a->ip)) == 0) {
				*l = a->hash;
				break;
			}
			l = &a->hash;
		}

		if (a) {
			/* take out of re-transmit chain */
			l = &arp->rxmt;
			for (fl = *l; fl; fl = fl->nextrxt) {
				if (fl == a) {
					*l = a->nextrxt;
					break;
				}
				l = &fl->nextrxt;
			}

			a->nextrxt = NULL;
			a->hash = NULL;
			a->hold = NULL;
			a->last = NULL;
			a->ifc = NULL;
			memset(a->ip, 0, sizeof(a->ip));
			memset(a->mac, 0, sizeof(a->mac));
		}
		qunlock(&arp->qlock);
	} else
		error(EINVAL, ERROR_FIXME);

	return len;
}

enum {
	Alinelen = 90,
};

static char *aformat = "%-6.6s %-8.8s %-40.40I %E\n";

int arpread(struct arp *arp, char *p, uint32_t offset, int len)
{
	struct arpent *a;
	int n;
	int left = len;
	int amt;

	if (offset % Alinelen)
		return 0;

	offset = offset / Alinelen;
	len = len / Alinelen;

	n = 0;
	for (a = arp->cache; len > 0 && a < &arp->cache[NCACHE]; a++) {
		if (a->state == 0)
			continue;
		if (offset > 0) {
			offset--;
			continue;
		}
		len--;
		left--;
		qlock(&arp->qlock);
		amt = snprintf(p + n, left, aformat, a->type->name, arpstate[a->state],
		               a->ip, a->mac);
		n += amt;
		left -= amt;
		qunlock(&arp->qlock);
	}

	return n;
}

static uint64_t rxmitsols(struct arp *arp)
{
	unsigned int sflag;
	struct block *next, *xp;
	struct arpent *a, *b, **l;
	struct Fs *f;
	uint8_t ipsrc[IPaddrlen];
	struct Ipifc *ifc = NULL;
	uint64_t nrxt;

	qlock(&arp->qlock);
	f = arp->f;

	a = arp->rxmt;
	if (a == NULL) {
		nrxt = 0;
		goto dodrops;	/* return nrxt; */
	}
	nrxt = a->rtime - NOW;
	if (nrxt > 3 * ReTransTimer / 4)
		goto dodrops;	/* return nrxt; */

	for (; a; a = a->nextrxt) {
		ifc = a->ifc;
		assert(ifc != NULL);
		if ((a->rxtsrem <= 0) || !(canrlock(&ifc->rwlock))
			|| (a->ifcid != ifc->ifcid)) {
			xp = a->hold;
			a->hold = NULL;

			if (xp) {
				if (arp->dropl == NULL)
					arp->dropf = xp;
				else
					arp->dropl->list = xp;
			}

			cleanarpent(arp, a);
		} else
			break;
	}
	if (a == NULL)
		goto dodrops;

	qunlock(&arp->qlock);	/* for icmpns */
	if ((sflag = ipv6anylocal(ifc, ipsrc)) != SRC_UNSPEC)
		icmpns(f, ipsrc, sflag, a->ip, TARG_MULTI, ifc->mac);

	runlock(&ifc->rwlock);
	qlock(&arp->qlock);

	/* put to the end of re-transmit chain */
	l = &arp->rxmt;
	for (b = *l; b; b = b->nextrxt) {
		if (b == a) {
			*l = a->nextrxt;
			break;
		}
		l = &b->nextrxt;
	}
	for (b = *l; b; b = b->nextrxt) {
		l = &b->nextrxt;
	}
	*l = a;
	a->rxtsrem--;
	a->nextrxt = NULL;
	a->rtime = NOW + ReTransTimer;

	a = arp->rxmt;
	if (a == NULL)
		nrxt = 0;
	else
		nrxt = a->rtime - NOW;

dodrops:
	xp = arp->dropf;
	arp->dropf = NULL;
	arp->dropl = NULL;
	qunlock(&arp->qlock);

	for (; xp; xp = next) {
		next = xp->list;
		icmphostunr(f, ifc, xp, icmp6_adr_unreach, 1);
	}

	return nrxt;

}

static int rxready(void *v)
{
	struct arp *arp = (struct arp *)v;
	int x;

	x = ((arp->rxmt != NULL) || (arp->dropf != NULL));

	return x;
}

static void rxmitproc(void *v)
{
	ERRSTACK(2);
	struct arp *arp = v;
	uint64_t wakeupat;

	arp->rxmitp = current;
	if (waserror()) {
		arp->rxmitp = 0;
		poperror();
		warn("arp rxmit ktask exited");
		return;
	}
	for (;;) {
		wakeupat = rxmitsols(arp);
		if (wakeupat == 0)
			rendez_sleep(&arp->rxmtq, rxready, v);
		else if (wakeupat > ReTransTimer / 4)
			kthread_usleep(wakeupat * 1000);
	}
	poperror();
}
