Перейти к содержимому
Калькуляторы

Модифицированный модуль RAWNAT Натим и шейпим 2+ гбит/c с загрузкой ядер 2-3%

По многочисленным просьбам выкладываю небольшую доделку к модулю RAWNAT из пакета xtables-addons. Суть доделки в том, что в отличие от оригинала, меняющего IP пакетов в соответствии с правилом iptables, этот модуль смотрит в находящуюся внутри него таблицу соответствия "старый ip -> новый ip" и меняет в соответствии с ней. Также имеются таблицы не для смены IP, а для установки skb->priority, поэтому получается табличный аналог -j CLASSIFY. Все таблицы в данной версии содержат 65535 записей, что достаточно для обработки подсети /16. Больше нам не требовалось. Имеется таблица для SNAT, DNAT, и 4 таблицы для CLASSIFY.

 

По результатам работы (более полугода), загрузка ядер обычного core i7 при шейпинге (tc htb...) трафика порядка 1.5 гбит/c в обе стороны составляет 2-3% - это на linux 3.7 с отключенным route cache. Такая же ситуация и с натом, но нат у нас делается на одной машине с bgp, который дает основную нагрузку на ядра. Сетевые карты - ixgbe.

 

Собирать следующим образом:

 

./configure

./make

./make install

cd extensions

gcc gcc -o iptrnat iptrnat.c

cp ./iptrnat /usr/local/bin

 

Использование. Для примера имеем две подсети серых адресов 192.168.0.0/19 и 192.168.64.0/19, одну подсеть реальников 195.33.64.0/20.

 

modprobe xt_RAWNAT (в dmesg должно появиться сообщение, что загружен правильный модуль)

 

iptables -A POSTROUTING -t rawpost -s 192.168.0.0/19 -j TABSNAT

iptables -A POSTROUTING -t rawpost -s 192.168.64.0/19 -j TABSNAT

iptables -A PREROUTING -t raw -d 195.33.64.0/20 -j TABDNAT

 

Добавляем сопоставление:

 

iptrnat -a -t 1 -i 195.33.64.5 -r 192.168.10.33

iptrnat -a -t 2 -i 192.168.10.33 -r 195.33.64.5

 

Теперь проходящий с адреса 192.168.10.33 будет превращаться в 195.33.64.5 и наоборот. Такое сопоставление нужно добавлять скриптом при авторизации каждого клиента, например, при помощи lISG.

 

Удаление сопоставления при выходе клиента из сети:

 

iptrnat -d -t 1 -i 195.33.64.5

iptrnat -d -t 2 -i 192.168.10.33

 

Шейпинг можно сделать например так. eth0 - внутренний интерфейс, eth1 - наружный:

 

tc qdisc add dev eth0 root handle 1: htb default 1

tc class replace dev eth0 classid 1:1 htb rate 2000Mbit ceil 2000Mbit quantum 1500 burst 2000k cburst 2000k

tc qdisc add dev eth0 parent 1:1 handle 10: pfifo limit 10000

 

tc qdisc add dev eth1 root handle 1: htb default 1

tc class replace dev eth1 classid 1:1 htb rate 2000Mbit ceil 2000Mbit quantum 1500 burst 2000k cburst 2000k

tc qdisc add dev eth1 parent 1:1 handle 10: pfifo limit 10000

 

iptables -t mangle -A POSTROUTING -s 192.168.0.0/16 -o eth1 -j TABCLAS --cmatch src --ctable 3

iptables -t mangle -A POSTROUTING -s 195.33.64.0/20 -o eth1 -j TABCLAS --cmatch src --ctable 4

iptables -t mangle -A POSTROUTING -d 192.168.0.0/16 -o eth0 -j TABCLAS --cmatch dst --ctable 5

iptables -t mangle -A POSTROUTING -d 195.33.64.0/20 -o eth0 -j TABCLAS --cmatch dst --ctable 6

 

И для каждого клиента создаем правила. Допустим, у клиента с номером $ID имеется 3 адреса - 192.168.10.33, 192.168.55.70 и реальник 195.33.65.95:

 

