I create a Linux bridge and add two virtual interface to this bridge.
ip link add br0 address 01:02:03:04:00:00 type bridge
ip link add veth0 address 01:02:03:04:00:10 type dummy
ip link add veth1 address 01:02:03:04:00:20 type dummy
ip link set dev veth0 master br0
ip link set dev veth1 master br0
ip link set br0 up
ip link set veth0 up
ip link set veth1 up
Then write a raw socket listening program that bind the veth0.
socket = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))
struct sockaddr_ll sockaddr;
memset(&sockaddr, 0x0, sizeof(sockaddr));
sockaddr.sll_family = AF_PACKET;
sockaddr.sll_protocol = htons(ETH_P_ALL);
sockaddr.sll_pkttype = PACKET_OUTGOING;
sockaddr.sll_ifindex = if_nametoindex("veth0");
bind(socket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)
Then write a sender program that same way created as the listener, using veth1 interface. That program send eth frame.
struct ethhdr_frame* eth_packet;
eth_packet->h_dest = "01:02:03:04:00:10" //it not string, just show purpose
eth_packet->h_source = "01:02:03:04:00:20"
eth_packet->h_proto = 0x88b5
eth_packet->payload = "hello world!"
Now my problem is listener can't capture eth frame which is send by my sender. To find where is my packet dropped, I used ftrace filtered by br*, but even any bridge handler function wasn't call.
$cd /sys/kernel/debug/tracing
$echo br* > set_ftrace_filter
$echo function_graph > current_tracer
$echo 1 > tracing_on ; ./my_sender ; echo 0 > tracing_on