inetdev_init && inetdev_destroy
inetdev_init为传入设备分配和绑定ip控制块,查看其调用关系如下:
/**
* fs_initcall(inet_init)
* |-->inet_init
* |-->ip_init
* |-->ip_rt_init
* |-->devinet_init
* |-->inetdev_event
* |---->inetdev_init
* |---->inetdev_destroy
*/
inetdev_init && inetdev_destroy在devinet_init中注册通知链事件,在设备注册NETDEV_REGISTER和修改mtuNETDEV_CHANGEMTU时调用inetdev_init,在设备注销NETDEV_UNREGISTER时调用inetdev_destroy;
/* 为指定网络设备分配并绑定ip控制块 */
static struct in_device *inetdev_init(struct net_device *dev)
{
struct in_device *in_dev;
int err = -ENOMEM; ASSERT_RTNL(); /* 分配ip地址控制块 */
in_dev = kzalloc(sizeof(*in_dev), GFP_KERNEL);
if (!in_dev)
goto out;
/* 拷贝配置信息 */
memcpy(&in_dev->cnf, dev_net(dev)->ipv4.devconf_dflt,
sizeof(in_dev->cnf));
in_dev->cnf.sysctl = NULL;
/* 设置所属设备 */
in_dev->dev = dev; /*分配邻居项参数 */
in_dev->arp_parms = neigh_parms_alloc(dev, &arp_tbl);
if (!in_dev->arp_parms)
goto out_kfree;
/* 若允许转发 */
if (IPV4_DEVCONF(in_dev->cnf, FORWARDING))
/* 禁用设备的lro功能,大包不合并 */
dev_disable_lro(dev);
/* Reference in_dev->dev */
dev_hold(dev);
/* Account for reference dev->ip_ptr (below) */
in_dev_hold(in_dev); err = devinet_sysctl_register(in_dev);
if (err) {
in_dev->dead = ;
in_dev_put(in_dev);
in_dev = NULL;
goto out;
}
/* 组播初始化 */
ip_mc_init_dev(in_dev); /* 设备启动,则启动组播 */
if (dev->flags & IFF_UP)
ip_mc_up(in_dev); /* we can receive as soon as ip_ptr is set -- do this last */
/* 将配置块赋值给设备ip_ptr指针 */
rcu_assign_pointer(dev->ip_ptr, in_dev);
out:
return in_dev ?: ERR_PTR(err);
out_kfree:
kfree(in_dev);
in_dev = NULL;
goto out;
}
/* 销毁控制块 */
static void inetdev_destroy(struct in_device *in_dev)
{
struct in_ifaddr *ifa;
struct net_device *dev; ASSERT_RTNL(); dev = in_dev->dev; /* 设置控制块销毁标记 */
in_dev->dead = ; /* 销毁组播 */
ip_mc_destroy_dev(in_dev); /* 遍历ip地址列表 */
while ((ifa = in_dev->ifa_list) != NULL) {
/* 删除地址 */
inet_del_ifa(in_dev, &in_dev->ifa_list, );
inet_free_ifa(ifa);
} /* 设备的ip控制块赋值为NULL */
RCU_INIT_POINTER(dev->ip_ptr, NULL); /* sysctl注销 */
devinet_sysctl_unregister(in_dev); /* 释放邻居项参数 */
neigh_parms_release(&arp_tbl, in_dev->arp_parms); /* 关闭arp */
arp_ifdown(dev); /* 减少ip控制块引用 */
call_rcu(&in_dev->rcu_head, in_dev_rcu_put);
}
inetdev_init && inetdev_destroy的更多相关文章
- IP编址
IP地址 /include/linux/inetdevice.h,定义IPV4专用的网络设备相关的结构.宏等 /net/ipv4/devinet.c.支持IPV4特性的设备操作接口 数据组织 net_ ...
随机推荐
- [Leetcode] 2.Add Two Numbers(List To Long,模拟)
本题题意是指将两个数倒序存储在链表中,再将两数之和同样存储在链表中输出. 我最开始的思路是将每一位相加,再考虑是否进位,但这时就需要考虑一些情况,比较麻烦. 于是我决定采取另一种在网上新学到的方法:这 ...
- 在Ubuntu系统下编译arcsim仿真器
首先,用tar zxvf arcsim-0.2.1.tar.gz 将软件包解压 然后,打开里面的INSTALL文件,按照里面的步骤一步一步安装库.Ubuntu13.04下 1.BLAS sudo ap ...
- Codeforces 498B Name That Tune
不想说啥了…这是我被卡常数卡得最惨的一次… 首先根据期望的线性性,我们考虑每首歌能够被认出来的概率,也就是每首歌对答案贡献的期望.那么定义F[i]为第i首歌被认出来的概率是做不了的,自然想到F[i][ ...
- python 深浅copy的例子
1. copy.copy 浅拷贝 只拷贝父对象,不会拷贝对象的内部的子对象.2. copy.deepcopy 深拷贝 拷贝对象及其子对象一个很好的例子:import copya = [1, 2, 3, ...
- MySQL5.6之Index Condition Pushdown(ICP,索引条件下推)-Using index condition
http://blog.itpub.net/22664653/viewspace-1210844/ -- 这篇博客写的更细,以后看 ICP(index condition pushdown)是mysq ...
- 【贪心/DP/单调队列】【CF1029B】Creating the Contest
Description 给你一个单调不下降的长度为n的序列,请你找出一个最长的子序列,满足找出的子序列中,\(A_i<=A_{i-1}~\times~2\),其中i为下标,A为找出的子序列.对于 ...
- JavaScript定义类与对象的一些方法
最近偶然碰到有朋友问我"hoisting"的问题.即在js里所有变量的声明都是置顶的,而赋值则是在之后发生的.可以看看这个例子: 1 var a = 'global'; 2 (fu ...
- BZOJ1880: [Sdoi2009]Elaxia的路线(最短路)
1880: [Sdoi2009]Elaxia的路线 Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 2049 Solved: 805 题目链接:https ...
- 实体框架(Entity Framework)快速入门
实体 框架 (Entity Framework )简介 实体框架Entity Framework 是 ADO .NET 中的一组支持 开发 面向数据的软件应用程序的技术.是微软的一个ORM框架. OR ...
- nginx 静态服务器设置
一.配置Nginx [root@VM_16_15_centos nginx]# cd conf.d/ [root@VM_16_15_centos conf.d]# ll total 4 -rwxr-x ...