# 通知設計書 11-RENAME

## 概要

本ドキュメントは、FreeBSDカーネルにおけるIFNET RENAME通知の設計を記述する。ネットワークインターフェースの名前が変更された際にdevctl(4)サブシステムを通じてユーザーランドに通知を送信する仕組みについて定義する。

### 本通知の処理概要

IFNET RENAME通知は、ネットワークインターフェースの名前変更が完了した時点でカーネルからユーザーランドへ発行されるdevctl通知である。

**業務上の目的・背景**：ネットワークインターフェースの名前はシステム管理上の重要な識別子であり、名前変更が発生した際にdevd(8)やその他のユーザーランドプロセスが適切に対応できるようにするために本通知が必要である。インターフェース名の変更はifconfig(8)のrenameコマンドやSIOCSIFNAME ioctlを通じて行われ、ファイアウォールルールやネットワーク設定の再構成が必要になる場合がある。

**通知の送信タイミング**：if_rename()関数の処理完了後、旧インターフェース名と新インターフェース名の両方が確定した時点で送信される。具体的には、sockaddr_dlの更新、EVENTHANDLER_INVOKEによるifnet_rename_eventの発行、IFF_RENAMINGフラグのクリアの後に発行される。

**通知の受信者**：devctl(4)デバイスをオープンしているユーザーランドプロセス。主にdevd(8)デーモンが受信し、設定ファイルに基づいてアクションを実行する。

**通知内容の概要**：システム名「IFNET」、サブシステム名として旧インターフェース名、タイプ「RENAME」、データとして新インターフェース名（name=新名前）が通知される。

**期待されるアクション**：devd(8)が通知を受信し、ネットワーク設定の更新、ファイアウォールルールの再適用、ログの記録などを行う。

## 通知種別

カーネルdevctl通知（devctl_notify経由）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 非同期（devctl(4)キュー経由） |
| 優先度 | 通常 |
| リトライ | なし |

### 送信先決定ロジック

devctl(4)デバイスファイル(/dev/devctl)をオープンしているすべてのプロセスに対してブロードキャスト送信される。受信者の選別はdevd(8)等のユーザーランド側で行う。

## 通知テンプレート

### devctl通知の場合

| 項目 | 内容 |
|-----|------|
| システム名 | IFNET |
| サブシステム名 | {旧インターフェース名} |
| タイプ | RENAME |
| データ | name={新インターフェース名} |

### 本文テンプレート

```
!system=IFNET subsystem={old_name} type=RENAME name={new_name}
```

### 添付ファイル

該当なし（カーネル通知のため添付ファイルの概念はない）

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| old_name | 変更前のインターフェース名 | ifp->if_xname（変更前にコピー） | Yes |
| new_name | 変更後のインターフェース名 | SIOCSIFNAME ioctlで指定された新名前 | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| ioctl操作 | SIOCSIFNAME | インターフェース名変更が成功した場合 | ifconfig renameコマンド等から呼ばれるioctl |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| 同名変更 | 新名前が旧名前と同一の場合、if_rename()が早期リターン（error=0）し通知は発行されない |
| 名前衝突 | 新名前が既存インターフェースと衝突する場合、EEXISTエラーで通知は発行されない |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[SIOCSIFNAME ioctl受信] --> B[if_rename呼び出し]
    B --> C{新旧名前が同一?}
    C -->|Yes| D[0を返却・通知なし]
    C -->|No| E{新名前のインターフェースが存在?}
    E -->|Yes| F[EEXISTを返却・通知なし]
    E -->|No| G[IFF_RENAMINGフラグ設定]
    G --> H[sockaddr_dl更新]
    H --> I[EVENTHANDLER_INVOKE ifnet_rename_event]
    I --> J[IFF_RENAMINGフラグクリア]
    J --> K[devctl_notify IFNET/old_name/RENAME/name=new_name]
    K --> L[0を返却]
    D --> M[終了]
    F --> M
    L --> M
