《深入理解Linux网络技术内幕》阅读笔记 --- 路由表

路由表基本概念

1、路由是由多个不同的数据结构的组合来描述的,每个数据结构代表路由信息的不同部分。例如,一个fib_node对应一个单独的子网,一个fib_alias对应一条路由。这样做的原因是只需通过部分字段可以区分多条路由。路由子系统不是维护一个庞大而臃肿的结构而是将路由分散为多个片段,这样更容易在相似的路由间共享通用的信息,因而就可以分离出不同的函数,并在这些函数之间定义更加清晰的接口。

  数据结构之间的关系如下所示:fib_table结构包含一个由33个指针组成的向量,每个指针对应一个网络掩码并指向一个类型为fn_zone的数据结构。fn_zone结构将路由组成hash表,每个单独的子网对应一个fib_node实例,用变量fn_key识别,例如对于子网10.1.1.0/24,fn_key为10.1.1。目的子网相同的不同路由共享同一个fib_node,每条路由都有自己的fib_alias结构,而每个fib_alias实例都与一个fib_info结构相关联,该结构中保存着真实路由信息。需要注意的是,fib_alias和fib_info之间不是一对一的关联,多个fib_alias结构可能共享同一个fib_info结构。例如,有五条到不同目的网络的路由碰巧使用同一个下一跳网关,那么对所有这五条路由来说下一跳信息都是相同的,因而就可以共享相同的下一跳信息。所以这种情况下就有五个fib_node结构和五个fib_alias结构,但只有一个fib_info结构。

  每个fib_info结构可以包含一个或多个fib_nh结构,每个fib_nh结构表示下一跳路由器,一个下一跳路由器的信息中包括通过哪个设备能到达该路由器。

2、向路由表中插入一条新的路由是通过fn_hash_insert函数实现的,事实上,调用此函数的还有处理路由的尾部追加(append)、首部追加(prepend)、改变(change)和替换(replace)操作,这些不同的操作是由传入的NLM_F_XXX标识参数来区分的。路由的删除由fn_hash_delete完成,删除路由要比添加路由简单,因为删除路由只有一种操作

3、垃圾回收:在一定条件下,fib_sync_down会变量路由表,设置RTNH_F_DEAD标识来标记满足删除条件的路由项。之后,调用fib_flush再次遍历路由表并删除设置了该标志的路由项。注意:没有周期性的函数来清理路由表。

4、对于路由的查找,总是首先搜索路由缓存,当路由缓存没有查找到时,通过ip_route_input_slow和ip_route_output_slow函数来查找路由表

5、不论是哪个方向的流量,都是利用fib_lookup来查找路由表,fib_lookup函数是对每一个路由表所提供的一个包含查找函数的包裹函数,当不支持策略路由时,查找函数版本是针对local表和main表,当支持策略路由时,逻辑更为复杂,需要查找由策略路由提供的路由表。

6、所有的路由表查找,不论路由表是否由策略路由提供,也不论流量方向如何,都是利用fn_hash_lookup来查找。fn_hash_lookup搜索一个能够将封包路由到特定目的地的fib_node实例。遍历上图中的fn_zone,再通过fn_key为关键字,查找到fn_zone中hash表中对应的fib_node。之后,它还需要检查每一个潜在的路由项,来查找与输入参数struct flowi *flp中其他字段相匹配的路由,这个检查由fib_semantic_match完成

  fib_semantic_match被调用以发现在与给定的fib_node相关的路由(fib_alias结构)中,是否存在与搜索关键字所有字段都匹配的路由项。

7、dst->input和dst->output的可能的组合如下图所示:

输入路由

ip_route_input_slow的调用过程如下所示:

1、ip_route_input在调用fib_lookup查找路由成功时,会将封包发往本地或者转发,但两者都需要执行一些共同的任务,例如对于源地址的合理性检查,通过fib_validate_source检查欺骗企图,之后再创建和初始化一条新缓存表项

时间: 2024-08-02 10:40:59

《深入理解Linux网络技术内幕》阅读笔记 --- 路由表的相关文章

深入理解Linux网络技术内幕——IPv4 报文的传输发送

报文传输,指的是报文离开本机,发往其他系统的过程. 传输可以由L4层协议发起,也可以由报文转发发起. 在深入理解Linux网络技术内幕--IPv4 报文的接收(转发与本地传递)一文中,我们可以看到,报文转发最后会调用dst_output与邻居子系统进行交互,然后传给设备驱动程序. 这里,我们从L4层协议发起的传输,最后也会经历这一过程(调用dst_output).本文讨论的是L4层协议发起的传输,在IPv4协议处理(IP层)中的一些环节. 大蓝图 我们先看下传输环节的大蓝图,以便对传输这一过程有

深入理解Linux网络技术内幕——IPv4 报文的接收(转发与本地传递)

