当前位置:
文档之家› Linux协议栈实现分析完整版
Linux协议栈实现分析完整版
udp_queue_rcv_skb()
icmp_pointers->handler()
raw_rcv_skb()
udp_rcv()
icmp_rcv()
raw_rcv()
ipprot->handler() NF_HOOK(PF_INET, NF_IP_LOCAL_OUT) tcp、udp
raw_v4_input() raw ip_local_deliver_finish()
dst_output() skb->dst->output()
ip_forward_finish() NF_HOOK(PF_INET, NF_IP_FORWARD)
raw_rcv() ip_call_ra_chain()
NF_HOOK(PF_INET, NF_IP_LOCAL_IN) ip_defrag() ip_local_deliver()
NF_HOOK(PF_INET, NF_IP_PRE_ROUTING)
packet_type->func()(ip_rcv、arp_rcv) dev->hard_start_xmit() 驱动层 如驱动中的e1000_xmit_frame() OUTPUT handle_bridge() 桥模式 netif_receive_skb()
c:1622行,调用dev->poll(dev, &budget)
Net_rx_action
如果定义 POST_
q.c:90行,产生软中断,通过全局变量 q_vec的函数指针调用net_rx_action
2847行,函数net_dev_init中,将 _action函数指针传给softirq_vec.action, oftirq中通过h->action调用net_rx_action
tcp_v4_rcv()
udp_rcv()
write调用
write() sys_write() sock_writev() sock_readv_writev()
send调用
send() sys_send()
sendto调用
sendto() Sock层
sys_sendto()
sock_sendmsg() sock->ops->sendmsg() inet_stream_ops->sendmsg() inet_dgram_ops->sendmsg() inet_sendmsg() sk->sk_prot->sendmsg() tcp_prot->sendmsg() tcp_sendmsg() skb_entail() 填充发送队列 udp_prot->sendmsg() udp_sendmsg() inet_sockraw_ops->sendmsg()
ESTABLISHE D
^-tcp_output.c:1332行,tcp_transmit_skb tcp_output.c:278行,ip_queue_xmit | |如果定义了NETFILTER,先进入LOCAL_OUT | ip_output.c:401行:ip_queue_xmit2 ip_output.c:317行;skb->dst->output(skb); (在route.c的ip_route_*put*函数中进 dst->output函数指针付值=ip_output或 ip_mc_output或ip_rt_bug) case TCP_SYN_RECV(收到ACK)(Server端) 如果ouput tcp_set_state 能会到 tcp_data_snd_check (tcp_input.c:4030) tcp_ack_snd_check (tcp_input.c:4031) LISTEN
udp_rcv
ipprot->protocol = UDP
ip_local_deliver_finish
如果定义了NETFILTER,则先进入LOCAL_IN 转发 数据 包
t
tcp raw_v4_input ip_local_deliver
数据包发往本地 检查ip数据包的内容
Ip_forward
Tcp_output.c:278
Linux协议栈实现分析
功能模块、函数流程
Linux协议栈概括图
应用层 Socket操作函数集
inet_stream_ops INET层 tcp_prot
inet_dgram_ops
inet_sockraw_ops
udp_prot
raw_prot
传输层
网络层
sk->sk_receive_queue sk->sk_write_queue
__skb_queue_tail() tcp_rcv_established() skb_queue_tail(&sk->sk_receive_queue, skb) sock_queue_rcv_skb()
tcp_v4_do_rcv() ip_queue_xmit() raw_send_hdrinc() ip_route_output_flow() ip_push_pending_frames() tcp_v4_rcv()
Socket()
bind()
recvfrom()
请求数据
sendto()
sendto()
应答数据
recvfrom()
close()
close()
面向无连接的 Socket工作流程
socket调用
socket()
bind调用
bind()
listen调用
listen()
accept调用
accept()
sock_map_fd()
selinux_socket_bind()
inet_listen()
sock->ops->accept()
sock->ops->bind()
sockfd_put()
inet_accept()
inet_bind()
security_socket_post_accept()
type=SOCK_RAW
物理层
网络设备
INPUT
, 调用 sg
tcp_replace_ts_recent tcp_sequence tcp_paws_discard
!LISTEN && !ESTABLISHED
4, 函数中,将 i_fop指向 s结构。 d函数
tcp_rcv_state_proces s
tcp_fast_parse_options tcp_rcv_established
inet_bind()
sockfd_put()
close调用
close()
connect调用
connect()
sys_close()
sys_connect()
filp_close()
sk->sk_prot->connect()
fput()
tcp_v4_connect()
file->op->release()
如果定义了NETFILTER,则先进入 IP_FORWARD
Iq
lter
ip_options_compile ip_forward_finish ip_route_input_slow 在缓存中找到
ip_output.c:367
ip
进行路由,并把skb->dst->input函数 指针指向ip_local_deliver或ip_error 或ip_forward或ip Route.c:1658-1675行,在路由时 会先在路由缓存中查找,没找到则 由ip_route_input_slow函数从路 由表中查,并加入到缓存中
wk.baidu.com
ip_route_input_slow() 单播
ip_route_input_mc() 多播 路由处理
ip_route_input() hh->hh_output() dst->neighbour->output() neigh_compat_output() dev_queue_xmit() ip_rcv_finish()
__skb_queue_tail
tcp_v4_do_rcv
将数据包放入队列的尾部 sk->receive_queue 并调用sk->data_ready通知上层数据 到达
在这之间做了tcp checksum校验等
tcp_v4_rcv
ipprot->protocol = TCP
Protocol.c:56行开始,初始化全局数组 inet_protos, 在ip_input.c:262行查找到相应的接收函数 (tcp、udp、icmp、igmp)
ip_mc_output() 分片 ip_fragment() ip_finish_output() 分片
ip_output()
ip_forward() forward
local_in skb->dst->input() dst_input()
NF_HOOK(PF_INET, NF_IP_POST_ROUTING) ip_finish_output2()
ip_route_connect()
sock_close()
tcp_connect()
sock->ops->release()
tcp_transmit_skb()
tcp_close()、udp_close()
read调用
read() sys_read() sock_readv() sock_readv_writev()
sys_socketcall()
sys_socketcall()
sys_socketcall()
sys_socketcall()
sys_socket()
sys_bind()
sys_listen()
sys_accept()
sock_create()
sockfd_lookup()
sockfd_lookup()
ip_forward_options
ip_output.c:397
ip_
ip_route_input
ip_send
如果定义了NETF LOCAL_OUT
ip_rcv_finish
如果定义了NETFILTER,则先进入 PRE_ROUTING
ip
ip_fragment ip_rcv
如果产生了分片 即skb->len > rt->u.dst.pmtu 并将ip_output函数指针做为参数 给ip_fragment
sockfd_lookup()
__sock_create()
security_socket_bind()
security_socket_listen()
sock_alloc()
sock_alloc()
security_ops->socket_bind()
sock->ops->listen()
security_socket_accept()
recv调用
recv() sys_recv()
recvfrom调用
recvfrom() Sock层
sys_recvfrom()
sock_recvmsg() sock->ops->recvmsg() inet_stream_ops->recvmsg() inet_dgram_ops->recvmsg() sock_common_recvmsg() sk->sk_prot->recvmsg() tcp_prot->recvmsg() tcp_recvmsg() udp_prot->recvmsg() udp_recvmsg() skb_recv_datagram() NOT NULL 读取 skb_dequeue() 读取 inet_sockraw_ops->recvmsg()
INET Sock层
raw_prot->recvmsg() raw_recvmsg()
sk->receive_quene NULL sk->sk_backlog_rcv()
sk->sk_receive_queue
填充 tcp_v4_do_rcv() tcp_rcv_established()
填充 sock_queue_rcv_skb() IP 层 raw_rcv()
do_softirq
2751行,同时将queue->blog_dev.poll指向 s_backlog函数
ksoftirqd
内核线程,进程调度 将从网卡驱动接收到的 sk_buff放到内核接收队列中 通过__skb_queue_tail函数实 现
netif_rx
网络数据交互模型
服务器
Socket()
Dev.c:1489行,调用ip_rcv函数 在ip_output.c:1001行初始化了 ip_packet_type,使它的成员func指向 ip_rcv函数 Dev.c:1553行,通过__skb_dequeue 函数取得sk_buff,
netif_receive_skb
Process_backlog
客户端
bind() Socket()
listen()
accept()
建立连接
connet()
read() recv()
请求数据
write() send()
write() send()
应答数据
read() recv()
close()
close()
面向连接的 Socket工作流程
服务器
Socket()
客户端