主要是阅读arp相关的代码时遇到了这个函数。主要是在发送arp请求时,若产生请求的主机有多个ip地址时,通过该函数获取到最佳的ip地址。

 

 

 

 

__be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope)
{
	__be32 addr = 0;
	struct in_device *in_dev;
	struct net *net = dev_net(dev);

	rcu_read_lock();
	in_dev = __in_dev_get_rcu(dev);  //获取该设备对应的ip地址
	if (!in_dev)
		goto no_in_dev;
	/*遍历in_dev-> ifa_list地址列表中所有的primary地址*/
	for_primary_ifa(in_dev) {
		/*进行scope判断,若primary地址的scope大于传递过来的scope值,则继续循环*/
		if (ifa->ifa_scope > scope)
			continue;

/*1、若目的地址为空,则直接选择该primary ip地址
2、该primary ip地址与dst地址在同一个子网内,则将ip地址赋值给addr,程序返回*/
		if (!dst || inet_ifa_match(dst, ifa)) {
			addr = ifa->ifa_local;
			break;
		}
		/*将第一个primary ip地址作为默认选择地址*/
		if (!addr)
			addr = ifa->ifa_local;
	} endfor_ifa(in_dev);
no_in_dev:
	rcu_read_unlock();

	/*此处判断addr是否为空,若不为空,则认为找到了符合要求的ip地址,程序返回。
	找到符合要求的ip地址的可能原因:
1)	符合要求的ip地址与dst地址在同一个子网内
2)	符合要求的ip地址与dst地址不在同一个子网内,此时为该设备中第一个scope值小于指定值的primary ip
*/
	if (addr)
		goto out;

	/* Not loopback addresses on loopback should be preferred
	   in this case. It is importnat that lo is the first interface
	   in dev_base list.
	 */
	read_lock(&dev_base_lock);
	rcu_read_lock();
	/*如果在指定的设备上没有找到符合要求的ip地址,则会扩大范围,在所有的设备上查找符合要求的ip地址*/
	for_each_netdev(net, dev) {
		if ((in_dev = __in_dev_get_rcu(dev)) == NULL)
			continue;
		/*此时查找的条件已经放宽:
只要scope值小于指定的scope值,则认为找到ip地址,程序返回*/
		for_primary_ifa(in_dev) {
			if (ifa->ifa_scope != RT_SCOPE_LINK &&
			    ifa->ifa_scope <= scope) {
				addr = ifa->ifa_local;
				goto out_unlock_both;
			}
		} endfor_ifa(in_dev);
	}
out_unlock_both:
	read_unlock(&dev_base_lock);
	rcu_read_unlock();
out:
	return addr;
}


 

Logo

更多推荐