linux内核的邻居表,Linux内核报文收发-L3 - Section 3. IP协议、邻居子系统主要是接收、转发和发送三部分...

版本说明

Linux版本: 3.10.103

网卡驱动: ixgbe

网络协议注册

inet_init主要是注册各种协议

注册TCP协议proto_register(&tcp_prot, 1)

继续注册UDP、RAW、PING

arp_init, ip_init, tcp_init, udp_init, ping_init, icmp_init

dev_add_pack(&ip_packet_type)主要是注册ip报文处理函数ip_rcv到pttype_base。

arp_init-->dev_add_pack(&arp_packet_type)主要是注册arp报文处理函数arp_rcv到pttype_base。

报文处理

网卡调用__netif_receivve_skb_core后,会调用deliver_skb(skb, pt_prev, orig_dev)处理对应的3层协议函数。

ip协议

ip_rcv主要获取报文头,报文健康检查,最后进入NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING,...,ip_rcv_finish)。

ip_rcv_finish进行路由查找,ip_route_input_noref-->ip_route_input_slow进行慢速路由判定。

ip_route_input_slow判定报文是本地的话,就给input装载ip_local_deliver函数,如果不是本地继续调用ip_mkroute_input-->__mkroute_input查找路由,并且给input装载ip_forward函数,output装载ip_output。

ip_local_deliver函数直接进入NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_IN,..., ip_local_deliver_finish)。

ip_local_deliver_finish调用ipprot->handler进入4层的协议处理函数。

ip_forward进入NF_HOOK(NFPROTO_IPV4, NF_INET_FORWARD,..., ip_forward_finish)。

ip_forward_finish调用output装载的ip_output。

ip_output进入NF_HOOK(NFPROTO_IPV4, NF_INET_POST_ROUTING,...,ip_finish_output)

ip_finish_output进行分片的判断和操作,此处涉及到GSO的判定,最后调用ip_finish_output2。

ip_finish_output2调用__ipv4_neigh_lookup_noref进行邻居子系统的表查找,ipv4主要是arp表,查找到arp表,则调用dst_neigh_output-->neigh_hh_output-->dev_queue_xmit进行报文发送。

如果没有查找到,则调用__neigh_create-->arp_constructor进行发送等函数的装载,最后也调用dst_neigh_output,然后也调用装载的发送函数,将报文修改为request,调用dev_queue_xmit进行发送。

arp协议

arp_rcv健康检查后,进入NF_HOOK(NFPROTO_ARP, NF_ARP_IN, ..., arp_process)

arp_process完成了所有的处理操作,包括是reply报文则更新arp表;如果是request本地的话,则更新或者创建arp表,并且调用arp_send回复arp报文;如果不是本地不支持arp proxy的话,丢弃报文;支持的话转发报文。

arp_send调用arp_create创建报文,并且调用arp_xmit发送报文。

arp_xmit进入NF_HOOK(NFPROTO_ARP, NF_ARP_OUT, ..., dev_queue_xmit_sk),最后调用dev_queue_xmit发送报文。

转发流程

邻居子系统

Generic neighbouring interface(VFT),为上层协议提供了一个统一的输出接口neigh->output()。

Generic neighbouring interface,为下层提供的也是一个统一的接口dev_queue_xmit()。

ARP是为IPV4设计的地址解析协议,而ND(neighbour detect)则是为IPv6设计的。这些地址解析协议可以说是“嵌入”在邻居子系统里面,但是又可以自由灵活的拆卸,非常方便。

为了加速数据包的发送速度,会将路由表和邻居缓存进行绑定,这个绑定其实就是把邻居缓存中的每个项的结构体嵌入路由表中的一个路由项中,这样报文在查找到路由以后,其实也相当于已经在邻居子系统中查到了缓存,减少了查找的次数。这样在进入邻居子系统后的处理流程就很短。

struct neigh_table :邻居表,每个地址解析协议就会创建这样的一个表(比如arp)

struct neighbour :邻居项代表一个邻居。邻居项用哈希表+链表链的组织方式

struct hh_cache :这个字段存的就是封装好的二层协议头部,每个报文在进入邻居子系统前都会查找路由,路由项中就会包含这hh_cache这个结构

状态机

邻居项存在一种状态机,邻居项都有一个对于管理和维护邻居表来说非常重要的成员,nud_state,用来表示该邻居项当前所处的状态。下面依依介绍这几个状态:

NUD_NONE:邻居项刚建立时处于的状态,在该状态下,还没有硬件地址可以用,所以还不能发送请求报文。一旦有报文要输出到该邻居,便会出发对该邻居硬件地址的请求,进入NUD_INCOMPLETE状态,并缓存发送的报文。

