我有一个正在运行原始IP套接字的应用程序,此套接字的目标由通过“ip route add”命令安装的路由控制。 这些路由可以在套接字的生命周期中改变(例如,因为下一跳改变)
简化,可以说我有2个接口, eth0和eth1 。 我也有一个通过eth0的默认路由。
原始套接字的端点是例如10.10.10.10 ,eth1的地址是100.0.0.1 ,我在原始套接字的生命期内执行以下操作:
ip -f inet route delete 10.10.10.10 ip -f inet route add 100.0.0.2 dev eth1 ip -f inet route add 10.10.10.10/32 via 100.0.0.2 dev eth1
现在我所看到的是,在这个操作之后,stream量通过eth1正确地传送了几秒钟,然后在短时间内(通过eth0)出错了(不到半秒),然后再次正确(就我所能看到的永久)。
所以我的主要问题是:有没有人可以解释一下这里可能会出错? 我之前提到的序列之后尝试添加ip route flush cache ,但没有做任何事情。 我目前困惑,为什么交通有时会下降。 我认为这可能是路由命令中的计时问题,或者其他一些触发器在一秒钟内禁用路由,但是我的选项已经不多了。
我尝试在我的原始套接字上使用SO_BINDTODEVICE选项,但是这并没有什么帮助,主要的区别是,当stream量出错时,根本不会发送出去,因为它会覆盖错误的接口。 不过,我所希望的是,这将设置errno类似E_CANNOTROUTE(这不存在),所以我可以抓住这个,然后重试发送数据包。 它目前不这样做,但有没有办法,我可以赶上这样的失败? 我(几乎)完全控制系统和运行套接字的应用程序。
我所知道的一个解决scheme将是不使用L3原始套接字,而是使用AF_PACKET套接字(也可以自己做ARP / ND),但我宁愿不要进入。
通过改变这个路由改变行为,我改善了我的系统的行为。 当我必须更新下一跳时,我现在查看已经安装的路由并采取以下操作:
虽然这稳定了我的大部分问题,但是当实际删除+添加(新机制中的最后一种情况)发生时,我仍然有时会看到同样的情况发生(尽pipeless得多)。 而且,这实际上仍然不能解释发生了什么问题(只是绕过了它),所以我现在就把这个问题留下来,因为我真的很好奇这里出了什么问题。
仅供参考:就centos4而言,我有这个问题,从32位的centos4到centos6。
如果我理解正确,数据包应该总是出去eth1,你的问题是,当在eth1上更新到一个新的下一跳时,你的数据包有时会出去eth0? 那将是因为你的delete + add不是一个primefaces操作。
先尝试添加,然后删除。 删除必须具体(与我相信的设备和下一步),以便它不会也删除您刚刚添加的新路线。