↓ メインコンテンツへスキップ
  1. ネットワーク 記事一覧/
  2. MPLS記事一覧/

MPLSのラベル操作(push / swap / pop)とPHP

目次

MPLSのラベル操作(push / swap / pop)とPHP

MPLSのルータ(LSR)がパケットに対して行う操作は、ラベルを積むpush、先頭のラベルを付け替えるswap、先頭のラベルを外すpopの3つです。本記事では、1つのパケットが入口のPEから出口のPEまで運ばれる間に各ルータがどの表を引いて何をするか、出口の1つ手前でラベルを外すPHP(Penultimate Hop Popping)とは何かを解説し、IOS XR(XRd)のラボで1ホップずつ確かめます。ラベルの形式はMPLSラベルとラベルスタックで解説しています。

3つの操作と2つの表

操作行うLSR内容
push入口LSR(PE1)ラベルの付いていないIPパケットを受け取り、宛先で決まるFECのラベルを積んで送り出す。
swap中継LSR(P1・P2)先頭のラベルを、次のLSRから受け取ったラベルに付け替える。
pop出口LSRの1つ手前(P3)または出口LSR先頭のラベルを外す。外した結果ラベルが無くなれば、IPパケットとして扱う。

どの表を引くかは、受け取ったパケットにラベルが付いているかで決まります。

受け取ったパケット引く表IOS XRの確認コマンド
ラベル無し(IPパケット)FIB。宛先IPアドレスをロンゲストマッチで検索し、結果に付いているラベルをpushする(RFC 3031のFTN)show cef <プレフィックス> detail(labels imposed {…})
ラベル付きLFIB。先頭のラベル値を索引に、操作(swap / pop)と出力先を引く(同ILM)show mpls forwarding(Local / Outgoing 列)

中継LSRはIPヘッダーを見ません。先頭のラベルだけを引き、Outgoing Labelの値に付け替える(swap)か、Popなら外して送り出します。

show mpls forwardingのOutgoing Label列には、ラベル値のほかに次の表示が出ます。

表示意味
数値その値にswapする。
Pop先頭のラベルを外す。次のLSRがこのプレフィックスに対してimplicit-null(3)を配ってきたとき。
Exp-Null-v4先頭のラベルを0(IPv4 Explicit NULL)にswapする。次のLSRがexplicit-nullを配ってきたとき。
Unlabelledラベルを外してIPパケットとして送る。次ホップがMPLSを話さない(CE向けなど)か、次ホップからそのプレフィックスのラベルを受け取っていないとき。
Aggregateラベルを外し、改めてIP検索を行う。1つのラベルがVRFのテーブル全体を指していて転送先が決まらないときの表示で、VPNラベルの割り当てをVRFごとに1つ(per-VRF)にした場合や、集約したプレフィックスに付いたラベルで使われる。本記事のラボには集約ラベルが要る経路(redistribute connectedで入れた接続経路など)が無いため、この表示は出ていません。 割り当てモードの違いはMPLS VPNのVPNラベルの割り当てで解説しています。

ラベルは1ホップごとに付け替わる

ラベルは隣接する2台の間でだけ意味を持つ値なので、パケットがLSRを通るたびに値が変わります。上の図では、PE1が付けた30005(P1が6.6.6.6/32に割り当てた値)を、P1が40005(P2が同じプレフィックスに割り当てた値)に、P2が50005(P3の値)に付け替えています。値の決まり方はLDPとはで解説しています。各LSRは自分のローカルラベルを独立に割り当てるため、隣どうしでたまたま同じ値になることもあります。その場合も付け替えは行われており、値が一致しているだけです。割り当てはルータを再起動すると変わるので、ラベルの値そのものに意味はありません。

PHP(Penultimate Hop Popping)

出口LSRは、自分に直結する経路(ループバックなど)に対してimplicit-null(3) を配ります。これを受け取った1つ手前のLSRは、そのプレフィックス宛てのパケットからラベルを外して(pop)送ります。この動作がPHPです。

PHPの目的は、出口LSRの検索回数を減らすことです(RFC 3031 3.16節)。出口LSRがラベル付きのまま受け取ると、まずLFIBでラベルを引いて「自分宛てなので外す」と判断し、続けてIPヘッダーでFIBを引く、という2回の検索が必要になります。1つ手前でラベルを外しておけば、出口LSRはIPパケットとして受け取り、FIBの検索1回で済みます。

PHPを使わない場合は、出口LSRにexplicit-null(0) を配らせます。1つ手前のLSRはラベルを0にswapして送り、出口LSRはラベル0を外してからIP検索を行います。ラベルのTC(QoSのクラス)を出口LSRまで届けたいときに使います。IOS XRではmpls ldp配下のlabel local advertise explicit-nullで切り替えます。

