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

LDPとは

目次

LDPとは

LDP(Label Distribution Protocol、RFC 5036)は、MPLSのラベルを隣のルータへ配るプロトコルです。経路そのものはOSPFやIS-ISが配り、LDPは「そのプレフィックスに私はこのラベルを使う」という対応だけを配ります。本記事ではLDPが隣を見つけてセッションを張りラベルを配るまでを解説し、IOS XR(XRd)のラボで確立の全過程をパケットで追います。ラベルの付け替えはMPLSのラベル操作(push / swap / pop)とPHPで解説しています。

LDPの3つの段階

LDPの動きは3つに分かれます。

段階使うものやること
DiscoveryUDP 646、宛先224.0.0.2Helloを撒いて隣のLSRを見つける
SessionTCP 646見つけた相手とTCPをつなぎ、パラメータを合わせる
Advertisement同じTCP接続自分のアドレスとラベルの対応を送る

Helloだけがマルチキャストで、相手が決まってからはユニキャストのTCPに移ります。TCPを先に張りにいくのは転送アドレスが大きいほうで、小さいほうは待ち受けます。

LDP識別子

LDPは相手をLDP識別子で識別します。6オクテットで、<LSRのID>:<ラベルスペース>と表記します。

前半4オクテットはルータを一意に識別する値で、ルータIDと同じ値にすることが一般的です。後半2オクテットはラベルスペースの番号で、0はプラットフォーム全体で1つのラベル空間を使うことを表します。インタフェースごとにラベル空間を分ける構成では0以外になります。

LDPのメッセージ

RFC 5036が定義するメッセージは11種類です。タイプ値は2オクテットで、種類ごとに番号が割り当てられています。

メッセージType役割
Notification0x0001エラーやセッションの終了を伝える
Hello0x0100隣を見つける。UDPで送る唯一のメッセージ
Initialization0x0200セッションのパラメータを提示する
KeepAlive0x0201セッションを維持する
Address0x0300自分が持つIPアドレスを伝える
Address Withdraw0x0301伝えたアドレスを取り消す
Label Mapping0x0400プレフィックスとラベルの対応を伝える
Label Request0x0401ラベルを要求する(Downstream-on-Demandで使う)
Label Abort Request0x0402出した要求を取り消す
Label Withdraw0x0403配ったラベルを取り消す
Label Release0x0404受け取ったラベルを返す

このうちAddress Withdraw以降の取り消し系は、経路が消えたときやセッションが切れたときに使われます。

Addressが要る理由は、LDPの識別子とラベルを付ける宛先のIPアドレスが別物だからです。受け取った側は、Addressで教わったアドレスの一覧を使って「このネクストホップはどのLDPピアか」を対応付けます。

ラベルの配り方

IOS XRの既定はDownstream-Unsolicitedで、要求を待たずに自分のラベルを配ります。要求があってから配るDownstream-on-Demandもあり、そちらではLabel Requestを使います。配布モードの違いは別記事で解説します。

セッションが上がると、まずAddressで自分のアドレスを送り、続けて持っているプレフィックスの数だけLabel Mappingを送ります。以後は経路が増減したときに差分だけを送り、KeepAliveで接続を維持します。

DiscoveryとSessionは単位が違う

3つの段階のうち、Discoveryはリンクごと、Sessionはピアごとです。ここが対応していないため、リンクが複数あると数が一致しません。

項目DiscoverySession
数の単位インタフェースごとに1つLDPピアごとに1つ
使うアドレスインタフェースのIPアドレス転送アドレス(通常はLoopback)
トランスポートUDP 646のマルチキャストTCP 646のユニキャスト
相手の決め方マルチキャストで探すHelloで知った転送アドレスへ接続する
役割隣にどのLSRがいるかを知るラベルを運ぶ信頼できる通路を作る
切れたと判断するまでHelloのホールドタイム15秒セッションのホールドタイム180秒

PE1とP1を2本のリンクでつなぐと、Discoveryは2つ、Sessionは1本になります。LDPが相手を識別するのはLDP識別子、つまりラベルスペースの単位だからです。ラベルスペースが:0、すなわちプラットフォーム全体で1つなら、どのリンクから来ても同じラベルが有効なので、セッションを分ける理由がありません。

この非対称には運用上の意味があります。片方のリンクが落ちてもセッションは切れません。Discovery Sourceが1つ減るだけで、残った経路でTCP接続が続くためです。ラベルの再配布が起きないので、リンク障害のたびにラベルが振り直されることを避けられます。逆にすべてのリンクが落ちるとDiscovery Sourceが0になり、セッションも終了します

