diff options
author | Jerry Jelinek <jerry.jelinek@joyent.com> | 2011-02-14 16:32:12 -0700 |
---|---|---|
committer | Jerry Jelinek <jerry.jelinek@joyent.com> | 2011-02-14 16:32:12 -0700 |
commit | 2e90f839a513a397c7bc8eb94b3b7e0139120cb4 (patch) | |
tree | ace084a772f6bf1420d54798a6ea703b257209c1 | |
parent | 18a2608d74a29b0a9383e81186b5db6e7a7cd804 (diff) | |
download | illumos-joyent-2e90f839a513a397c7bc8eb94b3b7e0139120cb4.tar.gz |
OS-224 add more zonecfg net properties
-rw-r--r-- | usr/src/cmd/zoneadm/zoneadm.c | 2 | ||||
-rw-r--r-- | usr/src/cmd/zoneadmd/zoneadmd.c | 72 | ||||
-rw-r--r-- | usr/src/cmd/zonecfg/zonecfg.c | 200 | ||||
-rw-r--r-- | usr/src/cmd/zonecfg/zonecfg.h | 3 | ||||
-rw-r--r-- | usr/src/cmd/zonecfg/zonecfg_grammar.y | 5 | ||||
-rw-r--r-- | usr/src/cmd/zonecfg/zonecfg_lex.l | 10 | ||||
-rw-r--r-- | usr/src/head/libzonecfg.h | 16 | ||||
-rw-r--r-- | usr/src/lib/libzonecfg/common/libzonecfg.c | 140 | ||||
-rw-r--r-- | usr/src/lib/libzonecfg/common/mapfile-vers | 3 | ||||
-rw-r--r-- | usr/src/lib/libzonecfg/dtd/zonecfg.dtd.1 | 6 |
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 "" |