在发送ipv6 udp单播报文时,发包失败,sendto接口一直报-1,发包失败。经过排查socket状态
、ipv6 nd和路由状态也都正常,只好进入内核查看错误原因由此总结了ipv6 udp sendto
(发包->查找出接口(路由))流程。
Linux版本4.1.15
1、问题分析:
经过跟踪排查,发现在rt6_selete函数中的find_rr_leaf函数中无法找到合适的出接口导致报错
在find_match中,会使用rt6_score_route->rt6_check_dev流程对oif和rt_info路由信息进行对比
这时对比能正常找到路由的v6 ping流程,发现oif值存在问题(不为空),有一个奇怪的值。
`oif` 参数表示发送数据包的出口网络接口(即出接口)。它指定了数据包从哪个网络接口发送。这个参数实际上是在IPv6协议栈传输数据时根据用户传递的参数在不同的函数之间进行传递的。对于当前流程来说,oif字段来源于udpv6_sendmsg函数中初始化的f16.flowi6_oif,而这个值来源于sendto接口中传入的sin6_scope_id。最终问题发现了,sockaddr_in6结构体没有正确初始化,scope_id存在非0值。
这时我们还是要回头来看一下这个sin6_scope_id到底是什么东西。在其他博主的blog中发现了
解释
“这个字段在我们使用链路本地地址来编程的时候是必须要使用的,这个字段表示我们需要选择接口ID。为什么需要需要有这么一个字段,那是因为链路本地地址的特殊性,一个网络节点可以有多个网络接口,多个网络接口可以有相同的链路本地地址,例如我们需要bi