Niedawno skonfigurowałem nowy Ubuntu Server 10.04 i zauważyłem, że mój serwer UDP nie widzi już danych multiemisji wysyłanych do interfejsu, nawet po dołączeniu do grupy multiemisji. Mam dokładnie taką samą konfigurację na dwóch innych maszynach Ubuntu 8.04.4 LTS i nie ma problemu z odbieraniem danych po dołączeniu do tej samej grupy multiemisji.
Karta Ethernet to Broadcom netXtreme II BCM5709, a zastosowany sterownik to:
b $ ethtool -i eth1
driver: bnx2
version: 2.0.2
firmware-version: 5.0.11 NCSI 2.0.5
bus-info: 0000:01:00.1
Używam smcroute do zarządzania moimi rejestracjami multiemisji.
b$ smcroute -d
b$ smcroute -j eth1 233.37.54.71
Po dołączeniu do grupy ip maddr pokazuje nowo dodaną rejestrację.
b$ ip maddr
1: lo
inet 224.0.0.1
inet6 ff02::1
2: eth0
link 33:33:ff:40:c6:ad
link 01:00:5e:00:00:01
link 33:33:00:00:00:01
inet 224.0.0.1
inet6 ff02::1:ff40:c6ad
inet6 ff02::1
3: eth1
link 01:00:5e:25:36:47
link 01:00:5e:25:36:3e
link 01:00:5e:25:36:3d
link 33:33:ff:40:c6:af
link 01:00:5e:00:00:01
link 33:33:00:00:00:01
inet 233.37.54.71 <------- McastGroup.
inet 224.0.0.1
inet6 ff02::1:ff40:c6af
inet6 ff02::1
Jak dotąd tak dobrze, widzę, że otrzymuję dane dla tej grupy multiemisji.
b$ sudo tcpdump -i eth1 -s 65534 host 233.37.54.71
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 65534 bytes
09:30:09.924337 IP 192.164.1.120.58848 > 233.37.54.71.15572: UDP, length 212
09:30:09.947547 IP 192.164.1.120.58848 > 233.37.54.71.15572: UDP, length 212
09:30:10.108378 IP 192.164.1.120.58866 > 233.37.54.71.15574: UDP, length 268
09:30:10.196841 IP 192.164.1.120.58848 > 233.37.54.71.15572: UDP, length 212
...
Mogę również potwierdzić, że interfejs odbiera pakiety Mcast.
b $ ethtool -S eth1 | grep mcast_pack
rx_mcast_packets: 103998
tx_mcast_packets: 33
Teraz jest problem. Kiedy próbuję przechwycić ruch za pomocą prostego serwera ruby UDP, otrzymuję zero danych! Oto prosty serwer, który odczytuje dane wysyłane przez port 15572 i drukuje pierwsze dwa znaki. Działa to na dwóch serwerach Ubuntu 8.04.4, ale nie na serwerze 10.04.
require 'socket'
s = UDPSocket.new
s.bind("", 15572)
5.times do
text, sender = s.recvfrom(2)
puts text
end
Jeśli wyślę pakiet UDP spreparowany w rubinie do localhost, serwer odbierze go i wydrukuje dwa pierwsze znaki. Wiem więc, że powyższy serwer działa poprawnie.
irb(main):001:0> require 'socket'
=> true
irb(main):002:0> s = UDPSocket.new
=> #<UDPSocket:0x7f3ccd6615f0>
irb(main):003:0> s.send("I2 XXX", 0, 'localhost', 15572)
Kiedy sprawdzam statystyki protokołu, widzę, że InMcastPkts nie rośnie. Podczas gdy na innych serwerach 8.04, w tej samej sieci, otrzymałem kilka tysięcy pakietów w 10 sekund.
b $ netstat -sgu ; sleep 10 ; netstat -sgu
IcmpMsg:
InType3: 11
OutType3: 11
Udp:
446 packets received
4 packets to unknown port received.
0 packet receive errors
461 packets sent
UdpLite:
IpExt:
InMcastPkts: 4654 <--------- Same as below
OutMcastPkts: 3426
InBcastPkts: 9854
InOctets: -1691733021
OutOctets: 51187936
InMcastOctets: 145207
OutMcastOctets: 109680
InBcastOctets: 1246341
IcmpMsg:
InType3: 11
OutType3: 11
Udp:
446 packets received
4 packets to unknown port received.
0 packet receive errors
461 packets sent
UdpLite:
IpExt:
InMcastPkts: 4656 <-------------- Same as above
OutMcastPkts: 3427
InBcastPkts: 9854
InOctets: -1690886265
OutOctets: 51188788
InMcastOctets: 145267
OutMcastOctets: 109712
InBcastOctets: 1246341
Jeśli spróbuję zmusić interfejs do trybu promis, nic się nie zmieni.
W tym momencie utknąłem. Potwierdziłem, że konfiguracja jądra ma włączoną multiemisję. Być może istnieją inne opcje konfiguracji, które powinienem sprawdzić?
b $ grep CONFIG_IP_MULTICAST /boot/config-2.6.32-23-server
CONFIG_IP_MULTICAST=y
Czy są jakieś przemyślenia na temat tego, gdzie się udać?
rp_filter
i/proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
, a następnie rozpoczął pracę.Odpowiedzi:
W naszym przypadku nasz problem został rozwiązany za pomocą parametrów sysctl, innych niż Maciej.
Pamiętaj, że nie mówię w imieniu OP (buecking), pojawiłem się w tym poście ze względu na problem związany z podstawowymi szczegółami (brak ruchu multiemisji w obszarze użytkownika).
Mamy aplikację, która odczytuje dane wysyłane na cztery adresy multiemisji i unikalny port na adres multiemisji z urządzenia, które jest (zwykle) podłączone bezpośrednio do interfejsu na serwerze odbierającym.
Próbowaliśmy wdrożyć to oprogramowanie w witrynie klienta, gdy w tajemniczy sposób zawiodło bez żadnego znanego powodu. Próby debugowania tego oprogramowania spowodowały sprawdzenie każdego wywołania systemowego, ostatecznie wszyscy powiedzieli nam to samo:
Nasze oprogramowanie prosi o dane, a system operacyjny nigdy ich nie udostępnia.
Zwiększony licznik pakietów multiemisji, tcpdump, pokazał ruch docierający do interfejsu / konkretnego interfejsu, ale nie mogliśmy nic z tym zrobić. SELinux został wyłączony, iptables działało, ale nie miało żadnych reguł w żadnej z tabel.
Zakłopotani, byliśmy.
Podczas losowego przeszukiwania zaczęliśmy myśleć o parametrach jądra, które obsługuje sysctl, ale żadna z udokumentowanych funkcji nie była szczególnie istotna, lub jeśli miały one związek z ruchem multiemisji, były one włączone. Aha, a ifconfig umieścił „MULTICAST” w linii funkcji (up, broadcast, running, multicast). Z ciekawości spojrzeliśmy
/etc/sysctl.conf
. oto podstawowy obraz tego klienta ma na dole kilka dodatkowych wierszy.W naszym przypadku klient ustawił
net.ipv4.all.rp_filter = 1
. rp_filter to filtr Ścieżki trasy, który (jak rozumiem) odrzuca cały ruch, który nie mógłby dotrzeć do tego pola. Przeskakiwanie podsieci sieciowej, myśląc, że źródłowy adres IP jest sfałszowany.Cóż, ten serwer był w podsieci 192.168.1 / 24, a źródłowy adres IP urządzenia dla ruchu multiemisji znajdował się gdzieś w sieci 10. *. W ten sposób filtr uniemożliwiał serwerowi robienie czegokolwiek znaczącego z ruchem.
Kilka poprawek zatwierdzonych przez klienta;
net.ipv4.eth0.rp_filter = 1
inet.ipv4.eth1.rp_filter = 0
biegliśmy szczęśliwie.źródło
rp_filter
Dla naszego interfejsu sieciowego 10 Gb dumping wszystkich naszych pakietów UDP multicast. Wyłączenie filtra pozwala na przepływ wszystkiego.net.ipv4.all.rp_filter = 0
. W szczególności, gdy dane multiemisji docierały do eth2, musiałem ustawić zarównonet.ipv4.eth2.rp_filter = 0
inet.ipv4.all.rp_filter = 0
.TL / DR Upewnij się także, że multiemisja nie pochodzi z sieci Vlan.
tcpdump -e
pomogłoby ustalić, czy tak.Szczerze mówiąc, ktoś powinien zbudować stronę z listą kontrolną rzeczy, które mogą uniemożliwić multicastowi dotarcie do obszaru użytkownika. Walczyłem z tym od kilku dni i oczywiście nic, co mogłem znaleźć w Internecie, nie pomogło.
Nie tylko mogłem zobaczyć pakiety
tcpdump
, ale mogłem odbierać inne pakiety multiemisji dla innych producentów, tylko na innym interfejsie. Polecenie, którego użyłem do testowania, czy mogę odbierać multiemisję, brzmiało:Powodem
strace
jest to, że tak naprawdę nie mogłemsocat
wydrukować pakietów na standardowe wyjście, ale nastrace
wyjściu możesz wyraźnie zobaczyć, czysocat
odbiera rzeczywiste dane z powiązanego gniazda (w przeciwnym razie zostanie wyciszone po kilku początkowychselect
wywołaniach)rp_filter
sysctl - nie dotyczy, systemy są w tej samej sieci IP (ustawiłem je0
tak samo, wydaje się, że1
jest to ustawienie domyślne, przynajmniej dla Ubuntu).-e
flagi dotcpdump
i sprawdź tagi vlan. Konieczne będzie skonfigurowanie interfejsu w poprawnym vlan, zanim użytkownik będzie mógł uzyskać te pakiety. W gruncie rzeczy dla mnie było to, że producenci rozsyłania grupowego nie pingują, ale nawet nie dostają się do pamięci podręcznej ARP, chociaż wyraźnie widziałem odpowiedzi ARP.Aby uruchomić go z VLAN, ten link może być pomocny w konfiguracji routingu multiemisji. (Niestety, jestem w tym nowy, więc Reputacja nie pozwala mi dodawać odpowiedzi. Stąd ta edycja).
Oto co zrobiłem (w razie potrzeby użyj sudo):
W ten sposób dodatkowy interfejs, jeśli zostanie utworzony dla ruchu vlan z vlan id 100. IP vlan może być niepotrzebny. Następnie konfigurowany jest adres multiemisji dla nowego interfejsu (01: 00: 5e: 01: 01: 01 jest adresem warstwy łącza dla 239.1.1.1) i cały przychodzący ruch multiemisji jest powiązany z eth0_100. Zrobiłem także wszystkie możliwe kroki w powyższych odpowiedziach (sprawdź iptables, rp_filter itp.).
źródło
Możesz spróbować spojrzeć na te ustawienia:
proc
sysctl.conf
Zostały one wykorzystane do włączenia multiemisji w RHEL.
Możesz się upewnić, że zapora zezwala na ruch mutlicast; ponownie z RHEL włączyłem następujące:
źródło
Czy używasz przełącznika zarządzanego? Niektóre mają opcje zapobiegania „burzom rozgłoszeniowym” lub innym problemom związanym z multiemisją, które uniemożliwiłyby im niektóre typy pakietów. Proponuję zajrzeć do dokumentacji przełącznika.
źródło
Pewny czegos ""? Dlaczego nie skorzystać z adresu IP multiemisji do połączenia?
źródło