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

LDPのラベル広告制御(フィルタリング)

目次

LDPのラベル広告制御(フィルタリング)

LDPは既定で、IGPが知っているプレフィックスすべてにラベルを割り当てて配ります。しかし実際に必要なのは、BGPのネクストホップになるLoopbackの/32だけです。配るラベルを絞る3つの制御点を解説し、IOS XR(XRd)のラボで、絞っても通信が壊れないことを確かめます。LDPの基本はLDPとはで解説しています。

何を絞るのか

MPLSでパケットを運ぶとき、入口のPEが積むトランスポートラベルはBGPのネクストホップ(相手PEのLoopback)へ向かうLSPのラベルです。コアのリンクのサブネットは、そこを通過はしますがネクストホップにはならないので、ラベルを持つ必要がありません。

それでもLDPが全部に配ってしまうのは、規格が「何を配るか」を決めていないからです。RFC 5036の2.6.3節が定めるのはDownstream Unsolicited / Downstream on Demandという「いつ配るか」だけで、フィルタの仕組みはプロトコルに存在しません。何を配るかは実装ごとのローカルな方針です。

絞る理由は3つあります。ラベルテーブルが小さくなること、LDPが交換するメッセージが減ること、そして意図しないLSPを作らせないことです。

3つの制御点

ラベルは「自分のLIBに作る → 相手へ配る → 相手が受け取る」という順に流れます。IOS XRはこの3か所それぞれで止められます。

制御点 止まる場所 効果
label allocate 作る前 ローカルラベルを作らない。LIBそのものが小さくなる
label advertise 配るとき 作るが相手に配らない。ピアごとに変えられる
label remote accept 受け取るとき 受け取った分を捨てる。受ける側だけで決められる

自分の装置のラベルテーブルを小さくしたいならlabel allocate、相手に見せたくないだけならlabel advertise、相手の設定に期待できないならlabel remote accept、という使い分けになります。

3つともmpls ldpaddress-family ipv4配下のlabelにあり、local(自分が作る・配る)とremote(相手から受け取る)に分かれます。絞り込みの対象はルートポリシーではなくIPアクセスリストで、ピアの指定はLDP識別子3.3.3.3:0のようにラベルスペース番号まで含む形)です。

IOS XRの構文(XRd 26.1.1)
mpls ldp
 address-family ipv4
  label
   local
    allocate for <アクセスリスト>      ← 作る前に止める
    advertise
     to <LDP識別子> for <アクセスリスト>   ← ピアごとに配る中身を決める
   remote
    accept
     from <LDP識別子> for <アクセスリスト>  ← 受け取る側で捨てる

allocate forにはhost-routesというキーワードもあり、アクセスリストを書かずに「/32だけ」を指定できます。

フィルタを緩めるときはセッションのリセットが要る

一度取り下げたラベルは、フィルタを外しても自動では再広告されません。 LDPはDownstream Unsolicitedでも定期的な再送をしないため、advertiseのフィルタを消しただけでは相手のLIBは戻りません。戻すにはclear mpls ldp neighbor <相手>でセッションを張り直します。

フィルタをきつくする変更は即座に反映される(Label Withdrawが飛ぶ)のに、緩める変更は反映されない、という非対称があります。運用では、絞り込みを緩めた後にLSPが復活しない場合、設定ではなくこの性質を疑います。

検証構成

冗長性のない直列構成です。コア(PE1 - P1 - P2 - PE2)でOSPFとLDPを動かし、CE1とCE2はVRF CUST-AでPEに接続してVPNv4で疎通させます。

MPLS-FILTERラボ
  CE1 ------ PE1 ------ P1 ------ P2 ------ PE2 ------ CE2
(AS 65101)    |                               |    (AS 65102)
           vrf CUST-A                    vrf CUST-A
              └────── iBGP vpnv4(Lo0間)──────┘
