Skip to content

Conversation

@nadzyah
Copy link
Member

@nadzyah nadzyah commented Oct 14, 2025

This PR adds a Rust implementation of the nameif command from net-tools, which renames network interfaces based on MAC addresses

Like the original nameif command, the implemented solution supports reading from the configuration file (-c/--config-file option, default /etc/mactab) and from CLI arguments, e.g. nameif testif0 00:11:22:33:44:55

The -s/--syslog option from the original is not implemented for the sake of the PR size and will be added in a follow-up PR

The PR also adds compliance tests for the nameif command to verify that its behaviour matches the original nameif command one

Copy link
Member

@lvoytek lvoytek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM overall, just a few extra comments :)


/// Parse command-line interface/MAC pairs
fn parse_cli_pairs(pairs: &[String]) -> Result<Vec<InterfaceChange>> {
if !pairs.len().is_multiple_of(2) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This allows compilation on stable toolchains

Suggested change
if !pairs.len().is_multiple_of(2) {
if pairs.len() % 2 != 0 {

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lol, no idea why I initially thought of this function 😅

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well, actually, turned out that this is what cargo clippy prefers:
https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_multiple_of

a.is_multiple_of(b) is a clearer way to check for divisibility of a by b. This expression can never panic.

// SAFETY: Reading ifru_hwaddr which was just populated by the successful ioctl
let mac = unsafe {
let sa_data = &ifreq.ifr_ifru.ifru_hwaddr.sa_data;
sa_data[..MAC_MAX_LEN].iter().map(|&b| b as u8).collect()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this return a 6-byte address instead?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original implementation does copy all 14 bytes, not just 6:
https://github.com/ecki/net-tools/blob/fc3a1338e84f7387b105550499a164921ce286c9/nameif.c#L104

memcpy(mac, ifr.ifr_hwaddr.sa_data, MAC_ADDRESS_MAX_LENGTH);

https://github.com/ecki/net-tools/blob/fc3a1338e84f7387b105550499a164921ce286c9/lib/net-support.h#L250

#define MAC_ADDRESS_MAX_LENGTH (sizeof(((struct ifreq *)0)->ifr_hwaddr.sa_data))

AFAIU, this macro calculates the size of sa_data field at compile time, which equals 14 bytes

@nadzyah nadzyah merged commit 9ac6126 into main Nov 26, 2025
6 checks passed
@nadzyah nadzyah deleted the nameif-command branch November 26, 2025 17:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants