web-dev-qa-db-ja.com

物理ネットワークインターフェイスを名前空間に自動的に移動します

システム上のすべての物理インターフェイスを、「物理」と呼ばれる特定のネットワーク名前空間内に配置したいと思います。 ip link set enp2s0 netns physicaliw phy phy0 set netns name physicalなどのコマンドを使用してデバイスを手動で移動するのは簡単ですが、起動時と実行時に接続されているすべてのデバイスの両方で自動的に移動するようにします。

これを達成するための最良の方法は、udevルールまたはおそらくsystemdマジックを使用することです。

私が最初に思ったのは、適切なコマンドを実行するudevルールを記述することだけでしたが、検索で答えることができなかったいくつかの質問に遭遇しました。

  1. 物理インターフェイスと仮想インターフェイスを区別するにはどうすればよいですか?
  2. iwコマンドの代わりにipコマンドを発行できるように、WLANインターフェイスを区別するにはどうすればよいですか。
  3. iwコマンドに渡すことができるように、WLAN phyの名前を取得するにはどうすればよいですか?

上記が比較的単純であることを望んでいましたが、udevadm infoに明確な区別要素はありません。

3
rkjnsn

これらの情報のほとんどは、/sysから取得できます。

1a。 /sys/class/net/:含まれるすべてのタイプのネットワークデバイスのリスト

1b。 /sys/devices/virtual/net/:仮想ネットワークデバイスのリスト:lo、トンネル、veth、ブリッジなどが含まれます。したがって、前者にあるがこれにない場合は、物理的である必要があります。

  1. デバイスが最新のワイヤレスデバイス(ドライバー)の場合、エントリ/sys/class/net/<device>/phy82011/nameがあります。例:

    $ grep -s --with-filename ''  /sys/class/net/*/phy80211/name
    /sys/class/net/wlan0/phy80211/name:phy0
    /sys/class/net/wlan1/phy80211/name:phy1
    /sys/class/net/wlan2/phy80211/name:phy2
    

したがって、udev環境から適切なスクリプトを実行し、/sysのディレクトリとファイルと比較することで、それを実行するために必要なすべての情報を入手できます。

補足として、後でこれらのデバイスで作業する場合は、network名前空間(eg using nsenter --net=/var/run/netns/physical)、/sysのみを変更します。ホストのmount名前空間に残り、それらのデバイスの到着を反映しませんが、代わりにそれらが欠落していることを示します。 ip netns exec physical commandを使用しても問題ありません。マウントネームスペースが変更され、/sysが再マウントされます。

3
A.B

A.Bの回答に基づいて、次のルールを思いつきました。

SUBSYSTEM=="net", ACTION=="add", DEVPATH!="/devices/virtual/*", TAG+="systemd", ENV{SYSTEMD_WANTS}="[email protected]"

DEVPATH!="/devices/virtual/*は、物理デバイスのみを取得するための鍵です。 [email protected]は、インターフェースを目的の名前空間(physical)に移動するワンショットサービスです。

[Unit]
Description=Move interface to physical namespace
[email protected]
[email protected]

[Service]
Type=oneshot
ExecStart=/usr/local/sbin/move-netif %I physical

[email protected]指定された名前のネットワーク名前空間を作成するだけです。)

最後に、 move-netifは、インターフェースを移動する方法を理解する責任があります。

#!/bin/bash

devpath="$1"
target_ns="$2"

if [[ -e "$devpath/phy80211" ]]; then
  phy="$(basename "$(readlink "$devpath/phy80211")")"
  iw phy "$phy" set netns name "$target_ns"
else
  ifname="$(basename "$devpath")"
  ip link set "$ifname" netns "$target_ns"
fi
4
rkjnsn