[Patch, v2, 1/2] BCC: Python: Support 'fmod_ret' method for eBPF

Gang Yan posted 2 patches 8 months, 1 week ago
[Patch, v2, 1/2] BCC: Python: Support 'fmod_ret' method for eBPF
Posted by Gang Yan 8 months, 1 week ago
In kernel, there exists a lot of 'fmod_ret' functions, such as
'update_socket_protocol'. But it cannot attached in BCC-python directly,
so this patch provides an interface for python to use 'fmod_ret'
attaching method.

But there exists a question about how to check 'fmod_ret' support in
kernel, do you have any suggestion? I already considered checking the
kernel version which seems not suitable.

Signed-off-by: Gang Yan <yangang@kylinos.cn>
---
 src/python/bcc/__init__.py | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/src/python/bcc/__init__.py b/src/python/bcc/__init__.py
index 8bc85516..12ce3ef6 100644
--- a/src/python/bcc/__init__.py
+++ b/src/python/bcc/__init__.py
@@ -461,6 +461,7 @@ class BPF(object):
         self.raw_tracepoint_fds = {}
         self.kfunc_entry_fds = {}
         self.kfunc_exit_fds = {}
+        self.fmod_ret_fds = {}
         self.lsm_fds = {}
         self.perf_buffers = {}
         self.open_perf_events = {}
@@ -1157,6 +1158,12 @@ class BPF(object):
             return True
         return False
 
+    @staticmethod
+    def support_fmod_ret():
+        # It is not clear what can be used to check if 'fmod_ret'
+        # is supported by the kernel. Assuming checking kfunc is enough
+        return BPF.support_kfunc()
+
     def detach_kfunc(self, fn_name=b""):
         fn_name = _assert_is_bytes(fn_name)
         fn_name = BPF.add_prefix(b"kfunc__", fn_name)
@@ -1166,6 +1173,15 @@ class BPF(object):
         os.close(self.kfunc_entry_fds[fn_name])
         del self.kfunc_entry_fds[fn_name]
 
+    def detach_fmod_ret(self, fn_name=b""):
+        fn_name = _assert_is_bytes(fn_name)
+        fn_name = BPF.add_prefix(b"kmod_ret__", fn_name)
+
+        if fn_name not in self.fmod_ret_fds:
+            raise Exception("Fmod_ret func %s is not attached" % fn_name)
+        os.close(self.fmod_ret_fds[fn_name])
+        del self.fmod_ret_fds[fn_name]
+
     def detach_kretfunc(self, fn_name=b""):
         fn_name = _assert_is_bytes(fn_name)
         fn_name = BPF.add_prefix(b"kretfunc__", fn_name)
@@ -1189,6 +1205,22 @@ class BPF(object):
         self.kfunc_entry_fds[fn_name] = fd
         return self
 
+    def attach_fmod_ret(self, fn_name=b""):
+        fn_name = _assert_is_bytes(fn_name)
+        fn_name = BPF.add_prefix(b"kmod_ret__", fn_name)
+
+        if fn_name in self.fmod_ret_fds:
+            raise Exception("Fmod_ret func %s has been attached" % fn_name)
+
+        fn = self.load_func(fn_name, BPF.TRACING)
+        fd = lib.bpf_attach_kfunc(fn.fd)
+
+        if fd < 0:
+            raise Exception("Failed to attach BPF to fmod_ret kernel func")
+        self.fmod_ret_fds[fn_name] = fd
+
+        return self
+
     def attach_kretfunc(self, fn_name=b""):
         fn_name = _assert_is_bytes(fn_name)
         fn_name = BPF.add_prefix(b"kretfunc__", fn_name)
@@ -1824,6 +1856,8 @@ class BPF(object):
             self.detach_kretfunc(k)
         for k, v in list(self.lsm_fds.items()):
             self.detach_lsm(k)
+        for k, v in list(self.fmod_ret_fds.items()):
+            self.detach_fmod_ret(k)
 
         # Clean up opened perf ring buffer and perf events
         table_keys = list(self.tables.keys())
-- 
2.25.1
Re: [Patch, v2, 1/2] BCC: Python: Support 'fmod_ret' method for eBPF
Posted by Matthieu Baerts 8 months, 1 week ago
Hi Gang,

