计算机网络——从二层到三层

从物理层到MAC层

第一层(物理层)

电脑连电脑要配置这两台电脑的IP地址、子网掩码和默认网关。要想两台电脑能够通信,这三项必须配置成为一个网络,可以一个是192.168.0.1/24,另一个是192.168.0.2/24,否则是不通的。

两台电脑之间的网络包,包含MAC层吗?

当然包含,要完整。IP层要封装了MAC层才能将包放入物理层。

到此为止,两台电脑已经构成了一个最小的局域网,也即LAN。可以玩联机局域网游戏啦!

三台电脑怎么把三台电脑连在一起呢?

有一个叫作Hub的东西,也就是集线器。这种设备有多个口,可以将多台电脑连接起来。集线器完全在物理层工作。它会将自己收到的每一个字节,都复制到其他端口上去。这是第一层物理层联通的方案。

第二层(数据链路层)

Hub采取的是广播的模式,如果每一台电脑发出的包,宿舍的每个电脑都能收到,那就麻烦了。这就需要解决几个问题:

  1. 这个包是发给谁的?谁应该接收?
  2. 大家都在发,会不会产生混乱?有没有谁先发、谁后发的规则?
  3. 如果发送的时候出现了错误,怎么办?

这几个问题,都是第二层,数据链路层,也即MAC层要解决的问题。MAC的全称是Medium Access Control,即媒体访问控制。控制什么呢?其实就是控制在往媒体上发数据的时候,谁先发、谁后发的问题。防止发生混乱。

这解决的是第二个问题。这个问题中的规则,学名叫多路访问。有很多算法可以解决这个问题。就像车管所管束马路上跑的车,能想的办法都想过了。

比如接下来这三种方式:

  • 方式一:分多个车道。每个车一个车道,你走你的,我走我的。这在计算机网络里叫作信道划分;
  • 方式二:今天单号出行,明天双号出行,轮着来。这在计算机网络里叫作轮流协议;
  • 方式三:不管三七二十一,有事儿先出门,发现特堵,就回去。错过高峰再出。我们叫作随机接入协议。著名的以太网,用的就是这个方式。

解决了第二个问题,就是解决了媒体接入控制的问题,MAC的问题也就解决好了。这和MAC地址没什么关系。

接下来要解决第一个问题:发给谁,谁接收?这里用到一个物理地址,叫作链路层地址。但是因为第二层主要解决媒体接入控制的问题,所以它常被称为MAC地址

解决第一个问题就牵扯到第二层的网络包格式。对于以太网,第二层的最开始,就是目标的MAC地址和源的MAC地址。

img

接下来是类型,大部分的类型是IP数据包,然后IP里面包含TCP、UDP,以及HTTP等,这都是里层封装的事情。

有了这个目标MAC地址,数据包在链路上广播,MAC的网卡才能发现,这个包是给它的。MAC的网卡把包收进来,然后打开IP包,发现IP地址也是自己的,再打开TCP包,发现端口是自己,也就是80,而nginx就是监听80。

于是将请求提交给nginx,nginx返回一个网页。然后将网页需要发回请求的机器。然后层层封装,最后到MAC层。因为来的时候有源MAC地址,返回的时候,源MAC就变成了目标MAC,再返给请求的机器。

对于以太网,第二层的最后面是CRC,也就是循环冗余检测。通过XOR异或的算法,来计算整个包是否在发送的过程中出现了错误,主要解决第三个问题。

这里还有一个没有解决的问题,当源机器知道目标机器的时候,可以将目标地址放入包里面,如果不知道呢?一个广播的网络里面接入了N台机器,我怎么知道每个MAC地址是谁呢?这就是ARP协议,也就是已知IP地址,求MAC地址的协议。

img

在一个局域网里面,当知道了IP地址,不知道MAC怎么办呢?靠“吼”。

img

广而告之,发送一个广播包,谁是这个IP谁来回答。具体询问和回答的报文就像下面这样:

img

为了避免每次都用ARP请求,机器本地也会进行ARP缓存。当然机器会不断地上线下线,IP也可能会变,所以ARP的MAC地址缓存过一段时间就会过期。

局域网

组网的方法,对少数电脑来说没有问题,但是一旦机器数目增多,问题就出现了。因为Hub是广播的,不管某个接口是否需要,所有的Bit都会被发送出去,然后让主机来判断是不是需要。这种方式路上的车少就没问题,车一多,产生冲突的概率就提高了。而且把不需要的包转发过去,纯属浪费。看来Hub这种不管三七二十一都转发的设备是不行了,需要点儿智能的。因为每个口都只连接一台电脑,这台电脑又不怎么换IP和MAC地址,只要记住这台电脑的MAC地址,如果目标MAC地址不是这台电脑的,这个口就不用转发了。

谁能知道目标MAC地址是否就是连接某个口的电脑的MAC地址呢?

这就需要一个能把MAC头拿下来,检查一下目标MAC地址,然后根据策略转发的设备,这个设备显然是个二层设备,我们称为交换机

交换机怎么知道每个口的电脑的MAC地址呢?这需要交换机会学习。

一台MAC1电脑将一个包发送给另一台MAC2电脑,当这个包到达交换机的时候,一开始交换机也不知道MAC2的电脑在哪个口,所以没办法,它只能将包转发给除了来的那个口之外的其他所有的口。但是,这个时候,交换机会干一件非常聪明的事情,就是交换机会记住,MAC1是来自一个明确的口。以后有包的目的地址是MAC1的,直接发送到这个口就可以了。

当交换机作为一个关卡一样,过了一段时间之后,就有了整个网络的一个结构了,这个时候,基本上不用广播了,全部可以准确转发。当然,每个机器的IP地址会变,所在的口也会变,因而交换机上的学习的结果,我们称为转发表,是有一个过期时间的。

有了交换机,一般来说,你接个几十台、上百台电脑应该没啥问题。

总结

  • MAC层是用来解决多路访问的堵车问题的;

  • ARP是通过吼的方式来寻找目标MAC地址的,吼完之后记住一段时间,这个叫作缓存;

  • 交换机是有MAC地址学习能力的,学完了它就知道谁在哪儿了,不用广播了。

交换机与VLAN

拓扑结构是怎么形成的?

我们常见到的办公室大多是一排排的桌子,每个桌子都有网口,一排十几个座位就有十几个网口,一个楼层就会有几十个甚至上百个网口。如果算上所有楼层,这个场景自然比你宿舍里的复杂多了。具体哪里复杂呢?

首先,这个时候,一个交换机肯定不够用,需要多台交换机,交换机之间连接起来,就形成一个稍微复杂的拓扑结构

