kisa Опубликовано 18 декабря, 2016 · Жалоба Попробовал бондинг. Работает. Достаточно параметров командной строки. Но LACP 802.3AD режим пока не пробовал, только статику. Подробности здесь https://github.com/alexk99/the_router/blob/master/link_bonding.md Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
SyJet Опубликовано 18 декабря, 2016 · Жалоба ООО, интересная тема на самом деле.. еще немного и покупка аппаратных брасов не будет становится Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
nuclearcat Опубликовано 19 декабря, 2016 · Жалоба Ну я вот терминирую на сервере 2x10G, до 12к юзеров на сервер. Дальше я просто упираюсь в сетевые интерфейсы. Ставить больше карт с десятками - начинаются нюансы с производительностью шины, энергопотреблением, охлаждением сетевок, надежность здорово падает. Проще поставить еще один сервер и представить, что это еще одна линейная карта в шасси роутера:) Т.к. система у меня своя - унификация управления несколькими BRAS - не проблема. Фич из стека ядра я использую массу - HTB + fq, connmark, string matching (для отлова коннектов с определенных строчками и маркировки этих соединений), nat redirect, и еще много чего. Имхо реализовывать подобный функционал на DPDK - потребует массу работы, с очень сомнительной пользой. Может быть роутить/nat-ить гигабит-два на атоме, но смысл? Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
Ivan_83 Опубликовано 19 декабря, 2016 · Жалоба Фич из стека ядра я использую массу - HTB + fq, connmark, string matching (для отлова коннектов с определенных строчками и маркировки этих соединений), nat redirect, и еще много чего. Имхо реализовывать подобный функционал на DPDK - потребует массу работы, с очень сомнительной пользой. Может быть роутить/nat-ить гигабит-два на атоме, но смысл? Это твоя местная специфика. Людям нужно просто НАТ, без прибабахов, и то что они могут получать по 100г с таза и более вполне себе хорошо для них. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
nuclearcat Опубликовано 19 декабря, 2016 · Жалоба Это твоя местная специфика. Людям нужно просто НАТ, без прибабахов, и то что они могут получать по 100г с таза и более вполне себе хорошо для них. Какие еще 100Г? :) Причем тут местная специфика? Для начала, X710 до сих пор стабильно не работают, у меня результаты по производительности - чуть хуже X520. Много нюансов с прошивкой (Dell-овская прошивка тухлая, а интелевской просто так отказывается их шить), да и цена не особо сьедобная. Существующее на глобальном рынке железо (ессно не по заоблачным ценам) по сугубо аппаратным причинам не проглотит больше 40G на wirespeed со стабильным результатом. Чтобы банально воткнуть и заставить стабильно работать кучу двухпортовых X520 молотящих на полную катушку, прийдется здорово помучатся с подбором платформы. Обосновать это просто, на обычных UP материнках максимум два слота, которые удовлетворят требованиям X520. В лучшем случае, если будете тщательно отбирать, и не попадете на плату где дополнительный слот реализован через мост - то три. Значит больше - только E5 и два проца. А это неминуемо NUMA. А с NUMA код NAT очень серьезно усложняется, если хочется, чтобы он работал эффективно. X710 тоже весело, там всенепременно надо PCI-E 3.0+. Кстати, тут есть человек, который кажется с 40G(или 100G? если захочет - подтвердит :) ) картами наловился лулзов, особенно в том плане, что стандарт все толкуют несколько по разному, и фичи (кажется что-то связанное с FEC) реализуют тоже как вздумается. достаточно посмотреть в код netfilter, чтобы понять, что NAT в его правильной реализации - очень нетривиальная штука. На синтетических тестах работает что угодно, а если пнуть в продакшн "недоNAT", но юзеры сьедят с потрохами, когда nat pinning перестанет работать, или из-за неполной обработки трансляций найдут уязвимость. И самое главное, те, кому надо NAT-ить over 20G наврядли возжелают становится подопытными хомяками. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
kisa Опубликовано 19 декабря, 2016 (изменено) · Жалоба достаточно посмотреть в код netfilter, чтобы понять, что NAT в его правильной реализации - очень нетривиальная штука. На синтетических тестах работает что угодно, а если пнуть в продакшн "недоNAT", но юзеры сьедят с потрохами, когда nat pinning перестанет работать, или из-за неполной обработки трансляций найдут уязвимость. Так откройте код NPF, он в паблике. Оцените его тривиальность. И самое главное, те, кому надо NAT-ить over 20G наврядли возжелают становится подопытными хомяками. Чтобы отладить корректность кода не всегда нужна максимальная нагрузка. Корректная работа на нескольких g в реальной среде, плюс синтетик стресс тесты на максимальной скорости. Этого будет вполне достаточно. Изменено 19 декабря, 2016 пользователем kisa Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
Ivan_83 Опубликовано 19 декабря, 2016 · Жалоба Какие еще 100Г? :) rdp.ru такое запилили. Но железо там не десктопное, софт как раз на дпдк. Причем тут местная специфика? Притом что матчить стринги и красить трафик далеко не всем нужно, а если делать это вместе с натом то у тебя кеш вымывается быстрее и производительность проседает. Ну и полисинги/шейперы тоже роняют производительность. То что ты это делаешь и как делаешь это и есть твоя локальная специфика. Я не против, но без всего этого чисто НАТ на дпдк реально может выдавать сильно больше 20г. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
infery Опубликовано 19 декабря, 2016 · Жалоба Еще бы конфиг человичий, чтобы понятно было не только разработчику на DPDK. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
kisa Опубликовано 19 декабря, 2016 · Жалоба Еще бы конфиг человичий, чтобы понятно было не только разработчику на DPDK. А какие моменты непонятны? можно примеров? Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
infery Опубликовано 19 декабря, 2016 (изменено) · Жалоба А какие моменты непонятны? можно примеров? Можно как-то обходиться без этого, например? -w 0000:01:00.0 -w 0000:01:00.1 Было бы здорово просто указать eth[1-9]. Почему бы автоматически не биндиться на ядра. Или как оно там. --lcores='0@0,1@1,2@2,3@3' Для вас, наверняка, эти вещи очевидны, т.к. вы с DPDK плотно работает. А мне нужно просто запустить высокопроизводительный роутер, например. Что за "@"? Set the hexadecimal bitmask of the cores to run on. Нельзя просто номер ядра указать? Например, открыл htop, увидел 8 ядер. Забиндил на 1,3,5,7, если уж на то пошло. Вы написали такую крутую штуку, но вот маску она сама вычислить не может? Круто было бы сделать аля-циско - применения то схожи. Изменено 19 декабря, 2016 пользователем infery Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
Ivan_83 Опубликовано 19 декабря, 2016 · Жалоба Я дпдк в глаза не видел, но предположу. Было бы здорово просто указать eth[1-9]. Возможно дпдк цепляется не к сетевухам как они в ОС, а к сетевухам как они по слотам распиханы. А учитывая что линух номера в eth раздаёт как бык поссал то перевод eth в pci будет весьма не тривиальной задачей. Почему бы автоматически не биндиться на ядра. Или как оно там. Потому что может быть запущено несколько экземпляров на разных адаптерах и их лучше разносить. Опять же автоматически это делать можно но код ещё надо родить и отладить для таких случаев. Нельзя просто номер ядра указать? Например, открыл htop, увидел 8 ядер. Забиндил на 1,3,5,7, если уж на то пошло. Вы написали такую крутую штуку, но вот маску она сама вычислить не может? А если у тебя 2 проца физически по 4 ядра и 8 потоков каждый, как ты будешь биндить? Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
kisa Опубликовано 19 декабря, 2016 · Жалоба Это параметры самого dpdk. Да, вы правы, форма их описания не самая удобная. Но они хорошо документированы в пользовательской документации dpdk. Пока планов добавлять сюда синтаксического сахара нет, т.к. проект на стадии, когда им будут пользоваться люди с опытом и желанием экспериментировать. Свой конфиг я старался делать как можно более читаемым. Теперь по самим параметрам: -w 0000:01:00.0 -w 0000:01:00.1 эти параметры можно вообще не указывать, но если все-таки надо точно указать какие карты использовать, то никуда не дется. Даже в линуксе порой приходится писать правила udev, прежде чем появятся красивые имена eth1 привязанные именно к нужным сетевухам в нужной последовательности. --lcores='0@0,1@1,2@2,3@3' это строка обозначает карту привязок внутренних ядер (lcore) dpdk к ядрам реального процессора. 0@0 значит привязать lcore c номером 0 к cpu ядру 0. далее, в моем конфиге я оперирую lcore, а не процессорными ядрами. да, маску можно было и рассчитать, тут я согласен. если проект взлетит, то обещаю никого не обижать необходимостью рассчета масок. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
infery Опубликовано 19 декабря, 2016 · Жалоба kisa, Ivan_83, спасибо, что растолковали Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
nuclearcat Опубликовано 19 декабря, 2016 · Жалоба Так откройте код NPF, он в паблике. Оцените его тривиальность. Да, серьезно, согласен. Но вот если посмотреть npf_nat_create: mutex_enter(&np->n_lock); LIST_INSERT_HEAD(&np->n_nat_list, nt, nt_entry); mutex_exit(&np->n_lock); Ну и во многих других местах - сплошные mutex. Интересно насколько это повлияет на CPS. Я в DPDK не вникал совершенно, пишут что у них l-threads, и все отличается от тех же pthreads. Чтобы отладить корректность кода не всегда нужна максимальная нагрузка. Корректная работа на нескольких g в реальной среде, плюс синтетик стресс тесты на максимальной скорости. Этого будет вполне достаточно. Я вот как раз сейчас столкнулся с проблемой, которую разработчики netfilter воспроизвести не могут. Всплывает исключительно на >15G реального траффика, 1-4 раз в день. На синтетике, и на меньших нагрузках не всплывает. Возможно и не сетевой код, а что-то в таймерах поломали. Сначала разработчики не отвечали, но т.к. opensource - навставлял костылей, чтобы не падало и нашел более-менее стабильный вариант. rdp.ru такое запилили. Но железо там не десктопное, софт как раз на дпдк. Оно не то что не десктопное, а судя по их сайту оно как раз тщательно отобранное из серверного, или возможно кастомное. И именно затраченные усилия и средства на тестирование выливаются в стоимость решения. Судя по всему они еще и неплохо сертифицировались. Если делается opensource решение - то да, можно всем вместе отлаживать, и этим снизить конечную цену внедрения до очень приемлимой. При этом вполне можно зарабатывать, допиливая в софт хотелки пользователей, которые платежеспособны. Но когда это закрытое решение - то требования совершенно другие. На каждый чих или баг нужно заглядывать в рот автору, так как ни костылик не поставить, ни подправить функционал с багом. Притом что матчить стринги и красить трафик далеко не всем нужно, а если делать это вместе с натом то у тебя кеш вымывается быстрее и производительность проседает. Ну и полисинги/шейперы тоже роняют производительность. То что ты это делаешь и как делаешь это и есть твоя локальная специфика. Я не против, но без всего этого чисто НАТ на дпдк реально может выдавать сильно больше 20г. Если opensource проект - всеми руками за, по мере возможностей, если совпадает с рабочими интересами(т.е. есть где тестить) - стараюсь вносить свой вклад. Хотя как по мне, лучше пилить vanilla, там проблемой производительности сейчас очень плотно занимаются и разработчики отзывчивые. А полудоделанные проприетарные BRAS-ы "потестите бинарник" здесь всплывают с закономерным результатом. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
kisa Опубликовано 19 декабря, 2016 · Жалоба Так откройте код NPF, он в паблике. Оцените его тривиальность. Да, серьезно, согласен. Но вот если посмотреть npf_nat_create: mutex_enter(&np->n_lock); LIST_INSERT_HEAD(&np->n_nat_list, nt, nt_entry); mutex_exit(&np->n_lock); Ну и во многих других местах - сплошные mutex. Интересно насколько это повлияет на CPS. Для этого я и делал тесты. И производительностью я пока доволен. Если NPF окажется еще стабильным, то можно будет затеять второй раунд оптимизаций и т.д. Первый цикл c NPF я уже закончил. Нашел несколько серьезных багов, отправил их автору NPF. Переписал его ядро хранения сессий, оптимизировав его для ipv4, а затем и переведя на очень производительные cackoo кэши. Я в DPDK не вникал совершенно, пишут что у них l-threads, и все отличается от тех же pthreads. Никаких отличий нет. l-thread это обычные pthread, прибитые к cpu core. Чтобы отладить корректность кода не всегда нужна максимальная нагрузка. Корректная работа на нескольких g в реальной среде, плюс синтетик стресс тесты на максимальной скорости. Этого будет вполне достаточно. Я вот как раз сейчас столкнулся с проблемой, которую разработчики netfilter воспроизвести не могут. Всплывает исключительно на >15G реального траффика, 1-4 раз в день. На синтетике, и на меньших нагрузках не всплывает. Возможно и не сетевой код, а что-то в таймерах поломали. Сначала разработчики не отвечали, но т.к. opensource - навставлял костылей, чтобы не падало и нашел более-менее стабильный вариант. Ну так это скорей исключительная ситуация. При этом вполне можно зарабатывать, допиливая в софт хотелки пользователей, которые платежеспособны. Но когда это закрытое решение - то требования совершенно другие. На каждый чих или баг нужно заглядывать в рот автору, так как ни костылик не поставить, ни подправить функционал с багом. Если opensource проект - всеми руками за, по мере возможностей, если совпадает с рабочими интересами(т.е. есть где тестить) - стараюсь вносить свой вклад. Хотя как по мне, лучше пилить vanilla, там проблемой производительности сейчас очень плотно занимаются и разработчики отзывчивые. А полудоделанные проприетарные BRAS-ы "потестите бинарник" здесь всплывают с закономерным результатом. Решение еще не принятно, возможно, это будет именно opensource. Возможно нет. Я не спешу. За этим сюда и пришел выслушать мнения. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
kisa Опубликовано 19 декабря, 2016 · Жалоба Но когда это закрытое решение - то требования совершенно другие. На каждый чих или баг нужно заглядывать в рот автору, так как ни костылик не поставить, ни подправить функционал с багом. Как вариант - выдача исходников по запросу. Уже сейчас 2 трети проекта opensource - NPF и DPDK. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
nuclearcat Опубликовано 19 декабря, 2016 · Жалоба Для этого я и делал тесты. И производительностью я пока доволен. Если NPF окажется еще стабильным, то можно будет затеять второй раунд оптимизаций и т.д. Первый цикл c NPF я уже закончил. Нашел несколько серьезных багов, отправил их автору NPF. Переписал его ядро хранения сессий, оптимизировав его для ipv4, а затем и переведя на очень производительные cackoo кэши. Насколько я помню mutex при создании каждого соединения - это очень плохо для производительности. Надо смотреть весь код, чтобы сказать точно, но определенно не вижу там никакого группирования. Ну так это скорей исключительная ситуация. Сколько я писал в netdev@, а сейчас чаще лично авторам коммитов - скорее типичная. Тот же гугль очень тщательно гоняет патчи у себя в сети, но к примеру (давно было) баг с BQL как не старались, воспроизвести не могли, ходили по ssh ко мне на сервер и там отлаживали, хотя им такое юристы крайне не рекомендуют, чужие сервера трогать. Еще был случай с утечкой памяти в tcp, вылезал только на активно теряющих пакеты (wireless линки) множестве юзеров и 1+m коннектов на https балансировщик. Были как минимум два CVE всплывшие опять же у меня , https://vuldb.com/?id.12480 , https://bugzilla.redhat.com/show_bug.cgi?id=567530 Только я еще имею возможность и желание повыпрашивать помощи и что-то починить сам, а многие или английский не знают, или стесняются, или просто не хотят морочится, просто забивают после серьезных глюков и переходят на другие решения. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
kisa Опубликовано 19 декабря, 2016 · Жалоба Насколько я помню mutex при создании каждого соединения - это очень плохо для производительности. Надо смотреть весь код, чтобы сказать точно, но определенно не вижу там никакого группирования. Locks Aren't Slow; Lock Contention Is http://preshing.com/20111118/locks-arent-slow-lock-contention-is/ Сколько я не думал о том, как избавиться в NAT от shared структур и как следствие каких-либо защитных механизмов (не суть важно lockless или lock), т.е. фактически о шардинге, как это мне предлагал Русикевичус (автор NPF), никаких идеально красивых решений я не находил. Так или иначе, пока несколько ядер пытаются использовать один ресурс (это IP подсеть или один IP c их диапазонов портов) нужны механизмы защиты. Самый идеальный случай на каждую исходящую очередь и ядро к ней прибитое, выдавать свои внешние IP, в которые натить, тогда, вероятно, можно создать много conntrackdb шардов непересекающихся между собой и избавиться от таких блокировок, но все равно они вылезут в других местах. А о каком группировании речь? Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
kisa Опубликовано 19 декабря, 2016 · Жалоба Да, серьезно, согласен. Но вот если посмотреть npf_nat_create: mutex_enter(&np->n_lock); LIST_INSERT_HEAD(&np->n_nat_list, nt, nt_entry); mutex_exit(&np->n_lock); Похоже, вы смотрите родной репозиторий, смотрите мой форк https://github.com/alexk99/npf Там эта блокировка тоже есть. Но там есть и все оптимизации, о которых я говорил. Код очень простой. Начинать лучше npf_packet_handler(), потом если интерес не пропадет, можно глянуть npf_packet_handler_vec(). Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
nuclearcat Опубликовано 19 декабря, 2016 · Жалоба Я не заметил, чтобы ваш репозиторий отличался от оригинального, последний коммит в вашем форке 2 июня, как и в оригинальном. npf_packet_handler_vec там нет Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
kisa Опубликовано 19 декабря, 2016 · Жалоба Я не заметил, чтобы ваш репозиторий отличался от оригинального, последний коммит в вашем форке 2 июня, как и в оригинальном. npf_packet_handler_vec там нет branch alexk Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
Ivan_83 Опубликовано 19 декабря, 2016 · Жалоба Не смотрел код просто напишу. Чтобы избежать глобального лока при добавлении сессии или работе с ней берётся то что сейчас есть и создаётся массив вот таких списков с локами на каждый. Дальше на каждый пакет исходя из адресов высчитывается индекс в этом массиве (обычно по хэшу какомунить, быстрому/простому), по индексу берётся список с локом и от туда/туда кидается сессия. Чем больше массив - тем меньше вероятность что два потока наткнутся на взаимную блокировку. Элемент массива часто называется корзиной (bucket). Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
pavel.odintsov Опубликовано 20 декабря, 2016 · Жалоба Куда-то вы друзья в дебри ушли, линии кэша, коллизии хэшей, MPPS'ы... для роутера главное чтобы на нем лампочки моргали да коробка красивая была, это уже 90% успеха. Если коробочки красивой нету, то об чем речь? Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
kisa Опубликовано 20 декабря, 2016 (изменено) · Жалоба Не смотрел код просто напишу. Вот очень зря. Код NPF написан для NetBSD (включен в боевое ядро) и совсем не делитантом. Это надо брать в рассчет считая, что его автор натыкался на простейшие грабли, не зная примитивных способов обойти использование блокировок. Чтобы избежать глобального лока при добавлении сессии или работе с ней берётся то что сейчас есть и создаётся массив вот таких списков с локами на каждый. Дальше на каждый пакет исходя из адресов высчитывается индекс в этом массиве (обычно по хэшу какомунить, быстрому/простому), по индексу берётся список с локом и от туда/туда кидается сессия. Чем больше массив - тем меньше вероятность что два потока наткнутся на взаимную блокировку. Элемент массива часто называется корзиной (bucket). Это описание обычного классического хэша. У них огромное количество проблем. Мне больше нравятся хэши с открытой адресацией. Например, cuckoo. Потом блокировка, которую вы начали обсуждать, защищает список, который носит вспомогательный характер и не участвует в так называемом fast path. Эта блокировка очень короткая по времени, что в сочетании со spinlock реализацией влияет, но не думаю, что критично на производительность, иначе бы тесты warp17 не проходили. А в них скорость создания сессий была приличная. Если уж и идти дальше по пути оптимизации NPF, то эта блокировка может быть убрана. Но надо рассказать о том, что она делает, чтобы понять способ обхода ее. Блокировка защищает список сессий одного типа nat policy. Когда это тип будет удален, должны быть удалены и все сессии этого типа. Удаление типов nat policy очень редкое событие, происходит например, когда меняется конфиг и правило нат удаляется. Исходя из этого, чтобы избежать гонок (race/contention) во время добавления сессии, вместо одного списка нужно использовать N списков, где N количество рабочих потоков (lcore). Каждый поток будет сохранять свои сессии в свой список. Таким образом race/contention будет исключен, т.к. потоки не будут соперничать за один и тот же список. Код удаления должен будет пробежаться по всем спискам, чтобы найти все сессии всех рабочих потоков. Ну и в заключении, чтобы N рабочих потоков, добавляющих сессии, не конфликтовали с кодом удаления в простейшем случае можно добавить exсlusive/shared блокировку. Все рабочие потоки используют shared блокировку, код удаления exclusive. Т.к. использование shared блокировки - вообще ничего не стоит, это фактически инкремент, то проблема решена. Остаются редкие случаи удаления правил, которые будут вносит exlusive срабатывания, тогда ожидания неизбежны, но это случай удаления nat правила из конфига - очень редкое событие. Изменено 20 декабря, 2016 пользователем kisa Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
pavel.odintsov Опубликовано 20 декабря, 2016 (изменено) · Жалоба А что кстати на тему поддержки NAT helpers для ftp, sip и pptp и реассемблинга IPv4 фрагментов? Изменено 20 декабря, 2016 пользователем pavel.odintsov Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...