COGNITIVE

Networking

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 ラベル
    • そのルータとリンクでのみユニークであれば良い
  • IPアドレス
    • そのネットワーク全体(ドメイン)でユニークである必要がある

MPLSがかつて高速な処理といわれていたのにも上記の違いが大きく影響しています。

ラボ環境

実際に小規模なラボを作って動作を見ていきます。

  • Server
  • Router
    • Juniper vMX 17.1 KVM
      • logical-systemで論理ルータを切り出し、logical-tunnnelで接続します
      • 入手・設定方法はブログ等で散々書かれていますのでググってください

構成図

日本国内の拠点を以下のように接続したトポロジを考えます。
※実在する組織や拠点とは一切関係ありません 。
f:id:cognify:20170504232338j:plain
ほかの検証で利用した構成を流用したので、あまりイケてないですが今回はこれでやります。

事前準備

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 の順に通します。

行きのパス

f:id:cognify:20170504232411j:plain

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 の順に通します。

戻りのパス

f:id:cognify:20170504232604j:plain 上記と同様の設定を戻りの経路にするだけです。

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

f:id:cognify:20170505062703j:plain

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

f:id:cognify:20170505062722j:plain

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を用いてシグナリングすることが多いです。
運用上どうしても手動でパスを設定する必要がある場合以外は動的な設定を推奨します。

次回からLDP/RSVPを用いた動的な設定や、トラフィックエンジニアリングについて書いていきたいと思います。