简介
主要介绍/proc/sys/net/ipv6/conf 目录相关参数的含义说明,以及一部分的内核代码小小的分析。关于相关参数的更详细说明可见内核参考文档。
说明
/proc/sys/net/ipv6/conf/xxx 目录
| 选项 | 描述 | 备注 |
|---|---|---|
| accept_ra | 控制是否接受路由器通告(Router Advertisement)消息 | 1,接受路由器通告;0,不接受路由器通告;2,忽略forwarding配置,永远接受RA |
| accept_ra_pinfo | 控制是否使用RA消息中的前缀 | 1,接受;0,不接受 |
| accept_ra_defrtr | 控制是否使用RA消息中的默认网关 | 1,接受;0,不接受 |
| accept_ra_mtu | 控制是否使用RA消息中的MTU | 1,接受;0,不接受 |
| accept_redirects | 控制是否接受 IPv6 重定向消息 | 1,接受重定向消息; 0,不接受重定向消息 |
| autoconf | 控制是否自动配置 IPv6 地址 | 1,允许自动配置地址;0,禁止自动配置地址。 |
| disable_ipv6 | 控制是否完全禁用 IPv6 | 1,禁用 IPv6;0,启用 IPv6 |
| forwarding | 控制是否启用 IPv6 数据包转发功能 | 1,启用数据包转发; 0,禁用数据包转发 |
| hop_limit | 这个选项控制 IPv6 数据包的最大跳数 | 通常情况下,跳数限制是默认值 64。 |
| mtu | 这个选项控制 IPv6 的最大传输单元 | 指定 IPv6 数据包的最大大小。 |
| proxy_ndp | 控制是否启用 IPv6 邻居代理功能 | 1,启用邻居代理; 0,禁用邻居代理。 |
| router_probe_interval | 这个选项控制路由器探测的时间间隔 | 当一个路由器失效时,系统会定期发送路由器探测消息以检测路由器是否重新可用 |
| router_solicitations | 控制是否发送路由器请求消息。 | -1,不限制RS发送的次数;0 ,禁止发送路由器请求消息;设置为大于 0 的值则启用路由器请求消息,并设置请求的数量。 |
| dad_transmits | DAD检测的次数 | 0,则表示不进行DAD检测 |
conf/all conf/default
net/ipv6/addrconf.c中有两个全局变量ipv6_devconf和ipv6_devconf_dflt分别对应如下两个目录
/proc/sys/net/ipv6/conf/all/
/proc/sys/net/ipv6/conf/default/

这两个结构体主要是一些配置选项的初始化


而初始化的函数流程如下,重点在于addrconf_init_net函数
addrconf_init
register_pernet_subsys(&addrconf_ops);
addrconf_ops.init = addrconf_init_net
addrconf_init_net
kmemdup --> "all"
kmemdup --> "default"
__addrconf_sysctl_register "all"
__addrconf_sysctl_register "default"
函数addrconf_init_net中,kmemdup复制了两个配置,第一个配置ipv6_devconf,对应于all,第二个配置对应于默认dflt。(这里的kmemdup可以简单理解为kmalloc+memcpy)

复制后,调用__addrconf_sysctl_register函数

而__addrconf_sysctl_register函数先是对addrconf_sysctl全局变量进行复制给新变量table,然后table再更新为入参的struct ipv6_devconf *p的相关参数,这里的table[i].data += (char *)p - (char *)&ipv6_devconf没看懂是啥意思

接着就是把table中的相关参数一个一个注册到路径net/ipv6/confg/%s下,然后把table的值都赋予了入参struct ipv6_devconf *p的sysctl_header中,相当于以后要改自己接口(比如eth0)的配置项就可以通过这个sysctl_header找出来

而全局变量addrconf_sysctl则是对应着/proc/sys/net/ipv6/conf/xxx 目录下的各种内容

conf/eth0
那我们这种/proc/sys/net/ipv6/conf/eth0的目录,有自己网卡的单独配置项的是什么时候注册的呢

在函数ipv6_add_dev中创建inet6_dev时,调用addrconf_sysctl_register函数注册,然后兜兜转转还是到了前面分析的__addrconf_sysctl_register函数
ipv6_add_dev
err = addrconf_sysctl_register(ndev)
__addrconf_sysctl_register(dev_net(idev->dev), idev->dev->name,idev, &idev->cnf)
配置接口演示
以forwarding为例,可以看到其proc_handler是addrconf_sysctl_forwarding

从函数的内容可以大概分析入参write会显示这次是读还是写,而下面的proc_dointvec函数则是内核中的一个API,大概就是提取原来的目录下的数值大小。如果是write就会修改前面提到的table

因为对接口读写这块其实涉及到内核的sysctl子系统,所以就不多描述,反正就是出现问题的时候知道要去哪里找代码看即可