Маршрутизация multicast в Linux (IGMPv3 и IGMPv2)

В продолжение предыдущей заметки о статической маршрутизации multicast в Linux, это статья опишет возможности приложения mcproxy, которое управляет mroute-таблицей ядра Linux, исходя из IGMP-сигнализации. В отличии от всех остальных вариантов(igmpproxy с патчем и т.п.), mcproxy нормально работает с IGMPv3 (не падает). Использовалась версия из git (6638aa9), ОС Ubuntu Linux 14.04, ядро 3.13.0-32, iproute2 3.12.0-2

Если быть кратким, то смысл статьи в конфигурации из двух строчек (/etc/myproxy.conf):

protocol IGMPv3;
pinstance myProxy: ppp1 ==> eth0 tun0;

(В этом примере мультикаст принимается из ppp-тунеля и реплицируется (при наличии запросов снизу) в eth0 и тунельный интерфейс tun0)
И строки запуска:

# mcproxy -r -f /etc/mcproxy.conf

Лабораторный стенд выглядит следующим образом:

mcproxy test scheme

где G1 – генератор(источник) трафика (iperf),
R2 – маршрутизатор мультикаст (на основе IGMPv3 сигнализации)
C3, C4 – потребители мультикаста (клиенты)

mcproxy выполняет роль IGMP Querier (в сторону клиентов). Между маршрутизатором R1 и клиентами, при необходимости, могут быть установлены свитчи с включенным igmp-snooping.

В качестве G1, R2, C3 и C4 могут выступать реальные или виртуальные хосты или же ими могут являться сетевые контейнеры netns.

Подготовительные настройки:

root@G1:~# ifconfig eth12 192.0.2.1 up
root@G1:~# ip route add 0.0.0.0/0 via 192.0.2.2

root@R2:~# ifconfig eth21 192.0.2.2 up
root@R2:~# ifconfig eth23 198.51.100.2 up
root@R2:~# ifconfig eth24 203.0.114.2 up

root@C3:~# ifconfig eth32 198.51.100.3 up
root@C3:~# ip route add 0.0.0.0/0 via 198.51.100.2

root@C4:~# ifconfig eth42 203.0.114.4 up
root@C4:~# ip route add 0.0.0.0/0 via 203.0.114.2

Сборка mcproxy:

root@R2:~# git clone https://github.com/mcproxy/mcproxy.git
root@R2:~# cd mcproxy/mcproxy
root@R2:~# qmake mcproxy.pro
root@R2:~# make
root@R2:~# make install

Конфигурация /etc/mcproxy.conf на R2:

protocol IGMPv3;
pinstance myProxy: eth21 ==> eth23 eth24;

Запуск mcproxy:

root@R2:~# nohup mcproxy -r -f /etc/mcproxy.conf &

ключ -r выключает проверку RPF на указанных в конфигурации интерфейсах и all (net.ipv4.conf.all.rp_filter), это может потребоваться если со стороны генератора будет приходить мультикаст с source ip, которого нет среди префиксов таблицы маршрутизации.

Создаём 2 мультикаст потока(разные группы):

root@G1:~# iperf -u -c 232.0.0.0 -B 192.0.2.1 -b32k -t 10000 -T 10 &
root@G1:~# iperf -u -c 232.0.0.1 -B 192.0.2.1 -b32k -t 10000 -T 10 &

На одном клиенте join-им с помощью vlc 2 потока(в режиме IGMPv3), на другом только один:

user@C3:~$ cvlc udp://192.0.2.1@232.0.0.0:5002 &
user@C3:~$ cvlc udp://192.0.2.1@232.0.0.1:5002 &
user@C4:~$ cvlc udp://192.0.2.1@232.0.0.0:5002 &

Результат:

root@R2:~# ip mroute show
(192.0.2.1, 232.0.0.1)           Iif: eth21      Oifs: eth23 
(192.0.2.1, 232.0.0.0)           Iif: eth21      Oifs: eth23 eth24 
root@R2:~# tcpdump -i eth24 -n -nn -v -vv -s 0 -c 4
tcpdump: listening on eth24, link-type EN10MB (Ethernet), capture size 65535 bytes
22:14:42.370896 IP (tos 0x0, ttl 9, id 28151, offset 0, flags [DF], proto UDP (17), length 1498)
    192.0.2.1.5001 > 232.0.0.0.5001: [bad udp cksum 0xafd9 -> 0xf248!] UDP, length 1470
22:14:42.738393 IP (tos 0x0, ttl 9, id 28152, offset 0, flags [DF], proto UDP (17), length 1498)
    192.0.2.1.5001 > 232.0.0.0.5001: [bad udp cksum 0xafd9 -> 0x56af!] UDP, length 1470
22:14:43.105869 IP (tos 0x0, ttl 9, id 28153, offset 0, flags [DF], proto UDP (17), length 1498)
    192.0.2.1.5001 > 232.0.0.0.5001: [bad udp cksum 0xafd9 -> 0xfd7e!] UDP, length 1470
22:14:43.473392 IP (tos 0x0, ttl 9, id 28154, offset 0, flags [DF], proto UDP (17), length 1498)
    192.0.2.1.5001 > 232.0.0.0.5001: [bad udp cksum 0xafd9 -> 0x61e2!] UDP, length 1470

root@R2:~# tcpdump -i eth23 -n -nn -v -vv -s 0 -c 4
tcpdump: listening on eth23, link-type EN10MB (Ethernet), capture size 65535 bytes
22:14:49.943761 IP (tos 0x0, ttl 9, id 37246, offset 0, flags [DF], proto UDP (17), length 1498)
    192.0.2.1.52321 > 232.0.0.1.5001: [bad udp cksum 0xafda -> 0x7b90!] UDP, length 1470
22:14:50.088384 IP (tos 0x0, ttl 9, id 28172, offset 0, flags [DF], proto UDP (17), length 1498)
    192.0.2.1.5001 > 232.0.0.0.5001: [bad udp cksum 0xafd9 -> 0x41b8!] UDP, length 1470
22:14:50.311276 IP (tos 0x0, ttl 9, id 37247, offset 0, flags [DF], proto UDP (17), length 1498)
    192.0.2.1.52321 > 232.0.0.1.5001: [bad udp cksum 0xafda -> 0x2240!] UDP, length 1470
22:14:50.455888 IP (tos 0x0, ttl 9, id 28173, offset 0, flags [DF], proto UDP (17), length 1498)
    192.0.2.1.5001 > 232.0.0.0.5001: [bad udp cksum 0xafd9 -> 0xa627!] UDP, length 1470

Всё работает как надо. Для того, чтобы использовать IGMPv2 вместо IGMPv3, нужно в конфигурации исправить IGMPv3 на IGMPv2.

Advertisements

One thought on “Маршрутизация multicast в Linux (IGMPv3 и IGMPv2)

  1. Pingback: Маршрутизация multicast в Linux | Net-Labs.in

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s