转:Linux-2.6.21.1 网络函数调用流程 收藏
注:红色部分是我自己的补充说明。
转:Linux-2.6.21.1 网络函数调用流程
http://www.cublog.cn/u/12313/showart_312426.html
接收以太帧:
netif_rx
-> queue //管理队列
-> netif_receive_skb // 将帧的拷贝交给注册的协议函数处理、初始化skb->{h,nh,mac}
-> bond //多个接口绑定成一个
-> packet_type_all: deliver_skb
-> bridge //桥接
ip_forward
-> xfrm4_route_forward (net/xfrm.h, get xfrm_dst) //IPSec策略检验
-> xfrm_route_forward
-> __xfrm_route_forward
-> xfrm_lookup
-> xfrm_find_bundle
-> afinfo->find_bundle == __xfrm4_find_bundle
-> xfrm_bundle_create
-> afinfo->bundle_create == __xfrm4_bundle_create
tunnel mode //隧道模式
-> xfrm_dst_lookup
-> afinfo->dst_lookup == xfrm4_dst_lookup
-> __ip_route_output_key
-> dst_list: dst->list=policy_bundles, policy->bundles = dst
-> NF_HOOK(NF_FORWARD) //netfilter钩子
icmp_send
-> ip_route_output_key //查找目的地址的路由
-> ip_route_output_flow
-> icmp_push_reply
-> ip_append_data
-> skb_queue_walk
-> ip_push_appending_frames
tcp:
tcp_connect // tcp连接
-> ip_route_connect
-> ip_route_output_flow
tcp_sendmsg // tcp发送载荷数据
-> __tcp_push_appending_frames
-> tcp_write_xmit
-> tcp_transmit_skb
-> net_xmit_eval
-> icsk->icsk_af_ops->queue_xmit == ipv4_specific->queue_xmit == ip_queue_xmit
-> tcp_push_one
-> tcp_transmit_skb
-> net_xmit_eval
-> icsk->icsk_af_ops->queue_xmit == ipv4_specific->queue_xmit == ip_queue_xmit
//不知所云,前面是接收TCP的处理,到了后面又转成发送了??????????????
ip_push_pending_frames
-> __skb_dequeue(sk_write_queue)
-> NF_HOOK(NF_OUTPUT)
-> dst_output
ip_queue_xmit
-> ip_route_output_flow
-> xfrm_lookup
-> xfrm_find_bundle
-> bundle_create
-> afinfo->bundle_create == __xfrm4_bundle_create
-> xfrm_dst_lookup
-> afinfo->dst_lookup == xfrm4_dst_lookup
-> __ip_route_output_key
-> dst_list
-> dst->list=policy_bundles, policy->bundles = dst
转:Linux-2.6.21.1 网络函数调用流程
http://www.cublog.cn/u/12313/showart_312426.html
本文档的Copyleft归yfydz所有,使用GPL发布,可以自由拷贝,转载,转载时请保持文档的完整性,严禁用于任何商业用途。
msn: yfydz_no1@hotmail.com
来源:http://yfydz.cublog.cn
msn: yfydz_no1@hotmail.com
来源:http://yfydz.cublog.cn
接收以太帧:
netif_rx
-> queue //管理队列
-> netif_receive_skb // 将帧的拷贝交给注册的协议函数处理、初始化skb->{h,nh,mac}
-> bond //多个接口绑定成一个
-> packet_type_all: deliver_skb
-> bridge //桥接
-> packet_type(IPV4)->func == ip_rcv //交给IP分组处理函数
接收IPv4包:
接收IPv4包:
ip_rcv
-> NF_HOOK(PREROUTING) //netfilter钩子
->ip_rcv_finish //检查包的地址、校验和等
-> ip_route_input //路由缓存查找
-> ip_route_input_cached
-> ip_route_input_slow //路由表项查找
-> ip_mkroute_input
-> __mkroute_input
dst->input = ip_forward //数据包转发处理
dst->output = ip_output //dst->output是包发送的处理
-> dst_input //如果skb->dst有效
-> LOCAL_IN: dst->input == ip_local_deliver //本地处理
-> NF_HOOK(NF_INPUT)
-> ip_local_deliver_finish //处理分片等
-> ipprot->handler(tcp, udp, icmp ...)
-> NF_HOOK(PREROUTING) //netfilter钩子
->ip_rcv_finish //检查包的地址、校验和等
-> ip_route_input //路由缓存查找
-> ip_route_input_cached
-> ip_route_input_slow //路由表项查找
-> ip_mkroute_input
-> __mkroute_input
dst->input = ip_forward //数据包转发处理
dst->output = ip_output //dst->output是包发送的处理
-> dst_input //如果skb->dst有效
-> LOCAL_IN: dst->input == ip_local_deliver //本地处理
-> NF_HOOK(NF_INPUT)
-> ip_local_deliver_finish //处理分片等
-> ipprot->handler(tcp, udp, icmp ...)
-> FORWARD: dst->input == ip_forward //数据包转发处理
转发:
转发:
ip_forward
-> xfrm4_route_forward (net/xfrm.h, get xfrm_dst) //IPSec策略检验
-> xfrm_route_forward
-> __xfrm_route_forward
-> xfrm_lookup
-> xfrm_find_bundle
-> afinfo->find_bundle == __xfrm4_find_bundle
-> xfrm_bundle_create
-> afinfo->bundle_create == __xfrm4_bundle_create
tunnel mode //隧道模式
-> xfrm_dst_lookup
-> afinfo->dst_lookup == xfrm4_dst_lookup
-> __ip_route_output_key
-> dst_list: dst->list=policy_bundles, policy->bundles = dst
-> NF_HOOK(NF_FORWARD) //netfilter钩子
// 以上对分组进行各种检测,比如进出的设备、源路由选项、减TTL、 重新计算 校验和等。
-> ip_forward_finish
-> ip_forward_finish
-> ip_forward_options //处理IP选项其他部分(不包括路由警告、严格源路由)、重新计算校验和 。
-> dst_output
-> dst_output
-> dst->output (= ip_output)
输出:
icmp:
icmp_send
-> ip_route_output_key //查找目的地址的路由
-> ip_route_output_flow
-> icmp_push_reply
-> ip_append_data
-> skb_queue_walk
-> ip_push_appending_frames
tcp:
tcp_connect // tcp连接
-> ip_route_connect
-> ip_route_output_flow
tcp_sendmsg // tcp发送载荷数据
-> __tcp_push_appending_frames
-> tcp_write_xmit
-> tcp_transmit_skb
-> net_xmit_eval
-> icsk->icsk_af_ops->queue_xmit == ipv4_specific->queue_xmit == ip_queue_xmit
-> tcp_push_one
-> tcp_transmit_skb
-> net_xmit_eval
-> icsk->icsk_af_ops->queue_xmit == ipv4_specific->queue_xmit == ip_queue_xmit
//不知所云,前面是接收TCP的处理,到了后面又转成发送了??????????????
tcp_protocol->handler == tcp_v4_rcv
-> __inet_lookup
-> xfrm_policy_check
-> tcp_v4_do_rcv
-> tcp_rcv_state_process
-> icsk->icsk_af_ops->conn_request == tcp_v4_conn_request
-> tcp_v4_send_synack
-> ip_build_and_send_pkt
-> NF_HOOK( NF_OUTPUT ) //??????????????????????
-> __inet_lookup
-> xfrm_policy_check
-> tcp_v4_do_rcv
-> tcp_rcv_state_process
-> icsk->icsk_af_ops->conn_request == tcp_v4_conn_request
-> tcp_v4_send_synack
-> ip_build_and_send_pkt
-> NF_HOOK( NF_OUTPUT ) //??????????????????????
-> dst_output
udp:
udp_sendmsg
-> ip_route_output_flow
-> ip_append_data
-> __skb_queue_tail( sk_write_queue )
-> udp_push_pending_frames
-> ip_push_pending_frames
udp:
udp_sendmsg
-> ip_route_output_flow
-> ip_append_data
-> __skb_queue_tail( sk_write_queue )
-> udp_push_pending_frames
-> ip_push_pending_frames
raw:
raw_sendmsg
-> ip_route_output_flow
-> ip_append_data
-> __skb_queue_tail( sk_write_queue )
-> ip_push_pending_frames
raw_sendmsg
-> ip_route_output_flow
-> ip_append_data
-> __skb_queue_tail( sk_write_queue )
-> ip_push_pending_frames
ip_push_pending_frames
-> __skb_dequeue(sk_write_queue)
-> NF_HOOK(NF_OUTPUT)
-> dst_output
ip_queue_xmit
-> ip_route_output_flow
-> xfrm_lookup
-> xfrm_find_bundle
-> bundle_create
-> afinfo->bundle_create == __xfrm4_bundle_create
-> xfrm_dst_lookup
-> afinfo->dst_lookup == xfrm4_dst_lookup
-> __ip_route_output_key
-> dst_list
-> dst->list=policy_bundles, policy->bundles = dst
-> NF_HOOK(NF_OUTPUT)
-> dst_output
-> dst->output
-> dst_output
-> dst->output
dst_output: dst_list循环
-> dst->output == xfrm_dst->output == xfrm4_output == xfrm4_state_afinfo->output
-> NF_HOOK(POSTROUTING)
-> xfrm4_output_finish
-> gso ?
-> xfrm4_output_finish2
-> xfrm4_output_one
-> mode->output
-> type->output
-> skb->dst=dst_pop(skb->dst)
-> nf_hook(NF_OUTPUT)
-> !dst->xfrm
-> dst_output
-> nf_hook(POSTROUTING)
-> dst->output == ip_output
-> NF_HOOK(POSTROUTING)
-> ip_finish_output
-> ip_finish_output2
-> hh_output == dev_queue_xmit
-> dst->output == xfrm_dst->output == xfrm4_output == xfrm4_state_afinfo->output
-> NF_HOOK(POSTROUTING)
-> xfrm4_output_finish
-> gso ?
-> xfrm4_output_finish2
-> xfrm4_output_one
-> mode->output
-> type->output
-> skb->dst=dst_pop(skb->dst)
-> nf_hook(NF_OUTPUT)
-> !dst->xfrm
-> dst_output
-> nf_hook(POSTROUTING)
-> dst->output == ip_output
-> NF_HOOK(POSTROUTING)
-> ip_finish_output
-> ip_finish_output2
-> hh_output == dev_queue_xmit
c编程样本
ReplyDelete使用简单的计算代码对数字的平方根