--- usr/src/uts/common/sys/mac.h.fix_lo	2006-06-14 21:27:32.000000000 -0700
+++ usr/src/uts/common/sys/mac.h	2006-07-02 14:25:47.962970000 -0700
@@ -264,6 +264,7 @@
 typedef void		(*mac_resources_t)(void *);
 typedef void		(*mac_ioctl_t)(void *, queue_t *, mblk_t *);
 typedef mblk_t		*(*mac_tx_t)(void *, mblk_t *);
+typedef mblk_t		*(*mac_tx_lo_t)(void *, mblk_t *, void *);
 
 /*
  * MAC extensions. (Currently there are non defined).
@@ -330,7 +331,7 @@
 
 typedef void		(*mac_notify_t)(void *, mac_notify_type_t);
 typedef void		(*mac_rx_t)(void *, mac_resource_handle_t, mblk_t *);
-typedef void		(*mac_txloop_t)(void *, mblk_t *);
+typedef void		(*mac_txloop_t)(void *, mblk_t *, void *);
 typedef void		(*mac_blank_t)(void *, time_t, uint_t);
 
 /*
@@ -398,7 +399,7 @@
 extern void			mac_notify(mac_handle_t);
 extern mac_rx_handle_t		mac_rx_add(mac_handle_t, mac_rx_t, void *);
 extern void			mac_rx_remove(mac_handle_t, mac_rx_handle_t);
-extern mblk_t			*mac_txloop(void *, mblk_t *);
+extern mblk_t			*mac_txloop(void *, mblk_t *, void *);
 extern mac_txloop_handle_t	mac_txloop_add(mac_handle_t, mac_txloop_t,
     void *);
 extern void			mac_txloop_remove(mac_handle_t,
--- usr/src/uts/common/sys/dls_impl.h.fix_lo	2006-06-14 21:27:33.000000000 -0700
+++ usr/src/uts/common/sys/dls_impl.h	2006-07-05 11:05:02.406665000 -0700
@@ -145,8 +145,8 @@
 extern int		dls_fini(void);
 extern boolean_t	dls_accept(dls_impl_t *, const uint8_t *,
     dls_rx_t *, void **);
-extern boolean_t	dls_accept_loopback(dls_impl_t *, const uint8_t *,
-    dls_rx_t *, void **);
+extern boolean_t	dls_accept_loopback(dls_impl_t *, dls_impl_t *,
+    const uint8_t *, dls_rx_t *, void **);
 
 #ifdef	__cplusplus
 }
--- usr/src/uts/common/io/dls/dls.c.fix_lo	2006-06-14 21:27:37.000000000 -0700
+++ usr/src/uts/common/io/dls/dls.c	2006-07-05 14:06:05.229098000 -0700
@@ -795,7 +795,17 @@
 mblk_t *
 dls_tx(dls_channel_t dc, mblk_t *mp)
 {
-	const mac_txinfo_t *mtp = ((dls_impl_t *)dc)->di_txinfo;
+	dls_impl_t *dip = (dls_impl_t *)dc;
+	const mac_txinfo_t *mtp = dip->di_txinfo;
+	mac_handle_t mh = dip->di_mh;
+
+	if ((void*)mtp->mt_fn == (void*)mac_txloop) {
+		/* Only get here in the promisc loopback case */
+		/* cmn_err(CE_WARN,
+		   "dls_tx: Send promisc block"); */
+		return (((mac_tx_lo_t)mtp->mt_fn)
+			(mtp->mt_arg, mp, dip));
+	}
 
 	return (mtp->mt_fn(mtp->mt_arg, mp));
 }
@@ -904,9 +914,15 @@
 
 /*ARGSUSED*/
 boolean_t
