Created attachment 252894 [details] auto-switch DHCP rc.conf(5) directive to SYNCDHCP if devd(8) won't take over Generally, if user defines DHCP as ifconfig pseudo-argument in rc.conf(5), devd(8) and /etc/devd/dhclient.conf handle the setup task. But since /etc/rc.d/devd has "nojail" keyword defined, devd(8) won't run in any jail, while /etc/rc.d/dhclient is meant to be allowed in vnet-enabled jails since /etc/rc.d/dhclient got keyword nojail changed to nojailvnet. This change doesn't have any effect unless user defines "SYNCDHCP" instead of "DHCP" as pseudo-ifconfig argument in rc.conf(5), which seems to be not well documented. My suggestion is an auto-switch to SYNCDHCP behaviour (i. e. /etc/rc.d/netif will run /etc/rc.d/dhclient). This applies outside jails too, if user disabled devd(8) startup. If DHCP pseudo-arg is configured in a vnet-jail (no nojailvnet), the auto-switch to SYNCDHCP will do what user expects - without spending a lot of time to discover the to some degree misleading SYNCDHCP option, imho. I'm not aware of any negative impact this auto-switch could have.
As you already identified the problem is that ifconfig_<name>="... DHCP" doesn't work inside a vnet jail. The reason for this is that DHCP instead of SYNCDHCP relies on devd to respond to link up events and which is impossible inside a jail since it would require opening /dev/devctl inside the jail to get events into the kernel and that device support only one opening at a time (like tun and tap device). You have to use SYNCDHCP inside the jail or configure the host's devd to match on the jail interface name(s) with a higher priority than the default rules to make async DHCP work and use jexec to run the same script inside the correct jail with jexec.
(In reply to crest from comment #1) We need to either document thath DHCP is not a valid pseudo-argument in vnet-jails or do a auto-SYNCifying, like I proposed. Any objections to my patch?
Interface names can contain any null terminated string e.g. `$'💩 𓂸\n\t\377\10\10\10'` (including the NUL byte). They're unsafe (splitting, trimming, globbing), to expand in shell scripts outside of a double quoted strings e.g. `dhcpif $1`
(In reply to crest from comment #3) Good point. But this patch for syncdhcpif() of /etc/network.subr is not really affected, since $1 in syncdhcpif() was passed unquoted from ifconfig_up() which in turn got it from ifn_start() as unquoted parameter ${ifn}. get_if_var() uses ltr() to normalize IF. From a quick look, only IFNAME consisting of the four ".-/+" punctuation characters are valid, which are unconditionally replaced by the underscore character. rc(8) would break far earlier if somebody manually renamed the interface to anything allowed by the core struct (if not prevented by ifconfig(8)) and tries to non-maually attach dhclient to it. For consistency reasons I'd prefer to keep it unquoted since I see no possibility that $1 can ever be anything else than shell variable characters (get_if_var() would fail to return any of the DHCP pseudo-args, so syncdhcpif() wouldn't be called). The wrong whitespace indention bothers me more ;-) Thanks for looking at it!
Adding phabricator link: https://reviews.freebsd.org/D46687