正しい名前空間のインストール/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))

関連情報