I wrote an ebpf code to set tos of ip header, it take effective when attaching into the root path (1/sys/fs/cgroup/unified1), but it does not take effective when attaching into the child cgroup such as /sys/fs/cgroup/unified/docker/
code:
#include <linux/bpf.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <linux/ip.h>
#include <linux/in.h>
#include <linux/socket.h>
#include "bpf_helpers.h"
//#ifndef __section
//# define __section(NAME) \
// __attribute__((section(NAME), used))
//#endif
//
#ifndef BPF_FUNC
#define BPF_FUNC(NAME, ...) \
(*NAME)(__VA_ARGS__) = (void *) BPF_FUNC_##NAME
#endif
static void BPF_FUNC(trace_printk, const char *fmt, int fmt_size, ...);
#ifndef printk
# define printk(fmt, ...) \
({ \
char ____fmt[] = fmt; \
trace_printk(____fmt, sizeof(____fmt), ##__VA_ARGS__); \
})
#endif
SEC("sockops")
int set_initial_rto(struct bpf_sock_ops *skops)
{
int tos = 0x38;
int op = (int) skops->op;
printk("remote %x, op=%d tos %d\n",skops->remote_ip4, op,tos);
switch (op) {
case BPF_SOCK_OPS_TCP_CONNECT_CB:
case BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB:
case BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB:
printk("set tos %d",tos);
bpf_setsockopt(skops,IPPROTO_IP, IP_TOS, &tos, sizeof(tos));
break;
}
return 1;
}
char _license[] SEC("license") = "GPL";
Server env:
Ubuntu
kernel version : 5.4.0-77
bpf status:
# bpftool cgroup tree
CgroupPath
ID AttachType AttachFlags Name
/sys/fs/cgroup/unified/docker
10544 sock_ops set_tos
expected:
I can capture the package by tcpdump
actually:
tcpdump can't capture any package with DSCP mark
$ sudo tcpdump -vv -n ip -c 10 -i bond0.1000 and ip[1]=56
tcpdump: listening on bond0.1000, link-type EN10MB (Ethernet), capture size 262144 bytes
BTW, tcpdump can capture the package with DSCP mark if I attach the bpf prog to /sys/fs/cgroup/unified/