Π Π½Π°ΡΠ°Π»ΠΎΡΠΎ ΠΈΠΌΠ°ΡΠ΅ ΡΠ΅Ρ
Π½ΠΎΠ»ΠΎΠ³ΠΈΡ ΠΈ ΡΠ΅ ΠΊΠ°Π·Π²Π°ΡΠ΅ 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 ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ, Π½Π°ΡΠ΅ΡΠ΅Π½ verifier (Π½Π° Π°Π½Π³Π»ΠΈΠΉΡΠΊΠΈ ΡΠΎΠ·ΠΈ Π΅ΡΠ°ΠΏ ΡΠ΅ Π½Π°ΡΠΈΡΠ° verifier ΠΈ Π°Π· ΡΠ΅ ΠΏΡΠΎΠ΄ΡΠ»ΠΆΠ° Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌ Π°Π½Π³Π»ΠΈΠΉΡΠΊΠ°ΡΠ° Π΄ΡΠΌΠ°):
Verifier Π΅ ΡΡΠ°ΡΠΈΡΠ΅Π½ Π°Π½Π°Π»ΠΈΠ·Π°ΡΠΎΡ, ΠΊΠΎΠΉΡΠΎ Π³Π°ΡΠ°Π½ΡΠΈΡΠ°, ΡΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° Π½ΡΠΌΠ° Π΄Π° Π½Π°ΡΡΡΠΈ Π½ΠΎΡΠΌΠ°Π»Π½Π°ΡΠ° ΡΠ°Π±ΠΎΡΠ° Π½Π° ΡΠ΄ΡΠΎΡΠΎ. Π’ΠΎΠ²Π°, ΠΌΠ΅ΠΆΠ΄Ρ Π΄ΡΡΠ³ΠΎΡΠΎ, Π½Π΅ ΠΎΠ·Π½Π°ΡΠ°Π²Π°, ΡΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° Π½Π΅ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ Π½Π°ΠΌΠ΅ΡΠ²Π° Π² ΡΠ°Π±ΠΎΡΠ°ΡΠ° Π½Π° ΡΠΈΡΡΠ΅ΠΌΠ°ΡΠ° - BPF ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ΅, Π² Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡ ΠΎΡ ΡΠΈΠΏΠ°, ΠΌΠΎΠ³Π°Ρ Π΄Π° ΡΠ΅ΡΠ°Ρ ΠΈ ΠΏΡΠ΅Π½Π°ΠΏΠΈΡΠ²Π°Ρ ΡΠ΅ΠΊΡΠΈΠΈ ΠΎΡ ΠΏΠ°ΠΌΠ΅ΡΡΠ° Π½Π° ΡΠ΄ΡΠΎΡΠΎ, Π΄Π° Π²ΡΡΡΠ°Ρ ΡΡΠΎΠΉΠ½ΠΎΡΡΠΈ Π½Π° ΡΡΠ½ΠΊΡΠΈΠΈ, Π΄Π° ΠΈΠ·ΡΡΠ·Π²Π°Ρ, Π΄ΠΎΠ±Π°Π²ΡΡ, ΠΏΡΠ΅Π½Π°ΠΏΠΈΡΠ²Π°Ρ ΠΈ Π΄ΠΎΡΠΈ ΠΏΡΠ΅ΠΏΡΠ°ΡΠ° ΠΌΡΠ΅ΠΆΠΎΠ²ΠΈ ΠΏΠ°ΠΊΠ΅ΡΠΈ. Verifier Π³Π°ΡΠ°Π½ΡΠΈΡΠ°, ΡΠ΅ ΠΈΠ·ΠΏΡΠ»Π½Π΅Π½ΠΈΠ΅ΡΠΎ Π½Π° BPF ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° Π½ΡΠΌΠ° Π΄Π° ΡΡΠΈΠ½Π΅ ΡΠ΄ΡΠΎΡΠΎ ΠΈ ΡΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°, ΠΊΠΎΡΡΠΎ ΡΠΏΠΎΡΠ΅Π΄ ΠΏΡΠ°Π²ΠΈΠ»Π°ΡΠ° ΠΈΠΌΠ° Π΄ΠΎΡΡΡΠΏ Π·Π° Π·Π°ΠΏΠΈΡ, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ Π΄Π°Π½Π½ΠΈΡΠ΅ Π½Π° ΠΈΠ·Ρ ΠΎΠ΄ΡΡ ΠΏΠ°ΠΊΠ΅Ρ, Π½ΡΠΌΠ° Π΄Π° ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΏΡΠ΅Π·Π°ΠΏΠΈΡΠ΅ ΠΏΠ°ΠΌΠ΅ΡΡΠ° Π½Π° ΡΠ΄ΡΠΎΡΠΎ ΠΈΠ·Π²ΡΠ½ ΠΏΠ°ΠΊΠ΅ΡΠ°. Π©Π΅ ΡΠ°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ Π²Π΅ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΠ° ΠΌΠ°Π»ΠΊΠΎ ΠΏΠΎ-ΠΏΠΎΠ΄ΡΠΎΠ±Π½ΠΎ Π² ΡΡΠΎΡΠ²Π΅ΡΠ½ΠΈΡ ΡΠ°Π·Π΄Π΅Π», ΡΠ»Π΅Π΄ ΠΊΠ°ΡΠΎ ΡΠ΅ Π·Π°ΠΏΠΎΠ·Π½Π°Π΅ΠΌ Ρ Π²ΡΠΈΡΠΊΠΈ ΠΎΡΡΠ°Π½Π°Π»ΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠΈ Π½Π° BPF.
Π ΡΠ°ΠΊΠ°, ΠΊΠ°ΠΊΠ²ΠΎ Π½Π°ΡΡΠΈΡ
ΠΌΠ΅ Π΄ΠΎΡΠ΅Π³Π°? ΠΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΡΡ ΠΏΠΈΡΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° Π½Π° C, Π·Π°ΡΠ΅ΠΆΠ΄Π° Ρ Π² ΡΠ΄ΡΠΎΡΠΎ ΡΡΠ΅Π· ΡΠΈΡΡΠ΅ΠΌΠ½ΠΎ ΠΈΠ·Π²ΠΈΠΊΠ²Π°Π½Π΅ bpf(2)
, ΠΊΡΠ΄Π΅ΡΠΎ ΡΠ΅ ΠΏΡΠΎΠ²Π΅ΡΡΠ²Π° ΠΎΡ Π²Π΅ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ ΠΈ ΡΠ΅ ΠΏΡΠ΅Π²Π΅ΠΆΠ΄Π° Π² Π΅ΡΡΠ΅ΡΡΠ²Π΅Π½ Π±Π°ΠΉΡΠΊΠΎΠ΄. Π‘Π»Π΅Π΄ ΡΠΎΠ²Π° ΡΡΡΠΈΡΡ ΠΈΠ»ΠΈ Π΄ΡΡΠ³ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π» ΡΠ²ΡΡΠ·Π²Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° ΠΊΡΠΌ ΠΈΠ·ΡΠΎΡΠ½ΠΈΠΊΠ° Π½Π° ΡΡΠ±ΠΈΡΠΈΠ΅ ΠΈ ΡΡ Π·Π°ΠΏΠΎΡΠ²Π° Π΄Π° ΡΠ΅ ΠΈΠ·ΠΏΡΠ»Π½ΡΠ²Π°. Π Π°Π·Π΄Π΅Π»ΡΠ½Π΅ΡΠΎ Π½Π° ΡΡΠ°ΡΡΠΈΡΠ°Π½Π΅ ΠΈ ΡΠ²ΡΡΠ·Π²Π°Π½Π΅ Π΅ Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΠΎΡΠ°Π΄ΠΈ Π½ΡΠΊΠΎΠ»ΠΊΠΎ ΠΏΡΠΈΡΠΈΠ½ΠΈ. ΠΡΡΠ²ΠΎ, ΡΡΠ°ΡΡΠΈΡΠ°Π½Π΅ΡΠΎ Π½Π° Π²Π΅ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ Π΅ ΡΡΠ°Π²Π½ΠΈΡΠ΅Π»Π½ΠΎ ΡΠΊΡΠΏΠΎ ΠΈ ΠΊΠ°ΡΠΎ ΠΈΠ·ΡΠ΅Π³Π»ΡΠΌΠ΅ Π΅Π΄Π½Π° ΠΈ ΡΡΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° Π½ΡΠΊΠΎΠ»ΠΊΠΎ ΠΏΡΡΠΈ, Π½ΠΈΠ΅ Π³ΡΠ±ΠΈΠΌ ΠΊΠΎΠΌΠΏΡΡΡΡΠ½ΠΎ Π²ΡΠ΅ΠΌΠ΅. ΠΡΠΎΡΠΎ, ΠΊΠ°ΠΊ ΡΠΎΡΠ½ΠΎ Π΅ ΡΠ²ΡΡΠ·Π°Π½Π° Π΅Π΄Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° Π·Π°Π²ΠΈΡΠΈ ΠΎΡ Π½Π΅ΠΉΠ½ΠΈΡ ΡΠΈΠΏ ΠΈ Π΅Π΄ΠΈΠ½ βΡΠ½ΠΈΠ²Π΅ΡΡΠ°Π»Π΅Π½β ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ, ΡΠ°Π·ΡΠ°Π±ΠΎΡΠ΅Π½ ΠΏΡΠ΅Π΄ΠΈ Π³ΠΎΠ΄ΠΈΠ½Π°, ΠΌΠΎΠΆΠ΅ Π΄Π° Π½Π΅ Π΅ ΠΏΠΎΠ΄Ρ
ΠΎΠ΄ΡΡ Π·Π° Π½ΠΎΠ²ΠΈ Π²ΠΈΠ΄ΠΎΠ²Π΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ. (ΠΡΠΏΡΠ΅ΠΊΠΈ ΡΠ΅ ΡΠ΅Π³Π°, ΠΊΠΎΠ³Π°ΡΠΎ Π°ΡΡ
ΠΈΡΠ΅ΠΊΡΡΡΠ°ΡΠ° ΡΡΠ°Π²Π° ΠΏΠΎ-Π·ΡΡΠ»Π°, ΠΈΠΌΠ° ΠΈΠ΄Π΅Ρ ΡΠΎΠ·ΠΈ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ Π΄Π° ΡΠ΅ ΠΎΠ±Π΅Π΄ΠΈΠ½ΠΈ Π½Π° Π½ΠΈΠ²ΠΎ libbpf
.)
ΠΠ½ΠΈΠΌΠ°ΡΠ΅Π»Π½ΠΈΡΡ ΡΠΈΡΠ°ΡΠ΅Π» ΠΌΠΎΠΆΠ΅ Π΄Π° Π·Π°Π±Π΅Π»Π΅ΠΆΠΈ, ΡΠ΅ ΠΎΡΠ΅ Π½Π΅ ΡΠΌΠ΅ ΠΏΡΠΈΠΊΠ»ΡΡΠΈΠ»ΠΈ ΡΡΡ ΡΠ½ΠΈΠΌΠΊΠΈΡΠ΅. ΠΡΡΡΠ½ΠΎΡΡ Π²ΡΠΈΡΠΊΠΎ ΠΏΠΎ-Π³ΠΎΡΠ΅ Π½Π΅ ΠΎΠ±ΡΡΠ½ΡΠ²Π° Π·Π°ΡΠΎ BPF ΡΡΠ½Π΄Π°ΠΌΠ΅Π½ΡΠ°Π»Π½ΠΎ ΠΏΡΠΎΠΌΠ΅Π½Ρ ΠΊΠ°ΡΡΠΈΠ½Π°ΡΠ° Π² ΡΡΠ°Π²Π½Π΅Π½ΠΈΠ΅ Ρ ΠΊΠ»Π°ΡΠΈΡΠ΅ΡΠΊΠΈΡ BPF. ΠΠ²Π΅ ΠΈΠ½ΠΎΠ²Π°ΡΠΈΠΈ, ΠΊΠΎΠΈΡΠΎ Π·Π½Π°ΡΠΈΡΠ΅Π»Π½ΠΎ ΡΠ°Π·ΡΠΈΡΡΠ²Π°Ρ ΠΎΠ±Ρ Π²Π°ΡΠ° Π½Π° ΠΏΡΠΈΠ»ΠΎΠΆΠΈΠΌΠΎΡΡ, ΡΠ° Π²ΡΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡΠ° Π·Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π½Π° ΡΠΏΠΎΠ΄Π΅Π»Π΅Π½Π° ΠΏΠ°ΠΌΠ΅Ρ ΠΈ ΠΏΠΎΠΌΠΎΡΠ½ΠΈ ΡΡΠ½ΠΊΡΠΈΠΈ Π½Π° ΡΠ΄ΡΠΎΡΠΎ. Π BPF ΡΠΏΠΎΠ΄Π΅Π»Π΅Π½Π°ΡΠ° ΠΏΠ°ΠΌΠ΅Ρ ΡΠ΅ ΡΠ΅Π°Π»ΠΈΠ·ΠΈΡΠ° Ρ ΠΏΠΎΠΌΠΎΡΡΠ° Π½Π° ΡΠ°ΠΊΠ° Π½Π°ΡΠ΅ΡΠ΅Π½ΠΈΡΠ΅ ΠΊΠ°ΡΡΠΈ - ΡΠΏΠΎΠ΄Π΅Π»Π΅Π½ΠΈ ΡΡΡΡΠΊΡΡΡΠΈ ΠΎΡ Π΄Π°Π½Π½ΠΈ ΡΡΡ ΡΠΏΠ΅ΡΠΈΡΠΈΡΠ΅Π½ API. ΠΠ΅ΡΠΎΡΡΠ½ΠΎ ΡΠ° ΠΏΠΎΠ»ΡΡΠΈΠ»ΠΈ ΡΠΎΠ²Π° ΠΈΠΌΠ΅, Π·Π°ΡΠΎΡΠΎ ΠΏΡΡΠ²ΠΈΡΡ ΡΠΈΠΏ ΠΊΠ°ΡΡΠ°, ΠΊΠΎΠΉΡΠΎ ΡΠ΅ ΠΏΠΎΡΠ²ΠΈ, Π±Π΅ΡΠ΅ Ρ Π΅Ρ ΡΠ°Π±Π»ΠΈΡΠ°. Π‘Π»Π΅Π΄ ΡΠΎΠ²Π° ΡΠ΅ ΠΏΠΎΡΠ²ΠΈΡ Π° ΠΌΠ°ΡΠΈΠ²ΠΈ, Π»ΠΎΠΊΠ°Π»Π½ΠΈ (Π½Π° CPU) Ρ Π΅Ρ ΡΠ°Π±Π»ΠΈΡΠΈ ΠΈ Π»ΠΎΠΊΠ°Π»Π½ΠΈ ΠΌΠ°ΡΠΈΠ²ΠΈ, Π΄ΡΡΠ²Π΅ΡΠ° Π·Π° ΡΡΡΡΠ΅Π½Π΅, ΠΊΠ°ΡΡΠΈ, ΡΡΠ΄ΡΡΠΆΠ°ΡΠΈ ΡΠΊΠ°Π·Π°ΡΠ΅Π»ΠΈ ΠΊΡΠΌ BPF ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ ΠΈ ΠΌΠ½ΠΎΠ³ΠΎ Π΄ΡΡΠ³ΠΈ. Π’ΠΎΠ²Π°, ΠΊΠΎΠ΅ΡΠΎ Π΅ ΠΈΠ½ΡΠ΅ΡΠ΅ΡΠ½ΠΎ Π·Π° Π½Π°Ρ ΡΠ΅Π³Π°, Π΅, ΡΠ΅ BPF ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ΅ Π²Π΅ΡΠ΅ ΠΈΠΌΠ°Ρ ΡΠΏΠΎΡΠΎΠ±Π½ΠΎΡΡΡΠ° Π΄Π° Π·Π°ΠΏΠ°Π·Π²Π°Ρ ΡΡΡΡΠΎΡΠ½ΠΈΠ΅ΡΠΎ ΠΌΠ΅ΠΆΠ΄Ρ ΠΏΠΎΠ²ΠΈΠΊΠ²Π°Π½ΠΈΡΡΠ° ΠΈ Π΄Π° Π³ΠΎ ΡΠΏΠΎΠ΄Π΅Π»ΡΡ Ρ Π΄ΡΡΠ³ΠΈ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ ΠΈ Ρ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΡΠΊΠΎ ΠΏΡΠΎΡΡΡΠ°Π½ΡΡΠ²ΠΎ.
ΠΠΎΡΡΡΠΏΡΡ Π΄ΠΎ ΠΊΠ°ΡΡΠΈΡΠ΅ ΡΠ΅ ΠΎΡΡΡΠ΅ΡΡΠ²ΡΠ²Π° ΠΎΡ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΡΠΊΠΈ ΠΏΡΠΎΡΠ΅ΡΠΈ ΡΡΠ΅Π· ΡΠΈΡΡΠ΅ΠΌΠ½ΠΎ ΠΈΠ·Π²ΠΈΠΊΠ²Π°Π½Π΅ bpf(2)
ΠΈ ΠΎΡ BPF ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ, ΡΠ°Π±ΠΎΡΠ΅ΡΠΈ Π² ΡΠ΄ΡΠΎΡΠΎ, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΡΠΈ ΠΏΠΎΠΌΠΎΡΠ½ΠΈ ΡΡΠ½ΠΊΡΠΈΠΈ. ΠΡΠ²Π΅Π½ ΡΠΎΠ²Π° ΡΡΡΠ΅ΡΡΠ²ΡΠ²Π°Ρ ΠΏΠΎΠΌΠΎΡΠ½ΠΈΡΠΈ Π½Π΅ ΡΠ°ΠΌΠΎ Π·Π° ΡΠ°Π±ΠΎΡΠ° Ρ ΠΊΠ°ΡΡΠΈ, Π½ΠΎ ΠΈ Π·Π° Π΄ΠΎΡΡΡΠΏ Π΄ΠΎ Π΄ΡΡΠ³ΠΈ Π²ΡΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΠΈ Π½Π° ΡΠ΄ΡΠΎΡΠΎ. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, BPF ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ΅ ΠΌΠΎΠ³Π°Ρ Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ ΠΏΠΎΠΌΠΎΡΠ½ΠΈ ΡΡΠ½ΠΊΡΠΈΠΈ Π·Π° ΠΏΡΠ΅ΠΏΡΠ°ΡΠ°Π½Π΅ Π½Π° ΠΏΠ°ΠΊΠ΅ΡΠΈ ΠΊΡΠΌ Π΄ΡΡΠ³ΠΈ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠΈ, Π³Π΅Π½Π΅ΡΠΈΡΠ°Π½Π΅ Π½Π° ΠΏΠ΅ΡΡ ΡΡΠ±ΠΈΡΠΈΡ, Π΄ΠΎΡΡΡΠΏ Π΄ΠΎ ΡΡΡΡΠΊΡΡΡΠΈ Π½Π° ΡΠ΄ΡΠΎΡΠΎ ΠΈ Ρ.Π½.
Π ΠΎΠ±ΠΎΠ±ΡΠ΅Π½ΠΈΠ΅, 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. ΠΠ»Π°Ρ 7 Π΅ 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 Class 9 Operation Π΅ 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 ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° ΠΊΡΠΌ ΠΌΡΠ΅ΠΆΠΎΠ²ΠΈΡ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ, ΡΠ»Π΅Π΄ ΠΊΠΎΠ΅ΡΠΎ Π±ΡΡΡΠ»ΠΎΡΠ΄ΡΡΡΡ ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΎΡΠΈΠ΄Π΅ ΠΈ Π΄Π° ΡΠ΅ ΡΠ°ΠΌΠΎΡΠ±ΠΈΠ΅. ΠΡ Π΄ΡΡΠ³Π° ΡΡΡΠ°Π½Π°, ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π΅ΡΠ΅ ΡΠΈ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° Π·Π° ΠΏΡΠΎΡΠ»Π΅Π΄ΡΠ²Π°Π½Π΅ Π½Π° Π³ΡΠ΅ΡΠΊΠΈ, ΠΊΠΎΡΡΠΎ ΡΡΠ΅ Π½Π°ΠΏΠΈΡΠ°Π»ΠΈ Π½Π° ΠΊΠΎΠ»Π΅Π½Π΅ Π·Π° Π΄Π΅ΡΠ΅Ρ ΠΌΠΈΠ½ΡΡΠΈ - ΠΊΠΎΠ³Π°ΡΠΎ Π΅ Π·Π°Π²ΡΡΡΠ΅Π½Π°, Π±ΠΈΡ ΡΠ΅ ΠΈΡΠΊΠ°Π»ΠΈ Π΄Π° Π½ΡΠΌΠ° ΠΎΡΡΠ°Π²Π΅Π½ Π±ΠΎΠΊΠ»ΡΠΊ Π² ΡΠΈΡΡΠ΅ΠΌΠ°ΡΠ° ΠΈ Π»ΠΎΠΊΠ°Π»Π½ΠΈΡΠ΅ ΠΊΡΠΊΠΈΡΠΊΠΈ ΡΠ΅ Π³Π°ΡΠ°Π½ΡΠΈΡΠ°Ρ ΡΠΎΠ²Π°.
ΠΡ Π΄ΡΡΠ³Π° ΡΡΡΠ°Π½Π°, ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π΅ΡΠ΅ ΡΠΈ, ΡΠ΅ ΠΈΡΠΊΠ°ΡΠ΅ Π΄Π° ΡΠ΅ ΡΠ²ΡΡΠΆΠ΅ΡΠ΅ Ρ tracepoint Π² ΡΠ΄ΡΠΎΡΠΎ ΠΈ Π΄Π° ΡΡΠ±ΠΈΡΠ°ΡΠ΅ ΡΡΠ°ΡΠΈΡΡΠΈΠΊΠ° Π·Π° ΠΌΠ½ΠΎΠ³ΠΎ Π³ΠΎΠ΄ΠΈΠ½ΠΈ. Π ΡΠΎΠ·ΠΈ ΡΠ»ΡΡΠ°ΠΉ Π±ΠΈΡ
ΡΠ΅ ΠΈΡΠΊΠ°Π»ΠΈ Π΄Π° Π·Π°Π²ΡΡΡΠΈΡΠ΅ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΡΠΊΠ°ΡΠ° ΡΠ°ΡΡ ΠΈ Π΄Π° ΡΠ΅ Π²ΡΡΡΠ°ΡΠ΅ ΠΊΡΠΌ ΡΡΠ°ΡΠΈΡΡΠΈΠΊΠ°ΡΠ° ΠΎΡ Π²ΡΠ΅ΠΌΠ΅ Π½Π° Π²ΡΠ΅ΠΌΠ΅. Π€Π°ΠΉΠ»ΠΎΠ²Π°ΡΠ° ΡΠΈΡΡΠ΅ΠΌΠ° 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)
(Π½ΡΠΊΠΎΠΈ Π½Π΅ΠΏΠΎΠ΄Ρ
ΠΎΠ΄ΡΡΠΈ ΡΠ΅Π΄ΠΎΠ²Π΅ ΡΠ° ΠΏΡΠ΅ΠΌΠ°Ρ
Π½Π°ΡΠΈ ΠΎΡ ΠΈΠ·Ρ
ΠΎΠ΄Π° Π½Π° strace):
$ 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 System Call
ΠΡΠΎΠ³ΡΠ°ΠΌΠΈ Π½Π° BPF
ΠΡΠΈΡΠΊΠΈ BPF ΠΎΠ±Π΅ΠΊΡΠΈ ΡΠ΅ ΡΡΠ·Π΄Π°Π²Π°Ρ ΠΈ ΡΠΏΡΠ°Π²Π»ΡΠ²Π°Ρ ΠΎΡ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΡΠΊΠΎ ΠΏΡΠΎΡΡΡΠ°Π½ΡΡΠ²ΠΎ Ρ ΠΏΠΎΠΌΠΎΡΡΠ° Π½Π° ΡΠΈΡΡΠ΅ΠΌΠ½ΠΎ ΠΏΠΎΠ²ΠΈΠΊΠ²Π°Π½Π΅ bpf
, ΠΈΠΌΠ°Ρ ΡΠ»Π΅Π΄Π½ΠΈΡ ΠΏΡΠΎΡΠΎΡΠΈΠΏ:
#include <linux/bpf.h>
int bpf(int cmd, union bpf_attr *attr, unsigned int size);
ΠΡΠΎ Π³ΠΎ ΠΎΡΠ±ΠΎΡΠ° cmd
Π΅ Π΅Π΄Π½Π° ΠΎΡ ΡΡΠΎΠΉΠ½ΠΎΡΡΠΈΡΠ΅ Π½Π° type 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
ΡΠΈΠΉΡΠΎ Π³Π»ΠΎΠ±Π°Π»Π΅Π½ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ Π΅ 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 ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ ΠΈΠ»ΠΈ ΡΠΊΠ°Π·Π°ΡΠ΅Π»ΠΈ ΠΊΡΠΌ ΠΌΡΠ΅ΠΆΠΎΠ²ΠΈ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠΈ, ΠΊΠ°ΡΡΠΈ Π·Π° ΡΠ°Π±ΠΎΡΠ° Ρ perf ΡΡΠ±ΠΈΡΠΈΡ ΠΈ Ρ.Π½. Π’ΡΠΊ Π½ΡΠΌΠ° Π΄Π° Π³ΠΎΠ²ΠΎΡΠΈΠΌ Π·Π° ΡΡΡ
, Π·Π° Π΄Π° Π½Π΅ ΠΎΠ±ΡΡΠΊΠ°ΠΌΠ΅ ΡΠΈΡΠ°ΡΠ΅Π»Ρ. ΠΡΠ΄Π΅Π»Π½ΠΎ ΠΎΡ ΡΠΎΠ²Π°, Π½ΠΈΠ΅ ΠΈΠ³Π½ΠΎΡΠΈΡΠ°ΠΌΠ΅ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠΈΡΠ΅ ΡΡΡ ΡΠΈΠ½Ρ
ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΡΡΠ°, ΡΡΠΉ ΠΊΠ°ΡΠΎ ΡΠΎΠ²Π° Π½Π΅ Π΅ Π²Π°ΠΆΠ½ΠΎ Π·Π° Π½Π°ΡΠΈΡΠ΅ ΠΏΡΠΈΠΌΠ΅ΡΠΈ. ΠΡΠ»Π΅Π½ ΡΠΏΠΈΡΡΠΊ Π½Π° Π½Π°Π»ΠΈΡΠ½ΠΈΡΠ΅ ΡΠΈΠΏΠΎΠ²Π΅ ΠΊΠ°ΡΡΠΈ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° Π½Π°ΠΌΠ΅ΡΠΈΡΠ΅ Π² <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 Π΅ Π³Π»ΠΎΠ±Π°Π»Π½ΠΈΡΡ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ Π½Π° Π½Π°ΡΠΈΡ ΠΎΠ±Π΅ΠΊΡ. ΠΡΡΠΊΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° Π² ΡΠΈΡΡΠ΅ΠΌΠ°ΡΠ° ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° ΡΠΎΠ·ΠΈ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ, Π·Π° Π΄Π° ΠΎΡΠ²ΠΎΡΠΈ ΡΡΡΠ΅ΡΡΠ²ΡΠ²Π°ΡΠ° ΠΊΠ°ΡΡΠ° Ρ ΠΏΠΎΠΌΠΎΡΡΠ° Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄Π°ΡΠ° 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
ΠΡΡΠ²ΠΎ ΠΎΡΠ²ΠΎΡΠΈΡ
ΠΌΠ΅ ΠΊΠ°ΡΡΠ°ΡΠ° ΠΏΠΎ Π½Π΅ΠΉΠ½ΠΈΡ Π³Π»ΠΎΠ±Π°Π»Π΅Π½ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ Ρ ΠΏΠΎΠΌΠΎΡΡΠ° Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄Π°ΡΠ° 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
: ΠΎΡΠ²Π°ΡΡ ΡΡΡΠ΅ΡΡΠ²ΡΠ²Π°ΡΠ° ΠΊΠ°ΡΡΠ° ΠΏΠΎ Π½Π΅ΠΉΠ½ΠΈΡ Π³Π»ΠΎΠ±Π°Π»Π΅Π½ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡBPF_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
- ΡΠ΅Π³Π° Π½Π΅ Π΅ Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎ Π΄Π° ΠΈΠ½ΡΡΠ°Π»ΠΈΡΠ°ΠΌΠ΅ ΠΏΠ°ΠΊΠ΅ΡΠ° kernel-headers, Π·Π° Π΄Π° ΡΠ°Π·Π±Π΅ΡΠ΅ΠΌ ΠΊΠ°ΠΊ ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π°Ρ ΡΡΡΡΠΊΡΡΡΠΈΡΠ΅ Π½Π° ΡΠ΄ΡΠΎΡΠΎ. Π‘Π»Π΅Π΄Π½ΠΈΡΡ Π·Π°Π³Π»Π°Π²Π΅Π½ ΡΠ°ΠΉΠ» ΠΈΠ΄Π²Π° ΠΏΡΠΈ Π½Π°Ρ ΠΎΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ°ΡΠ° libbpf
. Π‘Π΅Π³Π° Π½ΠΈ ΡΡΡΠ±Π²Π° ΡΠ°ΠΌΠΎ Π·Π° Π΄Π΅ΡΠΈΠ½ΠΈΡΠ°Π½Π΅ Π½Π° ΠΌΠ°ΠΊΡΠΎΡΠ° SEC
, ΠΊΠΎΠΉΡΠΎ ΠΈΠ·ΠΏΡΠ°ΡΠ° Π·Π½Π°ΠΊΠ° Π² ΡΡΠΎΡΠ²Π΅ΡΠ½ΠΈΡ ΡΠ°Π·Π΄Π΅Π» Π½Π° ELF ΠΎΠ±Π΅ΠΊΡΠ½ΠΈΡ ΡΠ°ΠΉΠ». ΠΠ°ΡΠ°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° ΡΠ΅ ΡΡΠ΄ΡΡΠΆΠ° Π² ΡΠ°Π·Π΄Π΅Π»Π° xdp/simple
, ΠΊΡΠ΄Π΅ΡΠΎ ΠΏΡΠ΅Π΄ΠΈ Π½Π°ΠΊΠ»ΠΎΠ½Π΅Π½Π°ΡΠ° ΡΠ΅ΡΡΠ° Π΄Π΅ΡΠΈΠ½ΠΈΡΠ°ΠΌΠ΅ Π²ΠΈΠ΄Π° Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° BPF - ΡΠΎΠ²Π° Π΅ ΠΊΠΎΠ½Π²Π΅Π½ΡΠΈΡΡΠ°, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π° Π² libbpf
, Π²ΡΠ· ΠΎΡΠ½ΠΎΠ²Π° Π½Π° ΠΈΠΌΠ΅ΡΠΎ Π½Π° ΡΠ°Π·Π΄Π΅Π»Π°, ΡΠΎΠΉ ΡΠ΅ Π·Π°ΠΌΠ΅Π½ΠΈ ΠΏΡΠ°Π²ΠΈΠ»Π½ΠΈΡ ΡΠΈΠΏ ΠΏΡΠΈ ΡΡΠ°ΡΡΠΈΡΠ°Π½Π΅ bpf(2)
. Π‘Π°ΠΌΠ°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° Π½Π° ΠΠΠ€ Π΅ 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
. ΠΠ΅ΠΊΠ° Π½Π°ΠΌΠ΅ΡΠΈΠΌ Π½Π΅ΠΉΠ½ΠΈΡ ID:
# 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
, ΠΊΠΎΠΉΡΠΎ ΠΎΠΏΡΠ΅Π΄Π΅Π»Ρ ΠΎΡ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΠ° Π½Π° ΠΏΠΎΠΌΠΎΡΠ½Π°ΡΠ° ΡΡΠ½ΠΊΡΠΈΡ Π΄Π°Π»ΠΈ 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, Π±ΡΡ
Π° ΠΎΡ ΠΎΠ½Π»Π°ΠΉΠ½ ΠΎΠ±ΡΠ½ΠΎΡΡΡΠ° Π½Π° Linux, ΠΊΠΎΠ΅ΡΠΎ ΠΎΠ·Π½Π°ΡΠ°Π²Π°, ΡΠ΅ ΡΠ° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π»ΠΈ Π½Π°ΠΉ-ΠΏΠΎΠ·Π½Π°ΡΠΈΡ Π·Π° ΡΡΡ
(Π½ΠΎ Π½Π΅ ΠΈ Π·Π° Π½ΠΎΡΠΌΠ°Π»Π½ΠΎ Ρ
ΠΎΡΠ°) ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ Π·Π° Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡΠ²ΠΈΠ΅ Ρ ΡΠ΄ΡΠΎΡΠΎ: xdp_attach
ΠΊΠΎΠΏΠΈΡΠ° ΠΊΠΎΠ΄ ΠΎΡ libbpf
, Π° ΠΈΠΌΠ΅Π½Π½ΠΎ ΠΎΡ ΡΠ°ΠΉΠ»Π° netlink.c
ΠΠΎΠ±ΡΠ΅ Π΄ΠΎΡΠ»ΠΈ Π² ΡΠ²Π΅ΡΠ° Π½Π° netlink Π³Π½Π΅Π·Π΄Π°ΡΠ°
ΠΡΠ²ΠΎΡΠ΅ΡΠ΅ ΡΠΈΠΏ Π³Π½Π΅Π·Π΄ΠΎ Π·Π° ΠΌΡΠ΅ΠΆΠΎΠ²Π° Π²ΡΡΠ·ΠΊΠ° 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
ΠΠ΅ΠΊΠ° ΠΈΠ·ΠΏΡΠ°ΡΠΈΠΌ ping ΠΈ ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌ ΠΊΠ°ΡΡΠ°ΡΠ°:
$ 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/Π·Π²ΡΠ½
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
, Π΄ΠΎΡΡΠ°Π²Π΅Π½ ΠΊΠ°ΡΠΎ ΡΠ°ΡΡ ΠΎΡ ΡΠ΄ΡΠΎΡΠΎ Π½Π° Linux. Π’ΠΎΠΉ Π΅ Π½Π°ΠΏΠΈΡΠ°Π½ ΠΈ ΠΏΠΎΠ΄Π΄ΡΡΠΆΠ°Π½ ΠΎΡ BPF ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΡΠΈ Π·Π° BPF ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΡΠΈ ΠΈ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π·Π° ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ Π½Π° Π²ΡΠΈΡΠΊΠΈ Π²ΠΈΠ΄ΠΎΠ²Π΅ BPF ΠΎΠ±Π΅ΠΊΡΠΈ - Π·Π°ΡΠ΅ΠΆΠ΄Π°Π½Π΅ Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ, ΡΡΠ·Π΄Π°Π²Π°Π½Π΅ ΠΈ ΡΠ΅Π΄Π°ΠΊΡΠΈΡΠ°Π½Π΅ Π½Π° ΠΊΠ°ΡΡΠΈ, ΠΈΠ·ΡΠ»Π΅Π΄Π²Π°Π½Π΅ Π½Π° ΠΆΠΈΠ²ΠΎΡΠ° Π½Π° BPF Π΅ΠΊΠΎΡΠΈΡΡΠ΅ΠΌΠ°ΡΠ° ΠΈ Ρ.Π½. ΠΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ Π½Π°ΠΌΠ΅ΡΠΈ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΡ ΠΏΠΎΠ΄ ΡΠΎΡΠΌΠ°ΡΠ° Π½Π° ΠΈΠ·Ρ
ΠΎΠ΄Π½ΠΈ ΠΊΠΎΠ΄ΠΎΠ²Π΅ Π·Π° ΡΡΡΠ°Π½ΠΈΡΠΈ Ρ ΡΡΠΊΠΎΠ²ΠΎΠ΄ΡΡΠ²ΠΎ
ΠΡΠΌ ΠΌΠΎΠΌΠ΅Π½ΡΠ° Π½Π° ΠΏΠΈΡΠ°Π½Π΅ Π½Π° ΡΠ°Π·ΠΈ ΡΡΠ°ΡΠΈΡ 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 ΠΎΡ cilium, ΠΈΠ»ΠΈ ΠΏΠΎ-ΡΠΎΡΠ½ΠΎ ΠΎΡ Daniel Borkman, Π΅Π΄ΠΈΠ½ ΠΎΡ ΡΡΠ·Π΄Π°ΡΠ΅Π»ΠΈΡΠ΅ ΠΈ ΠΏΠΎΠ΄Π΄ΡΡΠΆΠ°ΡΠΈΡΠ΅ BPF. Π’ΠΎΠ²Π° Π΅ Π΅Π΄Π½ΠΎ ΠΎΡ ΠΏΡΡΠ²ΠΈΡΠ΅ ΡΠ΅ΡΠΈΠΎΠ·Π½ΠΈ ΠΎΠΏΠΈΡΠ°Π½ΠΈΡ, ΠΊΠΎΠ΅ΡΠΎ ΡΠ΅ ΠΎΡΠ»ΠΈΡΠ°Π²Π° ΠΎΡ ΠΎΡΡΠ°Π½Π°Π»ΠΈΡΠ΅ Ρ ΡΠΎΠ²Π°, ΡΠ΅ ΠΠ°Π½ΠΈΠ΅Π» Π·Π½Π°Π΅ ΡΠΎΡΠ½ΠΎ ΠΊΠ°ΠΊΠ²ΠΎ ΠΏΠΈΡΠ΅ ΠΈ ΡΠ°ΠΌ Π½ΡΠΌΠ° Π³ΡΠ΅ΡΠΊΠΈ. ΠΠΎ-ΡΠΏΠ΅ΡΠΈΠ°Π»Π½ΠΎ, ΡΠΎΠ·ΠΈ Π΄ΠΎΠΊΡΠΌΠ΅Π½Ρ ΠΎΠΏΠΈΡΠ²Π° ΠΊΠ°ΠΊ Π΄Π° ΡΠ°Π±ΠΎΡΠΈΡΠ΅ Ρ BPF ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ ΠΎΡ ΡΠΈΠΏΠ° XDP ΠΈ TC Ρ ΠΏΠΎΠΌΠΎΡΡΠ° Π½Π° Π΄ΠΎΠ±ΡΠ΅ ΠΏΠΎΠ·Π½Π°ΡΠ°ΡΠ° ΠΏΠΎΠΌΠΎΡΠ½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ip
ΠΎΡ ΠΏΠ°ΠΊΠ΅Ρiproute2
. -
Documentation/networking/filter.txt β ΠΎΡΠΈΠ³ΠΈΠ½Π°Π»Π΅Π½ ΡΠ°ΠΉΠ» Ρ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΡ Π·Π° ΠΊΠ»Π°ΡΠΈΡΠ΅ΡΠΊΠΈ ΠΈ ΡΠ»Π΅Π΄ ΡΠΎΠ²Π° ΡΠ°Π·ΡΠΈΡΠ΅Π½ BPF. ΠΠΎΠ±ΡΠΎ ΡΠ΅ΡΠΈΠ²ΠΎ, Π°ΠΊΠΎ ΠΈΡΠΊΠ°ΡΠ΅ Π΄Π° ΡΠ΅ Π·Π°Π΄ΡΠ»Π±ΠΎΡΠΈΡΠ΅ Π² Π°ΡΠ΅ΠΌΠ±Π»Π΅ΡΠ½ΠΈΡ Π΅Π·ΠΈΠΊ ΠΈ ΡΠ΅Ρ Π½ΠΈΡΠ΅ΡΠΊΠΈΡΠ΅ Π°ΡΡ ΠΈΡΠ΅ΠΊΡΡΡΠ½ΠΈ Π΄Π΅ΡΠ°ΠΉΠ»ΠΈ. -
ΠΠ»ΠΎΠ³ Π·Π° BPF ΠΎΡ facebook . ΠΠΊΡΡΠ°Π»ΠΈΠ·ΠΈΡΠ° ΡΠ΅ ΡΡΠ΄ΠΊΠΎ, Π½ΠΎ ΡΠΌΠ΅ΡΡΠ½ΠΎ, ΠΊΠ°ΠΊΡΠΎ ΠΏΠΈΡΠ°Ρ ΡΠ°ΠΌ ΠΠ»Π΅ΠΊΡΠ΅ΠΉ Π‘ΡΠ°ΡΠΎΠ²ΠΎΠΉΡΠΎΠ² (Π°Π²ΡΠΎΡ Π½Π° eBPF) ΠΈ ΠΠ½Π΄ΡΠΈΠΉ ΠΠ°ΠΊΡΠΈΠΉΠΊΠΎ - (ΠΏΠΎΠ΄Π΄ΡΡΠΆΠ°Ρ)libbpf
). -
Π’Π°ΠΉΠ½ΠΈΡΠ΅ Π½Π° bpftool . ΠΠ°Π±Π°Π²Π½Π° Π½ΠΈΡΠΊΠ° Π² Twitter ΠΎΡ Quentin Monnet Ρ ΠΏΡΠΈΠΌΠ΅ΡΠΈ ΠΈ ΡΠ°ΠΉΠ½ΠΈ Π·Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π½Π° bpftool. -
ΠΠΎΡΠΎΠΏΠ΅ΡΠ΅ ΡΠ΅ Π² BPF: ΡΠΏΠΈΡΡΠΊ Ρ ΠΌΠ°ΡΠ΅ΡΠΈΠ°Π»ΠΈ Π·Π° ΡΠ΅ΡΠ΅Π½Π΅ . ΠΠ³ΡΠΎΠΌΠ΅Π½ (ΠΈ Π²ΡΠ΅ ΠΎΡΠ΅ ΠΏΠΎΠ΄Π΄ΡΡΠΆΠ°Π½) ΡΠΏΠΈΡΡΠΊ Ρ Π²ΡΡΠ·ΠΊΠΈ ΠΊΡΠΌ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΡ Π½Π° BPF ΠΎΡ ΠΡΠ΅Π½ΡΠΈΠ½ ΠΠΎΠ½Π΅.
ΠΠ·ΡΠΎΡΠ½ΠΈΠΊ: www.habr.com