我们先来看两台交换机的情形。两台交换机连接着三个局域网,每个局域网上都有多台机器。如果机器1只知道机器4的IP地址,当它想要访问机器4,把包发出去的时候,它必须要知道机器4的MAC地址。

img

于是机器1发起广播,机器2收到这个广播,但是这不是找它的,所以没它什么事。

交换机A一开始是不知道任何拓扑信息的,在它收到这个广播后,采取的策略是,除了广播包来的方向外,它还要转发给其他所有的网口。

于是机器3也收到广播信息了,但是这和它也没什么关系。

当然,交换机B也是能够收到广播信息的,但是这时候它也是不知道任何拓扑信息的,因而也是进行广播的策略,将包转发到局域网三。

这个时候,机器4和机器5都收到了广播信息。

机器4主动响应说,这是找我的,这是我的MAC地址。

于是一个ARP请求就成功完成了。

在上面的过程中,交换机A和交换机B都是能够学习到这样的信息:

机器1是在左边这个网口的。当了解到这些拓扑信息之后,情况就好转起来。

当机器2要访问机器1的时候,机器2并不知道机器1的MAC地址,所以机器2会发起一个ARP请求。这个广播消息会到达机器1,也同时会到达交换机A。

这个时候交换机A已经知道机器1是不可能在右边的网口的,所以这个广播信息就不会广播到局域网二和局域网三。

当机器3要访问机器1的时候,也需要发起一个广播的ARP请求。

这个时候交换机A和交换机B都能够收到这个广播请求。

交换机A当然知道主机A是在左边这个网口的,所以会把广播消息转发到局域网一。

同时,交换机B收到这个广播消息之后,由于它知道机器1是不在右边这个网口的,所以不会将消息广播到局域网三。

如何解决常见的环路问题?

这样看起来,两台交换机工作得非常好。随着办公室越来越大,交换机数目肯定越来越多。当整个拓扑结构复杂了,这么多网线,绕过来绕过去,不可避免地会出现一些意料不到的情况。其中常见的问题就是环路问题

例如这个图,当两个交换机将两个局域网同时连接起来的时候。你可能会觉得,这样反而有了高可用性。但是却不幸地出现了环路。出现了环路会有什么结果呢?

img

我们来想象一下机器1访问机器2的过程。一开始,机器1并不知道机器2的MAC地址,所以它需要发起一个ARP的广播。广播到达机器2,机器2会把MAC地址返回来,看起来没有这两个交换机什么事情。

但是问题来了,这两个交换机还是都能够收到广播包的。

交换机A一开始是不知道机器2在哪个局域网的,所以它会把广播消息放到局域网二,在局域网二广播的时候,交换机B右边这个网口也是能够收到广播消息的。

交换机B会将这个广播息信息发送到局域网一。局域网一的这个广播消息,又会到达交换机A左边的这个接口。

交换机A这个时候还是不知道机器2在哪个局域网,于是将广播包又转发到局域网二。左转左转左转,好像是个圈哦。

可能有人会说,当两台交换机都能够逐渐学习到拓扑结构之后,是不是就可以了?

别想了,压根儿学不会的。机器1的广播包到达交换机A和交换机B的时候,本来两个交换机都学会了机器1是在局域网一的,但是当交换机A将包广播到局域网二之后,交换机B右边的网口收到了来自交换机A的广播包。

根据学习机制,这彻底损坏了交换机B的三观,刚才机器1还在左边的网口呢,怎么又出现在右边的网口呢?哦,那肯定是机器1换位置了,于是就误会了,交换机B就学会了,机器1是从右边这个网口来的,把刚才学习的那一条清理掉。

同理,交换机A右边的网口,也能收到交换机B转发过来的广播包,同样也误会了,于是也学会了,机器1从右边的网口来,不是从左边的网口来。

然而当广播包从左边的局域网一广播的时候,两个交换机再次刷新三观,原来机器1是在左边的,过一会儿,又发现不对,是在右边的,过一会,又发现不对,是在左边的。

这还是一个包转来转去,每台机器都会发广播包,交换机转发也会复制广播包,当广播包越来越多的时候,按照之前讲过一个共享道路的算法,也就是路会越来越堵,最后谁也别想走。所以,必须有一个方法解决环路的问题,怎么破除环路呢?

STP协议中那些难以理解的概念

在数据结构中,有一个方法叫作最小生成树。有环的我们常称为。将图中的环破了,就生成了。在计算机网络中,生成树的算法叫作STP,全称Spanning Tree Protocol

STP协议比较复杂,一开始很难看懂,但是其实这是一场血雨腥风的武林比武或者华山论剑,最终决出五岳盟主的方式。

img

在STP协议里面有很多概念,译名就非常拗口,但是我一作比喻,你很容易就明白了。

  • Root Bridge,也就是根交换机。这个比较容易理解,可以比喻为“掌门”交换机,是某棵树的老大,是掌门,最大的大哥。

  • Designated Bridges,有的翻译为指定交换机。这个比较难理解,可以想像成一个“小弟”,对于树来说,就是一棵树的树枝。所谓“指定”的意思是,我拜谁做大哥,其他交换机通过这个交换机到达根交换机,也就相当于拜他做了大哥。这里注意是树枝,不是叶子,因为叶子往往是主机。

  • Bridge Protocol Data Units (BPDU)网桥协议数据单元。可以比喻为“相互比较实力”的协议。行走江湖,比的就是武功,拼的就是实力。当两个交换机碰见的时候,也就是相连的时候,就需要互相比一比内力了。BPDU只有掌门能发,已经隶属于某个掌门的交换机只能传达掌门的指示。

  • Priority Vector优先级向量。可以比喻为实力 (值越小越牛)。实力是啥?就是一组ID数目,[Root Bridge ID, Root Path Cost, Bridge ID, and Port ID]。为什么这样设计呢?这是因为要看怎么来比实力。

    先看Root Bridge ID。

    拿出老大的ID看看,发现掌门一样,那就是师兄弟;

    再比Root Path Cost,也即我距离我的老大的距离,也就是拿和掌门关系比,看同一个门派内谁和老大关系铁;

    最后比Bridge ID,比我自己的ID,拿自己的本事比。

STP的工作过程是怎样的?

接下来,我们来看STP的工作过程。

一开始,江湖纷争,异常混乱。大家都觉得自己是掌门,谁也不服谁。于是,所有的交换机都认为自己是掌门,每个网桥都被分配了一个ID。这个ID里有管理员分配的优先级,当然网络管理员知道哪些交换机贵,哪些交换机好,就会给它们分配高的优先级。这种交换机生下来武功就很高,起步就是乔峰。

img

既然都是掌门,互相都连着网线,就互相发送BPDU来比功夫呗。这一比就发现,有人是岳不群,有人是封不平,赢的接着当掌门,输的就只好做小弟了。当掌门的还会继续发BPDU,而输的人就没有机会了。它们只有在收到掌门发的BPDU的时候,转发一下,表示服从命令。

