IP结构与操作之inet_confirm_addr && confirm_addr_indev

确认给定参数范围的ip地址是否存在;

 1 /*
 2  * Confirm that local IP address exists using wildcards:
 3  * - net: netns to check, cannot be NULL
 4  * - in_dev: only on this interface, NULL=any interface
 5  * - dst: only in the same subnet as dst, 0=any dst
 6  * - local: address, 0=autoselect the local address
 7  * - scope: maximum allowed scope value for the local address
 8  */
 9 
10 /* 
11     确认参数中给定的本地地址是否存在 
12     net: net命名空间,不能为空
13     in_dev: 在此ip控制块上,空表示任何设备上的控制块
14     dst: 与dst在同一子网,0表示不限制
15     local: 本地地址,0表示自动选择本地地址
16     scope: 本地地址最大允许的地址范围
17 */
18 
19 __be32 inet_confirm_addr(struct net *net, struct in_device *in_dev,
20              __be32 dst, __be32 local, int scope)
21 {
22     __be32 addr = 0;
23     struct net_device *dev;
24 
25     /* ip控制块存在,则从该控制块中选择地址 */
26     if (in_dev)
27         return confirm_addr_indev(in_dev, dst, local, scope);
28 
29     rcu_read_lock();
30     /* ip控制块不存在,则遍历所有设备 */
31     for_each_netdev_rcu(net, dev) {
32         /* 找到设备中的ip控制块 */
33         in_dev = __in_dev_get_rcu(dev);
34 
35         /* 如果ip控制块存在 */
36         if (in_dev) {
37             /* 从该控制块选择地址 */
38             addr = confirm_addr_indev(in_dev, dst, local, scope);
39             /* 找到则结束 */
40             if (addr)
41                 break;
42         }
43     }
44     rcu_read_unlock();
45 
46     return addr;
47 }

 

 1 /*
 2     从指定ip控制块中获取参数允许范围内的地址
 3     1. local dst都不在,找一个满足范围的ip
 4     2. local存在,dst不存在,找与local相等的满足范围的ip
 5     3. local不存在,dst存在,找满足范围的与dst在同一子网的ip
 6     4. local dst都存在,找与local相等,并且与dst在同一子网的ip
 7 */
 8 static __be32 confirm_addr_indev(struct in_device *in_dev, __be32 dst,
 9                   __be32 local, int scope)
10 {
11     int same = 0;
12     __be32 addr = 0;
13 
14     /* 遍历地址列表 */
15     for_ifa(in_dev) {
16 
17         if (!addr && /* 目标地址为空 */
18             (local == ifa->ifa_local || !local) && /* 本地地址相等或者参数地址为空 */
19             ifa->ifa_scope <= scope) { /* 当前地址满足<= 参数地址范围 */
20             /* 找到目标地址 */
21             addr = ifa->ifa_local;
22 
23             /* 满足子网要求 */
24             if (same)
25                 break;
26         }
27 
28         /* 未判断子网是否相同 */
29         if (!same) {
30             /* local dst不要求,或者在同一子网 */
31             same = (!local || inet_ifa_match(local, ifa)) &&
32                 (!dst || inet_ifa_match(dst, ifa));
33 
34             /* 满足子网要求且地址存在,则具体判断是哪种情况 */
35             if (same && addr) {
36 
37                 /* local存在或者local和dst都不存在 */
38                 if (local || !dst)
39                     break;
40 
41                 /* local不存在,dst存在 */
42                 
43                 /* Is the selected addr into dst subnet? */
44                 /* 目标地址与dst在同一子网 */
45                 if (inet_ifa_match(addr, ifa))
46                     break;
47 
48                 /* 目标地址与dst不在同一子网 */
49                 
50                 /* No, then can we use new local src? */
51                 /* 如果ifa满足范围,则使用这个ifa的地址 */
52                 if (ifa->ifa_scope <= scope) {
53                     addr = ifa->ifa_local;
54                     break;
55                 }
56 
57                 /* 查找失败,继续查找 */
58                 
59                 /* search for large dst subnet for addr */
60                 same = 0;
61             }
62         }
63     } endfor_ifa(in_dev);
64 
65     return same ? addr : 0;
66 }

 

posted @ 2017-09-17 21:01  AlexAlex  阅读(595)  评论(0编辑  收藏  举报