You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux内核网桥及接口L2报文追踪:发送帧无法捕获排查

问题排查与解决方案

核心问题分析

你的监听程序无法捕获发送帧,结合ftrace未触发网桥函数的现象,核心问题集中在接口类型错误、原始套接字配置不当和报文发送逻辑缺陷三个方面:

1. 错误使用Dummy接口

你创建的是dummy类型接口而非veth对:

  • Dummy接口是独立虚拟接口,仅用于模拟存在性,发送的报文会直接被丢弃,无法传递到网桥或其他接口;
  • Veth对是成对的虚拟接口,发送到一端的报文会直接转发到另一端,适合网桥内的跨接口测试。

2. 原始套接字绑定参数错误

监听程序中设置了sll_pkttype = PACKET_OUTGOING:

  • 该参数仅捕获从veth0发出的报文,而你需要捕获的是进入veth0的报文;
  • 应移除该参数(默认捕获所有类型)或设置为PACKET_HOST(捕获发往本地接口的报文)。

3. 发送端报文构造不规范

发送代码中用字符串表示MAC地址,但以太网帧要求二进制格式;同时未正确配置发送用的sockaddr_ll结构,导致报文无法正确发送到目标接口。


修正后的环境配置

首先替换Dummy接口为Veth对,确保报文能在网桥内流转:

# 创建网桥并启动
ip link add br0 address 01:02:03:04:00:00 type bridge
ip link set br0 up

# 创建veth对并设置MAC
ip link add veth0 type veth peer name veth1
ip link set veth0 address 01:02:03:04:00:10
ip link set veth1 address 01:02:03:04:00:20

# 将veth接口加入网桥并启动
ip link set veth0 master br0
ip link set veth1 master br0
ip link set veth0 up
ip link set veth1 up

修正后的监听程序代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netpacket/packet.h>
#include <net/ethernet.h>

int main() {
    int sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
    if (sock < 0) {
        perror("socket创建失败");
        exit(1);
    }

    struct sockaddr_ll sa;
    memset(&sa, 0, sizeof(sa));
    sa.sll_family = AF_PACKET;
    sa.sll_protocol = htons(ETH_P_ALL);
    sa.sll_ifindex = if_nametoindex("veth0"); // 绑定到veth0

    if (bind(sock, (struct sockaddr*)&sa, sizeof(sa)) < 0) {
        perror("bind失败");
        close(sock);
        exit(1);
    }

    unsigned char buf[2048];
    ssize_t len;
    printf("开始监听veth0...\n");
    while ((len = recv(sock, buf, sizeof(buf), 0)) > 0) {
        printf("捕获报文长度: %zd字节\n", len);
        // 可在此添加报文解析逻辑
    }

    close(sock);
    return 0;
}

修正后的发送程序代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netpacket/packet.h>
#include <net/ethernet.h>

int main() {
    int sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
    if (sock < 0) {
        perror("socket创建失败");
        exit(1);
    }

    // 构造以太网帧
    struct ethhdr {
        unsigned char h_dest[ETH_ALEN];
        unsigned char h_source[ETH_ALEN];
        unsigned short h_proto;
    } __attribute__((packed));

    const int PAYLOAD_SIZE = 12;
    unsigned char frame[sizeof(struct ethhdr) + PAYLOAD_SIZE];
    struct ethhdr* eth = (struct ethhdr*)frame;

    // 设置目标MAC(veth0)
    unsigned char dest_mac[] = {0x01, 0x02, 0x03, 0x04, 0x00, 0x10};
    memcpy(eth->h_dest, dest_mac, ETH_ALEN);
    // 设置源MAC(veth1)
    unsigned char src_mac[] = {0x01, 0x02, 0x03, 0x04, 0x00, 0x20};
    memcpy(eth->h_source, src_mac, ETH_ALEN);
    // 设置协议类型(0x88b5)
    eth->h_proto = htons(0x88b5);
    // 填充payload
    memcpy(frame + sizeof(struct ethhdr), "hello world!", PAYLOAD_SIZE);

    // 配置发送地址结构
    struct sockaddr_ll sa;
    memset(&sa, 0, sizeof(sa));
    sa.sll_family = AF_PACKET;
    sa.sll_protocol = htons(ETH_P_ALL);
    sa.sll_ifindex = if_nametoindex("veth1"); // 从veth1发送
    sa.sll_halen = ETH_ALEN;
    memcpy(sa.sll_addr, dest_mac, ETH_ALEN);

    ssize_t sent = sendto(sock, frame, sizeof(frame), 0, (struct sockaddr*)&sa, sizeof(sa));
    if (sent < 0) {
        perror("sendto失败");
        close(sock);
        exit(1);
    }
    printf("发送成功: %zd字节\n", sent);

    close(sock);
    return 0;
}

L2报文追踪方法

修正环境后,可通过以下方式追踪网桥内的报文流转:

1. 正确使用ftrace追踪网桥函数

网桥核心函数均以br_开头,需调整过滤规则:

cd /sys/kernel/debug/tracing
echo br_* > set_ftrace_filter
echo function > current_tracer
echo 1 > tracing_on
./my_sender
echo 0 > tracing_on
cat trace

可重点关注br_handle_frame(网桥接收报文入口)、br_forward(转发报文)、br_deliver(交付到本地接口)等函数。

2. 使用tcpdump捕获报文

  • 检查发送端是否发出报文:tcpdump -i veth1 ether host 01:02:03:04:00:10
  • 检查网桥是否接收报文:tcpdump -i br0 ether host 01:02:03:04:00:10
  • 检查目标接口是否收到报文:tcpdump -i veth0 ether host 01:02:03:04:00:10

3. 检查网桥转发表

确认目标MAC已注册到网桥FDB:

bridge fdb show br br0

4. 验证接口状态

确认所有接口已加入网桥并处于UP状态:

ip link show master br0

内容的提问来源于stack exchange,提问作者Abdurrahman Uslu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 05:54:22