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的更多相关文章

  1. IP编址

    IP地址 /include/linux/inetdevice.h,定义IPV4专用的网络设备相关的结构.宏等 /net/ipv4/devinet.c.支持IPV4特性的设备操作接口 数据组织 net_ ...

随机推荐

  1. 如何设计好的RESTful API之安全性

    保证RESTful API的安全性,主要包括三大方面: a) 对客户端做身份认证 b) 对敏感的数据做加密,并且防止篡改 c) 身份认证之后的授权 1.对客户端做身份认证,有几种常见的做法: 1)在请 ...

  2. vmware 虚拟机下安装centOS7.0

    当时安装的是 CentOS-7.0-1406-x86_64-DVD.iso 这个版本的镜像,提示: 您已经配置此虚拟机使用64位客户操作系统.但是64位操作系统不可用.此主机具有虚拟化支持能力的,可是 ...

  3. 【bzoj1708】[USACO2007 Oct]Money奶牛的硬币 背包dp

    题目描述 在创立了她们自己的政权之后,奶牛们决定推广新的货币系统.在强烈的叛逆心理的驱使下,她们准备使用奇怪的面值.在传统的货币系统中,硬币的面值通常是1,5,10,20或25,50,以及100单位的 ...

  4. HTML5 应用程序缓存

    使用HTML5,通过创建 cache manifest 文件,可以轻松创建web应用的离线缓存.   什么事应用程序缓存? HTML5引入了应用程序缓存,这意味着 web 应用可进行缓存,并在没有因特 ...

  5. BZOJ4871 Shoi2017摧毁“树状图”(树形dp)

    设f[i][0/1/2/3/4/5]表示i子树中选一条链不包含根/i子树中选一条链包含根但不能继续向上延伸/i子树中选一条链可以继续向上延伸/选两条链不包含根/选两条链包含根但不能继续向上延伸/选两条 ...

  6. 一条数据的HBase之旅,简明HBase入门教程-Write全流程

    如果将上篇内容理解为一个冗长的"铺垫",那么,从本文开始,剧情才开始正式展开.本文基于提供的样例数据,介绍了写数据的接口,RowKey定义,数据在客户端的组装,数据路由,打包分发, ...

  7. 洛谷 P3119 [USACO15JAN]草鉴定Grass Cownoisseur 解题报告

    P3119 [USACO15JAN]草鉴定Grass Cownoisseur 题目描述 约翰有\(n\)块草场,编号1到\(n\),这些草场由若干条单行道相连.奶牛贝西是美味牧草的鉴赏家,她想到达尽可 ...

  8. BZOJ1898: [Zjoi2005]Swamp 沼泽鳄鱼(矩阵乘法)

    1898: [Zjoi2005]Swamp 沼泽鳄鱼 题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1898 Description 潘塔 ...

  9. ubuntu14安装tensorflow并测试

    1.ubuntu版本的选择:看了很多博文,建议使用ubuntu14,稳定兼容性好. 2.tensorflow的安装: http://wiki.jikexueyuan.com/project/tenso ...

  10. POJ 3984 BFS

    迷宫问题 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 20665   Accepted: 12100 Descriptio ...