iptrnat -a -t 3 -i 192.168.10.33 -c 1:$ID

iptrnat -a -t 3 -i 192.168.55.70 -c 1:$ID

iptrnat -a -t 4 -i 195.33.65.95 -c 1:$ID

iptrnat -a -t 5 -i 192.168.10.33 -c 1:$ID

iptrnat -a -t 5 -i 192.168.55.70 -c 1:$ID

iptrnat -a -t 6 -i 195.33.65.95 -c 1:$ID

 

tc class replace dev eth0 parent 1:1 classid 1:$ID htb rate $SPEEDkibit ceil $SPEEDkibit quantum 1500 burst 10k cburst 10k

tc qdisc replace dev eth0 parent 1:$ID handle $ID:0 pfifo limit $QUEUE

 

tc class replace dev eth1 parent 1:1 classid 1:$ID htb rate $SPEEDkibit ceil $SPEEDkibit quantum 1500 burst 10k cburst 10k

tc qdisc replace dev eth1 parent 1:$ID handle $ID:0 pfifo limit $QUEUE

 

Как видно, все работает без заумных фильтров и гигантских деревьев. И почему это раньше никто не реализовал?

 

Скачать можно тут: http://195.22.104.3/xtables-addons-1.41-tabnat.tgz

Изменено пользователем vladd

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

интересная штука получается.

 

Можно будет отказаться от хэш-фильтров. Надо потестить.

 

Планируете разработчикам писать - что бы они закоммитили ?

Изменено пользователем alexxx71

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

я так понимая что это 1:1 NAT, тоесть просто занатить \24 на один-два ИП не получится ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Я так понял что это 1:1 NAT, но если нет match'а по таблице TABCLAS то пакет идет дальше и рано или поздно попадет под действие ipt_SAME, который его и занатит. Можно вообще не использовать сопоставления, а просто делать CLASSIFY. (итересно - это быстрее чем хеш-фильтры или утопия?)

Я правильно понял ?

Изменено пользователем alexxx71

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

интересная штука получается.

 

Можно будет отказаться от хэш-фильтров. Надо потестить.

 

Именно так. Работает все красивее и естественней. Плюс можно один класс делить между несколькими IP, из разных подсетей в произвольном количестве - нам это и надо было, т.к. на многих учетках у пользователей несколько адресов, и чтобы скорость между ними делилась.

 

А в отличие от того же ipfw, работает на нескольких ядрах и нагрузку дает на порядок меньшую. Такое впечатление, что с текущим железом и 10 гиг прожует.

 

Нат да, 1-к-1. Раньше приходилось для такого ната выстраивать огромное дерево и несколько десятков тысяч правил в iptables.

 

Планируете разработчикам писать - что бы они закоммитили ?

Да, надеюсь примут.

Изменено пользователем vladd

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Я так понял что это 1:1 NAT, но если нет match'а по таблице TABCLAS то пакет идет дальше и рано или поздно попадет под действие ipt_SAME, который его и занатит. Можно вообще не использовать сопоставления, а просто делать CLASSIFY.

TABCLAS - для классификации, TABDNAT/TABSNAT - для ната. Можно использовать только то, что нужно.

(итересно - это быстрее чем хеш-фильтры или утопия?)

Не медленнее точно, но гораздо проще и гибче в применении.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Приветствую, интересно покрутить данную наработку

 

Вопрос в лоб. Имеем серые подсети скажем 10.ХХХ.0.0/16, 10.YYY.0.0/16 и допустим 10.ZZZ.0.0/16

 

Естественно, у нас нет блоков реальников такого объема. Как в таком случае строить правила iptables 1-в-1? Уменьшать размеры до /24? или можно сделать что-то в духе:

10.XXX.0.0/16 в aaa.bbb.ccc.0/19

10.YYY.0.0/16 в aaa.bbb.ccc.0/19

10.ZZZ.0.0/16 в aaa.bbb.ccc.0/19

 

Вопрос номер два:

 

У нас есть два блока реальников из разных диапазонов и разных размеров: aaa.bbb.ccc.0/19 и ddd.eee.fff.0/20

