plan 9 kernel history: overview | file list | diff list

1998/0307/ip/ipifc.c (diff list | history)

1998/0306/sys/src/9/ip/ipifc.c:23,281998/0307/sys/src/9/ip/ipifc.c:23,29 (short | long | prev | next)
1998/0306    
Medium *media[] = 
{ 
	ðermedium, 
1998/0307    
	&pktmedium, 
1998/0306    
	&nullmedium, 
	0 
}; 
1998/0306/sys/src/9/ip/ipifc.c:151,1661998/0307/sys/src/9/ip/ipifc.c:152,169
1998/0306    
	} 
	wlock(ifc); 
 
	if(ipifcgrab(ifc) == 0); 
		goto out; 
1998/0307    
	/* dissociate routes */ 
	ifc->ifcid++; 
1998/0306    
 
1998/0307    
	/* disassociate device */ 
	(*ifc->m->unbind)(ifc); 
	memset(ifc->dev, 0, sizeof(ifc->dev)); 
	ifc->arg = nil; 
 
1998/0306    
	/* 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; 
1998/0306/sys/src/9/ip/ipifc.c:172,1851998/0307/sys/src/9/ip/ipifc.c:175,181
1998/0306    
		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: 
1998/0307    
	ifc->m = nil; 
1998/0306    
	wunlock(ifc); 
	poperror(); 
	return nil; 
1998/0306/sys/src/9/ip/ipifc.c:223,2291998/0307/sys/src/9/ip/ipifc.c:219,225
1998/0306    
	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); 
1998/0307    
			m += snprint(state+m, n - m, " %-20.20I", link->self->a); 
1998/0306    
		m += snprint(state+m, n - m, "\n"); 
	} 
	runlock(ifc); 
1998/0306/sys/src/9/ip/ipifc.c:272,2771998/0307/sys/src/9/ip/ipifc.c:268,275
1998/0306    
	c->wq = qopen(QMAX, 0, 0, 0); 
	ifc = (Ipifc*)c->ptcl; 
	ifc->conv = c; 
1998/0307    
	ifc->unbinding = 0; 
	ifc->m = nil; 
1998/0306    
} 
 
/*  
1998/0306/sys/src/9/ip/ipifc.c:281,2901998/0307/sys/src/9/ip/ipifc.c:279,291
1998/0306    
static void 
ipifcclose(Conv *c) 
{ 
	/* 
	 *  nothing to do since conversation stays open 
	 *  till the device is unbound. 
	 */ 
1998/0307    
	Ipifc *ifc; 
	Medium *m; 
 
	ifc = (Ipifc*)c->ptcl; 
	m = ifc->m; 
	if(m != nil && m->unbindonclose) 
		ipifcunbind(ifc); 
1998/0306    
	unlock(c); 
} 
 
1998/0306/sys/src/9/ip/ipifc.c:423,4291998/0307/sys/src/9/ip/ipifc.c:424,430
1998/0306    
 
	/* disassociate any addresses */ 
	while(lifc->link) 
		remselfcache(ifc, lifc, lifc->link->local->a); 
1998/0307    
		remselfcache(ifc, lifc, lifc->link->self->a); 
1998/0306    
 
	/* remove the route for this logical interface */ 
	if(isv4(ip)) 
1998/0306/sys/src/9/ip/ipifc.c:456,4611998/0307/sys/src/9/ip/ipifc.c:457,464
1998/0306    
		if(*cp != nil) { 
			ifc = (Ipifc*)(*cp)->ptcl; 
			m = ifc->m; 
1998/0307    
			if(m == nil) 
				continue; 
1998/0306    
			if(m->addroute != nil) 
				m->addroute(ifc, vers, addr, mask, gate, type); 
		} 
1998/0306/sys/src/9/ip/ipifc.c:473,4781998/0307/sys/src/9/ip/ipifc.c:476,483
1998/0306    
		if(*cp != nil) { 
			ifc = (Ipifc*)(*cp)->ptcl; 
			m = ifc->m; 
1998/0307    
			if(m == nil) 
				continue; 
1998/0306    
			if(m->remroute != nil) 
				m->remroute(ifc, vers, addr, mask); 
		} 
1998/0306/sys/src/9/ip/ipifc.c:603,6091998/0307/sys/src/9/ip/ipifc.c:608,614
1998/0306    
	} 
 
	/* look for a link for this lifc */ 
	for(lp = p->link; lp; lp = lp->locallink) 
1998/0307    
	for(lp = p->link; lp; lp = lp->selflink) 
1998/0306    
		if(lp->lifc == lifc) 
			break; 
 
1998/0306/sys/src/9/ip/ipifc.c:612,6191998/0307/sys/src/9/ip/ipifc.c:617,624
1998/0306    
		lp = smalloc(sizeof(*lp)); 
		lp->ref = 1; 
		lp->lifc = lifc; 
		lp->local = p; 
		lp->locallink = p->link; 
1998/0307    
		lp->self = p; 
		lp->selflink = p->link; 
1998/0306    
		p->link = lp; 
		lp->lifclink = lifc->link; 
		lifc->link = lp; 
1998/0306/sys/src/9/ip/ipifc.c:690,6961998/0307/sys/src/9/ip/ipifc.c:695,701
1998/0306    
remselfcache(Ipifc *ifc, Iplifc *lifc, uchar *a) 
{ 
	Ipself *p, **l; 
	Iplink *lp, *llp, **ill, **lll; 
1998/0307    
	Iplink *link, **l_self, **l_lifc; 
1998/0306    
 
	qlock(&selftab); 
 
1998/0306/sys/src/9/ip/ipifc.c:709,7221998/0307/sys/src/9/ip/ipifc.c:714,727
1998/0306    
	 *  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) 
1998/0307    
	l_lifc = &lifc->link; 
	for(link = *l_lifc; link; link = *l_lifc){ 
		if(link->self == p) 
1998/0306    
			break; 
		ill = &lp->lifclink; 
1998/0307    
		l_lifc = &link->lifclink; 
1998/0306    
	} 
 
	if(lp == nil) 
1998/0307    
	if(link == nil) 
1998/0306    
		goto out; 
 
	/* 
1998/0306/sys/src/9/ip/ipifc.c:723,7391998/0307/sys/src/9/ip/ipifc.c:728,744
1998/0306    
	 *  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) 
1998/0307    
	l_self = &p->link; 
	for(link = *l_self; link; link = *l_self){ 
		if(link == *(l_lifc)) 
1998/0306    
			break; 
		lll = &lp->locallink; 
1998/0307    
		l_self = &link->selflink; 
1998/0306    
	} 
 
	if(llp == nil) 
1998/0307    
	if(link == nil) 
1998/0306    
		panic("remselfcache"); 
 
	if(--(llp->ref) != 0) 
1998/0307    
	if(--(link->ref) != 0) 
1998/0306    
		goto out; 
 
	if((p->type & Rmulti) && ifc->m->remmulti != nil) 
1998/0306/sys/src/9/ip/ipifc.c:740,7481998/0307/sys/src/9/ip/ipifc.c:745,753
1998/0306    
		(*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); 
1998/0307    
	*l_lifc = link->lifclink; 
	*l_self = link->selflink; 
	iplinkfree(link); 
1998/0306    
 
	/* remove from routing table */ 
	if(isv4(a)) 
1998/0306/sys/src/9/ip/ipifc.c:1001,10591998/0307/sys/src/9/ip/ipifc.c:1006,1011
1998/0306    
			return V6; 
	} 
	return 0; 
} 
                 
/* 
 *  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; 
} 
 
/* 


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)