Skip to content

SRHとパケットウォーク

Read in English · Leer en español

Segment Routing Header(SRH)がパケットレベルでどう動くかを理解することは、SRv6ネットワークの設計とトラブルシューティングに欠かせません。このページでは、その仕組みを一歩ずつ追っていきます。

SRHのフォーマット(RFC 8754)

SRHは、Routing Type = 4のIPv6 Routing Headerです。

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Next Header  |  Hdr Ext Len  |  Routing Type | Segments Left |
|               |               |     (= 4)     |     (SL)      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Last Entry   |    Flags      |              Tag              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
|            Segment List[0] (128-bit IPv6 address)             |
|                        (Last SID)                             |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
|            Segment List[1] (128-bit IPv6 address)             |
|                                                               |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                            ...                                |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
|            Segment List[n] (128-bit IPv6 address)             |
|                       (First SID)                             |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
|                  Optional TLV objects                         |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

主なフィールド

フィールド サイズ 説明
Next Header 8ビット 次のヘッダーの種類(例:41 = IPv6、4 = IPv4)
Hdr Ext Len 8ビット 先頭8オクテットを除いたSRHの長さ(8オクテット単位)
Routing Type 8ビット SRHでは常に4
Segments Left(SL) 8ビット セグメントリストのインデックスで、現在アクティブなセグメントを指す
Last Entry 8ビット セグメントリストの最後の要素のインデックス(0始まり)
Flags 8ビット 現在は未使用(予約)
Tag 16ビット パケットのグルーピングやマーキング
Segment List 各128ビット SIDの順序付きリスト。逆順で格納される

逆順に注意

セグメントリストは逆順でエンコードされます。Segment List[0]が最後に処理されるSIDで、Segment List[n]が最初に処理されるSIDです。Segments Leftはnから始まり、0に向かってデクリメントされます。

パケットウォークの全体像

3ノード構成のSRv6ネットワークでパケットを追跡してみましょう。

Source (A) → Node B → Node C → Destination (D)

SRv6 SIDs:
  B::100  = End behavior on Node B
  C::200  = End.DT4 behavior on Node C (decap to IPv4)

B::100はノードBのEndビヘイビア、C::200はノードCのEnd.DT4ビヘイビア(デカプセル化してIPv4へ)です。

ステップ1:Ingress(送信元A)

送信元Aは10.0.0.2宛てのIPv4パケットを受信し、B、Cの順に経由させる必要があります。

Original packet:
  [IPv4: 10.0.0.1 → 10.0.0.2][Payload]

After SRv6 encapsulation:
  ┌──────────────────────────────────────────┐
  │ Outer IPv6 Header                         │
  │   Source:      A::1                       │
  │   Destination: B::100  ← Active SID      │
  │   Next Header: 43 (Routing)               │
  ├──────────────────────────────────────────┤
  │ SRH                                       │
  │   Segments Left: 1                        │
  │   Last Entry:    1                        │
  │   Segment List[0]: C::200  (last SID)     │
  │   Segment List[1]: B::100  (first SID)    │
  ├──────────────────────────────────────────┤
  │ Inner IPv4 Header                         │
  │   10.0.0.1 → 10.0.0.2                    │
  ├──────────────────────────────────────────┤
  │ Payload                                   │
  └──────────────────────────────────────────┘

DA = アクティブSID

IPv6の宛先アドレス(DA)は、常に現在アクティブなSID(Segment List[Segments Left])と一致します。

ステップ2:トランジット(ノードB:Endビヘイビア)

ノードBがパケットを受信します。DAが自身のローカルSID B::100(Endビヘイビア)に一致するので、次の処理を行います。

  1. Segments Leftをデクリメント:1 → 0
  2. Segment List[0]をIPv6のDAにコピー:DA = C::200
  3. 新しいDAに基づいて転送
After Node B processing:
  ┌──────────────────────────────────────────┐
  │ Outer IPv6 Header                         │
  │   Source:      A::1                       │
  │   Destination: C::200  ← Updated!        │
  ├──────────────────────────────────────────┤
  │ SRH                                       │
  │   Segments Left: 0     ← Decremented!    │
  │   Last Entry:    1                        │
  │   Segment List[0]: C::200                 │
  │   Segment List[1]: B::100                 │
  ├──────────────────────────────────────────┤
  │ Inner IPv4: 10.0.0.1 → 10.0.0.2          │
  ├──────────────────────────────────────────┤
  │ Payload                                   │
  └──────────────────────────────────────────┘

ステップ3:Egress(ノードC:End.DT4ビヘイビア)

