MPTCP Linux Development
 help / color / mirror / Atom feed
* [Patch, v2, 0/2] BCC: python: support fmod_ret
@ 2025-04-09  7:17 Gang Yan
  2025-04-09  7:17 ` [Patch, v2, 1/2] BCC: Python: Support 'fmod_ret' method for eBPF Gang Yan
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Gang Yan @ 2025-04-09  7:17 UTC (permalink / raw)
  To: mptcp; +Cc: Gang Yan

Support fmod_ret, and add a useful tool for mptcp, also
the interface can be verified with this function.

------
Changelog:
  v2:
    - change the name of the tool to 'mptcpify'
    - fix the code style problems in mptcpify.py
    - modify 'support_fmod_ret' in __init__.py, add some comment and
      ask for suggestions to BCC devs.

Hi Matt:

So nice to recieve your reply. Do you think we can create a PR with v2
patch to BCC now? The description of PR is attached below, Can you help
me to take a look?

'''
Multipath TCP (MPTCP) serves as an enhancement to the conventional TCP
protocol, enabling a single transport-layer connection to leverage
multiple network interfaces. This capability makes MPTCP advantageous
for applications requiring bandwidth consolidation, seamless failover
mechanisms, and more robust connectivity solutions.

Linux kernel starts to support MPTCP since v5.6, and it provides a
fmod_ret interface 'update_socket_protocol' to force applications using
MPTCP instead of TCP without modifyiing its code.

So these patches provide a tool named 'mptcpify' which can achieve this.
Using python-BCC is a more easy way for future development, so it is so
important to support 'fmod_ret' in python-BCC.

@matttbe from the MPTCP kernel team had a look at the new tool.
'''

Gang Yan (2):
  BCC: Python: Support 'fmod_ret' method for eBPF
  BCC: python: add a useful tool for mptcp

 src/python/bcc/__init__.py | 34 ++++++++++++++++
 tools/mptcpify.py          | 80 ++++++++++++++++++++++++++++++++++++++
 tools/mptcpify.txt         | 22 +++++++++++
 3 files changed, 136 insertions(+)
 create mode 100644 tools/mptcpify.py
 create mode 100644 tools/mptcpify.txt

-- 
2.25.1


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Patch, v2, 1/2] BCC: Python: Support 'fmod_ret' method for eBPF
  2025-04-09  7:17 [Patch, v2, 0/2] BCC: python: support fmod_ret Gang Yan
@ 2025-04-09  7:17 ` Gang Yan
  2025-04-09  8:26   ` Matthieu Baerts
  2025-04-09  7:17 ` [Patch, v2, 2/2] BCC: python: add a useful tool for mptcp Gang Yan
  2025-04-09  8:26 ` [Patch, v2, 0/2] BCC: python: support fmod_ret Matthieu Baerts
  2 siblings, 1 reply; 7+ messages in thread
From: Gang Yan @ 2025-04-09  7:17 UTC (permalink / raw)
  To: mptcp; +Cc: Gang Yan

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


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [Patch, v2, 2/2] BCC: python: add a useful tool for mptcp
  2025-04-09  7:17 [Patch, v2, 0/2] BCC: python: support fmod_ret Gang Yan
  2025-04-09  7:17 ` [Patch, v2, 1/2] BCC: Python: Support 'fmod_ret' method for eBPF Gang Yan
