/dev/ipnet can duplicate packets
If you use /dev/ipnet via snoop, say snoop -I igb0 on a physical nic and send traffic to a vnic over it, there will be packet duplication. Worse, if the router flag is turned on, thus ip forwarding, then this will cause a chain reaction that leads to a double fault due to stack overflow.
ipnet uses the ipobjs to hook into the traffic that goes across the ip layer. In addition, it enables the capturing of all multicast traffic that takes place. It is through this enabling that we get into trouble. When /dev/ipnet gets a DL_PROMISC_* request, it will go through and appropriately call and make a request for DLS_PROMISC_MULTI and pass that stream message off. This is eventually passed through streams to the function dls_promisc(). In dls_promisc we hit our error. By default, dls_promisc treats a request of DLS_PROMISC_MULTI and DLS_PROMISC_PHYS the same. Thus it asks mac for MAC_CLIENT_PROMISC_ALL. mac_promisc_add() will grant that to physical nics in the global zone. If you are within a zone with an exclusive stack, it filters what you receive such that you only receive broadcast, multicast, and unicast packets for your mac – as though you were plugged into a different switch port.
When this happens, our dls callback is set to be ip_input for our zone. Because we were snooping on igb0 and not the vnic, the vnic did not set its dls_promisc flags. The dls layer currently drops specific packets when promisc is active. Ideally we would not have these packets duplicated at all, but that's a future RFE. Because this was coming over different dls_t's we saw the duplication.
The fix here is actually a bit different. The root of this is that when ipnet requested just multicst traffic, we in fact gave it all traffic. Instead, if only DLS_PROMISC_MULTI is set then we should only request MAC_CLIENT_PROMISC_MULTI. This means that mac will only send us up multicast packets and not touch other unicast packets. In tandem, we need to make sure that the dls checks for the case where we have only set multicast and only drops multicast packets while in the normal data path and not the promiscuous callback path.