最近在弄IPV6时,发现一个问题,在pppoe接入时,ppp接口不发RS请求,因为ppp接入时,上级的RADVD是配置为单播的,不会发送广播RA,导致路由器无法获取前缀。
在UBUNTU主机上测试了一下,发现ifconfig down和up接口都不会发送RS请求,这着实很奇怪。
最后偶然发现,这是由于打开了IPV6的转发导致,即cat /proc/sys/net/ipv6/conf/all/forwarding为1。在下图中看到:
当开启了forwarding之后,就不再往外发送RS请求。可能内核觉得开了转发表示我自己就是路由器了,那我还发什么RS来请求路由呢。
所以要解决这个问题,需要修改内核发送RS处的逻辑,如何修改可以看下addrconf.c和ndisc.c两个文件的逻辑大概就可以知道如何改了。这里略过。下面说下,内核何时会发送RS(下面是pppoe拨号时的逻辑)?
内核何时会发送RS
首先ipv6cp阶段双方会确认一个UID,然后pppd进程就会根据这个uid配置链路本地地址,应用层配置地址会触发内核inet6_addr_add >> addrconf_dad_start >> addrconf_dad_completed >> ndisc_send_rs
这里就会发出第一个RS包,并设置定时器,定时器的时间和发包次数可以通过proc配置。如果收到了回复,那么就退出定时器,不再发送RS。
收RA包是在ndisc_rcv >> ndisc_router_discovery处理,里面会解析option信息,标志位,根据前缀配置地址,配置默认路由。
vlan2接口的RS什么时候发呢,差不了太多,是在vlan2起接口配置链路本地地址时发的,只是它是走addrconf_add_linklocal函数。注意:给接口配置链路本地地址才会触发内核发送RS报文。但内核会一直正确处理收到的RA。