ΠΠ° ΠΏΠΎΡΠ΅ΡΠΎΠΊΠΎΡ ΠΈΠΌΠ°ΡΠ΅ ΡΠ΅Ρ Π½ΠΎΠ»ΠΎΠ³ΠΈΡΠ° ΠΈ ΡΠ΅ Π²ΠΈΠΊΠ°ΡΠ΅ BPF. ΠΠ° ΠΏΠΎΠ³Π»Π΅Π΄Π½Π°Π²ΠΌΠ΅ , Π‘ΡΠ°Ρ Π·Π°Π²Π΅Ρ, ΡΡΠ°ΡΠΈΡΠ° Π²ΠΎ ΠΎΠ²Π°Π° ΡΠ΅ΡΠΈΡΠ°. ΠΠΎ 2013 Π³ΠΎΠ΄ΠΈΠ½Π°, ΠΏΡΠ΅ΠΊΡ Π½Π°ΠΏΠΎΡΠΈΡΠ΅ Π½Π° ΠΠ»Π΅ΠΊΡΠ΅Ρ Π‘ΡΠ°ΡΠΎΠ²ΠΎΠΈΡΠΎΠ² ΠΈ ΠΠ°Π½ΠΈΠ΅Π» ΠΠΎΡΠΊΠΌΠ°Π½, Π±Π΅ΡΠ΅ ΡΠ°Π·Π²ΠΈΠ΅Π½Π° ΠΈ Π²ΠΊΠ»ΡΡΠ΅Π½Π° Π²ΠΎ ΡΠ°Π΄ΡΠΎΡΠΎ Linux ΠΠΎΠ΄ΠΎΠ±ΡΠ΅Π½Π° Π²Π΅ΡΠ·ΠΈΡΠ° ΠΎΠΏΡΠΈΠΌΠΈΠ·ΠΈΡΠ°Π½Π° Π·Π° ΠΌΠΎΠ΄Π΅ΡΠ½ΠΈ 64-Π±ΠΈΡΠ½ΠΈ ΠΌΠ°ΡΠΈΠ½ΠΈ. ΠΠ²Π°Π° Π½ΠΎΠ²Π° ΡΠ΅Ρ Π½ΠΎΠ»ΠΎΠ³ΠΈΡΠ° ΠΊΡΠ°ΡΠΊΠΎ ΡΠ΅ Π½Π°ΡΠ΅ΠΊΡΠ²Π°ΡΠ΅ ΠΠ½Π°ΡΡΠ΅ΡΠ΅Π½ BPF, ΠΏΠΎΡΠΎΠ° ΠΏΡΠ΅ΠΈΠΌΠ΅Π½ΡΠ²Π°Π½Π° Π²ΠΎ ΠΡΠΎΡΠΈΡΠ΅Π½ BPF, Π° ΡΠ΅Π³Π°, Π½Π΅ΠΊΠΎΠ»ΠΊΡ Π³ΠΎΠ΄ΠΈΠ½ΠΈ ΠΏΠΎΠ΄ΠΎΡΠ½Π°, ΡΠΈΡΠ΅ Π΅Π΄Π½ΠΎΡΡΠ°Π²Π½ΠΎ ΡΠ° Π½Π°ΡΠ΅ΠΊΡΠ²Π°Π°Ρ BPF.
ΠΠΎ ΠΎΡΠ½ΠΎΠ²Π°, BPF Π΄ΠΎΠ·Π²ΠΎΠ»ΡΠ²Π° ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ»Π΅Π½ ΠΊΠΎΠ΄ ΠΎΠ±Π΅Π·Π±Π΅Π΄Π΅Π½ ΠΎΠ΄ ΠΊΠΎΡΠΈΡΠ½ΠΈΠΊΠΎΡ Π΄Π° ΡΠ΅ ΠΈΠ·Π²ΡΡΡΠ²Π° Π²ΠΎ ΠΏΡΠΎΡΡΠΎΡΠΎΡ Π½Π° ΡΠ°Π΄ΡΠΎΡΠΎ. Linux Π Π½ΠΎΠ²Π°ΡΠ° Π°ΡΡ ΠΈΡΠ΅ΠΊΡΡΡΠ° ΡΠ΅ ΠΏΠΎΠΊΠ°ΠΆΠ° ΠΊΠ°ΠΊΠΎ ΡΠΎΠ»ΠΊΡ ΡΡΠΏΠ΅ΡΠ½Π° ΡΡΠΎ Π½ΠΈ ΡΡΠ΅Π±Π°Π° ΡΡΡΠ΅ Π΄Π΅ΡΠ΅ΡΠΈΠ½Π° ΡΡΠ°ΡΠΈΠΈ Π·Π° Π΄Π° Π³ΠΈ ΠΎΠΏΠΈΡΠ΅ΠΌΠ΅ ΡΠΈΡΠ΅ Π½Π΅ΡΠ·ΠΈΠ½ΠΈ Π°ΠΏΠ»ΠΈΠΊΠ°ΡΠΈΠΈ. (ΠΠ΄ΠΈΠ½ΡΡΠ²Π΅Π½ΠΎΡΠΎ Π½Π΅ΡΡΠΎ ΡΡΠΎ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ΅ΡΠΈΡΠ΅ Π½Π΅ ΡΡΠΏΠ΅Π°ΡΠ° Π΄Π° Π³ΠΎ Π½Π°ΠΏΡΠ°Π²Π°Ρ, ΠΊΠ°ΠΊΠΎ ΡΡΠΎ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° Π²ΠΈΠ΄ΠΈΡΠ΅ Π½Π° ΡΠ°Π±Π΅Π»Π°ΡΠ° Π·Π° Π΅ΡΠΈΠΊΠ°ΡΠ½ΠΎΡΡ ΠΏΠΎΠ΄ΠΎΠ»Ρ, Π±Π΅ΡΠ΅ Π΄Π° ΡΠΎΠ·Π΄Π°Π΄Π°Ρ ΠΏΡΠΈΡΡΠΎΡΠ½ΠΎ Π»ΠΎΠ³ΠΎ.)
ΠΠ²Π°Π° ΡΡΠ°ΡΠΈΡΠ° ΡΠ° ΠΎΠΏΠΈΡΡΠ²Π° ΡΡΡΡΠΊΡΡΡΠ°ΡΠ° Π½Π° Π²ΠΈΡΡΡΠ΅Π»Π½Π°ΡΠ° ΠΌΠ°ΡΠΈΠ½Π° BPF, ΠΈΠ½ΡΠ΅ΡΡΠ΅ΡΡΠΈΡΠ΅ Π½Π° ΡΠ°Π΄ΡΠΎΡΠΎ Π·Π° ΡΠ°Π±ΠΎΡΠ° ΡΠΎ BPF, ΡΠ°Π·Π²ΠΎΡΠ½ΠΈΡΠ΅ Π°Π»Π°ΡΠΊΠΈ, ΠΊΠ°ΠΊΠΎ ΠΈ ΠΊΡΠ°ΡΠΎΠΊ, ΠΌΠ½ΠΎΠ³Ρ ΠΊΡΠ°ΡΠΎΠΊ ΠΏΡΠ΅Π³Π»Π΅Π΄ Π½Π° ΠΏΠΎΡΡΠΎΠ΅ΡΠΊΠΈΡΠ΅ ΡΠΏΠΎΡΠΎΠ±Π½ΠΎΡΡΠΈ, Ρ.Π΅. ΡΠ΅ ΡΡΠΎ ΡΠ΅ Π½ΠΈ ΡΡΠ΅Π±Π° Π²ΠΎ ΠΈΠ΄Π½ΠΈΠ½Π° Π·Π° ΠΏΠΎΠ΄Π»Π°Π±ΠΎΠΊΠΎ ΠΏΡΠΎΡΡΡΠ²Π°ΡΠ΅ Π½Π° ΠΏΡΠ°ΠΊΡΠΈΡΠ½ΠΈΡΠ΅ ΠΏΡΠΈΠΌΠ΅Π½ΠΈ Π½Π° BPF.
Π Π΅Π·ΠΈΠΌΠ΅ Π½Π° ΡΡΠ°ΡΠΈΡΠ°ΡΠ°
ΠΡΠ²ΠΎ, ΡΠ΅ ΡΠ° ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ Π°ΡΡ ΠΈΡΠ΅ΠΊΡΡΡΠ°ΡΠ° Π½Π° BPF ΠΎΠ΄ ΠΏΡΠΈΡΡΠ° ΠΏΠ΅ΡΡΠΏΠ΅ΠΊΡΠΈΠ²Π° ΠΈ ΡΠ΅ Π³ΠΈ ΠΏΡΠ΅ΡΡΡΠ°Π²ΠΈΠΌΠ΅ Π³Π»Π°Π²Π½ΠΈΡΠ΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠΈ.
ΠΠ΅ΡΠ΅ ΠΈΠΌΠ°ΡΡΠΈ ΠΈΠ΄Π΅ΡΠ° Π·Π° Π°ΡΡ ΠΈΡΠ΅ΠΊΡΡΡΠ°ΡΠ° ΠΊΠ°ΠΊΠΎ ΡΠ΅Π»ΠΈΠ½Π°, ΡΠ΅ ΡΠ° ΠΎΠΏΠΈΡΠ΅ΠΌΠ΅ ΡΡΡΡΠΊΡΡΡΠ°ΡΠ° Π½Π° Π²ΠΈΡΡΡΠ΅Π»Π½Π°ΡΠ° ΠΌΠ°ΡΠΈΠ½Π° BPF.
ΠΠΎ ΠΎΠ²ΠΎΡ Π΄Π΅Π» ΠΏΠΎΠ΄Π΅ΡΠ°Π»Π½ΠΎ ΡΠ΅ Π³ΠΎ ΡΠ°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ ΠΆΠΈΠ²ΠΎΡΠ½ΠΈΠΎΡ ΡΠΈΠΊΠ»ΡΡ Π½Π° ΠΎΠ±ΡΠ΅ΠΊΡΠΈΡΠ΅ Π½Π° BPF - ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ ΠΈ ΠΌΠ°ΠΏΠΈ.
Π‘ΠΎ ΠΎΠ΄ΡΠ΅Π΄Π΅Π½ΠΎ ΡΠ°Π·Π±ΠΈΡΠ°ΡΠ΅ Π·Π° ΡΠΈΡΡΠ΅ΠΌΠΎΡ Π²Π΅ΡΠ΅ ΠΏΠΎΡΡΠ°Π²Π΅Π½, ΠΊΠΎΠ½Π΅ΡΠ½ΠΎ ΡΠ΅ ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ ΠΊΠ°ΠΊΠΎ Π΄Π° ΠΊΡΠ΅ΠΈΡΠ°ΠΌΠ΅ ΠΈ ΠΌΠ°Π½ΠΈΠΏΡΠ»ΠΈΡΠ°ΠΌΠ΅ ΡΠΎ ΠΎΠ±ΡΠ΅ΠΊΡΠΈ ΠΎΠ΄ ΠΊΠΎΡΠΈΡΠ½ΠΈΡΠΊΠΈΠΎΡ ΠΏΡΠΎΡΡΠΎΡ ΠΊΠΎΡΠΈΡΡΠ΅ΡΡΠΈ ΡΠΏΠ΅ΡΠΈΡΠ°Π»Π΅Π½ ΡΠΈΡΡΠ΅ΠΌΡΠΊΠΈ ΠΏΠΎΠ²ΠΈΠΊ β bpf(2).
Π‘Π΅ ΡΠ°Π·Π±ΠΈΡΠ°, ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΠΏΠΈΡΡΠ²Π°ΡΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ ΠΊΠΎΡΠΈΡΡΠ΅ΡΡΠΈ ΡΠΈΡΡΠ΅ΠΌΡΠΊΠΈ ΠΏΠΎΠ²ΠΈΠΊ. ΠΠΎ, ΡΠΎΠ° Π΅ ΡΠ΅ΡΠΊΠΎ. ΠΠ° ΠΏΠΎΡΠ΅Π°Π»Π½ΠΎ ΡΡΠ΅Π½Π°ΡΠΈΠΎ, Π½ΡΠΊΠ»Π΅Π°ΡΠ½ΠΈΡΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ΅ΡΠΈ ΡΠ°Π·Π²ΠΈΡΠ° Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° libbpf. ΠΠ΅ ΡΠΎΠ·Π΄Π°Π΄Π΅ΠΌΠ΅ ΠΎΡΠ½ΠΎΠ²Π΅Π½ ΡΠΊΠ΅Π»Π΅Ρ Π·Π° Π°ΠΏΠ»ΠΈΠΊΠ°ΡΠΈΡΠ° BPF ΡΡΠΎ ΡΠ΅ Π³ΠΎ ΠΊΠΎΡΠΈΡΡΠΈΠΌΠ΅ Π²ΠΎ ΡΠ»Π΅Π΄Π½ΠΈΡΠ΅ ΠΏΡΠΈΠΌΠ΅ΡΠΈ.
ΠΠ²Π΄Π΅ ΡΠ΅ Π½Π°ΡΡΠΈΠΌΠ΅ ΠΊΠ°ΠΊΠΎ BPF-ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ΅ ΠΌΠΎΠΆΠ°Ρ Π΄Π° ΠΏΡΠΈΡΡΠ°ΠΏΠ°Ρ Π΄ΠΎ ΡΡΠ½ΠΊΡΠΈΠΈΡΠ΅ Π·Π° ΠΏΠΎΠΌΠΎΡ Π½Π° ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ - Π°Π»Π°ΡΠΊΠ° ΠΊΠΎΡΠ°, Π·Π°Π΅Π΄Π½ΠΎ ΡΠΎ ΠΌΠ°ΠΏΠΈΡΠ΅, ΡΡΡΡΠΈΠ½ΡΠΊΠΈ Π³ΠΈ ΠΏΡΠΎΡΠΈΡΡΠ²Π° ΠΌΠΎΠΆΠ½ΠΎΡΡΠΈΡΠ΅ Π½Π° Π½ΠΎΠ²ΠΈΠΎΡ BPF Π²ΠΎ ΡΠΏΠΎΡΠ΅Π΄Π±Π° ΡΠΎ ΠΊΠ»Π°ΡΠΈΡΠ½ΠΈΠΎΡ.
ΠΠΎ ΠΎΠ²ΠΎΡ ΠΌΠΎΠΌΠ΅Π½Ρ, ΡΠ΅ Π·Π½Π°Π΅ΠΌΠ΅ Π΄ΠΎΠ²ΠΎΠ»Π½ΠΎ Π·Π° Π΄Π° ΡΠ°Π·Π±Π΅ΡΠ΅ΠΌΠ΅ ΡΠΎΡΠ½ΠΎ ΠΊΠ°ΠΊΠΎ ΠΌΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° ΠΊΡΠ΅ΠΈΡΠ°ΠΌΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ ΡΡΠΎ ΠΊΠΎΡΠΈΡΡΠ°Ρ ΠΌΠ°ΠΏΠΈ. Π, Π΄ΡΡΠΈ ΠΈ Π΄Π° ΡΠΈΡΠ½Π΅ΠΌΠ΅ Π²ΠΎ Π³ΠΎΠ»Π΅ΠΌΠΈΠΎΡ ΠΈ ΠΌΠΎΡΠ΅Π½ ΠΏΡΠΎΠ²Π΅ΡΡΠ²Π°Ρ.
ΠΠ΅Π» Π·Π° ΠΏΠΎΠΌΠΎΡ Π·Π° ΡΠΎΠ° ΠΊΠ°ΠΊΠΎ Π΄Π° ΡΠ΅ ΡΠΎΠ±Π΅ΡΠ°Ρ ΠΏΠΎΡΡΠ΅Π±Π½ΠΈΡΠ΅ Π°Π»Π°ΡΠΊΠΈ ΠΈ ΡΠ°Π΄ΡΠΎ Π·Π° Π΅ΠΊΡΠΏΠ΅ΡΠΈΠΌΠ΅Π½ΡΠΈ.
ΠΠ° ΠΊΡΠ°ΡΠΎΡ ΠΎΠ΄ ΡΡΠ°ΡΠΈΡΠ°ΡΠ°, ΠΎΠ½ΠΈΠ΅ ΡΡΠΎ ΡΠ΅ ΠΏΡΠΎΡΠΈΡΠ°Π°Ρ Π΄ΠΎ ΡΡΠΊΠ° ΡΠ΅ Π½Π°ΡΠ΄Π°Ρ ΠΌΠΎΡΠΈΠ²ΠΈΡΠ°ΡΠΊΠΈ Π·Π±ΠΎΡΠΎΠ²ΠΈ ΠΈ ΠΊΡΠ°ΡΠΎΠΊ ΠΎΠΏΠΈΡ Π·Π° ΡΠΎΠ° ΡΡΠΎ ΡΠ΅ ΡΠ΅ ΡΠ»ΡΡΠΈ Π²ΠΎ ΡΠ»Π΅Π΄Π½ΠΈΡΠ΅ ΡΡΠ°ΡΠΈΠΈ. ΠΠ΅ Π½Π°Π²Π΅Π΄Π΅ΠΌΠ΅ ΠΈ Π³ΠΎΠ»Π΅ΠΌ Π±ΡΠΎΡ Π»ΠΈΠ½ΠΊΠΎΠ²ΠΈ Π·Π° ΡΠ°ΠΌΠΎΡΡΠΎΡΠ½ΠΎ ΡΡΠ΅ΡΠ΅ Π·Π° ΠΎΠ½ΠΈΠ΅ ΠΊΠΎΠΈ Π½Π΅ΠΌΠ°Π°Ρ ΠΆΠ΅Π»Π±Π° ΠΈΠ»ΠΈ ΠΌΠΎΠΆΠ½ΠΎΡΡ Π΄Π° Π³ΠΎ ΡΠ΅ΠΊΠ°Π°Ρ ΠΏΡΠΎΠ΄ΠΎΠ»ΠΆΠ΅Π½ΠΈΠ΅ΡΠΎ.
ΠΠΎΠ²Π΅Π΄ Π²ΠΎ Π°ΡΡ ΠΈΡΠ΅ΠΊΡΡΡΠ°ΡΠ° BPF
ΠΡΠ΅Π΄ Π΄Π° Π·Π°ΠΏΠΎΡΠ½Π΅ΠΌΠ΅ Π΄Π° ΡΠ° ΡΠ°Π·Π³Π»Π΅Π΄ΡΠ²Π°ΠΌΠ΅ Π°ΡΡ ΠΈΡΠ΅ΠΊΡΡΡΠ°ΡΠ° BPF, ΡΠ΅ ΡΠ΅ ΠΏΠΎΠ²ΠΈΠΊΠ°ΠΌΠ΅ ΠΏΠΎΡΠ»Π΅Π΄Π΅Π½ ΠΏΠ°Ρ (ΠΎΡ ). , ΠΊΠΎΡ Π±Π΅ΡΠ΅ ΡΠ°Π·Π²ΠΈΠ΅Π½ ΠΊΠ°ΠΊΠΎ ΠΎΠ΄Π³ΠΎΠ²ΠΎΡ Π½Π° ΠΏΠΎΡΠ°Π²Π°ΡΠ° Π½Π° RISC ΠΌΠ°ΡΠΈΠ½ΠΈΡΠ΅ ΠΈ Π³ΠΎ ΡΠ΅ΡΠΈ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠΎΡ ΡΠΎ Π΅ΡΠΈΠΊΠ°ΡΠ½ΠΎ ΡΠΈΠ»ΡΡΠΈΡΠ°ΡΠ΅ Π½Π° ΠΏΠ°ΠΊΠ΅ΡΠΈ. ΠΡΡ ΠΈΡΠ΅ΠΊΡΡΡΠ°ΡΠ° ΡΠ΅ ΠΏΠΎΠΊΠ°ΠΆΠ° ΠΊΠ°ΠΊΠΎ ΡΠΎΠ»ΠΊΡ ΡΡΠΏΠ΅ΡΠ½Π° ΡΡΠΎ, ΡΠΎΠ΄Π΅Π½Π° Π²ΠΎ Π΄Π΅Π²Π΅Π΄Π΅ΡΠ΅ΡΡΠΈΡΠ΅ Π²ΠΎ ΠΠ΅ΡΠΊΠ»ΠΈ UNIX, Π±Π΅ΡΠ΅ ΠΏΡΠ΅Π½Π΅ΡΠ΅Π½Π° Π½Π° ΠΏΠΎΠ²Π΅ΡΠ΅ΡΠΎ ΠΏΠΎΡΡΠΎΠ΅ΡΠΊΠΈ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠ²Π½ΠΈ ΡΠΈΡΡΠ΅ΠΌΠΈ, ΠΏΡΠ΅ΠΆΠΈΠ²Π΅Π° Π²ΠΎ Π»ΡΠ΄ΠΈΡΠ΅ Π΄Π²Π°Π΅ΡΠ΅ΡΡΠΈ ΠΈ ΡΓ¨ ΡΡΡΠ΅ Π½Π°ΠΎΡΠ° Π½ΠΎΠ²ΠΈ Π°ΠΏΠ»ΠΈΠΊΠ°ΡΠΈΠΈ.
ΠΠΎΠ²ΠΈΠΎΡ BPF Π±Π΅ΡΠ΅ ΡΠ°Π·Π²ΠΈΠ΅Π½ ΠΊΠ°ΠΊΠΎ ΠΎΠ΄Π³ΠΎΠ²ΠΎΡ Π½Π° ΡΠ΅ΠΏΡΠΈΡΡΡΠ½ΠΎΡΡΠ° Π½Π° 64-Π±ΠΈΡΠ½ΠΈ ΠΌΠ°ΡΠΈΠ½ΠΈ, ΠΎΠ±Π»Π°ΠΊ ΡΡΠ»ΡΠ³ΠΈ ΠΈ Π·Π³ΠΎΠ»Π΅ΠΌΠ΅Π½Π°ΡΠ° ΠΏΠΎΡΡΠ΅Π±Π° Π·Π° Π°Π»Π°ΡΠΊΠΈ Π·Π° ΡΠΎΠ·Π΄Π°Π²Π°ΡΠ΅ SDN (SΠ½Π°ΡΡΠ²Π΅Ρ-dΠ΅ΡΠΈΠ½ΠΈΡΠ°Π½ nΠΌΡΠ΅ΠΆΠ½ΠΎ ΡΠ°Π±ΠΎΡΠ΅ΡΠ΅). Π Π°Π·Π²ΠΈΠ΅Π½ ΠΎΠ΄ ΠΈΠ½ΠΆΠ΅Π½Π΅ΡΠΈ Π·Π° ΠΎΡΠ½ΠΎΠ²Π½ΠΈ ΠΌΡΠ΅ΠΆΠΈ ΠΊΠ°ΠΊΠΎ ΠΏΠΎΠ΄ΠΎΠ±ΡΠ΅Π½Π° Π·Π°ΠΌΠ΅Π½Π° Π·Π° ΠΊΠ»Π°ΡΠΈΡΠ½ΠΈΠΎΡ BPF, Π½ΠΎΠ²ΠΈΠΎΡ BPF Π½Π°ΡΠ΄Π΅ ΠΏΡΠΈΠΌΠ΅Π½Π° Π²ΠΎ ΡΠ΅ΡΠΊΠ°ΡΠ° Π·Π°Π΄Π°ΡΠ° Π½Π° ΡΡΠ°ΡΠΈΡΠ°ΡΠ΅ ΡΠ°ΠΌΠΎ ΡΠ΅ΡΡ ΠΌΠ΅ΡΠ΅ΡΠΈ ΠΏΠΎΠ΄ΠΎΡΠ½Π°. Linux ΡΠΈΡΡΠ΅ΠΌΠΈ, Π° ΡΠ΅Π³Π°, ΡΠ΅ΡΡ Π³ΠΎΠ΄ΠΈΠ½ΠΈ ΠΏΠΎ Π½ΠΈΠ²Π½ΠΎΡΠΎ ΠΏΠΎΡΠ°Π²ΡΠ²Π°ΡΠ΅, ΡΠ΅ Π½ΠΈ ΡΡΠ΅Π±Π° ΡΠ΅Π»Π° Π½ΠΎΠ²Π° ΡΡΠ°ΡΠΈΡΠ° ΡΠ°ΠΌΠΎ Π·Π° Π΄Π° Π³ΠΈ Π½Π°Π²Π΅Π΄Π΅ΠΌΠ΅ ΡΠ°Π·Π»ΠΈΡΠ½ΠΈΡΠ΅ Π²ΠΈΠ΄ΠΎΠ²ΠΈ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ.
Π‘ΠΌΠ΅ΡΠ½ΠΈ ΡΠ»ΠΈΠΊΠΈ
ΠΠΎ Π½Π΅Π³ΠΎΠ²ΠΎΡΠΎ ΡΠ°Π΄ΡΠΎ, BPF Π΅ Π²ΠΈΡΡΡΠ΅Π»Π½Π° ΠΌΠ°ΡΠΈΠ½Π° ΡΠΎ ΠΏΠ΅ΡΠΎΠΊ, ΠΊΠΎΡΠ° Π²ΠΈ ΠΎΠ²ΠΎΠ·ΠΌΠΎΠΆΡΠ²Π° Π΄Π° ΠΈΠ·Π²ΡΡΠΈΡΠ΅ βΠΏΡΠΎΠΈΠ·Π²ΠΎΠ»Π΅Π½β ΠΊΠΎΠ΄ Π²ΠΎ ΠΏΡΠΎΡΡΠΎΡΠΎΡ Π½Π° ΡΠ°Π΄ΡΠΎΡΠΎ Π±Π΅Π· Π΄Π° ΡΠ° Π·Π°Π³ΡΠΎΠ·ΠΈΡΠ΅ Π±Π΅Π·Π±Π΅Π΄Π½ΠΎΡΡΠ°. ΠΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ΅ BPF ΡΠ΅ ΠΊΡΠ΅ΠΈΡΠ°Π°Ρ Π²ΠΎ ΠΊΠΎΡΠΈΡΠ½ΠΈΡΠΊΠΈ ΠΏΡΠΎΡΡΠΎΡ, ΡΠ΅ Π²ΡΠΈΡΡΠ²Π°Π°Ρ Π²ΠΎ ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ ΠΈ ΡΠ΅ ΠΏΠΎΠ²ΡΠ·Π°Π½ΠΈ ΡΠΎ Π½Π΅ΠΊΠΎΡ ΠΈΠ·Π²ΠΎΡ Π½Π° Π½Π°ΡΡΠ°Π½ΠΈ. ΠΠ°ΡΡΠ°Π½ ΠΌΠΎΠΆΠ΅ Π΄Π° Π±ΠΈΠ΄Π΅, Π½Π° ΠΏΡΠΈΠΌΠ΅Ρ, ΠΈΡΠΏΠΎΡΠ°ΠΊΠ° Π½Π° ΠΏΠ°ΠΊΠ΅Ρ Π΄ΠΎ ΠΌΡΠ΅ΠΆΠ΅Π½ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΡΡ, Π»Π°Π½ΡΠΈΡΠ°ΡΠ΅ Π½Π° Π½Π΅ΠΊΠΎΡΠ° ΡΡΠ½ΠΊΡΠΈΡΠ° Π½Π° ΡΠ°Π΄ΡΠΎΡΠΎ ΠΈΡΠ½. ΠΠΎ ΡΠ»ΡΡΠ°Ρ Π½Π° ΠΏΠ°ΠΊΠ΅Ρ, ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° BPF ΡΠ΅ ΠΈΠΌΠ° ΠΏΡΠΈΡΡΠ°ΠΏ Π΄ΠΎ ΠΏΠΎΠ΄Π°ΡΠΎΡΠΈΡΠ΅ ΠΈ ΠΌΠ΅ΡΠ°ΠΏΠΎΠ΄Π°ΡΠΎΡΠΈΡΠ΅ Π½Π° ΠΏΠ°ΠΊΠ΅ΡΠΎΡ (Π·Π° ΡΠΈΡΠ°ΡΠ΅ ΠΈ, ΠΌΠΎΠΆΠ΅Π±ΠΈ, ΠΏΠΈΡΡΠ²Π°ΡΠ΅, Π²ΠΎ Π·Π°Π²ΠΈΡΠ½ΠΎΡΡ ΠΎΠ΄ ΡΠΈΠΏΠΎΡ Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ°); Π²ΠΎ ΡΠ»ΡΡΠ°Ρ Π½Π° ΠΈΠ·Π²ΡΡΡΠ²Π°ΡΠ΅ Π½Π° ΡΡΠ½ΠΊΡΠΈΡΠ°ΡΠ° Π½Π° ΡΠ°Π΄ΡΠΎΡΠΎ, Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠΈΡΠ΅ Π½Π° ΡΡΠ½ΠΊΡΠΈΡΠ°ΡΠ°, Π²ΠΊΠ»ΡΡΡΠ²Π°ΡΡΠΈ ΠΏΠΎΠΊΠ°ΠΆΡΠ²Π°ΡΠΈ ΠΊΠΎΠ½ ΠΌΠ΅ΠΌΠΎΡΠΈΡΠ°ΡΠ° Π½Π° ΡΠ°Π΄ΡΠΎΡΠΎ, ΠΈΡΠ½.
ΠΡΠ΄Π΅ Π²Π½ΠΈΠΌΠ°ΡΠ΅Π»Π½ΠΎ Π΄Π° Π³ΠΎ ΡΠ°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ ΠΎΠ²ΠΎΡ ΠΏΡΠΎΡΠ΅Ρ. ΠΠ° ΠΏΠΎΡΠ΅ΡΠΎΠΊ, Π°ΡΠ΄Π΅ Π΄Π° Π·Π±ΠΎΡΡΠ²Π°ΠΌΠ΅ Π·Π° ΠΏΡΠ²Π°ΡΠ° ΡΠ°Π·Π»ΠΈΠΊΠ° ΠΎΠ΄ ΠΊΠ»Π°ΡΠΈΡΠ½ΠΈΠΎΡ BPF, ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ΅ Π·Π° ΠΊΠΎΠΈ Π±Π΅Π° Π½Π°ΠΏΠΈΡΠ°Π½ΠΈ Π²ΠΎ Π°ΡΠ΅ΠΌΠ±Π»Π΅Ρ. ΠΠΎ Π½ΠΎΠ²Π°ΡΠ° Π²Π΅ΡΠ·ΠΈΡΠ°, Π°ΡΡ ΠΈΡΠ΅ΠΊΡΡΡΠ°ΡΠ° Π±Π΅ΡΠ΅ ΠΏΡΠΎΡΠΈΡΠ΅Π½Π° ΡΠ°ΠΊΠ° ΡΡΠΎ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ΅ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ ΠΏΠΈΡΡΠ²Π°Π°Ρ Π½Π° ΡΠ°Π·ΠΈΡΠΈ Π½Π° Π²ΠΈΡΠΎΠΊΠΎ Π½ΠΈΠ²ΠΎ, ΠΏΡΠ²Π΅Π½ΡΡΠ²Π΅Π½ΠΎ, ΡΠ΅ ΡΠ°Π·Π±ΠΈΡΠ°, Π²ΠΎ C. ΠΠ° ΠΎΠ²Π°, Π±Π΅ΡΠ΅ ΡΠ°Π·Π²ΠΈΠ΅Π½ Π±Π΅ΠΊΠ΅Π½Π΄ Π·Π° llvm, ΠΊΠΎΡ ΠΎΠ²ΠΎΠ·ΠΌΠΎΠΆΡΠ²Π° Π³Π΅Π½Π΅ΡΠΈΡΠ°ΡΠ΅ Π±Π°ΡΡΠ΅ΠΊΠΎΠ΄ Π·Π° Π°ΡΡ ΠΈΡΠ΅ΠΊΡΡΡΠ°ΡΠ° BPF.

ΠΡΡ
ΠΈΡΠ΅ΠΊΡΡΡΠ°ΡΠ° BPF Π±Π΅ΡΠ΅ Π΄ΠΈΠ·Π°ΡΠ½ΠΈΡΠ°Π½Π°, Π΄Π΅Π»ΡΠΌΠ½ΠΎ, Π΄Π° ΡΠ°Π±ΠΎΡΠΈ Π΅ΡΠΈΠΊΠ°ΡΠ½ΠΎ Π½Π° ΡΠΎΠ²ΡΠ΅ΠΌΠ΅Π½ΠΈ ΠΌΠ°ΡΠΈΠ½ΠΈ. ΠΠ° Π΄Π° ΠΌΠΎΠΆΠ΅ ΠΎΠ²Π° Π΄Π° ΡΡΠ½ΠΊΡΠΈΠΎΠ½ΠΈΡΠ° Π²ΠΎ ΠΏΡΠ°ΠΊΡΠ°, BPF Π±Π°ΡΡΠ΅ΠΊΠΎΠ΄ΠΎΡ, ΠΎΡΠΊΠ°ΠΊΠΎ ΡΠ΅ ΡΠ΅ Π²ΡΠΈΡΠ° Π²ΠΎ ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ, ΡΠ΅ ΠΏΡΠ΅Π²Π΅Π΄ΡΠ²Π° Π²ΠΎ ΠΌΠ°ΡΡΠΈΠ½ ΠΊΠΎΠ΄ ΠΊΠΎΡΠΈΡΡΠ΅ΡΡΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠ° Π½Π°ΡΠ΅ΡΠ΅Π½Π° JIT ΠΊΠΎΠΌΠΏΠ°ΡΠ»Π΅Ρ (JΡΡΡΠ° In TΠ²ΡΠ΅ΠΌΠ΅). Π‘Π»Π΅Π΄Π½ΠΎ, Π°ΠΊΠΎ ΡΠ΅ ΡΠ΅ΡΠ°Π²Π°ΡΠ΅, Π²ΠΎ ΠΊΠ»Π°ΡΠΈΡΠ½ΠΈΠΎΡ BPF ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° Π±Π΅ΡΠ΅ Π²ΡΠΈΡΠ°Π½Π° Π²ΠΎ ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ ΠΈ ΠΏΡΠΈΠΊΠ°ΡΠ΅Π½Π° Π½Π° ΠΈΠ·Π²ΠΎΡΠΎΡ Π½Π° Π½Π°ΡΡΠ°Π½ΠΎΡ Π°ΡΠΎΠΌΡΠΊΠΈ - Π²ΠΎ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡ Π½Π° Π΅Π΄Π΅Π½ ΡΠΈΡΡΠ΅ΠΌΡΠΊΠΈ ΠΏΠΎΠ²ΠΈΠΊ. ΠΠΎ Π½ΠΎΠ²Π°ΡΠ° Π°ΡΡ
ΠΈΡΠ΅ΠΊΡΡΡΠ°, ΠΎΠ²Π° ΡΠ΅ ΡΠ»ΡΡΡΠ²Π° Π²ΠΎ Π΄Π²Π΅ ΡΠ°Π·ΠΈ - ΠΏΡΠ²ΠΎ, ΠΊΠΎΠ΄ΠΎΡ ΡΠ΅ Π²ΡΠΈΡΡΠ²Π° Π²ΠΎ ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ ΡΠΎ ΠΏΠΎΠΌΠΎΡ Π½Π° ΡΠΈΡΡΠ΅ΠΌΡΠΊΠΈ ΠΏΠΎΠ²ΠΈΠΊ bpf(2)Π° ΠΏΠΎΡΠΎΠ°, ΠΏΠΎΠ΄ΠΎΡΠ½Π°, ΠΏΡΠ΅ΠΊΡ Π΄ΡΡΠ³ΠΈ ΠΌΠ΅Ρ
Π°Π½ΠΈΠ·ΠΌΠΈ ΠΊΠΎΠΈ Π²Π°ΡΠΈΡΠ°Π°Ρ Π²ΠΎ Π·Π°Π²ΠΈΡΠ½ΠΎΡΡ ΠΎΠ΄ Π²ΠΈΠ΄ΠΎΡ Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ°, ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° ΡΠ΅ ΠΏΡΠΈΠΊΠ°ΡΡΠ²Π° Π½Π° ΠΈΠ·Π²ΠΎΡΠΎΡ Π½Π° Π½Π°ΡΡΠ°Π½ΠΎΡ.
ΠΠ²Π΄Π΅ ΡΠΈΡΠ°ΡΠ΅Π»ΠΎΡ ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΈΠΌΠ° ΠΏΡΠ°ΡΠ°ΡΠ΅: Π΄Π°Π»ΠΈ Π±Π΅ΡΠ΅ ΠΌΠΎΠΆΠ½ΠΎ? ΠΠ°ΠΊΠΎ ΡΠ΅ Π³Π°ΡΠ°Π½ΡΠΈΡΠ° Π±Π΅Π·Π±Π΅Π΄Π½ΠΎΡΡΠ° Π½Π° ΠΈΠ·Π²ΡΡΡΠ²Π°ΡΠ΅ΡΠΎ Π½Π° ΡΠ°ΠΊΠΎΠ² ΠΊΠΎΠ΄? ΠΠ΅Π·Π±Π΅Π΄Π½ΠΎΡΡΠ° Π½Π° ΠΈΠ·Π²ΡΡΡΠ²Π°ΡΠ΅ΡΠΎ Π½ΠΈ Π΅ Π·Π°Π³Π°ΡΠ°Π½ΡΠΈΡΠ°Π½Π° ΡΠΎ ΡΠ°Π·Π°ΡΠ° Π½Π° Π²ΡΠΈΡΡΠ²Π°ΡΠ΅ Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ΅ BPF Π½Π°ΡΠ΅ΡΠ΅Π½Π° ΠΏΡΠΎΠ²Π΅ΡΡΠ²Π°Ρ (Π½Π° Π°Π½Π³Π»ΠΈΡΠΊΠΈ ΠΎΠ²Π°Π° ΡΠ°Π·Π° ΡΠ΅ Π½Π°ΡΠ΅ΠΊΡΠ²Π° ΠΏΡΠΎΠ²Π΅ΡΡΠ²Π°Ρ ΠΈ ΡΠ°Ρ ΡΠ΅ ΠΏΡΠΎΠ΄ΠΎΠ»ΠΆΠ°ΠΌ Π΄Π° Π³ΠΎ ΠΊΠΎΡΠΈΡΡΠ°ΠΌ Π°Π½Π³Π»ΠΈΡΠΊΠΈΠΎΡ Π·Π±ΠΎΡ):

ΠΡΠΎΠ²Π΅ΡΡΠ²Π°ΡΠΎΡ Π΅ ΡΡΠ°ΡΠΈΡΠ΅Π½ Π°Π½Π°Π»ΠΈΠ·Π°ΡΠΎΡ ΠΊΠΎΡ ΠΎΡΠΈΠ³ΡΡΡΠ²Π° Π΄Π΅ΠΊΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° Π½Π΅ Π³ΠΎ Π½Π°ΡΡΡΡΠ²Π° Π½ΠΎΡΠΌΠ°Π»Π½ΠΎΡΠΎ ΡΡΠ½ΠΊΡΠΈΠΎΠ½ΠΈΡΠ°ΡΠ΅ Π½Π° ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ. ΠΠ²Π°, ΠΏΠ°ΡΠ΅ΠΌ, Π½Π΅ Π·Π½Π°ΡΠΈ Π΄Π΅ΠΊΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° Π½Π΅ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ ΠΌΠ΅ΡΠ° Π²ΠΎ ΡΠ°Π±ΠΎΡΠ°ΡΠ° Π½Π° ΡΠΈΡΡΠ΅ΠΌΠΎΡ - ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ΅ BPF, Π²ΠΎ Π·Π°Π²ΠΈΡΠ½ΠΎΡΡ ΠΎΠ΄ Π²ΠΈΠ΄ΠΎΡ, ΠΌΠΎΠΆΠ°Ρ Π΄Π° ΡΠΈΡΠ°Π°Ρ ΠΈ ΠΏΡΠ΅ΠΏΠΈΡΡΠ²Π°Π°Ρ Π΄Π΅Π»ΠΎΠ²ΠΈ ΠΎΠ΄ ΠΌΠ΅ΠΌΠΎΡΠΈΡΠ°ΡΠ° Π½Π° ΡΠ°Π΄ΡΠΎΡΠΎ, Π΄Π° Π²ΡΠ°ΡΠ°Π°Ρ Π²ΡΠ΅Π΄Π½ΠΎΡΡΠΈ Π½Π° ΡΡΠ½ΠΊΡΠΈΠΈ, Π΄Π° ΡΠΊΡΠ°ΡΡΠ²Π°Π°Ρ, Π΄ΠΎΠ΄Π°Π²Π°Π°Ρ, ΠΏΡΠ΅ΠΏΠΈΡΡΠ²Π°Π°Ρ ΠΏΠ° Π΄ΡΡΠΈ ΠΈ ΠΏΡΠ΅ΠΏΡΠ°ΡΠ°ΡΠ΅ ΠΌΡΠ΅ΠΆΠ½ΠΈ ΠΏΠ°ΠΊΠ΅ΡΠΈ. ΠΠ΅ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΠΎΡ Π³Π°ΡΠ°Π½ΡΠΈΡΠ° Π΄Π΅ΠΊΠ° ΠΈΠ·Π²ΡΡΡΠ²Π°ΡΠ΅ΡΠΎ Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° BPF Π½Π΅ΠΌΠ° Π΄Π° Π³ΠΎ ΡΡΡΡΠΈ ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ ΠΈ Π΄Π΅ΠΊΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° ΡΡΠΎ, ΡΠΏΠΎΡΠ΅Π΄ ΠΏΡΠ°Π²ΠΈΠ»Π°ΡΠ°, ΠΈΠΌΠ° ΠΏΡΠΈΡΡΠ°ΠΏ Π·Π° Π·Π°ΠΏΠΈΡΡΠ²Π°ΡΠ΅, Π½Π° ΠΏΡΠΈΠΌΠ΅Ρ, ΠΏΠΎΠ΄Π°ΡΠΎΡΠΈΡΠ΅ Π½Π° ΠΏΠ°ΠΊΠ΅ΡΠΎΡ ΡΡΠΎ ΠΎΠ΄ΠΈ, Π½Π΅ΠΌΠ° Π΄Π° ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ° ΠΏΡΠ΅Π·Π°ΠΏΠΈΡΠ΅ ΠΌΠ΅ΠΌΠΎΡΠΈΡΠ°ΡΠ° Π½Π° ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ Π½Π°Π΄Π²ΠΎΡ ΠΎΠ΄ ΠΏΠ°ΠΊΠ΅ΡΠΎΡ. ΠΠ΅ Π³ΠΎ ΡΠ°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ Π²Π΅ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΠΎΡ ΠΌΠ°Π»ΠΊΡ ΠΏΠΎΠ΄Π΅ΡΠ°Π»Π½ΠΎ Π²ΠΎ ΡΠΎΠΎΠ΄Π²Π΅ΡΠ½ΠΈΠΎΡ Π΄Π΅Π», ΠΎΡΠΊΠ°ΠΊΠΎ ΡΠ΅ ΡΠ΅ Π·Π°ΠΏΠΎΠ·Π½Π°Π΅ΠΌΠ΅ ΡΠΎ ΡΠΈΡΠ΅ Π΄ΡΡΠ³ΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠΈ Π½Π° BPF.
ΠΠ½Π°ΡΠΈ, ΡΡΠΎ Π½Π°ΡΡΠΈΠ²ΠΌΠ΅ Π΄ΠΎΡΠ΅Π³Π°? ΠΠΎΡΠΈΡΠ½ΠΈΠΊΠΎΡ ΠΏΠΈΡΡΠ²Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° Π²ΠΎ C, ΡΠ° Π²ΡΠΈΡΡΠ²Π° Π²ΠΎ ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ ΠΊΠΎΡΠΈΡΡΠ΅ΡΡΠΈ ΡΠΈΡΡΠ΅ΠΌΡΠΊΠΈ ΠΏΠΎΠ²ΠΈΠΊ bpf(2), ΠΊΠ°Π΄Π΅ ΡΡΠΎ ΡΠ΅ ΠΏΡΠΎΠ²Π΅ΡΡΠ²Π° ΠΎΠ΄ ΠΏΡΠΎΠ²Π΅ΡΡΠ²Π°Ρ ΠΈ ΡΠ΅ ΠΏΡΠ΅Π²Π΅Π΄ΡΠ²Π° Π½Π° ΠΌΠ°ΡΡΠΈΠ½ Π±Π°ΡΡΠ΅ΠΊΠΎΠ΄. ΠΠΎΡΠΎΠ° ΠΈΡΡΠΈΠΎΡ ΠΈΠ»ΠΈ Π΄ΡΡΠ³ ΠΊΠΎΡΠΈΡΠ½ΠΈΠΊ ΡΠ° ΠΏΠΎΠ²ΡΠ·ΡΠ²Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° ΡΠΎ ΠΈΠ·Π²ΠΎΡΠΎΡ Π½Π° Π½Π°ΡΡΠ°Π½ΠΎΡ ΠΈ ΡΠ°Π° Π·Π°ΠΏΠΎΡΠ½ΡΠ²Π° Π΄Π° ΡΠ΅ ΠΈΠ·Π²ΡΡΡΠ²Π°. ΠΠ΄Π²ΠΎΡΡΠ²Π°ΡΠ΅ΡΠΎ Π½Π° Π±Π°Π³Π°ΠΆΠ½ΠΈΠΊΠΎΡ ΠΈ ΠΏΠΎΠ²ΡΠ·ΡΠ²Π°ΡΠ΅ΡΠΎ Π΅ Π½Π΅ΠΎΠΏΡ
ΠΎΠ΄Π½ΠΎ ΠΎΠ΄ Π½Π΅ΠΊΠΎΠ»ΠΊΡ ΠΏΡΠΈΡΠΈΠ½ΠΈ. ΠΡΠ²ΠΎ, Π²ΠΎΠ΄Π΅ΡΠ΅ Π½Π° ΠΏΡΠΎΠ²Π΅ΡΡΠ²Π°Ρ Π΅ ΡΠ΅Π»Π°ΡΠΈΠ²Π½ΠΎ ΡΠΊΠ°ΠΏΠΎ ΠΈ ΡΠΎ ΠΏΡΠ΅Π·Π΅ΠΌΠ°ΡΠ΅ Π½Π° ΠΈΡΡΠ°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° Π½Π΅ΠΊΠΎΠ»ΠΊΡ ΠΏΠ°ΡΠΈ Π³ΡΠ±ΠΈΠΌΠ΅ Π²ΡΠ΅ΠΌΠ΅ Π½Π° ΠΊΠΎΠΌΠΏΡΡΡΠ΅ΡΠΎΡ. ΠΡΠΎΡΠΎ, ΡΠΎΡΠ½ΠΎ ΠΊΠ°ΠΊΠΎ Π΅ ΠΏΠΎΠ²ΡΠ·Π°Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° Π·Π°Π²ΠΈΡΠΈ ΠΎΠ΄ Π½Π΅ΡΠ·ΠΈΠ½ΠΈΠΎΡ ΡΠΈΠΏ, Π° Π΅Π΄Π΅Π½ βΡΠ½ΠΈΠ²Π΅ΡΠ·Π°Π»Π΅Π½β ΠΈΠ½ΡΠ΅ΡΡΠ΅ΡΡ ΡΠ°Π·Π²ΠΈΠ΅Π½ ΠΏΡΠ΅Π΄ Π΅Π΄Π½Π° Π³ΠΎΠ΄ΠΈΠ½Π° ΠΌΠΎΠΆΠ΅Π±ΠΈ Π½Π΅ Π΅ ΠΏΠΎΠ³ΠΎΠ΄Π΅Π½ Π·Π° Π½ΠΎΠ²ΠΈ ΡΠΈΠΏΠΎΠ²ΠΈ Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ. (ΠΠ°ΠΊΠΎ ΡΠ΅Π³Π° ΠΊΠΎΠ³Π° Π°ΡΡ
ΠΈΡΠ΅ΠΊΡΡΡΠ°ΡΠ° ΡΡΠ°Π½ΡΠ²Π° ΠΏΠΎΠ·ΡΠ΅Π»Π°, ΠΏΠΎΡΡΠΎΠΈ ΠΈΠ΄Π΅ΡΠ° Π΄Π° ΡΠ΅ ΠΎΠ±Π΅Π΄ΠΈΠ½ΠΈ ΠΎΠ²ΠΎΡ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΡΡ Π½Π° Π½ΠΈΠ²ΠΎ libbpf.)
ΠΠ½ΠΈΠΌΠ°ΡΠ΅Π»Π½ΠΈΠΎΡ ΡΠΈΡΠ°ΡΠ΅Π» ΠΌΠΎΠΆΠ΅ Π΄Π° Π·Π°Π±Π΅Π»Π΅ΠΆΠΈ Π΄Π΅ΠΊΠ° ΡΓ¨ ΡΡΡΠ΅ Π½Π΅ ΡΠΌΠ΅ Π·Π°Π²ΡΡΠΈΠ»Π΅ ΡΠΎ ΡΠ»ΠΈΠΊΠΈΡΠ΅. ΠΠ°Π²ΠΈΡΡΠΈΠ½Π°, ΡΠ΅ΡΠΎ Π³ΠΎΡΠ΅Π½Π°Π²Π΅Π΄Π΅Π½ΠΎ Π½Π΅ ΠΎΠ±ΡΠ°ΡΠ½ΡΠ²Π° Π·ΠΎΡΡΠΎ BPF ΡΡΠ½Π΄Π°ΠΌΠ΅Π½ΡΠ°Π»Π½ΠΎ ΡΠ° ΠΌΠ΅Π½ΡΠ²Π° ΡΠ»ΠΈΠΊΠ°ΡΠ° Π²ΠΎ ΡΠΏΠΎΡΠ΅Π΄Π±Π° ΡΠΎ ΠΊΠ»Π°ΡΠΈΡΠ½ΠΈΠΎΡ BPF. ΠΠ²Π΅ ΠΈΠ½ΠΎΠ²Π°ΡΠΈΠΈ ΠΊΠΎΠΈ Π·Π½Π°ΡΠΈΡΠ΅Π»Π½ΠΎ Π³ΠΎ ΠΏΡΠΎΡΠΈΡΡΠ²Π°Π°Ρ ΠΎΠΏΡΠ΅Π³ΠΎΡ Π½Π° ΠΏΡΠΈΠΌΠ΅Π½Π»ΠΈΠ²ΠΎΡΡ ΡΠ΅ ΠΌΠΎΠΆΠ½ΠΎΡΡΠ° Π·Π° ΠΊΠΎΡΠΈΡΡΠ΅ΡΠ΅ Π½Π° ΡΠΏΠΎΠ΄Π΅Π»Π΅Π½Π° ΠΌΠ΅ΠΌΠΎΡΠΈΡΠ° ΠΈ ΠΏΠΎΠΌΠΎΡΠ½ΠΈ ΡΡΠ½ΠΊΡΠΈΠΈ Π½Π° ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ. ΠΠΎ BPF, ΡΠΏΠΎΠ΄Π΅Π»Π΅Π½Π°ΡΠ° ΠΌΠ΅ΠΌΠΎΡΠΈΡΠ° ΡΠ΅ ΠΈΠΌΠΏΠ»Π΅ΠΌΠ΅Π½ΡΠΈΡΠ° ΡΠΎ ΠΊΠΎΡΠΈΡΡΠ΅ΡΠ΅ Π½Π° ΡΠ°ΠΊΠ°Π½Π°ΡΠ΅ΡΠ΅Π½ΠΈΡΠ΅ ΠΌΠ°ΠΏΠΈ - ΡΠΏΠΎΠ΄Π΅Π»Π΅Π½ΠΈ ΡΡΡΡΠΊΡΡΡΠΈ Π½Π° ΠΏΠΎΠ΄Π°ΡΠΎΡΠΈ ΡΠΎ ΡΠΏΠ΅ΡΠΈΡΠΈΡΠ΅Π½ API. ΠΠ΅ΡΠΎΡΠ°ΡΠ½ΠΎ Π³ΠΎ Π΄ΠΎΠ±ΠΈΠ»Π΅ ΠΎΠ²Π° ΠΈΠΌΠ΅ Π·Π°ΡΠΎΠ° ΡΡΠΎ ΠΏΡΠ²ΠΈΠΎΡ ΡΠΈΠΏ Π½Π° ΠΌΠ°ΠΏΠ° ΡΡΠΎ ΡΠ΅ ΠΏΠΎΡΠ°Π²ΠΈΠ» Π΅ Ρ Π΅Ρ-ΡΠ°Π±Π΅Π»Π°. ΠΠΎΡΠΎΠ° ΡΠ΅ ΠΏΠΎΡΠ°Π²ΠΈΡΠ° Π½ΠΈΠ·ΠΈ, Π»ΠΎΠΊΠ°Π»Π½ΠΈ (ΠΏΠΎ ΠΏΡΠΎΡΠ΅ΡΠΎΡΡΠΊΠΈ) Ρ Π°Ρ ΡΠ°Π±Π΅Π»ΠΈ ΠΈ Π»ΠΎΠΊΠ°Π»Π½ΠΈ Π½ΠΈΠ·ΠΈ, ΡΡΠ΅Π±Π»Π° Π·Π° ΠΏΡΠ΅Π±Π°ΡΡΠ²Π°ΡΠ΅, ΠΌΠ°ΠΏΠΈ ΠΊΠΎΠΈ ΡΠΎΠ΄ΡΠΆΠ°Ρ ΠΏΠΎΠΊΠ°ΠΆΡΠ²Π°ΡΠΈ ΠΊΠΎΠ½ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ΅ BPF ΠΈ ΠΌΠ½ΠΎΠ³Ρ ΠΏΠΎΠ²Π΅ΡΠ΅. ΠΠ½Π° ΡΡΠΎ Π½ΠΈ Π΅ ΠΈΠ½ΡΠ΅ΡΠ΅ΡΠ½ΠΎ ΡΠ΅Π³Π° Π΅ Π΄Π΅ΠΊΠ° BPF ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ΅ ΡΠ΅Π³Π° ΠΈΠΌΠ°Π°Ρ ΠΌΠΎΠΆΠ½ΠΎΡΡ Π΄Π° ΡΠ° ΠΎΠΏΡΡΠΎΡΡΠ²Π°Π°Ρ ΡΠΎΡΡΠΎΡΠ±Π°ΡΠ° ΠΏΠΎΠΌΠ΅ΡΡ ΠΏΠΎΠ²ΠΈΡΠΈΡΠ΅ ΠΈ Π΄Π° ΡΠ° ΡΠΏΠΎΠ΄Π΅Π»ΡΠ²Π°Π°Ρ ΡΠΎ Π΄ΡΡΠ³ΠΈ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ ΠΈ ΡΠΎ ΠΊΠΎΡΠΈΡΠ½ΠΈΡΠΊΠΈΠΎΡ ΠΏΡΠΎΡΡΠΎΡ.
ΠΠΎ ΠΌΠ°ΠΏΠΈ ΡΠ΅ ΠΏΡΠΈΡΡΠ°ΠΏΡΠ²Π° ΠΎΠ΄ ΠΊΠΎΡΠΈΡΠ½ΠΈΡΠΊΠΈ ΠΏΡΠΎΡΠ΅ΡΠΈ ΠΊΠΎΡΠΈΡΡΠ΅ΡΡΠΈ ΡΠΈΡΡΠ΅ΠΌΡΠΊΠΈ ΠΏΠΎΠ²ΠΈΠΊ bpf(2), ΠΈ ΠΎΠ΄ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ΅ BPF ΠΊΠΎΠΈ ΡΠ°Π±ΠΎΡΠ°Ρ Π²ΠΎ ΡΠ°Π΄ΡΠΎΡΠΎ ΠΊΠΎΡΠΈΡΡΠ΅ΡΡΠΈ ΠΏΠΎΠΌΠΎΡΠ½ΠΈ ΡΡΠ½ΠΊΡΠΈΠΈ. ΠΠΎΠΊΡΠ°Ρ ΡΠΎΠ°, ΠΏΠΎΠΌΠΎΡΠ½ΠΈΡΠΈΡΠ΅ ΠΏΠΎΡΡΠΎΡΠ°Ρ Π½Π΅ ΡΠ°ΠΌΠΎ Π·Π° ΡΠ°Π±ΠΎΡΠ° ΡΠΎ ΠΌΠ°ΠΏΠΈ, ΡΡΠΊΡ ΠΈ Π·Π° ΠΏΡΠΈΡΡΠ°ΠΏ Π΄ΠΎ Π΄ΡΡΠ³ΠΈ ΡΠΏΠΎΡΠΎΠ±Π½ΠΎΡΡΠΈ Π½Π° ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ. ΠΠ° ΠΏΡΠΈΠΌΠ΅Ρ, BPF ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ΅ ΠΌΠΎΠΆΠ°Ρ Π΄Π° ΠΊΠΎΡΠΈΡΡΠ°Ρ ΠΏΠΎΠΌΠΎΡΠ½ΠΈ ΡΡΠ½ΠΊΡΠΈΠΈ Π·Π° ΠΏΡΠ΅ΠΏΡΠ°ΡΠ°ΡΠ΅ ΠΏΠ°ΠΊΠ΅ΡΠΈ Π΄ΠΎ Π΄ΡΡΠ³ΠΈ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΡΡΠΈ, Π³Π΅Π½Π΅ΡΠΈΡΠ°ΡΠ΅ Π½Π° Π½Π°ΡΡΠ°Π½ΠΈ Π½Π° perf, ΠΏΡΠΈΡΡΠ°ΠΏ Π΄ΠΎ ΡΡΡΡΠΊΡΡΡΠΈΡΠ΅ Π½Π° ΡΠ°Π΄ΡΠΎΡΠΎ ΠΈΡΠ½.

ΠΠ°ΠΊΡΠ°ΡΠΊΠΎ, BPF ΠΎΠ±Π΅Π·Π±Π΅Π΄ΡΠ²Π° ΠΌΠΎΠΆΠ½ΠΎΡΡ Π·Π° Π²ΡΠΈΡΡΠ²Π°ΡΠ΅ Π½Π° ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ»Π΅Π½, Ρ.Π΅., ΡΠ΅ΡΡΠΈΡΠ°Π½ ΠΎΠ΄ ΠΏΡΠΎΠ²Π΅ΡΡΠ²Π°Ρ, ΠΊΠΎΡΠΈΡΠ½ΠΈΡΠΊΠΈ ΠΊΠΎΠ΄ Π²ΠΎ ΠΏΡΠΎΡΡΠΎΡΠΎΡ Π½Π° ΡΠ°Π΄ΡΠΎΡΠΎ. ΠΠ²ΠΎΡ ΠΊΠΎΠ΄ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ° Π·Π°ΡΡΠ²Π° ΡΠΎΡΡΠΎΡΠ±Π°ΡΠ° ΠΏΠΎΠΌΠ΅ΡΡ ΠΏΠΎΠ²ΠΈΡΠΈΡΠ΅ ΠΈ Π΄Π° ΡΠ°Π·ΠΌΠ΅Π½ΡΠ²Π° ΠΏΠΎΠ΄Π°ΡΠΎΡΠΈ ΡΠΎ ΠΊΠΎΡΠΈΡΠ½ΠΈΡΠΊΠΈΠΎΡ ΠΏΡΠΎΡΡΠΎΡ, Π° ΠΈΡΡΠΎ ΡΠ°ΠΊΠ° ΠΈΠΌΠ° ΠΏΡΠΈΡΡΠ°ΠΏ Π΄ΠΎ ΠΏΠΎΡΡΠΈΡΡΠ΅ΠΌΠΈ Π½Π° ΡΠ°Π΄ΡΠΎΡΠΎ Π΄ΠΎΠ·Π²ΠΎΠ»Π΅Π½ΠΈ ΠΎΠ΄ ΠΎΠ²ΠΎΡ ΡΠΈΠΏ Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°.
ΠΠ²Π° Π΅ Π²Π΅ΡΠ΅ ΡΠ»ΠΈΡΠ½ΠΎ Π½Π° ΠΌΠΎΠΆΠ½ΠΎΡΡΠΈΡΠ΅ ΡΡΠΎ Π³ΠΈ ΠΎΠ±Π΅Π·Π±Π΅Π΄ΡΠ²Π°Π°Ρ ΠΌΠΎΠ΄ΡΠ»ΠΈΡΠ΅ Π½Π° ΡΠ°Π΄ΡΠΎΡΠΎ, Π²ΠΎ ΡΠΏΠΎΡΠ΅Π΄Π±Π° ΡΠΎ ΠΊΠΎΠΈ BPF ΠΈΠΌΠ° Π½Π΅ΠΊΠΎΠΈ ΠΏΡΠ΅Π΄Π½ΠΎΡΡΠΈ (ΡΠ΅ ΡΠ°Π·Π±ΠΈΡΠ°, ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΡΠΏΠΎΡΠ΅Π΄ΡΠ²Π°ΡΠ΅ ΡΠ°ΠΌΠΎ ΡΠ»ΠΈΡΠ½ΠΈ Π°ΠΏΠ»ΠΈΠΊΠ°ΡΠΈΠΈ, Π½Π° ΠΏΡΠΈΠΌΠ΅Ρ, ΡΠΈΡΡΠ΅ΠΌΡΠΊΠΎ ΡΠ»Π΅Π΄Π΅ΡΠ΅ - Π½Π΅ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° Π½Π°ΠΏΠΈΡΠ΅ΡΠ΅ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ»Π΅Π½ Π΄Π²ΠΈΠ³Π°ΡΠ΅Π» ΡΠΎ BPF). ΠΠΎΠΆΠ΅ Π΄Π° Π·Π°Π±Π΅Π»Π΅ΠΆΠΈΡΠ΅ ΠΏΠΎΠΌΠ°Π» ΠΏΡΠ°Π³ Π·Π° Π²Π»Π΅Π· (Π½Π΅ΠΊΠΎΠΈ ΡΡΠ»ΡΠΆΠ½ΠΈ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ ΠΊΠΎΠΈ ΠΊΠΎΡΠΈΡΡΠ°Ρ BPF Π½Π΅ Π±Π°ΡΠ°Π°Ρ ΠΎΠ΄ ΠΊΠΎΡΠΈΡΠ½ΠΈΠΊΠΎΡ Π΄Π° ΠΈΠΌΠ° Π²Π΅ΡΡΠΈΠ½ΠΈ Π·Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ°ΡΠ΅ Π½Π° ΡΠ°Π΄ΡΠΎΡΠΎ, ΠΈΠ»ΠΈ ΠΎΠΏΡΡΠΎ ΠΏΡΠΎΠ³ΡΠ°ΠΌΡΠΊΠΈ Π²Π΅ΡΡΠΈΠ½ΠΈ), Π±Π΅Π·Π±Π΅Π΄Π½ΠΎΡΡ ΠΏΡΠΈ ΠΈΠ·Π²ΡΡΡΠ²Π°ΡΠ΅ (ΠΊΡΠ΅Π½Π΅ΡΠ΅ ΡΠ° ΡΠ°ΠΊΠ°ΡΠ° Π²ΠΎ ΠΊΠΎΠΌΠ΅Π½ΡΠ°ΡΠΈΡΠ΅ Π·Π° ΠΎΠ½ΠΈΠ΅ ΠΊΠΎΠΈ Π½Π΅ Π³ΠΎ ΡΠΊΡΡΠΈΠ»Π΅ ΡΠΈΡΡΠ΅ΠΌΠΎΡ ΠΊΠΎΠ³Π° ΠΏΠΈΡΡΠ²Π°Π»Π΅ ΠΈΠ»ΠΈ ΠΌΠΎΠ΄ΡΠ»ΠΈ Π·Π° ΡΠ΅ΡΡΠΈΡΠ°ΡΠ΅), Π°ΡΠΎΠΌΠ½ΠΎΡΡ - ΠΈΠΌΠ° ΠΏΡΠ΅ΠΊΠΈΠ½ΠΈ ΠΏΡΠΈ ΠΏΠΎΠ²ΡΠΎΡΠ½ΠΎ Π²ΡΠΈΡΡΠ²Π°ΡΠ΅ Π½Π° ΠΌΠΎΠ΄ΡΠ»ΠΈΡΠ΅, Π° ΠΏΠΎΡΡΠΈΡΡΠ΅ΠΌΠΎΡ BPF ΠΎΡΠΈΠ³ΡΡΡΠ²Π° Π΄Π΅ΠΊΠ° Π½ΠΈΡΡ Π΅Π΄Π΅Π½ Π½Π°ΡΡΠ°Π½ Π½Π΅ Π΅ ΠΏΡΠΎΠΏΡΡΡΠ΅Π½ (Π΄Π° Π±ΠΈΠ΄Π΅ΠΌΠ΅ ΡΠ΅Ρ, ΠΎΠ²Π° Π½Π΅ Π²Π°ΠΆΠΈ Π·Π° ΡΠΈΡΠ΅ ΡΠΈΠΏΠΎΠ²ΠΈ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ BPF).
ΠΡΠΈΡΡΡΡΠ²ΠΎΡΠΎ Π½Π° ΡΠ°ΠΊΠ²ΠΈ ΡΠΏΠΎΡΠΎΠ±Π½ΠΎΡΡΠΈ Π³ΠΎ ΠΏΡΠ°Π²ΠΈ BPF ΡΠ½ΠΈΠ²Π΅ΡΠ·Π°Π»Π½Π° Π°Π»Π°ΡΠΊΠ° Π·Π° ΠΏΡΠΎΡΠΈΡΡΠ²Π°ΡΠ΅ Π½Π° ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ, ΡΡΠΎ ΡΠ΅ ΠΏΠΎΡΠ²ΡΠ΄ΡΠ²Π° ΠΈ Π²ΠΎ ΠΏΡΠ°ΠΊΡΠ°: ΡΠ΅ ΠΏΠΎΠ²Π΅ΡΠ΅ ΠΈ ΠΏΠΎΠ²Π΅ΡΠ΅ Π½ΠΎΠ²ΠΈ Π²ΠΈΠ΄ΠΎΠ²ΠΈ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ ΡΠ΅ Π΄ΠΎΠ΄Π°Π²Π°Π°Ρ Π²ΠΎ BPF, ΡΠ΅ ΠΏΠΎΠ²Π΅ΡΠ΅ ΠΈ ΠΏΠΎΠ²Π΅ΡΠ΅ Π³ΠΎΠ»Π΅ΠΌΠΈ ΠΊΠΎΠΌΠΏΠ°Π½ΠΈΠΈ ΠΊΠΎΡΠΈΡΡΠ°Ρ BPF Π½Π° Π±ΠΎΡΠ±Π΅Π½ΠΈ ΡΠ΅ΡΠ²Π΅ΡΠΈ 24Γ7, ΡΠ΅ ΠΏΠΎΠ²Π΅ΡΠ΅ ΠΈ ΠΏΠΎΠ²Π΅ΡΠ΅ ΡΡΠ°ΡΡΠ°ΠΏΠΈΡΠ΅ Π³ΠΎ Π³ΡΠ°Π΄Π°Ρ ΡΠ²ΠΎΡΠΎΡ Π±ΠΈΠ·Π½ΠΈΡ Π½Π° ΡΠ΅ΡΠ΅Π½ΠΈΡΠ° Π²ΡΠ· ΠΎΡΠ½ΠΎΠ²Π° Π½Π° ΠΊΠΎΠΈ ΡΠ΅ Π±Π°Π·ΠΈΡΠ°Π½ΠΈ Π½Π° BPF. BPF ΡΠ΅ ΠΊΠΎΡΠΈΡΡΠΈ Π½Π°ΡΠ΅ΠΊΠ°Π΄Π΅: Π²ΠΎ Π·Π°ΡΡΠΈΡΠ° ΠΎΠ΄ DDoS Π½Π°ΠΏΠ°Π΄ΠΈ, ΡΠΎΠ·Π΄Π°Π²Π°ΡΠ΅ SDN (Π½Π° ΠΏΡΠΈΠΌΠ΅Ρ, ΠΈΠΌΠΏΠ»Π΅ΠΌΠ΅Π½ΡΠ°ΡΠΈΡΠ° Π½Π° ΠΌΡΠ΅ΠΆΠΈ Π·Π° kubernetes), ΠΊΠ°ΠΊΠΎ Π³Π»Π°Π²Π½Π° Π°Π»Π°ΡΠΊΠ° Π·Π° ΡΠ»Π΅Π΄Π΅ΡΠ΅ Π½Π° ΡΠΈΡΡΠ΅ΠΌΠΎΡ ΠΈ ΡΠΎΠ±ΠΈΡΠ°Ρ Π½Π° ΡΡΠ°ΡΠΈΡΡΠΈΠΊΠ°, Π²ΠΎ ΡΠΈΡΡΠ΅ΠΌΠΈ Π·Π° ΠΎΡΠΊΡΠΈΠ²Π°ΡΠ΅ Π½Π° ΡΠΏΠ°Π΄ ΠΈ ΡΠΈΡΡΠ΅ΠΌΠΈ Π·Π° ΠΏΠ΅ΡΠΎΠΊ, ΠΈΡΠ½.
ΠΡΠ΄Π΅ Π΄Π° Π³ΠΎ Π·Π°Π²ΡΡΠΈΠΌΠ΅ ΠΏΡΠ΅Π³Π»Π΅Π΄Π½ΠΈΠΎΡ Π΄Π΅Π» ΠΎΠ΄ ΡΡΠ°ΡΠΈΡΠ°ΡΠ° ΠΎΠ²Π΄Π΅ ΠΈ Π΄Π° ΡΠ° ΡΠ°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ Π²ΠΈΡΡΡΠ΅Π»Π½Π°ΡΠ° ΠΌΠ°ΡΠΈΠ½Π° ΠΈ Π΅ΠΊΠΎΡΠΈΡΡΠ΅ΠΌΠΎΡ BPF ΠΏΠΎΠ΄Π΅ΡΠ°Π»Π½ΠΎ.
ΠΠΈΠ³ΡΠ΅ΡΠΈΡΠ°: ΠΊΠΎΠΌΡΠ½Π°Π»Π½ΠΈ ΡΡΠ»ΡΠ³ΠΈ
ΠΠ° Π΄Π° ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° Π³ΠΈ ΠΈΠ·Π²ΡΡΠΈΡΠ΅ ΠΏΡΠΈΠΌΠ΅ΡΠΈΡΠ΅ Π²ΠΎ ΡΠ»Π΅Π΄Π½ΠΈΡΠ΅ Π΄Π΅Π»ΠΎΠ²ΠΈ, ΠΌΠΎΠΆΠ΅Π±ΠΈ ΡΠ΅ Π²ΠΈ ΡΡΠ΅Π±Π°Π°Ρ Π³ΠΎΠ»Π΅ΠΌ Π±ΡΠΎΡ ΠΊΠΎΠΌΡΠ½Π°Π»Π½ΠΈ ΡΡΠ»ΡΠ³ΠΈ, Π±Π°ΡΠ΅ΠΌ llvm/clang ΡΠΎ ΠΏΠΎΠ΄Π΄ΡΡΠΊΠ° Π½Π° bpf ΠΈ bpftool. ΠΠΎ Π΄Π΅Π»ΠΎΡ ΠΠΎΠΆΠ΅ΡΠ΅ Π΄Π° Π³ΠΈ ΠΏΡΠΎΡΠΈΡΠ°ΡΠ΅ ΡΠΏΠ°ΡΡΡΠ²Π°ΡΠ° Π·Π° ΡΠΎΡΡΠ°Π²ΡΠ²Π°ΡΠ΅ Π½Π° ΠΊΠΎΠΌΡΠ½Π°Π»Π½ΠΈΡΠ΅ ΡΡΠ»ΡΠ³ΠΈ, ΠΊΠ°ΠΊΠΎ ΠΈ Π²Π°ΡΠΈΠΎΡ ΠΊΠ΅ΡΠ½Π΅Π». ΠΠ²ΠΎΡ Π΄Π΅Π» Π΅ ΠΏΠΎΡΡΠ°Π²Π΅Π½ ΠΏΠΎΠ΄ΠΎΠ»Ρ Π·Π° Π΄Π° Π½Π΅ ΡΠ΅ Π½Π°ΡΡΡΠΈ Ρ
Π°ΡΠΌΠΎΠ½ΠΈΡΠ°ΡΠ° Π½Π° Π½Π°ΡΠ°ΡΠ° ΠΏΡΠ΅Π·Π΅Π½ΡΠ°ΡΠΈΡΠ°.
BPF ΡΠ΅Π³ΠΈΡΡΡΠΈ Π½Π° Π²ΠΈΡΡΡΠ΅Π»Π½Π° ΠΌΠ°ΡΠΈΠ½Π° ΠΈ ΡΠΈΡΡΠ΅ΠΌ Π·Π° ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈ
ΠΡΡ ΠΈΡΠ΅ΠΊΡΡΡΠ°ΡΠ° ΠΈ ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΈΠΎΡ ΡΠΈΡΡΠ΅ΠΌ Π½Π° BPF Π±Π΅Π° ΡΠ°Π·Π²ΠΈΠ΅Π½ΠΈ Π·Π΅ΠΌΠ°ΡΡΠΈ Π³ΠΎ ΠΏΡΠ΅Π΄Π²ΠΈΠ΄ ΡΠ°ΠΊΡΠΎΡ Π΄Π΅ΠΊΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ΅ ΡΠ΅ Π±ΠΈΠ΄Π°Ρ Π½Π°ΠΏΠΈΡΠ°Π½ΠΈ Π½Π° ΡΠ°Π·ΠΈΠΊΠΎΡ C ΠΈ, ΠΏΠΎ Π²ΡΠΈΡΡΠ²Π°ΡΠ΅ΡΠΎ Π²ΠΎ ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ, ΠΏΡΠ΅Π²Π΅Π΄Π΅Π½ΠΈ Π²ΠΎ ΠΌΠ°ΡΡΠΈΠ½ ΠΊΠΎΠ΄. ΠΠ°ΡΠΎΠ°, Π±ΡΠΎΡΠΎΡ Π½Π° ΡΠ΅Π³ΠΈΡΡΡΠΈ ΠΈ ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²ΠΎΡΠΎ Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ Π±Π΅Π° ΠΈΠ·Π±ΡΠ°Π½ΠΈ ΡΠΎ ΠΎΠΊΠΎ Π½Π° ΠΏΡΠ΅ΡΠ΅ΠΊΠΎΡ, Π²ΠΎ ΠΌΠ°ΡΠ΅ΠΌΠ°ΡΠΈΡΠΊΠ° ΡΠΌΠΈΡΠ»Π°, Π½Π° ΠΌΠΎΠΆΠ½ΠΎΡΡΠΈΡΠ΅ Π½Π° ΡΠΎΠ²ΡΠ΅ΠΌΠ΅Π½ΠΈΡΠ΅ ΠΌΠ°ΡΠΈΠ½ΠΈ. ΠΠΎΠΊΡΠ°Ρ ΡΠΎΠ°, Π±Π΅Π° Π½Π°ΠΌΠ΅ΡΠ½Π°ΡΠΈ ΡΠ°Π·Π»ΠΈΡΠ½ΠΈ ΠΎΠ³ΡΠ°Π½ΠΈΡΡΠ²Π°ΡΠ° Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ΅, Π½Π° ΠΏΡΠΈΠΌΠ΅Ρ, Π΄ΠΎ Π½Π΅ΠΎΠ΄Π°ΠΌΠ½Π° Π½Π΅ Π±Π΅ΡΠ΅ ΠΌΠΎΠΆΠ½ΠΎ Π΄Π° ΡΠ΅ ΠΏΠΈΡΡΠ²Π°Π°Ρ ΡΠΈΠΊΠ»ΡΡΠΈ ΠΈ ΠΏΠΎΡΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ, Π° Π±ΡΠΎΡΠΎΡ Π½Π° ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈ Π±Π΅ΡΠ΅ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ Π½Π° 4096 (ΡΠ΅Π³Π° ΠΏΡΠΈΠ²ΠΈΠ»Π΅Π³ΠΈΡΠ°Π½ΠΈΡΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ ΠΌΠΎΠΆΠ°Ρ Π΄Π° Π²ΡΠΈΡΠ°Π°Ρ Π΄ΠΎ ΠΌΠΈΠ»ΠΈΠΎΠ½ ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈ).
BPF ΠΈΠΌΠ° Π΅Π΄ΠΈΠ½Π°Π΅ΡΠ΅Ρ 64-Π±ΠΈΡΠ½ΠΈ ΡΠ΅Π³ΠΈΡΡΡΠΈ Π΄ΠΎΡΡΠ°ΠΏΠ½ΠΈ Π·Π° ΠΊΠΎΡΠΈΡΠ½ΠΈΠΊΠΎΡ r0-r10 ΠΈ ΠΏΡΠΎΠ³ΡΠ°ΠΌΡΠΊΠΈ Π±ΡΠΎΡΠ°Ρ. Π Π΅Π³ΠΈΡΡΡΠΈΡΠ°ΡΡΠ΅ ΡΠ΅ r10 ΡΠΎΠ΄ΡΠΆΠΈ ΠΏΠΎΠΊΠ°ΠΆΡΠ²Π°Ρ Π½Π° ΡΠ°ΠΌΠΊΠ° ΠΈ Π΅ ΡΠ°ΠΌΠΎ Π·Π° ΡΠΈΡΠ°ΡΠ΅. ΠΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ΅ ΠΈΠΌΠ°Π°Ρ ΠΏΡΠΈΡΡΠ°ΠΏ Π΄ΠΎ ΡΡΠ΅ΠΊ ΠΎΠ΄ 512 Π±Π°ΡΡΠΈ ΠΏΡΠΈ ΠΈΠ·Π²ΡΡΡΠ²Π°ΡΠ΅ ΠΈ Π½Π΅ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½Π° ΠΊΠΎΠ»ΠΈΡΠΈΠ½Π° Π½Π° ΡΠΏΠΎΠ΄Π΅Π»Π΅Π½Π° ΠΌΠ΅ΠΌΠΎΡΠΈΡΠ° Π²ΠΎ ΡΠΎΡΠΌΠ° Π½Π° ΠΌΠ°ΠΏΠΈ.
ΠΠ° BPF ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ΅ ΠΈΠΌ Π΅ Π΄ΠΎΠ·Π²ΠΎΠ»Π΅Π½ΠΎ Π΄Π° ΠΈΠ·Π²ΡΡΡΠ²Π°Π°Ρ ΡΠΏΠ΅ΡΠΈΡΠΈΡΠ΅Π½ ΡΠ΅Ρ Π½Π° ΠΏΠΎΠΌΠΎΡΠ½ΠΈΡΠΈ Π½Π° ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ ΠΎΠ΄ ΡΠΈΠΏΠΎΡ Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° ΠΈ, ΠΎΠ΄ Π½Π΅ΠΎΠ΄Π°ΠΌΠ½Π°, ΡΠ΅Π΄ΠΎΠ²Π½ΠΈ ΡΡΠ½ΠΊΡΠΈΠΈ. Π‘Π΅ΠΊΠΎΡΠ° ΠΏΠΎΠ²ΠΈΠΊΠ°Π½Π° ΡΡΠ½ΠΊΡΠΈΡΠ° ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΏΠΎΡΡΠ°Π΅ Π΄ΠΎ ΠΏΠ΅Ρ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠΈ, ΠΏΡΠ΅Π½Π΅ΡΠ΅Π½ΠΈ Π²ΠΎ ΡΠ΅Π³ΠΈΡΡΡΠΈ r1-r5, Π° ΠΏΠΎΠ²ΡΠ°ΡΠ½Π°ΡΠ° Π²ΡΠ΅Π΄Π½ΠΎΡΡ ΡΠ΅ ΠΏΡΠ΅Π½Π΅ΡΡΠ²Π° Π½Π° r0. Π‘Π΅ Π³Π°ΡΠ°Π½ΡΠΈΡΠ° Π΄Π΅ΠΊΠ° ΠΏΠΎ Π²ΡΠ°ΡΠ°ΡΠ΅ΡΠΎ ΠΎΠ΄ ΡΡΠ½ΠΊΡΠΈΡΠ°ΡΠ° ΡΠΎΠ΄ΡΠΆΠΈΠ½Π°ΡΠ° Π½Π° ΡΠ΅Π³ΠΈΡΡΡΠΈΡΠ΅ r6-r9 ΠΠ΅ΠΌΠ° Π΄Π° ΡΠ΅ ΠΏΡΠΎΠΌΠ΅Π½ΠΈ.
ΠΠ° Π΅ΡΠΈΠΊΠ°ΡΠ½ΠΎ ΠΏΡΠ΅Π²Π΅Π΄ΡΠ²Π°ΡΠ΅ Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ°, ΡΠ΅Π³ΠΈΡΡΡΠΈ r0-r11 Π·Π° ΡΠΈΡΠ΅ ΠΏΠΎΠ΄Π΄ΡΠΆΠ°Π½ΠΈ Π°ΡΡ
ΠΈΡΠ΅ΠΊΡΡΡΠΈ ΡΠ΅ ΡΠ½ΠΈΠΊΠ°ΡΠ½ΠΎ ΠΌΠ°ΠΏΠΈΡΠ°Π½ΠΈ Π½Π° Π²ΠΈΡΡΠΈΠ½ΡΠΊΠΈ ΡΠ΅Π³ΠΈΡΡΡΠΈ, Π·Π΅ΠΌΠ°ΡΡΠΈ Π³ΠΈ ΠΏΡΠ΅Π΄Π²ΠΈΠ΄ ΠΊΠ°ΡΠ°ΠΊΡΠ΅ΡΠΈΡΡΠΈΠΊΠΈΡΠ΅ Π½Π° ABI Π½Π° ΡΠ΅ΠΊΠΎΠ²Π½Π°ΡΠ° Π°ΡΡ
ΠΈΡΠ΅ΠΊΡΡΡΠ°. ΠΠ° ΠΏΡΠΈΠΌΠ΅Ρ, Π·Π° x86_64 ΡΠ΅Π³ΠΈΡΡΡΠΈ r1-r5, ΡΡΠΎ ΡΠ΅ ΠΊΠΎΡΠΈΡΡΠΈ Π·Π° ΠΏΡΠ΅Π½Π΅ΡΡΠ²Π°ΡΠ΅ Π½Π° ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΈΡΠ΅ Π½Π° ΡΡΠ½ΠΊΡΠΈΡΠ°ΡΠ°, ΡΠ΅ ΠΏΡΠΈΠΊΠ°ΠΆΡΠ²Π°Π°Ρ Π²ΠΊΠ»ΡΡΠ΅Π½ΠΎ rdi, rsi, rdx, rcx, r8, ΠΊΠΎΠΈ ΡΠ΅ ΠΊΠΎΡΠΈΡΡΠ°Ρ Π·Π° ΠΏΡΠ΅Π½Π΅ΡΡΠ²Π°ΡΠ΅ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΈ Π½Π° ΡΡΠ½ΠΊΡΠΈΠΈΡΠ΅ Π²ΠΊΠ»ΡΡΠ΅Π½ΠΈ x86_64. ΠΠ° ΠΏΡΠΈΠΌΠ΅Ρ, ΠΊΠΎΠ΄ΠΎΡ Π»Π΅Π²ΠΎ ΡΠ΅ ΠΏΡΠ΅Π²Π΅Π΄ΡΠ²Π° Π½Π° ΠΊΠΎΠ΄ΠΎΡ ΠΎΠ΄ Π΄Π΅ΡΠ½Π°ΡΠ° ΡΡΡΠ°Π½Π° Π²Π°ΠΊΠ°:
1: (b7) r1 = 1 mov $0x1,%rdi
2: (b7) r2 = 2 mov $0x2,%rsi
3: (b7) r3 = 3 mov $0x3,%rdx
4: (b7) r4 = 4 mov $0x4,%rcx
5: (b7) r5 = 5 mov $0x5,%r8
6: (85) call pc+1 callq 0x0000000000001ee8Π Π΅Π³ΠΈΡΡΡΠΈΡΠ°Ρ ΡΠ΅ r0 ΠΈΡΡΠΎ ΡΠ°ΠΊΠ° ΡΠ΅ ΠΊΠΎΡΠΈΡΡΠΈ Π·Π° Π²ΡΠ°ΡΠ°ΡΠ΅ Π½Π° ΡΠ΅Π·ΡΠ»ΡΠ°ΡΠΎΡ ΠΎΠ΄ ΠΈΠ·Π²ΡΡΡΠ²Π°ΡΠ΅ΡΠΎ Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° ΠΈ Π²ΠΎ ΡΠ΅Π³ΠΈΡΡΠ°ΡΠΎΡ r1 Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° ΡΠ΅ ΠΏΡΠ΅Π½Π΅ΡΡΠ²Π° ΠΏΠΎΠΊΠ°ΠΆΡΠ²Π°Ρ ΠΊΠΎΠ½ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠΎΡ - Π²ΠΎ Π·Π°Π²ΠΈΡΠ½ΠΎΡΡ ΠΎΠ΄ Π²ΠΈΠ΄ΠΎΡ Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ°, ΠΎΠ²Π° ΠΌΠΎΠΆΠ΅ Π΄Π° Π±ΠΈΠ΄Π΅, Π½Π° ΠΏΡΠΈΠΌΠ΅Ρ, ΡΡΡΡΠΊΡΡΡΠ° (Π·Π° XDP) ΠΈΠ»ΠΈ ΡΡΡΡΠΊΡΡΡΠ° (Π·Π° ΡΠ°Π·Π»ΠΈΡΠ½ΠΈ ΠΌΡΠ΅ΠΆΠ½ΠΈ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ) ΠΈΠ»ΠΈ ΡΡΡΡΠΊΡΡΡΠ° (Π·Π° ΡΠ°Π·Π»ΠΈΡΠ½ΠΈ Π²ΠΈΠ΄ΠΎΠ²ΠΈ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ Π·Π° ΡΠ»Π΅Π΄Π΅ΡΠ΅) ΠΈΡΠ½.
ΠΠ½Π°ΡΠΈ, ΠΈΠΌΠ°Π²ΠΌΠ΅ ΡΠ΅Ρ Π½Π° ΡΠ΅Π³ΠΈΡΡΡΠΈ, ΠΏΠΎΠΌΠΎΡΠ½ΠΈΡΠΈ Π½Π° ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ, ΡΡΠ΅ΠΊ, ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΡΠ°Π»Π΅Π½ ΠΏΠΎΠΊΠ°ΠΆΡΠ²Π°Ρ ΠΈ ΡΠΏΠΎΠ΄Π΅Π»Π΅Π½Π° ΠΌΠ΅ΠΌΠΎΡΠΈΡΠ° Π²ΠΎ ΡΠΎΡΠΌΠ° Π½Π° ΠΌΠ°ΠΏΠΈ. ΠΠ΅ Π΄Π΅ΠΊΠ° ΡΠ΅ΡΠΎ ΡΠΎΠ° Π΅ Π°ΠΏΡΠΎΠ»ΡΡΠ½ΠΎ Π½Π΅ΠΎΠΏΡ ΠΎΠ΄Π½ΠΎ Π½Π° ΠΏΠ°ΡΡΠ²Π°ΡΠ΅ΡΠΎ, Π½ΠΎ...
ΠΡΠ΄Π΅ Π΄Π° Π³ΠΎ ΠΏΡΠΎΠ΄ΠΎΠ»ΠΆΠΈΠΌΠ΅ ΠΎΠΏΠΈΡΠΎΡ ΠΈ Π΄Π° ΡΠ°Π·Π³ΠΎΠ²Π°ΡΠ°ΠΌΠ΅ Π·Π° ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΈΠΎΡ ΡΠΈΡΡΠ΅ΠΌ Π·Π° ΡΠ°Π±ΠΎΡΠ° ΡΠΎ ΠΎΠ²ΠΈΠ΅ ΠΎΠ±ΡΠ΅ΠΊΡΠΈ. Π‘ΠΈΡΠ΅ () ΠΠ½ΡΡΡΡΠΊΡΠΈΠΈΡΠ΅ Π·Π° BPF ΠΈΠΌΠ°Π°Ρ ΡΠΈΠΊΡΠ½Π° 64-Π±ΠΈΡΠ½Π° Π³ΠΎΠ»Π΅ΠΌΠΈΠ½Π°. ΠΠΊΠΎ ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΡΠ΅ Π΅Π΄Π½Π° ΠΈΠ½ΡΡΡΡΠΊΡΠΈΡΠ° Π½Π° 64-Π±ΠΈΡΠ½Π° Big Endian ΠΌΠ°ΡΠΈΠ½Π°, ΡΠ΅ Π²ΠΈΠ΄ΠΈΡΠ΅
![]()
Π’ΡΠΊΠ° Code - ΠΎΠ²Π° Π΅ ΠΊΠΎΠ΄ΠΈΡΠ°ΡΠ΅ Π½Π° ΠΈΠ½ΡΡΡΡΠΊΡΠΈΡΠ°ΡΠ°, Dst/Src ΡΠ΅ ΡΠΈΡΡΠΈΡΠ°ΡΠ°ΡΠ° Π½Π° ΠΏΡΠΈΠΌΠ°ΡΠΎΡ ΠΈ ΠΈΠ·Π²ΠΎΡΠΎΡ, ΡΠΎΠΎΠ΄Π²Π΅ΡΠ½ΠΎ, Off - 16-Π±ΠΈΡΠ½Π° ΠΏΠΎΡΠΏΠΈΡΠ°Π½Π° Π²ΠΎΠ²Π»Π΅ΠΊΡΠ²Π°ΡΠ΅ ΠΈ Imm Π΅ 32-Π±ΠΈΡΠ΅Π½ ΠΏΠΎΡΠΏΠΈΡΠ°Π½ ΡΠ΅Π» Π±ΡΠΎΡ ΠΊΠΎΡ ΡΠ΅ ΠΊΠΎΡΠΈΡΡΠΈ Π²ΠΎ Π½Π΅ΠΊΠΎΠΈ ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈ (ΡΠ»ΠΈΡΠ½ΠΎ Π½Π° cBPF ΠΊΠΎΠ½ΡΡΠ°Π½ΡΠ°ΡΠ° K). ΠΠΎΠ΄ΠΈΡΠ°ΡΠ΅ Code ΠΈΠΌΠ° Π΅Π΄Π΅Π½ ΠΎΠ΄ Π΄Π²Π°ΡΠ° Π²ΠΈΠ΄Π°:

ΠΠ»Π°ΡΠΈΡΠ΅ Π½Π° ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈ 0, 1, 2, 3 Π΄Π΅ΡΠΈΠ½ΠΈΡΠ°Π°Ρ ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ Π·Π° ΡΠ°Π±ΠΎΡΠ° ΡΠΎ ΠΌΠ΅ΠΌΠΎΡΠΈΡΠ°. Π’ΠΈΠ΅ , BPF_LD, BPF_LDX, BPF_ST, BPF_STX, ΡΠΎΠΎΠ΄Π²Π΅ΡΠ½ΠΎ. ΠΠ»Π°ΡΠΈ 4, 7 (BPF_ALU, BPF_ALU64) ΡΠΎΡΠΈΠ½ΡΠ²Π°Π°Ρ Π·Π±ΠΈΡ Π½Π° ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈ ALU. ΠΠ»Π°ΡΠΈ 5, 6 (BPF_JMP, BPF_JMP32) ΡΠΎΠ΄ΡΠΆΠΈ ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈ Π·Π° ΡΠΊΠΎΠΊ.
ΠΠΎΠ½Π°ΡΠ°ΠΌΠΎΡΠ½ΠΈΠΎΡ ΠΏΠ»Π°Π½ Π·Π° ΠΏΡΠΎΡΡΡΠ²Π°ΡΠ΅ Π½Π° Π½Π°ΡΡΠ°Π²Π½ΠΈΠΎΡ ΡΠΈΡΡΠ΅ΠΌ BPF Π΅ ΠΊΠ°ΠΊΠΎ ΡΡΠΎ ΡΠ»Π΅Π΄ΡΠ²Π°: Π½Π°ΠΌΠ΅ΡΡΠΎ ΠΏΡΠ΅ΡΠΈΠ·Π½ΠΎ Π΄Π° Π³ΠΈ Π½Π°Π²Π΅Π΄Π΅ΠΌΠ΅ ΡΠΈΡΠ΅ ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈ ΠΈ Π½ΠΈΠ²Π½ΠΈΡΠ΅ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΈ, ΡΠ΅ ΡΠ°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ Π½Π΅ΠΊΠΎΠ»ΠΊΡ ΠΏΡΠΈΠΌΠ΅ΡΠΈ Π²ΠΎ ΠΎΠ²ΠΎΡ Π΄Π΅Π» ΠΈ ΠΎΠ΄ Π½ΠΈΠ² ΡΠ΅ ΡΡΠ°Π½Π΅ ΡΠ°ΡΠ½ΠΎ ΠΊΠ°ΠΊΠΎ Π²ΡΡΡΠ½ΠΎΡΡ ΡΡΠ½ΠΊΡΠΈΠΎΠ½ΠΈΡΠ°Π°Ρ ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈΡΠ΅ ΠΈ ΠΊΠ°ΠΊΠΎ Π΄Π° ΡΠ°ΡΠ½ΠΎ ΡΠ°ΡΠΊΠ»ΠΎΠΏΡΠ²Π°ΡΡΠ΅ ΠΊΠΎΡΠ° Π±ΠΈΠ»ΠΎ Π±ΠΈΠ½Π°ΡΠ½Π° Π΄Π°ΡΠΎΡΠ΅ΠΊΠ° Π·Π° BPF. ΠΠ° Π΄Π° Π³ΠΎ ΠΊΠΎΠ½ΡΠΎΠ»ΠΈΠ΄ΠΈΡΠ°ΠΌΠ΅ ΠΌΠ°ΡΠ΅ΡΠΈΡΠ°Π»ΠΎΡ ΠΏΠΎΠ΄ΠΎΡΠ½Π° Π²ΠΎ ΡΡΠ°ΡΠΈΡΠ°ΡΠ°, ΡΠ΅ ΡΠ΅ ΡΡΠ΅ΡΠ½Π΅ΠΌΠ΅ ΠΈ ΡΠΎ ΠΏΠΎΠ΅Π΄ΠΈΠ½Π΅ΡΠ½ΠΈ ΡΠΏΠ°ΡΡΡΠ²Π° Π²ΠΎ Π΄Π΅Π»ΠΎΠ²ΠΈΡΠ΅ Π·Π° Verifier, JIT ΠΊΠΎΠΌΠΏΠ°ΡΠ»Π΅Ρ, ΠΏΡΠ΅Π²ΠΎΠ΄ Π½Π° ΠΊΠ»Π°ΡΠΈΡΠ΅Π½ BPF, ΠΊΠ°ΠΊΠΎ ΠΈ ΠΏΡΠΈ ΠΏΡΠΎΡΡΡΠ²Π°ΡΠ΅ Π½Π° ΠΌΠ°ΠΏΠΈ, ΡΡΠ½ΠΊΡΠΈΠΈ Π·Π° ΠΏΠΎΠ²ΠΈΠΊΡΠ²Π°ΡΠ΅ ΠΈΡΠ½.
ΠΠΎΠ³Π° Π·Π±ΠΎΡΡΠ²Π°ΠΌΠ΅ Π·Π° ΠΏΠΎΠ΅Π΄ΠΈΠ½Π΅ΡΠ½ΠΈ ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈ, ΡΠ΅ ΡΠ΅ ΠΏΠΎΠ²ΠΈΠΊΠ°ΠΌΠ΅ Π½Π° ΠΎΡΠ½ΠΎΠ²Π½ΠΈΡΠ΅ Π΄Π°ΡΠΎΡΠ΅ΠΊΠΈ ΠΈ , ΠΊΠΎΠΈ Π³ΠΈ Π΄Π΅ΡΠΈΠ½ΠΈΡΠ°Π°Ρ Π½ΡΠΌΠ΅ΡΠΈΡΠΊΠΈΡΠ΅ ΠΊΠΎΠ΄ΠΎΠ²ΠΈ Π½Π° ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈΡΠ΅ Π½Π° BPF. ΠΠΎΠ³Π° ΡΠ°ΠΌΠΎΡΡΠΎΡΠ½ΠΎ ΡΠ° ΠΏΡΠΎΡΡΡΠ²Π°ΡΠ΅ Π°ΡΡ ΠΈΡΠ΅ΠΊΡΡΡΠ°ΡΠ° ΠΈ/ΠΈΠ»ΠΈ Π°Π½Π°Π»ΠΈΠ·ΠΈΡΠ°ΡΠ΅ Π±ΠΈΠ½Π°ΡΠ½ΠΈ Π΄Π°ΡΠΎΡΠ΅ΠΊΠΈ, ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° Π½Π°ΡΠ΄Π΅ΡΠ΅ ΡΠ΅ΠΌΠ°Π½ΡΠΈΠΊΠ° Π²ΠΎ ΡΠ»Π΅Π΄Π½ΠΈΡΠ΅ ΠΈΠ·Π²ΠΎΡΠΈ, ΠΏΠΎΠ΄ΡΠ΅Π΄Π΅Π½ΠΈ ΠΏΠΎ ΡΠ»ΠΎΠΆΠ΅Π½ΠΎΡΡ: , , ΠΈ, ΡΠ΅ΠΊΠ°ΠΊΠΎ, Π²ΠΎ ΠΈΠ·Π²ΠΎΡΠ½ΠΈΡΠ΅ ΠΊΠΎΠ΄ΠΎΠ²ΠΈ Linux β Π²Π΅ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ, JIT, BPF ΠΈΠ½ΡΠ΅ΡΠΏΡΠ΅ΡΠ΅Ρ.
ΠΡΠΈΠΌΠ΅Ρ: ΡΠ°ΡΠΊΠ»ΠΎΠΏΡΠ²Π°ΡΠ΅ Π½Π° BPF Π²ΠΎ Π²Π°ΡΠ°ΡΠ° Π³Π»Π°Π²Π°
ΠΡΠ΄Π΅ Π΄Π° ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ ΠΏΡΠΈΠΌΠ΅Ρ Π²ΠΎ ΠΊΠΎΡ ΡΠΎΡΡΠ°Π²ΡΠ²Π°ΠΌΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° readelf-example.c ΠΈ ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΡΠ΅ Π³ΠΎ Π΄ΠΎΠ±ΠΈΠ΅Π½ΠΈΠΎΡ Π±ΠΈΠ½Π°Ρ. ΠΠ΅ ΡΠ° ΠΎΡΠΊΡΠΈΠ΅ΠΌΠ΅ ΠΎΡΠΈΠ³ΠΈΠ½Π°Π»Π½Π°ΡΠ° ΡΠΎΠ΄ΡΠΆΠΈΠ½Π° readelf-example.c ΠΏΠΎΠ΄ΠΎΠ»Ρ, ΠΎΡΠΊΠ°ΠΊΠΎ ΡΠ΅ ΡΠ° Π²ΡΠ°ΡΠΈΠΌΠ΅ Π½Π΅Π³ΠΎΠ²Π°ΡΠ° Π»ΠΎΠ³ΠΈΠΊΠ° ΠΎΠ΄ Π±ΠΈΠ½Π°ΡΠ½ΠΈ ΠΊΠΎΠ΄ΠΎΠ²ΠΈ:
$ clang -target bpf -c readelf-example.c -o readelf-example.o -O2
$ llvm-readelf -x .text readelf-example.o
Hex dump of section '.text':
0x00000000 b7000000 01000000 15010100 00000000 ................
0x00000010 b7000000 02000000 95000000 00000000 ................ΠΡΠ²Π° ΠΊΠΎΠ»ΠΎΠ½Π° Π½Π° ΠΈΠ·Π»Π΅Π· readelf Π΅ Π²ΠΎΠ²Π»Π΅ΠΊΡΠ²Π°ΡΠ΅ ΠΈ Π·Π°ΡΠΎΠ° Π½Π°ΡΠ°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° ΡΠ΅ ΡΠΎΡΡΠΎΠΈ ΠΎΠ΄ ΡΠ΅ΡΠΈΡΠΈ ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ:
Code Dst Src Off Imm
b7 0 0 0000 01000000
15 0 1 0100 00000000
b7 0 0 0000 02000000
95 0 0 0000 00000000ΠΠΎΠΌΠ°Π½Π΄Π½ΠΈΡΠ΅ ΡΠΈΡΡΠΈ ΡΠ΅ Π΅Π΄Π½Π°ΠΊΠ²ΠΈ b7, 15, b7 ΠΈ 95. ΠΠΎΡΡΠ΅ΡΠ΅ΡΠ΅ ΡΠ΅ Π΄Π΅ΠΊΠ° Π½Π°ΡΠΌΠ°Π»ΠΊΡ Π·Π½Π°ΡΠ°ΡΠ½ΠΈΡΠ΅ ΡΡΠΈ Π±ΠΈΡΠ° ΡΠ΅ ΠΊΠ»Π°ΡΠ°ΡΠ° Π½Π° ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈ. ΠΠΎ Π½Π°ΡΠΈΠΎΡ ΡΠ»ΡΡΠ°Ρ, ΡΠ΅ΡΠ²ΡΡΠΈΠΎΡ Π±ΠΈΡ ΠΎΠ΄ ΡΠΈΡΠ΅ ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈ Π΅ ΠΏΡΠ°Π·Π΅Π½, ΡΠ°ΠΊΠ° ΡΡΠΎ ΠΊΠ»Π°ΡΠΈΡΠ΅ Π½Π° ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈ ΡΠ΅ 7, 5, 7, 5, ΡΠΎΠΎΠ΄Π²Π΅ΡΠ½ΠΎ. BPF_ALU64, Π° 5 Π΅ BPF_JMP. ΠΠ° Π΄Π²Π΅ΡΠ΅ ΠΊΠ»Π°ΡΠΈ, ΡΠΎΡΠΌΠ°ΡΠΎΡ Π½Π° ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈΡΠ΅ Π΅ ΠΈΡΡ (Π²ΠΈΠ΄ΠΈ ΠΏΠΎΠ³ΠΎΡΠ΅) ΠΈ ΠΌΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° ΡΠ° ΠΏΡΠ΅ΡΠ°Π±ΠΎΡΠΈΠΌΠ΅ Π½Π°ΡΠ°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° Π²Π°ΠΊΠ° (Π²ΠΎ ΠΈΡΡΠΎ Π²ΡΠ΅ΠΌΠ΅ ΡΠ΅ Π³ΠΈ ΠΏΡΠ΅ΡΠ°Π±ΠΎΡΠΈΠΌΠ΅ ΠΏΡΠ΅ΠΎΡΡΠ°Π½Π°ΡΠΈΡΠ΅ ΠΊΠΎΠ»ΠΎΠ½ΠΈ Π²ΠΎ ΡΠΎΠ²Π΅ΡΠΊΠ° ΡΠΎΡΠΌΠ°):
Op S Class Dst Src Off Imm
b 0 ALU64 0 0 0 1
1 0 JMP 0 1 1 0
b 0 ALU64 0 0 0 2
9 0 JMP 0 0 0 0ΠΠΏΠ΅ΡΠ°ΡΠΈΡΠ° b ΠΊΠ»Π°ΡΠ° ALU64 - ΠΠ°Π»ΠΈ . Π’ΠΎΡ ΠΌΡ Π΄ΠΎΠ΄Π΅Π»ΡΠ²Π° Π²ΡΠ΅Π΄Π½ΠΎΡΡ Π½Π° ΠΎΠ΄ΡΠ΅Π΄ΠΈΡΠ½ΠΈΠΎΡ ΡΠ΅Π³ΠΈΡΡΠ°Ρ. ΠΠΊΠΎ Π±ΠΈΡΠΎΡ Π΅ ΠΏΠΎΡΡΠ°Π²Π΅Π½ s (ΠΈΠ·Π²ΠΎΡ), ΡΠΎΠ³Π°Ρ Π²ΡΠ΅Π΄Π½ΠΎΡΡΠ° ΡΠ΅ Π·Π΅ΠΌΠ° ΠΎΠ΄ ΠΈΠ·Π²ΠΎΡΠ½ΠΈΠΎΡ ΡΠ΅Π³ΠΈΡΡΠ°Ρ, Π° Π°ΠΊΠΎ, ΠΊΠ°ΠΊΠΎ Π²ΠΎ Π½Π°ΡΠΈΠΎΡ ΡΠ»ΡΡΠ°Ρ, Π½Π΅ Π΅ ΠΏΠΎΡΡΠ°Π²Π΅Π½Π°, ΡΠΎΠ³Π°Ρ Π²ΡΠ΅Π΄Π½ΠΎΡΡΠ° ΡΠ΅ Π·Π΅ΠΌΠ° ΠΎΠ΄ ΠΏΠΎΠ»Π΅ΡΠΎ Imm. ΠΠ½Π°ΡΠΈ Π²ΠΎ ΠΏΡΠ²Π°ΡΠ° ΠΈ ΡΡΠ΅ΡΠ°ΡΠ° ΠΈΠ½ΡΡΡΡΠΊΡΠΈΡΠ° ΡΠ° ΠΈΠ·Π²ΡΡΡΠ²Π°ΠΌΠ΅ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΡΠ°ΡΠ° r0 = Imm. ΠΠΎΠ½Π°ΡΠ°ΠΌΡ, ΠΎΠΏΠ΅ΡΠ°ΡΠΈΡΠ°ΡΠ° JMP ΠΊΠ»Π°ΡΠ° 1 Π΅ (ΡΠΊΠΎΠΊ Π°ΠΊΠΎ Π΅ Π΅Π΄Π½Π°ΠΊΠΎΠ²). ΠΠΎ Π½Π°ΡΠΈΠΎΡ ΡΠ»ΡΡΠ°Ρ, ΠΎΠ΄ ΠΌΠ°Π»ΠΊΡ S Π΅ Π½ΡΠ»Π°, ΡΠ° ΡΠΏΠΎΡΠ΅Π΄ΡΠ²Π° Π²ΡΠ΅Π΄Π½ΠΎΡΡΠ° Π½Π° ΠΈΠ·Π²ΠΎΡΠ½ΠΈΠΎΡ ΡΠ΅Π³ΠΈΡΡΠ°Ρ ΡΠΎ ΠΏΠΎΠ»Π΅ΡΠΎ Imm. ΠΠΊΠΎ Π²ΡΠ΅Π΄Π½ΠΎΡΡΠΈΡΠ΅ ΡΠ΅ ΡΠΎΠ²ΠΏΠ°ΡΠ°Π°Ρ, ΡΠΎΠ³Π°Ρ ΡΠ΅ ΡΠ»ΡΡΡΠ²Π° ΡΡΠ°Π½Π·ΠΈΡΠΈΡΠ°ΡΠ° Π½Π° PC + OffΠΊΠ°Π΄Π΅ PC, ΠΊΠ°ΠΊΠΎ ΠΈ ΠΎΠ±ΠΈΡΠ½ΠΎ, ΡΠ° ΡΠΎΠ΄ΡΠΆΠΈ Π°Π΄ΡΠ΅ΡΠ°ΡΠ° Π½Π° ΡΠ»Π΅Π΄Π½Π°ΡΠ° ΠΈΠ½ΡΡΡΡΠΊΡΠΈΡΠ°. ΠΠΎΠ½Π΅ΡΠ½ΠΎ, JMP ΠΠ»Π°ΡΠ° 9 ΠΎΠΏΠ΅ΡΠ°ΡΠΈΡΠ° Π΅ . ΠΠ²Π°Π° ΠΈΠ½ΡΡΡΡΠΊΡΠΈΡΠ° ΡΠ° ΠΏΡΠ΅ΠΊΠΈΠ½ΡΠ²Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ°, Π²ΡΠ°ΡΠ°ΡΡΠΈ ΡΠ΅ Π²ΠΎ ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ r0. ΠΡΠ΄Π΅ Π΄Π° Π΄ΠΎΠ΄Π°Π΄Π΅ΠΌΠ΅ Π½ΠΎΠ²Π° ΠΊΠΎΠ»ΠΎΠ½Π° Π½Π° Π½Π°ΡΠ°ΡΠ° ΡΠ°Π±Π΅Π»Π°:
Op S Class Dst Src Off Imm Disassm
MOV 0 ALU64 0 0 0 1 r0 = 1
JEQ 0 JMP 0 1 1 0 if (r1 == 0) goto pc+1
MOV 0 ALU64 0 0 0 2 r0 = 2
EXIT 0 JMP 0 0 0 0 exitΠΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° Π³ΠΎ ΠΏΡΠ΅ΡΠ°Π±ΠΎΡΠΈΠΌΠ΅ ΠΎΠ²Π° Π²ΠΎ ΠΏΠΎΠΏΠΎΠ³ΠΎΠ΄Π½Π° ΡΠΎΡΠΌΠ°:
r0 = 1
if (r1 == 0) goto END
r0 = 2
END:
exitΠΠΊΠΎ ΡΠ΅ ΡΠ΅ΡΠΈΠΌΠ΅ ΡΡΠΎ ΠΈΠΌΠ° Π²ΠΎ ΡΠ΅Π³ΠΈΡΡΠ°ΡΠΎΡ r1 Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° ΡΠ΅ ΠΏΡΠ΅Π½Π΅ΡΡΠ²Π° ΠΏΠΎΠΊΠ°ΠΆΡΠ²Π°Ρ ΠΊΠΎΠ½ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠΎΡ ΠΎΠ΄ ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ ΠΈ Π²ΠΎ ΡΠ΅Π³ΠΈΡΡΠ°ΡΠΎΡ r0 Π²ΡΠ΅Π΄Π½ΠΎΡΡΠ° ΡΠ΅ Π²ΡΠ°ΡΠ° Π²ΠΎ ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ, ΡΠΎΠ³Π°Ρ ΠΌΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° Π²ΠΈΠ΄ΠΈΠΌΠ΅ Π΄Π΅ΠΊΠ° Π°ΠΊΠΎ ΠΏΠΎΠΊΠ°ΠΆΡΠ²Π°ΡΠΎΡ Π½Π° ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠΎΡ Π΅ Π½ΡΠ»Π°, ΡΠΎΠ³Π°Ρ Π²ΡΠ°ΡΠ°ΠΌΠ΅ 1, Π° Π²ΠΎ ΡΠΏΡΠΎΡΠΈΠ²Π½ΠΎ - 2. ΠΡΠ΄Π΅ Π΄Π° ΠΏΡΠΎΠ²Π΅ΡΠΈΠΌΠ΅ Π΄Π°Π»ΠΈ ΡΠΌΠ΅ Π²ΠΎ ΠΏΡΠ°Π²ΠΎ Π³Π»Π΅Π΄Π°ΡΡΠΈ Π³ΠΎ ΠΈΠ·Π²ΠΎΡΠΎΡ:
$ cat readelf-example.c
int foo(void *ctx)
{
return ctx ? 2 : 1;
}ΠΠ°, ΡΠΎΠ° Π΅ Π±Π΅ΡΠΌΠΈΡΠ»Π΅Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°, Π½ΠΎ ΡΠ΅ ΠΏΡΠ΅Π²Π΅Π΄ΡΠ²Π° Π²ΠΎ ΡΠ°ΠΌΠΎ ΡΠ΅ΡΠΈΡΠΈ Π΅Π΄Π½ΠΎΡΡΠ°Π²Π½ΠΈ ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈ.
ΠΡΠΊΠ»ΡΡΠΎΠΊ ΠΏΡΠΈΠΌΠ΅Ρ: 16-Π±Π°ΡΡΠ½Π° ΠΈΠ½ΡΡΡΡΠΊΡΠΈΡΠ°
ΠΡΠ΅ΡΡ
ΠΎΠ΄Π½ΠΎ ΡΠΏΠΎΠΌΠ΅Π½Π°Π²ΠΌΠ΅ Π΄Π΅ΠΊΠ° Π½Π΅ΠΊΠΎΠΈ ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈ Π·Π°Π·Π΅ΠΌΠ°Π°Ρ ΠΏΠΎΠ²Π΅ΡΠ΅ ΠΎΠ΄ 64 Π±ΠΈΡΠ°. ΠΠ²Π° ΡΠ΅ ΠΎΠ΄Π½Π΅ΡΡΠ²Π°, Π½Π° ΠΏΡΠΈΠΌΠ΅Ρ, Π·Π° ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈΡΠ΅ lddw (Π¨ΠΈΡΡΠ° = 0x18 = | | ) β Π²ΡΠΈΡΠ°ΡΡΠ΅ Π΄Π²ΠΎΠ΅Π½ Π·Π±ΠΎΡ ΠΎΠ΄ ΠΏΠΎΠ»ΠΈΡΠ°ΡΠ° Π²ΠΎ ΡΠ΅Π³ΠΈΡΡΠ°ΡΠΎΡ Imm. Π€Π°ΠΊΡ Π΅ Π΄Π΅ΠΊΠ° Imm ΠΈΠΌΠ° Π³ΠΎΠ»Π΅ΠΌΠΈΠ½Π° ΠΎΠ΄ 32, Π° Π΄Π²ΠΎΠ΅Π½ Π·Π±ΠΎΡ Π΅ 64 Π±ΠΈΡΠ°, ΡΠ°ΠΊΠ° ΡΡΠΎ Π²ΡΠΈΡΡΠ²Π°ΡΠ΅ΡΠΎ Π½Π° 64-Π±ΠΈΡΠ½Π° Π½Π΅ΠΏΠΎΡΡΠ΅Π΄Π½Π° Π²ΡΠ΅Π΄Π½ΠΎΡΡ Π²ΠΎ ΡΠ΅Π³ΠΈΡΡΠ°ΡΠΎΡ Π²ΠΎ Π΅Π΄Π½Π° 64-Π±ΠΈΡΠ½Π° ΠΈΠ½ΡΡΡΡΠΊΡΠΈΡΠ° Π½Π΅ΠΌΠ° Π΄Π° ΡΠ°Π±ΠΎΡΠΈ. ΠΠ° Π΄Π° Π³ΠΎ Π½Π°ΠΏΡΠ°Π²ΠΈΡΠ΅ ΠΎΠ²Π°, Π΄Π²Π΅ ΡΠΎΡΠ΅Π΄Π½ΠΈ ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈ ΡΠ΅ ΠΊΠΎΡΠΈΡΡΠ°Ρ Π·Π° ΡΠΊΠ»Π°Π΄ΠΈΡΠ°ΡΠ΅ Π½Π° Π²ΡΠΎΡΠΈΠΎΡ Π΄Π΅Π» ΠΎΠ΄ 64-Π±ΠΈΡΠ½Π°ΡΠ° Π²ΡΠ΅Π΄Π½ΠΎΡΡ Π²ΠΎ ΠΏΠΎΠ»Π΅ΡΠΎ Imm... ΠΡΠΈΠΌΠ΅Ρ:
$ cat x64.c
long foo(void *ctx)
{
return 0x11223344aabbccdd;
}
$ clang -target bpf -c x64.c -o x64.o -O2
$ llvm-readelf -x .text x64.o
Hex dump of section '.text':
0x00000000 18000000 ddccbbaa 00000000 44332211 ............D3".
0x00000010 95000000 00000000 ........ΠΠΎ Π±ΠΈΠ½Π°ΡΠ½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° ΠΈΠΌΠ° ΡΠ°ΠΌΠΎ Π΄Π²Π΅ ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈ:
Binary Disassm
18000000 ddccbbaa 00000000 44332211 r0 = Imm[0]|Imm[1]
95000000 00000000 exitΠΠ΅ ΡΠ΅ ΡΡΠ΅ΡΠ½Π΅ΠΌΠ΅ ΠΏΠΎΠ²ΡΠΎΡΠ½ΠΎ ΡΠΎ ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈ lddw, ΠΊΠΎΠ³Π° Π·Π±ΠΎΡΡΠ²Π°ΠΌΠ΅ Π·Π° ΠΏΡΠ΅ΡΠ΅Π»Π±ΠΈ ΠΈ ΡΠ°Π±ΠΎΡΠ° ΡΠΎ ΠΌΠ°ΠΏΠΈ.
ΠΡΠΈΠΌΠ΅Ρ: ΡΠ°ΡΠΊΠ»ΠΎΠΏΡΠ²Π°ΡΠ΅ Π½Π° BPF ΡΠΎ ΠΏΠΎΠΌΠΎΡ Π½Π° ΡΡΠ°Π½Π΄Π°ΡΠ΄Π½ΠΈ Π°Π»Π°ΡΠΊΠΈ
ΠΠ½Π°ΡΠΈ, Π½Π°ΡΡΠΈΠ²ΠΌΠ΅ Π΄Π° ΡΠΈΡΠ°ΠΌΠ΅ BPF Π±ΠΈΠ½Π°ΡΠ½ΠΈ ΠΊΠΎΠ΄ΠΎΠ²ΠΈ ΠΈ ΠΏΠΎΠ΄Π³ΠΎΡΠ²Π΅Π½ΠΈ ΡΠΌΠ΅ Π΄Π° Π³ΠΈ Π°Π½Π°Π»ΠΈΠ·ΠΈΡΠ°ΠΌΠ΅ ΡΠΈΡΠ΅ ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈ Π΄ΠΎΠΊΠΎΠ»ΠΊΡ Π΅ ΠΏΠΎΡΡΠ΅Π±Π½ΠΎ. Π‘Π΅ΠΏΠ°ΠΊ, Π²ΡΠ΅Π΄ΠΈ Π΄Π° ΡΠ΅ ΠΊΠ°ΠΆΠ΅ Π΄Π΅ΠΊΠ° Π²ΠΎ ΠΏΡΠ°ΠΊΡΠ° Π΅ ΠΏΠΎΡΠ΄ΠΎΠ±Π½ΠΎ ΠΈ ΠΏΠΎΠ±ΡΠ·ΠΎ Π΄Π° ΡΠ΅ ΡΠ°ΡΠΊΠ»ΠΎΠΏΠ°Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ΅ ΠΊΠΎΡΠΈΡΡΠ΅ΡΡΠΈ ΡΡΠ°Π½Π΄Π°ΡΠ΄Π½ΠΈ Π°Π»Π°ΡΠΊΠΈ, Π½Π° ΠΏΡΠΈΠΌΠ΅Ρ:
$ llvm-objdump -d x64.o
Disassembly of section .text:
0000000000000000 <foo>:
0: 18 00 00 00 dd cc bb aa 00 00 00 00 44 33 22 11 r0 = 1234605617868164317 ll
2: 95 00 00 00 00 00 00 00 exitΠΠΈΠ²ΠΎΡΠ½ΠΈΠΎΡ ΡΠΈΠΊΠ»ΡΡ Π½Π° ΠΎΠ±ΡΠ΅ΠΊΡΠΈΡΠ΅ BPF, Π΄Π°ΡΠΎΡΠ΅ΡΠ΅Π½ ΡΠΈΡΡΠ΅ΠΌ bpffs
(ΠΡΠ²ΠΎ Π½Π°ΡΡΠΈΠ² Π½Π΅ΠΊΠΎΠΈ ΠΎΠ΄ Π΄Π΅ΡΠ°Π»ΠΈΡΠ΅ ΠΎΠΏΠΈΡΠ°Π½ΠΈ Π²ΠΎ ΠΎΠ²Π°Π° ΠΏΠΎΡΡΠ΅ΠΊΡΠΈΡΠ° ΠΎΠ΄ ΠΠ»Π΅ΠΊΡΠ΅Ρ Π‘ΡΠ°ΡΠΎΠ²ΠΎΠΈΡΠΎΠ² Π²ΠΎ .)
ΠΠ±ΡΠ΅ΠΊΡΠΈΡΠ΅ Π½Π° BPF - ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ ΠΈ ΠΌΠ°ΠΏΠΈ - ΡΠ΅ ΠΊΡΠ΅ΠΈΡΠ°Π°Ρ ΠΎΠ΄ ΠΊΠΎΡΠΈΡΠ½ΠΈΡΠΊΠΈΠΎΡ ΠΏΡΠΎΡΡΠΎΡ ΠΊΠΎΡΠΈΡΡΠ΅ΡΡΠΈ ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ BPF_PROG_LOAD ΠΈ BPF_MAP_CREATE ΡΠΈΡΡΠ΅ΠΌΡΠΊΠΈ ΠΏΠΎΠ²ΠΈΠΊ bpf(2), ΡΠ΅ Π·Π±ΠΎΡΡΠ²Π°ΠΌΠ΅ Π·Π° ΡΠΎΠ° ΠΊΠ°ΠΊΠΎ ΡΠΎΡΠ½ΠΎ ΡΠ΅ ΡΠ»ΡΡΡΠ²Π° ΠΎΠ²Π° Π²ΠΎ ΡΠ»Π΅Π΄Π½ΠΈΠΎΡ Π΄Π΅Π». ΠΠ²Π° ΡΠΎΠ·Π΄Π°Π²Π° ΡΡΡΡΠΊΡΡΡΠΈ Π½Π° ΠΏΠΎΠ΄Π°ΡΠΎΡΠΈ Π½Π° ΡΠ°Π΄ΡΠΎΡΠΎ ΠΈ Π·Π° ΡΠ΅ΠΊΠΎΡΠ° ΠΎΠ΄ Π½ΠΈΠ² refcount (Π±ΡΠΎΡΠΎΡ Π½Π° ΡΠ΅ΡΠ΅ΡΠ΅Π½ΡΠΈ) Π΅ ΠΏΠΎΡΡΠ°Π²Π΅Π½ Π½Π° Π΅Π΄Π΅Π½, Π° Π΄Π΅ΡΠΊΡΠΈΠΏΡΠΎΡΠΎΡ Π½Π° Π΄Π°ΡΠΎΡΠ΅ΠΊΠ°ΡΠ° ΡΡΠΎ ΠΏΠΎΠΊΠ°ΠΆΡΠ²Π° Π½Π° ΠΎΠ±ΡΠ΅ΠΊΡΠΎΡ ΡΠ΅ Π²ΡΠ°ΡΠ° Π½Π° ΠΊΠΎΡΠΈΡΠ½ΠΈΠΊΠΎΡ. ΠΡΠΊΠ°ΠΊΠΎ ΡΠ΅ ΡΠ΅ Π·Π°ΡΠ²ΠΎΡΠΈ ΡΠ°ΡΠΊΠ°ΡΠ° refcount ΠΎΠ±ΡΠ΅ΠΊΡΠΎΡ ΡΠ΅ Π½Π°ΠΌΠ°Π»ΡΠ²Π° Π·Π° Π΅Π΄Π΅Π½, Π° ΠΊΠΎΠ³Π° ΡΠ΅ Π΄ΠΎΡΡΠΈΠ³Π½Π΅ Π½ΡΠ»Π°, ΠΏΡΠ΅Π΄ΠΌΠ΅ΡΠΎΡ ΡΠ΅ ΡΠ½ΠΈΡΡΡΠ²Π°.
ΠΠΊΠΎ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° ΠΊΠΎΡΠΈΡΡΠΈ ΠΌΠ°ΠΏΠΈ, ΡΠΎΠ³Π°Ρ refcount ΠΎΠ²ΠΈΠ΅ ΠΊΠ°ΡΡΠΈ ΡΠ΅ Π·Π³ΠΎΠ»Π΅ΠΌΡΠ²Π°Π°Ρ Π·Π° Π΅Π΄Π΅Π½ ΠΏΠΎ Π²ΡΠΈΡΡΠ²Π°ΡΠ΅ΡΠΎ Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ°, Ρ.Π΅. Π½ΠΈΠ²Π½ΠΈΡΠ΅ Π΄Π΅ΡΠΊΡΠΈΠΏΡΠΎΡΠΈ Π½Π° Π΄Π°ΡΠΎΡΠ΅ΠΊΠΈ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ Π·Π°ΡΠ²ΠΎΡΠ°Ρ ΠΎΠ΄ ΠΊΠΎΡΠΈΡΠ½ΠΈΡΠΊΠΈΠΎΡ ΠΏΡΠΎΡΠ΅Ρ ΠΈ ΡΡΡΠ΅ refcount Π½Π΅ΠΌΠ° Π΄Π° ΡΡΠ°Π½Π΅ Π½ΡΠ»Π°:

ΠΠΎ ΡΡΠΏΠ΅ΡΠ½ΠΎΡΠΎ Π²ΡΠΈΡΡΠ²Π°ΡΠ΅ Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ°, ΠΎΠ±ΠΈΡΠ½ΠΎ ΡΠ° ΠΏΡΠΈΠΊΠ°ΡΡΠ²Π°ΠΌΠ΅ Π½Π° Π½Π΅ΠΊΠΎΡ Π²ΠΈΠ΄ Π³Π΅Π½Π΅ΡΠ°ΡΠΎΡ Π½Π° Π½Π°ΡΡΠ°Π½ΠΈ. ΠΠ° ΠΏΡΠΈΠΌΠ΅Ρ, ΠΌΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° Π³ΠΎ ΡΡΠ°Π²ΠΈΠΌΠ΅ Π½Π° ΠΌΡΠ΅ΠΆΠ΅Π½ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΡΡ Π·Π° Π΄Π° Π³ΠΈ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΈΠΌΠ΅ Π΄ΠΎΡΠ΄ΠΎΠ²Π½ΠΈΡΠ΅ ΠΏΠ°ΠΊΠ΅ΡΠΈ ΠΈΠ»ΠΈ Π΄Π° Π³ΠΎ ΠΏΠΎΠ²ΡΠ·Π΅ΠΌΠ΅ ΡΠΎ Π½Π΅ΠΊΠΎΠΈ tracepoint Π²ΠΎ ΡΠ°Π΄ΡΠΎΡΠΎ. ΠΠΎ ΠΎΠ²ΠΎΡ ΠΌΠΎΠΌΠ΅Π½Ρ, ΡΠ΅ΡΠ΅ΡΠ΅Π½ΡΠ½ΠΈΠΎΡ Π±ΡΠΎΡΠ°Ρ ΠΈΡΡΠΎ ΡΠ°ΠΊΠ° ΡΠ΅ ΡΠ΅ Π·Π³ΠΎΠ»Π΅ΠΌΠΈ Π·Π° Π΅Π΄Π΅Π½ ΠΈ ΡΠ΅ ΠΌΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° Π³ΠΎ Π·Π°ΡΠ²ΠΎΡΠΈΠΌΠ΅ Π΄Π΅ΡΠΊΡΠΈΠΏΡΠΎΡΠΎΡ Π½Π° Π΄Π°ΡΠΎΡΠ΅ΠΊΠ°ΡΠ° Π²ΠΎ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° Π·Π° Π²ΡΠΈΡΡΠ²Π°ΡΠ΅.
Π¨ΡΠΎ ΡΠ΅ ΡΠ΅ ΡΠ»ΡΡΠΈ Π°ΠΊΠΎ ΡΠ΅Π³Π° Π³ΠΎ ΠΈΡΠΊΠ»ΡΡΠΈΠΌΠ΅ ΠΏΠΎΠ΄ΠΈΠ³Π½ΡΠ²Π°ΡΠΎΡ? Π’ΠΎΠ° Π·Π°Π²ΠΈΡΠΈ ΠΎΠ΄ ΡΠΈΠΏΠΎΡ Π½Π° Π³Π΅Π½Π΅ΡΠ°ΡΠΎΡ Π½Π° Π½Π°ΡΡΠ°Π½ΠΈ (ΠΊΡΠΊΠ°). Π‘ΠΈΡΠ΅ ΠΌΡΠ΅ΠΆΠ½ΠΈ ΠΊΡΠΊΠΈ ΡΠ΅ ΠΏΠΎΡΡΠΎΡΠ°Ρ ΠΎΡΠΊΠ°ΠΊΠΎ ΡΠ΅ Π·Π°Π²ΡΡΠΈ Π½Π°ΡΠΎΠ²Π°ΡΡΠ²Π°ΡΠΎΡ, ΡΠΎΠ° ΡΠ΅ ΡΠ°ΠΊΠ°Π½Π°ΡΠ΅ΡΠ΅Π½ΠΈΡΠ΅ Π³Π»ΠΎΠ±Π°Π»Π½ΠΈ ΠΊΡΠΊΠΈ. Π, Π½Π° ΠΏΡΠΈΠΌΠ΅Ρ, ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ΅ Π·Π° ΡΡΠ°Π³Π° ΡΠ΅ Π±ΠΈΠ΄Π°Ρ ΠΎΠ±ΡΠ°Π²Π΅Π½ΠΈ ΠΎΡΠΊΠ°ΠΊΠΎ ΡΠ΅ Π·Π°Π²ΡΡΠΈ ΠΏΡΠΎΡΠ΅ΡΠΎΡ ΡΡΠΎ Π³ΠΈ ΡΠΎΠ·Π΄Π°Π» (ΠΈ Π·Π°ΡΠΎΠ° ΡΠ΅ Π½Π°ΡΠ΅ΠΊΡΠ²Π°Π°Ρ Π»ΠΎΠΊΠ°Π»Π½ΠΈ, ΠΎΠ΄ βΠ»ΠΎΠΊΠ°Π»Π½ΠΎ Π²ΠΎ ΠΏΡΠΎΡΠ΅Ρβ). Π’Π΅Ρ Π½ΠΈΡΠΊΠΈ, Π»ΠΎΠΊΠ°Π»Π½ΠΈΡΠ΅ ΠΊΡΠΊΠΈ ΡΠ΅ΠΊΠΎΠ³Π°Ρ ΠΈΠΌΠ°Π°Ρ ΡΠΎΠΎΠ΄Π²Π΅ΡΠ΅Π½ Π΄Π΅ΡΠΊΡΠΈΠΏΡΠΎΡ Π½Π° Π΄Π°ΡΠΎΡΠ΅ΠΊΠ° Π²ΠΎ ΠΊΠΎΡΠΈΡΠ½ΠΈΡΠΊΠΈΠΎΡ ΠΏΡΠΎΡΡΠΎΡ ΠΈ Π·Π°ΡΠΎΠ° ΡΠ΅ Π·Π°ΡΠ²ΠΎΡΠ°Π°Ρ ΠΊΠΎΠ³Π° ΠΏΡΠΎΡΠ΅ΡΠΎΡ Π΅ Π·Π°ΡΠ²ΠΎΡΠ΅Π½, Π½ΠΎ Π³Π»ΠΎΠ±Π°Π»Π½ΠΈΡΠ΅ ΠΊΡΠΊΠΈ Π½Π΅ΠΌΠ°Π°Ρ. ΠΠ° ΡΠ»Π΅Π΄Π½Π°ΡΠ° ΡΠ»ΠΈΠΊΠ°, ΠΊΠΎΡΠΈΡΡΠ΅ΡΡΠΈ ΡΡΠ²Π΅Π½ΠΈ ΠΊΡΡΡΠΎΠ²ΠΈ, ΡΠ΅ ΠΎΠ±ΠΈΠ΄ΡΠ²Π°ΠΌ Π΄Π° ΠΏΠΎΠΊΠ°ΠΆΠ°ΠΌ ΠΊΠ°ΠΊΠΎ ΠΏΡΠ΅ΠΊΠΈΠ½ΡΠ²Π°ΡΠ΅ΡΠΎ Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° Π·Π° Π²ΡΠΈΡΡΠ²Π°ΡΠ΅ Π²Π»ΠΈΡΠ°Π΅ Π½Π° ΠΆΠΈΠ²ΠΎΡΠ½ΠΈΠΎΡ Π²Π΅ΠΊ Π½Π° ΠΎΠ±ΡΠ΅ΠΊΡΠΈΡΠ΅ Π²ΠΎ ΡΠ»ΡΡΠ°Ρ Π½Π° Π»ΠΎΠΊΠ°Π»Π½ΠΈ ΠΈ Π³Π»ΠΎΠ±Π°Π»Π½ΠΈ ΠΊΡΠΊΠΈ.

ΠΠΎΡΡΠΎ ΠΏΠΎΡΡΠΎΠΈ ΡΠ°Π·Π»ΠΈΠΊΠ° ΠΏΠΎΠΌΠ΅ΡΡ Π»ΠΎΠΊΠ°Π»Π½ΠΈ ΠΈ Π³Π»ΠΎΠ±Π°Π»Π½ΠΈ ΠΊΡΠΊΠΈ? ΠΠ·Π²ΡΡΡΠ²Π°ΡΠ΅ΡΠΎ Π½Π° Π½Π΅ΠΊΠΎΠΈ Π²ΠΈΠ΄ΠΎΠ²ΠΈ ΠΌΡΠ΅ΠΆΠ½ΠΈ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ ΠΈΠΌΠ° ΡΠΌΠΈΡΠ»Π° Π±Π΅Π· ΠΊΠΎΡΠΈΡΠ½ΠΈΡΠΊΠΈ ΠΏΡΠΎΡΡΠΎΡ, Π½Π° ΠΏΡΠΈΠΌΠ΅Ρ, Π·Π°ΠΌΠΈΡΠ»Π΅ΡΠ΅ Π·Π°ΡΡΠΈΡΠ° ΠΎΠ΄ DDoS - ΠΏΠΎΠ΄ΠΈΠ³Π½ΡΠ²Π°ΡΠΎΡ Π³ΠΈ ΠΏΠΈΡΡΠ²Π° ΠΏΡΠ°Π²ΠΈΠ»Π°ΡΠ° ΠΈ ΡΠ° ΠΏΠΎΠ²ΡΠ·ΡΠ²Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° BPF ΡΠΎ ΠΌΡΠ΅ΠΆΠ½ΠΈΠΎΡ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΡΡ, ΠΏΠΎ ΡΡΠΎ ΠΏΠΎΠ΄ΠΈΠ³Π½ΡΠ²Π°ΡΠΎΡ ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΎΠ΄ΠΈ ΠΈ Π΄Π° ΡΠ΅ ΡΠ±ΠΈΠ΅. ΠΠ΄ Π΄ΡΡΠ³Π° ΡΡΡΠ°Π½Π°, Π·Π°ΠΌΠΈΡΠ»Π΅ΡΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° Π·Π° ΡΡΠ°Π³Π° Π·Π° Π΄Π΅Π±Π°Π³ΠΈΡΠ°ΡΠ΅ ΡΡΠΎ ΡΡΠ΅ ΡΠ° Π½Π°ΠΏΠΈΡΠ°Π»Π΅ Π½Π° ΠΊΠΎΠ»Π΅Π½Π° Π·Π° Π΄Π΅ΡΠ΅Ρ ΠΌΠΈΠ½ΡΡΠΈ - ΠΊΠΎΠ³Π° ΡΠ΅ Π·Π°Π²ΡΡΠΈ, Π±ΠΈ ΡΠ°ΠΊΠ°Π»Π΅ Π΄Π° Π½Π΅ΠΌΠ° ΡΡΠ±ΡΠ΅ Π²ΠΎ ΡΠΈΡΡΠ΅ΠΌΠΎΡ, Π° Π»ΠΎΠΊΠ°Π»Π½ΠΈΡΠ΅ ΠΊΡΠΊΠΈ ΡΠ΅ Π³ΠΎ ΠΎΡΠΈΠ³ΡΡΠ°Π°Ρ ΡΠΎΠ°.
ΠΠ΄ Π΄ΡΡΠ³Π° ΡΡΡΠ°Π½Π°, Π·Π°ΠΌΠΈΡΠ»Π΅ΡΠ΅ Π΄Π΅ΠΊΠ° ΡΠ°ΠΊΠ°ΡΠ΅ Π΄Π° ΡΠ΅ ΠΏΠΎΠ²ΡΠ·Π΅ΡΠ΅ ΡΠΎ ΡΡΠ°Π³Π° ΡΠΎΡΠΊΠ° Π²ΠΎ ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ ΠΈ Π΄Π° ΡΠΎΠ±ΠΈΡΠ°ΡΠ΅ ΡΡΠ°ΡΠΈΡΡΠΈΠΊΠ° Π²ΠΎ ΡΠ΅ΠΊΠΎΡ Π½Π° ΠΌΠ½ΠΎΠ³Ρ Π³ΠΎΠ΄ΠΈΠ½ΠΈ. ΠΠΎ ΠΎΠ²ΠΎΡ ΡΠ»ΡΡΠ°Ρ, Π±ΠΈ ΡΠ°ΠΊΠ°Π»Π΅ Π΄Π° Π³ΠΎ ΠΊΠΎΠΌΠΏΠ»Π΅ΡΠΈΡΠ°ΡΠ΅ ΠΊΠΎΡΠΈΡΠ½ΠΈΡΠΊΠΈΠΎΡ Π΄Π΅Π» ΠΈ ΠΎΠ΄Π²ΡΠ΅ΠΌΠ΅-Π½Π°Π²ΡΠ΅ΠΌΠ΅ Π΄Π° ΡΠ΅ Π²ΡΠ°ΡΠ°ΡΠ΅ Π½Π° ΡΡΠ°ΡΠΈΡΡΠΈΠΊΠ°ΡΠ°. ΠΠ°ΡΠΎΡΠ΅ΡΠ½ΠΈΠΎΡ ΡΠΈΡΡΠ΅ΠΌ bpf ΡΠ° Π΄Π°Π²Π° ΠΎΠ²Π°Π° ΠΌΠΎΠΆΠ½ΠΎΡΡ. Π’ΠΎΠ° Π΅ ΠΏΡΠ΅Π²Π΄ΠΎ-Π΄Π°ΡΠΎΡΠ΅ΡΠ΅Π½ ΡΠΈΡΡΠ΅ΠΌ Π²ΠΎ ΠΌΠ΅ΠΌΠΎΡΠΈΡΠ°ΡΠ° ΡΡΠΎ ΠΎΠ²ΠΎΠ·ΠΌΠΎΠΆΡΠ²Π° ΡΠΎΠ·Π΄Π°Π²Π°ΡΠ΅ Π΄Π°ΡΠΎΡΠ΅ΠΊΠΈ ΡΡΠΎ ΡΠ΅ΡΠ΅ΡΠ΅Π½ΡΠΈΡΠ°Π°Ρ BPF ΠΎΠ±ΡΠ΅ΠΊΡΠΈ ΠΈ ΡΠΎ ΡΠΎΠ° ΡΠ΅ Π·Π³ΠΎΠ»Π΅ΠΌΡΠ²Π°Π°Ρ refcount ΠΏΡΠ΅Π΄ΠΌΠ΅ΡΠΈ. ΠΠΎ ΠΎΠ²Π°, Π½Π°ΡΠΎΠ²Π°ΡΡΠ²Π°ΡΠΎΡ ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΈΠ·Π»Π΅Π·Π΅, Π° ΠΎΠ±ΡΠ΅ΠΊΡΠΈΡΠ΅ ΡΡΠΎ Π³ΠΈ ΡΠΎΠ·Π΄Π°Π» ΡΠ΅ ΠΎΡΡΠ°Π½Π°Ρ ΠΆΠΈΠ²ΠΈ.

ΠΡΠ΅ΠΈΡΠ°ΡΠ΅ΡΠΎ Π΄Π°ΡΠΎΡΠ΅ΠΊΠΈ Π²ΠΎ bpffs ΠΊΠΎΠΈ ΡΠΏΠ°ΡΡΠ²Π°Π°Ρ Π½Π° BPF ΠΎΠ±ΡΠ΅ΠΊΡΠΈ ΡΠ΅ Π½Π°ΡΠ΅ΠΊΡΠ²Π° βΠ·Π°ΠΊΠ°ΡΡΠ²Π°ΡΠ΅β (ΠΊΠ°ΠΊΠΎ Π²ΠΎ ΡΠ»Π΅Π΄Π½Π°ΡΠ° ΡΡΠ°Π·Π°: βΠΏΡΠΎΡΠ΅ΡΠΎΡ ΠΌΠΎΠΆΠ΅ Π΄Π° Π·Π°ΠΊΠ°ΡΠΈ BPF ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° ΠΈΠ»ΠΈ ΠΌΠ°ΠΏΠ°β). Π‘ΠΎΠ·Π΄Π°Π²Π°ΡΠ΅ΡΠΎ ΠΎΠ±ΡΠ΅ΠΊΡΠΈ Π½Π° Π΄Π°ΡΠΎΡΠ΅ΠΊΠΈ Π·Π° ΠΎΠ±ΡΠ΅ΠΊΡΠΈΡΠ΅ BPF ΠΈΠΌΠ° ΡΠΌΠΈΡΠ»Π° Π½Π΅ ΡΠ°ΠΌΠΎ Π·Π° ΠΏΡΠΎΠ΄ΠΎΠ»ΠΆΡΠ²Π°ΡΠ΅ Π½Π° ΠΆΠΈΠ²ΠΎΡΠ½ΠΈΠΎΡ Π²Π΅ΠΊ Π½Π° Π»ΠΎΠΊΠ°Π»Π½ΠΈΡΠ΅ ΠΎΠ±ΡΠ΅ΠΊΡΠΈ, ΡΡΠΊΡ ΠΈ Π·Π° ΡΠΏΠΎΡΡΠ΅Π±Π»ΠΈΠ²ΠΎΡΡΠ° Π½Π° Π³Π»ΠΎΠ±Π°Π»Π½ΠΈΡΠ΅ ΠΎΠ±ΡΠ΅ΠΊΡΠΈ - Π²ΡΠ°ΡΠ°ΡΡΠΈ ΡΠ΅ Π½Π° ΠΏΡΠΈΠΌΠ΅ΡΠΎΡ ΡΠΎ Π³Π»ΠΎΠ±Π°Π»Π½Π°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° Π·Π° Π·Π°ΡΡΠΈΡΠ° Π½Π° DDoS, ΡΠ°ΠΊΠ°ΠΌΠ΅ Π΄Π° ΠΌΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° Π΄ΠΎΡΠ΄Π΅ΠΌΠ΅ ΠΈ Π΄Π° ΡΠ° ΡΠ°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ ΡΡΠ°ΡΠΈΡΡΠΈΠΊΠ°ΡΠ° ΠΎΠ΄ Π²ΡΠ΅ΠΌΠ΅ Π½Π° Π²ΡΠ΅ΠΌΠ΅.
ΠΠ°ΡΠΎΡΠ΅ΡΠ½ΠΈΠΎΡ ΡΠΈΡΡΠ΅ΠΌ BPF ΠΎΠ±ΠΈΡΠ½ΠΎ Π΅ ΠΌΠΎΠ½ΡΠΈΡΠ°Π½ /sys/fs/bpf, Π½ΠΎ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ ΠΌΠΎΠ½ΡΠΈΡΠ° ΠΈ Π»ΠΎΠΊΠ°Π»Π½ΠΎ, Π½Π° ΠΏΡΠΈΠΌΠ΅Ρ, Π²Π°ΠΊΠ°:
$ mkdir bpf-mountpoint
$ sudo mount -t bpf none bpf-mountpointΠΠΌΠΈΡΠ°ΡΠ° Π½Π° Π΄Π°ΡΠΎΡΠ΅ΡΠ½ΠΈΠΎΡ ΡΠΈΡΡΠ΅ΠΌ ΡΠ΅ ΠΊΡΠ΅ΠΈΡΠ°Π°Ρ ΡΠΎ ΠΏΠΎΠΌΠΎΡ Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄Π°ΡΠ° BPF_OBJ_PIN BPF ΡΠΈΡΡΠ΅ΠΌΡΠΊΠΈ ΠΏΠΎΠ²ΠΈΠΊ. ΠΠ° ΠΈΠ»ΡΡΡΡΠ°ΡΠΈΡΠ°, Π΄Π° Π·Π΅ΠΌΠ΅ΠΌΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°, Π΄Π° ΡΠ° ΠΊΠΎΠΌΠΏΠ°ΡΠ»ΠΈΡΠ°ΠΌΠ΅, Π΄Π° ΡΠ° ΠΏΠΎΠ΄ΠΈΠ³Π½Π΅ΠΌΠ΅ ΠΈ Π΄Π° ΡΠ° Π·Π°ΠΊΠ°ΡΠΈΠΌΠ΅ bpffs. ΠΠ°ΡΠ°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° Π½Π΅ ΠΏΡΠ°Π²ΠΈ Π½ΠΈΡΡΠΎ ΠΊΠΎΡΠΈΡΠ½ΠΎ, Π½ΠΈΠ΅ ΡΠ°ΠΌΠΎ Π³ΠΎ ΠΏΡΠ΅Π·Π΅Π½ΡΠΈΡΠ°ΠΌΠ΅ ΠΊΠΎΠ΄ΠΎΡ Π·Π° Π΄Π° ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° Π³ΠΎ ΡΠ΅ΠΏΡΠΎΠ΄ΡΡΠΈΡΠ°ΡΠ΅ ΠΏΡΠΈΠΌΠ΅ΡΠΎΡ:
$ cat test.c
__attribute__((section("xdp"), used))
int test(void *ctx)
{
return 0;
}
char _license[] __attribute__((section("license"), used)) = "GPL";ΠΡΠ΄Π΅ Π΄Π° ΡΠ° ΡΠΎΡΡΠ°Π²ΠΈΠΌΠ΅ ΠΎΠ²Π°Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° ΠΈ Π΄Π° ΡΠΎΠ·Π΄Π°Π΄Π΅ΠΌΠ΅ Π»ΠΎΠΊΠ°Π»Π½Π° ΠΊΠΎΠΏΠΈΡΠ° ΠΎΠ΄ Π΄Π°ΡΠΎΡΠ΅ΡΠ΅Π½ ΡΠΈΡΡΠ΅ΠΌ bpffs:
$ clang -target bpf -c test.c -o test.o
$ mkdir bpf-mountpoint
$ sudo mount -t bpf none bpf-mountpointΠ‘Π΅Π³Π° Π΄Π° ΡΠ° ΠΏΡΠ΅Π·Π΅ΠΌΠ΅ΠΌΠ΅ Π½Π°ΡΠ°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° ΠΊΠΎΡΠΈΡΡΠ΅ΡΡΠΈ ΡΠ° Π°Π»Π°ΡΠΊΠ°ΡΠ° bpftool ΠΈ ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΡΠ΅ Π³ΠΈ ΠΏΡΠΈΠ΄ΡΡΠΆΠ½ΠΈΡΠ΅ ΡΠΈΡΡΠ΅ΠΌΡΠΊΠΈ ΠΏΠΎΠ²ΠΈΡΠΈ bpf(2) (Π½Π΅ΠΊΠΎΠΈ ΠΈΡΠ΅Π»Π΅Π²Π°Π½ΡΠ½ΠΈ Π»ΠΈΠ½ΠΈΠΈ ΡΠ΅ ΠΎΡΡΡΡΠ°Π½Π΅ΡΠΈ ΠΎΠ΄ ΠΈΠ·Π»Π΅Π·ΠΎΡ Π½Π° ΡΡΠ°ΡΠ°):
$ sudo strace -e bpf bpftool prog load ./test.o bpf-mountpoint/test
bpf(BPF_PROG_LOAD, {prog_type=BPF_PROG_TYPE_XDP, prog_name="test", ...}, 120) = 3
bpf(BPF_OBJ_PIN, {pathname="bpf-mountpoint/test", bpf_fd=3}, 120) = 0ΠΠ²Π΄Π΅ ΡΠ° Π²ΡΠΈΡΠ°Π²ΠΌΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° ΠΊΠΎΡΠΈΡΡΠ΅ΡΡΠΈ BPF_PROG_LOAD, Π΄ΠΎΠ±ΠΈ Π΄Π΅ΡΠΊΡΠΈΠΏΡΠΎΡ Π½Π° Π΄Π°ΡΠΎΡΠ΅ΠΊΠ° ΠΎΠ΄ ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ 3 ΠΈ ΠΊΠΎΡΠΈΡΡΠ΅ΡΡΠΈ ΡΠ° ΠΊΠΎΠΌΠ°Π½Π΄Π°ΡΠ° BPF_OBJ_PIN Π³ΠΎ Π·Π°ΠΊΠ°ΡΠΈ ΠΎΠ²ΠΎΡ Π΄Π΅ΡΠΊΡΠΈΠΏΡΠΎΡ Π½Π° Π΄Π°ΡΠΎΡΠ΅ΠΊΠ° ΠΊΠ°ΠΊΠΎ Π΄Π°ΡΠΎΡΠ΅ΠΊΠ° "bpf-mountpoint/test". ΠΠΎ ΠΎΠ²Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° Π·Π° ΠΏΠΎΠ΄ΠΈΠ³Π½ΡΠ²Π°Ρ bpftool Π·Π°Π²ΡΡΠΈ ΡΠΎ ΡΠ°Π±ΠΎΡΠ°, Π½ΠΎ Π½Π°ΡΠ°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° ΠΎΡΡΠ°Π½Π° Π²ΠΎ ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ, ΠΈΠ°ΠΊΠΎ Π½Π΅ ΡΠ° ΠΏΡΠΈΠΊΠ°ΡΠΈΠ²ΠΌΠ΅ Π½Π° Π½ΠΈΡΡ Π΅Π΄Π΅Π½ ΠΌΡΠ΅ΠΆΠ΅Π½ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΡΡ:
$ sudo bpftool prog | tail -3
783: xdp name test tag 5c8ba0cf164cb46c gpl
loaded_at 2020-05-05T13:27:08+0000 uid 0
xlated 24B jited 41B memlock 4096BΠΠΎΠΆΠ΅ΠΌΠ΅ Π½ΠΎΡΠΌΠ°Π»Π½ΠΎ Π΄Π° Π³ΠΎ ΠΈΠ·Π±ΡΠΈΡΠ΅ΠΌΠ΅ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΡ Π½Π° Π΄Π°ΡΠΎΡΠ΅ΠΊΠ°ΡΠ° unlink(2) Π° ΠΏΠΎΡΠΎΠ° ΡΠΎΠΎΠ΄Π²Π΅ΡΠ½Π°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° ΡΠ΅ Π±ΠΈΠ΄Π΅ ΠΈΠ·Π±ΡΠΈΡΠ°Π½Π°:
$ sudo rm ./bpf-mountpoint/test
$ sudo bpftool prog show id 783
Error: get by id (783): No such file or directoryΠΡΠΈΡΠ΅ΡΠ΅ ΠΎΠ±ΡΠ΅ΠΊΡΠΈ
ΠΠ±ΠΎΡΡΠ²Π°ΡΡΠΈ Π·Π° Π±ΡΠΈΡΠ΅ΡΠ΅ ΠΎΠ±ΡΠ΅ΠΊΡΠΈ, Π½Π΅ΠΎΠΏΡ ΠΎΠ΄Π½ΠΎ Π΅ Π΄Π° ΡΠ΅ ΡΠ°Π·ΡΠ°ΡΠ½ΠΈ Π΄Π΅ΠΊΠ° ΠΎΡΠΊΠ°ΠΊΠΎ ΡΠ΅ ΡΠ° ΠΈΡΠΊΠ»ΡΡΠΈΠΌΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° ΠΎΠ΄ ΠΊΡΠΊΠ°ΡΠ° (Π³Π΅Π½Π΅ΡΠ°ΡΠΎΡ Π½Π° Π½Π°ΡΡΠ°Π½ΠΈ), Π½ΠΈΡΡ Π΅Π΄Π΅Π½ Π½ΠΎΠ² Π½Π°ΡΡΠ°Π½ Π½Π΅ΠΌΠ° Π΄Π° Π³ΠΎ Π°ΠΊΡΠΈΠ²ΠΈΡΠ° Π½Π΅Π³ΠΎΠ²ΠΎΡΠΎ Π»Π°Π½ΡΠΈΡΠ°ΡΠ΅, ΠΌΠ΅ΡΡΡΠΎΠ°, ΡΠΈΡΠ΅ ΡΠ΅ΠΊΠΎΠ²Π½ΠΈ ΠΏΡΠΈΠΌΠ΅ΡΠΎΡΠΈ Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° ΡΠ΅ Π±ΠΈΠ΄Π°Ρ Π·Π°Π²ΡΡΠ΅Π½ΠΈ Π²ΠΎ Π½ΠΎΡΠΌΠ°Π»Π΅Π½ ΡΠ΅Π΄ΠΎΡΠ»Π΅Π΄ .
ΠΠ΅ΠΊΠΎΠΈ ΡΠΈΠΏΠΎΠ²ΠΈ BPF ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ Π²ΠΈ Π΄ΠΎΠ·Π²ΠΎΠ»ΡΠ²Π°Π°Ρ Π΄Π° ΡΠ° Π·Π°ΠΌΠ΅Π½ΠΈΡΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° Π²ΠΎ Π»Π΅Ρ, Ρ.Π΅. ΠΎΠ±Π΅Π·Π±Π΅Π΄ΡΠ²Π°Π°Ρ Π°ΡΠΎΠΌΠΈΡΠ½ΠΎΡΡ Π½Π° Π½ΠΈΠ·Π°ΡΠ° replace = detach old program, attach new program. ΠΠΎ ΠΎΠ²ΠΎΡ ΡΠ»ΡΡΠ°Ρ, ΡΠΈΡΠ΅ Π°ΠΊΡΠΈΠ²Π½ΠΈ ΠΏΡΠΈΠΌΠ΅ΡΠΎΡΠΈ Π½Π° ΡΡΠ°ΡΠ°ΡΠ° Π²Π΅ΡΠ·ΠΈΡΠ° Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° ΡΠ΅ ΡΠ° Π·Π°Π²ΡΡΠ°Ρ ΡΠ²ΠΎΡΠ°ΡΠ° ΡΠ°Π±ΠΎΡΠ°, Π° ΠΎΠ΄ Π½ΠΎΠ²Π°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° ΡΠ΅ ΡΠ΅ ΡΠΎΠ·Π΄Π°Π΄Π°Ρ Π½ΠΎΠ²ΠΈ ΡΠΏΡΠ°Π²ΡΠ²Π°ΡΠΈ Π½Π° Π½Π°ΡΡΠ°Π½ΠΈ, Π° βΠ°ΡΠΎΠΌΠΈΡΠ½ΠΎΡΡΠ°β ΠΎΠ²Π΄Π΅ Π·Π½Π°ΡΠΈ Π΄Π΅ΠΊΠ° Π½Π΅ΠΌΠ° Π΄Π° ΡΠ΅ ΠΏΡΠΎΠΏΡΡΡΠΈ Π½ΠΈΡΡ Π΅Π΄Π΅Π½ Π½Π°ΡΡΠ°Π½.
ΠΡΠΈΠΊΠ°ΡΡΠ²Π°ΡΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ Π½Π° ΠΈΠ·Π²ΠΎΡΠΈ Π½Π° Π½Π°ΡΡΠ°Π½ΠΈ
ΠΠΎ ΠΎΠ²Π°Π° ΡΡΠ°ΡΠΈΡΠ°, Π½Π΅ΠΌΠ° ΠΎΠ΄Π΄Π΅Π»Π½ΠΎ Π΄Π° ΠΎΠΏΠΈΡΠ΅ΠΌΠ΅ ΠΏΠΎΠ²ΡΠ·ΡΠ²Π°ΡΠ΅ Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ ΡΠΎ ΠΈΠ·Π²ΠΎΡΠΈ Π½Π° Π½Π°ΡΡΠ°Π½ΠΈ, Π±ΠΈΠ΄Π΅ΡΡΠΈ ΠΈΠΌΠ° ΡΠΌΠΈΡΠ»Π° Π΄Π° ΡΠ΅ ΠΏΡΠΎΡΡΡΠ²Π° ΠΎΠ²Π° Π²ΠΎ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡ Π½Π° ΡΠΏΠ΅ΡΠΈΡΠΈΡΠ΅Π½ ΡΠΈΠΏ Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°. Π¦ΠΌ. ΠΏΠΎΠ΄ΠΎΠ»Ρ, Π²ΠΎ ΠΊΠΎΡΠ° ΠΏΠΎΠΊΠ°ΠΆΡΠ²Π°ΠΌΠ΅ ΠΊΠ°ΠΊΠΎ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ΅ ΠΊΠ°ΠΊΠΎ XDP ΡΠ΅ ΠΏΠΎΠ²ΡΠ·Π°Π½ΠΈ.
ΠΠ°Π½ΠΈΠΏΡΠ»ΠΈΡΠ°ΡΠ΅ ΡΠΎ ΠΎΠ±ΡΠ΅ΠΊΡΠΈ ΠΊΠΎΡΠΈΡΡΠ΅ΡΡΠΈ Π³ΠΎ ΡΠΈΡΡΠ΅ΠΌΡΠΊΠΈΠΎΡ ΠΏΠΎΠ²ΠΈΠΊ bpf
BPF ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ
Π‘ΠΈΡΠ΅ BPF ΠΎΠ±ΡΠ΅ΠΊΡΠΈ ΡΠ΅ ΠΊΡΠ΅ΠΈΡΠ°Π½ΠΈ ΠΈ ΡΠΏΡΠ°Π²ΡΠ²Π°Π½ΠΈ ΠΎΠ΄ ΠΊΠΎΡΠΈΡΠ½ΠΈΡΠΊΠΈΠΎΡ ΠΏΡΠΎΡΡΠΎΡ ΡΠΎ ΠΏΠΎΠΌΠΎΡ Π½Π° ΡΠΈΡΡΠ΅ΠΌΡΠΊΠΈ ΠΏΠΎΠ²ΠΈΠΊ bpf, ΡΠΎ ΡΠ»Π΅Π΄Π½ΠΈΠΎΠ² ΠΏΡΠΎΡΠΎΡΠΈΠΏ:
#include <linux/bpf.h>
int bpf(int cmd, union bpf_attr *attr, unsigned int size);ΠΠ²Π΅ Π³ΠΎ ΡΠΈΠΌΠΎΡ cmd Π΅ Π΅Π΄Π½Π° ΠΎΠ΄ Π²ΡΠ΅Π΄Π½ΠΎΡΡΠΈΡΠ΅ Π½Π° ΡΠΈΠΏΠΎΡ , attr β ΠΏΠΎΠΊΠ°ΠΆΡΠ²Π°Ρ Π½Π° ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΈ Π·Π° ΠΎΠ΄ΡΠ΅Π΄Π΅Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° ΠΈ size β Π³ΠΎΠ»Π΅ΠΌΠΈΠ½Π°ΡΠ° Π½Π° ΠΎΠ±ΡΠ΅ΠΊΡΠΎΡ ΡΠΏΠΎΡΠ΅Π΄ ΠΏΠΎΠΊΠ°ΠΆΡΠ²Π°ΡΠΎΡ, Ρ.Π΅. ΠΎΠ±ΠΈΡΠ½ΠΎ ΠΎΠ²Π° sizeof(*attr). ΠΠΎ ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ 5.8 ΡΠΈΡΡΠ΅ΠΌΡΠΊΠΈΠΎΡ ΠΏΠΎΠ²ΠΈΠΊ bpf ΠΏΠΎΠ΄Π΄ΡΠΆΡΠ²Π° 34 ΡΠ°Π·Π»ΠΈΡΠ½ΠΈ ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ ΠΈ union bpf_attr Π·Π°ΡΠ°ΡΠ° 200 Π»ΠΈΠ½ΠΈΠΈ. ΠΠΎ, Π½Π΅ ΡΡΠ΅Π±Π° Π΄Π° ΡΠ΅ ΠΏΠ»Π°ΡΠΈΠΌΠ΅ ΠΎΠ΄ ΠΎΠ²Π°, Π±ΠΈΠ΄Π΅ΡΡΠΈ ΡΠ΅ ΡΠ΅ Π·Π°ΠΏΠΎΠ·Π½Π°Π΅ΠΌΠ΅ ΡΠΎ ΠΊΠΎΠΌΠ°Π½Π΄ΠΈΡΠ΅ ΠΈ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΈΡΠ΅ Π²ΠΎ ΡΠ΅ΠΊΠΎΡ Π½Π° Π½Π΅ΠΊΠΎΠ»ΠΊΡ ΡΡΠ°ΡΠΈΠΈ.
ΠΠ° ΠΏΠΎΡΠ½Π΅ΠΌΠ΅ ΡΠΎ ΡΠΈΠΌΠΎΡ BPF_PROG_LOAD, ΠΊΠΎΡ ΡΠΎΠ·Π΄Π°Π²Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ Π·Π° BPF - Π·Π΅ΠΌΠ° ΡΠ΅Ρ ΠΎΠ΄ ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈ Π·Π° BPF ΠΈ Π³ΠΎ Π²ΡΠΈΡΡΠ²Π° Π²ΠΎ ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ. ΠΠΎ ΠΌΠΎΠΌΠ΅Π½ΡΠΎΡ Π½Π° Π²ΡΠΈΡΡΠ²Π°ΡΠ΅, ΠΏΡΠΎΠ²Π΅ΡΡΠ²Π°ΡΠΎΡ ΡΠ΅ ΡΡΠ°ΡΡΡΠ²Π°, Π° ΠΏΠΎΡΠΎΠ° JIT ΠΊΠΎΠΌΠΏΠ°ΡΠ»Π΅ΡΠΎΡ ΠΈ ΠΏΠΎ ΡΡΠΏΠ΅ΡΠ½ΠΎΡΠΎ ΠΈΠ·Π²ΡΡΡΠ²Π°ΡΠ΅, Π΄Π΅ΡΠΊΡΠΈΠΏΡΠΎΡΠΎΡ Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΡΠΊΠ°ΡΠ° Π΄Π°ΡΠΎΡΠ΅ΠΊΠ° ΡΠ΅ Π²ΡΠ°ΡΠ° Π½Π° ΠΊΠΎΡΠΈΡΠ½ΠΈΠΊΠΎΡ. ΠΠΈΠ΄ΠΎΠ²ΠΌΠ΅ ΡΡΠΎ ΡΠ΅ ΡΠ»ΡΡΡΠ²Π° ΡΠΎ Π½Π΅Π³ΠΎ ΠΏΠΎΠ½Π°ΡΠ°ΠΌΡ Π²ΠΎ ΠΏΡΠ΅ΡΡ
ΠΎΠ΄Π½ΠΈΠΎΡ Π΄Π΅Π» .
Π‘Π΅Π³Π° ΡΠ΅ Π½Π°ΠΏΠΈΡΠ΅ΠΌΠ΅ ΡΠΎΠΏΡΡΠ²Π΅Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° ΠΊΠΎΡΠ° ΡΠ΅ Π²ΡΠΈΡΠ° Π΅Π΄Π½ΠΎΡΡΠ°Π²Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° BPF, Π½ΠΎ ΠΏΡΠ²ΠΎ ΡΡΠ΅Π±Π° Π΄Π° ΠΎΠ΄Π»ΡΡΠΈΠΌΠ΅ ΠΊΠ°ΠΊΠ²Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° ΡΠ°ΠΊΠ°ΠΌΠ΅ Π΄Π° Π²ΡΠΈΡΠ°ΠΌΠ΅ - ΡΠ΅ ΡΡΠ΅Π±Π° Π΄Π° ΠΈΠ·Π±Π΅ΡΠ΅ΠΌΠ΅ ΠΈ Π²ΠΎ ΡΠ°ΠΌΠΊΠΈΡΠ΅ Π½Π° ΠΎΠ²ΠΎΡ ΡΠΈΠΏ Π½Π°ΠΏΠΈΡΠ΅ΡΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° ΠΊΠΎΡΠ° ΡΠ΅ Π³ΠΎ ΠΏΠΎΠ»ΠΎΠΆΠΈ ΡΠ΅ΡΡΠΎΡ Π·Π° Π²Π΅ΡΠΈΡΠΈΠΊΠ°ΡΠΈΡΠ°. Π‘Π΅ΠΏΠ°ΠΊ, Π·Π° Π΄Π° Π½Π΅ Π³ΠΎ ΠΊΠΎΠΌΠΏΠ»ΠΈΡΠΈΡΠ°ΠΌΠ΅ ΠΏΡΠΎΡΠ΅ΡΠΎΡ, Π΅Π²Π΅ Π³ΠΎ Π³ΠΎΡΠΎΠ²ΠΎ ΡΠ΅ΡΠ΅Π½ΠΈΠ΅: ΡΠ΅ Π·Π΅ΠΌΠ΅ΠΌΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° ΠΊΠ°ΠΊΠΎ BPF_PROG_TYPE_XDP, ΡΡΠΎ ΡΠ΅ ΡΠ° Π²ΡΠ°ΡΠΈ Π²ΡΠ΅Π΄Π½ΠΎΡΡΠ° XDP_PASS (ΠΏΡΠ΅ΡΠΊΠΎΠΊΠ½Π΅ΡΠ΅ Π³ΠΈ ΡΠΈΡΠ΅ ΠΏΠ°ΠΊΠ΅ΡΠΈ). ΠΠΎ Π°ΡΠ΅ΠΌΠ±Π»Π΅ΡΠΎΡ BPF ΠΈΠ·Π³Π»Π΅Π΄Π° ΠΌΠ½ΠΎΠ³Ρ Π΅Π΄Π½ΠΎΡΡΠ°Π²Π½ΠΎ:
r0 = 2
exitΠΡΠΊΠ°ΠΊΠΎ ΡΠ΅ ΡΠ΅ ΠΎΠ΄Π»ΡΡΠΈΠΌΠ΅ Π·Π° Π΄Π΅ΠΊΠ° ΡΠ΅ ΠΈΡΠΏΡΠ°ΡΠΈΠΌΠ΅, ΠΌΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° Π²ΠΈ ΠΊΠ°ΠΆΠ΅ΠΌΠ΅ ΠΊΠ°ΠΊΠΎ ΡΠ΅ Π³ΠΎ Π½Π°ΠΏΡΠ°Π²ΠΈΠΌΠ΅ ΡΠΎΠ°:
#define _GNU_SOURCE
#include <string.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <linux/bpf.h>
static inline __u64 ptr_to_u64(const void *ptr)
{
return (__u64) (unsigned long) ptr;
}
int main(void)
{
struct bpf_insn insns[] = {
{
.code = BPF_ALU64 | BPF_MOV | BPF_K,
.dst_reg = BPF_REG_0,
.imm = XDP_PASS
},
{
.code = BPF_JMP | BPF_EXIT
},
};
union bpf_attr attr = {
.prog_type = BPF_PROG_TYPE_XDP,
.insns = ptr_to_u64(insns),
.insn_cnt = sizeof(insns)/sizeof(insns[0]),
.license = ptr_to_u64("GPL"),
};
strncpy(attr.prog_name, "woo", sizeof(attr.prog_name));
syscall(__NR_bpf, BPF_PROG_LOAD, &attr, sizeof(attr));
for ( ;; )
pause();
}ΠΠ½ΡΠ΅ΡΠ΅ΡΠ½ΠΈΡΠ΅ Π½Π°ΡΡΠ°Π½ΠΈ Π²ΠΎ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° Π·Π°ΠΏΠΎΡΠ½ΡΠ²Π°Π°Ρ ΡΠΎ Π΄Π΅ΡΠΈΠ½ΠΈΡΠΈΡΠ° Π½Π° Π½ΠΈΠ·Π° insns - Π½Π°ΡΠ°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° BPF Π²ΠΎ ΠΌΠ°ΡΠΈΠ½ΡΠΊΠΈ ΠΊΠΎΠ΄. ΠΠΎ ΠΎΠ²ΠΎΡ ΡΠ»ΡΡΠ°Ρ, ΡΠ΅ΠΊΠΎΡΠ° ΠΈΠ½ΡΡΡΡΠΊΡΠΈΡΠ° ΠΎΠ΄ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° BPF Π΅ ΡΠΏΠ°ΠΊΡΠ²Π°Π½Π° Π²ΠΎ ΡΡΡΡΠΊΡΡΡΠ°ΡΠ° . ΠΡΠ²ΠΈΠΎΡ Π΅Π»Π΅ΠΌΠ΅Π½Ρ insns Π΅ Π²ΠΎ ΡΠΎΠ³Π»Π°ΡΠ½ΠΎΡΡ ΡΠΎ ΡΠΏΠ°ΡΡΡΠ²Π°ΡΠ° r0 = 2, Π²ΡΠΎΡΠΈΠΎΡ - exit.
ΠΠΎΠ²Π»Π΅ΠΊΡΠ²Π°ΡΠ΅. ΠΠ°Π΄ΡΠΎΡΠΎ Π΄Π΅ΡΠΈΠ½ΠΈΡΠ° ΠΏΠΎΠΏΠΎΠ³ΠΎΠ΄Π½ΠΈ ΠΌΠ°ΠΊΡΠΎΠ° Π·Π° ΠΏΠΈΡΡΠ²Π°ΡΠ΅ ΠΌΠ°ΡΠΈΠ½ΡΠΊΠΈ ΠΊΠΎΠ΄ΠΎΠ²ΠΈ ΠΈ ΠΊΠΎΡΠΈΡΡΠ΅ΡΠ΅ Π½Π° Π΄Π°ΡΠΎΡΠ΅ΠΊΠ°ΡΠ° Π·Π° Π·Π°Π³Π»Π°Π²ΠΈΠ΅ Π½Π° ΡΠ°Π΄ΡΠΎΡΠΎ tools/include/linux/filter.h Π±ΠΈ ΠΌΠΎΠΆΠ΅Π»Π΅ Π΄Π° ΠΏΠΈΡΡΠ²Π°ΠΌΠ΅
struct bpf_insn insns[] = {
BPF_MOV64_IMM(BPF_REG_0, XDP_PASS),
BPF_EXIT_INSN()
};ΠΠΎ, Π±ΠΈΠ΄Π΅ΡΡΠΈ ΠΏΠΈΡΡΠ²Π°ΡΠ΅ΡΠΎ BPF ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ Π²ΠΎ ΠΌΠ°ΡΡΠΈΠ½ ΠΊΠΎΠ΄ Π΅ ΠΏΠΎΡΡΠ΅Π±Π½ΠΎ ΡΠ°ΠΌΠΎ Π·Π° ΠΏΠΈΡΡΠ²Π°ΡΠ΅ ΡΠ΅ΡΡΠΎΠ²ΠΈ Π²ΠΎ ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ ΠΈ ΡΡΠ°ΡΠΈΠΈ Π·Π° BPF, ΠΎΡΡΡΡΡΠ²ΠΎΡΠΎ Π½Π° ΠΎΠ²ΠΈΠ΅ ΠΌΠ°ΠΊΡΠΎΠ° Π½Π°Π²ΠΈΡΡΠΈΠ½Π° Π½Π΅ Π³ΠΎ ΠΊΠΎΠΌΠΏΠ»ΠΈΡΠΈΡΠ° ΠΆΠΈΠ²ΠΎΡΠΎΡ Π½Π° ΡΠ°Π·Π²ΠΈΠ²Π°ΡΠΎΡ.
ΠΠΎ Π΄Π΅ΡΠΈΠ½ΠΈΡΠ°ΡΠ΅ΡΠΎ Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° BPF, ΠΏΡΠ΅ΠΌΠΈΠ½ΡΠ²Π°ΠΌΠ΅ ΠΊΠΎΠ½ Π½Π΅ΡΠ·ΠΈΠ½ΠΎ Π²ΡΠΈΡΡΠ²Π°ΡΠ΅ Π²ΠΎ ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ. ΠΠ°ΡΠΈΠΎΡ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΠΈΡΡΠΈΡΠΊΠΈ ΡΠ΅Ρ Π½Π° ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΈ attr Π³ΠΈ Π²ΠΊΠ»ΡΡΡΠ²Π° ΡΠΈΠΏΠΎΡ Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ°, ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²ΠΎΡΠΎ ΠΈ Π±ΡΠΎΡΠΎΡ Π½Π° ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈ, ΠΏΠΎΡΡΠ΅Π±Π½Π°ΡΠ° Π»ΠΈΡΠ΅Π½ΡΠ° ΠΈ ΠΈΠΌΠ΅ΡΠΎ "woo", ΠΊΠΎΡ Π³ΠΎ ΠΊΠΎΡΠΈΡΡΠΈΠΌΠ΅ Π·Π° Π΄Π° ΡΠ° ΠΏΡΠΎΠ½Π°ΡΠ΄Π΅ΠΌΠ΅ Π½Π°ΡΠ°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° Π½Π° ΡΠΈΡΡΠ΅ΠΌΠΎΡ ΠΏΠΎ ΠΏΡΠ΅Π·Π΅ΠΌΠ°ΡΠ΅ΡΠΎ. ΠΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ°, ΠΊΠ°ΠΊΠΎ ΡΡΠΎ Π΅ Π²Π΅ΡΠ΅Π½ΠΎ, ΡΠ΅ Π²ΡΠΈΡΡΠ²Π° Π²ΠΎ ΡΠΈΡΡΠ΅ΠΌΠΎΡ ΡΠΎ ΠΏΠΎΠΌΠΎΡ Π½Π° ΡΠΈΡΡΠ΅ΠΌΡΠΊΠΈ ΠΏΠΎΠ²ΠΈΠΊ bpf.
ΠΠ° ΠΊΡΠ°ΡΠΎΡ ΠΎΠ΄ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° Π·Π°Π²ΡΡΡΠ²Π°ΠΌΠ΅ Π²ΠΎ Π±Π΅ΡΠΊΠΎΠ½Π΅ΡΠ½Π° ΡΠ°ΠΌΠΊΠ° ΠΊΠΎΡΠ° Π³ΠΎ ΡΠΈΠΌΡΠ»ΠΈΡΠ° ΡΠΎΠ²Π°ΡΠΎΡ. ΠΠ΅Π· Π½Π΅Π³ΠΎ, ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° ΡΠ΅ Π±ΠΈΠ΄Π΅ ΡΠ±ΠΈΠ΅Π½Π° ΠΎΠ΄ ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ ΠΊΠΎΠ³Π° ΡΠ΅ ΡΠ΅ Π·Π°ΡΠ²ΠΎΡΠΈ Π΄Π΅ΡΠΊΡΠΈΠΏΡΠΎΡΠΎΡ Π½Π° Π΄Π°ΡΠΎΡΠ΅ΠΊΠ°ΡΠ° ΡΡΠΎ Π½ΠΈ Π³ΠΎ Π²ΡΠ°ΡΠΈ ΡΠΈΡΡΠ΅ΠΌΡΠΊΠΈΠΎΡ ΠΏΠΎΠ²ΠΈΠΊ bpf, ΠΈ Π½Π΅ΠΌΠ° Π΄Π° Π³ΠΎ Π²ΠΈΠ΄ΠΈΠΌΠ΅ Π²ΠΎ ΡΠΈΡΡΠ΅ΠΌΠΎΡ.
ΠΠ°, Π½ΠΈΠ΅ ΡΠΌΠ΅ ΠΏΠΎΠ΄Π³ΠΎΡΠ²Π΅Π½ΠΈ Π·Π° ΡΠ΅ΡΡΠΈΡΠ°ΡΠ΅. ΠΡΠ΄Π΅ Π΄Π° ΡΠ° ΡΠΎΡΡΠ°Π²ΠΈΠΌΠ΅ ΠΈ ΠΈΠ·Π²ΡΡΠΈΠΌΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° ΠΏΠΎΠ΄ straceΠ·Π° Π΄Π° ΠΏΡΠΎΠ²Π΅ΡΠΈΡΠ΅ Π΄Π°Π»ΠΈ ΡΓ¨ ΡΠ°Π±ΠΎΡΠΈ ΠΊΠ°ΠΊΠΎ ΡΡΠΎ ΡΡΠ΅Π±Π°:
$ clang -g -O2 simple-prog.c -o simple-prog
$ sudo strace ./simple-prog
execve("./simple-prog", ["./simple-prog"], 0x7ffc7b553480 /* 13 vars */) = 0
...
bpf(BPF_PROG_LOAD, {prog_type=BPF_PROG_TYPE_XDP, insn_cnt=2, insns=0x7ffe03c4ed50, license="GPL", log_level=0, log_size=0, log_buf=NULL, kern_version=KERNEL_V
ERSION(0, 0, 0), prog_flags=0, prog_name="woo", prog_ifindex=0, expected_attach_type=BPF_CGROUP_INET_INGRESS}, 72) = 3
pause(Π‘Π΅ Π΅ Π²ΠΎ ΡΠ΅Π΄, bpf(2) Π½ΠΈ ΡΠ° Π²ΡΠ°ΡΠΈ ΡΠ°ΡΠΊΠ°ΡΠ° 3 ΠΈ ΠΎΡΠΈΠ΄ΠΎΠ²ΠΌΠ΅ Π²ΠΎ Π±Π΅ΡΠΊΠΎΠ½Π΅ΡΠ½Π° ΡΠ°ΠΌΠΊΠ° ΡΠΎ pause(). ΠΡΠ΄Π΅ Π΄Π° ΡΠ΅ ΠΎΠ±ΠΈΠ΄Π΅ΠΌΠ΅ Π΄Π° ΡΠ° Π½Π°ΡΠ΄Π΅ΠΌΠ΅ Π½Π°ΡΠ°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° Π²ΠΎ ΡΠΈΡΡΠ΅ΠΌΠΎΡ. ΠΠ° Π΄Π° Π³ΠΎ Π½Π°ΠΏΡΠ°Π²ΠΈΡΠ΅ ΠΎΠ²Π°, ΡΠ΅ ΠΎΠ΄ΠΈΠΌΠ΅ Π½Π° Π΄ΡΡΠ³ ΡΠ΅ΡΠΌΠΈΠ½Π°Π» ΠΈ ΡΠ΅ ΡΠ° ΠΊΠΎΡΠΈΡΡΠΈΠΌΠ΅ Π°Π»Π°ΡΠΊΠ°ΡΠ° bpftool:
# bpftool prog | grep -A3 woo
390: xdp name woo tag 3b185187f1855c4c gpl
loaded_at 2020-08-31T24:66:44+0000 uid 0
xlated 16B jited 40B memlock 4096B
pids simple-prog(10381)ΠΠ»Π΅Π΄Π°ΠΌΠ΅ Π΄Π΅ΠΊΠ° ΠΈΠΌΠ° Π²ΡΠΈΡΠ°Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° Π½Π° ΡΠΈΡΡΠ΅ΠΌΠΎΡ woo ΡΠΈΡΡΡΠΎ Π³Π»ΠΎΠ±Π°Π»Π΅Π½ ID Π΅ 390 ΠΈ ΠΌΠΎΠΌΠ΅Π½ΡΠ°Π»Π½ΠΎ Π΅ Π²ΠΎ ΡΠ΅ΠΊ simple-prog ΠΈΠΌΠ° Π΄Π΅ΡΠΊΡΠΈΠΏΡΠΎΡ Π½Π° ΠΎΡΠ²ΠΎΡΠ΅Π½Π° Π΄Π°ΡΠΎΡΠ΅ΠΊΠ° ΡΡΠΎ ΠΏΠΎΠΊΠ°ΠΆΡΠ²Π° Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° (ΠΈ Π°ΠΊΠΎ simple-prog ΡΠΎΠ³Π°Ρ ΡΠ΅ ΡΠ° Π·Π°Π²ΡΡΠΈ ΡΠ°Π±ΠΎΡΠ°ΡΠ° woo ΡΠ΅ ΠΈΡΡΠ΅Π·Π½Π΅). ΠΡΠ΅ΠΊΡΠ²Π°Π½ΠΎ, ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° woo Π·Π΅ΠΌΠ° 16 Π±Π°ΡΡΠΈ - Π΄Π²Π΅ ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈ - ΠΎΠ΄ Π±ΠΈΠ½Π°ΡΠ½ΠΈ ΠΊΠΎΠ΄ΠΎΠ²ΠΈ Π²ΠΎ Π°ΡΡ
ΠΈΡΠ΅ΠΊΡΡΡΠ°ΡΠ° BPF, Π½ΠΎ Π²ΠΎ Π½Π΅ΡΠ·ΠΈΠ½Π°ΡΠ° ΠΌΠ°ΡΠΈΡΠ½Π° ΡΠΎΡΠΌΠ° (x86_64) Π²Π΅ΡΠ΅ Π΅ 40 Π±Π°ΡΡΠΈ. ΠΡΠ΄Π΅ Π΄Π° ΡΠ° ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ Π½Π°ΡΠ°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° Π²ΠΎ Π½Π΅ΡΠ·ΠΈΠ½Π°ΡΠ° ΠΎΡΠΈΠ³ΠΈΠ½Π°Π»Π½Π° ΡΠΎΡΠΌΠ°:
# bpftool prog dump xlated id 390
0: (b7) r0 = 2
1: (95) exitΠ½Π΅ΠΌΠ° ΠΈΠ·Π½Π΅Π½Π°Π΄ΡΠ²Π°ΡΠ°. Π‘Π΅Π³Π° Π΄Π° Π³ΠΎ ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ ΠΊΠΎΠ΄ΠΎΡ Π³Π΅Π½Π΅ΡΠΈΡΠ°Π½ ΠΎΠ΄ ΠΊΠΎΠΌΠΏΠ°ΡΠ»Π΅ΡΠΎΡ JIT:
# bpftool prog dump jited id 390
bpf_prog_3b185187f1855c4c_woo:
0: nopl 0x0(%rax,%rax,1)
5: push %rbp
6: mov %rsp,%rbp
9: sub $0x0,%rsp
10: push %rbx
11: push %r13
13: push %r14
15: push %r15
17: pushq $0x0
19: mov $0x2,%eax
1e: pop %rbx
1f: pop %r15
21: pop %r14
23: pop %r13
25: pop %rbx
26: leaveq
27: retqΠ½Π΅ ΠΌΠ½ΠΎΠ³Ρ Π΅ΡΠΈΠΊΠ°ΡΠ½ΠΈ Π·Π° exit(2), Π½ΠΎ ΠΈΡΠΊΡΠ΅Π½ΠΎ, Π½Π°ΡΠ°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° Π΅ ΠΏΡΠ΅ΠΌΠ½ΠΎΠ³Ρ Π΅Π΄Π½ΠΎΡΡΠ°Π²Π½Π°, Π° Π·Π° Π½Π΅ΡΡΠΈΠ²ΠΈΡΠ°Π»Π½ΠΈ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ, ΡΠ΅ΠΊΠ°ΠΊΠΎ, ΡΠ΅ ΠΏΠΎΡΡΠ΅Π±Π½ΠΈ ΠΏΡΠΎΠ»ΠΎΠ³ΠΎΡ ΠΈ Π΅ΠΏΠΈΠ»ΠΎΠ³ΠΎΡ Π΄ΠΎΠ΄Π°Π΄Π΅Π½ΠΈ ΠΎΠ΄ ΠΊΠΎΠΌΠΏΠ°ΡΠ»Π΅ΡΠΎΡ JIT.
ΠΠ°ΠΏΠΈ
BPF ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ΅ ΠΌΠΎΠΆΠ°Ρ Π΄Π° ΠΊΠΎΡΠΈΡΡΠ°Ρ ΡΡΡΡΠΊΡΡΡΠΈΡΠ°Π½ΠΈ ΠΌΠ΅ΠΌΠΎΡΠΈΡΠΊΠΈ ΠΎΠ±Π»Π°ΡΡΠΈ ΠΊΠΎΠΈ ΡΠ΅ Π΄ΠΎΡΡΠ°ΠΏΠ½ΠΈ ΠΈ Π·Π° Π΄ΡΡΠ³ΠΈΡΠ΅ BPF ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ ΠΈ Π·Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ΅ Π²ΠΎ ΠΊΠΎΡΠΈΡΠ½ΠΈΡΠΊΠΈΠΎΡ ΠΏΡΠΎΡΡΠΎΡ. ΠΠ²ΠΈΠ΅ ΠΎΠ±ΡΠ΅ΠΊΡΠΈ ΡΠ΅ Π½Π°ΡΠ΅ΠΊΡΠ²Π°Π°Ρ ΠΌΠ°ΠΏΠΈ ΠΈ Π²ΠΎ ΠΎΠ²ΠΎΡ Π΄Π΅Π» ΡΠ΅ ΠΏΠΎΠΊΠ°ΠΆΠ΅ΠΌΠ΅ ΠΊΠ°ΠΊΠΎ Π΄Π° ΠΌΠ°Π½ΠΈΠΏΡΠ»ΠΈΡΠ°ΠΌΠ΅ ΡΠΎ Π½ΠΈΠ² ΠΊΠΎΡΠΈΡΡΠ΅ΡΡΠΈ ΡΠΈΡΡΠ΅ΠΌΡΠΊΠΈ ΠΏΠΎΠ²ΠΈΠΊ bpf.
ΠΠ΅Π΄Π½Π°Ρ Π΄Π° ΠΊΠ°ΠΆΠ΅ΠΌΠ΅ Π΄Π΅ΠΊΠ° ΠΌΠΎΠΆΠ½ΠΎΡΡΠΈΡΠ΅ Π½Π° ΠΌΠ°ΠΏΠΈΡΠ΅ Π½Π΅ ΡΠ΅ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈ ΡΠ°ΠΌΠΎ Π½Π° ΠΏΡΠΈΡΡΠ°ΠΏ Π΄ΠΎ Π·Π°Π΅Π΄Π½ΠΈΡΠΊΠ° ΠΌΠ΅ΠΌΠΎΡΠΈΡΠ°. ΠΠΎΡΡΠΎΡΠ°Ρ ΠΌΠ°ΠΏΠΈ Π·Π° ΡΠΏΠ΅ΡΠΈΡΠ°Π»Π½Π° Π½Π°ΠΌΠ΅Π½Π° ΠΊΠΎΠΈ ΡΠΎΠ΄ΡΠΆΠ°Ρ, Π½Π° ΠΏΡΠΈΠΌΠ΅Ρ, ΠΏΠΎΠΊΠ°ΠΆΡΠ²Π°ΡΠΈ ΠΊΠΎΠ½ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ΅ BPF ΠΈΠ»ΠΈ ΠΏΠΎΠΊΠ°ΠΆΡΠ²Π°ΡΠΈ Π½Π° ΠΌΡΠ΅ΠΆΠ½ΠΈΡΠ΅ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΡΡΠΈ, ΠΌΠ°ΠΏΠΈ Π·Π° ΡΠ°Π±ΠΎΡΠ° ΡΠΎ Π½Π°ΡΡΠ°Π½ΠΈ Π½Π° ΠΏΠ΅ΡΡ ΠΈΡΠ½. ΠΠ° Π½ΠΈΠ² Π½Π΅ΠΌΠ° Π΄Π° Π·Π±ΠΎΡΡΠ²Π°ΠΌΠ΅ ΠΎΠ²Π΄Π΅, Π·Π° Π΄Π° Π½Π΅ Π³ΠΎ Π·Π±ΡΠ½ΠΈΠΌΠ΅ ΡΠΈΡΠ°ΡΠ΅Π»ΠΎΡ. ΠΡΠ²Π΅Π½ ΠΎΠ²Π°, Π³ΠΈ ΠΈΠ³Π½ΠΎΡΠΈΡΠ°ΠΌΠ΅ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠΈΡΠ΅ Π·Π° ΡΠΈΠ½Ρ
ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΡΠ°, Π±ΠΈΠ΄Π΅ΡΡΠΈ ΡΠΎΠ° Π½Π΅ Π΅ Π²Π°ΠΆΠ½ΠΎ Π·Π° Π½Π°ΡΠΈΡΠ΅ ΠΏΡΠΈΠΌΠ΅ΡΠΈ. ΠΠΎΠΌΠΏΠ»Π΅ΡΠ½Π° Π»ΠΈΡΡΠ° Π½Π° Π΄ΠΎΡΡΠ°ΠΏΠ½ΠΈ ΡΠΈΠΏΠΎΠ²ΠΈ ΠΌΠ°ΠΏΠΈ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ Π½Π°ΡΠ΄Π΅ Π²ΠΎ , Π° Π²ΠΎ ΠΎΠ²ΠΎΡ Π΄Π΅Π» ΠΊΠ°ΠΊΠΎ ΠΏΡΠΈΠΌΠ΅Ρ ΡΠ΅ Π³ΠΎ Π·Π΅ΠΌΠ΅ΠΌΠ΅ ΠΈΡΡΠΎΡΠΈΡΠΊΠΈ ΠΏΡΠ²ΠΈΠΎΡ ΡΠΈΠΏ, Ρ
Π΅Ρ ΡΠ°Π±Π΅Π»Π° BPF_MAP_TYPE_HASH.
ΠΠΊΠΎ ΠΊΡΠ΅ΠΈΡΠ°ΡΠ΅ Ρ
Π΅Ρ-ΡΠ°Π±Π΅Π»Π° Π²ΠΎ, Π΄Π° ΡΠ΅ΡΠ΅ΠΌΠ΅, C++, Π±ΠΈ ΡΠ΅ΠΊΠ»Π΅ unordered_map<int,long> woo, ΡΡΠΎ Π½Π° ΡΡΡΠΊΠΈ Π·Π½Π°ΡΠΈ βΠΠΈ ΡΡΠ΅Π±Π° ΠΌΠ°ΡΠ° woo Π½Π΅ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½Π° Π³ΠΎΠ»Π΅ΠΌΠΈΠ½Π°, ΡΠΈΠΈ ΠΊΠ»ΡΡΠ΅Π²ΠΈ ΡΠ΅ ΠΎΠ΄ ΡΠΈΠΏΠΎΡ int, Π° Π²ΡΠ΅Π΄Π½ΠΎΡΡΠΈΡΠ΅ ΡΠ΅ ΡΠΈΠΏΠΎΡ long" ΠΠ° Π΄Π° ΡΠΎΠ·Π΄Π°Π΄Π΅ΠΌΠ΅ Ρ
Π°Ρ-ΡΠ°Π±Π΅Π»Π° BPF, ΡΡΠ΅Π±Π° Π΄Π° Π³ΠΎ Π½Π°ΠΏΡΠ°Π²ΠΈΠΌΠ΅ ΠΈΡΡΠΎΡΠΎ, ΠΎΡΠ²Π΅Π½ ΡΡΠΎ ΡΡΠ΅Π±Π° Π΄Π° ΡΠ° ΠΎΠ΄ΡΠ΅Π΄ΠΈΠΌΠ΅ ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»Π½Π°ΡΠ° Π³ΠΎΠ»Π΅ΠΌΠΈΠ½Π° Π½Π° ΡΠ°Π±Π΅Π»Π°ΡΠ° ΠΈ Π½Π°ΠΌΠ΅ΡΡΠΎ Π΄Π° Π³ΠΈ ΡΠΏΠ΅ΡΠΈΡΠΈΡΠΈΡΠ°ΠΌΠ΅ ΡΠΈΠΏΠΎΠ²ΠΈΡΠ΅ Π½Π° ΠΊΠ»ΡΡΠ΅Π²ΠΈ ΠΈ Π²ΡΠ΅Π΄Π½ΠΎΡΡΠΈ, ΡΡΠ΅Π±Π° Π΄Π° Π³ΠΈ ΡΠΏΠ΅ΡΠΈΡΠΈΡΠΈΡΠ°ΠΌΠ΅ Π½ΠΈΠ²Π½ΠΈΡΠ΅ Π³ΠΎΠ»Π΅ΠΌΠΈΠ½ΠΈ Π²ΠΎ Π±Π°ΡΡΠΈ. . ΠΠ° Π΄Π° ΠΊΡΠ΅ΠΈΡΠ°ΡΠ΅ ΠΌΠ°ΠΏΠΈ ΠΊΠΎΡΠΈΡΡΠ΅ΡΠ΅ ΡΠ° ΠΊΠΎΠΌΠ°Π½Π΄Π°ΡΠ° BPF_MAP_CREATE ΡΠΈΡΡΠ΅ΠΌΡΠΊΠΈ ΠΏΠΎΠ²ΠΈΠΊ bpf. ΠΡΠ΄Π΅ Π΄Π° ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ ΠΏΠΎΠ²Π΅ΡΠ΅ ΠΈΠ»ΠΈ ΠΏΠΎΠΌΠ°Π»ΠΊΡ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° ΡΡΠΎ ΡΠΎΠ·Π΄Π°Π²Π° ΠΌΠ°ΠΏΠ°. ΠΠΎ ΠΏΡΠ΅ΡΡ
ΠΎΠ΄Π½Π°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° ΡΡΠΎ Π³ΠΈ Π²ΡΠΈΡΡΠ²Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ΅ BPF, ΠΎΠ²Π°Π° ΡΡΠ΅Π±Π° Π΄Π° Π²ΠΈ ΠΈΠ·Π³Π»Π΅Π΄Π° Π΅Π΄Π½ΠΎΡΡΠ°Π²Π½Π°:
$ cat simple-map.c
#define _GNU_SOURCE
#include <string.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <linux/bpf.h>
int main(void)
{
union bpf_attr attr = {
.map_type = BPF_MAP_TYPE_HASH,
.key_size = sizeof(int),
.value_size = sizeof(int),
.max_entries = 4,
};
strncpy(attr.map_name, "woo", sizeof(attr.map_name));
syscall(__NR_bpf, BPF_MAP_CREATE, &attr, sizeof(attr));
for ( ;; )
pause();
}ΠΠ²Π΄Π΅ Π΄Π΅ΡΠΈΠ½ΠΈΡΠ°ΠΌΠ΅ Π·Π±ΠΈΡ Π½Π° ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΈ attr, Π²ΠΎ ΠΊΠΎΡΠ° Π²Π΅Π»ΠΈΠΌΠ΅ βΠΠΈ ΡΡΠ΅Π±Π° Ρ
Π°Ρ ΡΠ°Π±Π΅Π»Π° ΡΠΎ ΠΊΠ»ΡΡΠ΅Π²ΠΈ ΠΈ Π²ΡΠ΅Π΄Π½ΠΎΡΡΠΈ Π·Π° Π³ΠΎΠ»Π΅ΠΌΠΈΠ½Π° sizeof(int), Π²ΠΎ ΠΊΠΎΡ ΠΌΠΎΠΆΠ°ΠΌ Π΄Π° ΡΡΠ°Π²Π°ΠΌ Π½Π°ΡΠΌΠ½ΠΎΠ³Ρ ΡΠ΅ΡΠΈΡΠΈ Π΅Π»Π΅ΠΌΠ΅Π½ΡΠΈβ. ΠΠΎΠ³Π° ΠΊΡΠ΅ΠΈΡΠ°ΡΠ΅ ΠΌΠ°ΠΏΠΈ BPF, ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° Π½Π°Π²Π΅Π΄Π΅ΡΠ΅ Π΄ΡΡΠ³ΠΈ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΈ, Π½Π° ΠΏΡΠΈΠΌΠ΅Ρ, Π½Π° ΠΈΡΡ Π½Π°ΡΠΈΠ½ ΠΊΠ°ΠΊΠΎ Π²ΠΎ ΠΏΡΠΈΠΌΠ΅ΡΠΎΡ ΡΠΎ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ°, Π³ΠΎ Π½Π°Π²Π΅Π΄ΠΎΠ²ΠΌΠ΅ ΠΈΠΌΠ΅ΡΠΎ Π½Π° ΠΎΠ±ΡΠ΅ΠΊΡΠΎΡ ΠΊΠ°ΠΊΠΎ "woo".
ΠΡΠ΄Π΅ Π΄Π° ΡΠ° ΠΊΠΎΠΌΠΏΠ°ΡΠ»ΠΈΡΠ°ΠΌΠ΅ ΠΈ ΠΈΠ·Π²ΡΡΠΈΠΌΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ°:
$ clang -g -O2 simple-map.c -o simple-map
$ sudo strace ./simple-map
execve("./simple-map", ["./simple-map"], 0x7ffd40a27070 /* 14 vars */) = 0
...
bpf(BPF_MAP_CREATE, {map_type=BPF_MAP_TYPE_HASH, key_size=4, value_size=4, max_entries=4, map_name="woo", ...}, 72) = 3
pause(ΠΠ²Π΅ Π³ΠΎ ΡΠΈΡΡΠ΅ΠΌΡΠΊΠΈΠΎΡ ΠΏΠΎΠ²ΠΈΠΊ bpf(2) Π½ΠΈ Π³ΠΎ Π²ΡΠ°ΡΠΈ Π΄Π΅ΡΠΊΡΠΈΠΏΡΠΎΡΠΎΡ Π½Π° ΠΌΠ°ΠΏΠ°ΡΠ° 3 Π° ΠΏΠΎΡΠΎΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ°, ΠΊΠ°ΠΊΠΎ ΡΡΠΎ ΡΠ΅ ΠΎΡΠ΅ΠΊΡΠ²Π°ΡΠ΅, ΡΠ΅ΠΊΠ° Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»Π½ΠΈ ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈ Π²ΠΎ ΡΠΈΡΡΠ΅ΠΌΡΠΊΠΈΠΎΡ ΠΏΠΎΠ²ΠΈΠΊ pause(2).
Π‘Π΅Π³Π° Π΄Π° ΡΠ° ΠΈΡΠΏΡΠ°ΡΠΈΠΌΠ΅ Π½Π°ΡΠ°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° Π²ΠΎ ΠΏΠΎΠ·Π°Π΄ΠΈΠ½Π° ΠΈΠ»ΠΈ Π΄Π° ΠΎΡΠ²ΠΎΡΠΈΠΌΠ΅ Π΄ΡΡΠ³ ΡΠ΅ΡΠΌΠΈΠ½Π°Π» ΠΈ Π΄Π° Π³ΠΎ ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ Π½Π°ΡΠΈΠΎΡ ΠΎΠ±ΡΠ΅ΠΊΡ ΠΊΠΎΡΠΈΡΡΠ΅ΡΡΠΈ ΡΠ° Π°Π»Π°ΡΠΊΠ°ΡΠ° bpftool (ΠΌΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° ΡΠ° ΡΠ°Π·Π»ΠΈΠΊΡΠ²Π°ΠΌΠ΅ Π½Π°ΡΠ°ΡΠ° ΠΊΠ°ΡΡΠ° ΠΎΠ΄ Π΄ΡΡΠ³ΠΈΡΠ΅ ΠΏΠΎ Π½Π΅ΡΠ·ΠΈΠ½ΠΎΡΠΎ ΠΈΠΌΠ΅):
$ sudo bpftool map
...
114: hash name woo flags 0x0
key 4B value 4B max_entries 4 memlock 4096B
...ΠΡΠΎΡΠΎΡ 114 Π΅ Π³Π»ΠΎΠ±Π°Π»Π½ΠΈΠΎΡ ΠΏΡΠΎΠ΅ΠΊΡ Π½Π° Π½Π°ΡΠΈΠΎΡ ΠΎΠ±ΡΠ΅ΠΊΡ. Π‘Π΅ΠΊΠΎΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° Π½Π° ΡΠΈΡΡΠ΅ΠΌΠΎΡ ΠΌΠΎΠΆΠ΅ Π΄Π° Π³ΠΎ ΠΊΠΎΡΠΈΡΡΠΈ ΠΎΠ²ΠΎΡ ID Π·Π° Π΄Π° ΠΎΡΠ²ΠΎΡΠΈ ΠΏΠΎΡΡΠΎΠ΅ΡΠΊΠ° ΠΌΠ°ΠΏΠ° ΠΊΠΎΡΠΈΡΡΠ΅ΡΡΠΈ ΡΠ° ΠΊΠΎΠΌΠ°Π½Π΄Π°ΡΠ° BPF_MAP_GET_FD_BY_ID ΡΠΈΡΡΠ΅ΠΌΡΠΊΠΈ ΠΏΠΎΠ²ΠΈΠΊ bpf.
Π‘Π΅Π³Π° ΠΌΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° ΡΠΈ ΠΈΠ³ΡΠ°ΠΌΠ΅ ΡΠΎ Π½Π°ΡΠ°ΡΠ° Ρ Π°Ρ-ΡΠ°Π±Π΅Π»Π°. ΠΠ° ΡΠ° ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ Π½Π΅Π³ΠΎΠ²Π°ΡΠ° ΡΠΎΠ΄ΡΠΆΠΈΠ½Π°:
$ sudo bpftool map dump id 114
Found 0 elementsΠΡΠ°Π·Π΅Π½. ΠΡΠ΄Π΅ Π΄Π° ΡΡΠ°Π²ΠΈΠΌΠ΅ Π²ΡΠ΅Π΄Π½ΠΎΡΡ Π²ΠΎ ΡΠΎΠ° hash[1] = 1:
$ sudo bpftool map update id 114 key 1 0 0 0 value 1 0 0 0ΠΡΠ΄Π΅ ΠΏΠΎΠ²ΡΠΎΡΠ½ΠΎ Π΄Π° ΡΠ° ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ ΡΠ°Π±Π΅Π»Π°ΡΠ°:
$ sudo bpftool map dump id 114
key: 01 00 00 00 value: 01 00 00 00
Found 1 elementΠ£ΡΠ°! Π£ΡΠΏΠ΅Π°Π²ΠΌΠ΅ Π΄Π° Π΄ΠΎΠ΄Π°Π΄Π΅ΠΌΠ΅ Π΅Π΄Π΅Π½ Π΅Π»Π΅ΠΌΠ΅Π½Ρ. ΠΠ°Π±Π΅Π»Π΅ΠΆΠ΅ΡΠ΅ Π΄Π΅ΠΊΠ° ΠΌΠΎΡΠ° Π΄Π° ΡΠ°Π±ΠΎΡΠΈΠΌΠ΅ Π½Π° Π½ΠΈΠ²ΠΎ Π½Π° Π±Π°ΡΡΠΈ Π·Π° Π΄Π° Π³ΠΎ Π½Π°ΠΏΡΠ°Π²ΠΈΠΌΠ΅ ΠΎΠ²Π°, Π±ΠΈΠ΄Π΅ΡΡΠΈ bptftool Π½Π΅ Π·Π½Π°Π΅ ΠΊΠ°ΠΊΠΎΠ² ΡΠΈΠΏ ΡΠ΅ Π²ΡΠ΅Π΄Π½ΠΎΡΡΠΈΡΠ΅ Π²ΠΎ ΡΠ°Π±Π΅Π»Π°ΡΠ° Π·Π° Ρ
Π°Ρ. (ΠΠ²Π° Π·Π½Π°Π΅ΡΠ΅ ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΈ ΡΠ΅ ΠΏΡΠ΅Π½Π΅ΡΠ΅ ΡΠΎ ΠΏΠΎΠΌΠΎΡ Π½Π° BTF, Π½ΠΎ ΠΏΠΎΠ²Π΅ΡΠ΅ Π·Π° ΡΠΎΠ° ΡΠ΅Π³Π°.)
ΠΠ°ΠΊΠΎ ΡΠΎΡΠ½ΠΎ bpftool ΡΠΈΡΠ° ΠΈ Π΄ΠΎΠ΄Π°Π²Π° Π΅Π»Π΅ΠΌΠ΅Π½ΡΠΈ? ΠΡΠ΄Π΅ Π΄Π° ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ ΠΏΠΎΠ΄ Ρ Π°ΡΠ±Π°ΡΠ°:
$ sudo strace -e bpf bpftool map dump id 114
bpf(BPF_MAP_GET_FD_BY_ID, {map_id=114, next_id=0, open_flags=0}, 120) = 3
bpf(BPF_MAP_GET_NEXT_KEY, {map_fd=3, key=NULL, next_key=0x55856ab65280}, 120) = 0
bpf(BPF_MAP_LOOKUP_ELEM, {map_fd=3, key=0x55856ab65280, value=0x55856ab652a0}, 120) = 0
key: 01 00 00 00 value: 01 00 00 00
bpf(BPF_MAP_GET_NEXT_KEY, {map_fd=3, key=0x55856ab65280, next_key=0x55856ab65280}, 120) = -1 ENOENTΠΡΠ²ΠΎ ΡΠ° ΠΎΡΠ²ΠΎΡΠΈΠ²ΠΌΠ΅ ΠΌΠ°ΠΏΠ°ΡΠ° ΡΠΎ Π½Π΅ΡΠ·ΠΈΠ½ΠΈΠΎΡ Π³Π»ΠΎΠ±Π°Π»Π΅Π½ ID ΠΊΠΎΡΠΈΡΡΠ΅ΡΡΠΈ ΡΠ° ΠΊΠΎΠΌΠ°Π½Π΄Π°ΡΠ° BPF_MAP_GET_FD_BY_ID ΠΈ bpf(2) Π½ΠΈ Π³ΠΎ Π²ΡΠ°ΡΠΈ Π΄Π΅ΡΠΊΡΠΈΠΏΡΠΎΡΠΎΡ 3. ΠΠΎΠ½Π°ΡΠ°ΠΌΠΎΡΠ½ΠΎ ΠΊΠΎΡΠΈΡΡΠ΅ΡΠ΅ Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄Π°ΡΠ° BPF_MAP_GET_NEXT_KEY Π³ΠΎ Π½Π°ΡΠ΄ΠΎΠ²ΠΌΠ΅ ΠΏΡΠ²ΠΈΠΎΡ ΠΊΠ»ΡΡ Π²ΠΎ ΡΠ°Π±Π΅Π»Π°ΡΠ° ΡΠΎ ΠΏΠΎΠ»Π°Π³Π°ΡΠ΅ NULL ΠΊΠ°ΠΊΠΎ ΠΏΠΎΠΊΠ°ΠΆΡΠ²Π°Ρ Π½Π° ΠΊΠΎΠΏΡΠ΅ΡΠΎ βΠΏΡΠ΅ΡΡ
ΠΎΠ΄Π½ΠΎβ. ΠΠΊΠΎ Π³ΠΎ ΠΈΠΌΠ°ΠΌΠ΅ ΠΊΠ»ΡΡΠΎΡ, ΠΌΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° Π½Π°ΠΏΡΠ°Π²ΠΈΠΌΠ΅ BPF_MAP_LOOKUP_ELEMΠΊΠΎΡ Π²ΡΠ°ΡΠ° Π²ΡΠ΅Π΄Π½ΠΎΡΡ Π½Π° ΠΏΠΎΠΊΠ°ΠΆΡΠ²Π°ΡΠΎΡ value. Π‘Π»Π΅Π΄Π½ΠΈΠΎΡ ΡΠ΅ΠΊΠΎΡ Π΅ Π΄Π° ΡΠ΅ ΠΎΠ±ΠΈΠ΄Π΅ΠΌΠ΅ Π΄Π° Π³ΠΎ Π½Π°ΡΠ΄Π΅ΠΌΠ΅ ΡΠ»Π΅Π΄Π½ΠΈΠΎΡ Π΅Π»Π΅ΠΌΠ΅Π½Ρ ΡΠΎ ΠΏΡΠ΅Π΄Π°Π²Π°ΡΠ΅ ΠΏΠΎΠΊΠ°ΠΆΡΠ²Π°Ρ Π½Π° ΡΠ΅ΠΊΠΎΠ²Π½ΠΈΠΎΡ ΠΊΠ»ΡΡ, Π½ΠΎ Π½Π°ΡΠ°ΡΠ° ΡΠ°Π±Π΅Π»Π° ΡΠΎΠ΄ΡΠΆΠΈ ΡΠ°ΠΌΠΎ Π΅Π΄Π΅Π½ Π΅Π»Π΅ΠΌΠ΅Π½Ρ ΠΈ ΠΊΠΎΠΌΠ°Π½Π΄Π°ΡΠ° BPF_MAP_GET_NEXT_KEY ΡΠ΅ Π²ΡΠ°ΡΠ° ENOENT.
ΠΠΎΠ±ΡΠΎ, Π°ΡΠ΄Π΅ Π΄Π° ΡΠ° ΠΏΡΠΎΠΌΠ΅Π½ΠΈΠΌΠ΅ Π²ΡΠ΅Π΄Π½ΠΎΡΡΠ° ΡΠΎ ΠΊΠ»ΡΡΠΎΡ 1, Π΄Π° ΡΠ΅ΡΠ΅ΠΌΠ΅ Π΄Π΅ΠΊΠ° Π½Π°ΡΠ°ΡΠ° Π΄Π΅Π»ΠΎΠ²Π½Π° Π»ΠΎΠ³ΠΈΠΊΠ° Π±Π°ΡΠ° ΡΠ΅Π³ΠΈΡΡΡΠ°ΡΠΈΡΠ° hash[1] = 2:
$ sudo strace -e bpf bpftool map update id 114 key 1 0 0 0 value 2 0 0 0
bpf(BPF_MAP_GET_FD_BY_ID, {map_id=114, next_id=0, open_flags=0}, 120) = 3
bpf(BPF_MAP_UPDATE_ELEM, {map_fd=3, key=0x55dcd72be260, value=0x55dcd72be280, flags=BPF_ANY}, 120) = 0ΠΠ°ΠΊΠΎ ΡΡΠΎ ΡΠ΅ ΠΎΡΠ΅ΠΊΡΠ²Π°ΡΠ΅, ΡΠΎΠ° Π΅ ΠΌΠ½ΠΎΠ³Ρ Π΅Π΄Π½ΠΎΡΡΠ°Π²Π½ΠΎ: ΠΊΠΎΠΌΠ°Π½Π΄Π°ΡΠ° BPF_MAP_GET_FD_BY_ID ΡΠ° ΠΎΡΠ²ΠΎΡΠ° Π½Π°ΡΠ°ΡΠ° ΠΊΠ°ΡΡΠ° ΠΏΠΎ ID, ΠΈ ΠΊΠΎΠΌΠ°Π½Π΄Π°ΡΠ° BPF_MAP_UPDATE_ELEM Π³ΠΎ ΠΏΡΠ΅ΠΏΠΈΡΡΠ²Π° Π΅Π»Π΅ΠΌΠ΅Π½ΡΠΎΡ.
ΠΠ½Π°ΡΠΈ, ΠΎΡΠΊΠ°ΠΊΠΎ ΡΠ΅ ΠΊΡΠ΅ΠΈΡΠ°ΠΌΠ΅ Ρ Π΅Ρ-ΡΠ°Π±Π΅Π»Π° ΠΎΠ΄ Π΅Π΄Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°, ΠΌΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° ΡΠ° ΡΠΈΡΠ°ΠΌΠ΅ ΠΈ ΠΏΠΈΡΡΠ²Π°ΠΌΠ΅ Π½Π΅ΡΠ·ΠΈΠ½Π°ΡΠ° ΡΠΎΠ΄ΡΠΆΠΈΠ½Π° ΠΎΠ΄ Π΄ΡΡΠ³Π°. ΠΠ°Π±Π΅Π»Π΅ΠΆΠ΅ΡΠ΅ Π΄Π΅ΠΊΠ° Π°ΠΊΠΎ ΠΌΠΎΠΆΠ΅Π²ΠΌΠ΅ Π΄Π° Π³ΠΎ Π½Π°ΠΏΡΠ°Π²ΠΈΠΌΠ΅ ΠΎΠ²Π° ΠΎΠ΄ ΠΊΠΎΠΌΠ°Π½Π΄Π½Π°ΡΠ° Π»ΠΈΠ½ΠΈΡΠ°, ΡΠΎΠ³Π°Ρ ΠΊΠΎΡΠ° Π±ΠΈΠ»ΠΎ Π΄ΡΡΠ³Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° Π½Π° ΡΠΈΡΡΠ΅ΠΌΠΎΡ ΠΌΠΎΠΆΠ΅ Π΄Π° Π³ΠΎ Π½Π°ΠΏΡΠ°Π²ΠΈ ΡΠΎΠ°. ΠΠΎΠΊΡΠ°Ρ ΠΊΠΎΠΌΠ°Π½Π΄ΠΈΡΠ΅ ΠΎΠΏΠΈΡΠ°Π½ΠΈ ΠΏΠΎΠ³ΠΎΡΠ΅, Π·Π° ΡΠ°Π±ΠΎΡΠ° ΡΠΎ ΠΌΠ°ΠΏΠΈ ΠΎΠ΄ ΠΊΠΎΡΠΈΡΠ½ΠΈΡΠΊΠΈΠΎΡ ΠΏΡΠΎΡΡΠΎΡ, :
BPF_MAP_LOOKUP_ELEM: Π½Π°ΡΠ΄Π΅ΡΠ΅ Π²ΡΠ΅Π΄Π½ΠΎΡΡ ΠΏΠΎ ΠΊΠ»ΡΡBPF_MAP_UPDATE_ELEM: Π°ΠΆΡΡΠΈΡΠ°ΡΠ΅/ΡΠΎΠ·Π΄Π°Π΄Π΅ΡΠ΅ Π²ΡΠ΅Π΄Π½ΠΎΡΡBPF_MAP_DELETE_ELEM: ΠΈΠ·Π²Π°Π΄Π΅ΡΠ΅ Π³ΠΎ ΠΊΠ»ΡΡΠΎΡBPF_MAP_GET_NEXT_KEY: Π½Π°ΡΠ΄Π΅ΡΠ΅ Π³ΠΎ ΡΠ»Π΅Π΄Π½ΠΈΠΎΡ (ΠΈΠ»ΠΈ ΠΏΡΠ²ΠΈΠΎΡ) ΠΊΠ»ΡΡBPF_MAP_GET_NEXT_ID: Π²ΠΈ ΠΎΠ²ΠΎΠ·ΠΌΠΎΠΆΡΠ²Π° Π΄Π° Π³ΠΈ ΠΏΠΎΠΌΠΈΠ½Π΅ΡΠ΅ ΡΠΈΡΠ΅ ΠΏΠΎΡΡΠΎΠ΅ΡΠΊΠΈ ΠΌΠ°ΠΏΠΈ, ΡΠ°ΠΊΠ° ΡΡΠ½ΠΊΡΠΈΠΎΠ½ΠΈΡΠ°bpftool mapBPF_MAP_GET_FD_BY_ID: ΠΎΡΠ²ΠΎΡΠ΅ΡΠ΅ ΠΏΠΎΡΡΠΎΠ΅ΡΠΊΠ° ΠΊΠ°ΡΡΠ° ΡΠΏΠΎΡΠ΅Π΄ Π½Π΅ΡΠ·ΠΈΠ½ΠΈΠΎΡ Π³Π»ΠΎΠ±Π°Π»Π΅Π½ IDBPF_MAP_LOOKUP_AND_DELETE_ELEM: Π°ΡΠΎΠΌΡΠΊΠΈ Π°ΠΆΡΡΠΈΡΠ°ΡΡΠ΅ ΡΠ° Π²ΡΠ΅Π΄Π½ΠΎΡΡΠ° Π½Π° ΠΎΠ±ΡΠ΅ΠΊΡΠΎΡ ΠΈ Π²ΡΠ°ΡΠ΅ΡΠ΅ ΡΠ° ΡΡΠ°ΡΠ°ΡΠ°BPF_MAP_FREEZE: Π½Π°ΠΏΡΠ°Π²Π΅ΡΠ΅ ΡΠ° ΠΊΠ°ΡΡΠ°ΡΠ° Π½Π΅ΠΏΡΠΎΠΌΠ΅Π½Π»ΠΈΠ²Π° ΠΎΠ΄ ΠΊΠΎΡΠΈΡΠ½ΠΈΡΠΊΠΈΠΎΡ ΠΏΡΠΎΡΡΠΎΡ (ΠΎΠ²Π°Π° ΠΎΠΏΠ΅ΡΠ°ΡΠΈΡΠ° Π½Π΅ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ Π²ΡΠ°ΡΠΈ)BPF_MAP_LOOKUP_BATCH,BPF_MAP_LOOKUP_AND_DELETE_BATCH,BPF_MAP_UPDATE_BATCH,BPF_MAP_DELETE_BATCH: ΠΌΠ°ΡΠΎΠ²Π½ΠΈ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ. ΠΠ° ΠΏΡΠΈΠΌΠ΅Ρ,BPF_MAP_LOOKUP_AND_DELETE_BATCH- ΠΎΠ²Π° Π΅ Π΅Π΄ΠΈΠ½ΡΡΠ²Π΅Π½ΠΈΠΎΡ ΡΠΈΠ³ΡΡΠ΅Π½ Π½Π°ΡΠΈΠ½ Π·Π° ΡΠΈΡΠ°ΡΠ΅ ΠΈ ΡΠ΅ΡΠ΅ΡΠΈΡΠ°ΡΠ΅ Π½Π° ΡΠΈΡΠ΅ Π²ΡΠ΅Π΄Π½ΠΎΡΡΠΈ ΠΎΠ΄ ΠΊΠ°ΡΡΠ°ΡΠ°
ΠΠ΅ ΡΠΈΡΠ΅ ΠΎΠ²ΠΈΠ΅ ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ ΡΠ°Π±ΠΎΡΠ°Ρ Π·Π° ΡΠΈΡΠ΅ ΡΠΈΠΏΠΎΠ²ΠΈ ΠΌΠ°ΠΏΠΈ, Π½ΠΎ Π³Π΅Π½Π΅ΡΠ°Π»Π½ΠΎ ΡΠ°Π±ΠΎΡΠ°ΡΠ° ΡΠΎ Π΄ΡΡΠ³ΠΈ ΡΠΈΠΏΠΎΠ²ΠΈ Π½Π° ΠΌΠ°ΠΏΠΈ ΠΎΠ΄ ΠΊΠΎΡΠΈΡΠ½ΠΈΡΠΊΠΈΠΎΡ ΠΏΡΠΎΡΡΠΎΡ ΠΈΠ·Π³Π»Π΅Π΄Π° ΡΠΎΡΠ΅ΠΌΠ° ΠΈΡΡΠΎ ΠΊΠ°ΠΊΠΎ ΠΈ ΡΠ°Π±ΠΎΡΠ°ΡΠ° ΡΠΎ Ρ Π°Ρ ΡΠ°Π±Π΅Π»ΠΈ.
ΠΠ° ΡΠ΅Π΄, Π΄Π° Π³ΠΈ Π·Π°Π²ΡΡΠΈΠΌΠ΅ Π½Π°ΡΠΈΡΠ΅ Π΅ΠΊΡΠΏΠ΅ΡΠΈΠΌΠ΅Π½ΡΠΈ ΡΠΎ Ρ Π΅Ρ-ΡΠ°Π±Π΅Π»Π°. ΠΠ°ΠΏΠΎΠΌΠ½Π΅ΡΠ΅ Π΄Π΅ΠΊΠ° ΡΠΎΠ·Π΄Π°Π΄ΠΎΠ²ΠΌΠ΅ ΡΠ°Π±Π΅Π»Π° ΡΡΠΎ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠΎΠ΄ΡΠΆΠΈ Π΄ΠΎ ΡΠ΅ΡΠΈΡΠΈ ΠΊΠ»ΡΡΠ΅Π²ΠΈ? ΠΡΠ΄Π΅ Π΄Π° Π΄ΠΎΠ΄Π°Π΄Π΅ΠΌΠ΅ ΡΡΡΠ΅ Π½Π΅ΠΊΠΎΠ»ΠΊΡ Π΅Π»Π΅ΠΌΠ΅Π½ΡΠΈ:
$ sudo bpftool map update id 114 key 2 0 0 0 value 1 0 0 0
$ sudo bpftool map update id 114 key 3 0 0 0 value 1 0 0 0
$ sudo bpftool map update id 114 key 4 0 0 0 value 1 0 0 0ΠΠΎΡΠ΅Π³Π° Π΄ΠΎΠ±ΡΠΎ:
$ sudo bpftool map dump id 114
key: 01 00 00 00 value: 01 00 00 00
key: 02 00 00 00 value: 01 00 00 00
key: 04 00 00 00 value: 01 00 00 00
key: 03 00 00 00 value: 01 00 00 00
Found 4 elementsΠΡΠ΄Π΅ Π΄Π° ΡΠ΅ ΠΎΠ±ΠΈΠ΄Π΅ΠΌΠ΅ Π΄Π° Π΄ΠΎΠ΄Π°Π΄Π΅ΠΌΠ΅ ΡΡΡΠ΅ Π΅Π΄Π΅Π½:
$ sudo bpftool map update id 114 key 5 0 0 0 value 1 0 0 0
Error: update failed: Argument list too longΠΡΠ΅ΠΊΡΠ²Π°Π½ΠΎ Π½Π΅ ΡΡΠΏΠ΅Π°Π²ΠΌΠ΅. ΠΡΠ΄Π΅ Π΄Π° ΡΠ° ΡΠ°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ Π³ΡΠ΅ΡΠΊΠ°ΡΠ° ΠΏΠΎΠ΄Π΅ΡΠ°Π»Π½ΠΎ:
$ sudo strace -e bpf bpftool map update id 114 key 5 0 0 0 value 1 0 0 0
bpf(BPF_MAP_GET_FD_BY_ID, {map_id=114, next_id=0, open_flags=0}, 120) = 3
bpf(BPF_OBJ_GET_INFO_BY_FD, {info={bpf_fd=3, info_len=80, info=0x7ffe6c626da0}}, 120) = 0
bpf(BPF_MAP_UPDATE_ELEM, {map_fd=3, key=0x56049ded5260, value=0x56049ded5280, flags=BPF_ANY}, 120) = -1 E2BIG (Argument list too long)
Error: update failed: Argument list too long
+++ exited with 255 +++Π‘Γ¨ Π΅ Π²ΠΎ ΡΠ΅Π΄: ΠΎΡΠ΅ΠΊΡΠ²Π°Π½ΠΎ, ΡΠΈΠΌΠΎΡ BPF_MAP_UPDATE_ELEM ΡΠ΅ ΠΎΠ±ΠΈΠ΄ΡΠ²Π° Π΄Π° ΡΠΎΠ·Π΄Π°Π΄Π΅ Π½ΠΎΠ², ΠΏΠ΅ΡΡΠΈ, ΠΊΠ»ΡΡ, Π½ΠΎ ΠΏΠ°ΡΠ° E2BIG.
ΠΠ½Π°ΡΠΈ, ΠΌΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° ΠΊΡΠ΅ΠΈΡΠ°ΠΌΠ΅ ΠΈ Π²ΡΠΈΡΠ°ΠΌΠ΅ BPF ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ, ΠΊΠ°ΠΊΠΎ ΠΈ Π΄Π° ΠΊΡΠ΅ΠΈΡΠ°ΠΌΠ΅ ΠΈ ΡΠΏΡΠ°Π²ΡΠ²Π°ΠΌΠ΅ ΡΠΎ ΠΌΠ°ΠΏΠΈ ΠΎΠ΄ ΠΊΠΎΡΠΈΡΠ½ΠΈΡΠΊΠΈΠΎΡ ΠΏΡΠΎΡΡΠΎΡ. Π‘Π΅Π³Π° Π΅ Π»ΠΎΠ³ΠΈΡΠ½ΠΎ Π΄Π° ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ ΠΊΠ°ΠΊΠΎ ΠΌΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° ΠΊΠΎΡΠΈΡΡΠΈΠΌΠ΅ ΠΌΠ°ΠΏΠΈ ΠΎΠ΄ ΡΠ°ΠΌΠΈΡΠ΅ BPF ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ. ΠΠΈ ΠΌΠΎΠΆΠ΅Π»Π΅ Π΄Π° Π·Π±ΠΎΡΡΠ²Π°ΠΌΠ΅ Π·Π° ΠΎΠ²Π° Π½Π° ΡΠ°Π·ΠΈΠΊΠΎΡ Π½Π° ΡΠ΅ΡΠΊΠΎ ΡΠΈΡΠ»ΠΈΠ²ΠΈΡΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ Π²ΠΎ ΠΌΠ°ΡΠΈΠ½ΡΠΊΠΈΡΠ΅ ΠΌΠ°ΠΊΡΠΎ ΠΊΠΎΠ΄ΠΎΠ²ΠΈ, Π½ΠΎ Π²ΡΡΡΠ½ΠΎΡΡ Π΄ΠΎΡΠ΄Π΅ Π²ΡΠ΅ΠΌΠ΅ Π΄Π° ΠΏΠΎΠΊΠ°ΠΆΠ΅ΠΌΠ΅ ΠΊΠ°ΠΊΠΎ Π²ΡΡΡΠ½ΠΎΡΡ ΡΠ΅ ΠΏΠΈΡΡΠ²Π°Π°Ρ ΠΈ ΠΎΠ΄ΡΠΆΡΠ²Π°Π°Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ΅ BPF - ΠΊΠΎΡΠΈΡΡΠ΅ΡΡΠΈ libbpf.
(ΠΠ° ΡΠΈΡΠ°ΡΠ΅Π»ΠΈΡΠ΅ ΠΊΠΎΠΈ ΡΠ΅ Π½Π΅Π·Π°Π΄ΠΎΠ²ΠΎΠ»Π½ΠΈ ΠΎΠ΄ Π½Π΅Π΄ΠΎΡΡΠ°ΡΠΎΠΊΠΎΡ Π½Π° ΠΏΡΠΈΠΌΠ΅Ρ Π½Π° Π½ΠΈΡΠΊΠΎ Π½ΠΈΠ²ΠΎ: Π΄Π΅ΡΠ°Π»Π½ΠΎ ΡΠ΅ Π³ΠΈ Π°Π½Π°Π»ΠΈΠ·ΠΈΡΠ°ΠΌΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ΅ ΡΡΠΎ ΠΊΠΎΡΠΈΡΡΠ°Ρ ΠΌΠ°ΠΏΠΈ ΠΈ ΡΡΠ½ΠΊΡΠΈΠΈ Π·Π° ΠΏΠΎΠΌΠΎΡ ΡΠΎΠ·Π΄Π°Π΄Π΅Π½ΠΈ ΡΠΎ libbpf ΠΈ Π΄Π° Π²ΠΈ ΠΊΠ°ΠΆΠ΅ ΡΡΠΎ ΡΠ΅ ΡΠ»ΡΡΡΠ²Π° Π½Π° Π½ΠΈΠ²ΠΎ Π½Π° ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈ. ΠΠ° ΡΠΈΡΠ°ΡΠ΅Π»ΠΈΡΠ΅ ΠΊΠΎΠΈ ΡΠ΅ Π½Π΅Π·Π°Π΄ΠΎΠ²ΠΎΠ»Π½ΠΈ ΠΌΠ½ΠΎΠ³Ρ, Π΄ΠΎΠ΄Π°Π΄ΠΎΠ²ΠΌΠ΅ Π½Π° ΡΠΎΠΎΠ΄Π²Π΅ΡΠ½ΠΎΡΠΎ ΠΌΠ΅ΡΡΠΎ Π²ΠΎ ΡΡΠ°ΡΠΈΡΠ°ΡΠ°.)
ΠΠΈΡΡΠ²Π°ΡΠ΅ BPF ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ ΠΊΠΎΡΠΈΡΡΠ΅ΡΡΠΈ libbpf
ΠΠΈΡΡΠ²Π°ΡΠ΅ΡΠΎ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ Π·Π° BPF ΡΠΎ ΠΏΠΎΠΌΠΎΡ Π½Π° ΠΌΠ°ΡΠΈΠ½ΡΠΊΠΈ ΠΊΠΎΠ΄ΠΎΠ²ΠΈ ΠΌΠΎΠΆΠ΅ Π΄Π° Π±ΠΈΠ΄Π΅ ΠΈΠ½ΡΠ΅ΡΠ΅ΡΠ½ΠΎ ΡΠ°ΠΌΠΎ ΠΏΡΠ²ΠΈΠΎΡ ΠΏΠ°Ρ, Π° ΠΏΠΎΡΠΎΠ° Π½Π°ΡΡΠ°Π½ΡΠ²Π° ΡΠΈΡΠΎΡΡ. ΠΠΎ ΠΎΠ²ΠΎΡ ΠΌΠΎΠΌΠ΅Π½Ρ ΡΡΠ΅Π±Π° Π΄Π° Π³ΠΎ ΡΠ²ΡΡΠΈΡΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ΡΠΎ ΠΊΠΎΠ½ llvm, ΠΊΠΎΡ ΠΈΠΌΠ° Π±Π΅ΠΊΠ΅Π½Π΄ Π·Π° Π³Π΅Π½Π΅ΡΠΈΡΠ°ΡΠ΅ ΠΊΠΎΠ΄ Π·Π° Π°ΡΡ
ΠΈΡΠ΅ΠΊΡΡΡΠ°ΡΠ° BPF, ΠΊΠ°ΠΊΠΎ ΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° libbpf, ΠΊΠΎΡ Π²ΠΈ ΠΎΠ²ΠΎΠ·ΠΌΠΎΠΆΡΠ²Π° Π΄Π° ΡΠ° Π½Π°ΠΏΠΈΡΠ΅ΡΠ΅ ΠΊΠΎΡΠΈΡΠ½ΠΈΡΠΊΠ°ΡΠ° ΡΡΡΠ°Π½Π° Π½Π° Π°ΠΏΠ»ΠΈΠΊΠ°ΡΠΈΠΈΡΠ΅ BPF ΠΈ Π΄Π° Π³ΠΎ Π²ΡΠΈΡΠ°ΡΠ΅ ΠΊΠΎΠ΄ΠΎΡ Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ΅ BPF Π³Π΅Π½Π΅ΡΠΈΡΠ°Π½ΠΈ ΡΠΎ ΠΊΠΎΡΠΈΡΡΠ΅ΡΠ΅ llvm/clang.
ΠΡΡΡΠ½ΠΎΡΡ, ΠΊΠ°ΠΊΠΎ ΡΡΠΎ ΡΠ΅ Π²ΠΈΠ΄ΠΈΠΌΠ΅ Π²ΠΎ ΠΎΠ²Π°Π° ΠΈ ΡΠ»Π΅Π΄Π½ΠΈΡΠ΅ Π½Π°ΠΏΠΈΡΠΈ, libbpf ΠΏΡΠ°Π²ΠΈ Π΄ΠΎΡΡΠ° ΡΠ°Π±ΠΎΡΠ° Π±Π΅Π· Π½Π΅Π³ΠΎ (ΠΈΠ»ΠΈ ΡΠ»ΠΈΡΠ½ΠΈ Π°Π»Π°ΡΠΊΠΈ - iproute2, libbcc, libbpf-go, ΠΈΡΠ½.) Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ Π΅ Π΄Π° ΡΠ΅ ΠΆΠΈΠ²Π΅Π΅. ΠΠ΄Π½Π° ΠΎΠ΄ ΡΠ±ΠΈΡΡΠ²Π΅Π½ΠΈΡΠ΅ ΠΊΠ°ΡΠ°ΠΊΡΠ΅ΡΠΈΡΡΠΈΠΊΠΈ Π½Π° ΠΏΡΠΎΠ΅ΠΊΡΠΎΡ libbpf Π΅ BPF CO-RE (Compile Once, Run Everywhere) - ΠΏΡΠΎΠ΅ΠΊΡ ΠΊΠΎΡ Π²ΠΈ ΠΎΠ²ΠΎΠ·ΠΌΠΎΠΆΡΠ²Π° Π΄Π° ΠΏΠΈΡΡΠ²Π°ΡΠ΅ BPF ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ ΠΊΠΎΠΈ ΡΠ΅ ΠΏΡΠ΅Π½ΠΎΡΠ»ΠΈΠ²ΠΈ ΠΎΠ΄ Π΅Π΄Π½ΠΎ ΠΊΠ΅ΡΠ½Π΅Π» Π΄ΠΎ Π΄ΡΡΠ³ΠΎ, ΡΠΎ ΠΌΠΎΠΆΠ½ΠΎΡΡ Π΄Π° ΡΠ°Π±ΠΎΡΠ°Ρ Π½Π° ΡΠ°Π·Π»ΠΈΡΠ½ΠΈ API (Π½Π° ΠΏΡΠΈΠΌΠ΅Ρ, ΠΊΠΎΠ³Π° ΡΡΡΡΠΊΡΡΡΠ°ΡΠ° Π½Π° ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ ΡΠ΅ ΠΌΠ΅Π½ΡΠ²Π° ΠΎΠ΄ Π²Π΅ΡΠ·ΠΈΡΠ°ΡΠ° Π΄ΠΎ Π²Π΅ΡΠ·ΠΈΡΠ°). ΠΠ° Π΄Π° ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΡΠ°Π±ΠΎΡΠΈΡΠ΅ ΡΠΎ CO-RE, Π²Π°ΡΠΈΠΎΡ ΠΊΠ΅ΡΠ½Π΅Π» ΠΌΠΎΡΠ° Π΄Π° Π±ΠΈΠ΄Π΅ ΠΊΠΎΠΌΠΏΠ°ΡΠ»ΠΈΡΠ°Π½ ΡΠΎ ΠΏΠΎΠ΄Π΄ΡΡΠΊΠ° Π·Π° BTF (Π½ΠΈΠ΅ ΠΎΠΏΠΈΡΡΠ²Π°ΠΌΠ΅ ΠΊΠ°ΠΊΠΎ Π΄Π° Π³ΠΎ Π½Π°ΠΏΡΠ°Π²ΠΈΡΠ΅ ΠΎΠ²Π° Π²ΠΎ Π΄Π΅Π»ΠΎΡ . ΠΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΠΏΡΠΎΠ²Π΅ΡΠΈΡΠ΅ Π΄Π°Π»ΠΈ Π²Π°ΡΠΈΠΎΡ ΠΊΠ΅ΡΠ½Π΅Π» Π΅ ΠΈΠ·Π³ΡΠ°Π΄Π΅Π½ ΡΠΎ BTF ΠΈΠ»ΠΈ Π½Π΅ ΠΌΠ½ΠΎΠ³Ρ Π΅Π΄Π½ΠΎΡΡΠ°Π²Π½ΠΎ - ΡΠΎ ΠΏΡΠΈΡΡΡΡΠ²ΠΎ Π½Π° ΡΠ»Π΅Π΄Π½Π°Π²Π° Π΄Π°ΡΠΎΡΠ΅ΠΊΠ°:
$ ls -lh /sys/kernel/btf/vmlinux
-r--r--r-- 1 root root 2.6M Jul 29 15:30 /sys/kernel/btf/vmlinuxΠΠ²Π°Π° Π΄Π°ΡΠΎΡΠ΅ΠΊΠ° ΡΠΊΠ»Π°Π΄ΠΈΡΠ° ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΠΈ Π·Π° ΡΠΈΡΠ΅ ΡΠΈΠΏΠΎΠ²ΠΈ ΠΏΠΎΠ΄Π°ΡΠΎΡΠΈ ΡΡΠΎ ΡΠ΅ ΠΊΠΎΡΠΈΡΡΠ°Ρ Π²ΠΎ ΡΠ°Π΄ΡΠΎΡΠΎ ΠΈ ΡΠ΅ ΠΊΠΎΡΠΈΡΡΠΈ Π²ΠΎ ΡΠΈΡΠ΅ Π½Π°ΡΠΈ ΠΏΡΠΈΠΌΠ΅ΡΠΈ ΡΠΎ ΠΊΠΎΡΠΈΡΡΠ΅ΡΠ΅ libbpf. ΠΠ΅ Π·Π±ΠΎΡΡΠ²Π°ΠΌΠ΅ Π΄Π΅ΡΠ°Π»Π½ΠΎ Π·Π° CO-RE Π²ΠΎ ΡΠ»Π΅Π΄Π½Π°ΡΠ° ΡΡΠ°ΡΠΈΡΠ°, Π½ΠΎ Π²ΠΎ ΠΎΠ²Π°Π° - ΡΠ°ΠΌΠΎ ΠΈΠ·Π³ΡΠ°Π΄ΠΈ ΡΠΈ ΡΠ°Π΄ΡΠΎ ΡΠΎ CONFIG_DEBUG_INFO_BTF.
ΠΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° libbpf ΠΆΠΈΠ²Π΅Π΅ ΠΏΡΠ°Π²ΠΎ Π²ΠΎ Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΡΠΌΠΎΡ tools/lib/bpf ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ ΠΈ Π½Π΅Π³ΠΎΠ²ΠΈΠΎΡ ΡΠ°Π·Π²ΠΎΡ ΡΠ΅ Π²ΡΡΠΈ ΠΏΡΠ΅ΠΊΡ ΠΌΠ΅ΡΠ»ΠΈΠ½Π³ Π»ΠΈΡΡΠ°ΡΠ° bpf@vger.kernel.org. Π‘Π΅ΠΏΠ°ΠΊ, ΡΠ΅ ΠΎΠ΄ΡΠΆΡΠ²Π° ΠΏΠΎΡΠ΅Π±Π½ΠΎ ΡΠΊΠ»Π°Π΄ΠΈΡΡΠ΅ Π·Π° ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅ Π½Π° Π°ΠΏΠ»ΠΈΠΊΠ°ΡΠΈΠΈΡΠ΅ ΠΊΠΎΠΈ ΠΆΠΈΠ²Π΅Π°Ρ Π½Π°Π΄Π²ΠΎΡ ΠΎΠ΄ ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ Π²ΠΎ ΠΊΠΎΡΠ° Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ°ΡΠ° Π½Π° ΡΠ°Π΄ΡΠΎΡΠΎ Π΅ ΠΏΡΠ΅ΡΠ»ΠΈΠΊΠ°Π½Π° Π·Π° ΠΏΡΠΈΡΡΠ°ΠΏ Π·Π° ΡΠΈΡΠ°ΡΠ΅ ΠΏΠΎΠ²Π΅ΡΠ΅ ΠΈΠ»ΠΈ ΠΏΠΎΠΌΠ°Π»ΠΊΡ ΠΊΠ°ΠΊΠΎ ΡΡΠΎ Π΅.
ΠΠΎ ΠΎΠ²ΠΎΡ Π΄Π΅Π» ΡΠ΅ ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ ΠΊΠ°ΠΊΠΎ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΠΊΡΠ΅ΠΈΡΠ°ΡΠ΅ ΠΏΡΠΎΠ΅ΠΊΡ ΡΡΠΎ ΠΊΠΎΡΠΈΡΡΠΈ libbpf, Π΄Π° Π½Π°ΠΏΠΈΡΠ΅ΠΌΠ΅ Π½Π΅ΠΊΠΎΠ»ΠΊΡ (ΠΏΠΎΠ²Π΅ΡΠ΅ ΠΈΠ»ΠΈ ΠΏΠΎΠΌΠ°Π»ΠΊΡ Π±Π΅ΡΠΌΠΈΡΠ»Π΅Π½ΠΈ) ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ Π·Π° ΡΠ΅ΡΡΠΈΡΠ°ΡΠ΅ ΠΈ Π΄Π΅ΡΠ°Π»Π½ΠΎ Π΄Π° Π°Π½Π°Π»ΠΈΠ·ΠΈΡΠ°ΠΌΠ΅ ΠΊΠ°ΠΊΠΎ ΡΡΠ½ΠΊΡΠΈΠΎΠ½ΠΈΡΠ° ΡΠ΅ΡΠΎ ΡΠΎΠ°. ΠΠ²Π° ΡΠ΅ Π½ΠΈ ΠΎΠ²ΠΎΠ·ΠΌΠΎΠΆΠΈ ΠΏΠΎΠ»Π΅ΡΠ½ΠΎ Π΄Π° ΠΎΠ±ΡΠ°ΡΠ½ΠΈΠΌΠ΅ Π²ΠΎ ΡΠ»Π΅Π΄Π½ΠΈΡΠ΅ Π΄Π΅Π»ΠΎΠ²ΠΈ ΡΠΎΡΠ½ΠΎ ΠΊΠ°ΠΊΠΎ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ΅ BPF ΠΊΠΎΠΌΡΠ½ΠΈΡΠΈΡΠ°Π°Ρ ΡΠΎ ΠΌΠ°ΠΏΠΈ, ΠΏΠΎΠΌΠ°Π³Π°ΡΠΈ Π½Π° ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ, BTF ΠΈΡΠ½.
ΠΠ±ΠΈΡΠ½ΠΎ ΠΏΡΠΎΠ΅ΠΊΡΠΈ ΠΊΠΎΡΠΈΡΡΠ°Ρ libbpf Π΄ΠΎΠ΄Π°Π΄Π΅ΡΠ΅ ΡΠΊΠ»Π°Π΄ΠΈΡΡΠ΅ Π½Π° GitHub ΠΊΠ°ΠΊΠΎ ΠΏΠΎΠ΄ΠΌΠΎΠ΄ΡΠ» Π·Π° git, Π½ΠΈΠ΅ ΡΠ΅ Π³ΠΎ ΡΡΠΎΡΠΈΠΌΠ΅ ΠΈΡΡΠΎΡΠΎ:
$ mkdir /tmp/libbpf-example
$ cd /tmp/libbpf-example/
$ git init-db
Initialized empty Git repository in /tmp/libbpf-example/.git/
$ git submodule add https://github.com/libbpf/libbpf.git
Cloning into '/tmp/libbpf-example/libbpf'...
remote: Enumerating objects: 200, done.
remote: Counting objects: 100% (200/200), done.
remote: Compressing objects: 100% (103/103), done.
remote: Total 3354 (delta 101), reused 118 (delta 79), pack-reused 3154
Receiving objects: 100% (3354/3354), 2.05 MiB | 10.22 MiB/s, done.
Resolving deltas: 100% (2176/2176), done.ΠΠ΄Π΅ΡΠ΅ Π½Π° libbpf ΠΌΠ½ΠΎΠ³Ρ Π΅Π΄Π½ΠΎΡΡΠ°Π²Π½ΠΎ:
$ cd libbpf/src
$ mkdir build
$ OBJDIR=build DESTDIR=root make -s install
$ find root
root
root/usr
root/usr/include
root/usr/include/bpf
root/usr/include/bpf/bpf_tracing.h
root/usr/include/bpf/xsk.h
root/usr/include/bpf/libbpf_common.h
root/usr/include/bpf/bpf_endian.h
root/usr/include/bpf/bpf_helpers.h
root/usr/include/bpf/btf.h
root/usr/include/bpf/bpf_helper_defs.h
root/usr/include/bpf/bpf.h
root/usr/include/bpf/libbpf_util.h
root/usr/include/bpf/libbpf.h
root/usr/include/bpf/bpf_core_read.h
root/usr/lib64
root/usr/lib64/libbpf.so.0.1.0
root/usr/lib64/libbpf.so.0
root/usr/lib64/libbpf.a
root/usr/lib64/libbpf.so
root/usr/lib64/pkgconfig
root/usr/lib64/pkgconfig/libbpf.pcΠΠ°ΡΠΈΠΎΡ ΡΠ»Π΅Π΄Π΅Π½ ΠΏΠ»Π°Π½ Π²ΠΎ ΠΎΠ²ΠΎΡ Π΄Π΅Π» Π΅ ΠΊΠ°ΠΊΠΎ ΡΡΠΎ ΡΠ»Π΅Π΄ΡΠ²Π°: ΡΠ΅ Π½Π°ΠΏΠΈΡΠ΅ΠΌΠ΅ BPF ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° ΠΊΠ°ΠΊΠΎ BPF_PROG_TYPE_XDP, ΠΈΡΡΠΎ ΠΊΠ°ΠΊΠΎ ΠΈ Π²ΠΎ ΠΏΡΠ΅ΡΡ
ΠΎΠ΄Π½ΠΈΠΎΡ ΠΏΡΠΈΠΌΠ΅Ρ, Π½ΠΎ Π²ΠΎ C, Π³ΠΎ ΠΊΠΎΠΌΠΏΠ°ΡΠ»ΠΈΡΠ°ΠΌΠ΅ ΠΊΠΎΡΠΈΡΡΠ΅ΡΡΠΈ clang, ΠΈ Π½Π°ΠΏΠΈΡΠ΅ΡΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° Π·Π° ΠΏΠΎΠΌΠΎΡ ΠΊΠΎΡΠ° ΡΠ΅ ΡΠ° Π²ΡΠΈΡΠ° Π²ΠΎ ΡΠ°Π΄ΡΠΎΡΠΎ. ΠΠΎ ΡΠ»Π΅Π΄Π½ΠΈΡΠ΅ Π΄Π΅Π»ΠΎΠ²ΠΈ ΡΠ΅ Π³ΠΈ ΠΏΡΠΎΡΠΈΡΠΈΠΌΠ΅ ΠΌΠΎΠΆΠ½ΠΎΡΡΠΈΡΠ΅ ΠΈ Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° BPF ΠΈ Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° Π·Π° ΠΏΠΎΠΌΠΎΡΠ½ΠΈΠΊ.
ΠΡΠΈΠΌΠ΅Ρ: ΡΠΎΠ·Π΄Π°Π²Π°ΡΠ΅ Π½Π° ΠΏΠΎΠ»Π½ΠΎΠΏΡΠ°Π²Π½Π° Π°ΠΏΠ»ΠΈΠΊΠ°ΡΠΈΡΠ° ΠΊΠΎΡΠΈΡΡΠ΅ΡΡΠΈ libbpf
ΠΠ° ΠΏΠΎΡΠ΅ΡΠΎΠΊ, ΡΠ° ΠΊΠΎΡΠΈΡΡΠΈΠΌΠ΅ Π΄Π°ΡΠΎΡΠ΅ΠΊΠ°ΡΠ° /sys/kernel/btf/vmlinux, ΡΡΠΎ Π±Π΅ΡΠ΅ ΡΠΏΠΎΠΌΠ΅Π½Π°ΡΠΎ ΠΏΠΎΠ³ΠΎΡΠ΅, ΠΈ ΠΊΡΠ΅ΠΈΡΠ°ΡΡΠ΅ Π³ΠΎ Π½Π΅Π³ΠΎΠ²ΠΈΠΎΡ Π΅ΠΊΠ²ΠΈΠ²Π°Π»Π΅Π½Ρ Π²ΠΎ ΡΠΎΡΠΌΠ° Π½Π° Π΄Π°ΡΠΎΡΠ΅ΠΊΠ° Π·Π° Π·Π°Π³Π»Π°Π²ΠΈΠ΅:
$ bpftool btf dump file /sys/kernel/btf/vmlinux format c > vmlinux.hΠΠ²Π°Π° Π΄Π°ΡΠΎΡΠ΅ΠΊΠ° ΡΠ΅ Π³ΠΈ ΡΠΊΠ»Π°Π΄ΠΈΡΠ° ΡΠΈΡΠ΅ ΡΡΡΡΠΊΡΡΡΠΈ Π½Π° ΠΏΠΎΠ΄Π°ΡΠΎΡΠΈ Π΄ΠΎΡΡΠ°ΠΏΠ½ΠΈ Π²ΠΎ Π½Π°ΡΠΈΠΎΡ ΠΊΠ΅ΡΠ½Π΅Π», Π½Π° ΠΏΡΠΈΠΌΠ΅Ρ, Π²Π°ΠΊΠ° ΡΠ΅ Π΄Π΅ΡΠΈΠ½ΠΈΡΠ° Π·Π°Π³Π»Π°Π²ΠΈΠ΅ΡΠΎ IPv4 Π²ΠΎ ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ:
$ grep -A 12 'struct iphdr {' vmlinux.h
struct iphdr {
__u8 ihl: 4;
__u8 version: 4;
__u8 tos;
__be16 tot_len;
__be16 id;
__be16 frag_off;
__u8 ttl;
__u8 protocol;
__sum16 check;
__be32 saddr;
__be32 daddr;
};Π‘Π΅Π³Π° ΡΠ΅ ΡΠ° Π½Π°ΠΏΠΈΡΠ΅ΠΌΠ΅ Π½Π°ΡΠ°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° BPF Π²ΠΎ C:
$ cat xdp-simple.bpf.c
#include "vmlinux.h"
#include <bpf/bpf_helpers.h>
SEC("xdp/simple")
int simple(void *ctx)
{
return XDP_PASS;
}
char LICENSE[] SEC("license") = "GPL";ΠΠ°ΠΊΠΎ Π½Π°ΡΠ°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° ΡΠ΅ ΠΏΠΎΠΊΠ°ΠΆΠ° ΠΊΠ°ΠΊΠΎ ΠΌΠ½ΠΎΠ³Ρ Π΅Π΄Π½ΠΎΡΡΠ°Π²Π½Π°, ΡΠ΅ΠΏΠ°ΠΊ ΡΡΠ΅Π±Π° Π΄Π° ΠΎΠ±ΡΠ½Π΅ΠΌΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° ΠΌΠ½ΠΎΠ³Ρ Π΄Π΅ΡΠ°Π»ΠΈ. ΠΡΠ²ΠΎ, ΠΏΡΠ²Π°ΡΠ° Π΄Π°ΡΠΎΡΠ΅ΠΊΠ° ΡΠΎ Π·Π°Π³Π»Π°Π²ΠΈΠ΅ ΡΡΠΎ ΡΠ° Π²ΠΊΠ»ΡΡΡΠ²Π°ΠΌΠ΅ Π΅ vmlinux.h, ΠΊΠΎΡ ΡΡΠΎΡΡΠΊΡ Π³ΠΎ Π³Π΅Π½Π΅ΡΠΈΡΠ°Π²ΠΌΠ΅ ΠΊΠΎΡΠΈΡΡΠ΅ΡΡΠΈ Π³ΠΎ bpftool btf dump - ΡΠ΅Π³Π° Π½Π΅ ΡΡΠ΅Π±Π° Π΄Π° Π³ΠΎ ΠΈΠ½ΡΡΠ°Π»ΠΈΡΠ°ΠΌΠ΅ ΠΏΠ°ΠΊΠ΅ΡΠΎΡ ΠΊΠ΅ΡΠ½Π΅Π»-Π·Π°Π³Π»Π°Π²ΠΈΡΠ° Π·Π° Π΄Π° Π΄ΠΎΠ·Π½Π°Π΅ΠΌΠ΅ ΠΊΠ°ΠΊΠΎ ΠΈΠ·Π³Π»Π΅Π΄Π°Π°Ρ ΡΡΡΡΠΊΡΡΡΠΈΡΠ΅ Π½Π° ΡΠ°Π΄ΡΠΎΡΠΎ. Π‘Π»Π΅Π΄Π½Π°ΡΠ° Π΄Π°ΡΠΎΡΠ΅ΠΊΠ° ΡΠΎ Π·Π°Π³Π»Π°Π²ΠΈΠ΅ Π΄ΠΎΠ°ΡΠ° ΠΊΠ°Ρ Π½Π°Ρ ΠΎΠ΄ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ°ΡΠ° libbpf. Π‘Π΅Π³Π° Π½ΠΈ ΡΡΠ΅Π±Π° ΡΠ°ΠΌΠΎ Π·Π° Π΄Π° Π³ΠΎ Π΄Π΅ΡΠΈΠ½ΠΈΡΠ°ΠΌΠ΅ ΠΌΠ°ΠΊΡΠΎΡΠΎ SEC, ΠΊΠΎΡ Π³ΠΎ ΠΈΡΠΏΡΠ°ΡΠ° Π·Π½Π°ΠΊΠΎΡ Π΄ΠΎ ΡΠΎΠΎΠ΄Π²Π΅ΡΠ½ΠΈΠΎΡ Π΄Π΅Π» ΠΎΠ΄ Π΄Π°ΡΠΎΡΠ΅ΠΊΠ°ΡΠ° ΡΠΎ ΠΎΠ±ΡΠ΅ΠΊΡ ELF. ΠΠ°ΡΠ°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° Π΅ ΡΠΎΠ΄ΡΠΆΠ°Π½Π° Π²ΠΎ Π΄Π΅Π»ΠΎΡ xdp/simple, ΠΊΠ°Π΄Π΅ ΡΡΠΎ ΠΏΡΠ΅Π΄ ΠΊΠΎΡΠ° ΡΡΡΠ° Π³ΠΎ Π΄Π΅ΡΠΈΠ½ΠΈΡΠ°ΠΌΠ΅ ΡΠΈΠΏΠΎΡ Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° BPF - ΠΎΠ²Π° Π΅ ΠΊΠΎΠ½Π²Π΅Π½ΡΠΈΡΠ°ΡΠ° ΡΡΠΎ ΡΠ΅ ΠΊΠΎΡΠΈΡΡΠΈ Π²ΠΎ libbpf, Π²ΡΠ· ΠΎΡΠ½ΠΎΠ²Π° Π½Π° ΠΈΠΌΠ΅ΡΠΎ Π½Π° Π΄Π΅Π»ΠΎΡ ΡΠ΅ Π³ΠΎ Π·Π°ΠΌΠ΅Π½ΠΈ ΡΠΎΡΠ½ΠΈΠΎΡ ΡΠΈΠΏ ΠΏΡΠΈ ΡΡΠ°ΡΡΡΠ²Π°ΡΠ΅ bpf(2). Π‘Π°ΠΌΠ°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° BPF Π΅ C - ΠΌΠ½ΠΎΠ³Ρ Π΅Π΄Π½ΠΎΡΡΠ°Π²Π½ΠΎ ΠΈ ΡΠ΅ ΡΠΎΡΡΠΎΠΈ ΠΎΠ΄ Π΅Π΄Π½Π° Π»ΠΈΠ½ΠΈΡΠ° return XDP_PASS. ΠΠΎΠ½Π΅ΡΠ½ΠΎ, ΠΏΠΎΡΠ΅Π±Π΅Π½ Π΄Π΅Π» "license" Π³ΠΎ ΡΠΎΠ΄ΡΠΆΠΈ ΠΈΠΌΠ΅ΡΠΎ Π½Π° Π»ΠΈΡΠ΅Π½ΡΠ°ΡΠ°.
ΠΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° ΡΠ° ΠΊΠΎΠΌΠΏΠ°ΡΠ»ΠΈΡΠ°ΠΌΠ΅ Π½Π°ΡΠ°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° ΠΊΠΎΡΠΈΡΡΠ΅ΡΡΠΈ llvm/clang, Π²Π΅ΡΠ·ΠΈΡΠ° >= 10.0.0, ΠΈΠ»ΠΈ ΡΡΡΠ΅ ΠΏΠΎΠ΄ΠΎΠ±ΡΠΎ, ΠΏΠΎΠ³ΠΎΠ»Π΅ΠΌΠ° (Π²ΠΈΠ΄ΠΈ Π΄Π΅Π» ):
$ clang --version
clang version 11.0.0 (https://github.com/llvm/llvm-project.git afc287e0abec710398465ee1f86237513f2b5091)
...
$ clang -O2 -g -c -target bpf -I libbpf/src/root/usr/include xdp-simple.bpf.c -o xdp-simple.bpf.oΠΠ΅ΡΡ ΠΈΠ½ΡΠ΅ΡΠ΅ΡΠ½ΠΈΡΠ΅ ΠΊΠ°ΡΠ°ΠΊΡΠ΅ΡΠΈΡΡΠΈΠΊΠΈ: ΡΠ° ΠΏΠΎΡΠΎΡΡΠ²Π°ΠΌΠ΅ ΡΠ΅Π»Π½Π°ΡΠ° Π°ΡΡ
ΠΈΡΠ΅ΠΊΡΡΡΠ° -target bpf ΠΈ ΠΏΠ°ΡΠΎΡ Π΄ΠΎ Π·Π°Π³Π»Π°Π²ΠΈΡΠ°ΡΠ° libbpf, ΠΊΠΎΡ Π½Π΅ΠΎΠ΄Π°ΠΌΠ½Π° Π³ΠΎ ΠΈΠ½ΡΡΠ°Π»ΠΈΡΠ°Π²ΠΌΠ΅. ΠΡΡΠΎ ΡΠ°ΠΊΠ°, Π½Π΅ Π·Π°Π±ΠΎΡΠ°Π²Π°ΡΡΠ΅ Π·Π° -O2, Π±Π΅Π· ΠΎΠ²Π°Π° ΠΎΠΏΡΠΈΡΠ° ΠΌΠΎΠΆΠ΅ Π΄Π° Π²Π΅ ΡΠ΅ΠΊΠ°Π°Ρ ΠΈΠ·Π½Π΅Π½Π°Π΄ΡΠ²Π°ΡΠ° Π²ΠΎ ΠΈΠ΄Π½ΠΈΠ½Π°. ΠΠ° Π³ΠΎ ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ Π½Π°ΡΠΈΠΎΡ ΠΊΠΎΠ΄, Π΄Π°Π»ΠΈ ΡΡΠΏΠ΅Π°Π²ΠΌΠ΅ Π΄Π° ΡΠ° Π½Π°ΠΏΠΈΡΠ΅ΠΌΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° ΡΡΠΎ ΡΠ° ΡΠ°ΠΊΠ°Π²ΠΌΠ΅?
$ llvm-objdump --section=xdp/simple --no-show-raw-insn -D xdp-simple.bpf.o
xdp-simple.bpf.o: file format elf64-bpf
Disassembly of section xdp/simple:
0000000000000000 <simple>:
0: r0 = 2
1: exitΠΠ°, ΡΡΠΏΠ΅Π°! Π‘Π΅Π³Π°, ΠΈΠΌΠ°ΠΌΠ΅ Π±ΠΈΠ½Π°ΡΠ½Π° Π΄Π°ΡΠΎΡΠ΅ΠΊΠ° ΡΠΎ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° ΠΈ ΡΠ°ΠΊΠ°ΠΌΠ΅ Π΄Π° ΡΠΎΠ·Π΄Π°Π΄Π΅ΠΌΠ΅ Π°ΠΏΠ»ΠΈΠΊΠ°ΡΠΈΡΠ° ΠΊΠΎΡΠ° ΡΠ΅ ΡΠ° Π²ΡΠΈΡΠ° Π²ΠΎ ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ. ΠΠ° ΡΠ°Π° ΡΠ΅Π» Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ°ΡΠ° libbpf Π½ΠΈ Π½ΡΠ΄ΠΈ Π΄Π²Π΅ ΠΎΠΏΡΠΈΠΈ - ΠΊΠΎΡΠΈΡΡΠ΅ΡΠ΅ API ΠΎΠ΄ ΠΏΠΎΠ½ΠΈΡΠΊΠΎ Π½ΠΈΠ²ΠΎ ΠΈΠ»ΠΈ API ΠΎΠ΄ ΠΏΠΎΠ²ΠΈΡΠΎΠΊΠΎ Π½ΠΈΠ²ΠΎ. ΠΠ΅ ΠΎΠ΄ΠΈΠΌΠ΅ Π½Π° Π²ΡΠΎΡΠΈΠΎΡ Π½Π°ΡΠΈΠ½, Π±ΠΈΠ΄Π΅ΡΡΠΈ ΡΠ°ΠΊΠ°ΠΌΠ΅ Π΄Π° Π½Π°ΡΡΠΈΠΌΠ΅ ΠΊΠ°ΠΊΠΎ Π΄Π° ΠΏΠΈΡΡΠ²Π°ΠΌΠ΅, Π²ΡΠΈΡΠ°ΠΌΠ΅ ΠΈ ΠΏΠΎΠ²ΡΠ·ΡΠ²Π°ΠΌΠ΅ BPF ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ ΡΠΎ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»Π΅Π½ Π½Π°ΠΏΠΎΡ Π·Π° Π½ΠΈΠ²Π½ΠΎ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»Π½ΠΎ ΠΏΡΠΎΡΡΡΠ²Π°ΡΠ΅.
ΠΡΠ²ΠΎ, ΡΡΠ΅Π±Π° Π΄Π° Π³ΠΎ Π³Π΅Π½Π΅ΡΠΈΡΠ°ΠΌΠ΅ βΡΠΊΠ΅Π»Π΅ΡΠΎΡβ Π½Π° Π½Π°ΡΠ°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° ΠΎΠ΄ Π½Π΅ΡΠ·ΠΈΠ½Π°ΡΠ° Π±ΠΈΠ½Π°ΡΠ½ΠΎΡΡ ΠΊΠΎΡΠΈΡΡΠ΅ΡΡΠΈ ΡΠ° ΠΈΡΡΠ°ΡΠ° Π°Π»Π°ΡΠΊΠ° bpftool β ΡΠ²Π°ΡΡΠ°ΡΡΠΊΠΈΠΎΡ Π½ΠΎΠΆ Π½Π° ΡΠ²Π΅ΡΠΎΡ Π½Π° BPF (ΡΡΠΎ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ ΡΡΠ°ΡΠΈ Π±ΡΠΊΠ²Π°Π»Π½ΠΎ, Π±ΠΈΠ΄Π΅ΡΡΠΈ ΠΠ°Π½ΠΈΠ΅Π» ΠΠΎΡΠΊΠΌΠ°Π½, Π΅Π΄Π΅Π½ ΠΎΠ΄ ΠΊΡΠ΅Π°ΡΠΎΡΠΈΡΠ΅ ΠΈ ΠΎΠ΄ΡΠΆΡΠ²Π°ΡΠΈΡΠ΅ Π½Π° BPF, Π΅ Π¨Π²Π°ΡΡΠ°ΡΠ΅Ρ):
$ bpftool gen skeleton xdp-simple.bpf.o > xdp-simple.skel.hΠΠΎ Π΄Π°ΡΠΎΡΠ΅ΠΊΠ° xdp-simple.skel.h Π³ΠΎ ΡΠΎΠ΄ΡΠΆΠΈ Π±ΠΈΠ½Π°ΡΠ½ΠΈΠΎΡ ΠΊΠΎΠ΄ Π½Π° Π½Π°ΡΠ°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° ΠΈ ΡΡΠ½ΠΊΡΠΈΠΈ Π·Π° ΡΠΏΡΠ°Π²ΡΠ²Π°ΡΠ΅ - Π²ΡΠΈΡΡΠ²Π°ΡΠ΅, ΠΏΡΠΈΠΊΠ°ΡΡΠ²Π°ΡΠ΅, Π±ΡΠΈΡΠ΅ΡΠ΅ Π½Π° Π½Π°ΡΠΈΠΎΡ ΠΎΠ±ΡΠ΅ΠΊΡ. ΠΠΎ Π½Π°ΡΠΈΠΎΡ Π΅Π΄Π½ΠΎΡΡΠ°Π²Π΅Π½ ΡΠ»ΡΡΠ°Ρ ΠΎΠ²Π° ΠΈΠ·Π³Π»Π΅Π΄Π° ΠΊΠ°ΠΊΠΎ ΠΏΡΠ΅ΡΠ΅ΡΡΠ²Π°ΡΠ΅, Π½ΠΎ ΠΈΡΡΠΎ ΡΠ°ΠΊΠ° ΡΡΠ½ΠΊΡΠΈΠΎΠ½ΠΈΡΠ° ΠΈ Π²ΠΎ ΡΠ»ΡΡΠ°Ρ ΠΊΠΎΠ³Π° Π΄Π°ΡΠΎΡΠ΅ΠΊΠ°ΡΠ° ΡΠΎ ΠΎΠ±ΡΠ΅ΠΊΡ ΡΠΎΠ΄ΡΠΆΠΈ ΠΌΠ½ΠΎΠ³Ρ BPF ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ ΠΈ ΠΌΠ°ΠΏΠΈ ΠΈ Π·Π° Π΄Π° Π³ΠΎ Π²ΡΠΈΡΠ°ΠΌΠ΅ ΠΎΠ²ΠΎΡ ΡΠΈΠ½ΠΎΠ²ΡΠΊΠΈ ELF, ΡΠ°ΠΌΠΎ ΡΡΠ΅Π±Π° Π΄Π° Π³ΠΎ Π³Π΅Π½Π΅ΡΠΈΡΠ°ΠΌΠ΅ ΡΠΊΠ΅Π»Π΅ΡΠΎΡ ΠΈ Π΄Π° ΠΏΠΎΠ²ΠΈΠΊΠ°ΠΌΠ΅ Π΅Π΄Π½Π° ΠΈΠ»ΠΈ Π΄Π²Π΅ ΡΡΠ½ΠΊΡΠΈΠΈ ΠΎΠ΄ ΠΏΡΠΈΡΠΏΠΎΡΠΎΠ±Π΅Π½Π°ΡΠ° Π°ΠΏΠ»ΠΈΠΊΠ°ΡΠΈΡΠ° ΡΡΠΎ ΡΠ° ΠΈΠΌΠ°ΠΌΠ΅. ΠΏΠΈΡΡΠ²Π°Π°Ρ ΠΡΠ΄Π΅ Π΄Π° ΠΏΡΠΎΠ΄ΠΎΠ»ΠΆΠΈΠΌΠ΅ ΡΠ΅Π³Π°.
Π‘ΡΡΠΎΠ³ΠΎ ΠΊΠ°ΠΆΠ°Π½ΠΎ, Π½Π°ΡΠ°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° Π·Π° Π²ΡΠΈΡΡΠ²Π°ΡΠ΅ Π΅ ΡΡΠΈΠ²ΠΈΡΠ°Π»Π½Π°:
#include <err.h>
#include <unistd.h>
#include "xdp-simple.skel.h"
int main(int argc, char **argv)
{
struct xdp_simple_bpf *obj;
obj = xdp_simple_bpf__open_and_load();
if (!obj)
err(1, "failed to open and/or load BPF objectn");
pause();
xdp_simple_bpf__destroy(obj);
}Π’ΡΠΊΠ° struct xdp_simple_bpf Π΄Π΅ΡΠΈΠ½ΠΈΡΠ°Π½ΠΈ Π²ΠΎ Π΄Π°ΡΠΎΡΠ΅ΠΊΠ°ΡΠ° xdp-simple.skel.h ΠΈ ΡΠ° ΠΎΠΏΠΈΡΡΠ²Π° Π½Π°ΡΠ°ΡΠ° Π΄Π°ΡΠΎΡΠ΅ΠΊΠ° ΡΠΎ ΠΎΠ±ΡΠ΅ΠΊΡ:
struct xdp_simple_bpf {
struct bpf_object_skeleton *skeleton;
struct bpf_object *obj;
struct {
struct bpf_program *simple;
} progs;
struct {
struct bpf_link *simple;
} links;
};ΠΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° Π²ΠΈΠ΄ΠΈΠΌΠ΅ ΡΡΠ°Π³ΠΈ ΠΎΠ΄ API Π½Π° Π½ΠΈΡΠΊΠΎ Π½ΠΈΠ²ΠΎ ΠΎΠ²Π΄Π΅: ΡΡΡΡΠΊΡΡΡΠ°ΡΠ° struct bpf_program *simple ΠΈ struct bpf_link *simple. ΠΡΠ²Π°ΡΠ° ΡΡΡΡΠΊΡΡΡΠ° ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΠΎ ΡΠ° ΠΎΠΏΠΈΡΡΠ²Π° Π½Π°ΡΠ°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°, Π½Π°ΠΏΠΈΡΠ°Π½Π° Π²ΠΎ Π΄Π΅Π»ΠΎΡ xdp/simple, Π° Π²ΡΠΎΡΠΈΠΎΡ ΠΎΠΏΠΈΡΡΠ²Π° ΠΊΠ°ΠΊΠΎ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° ΡΠ΅ ΠΏΠΎΠ²ΡΠ·ΡΠ²Π° ΡΠΎ ΠΈΠ·Π²ΠΎΡΠΎΡ Π½Π° Π½Π°ΡΡΠ°Π½ΠΎΡ.
Π€ΡΠ½ΠΊΡΠΈΡΠ° xdp_simple_bpf__open_and_load, ΠΎΡΠ²ΠΎΡΠ° ΠΎΠ±ΡΠ΅ΠΊΡ ELF, Π³ΠΎ Π°Π½Π°Π»ΠΈΠ·ΠΈΡΠ°, Π³ΠΈ ΡΠΎΠ·Π΄Π°Π²Π° ΡΠΈΡΠ΅ ΡΡΡΡΠΊΡΡΡΠΈ ΠΈ ΠΏΠΎΠ΄ΡΡΡΡΠΊΡΡΡΠΈ (ΠΏΠΎΠΊΡΠ°Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ°, ELF ΡΠΎΠ΄ΡΠΆΠΈ ΠΈ Π΄ΡΡΠ³ΠΈ Π΄Π΅Π»ΠΎΠ²ΠΈ - ΠΏΠΎΠ΄Π°ΡΠΎΡΠΈ, ΠΏΠΎΠ΄Π°ΡΠΎΡΠΈ ΡΠ°ΠΌΠΎ Π·Π° ΡΠΈΡΠ°ΡΠ΅, ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΠΈ Π·Π° Π΄Π΅Π±Π°Π³ΠΈΡΠ°ΡΠ΅, Π»ΠΈΡΠ΅Π½ΡΠ° ΠΈΡΠ½.), Π° ΠΏΠΎΡΠΎΠ° Π³ΠΎ Π²ΡΠΈΡΡΠ²Π° Π²ΠΎ ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ ΠΊΠΎΡΠΈΡΡΠ΅ΡΡΠΈ ΡΠΈΡΡΠ΅ΠΌ ΡΠ°Π²Π΅ΡΠ΅ ΡΠ΅ bpf, ΡΡΠΎ ΠΌΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° Π³ΠΎ ΠΏΡΠΎΠ²Π΅ΡΠΈΠΌΠ΅ ΡΠΎ ΠΊΠΎΠΌΠΏΠ°ΡΠ»ΠΈΡΠ°ΡΠ΅ ΠΈ ΠΈΠ·Π²ΡΡΡΠ²Π°ΡΠ΅ Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ°:
$ clang -O2 -I ./libbpf/src/root/usr/include/ xdp-simple.c -o xdp-simple ./libbpf/src/root/usr/lib64/libbpf.a -lelf -lz
$ sudo strace -e bpf ./xdp-simple
...
bpf(BPF_BTF_LOAD, 0x7ffdb8fd9670, 120) = 3
bpf(BPF_PROG_LOAD, {prog_type=BPF_PROG_TYPE_XDP, insn_cnt=2, insns=0xdfd580, license="GPL", log_level=0, log_size=0, log_buf=NULL, kern_version=KERNEL_VERSION(5, 8, 0), prog_flags=0, prog_name="simple", prog_ifindex=0, expected_attach_type=0x25 /* BPF_??? */, ...}, 120) = 4ΠΡΠ΄Π΅ ΡΠ΅Π³Π° Π΄Π° ΡΠ° ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ Π½Π°ΡΠ°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° ΠΊΠΎΡΠΈΡΡΠ΅ΡΡΠΈ ΡΠ° bpftool. ΠΡΠ΄Π΅ Π΄Π° ΡΠ° Π½Π°ΡΠ΄Π΅ΠΌΠ΅ Π½Π΅ΡΠ·ΠΈΠ½Π°ΡΠ° Π»ΠΈΡΠ½Π° ΠΊΠ°ΡΡΠ°:
# bpftool p | grep -A4 simple
463: xdp name simple tag 3b185187f1855c4c gpl
loaded_at 2020-08-01T01:59:49+0000 uid 0
xlated 16B jited 40B memlock 4096B
btf_id 185
pids xdp-simple(16498)ΠΈ dump (ΠΊΠΎΡΠΈΡΡΠΈΠΌΠ΅ ΡΠΊΡΠ°ΡΠ΅Π½Π° ΡΠΎΡΠΌΠ° Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄Π°ΡΠ° bpftool prog dump xlated):
# bpftool p d x id 463
int simple(void *ctx):
; return XDP_PASS;
0: (b7) r0 = 2
1: (95) exitΠΠ΅ΡΡΠΎ Π½ΠΎΠ²ΠΎ! ΠΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° ΠΎΡΠΏΠ΅ΡΠ°ΡΠΈ Π΄Π΅Π»ΠΎΠ²ΠΈ ΠΎΠ΄ Π½Π°ΡΠ°ΡΠ° ΠΈΠ·Π²ΠΎΡΠ½Π° Π΄Π°ΡΠΎΡΠ΅ΠΊΠ° C. ΠΠ²Π° Π±Π΅ΡΠ΅ Π½Π°ΠΏΡΠ°Π²Π΅Π½ΠΎ ΠΎΠ΄ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ°ΡΠ° libbpf, ΠΊΠΎΡ Π³ΠΎ Π½Π°ΡΠ΄Π΅ Π΄Π΅Π»ΠΎΡ Π·Π° ΠΎΡΡΡΡΠ°Π½ΡΠ²Π°ΡΠ΅ Π³ΡΠ΅ΡΠΊΠΈ Π²ΠΎ Π±ΠΈΠ½Π°ΡΠ½ΠΈΠΎΡ, Π³ΠΎ ΠΊΠΎΠΌΠΏΠ°ΡΠ»ΠΈΡΠ° Π²ΠΎ ΠΎΠ±ΡΠ΅ΠΊΡ BTF, Π³ΠΎ Π²ΡΠΈΡΠ° Π²ΠΎ ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ ΠΊΠΎΡΠΈΡΡΠ΅ΡΡΠΈ BPF_BTF_LOAD, Π° ΠΏΠΎΡΠΎΠ° Π½Π°Π²Π΅Π΄Π΅ΡΠ΅ Π³ΠΎ Π΄ΠΎΠ±ΠΈΠ΅Π½ΠΈΠΎΡ Π΄Π΅ΡΠΊΡΠΈΠΏΡΠΎΡ Π½Π° Π΄Π°ΡΠΎΡΠ΅ΠΊΠ°ΡΠ° ΠΏΡΠΈ Π²ΡΠΈΡΡΠ²Π°ΡΠ΅ Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° ΡΠΎ ΠΊΠΎΠΌΠ°Π½Π΄Π°ΡΠ° BPG_PROG_LOAD.
ΠΠΎΠΌΠΎΡΠ½ΠΈΡΠΈ Π½Π° ΡΠ°Π΄ΡΠΎΡΠΎ
ΠΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ΅ BPF ΠΌΠΎΠΆΠ°Ρ Π΄Π° ΠΈΠ·Π²ΡΡΡΠ²Π°Π°Ρ βΠ½Π°Π΄Π²ΠΎΡΠ΅ΡΠ½ΠΈβ ΡΡΠ½ΠΊΡΠΈΠΈ - ΠΏΠΎΠΌΠ°Π³Π°ΡΠΈ Π½Π° ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ. ΠΠ²ΠΈΠ΅ ΠΏΠΎΠΌΠΎΡΠ½ΠΈ ΡΡΠ½ΠΊΡΠΈΠΈ ΠΈΠΌ ΠΎΠ²ΠΎΠ·ΠΌΠΎΠΆΡΠ²Π°Π°Ρ Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ΅ BPF Π΄Π° ΠΏΡΠΈΡΡΠ°ΠΏΡΠ²Π°Π°Ρ Π΄ΠΎ ΡΡΡΡΠΊΡΡΡΠΈΡΠ΅ Π½Π° ΡΠ°Π΄ΡΠΎΡΠΎ, Π΄Π° ΡΠΏΡΠ°Π²ΡΠ²Π°Π°Ρ ΡΠΎ ΠΌΠ°ΠΏΠΈ, Π° ΠΈΡΡΠΎ ΡΠ°ΠΊΠ° Π΄Π° ΠΊΠΎΠΌΡΠ½ΠΈΡΠΈΡΠ°Π°Ρ ΡΠΎ βΡΠ΅Π°Π»Π½ΠΈΠΎΡ ΡΠ²Π΅Ρβ - Π΄Π° ΡΠΎΠ·Π΄Π°Π²Π°Π°Ρ Π½Π°ΡΡΠ°Π½ΠΈ Π½Π° ΠΏΠ΅ΡΡ, Π΄Π° ΠΊΠΎΠ½ΡΡΠΎΠ»ΠΈΡΠ°Π°Ρ Ρ Π°ΡΠ΄Π²Π΅Ρ (Π½Π° ΠΏΡΠΈΠΌΠ΅Ρ, ΠΏΡΠ΅Π½Π°ΡΠΎΡΡΠ²Π°ΡΠ΅ Π½Π° ΠΏΠ°ΠΊΠ΅ΡΠΈ) ΠΈΡΠ½.
ΠΡΠΈΠΌΠ΅Ρ: bpf_get_smp_processor_id
ΠΠΎ ΡΠ°ΠΌΠΊΠΈΡΠ΅ Π½Π° ΠΏΠ°ΡΠ°Π΄ΠΈΠ³ΠΌΠ°ΡΠ° βΡΡΠ΅ΡΠ΅ ΠΏΡΠ΅ΠΊΡ ΠΏΡΠΈΠΌΠ΅Ρβ, Π΄Π° ΡΠ°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ Π΅Π΄Π½Π° ΠΎΠ΄ ΡΡΠ½ΠΊΡΠΈΠΈΡΠ΅ Π½Π° ΠΏΠΎΠΌΠΎΡΠ½ΠΈΠΊΠΎΡ. bpf_get_smp_processor_id(), Π²ΠΎ Π΄Π°ΡΠΎΡΠ΅ΠΊΠ° kernel/bpf/helpers.c. ΠΠΎ Π²ΡΠ°ΡΠ° Π±ΡΠΎΡΠΎΡ Π½Π° ΠΏΡΠΎΡΠ΅ΡΠΎΡΠΎΡ Π½Π° ΠΊΠΎΡ ΡΠ°Π±ΠΎΡΠΈ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° BPF ΡΡΠΎ ΡΠ° ΠΏΠΎΠ²ΠΈΠΊΠ°. ΠΠΎ, Π½ΠΈΠ΅ Π½Π΅ ΡΠΌΠ΅ ΡΠΎΠ»ΠΊΡ Π·Π°ΠΈΠ½ΡΠ΅ΡΠ΅ΡΠΈΡΠ°Π½ΠΈ Π·Π° Π½Π΅Π³ΠΎΠ²Π°ΡΠ° ΡΠ΅ΠΌΠ°Π½ΡΠΈΠΊΠ° ΠΊΠ°ΠΊΠΎ Π·Π° ΡΠ°ΠΊΡΠΎΡ Π΄Π΅ΠΊΠ° Π½Π΅ΡΠ·ΠΈΠ½Π°ΡΠ° ΠΈΠΌΠΏΠ»Π΅ΠΌΠ΅Π½ΡΠ°ΡΠΈΡΠ° ΡΡΠ°Π΅ Π΅Π΄Π½Π° Π»ΠΈΠ½ΠΈΡΠ°:
BPF_CALL_0(bpf_get_smp_processor_id)
{
return smp_processor_id();
}ΠΠ΅ΡΠΈΠ½ΠΈΡΠΈΠΈΡΠ΅ Π½Π° ΠΏΠΎΠΌΠΎΡΠ½ΠΈΡΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ Π½Π° BPF ΡΠ΅ ΡΠ»ΠΈΡΠ½ΠΈ Π½Π° Π΄Π΅ΡΠΈΠ½ΠΈΡΠΈΠΈΡΠ΅ Π½Π° ΡΠΈΡΡΠ΅ΠΌΡΠΊΠΈΡΠ΅ ΠΏΠΎΠ²ΠΈΡΠΈ. LinuxΠΠ° ΠΏΡΠΈΠΌΠ΅Ρ, ΠΎΠ²Π΄Π΅ Π΅ Π΄Π΅ΡΠΈΠ½ΠΈΡΠ°Π½Π° ΡΡΠ½ΠΊΡΠΈΡΠ° ΠΊΠΎΡΠ° Π½Π΅ΠΌΠ° Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠΈ. (Π€ΡΠ½ΠΊΡΠΈΡΠ° ΠΊΠΎΡΠ° ΠΏΡΠΈΠΌΠ°, Π΄Π° ΡΠ΅ΡΠ΅ΠΌΠ΅, ΡΡΠΈ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠΈ Π΅ Π΄Π΅ΡΠΈΠ½ΠΈΡΠ°Π½Π° ΡΠΎ ΠΏΠΎΠΌΠΎΡ Π½Π° ΠΌΠ°ΠΊΡΠΎ BPF_CALL_3. ΠΠ°ΠΊΡΠΈΠΌΠ°Π»Π½ΠΈΠΎΡ Π±ΡΠΎΡ Π½Π° Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠΈ Π΅ ΠΏΠ΅Ρ.) Π‘Π΅ΠΏΠ°ΠΊ, ΠΎΠ²Π° Π΅ ΡΠ°ΠΌΠΎ ΠΏΡΠ²ΠΈΠΎΡ Π΄Π΅Π» ΠΎΠ΄ Π΄Π΅ΡΠΈΠ½ΠΈΡΠΈΡΠ°ΡΠ°. ΠΡΠΎΡΠΈΠΎΡ Π΄Π΅Π» Π΅ Π΄Π° ΡΠ΅ Π΄Π΅ΡΠΈΠ½ΠΈΡΠ° ΡΡΡΡΠΊΡΡΡΠ°ΡΠ° Π½Π° ΡΠΈΠΏΠΎΡ struct bpf_func_proto, ΠΊΠΎΡ ΡΠΎΠ΄ΡΠΆΠΈ ΠΎΠΏΠΈΡ Π½Π° ΡΡΠ½ΠΊΡΠΈΡΠ°ΡΠ° ΠΏΠΎΠΌΠΎΡΠ½ΠΈΠΊ ΡΡΠΎ ΠΏΡΠΎΠ²Π΅ΡΡΠ²Π°ΡΠΎΡ ΡΠ° ΡΠ°Π·Π±ΠΈΡΠ°:
const struct bpf_func_proto bpf_get_smp_processor_id_proto = {
.func = bpf_get_smp_processor_id,
.gpl_only = false,
.ret_type = RET_INTEGER,
};Π Π΅Π³ΠΈΡΡΡΠΈΡΠ°ΡΠ΅ Π½Π° ΡΡΠ½ΠΊΡΠΈΠΈ Π·Π° ΠΏΠΎΠΌΠΎΡΠ½ΠΈΠΊ
ΠΠ° Π΄Π° ΠΌΠΎΠΆΠ°Ρ BPF ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ΅ ΠΎΠ΄ ΠΎΠ΄ΡΠ΅Π΄Π΅Π½ ΡΠΈΠΏ Π΄Π° ΡΠ° ΠΊΠΎΡΠΈΡΡΠ°Ρ ΠΎΠ²Π°Π° ΡΡΠ½ΠΊΡΠΈΡΠ°, ΡΠΈΠ΅ ΠΌΠΎΡΠ° Π΄Π° ΡΠ° ΡΠ΅Π³ΠΈΡΡΡΠΈΡΠ°Π°Ρ, Π½Π° ΠΏΡΠΈΠΌΠ΅Ρ Π·Π° ΡΠΈΠΏΠΎΡ BPF_PROG_TYPE_XDP Π²ΠΎ ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ Π΅ Π΄Π΅ΡΠΈΠ½ΠΈΡΠ°Π½Π° ΡΡΠ½ΠΊΡΠΈΡΠ° xdp_func_proto, ΡΡΠΎ ΠΎΠ΄ΡΠ΅Π΄ΡΠ²Π° ΠΎΠ΄ ID Π½Π° ΡΡΠ½ΠΊΡΠΈΡΠ°ΡΠ° ΠΏΠΎΠΌΠΎΡΠ½ΠΈΠΊ Π΄Π°Π»ΠΈ XDP ΡΠ° ΠΏΠΎΠ΄Π΄ΡΠΆΡΠ²Π° ΠΎΠ²Π°Π° ΡΡΠ½ΠΊΡΠΈΡΠ° ΠΈΠ»ΠΈ Π½Π΅. ΠΠ°ΡΠ°ΡΠ° ΡΡΠ½ΠΊΡΠΈΡΠ° Π΅ :
static const struct bpf_func_proto *
xdp_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
{
switch (func_id) {
...
case BPF_FUNC_get_smp_processor_id:
return &bpf_get_smp_processor_id_proto;
...
}
}ΠΠΎΠ²ΠΈΡΠ΅ ΡΠΈΠΏΠΎΠ²ΠΈ Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ BPF ΡΠ΅ βΠ΄Π΅ΡΠΈΠ½ΠΈΡΠ°Π½ΠΈβ Π²ΠΎ Π΄Π°ΡΠΎΡΠ΅ΠΊΠ°ΡΠ° ΠΊΠΎΡΠΈΡΡΠ΅ΡΡΠΈ ΠΌΠ°ΠΊΡΠΎ BPF_PROG_TYPE. ΠΠ΅ΡΠΈΠ½ΠΈΡΠ°Π½ΠΎ Π²ΠΎ Π½Π°Π²ΠΎΠ΄Π½ΠΈΡΠΈ Π·Π°ΡΠΎΠ° ΡΡΠΎ Π΅ Π»ΠΎΠ³ΠΈΡΠΊΠ° Π΄Π΅ΡΠΈΠ½ΠΈΡΠΈΡΠ°, Π° Π²ΠΎ ΡΠ΅ΡΠΌΠΈΠ½ΠΈΡΠ΅ Π½Π° ΡΠ°Π·ΠΈΠΊΠΎΡ C Π΄Π΅ΡΠΈΠ½ΠΈΡΠΈΡΠ°ΡΠ° Π½Π° ΡΠ΅Π» ΡΠ΅Ρ Π±Π΅ΡΠΎΠ½ΡΠΊΠΈ ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΈΠΈ ΡΠ΅ ΡΠ°Π²ΡΠ²Π° Π½Π° Π΄ΡΡΠ³ΠΈ ΠΌΠ΅ΡΡΠ°. ΠΠΎΠ½ΠΊΡΠ΅ΡΠ½ΠΎ, Π²ΠΎ Π΄ΠΎΡΠΈΠ΅ΡΠΎ kernel/bpf/verifier.c ΡΠΈΡΠ΅ Π΄Π΅ΡΠΈΠ½ΠΈΡΠΈΠΈ ΠΎΠ΄ Π΄Π°ΡΠΎΡΠ΅ΠΊΠ°ΡΠ° bpf_types.h ΡΠ΅ ΠΊΠΎΡΠΈΡΡΠ°Ρ Π·Π° ΡΠΎΠ·Π΄Π°Π²Π°ΡΠ΅ Π½ΠΈΠ·Π° ΡΡΡΡΠΊΡΡΡΠΈ bpf_verifier_ops[]:
static const struct bpf_verifier_ops *const bpf_verifier_ops[] = {
#define BPF_PROG_TYPE(_id, _name, prog_ctx_type, kern_ctx_type)
[_id] = & _name ## _verifier_ops,
#include <linux/bpf_types.h>
#undef BPF_PROG_TYPE
};ΠΠ΄Π½ΠΎΡΠ½ΠΎ, Π·Π° ΡΠ΅ΠΊΠΎΡ ΡΠΈΠΏ Π½Π° BPF ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°, ΡΠ΅ Π΄Π΅ΡΠΈΠ½ΠΈΡΠ° ΠΏΠΎΠΊΠ°ΠΆΡΠ²Π°Ρ ΠΊΠΎΠ½ ΡΡΡΡΠΊΡΡΡΠ° Π½Π° ΠΏΠΎΠ΄Π°ΡΠΎΡΠΈ ΠΎΠ΄ ΡΠΈΠΏΠΎΡ struct bpf_verifier_ops, ΠΊΠΎΡ ΡΠ΅ ΠΈΠ½ΠΈΡΠΈΡΠ°Π»ΠΈΠ·ΠΈΡΠ° ΡΠΎ Π²ΡΠ΅Π΄Π½ΠΎΡΡΠ° _name ## _verifier_opsΡ.Π΅. xdp_verifier_ops Π·Π° xdp. Π‘ΡΡΡΠΊΡΡΡΠ° xdp_verifier_ops Π²ΠΎ Π΄Π°ΡΠΎΡΠ΅ΠΊΠ° net/core/filter.c ΠΊΠ°ΠΊΠΎ ΡΡΠΎ ΡΠ»Π΅Π΄ΡΠ²Π°:
const struct bpf_verifier_ops xdp_verifier_ops = {
.get_func_proto = xdp_func_proto,
.is_valid_access = xdp_is_valid_access,
.convert_ctx_access = xdp_convert_ctx_access,
.gen_prologue = bpf_noop_prologue,
};ΠΠ²Π΄Π΅ ΡΠ° Π³Π»Π΅Π΄Π°ΠΌΠ΅ Π½Π°ΡΠ°ΡΠ° ΠΏΠΎΠ·Π½Π°ΡΠ° ΡΡΠ½ΠΊΡΠΈΡΠ° xdp_func_proto, ΠΊΠΎΡ ΡΠ΅ Π³ΠΎ Π°ΠΊΡΠΈΠ²ΠΈΡΠ° ΠΏΡΠΎΠ²Π΅ΡΡΠ²Π°ΡΠΎΡ ΡΠ΅ΠΊΠΎΠ³Π°Ρ ΠΊΠΎΠ³Π° ΡΠ΅ Π½Π°ΠΈΠ΄Π΅ Π½Π° ΠΏΡΠ΅Π΄ΠΈΠ·Π²ΠΈΠΊ Π½Π΅ΠΊΠΎΡ Π²ΠΈΠ΄ ΡΡΠ½ΠΊΡΠΈΠΈ Π²ΠΎ BPF ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°, Π²ΠΈΠ΄ΠΈ .
ΠΡΠ΄Π΅ Π΄Π° ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ ΠΊΠ°ΠΊΠΎ Ρ
ΠΈΠΏΠΎΡΠ΅ΡΠΈΡΠΊΠ° BPF ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° ΡΠ° ΠΊΠΎΡΠΈΡΡΠΈ ΡΡΠ½ΠΊΡΠΈΡΠ°ΡΠ° bpf_get_smp_processor_id. ΠΠ° Π΄Π° Π³ΠΎ Π½Π°ΠΏΡΠ°Π²ΠΈΡΠ΅ ΠΎΠ²Π°, ΡΠ° ΠΏΡΠ΅ΠΏΠΈΡΡΠ²Π°ΠΌΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° ΠΎΠ΄ Π½Π°ΡΠΈΠΎΡ ΠΏΡΠ΅ΡΡ
ΠΎΠ΄Π΅Π½ Π΄Π΅Π» Π½Π° ΡΠ»Π΅Π΄Π½ΠΈΠΎΠ² Π½Π°ΡΠΈΠ½:
#include "vmlinux.h"
#include <bpf/bpf_helpers.h>
SEC("xdp/simple")
int simple(void *ctx)
{
if (bpf_get_smp_processor_id() != 0)
return XDP_DROP;
return XDP_PASS;
}
char LICENSE[] SEC("license") = "GPL";ΡΠΈΠΌΠ±ΠΎΠ» bpf_get_smp_processor_id Π² <bpf/bpf_helper_defs.h> Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ libbpf ΠΊΠ°ΠΊΠΎ
static u32 (*bpf_get_smp_processor_id)(void) = (void *) 8;ΡΠΎΠ° Π΅, bpf_get_smp_processor_id Π΅ ΡΡΠ½ΠΊΡΠΈΡΠΊΠΈ ΠΏΠΎΠΊΠ°ΠΆΡΠ²Π°Ρ ΡΠΈΡΠ° Π²ΡΠ΅Π΄Π½ΠΎΡΡ Π΅ 8, ΠΊΠ°Π΄Π΅ ΡΡΠΎ 8 Π΅ Π²ΡΠ΅Π΄Π½ΠΎΡΡΠ° BPF_FUNC_get_smp_processor_id ΡΠΈΠΏ enum bpf_fun_id, ΡΡΠΎ Π½ΠΈ Π΅ Π΄Π΅ΡΠΈΠ½ΠΈΡΠ°Π½ΠΎ Π²ΠΎ Π΄Π°ΡΠΎΡΠ΅ΠΊΠ°ΡΠ° vmlinux.h (Π΄Π°ΡΠΎΡΠ΅ΠΊΠ° bpf_helper_defs.h Π²ΠΎ ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ ΡΠ΅ Π³Π΅Π½Π΅ΡΠΈΡΠ° ΡΠΊΡΠΈΠΏΡΠ°, ΡΠ°ΠΊΠ° ΡΡΠΎ βΠΌΠ°Π³ΠΈΡΠ½ΠΈΡΠ΅β Π±ΡΠΎΠ΅Π²ΠΈ ΡΠ΅ Π²ΠΎ ΡΠ΅Π΄). ΠΠ²Π°Π° ΡΡΠ½ΠΊΡΠΈΡΠ° Π½Π΅ Π·Π΅ΠΌΠ° Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠΈ ΠΈ Π²ΡΠ°ΡΠ° Π²ΡΠ΅Π΄Π½ΠΎΡΡ ΠΎΠ΄ ΡΠΈΠΏΠΎΡ __u32. ΠΠΎΠ³Π° ΡΠ΅ Π³ΠΎ ΠΈΠ·Π²ΡΡΠΈΠΌΠ΅ Π²ΠΎ Π½Π°ΡΠ°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°, clang Π³Π΅Π½Π΅ΡΠΈΡΠ° ΠΈΠ½ΡΡΡΡΠΊΡΠΈΡΠ° BPF_CALL βΠ²ΠΈΡΡΠΈΠ½ΡΠΊΠΈΠΎΡ Π²ΠΈΠ΄β ΠΡΠ΄Π΅ Π΄Π° ΡΠ° ΡΠΎΡΡΠ°Π²ΠΈΠΌΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° ΠΈ Π΄Π° Π³ΠΎ ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ Π΄Π΅Π»ΠΎΡ xdp/simple:
$ clang -O2 -g -c -target bpf -I libbpf/src/root/usr/include xdp-simple.bpf.c -o xdp-simple.bpf.o
$ llvm-objdump -D --section=xdp/simple xdp-simple.bpf.o
xdp-simple.bpf.o: file format elf64-bpf
Disassembly of section xdp/simple:
0000000000000000 <simple>:
0: 85 00 00 00 08 00 00 00 call 8
1: bf 01 00 00 00 00 00 00 r1 = r0
2: 67 01 00 00 20 00 00 00 r1 <<= 32
3: 77 01 00 00 20 00 00 00 r1 >>= 32
4: b7 00 00 00 02 00 00 00 r0 = 2
5: 15 01 01 00 00 00 00 00 if r1 == 0 goto +1 <LBB0_2>
6: b7 00 00 00 01 00 00 00 r0 = 1
0000000000000038 <LBB0_2>:
7: 95 00 00 00 00 00 00 00 exitΠΠΎ ΠΏΡΠ²Π°ΡΠ° Π»ΠΈΠ½ΠΈΡΠ° Π³Π»Π΅Π΄Π°ΠΌΠ΅ ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈ call, ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΠ°Ρ IMM ΡΡΠΎ Π΅ Π΅Π΄Π½Π°ΠΊΠ²ΠΎ Π½Π° 8, ΠΈ SRC_REG - Π½ΡΠ»Π°. Π‘ΠΏΠΎΡΠ΅Π΄ Π΄ΠΎΠ³ΠΎΠ²ΠΎΡΠΎΡ ABI ΡΡΠΎ Π³ΠΎ ΠΊΠΎΡΠΈΡΡΠΈ Π²Π΅ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΠΎΡ, ΠΎΠ²Π° Π΅ ΠΏΠΎΠ²ΠΈΠΊ Π΄ΠΎ ΡΡΠ½ΠΊΡΠΈΡΠ°ΡΠ° ΠΏΠΎΠΌΠΎΡΠ½ΠΈΠΊ Π±ΡΠΎΡ ΠΎΡΡΠΌ. ΠΡΠΊΠ°ΠΊΠΎ ΡΠ΅ ΡΠ΅ ΡΡΠ°ΡΡΡΠ²Π°, Π»ΠΎΠ³ΠΈΠΊΠ°ΡΠ° Π΅ Π΅Π΄Π½ΠΎΡΡΠ°Π²Π½Π°. ΠΡΠ°ΡΠ΅ΡΠ΅ ΡΠ° Π²ΡΠ΅Π΄Π½ΠΎΡΡΠ° ΠΎΠ΄ ΡΠ΅Π³ΠΈΡΡΠ°ΡΠΎΡ r0 ΠΊΠΎΠΏΠΈΡΠ°Π½ΠΈ Π½Π° r1 Π° Π½Π° Π»ΠΈΠ½ΠΈΠΈΡΠ΅ 2,3 ΡΠ΅ ΠΏΡΠ΅ΡΠ²ΠΎΡΠ° Π²ΠΎ ΡΠΈΠΏ u32 β Π³ΠΎΡΠ½ΠΈΡΠ΅ 32 Π±ΠΈΡΠ° ΡΠ΅ ΠΈΠ·Π±ΡΠΈΡΠ°Π½ΠΈ. ΠΠ° Π»ΠΈΠ½ΠΈΠΈΡΠ΅ 4,5,6,7 Π²ΡΠ°ΡΠ°ΠΌΠ΅ 2 (XDP_PASS) ΠΈΠ»ΠΈ 1 (XDP_DROP) Π²ΠΎ Π·Π°Π²ΠΈΡΠ½ΠΎΡΡ ΠΎΠ΄ ΡΠΎΠ° Π΄Π°Π»ΠΈ ΠΏΠΎΠΌΠΎΡΠ½Π°ΡΠ° ΡΡΠ½ΠΊΡΠΈΡΠ° ΠΎΠ΄ Π»ΠΈΠ½ΠΈΡΠ°ΡΠ° 0 Π²ΡΠ°ΡΠΈΠ»Π° Π½ΡΠ»ΡΠ° ΠΈΠ»ΠΈ Π½Π΅Π½ΡΠ»ΡΠ° Π²ΡΠ΅Π΄Π½ΠΎΡΡ.
ΠΡΠ΄Π΅ Π΄Π° ΡΠ΅ ΡΠ΅ΡΡΠΈΡΠ°ΠΌΠ΅: Π²ΡΠΈΡΠ°ΡΡΠ΅ ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° ΠΈ ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΡΠ΅ Π³ΠΎ ΠΈΠ·Π»Π΅Π·ΠΎΡ bpftool prog dump xlated:
$ bpftool gen skeleton xdp-simple.bpf.o > xdp-simple.skel.h
$ clang -O2 -g -I ./libbpf/src/root/usr/include/ -o xdp-simple xdp-simple.c ./libbpf/src/root/usr/lib64/libbpf.a -lelf -lz
$ sudo ./xdp-simple &
[2] 10914
$ sudo bpftool p | grep simple
523: xdp name simple tag 44c38a10c657e1b0 gpl
pids xdp-simple(10915)
$ sudo bpftool p d x id 523
int simple(void *ctx):
; if (bpf_get_smp_processor_id() != 0)
0: (85) call bpf_get_smp_processor_id#114128
1: (bf) r1 = r0
2: (67) r1 <<= 32
3: (77) r1 >>= 32
4: (b7) r0 = 2
; }
5: (15) if r1 == 0x0 goto pc+1
6: (b7) r0 = 1
7: (95) exitΠΠΎ ΡΠ΅Π΄, ΠΏΡΠΎΠ²Π΅ΡΡΠ²Π°ΡΠΎΡ Π³ΠΎ Π½Π°ΡΠ΄Π΅ ΡΠΎΡΠ½ΠΈΠΎΡ ΠΏΠΎΠΌΠΎΡΠ½ΠΈΠΊ Π½Π° ΡΠ°Π΄ΡΠΎΡΠΎ.
ΠΡΠΈΠΌΠ΅Ρ: ΠΏΡΠ΅Π½Π΅ΡΡΠ²Π°ΡΠ΅ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠΈ ΠΈ Π½Π° ΠΊΡΠ°ΡΠΎΡ Π²ΠΎΠ΄Π΅ΡΠ΅ Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ°!
Π‘ΠΈΡΠ΅ ΠΏΠΎΠΌΠΎΡΠ½ΠΈ ΡΡΠ½ΠΊΡΠΈΠΈ Π½Π° Π½ΠΈΠ²ΠΎ Π½Π° ΡΠ°Π±ΠΎΡΠ° ΠΈΠΌΠ°Π°Ρ ΠΏΡΠΎΡΠΎΡΠΈΠΏ
u64 fn(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5)ΠΠ°ΡΠ°ΠΌΠ΅ΡΡΠΈΡΠ΅ Π·Π° ΠΏΠΎΠΌΠΎΡΠ½ΠΈΡΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ ΡΠ΅ ΠΏΡΠ΅Π½Π΅ΡΡΠ²Π°Π°Ρ Π²ΠΎ ΡΠ΅Π³ΠΈΡΡΡΠΈ r1-r5, Π° Π²ΡΠ΅Π΄Π½ΠΎΡΡΠ° ΡΠ΅ Π²ΡΠ°ΡΠ° Π²ΠΎ ΡΠ΅Π³ΠΈΡΡΠ°ΡΠΎΡ r0. ΠΠ΅ΠΌΠ° ΡΡΠ½ΠΊΡΠΈΠΈ ΠΊΠΎΠΈ Π·Π΅ΠΌΠ°Π°Ρ ΠΏΠΎΠ²Π΅ΡΠ΅ ΠΎΠ΄ ΠΏΠ΅Ρ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠΈ, Π° ΠΏΠΎΠ΄Π΄ΡΡΠΊΠ°ΡΠ° Π·Π° Π½ΠΈΠ² Π½Π΅ ΡΠ΅ ΠΎΡΠ΅ΠΊΡΠ²Π° Π΄Π° Π±ΠΈΠ΄Π΅ Π΄ΠΎΠ΄Π°Π΄Π΅Π½Π° Π²ΠΎ ΠΈΠ΄Π½ΠΈΠ½Π°.
ΠΡΠ΄Π΅ Π΄Π° Π³ΠΎ ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ Π½ΠΎΠ²ΠΈΠΎΡ ΠΏΠΎΠΌΠΎΡΠ½ΠΈΠΊ Π½Π° ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ ΠΈ ΠΊΠ°ΠΊΠΎ BPF Π³ΠΈ ΠΏΡΠ΅Π½Π΅ΡΡΠ²Π° ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΈΡΠ΅. ΠΡΠ΄Π΅ Π΄Π° ΠΏΡΠ΅ΠΏΠΈΡΠ΅ΠΌΠ΅ xdp-simple.bpf.c ΠΊΠ°ΠΊΠΎ ΡΡΠΎ ΡΠ»Π΅Π΄ΡΠ²Π° (ΠΎΡΡΠ°Π½Π°ΡΠΈΠΎΡ Π΄Π΅Π» ΠΎΠ΄ ΡΠ΅Π΄ΠΎΠ²ΠΈΡΠ΅ Π½Π΅ ΡΠ΅ ΠΏΡΠΎΠΌΠ΅Π½Π΅ΡΠΈ):
SEC("xdp/simple")
int simple(void *ctx)
{
bpf_printk("running on CPU%un", bpf_get_smp_processor_id());
return XDP_PASS;
}ΠΠ°ΡΠ°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° Π³ΠΎ ΠΏΠ΅ΡΠ°ΡΠΈ Π±ΡΠΎΡΠΎΡ Π½Π° ΠΏΡΠΎΡΠ΅ΡΠΎΡΠΎΡ Π½Π° ΠΊΠΎΡ ΡΠ°Π±ΠΎΡΠΈ. ΠΡΠ΄Π΅ Π΄Π° Π³ΠΎ ΠΊΠΎΠΌΠΏΠ°ΡΠ»ΠΈΡΠ°ΠΌΠ΅ ΠΈ Π΄Π° Π³ΠΎ ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ ΠΊΠΎΠ΄ΠΎΡ:
$ llvm-objdump -D --section=xdp/simple --no-show-raw-insn xdp-simple.bpf.o
0000000000000000 <simple>:
0: r1 = 10
1: *(u16 *)(r10 - 8) = r1
2: r1 = 8441246879787806319 ll
4: *(u64 *)(r10 - 16) = r1
5: r1 = 2334956330918245746 ll
7: *(u64 *)(r10 - 24) = r1
8: call 8
9: r1 = r10
10: r1 += -24
11: r2 = 18
12: r3 = r0
13: call 6
14: r0 = 2
15: exitΠΠΎ ΡΠ΅Π΄ΠΎΠ²ΠΈΡΠ΅ 0-7 ΡΠ° ΠΏΠΈΡΡΠ²Π°ΠΌΠ΅ Π½ΠΈΠ·Π°ΡΠ° running on CPU%un, Π° ΠΏΠΎΡΠΎΠ° Π½Π° Π»ΠΈΠ½ΠΈΡΠ°ΡΠ° 8 ΡΠ° ΡΡΠ°ΡΡΡΠ²Π°ΠΌΠ΅ ΠΏΠΎΠ·Π½Π°ΡΠ°ΡΠ° bpf_get_smp_processor_id. ΠΠ° Π»ΠΈΠ½ΠΈΠΈΡΠ΅ 9-12 Π³ΠΈ ΠΏΠΎΠ΄Π³ΠΎΡΠ²ΡΠ²Π°ΠΌΠ΅ ΠΏΠΎΠΌΠΎΡΠ½ΠΈΡΠ΅ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠΈ bpf_printk - ΡΠ΅Π³ΠΈΡΡΡΠΈ r1, r2, r3. ΠΠΎΡΡΠΎ ΠΈΠΌΠ° ΡΡΠΈ, Π° Π½Π΅ Π΄Π²Π΅? ΠΠΈΠ΄Π΅ΡΡΠΈ bpf_printk - ΠΎΠΊΠΎΠ»Ρ Π²ΠΈΡΡΠΈΠ½ΡΠΊΠΈΠΎΡ ΠΏΠΎΠΌΠΎΡΠ½ΠΈΠΊ bpf_trace_printk, ΠΊΠΎΡ ΡΡΠ΅Π±Π° Π΄Π° ΡΠ° ΠΏΠΎΠΌΠΈΠ½Π΅ Π³ΠΎΠ»Π΅ΠΌΠΈΠ½Π°ΡΠ° Π½Π° Π½ΠΈΠ·Π°ΡΠ° Π·Π° ΡΠΎΡΠΌΠ°Ρ.
ΠΡΠ΄Π΅ ΡΠ΅Π³Π° Π΄Π° Π΄ΠΎΠ΄Π°Π΄Π΅ΠΌΠ΅ Π½Π΅ΠΊΠΎΠ»ΠΊΡ Π»ΠΈΠ½ΠΈΠΈ xdp-simple.cΡΠ°ΠΊΠ° ΡΡΠΎ Π½Π°ΡΠ°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° ΡΠ΅ ΠΏΠΎΠ²ΡΠ·ΡΠ²Π° ΡΠΎ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΡΡΠΎΡ lo ΠΈ Π½Π°Π²ΠΈΡΡΠΈΠ½Π° Π·Π°ΠΏΠΎΡΠ½Π°!
$ cat xdp-simple.c
#include <linux/if_link.h>
#include <err.h>
#include <unistd.h>
#include "xdp-simple.skel.h"
int main(int argc, char **argv)
{
__u32 flags = XDP_FLAGS_SKB_MODE;
struct xdp_simple_bpf *obj;
obj = xdp_simple_bpf__open_and_load();
if (!obj)
err(1, "failed to open and/or load BPF objectn");
bpf_set_link_xdp_fd(1, -1, flags);
bpf_set_link_xdp_fd(1, bpf_program__fd(obj->progs.simple), flags);
cleanup:
xdp_simple_bpf__destroy(obj);
}ΠΠ²Π΄Π΅ ΡΠ° ΠΊΠΎΡΠΈΡΡΠΈΠΌΠ΅ ΡΡΠ½ΠΊΡΠΈΡΠ°ΡΠ° bpf_set_link_xdp_fd, ΠΊΠΎΡ Π³ΠΈ ΠΏΠΎΠ²ΡΠ·ΡΠ²Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ΅ BPF ΠΎΠ΄ ΡΠΈΠΏΠΎΡ XDP ΡΠΎ ΠΌΡΠ΅ΠΆΠ½ΠΈΡΠ΅ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΡΡΠΈ. ΠΠΎ ΡΠΈΡΡΠΈΡΠ°Π²ΠΌΠ΅ Π±ΡΠΎΡΠΎΡ Π½Π° ΠΈΠ½ΡΠ΅ΡΡΠ΅ΡΡΠΎΡ lo, ΡΡΠΎ Π΅ ΡΠ΅ΠΊΠΎΠ³Π°Ρ 1. ΠΠ° ΠΈΠ·Π²ΡΡΡΠ²Π°ΠΌΠ΅ ΡΡΠ½ΠΊΡΠΈΡΠ°ΡΠ° Π΄Π²Π°ΠΏΠ°ΡΠΈ Π·Π° ΠΏΡΠ²ΠΎ Π΄Π° ΡΠ° ΠΎΡΠΊΠ°ΡΠΈΠΌΠ΅ ΡΡΠ°ΡΠ°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° Π΄ΠΎΠΊΠΎΠ»ΠΊΡ Π΅ ΠΏΡΠΈΠΊΠ°ΡΠ΅Π½Π°. ΠΠ°Π±Π΅Π»Π΅ΠΆΠ΅ΡΠ΅ Π΄Π΅ΠΊΠ° ΡΠ΅Π³Π° Π½Π΅ Π½ΠΈ ΡΡΠ΅Π±Π° ΠΏΡΠ΅Π΄ΠΈΠ·Π²ΠΈΠΊ pause ΠΈΠ»ΠΈ Π±Π΅ΡΠΊΠΎΠ½Π΅ΡΠ½Π° ΡΠ°ΠΌΠΊΠ°: Π½Π°ΡΠ°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° Π·Π° Π²ΡΠΈΡΡΠ²Π°ΡΠ΅ ΡΠ΅ ΠΈΠ·Π»Π΅Π·Π΅, Π½ΠΎ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° BPF Π½Π΅ΠΌΠ° Π΄Π° Π±ΠΈΠ΄Π΅ ΡΠ±ΠΈΠ΅Π½Π° Π±ΠΈΠ΄Π΅ΡΡΠΈ Π΅ ΠΏΠΎΠ²ΡΠ·Π°Π½Π° ΡΠΎ ΠΈΠ·Π²ΠΎΡΠΎΡ Π½Π° Π½Π°ΡΡΠ°Π½ΠΎΡ. ΠΠΎ ΡΡΠΏΠ΅ΡΠ½ΠΎ ΠΏΡΠ΅Π·Π΅ΠΌΠ°ΡΠ΅ ΠΈ ΠΏΠΎΠ²ΡΠ·ΡΠ²Π°ΡΠ΅, ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° ΡΠ΅ ΡΠ΅ ΡΡΠ°ΡΡΡΠ²Π° Π·Π° ΡΠ΅ΠΊΠΎΡ ΠΌΡΠ΅ΠΆΠ΅Π½ ΠΏΠ°ΠΊΠ΅Ρ ΡΡΠΎ ΡΠ΅ ΠΏΡΠΈΡΡΠΈΠ³Π½Π΅ lo.
ΠΡΠ΄Π΅ Π΄Π° ΡΠ° ΠΏΡΠ΅Π·Π΅ΠΌΠ΅ΠΌΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° ΠΈ Π΄Π° Π³ΠΎ ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΡΡΠΎΡ lo:
$ sudo ./xdp-simple
$ sudo bpftool p | grep simple
669: xdp name simple tag 4fca62e77ccb43d6 gpl
$ ip l show dev lo
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 xdpgeneric qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
prog/xdp id 669ΠΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° ΡΡΠΎ ΡΠ° ΠΏΡΠ΅Π·Π΅ΠΌΠ°Π²ΠΌΠ΅ ΠΈΠΌΠ° ID 669 ΠΈ Π³ΠΎ Π³Π»Π΅Π΄Π°ΠΌΠ΅ ΠΈΡΡΠΈΠΎΡ ID Π½Π° ΠΈΠ½ΡΠ΅ΡΡΠ΅ΡΡΠΎΡ lo. ΠΠ΅ ΠΈΡΠΏΡΠ°ΡΠΈΠΌΠ΅ Π½Π΅ΠΊΠΎΠ»ΠΊΡ ΠΏΠ°ΠΊΠ΅ΡΠΈ Π΄ΠΎ 127.0.0.1 (Π±Π°ΡΠ°ΡΠ΅ + ΠΎΠ΄Π³ΠΎΠ²ΠΎΡ):
$ ping -c1 localhostΠ° ΡΠ΅Π³Π° Π΄Π° ΡΠ° ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ ΡΠΎΠ΄ΡΠΆΠΈΠ½Π°ΡΠ° Π½Π° Π²ΠΈΡΡΡΠ΅Π»Π½Π°ΡΠ° Π΄Π°ΡΠΎΡΠ΅ΠΊΠ° Π·Π° ΠΎΡΡΡΡΠ°Π½ΡΠ²Π°ΡΠ΅ Π³ΡΠ΅ΡΠΊΠΈ /sys/kernel/debug/tracing/trace_pipe, Π²ΠΎ ΠΊΠΎΡΠ° bpf_printk Π³ΠΈ ΠΏΠΈΡΡΠ²Π° ΡΠ²ΠΎΠΈΡΠ΅ ΠΏΠΎΡΠ°ΠΊΠΈ:
# cat /sys/kernel/debug/tracing/trace_pipe
ping-13937 [000] d.s1 442015.377014: bpf_trace_printk: running on CPU0
ping-13937 [000] d.s1 442015.377027: bpf_trace_printk: running on CPU0ΠΠ΅Π° Π·Π°Π±Π΅Π»Π΅ΠΆΠ°Π½ΠΈ Π΄Π²Π° ΠΏΠ°ΠΊΠ΅ΡΠΈ lo ΠΈ ΠΎΠ±ΡΠ°Π±ΠΎΡΠ΅Π½Π° Π½Π° CPU0 - Π½Π°ΡΠ°ΡΠ° ΠΏΡΠ²Π° ΠΏΠΎΠ»Π½ΠΎΠΏΡΠ°Π²Π½Π° Π±Π΅ΡΠΌΠΈΡΠ»Π΅Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° BPF ΡΠ°Π±ΠΎΡΠ΅ΡΠ΅!
ΠΡΠ΅Π΄ΠΈ Π΄Π° ΡΠ΅ Π½Π°ΠΏΠΎΠΌΠ΅Π½Π΅ Π΄Π΅ΠΊΠ° bpf_printk ΠΠ΅ Π΅ Π·Π° ΡΠ°Π±Π΅ ΡΡΠΎ ΠΏΠΈΡΡΠ²Π° Π²ΠΎ Π΄Π°ΡΠΎΡΠ΅ΠΊΠ°ΡΠ° Π·Π° ΠΎΡΡΡΡΠ°Π½ΡΠ²Π°ΡΠ΅ Π³ΡΠ΅ΡΠΊΠΈ: ΠΎΠ²Π° Π½Π΅ Π΅ Π½Π°ΡΡΡΠΏΠ΅ΡΠ½ΠΈΠΎΡ ΠΏΠΎΠΌΠΎΡΠ½ΠΈΠΊ Π·Π° ΡΠΏΠΎΡΡΠ΅Π±Π° Π²ΠΎ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΡΡΠ²ΠΎΡΠΎ, Π½ΠΎ Π½Π°ΡΠ°ΡΠ° ΡΠ΅Π» Π±Π΅ΡΠ΅ Π΄Π° ΠΏΠΎΠΊΠ°ΠΆΠ΅ΠΌΠ΅ Π½Π΅ΡΡΠΎ Π΅Π΄Π½ΠΎΡΡΠ°Π²Π½ΠΎ.
ΠΡΠΈΡΡΠ°ΠΏ Π΄ΠΎ ΠΌΠ°ΠΏΠΈ ΠΎΠ΄ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ΅ BPF
ΠΡΠΈΠΌΠ΅Ρ: ΠΊΠΎΡΠΈΡΡΠ΅ΡΠ΅ Π½Π° ΠΌΠ°ΠΏΠ° ΠΎΠ΄ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° BPF
ΠΠΎ ΠΏΡΠ΅ΡΡ
ΠΎΠ΄Π½ΠΈΡΠ΅ Π΄Π΅Π»ΠΎΠ²ΠΈ Π½Π°ΡΡΠΈΠ²ΠΌΠ΅ ΠΊΠ°ΠΊΠΎ Π΄Π° ΠΊΡΠ΅ΠΈΡΠ°ΠΌΠ΅ ΠΈ ΠΊΠΎΡΠΈΡΡΠΈΠΌΠ΅ ΠΌΠ°ΠΏΠΈ ΠΎΠ΄ ΠΊΠΎΡΠΈΡΠ½ΠΈΡΠΊΠΈΠΎΡ ΠΏΡΠΎΡΡΠΎΡ, Π° ΡΠ΅Π³Π° Π΄Π° Π³ΠΎ ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ Π΄Π΅Π»ΠΎΡ Π½Π° ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ. ΠΠ° ΠΏΠΎΡΠ½Π΅ΠΌΠ΅, ΠΊΠ°ΠΊΠΎ ΠΈ ΠΎΠ±ΠΈΡΠ½ΠΎ, ΡΠΎ ΠΏΡΠΈΠΌΠ΅Ρ. ΠΡΠ΄Π΅ Π΄Π° ΡΠ° ΠΏΡΠ΅ΡΠ°Π±ΠΎΡΠΈΠΌΠ΅ Π½Π°ΡΠ°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° xdp-simple.bpf.c ΠΊΠ°ΠΊΠΎ ΡΡΠΎ ΡΠ»Π΅Π΄ΡΠ²Π°:
#include "vmlinux.h"
#include <bpf/bpf_helpers.h>
struct {
__uint(type, BPF_MAP_TYPE_ARRAY);
__uint(max_entries, 8);
__type(key, u32);
__type(value, u64);
} woo SEC(".maps");
SEC("xdp/simple")
int simple(void *ctx)
{
u32 key = bpf_get_smp_processor_id();
u32 *val;
val = bpf_map_lookup_elem(&woo, &key);
if (!val)
return XDP_ABORTED;
*val += 1;
return XDP_PASS;
}
char LICENSE[] SEC("license") = "GPL";ΠΠ° ΠΏΠΎΡΠ΅ΡΠΎΠΊΠΎΡ Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° Π΄ΠΎΠ΄Π°Π΄ΠΎΠ²ΠΌΠ΅ Π΄Π΅ΡΠΈΠ½ΠΈΡΠΈΡΠ° Π·Π° ΠΌΠ°ΠΏΠ° woo: ΠΠ²Π° Π΅ Π½ΠΈΠ·Π° ΡΠΎ 8 Π΅Π»Π΅ΠΌΠ΅Π½ΡΠΈ ΡΡΠΎ ΡΠΊΠ»Π°Π΄ΠΈΡΠ° Π²ΡΠ΅Π΄Π½ΠΎΡΡΠΈ ΠΊΠ°ΠΊΠΎ u64 (Π²ΠΎ C Π±ΠΈ Π΄Π΅ΡΠΈΠ½ΠΈΡΠ°Π»Π΅ ΡΠ°ΠΊΠ²Π° Π½ΠΈΠ·Π° ΠΊΠ°ΠΊΠΎ u64 woo[8]). ΠΠΎ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° "xdp/simple" Π³ΠΎ Π΄ΠΎΠ±ΠΈΠ²Π°ΠΌΠ΅ ΡΠ΅ΠΊΠΎΠ²Π½ΠΈΠΎΡ Π±ΡΠΎΡ Π½Π° ΠΏΡΠΎΡΠ΅ΡΠΎΡΠΎΡ Π²ΠΎ ΠΏΡΠΎΠΌΠ΅Π½Π»ΠΈΠ²Π° key Π° ΠΏΠΎΡΠΎΠ° ΡΠΎ ΠΏΠΎΠΌΠΎΡ Π½Π° ΡΡΠ½ΠΊΡΠΈΡΠ°ΡΠ° ΠΏΠΎΠΌΠΎΡΠ½ΠΈΠΊ bpf_map_lookup_element Π΄ΠΎΠ±ΠΈΠ²Π°ΠΌΠ΅ ΠΏΠΎΠΊΠ°ΠΆΡΠ²Π°Ρ Π΄ΠΎ ΡΠΎΠΎΠ΄Π²Π΅ΡΠ½ΠΈΠΎΡ Π·Π°ΠΏΠΈΡ Π²ΠΎ Π½ΠΈΠ·Π°ΡΠ°, ΠΊΠΎΡ Π³ΠΎ Π·Π³ΠΎΠ»Π΅ΠΌΡΠ²Π°ΠΌΠ΅ Π·Π° Π΅Π΄Π΅Π½. ΠΡΠ΅Π²Π΅Π΄Π΅Π½ΠΎ Π½Π° ΡΡΡΠΊΠΈ: Π½ΠΈΠ΅ ΠΏΡΠ΅ΡΠΌΠ΅ΡΡΠ²Π°ΠΌΠ΅ ΡΡΠ°ΡΠΈΡΡΠΈΠΊΠ° Π·Π° ΡΠΎΠ° ΠΊΠΎΡ ΠΏΡΠΎΡΠ΅ΡΠΎΡΠΎΡ Π³ΠΈ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠ²Π°Π» Π΄ΠΎΡΠ΄ΠΎΠ²Π½ΠΈΡΠ΅ ΠΏΠ°ΠΊΠ΅ΡΠΈ. ΠΡΠ΄Π΅ Π΄Π° ΡΠ΅ ΠΎΠ±ΠΈΠ΄Π΅ΠΌΠ΅ Π΄Π° ΡΠ° ΠΈΠ·Π²ΡΡΠΈΠΌΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ°:
$ clang -O2 -g -c -target bpf -I libbpf/src/root/usr/include xdp-simple.bpf.c -o xdp-simple.bpf.o
$ bpftool gen skeleton xdp-simple.bpf.o > xdp-simple.skel.h
$ clang -O2 -g -I ./libbpf/src/root/usr/include/ -o xdp-simple xdp-simple.c ./libbpf/src/root/usr/lib64/libbpf.a -lelf -lz
$ sudo ./xdp-simpleΠΡΠ΄Π΅ Π΄Π° ΠΏΡΠΎΠ²Π΅ΡΠΈΠΌΠ΅ Π΄Π°Π»ΠΈ Π΅ ΠΏΠΎΠ²ΡΠ·Π°Π½Π° ΡΠΎ lo ΠΈ ΠΈΡΠΏΡΠ°ΡΠ΅ΡΠ΅ Π½Π΅ΠΊΠΎΠ»ΠΊΡ ΠΏΠ°ΠΊΠ΅ΡΠΈ:
$ ip l show dev lo
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 xdpgeneric qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
prog/xdp id 108
$ for s in `seq 234`; do sudo ping -f -c 100 127.0.0.1 >/dev/null 2>&1; doneΠ‘Π΅Π³Π° Π΄Π° ΡΠ° ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ ΡΠΎΠ΄ΡΠΆΠΈΠ½Π°ΡΠ° Π½Π° Π½ΠΈΠ·Π°ΡΠ°:
$ sudo bpftool map dump name woo
[
{ "key": 0, "value": 0 },
{ "key": 1, "value": 400 },
{ "key": 2, "value": 0 },
{ "key": 3, "value": 0 },
{ "key": 4, "value": 0 },
{ "key": 5, "value": 0 },
{ "key": 6, "value": 0 },
{ "key": 7, "value": 46400 }
]Π Π΅ΡΠΈΡΠΈ ΡΠΈΡΠ΅ ΠΏΡΠΎΡΠ΅ΡΠΈ Π±Π΅Π° ΠΎΠ±ΡΠ°Π±ΠΎΡΠ΅Π½ΠΈ Π½Π° CPU7. ΠΠ²Π° Π½Π΅ Π½ΠΈ Π΅ Π²Π°ΠΆΠ½ΠΎ, Π³Π»Π°Π²Π½Π°ΡΠ° ΡΠ°Π±ΠΎΡΠ° Π΅ ΡΡΠΎ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° ΡΠ°Π±ΠΎΡΠΈ ΠΈ ΡΠ°Π·Π±ΠΈΡΠ°ΠΌΠ΅ ΠΊΠ°ΠΊΠΎ Π΄Π° ΠΏΡΠΈΡΡΠ°ΠΏΠΈΠΌΠ΅ Π΄ΠΎ ΠΌΠ°ΠΏΠΈ ΠΎΠ΄ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ΅ BPF - ΠΊΠΎΡΠΈΡΡΠ΅ΡΡΠΈ .
ΠΠΈΡΡΠΈΡΠ΅Π½ ΠΈΠ½Π΄Π΅ΠΊΡ
ΠΠ½Π°ΡΠΈ, ΠΌΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° ΠΏΡΠΈΡΡΠ°ΠΏΠΈΠΌΠ΅ Π΄ΠΎ ΠΊΠ°ΡΡΠ°ΡΠ° ΠΎΠ΄ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° BPF ΠΊΠΎΡΠΈΡΡΠ΅ΡΡΠΈ ΠΏΠΎΠ²ΠΈΡΠΈ ΠΊΠ°ΠΊΠΎ
val = bpf_map_lookup_elem(&woo, &key);ΠΊΠ°Π΄Π΅ ΡΡΠΎ ΠΈΠ·Π³Π»Π΅Π΄Π° ΡΡΠ½ΠΊΡΠΈΡΠ°ΡΠ° ΠΏΠΎΠΌΠΎΡΠ½ΠΈΠΊ
void *bpf_map_lookup_elem(struct bpf_map *map, const void *key)Π½ΠΎ Π½ΠΈΠ΅ ΠΏΠΎΠΌΠΈΠ½ΡΠ²Π°ΠΌΠ΅ ΠΏΠΎΠΊΠ°ΠΆΡΠ²Π°Ρ &woo Π½Π° Π½Π΅ΠΈΠΌΠ΅Π½ΡΠ²Π°Π½Π° ΡΡΡΡΠΊΡΡΡΠ° struct { ... }...
ΠΠΊΠΎ Π³ΠΎ ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ Π°ΡΠ΅ΠΌΠ±Π»Π΅ΡΠΎΡ Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ°, ΡΠ΅ Π²ΠΈΠ΄ΠΈΠΌΠ΅ Π΄Π΅ΠΊΠ° Π²ΡΠ΅Π΄Π½ΠΎΡΡΠ° &woo Π²ΡΡΡΠ½ΠΎΡΡ Π½Π΅ Π΅ Π΄Π΅ΡΠΈΠ½ΠΈΡΠ°Π½ΠΎ (Π»ΠΈΠ½ΠΈΡΠ° 4):
llvm-objdump -D --section xdp/simple xdp-simple.bpf.o
xdp-simple.bpf.o: file format elf64-bpf
Disassembly of section xdp/simple:
0000000000000000 <simple>:
0: 85 00 00 00 08 00 00 00 call 8
1: 63 0a fc ff 00 00 00 00 *(u32 *)(r10 - 4) = r0
2: bf a2 00 00 00 00 00 00 r2 = r10
3: 07 02 00 00 fc ff ff ff r2 += -4
4: 18 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r1 = 0 ll
6: 85 00 00 00 01 00 00 00 call 1
...ΠΈ Π΅ ΡΠΎΠ΄ΡΠΆΠ°Π½ Π²ΠΎ ΠΏΡΠ΅ΠΌΠ΅ΡΡΡΠ²Π°ΡΠ°ΡΠ°:
$ llvm-readelf -r xdp-simple.bpf.o | head -4
Relocation section '.relxdp/simple' at offset 0xe18 contains 1 entries:
Offset Info Type Symbol's Value Symbol's Name
0000000000000020 0000002700000001 R_BPF_64_64 0000000000000000 wooΠΠΎ, Π°ΠΊΠΎ ΡΠ° ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ Π²Π΅ΡΠ΅ Π²ΡΠΈΡΠ°Π½Π°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°, Π³Π»Π΅Π΄Π°ΠΌΠ΅ ΠΏΠΎΠΊΠ°ΠΆΡΠ²Π°Ρ ΠΊΠΎΠ½ ΠΏΡΠ°Π²ΠΈΠ»Π½Π°ΡΠ° ΠΊΠ°ΡΡΠ° (Π»ΠΈΠ½ΠΈΡΠ° 4):
$ sudo bpftool prog dump x name simple
int simple(void *ctx):
0: (85) call bpf_get_smp_processor_id#114128
1: (63) *(u32 *)(r10 -4) = r0
2: (bf) r2 = r10
3: (07) r2 += -4
4: (18) r1 = map[id:64]
...Π’Π°ΠΊΠ°, ΠΌΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° Π·Π°ΠΊΠ»ΡΡΠΈΠΌΠ΅ Π΄Π΅ΠΊΠ° Π²ΠΎ ΠΌΠΎΠΌΠ΅Π½ΡΠΎΡ Π½Π° ΡΡΠ°ΡΡΡΠ²Π°ΡΠ΅ Π½Π° Π½Π°ΡΠ°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° Π·Π° Π²ΡΠΈΡΡΠ²Π°ΡΠ΅, Π²ΡΡΠΊΠ°ΡΠ° Π΄ΠΎ &woo Π±Π΅ΡΠ΅ Π·Π°ΠΌΠ΅Π½Π΅Ρ ΡΠΎ Π½Π΅ΡΡΠΎ ΡΠΎ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° libbpf. ΠΡΠ²ΠΎ ΡΠ΅ Π³ΠΎ ΡΠ°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ ΠΈΠ·Π»Π΅Π·ΠΎΡ strace:
$ sudo strace -e bpf ./xdp-simple
...
bpf(BPF_MAP_CREATE, {map_type=BPF_MAP_TYPE_ARRAY, key_size=4, value_size=8, max_entries=8, map_name="woo", ...}, 120) = 4
bpf(BPF_PROG_LOAD, {prog_type=BPF_PROG_TYPE_XDP, prog_name="simple", ...}, 120) = 5ΠΠΎ Π³Π»Π΅Π΄Π°ΠΌΠ΅ ΡΠΎΠ° libbpf ΡΠΎΠ·Π΄Π°Π΄Π΅ ΠΌΠ°ΠΏΠ° woo Π° ΠΏΠΎΡΠΎΠ° ΡΠ° ΠΏΡΠ΅Π·Π΅ΠΌΠ°Π²ΠΌΠ΅ Π½Π°ΡΠ°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° simple. ΠΡΠ΄Π΅ Π²Π½ΠΈΠΌΠ°ΡΠ΅Π»Π½ΠΎ Π΄Π° ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ ΠΊΠ°ΠΊΠΎ ΡΠ° Π²ΡΠΈΡΡΠ²Π°ΠΌΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ°:
- ΡΠ°Π²Π΅ΡΠ΅ ΡΠ΅
xdp_simple_bpf__open_and_loadΠΎΠ΄ Π΄Π°ΡΠΎΡΠ΅ΠΊΠ°xdp-simple.skel.h - ΡΡΠΎ ΠΏΡΠ΅Π΄ΠΈΠ·Π²ΠΈΠΊΡΠ²Π°
xdp_simple_bpf__loadΠΎΠ΄ Π΄Π°ΡΠΎΡΠ΅ΠΊΠ°xdp-simple.skel.h - ΡΡΠΎ ΠΏΡΠ΅Π΄ΠΈΠ·Π²ΠΈΠΊΡΠ²Π°
bpf_object__load_skeletonΠΎΠ΄ Π΄Π°ΡΠΎΡΠ΅ΠΊΠ°libbpf/src/libbpf.c - ΡΡΠΎ ΠΏΡΠ΅Π΄ΠΈΠ·Π²ΠΈΠΊΡΠ²Π°
bpf_object__load_xattrΠ½Π°libbpf/src/libbpf.c
ΠΠΎΡΠ»Π΅Π΄Π½Π°ΡΠ° ΡΡΠ½ΠΊΡΠΈΡΠ°, ΠΌΠ΅ΡΡ Π΄ΡΡΠ³ΠΎΡΠΎ, ΡΠ΅ ΡΠ΅ ΡΠ°Π²ΠΈ bpf_object__create_maps, ΠΊΠΎΡ ΡΠΎΠ·Π΄Π°Π²Π° ΠΈΠ»ΠΈ ΠΎΡΠ²ΠΎΡΠ° ΠΏΠΎΡΡΠΎΠ΅ΡΠΊΠΈ ΠΌΠ°ΠΏΠΈ, ΠΏΡΠ΅ΡΠ²ΠΎΡΠ°ΡΡΠΈ Π³ΠΈ Π²ΠΎ Π΄Π΅ΡΠΊΡΠΈΠΏΡΠΎΡΠΈ Π½Π° Π΄Π°ΡΠΎΡΠ΅ΠΊΠΈ. (ΠΠ²Π΄Π΅ Π³Π»Π΅Π΄Π°ΠΌΠ΅ BPF_MAP_CREATE Π²ΠΎ ΠΈΠ·Π»Π΅Π·ΠΎΡ strace.) ΠΠΎΡΠΎΠ° ΡΠ΅ ΠΏΠΎΠ²ΠΈΠΊΡΠ²Π° ΡΡΠ½ΠΊΡΠΈΡΠ°ΡΠ° bpf_object__relocate ΠΈ ΡΠ°Π° Π΅ ΡΠ°Π° ΡΡΠΎ Π½Π΅ ΠΈΠ½ΡΠ΅ΡΠ΅ΡΠΈΡΠ°, Π±ΠΈΠ΄Π΅ΡΡΠΈ ΡΠ΅ ΡΠ΅ΡΠ°Π²Π°ΠΌΠ΅ ΡΡΠΎ Π²ΠΈΠ΄ΠΎΠ²ΠΌΠ΅ woo Π²ΠΎ ΡΠ°Π±Π΅Π»Π°ΡΠ° Π·Π° ΠΏΡΠ΅ΠΌΠ΅ΡΡΡΠ²Π°ΡΠ΅. ΠΡΡΡΠ°ΠΆΡΠ²Π°ΡΡΠΈ Π³ΠΎ, Π½Π° ΠΊΡΠ°ΡΠΎΡ ΡΠ΅ Π½Π°ΠΎΡΠ°ΠΌΠ΅ Π²ΠΎ ΡΡΠ½ΠΊΡΠΈΡΠ° bpf_program__relocate, ΠΊΠΎΠΈ :
case RELO_LD64:
insn[0].src_reg = BPF_PSEUDO_MAP_FD;
insn[0].imm = obj->maps[relo->map_idx].fd;
break;ΠΠ°ΡΠΎΠ°, Π³ΠΈ Π·Π΅ΠΌΠ°ΠΌΠ΅ Π½Π°ΡΠΈΡΠ΅ ΡΠΏΠ°ΡΡΡΠ²Π°
18 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r1 = 0 llΠΈ Π·Π°ΠΌΠ΅Π½Π΅ΡΠ΅ Π³ΠΎ ΠΈΠ·Π²ΠΎΡΠ½ΠΈΠΎΡ ΡΠ΅Π³ΠΈΡΡΠ°Ρ Π²ΠΎ Π½Π΅Π³ΠΎ ΡΠΎ BPF_PSEUDO_MAP_FD, ΠΈ ΠΏΡΠ²ΠΈΠΎΡ IMM Π½Π° Π΄Π΅ΡΠΊΡΠΈΠΏΡΠΎΡΠΎΡ Π½Π° Π΄Π°ΡΠΎΡΠ΅ΠΊΠ°ΡΠ° Π½Π° Π½Π°ΡΠ°ΡΠ° ΠΊΠ°ΡΡΠ° ΠΈ, Π°ΠΊΠΎ Π΅ Π΅Π΄Π½Π°ΠΊΠΎΠ² Π½Π°, Π½Π° ΠΏΡΠΈΠΌΠ΅Ρ, 0xdeadbeef, ΡΠΎΠ³Π°Ρ ΠΊΠ°ΠΊΠΎ ΡΠ΅Π·ΡΠ»ΡΠ°Ρ ΡΠ΅ ΡΠ° Π΄ΠΎΠ±ΠΈΠ΅ΠΌΠ΅ ΠΈΠ½ΡΡΡΡΠΊΡΠΈΡΠ°ΡΠ°
18 11 00 00 ef eb ad de 00 00 00 00 00 00 00 00 r1 = 0 llΠΠ²Π° Π΅ Π½Π°ΡΠΈΠ½ΠΎΡ Π½Π° ΠΊΠΎΡ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΠΈΡΠ΅ Π·Π° ΠΊΠ°ΡΡΠ°ΡΠ° ΡΠ΅ ΠΏΡΠ΅Π½Π΅ΡΡΠ²Π°Π°Ρ Π½Π° ΠΎΠ΄ΡΠ΅Π΄Π΅Π½Π° Π²ΡΠΈΡΠ°Π½Π° BPF ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°. ΠΠΎ ΠΎΠ²ΠΎΡ ΡΠ»ΡΡΠ°Ρ, ΠΌΠ°ΠΏΠ°ΡΠ° ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ ΠΊΡΠ΅ΠΈΡΠ° ΡΠΎ ΠΊΠΎΡΠΈΡΡΠ΅ΡΠ΅ BPF_MAP_CREATE, ΠΈ ΡΠ΅ ΠΎΡΠ²ΠΎΡΠΈ ΡΠΎ ID ΠΊΠΎΡΠΈΡΡΠ΅ΡΡΠΈ BPF_MAP_GET_FD_BY_ID.
ΠΠΊΡΠΏΠ½ΠΎ, ΠΏΡΠΈ ΠΊΠΎΡΠΈΡΡΠ΅ΡΠ΅ libbpf Π°Π»Π³ΠΎΡΠΈΡΠΌΠΎΡ Π΅ ΠΊΠ°ΠΊΠΎ ΡΡΠΎ ΡΠ»Π΅Π΄ΡΠ²Π°:
- Π·Π° Π²ΡΠ΅ΠΌΠ΅ Π½Π° ΠΊΠΎΠΌΠΏΠΈΠ»Π°ΡΠΈΡΠ°ΡΠ°, Π²ΠΎ ΡΠ°Π±Π΅Π»Π°ΡΠ° Π·Π° ΠΏΡΠ΅ΠΌΠ΅ΡΡΡΠ²Π°ΡΠ΅ ΡΠ΅ ΠΊΡΠ΅ΠΈΡΠ°Π°Ρ Π·Π°ΠΏΠΈΡΠΈ Π·Π° Π²ΡΡΠΊΠΈ Π΄ΠΎ ΠΌΠ°ΠΏΠΈ
libbpfΡΠ° ΠΎΡΠ²ΠΎΡΠ° ΠΊΠ½ΠΈΠ³Π°ΡΠ° ΡΠΎ ΠΎΠ±ΡΠ΅ΠΊΡΠΈ ELF, Π³ΠΈ Π½Π°ΠΎΡΠ° ΡΠΈΡΠ΅ ΠΊΠΎΡΠΈΡΡΠ΅Π½ΠΈ ΠΌΠ°ΠΏΠΈ ΠΈ ΡΠΎΠ·Π΄Π°Π²Π° Π΄Π΅ΡΠΊΡΠΈΠΏΡΠΎΡΠΈ Π½Π° Π΄Π°ΡΠΎΡΠ΅ΠΊΠΈ Π·Π° Π½ΠΈΠ²- Π΄Π΅ΡΠΊΡΠΈΠΏΡΠΎΡΠΈΡΠ΅ Π½Π° Π΄Π°ΡΠΎΡΠ΅ΠΊΠΈΡΠ΅ ΡΠ΅ Π²ΡΠΈΡΡΠ²Π°Π°Ρ Π²ΠΎ ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ ΠΊΠ°ΠΊΠΎ Π΄Π΅Π» ΠΎΠ΄ ΠΈΠ½ΡΡΡΡΠΊΡΠΈΡΠ°ΡΠ°
LD64
ΠΠ°ΠΊΠΎ ΡΡΠΎ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° Π·Π°ΠΌΠΈΡΠ»ΠΈΡΠ΅, ΠΏΡΠ΅ΡΡΡΠΎΠΈ ΡΡΡΠ΅ ΠΏΠΎΠ²Π΅ΡΠ΅ ΠΈ ΡΠ΅ ΠΌΠΎΡΠ°ΠΌΠ΅ Π΄Π° ΡΠ° ΡΠ°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ ΡΡΡΡΠΈΠ½Π°ΡΠ°. ΠΠ° ΡΡΠ΅ΡΠ°, ΠΈΠΌΠ°ΠΌΠ΅ ΠΏΠΎΠΈΠΌ - Π³ΠΎ Π·Π°ΠΏΠΈΡΠ°Π²ΠΌΠ΅ Π·Π½Π°ΡΠ΅ΡΠ΅ΡΠΎ BPF_PSEUDO_MAP_FD Π²ΠΎ ΠΈΠ·Π²ΠΎΡΠ½ΠΈΠΎΡ ΡΠ΅Π³ΠΈΡΡΠ°Ρ ΠΈ ΠΌΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° Π³ΠΎ Π·Π°ΠΊΠΎΠΏΠ°ΠΌΠ΅, ΡΡΠΎ ΡΠ΅ Π½Π΅ ΠΎΠ΄Π²Π΅Π΄Π΅ Π΄ΠΎ ΡΠ²Π΅ΡΠΈΡΠ°ΡΠ° Π½Π° ΡΠΈΡΠ΅ ΡΠ²Π΅ΡΡΠΈ - kernel/bpf/verifier.c, ΠΊΠ°Π΄Π΅ ΡΡΠΎ ΡΡΠ½ΠΊΡΠΈΡΠ°ΡΠ° ΡΠΎ ΠΊΠ°ΡΠ°ΠΊΡΠ΅ΡΠΈΡΡΠΈΡΠ½ΠΎ ΠΈΠΌΠ΅ Π·Π°ΠΌΠ΅Π½ΡΠ²Π° Π΄Π΅ΡΠΊΡΠΈΠΏΡΠΎΡ Π½Π° Π΄Π°ΡΠΎΡΠ΅ΠΊΠ° ΡΠΎ Π°Π΄ΡΠ΅ΡΠ° Π½Π° ΡΡΡΡΠΊΡΡΡΠ° ΠΎΠ΄ ΡΠΈΠΏΠΎΡ struct bpf_map:
static int replace_map_fd_with_map_ptr(struct bpf_verifier_env *env) {
...
f = fdget(insn[0].imm);
map = __bpf_map_get(f);
if (insn->src_reg == BPF_PSEUDO_MAP_FD) {
addr = (unsigned long)map;
}
insn[0].imm = (u32)addr;
insn[1].imm = addr >> 32;(ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ Π½Π°ΡΠ΄Π΅ ΡΠ΅Π»ΠΎΡΠ½ΠΈΠΎΡ ΠΊΠΎΠ΄ ). Π’Π°ΠΊΠ°, ΠΌΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° Π³ΠΎ ΠΏΡΠΎΡΠΈΡΠΈΠΌΠ΅ Π½Π°ΡΠΈΠΎΡ Π°Π»Π³ΠΎΡΠΈΡΠ°ΠΌ:
- Π΄ΠΎΠ΄Π΅ΠΊΠ° ΡΠ° Π²ΡΠΈΡΡΠ²Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ°, Π²Π΅ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΠΎΡ ΡΠ° ΠΏΡΠΎΠ²Π΅ΡΡΠ²Π° ΠΏΡΠ°Π²ΠΈΠ»Π½Π°ΡΠ° ΡΠΏΠΎΡΡΠ΅Π±Π° Π½Π° ΠΊΠ°ΡΡΠ°ΡΠ° ΠΈ ΡΠ° ΠΏΠΈΡΡΠ²Π° Π°Π΄ΡΠ΅ΡΠ°ΡΠ° Π½Π° ΡΠΎΠΎΠ΄Π²Π΅ΡΠ½Π°ΡΠ° ΡΡΡΡΠΊΡΡΡΠ°
struct bpf_map
ΠΠΎΠ³Π° ΡΠ° ΠΏΡΠ΅Π·Π΅ΠΌΠ°ΡΠ΅ Π±ΠΈΠ½Π°ΡΠ½Π°ΡΠ° ELF ΠΊΠΎΡΠΈΡΡΠ΅ΡΡΠΈ libbpf ΠΠΌΠ° ΡΡΡΠ΅ ΠΌΠ½ΠΎΠ³Ρ ΡΠ°Π±ΠΎΡΠΈ, Π½ΠΎ ΡΠ΅ ΡΠ°Π·Π³ΠΎΠ²Π°ΡΠ°ΠΌΠ΅ Π·Π° ΡΠΎΠ° Π²ΠΎ Π΄ΡΡΠ³ΠΈ ΡΡΠ°ΡΠΈΠΈ.
ΠΡΠΈΡΡΠ²Π°ΡΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ ΠΈ ΠΌΠ°ΠΏΠΈ Π±Π΅Π· libbpf
ΠΠ°ΠΊΠΎ ΡΡΠΎ Π²Π΅ΡΠΈΠ²ΠΌΠ΅, Π΅Π²Π΅ ΠΏΡΠΈΠΌΠ΅Ρ Π·Π° ΡΠΈΡΠ°ΡΠ΅Π»ΠΈΡΠ΅ ΠΊΠΎΠΈ ΡΠ°ΠΊΠ°Π°Ρ Π΄Π° Π·Π½Π°Π°Ρ ΠΊΠ°ΠΊΠΎ Π΄Π° ΠΊΡΠ΅ΠΈΡΠ°Π°Ρ ΠΈ Π²ΡΠΈΡΠ°Π°Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° ΡΡΠΎ ΠΊΠΎΡΠΈΡΡΠΈ ΠΌΠ°ΠΏΠΈ, Π±Π΅Π· ΠΏΠΎΠΌΠΎΡ libbpf. ΠΠ²Π° ΠΌΠΎΠΆΠ΅ Π΄Π° Π±ΠΈΠ΄Π΅ ΠΊΠΎΡΠΈΡΠ½ΠΎ ΠΊΠΎΠ³Π° ΡΠ°Π±ΠΎΡΠΈΡΠ΅ Π²ΠΎ ΡΡΠ΅Π΄ΠΈΠ½Π° Π·Π° ΠΊΠΎΡΠ° Π½Π΅ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΡΠΎΠ·Π΄Π°Π²Π°ΡΠ΅ Π·Π°Π²ΠΈΡΠ½ΠΎΡΡΠΈ, ΠΈΠ»ΠΈ Π΄Π° Π³ΠΎ Π·Π°ΡΡΠ²ΡΠ²Π°ΡΠ΅ ΡΠ΅ΠΊΠΎΡ Π΄Π΅Π» ΠΈΠ»ΠΈ ΠΊΠΎΠ³Π° ΠΏΠΈΡΡΠ²Π°ΡΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° ΠΊΠ°ΠΊΠΎ , ΠΊΠΎΡ Π³Π΅Π½Π΅ΡΠΈΡΠ° Π±ΠΈΠ½Π°ΡΠ΅Π½ ΠΊΠΎΠ΄ BPF Π²ΠΎ Π»Π΅Ρ.
ΠΠ° ΠΏΠΎΠ»Π΅ΡΠ½ΠΎ Π΄Π° ΡΠ΅ ΡΠ»Π΅Π΄ΠΈ Π»ΠΎΠ³ΠΈΠΊΠ°ΡΠ°, ΡΠ΅ Π³ΠΎ ΠΏΡΠ΅ΡΠ°Π±ΠΎΡΠΈΠΌΠ΅ Π½Π°ΡΠΈΠΎΡ ΠΏΡΠΈΠΌΠ΅Ρ Π·Π° ΠΎΠ²ΠΈΠ΅ ΡΠ΅Π»ΠΈ xdp-simple. Π¦Π΅Π»ΠΎΡΠ½ΠΈΠΎΡ ΠΈ ΠΌΠ°Π»ΠΊΡ ΠΏΡΠΎΡΠΈΡΠ΅Π½ ΠΊΠΎΠ΄ Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° Π΄ΠΈΡΠΊΡΡΠΈΡΠ°Π½Π° Π²ΠΎ ΠΎΠ²ΠΎΡ ΠΏΡΠΈΠΌΠ΅Ρ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ Π½Π°ΡΠ΄Π΅ Π²ΠΎ ΠΎΠ²Π° .
ΠΠΎΠ³ΠΈΠΊΠ°ΡΠ° Π½Π° Π½Π°ΡΠ°ΡΠ° Π°ΠΏΠ»ΠΈΠΊΠ°ΡΠΈΡΠ° Π΅ ΡΠ»Π΅Π΄Π½Π°:
- ΠΊΡΠ΅ΠΈΡΠ°ΡΡΠ΅ ΠΌΠ°ΠΏΠ° Π½Π° ΡΠΈΠΏ
BPF_MAP_TYPE_ARRAYΠΊΠΎΡΠΈΡΡΠ΅ΡΡΠΈ ΡΠ° ΠΊΠΎΠΌΠ°Π½Π΄Π°ΡΠ°BPF_MAP_CREATE, - ΠΊΡΠ΅ΠΈΡΠ°ΡΡΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° ΡΡΠΎ ΡΠ° ΠΊΠΎΡΠΈΡΡΠΈ ΠΎΠ²Π°Π° ΠΊΠ°ΡΡΠ°,
- ΠΏΠΎΠ²ΡΠ·Π΅ΡΠ΅ ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° ΡΠΎ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΡΡΠΎΡ
lo,
ΡΡΠΎ ΡΠ΅ ΠΏΡΠ΅Π²Π΅Π΄ΡΠ²Π° Π²ΠΎ ΡΠΎΠ²Π΅ΡΠΊΠΎ ΠΊΠ°ΠΊΠΎ
int main(void)
{
int map_fd, prog_fd;
map_fd = map_create();
if (map_fd < 0)
err(1, "bpf: BPF_MAP_CREATE");
prog_fd = prog_load(map_fd);
if (prog_fd < 0)
err(1, "bpf: BPF_PROG_LOAD");
xdp_attach(1, prog_fd);
}Π’ΡΠΊΠ° map_create ΡΠΎΠ·Π΄Π°Π²Π° ΠΊΠ°ΡΡΠ° Π½Π° ΠΈΡΡ Π½Π°ΡΠΈΠ½ ΠΊΠ°ΠΊΠΎ ΡΡΠΎ Π½Π°ΠΏΡΠ°Π²ΠΈΠ²ΠΌΠ΅ Π²ΠΎ ΠΏΡΠ²ΠΈΠΎΡ ΠΏΡΠΈΠΌΠ΅Ρ Π·Π° ΡΠΈΡΡΠ΅ΠΌΡΠΊΠΈΠΎΡ ΠΏΠΎΠ²ΠΈΠΊ bpf - βΠΠ°Π΄ΡΠΎ, ΡΠ΅ ΠΌΠΎΠ»Π°ΠΌ Π½Π°ΠΏΡΠ°Π²ΠΈ ΠΌΠΈ Π½ΠΎΠ²Π° ΠΌΠ°ΠΏΠ° Π²ΠΎ ΡΠΎΡΠΌΠ° Π½Π° Π½ΠΈΠ·Π° ΠΎΠ΄ 8 Π΅Π»Π΅ΠΌΠ΅Π½ΡΠΈ ΠΊΠ°ΠΊΠΎ __u64 ΠΈ Π²ΡΠ°ΡΠ΅ΡΠ΅ ΠΌΠΈ Π³ΠΎ Π΄Π΅ΡΠΊΡΠΈΠΏΡΠΎΡΠΎΡ Π½Π° Π΄Π°ΡΠΎΡΠ΅ΠΊΠ°ΡΠ°β:
static int map_create()
{
union bpf_attr attr;
memset(&attr, 0, sizeof(attr));
attr.map_type = BPF_MAP_TYPE_ARRAY,
attr.key_size = sizeof(__u32),
attr.value_size = sizeof(__u64),
attr.max_entries = 8,
strncpy(attr.map_name, "woo", sizeof(attr.map_name));
return syscall(__NR_bpf, BPF_MAP_CREATE, &attr, sizeof(attr));
}ΠΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° Π΅ ΠΈΡΡΠΎ ΡΠ°ΠΊΠ° Π»Π΅ΡΠ½Π° Π·Π° Π²ΡΠΈΡΡΠ²Π°ΡΠ΅:
static int prog_load(int map_fd)
{
union bpf_attr attr;
struct bpf_insn insns[] = {
...
};
memset(&attr, 0, sizeof(attr));
attr.prog_type = BPF_PROG_TYPE_XDP;
attr.insns = ptr_to_u64(insns);
attr.insn_cnt = sizeof(insns)/sizeof(insns[0]);
attr.license = ptr_to_u64("GPL");
strncpy(attr.prog_name, "woo", sizeof(attr.prog_name));
return syscall(__NR_bpf, BPF_PROG_LOAD, &attr, sizeof(attr));
}Π’Π΅ΡΠΊΠΈΠΎΡ Π΄Π΅Π» prog_load Π΅ Π΄Π΅ΡΠΈΠ½ΠΈΡΠΈΡΠ°ΡΠ° Π½Π° Π½Π°ΡΠ°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° BPF ΠΊΠ°ΠΊΠΎ Π½ΠΈΠ·Π° ΡΡΡΡΠΊΡΡΡΠΈ struct bpf_insn insns[]. ΠΠΎ, Π±ΠΈΠ΄Π΅ΡΡΠΈ ΠΊΠΎΡΠΈΡΡΠΈΠΌΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° ΡΡΠΎ ΡΠ° ΠΈΠΌΠ°ΠΌΠ΅ Π²ΠΎ C, ΠΌΠΎΠΆΠ΅ΠΌΠ΅ ΠΌΠ°Π»ΠΊΡ Π΄Π° ΠΈΠ·ΠΌΠ°ΠΌΠΈΠΌΠ΅:
$ llvm-objdump -D --section xdp/simple xdp-simple.bpf.o
0000000000000000 <simple>:
0: 85 00 00 00 08 00 00 00 call 8
1: 63 0a fc ff 00 00 00 00 *(u32 *)(r10 - 4) = r0
2: bf a2 00 00 00 00 00 00 r2 = r10
3: 07 02 00 00 fc ff ff ff r2 += -4
4: 18 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r1 = 0 ll
6: 85 00 00 00 01 00 00 00 call 1
7: b7 01 00 00 00 00 00 00 r1 = 0
8: 15 00 04 00 00 00 00 00 if r0 == 0 goto +4 <LBB0_2>
9: 61 01 00 00 00 00 00 00 r1 = *(u32 *)(r0 + 0)
10: 07 01 00 00 01 00 00 00 r1 += 1
11: 63 10 00 00 00 00 00 00 *(u32 *)(r0 + 0) = r1
12: b7 01 00 00 02 00 00 00 r1 = 2
0000000000000068 <LBB0_2>:
13: bf 10 00 00 00 00 00 00 r0 = r1
14: 95 00 00 00 00 00 00 00 exitΠ‘Π΅Π²ΠΊΡΠΏΠ½ΠΎ, ΡΡΠ΅Π±Π° Π΄Π° Π½Π°ΠΏΠΈΡΠ΅ΠΌΠ΅ 14 ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈ Π²ΠΎ ΡΠΎΡΠΌΠ° Π½Π° ΡΡΡΡΠΊΡΡΡΠΈ ΠΊΠ°ΠΊΠΎ struct bpf_insn (ΡΠΎΠ²Π΅Ρ: Π·Π΅ΠΌΠ΅ΡΠ΅ Π³ΠΎ Π΄Π΅ΠΏΠΎΠ½ΠΈΡΠ°ΡΠ° ΠΎΠ΄ΠΎΠ·Π³ΠΎΡΠ°, ΠΏΠΎΠ²ΡΠΎΡΠ½ΠΎ ΠΏΡΠΎΡΠΈΡΠ°ΡΡΠ΅ Π³ΠΎ Π΄Π΅Π»ΠΎΡ Π·Π° ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈ, ΠΎΡΠ²ΠΎΡΠ΅ΡΠ΅ ΠΈ ΠΈ ΠΎΠ±ΠΈΠ΄Π΅ΡΠ΅ ΡΠ΅ Π΄Π° ΠΎΠ΄ΡΠ΅Π΄ΠΈΡΠ΅ struct bpf_insn insns[] ΡΠ°ΠΌ):
struct bpf_insn insns[] = {
/* 85 00 00 00 08 00 00 00 call 8 */
{
.code = BPF_JMP | BPF_CALL,
.imm = 8,
},
/* 63 0a fc ff 00 00 00 00 *(u32 *)(r10 - 4) = r0 */
{
.code = BPF_MEM | BPF_STX,
.off = -4,
.src_reg = BPF_REG_0,
.dst_reg = BPF_REG_10,
},
/* bf a2 00 00 00 00 00 00 r2 = r10 */
{
.code = BPF_ALU64 | BPF_MOV | BPF_X,
.src_reg = BPF_REG_10,
.dst_reg = BPF_REG_2,
},
/* 07 02 00 00 fc ff ff ff r2 += -4 */
{
.code = BPF_ALU64 | BPF_ADD | BPF_K,
.dst_reg = BPF_REG_2,
.imm = -4,
},
/* 18 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r1 = 0 ll */
{
.code = BPF_LD | BPF_DW | BPF_IMM,
.src_reg = BPF_PSEUDO_MAP_FD,
.dst_reg = BPF_REG_1,
.imm = map_fd,
},
{ }, /* placeholder */
/* 85 00 00 00 01 00 00 00 call 1 */
{
.code = BPF_JMP | BPF_CALL,
.imm = 1,
},
/* b7 01 00 00 00 00 00 00 r1 = 0 */
{
.code = BPF_ALU64 | BPF_MOV | BPF_K,
.dst_reg = BPF_REG_1,
.imm = 0,
},
/* 15 00 04 00 00 00 00 00 if r0 == 0 goto +4 <LBB0_2> */
{
.code = BPF_JMP | BPF_JEQ | BPF_K,
.off = 4,
.src_reg = BPF_REG_0,
.imm = 0,
},
/* 61 01 00 00 00 00 00 00 r1 = *(u32 *)(r0 + 0) */
{
.code = BPF_MEM | BPF_LDX,
.off = 0,
.src_reg = BPF_REG_0,
.dst_reg = BPF_REG_1,
},
/* 07 01 00 00 01 00 00 00 r1 += 1 */
{
.code = BPF_ALU64 | BPF_ADD | BPF_K,
.dst_reg = BPF_REG_1,
.imm = 1,
},
/* 63 10 00 00 00 00 00 00 *(u32 *)(r0 + 0) = r1 */
{
.code = BPF_MEM | BPF_STX,
.src_reg = BPF_REG_1,
.dst_reg = BPF_REG_0,
},
/* b7 01 00 00 02 00 00 00 r1 = 2 */
{
.code = BPF_ALU64 | BPF_MOV | BPF_K,
.dst_reg = BPF_REG_1,
.imm = 2,
},
/* <LBB0_2>: bf 10 00 00 00 00 00 00 r0 = r1 */
{
.code = BPF_ALU64 | BPF_MOV | BPF_X,
.src_reg = BPF_REG_1,
.dst_reg = BPF_REG_0,
},
/* 95 00 00 00 00 00 00 00 exit */
{
.code = BPF_JMP | BPF_EXIT
},
};ΠΠ΅ΠΆΠ±Π° Π·Π° ΠΎΠ½ΠΈΠ΅ ΠΊΠΎΠΈ ΡΠ°ΠΌΠΈΡΠ΅ Π½Π΅ Π³ΠΎ Π½Π°ΠΏΠΈΡΠ°Π»Π΅ ΠΎΠ²Π° - Π½Π°ΡΠ΄Π΅ΡΠ΅ map_fd.
ΠΠΎ Π½Π°ΡΠ°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° ΠΎΡΡΠ°Π½Π° ΡΡΡΠ΅ Π΅Π΄Π΅Π½ Π½Π΅ΠΎΡΠΊΡΠΈΠ΅Π½ Π΄Π΅Π» - xdp_attach. ΠΠ° ΠΆΠ°Π», ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ΅ ΠΊΠ°ΠΊΠΎ XDP Π½Π΅ ΠΌΠΎΠΆΠ°Ρ Π΄Π° ΡΠ΅ ΠΏΠΎΠ²ΡΠ·Π°Ρ ΠΊΠΎΡΠΈΡΡΠ΅ΡΡΠΈ ΡΠΈΡΡΠ΅ΠΌΡΠΊΠΈ ΠΏΠΎΠ²ΠΈΠΊ bpfΠΡΡΠ΅ΡΠΎ ΡΡΠΎ Π³ΠΈ ΡΠΎΠ·Π΄Π°Π΄ΠΎΠ° BPF ΠΈ XDP Π±Π΅Π° ΠΎΠ΄ ΠΎΠ½Π»Π°ΡΠ½ Π·Π°Π΅Π΄Π½ΠΈΡΠ°ΡΠ°. Linux, ΡΡΠΎ Π·Π½Π°ΡΠΈ Π΄Π΅ΠΊΠ° Π³ΠΎ ΠΊΠΎΡΠΈΡΡΠ΅Π»Π΅ ΠΎΠ½ΠΎΡ ΡΡΠΎ ΠΈΠΌ Π±ΠΈΠ» Π½Π°ΡΠΏΠΎΠ·Π½Π°Ρ (Π½ΠΎ Π½Π΅ Π·Π° Π½ΠΎΡΠΌΠ°Π»Π½ΠΎ Π»ΡΡΠ΅) ΠΈΠ½ΡΠ΅ΡΡΠ΅ΡΡ Π·Π° ΠΈΠ½ΡΠ΅ΡΠ°ΠΊΡΠΈΡΠ° ΡΠΎ ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ: , ΠΈΡΡΠΎ ΡΠ°ΠΊΠ° Π²ΠΈΠ΄ΠΈ . ΠΠ°ΡΠ΅Π΄Π½ΠΎΡΡΠ°Π²Π½ΠΈΠΎΡ Π½Π°ΡΠΈΠ½ Π·Π° ΠΈΠΌΠΏΠ»Π΅ΠΌΠ΅Π½ΡΠ°ΡΠΈΡΠ° xdp_attach Π³ΠΎ ΠΊΠΎΠΏΠΈΡΠ° ΠΊΠΎΠ΄ΠΎΡ ΠΎΠ΄ libbpf, ΠΈΠΌΠ΅Π½ΠΎ, ΠΎΠ΄ Π΄Π°ΡΠΎΡΠ΅ΠΊΠ°ΡΠ° , ΡΡΠΎ ΠΈ Π³ΠΎ Π½Π°ΠΏΡΠ°Π²ΠΈΠ²ΠΌΠ΅, ΡΠΊΡΠ°ΡΡΠ²Π°ΡΡΠΈ Π³ΠΎ ΠΌΠ°Π»ΠΊΡ:
ΠΠΎΠ±ΡΠ΅Π΄ΠΎΡΠ΄ΠΎΠ²ΡΠ΅ Π²ΠΎ ΡΠ²Π΅ΡΠΎΡ Π½Π° Π½Π΅ΡΠ»ΠΈΠ½ΠΊ ΠΏΡΠΈΠΊΠ»ΡΡΠΎΡΠΈΡΠ΅
ΠΡΠ²ΠΎΡΠ΅ΡΠ΅ ΡΠΈΠΏ Π½Π° ΠΌΡΠ΅ΠΆΠ΅Π½ ΠΏΡΠΈΠΊΠ»ΡΡΠΎΠΊ NETLINK_ROUTE:
int netlink_open(__u32 *nl_pid)
{
struct sockaddr_nl sa;
socklen_t addrlen;
int one = 1, ret;
int sock;
memset(&sa, 0, sizeof(sa));
sa.nl_family = AF_NETLINK;
sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
if (sock < 0)
err(1, "socket");
if (setsockopt(sock, SOL_NETLINK, NETLINK_EXT_ACK, &one, sizeof(one)) < 0)
warnx("netlink error reporting not supported");
if (bind(sock, (struct sockaddr *)&sa, sizeof(sa)) < 0)
err(1, "bind");
addrlen = sizeof(sa);
if (getsockname(sock, (struct sockaddr *)&sa, &addrlen) < 0)
err(1, "getsockname");
*nl_pid = sa.nl_pid;
return sock;
}Π§ΠΈΡΠ°ΠΌΠ΅ ΠΎΠ΄ ΠΎΠ²ΠΎΡ ΡΠΎΠΊΠ΅Ρ:
static int bpf_netlink_recv(int sock, __u32 nl_pid, int seq)
{
bool multipart = true;
struct nlmsgerr *errm;
struct nlmsghdr *nh;
char buf[4096];
int len, ret;
while (multipart) {
multipart = false;
len = recv(sock, buf, sizeof(buf), 0);
if (len < 0)
err(1, "recv");
if (len == 0)
break;
for (nh = (struct nlmsghdr *)buf; NLMSG_OK(nh, len);
nh = NLMSG_NEXT(nh, len)) {
if (nh->nlmsg_pid != nl_pid)
errx(1, "wrong pid");
if (nh->nlmsg_seq != seq)
errx(1, "INVSEQ");
if (nh->nlmsg_flags & NLM_F_MULTI)
multipart = true;
switch (nh->nlmsg_type) {
case NLMSG_ERROR:
errm = (struct nlmsgerr *)NLMSG_DATA(nh);
if (!errm->error)
continue;
ret = errm->error;
// libbpf_nla_dump_errormsg(nh); too many code to copy...
goto done;
case NLMSG_DONE:
return 0;
default:
break;
}
}
}
ret = 0;
done:
return ret;
}ΠΠΎΠ½Π΅ΡΠ½ΠΎ, ΡΡΠΊΠ° Π΅ Π½Π°ΡΠ°ΡΠ° ΡΡΠ½ΠΊΡΠΈΡΠ° ΠΊΠΎΡΠ° ΠΎΡΠ²ΠΎΡΠ° ΡΠΎΠΊΠ΅Ρ ΠΈ ΠΈΡΠΏΡΠ°ΡΠ° ΠΏΠΎΡΠ΅Π±Π½Π° ΠΏΠΎΡΠ°ΠΊΠ° Π΄ΠΎ Π½Π΅Π³ΠΎ ΡΡΠΎ ΡΠΎΠ΄ΡΠΆΠΈ Π΄Π΅ΡΠΊΡΠΈΠΏΡΠΎΡ Π½Π° Π΄Π°ΡΠΎΡΠ΅ΠΊΠ°:
static int xdp_attach(int ifindex, int prog_fd)
{
int sock, seq = 0, ret;
struct nlattr *nla, *nla_xdp;
struct {
struct nlmsghdr nh;
struct ifinfomsg ifinfo;
char attrbuf[64];
} req;
__u32 nl_pid = 0;
sock = netlink_open(&nl_pid);
if (sock < 0)
return sock;
memset(&req, 0, sizeof(req));
req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
req.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
req.nh.nlmsg_type = RTM_SETLINK;
req.nh.nlmsg_pid = 0;
req.nh.nlmsg_seq = ++seq;
req.ifinfo.ifi_family = AF_UNSPEC;
req.ifinfo.ifi_index = ifindex;
/* started nested attribute for XDP */
nla = (struct nlattr *)(((char *)&req)
+ NLMSG_ALIGN(req.nh.nlmsg_len));
nla->nla_type = NLA_F_NESTED | IFLA_XDP;
nla->nla_len = NLA_HDRLEN;
/* add XDP fd */
nla_xdp = (struct nlattr *)((char *)nla + nla->nla_len);
nla_xdp->nla_type = IFLA_XDP_FD;
nla_xdp->nla_len = NLA_HDRLEN + sizeof(int);
memcpy((char *)nla_xdp + NLA_HDRLEN, &prog_fd, sizeof(prog_fd));
nla->nla_len += nla_xdp->nla_len;
/* if user passed in any flags, add those too */
__u32 flags = XDP_FLAGS_SKB_MODE;
nla_xdp = (struct nlattr *)((char *)nla + nla->nla_len);
nla_xdp->nla_type = IFLA_XDP_FLAGS;
nla_xdp->nla_len = NLA_HDRLEN + sizeof(flags);
memcpy((char *)nla_xdp + NLA_HDRLEN, &flags, sizeof(flags));
nla->nla_len += nla_xdp->nla_len;
req.nh.nlmsg_len += NLA_ALIGN(nla->nla_len);
if (send(sock, &req, req.nh.nlmsg_len, 0) < 0)
err(1, "send");
ret = bpf_netlink_recv(sock, nl_pid, seq);
cleanup:
close(sock);
return ret;
}ΠΠ½Π°ΡΠΈ, ΡΓ¨ Π΅ ΠΏΠΎΠ΄Π³ΠΎΡΠ²Π΅Π½ΠΎ Π·Π° ΡΠ΅ΡΡΠΈΡΠ°ΡΠ΅:
$ cc nolibbpf.c -o nolibbpf
$ sudo strace -e bpf ./nolibbpf
bpf(BPF_MAP_CREATE, {map_type=BPF_MAP_TYPE_ARRAY, map_name="woo", ...}, 72) = 3
bpf(BPF_PROG_LOAD, {prog_type=BPF_PROG_TYPE_XDP, insn_cnt=15, prog_name="woo", ...}, 72) = 4
+++ exited with 0 +++ΠΡΠ΄Π΅ Π΄Π° Π²ΠΈΠ΄ΠΈΠΌΠ΅ Π΄Π°Π»ΠΈ Π½Π°ΡΠ°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° Π΅ ΠΏΠΎΠ²ΡΠ·Π°Π½Π° ΡΠΎ lo:
$ ip l show dev lo
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 xdpgeneric qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
prog/xdp id 160ΠΡΠ΄Π΅ Π΄Π° ΠΈΡΠΏΡΠ°ΡΠΈΠΌΠ΅ ΠΏΠΈΠ½Π³ ΠΈ Π΄Π° ΡΠ° ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ ΠΌΠ°ΠΏΠ°ΡΠ°:
$ for s in `seq 234`; do sudo ping -f -c 100 127.0.0.1 >/dev/null 2>&1; done
$ sudo bpftool m dump name woo
key: 00 00 00 00 value: 90 01 00 00 00 00 00 00
key: 01 00 00 00 value: 00 00 00 00 00 00 00 00
key: 02 00 00 00 value: 00 00 00 00 00 00 00 00
key: 03 00 00 00 value: 00 00 00 00 00 00 00 00
key: 04 00 00 00 value: 00 00 00 00 00 00 00 00
key: 05 00 00 00 value: 00 00 00 00 00 00 00 00
key: 06 00 00 00 value: 40 b5 00 00 00 00 00 00
key: 07 00 00 00 value: 00 00 00 00 00 00 00 00
Found 8 elementsΠ£ΡΠ°, ΡΓ¨ ΡΠ°Π±ΠΎΡΠΈ. ΠΠ°Π±Π΅Π»Π΅ΠΆΠ΅ΡΠ΅, ΠΏΠ°ΡΠ΅ΠΌ, Π΄Π΅ΠΊΠ° Π½Π°ΡΠ°ΡΠ° ΠΊΠ°ΡΡΠ° ΠΏΠΎΠ²ΡΠΎΡΠ½ΠΎ Π΅ ΠΏΡΠΈΠΊΠ°ΠΆΠ°Π½Π° Π²ΠΎ ΡΠΎΡΠΌΠ° Π½Π° Π±Π°ΡΡΠΈ. ΠΠ²Π° ΡΠ΅ Π΄ΠΎΠ»ΠΆΠΈ Π½Π° ΡΠ°ΠΊΡΠΎΡ Π΄Π΅ΠΊΠ°, Π·Π° ΡΠ°Π·Π»ΠΈΠΊΠ° ΠΎΠ΄ libbpf Π½Π΅ Π²ΡΠΈΡΠ°Π²ΠΌΠ΅ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΠΈ Π·Π° ΡΠΈΠΏΠΎΡ (BTF). ΠΠΎ, ΡΠ»Π΅Π΄Π½ΠΈΠΎΡ ΠΏΠ°Ρ ΡΠ΅ Π·Π±ΠΎΡΡΠ²Π°ΠΌΠ΅ ΠΏΠΎΠ²Π΅ΡΠ΅ Π·Π° ΠΎΠ²Π°.
ΠΠ»Π°ΡΠΊΠΈ Π·Π° ΡΠ°Π·Π²ΠΎΡ
ΠΠΎ ΠΎΠ²ΠΎΡ Π΄Π΅Π», ΡΠ΅ Π³ΠΎ ΡΠ°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»Π½ΠΈΠΎΡ ΠΏΠ°ΠΊΠ΅Ρ ΡΠΎ Π°Π»Π°ΡΠΊΠΈ Π·Π° ΡΠ°Π·Π²ΠΈΠ²Π°ΡΠΈ Π½Π° BPF.
ΠΠΏΡΡΠΎ Π·Π΅ΠΌΠ΅Π½ΠΎ, Π½Π΅ Π²ΠΈ ΡΡΠ΅Π±Π° Π½ΠΈΡΡΠΎ ΠΏΠΎΡΠ΅Π±Π½ΠΎ Π·Π° Π΄Π° ΡΠ°Π·Π²ΠΈΠ΅ΡΠ΅ BPF ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ - BPF ΡΠ°Π±ΠΎΡΠΈ Π½Π° ΠΊΠΎΠ΅ Π±ΠΈΠ»ΠΎ ΠΏΡΠΈΡΡΠΎΡΠ½ΠΎ ΡΠ°Π΄ΡΠΎ Π·Π° Π΄ΠΈΡΡΡΠΈΠ±ΡΡΠΈΡΠ°, Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ΅ ΡΠ΅ ΠΈΠ·Π³ΡΠ°Π΄Π΅Π½ΠΈ ΡΠΎ ΠΊΠΎΡΠΈΡΡΠ΅ΡΠ΅ clang, ΠΊΠΎΡ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ Π½Π°Π±Π°Π²ΠΈ ΠΎΠ΄ ΠΏΠ°ΠΊΡΠ²Π°ΡΠ΅ΡΠΎ. Π‘Π΅ΠΏΠ°ΠΊ, ΠΏΠΎΡΠ°Π΄ΠΈ ΡΠ°ΠΊΡΠΎΡ ΡΡΠΎ BPF Π΅ Π²ΠΎ ΡΠ°Π·Π²ΠΎΡ, ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ ΠΈ Π°Π»Π°ΡΠΊΠΈΡΠ΅ ΠΏΠΎΡΡΠΎΡΠ°Π½ΠΎ ΡΠ΅ ΠΌΠ΅Π½ΡΠ²Π°Π°Ρ, Π°ΠΊΠΎ Π½Π΅ ΡΠ°ΠΊΠ°ΡΠ΅ Π΄Π° ΠΏΠΈΡΡΠ²Π°ΡΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ Π·Π° BPF ΠΊΠΎΡΠΈΡΡΠ΅ΡΡΠΈ ΡΡΠ°ΡΠΎΠΌΠΎΠ΄Π½ΠΈ ΠΌΠ΅ΡΠΎΠ΄ΠΈ ΠΎΠ΄ 2019 Π³ΠΎΠ΄ΠΈΠ½Π°, ΡΠΎΠ³Π°Ρ ΡΠ΅ ΠΌΠΎΡΠ° Π΄Π° ΠΊΠΎΠΌΠΏΠ°ΡΠ»ΠΈΡΠ°ΡΠ΅
llvm/clangpahole- Π½Π΅Π³ΠΎΠ²ΠΎΡΠΎ ΡΠ°Π΄ΡΠΎ
bpftool
(ΠΠ° ΡΠ΅ΡΠ΅ΡΠ΅Π½ΡΠ°: ΠΎΠ²ΠΎΡ Π΄Π΅Π» ΠΈ ΡΠΈΡΠ΅ ΠΏΡΠΈΠΌΠ΅ΡΠΈ Π²ΠΎ ΡΡΠ°ΡΠΈΡΠ°ΡΠ° Π±Π΅Π° ΠΈΠ·Π²ΡΡΠ΅Π½ΠΈ Π½Π° Debian 10.)
llvm/clang
BPF Π΅ ΠΏΡΠΈΡΠ°ΡΠ΅Π»ΡΠΊΠΈ ΡΠ°ΡΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ ΡΠΎ LLVM ΠΈ, ΠΈΠ°ΠΊΠΎ Π½Π΅ΠΎΠ΄Π°ΠΌΠ½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ΅ Π·Π° BPF ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ ΠΊΠΎΠΌΠΏΠ°ΡΠ»ΠΈΡΠ°Π°Ρ ΡΠΎ ΠΊΠΎΡΠΈΡΡΠ΅ΡΠ΅ Π½Π° gcc, ΡΠ΅Π»ΠΈΠΎΡ ΡΠ΅ΠΊΠΎΠ²Π΅Π½ ΡΠ°Π·Π²ΠΎΡ Π΅ ΠΈΠ·Π²ΡΡΠ΅Π½ Π·Π° LLVM. ΠΠ°ΡΠΎΠ°, ΠΏΡΠ΅Π΄ ΡΓ¨, ΡΠ΅ ΡΠ° ΠΈΠ·Π³ΡΠ°Π΄ΠΈΠΌΠ΅ ΡΠ΅ΠΊΠΎΠ²Π½Π°ΡΠ° Π²Π΅ΡΠ·ΠΈΡΠ° clang ΠΎΠ΄ git:
$ sudo apt install ninja-build
$ git clone --depth 1 https://github.com/llvm/llvm-project.git
$ mkdir -p llvm-project/llvm/build/install
$ cd llvm-project/llvm/build
$ cmake .. -G "Ninja" -DLLVM_TARGETS_TO_BUILD="BPF;X86"
-DLLVM_ENABLE_PROJECTS="clang"
-DBUILD_SHARED_LIBS=OFF
-DCMAKE_BUILD_TYPE=Release
-DLLVM_BUILD_RUNTIME=OFF
$ time ninja
... ΠΌΠ½ΠΎΠ³ΠΎ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ ΡΠΏΡΡΡΡ
$Π‘Π΅Π³Π° ΠΌΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° ΠΏΡΠΎΠ²Π΅ΡΠΈΠΌΠ΅ Π΄Π°Π»ΠΈ ΡΓ¨ ΡΠ΅ ΡΠΎΠ±ΡΠ°Π»ΠΎ ΠΏΡΠ°Π²ΠΈΠ»Π½ΠΎ:
$ ./bin/llc --version
LLVM (http://llvm.org/):
LLVM version 11.0.0git
Optimized build.
Default target: x86_64-unknown-linux-gnu
Host CPU: znver1
Registered Targets:
bpf - BPF (host endian)
bpfeb - BPF (big endian)
bpfel - BPF (little endian)
x86 - 32-bit X86: Pentium-Pro and above
x86-64 - 64-bit X86: EM64T and AMD64(Π£ΠΏΠ°ΡΡΡΠ²ΠΎ Π·Π° ΡΠΊΠ»ΠΎΠΏΡΠ²Π°ΡΠ΅ clang ΠΏΡΠ΅Π·Π΅ΠΌΠ΅Π½ΠΎ ΠΎΠ΄ ΠΌΠ΅Π½Π΅ ΠΎΠ΄ .)
ΠΠ΅ΠΌΠ° Π΄Π° Π³ΠΈ ΠΈΠ½ΡΡΠ°Π»ΠΈΡΠ°ΠΌΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ΅ ΡΡΠΎ ΡΡΠΎΡΡΠΊΡ Π³ΠΈ ΠΈΠ·Π³ΡΠ°Π΄ΠΈΠ²ΠΌΠ΅, ΡΡΠΊΡ ΡΠ°ΠΌΠΎ Π΄Π° Π³ΠΈ Π΄ΠΎΠ΄Π°Π΄Π΅ΠΌΠ΅ Π²ΠΎ Π½ΠΈΠ² PATH, Π½Π° ΠΏΡΠΈΠΌΠ΅Ρ:
export PATH="`pwd`/bin:$PATH"(ΠΠ²Π° ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ Π΄ΠΎΠ΄Π°Π΄Π΅ Π½Π° .bashrc ΠΈΠ»ΠΈ Π²ΠΎ ΠΏΠΎΡΠ΅Π±Π½Π° Π΄Π°ΡΠΎΡΠ΅ΠΊΠ°. ΠΠΈΡΠ½ΠΎ, Π΄ΠΎΠ΄Π°Π²Π°ΠΌ Π²Π°ΠΊΠ²ΠΈ ΡΠ°Π±ΠΎΡΠΈ ~/bin/activate-llvm.sh ΠΈ ΠΊΠΎΠ³Π° Π΅ ΠΏΠΎΡΡΠ΅Π±Π½ΠΎ Π³ΠΎ ΠΏΡΠ°Π²Π°ΠΌ ΡΠΎΠ° . activate-llvm.sh.)
ΠΠ°Ρ ΠΎΠ» ΠΈ ΠΠ’Π€
ΠΠ»Π°ΡΠΊΠ° pahole ΡΠ΅ ΠΊΠΎΡΠΈΡΡΠΈ ΠΏΡΠΈ Π³ΡΠ°Π΄Π΅ΡΠ΅ Π½Π° ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ Π·Π° ΠΊΡΠ΅ΠΈΡΠ°ΡΠ΅ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΠΈ Π·Π° Π΄Π΅Π±Π°Π³ΠΈΡΠ°ΡΠ΅ Π²ΠΎ BTF ΡΠΎΡΠΌΠ°Ρ. ΠΠΎ ΠΎΠ²Π°Π° ΡΡΠ°ΡΠΈΡΠ° Π½Π΅ΠΌΠ° Π΄Π° Π½Π°Π²Π»Π΅Π³ΡΠ²Π°ΠΌΠ΅ Π²ΠΎ Π΄Π΅ΡΠ°Π»ΠΈ Π·Π° Π΄Π΅ΡΠ°Π»ΠΈΡΠ΅ Π·Π° BTF ΡΠ΅Ρ
Π½ΠΎΠ»ΠΎΠ³ΠΈΡΠ°ΡΠ°, ΠΎΡΠ²Π΅Π½ ΡΠ°ΠΊΡΠΎΡ Π΄Π΅ΠΊΠ° Π΅ ΠΏΠΎΠ³ΠΎΠ΄Π½Π° ΠΈ ΡΠ°ΠΊΠ°ΠΌΠ΅ Π΄Π° ΡΠ° ΠΊΠΎΡΠΈΡΡΠΈΠΌΠ΅. ΠΠ½Π°ΡΠΈ, Π°ΠΊΠΎ ΡΠ°ΠΊΠ°ΡΠ΅ Π΄Π° Π³ΠΎ ΠΈΠ·Π³ΡΠ°Π΄ΠΈΡΠ΅ Π²Π°ΡΠΈΠΎΡ ΠΊΠ΅ΡΠ½Π΅Π», ΠΏΡΠ²ΠΎ ΠΈΠ·Π³ΡΠ°Π΄ΠΈ pahole (Π±Π΅Π· pahole Π½Π΅ΠΌΠ° Π΄Π° ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° Π³ΠΎ ΠΈΠ·Π³ΡΠ°Π΄ΠΈΡΠ΅ ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ ΡΠΎ ΠΎΠΏΡΠΈΡΠ°ΡΠ° CONFIG_DEBUG_INFO_BTF:
$ git clone https://git.kernel.org/pub/scm/devel/pahole/pahole.git
$ cd pahole/
$ sudo apt install cmake
$ mkdir build
$ cd build/
$ cmake -D__LIB=lib ..
$ make
$ sudo make install
$ which pahole
/usr/local/bin/paholeΠΠ°Π΄ΡΠ° Π·Π° Π΅ΠΊΡΠΏΠ΅ΡΠΈΠΌΠ΅Π½ΡΠΈΡΠ°ΡΠ΅ ΡΠΎ BPF
ΠΠΎΠ³Π° Π³ΠΈ ΠΈΡΡΡΠ°ΠΆΡΠ²Π°ΠΌ ΠΌΠΎΠΆΠ½ΠΎΡΡΠΈΡΠ΅ Π½Π° BPF, ΡΠ°ΠΊΠ°ΠΌ Π΄Π° Π³ΠΎ ΡΠΎΠ±Π΅ΡΠ°ΠΌ ΡΠΎΠΏΡΡΠ²Π΅Π½ΠΎΡΠΎ ΡΠ°Π΄ΡΠΎ. ΠΠ²Π°, Π³Π΅Π½Π΅ΡΠ°Π»Π½ΠΎ ΠΊΠ°ΠΆΠ°Π½ΠΎ, Π½Π΅ Π΅ Π½Π΅ΠΎΠΏΡ ΠΎΠ΄Π½ΠΎ, Π±ΠΈΠ΄Π΅ΡΡΠΈ ΡΠ΅ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° Π³ΠΈ ΠΊΠΎΠΌΠΏΠ°ΡΠ»ΠΈΡΠ°ΡΠ΅ ΠΈ Π²ΡΠΈΡΠ°ΡΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ΅ BPF Π½Π° ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ Π·Π° Π΄ΠΈΡΡΡΠΈΠ±ΡΡΠΈΡΠ°, Π½ΠΎ ΡΠ΅ΠΏΠ°ΠΊ, ΠΏΠΎΡΠ΅Π΄ΡΠ²Π°ΡΠ΅ΡΠΎ ΡΠΎΠΏΡΡΠ²Π΅Π½ ΠΊΠ΅ΡΠ½Π΅Π» Π²ΠΈ ΠΎΠ²ΠΎΠ·ΠΌΠΎΠΆΡΠ²Π° Π΄Π° Π³ΠΈ ΠΊΠΎΡΠΈΡΡΠΈΡΠ΅ Π½Π°ΡΠ½ΠΎΠ²ΠΈΡΠ΅ ΠΊΠ°ΡΠ°ΠΊΡΠ΅ΡΠΈΡΡΠΈΠΊΠΈ Π½Π° BPF, ΠΊΠΎΠΈ Π²ΠΎ Π½Π°ΡΠ΄ΠΎΠ±Π°Ρ ΡΠ»ΡΡΠ°Ρ ΡΠ΅ ΡΠ΅ ΠΏΠΎΡΠ°Π²Π°Ρ Π²ΠΎ Π²Π°ΡΠ°ΡΠ° Π΄ΠΈΡΡΡΠΈΠ±ΡΡΠΈΡΠ° Π·Π° Π½Π΅ΠΊΠΎΠ»ΠΊΡ ΠΌΠ΅ΡΠ΅ΡΠΈ. , ΠΈΠ»ΠΈ, ΠΊΠ°ΠΊΠΎ Π²ΠΎ ΡΠ»ΡΡΠ°ΡΠΎΡ ΡΠΎ Π½Π΅ΠΊΠΎΠΈ Π°Π»Π°ΡΠΊΠΈ Π·Π° Π΄Π΅Π±Π°Π³ΠΈΡΠ°ΡΠ΅, Π²ΠΎΠΎΠΏΡΡΠΎ Π½Π΅ΠΌΠ° Π΄Π° Π±ΠΈΠ΄Π°Ρ ΡΠΏΠ°ΠΊΡΠ²Π°Π½ΠΈ Π²ΠΎ Π΄ΠΎΠ³Π»Π΅Π΄Π½Π° ΠΈΠ΄Π½ΠΈΠ½Π°. ΠΡΡΠΎ ΡΠ°ΠΊΠ°, Π½Π΅Π³ΠΎΠ²ΠΎΡΠΎ ΡΠΎΠΏΡΡΠ²Π΅Π½ΠΎ ΡΠ°Π΄ΡΠΎ ΠΏΡΠ°Π²ΠΈ Π΄Π° ΡΠ΅ ΡΡΠ²ΡΡΠ²ΡΠ²Π° Π²Π°ΠΆΠ½ΠΎ Π΄Π° ΡΠ΅ Π΅ΠΊΡΠΏΠ΅ΡΠΈΠΌΠ΅Π½ΡΠΈΡΠ° ΡΠΎ ΠΊΠΎΠ΄ΠΎΡ.
ΠΠ° Π΄Π° ΠΈΠ·Π³ΡΠ°Π΄ΠΈΡΠ΅ ΠΊΠ΅ΡΠ½Π΅Π», ΠΏΠΎΡΡΠ΅Π±Π΅Π½ Π²ΠΈ Π΅, ΠΏΡΠ²ΠΎ, ΡΠ°ΠΌΠΈΠΎΡ ΠΊΠ΅ΡΠ½Π΅Π», ΠΈ Π²ΡΠΎΡΠΎ, Π΄Π°ΡΠΎΡΠ΅ΠΊΠ° Π·Π° ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡΠ° Π½Π° ΡΠ°Π΄ΡΠΎΡΠΎ. ΠΠ° Π΄Π° Π΅ΠΊΡΠΏΠ΅ΡΠΈΠΌΠ΅Π½ΡΠΈΡΠ°ΠΌΠ΅ ΡΠΎ BPF ΠΌΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° Π³ΠΎ ΠΊΠΎΡΠΈΡΡΠΈΠΌΠ΅ Π²ΠΎΠΎΠ±ΠΈΡΠ°Π΅Π½ΠΎΡΠΎ ΡΠ°Π΄ΡΠΎ ΠΈΠ»ΠΈ Π΅Π΄Π½ΠΎ ΠΎΠ΄ ΡΠ°Π΄ΡΠ°ΡΠ° Π½Π° ΡΠ°Π·Π²ΠΈΠ²Π°ΡΠΈΡΠ΅. ΠΡΡΠΎΡΠΈΡΠΊΠΈ Π³Π»Π΅Π΄Π°Π½ΠΎ, ΡΠ°Π·Π²ΠΎΡΠΎΡ Π½Π° BPF ΡΠ΅ ΠΎΠ΄Π²ΠΈΠ²Π°Π» Π²ΠΎ ΡΠ°ΠΌΠΊΠΈΡΠ΅ Π½Π° ΠΌΡΠ΅ΠΆΠ½Π°ΡΠ° Π·Π°Π΅Π΄Π½ΠΈΡΠ°. Linux ΠΈ Π·Π°ΡΠΎΠ° ΡΠΈΡΠ΅ ΠΏΡΠΎΠΌΠ΅Π½ΠΈ ΠΏΠΎΡΠ°Π½ΠΎ ΠΈΠ»ΠΈ ΠΏΠΎΠ΄ΠΎΡΠ½Π° ΠΎΠ΄Π°Ρ ΠΏΡΠ΅ΠΊΡ ΠΠ΅ΡΠ²ΠΈΠ΄ ΠΠΈΠ»Π΅Ρ, ΠΎΠ΄ΡΠΆΡΠ²Π°ΡΠΎΡ Π½Π° ΠΌΡΠ΅ΠΆΠ°ΡΠ° LinuxΠΠΎ Π·Π°Π²ΠΈΡΠ½ΠΎΡΡ ΠΎΠ΄ Π½ΠΈΠ²Π½Π°ΡΠ° ΠΏΡΠΈΡΠΎΠ΄Π° - ΠΏΠΎΠΏΡΠ°Π²ΠΊΠΈ ΠΈΠ»ΠΈ Π½ΠΎΠ²ΠΈ ΡΡΠ½ΠΊΡΠΈΠΈ - ΠΏΡΠΎΠΌΠ΅Π½ΠΈΡΠ΅ Π²ΠΎ ΠΌΡΠ΅ΠΆΠ°ΡΠ° Π·Π°Π²ΡΡΡΠ²Π°Π°Ρ Π²ΠΎ Π΅Π΄Π½ΠΎ ΠΎΠ΄ Π΄Π²Π΅ΡΠ΅ ΡΠ°Π΄ΡΠ°: ΠΈΠ»ΠΈ . ΠΡΠΎΠΌΠ΅Π½ΠΈΡΠ΅ Π·Π° BPF ΡΠ΅ ΡΠ°ΡΠΏΡΠ΅Π΄Π΅Π»ΡΠ²Π°Π°Ρ Π½Π° ΠΈΡΡ Π½Π°ΡΠΈΠ½ ΠΏΠΎΠΌΠ΅ΡΡ ΠΈ , ΠΊΠΎΠΈ ΠΏΠΎΡΠΎΠ° ΡΠ΅ Π·Π΄ΡΡΠΆΡΠ²Π°Π°Ρ Π²ΠΎ net ΠΈ net-next, ΡΠΎΠΎΠ΄Π²Π΅ΡΠ½ΠΎ. ΠΠ° ΠΏΠΎΠ²Π΅ΡΠ΅ Π΄Π΅ΡΠ°Π»ΠΈ, Π²ΠΈΠ΄Π΅ΡΠ΅ ΠΈ . ΠΠ°ΡΠΎΠ° ΠΈΠ·Π±Π΅ΡΠ΅ΡΠ΅ ΡΠ°Π΄ΡΠΎ Π²ΡΠ· ΠΎΡΠ½ΠΎΠ²Π° Π½Π° Π²Π°ΡΠΈΠΎΡ Π²ΠΊΡΡ ΠΈ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅ Π·Π° ΡΡΠ°Π±ΠΈΠ»Π½ΠΎΡΡ Π½Π° ΡΠΈΡΡΠ΅ΠΌΠΎΡ Π½Π° ΠΊΠΎΡΡΡΠΎ Π³ΠΎ ΡΠ΅ΡΡΠΈΡΠ°ΡΠ΅ (*-next ΠΊΠ΅ΡΠ½Π΅Π»ΠΈΡΠ΅ ΡΠ΅ Π½Π°ΡΠ½Π΅ΡΡΠ°Π±ΠΈΠ»Π½ΠΈ ΠΎΠ΄ Π½Π°Π²Π΅Π΄Π΅Π½ΠΈΡΠ΅).
ΠΠ°Π΄Π²ΠΎΡ ΠΎΠ΄ ΠΎΠΏΡΠ΅Π³ΠΎΡ Π½Π° ΠΎΠ²Π°Π° ΡΡΠ°ΡΠΈΡΠ° Π΅ Π΄Π° ΡΠ΅ Π·Π±ΠΎΡΡΠ²Π° Π·Π° ΡΠΎΠ° ΠΊΠ°ΠΊΠΎ Π΄Π° ΡΠΏΡΠ°Π²ΡΠ²Π°ΡΠ΅ ΡΠΎ Π΄Π°ΡΠΎΡΠ΅ΠΊΠΈΡΠ΅ Π·Π° ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡΠ° Π½Π° ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ - ΡΠ΅ ΠΏΡΠ΅ΡΠΏΠΎΡΡΠ°Π²ΡΠ²Π° Π΄Π΅ΠΊΠ° ΠΈΠ»ΠΈ Π²Π΅ΡΠ΅ Π·Π½Π°Π΅ΡΠ΅ ΠΊΠ°ΠΊΠΎ Π΄Π° Π³ΠΎ Π½Π°ΠΏΡΠ°Π²ΠΈΡΠ΅ ΠΎΠ²Π°, ΠΈΠ»ΠΈ ΡΠ°ΠΌ ΠΏΠΎ ΡΠ΅Π±Π΅. Π‘Π΅ΠΏΠ°ΠΊ, ΡΠ»Π΅Π΄Π½ΠΈΡΠ΅ ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈ ΡΡΠ΅Π±Π° Π΄Π° Π±ΠΈΠ΄Π°Ρ ΠΏΠΎΠ²Π΅ΡΠ΅ ΠΈΠ»ΠΈ ΠΏΠΎΠΌΠ°Π»ΠΊΡ Π΄ΠΎΠ²ΠΎΠ»Π½ΠΈ Π·Π° Π΄Π° Π²ΠΈ Π΄Π°Π΄Π°Ρ ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»Π΅Π½ ΡΠΈΡΡΠ΅ΠΌ ΡΠΎ ΠΎΠ²ΠΎΠ·ΠΌΠΎΠΆΠ΅Π½ BPF.
ΠΡΠ΅Π·Π΅ΠΌΠ΅ΡΠ΅ Π΅Π΄Π½ΠΎ ΠΎΠ΄ Π³ΠΎΡΠ΅Π½Π°Π²Π΅Π΄Π΅Π½ΠΈΡΠ΅ ΠΊΠ΅ΡΠ½Π΅Π»ΠΈ:
$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git
$ cd bpf-nextΠΠ·Π³ΡΠ°Π΄Π΅ΡΠ΅ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»Π½Π° ΡΠ°Π±ΠΎΡΠ½Π° ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡΠ° Π½Π° ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ:
$ cp /boot/config-`uname -r` .config
$ make localmodconfigΠΠ²ΠΎΠ·ΠΌΠΎΠΆΠ΅ΡΠ΅ BPF ΠΎΠΏΡΠΈΠΈ Π²ΠΎ Π΄Π°ΡΠΎΡΠ΅ΠΊΠ°ΡΠ° .config ΠΏΠΎ Π²Π°Ρ ΠΈΠ·Π±ΠΎΡ (Π½Π°ΡΠ²Π΅ΡΠΎΡΠ°ΡΠ½ΠΎ CONFIG_BPF Π²Π΅ΡΠ΅ ΡΠ΅ Π±ΠΈΠ΄Π΅ ΠΎΠ²ΠΎΠ·ΠΌΠΎΠΆΠ΅Π½ΠΎ Π±ΠΈΠ΄Π΅ΡΡΠΈ systemd Π³ΠΎ ΠΊΠΎΡΠΈΡΡΠΈ). ΠΠ²Π΅ ΡΠΏΠΈΡΠΎΠΊ Π½Π° ΠΎΠΏΡΠΈΠΈ ΠΎΠ΄ ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ ΡΡΠΎ ΡΠ΅ ΠΊΠΎΡΠΈΡΡΠΈ Π·Π° ΠΎΠ²Π°Π° ΡΡΠ°ΡΠΈΡΠ°:
CONFIG_CGROUP_BPF=y
CONFIG_BPF=y
CONFIG_BPF_LSM=y
CONFIG_BPF_SYSCALL=y
CONFIG_ARCH_WANT_DEFAULT_BPF_JIT=y
CONFIG_BPF_JIT_ALWAYS_ON=y
CONFIG_BPF_JIT_DEFAULT_ON=y
CONFIG_IPV6_SEG6_BPF=y
# CONFIG_NETFILTER_XT_MATCH_BPF is not set
# CONFIG_BPFILTER is not set
CONFIG_NET_CLS_BPF=y
CONFIG_NET_ACT_BPF=y
CONFIG_BPF_JIT=y
CONFIG_BPF_STREAM_PARSER=y
CONFIG_LWTUNNEL_BPF=y
CONFIG_HAVE_EBPF_JIT=y
CONFIG_BPF_EVENTS=y
CONFIG_BPF_KPROBE_OVERRIDE=y
CONFIG_DEBUG_INFO_BTF=yΠΠΎΡΠΎΠ° ΠΌΠΎΠΆΠ΅ΠΌΠ΅ Π»Π΅ΡΠ½ΠΎ Π΄Π° Π³ΠΈ ΡΠΎΠ±Π΅ΡΠ΅ΠΌΠ΅ ΠΈ ΠΈΠ½ΡΡΠ°Π»ΠΈΡΠ°ΠΌΠ΅ ΠΌΠΎΠ΄ΡΠ»ΠΈΡΠ΅ ΠΈ ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ (ΠΏΠ°ΡΠ΅ΠΌ, ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° Π³ΠΎ ΡΠΎΡΡΠ°Π²ΠΈΡΠ΅ ΠΊΠΎΡΠΈΡΡΠ΅ΡΡΠΈ Π³ΠΎ Π½ΠΎΠ²ΠΎΡΠΎΠ±ΡΠ°Π½ΠΈΠΎΡ clangΡΠΎ Π΄ΠΎΠ΄Π°Π²Π°ΡΠ΅ CC=clang):
$ make -s -j $(getconf _NPROCESSORS_ONLN)
$ sudo make modules_install
$ sudo make installΠΈ ΡΠ΅ ΡΠ΅ΡΡΠ°ΡΡΠΈΡΠ° ΡΠΎ Π½ΠΎΠ²ΠΎΡΠΎ ΡΠ°Π΄ΡΠΎ (ΡΠ°Ρ Π³ΠΎ ΠΊΠΎΡΠΈΡΡΠ°ΠΌ Π·Π° ΠΎΠ²Π° kexec ΠΎΠ΄ ΠΏΠ°ΠΊΡΠ²Π°ΡΠ΅ΡΠΎ kexec-tools):
v=5.8.0-rc6+ # Π΅ΡΠ»ΠΈ Π²Ρ ΠΏΠ΅ΡΠ΅ΡΠΎΠ±ΠΈΡΠ°Π΅ΡΠ΅ ΡΠ΅ΠΊΡΡΠ΅Π΅ ΡΠ΄ΡΠΎ, ΡΠΎ ΠΌΠΎΠΆΠ½ΠΎ Π΄Π΅Π»Π°ΡΡ v=`uname -r`
sudo kexec -l -t bzImage /boot/vmlinuz-$v --initrd=/boot/initrd.img-$v --reuse-cmdline &&
sudo kexec -ebpftool
ΠΠ°ΡΡΠ΅ΡΡΠΎ ΠΊΠΎΡΠΈΡΡΠ΅Π½Π°ΡΠ° Π°Π»Π°ΡΠΊΠ° Π²ΠΎ ΡΡΠ°ΡΠΈΡΠ°ΡΠ° ΡΠ΅ Π±ΠΈΠ΄Π΅ Π°Π»Π°ΡΠΊΠ°ΡΠ° bpftool, ΠΈΡΠΏΠΎΡΠ°ΡΠ°Π½ ΠΊΠ°ΠΊΠΎ Π΄Π΅Π» ΠΎΠ΄ ΡΠ°Π΄ΡΠΎΡΠΎ LinuxΠΠ°ΠΏΠΈΡΠ°Π½ΠΎ Π΅ ΠΈ ΠΎΠ΄ΡΠΆΡΠ²Π°Π½ΠΎ ΠΎΠ΄ ΡΠ°Π·Π²ΠΈΠ²Π°ΡΠΈ Π½Π° BPF Π·Π° ΡΠ°Π·Π²ΠΈΠ²Π°ΡΠΈ Π½Π° BPF ΠΈ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ ΠΊΠΎΡΠΈΡΡΠΈ Π·Π° ΡΠΏΡΠ°Π²ΡΠ²Π°ΡΠ΅ ΡΠΎ ΡΠΈΡΠ΅ Π²ΠΈΠ΄ΠΎΠ²ΠΈ ΠΎΠ±ΡΠ΅ΠΊΡΠΈ Π½Π° BPF - Π²ΡΠΈΡΡΠ²Π°ΡΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ, ΠΊΡΠ΅ΠΈΡΠ°ΡΠ΅ ΠΈ ΠΌΠ΅Π½ΡΠ²Π°ΡΠ΅ ΠΌΠ°ΠΏΠΈ, ΠΈΡΡΡΠ°ΠΆΡΠ²Π°ΡΠ΅ Π½Π° Π΅ΠΊΠΎΡΠΈΡΡΠ΅ΠΌΠΎΡ Π½Π° BPF ΠΈ Π΄ΡΡΠ³ΠΎ. ΠΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΡΠ°ΡΠ° Π²ΠΎ ΡΠΎΡΠΌΠ° Π½Π° ΠΈΠ·Π²ΠΎΡΠ΅Π½ ΠΊΠΎΠ΄ Π·Π° ΡΡΡΠ°Π½ΠΈΡΠΈΡΠ΅ ΡΠΎ ΡΠΏΠ°ΡΡΡΠ²Π° ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ Π½Π°ΡΠ΄Π΅. ΠΈΠ»ΠΈ, Π²Π΅ΡΠ΅ ΡΠΎΡΡΠ°Π²Π΅Π½ΠΎ, .
ΠΠΎ Π²ΡΠ΅ΠΌΠ΅ΡΠΎ Π½Π° ΠΎΠ²Π° ΠΏΠΈΡΡΠ²Π°ΡΠ΅ bpftool Π΄ΠΎΠ°ΡΠ° Π³ΠΎΡΠΎΠ²ΠΎ ΡΠ°ΠΌΠΎ Π·Π° RHEL, Fedora ΠΈ Ubuntu (Π²ΠΈΠ΄Π΅ΡΠ΅, Π½Π° ΠΏΡΠΈΠΌΠ΅Ρ, , ΠΊΠΎΡ ΡΠ° ΡΠ°ΡΠΊΠ°ΠΆΡΠ²Π° Π½Π΅Π΄ΠΎΠ²ΡΡΠ΅Π½Π°ΡΠ° ΠΏΡΠΈΠΊΠ°Π·Π½Π° Π·Π° ΠΏΠ°ΠΊΡΠ²Π°ΡΠ΅ΡΠΎ bpftool Π² Debian). ΠΠΎ, Π°ΠΊΠΎ Π²Π΅ΡΠ΅ ΡΡΠ΅ Π³ΠΎ ΡΠΊΠ»ΠΎΠΏΠΈΠ»Π΅ Π²Π°ΡΠ΅ΡΠΎ ΡΠ°Π΄ΡΠΎ, ΡΠΎΠ³Π°Ρ ΡΠΊΠ»ΠΎΠΏΠ΅ΡΠ΅ Π³ΠΎ bpftool Π»Π΅ΡΠ½ΠΎ ΠΊΠ°ΠΊΠΎ ΠΏΠΈΡΠ°:
$ cd ${linux}/tools/bpf/bpftool
# ... ΠΏΡΠΎΠΏΠΈΡΠΈΡΠ΅ ΠΏΡΡΠΈ ΠΊ ΠΏΠΎΡΠ»Π΅Π΄Π½Π΅ΠΌΡ clang, ΠΊΠ°ΠΊ ΡΠ°ΡΡΠΊΠ°Π·Π°Π½ΠΎ Π²ΡΡΠ΅
$ make -s
Auto-detecting system features:
... libbfd: [ on ]
... disassembler-four-args: [ on ]
... zlib: [ on ]
... libcap: [ on ]
... clang-bpf-co-re: [ on ]
Auto-detecting system features:
... libelf: [ on ]
... zlib: [ on ]
... bpf: [ on ]
$(ΡΡΠΊΠ° ${linux} - ΠΎΠ²Π° Π΅ Π²Π°ΡΠΈΠΎΡ Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΡΠΌ Π½Π° ΡΠ°Π΄ΡΠΎΡΠΎ.) ΠΠΎ ΠΈΠ·Π²ΡΡΡΠ²Π°ΡΠ΅ΡΠΎ Π½Π° ΠΎΠ²ΠΈΠ΅ ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ bpftool ΡΠ΅ Π±ΠΈΠ΄Π°Ρ ΡΠΎΠ±ΡΠ°Π½ΠΈ Π²ΠΎ Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΡΠΌ ${linux}/tools/bpf/bpftool ΠΈ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ Π΄ΠΎΠ΄Π°Π΄Π΅ Π½Π° ΠΏΠ°ΡΠ΅ΠΊΠ°ΡΠ° (ΠΏΡΠ΅Π΄ ΡΠ΅ Π½Π° ΠΊΠΎΡΠΈΡΠ½ΠΈΠΊΠΎΡ root) ΠΈΠ»ΠΈ ΡΠ°ΠΌΠΎ ΠΊΠΎΠΏΠΈΡΠ°ΡΡΠ΅ Π²ΠΎ /usr/local/sbin.
Π‘ΠΎΠ±Π΅ΡΠΈ bpftool Π½Π°ΡΠ΄ΠΎΠ±ΡΠΎ Π΅ Π΄Π° ΡΠ΅ ΠΊΠΎΡΠΈΡΡΠΈ Π²ΡΠΎΡΠΎΡΠΎ clang, ΡΠΊΠ»ΠΎΠΏΠ΅Π½ ΠΊΠ°ΠΊΠΎ ΡΡΠΎ Π΅ ΠΎΠΏΠΈΡΠ°Π½ ΠΏΠΎΠ³ΠΎΡΠ΅ ΠΈ ΠΏΡΠΎΠ²Π΅ΡΠ΅ΡΠ΅ Π΄Π°Π»ΠΈ Π΅ ΠΏΡΠ°Π²ΠΈΠ»Π½ΠΎ ΡΠΊΠ»ΠΎΠΏΠ΅Π½ - ΠΊΠΎΡΠΈΡΡΠ΅ΡΡΠΈ, Π½Π° ΠΏΡΠΈΠΌΠ΅Ρ, ΠΊΠΎΠΌΠ°Π½Π΄Π°ΡΠ°
$ sudo bpftool feature probe kernel
Scanning system configuration...
bpf() syscall for unprivileged users is enabled
JIT compiler is enabled
JIT compiler hardening is disabled
JIT compiler kallsyms exports are enabled for root
...ΡΡΠΎ ΡΠ΅ ΠΏΠΎΠΊΠ°ΠΆΠ΅ ΠΊΠΎΠΈ ΠΊΠ°ΡΠ°ΠΊΡΠ΅ΡΠΈΡΡΠΈΠΊΠΈ Π½Π° BPF ΡΠ΅ ΠΎΠ²ΠΎΠ·ΠΌΠΎΠΆΠ΅Π½ΠΈ Π²ΠΎ Π²Π°ΡΠΈΠΎΡ ΠΊΠ΅ΡΠ½Π΅Π».
ΠΠ°ΡΠ΅ΠΌ, ΠΏΡΠ΅ΡΡ ΠΎΠ΄Π½Π°ΡΠ° ΠΊΠΎΠΌΠ°Π½Π΄Π° ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ ΠΈΠ·Π²ΡΡΠΈ ΠΊΠ°ΠΊΠΎ
# bpftool f p kΠΠ²Π° ΡΠ΅ ΠΏΡΠ°Π²ΠΈ ΠΏΠΎ Π°Π½Π°Π»ΠΎΠ³ΠΈΡΠ° ΡΠΎ ΠΊΠΎΠΌΡΠ½Π°Π»Π½ΠΈΡΠ΅ ΡΡΠ»ΡΠ³ΠΈ ΠΎΠ΄ ΠΏΠ°ΠΊΠ΅ΡΠΎΡ iproute2, ΠΊΠ°Π΄Π΅ ΡΡΠΎ ΠΌΠΎΠΆΠ΅ΠΌΠ΅, Π½Π° ΠΏΡΠΈΠΌΠ΅Ρ, Π΄Π° ΠΊΠ°ΠΆΠ΅ΠΌΠ΅ ip a s eth0 Π½Π°ΠΌΠ΅ΡΡΠΎ ip addr show dev eth0.
ΠΠ°ΠΊΠ»ΡΡΠΎΠΊ
BPF Π²ΠΈ ΠΎΠ²ΠΎΠ·ΠΌΠΎΠΆΡΠ²Π° Π΄Π° ΠΎΠ±Π»Π΅ΡΠ΅ΡΠ΅ Π±ΠΎΠ»Π²Π° Π·Π° Π΅ΡΠΈΠΊΠ°ΡΠ½ΠΎ ΠΌΠ΅ΡΠ΅ΡΠ΅ ΠΈ ΠΌΠ΅Π½ΡΠ²Π°ΡΠ΅ Π½Π° ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»Π½ΠΎΡΡΠ° Π½Π° ΡΠ°Π΄ΡΠΎΡΠΎ Π½Π° ΠΏΠ°Ρ. Π‘ΠΈΡΡΠ΅ΠΌΠΎΡ ΡΠ΅ ΠΏΠΎΠΊΠ°ΠΆΠ° ΠΊΠ°ΠΊΠΎ ΠΌΠ½ΠΎΠ³Ρ ΡΡΠΏΠ΅ΡΠ΅Π½, ΡΠΏΠΎΡΠ΅Π΄ Π½Π°ΡΠ΄ΠΎΠ±ΡΠΈΡΠ΅ ΡΡΠ°Π΄ΠΈΡΠΈΠΈ Π½Π° UNIX: Π΅Π΄Π½ΠΎΡΡΠ°Π²Π΅Π½ ΠΌΠ΅Ρ Π°Π½ΠΈΠ·Π°ΠΌ ΠΊΠΎΡ Π²ΠΈ ΠΎΠ²ΠΎΠ·ΠΌΠΎΠΆΡΠ²Π° Π΄Π° Π³ΠΎ (ΡΠ΅)ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ°ΡΠ΅ ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ ΠΎΠ²ΠΎΠ·ΠΌΠΎΠΆΠΈ ΠΎΠ³ΡΠΎΠΌΠ΅Π½ Π±ΡΠΎΡ Π»ΡΡΠ΅ ΠΈ ΠΎΡΠ³Π°Π½ΠΈΠ·Π°ΡΠΈΠΈ Π΄Π° Π΅ΠΊΡΠΏΠ΅ΡΠΈΠΌΠ΅Π½ΡΠΈΡΠ°Π°Ρ. Π, ΠΈΠ°ΠΊΠΎ Π΅ΠΊΡΠΏΠ΅ΡΠΈΠΌΠ΅Π½ΡΠΈΡΠ΅, ΠΊΠ°ΠΊΠΎ ΠΈ ΡΠ°Π·Π²ΠΎΡΠΎΡ Π½Π° ΡΠ°ΠΌΠ°ΡΠ° ΠΈΠ½ΡΡΠ°ΡΡΡΡΠΊΡΡΡΠ° Π½Π° BPF, ΡΠ΅ Π΄Π°Π»Π΅ΠΊΡ ΠΎΠ΄ Π·Π°Π²ΡΡΠ΅Π½ΠΈ, ΡΠΈΡΡΠ΅ΠΌΠΎΡ Π²Π΅ΡΠ΅ ΠΈΠΌΠ° ΡΡΠ°Π±ΠΈΠ»Π΅Π½ ABI ΡΡΠΎ Π²ΠΈ ΠΎΠ²ΠΎΠ·ΠΌΠΎΠΆΡΠ²Π° Π΄Π° ΠΈΠ·Π³ΡΠ°Π΄ΠΈΡΠ΅ ΡΠΈΠ³ΡΡΠ½Π°, ΠΈ ΡΡΠΎ Π΅ Π½Π°ΡΠ²Π°ΠΆΠ½ΠΎ, Π΅ΡΠ΅ΠΊΡΠΈΠ²Π½Π° Π΄Π΅Π»ΠΎΠ²Π½Π° Π»ΠΎΠ³ΠΈΠΊΠ°.
ΠΠΈ ΡΠ°ΠΊΠ°Π» Π΄Π° Π·Π°Π±Π΅Π»Π΅ΠΆΠ°ΠΌ Π΄Π΅ΠΊΠ°, ΡΠΏΠΎΡΠ΅Π΄ ΠΌΠΎΠ΅ ΠΌΠΈΡΠ»Π΅ΡΠ΅, ΡΠ΅Ρ Π½ΠΎΠ»ΠΎΠ³ΠΈΡΠ°ΡΠ° ΡΡΠ°Π½Π° ΡΠΎΠ»ΠΊΡ ΠΏΠΎΠΏΡΠ»Π°ΡΠ½Π° Π·Π°ΡΠΎΠ° ΡΡΠΎ, ΠΎΠ΄ Π΅Π΄Π½Π° ΡΡΡΠ°Π½Π°, ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΈΠ³ΡΠ° (Π°ΡΡ ΠΈΡΠ΅ΠΊΡΡΡΠ°ΡΠ° Π½Π° ΠΌΠ°ΡΠΈΠ½Π°ΡΠ° ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ ΡΠ°Π·Π±Π΅ΡΠ΅ ΠΏΠΎΠ²Π΅ΡΠ΅ ΠΈΠ»ΠΈ ΠΏΠΎΠΌΠ°Π»ΠΊΡ Π²ΠΎ Π΅Π΄Π½Π° Π²Π΅ΡΠ΅Ρ), Π° ΠΎΠ΄ Π΄ΡΡΠ³Π° ΡΡΡΠ°Π½Π° Π΄Π° ΡΠ΅ ΡΠ΅ΡΠ°Π²Π°Π°Ρ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠΈ ΠΊΠΎΠΈ Π½Π΅ ΠΌΠΎΠΆΠ΅Π»Π΅ Π΄Π° ΡΠ΅ ΡΠ΅ΡΠ°Ρ (ΠΏΡΠ΅ΠΊΡΠ°ΡΠ½ΠΎ) ΠΏΡΠ΅Π΄ Π½Π΅ΡΠ·ΠΈΠ½ΠΎΡΠΎ ΠΏΠΎΡΠ°Π²ΡΠ²Π°ΡΠ΅. ΠΠ²ΠΈΠ΅ Π΄Π²Π΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠΈ Π·Π°Π΅Π΄Π½ΠΎ Π³ΠΈ ΠΏΡΠΈΠ½ΡΠ΄ΡΠ²Π°Π°Ρ Π»ΡΡΠ΅ΡΠΎ Π΄Π° Π΅ΠΊΡΠΏΠ΅ΡΠΈΠΌΠ΅Π½ΡΠΈΡΠ°Π°Ρ ΠΈ Π΄Π° ΡΠΎΠ½ΡΠ²Π°Π°Ρ, ΡΡΠΎ Π΄ΠΎΠ²Π΅Π΄ΡΠ²Π° Π΄ΠΎ ΠΏΠΎΡΠ°Π²Π° Π½Π° ΡΠ΅ ΠΏΠΎΠ²Π΅ΡΠ΅ ΠΈ ΠΏΠΎΠ²Π΅ΡΠ΅ ΠΈΠ½ΠΎΠ²Π°ΡΠΈΠ²Π½ΠΈ ΡΠ΅ΡΠ΅Π½ΠΈΡΠ°.
ΠΠ²Π°Π° ΡΡΠ°ΡΠΈΡΠ°, ΠΈΠ°ΠΊΠΎ Π½Π΅ Π΅ ΠΎΡΠΎΠ±Π΅Π½ΠΎ ΠΊΡΠ°ΡΠΊΠ°, Π΅ ΡΠ°ΠΌΠΎ Π²ΠΎΠ²Π΅Π΄ Π²ΠΎ ΡΠ²Π΅ΡΠΎΡ Π½Π° BPF ΠΈ Π½Π΅ ΠΎΠΏΠΈΡΡΠ²Π° βΠ½Π°ΠΏΡΠ΅Π΄Π½ΠΈβ ΠΊΠ°ΡΠ°ΠΊΡΠ΅ΡΠΈΡΡΠΈΠΊΠΈ ΠΈ Π²Π°ΠΆΠ½ΠΈ Π΄Π΅Π»ΠΎΠ²ΠΈ ΠΎΠ΄ Π°ΡΡ ΠΈΡΠ΅ΠΊΡΡΡΠ°ΡΠ°. ΠΠ»Π°Π½ΠΎΡ Π·Π° ΠΏΠΎΠ½Π°ΡΠ°ΠΌΡ Π΅ ΠΎΡΠΏΡΠΈΠ»ΠΈΠΊΠ° Π²Π°ΠΊΠ°: ΡΠ»Π΅Π΄Π½Π°ΡΠ° ΡΡΠ°ΡΠΈΡΠ° ΡΠ΅ Π±ΠΈΠ΄Π΅ ΠΏΡΠ΅Π³Π»Π΅Π΄ Π½Π° ΡΠΈΠΏΠΎΠ²ΠΈΡΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ Π½Π° BPF (ΠΏΠΎΡΡΠΎΡΠ°Ρ 5.8 ΡΠΈΠΏΠΎΠ²ΠΈ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ ΠΏΠΎΠ΄Π΄ΡΠΆΠ°Π½ΠΈ Π²ΠΎ ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ 30), ΠΏΠΎΡΠΎΠ° ΠΊΠΎΠ½Π΅ΡΠ½ΠΎ ΡΠ΅ ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ ΠΊΠ°ΠΊΠΎ Π΄Π° Π½Π°ΠΏΠΈΡΠ΅ΡΠ΅ Π²ΠΈΡΡΠΈΠ½ΡΠΊΠΈ BPF Π°ΠΏΠ»ΠΈΠΊΠ°ΡΠΈΠΈ ΠΊΠΎΡΠΈΡΡΠ΅ΡΡΠΈ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ Π·Π° ΡΠ»Π΅Π΄Π΅ΡΠ΅ Π½Π° ΡΠ°Π΄ΡΠΎΡΠΎ ΠΊΠ°ΠΊΠΎ ΠΏΡΠΈΠΌΠ΅Ρ, ΡΠΎΠ³Π°Ρ Π΅ Π²ΡΠ΅ΠΌΠ΅ Π·Π° ΠΏΠΎΠ΄Π»Π°Π±ΠΎΠΊ ΠΊΡΡΡ Π·Π° Π°ΡΡ ΠΈΡΠ΅ΠΊΡΡΡΠ°ΡΠ° BPF, ΠΏΡΠΎΡΠ»Π΅Π΄Π΅Π½ ΡΠΎ ΠΏΡΠΈΠΌΠ΅ΡΠΈ Π½Π° BPF Π²ΠΌΡΠ΅ΠΆΡΠ²Π°ΡΠ΅ ΠΈ Π±Π΅Π·Π±Π΅Π΄Π½ΠΎΡΠ½ΠΈ Π°ΠΏΠ»ΠΈΠΊΠ°ΡΠΈΠΈ.
ΠΡΠ΅ΡΡ ΠΎΠ΄Π½ΠΈ Π½Π°ΠΏΠΈΡΠΈ ΠΎΠ΄ ΠΎΠ²Π°Π° ΡΠ΅ΡΠΈΡΠ°
ΠΡΡΠΊΠΈ
β Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΡΠ° Π·Π° BPF ΠΎΠ΄ ΡΠΈΠ»ΠΈΡΠΌ, ΠΏΠΎΡΠΎΡΠ½ΠΎ ΠΎΠ΄ ΠΠ°Π½ΠΈΠ΅Π» ΠΠΎΡΠΊΠΌΠ°Π½, Π΅Π΄Π΅Π½ ΠΎΠ΄ ΠΊΡΠ΅Π°ΡΠΎΡΠΈΡΠ΅ ΠΈ ΠΎΠ΄ΡΠΆΡΠ²Π°ΡΠΈΡΠ΅ Π½Π° BPF. ΠΠ²Π° Π΅ Π΅Π΄Π΅Π½ ΠΎΠ΄ ΠΏΡΠ²ΠΈΡΠ΅ ΡΠ΅ΡΠΈΠΎΠ·Π½ΠΈ ΠΎΠΏΠΈΡΠΈ, ΠΊΠΎΡ ΡΠ΅ ΡΠ°Π·Π»ΠΈΠΊΡΠ²Π° ΠΎΠ΄ Π΄ΡΡΠ³ΠΈΡΠ΅ ΠΏΠΎ ΡΠΎΠ° ΡΡΠΎ ΠΠ°Π½ΠΈΠ΅Π» ΡΠΎΡΠ½ΠΎ Π·Π½Π°Π΅ Π·Π° ΡΡΠΎ ΠΏΠΈΡΡΠ²Π° ΠΈ ΡΠ°ΠΌΡ Π½Π΅ΠΌΠ° Π½ΠΈΠΊΠ°ΠΊΠ²ΠΈ Π³ΡΠ΅ΡΠΊΠΈ. ΠΠΎΠ½ΠΊΡΠ΅ΡΠ½ΠΎ, ΠΎΠ²ΠΎΡ Π΄ΠΎΠΊΡΠΌΠ΅Π½Ρ ΠΎΠΏΠΈΡΡΠ²Π° ΠΊΠ°ΠΊΠΎ Π΄Π° ΡΠ΅ ΡΠ°Π±ΠΎΡΠΈ ΡΠΎ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ΅ BPF ΠΎΠ΄ ΡΠΈΠΏΠΎΠ²ΠΈΡΠ΅ XDP ΠΈ TC ΠΊΠΎΡΠΈΡΡΠ΅ΡΡΠΈ ΡΠ° Π΄ΠΎΠ±ΡΠΎ ΠΏΠΎΠ·Π½Π°ΡΠ°ΡΠ° Π°Π»Π°ΡΠΊΠ°
ipΠΎΠ΄ ΠΏΠ°ΠΊΡΠ²Π°ΡΠ΅ΡΠΎiproute2.β ΠΎΡΠΈΠ³ΠΈΠ½Π°Π»Π½Π° Π΄Π°ΡΠΎΡΠ΅ΠΊΠ° ΡΠΎ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΡΠ° Π·Π° ΠΊΠ»Π°ΡΠΈΡΠ΅Π½, Π° ΠΏΠΎΡΠΎΠ° ΠΏΡΠΎΠ΄ΠΎΠ»ΠΆΠ΅Π½ BPF. ΠΠΎΠ±ΡΠΎ ΡΠΈΡΠ°ΡΠ΅ Π°ΠΊΠΎ ΡΠ°ΠΊΠ°ΡΠ΅ Π΄Π° ΠΈΡΡΡΠ°ΠΆΡΠ²Π°ΡΠ΅ Π²ΠΎ Π°ΡΠ΅ΠΌΠ±Π»Π΅ΡΡΠΊΠΈΠΎΡ ΡΠ°Π·ΠΈΠΊ ΠΈ ΡΠ΅Ρ Π½ΠΈΡΠΊΠΈΡΠ΅ Π°ΡΡ ΠΈΡΠ΅ΠΊΡΠΎΠ½ΡΠΊΠΈ Π΄Π΅ΡΠ°Π»ΠΈ.
. Π‘Π΅ Π°ΠΆΡΡΠΈΡΠ° ΡΠ΅ΡΠΊΠΎ, Π½ΠΎ ΡΠΎΠΎΠ΄Π²Π΅ΡΠ½ΠΎ, ΠΊΠ°ΠΊΠΎ ΡΡΠΎ ΠΏΠΈΡΡΠ²Π°Π°Ρ ΡΠ°ΠΌΡ ΠΠ»Π΅ΠΊΡΠ΅Ρ Π‘ΡΠ°ΡΠΎΠ²ΠΎΠΈΡΠΎΠ² (Π°Π²ΡΠΎΡ Π½Π° eBPF) ΠΈ ΠΠ½Π΄ΡΠΈΡ ΠΠ°ΠΊΡΠΈΠΈΠΊΠΎ - (ΠΎΠ΄ΡΠΆΡΠ²Π°Ρ).
libbpf).. ΠΠ°Π±Π°Π²Π½Π° Π½ΠΈΡΠΊΠ° Π½Π° Π’Π²ΠΈΡΠ΅Ρ ΠΎΠ΄ ΠΠ²Π΅Π½ΡΠΈΠ½ ΠΠΎΠ½Π΅ ΡΠΎ ΠΏΡΠΈΠΌΠ΅ΡΠΈ ΠΈ ΡΠ°ΡΠ½ΠΈ Π·Π° ΠΊΠΎΡΠΈΡΡΠ΅ΡΠ΅ bpftool.
. ΠΠ³ΡΠΎΠΌΠ½Π° (ΠΈ ΡΓ¨ ΡΡΡΠ΅ ΠΎΠ΄ΡΠΆΡΠ²Π°Π½Π°) Π»ΠΈΡΡΠ° Π½Π° Π»ΠΈΠ½ΠΊΠΎΠ²ΠΈ Π΄ΠΎ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΡΠ°ΡΠ° Π½Π° BPF ΠΎΠ΄ ΠΠ²Π΅Π½ΡΠΈΠ½ ΠΠΎΠ½Π΅.
ΠΠ·Π²ΠΎΡ: www.habr.com
