devip: verify ifcid on routehint check, check Route.ref for free'd routes
v4lookup() and v6lookup() do not acquire the routelock, so it is possible to hit routes that are on the freelist. to detect these, we set ref to 0 and check for this case, avoiding overriding the ifc. re-evaluate routes when the ifcid on the route hint doesnt match.front
parent
638b4a1ec1
commit
575398eb9b
|
@ -22,6 +22,7 @@ freeroute(Route *r)
|
||||||
{
|
{
|
||||||
Route **l;
|
Route **l;
|
||||||
|
|
||||||
|
r->ref = 0;
|
||||||
r->left = nil;
|
r->left = nil;
|
||||||
r->right = nil;
|
r->right = nil;
|
||||||
if(r->type & Rv4)
|
if(r->type & Rv4)
|
||||||
|
@ -541,8 +542,13 @@ v4lookup(Fs *f, uchar *a, uchar *s, Routehint *rh)
|
||||||
Route *p, *q;
|
Route *p, *q;
|
||||||
Ipifc *ifc;
|
Ipifc *ifc;
|
||||||
|
|
||||||
if(rh != nil && rh->r != nil && rh->r->ifc != nil && rh->rgen == v4routegeneration)
|
if(rh != nil
|
||||||
return rh->r;
|
&& rh->rgen == v4routegeneration
|
||||||
|
&& (q = rh->r) != nil
|
||||||
|
&& (ifc = q->ifc) != nil
|
||||||
|
&& q->ifcid == ifc->ifcid
|
||||||
|
&& q->ref > 0)
|
||||||
|
return q;
|
||||||
|
|
||||||
la = nhgetl(a);
|
la = nhgetl(a);
|
||||||
ls = nhgetl(s);
|
ls = nhgetl(s);
|
||||||
|
@ -570,7 +576,10 @@ v4lookup(Fs *f, uchar *a, uchar *s, Routehint *rh)
|
||||||
p = p->mid;
|
p = p->mid;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(q != nil && (q->ifc == nil || q->ifcid != q->ifc->ifcid)){
|
if(q == nil || q->ref == 0)
|
||||||
|
return nil;
|
||||||
|
|
||||||
|
if(q->ifc == nil || q->ifcid != q->ifc->ifcid){
|
||||||
if(q->type & Rifc) {
|
if(q->type & Rifc) {
|
||||||
hnputl(gate+IPv4off, q->v4.address);
|
hnputl(gate+IPv4off, q->v4.address);
|
||||||
memmove(gate, v4prefix, IPv4off);
|
memmove(gate, v4prefix, IPv4off);
|
||||||
|
@ -602,13 +611,19 @@ v6lookup(Fs *f, uchar *a, uchar *s, Routehint *rh)
|
||||||
Ipifc *ifc;
|
Ipifc *ifc;
|
||||||
int h;
|
int h;
|
||||||
|
|
||||||
if(isv4(a) && isv4(s))
|
if(isv4(s)){
|
||||||
return v4lookup(f, a+IPv4off, s+IPv4off, rh);
|
if(isv4(a))
|
||||||
if(isv4(s))
|
return v4lookup(f, a+IPv4off, s+IPv4off, rh);
|
||||||
return nil;
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
if(rh != nil && rh->r != nil && rh->r->ifc != nil && rh->rgen == v6routegeneration)
|
if(rh != nil
|
||||||
return rh->r;
|
&& rh->rgen == v6routegeneration
|
||||||
|
&& (q = rh->r) != nil
|
||||||
|
&& (ifc = q->ifc) != nil
|
||||||
|
&& q->ifcid == ifc->ifcid
|
||||||
|
&& q->ref > 0)
|
||||||
|
return q;
|
||||||
|
|
||||||
for(h = 0; h < IPllen; h++){
|
for(h = 0; h < IPllen; h++){
|
||||||
la[h] = nhgetl(a+4*h);
|
la[h] = nhgetl(a+4*h);
|
||||||
|
@ -668,7 +683,10 @@ v6lookup(Fs *f, uchar *a, uchar *s, Routehint *rh)
|
||||||
next: ;
|
next: ;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(q != nil && (q->ifc == nil || q->ifcid != q->ifc->ifcid)){
|
if(q == nil || q->ref == 0)
|
||||||
|
return nil;
|
||||||
|
|
||||||
|
if(q->ifc == nil || q->ifcid != q->ifc->ifcid){
|
||||||
if(q->type & Rifc) {
|
if(q->type & Rifc) {
|
||||||
for(h = 0; h < IPllen; h++)
|
for(h = 0; h < IPllen; h++)
|
||||||
hnputl(gate+4*h, q->v6.address[h]);
|
hnputl(gate+4*h, q->v6.address[h]);
|
||||||
|
|
Loading…
Reference in New Issue