ΠšΡ€Π°Ρ‚ΠΊΠΎ въвСдСниС Π² BPF ΠΈ eBPF

Π₯Π΅ΠΉ Π₯Π°Π±Ρ€! Π˜Π½Ρ„ΠΎΡ€ΠΌΠΈΡ€Π°ΠΌΠ΅ Π²ΠΈ, Ρ‡Π΅ подготвямС ΠΈΠ·Π΄Π°Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° ΠΊΠ½ΠΈΠ³Π° "ΠΠ°Π±Π»ΡŽΠ΄Π°Π΅ΠΌΠΎΡΡ‚ Π½Π° Linux с BPF".

ΠšΡ€Π°Ρ‚ΠΊΠΎ въвСдСниС Π² BPF ΠΈ eBPF
Въй ΠΊΠ°Ρ‚ΠΎ Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»Π½Π°Ρ‚Π° машина BPF ΠΏΡ€ΠΎΠ΄ΡŠΠ»ΠΆΠ°Π²Π° Π΄Π° сС Ρ€Π°Π·Π²ΠΈΠ²Π° ΠΈ сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎ Π½Π° ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ°, Π½ΠΈΠ΅ ΠΏΡ€Π΅Π²Π΅Π΄ΠΎΡ…ΠΌΠ΅ статия Π·Π° вас, описваща Π½Π΅ΠΉΠ½ΠΈΡ‚Π΅ основни характСристики ΠΈ Ρ‚Π΅ΠΊΡƒΡ‰ΠΎ ΡΡŠΡΡ‚ΠΎΡΠ½ΠΈΠ΅.

ΠŸΡ€Π΅Π· послСднитС Π³ΠΎΠ΄ΠΈΠ½ΠΈ инструмСнтитС ΠΈ Ρ‚Π΅Ρ…Π½ΠΈΠΊΠΈΡ‚Π΅ Π·Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ€Π°Π½Π΅ ΠΏΡ€ΠΈΠ΄ΠΎΠ±ΠΈΡ…Π° популярност, Π·Π° Π΄Π° компСнсират ограничСнията Π½Π° ядрото Π½Π° Linux Π² случаитС, ΠΊΠΎΠ³Π°Ρ‚ΠΎ сС изисква ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ с висока производитСлност. Π•Π΄ΠΈΠ½ ΠΎΡ‚ Π½Π°ΠΉ-популярнитС ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈ ΠΎΡ‚ Ρ‚ΠΎΠ·ΠΈ Π²ΠΈΠ΄ Π΅ Ρ‚.Π½Π°Ρ€ байпас Π½Π° ядрото (байпас Π½Π° ядрото) ΠΈ позволява, прСскачайки мрСТовия слой Π½Π° ядрото, Π΄Π° ΠΈΠ·Π²ΡŠΡ€ΡˆΠ²Π° цялата ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ ΠΎΡ‚ потрСбитСлското пространство. ЗаобикалянСто Π½Π° ядрото ΡΡŠΡ‰ΠΎ Π²ΠΊΠ»ΡŽΡ‡Π²Π° ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Π½Π° ΠΌΡ€Π΅ΠΆΠΎΠ²Π°Ρ‚Π° ΠΊΠ°Ρ€Ρ‚Π° ΠΎΡ‚ потрСбитСлско пространство. Π‘ Π΄Ρ€ΡƒΠ³ΠΈ Π΄ΡƒΠΌΠΈ, ΠΊΠΎΠ³Π°Ρ‚ΠΎ Ρ€Π°Π±ΠΎΡ‚ΠΈΠΌ с ΠΌΡ€Π΅ΠΆΠΎΠ²Π° ΠΊΠ°Ρ€Ρ‚Π°, Π½ΠΈΠ΅ Ρ€Π°Π·Ρ‡ΠΈΡ‚Π°ΠΌΠ΅ Π½Π° Π΄Ρ€Π°ΠΉΠ²Π΅Ρ€Π° потрСбитСлско пространство.

Π§Ρ€Π΅Π· ΠΏΡ€Π΅Ρ…Π²ΡŠΡ€Π»ΡΠ½Π΅ Π½Π° пълния ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ» Π½Π° ΠΌΡ€Π΅ΠΆΠΎΠ²Π°Ρ‚Π° ΠΊΠ°Ρ€Ρ‚Π° към ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° Π·Π° потрСбитСлско пространство, Π½ΠΈΠ΅ намалявамС Ρ€Π΅ΠΆΠΈΠΉΠ½ΠΈΡ‚Π΅ Ρ€Π°Π·Ρ…ΠΎΠ΄ΠΈ, ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π΅Π½ΠΈ ΠΎΡ‚ ядрото (ΠΏΡ€Π΅Π²ΠΊΠ»ΡŽΡ‡Π²Π°Π½Π΅ Π½Π° контСкста, ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π½Π° мрСТовия слой, ΠΏΡ€Π΅ΠΊΡŠΡΠ²Π°Π½ΠΈΡ ΠΈ Ρ‚.Π½.), ΠΊΠΎΠ΅Ρ‚ΠΎ Π΅ ΠΌΠ½ΠΎΠ³ΠΎ Π²Π°ΠΆΠ½ΠΎ ΠΏΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π° със скорости ΠΎΡ‚ 10Gb/s ΠΈΠ»ΠΈ ΠΏΠΎ-висок. ЗаобикалянС Π½Π° ядрото плюс комбинация ΠΎΡ‚ Π΄Ρ€ΡƒΠ³ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ (ΠΏΠ°ΠΊΠ΅Ρ‚Π½Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ°) ΠΈ Π²Π½ΠΈΠΌΠ°Ρ‚Π΅Π»Π½Π° настройка Π½Π° производитСлността (NUMA счСтоводство, Π˜Π·ΠΎΠ»Π°Ρ†ΠΈΡ Π½Π° процСсора, ΠΈ Ρ‚.Π½.) отговарят Π½Π° основитС Π½Π° високопроизводитСлната ΠΌΡ€Π΅ΠΆΠ° Π² потрСбитСлското пространство. МоТС Π±ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅Π½ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π·Π° Ρ‚ΠΎΠ·ΠΈ Π½ΠΎΠ² ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ към ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ°Ρ‚Π° Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ Π΅ DPDK ΠΎΡ‚ Intel (ΠšΠΎΠΌΠΏΠ»Π΅ΠΊΡ‚ Π·Π° Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π½Π° Data Plane), Π²ΡŠΠΏΡ€Π΅ΠΊΠΈ Ρ‡Π΅ ΠΈΠΌΠ° Π΄Ρ€ΡƒΠ³ΠΈ Π΄ΠΎΠ±Ρ€Π΅ извСстни инструмСнти ΠΈ Ρ‚Π΅Ρ…Π½ΠΈΠΊΠΈ, Π²ΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅Π»Π½ΠΎ VPP ΠΎΡ‚ Cisco (Vector Packet Processing), Netmap ΠΈ, Ρ€Π°Π·Π±ΠΈΡ€Π° сС, Ρ…Π°ΠΏΠ°ΠΌ.