出口LSRが配る値1つ手前のLSRの操作出口LSRの検索
implicit-null(3、既定)popIP検索1回
explicit-null(0)0にswapラベル検索 + IP検索

PHPはあくまで「最後のラベルを1つ手前で外す」動作です。MPLS VPNのようにラベルが2段ある場合、1つ手前のLSRが外すのは先頭のトランスポートラベルだけで、VPNラベルは出口PEまで届きます。

実機での検証

検証環境

CE1 — PE1 — P1 — P2 — P3 — PE2 — CE2 を直列につないでいます。AS 65001のPE1 / P1 / P2 / P3 / PE2がMPLSネットワークで、OSPF(area 0、全リンクnetwork point-to-point)で経路を、LDPでラベルを配っています。CE1とCE2はPEとeBGPで経路を交換し、PE1とPE2はLoopback0間のiBGP(next-hop-self)で外部経路のネクストホップを自分のLoopback0にします。CE3 / CE4はVRF CUST-Aの顧客で、VPNの2段のラベルのうちPHPで外れるのが先頭だけであることの確認に使います。

中継のP1 / P2 / P3は、動的ラベルの範囲を30000〜 / 40000〜 / 50000〜に分けて起動しています(mpls label range table 0)。各LSRはラベルを独立に割り当てるので、既定の範囲のままだと隣どうしで同じ値になることがあり、swapが値の変化として見えなくなるためです。範囲を分けても動作は変わりません。

ルータ役割Lo0動的ラベルの範囲
CE1顧客側(AS 65101)、192.168.1.0/24を広告1.1.1.1/32—
PE1入口LSR(push)2.2.2.2/32既定(24000〜)
P1中継LSR(swap)3.3.3.3/3230000〜39999
P2中継LSR(swap)4.4.4.4/3240000〜49999
P3出口の1つ手前(pop)5.5.5.5/3250000〜59999
PE2出口LSR6.6.6.6/32既定(24000〜)
CE2顧客側(AS 65102)、192.168.2.0/24を広告7.7.7.7/32—
CE3 / CE4VRF CUST-Aの顧客側、192.168.3.0/24 / 192.168.4.0/248.8.8.8 / 9.9.9.9—

CE1から192.168.2.1(CE2)、CE3から192.168.4.1(CE4)へpingを打ち、コアの4リンクでキャプチャーします。192.168.2.0/24のBGPネクストホップはPE2のLoopback0(6.6.6.6)なので、各LSRが引くのは6.6.6.6/32のエントリです。

検証のSTEP

STEP操作確かめること
0初期状態(既定 = PHP)PE1がpush、P1とP2がswap、P3がpopすること。4リンクのpcapと各ルータのFIB / LFIBを突き合わせる。VPNの2段では先頭だけが外れること
1PE2にlabel local advertise explicit-nullpopの位置がP3からPE2に移り、P3の操作がExp-Null-v4へのswapになること
2STEP 1を削除(最終状態)STEP 0と同じに戻ること

push:入口のPE1がラベルを付ける

PE1は192.168.2.0/24をネクストホップ6.6.6.6として学んでいるため、pushするラベルは6.6.6.6/32のFIBエントリに入っています。labels imposed {30005}がその値で、P1が6.6.6.6/32に割り当てたラベルです。

PE1 show cef 6.6.6.6/32 detail(STEP 0)
RP/0/RP0/CPU0:PE1#show cef 6.6.6.6/32 detail
Tue Sep 22 04:11:39.891 UTC
6.6.6.6/32, version 17, internal 0x1000001 0x10 (ptr 0x88519ae0) [2], 0x600 (0x894f2018), 0xa28 (0x899723f8)
 Updated Sep 22 00:53:32.311
 local adjacency to GigabitEthernet0/0/0/1

 Prefix Len 32, traffic index 0, precedence n/a, priority 1
  gateway array (0x8938b638) reference count 15, flags 0x68, source lsd (5), 1 backups
                [6 type 5 flags 0x8401 (0x899ab460) ext 0x0 (0x0)]
  LW-LDI[type=5, refc=3, ptr=0x894f2018, sh-ldi=0x899ab460]
  gateway array update type-time 1 Sep 22 00:53:32.252
 LDI Update time Sep 22 00:53:32.253
 LW-LDI-TS Sep 22 00:53:32.311
   via 10.2.3.3/32, GigabitEthernet0/0/0/1, 6 dependencies, weight 0, class 0 [flags 0x0]
    path-idx 0 NHID 0x4 [0x8a7776e0 0x0]
    next hop 10.2.3.3/32
    local adjacency
     local label 24006      labels imposed {30005}

    Load distribution: 0 (refcount 6)

    Hash  OK  Interface                 Address
    0     Y   GigabitEthernet0/0/0/1    10.2.3.3

