Rumah >Tutorial sistem >LINUX >Menggunakan Netlink untuk komunikasi antara ruang pengguna dan ruang kernel
Pada tahun 2001, jawatankuasa IETF ForCES secara rasmi menjalankan kerja penyeragaman pada Netlink. Jamal Hadi Salim mencadangkan mentakrifkan Netlink sebagai protokol untuk komunikasi antara komponen enjin penghalaan peranti rangkaian dan komponen kawalan dan pengurusannya. Walau bagaimanapun, cadangan beliau tidak diterima pakai pada akhirnya, dan telah digantikan dengan corak yang kita lihat hari ini: Netlink telah direka sebagai domain protokol baharu, domain.
Tobas, bapa Linux, pernah berkata "Linux ialah evolusi, bukan reka bentuk pintar". Apa maksudnya? Dalam erti kata lain, Netlink juga mengikut konsep reka bentuk tertentu Linux, iaitu, tiada dokumen spesifikasi lengkap atau dokumen reka bentuk. Cuma apa? Anda tahu---"Baca kod sumber f**king".
Sudah tentu, artikel ini bukan untuk menganalisis mekanisme pelaksanaan Netlink di Linux, tetapi untuk berkongsi dengan anda topik "Apa itu Netlink" dan "Bagaimana untuk menggunakan Netlink dengan baik Anda hanya perlu membaca sumber kernel". kod apabila anda menghadapi masalah.
Apa itu NetlinkUntuk memahami Netlink, anda perlu memahami beberapa perkara penting:
1. Subsistem pemesejan tanpa sambungan untuk datagram
2. Dilaksanakan berdasarkan seni bina Soket BSD biasa
Mengenai perkara pertama, mudah untuk kita memikirkan protokol UDP. Ia bagus untuk memikirkan perkara ini. Tidak munasabah untuk memahami Netlink berdasarkan protokol UDP Selagi anda boleh membuat persamaan dan belajar dengan analogi, pandai meringkaskan, mengaitkan, dan akhirnya merealisasikan pemindahan pengetahuan, ini adalah intipati pembelajaran. Netlink boleh merealisasikan komunikasi data dua arah dan tak segerak antara kernel->pengguna dan pengguna->kernel Ia juga menyokong komunikasi data antara dua proses pengguna dan juga antara dua subsistem kernel. Dalam artikel ini, kami tidak akan mempertimbangkan dua yang terakhir, dan menumpukan pada cara melaksanakan komunikasi data antara pengguna <->
Apabila anda melihat titik kedua, adakah gambar berikut terlintas di fikiran anda? Jika ya, bermakna anda mempunyai akar kebijaksanaan, sudah tentu, jika tidak, tidak mengapa, akar kebijaksanaan boleh tumbuh perlahan-lahan, haha.
Kami terutamanya akan menggunakan socket(), bind(), sendmsg() apabila mempraktikkan pengaturcaraan soket Netlink nanti
Panggilan sistem sepertidan recvmsg(), dan sudah tentu mekanisme pengundian yang disediakan oleh soket.
Jenis komunikasi NetlinkNetlink menyokong dua jenis kaedah komunikasi: unicast dan multicast.
Unicast: Selalunya digunakan untuk komunikasi data 1:1 antara proses pengguna dan subsistem kernel. Ruang pengguna menghantar arahan ke kernel, dan kemudian menerima hasil arahan daripada kernel.
Multicast: Selalunya digunakan untuk komunikasi data 1:N antara proses kernel dan berbilang proses pengguna. Kernel bertindak sebagai pemula sesi, dan aplikasi ruang pengguna adalah penerima. Untuk melaksanakan fungsi ini, program ruang kernel akan mencipta kumpulan multicast, dan kemudian semua proses ruang pengguna yang berminat dengan mesej yang dihantar oleh proses kernel akan menyertai kumpulan untuk menerima mesej yang dihantar daripada kernel. Seperti berikut:
Komunikasi antara proses A dan subsistem 1 adalah unicast, dan komunikasi antara proses B dan C dan subsistem 2 adalah multicast. Gambar di atas juga memberitahu kita mesej. Data yang dipindahkan dari ruang pengguna ke kernel tidak perlu beratur, iaitu, operasi diselesaikan secara serentak manakala data yang dipindahkan dari ruang kernel ke ruang pengguna perlu beratur, iaitu tidak segerak; Memahami perkara ini boleh menjimatkan banyak lencongan semasa membangunkan modul aplikasi berdasarkan Netlink. Jika anda menghantar mesej kepada kernel dan perlu mendapatkan maklumat tertentu dalam kernel, seperti jadual penghalaan atau maklumat lain, jika jadual penghalaan terlalu besar, maka apabila kernel mengembalikan data kepada anda melalui Netlink, anda boleh memikirkan tentang bagaimana untuk menerimanya Masalah data, lagipun, anda telah melihat baris gilir keluaran, anda tidak boleh menutup mata.
Format mesej NetlinkMesej Netlink terdiri daripada dua bahagian: pengepala mesej dan muatan, dan keseluruhan mesej Netlink adalah sejajar 4-bait dan umumnya dihantar dalam susunan bait hos. Pengepala mesej ditetapkan pada 16 bait dan panjang badan mesej berubah-ubah:
Pengepala mesej NetlinkPengepala mesej ditakrifkan dalam fail
Klik (di sini) untuk runtuh atau buka
Penjelasan dan penerangan tentang sifat-sifat setiap ahli dalam pengepala mesej:
nlmsg_len: Panjang keseluruhan mesej, dalam bait. Termasuk pengepala mesej Netlink itu sendiri.
nlmsg_type: Jenis mesej, iaitu, sama ada data atau mesej kawalan. Pada masa ini (kernel versi 2.6.21) Netlink hanya menyokong empat jenis mesej kawalan, seperti berikut:
NLMSG_NOOP - mesej kosong, jangan buat apa-apa
NLMSG_ERROR - Menunjukkan bahawa mesej mengandungi ralat
NLMSG_DONE - Jika kernel mengembalikan berbilang mesej melalui baris gilir Netlink, mesej terakhir dalam baris gilir adalah jenis NLMSG_DONE, dan atribut nlmsg_flags bagi semua mesej yang tinggal mempunyai bit NLM_F_MULTI yang ditetapkan untuk sah.
NLMSG_OVERRUN-Belum digunakan lagi.
nlmsg_flags: Maklumat deskriptif tambahan dilampirkan pada mesej, seperti NLM_F_MULTI yang dinyatakan di atas. Petikan adalah seperti berikut:
Selagi anda tahu bahawa nlmsg_flags mempunyai berbilang nilai, bagi peranan dan makna setiap nilai, anda pasti boleh mencari jawapannya melalui Google dan kod sumber, jadi saya tidak akan menerangkan butiran di sini. Semua nilai dalam kernel 2.6.21 sebelumnya:
nlmsg_seq: nombor urutan mesej. Oleh kerana Netlink berorientasikan kepada datagram, terdapat risiko kehilangan data, tetapi Netlink menyediakan mekanisme untuk memastikan mesej tidak hilang, membolehkan pembangun program melaksanakannya mengikut keperluan sebenar mereka. Nombor jujukan mesej biasanya digunakan bersama dengan mesej jenis NLM_F_ACK Jika aplikasi pengguna perlu memastikan bahawa setiap mesej yang dihantar berjaya diterima oleh kernel, maka ia memerlukan program pengguna untuk menetapkan nombor jujukan itu sendiri semasa menghantar mesej, dan kernel menerima mesej Kemudian ekstrak nombor siri, dan kemudian tetapkan nombor siri yang sama dalam mesej respons yang dihantar kepada program pengguna. Agak serupa dengan mekanisme respons dan pengesahan TCP.
Nota: Apabila kernel secara aktif menghantar mesej siaran ke ruang pengguna, medan dalam mesej ini sentiasa 0.
nlmsg_pid: Apabila saluran pertukaran data diwujudkan melalui Netlink antara proses ruang pengguna dan subsistem tertentu dalam ruang kernel, Netlink akan menetapkan pengenalan digital unik kepada setiap saluran tersebut. Fungsi utamanya adalah untuk mengaitkan mesej permintaan dan mesej respons dari ruang pengguna. Secara terang-terangan, jika terdapat berbilang proses pengguna dalam ruang pengguna dan berbilang proses dalam ruang kernel, Netlink mesti menyediakan mekanisme untuk memastikan interaksi data antara setiap pasangan proses komunikasi ruang "kernel pengguna" boleh berlaku.
Iaitu, apabila proses A dan B memperoleh maklumat daripada subsistem 1 melalui Netlink, subsistem 1 mesti memastikan bahawa data respons yang dihantar semula ke proses A tidak akan dihantar ke proses B. Ia terutamanya sesuai untuk senario di mana proses ruang pengguna mendapatkan data daripada ruang kernel. Biasanya, apabila proses ruang pengguna menghantar mesej ke kernel, ia biasanya memberikan ID proses proses semasa kepada pembolehubah ini melalui panggilan sistem getpid(). dapatkan respons daripada kernel. Medan ini ditetapkan kepada 0 untuk mesej yang dihantar secara aktif dari kernel ke ruang pengguna.
Isi mesej NetlinkIsi mesej Netlink menggunakan format TLV (Type-Length-Value):
Setiap atribut Netlink diwakili oleh struct nlattr{} dalam fail
Mesej petunjuk ralat disediakan oleh Netlink
Kandungan Apabila ralat berlaku semasa komunikasi antara aplikasi ruang pengguna dan proses ruang kernel melalui Netlink, Netlink mesti memberitahu ruang pengguna tentang ralat tersebut. Netlink merangkum mesej ralat secara berasingan,Klik (di sini) untuk runtuh atau buka
1. Habis daya ingatan
2. Limpahan penimbal dalam proses penerimaan ruang pengguna. Sebab utama limpahan penimbal mungkin: proses ruang pengguna berjalan terlalu perlahan atau baris gilir terima terlalu pendek.
Jika Netlink tidak dapat menghantar mesej dengan betul kepada proses penerimaan dalam ruang pengguna, maka proses penerimaan dalam ruang pengguna akan mengembalikan ralat kehabisan memori (ENOBUFS) apabila memanggil panggilan sistem recvmsg() Ini perlu diberi perhatian. Dalam erti kata lain, situasi limpahan penimbal tidak akan dihantar dalam panggilan sistem sendmsg() daripada pengguna->kernel Sebabnya telah dinyatakan sebelum ini.
Sudah tentu, jika komunikasi soket menyekat digunakan, tiada bahaya yang tersembunyi dari keletihan ingatan Mengapa ini? Pergi ke Google dengan cepat dan cari apa itu soket penyekat. Jika anda belajar tanpa berfikir, anda akan menjadi sia-sia; jika anda berfikir tanpa belajar, anda akan berada dalam bahaya.
Struktur alamat NetlinkDalam catatan blog TCP, kami menyebut struktur alamat dan struktur alamat standard yang digunakan dalam proses pengaturcaraan Internet Hubungan mereka dengan struktur alamat Netlink adalah seperti berikut:
Takrifan dan penerangan terperinci bagi struct sockaddr_nl{} adalah seperti berikut:
Klik (di sini) untuk runtuh atau buka
nl_pid: Atribut ini ialah ID proses menghantar atau menerima mesej Seperti yang kami katakan sebelum ini, Netlink bukan sahaja dapat merealisasikan komunikasi ruang kernel pengguna, tetapi juga membolehkan komunikasi masa nyata antara dua proses dalam ruang pengguna, atau antara dua proses dalam. ruang kernel. Apabila atribut ini ialah 0, ia biasanya digunakan pada dua situasi berikut:
Pertama, destinasi yang ingin kami hantar ialah kernel, iaitu, apabila menghantar dari ruang pengguna ke ruang kernel, nl_pid dalam struktur alamat Netlink yang kami bina biasanya ditetapkan kepada 0. Satu perkara yang perlu saya jelaskan kepada anda di sini ialah dalam spesifikasi Netlink, nama penuh PID ialah Port-ID (32bits), dan fungsi utamanya ialah untuk mengenal pasti saluran soket berasaskan netlink secara unik. Biasanya nl_pid ditetapkan kepada ID proses proses semasa. Walau bagaimanapun, untuk kes di mana beberapa utas proses menggunakan soket netlink pada masa yang sama, tetapan nl_pid biasanya dilaksanakan seperti berikut:
Klik (di sini) untuk runtuh atau buka
nl_groups: Jika proses ruang pengguna ingin menyertai kumpulan multicast, ia mesti melaksanakan panggilan sistem bind(). Medan ini menentukan
mask nombor kumpulan multicast yang pemanggil ingin sertai (perhatikan bahawa ia bukan nombor kumpulan, kami akan menerangkan medan ini secara terperinci kemudian). Jika medan ini ialah 0, ini bermakna pemanggil tidak mahu menyertai mana-mana kumpulan multicast. Untuk setiap protokol kepunyaan domain protokol Netlink, sehingga 32 kumpulan multicast boleh disokong (kerana panjang nl_groups ialah 32 bit), dan setiap kumpulan multicast diwakili oleh satu bit.
Mengenai baki pengetahuan Netlink, kami akan membincangkannya apabila ia berguna dalam sesi praktikal kemudian.Belum habis, bersambung...
Atas ialah kandungan terperinci Menggunakan Netlink untuk komunikasi antara ruang pengguna dan ruang kernel. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!