ルータ Lo0 役割 リンク サブネット
CE1 1.1.1.1 AS 65101、192.168.1.0/24 CE1 - PE1 10.1.2.0/24(VRF)
PE1 2.2.2.2 入口/出口LSR、vrf CUST-A PE1 - P1 10.2.3.0/24
P1 3.3.3.3 中継LSR P1 - P2 10.3.4.0/24
P2 4.4.4.4 中継LSR P2 - PE2 10.4.5.0/24
PE2 5.5.5.5 入口/出口LSR、vrf CUST-A PE2 - CE2 10.5.6.0/24(VRF)
CE2 6.6.6.6 AS 65102、192.168.2.0/24

グローバルのOSPFが知るのは7プレフィックスです。Lo0の/32が4本と、コアのリンクの/24が3本。PE - CEのリンクはVRFにあるためグローバルのOSPFに入らず、はじめからラベルが付きません。

検証の全体像

STEP 操作 確かめること
0 初期状態 7本すべてにラベルが付いていること。ping / tracerouteが通ること
1 label allocateで/32だけに絞る(コア4台) LIBが7→4に縮むこと。pingとtracerouteが変わらないこと
2 label advertiseでPE1へ配る中身だけ絞る PE1のRemote bindingsが減り、絞っていないP2は変わらないこと
3 送信側を外しlabel remote acceptで受信側を絞る P1は送っているのにPE1が持たないこと
4 すべて撤去(最終状態) STEP 0と同じに戻ること

疎通はCE1からping 192.168.2.1 source 192.168.1.1 count 50 timeout 1tracerouteで各STEP測っています。

STEP 0:既定では全プレフィックスにラベルが付く

P1のローカルバインディングです。Lo0の/32が4本とリンクの/24が3本、合わせて7本すべてにラベルが割り当たっています。

STEP 0 P1 show mpls ldp bindings local
RP/0/RP0/CPU0:P1#show mpls ldp bindings local
Sat Sep 12 02:38:02.240 UTC

2.2.2.2/32, rev 12
	Local binding: label: 24002
3.3.3.3/32, rev 2
	Local binding: label: ImpNull
4.4.4.4/32, rev 9
	Local binding: label: 24000
5.5.5.5/32, rev 14
	Local binding: label: 24003
10.2.3.0/24, rev 25
	Local binding: label: ImpNull
10.3.4.0/24, rev 27
	Local binding: label: ImpNull
10.4.5.0/24, rev 29
	Local binding: label: 24001

転送テーブルを見ると、その/24のラベルが使われていないことが数字で分かります。10.4.5.0/24のラベル24001はBytes Switched0です。

STEP 0 P1 show mpls forwarding
RP/0/RP0/CPU0:P1#show mpls forwarding
Sat Sep 12 02:38:03.103 UTC
Local  Outgoing    Prefix             Outgoing     Next Hop        Bytes       
Label  Label       or ID              Interface                    Switched    
------ ----------- ------------------ ------------ --------------- ------------
24000  Pop         4.4.4.4/32         Gi0/0/0/1    10.3.4.4        17265       
24001  Pop         10.4.5.0/24        Gi0/0/0/1    10.3.4.4        0           
24002  Pop         2.2.2.2/32         Gi0/0/0/0    10.2.3.2        1615        
24003  24003       5.5.5.5/32         Gi0/0/0/1    10.3.4.4        69570       

STEP 1:作る前に止める(label allocate)

コア4台に、Lo0の/32だけを許可するアクセスリストとallocate forを入れます。

STEP 1 P1にcommitした設定
ipv4 access-list LDP-LOOPBACKS
 10 permit ipv4 host 2.2.2.2 any
 20 permit ipv4 host 3.3.3.3 any
 30 permit ipv4 host 4.4.4.4 any
 40 permit ipv4 host 5.5.5.5 any
!
mpls ldp
 address-family ipv4
  label
   local
    allocate for LDP-LOOPBACKS

ローカルバインディングが4本になり、/24は消えます。

STEP 1 P1 show mpls ldp bindings local
RP/0/RP0/CPU0:P1#show mpls ldp bindings local
Sat Sep 12 02:45:17.334 UTC

2.2.2.2/32, rev 12
	Local binding: label: 24002
3.3.3.3/32, rev 2
	Local binding: label: ImpNull
