1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2022 Felix Fietkau <nbd@nbd.name>
7 #include <sys/socket.h>
8 #include <sys/resource.h>
9 #include <netinet/if_ether.h>
10 #include <netlink/msg.h>
11 #include <netlink/attr.h>
12 #include <netlink/socket.h>
13 #include <linux/rtnetlink.h>
14 #include <linux/pkt_cls.h>
16 #include <bpf/libbpf.h>
19 static int unetd_bpf_pr(enum libbpf_print_level level
, const char *format
,
22 return vfprintf(stderr
, format
, args
);
25 static void unetd_init_env(void)
27 struct rlimit limit
= {
28 .rlim_cur
= RLIM_INFINITY
,
29 .rlim_max
= RLIM_INFINITY
,
32 setrlimit(RLIMIT_MEMLOCK
, &limit
);
36 unetd_set_prog_mtu(struct bpf_object
*obj
, uint32_t mtu
)
38 struct bpf_map
*map
= NULL
;
40 while ((map
= bpf_object__next_map(obj
, map
)) != NULL
) {
41 if (!strstr(bpf_map__name(map
), ".rodata"))
44 bpf_map__set_initial_value(map
, &mtu
, sizeof(mtu
));
49 unetd_attach_bpf_prog(int ifindex
, int fd
, bool egress
)
51 DECLARE_LIBBPF_OPTS(bpf_tc_hook
, hook
,
52 .attach_point
= egress
? BPF_TC_EGRESS
: BPF_TC_INGRESS
,
54 DECLARE_LIBBPF_OPTS(bpf_tc_opts
, attach_tc
,
55 .flags
= BPF_TC_F_REPLACE
,
58 .priority
= UNETD_MSS_PRIO_BASE
);
60 bpf_tc_hook_create(&hook
);
62 return bpf_tc_attach(&hook
, &attach_tc
);
65 int unetd_attach_mssfix(int ifindex
, int mtu
)
67 struct bpf_program
*prog
;
68 struct bpf_object
*obj
;
76 libbpf_set_print(unetd_bpf_pr
);
78 obj
= bpf_object__open_file(mssfix_path
, NULL
);
79 if (libbpf_get_error(obj
)) {
80 perror("bpf_object__open_file");
84 prog
= bpf_object__find_program_by_name(obj
, "mssfix");
86 perror("bpf_object__find_program_by_name");
90 bpf_program__set_type(prog
, BPF_PROG_TYPE_SCHED_CLS
);
92 unetd_set_prog_mtu(obj
, mtu
);
94 if (bpf_object__load(obj
)) {
95 perror("bpf_object__load");
99 prog_fd
= bpf_program__fd(prog
);
100 unetd_attach_bpf_prog(ifindex
, prog_fd
, true);
101 unetd_attach_bpf_prog(ifindex
, prog_fd
, false);
106 bpf_object__close(obj
);