# 機能設計書 39-netgraph

## 概要

本ドキュメントは、FreeBSDカーネル内のモジュラーネットワーキングフレームワークであるnetgraphの機能設計書である。

### 本機能の処理概要

netgraphは、カーネル内でノードとフックの接続によるグラフ構造を用いてネットワークプロトコルスタックを動的に構築するフレームワークである。各ノードはデータの受信・変換・転送を行い、フック（エッジ）で相互接続される。

**業務上の目的・背景**：従来の固定的なプロトコルスタック構造では対応が困難なネットワーク処理（PPP、ATM、Bluetooth、VPN、トンネリング、暗号化等）に対して、モジュラーで柔軟なフレームワークを提供する。各プロトコル処理をノードとして実装し、動的に接続・切断することでカスタムプロトコルスタックを構築可能にする。

**機能の利用シーン**：PPP接続の構築、Bluetoothプロトコルスタック、イーサネットブリッジング（ng_bridge）、BPFフィルタリング（ng_bpf）、NAT処理、VPN/トンネリング、ネットワーク統計収集等で利用される。

**主要な処理内容**：
1. ノードの作成・削除・管理
2. フック（ノード間接続）の作成・削除
3. コントロールメッセージの送受信
4. データメッセージ（mbuf）の転送
5. ノードタイプの動的登録
6. ngctl(8)によるユーザ空間からの制御
7. トポロジー管理（グラフ構造の管理）
8. キューイングとスレッド管理

**関連システム・外部連携**：Bluetoothスタック（sys/netgraph/bluetooth/）、PPP、イーサネットドライバ、ngctl(8)コマンド、libnetgraph

**権限による制御**：ソケット（AF_NETGRAPH）の作成にはroot権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | カーネルフレームワークのため該当する画面なし |

## 機能種別

カーネルフレームワーク（モジュラーネットワーク処理パイプライン）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ノードタイプ | string | Yes | 作成するノードの種類 | 登録済みノードタイプ |
| ノード名 | string | No | ノードの識別名 | ユニークな名前 |
| フック名 | string | Yes | 接続先フック名 | ノードタイプで定義されたフック名 |
| コントロールメッセージ | struct ng_mesg | No | ノードへの制御コマンド | 有効なメッセージ構造 |

### 入力データソース

AF_NETGRAPHソケット（ngctl経由）、カーネル内部ノード間通信

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| データmbuf | mbuf chain | ノード間で転送されるネットワークデータ |
| 応答メッセージ | struct ng_mesg | コントロールメッセージへの応答 |
| ノード/フック情報 | struct nodeinfo/hookinfo | ノード・フックの状態情報 |

### 出力先

次のノード（フック経由）、AF_NETGRAPHソケット（ユーザ空間）

## 処理フロー

### 処理シーケンス

```
1. ノードタイプの登録（ng_newtype()）
   └─ カーネルモジュールロード時にコンストラクタで登録
2. ノードの作成（ng_make_node_common()）
   └─ ノードタイプのコンストラクタ呼び出し
3. フックの作成と接続（ng_add_hook()/ng_connect()）
   └─ 2つのノード間にデータパスを確立
4. データ処理（ng_rcvdata()）
   └─ フック経由でmbufがノードのrcvdata関数に配信
5. コントロールメッセージ処理（ng_rcvmsg()）
   └─ ノードのrcvmsg関数に配信
6. ノード/フックの切断・削除
   └─ ng_disconnect()/ng_rmnode()
```

### フローチャート

