3

我有一个在 Linux (2.6.38.8) 上运行的应用程序,使用 libpcap (>1.0) 捕获通过以太网传输的数据包。我的应用程序使用了接近 100% 的 CPU,我不确定我是否尽可能高效地使用 libpcap。

我正在努力寻找 pcap 可调参数和性能之间的任何关联。

这是我的简化代码(错误检查等省略):

// init libpcap
pcap_t *p = pcap_create("eth0", my_errbuf);
pcap_set_snaplen(p, 65535);
pcap_set_promisc(p, 0);
pcap_set_timeout(p, 1000);
pcap_set_buffer_size(p, 16<<20); // 16MB
pcap_activate(p);

// filter
struct bpf_program filter;
pcap_compile(p, &filter, "ether dst 00:11:22:33:44:55", 0, 0);
pcap_setfilter(p, &filter);

// do work
while (1) {
    int ret = pcap_dispatch(p, -1, my_callback, (unsigned char *) my_args);
    if (ret <= 0) {
        if (ret == -1) {
            printf("pcap_dispatch error: %s\n", pcap_geterr(p));
        } else if (ret == -2) {
            printf("pcap_dispatch broken loop\n");
        } else if (ret == 0) {
            printf("pcap_dispatch zero packets read\n");
        } else {
            printf("pcap_dispatch returned unexpectedly");
        }
    } else if (ret > 1) {
        printf("processed %d packets\n", ret);
    }
}

使用 1000 毫秒超时和 2M、4M 和 16M 缓冲区大小时的结果在高数据速率(~200 1kB 数据包/秒)下是相同的:pcap_dispatch 始终返回 2。根据 pcap_dispatch 手册页,我希望pcap_dispatch 在缓冲区已满或超时到期时返回。但是返回值为 2 时,这两个条件都不应该满足,因为只读取了 2kB 的数据,并且只经过了 2/200 秒。

如果我降低数据速率(约 100 个 1kB 数据包/秒),pcap_dispatch 会返回 2 到 7,因此将数据速率减半会影响每个 pcap_dispatch 处理的数据包数量。(我认为数据包越多越好,因为这意味着操作系统和用户空间之间的上下文切换更少——这是真的吗?)

超时值似乎也没有什么区别。

在所有情况下,我的 CPU 使用率都接近 100%。

我开始怀疑我是否应该尝试使用 PF_RING 版本的 libpcap,但从我在 SO 和 libpcap 邮件列表中阅读的内容来看,libpcap > 1.0 无论如何都会执行零拷贝,所以可能没有意义。

任何想法,指针非常感谢!G

4

0 回答 0