Page MenuHomeFreeBSD

Change lowest address on subnet (host 0) not to broadcast by default.
ClosedPublic

Authored by karels on Sep 6 2021, 2:47 PM.

Details

Summary

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. 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_zero) 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.

Test Plan

Tested with ARP, ICMP, TCP, forwarding; tested host part of 0 with IPv6

Diff Detail

Repository
R10 FreeBSD src repository
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.

Event Timeline

karels requested review of this revision.Sep 6 2021, 2:47 PM
rgrimes added a subscriber: rgrimes.

Looks ok to me, just a comment on keeping code speed the same in almost all cases.

sys/netinet/in.c
1182

There might be a micro optimization here to do the V_broadcast_zero test LAST, that way the additional test in the fast path only occurs after the tests we have been doing all along.

This revision is now accepted and ready to land.Sep 6 2021, 4:16 PM
sys/netinet/in.c
1182

Actually, I put it first as a micro-optimization. As it is false by default, the test fails immediately and we don't have to evaluate the rest.

btw, I will wait for comments from the subscribers on D19316 who proposed it, then mention it on -net for any other comments.

Two comments: RFC 3021 eliminates both the all-ones broadcast address and the all-zeroes broadcast address on an interface when configured as a /31. Is that all-ones address already handled somehow by how ia->ia_broadaddr.sin_addr.s_addr is getting set elsewhere? In both the old and new code, the IN_RFC3021_MASK test is not eliminating the all-ones broadcast address in this function.

Also, as a micro optimization: there is already a test for a 32-bit subnet mask; can you simply combine that with the test for the 31-bit subnet mask, e.g. ia->ia_subnetmask >= IN_RFC3021_MASK, making sure it's an unsigned comparison?

rgrimes added subscribers: schoen_loyalty.org, emaste, bz.

Add some reviewers, and pull in most of the subscribers fro D19316

Answering John's question about RFC3021 masks, now that I have checked and tested it: if a broadcast network is a /31, then the broadcast address is set to the local broadcast address (all ones), and nether .0 nor .1 is broadcast.

Change sysctl name to net.inet.ip.broadcast_lowest

This revision now requires review to proceed.Sep 12 2021, 2:49 PM

Update sysctl name to broadcast_lowest throughout.

Answering John's question about RFC3021 masks, now that I have checked and tested it: if a broadcast network is a /31, then the broadcast address is set to the local broadcast address (all ones), and nether .0 nor .1 is broadcast.

Doesnt this occur because your looking at a network interface that is infact no longer a "broadcast" type but has been changed to P2P

vlan999: flags=8003<UP,BROADCAST,MULTICAST> metric 0 mtu 1500

ether 00:00:00:00:00:00
inet 255.255.0.23 netmask 0xffffff00 broadcast 255.255.0.255 
vlan: 0 vlanpcp: 0 parent interface: <none>
groups: vlan

tun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> metric 0 mtu 1500

options=80000<LINKSTATE>
inet 65.75.216.238 --> 65.75.216.237  netmask 0xffffffff 
groups: tun 
Opened by PID 65746

Note VLAN999 is a BROADCAST interface, and tun0 is a POINTOPOINT (sic, why has the second T in POINTTOPOINT been dropped???).

This revision is now accepted and ready to land.Sep 12 2021, 4:03 PM

Is tun0 normally broadcast? However, I tested this with tap0, and it remained a broadcast interface with the usual flags, and broadcast address set to 255.255.255.255 by default.