Setting Permanent Interface Settings with  udevadm in Linux

1. What is udevadm?

udevadm is the command-line utility for controlling the systemd-udevd daemon and interacting with the kernel’s device manager, udev.

  • udev (userspace /dev) is the device manager for the Linux kernel. It handles the dynamic management of device nodes in the /dev directory and manages all user-space events generated when hardware devices are added, removed, or changed (hot plugging).
  • udevadm allows you to:
    • Control the daemon (e.g., reloading rules).
    • Query device information (e.g., attributes needed for matching in rules).
    • Simulate kernel events to test rules.
    • Trigger re-processing of events for existing devices.

2. Why is this used? (The Role of udev Rules)

The purpose of using a udev rule for this is to ensure that a specific command runs immediately after the kernel recognizes and initializes a network interface, but before the network configuration services (like NetworkManager or systemd-networkd) start managing it.

udev rules are processed sequentially based on filenames (e.g., 10-myrule.rules runs before 70-persistent-net.rules), allowing custom device handling to take place early in the boot process. This ensures hardware-level settings are applied consistently and immediately upon device detection.


3. Why this is better than setting it with a “service”?

Using a udev rule (via a command specified in the rule) is often superior to a custom systemd service for initial, low-level hardware configuration (like ethtool settings) for a few key reasons:

  1. Event driven and timely: A udev rule is event-driven. It executes immediately when the kernel’s device detection event occurs for the specific network card. A custom service, on the other hand, runs based on its configured dependencies and timing in the boot sequence, which might be too late—the network service might have already brought the interface up with default settings, requiring a disruptive reset to apply the custom configuration.
  2. Device-Specific: The udev rule is tied directly to the device’s hardware identity (like its MAC address or PCI path). If the device is hot-plugged, the rule will re-run automatically. A simple systemd service usually just runs once during boot.
  3. Correct Initialization Order: For settings like link speed, duplex, the configuration needs to happen right after the driver loads. Udev is designed for this exact stage of device initialization.

Step-by-Step Implementation Guide

In this example, the goal is to permanently set a 10 Gigabit Ethernet (10G) interface to a 1 Gigabit (1G) speed. The temporary command is:

Bash

sudo ethtool -s <interface-name> speed 1000 duplex full autoneg off

Step 1: Identify the Interface Attributes

You need a reliable way to identify your specific network interface.

You can use ip link show in a bash shell to view the interfaces.

Another mtheod using the PCI address (KERNELS) is usually the most accurate, as interface names like eth0 or enpXsY can change.

  • Find the interface’s system path:

udevadm info -q path -n <interface-name>

udevadm info -a -p <output of the above command>

  • Look for a stable attribute like the PCI device address under the parent device, something like:

'/devices/pci0000:00/0000:00:1c.4/0000:05:00.0': KERNELS=="0000:05:00.0" <-- **Use this PCI address** SUBSYSTEMS=="pci" The key to use in your rule will be KERNELS.

Step 2: Create the udev Rule File

Create a new udev rule file in the /etc/udev/rules.d/ directory. Use a low number (like 20) to ensure your rule runs before standard network configuration rules, which often start around 70 or 80.

  • Create the file (using sudo):

sudo vi /etc/udev/rules.d/20-network-speed.rules

  • Add the following rule, replacing the placeholder values:

Key-Value explanation:

SUBSYSTEM=="net" Apply this rule only to network devices

ACTION=="add" Run this rule when a device is added (at boot/hotplug).

KERNELS=="0000:05:00.0" Match the specific device using its stable PCI address (replace this with your actual value).

NAME=="enp5s0" Optional: Match the interface name (replace with your interface name). This adds redundancy.

RUN+="/usr/sbin/ethtool -s $kernel speed 1000 duplex full autoneg off" The command to execute.

$kernel is a placeholder that udev expands to the interface’s kernel name (e.g., enp5s0). Use the full path to ethtool (/usr/sbin/ethtool)

Example Rule (20-network-speed.rules):

SUBSYSTEM=="net", ACTION=="add", KERNELS=="0000:05:00.0", RUN+="/usr/sbin/ethtool -s $kernel speed 1000 duplex full autoneg off"

Note: In some distributions, the ethtool binary may be in /sbin/ethtool instead.

Step 3: Apply and Test the Rules

  • Reload the udev rules database:

sudo udevadm control --reload-rules

  • Trigger the rules for the device (simulates the device being “added”):

sudo udevadm trigger --subsystem=net --action=add

  • Verify the setting

ethtool <interface-name>

The output under Speed: should now show 1000Mb/s (or 1000baseT/Full).

The setting is now persistent across reboots because the udev rule runs every time the kernel detects the specific network interface.

Leave a Reply

Your email address will not be published. Required fields are marked *