svcj: correctly handle kernels without INET or INET6

If either INET or INET6 is not enabled in the kernel, then the jail(8)
options ip4=<new|inherit> resp. ip6=<new|inherit> are not available.
Detect this case and don't try to provide those options, otherwise
svcjs will not start.

Do this automatically (without a warning) so that net_basic, which
includes both netv4 and netv6, continues to work as expected.

If _svcj_ipaddrs is explicitly configured with an address for an IP
version not supported by the kernel, issue a warning but continue to
start the service.  This can result in the service being started with
fewer addresses than expected, but never more.

Reviewed by:	netchild, des
Approved by:	des (mentor)
Differential Revision:	https://reviews.freebsd.org/D49976
This commit is contained in:
Lexi Winter 2025-05-27 08:31:18 +01:00
parent adef3618b8
commit 06c41801af

View file

@ -1214,27 +1214,43 @@ run_rc_command()
fi
fi
_svcj_ip="inherit"
_svcj_ip4_addrs=""
_svcj_ip6_addrs=""
for addr in $_svcj_ipaddrs; do
case $addr in
*:*) _svcj_ip6_addrs="$addr,${_svcj_ip6_addrs}" ;;
*) _svcj_ip4_addrs="$addr,${_svcj_ip4_addrs}" ;;
esac
done
_svcj_cmd_options=""
if [ -n "$_svcj_ip4_addrs" ]; then
_svcj_cmd_options="ip4.addr=${_svcj_ip4_addrs%*,} ${_svcj_cmd_options}"
if [ -n "$_svcj_ipaddrs" ]; then
_svcj_ip="new"
for addr in $_svcj_ipaddrs; do
case $addr in
*:*) _svcj_ip6_addrs="$addr,${_svcj_ip6_addrs}" ;;
*) _svcj_ip4_addrs="$addr,${_svcj_ip4_addrs}" ;;
esac
done
else
_svcj_ip="inherit"
fi
if [ -n "$_svcj_ip6_addrs" ]; then
_svcj_cmd_options="ip6.addr=${_svcj_ip6_addrs%*,} ${_svcj_cmd_options}"
_svcj_ip="new"
if check_kern_features inet; then
_svcj_ip4="ip4=${_svcj_ip}"
if [ -n "$_svcj_ip4_addrs" ]; then
_svcj_cmd_options="ip4.addr=${_svcj_ip4_addrs%*,} ${_svcj_cmd_options}"
fi
else
if [ -n "$_svcj_ip4_addrs" ]; then
warn "$rc_service: ${name}_svcj_ipaddrs contains at least one IPv4 address, but IPv4 is not enabled in the kernel; IPv4 addresses will be ignored."
fi
fi
if check_kern_features inet6; then
_svcj_ip6="ip6=${_svcj_ip}"
if [ -n "$_svcj_ip6_addrs" ]; then
_svcj_cmd_options="ip6.addr=${_svcj_ip6_addrs%*,} ${_svcj_cmd_options}"
fi
else
if [ -n "$_svcj_ip6_addrs" ]; then
warn "$rc_service: ${name}_svcj_ipaddrs contains at least one IPv6 address, but IPv6 is not enabled in the kernel; IPv6 addresses will be ignored."
fi
fi
if [ -n "$_svcj_options" ]; then # translate service jail options
@ -1245,19 +1261,19 @@ run_rc_command()
_svcj_cmd_options="allow.mlock ${_svcj_cmd_options}"
;;
netv4)
_svcj_cmd_options="ip4=${_svcj_ip} allow.reserved_ports ${_svcj_cmd_options}"
_svcj_cmd_options="${_svcj_ip4} allow.reserved_ports ${_svcj_cmd_options}"
;;
netv6)
_svcj_cmd_options="ip6=${_svcj_ip} allow.reserved_ports ${_svcj_cmd_options}"
_svcj_cmd_options="${_svcj_ip6} allow.reserved_ports ${_svcj_cmd_options}"
;;
net_basic)
_svcj_cmd_options="ip4=${_svcj_ip} ip6=${_svcj_ip} allow.reserved_ports ${_svcj_cmd_options}"
_svcj_cmd_options="${_svcj_ip4} ${_svcj_ip6} allow.reserved_ports ${_svcj_cmd_options}"
;;
net_raw)
_svcj_cmd_options="allow.raw_sockets ${_svcj_cmd_options}"
;;
net_all)
_svcj_cmd_options="allow.socket_af allow.raw_sockets allow.reserved_ports ip4=${_svcj_ip} ip6=${_svcj_ip} ${_svcj_cmd_options}"
_svcj_cmd_options="allow.socket_af allow.raw_sockets allow.reserved_ports ${_svcj_ip4} ${_svcj_ip6} ${_svcj_cmd_options}"
;;
nfsd)
_svcj_cmd_options="allow.nfsd enforce_statfs=1 ${_svcj_cmd_options}"