inet_select_addr

当通过输出设备向目的地址发送报文时,如果没有源地址,则需要调用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 }
时间: 2024-10-20 11:09:37

inet_select_addr的相关文章

ICMP:Internet控制报文协议实现学习笔记

ICMP是网络层的一个协议,可以看作IP协议的附属协议,因为它主要被IP用来与其他主机或路由器交换错误报文及其他需要注意的信息.当然,更高层协议(tcp/udp)甚至有些用户进程也可能用到ICMP报文 注册ICMP协议和ICMP协议的处理涉及以下文件: net/ipv4/icmp.c ICMP协议处理入口 net/ipv4/af_inet.c 网络层和传输层接口 ICMP报文结构 参见tcp/ip协议学习笔记(5)Internet Control Message Protocol(ICMP) 注

Linux netfilter 学习笔记 之十二 ip层netfilter的NAT模块代码分析

本节主要是分析NAT模块相关的hook函数与target函数,主要是理清NAT模块实现的原理等. 1.NAT相关的hook函数分析 NAT模块主要是在NF_IP_PREROUTING.NF_IP_POSTROUTING.NF_IP_LOCAL_OUT.NF_IP_LOCAL_IN四个节点上进行NAT操作,在上一节中我们知道nat表中只有PREROUTING.POSTROUTING.LOCAL_OUT三条链,而没有NF_IP_LOCAL_IN链,所以不能创建在LOCAL_IN hook点的SNAT

linux网络协议栈--路由流程分析

转:http://blog.csdn.net/hsly_support/article/details/8797976 来吧,路由 路由是网络的核心,是linux网络协议栈的核心,我们找个入口进去看看 还记得在笔记5-IP层的处理1中ip_rcv_finish走到过一个岔口 ->ip_rcv_finish() ->ip_route_input()  查找路由信息 ->if (iph->ihl > 5 && ip_rcv_options(skb)) 如果IP头部

IP编址

IP地址 /include/linux/inetdevice.h,定义IPV4专用的网络设备相关的结构.宏等 /net/ipv4/devinet.c,支持IPV4特性的设备操作接口 数据组织 net_device结构中包含了驱动相关的所有信息,先按分类把同一类型的信息组织到其他结构中,然后嵌套到net_device结构中.例如,与ipv4相关的配置存放在in_device结构中,IP地址.子网掩码.广播地址等信息存放到in_ifaddr结构中等 相关函数 inetdev_init()     为