手当たり次第に書くんだ

飽きっぽいのは本能

VyOS PPPoE 利用時の MTU と MSS

概要

普段インターネットを利用する際、MTU や MSS を意識する人はほとんどいません。しかし、ネットワークエンジニアであってもこの仕組みを正確に理解していないケースが意外と多いものです。

MTU(Maximum Transmission Unit)や MSS(Maximum Segment Size)は、特に WAN(広域ネットワーク)を扱うときに重要になります。WAN では、利用する回線方式やトンネル(VPN、PPPoE など)によって通信経路上の MTU が変化します。その結果、適切に調整されていないと通信が断続的になったり、特定サイトにアクセスできないなどの問題を引き起こします。

最近では、ルーターや OS が自動で最適な値を設定してくれるため、あまり意識されることはなくなりました。しかし、根本原理を理解していないと、トラブルシューティングの際に思わぬ落とし穴にはまります。

本稿では、PPPoE 利用時における MTU と MSS の関係を題材に、これらの値がどのように決定され、なぜ調整が必要なのかを整理します。ここで理解しておくと、PPPoE に限らず、GRE、IPsec、WireGuard など他のトンネリング方式でも応用できるはずです。

MTU

まず MTU について整理しましょう。

MTU とは

MTU(Maximum Transmission Unit)は、1 回の通信で転送可能な最大の IP データグラムサイズを示す値です。
MTU は IP 層の概念であり、実際の数値は下位層(Ethernet、PPP、トンネルなど)の仕様に依存します。つまり、どのネットワークメディアを使うかによって上限が異なります。

Ethernet における MTU サイズ

Ethernet の標準的な MTU は 1500 バイトです。
ただし、Ethernet フレーム全体では以下のヘッダーが付与されるため、実際のフレーム長は 1518 バイトになります。

  • Ethernetヘッダー:14バイト
  • FCS(Frame Check Sequence):4バイト

→ 合計 1518 バイト

このうち、MTU の定義に含まれるのは IPデータグラム部分(1500バイト)であり、EthernetのヘッダーやFCSは除外されます。

PPPoEで追加されるヘッダーとMTUの算出

PPPoE(Point-to-Point Protocol over Ethernet)は、Ethernet上にさらにPPPをカプセル化するため、追加ヘッダーによって実際の転送可能サイズが減少します。
フレッツ光で用いられる PPPoE の構成では、以下のようなヘッダーが付加されます。

ヘッダーByte
IP20
UDP8
L2TP16
PPP2
合計46

EthernetのMTU 1500 から 46 バイトを差し引くと、1454 バイトが PPPoE 利用時の実効 MTU となります。
なお、純粋な PPPoE 接続では L2TP を使用しないため、ヘッダーサイズは異なります(フレッツ光固有の構成)。

PPPoEのMTUを検証

PPPoEクライアント設定

VyOSでもPPPoEサーバーを構成できますが、フレッツ光と同じ環境を作るのは難しかったため、実際にフレッツ光を使用しています。PPPoEクライアントとなるルーターにはVyOSを使用し、MTU検証の為、MTUの明示的な設定を削除しています。

set interfaces pppoe pppoe0 authentication password 'password'
set interfaces pppoe pppoe0 authentication user 'user@test.local'
set interfaces pppoe pppoe0 source-interface 'eth1'

本来は下記のように明示的にMTUを設定します。

set interfaces pppoe pppoe0 authentication password 'password'
set interfaces pppoe pppoe0 authentication user 'user@test.local'
set interfaces pppoe pppoe0 mtu '1454'
set interfaces pppoe pppoe0 source-interface 'eth1'

PingによるMTU調査

Pingを使用して適切なMTUを確認することができます。ここでの条件は、4回、DFビットをON(1)、サイズを試験内容により可変とします。

データサイズ:1500

1500byteでは応答がありません。VyOS上でPingを実行していますが、既にMTUは1454だと出力されています。「Path MTU Discovery」で通知されたものかもしれませんが、今回は考察では対象外とします。

vyos@vyos:~$ /bin/ping xxx.xxx.xxx.xxx  -c 4 -M do -s 1500

PING xxx.xxx.xxx.xxx (xxx.xxx.xxx.xxx) 1500(1528) bytes of data.
/bin/ping: local error: message too long, mtu=1454
/bin/ping: local error: message too long, mtu=1454
/bin/ping: local error: message too long, mtu=1454
/bin/ping: local error: message too long, mtu=1454

--- xxx.xxx.xxx.xxx ping statistics ---
4 packets transmitted, 0 received, +4 errors, 100% packet loss, time 3105ms
データサイズ:1454

1454byteでも応答がありません。

vyos@vyos:~$ /bin/ping xxx.xxx.xxx.xxx  -c 4 -M do -s 1454

PING xxx.xxx.xxx.xxx (xxx.xxx.xxx.xxx) 1454(1482) bytes of data.
/bin/ping: local error: message too long, mtu=1454
/bin/ping: local error: message too long, mtu=1454
/bin/ping: local error: message too long, mtu=1454
/bin/ping: local error: message too long, mtu=1454

--- xxx.xxx.xxx.xxx ping statistics ---
4 packets transmitted, 0 received, +4 errors, 100% packet loss, time 3088ms
データサイズ:1426

