duplicating packets in promisc mode #13

Closed
thepax opened this Issue Nov 9, 2012 · 4 comments

3 participants

@thepax

There are duplicating packets in promisc mode inside VM - all outgoing packets are sent back into VM.

Inside Linux VM:

[root@qz1 ~]# ifconfig eth0
eth0 Link encap:Ethernet HWaddr B2:28:EA:21:A3:8A

inet addr:10.30.4.97 Bcast:10.30.4.255 Mask:255.255.255.0
inet6 addr: fe80::b028:eaff:fe21:a38a/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:21292 errors:0 dropped:0 overruns:0 frame:0
TX packets:29 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:2203766 (2.1 MiB) TX bytes:2295 (2.2 KiB)

[root@qz1 ~]# tcpdump -i eth0 -n icmp
[ 71.017431] device eth0 entered promiscuous mode
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
11:10:09.042654 IP 10.30.3.17 > 10.30.4.97: ICMP echo request, id 35093, seq 1, length 64
11:10:09.283911 IP 10.30.4.97 > 10.30.3.17: ICMP echo reply, id 35093, seq 1, length 64
11:10:09.284362 IP 10.30.4.97 > 10.30.3.17: ICMP echo reply, id 35093, seq 1, length 64
11:10:10.038734 IP 10.30.3.17 > 10.30.4.97: ICMP echo request, id 35093, seq 2, length 64
11:10:10.038845 IP 10.30.4.97 > 10.30.3.17: ICMP echo reply, id 35093, seq 2, length 64
11:10:10.039287 IP 10.30.4.97 > 10.30.3.17: ICMP echo reply, id 35093, seq 2, length 64
11:10:11.039998 IP 10.30.3.17 > 10.30.4.97: ICMP echo request, id 35093, seq 3, length 64
11:10:11.040106 IP 10.30.4.97 > 10.30.3.17: ICMP echo reply, id 35093, seq 3, length 64
11:10:11.040552 IP 10.30.4.97 > 10.30.3.17: ICMP echo reply, id 35093, seq 3, length 64
11:10:12.041021 IP 10.30.3.17 > 10.30.4.97: ICMP echo request, id 35093, seq 4, length 64
11:10:12.041102 IP 10.30.4.97 > 10.30.3.17: ICMP echo reply, id 35093, seq 4, length 64
11:10:12.041530 IP 10.30.4.97 > 10.30.3.17: ICMP echo reply, id 35093, seq 4, length 64

12 packets captured
16 packets received by filter
0 packets dropped by kernel
[ 92.014430] device eth0 left promiscuous mode

[root@qz1 ~]# tcpdump -i eth0 -n -p icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
11:10:20.354079 IP 10.30.3.17 > 10.30.4.97: ICMP echo request, id 35349, seq 1, length 64
11:10:20.354160 IP 10.30.4.97 > 10.30.3.17: ICMP echo reply, id 35349, seq 1, length 64
11:10:21.356011 IP 10.30.3.17 > 10.30.4.97: ICMP echo request, id 35349, seq 2, length 64
11:10:21.356087 IP 10.30.4.97 > 10.30.3.17: ICMP echo reply, id 35349, seq 2, length 64
11:10:22.356955 IP 10.30.3.17 > 10.30.4.97: ICMP echo request, id 35349, seq 3, length 64
11:10:22.357042 IP 10.30.4.97 > 10.30.3.17: ICMP echo reply, id 35349, seq 3, length 64
11:10:23.358160 IP 10.30.3.17 > 10.30.4.97: ICMP echo request, id 35349, seq 4, length 64
11:10:23.358233 IP 10.30.4.97 > 10.30.3.17: ICMP echo reply, id 35349, seq 4, length 64

8 packets captured
8 packets received by filter
0 packets dropped by kernel

@thepax

The issues is that DLS (via DLPI) initializes promisc mode without MAC_PROMISC_FLAGS_NO_TX_LOOP flag.

The following quick-hack fixes the issue:

diff --git a/usr/src/uts/common/io/dls/dls.c b/usr/src/uts/common/io/dls/dls.c
index d35c1e4..b00cbdf 100644
--- a/usr/src/uts/common/io/dls/dls.c 
+++ b/usr/src/uts/common/io/dls/dls.c
@@ -261,7 +261,7 @@ dls_promisc(dld_str_t *dsp, uint32_t new_flags)
                dsp->ds_promisc = new_flags;
                err = mac_promisc_add(dsp->ds_mch, MAC_CLIENT_PROMISC_ALL,
                    dls_rx_promisc, dsp, &dsp->ds_mph,
-                   (new_flags != DLS_PROMISC_SAP) ? 0 :
+                   (new_flags != DLS_PROMISC_SAP) ? MAC_PROMISC_FLAGS_NO_TX_LOOP :
                    MAC_PROMISC_FLAGS_NO_PHYS);
                if (err != 0) {
                        dsp->ds_promisc = old_flags;
@@ -300,7 +300,7 @@ dls_promisc(dld_str_t *dsp, uint32_t new_flags)
                /* Honors both after-remove and before-add semantics! */
                dsp->ds_promisc = new_flags;
                err = mac_promisc_add(dsp->ds_mch, MAC_CLIENT_PROMISC_ALL,
-                   dls_rx_promisc, dsp, &dsp->ds_mph, 0);
+                   dls_rx_promisc, dsp, &dsp->ds_mph, MAC_PROMISC_FLAGS_NO_TX_LOOP);
                if (err != 0)
                        dsp->ds_promisc = old_flags;
        } else {

Though, it's not a solution.

@sjorge

For traceability, upstream bug https://www.illumos.org/issues/3847

@rmustacc
Joyent member

I've just verified that this is solved with the recent bardiche work. I'll close this ticket when that lands.

@rmustacc
Joyent member

Resolved through joyent/illumos-joyent@ad740f5 and 31a39c6.

@rmustacc rmustacc closed this Mar 20, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment