《TCP/IP具体解释卷2:实现》笔记--选路请求和选路消息
内核的各种协议并不直接使用前面提供的函数来訪问选路树,而是调用几个函数:rtalloc和rtallocl是完毕路由表查询的两个
函数;rtrequest函数用于加入和删除路由表项;另外大多数接口在接口连接或断开时都会调用函数rtinit。
选路消息在两个方向上传递信息。
进程(route命令)或守护进程(routed或gated)把选路消息写入选路插口。以使内核加入
路由、删除路由或者改动现有的路由。当有时间发生时,如接口断开、收到重定向等,内核也会发送选路消息。进程通过选路
插口来读取它们感兴趣的内容。
内核还提供了还有一种訪问路由表的接口,即系统的sysctl调用。
1.rtalloc和rtalloc1函数
通常,路由表的查找通过调查rtalloc和rtalloc1函数来实现的。
rtalloc调用rtalloc1,rtalloc1调用rnh_matchaddr函数,对于
Internet地址来说,该函数就是rn_match函数。
rtalloc1的大概处理流程例如以下:
调用rn_match,假设符合下列三个条件,则查找成功。
1)存在该协议族的路由表。
2)rn_match返回一个非空指针;而且
3)匹配的radix_node结构没有设置RNF_ROOT标志。
假设查找成功。则指向匹配的radix_node结构的指针保存在rt中。假设调用的第二个參数非0,并且匹配的路由表设有
RTF_CLONING标志。则调用rtrequest函数发送RTM_RESOLVE命令来创建一个新的rtentry结构,该结构是查询结果的
克隆。
2.宏RTFREE和rtfree函数
宏RTFREE,仅在引用计数小于等于1时才调用rtfree函数。否则,它仅完毕引用计数的递减。
3.rtrequest函数
rtrequest函数是加入和删除路由表项的关键点。下图给出了调用它的一些其它函数。
rtrequest是一个switch语句。每一个case相应一个命令:RTM_ADD、RTM_DELETE和RTM_RESOLVE。
对于RTM_DELETE命令:
1.从选路树中删除路由
2.删除对网络路由表项的引用。
3.调用接口请求函数。假设该表项定义了ifa_rtrequest函数,就调用该函数。ARP会使用该函数。
4.返回指针或删除引用。
假设调用者须要选路树中被删除的rtentry结构指针,则返回该指针。但此时不能释放该表项。调用
这必须使用完该表项后调用rtfree来删除它。
对于RTM_RESOLVE命令:
仅仅有rtalloc1可以携带此命令參数调用本函数。
也仅仅有在从一个设有RTF_CLONING标志的表项中克隆一个新的表项时,
rtalloc1才这么用。
这个命令将跳转到makeroute标记处继续运行。
对于RTM_ADD命令:
定位对应的接口。查找适当的本地接口,并返回指向该接口的ifaddr结构的指针。
进入makeroute标记处运行。
makeroute的大概处理流程例如以下:
1.为路由表项分配存储器。分配rtentry结构。
2.分配并复制网关地址。
3.复制目的地址。
4.往选路树中加入表项(rtentry结构)。
5.保存接口指针。递增ifaddr结构的引用计数,并保存ifaddr和ifnet结构的指针。
6.为新克隆的路由复制度量。假设是RTM_RESOLVE。则把被克隆的表项中的整个度量结构拷贝到新的表项里。
假设是
RTM_ADD,则调用者可在函数返回后设置该度量值。
7.调用接口请求函数。假设为该表项定义了ifa_rtrequest函数,则调用该函数。
8.返回指正并递增引用计数。假设调用者须要改新结构的指针,在返回该指针。并将该引用计数值从0递增到1。
4.rtinit函数
Internet协议加入或删除相关接口的路由时,对rtinit的调用有四个。
1.在设置点到点接口的目的地址时。in_control调用rtinit两次。第一次调用指定RTM_DELETE命令,以删除全部现存的到
该目的地址的路由,第二次调用指定RTM_ADD命令,以加入新路由。
2.in_ifinit调用rtinit为广播网络加入一条网络路由或为点到点链路加入一条主机路由。
假设是给以太网接口加入的路由。
3.in_ifscrub调用rtinit。以删除一个接口现存的路由。
函数的大概处理流程例如以下:
1.为路由获取目的地址。
假设是一个到达某主机的路由,则目的地址是点到点链路的还有一端。否则。我们处理的就是一个
网络路由。其目的地址是接口的单播地址。
2.假设要删除路由,则必须在路由表中查找该目的地址。并得到它的路由表。
3.调用rt_request运行RTM_ADD或者RTM_DELETE命令。
4.假设删除成功。则产生一个选路消息。
5.假设加入成功可是新路由表项接口的ifaddr指针不等于调用參数,则表明有差错产生。
做例如以下步骤:向控制台输出一条
出错消息;假设rt_request获得到的rtentry中ifa_rtrequest函数(rt->ifa->ifa_rtrequest),就以RTM_DELETE为參数调用
它。假设函数的參数中ifa定义了ifa_rtrequest函数,就以RTM_ADD为參数调用它。最后产生选路消息。
5.rtredirct函数
当收到一个ICMP重定向后。icmp_input调用rtredirect及pfctlinput。
后一个函数又调用udp_cltinput和tcp_ctlinput,这两个
函数遍历全部的UDP和TCP协议控制块(PCB)。假设PCB连接到一个外部地址。而到该外部地址的方向已经被改变,而且
该PCB持有到那个外部地址的路由,则调用rtfree释放该路由。
下一次使用这些控制块发送外部地址的IP数据报时,就会调用
rtalloc。并在路由表中查找该目的地址。非常可能会找到一条新的路由。
rtredirect函数的作用是验证重定向中的信息。并马上更新路由表。产生选路插口消息。
该函数的大概处理流程例如以下:
1.新路由必须直接相连,否则该重定向失效。
2.查找目的地址的路由表项并验证重定向。
调用rtalloc1在路由表中查找到目的地址的路由。验证重定向时,下列条件必须为
真:
必须未设置RTF_DONE标志。
rtalloc必须已经找到一个到dst的路由表项。
发送重定向的路由器的地址必须等于当前为目的地址设置的rt_gateway.
新网关的接口必须等于当前为目的地址设置的接口,也就是说,新网关必须和当前网关在同一网络上。
新网关不能把到这个主机的路由改变到自己。也就是说。不能存在与gateway相等的有单播地址或广播地址的连接着的接口。
3.创建新的主机路由。假设到达目的地址的当前路由是一个网络路由,而且重定向是主机重定向而不是网络重定向,那么就为
该目的地址建立一个主机路由(调用rtrequest,RTM_ADD)。而不必去管现存的网络路由。
4.改变现存的主机路由。当到达目的地址的当前路由已经是一个主机路由时,不须要创建新的表项。而是改动现存的表项。
5.由rt_missmsg产生一个选路插口消息。
6.选路消息的结构
选路消息有一个定长的首部和至多8个插口地址结构组成。该定长首部是下列三种结构中的一个:
rt_msghdr
if_msghdr
ifa_msghdr
选路消息三种首部结构的前三个成员的数据类型及其含义是同样的,分别为:消息的长度,版本号和类型。
每中结构都都有
一个成员来编码首部之后8个可能的插口地址:rtm_addr、ifm_addrs和ifam_addrs成员。它们都是一个比特掩码。
下图给出了最经常使用的结构,rt_msghdr。
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvVE9ERDkxMQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
RTM_IFINFO消息使用了下图的if_msghdr结构。
RTM_NEWADDR和RTM_DELADDR消息使用了下图的ifa_msghdr结构。
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvVE9ERDkxMQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
三个变量rtm_addrs、ifm_addrs和ifam_addrs都是比特掩码。它们定义了首部之后的插口地址结构。下图给出了比特掩码
用到的一些常量。
内核用上图的数组下标来引用rt_addrinfo结构。例如以下图所看到的。
假设rti_addrs成员中设置了RTA_GATEWAY比特,则rti_info[RTA_GATEWAY]成员就是含网关地址的插口地址结构的指针。
7.rt_missmsg函数
rt_missmsg函数使用了rt_addrinfo结构,并调用rt_msg1在mbuf链中为进程创建了对应的变长消息,之后调用raw_input将
该mbuf链传递给全部相关的选路插口。函数的处理流程例如以下:
1.在mbuf中创建消息。
rt_msg1在mbuf链中创建对应的消息,并返回该链的指针,下图为rt_msg1创建的一个mbuf链。
2.完毕消息的创建。
设置rt_msghdr的其它成员。
3.设置消息的协议,调用raw_input。
8.rt_ifmsg函数
在if_up和if_down中都调用了rt_ifmsg。在接口连接或断开时,该函数被用来产生一个选路插口消息。
函数的大概处理流程
例如以下:
1.调用rt_msg1函数在mbuf链中创建消息。
2.完毕消息的创建。
设置if_msghdr接口中其它成员。
3.设置消息的协议,调用raw_input。
9.rt_newaddrmsg函数
在接口上加入或者删除一个地址时。rtinit要以RTM_ADD或者RTM_DELETE为參数调用rt_newaddrmsg。函数的大概处理
流程例如以下:
1.调用rt_msg1函数在mbuf链中创建消息。
2.完毕消息的创建。设置ifa_msghdr接口中其它成员。
3.设置消息的协议,调用raw_input。
《TCP/IP具体解释卷2:实现》笔记--选路请求和选路消息的更多相关文章
- 《TCP/IP具体解释卷2:实现》笔记--接口层
接口层包含在本地网上发送和接收分组的硬件与软件. 我们用设备驱动程序来表示与硬件及网络接口通信的软件,网络接口是指在一个特定网络上硬件与设备驱动器之间的接口. Net/3接口层试图在网络协议和连接到一 ...
- 《TCP/IP具体解释卷2:实现》笔记--IP多播
D类IP地址(224.0.0.0到239.255.255.255)不识别互联网内的单个接口,但识别接口组,被称为多播组. 单个网络上的组成员利用IGMP协议在系统之间通信. 多播路由器用多播选录协议. ...
- 《TCP/IP具体解释卷2:实现》笔记--UDP:用户数据报协议
用户数据报协议.即UDP,是一个面向数据报的简单运输层协议:进程的每次输出操作仅仅产生一个UDP数据报,从而发送 一个IP数据报. 进程通过创建一个Internet域内的SOCK_DGRAM类型的插口 ...
- 《TCP/IP具体解释卷2:实现》笔记--协议控制块
协议层使用协议控制块(PCB)存放各UDP和TCP插口所要求的多个信息片.Internet协议维护Internet协议控制块 (internet protocol control block)和TCP ...
- 《TCP/IP具体解释卷2:实现》笔记--ICMP:Internet控制报文协议
ICMP在IP系统间传递差错和管理报文,是不论什么IP实现必须和要求的组成部分.能够把ICMP分成两类:差错和查询.查询报文 是用一对请求和回答定义的.差错报文通常包括了引起错误的IP包的第一个分片的 ...
- 《TCP/IP具体解释卷2:实现》笔记--IP:网际协议
本章介绍IP分组的结构和主要的IP处理过程,包含输入,转发和输出. 下图显示了IP层常见的组织形式. 在之前的文章中.我们看到了网络接口怎样把到达的IP分组放到IP输入队列ipintrq中去,并怎样调 ...
- 《TCP/IP具体解释卷2:实现》笔记--IP的分片和重装
IP首部内有三个字段实现分片和重装:标识字段(ip_id).标志字段(ip_off的3个高位比特)和偏移字段(ip_off的13个低位 比特).标志字段由3个1bit标志组成.比特0是保留的必须为0, ...
- 《TCP/IP具体解释卷2:实现》笔记--域和协议
Net/3组把协议关联到一个域,而且用一个协议族常量来标识每一个域.Net/3还通过全部的编址方法将协议分组. 在一个域中 的每一个协议使用同类地址.而且每种地址仅仅被一个域使用.作为结果,一个域能通 ...
- 《TCP/IP具体解释卷2:实现》笔记--4种不同类型的mbuf
mbuf的主要用途是保存子进程和网络接口间互相传递的用户数据.但mbuf也用于保存其它各种数据:源于目的地址.插口 选项等等. 以下介绍我们要遇到的四种类型的mbuf,它们根据在成员m_flag中填写 ...
随机推荐
- SQL语句大小写是否区分的问题,批量修改整个数据库所有表所有字段大小写
一.实例介绍 SQL语句大小写到底是否区分呢?我们先从下面的这个例子来看一下: 例: --> 创建表,插入数据: declare @maco table (number int,myvalue ...
- python input 与raw_input函数的区别
转自:http://blog.csdn.net/sruru/article/details/7790436 以前没有深入考虑过raw_input与input函数的区别,所以一直比较困惑,今天测试之后, ...
- C#.NET常见问题(FAQ)-如何批量增加或取消注释
选中一批文本之后 批量增加注释:Ctrl+K Ctrl+C 批量取消注释:Ctrl+K Ctrl+U 更多教学视频和资料下载,欢迎关注以下信息: 我的优酷空间: http://i.youku. ...
- Discuz常见大问题-如何允许用户插入视频-如何自己在页面中插入视频
从视频的下面分享中获取html代码 然后粘贴到你创建页面的指定位置(注意从优酷复制的视频宽度和高度可能比较小,你可以自己调整,或者占据100%) 最终的实现效果
- php之快速入门学习-9(switch)
PHP Switch 语句 switch 语句用于根据多个不同条件执行不同动作. PHP Switch 语句 如果您希望有选择地执行若干代码块之一,请使用 switch 语句. <?php sw ...
- JDBC四(web基础学习笔记十)
一.增加 .修改.删除.查询 将功能整合在一个类中 package pb.base; import java.sql.Connection; import java.sql.DriverManager ...
- [转]自定义Drawable实现灵动的红鲤鱼动画(上篇)
此篇中的小鱼动画是模仿国外一个大牛做的flash动画,第一眼就爱上它了,简约灵动又不失美学,于是抽空试着尝试了一下,如下是我用Android实现的效果图: 小鱼儿 由于整个绘制分析过程比较繁琐所以 ...
- PHPstorm最常用的快捷键,提高开发效率
PHPstorm最常用的快捷键,提高开发效率 •ctrl+b 跳到变量申明处 •Ctrl + E 打开最近文件 •Ctrl + R 替换. •Ctrl + D 复制粘贴.将当前行或者选择的内容复制粘贴 ...
- 恭喜您成为2014年度Microsoft MVP!
- 深入浅出搜索架构引擎、方案与细节 倒排 bitmap
深入浅出搜索架构引擎.方案与细节(上) 2017-02-14 23:55 58沈剑0 20 阅读 131 一.缘起 <100亿数据1万属性数据架构设计>文章发布后,不少朋友对58同城自 ...