- Static Multicast Routing
- Содержание
- Ссылки [ править ]
- Общие понятия [ править ]
- Подготовка шлюза [ править ]
- Конфигурация [ править ]
- Настройка маршрутизации [ править ]
- Проверка работы [ править ]
- Настройка статической маршрутизации [ править ]
- Особенности работы с Multicast
- Создание сокета
- Связывание сокета
- Подключение к группе
- А как в boost’e ?
- Несколько групп для одного сокета
- Net-Labs.in
- Network, ISP
- Маршрутизация multicast в Linux
- Статическая маршрутизация multicast
- Ренамберинг мультикаст групп
- Прочее
Static Multicast Routing
Настройка статической multicast-маршрутизации на дистрибутивах ALT Linux.
Содержание
Ссылки [ править ]
Общие понятия [ править ]
Рассмотрим типичную схему multicast-маршрутизации с выделенным сервером, имеющим два сетевых интерфейса:
- eth0 — публичный интерфейс, на который придет поток от провайдера;
- eth1 — интерфейс в локальную сеть, в которой находятся клиенты.
Multicast-маршрутизация осуществляется по протоколу IGMP. IGMP (англ. Internet Group Management Protocol — протокол управления группами Интернета) — протокол управления групповой (multicast) передачей данных в сетях, основанных на протоколе IP. В данном руководстве используется IGMP версии 1.
На шлюзе должна быть разрешена пересылка сетевых пакетов (forwarding) и запущен демон multicast-маршрутизации. Мы рекомендуем использовать в качестве такого демона igmpproxy. При этом клиенты должны явно присоединиться к MC-группе. Вы можете явно назначить multicast-маршруты без этого требования к клиентам, если используете пакет smcroute.
Примечание: интерфейсы в дистрибутивах на базе Пятой платформы будут соответственно breth0 и breth1, однако мы не рекомендуем делать на них маршрутизацию.
Подготовка шлюза [ править ]
Для начала необходимо установить дистрибутив ALT Linux и пакет демон multicast-маршрутизации igmpproxy и программу настройки статических маршрутов smcroute из соответствующего репозитория:
Также необходимы пакеты iptables net-tools iproute2, в дистрибутивах ALT Linux они присутствуют по умолчанию.
Для мониторинга можно установить пакеты tcpdump, wireshark и iperf
Все манипуляции осуществляются под правами пользователя root.
Конфигурация [ править ]
Для дистрибутивов на базе Пятой платформы файл /etc/igmpproxy.conf вместо eth0 и eth1 исполь-зуйте breth0 и breth1 соответственно.
Настройка маршрутизации [ править ]
1. Шлюз должен быть настроен для маршрутизации сетевых пакетов:
- Находится в режиме «Шлюз» в модуле «Брандмауэр» в дистрибутивах на базе Пятой платформы;
- или настраиваем вручную: в файле /etc/net/sysctl.conf параметр net.ipv4.ip_forward должен быть установлен в «1»:
Также в файл /etc/net/sysctl.conf добавляем параметры: отключаем reverse path filtering для eth0 и для ядер 2.6.x указываем версию IGMP (igmpproxy поддерживает только IGMPv1 и IGMPv2 на внутреннем интерфейсе):
Примечание: после внесения изменений в этот файл необходимо перезагрузить компьютер.
2. Проверяем готовность к маршрутизации:
3. Настраиваем цепочки iptables для работы со специальными multicast-подсетями:
4. Прописываем маршрут:
5. Запускаем демона:
Журнал работы igmpproxy ведётся в /var/log/messages. Для отладки можно запустить командой igmpproxy -d /etc/igmpproxy.conf
Проверка работы [ править ]
После запуска igmpproxy должны появится соответствующие флаги:
В файлах состояния ядра появятся записи:
Маршруты можно найти в файлах:
Виртуальные интерфейсы для маршрутизации:
Настройка статической маршрутизации [ править ]
Для статической маршрутизации демон igmpproxy запускать не нужно.
1. Запускаем демон:
2. Настраиваем маршруты:
- eth0 — входящий интерфейс для трафика
- 10.1.0.18 — адрес интерфейса-источника трафика (можно получить по команде tcpdump -i eth0 dst host 224.2.2.2)
- 224.2.2.2 — MC-группа в сети 224.0.0.0/4
- eth1 — один или несколько внешних интерфейсов
Источник
Особенности работы с Multicast
Хочу поделиться небольшим опытом работы с технологией групповой передачи данных, или иначе UDP Multicast, и проблемой особенностью, которая возникает при написании кроссплатформенного кода.
Сразу оговорюсь, что в этой статье не будет рассматривать сама технология и протокол UDP, для этого лучше обратиться к UDP, а потом к Multicast.
Итак, вся работа начинается с создания сокета и его «настройки». В общих чертах выглядит это так
1. создать сокет
2. сделать bind
3. подключится с Multicast группе.
Теперь по порядку
Создание сокета
Тут все просто и без подвохов
Связывание сокета
Первое что мы должны сделать, это позволить использовать PORT повторно, т.к. помимо нас кто-то еще может работать с этим портом.
Функция setsockopt позволяет задать опции для сокета. Интересным моментом является то, что значение опции передается по указателю на void, т.к. некоторые опции требует не просто флаг включено/выключено, а структуры с дополнительными то данными.
Далее нам необходимо связать сокет с портом. А может еще и адресом? Тут вступает в силу первая проблема особенность — различная идеология ядер Windows и Linux. А именно то, что под Windows мы не можем забиндиться на адрес Multicast группы (получаем ошибку) и должны биндиться на INADDR_ANY
На Linux мы можем так же забиндиться на INADDR_ANY, но в этом случае мы будем получать все дейтаграммы пришедшие на забинденный нами порт. Для того чтобы получать дейтаграммы только из нужной группы, необходимо забиндиться именно на адрес этой группы (ну и порт конечно не забыть).
Подключение к группе
Главной особенностью Multicast является то, что наш хост не будет получать данных до тех пор пока мы не подключимся к Multicast группе. Подключение на уровне пользователя выглядит как установка опции для сокета.
где ip_mreq.imr_multiaddr это адрес мультикаст группы. А ip_mreq.imr_interface это адрес интерфейса, на котором мы ожидаем получать дейтаграммы. INADDR_ANY в данном случае говорит о том, что мы оставляем это право за ядром, которое выберет интерфейс исходя из таблицы роутинга. Далее ядро проверит не подключены ли мы уже к этой группе, и если нет, то отправит запрос на ближайший Multicast сервер. Тот в свою очередь дальше и т.д. После чего нам на хост будут отправлять дейтаграммы, отправляемые в данную Multicast группу.
Но что делать с Windows который забинден на INADDR_ANY? Он что будет получать все дейтаграммы отправленные на слушаемый порт? Судя по всему ядро Windows, при указании этой опции для сокета, само производит фильтрацию получаемых данных. И таким образом на сокет доставляются данные только из подписанных групп.
На Linux для того, чтобы получать данные на сокет только от подключенной Multicast группы, необходимо забиндиться на ее же адрес.
Если вы мне не верите (а я сам в это в начале не поверил) то поверьте ему
Unix Network Programming 3 издание. глава 21.6 страница 599
— Чтобы получить дейтаграмму многоадресной передачи, процесс должен присоединиться к группе, а также связать при помощи функции bind сокет UDP с номером порта, который будет использоваться как номер порта получателя для дейтаграмм, отсылаемых данной группе.
…
Связывая порт, приложение указывает UDP, что требуется получать отправляемые на этот порт дейтаграммы. Некоторые приложения в дополнения к связыванию порта также связывают при помощи функции bind адрес многоадресной передачи с сокетом. Это предотвращает доставку сокету любых других дейтаграмм, которые могли быть получены для этого порта.
А как в boost’e ?
Разочарую вас, в boost все аналогично API, никакой адаптации под единую логику не производится. Таким образом, используя его для написание кроссплатформенного приложение вам все равно придется делать
Несколько групп для одного сокета
Пока писал пост, понял, что путь, предложенный для Linux, скрывает одно ограничение. Мы должны работать по принципу один сокет — одна Multicast группа. Так как навряд ли возможно забиндиться сразу не несколько адресов.
Обрисую ситуацию. Есть сервер, он вещает данные в несколько мультикаст групп на один порт.
Есть клиент, он желает получать от сервера данные только в нескольких группах. Тогда ему нужно предпринять следующие действия:
1. биндиться на INADDR_ANY
2. далее фильтровать все полученные дейтаграммы в ручную определяя их destination 1 адрес.
Процесс фильтрации полученных на сокете дейтаграмм по destination адресу вытекает из того, что возможна ситуация когда на машине клиента есть еще другой софт который подключается к каким то другим группам но с тем же портом и тогда оба сокета будут получать дейтаграммы со всех подключенных групп на этом порту.
Но при этом на лицо проблема избыточности данных.
Ну собственно об тих особенностях работы с Multicast я и хотел вам рассказать, не зная которых вы рискуете наступить на грабли.
PS. Для того что бы все это прочувствовать предлагаю проделать следующие шаги.
1. Собрать receiver
2. Собрать sender
Далее на Linux запустить
3. Запустить: receiver 0.0.0.0 239.192.100.1
4. Запустить: receiver 0.0.0.0 239.192.100.2
5. Запустить: sender 239.192.100.1
6. Убедить что оба receiver’a получат данные
Далее тоже запустить на Windows
7. Убедиться что данные получит только тот кому мы их отправили.
1 Еще одной особенностью UDP является то, что адрес отправителя и получателя явным образом не указывается в заголовке UDP сообщения. Но он учитывается при подсчете чексумы, таким образом получая дейтаграмму UDP модуль должен составить свой псевдо заголовок, рассчитать чексуму и сравнив ее с полученной, принять решении о том что дейтаграмма адресовалась именно нам. Судя по всему Linux делает эту проверку, используя в качестве destination адрес на который мы забиндились, из за чего и получается описанная выше проблема особенность.
Источник
Net-Labs.in
Network, ISP
Маршрутизация multicast в Linux
В современных реалиях, скорее всего, нет смысла заниматься маршрутизацией(репликацией) multicast-трафика с помощью софтроутеров(будь то ядро Linux или что-то иное). Причина довольно простая – даже дешёвые свитчи умеют L2/L3-multicast(хоть и с ограничениями по количеству групп/маршрутов, но всё же это делается в asic-ах). Однако, существует ряд задач, которые могут быть не решены в “железе” (нет поддержки со стороны ПО/невозможно реализовать ввиду возможностей asic), например ренамберинг(изменение destination ip), внесение случайных задержек(перемешивание), отправка multicast в тунель, резервирование источника по произвольному критерию.
Зачем может потребоваться ренамберинг мультикаст группы? Во-первых, маппинг IP-mac неодназначен(например, группам 238.1.1.1 и 239.1.1.1 соответствует один и тот же mac-адрес), что может вызвать проблемы в L2-сегменте. Конечно, такая коллизия маловероятна, однако возможна, когда вы берёте multicast из разных внешних источников(в принципе, IP-адреса могут даже полностью совпасть). Во-вторых, вы можете захотеть скрыть свой источник, изменив и destination и source адрес. В destination может быть “спрятан” номер AS источника(RFC3180), по source тоже можно догадаться об источнике, если он не серый. В третьих, перенумеровать группу может потребоваться для избежания коллизии на оборудовании, где заканчивается TCAM под multicast (как временное решение до замены оборудования/изменения схемы сети). И наконец, вы решили зарезервировать ТВ-каналы путём их получения из разных источников(т.е. вливать на сервер 2 разных группы(но одинаковых по контенту) и забирать из него одну, результирующую(работающую))
Внести случайную задержку(reordering) или потери может потребоваться для проверки поведения используемых STB/soft-плееров. Например, вам интересно, как будет выглядеть картинка, если где-то на сети мультикаст пройдёт через per-packet балансировку и не зависнет ли плеер при наличии потери пакетов, будут ли издаваться неприятные скрипящие звуки или же просто квадратики и тишина.
При написании этой заметки использовался Ubuntu Linux 14.04 LTS (ядро 3.13.0-24-generic), но применимо для большинства современных дистрибутивов, однако необходимо проверить поддержку IPv4 multicast в ядре:
В отличии от unicast роутинга, утилиты ip недостаточно даже для статической (S, G) маршрутизации, не говоря уже про динамическую. Для формирования таблицы мультикаст-репликации требуются “сторонние” userspace-утилиты. Например, для статических маршрутов это smcroute, для построения таблицы по igmp-запросам с даунлинк-интерфейсов – igmpproxy(маршрут добавляется в ядро тогда, когда “снизу” приходит igmp-запрос), для работы с PIM-SM сигнализацией – pimd(требуется поддержка PIMSM_V2 со стороны ядра).
Статическая маршрутизация multicast
Рассмотрим следующую задачу: осуществить репликацию мультикаст-трафика (*, 233.251.240.1) с интерфейса eth1 на интерфейсы eth2 и eth3, при этом на eth1 эта группа приходит только по igmpv2-запросу.
Конфигурация интерфейсов выглядет следующим образом:
К сожаленью, smcroute в ubuntu 14.04 не поддерживает (*, G)-форму, поэтому придётся скомпилировать из исходников:
Прежде чем запускать маршрутизацию(инсталлировать маршруты в ядро), нужно отключить RPF на интерфейсе eth1(поскольку по условию задачи считаем, что source ip multicast-группы может быть произвольным):
Кроме того, устанавливаем явным образом режим работы igmp на интерфейсе eth1:
Теперь переходим к конфигурации smcroute(/etc/smcroute.conf):
(необходим перевод строки в конце конфигурации)
Первая строчка – подключить группу по протоколу igmp(залить эту информацию в ядро), вторая – собственно мультикаст-маршрут.
Запускаем smcroute:
(логи пишутся в syslog)
Проверяем таблицу igmp:
Всё верно, 01F0FBE9 это наша группа 233.251.240.1.
До того, как в eth1 польётся мультикаст, таблица маршрутизации в ядре будет выглядеть таким образом:
Затем примет такой вид:
Проверяем работу репликации:
Ренамберинг мультикаст групп
Для того, чтобы изменить IP multicast группы используем DNAT. Например, мы хотим изменить 233.251.240.1 на 233.251.250.5:
/etc/smcroute.conf будет выглядеть следующим образом:
(в маршруте фигурирует новый адрес по причине того, что DNAT делается в PREROUTING-е)
Далее, чистим conntrack(командой “conntrack -F”) и проверяем:
Как нетрудно догадаться, чтобы подменить ещё и source ip, будем использовать SNAT:
Снова чистим conntrack(“conntrack -F”) и проверяем:
Прочее
С помощью iptables и tc можно ещё что-нибудь сделать с трафиком(внести задержки и потери, например). При желании, можно организовать резервирование ТВ-канала путём переключения источника вещания с помощью скриптов(smcroute-ом можно управлять “извне”), придумав произвольные критерии выбора лучшего источника(подобные решения для операторов существуют и стоят больших денег)
Источник