はじめに
Applicationが送信先IP Addressを指定すると、LinuxはRouting Tableを使ってPacketをどこへ送るか判断します。しかしEthernetで実際にFrameを送るには、次に渡す相手であるNext HopのMAC Addressも必要です。
同一Subnet宛てならDestination Host自身がNext Hopになり、別Subnet宛てなら通常GatewayがNext Hopになります。IPv4ではARP、IPv6ではNeighbor DiscoveryによってNext HopのLink Layer Addressを解決します。
本記事ではRoute LookupからNeighbor解決、Ethernet Frame送信までをつなげ、同一Subnetと別Subnetの違い、Linux上での確認方法、よくある障害を解説します。
Routingとは
RoutingはDestination IP Addressに基づいてPacketの経路を選ぶ仕組みです。LinuxはHostとして自分のPacketを送るだけでなく、IP Forwardingが有効ならRouterとしてInterface間でPacketを転送できます。

RoutingはIP Layerの判断です。Routeが決まった後、EthernetなどのLink LayerでNext Hopへ渡すためにNeighbor情報を利用します。「最終Destination IP」と「次にFrameを渡すNext Hop」を分けて考えることが重要です。
Routing Tableの見方
ip route show
| 項目 | 意味 |
|---|---|
| Destination | Routeが対象とするNetwork Prefix |
| via | Next Hop Gateway |
| dev | Output Interface |
| src | 推奨されるSource Address |
| metric | 同じPrefix Lengthなど、競合するRoute間の優先度判断に使われる値。一般に小さい値が優先される |
| scope | Routeが有効な範囲 |
| proto | Routeを追加した起源 |
この例では、192.0.2.0/24がeth0に接続されており、より具体的なRouteに一致しないDestinationへのPacketは、Default Gateway 192.0.2.1を経由してeth0から送信されます。
Route Lookupの仕組み
複数のRouteがDestinationに一致する場合、基本となる考え方は最も長いPrefixに一致するRouteを選ぶLongest Prefix Matchです。たとえば10.0.0.25はdefault、10.0.0.0/8、10.0.0.0/24のすべてに一致しますが、より具体的な/24が優先されます。
Destination: 10.0.0.25
0.0.0.0/0 → 一致
10.0.0.0/8 → 一致
10.0.0.0/24 → 最長Prefixのため選択
実際のLinuxでは、Policy Routing Rule(ip rule)を優先順に評価し、Ruleで指定されたRouting Tableを参照してRoute Lookupを行います。Source Address、fwmark、Interfaceなどを条件に、異なるRouting Tableを参照する構成もあります。
ip route getは特定Destinationに対する実際のLookup結果を確認するのに適しています。必要に応じてfromでSource Addressを指定し、Multi-homed Hostの経路を確認します。

この例では、8.8.8.8宛のPacketは、Gateway 192.0.2.1を経由し、eth0からSource IP 192.0.2.10で送信されます。
Default Gatewayとは
Default Gatewayは、より具体的なRouteがないDestinationへPacketを渡すNext Hop Routerです。IPv4のDefault Routeは0.0.0.0/0、IPv6では::/0で表されます。
Gatewayは原則としてOutput InterfaceからLink Layerで到達できる必要があります。GatewayへFrameを送れなければ、その先のNetworkへPacketを転送できません。Default Gatewayが設定されていても、Neighbor解決やSwitch経路が正常とは限りません。

ARPとは
ARPはIPv4 Addressに対応するMAC Addressを同一Link上で調べるProtocolです。送信側は「このIPv4 Addressを持つHostは誰か」というARP RequestをBroadcastし、該当Hostが自身のMAC AddressをARP Replyで返します。

ARPはRouterを越えて最終DestinationのMAC Addressを調べる仕組みではありません。別Subnet宛てでは、LinuxはNext HopであるGatewayのIPv4 AddressについてARPを行います。
Neighbor Tableとは
Linuxは解決したIP AddressとLink Layer Addressの対応をNeighbor TableへCacheします。IPv4のARP CacheもLinuxのNeighbor Subsystemで管理されるため、ip neighborでIPv4 / IPv6のNeighbor Entryを共通して確認できます。
各ステートの意味は以下の通りです。
| State | 概要 |
|---|---|
| INCOMPLETE | Address解決を実行中 |
| REACHABLE | 到達可能と確認されている |
| STALE | Entryはあるが最近の到達確認がない |
| DELAY | 到達確認を遅延している |
| PROBE | 到達性を能動的に確認している |
| FAILED | Address解決または到達確認に失敗した |
| PERMANENT | 管理者が固定的に設定したEntry |
STALEは直ちに障害を意味しません。次に通信すると到達性確認へ進みます。INCOMPLETEやFAILEDが続く場合は、相手Host、VLAN、Subnet Mask、Switch Port、FirewallによるARP / NDP制限などを確認します。
Neighbor Tableは、ip neigh show コマンドを実行することで確認可能です。

この例では、eth0上のIP Addressに対応するMAC Address(lladdr)と、そのNeighborの状態が表示されています。REACHABLEは最近到達可能であることが確認された状態、STALEはEntryは存在するものの、最近の到達可能性が確認されていない状態を示します。
同一Subnetへの通信
同一Subnetと判断するとGatewayを経由せず、Destination Host自身をNext Hopとして扱います。IP HeaderのDestinationは192.168.1.20、Ethernet HeaderのDestination MACも192.168.1.20に対応するMAC Addressになります。