```mermaid
flowchart TD
    A[モジュールロード] --> B[ng_newtype: ノードタイプ登録]
    B --> C[ngctl mknode: ノード作成]
    C --> D[ngctl connect: フック接続]
    D --> E{データ/コントロール?}
    E -->|データ| F[ng_rcvdata → ノードのrcvdata]
    E -->|コントロール| G[ng_rcvmsg → ノードのrcvmsg]
    F --> H[処理 → 次ノードへ転送]
    G --> I[応答メッセージ]
    H --> J{次ノード存在?}
    J -->|Yes| F
    J -->|No| K[終端]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-39-01 | ノードタイプ固有処理 | 各ノードタイプはconstructor, rcvmsg, rcvdata, shutdown, newhookの5つのメソッドを実装 | 全ノードタイプ |
| BR-39-02 | トポロジーロック | グラフトポロジーの変更はトポロジーロック（rw_lock）で保護 | ノード/フック追加・削除時 |
| BR-39-03 | 参照カウント | ノードとフックは参照カウントで管理され、参照がゼロになると自動解放 | 常時 |
| BR-39-04 | キュー処理 | データとコントロールメッセージはアイテムキューに入れられ、netisr的に処理 | 全メッセージ |

### 計算ロジック

特になし

## データベース操作仕様

該当なし

### 操作別データベース影響一覧

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| EEXIST | 既存 | 同名ノードの作成 | 別名を使用 |
| ENOENT | 未存在 | 存在しないノード/フック指定 | 名前確認 |
| EOPNOTSUPP | 非対応 | ノードがサポートしないコントロールメッセージ | ノードタイプ仕様確認 |
| ENOMEM | メモリ不足 | ノード/フック作成時のメモリ不足 | システムリソース確認 |

### リトライ仕様

なし

## トランザクション仕様

トポロジー変更はトポロジーライトロック下でアトミックに実行される。

## パフォーマンス要件

データパス（rcvdata）は最小限のオーバーヘッドで設計されている。ノード間のデータ転送はインラインのmbuf受け渡しで行われ、コピーは発生しない。

## セキュリティ考慮事項

- AF_NETGRAPHソケットの作成にはroot権限が必要
- ノードの名前空間はカーネル全体で共有される
- 不正なトポロジー構成によるカーネルパニック防止のためのバリデーション

## 備考

netgraphはWhistle Communications社のJulian Elischer氏とArchie Cobbs氏により開発された。FreeBSD固有のフレームワークであり、PPPoE、Bluetooth、ATM等のプロトコルスタックの基盤として広く使用されている。

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | netgraph.h | `sys/netgraph/netgraph.h` | struct ng_node（ノード）、struct ng_hook（フック）、struct ng_type（ノードタイプ定義）、struct ng_item（キューアイテム） |
| 1-2 | ng_message.h | `sys/netgraph/ng_message.h` | struct ng_mesg（コントロールメッセージ）、NGMコマンドタイプ |

**読解のコツ**: netgraphの中心概念は「ノード」と「フック」の2つ。各ノードはng_type構造体でメソッドテーブルを定義し、フックを通じてデータを送受信する。ng_base.cのトポロジーロック（ng_topo_lock）がグラフ構造変更の同期制御を行う。

#### Step 2: 基盤処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ng_base.c | `sys/netgraph/ng_base.c` | ノード/フック/メッセージの基本操作、トポロジーロック |

**主要処理フロー**:
1. **76行目**: MODULE_VERSION(netgraph, NG_ABI_VERSION)
2. **79-84行目**: ng_topo_lock - トポロジーロックとマクロ群
3. **86-99行目**: NETGRAPH_DEBUGモードの全ノード/全フックリスト

#### Step 3: ノードタイプの実装例を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ng_echo.c | `sys/netgraph/ng_echo.c` | 最もシンプルなノードタイプ実装例 |
| 3-2 | ng_ether.c | `sys/netgraph/ng_ether.c` | イーサネットノードタイプ |
| 3-3 | ng_bridge.c | `sys/netgraph/ng_bridge.c` | ブリッジノードタイプ |

### プログラム呼び出し階層図

```
[ノードタイプ登録]
ng_newtype() [ng_base.c]

[ノード作成]
ng_make_node_common() [ng_base.c]
    +-- type->constructor() - ノードタイプ固有初期化

[フック接続]
ng_add_hook() [ng_base.c]
    +-- ng_findhook() - フック検索
    +-- ng_connect() - 2ノード間接続
        +-- type->newhook() - ノードタイプ固有フック初期化

[データ転送]
ng_rcvdata() [ng_base.c]
    +-- ng_apply_item() - アイテムキュー処理
        +-- type->rcvdata() - ノードタイプ固有データ処理

[コントロールメッセージ]
ng_rcvmsg() [ng_base.c]
    +-- ng_apply_item() - アイテムキュー処理
        +-- type->rcvmsg() - ノードタイプ固有メッセージ処理

[ユーザ空間連携]
ngctl(8) → AF_NETGRAPH socket → ng_socket.c
```

### データフロー図

```
[ユーザ空間]                [カーネル - netgraph]

ngctl ──── AF_NETGRAPH ──> ng_socket ノード
                               |
                          コントロールメッセージ
                               |
                          [ng_ether] ─── hook ─── [ng_bridge] ─── hook ─── [ng_ether]
                               |                       |                       |
                          NIC受信                  MAC学習/転送             NIC送信
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ng_base.c | `sys/netgraph/ng_base.c` | ソース | netgraph基盤処理 |
| netgraph.h | `sys/netgraph/netgraph.h` | ヘッダ | ノード/フック/タイプ構造体定義 |
| ng_message.h | `sys/netgraph/ng_message.h` | ヘッダ | メッセージ構造体定義 |
| ng_parse.h | `sys/netgraph/ng_parse.h` | ヘッダ | パース関数定義 |
| ng_echo.c | `sys/netgraph/ng_echo.c` | ソース | echoノードタイプ |
| ng_ether.c | `sys/netgraph/ng_ether.c` | ソース | イーサネットノード |
| ng_bridge.c | `sys/netgraph/ng_bridge.c` | ソース | ブリッジノード |
| ng_bpf.c | `sys/netgraph/ng_bpf.c` | ソース | BPFフィルタノード |
| ng_socket.c | `sys/netgraph/ng_socket.c` | ソース | ソケットノード（ユーザ空間連携） |
| bluetooth/ | `sys/netgraph/bluetooth/` | ディレクトリ | Bluetoothノード群 |
| netflow/ | `sys/netgraph/netflow/` | ディレクトリ | NetFlowノード群 |
