Hi,
attached and inline you will find a improved and more robust version
of if2mac initscript and a example configuration file.
The script is tested only on 5 systems, my desktop (3 nics)
and my 2 routers (8/12 nics + wlan) and 2 NAS and seems to work.
If there are any bold testers who want to give it a try
their feedback, hints, critics and improvements are 
appreciated.

What works:
1) basic renaming of interfaces based on configuration file
     is stable.
2) Interfaces of type en*, et*, wl* unknown to the config
    file are added to the end of the list on the fly and renamed too
    as they would stay as ethXrenamed after the first pass.
    A warning is printed and the user is invited to add them
    to the config file. If you know a better solution please tell me.
3) config file format same as previous versions

What deos not work
1) interaction with udev/eudev in the case of rmmod/insmod.

What I changed in this version:
1) mac address from the config file are validated to avoid
    to suck in garbage (empty lines etc.)
    mac address retrieved from /sysfs are validated also
     just for paranoia. 

Ciao,
Tito

<--- snip ---->
#!/bin/sh
### BEGIN INIT INFO
# Provides:          if2mac
# Required-Start:    mountkernfs
# Required-Stop:
# Should-Start:
# Should-Stop:
# Default-Start:     S
# Default-Stop:
# X-Start-Before:    $network
# X-Start-After:
# Short-Description: Rename network interface based on MAC address
# Description:       Rename network interface based on MAC address on boot.
### END INIT INFO

# if2mac v. 0.3 (C) 2020-2021 T.R. <[email protected]> GPLv2

PATH=/sbin:/bin:/usr/sbin:/usr/bin

. /lib/lsb/init-functions

NAME=if2mac
SCRIPTNAME="/etc/init.d/$NAME"
DESC="Rename network interfaces based on MAC address"
CONFIG_FILE="/etc/if2mac.conf"
SUFFIX="renamed"
# Paths that must exist and programs needed
SYSFS_NET="/sys/class/net"
SED="/bin/sed"
if   test -x "/bin/ip" ; then
                IP="/bin/ip"
elif test -x "/sbin/ip" ; then
                IP="/sbin/ip"
else
                log_warning_msg "Command $IP not found"
                exit 1
fi
if test ! -x "$SED" ; then
                log_warning_msg "Command $SED not found"
                exit 1
fi
if test ! -f "$CONFIG_FILE" ; then
                log_warning_msg "Configuration file $CONFIG_FILE not found"
                exit 1
fi
if test ! -d "$SYSFS_NET" ; then
                log_warning_msg "Directory $SYSFS_NET not found"
                exit 1
fi

# We source for WIRED_MAC_LIST, WIRELESS_MAC_LIST,
# WIRED_PREFIX and WIRELESS_PREFIX.

# shellcheck source=/etc/if2mac.conf
. "$CONFIG_FILE"

fnmatch() { case "$2" in $1) return 0;; *) return 1 ;; esac ; }

iface_rename () {
        "$IP" link set "$1" down
        "$IP" link set "$1" name "$2"
        RET=$?
        if [ "x$RET" = "x0" ] ; then
                        log_action_msg "renamed $1 to $2"
                        "$IP" link set "$2" up
                        return 0
        else
                        log_warning_msg "failed to rename $1 to $2"
                        "$IP" link set "$1" up
                        return 1
        fi
}

ismac() {
        case $1
        in 
        
[0-9a-f][0-9a-f]:[0-9a-z][0-9a-f]:[0-9a-f][0-9a-f]:[0-9a-f][0-9a-f]:[0-9a-f][0-9a-f]:[0-9a-f][0-9a-f])
                return 0;
        ;;
        *)
                log_warning_msg "Invalid MAC address $1"        
                return 1;
        ;;
        esac
}