On 09/04/2025 09:17, Gang Yan wrote:
> In kernel, there exists a lot of 'fmod_ret' functions, such as
> 'update_socket_protocol'. But it cannot attached in BCC-python directly,
> so this patch provides an interface for python to use 'fmod_ret'
> attaching method.
> 
> But there exists a question about how to check 'fmod_ret' support in
> kernel, do you have any suggestion? I already considered checking the
> kernel version which seems not suitable.
> 
> Signed-off-by: Gang Yan <yangang@kylinos.cn>
> ---
>  src/python/bcc/__init__.py | 34 ++++++++++++++++++++++++++++++++++
>  1 file changed, 34 insertions(+)
> 
> diff --git a/src/python/bcc/__init__.py b/src/python/bcc/__init__.py
> index 8bc85516..12ce3ef6 100644
> --- a/src/python/bcc/__init__.py
> +++ b/src/python/bcc/__init__.py

(...)

> @@ -1189,6 +1205,22 @@ class BPF(object):
>          self.kfunc_entry_fds[fn_name] = fd
>          return self
>  
> +    def attach_fmod_ret(self, fn_name=b""):
> +        fn_name = _assert_is_bytes(fn_name)
> +        fn_name = BPF.add_prefix(b"kmod_ret__", fn_name)
> +
> +        if fn_name in self.fmod_ret_fds:
> +            raise Exception("Fmod_ret func %s has been attached" % fn_name)
Detail: maybe clearer with this:

  "Fmod_ret func %s is already attached"

(...)

Cheers,
Matt
-- 
Sponsored by the NGI0 Core fund.
Re: [Patch, v2, 1/2] BCC: Python: Support 'fmod_ret' method for eBPF
Posted by Gang Yan 8 months, 1 week ago
On Wed, Apr 09, 2025 at 10:26:23AM +0200, Matthieu Baerts wrote:
Hi Matt,
> Hi Gang,
> 
> On 09/04/2025 09:17, Gang Yan wrote:
> > In kernel, there exists a lot of 'fmod_ret' functions, such as
> > 'update_socket_protocol'. But it cannot attached in BCC-python directly,
> > so this patch provides an interface for python to use 'fmod_ret'
> > attaching method.
> > 
> > But there exists a question about how to check 'fmod_ret' support in
> > kernel, do you have any suggestion? I already considered checking the
> > kernel version which seems not suitable.
> > 
> > Signed-off-by: Gang Yan <yangang@kylinos.cn>
> > ---
> >  src/python/bcc/__init__.py | 34 ++++++++++++++++++++++++++++++++++
> >  1 file changed, 34 insertions(+)
> > 
> > diff --git a/src/python/bcc/__init__.py b/src/python/bcc/__init__.py
> > index 8bc85516..12ce3ef6 100644
> > --- a/src/python/bcc/__init__.py
> > +++ b/src/python/bcc/__init__.py
> 
> (...)
> 
> > @@ -1189,6 +1205,22 @@ class BPF(object):
> >          self.kfunc_entry_fds[fn_name] = fd
> >          return self
> >  
> > +    def attach_fmod_ret(self, fn_name=b""):
> > +        fn_name = _assert_is_bytes(fn_name)
> > +        fn_name = BPF.add_prefix(b"kmod_ret__", fn_name)
> > +
> > +        if fn_name in self.fmod_ret_fds:
> > +            raise Exception("Fmod_ret func %s has been attached" % fn_name)
> Detail: maybe clearer with this:
> 
>   "Fmod_ret func %s is already attached"
> 
> (...)
>
In BCC's attach_kfunc:
	if fn_name in self.kfunc_entry_fds:
            raise Exception("Kernel entry func %s has been attached" % fn_name)
So I think it's better to keep the same with it.

I agree with your view that mptcpify.py should, by default, enforce the
use of MPTCP for all applications, and this feature will be incorporated
before it is integrated into BCC tools.

The PR link:
https://github.com/iovisor/bcc/pull/5274

Thanks!
Best wishes!
Gang
> Cheers,
> Matt
> -- 
> Sponsored by the NGI0 Core fund.
> 
>