Kernel Linux tidak melewati paket UDP multicast

35

Baru-baru ini saya telah menyiapkan Ubuntu Server 10.04 baru dan menyadari bahwa server UDP saya tidak lagi dapat melihat data multicast dikirim ke antarmuka, bahkan setelah bergabung dengan grup multicast. Saya memiliki pengaturan yang sama persis pada dua mesin Ubuntu 8.04.4 LTS lainnya dan tidak ada masalah dalam menerima data setelah bergabung dengan grup multicast yang sama.

Kartu ethernet adalah Broadcom netXtreme II BCM5709 dan driver yang digunakan adalah:

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

Saya menggunakan smcroute untuk mengelola pendaftaran multicast saya.

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

Setelah bergabung dengan grup, ip maddr menunjukkan pendaftaran yang baru ditambahkan.

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

Sejauh ini bagus, saya dapat melihat bahwa saya menerima data untuk grup multicast ini.

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

Saya juga dapat mengonfirmasi bahwa antarmuka menerima paket mcast.

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

Sekarang, inilah masalahnya. Ketika saya mencoba untuk menangkap lalu lintas menggunakan server UDP ruby ​​sederhana, saya menerima nol data! Inilah server sederhana yang membaca pengiriman data pada port 15572 dan mencetak dua karakter pertama. Ini berfungsi pada dua Server Ubuntu 8.04.4, tetapi tidak pada server 10.04.

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

Jika saya mengirim paket UDP dibuat dalam ruby ​​ke localhost, server menerimanya dan mencetak dua karakter pertama. Jadi saya tahu bahwa server di atas berfungsi dengan benar.

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)

Ketika saya memeriksa statistik protokol saya melihat bahwa InMcastPkts tidak meningkat. Sementara di server 8.04 lainnya, di jaringan yang sama, menerima beberapa ribu paket dalam 10 detik.

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

Jika saya mencoba memaksa antarmuka ke mode promisc tidak ada perubahan.

Pada titik ini saya terjebak. Saya telah mengkonfirmasi konfigurasi kernel telah mengaktifkan multicast. Mungkin ada opsi konfigurasi lain yang harus saya periksa?

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

Adakah pemikiran ke mana harus pergi dari sini?

