Translate

Archives

Plumbing NICs in Linux

Setting up a network card in Solaris (prior to Solaris 11) involving plumbing the interface prior to configuring it. If you did not plumb the interface, you did not see the interface. This is a feature which many people liked but was missing from Linux until quite recently.

One recent feature in the Linux kernel (2.6.13 and later), is the ability to bind or unbind a device driver from user space. This can be used to make a network interface completely disappear from the output of ifconfig -a.

Previously, the only way to disconnect a driver from a device was usually to unload the whole driver from memory, using rmmod or modprobe -r.

For example, consider the following output from ifconfig -a:

....
p1p1: flags=4099  mtu 1500
        ether b8:97:5a:04:e2:11  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

p2p1: flags=4163  mtu 1500
        inet 192.168.0.103  netmask 255.255.255.0  broadcast 192.168.0.255
        inet6 fe80::215:17ff:fea5:fe8b  prefixlen 64  scopeid 0x20
        ether 00:15:17:a5:fe:8b  txqueuelen 1000  (Ethernet)
        RX packets 1811  bytes 1490349 (1.4 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 1530  bytes 244184 (238.4 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device interrupt 18  memory 0xf7c40000-f7c60000
....


As you can see, the p1p1 interface is not configured and adds no value to the output. So how can you unplumb the interface so that it does not appear in the output? The answer is surprisingly simple.

Use the output of a utility like lspci to determine the device driver used with the interface. In my case it was r8169. In the sysfs pseudo filesystem, every driver now has bind and unbind files associated with it:

# tree /sys/bus/pci/drivers/r8169
/sys/bus/pci/drivers/r8169
├── 0000:02:00.0 -> ../../../../devices/pci0000:00/0000:00:1c.1/0000:02:00.0
├── bind
├── module -> ../../../../module/r8169
├── new_id
├── remove_id
├── uevent
└── unbind


In order to unbind a device from a driver, simply write the bus id of the device to the unbind file:

 #  echo -n "0000:02:00.0" > /sys/bus/pci/drivers/r8169/unbind0


and the device will no longer be bound to the driver an thus no longer be displayed in the output of ifconfig -a

# tree /sys/bus/pci/drivers/r8169
/sys/bus/pci/drivers/r8169
├── bind
├── module -> ../../../../module/r8169
├── new_id
├── remove_id
├── uevent
└── unbind


To bind a device to a driver, the device must first not be controlled by any other driver. Then, simply write the bus id of the device you wish to bind, into the bind file for that driver:

This capability is very useful for switching devices between drivers which handle the same type of device. Linux distributions sometimes offer multiple drivers of different version levels in their kernel packages.

Note that this change does not persist across a reboot unless you modify the appropriate modprobe configuration file.

Comments are closed.