本好き鉄っちゃんの自己紹介

トップページ


IPネットワークでarpキャッシュがネットワーク障害を引き起こす場合

マシンをネットワークから切り離し、既存のサーバをIPエイリアスで臨時に代理として使う場合に、残存するarpキャッシュによるネットワークの不到達を実験してみました。

なおIPエイリアスを使わず代替サーバを独自にたてる場合は、その起動時にマシンがリモートarpキャッシュを更新するようなarp要求を行うので、このような問題は発生しないはずです。

またarpキャッシュは時間が経過すればクリアされます。すぐには通信が確立しなくても、しばらく待てば、開通します。キャッシュの有効期限は実装にもよると思いますが、数分から20分程度のようです。
ログインしてrootユーザになれるのであれば、不要なarpキャッシュを削除することも可能です。


3台のマシンはともにLinux 2.4.18です。pingは iputils-ss001110 です。

hostA192.168.1.31ネットワークから切り離す
hostB192.168.1.16hostAのIPアドレスをエイリアスとして設定
hostC192.168.1.1hostAに対し通信する必要のあるマシン

hostAをネットワークから切り離し、別のhostBに、そのIPアドレス(192.168.1.31)をエイリアスとして設定。
しかし、hostCからhostAのIPアドレへのpingが失敗する

[root@hostA /root]# /sbin/ifconfig eth0 down
    -----
[root@hostB /root]# /sbin/ifconfig eth0:0 192.168.1.31
    -----
[foo@hostC ~] ping 192.168.1.31
PING 192.168.1.31 (192.168.1.31) 送信元 192.168.1.1 : 56(84) bytes of data.

--- 192.168.1.31 ping 統計 ---
送信パケット数 9, 受信パケット数 0, パケット損失 100%
[foo@hostC ~]

hostCにあるarpキャッシュのうち、hostAに関するものを更新するため、hostBから、hostCへpingを実行。
しかし、hostCから、hostAのIPアドレス(現在はhostBのエイリアス)へpingを実行しても失敗する。当然、ですね。

[root@hostB /root]# ping 192.168.1.1
PING 192.168.1.1 (192.168.1.1) from 192.168.1.16 : 56(84) bytes of data.
64 bytes from 192.168.1.1: icmp_seq=0 ttl=255 time=979 usec
64 bytes from 192.168.1.1: icmp_seq=1 ttl=255 time=680 usec

--- 192.168.1.1 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max/mdev = 0.680/0.829/0.979/0.152 ms
[root@hostB /root]#
    -----
[foo@hostC ~] ping 192.168.1.31
PING 192.168.1.31 (192.168.1.31) 送信元 192.168.1.1 : 56(84) bytes of data.

--- 192.168.1.31 ping 統計 ---
送信パケット数 2, 受信パケット数 0, パケット損失 100%
[foo@hostC ~]

そこで、hostAのIPアドレス(実はhostBのエイリアス)を発信元にして、ネットワークへブロードキャストpingを実行。すると、前回はダメだったhostCからhostAのIPアドレスへのpingが成功する。

[root@hostB /root]# ping -I 192.168.1.31 -b 192.168.1.255
PING 192.168.1.255 (192.168.1.255) from 192.168.1.31 : 56(84) bytes of data.
64 bytes from 192.168.1.1: icmp_seq=0 ttl=255 time=2.024 msec
64 bytes from 192.168.1.31: icmp_seq=0 ttl=255 time=2.649 msec (DUP!)
64 bytes from 192.168.1.254: icmp_seq=0 ttl=255 time=6.813 msec (DUP!)
64 bytes from 192.168.1.1: icmp_seq=1 ttl=255 time=933 usec
64 bytes from 192.168.1.254: icmp_seq=1 ttl=255 time=1.019 msec (DUP!)
64 bytes from 192.168.1.31: icmp_seq=1 ttl=255 time=1.180 msec (DUP!)
64 bytes from 192.168.1.1: icmp_seq=2 ttl=255 time=4.940 msec
64 bytes from 192.168.1.254: icmp_seq=2 ttl=255 time=4.992 msec (DUP!)
64 bytes from 192.168.1.31: icmp_seq=2 ttl=255 time=6.555 msec (DUP!)

--- 192.168.1.255 ping statistics ---
3 packets transmitted, 3 packets received, +6 duplicates, 0% packet loss
round-trip min/avg/max/mdev = 0.933/3.456/6.813/2.251 ms
[root@hostB /root]#
   ------
[foo@hostC ~] ping 192.168.1.31
PING 192.168.1.31 (192.168.1.31) 送信元 192.168.1.1 : 56(84) bytes of data.
64 バイト応答 送信元 192.168.1.31: icmp_seq=0 ttl=255 時間=1.262ミリ秒
64 バイト応答 送信元 192.168.1.31: icmp_seq=1 ttl=255 時間=776 マイクロ秒
64 バイト応答 送信元 192.168.1.31: icmp_seq=2 ttl=255 時間=762 マイクロ秒

--- 192.168.1.31 ping 統計 ---
送信パケット数 3, 受信パケット数 3, パケット損失 0%
Round-Trip 最小/平均/最大/mdev = 0.762/0.933/1.262/0.233ミリ秒
[foo@hostC ~] 

なお、この方法で解決しないマシンもありました。また hostCも、hostAのIPアドレスへpingを何度か繰り返すうちに導通した場合があります(ただ単に古いキャッシュが更新されただけかもしれません)。
リモートマシン(例では hostC)でroot権限が使えるならば、arpコマンドで問題のIPアドレスに関するエントリを削除してから、そのIPアドレスへpingを実行すれば、必ず解決します。

[root@hostC /root]# arp -a  <--- arpキャッシュテーブルを表示
router (192.168.1.254) at 00:ZZ:99:0D:E7:YY [ether] on eth0
hostA (192.168.1.31) at 00:90:YY:42:ZZ:D8 [ether] on eth0
hostB (192.168.1.16) at 00:E0:XX:7E:XX:77 [ether] on eth0
[root@hostC /root]# arp -d 192.168.1.16   <--- ** 不要なキャッシュを削除 **
[root@hostC /root]# ping 192.168.1.16
PING 192.168.1.16 (192.168.1.16) from 192.168.1.1 : 56(84) bytes of data.
64 bytes from 192.168.1.16: icmp_seq=0 ttl=255 time=1.846 msec
64 bytes from 192.168.1.16: icmp_seq=1 ttl=255 time=719 usec

--- 192.168.1.16 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max/mdev = 0.719/1.282/1.846/0.564 ms
[root@hostC /root]# arp -a
router (192.168.1.254) at 00:ZZ:99:0D:E7:YY [ether] on eth0
hostA (192.168.1.31) at 00:E0:XX:7E:XX:77 [ether] on eth0  <--- ** 更新されている **
hostB (192.168.1.16) at 00:E0:XX:7E:XX:77 [ether] on eth0
[root@hostC /root]# 

参考文献: W.Richard Stevens 著, 橘康雄 訳, 井上尚司 監訳 『詳解TCP/IPプロトコル Vol.1』,ピアソン・エデュケーション,2000年


2003年11月3日 更新
作成 2002年7月9日
Copyright(C) SUZUKI Yasuhiro
メール