Frage Linux-Kernel wird nicht durch Multicast-UDP-Pakete geleitet


Vor kurzem habe ich einen neuen Ubuntu-Server 10.04 eingerichtet und festgestellt, dass mein UDP-Server nicht mehr in der Lage ist um alle Multicast-Daten anzuzeigen, die an die Schnittstelle gesendet wurden, selbst nachdem sie der Multicast-Gruppe beigetreten sind. Ich habe das gleiche Setup auf zwei anderen Ubuntu 8.04.4 LTS-Rechnern und es gibt kein Problem beim Empfangen von Daten nach dem Beitritt der gleichen Multicast-Gruppe.

Die Ethernet-Karte ist ein 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 verwende smcroute, um meine Multicast-Registrierungen zu verwalten.

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

So weit, so gut, ich kann sehen, dass ich Daten für diese Multicast-Gruppe empfange.

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

Jetzt ist hier das Problem. Wenn ich versuche, den Verkehr mit einem einfachen Ruby-UDP-Server zu erfassen, erhalte ich null Daten! Hier ist ein einfacher Server, der Daten liest, die an Port 15572 gesendet werden, und druckt die ersten zwei Zeichen. Dies funktioniert auf den beiden 8.04.4 Ubuntu Servern, nicht aber 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 zwei Zeichen aus. Ich weiß also, dass der obige Server 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. Während an Die anderen 8.04-Server im selben Netzwerk erhielten in zehn Sekunden einige tausend Pakete.

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 Schnittstelle in Promisc-Modus zu zwingen, ändert sich nichts.

An diesem Punkt stecke ich fest. Ich habe bestätigt, dass die Kernel-Konfiguration Multicast aktiviert hat. 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, wohin du von hier gehst?


32
2017-07-23 01:00


Ursprung


Stelle dir das vor. Ich gehe, um eine neue Frage einzugeben, der verwandte Algorithmus zeigt mir glücklich, dass diese Frage existiert, aber es hat keine sinnvollen Antworten. Boo :(. - VxJasonxV
Ich bin mir nicht sicher, wie genau ich das Kopfgeld vergeben werde. Ein Kollege hat das Problem gefunden und ich habe herausgefunden, WARUM es passiert ist. Ich bin mehr als bereit, Vorschläge zu unterbreiten, wie man das Kopfgeld vergibt. - VxJasonxV
bist du noch da? Ich habe ein paar Fragen für dich. - VxJasonxV
Ich habe dieses Problem auch. Lieber Bückling, löst du es?
An andere, die dieses Problem hatten - lies alle Antworten zu dieser Frage, weil es 2-3 O / S-Einstellungen gibt, die behoben werden müssen. Wir haben dieses Problem gelöst, indem wir geändert haben rp_filter und /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts und dann fing es an zu arbeiten. - Sam Goldberg


Antworten:


In unserem Fall wurde unser Problem durch sysctl-Parameter gelöst, eine andere als Maciej.

Bitte beachten Sie, dass ich nicht für das OP (buecking) spreche, ich kam auf diesen Beitrag wegen des Problems, das durch das grundlegende Detail (kein Multicast-Verkehr in userland) verwandt ist.

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

Wir haben versucht, diese Software auf einer Kundenseite zu installieren, als sie auf geheimnisvolle Weise ohne bekannten Grund fehlschlug. Versuche, diese Software zu debuggen, führten dazu, dass alle Systemaufrufe überprüft wurden. Letztendlich sagten sie uns alle dasselbe:

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

Der Multicast-Paketzähler wurde inkrementiert, tcpdump zeigte, dass der Verkehr die Box / spezifische Schnittstelle erreichte, aber wir konnten nichts damit anfangen. SELinux war deaktiviert, iptables lief, hatte aber in keiner der Tabellen Regeln.

Stupid waren wir.

Beim zufälligen Stöbern begannen wir, über die Kernel-Parameter nachzudenken, die sysctl behandelt, aber keines der dokumentierten Features war besonders relevant, oder wenn sie mit dem Multicast-Verkehr zu tun hatten, wurden sie aktiviert. Oh, und ifconfig listete "MULTICAST" in der Featurezeile auf (up, broadcast, running, multicast). Aus Neugier blickten wir uns an /etc/sysctl.conf. "Und siehe da, das Basisbild dieses Kunden wurde um ein paar zusätzliche Zeilen erweitert.

In unserem Fall hatte der Kunde festgelegt net.ipv4.all.rp_filter = 1. rp_filter ist der Route-Path-Filter, der (wie ich es verstehe) den gesamten Datenverkehr ablehnt, der dieses Feld möglicherweise nicht erreicht hätte. Netzwerk-Subnetz-Hopping, wobei der Gedanke besteht, dass die Quell-IP gefälscht wird.

Nun, 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. Somit verhinderte der Filter, dass der Server etwas Sinnvolles mit dem Verkehr machte.

Ein paar Verbesserungen vom Kunden genehmigt; net.ipv4.eth0.rp_filter = 1 und net.ipv4.eth1.rp_filter = 0 und wir liefen glücklich.


31
2017-12-27 22:50



Das hat funktioniert! Das rp_filter Für unsere 10-Gb-Netzwerkschnittstelle wurden alle unsere UDP-Multicast-Pakete gedumpt. Wenn Sie den Filter ausschalten, fließt alles durch. - chrisaycock
Wir hatten Probleme beim Einrichten von Streaming über AMT-Multicast über das Tun-Gerät auf einem Ubuntu-Empfänger, und wir konnten sehen, dass Pakete über tcpdump an das Gerät gesendet wurden, aber die Anwendung wollte einfach nicht streamen. Dieser Beitrag hat uns gerettet! - software engineer


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

In aller Fairness sollte jemand eine Seite mit einer Checkliste von Dingen bauen, die verhindern können, dass Multicast das Nutzerland erreicht. Ich habe ein paar Tage damit zu kämpfen, und natürlich half nichts, was ich im Web finden konnte.

Nicht nur ich konnte die Pakete in der tcpdump, Ich könnte tatsächlich andere Multicast-Pakete für andere Hersteller nur an einer anderen Schnittstelle empfangen. Der Befehl, den ich zum Testen verwendet 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 für strace hier ist, dass ich eigentlich nicht machen konnte socat die Pakete zum stdout ausdrucken, aber in strace Ausgabe können Sie deutlich sehen, ob socat empfängt tatsächliche Daten von der gebundenen Buchse (es wird sonst nach ein paar Initialen stummgeschaltet) select Anrufe)

  • rp_filter sysctl - trifft nicht zu, die Systeme sind im selben IP-Netzwerk (ich setze sie auf 0 trotzdem scheint das 1 ist jetzt eine Standardeinstellung, zumindest für Ubuntu).
  • Firewalls / etc - das Empfangssystem ist Firewall-frei (ich glaube nicht, dass Pakete in tcpdump angezeigt werden, wenn sie Firewalls sind, aber ich denke, es ist möglich, wenn die Firewall witzig ist)
  • IP / Multicast-Routing und mehrere Schnittstellen - Ich bin der Gruppe explizit an der richtigen Schnittstelle beigetreten
  • Verrückte Netzwerkhardware - das war mein letzter Ausweg, aber das Umrüsten von einem Laptop zu einem Intel NUC hat nicht geholfen. Das ist ungefähr da, wo ich begonnen habe, meine Ellbogen zu kauen und es in SE zu veröffentlichen.
  • Das Problem in meinem Fall war die Verwendung von VLANs durch die spezialisierte Hardware, die diese Multicast-Pakete erzeugte. Um zu sehen, ob dies Ihr Problem ist, stellen Sie sicher, dass das Problem auftritt -e Flagge zu tcpdumpund nach vlan-Tags suchen. Es wird erforderlich sein, eine Schnittstelle in den korrekten Vlan zu konfigurieren, bevor Benutzerland diese Pakete erhalten kann. Das Giveaway für mich war eigentlich, dass die Multicast-Produzenten nicht pingen werden, aber nicht einmal in den ARP-Cache gelangen, obwohl ich deutlich ARP-Antworten sehen konnte.

