From owner-freebsd-net@FreeBSD.ORG Wed Mar 7 12:31:05 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 553D716A400; Wed, 7 Mar 2007 12:31:05 +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 1365413C4A5; Wed, 7 Mar 2007 12:31:05 +0000 (UTC) (envelope-from bms@FreeBSD.org) Received: from out1.internal (unknown [10.202.2.149]) by out1.messagingengine.com (Postfix) with ESMTP id A2EC11F5DFF; Wed, 7 Mar 2007 07:31:04 -0500 (EST) Received: from heartbeat1.messagingengine.com ([10.202.2.160]) by out1.internal (MEProxy); Wed, 07 Mar 2007 07:31:04 -0500 X-Sasl-enc: lWPUQ2XTp9YziyJuPubgr6/48i0f3VJH8HBrezLr6DPr 1173270664 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 331C7165B2; Wed, 7 Mar 2007 07:31:03 -0500 (EST) Message-ID: <45EEB086.3050409@FreeBSD.org> Date: Wed, 07 Mar 2007 12:31:02 +0000 From: "Bruce M. Simpson" User-Agent: Thunderbird 1.5.0.9 (X11/20070125) MIME-Version: 1.0 To: "Bruce M. Simpson" References: <45C0CA5D.5090903@incunabulum.net> <45E6BEE0.2050307@FreeBSD.org> <45E6C22D.7060200@freebsd.org> <45E6D70C.10104@FreeBSD.org> In-Reply-To: <45E6D70C.10104@FreeBSD.org> Content-Type: multipart/mixed; boundary="------------070900070803040605090309" Cc: Andre Oppermann , net@FreeBSD.org Subject: Re: Inconsistencies 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: Wed, 07 Mar 2007 12:31:05 -0000 This is a multi-part message in MIME format. --------------070900070803040605090309 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Bruce M. Simpson wrote: > > Dealing with dhclient is a separate issue -- here, something like > IP_SENDIF needs to be introduced, as we are truly in an 'ip > unnumbered' situation -- ie the ifnet MAY not yet have been assigned > an IPv4 address at all, and IP_SENDSRCADDR implies that you are source > routing in the local stack by passing the address of a numbered interface I have just committed a change in bms_netdev which enforces strict and better defined semantics for the IP_SENDSRCADDR option in udp_output(). This fits one of the main intended use cases of this option, e.g. a routing daemon, bound to 0.0.0.0 and a non-ephemeral port, which needs to explicitly override the hard-coded source selection policy in ip_output() to send an undirected broadcast on a numbered interface. It also fits a use case whereby a bound socket may wish to temporarily ask for default source selection policy by specifying INADDR_ANY, although this needs to be reviewed and tested further; I believe in_pcbbind_setup() will detect a collision in this case. We always obtain the inp_info write lock if IP_SENDSRCADDR was specified, in case we need to temporarily re-bind laddr. Pseudo-conditions as follows. IP_SENDSRCADDR with lport NOT BOUND is NOT OK. We should never try to persistently bind a socket which is not bound unless we are bind(2). IP_SENDSRCADDR with !INADDR_ANY when laddr is NOT BOUND is OK. It means override the source selection logic and use src.sin_addr instead. IP_SENDSRCADDR with INADDR_ANY when laddr is BOUND is OK; it It means override the bound address and use source selection logic instead. IP_SENDSRCADDR with INADDR_ANY when laddr is BOUND is OK. It means override the bound address and use source selection logic instead. IP_SENDSRCADDR with INADDR_ANY when laddr is NOT BOUND is NOT OK. It means no valid source is specified. Regards, BMS --------------070900070803040605090309 Content-Type: text/x-patch; name="ipsendsrcaddr.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="ipsendsrcaddr.diff" --- //depot/vendor/freebsd/src/sys/netinet/udp_usrreq.c 2007/02/20 10:22:30 +++ //depot/user/bms/netdev/sys/netinet/udp_usrreq.c 2007/03/07 12:28:16 @@ -747,7 +747,8 @@ return (EMSGSIZE); } - src.sin_addr.s_addr = INADDR_ANY; + bzero(&src, sizeof(src)); + if (control != NULL) { /* * XXX: Currently, we assume all the optional information is @@ -777,12 +778,10 @@ error = EINVAL; break; } - bzero(&src, sizeof(src)); src.sin_family = AF_INET; src.sin_len = sizeof(src); - src.sin_port = inp->inp_lport; src.sin_addr = *(struct in_addr *)CMSG_DATA(cm); break; default: error = ENOPROTOOPT; break; @@ -797,7 +796,7 @@ return (error); } - if (src.sin_addr.s_addr != INADDR_ANY || addr != NULL) { + if (src.sin_family == AF_INET || addr != NULL) { INP_INFO_WLOCK(&udbinfo); unlock_udbinfo = 1; } else @@ -810,11 +809,20 @@ laddr = inp->inp_laddr; lport = inp->inp_lport; - if (src.sin_addr.s_addr != INADDR_ANY) { - if (lport == 0) { + + /* + * If the IP_SENDSRCADDR control message was specified, override the + * source address for this datagram. Its use is invalidated if the + * address thus specified is incomplete or clobbers other inpcbs. + */ + if (src.sin_family == AF_INET) { + if ((lport == 0) || + (laddr.s_addr == INADDR_ANY && + src.sin_addr.s_addr == INADDR_ANY)) { error = EINVAL; goto release; } + src.sin_port = lport; error = in_pcbbind_setup(inp, (struct sockaddr *)&src, &laddr.s_addr, &lport, td->td_ucred); if (error) --------------070900070803040605090309--