组播分片报文重组后丢包问题(后续)

5 篇文章 0 订阅

组播分片报文重组后丢包问题(后续)

上篇组播分片报文重组后丢包问题,分析到最后是接口eth0和eth1在同一个广播域,且两个接口都处于混杂模式导致。

解决方案是关闭接口的混杂模式。

尝试清除IFF_PROMISC失败

于是想清除IFF_PROMISC标志,验证问题是否消失。

手动echo设置清除

手动清除失败,但其他标志位可以成功清除。看起来像是IFF_PROMISC被设定不可清除。

root@test:~# cat /sys/class/net/eth0/flags 
0x1103
root@test:~# echo 0x1003 > /sys/class/net/eth0/flags  //尝试清除IFF_PROMISC失败
root@test:~# cat /sys/class/net/eth0/flags 
0x1103
root@test:~# 
root@test:~# echo 0x1102 > /sys/class/net/eth0/flags   //清除IFF_UP成功
root@test:~# cat /sys/class/net/eth0/flags 
0x1102
root@test:~# echo 0x103 > /sys/class/net/eth0/flags   //清除IFF_MULTICAST成功
root@test:~# cat /sys/class/net/eth0/flags 
0x103

最为对比 eth2接口的IFF_PROMISC标志就可以成功设置和清除。

root@test:~# cat /sys/class/net/eth2/flags 
0x1003
root@test:~# echo 0x1103 > /sys/class/net/eth2/flags
root@test:~# cat /sys/class/net/eth2/flags 
0x1103
root@test:~# echo 0x1003 > /sys/class/net/eth2/flags
root@test:~# cat /sys/class/net/eth2/flags 
0x1003

通过ioctl接口设置清除

手动设置清除不行,于是尝试使用ioctl接口设置清除。写了个change工具通过ioctl设置SIOCGIFFLAGS。
经过验证,结果和手动设置相同。无法修改接口eth0和eth1的IFF_PROMISC标志,但可以修改其他标志位。

root@test:~# cat /sys/class/net/eth0/flags 
0x1103
root@test:~# ./change eth0 8
root@test:~# cat /sys/class/net/eth0/flags 
0x1103

root@test:~# ./change eth0 0
root@test:~# cat /sys/class/net/eth0/flags 
0x1102
root@test:~# ./change eth0 0
root@test:~# cat /sys/class/net/eth0/flags 
0x1103

root@test:~# ./change eth0 12
root@test:~# cat /sys/class/net/eth0/flags 
0x103
root@test:~# ./change eth0 12
root@test:~# cat /sys/class/net/eth0/flags 
0x1103

作为对比,eth0是可以设置清除IFF_PROMISC

//eth2 可以正常设置和清除IFF_PROMISC标志
root@test:~# cat /sys/class/net/eth2/flags 
0x1003
root@test:~# ./change eth2 8           //设置IFF_PROMISC
root@test:~# cat /sys/class/net/eth2/flags 
0x1103
root@test:~# ./change eth2 8          //清除IFF_PROMISC
root@test:~# cat /sys/class/net/eth2/flags 
0x1003

分析驱动代码

一度怀疑是驱动代码逻辑写死IFF_PROMISC不允许修改,随即就推翻了。因为eth2接口是相同的驱动,但IFF_PROMISC标志可以随意设置清除。
稳妥起见还是查阅了驱动代码,没有发现特殊逻辑。

虚拟vlan配置

固件团队分析到后面发现了原因。问题的引入来自于之前一次新增vlan操作。
eth0新增了eth0.10虚拟vlan,配置的 mac地址和eth0不一样,eth1新增了eth0.20虚拟vlan,配置的mac地址和eth1的mac不一样。
eth0 mac地址是70:b3:d5:20:00:21,但eth0.10地址是70:b3:d5:21:64:00。
eth1 mac地址是70:b3:d5:20:ff:21,但eth1.20地址是70:b3:d5:21:c8:01。

