带有外部程序的高级动态路由

lbe*_*gni 6 linux routing iptables tc iproute2

我需要构建一个系统,在该系统中我能够根据许多参数(例如端口/协议等)路由数据包,这些参数在某种程度上是“正常的”,但也包括其他方面,例如队列长度和其他外部因素. 我的路由器由 2 个内部接口 (802.11) 和两个外部接口(一个 ADSL,一个 LTE)组成。所以我想通过外部程序检查每个数据包,并决定应该路由哪个接口。

我看了一下iproute2,但我没有找到任何方法将每个数据包传递给外部程序,或者以某种方式为每个数据包动态选择路由。

所以问题是:做到这一点的最佳方法是什么?是否已经有朝这个方向发展的工具,还是我应该依靠自己制作的东西,并通过 linux 标准工具传递数据包?

Jof*_*rey 8

Netfilter (iptables) 有队列模块将帧发送到用户空间程序。不同语言(cpython、 perl 等)的库可用于检查数据包。处理完帧后,您将返回 ACCEPT 或 DROP 判决、原始帧或修改帧,以及设置标记的选项。

我猜测您可以使用标记在 netfilter 链的其余部分以不同的方式处理此数据包,并更改路由标记以选择特定的路由表。

这将是比非常低级别的设备处理更优雅的解决方案,但可能是性能问题,具体取决于您的用户空间实现的选择。

我在另一个项目中使用它来修改来自损坏客户端的传入 DHCP 帧,但从未使用过该标记。


jch*_*jch 7

用户空间路由可以通过将默认路由指向tun设备并让用户空间程序检查每个接收到的数据包来实现。这是一种效率低下且脆弱的方法,但它已经奏效了——由于 Henning Rogge,有一个 AODVv2 实现以这种方式工作。

当然,另一种选择是在内核中实现你的路由协议——AODV/DYMO/AODVv2 的大多数实现都是这样工作的。

在开始此类任务之前,我建议您仔细考虑是否需要为每个单独的数据包做出路由决策;如果可能,更好的方法是动态操作路由表,同时将实际转发留给内核。本草稿给出了使用这种方法可以实现的目标的示例。(免责声明:我是合著者。)