Старое
название интерфейсов, такое как к примеру
eth0, кануло в лету (ну почти, иногда старые
имена можно встретить). В RHEL7 используются
следующие варианты схем наименования
сетевого интерфейса, в порядке применения:
-
Имя,
предоставляемое аппаратным обеспечением
(Firmware или BIOS), включающее порядковый
номер, для устройств, расположенных на
материнской плате, к примеру eno1. Если
выбор имени не произведен, используется
схема 2.
-
Имя,
предоставляемое аппаратным обеспечением
(Firmware или BIOS), включающее порядковый
номер слота PCI Express, к примеру ens1. Если
выбор не произведен, используется схема
3.
-
Имя
формируется из физического положения
точки подключения устройства, к примеру
enp2s0. Иначе используется схема 5.
-
Имя
включает MAC устройства, к примеру
enx94de80a44f0c. Эта схема по умолчанию не
используется.
-
Старая
схема, где имя присваивается ядром в
порядке обнаружения интерфейса, к
примеру eth0 и т.д.
Это
поведение по умолчанию.
Новые
имена сами по себе содержат полезную
информацию. Принятое соглашение о
наименовании следующее: первые два
символа отражают тип интерфейса:
-
en
— Ethernet.
-
wl
— беспроводная локальная сеть, WLAN.
-
ww
— беспроводная глобальная сеть, WWAN.
Далее
следует тип, отражающий схему наименования,
описанную выше:
-
o<index>
—
индекс для устройств расположенных на
материнской плате.
-
s<slot>[f<function>][d<dev_id>]
—
сначала идет номер
PCI
Express
слота, далее
f<function>
- номер
функции у многофункционального PCI
устройства (я не встречал таких
плат)
и
последним идет идентификатор устройства.
-
p<bus>s<slot>[f<function>][d<dev_id>]
—
расположение устройства на PCI шине.
Домен
PCI (p<bus>)
указывается только если он отличен от
нулевого (это можно увидеть в больших
системах). Номер функции и номер
устройства аналогично предыдущему
примеру.
-
p<bus>s<slot>[f<function>][u<port>][..][c<config>][i<interface>]
—
расположение
устройства на USB
шине, причем
учитывается
вся цепочка портов.
-
x<MAC>
—
MAC адрес.
Нужно
отметить, что имя не может быть более
15 символов, это ограничение ядра.
В
случае использования VLAN добавляется
следующее соглашение о имени интерфейса:
-
vlan<vlanid>
— имя с полным номером vlanid, к примеру
vlan0012 или имя с сокращенным vlanid — vlan12
-
device_name.<vlanid>
- имя интерфейса и VLAN ID в полном или
сокращенном виде, к примеру ens3.0012 или
ens3.12
Как
бы глупо это не звучало, но помимо
описанных соглашений о наименовании,
есть еще одно, используемое при помощи
утилиты udev — biosdevname (насколько я понял,
возникло это соглашение по инициативе
DELL и используется на их серверах). Оно
имеет силу только при наличии установленного
пакета biosdevname и при указании biosdevname=1 при
загрузке системы. Переименования будут
производится только для встроенных
интерфейсов. При этом:
-
Встроенные
интерфейсы будут иметь имя типа
em[123...]
-
Интерфейсы,
подключенные по шине PCI — p<slot>p<ethernet
port>, к примеру p3p4
Чтобы
окончательно не запутаться в теоретической
части, рассмотрим более глубоко процесс
присваивания имени интерфейсу по шагам.
Ниже пример того что происходит, когда
в системе появляется новый интерфейс:
#
udevadm monitor
...
KERNEL[27783.869667]
add
/devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7.4/1-7.4:1.0/net/eth0
(net)
...
KERNEL[27783.879674]
move
/devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7.4/1-7.4:1.0/net/enp0s20u7u4
(net)
UDEV
[27783.892038] add
/devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7.4/1-7.4:1.0/net/enp0s20u7u4
(net)
...
Т.е.
сначала интерфейс появился со старым,
знакомым именем eth0, а далее стал
enp0s20u7u4. Нетрудно заметить, что новое имя
сразу отображает что это адаптер Ethernet
(en), подключенный к USB шине через usb хаб
(в имени два usb порта u7u4). Достаточно
удобно.
Посмотрим,
что выполняет udev над интерфейсом:
#
udevadm test
/sys/devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7.4/1-7.4:1.0/net/enp0s20u7u4
...
PROGRAM
'/lib/udev/rename_device' /usr/lib/udev/rules.d/60-net.rules:1
starting
'/lib/udev/rename_device'
Что
происходит: правило udev
/usr/lib/udev/rules.d/60-net.rules при помощи
/lib/udev/rename_device, просматривает конфигурационные
файлы сетевых интерфейсов -
/etc/sysconfig/network-scripts/ifcfg-*, и если есть
соответствие MAC адреса добавляемого
интерфейса и адреса в директиве HWADDR, то
имя интерфейса устанавливается в
соответствии с директивой DEVICE.
Сейчас
воспользуемся небольшой хитростью,
чтобы процесс применения правил udev был
более наглядным. Создадим конфигурационный
файл ifcfg-tstif0 с именем tstif0 для нашего
адаптера и вставим адаптер. Интерфейс
в системе станет tstif0. Теперь удалим
конфигурационный файл, и посмотрим на
обработку правил еще раз, но уже для
интерфейса tstif0, в конечном итоге мы
должны будем получить имя enp0s20u7u4.
Запустим
еще раз, первое правило не отработает,
т.к. конфигурационный файл мы удалили:
PROGRAM
'/lib/udev/rename_device' /usr/lib/udev/rules.d/60-net.rules:1
starting
'/lib/udev/rename_device'
'/lib/udev/rename_device'
[5023] exit with return code 0
PROGRAM
'/sbin/biosdevname --policy physical -i tstif0'
/usr/lib/udev/rules.d/71-biosdevname.rules:22
starting
'/sbin/biosdevname --policy physical -i tstif0'
'/sbin/biosdevname
--policy physical -i tstif0' [5024] exit with return code 2
Правило
/usr/lib/udev/rules.d/71-biosdevname.rules реализует выше
рассмотренное соглашение о именах при
использовании biosdevname. Уточнение, это
правило работает, если в системе
установлен biosdevname, при загрузке не был
использован параметр biosdevname=0, и если
имя не было назначено на предыдущем
шаге.
IMPORT
builtin 'net_id' /usr/lib/udev/rules.d/75-net-description.rules:6
IMPORT
builtin skip 'usb_id'
/usr/lib/udev/rules.d/75-net-description.rules:8
IMPORT
builtin 'hwdb' /usr/lib/udev/rules.d/75-net-description.rules:8
На
этом этапе правилом
/usr/lib/udev/rules.d/75-net-description.rules, заполняются
следующие директивы описания устройства:
ID_NET_NAME_ONBOARD, ID_NET_NAME_SLOT, ID_NET_NAME_PATH и
ID_NET_NAME_MAC. Не все директивы могут быть
заполнены, поскольку не все устройства
могут иметь требуемую информацию.
IMPORT
builtin 'path_id' /usr/lib/udev/rules.d/80-net-setup-link.rules:5
IMPORT
builtin 'net_setup_link'
/usr/lib/udev/rules.d/80-net-setup-link.rules:9
Config
file /usr/lib/systemd/network/99-default.link applies to device
tstif0
NAME
'enp0s20u7u4' /usr/lib/udev/rules.d/80-net-setup-link.rules:11
Вот
оно правило, которое устанавливает имя
для интерфейса в данном случае -
/usr/lib/udev/rules.d/80-net-setup-link.rules. Что по этому
правило происходит: если интерфейс не
был переименован на предыдущих шагах,
и если не задан параметр ядра net.ifnames=0,
то имя интерфейса устанавливается в
соответствии с порядком по приоритету
из полученных ранее директив:
ID_NET_NAME_ONBOARD, ID_NET_NAME_SLOT, ID_NET_NAME_PATH. Если ни
одна из директив не определена, то
интерфейс остается не переименованным,
т.е. старый вариант именования — eth0.
Для
понимания, посмотреть возможные имена
можно так:
#
udevadm info /sys/class/net/tstif0 | grep ID_NET_NAME
E:
ID_NET_NAME=enp0s20u7u4
E:
ID_NET_NAME_MAC=enx00101402bca7
E:
ID_NET_NAME_PATH=enp0s20u7u4
Можно
заметить, что почти все пункты (за
исключением 5 — старого именования) из
стандартного соглашения о наименовании
реализуются в правилах udev:
75-net-description.rules и 80-net-setup-link.rules. Можно
возразить, а где наименование по MAC
адресам? Включение его можно произвести
правкой правила 80-net-setup-link.rules. Скопируйте
его:
#
cp /usr/lib/udev/rules.d/80-net-name-slot.rules /etc/udev/rules.d
И
добавьте строку выделенную курсивом
на листинге:
#
grep -v "^#\|^$" /etc/udev/rules.d/80-net-name-slot.rules
ACTION!="add",
GOTO="net_name_slot_end"
SUBSYSTEM!="net",
GOTO="net_name_slot_end"
NAME!="",
GOTO="net_name_slot_end"
IMPORT{cmdline}="net.ifnames"
ENV{net.ifnames}=="0",
GOTO="net_name_slot_end"
NAME=="",
ENV{ID_NET_NAME_MAC}!="", NAME="$env{ID_NET_NAME_MAC}"
NAME=="",
ENV{ID_NET_NAME_ONBOARD}!="",
NAME="$env{ID_NET_NAME_ONBOARD}"
NAME=="",
ENV{ID_NET_NAME_SLOT}!="", NAME="$env{ID_NET_NAME_SLOT}"
NAME=="",
ENV{ID_NET_NAME_PATH}!="", NAME="$env{ID_NET_NAME_PATH}"
LABEL="net_name_slot_end"
Не
уверен, что данный вариант именования
удобен.
Итак,
мы обсудили несколько соглашений о
наименовании сетевых интерфейсов,
рассмотрели по шагам, как происходит
выбор имени, попутно узнали, что
net.ifnames=0 отключает новую схему наименования,
и последнее замечание: не используйте
имена из пространства ядра - ethX в схеме
с присвоением имен через файлы ifcfg-*.