概述

1、不论是入口还是出口流量,都是利用fib_lookup来查找路由表,fib_lookup是对每一个路由表所提供的查找函数的包裹函数,当不支持策略路由时,查找函数版本针对的是local表和main表

2、辅助函数:

  • fib_validate_source:对从一个给定设备接收到的封包的源IP地址检查,检测企图的IP欺骗,而且要在开启非对称路由情况下,确保封包的源IP地址通过该封包接收接口是可达的。另外,该函数也返回用于反方向的首选源地址spec_dst,并初始化路由标签(routing tag)
  • inet_select_addr:给定一个设备dev,一个IP地址dst和一个scope,返回为scope的第一个主地址,用于从设备dev向dst发送封包。如果dev上配置的地址都不满足由scope和dst限定的条件,则该函数尝试其他设备,检验是否存在一个IP地址,配置所要求的scope
  • rt_set_nexthop:给定一个路由缓存项rtable和一个路由查找结果res,完成rtable的各字段的初始化,如rt_gateway,嵌入dst_entry的metrics向量等

3、fn_hash_lookup搜索一个能够将封包路由到特定目的地的fib_node实例。

4、初始化入口流量的函数指针:入口IP流量是由ip_rcv_finish处理,该函数参照路由表来决定将封包送往本地还是丢弃。在路由缓存不命中的情况下,ip_route_input_slow可以创建以下三种dst->input和dst->output的组合:

  • 当封包被转发时,函数将dst->input初始化为ip_forward,将dst->output初始化为ip_output。所以dst_output将调用ip_forward,而在ip_forward的结尾处间接调用dst_output,即ip_output
  • 如果封包被送往本地,函数将dst->input初始化为ip_local_deliver,此时不需要初始化dst->output,但它还是被初始化为ip_rt_error,用于检测在处理送往本地封包的dst->ouput是否被错误调用
  • 如果根据路由表得出目的地址不可达,dst->input被初始化为ip_error,这将产生一个ICMP消息,消息类型依赖于路由查找返回的准确结果,因为ip_error将skb缓冲区释放,所以不需要初始化dst->output,因为即使在犯错情况下它也不会被调用

5、初始化出口流量的函数指针:同理ip_route_output_slow可以创建以下四种dst->input和dst->output的组合:

  • 如果目的地是远程主机,dst->output初始化为ip_output,同理我们可以将dst->input初始化为ip_rt_error
  • 如果目的地是本地系统,函数将dst->output初始化为ip_output,将dst->input初始化为ip_local_deliver。这样可以形成一个循环,当dst_ouput调用ip_output时,后者将封包通过loopback设备送出,导致ip_rcv和ip_rcv_finish的执行。ip_rcv_finish检查入口缓冲区,看到skb->dst中已经存在路由信息,因此调用dst_input,启用ip_local_deliver
  • 如果目的地是本地配置的多播IP地址,函数将dst->output初始化为ip_mc_output,接下来由多播代码来处理该封包,此时不初始化dst->output
  • 当内核编译为支持多播路由时,仍然将dst->output初始化为ip_mc_output,但同时将dst->input初始化为ip_mr_input函数

6、不论是否支持多路径缓存,路由缓存表项的分配和初始化都是通过__mkroute_input和__mkroute_output来完成的,无论ip_route_input_slow或ip_route_output_slow触发将新的路由表项插入到缓存内的操作时,都是调用rt_intern_hash函数来执行

7、首选源地址:添加到路由缓存的路由项是单向的,意味着将用于被路由封包源IP地址的反方向上的流量,不能使用该路由项来进行路由,然而在某些情况下,接收到封包可能触发一个动作,要求本地主机选择一个源IP地址,以便在向发送方回送封包时使用,这个地址即首选源地址。首选源地址的选择如下:

8、路由失败:当一个封包由于主机配置或者由于没有路由匹配而不能被路由时,一个新的路由项就被添加到缓存中,该路由的dst->input被初始化为ip_error。这意味着所有匹配该路由的入口封包将由ip_error来处理。将错误路由添加到缓存中是有意义的,因为这样可以加速对后续发送给同样不正确地址的封包错误进行处理

9、输出路由:不论将封包送往本地或者转发出去,两者都需要执行以下任务:(1)、从匹配的路由项中选择处使用的出口设备,(2)根据被搜索路由项的scope选择出要使用的源IP地址,(3)、创建及初始化一个新缓存表项,并将它插入到缓存中

10、因为调用ip_route_output_slow只是为了路由本地产生的流量,所以搜索关键字fl中的源设备被初始化为回环设备,同时,如果目的地址也是本地地址,那么出口地址也被初始化为回环设备

11、路由时,源IP地址的选择如下:

12、当fib_lookup看到封包的目的地址是本地配置地址,或者当封包中没有提供目的地址时(即搜索包含了未知地址0.0.0.0),该封包被送往本地。在这种情况下,出口设备被设置为回环地址,这意味着封包不会离开本地主机,该封包被发送后重新输入到IP输入栈。dst->input被初始化为ip_local_deliver,当封包重新注入IP输入栈时,ip_rcv_finish将启用dst_input,即启用ip_local_deliver函数来处理该封包。注意:当搜索关键字中,源IP地址和目的IP地址都没有被设置时,封包被送往本地,源地址和目的地址被设置为默认回环地址127.0.0.1(INADDR_LOOPBACK),该地址的scope为RT_SCOPE_HOST

13、当查找返回的路由是默认路由时,需要选择使用默认网关。这是由fib_select_default来完成的。(当res.prefixlen字段为0时表示是默认路由,这表示“前缀长度”,即与该地址相关的网络掩码长度为0)

