URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID3
Нить номер: 81792
[ Назад ]

Исходное сообщение
"Раздел полезных советов: Multicast во FreeBSD без igmpproxy"

Отправлено auto_tips , 12-Дек-11 14:33 
Иван Рожук опубликовал скрипт [[http://www.netlab.linkpc.net/download/software/FreeBSD/mcast... mcastbr2.sh]] для проброса multicast через шлюз на базе FreeBSD штатными средствами netgraph, без использования неработающих у многих igmpproxy и mrouted.

   #!/bin/sh

   # Copyright (c) 2011 Rozhuk Ivan <rozhuk.im@gmail.com>
   # All rights reserved.
   #
   # Subject to the following obligations and disclaimer of warranty, use and
   # redistribution of this software, in source or object code forms, with or
   # without modifications are expressly permitted by Whistle Communications;
   # provided, however, that:
   # 1. Any and all reproductions of the source or object code must include the
   #    copyright notice above and the following disclaimer of warranties; and
   # 2. No rights are granted, in any manner or form, to use Whistle
   #    Communications, Inc. trademarks, including the mark "WHISTLE
   #    COMMUNICATIONS" on advertising, endorsements, or otherwise except as
   #    such appears in the above copyright notice or in the software.
   #
   # THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
   # TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
   # REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
   # INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
   # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
   # WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
   # REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
   # SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
   # IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
   # RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
   # WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
   # PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
   # SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
   # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   # THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
   # OF SUCH DAMAGE.
   #
   # Author: Rozhuk Ivan <rozhuk.im@gmail.com>
   #
   # $FreeBSD: src/sys/netgraph/ng_l2ccp.c,v 1.0.0.1 2010/09/19 08:13:06 kensmith Exp $


   # This script create bridge between two network interfaces
   # downstream - network with clients
   # upstream - network with multicast
   # downstream <-IGMP-> upstream
   # downstream <-UDP<- upstream
   # only packets with multicast dst mac addr forwarded trouth bridge and (!) not pass to network stack

   IF_UPSTREAM="$2"
   IF_DOWNSTREAM="$3"
   BR_NAME="${IF_UPSTREAM}-${IF_DOWNSTREAM}-br"
   PATTERN_MCAST_IGMP="ether[0] & 1 = 1 and (ether[0:4] != 0xffffffff or ether[4:2] != 0xffff) and ip[9] = 2"
   PATTERN_MCAST_IGMP_UDP="ether[0] & 1 = 1 and (ether[0:4] != 0xffffffff or ether[4:2] != 0xffff) and (ip[9] = 17 or ip[9] = 2)"
   # allways NOT MATCH
   BPFPROG_PASSTOUTH="bpf_prog_len=1 bpf_prog=[ { code=6 jt=0 jf=0 k=0 } ]"


   usage_msg()
   {
   echo "usage: start|stop upstreamIF downstreamIF1"
   echo "This create bridge beetwen two IFs for IGMP, and UDP from upstreamIF to downstreamIF1"
   }


   if [ -z "${IF_UPSTREAM}" -o -z "${IF_DOWNSTREAM}" ]; then
   usage_msg
   return 1
   fi
   if ! ifconfig "$IF_UPSTREAM" > /dev/null 2>&1 ; then
   usage_msg
   echo "Invalid upstream interface: ${IF_UPSTREAM}"
   return 1
   fi
   if ! ifconfig "$IF_DOWNSTREAM" > /dev/null 2>&1 ; then
   usage_msg
   echo "Invalid downstream interface: ${IF_DOWNSTREAM}"
   return 1
   fi


   case "$1" in
   start)
   # load modules
   kldload ng_ether > /dev/null 2>&1
   kldload ng_bpf > /dev/null 2>&1

   echo "start bridging beetwen ${IF_UPSTREAM} and ${IF_DOWNSTREAM}"

   BPFPROG_MCAST_IGMP=$( tcpdump -s 65535 -ddd ${PATTERN_MCAST_IGMP} | \
   ( read len ; \
   echo -n "bpf_prog_len=$len " ; \
   echo -n "bpf_prog=[" ; \
   while read code jt jf k ; do \
     echo -n " { code=$code jt=$jt jf=$jf k=$k }" ; \
   done ; \
   echo " ]" ) )

   BPFPROG_MCAST_IGMP_UDP=$( tcpdump -s 65535 -ddd ${PATTERN_MCAST_IGMP_UDP} | \
   ( read len ; \
   echo -n "bpf_prog_len=$len " ; \
   echo -n "bpf_prog=[" ; \
   while read code jt jf k ; do \
     echo -n " { code=$code jt=$jt jf=$jf k=$k }" ; \
   done ; \
   echo " ]" ) )

   # create and connect nodes
   ngctl mkpeer ${IF_UPSTREAM}: bpf lower ${IF_UPSTREAM}-lower
   ngctl name ${IF_UPSTREAM}:lower ${BR_NAME}-bpf
   ngctl connect ${IF_UPSTREAM}: ${BR_NAME}-bpf: upper ${IF_UPSTREAM}-upper
   ngctl connect ${IF_DOWNSTREAM}: ${BR_NAME}-bpf: lower ${IF_DOWNSTREAM}-lower
   ngctl connect ${IF_DOWNSTREAM}: ${BR_NAME}-bpf: upper ${IF_DOWNSTREAM}-upper

   # configure BPF node
   ngctl msg ${BR_NAME}-bpf: setprogram { thisHook=\"${IF_UPSTREAM}-lower\" ifMatch=\"${IF_DOWNSTREAM}-lower\" ifNotMatch=\"${IF_UPSTREAM}-upper\" ${BPFPROG_MCAST_IGMP_UDP} }
   ngctl msg ${BR_NAME}-bpf: setprogram { thisHook=\"${IF_UPSTREAM}-upper\" ifMatch=\"\" ifNotMatch=\"${IF_UPSTREAM}-lower\" ${BPFPROG_PASSTOUTH} }
   ngctl msg ${BR_NAME}-bpf: setprogram { thisHook=\"${IF_DOWNSTREAM}-lower\" ifMatch=\"${IF_UPSTREAM}-lower\" ifNotMatch=\"${IF_DOWNSTREAM}-upper\" ${BPFPROG_MCAST_IGMP} }
   ngctl msg ${BR_NAME}-bpf: setprogram { thisHook=\"${IF_DOWNSTREAM}-upper\" ifMatch=\"\" ifNotMatch=\"${IF_DOWNSTREAM}-lower\" ${BPFPROG_PASSTOUTH} }

   # configure net if
   ngctl msg ${IF_UPSTREAM}: setautosrc 1
   ngctl msg ${IF_UPSTREAM}: setpromisc 1
   #ngctl msg ${IF_DOWNSTREAM}: setautosrc 0
   ngctl msg ${IF_DOWNSTREAM}: setpromisc 1
   ;;
   stop)
   echo "stop"
   # remove hooks and nodes
   ngctl rmhook ${IF_UPSTREAM}: lower
   ngctl rmhook ${IF_UPSTREAM}: upper
   ngctl rmhook ${IF_DOWNSTREAM}: lower
   ngctl rmhook ${IF_DOWNSTREAM}: upper
   ngctl shutdown ${BR_NAME}-bpf:

   # unload modules
   #kldunload ng_ether > /dev/null 2>&1
   #kldunload ng_bpf > /dev/null 2>&1
   ;;
   *)
   usage_msg
   esac


   return 0


Суть скрипта: между интерфейсами (ng_ether) создается подобие бриджа с ng_bpf посередине, который пропускает через себя только мультикаст. Причем эти пакеты проходят полностью в обход сетевого стека.

URL: http://vadimnuclight.ya.ru/replies.xml?item_no=18
Обсуждается: http://www.opennet.me/tips/info/2649.shtml


Содержание

Сообщения в этом обсуждении
"Multicast во FreeBSD без igmpproxy"
Отправлено Bocha , 12-Дек-11 14:33 
nuclight, привет и спасибо тебе и Ивану за скрипт. Не хочу показаться невежливым, но может вам помочь перевести фразы на нормальный английский, а то пока читал - рыдал, но это никак не умаляет качества самого скрипта, разумеется.

"Multicast во FreeBSD без igmpproxy"
Отправлено Ivan_83 , 14-Дек-11 15:40 
Конечно помогайте, у меня с английским не очень.

"Multicast во FreeBSD без igmpproxy"
Отправлено Bocha , 15-Дек-11 07:49 
Собственно, вам надо три строчки заменить:
- # This script create bridge between two network interfaces
+ # This script creates bridge between two network interfaces

- # only packets with multicast dst mac addr forwarded trouth bridge and (!) not pass to network stack
+ # only packets with multicast destination mac address are forwarded through the bridge and (!) are not passed to network stack

- echo "This create bridge beetwen two IFs for IGMP, and UDP from upstreamIF to downstreamIF1"
+ echo "This will create bridge between two interfaces for IGMP, and UDP from upstreamIF to downstreamIF1"


"Multicast во FreeBSD без igmpproxy"
Отправлено Ivan_83 , 15-Дек-11 20:04 
> Собственно, вам надо три строчки заменить:

Благодарю, пофиксил



"Multicast во FreeBSD без igmpproxy"
Отправлено omn , 12-Дек-11 17:53 
Спасибо за нормальную реализацию мультикаста! :)

"Multicast во FreeBSD без igmpproxy"
Отправлено dvg , 12-Дек-11 19:40 
nuclight, ты как обычно нереально крут! Даже мысли не было что это можно реализовать на нетграфе, казалось там все очень сложно.

"Multicast во FreeBSD без igmpproxy"
Отправлено dvg , 12-Дек-11 19:41 
Да, кстати автору, Ивану, огромный решпект.

"Multicast во FreeBSD без igmpproxy"
Отправлено 34567 , 13-Дек-11 11:35 
Красиво, но, собственно, вопрос - а как быть с подпиской? multicast join пакеты будут уходить с src-адресом в downstream подсети до которой в ПИМ нет маршрута.

"Multicast во FreeBSD без igmpproxy"
Отправлено Ivan_83 , 14-Дек-11 15:52 
PIM в деталях не знаю.
У меня ситуация такая: на внешнем интерфейсе ip нет (арп зафильтрован тоже), инет по PPPoE, порт.сек. пропускает через порт только один мак. Поэтому у меня ng_ether на внешнем интерфейсе подставляет свой мак, вместо маков с локалки.
Если требуется чтобы на внешку улетал определённый src-ip то можно подключить ng_patch двумя хуками к ng_bpf и перенаправить пакеты в upstream через него, а в нём по оффсету менять 4 байта=ip-src, и ещё нужно выставить CSUM_IP (и CSUM_UDP?), если сетевуха поддерживает аппаратно их расчёт и/или если на принимающей стороне не проверяется контрольная сумма ip пакетов то всё будет работать и пакеты будут валится провайдеру не только с одного мак адреса но и с одного ip.
В моём случае прову пофик с какого IP летят пакеты, поскольку они могут лететь только на мультикаст адреса, а для мультикаста арп не нужен, там просто 4 байта IP адреса помешаются в старшие 4 байта MAC адреса.

"Multicast во FreeBSD без igmpproxy"
Отправлено 34567 , 15-Дек-11 12:34 
Хм... про патч, честно говоря, не думал... Я как-то пробовал нечто подобное когда сидел на корбилайне (мост с бпф), входящий мультикаст с видео проходил нормально, но подписка от плеера не работала, работало только если ручками mtest'ом цепляться к группе с роутера. А потом и пчелайн нешифрованое ТВ вырубил и я прова сменил. С патчем поэкспериментирую, спасибо.

"Multicast во FreeBSD без igmpproxy"
Отправлено Ivan_83 , 15-Дек-11 12:47 
Попробуйте в начале без ng_patch, может и так заработает.

"Multicast во FreeBSD без igmpproxy"
Отправлено FK , 15-Дек-11 14:05 
Вот-вот! Если по обе стороны Фри разные подсети, то без изменения IGMP-пакетов не обойтись. Суть igmpproxy, mrouted и проч. в том, что они ловят запросы подписки на внутренней подсети а поймав - подписывают уже роутер (Фрю) у аплинка. А вот приходящий мультикаст уже да, уже можно пробрасывать.

"Multicast во FreeBSD без igmpproxy"
Отправлено Ivan_83 , 15-Дек-11 19:57 
Это IP мания от не знания L2 :)
Мультикаст это L2. На какой интерфейс пришёл запрос подписки на тот и начинают лить мультикаст, на принадлежность IP к сетям не смотрит. Те IP адрес клиента в данном случае также "важен/нужен" как хостнейм в локалке.
У меня вообще один физ интерфейс, два влана между которыми я и бриджую мультикаст. Провайдер фильтрует ARP у себя, поэтому нет никакой разницы какой src-ip у меня будет, он не узнает мак куда слать, и не должен знать, а должен слать на мультикаст мак.
Суть mrouted в том, чтобы обеспечить функционал типа igmp snooping либо туннелирование мультикаста на другой такой же роутер но юникастом (там ещё протокол маршрутизации есть, но это когда несколько mrouted между собой общаются). Те mrouted знает где источники мультикаста, и где и какие потребители, и гоняет только нужный трафик через нужные интерфейсы. В случае с двумя интерфейсами принципиальной разницы не будет. Более того, mrouted заставит прописать хотя бы фейковые IP на интерфейсах.
Тут есть примеры:
http://www.netup.tv/ru-RU/configuring-igmp-in-lan-for-managi...
но клиентские IP там только для отчёту, как хостнейм в логах.

"Multicast во FreeBSD без igmpproxy"
Отправлено 34567 , 16-Дек-11 22:42 
Нет уж, сударь, позвольте...
Мультикаст L2 и мультикаст L3 это разные вещи, каждый на своем уровне. Мультикаст ip пакеты маршрутизируются также как и обычные ip unicast (ну почти так же). Они должны проходить сквозь роутеры на 3м уровне и роутеры должны поддерживать таблицы групмемберов. Для этого есть свои протоколы PIM-DM и PIM-SM, аналогично как для уникаста оспф. И также как и с уникастом если в АС нет пути до подсети источника/назначения, то "обратный" трафик не бегает. А роутеры обмениваются информацией только с тем кому доверяют (со своими). (Вы ведь не будите принимать оспф-анонсы c customer-подсетей? Поэтому им приходся ставить или прокси или роутер с НАТом, который прячет домашнюю подсеть. igmproxy для l3 играет роль НАТа если очень уж грубо выразиться. Он ловит игмп джоин на одном интерфейсе и ретранслирует джоин на туже группу со свого дургого интерфейса, со своим адресом источника. "Пропихивание" мультикаста сквозь бридж также не заменяет маршрутизации на 3м уровне как и "пропихивание" сквозь бридж ip-уникаста. Да, сниффером можно будет ловить пакеты соседних подсетей с "той стороны роутера", но с ними нельзя полноценно общаться. Фича мультикаста в том что "снифинга" собственно и достаточно чтобы получать то что тебе нужно от видео-потока.
Ситуция с вашим провом весьма интересна, возможно он просто не маршрутизирует мкаст трафик на 3м уровне и источник потока и подписчики (клиенты) находятся в одном Л2 бродкаст домене.
С пчелайна я ушел - сейчас поэкспериментировать "на живую" не на чем, разве что свою лабу сделать если времечко выйдет.

"Multicast во FreeBSD без igmpproxy"
Отправлено Ivan_83 , 18-Дек-11 21:29 
>[оверквотинг удален]
> интерфейсе и ретранслирует джоин на туже группу со свого дургого интерфейса,
> со своим адресом источника. "Пропихивание" мультикаста сквозь бридж также не заменяет
> маршрутизации на 3м уровне как и "пропихивание" сквозь бридж ip-уникаста. Да,
> сниффером можно будет ловить пакеты соседних подсетей с "той стороны роутера",
> но с ними нельзя полноценно общаться. Фича мультикаста в том что
> "снифинга" собственно и достаточно чтобы получать то что тебе нужно от
> видео-потока.
> Ситуция с вашим провом весьма интересна, возможно он просто не маршрутизирует мкаст
> трафик на 3м уровне и источник потока и подписчики (клиенты) находятся
> в одном Л2 бродкаст домене.

На уровне провайдера L3 - излишество. Проще мультикаст влан, и игмп снупинг, при этом мультикаст роутеры не нужны, и броадкаст домена для клиентов не образуется. Это всё делается на L2 коммутаторах, которым всё равно какой IP у джоин пакетов, им важно только с какого порта оно пришло.
Роутинг на L3, про который я читал, сводился к оптимальному выбору пути между роутерами для трафика.
Для меня мультикаст в L3 это просто набор костылей, позволяющий:
- намекнуть драйверу сетевухи какие DST MAC адреса принимать
- без использования ARP для преобразования DST IP в MAC посылать запросы сразу группе получателей.
Я не копал мультикаст код в ядре сколь нибудь глубоко (оно там вынесено отдельно, а меня интересовал базовый=основной функционал IP и ARP), потому что мультикаст на L2 прекрасно работает и так, а с мультикастом в чистом L3 (например через p2p туннели или инет) я не сталкивался.
...
L3 роутеры могут и дальше обмениваться маршрутами только со своими, но потом им приходит джоин от клиента, он приходит на определённый сетевой интерфейс, и роутер должен начать выплёвывать туда данные, а выплёвывать он их будет на мультикаст адрес - мультикаст MAC. Таким образом, нет разницы с какого IP и MAC пришёл запрос, в случае если это клиент подписывался. Разница появляется если это какой то сервис, к которому должны напрямую потом подключатся. Я когда то писал клиент-серверный чат под винду, в последней версии поиск сервера был через мультикаст: сервера джойнились и слушали на мультикаст адресе, клиент на этот адрес кидал запрос ("ау, кто есть?") а сервера отвечали уже напрямую.


"Multicast во FreeBSD без igmpproxy"
Отправлено Ivan_83 , 14-Дек-11 21:10 
Расписал всё в подробностях на русском, с примерами:
http://www.netlab.linkpc.net/forum/index.php?topic=796

"Multicast во FreeBSD без igmpproxy"
Отправлено unscrubber , 15-Дек-11 08:27 
Авторам решения - спасибо, но с наскоку не получилось (хотя модули есть соответствующие):
у меня на freebsd 7 (PF firewall) при попытке запуска сваливается шелл-процесс с сообщением что не хватило свопа, а свопа в сам деле нет ибо система на flash/ssd в r/o и /tmp+/var на рамдиске (256MB), оперативки достаточно много (1 ГБ, свободно обычно >600 МБ) - в каком направлении копать?  На каких версиях freebsd проверялась работоспособность решения (6/7/8)? Насколько понимаю опции сборки ядра вряд-ли важны .. если важны - то хотелось бы знать какие :-)
Заранее спасибо за ответы, позже на 8ке повторю, но хотелось бы и с 7кой разобраться.

"Multicast во FreeBSD без igmpproxy"
Отправлено Ivan_83 , 15-Дек-11 11:28 
У меня 8.2 х64, но это не должно иметь значения. Памяти там требуется не много, совсем не во время работы. Возможно проблема с либами которые преобразуют выражения для фильтра с помощью tcpdump в код для bpf.
Попробуйте в консоле: tcpdump -s 65535 -ddd 'ether[0] & 1 = 1 and (ether[0:4] != 0xffffffff or ether[4:2] != 0xffff) and ip[9] = 2'
(это выдало одинаковый код на 8.2 со всеми апдейтами и 7.3 которой года полтора, а на арм железке с 32мб озу, без свопа и флешкой рв получил ошибку 1)
У обоих сильно порезанное от лишнего, нетграф везде модулями, единственное BFP у обоих в ядре, чего вроде в генерике нет.

В качестве решения можно сгенерить этот код на любой машине, и подправить скрипт чтобы не вызывал tcpdump (написать аналогично PASSTROUTH). PASSTROUTH = я руками правил вывод tcpdump -ddd чтобы получить NotMatch всегда.
У меня оно так как есть, потому что ошибок я не словил, и править условия для фильтров было легко, кроме того мост легко переделать под что угодно просто поигравшись с tcpdump фильтрами. К тому же это отличный пример практического использования ng_bpf, с кодами была бы сплошная магия, а так понятно что откуда и для чего.


"Multicast во FreeBSD без igmpproxy"
Отправлено unscrubber , 24-Дек-11 21:14 
наконец то удалось найти время для экспериментов

> У меня 8.2 х64, но это не должно иметь значения. Памяти там
> требуется не много, совсем не во время работы. Возможно проблема с
> либами которые преобразуют выражения для фильтра с помощью tcpdump в код

..
> Попробуйте в консоле: tcpdump -s 65535 -ddd 'ether[0] & 1 = 1
> and (ether[0:4] != 0xffffffff or ether[4:2] != 0xffff) and ip[9] =
> 2'

...

запустил в консоли, потом посмотрел вывод, почитал маны, понял что вроде валидный вывод, сделал вспомогательный подскриптик как часть с инициализацией BPFPROG_MCAST_IGMP (я так понимаю по логике это достаточно статичный массив если провайдер не меняет настройки вещания) чтоб не руками набивать, скинул в текстовые файлы. сделал "лениво-отладочную" версию скрипта с жестко прошитыми интерфейсами и выводом по эхо номеров строк скрипта выполненых, вобщем ошибок не было, модифицировал ваш скрипт заменив подпрограмку с использованием вызова tcpdump на bpfprog из файлов в которые заранее сохранял - запустил - и о чудо работает черт подери !!! :D сижу смотрю наконец бридж-тв... мтс на кабельном отрубили его.. пришлось ip-tv подключать

рад очень, странно что исходная версия подвисала, но главно чтотеперь работает, решение изящное, не надо пересобирать после обновлений этот порт igmpproxy ... он коненчо служил верой и правдой мне пару лет но через bpf еще интересней и универсальней получается.


"Multicast во FreeBSD без igmpproxy"
Отправлено michaeladm , 26-Дек-11 09:40 
> unscrubber
> ....
> коненчо служил верой и правдой мне пару лет но через bpf
> еще интересней и универсальней получается.

а можно поподробней


"Multicast во FreeBSD без igmpproxy"
Отправлено unscrubber , 28-Дек-11 14:22 
объясняю коряво и быстро (как могу),
при настройке igmp.conf надо знать (например запуская бинарник igmpproxy с ключём -d, помоему я так делал при первой настройке, сам провайдер нифига не говорит обычно о этих деталях - им проще когда абоненты дылинк-коробки покупают, на форумах не факт что свежая инфа найдется) с каких мультикаст сетей/адресов вещает провайдер чтобы вбить их в altnet на upstream интерфейсе в конфиге.. соответственно при изменениях - надо снова как то вычислять и сохранять конфиг,
и вторая половина - настройка файрвола, если эти подсети были в таблицах перечислены то обновлять.

на igmpproxy примерно год работал ip-tv, но потом в виду наличия тв-тюнер карты и взымания платы за ip-tv выключил (был еще отмечен какой то несанкционированный паразитный траффик входящий порядка 5-100КБ/с, даже если во внутренней сети все клиенты поотключались), а когда мне спустя полтора года снова потребовалось задействовать ранее настраивавшийся и успешно работавший igmpproxy (при отключении просто закоментированы были правила в pf.conf  igmpproxy_enabled="NO" в rc.conf) - во первых не заработало со старыми настройками (во внутренней сети клиенты не получили потока), во вторых не заработало с новыми настройками и даже с альтнетами 0.0.0.0 не было успеха. Не исключаю что я делал диагностику не правильно, попозже приобщу фрагменты конфигов которые "не взлетели" - там имхо изобретать особо нечего.

Резюме:
плюсы от использования решения с ng_bpf вижу в том что меньше конфигов править при изменениях, и эти модули по идее есть всегда под рукой, и они написаны на высоком "ядерном" уровне качества - не надо ставить дополнительные порты (например igmpproxy или udpxy). Хотя если честно для меня все это так и осталось магией - я еще не осознал саму ng_bpf технику что используется скриптом :)