少しずつ下げていき、1426byteで応答ありました。

vyos@vyos:~$ /bin/ping xxx.xxx.xxx.xxx  -c 4 -M do -s 1426

PING xxx.xxx.xxx.xxx (xxx.xxx.xxx.xxx) 1426(1454) bytes of data.
1434 bytes from xxx.xxx.xxx.xxx: icmp_seq=1 ttl=54 time=3.71 ms
1434 bytes from xxx.xxx.xxx.xxx: icmp_seq=2 ttl=54 time=3.83 ms
1434 bytes from xxx.xxx.xxx.xxx: icmp_seq=3 ttl=54 time=4.52 ms
1434 bytes from xxx.xxx.xxx.xxx: icmp_seq=4 ttl=54 time=4.02 ms

--- xxx.xxx.xxx.xxx ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3005ms
rtt min/avg/max/mdev = 3.709/4.017/4.517/0.308 ms
MTU調査の結果

想定されるMTUサイズ:1454byteに対し、Pingで送信できる最大値は1426byteでした。1454-1426=28byteの差がありますね。これはPingで確認している為、MTUに対してIPヘッダー(20byte)とICMPヘッダー(8byte)が付与されています。つまりPingでMTUを調査する場合は、Pingで送信できる最大データサイズにIPヘッダーとICMPヘッダーを合算する必要があります。結果、想定通りのMTU:1454byte(1426+20+8=1454)であることが確かめられました。

フラグメントについて

1500byteのデータでも、DFビットをOFFにすると応答があります。これはルーターがPPPoEインターフェイスから出力する際にパケットを適切なサイズに分割(フラグメント)し送信している為です。この分割処理はルーターに余計な負荷をかける為、MTUの明示的な設定や、後述の「Path MTU Discovery」の仕組みを使用して、送信元のホストであらかじめ適切なサイズでパケットを生成したほうが良いのです。

※自分のPCでパケットキャプチャすると分かりますが基本的にDFビットはONになっています。

vyos@vyos:~$ /bin/ping xxx.xxx.xxx.xxx  -c 4 -s 1500

PING xxx.xxx.xxx.xxx (xxx.xxx.xxx.xxx) 1500(1528) bytes of data.
1508 bytes from xxx.xxx.xxx.xxx: icmp_seq=1 ttl=54 time=7.12 ms
1508 bytes from xxx.xxx.xxx.xxx: icmp_seq=2 ttl=54 time=3.88 ms
1508 bytes from xxx.xxx.xxx.xxx: icmp_seq=3 ttl=54 time=4.06 ms
1508 bytes from xxx.xxx.xxx.xxx: icmp_seq=4 ttl=54 time=4.14 ms

--- xxx.xxx.xxx.xxx ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 3.880/4.799/7.117/1.341 ms
Path MTU Discovery

Path MTU Discoveryは自動的にMTUを検出する機能で、ルーターでも、一般的に使用されるPC(Windows/Mac/Linux等)でも基本的に有効になっています。普段使うPCでMTUを意識しないのはその為です。ただ、ICMPのType3/Code4が破棄されると動作しません。インターネット上では様々な機器を経由して通信している為、ICMPのType3/Code4が破棄される可能性も十分にあります。破棄される場合、経路上のルーターでフラグメント処理をすることになりますが、そもそもフラグメントパケットを破棄している場合もあります。この為、ルーターで適切なMTUを設定したほうが良いのです(もちろん設定しなくても問題ないケースもあります)。

自宅がフレッツ光の環境の人は、自身のPC上で適当にインターネット閲覧中にWiresharkでパケットキャプチャ(ICMPでディスプレイフィルター)をすると、「Destination unreachable (Fragmentation needed)」がinfoに含まれるパケットを観測できると思います。これがPath MTU Discoveryで使用されるICMPのType3/Code4です。そのパケットの中に「MTU of next hop: 1454」などのそれらしい情報を確認できると思います。

MTUのまとめ

MTUの値は、前述の通りPingを使用して確認可能ですが、本来の順序は、①回線(カプセル化)の仕様を確認する、②Pingで確認する、が正しい方法です。この考え方を応用すれば、例えばGREでトンネリングする場合のMTUはどうなるか、等も簡単に確認できると思います。

MSS

MSSについて整理します。

MSSとは

MSS(Maximum Segment Size)はTCPにおける概念であり、受信可能なセグメントの最大サイズです。

EthernetにおけるMSSサイズ

EthernetにおけるMSSの最大値は1460byteです。EthernetにおけるMTUの最大値の1500byteからIPヘッダー(20byte)とTCPヘッダー(20byte)を差し引いています(1500-20-20=1460)。

TCP Option

MSSのサイズは1460byteでも、実際にデータを格納できるサイズは1448byteです。この12byte分はTCP Optionであり、TCP OptionにはTime Stamp等の情報(他、No Operation、MSS等)が含まれています。

PPPoEでのMSSの算出

フレッツ光のPPPoEでのMSSは1414byteです。この通り、MSSの算出はMTUありきであり、MTU-IPヘッダー-TCPヘッダーとなり不変です。つまり常にMTUから-40byteになります。

VyOS PPPoE 利用時の MTU と MSS

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

トップへ戻る