問題現象:ping xxxx 提示
# ping 121.10.41.62
PING 121.10.41.62 (121.10.41.62) 56(84) bytes of data.
From 14.116.225.5: icmp_seq=2 Destination Host Unreachable
首先要明白 Destination Host Unreachable 代表了什么??
說明了:"沒有跟對方建立連接";此鏈接並非tcp的鏈接
那怎么排查呢?
1、首先查看路由是否正確有沒有;通過netstat -rn route -nv ip route 等命令查看 ping 41.62 地址時 需要的路由是否正確
根據路由結果 此時報文應該走默認路由 出去 ;
查看ip neigh arp -nv 默認路由鄰居表項存在
2、路由route 以及neigh 都存在 為什么還是出現這個錯誤呢?
那就只能從頭到位排查了:
- 首先ping lo 查看tcp/ip 協議棧是否正確
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data. 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.033 ms 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.025 ms
- ping ethx 接口ip 同一個網段的地址;也能通 說明此時接口設備驅動沒問題,報文能發送出去也能收包
Tcp/ip 協議棧 dev 設備驅動都是正常 路由 neighbour 也是正常----怎么還是有問題??
難道是查看的東西 使用的工具有問題?
在回頭想一下: ping lo 證明了協議棧沒問題 ping dev 說明驅動基本ok;
route -nv 說明有了路由---------有了路由 報文就會從這個路由走嗎??
萬一是從別的路由走呢???
所以通過ip route get 121.10.41.62 發現其路由 via 是個莫名其妙的地址
同時查看ip neigh 發現有這個莫名其妙的地址對應的 表項;不過此表項為failed;
所以此時就能解釋通了:ping 此ip 地址提示Destination Host Unreachable。
報文查找路由的時候出現錯誤,找到錯誤的出口路由ip;此時路由出口IP的arp 表項不存在
所以導致了 上述錯誤!!
那么后續需要處理的問題時---為什么出現上述錯誤:路由查找錯誤?
$ip route get 121.10.41.62 121.10.41.62 via 10.16.143.108 dev eth8 src 14.116.225.5 cache ipid 0x0bca rtt 186ms rttvar 144ms ssthresh 51 cwnd 46 reordering 9
這里面有個比較好的工具: ip route get xxx 可以直接查找其對應的路由
相關命令有:
- ip route show cache
- ip route flush cache
- ip route list/show
- ip neigh
- ip addr
- ip link
ip 命令和ifconfig route arp 等命令相似並且包含它們的功能---可以好好研究一下
現在來詳細看下為什么會提示Destination Host Unreachable;
協議棧封包時 ;ip層報文處理完后,需要填充對應的mac 地址; 所以需要根據目的出口Ip來填充mac,由於出口路由via 是 10.16.143.108 ;
1、發出arp req報文請求此ip 地址對應的mac 地址;
2、發出arp 請求報文后,等待arp 應答報文,如果超時 就會調用
neigh_timer_handler---->neigh_invalidate--->
neigh->ops->error_report(arp_error_report)
---->dst->ops->link_failure(skb);---->ipv4_link_failure
---->kfree_skb
[752934.081279] [<ffffffff8151cd99>] ipv4_link_failure+0x1d/0x70 [752934.081281] [<ffffffff8154436b>] arp_error_report+0x30/0x3c [752934.081284] [<ffffffff814dc741>] neigh_invalidate+0x4b/0x7e [752934.081286] [<ffffffff814dd2b0>] neigh_timer_handler+0x181/0x258 [752934.081289] [<ffffffff81054497>] run_timer_softirq+0x16e/0x200 [752934.081292] [<ffffffff814dd12f>] ? neigh_update+0x3c4/0x3c4
這里主要看下:ipv4_link_failure
static void ipv4_link_failure(struct sk_buff *skb) { struct rtable *rt; icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0); rt = skb_rtable(skb); if (rt) dst_set_expires(&rt->dst, 0); }
這也就是: 通過發送icmp報文提示 dest/host unreach
此時 源地址就是arp 發送使用的source ip
ping 10.67.10.173 PING 10.67.10.173 (10.67.10.173) 56(84) bytes of data. From 10.67.10.174 icmp_seq=1 Destination Host Unreachable From 10.67.10.174 icmp_seq=5 Destination Host Unreachable From 10.67.10.174 icmp_seq=6 Destination Host Unreachable From 10.67.10.174 icmp_seq=7 Destination Host Unreachable From 10.67.10.174 icmp_seq=11 Destination Host Unreachable From 10.67.10.174 icmp_seq=12 Destination Host Unreachable From 10.67.10.174 icmp_seq=13 Destination Host Unreachable
tcpdump -i lo icmp -ne tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes 06:40:42.484220 00:00:00:00:00:00 > 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 126: 10.67.10.174 > 10.67.10.174: ICMP host 10.67.10.173 unreachable, length 92 06:40:45.484218 00:00:00:00:00:00 > 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 126: 10.67.10.174 > 10.67.10.174: ICMP host 10.67.10.173 unreachable, length 92 06:40:45.484226 00:00:00:00:00:00 > 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 126: 10.67.10.174 > 10.67.10.174: ICMP host 10.67.10.173 unreachable, length 92 06:40:48.484220 00:00:00:00:00:00 > 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 126: 10.67.10.174 > 10.67.10.174: ICMP host 10.67.10.173 unreachable, length 92 06:40:51.484219 00:00:00:00:00:00 > 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 126: 10.67.10.174 > 10.67.10.174: ICMP host 10.67.10.173 unreachable, length 92 06:40:51.484225 00:00:00:00:00:00 > 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 126: 10.67.10.174 > 10.67.10.174: ICMP host 10.67.10.173 unreachable, length 92
可以看到 eth1 接口ip 為10.67.10.174 時 去ping 一個不存在主機的ip 10.67.10.173 ;
在lo 接口上抓包;可以看到對應的icmp 報文;
報文如下:


也就是 icmp報文中 的控制信息中會帶上觸發這個icmp報文的原始報文
