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

MPLSのQoS(EXPとuniform / pipe / short-pipe)

目次

MPLSのQoS(EXPとuniform / pipe / short-pipe)

MPLSのラベルには3ビットのEXPフィールドがあり、ラベルを付けたルータが優先度を書き込みます。IPのDSCPとは別の値で、ラベルが付いている区間だけ意味を持ちます。事業者はEXPで自網のQoSを決め、顧客のDSCPには触れない、といった使い分けができます。この記事ではEXPの位置と既定の動作、入口PEと途中のPルータでの書き換え、そして出口PEの3つの振る舞い(uniform / pipe / short-pipe)を解説し、IOS XR(XRv9000)のラボでキャプチャーを取って確かめます。

ラベルの構造とPHPはMPLSのラベルとラベルスタック、L3VPNのラベル2段構成はMPLSのラベル操作(push / swap / pop)で解説しています。

EXPの3ビット

ラベルはパケットに4バイト(32ビット)のラベルスタックエントリとして付き、その内訳はLabel(ラベル値)20ビット、EXP 3ビット、S(Bottom of Stack)1ビット、TTL 8ビットです。

このフィールドはRFC 3032でEXP(Experimental Use、実験用)として定められ、RFC 5462でTC(Traffic Class)に改名されました。ビット数も位置も変わっていません。IOS XRの設定(set mpls experimental)もshowの列(Exp)も、Wiresharkの表示(MPLS Experimental Bits)も今はEXPなので、この記事ではEXPと呼びます。

値の意味は規格では決まっていません。0〜7のどれをどのサービスに割り当てるかは事業者が決めます。何も設定しない場合、IPのprecedence(DSCPの上位3ビット)がEXPに写ります。DSCP 46(EF)はprecedence 5なのでEXP 5、DSCP 24(CS3)はEXP 3になります(この記事の検証機であるXRv9000 26.1.1と、CEに使ったXRd 26.1.1で観測した動作です)。

imposition と topmost

IOS XRでEXPを書き込むコマンドは2つあり、対象が違います。

コマンド対象使う場所
set mpls experimental imposition <0-7>これから付けるラベル全部入口PEの、顧客側インタフェースの入力
set mpls experimental topmost <0-7>いちばん外側のラベル1枚ラベルが付いた後。コア側インタフェースの出力や、Pルータの入力

L3VPNではラベルが2段(外側がLDP、内側がVPN)になるため、この違いがそのまま結果に出ます。impositionは2段とも同じ値になり、topmostは外側だけが変わります。PHPで外側が外れると、topmostで書いた値は消え、内側の値が見えます。

出口PEの3つのモード

RFC 3270は、MPLSでDiffServを運ぶときのトンネルの振る舞いを3つに分けています。違いは出口PEが何を見てキューを選ぶかと、顧客のDSCPを書き換えるかの2点です。

モードRFCの節出口PEが見るもの顧客のDSCP
uniform2.6.3節(MAY)ラベルのEXPEXPに合わせて書き換える
pipe2.6.2節(MUST)ラベルのEXP変えない
short-pipe2.6.2.1節(MAY)顧客のDSCP変えない

uniformは網の中の扱いを顧客側にも反映させる形、pipeは網の中だけで完結させる形、short-pipeは出口では顧客の値に従う形です。IOS XRはモードを名前で指定するのではなく、policy-mapの書き方でどれになるかが決まります。今回の検証では、EXPをqos-groupに写して出力でset dscpすればuniform、qos-groupでキューを選ぶだけならpipe、出力でmatch dscpを使えばshort-pipeの動きになりました。

uniform / pipe / short-pipe の違い

検証構成

CE1 - PE1 - P1 - PE2 - CE2の5台です。コアはOSPF + LDP、PE間はiBGP vpnv4でVRF CUST-Aを通し、CEとPEはeBGPでつなぎます。CE1からCE2へのパケットはPE1でラベルが2段付き、P1がPHPで外側を外すので、P1 - PE2間は1段になります。

検証構成

PE1 / P1 / PE2はXRv9000、CE1 / CE2はXRdです。XRd(Control Plane)ではservice-policyがデータプレーンに入らないため、QoSの検証にはXRv9000を使っています。CE1からはtypeオプションでToSを変えたpingを送り、DSCP 0 / 24 / 46の3種類で結果を比べます。

検証の全体像

