On Wed, May 24, 2023 at 05:28:58PM +0200, Alexander Bluhm wrote:
> On Tue, May 23, 2023 at 02:14:57PM +0200, Jan Klemkow wrote:
> > Hi,
> >
> > This diff sets needed offloading flags and the calculated mss to LRO
> > mbufs in ix(4). Thus, we can forward this packets and process them via
> > tcp_if_output_tso(). This diff also uses tcp_if_output_tso() in
> > ip6_forward().
> >
> > I tested the ip6_forward path via the address family transition in pf:
> >
> > pass in inet from 192.168.1.1 to 192.168.13.2 af-to \
> > inet6 from fc00:13::1 to fc00:13::2
> >
> > ok?
>
> crashes during my tests with lro turned on. Looks like devision
> by zero.
I added a check, that avoids the TSO flags if mss it zero. Thus, we
avoid a division by zero in later TSO processing.
ok?
Thanks,
Jan
Index: dev/pci/if_ix.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_ix.c,v
retrieving revision 1.196
diff -u -p -r1.196 if_ix.c
--- dev/pci/if_ix.c 23 May 2023 09:16:16 -0000 1.196
+++ dev/pci/if_ix.c 25 May 2023 20:02:06 -0000
@@ -3257,13 +3257,40 @@ ixgbe_rxeof(struct rx_ring *rxr)
if (sendmp->m_pkthdr.ph_mss > 0) {
struct ether_extracted ext;
+ uint64_t hlen;
uint16_t pkts = sendmp->m_pkthdr.ph_mss;
+ /* Calculate header size. */
ether_extract_headers(sendmp, &ext);
- if (ext.tcp)
+ hlen = sizeof(*ext.eh);
+ if (ext.ip4) {
+ hlen += ext.ip4->ip_hl << 2;
+ } else if (ext.ip6) {
+ if (ext.ip6->ip6_nxt == IPPROTO_TCP)
+ hlen += sizeof(*ext.ip6);
+ else
+ tcpstat_inc(tcps_inbadlro);
+ }
+ if (ext.tcp) {
tcpstat_inc(tcps_inhwlro);
- else
+ hlen += ext.tcp->th_off << 2;
+ } else {
tcpstat_inc(tcps_inbadlro);
+ }
+
+ /*
+ * If we gonna forward this packet, we have to
+ * mark it as TSO, recalculate the TCP checksum
+ * and set a correct mss.
+ */
+ sendmp->m_pkthdr.ph_mss =
+ (sendmp->m_pkthdr.len - hlen) / pkts;
+
+ if (sendmp->m_pkthdr.ph_mss != 0) {
+ SET(sendmp->m_pkthdr.csum_flags,
+ M_TCP_CSUM_OUT | M_TCP_TSO);
+ }
+
tcpstat_add(tcps_inpktlro, pkts);
}
Index: netinet6/ip6_forward.c
===================================================================
RCS file: /cvs/src/sys/netinet6/ip6_forward.c,v
retrieving revision 1.109
diff -u -p -r1.109 ip6_forward.c
--- netinet6/ip6_forward.c 5 Apr 2023 13:56:31 -0000 1.109
+++ netinet6/ip6_forward.c 25 May 2023 20:03:06 -0000
@@ -63,8 +63,10 @@
#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
@@ -316,7 +318,11 @@ reroute:
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) {
@@ -326,6 +332,8 @@ reroute:
m_freem(m);
goto out;
}
+
+ in6_proto_cksum_out(m, ifp);
error = ifp->if_output(ifp, m, sin6tosa(sin6), rt);
if (error) {