ΠžΡ€Π³Π°Π½ΠΈΠ·Π°Ρ†ΠΈΡΡ‚Π° Π½Π° ΠΌΡ€Π΅ΠΆΠΎΠ²ΠΈΡ‚Π΅ взаимодСйствия Π² потрСбитСлското пространство ΠΈΠΌΠ° Ρ€Π΅Π΄ΠΈΡ†Π° Π½Π΅Π΄ΠΎΡΡ‚Π°Ρ‚ΡŠΡ†ΠΈ:

  • Π―Π΄Ρ€ΠΎΡ‚ΠΎ Π½Π° ОБ Π΅ абстракционСн слой Π·Π° Ρ…Π°Ρ€Π΄ΡƒΠ΅Ρ€Π½ΠΈ рСсурси. Въй ΠΊΠ°Ρ‚ΠΎ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ Π·Π° потрСбитСлско пространство трябва Π΄Π° управляват своитС рСсурси Π΄ΠΈΡ€Π΅ΠΊΡ‚Π½ΠΎ, Ρ‚Π΅ ΡΡŠΡ‰ΠΎ трябва Π΄Π° управляват собствСния си Ρ…Π°Ρ€Π΄ΡƒΠ΅Ρ€. Π’ΠΎΠ²Π° чСсто ΠΎΠ·Π½Π°Ρ‡Π°Π²Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ€Π°Π½Π΅ Π½Π° Π²Π°ΡˆΠΈΡ‚Π΅ собствСни Π΄Ρ€Π°ΠΉΠ²Π΅Ρ€ΠΈ.
  • Въй ΠΊΠ°Ρ‚ΠΎ напълно сС ΠΎΡ‚ΠΊΠ°Π·Π²Π°ΠΌΠ΅ ΠΎΡ‚ пространството Π½Π° ядрото, Π½ΠΈΠ΅ сС ΠΎΡ‚ΠΊΠ°Π·Π²Π°ΠΌΠ΅ ΠΈ ΠΎΡ‚ цялата ΠΌΡ€Π΅ΠΆΠΎΠ²Π° функционалност, прСдоставСна ΠΎΡ‚ ядрото. ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ Π·Π° потрСбитСлско пространство трябва Π΄Π° внСдрят ΠΎΡ‚Π½ΠΎΠ²ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΊΠΎΠΈΡ‚ΠΎ ΠΌΠΎΠΆΠ΅ Π²Π΅Ρ‡Π΅ Π΄Π° са прСдоставСни ΠΎΡ‚ ядрото ΠΈΠ»ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Π°Ρ‚Π° систСма.
  • ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ работят Π² Ρ€Π΅ΠΆΠΈΠΌ sandbox, ΠΊΠΎΠ΅Ρ‚ΠΎ сСриозно ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π°Π²Π° тяхното взаимодСйствиС ΠΈ ΠΈΠΌ ΠΏΡ€Π΅Ρ‡ΠΈ Π΄Π° сС ΠΈΠ½Ρ‚Π΅Π³Ρ€ΠΈΡ€Π°Ρ‚ с Π΄Ρ€ΡƒΠ³ΠΈ части Π½Π° ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Π°Ρ‚Π° систСма.

По ΡΡŠΡ‰Π΅ΡΡ‚Π²ΠΎ, ΠΊΠΎΠ³Π°Ρ‚ΠΎ Ρ€Π°Π±ΠΎΡ‚ΠΈΡ‚Π΅ Π² ΠΌΡ€Π΅ΠΆΠ° Π² потрСбитСлско пространство, подобрСнията Π² производитСлността сС постигат Ρ‡Ρ€Π΅Π· прСмСстванС Π½Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ°Ρ‚Π° Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ ΠΎΡ‚ ядрото към потрСбитСлското пространство. XDP ΠΏΡ€Π°Π²ΠΈ Ρ‚ΠΎΡ‡Π½ΠΎ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΡ‚ΠΎ: прСмСства ΠΌΡ€Π΅ΠΆΠΎΠ²ΠΈΡ‚Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ ΠΎΡ‚ потрСбитСлското пространство (Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈ, ΠΊΠΎΠ½Π²Π΅Ρ€Ρ‚ΠΎΡ€ΠΈ, ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ΠΈΠ·ΠΈΡ€Π°Π½Π΅ ΠΈ Ρ‚.Π½.) Π² областта Π½Π° ядрото. XDP Π½ΠΈ позволява Π΄Π° изпълним ΠΌΡ€Π΅ΠΆΠΎΠ²Π°Ρ‚Π° функция Π²Π΅Π΄Π½Π°Π³Π° Ρ‰ΠΎΠΌ ΠΏΠ°ΠΊΠ΅Ρ‚ΡŠΡ‚ достигнС мрСТовия интСрфСйс ΠΈ ΠΏΡ€Π΅Π΄ΠΈ Π΄Π° Π·Π°ΠΏΠΎΡ‡Π½Π΅ Π΄Π° ΠΏΡŠΡ‚ΡƒΠ²Π° Π΄ΠΎ ΠΌΡ€Π΅ΠΆΠΎΠ²Π°Ρ‚Π° подсистСма Π½Π° ядрото. Π’ Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚ Π½Π° Ρ‚ΠΎΠ²Π° скоростта Π½Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈΡ‚Π΅ сС ΡƒΠ²Π΅Π»ΠΈΡ‡Π°Π²Π° Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»Π½ΠΎ. Как ΠΎΠ±Π°Ρ‡Π΅ ядрото позволява Π½Π° потрСбитСля Π΄Π° изпълнява своитС ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ Π² пространството Π½Π° ядрото? ΠŸΡ€Π΅Π΄ΠΈ Π΄Π° ΠΎΡ‚Π³ΠΎΠ²ΠΎΡ€ΠΈΠΌ Π½Π° Ρ‚ΠΎΠ·ΠΈ Π²ΡŠΠΏΡ€ΠΎΡ, Π½Π΅ΠΊΠ° Π΄Π° Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ ΠΊΠ°ΠΊΠ²ΠΎ Π΅ BPF.

