devip: implement source specific routing
This commit is contained in:
parent
dc8432d459
commit
c2dd9b1da7
12 changed files with 1069 additions and 1003 deletions
|
@ -74,7 +74,7 @@ freeblistchain(Block *bp)
|
|||
}
|
||||
|
||||
/*
|
||||
* create a new arp entry for an ip address.
|
||||
* create a new arp entry for an ip address on ifc.
|
||||
*/
|
||||
static Arpent*
|
||||
newarp6(Arp *arp, uchar *ip, Ipifc *ifc, int addrxt)
|
||||
|
@ -82,7 +82,6 @@ newarp6(Arp *arp, uchar *ip, Ipifc *ifc, int addrxt)
|
|||
uint t;
|
||||
Block *xp;
|
||||
Arpent *a, *e, *f, **l;
|
||||
Medium *m = ifc->m;
|
||||
int empty;
|
||||
|
||||
/* find oldest entry */
|
||||
|
@ -128,10 +127,9 @@ newarp6(Arp *arp, uchar *ip, Ipifc *ifc, int addrxt)
|
|||
a->hash = *l;
|
||||
*l = a;
|
||||
|
||||
memmove(a->ip, ip, sizeof(a->ip));
|
||||
ipmove(a->ip, ip);
|
||||
a->utime = NOW;
|
||||
a->ctime = 0;
|
||||
a->type = m;
|
||||
|
||||
a->rtime = NOW + ReTransTimer;
|
||||
a->rxtsrem = MAX_MULTICAST_SOLICIT;
|
||||
|
@ -172,8 +170,10 @@ cleanarpent(Arp *arp, Arpent *a)
|
|||
|
||||
a->utime = 0;
|
||||
a->ctime = 0;
|
||||
a->type = 0;
|
||||
a->state = 0;
|
||||
|
||||
a->ifc = nil;
|
||||
a->ifcid = 0;
|
||||
|
||||
/* take out of current chain */
|
||||
l = &arp->hash[haship(a->ip)];
|
||||
|
@ -198,7 +198,6 @@ cleanarpent(Arp *arp, Arpent *a)
|
|||
a->hash = nil;
|
||||
freeblistchain(a->hold);
|
||||
a->hold = a->last = nil;
|
||||
a->ifc = nil;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -212,7 +211,6 @@ arpget(Arp *arp, Block *bp, int version, Ipifc *ifc, uchar *ip, uchar *mac)
|
|||
{
|
||||
int hash;
|
||||
Arpent *a;
|
||||
Medium *type = ifc->m;
|
||||
uchar v6ip[IPaddrlen];
|
||||
|
||||
if(version == V4){
|
||||
|
@ -223,11 +221,9 @@ arpget(Arp *arp, Block *bp, int version, Ipifc *ifc, uchar *ip, uchar *mac)
|
|||
qlock(arp);
|
||||
hash = haship(ip);
|
||||
for(a = arp->hash[hash]; a != nil; a = a->hash){
|
||||
if(ipcmp(ip, a->ip) == 0)
|
||||
if(type == a->type)
|
||||
if(a->ifc == ifc && a->ifcid == ifc->ifcid && ipcmp(ip, a->ip) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if(a == nil){
|
||||
a = newarp6(arp, ip, ifc, (version != V4));
|
||||
a->state = AWAIT;
|
||||
|
@ -245,7 +241,7 @@ arpget(Arp *arp, Block *bp, int version, Ipifc *ifc, uchar *ip, uchar *mac)
|
|||
return a; /* return with arp qlocked */
|
||||
}
|
||||
|
||||
memmove(mac, a->mac, a->type->maclen);
|
||||
memmove(mac, a->mac, ifc->m->maclen);
|
||||
|
||||
/* remove old entries */
|
||||
if(NOW - a->ctime > 15*60*1000)
|
||||
|
@ -286,63 +282,53 @@ arpresolve(Arp *arp, Arpent *a, Medium *type, uchar *mac)
|
|||
l = &f->nextrxt;
|
||||
}
|
||||
}
|
||||
|
||||
memmove(a->mac, mac, type->maclen);
|
||||
a->type = type;
|
||||
a->state = AOK;
|
||||
a->utime = NOW;
|
||||
bp = a->hold;
|
||||
assert(bp->list == nil);
|
||||
a->hold = a->last = nil;
|
||||
qunlock(arp);
|
||||
|
||||
return bp;
|
||||
}
|
||||
|
||||
void
|
||||
arpenter(Fs *fs, int version, uchar *ip, uchar *mac, int n, int refresh)
|
||||
int
|
||||
arpenter(Fs *fs, int version, uchar *ip, uchar *mac, int n, uchar *src, int refresh)
|
||||
{
|
||||
Arp *arp;
|
||||
Route *r;
|
||||
Arpent *a, *f, **l;
|
||||
Ipifc *ifc;
|
||||
Medium *type;
|
||||
Block *bp, *next;
|
||||
Medium *m;
|
||||
uchar v6ip[IPaddrlen];
|
||||
|
||||
arp = fs->arp;
|
||||
|
||||
if(n != 6)
|
||||
return;
|
||||
|
||||
switch(version){
|
||||
case V4:
|
||||
r = v4lookup(fs, ip, nil);
|
||||
r = v4lookup(fs, ip, src, nil);
|
||||
v4tov6(v6ip, ip);
|
||||
ip = v6ip;
|
||||
break;
|
||||
case V6:
|
||||
r = v6lookup(fs, ip, nil);
|
||||
r = v6lookup(fs, ip, src, nil);
|
||||
break;
|
||||
default:
|
||||
panic("arpenter: version %d", version);
|
||||
return; /* to supress warnings */
|
||||
return -1; /* to supress warnings */
|
||||
}
|
||||
|
||||
if(r == nil)
|
||||
return;
|
||||
|
||||
ifc = r->ifc;
|
||||
type = ifc->m;
|
||||
if(r == nil || (ifc = r->ifc) == nil || (m = ifc->m) == nil || m->maclen != n || m->maclen == 0)
|
||||
return -1;
|
||||
|
||||
qlock(arp);
|
||||
for(a = arp->hash[haship(ip)]; a != nil; a = a->hash){
|
||||
if(a->type != type || (a->state != AWAIT && a->state != AOK))
|
||||
if(a->state != AWAIT && a->state != AOK)
|
||||
continue;
|
||||
if(a->ifc != ifc || a->ifcid != ifc->ifcid)
|
||||
continue;
|
||||
|
||||
if(ipcmp(a->ip, ip) == 0){
|
||||
a->state = AOK;
|
||||
memmove(a->mac, mac, type->maclen);
|
||||
memmove(a->mac, mac, n);
|
||||
|
||||
if(version == V6){
|
||||
/* take out of re-transmit chain */
|
||||
|
@ -356,8 +342,6 @@ arpenter(Fs *fs, int version, uchar *ip, uchar *mac, int n, int refresh)
|
|||
}
|
||||
}
|
||||
|
||||
a->ifc = ifc;
|
||||
a->ifcid = ifc->ifcid;
|
||||
bp = a->hold;
|
||||
a->hold = a->last = nil;
|
||||
if(version == V4)
|
||||
|
@ -367,46 +351,52 @@ arpenter(Fs *fs, int version, uchar *ip, uchar *mac, int n, int refresh)
|
|||
qunlock(arp);
|
||||
|
||||
while(bp != nil){
|
||||
next = bp->list;
|
||||
if(waserror()){
|
||||
freeblistchain(next);
|
||||
runlock(ifc);
|
||||
nexterror();
|
||||
if(!canrlock(ifc)){
|
||||
freeblistchain(bp);
|
||||
break;
|
||||
}
|
||||
rlock(ifc);
|
||||
if(ifc->m != nil)
|
||||
ifc->m->bwrite(ifc, concatblock(bp), version, ip);
|
||||
else
|
||||
freeblist(bp);
|
||||
if(ifc->m != m){
|
||||
runlock(ifc);
|
||||
freeblistchain(bp);
|
||||
break;
|
||||
}
|
||||
next = bp->list;
|
||||
bp->list = nil;
|
||||
if(waserror()){
|
||||
runlock(ifc);
|
||||
freeblistchain(next);
|
||||
break;
|
||||
}
|
||||
m->bwrite(ifc, concatblock(bp), version, ip);
|
||||
runlock(ifc);
|
||||
poperror();
|
||||
bp = next;
|
||||
}
|
||||
return;
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(refresh == 0){
|
||||
a = newarp6(arp, ip, ifc, 0);
|
||||
a->state = AOK;
|
||||
a->type = type;
|
||||
a->ctime = NOW;
|
||||
memmove(a->mac, mac, type->maclen);
|
||||
memmove(a->mac, mac, n);
|
||||
}
|
||||
|
||||
qunlock(arp);
|
||||
return refresh == 0;
|
||||
}
|
||||
|
||||
int
|
||||
arpwrite(Fs *fs, char *s, int len)
|
||||
{
|
||||
int n;
|
||||
Route *r;
|
||||
Arp *arp;
|
||||
Arpent *a;
|
||||
Arpent *a, *x;
|
||||
Medium *m;
|
||||
char *f[4], buf[256];
|
||||
uchar ip[IPaddrlen], mac[MAClen];
|
||||
char *f[5], buf[256];
|
||||
uchar ip[IPaddrlen], src[IPaddrlen], mac[MAClen];
|
||||
|
||||
arp = fs->arp;
|
||||
|
||||
|
@ -419,7 +409,7 @@ arpwrite(Fs *fs, char *s, int len)
|
|||
if(len > 0 && buf[len-1] == '\n')
|
||||
buf[len-1] = 0;
|
||||
|
||||
n = getfields(buf, f, 4, 1, " ");
|
||||
n = getfields(buf, f, nelem(f), 1, " ");
|
||||
if(strcmp(f[0], "flush") == 0){
|
||||
qlock(arp);
|
||||
for(a = arp->cache; a < &arp->cache[NCACHE]; a++){
|
||||
|
@ -428,6 +418,8 @@ arpwrite(Fs *fs, char *s, int len)
|
|||
a->hash = nil;
|
||||
a->state = 0;
|
||||
a->utime = 0;
|
||||
a->ifc = nil;
|
||||
a->ifcid = 0;
|
||||
freeblistchain(a->hold);
|
||||
a->hold = a->last = nil;
|
||||
}
|
||||
|
@ -442,47 +434,49 @@ arpwrite(Fs *fs, char *s, int len)
|
|||
default:
|
||||
error(Ebadarg);
|
||||
case 3:
|
||||
if (parseip(ip, f[1]) == -1)
|
||||
if(parseip(ip, f[1]) == -1)
|
||||
error(Ebadip);
|
||||
if(isv4(ip))
|
||||
r = v4lookup(fs, ip+IPv4off, nil);
|
||||
else
|
||||
r = v6lookup(fs, ip, nil);
|
||||
if(r == nil)
|
||||
error("Destination unreachable");
|
||||
m = r->ifc->m;
|
||||
n = parsemac(mac, f[2], m->maclen);
|
||||
if((n = parsemac(mac, f[2], sizeof(mac))) <= 0)
|
||||
error(Ebadarp);
|
||||
findlocalip(fs, src, ip);
|
||||
break;
|
||||
case 4:
|
||||
m = ipfindmedium(f[1]);
|
||||
if(m == nil)
|
||||
if(m == nil || m->maclen == 0)
|
||||
error(Ebadarp);
|
||||
if (parseip(ip, f[2]) == -1)
|
||||
if(parseip(ip, f[2]) == -1)
|
||||
error(Ebadip);
|
||||
if((n = parsemac(mac, f[3], sizeof(mac))) != m->maclen)
|
||||
error(Ebadarp);
|
||||
findlocalip(fs, src, ip);
|
||||
break;
|
||||
case 5:
|
||||
m = ipfindmedium(f[1]);
|
||||
if(m == nil || m->maclen == 0)
|
||||
error(Ebadarp);
|
||||
if(parseip(ip, f[2]) == -1)
|
||||
error(Ebadip);
|
||||
if((n = parsemac(mac, f[3], sizeof(mac))) != m->maclen)
|
||||
error(Ebadarp);
|
||||
if(parseip(src, f[4]) == -1)
|
||||
error(Ebadip);
|
||||
n = parsemac(mac, f[3], m->maclen);
|
||||
break;
|
||||
}
|
||||
|
||||
if(m->ares == nil)
|
||||
error(Ebadarp);
|
||||
|
||||
m->ares(fs, V6, ip, mac, n, 0);
|
||||
if(arpenter(fs, V6, ip, mac, n, src, 0) <= 0)
|
||||
error("destination unreachable");
|
||||
} else if(strcmp(f[0], "del") == 0){
|
||||
if(n != 2)
|
||||
if (n != 2)
|
||||
error(Ebadarg);
|
||||
|
||||
if (parseip(ip, f[1]) == -1)
|
||||
error(Ebadip);
|
||||
|
||||
qlock(arp);
|
||||
for(a = arp->hash[haship(ip)]; a != nil; a = a->hash)
|
||||
if(memcmp(ip, a->ip, sizeof(a->ip)) == 0)
|
||||
break;
|
||||
|
||||
if(a != nil){
|
||||
cleanarpent(arp, a);
|
||||
memset(a->ip, 0, sizeof(a->ip));
|
||||
memset(a->mac, 0, sizeof(a->mac));
|
||||
for(a = arp->hash[haship(ip)]; a != nil; a = x){
|
||||
x = a->hash;
|
||||
if(ipcmp(ip, a->ip) == 0){
|
||||
cleanarpent(arp, a);
|
||||
memset(a->ip, 0, sizeof(a->ip));
|
||||
memset(a->mac, 0, sizeof(a->mac));
|
||||
}
|
||||
}
|
||||
qunlock(arp);
|
||||
} else
|
||||
|
@ -491,13 +485,6 @@ arpwrite(Fs *fs, char *s, int len)
|
|||
return len;
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
Alinelen= 90,
|
||||
};
|
||||
|
||||
char *aformat = "%-6.6s %-8.8s %-40.40I %-32.32s\n";
|
||||
|
||||
static void
|
||||
convmac(char *p, uchar *mac, int n)
|
||||
{
|
||||
|
@ -506,34 +493,40 @@ convmac(char *p, uchar *mac, int n)
|
|||
}
|
||||
|
||||
int
|
||||
arpread(Arp *arp, char *p, ulong offset, int len)
|
||||
arpread(Arp *arp, char *s, ulong offset, int len)
|
||||
{
|
||||
uchar ip[IPaddrlen], src[IPaddrlen];
|
||||
char mac[2*MAClen+1], *p, *state;
|
||||
Ipifc *ifc;
|
||||
Arpent *a;
|
||||
int n;
|
||||
char mac[2*MAClen+1];
|
||||
long n, o;
|
||||
|
||||
if(offset % Alinelen)
|
||||
return 0;
|
||||
|
||||
offset = offset/Alinelen;
|
||||
len = len/Alinelen;
|
||||
|
||||
n = 0;
|
||||
p = s;
|
||||
o = -offset;
|
||||
for(a = arp->cache; len > 0 && a < &arp->cache[NCACHE]; a++){
|
||||
if(a->state == 0)
|
||||
if(a->state == 0 || (ifc = a->ifc) == nil || a->ifcid != ifc->ifcid)
|
||||
continue;
|
||||
if(offset > 0){
|
||||
offset--;
|
||||
continue;
|
||||
}
|
||||
len--;
|
||||
|
||||
qlock(arp);
|
||||
convmac(mac, a->mac, a->type->maclen);
|
||||
n += sprint(p+n, aformat, a->type->name, arpstate[a->state], a->ip, mac);
|
||||
state = arpstate[a->state];
|
||||
ipmove(ip, a->ip);
|
||||
convmac(mac, a->mac, ifc->m->maclen);
|
||||
qunlock(arp);
|
||||
|
||||
ipv6local(ifc, src, ip);
|
||||
n = snprint(p, len, "%-6.6s %-4.4s %-40.40I %-16.16s %I\n",
|
||||
ifc->m->name, state, ip, mac, src);
|
||||
if(o < 0) {
|
||||
if(n > -o)
|
||||
memmove(p, p-o, n+o);
|
||||
o += n;
|
||||
} else {
|
||||
len -= n;
|
||||
p += n;
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
return p - s;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -547,7 +540,7 @@ ndpsendsol(Fs *f, Ipifc *ifc, Arpent *a)
|
|||
ipmove(src, ((Ip6hdr*)a->last->rp)->src);
|
||||
arprelease(f->arp, a);
|
||||
|
||||
if(iplocalonifc(ifc, src) || ipproxyifc(f, ifc, src))
|
||||
if(iplocalonifc(ifc, src) != nil || ipproxyifc(f, ifc, src))
|
||||
goto send;
|
||||
} else {
|
||||
arprelease(f->arp, a);
|
||||
|
|
|
@ -848,7 +848,7 @@ setladdrport(Conv* c, char* str, int announcing)
|
|||
else {
|
||||
if(parseip(addr, str) == -1)
|
||||
return Ebadip;
|
||||
if(ipforme(c->p->f, addr) || ipismulticast(addr))
|
||||
if(ipforme(c->p->f, addr) != 0 || ipismulticast(addr))
|
||||
ipmove(c->laddr, addr);
|
||||
else
|
||||
return "not a local IP address";
|
||||
|
|
|
@ -33,9 +33,9 @@ static void etherunbind(Ipifc *ifc);
|
|||
static void etherbwrite(Ipifc *ifc, Block *bp, int version, uchar *ip);
|
||||
static void etheraddmulti(Ipifc *ifc, uchar *a, uchar *ia);
|
||||
static void etherremmulti(Ipifc *ifc, uchar *a, uchar *ia);
|
||||
static void etherareg(Fs *f, Ipifc *ifc, uchar *ip, uchar *proxy);
|
||||
static Block* multicastarp(Fs *f, Arpent *a, Medium*, uchar *mac);
|
||||
static void sendarp(Ipifc *ifc, Arpent *a);
|
||||
static void sendgarp(Ipifc *ifc, uchar*);
|
||||
static int multicastea(uchar *ea, uchar *ip);
|
||||
static void recvarpproc(void*);
|
||||
static void resolveaddr6(Ipifc *ifc, Arpent *a);
|
||||
|
@ -53,8 +53,7 @@ Medium ethermedium =
|
|||
.bwrite= etherbwrite,
|
||||
.addmulti= etheraddmulti,
|
||||
.remmulti= etherremmulti,
|
||||
.ares= arpenter,
|
||||
.areg= sendgarp,
|
||||
.areg= etherareg,
|
||||
.pref2addr= etherpref2addr,
|
||||
};
|
||||
|
||||
|
@ -70,8 +69,7 @@ Medium gbemedium =
|
|||
.bwrite= etherbwrite,
|
||||
.addmulti= etheraddmulti,
|
||||
.remmulti= etherremmulti,
|
||||
.ares= arpenter,
|
||||
.areg= sendgarp,
|
||||
.areg= etherareg,
|
||||
.pref2addr= etherpref2addr,
|
||||
};
|
||||
|
||||
|
@ -271,7 +269,7 @@ etherbwrite(Ipifc *ifc, Block *bp, int version, uchar *ip)
|
|||
|
||||
/* get mac address of destination */
|
||||
a = arpget(er->f->arp, bp, version, ifc, ip, mac);
|
||||
if(a){
|
||||
if(a != nil){
|
||||
/* check for broadcast or multicast */
|
||||
bp = multicastarp(er->f, a, ifc->m, mac);
|
||||
if(bp==nil){
|
||||
|
@ -471,8 +469,8 @@ sendarp(Ipifc *ifc, Arpent *a)
|
|||
arprelease(er->f->arp, a);
|
||||
|
||||
n = sizeof(Etherarp);
|
||||
if(n < a->type->mintu)
|
||||
n = a->type->mintu;
|
||||
if(n < ifc->m->mintu)
|
||||
n = ifc->m->mintu;
|
||||
bp = allocb(n);
|
||||
memset(bp->rp, 0, n);
|
||||
e = (Etherarp*)bp->rp;
|
||||
|
@ -536,10 +534,6 @@ sendgarp(Ipifc *ifc, uchar *ip)
|
|||
Etherarp *e;
|
||||
Etherrock *er = ifc->arg;
|
||||
|
||||
/* don't arp for our initial non address */
|
||||
if(ipcmp(ip, IPnoaddr) == 0)
|
||||
return;
|
||||
|
||||
n = sizeof(Etherarp);
|
||||
if(n < ifc->m->mintu)
|
||||
n = ifc->m->mintu;
|
||||
|
@ -585,7 +579,7 @@ recvarp(Ipifc *ifc)
|
|||
case ARPREPLY:
|
||||
/* check for machine using my ip address */
|
||||
v4tov6(ip, e->spa);
|
||||
if(iplocalonifc(ifc, ip) || ipproxyifc(er->f, ifc, ip)){
|
||||
if(iplocalonifc(ifc, ip) != nil || ipproxyifc(er->f, ifc, ip)){
|
||||
if(memcmp(e->sha, ifc->mac, sizeof(e->sha)) != 0){
|
||||
print("arprep: 0x%E/0x%E also has ip addr %V\n",
|
||||
e->s, e->sha, e->spa);
|
||||
|
@ -594,14 +588,13 @@ recvarp(Ipifc *ifc)
|
|||
}
|
||||
|
||||
/* make sure we're not entering broadcast addresses */
|
||||
if(ipcmp(ip, ipbroadcast) == 0 ||
|
||||
!memcmp(e->sha, etherbroadcast, sizeof(e->sha))){
|
||||
if(ipcmp(ip, ipbroadcast) == 0 || memcmp(e->sha, etherbroadcast, sizeof(e->sha)) == 0){
|
||||
print("arprep: 0x%E/0x%E cannot register broadcast address %I\n",
|
||||
e->s, e->sha, e->spa);
|
||||
break;
|
||||
}
|
||||
|
||||
arpenter(er->f, V4, e->spa, e->sha, sizeof(e->sha), 0);
|
||||
arpenter(er->f, V4, e->spa, e->sha, sizeof(e->sha), e->tpa, 0);
|
||||
break;
|
||||
|
||||
case ARPREQUEST:
|
||||
|
@ -611,9 +604,9 @@ recvarp(Ipifc *ifc)
|
|||
|
||||
/* check for machine using my ip or ether address */
|
||||
v4tov6(ip, e->spa);
|
||||
if(iplocalonifc(ifc, ip) || ipproxyifc(er->f, ifc, ip)){
|
||||
if(iplocalonifc(ifc, ip) != nil || ipproxyifc(er->f, ifc, ip)){
|
||||
if(memcmp(e->sha, ifc->mac, sizeof(e->sha)) != 0){
|
||||
if (memcmp(eprinted, e->spa, sizeof(e->spa))){
|
||||
if(memcmp(eprinted, e->spa, sizeof(e->spa)) != 0){
|
||||
/* print only once */
|
||||
print("arpreq: 0x%E also has ip addr %V\n", e->sha, e->spa);
|
||||
memmove(eprinted, e->spa, sizeof(e->spa));
|
||||
|
@ -627,12 +620,11 @@ recvarp(Ipifc *ifc)
|
|||
}
|
||||
|
||||
/* refresh what we know about sender */
|
||||
arpenter(er->f, V4, e->spa, e->sha, sizeof(e->sha), 1);
|
||||
arpenter(er->f, V4, e->spa, e->sha, sizeof(e->sha), e->tpa, 1);
|
||||
|
||||
/* answer only requests for our address or systems we're proxying for */
|
||||
v4tov6(ip, e->tpa);
|
||||
if(!iplocalonifc(ifc, ip))
|
||||
if(!ipproxyifc(er->f, ifc, ip))
|
||||
if(iplocalonifc(ifc, ip) == nil && !ipproxyifc(er->f, ifc, ip))
|
||||
break;
|
||||
|
||||
n = sizeof(Etherarp);
|
||||
|
@ -742,7 +734,7 @@ ethermediumlink(void)
|
|||
static void
|
||||
etherpref2addr(uchar *pref, uchar *ea)
|
||||
{
|
||||
pref[8] = ea[0] | 0x2;
|
||||
pref[8] = ea[0] ^ 0x2;
|
||||
pref[9] = ea[1];
|
||||
pref[10] = ea[2];
|
||||
pref[11] = 0xFF;
|
||||
|
@ -751,3 +743,31 @@ etherpref2addr(uchar *pref, uchar *ea)
|
|||
pref[14] = ea[4];
|
||||
pref[15] = ea[5];
|
||||
}
|
||||
|
||||
static void
|
||||
etherareg(Fs *f, Ipifc *ifc, uchar *ip, uchar *proxy)
|
||||
{
|
||||
static char tdad[] = "dad6";
|
||||
uchar mcast[IPaddrlen];
|
||||
|
||||
if(ipcmp(ip, IPnoaddr) == 0)
|
||||
return;
|
||||
|
||||
if(isv4(ip)){
|
||||
sendgarp(ifc, ip);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!iptentative(f, ip)){
|
||||
icmpna(f, proxy, v6allnodesL, ip, ifc->mac, 1<<5);
|
||||
return;
|
||||
}
|
||||
|
||||
/* temporarily add route for duplicate address detection */
|
||||
ipv62smcast(mcast, ip);
|
||||
addroute(f, mcast, IPallbits, v6Unspecified, IPallbits, ip, Rmulti, ifc, tdad);
|
||||
|
||||
icmpns(f, 0, SRC_UNSPEC, ip, TARG_MULTI, ifc->mac);
|
||||
|
||||
remroute(f, mcast, IPallbits, v6Unspecified, IPallbits, ip, Rmulti, ifc, tdad);
|
||||
}
|
||||
|
|
|
@ -200,7 +200,7 @@ ip4reply(Fs *f, uchar ip4[4])
|
|||
if(ipismulticast(addr))
|
||||
return 0;
|
||||
i = ipforme(f, addr);
|
||||
return i == 0 || (i & Runi) != 0;
|
||||
return i == 0 || i == Runi;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -211,7 +211,7 @@ ip4me(Fs *f, uchar ip4[4])
|
|||
v4tov6(addr, ip4);
|
||||
if(ipismulticast(addr))
|
||||
return 0;
|
||||
return (ipforme(f, addr) & Runi) != 0;
|
||||
return ipforme(f, addr) == Runi;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -401,7 +401,7 @@ icmpiput(Proto *icmp, Ipifc*, Block *bp)
|
|||
break;
|
||||
case Unreachable:
|
||||
if(p->code >= nelem(unreachcode)) {
|
||||
snprint(m2, sizeof m2, "unreachable %V->%V code %d",
|
||||
snprint(m2, sizeof m2, "unreachable %V -> %V code %d",
|
||||
p->src, p->dst, p->code);
|
||||
msg = m2;
|
||||
} else
|
||||
|
@ -452,7 +452,7 @@ raise:
|
|||
freeblist(bp);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
icmpadvise(Proto *icmp, Block *bp, char *msg)
|
||||
{
|
||||
Conv **c, *s;
|
||||
|
@ -478,7 +478,7 @@ icmpadvise(Proto *icmp, Block *bp, char *msg)
|
|||
freeblist(bp);
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
icmpstats(Proto *icmp, char *buf, int len)
|
||||
{
|
||||
Icmppriv *priv;
|
||||
|
|
|
@ -211,7 +211,7 @@ newIPICMP(int packetlen)
|
|||
return nbp;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
icmpadvise6(Proto *icmp, Block *bp, char *msg)
|
||||
{
|
||||
ushort recid;
|
||||
|
@ -223,7 +223,8 @@ icmpadvise6(Proto *icmp, Block *bp, char *msg)
|
|||
|
||||
for(c = icmp->conv; *c; c++) {
|
||||
s = *c;
|
||||
if(s->lport == recid && ipcmp(s->raddr, p->dst) == 0){
|
||||
if(s->lport == recid)
|
||||
if(ipcmp(s->laddr, p->dst) == 0 || ipcmp(s->raddr, p->dst) == 0){
|
||||
if(s->ignoreadvice)
|
||||
break;
|
||||
qhangup(s->rq, msg);
|
||||
|
@ -280,7 +281,7 @@ icmpkick6(void *x, Block *bp)
|
|||
ipoput6(c->p->f, bp, 0, c->ttl, c->tos, nil);
|
||||
}
|
||||
|
||||
char*
|
||||
static char*
|
||||
icmpctl6(Conv *c, char **argv, int argc)
|
||||
{
|
||||
Icmpcb6 *icb;
|
||||
|
@ -311,10 +312,14 @@ goticmpkt6(Proto *icmp, Block *bp, int muxkey)
|
|||
|
||||
for(c = icmp->conv; *c; c++){
|
||||
s = *c;
|
||||
if(s->lport == recid && ipcmp(s->raddr, addr) == 0){
|
||||
if(s->lport != recid)
|
||||
continue;
|
||||
if(ipcmp(s->laddr, addr) == 0){
|
||||
qpass(s->rq, concatblock(bp));
|
||||
return;
|
||||
}
|
||||
if(ipcmp(s->raddr, addr) == 0)
|
||||
qpass(s->rq, copyblock(bp, blocklen(bp)));
|
||||
}
|
||||
|
||||
freeblist(bp);
|
||||
|
@ -416,7 +421,7 @@ icmpna(Fs *f, uchar* src, uchar* dst, uchar* targ, uchar* mac, uchar flags)
|
|||
np->ttl = HOP_LIMIT;
|
||||
np->vcf[0] = 0x06 << 4;
|
||||
ipriv->out[NbrAdvert]++;
|
||||
netlog(f, Logicmp, "sending neighbor advertisement %I\n", src);
|
||||
netlog(f, Logicmp, "sending neighbor advertisement %I\n", targ);
|
||||
ipoput6(f, nbp, 0, MAXTTL, DFLTTOS, nil);
|
||||
}
|
||||
|
||||
|
@ -692,26 +697,19 @@ targettype(Fs *f, Ipifc *ifc, uchar *target)
|
|||
int t;
|
||||
|
||||
rlock(ifc);
|
||||
if(ipproxyifc(f, ifc, target)) {
|
||||
runlock(ifc);
|
||||
return Tuniproxy;
|
||||
}
|
||||
|
||||
for(lifc = ifc->lifc; lifc; lifc = lifc->next)
|
||||
if(ipcmp(lifc->local, target) == 0) {
|
||||
t = (lifc->tentative)? Tunitent: Tunirany;
|
||||
runlock(ifc);
|
||||
return t;
|
||||
}
|
||||
|
||||
if((lifc = iplocalonifc(ifc, target)) != nil)
|
||||
t = lifc->tentative? Tunitent: Tunirany;
|
||||
else if(ipproxyifc(f, ifc, target))
|
||||
t = Tuniproxy;
|
||||
else
|
||||
t = 0;
|
||||
runlock(ifc);
|
||||
return 0;
|
||||
return t;
|
||||
}
|
||||
|
||||
static void
|
||||
icmpiput6(Proto *icmp, Ipifc *ipifc, Block *bp)
|
||||
{
|
||||
int refresh = 1;
|
||||
char *msg, m2[128];
|
||||
uchar pktflags;
|
||||
uchar *packet = bp->rp;
|
||||
|
@ -797,16 +795,12 @@ icmpiput6(Proto *icmp, Ipifc *ipifc, Block *bp)
|
|||
/* fall through */
|
||||
|
||||
case Tuniproxy:
|
||||
if(ipcmp(np->src, v6Unspecified) != 0) {
|
||||
arpenter(icmp->f, V6, np->src, np->lnaddr,
|
||||
8*np->olen-2, 0);
|
||||
if(ipv6local(ipifc, lsrc, np->src)) {
|
||||
arpenter(icmp->f, V6, np->src, np->lnaddr, 8*np->olen-2, lsrc, 0);
|
||||
pktflags |= Sflag;
|
||||
}
|
||||
if(!ipv6local(ipifc, lsrc, np->src))
|
||||
break;
|
||||
icmpna(icmp->f, lsrc,
|
||||
(ipcmp(np->src, v6Unspecified) == 0?
|
||||
v6allnodesL: np->src),
|
||||
} else
|
||||
ipmove(lsrc, np->target);
|
||||
icmpna(icmp->f, lsrc, (pktflags & Sflag) ? np->src : v6allnodesL,
|
||||
np->target, ipifc->mac, pktflags);
|
||||
break;
|
||||
case Tunitent:
|
||||
|
@ -830,9 +824,10 @@ icmpiput6(Proto *icmp, Ipifc *ipifc, Block *bp)
|
|||
* the arp table.
|
||||
*/
|
||||
lifc = iplocalonifc(ipifc, np->target);
|
||||
if(lifc && lifc->tentative)
|
||||
refresh = 0;
|
||||
arpenter(icmp->f, V6, np->target, np->lnaddr, 8*np->olen-2, refresh);
|
||||
if(lifc != nil && lifc->tentative)
|
||||
arpenter(icmp->f, V6, np->target, np->lnaddr, 8*np->olen-2, np->target, 0);
|
||||
else if(ipv6local(ipifc, lsrc, np->target))
|
||||
arpenter(icmp->f, V6, np->target, np->lnaddr, 8*np->olen-2, lsrc, 1);
|
||||
freeblist(bp);
|
||||
break;
|
||||
|
||||
|
@ -846,7 +841,7 @@ raise:
|
|||
freeblist(bp);
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
icmpstats6(Proto *icmp6, char *buf, int len)
|
||||
{
|
||||
Icmppriv6 *priv;
|
||||
|
@ -872,6 +867,14 @@ extern char* icmpannounce(Conv *c, char **argv, int argc);
|
|||
extern char* icmpconnect(Conv *c, char **argv, int argc);
|
||||
extern void icmpclose(Conv *c);
|
||||
|
||||
static void
|
||||
icmpclose6(Conv *c)
|
||||
{
|
||||
Icmpcb6 *icb = (Icmpcb6*)c->ptcl;
|
||||
icb->headers = 0;
|
||||
icmpclose(c);
|
||||
}
|
||||
|
||||
void
|
||||
icmp6init(Fs *fs)
|
||||
{
|
||||
|
@ -883,7 +886,7 @@ icmp6init(Fs *fs)
|
|||
icmp6->announce = icmpannounce;
|
||||
icmp6->state = icmpstate;
|
||||
icmp6->create = icmpcreate6;
|
||||
icmp6->close = icmpclose;
|
||||
icmp6->close = icmpclose6;
|
||||
icmp6->rcv = icmpiput6;
|
||||
icmp6->stats = icmpstats6;
|
||||
icmp6->ctl = icmpctl6;
|
||||
|
|
|
@ -124,7 +124,7 @@ ipoput4(Fs *f, Block *bp, int gating, int ttl, int tos, Routehint *rh)
|
|||
Block *xp, *nb;
|
||||
Ip4hdr *eh, *feh;
|
||||
int lid, len, seglen, chunk, dlen, blklen, offset, medialen;
|
||||
Route *r, *sr;
|
||||
Route *r;
|
||||
IP *ip;
|
||||
int rv = 0;
|
||||
|
||||
|
@ -154,24 +154,16 @@ ipoput4(Fs *f, Block *bp, int gating, int ttl, int tos, Routehint *rh)
|
|||
goto free;
|
||||
}
|
||||
|
||||
r = v4lookup(f, eh->dst, rh);
|
||||
if(r == nil){
|
||||
r = v4lookup(f, eh->dst, eh->src, rh);
|
||||
if(r == nil || (ifc = r->ifc) == nil){
|
||||
ip->stats[OutNoRoutes]++;
|
||||
netlog(f, Logip, "no interface %V\n", eh->dst);
|
||||
netlog(f, Logip, "no interface %V -> %V\n", eh->src, eh->dst);
|
||||
rv = -1;
|
||||
goto free;
|
||||
}
|
||||
|
||||
ifc = r->ifc;
|
||||
if(r->type & (Rifc|Runi))
|
||||
if(r->type & (Rifc|Runi|Rbcast|Rmulti))
|
||||
gate = eh->dst;
|
||||
else
|
||||
if(r->type & (Rbcast|Rmulti)) {
|
||||
gate = eh->dst;
|
||||
sr = v4lookup(f, eh->src, nil);
|
||||
if(sr != nil && (sr->type & Runi))
|
||||
ifc = sr->ifc;
|
||||
}
|
||||
else
|
||||
gate = r->v4.gate;
|
||||
|
||||
|
@ -380,7 +372,7 @@ ipiput4(Fs *f, Ipifc *ifc, Block *bp)
|
|||
|
||||
/* don't forward to source's network */
|
||||
rh.r = nil;
|
||||
r = v4lookup(f, h->dst, &rh);
|
||||
r = v4lookup(f, h->dst, h->src, &rh);
|
||||
if(r == nil || r->ifc == ifc){
|
||||
ip->stats[OutDiscards]++;
|
||||
freeblist(bp);
|
||||
|
|
|
@ -39,7 +39,7 @@ enum
|
|||
Maxproto= 20,
|
||||
Maxincall= 10,
|
||||
Nchans= 1024,
|
||||
MAClen= 16, /* longest mac address */
|
||||
MAClen= 8, /* longest mac address */
|
||||
|
||||
MAXTTL= 255,
|
||||
DFLTTOS= 0,
|
||||
|
@ -242,18 +242,8 @@ struct Medium
|
|||
/* process packets written to 'data' */
|
||||
void (*pktin)(Fs *f, Ipifc *ifc, Block *bp);
|
||||
|
||||
/* routes for router boards */
|
||||
void (*addroute)(Ipifc *ifc, int, uchar*, uchar*, uchar*, int);
|
||||
void (*remroute)(Ipifc *ifc, int, uchar*, uchar*);
|
||||
void (*flushroutes)(Ipifc *ifc);
|
||||
|
||||
/* for routing multicast groups */
|
||||
void (*joinmulti)(Ipifc *ifc, uchar *a, uchar *ia);
|
||||
void (*leavemulti)(Ipifc *ifc, uchar *a, uchar *ia);
|
||||
|
||||
/* address resolution */
|
||||
void (*ares)(Fs*, int, uchar*, uchar*, int, int); /* resolve */
|
||||
void (*areg)(Ipifc*, uchar*); /* register */
|
||||
void (*areg)(Fs *f, Ipifc *ifc, uchar *ip, uchar *proxy); /* register */
|
||||
|
||||
/* v6 address generation */
|
||||
void (*pref2addr)(uchar *pref, uchar *ea);
|
||||
|
@ -268,6 +258,7 @@ struct Iplifc
|
|||
uchar mask[IPaddrlen];
|
||||
uchar remote[IPaddrlen];
|
||||
uchar net[IPaddrlen];
|
||||
uchar type; /* ruoute type */
|
||||
uchar tentative; /* =1 => v6 dup disc on, =0 => confirmed unique */
|
||||
uchar onlink; /* =1 => onlink, =0 offlink. */
|
||||
uchar autoflag; /* v6 autonomous flag */
|
||||
|
@ -509,13 +500,11 @@ void ifclogclose(Fs*, Chan*);
|
|||
* iproute.c
|
||||
*/
|
||||
typedef struct RouteTree RouteTree;
|
||||
typedef struct Routewalk Routewalk;
|
||||
typedef struct V4route V4route;
|
||||
typedef struct V6route V6route;
|
||||
|
||||
enum
|
||||
{
|
||||
|
||||
/* type bits */
|
||||
Rv4= (1<<0), /* this is a version 4 route */
|
||||
Rifc= (1<<1), /* this route is a directly connected interface */
|
||||
|
@ -524,27 +513,18 @@ enum
|
|||
Rbcast= (1<<4), /* a broadcast self address */
|
||||
Rmulti= (1<<5), /* a multicast self address */
|
||||
Rproxy= (1<<6), /* this route should be proxied */
|
||||
};
|
||||
|
||||
struct Routewalk
|
||||
{
|
||||
int o;
|
||||
int h;
|
||||
char* p;
|
||||
char* e;
|
||||
void* state;
|
||||
void (*walk)(Route*, Routewalk*);
|
||||
Rsrc= (1<<7), /* source specific route */
|
||||
};
|
||||
|
||||
struct RouteTree
|
||||
{
|
||||
Route* right;
|
||||
Route* left;
|
||||
Route* mid;
|
||||
Route *mid;
|
||||
Route *left;
|
||||
Route *right;
|
||||
Ipifc *ifc;
|
||||
uchar ifcid; /* must match ifc->id */
|
||||
uchar depth;
|
||||
uchar type;
|
||||
uchar ifcid; /* must match ifc->id */
|
||||
Ipifc *ifc;
|
||||
char tag[4];
|
||||
int ref;
|
||||
};
|
||||
|
@ -553,6 +533,10 @@ struct V4route
|
|||
{
|
||||
ulong address;
|
||||
ulong endaddress;
|
||||
|
||||
ulong source;
|
||||
ulong endsource;
|
||||
|
||||
uchar gate[IPv4addrlen];
|
||||
};
|
||||
|
||||
|
@ -560,6 +544,10 @@ struct V6route
|
|||
{
|
||||
ulong address[IPllen];
|
||||
ulong endaddress[IPllen];
|
||||
|
||||
ulong source[IPllen];
|
||||
ulong endsource[IPllen];
|
||||
|
||||
uchar gate[IPaddrlen];
|
||||
};
|
||||
|
||||
|
@ -572,17 +560,14 @@ struct Route
|
|||
V4route v4;
|
||||
};
|
||||
};
|
||||
extern void v4addroute(Fs *f, char *tag, uchar *a, uchar *mask, uchar *gate, int type);
|
||||
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, Routehint *h);
|
||||
extern Route* v6lookup(Fs *f, uchar *a, Routehint *h);
|
||||
|
||||
extern void addroute(Fs *f, uchar *a, uchar *mask, uchar *s, uchar *smask, uchar *gate, int type, Ipifc *ifc, char *tag);
|
||||
extern void remroute(Fs *f, uchar *a, uchar *mask, uchar *s, uchar *smask, uchar *gate, int type, Ipifc *ifc, char *tag);
|
||||
extern Route* v4lookup(Fs *f, uchar *a, uchar *s, Routehint *h);
|
||||
extern Route* v6lookup(Fs *f, uchar *a, uchar *s, Routehint *h);
|
||||
extern long routeread(Fs *f, char*, ulong, int);
|
||||
extern long routewrite(Fs *f, Chan*, char*, int);
|
||||
extern void routetype(int, char*);
|
||||
extern void ipwalkroutes(Fs*, Routewalk*);
|
||||
extern void convroute(Route*, uchar*, uchar*, uchar*, char*, int*);
|
||||
extern void routetype(int type, char p[8]);
|
||||
|
||||
/*
|
||||
* devip.c
|
||||
|
@ -607,7 +592,6 @@ struct Arpent
|
|||
{
|
||||
uchar ip[IPaddrlen];
|
||||
uchar mac[MAClen];
|
||||
Medium *type; /* media type */
|
||||
Arpent* hash;
|
||||
Block* hold;
|
||||
Block* last;
|
||||
|
@ -627,7 +611,7 @@ extern int arpwrite(Fs*, char*, int);
|
|||
extern Arpent* arpget(Arp*, Block *bp, int version, Ipifc *ifc, uchar *ip, uchar *h);
|
||||
extern void arprelease(Arp*, Arpent *a);
|
||||
extern Block* arpresolve(Arp*, Arpent *a, Medium *type, uchar *mac);
|
||||
extern void arpenter(Fs*, int version, uchar *ip, uchar *mac, int len, int norefresh);
|
||||
extern int arpenter(Fs*, int version, uchar *ip, uchar *mac, int n, uchar *src, int norefresh);
|
||||
extern void ndpsendsol(Fs*, Ipifc*, Arpent*);
|
||||
|
||||
/*
|
||||
|
@ -674,21 +658,16 @@ extern Medium* ipfindmedium(char *name);
|
|||
extern void addipmedium(Medium *med);
|
||||
extern int ipforme(Fs*, uchar *addr);
|
||||
extern int iptentative(Fs*, uchar *addr);
|
||||
extern int ipisbm(uchar *);
|
||||
extern int ipismulticast(uchar *);
|
||||
extern Ipifc* findipifc(Fs*, uchar *remote, int type);
|
||||
extern int ipisbm(uchar *ip);
|
||||
extern int ipismulticast(uchar *ip);
|
||||
extern Ipifc* findipifc(Fs*, uchar *local, uchar *remote, int type);
|
||||
extern Ipifc* findipifcstr(Fs *f, char *s);
|
||||
extern void findlocalip(Fs*, uchar *local, uchar *remote);
|
||||
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 Iplifc* ipremoteonifc(Ipifc *ifc, uchar *ip);
|
||||
extern int ipproxyifc(Fs *f, Ipifc *ifc, uchar *ip);
|
||||
extern int ipismulticast(uchar *ip);
|
||||
extern int ipisbooting(void);
|
||||
extern int ipifccheckin(Ipifc *ifc, Medium *med);
|
||||
extern void ipifccheckout(Ipifc *ifc);
|
||||
extern int ipifcgrab(Ipifc *ifc);
|
||||
extern void ipifcaddroute(Fs*, int, uchar*, uchar*, uchar*, int);
|
||||
extern void ipifcremroute(Fs*, int, uchar*, uchar*);
|
||||
extern void ipifcremmulti(Conv *c, uchar *ma, uchar *ia);
|
||||
extern void ipifcaddmulti(Conv *c, uchar *ma, uchar *ia);
|
||||
extern char* ipifcrem(Ipifc *ifc, char **argv, int argc);
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -38,7 +38,7 @@ ipoput6(Fs *f, Block *bp, int gating, int ttl, int tos, Routehint *rh)
|
|||
IP *ip;
|
||||
Ip6hdr *eh;
|
||||
Ipifc *ifc;
|
||||
Route *r, *sr;
|
||||
Route *r;
|
||||
|
||||
ip = f->ip;
|
||||
|
||||
|
@ -74,23 +74,16 @@ ipoput6(Fs *f, Block *bp, int gating, int ttl, int tos, Routehint *rh)
|
|||
goto free;
|
||||
}
|
||||
|
||||
r = v6lookup(f, eh->dst, rh);
|
||||
if(r == nil){
|
||||
r = v6lookup(f, eh->dst, eh->src, rh);
|
||||
if(r == nil || (r->type & Rv4) != 0 || (ifc = r->ifc) == nil){
|
||||
ip->stats[OutNoRoutes]++;
|
||||
netlog(f, Logip, "no interface %I\n", eh->dst);
|
||||
netlog(f, Logip, "no interface %I -> %I\n", eh->src, eh->dst);
|
||||
rv = -1;
|
||||
goto free;
|
||||
}
|
||||
|
||||
ifc = r->ifc;
|
||||
if(r->type & (Rifc|Runi))
|
||||
if(r->type & (Rifc|Runi|Rbcast|Rmulti))
|
||||
gate = eh->dst;
|
||||
else if(r->type & (Rbcast|Rmulti)) {
|
||||
gate = eh->dst;
|
||||
sr = v6lookup(f, eh->src, nil);
|
||||
if(sr && (sr->type & Runi))
|
||||
ifc = sr->ifc;
|
||||
}
|
||||
else
|
||||
gate = r->v6.gate;
|
||||
|
||||
|
@ -226,7 +219,6 @@ ipiput6(Fs *f, Ipifc *ifc, Block *bp)
|
|||
{
|
||||
int hl, hop, tos, notforme, tentative;
|
||||
uchar proto;
|
||||
uchar v6dst[IPaddrlen];
|
||||
IP *ip;
|
||||
Ip6hdr *h;
|
||||
Proto *p;
|
||||
|
@ -251,10 +243,8 @@ ipiput6(Fs *f, Ipifc *ifc, Block *bp)
|
|||
}
|
||||
|
||||
h = (Ip6hdr *)bp->rp;
|
||||
|
||||
memmove(&v6dst[0], &h->dst[0], IPaddrlen);
|
||||
notforme = ipforme(f, v6dst) == 0;
|
||||
tentative = iptentative(f, v6dst);
|
||||
notforme = ipforme(f, h->dst) == 0;
|
||||
tentative = iptentative(f, h->dst);
|
||||
|
||||
if(tentative && h->proto != ICMPv6) {
|
||||
print("tentative addr, drop\n");
|
||||
|
@ -290,8 +280,8 @@ ipiput6(Fs *f, Ipifc *ifc, Block *bp)
|
|||
|
||||
/* don't forward to source's network */
|
||||
rh.r = nil;
|
||||
r = v6lookup(f, h->dst, &rh);
|
||||
if(r == nil || r->ifc == ifc){
|
||||
r = v6lookup(f, h->dst, h->src, &rh);
|
||||
if(r == nil || (r->type & Rv4) != 0 || r->ifc == ifc){
|
||||
ip->stats[OutDiscards]++;
|
||||
freeblist(bp);
|
||||
return;
|
||||
|
|
|
@ -564,10 +564,10 @@ rudpiput(Proto *rudp, Ipifc *ifc, Block *bp)
|
|||
c->rport = rport;
|
||||
|
||||
/* reply with the same ip address (if not broadcast) */
|
||||
if(ipforme(f, laddr) == Runi)
|
||||
ipmove(c->laddr, laddr);
|
||||
else
|
||||
if(ipforme(f, laddr) != Runi)
|
||||
ipv6local(ifc, c->laddr, c->raddr);
|
||||
else
|
||||
ipmove(c->laddr, laddr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -864,8 +864,7 @@ tcpmtu(Route *r, int version, uint *scale)
|
|||
* otherwise, we use the default MSS which assumes a
|
||||
* safe minimum MTU of 1280 bytes for V6.
|
||||
*/
|
||||
if(r != nil){
|
||||
ifc = r->ifc;
|
||||
if(r != nil && (ifc = r->ifc) != nil){
|
||||
mtu = ifc->maxtu - ifc->m->hsize;
|
||||
if(version == V4)
|
||||
return mtu - (TCP4_PKT + TCP4_HDRSIZE);
|
||||
|
@ -1314,7 +1313,7 @@ tcpsndsyn(Conv *s, Tcpctl *tcb)
|
|||
tcb->sndsyntime = NOW;
|
||||
|
||||
/* set desired mss and scale */
|
||||
tcb->mss = tcpmtu(v6lookup(s->p->f, s->raddr, s), s->ipversion, &tcb->scale);
|
||||
tcb->mss = tcpmtu(v6lookup(s->p->f, s->raddr, s->laddr, s), s->ipversion, &tcb->scale);
|
||||
tpriv = s->p->priv;
|
||||
tpriv->stats[Mss] = tcb->mss;
|
||||
}
|
||||
|
@ -1492,7 +1491,7 @@ sndsynack(Proto *tcp, Limbo *lp)
|
|||
seg.ack = lp->irs+1;
|
||||
seg.flags = SYN|ACK;
|
||||
seg.urg = 0;
|
||||
seg.mss = tcpmtu(v6lookup(tcp->f, lp->raddr, nil), lp->version, &scale);
|
||||
seg.mss = tcpmtu(v6lookup(tcp->f, lp->raddr, lp->laddr, nil), lp->version, &scale);
|
||||
seg.wnd = QMAX;
|
||||
|
||||
/* if the other side set scale, we should too */
|
||||
|
@ -1768,7 +1767,7 @@ tcpincoming(Conv *s, Tcp *segp, uchar *src, uchar *dst, uchar version)
|
|||
tcb->flags |= SYNACK;
|
||||
|
||||
/* set desired mss and scale */
|
||||
tcb->mss = tcpmtu(v6lookup(s->p->f, src, s), version, &tcb->scale);
|
||||
tcb->mss = tcpmtu(v6lookup(s->p->f, src, dst, s), version, &tcb->scale);
|
||||
|
||||
/* our sending max segment size cannot be bigger than what he asked for */
|
||||
if(lp->mss != 0 && lp->mss < tcb->mss)
|
||||
|
|
Loading…
Reference in a new issue