~kris/9p

9hist

dc81b36ec040feee81bc100c5396a1f2e881f77d — David du Colombier 28 years ago 01c8a08
Plan 9 from Bell Labs 1998-03-07
8 files changed, 71 insertions(+), 111 deletions(-)

M ip/ethermedium.c
M ip/il.c
M ip/ip.c
M ip/ip.h
M ip/ipifc.c
M ip/netlog.c
M ip/nullmedium.c
M ip/pktmedium.c
M ip/ethermedium.c => ip/ethermedium.c +9 -17
@@ 45,6 45,7 @@ Medium ethermedium =
	nil,			/* flushroute */
	nil,			/* joinmulti */
	nil,			/* leavemulti */
	0,			/* don't unbind on last close */
};

typedef struct	Etherrock Etherrock;


@@ 205,7 206,7 @@ etherunbind(Ipifc *ifc)
}

/*
 *  called by ipoput with a single block to write
 *  called by ipoput with a single block to write with ifc rlock'd
 */
static void
etherbwrite(Ipifc *ifc, Block *bp, int version, uchar *ip)


@@ 215,17 216,6 @@ etherbwrite(Ipifc *ifc, Block *bp, int version, uchar *ip)
	uchar mac[6];
	Etherrock *er = ifc->arg;

	if(waserror()) {
		print("etherbwrite failed\n");
		ipifccheckout(ifc);
		return;
	}
	if(ipifccheckin(ifc, &ethermedium) < 0){
		freeb(bp);
		poperror();
		return;
	}

	/* get mac address of destination */
	a = arpget(bp, version, &ethermedium, ip, mac);
	if(a){


@@ 233,7 223,7 @@ etherbwrite(Ipifc *ifc, Block *bp, int version, uchar *ip)
		bp = multicastarp(a, mac);
		if(bp == nil){
			sendarp(ifc, a);
			goto out;
			return;
		}
	}



@@ 261,10 251,6 @@ etherbwrite(Ipifc *ifc, Block *bp, int version, uchar *ip)

	devtab[er->mchan->type]->bwrite(er->mchan, bp, 0);
	ifc->out++;

out:
	ipifccheckout(ifc);
	poperror();
}

/*


@@ 276,22 262,28 @@ etherread(void *a)
	Ipifc *ifc;
	Block *bp;
	Etherrock *er;
	int locked = 0;

	ifc = a;
	er = ifc->arg;
	er->readp = up;	/* hide identity under a rock for unbind */
	if(waserror()){
		if(locked)
			runlock(ifc);
		er->readp = 0;
		pexit("hangup", 1);
	}
	for(;;){
		bp = devtab[er->mchan->type]->bread(er->mchan, ifc->maxmtu, 0);
		rlock(ifc);	locked = 1;	USED(locked);
		ifc->in++;
		bp->rp += ifc->m->hsize;
		if(ifc->lifc == nil)
			freeb(bp);
		else
			ipiput(ifc->lifc->local, bp);
		runlock(ifc);	locked = 0;	USED(locked);

	}
}


M ip/il.c => ip/il.c +1 -0
@@ 347,6 347,7 @@ ilxstats(char *buf, int len)
		il.csumerr, il.hlenerr, il.lenerr, il.order, il.rexmit);
	n += snprint(buf+n, len-n, " dupp %d dupb %d\n",
		ilstats.dup, ilstats.dupb);
	return n;
}

void

M ip/ip.c => ip/ip.c +13 -1
@@ 127,6 127,14 @@ ipoput(Block *bp, int gating, int ttl)
	}
	ifc = r->ifc;

	if(waserror()){
		runlock(ifc);
		nexterror();
	}
	rlock(ifc);
	if(ifc->m == nil)
		goto raise;

	/* If we dont need to fragment just send it */
	medialen = ifc->m->maxmtu - ifc->m->hsize;
	if(len <= medialen) {


@@ 141,6 149,8 @@ ipoput(Block *bp, int gating, int ttl)

/*print("ipoput %V->%V via %V\n", eh->src, eh->dst, gate);*/
		ifc->m->bwrite(ifc, bp, V4, gate);
		runlock(ifc);
		poperror();
		return;
	}



@@ 203,7 213,7 @@ ipoput(Block *bp, int gating, int ttl)
			chunk -= blklen;
			if(xp->rp == xp->wp)
				xp = xp->next;
		} 
		}

		feh->cksum[0] = 0;
		feh->cksum[1] = 0;


@@ 212,6 222,8 @@ ipoput(Block *bp, int gating, int ttl)
	}

raise:
	runlock(ifc);
	poperror();
	freeblist(bp);	
}