4.4.4.4/32, rev 9
	Local binding: label: 24000
5.5.5.5/32, rev 14
	Local binding: label: 24003

転送テーブルからも24001が消え、Lo0の3エントリーだけになりました。

STEP 1 P1 show mpls forwarding
RP/0/RP0/CPU0:P1#show mpls forwarding
Sat Sep 12 02:45:18.667 UTC
Local  Outgoing    Prefix             Outgoing     Next Hop        Bytes       
Label  Label       or ID              Interface                    Switched    
------ ----------- ------------------ ------------ --------------- ------------
24000  Pop         4.4.4.4/32         Gi0/0/0/1    10.3.4.4        24167       
24002  Pop         2.2.2.2/32         Gi0/0/0/0    10.2.3.2        34825       
24003  24003       5.5.5.5/32         Gi0/0/0/1    10.3.4.4        101594      

絞っても通信は変わらない

この記事の核心です。CE1からCE2へのtracerouteは、STEP 0とまったく同じラベルスタックを通ります。

STEP 1 CE1 traceroute
RP/0/RP0/CPU0:CE1#traceroute 192.168.2.1 source 192.168.1.1
Sat Sep 12 02:49:06.719 UTC

Type escape sequence to abort.
Tracing the route to 192.168.2.1

 1  10.1.2.2 5 msec  4 msec  4 msec 
 2  10.2.3.3 [MPLS: Labels 24003/24005 Exp 0] 14 msec  22 msec  14 msec 
 3  10.3.4.4 [MPLS: Labels 24003/24005 Exp 0] 15 msec  15 msec  16 msec 
 4  10.4.5.5 [MPLS: Label 24005 Exp 0] 16 msec  15 msec  15 msec 
 5  10.5.6.6 16 msec  *  17 msec 

トランスポートラベル24003(5.5.5.5/32行き)とVPNラベル24005の2段スタックで、P2でPHPによりトランスポートラベルが外れる、という動きが保たれています。pingも全STEPで無損失でした。

STEP LIBのプレフィックス数(P1) CE1 → CE2のping
0 7 100%(50/50)
1 4 100%(50/50)
2 4 100%(50/50)
3 4 100%(50/50)
4 7 100%(50/50)

ラベルを4割減らしても、転送は1パケットも落ちません。

STEP 2:配るときに止める(label advertise)

P1がPE1にだけ配る中身を5.5.5.5/32に絞ります。P2向けは触りません。

STEP 2 P1にcommitした設定
ipv4 access-list LDP-PE2-ONLY
 10 permit ipv4 host 5.5.5.5 any
!
mpls ldp
 address-family ipv4
  label
   local
    advertise
     to 2.2.2.2:0 for LDP-PE2-ONLY

同じP1を相手にしていても、PE1が受け取るラベルは1本、P2は4本のままです。Labelsの列にそれが出ます。

STEP 2 PE1 show mpls ldp neighbor brief
RP/0/RP0/CPU0:PE1#show mpls ldp neighbor brief
Sat Sep 12 02:53:32.502 UTC

Peer               GR  NSR  Up Time     Discovery   Addresses     Labels    
                                        ipv4  ipv6  ipv4  ipv6  ipv4   ipv6 
-----------------  --  ---  ----------  ----------  ----------  ------------
3.3.3.3:0          N   N    00:18:17    1     0     3     0     1      0    
STEP 2 P2 show mpls ldp neighbor brief(絞っていない側)
RP/0/RP0/CPU0:P2#show mpls ldp neighbor brief
Sat Sep 12 02:52:41.600 UTC

Peer               GR  NSR  Up Time     Discovery   Addresses     Labels    
                                        ipv4  ipv6  ipv4  ipv6  ipv4   ipv6 
-----------------  --  ---  ----------  ----------  ----------  ------------
3.3.3.3:0          N   N    00:54:50    1     0     3     0     4      0    
5.5.5.5:0          N   N    00:49:38    1     0     2     0     4      0    

設定を入れた瞬間、P1はPE1へLabel Withdrawを3つ送っています。添付のキャプチャーのNo.1832です。

