M ip/ip.h => ip/ip.h +0 -1
@@ 8,7 8,6 @@ typedef struct Ipselftab Ipselftab;
typedef struct Iplink Iplink;
typedef struct Iplifc Iplifc;
typedef struct Ipmulti Ipmulti;
-typedef struct Iproute Iproute;
typedef struct IProuter IProuter;
typedef struct Ipifc Ipifc;
typedef struct Log Log;
M ip/ipifc.c => ip/ipifc.c +15 -5
@@ 360,7 360,7 @@ ipifcadd(Ipifc *ifc, char **argv, int argc)
if(isv4(ip))
v4addroute(f, tifc, rem+IPv4off, mask+IPv4off, ip+IPv4off, type);
else
- v6addroute(f, tifc, ip, mask, rem, type);
+ v6addroute(f, tifc, rem, mask, ip, type);
addselfcache(f, ifc, lifc, ip, Runi);
@@ 860,11 860,15 @@ ipforme(Fs *f, uchar *addr)
Ipifc*
findipifc(Fs *f, uchar *remote, int type)
{
- Ipifc *ifc;
+ Ipifc *ifc, *x;
Iplifc *lifc;
Conv **cp, **e;
uchar gnet[IPaddrlen];
+ uchar xmask[IPaddrlen];
+
+ x = nil;
+ /* find most specific match */
e = &f->ipifc->conv[f->ipifc->nc];
for(cp = f->ipifc->conv; cp < e; cp++){
if(*cp == 0)
@@ 872,12 876,18 @@ findipifc(Fs *f, uchar *remote, int type)
ifc = (Ipifc*)(*cp)->ptcl;
for(lifc = ifc->lifc; lifc; lifc = lifc->next){
maskip(remote, lifc->mask, gnet);
- if(ipcmp(gnet, lifc->net) == 0)
- return ifc;
+ if(ipcmp(gnet, lifc->net) == 0){
+ if(x == nil || ipcmp(lifc->mask, xmask) > 0){
+ x = ifc;
+ ipmove(xmask, lifc->mask);
+ }
+ }
}
}
+ if(x != nil)
+ return x;
- /* for now for broadcast and mutlicast, just use first interface */
+ /* for now for broadcast and multicast, just use first interface */
if(type & (Rbcast|Rmulti)){
for(cp = f->ipifc->conv; cp < e; cp++){
if(*cp == 0)
M ip/iproute.c => ip/iproute.c +25 -6
@@ 263,7 263,15 @@ addnode(Fs *f, Route **cur, Route *new)
addqueue(&f->queue, p);
break;
case Requals:
- copygate(p, new);
+ /*
+ * supercede the old entry if the old one isn't
+ * a local interface.
+ */
+ if((p->type & Rifc) == 0){
+ p->type = new->type;
+ p->ifcid = -1;
+ copygate(p, new);
+ }
freeroute(new);
break;
case Rcontained:
@@ 471,7 479,11 @@ v4lookup(Fs *f, uchar *a)
p = p->left;
if(q && (q->ifc == nil || q->ifcid != q->ifc->ifcid)){
- v4tov6(gate, q->v4.gate);
+ if(q->type & Rifc) {
+ hnputl(gate+IPv4off, q->v4.address);
+ memmove(gate, v4prefix, IPv4off);
+ } else
+ v4tov6(gate, q->v4.gate);
q->ifc = findipifc(f, gate, q->type);
if(q->ifc == nil)
return nil;
@@ 488,6 500,7 @@ v6lookup(Fs *f, uchar *a)
ulong la[IPllen];
int h;
ulong x, y;
+ uchar gate[IPaddrlen];
if(memcmp(a, v4prefix, 12) == 0){
q = v4lookup(f, a+12);
@@ 527,12 540,18 @@ v6lookup(Fs *f, uchar *a)
next: ;
}
- if(q && q->ifc == nil){
- q->ifc = findipifc(f, q->v6.gate, q->type);
+ if(q && (q->ifc == nil || q->ifcid != q->ifc->ifcid)){
+ if(q->type & Rifc) {
+ hnputl(gate, q->v6.gate[0]);
+ hnputl(gate+4, q->v6.gate[1]);
+ hnputl(gate+8, q->v6.gate[2]);
+ hnputl(gate+12, q->v6.gate[3]);
+ q->ifc = findipifc(f, gate, q->type);
+ } else
+ q->ifc = findipifc(f, q->v6.gate, q->type);
if(q->ifc == nil)
return nil;
- if(q->ifcid != q->ifc->ifcid)
- return nil;
+ q->ifcid = q->ifc->ifcid;
}
return q;