M ip/ip.h => ip/ip.h +4 -2
@@ 116,6 116,8 @@ struct Medium
	/* for routing multicast groups */
	void	(*joinmulti)(Ipifc *ifc, uchar *a, uchar *ia, uchar **iap);
	void	(*leavemulti)(Ipifc *ifc, uchar *a, uchar *ia);

	int	unbindonclose;	/* if non-zero, unbind on last close */
};

/* logical interface associated with a physical one */


@@ 132,9 134,9 @@ struct Iplifc
/* binding twixt Ipself and Ipifc */
struct Iplink
{
	Ipself	*local;
	Ipself	*self;
	Iplifc	*lifc;
	Iplink	*locallink;	/* next link for this local address */
	Iplink	*selflink;	/* next link for this local address */
	Iplink	*lifclink;	/* next link for this ifc */
	ulong	expire;
	Iplink	*next;		/* free list */

M ip/ipifc.c => ip/ipifc.c +42 -90
@@ 23,6 23,7 @@ extern	Fs	fs;
Medium *media[] =
{
	&ethermedium,
	&pktmedium,
	&nullmedium,
	0
};


@@ 151,16 152,18 @@ ipifcunbind(Ipifc *ifc)
	}
	wlock(ifc);

	if(ipifcgrab(ifc) == 0);
		goto out;
	/* dissociate routes */
	ifc->ifcid++;

	/* disassociate device */
	(*ifc->m->unbind)(ifc);
	memset(ifc->dev, 0, sizeof(ifc->dev));
	ifc->arg = nil;

	/* hangup queues to stop queuing of packets */
	qhangup(ifc->conv->rq, "unbind");
	qhangup(ifc->conv->wq, "unbind");

	/* dissociate routes */
	ifc->ifcid++;

	/* disassociate logical interfaces */
	av[0] = "remove";
	av[1] = ip;


@@ 172,14 175,7 @@ ipifcunbind(Ipifc *ifc)
		ipifcrem(ifc, av, 3, 0);
	}

	/* disassociate device */
	(*ifc->m->unbind)(ifc);
	memset(ifc->dev, 0, sizeof(ifc->dev));
	ifc->arg = nil;
	ifc->m = &nullmedium;
	ifc->unbinding = 0;

out:
	ifc->m = nil;
	wunlock(ifc);
	poperror();
	return nil;


@@ 223,7 219,7 @@ ipifclocal(Conv *c, char *state, int n)
	for(lifc = ifc->lifc; lifc; lifc = lifc->next){
		m += snprint(state+m, n - m, "%-20.20I ->", lifc->local);
		for(link = lifc->link; link; link = link->lifclink)
			m += snprint(state+m, n - m, " %-20.20I", link->local->a);
			m += snprint(state+m, n - m, " %-20.20I", link->self->a);
		m += snprint(state+m, n - m, "\n");
	}
	runlock(ifc);


@@ 272,6 268,8 @@ ipifccreate(Conv *c)
	c->wq = qopen(QMAX, 0, 0, 0);
	ifc = (Ipifc*)c->ptcl;
	ifc->conv = c;
	ifc->unbinding = 0;
	ifc->m = nil;
}

/* 


@@ 281,10 279,13 @@ ipifccreate(Conv *c)
static void
ipifcclose(Conv *c)
{
	/*
	 *  nothing to do since conversation stays open
	 *  till the device is unbound.
	 */
	Ipifc *ifc;
	Medium *m;

	ifc = (Ipifc*)c->ptcl;
	m = ifc->m;
	if(m != nil && m->unbindonclose)
		ipifcunbind(ifc);
	unlock(c);
}



@@ 423,7 424,7 @@ ipifcrem(Ipifc *ifc, char **argv, int argc, int dolock)

	/* disassociate any addresses */
	while(lifc->link)
		remselfcache(ifc, lifc, lifc->link->local->a);
		remselfcache(ifc, lifc, lifc->link->self->a);

	/* remove the route for this logical interface */
	if(isv4(ip))


@@ 456,6 457,8 @@ ipifcaddroute(int vers, uchar *addr, uchar *mask, uchar *gate, int type)
		if(*cp != nil) {
			ifc = (Ipifc*)(*cp)->ptcl;
			m = ifc->m;
			if(m == nil)
				continue;
			if(m->addroute != nil)
				m->addroute(ifc, vers, addr, mask, gate, type);
		}


@@ 473,6 476,8 @@ ipifcremroute(int vers, uchar *addr, uchar *mask)
		if(*cp != nil) {
			ifc = (Ipifc*)(*cp)->ptcl;
			m = ifc->m;
			if(m == nil)
				continue;
			if(m->remroute != nil)
				m->remroute(ifc, vers, addr, mask);
		}


@@ 603,7 608,7 @@ addselfcache(Ipifc *ifc, Iplifc *lifc, uchar *a, int type)
	}

	/* look for a link for this lifc */
	for(lp = p->link; lp; lp = lp->locallink)
	for(lp = p->link; lp; lp = lp->selflink)
		if(lp->lifc == lifc)
			break;



