Kernel Linux che non passa attraverso pacchetti UDP multicast


35

Di recente ho installato un nuovo Ubuntu Server 10.04 e ho notato che il mio server UDP non è più in grado di vedere i dati multicast inviati all'interfaccia, anche dopo essermi unito al gruppo multicast. Ho configurato esattamente lo stesso su altre due macchine Ubuntu 8.04.4 LTS e non c'è alcun problema a ricevere i dati dopo essermi unito allo stesso gruppo multicast.

La scheda Ethernet è una Broadcom netXtreme II BCM5709 e il driver utilizzato è:

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

Sto usando smcroute per gestire le mie registrazioni multicast.

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

Dopo essersi unito al gruppo ip maddr mostra la registrazione appena aggiunta.

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

Fin qui tutto bene, posso vedere che sto ricevendo dati per questo gruppo multicast.

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

Posso anche confermare che l'interfaccia sta ricevendo pacchetti mcast.

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

Ora ecco il problema. Quando provo a catturare il traffico usando un semplice server UDP ruby ​​ricevo zero dati! Ecco un semplice server che legge l'invio dei dati sulla porta 15572 e stampa i primi due caratteri. Funziona sui due server Ubuntu 8.04.4, ma non sul server 10.04.

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

Se invio un pacchetto UDP creato in ruby ​​a localhost, il server lo riceve e stampa i primi due caratteri. Quindi so che il server sopra funziona correttamente.

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)

Quando controllo le statistiche del protocollo, vedo che InMcastPkts non aumenta. Mentre sugli altri server 8.04, sulla stessa rete, sono state ricevute alcune migliaia di pacchetti in 10 secondi.

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

Se provo a forzare l'interfaccia in modalità promisc, nulla cambia.

A questo punto sono bloccato. Ho confermato che la configurazione del kernel ha il multicast abilitato. Forse ci sono altre opzioni di configurazione che dovrei controllare?

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

Qualche idea su dove andare da qui?


Vai a capire. Vado a inserire una nuova domanda, l'algoritmo correlato mi mostra felicemente che questa domanda esiste, ma non ha risposte significative. Boo :(.
VxJasonxV

Non sono sicuro di come assegnerò esattamente la taglia. Un collega ha riscontrato il problema e ho capito PERCHÉ è successo come è successo. Sono più che disposto a intrattenere suggerimenti su come assegnare la taglia.
VxJasonxV,

sei ancora in giro? Ho alcune domande per te.
VxJasonxV,

Anch'io ho questo problema. Caro buecking, lo risolvi?

Per gli altri che hanno avuto questo problema - leggi tutte le risposte a questa domanda, perché ci sono 2-3 impostazioni O / S che devono essere riparate. Abbiamo risolto questo problema modificando rp_filtered /proc/sys/net/ipv4/icmp_echo_ignore_broadcastse poi è iniziato a lavorare.
Sam Goldberg,

Risposte:


35

Nel nostro caso, il nostro problema è stato risolto da parametri sysctl, uno diverso da Maciej.

Si prega di notare che non parlo per l'OP (buecking), sono venuto su questo post a causa del problema correlato dai dettagli di base (nessun traffico multicast in userland).

Abbiamo un'applicazione che legge i dati inviati a quattro indirizzi multicast e una porta univoca per indirizzo multicast, da un'appliance (di solito) connessa direttamente a un'interfaccia sul server ricevente.

Stavamo tentando di distribuire questo software su un sito del cliente quando misteriosamente fallito senza motivo noto. I tentativi di debug di questo software hanno portato all'ispezione di ogni chiamata di sistema, alla fine ci hanno detto la stessa cosa:

Il nostro software richiede dati e il sistema operativo non ne fornisce mai nessuno.

Il contatore di pacchetti multicast incrementato, tcpdump mostrava il traffico che raggiungeva il box / l'interfaccia specifica, ma non potevamo farci nulla. SELinux era disabilitato, iptables era in esecuzione ma non aveva regole in nessuna delle tabelle.

Perplessi, lo eravamo.

Frugando casualmente, abbiamo iniziato a pensare ai parametri del kernel che sysctl gestisce, ma nessuna delle funzionalità documentate era particolarmente rilevante, o se avevano a che fare con il traffico multicast, erano abilitate. Oh, e ifconfig ha elencato "MULTICAST" nella linea caratteristica (up, broadcast, running, multicast). Per curiosità abbiamo guardato /etc/sysctl.conf. Ecco, l'immagine di base di questo cliente aveva un paio di righe extra aggiunte in fondo.

Nel nostro caso, il cliente aveva impostato net.ipv4.all.rp_filter = 1. rp_filter è il filtro Percorso percorso, che (a quanto ho capito) rifiuta tutto il traffico che non avrebbe potuto raggiungere questa casella. Esplorazione della sottorete di rete, il pensiero è che l'IP di origine viene contraffatto.

Bene, questo server era su una sottorete 192.168.1 / 24 e l'indirizzo IP di origine dell'appliance per il traffico multicast era da qualche parte nella rete 10. *. Pertanto, il filtro impediva al server di eseguire operazioni significative sul traffico.

Un paio di modifiche approvate dal cliente; net.ipv4.eth0.rp_filter = 1e net.ipv4.eth1.rp_filter = 0stavamo correndo felici.


