加入收藏 | 设为首页 | 会员中心 | 我要投稿 云计算网_泰州站长网 (http://www.0523zz.com/)- 视觉智能、AI应用、CDN、行业物联网、智能数字人!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

Linux内核分析 - 网络[九]:邻居表

发布时间:2016-01-23 17:24:38 所属栏目:Linux 来源:网络整理
导读:内核版本:2.6.34 这部分的重点是三个核心的数据结构-邻居表、邻居缓存、代理邻居表,以及NUD状态转移图。 总的来说,要成功添加一条邻居表项,需要满足两个条

实际上,arp_process是接收到ARP报文的处理函数,它涉及到的是邻居表项在收到arp请求和响应的情况,下图反映 了arp_process中所涉及的状态转移:收到arp请求,NUD_NONE -> NUD_STALE;收到arp响应, NUD_INCOMPLETE/NUD_DELAY/NUD_PROBE -> NUD_REACHABLE。根据之前分析,我认为还存在NUD_NONE -> NUD_REACHABLE和 NUD_INCOMPLETE -> NUD_STALE的转移,作何解释?

Linux内核分析 - 网络[九]:邻居表

NUD状态

每个邻居表项在生效前都要经历一系列的状态迁移,每个状态都有不同的含义,在前面已经多次提到了NUD状态。要添加一条有 效的邻居表项,有效途径有两条:

先引用再确认- NUD_NONE -> NUD_INCOMPLETE -> NUD_REACHABLE

先确认再引用 - NUD_NONE -> NUD_STALE -> NUD_DELAY -> NUD_PROBE -> NUD_REACHABLE

其中neigh_timer_handler定时器 、neigh_periodic_work工作队列会异步的更改NUD状态,neigh_timer_handler用于NUD_INCOMPLETE, NUD_DELAY, NUD_PROBE, NUD_REACHABLE状态;neigh_periodic_work用于NUD_STALE。注意neigh_timer_handler是每个表项一个的,而 neigh_periodic_work是唯一的,NUD_STALE状态的表项没必要单独使用定时器,定期检查过期就可以了,这样大大节省了资源。

neigh_update则专门用于更新表项状态,neigh_send_event则是解析表项时的状态更新,能更新表项的函数很多,这里不一 一列出。

Linux内核分析 - 网络[九]:邻居表

neigh_timer_handler 定时器函数

当neigh处于NUD_INCOMPLETE, NUD_DELAY, NUD_PEOBE, NUD_REACHABLE时会添 加定时器,即neigh_timer_handler,它处理各个状态在定时器到期时的情况。

当neigh处于NUD_REACHABLE状态时,根据NUD 的状态转移图,它有三种转移可能,分别对应下面三个条件语句。neigh->confirmed代表最近收到来自对应邻居项的报文时 间,neigh->used代表最近使用该邻居项的时间。

-如果超时,但期间收到对方的报文,不更改状态,并重置超时时间为 neigh->confirmed+reachable_time;

-如果超时,期间未收到对方报文,但主机使用过该项,则迁移至NUD_DELAY状态, 并重置超时时间为neigh->used+delay_probe_time;

-如果超时,且既未收到对方报文,也未使用过该项,则怀疑该项可 能不可用了,迁移至NUD_STALE状态,而不是立即删除,neigh_periodic_work()会定时的清除NUD_STALE状态的表项。

if (state & NUD_REACHABLE) {     
 if (time_before_eq(now,     
   neigh->confirmed + neigh->parms->reachable_time)) {     
  NEIGH_PRINTK2("neigh %p is still alive.n", neigh);     
  next = neigh->confirmed + neigh->parms->reachable_time;     
 } else if (time_before_eq(now,     
   neigh->used + neigh->parms->delay_probe_time)) {     
  NEIGH_PRINTK2("neigh %p is delayed.n", neigh);     
  neigh->nud_state = NUD_DELAY;     
  neigh->updated = jiffies;     
  neigh_suspect(neigh);     
  next = now + neigh->parms->delay_probe_time;     
 } else {     
  NEIGH_PRINTK2("neigh %p is suspected.n", neigh);     
  neigh->nud_state = NUD_STALE;     
  neigh->updated = jiffies;     
  neigh_suspect(neigh);     
  notify = 1;     
 }     
}

(编辑:云计算网_泰州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读