Сейчас они попилены на более мелкие, но есть возможность воссоединить один из них в большой. Вопрос в том, как строить правила ната имея разные блоки реальников?

 

 

iptrnat -a -t 1 -i 195.33.64.5 -r 192.168.10.33

iptrnat -a -t 2 -i 192.168.10.33 -r 195.33.64.5

 

На что в данном случае влияют эти -t 1 и -t 2?

Как я понял 1 и 2 это номера таблиц.

 

Одна таблица на одно сопоставление идет? Или какой тут принцип?

Изменено пользователем micol

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Доброго времени суток!

 

Очень заинтересовала приведённая разработка. Захотелось посмотреть. Но не удалось собрать.

Тестировал на одной и той же машине с разными версиями ядер (2.6.39 - 3.10.17) Обнаружил две проблемы. Первая возникает при сборке с ядрами версией выше 3.5.7 Её победить удалось. Вторая при сборке с ядром любой версии.

/root/shaping/ipt_TABCLAS/xtables-addons-1.41/extensions/xt_RAWNAT.c: В функции «ipt_rnat_set_ctl»:
/root/shaping/ipt_TABCLAS/xtables-addons-1.41/extensions/xt_RAWNAT.c:437:3: предупреждение: format «%ld» expects argument of type «long int», but argument 2 has type «__be32» [-Wformat] 
/root/shaping/ipt_TABCLAS/xtables-addons-1.41/extensions/xt_RAWNAT.c:437:3: предупреждение: format «%ld» expects argument of type «long int», but argument 3 has type «__be32» [-Wformat]
WARNING: "nf_nat_setup_info" [/root/shaping/ipt_TABCLAS/xtables-addons-1.41/extensions/xt_DNETMAP.ko] undefined!
WARNING: "ipt_unregister_table" [/root/shaping/ipt_TABCLAS/xtables-addons-1.41/extensions/iptable_rawpost.ko] undefined!   
WARNING: "ipt_register_table" [/root/shaping/ipt_TABCLAS/xtables-addons-1.41/extensions/iptable_rawpost.ko] undefined!   
WARNING: "ipt_do_table" [/root/shaping/ipt_TABCLAS/xtables-addons-1.41/extensions/iptable_rawpost.ko] undefined! 
In file included from ../include/net/netfilter/nf_nat.h:4:0,  
                from libxt_DNETMAP.c:14: 
../include/net/netfilter/nf_conntrack_tuple.h:29:7: ошибка: повторное определение «union nf_conntrack_man_proto» 
/usr/include/linux/netfilter/nf_conntrack_tuple_common.h:13:7: замечание: originally defined here 
make[3]: *** [libxt_DNETMAP.oo] Error 1 
make[2]: *** [user-all-local] Error 2 
make[1]: *** [all-recursive] Error 1                                                                                                                         
make: *** [all] Error 2                                                                                                                                      

Дистрибутив: gentoo

gcc версия 4.6.3 (Gentoo 4.6.3 p1.13, pie-0.5.2)

Конфиг ядра 3.5.7 в аттаче.

 

Подскажите, пожалуйста, что пропатчить в исходниках. В первую очередь интересует сборка для ядра 3.10.7

Ежели потребуется дополнительная информация, постараюсь предоставить.

config.gz

Изменено пользователем OperationCwal

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Жаль, что тема заглохла. Очень любопытное решение.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Начал доделывать: https://github.com/alexey001/xtables-addons.

Для таргета TABCLAS сделан lookup из таблицы роутинга , в качестве классификатора юзается realm , тоесть както так:

 

iptables ...... -j TABCLAS --rtable 100 --cmatch dst

 

ip route add 1.2.3.4 dev lo realm 1/100 table 100.

 

Соответственно будет брать из таблицы 100 (при совпадении) realm и засовывать его в priority (class). Ну и переведен на xtables поновее.

 

Если нужны realm > 255 патч к iproute2.

 