Um es mit VLAN laufen zu lassen dieser Link kann hilfreich sein, Multicast-Routing zu konfigurieren. (Leider bin ich neu hier, so dass Reputation es mir nicht erlaubt, eine Antwort hinzuzufügen. Daher diese Bearbeitung.)

Hier ist was ich getan habe (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-Adresse ist möglicherweise nicht erforderlich. Dann wird eine Multicast-Adresse für die neue Schnittstelle konfiguriert (01: 00: 5e: 01: 01: 01 ist die Link-Layer-Adresse für 239.1.1.1) und der gesamte eingehende Multicast-Verkehr ist an eth0_100 gebunden. Ich habe auch alle möglichen Schritte in den Antworten oben gemacht (iptables, rp_filter etc.).


3
2017-07-08 08:10



@Gero: Das Hinzufügen von Multicast-Routen wird eingerichtet ausgehend Multicast, nicht ankommendes Multicast. Sie sollten Multicast-IP-Adressen nicht direkt an Schnittstellen binden, es sei denn, Sie tun etwas Funkhaftes, es ist normalerweise Aufgabe der Anwendung. - Pawel Veselov


Vielleicht möchten Sie diese Einstellungen ausprobieren:

Proz

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 zum Aktivieren von Multicasting in RHEL verwendet.

Möglicherweise möchten Sie sicherstellen, dass Ihre Firewall den Multicast-Datenverkehr 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

2
2017-12-21 00:27



Broadcast-Optionen gelten auch für "Multicast"? - Raedwald


Verwenden Sie einen verwalteten Switch? Einige haben Optionen, Broadcast-Stürme oder andere Multicast-Probleme zu verhindern, die dazu führen, dass sie bestimmte Arten von Paketen verhindern. Ich würde vorschlagen, dass Sie sich Ihre Switch-Dokumentation ansehen.


0
2017-12-21 02:54





s.bind("", 15572)

Sicher über ""? Warum nicht mit der Multicast-IP-Adresse verbinden?


0
2018-01-31 18:19



leere Host-Adressen bedeuten üblicherweise "alle Schnittstellen". - VxJasonxV