2
Questo ha funzionato! L' rp_filterinterfaccia di rete da 10 Gb stava eseguendo il dump di tutti i nostri pacchetti multicast UDP. Lo spegnimento del filtro lascia passare tutto.
chrisaycock,

Stavamo riscontrando problemi durante l'impostazione dello streaming su AMT multicast sul dispositivo tun su un ricevitore Ubuntu e potevamo vedere i pacchetti consegnati al dispositivo tramite tcpdump, ma l'applicazione non voleva semplicemente lo streaming. Questo post ci ha salvato!
ingegnere del software il

2
In esecuzione su Ubuntu 14.04, questo ha funzionato solo per me dopo aver impostato anche net.ipv4.all.rp_filter = 0. In particolare, con i dati multicast in arrivo su eth2, ho dovuto impostare sia net.ipv4.eth2.rp_filter = 0e net.ipv4.all.rp_filter = 0.
T-Hawk,

4

TL / DR Assicurati anche che il tuo multicast non provenga da un vlan. tcpdump -eaiuterebbe a determinare se lo fanno.

In tutta onestà, qualcuno dovrebbe costruire una pagina con un elenco di controllo di cose che possono impedire al multicast di raggiungere l'area utente. Ho lottato con questo per un paio di giorni, e naturalmente nulla che potessi trovare sul web mi ha aiutato.

Non solo potevo vedere i pacchetti nel tcpdump, potevo effettivamente ricevere altri pacchetti multicast, per altri produttori, solo su un'altra interfaccia. Il comando che ho finito per usare per verificare se posso ricevere multicast era:

$ 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

Il motivo di stracequesto è che in realtà non sono riuscito a socatstampare i pacchetti sullo stdout, ma stracenell'output puoi vedere chiaramente se socatsta ricevendo dati effettivi dal socket associato (sarà muto altrimenti dopo un paio di selectchiamate iniziali )

  • rp_filtersysctl - non si applica, i sistemi sono sulla stessa rete IP (li ho impostati 0tutti allo stesso modo, sembra che 1sia un'impostazione predefinita ora, almeno per Ubuntu).
  • firewall / ecc. - il sistema di ricezione è privo di firewall (non credo che i pacchetti verranno visualizzati in tcpdump se fossero protetti da firewall, ma immagino che sia possibile se il firewall è divertente)
  • Routing IP / Multicast e interfacce multiple: mi sono unito esplicitamente al gruppo sull'interfaccia corretta
  • Hardware di rete stravagante: questa è stata la mia ultima risorsa, ma cambiare alcuni laptop con un Intel NUC non ha aiutato. Questo è dove ho iniziato a mordicchiarmi i gomiti e perpetrare la pubblicazione su SE.
  • Nel mio caso il problema era l'uso delle VLAN da parte dell'hardware specializzato che produceva quei pacchetti multicast. Per vedere se questo è il tuo problema, assicurati di includere -eflag in tcpdumpe controlla i tag vlan. Sarà richiesto di configurare un'interfaccia nel vlan corretto prima che userland sia in grado di ottenere quei pacchetti. L'omaggio per me in realtà è stato che i produttori multicast non eseguono il ping, ma non entrano nemmeno nella cache ARP, anche se ho potuto vedere chiaramente le risposte ARP.

Per farlo funzionare con VLAN questo link potrebbe essere utile per configurare il routing multicast. (Purtroppo sono nuovo a questo, quindi Reputazione non mi consente di aggiungere una risposta. Da qui questa modifica.)

Ecco cosa ho fatto (usare sudo se necessario):

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

In questo modo un'interfaccia aggiuntiva se creata per il traffico vlan con vlan id 100. L'ip vlan potrebbe non essere necessario. Quindi viene configurato un indirizzo multicast per la nuova interfaccia (01: 00: 5e: 01: 01: 01 è l'indirizzo del livello di collegamento per 239.1.1.1) e tutto il traffico multicast in entrata viene associato a eth0_100. Ho anche fatto tutti i passaggi possibili nelle risposte sopra (controlla iptables, rp_filter ecc.).


@Gero: l'aggiunta del percorso multicast imposta il multicast in uscita , non il multicast in arrivo. Non dovresti associare direttamente gli indirizzi IP multicast alle interfacce, a meno che tu non stia facendo qualcosa di strano, è normalmente il lavoro dell'applicazione.
Pawel Veselov,

2

Potresti provare a guardare queste impostazioni:

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

Questi sono stati usati per abilitare il multicasting in RHEL.

Potresti voler assicurarti che il tuo firewall stia consentendo il traffico mutlicast; di nuovo con RHEL ho abilitato quanto segue:

# 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

Le opzioni "broadcast" si applicano anche al "multicast"?
Raedwald,

0

Stai usando uno switch gestito? Alcuni hanno opzioni per prevenire "tempeste di trasmissione" o altri problemi multicast, che potrebbero impedire loro determinati tipi di pacchetti. Suggerirei di dare un'occhiata alla documentazione del tuo interruttore.


0
s.bind("", 15572)

Sicuro di ""? Perché non utilizzare l'indirizzo IP multicast a cui collegarsi?


gli indirizzi host vuoti significano comunemente "tutte le interfacce".
VxJasonxV,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.