Junosで始めるMPLS入門 その1 Static LSP編
これから何回かに分けてJunosのMPLSで遊んでみようと思います。
特に面白いネタがあるわけでもありませんが、最近MPLSをベースにした技術ネタについて話す機会が多くなったので、基礎から一通りまとめてみます。
最終的には、MPLS-EVPNやSegment Routing(動けば)なども扱う予定です。
MPLS とは
RFC読んでください。
ラベル情報を元にパケットを転送する技術です。
昔はIPベースのルーティングより高速と言われていましたが、ルータの性能も飛躍的に向上したので、パトリシアツリーの検索を行うIPルーティングと比較しても速度的には大差はありません。
現在のMPLSは、ラベルをスタックすることで実現可能なIP-VPNサービスや、FRR、トラフィックエンジニアリングなどの運用面での利用が主流です。
ラベル構造
”SHIM Header” でググってください。
32bitの固定長の空間に20bitのlabel valueとlabel stackのための情報などが入っています。
MPLSの基本動作
MPLSのラベルオペレーションには基本的に以下の3つの操作しかありません。
- Push
- ラベルをパケットの先頭に追加する操作
- ラベルは複数追加することが可能です(ラベルスタック)
- Pop
- パケットの先頭からラベルを削除する操作
- 複数ラベルがスタックされている場合、下のラベルは削除されません
- Swap
- 先頭のラベルを新しいラベルで置き換える操作
- パケットを中継するルータで必要な動作です
付ける、剥がす、置き換えるです。
SwapとPushを同時に行うこともあります。
この3つの動作を組み合わせて、IP-VPNや高度なトラフィックエンジニアリングを実現しています。
MPLSは上記のラベルの操作と転送は実施しますが、ラベル情報そのものの交換や割り当ては行わないので、動的にラベル情報を通知・要求するプロトコルや、手動設定でラベル情報を交換する必要があります。
ラベルとIPアドレスの決定的な違い
ルーティングに使用するIPアドレスと、MPLSで使用するラベルの役割の大きな違いは以下です。
MPLSがかつて高速な処理といわれていたのにも上記の違いが大きく影響しています。
ラボ環境
実際に小規模なラボを作って動作を見ていきます。
- Server
- Ubuntu 16.04 LTS
- Router
- Juniper vMX 17.1 KVM
- logical-systemで論理ルータを切り出し、logical-tunnnelで接続します
- 入手・設定方法はブログ等で散々書かれていますのでググってください
- Juniper vMX 17.1 KVM
構成図
日本国内の拠点を以下のように接続したトポロジを考えます。
※実在する組織や拠点とは一切関係ありません 。
ほかの検証で利用した構成を流用したので、あまりイケてないですが今回はこれでやります。
事前準備
logical-system の設定
各拠点分のルータをlogical-systemで作成します。
ls間はlogical tunnel(lt)で接続します。
余談ですが、logical-systemでは以下のコマンドで各論理ルータにログインすることができます。
コマンドを打つ度にlogical-systemの指定をしなくてよくなります。
root@lab-vmx01> set cli logical-system Fukuoka Logical system: Fukuoka root@lab-vmx01:Fukuoka> root@lab-vmx01:Fukuoka> clear cli logical-system Cleared default logical system root@lab-vmx01>
IGPの設定
宛先Prefixをラベル情報にマッピングする場合、予め経路情報をIGPで収束しておく必要があるため、各ルータでOSPFを有効にします。
root@lab-vmx01:Fukuoka> show configuration protocols ospf area 0.0.0.0 { interface all; }
Static LSPによる制御
先ずはLDPなどを使わずに、ラベルを手動で割り当てて制御してみます。
これは 非常に面倒でミスをしやすい やり方なので通常運用ではあまり行いません。
LSPは一方向のパスなので、行きと戻りで2本作ります。
ここではFukuokaからToyosuへのパスを考えます。
双方向のパスが違う経路を通るようにします。
Fukuoka→Toyosu 方向
Fukuokaのloopback 10.255.255.9からToyosuのloopback 10.255.255.6への経路をstatic LSPで設定します。
Fukuoka→Nagoya→Dojima→Otemachi→Shibuya→Toyosu の順に通します。
行きのパス
Fukuoka→Toyosu 方向のラベル操作は以下の順で実施します。
1. Fukuokaでラベル1000001をpush,Nagoyaへ転送
2. Nagoyaでラベル1000001を1000002にswap,Dojimaへ転送
3. Dojimaでラベル1000002を1000003にswap,Otemachiへ転送
4. Otemachiでラベル1000003を1000004にswap,Shibuyaへ転送
5. Shibuyaでラベル1000004を0にswap=pop(PHP),Toyosuへ転送
6. ラベルが剝がされたパケットがToyosuに到達
ingress LSRとなるFukuokaで、ラベル1000001をパケットにpushします。
Toyosu向けのstatic lspを定義し、ネクストホップをNagoyaに向けます。
また、宛先となるToyosuのloopbackをMPLSのルーティングテーブルであるinet.3にインストールします。
root@lab-vmx01:Fukuoka> show configuration protocols mpls static-label-switched-path to_Toyosu { ingress { install 10.255.255.6/32; next-hop 10.0.0.26; to 10.0.0.17; push 1000001; } } interface all;
宛先のstatic routeをlspに向けます。
root@lab-vmx01:Fukuoka> show configuration routing-options static { route 10.255.255.6/32 { static-lsp-next-hop to_Toyosu; } }
設定どおり1000001をpushする動作になっていることがわかります。
root@lab-vmx01:Fukuoka> show route table inet.0 protocol static inet.0: 26 destinations, 27 routes (26 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 10.255.255.6/32 *[Static/5] 04:54:46 > to 10.0.0.26 via lt-0/0/0.27, Push 1000001 root@lab-vmx01:Fukuoka> show route table inet.3 inet.3: 2 destinations, 2 routes (2 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 10.0.0.17/32 *[MPLS/6/1] 02:01:11, metric 0 > to 10.0.0.26 via lt-0/0/0.27, Push 1000001 10.255.255.6/32 *[MPLS/6/1] 02:01:11, metric 0 > to 10.0.0.26 via lt-0/0/0.27, Push 1000001
Nagoya,Dojima,OtemachiはTransit LSRとなります。
つまり中継ルータです。swapを行い、PushやPopは行いません。
ここでは一つ前のLSRがswap(push)してきたラベルを判別し、新しいラベルにswapしています。
例えば、DojimaではNagoyaがswapした1000002というラベルを受け取ったら新しく1000003というラベルにswapするという設定をしています。
root@lab-vmx01:Nagoya> show configuration protocols mpls static-label-switched-path to_Toyosu { transit 1000001 { next-hop 10.0.0.22; swap 1000002; } } interface all; root@lab-vmx01:Dojima> show configuration protocols mpls static-label-switched-path to_Toyosu { transit 1000002 { next-hop 10.0.0.0; swap 1000003; } } interface all; root@lab-vmx01:Otemachi> show configuration protocols mpls static-label-switched-path to_Toyosu { transit 1000003 { next-hop 10.0.0.3; swap 1000004; } } interface all;
root@lab-vmx01:Dojima> show route table mpls.0 mpls.0: 5 destinations, 5 routes (5 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 0 *[MPLS/0] 07:05:17, metric 1 Receive 1 *[MPLS/0] 07:05:17, metric 1 Receive 2 *[MPLS/0] 07:05:17, metric 1 Receive 13 *[MPLS/0] 07:05:17, metric 1 Receive 1000002 *[MPLS/6] 02:34:18, metric 1 > to 10.0.0.0 via lt-0/0/0.1, Swap 1000003
以上が、transit LSRの設定になります。
Shibuyaは少し特殊な設定をします。
ShibuyaもToyosu向けの中継ルータであることには変わりありませんが、Toyosuの一つ前、つまり最後から二番目(Penultimate)のホップに位置するルータですので、ここでラベルをswapする意味がありません。
ラベルをここでpopしてネクストホップへ転送しても、次は宛先のToyosuなので問題ないはずです。
なのでここではラベルをpopする設定を入れます。
これが Penultimate Hop Popping(PHP) という動作です。
LDPなどを有効にしている場合、JunosはこのPHPをデフォルトで実行します。
root@lab-vmx01:Shibuya> show configuration protocols mpls static-label-switched-path to_Toyosu { transit 1000004 { next-hop 10.0.0.17; swap 0; } }
popという明示的な設定もありますが、ここではラベル0にswapしています。
このラベル0は特殊なラベルで受信時にラベルをpopしIPパケットとして転送することを意味します。
1000004を受信したときの動作がS=0 Popとなっていることがわかります。
root@lab-vmx01:Shibuya:> show route table mpls.0 mpls.0: 6 destinations, 6 routes (6 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 0 *[MPLS/0] 07:07:32, metric 1 Receive 1 *[MPLS/0] 07:07:32, metric 1 Receive 2 *[MPLS/0] 07:07:32, metric 1 Receive 13 *[MPLS/0] 07:07:32, metric 1 Receive 1000004 *[MPLS/6] 02:31:45, metric 1 > to 10.0.0.17 via lt-0/0/0.16, Swap 0 1000004(S=0) *[MPLS/6] 02:31:45, metric 1 > to 10.0.0.17 via lt-0/0/0.16, Pop
Toyosu→Fukuoka 方向
Toyosu→Shinagawa→Ikebukuro→Shinsaibasi→Fukuoka の順に通します。
戻りのパス
上記と同様の設定を戻りの経路にするだけです。
Toyosu→Fukuoka 方向のラベル操作は以下の順で実施します。
1. Toyosuでラベル1000101をpush,Shinagawaへ転送
2. Shinagawaでラベル1000101を1000102にswap,Ikebukuroへ転送
3. Ikebukuroでラベル1000102を1000103にswap,Shinsaibashiへ転送
4. Shinsaibashiでラベル1000103を0にswap=pop(PHP),Fukuokaへ転送
5. ラベルが剝がされたパケットがFukuokaに到達
確認
双方向で明示的に指定したパスで到達していることが確認できます。
traceroute: Fukuoka → Toyosu
root@lab-vmx01:Fukuoka> traceroute 10.255.255.6 source 10.255.255.9 traceroute to 10.255.255.6 (10.255.255.6) from 10.255.255.9, 30 hops max, 48 byte packets 1 10.0.0.26 (10.0.0.26) 0.793 ms 0.523 ms 0.420 ms MPLS Label=1000001 CoS=0 TTL=1 S=1 2 10.0.0.22 (10.0.0.22) 0.406 ms 0.357 ms 0.373 ms MPLS Label=1000002 CoS=0 TTL=1 S=1 3 10.0.0.0 (10.0.0.0) 0.373 ms 0.388 ms 0.395 ms MPLS Label=1000003 CoS=0 TTL=1 S=1 4 10.0.0.3 (10.0.0.3) 0.416 ms 0.396 ms 0.432 ms MPLS Label=1000004 CoS=0 TTL=1 S=1 5 10.255.255.6 (10.255.255.6) 0.465 ms 0.393 ms 0.383 ms
traceroute: Toyosu → Fukuoka
root@lab-vmx01:Toyosu> traceroute 10.255.255.9 source 10.255.255.6 traceroute to 10.255.255.9 (10.255.255.9) from 10.255.255.6, 30 hops max, 48 byte packets 1 10.0.0.21 (10.0.0.21) 0.915 ms 0.605 ms 0.365 ms MPLS Label=1000101 CoS=0 TTL=1 S=1 2 10.0.0.18 (10.0.0.18) 0.381 ms 0.384 ms 0.401 ms MPLS Label=1000102 CoS=0 TTL=1 S=1 3 10.0.0.8 (10.0.0.8) 0.424 ms 0.368 ms 0.368 ms MPLS Label=1000103 CoS=0 TTL=1 S=1 4 10.255.255.9 (10.255.255.9) 0.359 ms 0.353 ms 0.372 ms
LSPを用いない場合、単純にIGPであるOSPFの最小メトリックがベストパスになります。
特殊なラベル
一部のラベル(0-15)は予約ラベルといって用途が決まっています。
よく使うのは以下の4つなので覚えておくと便利です。
- 0: IPv4 Explicit Null label
- 1: Router Alert label
- 2: IPv6 Explicit Null label
- 3: Implicit Null label
まとめ
今回はMPLSの基本動作をみるために手動でラベル設定を行いました。
上記のように手動でラベル操作を設定することも可能ですが、あまりにも手間がかかるので通常はLDPやRSVPを用いてシグナリングすることが多いです。
運用上どうしても手動でパスを設定する必要がある場合以外は動的な設定を推奨します。