Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/xen/xen add support for skipping IPv6 checksum vali...
details: https://anonhg.NetBSD.org/src/rev/41180140d2b9
branches: trunk
changeset: 970366:41180140d2b9
user: jdolecek <jdolecek%NetBSD.org@localhost>
date: Sun Mar 22 00:11:02 2020 +0000
description:
add support for skipping IPv6 checksum validation aka offloading -
for xennet(4) both Rx and Tx, for xvif(4) only Tx for now
diffstat:
sys/arch/xen/xen/if_xennet_xenbus.c | 16 +++-
sys/arch/xen/xen/xennet_checksum.c | 115 ++++++++++++++++++++++++++--------
sys/arch/xen/xen/xennetback_xenbus.c | 16 +++-
3 files changed, 108 insertions(+), 39 deletions(-)
diffs (300 lines):
diff -r 678ca50d615f -r 41180140d2b9 sys/arch/xen/xen/if_xennet_xenbus.c
--- a/sys/arch/xen/xen/if_xennet_xenbus.c Sun Mar 22 00:05:17 2020 +0000
+++ b/sys/arch/xen/xen/if_xennet_xenbus.c Sun Mar 22 00:11:02 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_xennet_xenbus.c,v 1.92 2020/03/19 10:53:43 jdolecek Exp $ */
+/* $NetBSD: if_xennet_xenbus.c,v 1.93 2020/03/22 00:11:02 jdolecek Exp $ */
/*
* Copyright (c) 2006 Manuel Bouyer.
@@ -84,7 +84,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_xennet_xenbus.c,v 1.92 2020/03/19 10:53:43 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_xennet_xenbus.c,v 1.93 2020/03/22 00:11:02 jdolecek Exp $");
#include "opt_xen.h"
#include "opt_nfs_boot.h"
@@ -389,7 +389,14 @@
ifp->if_capabilities =
IFCAP_CSUM_IPv4_Rx | IFCAP_CSUM_IPv4_Tx
| IFCAP_CSUM_UDPv4_Rx | IFCAP_CSUM_UDPv4_Tx
- | IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_TCPv4_Tx;
+ | IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_TCPv4_Tx
+ | IFCAP_CSUM_UDPv6_Rx | IFCAP_CSUM_UDPv6_Tx
+ | IFCAP_CSUM_TCPv6_Rx | IFCAP_CSUM_TCPv6_Tx;
+#define XN_M_CSUM_SUPPORTED ( \
+ M_CSUM_TCPv4 | M_CSUM_UDPv4 | M_CSUM_IPv4 \
+ | M_CSUM_TCPv6 | M_CSUM_UDPv6 \
+ )
+
IFQ_SET_READY(&ifp->if_snd);
if_attach(ifp);
ether_ifattach(ifp, sc->sc_enaddr);
@@ -1229,8 +1236,7 @@
break;
}
- if ((m->m_pkthdr.csum_flags &
- (M_CSUM_TCPv4 | M_CSUM_UDPv4 | M_CSUM_IPv4)) != 0) {
+ if ((m->m_pkthdr.csum_flags & XN_M_CSUM_SUPPORTED) != 0) {
txflags = NETTXF_csum_blank;
} else {
txflags = NETTXF_data_validated;
diff -r 678ca50d615f -r 41180140d2b9 sys/arch/xen/xen/xennet_checksum.c
--- a/sys/arch/xen/xen/xennet_checksum.c Sun Mar 22 00:05:17 2020 +0000
+++ b/sys/arch/xen/xen/xennet_checksum.c Sun Mar 22 00:11:02 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: xennet_checksum.c,v 1.8 2020/03/19 10:53:43 jdolecek Exp $ */
+/* $NetBSD: xennet_checksum.c,v 1.9 2020/03/22 00:11:02 jdolecek Exp $ */
/*-
* Copyright (c)2006 YAMAMOTO Takashi,
@@ -27,7 +27,11 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xennet_checksum.c,v 1.8 2020/03/19 10:53:43 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xennet_checksum.c,v 1.9 2020/03/22 00:11:02 jdolecek Exp $");
+
+#ifdef _KERNEL_OPT
+#include "opt_inet.h"
+#endif
#include <sys/types.h>
#include <sys/param.h>
@@ -43,6 +47,8 @@
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
+#include <netinet/ip6.h>
+#include <netinet6/in6_offload.h>
#include <xen/xennet_checksum.h>
@@ -57,16 +63,15 @@
EVCNT_ATTACH_STATIC(xn_cksum_undefer);
EVCNT_ATTACH_STATIC(xn_cksum_valid);
+#ifdef XENNET_DEBUG
/* ratecheck(9) for checksum validation failures */
static const struct timeval xn_cksum_errintvl = { 600, 0 }; /* 10 min, each */
+#endif
static void *
m_extract(struct mbuf *m, int off, int len)
{
- KASSERT(m->m_pkthdr.len >= off + len);
- KASSERT(m->m_len >= off + len);
-
- if (m->m_pkthdr.len >= off + len)
+ if (m->m_len >= off + len)
return mtod(m, char *) + off;
else
return NULL;
@@ -80,7 +85,10 @@
xennet_checksum_fill(struct ifnet *ifp, struct mbuf *m, bool data_validated)
{
const struct ether_header *eh;
- struct ip *iph;
+ struct ip *iph = NULL;
+#ifdef INET6
+ struct ip6_hdr *ip6h = NULL;
+#endif
int ehlen;
int iphlen;
int iplen;
@@ -98,27 +106,49 @@
return EINVAL;
}
etype = eh->ether_type;
- if (etype == htobe16(ETHERTYPE_VLAN)) {
- ehlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
- } else if (etype == htobe16(ETHERTYPE_IP)) {
- ehlen = ETHER_HDR_LEN;
- } else {
- static struct timeval lasttime;
- if (ratecheck(&lasttime, &xn_cksum_errintvl))
- printf("%s: unknown etype %#x passed%s\n",
- ifp->if_xname, ntohs(etype),
- data_validated ? "" : " no checksum");
- return EINVAL;
+ ehlen = ETHER_HDR_LEN;
+ if (__predict_false(etype == htons(ETHERTYPE_VLAN))) {
+ struct ether_vlan_header *evl = m_extract(m, 0, sizeof(*evl));
+ if (evl == NULL) {
+ /* Too short, packet will be dropped by upper layer */
+ return EINVAL;
+ }
+ ehlen += ETHER_VLAN_ENCAP_LEN;
+ etype = ntohs(evl->evl_proto);
}
- iph = m_extract(m, ehlen, sizeof(*iph));
- if (iph == NULL) {
- /* Too short, packet will be dropped by upper layer */
- return EINVAL;
+ switch (etype) {
+ case htons(ETHERTYPE_IP):
+ iph = m_extract(m, ehlen, sizeof(*iph));
+ if (iph == NULL) {
+ /* Too short, packet will be dropped by upper layer */
+ return EINVAL;
+ }
+ nxt = iph->ip_p;
+ iphlen = iph->ip_hl << 2;
+ iplen = ntohs(iph->ip_len);
+ break;
+#ifdef INET6
+ case htons(ETHERTYPE_IPV6):
+ ip6h = m_extract(m, ehlen, sizeof(*ip6h));
+ if (ip6h == NULL) {
+ /* Too short, packet will be dropped by upper layer */
+ return EINVAL;
+ }
+ if ((ip6h->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) {
+ /* Bad version */
+ return EINVAL;
+ }
+ nxt = ip6h->ip6_nxt;
+ iphlen = sizeof(*ip6h);
+ iplen = ntohs(ip6h->ip6_plen);
+ break;
+#endif
+ default:
+ /* Not supported ethernet type */
+ return EOPNOTSUPP;
}
- nxt = iph->ip_p;
- iphlen = iph->ip_hl << 2;
- iplen = ntohs(iph->ip_len);
+
if (ehlen + iplen > m->m_pkthdr.len) {
/* Too short, packet will be dropped by upper layer */
return EINVAL;
@@ -126,27 +156,47 @@
switch (nxt) {
case IPPROTO_UDP:
- m->m_pkthdr.csum_flags = M_CSUM_UDPv4 | M_CSUM_IPv4;
+ if (iph)
+ m->m_pkthdr.csum_flags = M_CSUM_UDPv4 | M_CSUM_IPv4;
+#ifdef INET6
+ else
+ m->m_pkthdr.csum_flags = M_CSUM_UDPv6;
+#endif
m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum);
m->m_pkthdr.csum_data |= iphlen << 16;
break;
case IPPROTO_TCP:
- m->m_pkthdr.csum_flags = M_CSUM_TCPv4 | M_CSUM_IPv4;
+ if (iph)
+ m->m_pkthdr.csum_flags = M_CSUM_TCPv4 | M_CSUM_IPv4;
+#ifdef INET6
+ else
+ m->m_pkthdr.csum_flags = M_CSUM_TCPv6;
+#endif
m->m_pkthdr.csum_data = offsetof(struct tcphdr, th_sum);
m->m_pkthdr.csum_data |= iphlen << 16;
break;
case IPPROTO_ICMP:
case IPPROTO_IGMP:
- m->m_pkthdr.csum_flags = M_CSUM_IPv4;
+ if (iph)
+ m->m_pkthdr.csum_flags = M_CSUM_IPv4;
m->m_pkthdr.csum_data = iphlen << 16;
break;
+ case IPPROTO_HOPOPTS:
+ case IPPROTO_ICMPV6:
+ case IPPROTO_FRAGMENT:
+ /* nothing to do */
+ error = 0;
+ goto out;
+ /* NOTREACHED */
default:
{
+#ifdef XENNET_DEBUG
static struct timeval lasttime;
if (ratecheck(&lasttime, &xn_cksum_errintvl))
printf("%s: unknown proto %d passed%s\n",
ifp->if_xname, nxt,
data_validated ? "" : " no checksum");
+#endif /* XENNET_DEBUG */
error = EINVAL;
goto out;
}
@@ -163,7 +213,7 @@
* checksumming requires this. in_undefer_cksum()
* also needs it to be zero.
*/
- if (m->m_pkthdr.csum_flags & M_CSUM_IPv4)
+ if (iph != NULL && (m->m_pkthdr.csum_flags & M_CSUM_IPv4))
iph->ip_sum = 0;
if (sw_csum & (M_CSUM_IPv4|M_CSUM_UDPv4|M_CSUM_TCPv4)) {
@@ -171,6 +221,13 @@
sw_csum & (M_CSUM_IPv4|M_CSUM_UDPv4|M_CSUM_TCPv4));
}
+#ifdef INET6
+ if (sw_csum & (M_CSUM_UDPv6|M_CSUM_TCPv6)) {
+ in6_undefer_cksum(m, ehlen,
+ sw_csum & (M_CSUM_UDPv6|M_CSUM_TCPv6));
+ }
+#endif
+
if (m->m_pkthdr.csum_flags != 0) {
xn_cksum_defer.ev_count++;
#ifdef M_CSUM_BLANK
diff -r 678ca50d615f -r 41180140d2b9 sys/arch/xen/xen/xennetback_xenbus.c
--- a/sys/arch/xen/xen/xennetback_xenbus.c Sun Mar 22 00:05:17 2020 +0000
+++ b/sys/arch/xen/xen/xennetback_xenbus.c Sun Mar 22 00:11:02 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: xennetback_xenbus.c,v 1.83 2020/03/21 23:25:53 jdolecek Exp $ */
+/* $NetBSD: xennetback_xenbus.c,v 1.84 2020/03/22 00:11:02 jdolecek Exp $ */
/*
* Copyright (c) 2006 Manuel Bouyer.
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xennetback_xenbus.c,v 1.83 2020/03/21 23:25:53 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xennetback_xenbus.c,v 1.84 2020/03/22 00:11:02 jdolecek Exp $");
#include "opt_xen.h"
@@ -306,7 +306,13 @@
ifp->if_capabilities =
IFCAP_CSUM_IPv4_Tx
| IFCAP_CSUM_UDPv4_Tx
- | IFCAP_CSUM_TCPv4_Tx;
+ | IFCAP_CSUM_TCPv4_Tx
+ | IFCAP_CSUM_UDPv6_Tx
+ | IFCAP_CSUM_TCPv6_Tx;
+#define XN_M_CSUM_SUPPORTED ( \
+ M_CSUM_TCPv4 | M_CSUM_UDPv4 | M_CSUM_IPv4 \
+ | M_CSUM_TCPv6 | M_CSUM_UDPv6 \
+ )
ifp->if_ioctl = xennetback_ifioctl;
ifp->if_start = xennetback_ifstart;
ifp->if_watchdog = xennetback_ifwatchdog;
@@ -1050,7 +1056,7 @@
rxresp->offset = offset;
rxresp->status = m->m_pkthdr.len;
if ((m->m_pkthdr.csum_flags &
- (M_CSUM_TCPv4 | M_CSUM_UDPv4 | M_CSUM_IPv4)) != 0) {
+ XN_M_CSUM_SUPPORTED) != 0) {
rxresp->flags = NETRXF_csum_blank;
} else {
rxresp->flags = NETRXF_data_validated;
@@ -1366,7 +1372,7 @@
rxresp->offset = 0;
rxresp->status = m->m_pkthdr.len;
if ((m->m_pkthdr.csum_flags &
- (M_CSUM_TCPv4 | M_CSUM_UDPv4 | M_CSUM_IPv4)) != 0) {
+ XN_M_CSUM_SUPPORTED) != 0) {
rxresp->flags = NETRXF_csum_blank;
} else {
rxresp->flags = NETRXF_data_validated;
Home |
Main Index |
Thread Index |
Old Index