STEP 2 No.1832 Label Withdrawal ×3(P1 → PE1、tshark -V 抜粋)
Internet Protocol Version 4, Src: 3.3.3.3, Dst: 2.2.2.2
Label Distribution Protocol
    Version: 1
    PDU Length: 90
    LSR ID: 3.3.3.3
    Label Space ID: 0
        Message Type: Label Withdrawal Message (0x402)
                    FEC Element Length: 32
                    Prefix: 3.3.3.3
        Message Type: Label Withdrawal Message (0x402)
                    FEC Element Length: 32
                    Prefix: 4.4.4.4
        Message Type: Label Withdrawal Message (0x402)
                    FEC Element Length: 32
                    Prefix: 2.2.2.2
上のtshark出力のパケット(No.1832 Label Withdrawal)のpcapをダウンロード

PE1が持たなくなったのは、P1が送るのをやめたからです。

STEP 3:受け取るときに止める(label remote accept)

送信側のフィルタを外し、今度はPE1側で受け取りを絞ります。前述のとおりフィルタを外しただけでは取り下げたラベルが戻らないので、clear mpls ldp neighbor 2.2.2.2でセッションを張り直してから投入しています。

STEP 3 PE1にcommitした設定
ipv4 access-list LDP-PE2-ONLY
 10 permit ipv4 host 5.5.5.5 any
!
mpls ldp
 address-family ipv4
  label
   remote
    accept
     from 3.3.3.3:0 for LDP-PE2-ONLY

PE1から見た結果は、STEP 2と区別が付きません。Labelsはやはり1です。

STEP 3 PE1 show mpls ldp neighbor brief
RP/0/RP0/CPU0:PE1#show mpls ldp neighbor brief
Sat Sep 12 03:02:00.308 UTC

Peer               GR  NSR  Up Time     Discovery   Addresses     Labels    
                                        ipv4  ipv6  ipv4  ipv6  ipv4   ipv6 
-----------------  --  ---  ----------  ----------  ----------  ------------
3.3.3.3:0          N   N    00:04:00    1     0     3     0     1      0    

違いが出るのは線路の上です。P1は4本すべてのLabel Mappingを送っています。添付のキャプチャーのNo.2867です。

STEP 3 No.2867 Label Mapping ×4(P1 → PE1、tshark -V 抜粋)
Internet Protocol Version 4, Src: 3.3.3.3, Dst: 2.2.2.2
Label Distribution Protocol
    Version: 1
    PDU Length: 118
    LSR ID: 3.3.3.3
    Label Space ID: 0
        Message Type: Label Mapping Message (0x400)
                    FEC Element Length: 32
                    Prefix: 3.3.3.3
        Message Type: Label Mapping Message (0x400)
                    FEC Element Length: 32
                    Prefix: 4.4.4.4
        Message Type: Label Mapping Message (0x400)
                    FEC Element Length: 32
                    Prefix: 2.2.2.2
        Message Type: Label Mapping Message (0x400)
                    FEC Element Length: 32
                    Prefix: 5.5.5.5
上のtshark出力のパケット(No.2867 Label Mapping)のpcapをダウンロード

2.2.2.2 / 3.3.3.3 / 4.4.4.4のマッピングは届いていますが、PE1はアクセスリストに一致しないので捨てています。showの数字は同じでも、帯域とメッセージ処理は節約できていません。 相手の設定を変えられる立場ならadvertise側で止めるほうが有利です。

どちらで止めるか LDPメッセージ 使いどころ
advertise(送信側) 流れない 自分が広告する側を管理できるとき
remote accept(受信側) 流れる(捨てるだけ) 相手の設定に期待できないとき、受ける側だけで決めたいとき

STEP 4:撤去して元に戻る

すべてのアクセスリストとフィルタを外すと、LIBは7本に戻ります。撤去時はPE1がLabel Requestを送り、P1が7本のLabel Mappingを返しています(キャプチャーのNo.3745とNo.3755)。

STEP 4 P1 show mpls ldp bindings summary
RP/0/RP0/CPU0:P1#show mpls ldp bindings summary
Sat Sep 12 03:07:12.304 UTC