Subnet Maskが誤っていると、Remote Networkの相手を同一Link上と判断してARPを繰り返すことがあります。IP AddressだけでなくPrefix Lengthも確認することが重要です。
別Subnetへの通信
IP HeaderのDestinationは10.0.0.20のままですが、最初のEthernet FrameのDestination MACはGatewayである192.168.1.1のMAC Addressです。Destination ServerのMAC AddressをLocal HostがARPで調べるわけではありません。

GatewayはFrameを受け取り、IP Headerを見て次のRouteを選択します。次のLink用に新しいEthernet Headerを作って転送します。各RouterでLayer 2 Headerは変わりますが、NATなどがなければDestination IP Addressは維持されます。
Ethernet Frameを作って送信する
RouteとNeighbor Entryが決まると、LinuxはNext Hopへ送るためのLink Layer Headerを関連付けます。EthernetではSource MACにOutput InterfaceのMAC Address、Destination MACにNext HopのMAC Addressを設定します。

Neighbor解決中は、対象Packetが一時的にQueueされる場合があります。解決できれば送信し、失敗すればDropや到達不能Errorにつながります。Queue量には上限があります。
IPv6ではNDPを利用する
IPv6ではARPを使わず、ICMPv6を基盤とするNeighbor Discovery Protocolを利用します。Neighbor SolicitationとNeighbor AdvertisementによってIPv6 AddressとLink Layer Addressの対応を解決します。
NDPはAddress解決だけでなく、Router Discovery、Prefix情報、Neighbor Unreachability Detection、Duplicate Address Detectionなどにも関係します。ICMPv6を広く遮断するとIPv6通信の基本機能を壊す可能性があります。
LinuxでRoutingとNeighborを確認する
RoutingとNeighborの確認に関連するコマンドを紹介します。
| コマンド | 主に確認できること |
|---|---|
ip address show | Interfaceに設定されているIPv4 / IPv6 AddressやInterfaceの状態 |
ip route show | IPv4のRouting Table。Destination、Gateway、Output Interface、Source Addressなど |
ip -6 route show | IPv6のRouting Table |
ip rule show | Policy RoutingのRule。どの条件でどのRouting Tableを参照するか |
ip route get 10.0.0.20 | 10.0.0.20宛に実際に選択されるRoute、Next Hop、Output Interface、Source Address |
ip route get 10.0.0.20 from 192.168.1.10 | Source Addressを192.168.1.10に指定した場合に選択されるRoute |
ip neighbor show | IPv4 / IPv6のNeighbor Table。IP AddressとMAC Address、Neighbor Stateの対応 |
ip -4 neighbor show | IPv4のNeighbor Entry(ARP Cache) |
ip -6 neighbor show | IPv6のNeighbor Table。NDPで解決されたIPv6 AddressとMAC Addressなど |
tcpdump -i enp1s0 -nn arp | enp1s0を流れるARP Request / ReplyをCapture |
tcpdump -i enp1s0 -nn 'icmp6' | enp1s0を流れるICMPv6をCapture。NDPのNS / NAなどの確認にも利用可能 |
Routing障害はRoute → Neighbor → Packetの順に確認する
障害調査では、まずip route getで実際に選択されるRoute、Output Interface、Next Hopを確認します。次にip neighborでNext HopのMAC AddressとNeighbor Stateを確認し、必要に応じてtcpdumpでARP Request / ReplyまたはNDP Messageを観察します。

Neighbor Entryを手動削除すると再解決を発生させられますが、進行中の通信へ影響する可能性があります。Production環境では対象InterfaceとIP Addressを正確に確認し、必要性と影響を評価してから実行します。
よくあるNetwork障害
| 現象 | 主な確認 |
|---|---|
| No route to host | Route、Policy Rule、Interface状態、Errorの発生元 |
| 想定外のInterfaceから送信 | Longest Prefix、Metric、Policy Routing |
| ARP RequestへReplyがない | Subnet、VLAN、相手Host、Switch、Security設定 |
| NeighborがFAILED | Next Hopの到達性とAddress重複 |
| Gatewayへは届くがRemoteへ届かない | Gateway以降のRoute、Firewall、戻り経路 |
| 片方向だけ通信できる | Asymmetric Routing、Reverse Path Filter、Firewall |
pingの成功だけでTCP Application通信が正常とは判断できません。逆にICMP Echoが制限されていてもTCPは成功する場合があります。対象ProtocolとPortを使って確認し、Routing、Neighbor、Packet Captureを組み合わせます。
まとめ
LinuxのPacket送信では、まずRoute LookupによってOutput Interface、Source Address、Next Hopを決定します。同一SubnetではDestination Host自身、別Subnetでは通常GatewayがNext Hopになります。
次にIPv4ではARP、IPv6ではNDPを使ってNext HopのLink Layer Addressを解決し、Ethernet Headerを付けてFrameを送信します。別Subnetへの通信でも、最終Destination IP Addressと最初にFrameを渡すNext Hopは別々に考えることが重要です。
障害調査では、ip route get → ip neighbor → tcpdumpの順で確認すると、Routeの問題なのか、Neighbor解決の問題なのか、実際のPacket送受信の問題なのかを切り分けやすくなります。
Linuxにおけるネットワークの仕組みについては、以下の書籍にまとめています。興味がありましたら、ぜひ読んでみてください。
Linuxのネットワークの仕組みを
図解で理解したい方へ
Socket・TCP・ルーティング・NIC 現場で役立つ通信処理の基礎知識など Linuxにおけるネットワークの仕組みを図解を中心にわかりやすく解説しています。
Kindleで書籍を見る →


コメント