diff options
author | Joshua M. Clulow <jmc@joyent.com> | 2018-05-02 15:17:11 -0700 |
---|---|---|
committer | Joshua M. Clulow <jmc@joyent.com> | 2018-08-30 04:37:16 +0000 |
commit | 0089e650ba9665ea65be91bc2541cfa8dee22919 (patch) | |
tree | 27334bec0b0c5960b76ebfc10ae7e16546e4cbab | |
parent | fb2422a25cfeb7137e66e7a24541eafb83165362 (diff) | |
download | illumos-joyent-dev-bhyve-promisc.tar.gz |
OS-6892 viona should allow promisc interfacesdev-bhyve-promisc
-rw-r--r-- | usr/src/lib/brand/bhyve/zone/statechange | 2 | ||||
-rw-r--r-- | usr/src/uts/i86pc/io/viona/viona.c | 36 |
2 files changed, 36 insertions, 2 deletions
diff --git a/usr/src/lib/brand/bhyve/zone/statechange b/usr/src/lib/brand/bhyve/zone/statechange index 76cfbffc17..93d3e7c43d 100644 --- a/usr/src/lib/brand/bhyve/zone/statechange +++ b/usr/src/lib/brand/bhyve/zone/statechange @@ -19,4 +19,6 @@ typeset -A FORCED_ATTRS FORCED_ATTRS["zlog-mode"]=g-- FORCED_ATTRS["zlog-name"]=platform.log +jst_ufpromisc="yes" + . /usr/lib/brand/jcommon/statechange diff --git a/usr/src/uts/i86pc/io/viona/viona.c b/usr/src/uts/i86pc/io/viona/viona.c index 3c52457a0b..0576d7eda9 100644 --- a/usr/src/uts/i86pc/io/viona/viona.c +++ b/usr/src/uts/i86pc/io/viona/viona.c @@ -228,6 +228,7 @@ #include <sys/mac_client.h> #include <sys/mac_provider.h> #include <sys/mac_client_priv.h> +#include <sys/mac_impl.h> #include <sys/vlan.h> #include <inet/ip.h> @@ -436,6 +437,7 @@ struct viona_link { datalink_id_t l_linkid; mac_handle_t l_mh; mac_client_handle_t l_mch; + mac_promisc_handle_t l_mph; pollhead_t l_pollhead; }; @@ -1318,12 +1320,38 @@ static void viona_worker_rx(viona_vring_t *ring, viona_link_t *link) { proc_t *p = ttoproc(curthread); + boolean_t promisc = B_FALSE; ASSERT(MUTEX_HELD(&ring->vr_lock)); ASSERT3U(ring->vr_state, ==, VRS_RUN); atomic_or_16(ring->vr_used_flags, VRING_USED_F_NO_NOTIFY); - mac_rx_set(link->l_mch, viona_rx, link); + + /* + * If this VNIC has been configured in unfiltered promiscuous mode, try + * to set up a promisc callback. This enables guests that need to use + * addresses other than the primary address to see all traffic. + * + * The callback will be configured to fix up any missing frame + * checksums, to strip VLAN headers, and to receive only inbound + * traffic. It will thus be analogous to the regular callback passed + * to mac_rx_set(), except with a less constrained view of incoming + * traffic. + */ + if (!mac_get_promisc_filtered(link->l_mch)) { + uint16_t flags = MAC_PROMISC_FLAGS_DO_FIXUPS | + MAC_PROMISC_FLAGS_NO_TX_LOOP | + MAC_PROMISC_FLAGS_VLAN_TAG_STRIP; + + if (mac_promisc_add(link->l_mch, MAC_CLIENT_PROMISC_ALL, + viona_rx, link, &link->l_mph, flags) == 0) { + promisc = B_TRUE; + } + } + + if (!promisc) { + mac_rx_set(link->l_mch, viona_rx, link); + } do { /* @@ -1343,7 +1371,11 @@ viona_worker_rx(viona_vring_t *ring, viona_link_t *link) * acquire vr_lock for tasks such as delivering an interrupt. In order * to avoid such deadlocks, vr_lock must temporarily be dropped here. */ - mac_rx_clear(link->l_mch); + if (promisc) { + mac_promisc_remove(link->l_mph); + } else { + mac_rx_clear(link->l_mch); + } mutex_enter(&ring->vr_lock); } |