"Multicast во FreeBSD без igmpproxy"
Отправлено Ivan_83 , 29-Дек-11 22:01 
> Резюме:
> плюсы от использования решения с ng_bpf вижу в том что меньше конфигов
> править при изменениях, и эти модули по идее есть всегда под
> рукой, и они написаны на высоком "ядерном" уровне качества - не
> надо ставить дополнительные порты (например igmpproxy или udpxy). Хотя если честно
> для меня все это так и осталось магией - я еще
> не осознал саму ng_bpf технику что используется скриптом :)

На каждый хук, подключённый к ng_bpf можно назначить программу, результатом которой может быть пересылка пакета на один из двух указанных в программе хуков. Можно пересылать пакет не целиком а обрезать.
upper - это хуки на которых трафик от самой системы/в систему
lower - драйвер сетевухи

Всё что идёт с upper пересылается на lower без раздумий.
Если с lower идёт что то, что подпадает под условия мультикаста, то оно пересылается на lower другой сетевухи, остальное на upper этой же сетевухи.

bpf реализует простенький ассемблер, уровня: загрузить 1/2/4 байт с такого то смещения, сравнить, да - переход на XXX строку, нет - переход на YYY строку. Если возвращается 0 - то не совпало, если больше нуля - то столько бат переслать на хук match.
tcpdump -d "выражение" - прекрасно это иллюстрирует.
Более подробно или у нюклайта (постера новости) в блоге или в исходниках/манах.


