1 // SPDX-License-Identifier: GPL-2.0
2 #include <test_progs.h>
14 .cb32
[0] = 0x81828384,
17 static void on_sample(void *ctx
, int cpu
, void *data
, __u32 size
)
19 struct meta
*meta
= (struct meta
*)data
;
20 struct ipv6_packet
*pkt_v6
= data
+ sizeof(*meta
);
23 if (CHECK(size
!= 72 + sizeof(*meta
), "check_size", "size %u != %zu\n",
24 size
, 72 + sizeof(*meta
)))
26 if (CHECK(meta
->ifindex
!= 1, "check_meta_ifindex",
27 "meta->ifindex = %d\n", meta
->ifindex
))
28 /* spurious kfree_skb not on loopback device */
30 if (CHECK(meta
->cb8_0
!= cb
.cb8
[0], "check_cb8_0", "cb8_0 %x != %x\n",
31 meta
->cb8_0
, cb
.cb8
[0]))
33 if (CHECK(meta
->cb32_0
!= cb
.cb32
[0], "check_cb32_0",
35 meta
->cb32_0
, cb
.cb32
[0]))
37 if (CHECK(pkt_v6
->eth
.h_proto
!= 0xdd86, "check_eth",
38 "h_proto %x\n", pkt_v6
->eth
.h_proto
))
40 if (CHECK(pkt_v6
->iph
.nexthdr
!= 6, "check_ip",
41 "iph.nexthdr %x\n", pkt_v6
->iph
.nexthdr
))
43 if (CHECK(pkt_v6
->tcp
.doff
!= 5, "check_tcp",
44 "tcp.doff %x\n", pkt_v6
->tcp
.doff
))
50 void test_kfree_skb(void)
52 struct __sk_buff skb
= {};
53 struct bpf_prog_test_run_attr tattr
= {
55 .data_size_in
= sizeof(pkt_v6
),
57 .ctx_size_in
= sizeof(skb
),
59 struct bpf_prog_load_attr attr
= {
60 .file
= "./kfree_skb.o",
63 struct bpf_link
*link
= NULL
, *link_fentry
= NULL
, *link_fexit
= NULL
;
64 struct bpf_map
*perf_buf_map
, *global_data
;
65 struct bpf_program
*prog
, *fentry
, *fexit
;
66 struct bpf_object
*obj
, *obj2
= NULL
;
67 struct perf_buffer_opts pb_opts
= {};
68 struct perf_buffer
*pb
= NULL
;
69 int err
, kfree_skb_fd
;
75 err
= bpf_prog_load("./test_pkt_access.o", BPF_PROG_TYPE_SCHED_CLS
,
76 &obj
, &tattr
.prog_fd
);
77 if (CHECK(err
, "prog_load sched cls", "err %d errno %d\n", err
, errno
))
80 err
= bpf_prog_load_xattr(&attr
, &obj2
, &kfree_skb_fd
);
81 if (CHECK(err
, "prog_load raw tp", "err %d errno %d\n", err
, errno
))
84 prog
= bpf_object__find_program_by_title(obj2
, "tp_btf/kfree_skb");
85 if (CHECK(!prog
, "find_prog", "prog kfree_skb not found\n"))
87 fentry
= bpf_object__find_program_by_title(obj2
, "fentry/eth_type_trans");
88 if (CHECK(!fentry
, "find_prog", "prog eth_type_trans not found\n"))
90 fexit
= bpf_object__find_program_by_title(obj2
, "fexit/eth_type_trans");
91 if (CHECK(!fexit
, "find_prog", "prog eth_type_trans not found\n"))
94 global_data
= bpf_object__find_map_by_name(obj2
, "kfree_sk.bss");
95 if (CHECK(!global_data
, "find global data", "not found\n"))
98 link
= bpf_program__attach_raw_tracepoint(prog
, NULL
);
99 if (CHECK(IS_ERR(link
), "attach_raw_tp", "err %ld\n", PTR_ERR(link
)))
101 link_fentry
= bpf_program__attach_trace(fentry
);
102 if (CHECK(IS_ERR(link_fentry
), "attach fentry", "err %ld\n",
103 PTR_ERR(link_fentry
)))
105 link_fexit
= bpf_program__attach_trace(fexit
);
106 if (CHECK(IS_ERR(link_fexit
), "attach fexit", "err %ld\n",
107 PTR_ERR(link_fexit
)))
110 perf_buf_map
= bpf_object__find_map_by_name(obj2
, "perf_buf_map");
111 if (CHECK(!perf_buf_map
, "find_perf_buf_map", "not found\n"))
114 /* set up perf buffer */
115 pb_opts
.sample_cb
= on_sample
;
116 pb_opts
.ctx
= &passed
;
117 pb
= perf_buffer__new(bpf_map__fd(perf_buf_map
), 1, &pb_opts
);
118 if (CHECK(IS_ERR(pb
), "perf_buf__new", "err %ld\n", PTR_ERR(pb
)))
121 memcpy(skb
.cb
, &cb
, sizeof(cb
));
122 err
= bpf_prog_test_run_xattr(&tattr
);
123 duration
= tattr
.duration
;
124 CHECK(err
|| tattr
.retval
, "ipv6",
125 "err %d errno %d retval %d duration %d\n",
126 err
, errno
, tattr
.retval
, duration
);
128 /* read perf buffer */
129 err
= perf_buffer__poll(pb
, 100);
130 if (CHECK(err
< 0, "perf_buffer__poll", "err %d\n", err
))
133 /* make sure kfree_skb program was triggered
134 * and it sent expected skb into ring buffer
138 err
= bpf_map_lookup_elem(bpf_map__fd(global_data
), &zero
, test_ok
);
139 if (CHECK(err
, "get_result",
140 "failed to get output data: %d\n", err
))
143 CHECK_FAIL(!test_ok
[0] || !test_ok
[1]);
145 perf_buffer__free(pb
);
146 if (!IS_ERR_OR_NULL(link
))
147 bpf_link__destroy(link
);
148 if (!IS_ERR_OR_NULL(link_fentry
))
149 bpf_link__destroy(link_fentry
);
150 if (!IS_ERR_OR_NULL(link_fexit
))
151 bpf_link__destroy(link_fexit
);
152 bpf_object__close(obj
);
153 bpf_object__close(obj2
);