Raspbian stretchのネットワークインターフェースの初期化過程を調べてみる

Raspberry Pi 3
ネットワークのインターフェース名が変わってしまい戸惑っています。新しい名前に変更しても今まで通りに動かなかったりします。
まずはRaspbian stretchのネットワークインターフェースがどのように初期化されるのか調べてみます。


前回の記事 Raspbian stretchのインターフェース設定に苦戦中です
で愚痴りましたようにRaspbian stretchのネットワーク周りをうまく動かすことができません。
アクセスポイント化しようとしたらネットワークが起動しなくなったり、WiFiの認証が動かなかったり。これは改めて初期化の手順を追ってどこで何がどう設定されるか理解しないとダメなようです。

初期化はどこで行われているの?

順番に見ていきたいのですが私はLinuxに詳しくはありません。できるだけWindowsユーザー視点で書いていきます。
Linuxはディストリビューションやそれぞれのバージョンによって多種多様な初期化の仕方があります。初心者を振るい落とす難関です。
Raspbianでもwheezyとjessieではかなり違います。フォーラムでも区別がついていない書込みがあります。これにstretchが加わったのですから大変です。

Raspbian stretchはDebian 9 stretchベースであり、よりsystemdやudevという仕組みを使うようになってきているはずです。
少なくともインターフェース名はudevで決定しているようです。

udevで何をしているかを表示してくれる便利なコマンドudevadmというのがあります。やってみます。

インターフェース名の確認

その前にネットワークインターフェースの一覧を確認します。
$ ls -1 /sys/class/net
enxaabbcc001122
lo
wlan0
これはRaspberry Pi 3での例です。enxで始まるのが有線LANです。aabbcc001122の部分はMACアドレスになっています。wlan0はWiFiです。RPi3のオンボードWiFiです。USB接続ではないため以前と名前は変わっていません。オンボードLANは内部でUSBで接続されているため名前が変わりました。
USBで他のネットワークインターフェースを接続していれば認識されたインターフェースが表示されているでしょう。

udevadmで初期化の確認

それではudevadmを実行してみます。testコマンドでudevの動作をシミュレーションできるそうです。
sudo udevadm test /sys/class/net/enxaabbcc001122
コマンド最後の部分は先ほど確認したご自分のインターフェース名に置き換えてください。
結果は長いですね。こんな風に書かれている場所があるはずです。
Reading rules file: /lib/udev/rules.d/99-systemd.rules
rules contain 196608 bytes tokens (16384 * 12 bytes), 25016 bytes strings
17530 strings (143345 bytes), 15103 de-duplicated (120757 bytes), 2428 trie nodes used
IMPORT builtin 'net_id' /lib/udev/rules.d/73-usb-net-by-mac.rules:13
NAME 'enxaabbcc001122' /lib/udev/rules.d/73-usb-net-by-mac.rules:13
IMPORT builtin 'net_id' /lib/udev/rules.d/75-net-description.rules:6
IMPORT builtin 'usb_id' /lib/udev/rules.d/75-net-description.rules:8
/sys/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.1/1-1.1:1.0: if_class 255 protocol 0
IMPORT builtin 'hwdb' /lib/udev/rules.d/75-net-description.rules:8
RUN 'ifupdown-hotplug' /lib/udev/rules.d/80-ifupdown.rules:5
IMPORT builtin 'path_id' /lib/udev/rules.d/80-net-setup-link.rules:5
IMPORT builtin 'net_setup_link' /lib/udev/rules.d/80-net-setup-link.rules:9
Config file /lib/systemd/network/99-default.link applies to device enxaabbcc001122
ルールが全て読み込まれたら条件に合った処理行われます。番号の若い順にルールが適用され、最後にまとめて設定されるようです。
"/lib/udev/rules.d/73-usb-net-by-mac.rules"というファイルのルールで名前が変更されているようです。
"/lib/udev/rules.d/80-ifupdown.rules"でhotplugオプションが指定されているインターフェースを起動しているようです。

"/lib/udev/rules.d/73-usb-net-by-mac.rules"ファイルを開いて見ましょう。
# Use MAC based names for network interfaces which are directly or indirectly
# on USB and have an universally administered (stable) MAC address (second bit
# is 0). Don't do this when ifnames is disabled via kernel command line or
# customizing/disabling 99-default.link (or previously 80-net-setup-link.rules).

IMPORT{cmdline}="net.ifnames"
ENV{net.ifnames}=="0", GOTO="usb_net_by_mac_end"