```

## データベース参照・更新仕様

該当なし（カーネル内メモリ構造体の操作のみ）

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| ifnet構造体 | インターフェース情報の参照 | カーネル内部のネットワークインターフェース構造体 |
| sockaddr_dl | リンク層アドレス情報 | ifp->if_addr内のアドレス構造体 |

### テーブル別参照項目詳細

#### ifnet構造体

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| if_xname | インターフェース名 | 対象インターフェースを指定 |
| if_flags | インターフェースフラグ | IFF_RENAMINGの設定・解除 |
| if_addr | インターフェースアドレス | sockaddr_dlの更新用 |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| ifnet構造体 | UPDATE | if_xnameを新名前に更新 |
| sockaddr_dl | UPDATE | sdl_dataとsdl_nlenを新名前に更新 |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| EEXIST | 新名前が既存インターフェースと衝突 | エラーを呼び出し元に返却、通知は発行しない |
| 同名指定 | 新名前と旧名前が同一 | 正常終了（0）を返却、通知は発行しない |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし |
| リトライ間隔 | 該当なし |
| リトライ対象エラー | 該当なし |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし（カーネルレベル） |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし。カーネルイベント発生時に即座に通知される。

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

- devctl(4)デバイスへのアクセスにはroot権限が必要
- SIOCSIFNAME ioctlの実行にはPRIV_NET_SETIFNAME権限が必要（priv_check経由）
- インターフェース名はIFNAMSIZ（16バイト）以内に制限される

## 備考

- if_rename()関数はsys/net/if.cの3010行目に定義されている
- devctl_notify()呼び出しは3064行目で行われる
- EVENTHANDLER_INVOKEによるifnet_rename_eventは3059行目で先に発行される

---

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

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

### 推奨読解順序

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

ifnet構造体とsockaddr_dl構造体がインターフェースの名前情報を保持しており、これらの構造体の理解が前提となる。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | if_var.h | `sys/net/if_var.h` | ifnet構造体のif_xnameフィールド（インターフェース名を保持するchar配列） |
| 1-2 | if_dl.h | `sys/net/if_dl.h` | sockaddr_dl構造体のsdl_data、sdl_nlen（リンク層アドレスの名前部分） |

**読解のコツ**: FreeBSDのネットワークスタックでは、if_xnameがインターフェースの表示名として使用される。sockaddr_dlはリンク層情報を格納し、名前とハードウェアアドレスの両方を含む。

#### Step 2: エントリーポイントを理解する

SIOCSIFNAME ioctlがif_rename()を呼び出すまでの流れを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | if.c | `sys/net/if.c` | ifioctl()関数内のSIOCSIFNAMEケース（2583-2587行目付近） |

**主要処理フロー**:
1. **2586行目**: if_rename(ifp, new_name)の呼び出し

#### Step 3: 名前変更処理とdevctl通知を理解する

if_rename()関数の内部処理を追う。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | if.c | `sys/net/if.c` | if_rename()関数（3010-3067行目） |

**主要処理フロー**:
- **3020行目**: 同名チェック（変更なしの場合は早期リターン）
- **3022行目**: ifunit()による既存名の衝突チェック
- **3031行目**: IFF_RENAMINGフラグの設定
- **3036行目**: 旧名前のバックアップ
- **3037行目**: if_xnameに新名前を設定
- **3051行目**: sockaddr_dlのデータ更新
- **3059行目**: EVENTHANDLER_INVOKE(ifnet_rename_event)
- **3061行目**: IFF_RENAMINGフラグのクリア
- **3063-3064行目**: devctl_notify("IFNET", old_name, "RENAME", strbuf)

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

```
ifioctl() [sys/net/if.c]
    |
    +-- if_rename() [sys/net/if.c:3010]
           |
           +-- ifunit() [名前衝突チェック]
           +-- IF_ADDR_WLOCK/WUNLOCK [アドレスロック]
           +-- EVENTHANDLER_INVOKE(ifnet_rename_event)
           +-- devctl_notify("IFNET", old_name, "RENAME", ...)
```

### データフロー図

```
[入力]                       [処理]                          [出力]

SIOCSIFNAME ioctl  --->  if_rename()               --->  devctl(4)キュー
(new_name)                  |                              |
                            +-- ifnet.if_xname更新          +-- devd(8)
                            +-- sockaddr_dl更新
                            +-- EVENTHANDLER発行
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| if.c | `sys/net/if.c` | ソース | if_rename()の実装、devctl_notify呼び出し |
| if_var.h | `sys/net/if_var.h` | ヘッダー | ifnet構造体の定義 |
| if_dl.h | `sys/net/if_dl.h` | ヘッダー | sockaddr_dl構造体の定義 |
| devctl.h | `sys/sys/devctl.h` | ヘッダー | devctl_notify()のプロトタイプ |
| devd.conf | `/etc/devd.conf` | 設定 | devd(8)のアクション定義（ユーザーランド側） |