-dls_accept_loopback(dls_impl_t *dip, const uint8_t *daddr, dls_rx_t *di_rx,
-    void **di_rx_arg)
+dls_accept_loopback(dls_impl_t *dip, dls_impl_t *dip_caller,
+    const uint8_t *daddr, dls_rx_t *di_rx, void **di_rx_arg)
 {
+	/* Only check accept of the promiscuous loopback call if the packet was
+	   not sent (i.e., tx'ed) on our own dls_impl_t* */
+	/* cmn_err(CE_WARN, "dls_accept_loopback: caller: %lu; target: %lu",
+	   (size_t)dip_caller, (size_t)dip); */
+	if (dip_caller == dip)
+		return (B_FALSE);
 	/*
 	 * We must not accept packets if the dls_impl_t is not marked as bound
 	 * or is being removed.
--- usr/src/uts/common/io/dls/dls_link.c.fix_lo	2006-06-14 21:27:37.000000000 -0700
+++ usr/src/uts/common/io/dls/dls_link.c	2006-07-05 11:17:38.480796000 -0700
@@ -593,7 +593,7 @@
 }
 
 static void
-i_dls_link_ether_loopback(void *arg, mblk_t *mp)
+i_dls_link_ether_loopback(void *arg, mblk_t *mp, void* dip_caller)
 {
 	dls_link_t			*dlp = arg;
 	mod_hash_t			*hash = dlp->dl_impl_hash;
@@ -652,8 +652,8 @@
 		 * Find dls_impl_t that will accept the sub-chain.
 		 */
 		for (dip = dhp->dh_list; dip != NULL; dip = dip->di_nextp) {
-			if (!dls_accept_loopback(dip, daddr, &di_rx,
-			    &di_rx_arg))
+			if (!dls_accept_loopback(dip, dip_caller, daddr,
+						 &di_rx, &di_rx_arg))
 				continue;
 
 			/*
@@ -695,7 +695,8 @@
 		 * Find the first dls_impl_t that will accept the sub-chain.
 		 */
 		for (dip = dhp->dh_list; dip != NULL; dip = dip->di_nextp)
-			if (dls_accept_loopback(dip, daddr, &di_rx, &di_rx_arg))
+			if (dls_accept_loopback(dip, dip_caller, daddr, &di_rx,
+						&di_rx_arg))
 				break;
 
 		/*
@@ -715,8 +716,9 @@
 			 */
 			for (ndip = dip->di_nextp; ndip != NULL;
 			    ndip = ndip->di_nextp)
-				if (dls_accept_loopback(ndip, daddr,
-				    &ndi_rx, &ndi_rx_arg))
+				if (dls_accept_loopback(ndip, dip_caller,
+							daddr, &ndi_rx,
+							&ndi_rx_arg))
 					break;
 
 			/*
--- usr/src/uts/common/io/aggr/aggr_lacp.c.fix_lo	2006-06-14 21:27:39.000000000 -0700
+++ usr/src/uts/common/io/aggr/aggr_lacp.c	2006-06-30 15:49:14.880545000 -0700
@@ -569,7 +569,11 @@
 	 * loading mt_fn and mt_arg.
 	 */
 	mtp = portp->lp_txinfo;
-	mtp->mt_fn(mtp->mt_arg, mp);
+	if ((void*)mtp->mt_fn == (void*)mac_txloop)
+		/* TODO: replace NULL with caller's dls_link_t* */
+		((mac_tx_lo_t)mtp->mt_fn)(mtp->mt_arg, mp, NULL);
+	else
+		mtp->mt_fn(mtp->mt_arg, mp);
 
 	pl->NTT = B_FALSE;
 	portp->lp_lacp_stats.LACPDUsTx++;
@@ -901,7 +905,11 @@
 	 * loading mt_fn and mt_arg.
 	 */
 	mtp = portp->lp_txinfo;
-	mtp->mt_fn(mtp->mt_arg, mp);
+	if ((void*)mtp->mt_fn == (void*)mac_txloop)
+		/* TODO: replace NULL with caller's dls_link_t* */
+		((mac_tx_lo_t)mtp->mt_fn)(mtp->mt_arg, mp, NULL);
+	else
+		mtp->mt_fn(mtp->mt_arg, mp);
 	return;
 
 bail:
--- usr/src/uts/common/io/aggr/aggr_send.c.fix_lo	2006-06-14 21:27:39.000000000 -0700
+++ usr/src/uts/common/io/aggr/aggr_send.c	2006-06-30 15:50:04.066406000 -0700
@@ -240,7 +240,14 @@
 		 * changes between loading mt_fn and mt_arg.
 		 */
 		mtp = port->lp_txinfo;
-		if ((mp = mtp->mt_fn(mtp->mt_arg, mp)) != NULL) {
+		if ((void*)mtp->mt_fn == (void*)mac_txloop)
+			/* TODO: replace NULL with caller's
+			   dls_link_t* */
+			mp = ((mac_tx_lo_t)mtp->mt_fn)
+				(mtp->mt_arg, mp, NULL);
+		else
+			mp = mtp->mt_fn(mtp->mt_arg, mp);
+		if (mp != NULL) {
 			mp->b_next = nextp;
 			break;
 		}
--- usr/src/uts/common/io/mac/mac.c.fix_lo	2006-06-14 21:27:39.000000000 -0700
+++ usr/src/uts/common/io/mac/mac.c	2006-07-05 11:34:02.796287000 -0700
@@ -205,7 +205,7 @@
 	 */
 	mip->mi_txinfo.mt_fn = mp->m_tx;
 	mip->mi_txinfo.mt_arg = mp->m_driver;
-	mip->mi_txloopinfo.mt_fn = mac_txloop;
+	mip->mi_txloopinfo.mt_fn = (mac_tx_t) mac_txloop;
 	mip->mi_txloopinfo.mt_arg = mip;
 
 	/*
@@ -1249,7 +1249,7 @@
  * Transmit function -- ONLY used when there are registered loopback listeners.
  */
 mblk_t *
-mac_txloop(void *arg, mblk_t *bp)
+mac_txloop(void *arg, mblk_t *bp, void *dip_caller)
 {
 	mac_impl_t	*mip = arg;
 	mac_t		*mp = mip->mi_mp;
@@ -1280,7 +1280,7 @@
 			else
 				loop_bp = NULL;
 
-			mtfp->mtf_fn(mtfp->mtf_arg, bp);
+			mtfp->mtf_fn(mtfp->mtf_arg, bp, dip_caller);
 			mtfp = mtfp->mtf_nextp;
 		}
 		rw_exit(&mip->mi_txloop_lock);
--- usr/src/uts/sun4v/io/vsw.c.fix_lo	2006-06-14 21:27:43.000000000 -0700
+++ usr/src/uts/sun4v/io/vsw.c	2006-06-30 15:50:57.731978000 -0700
@@ -1247,7 +1247,14 @@
 			mp->b_next = NULL;
 
 			mtp = vswp->txinfo;
-			if ((mp = mtp->mt_fn(mtp->mt_arg, mp)) != NULL) {
+			if ((void*)mtp->mt_fn == (void*)mac_txloop)
+				/* TODO: replace NULL with caller's
+				   dls_link_t* */
+				mp = ((mac_tx_lo_t)mtp->mt_fn)
+					(mtp->mt_arg, mp, NULL);
+			else
+				mp = mtp->mt_fn(mtp->mt_arg, mp);
+			if (mp != NULL) {
 				mp->b_next = nextp;
 				break;
 			}
