Android有线IPV6总结(二):内核中RS与RA的一点学习

RS:Router Solicitation路由器请求

RA:Router Advertisement路由器公告

 

在Android系统中我们想要打开一个网络接口(比如eth0)的ipv6功能,用命令的话我们有如下两种办法:

1,echo 0 > /proc/sys/net/ipv6/conf/eth0/disable_ipv6

直接读写的内核proc文件

2,ndc interface ipv6 eth0 enable

用ndc命令,最终也是写内核proc文件

 

如上的操作proc文件就是触发网络终端发送RS报文的方式,接下来就记录一下内核中对应的代码流程:

写disable_ipv6文件对应的文件系统函数为:

addrconf_sysctl_disable

static
int addrconf_sysctl_disable(struct ctl_table *ctl, int write,
                            void __user *buffer, size_t *lenp, loff_t *ppos)
{
        int *valp = ctl->data;
        int val = *valp;
        loff_t pos = *ppos;
        struct ctl_table lctl;
        int ret;

        /*
         * ctl->data points to idev->cnf.disable_ipv6, we should
         * not modify it until we get the rtnl lock.
         */
        lctl = *ctl;
        lctl.data = &val;

        ret = proc_dointvec(&lctl, write, buffer, lenp, ppos);

        if (write)
                ret = addrconf_disable_ipv6(ctl, valp, val);
        if (ret)
                *ppos = pos;
        return ret;
}

接下来进入addrconf_disable_ipv6

static int addrconf_disable_ipv6(struct ctl_table *table, int *p, int newf)
{
        struct net *net;
        int old;

        if (!rtnl_trylock())
                return restart_syscall();

        net = (struct net *)table->extra2;
        old = *p;
        *p = newf;
        //如果值不变则不作处理
        if (p == &net->ipv6.devconf_dflt->disable_ipv6) {
                rtnl_unlock();
                return 0;
        }

        if (p == &net->ipv6.devconf_all->disable_ipv6) {
                net->ipv6.devconf_dflt->disable_ipv6 = newf;
                addrconf_disable_change(net, newf);
        } else if ((!newf) ^ (!old)) //如果值发生变化则作处理
                dev_disable_change((struct inet6_dev *)table->extra1);

        rtnl_unlock();
        return 0;
}

接下来进入dev_disable_change

static void dev_disable_change(struct inet6_dev *idev)
{
        struct netdev_notifier_info info;

        if (!idev || !idev->dev)
                return;

        netdev_notifier_info_init(&info, idev->dev);
        if (idev->cnf.disable_ipv6)
                addrconf_notify(NULL, NETDEV_DOWN, &info);  //关闭ipv6
        else
                addrconf_notify(NULL, NETDEV_UP, &info);  //开启ipv6
}

这里只看开启ipv6,所以接下来看addrconf_notify对NETDEV_UP的处理

        case NETDEV_UP:
        case NETDEV_CHANGE:
                if (dev->flags & IFF_SLAVE)
                        break;

                if (idev && idev->cnf.disable_ipv6)
                        break;

                if (event == NETDEV_UP) {  //NETDEV_UP
                        if (!addrconf_qdisc_ok(dev)) {
                                /* device is not ready yet. */
                                pr_info("ADDRCONF(NETDEV_UP): %s: link is not ready\n",
                                        dev->name);
                                break;
                        }

                        if (!idev && dev->mtu >= IPV6_MIN_MTU)
                                idev = ipv6_add_dev(dev);  //将dev加入ipv6协议栈

                        if (!IS_ERR_OR_NULL(idev)) {
                                idev->if_flags |= IF_READY;
                                run_pending = 1;
                        }
                } else {
                        if (!addrconf_qdisc_ok(dev)) {
                                /* device is still not ready. */
                                break;
                        }

                        if (idev) {
                                if (idev->if_flags & IF_READY)
                                        /* device is already configured. */
                                        break;
                                idev->if_flags |= IF_READY;
                        }

                        pr_info("ADDRCONF(NETDEV_CHANGE): %s: link becomes ready\n",
                                dev->name);

                        run_pending = 1;
                }
                switch
  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值