admin管理员组

文章数量:1642238

项目采用的是3.10.108的kernel,在测试时使用发包功率高速发送DHCP Request报文,发现busybox中的udhcpd 进程状态为D,抓包看,没有offer包,而且样机ping不通。

分析发现是在kernel中的函数udp_queue_rcv_skb中:
if (sk_rcvqueues_full(sk, skb, sk->sk_rcvbuf))
{
//printk(“%s %d goto drop; \r\n”, FUNCTION, LINE);
goto drop;
}
丢包;

打印调试代码后发现:
[16:52:24] : __udp4_lib_mcast_deliver 1641 do flush_stack
[16:52:24] : sock_queue_rcv_skb 483 call sk->sk_data_ready
[16:52:24] :
[16:52:24] : __udp4_lib_mcast_deliver 1641 do flush_stack
[16:52:24] : udp_queue_rcv_skb 1538 goto drop;
[16:52:24] :
[16:52:24] : __udp4_lib_mcast_deliver 1641 do flush_stack
[16:52:24] : udp_queue_rcv_skb 1538 goto drop;
[16:52:24] :
[16:52:24] : __udp4_lib_mcast_deliver 1641 do flush_stack
[16:52:24] : sock_queue_rcv_skb 483 call sk->sk_data_ready
[16:52:24] :
[16:52:24] : __udp4_lib_mcast_deliver 1641 do flush_stack
[16:52:24] : udp_queue_rcv_skb 1538 goto drop;
[16:52:24] :
[16:52:24] : __udp4_lib_mcast_deliver 1641 do flush_stack
[16:52:24] : udp_queue_rcv_skb 1538 goto drop;
[16:52:24] :
[16:52:24] : __udp4_lib_mcast_deliver 1641 do flush_stack
[16:52:24] : sock_queue_rcv_skb 483 call sk->sk_data_ready
[16:52:24] :
[16:52:24] : __udp4_lib_mcast_deliver 1641 do flush_stack
[16:52:24] : udp_queue_rcv_skb 1538 goto drop;
[16:52:24] :
[16:52:24] : __udp4_lib_mcast_deliver 1641 do flush_stack
[16:52:24] : udp_queue_rcv_skb 1538 goto drop;
[16:52:24] :
[16:52:24] : __udp4_lib_mcast_deliver 1641 do flush_stack
[16:52:24] : sock_queue_rcv_skb 483 call sk->sk_data_ready
[16:52:24] :
[16:52:24] : __udp4_lib_mcast_deliver 1641 do flush_stack
[16:52:24] : udp_queue_rcv_skb 1538 goto drop;
[16:52:24] :
[16:52:24] : __udp4_lib_mcast_deliver 1641 do flush_stack
[16:52:24] : sock_queue_rcv_skb 483 call sk->sk_data_ready
[16:52:24] :
[16:52:24] : __udp4_lib_mcast_deliver 1641 do flush_stack
[16:52:24] : udp_queue_rcv_skb 1538 goto drop;
[16:52:24] :
[16:52:24] : __udp4_lib_mcast_deliver 1641 do flush_stack
[16:52:24] : udp_queue_rcv_skb 1538 goto drop;
[16:52:29] : udhcpd_main 501 : select retval = 1

udp协议栈中多次接收到包,并且把包放入sk->sk_receive_queue队列,但是上层的应用程序select却检测到一次socket可读并收包,这样导致队列满而数据包被丢弃。
问题原因找到,在busybox中汇报调用了
fd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));导致进程处于D状态。包没有发出去,导致IP地址续约失败。

本文标签: 报文速率Linuxudp