クイックスタート:5分以内にMPLS + LDPを動かす
理論を読む前にMPLSフォワーディングとLDPネイバーが動作する様子を確認したい場合は、最短手順を紹介します。FRRouting 8.x以降、Linuxカーネル4.4以上、そして通信可能な最低2台のVMまたはネットワーク名前空間が必要です。
ステップ1 — LinuxカーネルでMPLSを有効化する
FRRoutingはコントロールプレーンを担当しますが、実際のラベルフォワーディングはLinuxカーネルが行います。2つのモジュールをロードし、ラベル付きトラフィックを通過させるすべてのインターフェースでMPLS入力を有効にする必要があります。
# MPLSフォワーディングモジュールをロード
modprobe mpls_router
modprobe mpls_iptunnel
# トランジットインターフェースでMPLS入力を有効化
sysctl -w net.mpls.conf.eth0.input=1
sysctl -w net.mpls.conf.eth1.input=1
# プラットフォームラベル上限を引き上げる(デフォルトは0 — これがないとMPLSは動作しない)
sysctl -w net.mpls.platform_labels=100000
再起動後も設定が保持されるよう永続化します:
# /etc/sysctl.d/mpls.conf
net.mpls.platform_labels = 100000
net.mpls.conf.eth0.input = 1
net.mpls.conf.eth1.input = 1
また、起動時にモジュールがロードされるよう/etc/modulesにも追加します:
echo -e "mpls_router\nmpls_iptunnel" >> /etc/modules
ステップ2 — FRRoutingでLDPデーモンを有効化する
# /etc/frr/daemonsを編集
ospfd=yes
ldpd=yes
systemctl restart frr
ステップ3 — vtyshで最小限のLDP設定を行う
vtysh
router ospf
network 10.0.12.0/30 area 0
network 1.1.1.1/32 area 0
!
mpls ldp
router-id 1.1.1.1
!
address-family ipv4
discovery transport-address 1.1.1.1
!
interface eth0
!
!
LDPを動かすために必要なのはこれだけです。では、内部で何が起きているのかを理解していきましょう。
詳細解説:MPLSラベルスイッチングとLDPの仕組み
MPLSはサービスプロバイダーネットワークおよびあらゆる本格的なVPN展開において基盤となる技術です。20ビットのラベルが各中継ホップでのフルIPルックアップを置き換える仕組みを理解すると、パケットフォワーディングに対する考え方が変わります——SPの世界が急に明確に見えてきます。
従来のIPルーティングは各ホップで宛先アドレスを検査し、最長プレフィックスマッチを実行します——大規模環境ではコストが高くなります。MPLSはこれを各中継ルーターでの20ビットラベルルックアップに置き換えます。ラベルはネットワークエッジでパケットにプッシュされ、各中継ホップでスワップされ、配送前にポップされます。3つの操作があり、ルーターはいずれか一つを選択します:
- PUSH — 入力LSRがパケットにラベルを追加する
- SWAP — 中継LSRが受信したラベルを新しいラベルに交換する
- POP — 出力LSRがラベルを取り除き、IPパケットを配送する
LDP(Label Distribution Protocol)はラベルの割り当てを自動的に処理します。ルーターはUDP 646マルチキャストでネイバーを検出し、ポート646でTCPセッションを確立してラベルとFECのバインディングを交換します。FEC(Forwarding Equivalence Class)は単なる宛先プレフィックスです。LDPはIGPルーティングテーブルを基盤としているため、LDPが機能するにはOSPF(またはIS-IS)が動作して収束している必要があります。
3台構成のラボトポロジー
エンドツーエンドで構築・検証するトポロジーを以下に示します:
PC1 --- R1 (入力LSR) --- R2 (中継LSR) --- R3 (出力LSR) --- PC2
Lo: 1.1.1.1/32 Lo: 2.2.2.2/32 Lo: 3.3.3.3/32
10.0.12.1/30 10.0.12.2/30
10.0.23.1/30 10.0.23.2/30
3台のルーター全体のFRR設定
R1 — 入力LSR:
frr version 9.1
hostname R1
!
interface eth0
ip address 10.0.12.1/30
!
interface lo0
ip address 1.1.1.1/32
!
router ospf
ospf router-id 1.1.1.1
network 1.1.1.1/32 area 0
network 10.0.12.0/30 area 0
!
mpls ldp
router-id 1.1.1.1
!
address-family ipv4
discovery transport-address 1.1.1.1
!
interface eth0
!
!
R2 — 中継LSR:
frr version 9.1
hostname R2
!
interface eth0
ip address 10.0.12.2/30
!
interface eth1
ip address 10.0.23.1/30
!
interface lo0
ip address 2.2.2.2/32
!
router ospf
ospf router-id 2.2.2.2
network 2.2.2.2/32 area 0
network 10.0.12.0/30 area 0
network 10.0.23.0/30 area 0
!
mpls ldp
router-id 2.2.2.2
!
address-family ipv4
discovery transport-address 2.2.2.2
!
interface eth0
interface eth1
!
!
R3 — 出力LSR:
frr version 9.1
hostname R3
!
interface eth0
ip address 10.0.23.2/30
!
interface lo0
ip address 3.3.3.3/32
!
router ospf
ospf router-id 3.3.3.3
network 3.3.3.3/32 area 0
network 10.0.23.0/30 area 0
!
mpls ldp
router-id 3.3.3.3
!
address-family ipv4
discovery transport-address 3.3.3.3
!
interface eth0
!
!
応用:ラベルスイッチングパスの検証
設定は基本中の基本です。データプレーンでラベルが実際にプッシュ、スワップ、ポップされているかをエンドツーエンドで検証する方法を紹介します。
LDPネイバーの状態確認
vtysh -c "show mpls ldp neighbor"
AF ID State Remote Address Uptime
ipv4 2.2.2.2 OPERATIONAL 2.2.2.2 00:08:41
ipv4 3.3.3.3 OPERATIONAL 3.3.3.3 00:08:39
両ネイバーがOPERATIONALであれば、LDPセッションが確立され、ラベルバインディングが交換済みであることを確認できます。
ラベル情報ベース(LIB)の確認
vtysh -c "show mpls ldp binding"
AF Destination Nexthop Local Label Remote Label In Use
ipv4 1.1.1.1/32 10.0.12.1 imp-null 16 yes
ipv4 2.2.2.2/32 - 16 imp-null yes
ipv4 3.3.3.3/32 10.0.23.2 17 16 yes
imp-nullエントリはPHP(Penultimate Hop Popping:最終手前ホップでのポップ)を示しています——出力ルーターの手前のルーターがラベルをスワップする代わりにポップします。これはデフォルトの動作であり、完全に正常です。
カーネルレベルのMPLSフォワーディングテーブルの確認
# FRRの視点
vtysh -c "show mpls table"
# Linuxカーネルの視点
ip -f mpls route show
tcpdumpでラベル付きパケットをキャプチャする
# R2のトランジットインターフェースで、リアルタイムにラベルスワップを監視する
tcpdump -i eth0 -n -e mpls
tcpdumpの出力にMPLSラベルが表示されれば、データプレーンが実際に機能していることがわかります。4バイトのラベルヘッダーはEthernetフレームとIPヘッダーの間に位置し、エンドポイントからは見えませんが、中継LSRが唯一気にする情報です。
エンドツーエンドの疎通確認
# R1からLSPを経由してR3のループバックにpingを送る
ping 3.3.3.3 -I 1.1.1.1
OSPFが収束し、LDPがバインディングを配布済みであれば、完全なラベルスイッチングパスを経由して通信が行われます。
実践的なヒント:実際の障害デバッグから得た教訓
1. カーネルモジュールはFRRより前にロードする必要がある
LDPセッションは確立されているのにフォワーディングテーブルにラベルが表示されない原因を追い続けて、かなりの時間を無駄にしました。原因はFRR起動前にmpls_routerがロードされていなかったことでした。必ず確認してください:
lsmod | grep mpls
2. MPLS入力はインターフェースごとに設定する — 新しいインターフェースを忘れずに
稼働中のルーターに新しいインターフェースを追加してnet.mpls.conf.<iface>.input=1を設定し忘れると、ラベル付きパケットがサイレントにドロップされます。エラーも警告も出ません。そのため、新しいインターフェースの作成時に自動でMPLSを有効化する小さなスクリプトを用意しています。
3. トランスポートアドレスはIGP経由で到達可能でなければならない
私の環境では常にループバックに設定しているdiscovery transport-addressは、OSPFにアドバタイズする必要があります。OSPFがループバックプレフィックスを再配信していない場合、LDPはHelloパケットを送信しても、ラベル交換のためのTCPセッションが確立されません。LDPネイバーがINITIALIZED状態のままの場合はまずOSPFを確認してください。
4. ホームラボのテストにはネットワーク名前空間を使う
3台の物理マシンや3台のVMは必要ありません。Linuxのネットワーク名前空間を使えば、1台のホスト上で分離されたFRRインスタンスを実行できます:
# 分離された名前空間を作成
ip netns add R1
ip netns add R2
ip netns add R3
# R1とR2の間にvethペアを作成
ip link add r1-eth0 netns R1 type veth peer name r2-eth0 netns R2
# 各名前空間内にアドレスを割り当て
ip netns exec R1 ip addr add 10.0.12.1/30 dev r1-eth0
ip netns exec R1 ip link set r1-eth0 up
ip netns exec R2 ip addr add 10.0.12.2/30 dev r2-eth0
ip netns exec R2 ip link set r2-eth0 up
# 名前空間内でMPLSを有効化
ip netns exec R1 sysctl -w net.mpls.conf.r1-eth0.input=1
ip netns exec R1 sysctl -w net.mpls.platform_labels=100000
各名前空間はそれぞれ独自のFRR設定ディレクトリとデーモンセットを持ちます。削除はip netns del R1だけで完了します。実際のトラフィックが流れる環境に触れる前に、MPLSの設定はすべてこの方法でテストしています。
5. 問題発生時はLDPセッションネゴシエーションをデバッグする
# vtysh内でLDPデバッグ出力を有効化
debug mpls ldp
debug mpls ldp discovery
debug mpls ldp messages recv
debug mpls ldp messages sent
# FRRのログをリアルタイムで監視し、LDPイベントをフィルタリング
tail -f /var/log/frr/frr.log | grep -i ldp
最も一般的な障害の原因は、トランスポートアドレスへの到達不可能とルーターIDの不一致です。デバッグ出力を見れば、どちらも数秒以内に明らかになります。
この基礎が固まれば、次の明確な課題はMPLS L3VPNです:MP-BGPがPEルーター間でVPNv4ルートを伝達し、LDPがその下でトランスポートラベルを提供します。これがサービスプロバイダーが共有物理インフラ上で顧客トラフィックを分離する仕組みです。より大きなテーマですが、このラボはまさにその前提条件となります。