ノードCがパケットを受信します。DAが自身のローカルSID C::200(End.DT4ビヘイビア)に一致します。

  1. SL = 0なので、これが最後のセグメント
  2. デカプセル化:外側のIPv6ヘッダーとSRHを取り除く
  3. 指定されたVRFテーブルで内側のIPv4 DAをルックアップ
  4. 元のIPv4パケットを転送
After Node C processing:
  [IPv4: 10.0.0.1 → 10.0.0.2][Payload]  ← Original packet restored!

ステップ4:配送

元のIPv4パケットは、SRv6を経由したことをまったく意識させずに宛先10.0.0.2へ届けられます。

パケットウォークのシーケンス図

sequenceDiagram
    participant A as 送信元A
    participant B as ノードB (End)
    participant C as ノードC (End.DT4)
    participant D as 宛先

    A->>A: 10.0.0.2宛てのIPv4パケットを受信
    A->>A: カプセル化: IPv6(DA=B::100) + SRH[C::200, B::100] + IPv4
    A->>B: B::100へ転送 (SL=1)

    B->>B: B::100に一致 → Endビヘイビア
    B->>B: SL: 1→0, DA: B::100→C::200
    B->>C: C::200へ転送 (SL=0)

    C->>C: C::200に一致 → End.DT4ビヘイビア
    C->>C: デカプセル化し、VRFでIPv4をルックアップ
    C->>D: 元のIPv4パケットを転送

PSP、USP、USDフレーバー

SRv6のエンドポイントは、SRHの扱い方を最適化するさまざまなフレーバーをサポートできます。

フレーバー 正式名称 説明
PSP Penultimate Segment Pop 最後から2番目のノード(SL=1)が、最後のセグメントへ転送する前にSRHを取り除く。Egressノードの負荷を減らせる
USP Ultimate Segment Pop 最後のノード自身がSRHを取り除く
USD Ultimate Segment Decap 最後のノードが外側のIPv6ヘッダーとSRHをまとめてデカプセル化する。End.DT4/DT6と組み合わせて使う

最も一般的なのはPSP

PSPはSRHの除去をEgress PEから肩代わりして効率を高めるため、広く使われています。最近の実装の多くはEnd with PSPまたはEnd with PSP-USP-USDを広告します。

TLV付きのSRH

SRHは、セグメントリストの後ろにオプションのTLV(Type-Length-Value)オブジェクトを運べます。

TLV 説明
HMAC TLV SRHの暗号学的な認証
Padding TLV アライメントのためのパディング
NSH Carrier TLV サービスチェイニング用のNSHメタデータを運ぶ

Reduced Encapsulation(H.Encaps.Red)

H.Encaps.Red(Reduced Encapsulation、RFC 8986)は、経路の最初のSIDをセグメントリストから省くことでSRHを最適化します。最初のSIDはヘッドエンドがすでにIPv6のDAに入れているためです。これによりパケットごとに16バイトを節約でき、SIDが1つだけの経路ではSRH自体が不要になります。

Path: SID-1 → SID-2 → SID-3   (segment list is stored in reverse order)

H.Encaps:      SRH [SID-3, SID-2, SID-1], SL=2, DA = SID-1
H.Encaps.Red:  SRH [SID-3, SID-2],        SL=2, DA = SID-1  ← SID-1 only in the DA

H.Encaps.Redでは、SID-1はDAにだけ存在し、SRHには入りません。SLは省略しない場合と同じ値(2)から始まります。

確認コマンド

# SRv6パケットをキャプチャ(Routing Header、Next Header 43)
tcpdump -i eth0 -vv 'ip6 proto 43'

# ローカルSIDテーブルを表示
ip -6 route show | grep seg6local

# tsharkでデコード
tshark -i eth0 -O ipv6 -Y 'ipv6.routing.type == 4'
show segment-routing srv6 sid
show cef ipv6 <SID> detail
debug segment-routing srv6 dataplane
show route table inet6.0 protocol srv6
show spring-traffic-engineering srv6-sid

関連ページ

参考文献

  1. RFC 8754 - IPv6 Segment Routing Header (SRH) - SRHのフォーマット、フィールド、パケット処理ルールの完全な仕様
  2. RFC 8986 - SRv6 Network Programming - End、End.X、End.DT4などのエンドポイントビヘイビアと、PSP、USP、USDフレーバーを定義
  3. SRv6 Linux Kernel Implementation - Linuxカーネルのseg6/seg6localライトウェイトトンネルの設定ガイド (英語)
  4. Cisco IOS-XR: Configure Segment Routing over IPv6 (SRv6) - NCS 5500向けCisco IOS-XRのSRv6設定ガイド (英語)