USB over IP on Linux: Setup, Installation, and Usage

Jarret B

Well-Known Member
Staff member
Joined
May 22, 2017
Messages
352
Reaction score
396
Credits
12,511
USB over IP is a TCP/IP Protocol to allow access of a remote USB device to a client system.

The USBIP Protocol, more information on the protocol, can be found at https://www.kernel.org/doc/html/latest/usb/usbip_protocol.html, is set up as a server/client architecture. Once you have the shared devices setup on the ‘server’, the clients are allowed access to the device. Clients can be almost any type of Linux or Windows. I am covering setting this up for Linux.

For some people, they set up a Raspberry Pi as a ‘server’ and share devices such as printers that are not network accessible. Of course, most printers these days are network capable, but older devices are not.

Installation

I am doing this on Ubuntu 22.04 as a ‘server’. Let’s look at getting this installed.

You should initially update the repositories and upgrade the packages.

sudo apt update
sudo apt upgrade -y
sudo apt autoremove -y


Next, we can start the installation of the packages.

We are going to add the USB/IP modules to your kernel, but if this doesn’t work properly, we can also have the modules loaded on startup.

So, we need to install the packages:

sudo apt install linux-tools-$(uname -r) hwdata -y
sudo apt install linux-tools-generic -y


The first set of packages, ‘linux-tools-$(uname -r)’ is the set of USB/IP packages for your specific kernel. The ‘hwdata’ is the hardware data of the USB devices.

The second command gets and installs the most up-to-date version of the ‘linux-tools’ which includes the USB/IP tools.

We should now have all the tools needed, we just need to get them loaded.

To update the kernel, we use the ‘modprobe’ command:

sudo modprobe usbip_core
sudo modprobe usbip_host


These should place the two necessary modules in the kernel. You can test that it loaded the modules with the command:

sudo lsmod | grep usbip

The response should show the modules ‘usbip-host’ for the module ‘usbip_core’.

If you should reboot, you can test the modules with the ‘lsmod’ command again.

In my case, the modules did not load automatically during the boot. So, to fix this, I added the two modules to the list ‘/etc/modules’. Use your favorite editor, but make sure you have root privileges. At the end of the comments, add the following and save the file:

usbip_core
usbip_host


If you wanted, you can reboot to verify that the modules are loading.

The ‘usbip_core’ module allows for the transmission of packets for a USB device over IP. This allows remote systems to receive TCP/IP packets. The system uses ‘usbip_host’ for the ‘server’ and is bound to a physical USB device so the user can export it to a ‘client’ system. For the creation of a ‘virtual’ USB host controller for the connection of real or virtual USB devices, the system needs the module ‘vhci_hcd’.

Here, the ‘usbip_core’ is required by both the ‘server’ and ‘client’ to provide connectivity for sending and receiving packets. The system needs ‘usb_host’ module on the ‘server’ to provide access to the physical USB devices. The client needs the module ‘vhci_vcd’ for creating virtual ports and devices.

There is also a Daemon that should run in the background. You can test it in two ways. The first is to check for the running process with the command ‘ps -e | grep usbipd’. If it shows a response, then you are good. The second way is to see if the Daemon has opened Port 3240 with the command ‘netstat -lnt’ which should have an entry ‘0.0.0.0:3240’ listening.

If neither command shows that the Daemon is running, then you can start the Daemon manually with the command ‘sudo usbip -d’. The parameter allows the Daemon to run in the background. If you start the Daemon and get an error, then the Daemon may already be running. You can stop the Daemon and run it in the foreground so you can see any messages with the command ‘sudo usbipd’. If you have troubles attaching to devices, then stop the running Daemon and run it with elevated privileges.

NOTE: If on the server or client side, you have a firewall, open Port 3240.

For the USBIP Client, you need to install the same packages as the server.

The two modules you need to load into the kernel are:

usbip_core
vhci_hcd


Once the system loads the modules, you should be able to accomplish connecting USB over IP sharing.

USBIP Usage

There are USBIP commands we can use only on either the ‘server’, ‘client’ or both.

You can use the ‘list’ command on both systems, it just depends which system you are on. On a ‘server’, we can use the parameter ‘-l’ to list the local USB devices.

We can verify that the installation of the files by running the command ‘usbip list -l’ to use the ‘usbip’ command to list all the local USB devices. I show the output of the command in Figure 1.

