当通过输出设备向目的地址发送报文时,如果没有源地址,则需要调用inet_select_addr来选择ip地址作为源地址;
?1 /* ??2 ????选择ip地址 ??3 ??4 ????通过设备找到ip控制块,从ip控制块中遍历地址列表中的主地址, ?5 ????优先选择满足范围,满足于目的地址网络部分相同的地址, ?6 ????找不到则默认第一个满足范围的地址 ?7 ??8 ????找不到ip控制块,则走no_in_dev流程 ?9 ??*/ 10 __be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope) 11 { 12 ????__be32 addr = 0; 13 ????struct in_device *in_dev; 14 ????struct net *net = dev_net(dev); 15 ????int master_idx; 16 ?17 ????rcu_read_lock(); 18 ?19 ????/* 获取ip配置块 */ 20 ????in_dev = __in_dev_get_rcu(dev); 21 ????if (!in_dev) 22 ????????goto no_in_dev; 23 ?24 ????/* 遍历链表中的主地址 */ 25 ????for_primary_ifa(in_dev) { 26 ?????27 ????????/* 当前地址范围> 传入地址范围 28 ????????????则实际地址范围小,不满足要求 29 ????????*/ 30 ????????if (ifa->ifa_scope > scope) 31 ????????????continue; 32 ?33 ????????/* 如果未提供目的地址|| 目的地址与当前地址网络部分相同 */ 34 ????????if (!dst || inet_ifa_match(dst, ifa)) { 35 ????????????/* 设置当前地址为查找地址 */ 36 ????????????addr = ifa->ifa_local; 37 ????????????break; 38 ????????} 39 ?40 ????????/* ????如果第一次遍历到这里地址未找到, 41 ????????????则先将其默认为第一个满足范围主地址 ?42 ????????*/ 43 ????????if (!addr) 44 ????????????addr = ifa->ifa_local; 45 ????} endfor_ifa(in_dev); 46 ?47 ????/* 找到地址 */ 48 ????if (addr) 49 ????????goto out_unlock; 50 ?51 /* 没有ip控制块 */ 52 no_in_dev: 53 ?54 ????/* TODO l3mdev相关不熟 */ 55 ?56 ????/* 获取主设备id */ 57 ????master_idx = l3mdev_master_ifindex_rcu(dev); 58 ?59 ????/* For VRFs, the VRF device takes the place of the loopback device, 60 ?????* with addresses on it being preferred. ?Note in such cases the 61 ?????* loopback device will be among the devices that fail the master_idx 62 ?????* equality check in the loop below. 63 ?????*/ 64 ????/* 主设备id不为空,通过该设备id能够获取到设备, 65 ????????通过该设备能够获取到地址控制块 66 ????*/ 67 ????if (master_idx && 68 ????????(dev = dev_get_by_index_rcu(net, master_idx)) && 69 ????????(in_dev = __in_dev_get_rcu(dev))) { 70 ????????/* 选择ip地址 */ 71 ????????addr = in_dev_select_addr(in_dev, scope); 72 ????????if (addr) 73 ????????????goto out_unlock; 74 ????} 75 ?76 ????/* Not loopback addresses on loopback should be preferred 77 ???????in this case. It is important that lo is the first interface 78 ???????in dev_base list. 79 ?????*/ 80 ????/* 遍历所有设备 */ 81 ????for_each_netdev_rcu(net, dev) { 82 ?83 ????????/* 与主设备不等 */ 84 ????????if (l3mdev_master_ifindex_rcu(dev) != master_idx) 85 ????????????continue; 86 ?87 ????????/* 获取地址配置块 */ 88 ????????in_dev = __in_dev_get_rcu(dev); 89 ????????if (!in_dev) 90 ????????????continue; 91 ?92 ????????/* 获取ip地址 */ 93 ????????addr = in_dev_select_addr(in_dev, scope); 94 ????????if (addr) 95 ????????????goto out_unlock; 96 ????} 97 out_unlock: 98 ????rcu_read_unlock(); 99 ????return addr;100 }
1 /* 通过ip控制块和范围选择合适地址 */ 2 static __be32 in_dev_select_addr(const struct in_device *in_dev, 3 ?????????????????int scope) 4 { 5 ????/* 遍历该ip控制块中主地址 */ 6 ????for_primary_ifa(in_dev) { 7 ????????/* 找地址范围不是link && 范围小于输入范围的地址 */ 8 ????????if (ifa->ifa_scope != RT_SCOPE_LINK && 9 ????????????ifa->ifa_scope <= scope)10 ????????????return ifa->ifa_local;11 ????} endfor_ifa(in_dev);12 13 ????return 0;14 }
inet_select_addr
原文地址:http://www.cnblogs.com/wanpengcoder/p/7536913.html