if2mac() {
        # We need two passes to allow interface swapping
        log_action_msg "Pass 1..."
        # We exit if there are no interfaces in list
        INTERFACE_LIST=$(ls "$SYSFS_NET")
        if test -z "$INTERFACE_LIST" ; then
                        log_daemon_msg "No interfaces detected!"
                        return 0
        fi
        for IFNAME in $INTERFACE_LIST
        do
                        # PREFIXES AND PATHS:
                        # en     Ethernet wired
                        # et     Ethernet wired old
                        # ib     InfiniBand
                        # sl     Serial line IP (slip)
                        # wl     Wireless local area network (WLAN)
                        # ww     Wireless wide area network (WWAN)
                        # WARNING: Only en, et and wl are supported.
                        if fnmatch 'en*' "$IFNAME" || fnmatch 'et*' "$IFNAME" 
|| fnmatch 'wl*' "$IFNAME"; then
                                        iface_rename "$IFNAME" "$IFNAME$SUFFIX"
                        fi
        done
        log_action_msg "Pass 2..."
        # We exit if there are no interfaces in list
        INTERFACE_LIST=$(ls "$SYSFS_NET")
        if test -z "INTERFACE_$LIST" ; then
                        log_daemon_msg "No interfaces detected!"
                        return 0
        fi
        for IFNAME in $INTERFACE_LIST
        do
                        if fnmatch 'en*' "$IFNAME" || fnmatch 'et*' "$IFNAME" 
|| fnmatch 'wl*' "$IFNAME"; then
                                        PREFIX="$WIRED_PREFIX"
                                        MAC_LIST="$WIRED_MAC_LIST"
                                        if fnmatch 'wl*' "$IFNAME" ; then
                                                        
PREFIX="$WIRELESS_PREFIX"
                                                        
MAC_LIST="$WIRELESS_MAC_LIST"
                                        fi
                                        IFNAME_MAC=$(cat 
"$SYSFS_NET/$IFNAME/address")
                                        # Convert to lowercase
                                        IFNAME_MAC=$(echo "$IFNAME_MAC" | 
"$SED" 's/[A-Z]/\L&/g')
                                        NUM=0
                                        FOUND=0
                                        for CONFIG_MAC in $MAC_LIST
                                        do
                                                        # Convert to lowercase
                                                        CONFIG_MAC=$(echo 
"$CONFIG_MAC" | "$SED" 's/[A-Z]/\L&/g')
                                                        # Check validity of 
input from config file
                                                        # and of the macddress 
retrieved from /sys.
                                                        if ismac "$CONFIG_MAC" 
&& ismac "$IFNAME_MAC"; then
                                                                if [ 
"$CONFIG_MAC" = "$IFNAME_MAC" ] ; then
                                                                                
FOUND=1
                                                                                
iface_rename "$IFNAME" "$PREFIX$NUM" "$CONFIG_MAC"
                                                                                
break
                                                                fi
                                                                NUM=$((NUM + 1))
                                                        fi
                                        done
                                        if [ "x$FOUND" = "x0" ] ; then
                                                        log_warning_msg "MAC 
address $IFNAME_MAC not found in $CONFIG_FILE. Please add it."
                                                        iface_rename "$IFNAME" 
"$PREFIX$NUM" "$IFNAME_MAC"
                                                        # Add it to end of the 
list or if there are more than one they will get all the same number
                                                        if fnmatch 'en*' 
"$IFNAME" || fnmatch 'et*' "$IFNAME" ; then
                                                                        
WIRED_MAC_LIST="$WIRED_MAC_LIST $IFNAME_MAC"
                                                        else
                                                                        
WIRELESS_MAC_LIST="$WIRELESS_MAC_LIST $IFNAME_MAC"
                                                        fi
                                        fi
                        fi
        done
        return 0
}

case "$1" in
        start|reload|force-reload|restart)
                        log_action_msg "$DESC: $NAME"
                        if2mac
                        exit 0
        ;;
        stop)
        ;;
        *)
                        log_action_msg "Usage: $SCRIPTNAME 
{start|stop|reload|force-reload|restart}"
                        exit 2
        ;;
esac
exit 0
<---snip--->
_______________________________________________
Dng mailing list
[email protected]
https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng

Reply via email to