BPF ΠΈ eBPF

Π’ΡŠΠΏΡ€Π΅ΠΊΠΈ Π½Π΅ съвсСм ясното ΠΈΠΌΠ΅, BPF (Packet Filtering, Berkeley) Π²ΡΡŠΡ‰Π½ΠΎΡΡ‚ Π΅ ΠΌΠΎΠ΄Π΅Π» Π½Π° Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»Π½Π° машина. Π’Π°Π·ΠΈ Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»Π½Π° машина ΠΏΡŠΡ€Π²ΠΎΠ½Π°Ρ‡Π°Π»Π½ΠΎ Π΅ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΈΡ€Π°Π½Π° Π΄Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π²Π° Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈΡ€Π°Π½Π΅ Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ, ΠΎΡ‚ΠΊΡŠΠ΄Π΅Ρ‚ΠΎ ΠΈΠ΄Π²Π° ΠΈ ΠΈΠΌΠ΅Ρ‚ΠΎ.

Π•Π΄ΠΈΠ½ ΠΎΡ‚ Π½Π°ΠΉ-извСстнитС инструмСнти, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‰ΠΈ BPF, Π΅ tcpdump. ΠŸΡ€ΠΈ ΠΏΡ€ΠΈΡ…Π²Π°Ρ‰Π°Π½Π΅ Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ с tcpdump потрСбитСлят ΠΌΠΎΠΆΠ΅ Π΄Π° посочи ΠΈΠ·Ρ€Π°Π· Π·Π° Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈΡ€Π°Π½Π΅ Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ. Π©Π΅ Π±ΡŠΠ΄Π°Ρ‚ ΡƒΠ»ΠΎΠ²Π΅Π½ΠΈ само ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ, ΠΊΠΎΠΈΡ‚ΠΎ отговарят Π½Π° Ρ‚ΠΎΠ·ΠΈ ΠΈΠ·Ρ€Π°Π·. НапримСр ΠΈΠ·Ρ€Π°Π·ΡŠΡ‚ "tcp dst port 80” сС отнася Π·Π° всички TCP ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ, пристигащи Π½Π° ΠΏΠΎΡ€Ρ‚ 80. ΠšΠΎΠΌΠΏΠΈΠ»Π°Ρ‚ΠΎΡ€ΡŠΡ‚ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΡŠΠΊΡ€Π°Ρ‚ΠΈ Ρ‚ΠΎΠ·ΠΈ ΠΈΠ·Ρ€Π°Π·, ΠΊΠ°Ρ‚ΠΎ Π³ΠΎ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ²Π° Π² BPF Π±Π°ΠΉΡ‚ ΠΊΠΎΠ΄.

$ sudo tcpdump -d "tcp dst port 80"
(000) ldh [12] (001) jeq #0x86dd jt 2 jf 6
(002) ldb [20] (003) jeq #0x6 jt 4 jf 15
(004) ldh [56] (005) jeq #0x50 jt 14 jf 15
(006) jeq #0x800 jt 7 jf 15
(007) ldb [23] (008) jeq #0x6 jt 9 jf 15
(009) ldh [20] (010) jset #0x1fff jt 15 jf 11
(011) ldxb 4*([14]&0xf)
(012) ldh [x + 16] (013) jeq #0x50 jt 14 jf 15
(014) ret #262144
(015) ret #0

По ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏ Ρ‚ΠΎΠ²Π° ΠΏΡ€Π°Π²ΠΈ Π³ΠΎΡ€Π½Π°Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°:

  • Π˜Π½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡ (000): Π—Π°Ρ€Π΅ΠΆΠ΄Π° ΠΏΠ°ΠΊΠ΅Ρ‚Π° ΠΏΡ€ΠΈ отмСстванС 12, ΠΊΠ°Ρ‚ΠΎ 16-Π±ΠΈΡ‚ΠΎΠ²Π° Π΄ΡƒΠΌΠ°, Π² Π°ΠΊΡƒΠΌΡƒΠ»Π°Ρ‚ΠΎΡ€Π°. ΠžΡ‚ΠΌΠ΅ΡΡ‚Π²Π°Π½Π΅ 12 ΡΡŠΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²Π° Π½Π° ethertype Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚Π°.
  • Π˜Π½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡ (001): сравнява стойността Π² Π°ΠΊΡƒΠΌΡƒΠ»Π°Ρ‚ΠΎΡ€Π° с 0x86dd, Ρ‚.Π΅. със стойността Π½Π° ethertype Π·Π° IPv6. Ако Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚ΡŠΡ‚ Π΅ Π²Π΅Ρ€Π΅Π½, Ρ‚ΠΎΠ³Π°Π²Π° програмният брояч ΠΎΡ‚ΠΈΠ²Π° към инструкция (002), Π° Π°ΠΊΠΎ Π½Π΅, Ρ‚ΠΎΠ³Π°Π²Π° към (006).
  • Π˜Π½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡ (006): сравнява стойността с 0x800 (стойност Π½Π° ethertype Π·Π° IPv4). Ако ΠΎΡ‚Π³ΠΎΠ²ΠΎΡ€ΡŠΡ‚ Π΅ Π²Π΅Ρ€Π΅Π½, Ρ‚ΠΎΠ³Π°Π²Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° ΠΎΡ‚ΠΈΠ²Π° Π½Π° (007), Π°ΠΊΠΎ Π½Π΅, Ρ‚ΠΎΠ³Π°Π²Π° Π½Π° (015).

