写点什么

RoCE 多网卡时,报文可以过去,但是回不来

  • 2023-05-27
    广东
  • 本文字数:3760 字

    阅读完需:约 12 分钟

RoCE多网卡时,报文可以过去,但是回不来

本文分享自华为云社区《<跟唐老师学习云网络> - RoCE多网卡时,报文可以过去,但是回不来》,作者: tsjsdbd 。

一、网络概要


一台机子,接入 2 个子网,一个普通通信的,一个高速通信的。并且接入高速通信子网,有 8 张网卡。如下图:



本文描述的问题,只关注高速子网这一部分。为帮助理解问题,网络可以简化为:



每个网卡,都有分配该子网的一个 IP。如下:


二、问题现象


A 只能通 B 里面的一个 IP,其余 7 个 IP 都不通。下图为 A--->B 的结果:



图示:只有 1 个 IP 能通



反过来也一样,后面只讲一个方向的(A-->B)。

三、问题定位

1. 先看报文有没有到达 B。


如果都不能到 B,说明网络接的有问题。如果到了 B,但是不回来,说明路由配置可能有问题。


Ping 不通的 ip(228)时,在主机 B 上面进行抓包分析(228 对应的网卡名是 enp80s0f0,所以这里监听这个网卡):


tcpdump -i enp80s0f0 -n arplistening on enp80s0f0, link-type EN10MB (Ethernet), capture size 262144 bytes17:02:23.720556 ARP, Request who-has 29.28.195.228 tell 29.28.204.80, length 4617:02:24.758954 ARP, Request who-has 29.28.195.228 tell 29.28.204.80, length 4617:02:25.782954 ARP, Request who-has 29.28.195.228 tell 29.28.204.80, length 4617:02:26.807063 ARP, Request who-has 29.28.195.228 tell 29.28.204.80, length 46^C
复制代码


可以看到,报文能到 B。

2. 但是为什么 B 不给 A 回消息呢?


于是我们来看看,当 B 要给 A 回消息时,路由怎么走的?


查看路由表:


ip routedefault via 192.168.0.1 dev enp218s0 proto dhcp metric 10429.28.192.0/20 dev enp137s0f1 proto kernel scope link src 29.28.201.211 metric 10529.28.192.0/20 dev enp137s0f0 proto kernel scope link src 29.28.193.28 metric 10629.28.192.0/20 dev enp80s0f1 proto kernel scope link src 29.28.204.230 metric 10729.28.192.0/20 dev enp106s0f0 proto kernel scope link src 29.28.194.199 metric 10829.28.192.0/20 dev enp106s0f1 proto kernel scope link src 29.28.195.31 metric 10929.28.192.0/20 dev enp80s0f0 proto kernel scope link src 29.28.195.228 metric 11029.28.192.0/20 dev enp234s0f1 proto kernel scope link src 29.28.197.165 metric 11129.28.192.0/20 dev enp234s0f0 proto kernel scope link src 29.28.195.75 metric 112
复制代码


根据以前学的 router 知识,可以看到,(排除 default 路由外)应该是会匹配到 第 1 条(标红)规则。


注:metric 表示路由代价,目的子网都匹配的情况下,会选代价最低的那一条。


即 B-->A 给 A 回消息时,报文要从 网卡 enp137s0f1 发出去,并且发出去的报文源地址要设为 29.28.201.211。



难怪不通,因为答非所问了嘛(回 arp 报文,内容对不上)。


再看为什么 211 这个 ip 能通?


因为 211 是该子网路由选择,所对应的 IP,所以刚好能通。



这就解释了为什么刚好 1 个 IP 能通,另外 7 个不通。

3. 如何让报文从哪个口收到,就从哪个口回去?


往外发报文,根据源地址来选择网卡(注意这里的源是指 主机 B,因为回报文是往外发),这种场景可以称之为「源地址路由」,而要实现源地址路由,就需要用到「ip rule 路由策略」这种高级路由配置。


四、ip rule 路由策略


在配置「源地址路由」规则前,我们需要先补充一点基础知识。

1. 路由表“副本”


以前我们学的 route -n 路由表,其实属于“新手村”,即系统默认使用这张路由规则表。但就像《剑来》里面说的那样,在新手村外还有很多其他“境界”。Linux 新版本(2.x 之后)为实现更复杂的路由能力,将原来的“新手村”,复制了很多的“副本”。


Ps:这种增加“副本”的思路,在咱们 IT 领域非常常见,比如我们之前学到的各种 namespace。



当前系统总的“副本”数量,在 /etc/iproute2/rt_tables 这个文件中。


255 local254 main253 default0 unspec
复制代码


我们之前学的 route -n 新手村表,就是其中的 254 这个副本号,名字叫做 main。


要增加副本,可以如下这么操作:


echo "$id $table" >> /etc/iproute2/rt_tables
复制代码


就行了。

2. 如何决定使用哪个“副本”


为了确认使用哪个“副本”,在前面补了一个 rule 规则。



条件基本就是:源 IP,目的地址,收到网口这些。


具体见:https://www.computerhope.com/unix/ip.htm


所以现在流程变成了:


  1. 新增一个副本

  2. 设置 rule 规则,指向这个新增的副本

  3. 往副本里面增加以前学会的 route 记录


比如,我们希望某个源 IP 为 29.28.201.211 的报文,走独立的“路由副本”策略:


新建“路由副本”


echo "200 table0" >> /etc/iproute2/rt_tables
复制代码


增加规则,使这种报文,走该独立副本。(from 表示源 ip)


