diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/net/if.h | 4 | ||||
-rw-r--r-- | sys/net/if_loop.c | 27 | ||||
-rw-r--r-- | sys/netinet/tcp_input.c | 2 | ||||
-rw-r--r-- | sys/netinet/tcp_output.c | 3 | ||||
-rw-r--r-- | sys/netinet/tcp_subr.c | 3 | ||||
-rw-r--r-- | sys/netinet/tcp_syncache.c | 3 | ||||
-rw-r--r-- | sys/netinet/tcp_timewait.c | 3 | ||||
-rw-r--r-- | sys/netinet6/ip6_forward.c | 8 | ||||
-rw-r--r-- | sys/netinet6/ip6_ipsec.c | 1 | ||||
-rw-r--r-- | sys/netinet6/ip6_output.c | 18 | ||||
-rw-r--r-- | sys/netinet6/udp6_usrreq.c | 4 | ||||
-rw-r--r-- | sys/sys/mbuf.h | 11 |
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. |