我使用BPF加密器集合(BCC)编写了一个eBPF程序来修改传出的UDP数据包。
我使用了BPF_PROG_TYPE_SCHED_ACT
类型的程序,我希望这是正确的。(https://ebpf-docs.dylanreimerink.nl/linux/program-type/)。
但是装上之后,我不知道如何“激活”它。将其附加到eth0
或其他东西似乎不起作用。我猜我需要tc
命令,但我不明白为什么(因为我不知道那到底是什么)。
下面是我的Python脚本:
import sys
import time
from bcc import BPF
def main():
src = open("my_example.c").read()
b = BPF(text=src, cflags=["-Wno-macro-redefined"]) # 3
# fn = b.load_func("my_example", BPF.SK_SKB)
fn = b.load_func("my_example", BPF.SCHED_CLS)
b.attach_raw_socket(fn, "eth0") # this doesn't work
if __name__ == "__main__":
main()
而eBPF计划本身是这样的:
#include <bcc/bpf.h>
#include <linux/if_ether.h>
#include <linux/ip.h>
#include <linux/udp.h>
int my_example(struct __sk_buff *skb)
{
if(skb->protocol != htons(ETH_P_IP)) return TC_ACT_OK;
if(skb->pkt_type != PACKET_OUTGOING) return TC_ACT_OK;
if(skb->wire_len<176) return TC_ACT_OK;
if(skb->len<176) return TC_ACT_OK;
bpf_skb_pull_data(skb, 176);
u8* packet = (u8*)(long)skb->data;
u8* packet_end = (u8*)(long)skb->data_end;
if(packet_end<packet+176) return TC_ACT_OK;
if(packet[94] != 0x54) return TC_ACT_OK;
bpf_skb_change_tail(skb, 30, 0);
packet=(u8*)(long)skb->data;
packet_end=(u8*)(long)skb->data_end;
if (packet_end<packet+206) return TC_ACT_OK;
packet[205] = packet[205-30];
packet[94] = 0x56;
// ...
// more code for length and checksums ...
return TC_ACT_RECLASSIFY;
}
如何“激活”这个程序?
1条答案
按热度按时间polhcujo1#
**TL; DR.**您可以使用Python pyroute 2库将程序附加到接口eth0的tc钩子。请参阅我文章末尾的代码示例。
这不起作用,因为您将程序声明为SCHED_CLS类型,然后试图将其附加到不同的钩子上。
如果你使用bcc,你可以检查示例程序https://github.com/iovisor/bcc/blob/master/examples/networking/xdp/xdp_drop_count.py(该程序同时处理XDP和tc)。特别是,您可以将tc-bpf程序附加到: