Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement psock_update_sk_prot, for eBPF SOCKMAP support #521

Open
skeggse opened this issue Oct 14, 2024 · 2 comments
Open

Implement psock_update_sk_prot, for eBPF SOCKMAP support #521

skeggse opened this issue Oct 14, 2024 · 2 comments

Comments

@skeggse
Copy link

skeggse commented Oct 14, 2024

I'd like to "splice" TCP and MPTCP sockets together using an eBPF SOCKMAP in a BPF_SK_SKB_STREAM_VERDICT program.

I managed to get a program compiled and loaded that did just that, but when running it I got an obscure errno 95 ("Operation not supported").

After some hunting, I found the following in the bpf syscall implementation:

if (!sock_map_sk_is_suitable(sk)) {
ret = -EOPNOTSUPP;
goto out;
}

static bool sock_map_sk_is_suitable(const struct sock *sk)
{
return !!sk->sk_prot->psock_update_sk_prot;
}

I couldn't find an implementation of psock_update_sk_prot for MPTCP either upstream or in this repository, so I'm guessing that's the cause of the issue I'm seeing. I really have no idea what psock_update_sk_prot is supposed to do - I'm a user, not a Kernel developer, but I'd love to be able to add my MPTCP sockets to a socket map!

Curious if there are implementation challenges to doing this, or if this is simply a yet-unimplemented method.

@skeggse skeggse changed the title Implement psock_update_sk_prot for eBPF SOCKMAP support Implement psock_update_sk_prot, for eBPF SOCKMAP support Oct 14, 2024
@matttbe
Copy link
Member

matttbe commented Oct 14, 2024

Hi,

Thank you for having created this issue.

It looks like it is an important missing feature, I guess nobody took the time to implement that. Do you have a small example on how to use this feature from the user space?

@skeggse
Copy link
Author

skeggse commented Oct 15, 2024

Yeah! Here's an example using Python and bcc.

import ctypes
import socket

from bcc import lib, BPF

b = BPF(
  text="""\
struct sock_key {
  u64 cookie;
};

BPF_SOCKHASH(my_hash, struct sock_key, 65535);
"""
)

map_fd = lib.bpf_table_fd(b.module, b"my_hash")

# Fairly arbitrary for this example.
class sock_key(ctypes.Structure):
  _fields_ = [("cookie", ctypes.c_uint64)]

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_MPTCP)

# Returns -95, in part due to the missing psock_update_sk_prot implementation.
lib.bpf_update_elem(map_fd, ctypes.byref(sock_key(0)), ctypes.byref(ctypes.c_int(sock.fileno())), 0)

For a more worked example, see https://github.com/skeggse/mptcp-ebpf-proxy - the above example shows some of the necessary steps, but is not sufficient because:

  • we never attach a program to the eBPF map
  • we never connect the socket to anything (for TCP, the socket must be in a valid state, which seems like perhaps a useful check to also have for MPTCP)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Needs triage
Development

No branches or pull requests

2 participants