@ 2025-04-09  7:17 ` Gang Yan
  2025-04-09  8:26   ` Matthieu Baerts
  2025-04-09  8:26 ` [Patch, v2, 0/2] BCC: python: support fmod_ret Matthieu Baerts
  2 siblings, 1 reply; 7+ messages in thread
From: Gang Yan @ 2025-04-09  7:17 UTC (permalink / raw)
  To: mptcp; +Cc: Gang Yan

Multipath TCP (MPTCP) is an extension of the standard TCP protocol
that allows a single transport connection to use multiple network
interfaces or paths. MPTCP is useful for applications like bandwidth
aggregation, failover, and more resilient connections.

Linux kernel starts to support MPTCP since v5.6, this patch provides
a method which can easily force applications use MPTCP socket without
modifing its code.

Signed-off-by: Gang Yan <yangang@kylinos.cn>
---
 tools/mptcpify.py  | 80 ++++++++++++++++++++++++++++++++++++++++++++++
 tools/mptcpify.txt | 22 +++++++++++++
 2 files changed, 102 insertions(+)
 create mode 100644 tools/mptcpify.py
 create mode 100644 tools/mptcpify.txt

diff --git a/tools/mptcpify.py b/tools/mptcpify.py
new file mode 100644
index 00000000..efdbd910
--- /dev/null
+++ b/tools/mptcpify.py
@@ -0,0 +1,80 @@
+#!/usr/bin/env python
+#
+# mptcpify Make the applications to use MPTCP.
+#           For Linux, uses BCC, eBPF. Embedded C.
+#
+# USAGE: mptcpify -t
+#
+# Copyright 2025 Kylin Software, Inc.
+# Licensed under the Apache License, Version 2.0 (the "License")
+#
+# 05-Apr-2025   Gang Yan   Created this.
+
+import ctypes as ct
+import argparse
+import signal
+import time
+
+from bcc import BPF
+
+#arguments
+parser = argparse.ArgumentParser(
+         description="mptcpify try to force applications to use MPTCP instead of TCP")
+parser.add_argument("-t", "--targets", required=True, type=str,
+                    help="use ',' for multi targets, eg: 'iperf3,rsync'")
+
+args_str = parser.parse_args()
+args_list = [t.strip() for t in args_str.targets.split(',')]
+
+if (not BPF.support_fmod_ret()):
+    print("Your kernel version is too old,"
+          " fmod_ret method is only support kernel v5.7 and later.")
+    exit()
+
+TASK_COMM_LEN = 18
+
+class app_name(ct.Structure):
+    _fields_ = [("str", ct.c_char * TASK_COMM_LEN)]
+
+# define BPF program
+prog = """
+#include <linux/net.h>
+#include <uapi/linux/in.h>
+#include <linux/string.h>
+
+struct app_name {
+    char name[TASK_COMM_LEN];
+};
+
+BPF_HASH(support_apps, struct app_name);
+
+KMOD_RET(update_socket_protocol, int family, int type, int protocol, int ret)
+{
+    struct app_name target = {};
+    bpf_get_current_comm(&target.name, TASK_COMM_LEN);
+
+    if ((family == AF_INET || family == AF_INET6) &&
+        type == SOCK_STREAM &&
+        (!protocol || protocol == IPPROTO_TCP) &&
+        support_apps.lookup(&target))
+        return IPPROTO_MPTCP;
+
+    return protocol;
+
+}
+
+"""
+
+b = BPF(text=prog)
+b.attach_fmod_ret("update_socket_protocol")
+
+support_apps = b.get_table("support_apps")
+for i in args_list:
+    app = i.encode()
+    name = app_name()
+    name.str = app[:TASK_COMM_LEN-1].ljust(TASK_COMM_LEN, b'\0')
+    support_apps[name] = ct.c_uint32(1)
+
+print("MPTCP is been forced for ", args_list);
+signal.pause()
+
diff --git a/tools/mptcpify.txt b/tools/mptcpify.txt
new file mode 100644
index 00000000..adef70ea
--- /dev/null
+++ b/tools/mptcpify.txt
@@ -0,0 +1,22 @@
+Demonstrations of mptcpify, the Linux eBPF/bcc version.
+
+
+mptcpify forces the application to use to MPTCP instead of TCP.
+
+mptcpify has been verified with iperf3 and rsync[TCP module]. It can be used
+for incresing the speed of transferring data with rsync.
+
+The MPTCP configuration is decribed in
+https://www.mptcp.dev/pm.html
+
+USAGE message:
+
+usage: sudo python ./mptcpify.py [-h] -t TARGETS
+
+mptcpify try to force applications to use MPTCP instead of TCP
+
+options:
+  -h, --help            show this help message and exit
+  -t TARGETS, --targets TARGETS
+                        use ',' for multi targets, eg: 'iperf3,rsync'
+
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [Patch, v2, 0/2] BCC: python: support fmod_ret
  2025-04-09  7:17 [Patch, v2, 0/2] BCC: python: support fmod_ret Gang Yan
  2025-04-09  7:17 ` [Patch, v2, 1/2] BCC: Python: Support 'fmod_ret' method for eBPF Gang Yan
  2025-04-09  7:17 ` [Patch, v2, 2/2] BCC: python: add a useful tool for mptcp Gang Yan
@ 2025-04-09  8:26 ` Matthieu Baerts
  2 siblings, 0 replies; 7+ messages in thread
From: Matthieu Baerts @ 2025-04-09  8:26 UTC (permalink / raw)
  To: Gang Yan, mptcp

Hi Gang,

On 09/04/2025 09:17, Gang Yan wrote:
> Support fmod_ret, and add a useful tool for mptcp, also
> the interface can be verified with this function.
> 
> ------
> Changelog:
>   v2:
>     - change the name of the tool to 'mptcpify'
>     - fix the code style problems in mptcpify.py
>     - modify 'support_fmod_ret' in __init__.py, add some comment and
>       ask for suggestions to BCC devs.
> 
> Hi Matt:
> 
> So nice to recieve your reply. Do you think we can create a PR with v2
> patch to BCC now? The description of PR is attached below, Can you help
> me to take a look?

Thank you for the v2. I have just some small comments, but it is not
blocking, the rest looks good to me.

Then yes, please create the PR, no need to send a v3.

