{
char *err;
+ wlock(ifc);
if(waserror()){
wunlock(ifc);
nexterror();
}
- wlock(ifc);
-
- /* dissociate routes */
- if(ifc->m != nil && ifc->m->unbindonclose == 0)
- ifc->conv->inuse--;
- ifc->ifcid++;
/* disassociate logical interfaces (before zeroing ifc->arg) */
while(ifc->lifc){
qclose(ifc->conv->wq);
qclose(ifc->conv->sq);
+ /* dissociate routes */
+ ifc->ifcid++;
+ if(ifc->m != nil && ifc->m->unbindonclose == 0)
+ ifc->conv->inuse--;
ifc->m = nil;
+
wunlock(ifc);
poperror();
return nil;
runlock(ifc);
nexterror();
}
- if(ifc->m == nil || ifc->m->pktin == nil)
- freeb(bp);
- else
+ if(ifc->m && ifc->m->pktin)
(*ifc->m->pktin)(c->p->f, ifc, bp);
+ else
+ freeb(bp);
runlock(ifc);
poperror();
}
}
if(isv4(ip))
tentative = 0;
+
wlock(ifc);
+ if(waserror()){
+ wunlock(ifc);
+ nexterror();
+ }
/* ignore if this is already a local address for this ifc */
for(lifc = ifc->lifc; lifc; lifc = lifc->next) {
}
/* register the address on this network for address resolution */
- if(isv4(ip) && ifc->m->areg != nil)
+ if(isv4(ip) && ifc->m->areg)
(*ifc->m->areg)(ifc, ip);
out:
wunlock(ifc);
+ poperror();
+
if(tentative && sendnbrdisc)
icmpns(f, 0, SRC_UNSPEC, ip, TARG_MULTI, ifc->mac);
return nil;
if (parseip(rem, argv[3]) == -1)
return Ebadip;
- wlock(ifc);
-
/*
* find address on this interface and remove from chain.
* for pt to pt we actually specify the remote address as the
* addresss to remove.
*/
+ wlock(ifc);
for(lifc = ifc->lifc; lifc != nil; lifc = lifc->next) {
if (memcmp(ip, lifc->local, IPaddrlen) == 0
&& memcmp(mask, lifc->mask, IPaddrlen) == 0
&& memcmp(rem, lifc->remote, IPaddrlen) == 0)
break;
}
-
rv = ipifcremlifc(ifc, lifc);
wunlock(ifc);
return rv;
ifc = (Ipifc*)(*cp)->ptcl;
m = ifc->m;
if(m && m->addroute)
- m->addroute(ifc, vers, addr, mask, gate, type);
+ (*m->addroute)(ifc, vers, addr, mask, gate, type);
}
}
}
if(*cp != nil) {
ifc = (Ipifc*)(*cp)->ptcl;
m = ifc->m;
- if(m && m->remroute)
- m->remroute(ifc, vers, addr, mask);
+ if(m && m->remroute){
+ if(!waserror()){
+ (*m->remroute)(ifc, vers, addr, mask);
+ poperror();
+ }
+ }
}
}
}
if(ifc->m == nil)
return "ipifc not yet bound to device";
- if(waserror()){
- wunlock(ifc);
- nexterror();
- }
wlock(ifc);
while(ifc->lifc){
err = ipifcremlifc(ifc, ifc->lifc);
- if(err)
- error(err);
+ if(err){
+ wunlock(ifc);
+ return err;
+ }
}
wunlock(ifc);
- poperror();
err = ipifcadd(ifc, argv, argc, 0, nil);
if(err)
int h;
qlock(f->self);
+ if(waserror()){
+ qunlock(f->self);
+ nexterror();
+ }
/* see if the address already exists */
h = hashipa(a);
else
v6addroute(f, tifc, a, IPallbits, a, type);
- if((type & Rmulti) && ifc->m->addmulti != nil)
+ if((type & Rmulti) && ifc->m->addmulti)
(*ifc->m->addmulti)(ifc, a, lifc->local);
} else
lp->ref++;
qunlock(f->self);
+ poperror();
}
/*
if(--(link->ref) != 0)
goto out;
- if((p->type & Rmulti) && ifc->m->remmulti != nil)
- (*ifc->m->remmulti)(ifc, a, lifc->local);
+ if((p->type & Rmulti) && ifc->m->remmulti){
+ if(!waserror()){
+ (*ifc->m->remmulti)(ifc, a, lifc->local);
+ poperror();
+ }
+ }
/* ref == 0, remove from both chains and free the link */
*l_lifc = link->lifclink;
if((*p)->inuse == 0)
continue;
ifc = (Ipifc*)(*p)->ptcl;
+ wlock(ifc);
if(waserror()){
wunlock(ifc);
nexterror();
}
- wlock(ifc);
for(lifc = ifc->lifc; lifc; lifc = lifc->next)
if(ipcmp(ia, lifc->local) == 0)
addselfcache(f, ifc, lifc, ma, Rmulti);
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);
runlock(nifc);
continue;
}
+ if(waserror()){
+ runlock(nifc);
+ nexterror();
+ }
for(lifc = nifc->lifc; lifc; lifc = lifc->next){
maskip(ip, lifc->mask, net);
if(ipcmp(net, lifc->remote) == 0) {
}
}
runlock(nifc);
+ poperror();
}
}
else { /* V4 */
runlock(nifc);
continue;
}
+ if(waserror()){
+ runlock(nifc);
+ nexterror();
+ }
for(lifc = nifc->lifc; lifc; lifc = lifc->next){
maskip(ip, lifc->mask, net);
if(ipcmp(net, lifc->remote) == 0){
}
}
runlock(nifc);
+ poperror();
}
}
}
lifc->origint = origint;
/* issue "add" ctl msg for v6 link-local addr and prefix len */
- if(!ifc->m->pref2addr)
+ if(ifc->m->pref2addr == nil)
return Ebadarg;
- ifc->m->pref2addr(prefix, ifc->mac); /* mac → v6 link-local addr */
+ (*ifc->m->pref2addr)(prefix, ifc->mac); /* mac → v6 link-local addr */
sprint(addr, "%I", prefix);
sprint(preflen, "/%d", plen);
params[0] = "add";