How to Filter RX vs TX Packets in tcpdump When Diagnosing MAC Address Conflicts


2 views

When troubleshooting MAC address conflicts or layer 2 loops, you might encounter situations where your host receives frames containing its own MAC address as the source. The Linux kernel typically logs this as:

bridgename: received packet on bond0.2222 with own address as source address

Standard tcpdump filters like ether src MAC can't distinguish between transmitted (TX) and received (RX) frames because they only examine frame contents. This makes it challenging to identify rogue frames in packet captures.

The solution lies in tcpdump's direction qualifiers for interfaces:

# Capture only received frames with specific source MAC
tcpdump -i bond0.2222 'inbound && ether src 00:11:22:33:44:55'

# Capture only transmitted frames with specific source MAC  
tcpdump -i bond0.2222 'outbound && ether src 00:11:22:33:44:55'

Key points:

  • inbound filters for frames received by the interface
  • outbound filters for frames transmitted by the interface
  • Combine with standard MAC filters for precise targeting

For more advanced filtering, eBPF provides direct access to kernel metadata:

# Filter RX packets with BPF (using ifindex direction)
tcpdump -i eth0 'ether src 00:11:22:33:44:55 and (ifindex != 0)'

# Advanced BPF example checking skb->pkt_type
tcpdump -i eth0 -ddd 'ether src 00:11:22:33:44:55' | \
awk '/ldh/ {print "0x" $3}' | \
xargs -I {} sudo tcpdump -i eth0 -Q in -y EN10MB 'ether src {}'

Here's how I diagnosed a virtual machine MAC conflict:

# First, identify the problematic interface
ip -br link show | grep bond0.2222

# Then run directional capture
sudo tcpdump -i bond0.2222 -nn -vvv -XX \
'inbound && ether src 00:11:22:33:44:55' -w conflict.pcap

# Analyze with Wireshark or tshark
tshark -r conflict.pcap -Y "eth.src == 00:11:22:33:44:55" \
-T fields -e frame.time -e eth.src -e eth.dst

For persistent issues, consider kernel-level monitoring:

# Monitor bridge operations
echo 1 > /sys/class/net/br0/bridge/multicast_snooping

# Or use ftrace for deep inspection
echo 1 > /sys/kernel/debug/tracing/events/net/netif_receive_skb/enable
cat /sys/kernel/debug/tracing/trace_pipe | grep '00:11:22:33:44:55'

When diagnosing layer 2 network issues involving MAC address conflicts, one particularly tricky scenario occurs when a host receives frames containing its own MAC address as the source. This typically indicates:

  • A network loop creating packet duplication
  • Another device with a duplicate MAC address
  • Improper virtualization bridge configuration

Traditional packet capture filters like ether src MAC can't distinguish between transmitted and received frames because:

tcpdump -i bond0 -n 'ether src 00:11:22:33:44:55'

This will capture both legitimate outgoing frames AND rogue incoming frames with the same source MAC, making diagnosis difficult.

Linux's libpcap provides direction indicators we can leverage in BPF filters:

# Capture only received frames with our MAC as source
tcpdump -i bond0 -n 'inbound and ether src 00:11:22:33:44:55'

# Capture only transmitted frames
tcpdump -i bond0 -n 'outbound and ether src 00:11:22:33:44:55'

For deeper inspection, we can use eBPF to track packet directions at the kernel level:

# BPF program to count direction-violating frames
#include 
#include 

SEC("xdp")
int count_mac_violations(struct xdp_md *ctx) {
    void *data = (void *)(long)ctx->data;
    void *data_end = (void *)(long)ctx->data_end;
    struct ethhdr *eth = data;

    if (eth + 1 > data_end)
        return XDP_PASS;

    // Check if source MAC matches our interface
    if (eth->h_source[0] == 0x00 && ... ) {
        if (ctx->ingress_ifindex == OUR_INTERFACE_INDEX) {
            // Counter for received frames with our MAC
            increment_counter(0);
        } else {
            // Counter for transmitted frames (normal case)
            increment_counter(1);
        }
    }
    return XDP_PASS;
}

For Linux bridge configurations showing CAM table issues:

# Show MAC address table with timestamps
bridge -d fdb show | grep 00:11:22:33:44:55

# Monitor bridge traffic with direction info
tc -s filter show dev bond0 parent ffff:
  1. First confirm the anomaly with bridge logs:
    dmesg | grep "with own address as source"
  2. Isolate received rogue frames:
    tcpdump -i bond0 -nn -c 10 'inbound and ether src 00:11:22:33:44:55' -w rogue.pcap
  3. Compare with transmitted frames:
    tcpdump -i bond0 -nn -c 10 'outbound and ether src 00:11:22:33:44:55' -w valid.pcap
Symptom Likely Cause Solution
Frequent MAC flapping Network loop Enable STP/RSTP
Persistent duplicate MAC VM cloning issue Regenerate MACs
Intermittent occurrences Faulty NIC Replace hardware