summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/net/if.h4
-rw-r--r--sys/net/if_loop.c27
-rw-r--r--sys/netinet/tcp_input.c2
-rw-r--r--sys/netinet/tcp_output.c3
-rw-r--r--sys/netinet/tcp_subr.c3
-rw-r--r--sys/netinet/tcp_syncache.c3
-rw-r--r--sys/netinet/tcp_timewait.c3
-rw-r--r--sys/netinet6/ip6_forward.c8
-rw-r--r--sys/netinet6/ip6_ipsec.c1
-rw-r--r--sys/netinet6/ip6_output.c18
-rw-r--r--sys/netinet6/udp6_usrreq.c4
-rw-r--r--sys/sys/mbuf.h11
12 files changed, 60 insertions, 27 deletions
diff --git a/sys/net/if.h b/sys/net/if.h
index 47292cb..05be58f 100644
--- a/sys/net/if.h
+++ b/sys/net/if.h
@@ -230,6 +230,10 @@ struct if_data {
#define IFCAP_VLAN_HWTSO 0x40000 /* can do IFCAP_TSO on VLANs */
#define IFCAP_LINKSTATE 0x80000 /* the runtime link state is dynamic */
#define IFCAP_NETMAP 0x100000 /* netmap mode supported/enabled */
+#define IFCAP_RXCSUM_IPV6 0x200000 /* can offload checksum on IPv6 RX */
+#define IFCAP_TXCSUM_IPV6 0x400000 /* can offload checksum on IPv6 TX */
+
+#define IFCAP_HWCSUM_IPV6 (IFCAP_RXCSUM_IPV6 | IFCAP_TXCSUM_IPV6)
#define IFCAP_HWCSUM (IFCAP_RXCSUM | IFCAP_TXCSUM)
#define IFCAP_TSO (IFCAP_TSO4 | IFCAP_TSO6)
diff --git a/sys/net/if_loop.c b/sys/net/if_loop.c
index 80e0eea..23eb450 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:
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index 5a94c6e..292dd6b 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -589,7 +589,7 @@ tcp_input(struct mbuf *m, int off0)
ip6 = mtod(m, struct ip6_hdr *);
th = (struct tcphdr *)((caddr_t)ip6 + off0);
tlen = sizeof(*ip6) + ntohs(ip6->ip6_plen) - off0;
- if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) {
+ if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID_IPV6) {
if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR)
th->th_sum = m->m_pkthdr.csum_data;
else
diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c
index e3cfbea..8e0f369 100644
--- a/sys/netinet/tcp_output.c
+++ b/sys/netinet/tcp_output.c
@@ -1047,7 +1047,6 @@ send:
* checksum extended header and data.
*/
m->m_pkthdr.len = hdrlen + len; /* in6_cksum() need this */
- m->m_pkthdr.csum_flags = CSUM_TCP;
m->m_pkthdr.csum_data = offsetof(struct tcphdr, th_sum);
#ifdef INET6
if (isipv6) {
@@ -1055,6 +1054,7 @@ send:
* ip6_plen is not need to be filled now, and will be filled
* in ip6_output.
*/
+ m->m_pkthdr.csum_flags = CSUM_TCP_IPV6;
th->th_sum = in6_cksum_pseudo(ip6, sizeof(struct tcphdr) +
optlen + len, IPPROTO_TCP, 0);
}
@@ -1064,6 +1064,7 @@ send:
#endif
#ifdef INET
{
+ m->m_pkthdr.csum_flags = CSUM_TCP;
th->th_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr,
htons(sizeof(struct tcphdr) + IPPROTO_TCP + len + optlen));
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
index 108d64e..05da82e 100644
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -619,10 +619,10 @@ tcp_respond(struct tcpcb *tp, void *ipgen, struct tcphdr *th, struct mbuf *m,
nth->th_win = htons((u_short)win);
nth->th_urp = 0;
- m->m_pkthdr.csum_flags = CSUM_TCP;
m->m_pkthdr.csum_data = offsetof(struct tcphdr, th_sum);
#ifdef INET6
if (isipv6) {
+ m->m_pkthdr.csum_flags = CSUM_TCP_IPV6;
nth->th_sum = in6_cksum_pseudo(ip6,
tlen - sizeof(struct ip6_hdr), IPPROTO_TCP, 0);
ip6->ip6_hlim = in6_selecthlim(tp != NULL ? tp->t_inpcb :
@@ -634,6 +634,7 @@ tcp_respond(struct tcpcb *tp, void *ipgen, struct tcphdr *th, struct mbuf *m,
#endif
#ifdef INET
{
+ m->m_pkthdr.csum_flags = CSUM_TCP;
nth->th_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr,
htons((u_short)(tlen - sizeof(struct ip) + ip->ip_p)));
}
diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c
index fcac95f..21a72f4 100644
--- a/sys/netinet/tcp_syncache.c
+++ b/sys/netinet/tcp_syncache.c
@@ -1473,10 +1473,10 @@ syncache_respond(struct syncache *sc)
optlen = 0;
M_SETFIB(m, sc->sc_inc.inc_fibnum);
- m->m_pkthdr.csum_flags = CSUM_TCP;
m->m_pkthdr.csum_data = offsetof(struct tcphdr, th_sum);
#ifdef INET6
if (sc->sc_inc.inc_flags & INC_ISIPV6) {
+ m->m_pkthdr.csum_flags = CSUM_TCP_IPV6;
th->th_sum = in6_cksum_pseudo(ip6, tlen + optlen - hlen,
IPPROTO_TCP, 0);
ip6->ip6_hlim = in6_selecthlim(NULL, NULL);
@@ -1488,6 +1488,7 @@ syncache_respond(struct syncache *sc)
#endif
#ifdef INET
{
+ m->m_pkthdr.csum_flags = CSUM_TCP;
th->th_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr,
htons(tlen + optlen - hlen + IPPROTO_TCP));
error = ip_output(m, sc->sc_ipopts, NULL, 0, NULL, NULL);
diff --git a/sys/netinet/tcp_timewait.c b/sys/netinet/tcp_timewait.c
index 3be23dc..397aaae 100644
--- a/sys/netinet/tcp_timewait.c
+++ b/sys/netinet/tcp_timewait.c
@@ -574,10 +574,10 @@ tcp_twrespond(struct tcptw *tw, int flags)
th->th_flags = flags;
th->th_win = htons(tw->last_win);
- m->m_pkthdr.csum_flags = CSUM_TCP;
m->m_pkthdr.csum_data = offsetof(struct tcphdr, th_sum);
#ifdef INET6
if (isipv6) {
+ m->m_pkthdr.csum_flags = CSUM_TCP_IPV6;
th->th_sum = in6_cksum_pseudo(ip6,
sizeof(struct tcphdr) + optlen, IPPROTO_TCP, 0);
ip6->ip6_hlim = in6_selecthlim(inp, NULL);
@@ -590,6 +590,7 @@ tcp_twrespond(struct tcptw *tw, int flags)
#endif
#ifdef INET
{
+ m->m_pkthdr.csum_flags = CSUM_TCP;
th->th_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr,
htons(sizeof(struct tcphdr) + optlen + IPPROTO_TCP));
ip->ip_len = m->m_pkthdr.len;
diff --git a/sys/netinet6/ip6_forward.c b/sys/netinet6/ip6_forward.c
index dfecdc1..93c7bf2 100644
--- a/sys/netinet6/ip6_forward.c
+++ b/sys/netinet6/ip6_forward.c
@@ -581,9 +581,9 @@ skip_routing:
m->m_flags |= M_FASTFWD_OURS;
if (m->m_pkthdr.rcvif == NULL)
m->m_pkthdr.rcvif = V_loif;
- if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
+ if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA_IPV6) {
m->m_pkthdr.csum_flags |=
- CSUM_DATA_VALID | CSUM_PSEUDO_HDR;
+ CSUM_DATA_VALID_IPV6 | CSUM_PSEUDO_HDR;
m->m_pkthdr.csum_data = 0xffff;
}
#ifdef SCTP
@@ -601,9 +601,9 @@ skip_routing:
if (m->m_flags & M_FASTFWD_OURS) {
if (m->m_pkthdr.rcvif == NULL)
m->m_pkthdr.rcvif = V_loif;
- if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
+ if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA_IPV6) {
m->m_pkthdr.csum_flags |=
- CSUM_DATA_VALID | CSUM_PSEUDO_HDR;
+ CSUM_DATA_VALID_IPV6 | CSUM_PSEUDO_HDR;
m->m_pkthdr.csum_data = 0xffff;
}
#ifdef SCTP
diff --git a/sys/netinet6/ip6_ipsec.c b/sys/netinet6/ip6_ipsec.c
index e868917..757f1cc 100644
--- a/sys/netinet6/ip6_ipsec.c
+++ b/sys/netinet6/ip6_ipsec.c
@@ -291,6 +291,7 @@ ip6_ipsec_output(struct mbuf **m, struct inpcb *inp, int *flags, int *error,
/*
* Do delayed checksums now because we send before
* this is done in the normal processing path.
+ * XXX-BZ CSUM_DELAY_DATA_IPV6?
*/
if ((*m)->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
ipseclog((LOG_DEBUG,
diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c
index ec2d9bd..fddb45b 100644
--- a/sys/netinet6/ip6_output.c
+++ b/sys/netinet6/ip6_output.c
@@ -190,7 +190,7 @@ in6_delayed_cksum(struct mbuf *m, uint32_t plen, u_short offset)
u_short csum;
csum = in_cksum_skip(m, offset + plen, offset);
- if (m->m_pkthdr.csum_flags & CSUM_UDP && csum == 0)
+ if (m->m_pkthdr.csum_flags & CSUM_UDP_IPV6 && csum == 0)
csum = 0xffff;
offset += m->m_pkthdr.csum_data; /* checksum offset */
@@ -885,9 +885,9 @@ again:
m->m_flags |= M_FASTFWD_OURS;
if (m->m_pkthdr.rcvif == NULL)
m->m_pkthdr.rcvif = V_loif;
- if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
+ if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA_IPV6) {
m->m_pkthdr.csum_flags |=
- CSUM_DATA_VALID | CSUM_PSEUDO_HDR;
+ CSUM_DATA_VALID_IPV6 | CSUM_PSEUDO_HDR;
m->m_pkthdr.csum_data = 0xffff;
}
#ifdef SCTP
@@ -905,9 +905,9 @@ again:
if (m->m_flags & M_FASTFWD_OURS) {
if (m->m_pkthdr.rcvif == NULL)
m->m_pkthdr.rcvif = V_loif;
- if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
+ if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA_IPV6) {
m->m_pkthdr.csum_flags |=
- CSUM_DATA_VALID | CSUM_PSEUDO_HDR;
+ CSUM_DATA_VALID_IPV6 | CSUM_PSEUDO_HDR;
m->m_pkthdr.csum_data = 0xffff;
}
#ifdef SCTP
@@ -960,8 +960,8 @@ passout:
* XXX-BZ Need a framework to know when the NIC can handle it, even
* with ext. hdrs.
*/
- if (sw_csum & CSUM_DELAY_DATA) {
- sw_csum &= ~CSUM_DELAY_DATA;
+ if (sw_csum & CSUM_DELAY_DATA_IPV6) {
+ sw_csum &= ~CSUM_DELAY_DATA_IPV6;
in6_delayed_cksum(m, plen, sizeof(struct ip6_hdr));
}
#ifdef SCTP
@@ -1076,9 +1076,9 @@ passout:
* fragmented packets, then do it here.
* XXX-BZ handle the hw offloading case. Need flags.
*/
- if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
+ if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA_IPV6) {
in6_delayed_cksum(m, plen, hlen);
- m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
+ m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA_IPV6;
}
#ifdef SCTP
if (m->m_pkthdr.csum_flags & CSUM_SCTP) {
diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c
index 9d10dee..c43d958 100644
--- a/sys/netinet6/udp6_usrreq.c
+++ b/sys/netinet6/udp6_usrreq.c
@@ -230,7 +230,7 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
goto badunlocked;
}
- if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) {
+ if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID_IPV6) {
if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR)
uh_sum = m->m_pkthdr.csum_data;
else
@@ -784,7 +784,7 @@ udp6_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr6,
ip6->ip6_dst = *faddr;
udp6->uh_sum = in6_cksum_pseudo(ip6, plen, IPPROTO_UDP, 0);
- m->m_pkthdr.csum_flags = CSUM_UDP;
+ m->m_pkthdr.csum_flags = CSUM_UDP_IPV6;
m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum);
flags = 0;
diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h
index 2a6c8aa..679f86e 100644
--- a/sys/sys/mbuf.h
+++ b/sys/sys/mbuf.h
@@ -283,15 +283,24 @@ struct mbuf {
#define CSUM_FRAGMENT 0x0010 /* will do IP fragmentation */
#define CSUM_TSO 0x0020 /* will do TSO */
#define CSUM_SCTP 0x0040 /* will csum SCTP */
+/* CSUM_SCTP_IPV6 0x0080 will csum IPv6/SCTP */
#define CSUM_IP_CHECKED 0x0100 /* did csum IP */
#define CSUM_IP_VALID 0x0200 /* ... the csum is valid */
#define CSUM_DATA_VALID 0x0400 /* csum_data field is valid */
#define CSUM_PSEUDO_HDR 0x0800 /* csum_data has pseudo hdr */
#define CSUM_SCTP_VALID 0x1000 /* SCTP checksum is valid */
+#define CSUM_UDP_IPV6 0x2000 /* will csum IPv6/UDP */
+#define CSUM_TCP_IPV6 0x4000 /* will csum IPv6/TCP */
+/* CSUM_TSO_IPV6 0x8000 will do IPv6/TSO */
+
+/* CSUM_FRAGMENT_IPV6 0x10000 will do IPv6 fragementation */
+
+#define CSUM_DELAY_DATA_IPV6 (CSUM_TCP_IPV6 | CSUM_UDP_IPV6)
+#define CSUM_DATA_VALID_IPV6 CSUM_DATA_VALID
#define CSUM_DELAY_DATA (CSUM_TCP | CSUM_UDP)
-#define CSUM_DELAY_IP (CSUM_IP) /* XXX add ipv6 here too? */
+#define CSUM_DELAY_IP (CSUM_IP) /* Only v4, no v6 IP hdr csum */
/*
* mbuf types.
OpenPOWER on IntegriCloud