Search code examples
clinux-kernelnetwork-programmingiptablesebpf

BPF: mark in structure __skbuff is not writeable?


I have a BPF code (section "classifier"). I use this to load to an interface using the tc (traffic controller) utility. My code changes the mark in __skbuff. Later when I try to catch this mark using iptables, I observe that the mark I edited has disappeared.

Code:

__section("classifier")
int function(struct __sk_buff *skb)
{
    skb->mark = 0x123;

I use the iptable mangle table's below rule to see if the mark is written correctly.

# iptables -t mangle -A PREROUTING -i <my_interface> \
    -m mark --mark 0x123 \
    -j LOG --log-prefix "MY_PRINTS" --log-level 7

Following are the TC commands I used to load my bpf programs ;

# tc qdisc add dev <myInterface> root handle 1: prio
# tc filter add dev <myInterface> parent 1: bpf obj bpf.o flowid 1:1 direct-action


Solution

  • The issue is in your tc commands. You are attaching your filter on the egress side.

    The root parent refers to the egress side, used for traffic shaping. If instead you want to attach your filter on the ingress side, you should use something like this (no handle needed):

    # tc qdisc add dev <myInterface> ingress
    # tc filter add dev <myInterface> ingress bpf obj bpf.o direct-action
    

    Or, better practice, use the BPF-specific qdisc clsact, which can be used to attach filters for both ingress and egress (not much documentation on it, besides its commit log and Cilium's BPF documentation (search for clsact)):

    # tc qdisc add dev <myInterface> clsact
    # tc filter add dev <myInterface> ingress bpf obj bpf.o direct-action