Skip to content

Commit 111ab20

Browse files
committed
compatibility for iptables from 5.4 to 6.0 kernel version
Signed-off-by: Menglong Dong <imagedong@tencent.com>
1 parent 10e8c63 commit 111ab20

9 files changed

Lines changed: 119 additions & 41 deletions

File tree

common.mk

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,12 +92,12 @@ progs/%.o: progs/%.c kheaders.h
9292
@file $@ | grep debug_info > /dev/null || (rm $@ && exit 1)
9393

9494
%.skel.h: %.o
95-
$(BPFTOOL) gen skeleton $< > $@
95+
$(BPFTOOL) gen skeleton $< $(SKEL_FLAGS) > $@
9696

9797
$(bpf_progs): %: %.skel.h
98-
@echo "bpf compile success"
98+
@:
9999

100-
bpf: $(bpf_progs)
100+
bpf: $(bpf_progs) $(bpf_progs_ext)
101101

102102
$(progs): %: %.c bpf
103103
@if [ -n "$(prog-$@)" ]; then \

component/sys_utils.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <string.h>
1313
#include <stdlib.h>
1414
#include <sys/resource.h>
15+
#include <sys/utsname.h>
1516

1617
#include "sys_utils.h"
1718

@@ -68,3 +69,14 @@ bool fsearch(FILE *f, char *target)
6869
}
6970
return false;
7071
}
72+
73+
int kernel_version()
74+
{
75+
int major, minor, patch;
76+
struct utsname buf;
77+
78+
uname(&buf);
79+
sscanf(buf.release, "%d.%d.%d", &major, &minor, &patch);
80+
81+
return kv_to_num(major, minor, patch);
82+
}

component/sys_utils.h

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@
1313

1414
extern int log_level;
1515

16-
int execf(char *output, char *fmt, ...);
17-
int exec(char *cmd, char *output);
18-
int liberate_l();
19-
bool fsearch(FILE *f, char *target);
16+
int execf(char *output, char *fmt, ...);
17+
int exec(char *cmd, char *output);
18+
int liberate_l();
19+
bool fsearch(FILE *f, char *target);
20+
int kernel_version();
2021

2122
static inline int simple_exec(char *cmd)
2223
{
@@ -28,6 +29,17 @@ static inline bool file_exist(char *path)
2829
return access(path, F_OK) == 0;
2930
}
3031

32+
static inline int kv_to_num(int major, int minor, int patch)
33+
{
34+
return (major << 16) + (minor << 8) + patch;
35+
}
36+
37+
/* compare current kernel version with the provided one */
38+
static inline int kv_compare(int major, int minor, int patch)
39+
{
40+
return kernel_version() - kv_to_num(major, minor, patch);
41+
}
42+
3143
#define pr_level(level, target, fmt, args...) \
3244
do { \
3345
if (level <= log_level) \

shared/bpf/skb_utils.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,19 @@ struct {
3434
bpf_probe_read_kernel(&tmp, sizeof(src), &(src)); \
3535
tmp; \
3636
})
37+
3738
#undef _C
3839
#ifdef COMPAT_MODE
3940
#define _C(src, a) _(src->a)
41+
#define _CF(src, a) _(src->a)
42+
#else
43+
#define _C(src, a, ...) BPF_CORE_READ(src, a, ##__VA_ARGS__)
44+
#endif
45+
46+
#ifdef CORE_FULL
47+
#define _CT(src, a, ...) BPF_CORE_READ(src, a, ##__VA_ARGS__)
4048
#else
41-
#define _C(src, a, ...) BPF_CORE_READ(src, a, ##__VA_ARGS__)
49+
#define _CT(src, a, ...) _(src->a)
4250
#endif
4351

4452
#ifdef COMPAT_MODE

