diff --git a/usr.sbin/jail/jail.8 b/usr.sbin/jail/jail.8 --- a/usr.sbin/jail/jail.8 +++ b/usr.sbin/jail/jail.8 @@ -285,11 +285,17 @@ 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 @@ 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 diff --git a/usr.sbin/jail/jail.c b/usr.sbin/jail/jail.c --- a/usr.sbin/jail/jail.c +++ b/usr.sbin/jail/jail.c @@ -146,6 +146,20 @@ 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 @@ 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 @@ 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) { - ncs = strchr(cs, ','); - if (ncs) - *ncs = '\0'; - add_param(NULL, NULL, KP_IP4_ADDR, cs); - if (!ncs) - break; - } - } -#endif -#ifdef INET6 - else if (!strncmp(argv[i], "ip6.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_IP6_ADDR, cs); + add_param(NULL, NULL, + listparams[l].param, cs); if (!ncs) break; } + break; } -#endif - else + if (l == nitems(listparams)) add_param(NULL, NULL, 0, argv[i]); } } else { diff --git a/usr.sbin/jail/tests/jail_basic_test.sh b/usr.sbin/jail/tests/jail_basic_test.sh --- a/usr.sbin/jail/tests/jail_basic_test.sh +++ b/usr.sbin/jail/tests/jail_basic_test.sh @@ -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 @@ 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 @@ jail -r basejail_nochild } +atf_test_case "commands" "cleanup" commands_head() { atf_set descr 'Commands jail test' @@ -129,6 +157,7 @@ atf_init_test_cases() { atf_add_test_case "basic" + atf_add_test_case "list" atf_add_test_case "nested" atf_add_test_case "commands" }