本文主要是介绍ip_route_output_slow() ip_route_input()与linux的tunnel技术实现 ipip_tunnel_lookup,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Linux-2.6.21.1 网络函数调用流程
接收以太帧:netif_rx
-> queue
-> netif_receive_skb
-> bond
-> packet_type_all: deliver_skb
-> bridge
-> packet_type(IPV4)->func == ip_rcv
接收IPv4包:
-> NF_HOOK(PREROUTING)
->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_input
-> 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)
-> 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)
-> ip_forward_finish
-> dst_output
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
-> ip_route_connect
-> ip_route_output_flow
tcp_sendmsg
-> __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
-> __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
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
-> dst_output
-> dst->output
-> 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
有段日子没写了,今天继续,想了一下,觉得先温习一下tunnel技术。
(一)tunnel即隧道,被用于在公网内传输私网数据,也就是VPN。实现类似于我们学习的数据结构中的栈,把数据报文封装在新的报文中,通过第三方协议(比如IP协议)传输到对端,对端进行解封,重新路由。
linux内核支持IPIP/GRE隧道协议(不考虑IPV6) tunnel4.c是一个框架程序,相当于容器,ipip是他肚子里的实体。觉得没有必要这么写,因为ip_gre.c的实现就不是这样的。
IPIP是最简单的实现隧道功能的协议,只支持承载IP报文,所以在应用上也就有了局限性,比如无法实现ARP代理,但对于分析设计思路还是非常好的,简单的东西往往更具有代表性,复杂的东西简单化么,我不是博士,所以没有能力把这么简单的东西说的谁也看不懂。
(二)在ipip中,首先要理解的是初始化过程
|
这篇关于ip_route_output_slow() ip_route_input()与linux的tunnel技术实现 ipip_tunnel_lookup的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!