12

I have a Windows 10 with installed WSL2. In WSL2 I have an Ubuntu. I need to work directly from Ubuntu with different adapters that I have in my physical PC and have access to them from Windows. But in WSL2 I have only one virtual adapter. And do not see other adapters when run ifconfig -a. Is there a way to make available/visible all Windows' network adapters inside Ubuntu?

Use case: I have PC with many adapters that physically are connected to the different devices. I need to send signals(requests) to these devices.

1
  • 2
    Side-note: You may want to try to start breaking that ifconfig muscle-memory. It's a deprecated command that has already disappeared from some distributions (openSUSE Leap and Tumbleweed, at least, although many other distros keep it around for compatibility). Try ip link as its modern replacement. Bonus -- ip --color=always link (if you're into that kind of thing -- I think it improves readability). Commented Aug 23, 2021 at 9:03

6 Answers 6

12

As as release 2.0.0 of WSL2, there are two separate networking modes available. The use-case mentioned in this question would now best be handled with the new "Mirrored" networking mode.

Mirrored Mode


Notes:

  • Available in Windows 11 23H2 and WSL2 2.0.0 and later*

  • From @KenvixZure in the comments:

    There are still many issues about mirrored mode. If your application runs fine in NAT mode, don't change it.

    This is good and appreciated advice. Mirrored Mode is a relatively new feature of WSL2 and, while I haven't personally experienced issues directly, it is expected that there will be some issues to work out.


In Mirrored Mode, the network interfaces from Windows are mirrored into WSL2, allowing them to be treated separately again similar to (but improved from) the way they were in WSL1 (mentioned below). Communicating with devices on your local network that are connected to different NICs in the Windows host should now be completely possible with this mode enabled.

To enable Mirrored mode:

  • Add the following to your <windows_user_profile>/.wslconfig:

    [wsl2]
    networkingMode=mirrored
    
  • Exit your WSL distribution

  • Run wsl --shutdown from PowerShell then restart WSL

Running ip addr and ip link should now show you all of the physical interfaces (and some virtual ones as well) from Windows, with the ability to route between them as desired.

Note that WiFi interfaces in Windows will appear at wired NICs in this mode. Some other limitations may apply, but you are at least able to bring these interfaces up and down from within WSL2 (unlike WSL1 mentioned below).

NAT Networking Mode

This was the original answer to this question. It still applies for the default, NAT networking mode. If you are on an older version of Windows and/or WSL, then you'll definitely be in this mode.

As you've seen, WSL1 gives you a better mapping of Windows interfaces to "Linux interfaces", but it's important to understand the differences between WSL1 and WSL2 in this regard:

  • Under WSL1, when a Linux app calls a Linux API, WSL1 is responsible for trying to map this to Windows APIs. So when ifconfig (or ip) trys to call getifaddrs to get the available interfaces, WSL1 pops in the list that the Windows kernel knows about.

  • WSL2, on the other hand, is running a real Linux kernel in a virtualized environment (a subset of Hyper-V). A getifaddrs there enumerates the interfaces that the virtual machine provides to the Linux kernel.

There are advantages and disadvantages to both:

  • The biggest problem in WSL1 is that you are going to be very limited in what you can do with these interfaces. Microsoft's Windows->Linux API mapping only goes so deep when it comes to hardware.

    For instance, even a very basic task like bringing an interface up or down isn't going to work. E.g. sudo ip link set wifi0 down will always return RTNETLINK answers: Operation not permitted. You can't put the interface into promiscuous mode, run WireShark, or anything like that.

  • And WSL2's virtualization means, of course, that you don't even see the Windows interfaces when calling Linux commands. On the other hand, you get full access to the virtual interfaces.

There may be some WSL2 possibilities for you, depending on your use-case. You mentioned that you have multiple interfaces installed, with each connected to a different endpoint device.