img

数字表示优先级。就像这个图,5和6碰见了,6的优先级低,所以乖乖做小弟。于是一个小门派形成,5是掌门,6是小弟。其他诸如1-7、2-8、3-4这样的小门派,也诞生了。于是江湖出现了很多小的门派,小的门派,接着合并。

合并的过程会出现以下四种情形,分别来介绍。

情形一:掌门遇到掌门

当5碰到了1,掌门碰见掌门,1觉得自己是掌门,5也刚刚跟别人PK完成为掌门。这俩掌门比较功夫,最终1胜出。于是输掉的掌门5就会率领所有的小弟归顺。结果就是1成为大掌门。

img

情形二:同门相遇

同门相遇可以是掌门与自己的小弟相遇,这说明存在“环”了。这个小弟已经通过其他门路拜在你门下,结果你还不认识,就PK了一把。结果掌门发现这个小弟功夫不错,不应该级别这么低,就把它招到门下亲自带,那这个小弟就相当于升职了。

我们再来看,假如1和6相遇。6原来就拜在1的门下,只不过6的上司是5,5的上司是1。1发现,6距离我才只有2,比从5这里过来的5(=4+1)近多了,那6就直接汇报给我吧。于是,5和6分别汇报给1。

img

同门相遇还可以是小弟相遇。这个时候就要比较谁和掌门的关系近,当然近的当大哥。刚才5和6同时汇报给1了,后来5和6再比较功夫的时候发现,5你直接汇报给1距离是4,如果5汇报给6再汇报给1,距离只有2+1=3,所以5干脆拜6为上司。

情形三:掌门与其他帮派小弟相遇

小弟拿本帮掌门和这个掌门比较,赢了,这个掌门拜入门来。输了,会拜入新掌门,并且逐渐拉拢和自己连接的兄弟,一起弃暗投明。

img

例如,2和7相遇,虽然7是小弟,2是掌门。就个人武功而言,2比7强,但是7的掌门是1,比2牛,所以没办法,2要拜入7的门派,并且连同自己的小弟都一起拜入。

情形四:不同门小弟相遇

各自拿掌门比较,输了的拜入赢的门派,并且逐渐将与自己连接的兄弟弃暗投明。

img

例如,5和4相遇。虽然4的武功好于5,但是5的掌门是1,比4牛,于是4拜入5的门派。后来当3和4相遇的时候,3发现4已经叛变了,4说我现在老大是1,比你牛,要不你也来吧,于是3也拜入1。

最终,生成一棵树,武林一统,天下太平。但是天下大势,分久必合,合久必分,天下统一久了,也会有相应的问题。

如何解决广播问题和安全问题?

毕竟机器多了,交换机也多了,就算交换机比Hub智能一些,但是还是难免有广播的问题,一大波机器,相关的部门、不相关的部门,广播一大堆,性能就下来了。就像一家公司,创业的时候,一二十个人,坐在一个会议室,有事情大家讨论一下,非常方便。但是如果变成了50个人,全在一个会议室里面吵吵,就会乱的不得了。

你们公司有不同的部门,有的部门需要保密的,比如人事部门,肯定要讨论升职加薪的事儿。由于在同一个广播域里面,很多包都会在一个局域网里面飘啊飘,碰到了一个会抓包的程序员,就能抓到这些包,如果没有加密,就能看到这些敏感信息了。还是上面的例子,50个人在一个会议室里面七嘴八舌的讨论,其中有两个HR,那他们讨论的问题,肯定被其他人偷偷听走了。

那咋办,分部门,分会议室呗。那我们就来看看怎么分。

有两种分的方法,一个是物理隔离。每个部门设一个单独的会议室,对应到网络方面,就是每个部门有单独的交换机,配置单独的子网,这样部门之间的沟通就需要路由器了。这样的问题在于,有的部门人多,有的部门人少。人少的部门慢慢人会变多,人多的部门也可能人越变越少。如果每个部门有单独的交换机,口多了浪费,少了又不够用。

另外一种方式是虚拟隔离,就是用我们常说的VLAN,或者叫虚拟局域网。使用VLAN,一个交换机上会连属于多个局域网的机器,那交换机怎么区分哪个机器属于哪个局域网呢?

img

我们只需要在原来的二层的头上加一个TAG,里面有一个VLAN ID,一共12位。为什么是12位呢?因为12位可以划分4096个VLAN。这样是不是还不够啊。现在的情况证明,目前云计算厂商里面绝对不止4096个用户。

如果我们买的交换机是支持VLAN的,当这个交换机把二层的头取下来的时候,就能够识别这个VLAN ID。这样只有相同VLAN的包,才会互相转发,不同VLAN的包,是看不到的。这样广播问题和安全问题就都能够解决了。

img

我们可以设置交换机每个口所属的VLAN。如果某个口坐的是程序员,他们属于VLAN 10;如果某个口坐的是人事,他们属于VLAN 20;如果某个口坐的是财务,他们属于VLAN 30。这样,财务发的包,交换机只会转发到VLAN 30的口上。程序员啊,你就监听VLAN 10吧,里面除了代码,啥都没有。

而且对于交换机来讲,每个VLAN的口都是可以重新设置的。一个财务走了,把他所在的作为的口从VLAN 30移除掉,来了一个程序员,坐在财务的位置上,就把这个口设置为VLAN 10,十分灵活。

有人会问交换机之间怎么连接呢?将两个交换机连接起来的口应该设置成什么VLAN呢?对于支持VLAN的交换机,有一种口叫作Trunk口。它可以转发属于任何VLAN的口。交换机之间可以通过这种口相互连接。

总结

  • 当交换机的数目越来越多的时候,会遭遇环路问题,让网络包迷路,这就需要使用STP协议,通过华山论剑比武的方式,将有环路的图变成没有环路的树,从而解决环路问题。
  • 交换机数目多会面临隔离问题,可以通过VLAN形成虚拟局域网,从而解决广播问题和安全问题。

ICMP与ping

ICMP协议的格式

一般情况下,你会想到ping一下。那你知道ping是如何工作的吗?

ping是基于ICMP协议工作的。ICMP全称Internet Control Message Protocol,就是互联网控制报文协议。这里面的关键词是“控制”,那具体是怎么控制的呢?

网络包在异常复杂的网络环境中传输时,常常会遇到各种各样的问题。当遇到问题的时候,总不能“死个不明不白”,要传出消息来,报告情况,这样才可以调整传输策略。这就相当于我们经常看到的电视剧里,古代行军的时候,为将为帅者需要通过侦察兵、哨探或传令兵等人肉的方式来掌握情况,控制整个战局。

