Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/ip_output.c
Show First 20 Lines • Show All 763 Lines • ▼ Show 20 Lines | if (m->m_pkthdr.csum_flags & CSUM_SCTP & ~ifp->if_hwassist) { | ||||
sctp_delayed_cksum(m, (uint32_t)(ip->ip_hl << 2)); | sctp_delayed_cksum(m, (uint32_t)(ip->ip_hl << 2)); | ||||
m->m_pkthdr.csum_flags &= ~CSUM_SCTP; | m->m_pkthdr.csum_flags &= ~CSUM_SCTP; | ||||
} | } | ||||
#endif | #endif | ||||
/* | /* | ||||
* If small enough for interface, or the interface will take | * If small enough for interface, or the interface will take | ||||
* care of the fragmentation for us, we can just send directly. | * care of the fragmentation for us, we can just send directly. | ||||
* Note that if_vxlan could have requested TSO even though the outer | |||||
* frame is UDP. It is correct to not fragment such datagrams and | |||||
* instead just pass them on to the driver. | |||||
*/ | */ | ||||
if (ip_len <= mtu || | if (ip_len <= mtu || | ||||
(m->m_pkthdr.csum_flags & ifp->if_hwassist & CSUM_TSO) != 0) { | (m->m_pkthdr.csum_flags & ifp->if_hwassist & | ||||
(CSUM_TSO | CSUM_INNER_TSO)) != 0) { | |||||
ip->ip_sum = 0; | ip->ip_sum = 0; | ||||
if (m->m_pkthdr.csum_flags & CSUM_IP & ~ifp->if_hwassist) { | if (m->m_pkthdr.csum_flags & CSUM_IP & ~ifp->if_hwassist) { | ||||
ip->ip_sum = in_cksum(m, hlen); | ip->ip_sum = in_cksum(m, hlen); | ||||
m->m_pkthdr.csum_flags &= ~CSUM_IP; | m->m_pkthdr.csum_flags &= ~CSUM_IP; | ||||
} | } | ||||
/* | /* | ||||
* Record statistics for this interface address. | * Record statistics for this interface address. | ||||
* With CSUM_TSO the byte/packet count will be slightly | * With CSUM_TSO the byte/packet count will be slightly | ||||
* incorrect because we count the IP+TCP headers only | * incorrect because we count the IP+TCP headers only | ||||
* once instead of for every generated packet. | * once instead of for every generated packet. | ||||
*/ | */ | ||||
if (!(flags & IP_FORWARDING) && ia) { | if (!(flags & IP_FORWARDING) && ia) { | ||||
if (m->m_pkthdr.csum_flags & CSUM_TSO) | if (m->m_pkthdr.csum_flags & | ||||
(CSUM_TSO | CSUM_INNER_TSO)) | |||||
counter_u64_add(ia->ia_ifa.ifa_opackets, | counter_u64_add(ia->ia_ifa.ifa_opackets, | ||||
m->m_pkthdr.len / m->m_pkthdr.tso_segsz); | m->m_pkthdr.len / m->m_pkthdr.tso_segsz); | ||||
else | else | ||||
counter_u64_add(ia->ia_ifa.ifa_opackets, 1); | counter_u64_add(ia->ia_ifa.ifa_opackets, 1); | ||||
counter_u64_add(ia->ia_ifa.ifa_obytes, m->m_pkthdr.len); | counter_u64_add(ia->ia_ifa.ifa_obytes, m->m_pkthdr.len); | ||||
} | } | ||||
#ifdef MBUF_STRESS_TEST | #ifdef MBUF_STRESS_TEST | ||||
if (mbuf_frag_size && m->m_pkthdr.len > mbuf_frag_size) | if (mbuf_frag_size && m->m_pkthdr.len > mbuf_frag_size) | ||||
m = m_fragment(m, M_NOWAIT, mbuf_frag_size); | m = m_fragment(m, M_NOWAIT, mbuf_frag_size); | ||||
#endif | #endif | ||||
/* | /* | ||||
* Reset layer specific mbuf flags | * Reset layer specific mbuf flags | ||||
* to avoid confusing lower layers. | * to avoid confusing lower layers. | ||||
*/ | */ | ||||
m_clrprotoflags(m); | m_clrprotoflags(m); | ||||
IP_PROBE(send, NULL, NULL, ip, ifp, ip, NULL); | IP_PROBE(send, NULL, NULL, ip, ifp, ip, NULL); | ||||
error = ip_output_send(inp, ifp, m, gw, ro, | error = ip_output_send(inp, ifp, m, gw, ro, | ||||
(flags & IP_NO_SND_TAG_RL) ? false : true); | (flags & IP_NO_SND_TAG_RL) ? false : true); | ||||
goto done; | goto done; | ||||
} | } | ||||
/* Balk when DF bit is set or the interface didn't support TSO. */ | /* Balk when DF bit is set or the interface didn't support TSO. */ | ||||
if ((ip_off & IP_DF) || (m->m_pkthdr.csum_flags & CSUM_TSO)) { | if ((ip_off & IP_DF) || | ||||
(m->m_pkthdr.csum_flags & (CSUM_TSO | CSUM_INNER_TSO))) { | |||||
error = EMSGSIZE; | error = EMSGSIZE; | ||||
IPSTAT_INC(ips_cantfrag); | IPSTAT_INC(ips_cantfrag); | ||||
goto bad; | goto bad; | ||||
} | } | ||||
/* | /* | ||||
* Too large for interface; fragment if possible. If successful, | * Too large for interface; fragment if possible. If successful, | ||||
* on return, m will point to a list of packets to be sent. | * on return, m will point to a list of packets to be sent. | ||||
▲ Show 20 Lines • Show All 770 Lines • Show Last 20 Lines |