diff --git a/lib/rt_names.c b/lib/rt_names.c
index 911e4d2..aac5859 100644
--- a/lib/rt_names.c
+++ b/lib/rt_names.c
@@ -307,7 +307,7 @@ int rtnl_rtrealm_a2n(__u32 *id, const char *arg)
       }

       res = strtoul(arg, &end, 0);
-       if (!end || end == arg || *end || res > 255)
+       if (!end || end == arg || *end || res > 65535)
               return -1;
       *id = res;
       return 0;

 

 

Решение АБСОЛЮТНО не тестированное (времени не было), но вроде должно работать :)

 

P.S. Все работает , но надо учитывать что в tc класс - hex , в iproute realm - dec , t.e например для tc класс 1:20 для iproute realm 1/32

Изменено пользователем alex_001

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Тот самый случай, когда и хочется, и колется. ;)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

с отключенным route cache

Кто-нибудь имеет больше информации о том как это делать и какой профит с включенным "route cache" и без?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

ThreeDHead

Как сделать - поставить ядро начиная с 3.6 и выше. Сведения про профит противоречивы, но вероятно после отключения стало лучше, раз его глобально выпилили.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

kayot, есть где подробнее посмотреть, а то ченйнджлоги молчат?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

но вероятно после отключения стало лучше

Лучше стало только в части cache thrashing неконтролируемым внешним воздействием - его больше нет. В остальном, очевидно, что существует некий размер таблицы маршрутизации, при котором новая схема начнет проигрывать.

 

https://home.regit.org/2013/03/david-miller-routing-cache-is-dead-now-what/

http://www.spinics.net/lists/netdev/msg205545.html

Изменено пользователем vitalyb

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

vitalyb

Спасибо, стало яснее.

Профит от кеша был невелик, а вот возможность загнать удаленный хост в DOS была. Потому и прибили.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Что есть "отключенный route cache"? Как это делается и какие накладные и какой профит?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Что есть "отключенный route cache"? Как это делается и какие накладные и какой профит?

Про профит написали. Что это есть - этакая динамическая route table , lookup делался по ней и только если нет в кэше лезло в осн. таблицу (заполняя попутно кэш). Я так понимаю смогли выпилить когда осн. таблицу стали хранить в trie (раньше это была опция) , размер уменьшился , и видимо время выборки стало практически равным времени выборки из кэша.

Проблемы с кэшем как уже указывали - возможность DOS'a и необходимость сборки мусора (старых записей).

Сам кэш можно посмотреть - 'ip route sh cache'

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Т.е. "отключенный route cache", это ничто иное как тупо версия ядра >= 3.6

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Т.е. "отключенный route cache", это ничто иное как тупо версия ядра >= 3.6

Не совсем. В более ранних версиях, точно не скажу с каких, он отключался автоматически если начинал идти "плохой" трафик. см. крутилку

/proc/sys/net/ipv4/rt_cache_rebuild_count

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Если кто хочет на gentoo попробовать - https://github.com/alexey001/iln-overlay тут патченный ebuild iproute2.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Небольшой скрипт для управления всей конструкцией. https://github.com/alexey001/farsh/tree/master/shell

инициализация: shp.sh shaper_init; shp.sh shaper_load.

Ссылка на ebuild для klish - в пред. посте.

Действия по добавлению/изменению лучше делать через clish - проверки на правильность параметров в самом скрипте не делал.

Изменено пользователем alex_001

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Планируете разработчикам писать - что бы они закоммитили ?

Да, надеюсь примут.

v2.4 (2014-01-09)

=================

Enhancements:

- Support for Linux up to 3.13

Changes:

- remove unmaintained RAWSNAT/RAWDNAT code

 

 

ЗЫ. Коллеги, ни у кого сырцов не осталось? До автора не достучался, ссылка мертвая. (((

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

присоеденяюсь к вопросу pppoetest

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Гость
Ответить в тему...

×   Вставлено в виде отформатированного текста.   Вставить в виде обычного текста

  Разрешено не более 75 смайлов.

×   Ваша ссылка была автоматически встроена.   Отобразить как ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставить изображения напрямую. Загрузите или вставьте изображения по ссылке.