Force creation of 70-persistent-net.rules on CentOS /Redhat 7/8

Windows Articles

Configure Samba File share Services with Ubuntu 20.04 LTS

Here, Today! let's discuss samba file share service with Ubuntu 20.04 LTS. If you need to share files between Linux and MS Windows...

Install Matomo on Ubuntu 20.04

Hello, friends. In this post, you will learn how to install Matomo on Ubuntu 20.04. It's quite useful to measure the traffic to our...

How to change DNS in Windows 10

Hi! Today we will talk a bit about networks. In fact, we will touch on a topic related to connectivity. Specifically we will see...

The new Windows 10 file explorer will arrive with 21H2 update.

Hello! Microsoft does not stop working (except at Christmas) to continue polishing to Windows 10. In fact, users are gradually receiving the 20H2 update....

How to create an FTP server in Android

Hello! How are you? Currently sharing files from your PC to Android can be more comfortable and easy, without the need to use a...
Mel Khamlichi
Mel Khamlichihttp://www.osradar.com
Founder of Osradar, from Amsterdam Netherlands

Hello if you have these option enabled in your grup conf net.ifnames=0 and biosdevname=0 , maybe you need to gecreete the 70-persistent-net.rules file to keep static mac adress on your configurations

My Linux Server is Centos8.1 but this way should work on RHEL 6/7 based Systems.

As you can see i have no rule called 70-persistent-net.rules

[root@192 rules.d]# ls -altr /etc/udev/rules.d
total 4
-rw-r–r–. 1 root root 628 Jun 3 2019 70-persistent-ipoib.rules
drwxr-xr-x. 2 root root 39 Feb 24 11:05 .
drwxr-xr-x. 4 root root 68 Mar 26 10:42 ..
[root@192 rules.d]#

  • Logon under root or sudo -s
  • Create “/lib/udev/write_net_rules” file with content:
#!/bin/sh -e
#
# Copyright (C) 2006 Marco d'Itri <md@Linux.IT>
# Copyright (C) 2007 Kay Sievers <kay.sievers@vrfy.org>
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation version 2 of the License.
#
# This script is run to create persistent network device naming rules
# based on properties of the device.
# If the interface needs to be renamed, INTERFACE_NEW=<name> will be printed
# on stdout to allow udev to IMPORT it.

# variables used to communicate:
#   MATCHADDR             MAC address used for the match
#   MATCHID               bus_id used for the match
#   MATCHDEVID            dev_id used for the match
#   MATCHDRV              driver name used for the match
#   MATCHIFTYPE           interface type match
#   COMMENT               comment to add to the generated rule
#   INTERFACE_NAME        requested name supplied by external tool
#   INTERFACE_NEW         new interface name returned by rule writer

# debug, if UDEV_LOG=<debug>
if [ -n "$UDEV_LOG" ]; then
	if [ "$UDEV_LOG" -ge 7 ]; then
		set -x
	fi
fi

if [ -n "$ASSIGNED_INTERFACE_NAME" -a "$ASSIGNED_INTERFACE_NAME" = "$INTERFACE_NAME" ]; then
	exit 0
fi

RULES_FILE='/etc/udev/rules.d/70-persistent-net.rules'

. /lib/udev/rule_generator.functions

find_all_ifcfg() {
    local links=$1
    local __sed_discard_ignored_files='/\(~\|\.bak\|\.orig\|\.rpmnew\|\.rpmorig\|\.rpmsave\)$/d'

    files=$(echo /etc/sysconfig/network-scripts/ifcfg-* \
	| LC_ALL=C sed -e "$__sed_discard_ignored_files")
    for i in $files; do
	(
	    . $i
	    [ -n "$HWADDR" ] && [ "${links%%[ \[\]0-9]*}" = "${DEVICE%%[ \[\]0-9]*}" ] && echo $DEVICE
	)
    done
}

interface_name_taken() {
	local value="$(find_all_rules 'NAME=' $INTERFACE)"
	if [ "$value" ]; then
		return 0
	else
	        for i in $(find_all_ifcfg "$INTERFACE"); do
		        [ "$INTERFACE" = "$i" ] && return 0
		done
		return 1
	fi
}

find_next_available() {
	raw_find_next_available $(find_all_rules 'NAME=' "$1") $(find_all_ifcfg "$1")
}

