Linux-Kernel leitet keine Multicast-UDP-Pakete weiter

35

Kürzlich habe ich einen neuen Ubuntu Server 10.04 eingerichtet und festgestellt, dass mein UDP-Server keine Multicast-Daten mehr sehen kann, die an die Schnittstelle gesendet wurden, selbst nachdem er der Multicast-Gruppe beigetreten ist. Ich habe genau das gleiche Setup auf zwei anderen Ubuntu 8.04.4 LTS-Maschinen und es gibt kein Problem, Daten zu empfangen, nachdem ich derselben Multicast-Gruppe beigetreten bin.

Die Ethernet-Karte ist eine Broadcom netXtreme II BCM5709 und der verwendete Treiber ist:

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

Ich verwalte meine Multicast-Registrierungen mit smcroute.

b$ smcroute -d
b$ smcroute -j eth1 233.37.54.71

Nach dem Beitritt zur Gruppe zeigt ip maddr die neu hinzugefügte Registrierung an.

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

Soweit so gut, kann ich sehen, dass ich Daten für diese Multicast-Gruppe erhalte.

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
...

Ich kann auch bestätigen, dass die Schnittstelle Mcast-Pakete empfängt.

b $ ethtool -S eth1 | grep mcast_pack
rx_mcast_packets: 103998
tx_mcast_packets: 33

Hier ist das Problem. Wenn ich versuche, den Datenverkehr mit einem einfachen Ruby-UDP-Server zu erfassen, erhalte ich keine Daten! Hier ist ein einfacher Server, der die an Port 15572 gesendeten Daten liest und die ersten beiden Zeichen druckt. Dies funktioniert auf den beiden 8.04.4 Ubuntu Servern, nicht jedoch auf dem 10.04 Server.

require 'socket'
s = UDPSocket.new
s.bind("", 15572)
5.times do
  text, sender = s.recvfrom(2)
  puts text
end

Wenn ich ein in Ruby erstelltes UDP-Paket an localhost sende, empfängt der Server es und druckt die ersten beiden Zeichen aus. Ich weiß also, dass der Server oben richtig funktioniert.

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)

Wenn ich die Protokollstatistik überprüfe, sehe ich, dass InMcastPkts nicht zunimmt. Auf den anderen 8.04-Servern im selben Netzwerk wurden innerhalb von 10 Sekunden einige Tausend Pakete empfangen.

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

Wenn ich versuche, die Benutzeroberfläche in den Promisc-Modus zu versetzen, ändert sich nichts.

An diesem Punkt stecke ich fest. Ich habe bestätigt, dass in der Kernel-Konfiguration Multicast aktiviert ist. Vielleicht gibt es andere Konfigurationsoptionen, die ich überprüfen sollte?

b $ grep CONFIG_IP_MULTICAST /boot/config-2.6.32-23-server
CONFIG_IP_MULTICAST=y

Irgendwelche Gedanken darüber, wohin man von hier aus gehen soll?

bückend
quelle
Stelle dir das vor. Ich gehe, um eine neue Frage einzugeben. Der zugehörige Algorithmus zeigt mir gerne, dass diese Frage existiert, hat aber keine aussagekräftigen Antworten. Boo :(.
VxJasonxV
Ich bin nicht sicher, wie genau ich das Kopfgeld vergeben werde. Ein Mitarbeiter fand das Problem und ich fand heraus, WARUM es geschah, wie es geschah. Ich bin mehr als bereit, Vorschläge für die Vergabe des Kopfgeldes zu unterhalten.
VxJasonxV
bist du noch da? Ich habe ein paar Fragen für dich.
VxJasonxV
Ich habe auch dieses Problem. Liebes buecking, lösen Sie es?
Anderen, die dieses Problem hatten - lesen Sie alle Antworten auf diese Frage, da 2-3 Betriebssystemeinstellungen behoben werden müssen. Wir beschlossen , dieses Problem durch eine Änderung rp_filterund /proc/sys/net/ipv4/icmp_echo_ignore_broadcastsund es begann dann zu arbeiten.
Sam Goldberg

Antworten:

35

In unserem Fall wurde unser Problem durch sysctl-Parameter gelöst, die sich von denen von Maciej unterscheiden.

Bitte beachte, dass ich nicht für das OP spreche (buecking), ich bin auf diesen Beitrag gekommen, weil das Problem durch das grundlegende Detail zusammenhängt (kein Multicast-Verkehr im Userland).

Wir haben eine Anwendung, die an vier Multicast-Adressen gesendete Daten und einen eindeutigen Port pro Multicast-Adresse von einer Appliance liest, die (normalerweise) direkt mit einer Schnittstelle auf dem empfangenden Server verbunden ist.

Wir haben versucht, diese Software auf einem Kundenstandort bereitzustellen, als sie ohne bekannten Grund auf mysteriöse Weise fehlschlug. Versuche, diese Software zu debuggen, führten dazu, dass jeder Systemaufruf überprüft wurde. Letztendlich sagten uns alle dasselbe:

Unsere Software fragt nach Daten, und das Betriebssystem stellt keine zur Verfügung.

Der Multicast-Paketzähler wurde inkrementiert, tcpdump zeigte den Datenverkehr an, der die Box / spezifische Schnittstelle erreichte, aber wir konnten nichts damit anfangen. SELinux war deaktiviert, iptables wurde ausgeführt, es gab jedoch keine Regeln in einer der Tabellen.

Verblüfft waren wir.

Beim zufälligen Herumstöbern haben wir uns Gedanken über die Kernelparameter gemacht, die sysctl verarbeitet, aber keine der dokumentierten Funktionen war besonders relevant, oder wenn sie mit Multicast-Verkehr zu tun hatten, waren sie aktiviert. Oh, und ifconfig listete "MULTICAST" in der Feature-Zeile auf (up, broadcast, running, multicast). Aus Neugier haben wir angeschaut /etc/sysctl.conf. Bitte beachten Sie, dass dem Basis-Image dieses Kunden unten ein paar zusätzliche Zeilen hinzugefügt wurden.

In unserem Fall hatte der Kunde eingestellt net.ipv4.all.rp_filter = 1. rp_filter ist der Route Path-Filter, der (wie ich es verstehe) den gesamten Verkehr ablehnt, der diese Box möglicherweise nicht erreicht haben könnte. Netzwerk-Subnetz-Hopping, der Gedanke ist, dass die Quell-IP gefälscht wird.

Dieser Server befand sich in einem 192.168.1 / 24-Subnetz und die Quell-IP-Adresse der Appliance für den Multicast-Verkehr befand sich irgendwo im 10. * Netzwerk. Daher verhinderte der Filter, dass der Server mit dem Datenverkehr etwas Sinnvolles anfing.

Ein paar vom Kunden genehmigte Änderungen; net.ipv4.eth0.rp_filter = 1und net.ipv4.eth1.rp_filter = 0und wir rannten glücklich.

VxJasonxV
quelle
2
Das hat funktioniert! Die rp_filterfür unsere 10-Gbit-Netzwerkschnittstelle hat alle unsere UDP-Multicast-Pakete ausgegeben. Den Filter abschalten und alles durchfließen lassen.
Chrisaycock
Wir hatten Probleme beim Einrichten des Streamings über AMT-Multicast über das Tun-Gerät auf einem Ubuntu-Empfänger, und wir konnten feststellen, dass Pakete über tcpdump an das Gerät gesendet wurden, aber die Anwendung möchte einfach kein Streaming durchführen. Dieser Beitrag hat uns gerettet!
Software Engineer
2
Unter Ubuntu 14.04 funktionierte dies nur, nachdem ich es auch eingestellt hatte net.ipv4.all.rp_filter = 0. Insbesondere mit den Multicast-Daten, die auf eth2 ankamen, musste ich sowohl net.ipv4.eth2.rp_filter = 0als auch festlegen net.ipv4.all.rp_filter = 0.
T-Hawk
4

TL / DR Stellen Sie außerdem sicher, dass Ihr Multicast nicht von einem VLAN stammt. tcpdump -ewürde helfen festzustellen, ob sie es tun.

Um ehrlich zu sein, sollte jemand eine Seite mit einer Checkliste von Dingen erstellen, die verhindern können, dass Multicast das Benutzerland erreicht. Ich habe seit ein paar Tagen damit zu kämpfen, und natürlich half nichts, was ich im Internet finden konnte.

Ich konnte nicht nur die Pakete im sehen tcpdump, sondern auch andere Multicast-Pakete für andere Hersteller erhalten, nur auf einer anderen Schnittstelle. Der Befehl, mit dem ich getestet habe, ob ich Multicast empfangen kann, war:

$ GRP=224.x.x.x # set me to the group
$ PORT=yyyy # set me to the receiving port
$ IFACE=mmmm # set me to the name or IP address of the interface
$ strace -f socat -  UDP4-DATAGRAM:$GRP:$PORT,ip-add-membership=$GRP:$IFACE,bind=0.0.0.0:$PORT,multicast-loop=0

Der Grund stracehier ist , dass ich eigentlich nicht machen socatdie Pakete an die stdout ausdrucken, aber in straceAusgabe kann man deutlich sehen , ob socatIstdaten von dem gebundenen Aufnahmebuchse (es stumm sonst nach ein paar anfänglichen sein werden selectAnrufe)

  • rp_filtersysctl - trifft nicht zu, die Systeme befinden sich im selben IP-Netzwerk (ich habe sie auf den gleichen Wert eingestellt 0, das scheint 1jetzt eine Standardeinstellung zu sein, zumindest für Ubuntu).
  • firewalls / etc - das empfangende system ist frei von firewalls (ich glaube nicht, dass pakete in tcpdump angezeigt werden, wenn sie firewalls waren, aber ich denke, es ist möglich, wenn die firewalls witzig sind)
  • IP / Multicast-Routing und mehrere Schnittstellen - Ich bin der Gruppe explizit über die richtige Schnittstelle beigetreten
  • Verrückte Netzwerkhardware - das war mein letzter Ausweg, aber der Wechsel eines Laptops zu einem Intel NUC half nicht. Hier habe ich angefangen, an meinen Ellbogen zu kauen und dies an SE zu senden.
  • Das Problem in meinem Fall war die Verwendung von VLANs durch die spezialisierte Hardware, die diese Multicast-Pakete produzierte. Um festzustellen, ob dies Ihr Problem ist, stellen Sie sicher, dass Sie -eflag to tcpdumpeinschließen und nach vlan-Tags suchen. Es ist erforderlich, eine Schnittstelle für das richtige VLAN zu konfigurieren, bevor userland diese Pakete abrufen kann. Das Werbegeschenk für mich war eigentlich, dass die Multicast-Produzenten nicht pingen, aber nicht einmal in den ARP-Cache gelangen, obwohl ich ARP-Antworten deutlich sehen konnte.

Um es mit VLAN zum Laufen zu bringen, kann dieser Link hilfreich sein, um das Multicast-Routing zu konfigurieren. (Leider bin ich neu in diesem Bereich, so dass ich aufgrund des Ansehens keine Antwort hinzufügen kann. Daher diese Änderung.)

Folgendes habe ich getan (benutze sudo, wenn nötig):

ip link add link eth0 name eth0_100 type vlan id 100
ip addr add 192.168.100.2/24 brd 192.168.100.255 dev eth0_100
ip link set dev eth0_100 up
ip maddr add 01:00:5e:01:01:01 dev eth0_100
route -n add -net 224.0.0.0 netmask 240.0.0.0 dev eth0_100

Auf diese Weise wird eine zusätzliche Schnittstelle für den VLAN-Verkehr mit der VLAN-ID 100 erstellt. Die VLAN-IP ist möglicherweise nicht erforderlich. Dann wird eine Multicast-Adresse für die neue Schnittstelle konfiguriert (01: 00: 5e: 01: 01: 01 ist die Verbindungsschichtadresse für 239.1.1.1) und der gesamte eingehende Multicast-Verkehr wird an eth0_100 gebunden. Ich habe auch alle möglichen Schritte in den obigen Antworten ausgeführt (iptables, rp_filter usw. überprüfen).

Pawel Veselov
quelle
@Gero: Durch Hinzufügen einer Multicast-Route wird ausgehender Multicast eingerichtet, nicht eingehender Multicast. Sie sollten Multicast-IP-Adressen nicht direkt an Schnittstellen binden, es sei denn, Sie tun etwas Ungewöhnliches, es ist normalerweise die Aufgabe der Anwendung.
Pawel Veselov
2

Vielleicht möchten Sie versuchen, sich diese Einstellungen anzusehen:

proc

echo "0" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts

sysctl.conf

sed -i -e 's|^net.ipv4.icmp_echo_ignore_broadcasts =.*|net.ipv4.icmp_echo_ignore_broadcasts = 0|g' /etc/sysctl.conf

Diese wurden verwendet, um Multicasting in RHEL zu ermöglichen.

Möglicherweise möchten Sie sicherstellen, dass Ihre Firewall den Mutlicast-Verkehr zulässt. wieder mit RHEL habe ich folgendes aktiviert:

# allow anything in on multicast addresses
-A INPUT -s 224.0.0.0/4 -j ACCEPT
-A INPUT -p igmp -d 224.0.0.0/4 -j ACCEPT
# needed for multicast ping responses
-A INPUT -p icmp --icmp-type 0 -j ACCEPT
user64259
quelle
"Broadcast" -Optionen gelten auch für "Multicast"?
Raedwald
0

Verwenden Sie einen verwalteten Switch? Einige haben Optionen, um "Broadcast Storms" oder andere Multicast-Probleme zu verhindern, die dazu führen würden, dass sie bestimmte Pakettypen verhindern. Ich würde vorschlagen, einen Blick auf Ihre Switch-Dokumentation zu werfen.

Gerät
quelle
0
s.bind("", 15572)

Sicher über ""? Warum nicht die Multicast-IP-Adresse zum Binden verwenden?

Poige
quelle
Leere Hostadressen bedeuten üblicherweise "alle Schnittstellen".
VxJasonxV