--- old/usr/src/uts/common/io/mac/mac_sched.c	Tue Feb  5 11:49:59 2019
+++ new/usr/src/uts/common/io/mac/mac_sched.c	Tue Feb  5 11:49:59 2019
@@ -21,8 +21,8 @@
 /*
  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
- * Copyright 2017 Joyent, Inc.
  * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2019 Joyent, Inc.
  */
 
 /*
@@ -42,157 +42,157 @@
  *
  * MAC
  *
- * 	This driver. It interfaces with device drivers and provides abstractions
- * 	that the rest of the system consumes. All data links -- things managed
- * 	with dladm(1M), are accessed through MAC.
+ *	This driver. It interfaces with device drivers and provides abstractions
+ *	that the rest of the system consumes. All data links -- things managed
+ *	with dladm(1M), are accessed through MAC.
  *
  * GLDv3 DEVICE DRIVER
  *
- * 	A GLDv3 device driver refers to a driver, both for pseudo-devices and
- * 	real devices, which implement the GLDv3 driver API. Common examples of
- * 	these are igb and ixgbe, which are drivers for various Intel networking
- * 	cards. These devices may or may not have various features, such as
- * 	hardware rings and checksum offloading. For MAC, a GLDv3 device is the
- * 	final point for the transmission of a packet and the starting point for
- * 	the receipt of a packet.
+ *	A GLDv3 device driver refers to a driver, both for pseudo-devices and
+ *	real devices, which implement the GLDv3 driver API. Common examples of
+ *	these are igb and ixgbe, which are drivers for various Intel networking
+ *	cards. These devices may or may not have various features, such as
+ *	hardware rings and checksum offloading. For MAC, a GLDv3 device is the
+ *	final point for the transmission of a packet and the starting point for
+ *	the receipt of a packet.
  *
  * FLOWS
  *
- * 	At a high level, a flow refers to a series of packets that are related.
- * 	Often times the term is used in the context of TCP to indicate a unique
- * 	TCP connection and the traffic over it. However, a flow can exist at
- * 	other levels of the system as well. MAC has a notion of a default flow
- * 	which is used for all unicast traffic addressed to the address of a MAC
- * 	device. For example, when a VNIC is created, a default flow is created
- * 	for the VNIC's MAC address. In addition, flows are created for broadcast
- * 	groups and a user may create a flow with flowadm(1M).
+ *	At a high level, a flow refers to a series of packets that are related.
+ *	Often times the term is used in the context of TCP to indicate a unique
+ *	TCP connection and the traffic over it. However, a flow can exist at
+ *	other levels of the system as well. MAC has a notion of a default flow
+ *	which is used for all unicast traffic addressed to the address of a MAC
+ *	device. For example, when a VNIC is created, a default flow is created
+ *	for the VNIC's MAC address. In addition, flows are created for broadcast
+ *	groups and a user may create a flow with flowadm(1M).
  *
  * CLASSIFICATION
  *
- * 	Classification refers to the notion of identifying an incoming frame
- * 	based on its destination address and optionally its source addresses and
- * 	doing different processing based on that information. Classification can
- * 	be done in both hardware and software. In general, we usually only
- * 	classify based on the layer two destination, eg. for Ethernet, the
- * 	destination MAC address.
+ *	Classification refers to the notion of identifying an incoming frame
+ *	based on its destination address and optionally its source addresses and
+ *	doing different processing based on that information. Classification can
+ *	be done in both hardware and software. In general, we usually only
+ *	classify based on the layer two destination, eg. for Ethernet, the
+ *	destination MAC address.
  *
- * 	The system also will do classification based on layer three and layer
- * 	four properties. This is used to support things like flowadm(1M), which
- * 	allows setting QoS and other properties on a per-flow basis.
+ *	The system also will do classification based on layer three and layer
+ *	four properties. This is used to support things like flowadm(1M), which
+ *	allows setting QoS and other properties on a per-flow basis.
  *
  * RING
  *
- * 	Conceptually, a ring represents a series of framed messages, often in a
- * 	contiguous chunk of memory that acts as a circular buffer. Rings come in
- * 	a couple of forms. Generally they are either a hardware construct (hw
- * 	ring) or they are a software construct (sw ring) maintained by MAC.
+ *	Conceptually, a ring represents a series of framed messages, often in a
+ *	contiguous chunk of memory that acts as a circular buffer. Rings come in
+ *	a couple of forms. Generally they are either a hardware construct (hw
+ *	ring) or they are a software construct (sw ring) maintained by MAC.
  *
  * HW RING
  *
- * 	A hardware ring is a set of resources provided by a GLDv3 device driver
- * 	(even if it is a pseudo-device). A hardware ring comes in two different
- * 	forms: receive (rx) rings and transmit (tx) rings. An rx hw ring is
- * 	something that has a unique DMA (direct memory access) region and
- * 	generally supports some form of classification (though it isn't always
- * 	used), as well as a means of generating an interrupt specific to that
- * 	ring. For example, the device may generate a specific MSI-X for a PCI
- * 	express device. A tx ring is similar, except that it is dedicated to
- * 	transmission. It may also be a vector for enabling features such as VLAN
- * 	tagging and large transmit offloading. It usually has its own dedicated
- * 	interrupts for transmit being completed.
+ *	A hardware ring is a set of resources provided by a GLDv3 device driver
+ *	(even if it is a pseudo-device). A hardware ring comes in two different
+ *	forms: receive (rx) rings and transmit (tx) rings. An rx hw ring is
+ *	something that has a unique DMA (direct memory access) region and
+ *	generally supports some form of classification (though it isn't always
+ *	used), as well as a means of generating an interrupt specific to that
+ *	ring. For example, the device may generate a specific MSI-X for a PCI
+ *	express device. A tx ring is similar, except that it is dedicated to
+ *	transmission. It may also be a vector for enabling features such as VLAN
+ *	tagging and large transmit offloading. It usually has its own dedicated
+ *	interrupts for transmit being completed.
  *
  * SW RING
  *
- * 	A software ring is a construction of MAC. It represents the same thing
- * 	that a hardware ring generally does, a collection of frames. However,
- * 	instead of being in a contiguous ring of memory, they're instead linked
- * 	by using the mblk_t's b_next pointer. Each frame may itself be multiple
- * 	mblk_t's linked together by the b_cont pointer. A software ring always
- * 	represents a collection of classified packets; however, it varies as to
- * 	whether it uses only layer two information, or a combination of that and
- * 	additional layer three and layer four data.
+ *	A software ring is a construction of MAC. It represents the same thing
+ *	that a hardware ring generally does, a collection of frames. However,
+ *	instead of being in a contiguous ring of memory, they're instead linked
+ *	by using the mblk_t's b_next pointer. Each frame may itself be multiple
+ *	mblk_t's linked together by the b_cont pointer. A software ring always
+ *	represents a collection of classified packets; however, it varies as to
+ *	whether it uses only layer two information, or a combination of that and
+ *	additional layer three and layer four data.
  *
  * FANOUT
  *
- * 	Fanout is the idea of spreading out the load of processing frames based
- * 	on the source and destination information contained in the layer two,
- * 	three, and four headers, such that the data can then be processed in
- * 	parallel using multiple hardware threads.
+ *	Fanout is the idea of spreading out the load of processing frames based
+ *	on the source and destination information contained in the layer two,
+ *	three, and four headers, such that the data can then be processed in
+ *	parallel using multiple hardware threads.
  *
- * 	A fanout algorithm hashes the headers and uses that to place different
- * 	flows into a bucket. The most important thing is that packets that are
- * 	in the same flow end up in the same bucket. If they do not, performance
- * 	can be adversely affected. Consider the case of TCP.  TCP severely
- * 	penalizes a connection if the data arrives out of order. If a given flow
- * 	is processed on different CPUs, then the data will appear out of order,
- * 	hence the invariant that fanout always hash a given flow to the same
- * 	bucket and thus get processed on the same CPU.
+ *	A fanout algorithm hashes the headers and uses that to place different
+ *	flows into a bucket. The most important thing is that packets that are
+ *	in the same flow end up in the same bucket. If they do not, performance
+ *	can be adversely affected. Consider the case of TCP.  TCP severely
+ *	penalizes a connection if the data arrives out of order. If a given flow
+ *	is processed on different CPUs, then the data will appear out of order,
+ *	hence the invariant that fanout always hash a given flow to the same
+ *	bucket and thus get processed on the same CPU.
  *
  * RECEIVE SIDE SCALING (RSS)
  *
  *
- * 	Receive side scaling is a term that isn't common in illumos, but is used
- * 	by vendors and was popularized by Microsoft. It refers to the idea of
- * 	spreading the incoming receive load out across multiple interrupts which
- * 	can be directed to different CPUs. This allows a device to leverage
- * 	hardware rings even when it doesn't support hardware classification. The
- * 	hardware uses an algorithm to perform fanout that ensures the flow
- * 	invariant is maintained.
+ *	Receive side scaling is a term that isn't common in illumos, but is used
+ *	by vendors and was popularized by Microsoft. It refers to the idea of
+ *	spreading the incoming receive load out across multiple interrupts which
+ *	can be directed to different CPUs. This allows a device to leverage
+ *	hardware rings even when it doesn't support hardware classification. The
+ *	hardware uses an algorithm to perform fanout that ensures the flow
+ *	invariant is maintained.
  *
  * SOFT RING SET
  *
- * 	A soft ring set, commonly abbreviated SRS, is a collection of rings and
- * 	is used for both transmitting and receiving. It is maintained in the
- * 	structure mac_soft_ring_set_t. A soft ring set is usually associated
- * 	with flows, and coordinates both the use of hardware and software rings.
- * 	Because the use of hardware rings can change as devices such as VNICs
- * 	come and go, we always ensure that the set has software classification
- * 	rules that correspond to the hardware classification rules from rings.
+ *	A soft ring set, commonly abbreviated SRS, is a collection of rings and
+ *	is used for both transmitting and receiving. It is maintained in the
+ *	structure mac_soft_ring_set_t. A soft ring set is usually associated
+ *	with flows, and coordinates both the use of hardware and software rings.
+ *	Because the use of hardware rings can change as devices such as VNICs
+ *	come and go, we always ensure that the set has software classification
+ *	rules that correspond to the hardware classification rules from rings.
  *
- * 	Soft ring sets are also used for the enforcement of various QoS
- * 	properties. For example, if a bandwidth limit has been placed on a
- * 	specific flow or device, then that will be enforced by the soft ring
- * 	set.
+ *	Soft ring sets are also used for the enforcement of various QoS
+ *	properties. For example, if a bandwidth limit has been placed on a
+ *	specific flow or device, then that will be enforced by the soft ring
+ *	set.
  *
  * SERVICE ATTACHMENT POINT (SAP)
  *
- * 	The service attachment point is a DLPI (Data Link Provider Interface)
- * 	concept; however, it comes up quite often in MAC. Most MAC devices speak
- * 	a protocol that has some notion of different channels or message type
- * 	identifiers. For example, Ethernet defines an EtherType which is a part
- * 	of the Ethernet header and defines the particular protocol of the data
- * 	payload. If the EtherType is set to 0x0800, then it defines that the
- * 	contents of that Ethernet frame is IPv4 traffic. For Ethernet, the
- * 	EtherType is the SAP.
+ *	The service attachment point is a DLPI (Data Link Provider Interface)
+ *	concept; however, it comes up quite often in MAC. Most MAC devices speak
+ *	a protocol that has some notion of different channels or message type
+ *	identifiers. For example, Ethernet defines an EtherType which is a part
+ *	of the Ethernet header and defines the particular protocol of the data
+ *	payload. If the EtherType is set to 0x0800, then it defines that the
+ *	contents of that Ethernet frame is IPv4 traffic. For Ethernet, the
+ *	EtherType is the SAP.
  *
- * 	In DLPI, a given consumer attaches to a specific SAP. In illumos, the ip
- * 	and arp drivers attach to the EtherTypes for IPv4, IPv6, and ARP. Using
- * 	libdlpi(3LIB) user software can attach to arbitrary SAPs. With the
- * 	exception of 802.1Q VLAN tagged traffic, MAC itself does not directly
- * 	consume the SAP; however, it uses that information as part of hashing
- * 	and it may be used as part of the construction of flows.
+ *	In DLPI, a given consumer attaches to a specific SAP. In illumos, the ip
+ *	and arp drivers attach to the EtherTypes for IPv4, IPv6, and ARP. Using
+ *	libdlpi(3LIB) user software can attach to arbitrary SAPs. With the
+ *	exception of 802.1Q VLAN tagged traffic, MAC itself does not directly
+ *	consume the SAP; however, it uses that information as part of hashing
+ *	and it may be used as part of the construction of flows.
  *
  * PRIMARY MAC CLIENT
  *
- * 	The primary mac client refers to a mac client whose unicast address
- * 	matches the address of the device itself. For example, if the system has
- * 	instance of the e1000g driver such as e1000g0, e1000g1, etc., the
- * 	primary mac client is the one named after the device itself. VNICs that
- * 	are created on top of such devices are not the primary client.
+ *	The primary mac client refers to a mac client whose unicast address
+ *	matches the address of the device itself. For example, if the system has
+ *	instance of the e1000g driver such as e1000g0, e1000g1, etc., the
+ *	primary mac client is the one named after the device itself. VNICs that
+ *	are created on top of such devices are not the primary client.
  *
  * TRANSMIT DESCRIPTORS
  *
- * 	Transmit descriptors are a resource that most GLDv3 device drivers have.
- * 	Generally, a GLDv3 device driver takes a frame that's meant to be output
- * 	and puts a copy of it into a region of memory. Each region of memory
- * 	usually has an associated descriptor that the device uses to manage
- * 	properties of the frames. Devices have a limited number of such
- * 	descriptors. They get reclaimed once the device finishes putting the
- * 	frame on the wire.
+ *	Transmit descriptors are a resource that most GLDv3 device drivers have.
+ *	Generally, a GLDv3 device driver takes a frame that's meant to be output
+ *	and puts a copy of it into a region of memory. Each region of memory
+ *	usually has an associated descriptor that the device uses to manage
+ *	properties of the frames. Devices have a limited number of such
+ *	descriptors. They get reclaimed once the device finishes putting the
+ *	frame on the wire.
  *
- * 	If the driver runs out of transmit descriptors, for example, the OS is
- * 	generating more frames than it can put on the wire, then it will return
- * 	them back to the MAC layer.
+ *	If the driver runs out of transmit descriptors, for example, the OS is
+ *	generating more frames than it can put on the wire, then it will return
+ *	them back to the MAC layer.
  *
  * ---------------------------------
  * Rings, Classification, and Fanout
@@ -1194,7 +1194,7 @@
 #define	MAC_SRS_WORKER_POLLING_ON(mac_srs) {				\
 	ASSERT(MUTEX_HELD(&(mac_srs)->srs_lock));			\
 	if (((mac_srs)->srs_state &					\
-	    (SRS_POLLING_CAPAB|SRS_WORKER|SRS_POLLING)) == 		\
+	    (SRS_POLLING_CAPAB|SRS_WORKER|SRS_POLLING)) ==		\
 	    (SRS_POLLING_CAPAB|SRS_WORKER)) {				\
 		(mac_srs)->srs_state |= SRS_POLLING;			\
 		(void) mac_hwring_disable_intr((mac_ring_handle_t)	\
@@ -1217,11 +1217,11 @@
 									\
 	ASSERT(MUTEX_HELD(&(mac_srs)->srs_lock));			\
 	srs_rx->sr_poll_thr_sig++;					\
-	if (((mac_srs)->srs_state & 					\
+	if (((mac_srs)->srs_state &					\
 	    (SRS_POLLING_CAPAB|SRS_WORKER|SRS_GET_PKTS)) ==		\
 		(SRS_WORKER|SRS_POLLING_CAPAB)) {			\
 		(mac_srs)->srs_state |= SRS_GET_PKTS;			\
-		cv_signal(&(mac_srs)->srs_cv);   			\
+		cv_signal(&(mac_srs)->srs_cv);				\
 	} else {							\
 		srs_rx->sr_poll_thr_busy++;				\
 	}								\
@@ -1241,7 +1241,7 @@
 	clock_t now = ddi_get_lbolt();					\
 	if ((mac_srs)->srs_bw->mac_bw_curr_time != now) {		\
 		(mac_srs)->srs_bw->mac_bw_curr_time = now;		\
-		(mac_srs)->srs_bw->mac_bw_used = 0;	       		\
+		(mac_srs)->srs_bw->mac_bw_used = 0;			\
 		if ((mac_srs)->srs_bw->mac_bw_state & SRS_BW_ENFORCED)	\
 			(mac_srs)->srs_bw->mac_bw_state &= ~SRS_BW_ENFORCED; \
 	}								\
@@ -1715,6 +1715,7 @@
 	uint32_t	src_val, dst_val;
 	boolean_t	modifiable = B_TRUE;
 	boolean_t	v6;
+	int		errno;
 
 	ASSERT(MBLKL(mp) >= hdrsize);
 
@@ -1789,15 +1790,27 @@
 		 * when mac_ip_hdr_length_v6() fails because of malformed
 		 * packets or because mblks need to be concatenated using
 		 * pullupmsg().
-		 *
-		 * Perform a version check to prevent parsing weirdness...
 		 */
