diff options
author | Andre Oppermann <andre@FreeBSD.org> | 2013-06-03 12:55:13 +0000 |
---|---|---|
committer | Andre Oppermann <andre@FreeBSD.org> | 2013-06-03 12:55:13 +0000 |
commit | 3c914c547e923bab0a3e26835bab96625ba528aa (patch) | |
tree | 1234da94faa0d8e5fb8d693bb7883535361a40a4 /sys/netinet/tcp_input.c | |
parent | acbbd07aca9be2db7723f0299778eceae8e2ea87 (diff) | |
download | src-3c914c547e923bab0a3e26835bab96625ba528aa.tar.gz src-3c914c547e923bab0a3e26835bab96625ba528aa.zip |
Allow drivers to specify a maximum TSO length in bytes if they are
limited in the amount of data they can handle at once.
Drivers can set ifp->if_hw_tsomax before calling ether_ifattach() to
change the limit.
The lowest allowable size is IP_MAXPACKET / 8 (8192 bytes) as anything
less wouldn't be very useful anymore. The upper limit is still at
IP_MAXPACKET (65536 bytes). Raising it requires further auditing of
the IPv4/v6 code path's as the length field in the IP header would
overflow leading to confusion in firewalls and others packet handler on
the real size of the packet.
The placement into "struct ifnet" is a bit hackish but the best place
that was found. When the stack/driver boundary is updated it should
be handled in a better way.
Submitted by: cperciva (earlier version)
Reviewed by: cperciva
Tested by: cperciva
MFC after: 1 week (using spare struct members to preserve ABI)
Notes
Notes:
svn path=/head/; revision=251296
Diffstat (limited to 'sys/netinet/tcp_input.c')
-rw-r--r-- | sys/netinet/tcp_input.c | 17 |
1 files changed, 10 insertions, 7 deletions
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index a3122a193938..25b320ee0cfb 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -3434,7 +3434,7 @@ tcp_xmit_timer(struct tcpcb *tp, int rtt) */ void tcp_mss_update(struct tcpcb *tp, int offer, int mtuoffer, - struct hc_metrics_lite *metricptr, int *mtuflags) + struct hc_metrics_lite *metricptr, struct tcp_ifcap *cap) { int mss = 0; u_long maxmtu = 0; @@ -3461,7 +3461,7 @@ tcp_mss_update(struct tcpcb *tp, int offer, int mtuoffer, /* Initialize. */ #ifdef INET6 if (isipv6) { - maxmtu = tcp_maxmtu6(&inp->inp_inc, mtuflags); + maxmtu = tcp_maxmtu6(&inp->inp_inc, cap); tp->t_maxopd = tp->t_maxseg = V_tcp_v6mssdflt; } #endif @@ -3470,7 +3470,7 @@ tcp_mss_update(struct tcpcb *tp, int offer, int mtuoffer, #endif #ifdef INET { - maxmtu = tcp_maxmtu(&inp->inp_inc, mtuflags); + maxmtu = tcp_maxmtu(&inp->inp_inc, cap); tp->t_maxopd = tp->t_maxseg = V_tcp_mssdflt; } #endif @@ -3605,11 +3605,12 @@ tcp_mss(struct tcpcb *tp, int offer) struct inpcb *inp; struct socket *so; struct hc_metrics_lite metrics; - int mtuflags = 0; + struct tcp_ifcap cap; KASSERT(tp != NULL, ("%s: tp == NULL", __func__)); - - tcp_mss_update(tp, offer, -1, &metrics, &mtuflags); + + bzero(&cap, sizeof(cap)); + tcp_mss_update(tp, offer, -1, &metrics, &cap); mss = tp->t_maxseg; inp = tp->t_inpcb; @@ -3654,8 +3655,10 @@ tcp_mss(struct tcpcb *tp, int offer) SOCKBUF_UNLOCK(&so->so_rcv); /* Check the interface for TSO capabilities. */ - if (mtuflags & CSUM_TSO) + if (cap.ifcap & CSUM_TSO) { tp->t_flags |= TF_TSO; + tp->t_tsomax = cap.tsomax; + } } /* |