STEP操作確かめること
0QoSの設定なし既定でIP precedenceがEXPに写ること
1PE1でラベルにEXP 5を付ける(imposition)DSCPに関係なく2段ともEXP 5になること
2コア側の出力で外側だけEXP 6にする(topmost)外側だけ変わり、PHPの後は内側の値が見えること
3PルータでEXPを付け替える(qos-group経由)P1 - PE2間のEXPが2になること
4出口PEでEXPをDSCPに反映する(uniform)PE2 - CE2間のDSCPが書き換わること
5出口PEでEXPを使ってキューを選ぶ(pipe)DSCPが変わらず、EXPでキューが決まること
6出口PEで顧客のDSCPでキューを選ぶ(short-pipe)DSCPが変わらず、顧客の値でキューが決まること

既定の動作(STEP 0)

QoSを何も設定していない状態です。CE1からCE2へのtracerouteに、ラベル2段とExp 0が出ています。

STEP 0 CE1 traceroute 192.168.2.1
RP/0/RP0/CPU0:CE1#traceroute 192.168.2.1 source 192.168.1.1 timeout 1 probe 2 maxttl 5
Sun Oct  4 10:36:53.929 UTC

Type escape sequence to abort.
Tracing the route to 192.168.2.1

 1  10.11.101.11 71 msec  15 msec
 2  10.1.11.1 [MPLS: Labels 24001/24003 Exp 0] 88 msec  30 msec
 3  10.1.22.22 [MPLS: Label 24003 Exp 0] 70 msec  30 msec
 4  10.22.102.102 23 msec  *

DSCP 46を付けたpingでは、ラベルのEXPが5になります。PE1 - P1間のキャプチャーのNo.172です。

STEP 0 No.172 ICMP Echo request(PE1 → P1、tshark -V 抜粋)
MultiProtocol Label Switching Header, Label: 24001, Exp: 5, S: 0, TTL: 254
    0000 0101 1101 1100 0001 .... .... .... = MPLS Label: 24001 (0x05dc1)
    .... .... .... .... .... 101. .... .... = MPLS Experimental Bits: 5
    .... .... .... .... .... ...0 .... .... = MPLS Bottom Of Label Stack: 0
    .... .... .... .... .... .... 1111 1110 = MPLS TTL: 254
MultiProtocol Label Switching Header, Label: 24003, Exp: 5, S: 1, TTL: 254
    0000 0101 1101 1100 0011 .... .... .... = MPLS Label: 24003 (0x05dc3)
    .... .... .... .... .... 101. .... .... = MPLS Experimental Bits: 5
    .... .... .... .... .... ...1 .... .... = MPLS Bottom Of Label Stack: 1
    .... .... .... .... .... .... 1111 1110 = MPLS TTL: 254
上のtshark出力のパケット(No.172)のpcapをダウンロード

DSCP 0はEXP 0、DSCP 24はEXP 3でした。precedenceがそのまま写っています。IPのDSCPはどの区間でも変わりません。

入口PEでEXPを決める(STEP 1・2)

PE1の顧客側インタフェースの入力に、EXP 5を書き込むpolicy-mapを当てます。

STEP 1でPE1にcommitした設定
policy-map PE1-CE-IN
 class class-default
  set mpls experimental imposition 5
 !
 end-policy-map
!
interface GigabitEthernet0/0/0/0
 service-policy input PE1-CE-IN
!

DSCP 0のパケットでも、ラベルは2段ともEXP 5になりました。DSCPは0のままです。

STEP 1 No.144 ICMP Echo request(PE1 → P1、tshark -V 抜粋)
MultiProtocol Label Switching Header, Label: 24001, Exp: 5, S: 0, TTL: 254
    0000 0101 1101 1100 0001 .... .... .... = MPLS Label: 24001 (0x05dc1)
    .... .... .... .... .... 101. .... .... = MPLS Experimental Bits: 5
    .... .... .... .... .... ...0 .... .... = MPLS Bottom Of Label Stack: 0
    .... .... .... .... .... .... 1111 1110 = MPLS TTL: 254
MultiProtocol Label Switching Header, Label: 24003, Exp: 5, S: 1, TTL: 254
上のtshark出力のパケット(No.144)のpcapをダウンロード

STEP 2では、これに加えてコア側の出力にset mpls experimental topmost 6を当てました。PE1 - P1間は外側が6、内側は5です。

