Network Layer

ICMP

互联网控制消息协议Internet Control Message Protocol,ICMP)用于网际协议(IP)中发送控制消息,提供可能发生在通信环境中的各种问题反馈。通过这些信息,使管理者可以对所发生的问题作出诊断,然后采取适当的措施解决。

ICMP 有很多类型,最常用的类型是主动请求为 8,主动请求的应答为 0。

查询报文类型

主动发起的类型。比如 ping 就是查询报文,是一种主动请求,并且获得主动应答的 ICMP 协议。

ping 的主动请求,称为 ICMP ECHO REQUEST,主动请求的回复,称为 ICMP ECHO REPLY

差错报文类型

异常情况发起,报告发生了不好的事。比如:终点不可达为3,源抑制为4,超时为11,重定向为5。

Traceroute 故意设置特殊的 TTL,来追踪去往目的地时沿途经过的路由器。

Traceroute 的参数指向某个目的 IP 地址,它会发送一个 UDP 的数据包。将 TTL 设置成 1,然后依次累加,直到到达目的主机,所以就能拿到所有的路由器 IP。

IP

IP 地址被点分割为四个部分,每部分 8bit,所以 IP一共是 32 位。IPV6 有 128 位,比如 fe80::f816:3eff:fec7:7975/64 。

每个 IP 地址又包括了主机号网络号两部分。相同网络号的主机组成一个子网;不同子网再通过路由器连接,组成一个庞大的网络。

五类 IP

CIDR

无类别域间路由(Classless Inter-Domain Routing、CIDR)将 32 位的IP 地址一分为二,前面是网络号,后面是主机号。X.X.X.X/A,意思是 32 位中,前 A 位是网络号,后 32 - A 位是主机号。10.126.6.255 是广播地址(一旦发送这个地址,10.126.6 网络里面的所有机器都可以收到),255.255.255.0 是子网掩码。将子网掩码与 IP 地址进行 AND 计算,就得到网络号。

例如,求 16.158.165.91/22 的第一个地址、子网掩码、广播地址。可以这么拆解:16.158.<101001>.<01>.91。第一个地址是16.158.<101001>.<00>.1,即16.158.164.1。子网掩码是 255.255.<111111>.<00>.0,即255.255.252.0。广播地址为 16.158.<101001>.<11>.255,即16.158.167.255。

查看 IP

在 Windows 中通过 ipconfig 查看 IP,在 Linux 中通过 ifconfig (net-tools)或ip iddr(iproute2)查看。

# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UNKNOWN qlen 1000
    link/ether 00:16:3e:0e:33:97 brd ff:ff:ff:ff:ff:ff
    inet 10.126.6.109/24 brd 10.126.6.255 scope global dynamic eth0
       valid_lft 292567783sec preferred_lft 292567783sec

ip addr 会显示所有的网卡,网卡可以有 IP 地址,也可以没有。上面输出 10.126.6.109 就是一个 IP 地址。

在 IP 地址的后面有个 scope,对于 eth0 这张网卡来讲,是 global,说明这张网卡是可以对外的,可以接收来自各个地方的包。对于 lo 来讲,是 host,说明这张网卡仅仅可以供本机相互通信。

在IP地址的上一行是 link/ether 00:16:3e:0e:33:97 brd ff:ff:ff:ff:ff:ff,这个被称为MAC地址,是一个网卡的物理地址,用十六进制,6个byte表示。MAC地址的通信范围比较小,局限在一个子网里面。

第一行的 <BROADCAST,MULTICAST,UP,LOWER_UP> 是 net_device flags网络设备的状态标识。UP 表示网卡处于启动的状态;BROADCAST 表示这个网卡有广播地址,可以发送广播包;MULTICAST 表示网卡可以发送多播包;LOWER_UP 表示L1是启动的,也即网线插着呢。

mtu 1500 表示最大传输单元MTU为1500,这是以太网的默认值。

qdisc pfifo_fast 表示排队规则为 pfifo_fast。qdisc 全称是 queueing discipline。

  • 最简单的 qdisc 是 pfifo,它不对进入的数据包做任何的处理,数据包采用先入先出的方式通过队列。

  • pfifo_fast 包括三个波段(band)。在每个波段里面,使用先进先出规则。

  • 三个波段(band)的优先级不同,band 0 ~ 2 优先级依次降低。比如若 band 0 里面有数据包,系统就不会处理 band 1 里面的数据包。

  • 数据包是按照服务类型(Type of Service,TOS)被分配到三个波段(band)里面的。TOS 是 IP 头里面的一个字段,代表了当前的包是高优先级的,还是低优先级的。

IP 头

  • 版本号:主流还是 IPv4

  • TOS 见上文

  • TTL 见 ICMP

  • 协议:指 TCP 还是 UDP

网关

在进行网卡配置的时候,除了IP地址,还需要配置一个 Gateway 的东西,这个就是网关。Gateway 的地址一定是和源 IP 地址是一个网段的。

Linux默认的逻辑是,如果是一个跨网段的调用,它便不会直接将包发送到网络上,而是企图将包发送到网关。也就是说如果你配置了网关,Linux 会获取网关的 MAC 地址,然后将包发送出去。

转发网关

