특정 네트워크 인터페이스(예: )가 실제로 네트워크 인터페이스 eth1
유형인지 명확하게 식별할 수 있습니까? veth
컨테이너에서는 네트워크 인터페이스 이름이 eth*
로 시작하는 경우가 많으며 컬렉션에 실수가 있는지 veth*
확인할 방법이 없습니다 . eth
이것이 테스트를 통과할 것인가 /sys/class/net
?
내 생각에는 iflink
의 요소가 네트워크 인터페이스를 /sys/class/net/...
명시적으로 식별하지 않지만 veth
다른 상황에서도 사용된다는 것입니다. 내 문제가 파일 시스템을 사용하여 해결될 수 없는 경우 /sys/class/net/...
, 이 정보를 제공할 수 있는 소켓 호출이 있습니까(바람직하게는 Python에서)?
답변1
더 많은 조사를 통해 다행히도 /sys/class/net/...
.예달성 가능.
올바른 네임스페이스 설치/sys/class/net
감사해요"네트워크 네임스페이스로 전환해도 /sys/class/net이 변경되지 않습니까?"에 대한 Danila Kiver의 답변내가 해야 할 일은 (네트워크) 네임스페이스 와 해당 분기 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
그러나 Linux 커널의 NETLINK 인터페이스는 필요한 정보를 제공합니다. 그렇지 않으면 명령이 ip link
인터페이스 유형을 결정할 수 없습니다.
여기서 핵심은 IFLA_LINKINFO
커널에서 네트워크 링크(예: 네트워크 인터페이스) 목록을 요청할 때 반환되는 속성입니다. 그 안에는 네트워크 인터페이스나 Linux 커널 브리지 에 적용되는 IFLA_INFO_KIND
또 다른 속성이 있습니다 .veth
veth
bridge
이는 IFLA_LINKINFO
선택적 속성입니다. 예를 들어 루프백, 이더넷 및 Wi-Fi 네트워크 인터페이스에서는 제공되지 않습니다 IFLA_LINKINFO
.
이 정보는 유명한 Python을 사용하여 쉽게 얻을 수 있습니다.파이루트2네트워크 링크 라이브러리. pyroute2
쉽게 설치하여 모든 불쾌한 NETLINK 항목을 제거하십시오 pip3
. 이 예제는 현재 네트워크 네임스페이스에 표시되는 모든 네트워크 인터페이스를 반복하여 이름, 인터페이스 인덱스 및 값 IFLA_LINKINFO
(있는 경우)을 제공합니다.
pyroute2에서 IPRoute 가져오기 네트워크 = IP 경로() netw.get_links()의 링크의 경우: ifindex = 링크['인덱스'] ifname = link.get_attr('IFLA_IFNAME') linkinfo = link.get_attr('IFLA_LINKINFO') linkinfo가 None이 아닌 경우: 링크 유형 = linkinfo.get_attr('IFLA_INFO_KIND') 기타: 링크 유형 = '없음' print('{0}: #{1} {2}'.format(ifname, ifindex, linktype))