STEP 2 No.142 ICMP Echo request(PE1 → P1、tshark -V 抜粋)
MultiProtocol Label Switching Header, Label: 24001, Exp: 6, S: 0, TTL: 254
    0000 0101 1101 1100 0001 .... .... .... = MPLS Label: 24001 (0x05dc1)
    .... .... .... .... .... 110. .... .... = MPLS Experimental Bits: 6
    .... .... .... .... .... ...0 .... .... = MPLS Bottom Of Label Stack: 0
    .... .... .... .... .... .... 1111 1110 = MPLS TTL: 254
MultiProtocol Label Switching Header, Label: 24003, Exp: 5, S: 1, TTL: 254
上のtshark出力のパケット(No.142)のpcapをダウンロード

P1が外側を外した後のP1 - PE2間はEXP 5です。topmostで書いた6は、外側のラベルと一緒に消えます。

STEP 2 No.144 ICMP Echo request(P1 → PE2、tshark -V 抜粋)
MultiProtocol Label Switching Header, Label: 24003, Exp: 5, S: 1, TTL: 253
    0000 0101 1101 1100 0011 .... .... .... = MPLS Label: 24003 (0x05dc3)
    .... .... .... .... .... 101. .... .... = MPLS Experimental Bits: 5
    .... .... .... .... .... ...1 .... .... = MPLS Bottom Of Label Stack: 1
    .... .... .... .... .... .... 1111 1101 = MPLS TTL: 253
上のtshark出力のパケット(No.144)のpcapをダウンロード

PルータでEXPを付け替える(STEP 3)

途中のPルータでも書き換えられます。P1の入力でmatch mpls experimental topmost 5に一致したパケットをqos-group 5にし、出力でqos-group 5のパケットにset mpls experimental topmost 2を当てました。qos-groupはルータの中だけで使う印で、パケットには出ません。

P1 - PE2間のEXPは2になりました。PHPで外側を外した後に残ったVPNラベルに対して、出力のpolicyが効いています。

STEP 3 No.173 ICMP Echo request(P1 → PE2、tshark -V 抜粋)
MultiProtocol Label Switching Header, Label: 24003, Exp: 2, S: 1, TTL: 253
    0000 0101 1101 1100 0011 .... .... .... = MPLS Label: 24003 (0x05dc3)
    .... .... .... .... .... 010. .... .... = MPLS Experimental Bits: 2
    .... .... .... .... .... ...1 .... .... = MPLS Bottom Of Label Stack: 1
    .... .... .... .... .... .... 1111 1101 = MPLS TTL: 253
上のtshark出力のパケット(No.173)のpcapをダウンロード

出口PEの3モード(STEP 4・5・6)

STEP 4から6は、入口PEのimposition 5をそのままに、出口PE2の設定だけを入れ替えます。

uniform:EXPをDSCPに反映する(STEP 4)

PE2のコア側入力でmatch mpls experimental topmost 5をqos-group 5に写し、CE側の出力でqos-group 5にset dscp cs5を当てます。PE2 - CE2間に出たパケットは、元のDSCPが0でも24でも46でも、すべてDSCP 40(CS5)になりました。

STEP 4 No.15 ICMP Echo request(PE2 → CE2、tshark -V 抜粋)
    Differentiated Services Field: 0xa0 (DSCP: CS5, ECN: Not-ECT)
        1010 00.. = Differentiated Services Codepoint: Class Selector 5 (40)
        .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
    Total Length: 100
上のtshark出力のパケット(No.15)のpcapをダウンロード

pipe:EXPでキューを選び、DSCPは変えない(STEP 5)

CE側の出力を、親でshape average 300 kbps、子でqos-group 5のクラスにbandwidth remaining percent 80を割り当てる形に替えました。set dscpは書きません。

CE1からDSCP 46(ToS 184)とDSCP 0を各1000発、4秒ずらして同時に流すと、どちらも1000/1000で、RTTの平均はともに70ミリ秒でした。EXPで選ばれるキューが同じなので差が出ません。DSCPは46と0のまま届いています。

STEP 5 PE2 show policy-map interface GigabitEthernet0/0/0/1 output(抜粋)
GigabitEthernet0/0/0/1 output: PE2-CE-PIPE

