diff options
| -rw-r--r-- | sys/src/9/ip/arp.c | 5 | ||||
| -rw-r--r-- | sys/src/9/ip/devip.c | 14 | ||||
| -rw-r--r-- | sys/src/9/ip/esp.c | 11 | ||||
| -rw-r--r-- | sys/src/9/ip/ethermedium.c | 7 | ||||
| -rw-r--r-- | sys/src/9/ip/icmp6.c | 42 | ||||
| -rw-r--r-- | sys/src/9/ip/ip.c | 23 | ||||
| -rw-r--r-- | sys/src/9/ip/ip.h | 40 | ||||
| -rw-r--r-- | sys/src/9/ip/ipaux.c | 9 | ||||
| -rw-r--r-- | sys/src/9/ip/ipifc.c | 227 | ||||
| -rw-r--r-- | sys/src/9/ip/iproute.c | 36 | ||||
| -rw-r--r-- | sys/src/9/ip/ipv6.c | 18 | ||||
| -rw-r--r-- | sys/src/9/ip/rudp.c | 2 | ||||
| -rw-r--r-- | sys/src/9/ip/udp.c | 46 |
13 files changed, 195 insertions, 285 deletions
diff --git a/sys/src/9/ip/arp.c b/sys/src/9/ip/arp.c index 9d650a978..ba158cf29 100644 --- a/sys/src/9/ip/arp.c +++ b/sys/src/9/ip/arp.c @@ -539,7 +539,6 @@ arpread(Arp *arp, char *p, ulong offset, int len) extern int rxmitsols(Arp *arp) { - uint sflag; Block *next, *xp; Arpent *a, *b, **l; Fs *f; @@ -582,8 +581,8 @@ rxmitsols(Arp *arp) qunlock(arp); /* for icmpns */ - if((sflag = ipv6anylocal(ifc, ipsrc)) != SRC_UNSPEC) - icmpns(f, ipsrc, sflag, a->ip, TARG_MULTI, ifc->mac); + if(ipv6local(ifc, ipsrc, a->ip)) + icmpns(f, ipsrc, SRC_UNI, a->ip, TARG_MULTI, ifc->mac); runlock(ifc); qlock(arp); diff --git a/sys/src/9/ip/devip.c b/sys/src/9/ip/devip.c index 2629c02ef..18dbf54ff 100644 --- a/sys/src/9/ip/devip.c +++ b/sys/src/9/ip/devip.c @@ -919,12 +919,7 @@ Fsstdconnect(Conv *c, char *argv[], int argc) return p; } - if( (memcmp(c->raddr, v4prefix, IPv4off) == 0 && - memcmp(c->laddr, v4prefix, IPv4off) == 0) - || ipcmp(c->raddr, IPnoaddr) == 0) - c->ipversion = V4; - else - c->ipversion = V6; + c->ipversion = convipvers(c); return nil; } @@ -1150,12 +1145,6 @@ ipwrite(Chan* ch, void *v, long n, vlong off) if (parseip(ia, cb->f[1]) == -1) error(Ebadip); ipifcremmulti(c, c->raddr, ia); - } else if(strcmp(cb->f[0], "maxfragsize") == 0){ - if(cb->nf < 2) - error("maxfragsize needs size"); - - c->maxfragsize = (int)strtol(cb->f[1], nil, 0); - } else if(x->ctl != nil) { p = x->ctl(c, cb->f, cb->nf); if(p != nil) @@ -1329,7 +1318,6 @@ retry: c->lport = 0; c->rport = 0; c->restricted = 0; - c->maxfragsize = 0; c->ttl = MAXTTL; qreopen(c->rq); qreopen(c->wq); diff --git a/sys/src/9/ip/esp.c b/sys/src/9/ip/esp.c index 667090953..8fec0c766 100644 --- a/sys/src/9/ip/esp.c +++ b/sys/src/9/ip/esp.c @@ -267,17 +267,6 @@ espclose(Conv *c) } static int -convipvers(Conv *c) -{ - if((memcmp(c->raddr, v4prefix, IPv4off) == 0 && - memcmp(c->laddr, v4prefix, IPv4off) == 0) || - ipcmp(c->raddr, IPnoaddr) == 0) - return V4; - else - return V6; -} - -static int pktipvers(Fs *f, Block **bpp) { if (*bpp == nil || BLEN(*bpp) == 0) { diff --git a/sys/src/9/ip/ethermedium.c b/sys/src/9/ip/ethermedium.c index 346093795..d8691b0e7 100644 --- a/sys/src/9/ip/ethermedium.c +++ b/sys/src/9/ip/ethermedium.c @@ -477,7 +477,7 @@ sendarp(Ipifc *ifc, Arpent *a) memset(bp->rp, 0, n); e = (Etherarp*)bp->rp; memmove(e->tpa, a->ip+IPv4off, sizeof(e->tpa)); - ipv4local(ifc, e->spa); + ipv4local(ifc, e->spa, e->tpa); memmove(e->sha, ifc->mac, sizeof(e->sha)); memset(e->d, 0xff, sizeof(e->d)); /* ethernet broadcast */ memmove(e->s, ifc->mac, sizeof(e->s)); @@ -496,7 +496,6 @@ sendarp(Ipifc *ifc, Arpent *a) static void resolveaddr6(Ipifc *ifc, Arpent *a) { - int sflag; Block *bp; Etherrock *er = ifc->arg; uchar ipsrc[IPaddrlen]; @@ -526,8 +525,8 @@ resolveaddr6(Ipifc *ifc, Arpent *a) a->rxtsrem--; arprelease(er->f->arp, a); - if(sflag = ipv6anylocal(ifc, ipsrc)) - icmpns(er->f, ipsrc, sflag, a->ip, TARG_MULTI, ifc->mac); + if(ipv6local(ifc, ipsrc, a->ip)) + icmpns(er->f, ipsrc, SRC_UNI, a->ip, TARG_MULTI, ifc->mac); } /* diff --git a/sys/src/9/ip/icmp6.c b/sys/src/9/ip/icmp6.c index 5557c6042..17d24d623 100644 --- a/sys/src/9/ip/icmp6.c +++ b/sys/src/9/ip/icmp6.c @@ -331,7 +331,7 @@ mkechoreply6(Block *bp, Ipifc *ifc) ipmove(addr, p->src); if(!isv6mcast(p->dst)) ipmove(p->src, p->dst); - else if (!ipv6anylocal(ifc, p->src)) + else if (!ipv6local(ifc, p->src, addr)) return nil; ipmove(p->dst, addr); p->type = EchoReplyV6; @@ -440,7 +440,7 @@ icmphostunr(Fs *f, Ipifc *ifc, Block *bp, int code, int free) np = (IPICMP *)nbp->rp; rlock(ifc); - if(ipv6anylocal(ifc, np->src)) + if(ipv6local(ifc, np->src, p->src)) netlog(f, Logicmp, "send icmphostunr -> src %I dst %I\n", p->src, p->dst); else { netlog(f, Logicmp, "icmphostunr fail -> src %I dst %I\n", p->src, p->dst); @@ -487,7 +487,7 @@ icmpttlexceeded6(Fs *f, Ipifc *ifc, Block *bp) nbp = newIPICMP(sz); np = (IPICMP *) nbp->rp; - if(ipv6anylocal(ifc, np->src)) + if(ipv6local(ifc, np->src, p->src)) netlog(f, Logicmp, "send icmpttlexceeded6 -> src %I dst %I\n", p->src, p->dst); else { @@ -526,7 +526,7 @@ icmppkttoobig6(Fs *f, Ipifc *ifc, Block *bp) nbp = newIPICMP(sz); np = (IPICMP *)nbp->rp; - if(ipv6anylocal(ifc, np->src)) + if(ipv6local(ifc, np->src, p->src)) netlog(f, Logicmp, "send icmppkttoobig6 -> src %I dst %I\n", p->src, p->dst); else { @@ -778,18 +778,11 @@ icmpiput6(Proto *icmp, Ipifc *ipifc, Block *bp) } bp->rp -= IPICMPSZ; } - goticmpkt6(icmp, bp, 0); break; case RouterAdvert: case RouterSolicit: - /* using lsrc as a temp, munge hdr for goticmp6 */ - if (0) { - memmove(lsrc, p->src, IPaddrlen); - memmove(p->src, p->dst, IPaddrlen); - memmove(p->dst, lsrc, IPaddrlen); - } goticmpkt6(icmp, bp, p->type); break; @@ -809,21 +802,21 @@ icmpiput6(Proto *icmp, Ipifc *ipifc, Block *bp) 8*np->olen-2, 0); pktflags |= Sflag; } - if(ipv6local(ipifc, lsrc)) - icmpna(icmp->f, lsrc, - (ipcmp(np->src, v6Unspecified) == 0? - v6allnodesL: np->src), - np->target, ipifc->mac, pktflags); - else - freeblist(bp); + if(!ipv6local(ipifc, lsrc, np->src)) + break; + icmpna(icmp->f, lsrc, + (ipcmp(np->src, v6Unspecified) == 0? + v6allnodesL: np->src), + np->target, ipifc->mac, pktflags); break; - case Tunitent: - /* not clear what needs to be done. send up - * an icmp mesg saying don't use this address? */ - default: - freeblist(bp); + /* + * not clear what needs to be done. send up + * an icmp mesg saying don't use this address? + */ + break; } + freeblist(bp); break; case NbrAdvert: @@ -839,8 +832,7 @@ icmpiput6(Proto *icmp, Ipifc *ipifc, Block *bp) lifc = iplocalonifc(ipifc, np->target); if(lifc && lifc->tentative) refresh = 0; - arpenter(icmp->f, V6, np->target, np->lnaddr, 8*np->olen-2, - refresh); + arpenter(icmp->f, V6, np->target, np->lnaddr, 8*np->olen-2, refresh); freeblist(bp); break; diff --git a/sys/src/9/ip/ip.c b/sys/src/9/ip/ip.c index 32b95b4b6..6c4d02992 100644 --- a/sys/src/9/ip/ip.c +++ b/sys/src/9/ip/ip.c @@ -63,8 +63,6 @@ ip_init_6(Fs *f) v6p->hp.rxmithost = 1000; /* v6 RETRANS_TIMER */ - v6p->cdrouter = -1; - f->v6p = v6p; } @@ -118,7 +116,7 @@ iprouting(Fs *f, int on) } int -ipoput4(Fs *f, Block *bp, int gating, int ttl, int tos, Conv *c) +ipoput4(Fs *f, Block *bp, int gating, int ttl, int tos, Routehint *rh) { Ipifc *ifc; uchar *gate; @@ -156,7 +154,7 @@ ipoput4(Fs *f, Block *bp, int gating, int ttl, int tos, Conv *c) goto free; } - r = v4lookup(f, eh->dst, c); + r = v4lookup(f, eh->dst, rh); if(r == nil){ ip->stats[OutNoRoutes]++; netlog(f, Logip, "no interface %V\n", eh->dst); @@ -193,10 +191,7 @@ ipoput4(Fs *f, Block *bp, int gating, int ttl, int tos, Conv *c) goto raise; /* If we dont need to fragment just send it */ - if(c && c->maxfragsize && c->maxfragsize < ifc->maxtu) - medialen = c->maxfragsize - ifc->m->hsize; - else - medialen = ifc->maxtu - ifc->m->hsize; + medialen = ifc->maxtu - ifc->m->hsize; if(len <= medialen) { if(!gating) hnputs(eh->id, incref(&ip->id4)); @@ -315,8 +310,6 @@ ipiput4(Fs *f, Ipifc *ifc, Block *bp) int notforme; uchar *dp, v6dst[IPaddrlen]; IP *ip; - Route *r; - Conv conv; if(BLKIPVER(bp) != IP_VER4) { ipiput6(f, ifc, bp); @@ -377,15 +370,17 @@ ipiput4(Fs *f, Ipifc *ifc, Block *bp) /* route */ if(notforme) { + Route *r; + Routehint rh; + if(!ip->iprouting){ freeblist(bp); return; } /* don't forward to source's network */ - memmove(&conv, ifc->conv, sizeof conv); - conv.r = nil; - r = v4lookup(f, h->dst, &conv); + rh.r = nil; + r = v4lookup(f, h->dst, &rh); if(r == nil || r->ifc == ifc){ ip->stats[OutDiscards]++; freeblist(bp); @@ -419,7 +414,7 @@ if(r->ifc == nil) panic("nil route ifc"); ip->stats[ForwDatagrams]++; tos = h->tos; hop = h->ttl; - ipoput4(f, bp, 1, hop - 1, tos, &conv); + ipoput4(f, bp, 1, hop - 1, tos, &rh); return; } diff --git a/sys/src/9/ip/ip.h b/sys/src/9/ip/ip.h index 7eb001ba8..84e776e4e 100644 --- a/sys/src/9/ip/ip.h +++ b/sys/src/9/ip/ip.h @@ -21,10 +21,10 @@ typedef struct Proto Proto; typedef struct Arpent Arpent; typedef struct Arp Arp; typedef struct Route Route; +typedef struct Routehint Routehint; typedef struct Routerparams Routerparams; typedef struct Hostparams Hostparams; -typedef struct v6router v6router; typedef struct v6params v6params; #pragma incomplete Arp @@ -164,6 +164,12 @@ struct Ip4hdr uchar dst[4]; /* IP destination */ }; +struct Routehint +{ + Route *r; /* last route used */ + ulong rgen; /* routetable generation for *r */ +}; + /* * one per conversation directory */ @@ -191,8 +197,6 @@ struct Conv int length; int state; - int maxfragsize; /* If set, used for fragmentation */ - /* udp specific */ int headers; /* data src/dst headers in udp */ int reliable; /* true if reliable udp */ @@ -217,8 +221,7 @@ struct Conv void* ptcl; /* protocol specific stuff */ - Route *r; /* last route used */ - ulong rgen; /* routetable generation for *r */ + Routehint; }; struct Medium @@ -443,23 +446,10 @@ struct Fs long ndbmtime; }; -/* one per default router known to host */ -struct v6router { - uchar inuse; - Ipifc *ifc; - int ifcid; - uchar routeraddr[IPaddrlen]; - long ltorigin; - Routerparams rp; -}; - struct v6params { Routerparams rp; /* v6 params, one copy per node now */ Hostparams hp; - v6router v6rlist[3]; /* max 3 default routers, currently */ - int cdrouter; /* uses only v6rlist[cdrouter] if */ - /* cdrouter >= 0. */ }; @@ -586,8 +576,8 @@ extern void v4addroute(Fs *f, char *tag, uchar *a, uchar *mask, uchar *gate, int extern void v6addroute(Fs *f, char *tag, uchar *a, uchar *mask, uchar *gate, int type); extern void v4delroute(Fs *f, uchar *a, uchar *mask, int dolock); extern void v6delroute(Fs *f, uchar *a, uchar *mask, int dolock); -extern Route* v4lookup(Fs *f, uchar *a, Conv *c); -extern Route* v6lookup(Fs *f, uchar *a, Conv *c); +extern Route* v4lookup(Fs *f, uchar *a, Routehint *h); +extern Route* v6lookup(Fs *f, uchar *a, Routehint *h); extern long routeread(Fs *f, char*, ulong, int); extern long routewrite(Fs *f, Chan*, char*, int); extern void routetype(int, char*); @@ -654,6 +644,7 @@ extern int isv4(uchar*); extern void v4tov6(uchar *v6, uchar *v4); extern int v6tov4(uchar *v4, uchar *v6); extern int eipfmt(Fmt*); +extern int convipvers(Conv *c); #define ipmove(x, y) memmove(x, y, IPaddrlen) #define ipcmp(x, y) ( (x)[IPaddrlen-1] != (y)[IPaddrlen-1] || memcmp(x, y, IPaddrlen) ) @@ -686,9 +677,8 @@ extern int ipisbm(uchar *); extern int ipismulticast(uchar *); extern Ipifc* findipifc(Fs*, uchar *remote, int type); extern void findlocalip(Fs*, uchar *local, uchar *remote); -extern int ipv4local(Ipifc *ifc, uchar *addr); -extern int ipv6local(Ipifc *ifc, uchar *addr); -extern int ipv6anylocal(Ipifc *ifc, uchar *addr); +extern int ipv4local(Ipifc *ifc, uchar *local, uchar *remote); +extern int ipv6local(Ipifc *ifc, uchar *local, uchar *remote); extern Iplifc* iplocalonifc(Ipifc *ifc, uchar *ip); extern int ipproxyifc(Fs *f, Ipifc *ifc, uchar *ip); extern int ipismulticast(uchar *ip); @@ -714,8 +704,8 @@ extern void icmpttlexceeded(Fs*, uchar*, Block*); extern ushort ipcsum(uchar*); extern void ipiput4(Fs*, Ipifc*, Block*); extern void ipiput6(Fs*, Ipifc*, Block*); -extern int ipoput4(Fs*, Block*, int, int, int, Conv*); -extern int ipoput6(Fs*, Block*, int, int, int, Conv*); +extern int ipoput4(Fs*, Block*, int, int, int, Routehint*); +extern int ipoput6(Fs*, Block*, int, int, int, Routehint*); extern int ipstats(Fs*, char*, int); extern ushort ptclbsum(uchar*, int); extern ushort ptclcsum(Block*, int, int); diff --git a/sys/src/9/ip/ipaux.c b/sys/src/9/ip/ipaux.c index fd253dafe..e16249546 100644 --- a/sys/src/9/ip/ipaux.c +++ b/sys/src/9/ip/ipaux.c @@ -366,3 +366,12 @@ iphtlook(Ipht *ht, uchar *sa, ushort sp, uchar *da, ushort dp) unlock(ht); return nil; } + +int +convipvers(Conv *c) +{ + if(isv4(c->raddr) && isv4(c->laddr) || ipcmp(c->raddr, IPnoaddr) == 0) + return V4; + else + return V6; +} diff --git a/sys/src/9/ip/ipifc.c b/sys/src/9/ip/ipifc.c index 84194a70e..3ed24fa60 100644 --- a/sys/src/9/ip/ipifc.c +++ b/sys/src/9/ip/ipifc.c @@ -1095,7 +1095,7 @@ iptentative(Fs *f, uchar *addr) * 0 - no match * Runi * Rbcast - * Rmcast + * Rmulti */ int ipforme(Fs *f, uchar *addr) @@ -1163,7 +1163,6 @@ findipifc(Fs *f, uchar *remote, int type) enum { unknownv6, /* UGH */ -// multicastv6, unspecifiedv6, linklocalv6, globalv6, @@ -1237,140 +1236,135 @@ findprimaryipv4(Fs *f, uchar *local) return; } } + ipmove(local, IPnoaddr); } -/* - * find the local address 'closest' to the remote system, copy it to - * local and return the ifc for that address - */ -void -findlocalip(Fs *f, uchar *local, uchar *remote) +static int +comprefixlen(uchar *a, uchar *b, int n) { - int version, atype = unspecifiedv6, atypel = unknownv6; - int atyper, deprecated; - uchar gate[IPaddrlen], gnet[IPaddrlen]; - Ipifc *ifc; - Iplifc *lifc; - Route *r; - - USED(atype); - USED(atypel); - qlock(f->ipifc); - r = v6lookup(f, remote, nil); - version = (memcmp(remote, v4prefix, IPv4off) == 0)? V4: V6; - - if(r != nil){ - ifc = r->ifc; - if(r->type & Rv4) - v4tov6(gate, r->v4.gate); - else { - ipmove(gate, r->v6.gate); - ipmove(local, v6Unspecified); - } - - switch(version) { - case V4: - /* find ifc address closest to the gateway to use */ - for(lifc = ifc->lifc; lifc; lifc = lifc->next){ - maskip(gate, lifc->mask, gnet); - if(ipcmp(gnet, lifc->net) == 0){ - ipmove(local, lifc->local); - goto out; - } - } - break; - case V6: - /* find ifc address with scope matching the destination */ - atyper = v6addrtype(remote); - deprecated = 0; - for(lifc = ifc->lifc; lifc; lifc = lifc->next){ - atypel = v6addrtype(lifc->local); - /* prefer appropriate scope */ - if(atypel > atype && atype < atyper || - atypel < atype && atype > atyper){ - ipmove(local, lifc->local); - deprecated = !v6addrcurr(lifc); - atype = atypel; - } else if(atypel == atype){ - /* avoid deprecated addresses */ - if(deprecated && v6addrcurr(lifc)){ - ipmove(local, lifc->local); - atype = atypel; - deprecated = 0; - } - } - if(atype == atyper && !deprecated) - goto out; - } - if(atype >= atyper) - goto out; - break; - default: - panic("findlocalip: version %d", version); - } - } + int i, c; - switch(version){ - case V4: - findprimaryipv4(f, local); - break; - case V6: - findprimaryipv6(f, local); - break; - default: - panic("findlocalip2: version %d", version); + for(i = 0; i < n; i++){ + if((c = a[i] ^ b[i]) == 0) + continue; + for(i <<= 3; (c & 0x80) == 0; i++) + c <<= 1; + return i; } - -out: - qunlock(f->ipifc); + return i << 3; } /* - * return first v4 address associated with an interface + * return v4 address associated with an interface close to remote */ int -ipv4local(Ipifc *ifc, uchar *addr) +ipv4local(Ipifc *ifc, uchar *local, uchar *remote) { Iplifc *lifc; + int a, b; - for(lifc = ifc->lifc; lifc; lifc = lifc->next){ - if(isv4(lifc->local)){ - memmove(addr, lifc->local+IPv4off, IPv4addrlen); - return 1; + b = -1; + for(lifc = ifc->lifc; lifc != nil; lifc = lifc->next){ + if(!isv4(lifc->local)) + continue; + a = comprefixlen(lifc->local+IPv4off, remote, IPv4addrlen); + if(a > b){ + b = a; + memmove(local, lifc->local+IPv4off, IPv4addrlen); } } - return 0; + return b >= 0; } /* - * return first v6 address associated with an interface + * return v6 address associated with an interface close to remote */ int -ipv6local(Ipifc *ifc, uchar *addr) +ipv6local(Ipifc *ifc, uchar *local, uchar *remote) { + struct { + int atype; + int deprecated; + int comprefixlen; + } a, b; + int atype; Iplifc *lifc; - for(lifc = ifc->lifc; lifc; lifc = lifc->next){ - if(!isv4(lifc->local) && !(lifc->tentative)){ - ipmove(addr, lifc->local); - return 1; + if(isv4(remote)){ + ipmove(local, v4prefix); + return ipv4local(ifc, local+IPv4off, remote+IPv4off); + } + + atype = v6addrtype(remote); + ipmove(local, v6Unspecified); + b.atype = unknownv6; + b.deprecated = 1; + b.comprefixlen = 0; + + for(lifc = ifc->lifc; lifc != nil; lifc = lifc->next){ + if(lifc->tentative) + continue; + + a.atype = v6addrtype(lifc->local); + a.deprecated = !v6addrcurr(lifc); + a.comprefixlen = comprefixlen(lifc->local, remote, IPaddrlen); + + /* prefer appropriate scope */ + if(a.atype != b.atype){ + if(a.atype > b.atype && b.atype < atype || + a.atype < b.atype && b.atype > atype) + goto Good; + continue; } + /* prefer non-deprecated addresses */ + if(a.deprecated != b.deprecated){ + if(b.deprecated) + goto Good; + continue; + } + /* prefer longer common prefix */ + if(a.comprefixlen != b.comprefixlen){ + if(a.comprefixlen > b.comprefixlen) + goto Good; + continue; + } + continue; + Good: + b = a; + ipmove(local, lifc->local); } - return 0; + + return b.atype >= atype; } -int -ipv6anylocal(Ipifc *ifc, uchar *addr) +/* + * find the local address 'closest' to the remote system, copy it to local + */ +void +findlocalip(Fs *f, uchar *local, uchar *remote) { - Iplifc *lifc; + Route *r; - for(lifc = ifc->lifc; lifc; lifc = lifc->next){ - if(!isv4(lifc->local)){ - ipmove(addr, lifc->local); - return SRC_UNI; + qlock(f->ipifc); + if((r = v6lookup(f, remote, nil)) != nil){ + if(r->type & Runi){ + ipmove(local, remote); + goto out; + } + if((r->type & (Rifc|Rbcast|Rmulti|Rv4)) == Rv4){ + ipmove(local, v4prefix); + if(ipv4local(r->ifc, local+IPv4off, r->v4.gate)) + goto out; } + if(ipv6local(r->ifc, local, remote)) + goto out; } - return SRC_UNSPEC; + if(isv4(remote)) + findprimaryipv4(f, local); + else + findprimaryipv6(f, local); +out: + qunlock(f->ipifc); } /* @@ -1605,29 +1599,6 @@ ipifcregisterproxy(Fs *f, Ipifc *ifc, uchar *ip) } } - -/* added for new v6 mesg types */ -static void -adddefroute6(Fs *f, uchar *gate, int force) -{ - Route *r; - - r = v6lookup(f, v6Unspecified, nil); - /* - * route entries generated by all other means take precedence - * over router announcements. - */ - if (r && !force && strcmp(r->tag, "ra") != 0) - return; - - v6delroute(f, v6Unspecified, v6Unspecified, 1); - v6addroute(f, "ra", v6Unspecified, v6Unspecified, gate, 0); -} - -enum { - Ngates = 3, -}; - char* ipifcadd6(Ipifc *ifc, char**argv, int argc) { diff --git a/sys/src/9/ip/iproute.c b/sys/src/9/ip/iproute.c index 518950309..f6a4be7f1 100644 --- a/sys/src/9/ip/iproute.c +++ b/sys/src/9/ip/iproute.c @@ -323,7 +323,6 @@ v4addroute(Fs *f, char *tag, uchar *a, uchar *mask, uchar *gate, int type) } #define V6H(a) (((a)[IPllen-1] & 0x07ffffff)>>(32-Lroot-5)) -#define ISDFLT(a, mask, tag) ((ipcmp((a),v6Unspecified)==0) && (ipcmp((mask),v6Unspecified)==0) && (strcmp((tag), "ra")!=0)) void v6addroute(Fs *f, char *tag, uchar *a, uchar *mask, uchar *gate, int type) @@ -333,12 +332,6 @@ v6addroute(Fs *f, char *tag, uchar *a, uchar *mask, uchar *gate, int type) ulong x, y; int h, eh; - /* - if(ISDFLT(a, mask, tag)) - f->v6p->cdrouter = -1; - */ - - for(h = 0; h < IPllen; h++){ x = nhgetl(a+4*h); y = nhgetl(mask+4*h); @@ -482,15 +475,15 @@ v6delroute(Fs *f, uchar *a, uchar *mask, int dolock) } Route* -v4lookup(Fs *f, uchar *a, Conv *c) +v4lookup(Fs *f, uchar *a, Routehint *rh) { Route *p, *q; ulong la; uchar gate[IPaddrlen]; Ipifc *ifc; - if(c != nil && c->r != nil && c->r->ifc != nil && c->rgen == v4routegeneration) - return c->r; + if(rh != nil && rh->r != nil && rh->r->ifc != nil && rh->rgen == v4routegeneration) + return rh->r; la = nhgetl(a); q = nil; @@ -517,16 +510,16 @@ v4lookup(Fs *f, uchar *a, Conv *c) q->ifcid = ifc->ifcid; } - if(c != nil){ - c->r = q; - c->rgen = v4routegeneration; + if(rh != nil){ + rh->r = q; + rh->rgen = v4routegeneration; } return q; } Route* -v6lookup(Fs *f, uchar *a, Conv *c) +v6lookup(Fs *f, uchar *a, Routehint *rh) { Route *p, *q; ulong la[IPllen]; @@ -536,18 +529,18 @@ v6lookup(Fs *f, uchar *a, Conv *c) Ipifc *ifc; if(memcmp(a, v4prefix, IPv4off) == 0){ - q = v4lookup(f, a+IPv4off, c); + q = v4lookup(f, a+IPv4off, rh); if(q != nil) return q; } - if(c != nil && c->r != nil && c->r->ifc != nil && c->rgen == v6routegeneration) - return c->r; + if(rh != nil && rh->r != nil && rh->r->ifc != nil && rh->rgen == v6routegeneration) + return rh->r; for(h = 0; h < IPllen; h++) la[h] = nhgetl(a+4*h); - q = 0; + q = nil; for(p=f->v6root[V6H(la)]; p;){ for(h = 0; h < IPllen; h++){ x = la[h]; @@ -588,9 +581,10 @@ next: ; q->ifc = ifc; q->ifcid = ifc->ifcid; } - if(c != nil){ - c->r = q; - c->rgen = v6routegeneration; + + if(rh != nil){ + rh->r = q; + rh->rgen = v6routegeneration; } return q; diff --git a/sys/src/9/ip/ipv6.c b/sys/src/9/ip/ipv6.c index 8b50706f4..1fbfedc34 100644 --- a/sys/src/9/ip/ipv6.c +++ b/sys/src/9/ip/ipv6.c @@ -28,7 +28,7 @@ static Block* procxtns(IP *ip, Block *bp, int doreasm); int unfraglen(Block *bp, uchar *nexthdr, int setfh); int -ipoput6(Fs *f, Block *bp, int gating, int ttl, int tos, Conv *c) +ipoput6(Fs *f, Block *bp, int gating, int ttl, int tos, Routehint *rh) { int medialen, len, chunk, uflen, flen, seglen, lid, offset, fragoff; int morefrags, blklen, rv = 0, tentative; @@ -74,9 +74,8 @@ ipoput6(Fs *f, Block *bp, int gating, int ttl, int tos, Conv *c) goto free; } - r = v6lookup(f, eh->dst, c); + r = v6lookup(f, eh->dst, rh); if(r == nil){ -// print("no route for %I, src %I free\n", eh->dst, eh->src); ip->stats[OutNoRoutes]++; netlog(f, Logip, "no interface %I\n", eh->dst); rv = -1; @@ -231,7 +230,6 @@ ipiput6(Fs *f, Ipifc *ifc, Block *bp) IP *ip; Ip6hdr *h; Proto *p; - Route *r, *sr; ip = f->ip; ip->stats[InReceives]++; @@ -274,6 +272,9 @@ ipiput6(Fs *f, Ipifc *ifc, Block *bp) /* route */ if(notforme) { + Route *r; + Routehint rh; + if(!ip->iprouting){ freeblist(bp); return; @@ -288,10 +289,9 @@ ipiput6(Fs *f, Ipifc *ifc, Block *bp) } /* don't forward to source's network */ - sr = v6lookup(f, h->src, nil); - r = v6lookup(f, h->dst, nil); - - if(r == nil || sr == r){ + rh.r = nil; + r = v6lookup(f, h->dst, &rh); + if(r == nil || r->ifc == ifc){ ip->stats[OutDiscards]++; freeblist(bp); return; @@ -315,7 +315,7 @@ ipiput6(Fs *f, Ipifc *ifc, Block *bp) h = (Ip6hdr *)bp->rp; tos = IPV6CLASS(h); hop = h->ttl; - ipoput6(f, bp, 1, hop-1, tos, nil); + ipoput6(f, bp, 1, hop-1, tos, &rh); return; } diff --git a/sys/src/9/ip/rudp.c b/sys/src/9/ip/rudp.c index cc3da20f6..bbf779b02 100644 --- a/sys/src/9/ip/rudp.c +++ b/sys/src/9/ip/rudp.c @@ -567,7 +567,7 @@ rudpiput(Proto *rudp, Ipifc *ifc, Block *bp) if(ipforme(f, laddr) == Runi) ipmove(c->laddr, laddr); else - v4tov6(c->laddr, ifc->lifc->local); + ipv6local(ifc, c->laddr, c->raddr); } break; } diff --git a/sys/src/9/ip/udp.c b/sys/src/9/ip/udp.c index adaaac0df..fbaabd634 100644 --- a/sys/src/9/ip/udp.c +++ b/sys/src/9/ip/udp.c @@ -189,7 +189,7 @@ udpkick(void *x, Block *bp) Udppriv *upriv; Fs *f; int version; - Conv *rc; + Routehint *rh; upriv = c->p->priv; f = c->p->f; @@ -222,18 +222,12 @@ udpkick(void *x, Block *bp) } if(ucb->headers) { - if(memcmp(laddr, v4prefix, IPv4off) == 0 - || ipcmp(laddr, IPnoaddr) == 0) - version = 4; + if(isv4(laddr) || ipcmp(laddr, IPnoaddr) == 0) + version = V4; else - version = 6; + version = V6; } else { - if( (memcmp(c->raddr, v4prefix, IPv4off) == 0 && - memcmp(c->laddr, v4prefix, IPv4off) == 0) - || ipcmp(c->raddr, IPnoaddr) == 0) - version = 4; - else - version = 6; + version = convipvers(c); } dlen = blocklen(bp); @@ -253,14 +247,14 @@ udpkick(void *x, Block *bp) v6tov4(uh4->udpdst, raddr); hnputs(uh4->udpdport, rport); v6tov4(uh4->udpsrc, laddr); - rc = nil; + rh = nil; } else { v6tov4(uh4->udpdst, c->raddr); hnputs(uh4->udpdport, c->rport); if(ipcmp(c->laddr, IPnoaddr) == 0) findlocalip(f, c->laddr, c->raddr); v6tov4(uh4->udpsrc, c->laddr); - rc = c; + rh = c; } hnputs(uh4->udpsport, c->lport); hnputs(uh4->udplen, ptcllen); @@ -269,7 +263,7 @@ udpkick(void *x, Block *bp) hnputs(uh4->udpcksum, ptclcsum(bp, UDP4_PHDR_OFF, dlen+UDP_UDPHDR_SZ+UDP4_PHDR_SZ)); uh4->vihl = IP_VER4; - ipoput4(f, bp, 0, c->ttl, c->tos, rc); + ipoput4(f, bp, 0, c->ttl, c->tos, rh); break; case V6: @@ -287,14 +281,14 @@ udpkick(void *x, Block *bp) ipmove(uh6->udpdst, raddr); hnputs(uh6->udpdport, rport); ipmove(uh6->udpsrc, laddr); - rc = nil; + rh = nil; } else { ipmove(uh6->udpdst, c->raddr); hnputs(uh6->udpdport, c->rport); if(ipcmp(c->laddr, IPnoaddr) == 0) findlocalip(f, c->laddr, c->raddr); ipmove(uh6->udpsrc, c->laddr); - rc = c; + rh = c; } hnputs(uh6->udpsport, c->lport); hnputs(uh6->udplen, ptcllen); @@ -306,7 +300,7 @@ udpkick(void *x, Block *bp) uh6->viclfl[0] = IP_VER6; hnputs(uh6->len, ptcllen); uh6->nextheader = IP_UDPPROTO; - ipoput6(f, bp, 0, c->ttl, c->tos, rc); + ipoput6(f, bp, 0, c->ttl, c->tos, rh); break; default: @@ -336,7 +330,7 @@ udpiput(Proto *udp, Ipifc *ifc, Block *bp) upriv->ustats.udpInDatagrams++; uh4 = (Udp4hdr*)(bp->rp); - version = ((uh4->vihl&0xF0)==IP_VER6) ? 6 : 4; + version = ((uh4->vihl&0xF0)==IP_VER6) ? V6 : V4; /* Put back pseudo header for checksum * (remember old values for icmpnoconv()) */ @@ -424,18 +418,8 @@ udpiput(Proto *udp, Ipifc *ifc, Block *bp) if(c->state == Announced){ if(ucb->headers == 0){ /* create a new conversation */ - if(ipforme(f, laddr) != Runi) { - switch(version){ - case V4: - v4tov6(laddr, ifc->lifc->local); - break; - case V6: - ipmove(laddr, ifc->lifc->local); - break; - default: - panic("udpiput3: version %d", version); - } - } + if(ipforme(f, laddr) != Runi) + ipv6local(ifc, laddr, raddr); c = Fsnewcall(c, raddr, rport, laddr, lport, version); if(c == nil){ qunlock(udp); @@ -533,7 +517,7 @@ udpadvise(Proto *udp, Block *bp, char *msg) int version; h4 = (Udp4hdr*)(bp->rp); - version = ((h4->vihl&0xF0)==IP_VER6) ? 6 : 4; + version = ((h4->vihl&0xF0)==IP_VER6) ? V6 : V4; switch(version) { case V4: |