ICMP报文是封装在IP包里面的。因为传输指令的时候,肯定需要源地址和目标地址。它本身非常简单。因为作为侦查兵,要轻装上阵,不能携带大量的包袱。

img

ICMP报文有很多的类型,不同的类型有不同的代码。最常用的类型是主动请求为8,主动请求的应答为0

查询报文类型

我们经常在电视剧里听到这样的话:主帅说,来人哪!前方战事如何,快去派人打探,一有情况,立即通报!

这种是主帅发起的,主动查看敌情,对应ICMP的查询报文类型。例如,常用的ping就是查询报文,是一种主动请求,并且获得主动应答的ICMP协议。所以,ping发的包也是符合ICMP协议格式的,只不过它在后面增加了自己的格式。

对ping的主动请求,进行网络抓包,称为ICMP ECHO REQUEST。同理主动请求的回复,称为ICMP ECHO REPLY。比起原生的ICMP,这里面多了两个字段,一个是标识符。这个很好理解,你派出去两队侦查兵,一队是侦查战况的,一队是去查找水源的,要有个标识才能区分。另一个是序号,你派出去的侦查兵,都要编个号。如果派出去10个,回来10个,就说明前方战况不错;如果派出去10个,回来2个,说明情况可能不妙。

在选项数据中,ping还会存放发送请求的时间值,来计算往返时间,说明路程的长短。

差错报文类型

当然也有另外一种方式,就是差错报文。

主帅骑马走着走着,突然来了一匹快马,上面的小兵气喘吁吁的:报告主公,不好啦!张将军遭遇埋伏,全军覆没啦!这种是异常情况发起的,来报告发生了不好的事情,对应ICMP的差错报文类型

我举几个ICMP差错报文的例子:终点不可达为3,源抑制为4,超时为11,重定向为5。这些都是什么意思呢?我给你具体解释一下。

第一种是终点不可达。小兵:报告主公,您让把粮草送到张将军那里,结果没有送到。

如果你是主公,你肯定会问,为啥送不到?具体的原因在代码中表示就是,网络不可达代码为0,主机不可达代码为1,协议不可达代码为2,端口不可达代码为3,需要进行分片但设置了不分片位代码为4。

具体的场景就像这样:

  • 网络不可达:主公,找不到地方呀?
  • 主机不可达:主公,找到地方没这个人呀?
  • 协议不可达:主公,找到地方,找到人,口号没对上,人家天王盖地虎,我说12345!
  • 端口不可达:主公,找到地方,找到人,对了口号,事儿没对上,我去送粮草,人家说他们在等救兵。
  • 需要进行分片但设置了不分片位:主公,走到一半,山路狭窄,想换小车,但是您的将令,严禁换小车,就没办法送到了。

第二种是源站抑制,也就是让源站放慢发送速度。小兵:报告主公,您粮草送的太多了吃不完。

第三种是时间超时,也就是超过网络包的生存时间还是没到。小兵:报告主公,送粮草的人,自己把粮草吃完了,还没找到地方,已经饿死啦。

第四种是路由重定向,也就是让下次发给另一个路由器。小兵:报告主公,上次送粮草的人本来只要走一站地铁,非得从五环绕,下次别这样了啊。

差错报文的结构相对复杂一些。除了前面还是IP,ICMP的前8字节不变,后面则跟上出错的那个IP包的IP头和IP正文的前8个字节。

而且这类侦查兵特别恪尽职守,不但自己返回来报信,还把一部分遗物也带回来。

  • 侦察兵:报告主公,张将军已经战死沙场,这是张将军的印信和佩剑。
  • 主公:神马?张将军是怎么死的(可以查看ICMP的前8字节)?没错,这是张将军的剑,是他的剑(IP数据包的头及正文前8字节)。

ping:查询报文类型的使用

接下来,我们重点来看ping的发送和接收过程。

img

假定主机A的IP地址是192.168.1.1,主机B的IP地址是192.168.1.2,它们都在同一个子网。那当你在主机A上运行“ping 192.168.1.2”后,会发生什么呢?

ping命令执行的时候,源主机首先会构建一个ICMP请求数据包,ICMP数据包内包含多个字段。最重要的是两个,第一个是类型字段,对于请求数据包而言该字段为 8;另外一个是顺序号,主要用于区分连续ping的时候发出的多个数据包。每发出一个请求数据包,顺序号会自动加1。为了能够计算往返时间RTT,它会在报文的数据部分插入发送时间。

然后,由ICMP协议将这个数据包连同地址192.168.1.2一起交给IP层。IP层将以192.168.1.2作为目的地址,本机IP地址作为源地址,加上一些其他控制信息,构建一个IP数据包。

接下来,需要加入MAC头。如果在本节ARP映射表中查找出IP地址192.168.1.2所对应的MAC地址,则可以直接使用;如果没有,则需要发送ARP协议查询MAC地址,获得MAC地址后,由数据链路层构建一个数据帧,目的地址是IP层传过来的MAC地址,源地址则是本机的MAC地址;还要附加上一些控制信息,依据以太网的介质访问规则,将它们传送出去。

主机B收到这个数据帧后,先检查它的目的MAC地址,并和本机的MAC地址对比,如符合,则接收,否则就丢弃。接收后检查该数据帧,将IP数据包从帧中提取出来,交给本机的IP层。同样,IP层检查后,将有用的信息提取后交给ICMP协议。

主机B会构建一个 ICMP 应答包,应答数据包的类型字段为 0,顺序号为接收到的请求数据包中的顺序号,然后再发送出去给主机A。

在规定的时候间内,源主机如果没有接到 ICMP 的应答包,则说明目标主机不可达;如果接收到了 ICMP 应答包,则说明目标主机可达。此时,源主机会检查,用当前时刻减去该数据包最初从源主机上发出的时刻,就是 ICMP 数据包的时间延迟。

当然这只是最简单的,同一个局域网里面的情况。如果跨网段的话,还会涉及网关的转发、路由器的转发等等。但是对于ICMP的头来讲,是没什么影响的。会影响的是根据目标IP地址,选择路由的下一跳,还有每经过一个路由器到达一个新的局域网,需要换MAC头里面的MAC地址。

如果在自己的可控范围之内,当遇到网络不通的问题的时候,除了直接ping目标的IP地址之外,还应该有一个清晰的网络拓扑图。并且从理论上来讲,应该要清楚地知道一个网络包从源地址到目标地址都需要经过哪些设备,然后逐个ping中间的这些设备或者机器。如果可能的话,在这些关键点,通过tcpdump -i eth0 icmp,查看包有没有到达某个点,回复的包到达了哪个点,可以更加容易推断出错的位置。