14、即使fib_lookup路由查找失败,但还是可能成功地将封包发送出去,当搜索关键字提供了出口设备,ip_route_output_slow假定通过该出口设备可以直接到达目的地。在这种情况下,如果还没有源IP地址,则还需要设置一个scope为RT_SCOPE_LINK的源IP地址,可能的情况下用的是该出口设备上的一个地址

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

  1. 深入理解linux网络技术内幕读书笔记(三)--用户空间与内核的接口

    Table of Contents 1 概论 1.1 procfs (/proc 文件系统) 1.1.1 编程接口 1.2 sysctl (/proc/sys目录) 1.2.1 编程接口 1.3 sy ...

  2. 深入理解linux网络技术内幕读书笔记(十)--帧的接收

    Table of Contents 1 概述 1.1 帧接收的中断处理 2 设备的开启与关闭 3 队列 4 通知内核帧已接收:NAPI和netif_rx 4.1 NAPI简介 4.1.1 NAPI优点 ...

  3. 深入理解linux网络技术内幕读书笔记(九)--中断与网络驱动程序

    Table of Contents 1 接收到帧时通知驱动程序 1.1 轮询 1.2 中断 2 中断处理程序 3 抢占功能 4 下半部函数 4.1 内核2.4版本以后的下半部函数: 引入软IRQ 5 ...

  4. 深入理解linux网络技术内幕读书笔记(四)--通知链

    Table of Contents 1 概述 2 定义链 3 链注册 4 链上的通知事件 5 网络子系统的通知链 5.1 包裹函数 5.2 范例 6 测试实例 概述 [注意] 通知链只在内核子系统之间 ...

  5. 深入理解linux网络技术内幕读书笔记(二)--关键数据结构

    Table of Contents 1 套接字缓冲区: sk_buff结构 1.1 网络选项及内核结构 1.2 结构说明及操作函数 2 net_device结构 2.1 MTU 2.2 结构说明及操作 ...

  6. 深入理解linux网络技术内幕读书笔记(八)--设备注册与初始化

    Table of Contents 1 设备注册之时 2 设备除名之时 3 分配net_device结构 4 NIC注册和除名架构 4.1 注册 4.2 除名 5 设备初始化 6 设备类型初始化: x ...

  7. 深入理解linux网络技术内幕读书笔记(七)--组件初始化的内核基础架构

    Table of Contents 1 引导期间的内核选项 2 注册关键字 3 模块初始化代码 引导期间的内核选项 linux运行用户把内核配置选项传给引导记录,然后引导记录再把选项传给内核. 在引导 ...

  8. 深入理解linux网络技术内幕读书笔记(五)--网络设备初始化

    Table of Contents 1 简介 2 系统初始化概论 2.1 引导期间选项 2.2 中断和定时器 2.3 初始化函数 3 设备注册和初始化 3.1 硬件初始化 3.2 软件初始化 3.3 ...

  9. 深入理解linux网络技术内幕读书笔记(六)--PCI层与网络接口卡

    Table of Contents 1 本章涉及的数据结构 1.1 pci_device_id结构 1.2 pci_dev结构 1.3 pci_driver结构 2 PCI NIC设备驱动程序的注册 ...

  10. 深入理解linux网络技术内幕读书笔记(一)--简介

    Table of Contents 1 基本术语 1.1 本书常用的缩写 2 引用计数 2.1 引用计数函数 3 垃圾回收 3.1 异步 3.2 同步 4 函数指针 4.1 缺点 5 goto语句 5 ...

随机推荐

  1. [Android]Volley源代码分析(叁)Network

    假设各位看官细致看过我之前的文章,实际上Network这块的仅仅是点小功能的补充.我们来看下NetworkDispatcher的核心处理逻辑: <span style="font-si ...

  2. Enable multithreading to use std::thread: Operation not permitted问题解决

    在用g++ 4.8.2编译C++11的线程代码后,运行时遇到了如下报错: terminate called after throwing an instance of 'std::system_err ...

  3. PHP命名空间规则解析及高级功能3

    PHP命名空间规则解析及高级功能 -- : 来源:中国站长站综合 编辑:水色皇朝[纠错]1人评论 A-A+ 怎么开淘宝店 网站优化方法 创业如何获得投资 怎么做微商 最新LOL活动 日前发布的PHP ...

  4. make命令用法--转

    转自:http://www.techug.com/make 代码变成可执行文件,叫做编译(compile):先编译这个,还是先编译那个(即编译的安排),叫做构建(build). Make是最常用的构建 ...

  5. [搬运]CORBA中BOA和POA的含义

    先来BOA,搬自:http://www.cl.cam.ac.uk/research/dtg/attarchive/omniORB/doc/2.8/omniORB2/node6.html The Bas ...

  6. SPI—读写串行 FLASH

    SPI协议简介SPI 协议是由摩托罗拉公司提出的通讯协议(Serial Peripheral Interface),即串行外围设备接口,是一种高速全双工的通信总线.它被广泛地使用在 ADC. LCD ...

  7. JQuery EasyUI 请求/加载 两次

    解决方案如下: Html页面中的Table标签中包含class属性(class="easyui-datagrid"),删除即可.

  8. NumberUtils

    package cn.edu.hbcf.common.utils; import java.math.BigDecimal; import java.text.NumberFormat; import ...

  9. git三种模式及常用命令

    Git的三种重要模式,分别是已提交.已修改.已暂存. 已提交(committed):表示数据文件已经顺利提交到Git数据库中. 已修改(modified):表示数据文件已经被修改,但未被保存到Git数 ...

  10. html几种美丽的分割线

    一.普通 1.<HR> 2.<HR align=center width=300 color=#987cb9 SIZE=1>align 线条位置(可选left.right.ce ...