/* 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 <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 <net/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();
}
