P4プログラミングによるIPトンネリングの実装とヘッダ展開ロジック

トンネリングとP4パイプラインの基本架构

IPトンネリングは、物理的に分散したネットワークノード間に論理的なポイントツーポイント接続を形成するカプセル化技術です。送信端では、元のペイロードデータを新たなIPヘッダーでラップし、外部ルーティングにおいてトンネル出口ノードのアドレスを対象とします。P4言語ではデータプレーンの処理パイプラインがハードコードされますが、具体的な転送エントリは制御プレーン経由で動的に注入されます。テーブル定義はマッチキーと実行アクションを紐付け、制御側から提供されたパラメータを組み合わせてパケットの振る舞いを決定します。

実験の目的と構造設計

本課題では、既存のLIP転送基盤にトンネリングサポート機能を拡張します。従来の宛先IPアドレスに基づくフォワーディングに加え、独自のカプセル化ヘッダーを検出し、その内容に基づいて出力チャネルを制御する仕組みを構築します。作成するヘッダ型には、カプセル化対象のプロトコル種別を示すフィールドと、論理経路を特定するための識別子を含めます。これにより、外部IPアドレスの変動に左右されず、定義済みのトンネル経路に対して安定した配送を実現します。また、標準IPパケット到達時は通常ルーティングへ自動切り替えるフォールバック構造も実装します。

ヘッダ構造体への追加イメージ:

struct headers_t {
    ethernet_t       eth;
    tunnel_hdr_t     tun;
    ipv4_t           ip;
}

パーサの状態遷移変更

新規ヘッダの検出と連続展開を行うため、状態マシンの分岐ロジックを更新します。 etherType を判定基準とし、トンネルタイプ検知時にはまずは`tun`フィールドを抽出した後、内部プロトコルフィールドを確認して通常 IPv4 パーサーへ制御を委譲します。

parser TnlParser(packet_in packet, out headers_t hdr, inout metadata meta, inout standard_metadata_t std_meta) {
    state start {
        packet.extract(hdr.eth);
        transition select(hdr.eth.etherType) {
            ETHER_TYPE_IPV4: parse_ipv4;
            ETHER_TYPE_TNL:  parse_tunnel;
            default:         accept;
        }
    }
    state parse_ipv4 {
        packet.extract(hdr.ip);
        transition accept;
    }
    state parse_tunnel {
        packet.extract(hdr.tun);
        transition select(hdr.tun.inner_proto) {
            ETHER_TYPE_IPV4: parse_ipv4;
            default:         accept;
        }
    }
}

コントロールプレーンとマッチング定義

エGRESSポート決定のアクションとテーブルを作成します。`exact` キーを使用してトンネル識別子を照合し、制御面から授与されたポート番号を `egress_spec` に反映します。適用ブロックではヘッダの有効性フラグを監視し、優先度の高い順にテーブル実行を呼び出します。

action forward_via_tunnel(egressSpec_t output_port) {
    std_meta.egress_spec = output_port;
}

table tunnel_table {
    key = {
        hdr.tun.next_hop_id: exact;
    }
    actions = {
        forward_via_tunnel;
        drop;
        NoAction;
    }
    size = 1024;
    default_action = drop();
}

control IngressCtrl(inout headers_t hdr, inout metadata meta, inout standard_metadata_t std_meta) {
    apply {
        if (hdr.tun.isValid()) {
            tunnel_table.apply();
        } else if (hdr.ip.isValid()) {
            ipv4_lpm_table.apply();
        }
    }
}

デパーサーと動作検証

再構築フェーズでは、各ヘッダの抽出完了状態に関わらずデパーサーが内部的に `isValid` を評価するため、開発者は手動チェックを追加する必要はありません。定義した順序でemitを呼び出すことで、カプセル化レイヤー構造が正しく復元されます。

control OutDeparser(packet_out packet, in headers_t hdr) {
    apply {
        packet.emit(hdr.eth);
        packet.emit(hdr.tun);
        packet.emit(hdr.ip);
    }
}

実装をコンパイルし実行環境にデプロイした後、h3 に対する宛先設定を調整するとトンネル転送が正常に稼働していることを確認できます。この際、転送判定は独自ヘッダー内の識別子値に完全に依存するため、外部IPアドレスの内容が変更されても初期設定された論理パスを通じてパケットが配送されます。従来のIPルーティングテーブルの干渉を受けずに独立した仮想回線としての機能が発揮されます。

タグ: P4-lang tunnel-encapsulation packet-parser state-machine action-table

8月8日 13:14 投稿