И Ρ‚Π°ΠΊΠ° Π½Π°Ρ‚Π°Ρ‚ΡŠΠΊ, Π΄ΠΎΠΊΠ°Ρ‚ΠΎ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° Π·Π° Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈΡ€Π°Π½Π΅ Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ Π²ΡŠΡ€Π½Π΅ Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚. ОбикновСно Π΅ Π±ΡƒΠ»Π΅Π²ΠΎ. Π’Ρ€ΡŠΡ‰Π°Π½Π΅Ρ‚ΠΎ Π½Π° Π½Π΅Π½ΡƒΠ»Π΅Π²Π° стойност (инструкция (014)) ΠΎΠ·Π½Π°Ρ‡Π°Π²Π°, Ρ‡Π΅ ΠΏΠ°ΠΊΠ΅Ρ‚ΡŠΡ‚ Π΅ съвпаднал, Π° Π²Ρ€ΡŠΡ‰Π°Π½Π΅Ρ‚ΠΎ Π½Π° Π½ΡƒΠ»Π° (инструкция (015)) ΠΎΠ·Π½Π°Ρ‡Π°Π²Π°, Ρ‡Π΅ ΠΏΠ°ΠΊΠ΅Ρ‚ΡŠΡ‚ Π½Π΅ Π΅ съвпаднал.

Π’ΠΈΡ€Ρ‚ΡƒΠ°Π»Π½Π°Ρ‚Π° машина BPF ΠΈ нСйният Π±Π°ΠΉΡ‚ ΠΊΠΎΠ΄ бяха ΠΏΡ€Π΅Π΄Π»ΠΎΠΆΠ΅Π½ΠΈ ΠΎΡ‚ Π‘Ρ‚ΠΈΠ² Маккан ΠΈ Π’Π°Π½ Π”ΠΆΠ΅ΠΉΠΊΡŠΠ±ΡΡŠΠ½ Π² края Π½Π° 1992 Π³., ΠΊΠΎΠ³Π°Ρ‚ΠΎ ΠΈΠ·Π»Π΅Π·Π΅ тяхната статия. BSD ΠΏΠ°ΠΊΠ΅Ρ‚Π΅Π½ Ρ„ΠΈΠ»Ρ‚ΡŠΡ€: Нова Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π° Π·Π° улавянС Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ Π½Π° Π½ΠΈΠ²ΠΎ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π», Π·Π° ΠΏΡŠΡ€Π²ΠΈ ΠΏΡŠΡ‚ Ρ‚Π°Π·ΠΈ тСхнология бСшС прСдставСна Π½Π° конфСрСнцията Π½Π° Usenix ΠΏΡ€Π΅Π· Π·ΠΈΠΌΠ°Ρ‚Π° Π½Π° 1993 Π³.

Въй ΠΊΠ°Ρ‚ΠΎ BPF Π΅ Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»Π½Π° машина, Ρ‚ΠΎΠΉ опрСдСля срСдата, Π² която сС ΠΈΠ·ΠΏΡŠΠ»Π½ΡΠ²Π°Ρ‚ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅. Π’ допълнСниС към Π±Π°ΠΉΡ‚ ΠΊΠΎΠ΄Π°, Ρ‚ΠΎΠΉ ΡΡŠΡ‰ΠΎ Ρ‚Π°ΠΊΠ° Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ€Π° ΠΌΠΎΠ΄Π΅Π» Π½Π° ΠΏΠ°ΠΌΠ΅Ρ‚ Π·Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ (инструкциитС Π·Π° Π·Π°Ρ€Π΅ΠΆΠ΄Π°Π½Π΅ сС ΠΏΡ€ΠΈΠ»Π°Π³Π°Ρ‚ ΠΈΠΌΠΏΠ»ΠΈΡ†ΠΈΡ‚Π½ΠΎ към ΠΏΠ°ΠΊΠ΅Ρ‚), рСгистри (A ΠΈ X; Π°ΠΊΡƒΠΌΡƒΠ»Π°Ρ‚ΠΎΡ€Π½ΠΈ ΠΈ индСксни рСгистри), ΠΏΠ°ΠΌΠ΅Ρ‚ Π·Π° ΠΏΠ°ΠΌΠ΅Ρ‚ ΠΈ скрит ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ΅Π½ брояч. Π˜Π½Ρ‚Π΅Ρ€Π΅ΡΠ½ΠΎΡ‚ΠΎ Π΅, Ρ‡Π΅ Π±Π°ΠΉΡ‚ ΠΊΠΎΠ΄ΡŠΡ‚ Π½Π° BPF Π΅ ΠΌΠΎΠ΄Π΅Π»ΠΈΡ€Π°Π½ слСд Motorola 6502 ISA. ΠšΠ°ΠΊΡ‚ΠΎ Π‘Ρ‚ΠΈΠ² Маккан си спомня Π² своя ΠΏΠ»Π΅Π½Π°Ρ€Π΅Π½ Π΄ΠΎΠΊΠ»Π°Π΄ Π½Π° Sharkfest '11 Ρ‚ΠΎΠΉ бСшС Π·Π°ΠΏΠΎΠ·Π½Π°Ρ‚ с компилация 6502 ΠΎΡ‚ гимназията, ΠΊΠΎΠ³Π°Ρ‚ΠΎ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ€Π°ΡˆΠ΅ Π½Π° Apple II, ΠΈ Ρ‚ΠΎΠ²Π° Π·Π½Π°Π½ΠΈΠ΅ повлия Π½Π° Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚Π° ΠΌΡƒ ΠΏΠΎ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΈΡ€Π°Π½Π΅ Π½Π° Π±Π°ΠΉΡ‚ ΠΊΠΎΠ΄Π° Π½Π° BPF.

ΠŸΠΎΠ΄Π΄Ρ€ΡŠΠΆΠΊΠ°Ρ‚Π° Π½Π° BPF Π΅ Π²Π½Π΅Π΄Ρ€Π΅Π½Π° Π² ядрото Π½Π° Linux във вСрсия v2.5 ΠΈ ΠΏΠΎ-Π½ΠΎΠ²Π°, Π΄ΠΎΠ±Π°Π²Π΅Π½Π° Π³Π»Π°Π²Π½ΠΎ ΠΎΡ‚ Jay Schullist. BPF ΠΊΠΎΠ΄ΡŠΡ‚ остана Π½Π΅ΠΏΡ€ΠΎΠΌΠ΅Π½Π΅Π½ Π΄ΠΎ 2011 Π³., ΠΊΠΎΠ³Π°Ρ‚ΠΎ Π•Ρ€ΠΈΠΊ Π”ΡŽΠΌΠ°ΡΠ΅Ρ‚ ΠΏΡ€Π΅Ρ€Π°Π±ΠΎΡ‚ΠΈ BPF ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚Π°Ρ‚ΠΎΡ€Π°, Π·Π° Π΄Π° Ρ€Π°Π±ΠΎΡ‚ΠΈ Π² JIT Ρ€Π΅ΠΆΠΈΠΌ (Π˜Π·Ρ‚ΠΎΡ‡Π½ΠΈΠΊ: JIT Π·Π° ΠΏΠ°ΠΊΠ΅Ρ‚Π½ΠΈ Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈ). Π‘Π»Π΅Π΄ Ρ‚ΠΎΠ²Π°, вмСсто Π΄Π° ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚ΠΈΡ€Π° Π±Π°ΠΉΡ‚ ΠΊΠΎΠ΄Π° Π½Π° BPF, ядрото ΠΌΠΎΠΆΠ΅ Π΄ΠΈΡ€Π΅ΠΊΡ‚Π½ΠΎ Π΄Π° ΠΊΠΎΠ½Π²Π΅Ρ€Ρ‚ΠΈΡ€Π° BPF ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ Π² Ρ†Π΅Π»Π΅Π²Π°Ρ‚Π° Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°: x86, ARM, MIPS ΠΈ Ρ‚.Π½.

