NICのバレルロール解消のススメ

Linux、おもにFedoraやCentOSでNICを複数枚指して、でもHDDをリムーバブルする関係上、MACアドレスによるバインドが不可能で、それでもNICとeth0,eth1の対応関係を変化させたくない。

そんな悩みを抱えているニッチすぎる方へのご提案です。
Fedora12でしか試してません。実際どうなるかは試してみてください。

さて、LinuxがHWを認識するのは、udevの働きであることは周知のとおりです。
以下、某所のudevガイドの翻訳文を引用します。
•ユーザスペースでの実行

•デバイスファイルを動的に作成/削除
•一貫性のある命名規則の提供
•ユーザスペース向けAPIの提供
つまりudevは、上記の目標をもって開発された、動的にハードウエアを認識しつつ、それをユーザー側からは一意に認識するためのツールである、という認識でよいのかなと思います。

Linuxにおいて、ハードウエアの増設などで、ディバイスの変更のイベントが検知されると、カーネルはその命名のためにudevに確認を求め、udevは/etc/rules.d/以下のルールファイルを適用します。その際、命名に際して使用するのは、カーネルから渡された値。つまりはlsmodやlspciなどのコマンドで得られる、ドライバ認識情報だそうです。

さて、NIC認識において、udevは以下のファイルを読んで、ディバイス認識を行います。
 vim /etc/udev/rules.d/70-persistent-net.rules
が、これも既知の問題ですが、udevは重複したディバイスを認識する時、その認識順序は安定せず、またこの問題の根本的な解決方法は、同一製品の場合は非常に難しいとされています。

理由は簡単です。
ドライバ認識レベルで、カーネルが認識できそうな情報は、ざっと考えたところ、
  • MACアドレス
  • ドライバ名称
この二つくらいです。
そして、ことLinuxにおいて。互換ドライバやその他カスタムドライバを使わざるを得ない状況が、日常的に発生するこのOS上では、ドライバ名に依存したシステムは非効率といわざるをえません。
当然、udevの上記NICのルールファイル中でも、認識したHWはMACアドレスで認識をしています。
そもそも、MACアドレスはPC上での個体識別番号ですので、不思議はありません。

ごく基本的なことですが、説明を重ねます。
ネットワークカード(以下NIC)はMACアドレスをもっており、16進数12ケタとなっています。このうち、前6けたがメーカを表すベンダーコード、残り6けたで製品固有の番号を表します。

よって今回のメソッドでは、異なメーカーのNICを使用していることを想定して、ベンダーコードによるふるいわけを実現しています。

以下、そのための実現プロセスを記述します。


以下の例文ファイルでは、VM上のデタラメMACアドレスをもった仮想NIC、AMD(上)とインテル(下)に代役を頼んであります。

 # PCI device 0x1022:0x2000 (pcnet32) AMDの仮想NIC
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="08:00:11:bb:bb:bb", ATTR{type}=="1", KERNEL=="eth*", NAME="eth1"


# PCI device 0x8086:0x100e (e1000) インテルの仮想NIC
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="08:00:00:aa:aa:aa", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"

※ベンダーコードも便宜上適当です。

HDDを抜き差しして持ち歩く実習室のような環境では、MACアドレスごとに定義が増えていくので、ethX(X=1,2,・・・n)が無限増殖することとなります。

 そこで、とある偉大な先輩は、このeth無限増殖の解決策として、このrulesファイルを、終了時にcronで消去する、便利なスクリプトを組んでくれました。

が、ここで別の問題がでてきました。
いちいち終了時にrulesファイルを消去すると、次にeth0の名前をゲットできるのが、上の例ではAMDかintel、どちらのNICなのかが、固定されないのです
これが、上記udevの仕様上の限界です。

よって、sysconfigでDEVICE=eth0と記述した場合、どっちか先ににeth0をゲットしたほうにこの設定値が割り振られるため、BOOTPROTO=staticにしていると、もう片方の通常使っていない(多くはケーブルが刺さっていない)NICを見にいってしまいます。
結果、ネットがつながらないことになります。

そこで、今回このMACアドレス指定の一部を、ワイルドカード指定します
今回は、ベンダーコードをそのままのこして、個体コードをワイルドカードすることにより、メーカーを識別してeth0,eth1を割り振ります。

# PCI device 0x1022:0x2000 (pcnet32)

SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="08:00:11:??:??:??", ATTR{type}=="1", KERNEL=="eth*", NAME="eth1"

# PCI device 0x8086:0x100e (e1000)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="08:00:00:??:??:??", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"

これで、正常起動を確認しました。ちゃんとMACアドレス固定時と同じethに、NICが割り振られて、ネット通信が可能です。
また、仮想NICのMACアドレスの下6けたを変更後も、同じ設定ファイルでの運用が可能であることも確認しました。

が、これには問題があります。
 
① 同メーカ:異ベンダーコードに対応できない
製造ロットなどにより、(Appleなどは顕著ですが)大企業ですと企業一つで、いくつものベンダーコードを持っています。よって、同メーカでもeth2を新規生成してしまう可能性はあります。
 
② 同メーカには対応できない
ちなみに、このベンダコード部を同一にしたNIC2枚で、後半をワイルドカード指定すると、片方のNICがうまく認識されませんでした。が、製品によっては後半のケタで絞り込みが可能かもしれません。
(とくに同一ロットのマザーボードのNICのMACアドレスなど。
この辺は、個別に煮詰めていただく必要があります。

以上です。

コメント