summaryrefslogtreecommitdiff
path: root/usr/src/lib/libdladm
diff options
context:
space:
mode:
authorEric Cheng <none@none>2009-10-07 14:39:04 -0700
committerEric Cheng <none@none>2009-10-07 14:39:04 -0700
commit25ec3e3dd27cc1038c10efa18ed08f064eab5fbe (patch)
tree8e5ece639c198513f5115cd16c6f21616b943dde /usr/src/lib/libdladm
parent0ff6bfafbd510fac2721570482eceb0d24afe291 (diff)
downloadillumos-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.c30
-rw-r--r--usr/src/lib/libdladm/common/flowprop.c6
-rw-r--r--usr/src/lib/libdladm/common/libdladm.c90
-rw-r--r--usr/src/lib/libdladm/common/libdladm.h7
-rw-r--r--usr/src/lib/libdladm/common/libdladm_impl.h10
-rw-r--r--usr/src/lib/libdladm/common/libdlflow.c20
-rw-r--r--usr/src/lib/libdladm/common/linkprop.c248
-rw-r--r--usr/src/lib/libdladm/common/mapfile-vers4
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;