指定されたNICにネットワークケーブルが接続されているかどうかを確認します

指定されたNICにネットワークケーブルが接続されているかどうかを確認します

サーバーには複数の NIC がありますが、そのうちの 1 つにのみケーブルが接続されています。

特定のポートethXが接続されているかどうかをテストするにはどうすればよいでしょうか?

似たようなものがたくさん見つかりました質問、しかし、どちらも私には機能しませethtoolcat /sys/class/net/eth1/carrier

私の場合、ケーブルは実際には に接続されていますeth2が、ethtoolそれでも表示されますLink detected: no

Settings for eth2:
    Supported ports: [ FIBRE ]
    Supported link modes:   10000baseT/Full 
    Supported pause frame use: Symmetric
    Supports auto-negotiation: No
    Advertised link modes:  10000baseT/Full 
    Advertised pause frame use: Symmetric
    Advertised auto-negotiation: No
    Speed: Unknown!
    Duplex: Unknown! (255)
    Port: Direct Attach Copper
    PHYAD: 0
    Transceiver: internal
    Auto-negotiation: off
    Supports Wake-on: d
    Wake-on: d
    Current message level: 0x00000007 (7)
                   drv probe link
    Link detected: no

にはケーブルが接続されていませんeth3が、ethtool出力はほぼ同じに見えます。

diff <(ethtool eth2) <(ethtool eth3)
1c1
< Settings for eth2:
---
> Settings for eth3:
11c11
<   Port: Direct Attach Copper
---
>   Port: Other

最初にインターフェイスを起動するとeth2ethtoolが表示されますLink detected: yes。その後、インターフェイスをダウンしても、ethtoolはリンクを として報告します。yes

つまり、ethtoolインターフェースがアップグレードされる前は、最初は機能しないようです。

特定のインターフェースにケーブルが接続されているかどうかを確実にテストするにはどうすればよいでしょうか?

答え1

ソケットにケーブルが差し込まれた物理的な状態ではなく、NIC のリンク状態を調べたいのだと思います (調べるのは不可能かもしれません)。

ちょっと検索してみると、すでに答えが見つかるのではないかと思います。インターフェースを起動し、リンクが見つかるまで待ちます。リンクがあれば (数秒かかる場合があります)、 、ethtoolまたはcarrierおよび/または のoperstate出力を確認します/sys/class/net/$NIC/

ifconfig somenic up次の 2 つの呼び出しを行うようですioctl:

ioctl(4, SIOCGIFFLAGS, {ifr_name="somenic", ifr_flags=IFF_BROADCAST|IFF_MULTICAST}) = 0
ioctl(4, SIOCSIFFLAGS, {ifr_name="somenic", ifr_flags=IFF_UP|IFF_BROADCAST|IFF_RUNNING|IFF_MULTICAST}) = 0

つまり、 を設定しますIFF_UPここ実際にデバイスを初期化する設定は次のとおりです。

次に、 (ソケット I/O 制御インターフェイス フラグの設定)を使用してIFF_UPビットを設定し、インターフェイスをオンにします。dev->flagioctl(SIOCSIFFLAGS)

ただし、後者のコマンド ( ioctl(SIOCSIFFLAGS)) は、デバイスの open メソッドを呼び出します。

実際のコードに関する限り、ドライバーは char ドライバーや block ドライバーと同じタスクの多くを実行する必要があります。open は必要なシステム リソースを要求し、インターフェイスを起動するように指示します。

同様のコメントはe1000eドライバーソース:

/**
 * e1000e_open - Called when a network interface is made active
 * @netdev: network interface device structure
 *
 * Returns 0 on success, negative value on failure
 *                                                                                                                                                                           * The open entry point is called when a network interface is made
 * active by the system (IFF_UP).  At this point all resources needed
 * for transmit and receive operations are allocated, the interrupt
 * handler is registered with the OS, the watchdog timer is started,
 * and the stack is notified that the interface is ready.
 **/
int e1000e_open(struct net_device *netdev)  

つまり、NICのリンク状態を意味のある方法で見つける方法はないということです。ハードウェアが初期化されないためです。


もちろん、一部のドライバーが異なる動作をして、誰かが設定する前にハードウェアを初期化することは少なくとも理論的には可能ですがIFF_UP、それでも一般的なケースでは役に立ちません。

1 台のマシン ( e1000eCisco スイッチに接続) でインターフェイスをプルダウンすると、スイッチもリンクがダウンしたことを認識します。

別のマシン (Realtek NIC が組み込まれている) では、アップからダウンへの変更により、リモート スイッチが短時間切断されますが、スイッチはリンクを認識し、その後再びアップになります。 (ethtoolただし、PC 側では「リンクなし」と表示されます。) これは、Wake-on-LAN などの準備と関係があるかどうかはわかりませんが、まったくわかりません。

答え2

ifplugstatusパッケージからコマンドを試すifplugd

$ ifplugstatus net0
net0: unplugged

$ ifplugstatus wlnet0
wlnet0: link beat detected

画面出力以外にも、コマンドの終了ステータスからも確認できます。

(manページより)

戻り値

  0 Success

  1 Failure

  2 Link beat detected (only available when an interface is specified)

  3 Unplugged (same here)

答え3

ethertoolsのソースコードを確認しましたが、リンク状態が記述されている箇所が見つかりませんでした。

その後、これが SO の質問とまったく同じであることがわかりました。https://stackoverflow.com/questions/808560/how-to-detect-the-physical-connected-state-of-a-network-cable-connector

そこにリストされている回答のほとんど (mii-tools、ethertool、cat the carrier または operstate、dmesg) を試しましたが、ifconfig がダウンしているときにリンク上で正しく機能するものはありませんでした。

SOの質問は6年以上前のものなので、可能答えはすでにそこにあります。

私の意見としては、標準の Linux ツールでは、キャリアを起動してみるまでキャリアをチェックできないということです。その後は、mii-toolsリンク検出は正常に機能し、一貫した回答が得られるようです。

私はrtnetlinkと、検出を扱う他の回答を試しませんでした。変更リンク状態ですが、これはおそらくあなたが望んでいたものではないと思います。

関連情報