ebpf: Change error types to `c_long`

All helper functions and context methods are returning `c_long` as an
error. Before this change, aya-template and book examples were adjusting
the error type in `try_*` functionns return type of the program. For
example, for XDP programs programs, which return `u32`, the type
returned by `try_*` functions, was `Result<u32, u32>`.

This approach is forcing people to write boilerplate code for casting
errors from `c_long` to the expected type, like:

```rust
MY_MAP.insert(k, v, 0).map_err(|_| 1u32)?;
```

This change solves that problem by:

* Using `Result<i32, c_long>` as a type for `try_*` functions for
  SKB-based programs and then replacing errors with `TC_ACT_SHOT` or
  `0` once in the main program function.
* Using `Result<u32, c_long>` as a type for `try_*` functions in `try_*`
  funnctions for XDP programs and then replacing errors with `XDP_ABORT`.
* Using either `Result<u32, c_long>` or `Result<i32, c_long>` as types
  in `try_*` functions for all other program types where the return value
  matters (LSM, sysctl etc.) and replacing the error either with `0` or
  `1` (depending on which number means "block the action" for particular
  type of program).
* Using `Result<(), c_long` for all other program types where the
  return value doesn't matter (kprobe, uprobe etc.).

So errors can be handled without casting, like:

```rust
MY_MAP.insert(k, v, 0)?;
```

The other change is fixing return values of cgroup_skb, sockopt and
sysctl programs (1 means "allow", 0 means "deny").

Signed-off-by: Michal Rostecki <vadorovsky@gmail.com>
pull/84/head
Michal Rostecki 2 years ago committed by Michal Rostecki
parent 4ce0e28314
commit f4b3a8cea0

