nconsistencies with IP_ONESBCAST and/or IP_SENDSRCADDR

Bruce M. Simpson bms at FreeBSD.org
Thu Mar 1 11:54:11 UTC 2007


Bruce M Simpson wrote:
> Hello,
>
> In preparation for tightening up our handling of INADDR_BROADCAST 
> sends, I ran some brief tests today on the network stack with the 
> attached test code.
>
> I found some inconsistencies when run against 6.2-RELEASE;
>
> 1. IP_ONESBCAST breaks if SO_DONTROUTE is specified.
>
> One thing appears to be consistent about the failure mode: bad UDP 
> checksums.
> dc(4) is being used on the destination end of the test network, so 
> checksum offloading should not be an issue.
> I am also seeing the wrong destination address being used in most 
> cases. This is intermittent regardless of whether the socket is bound 
> or unbound.
This is consistent with ip_output() treating its internal flag 
IP_SENDONES as separate from IP_ROUTETOIF. I was skimming an old patch 
of mine which attempts to implement part of SO_BINDTODEVICE which 
contains a fix related to this condition.

The fix isn't the right fix so I will revisit this now and hopefully 
commit a fix shortly.
>
> 2. IP_SENDSRCADDR has some other inconsistencies.
> a. The option is always rejected if the socket is not bound.
> I find this behaviour suspect; the whole point of the option is to 
> specify, for SOCK_DGRAM and SOCK_RAW, the source address of a packet.
> b. 0.0.0.0 is always accepted.
> A regular interface lookup is used based on destination if this is 
> specified. This appears suspect to me because such an option is 
> redundant.
This is of course a separate issue. Because it's more involved (it 
concerns the general concept of 'ip unnumbered' in the stack) it needs 
further consideration before any fix is attempted.

udp_output() will only call in_pcbbind_setup() if a non-INADDR_ANY 
source address was specified; this is usually obtained from the socket 
being bound previously. This explains why the IP_SENDSRCADDR option is 
rejected in udp_output() for an unbound socket. It *will* be accepted if 
the option contains INADDR_ANY. In this case, normal source address 
selection takes place.

This is a good use case demonstrating the need for source address 
selection logic such as is now found in NetBSD.

There is no sanity checking on the IP_SENDSRCADDR option data containing 
INADDR_ANY; such an option is redundant and is nonsensical for an 
unbound socket. We should reject the option if it contains INADDR_ANY if 
and only if the socket is not bound. Implementing such a check is fairly 
easy and makes sense for this use case. Returning EINVAL in this case 
seems acceptable according to ip(4).

The option *should* be accepted if the application has bound the socket 
to a device somehow (oh dear, SO_BINDTODEVICE rears its head again) as 
DHCP for example needs to override any IPv4 address which may be 
assigned on an ifnet with 0.0.0.0.

Regards,
BMS



More information about the freebsd-net mailing list