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.
Details
Tested with ARP, ICMP, TCP, forwarding; tested host part of 0 with IPv6
Diff Detail
- Repository
- rS FreeBSD src repository - subversion
- Lint
Lint Passed - Unit
No Test Coverage - Build Status
Buildable 41472 Build 38361: arc lint + arc unit
Event Timeline
Looks ok to me, just a comment on keeping code speed the same in almost all cases.
sys/netinet/in.c | ||
---|---|---|
1147 | 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. |
sys/netinet/in.c | ||
---|---|---|
1147 | 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?
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.
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???).
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.