1

我写了一个这样的简单程序:

SEC("tc_redirect")
int _egress_redirect(struct __sk_buff *skb){
    return bpf_redirect(5,0); // redirect all egress packets to interface 5
}
# tc filter add dev (4) egress prio 1 handle 1 bpf da obj x.o sec tc_redirect

发送方将数据包重定向到接口 5,接收方在对等接口接收数据包,但像 iperf 这样的程序没有收到它,为什么?

4

1 回答 1

1

如果您可以观察到数据包到达接收器的接口(例如,使用 tcpdump)但不在您的用户空间进程中,则该数据包可能在其间被内核丢弃

您应该检查目标 IP、目标 MAC 地址和目标端口是否正确。您还可以使用以下 bcc 脚本查看哪个内核函数丢弃了数据包。然后在例如 bootlin 上搜索该功能可以为您提供一些关于正在发生的事情的指示。

#!/usr/bin/python
#
# packetdrop  Prints the kernel functions responsible for packet drops. Similar
#             to dropwatch.
#
# REQUIRES: Linux 4.7+ (BPF_PROG_TYPE_TRACEPOINT support).
#
# Copyright 2018 Orange.
# Licensed under the Apache License, Version 2.0 (the "License")
from __future__ import print_function
from bcc import BPF
from time import sleep

# load BPF program
b = BPF(text="""
struct key_t {
    u64 location;
};
BPF_HASH(drops, struct key_t);
TRACEPOINT_PROBE(skb, kfree_skb) {
    u64 zero = 0, *count;
    struct key_t key = {};
    // args is from /sys/kernel/debug/tracing/events/skb/kfree_skb/format
    key.location = (u64)args->location;
    count = drops.lookup_or_init(&key, &zero);
    (*count)++;
    return 0;
};
""")

# header
print("Tracing... Ctrl-C to end.")

# format output
try:
    sleep(99999999)
except KeyboardInterrupt:
    pass

print("\n%-16s %-26s %8s" % ("ADDR", "FUNC", "COUNT"))
drops = b.get_table("drops")
print(drops.items()[0][1].value)
for k, v in sorted(drops.items(),
                   key=lambda elem: elem[1].value):
    print("%-16x %-26s %8d"
          % (k.location, b.ksym(k.location), v.value))
于 2020-08-11T07:24:09.320 回答