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中压缩、网络传输与系统监控工具的使用完整指南

《Linux中压缩、网络传输与系统监控工具的使用完整指南》在Linux系统管理中,压缩与传输工具是数据备份和远程协作的桥梁,而系统监控工具则是保障服务器稳定运行的眼睛,下面小编就来和大家详细介绍一下它... 目录引言一、压缩与解压:数据存储与传输的优化核心1. zip/unzip:通用压缩格式的便捷操作2.

Python实现对阿里云OSS对象存储的操作详解

《Python实现对阿里云OSS对象存储的操作详解》这篇文章主要为大家详细介绍了Python实现对阿里云OSS对象存储的操作相关知识,包括连接,上传,下载,列举等功能,感兴趣的小伙伴可以了解下... 目录一、直接使用代码二、详细使用1. 环境准备2. 初始化配置3. bucket配置创建4. 文件上传到os

关于集合与数组转换实现方法

《关于集合与数组转换实现方法》:本文主要介绍关于集合与数组转换实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、Arrays.asList()1.1、方法作用1.2、内部实现1.3、修改元素的影响1.4、注意事项2、list.toArray()2.1、方

使用Python实现可恢复式多线程下载器

《使用Python实现可恢复式多线程下载器》在数字时代,大文件下载已成为日常操作,本文将手把手教你用Python打造专业级下载器,实现断点续传,多线程加速,速度限制等功能,感兴趣的小伙伴可以了解下... 目录一、智能续传:从崩溃边缘抢救进度二、多线程加速:榨干网络带宽三、速度控制:做网络的好邻居四、终端交互

java实现docker镜像上传到harbor仓库的方式

《java实现docker镜像上传到harbor仓库的方式》:本文主要介绍java实现docker镜像上传到harbor仓库的方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录1. 前 言2. 编写工具类2.1 引入依赖包2.2 使用当前服务器的docker环境推送镜像2.2

C++20管道运算符的实现示例

《C++20管道运算符的实现示例》本文简要介绍C++20管道运算符的使用与实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录标准库的管道运算符使用自己实现类似的管道运算符我们不打算介绍太多,因为它实际属于c++20最为重要的

Java easyExcel实现导入多sheet的Excel

《JavaeasyExcel实现导入多sheet的Excel》这篇文章主要为大家详细介绍了如何使用JavaeasyExcel实现导入多sheet的Excel,文中的示例代码讲解详细,感兴趣的小伙伴可... 目录1.官网2.Excel样式3.代码1.官网easyExcel官网2.Excel样式3.代码

Linux中SSH服务配置的全面指南

《Linux中SSH服务配置的全面指南》作为网络安全工程师,SSH(SecureShell)服务的安全配置是我们日常工作中不可忽视的重要环节,本文将从基础配置到高级安全加固,全面解析SSH服务的各项参... 目录概述基础配置详解端口与监听设置主机密钥配置认证机制强化禁用密码认证禁止root直接登录实现双因素

python实现对数据公钥加密与私钥解密

《python实现对数据公钥加密与私钥解密》这篇文章主要为大家详细介绍了如何使用python实现对数据公钥加密与私钥解密,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录公钥私钥的生成使用公钥加密使用私钥解密公钥私钥的生成这一部分,使用python生成公钥与私钥,然后保存在两个文

浏览器插件cursor实现自动注册、续杯的详细过程

《浏览器插件cursor实现自动注册、续杯的详细过程》Cursor简易注册助手脚本通过自动化邮箱填写和验证码获取流程,大大简化了Cursor的注册过程,它不仅提高了注册效率,还通过友好的用户界面和详细... 目录前言功能概述使用方法安装脚本使用流程邮箱输入页面验证码页面实战演示技术实现核心功能实现1. 随机