ref: 20cbb88e32ece30dd984ab658c365f574790d6ba
parent: 87df80019e3676583f2d60d500179ddcfabab584
parent: 71f807873b43a4d2a2e2c9d1acbe1d97b5fdf18c
author: cinap_lenrek <[email protected]>
date: Sun Mar 18 03:53:10 EDT 2018
merge
--- a/sys/src/9/ip/arp.c
+++ b/sys/src/9/ip/arp.c
@@ -539,7 +539,6 @@
extern int
rxmitsols(Arp *arp)
{
- uint sflag;
Block *next, *xp;
Arpent *a, *b, **l;
Fs *f;
@@ -582,8 +581,8 @@
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);
--- a/sys/src/9/ip/devip.c
+++ b/sys/src/9/ip/devip.c
@@ -919,12 +919,7 @@
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 @@
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 @@
c->lport = 0;
c->rport = 0;
c->restricted = 0;
- c->maxfragsize = 0;
c->ttl = MAXTTL;
qreopen(c->rq);
qreopen(c->wq);
--- a/sys/src/9/ip/esp.c
+++ b/sys/src/9/ip/esp.c
@@ -267,17 +267,6 @@
}
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) {
--- a/sys/src/9/ip/ethermedium.c
+++ b/sys/src/9/ip/ethermedium.c
@@ -477,7 +477,7 @@
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 @@
static void
resolveaddr6(Ipifc *ifc, Arpent *a)
{
- int sflag;
Block *bp;
Etherrock *er = ifc->arg;
uchar ipsrc[IPaddrlen];
@@ -526,8 +525,8 @@
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);
}
/*
--- a/sys/src/9/ip/icmp6.c
+++ b/sys/src/9/ip/icmp6.c
@@ -331,7 +331,7 @@
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 @@
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 @@
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 @@
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 @@
}
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 @@
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 @@
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;
--- a/sys/src/9/ip/ip.c
+++ b/sys/src/9/ip/ip.c
@@ -63,8 +63,6 @@
v6p->hp.rxmithost = 1000; /* v6 RETRANS_TIMER */
- v6p->cdrouter = -1;
-
f->v6p = v6p;
}
@@ -118,7 +116,7 @@
}
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 @@
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 @@
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 @@
int notforme;
uchar *dp, v6dst[IPaddrlen];
IP *ip;
- Route *r;
- Conv conv;
if(BLKIPVER(bp) != IP_VER4) {
ipiput6(f, ifc, bp);
@@ -377,6 +370,9 @@
/* route */
if(notforme) {
+ Route *r;
+ Routehint rh;
+
if(!ip->iprouting){
freeblist(bp);
return;
@@ -383,9 +379,8 @@
}
/* 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 @@
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;
}
--- a/sys/src/9/ip/ip.h
+++ b/sys/src/9/ip/ip.h
@@ -21,10 +21,10 @@
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 @@
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 @@
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 @@
void* ptcl; /* protocol specific stuff */
- Route *r; /* last route used */
- ulong rgen; /* routetable generation for *r */
+ Routehint;
};
struct Medium
@@ -443,23 +446,10 @@
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 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 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 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 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);
--- a/sys/src/9/ip/ipaux.c
+++ b/sys/src/9/ip/ipaux.c
@@ -366,3 +366,12 @@
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;
+}
--- a/sys/src/9/ip/ipifc.c
+++ b/sys/src/9/ip/ipifc.c
@@ -1095,7 +1095,7 @@
* 0 - no match
* Runi
* Rbcast
- * Rmcast
+ * Rmulti
*/
int
ipforme(Fs *f, uchar *addr)
@@ -1163,7 +1163,6 @@
enum {
unknownv6, /* UGH */
-// multicastv6,
unspecifiedv6,
linklocalv6,
globalv6,
@@ -1237,140 +1236,135 @@
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;
+ int i, c;
- 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);
- }
+ 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;
}
-
- switch(version){
- case V4:
- findprimaryipv4(f, local);
- break;
- case V6:
- findprimaryipv6(f, local);
- break;
- default:
- panic("findlocalip2: version %d", version);
- }
-
-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);
}
/*
@@ -1604,29 +1598,6 @@
}
}
}
-
-
-/* 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)
--- a/sys/src/9/ip/iproute.c
+++ b/sys/src/9/ip/iproute.c
@@ -323,7 +323,6 @@
}
#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 @@
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,7 +475,7 @@
}
Route*
-v4lookup(Fs *f, uchar *a, Conv *c)
+v4lookup(Fs *f, uchar *a, Routehint *rh)
{
Route *p, *q;
ulong la;
@@ -489,8 +482,8 @@
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,9 +510,9 @@
q->ifcid = ifc->ifcid;
}
- if(c != nil){
- c->r = q;
- c->rgen = v4routegeneration;
+ if(rh != nil){
+ rh->r = q;
+ rh->rgen = v4routegeneration;
}
return q;
@@ -526,7 +519,7 @@
}
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 @@
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 @@
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;
--- a/sys/src/9/ip/ipv6.c
+++ b/sys/src/9/ip/ipv6.c
@@ -28,7 +28,7 @@
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 @@
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 @@
IP *ip;
Ip6hdr *h;
Proto *p;
- Route *r, *sr;
ip = f->ip;
ip->stats[InReceives]++;
@@ -274,6 +272,9 @@
/* route */
if(notforme) {
+ Route *r;
+ Routehint rh;
+
if(!ip->iprouting){
freeblist(bp);
return;
@@ -288,10 +289,9 @@
}
/* 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 @@
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;
}
--- a/sys/src/9/ip/rudp.c
+++ b/sys/src/9/ip/rudp.c
@@ -567,7 +567,7 @@
if(ipforme(f, laddr) == Runi)
ipmove(c->laddr, laddr);
else
- v4tov6(c->laddr, ifc->lifc->local);
+ ipv6local(ifc, c->laddr, c->raddr);
}
break;
}
--- a/sys/src/9/ip/udp.c
+++ b/sys/src/9/ip/udp.c
@@ -189,7 +189,7 @@
Udppriv *upriv;
Fs *f;
int version;
- Conv *rc;
+ Routehint *rh;
upriv = c->p->priv;
f = c->p->f;
@@ -222,18 +222,12 @@
}
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,7 +247,7 @@
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);
@@ -260,7 +254,7 @@
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 @@
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,7 +281,7 @@
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);
@@ -294,7 +288,7 @@
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 @@
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 @@
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 @@
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 @@
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:
--- a/sys/src/cmd/ip/ipconfig/ipv6.c
+++ b/sys/src/cmd/ip/ipconfig/ipv6.c
@@ -468,7 +468,6 @@
recvrarouter(uchar buf[], int pktlen)
{
USED(buf, pktlen);
- ralog("i am a router and got a router advert");
}
/* host receiving a router advertisement calls this */