From nobody Fri Sep 19 19:13:45 2025 X-Original-To: net@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4cT2H14Tdyz67SF6 for ; Fri, 19 Sep 2025 19:13:49 +0000 (UTC) (envelope-from avg@FreeBSD.org) Received: from smtp.freebsd.org (smtp.freebsd.org [IPv6:2610:1c1:1:606c::24b:4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "smtp.freebsd.org", Issuer "R13" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4cT2H13Xq4z3Hvv for ; Fri, 19 Sep 2025 19:13:49 +0000 (UTC) (envelope-from avg@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1758309229; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding:autocrypt:autocrypt; bh=xeF5+1OgJRhLVcGohe/6DnWm7Ja4Pgjfum8zir0SySc=; b=HgDuZpEaKXrkfcH0sO1rZjWnAk0azpqFB3rz1z+NqYUbOE8J8RaXOf3IPNEgdHev0CQwFp qyY76MCZR4hYAx9dQUIPP3zcDW3jO9hMTxpPU+bcDO3tCN3jDp1IGdHHzcJ9D1puBrKEfa v6WXxRFxAq28wYCGmveq8c3OoyaFQIvqQAfJHXIZF1Zsuml2HdGL/jXRdBGHd4OsPKEM2F sQwng/LC14ifSO2nviJQOFWr/bckfxt9WXgkr6r7zFx6HZHq0nociEqwk+H26ErawxAhDy i26vQF7wZnCBS97khyUqiTj6xhvFzUjGWxHsXGO/8woKWu2GsTge/UPGdlmJVw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1758309229; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding:autocrypt:autocrypt; bh=xeF5+1OgJRhLVcGohe/6DnWm7Ja4Pgjfum8zir0SySc=; b=uPLvxIsHUorh4SetzEjuiekTZ9vI8OmWU8keCw8Nwg7eP7LvIdz5sbI3iQmOMX7Dd1dPkI ZrvXwFwmkXzqiM+ErXlaJ4HbHWWKCQmD+738eH2O8bqs8vOXRaorenR+SZLjl7QjFd/UuP B1MlFC6zbsaSn5P9iJNYSXitolvUs4/FXaVMIrvC6VjYAg6ZB6FaD3a2kiW2HKbucMmg+y xWk6kRy2tAHQNmnGkMdpiISh+mkcw5favJ5V1CvZcKj3+FXuHS+FJ+YRkBLCahKVx6j/C7 vfjYngU8cPPK+tNDK+SXIvxxzp+B9X8hphMsZF7wHN71/FbbqqffYM+MR5xfSg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1758309229; a=rsa-sha256; cv=none; b=lDjtBMVjhuMMOTR6GQ41l0Wv5r8ohAL1bdGjXIzkT1oKiKXiqW3RbpmtMMpsBXgMhkxexT Q8sNAZnopfuuJIWzCPSUFFQSjFTbCb3J4viLP+52nDSsoUYm9IdVIvyP0R+8R1iZYUHzeF a+WQZzrLurd/0dVpY/oH5WYf5Y9MKlcFrsDrD6905WST+EP4R7ITyG1ZsSQIe+yYg9H0ov iSQQs4x41bioSk0Rcn3Z28e4xZIzFU5ZF49t5FZUIEL1zI8CcHJMbmVqx8Sy1fuD1riJ4v 6znPW35VjvNgQJm7/SImT75n1JUE3CegibUqYRI+Q1eaXmKCOCB1TX3Wi37FrQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from [192.168.0.88] (unknown [93.188.39.137]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) (Authenticated sender: avg/mail) by smtp.freebsd.org (Postfix) with ESMTPSA id 4cT2H111Wnz71Z for ; Fri, 19 Sep 2025 19:13:48 +0000 (UTC) (envelope-from avg@FreeBSD.org) Message-ID: <6abe9da1-9818-438b-ad8f-5424e50a39ce@FreeBSD.org> Date: Fri, 19 Sep 2025 22:13:45 +0300 List-Id: Networking and TCP/IP with FreeBSD List-Archive: https://lists.freebsd.org/archives/freebsd-net List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-freebsd-net@FreeBSD.org MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Content-Language: en-US To: "net@FreeBSD.org" From: Andriy Gapon Subject: DHCP on multi-homed host, some thoughts Autocrypt: addr=avg@FreeBSD.org; keydata= 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 gpPTjT15L8xGftEjQXF6 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit Admittedly not a very common configuration, but still possible and some people have it (according to the Internet). I am also trying to set up such a configuration for "reasons". In the simplest form, there are two network interfaces connected to two different networks. Each network has its own DHCP server, its own router / gateway to the wider Internet, its own DNS server(s), etc. The networks are likely to be completely unaware of each other. The host itself may be a router providing internet access to another local network via another interface (or even multiple networks + interfaces). But that's not important. Some things provided via DHCP are per interface, but others are per host ("global"). Each interface can get its own IP address, that's fine. But, for example, which gateway to select for the default route? Dealing with those "global" things is the main issue in such a setup. What do we have now? Specifically, with dhclient that's a part of the base. Essentially, it has a winner takes it all approach. That's implemented in the default dhclient-script and the gist of the logic is in is_default_interface() function. Whichever interface is first to get a lease with a router wins. dhclient-script would set the default route to the router and as long as the default route goes through the interface, the interface remains the winner (for subsequent updates). So, the winner gets to set the default route. The winner also gets to set the resolver configuration (using resolvconf(8), by default). Losers can only configure their interface, other information is lost. If DHCP is simply configured for multiple interfaces via rc.conf, without any extra settings, then there is an obvious problem. A winner would depend on random things like which interface gets link first, which DHCP sever is more responsive, etc. And a random winner is not always what is desired. As far as I know, there is no way to set any priority or anything like that. I found only two solutions used by other people, both not ideal. One solution is to start dhclient-s "manually" (i.e., outside of rc.conf declarative configuration) via something like rc.local. This way we can control which interface gets configured first. The other approach is to create a dhclient.conf configuration for the "secondary" interface(s) which would ignore the "global" options (routers, name servers, etc). This way the "primary" interface would be the only one that gets and sets the global configuration while all interfaces get their individual IP configuration. The latter approach is "less intrusive" (more declarative), but it has a flaw that if the selected primary network is down then there would be no default route at all. Both solutions still have the issue of discarding the global options from the secondary interface (either explicitly in dhclient.conf or by dhclient-script's strategy). And those options may come handy if we want to dynamically flip (and as seamlessly as possible) between interfaces based on some events / criteria. It's especially interesting that dhclient uses the power of resolvconf(8) (unless forced to update /etc/resolv.conf directly) but still takes only the winner's configuration. I think that it could just add configurations from all interfaces and let resolvconf(8) deal with that. And an administrator would have control over how multiple configurations are merged via resolvconf.conf. Especially, if a local resolver (like unbound, for instance) is used. E.g., it would be possible to use different name servers based on domain, etc. Regarding routing, these days we can have multiple FIBs, so instead of discarding "secondary" routing information we could use it to configure a non-default FIB. Initially, I wanted to start working on some changes to dhclient-script to implement those ideas. But then it occurred to me that it would easier to get what I want by changes external to dhclient. If there was a way to run a secondary dhclient with a non-default FIB (e.g., via setfib) then that alone would achieve the goals: - the secondary dhclient would be considered a winner because it's the only one to set the default route of the FIB; - so, it would obviously set the default route in the FIB; - and because the dhclient is considered a winner, it would also call resolvconf. I wonder if it would be a good idea to run dhclient under setfib if an interface is configured with DHCP/DHCPSYNC "virtual" option and real ifconfig 'fib' option. Or would that clash with some other uses / intentions? Then maybe we could add another virtual option like FIB or DHCPFIB? Or, probably even better, some thing like dhclient_fib_IF=X? Akin to background_dhclient, for example. The standard dhclient_fib option is, obviously, of no use because it would put all dhclient-s into the same FIB. -- Andriy Gapon