要求されたIPアドレスが他の(無効になった)インターフェイスに関連付けられている場合、LinuxはARP要求メッセージに応答しません。

要求されたIPアドレスが他の(無効になった)インターフェイスに関連付けられている場合、LinuxはARP要求メッセージに応答しません。

私はコンピュータ(カーネル)を持っています。3.2.0-23 - 一般)はインターフェース192.168.1.2/24で構成され、インターフェースのアドレスも使用します。eth0192.168.1.1192.168.1.2tun0

root@T42:~# ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:16:41:54:01:93 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.2/24 scope global eth0
    inet6 fe80::216:41ff:fe54:193/64 scope link
       valid_lft forever preferred_lft forever
3: bond0: <BROADCAST,MULTICAST,MASTER> mtu 1500 qdisc noop state DOWN
    link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
4: irda0: <NOARP> mtu 2048 qdisc noop state DOWN qlen 8
    link/irda 00:00:00:00 brd ff:ff:ff:ff
5: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:13:ce:8b:99:3e brd ff:ff:ff:ff:ff:ff
    inet 10.30.51.53/24 brd 10.30.51.255 scope global eth1
    inet6 fe80::213:ceff:fe8b:993e/64 scope link
       valid_lft forever preferred_lft forever
6: tun0: <POINTOPOINT,MULTICAST,NOARP> mtu 1500 qdisc pfifo_fast state DOWN qlen 100
    link/none
    inet 192.168.1.1 peer 192.168.1.2/32 scope global tun0
root@T42:~# ip route show dev eth0
192.168.1.0/24  proto kernel  scope link  src 192.168.1.2 
root@T42:~# 

上記のようにtun0管理上無効になっています(ip link set dev tun0 down)。 ARP要求を受信すると、192.168.1.2PCは次の要求に応答しません。

root@T42:~# tcpdump -nei eth0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
15:30:34.875427 00:1a:e2:ae:cb:b7 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 60: Request who-has 192.168.1.2 tell 192.168.1.1, length 46
15:30:36.875268 00:1a:e2:ae:cb:b7 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 60: Request who-has 192.168.1.2 tell 192.168.1.1, length 46
15:30:39.138651 00:1a:e2:ae:cb:b7 > 00:1a:e2:ae:cb:b7, ethertype Loopback (0x9000), length 60:
^C
3 packets captured
3 packets received by filter
0 packets dropped by kernel
root@T42:~#

tun0インターフェイスを削除した後にのみ、(ip link del dev tun0)PCは192.168.1.2インターフェイスのARP要求に応答します。eth0

ルーティングテーブルは、前と後がまったく同じように見えますip link del dev tun0

root@T42:~# netstat -rn
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         10.30.51.254    0.0.0.0         UG        0 0          0 eth1
10.30.51.0      0.0.0.0         255.255.255.0   U         0 0          0 eth1
192.168.1.0     192.168.1.2     255.255.255.0   UG        0 0          0 eth0
root@T42:~# ip link del dev tun0
root@T42:~# netstat -rn
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         10.30.51.254    0.0.0.0         UG        0 0          0 eth1
10.30.51.0      0.0.0.0         255.255.255.0   U         0 0          0 eth1
192.168.1.0     192.168.1.2     255.255.255.0   UG        0 0          0 eth0
root@T42:~# 

以下のルーティングエントリは、次のコマンドを使用して削除されましたip link set dev tun0 down

Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
192.168.1.2     0.0.0.0         255.255.255.255 UH        0 0          0 tun0

しかし、ルーティングテーブルはコマンドの前と後とまったく同じですが、カーネルが実行するip link del dev tun0実際のルーティングの決定は次のとおりです。

T42:~# ip route get 192.168.1.1
local 192.168.1.1 dev lo  src 192.168.1.1 
    cache <local> 
T42:~# ip link del dev tun0
T42:~# ip route get 192.168.1.1
192.168.1.1 dev eth0  src 192.168.1.2 
    cache  ipid 0x8390
T42:~# 

これが予想される動作ですか?カーネルがルーティングテーブルを無視するのはなぜですか?

ベストアンサー1

正確に言えば、ルーティングテーブルは無視されません。優先順位が高いルーティングテーブルに上書きされます。

どうなりますか?

入力時に表示されるルーティングテーブルは、カーネルip route showで使用される唯一のルーティングテーブルではありません。実際、ルーティングテーブルはデフォルトで3つあり、次のコマンドに示す順序で検索されますip rule

# ip rule show
0:      from all lookup local
32766:  from all lookup main
32767:  from all lookup default

おなじみのテーブルはですがmain、優先順位が最も高いルーティングテーブルはですlocal。このテーブルは、ローカルおよびブロードキャストルーティングを追跡するためにカーネルによって管理されます。つまり、テーブルはlocalカーネルに自分のインターフェイスのアドレスにルーティングする方法を伝えます。次のようになります。

# ip route show table local
broadcast 127.0.0.0 dev lo  proto kernel  scope link  src 127.0.0.1
local 127.0.0.0/8 dev lo  proto kernel  scope host  src 127.0.0.1
local 127.0.0.1 dev lo  proto kernel  scope host  src 127.0.0.1
broadcast 127.255.255.255 dev lo  proto kernel  scope link  src 127.0.0.1
broadcast 192.168.1.0 dev eth0  proto kernel  scope link  src 192.168.1.2
local 192.168.1.1 dev tun0  proto kernel  scope host  src 192.168.1.1
local 192.168.1.2 dev eth0  proto kernel  scope host  src 192.168.1.2
broadcast 192.168.1.255 dev eth0  proto kernel  scope link  src 192.168.1.2

引用を参照してくださいtun0。これが奇妙な結果をもたらす原因ですroute get。 192.168.1.1はローカルアドレスと呼ばれています。つまり、192.168.1.1にARP応答を送信したい場合は、それを自分自身に送信するのが簡単です。私たちはlocalテーブルでパスを見つけたので、もはやパスを検索せず、あえてテーブルをチェックmainしません。default

なぜテーブルが複数あるのですか?

少なくともip route入力できますが、「明白な」パスが複雑に絡み合っているのを見ることができない場合は良いでしょう(route printWindowsシステムで入力してみてください)。また、誤った構成に対する最小限の保護としても機能します。デフォルトのルーティングテーブルが難読化されていても、カーネルは依然として自己通信方法を知っています。

(もともとローカルパスを保存するのはなぜですか?それで、カーネルは他のすべてのものと同じルックアップコードを使用してローカルアドレスを見つけることができます。これは内部的に作業を簡単にします。)

このマルチテーブルスキームを使用して実行できる他の興味深い作業があります。具体的には、独自のテーブルを追加して検索ルールを指定できます。これを「ポリシールーティング」といい、そのポリシーに基づいてパケットをルーティングする場合源泉アドレス、これがLinuxで動作する方法です。

特に難しい作業や実験的な作業を行う場合は、localコマンドでパスを指定して直接パスを追加または削除できます。しかし、あなたが何をしているのかわからない場合は、カーネルを混乱させる可能性が非常に高いです。もちろん、カーネルは引き続き独自のパスを追加および削除するため、パスを上書きしないように注意する必要があります。table localip route

最後に、すべてのルーティングテーブルを一度に表示するには、次の手順を実行します。

# ip route show table all

詳細については、以下を確認してください。ip-rule(8)マンページまたはiproute2 ドキュメント。また試すことができます高度なルーティングおよびトラフィック制御方法できることのいくつかの例です。

おすすめ記事