dump rtable and dst_entry

本文探讨了IP路由查找过程及其与邻居查找子系统的交互。详细解释了如何通过检查rtable结构中的rt_gateway字段来确定是否需要进行网关MAC地址查找,以及当该字段为空时如何直接查找目标IP地址对应的MAC地址。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值