bpfman_api/
lib.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright Authors of bpfman
3
4use bpfman::{
5    errors::BpfmanError,
6    types::{BytecodeImage, Location, Program},
7};
8
9use crate::v1::{
10    attach_info::Info, bytecode_location::Location as V1Location, AttachInfo,
11    BytecodeImage as V1BytecodeImage, BytecodeLocation, FentryAttachInfo, FexitAttachInfo,
12    KernelProgramInfo as V1KernelProgramInfo, KprobeAttachInfo, ProgramInfo,
13    ProgramInfo as V1ProgramInfo, TcAttachInfo, TcxAttachInfo, TracepointAttachInfo,
14    UprobeAttachInfo, XdpAttachInfo,
15};
16
17#[path = "bpfman.v1.rs"]
18#[rustfmt::skip]
19#[allow(clippy::all)]
20pub mod v1;
21
22impl TryFrom<&Program> for ProgramInfo {
23    type Error = BpfmanError;
24
25    fn try_from(program: &Program) -> Result<Self, Self::Error> {
26        let data = program.get_data();
27
28        let bytecode = match data.get_location()? {
29            Location::Image(m) => {
30                Some(BytecodeLocation {
31                    location: Some(V1Location::Image(V1BytecodeImage {
32                        url: m.get_url().to_string(),
33                        image_pull_policy: m.get_pull_policy().to_owned() as i32,
34                        // Never dump Plaintext Credentials
35                        username: Some(String::new()),
36                        password: Some(String::new()),
37                    })),
38                })
39            }
40            Location::File(m) => Some(BytecodeLocation {
41                location: Some(V1Location::File(m.to_string())),
42            }),
43        };
44
45        let attach_info = AttachInfo {
46            info: match program.clone() {
47                Program::Xdp(p) => Some(Info::XdpAttachInfo(XdpAttachInfo {
48                    priority: p.get_priority()?,
49                    iface: p.get_iface()?.to_string(),
50                    position: p.get_current_position()?.unwrap_or(0) as i32,
51                    proceed_on: p.get_proceed_on()?.as_action_vec(),
52                    netns: p
53                        .get_netns()?
54                        .and_then(|path| path.into_os_string().into_string().ok()),
55                })),
56                Program::Tc(p) => Some(Info::TcAttachInfo(TcAttachInfo {
57                    priority: p.get_priority()?,
58                    iface: p.get_iface()?.to_string(),
59                    position: p.get_current_position()?.unwrap_or(0) as i32,
60                    direction: p.get_direction()?.to_string(),
61                    proceed_on: p.get_proceed_on()?.as_action_vec(),
62                    netns: p
63                        .get_netns()?
64                        .and_then(|path| path.into_os_string().into_string().ok()),
65                })),
66
67                Program::Tcx(p) => Some(Info::TcxAttachInfo(TcxAttachInfo {
68                    priority: p.get_priority()?,
69                    iface: p.get_iface()?.to_string(),
70                    position: p.get_current_position()?.unwrap_or(0) as i32,
71                    direction: p.get_direction()?.to_string(),
72                    netns: p
73                        .get_netns()?
74                        .and_then(|path| path.into_os_string().into_string().ok()),
75                })),
76                Program::Tracepoint(p) => Some(Info::TracepointAttachInfo(TracepointAttachInfo {
77                    tracepoint: p.get_tracepoint()?.to_string(),
78                })),
79                Program::Kprobe(p) => Some(Info::KprobeAttachInfo(KprobeAttachInfo {
80                    fn_name: p.get_fn_name()?.to_string(),
81                    offset: p.get_offset()?,
82                    retprobe: p.get_retprobe()?,
83                    container_pid: p.get_container_pid()?,
84                })),
85                Program::Uprobe(p) => Some(Info::UprobeAttachInfo(UprobeAttachInfo {
86                    fn_name: p.get_fn_name()?.map(|v| v.to_string()),
87                    offset: p.get_offset()?,
88                    target: p.get_target()?.to_string(),
89                    retprobe: p.get_retprobe()?,
90                    pid: p.get_pid()?,
91                    container_pid: p.get_container_pid()?,
92                })),
93                Program::Fentry(p) => Some(Info::FentryAttachInfo(FentryAttachInfo {
94                    fn_name: p.get_fn_name()?.to_string(),
95                })),
96                Program::Fexit(p) => Some(Info::FexitAttachInfo(FexitAttachInfo {
97                    fn_name: p.get_fn_name()?.to_string(),
98                })),
99                Program::Unsupported(_) => None,
100            },
101        };
102
103        // Populate the Program Info with bpfman data
104        Ok(V1ProgramInfo {
105            name: data.get_name()?.to_string(),
106            bytecode,
107            attach: Some(attach_info),
108            global_data: data.get_global_data()?,
109            map_owner_id: data.get_map_owner_id()?,
110            map_pin_path: data
111                .get_map_pin_path()?
112                .map_or(String::new(), |v| v.to_str().unwrap().to_string()),
113            map_used_by: data
114                .get_maps_used_by()?
115                .iter()
116                .map(|m| m.to_string())
117                .collect(),
118            metadata: data.get_metadata()?,
119        })
120    }
121}
122
123impl TryFrom<&Program> for V1KernelProgramInfo {
124    type Error = BpfmanError;
125
126    fn try_from(program: &Program) -> Result<Self, Self::Error> {
127        // Get the Kernel Info.
128        let data = program.get_data();
129
130        // Populate the Kernel Info.
131        Ok(V1KernelProgramInfo {
132            id: data.get_id()?,
133            name: data.get_kernel_name()?.to_string(),
134            program_type: program.kind() as u32,
135            loaded_at: data.get_kernel_loaded_at()?.to_string(),
136            tag: data.get_kernel_tag()?.to_string(),
137            gpl_compatible: data.get_kernel_gpl_compatible()?,
138            map_ids: data.get_kernel_map_ids()?,
139            btf_id: data.get_kernel_btf_id()?,
140            bytes_xlated: data.get_kernel_bytes_xlated()?,
141            jited: data.get_kernel_jited()?,
142            bytes_jited: data.get_kernel_bytes_jited()?,
143            bytes_memlock: data.get_kernel_bytes_memlock()?,
144            verified_insns: data.get_kernel_verified_insns()?,
145        })
146    }
147}
148
149impl From<V1BytecodeImage> for BytecodeImage {
150    fn from(value: V1BytecodeImage) -> Self {
151        // This function is mapping an empty string to None for
152        // username and password.
153        let username = if value.username.is_some() {
154            match value.username.unwrap().as_ref() {
155                "" => None,
156                u => Some(u.to_string()),
157            }
158        } else {
159            None
160        };
161        let password = if value.password.is_some() {
162            match value.password.unwrap().as_ref() {
163                "" => None,
164                u => Some(u.to_string()),
165            }
166        } else {
167            None
168        };
169        BytecodeImage::new(value.url, value.image_pull_policy, username, password)
170    }
171}