実機での検証

検証環境

CE1 — PE1 — P1 — P2 — PE2 — CE2 を直列につないでいます。AS 65001のPE1 / P1 / P2 / PE2がMPLSネットワークで、OSPF(area 0、全リンクnetwork point-to-point)で経路を、LDPでラベルを配っています。CE3 / CE4はVRF CUST-Aの顧客です。

ルータ役割Lo0リンク
CE1顧客側(AS 65101)、192.168.1.0/24を広告1.1.1.1/32Gi0/0/0/0 10.1.2.1
PE1入口 / 出口LSR(AS 65001)2.2.2.2/32Gi0/0/0/0 10.1.2.2 / Gi0/0/0/1 10.2.3.2
P1中継LSR3.3.3.3/32Gi0/0/0/0 10.2.3.3 / Gi0/0/0/1 10.3.4.3
P2中継LSR4.4.4.4/32Gi0/0/0/0 10.3.4.4 / Gi0/0/0/1 10.4.5.4
PE2入口 / 出口LSR(AS 65001)5.5.5.5/32Gi0/0/0/0 10.4.5.5 / Gi0/0/0/1 10.5.6.5
CE2顧客側(AS 65102)、192.168.6.0/24を広告6.6.6.6/32Gi0/0/0/0 10.5.6.6
CE3VRF CUST-Aの顧客側(AS 65107)、192.168.7.0/24を広告7.7.7.7/32Gi0/0/0/0 10.2.7.7(PE1 Gi0/0/0/2)
CE4VRF CUST-Aの顧客側(AS 65108)、192.168.8.0/24を広告8.8.8.8/32Gi0/0/0/0 10.5.8.8(PE2 Gi0/0/0/2)

PE1 - P1の1リンクをキャプチャーし、LDPのやりとりをパケットで確かめます。

検証のSTEP

STEP操作狙い
0初期状態定常状態のHelloとKeepAlive、LDP識別子、バインディングを確認する
1PE1のmpls ldpからinterface Gi0/0/0/1を外し、戻す確立の全過程を1本のpcapに収める
2PE1にだけLDPの認証を設定認証が合わないとセッションが張れないこと。Helloは流れ続けること
3STEP 2を削除STEP 0と同じに戻ること
4PE1 - P1を2本にするDiscoveryが2つに増えてもSessionは1本のままであること

STEP 0:初期状態

PE1から見た隣の状態です。自分のLDP識別子が2.2.2.2:0、相手が3.3.3.3:0です。

STEP 0 PE1 show mpls ldp discovery
Local LDP Identifier: 2.2.2.2:0
Discovery Sources:
  Interfaces:
    GigabitEthernet0/0/0/1 : xmit/recv
      VRF: 'default' (0x60000000)
      LDP Id: 3.3.3.3:0, Transport address: 3.3.3.3
          Hold time: 15 sec (local:15 sec, peer:15 sec)
          Established: Sep 10 14:56:38.298 (08:28:02 ago)

xmit/recvはHelloを送受信できている状態です。ホールドタイムは15秒で、この間にHelloが届かなければ相手を失ったと判断します。

セッションの側はTCPです。show mpls ldp neighbor detailに接続の両端が出ます。

STEP 0 PE1 show mpls ldp neighbor detail(抜粋)
Peer LDP Identifier: 3.3.3.3:0
  TCP connection: 3.3.3.3:63514 - 2.2.2.2:646
  Graceful Restart: No
  Session Holdtime: 180 sec
  State: Oper; Msgs sent/rcvd: 590/590; Downstream-Unsolicited
  Up time: 08:28:01
  LDP Discovery Sources:
    IPv4: (1)
      GigabitEthernet0/0/0/1
    IPv6: (0)
  Addresses bound to this peer:
    IPv4: (3)
      3.3.3.3        10.2.3.3       10.3.4.3       
    IPv6: (0)
  Peer holdtime: 180 sec; KA interval: 60 sec; Peer state: Estab

P1側が63514番から接続し、PE1が646で待ち受けています。転送アドレスは3.3.3.3と2.2.2.2なので、大きいほうのP1が接続する側になりました。Addresses bound to this peerがAddressメッセージで受け取ったアドレスの一覧です。

配ったラベルと受け取ったラベルはshow mpls ldp bindingsに並びます。

STEP 0 PE1 show mpls ldp bindings(先頭2件)
2.2.2.2/32, rev 7
	Local binding: label: ImpNull
	Remote bindings: (1 peers)
	    Peer                Label    
	    -----------------   ---------
	    3.3.3.3:0           24002   
