【2021/1/17修订】【梳理】计算机网络:自顶向下方法 第五章 网络层——控制(docx)

计算机网络

知 识 梳 理

(第一版)

建议先修课程:数据结构。
配套教材:
Computer Networking - A Top Down Approach, 7th edition James F. Kurose, Keith W. Ross
参考书目:
1、计算机网络(第7版) 谢希仁 编著 高等教育出版社


链接:https://pan.baidu.com/s/1iGh3vI22EuPIms2AQ3_Irw
提取码:0000
复制这段内容后打开百度网盘手机App,操作更方便哦


五 网络层——控制

5.1 简介

下面我们先简单说明路由器是怎样转发分组的。路由器通过路由算法构造(调整)路由表(一张路由表的示例如上图)来决定路由,然后根据路由表构造(调整)转发表并进行转发。若路由表指出到每一台主机应怎样转发,则路由表就会过于庞大;若指出到某个网络应如何转发,则每台路由器中的路由表含有的条目就可以大大减少。路由表至少包含目标主机所在的网络号和下一跳地址。
虽然互联网的分组转发一般都基于目的主机所在的网络,但在大多数情况下都允许有特例,即对特定的目的主机指明一个路由。这种路由叫做特定主机路由。采用特定主机路由可使网络管理人员更方便地控制、测试网络,同时也可在需要考虑某种安全问题时采用特定主机路由。在对网络的连接或路由表进行排错时,指明到某一台主机的特殊路由就十分有用。
路由器还可采用默认路由(default route)以减小路由表所占用的空间和搜索路由表所用的时间。这种转发方式在一个网络只有很少的对外连接时是很有用的。实际上,默认路由在主机发送IP数据报时往往更能显示出它的好处。主机在发送每一个IP数据报时都要查找自己的路由表。如果一台主机连接在一个小网络上,而这个网络只用一台路由器和互联网连接,那么在这种情况下使用默认路由是非常合适的。只要目的网络是其它网络,就一律选择默认路由,提升了路由效率。

当路由器收到一份待转发的数据报,从路由表得出下一跳路由器的IP地址后,不是把这个地址填入IP数据报,而是送交数据链路层的网络接口软件。网络接口软件使用地址解析协议(ARP,见第6章)把下一跳路由器的IP地址转换成硬件地址并将此硬件地址放在链路层帧的首部,然后根据这个硬件地址找到下一跳路由器。可见,当发送一连串数据报时,这种查找路由表、用ARP得到硬件地址、把硬件地址写入链路层帧首部等过程将不断重复,造成了一定的开销。
那么,能不能在路由表中不使用IP地址而直接使用硬件地址呢?不行。我们一定要弄清楚,使用抽象的IP地址,本来就是为了隐蔽各种底层网络的复杂性而便于分析和研究问题,这样就不可避免地要付出些代价,例如在选择路由时多了一些开销。但反过来,如果在路由表中直接使用硬件地址,那就会带来多得多的麻烦。

在划分子网的条件下,分组转发的步骤是:
(1) 从数据报的首部提取目的主机的IP地址D。
(2) 对路由器直接相连的网络逐个进行检查:用各网络的子网掩码S和D进行AND运算,看结果是否和相应的网络地址匹配。若匹配,则把分组进行直接交付(当然还需要把目标IP地址D转换成物理地址,把数据报封装成帧发送出去),转发任务结束。否则就是间接交付,执行 (3)。
(3) 若路由表中有目的地址为D的特定主机路由,则把数据报传送给路由表中所指明的下一跳路由器;否则,执行 (4)。
(4) 对路由表中的每一行(至少含有目的网络地址、子网掩码和下一跳地址),用其中的子网掩码S和D进行AND运算,其结果为N。若N与该行的目的网络地址匹配,则把数据报传送给路由表中所指明的下一跳路由器;否则,执行 (5)。
(5) 若路由表中有一个默认路由,则把数据报传送给路由表中所指明的默认路由器;否则,执行 (6)。
(6) 报告转发分组出错。

再次强调,路由表并没有给分组指明到某个网络的完整路径(即先经过哪一台路由器,再经过哪一台路由器,等等)。路由表指出,到某个网络应当先到某台路由器(下一跳路由器);到达下一跳路由器后,再继续查找其路由表,知道再下一步应当到哪一个路由器。这样一步一步地查找下去,直到最后到达目的网络。目前,路由表项目必须包括目的网络地址(及其子网掩码)和下一跳地址。
5.2 路由算法
理想条件下,路由算法选出将数据从发送方传输到接收方的成本最低的路径。当然,实践中涉及到的因素是很复杂的,比如许多路由器会过滤不同的包。路由算法给出的路由只能是相对于某一种特定要求下得出的较为合理的选择而已。
图论(graph theory)是路由问题的数学基础。一个图G由有序二元组<N,E>确定,记作G=<N,E>(有的资料记作G=(N,E))。N和E分别是结点集和边集。路由器等负责转发分组的网络设备用结点表示;连接结点与结点的边代表路由器之间的链路。每条边都有一个值,称为权(weight),代表分组经过这条边需要花费的成本。这个权值可以是链路的物理长度、链路速率,或者经济成本,等等,也可以是这些因素的一个或几个的函数。此外,每条边通常都是双向(无向)的。
路径(path),指的是一个结点序列(x_1,x_2,…,x_p),p个结点的路径共包含(p-1)条边(x_1,x_2 ),(x_2,x_3 ),…,(x_(p-1),x_p ),其中x_1和x_p分别是起点和终点。
路由算法要求出的结果就是:在网络中,指定发送方(起点)和接收方(终点),求一条双方之间的路径,此路径拥有某种最小的成本。

中心路由算法(centralized routing algorithm)在已知整个网络的必要信息的条件下,计算总开销最低的路径。这就要求计算之前获得足够多的已知条件,如所有的结点标识符、所有的链路及其花费等。计算可以在每台路由器的路由部件上进行,也可以交由路由器连接的远程数据中心进行。具有全局状态信息的算法常称为链路状态算法(link-state algorithm),因为该算法必须考虑每条链路的成本(考虑链路状态)。
去中心路由算法(decentralized routing algorithm)则迭代地、分布式地计算所需路径。没有一个结点具有所有链路的开销的完整信息;相反,每个结点一开始只知道与自己直连的链路的开销。通过迭代的计算过程和信息交换,一个结点最后也能计算出到达若干个接收方的总成本最低的路径。后续将学习的一种去中心化路由算法叫做距离向量(distance-vector)算法,因为每个结点维护一个记录了网络中的其它结点的花销的向量。去中心化路由算法与邻接的路由器交换需要的信息。

路由算法也可分为静态路由(static routing)算法和动态路由(dynamic routing)算法,分别也称非自适应路由算法和自适应路由算法。在静态路由算法中,路由改变得很慢,常常只有在人为干涉(如:编辑了一条链路的花费信息)时,才会导致最终结果变动。动态路由算法在网络拓扑和网络流量改变时,计算出的路由结果一般也会变化。动态路由算法可以周期性地重新运行,也可以在特定的条件下(例如:链路的开销改变,或网络结构改变)自动重新运行。由于动态路由算法更容易受网络状况的影响,因此它们对路由环路(routing loop)、路由振荡(route oscillation)等问题更敏感。路由振荡就是路由的频繁变化。例如某条链路频繁up / down(连接 / 断开),可能就会引起路由器不断重新计算路由。严重时,可以导致网络不稳定、不可用。
静态路由实现简单,开销较小,而动态路由较为复杂,开销较大。因此,动态路由选择适用于较复杂的大网络。

路由算法也可以按照负载敏感(load-sensitive)和负载不敏感(load-insensitive)来分类。在负载敏感型算法中,链路成本动态反映了拥塞程度。早期的ARPAnet路由算法是负载敏感的,算法的应用过程遇到诸多困难。今天的路由算法,如RIP、OSPF、BGP等,则对负载不敏感,链路成本不易受链路当前拥塞程度的影响。

在链路状态算法中,为了让所有结点都获得整个网络的必要信息,每个结点会广播链路状态分组给网络中的其它结点,每个分组包含它所连接的链路的标识符与开销。实际上,这经常通过链路状态广播(link-state broadcast)来完成。最终,所有结点都包含相同的、整个网络的总览。每个结点在这时都可以运行链路状态算法来完成计算。

Dijkstra算法属于链路状态算法,原是针对最短路求解设计,但可以直接套用于求得最小花费的路径。
Dijkstra算法(单源最短路)
用途:求连通图的定点到其余点的最短距离。
算法内容:
设边权为非负的带权连通图G(V,E),边权w(x,y)代表从x到y的边(x,y)的长(直接相连两点的通路长度),定点(源点)s,数组{d_|V| }代表定点s到各点的通路的估计最短距离。
记d_s=0,d的其余元素记为+∞。设集合U代表已经估计最短距离的顶点集合(先不要将s加入集合U)。
循环以下部分直到U=V(|U|=|V|):
对未加入集合U的其它顶点,选出d值最小的顶点x,更新其全部邻接点y(无论是否已访问):
d_y=min(d_y, d_x+w(x,y))=min(|sy|, |sx|+|xy|)
将x放入集合U。
算法结束。此时{d_|V| }代表定点s到各点的通路的最短距离。
由于每次将新的顶点加入集合U之后,都要查找下一个未估计最短距离的顶点,因此总的时间复杂度按O(|V|^2 )估计。
Dijkstra算法是迭代的:当进行k次迭代后,k个结点的最短路被计算完毕。并且,在到所有结点的最短路中,这k条路径的长度最短。
若对上述算法稍加修改,额外进行一些必要的记录,则当LS算法结束后,对每个结点,我们都有沿源点到此结点的最短路的此结点的前驱;于是,可以构造出源点到每个结点的最短路径。在转发表中,可以为每个结点记录以最小开销到达每个目的地的下一跳需要到达的结点。

