2006.09.11 netgraph(4)を攻略してみる netgraph(4) は簡単だけど難しいね。ってことで。 netgraph はグラフベースのカーネルネットワークサブシステムで, 既存の ネットワークサブシステムを置き換えるよりもむしろ, 補完するための仕 組みを提供します。もっと色々と特徴はあるけど詳しくは netgraph(4) の マニュアルを読んで欲しい。 補完するネットワーク機構は色々なものがあるが(7-current で見ると 56 個あるし, ports でもいくつか提供されている), 有名どころは 2〜3 個, 世間的に(?) 使われてるのは 10 個程度であろう。独断と偏見で選ぶとす れば下記の通りとなる。 有名どころ ng_bluetooth Bluetooth ドライバー ng_pppoe PPPoE ドライバー ng_nat NAT 機能 使われてそうなもの ng_bridge イーサネットブリッジ(L2)ドライバー ng_eiface ngeth? インターフェース(L2 モノで使用) ng_ether NIC を netgraph ノードへ組み込む ng_fec Fast EtherChannel ドライバー ng_iface ng? インターフェース(L3 モノで使用, PPPoE等) ng_ipfw netgraph サブシステムと ipfw(4) をつなぐインターフェース ng_ksocket kernel socket を netgraph ノードへ組み込み ng_one2many パケット多重化ドライバー ng_socket socket を netgraph ノードへ組み込み ng_vlan IEEE 802.1q VLAN タギングドライバー このうちいくつかについてコメントするとしたら… ng_bridge if_bridge(4)を使った方が簡単だし, ifconfig(8) で確認でき るので使用はお勧めしない。 ng_one2many いわゆる複数の NIC を使ってパケットの送受信を行うことを 実現するための仕組みで(例えば FastEther ×2 であたかも 200Mbps のインターフェースを持つような), 残念ながら, 同 じことする ng_fec を使った方がいいです。どっちも Cisco なプロトコル(よって Cisco 製のスイッチが必要)ですが, one2many をサポートしている古い機器は見つけるのが大変か もしれません。 ng_fec Fast EtherChannel です。Cisco の人(?)なら萌えるキーワー ドでしょう。NIC の先が, Cisco のスイッチか ng_fec 使っ てる FreeBSD を使うなら, ×n な世界を堪能できます。 ng_vlan if_vlan(4)を使った方が簡単だし, ifconfig(8)で確認できる ので使用はお勧めしない。 というわけで(?)かなぁ〜り玉石混合だったりする。 netgraph(4)について調べていて思うのは「ノード」がどのような形態 をとるか, という点が重要だと思っています。調べた中で…の話なので 全てのノード(モジュール)を分類した分けではありませんが, おおよそ 下記の通りとなります。 1. ノード自動生成型(ng_ether, ng_atm) これらの netgraph モジュールを組み込んだ瞬間から netgraph ノードが作成されます。モジュールを取り外す以外でノードを削 除する方法(ngctl shutdown は失敗する, ngctl rmhook は無視) はありません。削除できない, という意味では非常に特殊なノー ドとなります。なお通常の方法での削除の話なので, kldunload するなどで, ng_ether やインターフェースが消えると, 削除さ れます。 2. ノード手動生成型(ng_iface, ng_eiface) ngctl mkpeer . という形で, 半ば独立したノード(他のノードと の connection を持たない)を作成することができます。 3. 他ノード依存生成型(たぶんほとんど) ノード作成にあたって(ngctl mkpeer), 他ノードが存在すること が前提として, そのノードに引っかける(hook)ことで自分を作成 するタイプです。こういう風に制限することで片足を引っかけて, ngctl connect で両足ともに接点を持たせる, という仕組みにな っています(わけわかめ)。この事に気が付くまでに, 無駄にノー ドばかり作ってました:-)。 直観的には, ノード生成が他ノードに*従属する*形で作らなけれ ばならないため, 独立して組み合わせができそうなノードを作る 時でも, 一々指定しないといけません。これはノードを先に作っ て, 後から結びつけるということができないので, 事前にどうや ってつなげるか考えておかなければなりません:-)。 またこの結び付けは後から変更することができませんので, 間違 ったらノード削除から行うことになります。もっとも, ngctl rmhook と ngctl connect を駆使して, 片足づつ外せなくもないので, 根性でやろうと思えばできなくもないかもしれません。という けで, *根性で*, mkpeer 時とは別のノードに梯子替えできそ うなので, 「なんでこんな制限(?)があるのか不思議だけど, ま ぁ実装の問題だろうなぁ〜」と思いつつ, バッドノウハウとし て記憶しておく:-)。 netgraph いじり netgraph(4) を使い倒すなら ngctl(8) コマンド一つあればいいく らい, 設定が統一化されています。あと nghook(8) というコマンド がありますが, 無視していいでしょう:-)。 a. ノードの作成 ノード生成は大別して 2 つあります(上記 2, 3) ngctl mkpeer iface dummy inet (ノード手動生成型) ngctl mkpeer eiface dummy ether (ノード手動生成型) ngctl mkpeer rl0: bridge lower link0 (他ノード依存生成型) ngctl mkpper rl0: atmllc upper ether (他ノード依存生成型) 手動生成型は独立したノードが生成されるが, 他ノード依存型では ノード生成とともに, 他ノードとの結びつけ(hook)も行われる。 b. ノードの削除 ノードの削除が行える。ノード名が付いていない場合( と表示される)は ID の値を [] で括ってやって指定することにな る。通常運用ではノード名を付けた方がいいでしょう(ngctl name)。 ngctl shutdown ng0: ngctl shutdown ngeth0: ngctl shutdown '[0x7]': (ノード名が無い場合) なお, hook の関係によっては, つまり消えては困るノードがある 場合は, 指定されたノードが消えないこともあります。依存に注 意して消しましょう:-)。 c. ノード名を付ける 下記のようにしてノード名を付けることができる。ノード名 (path名)を指定するときは, 最後に : を付けるルールになる が, ngctl name の場合, 不要なので注意:-)。 ngctl name '[0x7]' br0 (rl0:lower と指定することも可) ngctl name rl0:upper atmllc0 d. ノードのリスト一覧 ngctl list e. ノードタイプの一覧 ngctl types f. ノードの接続図の作成 事前に graphics/graphviz をインストールしておく必要がある。 これを使うと, ノード間の接続を視覚化して確認することができ る。まぁただのテキストファイルなので直接眺めるもよし。 ngctl dot > /tmp/netgraph.dot; dotty /tmp/netgraph.dot g. ノード-ノード間の接続 ngctl mkpeer で片足(?)だけ接続できたところで, 残りの接続 を行う場合に使用する。 ngctl connect rl0: br0: upper link1 ngctl connect atmllc0: rl0: atm lower h. ノードの状態表示 ノードの接続状態を確認できる。ノード接続が成功している(?) 場合はもっとも状況がわかりやすい表と言える。 ngctl show atmllc0: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # ngctl show atmllc0: Name: atmllc0 Type: atmllc ID: 000000af Num hooks: 2 Local hook Peer name Peer type Peer ID Peer hook ---------- --------- --------- ------- --------- atm rl0 ether 00000002 lower ether rl0 ether 00000002 upper - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - i. 他にも… よく使うものとしては ngctl msg とか, まぁ覚えておいて損はあ りえそうな ngctl rmhook とか, 色々コマンドはありますが, モ ジュール依存なのでここでは省略しておく。 参考文献: オープンソースマガジン 2006年7月号 P141〜P146 FreeBSD でネットワーク自由自在 by 佐藤広生 http://people.allbsd.org/~hrs/FreeBSD/fig.ng_ether.bmp http://ezine.daemonnews.org/200406/netgraph.html http://ezine.daemonnews.org/200003/netgraph.html Written by 重村法克