日本語 man コマンド類 (ja-man-1.1j_5) と日本語 man ドキュメント (ja-man-doc-5.4 (5.4-RELEASE 用) など) をインストールすると、以下のような man コマンド閲覧、キーワード検索が コンソールからできるようになります。
4.11-RELEASE-K, 5.4-RELEASE-K, 5.5-RELEASE-K, 6.0-RELEASE-K から 6.4-RELEASE-K, 7.0-RELEASE-K から 7.4-RELEASE-K, 8.0-RELEASE-K から 8.4-RELEASE-K, 9.0-RELEASE-K から 9.3-RELEASE-K, 10.0-RELEASE-K から 10.3-RELEASE-K, 11.0-RELEASE-K から 11.4-RELEASE-K, 12.0-RELEASE-K, 12.1-RELEASE-K は、 プライベート版 (小金丸が編集してまとめたもの) ですが、 より多くの翻訳したファイルが含まれています。 (5.4-RELEASE-K から 6.4-RELEASE-K, 7.0-RELEASE-K から 7.4-RELEASE-K, 8.0-RELEASE-K から 8.4-RELEASE-K, 9.0-RELEASE-K から 9.3-RELEASE-K, 10.0-RELEASE-K から 10.3-RELEASE-K, 11.0-RELEASE-K から 11.4-RELEASE-K, 12.0-RELEASE-K から 12.4-RELEASE-K, 13.0-RELEASE-K から 13.3-RELEASE-K, 14.0-RELEASE-K から 14.1-RELEASE-K は、全翻訳済み)
13.3-STABLE-K, 15.0-CURRENT-K は現在、作成中で日々更新されています。
Table of Contents
NETGRAPH(4) FreeBSD カーネルインタフェースマニュアル NETGRAPH(4) 名称 netgraph -- カーネルネットワークサブシステムを基づくグラフ 解説 netgraph システムは、様々なネットワーク機能を実行するカーネルオブジェクト の実装のための均一でモジュール化されたシステムを提供します。ノードとして 知られているオブジェクトは、任意の複雑なグラフとしてアレンジすることがで きます。ノードは、グラフでエッジ (端) を形成して、2 つのノードを一緒に接 続するために使用されるフックを持っています。ノードは、データを処理する、 プロトコルを実装するなどのためにエッジ (端) に沿って通信します。 netgraph の目的は、既存のカーネルネットワークインフラストラクチャ (基盤) を置き換えるよりはむしろ補うことです。それは、次を提供します: • プロトコルとリンクレベルドライバを組み合わせるフレキシブルな方法。 • 新しいプロトコルを実装するためのモジュール化した方法。 • カーネル実体が相互通信するための共通のフレームワーク (枠組み)。 • 合理的に速くて、カーネルベースの実装。 ノートとタイプ netgraph で最も基本的な概念はノードのものです。すべてのノードは、明確な方 法で他のノードとそれらと交信する多くの前もって定義されたメソッドを実装し ます。 各ノードには、ノード作成時間に確定されるノードの静的な特性であるタイプが あります。ノードのタイプは、ユニークな ASCII タイプ名によって表現されま す。タイプは、ノードが何を行うか、そしてどのように他のノードと接続される かという意味を含みます。 オブジェクト指向言語では、タイプは、クラスであり、ノードは、それらの個別 のクラスのインスタンスです。すべてのノードタイプは、一般的なノードタイプ のサブクラスであり、したがって、ある共通の機能と能力 (例えば、ASCII 名を 持つ能力) を継承します。 ノードは、ノードを参照するために使用できるグローバルでユニークな ASCII 名 に割り当てられます。名前は、文字 `.' または `:' を含んではいけません、そ して、NG_NODESIZ 文字 (終端の NUL バイトを含んで) に制限されています。 各のノードのインスタンスには、32 ビットの 16 進数値で表現されるユニークな ID 番号があります。この値は、それに割り当てられた ASCII 名がないとき、 ノードを参照するために使用されます。 フック ノードは、各ノードから 1 つの、1 組のフックを接続することによって他のノー ドに接続されます。データは、接続された 1 組のフックに沿ってノード間を双方 向で流れます。ノードには、必要とするくらい多くのフックがあり、フックに必 要とされるどんな意味も割り当てられます。 フックには、これらの特性があります: • フックは、そのノード上のすべてのフックの中でユニークな (他のノード上 の他のフックには、同じ名前があるかもしれません) ASCII 名があります。 名前は、文字 `.' または `:' を含んではいけません、そして NG_HOOKSIZ 文字 (終端の NUL 文字を含んで) に制限されています。 • フックは、常に別のフックに接続されます。すなわち、フックは、それらが 接続されるとき作成され、どちらかのフックが取り除かれ両方のフックが破 壊されることによってエッジ (端) は、切断されます。 • フックは、着信パケットが直接配信されるよりむしろ入力キューシステムに よって常にキューに入れられる状態の中に設定することができます。割り込 みハンドラからデータを送るとき、これを使用することができ、処理は、他 の割り込みをブロックしないように迅速でなければなりません。 • フックは、最優先の受信データと受信メッセージ関数を供給できます。その 受信メッセージ関数は、一般的なノード全体のメソッドに優先してそのフッ クを通して受信されたデータとメッセージのために使用されるべきです。 ノードは、特別な意味をいくつかのフックに割り当てると決定します。例えば、 debug というフックに接続することは、そのフックにデバッグ情報を送信し始め ることによってノードは、トリガされます。 データフロー 2 つのタイプの情報がノード間を流れます: データメッセージとコントロール メッセージです。データメッセージは 1 度に 1 つのエッジをグラフ中のエッジ に沿った mbuf チェーンで渡されます。チェーンにおける最初の mbuf は M_PKTHDR フラグが設定されなければなりません。各ノードは、フックの 1 つを 通して受信されたデータを操作する方法を決定します。 また、データと共に、ノードは、コントロールメッセージを受信することができ ます。汎用とタイプ特有のコントロールメッセージがあります。コントロール メッセージは、共通のヘッダ形式があり、タイプ特有のデータが続き、効率のた めにバイナリ構造体です。しかしながら、ノードタイプは、デバッグとヒューマ ンインタフェース目的 (以下の NGM_ASCII2BINARY と NGM_BINARY2ASCII 一般的 なコントロールメッセージを参照) のためにバイナリと ASCII フォーマット間の 特有のデータのタイプの変換もサポートします。ノードは、これらの変換をサ ポートする必要はありません。 コントロールメッセージをアドレス指定する 2 つの方法があります。2 つのノー ドを接続するエッジのシーケンスがあるなら、メッセージは、メッセージ (相対 アドレシング) のための宛先 (終点) アドレスとして ASCII フック名に対応する シーケンスを指定することによって、``ソース (始点) 経路'' となります。宛先 (終点) が発信元 (始点) に隣接しているなら、発信元 (始点) ノードは、単に、 メッセージが送られるべきであるフックを (コードのポインタとして) 指定しま す。そうでなければ、受取人のノードのグローバルな ASCII 名 (または同等な ID を基とする名前) は、メッセージ (絶対アドレス指定) の宛先 (終点) アドレ スとして使用されます。2 つのタイプの ASCII アドレス指定は、絶対開始ノード とフックのシーケンスを指定することによって結合されます。ASCII アドレッシ ングモードだけが、カーネルの外で制御プログラムに利用可能です。ダイレクト ポインタの使用は、カーネルモジュールに制限されます。 メッセージは、しばしば反対の方向の応答メッセージがあとに続くコマンドを表 します。これを容易にするために、アドレス指定された応答のために適切な ``返 送アドレス'' をコントロールメッセージの受取人に提供します。 各コントロールメッセージは、メッセージのタイプ、すなわちそれをどのように 解釈するか、を示す ``typecookie'' と呼ばれる 32 ビットの値を含んでいま す。通常、各タイプは、解釈するというメッセージのためにユニークな type cookie を定義します。しかしながら、ノードは、2 つ以上のタイプのメッセージ を認識して実装するために選択することができます。 メッセージが (その ID またはグローバルな名前を使用することで直接アドレス 指定されたのと対照的に) それが特定のフックを通してそのノードに到着したア ドレスを含むアドレスに配信されるなら、フックは、その受信ノードに特定され ます。メッセージは、再ルートされるか受け継がれることができ、データパケッ トがノードの間で渡されるのとほぼ同じ方法で、これが必要なノードが決めるべ きです。フロー制御とリンク管理目的のための一連の標準のメッセージは通常、 このように渡されるベースシステムによって定義されます。通常、フロー制御 メッセージはそれらが関係するデータと逆の方向に進行します。 netgraph は (通常) 機能的 待ち時間を最小にするために、ほとんどの netgraph 操作は、機能的です。すな わち、データとコントロールメッセージは、キューとメールボックスを使用する ことよりむしろ関数呼び出しを行うことによって配信されます。例えば、ノード A がデータ mbuf を隣接しているノード B に送りたいなら、一般的な netgraph データ配信関数を呼び出します。この関数は、順番にノード B と呼び出し B の ``受信データ'' メソッドを位置付けます。これへの例外があります。 各ノードには、入力キューがあり、それらがノードの状態を変更するので、いく つかの操作は writers (書き込み側) となると考えることができます。明らか に、SMP 世界では、別のデータパケットがノードを通過していた間、ノードの状 態を変更されるなら、悪くなるでしょう。このために、入力キューはノード中に 書き込み側があるときのように reader/writer (読み込み側/書き込み側) セマン ティックを実装し、他のすべての要求は、キューに入れられ、さらに読み込み 側、書き込み側、どんな次のパケットもキューに入れられます。データをキュー に入れる理由がない場合では、入力メソッドは、上記のように直接呼び出されま す。 ノードは、すべての要求が書き込み側とみなされはずであるか、または特定の フックを越えて入る要求が書き込み側であるとみなされるはずであるか、または 特定のフックを越えて去るかまたは入るパケットは (すばやくハードウェアに戻 りたい割り込みルーチンでしばしば役に立つ) 直接配信するよりむしろ常に キューに入れるべきであると宣言するかもしれません。デフォルトで、すべての コントロールメッセージパケットはそれらの定義で読み込み側であることを明確 に宣言されない場合、書き込み側であるとみなされます。 (<netgraph/ng_message.h> 中の NGM_READONLY を参照してください。) この操作モードが良い性能の結果となりますが、ノード開発者のためにいくつか の意味を持っています: • ノードがデータかコントロールメッセージを配信するするときは、いつも、 ノードは、オリジナルの配信関数呼び出しが返る前に返っているメッセージ を受信する可能性を考慮する必要があります。 • netgraph は、ノードの間の内部の同期を行います。データは、常にエッジ ノードで ``グラフ'' に入ります。エッジノードは netgraph とシステムの ある他の部分の間をインタフェースで接続するノードです。``エッジノー ド'' に関する例は、デバイスドライバ, socket, ether, tty と ksocket ノードタイプを含んでいます。これらのエッジノードでは、呼び出しスレッ ドは、ノードで直接コードを実行し、そしてグラフ中でいくつかのエッジの 向こう側にデータを配信するために netgraph フレームワークでの要求する コードから実行します。実行の観点から、呼び出しスレッドは netgraph フ レームワークメソッドを、そうするためにロックを取得できるなら、次の ノードの入力メソッドを実行します。データがいくつかのデバイスかシステ ムエンティティ (実体) のために破棄されるか、キューに入れられるか、ま たはスレッドが次のノードでロックを取得することができないかのいずれか まで、これは、続きます。その場合には、データは、ノードのためにキュー に入れられ、実行は、オリジナルの呼び出しエンティティ (実体) に rewind back します。訳注: 意味不明。キューに入れられたデータは、それらの操作 を完了したとき、ロックの現在の所有者かそれとも、そのようなキューに入 れられた item があるとき活性化された特別の netgraph スレッドによって (キューから) 取り出し、処理されます。 • グラフがサイクルを含んでいるなら、無限ループが起こる可能性がありま す。 今までのところ、これらの問題は、実際に問題があると判明しませんでした。 カーネルの他の部分との相互作用 ノードには、デバイスハードウェア、カーネルプロトコルスタックなどのように netgraph サブシステムにおけるカーネルの外側の他のコンポーネントとの隠され た相互作用があります。事実上、netgraph の利点の 1 つは、一貫した通信フ レームワークでの異種のカーネルネットワークエンティティ (実体) を結合させ る能力です。 実例は、プロトコルファミリ PF_NETGRAPH で netgraph ノードと socket(2) の 両方である socket ノードタイプです。ソケットノードでユーザプロセスは netgraph に参加できます。他のノードは、普通のメソッドを使用するソケット ノードを使用して通信し、ノードは、協力ユーザプロセスとやりとりする情報も 渡されたという事実を隠します。 別の例は、ハードウェアへのノードインタフェースを提示するデバイスドライバ です。 ノードのメソッド ノードは、次のノードメソッドへの関数呼び出しによって次の動作について通知 され、そして受け付けるか、または (適切なエラーコードを返して) 拒絶されま す: 新しいノードの作成 タイプのコンストラクタが呼び出されます。新しいノードの作成が許される なら、コンストラクタのメソッドはそれが必要とするいくらかの特別のリ ソースを割り付けます。ハードウェアに対応するノードに関しては、一般的 にデバイスのアタッチルーチンの間に行います。しばしば、デバイス名に対 応するグローバルな ASCII 名は、同様にここに割り当てられます。 新しいフックの作成 フックは、作成され試験的にノードにリンクされます、そしてノードは、こ のフックについて説明するのに使用される名前に関して伝えられます。ノー ドは、それが必要とするいくらかの特別のデータ構造体をセットアップする か、またはフックの名前に基づく接続を拒絶するかもしれません。 2 つのフックの成功した接続 両端がそれらのフックを受け付けて、リンクが作られていた後に、ノード は、それらのピア (相手) がリンクされているのが誰かを見つける機会を得 て、次に、接続を拒絶すると決定することができます。分解 (tear-down) は、自動的です。また、これは、ノードが queueing モードに特定のフック (またはそのピア) を設定するかどうか決める時です。 フックの破棄 ノードは、壊れた接続について通知されます。ノードは、いくつかのフック は、クリティカルな操作であり、他は、使い捨てであると考えられます: 1 つのフックの切断は、ノードの全部のシャットダウンに影響するかもしれな い別のものの間に受け付けできるイベントであるかもしれません。 ノードのシャットダウン前処理 このメソッドは、以下で議論される本当のシャットダウンする前に呼び出さ れます。この方法のときに、ノードが完全に操作可能であり、``goodbye'' メッセージをピアに送信することができます、または、チェーンからそれ自 体を取り除き、ng_tee(4) ノードタイプのように、ピアを一緒に再接続する ことができます。 ノードのシャットダウン このメソッドは、ノードをクリーンアップして、このとき実行す必要がある どんな動作も行われることをを保証します。メソッドは、ノードの一般的な コンポーネントを取り除く一般的な (すなわち、スーパクラス) ノードのデ ストラクタを呼び出さなければなりません。いくつかのノード (通常 1 部の ハードウェアに関連している) はシャットダウンは、すべてのエッジ (端) を切断しノードをリセットしますが、それを取り除かないので、永続的で す。この場合、シャットダウン方法は、リソースを解放するべきではありま せんが、むしろ、クリーンアップして、次にシャットダウンが中断される一 般的なコードにシグナルを送るために NG_NODE_REVIVE() マクロを呼び出し ます。ハードウェアの撤去または (ng_rmnode_self() によって) アンロード するために、ノード自体によって開始されたシャットダウンの場合、それ は、存続しないそれ自体のシャットダウン方法にシグナルを送るために NGF_REALLY_DIE フラグを設定すべきです。 送信と受信データ また、他の 2 つのメソッドがすべてのノードでサポートされます: 受信データメッセージ item として通常参照される、netgraph queueable request item (キューに 入れることができる要求 item) は、この関数によって受信されます。item は mbuf へのポインタを含んでいます。 ノードは、どのフックに item が到着するかが通知され、処理決定でこの情 報を使用することができます。受信ノードは、完了時またはエラー時に、常 に mbuf チェーンを NG_FREE_M() (解放) しなければならないか、または他 のノード (またはカーネルモジュール) にそれを渡します。そこでは、それ を解放する責任があります。同様に、item は、それを他のノードに渡さない なら、NG_FREE_ITEM() マクロを使用して解放しなければなりません。item が解放時点で mbuf の参照をまだ保持しているなら、また、それらは、適切 に解放されます。したがって、mbuf が変更されるか item から別々に解放さ れる可能性があるなら、item の中で参照を取り除く NGI_GET_M() マクロを 使用して検索することもたいへん重要です。(または、同じオブジェクトを複 数解放することが生じます。) mbuf の内容のみを調べる必要があるなら、item の中で mbuf ポインタを読 み込み、再書き込みする NGI_M() マクロを使用することができます。 開発者が、mbuf チェーンに伴うどんなメタ情報も渡す必要があるなら、彼は mbuf_tags(9) フレームワーク (枠組み) を使用するべきです。古い netgraph の特定のメタデータ形式が現在時代遅れであることに注意してくだ さい。 受信ノードは netgraph NETISR システム (下記参照) で、キューに入れるこ とによってデータを延期すると決定するかもしれません。データが到着する フックの flags ワードで HK_QUEUE フラグの設定によって達成します。イン フラストラクチャは、直接それを配信するよりむしろビットとその後になっ て配信されるデータをキューに入れることを順守します。ノードは、それ自 体の出力パケットがキューに入れられるように、ピアノードでビットを設定 することに決定します。 ノードは、コード化を簡素化するために特定のフック上で受信されたデータ のために異なった受信データ関数を指名するために選びます。それは、これ をするために NG_HOOK_SET_RCVDATA(hook, fn) マクロを使用します。関数 は、そのフックからのすべての (単に) パケットを受信する以外のあらゆる 方法で同じ引数を受信します。 受信コントロールメッセージ このメソッドは、コントロールメッセージがノードにアドレス指定されると き、呼び出されます。受信されたデータのように、item は、コントロール メッセージへのポインタで受信されます。メッセージは、NGI_MSG() マクロ を使用して調べることができるか、または item の中で参照を取り除く NGI_GET_MSG() を使用して item から完全に抽出するすることができます。 item が解放される (NG_FREE_ITEM() を使用して) とき、まだメッセージの 参照を保持しているなら、メッセージは、適切に解放されます。参照を取り 除いてあるなら、ノードは、NG_FREE_MSG() マクロを使用してメッセージ自 体を解放しなければなりません。返送アドレスは、後でいつでも返答メッ セージを送ることができるように由来するメッセージのノードのアドレスを 与えて、常に供給されます。返りアドレスは、NGI_RETADDR() マクロを使用 して item から検索されます、そしてそのタイプは ng_ID_t です。すべての コントロールメッセージと応答は、タイプ M_NETGRAPH_MSG を malloc(9) で 割り付けられます。しかしながら、メッセージを割り当てて、書き込むため に NG_MKMESSAGE() と NG_MKRESPONSE() マクロを使用すればより便利です。 メッセージは NG_FREE_MSG() マクロを使用して解放されなければなりませ ん。 メッセージが特定のフックを通して配信されるなら、そのフックは、それが 到着したときノードが別のフックでメッセージをそれに転送したがっている ところで、フロー制御メッセージ、および状態変更メッセージのようなもの の使用を許すことが明らかになります。 ノードは、コード化を簡素化するために特定のフック上で受信されたメッ セージのために異なった受信メッセージ関数を指名するために選択できま す。それは、これを行うために NG_HOOK_SET_RCVMSG(hook, fn) マクロを使 用します。関数は、フックからのすべての (唯一の) メッセージを受信する 以外のあらゆる方法で同じ引数を受信します。 すべての参照の解放されたノードが自動的に解放できるように、参照カウントで いろいろ使われ、この振る舞いは ``タイプモジュール'' 書き込みが使用する一 貫して信頼できるフレームワークを提示するためにテストされてデバッグされて います。 アドレス指定 netgraph フレームワークは、明白であり、グラフで任意の 1 つのノードのアド レス指定を記述する方法を簡単に利用できるように提供されます。ノードの名前 付けは、タイプから独立しており、別のノード、または外部のコンポーネント は、一般的なメッセージタイプを送信するためにそれのアドレス指定するノード のタイプに関して何も知る必要はありません。ノードとフック名は、アドレス指 定を意味あるものとするように選ばれるべきです。 アドレス指定は、絶対的または相対的です。絶対的アドレス指定は、ノード名ま たは ID で始まって、コロンがあとに続いて、ピリオドで分離されたフック名の シーケンスが続きます。これは、指定されたノードで始まって、フックの指定さ れたシーケンスが続くことによって到達したノードをアドレス指定します。相対 的アドレスは、ローカルノードで暗黙のうちにフックの横断を始めるフック名の シーケンスだけを含んでいます。 ノード名のための 2、3 の特別な可能性があります。名前 `.' (`.:' として参照 される) は、常にローカルノードを参照します。また、グローバルな名前を持っ ていないノードは、角括弧の中に ID 番号の 16 進数表現を囲むことによって、 それらの ID 番号でアドレス指定ができます。ここに、有効な netgraph アドレ ス指定のいくつかの例があります: .: [3f]: foo: .:hook1 foo:hook1.hook2 [d80]:hook1 次の一連のノードは DLCI 16 と DLCI 20 上の PPP フレームで RFC-1490 フレー ムを備える 2 つのアクティブな論理 DLCI チャネルを持っている 1 つの物理的 なフレームリレーラインでサイトのために作成されるかもしれません: [type SYNC ] [type FRAME] [type RFC1490] [ "Frame1" ](uplink)<-->(data)[<un-named>](dlci16)<-->(mux)[<un-named> ] [ A ] [ B ](dlci20)<---+ [ C ] | | [ type PPP ] +>(mux)[<un-named>] [ D ] 名前 ``Frame1:uplink.dlci16'' を使用することによって、コントロールメッ セージをどこからでもノード C に常に送信することもあり得ます。またこの場 合、ノード C は、フック mux を通してそれに到達したメッセージが通知されま す。同様に、``Frame1:uplink.dlci20'' は、ノード D に確実に到達するために 使用されるかもしれませんし、そして、ノード A は、ノード B を ``.:uplink'' または単に ``uplink'' として参照するかもしれません。逆に、B は ``data'' として A を参照できます。アドレス ``mux.data'' は、ノード A にメッセージ をアドレス指定するために、ノード C と D の両方によって使用されるかもしれ ません。 これはコントロールメッセージのためだけであることに注意してください。それ ぞれのこれらの場合では、相対的なアドレッシングモードが使用されるところ で、発信元のノードと同様に、受信側は、メッセージが到着したフックについて 通知されます。これは、メッセージの中継点ごと (hop-by-hop) の配信のオプ ションと状態情報を許します。データメッセージは、各ノードが次の経路制御 (ルーティング) を決定し、出発フックを指定することによって、一度に 1 つの 中継点 (hop) だけに経路制御されます。したがって、B がフック data でフレー ムを受信するとき、DLCI を決定するためにフレームリレーヘッダをデコードし て、次にアンラップ (包みを解かれた) されたフレームを C か D のどちらかに 転送します。 同様の方法で、フロー制御メッセージは、発信データへの反対の方向に経路制御 (route) されます。例えば、``Frame1:'' からの ``buffer nearly full'' (ほと んどバッファは、満杯) というメッセージは同様のメッセージをノード C と D の両方に送信すると決定するノード B に渡されます。ノードは、メッセージを経 路制御するために direct hook pointer (ダイレクトフックポインタ) アドレス 指定を使用します。メッセージは ``Frame1:'' から同期応答、時間とサイクルの 節約として B に移動するかもしれません。 netgraph 構造体 構造体は (ノードにとって重要なカーネル構造のための) <netgraph/netgraph.h> と (また、ユーザプログラムとって重要なメッセージ定義のための) <netgraph/ng_message.h> で定義されます。 ノードの作者にとって重要な 2 つの基本的なオブジェクトタイプはノードとフッ クです。これらの 2 つのオブジェクトには、ノードの書き込み側にとって重要な 次の特性があります。 struct ng_node ノードの作者は、それらのポインタを宣言するために、常に次の typedef を 使用するべきであり、実際に構造体を決して宣言するべきではありません。 typedef struct ng_node *node_p; 以下の特性は、ノードに関連していて、次の方法でアクセスすることができ ます: 妥当性 ドライバまたは割り込みルーチンは、ノードがまだ有効であるかどうか チェックしたがっているかもしれません。呼び出し側がノードに関する 参照を保持するのでそれは、解放されていないと仮定されます。しかし ながら、それは、無効にされたか、またはそうでなければシャットダウ ンされているかもしれません。NG_NODE_IS_VALID(node) マクロを使用す ると、この状態は、戻ります。結局、無効のノードで実行するコードが ほとんど不可能のはずですが、このとき、その仕事は、終了していませ ん。 ノード ID (ng_ID_t) NG_NODE_ID(node) を使用することでこの特性を検索することができま す。 ノード名 オプションのグローバルでユニークな名前でヌル文字で終る文字列で す。ここに値があれば、それは、ノードの名前です。 if (NG_NODE_NAME(node)[0] != '\0') ... if (strcmp(NG_NODE_NAME(node), "fred") == 0) ... ノードに依存する不透明なクッキー どうようなポインタタイプでもここに置くことができます。マクロ NG_NODE_SET_PRIVATE(node, value) と NG_NODE_PRIVATE(node) は、そ れぞれ、この特性を設定して、検索します。 フックの数 NG_NODE_NUMHOOKS(node) マクロは、この値を検索するために使用されま す。 フック ノードには、多くのフックがあります。すべてのフックが何らかの状態 であるかどうかテストすることができるように縦断方法を提供します。 NG_NODE_FOREACH_HOOK(node, fn, arg, rethook) ここで fn は fn(hook, arg) の形式で、各フックで呼び出される関数で、0 を返すこ とで検索を終了します。検索が終了するなら、rethook は、検索が終え られたフックに設定されます。 struct ng_hook ノードの作者は、それらのポインタを宣言するために、常に次の typedef を 使用するべきです。 typedef struct ng_hook *hook_p; 以下の特性は、ノードに関連していて、次の方法でアクセスすることができ ます: フックに依存する不透明なクッキー どうようなポインタタイプでもここに置くことができます。マクロ NG_HOOK_SET_PRIVATE(hook, value) と NG_HOOK_PRIVATE(hook) は、そ れぞれ、この特性を設定して、検索します。 関連ノード マクロ NG_HOOK_NODE(hook) は、関連ノードを見つけます。 ピアフック (hook_p) この接続された相手の他のフック。NG_HOOK_PEER(hook) マクロは、ピア (相手側) を見つけます。 参照 NG_HOOK_REF(hook) と NG_HOOK_UNREF(hook) マクロは、フック参照カウ ントをそれに応じて、増加して、減少させます。減少の後に、利用者 は、別の参照がまだ有効でないいならフックが解放されたと常に仮定す るべきです。 オーバライド受信関数 NG_HOOK_SET_RCVDATA(hook, fn) と NG_HOOK_SET_RCVMSG(hook, fn) マ クロは、一般的な受信データと受信メッセージ関数に優先して使用され るオーバライド方法を設定するために使用することができます。これら の設定を取り消すには、それらを NULL に設定するマクロを使用しま す。それらは、それらが設定されるフック上で受信されたデータとメッ セージに使用されるだけです。 各ノードのためのフックの名前、参照カウント、およびリンクリストの維持 管理は netgraph サブシステムで自動的に処理されます。通常、ノードのプ ライベート情報は、ノードかフック構造体への逆方向のポインタを含んでい ます。フック構造体は、ノードのための参照カウントに含まなければならな い新しい参照としてカウントします。ノードコンストラクタが呼び出される とき、ノードが破壊されるとき、ノードで忘れずに NG_NODE_UNREF() をする べきであるように、既に計算された参照があります。 フックから、利用者は、対応するノード、およびすべてのアクティブなフッ クを横断することが可能なノードから取得することができます。 どのようにノードを定義するかの現在の例は、 src/sys/netgraph/ng_sample.c でいつも見ることができ、新しいノードの書 き込み側の出発点として使用されるべきです。 netgraph メッセージ構造体 コントロールメッセージには、次の構造体があります: #define NG_CMDSTRSIZ 32 /* 最大コマンド文字列 (ヌル文字を含む) */ struct ng_mesg { struct ng_msghdr { u_char version; /* NG_VERSION と等しくなければ ならない */ u_char spare; /* 4 バイトの詰めもの */ uint16_t spare2; uint32_t arglen; /* コマンド/応答データの長さ */ uint32_t cmd; /* コマンド識別子 */ uint32_t flags; /* メッセージ状態フラグ */ uint32_t token; /* 応答は, 同じトークンがあるべき */ uint32_t typecookie; /* ノードタイプは, このメッセージを 理解している */ u_char cmdstr[NG_CMDSTRSIZ]; /* コマンド文字列 + */ } header; char data[]; /* 実際のデータのためのプレースホールダ */ }; #define NG_ABI_VERSION 12 /* Netgraph カーネル ABI バージョン */ #define NG_VERSION 8 /* Netgraph メッセージバージョン */ #define NGF_ORIG 0x00000000 /* メッセージは, オリジナルの要求 */ #define NGF_RESP 0x00000001 /* メッセージは, 応答 */ コントロールメッセージは、上で示される固定ヘッダがあり、タイプクッキーと コマンドによって決まる可変長のデータセクションが続きます。各フィールド は、次に説明されます: version netgraph メッセージプロトコル自体のバージョンを示します。現在の バージョンは NG_VERSION です。 arglen これは data で始まる、任意の特別の引数の長さです。 flags これがコマンドまたは応答コントロールメッセージであるかどうかを示 します。 token token は、送信側が応答メッセージを対応するコマンドメッセージに一 致させることができる手段です。応答は、常に同じトークン (token) が あります。 typecookie 対応するノードタイプのユニークな 32 ビットの値です。ノードがタイ プクッキーを認識しないなら、EINVAL を返すことによってメッセージを 拒否しなければなりません。 各タイプには、それ自体のメッセージのためにコマンド、引数形式、お よびクッキーを定義するインクルードファイルがあるべきです。type cookie は、同じヘッダファイルが送信側と受信側の両方によって含まれ ていたことを保証します。ヘッダファイルの非互換な変更を行うとき、 typecookie は、変更されなければなりません。ユニークなタイプクッ キーを生成するための事実上のメソッドはヘッダファイルが書き込まれ ているときの (すなわち、``date -u +%s'' の出力) エポックからの秒 数となります。 一般的なノードタイプのために前もって定義された typecookie NGM_GENERIC_COOKIE、およびすべてのノードが理解している対応する一 組の一般的なメッセージがあります。これらのメッセージの処理は、自 動的です。 cmd メッセージコマンドのための識別子です。これは、タイプ特有であり、 typecookie と同じヘッダファイルで定義されます。 cmdstr コマンド (デバッグ目的だけのための) の短い人間が読めるバージョン の場所です。 いくつかのモジュールは、2 つ以上のヘッダファイルからのメッセージを実装す るために選択することができ、したがって、2 つ以上のタイプクッキーが認識さ れます。 コントロールメッセージ ASCII 形式 コントロールメッセージは、効率のためのバイナリ形式になっています。しかし ながら、デバッグとヒューマンインタフェースの目的のために、ノードタイプが サポートしているなら、コントロールメッセージは、同等な ASCII 形式と相互に 変換されるかもしれません。ASCII 形式は、次の 2 つの例外でバイナリ形式と同 様です: 1. cmdstr ヘッダフィールドは cmd ヘッダフィールドに対応している、コマン ドの ASCII 名を含まなければなりません。 2. 引数フィールドは、メッセージ引数のヌル文字で終わる ASCII 文字列バー ジョンを含んでいます。 一般的に、コントロールメッセージの引数フィールドはどんな任意の C データタ イプとなることができます。netgraph は、つぎの簡単な構文を備える ASCII で いくつかの前もって定義されたデータタイプをサポートするために解析ルーチン を含んでいます: • 整数タイプは 8、10、または 16 の基本数で表されます。 • 文字列は、二重引用符で囲まれ、普通の C 言語バックスラッシュエスケープ に順守します。 • IP アドレスは、明白な形式があります。 • 配列は、インデックス 0 で始まる連続してリストされた要素の角括弧で囲ま れます。要素には、それに先行するオプションのインデックスと等号 (`=') があるかもしれません。要素に明白なインデックスがないときはいつでも、 インデックスは、暗黙に要素の前のインデックスに 1 を加えます。 • 構造体は、中括弧で囲まれ、各フィールドは、形式 fieldname=value で指定 されます。 • 値が ``デフォルト値'' と等しい任意の配列の要素か構造体のフィールド は、省略されるかもしれません。整数型では、通常、デフォルト値は 0 で す。文字列型では、空の文字列です。 • 配列の要素と構造体のフィールドは、任意の順序で指定されるかもしれませ ん。 各ノードタイプは、解析するためと非解析するために必要なルーチンを提供する ことによって、それ自体の任意のタイプを定義できます。特定のノードタイプの ために定義された ASCII 形式は、対応するマニュアルページに文書化されていま す。 一般的なコントロールメッセージ 直接フレームワーク自体でサポートされる、すべてのノードのために動作してい る多数の標準の前もって定義されたメッセージがあります。これらは、メッセー ジの基本的なレイアウトと他の同様の情報とともに <netgraph/ng_message.h> で 定義されます。 NGM_CONNECT 両端で供給されたフック名を使用して、別のノードに接続します。 NGM_MKPEER 与えられたタイプのノードを接続し、次に、供給されたフック名を使用 してそれに接続します。 NGM_SHUTDOWN ターゲットノードは、すべての隣接ノードを切断しシャットダウンする べきです。物理的なハードウェアを表すようなパーシステント (持続的) ノードはノード名前空間から消え去るわけではありませんが、単にそれ ら自体をリセットします。ノードは、すべてのフックを切断しなければ なりません。これは、隣接ノード自体のシャットダウンとことによると 全体の接続グラフのカスケード (段階的な) のシャットダウンをもたら すかもしれません。 NGM_NAME 名前をノードに割り当てます。名前を持たないノードは、存在でき、こ れは NGM_MKPEER メソッドを使用することで作成されるノードのデフォ ルトです。そのようなノードは、相対的かまたはそれらの ID 番号での みアドレス指定することができます。 NGM_RMHOOK ノードは、隣接ノードの一つにフック接続を切るように依頼します。両 方のノードは、それらの ``disconnect'' (切断) メソッドを呼び出しま す。どちらのノードも、結果として完全にシャットダウンすることを選 ぶかもしれません。 NGM_NODEINFO ターゲットノードにそれ自体を説明するように依頼します。4 つの返さ れたフィールドは (指定されるなら) ノード名、ノードタイプ、ノード ID とアタッチされたフックの数です。ID は、そのノードにユニークな 内部の数です。 NGM_LISTHOOKS これは、NGM_NODEINFO によって与えられた情報を返しますが、さらに、 各リンクについて説明するフィールドの配列とそのリンクの遠端でノー ドのための説明を含んでいます。 NGM_LISTNAMES これは、指定されたノードについて説明する配列の各エントリである、 (NGM_NODEINFO のような) ノード記述の配列を返します。すべての指定 されたノードが説明されます。 NGM_LISTNODES これは、それらに名前があるかどうかにかかわらず、すべてのノードが リストされていることを除いて、NGM_LISTNAMES と同じです。 NGM_LISTTYPES これは、現在インストールされているすべての netgraph タイプのリス トを返します。 NGM_TEXT_STATUS ノードは、テキストでフォーマットされた状態メッセージを返します。 状態情報は、完全にノードタイプによって決定されます。それは、ノー ドそれ自体の中のサポートを必要とし、このメッセージをサポートしな いように選ぶノードのような唯一の ``一般的な'' メッセージです。テ キスト応答は NG_TEXTRESPONSE (現在 1024) バイトより少なくなければ なりません。これは、人間が読める形式で一般的な状態情報を返すため に使用できます。 NGM_BINARY2ASCII このメッセージは、バイナリのコントロールメッセージを ASCII 形式に 変換します。変換される全体のコントロールメッセージは NGM_BINARY2ASCII メッセージ自体の引数フィールドの中に含まれていま す。成功すれば、応答は ASCII 形式の同じコントロールメッセージを含 みます。ノードは、一般的にそれ自体を理解するメッセージを変換する 方法を知っているだけであるので、NGM_BINARY2ASCII のターゲットノー ドは、しばしば実際にそのメッセージを受信する同じノードです。 NGM_ASCII2BINARY NGM_BINARY2ASCII. の反対です。ASCII 形式で変換される全体のコント ロールメッセージは、NGM_ASCII2BINARY の引数部分に含まれていて、書 き込まれている flags, cmdstr と arglen ヘッダフィールド、および引 数フィールド中の引数のヌル文字で終わる文字列のバージョンのみを必 要とします。成功すれば、応答は、コントロールメッセージのバイナリ のバージョンを含んでいます。 フロー制御メッセージ グラフに関してノードに影響するコントロールメッセージに加えて、メッセージ が定義した多くのフロー制御もあります。現在のところこれらがシステムによっ て自動的に取り扱われないので、それらがフロー制御を利用することでグラフで 使用されて、これらのメッセージのあり得るパスにあるなら、ノードは、それら を取り扱う必要があります。これらのメッセージを理解していないノードのデ フォルト動作はそれらを次のノードに渡さなければなりません。うまくいけばい くつかのヘルパー関数が結局、これを援助します。これらのメッセージは、ま た、<netgraph/ng_message.h> で定義されて、それらを特定するのを助けるため にクッキー NG_FLOW_COOKIE を切り離します。それらは、ここで徹底的にカバー されません。 初期設定 基本の netgraph コードは、静的にカーネルにコンパイルされるか、または kldload(8) によって KLD として動的にロードされます。前の場合には、カーネ ル設定ファイルに options NETGRAPH を含めます。また、利用者は、カーネル編集で選択されたノードタイプを含むこ とができます、例えば: options NETGRAPH options NETGRAPH_SOCKET options NETGRAPH_ECHO netgraph サブシステムがいったんロードされると、個別のノードタイプは kldload(8) によって KLD モジュールとしていつでもロードできます。そのう え、netgraph は、自動的にこれを行う方法を知っています。未知のタイプ type の新しいノードを作成するという要求が行われたとき、netgraph は、KLD モ ジュール ng_<type>.ko をロードすることを試みます。 また、特定のデバイスドライバが netgraph ノードとしてデバイスの各インスタ ンスをエクスポートしたがっているとき、タイプは、ブート時にインストールす ることができます。 一般的に、新しいタイプは、ポインタをタイプ struct ng_type 構造体に供給す る、ng_newtype() を呼び出すことによって、いつでもカーネルからインストール することができます。 NETGRAPH_INIT() マクロは、リンカセットを使用することによって、このプロセ スを自動的に行います。 既存のノードタイプ 現在いくつかのノードタイプが存在します。それぞれは、それ自体のマニュアル ページに完全に文書化されています: SOCKET ソケットタイプは、新しいプロトコルドメイン PF_NETGRAPH で 2 つの 新しいソケットを実装しています。新しいソケットプロトコルは、 NG_DATA と NG_CONTROL で両方ともタイプ SOCK_DGRAM です。それぞれ の 1 つは、一般的にソケットノードに関連しています。両方のソケット がクローズしたとき、ノードは、シャットダウンします。NG_DATA ソ ケットは、送受信データに使用されます、一方 NG_CONTROL ソケット は、送受信コントロールメッセージに使用されます。データとコント ロールメッセージは struct sockaddr_ng ソケットアドレスを使用し て、sendto(2) と recvfrom(2) システムコールを使用して渡されます。 HOLE 一般的なメッセージのみに応答し、データのためには ``ブラックホー ル'' です。テストに役に立ちます。常に新しいフックを受け付けます。 ECHO 一般的なメッセージのみに応答し、到着したフックを通して常にデータ をエコーバックします。それら自身の応答としてどんな一般的でない メッセージを返します。テストに役に立ちます。常に新しいフックを受 け付けます。 TEE このノードは ``覗き見 (snooping)'' に役に立ちます。それには 4 つ のフックがあります: left, right, left2right と right2left です。 right から入るデータは left に渡され、right2left でコピーされ、 left から入るデータは、right に渡され、left2right でコピーされま す。left2right から入るデータは right に送られ、right2left からの データは left に送られます。 RFC1490 MUX カプセル化/非カプセル化されたフレームは RFC 1490 にしたがってコー ド化されます。カプセル化されたパケット (downstream (下流)) のため のフックと各プロトコル (すなわち、IP、PPP など) に 1 つのフックが あります。 FRAME RELAY MUX フレームリレー (Frame Relay) フレームをカプセル化/非カプセル化し ます。カプセル化されたパケット (downstream (下流)) のためのフック と各 DLCI に 1 つのフックがあります。 FRAME RELAY LMI フレームリレー ``LMI'' (リンク管理インタフェース (link management interface)) 操作とパケットを自動的に取り扱います。いくつかの LMI 規格のいずれかは交換のときに使用中であるかを自動的にプローブして 検出します。 TTY また、このノードは、回線制御規則 (line discipline) です。それは mbuf フレームと TTY が netgraph ノードとして現れるのを許容する、 連続したシリアルデータの間で単に変換されます。それには、プログラ ム可能な ``ホットキー (hotkey)'' 文字があります。 ASYNC このノードは、RFC 1662 にしたがって非同期フレームをカプセル化と非 カプセル化します。これは、非同期シリアルラインで PPP リンクをサ ポートするために TTY ノードタイプと連結して使用されます。 ETHERNET このノードは、システム中のあらゆるイーサネットインタフェースにア タッチされます。それは、インタフェースからフレームを送信すること と同様にネットワークから生のイーサネットフレームをキャプチャ (捕 獲) することを許します。 INTERFACE また、このノードは、システムネットワークインタフェースです。それ には、それぞれのプロトコルファミリ (IP、IPv6) を意味するフックが あり、ifconfig(8) の出力で現れます。インタフェースは ``ng0'', ``ng1'' などの名前が付けられます。 ONE2MANY このノードは、簡単なラウンドロビンマルチプレクサ (多重化) を実装 します。例えば、2 台のマシンの間の高速度リンクを取得するためにい くつかの LAN ポートを一緒に作動させるために使用することができま す。 種々の PPP 関連ノード netgraph で実行する完全なマルチリンク PPP 実装があります。 net/mpd5 ポートは、大変低いレイテンシ (待ち時間) の高能力 PPP シ ステムを作るためにこれらのモジュールを使用することができます。ま た、それは、PPTP ノードを使用することで PPTP VPN をサポートしま す。 PPPOE サーバとクライアントは PPPoE の実装をサポートします。ppp(8) か net/mpd5 ポートのどちらかに連動して使用します。 BRIDGE このノードは、イーサネットノードと共に、たいへんフレキシブルなブ リッジシステムを導入できるようにします。 KSOCKET この興味あるノードは、システムへのソケットに似ていますが、さらな る処理のために netgraph システムからすべてのデータを流用します。 これは、UDP トンネルをコマンド行からほぼ自明の実装を行うことをで きるようにします。 より多くのノードタイプについては、このマニュアルページの終りのセクション を参照してください。 注 コントロールメッセージをそれ (例えば、NGM_NODEINFO) に送信しようとするこ とによって、指定されたノードが存在するかどうかチェックすることができま す。存在していないなら、ENOENT が返されます。 すべてのデータメッセージは M_PKTHDR フラグセットがある mbuf チェーンで す。 ノードは、それらが割り付けるものを解放することに責任があります。3 つの例 外があります: 1. データリンクの向こう側に送信された mbuf は、送信側によって決して解放 されません。エラーの場合は、それらは、解放されているはずと考えられま す。 2. NG_SEND_MSG_*() ファミリマクロの 1 つを使用して送られたメッセージは 受信側によって解放されます。上記の場合のように、メッセージに関連して いるアドレスはその情報を保存したいなら、受信側は、それらをコピーする べきであるので、それらを割り付けられたかどうかによって解放されます。 3. コントロールメッセージとデータの両方は netgraph item で配信され キューに入れられます。item は NG_FREE_ITEM(item) を使用することで解 放されるか、または別のノードに渡さなければなりません。 関連ファイル <netgraph/netgraph.h> netgraph ノードによってカーネル中でもっぱら使用するための定義。 <netgraph/ng_message.h> netgraph メッセージを処理する必要があるどんなファイルでも必要とさ れる定義。 <netgraph/ng_socket.h> netgraph socket タイプノードを使用する必要がある定義。 <netgraph/ng_><type>.h タイプクッキー定義を含んでいる、netgraph type ノードを使用する必 要がある定義。 /boot/kernel/netgraph.ko netgraph サブシステムロード可能 KLD モジュール。 /boot/kernel/ng_<type>.ko ノードタイプ type のためのロード可能な KLD モジュール。 src/sys/netgraph/ng_sample.c 骨組み (スケルトン) の netgraph ノード。新しいノードタイプのため の出発点としてこれを使用してください。 ユーザモードサポート netgraph システムと情報をやりとりするユーザモードプログラムをサポートする ためのライブラリがあります。詳細については netgraph(3) を参照してくださ い。 2 つのユーザモードサポートプログラム ngctl(8) と nghook(8) は、マニュアル 設定とデバッグを支援するために利用可能です。 新しいノードタイプをデバッグするためのいくつかの役に立つ技術があります。 まず、最初にユーザモードで新しいノードタイプを実装することはデバッグをよ り簡単にします。tee ノードタイプも特に ngctl(8) と nghook(8) に関連するデ バッグの役に立ちます。 また、netgraph を使用することで解決されたいくつかの一般的なネットワーク問 題のための解決策については /usr/share/examples/netgraph の中を見てくださ い。 関連項目 socket(2), netgraph(3), ng_async(4), ng_atm(4), ng_atmllc(4), ng_bluetooth(4), ng_bpf(4), ng_bridge(4), ng_bt3c(4), ng_btsocket(4), ng_car(4), ng_cisco(4), ng_device(4), ng_echo(4), ng_eiface(4), ng_etf(4), ng_ether(4), ng_frame_relay(4), ng_gif(4), ng_gif_demux(4), ng_h4(4), ng_hci(4), ng_hole(4), ng_hub(4), ng_iface(4), ng_ip_input(4), ng_ipfw(4), ng_ksocket(4), ng_l2cap(4), ng_l2tp(4), ng_lmi(4), ng_mppc(4), ng_nat(4), ng_netflow(4), ng_one2many(4), ng_patch(4), ng_ppp(4), ng_pppoe(4), ng_pptpgre(4), ng_rfc1490(4), ng_socket(4), ng_split(4), ng_sppp(4), ng_sscfu(4), ng_sscop(4), ng_tee(4), ng_tty(4), ng_ubt(4), ng_UI(4), ng_uni(4), ng_vjc(4), ng_vlan(4), ngctl(8), nghook(8) 歴史 netgraph システムは、Whistle InterJet のためにカスタマイズされた FreeBSD 2.2 バージョンを使用して Whistle Communications, Inc. で設計さ れ、最初に実装されました。それは、最初に FreeBSD 3.4 のメインツリー (訳 注: CVS 管理されたツリー) でデビューしました。 作者 Archie Cobbs <archie@FreeBSD.org> によって寄贈され Julian Elischer <julian@FreeBSD.org> によって書かれました。 FreeBSD 11.4 November 25, 2013 FreeBSD 11.4