网络状态变化时,重新运行LS算法后,得到的路径通常也会变化。这种振荡不仅出现在链路状态算法中,还可以出现在基于拥塞或延时的链路测度算法中。若要避免这种振荡,可能第一时间想到的是将算法设计为不依赖链路流量的。但这并不可行,因为路由算法的目标之一就是避免经过高度拥塞的链路。另一个解决方案是:不让所有路由器在相同时间运行LS算法。这看起来是很容易实现的:当路由器运行同一算法的理论速率相同时,将开始运行的时间错开,就可以达到此目的。但是,研究表明,Internet上的路由器在此情况之下会发生自同步,最终使得路由器再次同步执行同一算法。避免自同步的一种方法是:让路由器随机决定发送链路通告的时间。

距离向量算法是迭代的、异步的、分布式的。“分布式的”是因为每个结点从它的一些邻接结点中获取一些信息,进行计算,并将计算结果返回给邻接的结点。“迭代的”是因为算法将一直继续,直到邻接结点之间没有任何新信息可以交换为止。这种算法也是可以自行终止的,无需额外的停止信号。“异步的”是因为算法不要求所有结点按照某种先后顺序(或者说,步调或节奏)配合。

设d_x (y)代表结点x到y的最短路长度,则最短路与著名的Bellman-Ford方程相关,即
█(d_x (y)=min┬v⁡(w(x,v)+d_v (y))#(1) )
min┬v⁡表示在所有可取的结点v中取最小值。该方程的意义相当直观:找到从x到v的最短路后,如果继续取到了v到y的最短路,就得到了x到y的最短路程为w(x,v)+d_v (y)。我们必须先从x的某个邻接点v开始,从x到y的最短路路程便为w(x,v)+d_v (y)可以取到的最小值。其中,必须取遍所有邻接点v。在这之后,对d_v (y)继续按照类似的方法处理。

方程(1)的解可用于构造起始结点x的转发表项。设v^为方程(1)中d_x (y)取得最小值时的邻接点。如果结点x打算向结点y通过最小开销路径发送数据包,则结点x应当先把数据包发送给结点v*。也就是说,结点x的转发表中应当指出目的地为y时下一跳为v。(1)的另一个重要贡献是:指出了DV算法中邻接点之间通信的形式。

其基本思想如下:设网络G=<N,E>,每个结点x从D_x (y)开始,其中D_x (y)是从结点x到y的最小开销路径的开销估计值,x,y都位于网络G中。DV算法令每个结点x维护如下的路由信息:
·对每个邻接结点v,从x到v的开销为c(x,v)。
·结点x的距离向量D_x=(D_x (y): y∈N),包含x到任意的目的地y的总开销的估计值。
·x的每个邻接结点v的距离向量D_v=(D_v (y): y∈N)。
在这个分布式、异步的算法中,每个结点时不时向它的每个邻接结点发送它自己的距离向量的副本。当结点x从一个邻接结点v收到一个新的距离向量时,它保存v的距离向量,并使用方程(1)更新其自己的距离向量:
D_x (y)=min┬v⁡(C(x,v)+D_v (y)), y∈N
如果在此更新步骤中,结点x的距离向量改变了,则结点x将发送更新后的距离向量给它的每个邻接结点,邻接结点便可更新各自的距离向量。照此下去,结点x到任意的目的地y的开销估计值D_x (y)将收敛(converge)至实际的最低开销d_x (y)。

以下是一种DV算法:

在这个DV算法中,与结点x相连的链路的开销有更新,或从邻接结点收到距离向量更新时,将自己的距离向量的估计值更新,并将更新后的距离向量发送给全部的邻接结点。但为了更新x的转发表中包含目的地y的项,结点x需要知道的并不是最短路的路程,而是下一跳需要跳至的结点。
LS算法是中心化的,所有结点在运行Dijkstra算法之前,都需要已知整个网络的必要信息。而DV算法是去中心化的,无需这些全局信息,每个结点仅需邻接结点的相关信息和从这些邻接结点发来的消息。DV算法应用于许多路由协议,比如Internet的RIP、BGP、ISO IDRP和Novell IPX。早期的ARPAnet也有使用。

上图给出一个环路,考虑两种情况(为了简便,仅考虑y和z的距离表中目的地为x的项):
a、边(x,y)的开销从4减少到1;b、边(x,y)的开销从4增加到60。
【情况a】
·在t_0时刻,y检测到了链路开销改变(从4到1),因此更新了自己的距离向量,并通知其邻接结点。
·在t_1时刻,z收到了y发来的距离向量,更新了自己的距离表。它重新计算了到x的最小开销(从5减低到2),并将它的新的距离向量发送给邻接结点。
·在t_2时刻,y收到了z发来的更新,更新了自己的距离表。y到其它结点的最小开销并未改变,所以y不向z发送任何消息。算法结束。
在本情况中,DV算法只进行了两次迭代就停止了。
【情况b】
需要用到的部分变量的初值是:
D_y (x)=4, D_y (z)=1, D_z (y)=1, D_z (x)=5
·在t_0时刻,y发现链路开销改变了(从4到60),因此重新计算了到x的最小开销路。注意:现在只有D_y (x)从4变成了60,其它值还没来得及更新,因此最短路为y→z→x,路程长度为6。
这就构成了一条路由环路(routing loop)。路由环路是一个黑洞——一个原计划转发到目的地的数据包,因故在某段路径之间循环。如果路由表不再改变,那么数据包就会永远在环路中循环。在本例中,如果数据包从y出发(无论是在传送中途继续出发还是开始传送),走最小开销路径就要经过z;如果数据包从z出发(无论是在传送中途继续出发还是开始传送),走最小开销路径就要经过y。
·后来,y更新了自己的距离向量,并通知给邻接结点。
·在t_1时刻,z收到了y的距离向量更新:y到x的最小开销路径长为6。于是z重新计算最小开销路径为z→y→x,路径总长为7。之后,z也向y发送已更新的距离向量。
·以此类推,该循环经过46次迭代后,D_z (x)>50。这时,z才能发现到x的最小开销路径为z→x。
这还不是最坏的情况。万一链路(x,y)和(x,z)堵塞,开销分别达到10000和9999,网络状态就非常难看了。这种问题有时称为无穷计数(count-to-infinity)。

上述问题可以通过毒性反转(poisoned reverse)解决。思路很简单:如果z需要经过y到达x,那么z将通知y,(z,x)的权为无限,即D_z (x)=+∞。只要后续还需要经过y到达x,那么这个谎就要继续撒下去。当然,y是相信z提供的信息的,于是y判定z到x之间没有边直接相连,于是y就不会尝试经过z到达x。
使用此策略后,回顾情况b。
y的距离表已经记录了D_z (x)=+∞。而(x,y)的长度已经从4增加到60,y更新自己的表以后,直接将到达y的需要发向x的全部数据包都路由到x,此时D_y (x)=60。这一点也会由y通知z。
在t_1时刻收到更新后,z马上将(z,x)的开销改为原来的50。这会是一条新的到x的最小开销路径,且不经过y,于是z就不需要再继续欺骗,而是在t_2时通知y:D_z (x)=50。
y收到z的通知后,y成功更新其距离表:D_y (x)=51(y→z→x)。根据毒性反转策略,这时y也会通知z:D_y (x)=+∞。
归结起来,就是当某个结点发现与自己相连的某条链路高度拥塞或断开后,就将自己到原先通过此链路连接的结点这条路径设为不可达(将故障链路毒化),并通知相邻的结点。
然而,这个单纯的毒性逆转方法仅仅对包含两个邻接结点的回路有效,无法解决更复杂的回路问题。

在DV算法中,每个结点只与邻接结点做额外的通信,但给出了涉及网络中的全部结点的信息;而LS算法要求全局信息,每个结点与其它结点均需要通信,但只提供邻接结点的信息。
我们从三个方面来比较这两种算法:
·报文复杂度。LS要求每个结点都知道全部链路的开销,需要发送信息O(|N||E|)条。当一条链路开销改变时,改变后的值必须通知到全部结点。DV算法只需要每次迭代时在邻接结点之间传输信息。算法收敛所需时间依赖于许多因素。链路开销改变时,DV算法仅在新的链路开销导致与该链路相连的结点的最低开销路径发生改变的时候,才传播已改变的链路开销。
·收敛速率。上面给出的LS算法是O(|N|^2 )的,并要求发送O(|N||E|)条报文。DV收敛得较慢,且存在路由环路和无穷计数问题。
·健壮性。当一台路由器故障时,在LS算法下,路由器会广播不正确的开销信息给邻接结点。在LS广播中,收到的数据包可能也会丢失或损坏。但是一个LS结点仅计算自己的转发表;其它结点也自行执行类似的计算。这就意味着在LS算法下,路由计算在某种程度上是分离的,提供了一定程度的健壮性。在DV算法下,一个结点可向任意或所有目的结点通告其不正确的最低开销路径。1997年,一个小型ISP的某台路由器的功能不正常,向美国的主干路由器提供了错误的路由信息,导致其它路由器向该故障路由器发送了大量流量,致使大部分Internet连接中断数小时。更一般地说,我们发现,每次迭代时,在DV算法中,一个结点的计算结果会传递给它的邻居,然后在下次迭代时再间接地传递给邻居的邻居。在此情况下,DV算法中一个不正确的结点计算值会扩散到整个网络。
总之,不能说两个算法的哪一个总是更有优势。这两种算法都在Internet中大量使用。
5.3 域内路由:RIP和OSPF
迄今为止的算法研究中,我们都将网络视为一个互连的路由器的简单集合,路由器之间没有什么区别。实际上,这个模型还是过于简单,难以描述当今的各种网络。原因主要有:
·规模。当网络变得极大时,路由器之间的通信、计算和存储路由信息的开销都将变得极其巨大。如今的Internet拥有至少数亿台路由器,存储所有可能的路由目的地需要天文数字的内存;在路由器间同步更新链路状态的消耗也是非常可观的,尤其是网络状态变化剧烈的时候,大量的带宽会消耗在交换变化的路由信息上,妨碍正常的数据通信。
·1.3节说过,Internet是一个ISP组成的网络,每个ISP都拥有自己的路由器网络。ISP通常希望能按照自己的意愿管理网络,例如运行何种路由算法,或向外界隐藏网络的内部结构。ISP或其它组织应当可以自行管理自己的网络(这是属于组织或部门内部的事情),并且仍然对外保持正常连接。
·没有考虑路由表的一致性。Internet设备分布广,对象多,动态变化,要及时地反映全部路由表是不可能的。因此,一旦发生动态变化,路由表会在相当长的时间内丢失一致性,这将导致寻址错误。因此,要保证路由表的一致性和完整性,有必要变化的影响限制在Internet中的一定范围内,让其它部分不会总是感觉在变化。
这些问题都可以通过自治系统(autonomous system,AS)来解决。每个AS包含一组路由器,它们运行在相同的管理协议下。一个AS经常由一个ISP里的路由器及路由器间的链路构成。一些ISP则将网络分给多个AS。有的Tier-1 ISP使用单个巨大的AS管理整个网络;其它Tier-1 ISP则将它们管理的ISP划分在数十个互连的AS中。每个自治系统由全球唯一的自治系统号(ASN)标识。ASN类似IP地址,由ICANN地区注册机构分配。
在2007年以前,ASN的长度为16位。从2007年初开始,各区域互联网注册管理机构已开始分配32位长度的ASN。这些编号将以“<高16位数值的10进制形式>.<低16位数值的10进制形式>”的形式来使用。RFC 4893说明了在BGP(见5.4节)中使用32位的ASN的方法。例如编号为“268468224”(10008000h)的ASN写作“4096.32768”。

同一AS的路由器运行相同的路由算法,并互相拥有对方的信息。在自治系统中运行的路由算法称为自治系统内路由协议(intra-autonomous system routing protocol),也称域内路由选择(intradomain routing)协议或内部网关协议(interior gateway protocol,IGP)或内部路由器协议(IRP)。

路由信息协议(routing information protocol,RIP)是内部网关协议中最先得到广泛使用的协议,是一种分布式的基于距离向量的路由选择协议,是互联网的标准协议,其最大优点就是简单。
RIP要求网络中的每一台路由器都要维护从它自己到其它每一个目的网络的距离记录(因此这是一组距离,即“距离向量”)。RIP协议将“距离”定义如下:
从一台路由器到直接连接的网络的距离为l;从一台路由器到非直接连接的网络的距离为经过的路由器数加1。
距离也称跳数(hop count)。每经过一台路由器,累计的跳数就加1。RIP认为,好的路由通过的路由器数目少,即“距离短”。RIP允许一条路径最多包含15个路由器。因此跳数等于16即不可达。可见RIP只适用于小型网络。
到直接连接的网络的距离也可定义为0。但两种不同的定义对实现RIP协议并无太大影响,因为重要的是找出最短距离,将所有的距离都加1或都减1,在不达到跳数限制的情况下,对选择最佳路由其实是一样的。
RIP不能在两个网络之间同时使用多条路由。RIP总是选择一条具有最少路由器的路由,哪怕还存在另一条高速(低时延)但路由器较多的路由。

RIP的特点是:
(1)仅和相邻路由器交换信息。如果两台路由器之间的通信不需要经过另一个路由器,那么这两台路由器就是相邻的。RIP规定,不相邻的路由器不交换信息。
(2)路由器交换的信息是本路由器当前知道的全部信息,即自己现在的路由表。也就是说,交换的信息是:到本自治系统中所有网络的(最短)距离,以及到每个网络应经过的下一跳路由器。
(3)按固定的时间间隔交换路由信息,例如,每隔30秒。然后路由器根据收到的路由信息更新路由表。当网络拓扑变化时,路由器也及时向相邻路由器通告拓扑变化后的路由信息。
路由器在刚刚开始工作时,它的路由表是空的。然后路由器就得出到直接相连的几个网络的距离(这些距离定义为1)。接着,每台路由器也只和数目非常有限的相邻路由器交换并更新路由信息。但经过若干次的更新后,所有的路由器最终都会知道到达本自治系统中任何一个网络的最短距离和下一跳路由器的地址。

现在较新的RIP版本是1998年11月公布的RIP2 [RFC2453](已成为互联网标准),新版本协议本身并无多大变化,但性能上有些改进。RIP2支持变长子网掩码和CIDR,还提供简单的鉴别(authentication)过程,也支持多播。
RIP2的报文格式如下:它的报头与RIP1相同,但后面的路由部分不一样。RIP是使用UDP进行传送的,端口为520。

RIP的报头有4字节,命令字段指出报文的意义。例如,1表示请求路由信息,2表示对请求路由信息的响应或未被请求而发出的路由更新报文。首部后面的“必为0”是为了4字节字的对齐。
RIP2报文中的路由部分由若干个路由信息组成。每个路由信息需要用20个字节。地址族标识符(地址类别)字段标识使用的地址协议。如采用IP地址就,值就为2(RIP也可用于非TCP/IP的情况)。路由标记填入自治系统号(ASN),这是考虑使RIP有可能收到本自治系统以外的路由选择信息。再在后面指出某个网络地址、该网络的子网掩码、下一跳路由器地址以及到此网络的距离。一份RIP报文最多可包括25个路由,因而RIP报文的最大长度是4+20×25=504字节。如超过,必须再用一份RIP报文来传送。
RIP2还具有简单的鉴别功能(确认合法的报文)。若使用鉴别,则将原来写入第一个路由信息(20字节)的位置用作鉴别。这时应将地址族标识符置为全1(FFFFh),而路由标记写入鉴别类型,剩下的16字节为鉴别数据。在鉴别数据之后才写入路由信息,但这时最多只能再放入24条路由信息。

RIP存在的一个问题是:当网络出现故障时,要经过比较长的时间才能将此信息传送到所有的路由器。但如果一台路由器发现了更短的路由,那么这种更新信息就传播得很快。这是RIP的特点:好消息传播得快,而坏消息传播得慢。网络故障信息的传播往往需要较长的时间(例如数分钟)。这是RIP的一个主要缺点。
为了使坏消息传播得更快些,可以采取多种措施。例如,让路由器记录收到某特定路由信息的接口,而不让同一路由信息再通过此接口向反方向传送。
使用RIP时,路由器之间交换的路由信息是路由器中的完整路由表,因而随着网络规模的扩大,开销也就增加。再结合“坏消息传播得慢”从而使得更新过程的收敛时间过长的问题,对于规模较大的网络就应当使用下面所述的OSPF协议。然而目前在规模较小的网络中,使用RIP的仍占多数。

在RIP2之后,还有一个新版本叫做RIPng(ng = next generation),定义于RFC 2080。这是RIPv2的一个扩展,提供了对IPv6的支持。但RIPng不再支持身份验证。IPv6路由器使用IPsec来进行身份验证。

开放最短路优先(Open shortest path first,OSPF)路由以及与它很相似的IS-IS(Intermediate System to Intermediate System),是Internet中Intra-AS路由常用的两个协议。OSPF的O代表open,表明该协议的规范是公开的。其最新版本OSPFv3定义于RFC 5340中。最初,OSPF是为了克服RIP的缺点在1989年开发出来的。
OSPF是一个LS协议,使用链路状态信息洪水(通过所有输出端口向相邻的路由器发送信息)和Dijkstra最短路算法。借助OSPF,每台路由器都构建了整个自治系统的完整拓扑。路由器在本地运行Dijkstra算法,为所有子网生成最短路树(一个连通的无向图G,以一个顶点v为根的最短路树满足:根结点v到任何其它顶点u的路径距离,等于图G中v到u的最短路径长度),其自身为根结点。每条链路的开销由网络管理员配置:假如把所有链路的开销都设为1,则Dijkstra算法构造的路由表将进行最小跳数路由;如果将开销设为与链路容量成反比例关系,则避免流量经过低带宽链路。OSPF还可根据IP数据报的TOS位的不同来设置不同的链路开销。总之,OSPF不强制执行设定链路权值的策略,这个职责交由网络管理员;但OSPF提供了根据给出的链路权值来计算最小开销路径的机制。
有了OSPF,一台路由器会向同一个AS中的其它全部路由器广播路由信息,而不仅仅向邻接的路由器发送。当链路状态(上行 / 下行状态或监测到的开销)改变时,会广播链路状态信息。它同样会周期性地广播链路状态(例如每30分钟一次),即使链路状态未发生变化。RFC 2328指出:“这种周期性的更新为链路状态算法增加了稳定性。” OSPF通告包括OSPF信息,不使用UDP而是直接由IP传递(降低频繁交换路由信息的额外开销),上层协议号为89。所以,OSPF协议必须自行确保可靠报文传输和链路广播等特性。OSPF向邻接结点发送一条HELLO报文,确定链路连通,于是允许OSPF路由器获得邻接路由器的网络范围的链路状态的数据库。
勘误:谢希仁《计算机网络》(第7版)第159页“只有当链路状态发生变化时,路由器才向所有路由器用洪泛法发送此信息。而不像RIP那样,不管网络拓扑有无发生变化,路由器之间都要定期交换路由表的信息。”与RFC 2328不符。

之前讨论链路状态路由时,都假设各个链路的权值(开销)已知,即OSPF之类的路由算法已经运行过,流量根据LS算法计算出的路由表流动。从因果关系来说,链路权重先给出,Dijkstra算法再产生结果——即路由,该路由的总开销最小。
实际上,这个因果关系可能反转,即根据路由目标来决定链路权重。例如,想让每条链路的最大利用率最小,则网管需要根据已知条件,如每个链路出入口的流量估计,来设置权重。
OSPF允许管理员给每条路由指派不同的代价。例如,高带宽的卫星链路对于非实时的业务可设置为较低的代价,但对于时延敏感的业务就可设置为非常高的代价。因此,OSPF对于不同类型的业务可计算出不同的路由。链路的代价可以是1至65535中的任何一个无量纲的数,因此十分灵活。商用的网络在使用OSPF时,通常根据链路带宽来计算链路的代价。这种灵活性是RIP所没有的。

OSPF的优点主要有:
·安全。OSPF路由器之间交换的信息可以进行鉴别,只有可信的路由器能在同一个AS内参与OSPF协议,于是得以避免恶意入侵者(或用新学到的知识在网络里乱搞的计算机网络课程学生)向路由表注入恶意信息。默认设置下,OSPF分组不被鉴别,可以被伪造。鉴别方法有两类:简单模式和MD5。在简单鉴别下,每台路由器配置相同的密码。路由器发送OSPF分组时,包括纯文本的密码。这显然是不安全的。MD5鉴别基于所有路由器中配置的共享密钥(shared secret key)。路由器发送每个OSPF分组时,都将分组连同附加的密钥一起计算MD5哈希。然后,路由器将哈希值写入OSPF分组。接收路由器则按照预置的密钥,计算MD5并与分组中附带的计算结果比较,鉴别其内容的正确性。MD5鉴别也用到了顺序号,防止重放攻击(replay attack,是指攻击者发送一个目标主机已接收过的包,来达到欺骗系统的目的,主要用于身份认证过程,破坏认证的正确性。)
·多条相同开销的路径。当到达同一目的地的相同开销的路径具有多条时,OSPF允许同时使用多条路径同时传输。相比之下,RIP只能找出到某个网络的一条路径。
·对单播与多播路由的综合支持。多播OSPF(MOSPF)提供了OSPF的简单扩展,支持多播路由。MOSPF使用已存在的OSPF链路数据库并添加一种新型的链路状态通告给已存在的OSPF链路状态广播机制。
·对单个自治系统提供层次性。OSPF自治系统可以划分为多个由32位的区域标识符(用点分十进制表示)标识的区域(area),每个区运行自己的OSPF链路状态路由算法,路由器仅对和自己位于同一区域的其它路由器广播链路状态,减少了整个网络的流量。在每个区域内,区域边界的若干台路由器路由数据包到其它区域。一个区域内部的路由器只知道本区域的完整网络拓扑,而不知道其它区域的网络拓扑。在一个AS中只有一个OSPF区域配置为主干区域(backbone area)0.0.0.0。骨干区域负责与同一自治系统的其它区域路由流量,总是包括整个AS的全部区域边界路由器(边缘路由器),不过也可以包含非边界路由器。AS内的跨区路由要求数据包先被路由到区域边界路由器(Intra-AS路由),然后通过骨干区域到达目的地所在区域的区域边界路由器,再到达最终目的地。当然,一个区域最好不要太大。
·OSPF的更新过程收敛较快。这使得链路状态数据库能较快地进行更新,并使各个路由器能及时更新其路由表。

此外,OSPF还具有如下特点:
·OSPF支持可变长度的子网划分和无分类的编址CIDR。
·由于网络中的链路状态可能经常发生变化,因此OSPF让每一个链路状态都带上一个32位的序号,序号越大状态就越新。OSPF规定,链路状态序号增长的速率不得超过每5秒钟1次。这样,全部序号空间在600年内不会产生重复号。

OSPF构成的数据报很短。这样做可减少路由信息的通信量,也不必将数据报分片。
OSPF的首部固定为24字节,各字段的意义是:
·版本。例如2或3。
·类型。可以是五种类型分组中的一种。
·分组长度。包括OSPF首部在内的分组长度,以字节为单位。
·路由器标识符。标志发送该分组的路由器的接口的IP地址。
·区域标识符。分组属于的区域的标识符。
·检验和。用来检测分组中的差错。
·鉴别类型。目前只有两种,0(无)和1(口令)。
·鉴别。鉴别类型为0时就填0,鉴别类型为1则填入8个字符的口令。

OSPF的五种分组类型分别是:
(1) 类型1,问候(Hello)分组,用来发现和维持邻站的可达性。
(2) 类型2,数据库描述(Database Description)分组,向邻站给出自己的链路状态数据库中的所有链路状态项目的摘要。
(3) 类型3,链路状态请求(Link State Request)分组,向对方请求发送某些链路状态项目的详细信息。
(4) 类型4,链路状态更新(Link State Update)分组,用洪泛法对全网更新链路状态。这种分组是最复杂的,也是OSPF协议最核心的部分。路由器使用这种分组将其链路状态通知给邻站。该类分组共有5种不同的链路状态,这里从略。
(5) 类型5,链路状态确认(Link State Acknowledgment)分组,对链路更新分组的确认。
OSPF规定,每两台相邻路由器每隔10秒钟要交换一次问候分组,这样就能确知哪些邻站是可达的。对相邻路由器来说,“可达”是最基本的要求,因为只有可达邻站的链路状态信息才存入链路状态数据库(路由表就是根据链路状态数据库计算出来的)。在正常情况下,网络中传送的绝大多数OSPF分组都是问候分组。若有40秒没有收到某个相邻路由器发来的问候分组,则可认为该相邻路由器是不可达的,应立即修改链路状态数据库,并重新计算路由表。
其它四种分组都用来同步链路状态数据库。同步,就是使得不同路由器的链路状态数据库的内容是一样的。两个同步的路由器叫做“完全邻接的”(fully adjacent)路由器。不是完全邻接的路由器表明它们虽然在物理上是相邻的,但其链路状态数据库并没有达到一致。当一台路由器刚开始工作时,它只能通过问候分组得知有哪些相邻的路由器在工作,以及将数据发往相邻路由器所需的开销。如果所有的路由器都把自己的本地链路状态信息对全网进行广播,那么各路由器只要将这些链路状态信息综合起来就可得出链路状态数据库。但这样做开销太大,因此OSPF采用下面的办法:
OSPF让每一台路由器用数据库描述分组和相邻路由器交换本数据库中已有的链路状态摘要信息。摘要信息主要指出:有哪些路由器的链路状态信息(及其序号)已经写入数据库。与相邻路由器交换数据库描述分组后,路由器就使用链路状态请求分组,向对方请求自己缺少的链路状态项目的详细信息。通过一系列这种分组交换,全网同步的链路数据库就建立了。

只要一台路由器的链路状态发生变化,该路由器就要使用链路状态更新分组,用洪泛法向全网更新链路状态。OSPF使用的是可靠的洪泛法:路由器用洪泛法发出链路状态更新分组,先发给相邻的路由器。路由器将收到的分组再进行转发时,要将其上游路由器排除在外。可靠的洪泛法在收到更新分组后发送确认(收到重复的更新分组只需要发送一次确认)。
一台路由器的链路状态只涉及到与相邻路由器的连通状态,与整个互联网的规模并无直接关系。因此当网络规模很大时,OSPF协议要比RIP好得多。OSPF没有“坏消息传播得慢”的问题,据统计,其响应网络变化的时间小于100 ms。
若N台路由器连接在一个以太网上,则每台路由器要向其它(N-1)台路由器发送链路状态信息,因而共有N(N—1)个链路状态要在这个以太网上传送。OSPF协议对这种多点接入的局域网采用了指定的路由器(designated router)的方法,使广播的信息量大大减少。指定的路由器代表该局域网上所有的链路向连接到该网络上的各路由器发送状态信息。
5.4 ISP间的路由:BGP
为了能在不同的自治系统之间通信,互相通信的AS必须运行相同的自治系统间路由协议(inter-autonomous system routing protocol),也称域间路由选择(intradomain routing)协议或或外部网关协议(exterior gateway protocol,EGP)或外部路由器协议(ERP)。事实上,Internet中的全部AS都运行同一个Inter-AS协议:边界网关协议(Border Gateway Protocol,BGP)。它是去中心化、异步的,是DV路由的重要支柱。BGP的最新版本为BGP4,定义于RFC 4271,在2006年发布。
BGP采用了路径向量(path vector)路由协议,它与距离向量协议(如RIP)和链路状态协议(如OSPF)有很大的区别。

在配置BGP时,每一个自治系统的管理员要选择至少一台路由器作为该自治系统的BGP发言人(BGP speaker,目前还没有更好的译名)。一般说来,两个BGP发言人都是通过一个共享网络连接在一起的。BGP发言人往往就是边界路由器,但也可以不是边界路由器。大多数AS在一台路由器上运行BGP。
BGP发言人与其它AS的BGP发言人要交换路由信息,就要先建立TCP连接(端口号为179),然后在此连接上交换BGP报文以建立BGP会话,利用BGP会话交换路由信息,如增加新的路由,或撤销过时路由,报告出错情况等等。使用TCP连接能提供可靠的服务,也简化了路由协议。使用TCP连接交换路由信息的两个BGP发言人,彼此成为对方的邻站(neighbor)或对等站(peer)。BGP报文使用TCP传送的原因是:面对的网络环境复杂,可靠性要求高。

在BGP中,分组不路由到特定的目标地址,而是根据CIDR前缀代表的一个或一组子网进行路由。例如,目的地可能是138.16.68/22,共计1024个IP地址。路由器的转发表项格式为有序对<p,I>,p代表这样的前缀,而I代表路由器的一个接口的接口号。

BGP支持每台路由器:
1、从邻接的自治系统获得前缀的可达性信息(到达某个网络需要经过的一系列自治系统)。BGP允许每个子网向Internet宣告其存在性。
2、根据前缀确定路由。路由到一个前缀可能有多条路线,路由器本地运行BGP路由选择过程(使用从邻接路由器接收到的可达性信息),结合指定的策略确定路线。
BGP交换路由信息的结点数量级是自治系统个数的量级,这要比这些自治系统中的网络数少很多。要在许多自治系统之间寻找一条较好的路径,就是要寻找正确的BGP发言人(或边界路由器),而在每一个自治系统中BGP发言人(或边界路由器)的数目是很少的。这样就使得自治系统之间的路由选择不致过分复杂。

单个自治系统内的各个路由器会建立iBGP(internal BGP)连接;而跨越两个AS的BGP连接称为eBGP(external BGP)连接。eBGP报文在自治系统内传输时,不附加任何存在性信息;到达新的自治系统后,网关路由器(边界路由器)会附加刻画本自治系统存在的信息,将其传递给内部路由器(与网关路由器相对)和其它自治系统的网关路由器。

路由器通过BGP通告前缀时,包括几个BGP属性。前缀连同属性一起叫做路由(route)。两个较重要的属性是AS-PATH和NEXT-HOP。AS-PATH包括通告已经经过的自治系统列表。为了更新AS-PATH,当一个前缀经过一个AS时,这个AS就把自己的ASN添加到AS-PATH里的列表去。BGP路由器也通过AS-PATH属性阻止环形通告:当路由器发现自己的AS已经在列表里的时候,就拒绝该通告。
NEXT-HOP(下一跳)属性提供了自治系统内和自治系统间路由协议之间的关键链路。NEXT-HOP是一个路由器接口的IP地址,它作为AS-PATH的开端。BGP报文将被转发到NEXT-HOP指向的路由器。

在BGP刚刚运行时,BGP邻站交换整张BGP路由表。但以后只需要在发生变化时更新有变化的部分。这样做对节省网络带宽和减少路由器的处理开销方面都有好处。

RFC 4271规定了BGP4的四种报文:
(1)OPEN(打开)报文,用来与相邻的另一个BGP发言人建立关系,使通信初始化。
(2)UPDATE(更新)报文,用来通告某一路由的信息,以及列出要撤销的多条路由。
(3)KEEPALIVE(保活)报文,用来周期性地证实邻站的连通性。
(4)NOTIFICATION(通知)报文,用来发送检测到的差错。
若两个邻站属于两个不同AS,而其中一个邻站打算和另一个邻站定期地交换路由信息,这就应当有一个商谈的过程(因为很可能对方路由器的负荷已很重因而不愿意再加重负担)。因此,一开始向邻站进行商谈时就必须发送OPEN报文。如果邻站接受这种邻站关系,就用KEEPALIVE报文响应。这样,两个BGP发言人的邻站关系就建立了。
一旦邻站关系建立了,就要继续维持这种关系。双方中的每一方都需要确信对方是存在的,且一直在保持这种邻站关系。为此,这两个BGP发言人彼此要周期性地交换KEEPALIVE报文(一般每隔30秒)。KEEPALIVE报文只有19字节长(只用BGP报文的通用首部),因此不会造成网络上太大的开销。
UPDATE报文是BGP的核心内容。BGP发言人可以用UPDATE报文撤销它以前曾经通知过的路由,也可以宣布增加新的路由。撤销路由可以一次撤销许多条,但增加新路由时,每份更新报文只能增加一条。

BGP可以很容易地解决距离向量路由选择算法中的“坏消息传播得慢”这一问题。当某路由器或链路故障时,由于BGP发言人可以从不止一个邻站获得路由信息,因此很容易选择出新的路由。距离向量算法往往不能给出正确的选择,是因为这些算法不能指出哪些邻站到目的站的路由是独立的。

BGP报文格式如下。四种类型的BGP报文具有同样的通用报头,其长度为19字节。通用报头分为三个字段:
标记(marker)字段16字节,用来鉴别收到的BGP报文(假定将来会出现合理的鉴别方案)。不使用鉴别时置全l。
长度字段指出包括通用首部在内的整个BGP报文以字节为单位的长度,最小值是19,最大值是4096。
类型字段的值为1到4,分别对应于上述四种BGP报文中的一种。

OPEN报文共有6个字段:版本(1字节,现在的值是4)、本自治系统号(2字节)、持续时间(2字节,以秒计算的保持为邻站关系的时间)、BGP标识符(4字节,通常就是该路由器的IP地址)、可选参数长度(1字节)和可选参数。
UPDATE报文共有5个字段,即不可行路由长度(2字节,指明下一个字段的长度)、撤销的路由(列出所有要撤销的路由)、路径属性总长度(2字节,指明下一个字段的长度)、路径属性(定义在这个报文中增加的路径的属性)和网络层可达性信息NLRI(Network Layer Reachability Information)。最后这个字段定义发出此报文的网络,包括网络前缀的位数、IP地址前缀。
KEEPALIVE报文只有BGP的19字节长的通用首部。
NOTIFICATION报文有3个字段,即错误代码(1字节)、错误子代码(1字节)和错误数据(给出差错的诊断信息)。

下面介绍热土豆路由(hot potato routing)。
该算法选择到NEXT-HOP的最小开销的路径。一般而言,要到达下一跳路由器所在的网关有多条路径,热土豆路由将选择开销最小的那条,然后将相应内容写入转发表。
该算法倾向于尽快将需要转发的分组传出当前的自治系统,而不考虑接下来的开销。就像你手里托着一个烫手的土豆,你只想尽快将它移走。所以该算法是一个自私的算法,它仅仅考虑将花在当前系统内的开销降到最低。同一AS内的不同路由器运行热土豆路由算法时,即便目的地相同,选出的路径也可以是不同的。

实践中,BGP使用更复杂的算法,尽管该算法也结合了热土豆路由的特点。对任何给定的目的地(前缀),输入BGP路由选择算法的是路由器已学习和接受的所有到达该前缀的路径。如果路径数不止一条,则依次按照下列规则淘汰,直到只剩下1条路由:
1、每条路由会被分配一个本地偏好(local preference)属性值。本地偏好可能由该路由器设置,或可能由在相同AS中的另一台路由器学习到。本地偏好属性由管理员设定,该值最高的路由将会被留下。
2、对剩余的路由(均拥有最高的本地偏好值),选择AS-PATH长度最短的。
3、对剩余的路由(均拥有最短的AS-PATH长度),执行热土豆路由算法,选择能用最小代价跳至下一跳的路由。
4、对剩余的路由,使用BGP标识符选择。
如果按照上述策略,BGP则不再是一个自私的算法:它首先考虑具有最短的自治系统路径(跳数最少)的路由。这将减小端到端延迟。
BGP是Internet的跨自治系统路由的实际标准。

除了作为Internet的Inter-AS路由协议,BGP还常用于实现IP任播服务。
DNS系统将DNS记录分布在众多DNS服务器上。当用户需要查找DNS时,用户被尽可能指向延迟最低的服务器获得内容。BGP路由选择算法为实现此目标提供了便利。CDN也可以使用IP任播,但实际上一般不使用,因为BGP路由可能导致同一个TCP连接的不同分组被导向不同的Web服务器。

商业ISP通常遵循这样的原则:任何流经它们的主干网络的流量的源或目的地至少要有一个为该ISP的客户。如果不采取这样的策略,源和目的地都不是该ISP客户的流量将可以途经该ISP的主干网络。也就是说,这些流量“白嫖”了这个ISP的主干网络资源。

为何自治系统内和自治系统间的路由使用不同的路由协议?因为这两种路由的目标在本质上是不同的:
·策略。在AS之间,路由策略是必须考虑的。AS一般很希望能控制经过自己的其它AS的流量,并且这些控制往往与经济、政治和安全等方面的考虑。比如说:有的自治系统愿意或不愿意让某些数据报通过本网络。又比如:我国国内的站点在互相传送数据报时不应经过国外兜圈子,特别是不要经过某些对我国的安全有威胁的国家。
BGP路由器之间传送的信息会包含该信息已经经过的路径,所以这种控制功能还是很容易实现的。在单个AS内,一切一般都遵循相同的管理策略,因此这些策略对路由的影响不大。
·规模。互联网的规模太大,使得自治系统之间的路由选择非常困难。目前在互联网的主干网路由器中,一张路由表的项目数早已超过了数万个网络前缀。如果使用链路状态协议,则每一台路由器都必须维持一个很大的链路状态数据库。对于这样大的主干网用Dijkstra算法计算最短路径时花费的时间也太长。另外,由于自治系统AS各自运行自己选定的内部路由选择协议,在不同AS之间,链路开销通常使用不同的单位,代表的意义往往也不同。因此,当一条路径通过几个不同AS时,要想对这样的路径计算出有意义的代价基本是不可能的。比较合理的做法是:在AS之间交换可达性信息。例如:仅告诉相邻路由器,到达目标网络可以经过哪些自治系统。
在AS之间路由时,要求路由算法和用到的数据结构能在大规模的网络中依然能正常运行。在单个AS内,规模的伸缩性(scalability)就不太看重了。如果单个ISP变得太大,则它总是可能把自己管理的网络分为若干个AS,然后在它们之间使用Inter-AS路由。
·性能。AS间路由是面向策略的,路由性能等指标一般不是首要考虑的因素,即有时为了满足相应的策略,宁愿选择更长的或花销更大的路由。实际上,刚才介绍的Inter-AS路由策略甚至都没有考虑链路开销,而主要考虑跳数。不过在单个AS内,情况就相反了,不大考虑策略,而是更着重性能。

对于BGP而言,只能是力求寻找一条能够到达目的网络且比较好的路由(例如不能在环路中反复传送,或数据报不能绕得太远),而并非要寻找一条最佳路由。

下面我们用一个实例来理清这几章的内容。
假设某单位创建了一个网络,有许多服务器:Web服务器,对外展示单位的主要信息,例如产品和服务;邮件服务器,负责与外界收发邮件;以及DNS服务器。
首先,需要获得Internet连接。单位需要向本地ISP联系,申请接入Internet;然后,需要部署网关路由器,它们负责连接到本地ISP的路由器。网线常使用双绞铜线或光纤。本地ISP会划给单位一片IP地址。建立物理连接并获得IP地址后,就可以向单位内的各个服务器指派IP地址了:Web服务器、邮件服务器、DNS服务器和网关路由器都需要IP地址,其它服务器和网络设备也都需要一个或多个IP地址。
除了与ISP签订合同,还需要向Internet注册机构获得域名。单位还需要出现在DNS系统中:为了访问各个服务器,外界需要先行访问单位的DNS服务器,所以必须向注册登记机构提供DNS服务器的IP地址。注册登记机构将向顶域服务器中为单位的DNS服务器增加记录条目。之后,外界用户只要知道域名,就可以通过DNS服务器获得单位的IP并访问了。
DNS服务器中,需要将域名映射到相应的服务器,例如Web服务器和邮件服务器,的IP地址。其它允许公开访问的服务器亦是如此。
外界向单位的服务器发送IP数据报时,要经过若干台路由器。为了正确确定转发链路,每台路由器都需要查找它的转发表。因此,它们必须得知单位所在子网的前缀。当ISP为单位分配了前缀后,ISP通过BGP通知它连接的ISP们,这些ISP也会不断将通告分发,最终Internet上的所有路由器都会存储此前缀至转发表。
5.5 SDN
SDN架构的四个主要特性如下:
·基于流的转发。SDN控制的交换机在进行分组转发时,可以同时根据运输层、网络层和链路层的一些字段来选择转发链路;相比之下,传统的转发机制仅根据IP数据报的目标IP地址转发。
·SDN将网络层划分为数据层面和控制层面。数据层面包含交换机,仅负责快速执行“匹配-动作”规则,查找流表,做出动作;而控制层面包括服务器和软件,管理交换机的流表。
·控制功能位于交换机外部。SDN控制层面是用软件实现的。与传统路由器不同,软件执行在远程服务器上,而不是交换机上。控制层面可以分为SDN控制器(或网络操作系统)和网络控制应用程序。控制器维护精确的网络状态信息,比如远程链路、交换机和主机的状态;同时提供允许应用程序监视、编程和控制所属网络设备的机制。控制器一般由许多服务器同时运行。
·可编程网络。由于运行在控制层面的应用程序的支持,网络是可编程的。SDN控制器提供API给这些应用程序,后者实现对数据层面的控制。例如,一个路由控制程序给出源与目的地之间的端到端路径(通过Dijkstra算法,使用SDN控制器维护的链路状态和结点状态信息计算出结果);另一个程序可能执行访问控制,比如阻止某些可疑数据包;还有一个程序以调控各个服务器的负载平衡的方式转发数据包。

在SDN中,网络的各个部件,比如交换机、SDN控制器、控制程序等,是单独的实体,每个实体都可以具有不同的供应商,也可以属于不同的组织。传统的网络模型中,交换机、路由器等相似的实体通常由单个提供商提供。这大大驱动了一个丰富、开放的网络生态系统的发展。

SDN控制器可以分为三层:
·通信层:在SDN控制器和被控制的网络设备之间通信。如果SDN控制器需要控制启用了SDN的远程设备,则需要运行相关的协议。此外,被控制的设备必须能将观察到的事件发送给控制器,例如链路状态是连通或停止(up or down),或者设备已加入网络,或者设备已经启动并可以操作。这些事件向控制器及时提供了网络状态。OpenFlow便是这样的协议。
·状态管理层。最终的控制决策由SDN控制平面控制,配置所有交换机的流表,以实现端到端转发、负载平衡、防火墙等功能。这要求控制器具有最新的包括主机、链路、交换机和其它受SDN控制的设备的状态信息。一个交换机的流表包括计数器,网络控制应用程序可能用到这些计数器的值。控制器要为每台设备给出流表,因此控制器自身也可以包含这些流表的副本。前面提到的这些,都由SDN控制器维护。
·网络控制应用层接口。控制器通过此接口与网络控制应用程序交流。此API允许网络控制应用程序通过状态管理层读写网络状态和流表。应用程序可以注册,以便在状态改变事件发生时收到通知并做出相应。两个流行的SDN控制器通过REST请求-响应接口与应用程序通信。

我们说,SDN控制器是逻辑中心化(logically centralized)的。控制器以外的实体可以将控制器视作单一的设备或服务。实际上,为了确保容错性和可用性,以及保证性能,控制器及其数据库都部署在大量的服务器上。在一组服务器上实现控制器功能时,必须考虑控制器的内部操作(例如维护事件的逻辑时间顺序、一致性等)的语义。在许多分布式系统中,都需要考虑类似的问题。

OpenFlow协议运行在SDN控制器和SDN控制的交换机或其它实现OpenFlow API的设备之间,运行在TCP上,默认端口为6653。从控制器流动到受控交换机的重要报文有:
·配置。此报文允许控制器请求和修改一台交换机的设置。
·修改状态。此报文用于控制器对交换机的流表进行增删改,或设置交换机端口的属性。
·读取状态。此报文用于控制器从交换机的流表和端口中收集统计数据与计数器的值。
·发送分组。此报文用于控制器在控制的交换机从特定端口发送一个特殊的报文。该报文包含有效负载。
·流移除。此报文通知控制器,一个流表项已经被移除。原因可能是超时或收到了修改状态报文。
·端口状态。该报文用于交换机通知控制器,自身有端口的状态发生改变。
·分组进入。分组到达交换机端口但不匹配任何流表项时,将交由控制器进行额外处理。匹配的分组也可能被送给控制器,用于执行动作。

Google部署了一个遍布全球的广域网,用于互连其数据中心和服务器阵列(位于ISP和IXP中)。这个网络叫B4,基于Google设计的SDN控制层面和OpenFlow协议。Google的网络能让WAN链路在长途线路上以接近70%的利用率运行,超过典型的链路利用率的2到3倍,并基于应用程序优先级和流需求来分割应用流。
Google B4网络与SDN配合得很好:【1】Google控制了包括位于ISP和IXP的网络边缘服务器和网络核心路由器内的全部设备。【2】带宽需求最大的应用是大规模的数据拷贝。在网络拥塞时,它将让位给更高优先级的交互性应用程序。【3】由于仅连接了几十个数据中心,集中式控制是可行的。
B4网络使用定制的交换机,每台交换机运行OpenFlow的一个少量扩展版本;OpenFlow代理(OFA)类似于控制代理(控制代理位于路由器中,具有最简易的功能,负责和控制器通信,并执行控制器的命令;控制代理不能直接交互,也不能主动参与计算转发表)。每个OFA连接到网络控制服务器(NCS)中的OpenFlow控制器(OFC),使用单独的“带外”(out-of-band)网络,与在数据中心之间携带流量的网络不同。OFC提供由NCS用于与受控的交换机通信的服务,方法上类似于最底层。在B4中,OFC也执行状态管理功能,在网络信息库(NIB)中存储结点和链路的状态。Google实现的OFC基于ONIX SDN控制器。两个路由协议:BGP和IS-IS(OSPF的类似物)分别用于数据中心间和数据中心内的路由。Paxos用于执行NCS部件的热复制,防止故障。
流量工程网络控制应用程序逻辑上位于网络控制服务器之上,与这些服务器交互,为应用流提供全局、网络范围的带宽。借助B4,SDN在全球网络提供商的网络运营中取得了重要的飞跃。

许多研究致力于开发未来的SDN架构和能力。通过简单的交换机硬件和复杂的软件控制层面,SDN革命正颠覆性地替代专用的单个交换机和路由器(同时具有数据和控制层面)。一种通用的SDN称为网络功能虚拟化(network functions virtualization,NFC)的目标是:使用简单的商用服务器、交换机和存储硬件来大量替代复杂的中间件(比如具有专用硬件和专有软件的用于媒体缓存/服务的中间件)。另一个研究领域旨在将SDN的概念从AS内设置扩展到AS间设置。
5.6 ICMP
Internet控制报文协议(Internet Control Message Protocol,ICMP)为主机和路由器使用,用于交换网络层信息。ICMP的典型用途是允许主机或路由器产生错误报告。例如,在HTTP会话中,给出错误信息“目标主机不可达”的是ICMP,提示IP路由器无法找到完成HTTP请求指定的主机的路径。这时,路由器创建并发送ICMP报文至源主机。

ICMP弥补了IP的两项不足:
·IP本身并没有一种内在的机制获取差错信息并进行相应的控制。
·IP没有针对主机的查询和管理机制。
ICMP常被视为IP的一部分。但从架构上说,它位于IP之上,因为ICMP报文被放入IP数据报内发送。当主机收到上层协议为ICMP的IP数据报时(协议号为1),将内容提取出来,类似于处理数据报中的TCP和UDP段时那样。

ICMP报文的报头都是8字节,前4字节是固定的:1字节的类型(type)、1字节的代码(code)和2字节的校验和。该校验和也是Internet校验和。剩余4字节则取决于ICMP报文的类型。
ICMP的数据部分还包含引起该ICMP报文首次生成的IP数据报的报头和前8字节,以便发送方能确定引发该差错的数据报。前8字节包含运输层端口号(对TCP和UDP)和报文序号(对TCP),这些信息对发送主机通知高层协议有用。

部分ICMP报文类型如下表。注意:ICMP报文并不仅仅用于报告错误。

类型5:重定向(redirect)。路由器把改变路由报文发送给主机,让主机知道下次应将数据报发送给另外的路由器(可通过更好的路由)。主机与路由器之间交换路由信息由ICMP重定向报文来实现。
类型13或14:时间戳(timestamp)请求或响应。用于向路由器或主机获取当前的日期时间。时间戳请求与回答可用于时钟同步和时间测量。
一种ICMP报文——源抑制(source quench)报文,实际上很少使用。其最初目的是用于拥塞控制,允许一台拥塞的路由器发送ICMP源抑制报文给指定主机,强制其降低传输速率。TCP拥有自己的拥塞控制机制,无需网络层提供此类信息。其它已不再使用的ICMP报文有:信息请求与回答报文、地址掩码请求与回答报文和路由器请求与通告报文。
下面对改变路由报文(类型5)进行简短解释。互联网的主机中也有一张路由表。当主机要发送数据报时,首先查找本机的路由表,看应当从哪一个接口把数据报发送出去。在互联网中主机的数量远大于路由器的数量,出于效率的考虑,这些主机不和连接在网络上的路由器定期交换路由信息。在主机刚开始工作时,一般都在路由表中设置一台默认路由器(默认网关)的IP地址。不管数据报要发送到哪个目的地址,都一律先把数据报传送给这台默认路由器,而这台默认路由器知道到每一个目的网络的最佳路由(通过和其它路由器交换路由信息)。如果默认路由器发现主机发往某个目的地址的数据报的最佳路由应当经过网络上的另一个路由器R时,就用改变路由报文把这个情况告诉主机。于是,该主机就在其路由表中增加一个项目:到某某目的地址应经过路由器R(而不是默认路由器)。

下面是不应发送ICMP差错报告报文的几种情况。
·对ICMP差错报告报文,不再发送ICMP差错报告报文。
·对第一个分片的数据报片的所有后续数据报片,都不发送ICMP差错报告报文。
·对具有多播地址的数据报,都不发送ICMP差错报告报文。
·对具有特殊地址(如127.0.0.0或0.0.0.0)的数据报,不发送ICMP差错报告报文。

ping(Packet Internet Groper)发送ICMP类型8代码0报文到目标主机。目标主机收到回送请求(echo request)后,返回一个类型0代码0的ICMP回送回复。许多TCP/IP实现支持在操作系统内架设ping服务器,即服务器不是一个进程。而ping客户端程序需要能够指示操作系统产生一个类型8编码0的ICMP报文。
有的主机为了防止恶意攻击,一律不理睬外界发送过来的回送请求 ICMP报文。

第一章介绍过traceroute程序(Windows平台下为tracert),它允许追踪当前主机到世界上任何其它主机之间的路由。traceroute通过ICMP报文实现。为了确定源主机与目标主机之间的路由器名称和地址,源主机中的traceroute发送一系列IP数据报到目的地,每份数据报包含一个UDP段,其UDP端口号不可达。第n份数据报的TTL为n。同时,源为每份数据报计时。第n份数据报到达第n台路由器时,其TTL过期,路由器丢弃数据报并发送ICMP警告报文给源主机(类型11代码0)。警告报文包含路由器名称和IP地址。ICMP报文到达源主机后,源从计时器读出值作为往返时间。
当有数据报到达目标主机时,由于UDP端口不可达,目标主机会发送一条端口不可达ICMP报文(类型3代码3)给源主机。源主机收到此报文后,就停止发送。不过,标准的traceroute程序仅发送3个包,而不是持续发送直到收到目标主机发送的ICMP报文为止。
于是,源主机得知了到目标主机之前的路由器数量和全部路由器的标识,以及两台主机之间的往返时间。traceroute客户端程序必须能令操作系统产生具有特定TTL值的UDP数据报;当返回了ICMP报文时,操作系统也需要进行通知。

RFC 4443为IPv6定义了ICMP的新版本ICMPv6。除了重新组织现有的ICMP类型和代码的定义外,ICMPv6还添加了IPv6功能所需的新类型和编码,包括“分组太大”类型和“未被承认的IPv6选项”错误代码。ARP(6.4节)和IGMP的功能都被合并到了ICMPv6中。
ICMPv6是面向报文的协议,它利用报文来报告差错,获取信息,探测邻站或管理多播通信。ICMPv6还增加了几个定义报文功能及含义的其它协议。在对ICMPv6报文进行归类时,不同的文献和RFC文档使用了不同的策略,有的把其中的一些报文定义为ICMPv6报文,而把另一些报文定义为邻站发现ND(Neighbor-Discovery)报文(管理链路上的节点到节点的通信)或多播听众交付MLD(Multicast Listener Delivery)报文。其实所有这些报文都应当是ICMPv6报文,只是功能和作用不同而已。因此我们把这些报文都列入ICMPv6的不同类别。使用这种分类方法的原因是所有这些报文都具有相同的格式,并且所有报文类型都由ICMPv6处理。其实,像ND和MLD这样的协议都是运行在ICMPv6之下的。基于这样的考虑,可把ICMPv6报文分类如下图。请注意,邻站发现报文和组成员关系报文分别是在ND协议和MLD协议的控制下进行发送和接收的。

ICMPv6的报头格式没有变动,依然是1字节的类型(type)、1字节的代码(code)和2字节的校验和。该校验和也是Internet校验和。剩余4字节则取决于ICMP报文的类型。
在错误报文中,最高位(最左)为0。对于信息报文,最高位为1。
错误 类型字段值
目标不可达 1
数据包过长 2
超时 3
参数错误 4
对于目标不可达错误报文,代码值的意义如下:

对于超时错误(类型3),代码0和1分别代表超过跳数限制(由路由器报错)、目标主机重组数据报片超时(由目标主机报错)。
当IPv6报头或扩展报头出现错误,导致数据报无法进一步处理时,由路由器或主机发送类型4的错误报文。该类错误报文的代码意义如下:
错误描述 代码
遇到错误的报头字段 0
遇到无法识别的下一个报头类型 1
遇到无法识别的IPv6选项 2
类型4错误报文的报头的后4个字节是指针,指出了IPv6数据报中错误发生的位置。
ICMPv6支持限制错误报文的数量。例如,规定发送方至少每隔一定的时间才可以发送一份差错报文;也可以规定每隔接口发送差错报文的速率不超过链路速率的某个百分比。

ICMPv6的回送请求报文的类型字段为128,该报文请求目标节点立即发回一份回送响应报文。回送请求报文用于检验可达性,以及为路由问题的诊断和处理提供辅助。回送请求报文报头的后4个字节是标识符和序列号字段,各占2字节,用于将回送应答报文与回送请求报文进行匹配。
ICMPv6的回送响应报文的类型字段为129。回送响应报文报头的后4个字节也是标识符和序列号字段,各占2字节。
5.7 网络管理和SNMP
虽然网络管理还没有精确定义,但它的内容可归纳为:网络管理包括对硬件、软件和人力的使用、综合与协调,以便对网络资源进行监视、测试、配置、分析、评价和控制,这样就能以合理的价格满足网络的一些需求,如实时运行性能、服务质量等。网络管理也简称为网管。
可见,网络管理并不是指对网络进行行政上的管理。网络管理主要包括:
·故障管理:故障检测、隔离和纠正。
·配置管理:初始化网络、并配置网络。
·计费管理:记录网络资源的使用。
·性能管理:估价系统资源的运行状况及通信效率等。
·网络安全管理:对授权机制、访问控制、加密和加密关键字的管理。
网络是一个非常复杂的分布式系统:网络上有很多不同厂家生产的、运行着多种协议的结点(主要是路由器),这些结点还相互通信、交换信息。网络的状态总是不断地变化着。我们应当使用一种机制,来比较统一地读取这些结点上的状态信息,有时还要把一些新的状态信息写入到这些结点上。

网络管理的关键部件包括:
·管理服务器(managing server)运行在网络运行中心(network operation center,NOC)的中心化网络管理站上,通常也有人的参与。管理服务器是执行网络管理活动的地方,控制网络管理信息的收集、处理、分析和显示。
·被管理设备(managed device)连同它的软件,位于被管理的网络中。被管设备可以是主机、路由器、交换机、中间件、MODEM、温度计等联网设备。一台被管理设备可以包含若干个被管理对象(managed objects)。这些对象才是被管理设备的硬件的实际部分(例如,一张网卡只是一台主机或路由器的一个部件)和用于这些硬件及软件组件的配置参数(例如,像OSPF这样的AS内部路由选择协议)。在被管设备中也会有一些不能被管理的对象。
·被管设备中的每个被管对象的信息收集在管理信息库(Management Information Base,MIB)中。信息的值为管理服务器所用,通常也可以由管理服务器设置。MIB对象可以是计数器(比如统计被丢弃的IP数据报或主机收到的UDP段),运行在DNS服务器上的软件版本之类的描述信息,某个设备是否正常的状态信息,或到某个目的地的路由等特定协议的信息。管理信息结构(structure of management information,SMI)数据描述语言指定MIB对象的名称和类型。形式化定义语言用于保证网络管理数据的语法和语义是良定义、无歧义的。相关的MIB对象被一起放在同一个MIB模块中。
·被管理设备中还有网络管理代理(network management agent),是一个在被管设备中运行的进程,用于与管理服务器通信,并在管理服务器的控制下本地执行操作。
·网络管理协议。网管协议运行在管理服务器和被管理设备之间,允许管理服务器查询被管理设备的状态,并通过网络管理代理间接控制被管理设备。代理使用网管协议向管理服务器通知异常事件(例如部件失败、触发性能阈值)。网管协议自己并不管理网络。相反,它提供网络管理员管理(监视、测试、轮询、配置、分析、评估和控制)网络的能力。这个区别要注意一下。

简单网络管理协议(simple network management protocol,SNMP)的最新版本为SNMPv3,是应用层协议,用于在管理服务器及代理之间传送网络管理控制和信息报文。SNMP中的管理程序和代理程序按客户-服务器方式工作。管理站是客户机,运行SNMP客户程序(管理程序);被管设备是服务器,运行SNMP服务器程序(代理程序)。
SNMP最常用的用途是:SNMP管理服务器向SNMP代理发送请求,代理执行动作并响应。请求常用于查询或修改被管理设备的MIB对象的值。SNMP的另一常用用途是:向管理服务器不请自来地发送消息(陷阱报文)的代理。陷阱报文用于通知服务器:异常情况(例如链路启用或停用)导致了MIB对象值的改变。

网络管理的基本原理是:若要管理某个对象,就必然会给该对象添加一些软件或硬件,但这种“添加”对原有对象的影响必须尽量小些。SNMP正是按照这条基本原理设计的,其最重要的指导思想就是:要尽可能简单。不过,现在SNMP协议已相当庞大,一点也不“简单”,整个标准共有八个RFC文档[RFC3411 ~ 3418]。这里只给出一些最基本的概念。

在网络正常工作时,SNMP可实现统计、配置、测试等功能。当网络故障时,可实现各种差错检测和恢复功能。
SNMP 是在TCP/IP基础上的网络管理协议,但也可扩展到其它类型的网络设备上。

管理信息结构SMI是SNMP的重要组成部分。SMI的功能应当有三个,即规定:
(1) 被管对象应怎样命名;(2) 用来存储被管对象的数据类型有哪些;(3) 在网络上传送的管理数据应如何编码。

SMI规定,所有的被管对象都必须处在对象命名树(object naming tree)上。对象命名树的根没有名字,它的下面有三个顶级对象,都是世界上著名的标准制定单位:ITU-T(过去叫做CCITT)、ISO,以及这两个组织的联合体,它们的标号分别是0到2。对象名习惯上用英文小写表示。在ISO的下面的一个标号为3的节点是ISO认同的组织成员org。在其下面有一个美国国防部(DoD)的子树(标号6),再下面就是internet(标号1)。在只讨论internet中的对象时,可只画出internet以下的子树,并在internet节点旁边写上对象标识符1.3.6.1即可。
在internet节点下面的标号为2的节点是mgmt(管理)。再下面只有一个节点,即管理信息库mib-2,其对象标识符为1.3.6.1.2.1。在mib-2下面包含了所有被SNMP管理的对象。

SMI使用抽象语法记法1(ISO制定的ASN.1)定义数据类型,但又增加了一些新的定义。因此SMI既是ASN.1的子集又是ASN.1的超集。ASN.1的记法很严格,使得数据的含义不存在任何可能的二义性。例如,使用ASN.1时不能简单地说“一个具有整数值的变量”,而必须说明该变量的准确格式和整数取值的范围。当网络中的计算机对数据项并不都使用相同的表示时,采用这种精确的记法就尤其重要。注意:抽象语法只描述数据的结构形式且与具体的编码格式无关,同时也不涉及这些数据结构在计算机内如何存放。
任何数据都具有两种重要的属性,即值(value)与类型(type)。“值”是某个值集合中的一个元素,而“类型”则是值集合的名字。如果给定一种类型,则这种类型的一个值就是该类型的一个具体实例。
SMI把数据类型分为两大类:简单类型和结构化类型。简单类型是最基本的、直接使用ASN.1定义的类型。下表给出了最主要的几种简单类型。

SMI定义了两种结构化类型。sequence类似C语言中的struct或record,是简单数据类型的组合(不一定要相同的类型)。而sequence of类似于C语言中的array,它是同一简单类型的组合,或同样类型的sequence的组合。

SMI使用ASN.1制定的基本编码规则BER(Basic Encoding Rule)进行数据的编码。BER指明了每种数据的类型和值。在发送端用BER编码,可把用ASN.1所表述的报文转换成唯一的比特序列。在接收端用BER进行解码,就可得到该比特序列所表示的ASN.1报文。
ASN.1把所有的数据元素都表示为T-L-V(tag,length,value,标签、类型、值)三个字段组成的序列。

T字段包含3个子字段:
·类型(2位)共四种:通用类(00),即ASN.1定义的类型;应用类(01),即SMI定义的类型;上下文类(10),即上下文所定义的类型;专用类(11),保留为特定厂商定义的类型。
·格式(1位)共两种,指出数据类型的种类:简单数据类型(0)、结构化数据类型(1)。
·编号(5位)用来标志不同的数据类型。编号的范围一般为0 ~ 30。当编号大于30时,T字段就要扩展为多个字节(这种情况很少用到,可参考ITU-TX.209,这里从略)。
下面是一些数据类型的T字段编码:

L字段即长度。当L字段为单字节时,最高位为0,后面7位定义V字段的长度;当L字段为多字节时,最高位为1,后面7位定义后续字节的字节数(用二进制整数表示)。这时,所有的后续字节并置起来的二进制整数定义V字段的长度。

V字段又叫做值字段,用于定义数据元素的值。

若被管设备使用的不是SNMP而是另一种网络管理协议,SNMP就无法控制该网络元素。这时可使用委托代理(proxy agent)。委托代理能提供协议转换和过滤操作等功能,对被管对象进行管理。

管理程序使用MIB中这些信息的值对网络进行管理(如:读取或修改)。只有在MIB中的对象才是SNMP能够管理的。例如,路由器应当维持各网络接口的状态、入分组和出分组的流量、丢弃的分组和有差错的报文的统计信息,而调制解调器则应当维持发送和接收的字符数、码元传输速率和接受的呼叫等统计信息。因此MIB中必须存在上面这样一些信息。
节点mib-2包含的信息类别举例:

再举一例,比如说要读写ip节点下的ipInReceives MIB变量(收到的IP数据包数量),则当需要调用此变量时,变量名应为:iso.org.dod.internet.mgmt.mib.ip.ipInReceives。它在命名树上的位置是:1.3.6.1.2.1.4.3。
MIB对象命名树的大小并没有限制。下面给出若干MIB变量的例子,以便更好地理解MIB:

上面列举的大多数项目的值可用一个整数来表示。但MIB也定义了更复杂的结构。例如,MIB变量ipRoutingTable则定义一张完整的路由表。还有其它一些MIB变量定义了路由表项目的内容,并允许网络管理协议访问路由器中的单个项目,包括前缀、地址掩码以及下一跳地址等。当然,MIB变量只给出了每个数据项的逻辑定义,而路由器内部使用的数据结构可能与MIB的定义不同。当查询到达路由器时,路由器的代理软件负责MIB变量和路由器用于存储的数据结构之间的映射。

实际上,SNMP的操作只有两种基本的管理功能,即:
(1)“读”操作,用Get报文来检测各被管对象的状况;
(2)“写”操作,用Set报文来改变各被管对象的状况。
这些功能通过探询(inquiry)实现,即SNMP管理进程向被管理设备周期性发送探询信息。上述时间间隔可通过SNMP的管理信息库MIB来建立。探询的好处是:第一,可使系统相对简单;第二,能限制通过网络所产生的管理信息的通信量。但探询管理协议不够灵活,而且管理的设备数目不能太多。探询系统的开销也较大。如果探询频繁而并未得到有用的报告,那么通信线路和计算机的CPU周期就被浪费了。
SNMP不是完全的探询协议,它允许不经过询问就能发送某些信息。这种信息称为陷阱(trap),表示它能够捕捉“事件”。但这种陷阱信息的参数是受限制的。
当被管对象的代理检测到事件发生时,就检查其门限(阈值)。代理只向管理进程报告达到某些门限的事件(即过滤)。此方法的好处是:第一,仅在严重事件发生时才发送陷阱;第二,陷阱信息很简单且所需字节很少。使用探询(至少是周期性地)以维持对网络资源的实时监视,同时也采用陷阱机制报告特殊事件,使得SNMP成为一种有效的网络管理协议。

目前,SNMP共定义了8种PDU,编号分别为0到3、5到8,编号为4的PDU已经废弃:

SNMP报文和PDU的格式如下:

和大多数TCP/IP协议不一样,SNMP报文没有固定的字段。相反,它们使用标准ASN.1编码。因此SNMP报文用人工进行编码和理解时都比较困难。一个SNMP报文共由四个部分组成,即版本、报头、安全参数和SNMP报文的数据部分。版本现在已是版本3。报头包括报文标识(message identification)、最大报文长度、报文标志(message flag)。报文标志占1字节,其中的每一位定义安全类型或其他信息。安全参数用来产生报文摘要。
在SNMP PDU前面还有两个有关加密信息的字段,当数据需要加密时才使用。与网络管理直接相关的是PDU部分。编号为0到3的前四种PDU的格式都是相同的,都由PDU类型、请求ID、差错状态、差错索引及变量绑定几个字段组成。

·GetRequest、GetNextRequest和GetBulkRequest PDU都是从管理服务器发送到代理的,目的是请求代理所在的被管设备的MIB对象的值。值正被请求的MIB对象在PDU的变量绑定部分指定。三种PDU请求的粒度不同:GetRequest能请求任意多个MIB值;多个GetNextRequest能用于顺序读取一个MIB对象的列表;GetBulkRequest允许一次返回一大块数据,避免使用大量GetRequest和GetNextRequest带来的额外开销。代理返回一个响应PDU,包括对象标识符和关联的值。
·SetRequest PDU用于管理服务器设置位于被管设备内的MIB对象的值。代理同样返回一个包含“noError”状态的响应PDU,代表相应的值已经成功设定。
·InformRequest PDU用于管理服务器将MIB信息通知给另一个管理服务器。
·Response PDU一般由被管理设备发送至管理服务器,返回服务器请求的信息。
·SNMPv2 PDU是陷阱报文。陷阱报文是异步生成的,即它们并不作为接收到的请求的响应,而是在需要通知管理服务器存在异常时,单独生成。RFC 3418定义了常见的陷阱类型,包括冷启动和热启动、链路启动或停止、邻接结点丢失、身份验证失败等事件。接收到的陷阱请求不要求从管理服务器得到响应。

·请求标识符(request ID)。由管理进程设置的4字节整数。代理进程在发送响应报文时也要返回此请求标识符。管理进程可同时向许多代理发出请求读取变量值的报文,请求标识符使管理进程识别返回的响应对应哪一份请求报文。
·错误状态(error status)。在请求报文中,这个字段是零。当代理进程响应时,就填入0 ~ 8中的一个数字。例如0表示noError(一切正常),1表示tooBig(代理无法把回答装入到一份SNMP报文之中),2表示noSuchName(操作指明了一个不存在的变量),3表示badValue(无效值或无效语法),等等(RFC 3416)。
·错误索引(error index)。在请求报文中,这个字段是零。当代理进程响应时,若出现noSuchName,badValue或readonly的差错,代理进程就设置一个整数,指明有差错的变量在变量列表中的偏移。
·变量绑定(variable-bindings)。指明一个或多个变量的名和值。在请求报文中,变量的值应忽略(类型是NULL)。

尽管SNMP PDU能通过不同的运输协议传输,但多用UDP,因此传送SNMP报文的开销较小。RFC 3417指出:UDP是“被偏好的运输映射”(the preferred transport mapping)。然而,UDP是不可靠的,无法保证请求和响应顺利到达。SNMP在运行代理程序的服务器端用熟知端口161来接收Get或Set报文和发送响应报文(与熟知端口通信的客户端使用临时端口),但运行管理程序的客户端则使用熟知端口162来接收来自各代理的trap报文。
Request ID字段能被管理服务器用于检测请求或响应丢失。管理服务器决定在一段时间后仍未收到响应时是否需要重新传输请求。SNMP标准没有规定重传的具体过程,甚至没有决定重传是否需要优先完成,只要求管理服务器“需要根据重传的频率和周期做出负责任的动作”(needs to act responsibly in respect to the frequency and duration of retransmissions)。

“SNMPv3可以被认为是具有附加安全性和管理能力的SNMPv2”(RFC 3410)。SNMPv3当然比v2有别的改变,但都不如在管理和安全方面明显。使用SNMPv3时,只有被授权的人员才有资格执行网络管理的功能(如关闭某一条链路)和读取有关网络管理的信息(如读取一个配置文件的内容)。
SNMPv3中,安全性的地位是首要的,因为之前的SNMP缺乏足够的安全性,导致SNMP只是首选用于监视而不是控制。

猜你喜欢

转载自blog.csdn.net/COFACTOR/article/details/111740784