From owner-freebsd-net@FreeBSD.ORG Thu Mar 1 11:54:10 2007 Return-Path: X-Original-To: net@FreeBSD.org Delivered-To: freebsd-net@FreeBSD.ORG Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id E447C16A405 for ; Thu, 1 Mar 2007 11:54:10 +0000 (UTC) (envelope-from bms@FreeBSD.org) Received: from out5.smtp.messagingengine.com (out5.smtp.messagingengine.com [66.111.4.29]) by mx1.freebsd.org (Postfix) with ESMTP id AACA013C4BF for ; Thu, 1 Mar 2007 11:54:10 +0000 (UTC) (envelope-from bms@FreeBSD.org) Received: from out1.internal (unknown [10.202.2.149]) by out1.messagingengine.com (Postfix) with ESMTP id A63C01F4088 for ; Thu, 1 Mar 2007 06:54:10 -0500 (EST) Received: from heartbeat1.messagingengine.com ([10.202.2.160]) by out1.internal (MEProxy); Thu, 01 Mar 2007 06:54:10 -0500 X-Sasl-enc: ZIVJM6QygzDQ4qZMvzTr3xV406BleRGeSW/wdf3J8ijR 1172750050 Received: from [192.168.123.18] (82-35-112-254.cable.ubr07.dals.blueyonder.co.uk [82.35.112.254]) by mail.messagingengine.com (Postfix) with ESMTP id 438B521049 for ; Thu, 1 Mar 2007 06:54:09 -0500 (EST) Message-ID: <45E6BEE0.2050307@FreeBSD.org> Date: Thu, 01 Mar 2007 11:54:08 +0000 From: "Bruce M. Simpson" User-Agent: Thunderbird 1.5.0.9 (X11/20070125) MIME-Version: 1.0 To: net@FreeBSD.org References: <45C0CA5D.5090903@incunabulum.net> In-Reply-To: <45C0CA5D.5090903@incunabulum.net> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: Subject: Re: nconsistencies with IP_ONESBCAST and/or IP_SENDSRCADDR X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 01 Mar 2007 11:54:11 -0000 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