dorssel / usbipd-win

Windows software for sharing locally connected USB devices to other machines, including Hyper-V guests and WSL 2.
GNU General Public License v3.0
3.45k stars 222 forks source link

Allow Specification of IP or Interface to bind to #985

Open Geofferey opened 1 month ago

Geofferey commented 1 month ago

I noticed when trying to utilize my USB WIFI adapter that it would disconnect from WSL when my active connection dropped. I quickly realized this is because usbipd binds to the IP of my host active interface and when it's IP evaporates so does the USB over IP connection from host to WSL. I've found a way around the issue by creating a virtual interface with static IP available to the host and WSL.. I can get usbipd to use that interface if all other connections are off when WSL initially starts and I attach the USB device. It even stays after turning my internal WIFI off/on from that point forward. If we could specify the IP or interface that usbip daemon binds to at startup it would definetly be a way more robust solution than having to fiddle with connections before starting anything. For a lil context I'm using the usb adapter on a laptop and not a stationary device with a stable connection.

Thank you for usbipd and any consideration in this matter!

dorssel commented 1 month ago

That's an interesting use case. I will consider it. But I am not sure whether you are right. usbipd binds to ANY_ADDRESS, i.e., interface agnostic. It is the client that decides to use a certain IP address (which then connects to a socket on the corresponding interface). Are you saying the WSL virtual switch isn't stable when your external network drops out? Then I would report that to WSL.

However, I think you can already accomplish what you suggest by running usbip from within WSL yourself. You can then use the stable IP address you have created. And if you are on Windows 11, you could use mirrored networkingMode which uses a localhost connection (that should be stable too).

Geofferey commented 1 month ago

@dorssel I am not entirely sure how WSL is told to initate the connection to windows hosts. What I have noticed is when it connectes and a interface with the default route is available it uses that. Another issue maybe that I am using bridged networking but IIRC it still tries to connect to the host IP when soley using internal. From what I'm seeing if there was a way to specify the IP WSL uses to "reach the host", that woud solve it.

Could you give me an example of your statement?

However, I think you can already accomplish what you suggest by running usbip from within WSL yourself.

Do you mean like this fom within WSL?:

  usbip list -r 172.20.25.1

Here is a snippet of output that lead me to the conclusion:

usbipd: info: Device with hardware-id '0bda:0811' found at busid '2-4'.
usbipd: info: Using WSL distribution 'Ubuntu-22.04' to attach; the device will be 
available in all WSL 2 distributions.
usbipd: info: Using IP address 10.0.0.109 to reach the host.

^ Problem being the IP it decided to use is ephemeral

Now if I disable all active external interfaces it will utilize my "stable" interface:

 usbipd attach -i 0bda:0811 -w -a
 usbipd: info: Device with hardware-id '0bda:0811' found at busid '2-4'.
 usbipd: info: Using WSL distribution 'Ubuntu-22.04' to attach; the device will be 
 available in all WSL 2 distributions.
 usbipd: info: Using IP address 172.20.25.1 to reach the host.
 usbipd: info: Starting endless attach loop; press Ctrl+C to quit.
 WSL Attached

Running it with the -a option in a tasksched before connecting keeps it using the stable IP' even if I turn my connections off/on or disconnect and reconnect the dongle.

Thank you again; I am just trying to be incredibly clear here. Hopefully this describes things better.

dorssel commented 1 month ago

When you use usbip attach --wsl, in the background some commands are run on the WSL side to get a list of IP addresses (WSL side). It also lists the IP addresses of the host and selects a host IP address that is reachable from one of the WSL addresses (same subnet). This is usually the WSL internal switch address (or 127.0.0.1 for mirrored mode). That address is supposed to be stable as long as WSL is running (it is ephemeral, yes, but stable once WSL has been booted). Also, on the host side, this is supposed to be independent of other (external) network interfaces. That's why it shouldn't matter whether your WiFi is stopped, or getting a new IP address. Are you saying that in your case the WSL address is not stable for the duration of the WSL boot session? Then that should be reported to the WSL team. Or did you add a secondary interface and that is not stable upon WiFi changes? Then you should fix that.

In any case, once the matching address has been determined (Using IP address x.x.x.x), it simple runs usbip attach -r x.x.x.x -b y-z on WSL. You can always do that yourself, with a different address if you want.

Now I understand that you added (besides the automatic WSL internal switch) a second interface common to the host and to WSL. And that it sometimes selects one, sometimes the other. That is correct, as it will simply use the first interface that it finds with a matching WSL/host IP address combination within the same subnet. I could add an --ip option to usbip attach --wsl to force it to use a specific IP address. But I first like to understand why exactly it is necessary. You are the first to report issues on this front, and I just want to understand the root cause.

ryankurte commented 2 weeks ago

hey i think i am having a similar issue... i have WSL configured using bridged mode via a hyper-v virtual switch so that the WSL instance is routable with a static IP on my local network, and -no other network interfaces active-.

wsl hostname -I reports the correct static IP address for the WSL instance, but usbipd seems to ignore this and attempt to connect the windows host IP like it's in mirrored mode?

dorssel commented 2 weeks ago

@ryankurte You're confusing things. The address used must be the host address, whereas wsl hostname returns the client address. And mirrored mode would just use 127.0.0.1.