"Multicast во FreeBSD без igmpproxy"
Отправлено Ivan_83 , 26-Дек-11 21:05 
> рад очень, странно что исходная версия подвисала, но главно чтотеперь работает, решение
> изящное, не надо пересобирать после обновлений этот порт igmpproxy ... он
> коненчо служил верой и правдой мне пару лет но через bpf
> еще интересней и универсальней получается.

В вашем случае почему то не хватало памяти для компиляции правил в бпф ассемблер, у меня такой же результат был на арм коробочке с 32 мб озу.
На работе самого нетграфа/бпф это не отражается.
Рад что у вас всё получилось.


"Multicast во FreeBSD без igmpproxy"
Отправлено unscrubber , 30-Дек-11 06:20 
>...и о чудо
> работает черт подери !!! ..

счастье было недолгим, даже при использовании сохраненных в файл паттернов/шаблонов для bpf (PATTERN_MCAST_IGMP и тп)  опять при запуске ng_ctl наблюдаю out of swap ошибки, после праздников поразбираюсь.

P.S.
не сразу нашел блог нуклайта о котором Иван пишет - на всякий случай пишу тут ссылочку, http://nuclight.livejournal.com/


"Multicast во FreeBSD без igmpproxy"
Отправлено unscrubber , 03-Янв-12 09:43 
> счастье было ...

