/* 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>

static void walkadd(struct Fs *, struct route **, struct route *);
static void addnode(struct Fs *, struct route **, struct route *);
static void calcd(struct route *);

/* these are used for all instances of IP */
struct route *v4freelist;
struct route *v6freelist;
rwlock_t routelock;
uint32_t v4routegeneration, v6routegeneration;

/*
 * TODO: Change this to a proper release.
 * At the moment this is difficult to do since deleting
 * a route involves manipulating more data structures than
 * a kref/struct route.  E.g., unlinking from the route tree
 * requires access to a parent pointer, which doesn't exist
 * in the route structure itself.
 */
static void route_release(struct kref *kref)
{
	(void)kref;
}

static void freeroute(struct route *r)
{
	struct route **l;

	r->rt.left = NULL;
	r->rt.right = NULL;
	if (r->rt.type & Rv4)
		l = &v4freelist;
	else
		l = &v6freelist;
	r->rt.mid = *l;
	*l = r;
}

static struct route *allocroute(int type)
{
	struct route *r;
	int n;
	struct route **l;

	if (type & Rv4) {
		n = sizeof(struct RouteTree) + sizeof(struct V4route);
		l = &v4freelist;
	} else {
		n = sizeof(struct RouteTree) + sizeof(struct V6route);
		l = &v6freelist;
	}

	r = *l;
	if (r != NULL) {
		*l = r->rt.mid;
	} else {
		r = kzmalloc(n, 0);
		if (r == NULL)
			panic("out of routing nodes");
	}
	memset(r, 0, n);
	r->rt.type = type;
	r->rt.ifc = NULL;
	kref_init(&r->rt.kref, route_release, 1);

	return r;
}

static void addqueue(struct route **q, struct route *r)
{
	struct route *l;

	if (r == NULL)
		return;

	l = allocroute(r->rt.type);
	l->rt.mid = *q;
	*q = l;
	l->rt.left = r;
}

/*
 *   compare 2 v6 addresses
 */
static int lcmp(uint32_t * a, uint32_t * b)
{
	int i;

	for (i = 0; i < IPllen; i++) {
		if (a[i] > b[i])
			return 1;
		if (a[i] < b[i])
			return -1;
	}
	return 0;
}

/*
 *  compare 2 v4 or v6 ranges
 */
enum {
	Rpreceeds,
	Rfollows,
	Requals,
	Rcontains,
	Rcontained,
};

static int rangecompare(struct route *a, struct route *b)
{
	if (a->rt.type & Rv4) {
		if (a->v4.endaddress < b->v4.address)
			return Rpreceeds;

		if (a->v4.address > b->v4.endaddress)
			return Rfollows;

		if (a->v4.address <= b->v4.address
			&& a->v4.endaddress >= b->v4.endaddress) {
			if (a->v4.address == b->v4.address
				&& a->v4.endaddress == b->v4.endaddress)
				return Requals;
			return Rcontains;
		}
		return Rcontained;
	}

	if (lcmp(a->v6.endaddress, b->v6.address) < 0)
		return Rpreceeds;

	if (lcmp(a->v6.address, b->v6.endaddress) > 0)
		return Rfollows;

	if (lcmp(a->v6.address, b->v6.address) <= 0
		&& lcmp(a->v6.endaddress, b->v6.endaddress) >= 0) {
		if (lcmp(a->v6.address, b->v6.address) == 0
			&& lcmp(a->v6.endaddress, b->v6.endaddress) == 0)
			return Requals;
		return Rcontains;
	}

	return Rcontained;
}

static void copygate(struct route *old, struct route *new)
{
	if (new->rt.type & Rv4)
		memmove(old->v4.gate, new->v4.gate, IPv4addrlen);
	else
		memmove(old->v6.gate, new->v6.gate, IPaddrlen);
}

/*
 *  walk down a tree adding nodes back in
 */
