diff --git a/sys/net/if_tuntap.c b/sys/net/if_tuntap.c --- a/sys/net/if_tuntap.c +++ b/sys/net/if_tuntap.c @@ -976,7 +976,8 @@ ifp->if_ioctl = tunifioctl; ifp->if_flags = iflags; IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); - ifp->if_capabilities |= IFCAP_LINKSTATE; + ifp->if_capabilities |= + IFCAP_LINKSTATE | IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6; ifp->if_capenable |= IFCAP_LINKSTATE; if ((tp->tun_flags & TUN_L2) != 0) { @@ -1789,6 +1790,24 @@ return (0); } + switch (ntohs(eh->ether_type)) { + case ETHERTYPE_IP: + if (ifp->if_capenable & IFCAP_RXCSUM) { + m->m_pkthdr.csum_flags |= + CSUM_IP_CHECKED | CSUM_IP_VALID; + m->m_pkthdr.csum_flags |= + CSUM_DATA_VALID | CSUM_SCTP_VALID | CSUM_PSEUDO_HDR; + m->m_pkthdr.csum_data = 0xffff; + } + break; + case ETHERTYPE_IPV6: + if (ifp->if_capenable & IFCAP_RXCSUM_IPV6) { + m->m_pkthdr.csum_flags |= + CSUM_DATA_VALID_IPV6 | CSUM_SCTP_VALID | CSUM_PSEUDO_HDR; + m->m_pkthdr.csum_data = 0xffff; + } + break; + } /* Pass packet up to parent. */ CURVNET_SET(ifp->if_vnet); NET_EPOCH_ENTER(et);