ping www.baidu.com, ip_route_output_flow returns ffff880c834f6900
crash> rtable ffff880c834f6900
struct rtable {
dst = {
callback_head = {
next = 0xffff880c834f7b00,
func = 0x0
},
child = 0x0,
dev = 0xffff880c7ec18000,
ops = 0xffffffff81cd8640 <ipv4_dst_ops>,
_metrics = 0xffffffff818c2301,
expires = 0x0,
path = 0xffff880c834f6900,
from = 0x0,
xfrm = 0x0,
input = 0xffffffff816117b0 <dst_discard>,
output = 0xffffffff81655330 <ip_output>,
flags = 0x0,
error = 0x0,
obsolete = 0xffff,
header_len = 0x0,
trailer_len = 0x0,
__pad3 = 0x0,
tclassid = 0x0,
__pad_to_align_refcnt = {0x0, 0x0},
__refcnt = {
counter = 0x0
},
__use = 0x0,
lastuse = 0x103203a31,
lwtstate = 0x0,
{
next = 0x0,
rt_next = 0x0,
rt6_next = 0x0,
dn_next = 0x0
}
},
rt_genid = 0x57,
rt_flags = 0x0,
rt_type = 0x1,
rt_is_input = 0x0,
rt_uses_gateway = 0x1,
rt_iif = 0x0,
rt_gateway = 0xa00c80a, # 10.200.0.10
rt_pmtu = 0x0,
rt_table_id = 0xfe,
rt_uncached = {
next = 0xffff880c834f69c0,
prev = 0xffff880c834f69c0
},
rt_uncached_list = 0x0
}
$ ip route
default via 10.200.0.10 dev em1
crash> net | grep ffff880c7ec18000
ffff880c7ec18000 em1 10.200.0.168
ping 192.168.1.19, ip_route_output_flow returns ffff880c58ed7300
crash> rtable ffff880c58ed7300
struct rtable {
dst = {
callback_head = {
next = 0xffff880c58ed6500,
func = 0xffffffff81219f40 <file_free_rcu>
},
child = 0x0,
dev = 0xffff880c693a0000,
ops = 0xffffffff81cd8640 <ipv4_dst_ops>,
_metrics = 0xffffffff818c2301,
expires = 0x0,
path = 0xffff880c58ed7300,
from = 0x0,
xfrm = 0x0,
input = 0xffffffff816117b0 <dst_discard>,
output = 0xffffffff81655330 <ip_output>,
flags = 0x0,
error = 0x0,
obsolete = 0xffff,
header_len = 0x0,
trailer_len = 0x0,
__pad3 = 0x0,
tclassid = 0x0,
__pad_to_align_refcnt = {0x0, 0x0},
__refcnt = {
counter = 0x0
},
__use = 0x0,
lastuse = 0x1030a4b07,
lwtstate = 0x0,
{
next = 0x0,
rt_next = 0x0,
rt6_next = 0x0,
dn_next = 0x0
}
},
rt_genid = 0x57,
rt_flags = 0x0,
rt_type = 0x1,
rt_is_input = 0x0,
rt_uses_gateway = 0x0,
rt_iif = 0x0,
rt_gateway = 0x0, # directly connected
rt_pmtu = 0x0,
rt_table_id = 0xfe,
rt_uncached = {
next = 0xffff880c58ed73c0,
prev = 0xffff880c58ed73c0
},
rt_uncached_list = 0xffff880c58ed73d0
}
$ ip route
192.168.1.0/24 dev p4p1 proto kernel scope link src 192.168.1.18
crash> net | grep ffff880c693a0000
ffff880c693a0000 p4p1 192.168.1.18
If rtable->rt_gateway is not NULL, find the mac address of the gateway using neighbouring subsystem.
If rtable->rt_gateway is NULL, the source and destination must be connected directly.
find the mac address of the destination ip address using neighbouring subsystem.
static struct neighbour *ipv4_neigh_lookup(const struct dst_entry *dst,
struct sk_buff *skb,
const void *daddr)
{
struct net_device *dev = dst->dev;
const __be32 *pkey = daddr;
const struct rtable *rt;
struct neighbour *n;
rt = (const struct rtable *) dst;
if (rt->rt_gateway)
pkey = (const __be32 *) &rt->rt_gateway;
else if (skb)
pkey = &ip_hdr(skb)->daddr;
n = __ipv4_neigh_lookup(dev, *(__force u32 *)pkey);
if (n)
return n;
return neigh_create(&arp_tbl, pkey, dev);
}