devip: cache arp entry in Routehint
Instead of having to do an arp hash table lookup for each outgoing ip packet, forward the Routehint pointer to the medium's bwrite() function and let it cache the arp entry pointer. This avoids route and arp hash table lookups for tcp, il and connection oriented udp. It also allows us to avoid multiple route and arp table lookups for the retransmits once an arp/neighbour solicitation response arrives.
This commit is contained in:
parent
d280f411f6
commit
1a6324970d
|
@ -19,6 +19,8 @@ enum
|
||||||
|
|
||||||
AOK = 1,
|
AOK = 1,
|
||||||
AWAIT = 2,
|
AWAIT = 2,
|
||||||
|
|
||||||
|
MAXAGE_TIMER = 15*60*1000,
|
||||||
};
|
};
|
||||||
|
|
||||||
char *arpstate[] =
|
char *arpstate[] =
|
||||||
|
@ -182,7 +184,7 @@ arplookup(Arp *arp, Ipifc *ifc, uchar *ip)
|
||||||
* waiting for ip->mac to be resolved.
|
* waiting for ip->mac to be resolved.
|
||||||
*/
|
*/
|
||||||
Arpent*
|
Arpent*
|
||||||
arpget(Arp *arp, Block *bp, int version, Ipifc *ifc, uchar *ip, uchar *mac)
|
arpget(Arp *arp, Block *bp, int version, Ipifc *ifc, uchar *ip, uchar *mac, Routehint *rh)
|
||||||
{
|
{
|
||||||
uchar v6ip[IPaddrlen];
|
uchar v6ip[IPaddrlen];
|
||||||
Arpent *a;
|
Arpent *a;
|
||||||
|
@ -191,15 +193,32 @@ arpget(Arp *arp, Block *bp, int version, Ipifc *ifc, uchar *ip, uchar *mac)
|
||||||
v4tov6(v6ip, ip);
|
v4tov6(v6ip, ip);
|
||||||
ip = v6ip;
|
ip = v6ip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(rh != nil
|
||||||
|
&& (a = rh->a) != nil
|
||||||
|
&& a->state == AOK
|
||||||
|
&& a->ifc == ifc
|
||||||
|
&& a->ifcid == ifc->ifcid
|
||||||
|
&& ipcmp(ip, a->ip) == 0){
|
||||||
|
memmove(mac, a->mac, ifc->m->maclen);
|
||||||
|
a->utime = NOW;
|
||||||
|
if(a->utime - a->ctime < MAXAGE_TIMER)
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
rlock(arp);
|
rlock(arp);
|
||||||
if((a = arplookup(arp, ifc, ip)) != nil && a->state == AOK){
|
if((a = arplookup(arp, ifc, ip)) != nil && a->state == AOK){
|
||||||
memmove(mac, a->mac, ifc->m->maclen);
|
memmove(mac, a->mac, ifc->m->maclen);
|
||||||
a->utime = NOW;
|
a->utime = NOW;
|
||||||
if(a->utime - a->ctime < 15*60*1000){
|
if(a->utime - a->ctime < MAXAGE_TIMER){
|
||||||
|
if(rh != nil)
|
||||||
|
rh->a = a;
|
||||||
runlock(arp);
|
runlock(arp);
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(rh != nil)
|
||||||
|
rh->a = nil;
|
||||||
runlock(arp);
|
runlock(arp);
|
||||||
wlock(arp);
|
wlock(arp);
|
||||||
if((a = arplookup(arp, ifc, ip)) == nil)
|
if((a = arplookup(arp, ifc, ip)) == nil)
|
||||||
|
@ -269,11 +288,11 @@ arprelease(Arp *arp, Arpent*)
|
||||||
* called with arp locked
|
* called with arp locked
|
||||||
*/
|
*/
|
||||||
Block*
|
Block*
|
||||||
arpresolve(Arp *arp, Arpent *a, Medium *type, uchar *mac)
|
arpresolve(Arp *arp, Arpent *a, uchar *mac, Routehint *rh)
|
||||||
{
|
{
|
||||||
Block *bp;
|
Block *bp;
|
||||||
|
|
||||||
memmove(a->mac, mac, type->maclen);
|
memmove(a->mac, mac, a->ifc->m->maclen);
|
||||||
if(a->state == AWAIT) {
|
if(a->state == AWAIT) {
|
||||||
rxmtunchain(arp, a);
|
rxmtunchain(arp, a);
|
||||||
a->rxtsrem = 0;
|
a->rxtsrem = 0;
|
||||||
|
@ -282,6 +301,8 @@ arpresolve(Arp *arp, Arpent *a, Medium *type, uchar *mac)
|
||||||
a->hold = a->last = nil;
|
a->hold = a->last = nil;
|
||||||
a->ctime = a->utime = NOW;
|
a->ctime = a->utime = NOW;
|
||||||
a->state = AOK;
|
a->state = AOK;
|
||||||
|
if(rh != nil)
|
||||||
|
rh->a = a;
|
||||||
wunlock(arp);
|
wunlock(arp);
|
||||||
|
|
||||||
return bp;
|
return bp;
|
||||||
|
@ -290,6 +311,7 @@ arpresolve(Arp *arp, Arpent *a, Medium *type, uchar *mac)
|
||||||
int
|
int
|
||||||
arpenter(Fs *fs, int version, uchar *ip, uchar *mac, int n, uchar *ia, Ipifc *ifc, int refresh)
|
arpenter(Fs *fs, int version, uchar *ip, uchar *mac, int n, uchar *ia, Ipifc *ifc, int refresh)
|
||||||
{
|
{
|
||||||
|
Routehint rh;
|
||||||
uchar v6ip[IPaddrlen];
|
uchar v6ip[IPaddrlen];
|
||||||
Block *bp, *next;
|
Block *bp, *next;
|
||||||
Arpent *a;
|
Arpent *a;
|
||||||
|
@ -299,14 +321,16 @@ arpenter(Fs *fs, int version, uchar *ip, uchar *mac, int n, uchar *ia, Ipifc *if
|
||||||
if(ifc->m == nil || ifc->m->maclen != n || ifc->m->maclen == 0)
|
if(ifc->m == nil || ifc->m->maclen != n || ifc->m->maclen == 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
rh.r = nil;
|
||||||
|
rh.a = nil;
|
||||||
switch(version){
|
switch(version){
|
||||||
case V4:
|
case V4:
|
||||||
r = v4lookup(fs, ip, ia, nil);
|
r = v4lookup(fs, ip, ia, &rh);
|
||||||
v4tov6(v6ip, ip);
|
v4tov6(v6ip, ip);
|
||||||
ip = v6ip;
|
ip = v6ip;
|
||||||
break;
|
break;
|
||||||
case V6:
|
case V6:
|
||||||
r = v6lookup(fs, ip, ia, nil);
|
r = v6lookup(fs, ip, ia, &rh);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
panic("arpenter: version %d", version);
|
panic("arpenter: version %d", version);
|
||||||
|
@ -326,9 +350,9 @@ arpenter(Fs *fs, int version, uchar *ip, uchar *mac, int n, uchar *ia, Ipifc *if
|
||||||
}
|
}
|
||||||
a = newarpent(arp, ip, ifc);
|
a = newarpent(arp, ip, ifc);
|
||||||
}
|
}
|
||||||
|
bp = arpresolve(arp, a, mac, &rh); /* unlocks arp */
|
||||||
if(version == V4)
|
if(version == V4)
|
||||||
ip += IPv4off;
|
ip += IPv4off;
|
||||||
bp = arpresolve(arp, a, ifc->m, mac); /* unlocks arp */
|
|
||||||
for(; bp != nil; bp = next){
|
for(; bp != nil; bp = next){
|
||||||
next = bp->list;
|
next = bp->list;
|
||||||
bp->list = nil;
|
bp->list = nil;
|
||||||
|
@ -336,7 +360,7 @@ arpenter(Fs *fs, int version, uchar *ip, uchar *mac, int n, uchar *ia, Ipifc *if
|
||||||
freeblistchain(next);
|
freeblistchain(next);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ipifcoput(ifc, bp, version, ip);
|
ipifcoput(ifc, bp, version, ip, &rh);
|
||||||
poperror();
|
poperror();
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -496,8 +520,9 @@ arpread(Arp *arp, char *s, ulong offset, int len)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ndpsendsol(Fs *f, Ipifc *ifc, Arpent *a)
|
ndpsendsol(Fs *f, Arpent *a)
|
||||||
{
|
{
|
||||||
|
Ipifc *ifc = a->ifc;
|
||||||
uchar targ[IPaddrlen], src[IPaddrlen];
|
uchar targ[IPaddrlen], src[IPaddrlen];
|
||||||
|
|
||||||
if(a->rxtsrem == 0)
|
if(a->rxtsrem == 0)
|
||||||
|
@ -538,7 +563,7 @@ rxmt(Arp *arp)
|
||||||
while((a = arp->rxmt[0]) != nil && NOW - a->ctime > 3*RETRANS_TIMER/4){
|
while((a = arp->rxmt[0]) != nil && NOW - a->ctime > 3*RETRANS_TIMER/4){
|
||||||
if(a->rxtsrem > 0 && (ifc = a->ifc) != nil && canrlock(ifc)){
|
if(a->rxtsrem > 0 && (ifc = a->ifc) != nil && canrlock(ifc)){
|
||||||
if(a->ifcid == ifc->ifcid){
|
if(a->ifcid == ifc->ifcid){
|
||||||
ndpsendsol(arp->f, ifc, a); /* unlocks arp */
|
ndpsendsol(arp->f, a); /* unlocks arp */
|
||||||
runlock(ifc);
|
runlock(ifc);
|
||||||
|
|
||||||
wlock(arp);
|
wlock(arp);
|
||||||
|
|
|
@ -1332,6 +1332,7 @@ retry:
|
||||||
c->state = Idle;
|
c->state = Idle;
|
||||||
ipmove(c->laddr, IPnoaddr);
|
ipmove(c->laddr, IPnoaddr);
|
||||||
ipmove(c->raddr, IPnoaddr);
|
ipmove(c->raddr, IPnoaddr);
|
||||||
|
c->a = nil;
|
||||||
c->r = nil;
|
c->r = nil;
|
||||||
c->rgen = 0;
|
c->rgen = 0;
|
||||||
c->lport = 0;
|
c->lport = 0;
|
||||||
|
|
|
@ -21,12 +21,12 @@ static void etherread4(void *a);
|
||||||
static void etherread6(void *a);
|
static void etherread6(void *a);
|
||||||
static void etherbind(Ipifc *ifc, int argc, char **argv);
|
static void etherbind(Ipifc *ifc, int argc, char **argv);
|
||||||
static void etherunbind(Ipifc *ifc);
|
static void etherunbind(Ipifc *ifc);
|
||||||
static void etherbwrite(Ipifc *ifc, Block *bp, int version, uchar *ip);
|
static void etherbwrite(Ipifc *ifc, Block *bp, int version, uchar *ip, Routehint *rh);
|
||||||
static void etheraddmulti(Ipifc *ifc, uchar *a, uchar *ia);
|
static void etheraddmulti(Ipifc *ifc, uchar *a, uchar *ia);
|
||||||
static void etherremmulti(Ipifc *ifc, uchar *a, uchar *ia);
|
static void etherremmulti(Ipifc *ifc, uchar *a, uchar *ia);
|
||||||
static void etherareg(Fs *f, Ipifc *ifc, Iplifc *lifc, uchar *ip);
|
static void etherareg(Fs *f, Ipifc *ifc, Iplifc *lifc, uchar *ip);
|
||||||
static Block* multicastarp(Fs *f, Arpent *a, Medium*, uchar *mac);
|
static Block* multicastarp(Fs *f, Arpent *a, uchar *mac, Routehint *rh);
|
||||||
static void sendarpreq(Ipifc *ifc, Arpent *a);
|
static void sendarpreq(Fs *f, Arpent *a);
|
||||||
static int multicastea(uchar *ea, uchar *ip);
|
static int multicastea(uchar *ea, uchar *ip);
|
||||||
static void recvarpproc(void*);
|
static void recvarpproc(void*);
|
||||||
static void etherpref2addr(uchar *pref, uchar *ea);
|
static void etherpref2addr(uchar *pref, uchar *ea);
|
||||||
|
@ -253,7 +253,7 @@ etherunbind(Ipifc *ifc)
|
||||||
* called by ipoput with a single block to write with ifc rlock'd
|
* called by ipoput with a single block to write with ifc rlock'd
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
etherbwrite(Ipifc *ifc, Block *bp, int version, uchar *ip)
|
etherbwrite(Ipifc *ifc, Block *bp, int version, uchar *ip, Routehint *rh)
|
||||||
{
|
{
|
||||||
Etherhdr *eh;
|
Etherhdr *eh;
|
||||||
Arpent *a;
|
Arpent *a;
|
||||||
|
@ -261,22 +261,22 @@ etherbwrite(Ipifc *ifc, Block *bp, int version, uchar *ip)
|
||||||
Etherrock *er = ifc->arg;
|
Etherrock *er = ifc->arg;
|
||||||
|
|
||||||
/* get mac address of destination */
|
/* get mac address of destination */
|
||||||
a = arpget(er->f->arp, bp, version, ifc, ip, mac);
|
a = arpget(er->f->arp, bp, version, ifc, ip, mac, rh);
|
||||||
if(a != nil){
|
if(a != nil){
|
||||||
/* check for broadcast or multicast */
|
/* check for broadcast or multicast */
|
||||||
bp = multicastarp(er->f, a, ifc->m, mac);
|
bp = multicastarp(er->f, a, mac, rh);
|
||||||
if(bp == nil){
|
if(bp == nil){
|
||||||
/* don't do anything if it's been less than a second since the last */
|
/* don't do anything if it's been less than a second since the last */
|
||||||
if(a->utime - a->ctime < RETRANS_TIMER){
|
if(a->utime - a->ctime < RETRANS_TIMER){
|
||||||
arprelease(er->f->arp, a);
|
arprelease(er->f->arp, a); /* unlocks arp */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switch(version){
|
switch(version){
|
||||||
case V4:
|
case V4:
|
||||||
sendarpreq(ifc, a); /* unlocks arp */
|
sendarpreq(er->f, a); /* unlocks arp */
|
||||||
break;
|
break;
|
||||||
case V6:
|
case V6:
|
||||||
ndpsendsol(er->f, ifc, a); /* unlocks arp */
|
ndpsendsol(er->f, a); /* unlocks arp */
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
panic("etherbwrite: version %d", version);
|
panic("etherbwrite: version %d", version);
|
||||||
|
@ -440,16 +440,17 @@ etherremmulti(Ipifc *ifc, uchar *a, uchar *)
|
||||||
* (only v4, v6 uses the neighbor discovery, rfc1970)
|
* (only v4, v6 uses the neighbor discovery, rfc1970)
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
sendarpreq(Ipifc *ifc, Arpent *a)
|
sendarpreq(Fs *f, Arpent *a)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
Block *bp;
|
Block *bp;
|
||||||
Etherarp *e;
|
Etherarp *e;
|
||||||
|
Ipifc *ifc = a->ifc;
|
||||||
Etherrock *er = ifc->arg;
|
Etherrock *er = ifc->arg;
|
||||||
uchar targ[IPv4addrlen], src[IPv4addrlen];
|
uchar targ[IPv4addrlen], src[IPv4addrlen];
|
||||||
|
|
||||||
memmove(targ, a->ip+IPv4off, IPv4addrlen);
|
memmove(targ, a->ip+IPv4off, IPv4addrlen);
|
||||||
arpcontinue(er->f->arp, a);
|
arpcontinue(f->arp, a);
|
||||||
|
|
||||||
if(!ipv4local(ifc, src, 0, targ))
|
if(!ipv4local(ifc, src, 0, targ))
|
||||||
return;
|
return;
|
||||||
|
@ -668,19 +669,19 @@ multicastea(uchar *ea, uchar *ip)
|
||||||
* IP address.
|
* IP address.
|
||||||
*/
|
*/
|
||||||
static Block*
|
static Block*
|
||||||
multicastarp(Fs *f, Arpent *a, Medium *medium, uchar *mac)
|
multicastarp(Fs *f, Arpent *a, uchar *mac, Routehint *rh)
|
||||||
{
|
{
|
||||||
/* is it broadcast? */
|
/* is it broadcast? */
|
||||||
if(ipforme(f, a->ip) == Rbcast){
|
if(ipforme(f, a->ip) == Rbcast){
|
||||||
memset(mac, 0xff, medium->maclen);
|
memset(mac, 0xff, a->ifc->m->maclen);
|
||||||
return arpresolve(f->arp, a, medium, mac);
|
return arpresolve(f->arp, a, mac, rh);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if multicast, fill in mac */
|
/* if multicast, fill in mac */
|
||||||
switch(multicastea(mac, a->ip)){
|
switch(multicastea(mac, a->ip)){
|
||||||
case V4:
|
case V4:
|
||||||
case V6:
|
case V6:
|
||||||
return arpresolve(f->arp, a, medium, mac);
|
return arpresolve(f->arp, a, mac, rh);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* let arp take care of it */
|
/* let arp take care of it */
|
||||||
|
|
|
@ -153,7 +153,7 @@ ipoput4(Fs *f, Block *bp, int gating, int ttl, int tos, Routehint *rh)
|
||||||
eh->cksum[1] = 0;
|
eh->cksum[1] = 0;
|
||||||
hnputs(eh->cksum, ipcsum(&eh->vihl));
|
hnputs(eh->cksum, ipcsum(&eh->vihl));
|
||||||
|
|
||||||
ipifcoput(ifc, bp, V4, gate);
|
ipifcoput(ifc, bp, V4, gate, rh);
|
||||||
runlock(ifc);
|
runlock(ifc);
|
||||||
poperror();
|
poperror();
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -237,7 +237,7 @@ ipoput4(Fs *f, Block *bp, int gating, int ttl, int tos, Routehint *rh)
|
||||||
feh->cksum[1] = 0;
|
feh->cksum[1] = 0;
|
||||||
hnputs(feh->cksum, ipcsum(&feh->vihl));
|
hnputs(feh->cksum, ipcsum(&feh->vihl));
|
||||||
|
|
||||||
ipifcoput(ifc, nb, V4, gate);
|
ipifcoput(ifc, nb, V4, gate, rh);
|
||||||
ip->stats[FragCreates]++;
|
ip->stats[FragCreates]++;
|
||||||
}
|
}
|
||||||
ip->stats[FragOKs]++;
|
ip->stats[FragOKs]++;
|
||||||
|
@ -308,8 +308,8 @@ ipiput4(Fs *f, Ipifc *ifc, Block *bp)
|
||||||
/* route */
|
/* route */
|
||||||
v4tov6(v6dst, h->dst);
|
v4tov6(v6dst, h->dst);
|
||||||
if(!ipforme(f, v6dst)) {
|
if(!ipforme(f, v6dst)) {
|
||||||
Route *r;
|
|
||||||
Routehint rh;
|
Routehint rh;
|
||||||
|
Route *r;
|
||||||
Ipifc *nifc;
|
Ipifc *nifc;
|
||||||
|
|
||||||
if(!ip->iprouting)
|
if(!ip->iprouting)
|
||||||
|
@ -317,6 +317,7 @@ ipiput4(Fs *f, Ipifc *ifc, Block *bp)
|
||||||
|
|
||||||
/* don't forward to source's network */
|
/* don't forward to source's network */
|
||||||
rh.r = nil;
|
rh.r = nil;
|
||||||
|
rh.a = nil;
|
||||||
r = v4lookup(f, h->dst, h->src, &rh);
|
r = v4lookup(f, h->dst, h->src, &rh);
|
||||||
if(r == nil || (nifc = r->ifc) == nil
|
if(r == nil || (nifc = r->ifc) == nil
|
||||||
|| (nifc == ifc && !ifc->reflect)){
|
|| (nifc == ifc && !ifc->reflect)){
|
||||||
|
|
|
@ -168,6 +168,7 @@ struct Routehint
|
||||||
{
|
{
|
||||||
Route *r; /* last route used */
|
Route *r; /* last route used */
|
||||||
ulong rgen; /* routetable generation for *r */
|
ulong rgen; /* routetable generation for *r */
|
||||||
|
Arpent *a; /* last arp entry used */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -232,7 +233,7 @@ struct Medium
|
||||||
int maclen; /* mac address length */
|
int maclen; /* mac address length */
|
||||||
void (*bind)(Ipifc*, int, char**);
|
void (*bind)(Ipifc*, int, char**);
|
||||||
void (*unbind)(Ipifc*);
|
void (*unbind)(Ipifc*);
|
||||||
void (*bwrite)(Ipifc *ifc, Block *b, int version, uchar *ip);
|
void (*bwrite)(Ipifc *ifc, Block *b, int version, uchar *ip, Routehint *rh);
|
||||||
|
|
||||||
/* for arming interfaces to receive multicast */
|
/* for arming interfaces to receive multicast */
|
||||||
void (*addmulti)(Ipifc *ifc, uchar *a, uchar *ia);
|
void (*addmulti)(Ipifc *ifc, uchar *a, uchar *ia);
|
||||||
|
@ -565,8 +566,8 @@ struct Route
|
||||||
|
|
||||||
extern void addroute(Fs *f, uchar *a, uchar *mask, uchar *s, uchar *smask, uchar *gate, int type, Ipifc *ifc, char *tag);
|
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 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* v4lookup(Fs *f, uchar *a, uchar *s, Routehint *rh);
|
||||||
extern Route* v6lookup(Fs *f, uchar *a, uchar *s, Routehint *h);
|
extern Route* v6lookup(Fs *f, uchar *a, uchar *s, Routehint *rh);
|
||||||
extern Route* v4source(Fs *f, uchar *a, uchar *s);
|
extern Route* v4source(Fs *f, uchar *a, uchar *s);
|
||||||
extern Route* v6source(Fs *f, uchar *a, uchar *s);
|
extern Route* v6source(Fs *f, uchar *a, uchar *s);
|
||||||
extern long routeread(Fs *f, char*, ulong, int);
|
extern long routeread(Fs *f, char*, ulong, int);
|
||||||
|
@ -611,12 +612,12 @@ struct Arpent
|
||||||
extern void arpinit(Fs*);
|
extern void arpinit(Fs*);
|
||||||
extern int arpread(Arp*, char*, ulong, int);
|
extern int arpread(Arp*, char*, ulong, int);
|
||||||
extern int arpwrite(Fs*, char*, int);
|
extern int arpwrite(Fs*, char*, int);
|
||||||
extern Arpent* arpget(Arp*, Block *bp, int version, Ipifc *ifc, uchar *ip, uchar *h);
|
extern Arpent* arpget(Arp*, Block *bp, int version, Ipifc *ifc, uchar *ip, uchar *mac, Routehint *rh);
|
||||||
extern void arprelease(Arp*, Arpent *a);
|
extern void arprelease(Arp*, Arpent *a);
|
||||||
extern void arpcontinue(Arp*, Arpent *a);
|
extern void arpcontinue(Arp*, Arpent *a);
|
||||||
extern Block* arpresolve(Arp*, Arpent *a, Medium *type, uchar *mac);
|
extern Block* arpresolve(Arp*, Arpent *a, uchar *mac, Routehint *rh);
|
||||||
extern int arpenter(Fs*, int version, uchar *ip, uchar *mac, int n, uchar *ia, Ipifc *ifc, int refresh);
|
extern int arpenter(Fs*, int version, uchar *ip, uchar *mac, int n, uchar *ia, Ipifc *ifc, int refresh);
|
||||||
extern void ndpsendsol(Fs*, Ipifc*, Arpent*);
|
extern void ndpsendsol(Fs*, Arpent*);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ipaux.c
|
* ipaux.c
|
||||||
|
@ -661,7 +662,7 @@ extern Medium pktmedium;
|
||||||
*/
|
*/
|
||||||
extern Medium* ipfindmedium(char *name);
|
extern Medium* ipfindmedium(char *name);
|
||||||
extern void addipmedium(Medium *med);
|
extern void addipmedium(Medium *med);
|
||||||
extern void ipifcoput(Ipifc *ifc, Block *bp, int version, uchar *ip);
|
extern void ipifcoput(Ipifc *ifc, Block *bp, int version, uchar *ip, Routehint *rh);
|
||||||
extern int ipforme(Fs*, uchar *addr);
|
extern int ipforme(Fs*, uchar *addr);
|
||||||
extern int ipismulticast(uchar *ip);
|
extern int ipismulticast(uchar *ip);
|
||||||
extern Ipifc* findipifc(Fs*, uchar *local, uchar *remote, int type);
|
extern Ipifc* findipifc(Fs*, uchar *local, uchar *remote, int type);
|
||||||
|
|
|
@ -347,7 +347,7 @@ ipifcsetspeed(Ipifc *ifc, int speed)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ipifcoput(Ipifc *ifc, Block *bp, int version, uchar *ip)
|
ipifcoput(Ipifc *ifc, Block *bp, int version, uchar *ip, Routehint *rh)
|
||||||
{
|
{
|
||||||
if(ifc->speed){
|
if(ifc->speed){
|
||||||
ulong now = MACHP(0)->ticks;
|
ulong now = MACHP(0)->ticks;
|
||||||
|
@ -363,7 +363,7 @@ ipifcoput(Ipifc *ifc, Block *bp, int version, uchar *ip)
|
||||||
}
|
}
|
||||||
bp = concatblock(bp);
|
bp = concatblock(bp);
|
||||||
ifc->load += BLEN(bp);
|
ifc->load += BLEN(bp);
|
||||||
ifc->m->bwrite(ifc, bp, version, ip);
|
ifc->m->bwrite(ifc, bp, version, ip, rh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -99,7 +99,7 @@ ipoput6(Fs *f, Block *bp, int gating, int ttl, int tos, Routehint *rh)
|
||||||
medialen = ifc->maxtu - ifc->m->hsize;
|
medialen = ifc->maxtu - ifc->m->hsize;
|
||||||
if(len <= medialen) {
|
if(len <= medialen) {
|
||||||
hnputs(eh->ploadlen, len - IP6HDR);
|
hnputs(eh->ploadlen, len - IP6HDR);
|
||||||
ipifcoput(ifc, bp, V6, gate);
|
ipifcoput(ifc, bp, V6, gate, rh);
|
||||||
runlock(ifc);
|
runlock(ifc);
|
||||||
poperror();
|
poperror();
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -195,7 +195,7 @@ ipoput6(Fs *f, Block *bp, int gating, int ttl, int tos, Routehint *rh)
|
||||||
if(xp->rp == xp->wp)
|
if(xp->rp == xp->wp)
|
||||||
xp = xp->next;
|
xp = xp->next;
|
||||||
}
|
}
|
||||||
ipifcoput(ifc, nb, V6, gate);
|
ipifcoput(ifc, nb, V6, gate, rh);
|
||||||
ip->stats[FragCreates]++;
|
ip->stats[FragCreates]++;
|
||||||
}
|
}
|
||||||
ip->stats[FragOKs]++;
|
ip->stats[FragOKs]++;
|
||||||
|
@ -252,8 +252,8 @@ ipiput6(Fs *f, Ipifc *ifc, Block *bp)
|
||||||
|
|
||||||
/* route */
|
/* route */
|
||||||
if(!ipforme(f, h->dst)) {
|
if(!ipforme(f, h->dst)) {
|
||||||
Route *r;
|
|
||||||
Routehint rh;
|
Routehint rh;
|
||||||
|
Route *r;
|
||||||
Ipifc *nifc;
|
Ipifc *nifc;
|
||||||
|
|
||||||
if(!ip->iprouting)
|
if(!ip->iprouting)
|
||||||
|
@ -268,6 +268,7 @@ ipiput6(Fs *f, Ipifc *ifc, Block *bp)
|
||||||
|
|
||||||
/* don't forward to source's network */
|
/* don't forward to source's network */
|
||||||
rh.r = nil;
|
rh.r = nil;
|
||||||
|
rh.a = nil;
|
||||||
r = v6lookup(f, h->dst, h->src, &rh);
|
r = v6lookup(f, h->dst, h->src, &rh);
|
||||||
if(r == nil || (nifc = r->ifc) == nil || (r->type & Rv4) != 0
|
if(r == nil || (nifc = r->ifc) == nil || (r->type & Rv4) != 0
|
||||||
|| (nifc == ifc && !ifc->reflect)){
|
|| (nifc == ifc && !ifc->reflect)){
|
||||||
|
|
|
@ -71,7 +71,7 @@ loopbackunbind(Ipifc *ifc)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
loopbackbwrite(Ipifc *ifc, Block *bp, int, uchar*)
|
loopbackbwrite(Ipifc *ifc, Block *bp, int, uchar*, Routehint*)
|
||||||
{
|
{
|
||||||
LB *lb;
|
LB *lb;
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
static void netdevbind(Ipifc *ifc, int argc, char **argv);
|
static void netdevbind(Ipifc *ifc, int argc, char **argv);
|
||||||
static void netdevunbind(Ipifc *ifc);
|
static void netdevunbind(Ipifc *ifc);
|
||||||
static void netdevbwrite(Ipifc *ifc, Block *bp, int version, uchar *ip);
|
static void netdevbwrite(Ipifc *ifc, Block *bp, int version, uchar *ip, Routehint*);
|
||||||
static void netdevread(void *a);
|
static void netdevread(void *a);
|
||||||
|
|
||||||
typedef struct Netdevrock Netdevrock;
|
typedef struct Netdevrock Netdevrock;
|
||||||
|
@ -99,7 +99,7 @@ netdevunbind(Ipifc *ifc)
|
||||||
* called by ipoput with a single block to write
|
* called by ipoput with a single block to write
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
netdevbwrite(Ipifc *ifc, Block *bp, int, uchar*)
|
netdevbwrite(Ipifc *ifc, Block *bp, int, uchar*, Routehint*)
|
||||||
{
|
{
|
||||||
Netdevrock *er = ifc->arg;
|
Netdevrock *er = ifc->arg;
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ nullunbind(Ipifc*)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
nullbwrite(Ipifc*, Block *bp, int, uchar*)
|
nullbwrite(Ipifc*, Block *bp, int, uchar*, Routehint*)
|
||||||
{
|
{
|
||||||
freeb(bp);
|
freeb(bp);
|
||||||
error("nullbwrite");
|
error("nullbwrite");
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
static void pktbind(Ipifc*, int, char**);
|
static void pktbind(Ipifc*, int, char**);
|
||||||
static void pktunbind(Ipifc*);
|
static void pktunbind(Ipifc*);
|
||||||
static void pktbwrite(Ipifc*, Block*, int, uchar*);
|
static void pktbwrite(Ipifc*, Block*, int, uchar*, Routehint*);
|
||||||
static void pktin(Fs*, Ipifc*, Block*);
|
static void pktin(Fs*, Ipifc*, Block*);
|
||||||
|
|
||||||
Medium pktmedium =
|
Medium pktmedium =
|
||||||
|
@ -49,7 +49,7 @@ pktunbind(Ipifc*)
|
||||||
* called by ipoput with a single packet to write
|
* called by ipoput with a single packet to write
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
pktbwrite(Ipifc *ifc, Block *bp, int, uchar*)
|
pktbwrite(Ipifc *ifc, Block *bp, int, uchar*, Routehint*)
|
||||||
{
|
{
|
||||||
/* enqueue onto the conversation's rq */
|
/* enqueue onto the conversation's rq */
|
||||||
if(ifc->conv->snoopers.ref > 0)
|
if(ifc->conv->snoopers.ref > 0)
|
||||||
|
|
Loading…
Reference in a new issue