예제 #1
0
파일: ipifc.c 프로젝트: qioixiy/harvey
/*
 *  remove a multicast address from an interface, called with c->car locked
 */
void
ipifcremmulti(Conv *c, uint8_t *ma, uint8_t *ia)
{
	Proc *up = externup();
	Ipmulti *multi, **l;
	Iplifc *lifc;
	Conv **p;
	Ipifc *ifc;
	Fs *f;

	f = c->p->f;

	for(l = &c->multi; *l; l = &(*l)->next)
		if(ipcmp(ma, (*l)->ma) == 0 && ipcmp(ia, (*l)->ia) == 0)
			break;

	multi = *l;
	if(multi == nil)
		return; 	/* we don't have it open */

	*l = multi->next;

	for(p = f->ipifc->conv; *p; p++){
		if((*p)->inuse == 0)
			continue;

		ifc = (Ipifc*)(*p)->ptcl;
		if(waserror()){
			wunlock(ifc);
			nexterror();
		}
		wlock(ifc);
		for(lifc = ifc->lifc; lifc; lifc = lifc->next)
			if(ipcmp(ia, lifc->local) == 0)
				remselfcache(f, ifc, lifc, ma);
		wunlock(ifc);
		poperror();
	}

	free(multi);
}
예제 #2
0
파일: ipifc.c 프로젝트: 7perl/akaros
/*
 *  remove a multicast address from an interface, called with c locked
 */
void ipifcremmulti(struct conv *c, uint8_t * ma, uint8_t * ia)
{
	ERRSTACK(1);
	struct Ipmulti *multi, **l;
	struct Iplifc *lifc;
	struct conv **p;
	struct Ipifc *ifc;
	struct Fs *f;

	f = c->p->f;

	for (l = &c->multi; *l; l = &(*l)->next)
		if (ipcmp(ma, (*l)->ma) == 0)
			if (ipcmp(ia, (*l)->ia) == 0)
				break;

	multi = *l;
	if (multi == NULL)
		return;	/* we don't have it open */

	*l = multi->next;

	for (p = f->ipifc->conv; *p; p++) {
		if ((*p)->inuse == 0)
			continue;

		ifc = (struct Ipifc *)(*p)->ptcl;
		if (waserror()) {
			wunlock(&ifc->rwlock);
			nexterror();
		}
		wlock(&ifc->rwlock);
		for (lifc = ifc->lifc; lifc; lifc = lifc->next)
			if (ipcmp(ia, lifc->local) == 0)
				remselfcache(f, ifc, lifc, ma);
		wunlock(&ifc->rwlock);
		poperror();
	}

	kfree(multi);
}
예제 #3
0
파일: ipifc.c 프로젝트: qioixiy/harvey
/*
 *  remove a logical interface from an ifc
 *  always called with ifc wlock'd
 */
static char*
ipifcremlifc(Ipifc *ifc, Iplifc *lifc)
{
	Iplifc **l;
	Fs *f;

	f = ifc->conv->p->f;

	/*
	 *  find address on this interface and remove from chain.
	 *  for pt to pt we actually specify the remote address as the
	 *  addresss to remove.
	 */
	for(l = &ifc->lifc; *l != nil && *l != lifc; l = &(*l)->next)
		;
	if(*l == nil)
		return "address not on this interface";
	*l = lifc->next;

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

	/* remove the route for this logical interface */
	if(isv4(lifc->local))
		v4delroute(f, lifc->remote+IPv4off, lifc->mask+IPv4off, 1);
	else {
		v6delroute(f, lifc->remote, lifc->mask, 1);
		if(ipcmp(lifc->local, v6loopback) == 0)
			/* remove route for all node multicast */
			v6delroute(f, v6allnodesN, v6allnodesNmask, 1);
		else if(memcmp(lifc->local, v6linklocal, v6llpreflen) == 0)
			/* remove route for all link multicast */
			v6delroute(f, v6allnodesL, v6allnodesLmask, 1);
	}

	free(lifc);
	return nil;
}