LIB Summary:
  Total Prefix   : 7 
  Revision No    : Current:38, Advertised:38
  Local Bindings : 7
      NULL    : 3 (implicit:3, explicit:0)
      Non-NULL: 4 (lowest:24000, highest:24003)
  Remote Bindings: 14
撤去後にP1が7本のラベルを配り直したパケット(No.3755 Label Mapping)のpcapをダウンロード

最終STEPのrunning-configは、ラボの起動時Configと1行も違いません。

設計上の注意

  • 絞る基準はBGPのネクストホップです。PEのLoopbackに加えて、RRやインターAS向けに他のPEから参照されるアドレスがあれば、それもアクセスリストに含めます。漏らすとそのPE宛のLSPだけが張れず、VPNが片方向で落ちます
  • allocateはLIBを小さくしますが、自分が経路を知らなくなるわけではありません。 show mpls ldp bindings summaryTotal Prefixは絞る前の本数のまま(N unresolved)と表示され、ラベルを作っていないプレフィックスも把握されています
  • フィルタを緩めた変更は、セッションを張り直すまで反映されません(前述)。メンテナンス手順にclear mpls ldp neighborを含めておきます

検証Configおよびshow結果

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

ファイル 内容
..._show.txt show version / show interface description / show mpls ldp bindings 一式 / show mpls forwarding など
..._log.txt そのSTEPの範囲だけに絞ったshow logging。各STEPの開始時にlogmsgでマーカーを入れ、その時刻をshow logging startに指定して取得したもの
..._run.txt そのSTEP時点のshow running-config(=そのSTEPの検証Config)
..._ping.txt そのSTEPのping(50発、timeout 1秒)とtraceroute
..._trace.txt show mpls ldp trace binding / peer / discovery など(コア4台のみ)
..._commit.cfg そのSTEPで実際にcommitした設定だけ。 設定を変えたルータの分のみ

STEP 0:初期状態

ルータ show出力 syslog running-config ping trace commit
CE1 show log run ping - -
PE1 show log run ping trace -
P1 show log run ping trace -
P2 show log run ping trace -
PE2 show log run ping trace -
CE2 show log run ping - -

STEP 1:label allocateで/32だけに絞る(コア4台)

ルータ show出力 syslog running-config ping trace commit
CE1 show log run ping - -
PE1 show log run ping trace cfg
P1 show log run ping trace cfg
P2 show log run ping trace cfg
PE2 show log run ping trace cfg
CE2 show log run ping - -

STEP 2:label advertiseでPE1へ配る中身だけ絞る

ルータ show出力 syslog running-config ping trace commit
CE1 show log run ping - -
PE1 show log run ping trace -
P1 show log run ping trace cfg
P2 show log run ping trace -
PE2 show log run ping trace -
CE2 show log run ping - -

STEP 3:送信側を外しlabel remote acceptで受信側を絞る

ルータ show出力 syslog running-config ping trace commit
CE1 show log run ping - -
PE1 show log run ping trace cfg
P1 show log run ping trace cfg
P2 show log run ping trace -
PE2 show log run ping trace -
CE2 show log run ping - -

STEP 4:すべて撤去(最終状態)

ルータ show出力 syslog running-config ping trace commit
CE1 show log run ping - -
PE1 show log run ping trace cfg
P1 show log run ping trace cfg
P2 show log run ping trace cfg
PE2 show log run ping trace cfg
CE2 show log run ping - -

PE1 - P1間のキャプチャー全体です。STEP 1のLabel Withdrawから、STEP 4でラベルが戻るまでが1本に入っています。

PE1 - P1間のキャプチャー全体をダウンロード

参考

出典 参照した箇所
RFC 5036 LDP Specification 2.6.3節(Downstream Unsolicited / on Demand)。ラベル広告のフィルタはRFCに規定が無いことの確認
IOS XR MPLS Configuration Guide label allocate / label advertise / label remote acceptの構文

検証はXRd 26.1.1(Cisco Modeling Labs)で実施しました。