PE1 - P1間のキャプチャーのNo.33が、CE1からのecho requestです。EtherTypeが0x8847になり、ラベル30005が付いています。

No.33 Echo request(PE1 → P1)tshark -V
    Type: MPLS label switched packet (0x8847)
    [Stream index: 4]
MultiProtocol Label Switching Header, Label: 30005, Exp: 0, S: 1, TTL: 254
    0000 0111 0101 0011 0101 .... .... .... = MPLS Label: 30005 (0x07535)
    .... .... .... .... .... 000. .... .... = MPLS Experimental Bits: 0
    .... .... .... .... .... ...1 .... .... = MPLS Bottom Of Label Stack: 1
    .... .... .... .... .... .... 1111 1110 = MPLS TTL: 254
Internet Protocol Version 4, Src: 192.168.1.1, Dst: 192.168.2.1
    0100 .... = Version: 4
    .... 0101 = Header Length: 20 bytes (5)
    Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
        0000 00.. = Differentiated Services Codepoint: Default (0)
        .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
    Total Length: 100
    Identification: 0x0000 (0)
    000. .... = Flags: 0x0
        0... .... = Reserved bit: Not set
        .0.. .... = Don't fragment: Not set
        ..0. .... = More fragments: Not set
    ...0 0000 0000 0000 = Fragment Offset: 0
    Time to Live: 254
上のtshark出力のパケット(No.33 Echo request)のpcapをダウンロード

swap:中継のP1とP2がラベルを付け替える

P1とP2はIPヘッダーを見ず、受け取ったラベルでLFIBを引きます。P1は30005を40005(P2が割り当てた値)に、P2は40005を50005(P3が割り当てた値)に付け替えます。

P1 show mpls forwarding(STEP 0)
RP/0/RP0/CPU0:P1#show mpls forwarding
Tue Sep 22 04:12:38.601 UTC
Local  Outgoing    Prefix             Outgoing     Next Hop        Bytes
Label  Label       or ID              Interface                    Switched
------ ----------- ------------------ ------------ --------------- ------------
30000  Pop         2.2.2.2/32         Gi0/0/0/0    10.2.3.2        38122
30001  Pop         4.4.4.4/32         Gi0/0/0/1    10.3.4.4        212
30002  Pop         10.4.5.0/24        Gi0/0/0/1    10.3.4.4        0
30003  40003       5.5.5.5/32         Gi0/0/0/1    10.3.4.4        0
30004  40004       10.5.6.0/24        Gi0/0/0/1    10.3.4.4        0
30005  40005       6.6.6.6/32         Gi0/0/0/1    10.3.4.4        37598
P2 show mpls forwarding(STEP 0)
RP/0/RP0/CPU0:P2#show mpls forwarding
Tue Sep 22 04:13:04.101 UTC
Local  Outgoing    Prefix             Outgoing     Next Hop        Bytes
Label  Label       or ID              Interface                    Switched
------ ----------- ------------------ ------------ --------------- ------------
40000  30000       2.2.2.2/32         Gi0/0/0/0    10.3.4.3        38553
40001  Pop         3.3.3.3/32         Gi0/0/0/0    10.3.4.3        274
40002  Pop         10.2.3.0/24        Gi0/0/0/0    10.3.4.3        0
40003  Pop         5.5.5.5/32         Gi0/0/0/1    10.4.5.5        318
40004  Pop         10.5.6.0/24        Gi0/0/0/1    10.4.5.5        0
40005  50005       6.6.6.6/32         Gi0/0/0/1    10.4.5.5        38553

同じecho requestを4リンクで追うと、ラベルの値が1ホップごとに変わり、ラベルのTTLも1ずつ減っていきます。

コアの4リンクで同じecho requestを見る(STEP 0)
$ tshark -r - -Y 'icmp.type==8 && ip.src==192.168.1.1' -T fields -e frame.number -e mpls.label -e mpls.ttl -e ip.ttl \
    < mpls-label-operation-step0-pe1p1.pcap
33	30005	254	254
$ tshark -r - -Y 'icmp.type==8 && ip.src==192.168.1.1' -T fields -e frame.number -e mpls.label -e mpls.ttl -e ip.ttl \
    < mpls-label-operation-step0-p1p2.pcap
