Skip to content

Commit

Permalink
Merge pull request #7459 from rancher-sandbox/change-veth-pair-ip
Browse files Browse the repository at this point in the history
Change veth pair ip
  • Loading branch information
Nino-K authored Sep 12, 2024
2 parents cced1b8 + 1e90eef commit bcac1f4
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 37 deletions.
8 changes: 1 addition & 7 deletions bats/tests/registry/creds.bats
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,7 @@ local_setup() {
# Essentially localhost, but needs to be a routable IP that also works
# from inside a container. Will be turned into a DNS name using sslip.io.
if is_windows; then
if using_networking_tunnel; then
# When using network tunnel, use a fixed address.
ipaddr="192.168.1.2"
else
# In WSL all distros have the same IP address
ipaddr="$(ip a show eth0 | awk '/inet / {sub("/.*",""); print $2}')"
fi
ipaddr="192.168.143.1"
else
# Lima uses a fixed hard-coded IP address
ipaddr="192.168.5.15"
Expand Down
16 changes: 8 additions & 8 deletions docs/networking/windows/rancher-desktop-networking.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,24 @@ end
subgraph netNs["Isolated Network Namespace"]
vsockVM{"VM Switch"}
tapDevice("eth0")
veth-rd1("veth-rd1")
veth-rd-ns("veth-rd-ns")
containers["containers"]
services["services"]
end
subgraph WSL["WSL"]
netNs
other-distro(("Other Distros"))
veth-rd0("veth-rd0")
veth-rd-wsl("veth-rd-wsl")
wsl-proxy{"wsl-proxy"}
end
vsockHost <----> eth & dns
eth <----> syscall
vsockHost ----> portForwarding
tapDevice -- ethernet frames --> vsockVM
veth-rd1 -- ethernet frames --> vsockVM
veth-rd0 <----> veth-rd1
veth-rd-ns -- ethernet frames --> vsockVM
veth-rd-wsl <----> veth-rd-ns
other-distro <----> wsl-proxy
wsl-proxy <----> veth-rd0
wsl-proxy <----> veth-rd-wsl
containers <----> tapDevice
services <----> tapDevice
vsockVM <-- AF_VSOCK ---> vsockHost
Expand All @@ -61,7 +61,7 @@ The host-switch runs on the Windows host and acts as a receiver for all traffic

The reason for its creation was that the `AF_VSOCK` connection could not be established between the host and a process residing inside the network namespace within the VM, as such capability is not currently supported by `AF_VSOCK`. As a result, the network setup was created. Its main responsibility is to respond to the handshake request from the `host-switch.exe`. Once the handshake process is successful with the `host-switch`, the `network-setup` process creates a new network namespace and attempts to start its subprocess, `vm-switch`, in the newly created network namespace. It also hands over the `AF_VSOCK` connection to the `vm-switch` as a file descriptor in the new namespace.

Additionally, it calls unshare with provided arguments through [---unshare-args](https://github.com/rancher-sandbox/rancher-desktop/blob/6abacdc804d6414f17439a97f22e0c9c87f6249d/cmd/network/setup_linux.go#L272). The process also establishes a Virtual Ethernet pair consisting of two endpoints: `veth-rd0` and `veth-rd1`. `veth-rd0` resides within the default namespace and is configured to listen on the IP address `192.168.1.1`. Conversely, `veth-rd1` is located within a network namespace and is assigned the IP address `192.168.1.2`. The virtual Ethernet pair allows accessibility from the default network into the network namespace, which is particularly useful when WSL integration is enabled.
Additionally, it calls unshare with provided arguments through [---unshare-args](https://github.com/rancher-sandbox/rancher-desktop/blob/6abacdc804d6414f17439a97f22e0c9c87f6249d/cmd/network/setup_linux.go#L272). The process also establishes a Virtual Ethernet pair consisting of two endpoints: `veth-rd-ns` and `veth-rd-wsl`. `veth-rd-wsl` resides within the default namespace and is configured to listen on the IP address `192.168.143.2`. Conversely, `veth-rd-ns` is located within a network namespace and is assigned the IP address `192.168.143.1`. The virtual Ethernet pair allows accessibility from the default network into the network namespace, which is particularly useful when WSL integration is enabled.

## Supported Flags:

Expand All @@ -83,7 +83,7 @@ Additionally, it calls unshare with provided arguments through [---unshare-args]

## vm-switch:

Once the network-setup starts the `vm-switch` process in the new namespace, the `vm-switch` creates a tap device (`eth0`) and a loopback device (`lo`). When the `eth0` tap device is successfully created, it uses the `DHCP` client to acquire an IP address within the defined range from the `DHCP` server. Once the `eth0` tap device is up and running, the kernel forwards all raw Ethernet frames originating from the network namespace to the tap device. In addition to the traffic from the network namespace, the kernel also forwards all the traffic that arrives at `veth-rd1` from its pair, `veth-rd0`, in the default namespace.
Once the network-setup starts the `vm-switch` process in the new namespace, the `vm-switch` creates a tap device (`eth0`) and a loopback device (`lo`). When the `eth0` tap device is successfully created, it uses the `DHCP` client to acquire an IP address within the defined range from the `DHCP` server. Once the `eth0` tap device is up and running, the kernel forwards all raw Ethernet frames originating from the network namespace to the tap device. In addition to the traffic from the network namespace, the kernel also forwards all the traffic that arrives at `veth-rd-ns` from its pair, `veth-rd-wsl`, in the default namespace.

The tap device forwards the Ethernet frames over [vsock](https://wiki.qemu.org/Features/VirtioVsock) to the host. The process on the host (`host-switch.exe`) decapsulates the frames. Since host-switch maintains both internal (`vm-switch` to `host-switch.exe`) and external (`host-switch.exe` to the internet) connections, it connects to the external endpoints via syscalls.

Expand Down Expand Up @@ -111,7 +111,7 @@ Its primary function comes into play when WSL integration is activated alongside

- **socketFile**: This is the path to the `.sock` file for the UNIX socket connection established between the Rancher Desktop guest agent and the `wsl-proxy`. If not provided, the default value of `/run/wsl-proxy.sock` is used.

- **upstreamAddress**: This is the IP address associated with the upstream server to use. It corresponds to the address of the veth pair connecting the default namespace to the network namespace, specifically `veth-rd1`. The default value is `192.168.1.2`.
- **upstreamAddress**: This is the IP address associated with the upstream server to use. It corresponds to the address of the veth pair connecting the default namespace to the network namespace, specifically `veth-rd-ns`. The default value is `192.168.143.1`.


## Process Timelines:
Expand Down
4 changes: 2 additions & 2 deletions pkg/rancher-desktop/backend/wsl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1360,8 +1360,8 @@ export default class WSLBackend extends events.EventEmitter implements VMBackend
k3sConf.ADDITIONAL_ARGS += ' --tls-san host.rancher-desktop.internal';
k3sConf.ADDITIONAL_ARGS += ' --tls-san host.docker.internal';

// Add the `veth-rd1` IP address from inside the namespace
k3sConf.ADDITIONAL_ARGS += ' --tls-san 192.168.1.2';
// Add the `veth-rd-ns` IP address from inside the namespace
k3sConf.ADDITIONAL_ARGS += ' --tls-san 192.168.143.1';

if (!config.kubernetes.options.flannel) {
console.log(`Disabling flannel and network policy`);
Expand Down
2 changes: 1 addition & 1 deletion src/go/networking/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ portForwarding["Port Forwarding"]
`host-switch` runs on the Windows host and acts as a receiver for all traffic originating from the network namespace within the WSL VM. It performs a handshake to find the right VM to talk to over `AF_VSOCK`. Once a correct VM is found, it then listens for the incoming traffic from that VM. In addition to this, it can provide a DNS resolver that runs in the user space network along with an API that allows for dynamic port forwarding.

## network-setup
Its main responsibility is to respond to the handshake request from the `host-switch.exe`, create a network namespace and start the `vm-switch` subprocess in the newly created network namespace. In addition, it also calls unshare with provided arguments through `--unshare-args`. Below is a sequence diagram demonstrating the process. The process also establishes a Virtual Ethernet pair consisting of two endpoints: `veth-rd0` and `veth-rd1`. `veth-rd0` resides within the default namespace and is configured to listen on the IP address `192.168.1.1`. Conversely, `veth-rd1` is located within a network namespace and is assigned the IP address `192.168.1.2`.
Its main responsibility is to respond to the handshake request from the `host-switch.exe`, create a network namespace and start the `vm-switch` subprocess in the newly created network namespace. In addition, it also calls unshare with provided arguments through `--unshare-args`. Below is a sequence diagram demonstrating the process. The process also establishes a Virtual Ethernet pair consisting of two endpoints: `veth-rd-wsl` and `veth-rd-ns`. `veth-rd-wsl` resides within the WSL's default namespace and is configured to listen on the IP address `192.168.143.2`. Conversely, `veth-rd-ns` is located within a network namespace and is assigned the IP address `192.168.143.1`.

## vm-switch
Once the `vm-switch` process starts in the new namespace, it creates a tap (`eth0`) and a `lo` device. The Kernel then forwards all the raw Ethernet frames to the tap device. The tap device forwards the frames over [vsock](https://wiki.qemu.org/Features/VirtioVsock) to the host. The process on the host (`host-switch.exe`) decapsulates the frames, and since it maintains both internal (`vm-switch` to `host-switch.exe`) and external (`host-switch.exe` to the internet) connections, it connects to the external endpoints via normal syscalls.
Expand Down
38 changes: 20 additions & 18 deletions src/go/networking/cmd/network/setup_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,18 @@ var (
)

const (
nsenter = "/usr/bin/nsenter"
unshare = "/usr/bin/unshare"
vsockHandshakePort = 6669
vsockDialPort = 6656
defaultTapDevice = "eth0"
defaultNSVeth = "veth-rd0"
rancherDesktopNSVeth = "veth-rd1"
defaultNamespacePID = 1
cidrOnes = 24
cidrBits = 32
nsenter = "/usr/bin/nsenter"
unshare = "/usr/bin/unshare"
vsockHandshakePort = 6669
vsockDialPort = 6656
defaultTapDevice = "eth0"
WSLVeth = "veth-rd-wsl"
WSLVethIP = "192.168.143.2"
namespaceVeth = "veth-rd-ns"
namespaceVethIP = "192.168.143.1"
defaultNamespacePID = 1
cidrOnes = 24
cidrBits = 32
)

func main() {
Expand Down Expand Up @@ -126,23 +128,23 @@ func main() {

err = createVethPair(defaultNamespacePID,
vmSwitchCmd.Process.Pid,
defaultNSVeth,
rancherDesktopNSVeth)
WSLVeth,
namespaceVeth)
if err != nil {
logrus.Fatalf("failed to create veth pair: %v", err)
}
defer cleanupVethLink(originNS)

if err := configureVethPair(rancherDesktopNSVeth, "192.168.1.2"); err != nil {
logrus.Fatalf("failed setting up veth: %s for rancher desktop namespace: %v", rancherDesktopNSVeth, err)
if err := configureVethPair(namespaceVeth, namespaceVethIP); err != nil {
logrus.Fatalf("failed setting up veth: %s for rancher desktop namespace: %v", namespaceVeth, err)
}

// switch back to the original namespace to configure veth0
if err := netns.Set(originNS); err != nil {
logrus.Fatalf("failed to switch back to original namespace: %v", err)
}
if err := configureVethPair(defaultNSVeth, "192.168.1.1"); err != nil {
logrus.Fatalf("failed setting up veth: %s for rancher desktop namespace: %v", rancherDesktopNSVeth, err)
if err := configureVethPair(WSLVeth, WSLVethIP); err != nil {
logrus.Fatalf("failed setting up veth: %s for rancher desktop namespace: %v", WSLVeth, err)
}

if err := originNS.Close(); err != nil {
Expand Down Expand Up @@ -237,9 +239,9 @@ func cleanupVethLink(originNS netns.NsHandle) {
// First, though, switch back to the default namespace if available.
// This would fail if we already switched to it (and closed the handle).
_ = netns.Set(originNS)
if link, err := netlink.LinkByName(defaultNSVeth); err == nil {
if link, err := netlink.LinkByName(WSLVeth); err == nil {
err = netlink.LinkDel(link)
logrus.Infof("tearing down link %s: %v", defaultNSVeth, err)
logrus.Infof("tearing down link %s: %v", WSLVeth, err)
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/go/networking/cmd/proxy/wsl_integration_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ var (
const (
defaultLogPath = "/var/log/wsl-proxy.log"
defaultSocket = "/run/wsl-proxy.sock"
bridgeIPAddr = "192.168.1.2"
bridgeIPAddr = "192.168.143.1"
)

func main() {
Expand Down

0 comments on commit bcac1f4

Please sign in to comment.