diff options
author | Eric Cheng <none@none> | 2009-10-07 14:39:04 -0700 |
---|---|---|
committer | Eric Cheng <none@none> | 2009-10-07 14:39:04 -0700 |
commit | 25ec3e3dd27cc1038c10efa18ed08f064eab5fbe (patch) | |
tree | 8e5ece639c198513f5115cd16c6f21616b943dde /usr/src/lib/libdladm | |
parent | 0ff6bfafbd510fac2721570482eceb0d24afe291 (diff) | |
download | illumos-joyent-25ec3e3dd27cc1038c10efa18ed08f064eab5fbe.tar.gz |
PSARC/2009/436 Anti-spoofing Link Protection
PSARC/2009/488 flowadm(1m) remote_port flow attribute
6884729 Integrate Link Protection Phase I
6882391 Offer flowadm -a remote_port
Diffstat (limited to 'usr/src/lib/libdladm')
-rw-r--r-- | usr/src/lib/libdladm/common/flowattr.c | 30 | ||||
-rw-r--r-- | usr/src/lib/libdladm/common/flowprop.c | 6 | ||||
-rw-r--r-- | usr/src/lib/libdladm/common/libdladm.c | 90 | ||||
-rw-r--r-- | usr/src/lib/libdladm/common/libdladm.h | 7 | ||||
-rw-r--r-- | usr/src/lib/libdladm/common/libdladm_impl.h | 10 | ||||
-rw-r--r-- | usr/src/lib/libdladm/common/libdlflow.c | 20 | ||||
-rw-r--r-- | usr/src/lib/libdladm/common/linkprop.c | 248 | ||||
-rw-r--r-- | usr/src/lib/libdladm/common/mapfile-vers | 4 |
8 files changed, 351 insertions, 64 deletions
diff --git a/usr/src/lib/libdladm/common/flowattr.c b/usr/src/lib/libdladm/common/flowattr.c index cbf31abc80..fd44c8bed9 100644 --- a/usr/src/lib/libdladm/common/flowattr.c +++ b/usr/src/lib/libdladm/common/flowattr.c @@ -50,15 +50,17 @@ static fad_checkf_t do_check_local_ip; static fad_checkf_t do_check_remote_ip; static fad_checkf_t do_check_protocol; static fad_checkf_t do_check_local_port; +static fad_checkf_t do_check_remote_port; static dladm_status_t do_check_port(char *, boolean_t, flow_desc_t *); static fattr_desc_t attr_table[] = { - { "local_ip", do_check_local_ip }, - { "remote_ip", do_check_remote_ip }, - { "transport", do_check_protocol }, - { "local_port", do_check_local_port }, - { "dsfield", do_check_dsfield }, + { "local_ip", do_check_local_ip }, + { "remote_ip", do_check_remote_ip }, + { "transport", do_check_protocol }, + { "local_port", do_check_local_port }, + { "remote_port", do_check_remote_port }, + { "dsfield", do_check_dsfield }, }; #define DLADM_MAX_FLOWATTRS (sizeof (attr_table) / sizeof (fattr_desc_t)) @@ -162,19 +164,26 @@ do_check_local_port(char *attr_val, flow_desc_t *fdesc) } dladm_status_t +do_check_remote_port(char *attr_val, flow_desc_t *fdesc) +{ + return (do_check_port(attr_val, B_FALSE, fdesc)); +} + +dladm_status_t do_check_port(char *attr_val, boolean_t local, flow_desc_t *fdesc) { char *endp = NULL; long val; + val = strtol(attr_val, &endp, 10); + if (val < 1 || val > MAX_PORT || *endp != '\0') + return (DLADM_STATUS_INVALID_PORT); if (local) { fdesc->fd_mask |= FLOW_ULP_PORT_LOCAL; - val = strtol(attr_val, &endp, 10); - if (val < 1 || val > MAX_PORT) - return (DLADM_STATUS_INVALID_PORT); fdesc->fd_local_port = htons((uint16_t)val); } else { - return (DLADM_STATUS_BADVAL); + fdesc->fd_mask |= FLOW_ULP_PORT_REMOTE; + fdesc->fd_remote_port = htons((uint16_t)val); } return (DLADM_STATUS_OK); @@ -391,6 +400,9 @@ dladm_flow_attr_port2str(dladm_flow_attr_t *attrp, char *buf, size_t buf_len) if (fdesc.fd_mask & FLOW_ULP_PORT_LOCAL) { (void) snprintf(buf, buf_len, "%d", ntohs(fdesc.fd_local_port)); + } else if (fdesc.fd_mask & FLOW_ULP_PORT_REMOTE) { + (void) snprintf(buf, buf_len, "%d", + ntohs(fdesc.fd_remote_port)); } else { buf[0] = '\0'; } diff --git a/usr/src/lib/libdladm/common/flowprop.c b/usr/src/lib/libdladm/common/flowprop.c index 067f3a020f..25cb714176 100644 --- a/usr/src/lib/libdladm/common/flowprop.c +++ b/usr/src/lib/libdladm/common/flowprop.c @@ -493,7 +493,7 @@ dladm_parse_flow_props(char *str, dladm_arg_list_t **listp, boolean_t novalues) */ static dladm_status_t i_dladm_flow_proplist_extract_one(dladm_arg_list_t *proplist, - const char *name, void *val) + const char *name, void *arg) { dladm_status_t status; dladm_arg_info_t *aip = NULL; @@ -543,8 +543,8 @@ i_dladm_flow_proplist_extract_one(dladm_arg_list_t *proplist, /* Extract kernel structure */ if (rpp->rp_extract != NULL) { - status = rpp->rp_extract(vdp, val, - aip->ai_count); + status = rpp->rp_extract(vdp, + aip->ai_count, arg); } else { status = DLADM_STATUS_BADARG; } diff --git a/usr/src/lib/libdladm/common/libdladm.c b/usr/src/lib/libdladm/common/libdladm.c index 9e03468c7d..8939d23331 100644 --- a/usr/src/lib/libdladm/common/libdladm.c +++ b/usr/src/lib/libdladm/common/libdladm.c @@ -30,6 +30,8 @@ #include <strings.h> #include <dirent.h> #include <stdlib.h> +#include <netinet/in.h> +#include <arpa/inet.h> #include <sys/param.h> #include <sys/stat.h> #include <sys/dld.h> @@ -80,6 +82,18 @@ static media_type_t media_type_table[] = { }; #define MEDIATYPECOUNT (sizeof (media_type_table) / sizeof (media_type_t)) +typedef struct { + uint32_t lp_type; + char *lp_name; +} link_protect_t; + +static link_protect_t link_protect_types[] = { + { MPT_MACNOSPOOF, "mac-nospoof" }, + { MPT_IPNOSPOOF, "ip-nospoof" }, + { MPT_RESTRICTED, "restricted" } +}; +#define LPTYPES (sizeof (link_protect_types) / sizeof (link_protect_t)) + dladm_status_t dladm_open(dladm_handle_t *handle) { @@ -836,6 +850,82 @@ dladm_pri2str(mac_priority_level_t pri, char *buf) return (buf); } +/* + * Convert protect string to a value. + */ +dladm_status_t +dladm_str2protect(char *token, uint32_t *ptype) +{ + link_protect_t *lp; + int i; + + for (i = 0; i < LPTYPES; i++) { + lp = &link_protect_types[i]; + if (strcmp(token, lp->lp_name) == 0) { + *ptype = lp->lp_type; + return (DLADM_STATUS_OK); + } + } + return (DLADM_STATUS_BADVAL); +} + +/* + * Convert protect value to a string. + */ +const char * +dladm_protect2str(uint32_t ptype, char *buf) +{ + const char *s = "--"; + link_protect_t *lp; + int i; + + for (i = 0; i < LPTYPES; i++) { + lp = &link_protect_types[i]; + if (lp->lp_type == ptype) { + s = lp->lp_name; + break; + } + } + (void) snprintf(buf, DLADM_STRSIZE, "%s", dgettext(TEXT_DOMAIN, s)); + return (buf); +} + +/* + * Convert an IPv4 address to/from a string. + */ +const char * +dladm_ipv4addr2str(void *addr, char *buf) +{ + if (inet_ntop(AF_INET, addr, buf, INET_ADDRSTRLEN) == NULL) + buf[0] = 0; + + return (buf); +} + +dladm_status_t +dladm_str2ipv4addr(char *token, void *addr) +{ + return (inet_pton(AF_INET, token, addr) == 1 ? + DLADM_STATUS_OK : DLADM_STATUS_INVALID_IP); +} + +/* + * Find the set bits in a mask. + * This is used for expanding a bitmask into individual sub-masks + * which can be used for further processing. + */ +void +dladm_find_setbits32(uint32_t mask, uint32_t *list, uint32_t *cnt) +{ + int i, c = 0; + + for (i = 0; i < 32; i++) { + if (((1 << i) & mask) != 0) + list[c++] = 1 << i; + } + *cnt = c; +} + void dladm_free_args(dladm_arg_list_t *list) { diff --git a/usr/src/lib/libdladm/common/libdladm.h b/usr/src/lib/libdladm/common/libdladm.h index 0e9a066083..1cddd9c66e 100644 --- a/usr/src/lib/libdladm/common/libdladm.h +++ b/usr/src/lib/libdladm/common/libdladm.h @@ -27,6 +27,7 @@ #define _LIBDLADM_H #include <sys/dls_mgmt.h> +#include <sys/dld.h> #include <sys/dlpi.h> /* @@ -224,6 +225,12 @@ extern boolean_t dladm_valid_linkname(const char *); extern boolean_t dladm_str2interval(char *, uint32_t *); extern dladm_status_t dladm_str2bw(char *, uint64_t *); extern const char *dladm_bw2str(int64_t, char *); +extern dladm_status_t dladm_str2pri(char *, mac_priority_level_t *); +extern const char *dladm_pri2str(mac_priority_level_t, char *); +extern dladm_status_t dladm_str2protect(char *, uint32_t *); +extern const char *dladm_protect2str(uint32_t, char *); +extern dladm_status_t dladm_str2ipv4addr(char *, void *); +extern const char *dladm_ipv4addr2str(void *, char *); extern dladm_status_t dladm_parse_flow_props(char *, dladm_arg_list_t **, boolean_t); diff --git a/usr/src/lib/libdladm/common/libdladm_impl.h b/usr/src/lib/libdladm/common/libdladm_impl.h index 61e584a051..f11ba5edd3 100644 --- a/usr/src/lib/libdladm/common/libdladm_impl.h +++ b/usr/src/lib/libdladm/common/libdladm_impl.h @@ -59,9 +59,7 @@ extern dladm_status_t i_dladm_rw_db(dladm_handle_t, const char *, mode_t, FILE *), void *, boolean_t); extern dladm_status_t i_dladm_get_state(dladm_handle_t, datalink_id_t, link_state_t *); - -extern const char *dladm_pri2str(mac_priority_level_t, char *); -extern dladm_status_t dladm_str2pri(char *, mac_priority_level_t *); +extern void dladm_find_setbits32(uint32_t, uint32_t *, uint32_t *); extern dladm_status_t dladm_parse_args(char *, dladm_arg_list_t **, boolean_t); extern void dladm_free_args(dladm_arg_list_t *); @@ -140,10 +138,10 @@ extern dladm_status_t dladm_flow_proplist_extract(dladm_arg_list_t *, * rp_extract extracts the kernel structure from the val_desc_t created * by the pd_check function. */ -typedef dladm_status_t rp_extractf_t(val_desc_t *propval, void *arg, - uint_t cnt); +typedef dladm_status_t rp_extractf_t(val_desc_t *, uint_t, void *); extern rp_extractf_t do_extract_maxbw, do_extract_priority, - do_extract_cpus; + do_extract_cpus, do_extract_protection, + do_extract_allowedips; typedef struct resource_prop_s { /* diff --git a/usr/src/lib/libdladm/common/libdlflow.c b/usr/src/lib/libdladm/common/libdlflow.c index da85f361ae..0f9a3e0af5 100644 --- a/usr/src/lib/libdladm/common/libdlflow.c +++ b/usr/src/lib/libdladm/common/libdlflow.c @@ -72,6 +72,7 @@ static const char *LOCAL_IP_ADDR = "local_ip"; static const char *REMOTE_IP_ADDR = "remote_ip"; static const char *TRANSPORT = "transport"; static const char *LOCAL_PORT = "local_port"; +static const char *REMOTE_PORT = "remote_port"; static const char *DSFIELD = "dsfield"; /* @@ -131,7 +132,6 @@ dladm_flow_parse_db(char *line, dld_flowinfo_t *attr) { char *token; char *value, *name = NULL; - char *endp = NULL; char *lasts = NULL; dladm_status_t status = DLADM_STATUS_FLOW_DB_PARSE_ERR; @@ -156,7 +156,7 @@ dladm_flow_parse_db(char *line, dld_flowinfo_t *attr) if (strcmp(name, "linkid") == 0) { if ((attr->fi_linkid = - (uint32_t)strtol(value, &endp, 10)) == + (uint32_t)strtol(value, NULL, 10)) == DATALINK_INVALID_LINKID) goto done; @@ -164,7 +164,7 @@ dladm_flow_parse_db(char *line, dld_flowinfo_t *attr) attr->fi_resource_props.mrp_mask |= MRP_MAXBW; attr->fi_resource_props.mrp_maxbw = - (uint64_t)strtol(value, &endp, 0); + (uint64_t)strtol(value, NULL, 0); } else if (strcmp(name, PRIORITY) == 0) { attr->fi_resource_props.mrp_mask |= MRP_PRIORITY; @@ -194,14 +194,20 @@ dladm_flow_parse_db(char *line, dld_flowinfo_t *attr) } else if (strcmp(name, TRANSPORT) == 0) { attr->fi_flow_desc.fd_mask |= FLOW_IP_PROTOCOL; attr->fi_flow_desc.fd_protocol = - (uint8_t)strtol(value, &endp, 0); + (uint8_t)strtol(value, NULL, 0); } else if (strcmp(name, LOCAL_PORT) == 0) { attr->fi_flow_desc.fd_mask |= FLOW_ULP_PORT_LOCAL; attr->fi_flow_desc.fd_local_port = - (uint16_t)strtol(value, &endp, 10); + (uint16_t)strtol(value, NULL, 10); attr->fi_flow_desc.fd_local_port = htons(attr->fi_flow_desc.fd_local_port); + } else if (strcmp(name, REMOTE_PORT) == 0) { + attr->fi_flow_desc.fd_mask |= FLOW_ULP_PORT_REMOTE; + attr->fi_flow_desc.fd_remote_port = + (uint16_t)strtol(value, NULL, 10); + attr->fi_flow_desc.fd_remote_port = + htons(attr->fi_flow_desc.fd_remote_port); } free(name); name = NULL; @@ -303,6 +309,10 @@ i_dladm_flow_fput_grp(FILE *fp, dld_flowinfo_t *attr) FPRINTF_ERR(fprintf(fp, "%s=%d\t", LOCAL_PORT, ntohs(attr->fi_flow_desc.fd_local_port))); + if (attr->fi_flow_desc.fd_mask & FLOW_ULP_PORT_REMOTE) + FPRINTF_ERR(fprintf(fp, "%s=%d\t", REMOTE_PORT, + ntohs(attr->fi_flow_desc.fd_remote_port))); + FPRINTF_ERR(fprintf(fp, "\n")); return (0); diff --git a/usr/src/lib/libdladm/common/linkprop.c b/usr/src/lib/libdladm/common/linkprop.c index d77707be99..eca1aecd7f 100644 --- a/usr/src/lib/libdladm/common/linkprop.c +++ b/usr/src/lib/libdladm/common/linkprop.c @@ -51,7 +51,6 @@ #include <sys/param.h> #include <sys/debug.h> #include <sys/dld.h> -#include <sys/mac_flow.h> #include <inttypes.h> #include <sys/ethernet.h> #include <inet/iptun.h> @@ -139,17 +138,21 @@ static pd_getf_t do_get_zone, do_get_autopush, do_get_rate_mod, i_dladm_cpus_get, i_dladm_priority_get, i_dladm_tagmode_get, i_dladm_range_get, get_stp_prop, get_bridge_forward, - get_bridge_pvid; + get_bridge_pvid, + /* the above need to be renamed to "do_get_xxx" */ + do_get_protection; static pd_setf_t do_set_zone, do_set_rate_prop, do_set_powermode_prop, do_set_radio_prop, i_dladm_set_public_prop, do_set_res, do_set_cpus, - set_stp_prop, set_bridge_forward, set_bridge_pvid; + set_stp_prop, set_bridge_forward, set_bridge_pvid, + do_set_protection; static pd_checkf_t do_check_zone, do_check_autopush, do_check_rate, do_check_hoplimit, do_check_encaplim, i_dladm_uint32_check, do_check_maxbw, do_check_cpus, - do_check_priority, check_stp_prop, check_bridge_pvid; + do_check_priority, check_stp_prop, check_bridge_pvid, + do_check_allowedips, do_check_prop; static dladm_status_t i_dladm_speed_get(dladm_handle_t, prop_desc_t *, datalink_id_t, char **, uint_t *, uint_t, uint_t *); @@ -341,8 +344,9 @@ static link_attr_t link_attr[] = { { MAC_PROP_LDECAY, sizeof (uint32_t), "learn_decay"}, - { MAC_PROP_PRIVATE, 0, "driver-private"} + { MAC_PROP_PROTECT, sizeof (mac_resource_props_t), "protection"}, + { MAC_PROP_PRIVATE, 0, "driver-private"} }; typedef struct bridge_public_prop_s { @@ -389,6 +393,12 @@ static val_desc_t link_tagmode_vals[] = { { "vlanonly", LINK_TAGMODE_VLANONLY } }; +static val_desc_t link_protect_vals[] = { + { "mac-nospoof", MPT_MACNOSPOOF }, + { "ip-nospoof", MPT_IPNOSPOOF }, + { "restricted", MPT_RESTRICTED } +}; + static val_desc_t dladm_wlan_radio_vals[] = { { "on", DLADM_WLAN_RADIO_ON }, { "off", DLADM_WLAN_RADIO_OFF } @@ -622,6 +632,16 @@ static prop_desc_t prop_table[] = { set_stp_prop, NULL, get_stp_prop, check_stp_prop, PD_AFTER_PERM, DATALINK_CLASS_PHYS|DATALINK_CLASS_AGGR| DATALINK_CLASS_ETHERSTUB|DATALINK_CLASS_SIMNET, DL_ETHER }, + + { "protection", { "--", RESET_VAL }, + link_protect_vals, VALCNT(link_protect_vals), + do_set_protection, NULL, do_get_protection, do_check_prop, 0, + DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, + + { "allowed-ips", { "--", 0 }, + NULL, 0, do_set_protection, NULL, + do_get_protection, do_check_allowedips, 0, + DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, }; #define DLADM_MAX_PROPS (sizeof (prop_table) / sizeof (prop_desc_t)) @@ -629,7 +649,9 @@ static prop_desc_t prop_table[] = { static resource_prop_t rsrc_prop_table[] = { {"maxbw", do_extract_maxbw}, {"priority", do_extract_priority}, - {"cpus", do_extract_cpus} + {"cpus", do_extract_cpus}, + {"protection", do_extract_protection}, + {"allowed-ips", do_extract_allowedips} }; #define DLADM_MAX_RSRC_PROP (sizeof (rsrc_prop_table) / \ sizeof (resource_prop_t)) @@ -667,29 +689,26 @@ static dladm_status_t i_dladm_getset_defval(dladm_handle_t, prop_desc_t *, #define AP_ANCHOR "[anchor]" #define AP_DELIMITER '.' +/* ARGSUSED */ static dladm_status_t -do_check_prop(prop_desc_t *pdp, char **prop_val, uint_t val_cnt, - val_desc_t *vdp) +do_check_prop(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, + char **prop_val, uint_t val_cnt, val_desc_t *vdp, datalink_media_t media) { int i, j; - dladm_status_t status = DLADM_STATUS_OK; for (j = 0; j < val_cnt; j++) { for (i = 0; i < pdp->pd_noptval; i++) { - if (strcasecmp(*prop_val, + if (strcasecmp(prop_val[j], pdp->pd_optval[i].vd_name) == 0) { break; } } - if (i == pdp->pd_noptval) { - status = DLADM_STATUS_BADVAL; - goto done; - } - (void) memcpy(vdp + j, &pdp->pd_optval[i], sizeof (val_desc_t)); - } + if (i == pdp->pd_noptval) + return (DLADM_STATUS_BADVAL); -done: - return (status); + (void) memcpy(&vdp[j], &pdp->pd_optval[i], sizeof (val_desc_t)); + } + return (DLADM_STATUS_OK); } static dladm_status_t @@ -727,7 +746,8 @@ i_dladm_set_single_prop(dladm_handle_t handle, datalink_id_t linkid, status = pdp->pd_check(handle, pdp, linkid, prop_val, val_cnt, vdp, media); } else if (pdp->pd_optval != NULL) { - status = do_check_prop(pdp, prop_val, val_cnt, vdp); + status = do_check_prop(handle, pdp, linkid, prop_val, + val_cnt, vdp, media); } else { status = DLADM_STATUS_BADARG; } @@ -1523,9 +1543,9 @@ do_check_maxbw(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, /* ARGSUSED */ dladm_status_t -do_extract_maxbw(val_desc_t *vdp, void *arg, uint_t cnt) +do_extract_maxbw(val_desc_t *vdp, uint_t cnt, void *arg) { - mac_resource_props_t *mrp = (mac_resource_props_t *)arg; + mac_resource_props_t *mrp = arg; bcopy((char *)vdp->vd_val, &mrp->mrp_maxbw, sizeof (uint64_t)); mrp->mrp_mask |= MRP_MAXBW; @@ -1728,9 +1748,9 @@ do_check_cpus(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, /* ARGSUSED */ dladm_status_t -do_extract_cpus(val_desc_t *vdp, void *arg, uint_t cnt) +do_extract_cpus(val_desc_t *vdp, uint_t cnt, void *arg) { - mac_resource_props_t *mrp = (mac_resource_props_t *)arg; + mac_resource_props_t *mrp = arg; mac_resource_props_t *vmrp = (mac_resource_props_t *)vdp->vd_val; int i; @@ -1804,9 +1824,9 @@ do_check_priority(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, /* ARGSUSED */ dladm_status_t -do_extract_priority(val_desc_t *vdp, void *arg, uint_t cnt) +do_extract_priority(val_desc_t *vdp, uint_t cnt, void *arg) { - mac_resource_props_t *mrp = (mac_resource_props_t *)arg; + mac_resource_props_t *mrp = arg; bcopy((char *)vdp->vd_val, &mrp->mrp_priority, sizeof (mac_priority_level_t)); @@ -1817,6 +1837,157 @@ do_extract_priority(val_desc_t *vdp, void *arg, uint_t cnt) /* ARGSUSED */ static dladm_status_t +do_set_protection(dladm_handle_t handle, prop_desc_t *pdp, + datalink_id_t linkid, val_desc_t *vdp, uint_t val_cnt, + uint_t flags, datalink_media_t media) +{ + mac_resource_props_t mrp; + dladm_status_t status = DLADM_STATUS_OK; + dld_ioc_macprop_t *dip; + + bzero(&mrp, sizeof (mac_resource_props_t)); + dip = i_dladm_buf_alloc_by_name(0, linkid, "protection", + flags, &status); + + if (dip == NULL) + return (status); + + if (strcmp(pdp->pd_name, "protection") == 0) { + status = do_extract_protection(vdp, val_cnt, &mrp); + if (status != DLADM_STATUS_OK) + goto done; + + } else if (strcmp(pdp->pd_name, "allowed-ips") == 0) { + status = do_extract_allowedips(vdp, val_cnt, &mrp); + if (status != DLADM_STATUS_OK) + goto done; + } else { + status = DLADM_STATUS_BADARG; + goto done; + } + + (void) memcpy(dip->pr_val, &mrp, dip->pr_valsize); + status = i_dladm_macprop(handle, dip, B_TRUE); + +done: + free(dip); + return (status); +} + +/* ARGSUSED */ +static dladm_status_t +do_get_protection(dladm_handle_t handle, prop_desc_t *pdp, + datalink_id_t linkid, char **prop_val, uint_t *val_cnt, + datalink_media_t media, uint_t flags, uint_t *perm_flags) +{ + dld_ioc_macprop_t *dip; + mac_resource_props_t mrp; + mac_protect_t *p; + dladm_status_t status; + int i; + + dip = i_dladm_get_public_prop(handle, linkid, "protection", flags, + &status, perm_flags); + if (dip == NULL) + return (status); + + bcopy(dip->pr_val, &mrp, sizeof (mac_resource_props_t)); + free(dip); + + p = &mrp.mrp_protect; + if ((mrp.mrp_mask & MRP_PROTECT) != 0 && + strcmp(pdp->pd_name, "protection") == 0) { + uint32_t cnt = 0, setbits[32]; + + dladm_find_setbits32(p->mp_types, setbits, &cnt); + if (cnt > *val_cnt) + return (DLADM_STATUS_BADVALCNT); + + for (i = 0; i < cnt; i++) + (void) dladm_protect2str(setbits[i], prop_val[i]); + + *val_cnt = cnt; + return (DLADM_STATUS_OK); + } + + if (p->mp_ipaddrcnt > 0 && + strcmp(pdp->pd_name, "allowed-ips") == 0) { + if (p->mp_ipaddrcnt > *val_cnt) + return (DLADM_STATUS_BADVALCNT); + + for (i = 0; i < p->mp_ipaddrcnt; i++) { + (void) dladm_ipv4addr2str(&p->mp_ipaddrs[i], + prop_val[i]); + } + *val_cnt = p->mp_ipaddrcnt; + return (DLADM_STATUS_OK); + } + + *val_cnt = 0; + return (DLADM_STATUS_OK); +} + +dladm_status_t +do_extract_protection(val_desc_t *vdp, uint_t cnt, void *arg) +{ + mac_resource_props_t *mrp = arg; + uint32_t types = 0; + int i; + + for (i = 0; i < cnt; i++) + types |= (uint32_t)vdp[i].vd_val; + + mrp->mrp_protect.mp_types = types; + mrp->mrp_mask |= MRP_PROTECT; + return (DLADM_STATUS_OK); +} + +dladm_status_t +do_extract_allowedips(val_desc_t *vdp, uint_t cnt, void *arg) +{ + mac_resource_props_t *mrp = arg; + mac_protect_t *p = &mrp->mrp_protect; + int i; + + if (vdp->vd_val == 0) { + cnt = (uint_t)-1; + } else { + for (i = 0; i < cnt; i++) + p->mp_ipaddrs[i] = (ipaddr_t)vdp[i].vd_val; + } + p->mp_ipaddrcnt = cnt; + mrp->mrp_mask |= MRP_PROTECT; + return (DLADM_STATUS_OK); +} + +/* ARGSUSED */ +static dladm_status_t +do_check_allowedips(dladm_handle_t handle, prop_desc_t *pdp, + datalink_id_t linkid, char **prop_val, uint_t val_cnt, + val_desc_t *vdp, datalink_media_t media) +{ + dladm_status_t status; + ipaddr_t addr; + int i; + + if (val_cnt > MPT_MAXIPADDR) + return (DLADM_STATUS_BADVALCNT); + + for (i = 0; i < val_cnt; i++) { + status = dladm_str2ipv4addr(prop_val[i], &addr); + if (status != DLADM_STATUS_OK) + return (status); + + if (addr == 0) + return (DLADM_STATUS_BADVAL); + + vdp[i].vd_val = (uintptr_t)addr; + } + return (DLADM_STATUS_OK); +} + +/* ARGSUSED */ +static dladm_status_t do_get_autopush(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags, uint_t *perm_flags) @@ -3438,7 +3609,7 @@ dladm_link_get_proplist(dladm_handle_t handle, datalink_id_t linkid, */ static dladm_status_t i_dladm_link_proplist_extract_one(dladm_handle_t handle, - dladm_arg_list_t *proplist, const char *name, void *val) + dladm_arg_list_t *proplist, const char *name, void *arg) { dladm_status_t status; dladm_arg_info_t *aip = NULL; @@ -3488,8 +3659,8 @@ i_dladm_link_proplist_extract_one(dladm_handle_t handle, /* Extract kernel structure */ if (rpp->rp_extract != NULL) { - status = rpp->rp_extract(vdp, val, - aip->ai_count); + status = rpp->rp_extract(vdp, + aip->ai_count, arg); } else { status = DLADM_STATUS_BADARG; } @@ -3511,20 +3682,15 @@ dladm_status_t dladm_link_proplist_extract(dladm_handle_t handle, dladm_arg_list_t *proplist, mac_resource_props_t *mrp) { - dladm_status_t status = DLADM_STATUS_OK; + dladm_status_t status; + int i; - status = i_dladm_link_proplist_extract_one(handle, proplist, "maxbw", - mrp); - if (status != DLADM_STATUS_OK) - return (status); - status = i_dladm_link_proplist_extract_one(handle, proplist, "priority", - mrp); - if (status != DLADM_STATUS_OK) - return (status); - status = i_dladm_link_proplist_extract_one(handle, proplist, "cpus", - mrp); - if (status != DLADM_STATUS_OK) - return (status); + for (i = 0; i < DLADM_MAX_RSRC_PROP; i++) { + status = i_dladm_link_proplist_extract_one(handle, + proplist, rsrc_prop_table[i].rp_name, mrp); + if (status != DLADM_STATUS_OK) + return (status); + } return (status); } diff --git a/usr/src/lib/libdladm/common/mapfile-vers b/usr/src/lib/libdladm/common/mapfile-vers index 81b5d363cc..f64b2d3cd1 100644 --- a/usr/src/lib/libdladm/common/mapfile-vers +++ b/usr/src/lib/libdladm/common/mapfile-vers @@ -157,6 +157,10 @@ SUNWprivate_1.1 { dladm_walk_hwgrp; dladm_pri2str; dladm_str2pri; + dladm_protect2str; + dladm_str2protect; + dladm_ipv4addr2str; + dladm_str2ipv4addr; dladm_start_usagelog; dladm_stop_usagelog; dladm_walk_usage_res; |