-		if (IPH_HDR_VERSION(ip6h) != IPV6_VERSION ||
-		    !mac_ip_hdr_length_v6(ip6h, mp->b_wptr, &hdr_len, &nexthdr,
-		    NULL)) {
+		errno = mac_ip_hdr_length_v6(ip6h, mp->b_wptr, &hdr_len,
+		    &nexthdr, NULL);
+		switch (errno) {
+		case EINVAL:
+			/* Bad version. */
+			*indx = 0;
+			*type = OTH;
+			return (0);
+		case 0:
+			break;
+		default:
 			goto src_dst_based_fanout;
 		}
 	} else {
+		if (IPH_HDR_VERSION(ipha) != IPV4_VERSION) {
+			/* Bad version. */
+			*indx = 0;
+			*type = OTH;
+			return (0);
+		}
 		hdr_len = IPH_HDR_LENGTH(ipha);
 		remlen = ntohs(ipha->ipha_length) - hdr_len;
 		nexthdr = ipha->ipha_protocol;
@@ -2207,13 +2220,13 @@
 void
 mac_rx_srs_poll_ring(mac_soft_ring_set_t *mac_srs)
 {
-	kmutex_t 		*lock = &mac_srs->srs_lock;
-	kcondvar_t 		*async = &mac_srs->srs_cv;
+	kmutex_t		*lock = &mac_srs->srs_lock;
+	kcondvar_t		*async = &mac_srs->srs_cv;
 	mac_srs_rx_t		*srs_rx = &mac_srs->srs_rx;
-	mblk_t 			*head, *tail, *mp;
-	callb_cpr_t 		cprinfo;
-	ssize_t 		bytes_to_pickup;
-	size_t 			sz;
+	mblk_t			*head, *tail, *mp;
+	callb_cpr_t		cprinfo;
+	ssize_t			bytes_to_pickup;
+	size_t			sz;
 	int			count;
 	mac_client_impl_t	*smcip;
 
@@ -2480,12 +2493,12 @@
 mac_srs_pick_chain(mac_soft_ring_set_t *mac_srs, mblk_t **chain_tail,
     size_t *chain_sz, int *chain_cnt)
 {
-	mblk_t 			*head = NULL;
-	mblk_t 			*tail = NULL;
+	mblk_t			*head = NULL;
+	mblk_t			*tail = NULL;
 	size_t			sz;
-	size_t 			tsz = 0;
+	size_t			tsz = 0;
 	int			cnt = 0;
-	mblk_t 			*mp;
+	mblk_t			*mp;
 
 	ASSERT(MUTEX_HELD(&mac_srs->srs_lock));
 	mutex_enter(&mac_srs->srs_bw->mac_bw_lock);
@@ -2566,9 +2579,9 @@
 void
 mac_rx_srs_drain(mac_soft_ring_set_t *mac_srs, uint_t proc_type)
 {
-	mblk_t 			*head;
+	mblk_t			*head;
 	mblk_t			*tail;
-	timeout_id_t 		tid;
+	timeout_id_t		tid;
 	int			cnt = 0;
 	mac_client_impl_t	*mcip = mac_srs->srs_mcip;
 	mac_srs_rx_t		*srs_rx = &mac_srs->srs_rx;
@@ -2806,9 +2819,9 @@
 void
 mac_rx_srs_drain_bw(mac_soft_ring_set_t *mac_srs, uint_t proc_type)
 {
-	mblk_t 			*head;
+	mblk_t			*head;
 	mblk_t			*tail;
-	timeout_id_t 		tid;
+	timeout_id_t		tid;
 	size_t			sz = 0;
 	int			cnt = 0;
 	mac_client_impl_t	*mcip = mac_srs->srs_mcip;
@@ -3073,8 +3086,8 @@
 void
 mac_srs_worker(mac_soft_ring_set_t *mac_srs)
 {
-	kmutex_t 		*lock = &mac_srs->srs_lock;
-	kcondvar_t 		*async = &mac_srs->srs_async;
+	kmutex_t		*lock = &mac_srs->srs_lock;
+	kcondvar_t		*async = &mac_srs->srs_async;
 	callb_cpr_t		cprinfo;
 	boolean_t		bw_ctl_flag;
 
@@ -3774,7 +3787,7 @@
  * queue any packets.
  */
 
-#define	MAC_TX_SOFT_RING_PROCESS(chain) {		       		\
+#define	MAC_TX_SOFT_RING_PROCESS(chain) {				\
 	index = COMPUTE_INDEX(hash, mac_srs->srs_tx_ring_count),	\
 	softring = mac_srs->srs_tx_soft_rings[index];			\
 	cookie = mac_tx_soft_ring_process(softring, chain, flag, ret_mp); \
@@ -4615,7 +4628,7 @@
  * a short period.
  */
 
-#define	SOFT_RING_ENQUEUE_CHAIN(ringp, mp, tail, cnt, sz) {	       	\
+#define	SOFT_RING_ENQUEUE_CHAIN(ringp, mp, tail, cnt, sz) {		\
 	/*								\
 	 * Enqueue our mblk chain.					\
 	 */								\
@@ -4792,7 +4805,7 @@
  * a short period.
  */
 
-#define	TX_SOFT_RING_ENQUEUE_CHAIN(ringp, mp, tail, cnt, sz) {	       	\
+#define	TX_SOFT_RING_ENQUEUE_CHAIN(ringp, mp, tail, cnt, sz) {		\
 	ASSERT(MUTEX_HELD(&ringp->s_ring_lock));			\
 	ringp->s_ring_state |= S_RING_ENQUEUED;				\
 	SOFT_RING_ENQUEUE_CHAIN(ringp, mp_chain, tail, cnt, sz);	\