root@test:~# ifconfig eth0
eth0: flags=4419<UP,BROADCAST,RUNNING,MULTICAST>  mtu 8966
        inet 10.84.10.42  netmask 255.255.255.0  broadcast 10.42.10.255
        inet6 fe80::72b3:d5ff:fe20:21  prefixlen 64  scopeid 0x20<link>
        ether 70:b3:d5:20:00:21  txqueuelen 1000  (Ethernet)
        RX packets 224529948  bytes 178857830781 (178.8 GB)
        RX errors 0  dropped 3  overruns 0  frame 0
        TX packets 305526669  bytes 131688196359 (131.6 GB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

root@test:~# ifconfig eth0.100
eth0.10: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 8966
        inet 192.168.10.42  netmask 255.255.255.0  broadcast 192.168.100.255
        inet6 fe80::72b3:d5ff:fe21:6400  prefixlen 64  scopeid 0x20<link>
        ether 70:b3:d5:21:64:00  txqueuelen 1000  (Ethernet)
        RX packets 16276987  bytes 6107515472 (6.1 GB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 275497881  bytes 117600578758 (117.6 GB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

root@test:~# ifconfig eth1
eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1466
        inet 10.84.0.42  netmask 255.255.255.0  broadcast 10.42.0.255
        inet6 fe80::72b3:d5ff:fe20:ff21  prefixlen 64  scopeid 0x20<link>
        ether 70:b3:d5:20:ff:21  txqueuelen 1000  (Ethernet)
        RX packets 233679757  bytes 181307309357 (181.3 GB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 62101583  bytes 5165309302 (5.1 GB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

root@test:~# ifconfig eth1.200
eth1.20: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1466
        inet 192.168.20.42  netmask 255.255.255.0  broadcast 192.168.200.255
        inet6 fe80::72b3:d5ff:fe21:c801  prefixlen 64  scopeid 0x20<link>
        ether 70:b3:d5:21:c8:01  txqueuelen 1000  (Ethernet)
        RX packets 3808158  bytes 517024458 (517.0 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 3828411  bytes 578738870 (578.7 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

由于eth0.10 的报文 要通过真实物理网口 eth0接收,而eth0的mac地址和eth0.10mac地址不同。为了能够接收发向eth0.10mac地址的报文。eth0需要设置成 IFF_PROMISC 模式。

检查多mac地址的代码逻辑在__dev_set_rx_mode中。
当dev->priv_flags没有设置 IFF_UNICAST_FLT时,会设置IFF_PROMISC标志。
在这里插入图片描述

至此,eth0和eth1为何IFF_PROMISC标志位设置的原因也找到了。

修改配置并验证

修改eth0.10 mac地址

手动修改eth0.10 mac地址,使其与eth0一致后。可以看到eth0的flags中 不再包含IFF_PROMISC标志。

root@test:~# cat /sys/class/net/eth0/flags 
0x1003
root@test:~# ifconfig eth0.10 down
root@test:~# ifconfig eth0.10 hw ether 70:b3:d5:20:00:21
root@test:~# ifconfig eth0.10 up
root@test:~# cat /sys/class/net/eth0/flags 
0x1003

验证组播

使用test程序验证,发现不再有丢帧问题。

root@test:~# ./test 239.0.0.15 1067 10.84.0.42
UDP Server 239.0.0.15: 1067
recv from: 10.84.0.73:1067  805583  c4acf
recv from: 10.84.0.73:1067  805584  c4ad0
recv from: 10.84.0.73:1067  805585  c4ad1
recv from: 10.84.0.73:1067  805586  c4ad2
recv from: 10.84.0.73:1067  805587  c4ad3
recv from: 10.84.0.73:1067  805588  c4ad4
recv from: 10.84.0.73:1067  805589  c4ad5
recv from: 10.84.0.73:1067  805590  c4ad6
recv from: 10.84.0.73:1067  805591  c4ad7
recv from: 10.84.0.73:1067  805592  c4ad8
recv from: 10.84.0.73:1067  805593  c4ad9
recv from: 10.84.0.73:1067  805594  c4ada
recv from: 10.84.0.73:1067  805595  c4adb
recv from: 10.84.0.73:1067  805596  c4adc
recv from: 10.84.0.73:1067  805597  c4add

验证通过。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浮沉飘摇

码字不易,打赏随意。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值