[转]深入理解 GRE tunnel

我以前写过一篇介绍 tunnel 的文章,只是做了大体的介绍。里面多数 tunnel 是很容易理解的,因为它们多是一对一的,换句话说,是直接从一端到另一端。比如 IPv6 over IPv4 的 tunnel,也就是 SIT,它的原理如下图所示:

显然,除了端点的 host A 和 host B之外,中间经过的任何设备都是看不到里面的 IPv6 的头,对于它们来说,经过 sit 发出的包和其它的 IPv4 的包没有任何区别。

GRE tunnel 却不一样了,它的原理从根本上和 sit,ipip 这样的 tunnel 就不一样。除了外层的 IP 头和内层的 IP 头之间多了一个 GRE 头之外,它最大的不同是,tunnel 不是建立在最终的 host 上,而是在中间的 router 上!换句话说,对于端点 host A 和 host B 来说,该 tunnel 是透明的(对比上面的 sit tunnel)。这是网上很多教程里没有直接告诉你的。理解这一点非常关键,正是因为它这么设计的,所以它才能解决 ipip tunnel 解决不了的问题。

所以,经过 GRE tunnel 发送的包(从 host A 发送到 host B)大体过程是这样子的(仍然借用了LARTC 中的例子):

我们可以看出,从 host A 发出的包其实就是一个很普通的 IP 包,除了目的地址不直接可达外。该 GRE tunnel 的一端是建立在 router A上,另一段是建立在 router B上,所以添加外部的 IP 头是在 router A 上完成的,而去掉外面的 IP 头是在 router B上完成的,两个端点的 host 上几乎什么都不用做(除了配置路由,把发送到 10.0.2.0 的包路由到 router A)!

这么设计的好处也就很容易看出来了,ipip tunnel 是端对端的,通信也就只能是点对点的,而 GRE tunnel 却可以进行多播。

现在让我们看看Linux内核是怎么实现的,我们必须假设 router A 和 B 上都是运行的 Linux,而 host A 和 B上运行什么是无所谓的。

发送过程是很简单的,因为 router A 上配置了一条路由规则,凡是发往 10.0.2.0 网络的包都要经过 netb 这个 tunnel 设备,在内核中经过 forward 之后就最终到达这个 GRE tunnel 设备的 ndo_start_xmit(),也就是 ipgre_tunnel_xmit() 函数。这个函数所做的事情无非就是通过 tunnel 的 header_ops 构造一个新的头,并把对应的外部 IP 地址填进去,最后发送出去。

稍微难理解的是接收过程,即 router B 上面进行的操作。这里需要指出的一点是,GRE tunnel 自己定义了一个新的 IP proto,也就是 IPPROTO_GRE。当 router B 收到从 router A 过来的这个包时,它暂时还不知道这个是 GRE 的包,它首先会把它当作普通的 IP 包处理。因为外部的 IP 头的目的地址是该路由器的地址,所以它自己会接收这个包,把它交给上层,到了 IP 层之后才发现这个包不是 TCP,UDP,而是 GRE,这时内核会转交给 GRE 模块处理。

GRE 模块注册了一个 hook:

PLAIN TEXT

C:

  1. static const struct gre_protocol ipgre_protocol = {
  2.         .handler = ipgre_rcv,
  3.         .err_handler = ipgre_err,
  4. };

所以真正处理这个包的函数是 ipgre_rcv() 。ipgre_rcv() 所做的工作是:通过外层IP 头找到对应的 tunnel,然后剥去外层 IP 头,把这个“新的”包重新交给 IP 栈去处理,像接收到普通 IP 包一样。到了这里,“新的”包处理和其它普通的 IP 包已经没有什么两样了:根据 IP 头中目的地址转发给相应的 host。注意:这里我所谓的“新的”包其实并不新,内核用的还是同一个copy,只是skbuff 里相应的指针变了。

以上就是Linux 内核对 GRE tunnel 的整个处理过程。另外,GRE 的头如下所示(图片来自这里):

IP header in GRE tunnel

GRE header

[转]深入理解 GRE tunnel,布布扣,bubuko.com

时间: 2024-12-22 22:52:04

[转]深入理解 GRE tunnel的相关文章

[转]深入理解GRE tunnel

Posted in Linux Kernel at November 8th, 2012 / 1 Comment ? 我以前写过一篇介绍 tunnel 的文章,只是做了大体的介绍.里面多数 tunnel 是很容易理解的,因为它们多是一对一的,换句话说,是直接从一端到另一端.比如 IPv6 over IPv4 的 tunnel,也就是 SIT,它的原理如下图所示: 显然,除了端点的 host A 和 host B之外,中间经过的任何设备都是看不到里面的 IPv6 的头,对于它们来说,经过 sit

两个局域网(办公网-IDC)安全互通方案2:by GRE and linux server&深入理解GRE

[第一.需求描述]     办公网和IDC两个局域网(or,任意两个不同局域网),相互隔离.但是在日常运维.研发过程中,需要在办公网访问IDC网络.如果都通过公网ip绕,既不方便,也不安全.如果拉专线,是最稳定可靠的办法.但是作为技术屌丝,想为公司省点钱(这也可以看作是技术价值的一部分),所以打算使用其他方案(当然是免费的方案,或者这样说,使用已有资源的方案.服务器当然也需要花钱的,但是你可以使用已有服务器来完成这个方案)解决这个需求. [第二.背景介绍]     办公网有lan192.168.

[转]在openvswitch上配置GRE tunnel

Posted in Linux Application at November 13th, 2012 如果你是用 openvswitch 内置的 GRE tunnel,那么配置很简单,基本上就一条命令: ovs-vsctl add-port br0 gre0 -- set interface gre0 type=gre options:remote_ip=192.168.1.10 本文想谈的显然不是这个.因为 upstream 内核(指 Linus tree)中的 openvswitch 是不支

【Cisco】 GRE Tunnel隧道

说明:A公司的PC1所在网段192.168.1.0/24要和B公司PC2所在网段172.16.2.0/24建立GRE tunnel通信 配置思路:1.R1与R2要能通信--R1和R2分别配置默认路由到ISP2.新建tunnel端口,设置IP,双方要在同一网段:配置source即公网出口IP和destination即对方公网出口ip3.此时双方tunnel已经建立起来了,需要建立路由,PC1网段到PC2网段,PC2网段到PC1网段,下一跳地址为对端ip:此时配置结束. 拓扑图如下: 配置信息: R

gre tunnel

http://searchenterprisewan.techtarget.com/tip/GRE-tunnel-vs-IPsec-tunnel-What-is-the-difference Encapsulating a packet for secure transportation on the network can be done using either GRE or IPsec protocols. This tip explains under what circumstance

Linux GRE tunnel的构建原理

Generic Enapsulation Tunnel是一种网络隧道技术,之所以称为通用隧道技术,是它可以用来将Ethernet.IP.MPLS等多种报文封装在IP报文中予以转发,在网络中存在较为大规模的应用. Linux系统原生支持了GRE接口,其配置命令如下: ip tunnel add gret1 mode gre remote 45.42.104.183 local 189.245.246.51 ttl 128  # 配置一条以189.245.246.51为源地址,45.42.104.1

linux cent os 6.4 建立GRE tunnel

加载GRE模块 modprobe ip_gre 创建Tunnel 名为office ip tunnel add office  mode gre  remote 111.206.164.122  local 111.206.0.88 ttl 255 ip link set office up 为tunnel 增加IP地址 ip add add 10.100.100.1/30  dev office 创建一个路由表,表名为136 ip route add default via 103.246.1

两个局域网(办公网-IDC)安全互通方案2:by GRE and linux server&深入理解GRE

(0)gre的turnel的打通 1. 这个过程就是双方建立turnel的过程.           (1)局域网路由过程 1.主机A发送一个源为192.168.1.2,目的为10.1.1.2的包 (2)封装过程 1.根据内网路由,可能是你的默认路由网关将之路由至192.168.1.254 2.192.168.1.254第一次封装包,增加增加gre包头,说明包的目的地址192.192.192.1和源地址192.192.192.2. 3.192.168.1.254第2次封装包,增加公网的包头(否则

Centos7 GRE Tunnel

一.关闭防火墙及selinux 二.CentOS7默认不加载gre内核模块,加载gre内核模块 # modprobe ip_gre   临时加载gre模块(重启后失效) # lsmod |grep gre 进行确认 三.两端添加gre1网卡 主机一: [[email protected] ~]# cat /etc/sysconfig/network-scripts/ifcfg-gre1 # DEVICE=gre1 TYPE=GRE ONBOOT=yes BOOTPROTO=static MY_O