sysprog21 / semu

A minimalist RISC-V system emulator capable of running Linux kernel
MIT License
252 stars 47 forks source link

Enable user-mode networking for unprivileged network namespaces #40

Open jserv opened 8 months ago

jserv commented 8 months ago

Beginning with version 3.8 of Linux, users without privileged access have been able to create network_namespaces and user_namespaces. Despite this, the utility of unprivileged network namespaces was limited because the creation of virtual ethernet (veth) pairs, which bridge the host and network namespaces, still demanded root access, effectively barring internet connectivity.

The slirp4netns provides a solution to this limitation by enabling an unprivileged connection of a network namespace to the internet. It achieves this by linking a TAP device within a network namespace to a TCP/IP stack operating in user mode, known as slirp, thereby facilitating internet access without the need for root privileges. This means that it is feasible for users to integrate slirp4netns to run a RISC-V/Linux guest with full user-mode networking.

Reference:

chiangkd commented 1 week ago

The slirp4netns utility connects a TAP device within a network namespace and sends packets to the host network stack through this device.

/* implements SlirpCb.send_packet */
static ssize_t libslirp_send_packet(const void *pkt, size_t pkt_len,
                                    void *opaque)
{
    struct libslirp_data *data = (struct libslirp_data *)opaque;
    return write(data->tapfd, pkt, pkt_len);
}

In the context of SEMU, to send packets to the host through a TAP device, I need to create a separate process (child) that uses unshare to establish a new network namespace. This can be done with the flags CLONE_NEWUSER | CLONE_NEWNET, while the kernel operations are managed by the parent process.

For reference, I examined the QEMU/slirp.c and libvdeslirp library. Functions like slirp_add_hostfwd and slirp_add_guestfwd are used to create port forwarding rules.

Is it possible to forward traffic from eth0 in the VM to the host machine?

jserv commented 1 week ago

In the context of SEMU, to send packets to the host through a TAP device, I need to create a separate process (child) that uses unshare to establish a new network namespace. This can be done with the flags CLONE_NEWUSER | CLONE_NEWNET, while the kernel operations are managed by the parent process.

You can send a pull request to consolidate the existing TAP based network device. Then, move forward to slirp.