• 邻居子系统 之 邻居项查找neigh_lookup、___neigh_lookup_noref


    概述

    邻居项查找是通过neigh_lookup相关函数来进行的;

    ___neigh_lookup_noref,该函数根据输出设备和主键值(IPv4为下一跳ip地址)在邻居项hash表中查找,找到则返回该项;

    neigh_lookup,该函数调用了___neigh_lookup_noref函数,并且在找到邻居项之后,进行引用计数的递增,然后返回该项;

    源码分析
     1 struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey,
     2                    struct net_device *dev)
     3 {
     4     struct neighbour *n;
     5 
     6     NEIGH_CACHE_STAT_INC(tbl, lookups);
     7 
     8     rcu_read_lock_bh();
     9 
    10     /* 非引用查找邻居项 */
    11     n = __neigh_lookup_noref(tbl, pkey, dev);
    12 
    13     /* 增加引用计数 */
    14     if (n) {
    15         if (!atomic_inc_not_zero(&n->refcnt))
    16             n = NULL;
    17         NEIGH_CACHE_STAT_INC(tbl, hits);
    18     }
    19 
    20     rcu_read_unlock_bh();
    21 
    22     /* 返回邻居项 */
    23     return n;
    24 }
    1 static inline struct neighbour *__neigh_lookup_noref(struct neigh_table *tbl,
    2                              const void *pkey,
    3                              struct net_device *dev)
    4 {
    5     return ___neigh_lookup_noref(tbl, tbl->key_eq, tbl->hash, pkey, dev);
    6 }
     1 static inline struct neighbour *___neigh_lookup_noref(
     2     struct neigh_table *tbl,
     3     bool (*key_eq)(const struct neighbour *n, const void *pkey),
     4     __u32 (*hash)(const void *pkey,
     5               const struct net_device *dev,
     6               __u32 *hash_rnd),
     7     const void *pkey,
     8     struct net_device *dev)
     9 {
    10     /* 获取hash */
    11     struct neigh_hash_table *nht = rcu_dereference_bh(tbl->nht);
    12     struct neighbour *n;
    13     u32 hash_val;
    14 
    15     /* 计算hash值 */
    16     hash_val = hash(pkey, dev, nht->hash_rnd) >> (32 - nht->hash_shift);
    17 
    18     /* 遍历hash表项 */
    19     for (n = rcu_dereference_bh(nht->hash_buckets[hash_val]);
    20          n != NULL;
    21          n = rcu_dereference_bh(n->next)) {
    22         /* 找到则返回该项 */
    23         if (n->dev == dev && key_eq(n, pkey))
    24             return n;
    25     }
    26 
    27     /* 未找到则返回NULL */
    28     return NULL;
    29 }
  • 相关阅读:
    chapter01
    2019.07.11
    系统进程
    Linex第五-第七章
    Linex第三章第四章
    Linux 系统管理 第二章第三章
    2019/7/24
    使用.htaccess进行浏览器图片文件缓存
    div+css3实现漂亮的多彩标签云,鼠标移动会有动画
    搜索排序的作弊与反作弊,面壁人与智子的巅峰对决
  • 原文地址:https://www.cnblogs.com/wanpengcoder/p/11755392.html
Copyright © 2020-2023  润新知