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 毫微微蜂窝情况下的 hNodeB,4G/LTE 情况下的 eNodeB)中,蜂窝协议栈被转换为 GTP,而不会破坏端到端隧道。因此,中间节点仅执行一些特定的中继功能。
在某个时候,GTP 数据包最终到达所谓的 GGSN (GSM/UMTS) 或 P-GW (LTE),它们终止隧道,解封装数据包并将其转发到外部分组数据网络。这可以是公共互联网,也可以是任何私有 IP 网络(甚至理论上可以是 X.25 等非 IP 网络)。
您可以在 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 负载或外部 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。