31	40005	253	254
$ tshark -r - -Y 'icmp.type==8 && ip.src==192.168.1.1' -T fields -e frame.number -e mpls.label -e mpls.ttl -e ip.ttl \
    < mpls-label-operation-step0-p2p3.pcap
34	50005	252	254
$ tshark -r - -Y 'icmp.type==8 && ip.src==192.168.1.1' -T fields -e frame.number -e mpls.label -e mpls.ttl -e ip.ttl \
    < mpls-label-operation-step0-p3pe2.pcap
35			251

CE1からのtracerouteにも、各ホップで受け取ったラベルが出ます。

CE1 traceroute(STEP 0)
RP/0/RP0/CPU0:CE1#traceroute 192.168.2.1 source 192.168.1.1 timeout 1 probe 2 maxttl 7
Tue Sep 22 04:10:51.791 UTC

Type escape sequence to abort.
Tracing the route to 192.168.2.1

 1  10.1.2.2 6 msec  5 msec
 2  10.2.3.3 [MPLS: Label 30005 Exp 0] 18 msec  18 msec
 3  10.3.4.4 [MPLS: Label 40005 Exp 0] 18 msec  17 msec
 4  10.4.5.5 [MPLS: Label 50005 Exp 0] 19 msec  17 msec
 5  10.5.6.6 19 msec  19 msec
 6  10.6.7.7 36 msec  *

pop(PHP):出口の1つ手前のP3がラベルを外す

PE2は自分のLoopback0(6.6.6.6/32)に対してimplicit-null(3)を配っています。P3のバインディングではPE2からの値がImpNull、LFIBでは出方向がPopです。

P3 show mpls ldp bindings 6.6.6.6/32(STEP 0)
RP/0/RP0/CPU0:P3#show mpls ldp bindings 6.6.6.6/32
Tue Sep 22 04:13:27.552 UTC
6.6.6.6/32, rev 18
	Local binding: label: 50005
	Remote bindings: (2 peers)
	    Peer                Label
	    -----------------   ---------
	    4.4.4.4:0           40005
	    6.6.6.6:0           ImpNull
P3 show mpls forwarding(STEP 0)
RP/0/RP0/CPU0:P3#show mpls forwarding
Tue Sep 22 04:13:28.219 UTC
Local  Outgoing    Prefix             Outgoing     Next Hop        Bytes
Label  Label       or ID              Interface                    Switched
------ ----------- ------------------ ------------ --------------- ------------
50000  40000       2.2.2.2/32         Gi0/0/0/0    10.4.5.4        37705
50001  40001       3.3.3.3/32         Gi0/0/0/0    10.4.5.4        0
50002  Pop         4.4.4.4/32         Gi0/0/0/0    10.4.5.4        380
50003  40002       10.2.3.0/24        Gi0/0/0/0    10.4.5.4        0
50004  Pop         10.3.4.0/24        Gi0/0/0/0    10.4.5.4        0
50005  Pop         6.6.6.6/32         Gi0/0/0/1    10.5.6.6        38345

P3 - PE2間のNo.35は、ラベルを外された後のecho requestです。EtherTypeは0x0800で、PE2はIPパケットとして受け取り、IP検索1回で転送します。

No.35 Echo request(P3 → PE2)tshark -V
    Type: IPv4 (0x0800)
    [Stream index: 4]
Internet Protocol Version 4, Src: 192.168.1.1, Dst: 192.168.2.1
    0100 .... = Version: 4
    .... 0101 = Header Length: 20 bytes (5)
    Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
        0000 00.. = Differentiated Services Codepoint: Default (0)
        .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
    Total Length: 100
    Identification: 0x0000 (0)
    000. .... = Flags: 0x0
        0... .... = Reserved bit: Not set
        .0.. .... = Don't fragment: Not set
        ..0. .... = More fragments: Not set
    ...0 0000 0000 0000 = Fragment Offset: 0
    Time to Live: 251
上のtshark出力のパケット(No.35 Echo request)のpcapをダウンロード

VPNの2段:PHPで外れるのは先頭だけ

CE3からCE4への経路では、PE1が2つのラベルをpushします。上がPE2へ届けるための30005、下がPE2が割り当てたVPNラベル24007です。

