Repository: libbpf/libbpf-rs (language: rust)

Issue:
Add bpf link functionality
As part of our effort to reach feature parity with libbpf-1.0, add a libbpf-rs interface for interacting with bpf links:

LIBBPF_API struct bpf_link *bpf_link__open(const char *path);
LIBBPF_API const char *bpf_link__pin_path(const struct bpf_link *link);
LIBBPF_API void bpf_link__disconnect(struct bpf_link *link);
LIBBPF_API int bpf_link__detach(struct bpf_link *link);

(https://github.com/libbpf/libbpf/blob/3591deb9bc6b0848721f831790b78ae0a593b4c5/src/libbpf.h#L378-L387)


Discussion / hints:

Fix patch:
diff --git a/libbpf-rs/src/link.rs b/libbpf-rs/src/link.rs
index 5321a9b0..dae40660 100644
--- a/libbpf-rs/src/link.rs
+++ b/libbpf-rs/src/link.rs
@@ -1,4 +1,4 @@
-use std::path::Path;
+use std::path::{Path, PathBuf};
 
 use crate::*;
 
@@ -15,6 +15,20 @@ impl Link {
         Link { ptr }
     }
 
+    /// Create link from BPF FS file.
+    pub fn open<P: AsRef<Path>>(&mut self, path: P) -> Result<Self> {
+        let path_c = util::path_to_cstring(path)?;
+        let path_ptr = path_c.as_ptr();
+        let ptr = unsafe { libbpf_sys::bpf_link__open(path_ptr) };
+
+        let err = unsafe { libbpf_sys::libbpf_get_error(ptr as *const _) };
+        if err != 0 {
+            return Err(Error::System(err as i32));
+        }
+
+        Ok(Link::new(ptr))
+    }
+
     /// Takes ownership from pointer.
     ///
     /// # Safety
@@ -70,6 +84,26 @@ impl Link {
     pub fn fd(&self) -> i32 {
         unsafe { libbpf_sys::bpf_link__fd(self.ptr) }
     }
+
+    /// Returns path to BPF FS file or `None` if not pinned.
+    pub fn pin_path(&self) -> Option<PathBuf> {
+        let path_ptr = unsafe { libbpf_sys::bpf_link__pin_path(self.ptr) };
+        if path_ptr.is_null() {
+            return None;
+        }
+
+        let path = match util::c_ptr_to_string(path_ptr) {
+            Ok(p) => p,
+            Err(_) => return None,
+        };
+
+        Some(PathBuf::from(path.as_str()))
+    }
+
+    pub fn detach(&self) -> Result<()> {
+        let ret = unsafe { libbpf_sys::bpf_link__detach(self.ptr) };
+        util::parse_ret(ret)
+    }
 }
 
 impl Drop for Link {


Test patch: