summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJerry Jelinek <jerry.jelinek@joyent.com>2011-02-14 16:32:12 -0700
committerJerry Jelinek <jerry.jelinek@joyent.com>2011-02-14 16:32:12 -0700
commit2e90f839a513a397c7bc8eb94b3b7e0139120cb4 (patch)
treeace084a772f6bf1420d54798a6ea703b257209c1
parent18a2608d74a29b0a9383e81186b5db6e7a7cd804 (diff)
downloadillumos-joyent-2e90f839a513a397c7bc8eb94b3b7e0139120cb4.tar.gz
OS-224 add more zonecfg net properties
-rw-r--r--usr/src/cmd/zoneadm/zoneadm.c2
-rw-r--r--usr/src/cmd/zoneadmd/zoneadmd.c72
-rw-r--r--usr/src/cmd/zonecfg/zonecfg.c200
-rw-r--r--usr/src/cmd/zonecfg/zonecfg.h3
-rw-r--r--usr/src/cmd/zonecfg/zonecfg_grammar.y5
-rw-r--r--usr/src/cmd/zonecfg/zonecfg_lex.l10
-rw-r--r--usr/src/head/libzonecfg.h16
-rw-r--r--usr/src/lib/libzonecfg/common/libzonecfg.c140
-rw-r--r--usr/src/lib/libzonecfg/common/mapfile-vers3
-rw-r--r--usr/src/lib/libzonecfg/dtd/zonecfg.dtd.16
10 files changed, 409 insertions, 48 deletions
diff --git a/usr/src/cmd/zoneadm/zoneadm.c b/usr/src/cmd/zoneadm/zoneadm.c
index 9931505a10..342cabb0f3 100644
--- a/usr/src/cmd/zoneadm/zoneadm.c
+++ b/usr/src/cmd/zoneadm/zoneadm.c
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 201l, Joyent Inc. All rights reserved.
+ * Copyright (c) 2011, Joyent Inc. All rights reserved.
*/
/*
diff --git a/usr/src/cmd/zoneadmd/zoneadmd.c b/usr/src/cmd/zoneadmd/zoneadmd.c
index 9b7c1247d8..9a28e6c3f5 100644
--- a/usr/src/cmd/zoneadmd/zoneadmd.c
+++ b/usr/src/cmd/zoneadmd/zoneadmd.c
@@ -740,6 +740,73 @@ mount_early_fs(void *data, const char *spec, const char *dir,
}
/*
+ * env variable name format
+ * _ZONECFG;{resource name};{identifying attr. name};{property name}
+ */
+static void
+set_zonecfg_env(char *phys, char *name, char *val)
+{
+ char nm[MAXNAMELEN];
+
+ (void) snprintf(nm, sizeof (nm), "_ZONECFG;net;%s;%s", phys, name);
+
+ (void) setenv(nm, val, 1);
+}
+
+/*
+ * Export zonecfg network settings into environment for the boot and state
+ * change hooks.
+ *
+ * We could export more of the config in the future, as necessary.
+ */
+static int
+setup_subproc_env()
+{
+ int res;
+ zone_dochandle_t handle;
+ struct zone_nwiftab ntab;
+
+ if ((handle = zonecfg_init_handle()) == NULL)
+ exit(Z_NOMEM);
+
+ if ((res = zonecfg_get_handle(zone_name, handle)) != Z_OK)
+ goto done;
+
+ if ((res = zonecfg_setnwifent(handle)) != Z_OK)
+ goto done;
+
+ while (zonecfg_getnwifent(handle, &ntab) == Z_OK) {
+ struct zone_nwif_attrtab *np;
+ char *phys;
+
+ phys = ntab.zone_nwif_physical;
+
+ set_zonecfg_env(phys, "physical",
+ ntab.zone_nwif_physical);
+
+ set_zonecfg_env(phys, "address", ntab.zone_nwif_address);
+ set_zonecfg_env(phys, "allowed-address",
+ ntab.zone_nwif_allowed_address);
+ set_zonecfg_env(phys, "defrouter", ntab.zone_nwif_defrouter);
+ set_zonecfg_env(phys, "global-nic", ntab.zone_nwif_gnic);
+ set_zonecfg_env(phys, "mac-addr", ntab.zone_nwif_mac);
+ set_zonecfg_env(phys, "vlan-id", ntab.zone_nwif_vlan_id);
+
+ for (np = ntab.zone_nwif_attrp; np != NULL;
+ np = np->zone_nwif_attr_next)
+ set_zonecfg_env(phys, np->zone_nwif_attr_name,
+ np->zone_nwif_attr_value);
+ }
+
+ (void) zonecfg_endnwifent(handle);
+ res = Z_OK;
+
+done:
+ zonecfg_fini_handle(handle);
+ return (res);
+}
+
+/*
* If retstr is not NULL, the output of the subproc is returned in the str,
* otherwise it is output using zerror(). Any memory allocated for retstr
* should be freed by the caller.
@@ -764,6 +831,11 @@ do_subproc(zlog_t *zlogp, char *cmdbuf, char **retstr)
inbuf = buf;
}
+ if (setup_subproc_env() != Z_OK) {
+ zerror(zlogp, B_FALSE, "failed to setup environment");
+ return (-1);
+ }
+
file = popen(cmdbuf, "r");
if (file == NULL) {
zerror(zlogp, B_TRUE, "could not launch: %s", cmdbuf);
diff --git a/usr/src/cmd/zonecfg/zonecfg.c b/usr/src/cmd/zonecfg/zonecfg.c
index 76a63fbb57..981a45b82b 100644
--- a/usr/src/cmd/zonecfg/zonecfg.c
+++ b/usr/src/cmd/zonecfg/zonecfg.c
@@ -238,6 +238,7 @@ char *prop_types[] = {
"mac-addr",
"vlan-id",
"global-nic",
+ "property",
NULL
};
@@ -412,6 +413,13 @@ static const char *net_res_scope_cmds[] = {
"exit",
"help",
"info",
+ "add property ",
+ "clear allowed-address",
+ "clear defrouter",
+ "clear global-nic",
+ "clear mac-addr",
+ "clear vlan-id",
+ "remove property ",
"set address=",
"set allowed-address=",
"set defrouter=",
@@ -419,11 +427,6 @@ static const char *net_res_scope_cmds[] = {
"set mac-addr=",
"set physical=",
"set vlan-id=",
- "clear allowed-address",
- "clear defrouter",
- "clear global-nic",
- "clear mac-addr",
- "clear vlan-id",
NULL
};
@@ -1009,6 +1012,9 @@ usage(boolean_t verbose, uint_t flags)
(void) fprintf(fp, gettext("Valid commands:\n"));
(void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
pt_to_str(PT_ADDRESS), gettext("<IP-address>"));
+ (void) fprintf(fp, "\t%s %s (%s=<value>,%s=<value>)\n",
+ cmd_to_str(CMD_ADD), pt_to_str(PT_NPROP),
+ pt_to_str(PT_NAME), pt_to_str(PT_VALUE));
(void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
pt_to_str(PT_ALLOWED_ADDRESS),
gettext("<IP-address>"));
@@ -1017,9 +1023,9 @@ usage(boolean_t verbose, uint_t flags)
(void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
pt_to_str(PT_MAC), gettext("<mac-address>"));
(void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
- pt_to_str(PT_VLANID), gettext("<vlan ID>"));
- (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
pt_to_str(PT_GNIC), gettext("<global zone NIC>"));
+ (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
+ pt_to_str(PT_VLANID), gettext("<vlan ID>"));
(void) fprintf(fp, gettext("See ifconfig(1M) for "
"details of the <interface> string.\n"));
(void) fprintf(fp, gettext("%s %s is valid "
@@ -1277,12 +1283,12 @@ usage(boolean_t verbose, uint_t flags)
rt_to_str(RT_FS), pt_to_str(PT_DIR),
pt_to_str(PT_SPECIAL), pt_to_str(PT_RAW),
pt_to_str(PT_TYPE), pt_to_str(PT_OPTIONS));
- (void) fprintf(fp, "\t%s\t\t%s, %s, %s, %s, %s, %s|%s\n",
+ (void) fprintf(fp, "\t%s\t\t%s, %s, %s, %s, %s, %s, %s %s\n",
rt_to_str(RT_NET),
pt_to_str(PT_ADDRESS), pt_to_str(PT_ALLOWED_ADDRESS),
- pt_to_str(PT_PHYSICAL), pt_to_str(PT_MAC),
- pt_to_str(PT_VLANID), pt_to_str(PT_GNIC),
- pt_to_str(PT_DEFROUTER));
+ pt_to_str(PT_GNIC), pt_to_str(PT_MAC),
+ pt_to_str(PT_PHYSICAL), pt_to_str(PT_NPROP),
+ pt_to_str(PT_VLANID), pt_to_str(PT_DEFROUTER));
(void) fprintf(fp, "\t%s\t\t%s\n", rt_to_str(RT_DEVICE),
pt_to_str(PT_MATCH));
(void) fprintf(fp, "\t%s\t\t%s, %s\n", rt_to_str(RT_RCTL),
@@ -1641,7 +1647,7 @@ create_func(cmd_t *cmd)
break;
case 'X':
(void) snprintf(zone_template, sizeof (zone_template),
- "/etc/zones/%s.xml", zone);
+ "%s/%s.xml", ZONE_CONFIG_ROOT, zone);
err = zonecfg_get_xml_handle(zone_template, handle);
if (err != Z_OK) {
zone_perror(execname, err, B_TRUE);
@@ -1754,6 +1760,7 @@ export_func(cmd_t *cmd)
struct zone_psettab psettab;
struct zone_mcaptab mcaptab;
struct zone_rctlvaltab *valptr;
+ struct zone_nwif_attrtab *nap;
struct zone_admintab admintab;
int err, arg;
char zonepath[MAXPATHLEN], outfile[MAXPATHLEN], pool[MAXNAMELEN];
@@ -1927,6 +1934,13 @@ export_func(cmd_t *cmd)
export_prop(of, PT_VLANID, nwiftab.zone_nwif_vlan_id);
export_prop(of, PT_GNIC, nwiftab.zone_nwif_gnic);
export_prop(of, PT_DEFROUTER, nwiftab.zone_nwif_defrouter);
+ for (nap = nwiftab.zone_nwif_attrp; nap != NULL;
+ nap = nap->zone_nwif_attr_next) {
+ fprintf(of, "%s %s (%s=%s,%s=\"%s\")\n",
+ cmd_to_str(CMD_ADD), pt_to_str(PT_NPROP),
+ pt_to_str(PT_NAME), nap->zone_nwif_attr_name,
+ pt_to_str(PT_VALUE), nap->zone_nwif_attr_value);
+ }
(void) fprintf(of, "%s\n", cmd_to_str(CMD_END));
}
(void) zonecfg_endnwifent(handle);
@@ -2318,6 +2332,65 @@ bad:
}
static void
+do_nwif_attr(complex_property_ptr_t cpp)
+{
+ complex_property_ptr_t cp;
+ struct zone_nwif_attrtab *np;
+ int err;
+ boolean_t seen_name = B_FALSE, seen_value = B_FALSE;
+
+ if ((np = calloc(1, sizeof (struct zone_nwif_attrtab))) == NULL) {
+ zone_perror(zone, Z_NOMEM, B_TRUE);
+ exit(Z_ERR);
+ }
+
+ for (cp = cpp; cp != NULL; cp = cp->cp_next) {
+ switch (cp->cp_type) {
+ case PT_NAME:
+ if (seen_name) {
+ zerr(gettext("%s already specified"),
+ pt_to_str(PT_NAME));
+ goto bad;
+ }
+ (void) strlcpy(np->zone_nwif_attr_name, cp->cp_value,
+ sizeof (np->zone_nwif_attr_name));
+ seen_name = B_TRUE;
+ break;
+ case PT_VALUE:
+ if (seen_value) {
+ zerr(gettext("%s already specified"),
+ pt_to_str(PT_VALUE));
+ goto bad;
+ }
+ (void) strlcpy(np->zone_nwif_attr_value, cp->cp_value,
+ sizeof (np->zone_nwif_attr_value));
+ seen_value = B_TRUE;
+ break;
+ default:
+ zone_perror(pt_to_str(PT_NPROP), Z_NO_PROPERTY_TYPE,
+ B_TRUE);
+ long_usage(CMD_ADD, B_TRUE);
+ usage(B_FALSE, HELP_PROPS);
+ zonecfg_free_nwif_attr_list(np);
+ return;
+ }
+ }
+
+ if (!seen_name)
+ zerr(gettext("%s not specified"), pt_to_str(PT_NAME));
+ if (!seen_value)
+ zerr(gettext("%s not specified"), pt_to_str(PT_VALUE));
+
+ err = zonecfg_add_nwif_attr(&in_progress_nwiftab, np);
+ if (err != Z_OK)
+ zone_perror(pt_to_str(PT_NPROP), err, B_TRUE);
+ return;
+
+bad:
+ zonecfg_free_nwif_attr_list(np);
+}
+
+static void
add_property(cmd_t *cmd)
{
char *prop_id;
@@ -2384,6 +2457,24 @@ add_property(cmd_t *cmd)
}
}
return;
+ case RT_NET:
+ if (prop_type != PT_NPROP) {
+ zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
+ B_TRUE);
+ long_usage(CMD_ADD, B_TRUE);
+ usage(B_FALSE, HELP_PROPS);
+ return;
+ }
+ pp = cmd->cmd_property_ptr[0];
+ if (pp->pv_type != PROP_VAL_COMPLEX) {
+ zerr(gettext("A %s value was expected here."),
+ pvt_to_str(PROP_VAL_COMPLEX));
+ saw_error = B_TRUE;
+ return;
+ }
+
+ do_nwif_attr(pp->pv_complex);
+ return;
case RT_RCTL:
if (prop_type != PT_VALUE) {
zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
@@ -2488,8 +2579,9 @@ add_func(cmd_t *cmd)
resource_scope = cmd->cmd_res_type;
end_op = CMD_ADD;
add_resource(cmd);
- } else
+ } else {
add_property(cmd);
+ }
}
/*
@@ -3383,6 +3475,7 @@ remove_property(cmd_t *cmd)
int err, res_type, prop_type;
property_value_ptr_t pp;
struct zone_rctlvaltab *rctlvaltab;
+ struct zone_nwif_attrtab *np;
complex_property_ptr_t cx;
res_type = resource_scope;
@@ -3443,6 +3536,49 @@ remove_property(cmd_t *cmd)
}
}
return;
+ case RT_NET:
+ if (prop_type != PT_NPROP) {
+ zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
+ B_TRUE);
+ long_usage(CMD_REMOVE, B_TRUE);
+ usage(B_FALSE, HELP_PROPS);
+ return;
+ }
+ pp = cmd->cmd_property_ptr[0];
+ if (pp->pv_type != PROP_VAL_COMPLEX) {
+ zerr(gettext("A %s value was expected here."),
+ pvt_to_str(PROP_VAL_COMPLEX));
+ saw_error = B_TRUE;
+ return;
+ }
+
+ np = alloca(sizeof (struct zone_nwif_attrtab));
+ for (cx = pp->pv_complex; cx != NULL; cx = cx->cp_next) {
+ switch (cx->cp_type) {
+ case PT_NAME:
+ (void) strlcpy(np->zone_nwif_attr_name,
+ cx->cp_value,
+ sizeof (np->zone_nwif_attr_name));
+ break;
+ case PT_VALUE:
+ (void) strlcpy(np->zone_nwif_attr_value,
+ cx->cp_value,
+ sizeof (np->zone_nwif_attr_value));
+ break;
+ default:
+ zone_perror(pt_to_str(prop_type),
+ Z_NO_PROPERTY_TYPE, B_TRUE);
+ long_usage(CMD_REMOVE, B_TRUE);
+ usage(B_FALSE, HELP_PROPS);
+ return;
+ }
+ }
+ np->zone_nwif_attr_next = NULL;
+
+ err = zonecfg_remove_nwif_attr(&in_progress_nwiftab, np);
+ if (err != Z_OK)
+ zone_perror(pt_to_str(prop_type), err, B_TRUE);
+ return;
case RT_RCTL:
if (prop_type != PT_VALUE) {
zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
@@ -3495,18 +3631,6 @@ remove_property(cmd_t *cmd)
zone_perror(pt_to_str(prop_type), err, B_TRUE);
zonecfg_free_rctl_value_list(rctlvaltab);
return;
- case RT_NET:
- if (prop_type != PT_DEFROUTER) {
- zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
- B_TRUE);
- long_usage(CMD_REMOVE, B_TRUE);
- usage(B_FALSE, HELP_PROPS);
- return;
- } else {
- bzero(&in_progress_nwiftab.zone_nwif_defrouter,
- sizeof (in_progress_nwiftab.zone_nwif_defrouter));
- return;
- }
default:
zone_perror(rt_to_str(res_type), Z_NO_RESOURCE_TYPE, B_TRUE);
long_usage(CMD_REMOVE, B_TRUE);
@@ -4221,10 +4345,12 @@ set_func(cmd_t *cmd)
* A nasty expression but not that complicated:
* 1. fs options are simple or list (tested below)
* 2. rctl value's are complex or list (tested below)
+ * 3. net attr's are complex (tested below)
* Anything else should be simple.
*/
if (!(res_type == RT_FS && prop_type == PT_OPTIONS) &&
!(res_type == RT_RCTL && prop_type == PT_VALUE) &&
+ !(res_type == RT_NET && prop_type == PT_NPROP) &&
(pp->pv_type != PROP_VAL_SIMPLE ||
(prop_id = pp->pv_simple) == NULL)) {
zerr(gettext("A %s value was expected here."),
@@ -4512,6 +4638,20 @@ set_func(cmd_t *cmd)
prop_id,
sizeof (in_progress_nwiftab.zone_nwif_defrouter));
break;
+ case PT_NPROP:
+ if (pp->pv_type != PROP_VAL_COMPLEX) {
+ zerr(gettext("A %s value was expected here."),
+ pvt_to_str(PROP_VAL_COMPLEX));
+ saw_error = B_TRUE;
+ return;
+ }
+ zonecfg_free_nwif_attr_list(
+ in_progress_nwiftab.zone_nwif_attrp);
+ in_progress_nwiftab.zone_nwif_attrp = NULL;
+ if (!(pp->pv_type == PROP_VAL_LIST &&
+ pp->pv_list == NULL))
+ add_property(cmd);
+ break;
default:
zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
B_TRUE);
@@ -5051,6 +5191,8 @@ loopend:
static void
output_net(FILE *fp, struct zone_nwiftab *nwiftab)
{
+ struct zone_nwif_attrtab *np;
+
(void) fprintf(fp, "%s:\n", rt_to_str(RT_NET));
output_prop(fp, PT_ADDRESS, nwiftab->zone_nwif_address, B_TRUE);
output_prop(fp, PT_ALLOWED_ADDRESS,
@@ -5060,6 +5202,14 @@ output_net(FILE *fp, struct zone_nwiftab *nwiftab)
output_prop(fp, PT_MAC, nwiftab->zone_nwif_mac, B_TRUE);
output_prop(fp, PT_PHYSICAL, nwiftab->zone_nwif_physical, B_TRUE);
output_prop(fp, PT_VLANID, nwiftab->zone_nwif_vlan_id, B_TRUE);
+
+ for (np = nwiftab->zone_nwif_attrp; np != NULL;
+ np = np->zone_nwif_attr_next) {
+ fprintf(fp, "\t%s: (%s=%s,%s=\"%s\")\n",
+ pt_to_str(PT_NPROP),
+ pt_to_str(PT_NAME), np->zone_nwif_attr_name,
+ pt_to_str(PT_VALUE), np->zone_nwif_attr_value);
+ }
}
static void
diff --git a/usr/src/cmd/zonecfg/zonecfg.h b/usr/src/cmd/zonecfg/zonecfg.h
index d516949bac..960a35d8a1 100644
--- a/usr/src/cmd/zonecfg/zonecfg.h
+++ b/usr/src/cmd/zonecfg/zonecfg.h
@@ -143,9 +143,10 @@ extern "C" {
#define PT_MAC 43
#define PT_VLANID 44
#define PT_GNIC 45
+#define PT_NPROP 46
#define PT_MIN PT_UNKNOWN
-#define PT_MAX PT_GNIC
+#define PT_MAX PT_NPROP
#define MAX_EQ_PROP_PAIRS 3
diff --git a/usr/src/cmd/zonecfg/zonecfg_grammar.y b/usr/src/cmd/zonecfg/zonecfg_grammar.y
index da393be79e..521953a909 100644
--- a/usr/src/cmd/zonecfg/zonecfg_grammar.y
+++ b/usr/src/cmd/zonecfg/zonecfg_grammar.y
@@ -137,7 +137,7 @@ complex_piece_func(int cp_type, const char *str, complex_property_ptr_t cp_next)
%token OPEN_PAREN CLOSE_PAREN COMMA DATASET LIMITPRIV BOOTARGS BRAND PSET PCAP
%token MCAP NCPUS IMPORTANCE SHARES MAXLWPS MAXSHMMEM MAXSHMIDS MAXMSGIDS
%token MAXSEMIDS LOCKED SWAP SCHED CLEAR DEFROUTER ADMIN USER AUTHS MAXPROCS
-%token ZFSPRI MAC VLANID GNIC
+%token ZFSPRI MAC VLANID GNIC NPROP
%type <strval> TOKEN EQUAL OPEN_SQ_BRACKET CLOSE_SQ_BRACKET
property_value OPEN_PAREN CLOSE_PAREN COMMA simple_prop_val
@@ -147,7 +147,7 @@ complex_piece_func(int cp_type, const char *str, complex_property_ptr_t cp_next)
%type <ival> property_name SPECIAL RAW DIR OPTIONS TYPE ADDRESS PHYSICAL NAME
MATCH ZONENAME ZONEPATH AUTOBOOT POOL LIMITPRIV BOOTARGS VALUE PRIV LIMIT
ACTION BRAND SCHED IPTYPE DEFROUTER HOSTID USER AUTHS FS_ALLOWED
- ALLOWED_ADDRESS MAC VLANID GNIC
+ ALLOWED_ADDRESS MAC VLANID GNIC NPROP
%type <cmd> command
%type <cmd> add_command ADD
%type <cmd> cancel_command CANCEL
@@ -990,6 +990,7 @@ property_name: SPECIAL { $$ = PT_SPECIAL; }
| MAC { $$ = PT_MAC; }
| VLANID { $$ = PT_VLANID; }
| GNIC { $$ = PT_GNIC; }
+ | NPROP { $$ = PT_NPROP; }
| NAME { $$ = PT_NAME; }
| VALUE { $$ = PT_VALUE; }
| MATCH { $$ = PT_MATCH; }
diff --git a/usr/src/cmd/zonecfg/zonecfg_lex.l b/usr/src/cmd/zonecfg/zonecfg_lex.l
index 603be43807..21a48f3ec3 100644
--- a/usr/src/cmd/zonecfg/zonecfg_lex.l
+++ b/usr/src/cmd/zonecfg/zonecfg_lex.l
@@ -247,6 +247,9 @@ static char *create_token(char *s);
<TSTATE>global-nic { return GNIC; }
<CSTATE>global-nic { return GNIC; }
+<TSTATE>property { return NPROP; }
+<CSTATE>property { return NPROP; }
+
<TSTATE>dir { return DIR; }
<CSTATE>dir { return DIR; }
@@ -371,6 +374,13 @@ static char *create_token(char *s);
return TOKEN;
}
+<CSTATE>\"[^\"\n]*[\"\n] {
+ yylval.strval = create_token(yytext + 1);
+ if (yylval.strval[yyleng - 2] == '"')
+ yylval.strval[yyleng - 2] = 0;
+ return TOKEN;
+ }
+
<TSTATE>\"[^\"\n]*[\"\n] {
yylval.strval = create_token(yytext + 1);
if (yylval.strval[yyleng - 2] == '"')
diff --git a/usr/src/head/libzonecfg.h b/usr/src/head/libzonecfg.h
index 00bfe5642a..17292bff9a 100644
--- a/usr/src/head/libzonecfg.h
+++ b/usr/src/head/libzonecfg.h
@@ -129,6 +129,8 @@ extern "C" {
#define MAXAUTHS 4096
#define ZONE_MGMT_PROF "Zone Management"
+#define ZONE_INT32SZ 11 /* string to hold 32bit int. */
+
/* Owner, group, and mode (defined by packaging) for the config directory */
#define ZONE_CONFIG_UID 0 /* root */
#define ZONE_CONFIG_GID 3 /* sys */
@@ -194,14 +196,21 @@ struct zone_fstab {
char zone_fs_raw[MAXPATHLEN]; /* device to fsck */
};
+struct zone_nwif_attrtab {
+ char zone_nwif_attr_name[MAXNAMELEN];
+ char zone_nwif_attr_value[MAXNAMELEN];
+ struct zone_nwif_attrtab *zone_nwif_attr_next;
+};
+
struct zone_nwiftab {
char zone_nwif_address[INET6_ADDRSTRLEN]; /* shared-ip only */
char zone_nwif_allowed_address[INET6_ADDRSTRLEN]; /* excl-ip only */
char zone_nwif_physical[LIFNAMSIZ];
char zone_nwif_mac[MAXMACADDRLEN]; /* excl-ip only */
- char zone_nwif_vlan_id[10]; /* excl-ip only */
+ char zone_nwif_vlan_id[ZONE_INT32SZ]; /* excl-ip only */
char zone_nwif_gnic[LIFNAMSIZ]; /* excl-ip only */
char zone_nwif_defrouter[INET6_ADDRSTRLEN];
+ struct zone_nwif_attrtab *zone_nwif_attrp;
};
struct zone_devtab {
@@ -352,10 +361,15 @@ extern int zonecfg_find_mounts(char *, int(*)(const struct mnttab *,
* Network interface configuration.
*/
extern int zonecfg_add_nwif(zone_dochandle_t, struct zone_nwiftab *);
+extern int zonecfg_add_nwif_attr(struct zone_nwiftab *,
+ struct zone_nwif_attrtab *);
extern int zonecfg_delete_nwif(zone_dochandle_t, struct zone_nwiftab *);
+extern void zonecfg_free_nwif_attr_list(struct zone_nwif_attrtab *);
extern int zonecfg_modify_nwif(zone_dochandle_t, struct zone_nwiftab *,
struct zone_nwiftab *);
extern int zonecfg_lookup_nwif(zone_dochandle_t, struct zone_nwiftab *);
+extern int zonecfg_remove_nwif_attr(struct zone_nwiftab *,
+ struct zone_nwif_attrtab *);
/*
* Hostid emulation configuration.
diff --git a/usr/src/lib/libzonecfg/common/libzonecfg.c b/usr/src/lib/libzonecfg/common/libzonecfg.c
index ffe883467c..8d11fbe848 100644
--- a/usr/src/lib/libzonecfg/common/libzonecfg.c
+++ b/usr/src/lib/libzonecfg/common/libzonecfg.c
@@ -87,6 +87,7 @@
#define DTD_ELEM_FS (const xmlChar *) "filesystem"
#define DTD_ELEM_FSOPTION (const xmlChar *) "fsoption"
#define DTD_ELEM_NET (const xmlChar *) "network"
+#define DTD_ELEM_NETATTR (const xmlChar *) "net-attr"
#define DTD_ELEM_RCTL (const xmlChar *) "rctl"
#define DTD_ELEM_RCTLVALUE (const xmlChar *) "rctl-value"
#define DTD_ELEM_ZONE (const xmlChar *) "zone"
@@ -1764,6 +1765,15 @@ zonecfg_free_rctl_value_list(struct zone_rctlvaltab *valtab)
free(valtab);
}
+void
+zonecfg_free_nwif_attr_list(struct zone_nwif_attrtab *valtab)
+{
+ if (valtab == NULL)
+ return;
+ zonecfg_free_nwif_attr_list(valtab->zone_nwif_attr_next);
+ free(valtab);
+}
+
static boolean_t
match_prop(xmlNodePtr cur, const xmlChar *attr, char *user_prop)
{
@@ -2090,18 +2100,16 @@ zonecfg_ifname_exists(sa_family_t af, char *ifname)
int
zonecfg_lookup_nwif(zone_dochandle_t handle, struct zone_nwiftab *tabptr)
{
- xmlNodePtr cur;
+ xmlNodePtr cur, val;
xmlNodePtr firstmatch;
int err;
char address[INET6_ADDRSTRLEN];
char physical[LIFNAMSIZ];
char mac[MAXMACADDRLEN];
- char vlan_id[10];
char gnic[LIFNAMSIZ];
size_t addrspec; /* nonzero if tabptr has IP addr */
size_t physspec; /* nonzero if tabptr has interface */
size_t macspec; /* nonzero if tabptr has mac addr */
- size_t vlanidspec; /* nonzero if tabptr has vlan ID */
size_t gnicspec; /* nonzero if tabptr has gnic */
size_t defrouterspec; /* nonzero if tabptr has def. router */
size_t allowed_addrspec;
@@ -2121,15 +2129,13 @@ zonecfg_lookup_nwif(zone_dochandle_t handle, struct zone_nwiftab *tabptr)
addrspec = strlen(tabptr->zone_nwif_address);
physspec = strlen(tabptr->zone_nwif_physical);
macspec = strlen(tabptr->zone_nwif_mac);
- vlanidspec = strlen(tabptr->zone_nwif_vlan_id);
gnicspec = strlen(tabptr->zone_nwif_gnic);
defrouterspec = strlen(tabptr->zone_nwif_defrouter);
allowed_addrspec = strlen(tabptr->zone_nwif_allowed_address);
if (addrspec != 0 && allowed_addrspec != 0)
return (Z_INVAL); /* can't specify both */
if (addrspec == 0 && physspec == 0 && defrouterspec == 0 &&
- allowed_addrspec == 0 && macspec == 0 && vlanidspec == 0 &&
- gnicspec == 0)
+ allowed_addrspec == 0 && macspec == 0 && gnicspec == 0)
return (Z_INSUFFICIENT_SPEC);
if ((err = operation_prep(handle)) != Z_OK)
@@ -2160,11 +2166,6 @@ zonecfg_lookup_nwif(zone_dochandle_t handle, struct zone_nwiftab *tabptr)
(fetchprop(cur, DTD_ATTR_MAC, mac, sizeof (mac)) != Z_OK ||
strcmp(tabptr->zone_nwif_mac, mac) != 0))
continue;
- if (iptype == ZS_EXCLUSIVE && vlanidspec != 0 &&
- (fetchprop(cur, DTD_ATTR_VLANID, vlan_id,
- sizeof (vlan_id)) != Z_OK ||
- strcmp(tabptr->zone_nwif_vlan_id, vlan_id) != 0))
- continue;
if (iptype == ZS_EXCLUSIVE && gnicspec != 0 &&
(fetchprop(cur, DTD_ATTR_GNIC, gnic,
sizeof (gnic)) != Z_OK ||
@@ -2237,13 +2238,39 @@ zonecfg_lookup_nwif(zone_dochandle_t handle, struct zone_nwiftab *tabptr)
sizeof (tabptr->zone_nwif_defrouter))) != Z_OK)
return (err);
+ tabptr->zone_nwif_attrp = NULL;
+ for (val = cur->xmlChildrenNode; val != NULL; val = val->next) {
+ struct zone_nwif_attrtab *valptr;
+
+ valptr = (struct zone_nwif_attrtab *)malloc(
+ sizeof (struct zone_nwif_attrtab));
+ if (valptr == NULL)
+ return (Z_NOMEM);
+
+ valptr->zone_nwif_attr_name[0] =
+ valptr->zone_nwif_attr_value[0] = '\0';
+ if (zonecfg_add_nwif_attr(tabptr, valptr) != Z_OK) {
+ free(valptr);
+ break;
+ }
+
+ if ((fetchprop(val, DTD_ATTR_NAME, valptr->zone_nwif_attr_name,
+ sizeof (valptr->zone_nwif_attr_name)) != Z_OK))
+ break;
+ if ((fetchprop(val, DTD_ATTR_VALUE,
+ valptr->zone_nwif_attr_value,
+ sizeof (valptr->zone_nwif_attr_value)) != Z_OK))
+ break;
+ }
+
return (Z_OK);
}
static int
zonecfg_add_nwif_core(zone_dochandle_t handle, struct zone_nwiftab *tabptr)
{
- xmlNodePtr newnode, cur = handle->zone_dh_cur;
+ xmlNodePtr newnode, cur = handle->zone_dh_cur, valnode;
+ struct zone_nwif_attrtab *valptr;
int err;
newnode = xmlNewTextChild(cur, NULL, DTD_ELEM_NET, NULL);
@@ -2278,6 +2305,21 @@ zonecfg_add_nwif_core(zone_dochandle_t handle, struct zone_nwiftab *tabptr)
(err = newprop(newnode, DTD_ATTR_GNIC,
tabptr->zone_nwif_gnic)) != Z_OK)
return (err);
+
+ for (valptr = tabptr->zone_nwif_attrp; valptr != NULL;
+ valptr = valptr->zone_nwif_attr_next) {
+ valnode = xmlNewTextChild(newnode, NULL, DTD_ELEM_NETATTR,
+ NULL);
+ err = newprop(valnode, DTD_ATTR_NAME,
+ valptr->zone_nwif_attr_name);
+ if (err != Z_OK)
+ return (err);
+ err = newprop(valnode, DTD_ATTR_VALUE,
+ valptr->zone_nwif_attr_value);
+ if (err != Z_OK)
+ return (err);
+ }
+
return (Z_OK);
}
@@ -2303,7 +2345,7 @@ zonecfg_delete_nwif_core(zone_dochandle_t handle, struct zone_nwiftab *tabptr)
{
xmlNodePtr cur = handle->zone_dh_cur;
boolean_t addr_match, phys_match, allowed_addr_match, mac_match,
- vlan_id_match, gnic_match;
+ gnic_match;
for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) {
if (xmlStrcmp(cur->name, DTD_ELEM_NET))
@@ -2317,13 +2359,11 @@ zonecfg_delete_nwif_core(zone_dochandle_t handle, struct zone_nwiftab *tabptr)
tabptr->zone_nwif_physical);
mac_match = match_prop(cur, DTD_ATTR_MAC,
tabptr->zone_nwif_mac);
- vlan_id_match = match_prop(cur, DTD_ATTR_VLANID,
- tabptr->zone_nwif_vlan_id);
gnic_match = match_prop(cur, DTD_ATTR_GNIC,
tabptr->zone_nwif_gnic);
if ((addr_match || allowed_addr_match || mac_match ||
- vlan_id_match || gnic_match) && phys_match) {
+ gnic_match) && phys_match) {
xmlUnlinkNode(cur);
xmlFreeNode(cur);
return (Z_OK);
@@ -2372,6 +2412,49 @@ zonecfg_modify_nwif(
return (Z_OK);
}
+int
+zonecfg_add_nwif_attr(struct zone_nwiftab *tabptr,
+ struct zone_nwif_attrtab *valtabptr)
+{
+ struct zone_nwif_attrtab *last, *old, *new;
+
+ last = tabptr->zone_nwif_attrp;
+ for (old = last; old != NULL; old = old->zone_nwif_attr_next)
+ last = old; /* walk to the end of the list */
+ new = valtabptr; /* alloc'd by caller */
+ new->zone_nwif_attr_next = NULL;
+ if (last == NULL)
+ tabptr->zone_nwif_attrp = new;
+ else
+ last->zone_nwif_attr_next = new;
+ return (Z_OK);
+}
+
+int
+zonecfg_remove_nwif_attr(struct zone_nwiftab *tabptr,
+ struct zone_nwif_attrtab *valtabptr)
+{
+ struct zone_nwif_attrtab *last, *this, *next;
+
+ last = tabptr->zone_nwif_attrp;
+ for (this = last; this != NULL; this = this->zone_nwif_attr_next) {
+ if (strcmp(this->zone_nwif_attr_name,
+ valtabptr->zone_nwif_attr_name) == 0 &&
+ strcmp(this->zone_nwif_attr_value,
+ valtabptr->zone_nwif_attr_value) == 0) {
+ next = this->zone_nwif_attr_next;
+ if (this == tabptr->zone_nwif_attrp)
+ tabptr->zone_nwif_attrp = next;
+ else
+ last->zone_nwif_attr_next = next;
+ free(this);
+ return (Z_OK);
+ } else
+ last = this;
+ }
+ return (Z_NO_PROPERTY_ID);
+}
+
/*
* Must be a comma-separated list of alpha-numeric file system names.
*/
@@ -4778,7 +4861,8 @@ zonecfg_setnwifent(zone_dochandle_t handle)
int
zonecfg_getnwifent(zone_dochandle_t handle, struct zone_nwiftab *tabptr)
{
- xmlNodePtr cur;
+ xmlNodePtr cur, val;
+ struct zone_nwif_attrtab *valptr;
int err;
if (handle == NULL)
@@ -4839,6 +4923,28 @@ zonecfg_getnwifent(zone_dochandle_t handle, struct zone_nwiftab *tabptr)
return (err);
}
+ tabptr->zone_nwif_attrp = NULL;
+ for (val = cur->xmlChildrenNode; val != NULL; val = val->next) {
+ valptr = (struct zone_nwif_attrtab *)malloc(
+ sizeof (struct zone_nwif_attrtab));
+ if (valptr == NULL)
+ return (Z_NOMEM);
+
+ valptr->zone_nwif_attr_name[0] =
+ valptr->zone_nwif_attr_value[0] = '\0';
+ if (zonecfg_add_nwif_attr(tabptr, valptr) != Z_OK) {
+ free(valptr);
+ break;
+ }
+
+ if (fetchprop(val, DTD_ATTR_NAME, valptr->zone_nwif_attr_name,
+ sizeof (valptr->zone_nwif_attr_name)) != Z_OK)
+ break;
+ if (fetchprop(val, DTD_ATTR_VALUE, valptr->zone_nwif_attr_value,
+ sizeof (valptr->zone_nwif_attr_value)) != Z_OK)
+ break;
+ }
+
handle->zone_dh_cur = cur->next;
return (Z_OK);
}
diff --git a/usr/src/lib/libzonecfg/common/mapfile-vers b/usr/src/lib/libzonecfg/common/mapfile-vers
index 0f3e1bdd31..d413c901f0 100644
--- a/usr/src/lib/libzonecfg/common/mapfile-vers
+++ b/usr/src/lib/libzonecfg/common/mapfile-vers
@@ -54,6 +54,7 @@ SYMBOL_VERSION SUNWprivate_1.1 {
zonecfg_add_fs_option;
zonecfg_add_admin;
zonecfg_add_nwif;
+ zonecfg_add_nwif_attr;
zonecfg_add_pkg;
zonecfg_add_pset;
zonecfg_add_rctl;
@@ -106,6 +107,7 @@ SYMBOL_VERSION SUNWprivate_1.1 {
zonecfg_find_scratch;
zonecfg_fini_handle;
zonecfg_free_fs_option_list;
+ zonecfg_free_nwif_attr_list;
zonecfg_free_rctl_value_list;
zonecfg_get_aliased_rctl;
zonecfg_get_attach_handle;
@@ -185,6 +187,7 @@ SYMBOL_VERSION SUNWprivate_1.1 {
zonecfg_ping_zoneadmd;
zonecfg_release_lock_file;
zonecfg_remove_fs_option;
+ zonecfg_remove_nwif_attr;
zonecfg_remove_rctl_value;
zonecfg_remove_userauths;
zonecfg_reverse_scratch;
diff --git a/usr/src/lib/libzonecfg/dtd/zonecfg.dtd.1 b/usr/src/lib/libzonecfg/dtd/zonecfg.dtd.1
index ede584430d..976e721c5f 100644
--- a/usr/src/lib/libzonecfg/dtd/zonecfg.dtd.1
+++ b/usr/src/lib/libzonecfg/dtd/zonecfg.dtd.1
@@ -47,7 +47,11 @@
<!ATTLIST inherited-pkg-dir directory CDATA #REQUIRED>
-<!ELEMENT network EMPTY>
+<!ELEMENT net-attr EMPTY>
+<!ATTLIST net-attr name CDATA #REQUIRED
+ value CDATA #REQUIRED>
+
+<!ELEMENT network (net-attr)*>
<!ATTLIST network address CDATA ""
allowed-address CDATA ""