write_rule() {
	local match="$1"
	local name="$2"
	local comment="$3"

	{
	if [ "$PRINT_HEADER" ]; then
		PRINT_HEADER=
		echo "# This file was automatically generated by the $0"
		echo "# program, run by the persistent-net-generator.rules rules file."
		echo "#"
		echo "# You can modify it, as long as you keep each rule on a single"
		echo "# line, and change only the value of the NAME= key."
	fi

	echo ""
	[ "$comment" ] && echo "# $comment"
	echo "SUBSYSTEM==\"net\", ACTION==\"add\"$match, NAME=\"$name\""
	} >> $RULES_FILE
}

if [ -z "$INTERFACE" ]; then
	echo "missing $INTERFACE" >&2
	exit 1
fi

# Prevent concurrent processes from modifying the file at the same time.
lock_rules_file

# Check if the rules file is writeable.
choose_rules_file

# the DRIVERS key is needed to not match bridges and VLAN sub-interfaces
if [ "$MATCHADDR" ]; then
	match="$match, DRIVERS==\"?*\", ATTR{address}==\"$MATCHADDR\""
else
	if [ "$INTERFACE_NAME" ]; then
		match="$match, DRIVERS==\"?*\", ENV{INTERFACE_NAME}==\"$INTERFACE_NAME\""
	fi
fi

if [ "$MATCHDRV" ]; then
	match="$match, DRIVERS==\"$MATCHDRV\""
fi

if [ "$MATCHDEVID" ]; then
	match="$match, ATTR{dev_id}==\"$MATCHDEVID\""
fi

if [ "$MATCHID" ]; then
	match="$match, KERNELS==\"$MATCHID\""
fi

if [ "$MATCHIFTYPE" ]; then
	match="$match, ATTR{type}==\"$MATCHIFTYPE\""
fi

if [ -z "$match" ]; then
	echo "missing valid match" >&2
	unlock_rules_file
	exit 1
fi

basename=${INTERFACE%%[0-9]*}
match="$match, KERNEL==\"$basename*\""

if [ "$INTERFACE_NAME" ]; then
	# external tools may request a custom name
	COMMENT="$COMMENT (custom name provided by external tool)"
	if [ "$INTERFACE_NAME" != "$INTERFACE" ]; then
		INTERFACE=$INTERFACE_NAME;
		echo "INTERFACE_NEW=$INTERFACE"
	fi
else
	# if a rule using the current name already exists, find a new name
	if interface_name_taken; then
		INTERFACE="$basename$(find_next_available "$basename[0-9]*")"
		# prevent INTERFACE from being "eth" instead of "eth0"
		[ "$INTERFACE" = "${INTERFACE%%[ \[\]0-9]*}" ] && INTERFACE=${INTERFACE}0
		echo "INTERFACE_NEW=$INTERFACE"
	fi
fi

# build a regular expression that matches the new rule that we want to write
new_rule_pattern=$(echo "^SUBSYSTEM==\"net\", ACTION==\"add\"$match, NAME=\"$INTERFACE\"$" | sed -re 's/([\?\*\{\}])/\/g')

# Double check if the new rule has already been written. This happens if
# multiple add events are generated before the script returns and udevd
# renames the interfaces. See #765577 for details.
if egrep -qs "$new_rule_pattern" $RO_RULES_FILE $RULES_FILE; then
	unlock_rules_file
	exit 0
fi

write_rule "$match" "$INTERFACE" "$COMMENT"

unlock_rules_file

exit 0
  • Make it executable:
chmod +x /lib/udev/write_net_rules
  • Create file “/lib/udev/rule_generator.functions” with content:
# functions used by the udev rule generator
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation version 2 of the License.

PATH='/sbin:/bin'

# Read a single line from file $1 in the $DEVPATH directory.
# The function must not return an error even if the file does not exist.
sysread() {
	local file="$1"
	[ -e "/sys$DEVPATH/$file" ] || return 0
	local value
	read value < "/sys$DEVPATH/$file" || return 0
	echo "$value"
}

sysreadlink() {
	local file="$1"
	[ -e "/sys$DEVPATH/$file" ] || return 0
	readlink -f /sys$DEVPATH/$file 2> /dev/null || true
}

# Return true if a directory is writeable.
writeable() {
	if ln -s test-link $1/.is-writeable 2> /dev/null; then
		rm -f $1/.is-writeable
		return 0
	else
		return 1
	fi
}

# Create a lock file for the current rules file.
lock_rules_file() {
	[ -e /dev/.udev/ ] || return 0

	RULES_LOCK="/dev/.udev/.lock-${RULES_FILE##*/}"

	retry=30
	while ! mkdir $RULES_LOCK 2> /dev/null; do
		if [ $retry -eq 0 ]; then
			 echo "Cannot lock $RULES_FILE!" >&2
			 exit 2
		fi
		sleep 1
		retry=$(($retry - 1))
	done
}