счастье есть :)
убрал из автостарта скрипт, если руками запускать то работает.
возможно разница в том как я строку-массив (программу для bpf) из файла загружал, в оригинале было PATTERN..= $ ( <some commands> )
я заменил PATTERN..= $ ( cat bpfprog_igmp.txt )
на PATTERN..=`cat bpfprog_igmp.txt`

P.S. с переключением каналов все хорошо на компе, хоть с winXP хоть с GNU/Linux


"Раздел полезных советов: Multicast во FreeBSD без igmpproxy"
Отправлено michaeladm , 15-Дек-11 21:32 
Огромное спасибо за реализацию нормального "мультикаст-моста". Но присутствует один глюк причем такой-же как и у igmpproxy, а именно, если в домашней сети смотреть с двух точек (например приставка Dlink DIB-120 и компьютер) один и тот-же канал, а потом, например компьютер, переключается на другой канал, то на приставке на ~100 секунд этот канал повисает (замирает изображение и нет звука). По прошествии 100 секунд на приставке само все начинает работать.
Система FreeBSD 8.2 RELENG_8, ядро и мир обновлялись недавно. Имеется возможность присвоить алиас или несколько алиасов в сторону провайдера (10.100.90.8, 10.100.90.9 и т.д.) если это может помоч в разрешении проблемы.

