源设备的选择
源地址的选择
一个网卡可能配有多个ip地址,在发包流程中,如果源地址没有显示指定的话,会通过
inet_select_addr选择源地址:
-
__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);
-
if (!in_dev)
-
goto no_in_dev;
-
-
for_primary_ifa(in_dev) {
-
if (ifa->ifa_scope > scope)
-
continue;
-
if (!dst || inet_ifa_match(dst, ifa)) {
-
addr = ifa->ifa_local;
-
break;
-
}
-
if (!addr)
-
addr = ifa->ifa_local;
-
} endfor_ifa(in_dev);
-
-
if (addr)
-
goto out_unlock;
-
no_in_dev:
-
-
/* Not loopback addresses on loopback should be preferred
-
in this case. It is importnat that lo is the first interface
-
in dev_base list.
-
*/
-
for_each_netdev_rcu(net, dev) {
-
in_dev = __in_dev_get_rcu(dev);
-
if (!in_dev)
-
continue;
-
-
for_primary_ifa(in_dev) {
-
if (ifa->ifa_scope != RT_SCOPE_LINK &&
-
ifa->ifa_scope <= scope) {
-
addr = ifa->ifa_local;
-
goto out_unlock;
-
}
-
} endfor_ifa(in_dev);
-
}
-
out_unlock:
-
rcu_read_unlock();
-
return addr;
-
}
其中scope定义如下 :
-
enum rt_scope_t {
-
RT_SCOPE_UNIVERSE=0,
-
/* User defined values */
-
RT_SCOPE_SITE=200,
-
RT_SCOPE_LINK=253,
-
RT_SCOPE_HOST=254,
-
RT_SCOPE_NOWHERE=255
-
}
网卡对应的ip信息存在in_device数据结构中:
-
struct in_device {
-
struct net_device *dev;
-
atomic_t refcnt;
-
int dead;
-
struct in_ifaddr *ifa_list; /* IP ifaddr chain */
-
struct ip_mc_list __rcu *mc_list; /* IP multicast filter chain */
-
int mc_count; /* Number of installed mcasts */
-
spinlock_t mc_tomb_lock;
-
struct ip_mc_list *mc_tomb;
-
unsigned long mr_v1_seen;
-
unsigned long mr_v2_seen;
-
unsigned long mr_maxdelay;
-
unsigned char mr_qrv;
-
unsigned char mr_gq_running;
-
unsigned char mr_ifc_count;
-
struct timer_list mr_gq_timer; /* general query timer */
-
struct timer_list mr_ifc_timer; /* interface change timer */
-
-
struct neigh_parms *arp_parms;
-
struct ipv4_devconf cnf;
-
struct rcu_head rcu_head;
-
}
-
struct in_ifaddr {
-
struct hlist_node hash;
-
struct in_ifaddr *ifa_next;
-
struct in_device *ifa_dev;
-
struct rcu_head rcu_head;
-
__be32 ifa_local;
-
__be32 ifa_address;
-
__be32 ifa_mask;
-
__be32 ifa_broadcast;
-
unsigned char ifa_scope;
-
unsigned char ifa_flags;
-
unsigned char ifa_prefixlen;
-
char ifa_label[IFNAMSIZ];
-
}
选择源地址主要基于两条:范围要大于传入的参数,即值要小于;属于同一个子网
ip地址存在
in_ifaddr 数据结构中,如下:
-
root@:/opt/module/net/udp# ip addr
-
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
-
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
-
inet 127.0.0.1/8 scope host lo
-
inet6 ::1/128 scope host
-
valid_lft forever preferred_lft forever
-
2: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast state DOWN qlen 1000
-
link/ether 60:eb:69:45:29:1b brd ff:ff:ff:ff:ff:ff
-
inet 10.1.2.3/24 brd 10.1.2.255 scope global eth0
-
inet 11.1.2.3/24 brd 11.1.2.255 scope global eth0:1
-
inet 128.1.2.3/16 brd 128.1.255.255 scope global eth0:2
-
inet6 fe80::62eb:69ff:fe45:291b/64 scope link
-
valid_lft forever preferred_lft forever
-
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
-
link/ether 1c:65:9d:2c:fe:f7 brd ff:ff:ff:ff:ff:ff
-
inet 192.168.1.109/24 brd 192.168.1.255 scope global wlan0
-
inet6 fe80::1e65:9dff:fe2c:fef7/64 scope link
-
valid_lft forever preferred_lft forever
-
for_each_netdev(&init_net, dev_tmp){
-
struct in_device *in_dev;
-
struct in_ifaddr *ifa;
-
in_dev = __in_dev_get_rcu(dev_tmp);
-
if (!in_dev)
-
return 0;
-
for (ifa = (in_dev)->ifa_list; ifa ; ifa = ifa->ifa_next)
-
printk("dev=%s,ip=%x,name=%s,scope=%d\n",dev_tmp->name,ifa->ifa_address,ifa->ifa_label,ifa->ifa_scope);
-
-
-
}
输出:
-
[ 3452.341006] dev=lo,ip=100007f,name=lo,scope=254
-
[ 3452.341014] dev=eth0,ip=302010a,name=eth0,scope=0
-
[ 3452.341017] dev=eth0,ip=302010b,name=eth0:1,scope=0
-
[ 3452.341021] dev=eth0,ip=3020180,name=eth0:2,scope=0
-
[ 3452.341025] dev=wlan0,ip=6d01a8c0,name=wlan0,scope=0
阅读(1813) | 评论(0) | 转发(0) |