Kernel do Linux não passando por pacotes UDP multicast

35

Recentemente, configurei um novo Ubuntu Server 10.04 e notei que meu servidor UDP não é mais capaz de ver dados multicast enviados para a interface, mesmo depois de ingressar no grupo multicast. Eu tenho exatamente o mesmo configurado em duas outras máquinas Ubuntu 8.04.4 LTS e não há problema em receber dados depois de ingressar no mesmo grupo multicast.

A placa Ethernet é um Broadcom netXtreme II BCM5709 e o driver usado é:

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

Estou usando o smcroute para gerenciar meus registros multicast.

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

Depois de ingressar no grupo, o ip maddr mostra o registro recém-adicionado.

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

Até aí tudo bem, posso ver que estou recebendo dados para esse grupo 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
...

Também posso confirmar que a interface está recebendo pacotes mcast.

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

Agora aqui está o problema. Quando tento capturar o tráfego usando um servidor UDP ruby ​​simples, recebo zero dados! Aqui está um servidor simples que lê o envio de dados na porta 15572 e imprime os dois primeiros caracteres. Isso funciona nos dois servidores Ubuntu 8.04.4, mas não no servidor 10.04.

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

Se eu enviar um pacote UDP criado em ruby ​​para o host local, o servidor o receberá e imprimirá os dois primeiros caracteres. Então eu sei que o servidor acima está funcionando corretamente.

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 verifico as estatísticas do protocolo, vejo que o InMcastPkts não está aumentando. Enquanto nos outros servidores 8.04, na mesma rede, recebeu alguns milhares de pacotes em 10 segundos.

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 eu tentar forçar a interface no modo promisc nada muda.

Neste ponto, eu estou preso. Confirmei que a configuração do kernel tem o multicast ativado. Talvez haja outras opções de configuração que eu deveria estar verificando?

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

Alguma idéia de para onde ir a partir daqui?

