--- 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-06-28 19:35:57.829035000 -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).
@@ -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/io/dls/dls.c.fix_lo	2006-06-14 21:27:37.000000000 -0700
+++ usr/src/uts/common/io/dls/dls.c	2006-06-29 10:07:02.996674000 -0700
@@ -795,7 +795,15 @@
 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 */
+		return ((*(mac_tx_lo_t*)mtp->mt_fn)
+			(mtp->mt_arg, mp, dip->di_dvp->dv_dlp));
+	}
 
 	return (mtp->mt_fn(mtp->mt_arg, mp));
 }
--- 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-29 10:32:13.211857000 -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-29 10:25:16.401166000 -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-06-29 10:20:07.125445000 -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 *dlp_arg)
 {
 	mac_impl_t	*mip = arg;
 	mac_t		*mp = mip->mi_mp;
@@ -1272,22 +1272,30 @@
 		rw_enter(&mip->mi_txloop_lock, RW_READER);
 		mtfp = mip->mi_mtfp;
 		while (mtfp != NULL && loop_bp != NULL) {
-			bp = loop_bp;
+			/* Only do the promiscuous loopback call if
+			   the packet was not sent (i.e., tx'ed) on
+			   our own dls_link_t* */
+			if (dlp_arg != mtfp->mtf_arg) {
+				bp = loop_bp;
+
+				/* XXX counter bump if copymsg()
+				   fails? */
+				if (mtfp->mtf_nextp != NULL)
+					loop_bp = copymsg(bp);
+				else
+					loop_bp = NULL;
 
-			/* XXX counter bump if copymsg() fails? */
-			if (mtfp->mtf_nextp != NULL)
-				loop_bp = copymsg(bp);
-			else
-				loop_bp = NULL;
-
-			mtfp->mtf_fn(mtfp->mtf_arg, bp);
+				mtfp->mtf_fn(mtfp->mtf_arg, bp);
+			}
 			mtfp = mtfp->mtf_nextp;
 		}
 		rw_exit(&mip->mi_txloop_lock);
 
 		/*
-		 * It's possible we've raced with the disabling of promiscuous
-		 * mode, in which case we can discard our copy.
+		 * It's possible we've raced with the disabling of
+		 * promiscuous mode _or_ our own dls_link_t* was the
+		 * last one in the chain, in which cases we can
+		 * discard our copy.
 		 */
 		if (loop_bp != NULL)
 			freemsg(loop_bp);
--- 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-29 10:18:16.400402000 -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;
 			}
