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: 192.168.1.2
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: 192.168.1.1
Receiver C’s MAC Address: 4C:CC:6A:DC:91:60, IP Address: 192.168.1.3
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 address 192.168.1.1 netmask 255.255.255.0 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.