Linux 内核网络协议栈涉及中间三层,分别为数据链路层、网络层和传输层,不涉及物理层,应用层的任务也是由用户空间程序来实现的。

Linux 内核网络协议栈在处理数据链路层时,MAC 地址填的应该就是网关的 MAC 地址。

Linux 网络协议栈(包含驱动)和网卡硬件的接口

MAC 地址由谁填写?

  • 源 MAC 地址:由协议栈填写。驱动在初始化时会将网卡的硬件 MAC 地址(从 EEPROM 读取)注册到 net_device 结构体中,协议栈在构造数据帧时直接使用该地址作为源 MAC。
  • 目标 MAC 地址:由协议栈通过 ARP(IPv4)或 NDP(IPv6)协议解析得到,并填入帧头。若目标 MAC 未知,协议栈会先触发 ARP 请求。
  • 硬件 Offload 例外:部分高端网卡支持 MAC 头自动生成(Offload),此时协议栈可能仅提供目标 MAC,硬件自行填充源 MAC 和校验。但默认情况下由协议栈完成。

所以,可以得出结论,绝大多数情况下是内核协议栈构建完包的内容之后,将包的地址告诉网卡,由网卡 DMA 进行发送。但是可能有问题,你会觉得如果网卡只是发送包而不做任何事,那么为什么说网卡是同时工作在数据链路层和物理层呢,好像看起来网卡仅仅工作在了物理层。

这是因为网卡硬件可能补充数据链路层细节:添加 FCS(帧校验序列),处理 VLAN 标签(如有配置),最终将完整帧转换为物理信号发送。

Linux 路由子系统

Linux 路由子系统由三部分组成:路由缓存、路由策略、路由表。

Linux 内核路由策略 / 为什么要有多个路由表?

策略路由就是根据配置策略查找路由表,早期的 Linux 版本是不支持策略路由的,默认的查找策略就是先查找 local 表,找不到再继续查找 main 表。

以下是一些基本的元素:

  • 策略条件:规定何时应用 Routing Policy,例如基于源地址、目标地址、服务类型等。
  • 动作:确定数据包应该如何处理,例如转发到特定的下一跳、阻止或允许传输等。

Linux|聊聊Linux系统中的路由策略 - 知乎

Linux 路由策略应用场景

那么路由策略有哪些应用场景呢?Routing policy 在 Linux 系统中的使用场景有很多,其中一些典型的情况包括:

  • 多路径负载均衡:如果你有多个网络接口连接到不同的网络,你可能希望在这些接口之间分配流量,以实现负载均衡。通过使用不同的路由表和策略规则;
  • VPN 和专线冗余:在使用 VPN 或专线连接到不同的网络提供商时,你可能需要设置冗余路径,以确保在一个连接失败时能够切换到另一个连接。
  • 策略路由:有时你可能需要根据数据包的特定属性(如源 IP 地址、目标 IP 地址、服务类型等)来选择不同的路由表。
  • QoS 优化:根据服务类型或数据包优先级,可以通过 Routing Policy 确保关键服务的低延迟和高带宽。
  • 故障切换:当一个网络路径出现故障时,Routing Policy 可以自动切换到备用路径,提高网络的可用性。

Linux 内核路由表

代码位于 Linux 路由子系统。

Linux 有多个路由表:Linux 中最多可以有 255 张路由表,其中默认情况下有 local, main 和 default 三张:

  • local:路由表 local 包含本机路由及广播信息。例如,在本机上执行 ssh 127.0.0.1 时,就会参考这份路由表的内容,在正常情况下,只要配置好网卡的网络设置,就会自动生成 local 路由表的内容,我们应该也不必修改其内容。
  • main:使用传统命令 route -n 所看到的路由表就是 main 的内容。Linux 系统在默认情况下使用这份路由表的内容来传输数据包,因此,其内容极为重要,在正常情况下,只要配置好网卡的网络设置,就会自动生成 main 路由表的内容。
  • default:最后是 default 路由表,这个路由表在默认情况下内容为空;除非有特别的要求,否则保持其内容为空即可。

数据包在传输时是根据 RPDB(路由策略数据库)内的策略决定数据包应该用哪个路由表。

Linux 内核路由表项解析

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         192.168.0.1     0.0.0.0         UG    0      0        0 eth0
26.11.0.0       0.0.0.0         255.255.0.0     U     0      0        0 eth1
26.11.0.0       0.0.0.0         255.255.0.0     U     100    0        0 eth2
26.11.0.0       0.0.0.0         255.255.0.0     U     200    0        0 eth3
26.11.0.0       0.0.0.0         255.255.0.0     U     300    0        0 eth4
26.11.0.0       0.0.0.0         255.255.0.0     U     400    0        0 eth5
26.11.0.0       0.0.0.0         255.255.0.0     U     500    0        0 eth6
26.11.0.0       0.0.0.0         255.255.0.0     U     600    0        0 eth7
26.11.0.0       0.0.0.0         255.255.0.0     U     700    0        0 eth8
26.11.160.0     26.11.164.193   255.255.240.0   UG    0      0        0 eth6
26.11.164.64    0.0.0.0         255.255.255.224 U     0      0        0 eth1
26.11.164.96    0.0.0.0         255.255.255.224 U     0      0        0 eth2
26.11.164.128   0.0.0.0         255.255.255.224 U     0      0        0 eth3
26.11.164.160   0.0.0.0         255.255.255.224 U     0      0        0 eth4
26.11.164.192   0.0.0.0         255.255.255.224 U     0      0        0 eth6
26.11.164.224   0.0.0.0         255.255.255.224 U     0      0        0 eth5
26.11.165.0     0.0.0.0         255.255.255.224 U     0      0        0 eth7
26.11.165.32    0.0.0.0         255.255.255.224 U     0      0        0 eth8
192.168.0.0     0.0.0.0         255.255.255.0   U     0      0        0 eth0

各列字段说明:

  • Destination:目标网络或目标主机过滤条件(表示如果目的地址在这个区间的时候触发这一条内容)。Destination 为 default(0.0.0.0)时,表示这个是默认项,也就是没有经过其他条件过滤的在这里。
  • Gateway:下一跳(网关地址),0.0.0.0 表示当前记录对应的 Destination 跟本机在同一个网段,通信时不需要经过网关。
  • Genmask:Destination 字段的网络掩码,Destination 是主机时需要设置为 255.255.255.255,是默认路由时会设置为 0.0.0.0
  • Flags:标记,含义参考表格后面的解释。
  • Metric:路由距离,到达指定网络所需的中转数,是大型局域网和广域网设置所必需的 (不在 Linux 内核中使用。)
  • Ref:路由项引用次数 (不在 Linux 内核中使用。)
  • Use:此路由项被路由软件查找的次数
  • Iface:网卡名字,例如 eth0,这个表示的是要通过 eth0 这个网络接口来转发。