Быть задающим много вопросов - это возможный путь в создании ядра. Мои знания немного устарели, но я склонен начинать с "make xconfig", а затем вы можете просматривать конфигурацию. Это те же самые вопросы, но они кажутся менее настойчивыми.
Использование всех настроек по умолчанию разумно.
Проведя дополнительные исследования, я пришел к выводу, что моя цель недостижима с использованием К счастью, это достижимо. /sys/class/net/...
.
/sys/class/net
Благодаря ответу Данилы Кивера на вопрос «Переключение в сетевое пространство имен не меняет /sys/class/net?» все, что мне нужно сделать, это смонтировать sysfs
в каком-то месте, чтобы получить правильное (сетевое пространство имен )для sysfs
и его class/net/
ветви.
В следующем примере Python сканирует сетевые пространства имен, а затем перечисляет все сетевые интерфейсы в определенном сетевом пространстве имен, помечая каждый физический сетевой интерфейс с помощью [PHY]
. Обратите внимание, что этот скрипт нуждается в руте/админке, особенно из-за монтирования.
import psutil
import nsenter
from ctypes import c_char_p, c_ulong
import ctypes.util
import os
import tempfile
# https://stackoverflow.com/a/29156997
libc = ctypes.CDLL(ctypes.util.find_library('c'), use_errno=True)
libc.mount.argtypes = (c_char_p, c_char_p, c_char_p, c_ulong, c_char_p)
libc.umount.argtypes = (c_char_p, )
netns_index = dict()
for process in psutil.process_iter():
netns_ref = '/proc/%d/ns/net' % process.pid
try:
netns_id = os.stat(netns_ref).st_ino
if netns_id not in netns_index:
netns_index[netns_id] = netns_ref
except PermissionError:
pass
with tempfile.TemporaryDirectory() as temp_mnt:
for netns_id, netns_ref in netns_index.items():
with nsenter.Namespace(netns_ref, 'net'):
print('net:[%d]' % netns_id)
if libc.mount('sysfs'.encode('ascii'),
temp_mnt.encode('ascii'),
'sysfs'.encode('ascii'),
0,
''.encode('ascii')) >= 0:
for nif_name in sorted(os.listdir('%s/class/net' % temp_mnt)):
nif_path = os.readlink('%s/class/net/%s' % (temp_mnt, nif_name))
phys_nif = not nif_path.startswith('../../devices/virtual/')
print(' %s %s' % (nif_name, '[PHY]' if phys_nif else ''))
libc.umount(temp_mnt.encode('ascii'))
/sys/class/net
Однако интерфейс NETLINK для ядра Linux предоставляет необходимую информацию, иначе команда ip link
не смогла бы определить тип интерфейса.
Ключевым здесь является атрибут IFLA_LINKINFO
, который возвращается при запросе у ядра списка сетевых ссылок (, то есть сетевых интерфейсов ). Внутри него находится еще один атрибут с именем IFLA_INFO_KIND
, это veth
в случае сетевого интерфейса veth
или bridge
в случае моста ядра Linux.
Обратите внимание, что атрибут IFLA_LINKINFO
является необязательным; например, сетевые интерфейсы loopback, ethernet и wifi не предлагают IFLA_LINKINFO
.
Эту информацию можно легко получить в Python, используя известную pyroute2 библиотеку netlink. pyroute2
имеет дело со всеми неприятными вещами NETLINK, его легко установить через pip3
. Этот пример просто перебирает все сетевые интерфейсы, видимые в текущем сетевом пространстве имен, задавая их имена, индекс интерфейса и значение IFLA_LINKINFO
, если оно присутствует.
from pyroute2 import IPRoute netw = IPRoute() for link in netw.get_links(): ifindex = link['index'] ifname = link.get_attr('IFLA_IFNAME') linkinfo = link.get_attr('IFLA_LINKINFO') if linkinfo is not None: linktype = linkinfo.get_attr('IFLA_INFO_KIND') else: linktype = 'None' print('{0}: #{1} {2}'.format(ifname, ifindex, linktype))