首页 > 系统 > Linux > 正文

Linux IP in IP隧道简述

2024-08-28 00:23:09
字体:
来源:转载
供稿:网友

前言:IPIP隧道是一种三层隧道,通过把原来的IP包封装在新的IP包里面,来创建隧道传输。本篇简单分析Linux(2.6.32版本)中的IPIP隧道的实现过程,期望有所借鉴,造出轮子:-)

一. IPIP的初始化

Linux中的IPIP隧道文件主要分布在tunnel4.cipip.c文件中。因为是三层隧道,在IP报文中填充的三层协议自然就不能是常见的TCP和UDP,所以,Linux抽象了一个隧道层,位置就相当于传输层,主要的实现就是在tunnel4.c中。来看看他们的初始化:

抽象的隧道层和IPIP模块都是以注册模块的方式进行初始化

module_init(tunnel4_init);module_init(ipip_init);

首先看隧道层的初始化,主要的工作就是注册隧道协议和对应的处理函数:

static int __init tunnel4_init(void){    if (inet_add_protocol(&tunnel4_protocol, IPPROTO_IPIP)) {        printk(KERN_ERR "tunnel4 init: can't add protocol/n");        return -EAGAIN;    }#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)    if (inet_add_protocol(&tunnel64_protocol, IPPROTO_IPV6)) {        printk(KERN_ERR "tunnel64 init: can't add protocol/n");        inet_del_protocol(&tunnel4_protocol, IPPROTO_IPIP);        return -EAGAIN;    }#endif    return 0;}

inet_add_protocol(&tunnel4_protocol, IPPROTO_IPIP)把IPIP隧道协议注册进inet_protos全局数组中,而inet_protos中的其他协议注册是在inet_init()中:

    if (inet_add_protocol(&icmp_protocol, IPPROTO_ICMP) < 0)        printk(KERN_CRIT "inet_init: Cannot add ICMP protocol/n");    if (inet_add_protocol(&udp_protocol, IPPROTO_UDP) < 0)        printk(KERN_CRIT "inet_init: Cannot add UDP protocol/n");    if (inet_add_protocol(&tcp_protocol, IPPROTO_TCP) < 0)        printk(KERN_CRIT "inet_init: Cannot add TCP protocol/n");#ifdef CONFIG_IP_MULTICAST    if (inet_add_protocol(&igmp_protocol, IPPROTO_IGMP) < 0)        printk(KERN_CRIT "inet_init: Cannot add IGMP protocol/n");#endif

看一下隧道层的处理函数:

static const struct net_protocol tunnel4_protocol = {    .handler    =   tunnel4_rcv,    .err_handler    =   tunnel4_err,    .no_policy  =   1,    .netns_ok   =   1,};

这样注册完后,当接收到三层类型是IPPROTO_IPIP时,就会调用tunnel4_rcv进行下一步的处理。可以说在隧道层对隧道协议进行的注册,保证能够识别接收到隧道包。而对隧道包的处理则是在IPIP中完成的。

for (handler = tunnel4_handlers; handler; handler = handler->next)        if (!handler->handler(skb))            return 0;icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);

在隧道层的处理函数中进一步调用注册的不同隧道协议的处理函数,分别处理。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表