The simplest scenario, if it works for you, would simply be to assign a different subnet to each interface in Windows and rely on Windows routing table to handle the packets to the devices based on their IP address. The virtual interface in WSL2 should "just work" and send the packets out to the Windows host for the correct routing.

If that doesn't work, then check out socat as another option. There's a Windows version available (although I haven't tried it), along with the standard Linux one that you'll find available in most distributions. I've had success creating TAP/TUN devices in WSL2 that map to other endpoints, although it's been a while since I've done it and don't quite remember the details off the top of my head. In theory, you could shuffle packages between a socat running on WSL2 and one running on the Windows host itself for more complicated use-cases.

And while it's not part of your use-case, I'll mention this for others who might read this, since it relates to the question. If you need to do something like enable or disable a Windows interface from within WSL (either 1 or 2) for some reason, consider calling out through powershell.exe. E.g.:

powershell.exe -c "Disable-NetAdapter  -name 'Wi-Fi'"

Note that this would need to be done in a UAC-elevated terminal, since WSL cannot do anything (even as root) that your Windows user can't do. Also note that in a UAC-elevated session, you may need to specify the full path to powershell.exe.

Finally, and I say this simply because I've seen some folks be critical of WSL limitations recently, I don't see any of this as a limitation of WSL. You'd run into the same issue with virtual interfaces if running under VMWare, VirtualBox, or any other virtualization environment. IMHO, WSL gives us quite a few more options to at least attempt to deal with this than other virtualization environments do.

4
  • 1
    Thank you a lot. It is one of the most detailed answers that I got on SO :) I added a use case to the question. And yes, you are right, reality is a way more complicate, But the option of setting subnets could be the plan B :) But first I will dive into your response and try to check what can I use. But anyway now it is much more clear for me the whole picture and reasons why it works/does not work in that way.
    – Dmytro Huz
    Commented Aug 24, 2021 at 4:35
  • 1
    There are still many issues about mirrored mode. If your application runs fine in NAT mode, don't change it. Commented Mar 25 at 11:54
  • @KenvixZure Thanks, and good point - I incorporated that into the answer. Commented Mar 25 at 12:02
  • Yes, according to the GitHub repository, it's mostly related to Docker, local loopback, routing, and iptables, for example, you may find that you can't access ports that are mapped from containers (although there's been some workaround, there are still a lot of changes needed). Also, you may find that your service can be accessed by other computers on the LAN, but not by your own computer from 127.0.0.1! Commented Mar 26 at 4:13
3

Negative answer: Not possible in WSL2, you will need to stay with WSL1.

WSL2 is essentially running inside a Hyper-V virtual machine. Its network interface, as in all virtual machines, is, well, virtual.

As a result, WSL2 doesn't see your network cards. Instead you have one virtual Ethernet device. This is because WSL2 is really designed for running and developing Linux applications on Windows, not for accessing the physical hardware.

If you really need to use the physical hardware, you'll need to either use Windows programs directly on Windows, or install a real Linux distro in dual-boot on the real hardware.

The most you can do is switch the WSL2 virtual network adapter from NAT to Bridged. This will give you better access to the network, although still the same one virtual adapter. (For that, see link).

1

Downgrading of WSL version to 1.0 helped to get the same adapter inside Ubuntu. Please, add comments if there is a way to make it in 2.0 version

4
  • Hi, @NotTheDr01ds thank you for our answer :) hm...yes, I tried that command with one of adapters and it really does not work. So does it mean that where is no way to operate with all real adapters through WSL? no matter what version it is
    – Dmytro Huz
    Commented Aug 23, 2021 at 9:02
  • >What's the end-goal? I have PC with many adapters that physically are connected to the different devices. I need to send signals(requests) to these devices. So as far as I understood I can't choose particular adapter and send the request via it from WSL directly?
    – Dmytro Huz
    Commented Aug 23, 2021 at 9:39
  • and thanks for your answers. they are helping me a lot. could you please post a new answer? unfortunately i'm not able to mark it as answer, but at least I can upvote it.
    – Dmytro Huz
    Commented Aug 23, 2021 at 9:41
  • 1
    Thanks @DmytroHuz. Sure thing - I've moved my previous comments to an "answer" for longevity and deleted those comments. I'd also recommend editing the use-case into your question. Can the routes be set up in Windows so that each device has its own IP on a subnet assigned to each adapter? If so, then simply addressing them from within WSL2 should get the requests routed to the right device. I'm guessing it's more complicated than that, though? :-) Commented Aug 23, 2021 at 15:22
