栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

linux路由子系统概念

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

linux路由子系统概念

1、基本概念

路由子系统工作在三层,用来转发入口流量。主要涉及 路由器、路由、路由表等概念。

路由器: 配备多个网络接口卡(NIC),并且能利用自身网络信息进行入口流量转发的设备。

路由:流量转发,决定目的地的过程

路由表:转发信息库,该库中储存路由需要本地接收还是转发的信息, 以及转发流量时所需要的信息。(即,信息库用来判断,要不要转发,如果要转发,向哪里转发)

不可路由地址,私有地址和本地环回地址不可路由。 当局域网(私有地址)的主机要与非该局域网的主机通信时,需要通过NAT来隐藏不可路由的子网。

定向广播:

子网广播:目的地址为本地子网的广播包。

定向广播:目的地址为远端子网的广播包。

定向子网广播针对ICMP ECHO REQUEST做特殊处理,以避免恶意攻击。

主地址、辅助地址、设备别名

地址属于主机而非接口,一个接口可以配置多个别名。(ip address add)。

一个NIC可配置多个朱地址和辅助地址,一个子网掩码只能有一个特定的主地址。

还有一个很重要的模块就是内核路由子系统,它应该是工作在L3层。发送报文时会在L3层打好IP头前,路由到具体的网络设备,然后才进入L2填充以太网头。路由的工作是通过函数ip_route_input()(/net/ipv4/route.c)实现的,对于进来的包可能的路由有这些:属于本地的数据(即是需要传递给TCP,UDP,IGMP这些上层协议的) ;需要要转发的数据包(网关或者NAT服务器之类的);不可能路由的数据包(地址信息有误);当路由发现是本地数据时,rth->u.dst.input = ip_local_deliver,返回后就可以在skb->dst->input(skb)中进入ip_local_deliver,找到对应的interface设备。如我们的eht0.y vlan虚拟设备,进入vlan处理流程。

2、Linux 作为一个路由器

Linux 作为一个路由器只需要打开 ipv4.forward 特性即可。

...
net.ipv4.ip_forward=1

$ sysctl -p

# 开启 NAT
$ iptables -t nat -A POSTROUTING -j MASQUERADE

开启了路由功能之后的 Linux 服务器就相当于一个 Router,Linux 服务器的路由表就相当于 Router 的路由表,Linux 服务器上的网卡就相当于 Router Interface。数据包会根据路由表规则在这些 “网卡” 中选择下一跳。

同时要注意 iptables 规则是否可能会造成混乱,对于 Router 所有数据包都是 SNAT,所以不需要配置 DNAT 规则,建议清理干净

3、route 指令

命令行下输入 ​​route -n​​​ 或 ​​netstat -rn​​,就可以打印本机的 main 路由表:

route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         172.18.22.1     0.0.0.0         UG    0      0        0 br-ex
172.18.22.0     0.0.0.0         255.255.255.0   U     0      0        0 br-ex
192.168.0.0     0.0.0.0         255.255.255.0   U     0      0        0 o-hm0
192.168.122.0   0.0.0.0         255.255.255.0   U     0      0        0 virbr0

4、操作实例

  • 1、要实现全网通信,也就是网络中任意两个节点都可以通信,就要求每个路由器的路由表中必须有到所有网段的路由。

  • 2、对于路由器来说,它只知道与自己直接相连的网段,对于没有直连的网络,则需要人工添加到这些网段的路由。如 R1 路由器直接与 A、B 两个网段相连,R1 会自动生成 A、B 网段的路由表,所以 R1 天然就知道数据包如何在在 A、B 网段之间进行转发。但 R1 没有与直接 C、D 网段相连,A、B 网段发出的数据包无法被 R1 转发至 C、D 网段,此时就需要手动添加 C、D 网段的路由到 R1(如上图所示)。此时 A 网段(192.168.0.2/24)访问 C 网段(172.16.1.2/24),R1 就知道该数据包应该被转发至 R2 的网关 172.16.0.2/24,R2 在根据目标地址(172.16.1.2/24)转发至 R3。

  • 3、​“下一跳” 指的是数据包下一步转发给哪个路由器,应该为目标路由器的入口地址​。对于点到点链路而言,“下一跳” 地址可以被写成目标网络的出口(如 serial 2/0),因为 PPP 协议,数据帧从一端发出,接收端只有一个;但对于路由器而言,因为路由器之间是一个以太网连接,这种情况下添加路由器,只能写下一跳地址,而不能写路由器的出口,因为路由器的出口连的是以太网,它无法知道该将数据包发给该以太网中的哪个路由器。

  • 4、路由器只关心到某个 ​网段​ 如何转发数据包,所以添加路由时一定要是某个网段的地址,而不能是某个特定地址的路由,即一定要确保 IP 地址的主机位全是 0。如果要让路由器转发到一个 IP 地址的路由,子网掩码要写成 4 个 255。如:​​R1(config)#ip route 192.168.1.3 255.255.255.255 172.16.0.2​​。