经常会遇到一个问题,如果不在我们的控制范围内,很多中间设备都是禁止ping的,但是ping不通不代表网络不通。这个时候就要使用telnet,通过其他协议来测试网络是否通,这个就不在本篇的讲述范围了。

说了这么多,你应该可以看出ping这个程序是使用了ICMP里面的ECHO REQUEST和ECHO REPLY类型的。

Traceroute:差错报文类型的使用

那其他的类型呢?是不是只有真正遇到错误的时候,才能收到呢?那也不是,有一个程序Traceroute,是个“大骗子”。它会使用ICMP的规则,故意制造一些能够产生错误的场景。

所以,Traceroute的第一个作用就是故意设置特殊的TTL,来追踪去往目的地时沿途经过的路由器。Traceroute的参数指向某个目的IP地址,它会发送一个UDP的数据包。将TTL设置成1,也就是说一旦遇到一个路由器或者一个关卡,就表示它“牺牲”了。

如果中间的路由器不止一个,当然碰到第一个就“牺牲”。于是,返回一个ICMP包,也就是网络差错包,类型是时间超时。那大军前行就带一顿饭,试一试走多远会被饿死,然后找个哨探回来报告,那我就知道大军只带一顿饭能走多远了。

接下来,将TTL设置为2。第一关过了,第二关就“牺牲”了,那我就知道第二关有多远。如此反复,直到到达目的主机。这样,Traceroute就拿到了所有的路由器IP。当然,有的路由器压根不会回这个ICMP。这也是Traceroute一个公网的地址,看不到中间路由的原因。

怎么知道UDP有没有到达目的主机呢?Traceroute程序会发送一份UDP数据报给目的主机,但它会选择一个不可能的值作为UDP端口号(大于30000)。当该数据报到达时,将使目的主机的 UDP模块产生一份“端口不可达”错误ICMP报文。如果数据报没有到达,则可能是超时。

这就相当于故意派人去西天如来那里去请一本《道德经》,结果人家信佛不信道,消息就会被打出来。被打的消息传回来,你就知道西天是能够到达的。为什么不去取《心经》呢?因为UDP是无连接的。也就是说这人一派出去,你就得不到任何音信。你无法区别到底是半路走丢了,还是真的信佛遁入空门了,只有让人家打出来,你才会得到消息。

Traceroute还有一个作用是故意设置不分片,从而确定路径的MTU。要做的工作首先是发送分组,并设置“不分片”标志。发送的第一个分组的长度正好与出口MTU相等。如果中间遇到窄的关口会被卡住,会发送ICMP网络差错包,类型为“需要进行分片但设置了不分片位”。其实,这是人家故意的好吧,每次收到ICMP“不能分片”差错时就减小分组的长度,直到到达目标主机。

总结

  • ICMP相当于网络世界的侦察兵。我讲了两种类型的ICMP报文,一种是主动探查的查询报文,一种异常报告的差错报文;
  • ping使用查询报文,Traceroute使用差错报文。

网关

MAC头和IP头的细节

由于在跨网关访问的时候,牵扯到MAC地址和IP地址的变化,这里有必要详细描述一下MAC头和IP头的细节。

img

在MAC头里面,先是目标MAC地址,然后是源MAC地址,然后有一个协议类型,用来说明里面是IP协议。IP头里面的版本号,目前主流的还是IPv4,服务类型TOS在ip addr命令的时候讲过,TTL在ICMP协议的时候讲过。另外,还有8位标识协议。这里到了下一层的协议,也就是,是TCP还是UDP。最重要的就是源IP和目标IP。先是源IP地址,然后是目标IP地址。

在任何一台机器上,当要访问另一个IP地址的时候,都会先判断,这个目标IP地址,和当前机器的IP地址,是否在同一个网段。怎么判断同一个网段呢?需要CIDR和子网掩码,这个在第三节的时候也讲过了。

如果是同一个网段,例如,你访问你旁边的兄弟的电脑,那就没网关什么事情,直接将源地址和目标地址放入IP头中,然后通过ARP获得MAC地址,将源MAC和目的MAC放入MAC头中,发出去就可以了。

如果不是同一网段,例如,你要访问你们校园网里面的BBS,该怎么办?这就需要发往默认网关Gateway。Gateway的地址一定是和源IP地址是一个网段的。往往不是第一个,就是第二个。例如192.168.1.0/24这个网段,Gateway往往会是192.168.1.1/24或者192.168.1.2/24。

如何发往默认网关呢?网关不是和源IP地址是一个网段的么?

这个过程就和发往同一个网段的其他机器是一样的:将源地址和目标IP地址放入IP头中,通过ARP获得网关的MAC地址,将源MAC和网关的MAC放入MAC头中,发送出去。网关所在的端口,例如192.168.1.1/24将网络包收进来,然后接下来怎么做,就完全看网关的了。

网关往往是一个路由器,是一个三层转发的设备。啥叫三层设备?把MAC头和IP头都取下来,然后根据里面的内容,看看接下来把包往哪里转发的设备。

很多情况下,人们把网关就叫作路由器。其实不完全准确,而另一种比喻更加恰当:路由器是一台设备,它有五个网口或者网卡,相当于有五只手,分别连着五个局域网。每只手的IP地址都和局域网的IP地址相同的网段,每只手都是它握住的那个局域网的网关。

任何一个想发往其他局域网的包,都会到达其中一只手,被拿进来,拿下MAC头和IP头,看看,根据自己的路由算法,选择另一只手,加上IP头和MAC头,然后扔出去。

静态路由是什么?

这个时候,问题来了,该选择哪一只手?IP头和MAC头加什么内容,哪些变、哪些不变呢?这个问题比较复杂,大致可以分为两类,一个是静态路由,一个是动态路由

静态路由,其实就是在路由器上,配置一条一条规则。这些规则包括:想访问BBS站(它肯定有个网段),从2号口出去,下一跳是IP2;想访问教学视频站(它也有个自己的网段),从3号口出去,下一跳是IP3,然后保存在路由器里。

每当要选择从哪只手抛出去的时候,就一条一条的匹配规则,找到符合的规则,就按规则中设置的那样,从某个口抛出去,找下一跳IPX。

IP头和MAC头哪些变、哪些不变?

对于IP头和MAC头哪些变、哪些不变的问题,可以分两种类型。我把它们称为“欧洲十国游”型和“玄奘西行”型

之前我说过,MAC地址是一个局域网内才有效的地址。因而,MAC地址只要过网关,就必定会改变,因为已经换了局域网。两者主要的区别在于IP地址是否改变。不改变IP地址的网关,我们称为转发网关;改变IP地址的网关,我们称为NAT网关

“欧洲十国游”型

结合这个图,我们先来看“欧洲十国游”型。

img

