邻居子系统 之 邻居项查找neigh_lookup、___neigh_lookup_noref
概述
邻居项查找是通过neigh_lookup相关函数来进行的;
___neigh_lookup_noref,该函数根据输出设备和主键值(IPv4为下一跳ip地址)在邻居项hash表中查找,找到则返回该项;
neigh_lookup,该函数调用了___neigh_lookup_noref函数,并且在找到邻居项之后,进行引用计数的递增,然后返回该项;
源码分析
struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey,
struct net_device *dev)
{
struct neighbour *n; NEIGH_CACHE_STAT_INC(tbl, lookups); rcu_read_lock_bh(); /* 非引用查找邻居项 */
n = __neigh_lookup_noref(tbl, pkey, dev); /* 增加引用计数 */
if (n) {
if (!atomic_inc_not_zero(&n->refcnt))
n = NULL;
NEIGH_CACHE_STAT_INC(tbl, hits);
} rcu_read_unlock_bh(); /* 返回邻居项 */
return n;
}
static inline struct neighbour *__neigh_lookup_noref(struct neigh_table *tbl,
const void *pkey,
struct net_device *dev)
{
return ___neigh_lookup_noref(tbl, tbl->key_eq, tbl->hash, pkey, dev);
}
static inline struct neighbour *___neigh_lookup_noref(
struct neigh_table *tbl,
bool (*key_eq)(const struct neighbour *n, const void *pkey),
__u32 (*hash)(const void *pkey,
const struct net_device *dev,
__u32 *hash_rnd),
const void *pkey,
struct net_device *dev)
{
/* 获取hash */
struct neigh_hash_table *nht = rcu_dereference_bh(tbl->nht);
struct neighbour *n;
u32 hash_val; /* 计算hash值 */
hash_val = hash(pkey, dev, nht->hash_rnd) >> ( - nht->hash_shift); /* 遍历hash表项 */
for (n = rcu_dereference_bh(nht->hash_buckets[hash_val]);
n != NULL;
n = rcu_dereference_bh(n->next)) {
/* 找到则返回该项 */
if (n->dev == dev && key_eq(n, pkey))
return n;
} /* 未找到则返回NULL */
return NULL;
}
邻居子系统 之 邻居项查找neigh_lookup、___neigh_lookup_noref的更多相关文章
- 邻居子系统 之 邻居项创建__neigh_create
概述 IP层输出数据包会根据路由的下一跳查询邻居项,如果不存在则会调用__neigh_create创建邻居项,然后调用邻居项的output函数进行输出: __neigh_create完成邻居项的创建, ...
- 邻居子系统 之 邻居表的初始化neigh_table_init
概述 邻居子系统支持多种实现,例如ARP,ND等,这些实现需要在其初始化的时候,调用neigh_table_init将邻居表项添加到全局邻居子系统数组中,并对实例中的字段(如hash,定时器等)进行相 ...
- 邻居子系统 之 状态定时器回调neigh_timer_handler
概述 在分配邻居子系统之后,会设置定时器来处理那些需要定时器处理的状态,定时器回调函数为neigh_timer_handler:函数会根据状态机变换规则对状态进行切换,切换状态后,如果需要更新输出函数 ...
- 邻居子系统 之 更新neigh_update
概述 neigh_update函数用来更新指定的邻居项,更新内容是硬件地址和状态,更新之后,会根据新状态设置其输出函数,CONNECTED状态则使用快速输出,否则使用慢速输出:如果是由原来的无效状态变 ...
- 邻居子系统输出 之 neigh_output、neigh_hh_output
概述 ip层在构造好ip头,检查完分片之后,会调用邻居子系统的输出函数neigh_output进行输出,输出分为有二层头缓存和没有两种情况,有缓存时调用neigh_hh_output进行快速输出,没有 ...
- 迁移到MSYS2 与 Qt 工具链注意的几个事情(g++在链接时,符号依赖项查找遵循从左至右的顺序,但qmake会自动合并造成错误。使用脚本给Mingw32-make创造出一个局部的VC编译环境)
Microsoft Visual Studio 2015社区版提供了强大的开发体验,且 Qt 提供了预编译版本.然而,由于客户提出兼容Windows XP ~ Windows 8.1 这样宽泛的环境要 ...
- 《深入理解Linux网络技术内幕》阅读笔记 --- 邻居子系统
1.封包从L3至L2的传送过程如下所示: 本地主机的路由子系统选择L3目的地址(下一个跃点). 根据路由表,如果下一个跃点在同一个网络中,邻居层就把目的L3地址解析为跃点的L2地址.这个关联会被放入缓 ...
- 邻居子系统1.5 neigh output
1.5.1 当邻居项不处于NUD_CONNECTD状态时,不允许快速路径发送报文,函数neigh_resolve_output 用于慢而安全的输出,通常用初始化neigh_ops结构 来实例outpu ...
- 邻居子系统 arp 状态图
随机推荐
- linux环境下,springboot jar启动方式
linux环境下,springboot jar启动方式 一.前台启动(ctrl+c会关掉进程) java -jar application.jar 二.后台启动(ctrl+c不会关闭) java -j ...
- Cannot assign to read only property 'exports' of object at webpack ....BaseClient
网上找了很多资料说是import和export不能一起用,改代码 其实根本原因是es6和es5混合使用造成的兼容性问题 只需要配置.babelrc就可以了 首先安装 npm install -D tr ...
- mint-ui下拉加载(demo实例)
<template> <div class="share"> <div class="header"> <div cl ...
- C++typedef struct和struct的区别
#include "pch.h" #include struct struct1 { int a; char b; char* c; }test1;//定义结构体变量 typede ...
- 终端复用工具-tmux
目录 终端复用工具--Tmux 一.为什么要用Tmux? 二.tmux是什么? 三.Tmux基本概念 四.Tmux使用规则 1.安装Tmux 2.基本使用 3.自定义配置文件 五.补充 1.tmux ...
- 02-【servlet】
1.什么是Servlet Servlet是JavaWeb的三大组件之一[Servlet,Filter,Listener],它属于动态资源.Servlet的作用是处理请求,服务器会把接收到的请求交给Se ...
- HTML 做圆形头像
Click me <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...
- 关于STM32运行时程序卡在B.处的解决方法
文章转载自:https://blog.csdn.net/u014470361/article/details/78780444 背景: 程序运行时,发现程序卡死在B.处. 解决方法: 程序卡死在B.处 ...
- 移动端css适配
/* iphoneX.iphoneXs */ @media only screen and (device-width: 375px) and (device-height: 812px) and ( ...
- POJ1639 算法竞赛进阶指南 野餐规划
题目描述 原题链接 一群小丑演员,以其出色的柔术表演,可以无限量的钻进同一辆汽车中,而闻名世界. 现在他们想要去公园玩耍,但是他们的经费非常紧缺. 他们将乘车前往公园,为了减少花费,他们决定选择一种合 ...