1、概述
ECMP(Equal Cost Multi Path),中文名叫等价多路径,是路由里的一项技术,作用是,在IP交换网络中存在到达同一目的地址的多条不同的路径,而且每条路径消耗的资源(Cost)一样的情况下,启用了ECMP功能的路由器就会根据配置策略,将它认定的“等价的IP报文”通过不同的路径均衡地转发出去,使转发达到负载均衡的目的。
2、具体介绍
使能ecmp的前提,就是需要内核使能CONFIG_IP_ROUTE_MULTIPATH配置,检查centos7.6内核,该配置已经使能。
[root@nm05-sdwan-jiankong-10e5e127e45 secure]# cat /boot/config-3.10.0-957.el7.x86_64 | grep IP
CONFIG_IP_ROUTE_MULTIPATH=y
CONFIG_IP_MULTIPLE_TABLES=y
当以上两个配置打开时,内核会对有多个默认网关设置做Round Robin选择。
[root@nm05-sdwan-jiankong-10e5e127e45 proc]# ip rou
default via 10.5.17.233 dev eth2 metric 2
default via 10.5.17.254 dev eth2 metric 2
针对这个服务器的两条默认网关,就是会轮流使用的,但是这个“轮流” 可以通过两个因素调整:1)hash策略 2) 权重;
1)hash策略
cat /proc/sys/net/ipv4/fib_multipath_hash_policy
fib_multipath_hash_policy用于指定路径选择时使用的哈希策略。默认值为0,表示基于三层头部数据的hash策略,另外值1,表示四层hash;值2表示三层或者内部三层的hash。
如果内核fib查询结果包含多个路径,由函数fib_multipath_hash计算hash值,之后,函数fib_select_multipath通过hash值选择其中的某个下一跳。
2)权重
通过添加路由的weight影响选择。
同时,内核也使用了路由缓存,一段时间内同一类IP报文,同一hash,使用相同的路由cache,路由缓存是会过期的,控制路由缓存超时的proc文件是:/proc/sys/net/ipv4/route/gc_timeout
如果需要使用ecmp,需要使用类似下面的配置命令:
[root@localhost ~]# ip route add default nexthop via 192.168.122.74 weight 1 nexthop via 192.168.122.93 weight 1
[root@localhost ~]#
[root@localhost ~]#
[root@localhost ~]#
[root@localhost ~]# ip route
default
nexthop via 192.168.122.74 dev eth0 weight 1
nexthop via 192.168.122.93 dev eth0 weight 1
192.168.122.0/24 dev eth0 proto kernel scope link src 192.168.122.185
其中192.168.122.74和192.168.122.93为两个默认网关。
最后,对于IPV4,虚假下一跳(配置静态arp)也是正常工作的原因是内核对于IPV4 默认不使用邻居表状态信息。
fib_multipath_use_neigh的值用于表示是否根据邻居表的状态选择路径,内核默认值0,表示不使用邻居表状态信息。
查询命令如下所示:
$ cat /proc/sys/net/ipv4/fib_multipath_use_neigh
有多路径的路由下决定下一跳时,是否考虑已经存在的邻居表的状态。如果关闭选项,则不使用邻居表信息,数据包被定向到的下一跳有可能是不通的。
3、举例
下面结合一个实际问题,进一步解释ecmp的原理。
问题现象:
同一台服务器上面的不同网卡配置同一网段的地址之后,其中一个网卡ping包不通问题,具体机器如下图所示:
定位过程:
a、在使用eth1进行ping包的时候,使用tcpdump在eth1进行抓包,发现可以发现回包,但是回包较少;
b、跟踪代码收包流程,发现在收包的skb中的devifindex为eth0的索引;
c、在eth0上面抓包,发现大部分回包都到了eth0口上面;
d、在对端机器上面查看邻居表项,发现如下现象:
Eth1网卡ip对应的mac地址为eth0的mac,于是跟踪arp学习流程。
e、重启机器,在干净环境下,使用eth1进行ping包,跟踪arp流程,本端机器进行arp学习之后,发现对端发回的arp request报文,此时报文的目的mac填充的是eth1的mac地址,但是本端没有处理,此后对端进行广播arp学习,此时回复的内容是eth1 ip地址对应eth0mac地址。
f、跟踪arp学习流程,发现是由于在fib_validate_source函数中会进行RPFILTER的判断,打开该判断后会对找到的路由所指定的出接口与报文的入接口进行比较,如果不同的话,则会返回错误,不进行arp报文的回复。
g、在实际的报文处理流程中,会根据对端的ip进行路由查找,由于路由如下所示,所以其会选择metric较小的路由进行流量的转发,也就是选择eth0作为出接口,所以发送接口与接收接口不一致,导致RPFILTER丢包。
h、可以使用如下方式关闭RPFILTER,就可以正常发送。
echo 0 > /proc/sys/net/ipv4/conf/eth1/rp_filter
echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter