aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNavdeep Parhar <np@FreeBSD.org>2020-09-18 02:21:15 +0000
committerNavdeep Parhar <np@FreeBSD.org>2020-09-18 02:21:15 +0000
commit72cc43df1731748c43db18cd491bc4b39f38fd83 (patch)
tree357d6c451182ba4f4ac292eb615668e7ebe22871
parent830edb4561d38e71470580890c17b362afb91a1a (diff)
downloadsrc-72cc43df1731748c43db18cd491bc4b39f38fd83.tar.gz
src-72cc43df1731748c43db18cd491bc4b39f38fd83.zip
Add a knob to allow zero UDP checksums for UDP/IPv6 traffic on the given UDP port.
This will be used by some upcoming changes to if_vxlan(4). RFC 7348 (VXLAN) says that the UDP checksum "SHOULD be transmitted as zero. When a packet is received with a UDP checksum of zero, it MUST be accepted for decapsulation." But the original IPv6 RFCs did not allow zero UDP checksum. RFC 6935 attempts to resolve this. Reviewed by: kib@ Sponsored by: Chelsio Communications Differential Revision: https://reviews.freebsd.org/D25873
Notes
Notes: svn path=/head/; revision=365869
-rw-r--r--sys/netinet/udp_var.h3
-rw-r--r--sys/netinet6/udp6_usrreq.c15
2 files changed, 17 insertions, 1 deletions
diff --git a/sys/netinet/udp_var.h b/sys/netinet/udp_var.h
index 5d04a9da9c1a..37bc0c846d99 100644
--- a/sys/netinet/udp_var.h
+++ b/sys/netinet/udp_var.h
@@ -154,6 +154,9 @@ VNET_DECLARE(int, udp_log_in_vain);
#define V_udp_blackhole VNET(udp_blackhole)
#define V_udp_log_in_vain VNET(udp_log_in_vain)
+VNET_DECLARE(int, zero_checksum_port);
+#define V_zero_checksum_port VNET(zero_checksum_port)
+
static __inline struct inpcbinfo *
udp_get_inpcbinfo(int protocol)
{
diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c
index 535ebcd45303..32aa21cb24a1 100644
--- a/sys/netinet6/udp6_usrreq.c
+++ b/sys/netinet6/udp6_usrreq.c
@@ -124,6 +124,11 @@ __FBSDID("$FreeBSD$");
#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.
* Per RFC 768, August, 1980.
@@ -267,7 +272,14 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
}
if (uh->uh_sum == 0) {
UDPSTAT_INC(udps_nosum);
- goto badunlocked;
+ /*
+ * 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;
}
}
@@ -287,6 +299,7 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
goto badunlocked;
}
+skip_checksum:
/*
* Construct sockaddr format source address.
*/