diff options
Diffstat (limited to 'sys/netinet')
-rw-r--r-- | sys/netinet/tcp_input.c | 17 | ||||
-rw-r--r-- | sys/netinet/tcp_output.c | 9 | ||||
-rw-r--r-- | sys/netinet/tcp_subr.c | 14 | ||||
-rw-r--r-- | sys/netinet/tcp_var.h | 17 |
4 files changed, 37 insertions, 20 deletions
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index a3122a1..25b320e 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; + } } /* diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c index 16038cb..b4342f3 100644 --- a/sys/netinet/tcp_output.c +++ b/sys/netinet/tcp_output.c @@ -769,12 +769,13 @@ send: ("%s: TSO can't do IP options", __func__)); /* - * Limit a burst to IP_MAXPACKET minus IP, + * Limit a burst to t_tsomax minus IP, * TCP and options length to keep ip->ip_len - * from overflowing. + * from overflowing or exceeding the maximum + * length allowed by the network interface. */ - if (len > IP_MAXPACKET - hdrlen) { - len = IP_MAXPACKET - hdrlen; + if (len > tp->t_tsomax - hdrlen) { + len = tp->t_tsomax - hdrlen; sendalot = 1; } diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c index 05030fd..c466bf4 100644 --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -1770,7 +1770,7 @@ tcp_mtudisc(struct inpcb *inp, int mtuoffer) * tcp_mss_update to get the peer/interface MTU. */ u_long -tcp_maxmtu(struct in_conninfo *inc, int *flags) +tcp_maxmtu(struct in_conninfo *inc, struct tcp_ifcap *cap) { struct route sro; struct sockaddr_in *dst; @@ -1795,10 +1795,11 @@ tcp_maxmtu(struct in_conninfo *inc, int *flags) maxmtu = min(sro.ro_rt->rt_rmx.rmx_mtu, ifp->if_mtu); /* Report additional interface capabilities. */ - if (flags != NULL) { + if (cap != NULL) { if (ifp->if_capenable & IFCAP_TSO4 && ifp->if_hwassist & CSUM_TSO) - *flags |= CSUM_TSO; + cap->ifcap |= CSUM_TSO; + cap->tsomax = ifp->if_hw_tsomax; } RTFREE(sro.ro_rt); } @@ -1808,7 +1809,7 @@ tcp_maxmtu(struct in_conninfo *inc, int *flags) #ifdef INET6 u_long -tcp_maxmtu6(struct in_conninfo *inc, int *flags) +tcp_maxmtu6(struct in_conninfo *inc, struct tcp_ifcap *cap) { struct route_in6 sro6; struct ifnet *ifp; @@ -1832,10 +1833,11 @@ tcp_maxmtu6(struct in_conninfo *inc, int *flags) IN6_LINKMTU(sro6.ro_rt->rt_ifp)); /* Report additional interface capabilities. */ - if (flags != NULL) { + if (cap != NULL) { if (ifp->if_capenable & IFCAP_TSO6 && ifp->if_hwassist & CSUM_TSO) - *flags |= CSUM_TSO; + cap->ifcap |= CSUM_TSO; + cap->tsomax = ifp->if_hw_tsomax; } RTFREE(sro6.ro_rt); } diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h index eddbd3c..0445d8c 100644 --- a/sys/netinet/tcp_var.h +++ b/sys/netinet/tcp_var.h @@ -208,6 +208,8 @@ struct tcpcb { u_int t_keepintvl; /* interval between keepalives */ u_int t_keepcnt; /* number of keepalives before close */ + u_int t_tsomax; /* tso burst length limit */ + uint32_t t_ispare[8]; /* 5 UTO, 3 TBD */ void *t_pspare2[4]; /* 4 TBD */ uint64_t _pad[6]; /* 6 TBD (1-2 CC/RTT?) */ @@ -324,6 +326,15 @@ struct hc_metrics_lite { /* must stay in sync with hc_metrics */ u_long rmx_recvpipe; /* inbound delay-bandwidth product */ }; +/* + * Used by tcp_maxmtu() to communicate interface specific features + * and limits at the time of connection setup. + */ +struct tcp_ifcap { + int ifcap; + u_int tsomax; +}; + #ifndef _NETINET_IN_PCB_H_ struct in_conninfo; #endif /* _NETINET_IN_PCB_H_ */ @@ -782,10 +793,10 @@ void tcp_reass_flush(struct tcpcb *); void tcp_reass_destroy(void); #endif void tcp_input(struct mbuf *, int); -u_long tcp_maxmtu(struct in_conninfo *, int *); -u_long tcp_maxmtu6(struct in_conninfo *, int *); +u_long tcp_maxmtu(struct in_conninfo *, struct tcp_ifcap *); +u_long tcp_maxmtu6(struct in_conninfo *, struct tcp_ifcap *); void tcp_mss_update(struct tcpcb *, int, int, struct hc_metrics_lite *, - int *); + struct tcp_ifcap *); void tcp_mss(struct tcpcb *, int); int tcp_mssopt(struct in_conninfo *); struct inpcb * |