Figure 1.jpg

FIGURE 1

For the ‘server’, we use the ‘bind’ command. The ‘bind’ command has one parameter of ‘-b’ for the ‘busid’ of the USB device. We ‘bind’ the devices so the remote systems can connect to them.

The ‘busid’ is shown in the listing from the ‘list’ command, as seen in Figure 1. The IDs will vary from system to system, so you always need to run the ‘list’ command to verify the ID. In Figure 1, you can see that the first device listed is the mouse with the ‘busid’ of ‘3-3’. We can also use the parameter ‘-p’ for a more parsable listing.

Let’s assume we want to ‘bind’ to the SanDisk Extreme Portable SSD which has a ‘busid’ of 4-4. The command we would issue is ‘sudo usbip bind -b 4-4’. If the binding is successful, the response should be ‘usbip: info: bind device on busid 4-4: complete’. If you get any other error, then you need to verify the installation of all packages and that the kernel modules are running.

Once a device has been bound to the ‘server’, we can release it by the command ‘unbind’. The command is ‘usbip unbind -b 4-4’.

NOTE: Once a device is bound to the Daemon, it is not accessible by the ‘server’.

Now we can ‘share’ or ‘unshare’ a USB device on a ‘server’. Now, we need to use these devices on a ‘client’ system.

To get a listing of the devices on a remote system, the ‘server’, we use the ‘list’ command. The command is:

sudo usbip list -r <server-ip>

The result should be a listing of the devices that are bound to the ‘server’.

We can ‘attach’ or ‘detach’ from the USB shared devices. To do this, we first need to ‘attach’ to a device with the command:

sudo usbip attach -r <server-ip> -b <busid>

In my case, I use the command ‘sudo usbip attach -r 192.168.1.218 -b 4-4’. There was no response on the ‘client’ side, but on systems set to show connected USB devices, I saw the new storage device appear.

You can run ‘lsusb’ on the client and see that the new USB device appears on the list, as shown in Figure 2.

Figure 2.jpg

FIGURE 2

I used storage devices, but the connections should work fine for most USB devices.

If a device is being used by a client, being attached to it, then a user cannot access the device on any other ‘client’.

To ‘detach’ a USB device, you need to find the Port number of the USB device. To find the Port numbers, use the command ‘sudo usbip port’ on the ‘client’. You should see something similar to Figure 3.

Figure 3.jpg

FIGURE 3

Here, you can see that I ‘attached’ two devices. The SanDisk Ultra is on Port ‘08’ and the SanDisk Extreme Portable SSD is on Port ‘09’. If I wanted to ‘detach’ the Extreme Portable SSD, I would use the command:

sudo usbip detach -p 09

A response should show the device detached once the command has completed, as shown in Figure 4.

Figure 4.jpg

FIGURE 4

This works for Ubuntu well. If you want to use USBIP on a VirtualBox machine running Ubuntu, then the setup has one extra step.

Oracle Virtual Box Machines

If you want to access a USB device over IP, then you need to change the machine image.

To change the machine image, you need to go to the folder where the file ‘vboxmanage’ is located. On Windows, it is ‘C:\Program Files\Oracle\VirtualBox\’ or on Linux it should be in a path to be run anywhere, then run the command:

vboxmanage usbfilter add 0 –target “<machine-name> -- name “All devices”

The ‘<machine-name>’ is the name of the machine that needs to be changed. Start the machine and install the ‘usbip’ packages as for a regular client.

The setup should then be the same as a regular ‘client’.

Kernel Modules

Sometimes, when you go to install the ‘linux-tools-$(uname -r)’, no packages are found. If you start the command ‘linux-tools-5’ or ‘linux-tools-6’ then press the tab key, you’ll get a listing of all possible package installations for that kernel version. Be sure to look for the package ending in ‘generic’. Use this list to compare it to your installed kernel versions under the ‘Advanced options’ in the Boot Menu. Load a kernel that has matching modules and install the modules.

This is probably the trickiest part of everything. It is making sure you have USBIP modules for your kernel.

Conclusion

No matter the Linux distro you may use, these instructions should work. The installation package may have a different name, but the remaining procedures are the same.

This is a great method to use to make a non-wireless USB device be network compatible.
 


Top