@@ 612,8 617,8 @@ addselfcache(Ipifc *ifc, Iplifc *lifc, uchar *a, int type)
		lp = smalloc(sizeof(*lp));
		lp->ref = 1;
		lp->lifc = lifc;
		lp->local = p;
		lp->locallink = p->link;
		lp->self = p;
		lp->selflink = p->link;
		p->link = lp;
		lp->lifclink = lifc->link;
		lifc->link = lp;


@@ 690,7 695,7 @@ static void
remselfcache(Ipifc *ifc, Iplifc *lifc, uchar *a)
{
	Ipself *p, **l;
	Iplink *lp, *llp, **ill, **lll;
	Iplink *link, **l_self, **l_lifc;

	qlock(&selftab);



@@ 709,40 714,40 @@ remselfcache(Ipifc *ifc, Iplifc *lifc, uchar *a)
	 *  walk down links from an ifc looking for one
	 *  that matches the selftab entry
	 */
	ill = &lifc->link;
	for(lp = *ill; lp; lp = *ill){
		if(lp->local == p)
	l_lifc = &lifc->link;
	for(link = *l_lifc; link; link = *l_lifc){
		if(link->self == p)
			break;
		ill = &lp->lifclink;
		l_lifc = &link->lifclink;
	}

	if(lp == nil)
	if(link == nil)
		goto out;

	/*
	 *  walk down the links from the selftab looking for
	 *  the one we just found
	 */
	lll = &p->link;
	for(llp = *lll; llp; llp = *lll){
		if(llp == lp)
	l_self = &p->link;
	for(link = *l_self; link; link = *l_self){
		if(link == *(l_lifc))
			break;
		lll = &lp->locallink;
		l_self = &link->selflink;
	}

	if(llp == nil)
	if(link == nil)
		panic("remselfcache");

	if(--(llp->ref) != 0)
	if(--(link->ref) != 0)
		goto out;

	if((p->type & Rmulti) && ifc->m->remmulti != nil)
		(*ifc->m->remmulti)(ifc, a, lifc->local);

	/* ref == 0, remove from both chains and free the link */
	*ill = lp->lifclink;
	*lll = llp->locallink;
	iplinkfree(lp);
	*l_lifc = link->lifclink;
	*l_self = link->selflink;
	iplinkfree(link);

	/* remove from routing table */
	if(isv4(a))


@@ 1004,59 1009,6 @@ ipismulticast(uchar *ip)
}

/*
 *  used to allow on the fly unbinds, return -1 if interface unusable
 */
int
ipifccheckin(Ipifc *ifc, Medium *med)
{
	int rv;

	lock(&ifc->idlock);
	if(ifc->unbinding || ifc->m != med)
		rv = -1;
	else
		rv = ++(ifc->ref);
	if(ifc->ref < 0) panic("ipifccheckin");
	unlock(&ifc->idlock);
	return rv;
}

void
ipifccheckout(Ipifc *ifc)
{
	lock(&ifc->idlock);
	if(--(ifc->ref) == 0)
	if(ifc->unbinding)
		wakeup(&ifc->wait);
	if(ifc->ref < 0) panic("ipifccheckin");
	unlock(&ifc->idlock);
}

static int
allout(void *x)
{
	Ipifc *ifc = x;

	return ifc->ref == 0;
}

int
ipifcgrab(Ipifc *ifc)
{
	lock(&ifc->idlock);
	if(ifc->unbinding){
		unlock(&ifc->idlock);
		return 0;
	}
	ifc->unbinding = 1;		/* after this ref can only go down */
	unlock(&ifc->idlock);

	sleep(&ifc->wait, allout, ifc);

	return 1;
}

/*
 *  add a multicast address to an interface, called with c->car locked
 */
void

M ip/netlog.c => ip/netlog.c +0 -1
@@ 152,7 152,6 @@ netlogctl(char* s, int len)
	int i, n, set;
	Logflag *f;
	char *fields[10], *p, buf[256];
	uchar addr[IPaddrlen];

	if(len == 0)
		return Ebadnetctl;

M ip/nullmedium.c => ip/nullmedium.c +1 -0
@@ 43,4 43,5 @@ Medium nullmedium =
	nil,		/* flushroute */
	nil,		/* joinmulti */
	nil,		/* leave multi */
	0,		/* don't unbind on last close */
};

M ip/pktmedium.c => ip/pktmedium.c +1 -0
@@ 32,6 32,7 @@ Medium pktmedium =
	nil,		/* flushroute */
	nil,		/* joinmulti */
	nil,		/* leave multi */
	1,		/* unbind on last close */
};

/*