NUD_INCOMPLETE:该状态是请求报文已发送,但尚未收到应答的状态。该状态下还没解析到硬件地址,因此尚无可用硬件地址,如果有报文要输出到该邻居,会将其缓存起来。这个状态会启动一个定时器,如果在定时器到期时还没有接收到邻居的回应,则会重复发送请求报文,否则发送请求报文的次数打到上限,便会进入NUD_FAILED。

NUD_REACHABLE:该状态以及得到并缓存了邻居的硬件地址。进入该状态首先设置邻居项相关的output函数(该状态使用neighbors_ops结构的connectd_outpt),然后查看是否存在要发送给该邻居的报文。如果在该状态下闲置时间达到上限,便会进入NUD_STATLE。

NUD_STATLE:该状态一旦有报文要输出到该邻居,则会进入NUD_DELAY并将该报文输出。如果在该状态下闲置时间达到上限,且此时的引用计数为1,则通过垃圾回收机制将其删除,在该状态下,报文的输出不收限制,使用慢速发送过程。

NUD_DELAY:该状态下表示NUD_STATE状态下发送的报文已经发出,需得到邻居的可达性确认的状态。在为接收到邻居的应答或确认时也会定时地重发请求,如果发送请求报文的次数到上限,如果收到邻居的应答,进入NUD_REACHABLE,否则进入NUD_FAILED,在该状态下,报文的输出不收限制,使用慢速发送过程。

操作

neigh_create:

创建一个neighbour项结构,当以下情况发生:

传输请求:向一台L2地址未知的主机传输请求,就需要对这个地址进行解析。

收到solicitation请求:收到这个请求的主机会假定两个系统有通信发生,会创建一个缓存项。

手工添加:手工添加一个邻居缓存项。

neigh_release:

这个函数会减少neighbour的引用计数,当引用计数为0时,才真正删除neighbour结构,这个函数真正调用neigh_destroy。以下是函数调用的原因:

内核企图向一个不可到达的主机发送报文。

与这个邻居结构相关的L2地址改变了。

邻居结构存在的时间太长,内核需要它占用的内存。

neigh_update:

更新neighbour状态和链路层地址。流程如下:

更新状态不是NUD_VALID态的邻居发生的变化,主要是状态机和neigh->output。

更新L2地址,给状态不是NUD_VALID态的邻居使用。

设置一个新的链路层地址。

改变NUD状态。

处理arp_queue队列。

arp例子

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/436661.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【转】EntityFramework使用Code First模式创建数据库控制生成单数形式的表名

使用Code-First模式生成数据库时,默认生成的数据库表的名称为类型的复数形式,例如实体类名称是"User",默认生成的数据库表名为“Users”,多数情况下我们并不想生成的数据库表名为复数形式,那么应该如何来控制…

0803

