This commit is contained in:
cinap_lenrek 2018-03-18 07:53:10 +01:00
commit 20cbb88e32
14 changed files with 208 additions and 299 deletions

View file

@ -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);

View file

@ -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);

View file

@ -266,17 +266,6 @@ espclose(Conv *c)
memset(ecb, 0, sizeof(Espcb));
}
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)
{

View file

@ -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);
}
/*

View file

@ -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;

View file

@ -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;
}

View file

@ -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);

View file

@ -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;
}

View file

@ -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,142 +1236,137 @@ findprimaryipv4(Fs *f, uchar *local)
return;
}
}
ipmove(local, IPnoaddr);
}
static int
comprefixlen(uchar *a, uchar *b, int n)
{
int i, c;
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;
}
return i << 3;
}
/*
* find the local address 'closest' to the remote system, copy it to
* local and return the ifc for that address
* return v4 address associated with an interface close to remote
*/
int
ipv4local(Ipifc *ifc, uchar *local, uchar *remote)
{
Iplifc *lifc;
int a, b;
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 b >= 0;
}
/*
* return v6 address associated with an interface close to remote
*/
int
ipv6local(Ipifc *ifc, uchar *local, uchar *remote)
{
struct {
int atype;
int deprecated;
int comprefixlen;
} a, b;
int atype;
Iplifc *lifc;
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 b.atype >= atype;
}
/*
* find the local address 'closest' to the remote system, copy it to local
*/
void
findlocalip(Fs *f, uchar *local, uchar *remote)
{
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);
if((r = v6lookup(f, remote, nil)) != nil){
if(r->type & Runi){
ipmove(local, remote);
goto out;
}
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)
if((r->type & (Rifc|Rbcast|Rmulti|Rv4)) == Rv4){
ipmove(local, v4prefix);
if(ipv4local(r->ifc, local+IPv4off, r->v4.gate))
goto out;
break;
default:
panic("findlocalip: version %d", version);
}
if(ipv6local(r->ifc, local, remote))
goto out;
}
switch(version){
case V4:
if(isv4(remote))
findprimaryipv4(f, local);
break;
case V6:
else
findprimaryipv6(f, local);
break;
default:
panic("findlocalip2: version %d", version);
}
out:
qunlock(f->ipifc);
}
/*
* return first v4 address associated with an interface
*/
int
ipv4local(Ipifc *ifc, uchar *addr)
{
Iplifc *lifc;
for(lifc = ifc->lifc; lifc; lifc = lifc->next){
if(isv4(lifc->local)){
memmove(addr, lifc->local+IPv4off, IPv4addrlen);
return 1;
}
}
return 0;
}
/*
* return first v6 address associated with an interface
*/
int
ipv6local(Ipifc *ifc, uchar *addr)
{
Iplifc *lifc;
for(lifc = ifc->lifc; lifc; lifc = lifc->next){
if(!isv4(lifc->local) && !(lifc->tentative)){
ipmove(addr, lifc->local);
return 1;
}
}
return 0;
}
int
ipv6anylocal(Ipifc *ifc, uchar *addr)
{
Iplifc *lifc;
for(lifc = ifc->lifc; lifc; lifc = lifc->next){
if(!isv4(lifc->local)){
ipmove(addr, lifc->local);
return SRC_UNI;
}
}
return SRC_UNSPEC;
}
/*
* see if this address is bound to the interface
*/
@ -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)
{

View file

@ -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;

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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:

View file

@ -468,7 +468,6 @@ static void
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 */