По-късно, ΠΏΡ€Π΅Π· 2014 Π³., АлСксСй Π‘Ρ‚Π°Ρ€ΠΎΠ²ΠΎΠΉΡ‚ΠΎΠ² ΠΏΡ€Π΅Π΄Π»ΠΎΠΆΠΈ Π½ΠΎΠ² JIT ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΡŠΠΌ Π·Π° BPF. Π’ΡΡŠΡ‰Π½ΠΎΡΡ‚ Ρ‚ΠΎΠ·ΠΈ Π½ΠΎΠ² JIT сС ΠΏΡ€Π΅Π²ΡŠΡ€Π½Π° Π² Π½ΠΎΠ²Π° Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°, Π±Π°Π·ΠΈΡ€Π°Π½Π° Π½Π° BPF ΠΈ бСшС Π½Π°Ρ€Π΅Ρ‡Π΅Π½Π° eBPF. Мисля, Ρ‡Π΅ ΠΈ Π΄Π²Π΅Ρ‚Π΅ Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»Π½ΠΈ машини ΡΡŠΡ‰Π΅ΡΡ‚Π²ΡƒΠ²Π°Ρ‚ ΡΡŠΠ²ΠΌΠ΅ΡΡ‚Π½ΠΎ извСстно Π²Ρ€Π΅ΠΌΠ΅, Π½ΠΎ Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈΡ€Π°Π½Π΅Ρ‚ΠΎ Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ Π² ΠΌΠΎΠΌΠ΅Π½Ρ‚Π° Π΅ Π²Π½Π΅Π΄Ρ€Π΅Π½ΠΎ Π²ΡŠΡ€Ρ…Ρƒ eBPF. Π’ΡΡŠΡ‰Π½ΠΎΡΡ‚ Π² ΠΌΠ½ΠΎΠ³ΠΎ ΡΡŠΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΈ Π·Π° докумСнтация BPF сС Π½Π°Ρ€ΠΈΡ‡Π° eBPF, Π° класичСският BPF Π΅ извСстСн днСс ΠΊΠ°Ρ‚ΠΎ cBPF.

