问题描述

开机ifconfig有2001开头的IPv6地址,并且

ping6 ipv6.google.com

能够ping通。

但一段时间后,

ping6 ipv6.google.com

直接返回

network is unreachable

但此时ifconfig中仍然有2001开头的IPv6地址,并且似乎重启也不会一定能够再连上IPv6。

原因分析

这种情况只出现在部分网络上,可能是IPv6架构的问题。

考虑到底是哪个地方网络断了,直接

traceroute ipv6.google.com

结果发现也是直接提示

network is unreachable

起初没在意,后来仔细想想traceroute中第一跳地址会是网关,直接提示network is unreachable可能是网关都不可达?

然后等IPv6恢复了马上试了下

traceroute ipv6.google.com

第一跳很快返回,找到问题点了,网关的问题。

尝试

ip -6 route show

在IPv6可用时显示

2001:250:5002:8100::/64 dev eth0  proto kernel  metric 256
fe80::/64 dev eth0  proto kernel  metric 256
default via fe80::ae85:3dff:feb2:c0b4 dev eth0  proto ra  metric 1024  expires 821sec

然后

route -6

显示

Kernel IPv6 routing table
Destination                    Next Hop                   Flag Met Ref Use If
2001:250:5002:8100::/64        ::                         U    256 0     0 eth0
fe80::/64                      ::                         U    256 0     0 eth0
::/0                           fe80::ae85:3dff:feb2:c0b4  UGDAe 1024 0     0 eth0
::/0                           ::                         !n   -1  1    19 lo
::1/128                        ::                         Un   0   1     5 lo
2001:250:5002:8100::/128       ::                         Un   0   1     0 lo
2001:250:5002:8100::3cee/128   ::                         Un   0   1    13 lo
fe80::/128                     ::                         Un   0   1     0 lo
fe80::ba27:ebff:fe10:41e4/128  ::                         Un   0   1    23 lo
ff00::/8                       ::                         U    256 1     0 eth0
::/0                           ::                         !n   -1  1    19 lo

那个fe80::ae85:3dff:feb2:c0b4就是默认网关了。

然后等到IPv6不可用时再尝试上述命令,就再也找不到fe80::ae85:3dff:feb2:c0b4了,意味着默认网关消失了。

注意到ip -6 route show中默认网关后有expires 821sec,以及route -6中默认网关后的UGDAe,感觉找到问题在哪了。

然后在网上搜到了Flag中各个字母代表的意思:

UP U
GATEWAY G
REJECT !
HOST H
REINSTATE R
DYNAMIC D
MODIFIED M
DEFAULT d
ALLONLINK a
ADDRCONF c
NONEXTHOP o
EXPIRES e
CACHE c
FLOW f
POLICY p
LOCAL l
MTU u
WINDOW w
IRTT i
NOTCACHED n

D代表DYNAMICe代表EXPIRES。有些疑惑网关是固定地址,为啥连接时采用的有效时间为30分钟的动态形式,先不管这个。

既然是有时间限制,那就一定有更新时间的方法,而网关消失就应该是时间没有更新,症结就应该在如何让有效时间自动更新了。

直接上tcpdump抓包

抓包就不说了,东西太杂,不过关于IPv6的,倒是有Route AdvertizeICMPv6一直出现,根据之前折腾openwrt的ipv6的经验,应该就是这两个报文的问题了。

接下来就像是碰运气了,因为没有系统学习IPv6的细节,只能靠感觉找了。不过也算是我脑洞大开,直接往路由器方向找,毕竟那边折腾协议这种经验多些,很快找到了我感兴趣的:

net.ipv6.conf.all.forwarding
net.ipv6.conf.default.accept_ra

然后找到了这两个参数的详细介绍:

forwarding

Type: BOOLEAN

Default: FALSE if global forwarding is disabled (default), otherwise TRUE

Configure interface-specific Host/Router behaviour.

Note: It is recommended to have the same setting on all interfaces; mixed router/host scenarios are rather uncommon.

Value FALSE: By default, Host behaviour is assumed. This means:

IsRouter flag is not set in Neighbour Advertisements.
Router Solicitations are being sent when necessary.
If accept_ra is TRUE (default), accept Router Advertisements (and do autoconfiguration).
If accept_redirects is TRUE (default), accept Redirects.
Value TRUE: If local forwarding is enabled, Router behaviour is assumed. This means exactly the reverse from the above:

IsRouter flag is set in Neighbour Advertisements.
Router Solicitations are not sent.
Router Advertisements are ignored.
Redirects are ignored.


accept_ra

Type: BOOLEAN

Accept Router Advertisements; autoconfigure using them.

Possible values are:

0: Do not accept Router Advertisements.
1: Accept Router Advertisements if forwarding is disabled.
2: Overrule forwarding behaviour. Accept Router Advertisements even if forwarding is enabled.

解决方法就出来啦!

解决办法

编辑sysctl.conf

nano /etc/sysctl.conf

#net.ipv6.conf.all.forwarding=1

注释去掉

并添加

net.ipv6.conf.eth0.accept_ra=2

然后重启,这时就不会出现过一段时间就出现network is unreachable的情况了。

参考