Class class-default
  Classification statistics          (packets/bytes)     (rate - kbps)
    Matched             :                1999/2834582              301
    Transmitted         :                1999/2834582              301
    Total Dropped       :                   0/0                    0

  Policy PE2-CE-PIPE-CHILD Class QG5
    Classification statistics          (packets/bytes)     (rate - kbps)
      Matched             :                1999/2834582              301
      Transmitted         :                1999/2834582              301
      Total Dropped       :                   0/0                    0
    Queueing statistics
      Queue ID                             : 32
      High watermark                       : N/A
      Inst-queue-len                       : N/A
      Avg-queue-len                        : N/A
      Taildropped(packets/bytes)           : 0/0
      Queue(conform)      :                1999/2834582              301
      RED random drops(packets/bytes)      : 0/0


  Policy PE2-CE-PIPE-CHILD Class class-default
    Classification statistics          (packets/bytes)     (rate - kbps)
      Matched             :                   0/0                    0

2本の負荷(各1000発)がQG5のクラスに入り、shaperどおり約301 kbpsで出ています(採取の瞬間に1発が通過中で1999です)。子policyのclass-defaultは0のままで、EXPで選んだクラスだけを通っていることが分かります。

short-pipe:顧客のDSCPでキューを選ぶ(STEP 6)

コア側入力のpolicyを外し、CE側の出力をmatch dscp efのクラスにpriority level 1とpolice rate 100 kbpsを当てる形に替えました。クラス分けの基準が、事業者のEXPから顧客のDSCPに変わります。

同じ負荷をかけると、DSCP 46は667/1000でRTTの平均が9ミリ秒、DSCP 0は1000/1000で37ミリ秒でした。EFは優先キューに入るので遅延が小さく、100 kbpsを超えた分はpolicerが捨てています。

STEP 6 PE2 show policy-map interface GigabitEthernet0/0/0/1 output(抜粋)
GigabitEthernet0/0/0/1 output: PE2-CE-SHORTPIPE

Class class-default
  Classification statistics          (packets/bytes)     (rate - kbps)
    Matched             :                2000/2836000              30
    Transmitted         :                1667/2363806              21
    Total Dropped       :                 333/472194               9

  Policy PE2-CE-SHORTPIPE-CHILD Class EF
    Classification statistics          (packets/bytes)     (rate - kbps)
      Matched             :                1000/1418000              30
      Transmitted         :                 667/945806               21
      Total Dropped       :                 333/472194               9
    Policing statistics                (packets/bytes)     (rate - kbps)
      Policed(conform)    :                 667/945806               21
      Policed(exceed)     :                 333/472194               9

DSCPは書き換えられていません。PE2 - CE2間に出たパケットは46のままです。

STEP 6 No.6 ICMP Echo request(PE2 → CE2、tshark -V 抜粋)
    Differentiated Services Field: 0xb8 (DSCP: EF, ECN: Not-ECT)
        1011 10.. = Differentiated Services Codepoint: Expedited Forwarding (46)
        .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
    Total Length: 1400
上のtshark出力のパケット(No.6)のpcapをダウンロード

設計上の注意

  • impositionとtopmostを取り違えると、ラベルの段数によって結果が変わります。L3VPNのように2段になる構成では、入口で全部に付けたいのか、外側だけを変えたいのかを決めてからコマンドを選びます
  • 出口PEのクラス分けは、コア側と顧客側で使える条件が違います。コア側の入力はまだラベルが付いているのでmatch mpls experimental、顧客側の出力はラベルが外れているのでmatch dscpです。EXPを顧客側まで持ち込むには、qos-groupに写して渡します
  • show policy-map interfaceのカウンタは、そのインタフェースのpolicyに一致した分だけです。PE2が外したVPNラベルの転送量はshow mpls forwardingには出ない(Unlabelledの行は0のまま)ので、キャプチャーかshow interfaceで確認します

検証Configおよびshow結果

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

ファイル内容
..._clear.txtそのSTEPの採取前にクリアしたカウンタ(QoS、インタフェース、MPLS転送)
..._ping.txtクリアの後に流したping / traceroute
..._show.txtshow version / show interface / show ospf database / show policy-map interface / show mpls forwarding など(PE・Pは1台70コマンド)
..._log.txtそのSTEPの範囲だけに絞ったshow logging。クリアの記録もSTEP<N>-CLEAR:として残っています
..._run.txtそのSTEP時点のshow running-config
..._trace.txtshow mpls ldp trace peer(PE1 / P1 / PE2)
..._commit.cfgそのSTEPで実際にcommitされた設定(変更したルータのみ)
..._load_tos<値>.txtCE1からかけた負荷(1400バイト、10ミリ秒間隔)の結果。負荷をかけたSTEPのみ
..._pmap-before.txt / ..._pmap-after.txt負荷の直前と直後に取ったshow policy-map interface

