Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/tcp_output.c
Show All 31 Lines | |||||
*/ | */ | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include "opt_inet.h" | #include "opt_inet.h" | ||||
#include "opt_inet6.h" | #include "opt_inet6.h" | ||||
#include "opt_ipsec.h" | #include "opt_ipsec.h" | ||||
#include "opt_kern_tls.h" | |||||
#include "opt_tcpdebug.h" | #include "opt_tcpdebug.h" | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/systm.h> | #include <sys/systm.h> | ||||
#include <sys/domain.h> | #include <sys/domain.h> | ||||
#ifdef TCP_HHOOK | #ifdef TCP_HHOOK | ||||
#include <sys/hhook.h> | #include <sys/hhook.h> | ||||
#endif | #endif | ||||
#include <sys/kernel.h> | #include <sys/kernel.h> | ||||
#ifdef KERN_TLS | |||||
#include <sys/ktls.h> | |||||
#endif | |||||
#include <sys/lock.h> | #include <sys/lock.h> | ||||
#include <sys/mbuf.h> | #include <sys/mbuf.h> | ||||
#include <sys/mutex.h> | #include <sys/mutex.h> | ||||
#include <sys/protosw.h> | #include <sys/protosw.h> | ||||
#include <sys/sdt.h> | #include <sys/sdt.h> | ||||
#include <sys/socket.h> | #include <sys/socket.h> | ||||
#include <sys/socketvar.h> | #include <sys/socketvar.h> | ||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
▲ Show 20 Lines • Show All 157 Lines • ▼ Show 20 Lines | #if 0 | ||||
int maxburst = TCP_MAXBURST; | int maxburst = TCP_MAXBURST; | ||||
#endif | #endif | ||||
#ifdef INET6 | #ifdef INET6 | ||||
struct ip6_hdr *ip6 = NULL; | struct ip6_hdr *ip6 = NULL; | ||||
int isipv6; | int isipv6; | ||||
isipv6 = (tp->t_inpcb->inp_vflag & INP_IPV6) != 0; | isipv6 = (tp->t_inpcb->inp_vflag & INP_IPV6) != 0; | ||||
#endif | #endif | ||||
bool hw_tls; | |||||
hselaskyUnsubmitted Done Inline Actionshselasky: ```
#ifdef KERN_TLS
const bool hw_tls = (so->so_snd.sb_flags & SB_TLS_IFNET) != 0;
#else
const… | |||||
Done Inline ActionsI could do that. In theory style(9) doesn't like assignments in declarations though we do violate that rule a bit. FWIW, the compiler generates identical output either way. jhb: I could do that. In theory style(9) doesn't like assignments in declarations though we do… | |||||
#ifdef KERN_TLS | |||||
if (so->so_snd.sb_flags & SB_TLS_IFNET) | |||||
hw_tls = true; | |||||
else | |||||
#endif | |||||
hw_tls = false; | |||||
INP_WLOCK_ASSERT(tp->t_inpcb); | INP_WLOCK_ASSERT(tp->t_inpcb); | ||||
#ifdef TCP_OFFLOAD | #ifdef TCP_OFFLOAD | ||||
if (tp->t_flags & TF_TOE) | if (tp->t_flags & TF_TOE) | ||||
return (tcp_offload_output(tp)); | return (tcp_offload_output(tp)); | ||||
#endif | #endif | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 764 Lines • ▼ Show 20 Lines | #endif | ||||
m->m_data += max_linkhdr; | m->m_data += max_linkhdr; | ||||
m->m_len = hdrlen; | m->m_len = hdrlen; | ||||
/* | /* | ||||
* Start the m_copy functions from the closest mbuf | * Start the m_copy functions from the closest mbuf | ||||
* to the offset in the socket buffer chain. | * to the offset in the socket buffer chain. | ||||
*/ | */ | ||||
mb = sbsndptr_noadv(&so->so_snd, off, &moff); | mb = sbsndptr_noadv(&so->so_snd, off, &moff); | ||||
if (len <= MHLEN - hdrlen - max_linkhdr) { | if (len <= MHLEN - hdrlen - max_linkhdr && !hw_tls) { | ||||
Not Done Inline ActionsShould you at ()'s here? hselasky: Should you at ()'s here? | |||||
Not Done Inline Actionss/at/add hselasky: s/at/add | |||||
Done Inline ActionsWe don't typically add excessive ()'s. style(9) discourages it and neither clang nor gcc warn in this case. It is pretty intuitive for comparisons to have higher precedence than logical and/or. jhb: We don't typically add excessive ()'s. style(9) discourages it and neither clang nor gcc warn… | |||||
m_copydata(mb, moff, len, | m_copydata(mb, moff, len, | ||||
mtod(m, caddr_t) + hdrlen); | mtod(m, caddr_t) + hdrlen); | ||||
if (SEQ_LT(tp->snd_nxt, tp->snd_max)) | if (SEQ_LT(tp->snd_nxt, tp->snd_max)) | ||||
sbsndptr_adv(&so->so_snd, mb, len); | sbsndptr_adv(&so->so_snd, mb, len); | ||||
m->m_len += len; | m->m_len += len; | ||||
} else { | } else { | ||||
if (SEQ_LT(tp->snd_nxt, tp->snd_max)) | if (SEQ_LT(tp->snd_nxt, tp->snd_max)) | ||||
msb = NULL; | msb = NULL; | ||||
else | else | ||||
msb = &so->so_snd; | msb = &so->so_snd; | ||||
m->m_next = tcp_m_copym(mb, moff, | m->m_next = tcp_m_copym(mb, moff, | ||||
&len, if_hw_tsomaxsegcount, | &len, if_hw_tsomaxsegcount, | ||||
if_hw_tsomaxsegsize, msb); | if_hw_tsomaxsegsize, msb, hw_tls); | ||||
if (len <= (tp->t_maxseg - optlen)) { | if (len <= (tp->t_maxseg - optlen)) { | ||||
/* | /* | ||||
* Must have ran out of mbufs for the copy | * Must have ran out of mbufs for the copy | ||||
* shorten it to no longer need tso. Lets | * shorten it to no longer need tso. Lets | ||||
* not put on sendalot since we are low on | * not put on sendalot since we are low on | ||||
* mbufs. | * mbufs. | ||||
*/ | */ | ||||
tso = 0; | tso = 0; | ||||
▲ Show 20 Lines • Show All 780 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
/* | /* | ||||
* This is a copy of m_copym(), taking the TSO segment size/limit | * This is a copy of m_copym(), taking the TSO segment size/limit | ||||
* constraints into account, and advancing the sndptr as it goes. | * constraints into account, and advancing the sndptr as it goes. | ||||
*/ | */ | ||||
struct mbuf * | struct mbuf * | ||||
tcp_m_copym(struct mbuf *m, int32_t off0, int32_t *plen, | tcp_m_copym(struct mbuf *m, int32_t off0, int32_t *plen, | ||||
int32_t seglimit, int32_t segsize, struct sockbuf *sb) | int32_t seglimit, int32_t segsize, struct sockbuf *sb, bool hw_tls) | ||||
{ | { | ||||
#ifdef KERN_TLS | |||||
struct ktls_session *tls, *ntls; | |||||
struct mbuf *start; | |||||
#endif | |||||
struct mbuf *n, **np; | struct mbuf *n, **np; | ||||
struct mbuf *top; | struct mbuf *top; | ||||
int32_t off = off0; | int32_t off = off0; | ||||
int32_t len = *plen; | int32_t len = *plen; | ||||
int32_t fragsize; | int32_t fragsize; | ||||
int32_t len_cp = 0; | int32_t len_cp = 0; | ||||
int32_t *pkthdrlen; | int32_t *pkthdrlen; | ||||
uint32_t mlen, frags; | uint32_t mlen, frags; | ||||
Show All 15 Lines | if ((sb) && (m == sb->sb_sndptr)) { | ||||
sb->sb_sndptroff += m->m_len; | sb->sb_sndptroff += m->m_len; | ||||
sb->sb_sndptr = m->m_next; | sb->sb_sndptr = m->m_next; | ||||
} | } | ||||
m = m->m_next; | m = m->m_next; | ||||
} | } | ||||
np = ⊤ | np = ⊤ | ||||
top = NULL; | top = NULL; | ||||
pkthdrlen = NULL; | pkthdrlen = NULL; | ||||
#ifdef KERN_TLS | |||||
if (m->m_flags & M_NOMAP) | |||||
tls = m->m_ext.ext_pgs->tls; | |||||
else | |||||
tls = NULL; | |||||
start = m; | |||||
#endif | |||||
while (len > 0) { | while (len > 0) { | ||||
if (m == NULL) { | if (m == NULL) { | ||||
KASSERT(len == M_COPYALL, | KASSERT(len == M_COPYALL, | ||||
("tcp_m_copym, length > size of mbuf chain")); | ("tcp_m_copym, length > size of mbuf chain")); | ||||
*plen = len_cp; | *plen = len_cp; | ||||
if (pkthdrlen != NULL) | if (pkthdrlen != NULL) | ||||
*pkthdrlen = len_cp; | *pkthdrlen = len_cp; | ||||
break; | break; | ||||
} | } | ||||
#ifdef KERN_TLS | |||||
if (hw_tls) { | |||||
if (m->m_flags & M_NOMAP) | |||||
ntls = m->m_ext.ext_pgs->tls; | |||||
else | |||||
ntls = NULL; | |||||
/* | |||||
* Avoid mixing TLS records with handshake | |||||
* data or TLS records from different | |||||
* sessions. | |||||
*/ | |||||
if (tls != ntls) { | |||||
MPASS(m != start); | |||||
*plen = len_cp; | |||||
if (pkthdrlen != NULL) | |||||
*pkthdrlen = len_cp; | |||||
break; | |||||
} | |||||
/* | |||||
* Don't end a send in the middle of a TLS | |||||
* record if it spans multiple TLS records. | |||||
*/ | |||||
if (tls != NULL && (m != start) && len < m->m_len) { | |||||
*plen = len_cp; | |||||
if (pkthdrlen != NULL) | |||||
*pkthdrlen = len_cp; | |||||
break; | |||||
} | |||||
} | |||||
#endif | |||||
mlen = min(len, m->m_len - off); | mlen = min(len, m->m_len - off); | ||||
if (seglimit) { | if (seglimit) { | ||||
/* | /* | ||||
* For M_NOMAP mbufs, add 3 segments | * For M_NOMAP mbufs, add 3 segments | ||||
* + 1 in case we are crossing page boundaries | * + 1 in case we are crossing page boundaries | ||||
* + 2 in case the TLS hdr/trailer are used | * + 2 in case the TLS hdr/trailer are used | ||||
* It is cheaper to just add the segments | * It is cheaper to just add the segments | ||||
* than it is to take the cache miss to look | * than it is to take the cache miss to look | ||||
▲ Show 20 Lines • Show All 140 Lines • Show Last 20 Lines |