@ -1,116 +1,112 @@
#![no_std] #![no_std]
#![no_main] #![no_main]
{% case program_type -%} {% case program_type -%}
{%- when "kprobe" %} {%- when "kprobe" %}
use aya_bpf::{macros::kprobe, programs::ProbeContext}; use aya_bpf::{
cty::c_long,
macros::kprobe,
programs::ProbeContext,
};
use aya_log_ebpf::info; use aya_log_ebpf::info;
#[kprobe(name = "{{crate_name}}")] #[kprobe(name = "{{crate_name}}")]
pub fn {{crate_name}}(ctx: ProbeContext) -> u32 { pub fn {{crate_name}}(ctx: ProbeContext) {
match try_{{crate_name}}(ctx) { let _ = try_{{crate_name}}(ctx);
Ok(ret) => ret,
Err(ret) => ret,
}
} }
fn try_{{crate_name}}(ctx: ProbeContext) -> Result<u32, u32> { fn try_{{crate_name}}(ctx: ProbeContext) -> Result<(), c_long> {
info!(&ctx, "function {{kprobe}} called"); info!(&ctx, "function {{kprobe}} called");
Ok(0) Ok(())
} }
{%- when "kretprobe" %} {%- when "kretprobe" %}
use aya_bpf::{macros::kretprobe, programs::ProbeContext}; use aya_bpf::{
cty::c_long,
macros::kretprobe,
programs::ProbeContext,
};
use aya_log_ebpf::info; use aya_log_ebpf::info;
#[kretprobe(name = "{{crate_name}}")] #[kretprobe(name = "{{crate_name}}")]
pub fn {{crate_name}}(ctx: ProbeContext) -> u32 { pub fn {{crate_name}}(ctx: ProbeContext) {
match try_{{crate_name}}(ctx) { let _ = try_{{crate_name}}(ctx);
Ok(ret) => ret,
Err(ret) => ret,
}
} }
fn try_{{crate_name}}(ctx: ProbeContext) -> Result<u32, u32> { fn try_{{crate_name}}(ctx: ProbeContext) -> Result<(), c_long> {
info!(&ctx, "function {{kprobe}} called"); info!(&ctx, "function {{kprobe}} called");
Ok(0) Ok(())
} }
{%- when "fentry" %} {%- when "fentry" %}
use aya_bpf::{ use aya_bpf::{
cty::c_long,
macros::fentry, macros::fentry,
programs::FEntryContext, programs::FEntryContext,
}; };
use aya_log_ebpf::info; use aya_log_ebpf::info;
#[fentry(name="{{crate_name}}")] #[fentry(name="{{crate_name}}")]
pub fn {{crate_name}}(ctx: FEntryContext) -> u32 { pub fn {{crate_name}}(ctx: FEntryContext) {
match try_{{crate_name}}(ctx) { let _ = try_{{crate_name}}(ctx);
Ok(ret) => ret,
Err(ret) => ret,
}
} }
fn try_{{crate_name}}(ctx: FEntryContext) -> Result<u32, u32> { fn try_{{crate_name}}(ctx: FEntryContext) -> Result<(), c_long> {
info!(&ctx, "function {{fn_name}} called"); info!(&ctx, "function {{fn_name}} called");
Ok(0) Ok(())
} }
{%- when "fexit" %} {%- when "fexit" %}
use aya_bpf::{ use aya_bpf::{
cty::c_long,
macros::fexit, macros::fexit,
programs::FExitContext, programs::FExitContext,
}; };
use aya_log_ebpf::info; use aya_log_ebpf::info;
#[fexit(name="{{crate_name}}")] #[fexit(name="{{crate_name}}")]
pub fn {{crate_name}}(ctx: FExitContext) -> u32 { pub fn {{crate_name}}(ctx: FExitContext) {
match try_{{crate_name}}(ctx) { let _ = try_{{crate_name}}(ctx);
Ok(ret) => ret,
Err(ret) => ret,
}
} }
fn try_{{crate_name}}(ctx: FExitContext) -> Result<u32, u32> { fn try_{{crate_name}}(ctx: FExitContext) -> Result<(), c_long> {
info!(&ctx, "function {{fn_name}} called"); info!(&ctx, "function {{fn_name}} called");
Ok(0) Ok(())
} }
{%- when "uprobe" %} {%- when "uprobe" %}
use aya_bpf::{ use aya_bpf::{
cty::c_long,
macros::uprobe, macros::uprobe,
programs::ProbeContext, programs::ProbeContext,
}; };
use aya_log_ebpf::info; use aya_log_ebpf::info;
#[uprobe(name="{{crate_name}}")] #[uprobe(name="{{crate_name}}")]
pub fn {{crate_name}}(ctx: ProbeContext) -> u32 { pub fn {{crate_name}}(ctx: ProbeContext) {
match try_{{crate_name}}(ctx) { let _ = try_{{crate_name}}(ctx);
Ok(ret) => ret,
Err(ret) => ret,
}
} }
fn try_{{crate_name}}(ctx: ProbeContext) -> Result<u32, u32> { fn try_{{crate_name}}(ctx: ProbeContext) -> Result<(), c_long> {
info!(&ctx, "function {{uprobe_fn_name}} called by {{uprobe_target}}"); info!(&ctx, "function {{uprobe_fn_name}} called by {{uprobe_target}}");
Ok(0) Ok(())
} }
{%- when "uretprobe" %} {%- when "uretprobe" %}
use aya_bpf::{ use aya_bpf::{
cty::c_long,
macros::uretprobe, macros::uretprobe,
programs::ProbeContext, programs::ProbeContext,
}; };
use aya_log_ebpf::info; use aya_log_ebpf::info;
#[uretprobe(name="{{crate_name}}")] #[uretprobe(name="{{crate_name}}")]
pub fn {{crate_name}}(ctx: ProbeContext) -> u32 { pub fn {{crate_name}}(ctx: ProbeContext) {
match try_{{crate_name}}(ctx) { let _ = try_{{crate_name}}(ctx);
Ok(ret) => ret,
Err(ret) => ret,
}
} }
fn try_{{crate_name}}(ctx: ProbeContext) -> Result<u32, u32> { fn try_{{crate_name}}(ctx: ProbeContext) -> Result<(), c_long> {
info!(&ctx, "function {{uprobe_fn_name}} called by {{uprobe_target}}"); info!(&ctx, "function {{uprobe_fn_name}} called by {{uprobe_target}}");
Ok(0) Ok(())
} }
{%- when "sock_ops" %} {%- when "sock_ops" %}
use aya_bpf::{ use aya_bpf::{
cty::c_long,
macros::sock_ops, macros::sock_ops,
programs::SockOpsContext, programs::SockOpsContext,
}; };
@ -120,16 +116,17 @@ use aya_log_ebpf::info;
pub fn {{crate_name}}(ctx: SockOpsContext) -> u32 { pub fn {{crate_name}}(ctx: SockOpsContext) -> u32 {
match try_{{crate_name}}(ctx) { match try_{{crate_name}}(ctx) {
Ok(ret) => ret, Ok(ret) => ret,
Err(ret) => ret, Err(_) => 1,
} }
} }
fn try_{{crate_name}}(ctx: SockOpsContext) -> Result<u32, u32> { fn try_{{crate_name}}(ctx: SockOpsContext) -> Result<u32, c_long> {
info!(&ctx, "received TCP connection"); info!(&ctx, "received TCP connection");
Ok(0) Ok(0)
} }
{%- when "sk_msg" %} {%- when "sk_msg" %}
use aya_bpf::{ use aya_bpf::{
cty::c_long,
macros::{map, sk_msg}, macros::{map, sk_msg},
maps::SockHash, maps::SockHash,
programs::SkMsgContext, programs::SkMsgContext,
@ -145,16 +142,21 @@ static {{sock_map}}: SockHash<SockKey> = SockHash::<SockKey>::with_max_entries(1
pub fn {{crate_name}}(ctx: SkMsgContext) -> u32 { pub fn {{crate_name}}(ctx: SkMsgContext) -> u32 {
match try_{{crate_name}}(ctx) { match try_{{crate_name}}(ctx) {
Ok(ret) => ret, Ok(ret) => ret,
Err(ret) => ret, Err(_) => 1,
} }
} }
fn try_{{crate_name}}(ctx: SkMsgContext) -> Result<u32, u32> { fn try_{{crate_name}}(ctx: SkMsgContext) -> Result<u32, c_long> {
info!(&ctx, "received a message on the socket"); info!(&ctx, "received a message on the socket");
Ok(0) Ok(0)
} }
{%- when "xdp" %} {%- when "xdp" %}
use aya_bpf::{bindings::xdp_action, macros::xdp, programs::XdpContext}; use aya_bpf::{
bindings::xdp_action,
cty::c_long,
macros::xdp,
programs::XdpContext,
};
use aya_log_ebpf::info; use aya_log_ebpf::info;
#[xdp(name = "{{crate_name}}")] #[xdp(name = "{{crate_name}}")]
@ -165,28 +167,34 @@ pub fn {{crate_name}}(ctx: XdpContext) -> u32 {
} }
} }
fn try_{{crate_name}}(ctx: XdpContext) -> Result<u32, u32> { fn try_{{crate_name}}(ctx: XdpContext) -> Result<u32, c_long> {
info!(&ctx, "received a packet"); info!(&ctx, "received a packet");
Ok(xdp_action::XDP_PASS) Ok(xdp_action::XDP_PASS)
} }
{%- when "classifier" %} {%- when "classifier" %}
use aya_bpf::{macros::classifier, programs::TcContext}; use aya_bpf::{
bindings::{TC_ACT_PIPE, TC_ACT_SHOT},
cty::c_long,
macros::classifier,
programs::TcContext,
};
use aya_log_ebpf::info; use aya_log_ebpf::info;
#[classifier(name = "{{crate_name}}")] #[classifier(name = "{{crate_name}}")]
pub fn {{crate_name}}(ctx: TcContext) -> i32 { pub fn {{crate_name}}(ctx: TcContext) -> i32 {
match try_{{crate_name}}(ctx) { match try_{{crate_name}}(ctx) {
Ok(ret) => ret, Ok(ret) => ret,
Err(ret) => ret, Err(_) => TC_ACT_SHOT,
} }
} }
fn try_{{crate_name}}(ctx: TcContext) -> Result<i32, i32> { fn try_{{crate_name}}(ctx: TcContext) -> Result<i32, c_long> {
info!(&ctx, "received a packet"); info!(&ctx, "received a packet");
Ok(0) Ok(TC_ACT_PIPE)
} }
{%- when "cgroup_skb" %} {%- when "cgroup_skb" %}
use aya_bpf::{ use aya_bpf::{
cty::c_long,
macros::cgroup_skb, macros::cgroup_skb,
programs::SkBuffContext, programs::SkBuffContext,
}; };
@ -196,35 +204,34 @@ use aya_log_ebpf::info;
pub fn {{crate_name}}(ctx: SkBuffContext) -> i32 { pub fn {{crate_name}}(ctx: SkBuffContext) -> i32 {
match try_{{crate_name}}(ctx) { match try_{{crate_name}}(ctx) {
Ok(ret) => ret, Ok(ret) => ret,
Err(ret) => ret, Err(_) => 0,
} }
} }
fn try_{{crate_name}}(ctx: SkBuffContext) -> Result<i32, i32> { fn try_{{crate_name}}(ctx: SkBuffContext) -> Result<i32, c_long> {
info!(&ctx, "received a packet"); info!(&ctx, "received a packet");
Ok(0) Ok(1)
} }
{%- when "tracepoint" %} {%- when "tracepoint" %}
use aya_bpf::{ use aya_bpf::{
cty::c_long,
macros::tracepoint, macros::tracepoint,
programs::TracePointContext, programs::TracePointContext,
}; };
use aya_log_ebpf::info; use aya_log_ebpf::info;
#[tracepoint(name = "{{crate_name}}")] #[tracepoint(name = "{{crate_name}}")]
pub fn {{crate_name}}(ctx: TracePointContext) -> u32 { pub fn {{crate_name}}(ctx: TracePointContext) {
match try_{{crate_name}}(ctx) { let _ = try_{{crate_name}}(ctx);
Ok(ret) => ret,
Err(ret) => ret,
}
} }
fn try_{{crate_name}}(ctx: TracePointContext) -> Result<u32, u32> { fn try_{{crate_name}}(ctx: TracePointContext) -> Result<(), c_long> {
info!(&ctx, "tracepoint {{tracepoint_name}} called"); info!(&ctx, "tracepoint {{tracepoint_name}} called");
Ok(0) Ok(())
} }
{%- when "lsm" %} {%- when "lsm" %}
use aya_bpf::{ use aya_bpf::{
cty::c_long,
macros::lsm, macros::lsm,
programs::LsmContext, programs::LsmContext,
}; };
@ -234,45 +241,52 @@ use aya_log_ebpf::info;
pub fn {{lsm_hook}}(ctx: LsmContext) -> i32 { pub fn {{lsm_hook}}(ctx: LsmContext) -> i32 {
match try_{{lsm_hook}}(ctx) { match try_{{lsm_hook}}(ctx) {
Ok(ret) => ret, Ok(ret) => ret,
Err(ret) => ret, Err(ret) => 1,
} }
} }
fn try_{{lsm_hook}}(ctx: LsmContext) -> Result<i32, i32> { fn try_{{lsm_hook}}(ctx: LsmContext) -> Result<i32, c_long> {
info!(&ctx, "lsm hook {{lsm_hook}} called"); info!(&ctx, "lsm hook {{lsm_hook}} called");
Ok(0) Ok(0)
} }
{%- when "tp_btf" %} {%- when "tp_btf" %}
use aya_bpf::{ use aya_bpf::{
cty::c_long,
macros::btf_tracepoint, macros::btf_tracepoint,
programs::BtfTracePointContext, programs::BtfTracePointContext,
}; };
use aya_log_ebpf::info; use aya_log_ebpf::info;
#[btf_tracepoint(name = "{{tracepoint_name}}")] #[btf_tracepoint(name = "{{tracepoint_name}}")]
pub fn {{tracepoint_name}}(ctx: BtfTracePointContext) -> i32 { pub fn {{tracepoint_name}}(ctx: BtfTracePointContext) {
match try_{{tracepoint_name}}(ctx) { let _ = try_{{tracepoint_name}}(ctx);
Ok(ret) => ret,
Err(ret) => ret,
}
} }
fn try_{{tracepoint_name}}(ctx: BtfTracePointContext) -> Result<i32, i32> { fn try_{{tracepoint_name}}(ctx: BtfTracePointContext) -> Result<(), c_long> {
info!(&ctx, "tracepoint {{tracepoint_name}} called"); info!(&ctx, "tracepoint {{tracepoint_name}} called");
Ok(0) Ok(())
} }
{%- when "socket_filter" %} {%- when "socket_filter" %}
use aya_bpf::{ use aya_bpf::{
cty::c_long,
macros::socket_filter, macros::socket_filter,
programs::SkBuffContext, programs::SkBuffContext,
}; };
#[socket_filter(name = "{{crate_name}}")] #[socket_filter(name = "{{crate_name}}")]
pub fn {{crate_name}}(_ctx: SkBuffContext) -> i64 { pub fn {{crate_name}}(ctx: SkBuffContext) -> i64 {
return 0 match try_{{crate_name}}(ctx) {
Ok(ret) => ret,
Err(_) => 0,
}
}
fn try_{{crate_name}}(ctx: SkBuffContext) -> Result<i64, c_long> {
Ok(0)
} }
{%- when "cgroup_sysctl" %} {%- when "cgroup_sysctl" %}
use aya_bpf::{ use aya_bpf::{
cty::c_long,
macros::cgroup_sysctl, macros::cgroup_sysctl,
programs::SysctlContext, programs::SysctlContext,
}; };
@ -282,61 +296,70 @@ use aya_log_ebpf::info;
pub fn {{crate_name}}(ctx: SysctlContext) -> i32 { pub fn {{crate_name}}(ctx: SysctlContext) -> i32 {
match try_{{crate_name}}(ctx) { match try_{{crate_name}}(ctx) {
Ok(ret) => ret, Ok(ret) => ret,
Err(ret) => ret, Err(_) => 0,
} }
} }
fn try_{{crate_name}}(ctx: SysctlContext) -> Result<i32, i32> { fn try_{{crate_name}}(ctx: SysctlContext) -> Result<i32, c_long> {
info!(&ctx, "sysctl operation called"); info!(&ctx, "sysctl operation called");
Ok(0) Ok(1)
} }
{%- when "cgroup_sockopt" %} {%- when "cgroup_sockopt" %}
use aya_bpf::{macros::cgroup_sockopt, programs::SockoptContext}; use aya_bpf::{
cty::c_long,
macros::cgroup_sockopt,
programs::SockoptContext,
};
use aya_log_ebpf::info; use aya_log_ebpf::info;
#[cgroup_sockopt({{sockopt_target}}, name = "{{crate_name}}")] #[cgroup_sockopt({{sockopt_target}}, name = "{{crate_name}}")]
pub fn {{crate_name}}(ctx: SockoptContext) -> i32 { pub fn {{crate_name}}(ctx: SockoptContext) -> i32 {
match try_{{crate_name}}(ctx) { match try_{{crate_name}}(ctx) {
Ok(ret) => ret, Ok(ret) => ret,
Err(ret) => ret, Err(_) => 0,
} }
} }
fn try_{{crate_name}}(ctx: SockoptContext) -> Result<i32, i32> { fn try_{{crate_name}}(ctx: SockoptContext) -> Result<i32, c_long> {
info!(&ctx, "{{sockopt_target}} called"); info!(&ctx, "{{sockopt_target}} called");
Ok(0) Ok(1)
} }
{%- when "raw_tracepoint" %} {%- when "raw_tracepoint" %}
use aya_bpf::{macros::raw_tracepoint, programs::RawTracePointContext}; use aya_bpf::{
cty::c_long,
macros::raw_tracepoint,
programs::RawTracePointContext,
};
use aya_log_ebpf::info; use aya_log_ebpf::info;
#[raw_tracepoint(name = "{{crate_name}}")] #[raw_tracepoint(name = "{{crate_name}}")]
pub fn {{crate_name}}(ctx: RawTracePointContext) -> i32 { pub fn {{crate_name}}(ctx: RawTracePointContext) {
match try_{{crate_name}}(ctx) { let _ = try_{{crate_name}}(ctx);
Ok(ret) => ret,
Err(ret) => ret,
}
} }
fn try_{{crate_name}}(ctx: RawTracePointContext) -> Result<i32, i32> { fn try_{{crate_name}}(ctx: RawTracePointContext) -> Result<(), c_long> {
info!(&ctx, "tracepoint {{tracepoint_name}} called"); info!(&ctx, "tracepoint {{tracepoint_name}} called");
Ok(0) Ok(())
} }
{%- when "perf_event" %} {%- when "perf_event" %}
use aya_bpf::{ use aya_bpf::{
helpers::bpf_get_smp_processor_id, macros::perf_event, programs::PerfEventContext, BpfContext, cty::c_long,
helpers::bpf_get_smp_processor_id,
macros::perf_event,
programs::PerfEventContext,
BpfContext,
}; };
use aya_log_ebpf::info; use aya_log_ebpf::info;
#[perf_event] #[perf_event]
pub fn {{crate_name}}(ctx: PerfEventContext) -> u32 { pub fn {{crate_name}}(ctx: PerfEventContext) -> u32 {
match try_{{crate_name}}(ctx) { match try_{{crate_name}}(ctx) {
Ok(ret) => ret, Ok(_) => 0,
Err(ret) => ret, Err(_) => 1,
} }
} }
fn try_{{crate_name}}(ctx: PerfEventContext) -> Result<u32, u32> { fn try_{{crate_name}}(ctx: PerfEventContext) -> Result<(), c_long> {
let cpu = unsafe { bpf_get_smp_processor_id() }; let cpu = unsafe { bpf_get_smp_processor_id() };
match ctx.pid() { match ctx.pid() {
0 => info!( 0 => info!(
@ -349,7 +372,7 @@ fn try_{{crate_name}}(ctx: PerfEventContext) -> Result<u32, u32> {
), ),
} }
Ok(0) Ok(())
} }
{%- endcase %} {%- endcase %}

Loading…
Cancel
Save