0

This is now possible in WSL2 with the tool available at https://github.com/dantmnf/WSLAttachSwitch

Just make one bridge per physical interface with Hyper-V Manager, and then add all your bridges with that tool, and you'll get one interface per "external" interface.

2
0

For older Windows/WSL2 versions I created a tool for exporting any network adapter. Published it here

In brief - AF_HYPERV/AF_VSOCK is used for communication between the host and the guest. Npcap is used on the host for capturing/injecting packets on the real interface. On the guest side - a tuntap mode tap adapters are used to capture/inject packets in the kernel stack.

The current setup that I use it on is:

  • Broadcom BCM5720 on a Dell R220. Access VLAN123 and tagged VLAN130;
  • Used the Add-VMNetworkAdapter and Set-VMNetworkAdapterVlan to create the respective Hyper-V adapters;
  • Used the above tools to make these adapters available to WSL2;
  • On the virtual adapters (Hyper-V Virtual Ethernet Adapter) I had to disable Recv Segment Coalescing as otherwise "jumbo frames" happen to be captured by pcap and injecting these into the linux tap does not work with the standard MTU.
0

This is a solution to allow seamless interoperability between your network and WSL.

https://github.com/Unsigned-Char/WSL2HyperVSwitch

Recipe: Persistent Network Configuration in WSL 2 using Hyper-V Virtual Switch

Problem Description

Connecting to services running in WSL 2 from external sources can be challenging due to the instances being on a different network. This guide offers a solution to replace the internal virtual switch of WSL 2 with an external version in Windows 20H2 (WSL 2.0) and configure it for better networking control.

Solution Overview

This recipe uses a Hyper-V virtual switch to bridge the WSL 2 network, providing improved control and visibility of Windows' network adapters within Ubuntu. The configuration supports both dynamic and static IP addressing, eliminating the need for port forwarding and simplifying network setup.

Steps

  1. Enable Hyper-V and Management PowerShell Features:

    • Open PowerShell as administrator and run:
      Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V
      Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V-Management-PowerShell
      
  2. Create an External Virtual Switch in Hyper-V:

    • Open PowerShell as administrator and run:
      New-VMSwitch -Name "External Switch" -NetAdapterName eth0
      
  3. Modify the WSL Configuration:

    • Create or modify the .wslconfig file in your user profile directory ($env:USERPROFILE/.wslconfig) with the following content:
      [wsl2]
      networkingMode=bridged
      vmSwitch="External Switch"
      dhcp=true
      ipv6=true
      
  4. Enable systemd in the WSL Distribution:

    • Edit the /etc/wsl.conf file in your WSL distribution and add the following lines:
      [boot]
      systemd=true
      [network]
      hostname = HOSTAGE
      generateResolvConf = false
      
  5. Configure Network Addressing:

    • For dynamic address configuration, ensure the following is present in /etc/systemd/network/10-eth0.network:
      [Match]
      Name=eth0
      [Network]
      DHCP=yes
      
    • For static address configuration, use:
      [Match]
      Name=eth0
      [Network]
      Address=192.168.x.xx/24
      Gateway=192.168.x.x
      DNS=192.168.x.x
      
  6. Link systemd Resolv.conf:

    • Create a symbolic link to link resolv.conf from systemd:
      ln -sfv /run/systemd/resolve/resolv.conf /etc/resolv.conf
      
  7. Verification:

    • Restart the WSL 2 instance and verify the network configuration with:
      ip addr show eth0
      

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .