Linux源码笔记-网络栈-发送流程
(1)socket层的发送
tcp_v4_send_ack
ip_send_unicast_reply
ip_route_output_key
ip_route_output_flow
ip_push_pending_frames
ip_send_skb
//////////////////////////////////////
udp_sendmsg
_ip_route_output_key
ip_route_output_flow
fib_lookup
udp_send_skb
ip_send_skb
//////////////////////////////////////
raw_sendmsg
ip_route_output_key
ip_route_output_flow
raw_send_hdrinc
dst_output
dst_output_sk
(2)确认下一跳路由
ip_queue_xmit
ip_route_output_ports
_ip_route_output_key
ip_route_output_flow
ip_local_out
ip_local_out_sk
dst_output_sk
/////////////////////////////////////////////////////////////
ip_route_output_flow
__ip_route_output_key
fib_lookup
__mkroute_output
rt_set_nexthop
(3)IP层的发送
ip_send_skb
ip_local_out
ip_local_out_sk
dst_output_sk
rtable->dst->output
ip_output
ip_finish_output
//邻居逻辑
ip_finish_output2
__neigh_create
neigh_table->constructor
arp_constructor
dst_neigh_output
//(A) 已经有arp邻居表项,直接发送
neigh_hh_output
dev_queue_xmit
//(B) 暂时没有arp邻居表现,先完成arp解析
neighbour->output
neighbour->ops->connected_output
neighbour->ops->output
neigh_resolve_output
// 周期性发送arp请求
neigh_event_send
__neigh_event_send
neigh_add_timer // neigh_timer_handler
neigh_probe
neighbour->ops->solicit
arp_solicit
arp_send
arp_xmit
dev_queue_xmit
dev_queue_xmit
(4)驱动层的直接发送
dev_queue_xmit
__dev_queue_xmit
//选择一个输出队列,将该数据包插入发送队列中。
netdev_pick_tx
// 如果存在 Qdisc->enqueue, 那么使用拥塞发送队列
_dev_xmit_skb
sch_direct_xmit
_qdisc_run
//(A) 本次被调度
qdisc_restart
sch_direct_xmit
dev_hard_start_xmit
xmit_one
netdev_start_xmit
net_device->netdev_ops->ndo_start_xmit
例如 ixgb_xmit_frame
例如 e1000_xmit_frame
例如 dm9000_start_xmit
//(B)如果待发的数据太多。一次没有发完,等下次再调度发送
_netif_schedule
netif_schedule_queue
_netif_schedule
_netif_reschedule
NET_TX_SOFTIRQ
//////////////////////////////////////
(4)驱动层的第二轮发送(上次遗留数据)
net_tx_action
qdisc_run
qdisc_restart
sch_direct_xmit
dev_hard_start_xmit
xmit_one
netdev_start_xmit
__netdev_start_xmit
net_device_ops->ndo_start_xmit
ethoc_start_xmit
ixgb_xmit_frame
dm9000_start_xmit
浙公网安备 33010602011771号