From b22b6abd3434bed270d4f27dfe33b3e6c2f6c82d Mon Sep 17 00:00:00 2001 From: Steven Hartland Date: Mon, 4 Aug 2014 16:32:08 +0000 Subject: [PATCH] Added support for extra ifconfig args to jail ip4.addr & ip6.addr params This allows for CARP interfaces to be used in jails e.g. ip4.addr = "em0|10.10.1.20/32 vhid 1 pass MyPass advskew 100" Before this change using exec.prestart to configure a CARP address would result in the wrong MAC being broadcast on startup as jail creates IP aliases to support ip[4|6].addr before exec.prestart is executed. PR: 191832 Reviewed by: jamie MFC after: 1 week X-MFC-With: r269340 Phabric: D528 Sponsored by: Multiplay --- usr.sbin/jail/command.c | 68 ++++++++++++++++++++++++++++++++++------- usr.sbin/jail/config.c | 12 +++++++- usr.sbin/jail/jail.8 | 17 ++++++++--- 3 files changed, 80 insertions(+), 17 deletions(-) diff --git a/usr.sbin/jail/command.c b/usr.sbin/jail/command.c index 04a4514da36..0d1c8985706 100644 --- a/usr.sbin/jail/command.c +++ b/usr.sbin/jail/command.c @@ -268,7 +268,7 @@ run_command(struct cfjail *j) pid_t pid; int argc, bg, clean, consfd, down, fib, i, injail, sjuser, timeout; #if defined(INET) || defined(INET6) - char *addr; + char *addr, *extrap, *p, *val; #endif static char *cleanenv; @@ -317,16 +317,30 @@ run_command(struct cfjail *j) switch (comparam) { #ifdef INET case IP__IP4_IFADDR: - argv = alloca(8 * sizeof(char *)); + argc = 0; + val = alloca(strlen(comstring->s) + 1); + strcpy(val, comstring->s); + cs = val; + extrap = NULL; + while ((p = strchr(cs, ' ')) != NULL && strlen(p) > 1) { + if (extrap == NULL) { + *p = '\0'; + extrap = p + 1; + } + cs = p + 1; + argc++; + } + + argv = alloca((8 + argc) * sizeof(char *)); *(const char **)&argv[0] = _PATH_IFCONFIG; - if ((cs = strchr(comstring->s, '|'))) { - argv[1] = alloca(cs - comstring->s + 1); - strlcpy(argv[1], comstring->s, cs - comstring->s + 1); + if ((cs = strchr(val, '|'))) { + argv[1] = alloca(cs - val + 1); + strlcpy(argv[1], val, cs - val + 1); addr = cs + 1; } else { *(const char **)&argv[1] = string_param(j->intparams[IP_INTERFACE]); - addr = comstring->s; + addr = val; } *(const char **)&argv[2] = "inet"; if (!(cs = strchr(addr, '/'))) { @@ -344,6 +358,15 @@ run_command(struct cfjail *j) argv[3] = addr; argc = 4; } + + if (!down) { + for (cs = strtok(extrap, " "); cs; cs = strtok(NULL, " ")) { + size_t len = strlen(cs) + 1; + argv[argc] = alloca(len); + strlcpy(argv[argc++], cs, len); + } + } + *(const char **)&argv[argc] = down ? "-alias" : "alias"; argv[argc + 1] = NULL; break; @@ -351,16 +374,30 @@ run_command(struct cfjail *j) #ifdef INET6 case IP__IP6_IFADDR: - argv = alloca(8 * sizeof(char *)); + argc = 0; + val = alloca(strlen(comstring->s) + 1); + strcpy(val, comstring->s); + cs = val; + extrap = NULL; + while ((p = strchr(cs, ' ')) != NULL && strlen(p) > 1) { + if (extrap == NULL) { + *p = '\0'; + extrap = p + 1; + } + cs = p + 1; + argc++; + } + + argv = alloca((8 + argc) * sizeof(char *)); *(const char **)&argv[0] = _PATH_IFCONFIG; - if ((cs = strchr(comstring->s, '|'))) { - argv[1] = alloca(cs - comstring->s + 1); - strlcpy(argv[1], comstring->s, cs - comstring->s + 1); + if ((cs = strchr(val, '|'))) { + argv[1] = alloca(cs - val + 1); + strlcpy(argv[1], val, cs - val + 1); addr = cs + 1; } else { *(const char **)&argv[1] = string_param(j->intparams[IP_INTERFACE]); - addr = comstring->s; + addr = val; } *(const char **)&argv[2] = "inet6"; argv[3] = addr; @@ -370,6 +407,15 @@ run_command(struct cfjail *j) argc = 6; } else argc = 4; + + if (!down) { + for (cs = strtok(extrap, " "); cs; cs = strtok(NULL, " ")) { + size_t len = strlen(cs) + 1; + argv[argc] = alloca(len); + strlcpy(argv[argc++], cs, len); + } + } + *(const char **)&argv[argc] = down ? "-alias" : "alias"; argv[argc + 1] = NULL; break; diff --git a/usr.sbin/jail/config.c b/usr.sbin/jail/config.c index 57967082b9f..cd02a500c54 100644 --- a/usr.sbin/jail/config.c +++ b/usr.sbin/jail/config.c @@ -576,7 +576,9 @@ check_intparams(struct cfjail *j) /* * IP addresses may include an interface to set that address on, - * and a netmask/suffix for that address. + * a netmask/suffix for that address and options for ifconfig. + * These are copied to an internal command parameter and then stripped + * so they won't be passed on to jailparam_set. */ defif = string_param(j->intparams[IP_INTERFACE]) != NULL; #ifdef INET @@ -601,6 +603,10 @@ check_intparams(struct cfjail *j) *cs = '\0'; s->len = cs - s->s; } + if ((cs = strchr(s->s, ' ')) != NULL) { + *cs = '\0'; + s->len = cs - s->s; + } } } #endif @@ -625,6 +631,10 @@ check_intparams(struct cfjail *j) *cs = '\0'; s->len = cs - s->s; } + if ((cs = strchr(s->s, ' ')) != NULL) { + *cs = '\0'; + s->len = cs - s->s; + } } } #endif diff --git a/usr.sbin/jail/jail.8 b/usr.sbin/jail/jail.8 index e43928a75cd..927e2bb449e 100644 --- a/usr.sbin/jail/jail.8 +++ b/usr.sbin/jail/jail.8 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd July 10, 2014 +.Dd August 4, 2014 .Dt JAIL 8 .Os .Sh NAME @@ -687,18 +687,24 @@ jail is created, and will be removed from the interface after the jail is removed. .It Va ip4.addr In addition to the IP addresses that are passed to the kernel, an -interface and/or a netmask may also be specified, in the form -.Dq Ar interface Ns | Ns Ar ip-address Ns / Ns Ar netmask . +interface, netmask and additional paramters (as supported by +.Xr ifconfig 8 Ns ) +may also be specified, in the form +.Dq Ar interface Ns | Ns Ar ip-address Ns / Ns Ar netmask param ... . If an interface is given before the IP address, an alias for the address will be added to that interface, as it is with the .Va interface parameter. If a netmask in either dotted-quad or CIDR form is given after an IP address, it will be used when adding the IP alias. +If additional parameters are specified then they will also be used when +adding the IP alias. .It Va ip6.addr In addition to the IP addresses that are passed to the kernel, -an interface and/or a prefix may also be specified, in the form -.Dq Ar interface Ns | Ns Ar ip-address Ns / Ns Ar prefix . +an interface, prefix and additional parameters (as supported by +.Xr ifconfig 8 Ns ) +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. @@ -1177,6 +1183,7 @@ environment of the first jail. .Xr pkill 1 , .Xr ps 1 , .Xr quota 1 , +.Xr ifconfig 8 , .Xr jail_set 2 , .Xr devfs 5 , .Xr fdescfs 5 ,