diff --git a/aya/include/linux_wrapper.h b/aya/include/linux_wrapper.h index ad38547c..58ffa680 100644 --- a/aya/include/linux_wrapper.h +++ b/aya/include/linux_wrapper.h @@ -4,8 +4,10 @@ #include #include #include +#include +#include /* workaround the fact that bindgen can't parse the IOC macros */ int AYA_PERF_EVENT_IOC_ENABLE = PERF_EVENT_IOC_ENABLE; int AYA_PERF_EVENT_IOC_DISABLE = PERF_EVENT_IOC_DISABLE; -int AYA_PERF_EVENT_IOC_SET_BPF = PERF_EVENT_IOC_SET_BPF; \ No newline at end of file +int AYA_PERF_EVENT_IOC_SET_BPF = PERF_EVENT_IOC_SET_BPF; diff --git a/aya/src/generated/linux_bindings_aarch64.rs b/aya/src/generated/linux_bindings_aarch64.rs index 85de3ac0..fa1d2f76 100644 --- a/aya/src/generated/linux_bindings_aarch64.rs +++ b/aya/src/generated/linux_bindings_aarch64.rs @@ -136,6 +136,16 @@ pub const XDP_FLAGS_MODES: u32 = 14; pub const XDP_FLAGS_MASK: u32 = 31; pub const SO_ATTACH_BPF: u32 = 50; pub const SO_DETACH_BPF: u32 = 27; +pub const TC_H_MAJ_MASK: u32 = 4294901760; +pub const TC_H_MIN_MASK: u32 = 65535; +pub const TC_H_UNSPEC: u32 = 0; +pub const TC_H_ROOT: u32 = 4294967295; +pub const TC_H_INGRESS: u32 = 4294967281; +pub const TC_H_CLSACT: u32 = 4294967281; +pub const TC_H_MIN_PRIORITY: u32 = 65504; +pub const TC_H_MIN_INGRESS: u32 = 65522; +pub const TC_H_MIN_EGRESS: u32 = 65523; +pub const TCA_BPF_FLAG_ACT_DIRECT: u32 = 1; pub type __u8 = ::std::os::raw::c_uchar; pub type __s16 = ::std::os::raw::c_short; pub type __u16 = ::std::os::raw::c_ushort; @@ -600,6 +610,68 @@ pub struct bpf_attr__bindgen_ty_19 { } #[repr(C)] #[derive(Debug, Copy, Clone)] +pub struct bpf_prog_info { + pub type_: __u32, + pub id: __u32, + pub tag: [__u8; 8usize], + pub jited_prog_len: __u32, + pub xlated_prog_len: __u32, + pub jited_prog_insns: __u64, + pub xlated_prog_insns: __u64, + pub load_time: __u64, + pub created_by_uid: __u32, + pub nr_map_ids: __u32, + pub map_ids: __u64, + pub name: [::std::os::raw::c_char; 16usize], + pub ifindex: __u32, + pub _bitfield_align_1: [u8; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub netns_dev: __u64, + pub netns_ino: __u64, + pub nr_jited_ksyms: __u32, + pub nr_jited_func_lens: __u32, + pub jited_ksyms: __u64, + pub jited_func_lens: __u64, + pub btf_id: __u32, + pub func_info_rec_size: __u32, + pub func_info: __u64, + pub nr_func_info: __u32, + pub nr_line_info: __u32, + pub line_info: __u64, + pub jited_line_info: __u64, + pub nr_jited_line_info: __u32, + pub line_info_rec_size: __u32, + pub jited_line_info_rec_size: __u32, + pub nr_prog_tags: __u32, + pub prog_tags: __u64, + pub run_time_ns: __u64, + pub run_cnt: __u64, + pub recursion_misses: __u64, +} +impl bpf_prog_info { + #[inline] + pub fn gpl_compatible(&self) -> __u32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_gpl_compatible(&mut self, val: __u32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1(gpl_compatible: __u32) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let gpl_compatible: u32 = unsafe { ::std::mem::transmute(gpl_compatible) }; + gpl_compatible as u64 + }); + __bindgen_bitfield_unit + } +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] pub struct btf_header { pub magic: __u16, pub version: __u8, @@ -689,7 +761,7 @@ pub enum perf_sw_ids { PERF_COUNT_SW_BPF_OUTPUT = 10, PERF_COUNT_SW_MAX = 11, } -#[repr(u64)] +#[repr(u32)] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub enum perf_event_sample_format { PERF_SAMPLE_IP = 1, @@ -713,7 +785,6 @@ pub enum perf_event_sample_format { PERF_SAMPLE_REGS_INTR = 262144, PERF_SAMPLE_PHYS_ADDR = 524288, PERF_SAMPLE_MAX = 1048576, - __PERF_SAMPLE_CALLCHAIN_EARLY = 9223372036854775808, } #[repr(C)] #[derive(Copy, Clone)] @@ -724,7 +795,7 @@ pub struct perf_event_attr { pub __bindgen_anon_1: perf_event_attr__bindgen_ty_1, pub sample_type: __u64, pub read_format: __u64, - pub _bitfield_align_1: [u32; 0], + pub _bitfield_align_1: [u64; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 8usize]>, pub __bindgen_anon_2: perf_event_attr__bindgen_ty_2, pub bp_type: __u32, @@ -757,8 +828,6 @@ pub union perf_event_attr__bindgen_ty_2 { #[derive(Copy, Clone)] pub union perf_event_attr__bindgen_ty_3 { pub bp_addr: __u64, - pub kprobe_func: __u64, - pub uprobe_path: __u64, pub config1: __u64, _bindgen_union_align: u64, } @@ -766,8 +835,6 @@ pub union perf_event_attr__bindgen_ty_3 { #[derive(Copy, Clone)] pub union perf_event_attr__bindgen_ty_4 { pub bp_len: __u64, - pub kprobe_addr: __u64, - pub probe_offset: __u64, pub config2: __u64, _bindgen_union_align: u64, } @@ -1081,47 +1148,14 @@ impl perf_event_attr { } } #[inline] - pub fn ksymbol(&self) -> __u64 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(29usize, 1u8) as u64) } - } - #[inline] - pub fn set_ksymbol(&mut self, val: __u64) { - unsafe { - let val: u64 = ::std::mem::transmute(val); - self._bitfield_1.set(29usize, 1u8, val as u64) - } - } - #[inline] - pub fn bpf_event(&self) -> __u64 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(30usize, 1u8) as u64) } - } - #[inline] - pub fn set_bpf_event(&mut self, val: __u64) { - unsafe { - let val: u64 = ::std::mem::transmute(val); - self._bitfield_1.set(30usize, 1u8, val as u64) - } - } - #[inline] - pub fn aux_output(&self) -> __u64 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(31usize, 1u8) as u64) } - } - #[inline] - pub fn set_aux_output(&mut self, val: __u64) { - unsafe { - let val: u64 = ::std::mem::transmute(val); - self._bitfield_1.set(31usize, 1u8, val as u64) - } - } - #[inline] pub fn __reserved_1(&self) -> __u64 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(32usize, 32u8) as u64) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(29usize, 35u8) as u64) } } #[inline] pub fn set___reserved_1(&mut self, val: __u64) { unsafe { let val: u64 = ::std::mem::transmute(val); - self._bitfield_1.set(32usize, 32u8, val as u64) + self._bitfield_1.set(29usize, 35u8, val as u64) } } #[inline] @@ -1154,9 +1188,6 @@ impl perf_event_attr { context_switch: __u64, write_backward: __u64, namespaces: __u64, - ksymbol: __u64, - bpf_event: __u64, - aux_output: __u64, __reserved_1: __u64, ) -> __BindgenBitfieldUnit<[u8; 8usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 8usize]> = Default::default(); @@ -1274,19 +1305,7 @@ impl perf_event_attr { let namespaces: u64 = unsafe { ::std::mem::transmute(namespaces) }; namespaces as u64 }); - __bindgen_bitfield_unit.set(29usize, 1u8, { - let ksymbol: u64 = unsafe { ::std::mem::transmute(ksymbol) }; - ksymbol as u64 - }); - __bindgen_bitfield_unit.set(30usize, 1u8, { - let bpf_event: u64 = unsafe { ::std::mem::transmute(bpf_event) }; - bpf_event as u64 - }); - __bindgen_bitfield_unit.set(31usize, 1u8, { - let aux_output: u64 = unsafe { ::std::mem::transmute(aux_output) }; - aux_output as u64 - }); - __bindgen_bitfield_unit.set(32usize, 32u8, { + __bindgen_bitfield_unit.set(29usize, 35u8, { let __reserved_1: u64 = unsafe { ::std::mem::transmute(__reserved_1) }; __reserved_1 as u64 }); @@ -1465,9 +1484,7 @@ pub enum perf_event_type { PERF_RECORD_SWITCH = 14, PERF_RECORD_SWITCH_CPU_WIDE = 15, PERF_RECORD_NAMESPACES = 16, - PERF_RECORD_KSYMBOL = 17, - PERF_RECORD_BPF_EVENT = 18, - PERF_RECORD_MAX = 19, + PERF_RECORD_MAX = 17, } pub const IFLA_XDP_UNSPEC: _bindgen_ty_79 = _bindgen_ty_79::IFLA_XDP_UNSPEC; pub const IFLA_XDP_FD: _bindgen_ty_79 = _bindgen_ty_79::IFLA_XDP_FD; @@ -1503,6 +1520,79 @@ pub struct ifinfomsg { pub ifi_flags: ::std::os::raw::c_uint, pub ifi_change: ::std::os::raw::c_uint, } +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct tcmsg { + pub tcm_family: ::std::os::raw::c_uchar, + pub tcm__pad1: ::std::os::raw::c_uchar, + pub tcm__pad2: ::std::os::raw::c_ushort, + pub tcm_ifindex: ::std::os::raw::c_int, + pub tcm_handle: __u32, + pub tcm_parent: __u32, + pub tcm_info: __u32, +} +pub const TCA_UNSPEC: _bindgen_ty_91 = _bindgen_ty_91::TCA_UNSPEC; +pub const TCA_KIND: _bindgen_ty_91 = _bindgen_ty_91::TCA_KIND; +pub const TCA_OPTIONS: _bindgen_ty_91 = _bindgen_ty_91::TCA_OPTIONS; +pub const TCA_STATS: _bindgen_ty_91 = _bindgen_ty_91::TCA_STATS; +pub const TCA_XSTATS: _bindgen_ty_91 = _bindgen_ty_91::TCA_XSTATS; +pub const TCA_RATE: _bindgen_ty_91 = _bindgen_ty_91::TCA_RATE; +pub const TCA_FCNT: _bindgen_ty_91 = _bindgen_ty_91::TCA_FCNT; +pub const TCA_STATS2: _bindgen_ty_91 = _bindgen_ty_91::TCA_STATS2; +pub const TCA_STAB: _bindgen_ty_91 = _bindgen_ty_91::TCA_STAB; +pub const TCA_PAD: _bindgen_ty_91 = _bindgen_ty_91::TCA_PAD; +pub const TCA_DUMP_INVISIBLE: _bindgen_ty_91 = _bindgen_ty_91::TCA_DUMP_INVISIBLE; +pub const TCA_CHAIN: _bindgen_ty_91 = _bindgen_ty_91::TCA_CHAIN; +pub const TCA_HW_OFFLOAD: _bindgen_ty_91 = _bindgen_ty_91::TCA_HW_OFFLOAD; +pub const __TCA_MAX: _bindgen_ty_91 = _bindgen_ty_91::__TCA_MAX; +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum _bindgen_ty_91 { + TCA_UNSPEC = 0, + TCA_KIND = 1, + TCA_OPTIONS = 2, + TCA_STATS = 3, + TCA_XSTATS = 4, + TCA_RATE = 5, + TCA_FCNT = 6, + TCA_STATS2 = 7, + TCA_STAB = 8, + TCA_PAD = 9, + TCA_DUMP_INVISIBLE = 10, + TCA_CHAIN = 11, + TCA_HW_OFFLOAD = 12, + __TCA_MAX = 13, +} +pub const TCA_BPF_UNSPEC: _bindgen_ty_133 = _bindgen_ty_133::TCA_BPF_UNSPEC; +pub const TCA_BPF_ACT: _bindgen_ty_133 = _bindgen_ty_133::TCA_BPF_ACT; +pub const TCA_BPF_POLICE: _bindgen_ty_133 = _bindgen_ty_133::TCA_BPF_POLICE; +pub const TCA_BPF_CLASSID: _bindgen_ty_133 = _bindgen_ty_133::TCA_BPF_CLASSID; +pub const TCA_BPF_OPS_LEN: _bindgen_ty_133 = _bindgen_ty_133::TCA_BPF_OPS_LEN; +pub const TCA_BPF_OPS: _bindgen_ty_133 = _bindgen_ty_133::TCA_BPF_OPS; +pub const TCA_BPF_FD: _bindgen_ty_133 = _bindgen_ty_133::TCA_BPF_FD; +pub const TCA_BPF_NAME: _bindgen_ty_133 = _bindgen_ty_133::TCA_BPF_NAME; +pub const TCA_BPF_FLAGS: _bindgen_ty_133 = _bindgen_ty_133::TCA_BPF_FLAGS; +pub const TCA_BPF_FLAGS_GEN: _bindgen_ty_133 = _bindgen_ty_133::TCA_BPF_FLAGS_GEN; +pub const TCA_BPF_TAG: _bindgen_ty_133 = _bindgen_ty_133::TCA_BPF_TAG; +pub const TCA_BPF_ID: _bindgen_ty_133 = _bindgen_ty_133::TCA_BPF_ID; +pub const __TCA_BPF_MAX: _bindgen_ty_133 = _bindgen_ty_133::__TCA_BPF_MAX; +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum _bindgen_ty_133 { + TCA_BPF_UNSPEC = 0, + TCA_BPF_ACT = 1, + TCA_BPF_POLICE = 2, + TCA_BPF_CLASSID = 3, + TCA_BPF_OPS_LEN = 4, + TCA_BPF_OPS = 5, + TCA_BPF_FD = 6, + TCA_BPF_NAME = 7, + TCA_BPF_FLAGS = 8, + TCA_BPF_FLAGS_GEN = 9, + TCA_BPF_TAG = 10, + TCA_BPF_ID = 11, + __TCA_BPF_MAX = 12, +} pub const AYA_PERF_EVENT_IOC_ENABLE: ::std::os::raw::c_int = 9216; pub const AYA_PERF_EVENT_IOC_DISABLE: ::std::os::raw::c_int = 9217; pub const AYA_PERF_EVENT_IOC_SET_BPF: ::std::os::raw::c_int = 1074013192; diff --git a/aya/src/generated/linux_bindings_x86_64.rs b/aya/src/generated/linux_bindings_x86_64.rs index 85de3ac0..fa1d2f76 100644 --- a/aya/src/generated/linux_bindings_x86_64.rs +++ b/aya/src/generated/linux_bindings_x86_64.rs @@ -136,6 +136,16 @@ pub const XDP_FLAGS_MODES: u32 = 14; pub const XDP_FLAGS_MASK: u32 = 31; pub const SO_ATTACH_BPF: u32 = 50; pub const SO_DETACH_BPF: u32 = 27; +pub const TC_H_MAJ_MASK: u32 = 4294901760; +pub const TC_H_MIN_MASK: u32 = 65535; +pub const TC_H_UNSPEC: u32 = 0; +pub const TC_H_ROOT: u32 = 4294967295; +pub const TC_H_INGRESS: u32 = 4294967281; +pub const TC_H_CLSACT: u32 = 4294967281; +pub const TC_H_MIN_PRIORITY: u32 = 65504; +pub const TC_H_MIN_INGRESS: u32 = 65522; +pub const TC_H_MIN_EGRESS: u32 = 65523; +pub const TCA_BPF_FLAG_ACT_DIRECT: u32 = 1; pub type __u8 = ::std::os::raw::c_uchar; pub type __s16 = ::std::os::raw::c_short; pub type __u16 = ::std::os::raw::c_ushort; @@ -600,6 +610,68 @@ pub struct bpf_attr__bindgen_ty_19 { } #[repr(C)] #[derive(Debug, Copy, Clone)] +pub struct bpf_prog_info { + pub type_: __u32, + pub id: __u32, + pub tag: [__u8; 8usize], + pub jited_prog_len: __u32, + pub xlated_prog_len: __u32, + pub jited_prog_insns: __u64, + pub xlated_prog_insns: __u64, + pub load_time: __u64, + pub created_by_uid: __u32, + pub nr_map_ids: __u32, + pub map_ids: __u64, + pub name: [::std::os::raw::c_char; 16usize], + pub ifindex: __u32, + pub _bitfield_align_1: [u8; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub netns_dev: __u64, + pub netns_ino: __u64, + pub nr_jited_ksyms: __u32, + pub nr_jited_func_lens: __u32, + pub jited_ksyms: __u64, + pub jited_func_lens: __u64, + pub btf_id: __u32, + pub func_info_rec_size: __u32, + pub func_info: __u64, + pub nr_func_info: __u32, + pub nr_line_info: __u32, + pub line_info: __u64, + pub jited_line_info: __u64, + pub nr_jited_line_info: __u32, + pub line_info_rec_size: __u32, + pub jited_line_info_rec_size: __u32, + pub nr_prog_tags: __u32, + pub prog_tags: __u64, + pub run_time_ns: __u64, + pub run_cnt: __u64, + pub recursion_misses: __u64, +} +impl bpf_prog_info { + #[inline] + pub fn gpl_compatible(&self) -> __u32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_gpl_compatible(&mut self, val: __u32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1(gpl_compatible: __u32) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let gpl_compatible: u32 = unsafe { ::std::mem::transmute(gpl_compatible) }; + gpl_compatible as u64 + }); + __bindgen_bitfield_unit + } +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] pub struct btf_header { pub magic: __u16, pub version: __u8, @@ -689,7 +761,7 @@ pub enum perf_sw_ids { PERF_COUNT_SW_BPF_OUTPUT = 10, PERF_COUNT_SW_MAX = 11, } -#[repr(u64)] +#[repr(u32)] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub enum perf_event_sample_format { PERF_SAMPLE_IP = 1, @@ -713,7 +785,6 @@ pub enum perf_event_sample_format { PERF_SAMPLE_REGS_INTR = 262144, PERF_SAMPLE_PHYS_ADDR = 524288, PERF_SAMPLE_MAX = 1048576, - __PERF_SAMPLE_CALLCHAIN_EARLY = 9223372036854775808, } #[repr(C)] #[derive(Copy, Clone)] @@ -724,7 +795,7 @@ pub struct perf_event_attr { pub __bindgen_anon_1: perf_event_attr__bindgen_ty_1, pub sample_type: __u64, pub read_format: __u64, - pub _bitfield_align_1: [u32; 0], + pub _bitfield_align_1: [u64; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 8usize]>, pub __bindgen_anon_2: perf_event_attr__bindgen_ty_2, pub bp_type: __u32, @@ -757,8 +828,6 @@ pub union perf_event_attr__bindgen_ty_2 { #[derive(Copy, Clone)] pub union perf_event_attr__bindgen_ty_3 { pub bp_addr: __u64, - pub kprobe_func: __u64, - pub uprobe_path: __u64, pub config1: __u64, _bindgen_union_align: u64, } @@ -766,8 +835,6 @@ pub union perf_event_attr__bindgen_ty_3 { #[derive(Copy, Clone)] pub union perf_event_attr__bindgen_ty_4 { pub bp_len: __u64, - pub kprobe_addr: __u64, - pub probe_offset: __u64, pub config2: __u64, _bindgen_union_align: u64, } @@ -1081,47 +1148,14 @@ impl perf_event_attr { } } #[inline] - pub fn ksymbol(&self) -> __u64 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(29usize, 1u8) as u64) } - } - #[inline] - pub fn set_ksymbol(&mut self, val: __u64) { - unsafe { - let val: u64 = ::std::mem::transmute(val); - self._bitfield_1.set(29usize, 1u8, val as u64) - } - } - #[inline] - pub fn bpf_event(&self) -> __u64 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(30usize, 1u8) as u64) } - } - #[inline] - pub fn set_bpf_event(&mut self, val: __u64) { - unsafe { - let val: u64 = ::std::mem::transmute(val); - self._bitfield_1.set(30usize, 1u8, val as u64) - } - } - #[inline] - pub fn aux_output(&self) -> __u64 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(31usize, 1u8) as u64) } - } - #[inline] - pub fn set_aux_output(&mut self, val: __u64) { - unsafe { - let val: u64 = ::std::mem::transmute(val); - self._bitfield_1.set(31usize, 1u8, val as u64) - } - } - #[inline] pub fn __reserved_1(&self) -> __u64 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(32usize, 32u8) as u64) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(29usize, 35u8) as u64) } } #[inline] pub fn set___reserved_1(&mut self, val: __u64) { unsafe { let val: u64 = ::std::mem::transmute(val); - self._bitfield_1.set(32usize, 32u8, val as u64) + self._bitfield_1.set(29usize, 35u8, val as u64) } } #[inline] @@ -1154,9 +1188,6 @@ impl perf_event_attr { context_switch: __u64, write_backward: __u64, namespaces: __u64, - ksymbol: __u64, - bpf_event: __u64, - aux_output: __u64, __reserved_1: __u64, ) -> __BindgenBitfieldUnit<[u8; 8usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 8usize]> = Default::default(); @@ -1274,19 +1305,7 @@ impl perf_event_attr { let namespaces: u64 = unsafe { ::std::mem::transmute(namespaces) }; namespaces as u64 }); - __bindgen_bitfield_unit.set(29usize, 1u8, { - let ksymbol: u64 = unsafe { ::std::mem::transmute(ksymbol) }; - ksymbol as u64 - }); - __bindgen_bitfield_unit.set(30usize, 1u8, { - let bpf_event: u64 = unsafe { ::std::mem::transmute(bpf_event) }; - bpf_event as u64 - }); - __bindgen_bitfield_unit.set(31usize, 1u8, { - let aux_output: u64 = unsafe { ::std::mem::transmute(aux_output) }; - aux_output as u64 - }); - __bindgen_bitfield_unit.set(32usize, 32u8, { + __bindgen_bitfield_unit.set(29usize, 35u8, { let __reserved_1: u64 = unsafe { ::std::mem::transmute(__reserved_1) }; __reserved_1 as u64 }); @@ -1465,9 +1484,7 @@ pub enum perf_event_type { PERF_RECORD_SWITCH = 14, PERF_RECORD_SWITCH_CPU_WIDE = 15, PERF_RECORD_NAMESPACES = 16, - PERF_RECORD_KSYMBOL = 17, - PERF_RECORD_BPF_EVENT = 18, - PERF_RECORD_MAX = 19, + PERF_RECORD_MAX = 17, } pub const IFLA_XDP_UNSPEC: _bindgen_ty_79 = _bindgen_ty_79::IFLA_XDP_UNSPEC; pub const IFLA_XDP_FD: _bindgen_ty_79 = _bindgen_ty_79::IFLA_XDP_FD; @@ -1503,6 +1520,79 @@ pub struct ifinfomsg { pub ifi_flags: ::std::os::raw::c_uint, pub ifi_change: ::std::os::raw::c_uint, } +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct tcmsg { + pub tcm_family: ::std::os::raw::c_uchar, + pub tcm__pad1: ::std::os::raw::c_uchar, + pub tcm__pad2: ::std::os::raw::c_ushort, + pub tcm_ifindex: ::std::os::raw::c_int, + pub tcm_handle: __u32, + pub tcm_parent: __u32, + pub tcm_info: __u32, +} +pub const TCA_UNSPEC: _bindgen_ty_91 = _bindgen_ty_91::TCA_UNSPEC; +pub const TCA_KIND: _bindgen_ty_91 = _bindgen_ty_91::TCA_KIND; +pub const TCA_OPTIONS: _bindgen_ty_91 = _bindgen_ty_91::TCA_OPTIONS; +pub const TCA_STATS: _bindgen_ty_91 = _bindgen_ty_91::TCA_STATS; +pub const TCA_XSTATS: _bindgen_ty_91 = _bindgen_ty_91::TCA_XSTATS; +pub const TCA_RATE: _bindgen_ty_91 = _bindgen_ty_91::TCA_RATE; +pub const TCA_FCNT: _bindgen_ty_91 = _bindgen_ty_91::TCA_FCNT; +pub const TCA_STATS2: _bindgen_ty_91 = _bindgen_ty_91::TCA_STATS2; +pub const TCA_STAB: _bindgen_ty_91 = _bindgen_ty_91::TCA_STAB; +pub const TCA_PAD: _bindgen_ty_91 = _bindgen_ty_91::TCA_PAD; +pub const TCA_DUMP_INVISIBLE: _bindgen_ty_91 = _bindgen_ty_91::TCA_DUMP_INVISIBLE; +pub const TCA_CHAIN: _bindgen_ty_91 = _bindgen_ty_91::TCA_CHAIN; +pub const TCA_HW_OFFLOAD: _bindgen_ty_91 = _bindgen_ty_91::TCA_HW_OFFLOAD; +pub const __TCA_MAX: _bindgen_ty_91 = _bindgen_ty_91::__TCA_MAX; +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum _bindgen_ty_91 { + TCA_UNSPEC = 0, + TCA_KIND = 1, + TCA_OPTIONS = 2, + TCA_STATS = 3, + TCA_XSTATS = 4, + TCA_RATE = 5, + TCA_FCNT = 6, + TCA_STATS2 = 7, + TCA_STAB = 8, + TCA_PAD = 9, + TCA_DUMP_INVISIBLE = 10, + TCA_CHAIN = 11, + TCA_HW_OFFLOAD = 12, + __TCA_MAX = 13, +} +pub const TCA_BPF_UNSPEC: _bindgen_ty_133 = _bindgen_ty_133::TCA_BPF_UNSPEC; +pub const TCA_BPF_ACT: _bindgen_ty_133 = _bindgen_ty_133::TCA_BPF_ACT; +pub const TCA_BPF_POLICE: _bindgen_ty_133 = _bindgen_ty_133::TCA_BPF_POLICE; +pub const TCA_BPF_CLASSID: _bindgen_ty_133 = _bindgen_ty_133::TCA_BPF_CLASSID; +pub const TCA_BPF_OPS_LEN: _bindgen_ty_133 = _bindgen_ty_133::TCA_BPF_OPS_LEN; +pub const TCA_BPF_OPS: _bindgen_ty_133 = _bindgen_ty_133::TCA_BPF_OPS; +pub const TCA_BPF_FD: _bindgen_ty_133 = _bindgen_ty_133::TCA_BPF_FD; +pub const TCA_BPF_NAME: _bindgen_ty_133 = _bindgen_ty_133::TCA_BPF_NAME; +pub const TCA_BPF_FLAGS: _bindgen_ty_133 = _bindgen_ty_133::TCA_BPF_FLAGS; +pub const TCA_BPF_FLAGS_GEN: _bindgen_ty_133 = _bindgen_ty_133::TCA_BPF_FLAGS_GEN; +pub const TCA_BPF_TAG: _bindgen_ty_133 = _bindgen_ty_133::TCA_BPF_TAG; +pub const TCA_BPF_ID: _bindgen_ty_133 = _bindgen_ty_133::TCA_BPF_ID; +pub const __TCA_BPF_MAX: _bindgen_ty_133 = _bindgen_ty_133::__TCA_BPF_MAX; +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum _bindgen_ty_133 { + TCA_BPF_UNSPEC = 0, + TCA_BPF_ACT = 1, + TCA_BPF_POLICE = 2, + TCA_BPF_CLASSID = 3, + TCA_BPF_OPS_LEN = 4, + TCA_BPF_OPS = 5, + TCA_BPF_FD = 6, + TCA_BPF_NAME = 7, + TCA_BPF_FLAGS = 8, + TCA_BPF_FLAGS_GEN = 9, + TCA_BPF_TAG = 10, + TCA_BPF_ID = 11, + __TCA_BPF_MAX = 12, +} pub const AYA_PERF_EVENT_IOC_ENABLE: ::std::os::raw::c_int = 9216; pub const AYA_PERF_EVENT_IOC_DISABLE: ::std::os::raw::c_int = 9217; pub const AYA_PERF_EVENT_IOC_SET_BPF: ::std::os::raw::c_int = 1074013192; diff --git a/aya/src/programs/cls.rs b/aya/src/programs/cls.rs deleted file mode 100644 index 08535183..00000000 --- a/aya/src/programs/cls.rs +++ /dev/null @@ -1,42 +0,0 @@ -use crate::{ - generated::bpf_prog_type::{BPF_PROG_TYPE_SCHED_ACT, BPF_PROG_TYPE_SCHED_CLS}, - programs::{load_program, ProgramData, ProgramError}, -}; - -#[derive(Debug)] -pub struct SchedClassifier { - pub(crate) data: ProgramData, -} - -impl SchedClassifier { - /// Loads the program inside the kernel. - /// - /// See also [`Program::load`](crate::programs::Program::load). - pub fn load(&mut self) -> Result<(), ProgramError> { - load_program(BPF_PROG_TYPE_SCHED_CLS, &mut self.data) - } - - /// Returns the name of the program. - pub fn name(&self) -> String { - self.data.name.to_string() - } -} - -#[derive(Debug)] -pub struct SchedAction { - pub(crate) data: ProgramData, -} - -impl SchedAction { - /// Loads the program inside the kernel. - /// - /// See also [`Program::load`](crate::programs::Program::load). - pub fn load(&mut self) -> Result<(), ProgramError> { - load_program(BPF_PROG_TYPE_SCHED_ACT, &mut self.data) - } - - /// Returns the name of the program. - pub fn name(&self) -> String { - self.data.name.to_string() - } -} diff --git a/aya/src/programs/mod.rs b/aya/src/programs/mod.rs index 0ff7758f..9b02b7f4 100644 --- a/aya/src/programs/mod.rs +++ b/aya/src/programs/mod.rs @@ -44,7 +44,7 @@ //! [`Bpf::program`]: crate::Bpf::program //! [`Bpf::program_mut`]: crate::Bpf::program_mut //! [maps]: crate::maps -mod cls; +mod tc; mod kprobe; mod perf_attach; mod probe; @@ -60,7 +60,7 @@ use libc::{close, ENOSPC}; use std::{cell::RefCell, cmp, convert::TryFrom, ffi::CStr, io, os::unix::io::RawFd, rc::Rc}; use thiserror::Error; -pub use cls::{SchedAction, SchedClassifier}; +pub use tc::{SchedClassifier, TcError, TcAttachPoint}; pub use kprobe::{KProbe, KProbeError}; use perf_attach::*; pub use probe::ProbeKind; @@ -132,6 +132,9 @@ pub enum ProgramError { #[error(transparent)] XdpError(#[from] XdpError), + + #[error(transparent)] + TcError(#[from] TcError), } pub trait ProgramFd { diff --git a/aya/src/programs/tc.rs b/aya/src/programs/tc.rs new file mode 100644 index 00000000..7c5721ee --- /dev/null +++ b/aya/src/programs/tc.rs @@ -0,0 +1,118 @@ +use thiserror::Error; + +use std::{io, os::unix::io::RawFd}; + +use crate::{ + generated::{ + TC_H_CLSACT, TC_H_MIN_INGRESS, TC_H_MIN_EGRESS, + bpf_prog_type::BPF_PROG_TYPE_SCHED_CLS, + }, + programs::{Link, LinkRef, load_program, ProgramData, ProgramError}, + sys::{netlink_qdisc_add_clsact, netlink_qdisc_attach, netlink_qdisc_detach}, + util::{ifindex_from_ifname, tc_handler_make}, +}; + +#[derive(Debug, Clone, Copy)] +#[repr(u32)] +pub enum TcAttachPoint { + Ingress = TC_H_MIN_INGRESS, + Egress = TC_H_MIN_EGRESS, + Custom, +} + +#[derive(Debug)] +pub struct SchedClassifier { + pub(crate) data: ProgramData, +} + +#[derive(Debug, Error)] +pub enum TcError { + #[error("netlink error while attaching ebpf program to tc")] + NetlinkError { + #[source] + io_error: io::Error, + }, + #[error("the clsact qdisc is already attached")] + AlreadyAttached, +} + +#[derive(Debug)] +struct TcLink { + if_index: i32, + attach_point: TcAttachPoint, + prog_fd: Option, + priority: u32, +} + +impl TcAttachPoint { + pub fn tcm_parent(&self, parent: u32) -> Result { + match *self { + TcAttachPoint::Custom => { + if parent == 0 { + return Err(io::Error::new(io::ErrorKind::Other, "Parent must be non-zero for Custom attach points")); + } + Ok(parent) + } + _ => Ok(tc_handler_make(TC_H_CLSACT, (*self).clone() as u32)) + } + } +} + +impl SchedClassifier { + /// Loads the program inside the kernel. + /// + /// See also [`Program::load`](crate::programs::Program::load). + pub fn load(&mut self) -> Result<(), ProgramError> { + load_program(BPF_PROG_TYPE_SCHED_CLS, &mut self.data) + } + + /// Returns the name of the program. + pub fn name(&self) -> String { + self.data.name.to_string() + } + + /// Attaches the program to the given `interface` and `attach-point` + pub fn attach(&mut self, interface: &str, attach_point: TcAttachPoint) -> Result { + let prog_fd = self.data.fd_or_err()?; + let if_index = unsafe { ifindex_from_ifname(interface) } + .map_err(|io_error| TcError::NetlinkError { io_error })?; + let prog_name = self.name(); + let priority = unsafe { netlink_qdisc_attach(if_index as i32, &attach_point, prog_fd, &prog_name[..]) } + .map_err(|io_error| TcError::NetlinkError { io_error })?; + Ok(self.data.link(TcLink { + if_index: if_index as i32, + attach_point, + prog_fd: Some(prog_fd), + priority, + })) + } + + /// Add "clasct" qdisc to an interface + pub fn qdisc_add_clsact_to_interface(if_name: &str) -> Result<(), ProgramError> { + // unsafe wrapper + let if_index = unsafe { ifindex_from_ifname(if_name) } + .map_err(|_| ProgramError::UnknownInterface {name: if_name.to_string()})?; + unsafe { netlink_qdisc_add_clsact(if_index as i32) } + .map_err(|io_error| TcError::NetlinkError { io_error })?; + Ok(()) + } +} + +impl Drop for TcLink { + fn drop(&mut self) { + let _ = self.detach(); + } +} + +impl Link for TcLink { + fn detach(&mut self) -> Result<(), ProgramError> { + if let Some(_) = self.prog_fd.take() { + unsafe { netlink_qdisc_detach(self.if_index, &self.attach_point, self.priority) } + .map_err(|io_error| TcError::NetlinkError { io_error })?; + Ok(()) + } else { + Err(ProgramError::AlreadyDetached) + } + } +} + diff --git a/aya/src/sys/netlink.rs b/aya/src/sys/netlink.rs index b3a9afbd..59bc850f 100644 --- a/aya/src/sys/netlink.rs +++ b/aya/src/sys/netlink.rs @@ -1,14 +1,28 @@ -use std::{io, mem, os::unix::io::RawFd, ptr}; +use std::{ + io, + mem, + os::unix::io::RawFd, + ptr, + slice, +}; use libc::{ c_int, close, getsockname, nlattr, nlmsgerr, nlmsghdr, recv, send, setsockopt, sockaddr_nl, socket, AF_NETLINK, AF_UNSPEC, IFLA_XDP, NETLINK_ROUTE, NLA_ALIGNTO, NLA_F_NESTED, NLMSG_DONE, - NLMSG_ERROR, NLM_F_ACK, NLM_F_MULTI, NLM_F_REQUEST, RTM_SETLINK, SOCK_RAW, SOL_NETLINK, + NLMSG_ERROR, NLM_F_ACK, NLM_F_EXCL, NLM_F_ECHO, NLM_F_CREATE, NLM_F_MULTI, NLM_F_REQUEST, RTM_SETLINK, SOCK_RAW, + SOL_NETLINK, RTM_NEWQDISC, RTM_NEWTFILTER, RTM_DELTFILTER, ETH_P_ALL, }; -use crate::generated::{ +use crate::{ + generated::{ _bindgen_ty_79::{IFLA_XDP_EXPECTED_FD, IFLA_XDP_FD, IFLA_XDP_FLAGS}, - ifinfomsg, NLMSG_ALIGNTO, XDP_FLAGS_REPLACE, + _bindgen_ty_91::{TCA_KIND, TCA_OPTIONS}, + _bindgen_ty_133::{TCA_BPF_FD, TCA_BPF_NAME, TCA_BPF_FLAGS}, + ifinfomsg, tcmsg, NLMSG_ALIGNTO, XDP_FLAGS_REPLACE, + TC_H_UNSPEC, TCA_BPF_FLAG_ACT_DIRECT, TC_H_CLSACT, TC_H_INGRESS, TC_H_MAJ_MASK, + }, + util::{htons, tc_handler_make}, + programs::TcAttachPoint, }; const NETLINK_EXT_ACK: c_int = 11; @@ -21,7 +35,7 @@ pub(crate) unsafe fn netlink_set_xdp_fd( old_fd: Option, flags: u32, ) -> Result<(), io::Error> { - let sock = NetlinkSocket::open().unwrap(); + let sock = NetlinkSocket::open()?; let seq = 1; // Safety: Request is POD so this is safe @@ -116,6 +130,233 @@ pub(crate) unsafe fn netlink_set_xdp_fd( Ok(()) } +pub(crate) unsafe fn netlink_qdisc_add_clsact( + if_index: i32 +) -> Result<(), io::Error> { + let sock = NetlinkSocket::open()?; + + let seq = 1; + let mut req = mem::zeroed::(); + + req.header = nlmsghdr { + nlmsg_len: (mem::size_of::() + mem::size_of::()) as u32, + nlmsg_flags: (NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE) as u16, + nlmsg_type: RTM_NEWQDISC, + nlmsg_pid: 0, + nlmsg_seq: seq, + }; + req.tc_info.tcm_family = AF_UNSPEC as u8; + req.tc_info.tcm_ifindex = if_index; + req.tc_info.tcm_handle = tc_handler_make(TC_H_CLSACT, TC_H_UNSPEC); + req.tc_info.tcm_parent = tc_handler_make(TC_H_CLSACT, TC_H_INGRESS); + req.tc_info.tcm_info = 0; + + let attrs_addr = &req as *const _ as usize + req.header.nlmsg_len as usize; + let attrs_addr = align_to(attrs_addr, NLMSG_ALIGNTO as usize); + let nla_hdr_len = align_to(mem::size_of::(), NLA_ALIGNTO as usize); + + // length of the root attribute + let mut nla_len = nla_hdr_len as u16; + + let mut offset = attrs_addr as usize; + let attr = nlattr { + nla_type: TCA_KIND as u16, + // size of payload + nla_len: (nla_hdr_len + 7) as u16, + }; + + // write header + ptr::write(offset as *mut nlattr, attr); + offset += nla_hdr_len; + // write the "clsact" string + let buf = slice::from_raw_parts_mut(offset as *mut u8, 7); + buf.copy_from_slice(b"clsact\0"); + nla_len += attr.nla_len; + + req.header.nlmsg_len += align_to(nla_len as usize, NLA_ALIGNTO as usize) as u32; + + if send( + sock.sock, + &req as *const _ as *const _, + req.header.nlmsg_len as usize, + 0, + ) < 0 + { + return Err(io::Error::last_os_error())?; + } + sock.recv()?; + + Ok(()) +} + +pub(crate) unsafe fn netlink_qdisc_detach( + if_index: i32, + attach_point: &TcAttachPoint, + priority: u32, +) -> Result<(), io::Error> { + let sock = NetlinkSocket::open()?; + let seq = 1; + let mut req = mem::zeroed::(); + + req.header = nlmsghdr{ + nlmsg_len: (mem::size_of::() + mem::size_of::()) as u32, + nlmsg_flags: (NLM_F_REQUEST | NLM_F_ACK) as u16, + nlmsg_type: RTM_DELTFILTER, + nlmsg_pid: 0, + nlmsg_seq: seq, + }; + + req.tc_info.tcm_family = AF_UNSPEC as u8; + req.tc_info.tcm_handle = 0; // auto-assigned, if not provided + req.tc_info.tcm_info = tc_handler_make(priority << 16, htons(ETH_P_ALL as u16) as u32); + req.tc_info.tcm_parent = attach_point.tcm_parent(0)?; + req.tc_info.tcm_ifindex = if_index; + + if send( + sock.sock, + &req as *const _ as *const _, + req.header.nlmsg_len as usize, + 0, + ) < 0 + { + return Err(io::Error::last_os_error())?; + } + + sock.recv()?; + + Ok(()) +} + +pub(crate) unsafe fn netlink_qdisc_attach( + if_index: i32, + attach_point: &TcAttachPoint, + prog_fd: RawFd, + prog_name: &str, +) -> Result { + let sock = NetlinkSocket::open()?; + let seq = 1; + let priority = 0; + let mut req = mem::zeroed::(); + + req.header = nlmsghdr{ + nlmsg_len: (mem::size_of::() + mem::size_of::()) as u32, + nlmsg_flags: (NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE | NLM_F_ECHO) as u16, + nlmsg_type: RTM_NEWTFILTER, + nlmsg_pid: 0, + nlmsg_seq: seq, + }; + req.tc_info.tcm_family = AF_UNSPEC as u8; + req.tc_info.tcm_handle = 0; // auto-assigned, if not provided + req.tc_info.tcm_ifindex = if_index; + req.tc_info.tcm_parent = attach_point.tcm_parent(0)?; + + req.tc_info.tcm_info = tc_handler_make(priority << 16, htons(ETH_P_ALL as u16) as u32); + + let attrs_addr = &req as *const _ as usize + req.header.nlmsg_len as usize; + let attrs_addr = align_to(attrs_addr, NLMSG_ALIGNTO as usize); + let nla_hdr_len = align_to(mem::size_of::(), NLA_ALIGNTO as usize); + + let mut nla_len = nla_hdr_len as u16; + + let mut offset = attrs_addr as usize; + + let attr = nlattr { + nla_type: TCA_KIND as u16, + nla_len: (nla_hdr_len + 4) as u16, + }; + + // write header + ptr::write(offset as *mut nlattr, attr); + offset += nla_hdr_len; + + // now write the actual "bpf" string + let buf = slice::from_raw_parts_mut(offset as *mut u8, 4); + buf.copy_from_slice(b"bpf\0"); + + offset += 4; + nla_len += attr.nla_len; + + let nested_tca_options_start = nla_len; + let nested_attr_offset = offset; + // now write the nested portion + + let mut nested_attr = nlattr { + nla_type: TCA_OPTIONS as u16 | NLA_F_NESTED as u16, + nla_len: nla_hdr_len as u16, // no data + }; + + offset += nla_hdr_len; + nla_len += attr.nla_len; + // add program fd and name. + + let attr = nlattr { + nla_type: TCA_BPF_FD as u16, + nla_len: (nla_hdr_len + mem::size_of::()) as u16, + }; + ptr::write(offset as *mut nlattr, attr); + offset += nla_hdr_len; + + ptr::write(offset as *mut RawFd, prog_fd); + offset += mem::size_of::(); + nla_len += attr.nla_len; + + let prog_name_null = prog_name.to_string() + "\0"; + let prog_name_len = prog_name_null.len(); + + let attr = nlattr { + nla_type: TCA_BPF_NAME as u16, + nla_len: (nla_hdr_len + prog_name_len) as u16, + }; + + ptr::write(offset as *mut nlattr, attr); + offset += nla_hdr_len; + + let buf = slice::from_raw_parts_mut(offset as *mut u8, prog_name_len); + buf.copy_from_slice(prog_name_null.as_bytes()); + + offset += prog_name_len; + nla_len += attr.nla_len; + + // write bpf flags for direct action, direct action is the default + let bpf_flags = TCA_BPF_FLAG_ACT_DIRECT; + let attr = nlattr { + nla_type: TCA_BPF_FLAGS as u16, + nla_len: (nla_hdr_len + mem::size_of::()) as u16, + }; + ptr::write(offset as *mut nlattr, attr); + offset += nla_hdr_len; + + ptr::write(offset as *mut u32, bpf_flags); + nla_len += attr.nla_len; + + // now write the NESTED nlattr + nested_attr.nla_len = nla_len - nested_tca_options_start; + ptr::write(nested_attr_offset as *mut nlattr, nested_attr); + req.header.nlmsg_len += align_to(nla_len as usize, NLA_ALIGNTO as usize) as u32; + + if send( + sock.sock, + &req as *const _ as *const _, + req.header.nlmsg_len as usize, + 0, + ) < 0 + { + return Err(io::Error::last_os_error())?; + } + + let reply_msg = sock.recv()?; + let mut tcinfo = 0; + for reply in &reply_msg { + if reply.header.nlmsg_type == RTM_NEWTFILTER { + let _tcmsg = reply._data.as_ptr() as *const tcmsg; + tcinfo = (*_tcmsg).tcm_info; + break; + } + } + let priority = ((tcinfo & TC_H_MAJ_MASK) >> 16) as u32; + Ok(priority) +} + #[repr(C)] struct Request { header: nlmsghdr, @@ -123,6 +364,12 @@ struct Request { attrs: [u8; 64], } +#[repr(C)] +struct QdiscRequest { + header: nlmsghdr, + tc_info: tcmsg, +} + struct NetlinkSocket { sock: RawFd, _nl_pid: u32, @@ -164,9 +411,9 @@ impl NetlinkSocket { }) } - fn recv(&self) -> Result<(), io::Error> { + fn recv(&self) -> Result, io::Error> { let mut buf = [0u8; 4096]; - + let mut messages = Vec::new(); let mut multipart = true; while multipart { multipart = false; @@ -184,9 +431,7 @@ impl NetlinkSocket { while offset < len { let message = NetlinkMessage::read(&buf[offset..])?; offset += align_to(message.header.nlmsg_len as usize, NLMSG_ALIGNTO as usize); - multipart = message.header.nlmsg_flags & NLM_F_MULTI as u16 != 0; - match message.header.nlmsg_type as i32 { NLMSG_ERROR => { let err = message.error.unwrap(); @@ -197,12 +442,12 @@ impl NetlinkSocket { return Err(io::Error::from_raw_os_error(-err.error)); } NLMSG_DONE => break, - _ => {} + _ => messages.push(message), } } } - Ok(()) + Ok(messages) } } @@ -258,3 +503,4 @@ impl Drop for NetlinkSocket { fn align_to(v: usize, align: usize) -> usize { (v + (align - 1)) & !(align - 1) } + diff --git a/aya/src/util.rs b/aya/src/util.rs index 4cfe11c8..f200b5f2 100644 --- a/aya/src/util.rs +++ b/aya/src/util.rs @@ -2,10 +2,18 @@ use std::{ collections::BTreeMap, fs::{self, File}, + ffi::CString, + os::raw::c_char, io::{self, BufReader}, str::FromStr, }; +use crate::{ + generated::{TC_H_MAJ_MASK, TC_H_MIN_MASK}, +}; + +use libc::if_nametoindex; + use io::BufRead; const ONLINE_CPUS: &str = "/sys/devices/system/cpu/online"; @@ -26,6 +34,10 @@ pub fn nr_cpus() -> Result { Ok(possible_cpus()?.len()) } +pub(crate) fn tc_handler_make(major: u32, minor: u32) -> u32 { + (major & TC_H_MAJ_MASK) | (minor & TC_H_MIN_MASK) +} + pub(crate) fn possible_cpus() -> Result, io::Error> { let data = fs::read_to_string(POSSIBLE_CPUS)?; parse_cpu_ranges(data.trim()).map_err(|_| { @@ -57,6 +69,28 @@ fn parse_cpu_ranges(data: &str) -> Result, ()> { Ok(cpus) } +/// Gets interface index from interface name. +pub unsafe fn ifindex_from_ifname(if_name: &str) -> Result { + let c_str_if_name = CString::new(if_name)?; + let c_if_name: *const c_char = c_str_if_name.as_ptr() as *const c_char; + // unsafe libc wrapper + let if_index = if_nametoindex(c_if_name); + if if_index == 0 { + return Err(io::Error::last_os_error()); + } + Ok(if_index) +} + + +/// htons and ntohs util functions +pub fn htons(u: u16) -> u16 { + u.to_be() +} + +pub fn ntohs(u: u16) -> u16 { + u16::from_be(u) +} + /// Loads kernel symbols from `/proc/kallsyms`. /// /// The symbols can be passed to [`StackTrace::resolve`](crate::maps::stack_trace::StackTrace::resolve). diff --git a/bpf/aya-bpf/src/maps/hash_map.rs b/bpf/aya-bpf/src/maps/hash_map.rs index 42b1ac12..9afc41a4 100644 --- a/bpf/aya-bpf/src/maps/hash_map.rs +++ b/bpf/aya-bpf/src/maps/hash_map.rs @@ -4,7 +4,7 @@ use aya_bpf_cty::{c_long, c_void}; use crate::{ bindings::{bpf_map_def, bpf_map_type::BPF_MAP_TYPE_HASH}, - helpers::{bpf_map_lookup_elem, bpf_map_update_elem}, + helpers::{bpf_map_lookup_elem, bpf_map_update_elem, bpf_map_delete_elem}, }; #[repr(transparent)] diff --git a/xtask/src/codegen/aya.rs b/xtask/src/codegen/aya.rs index f614299e..a55b70fb 100644 --- a/xtask/src/codegen/aya.rs +++ b/xtask/src/codegen/aya.rs @@ -59,6 +59,7 @@ fn codegen_bindings(opts: &Options) -> Result<(), anyhow::Error> { "bpf_map_type", "bpf_prog_type", "bpf_attach_type", + "bpf_prog_info", // BTF "btf_header", "btf_ext_info", @@ -80,6 +81,7 @@ fn codegen_bindings(opts: &Options) -> Result<(), anyhow::Error> { "perf_event_type", // NETLINK "ifinfomsg", + "tcmsg", ]; let vars = [ @@ -112,7 +114,22 @@ fn codegen_bindings(opts: &Options) -> Result<(), anyhow::Error> { // NETLINK "NLMSG_ALIGNTO", "IFLA_XDP_FD", + "TCA_KIND", + "TCA_OPTIONS", + "TCA_BPF_FD", + "TCA_BPF_NAME", + "TCA_BPF_FLAGS", + "TCA_BPF_FLAG_ACT_DIRECT", "XDP_FLAGS_.*", + "TC_H_MAJ_MASK", + "TC_H_MIN_MASK", + "TC_H_UNSPEC", + "TC_H_ROOT", + "TC_H_INGRESS", + "TC_H_CLSACT", + "TC_H_MIN_PRIORITY", + "TC_H_MIN_INGRESS", + "TC_H_MIN_EGRESS", ]; let dir = PathBuf::from("aya");