Welcome back to my series on ebpf. In the last post, I told you about BTF and generating Java classes for all BPF types. This week, we’re using these classes to write a simple packet blocker in pure Java. This is the culmination of my efforts that started in my post Hello eBPF: Generating C Code (8), to reduce the amount of C code that you have to write to create your eBPF application.
This blog post took again longer than expected, but you’ll soon see why. And I dropped libbcc support along the way.
After my last blog post, you still had to write the eBPF methods in a String embedded in the Java application. So if you wanted to write a simple XDP-based packet blocker that blocks every third incoming packet, you wrote the actual XDP logic into a String-typed field named EBPF_PROGRAM
. But we already can define the data types and global variables in Java, generating C code automatically. Can we do the same for the remaining C code? We can now. Introducing the new Java compiler plugin, that allows to you write the above in “pure” Java, using Java as a DSL for C (GitHub):
@BPF(license = "GPL") // define a license public abstract class XDPDropEveryThirdPacket extends BPFProgram implements XDPHook { // declare the global variable final GlobalVariable<@Unsigned Integer> count = new GlobalVariable<>(0); @BPFFunction public boolean shouldDrop() { return count.get() % 3 == 1; } @Override // defined in XDPHook, compiled to C public xdp_action xdpHandlePacket(Ptr<xdp_md> ctx) { // update count count.set(count.get() + 1); // drop based on count return shouldDrop() ? xdp_action.XDP_DROP : xdp_action.XDP_PASS; } public static void main(String[] args) throws InterruptedException { try (XDPDropEveryThirdPacket program = BPFProgram.load(XDPDropEveryThirdPacket.class)) { program.xdpAttach(XDPUtil.getNetworkInterfaceIndex()); while (true) { System.out.println("Packet count " + program.count.get()); Thread.sleep(1000); } } } }Continue reading