static void walkadd(struct Fs *f, struct route **root, struct route *p)
{
	struct route *l, *r;

	l = p->rt.left;
	r = p->rt.right;
	p->rt.left = 0;
	p->rt.right = 0;
	addnode(f, root, p);
	if (l)
		walkadd(f, root, l);
	if (r)
		walkadd(f, root, r);
}

/*
 *  calculate depth
 */
static void calcd(struct route *p)
{
	struct route *q;
	int d;

	if (p) {
		d = 0;
		q = p->rt.left;
		if (q)
			d = q->rt.depth;
		q = p->rt.right;
		if (q && q->rt.depth > d)
			d = q->rt.depth;
		q = p->rt.mid;
		if (q && q->rt.depth > d)
			d = q->rt.depth;
		p->rt.depth = d + 1;
	}
}

/*
 *  balance the tree at the current node
 */
static void balancetree(struct route **cur)
{
	struct route *p, *l, *r;
	int dl, dr;

	/*
	 * if left and right are
	 * too out of balance,
	 * rotate tree node
	 */
	p = *cur;
	dl = 0;
	if ((l = p->rt.left))
		dl = l->rt.depth;
	dr = 0;
	if ((r = p->rt.right))
		dr = r->rt.depth;

	if (dl > dr + 1) {
		p->rt.left = l->rt.right;
		l->rt.right = p;
		*cur = l;
		calcd(p);
		calcd(l);
	} else if (dr > dl + 1) {
		p->rt.right = r->rt.left;
		r->rt.left = p;
		*cur = r;
		calcd(p);
		calcd(r);
	} else
		calcd(p);
}

/*
 *  add a new node to the tree
 */
static void addnode(struct Fs *f, struct route **cur, struct route *new)
{
	struct route *p;

	p = *cur;
	if (p == 0) {
		*cur = new;
		new->rt.depth = 1;
		return;
	}

	switch (rangecompare(new, p)) {
	case Rpreceeds:
		addnode(f, &p->rt.left, new);
		break;
	case Rfollows:
		addnode(f, &p->rt.right, new);
		break;
	case Rcontains:
		/*
		 *  if new node is superset
		 *  of tree node,
		 *  replace tree node and
		 *  queue tree node to be
		 *  merged into root.
		 */
		*cur = new;
		new->rt.depth = 1;
		addqueue(&f->queue, p);
		break;
	case Requals:
		/*
		 *  supercede the old entry if the old one isn't
		 *  a local interface.
		 */
		if ((p->rt.type & Rifc) == 0) {
			p->rt.type = new->rt.type;
			p->rt.ifcid = -1;
			copygate(p, new);
		} else if (new->rt.type & Rifc)
			kref_get(&p->rt.kref, 1);
		freeroute(new);
		break;
	case Rcontained:
		addnode(f, &p->rt.mid, new);
		break;
	}

	balancetree(cur);
}

#define	V4H(a)	((a&0x07ffffff)>>(32-Lroot-5))

void v4addroute(struct Fs *f, char *tag, uint8_t *a, uint8_t *mask,
		uint8_t *gate, int type)
{
	struct route *p;
	uint32_t sa;
	uint32_t m;
	uint32_t ea;
	int h, eh;

	m = nhgetl(mask);
	sa = nhgetl(a) & m;
	ea = sa | ~m;

	eh = V4H(ea);
	for (h = V4H(sa); h <= eh; h++) {
		p = allocroute(Rv4 | type);
		p->v4.address = sa;
		p->v4.endaddress = ea;
		memmove(p->v4.gate, gate, sizeof(p->v4.gate));
		memmove(p->rt.tag, tag, sizeof(p->rt.tag));

		wlock(&routelock);
		addnode(f, &f->v4root[h], p);
		while ((p = f->queue)) {
			f->queue = p->rt.mid;
			walkadd(f, &f->v4root[h], p->rt.left);
			freeroute(p);
		}
		wunlock(&routelock);
	}
	v4routegeneration++;

	ipifcaddroute(f, Rv4, a, mask, gate, type);
}

