I used the BPF Compiler Collection (BCC) to write an eBPF program to modify outgoing UDP packets.
I used the program type BPF_PROG_TYPE_SCHED_ACT, which I hope is the right one. (https://ebpf-docs.dylanreimerink.nl/linux/program-type/).
But having loaded it, I don't know how to "activate" it. Attaching it to eth0 or something does not seem to work. I was guessing I need the tc command, but I don't understand why (because I don't know what that is, exactly).
Here is my Python script:
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()
While the eBPF Program itself is this:
#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;
}
How do I "activate" this program?
TL;DR. You can attach your program to the tc hook of interface eth0 with the Python pyroute2 library. See the code example at the end of my post.
This doesn't work because you declared your program as being of type SCHED_CLS and you then try to attach it to a different hook.
Given you are using bcc, you can check example program https://github.com/iovisor/bcc/blob/master/examples/networking/xdp/xdp_drop_count.py (that program handles both XDP and tc). In particular you can attach your tc-bpf program with: