Rubita
Rubita is a transpiler that converts a restricted Ruby DSL into BCC-compatible C code for eBPF programs.
Overview
Rubita enables you to write eBPF probes and kernel tracing programs using a Ruby-like syntax, which are then transpiled into BCC (Berkeley Packet Filter Compiler Collection) compatible C code. This makes it easier to write complex eBPF programs while leveraging Ruby's expressiveness.
Supported Features
- Map Declarations: Define eBPF hash maps with
BPF_HASH - Probe Definitions: Support for
TRACEPOINT_PROBE,KFUNC_PROBE,KRETFUNC_PROBE, andLSM_PROBE - Method Definitions: Define helper functions with
def - Field Access: Convert Ruby dot notation (
obj.field) to C pointer dereference (obj->field) - String Literals: Support format strings with proper escaping
Installation
Add this line to your application's Gemfile:
gem 'rubita', github: 'udzura/rubita'
And then execute:
bundle install
Basic Conversion
Hash Map Declaration
Ruby DSL:
BPF_HASH :events, key: :u64, value: :u64, size: 1024
Generated C:
BPF_HASH(events, u64, u64, 1024);
Tracepoint Probe
Ruby DSL:
TRACEPOINT_PROBE :syscalls, :sys_enter_open do
bpf_trace_printk("open syscall\n")
0
end
Generated C:
TRACEPOINT_PROBE(syscalls, sys_enter_open) {
bpf_trace_printk("open syscall\n");
return 0;
}
Kernel Function Probe
Ruby DSL:
KFUNC_PROBE :vfs_read do
bpf_trace_printk("Reading file: %d\n", args.got_bits)
0
end
Generated C:
KFUNC_PROBE(vfs_read) {
bpf_trace_printk("Reading file: %d\n", args->got_bits);
return 0;
}
Helper Functions
Ruby DSL:
def print_event(_ctx)
bpf_trace_printk("Event occurred\n")
0
end
Generated C:
int print_event(void *_ctx) {
bpf_trace_printk("Event occurred\n");
return 0;
}
Usage
require 'rubita'
ruby_code = <<~RUBY
BPF_HASH :counts, key: :u64, value: :u64, size: 10
TRACEPOINT_PROBE :syscalls, :sys_enter_openat do
bpf_trace_printk("openat\n")
0
end
RUBY
c_code = Rubita.transpile(ruby_code)
puts c_code
Development
After checking out the repo, run bin/setup to install dependencies. Then, run rake test to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/udzura/rubita.