服务器A要访问服务器B。首先,服务器A会思考,192.168.4.101和我不是一个网段的,因而需要先发给网关。那网关是谁呢?已经静态配置好了,网关是192.168.1.1。网关的MAC地址是多少呢?发送ARP获取网关的MAC地址,然后发送包。包的内容是这样的:

  • 源MAC:服务器A的MAC
  • 目标MAC:192.168.1.1这个网口的MAC
  • 源IP:192.168.1.101
  • 目标IP:192.168.4.101

包到达192.168.1.1这个网口,发现MAC一致,将包收进来,开始思考往哪里转发。

在路由器A中配置了静态路由之后,要想访问192.168.4.0/24,要从192.168.56.1这个口出去,下一跳为192.168.56.2。

于是,路由器A思考的时候,匹配上了这条路由,要从192.168.56.1这个口发出去,发给192.168.56.2,那192.168.56.2的MAC地址是多少呢?路由器A发送ARP获取192.168.56.2的MAC地址,然后发送包。包的内容是这样的:

  • 源MAC:192.168.56.1的MAC地址
  • 目标MAC:192.168.56.2的MAC地址
  • 源IP:192.168.1.101
  • 目标IP:192.168.4.101

包到达192.168.56.2这个网口,发现MAC一致,将包收进来,开始思考往哪里转发。

在路由器B中配置了静态路由,要想访问192.168.4.0/24,要从192.168.4.1这个口出去,没有下一跳了。因为我右手这个网卡,就是这个网段的,我是最后一跳了。

于是,路由器B思考的时候,匹配上了这条路由,要从192.168.4.1这个口发出去,发给192.168.4.101。那192.168.4.101的MAC地址是多少呢?路由器B发送ARP获取192.168.4.101的MAC地址,然后发送包。包的内容是这样的:

  • 源MAC:192.168.4.1的MAC地址
  • 目标MAC:192.168.4.101的MAC地址
  • 源IP:192.168.1.101
  • 目标IP:192.168.4.101

包到达服务器B,MAC地址匹配,将包收进来。

通过这个过程可以看出,每到一个新的局域网,MAC都是要变的,但是IP地址都不变。在IP头里面,不会保存任何网关的IP地址。所谓的下一跳是,某个IP要将这个IP地址转换为MAC放入MAC头。

之所以将这种模式比喻称为欧洲十国游,是因为在整个过程中,IP头里面的地址都是不变的。IP地址在三个局域网都可见,在三个局域网之间的网段都不会冲突。在三个网段之间传输包,IP头不改变。这就像在欧洲各国之间旅游,一个签证就能搞定。img

“玄奘西行”型

我们再来看“玄奘西行”型。

这里遇见的第一个问题是,局域网之间没有商量过,各定各的网段,因而IP段冲突了。最左面大唐的地址是192.168.1.101,最右面印度的地址也是192.168.1.101,如果单从IP地址上看,简直是自己访问自己,其实是大唐的192.168.1.101要访问印度的192.168.1.101。

怎么解决这个问题呢?既然局域网之间没有商量过,你们各管各的,那到国际上,也即中间的局域网里面,就需要使用另外的地址。就像出国,不能用咱们自己的身份证,而要改用护照一样,玄奘西游也要拿着专门取经的通关文牒,而不能用自己国家的身份证。

首先,目标服务器B在国际上要有一个国际的身份,我们给它一个192.168.56.2。在网关B上,我们记下来,国际身份192.168.56.2对应国内身份192.168.1.101。凡是要访问192.168.56.2,都转成192.168.1.101。

于是,源服务器A要访问目标服务器B,要指定的目标地址为192.168.56.2。这是它的国际身份。服务器A想,192.168.56.2和我不是一个网段的,因而需要发给网关,网关是谁?已经静态配置好了,网关是192.168.1.1,网关的MAC地址是多少?发送ARP获取网关的MAC地址,然后发送包。包的内容是这样的:

  • 源MAC:服务器A的MAC
  • 目标MAC:192.168.1.1这个网口的MAC
  • 源IP:192.168.1.101
  • 目标IP:192.168.56.2

包到达192.168.1.1这个网口,发现MAC一致,将包收进来,开始思考往哪里转发。

在路由器A中配置了静态路由:要想访问192.168.56.2/24,要从192.168.56.1这个口出去,没有下一跳了,因为我右手这个网卡,就是这个网段的,我是最后一跳了。

于是,路由器A思考的时候,匹配上了这条路由,要从192.168.56.1这个口发出去,发给192.168.56.2。那192.168.56.2的MAC地址是多少呢?路由器A发送ARP获取192.168.56.2的MAC地址。

当网络包发送到中间的局域网的时候,服务器A也需要有个国际身份,因而在国际上,源IP地址也不能用192.168.1.101,需要改成192.168.56.1。发送包的内容是这样的:

  • 源MAC:192.168.56.1的MAC地址
  • 目标MAC:192.168.56.2的MAC地址
  • 源IP:192.168.56.1
  • 目标IP:192.168.56.2

包到达192.168.56.2这个网口,发现MAC一致,将包收进来,开始思考往哪里转发。

路由器B是一个NAT网关,它上面配置了,要访问国际身份192.168.56.2对应国内身份192.168.1.101,于是改为访问192.168.1.101。

在路由器B中配置了静态路由:要想访问192.168.1.0/24,要从192.168.1.1这个口出去,没有下一跳了,因为我右手这个网卡,就是这个网段的,我是最后一跳了。

于是,路由器B思考的时候,匹配上了这条路由,要从192.168.1.1这个口发出去,发给192.168.1.101。

那192.168.1.101的MAC地址是多少呢?路由器B发送ARP获取192.168.1.101的MAC地址,然后发送包。内容是这样的:

  • 源MAC:192.168.1.1的MAC地址
  • 目标MAC:192.168.1.101的MAC地址
  • 源IP:192.168.56.1
  • 目标IP:192.168.1.101

包到达服务器B,MAC地址匹配,将包收进来。

从服务器B接收的包可以看出,源IP为服务器A的国际身份,因而发送返回包的时候,也发给这个国际身份,由路由器A做NAT,转换为国内身份。

从这个过程可以看出,IP地址也会变。这个过程用英文说就是Network Address Translation,简称NAT

其实这第二种方式我们经常见,现在大家每家都有家用路由器,家里的网段都是192.168.1.x,所以你肯定访问不了你邻居家的这个私网的IP地址的。所以,当我们家里的包发出去的时候,都被家用路由器NAT成为了运营商的地址了。

很多办公室访问外网的时候,也是被NAT过的,因为不可能办公室里面的IP也是公网可见的,公网地址实在是太贵了,所以一般就是整个办公室共用一个到两个出口IP地址。你可以通过 https://www.whatismyip.com/ 查看自己的出口IP地址。

