Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet6/udp6_usrreq.c
Show First 20 Lines • Show All 118 Lines • ▼ Show 20 Lines | |||||
#include <netinet6/in6_rss.h> | #include <netinet6/in6_rss.h> | ||||
#include <netinet6/udp6_var.h> | #include <netinet6/udp6_var.h> | ||||
#include <netinet6/scope6_var.h> | #include <netinet6/scope6_var.h> | ||||
#include <netipsec/ipsec_support.h> | #include <netipsec/ipsec_support.h> | ||||
#include <security/mac/mac_framework.h> | #include <security/mac/mac_framework.h> | ||||
VNET_DEFINE(int, zero_checksum_port) = 0; | |||||
#define V_zero_checksum_port VNET(zero_checksum_port) | |||||
SYSCTL_INT(_net_inet6_udp6, OID_AUTO, rfc6935_port, CTLFLAG_VNET | CTLFLAG_RW, | |||||
&VNET_NAME(zero_checksum_port), 0, | |||||
"Zero UDP checksum allowed for traffic to/from this port."); | |||||
/* | /* | ||||
* UDP protocol implementation. | * UDP protocol implementation. | ||||
* Per RFC 768, August, 1980. | * Per RFC 768, August, 1980. | ||||
*/ | */ | ||||
extern struct protosw inetsw[]; | extern struct protosw inetsw[]; | ||||
static void udp6_detach(struct socket *so); | static void udp6_detach(struct socket *so); | ||||
▲ Show 20 Lines • Show All 128 Lines • ▼ Show 20 Lines | if (nxt == IPPROTO_UDPLITE) { | ||||
} | } | ||||
} else { | } else { | ||||
if ((ulen < sizeof(struct udphdr)) || (plen != ulen)) { | if ((ulen < sizeof(struct udphdr)) || (plen != ulen)) { | ||||
UDPSTAT_INC(udps_badlen); | UDPSTAT_INC(udps_badlen); | ||||
goto badunlocked; | goto badunlocked; | ||||
} | } | ||||
if (uh->uh_sum == 0) { | if (uh->uh_sum == 0) { | ||||
UDPSTAT_INC(udps_nosum); | UDPSTAT_INC(udps_nosum); | ||||
/* | |||||
* dport 0 was rejected earlier so this is OK even if | |||||
* zero_checksum_port is 0 (which is its default value). | |||||
*/ | |||||
if (ntohs(uh->uh_dport) == V_zero_checksum_port) | |||||
goto skip_checksum; | |||||
else | |||||
goto badunlocked; | goto badunlocked; | ||||
} | } | ||||
} | } | ||||
if ((m->m_pkthdr.csum_flags & CSUM_DATA_VALID_IPV6) && | if ((m->m_pkthdr.csum_flags & CSUM_DATA_VALID_IPV6) && | ||||
!cscov_partial) { | !cscov_partial) { | ||||
if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) | if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) | ||||
uh_sum = m->m_pkthdr.csum_data; | uh_sum = m->m_pkthdr.csum_data; | ||||
else | else | ||||
uh_sum = in6_cksum_pseudo(ip6, ulen, nxt, | uh_sum = in6_cksum_pseudo(ip6, ulen, nxt, | ||||
m->m_pkthdr.csum_data); | m->m_pkthdr.csum_data); | ||||
uh_sum ^= 0xffff; | uh_sum ^= 0xffff; | ||||
} else | } else | ||||
uh_sum = in6_cksum_partial(m, nxt, off, plen, ulen); | uh_sum = in6_cksum_partial(m, nxt, off, plen, ulen); | ||||
if (uh_sum != 0) { | if (uh_sum != 0) { | ||||
UDPSTAT_INC(udps_badsum); | UDPSTAT_INC(udps_badsum); | ||||
goto badunlocked; | goto badunlocked; | ||||
} | } | ||||
skip_checksum: | |||||
/* | /* | ||||
* Construct sockaddr format source address. | * Construct sockaddr format source address. | ||||
*/ | */ | ||||
init_sin6(&fromsa[0], m, 0); | init_sin6(&fromsa[0], m, 0); | ||||
fromsa[0].sin6_port = uh->uh_sport; | fromsa[0].sin6_port = uh->uh_sport; | ||||
init_sin6(&fromsa[1], m, 1); | init_sin6(&fromsa[1], m, 1); | ||||
fromsa[1].sin6_port = uh->uh_dport; | fromsa[1].sin6_port = uh->uh_dport; | ||||
▲ Show 20 Lines • Show All 1,081 Lines • Show Last 20 Lines |