unlock_rules_file() {
	[ "$RULES_LOCK" ] || return 0
	rmdir $RULES_LOCK || true
}

# Choose the real rules file if it is writeable or a temporary file if not.
# Both files should be checked later when looking for existing rules.
choose_rules_file() {
	local tmp_rules_file="/dev/.udev/tmp-rules--${RULES_FILE##*/}"
	[ -e "$RULES_FILE" -o -e "$tmp_rules_file" ] || PRINT_HEADER=1

	if writeable ${RULES_FILE%/*}; then
		RO_RULES_FILE='/dev/null'
	else
		RO_RULES_FILE=$RULES_FILE
		RULES_FILE=$tmp_rules_file
	fi
}

# Return the name of the first free device.
raw_find_next_available() {
	local links="$*"

	local basename=${links%%[ 0-9]*}
	local max=-1
	for name in $links; do
		local num=${name#$basename}
		[ "$num" ] || num=0
		[ $num -gt $max ] && max=$num
	done

	local max=$(($max + 1))
	# "name0" actually is just "name"
	[ $max -eq 0 ] && return
	echo "$max"
}

# Find all rules matching a key (with action) and a pattern.
find_all_rules() {
	local key="$1"
	local linkre="$2"
	local match="$3"

	local search='.*[[:space:],]'"$key"'"('"$linkre"')".*'
	echo $(sed -n -r -e 's/^#.*//' -e "${match}s/${search}//p" \
		$RO_RULES_FILE \
		$([ -e $RULES_FILE ] && echo $RULES_FILE) \
		2>/dev/null)
}
  • Create file “/lib/udev/rules.d/75-persistent-net-generator.rules” with content:
# do not edit this file, it will be overwritten on update

# these rules generate rules for persistent network device naming
#
# variables used to communicate:
#   MATCHADDR             MAC address used for the match
#   MATCHID               bus_id used for the match
#   MATCHDRV              driver name used for the match
#   MATCHIFTYPE           interface type match
#   COMMENT               comment to add to the generated rule
#   INTERFACE_NAME        requested name supplied by external tool
#   INTERFACE_NEW         new interface name returned by rule writer

ACTION!="add", GOTO="persistent_net_generator_end"
SUBSYSTEM!="net", GOTO="persistent_net_generator_end"

# ignore the interface if a name has already been set
NAME=="?*", ENV{INTERFACE_NAME}=="", GOTO="persistent_net_generator_end"
NAME=="?*", ENV{INTERFACE_NAME}=="?*", ENV{ASSIGNED_INTERFACE_NAME}="$name"

# device name whitelist
KERNEL!="eth*|ath*|wlan*[0-9]|msh*|ra*|sta*|ctc*|lcs*|hsi*", GOTO="persistent_net_generator_end"

# ignore Xen virtual interfaces
SUBSYSTEMS=="xen", GOTO="persistent_net_generator_end"

# read MAC address
ENV{MATCHADDR}="$attr{address}"

# match interface type
ENV{MATCHIFTYPE}="$attr{type}"

# do not use empty address
ENV{MATCHADDR}=="00:00:00:00:00:00", ENV{MATCHADDR}=""

# do not use "locally administered" MAC address
ATTR{addr_assign_type}=="?*", ATTR{addr_assign_type}!="0", ENV{MATCHADDR}="", ENV{MATCHID}="$env{NET_MATCHID}"
ATTR{addr_assign_type}=="0", GOTO="globally_administered_whitelist"

# These vendors are known to violate the local MAC address assignment scheme
# Interlan, DEC (UNIBUS or QBUS), Apollo, Cisco, Racal-Datacom
ENV{MATCHADDR}=="02:07:01:*", GOTO="globally_administered_whitelist"
# 3Com
ENV{MATCHADDR}=="02:60:60:*", GOTO="globally_administered_whitelist"
# 3Com IBM PC; Imagen; Valid; Cisco; Apple
ENV{MATCHADDR}=="02:60:8c:*", GOTO="globally_administered_whitelist"
# Intel
ENV{MATCHADDR}=="02:a0:c9:*", GOTO="globally_administered_whitelist"
# Olivetti
ENV{MATCHADDR}=="02:aa:3c:*", GOTO="globally_administered_whitelist"
# CMC Masscomp; Silicon Graphics; Prime EXL
ENV{MATCHADDR}=="02:cf:1f:*", GOTO="globally_administered_whitelist"
# Prominet Corporation Gigabit Ethernet Switch
ENV{MATCHADDR}=="02:e0:3b:*", GOTO="globally_administered_whitelist"
# BTI (Bus-Tech, Inc.) IBM Mainframes
ENV{MATCHADDR}=="02:e6:d3:*", GOTO="globally_administered_whitelist"
# Realtek
ENV{MATCHADDR}=="52:54:00:*", GOTO="globally_administered_whitelist"
# Novell 2000
ENV{MATCHADDR}=="52:54:4c:*", GOTO="globally_administered_whitelist"
# Realtec
ENV{MATCHADDR}=="52:54:ab:*", GOTO="globally_administered_whitelist"
# Kingston Technologies
ENV{MATCHADDR}=="e2:0c:0f:*", GOTO="globally_administered_whitelist"

# match interface dev_id
ATTR{dev_id}=="?*", ENV{MATCHDEVID}="$attr{dev_id}"

# do not use "locally administered" MAC address
ENV{MATCHADDR}=="?[2367abef]:*", ENV{MATCHADDR}=""

LABEL="globally_administered_whitelist"

# build comment line for generated rule:
SUBSYSTEMS=="pci", ENV{COMMENT}="PCI device $attr{vendor}:$attr{device} ($driver)"
SUBSYSTEMS=="usb", ATTRS{idVendor}=="?*", ENV{COMMENT}="USB device 0x$attr{idVendor}:0x$attr{idProduct} ($driver)"
SUBSYSTEMS=="pcmcia", ENV{COMMENT}="PCMCIA device $attr{card_id}:$attr{manf_id} ($driver)"
SUBSYSTEMS=="ieee1394", ENV{COMMENT}="Firewire device $attr{host_id})"

# ibmveth likes to use "locally administered" MAC addresses
DRIVERS=="ibmveth", ENV{MATCHADDR}="$attr{address}", ENV{COMMENT}="ibmveth ($id)", ENV{MATCHID}=""

# S/390 uses id matches only, do not use MAC address match
SUBSYSTEMS=="ccwgroup", ENV{COMMENT}="S/390 $driver device at $id", ENV{MATCHID}="$id", ENV{MATCHDRV}="$driver", ENV{MATCHADDR}="", ENV{MATCHDEVID}=""

# see if we got enough data to create a rule
ENV{MATCHADDR}=="", ENV{MATCHID}=="", ENV{INTERFACE_NAME}=="", GOTO="persistent_net_generator_end"

# default comment
ENV{COMMENT}=="", ENV{COMMENT}="net device ($attr{driver})"

# write rule
DRIVERS=="?*", IMPORT{program}="write_net_rules"

# rename interface if needed
ENV{INTERFACE_NEW}=="?*", NAME="$env{INTERFACE_NEW}"

LABEL="persistent_net_generator_end"
  • Try it out: without reboot
/sbin/udevadm trigger --type=devices --action=add
cat /etc/udev/rules.d/70-persistent-net.rules

[root@192 rules.d]# cat 70-persistent-net.rules

[root@192 rules.d]# cat 70-persistent-net.rules
# This file was automatically generated by the /usr/lib/udev/write_net_rules
# program, run by the persistent-net-generator.rules rules file.
#
# You can modify it, as long as you keep each rule on a single
# line, and change only the value of the NAME= key.

# PCI device 0x8086:0x100e (e1000)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="08:00:27:c3:b2:fc", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"
[root@192 rules.d]#

Cheers !! . Big thank to Sergei Shuykov

More articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest article

Configure Samba File share Services with Ubuntu 20.04 LTS

Here, Today! let's discuss samba file share service with Ubuntu 20.04 LTS. If you need to share files between Linux and MS Windows...

Install Matomo on Ubuntu 20.04

Hello, friends. In this post, you will learn how to install Matomo on Ubuntu 20.04. It's quite useful to measure the traffic to our...

How to change DNS in Windows 10

Hi! Today we will talk a bit about networks. In fact, we will touch on a topic related to connectivity. Specifically we will see...

The new Windows 10 file explorer will arrive with 21H2 update.

Hello! Microsoft does not stop working (except at Christmas) to continue polishing to Windows 10. In fact, users are gradually receiving the 20H2 update....

How to create an FTP server in Android

Hello! How are you? Currently sharing files from your PC to Android can be more comfortable and easy, without the need to use a...
x