从物理层到MAC层
第一层(物理层)
网线
第二层(数据链路层)
Hub 采取的是广播的模式,如果每一台电脑发出的包,宿舍的每个电脑都能收到,那就麻烦了。这就需要解决几个问题:
- 这个包是发给谁的?谁应该接收?
- 大家都在发,会不会产生混乱?有没有谁先发、谁后发的规则?
- 如果发送的时候出现了错误,怎么办?
这几个问题,都是第二层,数据链路层,也即 MAC 层要解决的问题。MAC 的全称是 Medium Access Control,即媒体访问控制。控制什么呢?其实就是控制在往媒体上发数据的时候,谁先发、谁后发的问题。防止发生混乱。这解决的是第二个问题。这个问题中的规则,学名叫多路访问。
三种方式:
方式一:分多个车道。每个车一个车道,你走你的,我走我的。这在计算机网络里叫作信道划分;
方式二:今天单号出行,明天双号出行,轮着来。这在计算机网络里叫作轮流协议;
方式三:不管三七二十一,有事儿先出门,发现特堵,就回去。错过高峰再出。我们叫作随机接入协议。著名的以太网,用的就是这个方式。
接下来要解决第一个问题:发给谁,谁接收?这里用到一个物理地址,叫作链路层地址。但是因为第二层主要解决媒体接入控制的问题,所以它常被称为MAC 地址。
解决第一个问题就牵扯到第二层的网络包格式。
对于以太网,第二层的最后面是 CRC,也就是循环冗余检测。通过 XOR 异或的算法,来计算整个包是否在发送的过程中出现了错误,主要解决第三个问题。
这里还有一个没有解决的问题,当源机器知道目标机器的时候,可以将目标地址放入包里面,如果不知道呢?一个广播的网络里面接入了 N 台机器,我怎么知道每个 MAC 地址是谁呢?这就是ARP 协议,也就是已知 IP 地址,求 MAC 地址的协议。
ARP 是通过吼的方式(广播)来寻找目标 MAC 地址的,吼完之后记住一段时间,这个叫作缓存。
谁能知道目标 MAC 地址是否就是连接某个口的电脑的 MAC 地址呢?这就需要一个能把 MAC 头拿下来,检查一下目标 MAC 地址,然后根据策略转发的设备,这个设备显然是个二层设备,我们称为交换机。
交换机是有 MAC 地址学习能力的,学完了它就知道谁在哪儿了,不用广播了。(刚开始不知道的时候,是需要广播的)
交换机与VLAN
当交换机的数目越来越多的时候,会遭遇环路问题,让网络包迷路,这就需要使用 STP 协议,通过华山论剑比武的方式,将有环路的图变成没有环路的树,从而解决环路问题。
STP协议
在数据结构中,有一个方法叫做最小生成树。有环的我们常称为图。将图中的环破了,就生成了树。在计算机网络中,生成树的算法叫作 STP,全称 Spanning Tree Protocol。
STP 协议比较复杂,一开始很难看懂,但是其实这是一场血雨腥风的武林比武或者华山论剑,最终决出五岳盟主的方式。
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,拿自己的本事比。
交换机数目多会面临隔离问题,可以通过 VLAN 形成虚拟局域网,从而解决广播问题和安全问题。
对于支持 VLAN 的交换机,有一种口叫作 Trunk 口。它可以转发属于任何 VLAN 的口。交换机之间可以通过这种口相互连接。
ICMP与ping
ping 是基于 ICMP 协议工作的。
ICMP 全称 Internet Control Message Protocol,就是互联网控制报文协议。
ICMP 报文是封装在 IP 包里面的。因为传输指令的时候,肯定需要源地址和目标地址。它本身非常简单。因为作为侦查兵,要轻装上阵,不能携带大量的包袱。
ICMP 报文有很多的类型,不同的类型有不同的代码。最常用的类型是主动请求为 8,主动请求的应答为 0。
- 查询报文类型
常用的 ping 就是查询报文,是一种主动请求,并且获得主动应答的 ICMP 协议。所以,ping 发的包也是符合 ICMP 协议格式的,只不过它在后面增加了自己的格式。
对 ping 的主动请求,进行网络抓包,称为ICMP ECHO REQUEST。同理主动请求的回复,称为ICMP ECHO REPLY。比起原生的 ICMP,这里面多了两个字段,一个是标识符。这个很好理解,你派出去两队侦查兵,一队是侦查战况的,一队是去查找水源的,要有个标识才能区分。另一个是序号,你派出去的侦查兵,都要编个号。如果派出去 10 个,回来 10 个,就说明前方战况不错;如果派出去 10 个,回来 2 个,说明情况可能不妙。在选项数据中,ping 还会存放发送请求的时间值,来计算往返时间,说明路程的长短。 - 差错报文类型
举几个 ICMP 差错报文的例子:终点不可达为 3,源抑制为 4,超时为 11,重定向为 5。
ping:查询报文类型的使用
ICMP总结:
ICMP 相当于网络世界的侦察兵。我讲了两种类型的 ICMP 报文,一种是主动探查的查询报文,一种异常报告的差错报文;
ping 使用查询报文,Traceroute 使用差错报文。
世界这么大,我想出网关
在进行网卡配置的时候,除了 IP 地址,还需要配置一个Gateway 的东西,这个就是网关。
MAC 头和 IP 头
一旦配置了 IP 地址和网关,往往就能够指定目标地址进行访问了。由于在跨网关访问的时候,牵扯到 MAC 地址和 IP 地址的变化,这里有必要详细描述一下 MAC 头和 IP 头的细节。
路由器是一台设备,它有五个网口或者网卡,相当于有五只手,分别连着五个局域网。每只手的 IP 地址都和局域网的 IP 地址相同的网段,每只手都是它握住的那个局域网的网关。
IP 头和 MAC 头哪些变、哪些不变?
对于 IP 头和 MAC 头哪些变、哪些不变的问题,可以分两种类型。我把它们称为“欧洲十国游”型和“玄奘西行”型。
之前我说过,MAC 地址是一个局域网内才有效的地址。因而,MAC 地址只要过网关,就必定会改变,因为已经换了局域网。
两者主要的区别在于 IP 地址是否改变。不改变 IP 地址的网关,我们称为转发网关;改变 IP 地址的网关,我们称为NAT 网关。
网关总结:
- 如果离开本局域网,就需要经过网关,网关是路由器的一个网口;
- 路由器是一个三层设备,里面有如何寻找下一跳的规则;
- 经过路由器(网关)之后 MAC 头会变。
如果 IP 不变,转发网关,相当于不换护照的欧洲旅游;
如果 IP 变,NAT 网关,相当于换护照的玄奘西行。
路由协议
路由分静态路由和动态路由,静态路由可以配置复杂的策略路由,控制转发策略;
动态路由主流算法有两种,距离矢量算法和链路状态算法。
路由算法一:距离矢量路由算法
距离矢量路由(distance vector routing)。它是基于 Bellman-Ford 算法的。
这种算法的基本思路是,每个路由器都保存一个路由表,包含多行,每行对应网络中的一个路由器,每一行包含两部分信息,一个是要到目标路由器,从那条线出去,另一个是到目标路由器的距离。
由此可以看出,每个路由器都是知道全局信息的。那这个信息如何更新呢?每个路由器都知道自己和邻居之间的距离,每过几秒,每个路由器都将自己所知的到达所有的路由器的距离告知邻居,每个路由器也能从邻居那里得到相似的信息。
每个路由器根据新收集的信息,计算和其他路由器的距离,比如自己的一个邻居距离目标路由器的距离是 M,而自己距离邻居是 x,则自己距离目标路由器是 x+M。
这种算法存在的问题:
第一个问题:好消息传得快,坏消息传得慢。
第二个问题:每次发送的时候,要发送整个全局路由表。
所以上面的两个问题,限制了距离矢量路由的网络规模。
路由算法二:链路状态路由算法
链路状态路由(link state routing),基于 Dijkstra 算法。
这种算法的基本思路是:当一个路由器启动的时候,首先是发现邻居,向邻居 say hello,邻居都回复。然后计算和邻居的距离,发送一个 echo,要求马上返回,除以二就是距离。然后将自己和邻居之间的链路状态包广播出去,发送到整个网络的每个路由器。这样每个路由器都能够收到它和邻居之间的关系的信息。因而,每个路由器都能在自己本地构建一个完整的图,然后针对这个图使用 Dijkstra 算法,找到两点之间的最短路径。
不像距离距离矢量路由协议那样,更新时发送整个路由表。链路状态路由协议只广播更新的或改变的网络拓扑,这使得更新信息更小,节省了带宽和 CPU 利用率。而且一旦一个路由器挂了,它的邻居都会广播这个消息,可以使得坏消息迅速收敛。
动态路由协议
基于两种算法产生两种协议,BGP 协议和 OSPF 协议。
1. 基于链路状态路由算法的 OSPF
OSPF(Open Shortest Path First,开放式最短路径优先)就是这样一个基于链路状态路由协议,广泛应用在数据中心中的协议。由于主要用在数据中心内部,用于路由决策,因而称为内部网关协议(Interior Gateway Protocol,简称 IGP)。
内部网关协议的重点就是找到最短的路径。在一个组织内部,路径最短往往最优。当然有时候 OSPF 可以发现多个最短的路径,可以在这多个路径中进行负载均衡,这常常被称为等价路由。
2. 基于距离矢量路由算法的 BGP
但是外网的路由协议,也即国家之间的,又有所不同。我们称为外网路由协议(Border Gateway Protocol,简称 BGP)。
在网络世界,这一个个国家成为自治系统 AS(Autonomous System)。自治系统分几种类型。
- Stub AS:对外只有一个连接。这类 AS 不会传输其他 AS 的包。例如,个人或者小公司的网络。
- Multihomed AS:可能有多个连接连到其他的 AS,但是大多拒绝帮其他的 AS 传输包。例如一些大公司的网络。
- Transit AS:有多个连接连到其他的 AS,并且可以帮助其他的 AS 传输包。例如主干网。
每个自治系统都有边界路由器,通过它和外面的世界建立联系。
BGP 又分为两类,eBGP 和 iBGP。自治系统间,边界路由器之间使用 eBGP 广播路由。内部网络也需要访问其他的自治系统。边界路由器如何将 BGP 学习到的路由导入到内部网络呢?就是通过运行 iBGP,使得内部的路由器能够找到到达外网目的地的最好的边界路由器。
BGP 协议使用的算法是路径矢量路由协议(path-vector protocol)。它是距离矢量路由协议的升级版。
前面说了距离矢量路由协议的缺点。其中一个是收敛慢。在 BGP 里面,除了下一跳 hop 之外,还包括了自治系统 AS 的路径,从而可以避免坏消息传得慢的问题,也即上面所描述的,B 知道 C 原来能够到达 A,是因为通过自己,一旦自己都到达不了 A 了,就不用假设 C 还能到达 A 了。
另外,在路径中将一个自治系统看成一个整体,不区分自治系统内部的路由器,这样自治系统的数目是非常有限的。就像大家都能记住出去玩,从中国出发先到韩国然后到日本,只要不计算细到具体哪一站,就算是发送全局信息,也是没有问题的。