verificação
fonte
Vai saber. Entro em uma nova pergunta, o algoritmo relacionado mostra-me felizmente que essa pergunta existe, mas não tem respostas significativas. Boo :(.
VxJasonxV
Não tenho certeza de como exatamente vou premiar a recompensa. Um colega de trabalho encontrou o problema, e eu descobri por que aconteceu como aconteceu. Estou mais do que disposta a receber sugestões de como conceder a recompensa.
precisa saber é o seguinte
você ainda está por aí? Eu tenho algumas perguntas para você.
VxJasonxV
Eu tenho esse problema tambem. Caro comprador, você resolve?
Para outras pessoas que tiveram esse problema - leia todas as respostas sobre essa pergunta, porque há 2-3 configurações de O / S que precisam ser corrigidas. Resolvemos esse problema alterando rp_filtere /proc/sys/net/ipv4/icmp_echo_ignore_broadcastsem seguida, ele começou a trabalhar.
Sam Goldberg

Respostas:

35

Em nosso exemplo, nosso problema foi resolvido por parâmetros sysctl, um diferente do Maciej.

Observe que eu não falo pelo OP (verificação), vim nesta postagem devido ao problema estar relacionado aos detalhes básicos (sem tráfego multicast na área do usuário).

Temos um aplicativo que lê dados enviados para quatro endereços de difusão seletiva e uma porta exclusiva por endereço de difusão seletiva, de um dispositivo (geralmente) conectado diretamente a uma interface no servidor de recebimento.

Estávamos tentando implantar esse software no site de um cliente quando ele falhou misteriosamente sem motivo conhecido. Tentativas de depuração deste software resultaram na inspeção de todas as chamadas do sistema; no final, todas elas nos disseram a mesma coisa:

Nosso software solicita dados e o sistema operacional nunca fornece nenhum.

O contador de pacotes multicast foi incrementado, tcpdump mostrou o tráfego atingindo a caixa / interface específica, mas não conseguimos fazer nada com isso. O SELinux estava desativado, o iptables estava em execução, mas não possuía regras em nenhuma das tabelas.

Perplexo, nós estávamos.

Ao bisbilhotar aleatoriamente, começamos a pensar nos parâmetros do kernel que o sysctl manipula, mas nenhum dos recursos documentados era particularmente relevante ou, se tivessem a ver com o tráfego multicast, eles estavam habilitados. Ah, e o ifconfig listou "MULTICAST" na linha de recursos (up, broadcast, running, multicast). Por curiosidade, olhamos /etc/sysctl.conf. Eis que a imagem base deste cliente tinha duas linhas extras adicionadas a ela na parte inferior.

No nosso caso, o cliente havia definido net.ipv4.all.rp_filter = 1. rp_filter é o filtro Route Path, que (como eu o entendo) rejeita todo o tráfego que não poderia ter atingido essa caixa. Salto de sub-rede da rede, pensando que o IP de origem está sendo falsificado.

Bem, este servidor estava em uma sub-rede 192.168.1 / 24 e o endereço IP de origem do dispositivo para o tráfego multicast estava em algum lugar na rede 10. *. Portanto, o filtro impedia que o servidor fizesse algo significativo com o tráfego.

Alguns ajustes aprovados pelo cliente; net.ipv4.eth0.rp_filter = 1e net.ipv4.eth1.rp_filter = 0e estávamos correndo alegremente.

VxJasonxV
fonte
2
Isso funcionou! A rp_filterinterface de rede de 10 Gb despejava todos os pacotes multicast UDP. Desligar o filtro deixa tudo fluir.
Chrisaycock
Estávamos tendo problemas ao configurar o streaming via multicast AMT sobre o dispositivo tun em um receptor Ubuntu, e podíamos ver pacotes sendo entregues ao dispositivo via tcpdump, mas o aplicativo simplesmente não deseja transmitir. Este post nos salvou!
engenheiro de software
2
Rodando no Ubuntu 14.04, isso só funcionou para mim depois que eu também configurei net.ipv4.all.rp_filter = 0. Especificamente, com os dados multicast chegando no eth2, eu tive que definir ambos net.ipv4.eth2.rp_filter = 0e net.ipv4.all.rp_filter = 0.
T-Hawk
4

TL / DR Verifique também se o multicast não é proveniente de uma vlan. tcpdump -eajudaria a determinar se sim.

Com toda a justiça, alguém deve criar uma página com uma lista de coisas que podem impedir que o multicast chegue ao país do usuário. Estou lutando com isso há alguns dias e, naturalmente, nada que eu pudesse encontrar na Web ajudou.

Não apenas eu podia ver os pacotes no tcpdump, mas também receber outros pacotes multicast, para outros produtores, apenas em uma interface diferente. O comando que acabei usando para testar se posso receber multicast foi:

$ 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

A razão para straceisso é que, na verdade, eu não conseguia socatimprimir os pacotes no stdout, mas na stracesaída você pode ver claramente se socatestá recebendo dados reais do soquete vinculado (será mudo caso contrário após algumas selectchamadas iniciais )

  • rp_filtersysctl - não se aplica, os sistemas estão na mesma rede IP (eu os defino 0da mesma forma, parece que 1é uma configuração padrão agora, pelo menos para o Ubuntu).
  • firewalls / etc - o sistema receptor é livre de firewall (não acho que os pacotes aparecerão no tcpdump se estiverem com firewall, mas acho que é possível se o firewall for engraçado)
  • Roteamento IP / Multicast e várias interfaces - ingressei explicitamente no grupo na interface correta
  • Hardware de rede maluco - esse foi meu último recurso, mas mudar um laptop para um Intel NUC não ajudou. Foi aqui que comecei a roer os cotovelos e a postar isso no SE.
  • O problema no meu caso foi o uso de VLANs pelo hardware especializado que produzia esses pacotes multicast. Para verificar se esse é o seu problema, inclua -esinalizador para tcpdumpe verifique as tags vlan. Será necessário configurar uma interface na vlan correta antes que a terra do usuário possa obter esses pacotes. A oferta para mim, na verdade, foi que os produtores de difusão seletiva não efetuam ping, mas nem chegam ao cache do ARP, embora eu pudesse ver claramente as respostas do ARP.

Para executá-lo com VLAN, esse link pode ser útil para configurar o roteamento multicast. (Infelizmente, sou novo nisso, portanto a Reputação não me permite adicionar uma resposta. Daí esta edição.)

Aqui está o que eu fiz (use o sudo, se necessário):

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

Dessa maneira, uma interface adicional, se criada para o tráfego da vlan com o vlan id 100. O ip da vlan pode ser desnecessário. Em seguida, um endereço multicast é configurado para a nova interface (01: 00: 5e: 01: 01: 01 é o endereço da camada de link para 239.1.1.1) e todo o tráfego multicast recebido é vinculado a eth0_100. Eu também fiz todas as etapas possíveis nas respostas acima (verifique iptables, rp_filter etc).

Pawel Veselov
fonte
@ Gero: Adicionar rota multicast configura multicast de saída , não multicast de entrada. Você não deve vincular endereços IP multicast a interfaces diretamente, a menos que esteja fazendo algo descolado, normalmente é o trabalho do aplicativo.
Pawel Veselov
2

Você pode tentar examinar estas configurações:

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

Eles foram usados ​​para habilitar o multicasting no RHEL.

Você pode querer se certificar de que seu firewall está permitindo o tráfego mutlast; novamente com o RHEL, habilitei o seguinte:

# 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
fonte
As opções "broadcast" também se aplicam ao "multicast"?
precisa
0

Você está usando um comutador gerenciado? Alguns têm opções para evitar 'tempestades de transmissão' ou outros problemas de difusão seletiva, o que os faria impedir certos tipos de pacotes. Eu sugiro dar uma olhada na documentação do seu switch.

devicenull
fonte
0
s.bind("", 15572)

Tem certeza de ""? Por que não usar o endereço IP multicast para vincular?

poige
fonte
endereços de host vazios geralmente significam "todas as interfaces".
VxJasonxV