From owner-svn-src-all@freebsd.org Sat May 30 02:02:35 2020 Return-Path: Delivered-To: svn-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 766CB2F6F2C; Sat, 30 May 2020 02:02:35 +0000 (UTC) (envelope-from karels@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 49Yl7b2Zy7z3bhM; Sat, 30 May 2020 02:02:35 +0000 (UTC) (envelope-from karels@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 53E9120E75; Sat, 30 May 2020 02:02:35 +0000 (UTC) (envelope-from karels@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 04U22Zcw047750; Sat, 30 May 2020 02:02:35 GMT (envelope-from karels@FreeBSD.org) Received: (from karels@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 04U22ZgW047749; Sat, 30 May 2020 02:02:35 GMT (envelope-from karels@FreeBSD.org) Message-Id: <202005300202.04U22ZgW047749@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: karels set sender to karels@FreeBSD.org using -f From: Mike Karels Date: Sat, 30 May 2020 02:02:35 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r361641 - head/sys/arm64/broadcom/genet X-SVN-Group: head X-SVN-Commit-Author: karels X-SVN-Commit-Paths: head/sys/arm64/broadcom/genet X-SVN-Commit-Revision: 361641 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.33 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 30 May 2020 02:02:35 -0000 Author: karels Date: Sat May 30 02:02:34 2020 New Revision: 361641 URL: https://svnweb.freebsd.org/changeset/base/361641 Log: genet: fix issues with transmit checksum offload Fix problem with ICMP echo replies: check only deferred data checksum flags, and not the received checksum status bits, when checking whether a packet has a deferred checksum; otherwise echo replies are corrupted because the received checksum status bits are still present. Fix some unhandled cases in packet shuffling for checksum offload. Modified: head/sys/arm64/broadcom/genet/if_genet.c Modified: head/sys/arm64/broadcom/genet/if_genet.c ============================================================================== --- head/sys/arm64/broadcom/genet/if_genet.c Sat May 30 01:48:12 2020 (r361640) +++ head/sys/arm64/broadcom/genet/if_genet.c Sat May 30 02:02:34 2020 (r361641) @@ -948,6 +948,9 @@ gen_start(if_t ifp) GEN_UNLOCK(sc); } +/* Test for any delayed checksum */ +#define CSUM_DELAY_ANY (CSUM_TCP | CSUM_UDP | CSUM_IP6_TCP | CSUM_IP6_UDP) + static int gen_encap(struct gen_softc *sc, struct mbuf **mp) { @@ -978,12 +981,11 @@ gen_encap(struct gen_softc *sc, struct mbuf **mp) } offset = gen_parse_tx(m, csum_flags); sb = mtod(m, struct statusblock *); - if (csum_flags != 0) { + if ((csum_flags & CSUM_DELAY_ANY) != 0) { csuminfo = (offset << TXCSUM_OFF_SHIFT) | (offset + csumdata); - if (csum_flags & (CSUM_TCP | CSUM_UDP)) - csuminfo |= TXCSUM_LEN_VALID; - if (csum_flags & CSUM_UDP) + csuminfo |= TXCSUM_LEN_VALID; + if (csum_flags & (CSUM_UDP | CSUM_IP6_UDP)) csuminfo |= TXCSUM_UDP; sb->txcsuminfo = csuminfo; } else @@ -1045,7 +1047,7 @@ gen_encap(struct gen_softc *sc, struct mbuf **mp) if (i == 0) { length_status |= GENET_TX_DESC_STATUS_SOP | GENET_TX_DESC_STATUS_CRC; - if (csum_flags != 0) + if ((csum_flags & CSUM_DELAY_ANY) != 0) length_status |= GENET_TX_DESC_STATUS_CKSUM; } if (i == nsegs - 1) @@ -1087,6 +1089,7 @@ static int gen_parse_tx(struct mbuf *m, int csum_flags) { int offset, off_in_m; + bool copy = false, shift = false; u_char *p, *copy_p = NULL; struct mbuf *m0 = m; uint16_t ether_type; @@ -1098,22 +1101,44 @@ gen_parse_tx(struct mbuf *m, int csum_flags) m = m->m_next; off_in_m = 0; p = mtod(m, u_char *); + copy = true; } else { + /* + * If statusblock is not at beginning of mbuf (likely), + * then remember to move mbuf contents down before copying + * after them. + */ + if ((m->m_flags & M_EXT) == 0 && m->m_data != m->m_pktdat) + shift = true; p = mtodo(m, sizeof(struct statusblock)); off_in_m = sizeof(struct statusblock); } -/* If headers need to be copied contiguous to statusblock, do so. */ -#define COPY(size) { \ - if (copy_p != NULL) { \ - int hsize = size; \ - bcopy(p, copy_p, hsize); \ - m0->m_len += hsize; \ - m0->m_pkthdr.len += hsize; /* unneeded */ \ - copy_p += hsize; \ - m->m_len -= hsize; \ - m->m_data += hsize; \ - } \ +/* + * If headers need to be copied contiguous to statusblock, do so. + * If copying to the internal mbuf data area, and the status block + * is not at the beginning of that area, shift the status block (which + * is empty) and following data. + */ +#define COPY(size) { \ + int hsize = size; \ + if (copy) { \ + if (shift) { \ + u_char *p0; \ + shift = false; \ + p0 = mtodo(m0, sizeof(struct statusblock)); \ + m0->m_data = m0->m_pktdat; \ + bcopy(p0, mtodo(m0, sizeof(struct statusblock)),\ + m0->m_len - sizeof(struct statusblock)); \ + copy_p = mtodo(m0, sizeof(struct statusblock)); \ + } \ + bcopy(p, copy_p, hsize); \ + m0->m_len += hsize; \ + m0->m_pkthdr.len += hsize; /* unneeded */ \ + m->m_len -= hsize; \ + m->m_data += hsize; \ + } \ + copy_p += hsize; \ } KASSERT((sizeof(struct statusblock) + sizeof(struct ether_vlan_header) + @@ -1127,6 +1152,7 @@ gen_parse_tx(struct mbuf *m, int csum_flags) m = m->m_next; off_in_m = 0; p = mtod(m, u_char *); + copy = true; } else { off_in_m += sizeof(struct ether_vlan_header); p += sizeof(struct ether_vlan_header); @@ -1139,6 +1165,7 @@ gen_parse_tx(struct mbuf *m, int csum_flags) m = m->m_next; off_in_m = 0; p = mtod(m, u_char *); + copy = true; } else { off_in_m += sizeof(struct ether_header); p += sizeof(struct ether_header);