From 7ab5fa8717ddb27d557e0886c8f4a4f5dd5d05ec Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Mon, 16 Mar 1998 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1998-03-16 --- ip/ip.h | 1 - ip/ipifc.c | 20 +++++++++++++++----- ip/iproute.c | 31 +++++++++++++++++++++++++------ 3 files changed, 40 insertions(+), 12 deletions(-) diff --git a/ip/ip.h b/ip/ip.h index 91bf6cab6df859fd17e38fa8739658c7004aea03..cc663d48388991e6f7970758225c5957db8ecd04 100644 --- a/ip/ip.h +++ b/ip/ip.h @@ -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; diff --git a/ip/ipifc.c b/ip/ipifc.c index bf74c2e9d61345572bbddc9b0bfb4d65a5023af9..db35fd8c4a8c4fa1a3994e132d910a6b3853be22 100644 --- a/ip/ipifc.c +++ b/ip/ipifc.c @@ -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) diff --git a/ip/iproute.c b/ip/iproute.c index 4bf022e34c22990dd9c89d5ab30d9edf1711f37c..bd3e09476395406546036e2c138294a886551893 100644 --- a/ip/iproute.c +++ b/ip/iproute.c @@ -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;