data path
data path
应用层
busybox/ping.c
ping_main()
common_ping_main()
ping()
create_icmp_socket() //
socket(AF_INET, SOCK_RAW, 1);
ping4()
sendping4()
sendping_tail()
xsendto()
sendto() // 系统调用
--------------------
内核
网络
net/socket.c __sys_sendto() // sendto() 在内核的系统调用服务程序为 __sys_sendto()
sock_sendmsg()
sock_sendmsg_nosec()
raw_sendmsg() // sock->ops->sendmsg,应用层使用 SOCK_RAW 创建 socket,故 sock->ops->sendmsg 指向 raw_sendmsg()
net/ipv4/ip_output.c ip_push_pending_frames()
ip_send_skb()
ip_local_out()
__ip_local_out() // 经过 NF 的 LOCAL_OUT 钩子点
dst_output()
ip_output() // skb_dst(skb)->output
ip_finish_output()
__ip_finish_output()
ip_finish_output2()
net/core/neighbour.c/h neigh_output()
neigh_resolve_output()
net/core/dev.c dev_queue_xmit()
__dev_queue_xmit()
dev_hard_start_xmit()
xmit_one()
include/linux/netdevice.h netdev_start_xmit()
__netdev_start_xmit()
ops->ndo_start_xmit(skb, dev); // 送入驱动
驱动
drivers/net/usb/lan78xx.c lan78xx_start_xmit() // .ndo_start_xmit = lan78xx_start_xmit
skb_queue_tail() // 插入队列
tasklet_schedule(&dev->bh); // 触发任务调度 lan78xx_bh
lan78xx_bh()
lan78xx_tx_bh()
skb_dequeue() // 取出数据
usb_fill_bulk_urb() // 填充数据到 USB
drivers/usb/core usb_submit_urb() // USB 发送数据
--------------------
硬件