aboutsummaryrefslogtreecommitdiff
path: root/sys/net/if_loop.c
diff options
context:
space:
mode:
authorBjoern A. Zeeb <bz@FreeBSD.org>2012-05-28 09:30:13 +0000
committerBjoern A. Zeeb <bz@FreeBSD.org>2012-05-28 09:30:13 +0000
commit356ab07e2dba0f8e7300f2ffc2cf1c175aad34a8 (patch)
tree5f5a5c87a324064ee224e0476ab7846e52c50a3d /sys/net/if_loop.c
parent81174e787263a18dbd1fcc6b8cf211d314d170ae (diff)
It turns out that too many drivers are not only parsing the L2/3/4
headers for TSO but also for generic checksum offloading. Ideally we would only have one common function shared amongst all drivers, and perhaps when updating them for IPv6 we should introduce that. Eventually we should provide the meta information along with mbufs to avoid (re-)parsing entirely. To not break IPv6 (checksums and offload) and to be able to MFC the changes without risking to hurt 3rd party drivers, duplicate the v4 framework, as other OSes have done as well. Introduce interface capability flags for TX/RX checksum offload with IPv6, to allow independent toggling (where possible). Add CSUM_*_IPV6 flags for UDP/TCP over IPv6, and reserve further for SCTP, and IPv6 fragmentation. Define CSUM_DELAY_DATA_IPV6 as we do for legacy IP and add an alias for CSUM_DATA_VALID_IPV6. This pretty much brings IPv6 handling in line with IPv4. TSO is still handled in a different way and not via if_hwassist. Update ifconfig to allow (un)setting of the new capability flags. Update loopback to announce the new capabilities and if_hwassist flags. Individual driver updates will have to follow, as will SCTP. Reported by: gallatin, dim, .. Reviewed by: gallatin (glanced at?) MFC after: 3 days X-MFC with: r235961,235959,235958
Notes
svn path=/head/; revision=236170
Diffstat (limited to 'sys/net/if_loop.c')
-rw-r--r--sys/net/if_loop.c27
1 files changed, 21 insertions, 6 deletions
diff --git a/sys/net/if_loop.c b/sys/net/if_loop.c
index 80e0eead5141..23eb450f3f41 100644
--- a/sys/net/if_loop.c
+++ b/sys/net/if_loop.c
@@ -92,7 +92,9 @@
#endif
#define LO_CSUM_FEATURES (CSUM_IP | CSUM_TCP | CSUM_UDP | CSUM_SCTP)
-#define LO_CSUM_SET (CSUM_DATA_VALID | CSUM_PSEUDO_HDR | \
+#define LO_CSUM_FEATURES6 (CSUM_TCP_IPV6 | CSUM_UDP_IPV6 | CSUM_SCTP)
+#define LO_CSUM_SET (CSUM_DATA_VALID | CSUM_DATA_VALID_IPV6 | \
+ CSUM_PSEUDO_HDR | \
CSUM_IP_CHECKED | CSUM_IP_VALID | \
CSUM_SCTP_VALID)
@@ -143,8 +145,9 @@ lo_clone_create(struct if_clone *ifc, int unit, caddr_t params)
ifp->if_ioctl = loioctl;
ifp->if_output = looutput;
ifp->if_snd.ifq_maxlen = ifqmaxlen;
- ifp->if_capabilities = ifp->if_capenable = IFCAP_HWCSUM;
- ifp->if_hwassist = LO_CSUM_FEATURES;
+ ifp->if_capabilities = ifp->if_capenable =
+ IFCAP_HWCSUM | IFCAP_HWCSUM_IPV6;
+ ifp->if_hwassist = LO_CSUM_FEATURES | LO_CSUM_FEATURES6;
if_attach(ifp);
bpfattach(ifp, DLT_NULL, sizeof(u_int32_t));
if (V_loif == NULL)
@@ -247,12 +250,19 @@ looutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
#if 1 /* XXX */
switch (dst->sa_family) {
case AF_INET:
- case AF_INET6:
if (ifp->if_capenable & IFCAP_RXCSUM) {
m->m_pkthdr.csum_data = 0xffff;
m->m_pkthdr.csum_flags = LO_CSUM_SET;
}
m->m_pkthdr.csum_flags &= ~LO_CSUM_FEATURES;
+ break;
+ case AF_INET6:
+ if (ifp->if_capenable & IFCAP_RXCSUM_IPV6) {
+ m->m_pkthdr.csum_data = 0xffff;
+ m->m_pkthdr.csum_flags = LO_CSUM_SET;
+ }
+ m->m_pkthdr.csum_flags &= ~LO_CSUM_FEATURES6;
+ break;
case AF_IPX:
case AF_APPLETALK:
break;
@@ -436,10 +446,15 @@ loioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
ifp->if_capenable ^= IFCAP_RXCSUM;
if ((mask & IFCAP_TXCSUM) != 0)
ifp->if_capenable ^= IFCAP_TXCSUM;
+ if ((mask & IFCAP_RXCSUM_IPV6) != 0)
+ ifp->if_capenable ^= IFCAP_RXCSUM_IPV6;
+ if ((mask & IFCAP_TXCSUM_IPV6) != 0)
+ ifp->if_capenable ^= IFCAP_TXCSUM_IPV6;
+ ifp->if_hwassist = 0;
if (ifp->if_capenable & IFCAP_TXCSUM)
ifp->if_hwassist = LO_CSUM_FEATURES;
- else
- ifp->if_hwassist = 0;
+ if (ifp->if_capenable & IFCAP_TXCSUM_IPV6)
+ ifp->if_hwassist |= LO_CSUM_FEATURES6;
break;
default: