jail: Let a couple of parameter types be specified as lists

vnet.interface and zfs.dataset can be used to specify multiple
interfaces/datasets in jail.conf, but not on the command-line, which is
a bit surprising.  Extend the handling of ip(4|6).addr to those
parameters, update the description of vnet.interface in jail.8, and add
a rudimentary regression test.

Reviewed by:	zlei, jamie
MFC after:	1 week
Differential Revision:	https://reviews.freebsd.org/D47651
This commit is contained in:
Mark Johnston 2024-11-19 21:05:24 +00:00
parent d6b692835e
commit 48c738b038
3 changed files with 75 additions and 24 deletions

View File

@ -285,11 +285,17 @@ They can also be given the values
and
.Dq false .
Other parameters may have more than one value, specified as a
comma-separated list or with
comma-separated list, or with
.Dq +=
in the configuration file (see
.Xr jail.conf 5
for details).
List-based parameters may also be specified multiple times on the command
line, i.e.,
.Dq name=value1,value2
and
.Dq name=value1 name=value2
are equivalent for such parameters.
.Pp
The
.Nm
@ -944,8 +950,8 @@ an interface, prefix and additional parameters (as supported by
may also be specified, in the form
.Dq Ar interface Ns | Ns Ar ip-address Ns / Ns Ar prefix param ... .
.It Va vnet.interface
A network interface to give to a vnet-enabled jail after is it created.
The interface will automatically be released when the jail is removed.
A list of network interfaces to give to a vnet-enabled jail after is it created.
The interfaces will automatically be released when the jail is removed.
.It Va zfs.dataset
A list of ZFS datasets to be attached to the jail.
This requires

View File

@ -146,6 +146,20 @@ static const enum intparam cleancommands[] = {
IP__NULL
};
static const struct {
const char *name;
enum intparam param;
} listparams[] = {
#ifdef INET
{ "ip4.addr", KP_IP4_ADDR },
#endif
#ifdef INET6
{ "ip6.addr", KP_IP6_ADDR },
#endif
{ "vnet.interface", IP_VNET_INTERFACE },
{ "zfs.dataset", IP_ZFS_DATASET },
};
int
main(int argc, char **argv)
{
@ -330,6 +344,8 @@ main(int argc, char **argv)
usage();
docf = 0;
for (i = 0; i < argc; i++) {
size_t l;
if (!strncmp(argv[i], "command", 7) &&
(argv[i][7] == '\0' || argv[i][7] == '=')) {
if (argv[i][7] == '=')
@ -338,32 +354,32 @@ main(int argc, char **argv)
for (i++; i < argc; i++)
add_param(NULL, NULL, IP_COMMAND,
argv[i]);
continue;
}
#ifdef INET
else if (!strncmp(argv[i], "ip4.addr=", 9)) {
for (cs = argv[i] + 9;; cs = ncs + 1) {
/*
* Is this parameter a list?
*/
for (l = 0; l < nitems(listparams); l++) {
size_t len;
len = strlen(listparams[l].name);
if (strncmp(argv[i], listparams[l].name, len) ||
argv[i][len] != '=')
continue;
for (cs = argv[i] + len + 1;; cs = ncs + 1) {
ncs = strchr(cs, ',');
if (ncs)
*ncs = '\0';
add_param(NULL, NULL, KP_IP4_ADDR, cs);
add_param(NULL, NULL,
listparams[l].param, cs);
if (!ncs)
break;
}
break;
}
#endif
#ifdef INET6
else if (!strncmp(argv[i], "ip6.addr=", 9)) {
for (cs = argv[i] + 9;; cs = ncs + 1) {
ncs = strchr(cs, ',');
if (ncs)
*ncs = '\0';
add_param(NULL, NULL, KP_IP6_ADDR, cs);
if (!ncs)
break;
}
}
#endif
else
if (l == nitems(listparams))
add_param(NULL, NULL, 0, argv[i]);
}
} else {

View File

@ -25,9 +25,6 @@
# SUCH DAMAGE.
atf_test_case "basic" "cleanup"
atf_test_case "nested" "cleanup"
atf_test_case "commands" "cleanup"
basic_head()
{
atf_set descr 'Basic jail test'
@ -58,6 +55,36 @@ basic_cleanup()
jail -r basejail
}
atf_test_case "list" "cleanup"
list_head()
{
atf_set descr 'Specify some jail parameters as lists'
atf_set require.user root
}
list_body()
{
if [ "$(sysctl -qn kern.features.vimage)" -ne 1 ]; then
atf_skip "cannot create VNET jails"
fi
atf_check -o save:epair ifconfig epair create
epair=$(cat epair)
atf_check jail -c name=basejail vnet persist vnet.interface=${epair},${epair%a}b
atf_check -o ignore jexec basejail ifconfig ${epair}
atf_check -o ignore jexec basejail ifconfig ${epair%a}b
}
list_cleanup()
{
jail -r basejail
if [ -f epair ]; then
ifconfig $(cat epair) destroy
fi
}
atf_test_case "nested" "cleanup"
nested_head()
{
atf_set descr 'Hierarchical jails test'
@ -97,6 +124,7 @@ nested_cleanup()
jail -r basejail_nochild
}
atf_test_case "commands" "cleanup"
commands_head()
{
atf_set descr 'Commands jail test'
@ -129,6 +157,7 @@ commands_cleanup()
atf_init_test_cases()
{
atf_add_test_case "basic"
atf_add_test_case "list"
atf_add_test_case "nested"
atf_add_test_case "commands"
}