ref: 14f0eae74a9a9f5c5caebbecb11b136a12e65a22
parent: 04d6a2acecfe4fe44947da8b676f63bcd0f3c0fe
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat Nov 18 12:58:10 EST 2023
devip: have findipifc() return rlock'd interface, allow to use "del" instead of "remove" for route and interface operations The findipifc() function is kind of useless when it returns an unlocked interface without also providing the ifcid as the interface can be subject to reconfiguration while unlocked. Instead, we make findipifc() keep the interface that it returns locked. This is also needed for v4source() and v6source() functions, which call ipv4local()/ipv4local() which in turn walk the local interface chain, and must do so under the rlock. Also, accept the "del" verb in addition to "remove" to keep it consistent, which also leads to much more consistent naming in the code. Abbreviating remove to "rem" can collide with abbreviations for remote.
--- a/sys/man/3/ip
+++ b/sys/man/3/ip
@@ -210,8 +210,8 @@
.IR trampoline (8)
to a different ip stack.
.TP
-.BI remove\ "local mask"
-Remove a local IP address from an interface.
+.BI del\ "local mask"
+Delete a local IP address from an interface.
.TP
.BI mtu\ n
Set the maximum transfer unit for this device to
@@ -271,8 +271,8 @@
.I Media-addr
on this interface as a local address.
.TP
-.BI remmulti\ Media-addr
-Remove the multicast address
+.BI delmulti\ Media-addr
+Delete the multicast address
.I Media-addr
from this interface.
.TP
@@ -310,8 +310,8 @@
.RE
.PD
.TP
-.B remove6
-Remove local IPv6 addresses that have expired ther
+.B del6
+Delete local IPv6 addresses that have expired ther
valid life-time.
.TP
.BI "ra6 " "keyword value ..."
@@ -465,20 +465,20 @@
.B "-"
when unspecified.
.TP
-.BI remove\ "target mask"
+.BI del\ "target mask"
.TP
-.BI remove\ "target mask nexthop"
+.BI del\ "target mask nexthop"
.TP
-.BI remove\ "target mask source smask"
+.BI del\ "target mask source smask"
.TP
-.BI remove\ "target mask nexthop source smask"
+.BI del\ "target mask nexthop source smask"
.TP
-.BI remove\ "target mask nexthop interface source smask"
+.BI del\ "target mask nexthop interface source smask"
.TP
-.BI remove\ "target mask nexthop flags interface source smask"
+.BI del\ "target mask nexthop flags interface source smask"
.TP
-.BI remove\ "target mask nexthop flags tag interface source smask"
-Remove the matching route.
+.BI del\ "target mask nexthop flags tag interface source smask"
+Delete the matching route.
.
.SS "Address resolution
The file
@@ -662,7 +662,7 @@
to receive incoming calls.
.PP
The following control messages are supported:
-.TF "\fLremmulti \fIip\fR"
+.TF "\fLdelmulti \fIip\fR"
.PD
.TP
.BI connect\ ip-address ! port "!r " local
@@ -760,8 +760,8 @@
is present,
use it as the interface's multicast address.
.TP
-.BI remmulti\ ip
-Remove the address
+.BI delmulti\ ip
+Delete the address
.I ip
from this multicast interface.
.PP
--- a/sys/src/9/ip/arp.c
+++ b/sys/src/9/ip/arp.c
@@ -494,7 +494,6 @@
}
if((ifc = findipifc(fs, ia, ia, Runi)) == nil)
error("no interface");
- rlock(ifc);
if(!ipv6local(ifc, ia, 0, ip) || arpenter(fs, V6, ip, mac, n, ia, ifc, 0) < 0){
runlock(ifc);
error("destination unreachable");
@@ -522,8 +521,6 @@
if((ifc = findipifc(fs, ip, ip, Runi)) == nil)
error("no interface");
-
- rlock(ifc);
if(waserror()){
runlock(ifc);
nexterror();
--- a/sys/src/9/ip/devip.c
+++ b/sys/src/9/ip/devip.c
@@ -571,7 +571,7 @@
cv->perm = 0660;
while((mp = cv->multi) != nil)
- ipifcremmulti(cv, mp->ma, mp->ia);
+ ipifcdelmulti(cv, mp->ma, mp->ia);
if(cv->p->close != nil)
(*cv->p->close)(cv);
@@ -1210,15 +1210,16 @@
error(Ebadip);
ipifcaddmulti(c, ma, ia);
}
- } else if(strcmp(cb->f[0], "remmulti") == 0){
+ } else if (strcmp(cb->f[0], "delmulti") == 0
+ || strcmp(cb->f[0], "remmulti") == 0){
if(cb->nf < 2)
- error("remmulti needs interface address");
+ error("delmulti needs interface address");
if (parseip(ia, cb->f[1]) == -1)
error(Ebadip);
if(ipcmp(c->raddr, IPnoaddr) == 0 || ipismulticast(c->laddr))
- ipifcremmulti(c, c->laddr, ia);
+ ipifcdelmulti(c, c->laddr, ia);
else
- ipifcremmulti(c, c->raddr, ia);
+ ipifcdelmulti(c, c->raddr, ia);
} else if(x->ctl != nil) {
p = (*x->ctl)(c, cb->f, cb->nf);
if(p != nil)
--- a/sys/src/9/ip/ethermedium.c
+++ b/sys/src/9/ip/ethermedium.c
@@ -23,7 +23,7 @@
static void etherunbind(Ipifc *ifc);
static void etherbwrite(Ipifc *ifc, Block *bp, int version, uchar *ip, Routehint *rh);
static void etheraddmulti(Ipifc *ifc, uchar *a, uchar *ia);
-static void etherremmulti(Ipifc *ifc, uchar *a, uchar *ia);
+static void etherdelmulti(Ipifc *ifc, uchar *a, uchar *ia);
static void etherareg(Fs *f, Ipifc *ifc, Iplifc *lifc, uchar *ip);
static Block* multicastarp(Fs *f, Arpent *a, uchar *mac, Routehint *rh);
static Block* newEARP(void);
@@ -43,7 +43,7 @@
.unbind= etherunbind,
.bwrite= etherbwrite,
.addmulti= etheraddmulti,
-.remmulti= etherremmulti,
+.delmulti= etherdelmulti,
.areg= etherareg,
.pref2addr= etherpref2addr,
};
@@ -59,7 +59,7 @@
.unbind= etherunbind,
.bwrite= etherbwrite,
.addmulti= etheraddmulti,
-.remmulti= etherremmulti,
+.delmulti= etherdelmulti,
.areg= etherareg,
.pref2addr= etherpref2addr,
};
@@ -419,7 +419,7 @@
}
static void
-etherremmulti(Ipifc *ifc, uchar *a, uchar *)
+etherdelmulti(Ipifc *ifc, uchar *a, uchar *)
{
uchar mac[6];
char buf[64];
@@ -436,7 +436,7 @@
devtab[er->cchan6->type]->write(er->cchan6, buf, strlen(buf), 0);
break;
default:
- panic("etherremmulti: version %d", version);
+ panic("etherdelmulti: version %d", version);
}
}
@@ -734,10 +734,10 @@
ipv62smcast(a, ip);
addroute(f, a, IPallbits, v6Unspecified, IPallbits, ip, Rmulti, ifc, tdad);
if(waserror()){
- remroute(f, a, IPallbits, v6Unspecified, IPallbits, ip, Rmulti, ifc, tdad);
+ delroute(f, a, IPallbits, v6Unspecified, IPallbits, ip, Rmulti, ifc, tdad);
nexterror();
}
icmpns6(f, 0, SRC_UNSPEC, ip, TARG_MULTI, ifc->mac, 6);
poperror();
- remroute(f, a, IPallbits, v6Unspecified, IPallbits, ip, Rmulti, ifc, tdad);
+ delroute(f, a, IPallbits, v6Unspecified, IPallbits, ip, Rmulti, ifc, tdad);
}
--- a/sys/src/9/ip/ip.h
+++ b/sys/src/9/ip/ip.h
@@ -309,7 +309,7 @@
/* for arming interfaces to receive multicast */
void (*addmulti)(Ipifc *ifc, uchar *a, uchar *ia);
- void (*remmulti)(Ipifc *ifc, uchar *a, uchar *ia);
+ void (*delmulti)(Ipifc *ifc, uchar *a, uchar *ia);
/* process packets written to 'data' */
void (*pktin)(Fs *f, Ipifc *ifc, Block *bp);
@@ -478,7 +478,7 @@
int np;
Proto* p[Maxproto+1]; /* list of supported protocols */
Proto* t2p[256]; /* vector of all protocols */
- Proto* ipifc; /* kludge for ipifcremroute & ipifcaddroute */
+ Proto* ipifc; /* kludge for findipifc */
Proto* ipmux; /* kludge for finding an ip multiplexor */
IP *ip;
@@ -623,7 +623,7 @@
};
extern void addroute(Fs *f, uchar *a, uchar *mask, uchar *s, uchar *smask, uchar *gate, int type, Ipifc *ifc, char *tag);
-extern void remroute(Fs *f, uchar *a, uchar *mask, uchar *s, uchar *smask, uchar *gate, int type, Ipifc *ifc, char *tag);
+extern void delroute(Fs *f, uchar *a, uchar *mask, uchar *s, uchar *smask, uchar *gate, int type, Ipifc *ifc, char *tag);
extern Route* v4lookup(Fs *f, uchar *a, uchar *s, Routehint *rh);
extern Route* v6lookup(Fs *f, uchar *a, uchar *s, Routehint *rh);
extern Route* v4source(Fs *f, uchar *a, uchar *s);
@@ -734,13 +734,13 @@
extern Iplifc* iplocalonifc(Ipifc *ifc, uchar *ip);
extern Iplifc* ipremoteonifc(Ipifc *ifc, uchar *ip);
extern Ipmulti* ipifcgetmulti(Fs *f, Ipifc *ifc, uchar *ma);
-extern void ipifcremmulti(Conv *c, uchar *ma, uchar *ia);
extern void ipifcaddmulti(Conv *c, uchar *ma, uchar *ia);
-extern char* ipifcrem(Ipifc *ifc, char **argv, int argc);
+extern void ipifcdelmulti(Conv *c, uchar *ma, uchar *ia);
extern char* ipifcadd(Ipifc *ifc, char **argv, int argc, int tentative, Iplifc *lifcp);
+extern char* ipifcdel(Ipifc *ifc, char **argv, int argc);
extern long ipselftabread(Fs*, char *a, ulong offset, int n);
extern char* ipifcadd6(Ipifc *ifc, char**argv, int argc);
-extern char* ipifcremove6(Ipifc *ifc, char**argv, int argc);
+extern char* ipifcdel6(Ipifc *ifc, char**argv, int argc);
extern char* mediumunbindifc(Ipifc *ifc);
/*
--- a/sys/src/9/ip/ipifc.c
+++ b/sys/src/9/ip/ipifc.c
@@ -47,10 +47,10 @@
static char tifc[] = "ifc ";
static void addselfcache(Fs *f, Ipifc *ifc, Iplifc *lifc, uchar *a, int type);
-static void remselfcache(Fs *f, Ipifc *ifc, Iplifc *lifc, uchar *a);
+static void delselfcache(Fs *f, Ipifc *ifc, Iplifc *lifc, uchar *a);
static void ipifcregisteraddr(Fs*, Ipifc*, Iplifc*, uchar*);
static void ipifcregisterproxy(Fs*, Ipifc*, uchar*, int);
-static char* ipifcremlifc(Ipifc*, Iplifc**);
+static char* ipifcdellifc(Ipifc*, Iplifc**);
static char Ebound[] = "interface already bound";
static char Eunbound[] = "interface not bound";
@@ -206,7 +206,7 @@
/* disassociate logical interfaces */
while(ifc->lifc != nil)
- ipifcremlifc(ifc, &ifc->lifc);
+ ipifcdellifc(ifc, &ifc->lifc);
/* disassociate device */
if(m->unbind != nil){
@@ -693,7 +693,7 @@
* called with ifc wlock'd
*/
static char*
-ipifcremlifc(Ipifc *ifc, Iplifc **l)
+ipifcdellifc(Ipifc *ifc, Iplifc **l)
{
Iplifc *lifc = *l;
Fs *f = ifc->conv->p->f;
@@ -704,15 +704,15 @@
/* disassociate any addresses */
while(lifc->link != nil)
- remselfcache(f, ifc, lifc, lifc->link->self->a);
+ delselfcache(f, ifc, lifc, lifc->link->self->a);
/* remove the route for this logical interface */
if(lifc->onlink){
- remroute(f, lifc->remote, lifc->mask,
+ delroute(f, lifc->remote, lifc->mask,
lifc->local, IPallbits,
lifc->remote, lifc->type&~Rtrans, ifc, tifc);
if(v6addrtype(lifc->local) != linklocalv6)
- remroute(f, lifc->remote, lifc->mask,
+ delroute(f, lifc->remote, lifc->mask,
lifc->local, IPnoaddr,
lifc->remote, lifc->type, ifc, tifc);
}
@@ -731,11 +731,11 @@
/* remove route for all nodes multicast */
if((lifc->type & Rv4) == 0){
if(ipcmp(lifc->local, v6loopback) == 0){
- remroute(f, v6allnodesN, v6allnodesNmask,
+ delroute(f, v6allnodesN, v6allnodesNmask,
lifc->local, IPallbits,
v6allnodesN, Rmulti, ifc, tifc);
}
- remroute(f, v6allnodesL, v6allnodesLmask,
+ delroute(f, v6allnodesL, v6allnodesLmask,
lifc->local, IPallbits,
v6allnodesL, Rmulti, ifc, tifc);
}
@@ -749,7 +749,7 @@
* remove an address from an interface.
*/
char*
-ipifcrem(Ipifc *ifc, char **argv, int argc)
+ipifcdel(Ipifc *ifc, char **argv, int argc)
{
uchar ip[IPaddrlen], mask[IPaddrlen], rem[IPaddrlen];
Iplifc *lifc, **l;
@@ -778,7 +778,7 @@
break;
l = &lifc->next;
}
- err = ipifcremlifc(ifc, l);
+ err = ipifcdellifc(ifc, l);
wunlock(ifc);
return err;
}
@@ -796,7 +796,7 @@
wlock(ifc);
while(ifc->lifc != nil)
- ipifcremlifc(ifc, &ifc->lifc);
+ ipifcdellifc(ifc, &ifc->lifc);
wunlock(ifc);
err = ipifcadd(ifc, argv, argc, 0, nil);
@@ -882,14 +882,14 @@
err = ipifcadd(ifc, argv, argc, 0, nil);
else if(strcmp(argv[0], "try") == 0)
err = ipifcadd(ifc, argv, argc, 1, nil);
- else if(strcmp(argv[0], "remove") == 0)
- err = ipifcrem(ifc, argv, argc);
+ else if(strcmp(argv[0], "del") == 0 || strcmp(argv[0], "remove") == 0)
+ err = ipifcdel(ifc, argv, argc);
else if(strcmp(argv[0], "unbind") == 0)
err = ipifcunbind(ifc);
else if(strcmp(argv[0], "add6") == 0)
err = ipifcadd6(ifc, argv, argc);
- else if(strcmp(argv[0], "remove6") == 0)
- err = ipifcremove6(ifc, argv, argc);
+ else if(strcmp(argv[0], "del6") == 0 || strcmp(argv[0], "remove6") == 0)
+ err = ipifcdel6(ifc, argv, argc);
else {
wlock(ifc);
if(ifc->m == nil || ifc->m == &unboundmedium){
@@ -944,7 +944,7 @@
ipifc->nc = Maxmedia;
ipifc->ptclsize = sizeof(Ipifc);
- f->ipifc = ipifc; /* hack for ipifcremroute, findipifc, ... */
+ f->ipifc = ipifc;
f->self = smalloc(sizeof(Ipselftab)); /* hack for ipforme */
Fsproto(f, ipifc);
@@ -1086,7 +1086,7 @@
* Unlink from selftab if this is the last ref.
*/
static void
-remselfcache(Fs *f, Ipifc *ifc, Iplifc *lifc, uchar *a)
+delselfcache(Fs *f, Ipifc *ifc, Iplifc *lifc, uchar *a)
{
Ipself *p, **l;
Iplink *link, **l_self, **l_lifc;
@@ -1130,7 +1130,7 @@
}
if(link == nil)
- panic("remselfcache");
+ panic("delselfcache");
if(--(link->ref) != 0)
goto out;
@@ -1147,9 +1147,9 @@
poperror();
}
}
- if(ifc->m->remmulti != nil){
+ if(ifc->m->delmulti != nil){
if(!waserror()){
- (*ifc->m->remmulti)(ifc, a, lifc->local);
+ (*ifc->m->delmulti)(ifc, a, lifc->local);
poperror();
}
}
@@ -1156,7 +1156,7 @@
}
/* remove from routing table */
- remroute(f, a, IPallbits,
+ delroute(f, a, IPallbits,
lifc->local,
((p->type & (Rbcast|Rmulti)) != 0 || v6addrtype(a) == linklocalv6) ?
IPallbits : IPnoaddr,
@@ -1228,8 +1228,8 @@
}
/*
- * find the ifc on same net as the remote system. If none,
- * return nil.
+ * find the ifc on same net as the remote system.
+ * returns the rlocked ifc, otherwise nil.
*/
Ipifc*
findipifc(Fs *f, uchar *local, uchar *remote, int type)
@@ -1236,11 +1236,13 @@
{
uchar gnet[IPaddrlen];
int spec, xspec;
- Ipifc *ifc, *x;
+ uchar xifcid;
+ Ipifc *x, *ifc;
Iplifc *lifc;
Conv **cp;
x = nil;
+ xifcid = 0;
xspec = 0;
for(cp = f->ipifc->conv; *cp != nil; cp++){
ifc = (Ipifc*)(*cp)->ptcl;
@@ -1248,14 +1250,11 @@
continue;
for(lifc = ifc->lifc; lifc != nil; lifc = lifc->next){
if(type & Runi){
- if(ipcmp(remote, lifc->local) == 0){
- Found:
- runlock(ifc);
+ if(ipcmp(remote, lifc->local) == 0)
return ifc;
- }
} else if(type & (Rbcast|Rmulti)) {
if(ipcmp(local, lifc->local) == 0)
- goto Found;
+ return ifc;
}
maskip(remote, lifc->mask, gnet);
if(ipcmp(gnet, lifc->net) == 0){
@@ -1262,6 +1261,7 @@
spec = comprefixlen(remote, lifc->local, IPaddrlen);
if(spec > xspec){
x = ifc;
+ xifcid = ifc->ifcid;
xspec = spec;
}
}
@@ -1268,7 +1268,12 @@
}
runlock(ifc);
}
- return x;
+ if(x != nil && canrlock(x)){
+ if(x->ifcid == xifcid)
+ return x;
+ runlock(x);
+ }
+ return nil;
}
Ipifc*
@@ -1275,20 +1280,25 @@
findipifcstr(Fs *f, char *s)
{
uchar ip[IPaddrlen];
+ Ipifc *ifc;
Conv *c;
char *p;
long x;
+ ifc = nil;
x = strtol(s, &p, 10);
if(p > s && *p == '\0'){
if(x < 0)
return nil;
- if(x < f->ipifc->nc && (c = f->ipifc->conv[x]) != nil && ipifcinuse(c))
- return (Ipifc*)c->ptcl;
- }
- if(parseip(ip, s) != -1)
- return findipifc(f, ip, ip, Runi);
- return nil;
+ if(x < f->ipifc->nc && (c = f->ipifc->conv[x]) != nil){
+ if(ipifcinuse(c)){
+ ifc = (Ipifc*)c->ptcl;
+ rlock(ifc);
+ }
+ }
+ } else if(parseip(ip, s) != -1)
+ ifc = findipifc(f, ip, ip, Runi);
+ return ifc;
}
/*
@@ -1590,7 +1600,6 @@
f = c->p->f;
if((ifc = findipifc(f, ia, ma, Rmulti)) != nil){
- rlock(ifc);
if(waserror()){
runlock(ifc);
nexterror();
@@ -1618,7 +1627,7 @@
* remove a multicast address from an interface.
*/
void
-ipifcremmulti(Conv *c, uchar *ma, uchar *ia)
+ipifcdelmulti(Conv *c, uchar *ma, uchar *ia)
{
Ipmulti *multi, **l;
Iplifc *lifc;
@@ -1638,15 +1647,14 @@
f = c->p->f;
if((ifc = findipifc(f, ia, ma, Rmulti)) != nil){
- rlock(ifc);
if(!waserror()){
if((lifc = iplocalonifc(ifc, ia)) != nil)
- remselfcache(f, ifc, lifc, ma);
+ delselfcache(f, ifc, lifc, ma);
poperror();
}
if(!isv4(ia) && !islinklocal(ia) && !waserror()){
if((lifc = iplinklocalifc(ifc)) != nil)
- remselfcache(f, ifc, lifc, ma);
+ delselfcache(f, ifc, lifc, ma);
poperror();
}
runlock(ifc);
@@ -1694,7 +1702,7 @@
if(add)
addselfcache(f, nifc, lifc, a, Rmulti);
else
- remselfcache(f, nifc, lifc, a);
+ delselfcache(f, nifc, lifc, a);
}
if(add)
ipifcregisteraddr(f, nifc, lifc, ip);
@@ -1773,7 +1781,7 @@
}
char*
-ipifcremove6(Ipifc *ifc, char**, int argc)
+ipifcdel6(Ipifc *ifc, char**, int argc)
{
Iplifc *lifc, **l;
ulong now;
@@ -1786,7 +1794,7 @@
for(l = &ifc->lifc; (lifc = *l) != nil;) {
if((lifc->type & Rv4) == 0)
if(lifc->validlt != ~0UL && lifc->validlt < now-lifc->origint)
- if(ipifcremlifc(ifc, l) == nil)
+ if(ipifcdellifc(ifc, l) == nil)
continue;
l = &lifc->next;
}
--- a/sys/src/9/ip/iproute.c
+++ b/sys/src/9/ip/iproute.c
@@ -425,7 +425,7 @@
}
static void
-routerem(Fs *f, Route *r)
+routedel(Fs *f, Route *r)
{
Route **h, **e, **l, *p, *q;
@@ -464,7 +464,7 @@
}
static Route
-mkroute(uchar *a, uchar *mask, uchar *s, uchar *smask, uchar *gate, int type, Ipifc *ifc, char *tag)
+mkroute(uchar *a, uchar *mask, uchar *s, uchar *smask, uchar *gate, int type, Ipifc *ifc, uchar ifcid, char *tag)
{
ulong x, y;
Route r;
@@ -508,7 +508,7 @@
if(ifc != nil){
r.ifc = ifc;
- r.ifcid = ifc->ifcid;
+ r.ifcid = ifcid;
}
if(tag != nil)
@@ -520,7 +520,7 @@
void
addroute(Fs *f, uchar *a, uchar *mask, uchar *s, uchar *smask, uchar *gate, int type, Ipifc *ifc, char *tag)
{
- Route r = mkroute(a, mask, s, smask, gate, type, ifc, tag);
+ Route r = mkroute(a, mask, s, smask, gate, type, ifc, ifc->ifcid, tag);
wlock(&routelock);
routeadd(f, &r);
wunlock(&routelock);
@@ -527,15 +527,18 @@
}
void
-remroute(Fs *f, uchar *a, uchar *mask, uchar *s, uchar *smask, uchar *gate, int type, Ipifc *ifc, char *tag)
+delroute(Fs *f, uchar *a, uchar *mask, uchar *s, uchar *smask, uchar *gate, int type, Ipifc *ifc, char *tag)
{
- Route r = mkroute(a, mask, s, smask, gate, type, ifc, tag);
+ Route r = mkroute(a, mask, s, smask, gate, type, ifc, ifc->ifcid, tag);
wlock(&routelock);
- routerem(f, &r);
+ routedel(f, &r);
wunlock(&routelock);
}
-/* get the outgoing interface for route r */
+/*
+ * get the outgoing interface for route r,
+ * interface is returned rlocked.
+ */
static Ipifc*
routefindipifc(Route *r, Fs *f)
{
@@ -544,8 +547,12 @@
int i;
ifc = r->ifc;
- if(ifc != nil && ifc->ifcid == r->ifcid)
- return ifc;
+ if(ifc != nil && canrlock(ifc)){
+ if(ifc->ifcid == r->ifcid)
+ return ifc;
+ runlock(ifc);
+ r->ifc = nil;
+ }
if(r->type & Rsrc) {
if(r->type & Rv4) {
@@ -574,11 +581,11 @@
ipmove(gate, r->v6.gate);
}
- if((ifc = findipifc(f, local, gate, r->type)) == nil)
- return nil;
-
- r->ifc = ifc;
- r->ifcid = ifc->ifcid;
+ ifc = findipifc(f, local, gate, r->type);
+ if(ifc != nil) {
+ r->ifc = ifc;
+ r->ifcid = ifc->ifcid;
+ }
return ifc;
}
@@ -633,11 +640,15 @@
p = p->mid;
}
if(q != nil){
- if(routefindipifc(q, f) == nil)
+ ifc = routefindipifc(q, f);
+ if(ifc == nil)
q = nil;
- else if(rh != nil){
- rh->r = q;
- rh->rgen = v4routegeneration;
+ else {
+ if(rh != nil){
+ rh->r = q;
+ rh->rgen = v4routegeneration;
+ }
+ runlock(ifc);
}
}
runlock(&routelock);
@@ -726,11 +737,15 @@
next: ;
}
if(q != nil){
- if(routefindipifc(q, f) == nil)
+ ifc = routefindipifc(q, f);
+ if(ifc == nil)
q = nil;
- else if(rh != nil){
- rh->r = q;
- rh->rgen = v6routegeneration;
+ else {
+ if(rh != nil){
+ rh->r = q;
+ rh->rgen = v6routegeneration;
+ }
+ runlock(ifc);
}
}
runlock(&routelock);
@@ -767,6 +782,12 @@
p = p->right;
continue;
}
+
+ ifc = routefindipifc(p, f);
+ if(ifc == nil){
+ p = p->mid;
+ continue;
+ }
splen = 0;
if(p->type & Rsrc){
/* calculate local prefix length for source specific routes */
@@ -774,12 +795,13 @@
splen++;
hnputl(src, p->v4.source);
}
- if((ifc = routefindipifc(p, f)) == nil
- || !ipv4local(ifc, src, splen, (p->type & (Rifc|Rbcast|Rmulti|Rv4))==Rv4? p->v4.gate: a)){
+ if(!ipv4local(ifc, src, splen, (p->type & (Rifc|Rbcast|Rmulti|Rv4))==Rv4? p->v4.gate: a)){
+ runlock(ifc);
p = p->mid;
continue;
}
memmove(s, src, IPv4addrlen);
+ runlock(ifc);
q = p;
p = p->mid;
}
@@ -823,6 +845,12 @@
}
break;
}
+
+ ifc = routefindipifc(p, f);
+ if(ifc == nil){
+ p = p->mid;
+ continue;
+ }
splen = 0;
if(p->type & Rsrc){
/* calculate local prefix length for source specific routes */
@@ -836,12 +864,13 @@
splen += 32;
}
}
- if((ifc = routefindipifc(p, f)) == nil
- || !ipv6local(ifc, src, splen, a)){
+ if(!ipv6local(ifc, src, splen, a)){
+ runlock(ifc);
p = p->mid;
continue;
}
ipmove(s, src);
+ runlock(ifc);
q = p;
p = p->mid;
next: ;
@@ -1045,13 +1074,13 @@
* 7 add addr mask gate ifc src smask
* 8 add addr mask gate type ifc src smask
* 9 add addr mask gate type tag ifc src smask
- * 3 remove addr mask
- * 4 remove addr mask gate
- * 5 remove addr mask src smask
- * 6 remove addr mask gate src smask
- * 7 remove addr mask gate ifc src smask
- * 8 remove addr mask gate type ifc src smask
- * 9 remove addr mask gate type tag ifc src smask
+ * 3 del addr mask
+ * 4 del addr mask gate
+ * 5 del addr mask src smask
+ * 6 del addr mask gate src smask
+ * 7 del addr mask gate ifc src smask
+ * 8 del addr mask gate type ifc src smask
+ * 9 del addr mask gate type tag ifc src smask
*/
static Route
parseroute(Fs *f, char **argv, int argc)
@@ -1060,6 +1089,7 @@
uchar src[IPaddrlen], smask[IPaddrlen];
uchar gate[IPaddrlen];
Ipifc *ifc;
+ uchar ifcid;
char *tag;
int type;
@@ -1066,6 +1096,7 @@
type = 0;
tag = nil;
ifc = nil;
+ ifcid = 0;
ipmove(gate, IPnoaddr);
ipmove(src, IPnoaddr);
ipmove(smask, IPnoaddr);
@@ -1092,6 +1123,10 @@
ifc = findipifcstr(f, argv[4]);
if(argc > 6)
ifc = findipifcstr(f, argv[argc-3]);
+ if(ifc != nil){
+ ifcid = ifc->ifcid;
+ runlock(ifc);
+ }
if(argc > 7 && (type = parseroutetype(argv[4])) < 0)
error(Ebadctl);
@@ -1113,7 +1148,7 @@
error(Ebadip);
}
- return mkroute(addr, mask, src, smask, gate, type, ifc, tag);
+ return mkroute(addr, mask, src, smask, gate, type, ifc, ifcid, tag);
}
long
@@ -1138,15 +1173,17 @@
for(h = 0; h < nelem(f->v4root); h++)
while((x = looknodetag(f->v4root[h], tag)) != nil){
memmove(&r, x, sizeof(RouteTree) + sizeof(V4route));
- routerem(f, &r);
+ routedel(f, &r);
}
for(h = 0; h < nelem(f->v6root); h++)
while((x = looknodetag(f->v6root[h], tag)) != nil){
memmove(&r, x, sizeof(RouteTree) + sizeof(V6route));
- routerem(f, &r);
+ routedel(f, &r);
}
wunlock(&routelock);
- } else if(strcmp(cb->f[0], "add") == 0 || strcmp(cb->f[0], "remove") == 0){
+ } else if(strcmp(cb->f[0], "add") == 0
+ ||strcmp(cb->f[0], "del") == 0
+ ||strcmp(cb->f[0], "remove") == 0){
r = parseroute(f, cb->f, cb->nf);
if(*r.tag == 0){
a = c->aux;
@@ -1156,7 +1193,7 @@
if(strcmp(cb->f[0], "add") == 0)
routeadd(f, &r);
else
- routerem(f, &r);
+ routedel(f, &r);
wunlock(&routelock);
} else if(strcmp(cb->f[0], "tag") == 0) {
if(cb->nf < 2)
--- a/sys/src/9/port/netif.c
+++ b/sys/src/9/port/netif.c
@@ -341,13 +341,14 @@
nif->bypass = f;
} else if(matchtoken(buf, "headersonly")){
f->headersonly = 1;
- } else if((p = matchtoken(buf, "addmulti")) != 0){
+ } else if((p = matchtoken(buf, "addmulti")) != nil){
if(parseaddr(binaddr, p, nif->alen) < 0)
error("bad address");
p = netmulti(nif, f, binaddr, 1);
if(p)
error(p);
- } else if((p = matchtoken(buf, "remmulti")) != 0){
+ } else if((p = matchtoken(buf, "delmulti")) != nil
+ ||(p = matchtoken(buf, "remmulti")) != nil){
if(parseaddr(binaddr, p, nif->alen) < 0)
error("bad address");
p = netmulti(nif, f, binaddr, 0);
--- a/sys/src/cmd/nusb/ether/ether.c
+++ b/sys/src/cmd/nusb/ether/ether.c
@@ -421,7 +421,7 @@
if(nprom++ == 0 && eppromiscuous != nil)
(*eppromiscuous)(epctl, 1);
}
- } else if(n >= 9+12 && (memcmp(p, "addmulti ", 9)==0 || memcmp(p, "remmulti ", 9)==0)){
+ } else if(n >= 9+12 && (memcmp(p, "addmulti ", 9)==0 || memcmp(p, "delmulti ", 9)==0 || memcmp(p, "remmulti ", 9)==0)){
uchar ea[Eaddrlen];
int i;
@@ -431,7 +431,7 @@
}
i = activemulti(ea);
if(i >= 0){
- if(*p == 'r'){
+ if(*p != 'a'){
memmove(multiaddr[i], multiaddr[--nmulti], Eaddrlen);
if(epmulticast != nil)
(*epmulticast)(epctl, ea, 0);