Linux Kernel não passando por pacotes UDP multicast

33

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

A placa ethernet é uma 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 de multicast.

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

Após entrar no grupo ip maddr mostra o novo registro 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, eu posso ver que estou recebendo dados para este 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
...

Eu 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 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 localhost, 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 eu verifico as estatísticas do protocolo, vejo que InMcastPkts não está aumentando. Enquanto que na os outros servidores 8.04, na mesma rede, receberam 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 momento, estou preso. Confirmei que a configuração do kernel tem multicast ativado. Talvez existam 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 sobre para onde ir a partir daqui?

    
por buecking 23.07.2010 / 03:00

5 respostas

33

Em nossa instância, nosso problema foi resolvido pelos parâmetros sysctl, um diferente do Maciej.

Por favor, note que eu não falo para o OP (buecking), eu vim a este post devido ao problema ser relacionado pelo detalhe básico (sem tráfego multicast no userland).

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

Estávamos tentando implantar esse software em um site do cliente quando ele misteriosamente falhava sem motivo conhecido. Tentativas de depurar este 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, o tcpdump mostrou o tráfego chegando à caixa / interface específica, mas não conseguimos fazer nada com ele. O SELinux foi desativado, o iptables estava em execução, mas não tinha regras em nenhuma das tabelas.

Ficamos confusos.

Ao bisbilhotar aleatoriamente, começamos a pensar sobre os 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 ifconfig listou "MULTICAST" na linha de recursos (up, broadcast, running, multicast). Por curiosidade, olhamos para /etc/sysctl.conf . E eis que, a imagem de base desse cliente tinha algumas linhas extras adicionadas a ele na parte inferior.

No nosso caso, o cliente definiu net.ipv4.all.rp_filter = 1 . rp_filter é o filtro Caminho de Rota, que (pelo que entendi) rejeita todo o tráfego que não poderia ter atingido essa caixa. Rede de sub-rede hopping, o pensamento é que o IP de origem está sendo falsificado.

Bem, esse 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. *. Assim, o filtro estava impedindo o servidor de fazer algo significativo com o tráfego.

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

    
por 27.12.2010 / 23:50
3

TL / DR Verifique também se o seu multicast não vem de uma vlan. tcpdump -e ajudaria a determinar se eles fazem isso.

Com toda a honestidade, alguém deve construir uma página com uma lista de coisas que podem impedir que o multicast chegue à terra do usuário. Eu tenho lutado com isso por alguns dias e, naturalmente, nada que eu encontrei na web ajudou.

Não só eu pude ver os pacotes no tcpdump , eu realmente poderia receber outros pacotes multicast, para outros produtores, apenas em uma interface diferente. O comando que acabei usando para testar se eu posso receber 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

O motivo para strace aqui é que eu realmente não consegui fazer socat imprimir os pacotes no stdout, mas em strace output você pode ver claramente se socat está recebendo dados reais do limite socket (será mudo de outra forma após algumas chamadas select iniciais)

  • rp_filter sysctl - não se aplica, os sistemas estão na mesma rede IP (eu os defini como 0 , parece que 1 é uma configuração padrão agora, pelo menos para o Ubuntu).
  • firewalls / etc - o sistema de recebimento é livre de firewall (eu não acho que os pacotes aparecerão no tcpdump se eles fossem protegidos por firewall, mas eu acho que é possível se o firewall é engraçado)
  • Roteamento IP / Multicast e várias interfaces - Eu me associei explicitamente ao grupo na interface correta
  • Hardware de rede maluco - esse foi meu último recurso, mas mudar alguns notebooks para um Intel NUC não ajudou. Isto é sobre onde eu comecei a mastigar meus cotovelos e perpetrar postando isso para SE.
  • O problema no meu caso foi o uso de VLANs pelo hardware especializado que estava produzindo esses pacotes multicast. Para ver se esse é seu problema, inclua -e flag em tcpdump e verifique se há tags vlan. Será necessário configurar uma interface na vlan correta antes que o userland possa obter esses pacotes. A oferta para mim, na verdade, foi que os produtores de multicast não farão ping, mas nem entrarão no cache do ARP, embora eu possa ver claramente as respostas do ARP.

Para executá-lo com VLAN este link pode ser útil para configurar roteamento multicast. (Infelizmente eu sou novo nisso, então Reputation 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

Desta forma, uma interface adicional se for criada para o tráfego vlan com vlan id 100. O vlan ip 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 de entrada é ligado a eth0_100. Eu também fiz todos os passos possíveis nas respostas acima (verifique iptables, rp_filter etc).

    
por 08.07.2016 / 10:10
2

Você pode tentar ver essas 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

Estes foram usados para habilitar o multicast no RHEL.

Você pode querer certificar-se de que seu firewall está permitindo o tráfego de mutlicast; novamente com o RHEL eu 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
    
por 21.12.2010 / 01:27
0

Você está usando um switch gerenciado? Alguns têm opções para evitar 'tempestades de broadcast' ou outros problemas de multicast, que os impediriam de certos tipos de pacotes. Eu sugeriria dar uma olhada na documentação do seu switch.

    
por 21.12.2010 / 03:54
0
s.bind("", 15572)

Claro sobre ""? Por que não usar o endereço IP multicast para ligar?

    
por 31.01.2011 / 19:19