总结

  • 如果离开本局域网,就需要经过网关,网关是路由器的一个网口;
  • 路由器是一个三层设备,里面有如何寻找下一跳的规则;
  • 经过路由器之后MAC头要变,如果IP不变,相当于不换护照的欧洲旅游,如果IP变,相当于换护照的玄奘西行。

路由协议

如何配置路由?

路由器就是一台网络设备,它有多张网卡。当一个入口的网络包送到路由器时,它会根据一个本地的转发信息库,来决定如何正确地转发流量。这个转发信息库通常被称为路由表

一张路由表中会有多条路由规则。每一条规则至少包含这三项信息。

  • 目的网络:这个包想去哪儿?
  • 出口设备:将包从哪个口扔出去?
  • 下一跳网关:下一个路由器的地址。

通过route命令和ip route命令都可以进行查询或者配置。

例如,我们设置ip route add 10.176.48.0/20 via 10.173.32.1 dev eth0,就说明要去10.176.48.0/20这个目标网络,要从eth0端口出去,经过10.173.32.1。

之前的例子中,网关上的路由策略就是按照这三项配置信息进行配置的。这种配置方式的一个核心思想是:根据目的IP地址来配置路由

如何配置策略路由?

当然,在真实的复杂的网络环境中,除了可以根据目的ip地址配置路由外,还可以根据多个参数来配置路由,这就称为策略路由

可以配置多个路由表,可以根据源IP地址、入口设备、TOS等选择路由表,然后在路由表中查找路由。这样可以使得来自不同来源的包走不同的路由。

例如,我们设置:

ip rule add from 192.168.1.0/24 table 10 
ip rule add from 192.168.2.0/24 table 20

表示从192.168.1.10/24这个网段来的,使用table 10中的路由表,而从192.168.2.0/24网段来的,使用table20的路由表。

在一条路由规则中,也可以走多条路径。例如,在下面的路由规则中:

ip route add default scope global nexthop via 100.100.100.1 weight 1 nexthop via 200.200.200.1 weight 2

下一跳有两个地方,分别是100.100.100.1和200.200.200.1,权重分别为1比2。

在什么情况下会用到如此复杂的配置呢?举一个现实中的例子。

我是房东,家里从运营商那儿拉了两根网线。这两根网线分别属于两个运行商。一个带宽大一些,一个带宽小一些。这个时候,我就不能买普通的家用路由器了,得买个高级点的,可以接两个外网的。

家里的网络呢,就是普通的家用网段192.168.1.x/24。家里有两个租户,分别把线连到路由器上。IP地址为192.168.1.101/24和192.168.1.102/24,网关都是192.168.1.1/24,网关在路由器上。

家里的网段是私有网段,出去的包需要NAT成公网的IP地址,因而路由器是一个NAT路由器。

两个运营商都要为这个网关配置一个公网的IP地址。如果你去查看你们家路由器里的网段,基本就是我图中画的样子。

img

运行商里面也有一个IP地址,在运营商网络里面的网关。不同的运营商方法不一样,有的是/32的,也即一个一对一连接。

例如,运营商1给路由器分配的地址是183.134.189.34/32,而运营商网络里面的网关是183.134.188.1/32。有的是/30的,也就是分了一个特别小的网段。运营商2给路由器分配的地址是60.190.27.190/30,运营商网络里面的网关是60.190.27.189/30。

根据这个网络拓扑图,可以将路由配置成这样:

$ ip route list table main 
60.190.27.189/30 dev eth3  proto kernel  scope link  src 60.190.27.190
183.134.188.1 dev eth2  proto kernel  scope link  src 183.134.189.34
192.168.1.0/24 dev eth1  proto kernel  scope link  src 192.168.1.1
127.0.0.0/8 dev lo  scope link
default via 183.134.188.1 dev eth2

当路由这样配置的时候,就告诉这个路由器如下的规则:

  • 如果去运营商二,就走eth3;
  • 如果去运营商一呢,就走eth2;
  • 如果访问内网,就走eth1;
  • 如果所有的规则都匹配不上,默认走运营商一,也即走快的网络。

但是问题来了,租户A不想多付钱,他说我就上上网页,从不看电影,凭什么收我同样贵的网费啊?没关系,咱有技术可以解决。

下面我添加一个Table,名字叫chao

# echo 200 chao >> /etc/iproute2/rt_tables

添加一条规则:

# ip rule add from 192.168.1.101 table chao
# ip rule ls
0:    from all lookup local 
32765:    from 10.0.0.10 lookup chao
32766:    from all lookup main 
32767:    from all lookup default

设定规则为:从192.168.1.101来的包都查看个chao这个新的路由表。

在chao路由表中添加规则:

# ip route add default via 60.190.27.189 dev eth3 table chao
# ip route flush cache

默认的路由走慢的,谁让你不付钱。

上面说的都是静态的路由,一般来说网络环境简单的时候,在自己的可控范围之内,自己捣鼓还是可以的。但是有时候网络环境复杂并且多变,如果总是用静态路由,一旦网络结构发生变化,让网络管理员手工修改路由太复杂了,因而需要动态路由算法。

动态路由算法

使用动态路由路由器,可以根据路由协议算法生成动态路由表,随网络运行状况的变化而变化。那路由算法是什么样的呢?

我们可以想象唐僧西天取经,需要解决两大问题,一个是在每个国家如何找到正确的路,去换通关文牒、吃饭、休息;一个是在国家之间,野外行走的时候,如何找到正确的路、水源的问题。

img

无论是一个国家内部,还是国家之间,我们都可以将复杂的路径,抽象为一种叫作图的数据结构。至于唐僧西行取经,肯定想走得路越少越好,道路越短越好,因而这就转化成为如何在途中找到最短路径的问题。

求最短路径常用的有两种方法,一种是Bellman-Ford算法,一种是Dijkstra算法。在计算机网络中基本也是用这两种方法计算的。

1.距离矢量路由算法

第一大类的算法称为距离矢量路由distance vector routing)。它是基于Bellman-Ford算法的。

这种算法的基本思路是,每个路由器都保存一个路由表,包含多行,每行对应网络中的一个路由器,每一行包含两部分信息,一个是要到目标路由器,从那条线出去,另一个是到目标路由器的距离。

由此可以看出,每个路由器都是知道全局信息的。那这个信息如何更新呢?每个路由器都知道自己和邻居之间的距离,每过几秒,每个路由器都将自己所知的到达所有的路由器的距离告知邻居,每个路由器也能从邻居那里得到相似的信息。

每个路由器根据新收集的信息,计算和其他路由器的距离,比如自己的一个邻居距离目标路由器的距离是M,而自己距离邻居是x,则自己距离目标路由器是x+M。

