java 单机接口限流处理方案
1016
2022-10-11
Linux内核网络收包过程函数调用分析(linux内核收发包流程)
Linux内核网络收包过程函数调用分析
数据帧首先到达网卡的接收队列,分配RingBuffer DMA把数据搬运到网卡关联的内存 网卡向CPU发起硬中断,通知CPU有数据 调用驱动注册的硬中断处理函数 启动NAPI,触发软中断
本文以Intel igb网卡驱动为例说明收包过程:
网卡驱动注册硬中断处理函数
网卡驱动注册中断处理函数igb_msix_ring()。
igb_open() - drivers/net/ethernet/intel/igb/igb_main.c igb_request_irq - drivers/net/ethernet/intel/igb/igb_main.c igb_request_msix - drivers/net/ethernet/intel/igb/igb_main.c igb_msix_ring() - drivers/net/ethernet/intel/igb/igb_main.c
系统启动时注册软中断处理函数
NET_RX_SOFTIRQ的软中断处理函数为net_rx_action()。
subsys_initcall(net_dev_init) - net/core/dev.c net_dev_init() - net/core/dev.c open_softirq(NET_RX_SOFTIRQ, net_rx_action) - net/core/dev.c
系统启动时注册协议栈处理函数
在网络层,以IPv4为例,注册的协议处理函数为ip_rcv()。在传输层,根据协议注册其处理函数upd_rcv()、tcp_v4_rcv()、icmp_rcv()等。
fs_initcall(inet_init) - net/ipv4/af_inet.c inet_init() - net/ipv4/af_inet.c inet_add_protocol(&icmp_protocol, IPPROTO_ICMP) - net/ipv4/af_inet.c inet_add_protocol(&udp_protocol, IPPROTO_UDP) - net/ipv4/af_inet.c inet_add_protocol(&tcp_protocol, IPPROTO_TCP) - net/ipv4/af_inet.c dev_add_pack(&ip_packet_type) - net/ipv4/af_inet.c
硬中断处理函数
当有数据包到达网卡时,DMA把数据映射到内存,通知CPU硬中断,执行注册的硬中断处理函数igb_msix_ring(),简单处理后,发出软中断NET_RX_SOFTIRQ。
igb_msix_ring() - drivers/net/ethernet/intel/igb/igb_main.c __napi_schedule() - net/core/dev.c ____napi_schedule() - net/core/dev.c __raise_softirq_irqoff(NET_RX_SOFTIRQ) - net/core/dev.c
软中断处理函数
ksoftirqd为软中断处理进程,ksoftirqd收到NET_RX_SOFTIRQ软中断后,执行软中断处理函数net_rx_action(),调用网卡驱动poll()函数收包。最后通过调用注册的ip协议处理函数ip_rcv()将数据包送往协议栈。
run_ksoftirqd() - kernel/softirqd.c __do_softirq() - kernel/softirqd.c h->action(h) - kernel/softirqd.c net_rx_action() - net/core/dev.c napi_poll() - net/core/dev.c __napi_poll - net/core/dev.c work = n->poll(n, weight) - net/core/dev.c igb_poll() - drivers/net/ethernet/intel/igb/igb_main.c igb_clean_rx_irq() - drivers/net/ethernet/intel/igb/igb_main.c napi_gro_receive() - net/core/gro.c napi_skb_finish() - net/core/gro.c netif_receive_skb_list_internal() - net/core/dev.c __netif_receive_skb_list() - net/core/dev.c __netif_receive_skb_list_core - net/core/dev.c __netif_receive_skb_core - net/core/dev.c deliver_skb() - net/core/dev.c pt_prev->func(skb, skb->dev, pt_prev, orig_dev)
协议栈处理函数-L3
在软中断处理的最后,调用的pt_prev->func()函数即为协议栈注册ipv4处理函数ip_rcv()。网络层处理完成之后,根据传输协议执行注册的传输层处理函数tcp_v4_rcv或者udp_rcv()。
ip_rcv() - net/ipv4/ip_input.c ip_rcv_finish() - net/ipv4/ip_input.c dst_input() - include/net/dst.h ip_local_deliver() - net/ipv4/ip_input.c ip_local_deliver_finish() - net/ipv4/ip_input.c ip_protocol_deliver_rcu() - net/ipv4/ip_input.c ret = INDIRECT_CALL_2(ipprot->handler, tcp_v4_rcv, udp_rcv, skb)
协议栈处理函数-L4
这里以udp协议为例说明处理过程,tcp协议处理过程更复杂一些。最后将数据包添加到socket的接收队列。然后进入用户空间应用层面处理。
udp_rcv() - net/ipv4/udp.c udp_unicast_rcv_skb() - net/ipv4/udp.c udp_queue_rcv_skb() - net/ipv4/udp.c udp_queue_rcv_one_skb() - net/ipv4/udp.c __udp_queue_rcv_skb() - net/ipv4/udp.c __udp_enqueue_schedule_skb() - net/ipv4/udp.c __skb_queue_tail() - net/ipv4/udp.c
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~