"Раздел полезных советов: Multicast во FreeBSD без igmpproxy"
Отправлено Ivan_83 , 16-Дек-11 09:36 
Подозреваю что дело в реализации мультикаста в Dlink DIB-120: после отписки компа должен посылается лив пакет, в ответ приходит запрос на членство в группе, которые приставка походу игнорирует. Через 100 секунд она снова посылает джоин по своему таймеру и начинает получать данные.
Я специально у себя проверял такую же ситуацию ещё на первых рабочих версиях, но у меня 3 компьютера с IPTvPlayer, и взаимного влияния у меня нет.
Мосту вообще нет дела до IP адресов на интерфейсах фряхи.

"Multicast во FreeBSD без igmpproxy"
Отправлено xrensgory , 19-Дек-11 16:55 
Спасибо, добрый человек! Как-раз бьюсь с igmpproxy на FreeBSD и xbox360 в качестве клиента. Вечером буду пробовать

"Multicast во FreeBSD без igmpproxy"
Отправлено Piter_Ring , 20-Дек-11 21:10 
Не, мужики, нетграф - это сила !
и те кто им пользуются - так же не слабого десятка :).

В свое время на опеннете была статейка (мож и щас жива) Сага о биллинге. Так вот на ее основе была собрана система биллинга небольшого прова. Жива до сихпор. нетграф-вертушку (как ее назвали) пересилили на сторону "маршрутизаторов" на базе m0n0.ch (в народе моновол). Пришлось немножко пересобрать его образ. Ну а сам биллинг съехал на линукс. При том что трафик снимается чуть ли не каждые пару сек - нагрузка на систему совсем незаметная.