#define	V6H(a)	(((a)[IPllen-1] & 0x07ffffff)>>(32-Lroot-5))
#define ISDFLT(a, mask, tag) ((ipcmp((a),v6Unspecified)==0) && (ipcmp((mask),v6Unspecified)==0) && (strcmp((tag), "ra")!=0))

void v6addroute(struct Fs *f, char *tag, uint8_t *a, uint8_t *mask,
		uint8_t *gate, int type)
{
	struct route *p;
	uint32_t sa[IPllen], ea[IPllen];
	uint32_t x, y;
	int h, eh;

	/*
	   if(ISDFLT(a, mask, tag))
	   f->v6p->cdrouter = -1;
	 */

	for (h = 0; h < IPllen; h++) {
		x = nhgetl(a + 4 * h);
		y = nhgetl(mask + 4 * h);
		sa[h] = x & y;
		ea[h] = x | ~y;
	}

	eh = V6H(ea);
	for (h = V6H(sa); h <= eh; h++) {
		p = allocroute(type);
		memmove(p->v6.address, sa, IPaddrlen);
		memmove(p->v6.endaddress, ea, IPaddrlen);
		memmove(p->v6.gate, gate, IPaddrlen);
		memmove(p->rt.tag, tag, sizeof(p->rt.tag));

		wlock(&routelock);
		addnode(f, &f->v6root[h], p);
		while ((p = f->queue)) {
			f->queue = p->rt.mid;
			walkadd(f, &f->v6root[h], p->rt.left);
			freeroute(p);
		}
		wunlock(&routelock);
	}
	v6routegeneration++;

	ipifcaddroute(f, 0, a, mask, gate, type);
}

struct route **looknode(struct route **cur, struct route *r)
{
	struct route *p;

	for (;;) {
		p = *cur;
		if (p == 0)
			return 0;

		switch (rangecompare(r, p)) {
		case Rcontains:
			return 0;
		case Rpreceeds:
			cur = &p->rt.left;
			break;
		case Rfollows:
			cur = &p->rt.right;
			break;
		case Rcontained:
			cur = &p->rt.mid;
			break;
		case Requals:
			return cur;
		}
	}
}

void v4delroute(struct Fs *f, uint8_t *a, uint8_t *mask, int dolock)
{
	struct route **r, *p;
	struct route rt;
	int h, eh;
	uint32_t m;

	m = nhgetl(mask);
	rt.v4.address = nhgetl(a) & m;
	rt.v4.endaddress = rt.v4.address | ~m;
	rt.rt.type = Rv4;

	eh = V4H(rt.v4.endaddress);
	for (h = V4H(rt.v4.address); h <= eh; h++) {
		if (dolock)
			wlock(&routelock);
		r = looknode(&f->v4root[h], &rt);
		if (r) {
			p = *r;
			/* TODO: bad usage of kref (maybe use a release).  I
			 * didn't change this one, since it looks like the if
			 * code is when we want to release.  btw, use better
			 * code reuse btw v4 and v6... */
			if (kref_put(&p->rt.kref)) {
				*r = 0;
				addqueue(&f->queue, p->rt.left);
				addqueue(&f->queue, p->rt.mid);
				addqueue(&f->queue, p->rt.right);
				freeroute(p);
				while ((p = f->queue)) {
					f->queue = p->rt.mid;
					walkadd(f, &f->v4root[h], p->rt.left);
					freeroute(p);
				}
			}
		}
		if (dolock)
			wunlock(&routelock);
	}
	v4routegeneration++;

	ipifcremroute(f, Rv4, a, mask);
}

