Network 入口 |
PPPoE |
IPv6 |
xcast6 |
MTU
MTU
MTU の問題
PPPoE を利用する場合、例えば
- 端末(受信側) では MTU=1454,MSS=1414
- サーバ(提供側) では mtudisc=1
- ルータ(経路機器) では ICMP DU FN をきちんと返すこと、
パケットの分割・組立の動作を確認
などとしておく。そうでないと、
通信が途中で止ってしまうというような問題が起きる。
これは実は結構面倒な問題なのであるが、その辺の事情等を説明する。
URL
- pingでMTUサイズを調査する
-
http://www.atmarkit.co.jp/fwin2k/win2ktips/652pingmtu/pingmtu.html
- (ipf should have) MSS Clamping
-
http://false.net/ipfilter/2002_02/0356.html (not found)
-
FreeBSD で ADSL NAT ルータを作る →
-
Path MTU Discovery Black Hole 問題と対処
http://f1.aaa.livedoor.jp/~fexx/adsl/mtu-ja.html
- Path MTU Discovery Black hole 問題
-
http://www.soi.wide.ad.jp/class/20040021/slides/10/23.html
- RFC 2923 --
TCP Problems with Path MTU Discovery
-
http://www.faqs.org/rfcs/rfc2923.html
MTU が 1500 未満の世界
(MTU: Maximum Transmission Unit)
まず、MTU というものがある。最大転送単位。英語では Maximum Transmission Unit なので直訳である。
インターネットの通信は、
-
送りたい情報を小さな小間切にして、その一つ一つを
小包にして、発信元と配送先を書いた名札を付けて、それを
あたかも灯籠流しの灯籠を川に流すようにして、次々に飛ばす(流す)
という方式で行なわれている。この小包が packet、パケットである。このパケットの大きさが問題
になるという話である。
つまり
簡単に言えば MTU は(最大)パケットの大きさである。これは 32k バイト とか 1,500 バイトとか、
パケットが通る媒体によって違う。
LAN と WAN という用語がある。Local Area Network と Wide Area Network。
LAN | Local Area Network | 隣の機械との通信 |
WAN | Wide Area Network | 遠く離れた機械との通信 |
このうちの隣の機械との通信の
LAN で使われている Ethernet ではこのパケットの大きさは通常 1,500 バイトとなっている。
これがインターネット(WAN) に接続されていて、その通信先との経路の途中に
PPPoE 等の (ような 1,500 バイトのパケットをそのままでは通せない)
区間があると、問題が起きる。
- PPPoE
-
フレッツ・ADSLの地域 IP 網を利用する場合、接続業者までの通信に
PPPoE (PPP Point to Point Protocol over Ethernet,
RFC 2516,
同 日本語訳)
が使われる。
- MTU = 1454
-
この PPPoE では Ethernet の MTU = 1500 の世界の中に、
RFC2516 的には 6 バイトの PPPoE へッダと 2 バイトの ppp へッダを加える。このため、
1500 - ( 6 + 2 ) =
1492 バイトまでのパケットしか通れないことになる。つまり MTU = 1492 にする。
しかし NTT 東日本の場合、更に内部のネットワークの事情で
「MTU = 1454 にしておけば、必ずどこでも通る」ということになっているらしい。
これらの数字は、
通常の Ethernet の通信に使われる
1500より小さくなるので、問題が起きる。と言える。
(フレッツ網) の場合:
PC ==+
Server ==+== (PPPoE router) .....(FLETS 網) ...... (PPPoE 受付) === ISP
MTU = 1500 MTU = 1454
(ADSL) の場合:
PC ==+ DSLAM
Server ==+== (PPPoE router) ....(Access Line) ..... (PPPoE 受付) === ISP
MTU = 1500 MTU = 1454
(DSLAM = Digital Subscriber Line Access Multiplexer)
- 何故 MTU 1500 のままではだめなの
-
MTU 1500 のままでも、問題がない場合もある。しかし
次の理由で MTU は 1454 にしておいた方が問題が少ない。
FLETS 網や ADSL
がそういう小さい MTU しか許していないという問題ではなく、
「認証等の利便さから
Ethernet を利用した PPP (PPP over Ethernet)を使う」ので
「その Ethernet の 1500 bytes のパケットの中に
更に PPPoE や ppp のへッダを
を入れて送る必要がある」
から普通に通れる大きさは 1500 から少し小さくなる
- (ではどうやって対処するか) 分割 の場合と 破棄の場合
-
この為に上記 端末(PC)/サーバ(Server) の機械から送信された
1500 Bytes のパケットはそのままでは通れない。
で解決方法としては二つあって、
- 小さいパケットしか通れないところは分割して送り、出口で再生する
- 経路の全区間で通れるような大きさを調べて、その大きさで送出する
つまり前者では
PPPoE 通信の入り口で分割されるか破棄され、
後者の場合では
送出側ではパケットの大きさを小さくして再送信する。
その場合分けを表にすると次のようになる。
場合分け |
送信元での
net.inet.ip.mtudisc
の設定
| 意味 | 動作 |
分割 | 0 | 分割可 | 入口と出口で再組立 reassembly |
破棄 | 1 | DF(Dont Frag) bit set, 分割禁止 |
パケットを破棄した事を伝える為の
「
ICMP
(RFC792)
DU FN」パケットが送信元に送信され、
送信元では、パケットの大きさを小さくして再送信する。
|
- mtudisc
-
上の表で出た来た、
mtudisc というのは
Path MTU Discovery
(RFC 1191)
の略で、
「『通信しようとしている相手との間の経路全てに渡って』
通ることが出来る最大の MTU を調べる」という意味になる。
今自分が使っている機械の設定がどうなっているか、とか、では変更しようというような場合の操作は、
シェル窓で次のように行なう。
| 送信元での操作 | 意味 | 操作に必要な権限 |
確認 | % sysctl net.inet.ip.mtudisc | 確認のための表示 | 一般 |
設定 | $ sysctl -w net.inet.ip.mtudisc=1 | = 1 に設定する例 | 管理者 |
- DF bit
-
大きなパケットが、小さなパケットしか通さない点に到達した時に、
分割して通すか、破棄してしまうかのどちらの動作を行なうかは、
送信元での DF bit の設定による。DF は Don't Frag で、
「お願い、分割しないで」という要求になる。
mtudisc = 1 の時には、
IP packet
の中では DF bit (6bytes 目の最上位 bit) を立てて送信する。
これで ICMP Destination Unreachable が返って来るようなら、
小さい packet にして再送出するということになる。
(経路に問題がない時には、
どちらの方法でも結果的には DF bit が 1 でも 0 でも同じように転送が行なわれるように見える)
- ping -s
-
通信先までの経路について、どのくらいの大きさのパケットが送れるかを調べたいとする。
これを
手軽に試す方法として ping にパケットの大きさを指定して相手との通信を調べる
ということも出来る。OS に依って、書式が違うかも知れないが、
NetBSD (多分 *BSD の場合も全て) や Linux(RedHat) の場合
ping -s 1992 相手
Solaris 2.x, 8.x 等の場合
ping -s 相手 1992
のようにすると、
+8 された 2000 バイトのパケットを送って試すことがが出来る
(終了する時には ^C を入力する)。この数を大きくしたり小さくしたりして、
いくつの大きさまで通るかを調べられる。
ただし
管理者の設定によっては
「Web は見えるのに ping は通らない」
というようなことが良くあるので、
ping に全く応答がなければ、この方法は使えないことになる。
さて問題
上記、分割・破棄の
いづれの場合でも、途中の router 等の機械が正しく設定されていないか、
安全上の理由と称して、必要な packet を通さないようにしている場合に問題が起きる。
これを送り出し側の DF bit の設定の違いによって考えると次のようになる。
DF = 1 (分割しないこと)で送信している場合
分割しないとしているので、大きいものは通らない。初めから通らない。
通らない区間の入口では、
しかしそのむねを発信元に伝える必要がある。それなのに、
- フレッツ・ADSLの出入口のルータ、
つまり PPPoE をしゃべっていて、MTU を小さく制限してしまう機器が
そもそも、
パケットを破棄した時に
「ICMP DU FN」
(ICMP/Destination Unreachable/Fragmentation Needed)
パケットを送信しない
-
(上記機器が) ICMP DU FN は返すが、
経路の途中の FireWALL 等が「ICMP DU FN」パケットを通さない
-
同じ場合で、
経路の途中の NAT 機器が「ICMP DU FN」パケットを送信元に転送できない
これは
MTU Path discovery blackhole 問題
(RFC2923)
という。
特に、安易に
「ICMP を全て通すと、内部の経路等が分ってしまう」というような理由で、
「ICMP を一律に全て通さない」設定にしている場合、この問題が良く起きる。
DF = 0 (分割してもいい) で送信している場合
- パケットを正しく分割しない。
- 分割されたパケットを 防火壁(FireWALL) となっている機械等が破棄する
- 分割パケットを正しく組立出来ない。
前記 DF = 0,1 のどちらの場合も、接続の確立
( SYN packet で呼びかけて ACK packet で答える)
までは、パケットの大きさが小さいため、問題ないが、
その後のデータが大きい時には、データの転送が行われなかったり、
転送が途中で停止してしまう。
解決方法
本来の解決方法は、経路機器(router/PPPoE 装置等)の設定を正しくすること、
つまり
- (DF=1)
「ICMP を通らないようにするのは構わないが、その中で、
ICMP destination unreachable だけは通す」
設定とする。
- (DF=0)
パケットの分割・組立に問題があれば、それを解決する
である。本来はこれだけでいいはずである。
逃げ道
しかし、通常、上の解決方法が必要な経路機器は、
多くの場合、他人の管理にあり、対応してもらえるとは限らない。
そこで、逃げ道を考える
(RFC2923
TCP Problems with Path MTU Discovery
も参照)
PPPoE のルータを設定出来る時(あるいは PPPoE 機器 = ブロードバンドルータ の製造者)
ipnat の機能を利用して mss 1414 等に設定
sysctl -w net.inet.tcp.mss_ifmtu=1
設定例 ->
NetBSD ML より
(MSS の大きさなどについて) →
21
(ipnat.conf の書き方) →
39
データを発信する機械
上のように ルータで設定しても、まだ問題が残ることがある。
(特に自分の方でサーバを動かしていて、そこに
外の他の機械から要求が来た時)
そこで、次のうちのどちらかを設定する。
初めから MTU を 1454 (等)にして発信する
ifconfig (device) mtu 1454
(man ifconfig.if 参照)
しかしこれは 対応していない device driver が多いので、
次のように利用出来ないことも多い
makoto@milano 10:32:21/020427(/home/makoto)# ifconfig le0 mtu 1454
ifconfig: SIOCSIFMTU: Invalid argument
そこで、
DF bit を常に立てて通信する
sysctl -w net.inet.ip.mtudisc=1
とすることで
MTU discovery を有効にし、常に
DF=1 として送信することで
避けられる場合もある。
まとめ
以下で受信と送信という語があるが、これは
「1500 bytes 近くの、大きなパケットの」
という意味である。つまり大きなデータを転送する方向を考えている。
受信側
例えば、Web を見る側の設定。
- MTU を初めから 1454 等に設定する、と回避出来る。
-
ただし OS や driver によって、
MTU を 1500 以外に出来る場合と出来ない場合がある。
PPPoE ルータの管理・製造者
経路の管理者・特に防火壁 (FireWall)を設定する場合
- 他の機械から出ているものも含めて、
上記 ICMP DU の packet は落とさない
(filter で止めない)
ようにする
- 「断片化された packet は通さない」という設定も良く行なわれるが、
これも害がある。
送信側
ftp/Web server 等で情報を提供する側。メールサーバの送り出し。
更に URL
- MTUとフレッツ
-
http://www.editnet.co.jp/net/knowledge/010501.htm
- MTU の設定について
-
ping -f の紹介があるが、flood というのはそう使うものではない
と思う。
http://www.dive-in.to/~hideto/mtu/
-
RTシリーズのIPsec&IKE&VPN&...に関するFAQ
-
特定のサーバに接続すると通信が止まってしまいます。
http://www.rtpro.yamaha.co.jp/RT/FAQ/IPsec/faq_4_b.html
- RFC 2979 日本語訳
-
インターネット ファイアウォールのふるまいとその要件
http://www.ipa.go.jp/security/rfc/RFC2979JA.html
- bRoadLanner ファームウェア情報(プラネックス・コミュニケーションズ)
-
http://www.planex.co.jp/brl-01/download.htm
- マイクロ総研 高速ルータ「NetGenesis SuperOPT50」
-
http://www.watch.impress.co.jp/broadband/news/2002/02/01/netgen.htm
- マイクロ総研 NetGenesis 動作確認一覧
-
http://www.mrl.co.jp/support/nwglist.htm
- (株)メルコ・製品情報 >ネットワーク
-
http://buffalo.melcoinc.co.jp/products/catalog/network/index.html
-
TCP/IP Fundamentals
OSI Seven Layer Model & Seminar Outline
(英語)
-
http://www.uga.edu/~ucns/lans/tcpipsem/
- path MTU discovery broken (net.inet.ip.mtudisc)
-
http://www.netbsd.org/cgi-bin/query-pr-single.pl?number=12790
- 上記問題は 2002/05/26 頃解決している(はず)。以下は一例。
-
http://cvsweb.netbsd.org/cgi-bin/cvsweb.cgi/syssrc/sys/netinet/tcp_subr.c?sortby=date
の 1.128
Last Update
23:21:55 12/13/09
CCBot/2.0 (https://commoncrawl.org/faq/)
Apache/2.4.46 (Unix) PHP/7.4.15
(since 2002/03/20)