..._show.txtのshow policy-map interfaceと..._pmap-after.txtでは数字が違います。 前者はカウンタをクリアした後に流した各STEPのping(数十発)だけが載り、後者は負荷(1000発や500発)が載ります。本文で引用しているのは、負荷の値が必要な箇所では..._pmap-after.txtです。

カウンタをクリアしてからpingを流し、その後にshowを取っているので、各STEPの数値はそのSTEPだけの結果です。

STEP 0:QoSの設定なし

ルータクリアpingshow出力syslogrunning-configtrace
CE1clearpingshowlogrun—
PE1clearpingshowlogruntrace
P1clearpingshowlogruntrace
PE2clearpingshowlogruntrace
CE2clearpingshowlogrun—

STEP 1:PE1でラベルにEXP 5を付ける(imposition)

ルータクリアpingshow出力syslogrunning-configtrace投入した設定
CE1clearpingshowlogrun——
PE1clearpingshowlogruntracecommit
P1clearpingshowlogruntrace—
PE2clearpingshowlogruntrace—
CE2clearpingshowlogrun——

STEP 2:コア側の出力で外側だけEXP 6にする(topmost)

ルータクリアpingshow出力syslogrunning-configtrace投入した設定
CE1clearpingshowlogrun——
PE1clearpingshowlogruntracecommit
P1clearpingshowlogruntrace—
PE2clearpingshowlogruntrace—
CE2clearpingshowlogrun——

STEP 3:PルータでEXPを付け替える(qos-group経由)

ルータクリアpingshow出力syslogrunning-configtrace投入した設定
CE1clearpingshowlogrun——
PE1clearpingshowlogruntracecommit
P1clearpingshowlogruntracecommit
PE2clearpingshowlogruntrace—
CE2clearpingshowlogrun——

STEP 4:出口PEでEXPをDSCPに反映する(uniform)

ルータクリアpingshow出力syslogrunning-configtrace投入した設定
CE1clearpingshowlogrun——
PE1clearpingshowlogruntrace—
P1clearpingshowlogruntracecommit
PE2clearpingshowlogruntracecommit
CE2clearpingshowlogrun——

STEP 5:出口PEでEXPを使ってキューを選ぶ(pipe)

ルータクリアpingshow出力syslogrunning-configtrace投入した設定負荷前のpolicy-map負荷後のpolicy-map
CE1clearpingshowlogrun————
PE1clearpingshowlogruntrace———
P1clearpingshowlogruntrace———
PE2clearpingshowlogruntracecommitbeforeafter
CE2clearpingshowlogrun————

STEP 6:出口PEで顧客のDSCPでキューを選ぶ(short-pipe、最終状態)(最終状態)

ルータクリアpingshow出力syslogrunning-configtrace投入した設定負荷前のpolicy-map負荷後のpolicy-map
CE1clearpingshowlogrun————
PE1clearpingshowlogruntrace———
P1clearpingshowlogruntrace———
PE2clearpingshowlogruntracecommitbeforeafter
CE2clearpingshowlogrun————

CE1からかけた負荷(ping ... size 1400 interval 10)の記録です。負荷の直後のpolicy-mapは上の表の「負荷後のpolicy-map」です。

STEPToS結果ファイル
501000/1000、RTT 11/70/125 msload
51841000/1000、RTT 14/70/125 msload
601000/1000、RTT 7/37/95 msload
6184667/1000、RTT 6/9/69 msload

パケットキャプチャーはSTEPごとに4リンクで取得しています。

STEPCE1-PE1間PE1-P1間P1-PE2間PE2-CE2間
0pcappcappcappcap
1pcappcappcappcap
2pcappcappcappcap
3pcappcappcappcap
4pcappcappcappcap
5pcappcappcappcap
6pcappcappcappcap

参考

参考内容
RFC 3270MPLS Support of Differentiated Services。pipe(2.6.2節)、short-pipe(2.6.2.1節)、uniform(2.6.3節)
RFC 5462EXPフィールドをTrafficClass(TC)に改名。ビット数と位置は変更なし
検証環境XRv9000 26.1.1(PE1 / P1 / PE2)、XRd 26.1.1(CE1 / CE2)、Cisco Modeling Labs

関連記事