简单来说,每个 Router 都会连接多个 LAN,如果当前 Router 没有这个 LAN,那么 Router 就应该将数据包 ​下一跳​ 到连接这个 LAN 的 Router 上,之间可能隔着多个 Routers。

​NOTE​:需要注意的是,路由器功能生效的前提是连接一个 LAN 的路由网关接口必须配置了同一网段的网关 IP 地址。笔者经历过使用 DPDK 用户态数据面转发软件的场景,就是因为没有配置网管 IP 所以没有触发数据包的转发动作。无论是传统的路由交换组网场景,还是基于用户态内核旁路技术的自定义网络的组网场景,路由网关都是必要需要存在的。

5、Linux Kernel 路由子系统

Linux 在发送数据时和接收数据时都会涉及到路由子系统的工作。



Routing Table(路由表)在 Kernel 中的另外一个别名是 FIB(Forwarding Information Base,转发信息库)。所以,在 Kernel 中看到的 fib 开头的定义基本上就是和路由表相关的功能。

在默认情况下,Linux 只有 local 和 main 两个路由表,如果内核编译时支持策略路由,那么最多可以配置 255 个独立的路由表。查看是否开启了 CONFIG_IP_MULTIPLE_TABLES 多路由表支持。

若开启了,此时 Linux 自身会维护 4 个路由表:

$ cat /etc/iproute2/rt_tables
#
# reserved values
#
255 local
254 main
253 default
0 unspec
#
# local
#
#1  inr.ruhep
  • ​0 unspec table​: 系统保留表。
  • ​253 defulte table​:没特别指定的默认路由都放在该表。
  • 254 main table​:没指明路由表的所有路由都放在该表。
  • 255 locale table​:保存本地接口地址,广播地址、NAT 地址。该由系统维护,用户不得更改。

查看指定的路由表项目:

ip route list table {table_number}
# e.g.
$ ip route list table local

同时,Linux 支持 Network namespace,如果存在多个 Network namespace 的话,就会存在多套路由表。路由表在整个内核数据结构中的关联关系如下图所示。

6、发送数据时进行路由选择(选路)

Linux 在发送数据包的时候需要进行路由选路,因为服务器上可能会存在多张网卡设备。当待发送的数据包进入 IP 层的路由子系统时,就要进行路由选择(选路),以决定使用哪张网卡设备把数据包送出去。

IP 网络层数据包发送的入口函数是 ip_queue_xmit(),其中调用的 ip_route_output_ports() 函数实现了路由项的查找,继而完成路由选择,在路由表中进行匹配,然后决定使用哪个网卡发送出去。

7、接收数据时进行路由选择(选路)

因为 Linux 提供了路由器的功能,可以像路由器一样工作,将接收到的数据包通过合适的网卡将其转发出去。

IP 网络层数据包接收的入口函数是 ip_rcv(),执行后调用到 ip_rcv_finish(),在这里展开路由选择。

  • 如果匹配确实就是本设备的网络包,那么就通过 ip_local_deliver() 送到更上层的 TCP 层进行处理。
  • 如果匹配发现是非本设备的网络包,那就进入到 ip_forward() 进行转发,最后通过 ip_output() 发送出去。

    8、路由查找

上述内容提到,数据包发送过程中调用了 ip_route_output_ports() 来查找路由,数据包接收过程中调用了 ip_route_input_slow() 来查找。其实这两个函数最终都会调用到 fib_lookup() 这个核心函数。

fib_lookup() 函数依次到 local 和 main 表中进行匹配,匹配到后就返回。并且 local 表的优先级要高于 main 表,如果 local 表中找到了规则,则路由过程就结束了。

根据这个实现,当我们 ping 本地 IP 地址的时,eth0 上是抓不到包的。因为所有命中 local 表的包,都会被送往 loopback 设备,而不是 eth0。

©著作权归作者所有:来自51CTO博客作者云物互联的原创作品,请联系作者获取转载授权,否则将追究法律责任
Linux Kernel TCP/IP Stack — L3 Layer — 路由器子系统
https://blog.51cto.com/u_15301988/5180942

本节详细内容请参考:https://blog.51cto.com/u_15301988/5180942

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/914071.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号