ip rule add from 29.28.201.211 table table0
复制代码


然后我们往这个“路由表副本”里面,放入以前学到的普通的路由规则:


ip route add 29.28.192.0/20 dev eth0 table table0
复制代码


可以确认下副本中路由是否正确


ip route show table table029.28.192.0/20 dev eth0 scope link
复制代码


这样,我们就可以控制更复杂的路由规则了。

3. 再看“新手村”路由表


在知道路由表可以有很多“副本”之后,我们再回头看看原来那个“新手村”。


从 /etc/iproute2/rt_tables 文件内容可以知道,咱们“新手村”对应的那个路标表名字叫做 main。


所以查询这个表的内容:


root@tsjsdbd:/# ip route show table maindefault via 172.17.0.1 dev eth0172.17.0.0/16 dev eth0 proto kernel scope link src 172.17.0.2
复制代码


这个和我们平时看到的路由,是一样的:


root@tsjsdbd:/# ip routedefault via 172.17.0.1 dev eth0172.17.0.0/16 dev eth0 proto kernel scope link src 172.17.0.2
复制代码


也就是,我们平时敲的 route -n 看到的列表,其实就是 main 这张表里面的内容。


其余表(0-local,253-default,255-local)的内容,一般不用关注。

4. rule 规则匹配优先级


在 rule 规则表里面,很多记录的时候,匹配优先级是怎么定的?答案是每一条记录,它有个优先级的字段。


如下:


[root@tsjsdbd]# ip rule0: from all lookup local32766: from all lookup main32767: from all lookup default
复制代码


最前面的数字,就是优先级。数字越小,优先级越高,也就是会先进行匹配,同时也代表这条规则可以排的更靠前。


在 rule add 添加规则的时候,是可以指定“优先级的”。如:


ip rule add from 192.168.1.0/24 table table0 pri 333
复制代码


就可以指定


在不指定优先级的情况下,会默认加到当前最小值前面(即,不指定优先值时,会加一条优先级较高的 rule)。


如下:


[root@tsjsdbd]# ip rule add from 192.168.1.0/24 table table0 pri 333
复制代码


上面这条会加一条 333 优先级的 rule


[root@tsjsdbd]# ip rule add from 192.168.2.0/24 table table0
复制代码


这条没指定优先级,就会加一条优先级 332 的(因为当前 rule 里面最小的是 333)。


可以查询确认:


[root@tsjsdbd]# ip rule0: from all lookup local332: from 192.168.2.0/24 lookup table0333: from 192.168.1.0/24 lookup table032766: from all lookup main32767: from all lookup default
复制代码


删除 rule 的话,有几种便捷的指定方式:(优先级、条件、table)


ip rule del pri 333ip rule del from 192.168.2.0/24ip rule del table table0
复制代码


最后注意,添加或修改了 rule 规则后,不会立即生效,需要 ip route flush cache 后才生效(官方文档是这么说的,自己验证的时候注意下就行)。

五、源地址路由


再回到问题上来,8 个网卡,哪个口收到,要求使用该口的 ip 回去。可以通过 8 个路由 table 实现(因为大家的目标网段是一样的,所以在同一个 table 表里面话,不好写规则)。



于是,可以把 8 个路由规则,分散到 8 个“世界”中,然后通过 rule 分散后,各自进行匹配。


事实上,「源地址路由」的实现,一般都是这种套路:


  • 添加一条“源地址”的 rule


ip rule add from 192.168.1.2 table 100


  • 在目标 table 里面,设置路由规则


ip route add 172.25.2.0/24 via 192.168.1.5 table 100


最终解决 8 个 RoCE 网卡可以互通的路由设置如下:


  • table 表(8 个)


/root # cat /etc/iproute2/rt_tables200 table0201 table1202 table2203 table3204 table4205 table5206 table6207 table7
复制代码


  • rule 表(8 个)


/root # ip rule0: from all lookup local32758: from 29.28.197.165 lookup table732759: from 29.28.195.75 lookup table632760: from 29.28.201.211 lookup table532761: from 29.28.193.28 lookup table432762: from 29.28.195.31 lookup table332763: from 29.28.194.199 lookup table232764: from 29.28.204.230 lookup table132765: from 29.28.195.228 lookup table032766: from all lookup main32767: from all lookup default
复制代码


  • 每个 table 表里面,1 条路由规则


/root # ip route show table table529.28.192.0/20 dev enp137s0f1 scope link src 29.28.201.211
复制代码


以上 3 步行为,通过一个脚本来完成。

六、最后


最后我们来看看,网络有问题的时候,与设置完「源地址路由」后的区别:


查询“以 xx 为源 ip,以 yy 为目的 ip,路由选择结果是什么”方式,


可以使用 ip route get 命令。


设置前:


# ip route get 29.28.204.80 from 29.28.201.21129.28.204.80 from 29.28.201.211 dev enp137s0f0 uid 0
复制代码


设置后:


# ip route get 29.28.204.80 from 29.28.201.21129.28.204.80 from 29.28.201.211 dev enp137s0f1 table table5 uid 0
复制代码


可以看到,是按照我们的目标“哪个口来,哪个口回去”的方式运行的。


点击关注,第一时间了解华为云新鲜技术~

发布于: 刚刚阅读数: 3
用户头像

提供全面深入的云计算技术干货 2020-07-14 加入

生于云,长于云,让开发者成为决定性力量

评论

发布
暂无评论
RoCE多网卡时,报文可以过去,但是回不来_后端_华为云开发者联盟_InfoQ写作社区