PE1 show cef vrf CUST-A 192.168.4.0/24 detail(STEP 0)
RP/0/RP0/CPU0:PE1#show cef vrf CUST-A 192.168.4.0/24 detail
Tue Sep 22 04:11:44.681 UTC
192.168.4.0/24, version 7, internal 0x5000001 0x30 (ptr 0x885194c0) [1], 0x0 (0x0), 0x208 (0x89972398)
 Updated Sep 22 00:54:44.354
 Prefix Len 24, traffic index 0, precedence n/a, priority 3
  gateway array (0x8938bc68) reference count 1, flags 0x2038, source rib (7), 0 backups
                [1 type 1 flags 0x48441 (0x899ab4b8) ext 0x0 (0x0)]
  LW-LDI[type=0, refc=0, ptr=0x0, sh-ldi=0x0]
  gateway array update type-time 1 Sep 22 00:54:44.354
 LDI Update time Sep 22 00:54:44.354
   via 6.6.6.6/32, 3 dependencies, recursive [flags 0x6000]
    path-idx 0 NHID 0x0 [0x8856ecc8 0x0]
    recursion-via-/32
    next hop VRF - 'default', table - 0xe0000000
    next hop 6.6.6.6/32 via 24006/0/21
     next hop 10.2.3.3/32 GigabitEthernet0/0/0/1 labels imposed {30005 24007}

    Load distribution: 0 (refcount 1)

    Hash  OK  Interface                 Address
    0     Y   recursive                 24006/0

PE1 - P1間のNo.521が2段のecho requestです。

No.521 Echo request(PE1 → P1、2段)tshark -V
    Type: MPLS label switched packet (0x8847)
    [Stream index: 4]
MultiProtocol Label Switching Header, Label: 30005, Exp: 0, S: 0, TTL: 254
    0000 0111 0101 0011 0101 .... .... .... = MPLS Label: 30005 (0x07535)
    .... .... .... .... .... 000. .... .... = MPLS Experimental Bits: 0
    .... .... .... .... .... ...0 .... .... = MPLS Bottom Of Label Stack: 0
    .... .... .... .... .... .... 1111 1110 = MPLS TTL: 254
MultiProtocol Label Switching Header, Label: 24007, Exp: 0, S: 1, TTL: 254
    0000 0101 1101 1100 0111 .... .... .... = MPLS Label: 24007 (0x05dc7)
    .... .... .... .... .... 000. .... .... = MPLS Experimental Bits: 0
    .... .... .... .... .... ...1 .... .... = MPLS Bottom Of Label Stack: 1
    .... .... .... .... .... .... 1111 1110 = MPLS TTL: 254
Internet Protocol Version 4, Src: 192.168.3.1, Dst: 192.168.4.1
    0100 .... = Version: 4
    .... 0101 = Header Length: 20 bytes (5)
    Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
        0000 00.. = Differentiated Services Codepoint: Default (0)
        .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
    Total Length: 100
    Identification: 0x0000 (0)
    000. .... = Flags: 0x0
        0... .... = Reserved bit: Not set
        .0.. .... = Don't fragment: Not set
        ..0. .... = More fragments: Not set
    ...0 0000 0000 0000 = Fragment Offset: 0
    Time to Live: 254
上のtshark出力のパケット(No.521 Echo request、2段)のpcapをダウンロード

P3が外すのは先頭の50005だけで、P3 - PE2間のNo.522にはVPNラベル24007が残っています。

No.522 Echo request(P3 → PE2、VPNラベルのみ)tshark -V
    Type: MPLS label switched packet (0x8847)
    [Stream index: 4]
MultiProtocol Label Switching Header, Label: 24007, Exp: 0, S: 1, TTL: 251
    0000 0101 1101 1100 0111 .... .... .... = MPLS Label: 24007 (0x05dc7)
    .... .... .... .... .... 000. .... .... = MPLS Experimental Bits: 0
    .... .... .... .... .... ...1 .... .... = MPLS Bottom Of Label Stack: 1
    .... .... .... .... .... .... 1111 1011 = MPLS TTL: 251
Internet Protocol Version 4, Src: 192.168.3.1, Dst: 192.168.4.1
    0100 .... = Version: 4
    .... 0101 = Header Length: 20 bytes (5)
    Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
        0000 00.. = Differentiated Services Codepoint: Default (0)
        .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
    Total Length: 100
    Identification: 0x0000 (0)
    000. .... = Flags: 0x0
        0... .... = Reserved bit: Not set
        .0.. .... = Don't fragment: Not set
        ..0. .... = More fragments: Not set
    ...0 0000 0000 0000 = Fragment Offset: 0
    Time to Live: 254
上のtshark出力のパケット(No.522 Echo request)のpcapをダウンロード

PE2は24007でLFIBを引き、VRF CUST-AのCE4へIPパケットとして送り出します。

PE2 show mpls forwarding(STEP 0)
RP/0/RP0/CPU0:PE2#show mpls forwarding
Tue Sep 22 04:12:08.823 UTC
Local  Outgoing    Prefix             Outgoing     Next Hop        Bytes
Label  Label       or ID              Interface                    Switched
------ ----------- ------------------ ------------ --------------- ------------
24000  50000       2.2.2.2/32         Gi0/0/0/0    10.5.6.5        36750
24001  50001       3.3.3.3/32         Gi0/0/0/0    10.5.6.5        0
24002  50002       4.4.4.4/32         Gi0/0/0/0    10.5.6.5        0
24003  Pop         5.5.5.5/32         Gi0/0/0/0    10.5.6.5        212
24004  50003       10.2.3.0/24        Gi0/0/0/0    10.5.6.5        0
24005  50004       10.3.4.0/24        Gi0/0/0/0    10.5.6.5        0
24006  Pop         10.4.5.0/24        Gi0/0/0/0    10.5.6.5        0
24007  Unlabelled  192.168.4.0/24[V]  Gi0/0/0/2    10.6.9.9        13088

CE3からのtracerouteでも、先頭のラベルが付け替わり、最後のホップでVPNラベルだけが残ることが分かります。

CE3 traceroute(STEP 0)
RP/0/RP0/CPU0:CE3#traceroute 192.168.4.1 source 192.168.3.1 timeout 1 probe 2 maxttl 8
Tue Sep 22 04:11:20.459 UTC

Type escape sequence to abort.
Tracing the route to 192.168.4.1

 1  10.2.8.2 6 msec  5 msec
 2  10.2.3.3 [MPLS: Labels 30005/24007 Exp 0] 66 msec  22 msec
 3  10.3.4.4 [MPLS: Labels 40005/24007 Exp 0] 24 msec  23 msec
 4  10.4.5.5 [MPLS: Labels 50005/24007 Exp 0] 23 msec  31 msec
 5  10.5.6.6 [MPLS: Label 24007 Exp 0] 20 msec  20 msec
 6  10.6.9.9 22 msec  *

explicit-null:popの位置がPE2に移る

PE2にexplicit-nullを配らせます。

STEP 1 PE2にcommitした設定
RP/0/RP0/CPU0:PE2#show configuration commit changes last 1
Tue Sep 22 04:15:05.290 UTC
!! Building configuration...
!! IOS XR Configuration 26.1.1
mpls ldp
 address-family ipv4
  label
   local
    advertise
     explicit-null
    !
   !
  !
 !
!
end

P3がPE2から受け取る値はExpNullv4に変わり、LFIBの操作はPopからExp-Null-v4(ラベル0へのswap)になります。

P3 show mpls ldp bindings 6.6.6.6/32(STEP 1)
RP/0/RP0/CPU0:P3#show mpls ldp bindings 6.6.6.6/32
Tue Sep 22 04:19:21.900 UTC
6.6.6.6/32, rev 18
	Local binding: label: 50005
	Remote bindings: (2 peers)
	    Peer                Label
	    -----------------   ---------
	    4.4.4.4:0           40005
	    6.6.6.6:0           ExpNullv4
P3 show mpls forwarding(STEP 1)
RP/0/RP0/CPU0:P3#show mpls forwarding
Tue Sep 22 04:19:22.563 UTC
Local  Outgoing    Prefix             Outgoing     Next Hop        Bytes
Label  Label       or ID              Interface                    Switched
------ ----------- ------------------ ------------ --------------- ------------
50000  40000       2.2.2.2/32         Gi0/0/0/0    10.4.5.4        37713
50001  40001       3.3.3.3/32         Gi0/0/0/0    10.4.5.4        0
50002  Pop         4.4.4.4/32         Gi0/0/0/0    10.4.5.4        380
50003  40002       10.2.3.0/24        Gi0/0/0/0    10.4.5.4        0
50004  Pop         10.3.4.0/24        Gi0/0/0/0    10.4.5.4        0
50005  Exp-Null-v4 6.6.6.6/32         Gi0/0/0/1    10.5.6.6        39781

P3 - PE2間のNo.92では、CE1からのecho requestにラベル0が付いています。PE2はラベル0を外してからIP検索を行うので、検索が2回になります。

No.92 Echo request(P3 → PE2、explicit-null)tshark -V
    Type: MPLS label switched packet (0x8847)
    [Stream index: 5]
