The branch main has been updated by markj:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=48c738b038ac84f3334b20b9a0f56fa3d9b7f6d1

commit 48c738b038ac84f3334b20b9a0f56fa3d9b7f6d1
Author:     Mark Johnston <[email protected]>
AuthorDate: 2024-11-19 21:05:24 +0000
Commit:     Mark Johnston <[email protected]>
CommitDate: 2024-11-19 21:05:24 +0000

    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
---
 usr.sbin/jail/jail.8                   | 12 ++++++--
 usr.sbin/jail/jail.c                   | 52 ++++++++++++++++++++++------------
 usr.sbin/jail/tests/jail_basic_test.sh | 35 +++++++++++++++++++++--
 3 files changed, 75 insertions(+), 24 deletions(-)

diff --git a/usr.sbin/jail/jail.8 b/usr.sbin/jail/jail.8
index 67f325d15a93..aa540a50a725 100644
--- a/usr.sbin/jail/jail.8
+++ b/usr.sbin/jail/jail.8
@@ -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
diff --git a/usr.sbin/jail/jail.c b/usr.sbin/jail/jail.c
index 53e05870ff26..27769cc14958 100644
--- a/usr.sbin/jail/jail.c
+++ b/usr.sbin/jail/jail.c
@@ -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) {
-                                       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
index a907e713ab9a..5d67f42c2d56 100755
--- 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 @@ 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"
 }

Reply via email to