summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/io/mac
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/common/io/mac')
-rw-r--r--usr/src/uts/common/io/mac/mac.c96
-rw-r--r--usr/src/uts/common/io/mac/mac_client.c10
2 files changed, 104 insertions, 2 deletions
diff --git a/usr/src/uts/common/io/mac/mac.c b/usr/src/uts/common/io/mac/mac.c
index 61a5353365..e175f67313 100644
--- a/usr/src/uts/common/io/mac/mac.c
+++ b/usr/src/uts/common/io/mac/mac.c
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2014, Joyent, Inc. All rights reserved.
*/
/*
@@ -2685,6 +2685,100 @@ mac_margin_update(mac_handle_t mh, uint32_t margin)
return (margin_needed <= margin);
}
+int
+mac_mtu_add(mac_handle_t mh, uint32_t *mtup, boolean_t current)
+{
+ mac_impl_t *mip = (mac_impl_t *)mh;
+ mac_mtu_req_t *prev, *cur;
+ mac_propval_range_t mpr;
+ int err;
+
+ i_mac_perim_enter(mip);
+ rw_enter(&mip->mi_rw_lock, RW_WRITER);
+
+ if (current == B_TRUE)
+ *mtup = mip->mi_sdu_max;
+ mpr.mpr_count = 1;
+ err = mac_prop_info(mh, MAC_PROP_MTU, "mtu", NULL, 0, &mpr, NULL);
+ if (err != 0) {
+ rw_exit(&mip->mi_rw_lock);
+ i_mac_perim_exit(mip);
+ return (err);
+ }
+
+ if (*mtup > mip->mi_sdu_max ||
+ *mtup < mpr.mpr_range_uint32[0].mpur_min) {
+ rw_exit(&mip->mi_rw_lock);
+ i_mac_perim_exit(mip);
+ return (ENOTSUP);
+ }
+
+ prev = NULL;
+ for (cur = mip->mi_mtrp; cur != NULL; cur = cur->mtr_nextp) {
+ if (*mtup == cur->mtr_mtu) {
+ cur->mtr_ref++;
+ rw_exit(&mip->mi_rw_lock);
+ i_mac_perim_exit(mip);
+ return (0);
+ }
+
+ if (*mtup > cur->mtr_mtu)
+ break;
+
+ prev = cur;
+ }
+
+ cur = kmem_alloc(sizeof (mac_mtu_req_t), KM_SLEEP);
+ cur->mtr_mtu = *mtup;
+ cur->mtr_ref = 1;
+ if (prev != NULL) {
+ cur->mtr_nextp = prev->mtr_nextp;
+ prev->mtr_nextp = cur;
+ } else {
+ cur->mtr_nextp = mip->mi_mtrp;
+ mip->mi_mtrp = cur;
+ }
+
+ rw_exit(&mip->mi_rw_lock);
+ i_mac_perim_exit(mip);
+ return (0);
+}
+
+int
+mac_mtu_remove(mac_handle_t mh, uint32_t mtu)
+{
+ mac_impl_t *mip = (mac_impl_t *)mh;
+ mac_mtu_req_t *cur, *prev;
+
+ i_mac_perim_enter(mip);
+ rw_enter(&mip->mi_rw_lock, RW_WRITER);
+
+ prev = NULL;
+ for (cur = mip->mi_mtrp; cur != NULL; cur = cur->mtr_nextp) {
+ if (cur->mtr_mtu == mtu) {
+ ASSERT(cur->mtr_ref > 0);
+ cur->mtr_ref--;
+ if (cur->mtr_ref == 0) {
+ if (prev == NULL) {
+ mip->mi_mtrp = cur->mtr_nextp;
+ } else {
+ prev->mtr_nextp = cur->mtr_nextp;
+ }
+ kmem_free(cur, sizeof (mac_mtu_req_t));
+ }
+ rw_exit(&mip->mi_rw_lock);
+ i_mac_perim_exit(mip);
+ return (0);
+ }
+
+ prev = cur;
+ }
+
+ rw_exit(&mip->mi_rw_lock);
+ i_mac_perim_exit(mip);
+ return (ENOENT);
+}
+
/*
* MAC Type Plugin functions.
*/
diff --git a/usr/src/uts/common/io/mac/mac_client.c b/usr/src/uts/common/io/mac/mac_client.c
index 0f0d44cda5..88620518f1 100644
--- a/usr/src/uts/common/io/mac/mac_client.c
+++ b/usr/src/uts/common/io/mac/mac_client.c
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2014, Joyent, Inc. All rights reserved.
*/
/*
@@ -5258,6 +5258,14 @@ mac_set_mtu(mac_handle_t mh, uint_t new_mtu, uint_t *old_mtu_arg)
goto bail;
}
+ rw_enter(&mip->mi_rw_lock, RW_READER);
+ if (mip->mi_mtrp != NULL && new_mtu < mip->mi_mtrp->mtr_mtu) {
+ rv = EBUSY;
+ rw_exit(&mip->mi_rw_lock);
+ goto bail;
+ }
+ rw_exit(&mip->mi_rw_lock);
+
if (old_mtu != new_mtu) {
rv = mip->mi_callbacks->mc_setprop(mip->mi_driver,
"mtu", MAC_PROP_MTU, sizeof (uint_t), &new_mtu);