Network 入口 | PPPoE | IPv6 | xcast6 | MTU

MTU

MTU の問題

PPPoE を利用する場合、例えば

などとしておく。そうでないと、 通信が途中で止ってしまうというような問題が起きる。 これは実は結構面倒な問題なのであるが、その辺の事情等を説明する。

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。

LANLocal Area Network隣の機械との通信
WANWide 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 のパケットはそのままでは通れない。 で解決方法としては二つあって、
  1. 小さいパケットしか通れないところは分割して送り、出口で再生する
  2. 経路の全区間で通れるような大きさを調べて、その大きさで送出する
つまり前者では 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 (分割しないこと)で送信している場合

分割しないとしているので、大きいものは通らない。初めから通らない。 通らない区間の入口では、 しかしそのむねを発信元に伝える必要がある。それなのに、 これは MTU Path discovery blackhole 問題 (RFC2923) という。

特に、安易に 「ICMP を全て通すと、内部の経路等が分ってしまう」というような理由で、 「ICMP を一律に全て通さない」設定にしている場合、この問題が良く起きる。

DF = 0 (分割してもいい) で送信している場合

前記 DF = 0,1 のどちらの場合も、接続の確立 ( SYN packet で呼びかけて ACK packet で答える) までは、パケットの大きさが小さいため、問題ないが、 その後のデータが大きい時には、データの転送が行われなかったり、 転送が途中で停止してしまう。

解決方法

本来の解決方法は、経路機器(router/PPPoE 装置等)の設定を正しくすること、 つまり
  1. (DF=1) 「ICMP を通らないようにするのは構わないが、その中で、 ICMP destination unreachable だけは通す」 設定とする。
  2. (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 を見る側の設定。

PPPoE ルータの管理・製造者

経路の管理者・特に防火壁 (FireWall)を設定する場合

送信側

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

08:21:55 12/14/09
claudebot
Apache/2.0.65 (Unix) mod_ssl/2.0.65 OpenSSL/1.0.1g DAV/2 PHP/5.4.26
Count.cgi
(since 2002/03/20)