如何在Linux上实现每个数据包的多路径路由?


9

3.6之前的Linux内核使用路由缓存进行IPv4多路径路由,这意味着在两个单独的线路/ ISP之间进行路由非常容易。从3.6版开始,算法改为按数据包分组,这意味着需要一些路由表/规则/ iptables标记技巧才能实现两条线路/ ISP。

但是,如果您有两条使用同一ISP的线路,并且可以以平衡/故障转移的方式在每个数据包的基础上沿着一条线路将单个IP路由到两条线路,那么从3.6版开始,您可以轻松实现线路绑定(在IP级别),因为每个数据包在两个方向上的路由。

从4.4开始,内核再次基于基于源地址和目标地址的哈希值更改为基于流的负载平衡。

我当前正在运行内核4.4.36,并且正在通过PPPoE连接使用多路径路由。来自ISP的我的下游流量以每个数据包为基础通过两条单独的线路进行路由(一条IP沿着两条线路进行路由)。这使我的下载速度快于单个线路的速度。两条线的速度几乎相加。它确实运行良好,Skype视频,VoIP(UDP),YouTube等都很好。

由于具有良好的下游体验,我想在上游尝试,但上游的流量是根据较新的基于流的算法在两个ppp设备(具有相同IP地址)之间进行路由的。这意味着我无法实现比单行更快的上传速度。

有没有一种方法可以配置当前内核以使用每包算法?还是采用其他方法来实现每个数据包的多路径路由?我是否需要恢复到较旧的内核(出于各种其他原因,我不想这样做)?

我的ISP不支持多链接ppp。

如果相关,我目前正在Raspberry Pi 3上运行Arch Linux ARMv7。


3
这是一个非常糟糕的主意。L2处的每个数据包平衡(即MLPPP)包括足够的逻辑以按顺序重组数据包。通过IP运行此操作会为无序交付留下巨大的机会(如果不是不确定的话)。这将导致大量问题,包括慢速TCP会话,完全损坏的UDP,任何类型的实时流等问题。另一个问题是,即使您将数据包循环发送到ISP,绝对没有建议他们会同样向您保持平衡。
rnxrx

@rnxrx,谢谢您的评论-已编辑问题以提供更多详细信息。从我的问题出发:“ ISP的下行流量是在每个数据包的基础上跨两条单独的线路路由的”。ISP提供了一个控制面板-当我选择在两条线路上路由一个IP时,它们会按每个数据包路由它完美平衡的轮询。效果很好,两条线的总速度之和约为90%,并提供即时故障转移。Skype视频,VOIP通话,YouTube,BBC流等。一切都很棒-如此出色的下行体验让我想尝试上行
bao7uo 16/12/12

1
嗯-知道了...那么,您现在有两个唯一的IP(每个连接一个),还是通过两条并行路径路由到您身边的单个IP(或子网)?如果您正在运行任何类型的NAT,则在进行此平衡之前进行此操作显然至关重要。无论如何-您看过support.aa.net.uk/…吗?它使用iptables扩展来基本完成您所描述的内容,因此在相当现代的内核版本中应该相当一致。
rnxrx

感谢@rnxrx-是的,我可以选择其中任何一个(两个唯一IP或通过并行路径的单个IP)。我更喜欢单一IP选项,因为它似乎更有意义。
bao7uo

Answers:


3

好的,因此在花了更多时间进行调查之后,我找到了使用Linux TEQL(真链路均衡器)进行处理的方法。这是我松散跟随的链接,但有一些调整。

http://lartc.org/howto/lartc.loadshare.html

这就是我在Arch Linux ARMv7(Raspberry Pi 3)上运行它的方式。

开机时:

引导时应运行以下命令以加载适当的内核模块。

modprobe sch_teql

假设您要从eth0上的本地网络进行NAT,以下命令也将在引导时运行。

sysctl -w net.ipv4.ip_forward=1
iptables -A INPUT -i ppp+ -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i ppp+ -o eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A POSTROUTING -t nat -o teql+ -j MASQUERADE

FORWARD返回流量在ppp +上,而POSTROUTING MASQUERADE在teql +上,因为传出流量在teql上流出,而返回流量在ppp上返回。

当出现ppp链接时:

假设要进行负载平衡的链接为ppp,则以下命令将在脚本中的/etc/ppp/ip-up.d/脚本中运行。

sysctl -w net.ipv4.conf.ppp1.rp_filter=2
sysctl -w net.ipv4.conf.ppp2.rp_filter=2
tc qdisc add dev ppp1 root teql0
tc qdisc add dev ppp2 root teql0
ip address add 1.1.1.1/32 dev teql0
# you can add additional public IP addresses teql0 if you need to
ip link set teql0 up
ip route replace default scope global dev teql0

1.1.1.1面向ISP的公共IP地址在哪里。可以将其他公用IP分配给teql0设备,但无需将其分配给ppp设备。在我的设置中,两个ppp链接共享相同的IP(由pppoe协商,等等)。它手动分配的teql链接如上所示。ISP需要在两个链路上均等地发送IP流量。

在上面的脚本中,反向路径(rp_filter)都设置为2(loose),因此返回数据包不会由于返回数据包返回到ppp接口而不是teql0而被丢弃。

我已经按照这种方式进行设置,并且效果很好。很容易!链接发生故障时,将进行无缝故障转移。当他们出现时,他们只是再次开始工作。似乎在故障转移时没有数据包丢失或延迟,在备份时也没有。

另外,一位评论者建议使用以下链接,该链接使用策略路由,并使用iptables标记每个其他数据包等。但是,我将在几天后尝试查看它是否比上述方法更好,并在此提供反馈。

http://support.aa.net.uk/Router_-_Linux_upload_bonding_using_policy_routing


我从来没有尝试过策略路由,因为TEQL运行得很好。如果它还没有破裂的话
。。。– bao7uo

我正在尝试使它起作用。我有绑定功能,我可以使用路由器的绑定接口。但是我无法使NAT正常工作,来自我的LAN的流量没有沿着绑定链路移动:(
andynormancx

如果您发布有关服务器故障的新问题,并从评论中链接至该问题,我将尽力为您解决。包括尽可能多的信息,例如接口/ ip配置,路由表,iptables规则等。除非您可以在注释中放入所有信息?
bao7uo

1
PS。刚刚注意到我的配置中有一个错误。它说了sysctl -w net.ipv4.ip_forward但应该说,sysctl -w net.ipv4.ip_forward=1所以我在上面纠正了。这肯定会阻止来自LAN的流量沿着绑定链接向下传输。
bao7uo

我不认为这是阻止它工作的原因,我在sysctl中启用了转发。我现在正在尝试确定是否会出现我看到的大量乱序数据包。
andynormancx
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.