IP结构与操作之inetdev_init && inetdev_destroy

inetdev_init为传入设备分配和绑定ip控制块,查看其调用关系如下:

 1 /**
 2  * fs_initcall(inet_init)
 3  * |-->inet_init
 4  *      |-->ip_init
 5  *          |-->ip_rt_init
 6  *               |-->devinet_init
 7  *                   |-->inetdev_event
 8  *                      |---->inetdev_init
 9  *                      |---->inetdev_destroy
10  */

inetdev_init && inetdev_destroy在devinet_init中注册通知链事件,在设备注册NETDEV_REGISTER和修改mtuNETDEV_CHANGEMTU时调用inetdev_init,在设备注销NETDEV_UNREGISTER时调用inetdev_destroy;

 1 /* 为指定网络设备分配并绑定ip控制块 */
 2 static struct in_device *inetdev_init(struct net_device *dev)
 3 {
 4     struct in_device *in_dev;
 5     int err = -ENOMEM;
 6 
 7     ASSERT_RTNL();
 8 
 9     /* 分配ip地址控制块 */
10     in_dev = kzalloc(sizeof(*in_dev), GFP_KERNEL);
11     if (!in_dev)
12         goto out;
13     /* 拷贝配置信息 */
14     memcpy(&in_dev->cnf, dev_net(dev)->ipv4.devconf_dflt,
15             sizeof(in_dev->cnf));
16     in_dev->cnf.sysctl = NULL;
17     /* 设置所属设备 */
18     in_dev->dev = dev;
19 
20     /*分配邻居项参数  */
21     in_dev->arp_parms = neigh_parms_alloc(dev, &arp_tbl);
22     if (!in_dev->arp_parms)
23         goto out_kfree;
24     /* 若允许转发 */
25     if (IPV4_DEVCONF(in_dev->cnf, FORWARDING))
26         /* 禁用设备的lro功能,大包不合并 */
27         dev_disable_lro(dev);
28     /* Reference in_dev->dev */
29     dev_hold(dev);
30     /* Account for reference dev->ip_ptr (below) */
31     in_dev_hold(in_dev);
32 
33     err = devinet_sysctl_register(in_dev);
34     if (err) {
35         in_dev->dead = 1;
36         in_dev_put(in_dev);
37         in_dev = NULL;
38         goto out;
39     }
40     /* 组播初始化 */
41     ip_mc_init_dev(in_dev);
42 
43     /* 设备启动,则启动组播 */
44     if (dev->flags & IFF_UP)
45         ip_mc_up(in_dev);
46 
47     /* we can receive as soon as ip_ptr is set -- do this last */
48     /* 将配置块赋值给设备ip_ptr指针 */
49     rcu_assign_pointer(dev->ip_ptr, in_dev);
50 out:
51     return in_dev ?: ERR_PTR(err);
52 out_kfree:
53     kfree(in_dev);
54     in_dev = NULL;
55     goto out;
56 }
 1 /* 销毁控制块 */
 2 static void inetdev_destroy(struct in_device *in_dev)
 3 {
 4     struct in_ifaddr *ifa;
 5     struct net_device *dev;
 6 
 7     ASSERT_RTNL();
 8 
 9     dev = in_dev->dev;
10 
11     /* 设置控制块销毁标记 */
12     in_dev->dead = 1;
13 
14     /* 销毁组播 */
15     ip_mc_destroy_dev(in_dev);
16 
17     /* 遍历ip地址列表 */
18     while ((ifa = in_dev->ifa_list) != NULL) {
19         /* 删除地址 */
20         inet_del_ifa(in_dev, &in_dev->ifa_list, 0);
21         inet_free_ifa(ifa);
22     }
23 
24     /* 设备的ip控制块赋值为NULL */
25     RCU_INIT_POINTER(dev->ip_ptr, NULL);
26 
27     /* sysctl注销 */
28     devinet_sysctl_unregister(in_dev);
29 
30     /* 释放邻居项参数 */
31     neigh_parms_release(&arp_tbl, in_dev->arp_parms);
32 
33     /* 关闭arp */
34     arp_ifdown(dev);
35 
36     /* 减少ip控制块引用 */
37     call_rcu(&in_dev->rcu_head, in_dev_rcu_put);
38 }
原文地址:https://www.cnblogs.com/wanpengcoder/p/7536599.html