void v6delroute(struct Fs *f, uint8_t * a, uint8_t * mask, int dolock)
{
	struct route **r, *p;
	struct route rt;
	int h, eh;
	uint32_t x, y;

	for (h = 0; h < IPllen; h++) {
		x = nhgetl(a + 4 * h);
		y = nhgetl(mask + 4 * h);
		rt.v6.address[h] = x & y;
		rt.v6.endaddress[h] = x | ~y;
	}
	rt.rt.type = 0;

	eh = V6H(rt.v6.endaddress);
	for (h = V6H(rt.v6.address); h <= eh; h++) {
		if (dolock)
			wlock(&routelock);
		r = looknode(&f->v6root[h], &rt);
		if (r) {
			p = *r;
			/* TODO: bad usage of kref (maybe use a release).  I
			 * didn't change this one, since it looks like the if
			 * code is when we want to release.  btw, use better
			 * code reuse btw v4 and v6... */
			if (kref_put(&p->rt.kref)) {
				*r = 0;
				addqueue(&f->queue, p->rt.left);
				addqueue(&f->queue, p->rt.mid);
				addqueue(&f->queue, p->rt.right);
				freeroute(p);
				while ((p = f->queue)) {
					f->queue = p->rt.mid;
					walkadd(f, &f->v6root[h], p->rt.left);
					freeroute(p);
				}
			}
		}
		if (dolock)
			wunlock(&routelock);
	}
	v6routegeneration++;

	ipifcremroute(f, 0, a, mask);
}

struct route *v4lookup(struct Fs *f, uint8_t * a, struct conv *c)
{
	struct route *p, *q;
	uint32_t la;
	uint8_t gate[IPaddrlen];
	struct Ipifc *ifc;

	if (c != NULL && c->r != NULL && c->r->rt.ifc != NULL
		&& c->rgen == v4routegeneration)
		return c->r;

	la = nhgetl(a);
	q = NULL;
	for (p = f->v4root[V4H(la)]; p;)
		if (la >= p->v4.address) {
			if (la <= p->v4.endaddress) {
				q = p;
				p = p->rt.mid;
			} else
				p = p->rt.right;
		} else
			p = p->rt.left;

	if (q && (q->rt.ifc == NULL || q->rt.ifcid != q->rt.ifc->ifcid)) {
		if (q->rt.type & Rifc) {
			hnputl(gate + IPv4off, q->v4.address);
			memmove(gate, v4prefix, IPv4off);
		} else
			v4tov6(gate, q->v4.gate);
		ifc = findipifc(f, gate, q->rt.type);
		if (ifc == NULL)
			return NULL;
		q->rt.ifc = ifc;
		q->rt.ifcid = ifc->ifcid;
	}

	if (c != NULL) {
		c->r = q;
		c->rgen = v4routegeneration;
	}

	return q;
}

struct route *v6lookup(struct Fs *f, uint8_t * a, struct conv *c)
{
	struct route *p, *q;
	uint32_t la[IPllen];
	int h;
	uint32_t x, y;
	uint8_t gate[IPaddrlen];
	struct Ipifc *ifc;

	if (memcmp(a, v4prefix, IPv4off) == 0) {
		q = v4lookup(f, a + IPv4off, c);
		if (q != NULL)
			return q;
	}

	if (c != NULL && c->r != NULL && c->r->rt.ifc != NULL
		&& c->rgen == v6routegeneration)
		return c->r;

	for (h = 0; h < IPllen; h++)
		la[h] = nhgetl(a + 4 * h);

	q = 0;
	for (p = f->v6root[V6H(la)]; p;) {
		for (h = 0; h < IPllen; h++) {
			x = la[h];
			y = p->v6.address[h];
			if (x == y)
				continue;
			if (x < y) {
				p = p->rt.left;
				goto next;
			}
			break;
		}
		for (h = 0; h < IPllen; h++) {
			x = la[h];
			y = p->v6.endaddress[h];
			if (x == y)
				continue;
			if (x > y) {
				p = p->rt.right;
				goto next;
			}
			break;
		}
		q = p;
		p = p->rt.mid;
next:	;
	}

	if (q && (q->rt.ifc == NULL || q->rt.ifcid != q->rt.ifc->ifcid)) {
		if (q->rt.type & Rifc) {
			for (h = 0; h < IPllen; h++)
				hnputl(gate + 4 * h, q->v6.address[h]);
			ifc = findipifc(f, gate, q->rt.type);
		} else
			ifc = findipifc(f, q->v6.gate, q->rt.type);
		if (ifc == NULL)
			return NULL;
		q->rt.ifc = ifc;
		q->rt.ifcid = ifc->ifcid;
	}
	if (c != NULL) {
		c->r = q;
		c->rgen = v6routegeneration;
	}

