こんにちは、栗岡 です。
少しルーティングの動作について分からないことがあり、教えて頂きたいのです。
説明がダラダラと分かりにくい点などありますが、御容赦下さい。
(自分なりにはまとめたつもりなのですが。。)
以下のようなネットワークにおいて、
この先に、192.168.34. なネットワーク有り
| |
+---+---+ +---+---+
|router1| |router3|
+---+---+ +---+---+
|192.168.30.231 |192.168.30.233
| |
-------+-----+----------+---------+--------------
| |
|192.168.30.210 |192.168.30.232
+---+---+ +---+---+
| host1 | |router2|
+-------+ +---+---+
|
host1は、
RedHat 5.1, kernel 2.0.36 で、
# route add -net 192.168.34.0 netmask 255.255.255.0 gw 192.168.30.233
# netstat -rn
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
192.168.30.0 0.0.0.0 255.255.255.0 U 1500 0 0 eth0
192.168.34.0 192.168.30.233 255.255.255.0 UG 1500 0 0 eth0
127.0.0.0 0.0.0.0 255.0.0.0 U 3584 0 0 lo
0.0.0.0 192.168.30.231 0.0.0.0 UG 1500 0 0 eth0
のような設定になっています。
ここで、192.168.34. なネットワーク上のホストに traceroute すると、
# traceroute 192.168.34.100
traceroute to 192.168.34.100 (192.168.34.100), 30 hops max, 40 byte packets
1 192.168.30.233 (192.168.30.233) 1.464 ms 1.368 ms 1.299 ms
2 192.168.39.235 (192.168.39.235) 3.182 ms 3.079 ms 3.278 ms
3 192.168.34.100 (192.168.34.100) 4.402 ms 4.355 ms 4.149 ms
のようになっています。(全くもって正常です。)
-.-.-.-.-.
ここで、更に、
# route add -host 192.168.30.233 gw 192.168.30.232
などというものを追加して(なぜこんなものを入れるのかはのちほど、、)
# netstat -rn
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
192.168.30.233 192.168.30.232 255.255.255.255 UGH 1500 0 0 eth0
192.168.30.0 0.0.0.0 255.255.255.0 U 1500 0 0 eth0
192.168.34.0 192.168.30.233 255.255.255.0 UG 1500 0 0 eth0
127.0.0.0 0.0.0.0 255.0.0.0 U 3584 0 0 lo
0.0.0.0 192.168.30.231 0.0.0.0 UG 1500 0 0 eth0
の状態で、先程のtracerouteを行うと、
# traceroute 192.168.34.100
traceroute to 192.168.34.100 (192.168.34.100), 30 hops max, 40 byte packets
1 192.168.30.233 (192.168.30.233) 2.489 ms 192.168.30.232 (192.168.30.232) 1.654 ms 1.630 ms
2 192.168.30.233 (192.168.30.233) 2.872 ms 2.824 ms 2.895 ms
3 192.168.39.235 (192.168.39.235) 4.782 ms 4.603 ms 4.558 ms
4 192.168.34.100 (192.168.34.100) 6.258 ms 5.716 ms 5.951 ms
となり、どうやら 192.168.30.232 に最初にパケットを吐き出しているような気が
するのです。
という事は、このhost1の環境において(恐らくは 2.0.36)ルーティング動作を行う
場合、routing tableを再帰的?(こういう表現が正しいのか分かりません)に検索
しているように想像します。
-.-.-.-.-.
この状態で、「仮に」、
# route add -net 192.168.30.0 netmask 255.255.255.252 gw 192.168.30.2
# route add -host 192.168.30.2 gw 192.168.30.3
# netstat -rn
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
192.168.30.233 192.168.30.232 255.255.255.255 UGH 1500 0 0 eth0
192.168.30.2 192.168.30.3 255.255.255.255 UGH 1500 0 0 eth0
192.168.30.0 192.168.30.2 255.255.255.252 UG 1500 0 0 eth0
192.168.30.0 0.0.0.0 255.255.255.0 U 1500 0 0 eth0
192.168.34.0 192.168.30.233 255.255.255.0 UG 1500 0 0 eth0
127.0.0.0 0.0.0.0 255.0.0.0 U 3584 0 0 lo
0.0.0.0 192.168.30.231 0.0.0.0 UG 1500 0 0 eth0
の様な環境になったとして、
実際にはないのですが、仮に 192.168.30.2 に tracerouteや pingなどを行うと、
syslog に以下の様なメッセージを吐き、ダウンします。(コンソールにも出ます。)
----- ここから
Mar 30 23:15:25 skurioka kernel: Problem: block on freelist at 0335cdd0 isn't free.
Mar 30 23:15:25 skurioka kernel: kfree of non-kmalloced memory: 0335cc98, next= 00000000, order=1
Mar 30 23:15:25 skurioka kernel: kfree of non-kmalloced memory: 0335ddd8, next= 00000000, order=1776682
Mar 30 23:15:25 skurioka kernel: kfree of non-kmalloced memory: 0335ddd8, next= 00000000, order=1776682
Mar 30 23:15:25 skurioka kernel: kfree of non-kmalloced memory: 0335dd58, next= 00000000, order=1776682
Mar 30 23:15:25 skurioka kernel: kfree of non-kmalloced memory: 0335da18, next= 00000000, order=1776682
Mar 30 23:15:25 skurioka kernel: kfree of non-kmalloced memory: 0335da18, next= 00000000, order=1776682
Mar 30 23:15:25 skurioka kernel: kfree of non-kmalloced memory: 0335d998, next= 00000000, order=1776682
Mar 30 23:15:25 skurioka kernel: kfree of non-kmalloced memory: 0335d658, next= 00000000, order=1776682
Mar 30 23:15:25 skurioka kernel: kfree of non-kmalloced memory: 0335d658, next= 00000000, order=1776682
Mar 30 23:15:25 skurioka kernel: kfree of non-kmalloced memory: 0335d298, next= 00000000, order=1776682
Mar 30 23:15:25 skurioka kernel: kfree of non-kmalloced memory: 0335d298, next= 00000000, order=1776682
Mar 30 23:15:25 skurioka kernel: invalid operand: 0000
Mar 30 23:15:25 skurioka kernel: CPU: 0
Mar 30 23:15:25 skurioka kernel: EIP: 0010:[<00000007>]
Mar 30 23:15:25 skurioka kernel: EFLAGS: 00010203
Mar 30 23:15:25 skurioka kernel: eax: 030e2e98 ebx: 00000000 ecx: 030e2f10 edx: 030e2000
Mar 30 23:15:25 skurioka kernel: esi: 0335c000 edi: 0337e010 ebp: 00000001 esp: 0337e028
Mar 30 23:15:25 skurioka kernel: ds: 0018 es: 0018 fs: 002b gs: 002b ss: 0018
Mar 30 23:15:25 skurioka kernel: Corrupted stack page
Mar 30 23:15:25 skurioka kernel: Process traceroute (pid: 460, process nr: 33, stackpage=033c0000)
Mar 30 23:15:25 skurioka kernel: Stack: 00000000 00000001 00000000 00025c5e 00000000 001c2090 05dc0007 00000000
Mar 30 23:15:25 skurioka kernel: 031ea8c0 00000000 0055ffaa 0337e090 0335d018 021ea8c0 d21ea8c0 031ea8c0
Mar 30 23:15:25 skurioka kernel: 00000000 00000001 00000000 00025c5e 00000000 001c2090 05dc0007 d2000000
Mar 30 23:15:25 skurioka kernel: Call Trace: [<00140dd6>] [<00140cd3>] [<0014095b>] [<00140dd6>] [<00140cd3>] [<0014095b>] [<00140dd6>]
Mar 30 23:15:25 skurioka kernel: [<00140cd3>] [<0014095b>] [<00140dd6>] [<00140cd3>] [<0014095b>] [<00140cd3>]
Mar 30 23:15:25 skurioka kernel: Code: f0 c3 e2 00 f0 53 ff 00 f0 53 ff 00 f0 54 ff 00 f0 d2 9c 00
Mar 30 23:15:25 skurioka kernel: general protection: 0000
Mar 30 23:15:25 skurioka kernel: CPU: 0
Mar 30 23:15:25 skurioka kernel: EIP: 0010:[<032ce8dc>]
Mar 30 23:15:25 skurioka kernel: EFLAGS: 00010293
以降続く、、
----- ここまで
どうやら、フリーズというよりメモリ不足みたいなものでサービスが稼働出来ない
状況に陥っているような気がするのです。
-.-.-.-.-.
で、やっと質問なのですが(ここまで付き合って下さって有難うございます)、
上記の様な 論理的にloopするような routing定義をする事自体間違いなので、
やろうと思ってやるひとはいない と思いますが、仮に この host1において、
routed や gatedなどを動かしていてRIPなどで「受け付けてしまう」という
心配はないのでしょうか?
RIPの仕様自体、不勉強で殆ど(全く?)知らないのですが、gatedなどでは
インターフェイス単位でフィルタを掛けたり出来そうですが、ripin にして
いた場合に、何処かのわるものがネットワークに何らかの手段で接続した場合に
それは有り得るのでしょうか という質問なのです。
また、このようなrouting table を再帰的に検索するのには、どのような意味合い
(メリット)があるのでしょうか?
自分なりに何故そのようになっているのか考えてみたのですが、力不足故、
分かりませんでした。
また、上記の現象自体は、私が確認した限りでは linux 2.2.3, 2.2.4 カーネルと、
solaris7 では起きません。(routing tableは再帰的に検索していない。)
一応、2.2.4 での tracerouteの実行結果は、
# traceroute 192.168.34.100
1 192.168.30.233 (192.168.30.233) 2.508 ms 1.379 ms 1.355 ms
2 192.168.39.235 (192.168.39.235) 5.053 ms 3.216 ms 3.092 ms
3 192.168.34.100 (192.168.34.100) 5.481 ms 4.466 ms 4.183 ms
# traceroute 192.168.30.2
traceroute to 192.168.30.2 (192.168.30.2), 30 hops max, 40 byte packets
1 skurioka (192.168.30.210) 2992.243 ms !H 2997.482 ms !H 2999.586 ms !H
となり、問題なく動いています。
これらの場合に一つ気がついたのが、192.168.34. 宛のパケットを仮に
192.168.30.232 のルータに投げると、一回目は素直に、
# traceroute 192.168.34.100
traceroute to 192.168.34.100 (192.168.34.100), 30 hops max, 40 byte packets
1 192.168.30.232 (192.168.30.232) 3.020 ms 1.677 ms 1.639 ms
2 192.168.30.233 (192.168.30.233) 2.986 ms 2.918 ms 192.168.39.235 (192.168.39.235) 3.543 ms
3 192.168.34.100 (192.168.34.100) 8.665 ms 4.269 ms 4.222 ms
で、30.232->30.233->34.xxx のような経路になるのですが、
二回目以降になると、
traceroute to 192.168.34.100 (192.168.34.100), 30 hops max, 40 byte packets
1 192.168.30.233 (192.168.30.233) 1.563 ms 1.428 ms 1.326 ms
2 192.168.39.235 (192.168.39.235) 3.229 ms 3.063 ms 3.059 ms
3 192.168.34.100 (192.168.34.100) 4.404 ms 4.389 ms 4.431 ms
のように routing tableを書き換えていないのにも関わらず、直接 233のルータに
投げるようになっています。
これは経路が最適化された(?)という解釈でよいのでしょうか?
これらの 2.0系と2.2系+Solaris7 (と言ってしまっていいのか) のrouting動作の
違いが、先程のrouting tableの再帰検索と関係するのかどうかは分からないのですが
一応御報告まで。
-.-.-.-.-.
ということで、やはりダラダラと長くなってしまったのですが、要約すると、
2.0系カーネルにおいて、同一ネットワーク上のサブネット+ホストの論理的loopに
陥るrouting tableを RIPで受け付けることは有り得るのか?
なぜ、2.0系では routingを再帰的に検索しているのか?
(最適化する為であるならば、それはどのようなネットワーク構成を想定できるのか)
の2つなのです。
一度に2つの質問をするのは、MLではルール違反ですが、分けようがないので、
勘弁して下さい。m(_ _)m
以上、御存知の方がいらっしゃれば、御教示頂ければ幸いです。
また、「これはドコソコで聞いたほうがええよ」という御意見でも結構です。
宜しくお願い致します。
では、これにて。
--
Shinya Kurioka