"Multicast во FreeBSD без igmpproxy"
Отправлено xrensgory , 28-Дек-11 17:08 
интересно... внимательно поизучал сей скрипт, включил promisc mode на интерфейсе, который смотрит в сторону провайдера и IPTV через igmpproxy таки пошел. Думаю дело не в том, что igmpproxy не работает, а в том что ядро кладет на igmp, пока ему на скажешь

"Multicast во FreeBSD без igmpproxy"
Отправлено xrensgory , 28-Дек-11 17:12 
бррр, на мультикаст, пардон

"Multicast во FreeBSD без igmpproxy"
Отправлено The_Q , 09-Янв-12 20:20 
Ivan_83, на netgraph-интерфейсах (mpd) не должно работать?

"Multicast во FreeBSD без igmpproxy"
Отправлено Ivan_83 , 11-Янв-12 14:07 
> Ivan_83, на netgraph-интерфейсах (mpd) не должно работать?

ngX - это совсем другие интерфейсы, у них нет ng_ether хуков.
Если вам оч нужно, то придётся переписывать выражение фильтра, чтобы остался только L3, менять все матчи с маков на IP адреса.
Цепляться оно будет в разрыв, между ngX и остальными нодами от mpd.
Но сделать можно.


"Multicast во FreeBSD без igmpproxy"
Отправлено michaeladm , 11-Янв-12 14:31 
>> Ivan_83, на netgraph-интерфейсах (mpd) не должно работать?
> ngX - это совсем другие интерфейсы, у них нет ng_ether хуков.
> Если вам оч нужно, то придётся переписывать выражение фильтра, чтобы остался только
> L3, менять все матчи с маков на IP адреса.
> Цепляться оно будет в разрыв, между ngX и остальными нодами от mpd.
> Но сделать можно.

Кстати, это было-бы очень интересно. Т. к. многие не петрят вообще в ng..., в том числе и я, то может кто накрапает чтото работоспособное.


"Multicast во FreeBSD без igmpproxy"
Отправлено michaeladm , 11-Янв-12 15:18 
И еще заметил, правдо, может и не важно, но.
При попытке остановить выдаются такие сообщения:
stop bridging beetwen re1 and re0
ngctl: shutdown: No such file or directory

"Multicast во FreeBSD без igmpproxy"
Отправлено inox , 12-Янв-12 20:03 
Все бы хорошо, скрипт работает, но почему во время его работы вырубается updxy никто не подскажет? То есть запускается он нормально, но не вещает ничего ни на одном канале.

"Multicast во FreeBSD без igmpproxy"
Отправлено The_Q , 12-Янв-12 22:36 
А должен? Вы же мультикаст сбриджевали вовнутрь. Там его и ищите.

"Multicast во FreeBSD без igmpproxy"
Отправлено inox , 12-Янв-12 23:24 
Так udpxy ж сам умеет подписываться на мультикаст-группы. Просто нужно организовать работу iptv по проводам с помощью данного скрипта и udpxy через вафлю. Udpxy начинает работать только тогда, когда я останавливаю проброс с этого скрипта.
И как тогда искать мультикаст с udpxy внутри? Просто указать мультикастовый интерфейс внутренний (т.е. НА который идет проброс)?

"Multicast во FreeBSD без igmpproxy"
Отправлено Ivan_83 , 13-Янв-12 15:23 
> Так udpxy ж сам умеет подписываться на мультикаст-группы. Просто нужно организовать работу
> iptv по проводам с помощью данного скрипта и udpxy через вафлю.
> Udpxy начинает работать только тогда, когда я останавливаю проброс с этого
> скрипта.
> И как тогда искать мультикаст с udpxy внутри? Просто указать мультикастовый интерфейс
> внутренний (т.е. НА который идет проброс)?

Потому что мультикаст пакеты с внешнего=источника интерфейса не попадают в стёк, а улетают сразу в сеть.
Если вам нужно чтобы оно работало - пересобирайте граф так, чтобы копия пакетов улетала и в сетевой стёк. Вроде right2left ноды подцепленной к интерфейсам и бпф, в качестве прослойки должно хватит.


"Multicast во FreeBSD без igmpproxy"
Отправлено inox , 16-Янв-12 16:53 
А можно поподробнее как-нить объяснить? Просто я пока только фрю начал изучать досконально, и таких тонкостей настойки нетграфа к сожалению не знаю...