	return q;
}

void routetype(int type, char *p)
{
	memset(p, ' ', 4);
	p[4] = 0;
	if (type & Rv4)
		*p++ = '4';
	else
		*p++ = '6';
	if (type & Rifc)
		*p++ = 'i';
	if (type & Runi)
		*p++ = 'u';
	else if (type & Rbcast)
		*p++ = 'b';
	else if (type & Rmulti)
		*p++ = 'm';
	if (type & Rptpt)
		*p = 'p';
}

char *rformat = "%-15I %-4M %-15I %4.4s %4.4s %3s\n";

void convroute(struct route *r, uint8_t *addr, uint8_t *mask, uint8_t *gate,
	       char *t, int *nifc)
{
	int i;

	if (r->rt.type & Rv4) {
		memmove(addr, v4prefix, IPv4off);
		hnputl(addr + IPv4off, r->v4.address);
		memset(mask, 0xff, IPv4off);
		hnputl(mask + IPv4off, ~(r->v4.endaddress ^ r->v4.address));
		memmove(gate, v4prefix, IPv4off);
		memmove(gate + IPv4off, r->v4.gate, IPv4addrlen);
	} else {
		for (i = 0; i < IPllen; i++) {
			hnputl(addr + 4 * i, r->v6.address[i]);
			hnputl(mask + 4 * i,
			       ~(r->v6.endaddress[i] ^ r->v6.address[i]));
		}
		memmove(gate, r->v6.gate, IPaddrlen);
	}

	routetype(r->rt.type, t);

	if (r->rt.ifc)
		*nifc = r->rt.ifc->conv->x;
	else
		*nifc = -1;
}

/*
 *  this code is not in rr to reduce stack size
 */
static void sprintroute(struct route *r, struct routewalk *rw)
{
	int nifc, n;
	char t[5], *iname, ifbuf[5];
	uint8_t addr[IPaddrlen], mask[IPaddrlen], gate[IPaddrlen];
	char *p;

	convroute(r, addr, mask, gate, t, &nifc);
	iname = "-";
	if (nifc != -1) {
		iname = ifbuf;
		snprintf(ifbuf, sizeof ifbuf, "%d", nifc);
	}
	p = seprintf(rw->p, rw->e, rformat, addr, mask, gate, t, r->rt.tag,
		     iname);
	if (rw->o < 0) {
		n = p - rw->p;
		if (n > -rw->o) {
			memmove(rw->p, rw->p - rw->o, n + rw->o);
			rw->p = p + rw->o;
		}
		rw->o += n;
	} else
		rw->p = p;
}

/*
 *  recurse descending tree, applying the function in Routewalk
 */
static int rr(struct route *r, struct routewalk *rw)
{
	int h;

	if (rw->e <= rw->p)
		return 0;
	if (r == NULL)
		return 1;

	if (rr(r->rt.left, rw) == 0)
		return 0;

	if (r->rt.type & Rv4)
		h = V4H(r->v4.address);
	else
		h = V6H(r->v6.address);

	if (h == rw->h)
		rw->walk(r, rw);

	if (rr(r->rt.mid, rw) == 0)
		return 0;

	return rr(r->rt.right, rw);
}

void ipwalkroutes(struct Fs *f, struct routewalk *rw)
{
	rlock(&routelock);
	if (rw->e > rw->p) {
		for (rw->h = 0; rw->h < ARRAY_SIZE(f->v4root); rw->h++)
			if (rr(f->v4root[rw->h], rw) == 0)
				break;
	}
	if (rw->e > rw->p) {
		for (rw->h = 0; rw->h < ARRAY_SIZE(f->v6root); rw->h++)
			if (rr(f->v6root[rw->h], rw) == 0)
				break;
	}
	runlock(&routelock);
}