src/Makefile

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
ROOT ?= $(abspath ../)
2-
bpf_progs := progs/kprobe progs/tracing
2+
bpf_progs := progs/tracing
3+
bpf_progs_ext := progs/kprobe
34
progs := nettrace
45
prog-nettrace-origin = \
56
trace.c $(COMMON_SHARED) trace_probe.c trace_tracing.c \
@@ -19,6 +20,7 @@ COMPAT ?= $(if $(KERNEL),$(shell cat $(HEADERS)/Makefile | grep \
1920

2021
ifneq ($(strip $(COMPAT)),)
2122
CFLAGS += -DCOMPAT_MODE
23+
COMPAT_MODE := 1
2224
endif
2325

2426
NFT_HEADER := $(HEADERS)/include/net/netfilter/nf_tables.h
@@ -34,6 +36,21 @@ trace_group.c: trace.yaml
3436

3537
progs/kprobe.c: progs/kprobe_trace.h
3638

39+
kprobe_gen_cmd = @make BPF_CFLAGS="$(BPF_CFLAGS) $(1)" \
40+
SKEL_FLAGS="name $(2)" \
41+
progs/kprobe.skel.h; \
42+
mv progs/kprobe.skel.h progs/$(2).skel.h
43+
44+
ifndef COMPAT_MODE
45+
$(bpf_progs_ext):
46+
rm -rf progs/kprobe*.skel.h
47+
$(call kprobe_gen_cmd,-DCORE_FULL,kprobe_core)
48+
make progs/kprobe.skel.h
49+
else
50+
$(bpf_progs_ext): %: %.skel.h
51+
@:
52+
endif
53+
3754
nettrace.c: $(prog-nettrace-origin)
3855

3956
all: $(progs)

src/progs/kprobe.c

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -244,10 +244,10 @@ DEFINE_KPROBE(ipt_do_table, 1)
244244
struct xt_table *table = (void *)PT_REGS_PARM3(ctx);
245245
nf_event_t e = {
246246
.event = { .func = func, },
247-
.hook = _(state->hook),
247+
.hook = _C(state, hook),
248248
};
249249

250-
bpf_probe_read(e.table, sizeof(e.table) - 1, table->name);
250+
bpf_probe_read(e.table, sizeof(e.table) - 1, _C(table, name));
251251
return handle_entry(ctx, skb, &e.event, sizeof(e), func);
252252
}
253253

@@ -265,8 +265,8 @@ DEFINE_KPROBE(nf_hook_slow, 1)
265265
if (handle_entry(ctx, skb, &e.event, 0, func))
266266
return 0;
267267

268-
e.hook = _(state->hook);
269-
e.pf = _(state->pf);
268+
e.hook = _C(state, hook);
269+
e.pf = _C(state, pf);
270270
EVENT_OUTPUT(ctx, e);
271271
return 0;
272272

@@ -277,8 +277,8 @@ on_hooks:;
277277
if (handle_entry(ctx, skb, &hooks_event.event, 0, func))
278278
return 0;
279279

280-
hooks_event.hook = _(state->hook);
281-
hooks_event.pf = _(state->pf);
280+
hooks_event.hook = _C(state, hook);
281+
hooks_event.pf = _C(state, pf);
282282
num = _(entries->num_hook_entries);
283283

284284
#define COPY_HOOK(i) do { \
@@ -318,18 +318,20 @@ DEFINE_KPROBE_RAW(nft_do_chain, NULL)
318318
if (handle_entry(ctx, skb, &e.event, 0, func))
319319
return 0;
320320

321-
#ifndef NFT_HIGH_VERSION
322-
state = _(pkt->xt.state);
323-
#else
324-
state = _(pkt->state);
325-
#endif
326-
chain = (void *)PT_REGS_PARM2(ctx);
327-
table = _(chain->table);
328-
e.hook = _(state->hook);
329-
e.pf = _(state->pf);
321+
if (ARGS_GET_CONFIG(nft_high))
322+
state = _(((struct _nft_pktinfo_new *)pkt)->state);
323+
else
324+
state = _(((struct _nft_pktinfo *)pkt)->xt.state);
325+
326+
chain = (void *)PT_REGS_PARM2(ctx);
327+
table = _CT(chain, table);
328+
e.hook = _C(state, hook);
329+
e.pf = _C(state, pf);
330330

331-
bpf_probe_read_kernel_str(e.chain, sizeof(e.chain), _(chain->name));
332-
bpf_probe_read_kernel_str(e.table, sizeof(e.table), _(table->name));
331+
bpf_probe_read_kernel_str(e.chain, sizeof(e.chain),
332+
_CT(chain, name));
333+
bpf_probe_read_kernel_str(e.table, sizeof(e.table),
334+
_CT(table, name));
333335

334336
EVENT_OUTPUT(ctx, e);
335337
return 0;

src/progs/shared.h

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
bool drop_reason; \
1010
bool detail; \
1111
bool hooks; \
12-
bool ready;
12+
bool ready; \
13+
bool nft_high;
1314

1415
#include <skb_shared.h>
1516

@@ -81,4 +82,22 @@ typedef enum trace_mode {
8182
#define TRACE_MODE_INETL_MASK (1 << TRACE_MODE_INETL)
8283
#define TRACE_MODE_DROP_MASK (1 << TRACE_MODE_DROP)
8384

85+
struct _xt_action_param {
86+
void *arg1;
87+
void *arg2;
88+
void *state;
89+
};
90+
91+
struct _nft_pktinfo {
92+
void *skb;
93+
bool tprot_set;
94+
u8 tprot;
95+
struct _xt_action_param xt;
96+
};
97+
98+
struct _nft_pktinfo_new {
99+
void *skb;
100+
void *state;
101+
};
102+
84103
#endif

src/trace.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -245,11 +245,9 @@ static int trace_prepare_args()
245245
break;
246246
case TRACE_MODE_BASIC:
247247
case TRACE_MODE_DROP:
248-
if (!trace_ctx.drop_reason) {
249-
pr_err("skb drop reason is not support by your kernel"
250-
", please upgrade your kernel to 5.18+\n");
251-
goto err;
252-
}
248+
if (!trace_ctx.drop_reason)
249+
pr_warn("skb drop reason is not support by your kernel"
250+
", drop reason will not be printed\n");
253251
break;
254252
default:
255253
goto err;
@@ -273,6 +271,9 @@ static int trace_prepare_args()
273271

274272
trace_ctx.bpf_args.trace_mode = 1 << trace_ctx.mode;
275273
trace_ctx.detail = trace_ctx.bpf_args.detail;
274+
/* from v5.14, the struct of nft_pktinfo changed */
275+
trace_ctx.bpf_args.nft_high = kv_compare(5, 14, 0) >= 0;
276+
pr_debug("nft high version: %d\n", trace_ctx.bpf_args.nft_high);
276277

277278
return 0;
278279
err:

src/trace_probe.c

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
#include "trace.h"
22
#include "progs/kprobe.skel.h"
3+
#ifndef COMPAT_MODE
4+
#include "progs/kprobe_core.skel.h"
5+
#endif
36
#include "analysis.h"
47
#include "nettrace.h"
58
#include "analysis.h"
@@ -94,22 +97,26 @@ static int probe_trace_load(trace_t *trace)
9497
return -1;
9598
}
9699

100+
#define LOAD_SKEL(name) \
101+
skel = (void *) name##__open(); \
102+
if (skel && !name##__load((void *)skel)) \
103+
goto load_success; \
104+
pr_debug("failed to load skel: " #name "\n")
105+
97106
static struct kprobe *skel;
98107
static int probe_trace_open()
99108
{
100109
int i = 0;
101110

102-
skel = kprobe__open();
103-
if (!skel) {
104-
pr_err("failed to open kprobe-based eBPF\n");
105-
goto err;
106-
}
111+
#ifndef COMPAT_MODE
112+
LOAD_SKEL(kprobe_core);
113+
#endif
114+
LOAD_SKEL(kprobe);
107115

108-
if (kprobe__load(skel)) {
109-
pr_err("failed to load kprobe-based eBPF\n");
110-
goto err;
111-
}
116+
pr_err("failed to load kprobe-based eBPF\n");
117+
goto err;
112118

119+
load_success:
113120
bpf_set_config(skel, bss, trace_ctx.bpf_args);
114121
trace_ctx.obj = skel->obj;
115122

0 commit comments

Comments
 (0)