buecking
sumber
Sosok pergi. Saya masuk untuk memasukkan pertanyaan baru, algoritma terkait dengan senang hati menunjukkan kepada saya bahwa pertanyaan ini ada, tetapi tidak memiliki jawaban yang berarti. Boo :(.
VxJasonxV
Saya tidak yakin bagaimana tepatnya saya akan memberi hadiah. Seorang rekan kerja menemukan masalahnya, dan saya mencari tahu MENGAPA itu terjadi bagaimana itu terjadi. Saya lebih dari bersedia untuk memberikan saran tentang cara memberikan hadiah.
VxJasonxV
kamu masih ada? Saya punya beberapa pertanyaan untuk Anda.
VxJasonxV
Saya punya masalah ini juga. Buecking yang terhormat, apakah Anda menyelesaikannya?
Untuk orang lain yang memiliki masalah ini - baca semua jawaban pada pertanyaan ini, karena ada 2-3 pengaturan O / S yang perlu diperbaiki. Kami memecahkan masalah ini dengan mengubah rp_filterdan /proc/sys/net/ipv4/icmp_echo_ignore_broadcastsdan kemudian mulai bekerja.
Sam Goldberg

Jawaban:

35

Dalam contoh kami, masalah kami diselesaikan oleh parameter sysctl, satu berbeda dari Maciej.

Harap dicatat bahwa saya tidak berbicara untuk OP (buecking), saya datang pada posting ini karena masalah yang terkait dengan detail dasar (tidak ada lalu lintas multicast di userland).

Kami memiliki aplikasi yang membaca data yang dikirim ke empat alamat multicast, dan port unik per alamat multicast, dari alat yang (biasanya) terhubung langsung ke antarmuka di server penerima.

Kami berusaha untuk menyebarkan perangkat lunak ini di situs pelanggan ketika secara misterius gagal tanpa alasan yang diketahui. Upaya debugging perangkat lunak ini menghasilkan memeriksa setiap panggilan sistem, akhirnya mereka semua memberi tahu kami hal yang sama:

Perangkat lunak kami meminta data, dan OS tidak pernah menyediakannya.

Penghitung paket multicast bertambah, tcpdump menunjukkan lalu lintas yang mencapai kotak / antarmuka tertentu, namun kami tidak dapat melakukan apa-apa dengannya. SELinux dinonaktifkan, iptables sedang berjalan tetapi tidak memiliki aturan di salah satu tabel.

Bingung, kami.

Secara acak, kami mulai berpikir tentang parameter kernel yang ditangani sysctl, tetapi tidak ada fitur yang terdokumentasi yang secara khusus relevan, atau jika ada hubungannya dengan lalu lintas multicast, mereka diaktifkan. Oh, dan ifconfig memang mencantumkan "MULTICAST" di baris fitur (naik, siaran, lari, multicast). Karena penasaran kami melihat /etc/sysctl.conf. Lihatlah, gambar dasar pelanggan ini memiliki beberapa garis tambahan yang ditambahkan di bagian bawah.

Dalam kasus kami, pelanggan telah menetapkan net.ipv4.all.rp_filter = 1. rp_filter adalah filter Rute Jalan, yang (seperti yang saya mengerti) menolak semua lalu lintas yang tidak mungkin mencapai kotak ini. Subnet jaringan melompat, anggapan bahwa sumber IP sedang dipalsukan.

Nah, server ini menggunakan subnet 192.168.1 / 24 dan alamat IP sumber alat untuk lalu lintas multicast berada di suatu tempat di jaringan 10. *. Dengan demikian, filter itu mencegah server melakukan sesuatu yang berarti dengan lalu lintas.

Beberapa tweak disetujui oleh pelanggan; net.ipv4.eth0.rp_filter = 1dan net.ipv4.eth1.rp_filter = 0dan kami berlari dengan gembira.

VxJasonxV
sumber
2
Ini berhasil! The rp_filteruntuk antarmuka jaringan Gb kami 10 sedang membuang semua paket multicast UDP kami. Mematikan filter membiarkan semuanya mengalir.
chrisaycock
Kami mengalami masalah saat mengatur streaming melalui AMT multicast melalui perangkat tun pada penerima Ubuntu, dan kami bisa melihat paket dikirimkan ke perangkat melalui tcpdump, tetapi aplikasi tidak ingin melakukan streaming. Posting ini menyelamatkan kami!
insinyur perangkat lunak
2
Berjalan di Ubuntu 14.04, ini hanya berfungsi untuk saya setelah saya juga mengatur net.ipv4.all.rp_filter = 0. Secara khusus, dengan data multicast tiba di eth2, saya harus mengatur keduanya net.ipv4.eth2.rp_filter = 0dan net.ipv4.all.rp_filter = 0.
T-Hawk
4

TL / DR Juga pastikan multicast Anda tidak berasal dari vlan. tcpdump -eakan membantu menentukan apakah mereka melakukannya.

Dalam semua kewajaran, seseorang harus membangun sebuah halaman dengan daftar hal-hal yang dapat mencegah multicast mencapai tanah pengguna. Saya telah berjuang dengan itu selama beberapa hari, dan tentu saja tidak ada yang dapat saya temukan di web.

Tidak hanya saya bisa melihat paket di dalamnya tcpdump, saya sebenarnya bisa menerima paket multicast lainnya, untuk produsen lain, hanya pada antarmuka yang berbeda. Perintah yang akhirnya saya gunakan untuk menguji apakah saya dapat menerima multicast adalah:

$ 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

Alasan untuk di stracesini adalah bahwa saya sebenarnya tidak bisa socatmencetak paket ke stdout, tetapi dalam straceoutput Anda dapat dengan jelas melihat apakah socatmenerima data aktual dari soket terikat (itu akan bisu jika tidak setelah beberapa selectpanggilan awal )

  • rp_filtersysctl - tidak berlaku, sistem berada pada jaringan IP yang sama (saya mengaturnya untuk 0semua yang sama, tampaknya itu 1adalah pengaturan default sekarang, setidaknya untuk Ubuntu).
  • firewall / etc - sistem penerima bebas firewall (saya rasa paket tidak akan muncul di tcpdump jika firewall, tapi saya kira itu mungkin jika firewall lucu)
  • Routing IP / Multicast dan beberapa antarmuka - Saya secara eksplisit bergabung dengan grup pada antarmuka yang benar
  • Perangkat keras jaringan yang aneh - ini adalah pilihan terakhir saya, tetapi mengubah beberapa laptop menjadi Intel NUC tidak membantu. Ini adalah tentang di mana saya mulai mengunyah siku saya dan melakukan posting ini ke SE.
  • Masalah dalam kasus saya adalah penggunaan VLAN oleh perangkat keras khusus yang memproduksi paket multicast tersebut. Untuk melihat apakah ini masalah Anda, pastikan untuk menyertakan -eflag tcpdump, dan periksa tag vlan. Ini akan diperlukan untuk mengkonfigurasi antarmuka ke vlan yang benar sebelum userland bisa mendapatkan paket-paket itu. Hadiah untuk saya sebenarnya adalah bahwa produsen multicast tidak akan melakukan ping, tetapi bahkan tidak akan masuk ke cache ARP, meskipun saya bisa melihat dengan jelas balasan ARP.

Untuk menjalankannya dengan VLAN tautan ini mungkin berguna untuk mengkonfigurasi perutean multicast. (Sayangnya saya baru dalam hal ini sehingga Reputasi tidak memperbolehkan saya untuk menambahkan jawaban. Karenanya edit ini.)

Inilah yang saya lakukan (gunakan sudo jika diperlukan):

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

Dengan cara ini antarmuka tambahan jika dibuat untuk lalu lintas vlan dengan vlan id 100. Vlan ip mungkin tidak perlu. Kemudian alamat multicast dikonfigurasi untuk antarmuka baru (01: 00: 5e: 01: 01: 01 adalah alamat lapisan tautan untuk 239.1.1.1) dan semua lalu lintas multicast yang masuk terikat dengan eth0_100. Saya juga melakukan semua langkah yang mungkin dalam jawaban di atas (periksa iptables, rp_filter dll).

Pawel Veselov
sumber
@ Global: Menambahkan rute multicast mengatur multicast keluar , bukan multicast masuk. Anda tidak boleh mengikat alamat IP multicast ke antarmuka secara langsung, kecuali jika Anda melakukan sesuatu yang funky, itu biasanya pekerjaan aplikasi.
Pawel Veselov
2

Anda mungkin ingin mencoba dan melihat pengaturan ini:

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

Ini telah digunakan untuk mengaktifkan multicasting di RHEL.

Anda mungkin ingin memastikan bahwa firewall Anda mengizinkan lalu lintas mutlicast; lagi dengan RHEL Saya telah mengaktifkan yang berikut:

# 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
pengguna64259
sumber
Opsi "broadcast" juga berlaku untuk "multicast"?
Raedwald
0

Apakah Anda menggunakan sakelar yang dikelola? Beberapa memiliki opsi untuk mencegah 'badai siaran' atau masalah multicast lainnya, yang akan menyebabkan mereka mencegah jenis paket tertentu. Saya sarankan melihat dokumentasi switch Anda.

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

Yakin tentang ""? Mengapa tidak menggunakan alamat IP multicast untuk diikat?

poige
sumber
alamat host kosong biasanya berarti "semua antarmuka".
VxJasonxV