summaryrefslogtreecommitdiff
path: root/sys/src/9
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2022-12-13 22:23:01 +0000
committercinap_lenrek <cinap_lenrek@felloff.net>2022-12-13 22:23:01 +0000
commit074b691f16faba137ab9cb48471fc3160b33da40 (patch)
tree1fd8f9a2342185717d541655fc74347b5f570f56 /sys/src/9
parent5f42bde60275e9a0c3d317ee1e052e1aefdcdb19 (diff)
devip: tcpmssclamp() to minimum of source and destination interface MTU
We used to only clamp to the MTU of the destination interface, but this is wrong. We have to clamp to the minimum of both source and destination. For this, we change the gating argument type of ipoput4() and ipoput6() from int to Ipifc* to pass the source interface.
Diffstat (limited to 'sys/src/9')
-rw-r--r--sys/src/9/ip/esp.c6
-rw-r--r--sys/src/9/ip/gre.c14
-rw-r--r--sys/src/9/ip/icmp.c28
-rw-r--r--sys/src/9/ip/icmp6.c18
-rw-r--r--sys/src/9/ip/igmp.c4
-rw-r--r--sys/src/9/ip/il.c12
-rw-r--r--sys/src/9/ip/ip.c15
-rw-r--r--sys/src/9/ip/ip.h8
-rw-r--r--sys/src/9/ip/ipmux.c4
-rw-r--r--sys/src/9/ip/ipv6.c15
-rw-r--r--sys/src/9/ip/rudp.c12
-rw-r--r--sys/src/9/ip/tcp.c28
-rw-r--r--sys/src/9/ip/udp.c10
13 files changed, 90 insertions, 84 deletions
diff --git a/sys/src/9/ip/esp.c b/sys/src/9/ip/esp.c
index 1d8a86201..447254a1c 100644
--- a/sys/src/9/ip/esp.c
+++ b/sys/src/9/ip/esp.c
@@ -423,9 +423,9 @@ espkick(void *x)
qunlock(c);
/* print("esp: pass down: %uld\n", BLEN(bp)); */
if (vers.version == V4)
- ipoput4(c->p->f, bp, 0, c->ttl, c->tos, c);
+ ipoput4(c->p->f, bp, nil, c->ttl, c->tos, c);
else
- ipoput6(c->p->f, bp, 0, c->ttl, c->tos, c);
+ ipoput6(c->p->f, bp, nil, c->ttl, c->tos, c);
}
/*
@@ -574,7 +574,7 @@ espctl(Conv *c, char **f, int n)
/* called from icmp(v6) for unreachable hosts, time exceeded, etc. */
void
-espadvise(Proto *esp, Block *bp, char *msg)
+espadvise(Proto *esp, Block *bp, Ipifc *, char *msg)
{
Conv *c;
Versdep vers;
diff --git a/sys/src/9/ip/gre.c b/sys/src/9/ip/gre.c
index c18153472..80c3fb8dd 100644
--- a/sys/src/9/ip/gre.c
+++ b/sys/src/9/ip/gre.c
@@ -435,7 +435,7 @@ restart:
memmove(gre->src, grec->coa, sizeof gre->dst);
memmove(gre->dst, grec->south, sizeof gre->dst);
- ipoput4(c->p->f, copyblock(bp, BLEN(bp)), 0, gre->ttl - 1, gre->tos, nil);
+ ipoput4(c->p->f, copyblock(bp, BLEN(bp)), nil, gre->ttl - 1, gre->tos, nil);
grepdout++;
grebdout += BLEN(bp);
@@ -506,7 +506,7 @@ greuplink(Conv *c, Block *bp)
if(grec->ulsusp)
addring(&grec->ulbuffered, bp);
else{
- ipoput4(c->p->f, bp, 0, gre->ttl - 1, gre->tos, nil);
+ ipoput4(c->p->f, bp, nil, gre->ttl - 1, gre->tos, nil);
grepuout++;
grebuout += BLEN(bp);
}
@@ -777,7 +777,7 @@ grectldlresume(Conv *c, int, char **)
gre = (GREhdr *)bp->rp;
qunlock(&grec->lock);
- ipoput4(c->p->f, copyblock(bp, BLEN(bp)), 0, gre->ttl - 1, gre->tos, nil);
+ ipoput4(c->p->f, copyblock(bp, BLEN(bp)), nil, gre->ttl - 1, gre->tos, nil);
qlock(&grec->lock);
addring(&grec->dlpending, bp);
@@ -801,7 +801,7 @@ grectlulresume(Conv *c, int, char **)
gre = (GREhdr *)bp->rp;
qunlock(&grec->lock);
- ipoput4(c->p->f, bp, 0, gre->ttl - 1, gre->tos, nil);
+ ipoput4(c->p->f, bp, nil, gre->ttl - 1, gre->tos, nil);
qlock(&grec->lock);
}
grec->ulsusp = 0;
@@ -843,7 +843,7 @@ grectlforward(Conv *c, int, char **argv)
memmove(gre->dst, grec->south, sizeof gre->dst);
qunlock(&grec->lock);
- ipoput4(c->p->f, bp, 0, gre->ttl - 1, gre->tos, nil);
+ ipoput4(c->p->f, bp, nil, gre->ttl - 1, gre->tos, nil);
qlock(&grec->lock);
}
@@ -853,7 +853,7 @@ grectlforward(Conv *c, int, char **argv)
memmove(gre->dst, grec->south, sizeof gre->dst);
qunlock(&grec->lock);
- ipoput4(c->p->f, bp, 0, gre->ttl - 1, gre->tos, nil);
+ ipoput4(c->p->f, bp, nil, gre->ttl - 1, gre->tos, nil);
qlock(&grec->lock);
}
@@ -864,7 +864,7 @@ grectlforward(Conv *c, int, char **argv)
memmove(gre->dst, grec->south, sizeof gre->dst);
qunlock(&grec->lock);
- ipoput4(c->p->f, bp, 0, gre->ttl - 1, gre->tos, nil);
+ ipoput4(c->p->f, bp, nil, gre->ttl - 1, gre->tos, nil);
qlock(&grec->lock);
}
qunlock(&grec->lock);
diff --git a/sys/src/9/ip/icmp.c b/sys/src/9/ip/icmp.c
index 526540af3..c4168605b 100644
--- a/sys/src/9/ip/icmp.c
+++ b/sys/src/9/ip/icmp.c
@@ -185,7 +185,7 @@ icmpkick(void *x, Block *bp)
memset(p->cksum, 0, sizeof(p->cksum));
hnputs(p->cksum, ptclcsum(bp, ICMP_IPSIZE, blocklen(bp) - ICMP_IPSIZE));
ipriv->stats[OutMsgs]++;
- ipoput4(c->p->f, bp, 0, c->ttl, c->tos, nil);
+ ipoput4(c->p->f, bp, nil, c->ttl, c->tos, nil);
}
static int
@@ -240,7 +240,7 @@ icmpttlexceeded(Fs *f, Ipifc *ifc, Block *bp)
hnputs(np->seq, 0);
memset(np->cksum, 0, sizeof(np->cksum));
hnputs(np->cksum, ptclcsum(nbp, ICMP_IPSIZE, blocklen(nbp) - ICMP_IPSIZE));
- ipoput4(f, nbp, 0, MAXTTL, DFLTTOS, nil);
+ ipoput4(f, nbp, nil, MAXTTL, DFLTTOS, nil);
}
static void
@@ -280,7 +280,7 @@ icmpunreachable(Fs *f, Ipifc *ifc, Block *bp, int code, int seq)
hnputs(np->seq, seq);
memset(np->cksum, 0, sizeof(np->cksum));
hnputs(np->cksum, ptclcsum(nbp, ICMP_IPSIZE, blocklen(nbp) - ICMP_IPSIZE));
- ipoput4(f, nbp, 0, MAXTTL, DFLTTOS, nil);
+ ipoput4(f, nbp, nil, MAXTTL, DFLTTOS, nil);
}
void
@@ -302,7 +302,7 @@ icmpcantfrag(Fs *f, Block *bp, int mtu)
}
static void
-goticmpkt(Proto *icmp, Block *bp)
+goticmpkt(Proto *icmp, Block *bp, Ipifc *ifc)
{
uchar dst[IPaddrlen], src[IPaddrlen];
ushort recid;
@@ -331,7 +331,7 @@ goticmpkt(Proto *icmp, Block *bp)
q = nil;
qunlock(icmp);
- ipoput4(icmp->f, bp, 1, hop - 1, p->tos, q);
+ ipoput4(icmp->f, bp, ifc, hop - 1, p->tos, q);
return;
}
for(c = icmp->conv; (s = *c) != nil; c++){
@@ -386,7 +386,7 @@ static char *unreachcode[] =
};
static void
-icmpiput(Proto *icmp, Ipifc*, Block *bp)
+icmpiput(Proto *icmp, Ipifc *ifc, Block *bp)
{
int n;
Icmp *p;
@@ -426,14 +426,14 @@ icmpiput(Proto *icmp, Ipifc*, Block *bp)
if(r == nil)
goto raise;
ipriv->out[EchoReply]++;
- ipoput4(icmp->f, r, 0, MAXTTL, DFLTTOS, nil);
+ ipoput4(icmp->f, r, nil, MAXTTL, DFLTTOS, nil);
break;
case TimeExceed:
if(p->code == 0){
snprint(msg = m2, sizeof m2, "ttl exceeded at %V", p->src);
goto Advise;
}
- goticmpkt(icmp, bp);
+ goticmpkt(icmp, bp, ifc);
break;
case Unreachable:
if(p->code >= nelem(unreachcode)) {
@@ -455,14 +455,14 @@ icmpiput(Proto *icmp, Ipifc*, Block *bp)
pr = Fsrcvpcolx(icmp->f, p->proto);
if(pr != nil && pr->advise != nil) {
netlog(icmp->f, Logicmp, "advising %s!%V -> %V: %s\n", pr->name, p->src, p->dst, msg);
- (*pr->advise)(pr, bp, msg);
+ (*pr->advise)(pr, bp, ifc, msg);
return;
}
}
bp->rp -= ICMP_IPSIZE+ICMP_HDRSIZE;
/* wet floor */
default:
- goticmpkt(icmp, bp);
+ goticmpkt(icmp, bp, ifc);
break;
}
return;
@@ -479,7 +479,7 @@ raise:
* and send the advice to ip4.
*/
void
-icmpproxyadvice(Fs *f, Block *bp, uchar *ip4)
+icmpproxyadvice(Fs *f, Block *bp, Ipifc *ifc, uchar *ip4)
{
Icmp *p;
int hop;
@@ -509,14 +509,14 @@ icmpproxyadvice(Fs *f, Block *bp, uchar *ip4)
memset(p->cksum, 0, sizeof(p->cksum));
hnputs(p->cksum, ptclcsum(bp, ICMP_IPSIZE, blocklen(bp) - ICMP_IPSIZE));
- ipoput4(f, bp, 1, hop - 1, p->tos, nil);
+ ipoput4(f, bp, ifc, hop - 1, p->tos, nil);
return;
drop:
freeblist(bp);
}
static void
-icmpadvise(Proto *icmp, Block *bp, char *msg)
+icmpadvise(Proto *icmp, Block *bp, Ipifc *ifc, char *msg)
{
uchar dst[IPaddrlen], src[IPaddrlen];
ushort recid;
@@ -543,7 +543,7 @@ icmpadvise(Proto *icmp, Block *bp, char *msg)
hnputs_csum(p->icmpid, q->forward.rport, p->cksum);
qunlock(icmp);
- icmpproxyadvice(icmp->f, bp, p->src);
+ icmpproxyadvice(icmp->f, bp, ifc, p->src);
return;
}
for(c = icmp->conv; (s = *c) != nil; c++){
diff --git a/sys/src/9/ip/icmp6.c b/sys/src/9/ip/icmp6.c
index b49964c6d..bfcfcee92 100644
--- a/sys/src/9/ip/icmp6.c
+++ b/sys/src/9/ip/icmp6.c
@@ -216,7 +216,7 @@ newIPICMP(int packetlen)
}
static void
-icmpadvise6(Proto *icmp, Block *bp, char *msg)
+icmpadvise6(Proto *icmp, Block *bp, Ipifc *, char *msg)
{
ushort recid;
Conv **c, *s;
@@ -281,7 +281,7 @@ icmpkick6(void *x, Block *bp)
set_cksum(bp);
if(p->type <= Maxtype6)
ipriv->out[p->type]++;
- ipoput6(c->p->f, bp, 0, c->ttl, c->tos, nil);
+ ipoput6(c->p->f, bp, nil, c->ttl, c->tos, nil);
}
static char*
@@ -379,7 +379,7 @@ icmpns(Fs *f, uchar* src, int suni, uchar* targ, int tuni, uchar* mac)
set_cksum(nbp);
ipriv->out[NbrSolicit]++;
netlog(f, Logicmp, "sending neighbor solicitation %I\n", targ);
- ipoput6(f, nbp, 0, MAXTTL, DFLTTOS, nil);
+ ipoput6(f, nbp, nil, MAXTTL, DFLTTOS, nil);
}
/*
@@ -411,7 +411,7 @@ icmpna(Fs *f, uchar* src, uchar* dst, uchar* targ, uchar* mac, uchar flags)
set_cksum(nbp);
ipriv->out[NbrAdvert]++;
netlog(f, Logicmp, "sending neighbor advertisement %I\n", targ);
- ipoput6(f, nbp, 0, MAXTTL, DFLTTOS, nil);
+ ipoput6(f, nbp, nil, MAXTTL, DFLTTOS, nil);
}
void
@@ -452,7 +452,7 @@ icmphostunr6(Fs *f, Ipifc *ifc, Block *bp, int code, int tome)
ipiput6(f, ifc, nbp);
return;
}
- ipoput6(f, nbp, 0, MAXTTL, DFLTTOS, nil);
+ ipoput6(f, nbp, nil, MAXTTL, DFLTTOS, nil);
}
void
@@ -483,7 +483,7 @@ icmpttlexceeded6(Fs *f, Ipifc *ifc, Block *bp)
memmove(nbp->rp + IPICMPSZ, bp->rp, sz - IPICMPSZ);
set_cksum(nbp);
ipriv->out[TimeExceedV6]++;
- ipoput6(f, nbp, 0, MAXTTL, DFLTTOS, nil);
+ ipoput6(f, nbp, nil, MAXTTL, DFLTTOS, nil);
}
void
@@ -515,7 +515,7 @@ icmppkttoobig6(Fs *f, Ipifc *ifc, Block *bp)
memmove(nbp->rp + IPICMPSZ, bp->rp, sz - IPICMPSZ);
set_cksum(nbp);
ipriv->out[PacketTooBigV6]++;
- ipoput6(f, nbp, 0, MAXTTL, DFLTTOS, nil);
+ ipoput6(f, nbp, nil, MAXTTL, DFLTTOS, nil);
}
/*
@@ -692,7 +692,7 @@ icmpiput6(Proto *icmp, Ipifc *ifc, Block *bp)
if(r == nil)
goto raise;
ipriv->out[EchoReply]++;
- ipoput6(icmp->f, r, 0, MAXTTL, DFLTTOS, nil);
+ ipoput6(icmp->f, r, nil, MAXTTL, DFLTTOS, nil);
break;
case UnreachableV6:
@@ -724,7 +724,7 @@ icmpiput6(Proto *icmp, Ipifc *ifc, Block *bp)
pr = Fsrcvpcolx(icmp->f, p->proto);
if(pr != nil && pr->advise != nil) {
netlog(icmp->f, Logicmp, "advising %s!%I -> %I: %s\n", pr->name, p->src, p->dst, msg);
- (*pr->advise)(pr, bp, msg);
+ (*pr->advise)(pr, bp, ifc, msg);
return;
}
}
diff --git a/sys/src/9/ip/igmp.c b/sys/src/9/ip/igmp.c
index 6122b28e8..1ba28f16a 100644
--- a/sys/src/9/ip/igmp.c
+++ b/sys/src/9/ip/igmp.c
@@ -121,7 +121,7 @@ igmpsendreport(Fs *f, uchar *src, uchar *dst, uchar *group, int done)
p->proto = IP_IGMPPROTO;
memmove(p->group, group+IPv4off, IPv4addrlen);
hnputs(p->igmpcksum, ptclcsum(bp, IGMP_IPHDRSIZE, IGMP_HDRSIZE));
- ipoput4(f, bp, 0, 1, DFLTTOS, nil); /* TTL of 1 */
+ ipoput4(f, bp, nil, 1, DFLTTOS, nil); /* TTL of 1 */
}
static void
@@ -160,7 +160,7 @@ mldsendreport(Fs *f, uchar *src, uchar *dst, uchar *group, int done)
p->proto = IP_MLDPROTO;
hnputs(p->ploadlen, BLEN(bp) - IP6HDR);
- ipoput6(f, bp, 0, 1, DFLTTOS, nil); /* TTL of 1 */
+ ipoput6(f, bp, nil, 1, DFLTTOS, nil); /* TTL of 1 */
}
static void
diff --git a/sys/src/9/ip/il.c b/sys/src/9/ip/il.c
index bf72ec838..4bf21eb26 100644
--- a/sys/src/9/ip/il.c
+++ b/sys/src/9/ip/il.c
@@ -221,7 +221,7 @@ char* ilstart(Conv*, int, int);
void ilackproc(void*);
void iloutoforder(Conv*, Ilhdr*, Block*);
void iliput(Proto*, Ipifc*, Block*);
-void iladvise(Proto*, Block*, char*);
+void iladvise(Proto*, Block*, Ipifc*, char*);
int ilnextqt(Ilcb*);
void ilcbinit(Ilcb*);
int later(ulong, ulong, char*);
@@ -415,7 +415,7 @@ ilkick(void *x, Block *bp)
if(later(NOW, ic->timeout, nil))
ilsettimeout(ic);
- ipoput4(f, bp, 0, c->ttl, c->tos, c);
+ ipoput4(f, bp, nil, c->ttl, c->tos, c);
priv->stats[OutMsgs]++;
}
@@ -842,7 +842,7 @@ ilrexmit(Ilcb *ic)
ilbackoff(ic);
- ipoput4(c->p->f, nb, 0, c->ttl, c->tos, c);
+ ipoput4(c->p->f, nb, nil, c->ttl, c->tos, c);
/* statistics */
ic->rxtot++;
@@ -1044,7 +1044,7 @@ if(ipc->p==nil)
iltype[ih->iltype], nhgetl(ih->ilid), nhgetl(ih->ilack),
nhgets(ih->ilsrc), nhgets(ih->ildst));
- return ipoput4(ipc->p->f, bp, 0, ttl, tos, ipc);
+ return ipoput4(ipc->p->f, bp, nil, ttl, tos, ipc);
}
void
@@ -1078,7 +1078,7 @@ ilreject(Fs *f, Ilhdr *inih)
if(ilcksum)
hnputs(ih->ilsum, ptclcsum(bp, IL_IPSIZE, IL_HDRSIZE));
- ipoput4(f, bp, 0, MAXTTL, DFLTTOS, nil);
+ ipoput4(f, bp, nil, MAXTTL, DFLTTOS, nil);
}
void
@@ -1315,7 +1315,7 @@ ilfreeq(Ilcb *ic)
}
void
-iladvise(Proto *il, Block *bp, char *msg)
+iladvise(Proto *il, Block *bp, Ipifc*, char *msg)
{
Ilhdr *h;
Ilcb *ic;
diff --git a/sys/src/9/ip/ip.c b/sys/src/9/ip/ip.c
index 136ef1c66..751decffb 100644
--- a/sys/src/9/ip/ip.c
+++ b/sys/src/9/ip/ip.c
@@ -85,7 +85,7 @@ iprouting(Fs *f, int on)
}
int
-ipoput4(Fs *f, Block *bp, int gating, int ttl, int tos, Routehint *rh)
+ipoput4(Fs *f, Block *bp, Ipifc *gating, int ttl, int tos, Routehint *rh)
{
Ipifc *ifc;
uchar *gate;
@@ -135,9 +135,12 @@ ipoput4(Fs *f, Block *bp, int gating, int ttl, int tos, Routehint *rh)
goto raise;
medialen = ifc->maxtu - ifc->m->hsize;
- if(gating)
- tcpmssclamp(bp->rp, BLEN(bp), medialen);
- else {
+ if(gating != nil) {
+ int mtu = gating->maxtu - gating->m->hsize;
+ if(medialen < mtu)
+ mtu = medialen;
+ tcpmssclamp(bp->rp, BLEN(bp), mtu);
+ } else {
eh->vihl = IP_VER4|IP_HLEN4;
eh->tos = tos;
}
@@ -146,7 +149,7 @@ ipoput4(Fs *f, Block *bp, int gating, int ttl, int tos, Routehint *rh)
/* If we dont need to fragment just send it */
if(len <= medialen) {
hnputs(eh->length, len);
- if(!gating){
+ if(gating == nil){
hnputs(eh->id, incref(&ip->id4));
eh->frag[0] = 0;
eh->frag[1] = 0;
@@ -375,7 +378,7 @@ ipiput4(Fs *f, Ipifc *ifc, Block *bp)
}
ip->stats[ForwDatagrams]++;
- ipoput4(f, bp, 1, hop - 1, h->tos, &rh);
+ ipoput4(f, bp, ifc, hop - 1, h->tos, &rh);
return;
}
diff --git a/sys/src/9/ip/ip.h b/sys/src/9/ip/ip.h
index a75d59b89..f535367ce 100644
--- a/sys/src/9/ip/ip.h
+++ b/sys/src/9/ip/ip.h
@@ -432,7 +432,7 @@ struct Proto
void (*close)(Conv*);
void (*rcv)(Proto*, Ipifc*, Block*);
char* (*ctl)(Conv*, char**, int);
- void (*advise)(Proto*, Block*, char*);
+ void (*advise)(Proto*, Block*, Ipifc*, char*);
int (*stats)(Proto*, char*, int);
int (*local)(Conv*, char*, int);
int (*remote)(Conv*, char*, int);
@@ -741,13 +741,13 @@ extern void icmpnohost(Fs*, Ipifc*, Block*);
extern void icmpnoconv(Fs*, Block*);
extern void icmpcantfrag(Fs*, Block*, int);
extern void icmpttlexceeded(Fs*, Ipifc*, Block*);
-extern void icmpproxyadvice(Fs *, Block*, uchar*);
+extern void icmpproxyadvice(Fs *, Block*, Ipifc*, uchar*);
extern ushort ipcsum(uchar*);
extern void ipiput4(Fs*, Ipifc*, Block*);
extern void ipiput6(Fs*, Ipifc*, Block*);
-extern int ipoput4(Fs*, Block*, int, int, int, Routehint*);
-extern int ipoput6(Fs*, Block*, int, int, int, Routehint*);
+extern int ipoput4(Fs*, Block*, Ipifc*, int, int, Routehint*);
+extern int ipoput6(Fs*, Block*, Ipifc*, int, int, Routehint*);
extern int ipstats(Fs*, char*, int);
extern ushort ptclbsum(uchar*, int);
extern ushort ptclcsum(Block*, int, int);
diff --git a/sys/src/9/ip/ipmux.c b/sys/src/9/ip/ipmux.c
index 84de6fa3a..5d9421936 100644
--- a/sys/src/9/ip/ipmux.c
+++ b/sys/src/9/ip/ipmux.c
@@ -661,9 +661,9 @@ ipmuxkick(void *x)
Ip4hdr *ih4 = (Ip4hdr*)(bp->rp);
if((ih4->vihl & 0xF0) != IP_VER6)
- ipoput4(c->p->f, bp, 0, ih4->ttl, ih4->tos, nil);
+ ipoput4(c->p->f, bp, nil, ih4->ttl, ih4->tos, nil);
else
- ipoput6(c->p->f, bp, 0, ((Ip6hdr*)ih4)->ttl, 0, nil);
+ ipoput6(c->p->f, bp, nil, ((Ip6hdr*)ih4)->ttl, 0, nil);
}
}
diff --git a/sys/src/9/ip/ipv6.c b/sys/src/9/ip/ipv6.c
index 0e85fbfd6..4c79b004e 100644
--- a/sys/src/9/ip/ipv6.c
+++ b/sys/src/9/ip/ipv6.c
@@ -38,7 +38,7 @@ ip_init_6(Fs *f)
}
int
-ipoput6(Fs *f, Block *bp, int gating, int ttl, int tos, Routehint *rh)
+ipoput6(Fs *f, Block *bp, Ipifc *gating, int ttl, int tos, Routehint *rh)
{
int medialen, len, chunk, uflen, flen, seglen, lid, offset, fragoff;
int morefrags, blklen, rv = 0;
@@ -89,9 +89,12 @@ ipoput6(Fs *f, Block *bp, int gating, int ttl, int tos, Routehint *rh)
goto raise;
medialen = ifc->maxtu - ifc->m->hsize;
- if(gating)
- tcpmssclamp(bp->rp, BLEN(bp), medialen);
- else {
+ if(gating != nil){
+ int mtu = gating->maxtu - gating->m->hsize;
+ if(medialen < mtu)
+ mtu = medialen;
+ tcpmssclamp(bp->rp, BLEN(bp), mtu);
+ } else {
eh->vcf[0] = IP_VER6;
eh->vcf[0] |= tos >> 4;
eh->vcf[1] = tos << 4;
@@ -107,7 +110,7 @@ ipoput6(Fs *f, Block *bp, int gating, int ttl, int tos, Routehint *rh)
return 0;
}
- if(gating && !ifc->reassemble) {
+ if(gating != nil && !ifc->reassemble) {
/*
* v6 intermediate nodes are not supposed to fragment pkts;
* we fragment if ifc->reassemble is turned on; an exception
@@ -294,7 +297,7 @@ ipiput6(Fs *f, Ipifc *ifc, Block *bp)
ip->stats[ForwDatagrams]++;
h = (Ip6hdr*)bp->rp;
tos = (h->vcf[0]&0x0F)<<2 | (h->vcf[1]&0xF0)>>2;
- ipoput6(f, bp, 1, hop - 1, tos, &rh);
+ ipoput6(f, bp, ifc, hop - 1, tos, &rh);
return;
}
diff --git a/sys/src/9/ip/rudp.c b/sys/src/9/ip/rudp.c
index 18842479f..726e4286f 100644
--- a/sys/src/9/ip/rudp.c
+++ b/sys/src/9/ip/rudp.c
@@ -314,7 +314,7 @@ rudpclose(Conv *c)
* randomly don't send packets
*/
static void
-doipoput(Conv *c, Fs *f, Block *bp, int x, int ttl, int tos)
+doipoput(Conv *c, Fs *f, Block *bp, int ttl, int tos)
{
Rudpcb *ucb;
@@ -322,7 +322,7 @@ doipoput(Conv *c, Fs *f, Block *bp, int x, int ttl, int tos)
if(ucb->randdrop && nrand(100) < ucb->randdrop)
freeblist(bp);
else
- ipoput4(f, bp, x, ttl, tos, nil);
+ ipoput4(f, bp, nil, ttl, tos, nil);
}
int
@@ -437,7 +437,7 @@ rudpkick(void *x)
DPRINT("sent: %lud/%lud, %lud/%lud\n",
r->sndseq, r->sndgen, r->rcvseq, r->rcvgen);
- doipoput(c, f, bp, 0, c->ttl, c->tos);
+ doipoput(c, f, bp, c->ttl, c->tos);
if(waserror()) {
relput(r);
@@ -622,7 +622,7 @@ rudpctl(Conv *c, char **f, int n)
}
void
-rudpadvise(Proto *rudp, Block *bp, char *msg)
+rudpadvise(Proto *rudp, Block *bp, Ipifc *, char *msg)
{
Udphdr *h;
uchar source[IPaddrlen], dest[IPaddrlen];
@@ -987,7 +987,7 @@ relsendack(Conv *c, Reliable *r, int hangup)
hnputs(uh->udpcksum, ptclcsum(bp, UDP_IPHDR, UDP_RHDRSIZE));
DPRINT("sendack: %lud/%lud, %lud/%lud\n", 0L, r->sndgen, r->rcvseq, r->rcvgen);
- doipoput(c, f, bp, 0, c->ttl, c->tos);
+ doipoput(c, f, bp, c->ttl, c->tos);
}
@@ -1047,5 +1047,5 @@ relrexmit(Conv *c, Reliable *r)
upriv->rxmits++;
np = copyblock(r->unacked, blocklen(r->unacked));
DPRINT("rxmit r->ackrvcd+1 = %lud\n", r->ackrcvd+1);
- doipoput(c, f, np, 0, c->ttl, c->tos);
+ doipoput(c, f, np, c->ttl, c->tos);
}
diff --git a/sys/src/9/ip/tcp.c b/sys/src/9/ip/tcp.c
index f6fbf19ed..a5b1c5f2a 100644
--- a/sys/src/9/ip/tcp.c
+++ b/sys/src/9/ip/tcp.c
@@ -1391,10 +1391,10 @@ sndrst(Proto *tcp, uchar *source, uchar *dest, ushort length, Tcp *seg, uchar ve
switch(version) {
case V4:
hbp = htontcp4(seg, nil, &ph4, nil);
- return ipoput4(tcp->f, hbp, 0, MAXTTL, DFLTTOS, rh);
+ return ipoput4(tcp->f, hbp, nil, MAXTTL, DFLTTOS, rh);
case V6:
hbp = htontcp6(seg, nil, &ph6, nil);
- return ipoput6(tcp->f, hbp, 0, MAXTTL, DFLTTOS, rh);
+ return ipoput6(tcp->f, hbp, nil, MAXTTL, DFLTTOS, rh);
}
return -1;
}
@@ -1428,12 +1428,12 @@ tcphangup(Conv *s)
case V4:
tcb->protohdr.tcp4hdr.vihl = IP_VER4;
hbp = htontcp4(&seg, nil, &tcb->protohdr.tcp4hdr, tcb);
- ipoput4(s->p->f, hbp, 0, s->ttl, s->tos, s);
+ ipoput4(s->p->f, hbp, nil, s->ttl, s->tos, s);
break;
case V6:
tcb->protohdr.tcp6hdr.vcf[0] = IP_VER6;
hbp = htontcp6(&seg, nil, &tcb->protohdr.tcp6hdr, tcb);
- ipoput6(s->p->f, hbp, 0, s->ttl, s->tos, s);
+ ipoput6(s->p->f, hbp, nil, s->ttl, s->tos, s);
break;
default:
panic("tcphangup: version %d", s->ipversion);
@@ -1512,10 +1512,10 @@ sndsynack(Proto *tcp, Limbo *lp)
switch(lp->version) {
case V4:
hbp = htontcp4(&seg, nil, &ph4, nil);
- return ipoput4(tcp->f, hbp, 0, MAXTTL, DFLTTOS, &rh);
+ return ipoput4(tcp->f, hbp, nil, MAXTTL, DFLTTOS, &rh);
case V6:
hbp = htontcp6(&seg, nil, &ph6, nil);
- return ipoput6(tcp->f, hbp, 0, MAXTTL, DFLTTOS, &rh);
+ return ipoput6(tcp->f, hbp, nil, MAXTTL, DFLTTOS, &rh);
}
return -1;
}
@@ -2061,7 +2061,7 @@ done:
}
static void
-tcpiput(Proto *tcp, Ipifc*, Block *bp)
+tcpiput(Proto *tcp, Ipifc *ifc, Block *bp)
{
Tcp seg;
Tcp4hdr *h4;
@@ -2184,7 +2184,7 @@ reset:
hnputs_csum(h4->tcpdst+2, nhgets(q->forward.raddr+IPv4off+2), h4->tcpcksum);
hnputs_csum(h4->tcpdport, q->forward.rport, h4->tcpcksum);
qunlock(tcp);
- ipoput4(f, bp, 1, hop - 1, h4->tos, q);
+ ipoput4(f, bp, ifc, hop - 1, h4->tos, q);
return;
}
s = iphconv(iph);
@@ -2757,11 +2757,11 @@ tcpoutput(Conv *s)
switch(version){
case V4:
- if(ipoput4(f, hbp, 0, s->ttl, s->tos, s) < 0)
+ if(ipoput4(f, hbp, nil, s->ttl, s->tos, s) < 0)
localclose(s, Enoroute);
break;
case V6:
- if(ipoput6(f, hbp, 0, s->ttl, s->tos, s) < 0)
+ if(ipoput6(f, hbp, nil, s->ttl, s->tos, s) < 0)
localclose(s, Enoroute);
break;
}
@@ -2811,13 +2811,13 @@ tcpsendka(Conv *s)
/* Build header, link data and compute cksum */
tcb->protohdr.tcp4hdr.vihl = IP_VER4;
hbp = htontcp4(&seg, dbp, &tcb->protohdr.tcp4hdr, tcb);
- return ipoput4(s->p->f, hbp, 0, s->ttl, s->tos, s);
+ return ipoput4(s->p->f, hbp, nil, s->ttl, s->tos, s);
}
else {
/* Build header, link data and compute cksum */
tcb->protohdr.tcp6hdr.vcf[0] = IP_VER6;
hbp = htontcp6(&seg, dbp, &tcb->protohdr.tcp6hdr, tcb);
- return ipoput6(s->p->f, hbp, 0, s->ttl, s->tos, s);
+ return ipoput6(s->p->f, hbp, nil, s->ttl, s->tos, s);
}
}
@@ -3214,7 +3214,7 @@ tcptrim(Tcpctl *tcb, Tcp *seg, Block **bp, ushort *length)
}
static void
-tcpadvise(Proto *tcp, Block *bp, char *msg)
+tcpadvise(Proto *tcp, Block *bp, Ipifc *ifc, char *msg)
{
Tcp4hdr *h4;
Tcp6hdr *h6;
@@ -3259,7 +3259,7 @@ tcpadvise(Proto *tcp, Block *bp, char *msg)
hnputs(h4->tcpsport, q->forward.rport);
qunlock(tcp);
- icmpproxyadvice(tcp->f, bp, h4->tcpsrc);
+ icmpproxyadvice(tcp->f, bp, ifc, h4->tcpsrc);
return;
}
s = iphconv(iph);
diff --git a/sys/src/9/ip/udp.c b/sys/src/9/ip/udp.c
index a1db5713c..9e8d82b8e 100644
--- a/sys/src/9/ip/udp.c
+++ b/sys/src/9/ip/udp.c
@@ -267,7 +267,7 @@ udpkick(void *x, Block *bp)
csum = 0xffff; /* -0 */
hnputs(uh4->udpcksum, csum);
uh4->vihl = IP_VER4;
- ipoput4(f, bp, 0, c->ttl, c->tos, rh);
+ ipoput4(f, bp, nil, c->ttl, c->tos, rh);
break;
case V6:
@@ -303,7 +303,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, rh);
+ ipoput6(f, bp, nil, c->ttl, c->tos, rh);
break;
default:
@@ -433,7 +433,7 @@ Noconv:
if(memcmp(uh4->udpsrc, q->forward.laddr+IPv4off, IPv4addrlen) != 0)
q = nil;
qunlock(udp);
- ipoput4(f, bp, 1, hop - 1, uh4->tos, q);
+ ipoput4(f, bp, ifc, hop - 1, uh4->tos, q);
return;
}
c = iphconv(iph);
@@ -545,7 +545,7 @@ udpctl(Conv *c, char **f, int n)
}
void
-udpadvise(Proto *udp, Block *bp, char *msg)
+udpadvise(Proto *udp, Block *bp, Ipifc *ifc, char *msg)
{
Udp4hdr *h4;
Udp6hdr *h6;
@@ -588,7 +588,7 @@ udpadvise(Proto *udp, Block *bp, char *msg)
hnputs(h4->udpsport, q->forward.rport);
qunlock(udp);
- icmpproxyadvice(udp->f, bp, h4->udpsrc);
+ icmpproxyadvice(udp->f, bp, ifc, h4->udpsrc);
return;
}
s = iphconv(iph);