MultiProtocol Label Switching Header, Label: 0 (IPv4 Explicit-Null), Exp: 0, S: 1, TTL: 251
    0000 0000 0000 0000 0000 .... .... .... = MPLS Label: IPv4 Explicit-Null (0)
    .... .... .... .... .... 000. .... .... = MPLS Experimental Bits: 0
    .... .... .... .... .... ...1 .... .... = MPLS Bottom Of Label Stack: 1
    .... .... .... .... .... .... 1111 1011 = MPLS TTL: 251
Internet Protocol Version 4, Src: 192.168.1.1, Dst: 192.168.2.1
    0100 .... = Version: 4
    .... 0101 = Header Length: 20 bytes (5)
    Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
        0000 00.. = Differentiated Services Codepoint: Default (0)
        .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
    Total Length: 100
    Identification: 0x0000 (0)
    000. .... = Flags: 0x0
        0... .... = Reserved bit: Not set
        .0.. .... = Don't fragment: Not set
        ..0. .... = More fragments: Not set
    ...0 0000 0000 0000 = Fragment Offset: 0
    Time to Live: 254
上のtshark出力のパケット(No.92 Echo request)のpcapをダウンロード

VPNでは、ラベル0の下にVPNラベル24007が残った2段になります(No.584)。tracerouteでも5ホップ目にLabels 0/24007が出ます。

No.584 Echo request(P3 → PE2、explicit-null + VPNラベル)tshark -V
    Type: MPLS label switched packet (0x8847)
    [Stream index: 5]
MultiProtocol Label Switching Header, Label: 0 (IPv4 Explicit-Null), Exp: 0, S: 0, TTL: 251
    0000 0000 0000 0000 0000 .... .... .... = MPLS Label: IPv4 Explicit-Null (0)
    .... .... .... .... .... 000. .... .... = MPLS Experimental Bits: 0
    .... .... .... .... .... ...0 .... .... = MPLS Bottom Of Label Stack: 0
    .... .... .... .... .... .... 1111 1011 = MPLS TTL: 251
MultiProtocol Label Switching Header, Label: 24007, Exp: 0, S: 1, TTL: 254
    0000 0101 1101 1100 0111 .... .... .... = MPLS Label: 24007 (0x05dc7)
    .... .... .... .... .... 000. .... .... = MPLS Experimental Bits: 0
    .... .... .... .... .... ...1 .... .... = MPLS Bottom Of Label Stack: 1
    .... .... .... .... .... .... 1111 1110 = MPLS TTL: 254
Internet Protocol Version 4, Src: 192.168.3.1, Dst: 192.168.4.1
    0100 .... = Version: 4
    .... 0101 = Header Length: 20 bytes (5)
    Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
        0000 00.. = Differentiated Services Codepoint: Default (0)
        .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
    Total Length: 100
    Identification: 0x0000 (0)
    000. .... = Flags: 0x0
        0... .... = Reserved bit: Not set
        .0.. .... = Don't fragment: Not set
        ..0. .... = More fragments: Not set
    ...0 0000 0000 0000 = Fragment Offset: 0
    Time to Live: 254
上のtshark出力のパケット(No.584 Echo request、2段)のpcapをダウンロード
CE3 traceroute(STEP 1)
RP/0/RP0/CPU0:CE3#traceroute 192.168.4.1 source 192.168.3.1 timeout 1 probe 2 maxttl 8
Tue Sep 22 04:17:16.610 UTC

Type escape sequence to abort.
Tracing the route to 192.168.4.1

 1  10.2.8.2 6 msec  5 msec
 2  10.2.3.3 [MPLS: Labels 30005/24007 Exp 0] 25 msec  24 msec
 3  10.3.4.4 [MPLS: Labels 40005/24007 Exp 0] 21 msec  21 msec
 4  10.4.5.5 [MPLS: Labels 50005/24007 Exp 0] 21 msec  22 msec
 5  10.5.6.6 [MPLS: Labels 0/24007 Exp 0] 22 msec  23 msec
 6  10.6.9.9 25 msec  *

STEP 2で設定を削除すると、P3のLFIBはPopに戻ります。

P3 show mpls forwarding(STEP 2)
RP/0/RP0/CPU0:P3#show mpls forwarding
Tue Sep 22 04:25:10.263 UTC
Local  Outgoing    Prefix             Outgoing     Next Hop        Bytes
Label  Label       or ID              Interface                    Switched
------ ----------- ------------------ ------------ --------------- ------------
50000  40000       2.2.2.2/32         Gi0/0/0/0    10.4.5.4        37705
50001  40001       3.3.3.3/32         Gi0/0/0/0    10.4.5.4        0
50002  Pop         4.4.4.4/32         Gi0/0/0/0    10.4.5.4        380
50003  40002       10.2.3.0/24        Gi0/0/0/0    10.4.5.4        0
50004  Pop         10.3.4.0/24        Gi0/0/0/0    10.4.5.4        0
50005  Pop         6.6.6.6/32         Gi0/0/0/1    10.5.6.6        38239

