I have a Linux bridge (Ubuntu 15.10, 64bit, name Bridge B) with two physical interfaces, eth0 and eth1, and the bridge interface’s name is br0. Send A (Win 10) connects to eth0, and Receiver C (Win 10) connects to eth1. As shown in the figure below.

Sender A <------> (eth0) Bridge B (eth1) <------> Receiver C

Sender A’s MAC Address: D4:EE:07:3F:F9:0D, IP Address:
Bridge B’s eth0 MAC Address: B0:51:8E:FF:2F:C8, No IP Address
Bridge B’s eth1 MAC Address: B0:51:8E:FF:2F:C9, No IP Address
Bridge B’s br0 MAC Address is the same with eth0 (Auto), IP Address:
Receiver C’s MAC Address: 4C:CC:6A:DC:91:60, IP Address:

Send A send packet to Receiver C, such as icmp ping.

Before I configure ebtable rule in Bridge B for redirecting packet to layer 3, everything is OK, Receiver C receive Send A's ping packet with source MAC Address D4:EE:07:3F:F9:0D, and destination MAC Address 4C:CC:6A:DC:91:60, nothing changed after packet send out from Send A.

When I set up ebtable rules in Bridge B for redirecting forwarded packet to layer 3, then I can use iptables for packet filtering in Bridge B. Code is:

ebtables -t broute -A BROUTING -p IPv4 --logical-in br0 -j redirect

Then problem happened. Packet from Send A to Receiver C which through Bridge B's layer 3, I can see in Receiver C that the source MAC Address of the packet is B0:51:8E:FF:2F:C8. Obviously, the source MAC Address is changed to Bridge B’s br0 MAC Address.

I am wondering the problem is that when packet is redirected from layer 2 to layer 3, and then reroute by Bridge B in layer 3, the source MAC Address then be changed by Bridge B’s kernel.

Is there something I can do or configure to preserve source MAC Address unchanged after layer-3 filtering through Bridge B?

/etc/network/interface configuration in Bridge B

auto eth0
iface eth0 inet manual
up ifconfig eth0 up

auto eth1
iface eth1 inet manual
up ifconfig eth1 up

auto br0
iface br0 inet static
pre-up ip link set eth0 promisc on
pre-up ip link set eth1 promisc on
pre-up echo "1">/proc/sys/net/ipv4/ip_forward
bridge_ports eth0 eth1

CGretski, I read the man page of ebtables in http://ebtables.netfilter.org/misc/ebtables-man.html. My personal understanding is that when using ebtables “-j redirect”, the redirect target will change the MAC target address to the bridge device, then the packet can be sent to bridge interface br0, as mentioned in the example above. So, a packet from Sender A to Receiver C, the target mac address will be changed to bridge’s mac address, nothing mention about source mac address whether will be changed or not.

After filtering by Bridge B’s layer 3 (or nothing done by layer 3), the packet now should be rerouted to Receiver C. Then the target mac address of the packet will be changed to Receiver C. But on the same time, packet’s source mac address be changed to Bridge B’s mac address.

If I use "-j accept" in ebtables target, as you advice, packet will not be sent to layer 3, and transparently pass through Bridge B, nothing be changed, including source and target mac address. But I cannot do any layer 3 filtering.

The reason I want to maintain packet’s layer2 information is that I do not want Receiver C to sense of any existence of device between Sender A and itself. Another imporent reason is that in some scenarios, Receiver C (especially when it is a gateway) will drop the packet after source mac and ip verification.

1 Answer 1


Losing layer2 info is an expected side-effect of introducing Layer3 routing and is the very definition of the "-j redirect" target.

From ebtables man page:

The redirect target will change the MAC target address to that of the bridge device the frame arrived on.

you could try "-j accept" though that may not pass it up to layer 3 filtering.

What are you trying to achieve by maintaining layer2 information?

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .