Linux 内核 GTP 隧道模块¶
- 文档作者
Harald Welte <laforge@gnumonks.org> 和 Andreas Schultz <aschultz@tpip.net>
在 'drivers/net/gtp.c' 中,您可以找到 GTP 隧道端点的内核级实现。
什么是 GTP¶
GTP 是通用隧道协议,它是一种 3GPP 协议,用于在移动站(电话、调制解调器)和外部分组数据网络(如互联网)之间的互连之间隧道传输用户 IP 负载。
因此,当您从手机启动“数据连接”时,手机将使用控制平面来发出信号,以便在该外部数据网络和手机之间建立此类隧道。因此,隧道端点驻留在手机和网关中。所有中间节点仅传输封装的数据包。
电话本身不实现 GTP,而是使用一些其他依赖于技术的协议栈来传输用户 IP 负载,例如 LLC/SNDCP/RLC/MAC。
在蜂窝运营商基础设施中的某个网络元素(GPRS/EGPRS 或经典 UMTS 情况下的 SGSN,3G femtocell 情况下的 hNodeB,4G/LTE 情况下的 eNodeB),蜂窝协议栈被转换为 GTP *而不中断端到端隧道*。因此,中间节点仅执行一些特定的中继功能。
在某个时刻,GTP 数据包最终到达所谓的 GGSN (GSM/UMTS) 或 P-GW (LTE),它们终止隧道,解封装数据包并将其转发到外部分组数据网络。这可以是公共互联网,但也可以是任何私有 IP 网络(甚至理论上是一些非 IP 网络,如 X.25)。
您可以在 3GPP TS 29.060 协议规范中找到协议规范,可从 3GPP 网站公开获取:http://www.3gpp.org/DynaReport/29060.htm
为了方便起见,下面提供了 v13.6.0 的直接 PDF 链接:http://www.etsi.org/deliver/etsi_ts/129000_129099/129060/13.06.00_60/ts_129060v130600p.pdf
Linux GTP 隧道模块¶
该模块实现隧道端点的功能,即能够解封装手机发起的上行链路中的隧道 IP 数据包,并封装从外部分组网络接收到的原始 IP 数据包,以下行链路发送到手机。
它*仅*实现所谓的“用户平面”,携带用户 IP 负载,称为 GTP-U。它不实现“控制平面”,控制平面是一种用于建立和拆除 GTP 隧道的信令协议 (GTP-C)。
因此,为了有一个正常工作的 GGSN/P-GW 设置,您将需要一个用户空间程序来实现 GTP-C 协议,然后使用内核中 GTP-U 模块提供的 netlink 接口来配置内核模块。
这种分离的架构遵循其他协议的隧道模块,例如 PPPoE 或 L2TP,您还可以在其中运行用户空间守护程序来处理隧道建立、身份验证等,并且只有数据平面在内核内部加速。
不要被术语混淆:GTP 用户平面通过内核加速路径,而 GTP 控制平面进入用户空间 :)
该模块的官方主页位于 https://osmocom.org/projects/linux-kernel-gtp-u/wiki
支持 Linux 内核 GTP-U 的用户空间程序¶
在撰写本文时,至少有两个自由软件实现实现了 GTP-C,并且可以使用 netlink 接口来使用 Linux 内核 GTP-U 支持
OpenGGSN(C 中的经典 2G/3G GGSN):https://osmocom.org/projects/openggsn/wiki/OpenGGSN
ergw(Erlang 中的 GGSN + P-GW):https://github.com/travelping/ergw
用户空间库/命令行实用程序¶
有一个名为“libgtpnl”的用户空间库,它基于 libmnl,并实现了针对内核 GTP 模块提供的 netlink 接口的 C 语言 API
协议版本¶
GTP-U 有两个不同的版本:v0 [GSM TS 09.60] 和 v1 [3GPP TS 29.281]。两者都在内核 GTP 模块中实现。版本 0 是一个遗留版本,并且在最近的 3GPP 规范中已弃用。
GTP-U 使用 UDP 传输 PDU。 接收 UDP 端口对于 GTPv1-U 为 2151,对于 GTPv0-U 为 3386。
GTP-C 有三个版本:v0、v1 和 v2。 由于内核不实现 GTP-C,因此我们不必担心这一点。 用户空间中的控制平面实现负责实现这一点。
IPv6¶
3GPP 规范表明 IPv4 或 IPv6 可以用于内部(用户)IP 层,也可以用于外部(传输)层。
不幸的是,内核模块目前既不支持用户 IP 负载的 IPv6,也不支持外部 IP 层的 IPv6。 非常欢迎修复此问题的补丁或其他贡献!
邮件列表¶
如果您对如何从您自己的软件中使用内核 GTP 模块有疑问,或者想为代码做出贡献,请使用 osmocom-net-grps 邮件列表进行相关讨论。 可以通过 osmocom-net-gprs@lists.osmocom.org 访问该列表,用于管理您的订阅的 mailman 界面位于 https://lists.osmocom.org/mailman/listinfo/osmocom-net-gprs
问题跟踪器¶
Osmocom 项目在 https://osmocom.org/projects/linux-kernel-gtp-u/issues 维护内核 GTP-U 模块的问题跟踪器
历史/致谢¶
该模块最初由 Harald Welte 于 2012 年创建,但从未完成。 Pablo 进来完成了 Harald 留下的烂摊子。 但由于缺乏用户兴趣,它从未合并。
2015 年,Andreas Schultz 挺身而出,修复了更多错误,使用新功能对其进行了扩展,并最终推动我们所有人使其成为主线,并在 4.7.0 中合并。
架构细节¶
本地 GTP-U 实体和隧道识别¶
GTP-U 使用 UDP 传输 PDU。 接收 UDP 端口对于 GTPv1-U 为 2152,对于 GTPv0-U 为 3386。
每个 IP 地址只有一个 GTP-U 实体(因此,只有一个 SGSN/GGSN/S-GW/PDN-GW 实例)。 隧道端点标识符 (TEID) 对于每个 GTP-U 实体都是唯一的。
特定隧道仅由目标实体定义。 由于目标端口是恒定的,因此只有目标 IP 和 TEID 定义一个隧道。 源 IP 和端口对于隧道没有意义。
因此
发送时,远程实体由远程 IP 和隧道端点 ID 定义。 源 IP 和端口没有意义,可以随时更改。
接收时,本地实体由本地目标 IP 和隧道端点 ID 定义。 源 IP 和端口没有意义,可以随时更改。
[3GPP TS 29.281] 第 4.3.0 节定义了如下内容
The TEID in the GTP-U header is used to de-multiplex traffic
incoming from remote tunnel endpoints so that it is delivered to the
User plane entities in a way that allows multiplexing of different
users, different packet protocols and different QoS levels.
Therefore no two remote GTP-U endpoints shall send traffic to a
GTP-U protocol entity using the same TEID value except
for data forwarding as part of mobility procedures.
上面的定义仅定义了两个远程 GTP-U 端点*不应*发送到同一 TEID,它*不*禁止或排除这种情况。 事实上,提到的移动程序使得 GTP-U 实体必须接受来自多个或未知对等方的 TEID 的流量。
因此,接收端专门基于 TEID 而不是基于源 IP 来识别隧道!
APN 与网络设备¶
GTP-U 驱动程序为每个 Gi/SGi 接口创建一个 Linux 网络设备。
[3GPP TS 29.281] 调用 Gi/SGi 参考点为一个接口。 这可能会给人留下 GGSN/P-GW 只能有一个此类接口的印象。
正确的是,Gi/SGi 参考点定义了基于 GTP-U 隧道和基于 IP 的网络的 +3GPP 分组域 (PDN) 之间的互连。
在任何 3GPP 文档中都没有规定限制 GGSN/P-GW 实现的 Gi/SGi 接口的数量。
[3GPP TS 29.061] 第 11.3 节明确指出,特定 Gi/SGi 接口的选择是通过接入点名称 (APN) 进行的
2. each private network manages its own addressing. In general this
will result in different private networks having overlapping
address ranges. A logically separate connection (e.g. an IP in IP
tunnel or layer 2 virtual circuit) is used between the GGSN/P-GW
and each private network.
In this case the IP address alone is not necessarily unique. The
pair of values, Access Point Name (APN) and IPv4 address and/or
IPv6 prefixes, is unique.
为了支持重叠地址范围用例,每个 APN 都映射到一个单独的 Gi/SGi 接口(网络设备)。
注意
接入点名称纯粹是一个控制平面 (GTP-C) 概念。 在 GTP-U 级别,只有隧道端点标识符存在于 GTP-U 数据包中,并且网络设备是已知的
因此,对于给定的 UE,IP 到 PDN 网络的映射为
网络设备 + MS IP -> 对等 IP + 对等 TEID,
以及从 PDN 到 IP 网络
本地 GTP-U IP + TEID -> 网络设备
此外,在将接收到的 T-PDU 注入网络设备之前,会根据 PDP 上下文中记录的 IP 检查 MS IP。