疎通

ラベルの操作が変わっても、CE間の疎通はどのSTEPでも保たれています。

CE1 → CE2(グローバル、STEP 0)
RP/0/RP0/CPU0:CE1#ping 192.168.2.1 source 192.168.1.1 count 50 timeout 1
Tue Sep 22 04:10:49.733 UTC
Type escape sequence to abort.
Sending 50, 100-byte ICMP Echos to 192.168.2.1 timeout is 1 seconds:
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Success rate is 100 percent (50/50), round-trip min/avg/max = 18/25/79 ms
CE3 → CE4(VPN、STEP 0)
RP/0/RP0/CPU0:CE3#ping 192.168.4.1 source 192.168.3.1 count 50 timeout 1
Tue Sep 22 04:11:18.275 UTC
Type escape sequence to abort.
Sending 50, 100-byte ICMP Echos to 192.168.4.1 timeout is 1 seconds:
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Success rate is 100 percent (50/50), round-trip min/avg/max = 17/23/61 ms

検証Configおよびshow結果

各STEPで9台すべてから、次の種類をルータごとに分けて取得しています。検証Configはこの..._run.txtです(最終状態はSTEP 2のもの)。各STEPは「カウンタのクリア → ping → show」の順に採っているため、show mpls forwardingのBytes SwitchedはそのSTEPで流したpingの分だけを表します。

ファイル内容
..._clear.txtそのSTEPの最初にクリアしたカウンタ(clear counters interface と clear mpls forwarding counters)
..._ping.txtping(50発)とtraceroute。CE1 - CE2(グローバル)、CE3 - CE4(VPN)、PE1 - PE2(コアのLSP)
..._show.txtshow version / show interface description / show route / OSPF / LDP / show mpls forwarding / show mpls label range / show cef など。PEはBGPとVPNの表示を追加
..._log.txtそのSTEPの範囲だけに絞ったshow logging
..._run.txtそのSTEP時点のshow running-config(=そのSTEPの検証Config)
..._trace.txtコア5台のみ。show mpls ldp trace binding / peer / discovery / forwarding と show mpls lsd trace
..._commit.cfgそのSTEPで実際にcommitされた設定(変更したルータのみ)

STEP 0:初期状態(PHP)

ルータshow出力pingclearsyslogrunning-configtrace投入した設定
CE1showpingclearlogrun——
PE1showpingclearlogruntrace—
P1show—clearlogruntrace—
P2show—clearlogruntrace—
P3show—clearlogruntrace—
PE2showpingclearlogruntrace—
CE2showpingclearlogrun——
CE3showpingclearlogrun——
CE4showpingclearlogrun——

STEP 1:PE2にlabel local advertise explicit-null

ルータshow出力pingclearsyslogrunning-configtrace投入した設定
CE1showpingclearlogrun——
PE1showpingclearlogruntrace—
P1show—clearlogruntrace—
P2show—clearlogruntrace—
P3show—clearlogruntrace—
PE2showpingclearlogruntracecfg
CE2showpingclearlogrun——
CE3showpingclearlogrun——
CE4showpingclearlogrun——

STEP 2:explicit-nullを削除(最終状態)

ルータshow出力pingclearsyslogrunning-configtrace投入した設定
CE1showpingclearlogrun——
PE1showpingclearlogruntrace—
P1show—clearlogruntrace—
P2show—clearlogruntrace—
P3show—clearlogruntrace—
PE2showpingclearlogruntracecfg
CE2showpingclearlogrun——
CE3showpingclearlogrun——
CE4showpingclearlogrun——

パケットキャプチャーはSTEPごとに、コアの4リンクすべてで取得しています。

STEPPE1 - P1間P1 - P2間P2 - P3間P3 - PE2間
0pcappcappcappcap
1pcappcappcappcap
2pcappcappcappcap

参考

RFCタイトル概要
RFC 3031Multiprotocol Label Switching ArchitectureNHLFE / ILM / FTN(3.10〜3.12節)、ラベルの付け替え(3.13節)、PHP(3.16節)。
RFC 3032MPLS Label Stack Encoding予約ラベル(implicit-null 3、explicit-null 0)。
RFC 4182Removing a Restriction on the use of MPLS Explicit NULLExplicit NULLをボトム以外にも置けるようにした改訂。

書籍: Luc De Ghein『MPLS Fundamentals』(Cisco Press, 2006)Chapter 3

関連記事