这个算法比较简单,但是还是有问题。

第一个问题就是好消息传得快,坏消息传得慢。如果有个路由器加入了这个网络,它的邻居就能很快发现它,然后将消息广播出去。要不了多久,整个网络就都知道了。但是一旦一个路由器挂了,挂的消息是没有广播的。当每个路由器发现原来的道路到不了这个路由器的时候,感觉不到它已经挂了,而是试图通过其他的路径访问,直到试过了所有的路径,才发现这个路由器是真的挂了。

举个例子。

img

原来的网络包括两个节点,B和C。A加入了网络,它的邻居B很快就发现A启动起来了。于是它将自己和A的距离设为1,同样C也发现A起来了,将自己和A的距离设置为2。但是如果A挂掉,情况就不妙了。B本来和A是邻居,发现连不上A了,但是C还是能够连上,只不过距离远了点,是2,于是将自己的距离设置为3。殊不知C的距离2其实是基于原来自己的距离为1计算出来的。C发现自己也连不上A,并且发现B设置为3,于是自己改成距离4。依次类推,数越来越大,直到超过一个阈值,我们才能判定A真的挂了。

这个道理有点像有人走丢了。当你突然发现找不到这个人了。于是你去学校问,是不是在他姨家呀?找到他姨家,他姨说,是不是在他舅舅家呀?他舅舅说,是不是在他姥姥家呀?他姥姥说,是不是在学校呀?总归要问一圈,或者是超过一定的时间,大家才会认为这个人的确走丢了。如果这个人其实只是去见了一个谁都不认识的网友去了,当这个人回来的时候,只要他随便见到其中的一个亲戚,这个亲戚就会拉着他到他的家长那里,说你赶紧回家,你妈都找你一天了。

这种算法的第二个问题是,每次发送的时候,要发送整个全局路由表。网络大了,谁也受不了,所以最早的路由协议RIP就是这个算法。它适用于小型网络(小于15跳)。当网络规模都小的时候,没有问题。现在一个数据中心内部路由器数目就很多,因而不适用了。

所以上面的两个问题,限制了距离矢量路由的网络规模。

2.链路状态路由算法

第二大类算法是链路状态路由link state routing),基于Dijkstra算法。

这种算法的基本思路是:当一个路由器启动的时候,首先是发现邻居,向邻居say hello,邻居都回复。然后计算和邻居的距离,发送一个echo,要求马上返回,除以二就是距离。然后将自己和邻居之间的链路状态包广播出去,发送到整个网络的每个路由器。这样每个路由器都能够收到它和邻居之间的关系的信息。因而,每个路由器都能在自己本地构建一个完整的图,然后针对这个图使用Dijkstra算法,找到两点之间的最短路径。

不像距离距离矢量路由协议那样,更新时发送整个路由表。链路状态路由协议只广播更新的或改变的网络拓扑,这使得更新信息更小,节省了带宽和CPU利用率。而且一旦一个路由器挂了,它的邻居都会广播这个消息,可以使得坏消息迅速收敛。

动态路由协议

1.基于链路状态路由算法的OSPF

OSPFOpen Shortest Path First开放式最短路径优先)就是这样一个基于链路状态路由协议,广泛应用在数据中心中的协议。由于主要用在数据中心内部,用于路由决策,因而称为内部网关协议Interior Gateway Protocol,简称IGP)。

内部网关协议的重点就是找到最短的路径。在一个组织内部,路径最短往往最优。当然有时候OSPF可以发现多个最短的路径,可以在这多个路径中进行负载均衡,这常常被称为等价路由

img

这一点非常重要。有了等价路由,到一个地方去可以有相同的两个路线,可以分摊流量,还可以当一条路不通的时候,走另外一条路。这个在后面我们讲数据中心的网络的时候,一般应用的接入层会有负载均衡LVS。它可以和OSPF一起,实现高吞吐量的接入层设计。

有了内网的路由协议,在一个国家内,唐僧可以想怎么走怎么走了,两条路选一条也行。

2.基于距离矢量路由算法的BGP

但是外网的路由协议,也即国家之间的,又有所不同。我们称为外网路由协议Border Gateway Protocol,简称BGP)。

在一个国家内部,有路当然选近的走。但是国家之间,不光远近的问题,还有政策的问题。例如,唐僧去西天取经,有的路近。但是路过的国家看不惯僧人,见了僧人就抓。例如灭法国,连光头都要抓。这样的情况即便路近,也最好绕远点走。

对于网络包同样,每个数据中心都设置自己的Policy。例如,哪些外部的IP可以让内部知晓,哪些内部的IP可以让外部知晓,哪些可以通过,哪些不能通过。这就好比,虽然从我家里到目的地最近,但是不能谁都能从我家走啊!

在网络世界,这一个个国家成为自治系统AS(Autonomous System)。自治系统分几种类型。

  • Stub AS:对外只有一个连接。这类AS不会传输其他AS的包。例如,个人或者小公司的网络。
  • Multihomed AS:可能有多个连接连到其他的AS,但是大多拒绝帮其他的AS传输包。例如一些大公司的网络。
  • Transit AS:有多个连接连到其他的AS,并且可以帮助其他的AS传输包。例如主干网。

每个自治系统都有边界路由器,通过它和外面的世界建立联系。

img

BGP又分为两类,eBGP和iBGP。自治系统间,边界路由器之间使用eBGP广播路由。内部网络也需要访问其他的自治系统。边界路由器如何将BGP学习到的路由导入到内部网络呢?就是通过运行iBGP,使得内部的路由器能够找到到达外网目的地的最好的边界路由器。

BGP协议使用的算法是路径矢量路由协议(path-vector protocol)。它是距离矢量路由协议的升级版。

前面说了距离矢量路由协议的缺点。其中一个是收敛慢。在BGP里面,除了下一跳hop之外,还包括了自治系统AS的路径,从而可以避免坏消息传的慢的问题,也即上面所描述的,B知道C原来能够到达A,是因为通过自己,一旦自己都到达不了A了,就不用假设C还能到达A了。

另外,在路径中将一个自治系统看成一个整体,不区分自治系统内部的路由器,这样自治系统的数目是非常有限的。就像大家都能记住出去玩,从中国出发先到韩国然后到日本,只要不计算细到具体哪一站,就算是发送全局信息,也是没有问题的。

总结

  • 路由分静态路由和动态路由,静态路由可以配置复杂的策略路由,控制转发策略;
  • 动态路由主流算法有两种,距离矢量算法和链路状态算法。基于两种算法产生两种协议,BGP协议和OSPF协议。
posted @ 2020-05-13 20:16  小萝卜鸭  阅读(1517)  评论(0编辑  收藏  举报