올바른 네임스페이스 설치/sys/class/net

올바른 네임스페이스 설치/sys/class/net

특정 네트워크 인터페이스(예: )가 실제로 네트워크 인터페이스 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에 대한 올바른 보기를 얻을 수 있도록 어딘가에 설치하는 것뿐입니다 .sysfsclass/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또 다른 속성이 있습니다 .vethvethbridge

이는 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))

관련 정보