“同”表示完全相同的产品。产品后的数字是价钱。AMD的CPU只能配AMD的主板,INTEL亦然。在最后,给出了一5500元的液晶家用配置 -----------------CPUINTEL Celeron D 331(散装) /600AMD Sempron 2600(754盒装&#xff0…

linux grep子目录,linux grep搜索文件中的字符串

从文件中查找关键词grep linux text.txt //查找包含 linux的关键词[rootlocalhost ~]# grep root /etc/grouproot:x:0:rootbin:x:1:root,bin,daemon从多个文件中查找关键词[rootlocalhost ~]# grep root /etc/group /etc/my.cnf/etc/group:root:x:0:root/etc/my.cnf:user root…

【转】云服务器cvm 云服务器ecs区别

1、全称 cvm的英文全拼是 Cloud Virtual Machine (云虚拟机) ecs的英文全拼是 Elastic Compute Service(弹性计算服务) 2、对比 云服务器cvm是普遍的虚拟云服务器统称,是一种简单高效、安全可靠、处理能…

linux make怎么运行,Linux Make 命令教程

原标题:Linux Make 命令教程来自:阮一峰的网络日志链接:www.ruanyifeng.com/blog/2015/02/make.html代码变成可执行文件,叫做编译(compile);先编译这个,还是先编译那个(即编译的安排),叫做构建(…

快速了解c#中的索引器

快速了解c#中的索引器 C#中的索引器是新增加的,和属性有些不同。在c#中,属性可以是这样的:class Person {private string firstname;public string FirstName {get {return firstname;}set {firstname value;}}} 属性声明可以如下编码&#…

【转】C#运算符重载**

https://www.yiibai.com/csharp/csharp_operator_overloading.html 在C#中,可以重新定义或重载大多数内置运算符。 因此,程序员也可以使用具有用户定义类型的运算符。重载运算符是具有特殊名称的功能,关键字operator后跟定义运算符的符号。 类…

图形工具包 linux,GTK 4.0图形工具包正式发布:时隔四年的重大版本!

GTK是用于创建图形用户界面的工具包,GTK提供了一整套的小部件,适用于从小型一次性工具到完整的应用程序套件的项目。GTK是GNOME开发平台的核心,但是它也可以用于编写其他Linux环境的应用程序,以及针对微软Windows和苹果macOS的应用…

引用到网站绝对路径Server.MapPath(~/myfile.mdb)

在任何路径下,都可以用Server.MapPath("~/")引用到网站根目录下 转载于:https://www.cnblogs.com/yurichou/archive/2005/10/17/256357.html

【转】继承过程中 父类子类的 字段方法 内存分配 (非java语言)

名人名言:思想好比火星:一颗火星会点燃另一颗火星。一个深思熟虑的教师和班主任,总是力求在集体中创造一种共同热爱科学和渴求知识的气氛,使智力兴趣成为一些线索,以其真挚的、复杂的关系——即思想的相互关系把一个个…

linux设备驱动学习,linux设备驱动学习4

Linux设备驱动程序学习(4)-高级字符驱动程序操作[(1)ioctl and llseek]今天进入《Linux设备驱动程序(第3版)》第六章高级字符驱动程序操作的学习。一、ioctl大部分设备除了读写能力,还可进行超出简单的数据传输之外的操作,所以设备…

几个删除重复记录的SQL语句

几个删除重复记录的SQL语句在大的数据库应用中,经常因为各种原因遇到重复的记录,造成数据的冗余和维护上的不便。1.用rowid方法2.用group by方法3.用distinct方法 1。用rowid方法据据oracle带的rowid属性,进行判断,是否存在重复,语…

【转】产品经理如何进行BRD,MRD,PRD,DRD,FRD编写

转载自:http://minjiechenjava.iteye.com/blog/2304490, 侵删 PRD文档即产品需求文档,也叫业务需求文档。是产品项目由“概念化”阶段进入到“图纸化”阶段的最主要的一个文档。 产品需求文档的作用就是“对MRD中的内容进行指标化和技术化”…

linux磁盘永久挂载教程,linux 永久磁盘挂载

包年包月实例过期后,如果未在规定时间内续费,实例和磁盘均会自动释放,数据永久丢失,无法找回。关于预付费资源过期后的状态变化,请参考 预付费(包年包月)。在使用包年包月实例过程中,如果您觉得当前实例配置…

[代码阅读] ECS toString实现方法

引言 ECS 提供了一种编程方式来生成以不同标记语言编写的文档。它设计为通过面向对象的抽象来生成所有标签。 ECS 目前版本为1.4.2 ,支持 HTML 4.0 和 XML 。 因为工作原因,作者粗略读了ECS的部分原代码,着重了解ECS如果通过toString方法…

【转】设备数据通过Azure Functions 推送到 Power BI 数据大屏进行展示

设备数据通过Azure Functions 推送到 Power BI 数据大屏进行展示(1.准备工作) 原创 Sean Yu 云计算实战 2019-12-06 本案例适用于开发者入门理解Azure Functions/ IoT Hub / Service Bus / Power BI等几款产品。 主要实战的内容为: 将设备遥…

linux系统管理Linux系统实验,实验三 linux系统管理

实验三 linux系统管理【实验目的】练习Linux系统管理,熟悉Linux系统管理。【实验要求】通过Liunx用户和组管理、设备管理、文件系统管理、进程管理和shell程序设计,能够掌握linux系统管理,完成系统日常维护和管理工作,最后上交实验…

【转】Azure Messaging-ServiceBus Messaging消息队列技术系列1-基本概念和架构

前段时间研究了Window Azure ServiceBus Messaging消息队列技术,搞了很多技术研究和代码验证,最近准备总结一下,分享给大家。 首先,Windows Azure提供了两种类型的消息队列机制:Azure Queues和ServiceBus Queues。 其…

Atlas应用程序调试技巧

本文为翻译文章,原文地址:http://atlas.asp.net/docs/Overview/debug.aspx “Atlas”程序由服务器端代码和客户端代码组成,并且,浏览器可能会要去异步请求一些数据。那么,怎样才能Debug这样的web程序呢。本文将告诉…

linux 自动连接无限,hotplug应用实例:自动连接无线网

Linux内核提供了一种机制,使得有热插拔事件(比如插入或拔出U盘)发生时可以执行一个程序,在本文中我称之为hotplug程序。内核在调用hotplug程序时会传递一个命令行参数,这个参数是发生热插拔事件的子系统名称,常见的有usb, module,…