eBPF Ρ€Π°Π·ΡˆΠΈΡ€ΡΠ²Π° класичСската BPF Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»Π½Π° машина ΠΏΠΎ няколко Π½Π°Ρ‡ΠΈΠ½Π°:

  • Π Π°Π·Ρ‡ΠΈΡ‚Π° Π½Π° ΠΌΠΎΠ΄Π΅Ρ€Π½ΠΈ 64-Π±ΠΈΡ‚ΠΎΠ²ΠΈ Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€ΠΈ. eBPF ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° 64-Π±ΠΈΡ‚ΠΎΠ²ΠΈ рСгистри ΠΈ ΡƒΠ²Π΅Π»ΠΈΡ‡Π°Π²Π° броя Π½Π° Π½Π°Π»ΠΈΡ‡Π½ΠΈΡ‚Π΅ рСгистри ΠΎΡ‚ 2 (Π°ΠΊΡƒΠΌΡƒΠ»Π°Ρ‚ΠΎΡ€ ΠΈ X) Π½Π° 10. eBPF прСдоставя ΠΈ Π΄ΠΎΠΏΡŠΠ»Π½ΠΈΡ‚Π΅Π»Π½ΠΈ ΠΊΠΎΠ΄ΠΎΠ²Π΅ Π·Π° ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ (BPF_MOV, BPF_JNE, BPF_CALL…).
  • ΠžΡ‚Π΄Π΅Π»Π΅Π½ ΠΎΡ‚ подсистСмата Π½Π° мрСТовия слой. BPF бСшС ΡΠ²ΡŠΡ€Π·Π°Π½ с ΠΌΠΎΠ΄Π΅Π»Π° Π½Π° ΠΏΠ°Ρ€Ρ‚ΠΈΠ΄Π½ΠΈΡ‚Π΅ Π΄Π°Π½Π½ΠΈ. Въй ΠΊΠ°Ρ‚ΠΎ бСшС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½ Π·Π° Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈΡ€Π°Π½Π΅ Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ, нСговият ΠΊΠΎΠ΄ бСшС Π² подсистСмата, която ΠΎΡΠΈΠ³ΡƒΡ€ΡΠ²Π°ΡˆΠ΅ ΠΌΡ€Π΅ΠΆΠΎΠ²ΠΈ взаимодСйствия. Π’ΠΈΡ€Ρ‚ΡƒΠ°Π»Π½Π°Ρ‚Π° машина eBPF ΠΎΠ±Π°Ρ‡Π΅ Π²Π΅Ρ‡Π΅ Π½Π΅ Π΅ ΠΎΠ±Π²ΡŠΡ€Π·Π°Π½Π° с ΠΌΠΎΠ΄Π΅Π» Π½Π° Π΄Π°Π½Π½ΠΈ ΠΈ ΠΌΠΎΠΆΠ΅ Π΄Π° сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π·Π° всякакви Ρ†Π΅Π»ΠΈ. И Ρ‚Π°ΠΊΠ°, сСга ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° eBPF ΠΌΠΎΠΆΠ΅ Π΄Π° бъдС ΡΠ²ΡŠΡ€Π·Π°Π½Π° към tracepoint ΠΈΠ»ΠΈ kprobe. Π’ΠΎΠ²Π° отваря Π²Ρ€Π°Ρ‚Π°Ρ‚Π° към eBPF инструмСнти, Π°Π½Π°Π»ΠΈΠ· Π½Π° производитСлността ΠΈ ΠΌΠ½ΠΎΠ³ΠΎ Π΄Ρ€ΡƒΠ³ΠΈ случаи Π½Π° ΡƒΠΏΠΎΡ‚Ρ€Π΅Π±Π° Π² контСкста Π½Π° Π΄Ρ€ΡƒΠ³ΠΈ подсистСми Π½Π° ядрото. Π‘Π΅Π³Π° ΠΊΠΎΠ΄ΡŠΡ‚ Π½Π° eBPF сС Π½Π°ΠΌΠΈΡ€Π° Π² собствСн ΠΏΡŠΡ‚: kernel/bpf.
  • Π“Π»ΠΎΠ±Π°Π»Π½ΠΈ Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π° Π·Π° Π΄Π°Π½Π½ΠΈ, Π½Π°Ρ€Π΅Ρ‡Π΅Π½ΠΈ ΠšΠ°Ρ€Ρ‚ΠΈ. ΠšΠ°Ρ€Ρ‚ΠΈΡ‚Π΅ са Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π° Π½Π° ΠΊΠ»ΡŽΡ‡-стойност, ΠΊΠΎΠΈΡ‚ΠΎ осигуряват ΠΎΠ±ΠΌΠ΅Π½ Π½Π° Π΄Π°Π½Π½ΠΈ ΠΌΠ΅ΠΆΠ΄Ρƒ потрСбитСлското пространство ΠΈ пространството Π½Π° ядрото. eBPF прСдоставя няколко Π²ΠΈΠ΄Π° ΠΊΠ°Ρ€Ρ‚ΠΈ.
  • Π’Ρ‚ΠΎΡ€ΠΈΡ‡Π½ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ. По-спСциално, Π·Π° прСзаписванС Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚, изчисляванС Π½Π° ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π½Π° сума ΠΈΠ»ΠΈ ΠΊΠ»ΠΎΠ½ΠΈΡ€Π°Π½Π΅ Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚. Π’Π΅Π·ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ сС ΠΈΠ·ΠΏΡŠΠ»Π½ΡΠ²Π°Ρ‚ Π²ΡŠΡ‚Ρ€Π΅ Π² ядрото ΠΈ Π½Π΅ ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠ°Ρ‚ към ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ Π² потрСбитСлското пространство. Π’ допълнСниС, систСмни повиквания ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° сС правят ΠΎΡ‚ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ Π½Π° eBPF.
  • ΠšΡ€Π°ΠΉ Π½Π° Ρ€Π°Π·Π³ΠΎΠ²ΠΎΡ€ΠΈΡ‚Π΅. Π Π°Π·ΠΌΠ΅Ρ€ΡŠΡ‚ Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° Π² eBPF Π΅ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ Π΄ΠΎ 4096 Π±Π°ΠΉΡ‚Π°. Ѐункцията Π·Π° ΠΊΡ€Π°ΠΉ Π½Π° ΠΏΠΎΠ²ΠΈΠΊΠ²Π°Π½Π΅ позволява Π½Π° eBPF ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° Π΄Π° ΠΏΡ€Π΅Ρ…Π²ΡŠΡ€Π»ΠΈ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅Ρ‚ΠΎ Π½Π° Π½ΠΎΠ²Π° eBPF ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° ΠΈ ΠΏΠΎ Ρ‚ΠΎΠ·ΠΈ Π½Π°Ρ‡ΠΈΠ½ Π΄Π° Π·Π°ΠΎΠ±ΠΈΠΊΠΎΠ»ΠΈ Ρ‚ΠΎΠ²Π° ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅ (Π΄ΠΎ 32 ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° Π±ΡŠΠ΄Π°Ρ‚ ΡΠ²ΡŠΡ€Π·Π°Π½ΠΈ ΠΏΠΎ Ρ‚ΠΎΠ·ΠΈ Π½Π°Ρ‡ΠΈΠ½).

ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π·Π° eBPF

Има няколко ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° Π·Π° eBPF Π² ΠΈΠ·Ρ…ΠΎΠ΄Π½ΠΈΡ‚Π΅ ΠΊΠΎΠ΄ΠΎΠ²Π΅ Π½Π° ядрото Π½Π° Linux. Налични са Π½Π° samples/bpf/. Π—Π° Π΄Π° ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€Π°Ρ‚Π΅ Ρ‚Π΅Π·ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΈ, просто Π½Π°ΠΏΠΈΡˆΠ΅Ρ‚Π΅:

$ sudo make samples/bpf/

Няма Π΄Π° пиша сам Π½ΠΎΠ² ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π·Π° eBPF, Π° Ρ‰Π΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌ Π΅Π΄ΠΈΠ½ ΠΎΡ‚ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΈΡ‚Π΅, Π½Π°Π»ΠΈΡ‡Π½ΠΈ Π² samples/bpf/. Π©Π΅ Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌ някои части ΠΎΡ‚ ΠΊΠΎΠ΄Π° ΠΈ Ρ‰Π΅ обясня ΠΊΠ°ΠΊ Ρ€Π°Π±ΠΎΡ‚ΠΈ. ΠšΠ°Ρ‚ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΈΠ·Π±Ρ€Π°Ρ… ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° tracex4.

ΠšΠ°Ρ‚ΠΎ цяло всСки ΠΎΡ‚ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΈΡ‚Π΅ Π² samples/bpf/ сС ΡΡŠΡΡ‚ΠΎΠΈ ΠΎΡ‚ Π΄Π²Π° Ρ„Π°ΠΉΠ»Π°. Π’ Ρ‚Π°ΠΊΡŠΠ² случай:

  • tracex4_kern.c, ΡΡŠΠ΄ΡŠΡ€ΠΆΠ° изходния ΠΊΠΎΠ΄, ΠΊΠΎΠΉΡ‚ΠΎ Π΄Π° бъдС изпълнСн Π² ядрото ΠΊΠ°Ρ‚ΠΎ eBPF Π±Π°ΠΉΡ‚ΠΊΠΎΠ΄.
  • tracex4_user.c, ΡΡŠΠ΄ΡŠΡ€ΠΆΠ° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° ΠΎΡ‚ потрСбитСлското пространство.

