【実務・中級編】 L2(CoS)とL3(DSCP)のQoSマッピング設計 – インフラ・物理&L2/L3ネットワーク基礎実践ガイド

こんにちは、ネットワークの深淵へようこそ。主筆のエンジニアです。

皆さんは、Webアプリのレスポンスが「なぜか時々遅れる」という事象に直面したとき、どこを疑いますか?コードの最適化、DBのインデックス、あるいはクラウドのインスタンスサイズ……。もちろんそれらは重要ですが、パケットが物理的な導線を流れる際、スイッチやルーターのバッファで「順番待ち」を強いられている現実に目を向けるエンジニアは、意外と少ないものです。

今日は、インフラの品質を支える「QoS(Quality of Service)」、その中でも最も泥臭く、かつ重要なL2(CoS)とL3(DSCP)のマッピング設計について、パケットの鼓動を感じながら解説していきましょう。

—

1. なぜ「マッピング」が必要なのか?

結論から言えば、「レイヤーによって見える景色が違うから」です。

パケットが社内LANのスイッチを駆け抜け、ルーターを越えて広域ネットワークへ旅立つとき、その優先度を伝える「ラベル」は形を変えます。

  • L2のCoS (Class of Service): EthernetフレームのVLANタグ(802.1Q)内にある3ビットの領域(PCP: Priority Code Point)。
  • L3のDSCP (Differentiated Services Code Point): IPヘッダー内の6ビットの領域。

L2スイッチはIPヘッダーの中身を見ずに、VLANタグの3ビットだけを見て「これは音声パケットだから先に通そう」と判断します。しかし、ルーターがVLANタグを剥ぎ取ってルーティングを行う際、その「優先度情報」はIPヘッダーのDSCPに引き継がれていなければ、次のネットワークでパケットはただの「平民」に成り下がってしまいます。

この「情報のバトンタッチ」こそが、QoSマッピング設計の正体です。

—

2. 規格の構造を解剖する

Layer 2: 802.1p (PCP)

VLANタグの中には3ビットの優先度フィールドがあります。3ビットということは、0 から 7 までの8段階しか表現できません。

  • 0: Best Effort(標準)
  • 5: Voice(音声)
  • 7: Network Control(制御信号)

Layer 3: DSCP (RFC 2474)

IPヘッダーの「Type of Service (ToS)」フィールドを拡張したのがDSCPです。こちらは6ビット。つまり 0 から 63 までの64段階の細かな制御が可能です。

現場でよく使われるのは以下の値です:

  • CS0 (0): デフォルト
  • AFxx (Assured Forwarding): 業務アプリ用。AF31(26)など。
  • EF (Expedited Forwarding, 46): 音声などのリアルタイム通信用。最優先。

—

3. 実践:マッピング設計の標準モデル

64段階(DSCP)を8段階(CoS)に凝縮する際、デファクトスタンダードとなっている設計例を紹介します。RFC 4594(QoS構築のガイドライン)をベースにした、現場で「これなら間違いない」と言われる設定値です。

| サービス種別 | DSCP値 (名前) | DSCP値 (10進数) | L2 CoS (PCP) |
| :— | :— | :— | :— |
| 音声 (VoIP) | EF | 46 | 5 |
| ビデオ会議 | AF41 | 34 | 4 |
| 基幹業務アプリ | AF31 | 26 | 3 |
| 低優先データ | CS1 | 8 | 1 |
| デフォルト | DF (CS0) | 0 | 0 |

—

4. インフラ設定の実際(Cisco IOS-XEの例)

スイッチの入り口でDSCP値を信頼し、それを内部的にCoSへマッピングする設定を見てみましょう。これを怠ると、スイッチはすべてのパケットを「優先度0」として扱い、高負荷時に音声パケットを容赦なくドロップします。

# クラスマップの定義(どのパケットを特定するか)
class-map match-any VOICE_TRAFFIC
  match dscp ef

# ポリシーマップの定義(どう処理するか)
policy-map QOS_POLICY_IN
  class VOICE_TRAFFIC
    set cos 5  # DSCP 46(EF) を L2 CoS 5 に書き換えてバトンタッチ

# インターフェースへの適用
interface GigabitEthernet1/0/1
  description TRUST_BOUNDARY_PORT
  service-policy input QOS_POLICY_IN
  # 受信したDSCP値を信頼する設定
  qos trust dscp

—

5. アプリケーション層からのアプローチ

「インフラの設定なんて触れないよ」というWeb API開発者の皆さんも無関係ではありません。実は、プログラム側からパケットにDSCP値をマーキングすることが可能です。

Pythonでの実装例(Socket)

Pythonの socket ライブラリを使用して、送信するIPパケットのToSフィールド(DSCP含む)を直接指定できます。

import socket

# 送信先設定
dest_ip = "192.168.1.100"
dest_port = 8080

# ソケット作成
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# DSCP値を設定する。
# DSCP EF(46) を設定する場合、ToSフィールドは左に2ビットシフトさせる必要がある (RFC 2474)
# 46 << 2 = 184
dscp_ef = 46
tos_value = dscp_ef << 2

# IPヘッダーのToSフィールドに値をセット
sock.setsockopt(socket.IPPROTO_IP, socket.IP_TOS, tos_value)

try:
    print(f"DSCP {dscp_ef} (ToS {tos_value}) でパケットを送信中...")
    sock.sendto(b"Critical Data", (dest_ip, dest_port))
finally:
    sock.close()

curlでのデバッグ

APIの疎通確認時にQoSが効いているか試したい場合は、curl の --tos オプションが便利です。

# DSCP 46 (EF) を指定してリクエストを投げる
# 46 * 4 = 184 (0xb8)
curl --tos 184 http://api.example.local/v1/status

—

6. 現場でのトラブルシューティング:消えるタグの謎

設計通りにマッピングしたはずなのに、なぜかQoSが効かない。そんな時、歴戦のエンジニアはここを見ます。

1. 信頼境界(Trust Boundary)の不一致:
スイッチのポートで qos trust dscp が設定されていないと、スイッチはパケットが入ってきた瞬間にDSCP値を 0 に上書き(リマーク)してしまいます。
2. VPNやトンネルによるカプセル化:
IPsec VPNなどでパケットを包む際、外側のIPヘッダーに元のDSCP値をコピーする設定(Copy TOS)を忘れると、トンネル内では優先制御が効きません。
3. クラウド・インターネットの壁:
残念ながら、インターネットを経由すると、ほとんどのプロバイダーはDSCP値を無視、あるいは 0 にリセットします。QoSが有効なのは、あくまで「自分が支配しているネットワーク内」だけだと心得ましょう。

—

終わりに

QoSマッピングは、目に見えない「パケットの優先順位」を、異なるレイヤー間で整合性を保ちながら受け渡す、非常に繊細な設計作業です。

L2の3ビットという限られたリソースをどう使い、それをL3の広大なフィールドへどうマッピングするか。この設計思想一つで、輻輳(ふくそう)時のシステム耐性は劇的に変わります。次にWiresharkでパケットをキャプチャする際は、ぜひIPヘッダーの Differentiated Services Field を覗いてみてください。そこには、インフラエンジニアたちが込めた「パケットを無事に届けたい」という執念が刻まれているはずです。

それでは、また次のプロトコルの深淵でお会いしましょう。

コメント

タイトルとURLをコピーしました