Cheers,
Matt
-- 
Sponsored by the NGI0 Core fund.


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Patch, v2, 1/2] BCC: Python: Support 'fmod_ret' method for eBPF
  2025-04-09  7:17 ` [Patch, v2, 1/2] BCC: Python: Support 'fmod_ret' method for eBPF Gang Yan
@ 2025-04-09  8:26   ` Matthieu Baerts
  2025-04-09  9:29     ` Gang Yan
  0 siblings, 1 reply; 7+ messages in thread
From: Matthieu Baerts @ 2025-04-09  8:26 UTC (permalink / raw)
  To: Gang Yan, mptcp

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.


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Patch, v2, 2/2] BCC: python: add a useful tool for mptcp
  2025-04-09  7:17 ` [Patch, v2, 2/2] BCC: python: add a useful tool for mptcp Gang Yan
@ 2025-04-09  8:26   ` Matthieu Baerts
  0 siblings, 0 replies; 7+ messages in thread
From: Matthieu Baerts @ 2025-04-09  8:26 UTC (permalink / raw)
  To: Gang Yan, mptcp

Hi Gang,

On 09/04/2025 09:17, Gang Yan wrote:
> Multipath TCP (MPTCP) is an extension of the standard TCP protocol
> that allows a single transport connection to use multiple network
> interfaces or paths. MPTCP is useful for applications like bandwidth
> aggregation, failover, and more resilient connections.
> 
> Linux kernel starts to support MPTCP since v5.6, this patch provides
> a method which can easily force applications use MPTCP socket without
> modifing its code.
> 
> Signed-off-by: Gang Yan <yangang@kylinos.cn>
> ---
>  tools/mptcpify.py  | 80 ++++++++++++++++++++++++++++++++++++++++++++++
>  tools/mptcpify.txt | 22 +++++++++++++
>  2 files changed, 102 insertions(+)
>  create mode 100644 tools/mptcpify.py
>  create mode 100644 tools/mptcpify.txt
> 
> diff --git a/tools/mptcpify.py b/tools/mptcpify.py
> new file mode 100644
> index 00000000..efdbd910
> --- /dev/null
> +++ b/tools/mptcpify.py
> @@ -0,0 +1,80 @@
> +#!/usr/bin/env python
> +#
> +# mptcpify Make the applications to use MPTCP.
> +#           For Linux, uses BCC, eBPF. Embedded C.
> +#
> +# USAGE: mptcpify -t
> +#
> +# Copyright 2025 Kylin Software, Inc.
> +# Licensed under the Apache License, Version 2.0 (the "License")
> +#
> +# 05-Apr-2025   Gang Yan   Created this.
> +
> +import ctypes as ct
> +import argparse
> +import signal
> +import time
> +
> +from bcc import BPF
> +
> +#arguments
> +parser = argparse.ArgumentParser(
> +         description="mptcpify try to force applications to use MPTCP instead of TCP")
> +parser.add_argument("-t", "--targets", required=True, type=str,
> +                    help="use ',' for multi targets, eg: 'iperf3,rsync'")

If it is easy for you to have this argument optional, don't hesitate to
add this support: I think it will be useful to have this mode
"everything is forced to use MPTCP".

(...)

> +b = BPF(text=prog)
> +b.attach_fmod_ret("update_socket_protocol")
> +
> +support_apps = b.get_table("support_apps")
> +for i in args_list:
> +    app = i.encode()
> +    name = app_name()
> +    name.str = app[:TASK_COMM_LEN-1].ljust(TASK_COMM_LEN, b'\0')
> +    support_apps[name] = ct.c_uint32(1)
> +
> +print("MPTCP is been forced for ", args_list);

Detail: maybe better with "is being forced".

Cheers,
Matt
-- 
Sponsored by the NGI0 Core fund.


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Patch, v2, 1/2] BCC: Python: Support 'fmod_ret' method for eBPF
  2025-04-09  8:26   ` Matthieu Baerts
@ 2025-04-09  9:29     ` Gang Yan
  0 siblings, 0 replies; 7+ messages in thread
From: Gang Yan @ 2025-04-09  9:29 UTC (permalink / raw)
  To: Matthieu Baerts; +Cc: mptcp

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.
> 
> 

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2025-04-09  9:29 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-04-09  7:17 [Patch, v2, 0/2] BCC: python: support fmod_ret Gang Yan
2025-04-09  7:17 ` [Patch, v2, 1/2] BCC: Python: Support 'fmod_ret' method for eBPF Gang Yan
2025-04-09  8:26   ` Matthieu Baerts
2025-04-09  9:29     ` Gang Yan
2025-04-09  7:17 ` [Patch, v2, 2/2] BCC: python: add a useful tool for mptcp Gang Yan
2025-04-09  8:26   ` Matthieu Baerts
2025-04-09  8:26 ` [Patch, v2, 0/2] BCC: python: support fmod_ret Matthieu Baerts

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox