На диаграмме ниже изображен сценарий, который включает агрегирование трех медленных каналов пропускной способности через WAN
.
А быстрый хозяин на WAN
(@ 54.239.98.8
) обменивается данными с хостом на LAN
(@ 192.168.0.100
), который подключен через три медленных канала к WAN
через три роутера под управлением Linux v4.14.151 и netfilter
/iptables
брандмауэры:
IP-трафик от быстрый хозяин приходит фрагментированным и рандомизированным на три маршрутизатора (но всегда от 54.239.98.8
). У меня нет контроля над этой фрагментацией (корпоративная политика, подумайте) - я подозреваю, что фрагментация сделана нарочно быстрым хостом.
ЭТА ПРОБЛЕМА: Каждый маршрутизатор пытается повторно собрать фрагментированные IP-пакеты, что приводит к потере данных, потому что фрагменты проходят случайные пути через три маршрутизатора, и часто один маршрутизатор не может собрать все фрагменты пакета для успешной повторной сборки.
Проанализировав iptables / netfilter
На диаграмме ниже я вижу, что неправильная повторная сборка происходит в PREROUTING netfilter
крючок, перед цепочкой правил в 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-фрагментам проходить на целевой хост в локальной сети (@ 192.168.0.100
), который выполняет повторную сборку своего собственного пакета с пакетами, поступающими от всех трех маршрутизаторов. Это решение работает, но некрасиво, поскольку изменяет код ядра и отключает дефрагментацию для ВСЕ переадресованные пакеты (независимо от их источника).
ВОПРОС: Есть ли лучшее решение, чем изменение этого кода в ядре?
Особенно способ выборочного отключения дефрагментации IP только для пакетов, приходящих от быстрого хоста в WAN @ ip.src == 54.239.98.8
.