On Thu, 16 Jan 2020, Andrii Nakryiko wrote: > On 1/16/20 11:06 AM, Vincent Li wrote: > > > > > > On Thu, 16 Jan 2020, Toke Høiland-Jørgensen wrote: > > > > Hi Toke, > > > >> > >> You could also try the xdp-loader in xdp-tools: > >> https://github.com/xdp-project/xdp-tools > >> > >> It's somewhat basic still, but should be able to at least load a basic > >> program - please file a bug report if it fails. > > > > I tried the xdp-tools xdp-loader, when the optlen is global variable, I > > got: > > # xdp-loader load enp3s0 tcp_option.o > > Couldn't load BPF program: Relocation failed > > > > if I move the optlen, i variable to local variable, I got: > > > > # xdp-loader load enp3s0 tcp_option.o > > Couldn't load eBPF object: Invalid argument(-22) > > > > Here is the complete code: > > > > #include <stdint.h> > > #include <arpa/inet.h> > > #include <asm/byteorder.h> > > #include <linux/bpf.h> > > #include <linux/if_ether.h> > > #include <linux/ip.h> > > #include <linux/tcp.h> > > #include <linux/pkt_cls.h> > > > > /* > > * Sample XDP to parse tcp option. > > * compile it with: > > * clang -O2 -emit-llvm -c tcp_option.c -o - |llc -march=bpf -filetype=obj -o tcp_option.o > > * attach it to a device with XDP as: > > * ip link set dev lo xdp object tcp_option.o verbose > > */ > > > > #define SEC(NAME) __attribute__((section(NAME), used)) > > > > #define TCPOPT_EOL 0 /* End of options (1) */ > > #define TCPOPT_NOP 1 /* No-op (1) */ > > #define TCPOPT_MAXSEG 2 /* Maximum segment size (4) */ > > #define TCPOPT_WSCALE 3 /* Window scaling (3) */ > > #define TCPOPT_SACKOK 4 /* Selective ACK permitted (2) */ > > #define TCPOPT_SACK 5 /* Actual selective ACK (10-34) */ > > #define TCPOPT_TSTAMP 8 /* Timestamp (10) */ > > > > > > /* from bpf_helpers.h */ > > > > static int (*bpf_trace_printk)(const char *fmt, int fmt_size, ...) = > > (void *) BPF_FUNC_trace_printk; > > > > static unsigned long long (*bpf_get_prandom_u32)(void) = > > (void *) BPF_FUNC_get_prandom_u32; > > > > > > static int tcp_option(void *data, void *data_end) > > I don't know if xdp-loader handles subprogram calls and relocations. > Mark it as __always_inline. I tried __always_inline the tcp_option function, same relocation error, the relocation error only occurs when optlen is global variable, if I put optlen as local variable, it complains different error: xdp-loader load enp3s0 tcp_option.o Couldn't load eBPF object: Invalid argument(-22) I suspect this may not be specific to xdp-loader. In the beginning, I made some code changes in suricata/ebpf/xdp-filter.c to parse tcp options and I got same relocation error, this leads me to write a standalone sample xdp program and use iproutes to load the sample program. now we know the global variable cause iproutes to fail. and I am back to the original problem of suricata/ebpf/xdp-filter.c or xdp-loader libbpf way to load xdp program :).