3.3.3.3/32, rev 11
	Local binding: label: 24000
	Remote bindings: (1 peers)
	    Peer                Label    
	    -----------------   ---------
	    3.3.3.3:0           ImpNull 

自分のLoopback0である2.2.2.2/32にはImpNull(implicit-null)を配っています。自分が出口なので、1つ手前でラベルを外してほしいという意味です。

キャプチャーには、5秒ごとのHelloがUDP 646のマルチキャストで、60秒ごとのKeepAliveがTCP 646のユニキャストで流れています。

STEP 1:LDPを切って戻す

PE1のmpls ldpからinterface GigabitEthernet0/0/0/1を外し、49秒後に戻しました。syslogには切断と再確立が1組だけ残ります。

STEP 1 PE1 show logging(抜粋)
RP/0/RP0/CPU0:Sep 10 23:30:49.514 UTC: mpls_ldp[1178]: %ROUTING-LDP-5-NBR_CHANGE : VRF 'default' (0x60000000), Neighbor 3.3.3.3:0 is DOWN (LDP IPv4 disabled on interface) 
RP/0/RP0/CPU0:Sep 10 23:31:38.596 UTC: mpls_ldp[1178]: %ROUTING-LDP-5-NBR_CHANGE : VRF 'default' (0x60000000), Neighbor 3.3.3.3:0 is UP (IPv4 connection) 

キャプチャーには確立の全過程が連続して入りました。No.39からNo.47までが1回の確立です。

STEP 1 PE1 - P1 のキャプチャー(TCPとLDP、Helloを除く)
39	58.809799000	3.3.3.3	2.2.2.2	28509 → 646 [SYN] Seq=0 Win=16384 Len=0 MSS=1240 WS=1
41	58.830371000	2.2.2.2	3.3.3.3	646 → 28509 [SYN, ACK] Seq=0 Ack=1 Win=16384 Len=0 MSS=1240 WS=1
42	58.833393000	3.3.3.3	2.2.2.2	28509 → 646 [ACK] Seq=1 Ack=1 Win=16384 Len=0
43	58.834409000	3.3.3.3	2.2.2.2	Initialization Message 
44	58.939718000	2.2.2.2	3.3.3.3	Initialization Message Keep Alive Message 
45	58.943971000	3.3.3.3	2.2.2.2	Keep Alive Message 
46	59.021589000	2.2.2.2	3.3.3.3	Address Message Label Mapping Message Label Mapping Message Label Mapping Message Label Mapping Message Label Mapping Message Label Mapping Message Label Mapping Message Label Mapping Message 
47	59.024623000	3.3.3.3	2.2.2.2	Address Message Label Mapping Message Label Mapping Message Label Mapping Message Label Mapping Message Label Mapping Message Label Mapping Message Label Mapping Message 

TCPの3ウェイハンドシェイクが終わってから、Initializationが両方向に流れ、KeepAliveで確認し、AddressとLabel Mappingが続きます。確立からラベル配布までが0.2秒で終わっています。

Initializationの中身です。LDP識別子とセッションのパラメータが入っています。

STEP 1 No.43 Initialization(tshark -V 抜粋)
Internet Protocol Version 4, Src: 3.3.3.3, Dst: 2.2.2.2
    Version: 1
    PDU Length: 68
    LSR ID: 3.3.3.3
    Label Space ID: 0
        Message Type: Initialization Message (0x200)
                Session Protocol Version: 1
                Session KeepAlive Time: 180
                Session Max PDU Length: 0
上のtshark出力のパケット(No.43 Initialization)のpcapをダウンロード

Session KeepAlive Time: 180が提示したホールドタイムです。両者が出した値の小さいほうが採用され、その3分の1の60秒がKeepAliveの送信間隔になります。

No.46はAddressとLabel Mapping 8個が1つのTCPセグメントに入ったものです。

上で触れたパケット(No.46 Address + Label Mapping ×8)のpcapをダウンロード

切断のときはNotificationが送られます。No.12には2つ入っていました。

STEP 1 No.12 Notification(tshark -V 抜粋)
        Message Type: Notification Message (0x1)
                ..00 0000 0000 0000 0000 0000 0000 1001 = Status Data: Hold Timer Expired (0x9)
        Message Type: Notification Message (0x1)
                ..00 0000 0000 0000 0000 0000 0000 1010 = Status Data: Shutdown (0xA)
上のtshark出力のパケット(No.12 Notification)のpcapをダウンロード

このキャプチャーで観測できたメッセージは6種類で、タイプ値はRFC 5036の定義と一致しました。

観測したメッセージType
Notification0x0001
Hello0x0100
Initialization0x0200
KeepAlive0x0201
Address0x0300
Label Mapping0x0400

残るLabel Request / Label Abort Request / Label Withdraw / Label Release / Address Withdrawは、この検証では観測していません

STEP 2:片側だけ認証を設定する

PE1にだけLDPの認証を設定しました。DiscoveryとSessionが別の段階であることが、この状態によく現れます。

STEP 2 PE1 show mpls ldp discovery
Local LDP Identifier: 2.2.2.2:0
Discovery Sources:
  Interfaces:
    GigabitEthernet0/0/0/1 : xmit/recv
      VRF: 'default' (0x60000000)
      LDP Id: 3.3.3.3:0, Transport address: 3.3.3.3
          Hold time: 15 sec (local:15 sec, peer:15 sec)
          Established: Sep 10 23:31:38.337 (00:14:27 ago)

Helloは認証の対象ではないのでxmit/recvのままで、相手のLDP識別子も見えています。それでもネイバーは0件です。TCPが張れないためで、キャプチャーにはSYNの再送だけが並びます。

STEP 2 PE1 - P1 のキャプチャー(TCP 646)
9	11.273014000	2.2.2.2	3.3.3.3	646 → 28509 [FIN, ACK] Seq=1 Ack=19 Win=15867 Len=0
11	11.279687000	3.3.3.3	2.2.2.2	28509 → 646 [FIN, ACK] Seq=19 Ack=2 Win=15867 Len=0
16	13.302019000	3.3.3.3	2.2.2.2	29559 → 646 [SYN] Seq=0 Win=16384 Len=0 MSS=1240 WS=1
18	15.303119000	3.3.3.3	2.2.2.2	[TCP Retransmission] 29559 → 646 [SYN] Seq=0 Win=16384 Len=0 MSS=1240 WS=1
21	19.303361000	3.3.3.3	2.2.2.2	[TCP Retransmission] 29559 → 646 [SYN] Seq=0 Win=16384 Len=0 MSS=1240 WS=1
28	27.303824000	3.3.3.3	2.2.2.2	[TCP Retransmission] 29559 → 646 [SYN] Seq=0 Win=16384 Len=0 MSS=1240 WS=1

PE1側は受け取ったSYNを捨てています。syslogに理由が出ます。

STEP 2 PE1 show logging(抜粋)
RP/0/RP0/CPU0:Sep 10 23:41:19.620 UTC: mpls_ldp[1178]: %ROUTING-LDP-5-NBR_CHANGE : VRF 'default' (0x60000000), Neighbor 3.3.3.3:0 is DOWN (Session MD5 password changed) 
RP/0/RP0/CPU0:Sep 10 23:41:21.652 UTC: tcp[134]: %IP-TCP-3-BADAUTH : Invalid MD5 digest from 3.3.3.3:29559 to 2.2.2.2:646 for vrf:default (0x60000000) 

LDPの認証はTCPのMD5署名で行うため、LDPのメッセージが1つも流れないままTCPの段階で落ちます。認証の設定そのものは別記事で解説します。

STEP 3:認証を削除

設定を外すとセッションが戻り、バインディングも8件に復帰します。STEP 0と同じ状態です。

STEP 4:PE1 - P1を2本にする

PE1のGi0/0/0/3とP1のGi0/0/0/2を10.2.13.0/24でつなぎ、両方でOSPFとLDPを有効にしました。2本目のOSPFコストは100にしてあるので、転送経路は1本目のままです。

PE1のDiscovery Sourceは2つになります。

STEP 4 PE1 show mpls ldp discovery
Local LDP Identifier: 2.2.2.2:0
Discovery Sources:
  Interfaces:
    GigabitEthernet0/0/0/1 : xmit/recv
      VRF: 'default' (0x60000000)
      LDP Id: 3.3.3.3:0, Transport address: 3.3.3.3
          Hold time: 15 sec (local:15 sec, peer:15 sec)
          Established: Sep 11 02:59:52.792 (00:10:03 ago)

    GigabitEthernet0/0/0/3 : xmit/recv
      VRF: 'default' (0x60000000)
      LDP Id: 3.3.3.3:0, Transport address: 3.3.3.3
          Hold time: 15 sec (local:15 sec, peer:15 sec)
          Established: Sep 11 02:59:52.883 (00:10:03 ago)

どちらも相手は同じ3.3.3.3:0で、転送アドレスも同じ3.3.3.3です。一方でセッションは1本のままです。

