ΠΠ° ΠΏΠΎΡΠ΅ΡΠΎΠΊΠΎΡ ΠΈΠΌΠ°ΡΠ΅ ΡΠ΅Ρ
Π½ΠΎΠ»ΠΎΠ³ΠΈΡΠ° ΠΈ ΡΠ΅ Π²ΠΈΠΊΠ°ΡΠ΅ BPF. ΠΠ° ΠΏΠΎΠ³Π»Π΅Π΄Π½Π°Π²ΠΌΠ΅
ΠΡΡΠ±ΠΎ ΠΊΠ°ΠΆΠ°Π½ΠΎ, BPF Π²ΠΈ ΠΎΠ²ΠΎΠ·ΠΌΠΎΠΆΡΠ²Π° Π΄Π° ΠΈΠ·Π²ΡΡΠΈΡΠ΅ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ»Π΅Π½ ΠΊΠΎΠ΄ ΠΎΠ±Π΅Π·Π±Π΅Π΄Π΅Π½ ΠΎΠ΄ ΠΊΠΎΡΠΈΡΠ½ΠΈΠΊΠΎΡ Π²ΠΎ ΠΏΡΠΎΡΡΠΎΡΠΎΡ Π½Π° ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ Π½Π° Linux, Π° Π½ΠΎΠ²Π°ΡΠ° Π°ΡΡ ΠΈΡΠ΅ΠΊΡΡΡΠ° ΡΠ΅ ΠΏΠΎΠΊΠ°ΠΆΠ° ΡΠΎΠ»ΠΊΡ ΡΡΠΏΠ΅ΡΠ½Π° ΡΡΠΎ ΡΠ΅ Π½ΠΈ ΡΡΠ΅Π±Π°Π°Ρ ΡΡΡΠ΅ Π΄Π΅ΡΠ΅ΡΠΈΠ½Π° ΡΡΠ°ΡΠΈΠΈ Π·Π° Π΄Π° Π³ΠΈ ΠΎΠΏΠΈΡΠ΅ΠΌΠ΅ ΡΠΈΡΠ΅ Π½Π΅ΡΠ·ΠΈΠ½ΠΈ Π°ΠΏΠ»ΠΈΠΊΠ°ΡΠΈΠΈ. (ΠΠ΄ΠΈΠ½ΡΡΠ²Π΅Π½ΠΎΡΠΎ Π½Π΅ΡΡΠΎ ΡΡΠΎ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ΅ΡΠΈΡΠ΅ Π½Π΅ Π³ΠΎ Π½Π°ΠΏΡΠ°Π²ΠΈΡΠ° Π΄ΠΎΠ±ΡΠΎ, ΠΊΠ°ΠΊΠΎ ΡΡΠΎ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° Π²ΠΈΠ΄ΠΈΡΠ΅ Π²ΠΎ ΠΊΠΎΠ΄ΠΎΡ Π·Π° ΠΈΠ·Π²Π΅Π΄Π±Π° ΠΏΠΎΠ΄ΠΎΠ»Ρ, Π±Π΅ΡΠ΅ ΡΠΎΠ·Π΄Π°Π²Π°ΡΠ΅ ΠΏΡΠΈΡΡΠΎΡΠ½ΠΎ Π»ΠΎΠ³ΠΎ.)
ΠΠ²Π°Π° ΡΡΠ°ΡΠΈΡΠ° ΡΠ° ΠΎΠΏΠΈΡΡΠ²Π° ΡΡΡΡΠΊΡΡΡΠ°ΡΠ° Π½Π° Π²ΠΈΡΡΡΠ΅Π»Π½Π°ΡΠ° ΠΌΠ°ΡΠΈΠ½Π° BPF, ΠΈΠ½ΡΠ΅ΡΡΠ΅ΡΡΠΈΡΠ΅ Π½Π° ΡΠ°Π΄ΡΠΎΡΠΎ Π·Π° ΡΠ°Π±ΠΎΡΠ° ΡΠΎ BPF, ΡΠ°Π·Π²ΠΎΡΠ½ΠΈΡΠ΅ Π°Π»Π°ΡΠΊΠΈ, ΠΊΠ°ΠΊΠΎ ΠΈ ΠΊΡΠ°ΡΠΎΠΊ, ΠΌΠ½ΠΎΠ³Ρ ΠΊΡΠ°ΡΠΎΠΊ ΠΏΡΠ΅Π³Π»Π΅Π΄ Π½Π° ΠΏΠΎΡΡΠΎΠ΅ΡΠΊΠΈΡΠ΅ ΡΠΏΠΎΡΠΎΠ±Π½ΠΎΡΡΠΈ, Ρ.Π΅. ΡΠ΅ ΡΡΠΎ ΡΠ΅ Π½ΠΈ ΡΡΠ΅Π±Π° Π²ΠΎ ΠΈΠ΄Π½ΠΈΠ½Π° Π·Π° ΠΏΠΎΠ΄Π»Π°Π±ΠΎΠΊΠΎ ΠΏΡΠΎΡΡΡΠ²Π°ΡΠ΅ Π½Π° ΠΏΡΠ°ΠΊΡΠΈΡΠ½ΠΈΡΠ΅ ΠΏΡΠΈΠΌΠ΅Π½ΠΈ Π½Π° BPF.
Π Π΅Π·ΠΈΠΌΠ΅ Π½Π° ΡΡΠ°ΡΠΈΡΠ°ΡΠ°
bpf(2)
.
ΠΠΈΡΠ΅ΠΌ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ BPF Ρ ΠΏΠΎΠΌΠΎΡΡΡ libbpf
.libbpf
. ΠΠ΅ ΡΠΎΠ·Π΄Π°Π΄Π΅ΠΌΠ΅ ΠΎΡΠ½ΠΎΠ²Π΅Π½ ΡΠΊΠ΅Π»Π΅Ρ Π·Π° Π°ΠΏΠ»ΠΈΠΊΠ°ΡΠΈΡΠ° BPF ΡΡΠΎ ΡΠ΅ Π³ΠΎ ΠΊΠΎΡΠΈΡΡΠΈΠΌΠ΅ Π²ΠΎ ΡΠ»Π΅Π΄Π½ΠΈΡΠ΅ ΠΏΡΠΈΠΌΠ΅ΡΠΈ.
ΠΠΎΠ²Π΅Π΄ Π²ΠΎ Π°ΡΡ ΠΈΡΠ΅ΠΊΡΡΡΠ°ΡΠ° BPF
ΠΡΠ΅Π΄ Π΄Π° Π·Π°ΠΏΠΎΡΠ½Π΅ΠΌΠ΅ Π΄Π° ΡΠ° ΡΠ°Π·Π³Π»Π΅Π΄ΡΠ²Π°ΠΌΠ΅ Π°ΡΡ
ΠΈΡΠ΅ΠΊΡΡΡΠ°ΡΠ° BPF, ΡΠ΅ ΡΠ΅ ΠΏΠΎΠ²ΠΈΠΊΠ°ΠΌΠ΅ ΠΏΠΎΡΠ»Π΅Π΄Π΅Π½ ΠΏΠ°Ρ (ΠΎΡ
).
ΠΠΎΠ²ΠΈΠΎΡ 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
Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° ΡΠ΅ ΠΏΡΠ΅Π½Π΅ΡΡΠ²Π° ΠΏΠΎΠΊΠ°ΠΆΡΠ²Π°Ρ ΠΊΠΎΠ½ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠΎΡ - Π²ΠΎ Π·Π°Π²ΠΈΡΠ½ΠΎΡΡ ΠΎΠ΄ Π²ΠΈΠ΄ΠΎΡ Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ°, ΠΎΠ²Π° ΠΌΠΎΠΆΠ΅ Π΄Π° Π±ΠΈΠ΄Π΅, Π½Π° ΠΏΡΠΈΠΌΠ΅Ρ, ΡΡΡΡΠΊΡΡΡΠ° struct xdp_md
struct __sk_buff
struct pt_regs
ΠΠ½Π°ΡΠΈ, ΠΈΠΌΠ°Π²ΠΌΠ΅ ΡΠ΅Ρ Π½Π° ΡΠ΅Π³ΠΈΡΡΡΠΈ, ΠΏΠΎΠΌΠΎΡΠ½ΠΈΡΠΈ Π½Π° ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ, ΡΡΠ΅ΠΊ, ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΡΠ°Π»Π΅Π½ ΠΏΠΎΠΊΠ°ΠΆΡΠ²Π°Ρ ΠΈ ΡΠΏΠΎΠ΄Π΅Π»Π΅Π½Π° ΠΌΠ΅ΠΌΠΎΡΠΈΡΠ° Π²ΠΎ ΡΠΎΡΠΌΠ° Π½Π° ΠΌΠ°ΠΏΠΈ. ΠΠ΅ Π΄Π΅ΠΊΠ° ΡΠ΅ΡΠΎ ΡΠΎΠ° Π΅ Π°ΠΏΡΠΎΠ»ΡΡΠ½ΠΎ Π½Π΅ΠΎΠΏΡ ΠΎΠ΄Π½ΠΎ Π½Π° ΠΏΠ°ΡΡΠ²Π°ΡΠ΅ΡΠΎ, Π½ΠΎ...
ΠΡΠ΄Π΅ Π΄Π° Π³ΠΎ ΠΏΡΠΎΠ΄ΠΎΠ»ΠΆΠΈΠΌΠ΅ ΠΎΠΏΠΈΡΠΎΡ ΠΈ Π΄Π° ΡΠ°Π·Π³ΠΎΠ²Π°ΡΠ°ΠΌΠ΅ Π·Π° ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΈΠΎΡ ΡΠΈΡΡΠ΅ΠΌ Π·Π° ΡΠ°Π±ΠΎΡΠ° ΡΠΎ ΠΎΠ²ΠΈΠ΅ ΠΎΠ±ΡΠ΅ΠΊΡΠΈ. Π‘ΠΈΡΠ΅ (
Π’ΡΠΊΠ° 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.h
bpf_common.h
ΠΡΠΈΠΌΠ΅Ρ: ΡΠ°ΡΠΊΠ»ΠΎΠΏΡΠ²Π°ΡΠ΅ Π½Π° 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 ΠΎΠΏΠ΅ΡΠ°ΡΠΈΡΠ° Π΅ BPF_EXIT
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
= BPF_LD
BPF_DW
BPF_IMM
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
. ΠΠΎ ΠΎΠ²ΠΎΡ ΡΠ»ΡΡΠ°Ρ, ΡΠΈΡΠ΅ Π°ΠΊΡΠΈΠ²Π½ΠΈ ΠΏΡΠΈΠΌΠ΅ΡΠΎΡΠΈ Π½Π° ΡΡΠ°ΡΠ°ΡΠ° Π²Π΅ΡΠ·ΠΈΡΠ° Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° ΡΠ΅ ΡΠ° Π·Π°Π²ΡΡΠ°Ρ ΡΠ²ΠΎΡΠ°ΡΠ° ΡΠ°Π±ΠΎΡΠ°, Π° ΠΎΠ΄ Π½ΠΎΠ²Π°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° ΡΠ΅ ΡΠ΅ ΡΠΎΠ·Π΄Π°Π΄Π°Ρ Π½ΠΎΠ²ΠΈ ΡΠΏΡΠ°Π²ΡΠ²Π°ΡΠΈ Π½Π° Π½Π°ΡΡΠ°Π½ΠΈ, Π° βΠ°ΡΠΎΠΌΠΈΡΠ½ΠΎΡΡΠ°β ΠΎΠ²Π΄Π΅ Π·Π½Π°ΡΠΈ Π΄Π΅ΠΊΠ° Π½Π΅ΠΌΠ° Π΄Π° ΡΠ΅ ΠΏΡΠΎΠΏΡΡΡΠΈ Π½ΠΈΡΡ Π΅Π΄Π΅Π½ Π½Π°ΡΡΠ°Π½.
ΠΡΠΈΠΊΠ°ΡΡΠ²Π°ΡΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ Π½Π° ΠΈΠ·Π²ΠΎΡΠΈ Π½Π° Π½Π°ΡΡΠ°Π½ΠΈ
ΠΠΎ ΠΎΠ²Π°Π° ΡΡΠ°ΡΠΈΡΠ°, Π½Π΅ΠΌΠ° ΠΎΠ΄Π΄Π΅Π»Π½ΠΎ Π΄Π° ΠΎΠΏΠΈΡΠ΅ΠΌΠ΅ ΠΏΠΎΠ²ΡΠ·ΡΠ²Π°ΡΠ΅ Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ ΡΠΎ ΠΈΠ·Π²ΠΎΡΠΈ Π½Π° Π½Π°ΡΡΠ°Π½ΠΈ, Π±ΠΈΠ΄Π΅ΡΡΠΈ ΠΈΠΌΠ° ΡΠΌΠΈΡΠ»Π° Π΄Π° ΡΠ΅ ΠΏΡΠΎΡΡΡΠ²Π° ΠΎΠ²Π° Π²ΠΎ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡ Π½Π° ΡΠΏΠ΅ΡΠΈΡΠΈΡΠ΅Π½ ΡΠΈΠΏ Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°. Π¦ΠΌ.
ΠΠ°Π½ΠΈΠΏΡΠ»ΠΈΡΠ°ΡΠ΅ ΡΠΎ ΠΎΠ±ΡΠ΅ΠΊΡΠΈ ΠΊΠΎΡΠΈΡΡΠ΅ΡΡΠΈ Π³ΠΎ ΡΠΈΡΡΠ΅ΠΌΡΠΊΠΈΠΎΡ ΠΏΠΎΠ²ΠΈΠΊ bpf
BPF ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ
Π‘ΠΈΡΠ΅ BPF ΠΎΠ±ΡΠ΅ΠΊΡΠΈ ΡΠ΅ ΠΊΡΠ΅ΠΈΡΠ°Π½ΠΈ ΠΈ ΡΠΏΡΠ°Π²ΡΠ²Π°Π½ΠΈ ΠΎΠ΄ ΠΊΠΎΡΠΈΡΠ½ΠΈΡΠΊΠΈΠΎΡ ΠΏΡΠΎΡΡΠΎΡ ΡΠΎ ΠΏΠΎΠΌΠΎΡ Π½Π° ΡΠΈΡΡΠ΅ΠΌΡΠΊΠΈ ΠΏΠΎΠ²ΠΈΠΊ bpf
, ΡΠΎ ΡΠ»Π΅Π΄Π½ΠΈΠΎΠ² ΠΏΡΠΎΡΠΎΡΠΈΠΏ:
#include <linux/bpf.h>
int bpf(int cmd, union bpf_attr *attr, unsigned int size);
ΠΠ²Π΅ Π³ΠΎ ΡΠΈΠΌΠΎΡ cmd
Π΅ Π΅Π΄Π½Π° ΠΎΠ΄ Π²ΡΠ΅Π΄Π½ΠΎΡΡΠΈΡΠ΅ Π½Π° ΡΠΈΠΏΠΎΡ enum bpf_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 Π΅ ΡΠΏΠ°ΠΊΡΠ²Π°Π½Π° Π²ΠΎ ΡΡΡΡΠΊΡΡΡΠ°ΡΠ° bpf_insn
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 ΠΈΠ»ΠΈ ΠΏΠΎΠΊΠ°ΠΆΡΠ²Π°ΡΠΈ Π½Π° ΠΌΡΠ΅ΠΆΠ½ΠΈΡΠ΅ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΡΡΠΈ, ΠΌΠ°ΠΏΠΈ Π·Π° ΡΠ°Π±ΠΎΡΠ° ΡΠΎ Π½Π°ΡΡΠ°Π½ΠΈ Π½Π° ΠΏΠ΅ΡΡ ΠΈΡΠ½. ΠΠ° Π½ΠΈΠ² Π½Π΅ΠΌΠ° Π΄Π° Π·Π±ΠΎΡΡΠ²Π°ΠΌΠ΅ ΠΎΠ²Π΄Π΅, Π·Π° Π΄Π° Π½Π΅ Π³ΠΎ Π·Π±ΡΠ½ΠΈΠΌΠ΅ ΡΠΈΡΠ°ΡΠ΅Π»ΠΎΡ. ΠΡΠ²Π΅Π½ ΠΎΠ²Π°, Π³ΠΈ ΠΈΠ³Π½ΠΎΡΠΈΡΠ°ΠΌΠ΅ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠΈΡΠ΅ Π·Π° ΡΠΈΠ½Ρ
ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΡΠ°, Π±ΠΈΠ΄Π΅ΡΡΠΈ ΡΠΎΠ° Π½Π΅ Π΅ Π²Π°ΠΆΠ½ΠΎ Π·Π° Π½Π°ΡΠΈΡΠ΅ ΠΏΡΠΈΠΌΠ΅ΡΠΈ. ΠΠΎΠΌΠΏΠ»Π΅ΡΠ½Π° Π»ΠΈΡΡΠ° Π½Π° Π΄ΠΎΡΡΠ°ΠΏΠ½ΠΈ ΡΠΈΠΏΠΎΠ²ΠΈ ΠΌΠ°ΠΏΠΈ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ Π½Π°ΡΠ΄Π΅ Π²ΠΎ <linux/bpf.h>
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 map
BPF_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 (Π½ΠΈΠ΅ ΠΎΠΏΠΈΡΡΠ²Π°ΠΌΠ΅ ΠΊΠ°ΠΊΠΎ Π΄Π° Π³ΠΎ Π½Π°ΠΏΡΠ°Π²ΠΈΡΠ΅ ΠΎΠ²Π° Π²ΠΎ Π΄Π΅Π»ΠΎΡ
$ 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
ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ ΠΈ Π½Π΅Π³ΠΎΠ²ΠΈΠΎΡ ΡΠ°Π·Π²ΠΎΡ ΡΠ΅ Π²ΡΡΠΈ ΠΏΡΠ΅ΠΊΡ ΠΌΠ΅ΡΠ»ΠΈΠ½Π³ Π»ΠΈΡΡΠ°ΡΠ° [email protected]
. Π‘Π΅ΠΏΠ°ΠΊ, ΡΠ΅ ΠΎΠ΄ΡΠΆΡΠ²Π° ΠΏΠΎΡΠ΅Π±Π½ΠΎ ΡΠΊΠ»Π°Π΄ΠΈΡΡΠ΅ Π·Π° ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅ Π½Π° Π°ΠΏΠ»ΠΈΠΊΠ°ΡΠΈΠΈΡΠ΅ ΠΊΠΎΠΈ ΠΆΠΈΠ²Π΅Π°Ρ Π½Π°Π΄Π²ΠΎΡ ΠΎΠ΄ ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ
ΠΠΎ ΠΎΠ²ΠΎΡ Π΄Π΅Π» ΡΠ΅ ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ ΠΊΠ°ΠΊΠΎ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΠΊΡΠ΅ΠΈΡΠ°ΡΠ΅ ΠΏΡΠΎΠ΅ΠΊΡ ΡΡΠΎ ΠΊΠΎΡΠΈΡΡΠΈ 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 ΡΠ΅ βΠ΄Π΅ΡΠΈΠ½ΠΈΡΠ°Π½ΠΈβ Π²ΠΎ Π΄Π°ΡΠΎΡΠ΅ΠΊΠ°ΡΠ° include/linux/bpf_types.h
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 ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°, Π²ΠΈΠ΄ΠΈ verifier.c
ΠΡΠ΄Π΅ Π΄Π° ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ ΠΊΠ°ΠΊΠΎ Ρ
ΠΈΠΏΠΎΡΠ΅ΡΠΈΡΠΊΠ° 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_mp_*
ΠΠΈΡΡΠΈΡΠ΅Π½ ΠΈΠ½Π΄Π΅ΠΊΡ
ΠΠ½Π°ΡΠΈ, ΠΌΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° ΠΏΡΠΈΡΡΠ°ΠΏΠΈΠΌΠ΅ Π΄ΠΎ ΠΊΠ°ΡΡΠ°ΡΠ° ΠΎΠ΄ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° 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
. ΠΠ²Π° ΠΌΠΎΠΆΠ΅ Π΄Π° Π±ΠΈΠ΄Π΅ ΠΊΠΎΡΠΈΡΠ½ΠΎ ΠΊΠΎΠ³Π° ΡΠ°Π±ΠΎΡΠΈΡΠ΅ Π²ΠΎ ΡΡΠ΅Π΄ΠΈΠ½Π° Π·Π° ΠΊΠΎΡΠ° Π½Π΅ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΡΠΎΠ·Π΄Π°Π²Π°ΡΠ΅ Π·Π°Π²ΠΈΡΠ½ΠΎΡΡΠΈ, ΠΈΠ»ΠΈ Π΄Π° Π³ΠΎ Π·Π°ΡΡΠ²ΡΠ²Π°ΡΠ΅ ΡΠ΅ΠΊΠΎΡ Π΄Π΅Π» ΠΈΠ»ΠΈ ΠΊΠΎΠ³Π° ΠΏΠΈΡΡΠ²Π°ΡΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° ΠΊΠ°ΠΊΠΎ ply
ΠΠ° ΠΏΠΎΠ»Π΅ΡΠ½ΠΎ Π΄Π° ΡΠ΅ ΡΠ»Π΅Π΄ΠΈ Π»ΠΎΠ³ΠΈΠΊΠ°ΡΠ°, ΡΠ΅ Π³ΠΎ ΠΏΡΠ΅ΡΠ°Π±ΠΎΡΠΈΠΌΠ΅ Π½Π°ΡΠΈΠΎΡ ΠΏΡΠΈΠΌΠ΅Ρ Π·Π° ΠΎΠ²ΠΈΠ΅ ΡΠ΅Π»ΠΈ 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
(ΡΠΎΠ²Π΅Ρ: Π·Π΅ΠΌΠ΅ΡΠ΅ Π³ΠΎ Π΄Π΅ΠΏΠΎΠ½ΠΈΡΠ°ΡΠ° ΠΎΠ΄ΠΎΠ·Π³ΠΎΡΠ°, ΠΏΠΎΠ²ΡΠΎΡΠ½ΠΎ ΠΏΡΠΎΡΠΈΡΠ°ΡΡΠ΅ Π³ΠΎ Π΄Π΅Π»ΠΎΡ Π·Π° ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈ, ΠΎΡΠ²ΠΎΡΠ΅ΡΠ΅ linux/bpf.h
linux/bpf_common.h
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 Π±Π΅Π° ΠΎΠ΄ ΠΎΠ½Π»Π°ΡΠ½ Π·Π°Π΅Π΄Π½ΠΈΡΠ°ΡΠ° ΠΠΈΠ½ΡΠΊΡ, ΡΡΠΎ Π·Π½Π°ΡΠΈ Π΄Π΅ΠΊΠ° ΡΠ° ΠΊΠΎΡΠΈΡΡΠ΅Π° ΠΎΠ½Π°Π° ΡΡΠΎ ΠΈΠΌ Π΅ Π½Π°ΡΠΏΠΎΠ·Π½Π°ΡΠ° (Π½ΠΎ Π½Π΅ ΠΈ Π½ΠΎΡΠΌΠ°Π»Π½ΠΎ Π»ΡΡΠ΅) ΠΈΠ½ΡΠ΅ΡΡΠ΅ΡΡ Π·Π° ΠΈΠ½ΡΠ΅ΡΠ°ΠΊΡΠΈΡΠ° ΡΠΎ ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ: xdp_attach
Π³ΠΎ ΠΊΠΎΠΏΠΈΡΠ° ΠΊΠΎΠ΄ΠΎΡ ΠΎΠ΄ libbpf
, ΠΈΠΌΠ΅Π½ΠΎ, ΠΎΠ΄ Π΄Π°ΡΠΎΡΠ΅ΠΊΠ°ΡΠ° netlink.c
ΠΠΎΠ±ΡΠ΅Π΄ΠΎΡΠ΄ΠΎΠ²ΡΠ΅ Π²ΠΎ ΡΠ²Π΅ΡΠΎΡ Π½Π° Π½Π΅ΡΠ»ΠΈΠ½ΠΊ ΠΏΡΠΈΠΊΠ»ΡΡΠΎΡΠΈΡΠ΅
ΠΡΠ²ΠΎΡΠ΅ΡΠ΅ ΡΠΈΠΏ Π½Π° ΠΌΡΠ΅ΠΆΠ΅Π½ ΠΏΡΠΈΠΊΠ»ΡΡΠΎΠΊ 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
/clang
pahole
- Π½Π΅Π³ΠΎΠ²ΠΎΡΠΎ ΡΠ°Π΄ΡΠΎ
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 ΠΌΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° Π³ΠΎ ΠΊΠΎΡΠΈΡΡΠΈΠΌΠ΅ Π²ΠΎΠΎΠ±ΠΈΡΠ°Π΅Π½ΠΎΡΠΎ net
net-next
bpf
bpf-next
*-next
ΠΊΠ΅ΡΠ½Π΅Π»ΠΈΡΠ΅ ΡΠ΅ Π½Π°ΡΠ½Π΅ΡΡΠ°Π±ΠΈΠ»Π½ΠΈ ΠΎΠ΄ Π½Π°Π²Π΅Π΄Π΅Π½ΠΈΡΠ΅).
ΠΠ°Π΄Π²ΠΎΡ ΠΎΠ΄ ΠΎΠΏΡΠ΅Π³ΠΎΡ Π½Π° ΠΎΠ²Π°Π° ΡΡΠ°ΡΠΈΡΠ° Π΅ Π΄Π° ΡΠ΅ Π·Π±ΠΎΡΡΠ²Π° Π·Π° ΡΠΎΠ° ΠΊΠ°ΠΊΠΎ Π΄Π° ΡΠΏΡΠ°Π²ΡΠ²Π°ΡΠ΅ ΡΠΎ Π΄Π°ΡΠΎΡΠ΅ΠΊΠΈΡΠ΅ Π·Π° ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡΠ° Π½Π° ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ - ΡΠ΅ ΠΏΡΠ΅ΡΠΏΠΎΡΡΠ°Π²ΡΠ²Π° Π΄Π΅ΠΊΠ° ΠΈΠ»ΠΈ Π²Π΅ΡΠ΅ Π·Π½Π°Π΅ΡΠ΅ ΠΊΠ°ΠΊΠΎ Π΄Π° Π³ΠΎ Π½Π°ΠΏΡΠ°Π²ΠΈΡΠ΅ ΠΎΠ²Π°, ΠΈΠ»ΠΈ
ΠΡΠ΅Π·Π΅ΠΌΠ΅ΡΠ΅ Π΅Π΄Π½ΠΎ ΠΎΠ΄ Π³ΠΎΡΠ΅Π½Π°Π²Π΅Π΄Π΅Π½ΠΈΡΠ΅ ΠΊΠ΅ΡΠ½Π΅Π»ΠΈ:
$ 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 -e
bpftool
ΠΠ°ΡΡΠ΅ΡΡΠΎ ΠΊΠΎΡΠΈΡΡΠ΅Π½Π°ΡΠ° Π°Π»Π°ΡΠΊΠ° Π²ΠΎ ΡΡΠ°ΡΠΈΡΠ°ΡΠ° ΡΠ΅ Π±ΠΈΠ΄Π΅ Π°Π»Π°ΡΠΊΠ°ΡΠ° bpftool
, Π΄ΠΎΡΡΠ°Π²Π΅Π½ ΠΊΠ°ΠΊΠΎ Π΄Π΅Π» ΠΎΠ΄ ΠΊΠ΅ΡΠ½Π΅Π»ΠΎΡ ΠΠΈΠ½ΡΠΊΡ. ΠΠ°ΠΏΠΈΡΠ°Π½ Π΅ ΠΈ ΠΎΠ΄ΡΠΆΡΠ²Π°Π½ ΠΎΠ΄ BPF ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ΅ΡΠΈ Π·Π° BPF ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ΅ΡΠΈ ΠΈ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ ΠΊΠΎΡΠΈΡΡΠΈ Π·Π° ΡΠΏΡΠ°Π²ΡΠ²Π°ΡΠ΅ ΡΠΎ ΡΠΈΡΠ΅ Π²ΠΈΠ΄ΠΎΠ²ΠΈ BPF ΠΎΠ±ΡΠ΅ΠΊΡΠΈ - Π²ΡΠΈΡΡΠ²Π°ΡΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ, ΠΊΡΠ΅ΠΈΡΠ°ΡΠ΅ ΠΈ ΡΡΠ΅Π΄ΡΠ²Π°ΡΠ΅ ΠΌΠ°ΠΏΠΈ, ΠΈΡΡΡΠ°ΠΆΡΠ²Π°ΡΠ΅ Π½Π° ΠΆΠΈΠ²ΠΎΡΠΎΡ Π½Π° Π΅ΠΊΠΎΡΠΈΡΡΠ΅ΠΌΠΎΡ BPF ΠΈΡΠ½. ΠΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ Π½Π°ΡΠ΄Π΅ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΡΠ° Π²ΠΎ ΡΠΎΡΠΌΠ° Π½Π° ΠΈΠ·Π²ΠΎΡΠ½ΠΈ ΠΊΠΎΠ΄ΠΎΠ²ΠΈ Π·Π° man-ΡΡΡΠ°Π½ΠΈΡΠΈ
ΠΠΎ Π²ΡΠ΅ΠΌΠ΅ΡΠΎ Π½Π° ΠΎΠ²Π° ΠΏΠΈΡΡΠ²Π°ΡΠ΅ bpftool
Π΄ΠΎΠ°ΡΠ° Π³ΠΎΡΠΎΠ² ΡΠ°ΠΌΠΎ Π·Π° RHEL, Fedora ΠΈ Ubuntu (Π²ΠΈΠ΄ΠΈ, Π½Π° ΠΏΡΠΈΠΌΠ΅Ρ, bpftool
Π²ΠΎ ΠΠ΅Π±ΠΈΠ°Π½). ΠΠΎ, Π°ΠΊΠΎ Π²Π΅ΡΠ΅ ΡΡΠ΅ Π³ΠΎ ΠΈΠ·Π³ΡΠ°Π΄ΠΈΠ»Π΅ Π²Π°ΡΠΈΠΎΡ ΠΊΠ΅ΡΠ½Π΅Π», ΡΠΎΠ³Π°Ρ ΠΈΠ·Π³ΡΠ°Π΄ΠΈ 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 ΠΈ XDP β Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΡΠ° Π·Π° BPF ΠΎΠ΄ ΡΠΈΠ»ΠΈΡΠΌ, ΠΏΠΎΡΠΎΡΠ½ΠΎ ΠΎΠ΄ ΠΠ°Π½ΠΈΠ΅Π» ΠΠΎΡΠΊΠΌΠ°Π½, Π΅Π΄Π΅Π½ ΠΎΠ΄ ΠΊΡΠ΅Π°ΡΠΎΡΠΈΡΠ΅ ΠΈ ΠΎΠ΄ΡΠΆΡΠ²Π°ΡΠΈΡΠ΅ Π½Π° BPF. ΠΠ²Π° Π΅ Π΅Π΄Π΅Π½ ΠΎΠ΄ ΠΏΡΠ²ΠΈΡΠ΅ ΡΠ΅ΡΠΈΠΎΠ·Π½ΠΈ ΠΎΠΏΠΈΡΠΈ, ΠΊΠΎΡ ΡΠ΅ ΡΠ°Π·Π»ΠΈΠΊΡΠ²Π° ΠΎΠ΄ Π΄ΡΡΠ³ΠΈΡΠ΅ ΠΏΠΎ ΡΠΎΠ° ΡΡΠΎ ΠΠ°Π½ΠΈΠ΅Π» ΡΠΎΡΠ½ΠΎ Π·Π½Π°Π΅ Π·Π° ΡΡΠΎ ΠΏΠΈΡΡΠ²Π° ΠΈ ΡΠ°ΠΌΡ Π½Π΅ΠΌΠ° Π½ΠΈΠΊΠ°ΠΊΠ²ΠΈ Π³ΡΠ΅ΡΠΊΠΈ. ΠΠΎΠ½ΠΊΡΠ΅ΡΠ½ΠΎ, ΠΎΠ²ΠΎΡ Π΄ΠΎΠΊΡΠΌΠ΅Π½Ρ ΠΎΠΏΠΈΡΡΠ²Π° ΠΊΠ°ΠΊΠΎ Π΄Π° ΡΠ΅ ΡΠ°Π±ΠΎΡΠΈ ΡΠΎ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ΅ BPF ΠΎΠ΄ ΡΠΈΠΏΠΎΠ²ΠΈΡΠ΅ XDP ΠΈ TC ΠΊΠΎΡΠΈΡΡΠ΅ΡΡΠΈ ΡΠ° Π΄ΠΎΠ±ΡΠΎ ΠΏΠΎΠ·Π½Π°ΡΠ°ΡΠ° Π°Π»Π°ΡΠΊΠ°ip
ΠΎΠ΄ ΠΏΠ°ΠΊΡΠ²Π°ΡΠ΅ΡΠΎiproute2
. -
ΠΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΡΠ°/Π²ΠΌΡΠ΅ΠΆΡΠ²Π°ΡΠ΅/ΡΠΈΠ»ΡΠ΅Ρ.txt β ΠΎΡΠΈΠ³ΠΈΠ½Π°Π»Π½Π° Π΄Π°ΡΠΎΡΠ΅ΠΊΠ° ΡΠΎ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΡΠ° Π·Π° ΠΊΠ»Π°ΡΠΈΡΠ΅Π½, Π° ΠΏΠΎΡΠΎΠ° ΠΏΡΠΎΠ΄ΠΎΠ»ΠΆΠ΅Π½ BPF. ΠΠΎΠ±ΡΠΎ ΡΠΈΡΠ°ΡΠ΅ Π°ΠΊΠΎ ΡΠ°ΠΊΠ°ΡΠ΅ Π΄Π° ΠΈΡΡΡΠ°ΠΆΡΠ²Π°ΡΠ΅ Π²ΠΎ Π°ΡΠ΅ΠΌΠ±Π»Π΅ΡΡΠΊΠΈΠΎΡ ΡΠ°Π·ΠΈΠΊ ΠΈ ΡΠ΅Ρ Π½ΠΈΡΠΊΠΈΡΠ΅ Π°ΡΡ ΠΈΡΠ΅ΠΊΡΠΎΠ½ΡΠΊΠΈ Π΄Π΅ΡΠ°Π»ΠΈ. -
ΠΠ»ΠΎΠ³ Π·Π° BPF ΠΎΠ΄ Π€Π΅ΡΡΠ±ΡΠΊ . Π‘Π΅ Π°ΠΆΡΡΠΈΡΠ° ΡΠ΅ΡΠΊΠΎ, Π½ΠΎ ΡΠΎΠΎΠ΄Π²Π΅ΡΠ½ΠΎ, ΠΊΠ°ΠΊΠΎ ΡΡΠΎ ΠΏΠΈΡΡΠ²Π°Π°Ρ ΡΠ°ΠΌΡ ΠΠ»Π΅ΠΊΡΠ΅Ρ Π‘ΡΠ°ΡΠΎΠ²ΠΎΠΈΡΠΎΠ² (Π°Π²ΡΠΎΡ Π½Π° eBPF) ΠΈ ΠΠ½Π΄ΡΠΈΡ ΠΠ°ΠΊΡΠΈΠΈΠΊΠΎ - (ΠΎΠ΄ΡΠΆΡΠ²Π°Ρ).libbpf
). -
Π’Π°ΡΠ½ΠΈΡΠ΅ Π½Π° bpftool . ΠΠ°Π±Π°Π²Π½Π° Π½ΠΈΡΠΊΠ° Π½Π° Π’Π²ΠΈΡΠ΅Ρ ΠΎΠ΄ ΠΠ²Π΅Π½ΡΠΈΠ½ ΠΠΎΠ½Π΅ ΡΠΎ ΠΏΡΠΈΠΌΠ΅ΡΠΈ ΠΈ ΡΠ°ΡΠ½ΠΈ Π·Π° ΠΊΠΎΡΠΈΡΡΠ΅ΡΠ΅ bpftool. -
ΠΡΡΠ½Π΅ΡΠ΅ Π²ΠΎ BPF: ΡΠΏΠΈΡΠΎΠΊ Π½Π° ΠΌΠ°ΡΠ΅ΡΠΈΡΠ°Π» Π·Π° ΡΠΈΡΠ°ΡΠ΅ . ΠΠ³ΡΠΎΠΌΠ½Π° (ΠΈ ΡΓ¨ ΡΡΡΠ΅ ΠΎΠ΄ΡΠΆΡΠ²Π°Π½Π°) Π»ΠΈΡΡΠ° Π½Π° Π»ΠΈΠ½ΠΊΠΎΠ²ΠΈ Π΄ΠΎ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΡΠ°ΡΠ° Π½Π° BPF ΠΎΠ΄ ΠΠ²Π΅Π½ΡΠΈΠ½ ΠΠΎΠ½Π΅.
ΠΠ·Π²ΠΎΡ: www.habr.com