|
| 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) |
0 commit comments