不改变 IP 地址的网关。包到达网关后,源 MAC 变成网关出口的 MAC,目标 MAC 变成下一跳网关的 MAC 或目标 IP 的 MAC;源 IP 和目标 IP 不变。

如图 A 访问 192.168.56.2,A 配置了网关 192.168.1.1,通过 ARP 获取其 MAC:

  • 源 MAC:服务器 A 的 MAC

  • 目标 MAC:192.168.1.1 这个网口的 MAC

  • 源 IP:192.168.1.101

  • 目标 IP:192.168.56.2

路由器 A 配置了静态路由,要想访问192.168.56.2,要从 192.168.56.1 这个口出去,没有下一跳:

  • 源 MAC:192.168.56.1 的 MAC 地址

  • 目标 MAC:192.168.56.2 的 MAC 地址

  • 源 IP:192.168.1.101

  • 目标 IP:192.168.56.2

NAT 网关

NAT Network Address Translation)网关:改变 IP 地址(源和目标)的网关。MAC 地址的行为和转发网关是一致的;源 IP 和目标 IP 通过配置的 NAT 修改。NAT 可以分为三类:

  • 静态 NAT,内网 IP 与公网 IP 是一对一的映射关系。

  • 动态 NAT,内网 IP 从公网 IP 池中动态选一个映射。

  • 网络地址端口转换 NAPT(Network Address and Port Translation),内网 IP 映射到公网 IP 的不同端口,多个内网 IP共享同一个公网 IP。又可以分为三类:

    • SNAT,仅替换源 IP 或端口。主要用于内网多个 IP 共享一个公网 IP 来访问外网资源。

    • DNAT,仅替换目标 IP 或端口。主要用于公网 IP 通过不同端口号来访问内网资源,屏蔽真实 IP。

    • 双向地址转换。主要用于公网 IP 与内网 IP 一一对应,在虚拟环境中为虚拟机分配浮动的公网 IP。

如图,A 访问 192.168.56.2。A 配置了网关 192.168.1.1,通过 ARP 获取其 MAC 地址:

  • 源 MAC:A的 MAC

  • 目标 MAC:192.168.1.1 的 MAC

  • 源IP:192.168.1.101

  • 目标IP:192.168.56.2

包到达路由器 A 后,路由器 A 配置了静态路由:要想访问 192.168.56.2/24,要从 192.168.56.1这个口出去,没有下一跳。路由器 A 发送 ARP 获取 192.168.56.2 的 MAC:

  • 源 MAC:192.168.56.1 的 MAC 地址

  • 目标 MAC:192.168.56.2 的 MAC 地址

  • 源 IP:192.168.56.1

  • 目标 IP:192.168.56.2

路由器 B 配置了 NAT 网关:

  • 源 MAC:192.168.1.1 的 MAC 地址

  • 目标 MAC:192.168.1.101 的 MAC 地址

  • 源 IP:192.168.56.1

  • 目标 IP:192.168.1.101

关于 NAT 的具体应用可见操作系统-NAT

路由

网关往往是一个路由器,是一个三层转发的设备,它有五个网口或者网卡,分别连着五个局域网。每个口的 IP 地址都和局域网的 IP 地址相同的网段,每个口都是对应局域网的网关。

任何一个想发往其他局域网的包,都会到达其中一个口,拿下 MAC 头和 IP 头,根据路由算法,选择另一个口,加上 IP 头和 MAC 头再发出去。

路由种类:

  • 静态路由:路由项(routing entry)手动配置。

  • 动态路由:根据路由协议算法生成动态路由表,随网络运行状况的变化而变化。本质是最短路径算法,比如 Bellman-Ford、Dijkstra。

配置路由

路由规则包括:

  • 目的网络

  • 出口设备

  • 下一跳网关

通过 route 命令和 ip route 命令都可以进行查询或者配置。核心思想:根据目的 IP 地址来配置路由。

例如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、入口设备、TOS 等选择路由表。

# 从 192.168.1.0/24 来的使用表 10
ip rule add from 192.168.1.0/24 table 10 

# 从 192.168.2.0/24 来的使用表 20
ip rule add from 192.168.2.0/24 table 20

# 下一跳有两个地方,权重 1:2
ip route add default scope global nexthop via 100.100.100.1 weight 1 nexthop via 200.200.200.1 weight 2

距离矢量路由算法

距离矢量路由distance vector routing)是基于 Bellman-Ford 算法。

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

每个路由器都知道自己和邻居之间的距离,每个路由器都将自己所知的到达所有的路由器的距离告知邻居,每个路由器也能从邻居那里得到相似的信息。

问题:

  • 添加路由器很快能被广播,但是路由器下线很久才能被知道。

  • 每次发送都需要发送整个全局路由表。所以适用于小型网络(小于 15跳)。

链路状态路由算法

链路状态路由link state routing)是基于 Dijkstra 算法。

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

优点:

  • 每次广播都只发送改变的网络拓扑。

  • 路由器下线,它的邻居都会广播这个消息,很快就能被知道。

OSPF

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

有时候 OSPF 可以发现多个最短的路径,可以在这多个路径中进行负载均衡,这常常被称为等价路由

BGP

边界网关协议Border Gateway Protocol,BGP)是基于距离矢量路由算法。

BGP 分为两类,eBGP 和 iBGP。

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

Last updated