Skip to content

Commit 42eb2ca

Browse files
authored
Merge pull request #3 from Hevienz/main
add xdp support
2 parents 298b1b7 + 4fd20c7 commit 42eb2ca

File tree

8 files changed

+118
-1
lines changed

8 files changed

+118
-1
lines changed

CHANGES.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
## v0.1.1 (2024-07-05)
22
- Improve documentation
3+
- Add XDP support (@Hevienz)
4+
- `bpf_xdp_attach`
5+
- `bpf_xdp_detach`
36

47
## v0.1.0 (2024-07-01)
58
- Initial release.

examples/Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ minimal: build
99
kprobe: build
1010
sudo $(CWD)/kprobe.exe
1111

12+
xdp_counter: build
13+
sudo $(CWD)/xdp_counter.exe
14+
1215
tc: build
1316
sudo $(CWD)/tc.exe
1417

examples/dune

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
(executables
2-
(names tc bootstrap bootstrap_c kprobe minimal)
2+
(names tc bootstrap bootstrap_c kprobe minimal xdp_counter)
33
(libraries libbpf libbpf_maps))
44

55
; Below is repetitive build rules to compile *.bpf.c eBPF C source code that runs in the kernel
@@ -22,6 +22,15 @@
2222
(system
2323
"clang -g -O2 -target bpf -I/usr/include/%{architecture}-linux-gnu/ -c kprobe.bpf.c -D__TARGET_ARCH_%{read:arch}")))
2424

25+
(rule
26+
(mode
27+
(promote (until-clean)))
28+
(targets xdp_counter.bpf.o)
29+
(deps arch xdp_counter.bpf.c)
30+
(action
31+
(system
32+
"clang -g -O2 -target bpf -I/usr/include/%{architecture}-linux-gnu/ -c xdp_counter.bpf.c -D__TARGET_ARCH_%{read:arch}")))
33+
2534
(rule
2635
(mode
2736
(promote (until-clean)))

examples/xdp_counter.bpf.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2+
#include <linux/bpf.h>
3+
#include <bpf/bpf_helpers.h>
4+
5+
struct {
6+
__uint(type, BPF_MAP_TYPE_ARRAY);
7+
__uint(max_entries, 1);
8+
__type(key, int);
9+
__type(value, unsigned long);
10+
} packet_count SEC(".maps");
11+
12+
SEC("xdp")
13+
int count_packets(struct xdp_md *ctx) {
14+
int key = 0;
15+
unsigned long *value;
16+
17+
value = bpf_map_lookup_elem(&packet_count, &key);
18+
if (value)
19+
__sync_fetch_and_add(value, 1);
20+
21+
return XDP_PASS;
22+
}
23+
24+
char _license[] SEC("license") = "GPL";

examples/xdp_counter.ml

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
open Libbpf
2+
3+
let obj_path = "xdp_counter.bpf.o"
4+
let program_name = "count_packets"
5+
let map = "packet_count"
6+
let ifindex = 1 (* Usually localhost *)
7+
8+
let load_and_attach_xdp ifindex =
9+
(* Load the compiled eBPF object *)
10+
let obj = bpf_object_open obj_path in
11+
let _ = bpf_object_load obj in
12+
let program = bpf_object_find_program_by_name obj program_name in
13+
let fd = bpf_program_fd program in
14+
15+
let opts = Ctypes.from_voidp C.Types.Bpf_xdp.Attach_opts.t Ctypes.null in
16+
17+
(match C.Functions.bpf_xdp_attach ifindex fd Unsigned.UInt32.zero opts with
18+
| 0 -> ()
19+
| _ ->
20+
bpf_object_close obj;
21+
failwith "Failed to attach xdp program");
22+
23+
(obj, opts)
24+
25+
let teardown_xdp (obj, link) =
26+
let _ = C.Functions.bpf_xdp_detach 0 Unsigned.UInt32.zero link in
27+
bpf_object_close obj
28+
29+
let () =
30+
let obj, link = load_and_attach_xdp ifindex in
31+
(* Initialize bpf_map with value, if not the lookup will fail *)
32+
let counter = bpf_object_find_map_by_name obj map in
33+
34+
let exitting = ref false in
35+
let sig_handler = Sys.Signal_handle (fun _ -> exitting := true) in
36+
Sys.(set_signal sigint sig_handler);
37+
Sys.(set_signal sigterm sig_handler);
38+
39+
let rec loop () =
40+
if !exitting then ()
41+
else (
42+
Unix.sleep 1;
43+
let count =
44+
bpf_map_lookup_value ~key_ty:Ctypes.int ~val_ty:Ctypes.ulong
45+
~val_zero:Unsigned.ULong.zero counter 0
46+
in
47+
Printf.printf "Packet count %d\n%!" (Unsigned.ULong.to_int count);
48+
49+
loop ())
50+
in
51+
loop ();
52+
53+
teardown_xdp (obj, link)

src/bindings/c_function_description.ml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,17 @@ module Functions (F : Ctypes.FOREIGN) = struct
223223
foreign "bpf_map__delete_elem"
224224
(ptr Types.bpf_map @-> ptr void @-> size_t @-> uint64_t @-> returning int)
225225

226+
(* ================================== Xdp ================================== *)
227+
let bpf_xdp_attach =
228+
foreign "bpf_xdp_attach"
229+
(int @-> int @-> uint32_t
230+
@-> ptr Types.Bpf_xdp.Attach_opts.t
231+
@-> returning int)
232+
233+
let bpf_xdp_detach =
234+
foreign "bpf_xdp_detach"
235+
(int @-> uint32_t @-> ptr Types.Bpf_xdp.Attach_opts.t @-> returning int)
236+
226237
(* ================================== Traffic control ================================== *)
227238

228239
let bpf_tc_hook_create =

src/bindings/c_type_description.ml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,16 @@ module Types (F : Ctypes.TYPE) = struct
376376
let ring_buffer_opts : [ `Ring_buffer_opts ] structure typ =
377377
structure "ring_buffer_opts"
378378

379+
module Bpf_xdp = struct
380+
module Attach_opts = struct
381+
let t : [ `Attach_opts ] structure typ = structure "bpf_xdp_attach_opts"
382+
let ( -: ) ty label = field t label ty
383+
let sz = size_t -: "sz"
384+
let old_prog_fd = int -: "old_prog_fd"
385+
let () = seal t
386+
end
387+
end
388+
379389
module Bpf_tc = struct
380390
let attach_point : [ `INGRESS | `EGRESS | `CUSTOM ] typ =
381391
let def = c ~prefix:"BPF_TC_" in

supported.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
{
2+
"ocaml_libbpf.1.1": [
3+
"bpf_xdp_attach",
4+
"bpf_xdp_detach"
5+
],
26
"ocaml_libbpf.1.0": [
37
"libbpf_major_version",
48
"libbpf_minor_version",

0 commit comments

Comments
 (0)