long routeread(struct Fs *f, char *p, uint32_t offset, int n)
{
	struct routewalk rw;

	rw.p = p;
	rw.e = p + n;
	rw.o = -offset;
	rw.walk = sprintroute;

	ipwalkroutes(f, &rw);

	return rw.p - p;
}

/*
 *  this code is not in routeflush to reduce stack size
 */
void delroute(struct Fs *f, struct route *r, int dolock)
{
	uint8_t addr[IPaddrlen];
	uint8_t mask[IPaddrlen];
	uint8_t gate[IPaddrlen];
	char t[5];
	int nifc;

	convroute(r, addr, mask, gate, t, &nifc);
	if (r->rt.type & Rv4)
		v4delroute(f, addr + IPv4off, mask + IPv4off, dolock);
	else
		v6delroute(f, addr, mask, dolock);
}

/*
 *  recurse until one route is deleted
 *    returns 0 if nothing is deleted, 1 otherwise
 */
int routeflush(struct Fs *f, struct route *r, char *tag)
{
	if (r == NULL)
		return 0;
	if (routeflush(f, r->rt.mid, tag))
		return 1;
	if (routeflush(f, r->rt.left, tag))
		return 1;
	if (routeflush(f, r->rt.right, tag))
		return 1;
	if ((r->rt.type & Rifc) == 0) {
		if (tag == NULL ||
		    strncmp(tag, r->rt.tag, sizeof(r->rt.tag)) == 0) {
			delroute(f, r, 0);
			return 1;
		}
	}
	return 0;
}

long routewrite(struct Fs *f, struct chan *c, char *p, int n)
{
	ERRSTACK(1);
	int h, changed;
	char *tag;
	struct cmdbuf *cb;
	uint8_t addr[IPaddrlen];
	uint8_t mask[IPaddrlen];
	uint8_t gate[IPaddrlen];
	struct IPaux *a, *na;

	cb = parsecmd(p, n);
	if (waserror()) {
		kfree(cb);
		nexterror();
	}
	if (cb->nf < 1)
		error(EINVAL, "short control request");

	if (strcmp(cb->f[0], "flush") == 0) {
		tag = cb->f[1];
		for (h = 0; h < ARRAY_SIZE(f->v4root); h++)
			for (changed = 1; changed;) {
				wlock(&routelock);
				changed = routeflush(f, f->v4root[h], tag);
				wunlock(&routelock);
			}
		for (h = 0; h < ARRAY_SIZE(f->v6root); h++)
			for (changed = 1; changed;) {
				wlock(&routelock);
				changed = routeflush(f, f->v6root[h], tag);
				wunlock(&routelock);
			}
	} else if (strcmp(cb->f[0], "remove") == 0) {
		if (cb->nf < 3)
			error(EINVAL, ERROR_FIXME);
		parseip(addr, cb->f[1]);
		parseipmask(mask, cb->f[2]);
		if (memcmp(addr, v4prefix, IPv4off) == 0)
			v4delroute(f, addr + IPv4off, mask + IPv4off, 1);
		else
			v6delroute(f, addr, mask, 1);
	} else if (strcmp(cb->f[0], "add") == 0) {
		if (cb->nf < 4)
			error(EINVAL, ERROR_FIXME);
		parseip(addr, cb->f[1]);
		parseipmask(mask, cb->f[2]);
		parseip(gate, cb->f[3]);
		tag = "none";
		if (c != NULL) {
			a = c->aux;
			tag = a->tag;
		}
		if (memcmp(addr, v4prefix, IPv4off) == 0)
			v4addroute(f, tag, addr + IPv4off, mask + IPv4off,
				   gate + IPv4off, 0);
		else
			v6addroute(f, tag, addr, mask, gate, 0);
	} else if (strcmp(cb->f[0], "tag") == 0) {
		if (cb->nf < 2)
			error(EINVAL, ERROR_FIXME);

		a = c->aux;
		na = newipaux(a->owner, cb->f[1]);
		c->aux = na;
		kfree(a);
	}

	poperror();
	kfree(cb);
	return n;
}
