-/* $OpenBSD: if_ix.c,v 1.196 2023/05/23 09:16:16 jan Exp $ */
+/* $OpenBSD: if_ix.c,v 1.197 2023/06/01 09:05:33 jan Exp $ */
/******************************************************************************
sendmp = NULL;
mp->m_next = nxbuf->buf;
} else { /* Sending this frame? */
+ uint16_t pkts;
+
ixgbe_rx_checksum(staterr, sendmp);
if (hashtype != IXGBE_RXDADV_RSSTYPE_NONE) {
SET(sendmp->m_pkthdr.csum_flags, M_FLOWID);
}
- if (sendmp->m_pkthdr.ph_mss == 1)
- sendmp->m_pkthdr.ph_mss = 0;
+ pkts = sendmp->m_pkthdr.ph_mss;
+ sendmp->m_pkthdr.ph_mss = 0;
- if (sendmp->m_pkthdr.ph_mss > 0) {
+ if (pkts > 1) {
struct ether_extracted ext;
- uint16_t pkts = sendmp->m_pkthdr.ph_mss;
+ uint32_t hdrlen, paylen;
+ /* Calculate header size. */
ether_extract_headers(sendmp, &ext);
- if (ext.tcp)
+ hdrlen = sizeof(*ext.eh);
+ if (ext.ip4)
+ hdrlen += ext.ip4->ip_hl << 2;
+ if (ext.ip6)
+ hdrlen += sizeof(*ext.ip6);
+ if (ext.tcp) {
+ hdrlen += ext.tcp->th_off << 2;
tcpstat_inc(tcps_inhwlro);
- else
+ tcpstat_add(tcps_inpktlro, pkts);
+ } else {
tcpstat_inc(tcps_inbadlro);
- tcpstat_add(tcps_inpktlro, pkts);
+ }
+
+ /*
+ * If we gonna forward this packet, we have to
+ * mark it as TSO, set a correct mss,
+ * and recalculate the TCP checksum.
+ */
+ paylen = sendmp->m_pkthdr.len - hdrlen;
+ if (ext.tcp && paylen >= pkts) {
+ SET(sendmp->m_pkthdr.csum_flags,
+ M_TCP_TSO);
+ sendmp->m_pkthdr.ph_mss = paylen / pkts;
+ }
+ if (ext.tcp &&
+ ISSET(sendmp->m_pkthdr.csum_flags,
+ M_TCP_CSUM_IN_OK)) {
+ SET(sendmp->m_pkthdr.csum_flags,
+ M_TCP_CSUM_OUT);
+ }
}
ml_enqueue(&ml, sendmp);
-/* $OpenBSD: ip6_forward.c,v 1.109 2023/04/05 13:56:31 kn Exp $ */
+/* $OpenBSD: ip6_forward.c,v 1.110 2023/06/01 09:05:33 jan Exp $ */
/* $KAME: ip6_forward.c,v 1.75 2001/06/29 12:42:13 jinmei Exp $ */
/*
#include <netinet/ip_ah.h>
#include <netinet/ip_esp.h>
#include <netinet/udp.h>
-#include <netinet/tcp.h>
#endif
+#include <netinet/tcp.h>
+#include <netinet/tcp_timer.h>
+#include <netinet/tcp_var.h>
/*
* Forward a packet. If some error occurs return the sender
goto reroute;
}
#endif
- in6_proto_cksum_out(m, ifp);
+
+ error = tcp_if_output_tso(ifp, &m, sin6tosa(sin6), rt, IFCAP_TSOv6,
+ ifp->if_mtu);
+ if (error || m == NULL)
+ goto freecopy;
/* Check the size after pf_test to give pf a chance to refragment. */
if (m->m_pkthdr.len > ifp->if_mtu) {
goto out;
}
+ in6_proto_cksum_out(m, ifp);
error = ifp->if_output(ifp, m, sin6tosa(sin6), rt);
if (error) {
ip6stat_inc(ip6s_cantforward);