"Multicast во FreeBSD без igmpproxy"
Отправлено Ivan_83 , 17-Янв-12 14:06 
> А можно поподробнее как-нить объяснить? Просто я пока только фрю начал изучать
> досконально, и таких тонкостей настойки нетграфа к сожалению не знаю...

нода ng_ether подключена интерфейсу, у неё есть хуки:
lower - со стороны самой железки, те все полученные пакеты из сети здесь, если сюда что то подключено
upper - это со стороны ядра фри, здесь все пакеты которые вышли из сетевого стёка фри (которые она сама сгенерировала, например ссш, веб сервер и которые идут через неё транзитом в виде маршрутизации (роутинг) или нат)
Если к хукам ничего не подключено, нода ведёт себя так как будто одни соединены - те пакеты из сети прямиком идут в сетевой стёк, а пакеты из сетевого стёка идут в сеть.

Когда мы подключаем бпф, то настраиваем её так, чтобы все пакеты от upper хуков всегда уходили в lower хуки той же ноды.
А пакеты с lower хука попадают в upper хук той же ноды только если они не мультикаст, если же они мультикаст то мы их пересылаем на lower хук другой ноды, и в сетевой стёк они не попадают вообще.

Мультикаст определяется по установленному младшему биту в первом байте адреса назначения ethernet заголовка, так же введены дополнительные провеки: эзернет пакет должен содержать в себе IPv4 пакет, IPv4 должен содержать IGMP либо UPD, юдп мултикаст пересылается только в внешнего интерфейса на внутренний, игмп в обе стороны - там две немного разных программы для bpf.


"Multicast во FreeBSD без igmpproxy"
Отправлено AlexighTower , 18-Янв-12 18:04 
Поддерживаю вопрос, может кто из понимающих в нетграфе найдёт пяток минут сделать такие изменения, чтобы мультикаст бриджевался, но и uxpdy работал?
Было бы очень здорово и приятно...

"Multicast во FreeBSD без igmpproxy"
Отправлено Ivan_83 , 01-Мрт-12 21:10 
> Все бы хорошо, скрипт работает, но почему во время его работы вырубается
> updxy никто не подскажет? То есть запускается он нормально, но не
> вещает ничего ни на одном канале.

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

Возьмите обновлённую версию у меня с сайта и запустите добавив ещё один ключ, например так:
mcastbr2.sh start vlan886 vlan777 enable

С этим ключём он будет также и в ядро слать траффик, как было бы без моста.


"Multicast во FreeBSD без igmpproxy"
Отправлено michaeladm , 27-Фев-12 18:08 
...и еще один глупый вопрос. А чем может грозить promisc режим сетевых карт? Это может влиять както на безопасность или производительность сетевых карт?

"Multicast во FreeBSD без igmpproxy"
Отправлено Ivan_83 , 01-Мрт-12 21:16 
> ...и еще один глупый вопрос. А чем может грозить promisc режим сетевых
> карт? Это может влиять както на безопасность или производительность сетевых карт?

Если свич тупой/игмп снупинг не включён то мультикаст будет лететь во все порты такого свича, а поскольку адаптер в промиске то он будет их принимать и они будут дропаться уже где то в ядре фри.
Если бы промиск был выключен то сетевой адаптер сам бы их подропал или аппаратно или гдето внутри драйвера.

По сути промиск это отключения фильтра в сетевом адаптере. Этот фильтр пропускает только пакеты у которых DST MAC в белом списке адаптера. Список этот обычно не большой (4 - 32 записи), и при подписке на множество мультикаст групп адаптер либо переключится в промиск либо подписка закончится не удачей / трафик не пойдёт в ядро.



"Multicast во FreeBSD без igmpproxy"
Отправлено michaeladm , 18-Мрт-12 14:16 
> Для создания аналогичного по функционалу моста, в котором будет несколько

сетевых интерфейсов...

Ктонибудь уже сделал? подскажите пожалуйста.
Ничего не получается сделать на два интерфейса (две подсети дома) re1 и wlan0.


"Multicast во FreeBSD без igmpproxy"
Отправлено Ivan_83 , 18-Мрт-12 21:28 
>> Для создания аналогичного по функционалу моста, в котором будет несколько
> сетевых интерфейсов...
> Ктонибудь уже сделал? подскажите пожалуйста.
> Ничего не получается сделать на два интерфейса (две подсети дома) re1 и
> wlan0.

В обновлённой версии добавлен ещё один параметр, включающий форвад мультикста в сетевой стёк, для этого добавлены ng_hub.
Нужно скопировать часть которая создаёт часть графа для внутреннего интерфейса, а на хабе инетрфейса источника добавить ещё один линк и должно заработать.

Только мультикаст будет валится на оба интерфейса одинакого, те будет присутствовать лишний.

Как то так пропатчить, и может заработает.

IF_DOWNSTREAM="$3"
+IF_DOWNSTREAM1="$4"
-CP_MC_ENABLE="$4"
+ CP_MC_ENABLE="$5"

                               ngctl connect ${BR_NAME}-bpf: ${BR_NAME}-bpf:${IF_UPSTREAM}-h0 ${IF_UPSTREAM}-h2 h2
+                             ngctl connect ${BR_NAME}-bpf: ${BR_NAME}-bpf:${IF_UPSTREAM}-h0 ${IF_UPSTREAM}-h3 h3

                               ngctl msg ${BR_NAME}-bpf: setprogram { thisHook=\"${IF_UPSTREAM}-h2\" ifMatch=\"\" ifNotMatch=\"${IF_DOWNSTREAM}-lower\" ${BPFPROG_PASSTROUTH} }
+                             ngctl msg ${BR_NAME}-bpf: setprogram { thisHook=\"${IF_UPSTREAM}-h3\" ifMatch=\"\" ifNotMatch=\"${IF_DOWNSTREAM1}-lower\" ${BPFPROG_PASSTROUTH} }

                               ngctl msg ${BR_NAME}-bpf: setprogram { thisHook=\"${IF_DOWNSTREAM}-lower\" ifMatch=\"${IF_DOWNSTREAM}-h0\" ifNotMatch=\"${IF_DOWNSTREAM}-upper\" ${BPFPROG_MCAST_IGMP} }
                               ngctl msg ${BR_NAME}-bpf: setprogram { thisHook=\"${IF_DOWNSTREAM}-h1\" ifMatch=\"\" ifNotMatch=\"${IF_DOWNSTREAM}-upper\" ${BPFPROG_PASSTROUTH} }
                               ngctl msg ${BR_NAME}-bpf: setprogram { thisHook=\"${IF_DOWNSTREAM}-h2\" ifMatch=\"\" ifNotMatch=\"${IF_UPSTREAM}-lower\" ${BPFPROG_PASSTROUTH} }
+
+                             ngctl msg ${BR_NAME}-bpf: setprogram { thisHook=\"${IF_DOWNSTREAM1}-lower\" ifMatch=\"${IF_DOWNSTREAM1}-h0\" ifNotMatch=\"${IF_DOWNSTREAM1}-upper\" ${BPFPROG_MCAST_IGMP} }
+                             ngctl msg ${BR_NAME}-bpf: setprogram { thisHook=\"${IF_DOWNSTREAM1}-h1\" ifMatch=\"\" ifNotMatch=\"${IF_DOWNSTREAM1}-upper\" ${BPFPROG_PASSTROUTH} }
+                             ngctl msg ${BR_NAME}-bpf: setprogram { thisHook=\"${IF_DOWNSTREAM1}-h2\" ifMatch=\"\" ifNotMatch=\"${IF_UPSTREAM}-lower\" ${BPFPROG_PASSTROUTH} }


"Multicast во FreeBSD без igmpproxy"
Отправлено michaeladm , 19-Мрт-12 12:40 
> + ngctl msg ${BR_NAME}-bpf: setprogram { thisHook=\"${IF_DOWNSTREAM1}-lower\" ifMatch=\"${IF_DOWNSTREAM1}-h0\" ifNotMatch=\"${IF_DOWNSTREAM1}-upper\" ${BPFPROG_MCAST_IGMP} }
> + ngctl msg ${BR_NAME}-bpf: setprogram { thisHook=\"${IF_DOWNSTREAM1}-h1\" ifMatch=\"\" ifNotMatch=\"${IF_DOWNSTREAM1}-upper\" ${BPFPROG_PASSTROUTH} }
> + ngctl msg ${BR_NAME}-bpf: setprogram { thisHook=\"${IF_DOWNSTREAM1}-h2\" ifMatch=\"\" ifNotMatch=\"${IF_UPSTREAM}-lower\" ${BPFPROG_PASSTROUTH} }

на этих коммандах ругается:
ngctl: send msg: No such file or directory
ngctl: send msg: No such file or directory
ngctl: send msg: No such file or directory

...похоже, что чегото не хватает


"Multicast во FreeBSD без igmpproxy"
Отправлено lexx , 20-Мрт-12 06:04 
помогите !! как к этому скрипту прикрутить такой тунель... что бы отправить iptv в другую сетку

ngctl mkpeer switch: ksocket link3 inet/dgram/udp
ngctl name switch:link3 switch_socket
ngctl msg switch_socket: bind inet/${self}:${port}
ngctl msg switch_socket: connect inet/${peer}:${port}


"Multicast во FreeBSD без igmpproxy"
Отправлено Ivan_83 , 25-Мрт-12 00:28 
> помогите !! как к этому скрипту прикрутить такой тунель... что бы отправить
> iptv в другую сетку
> ngctl mkpeer switch: ksocket link3 inet/dgram/udp
> ngctl name switch:link3 switch_socket
> ngctl msg switch_socket: bind inet/${self}:${port}
> ngctl msg switch_socket: connect inet/${peer}:${port}

Вместо lower хука одного из интерфейсов подключается юдп сокет (см пример с туннелирование эзернета в юдп, в гугле).
Я так себе с работы мультикаст забирал.


"Multicast во FreeBSD без igmpproxy"
Отправлено aydnep , 09-Ноя-12 12:49 
помогите плз как заменить src-ip а то моему провайдеру не все равно какой src-ip посылает запрос

"Multicast во FreeBSD без igmpproxy"
Отправлено gaergaergear , 06-Окт-14 16:00 
Скажи своему провайдеру не вы*бываться, а настроить igmp_snooping multicast vlan.

"Раздел полезных советов: Multicast во FreeBSD без igmpproxy"
Отправлено Imhoil , 10-Апр-13 22:00 
Странно, имею от провайдера 2 физических подключения.
em1 - интернет + IPTV (100мбит)
em2 - только IPTV (100мбит)
em0 - локальный интерфейс
vlan101 - vlan для IPTV (vlandev em0)
Так как на домашний свич заведен гигабит, захотелось немножко сбалансировать нагрузку. То есть, скриптом вешаю мост с em2 на vlan101. Но при нагрузке на em1 более 70 мбит (качаю популярный торрент), получаю тормоза при просмотре IPTV и сообщения в лог такого типа:
kernel: Limiting closed port RST response from 469 to 200 packets/sec
kernel: Limiting open port RST response from 524 to 200 packets/sec
atop кажет такое
NET |  em1      98% |  pcki    9051  | pcko    5993  |  si   98 Mbps |  so 9591 Kbps
NET |  em2      10% |  pcki     932  | pcko       0  |  si   10 Mbps |  so    0 Kbps
NET |  em0       1% |  pcki       5  | pcko     922  |  si    9 Kbps |  so   10 Mbps
NET |  vlan101   0% |  pcki       3  | pcko     920  |  si    9 Kbps |  so 9994 Kbps