概述

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. (WPF)依赖属性

    属性触发器: <Button MinWidth=" 75" Margin="10"> <Button.Style> <Style ...

  2. 蓝牙(CoreBluetooth)-中心设备(客户端)

    蓝牙(CoreBluetooth)-中心设备(客户端) 蓝牙客户端-中心设备 主要内容 1. 创建`中央管理器` 2. 发现并且连接外设 3. 寻找连接上的外设数据 4. 发送读或写`特征值`的请求 ...

  3. NiftyNet 项目了解

    1. NiftyNet项目概述 NiftyNet项目对tensorflow进行了比较好的封装,实现了一整套的DeepLearning流程.将数据加载.模型加载,网络结构定义等进行了很好的分离,抽象封装 ...

  4. C++ STL标准模板库(list)

    //list的使用 #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<list> using namesp ...

  5. 【BZOJ】1680: [Usaco2005 Mar]Yogurt factory(贪心)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1680 看不懂英文.. 题意是有n天,第i天生产的费用是c[i],要生产y[i]个产品,可以用当天的也 ...

  6. 【Debian】install

    n年前的报废台式机实在不能忍受xp的速度,果断装Linux近期家里的小本装了Ubuntu14.04 ,实在不习惯最新的图形界面.装个debian试试吧. 1.专门弄一个空白分区2.官网下载debian ...

  7. 【Raspberry Pi】定时运行python程序读温湿度传感器数据&发邮件

    1.定时执行脚本 http://tech.it168.com/a2011/0707/1214/000001214830_all.shtml /sbin/service crond start //启动 ...

  8. javascript基本语法和变量(转)

    转载来自 阮一峰老师的文章,地址为:http://javascript.ruanyifeng.com/grammar/basic.html#toc0 1.1语句 JavaScript 程序的执行单位是 ...

  9. poj 3414(简单bfs)

    题目链接:http://poj.org/problem?id=3414 思路:bfs简单应用,增对瓶A或者瓶B进行分析就可以了,一共6种状态. #include<iostream> #in ...

  10. python+selenium之字符串切割操作

    python+selenium之字符串切割操作 在Python中自带的一个切割方法split(),这个方法不带参数,就默认按照空格去切割字段,如果带参数,就按照参数去切割. 新建一个python文件, ...