STEP 4 PE1 show mpls ldp neighbor detail(抜粋)
Peer LDP Identifier: 3.3.3.3:0
  TCP connection: 3.3.3.3:54016 - 2.2.2.2:646
  Graceful Restart: No
  Session Holdtime: 180 sec
  State: Oper; Msgs sent/rcvd: 22/21; Downstream-Unsolicited
  Up time: 00:09:50
  LDP Discovery Sources:
    IPv4: (2)
      GigabitEthernet0/0/0/1
      GigabitEthernet0/0/0/3
    IPv6: (0)
  Addresses bound to this peer:
    IPv4: (4)
      3.3.3.3        10.2.3.3       10.2.13.3      10.3.4.3       
    IPv6: (0)
  Peer holdtime: 180 sec; KA interval: 60 sec; Peer state: Estab

Peer LDP Identifierは1つ、TCP connectionも1本で、その下にLDP Discovery Sources: IPv4: (2)として2つのインタフェースが並びます。2つのDiscoveryが1つのSessionに集約されていることがこの1画面で読めます。Addresses bound to this peerが3件から4件に増えているのは、2本目のリンクのアドレス10.2.13.3をAddressメッセージで受け取ったためです。

隣接の数え方の違いは、OSPFと並べると分かりやすくなります。

プロトコルPE1から見たP1との隣接数
OSPF2(リンクごとに隣接を張る)
LDP Discovery2(リンクごとにHello)
LDP Session1(ピアごとに1本)

2本のリンクを同時にキャプチャーすると、流れるものがはっきり分かれます。

リンクHello(UDP 646)TCP 646のパケット
1本目(10.2.3.0/24)6512
2本目(10.2.13.0/24)640

Helloは両方に流れ、TCPは1本目にしか流れません。2本目はLDPが有効で隣も見えているのに、セッションはすでに1本目で確立しているため使われません。どちらのリンクが選ばれるかはセッションを張った時点で決まります。

キャプチャー

PE1 - P1の1リンクを採取しています。フィルターなしで取得しました。

STEP 0 定常状態

STEP 1 切断と確立

STEP 2 認証不一致

STEP 4 1本目(10.2.3.0/24)

STEP 4 2本目(10.2.13.0/24)

検証Configおよびshow結果

各STEPで8台すべてから、次の種類をルータごとに分けて取得しています。検証Configはこの..._run.txtです(最終状態は最後のSTEPのもの)。

ファイル内容
..._show.txtshow version / show interface description / show route と、OSPF・LDP・MPLS転送・BGPの一式
..._log.txtそのSTEPの範囲だけに絞ったshow logging
..._run.txtそのSTEP時点のshow running-config(=そのSTEPの検証Config)
..._trace.txtコア4台のLDPとLSDのトレース

STEP 0:初期状態

ルータshow出力syslogrunning-configtrace
CE1showlogrun-
PE1showlogruntrace
P1showlogruntrace
P2showlogruntrace
PE2showlogruntrace
CE2showlogrun-
CE3showlogrun-
CE4showlogrun-

STEP 1:LDPを切って戻す

ルータshow出力syslogrunning-configtrace
CE1showlogrun-
PE1showlogruntrace
P1showlogruntrace
P2showlogruntrace
PE2showlogruntrace
CE2showlogrun-
CE3showlogrun-
CE4showlogrun-

STEP 2:片側だけ認証を設定する

ルータshow出力syslogrunning-configtrace
CE1showlogrun-
PE1showlogruntrace
P1showlogruntrace
P2showlogruntrace
PE2showlogruntrace
CE2showlogrun-
CE3showlogrun-
CE4showlogrun-

STEP 3:認証を削除(最終状態)

ルータshow出力syslogrunning-configtrace
CE1showlogrun-
PE1showlogruntrace
P1showlogruntrace
P2showlogruntrace
PE2showlogruntrace
CE2showlogrun-
CE3showlogrun-
CE4showlogrun-

STEP 4:PE1 - P1を2本にする

ルータshow出力syslogrunning-configtrace
CE1showlogrun-
PE1showlogruntrace
P1showlogruntrace
P2showlogruntrace
PE2showlogruntrace
CE2showlogrun-
CE3showlogrun-
CE4showlogrun-

参考

RFCタイトル概要
RFC 5036LDP SpecificationDiscovery(2.4節)、セッション確立の状態遷移(2.5.4節)、TCP / UDPとも646番(3.10.1節)、メッセージのタイプ値。
RFC 3031Multiprotocol Label Switching Architectureラベル配布プロトコルの位置づけ。

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

関連記事