aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Karels <karels@FreeBSD.org>2021-09-05 18:14:04 +0000
committerMike Karels <karels@FreeBSD.org>2021-09-17 00:42:20 +0000
commitfd0765933c3ccb059ad7456e657b2e8ed22f58b0 (patch)
treec1990703db5cdadf0f182edd7ec15f92fcb47f7b
parentb43d7aa09b3c91fb6b652306db2ac13e1459c497 (diff)
downloadsrc-fd0765933c3c.tar.gz
src-fd0765933c3c.zip
Change lowest address on subnet (host 0) not to broadcast by default.
The address with a host part of all zeros was used as a broadcast long ago, but the default has been all ones since 4.3BSD and RFC1122. Until now, we would broadcast the host zero address as well as the configured address. Change to not broadcasting that address by default, but add a sysctl (net.inet.ip.broadcast_lowest) to re-enable it. Note that the correct way to use the zero address for broadcast would be to configure it as the broadcast address for the network. See https:/datatracker.ietf.org/doc/draft-schoen-intarea-lowest-address/ and the discussion in https://reviews.freebsd.org/D19316. Note, Linux now implements this. Reviewed by: rgrimes, tuexen; melifaro (previous version) MFC after: 1 month Relnotes: yes Differential Revision: https://reviews.freebsd.org/D31861
-rw-r--r--sys/netinet/in.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/sys/netinet/in.c b/sys/netinet/in.c
index e968a559a13c..b51f1111b88a 100644
--- a/sys/netinet/in.c
+++ b/sys/netinet/in.c
@@ -88,6 +88,12 @@ SYSCTL_INT(_net_inet_ip, OID_AUTO, no_same_prefix, CTLFLAG_VNET | CTLFLAG_RW,
&VNET_NAME(nosameprefix), 0,
"Refuse to create same prefixes on different interfaces");
+VNET_DEFINE_STATIC(bool, broadcast_lowest);
+#define V_broadcast_lowest VNET(broadcast_lowest)
+SYSCTL_BOOL(_net_inet_ip, OID_AUTO, broadcast_lowest, CTLFLAG_VNET | CTLFLAG_RW,
+ &VNET_NAME(broadcast_lowest), 0,
+ "Treat lowest address on a subnet (host 0) as broadcast");
+
VNET_DECLARE(struct inpcbinfo, ripcbinfo);
#define V_ripcbinfo VNET(ripcbinfo)
@@ -1170,10 +1176,10 @@ in_ifaddr_broadcast(struct in_addr in, struct in_ifaddr *ia)
return ((in.s_addr == ia->ia_broadaddr.sin_addr.s_addr ||
/*
- * Check for old-style (host 0) broadcast, but
+ * Optionally check for old-style (host 0) broadcast, but
* taking into account that RFC 3021 obsoletes it.
*/
- (ia->ia_subnetmask != IN_RFC3021_MASK &&
+ (V_broadcast_lowest && ia->ia_subnetmask != IN_RFC3021_MASK &&
ntohl(in.s_addr) == ia->ia_subnet)) &&
/*
* Check for an all one subnetmask. These