ACTION=="add", SUBSYSTEM=="net", SUBSYSTEMS=="usb", NAME=="", \
    ATTR{address}=="?[014589cd]:*", \
    TEST!="/etc/udev/rules.d/80-net-setup-link.rules", \
    TEST!="/etc/systemd/network/99-default.link", \
    IMPORT{builtin}="net_id", NAME="$env{ID_NET_NAME_MAC}"

LABEL="usb_net_by_mac_end"
ブートパラメータから変数を持ってきています。/boot/cmdline.txtファイルに"net.ifnames=0"を設定すると旧式の命名になるのはここで条件判断しているからですね。

udevでの処理が分かってきました。
名前の変更はudevで行われています。カーネルのブートパラメータで処理を飛ばすことができます。
すべてのルールの処理を行った後、システムへの反映はまとめ実行されます。つまり一番最後にルールを追加しておけば設定の上書きが可能です。それはおそらく"/etc/udev/rules.d"で行えるでしょう。
名前を変更あるいはSYMLINKでエイリアス名を設定したい場合も、udev処理の一番最後でやれば良さそうです。

私が/etc/network/interfacesを設定して再起動後にネットワークが動かなかったのはhotplugの指定をしていなかったのが原因のようです。jessieの時はそれでも動いていたのですが、より正しい動作になったと解釈しましょう。

ネットワークが動くのはなぜ?

ですが初期状態の/etc/network/interfacesフィルには何も記述されていません。どこかにhotplugの指定があるのでしょうか?
ifquery --list --allow=hotplug
と実行すると何も返ってきません。これは理解できます。何も書いてないのですから。

ですが有線LANをつなげば自動的にリンクが確立されます。WiFiも動きます。どこの誰がやってくれているのか、結局分からなくなりました。/etc/network/interfacesを使わないでネットワークの設定をする方法もあります。最近ではGUIに対応したネットワークのマネジメントツールもあるようです。しかしRaspbian stretchには入っていないようです。
という事は似たような何かが設定をしているはずなのですが・・・

起動時の初期化に関係しそうな設定ファイルを手当たり次第に開いて動きそうなプログラムを調べます。"/etc/default"ディレクトリに"avahi-daemon"なるファイルがあるのを見つけました。ネットに関わる事はわかりました。このファイル設定は生きているようです。
avahi-daemon"が何者なのか全く知識がありません。まずは動いているか探してみます。ログを検索してみます。
journalctl --all | grep  avahi
とすると動いているようです。
簡単に調べるとZeroconfとかいうネットワークを動かす最低限の仕組みのようです。お手軽で良いのですが、こういう基本的なことはRaspbianのマニュアルに書いて欲しいです。基本的なことほど暗黙知を必要とされるLinuxは面倒です。それともどこかに書いてあるのかな?

avahi-daemonがどうやって動き出すのか、他の設定と競合しないのか詳しい事は調べませんでした。
このまま/etc/network/interfacesの設定をすればこちらが優先されるようです。さて、これで本題のinterfacesのネットワーク名をどうするか・・・という点に注力できます。

あとがき

もしかして、
/etc/network/interfacesファイルに何も書かれなくなったのは、書けなくなったからでは?!
という疑念が・・・

Predictable Network Interface Namesでは何種類かのネットワーク名の命名方法があります。今回、Raspbian stretchではMACアドレスに基づくルールが追加されました。
/etc/network/interfacesをいじる汎用的なスクリプトにするには全ての命名方法を考慮しなくてはなりません。命名方法はいつでもユーザーが変更できます。命名方法の変更に合わせて/etc/network/interfacesの記述も変更しなくてはなりません。そうしなければネットワークは動かないのです。リモート管理のコンピュータで間違えて命名規則を変更したら面倒な事になりますね。

/etc/network/interfacesはPredictable Network Interface Namesとの相性がとても悪いです。どちらかを廃止しなくてはならないくらいだと思います。/etc/network/interfacesに代わる方法がもうあるのでしょうか?ご存知でしたらぜひ教えてください。
抽象化したインターフェース名にして物理インターフェースを覆い隠すのがスマートなはずで、Linuxな方々がそれをしないはずは無いと思うのですが。なんでこんな事になっているのでしょう。

Red Hatディストリビューションは早くからPredictable Network Interface Namesを導入していたようです。そちらの解決方法を検索する必要がありそうです。

やはり、旧式の命名方法にしてね、とするしかないのか・・・

コメント

最近のコメント

Threaded Recent Comments will be here.