Π’ Ρ‚ΠΎΠ·ΠΈ случай трябва Π΄Π° ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€Π°ΠΌΠ΅ tracex4_kern.c към eBPF Π±Π°ΠΉΡ‚ ΠΊΠΎΠ΄. Π’ ΠΌΠΎΠΌΠ΅Π½Ρ‚Π° Π² gcc няма ΡΡŠΡ€Π²ΡŠΡ€Π½Π° част Π·Π° eBPF. Π·Π° щастиС clang ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΏΡ€ΠΎΠΈΠ·Π²Π΅Π΄Π΅ eBPF Π±Π°ΠΉΡ‚ ΠΊΠΎΠ΄. Makefile ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° clang Π΄Π° ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€Π°ΠΌΠ΅ tracex4_kern.c към обСктния Ρ„Π°ΠΉΠ».

По-Π³ΠΎΡ€Π΅ спомСнах, Ρ‡Π΅ Π΅Π΄Π½Π° ΠΎΡ‚ Π½Π°ΠΉ-интСрСснитС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π½Π° eBPF са ΠΊΠ°Ρ€Ρ‚ΠΈΡ‚Π΅. tracex4_kern Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ€Π° Π΅Π΄Π½Π° ΠΊΠ°Ρ€Ρ‚Π°:

struct pair {
    u64 val;
    u64 ip;
};  

struct bpf_map_def SEC("maps") my_map = {
    .type = BPF_MAP_TYPE_HASH,
    .key_size = sizeof(long),
    .value_size = sizeof(struct pair),
    .max_entries = 1000000,
};

BPF_MAP_TYPE_HASH Π΅ Π΅Π΄ΠΈΠ½ ΠΎΡ‚ ΠΌΠ½ΠΎΠ³ΠΎΡ‚ΠΎ Π²ΠΈΠ΄ΠΎΠ²Π΅ ΠΊΠ°Ρ€Ρ‚ΠΈ, ΠΏΡ€Π΅Π΄Π»Π°Π³Π°Π½ΠΈ ΠΎΡ‚ eBPF. Π’ Ρ‚ΠΎΠ·ΠΈ случай Ρ‚ΠΎΠ²Π° Π΅ просто Ρ…Π΅Ρˆ. МоТС ΡΡŠΡ‰ΠΎ Π΄Π° стС забСлязали Ρ€Π΅ΠΊΠ»Π°ΠΌΠ°Ρ‚Π° SEC("maps"). SEC Π΅ макрос, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½ Π·Π° създаванС Π½Π° Π½ΠΎΠ²Π° сСкция Π½Π° Π΄Π²ΠΎΠΈΡ‡Π΅Π½ Ρ„Π°ΠΉΠ». Π’ΡΡŠΡ‰Π½ΠΎΡΡ‚ Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° tracex4_kern Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ€Π°Π½ΠΈ са ΠΎΡ‰Π΅ Π΄Π²Π° Ρ€Π°Π·Π΄Π΅Π»Π°:

SEC("kprobe/kmem_cache_free")
int bpf_prog1(struct pt_regs *ctx)
{   
    long ptr = PT_REGS_PARM2(ctx);

    bpf_map_delete_elem(&my_map, &ptr); 
    return 0;
}
    
SEC("kretprobe/kmem_cache_alloc_node") 
int bpf_prog2(struct pt_regs *ctx)
{
    long ptr = PT_REGS_RC(ctx);
    long ip = 0;

    // ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ ip-адрСс Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰Π΅ΠΉ стороны kmem_cache_alloc_node() 
    BPF_KRETPROBE_READ_RET_IP(ip, ctx);

    struct pair v = {
        .val = bpf_ktime_get_ns(),
        .ip = ip,
    };
    
    bpf_map_update_elem(&my_map, &ptr, &v, BPF_ANY);
    return 0;
}   

Π’Π΅Π·ΠΈ Π΄Π²Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π²ΠΈ позволяват Π΄Π° ΠΏΡ€Π΅ΠΌΠ°Ρ…Π½Π΅Ρ‚Π΅ запис ΠΎΡ‚ ΠΊΠ°Ρ€Ρ‚Π°Ρ‚Π° (kprobe/kmem_cache_free) ΠΈ Π΄ΠΎΠ±Π°Π²Π΅Ρ‚Π΅ Π½ΠΎΠ² запис към ΠΊΠ°Ρ€Ρ‚Π°Ρ‚Π° (kretprobe/kmem_cache_alloc_node). Всички ΠΈΠΌΠ΅Π½Π° Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, написани с Π³Π»Π°Π²Π½ΠΈ Π±ΡƒΠΊΠ²ΠΈ, ΡΡŠΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²Π°Ρ‚ Π½Π° макроси, Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ€Π°Π½ΠΈ Π² bpf_helpers.h.

Ако ΠΈΠ·Ρ…Π²ΡŠΡ€Π»Ρ сСкциитС Π½Π° обСктния Ρ„Π°ΠΉΠ», трябва Π΄Π° видя, Ρ‡Π΅ Ρ‚Π΅Π·ΠΈ Π½ΠΎΠ²ΠΈ сСкции Π²Π΅Ρ‡Π΅ са Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ€Π°Π½ΠΈ:

$ objdump -h tracex4_kern.o

tracex4_kern.o: file format elf64-little

Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000000 0000000000000000 0000000000000000 00000040 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 kprobe/kmem_cache_free 00000048 0000000000000000 0000000000000000 00000040 2**3
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
2 kretprobe/kmem_cache_alloc_node 000000c0 0000000000000000 0000000000000000 00000088 2**3
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
3 maps 0000001c 0000000000000000 0000000000000000 00000148 2**2
CONTENTS, ALLOC, LOAD, DATA
4 license 00000004 0000000000000000 0000000000000000 00000164 2**0
CONTENTS, ALLOC, LOAD, DATA
5 version 00000004 0000000000000000 0000000000000000 00000168 2**2
CONTENTS, ALLOC, LOAD, DATA
6 .eh_frame 00000050 0000000000000000 0000000000000000 00000170 2**3
CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA

