예제 #1
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;
}
예제 #2
0
파일: ipifc.c 프로젝트: 7perl/akaros
// added for new v6 mesg types
static void adddefroute6(struct Fs *f, uint8_t * gate, int force)
{
	struct route *r;

	r = v6lookup(f, v6Unspecified, NULL);
	if (r != NULL)
		if (!(force) && (strcmp(r->rt.tag, "ra") != 0))	// route entries generated
			return;	// by all other means take
	// precedence over router annc

	v6delroute(f, v6Unspecified, v6Unspecified, 1);
	v6addroute(f, "ra", v6Unspecified, v6Unspecified, gate, 0);
}
예제 #3
0
파일: ipifc.c 프로젝트: qioixiy/harvey
/* added for new v6 mesg types */
static void
adddefroute6(Fs *f, uint8_t *gate, int force)
{
	Route *r;

	r = v6lookup(f, v6Unspecified, nil);
	/*
	 * route entries generated by all other means take precedence
	 * over router announcements.
	 */
	if (r && !force && strcmp(r->tag, "ra") != 0)
		return;

	v6delroute(f, v6Unspecified, v6Unspecified, 1);
	v6addroute(f, "ra", v6Unspecified, v6Unspecified, gate, 0);
}
예제 #4
0
파일: ipifc.c 프로젝트: qioixiy/harvey
/*
 *  Decrement reference for this address on this link.
 *  Unlink from selftab if this is the last ref.
 *	called with c->car locked
 */
static void
remselfcache(Fs *f, Ipifc *ifc, Iplifc *lifc, uint8_t *a)
{
	Ipself *p, **l;
	Iplink *link, **l_self, **l_lifc;

	qlock(f->self);

	/* find the unique selftab entry */
	l = &f->self->hash[hashipa(a)];
	for(p = *l; p; p = *l){
		if(ipcmp(p->a, a) == 0)
			break;
		l = &p->next;
	}

	if(p == nil)
		goto out;

	/*
	 *  walk down links from an ifc looking for one
	 *  that matches the selftab entry
	 */
	l_lifc = &lifc->link;
	for(link = *l_lifc; link; link = *l_lifc){
		if(link->self == p)
			break;
		l_lifc = &link->lifclink;
	}

	if(link == nil)
		goto out;

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

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

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

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

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

	if(p->link != nil)
		goto out;

	/* remove from routing table */
	if(isv4(a))
		v4delroute(f, a+IPv4off, IPallbits+IPv4off, 1);
	else
		v6delroute(f, a, IPallbits, 1);

	/* no more links, remove from hash and free */
	*l = p->next;
	ipselffree(p);

	/* if IPnoaddr, forget */
	if(ipcmp(a, v4prefix) == 0 || ipcmp(a, IPnoaddr) == 0)
		f->self->acceptall = 0;

out:
	qunlock(f->self);
}