下图描述了一个场景,涉及在 上聚合三个慢速通道 吞吐量WAN
。
快速主机WAN
(@ )上的主机正在与(@ )54.239.98.8
上的主机进行通信,该主机通过三个运行 Linux v4.14.151 的路由器和/防火墙通过三个慢速通道连接到:LAN
192.168.0.100
WAN
netfilter
iptables
来自快速主机到达三台路由器时,碎片化且随机化(但始终来自54.239.98.8
)。我无法控制这种碎片化(公司政治,想想吧)——我怀疑碎片化是快速主机故意造成的。
问题:每个路由器都尝试重新组合碎片化的 IP 数据包,这会导致数据丢失,因为碎片通过三个路由器采用随机路径,并且一个路由器通常无法收集所有数据包碎片以成功重新组合。
通过分析iptables / netfilter
下图,我发现有问题的重组发生在 PREROUTINGnetfilter
钩子中,在表中的规则链raw
被处理之前。
尝试的解决方案:我已修改内核模块nf_defrag_ipv4
以禁用钩子中有问题的碎片整理PREROUTING
,如下所示:
static const struct nf_hook_ops ipv4_defrag_ops[] = {
{
.hook = ipv4_conntrack_defrag, /* I changed this to point to: return NF_ACCEPT; */
.pf = NFPROTO_IPV4,
.hooknum = NF_INET_PRE_ROUTING,
.priority = NF_IP_PRI_CONNTRACK_DEFRAG,
},
{
.hook = ipv4_conntrack_defrag,
.pf = NFPROTO_IPV4,
.hooknum = NF_INET_LOCAL_OUT,
.priority = NF_IP_PRI_CONNTRACK_DEFRAG,
},
};
该模块的完整源代码可以查看这里。
此代码更改禁用了所有传入数据包的重组,并允许未更改的 IP 片段传递到 LAN 上的目标主机 (@ 192.168.0.100
),该主机使用来自所有三个路由器的数据包完成自己的数据包重组。此解决方案有效,但很丑陋,因为它修改了内核代码并禁用了碎片整理全部转发的数据包(不管其来源)。
问题: 除了在内核中更改此代码之外,还有更好的解决方案吗?
特别是有一种方法可以选择性地仅对来自 WAN @ 上的快速主机的数据包禁用 IP 碎片整理ip.src == 54.239.98.8
。