ВсС ΠΎΡ‰Π΅ ΠΈΠΌΠ°ΠΌ tracex4_user.c, основна ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°. По ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏ Ρ‚Π°Π·ΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° ΡΠ»ΡƒΡˆΠ° Π·Π° ΡΡŠΠ±ΠΈΡ‚ΠΈΡ kmem_cache_alloc_node. ΠšΠΎΠ³Π°Ρ‚ΠΎ възникнС Ρ‚Π°ΠΊΠΎΠ²Π° ΡΡŠΠ±ΠΈΡ‚ΠΈΠ΅, сС изпълнява ΡΡŠΠΎΡ‚Π²Π΅Ρ‚Π½ΠΈΡΡ‚ eBPF ΠΊΠΎΠ΄. ΠšΠΎΠ΄ΡŠΡ‚ записва IP Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π° Π½Π° ΠΎΠ±Π΅ΠΊΡ‚Π° Π² ΠΊΠ°Ρ€Ρ‚Π° ΠΈ слСд Ρ‚ΠΎΠ²Π° ΠΎΠ±Π΅ΠΊΡ‚ΡŠΡ‚ сС ΠΏΡ€Π΅ΠΊΠ°Ρ€Π²Π° ΠΏΡ€Π΅Π· Π³Π»Π°Π²Π½Π°Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°. ΠŸΡ€ΠΈΠΌΠ΅Ρ€:

$ sudo ./tracex4
obj 0xffff8d6430f60a00 is 2sec old was allocated at ip ffffffff9891ad90
obj 0xffff8d6062ca5e00 is 23sec old was allocated at ip ffffffff98090e8f
obj 0xffff8d5f80161780 is 6sec old was allocated at ip ffffffff98090e8f

Как са ΡΠ²ΡŠΡ€Π·Π°Π½ΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° Π·Π° потрСбитСлско пространство ΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° eBPF? ΠŸΡ€ΠΈ инициализация tracex4_user.c Π·Π°Ρ€Π΅ΠΆΠ΄Π° ΠΎΠ±Π΅ΠΊΡ‚Π΅Π½ Ρ„Π°ΠΉΠ» tracex4_kern.o ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π½Π° функцията load_bpf_file.

int main(int ac, char **argv)
{
    struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
    char filename[256];
    int i;

    snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);

    if (setrlimit(RLIMIT_MEMLOCK, &r)) {
        perror("setrlimit(RLIMIT_MEMLOCK, RLIM_INFINITY)");
        return 1;
    }

    if (load_bpf_file(filename)) {
        printf("%s", bpf_log_buf);
        return 1;
    }

    for (i = 0; ; i++) {
        print_old_objects(map_fd[1]);
        sleep(1);
    }

    return 0;
}

Π”ΠΎΠΊΠ°Ρ‚ΠΎ ΠΏΡ€Π°Π²ΠΈΡ‚Π΅ load_bpf_file сС добавят сонди, Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ€Π°Π½ΠΈ Π² eBPF Ρ„Π°ΠΉΠ»Π° /sys/kernel/debug/tracing/kprobe_events. Π‘Π΅Π³Π° Π½ΠΈΠ΅ ΡΠ»ΡƒΡˆΠ°ΠΌΠ΅ Π·Π° Ρ‚Π΅Π·ΠΈ ΡΡŠΠ±ΠΈΡ‚ΠΈΡ ΠΈ Π½Π°ΡˆΠ°Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° ΠΌΠΎΠΆΠ΅ Π΄Π° Π½Π°ΠΏΡ€Π°Π²ΠΈ Π½Π΅Ρ‰ΠΎ, ΠΊΠΎΠ³Π°Ρ‚ΠΎ сС случат.

$ sudo cat /sys/kernel/debug/tracing/kprobe_events
p:kprobes/kmem_cache_free kmem_cache_free
r:kprobes/kmem_cache_alloc_node kmem_cache_alloc_node

Всички Π΄Ρ€ΡƒΠ³ΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ Π² sample/bpf/ са структурирани ΠΏΠΎ ΠΏΠΎΠ΄ΠΎΠ±Π΅Π½ Π½Π°Ρ‡ΠΈΠ½. Π’Π΅ Π²ΠΈΠ½Π°Π³ΠΈ ΡΡŠΠ΄ΡŠΡ€ΠΆΠ°Ρ‚ Π΄Π²Π° Ρ„Π°ΠΉΠ»Π°:

  • XXX_kern.c: ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° eBPF.
  • XXX_user.c: основна ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°.

ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° eBPF Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ€Π° ΠΊΠ°Ρ€Ρ‚ΠΈΡ‚Π΅ ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈΡ‚Π΅, ΡΠ²ΡŠΡ€Π·Π°Π½ΠΈ с Π΄Π°Π΄Π΅Π½Π° сСкция. ΠšΠΎΠ³Π°Ρ‚ΠΎ ядрото ΠΈΠ·Π»ΡŠΡ‡Π²Π° ΡΡŠΠ±ΠΈΡ‚ΠΈΠ΅ ΠΎΡ‚ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ Ρ‚ΠΈΠΏ (Π½Π°ΠΏΡ€. tracepoint), ΠΎΠ±Π²ΡŠΡ€Π·Π°Π½ΠΈΡ‚Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ сС ΠΈΠ·ΠΏΡŠΠ»Π½ΡΠ²Π°Ρ‚. ΠšΠ°Ρ€Ρ‚ΠΈΡ‚Π΅ осигуряват комуникация ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° Π½Π° ядрото ΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° Π·Π° потрСбитСлско пространство.

Π—Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅

Π’ Ρ‚Π°Π·ΠΈ статия BPF ΠΈ eBPF бяха обсъдСни Π² ΠΎΠ±Ρ‰ΠΈ Π»ΠΈΠ½ΠΈΠΈ. Π—Π½Π°ΠΌ, Ρ‡Π΅ днСс ΠΈΠΌΠ° ΠΌΠ½ΠΎΠ³ΠΎ информация ΠΈ рСсурси Π·Π° eBPF, Ρ‚Π°ΠΊΠ° Ρ‡Π΅ Ρ‰Π΅ ΠΏΡ€Π΅ΠΏΠΎΡ€ΡŠΡ‡Π°ΠΌ ΠΎΡ‰Π΅ няколко ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»Π° Π·Π° ΠΏΠΎ-Π½Π°Ρ‚Π°Ρ‚ΡŠΡˆΠ½ΠΎ ΠΏΡ€ΠΎΡƒΡ‡Π²Π°Π½Π΅.

ΠŸΡ€Π΅ΠΏΠΎΡ€ΡŠΡ‡Π²Π°ΠΌ Π΄Π° ΠΏΡ€ΠΎΡ‡Π΅Ρ‚Π΅Ρ‚Π΅:

Π˜Π·Ρ‚ΠΎΡ‡Π½ΠΈΠΊ: www.habr.com

ДобавянС Π½Π° Π½ΠΎΠ² ΠΊΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€