我们知道,报文经过网卡驱动处理后,调用net_receive_skb传递给具体的协议处理函数,对于IPv4报文来说,其协议处理函数就是ip_rcv了,ip_rcv在进行一些健康检查等操作后,会调用ip_rcv_finish来处理报文.这也是IPv4协议对报文接收处理的开始. 我们先看下ip_rcv_finish源代码: ip_rcv_finish: //ip数据报文的主要处理程序(ip_rcv仅仅只是对ip数据报做一些健康性检查) //ip_rcv_finish 其实是进行路由表查询,,决定报文

《深入理解Linux网络技术内幕》阅读笔记 --- 路由

一.Linux内核中路由相关的主要数据结构 struct fib_result:对路由表查找后返回该结构,它的内容并不是简单的包含下一跳信息,而且包含其他特性,例如策略路由所需的更多参数. struct fib_rule:表示由策略路由在路由流量时选择路由表的规则 struct fib_node:一条路由表项.例如,该数据结构用于存储由route add或ip route add命令添加一条路由时生成的信息. struct fn_zone:一个zone表示子网掩码长度相同的一组路由 struct

深入理解Linux网络技术内幕——设备的注册于初始化(一)

副标题:设备注册相关的基本结构的原理框架 设备注册与删除时间 设备在下列两种情况下进行注册: 1)加载NIC驱动时 2)插入热插拔设备时 这里NIC与热插拔设备有些不同.a.对于非热插拔NIC来说,NIC的注册是伴随着其驱动的发生的,而NIC可以内建到内核,也可以作为模块载入,如果内建入内核,则NIC设备和初始化均发生在引导时,如果NIC作为模块加载,则NIC的注册和驱动初始化均发生在模块加载时.b. 对于热插拔NIC设备来说,其驱动已经加载,因此设备的注册发生在插入设备,内核通知关联驱动时.

深入理解Linux网络技术内幕——帧的接收与传输

帧的接收 NAPI与netif_rx(非NAPI) Linux内核获取网络帧到达通知的方式有两中:中断和轮询.(中断值设备向内核发出中断,轮询指linux内核主动轮询设备) 在早起的linux内核中,网络帧主要以中断的方式通知linux内核帧的到达.这是非NAPI方式. 现在的操作系统中,linux内核使用NAPI方式, 获取帧到达的消息.NAPI混合使用了中断和轮询. netif_rx(非NAPI): 每一个帧接收完毕时,设备向内核发送一个中断.(在低流量负载的情况下,这种方式对比轮询优势明显

深入理解Linux网络技术内幕——协议处理函数

网络帧在进入网络层时,需要区分不同的网络协议进行处理,这就需要涉及协议处理函数. 首先我们从驱动接收到一个数据帧,分析数据帧在协议栈中自下而上的传输流程. 设备驱动程序在接收到一个数据帧时,会将其保存在一个sk_buff缓冲区数据结构,并对其进行初始化. struct sk_buff { ...... __be16 protocol:16; ...... } 在这个缓冲区结构体中,有一个protocol字段,用于标识网络层的协议. 我们知道网络帧在设备驱动程序中处理后,设备驱动程序会调用neti

深入理解Linux网络技术内幕——路由子系统的概念与高级路由

本文讨论IPv4的路由子系统.(IPv6对路由的处理不同). 基本概念 路由子系统工作在三层,用来转发入口流量. 路由子系统主要设计 路由器.路由.路由表等概念. 路由器: 配备多个网络接口卡(NIC),并且能利用自身网络信息进行入口流量转发的设备. 路由: 流量转发,决定目的地的过程 路由表:转发信息库,该库中储存路由需要本地接收还是转发的信息, 以及转发流量时所需要的信息.(即,信息库用来判断,要不要转发,如果要转发,向哪里转发). 我们了解,路由器有多个网卡,但是多个NIC的设备不一定就是

深入理解Linux网络技术内幕——网络设备初始化

概述 内核的初始化过程过程中,与网络相关的工作如下所示: 内核引导时执行start_kernel,start_kernel结束之前会调用rest_init,rest_init初始化内核线程init(在Linux3-12中为kernel_init). asmlinkage void __init start_kernel(void) { ... parse_early_param();//间接调用parse_args parse_args(...); //处理内核引导程序(boot loader)

深入理解Linux网络技术内幕——用户空间与内核空间交互

概述: 内核空间与用户空间经常需要进行交互.举个例子:当用户空间使用一些配置命令如ifconfig或route时,内核处理程序就要响应这些处理请求. 用户空间与内核有多种交互方式,最常用的有以下四种:通过/proc虚拟文件系统,通过/sys虚拟文件系统,通过ioctl系统调用,通过Netlink socket. 其中编写程序时最常使用ioctl,这四种方式中有两种是通过虚拟文件系统. procfs 与 sysctl procfs挂载/proc  sysctl挂载在/proc/sys(与后面介绍的