This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
software:freebsd:igmpproxy_on_netgraph [2015/05/14 10:09] – [История] root | software:freebsd:igmpproxy_on_netgraph [2022/02/05 05:30] (current) – root | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== | + | ====== igmpproxy |
Скрипт собирающий netgraph мост для мультикаст трафика (IGMP, UDP) между двумя сетевыми интерфейсами предназначен для замены igmpproxy/ | Скрипт собирающий netgraph мост для мультикаст трафика (IGMP, UDP) между двумя сетевыми интерфейсами предназначен для замены igmpproxy/ | ||
- | + | [[http:// | |
- | [url=http:// | + | |
Обсуждения: | Обсуждения: | ||
- | [url=http:// | + | [[http:// |
- | [url=http:// | + | [[http:// |
Line 13: | Line 12: | ||
Создать мост между em0 и re0, где re0 подключён к сети с мультикастом: | Создать мост между em0 и re0, где re0 подключён к сети с мультикастом: | ||
< | < | ||
- | или | + | или |
< | < | ||
- | если нужно чтобы трафик попадал в сетевой стёк ОС, как было до установки моста. | ||
Удалить мост: | Удалить мост: | ||
< | < | ||
- | |||
- | |||
- | ===== История ===== | ||
- | igmpproxy и mrouted у меня работать отказались, | ||
- | - **IGMP** на multicast адреса из локалки в сеть провайдера и обратно; | ||
- | - **UDP** на multicast адреса из сети провайдера в локалку. Броадкаст не нужен, и направляется в ядро как обычно.\\ | ||
- | |||
- | Несмотря на цифру 2, по сути эта третья версия графа, получившая в результате оптимизации первых двух.\\ | ||
- | * Первая содержала **ng_ether**, | ||
- | * Вторая содержала **ng_ether**, | ||
- | * Окончательная содержит: | ||
- | В первых двух версиях создавалась копия пакета, | ||
- | * Добавлено опционально использование **ng_hub** - для режима когда мультикаст/ | ||
- | |||
===== Принцип работы ===== | ===== Принцип работы ===== | ||
- | {{:ru: | + | ==== netgraph ==== |
+ | Его можно сравнить с LUA: он даёт широкие возможности по манипуляции с сетевыми пакетами, | ||
+ | У меня было много разных вариантов но в конце мне удалось свести количество нод к двум: **ng_ether** и **ng_bpf**.\\ | ||
+ | **ng_ether** — имеет несколько хуков: __lower__ — это вход/ | ||
+ | **ng_bpf** — программируемая нода, общий смысл программ: | ||
+ | Не большая хитрость ноды в том, что программа устанавливается на входную ноду. Но ноды которые указаны как выходные тоже могут принимать пакеты и обрабатывать они их будут по тем программам которые ассоциированы с ними.\\ | ||
+ | |||
+ | ==== Передача пакетов ==== | ||
+ | {{software: | ||
**BPF** настроен таким образом чтобы пропускать все без исключения пакеты с __upper__ хуков **ng_ether** нод на __lower__ хуки (пакеты от системы в сеть). Приходящие из сети пакеты с __lower__ хуков нод проверяются в **BPF**, и\\ | **BPF** настроен таким образом чтобы пропускать все без исключения пакеты с __upper__ хуков **ng_ether** нод на __lower__ хуки (пакеты от системы в сеть). Приходящие из сети пакеты с __lower__ хуков нод проверяются в **BPF**, и\\ | ||
- если это мультикаст; | - если это мультикаст; | ||
Line 45: | Line 37: | ||
- | ===== Тонкости ===== | + | ==== Фильтры |
- | 1. Пришлось включить **promisc** режим на обоих интерфейсах, иначе | + | IGMP (IPv4) подпадает под такой фильтр в tcpdump: |
+ | < | ||
+ | где:\\ | ||
+ | **ether[0] & 1 = 1** — проверяем первый байт эзернет пакета, там dst mac адрес, если его первый бит = 1 то пакет multicast или broadcast\\ | ||
+ | **(ether[0:4] != 0xffffffff or ether[4:2] != 0xffff)** — здесь проверяем что dst mac пакета | ||
+ | **ip[9] = 2** — Проверяем что IP proto = IGMP\\ | ||
+ | **ether** — означает что смещение и длинна считаются относительно эзернет заголовка, при этом | ||
+ | ip — это смещение относительно эзернет заголовка, примерно эквивалентно: ip[9] = ether[23], где 23 = 14 + 9, 14 — размер эзернет заголовка. Ещё оно проверяет что ether[12:2] = IP.\\ | ||
+ | В случае инкапсуляции в VLAN придётся переписывать условия.\\ | ||
- | 2. Пришлось включить **autosrc** | + | Теперь получим ассемблерный код для bpf: |
+ | < | ||
+ | (имя интерфейса указывать не обязательно, | ||
+ | < | ||
+ | 48 0 0 0 | ||
+ | 84 0 0 1 | ||
+ | 21 0 9 1 | ||
+ | 32 0 0 0 | ||
+ | 21 0 2 4294967295 | ||
+ | 40 0 0 4 | ||
+ | 21 5 0 65535 | ||
+ | 40 0 0 12 | ||
+ | 21 0 3 2048 | ||
+ | 48 0 0 23 | ||
+ | 21 0 1 2 | ||
+ | 6 0 0 65535 | ||
+ | 6 0 0 0</ | ||
+ | Это и нужно скармливать в ng_bpf чтобы отделить IGMP (IPv4) от всего остального.\\ | ||
+ | |||
+ | IGMP (IPv4) + UDP (IPv4) в tcpdump: | ||
+ | < | ||
+ | Всё аналогично, ip[9] = 17 — IP proto = UDP.\\ | ||
+ | |||
+ | И чтобы | ||
+ | < | ||
+ | Это одно строчная «программа» для BPF всегда возвращает NotMatch. | ||
+ | |||
+ | |||
+ | ==== Тонкости ==== | ||
+ | 1. Адаптеры нужно перевести в «не | ||
+ | < | ||
+ | |||
+ | 2. autosrc на WAN интерфейсе | ||
+ | < | ||
3. Моему провайдеру нет дела до того какой src-ip в IP приходит от меня, если бы было, то я бы попробовал гнать трафик в сторону провайдера через **ng_patch** ноду, которая бы заменяла src-ip на нужны, и выставляла CSUM_IP и CSUM_UDP в заголовке пакета - есть шанс что драйвер сетевого адаптера сам рассчитает эти суммы либо что оборудование провайдера проигнорирует неверную контрольную сумму в IGMP пакетах от меня. Нода также подключается обоими хуками к BPF, выход настраивается на passtrouth (пересылку всех пакетов) на __lower__ хук __ng_ether__ на адаптере в сети провайдера, | 3. Моему провайдеру нет дела до того какой src-ip в IP приходит от меня, если бы было, то я бы попробовал гнать трафик в сторону провайдера через **ng_patch** ноду, которая бы заменяла src-ip на нужны, и выставляла CSUM_IP и CSUM_UDP в заголовке пакета - есть шанс что драйвер сетевого адаптера сам рассчитает эти суммы либо что оборудование провайдера проигнорирует неверную контрольную сумму в IGMP пакетах от меня. Нода также подключается обоими хуками к BPF, выход настраивается на passtrouth (пересылку всех пакетов) на __lower__ хук __ng_ether__ на адаптере в сети провайдера, | ||
4. Работает на vlan интерфейсах. | 4. Работает на vlan интерфейсах. | ||
+ | |||
+ | |||
+ | ===== История ===== | ||
+ | igmpproxy и mrouted у меня работать отказались: | ||
+ | < | ||
+ | а я этого не сделал.\\ | ||
+ | После нескольких часов проб, чтения и новых проб я решил не заниматься ремонтом ядра и этих приложений, | ||
+ | * **IGMP** на multicast адреса из локалки в сеть провайдера и обратно; | ||
+ | * **UDP** на multicast адреса из сети провайдера в локалку. Броадкаст не нужен, и направляется в ядро как обычно. | ||
+ | |||
+ | Несмотря на цифру 2, по сути эта третья версия графа, получившая в результате оптимизации первых двух.\\ | ||
+ | * Первая содержала **ng_ether**, | ||
+ | * Вторая содержала **ng_ether**, | ||
+ | * Окончательная содержит: | ||
+ | В первых двух версиях создавалась копия пакета, | ||
+ | * Добавлено опционально использование **ng_hub** - для режима когда мультикаст/ | ||
Line 58: | Line 107: | ||
===== PS ===== | ===== PS ===== | ||
Для создания аналогичного по функционалу моста, в котором будет несколько сетевых интерфейсов в разных сетях с мультикастом и несколько сетевых адаптеров в сетях куда его нужно переправить потребуется на каждый сетевой адаптер вешать по **ng_split** + **ng_one2many** и по одной **ng_one2many** с каждой стороны моста для рассылки копий мультикаста на все интерфейсы. __upper__ хуки **ng_ether** нод по прежнему будут напрямую подключатся к BPF. В случае нескольких сетей - источников мультикаста будет ещё проблема с возможным перекрытием адресных пространств, | Для создания аналогичного по функционалу моста, в котором будет несколько сетевых интерфейсов в разных сетях с мультикастом и несколько сетевых адаптеров в сетях куда его нужно переправить потребуется на каждый сетевой адаптер вешать по **ng_split** + **ng_one2many** и по одной **ng_one2many** с каждой стороны моста для рассылки копий мультикаста на все интерфейсы. __upper__ хуки **ng_ether** нод по прежнему будут напрямую подключатся к BPF. В случае нескольких сетей - источников мультикаста будет ещё проблема с возможным перекрытием адресных пространств, | ||
+ | |||
+ | |||
+ | ===== Ссылки ===== | ||
+ | [[http:// | ||
+ | [[http:// | ||
+ | [[http:// | ||
+ | [[http:// | ||
+ | |||
+ | |||
+ | |||
+ | {{tag> |