ip_route_output_slow() ip_route_input()与linux的tunnel技术实现 ipip_tunnel_lookup

2024-04-30 14:08

本文主要是介绍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包:
ip_rcv
  -> 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:
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
 
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 )
              -> 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:
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_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


有段日子没写了,今天继续,想了一下,觉得先温习一下tunnel技术。

(一)tunnel即隧道,被用于在公网内传输私网数据,也就是VPN。实现类似于我们学习的数据结构中的栈,把数据报文封装在新的报文中,通过第三方协议(比如IP协议)传输到对端,对端进行解封,重新路由。

linux内核支持IPIP/GRE隧道协议(不考虑IPV6) tunnel4.c是一个框架程序,相当于容器,ipip是他肚子里的实体。觉得没有必要这么写,因为ip_gre.c的实现就不是这样的。

IPIP是最简单的实现隧道功能的协议,只支持承载IP报文,所以在应用上也就有了局限性,比如无法实现ARP代理,但对于分析设计思路还是非常好的,简单的东西往往更具有代表性,复杂的东西简单化么,我不是博士,所以没有能力把这么简单的东西说的谁也看不懂。

(二)在ipip中,首先要理解的是初始化过程

static int __init ipip_init(void)
{
    int err;

    printk(banner);
    //在框架程序里添加接收处理函数
    if (xfrm4_tunnel_register(&ipip_handler, AF_INET)) {
        printk(KERN_INFO "ipip init: can't register tunnel\n");
        return -EAGAIN;
    }
   //创建虚拟接口,这个很重要,在配置好tunnel后,如果发送的目的地址是私网的IP,路由系统就会把报文发送给这个虚拟接口,这样私网报文就通过ipip_tunnel_xmit函数被封装起来了,通过路由系统重新路由,找到公网IP对应的物理接口,把报文通过这个真是的物理接口发送给对端网关,也就是隧道的另一端。
    ipip_fb_tunnel_dev = alloc_netdev(sizeof(struct ip_tunnel),
                     "tunl0",
                     ipip_tunnel_setup);
    if (!ipip_fb_tunnel_dev) {
        err = -ENOMEM;
        

这篇关于ip_route_output_slow() ip_route_input()与linux的tunnel技术实现 ipip_tunnel_lookup的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/949076

相关文章

linux-基础知识3

打包和压缩 zip 安装zip软件包 yum -y install zip unzip 压缩打包命令: zip -q -r -d -u 压缩包文件名 目录和文件名列表 -q:不显示命令执行过程-r:递归处理,打包各级子目录和文件-u:把文件增加/替换到压缩包中-d:从压缩包中删除指定的文件 解压:unzip 压缩包名 打包文件 把压缩包从服务器下载到本地 把压缩包上传到服务器(zip

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

【专题】2024飞行汽车技术全景报告合集PDF分享(附原数据表)

原文链接: https://tecdat.cn/?p=37628 6月16日,小鹏汇天旅航者X2在北京大兴国际机场临空经济区完成首飞,这也是小鹏汇天的产品在京津冀地区进行的首次飞行。小鹏汇天方面还表示,公司准备量产,并计划今年四季度开启预售小鹏汇天分体式飞行汽车,探索分体式飞行汽车城际通勤。阅读原文,获取专题报告合集全文,解锁文末271份飞行汽车相关行业研究报告。 据悉,业内人士对飞行汽车行业

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo