BPF Π·Π° Π½Π°Ρ˜ΠΌΠ°Π»ΠΈΡ‚Π΅, ΠΏΡ€Π² Π΄Π΅Π»: ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ΅Π½ BPF

На ΠΏΠΎΡ‡Π΅Ρ‚ΠΎΠΊΠΎΡ‚ имашС Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΡ˜Π° ΠΈ сС викашС BPF. Ја ΠΏΠΎΠ³Π»Π΅Π΄Π½Π°Π²ΠΌΠ΅ ΠΏΡ€Π΅Ρ‚Ρ…ΠΎΠ΄Π½ΠΈΠΎΡ‚, старозавСтна ΡΡ‚Π°Ρ‚ΠΈΡ˜Π° ΠΎΠ΄ ΠΎΠ²Π°Π° ΡΠ΅Ρ€ΠΈΡ˜Π°. Π’ΠΎ 2013 Π³ΠΎΠ΄ΠΈΠ½Π°, ΠΏΡ€Π΅ΠΊΡƒ Π½Π°ΠΏΠΎΡ€ΠΈΡ‚Π΅ Π½Π° АлСксСј Π‘Ρ‚Π°Ρ€ΠΎΠ²ΠΎΠΈΡ‚ΠΎΠ² ΠΈ Π”Π°Π½ΠΈΠ΅Π» Π‘ΠΎΡ€ΠΊΠΌΠ°Π½, бСшС Ρ€Π°Π·Π²ΠΈΠ΅Π½Π° ΠΏΠΎΠ΄ΠΎΠ±Ρ€Π΅Π½Π° Π²Π΅Ρ€Π·ΠΈΡ˜Π° Π½Π° истата, ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€Π°Π½Π° Π·Π° ΠΌΠΎΠ΄Π΅Ρ€Π½ΠΈ 64-Π±ΠΈΡ‚Π½ΠΈ машини, која бСшС Π²ΠΊΠ»ΡƒΡ‡Π΅Π½Π° Π²ΠΎ ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚ Π½Π° Линукс. Оваа Π½ΠΎΠ²Π° Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΡ˜Π° Π½Π°ΠΊΡ€Π°Ρ‚ΠΊΠΎ бСшС Π½Π°Ρ€Π΅Ρ‡Π΅Π½Π° Internal BPF, ΠΏΠΎΡ‚ΠΎΠ° ΠΏΡ€Π΅ΠΈΠΌΠ΅Π½ΡƒΠ²Π°Π½Π° Π²ΠΎ Extended BPF, Π° сСга, ΠΏΠΎ Π½Π΅ΠΊΠΎΠ»ΠΊΡƒ Π³ΠΎΠ΄ΠΈΠ½ΠΈ, ситС Сдноставно ја Π½Π°Ρ€Π΅ΠΊΡƒΠ²Π°Π°Ρ‚ BPF.

Π“Ρ€ΡƒΠ±ΠΎ ΠΊΠ°ΠΆΠ°Π½ΠΎ, BPF Π²ΠΈ ΠΎΠ²ΠΎΠ·ΠΌΠΎΠΆΡƒΠ²Π° Π΄Π° ΠΈΠ·Π²Ρ€ΡˆΠΈΡ‚Π΅ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»Π΅Π½ ΠΊΠΎΠ΄ ΠΎΠ±Π΅Π·Π±Π΅Π΄Π΅Π½ ΠΎΠ΄ корисникот Π²ΠΎ просторот Π½Π° ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚ Π½Π° Linux, Π° Π½ΠΎΠ²Π°Ρ‚Π° Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π° сС ΠΏΠΎΠΊΠ°ΠΆΠ° Ρ‚ΠΎΠ»ΠΊΡƒ ΡƒΡΠΏΠ΅ΡˆΠ½Π° ΡˆΡ‚ΠΎ ќС Π½ΠΈ Ρ‚Ρ€Π΅Π±Π°Π°Ρ‚ ΡƒΡˆΡ‚Π΅ дСсСтина статии Π·Π° Π΄Π° Π³ΠΈ опишСмС ситС нСјзини Π°ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΠΈ. (ЕдинствСното Π½Π΅ΡˆΡ‚ΠΎ ΡˆΡ‚ΠΎ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ΅Ρ€ΠΈΡ‚Π΅ Π½Π΅ Π³ΠΎ Π½Π°ΠΏΡ€Π°Π²ΠΈΡ˜Π° Π΄ΠΎΠ±Ρ€ΠΎ, ΠΊΠ°ΠΊΠΎ ΡˆΡ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Π²ΠΈΠ΄ΠΈΡ‚Π΅ Π²ΠΎ ΠΊΠΎΠ΄ΠΎΡ‚ Π·Π° ΠΈΠ·Π²Π΅Π΄Π±Π° ΠΏΠΎΠ΄ΠΎΠ»Ρƒ, бСшС создавањС ΠΏΡ€ΠΈΡΡ‚ΠΎΡ˜Π½ΠΎ Π»ΠΎΠ³ΠΎ.)

Оваа ΡΡ‚Π°Ρ‚ΠΈΡ˜Π° ја ΠΎΠΏΠΈΡˆΡƒΠ²Π° структурата Π½Π° Π²ΠΈΡ€Ρ‚ΡƒΠ΅Π»Π½Π°Ρ‚Π° машина BPF, ΠΈΠ½Ρ‚Π΅Ρ€Ρ„Π΅Ρ˜ΡΠΈΡ‚Π΅ Π½Π° Ρ˜Π°Π΄Ρ€ΠΎΡ‚ΠΎ Π·Π° Ρ€Π°Π±ΠΎΡ‚Π° со BPF, Ρ€Π°Π·Π²ΠΎΡ˜Π½ΠΈΡ‚Π΅ Π°Π»Π°Ρ‚ΠΊΠΈ, ΠΊΠ°ΠΊΠΎ ΠΈ ΠΊΡ€Π°Ρ‚ΠΎΠΊ, ΠΌΠ½ΠΎΠ³Ρƒ ΠΊΡ€Π°Ρ‚ΠΎΠΊ ΠΏΡ€Π΅Π³Π»Π΅Π΄ Π½Π° постоСчкитС способности, Ρ‚.Π΅. сС ΡˆΡ‚ΠΎ ќС Π½ΠΈ Ρ‚Ρ€Π΅Π±Π° Π²ΠΎ ΠΈΠ΄Π½ΠΈΠ½Π° Π·Π° ΠΏΠΎΠ΄Π»Π°Π±ΠΎΠΊΠΎ ΠΏΡ€ΠΎΡƒΡ‡ΡƒΠ²Π°ΡšΠ΅ Π½Π° ΠΏΡ€Π°ΠΊΡ‚ΠΈΡ‡Π½ΠΈΡ‚Π΅ ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈ Π½Π° BPF.
BPF Π·Π° Π½Π°Ρ˜ΠΌΠ°Π»ΠΈΡ‚Π΅, ΠΏΡ€Π² Π΄Π΅Π»: ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ΅Π½ BPF

Π Π΅Π·ΠΈΠΌΠ΅ Π½Π° ΡΡ‚Π°Ρ‚ΠΈΡ˜Π°Ρ‚Π°

Π’ΠΎΠ²Π΅Π΄ Π²ΠΎ Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°Ρ‚Π° BPF. ΠŸΡ€Π²ΠΎ, ќС ја ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°Ρ‚Π° Π½Π° BPF ΠΎΠ΄ ΠΏΡ‚ΠΈΡ‡Ρ˜Π° пСрспСктива ΠΈ ќС Π³ΠΈ прСтставимС Π³Π»Π°Π²Π½ΠΈΡ‚Π΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΈ.

РСгистри ΠΈ ΠΊΠΎΠΌΠ°Π½Π΄Π΅Π½ систСм Π½Π° Π²ΠΈΡ€Ρ‚ΡƒΠ΅Π»Π½Π°Ρ‚Π° машина BPF. Π’Π΅ΡœΠ΅ имајќи идСја Π·Π° Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°Ρ‚Π° ΠΊΠ°ΠΊΠΎ Ρ†Π΅Π»ΠΈΠ½Π°, ќС ја опишСмС структурата Π½Π° Π²ΠΈΡ€Ρ‚ΡƒΠ΅Π»Π½Π°Ρ‚Π° машина BPF.

Π–ΠΈΠ²ΠΎΡ‚Π΅Π½ циклус Π½Π° ΠΎΠ±Ρ˜Π΅ΠΊΡ‚ΠΈ BPF, Π΄Π°Ρ‚ΠΎΡ‚Π΅Ρ‡Π΅Π½ систСм bpffs. Π’ΠΎ овој Π΄Π΅Π» ΠΏΠΎΠ΄Π΅Ρ‚Π°Π»Π½ΠΎ ќС Π³ΠΎ Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ ΠΆΠΈΠ²ΠΎΡ‚Π½ΠΈΠΎΡ‚ циклус Π½Π° ΠΎΠ±Ρ˜Π΅ΠΊΡ‚ΠΈΡ‚Π΅ Π½Π° BPF - ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ ΠΈ ΠΌΠ°ΠΏΠΈ.

Π£ΠΏΡ€Π°Π²ΡƒΠ²Π°ΡšΠ΅ со ΠΎΠ±Ρ˜Π΅ΠΊΡ‚ΠΈ ΠΊΠΎΡ€ΠΈΡΡ‚Π΅Ρ˜ΡœΠΈ Π³ΠΎ систСмскиот ΠΏΠΎΠ²ΠΈΠΊ bpf. Π‘ΠΎ ΠΎΠ΄Ρ€Π΅Π΄Π΅Π½ΠΎ Ρ€Π°Π·Π±ΠΈΡ€Π°ΡšΠ΅ Π·Π° систСмот вСќС поставСн, ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎ ќС ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ ΠΊΠ°ΠΊΠΎ Π΄Π° ΠΊΡ€Π΅ΠΈΡ€Π°ΠΌΠ΅ ΠΈ ΠΌΠ°Π½ΠΈΠΏΡƒΠ»ΠΈΡ€Π°ΠΌΠ΅ со ΠΎΠ±Ρ˜Π΅ΠΊΡ‚ΠΈ ΠΎΠ΄ корисничкиот простор ΠΊΠΎΡ€ΠΈΡΡ‚Π΅Ρ˜ΡœΠΈ ΡΠΏΠ΅Ρ†ΠΈΡ˜Π°Π»Π΅Π½ систСмски ΠΏΠΎΠ²ΠΈΠΊ βˆ’ bpf(2).

ПишСм ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ BPF с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ libbpf. Π‘Π΅ Ρ€Π°Π·Π±ΠΈΡ€Π°, ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° ΠΏΠΈΡˆΡƒΠ²Π°Ρ‚Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ ΠΊΠΎΡ€ΠΈΡΡ‚Π΅Ρ˜ΡœΠΈ систСмски ΠΏΠΎΠ²ΠΈΠΊ. Но, Ρ‚ΠΎΠ° Π΅ Ρ‚Π΅ΡˆΠΊΠΎ. Π—Π° ΠΏΠΎΡ€Π΅Π°Π»Π½ΠΎ сцСнарио, Π½ΡƒΠΊΠ»Π΅Π°Ρ€Π½ΠΈΡ‚Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ΅Ρ€ΠΈ Ρ€Π°Π·Π²ΠΈΡ˜Π° Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° libbpf. ЌС создадСмС основСн скСлСт Π·Π° Π°ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΡ˜Π° BPF ΡˆΡ‚ΠΎ ќС Π³ΠΎ користимС Π²ΠΎ слСднитС ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΈ.

ΠŸΠΎΠΌΠΎΡˆΠ½ΠΈΡ†ΠΈ Π½Π° Ρ˜Π°Π΄Ρ€ΠΎΡ‚ΠΎ. ОвдС ќС Π½Π°ΡƒΡ‡ΠΈΠΌΠ΅ ΠΊΠ°ΠΊΠΎ BPF-ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ ΠΌΠΎΠΆΠ°Ρ‚ Π΄Π° пристапат Π΄ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈΡ‚Π΅ Π·Π° помош Π½Π° ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚ - Π°Π»Π°Ρ‚ΠΊΠ° која, Π·Π°Π΅Π΄Π½ΠΎ со ΠΌΠ°ΠΏΠΈΡ‚Π΅, ΡΡƒΡˆΡ‚ΠΈΠ½ΡΠΊΠΈ Π³ΠΈ ΠΏΡ€ΠΎΡˆΠΈΡ€ΡƒΠ²Π° моТноститС Π½Π° Π½ΠΎΠ²ΠΈΠΎΡ‚ BPF Π²ΠΎ спорСдба со класичниот.

ΠŸΡ€ΠΈΡΡ‚Π°ΠΏ Π΄ΠΎ ΠΌΠ°ΠΏΠΈ ΠΎΠ΄ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ BPF. Π”ΠΎ овој ΠΌΠΎΠΌΠ΅Π½Ρ‚, ќС Π·Π½Π°Π΅ΠΌΠ΅ Π΄ΠΎΠ²ΠΎΠ»Π½ΠΎ Π·Π° Π΄Π° Ρ€Π°Π·Π±Π΅Ρ€Π΅ΠΌΠ΅ Ρ‚ΠΎΡ‡Π½ΠΎ ΠΊΠ°ΠΊΠΎ ΠΌΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° ΠΊΡ€Π΅ΠΈΡ€Π°ΠΌΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ ΡˆΡ‚ΠΎ користат ΠΌΠ°ΠΏΠΈ. И, Π΄ΡƒΡ€ΠΈ ΠΈ Π΄Π° Ρ•ΠΈΡ€Π½Π΅ΠΌΠ΅ Π²ΠΎ Π³ΠΎΠ»Π΅ΠΌΠΈΠΎΡ‚ ΠΈ моќСн ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡƒΠ²Π°Ρ‡.

Алатки Π·Π° Ρ€Π°Π·Π²ΠΎΡ˜. Π”Π΅Π» Π·Π° помош Π·Π° Ρ‚ΠΎΠ° ΠΊΠ°ΠΊΠΎ Π΄Π° сС собСрат ΠΏΠΎΡ‚Ρ€Π΅Π±Π½ΠΈΡ‚Π΅ Π°Π»Π°Ρ‚ΠΊΠΈ ΠΈ Ρ˜Π°Π΄Ρ€ΠΎ Π·Π° СкспСримСнти.

Π—Π°ΠΊΠ»ΡƒΡ‡ΠΎΠΊ. На ΠΊΡ€Π°Ρ˜ΠΎΡ‚ ΠΎΠ΄ ΡΡ‚Π°Ρ‚ΠΈΡ˜Π°Ρ‚Π°, ΠΎΠ½ΠΈΠ΅ ΡˆΡ‚ΠΎ ќС ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Π°Ρ‚ Π΄ΠΎ Ρ‚ΡƒΠΊΠ° ќС Π½Π°Ρ˜Π΄Π°Ρ‚ ΠΌΠΎΡ‚ΠΈΠ²ΠΈΡ€Π°Ρ‡ΠΊΠΈ Π·Π±ΠΎΡ€ΠΎΠ²ΠΈ ΠΈ ΠΊΡ€Π°Ρ‚ΠΎΠΊ опис Π·Π° Ρ‚ΠΎΠ° ΡˆΡ‚ΠΎ ќС сС случи Π²ΠΎ слСднитС статии. ЌС Π½Π°Π²Π΅Π΄Π΅ΠΌΠ΅ ΠΈ Π³ΠΎΠ»Π΅ΠΌ Π±Ρ€ΠΎΡ˜ Π»ΠΈΠ½ΠΊΠΎΠ²ΠΈ Π·Π° ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡ˜Π½ΠΎ ΡƒΡ‡Π΅ΡšΠ΅ Π·Π° ΠΎΠ½ΠΈΠ΅ ΠΊΠΎΠΈ Π½Π΅ΠΌΠ°Π°Ρ‚ ΠΆΠ΅Π»Π±Π° ΠΈΠ»ΠΈ моТност Π΄Π° Π³ΠΎ Ρ‡Π΅ΠΊΠ°Π°Ρ‚ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ.

Π’ΠΎΠ²Π΅Π΄ Π²ΠΎ Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°Ρ‚Π° BPF

ΠŸΡ€Π΅Π΄ Π΄Π° Π·Π°ΠΏΠΎΡ‡Π½Π΅ΠΌΠ΅ Π΄Π° ја Ρ€Π°Π·Π³Π»Π΅Π΄ΡƒΠ²Π°ΠΌΠ΅ Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°Ρ‚Π° BPF, ќС сС ΠΏΠΎΠ²ΠΈΠΊΠ°ΠΌΠ΅ послСдСн ΠΏΠ°Ρ‚ (ΠΎΡ…). класичСн BPF, кој бСшС Ρ€Π°Π·Π²ΠΈΠ΅Π½ ΠΊΠ°ΠΊΠΎ ΠΎΠ΄Π³ΠΎΠ²ΠΎΡ€ Π½Π° ΠΏΠΎΡ˜Π°Π²Π°Ρ‚Π° Π½Π° RISC ΠΌΠ°ΡˆΠΈΠ½ΠΈΡ‚Π΅ ΠΈ Π³ΠΎ Ρ€Π΅ΡˆΠΈ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΎΡ‚ со Сфикасно Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈΡ€Π°ΡšΠ΅ Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ. АрхитСктурата сС ΠΏΠΎΠΊΠ°ΠΆΠ° ΠΊΠ°ΠΊΠΎ Ρ‚ΠΎΠ»ΠΊΡƒ ΡƒΡΠΏΠ΅ΡˆΠ½Π° ΡˆΡ‚ΠΎ, Ρ€ΠΎΠ΄Π΅Π½Π° Π²ΠΎ дСвСдСсСттитС Π²ΠΎ Π‘Π΅Ρ€ΠΊΠ»ΠΈ UNIX, бСшС прСнСсСна Π½Π° ΠΏΠΎΠ²Π΅ΡœΠ΅Ρ‚ΠΎ постоСчки ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΈΠ²Π½ΠΈ систСми, ΠΏΡ€Π΅ΠΆΠΈΠ²Π΅Π° Π²ΠΎ Π»ΡƒΠ΄ΠΈΡ‚Π΅ дваСсСтти ΠΈ сè ΡƒΡˆΡ‚Π΅ Π½Π°ΠΎΡ“Π° Π½ΠΎΠ²ΠΈ Π°ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΠΈ.

Новиот BPF бСшС Ρ€Π°Π·Π²ΠΈΠ΅Π½ ΠΊΠ°ΠΊΠΎ ΠΎΠ΄Π³ΠΎΠ²ΠΎΡ€ Π½Π° сСприсутноста Π½Π° 64-Π±ΠΈΡ‚Π½ΠΈ машини, ΠΎΠ±Π»Π°ΠΊ услуги ΠΈ Π·Π³ΠΎΠ»Π΅ΠΌΠ΅Π½Π°Ρ‚Π° ΠΏΠΎΡ‚Ρ€Π΅Π±Π° Π·Π° Π°Π»Π°Ρ‚ΠΊΠΈ Π·Π° создавањС SDN (SΠ½Π°Ρ„Ρ‚Π²Π΅Ρ€-dΠ΅Ρ„ΠΈΠ½ΠΈΡ€Π°Π½ nΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ°). Π Π°Π·Π²ΠΈΠ΅Π½ ΠΎΠ΄ ΠΈΠ½ΠΆΠ΅Π½Π΅Ρ€ΠΈ Π½Π° ΠΊΠ΅Ρ€Π½Π΅Π»-ΠΌΡ€Π΅ΠΆΠ½ΠΈ ΠΊΠ°ΠΊΠΎ ΠΏΠΎΠ΄ΠΎΠ±Ρ€Π΅Π½Π° Π·Π°ΠΌΠ΅Π½Π° Π·Π° класичниот BPF, Π½ΠΎΠ²ΠΈΠΎΡ‚ BPF Π±ΡƒΠΊΠ²Π°Π»Π½ΠΎ ΡˆΠ΅ΡΡ‚ мСсСци ΠΏΠΎΠ΄ΠΎΡ†Π½Π° најдС Π°ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΠΈ Π²ΠΎ Ρ‚Π΅ΡˆΠΊΠ°Ρ‚Π° Π·Π°Π΄Π°Ρ‡Π° Π΄Π° Π³ΠΈ слСди систСмитС Π½Π° Linux, Π° сСга, ΡˆΠ΅ΡΡ‚ Π³ΠΎΠ΄ΠΈΠ½ΠΈ ΠΏΠΎ Π½Π΅Π³ΠΎΠ²ΠΎΡ‚ΠΎ ΠΏΠΎΡ˜Π°Π²ΡƒΠ²Π°ΡšΠ΅, ќС Π½ΠΈ Ρ‚Ρ€Π΅Π±Π° Ρ†Π΅Π»Π° слСдна ΡΡ‚Π°Ρ‚ΠΈΡ˜Π° само Π·Π° Π½Π°Π²Π΅Π΄Π΅Ρ‚Π΅ Π³ΠΈ Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈΡ‚Π΅ Ρ‚ΠΈΠΏΠΎΠ²ΠΈ Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ.

БмСшни слики

Π’ΠΎ Π½Π΅Π³ΠΎΠ²ΠΎΡ‚ΠΎ Ρ˜Π°Π΄Ρ€ΠΎ, BPF Π΅ Π²ΠΈΡ€Ρ‚ΡƒΠ΅Π»Π½Π° машина со пСсок, која Π²ΠΈ ΠΎΠ²ΠΎΠ·ΠΌΠΎΠΆΡƒΠ²Π° Π΄Π° ΠΈΠ·Π²Ρ€ΡˆΠΈΡ‚Π΅ β€žΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»Π΅Π½β€œ ΠΊΠΎΠ΄ Π²ΠΎ просторот Π½Π° Ρ˜Π°Π΄Ρ€ΠΎΡ‚ΠΎ Π±Π΅Π· Π΄Π° ја Π·Π°Π³Ρ€ΠΎΠ·ΠΈΡ‚Π΅ бСзбСдноста. ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ BPF сС ΠΊΡ€Π΅ΠΈΡ€Π°Π°Ρ‚ Π²ΠΎ кориснички простор, сС Π²Ρ‡ΠΈΡ‚ΡƒΠ²Π°Π°Ρ‚ Π²ΠΎ ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚ ΠΈ сС ΠΏΠΎΠ²Ρ€Π·Π°Π½ΠΈ со нСкој ΠΈΠ·Π²ΠΎΡ€ Π½Π° настани. Настан ΠΌΠΎΠΆΠ΅ Π΄Π° Π±ΠΈΠ΄Π΅, Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€, испорака Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚ Π΄ΠΎ ΠΌΡ€Π΅ΠΆΠ΅Π½ ΠΈΠ½Ρ‚Π΅Ρ€Ρ„Π΅Ρ˜Ρ, Π»Π°Π½ΡΠΈΡ€Π°ΡšΠ΅ Π½Π° нСкоја Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡ˜Π° Π½Π° Ρ˜Π°Π΄Ρ€ΠΎΡ‚ΠΎ ΠΈΡ‚Π½. Π’ΠΎ ΡΠ»ΡƒΡ‡Π°Ρ˜ Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚, ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° BPF ќС ΠΈΠΌΠ° пристап Π΄ΠΎ ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈΡ‚Π΅ ΠΈ ΠΌΠ΅Ρ‚Π°ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈΡ‚Π΅ Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΡ‚ (Π·Π° Ρ‡ΠΈΡ‚Π°ΡšΠ΅ ΠΈ, ΠΌΠΎΠΆΠ΅Π±ΠΈ, ΠΏΠΈΡˆΡƒΠ²Π°ΡšΠ΅, Π²ΠΎ зависност ΠΎΠ΄ Ρ‚ΠΈΠΏΠΎΡ‚ Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π°); Π²ΠΎ ΡΠ»ΡƒΡ‡Π°Ρ˜ Π½Π° ΠΈΠ·Π²Ρ€ΡˆΡƒΠ²Π°ΡšΠ΅ Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡ˜Π°Ρ‚Π° Π½Π° Ρ˜Π°Π΄Ρ€ΠΎΡ‚ΠΎ, Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΈΡ‚Π΅ Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡ˜Π°Ρ‚Π°, Π²ΠΊΠ»ΡƒΡ‡ΡƒΠ²Π°Ρ˜ΡœΠΈ ΠΏΠΎΠΊΠ°ΠΆΡƒΠ²Π°Ρ‡ΠΈ ΠΊΠΎΠ½ ΠΌΠ΅ΠΌΠΎΡ€ΠΈΡ˜Π°Ρ‚Π° Π½Π° Ρ˜Π°Π΄Ρ€ΠΎΡ‚ΠΎ, ΠΈΡ‚Π½.

АјдС Π²Π½ΠΈΠΌΠ°Ρ‚Π΅Π»Π½ΠΎ Π΄Π° Π³ΠΎ Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ овој процСс. Π—Π° ΠΏΠΎΡ‡Π΅Ρ‚ΠΎΠΊ, ајдС Π΄Π° Π·Π±ΠΎΡ€ΡƒΠ²Π°ΠΌΠ΅ Π·Π° ΠΏΡ€Π²Π°Ρ‚Π° Ρ€Π°Π·Π»ΠΈΠΊΠ° ΠΎΠ΄ класичниот BPF, ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ Π·Π° ΠΊΠΎΠΈ Π±Π΅Π° напишани Π²ΠΎ асСмблСр. Π’ΠΎ Π½ΠΎΠ²Π°Ρ‚Π° Π²Π΅Ρ€Π·ΠΈΡ˜Π°, Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°Ρ‚Π° бСшС ΠΏΡ€ΠΎΡˆΠΈΡ€Π΅Π½Π° Ρ‚Π°ΠΊΠ° ΡˆΡ‚ΠΎ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ ΠΌΠΎΠΆΠ΅ Π΄Π° сС ΠΏΠΈΡˆΡƒΠ²Π°Π°Ρ‚ Π½Π° Ρ˜Π°Π·ΠΈΡ†ΠΈ Π½Π° високо Π½ΠΈΠ²ΠΎ, првСнствСно, сС Ρ€Π°Π·Π±ΠΈΡ€Π°, Π²ΠΎ C. Π—Π° ΠΎΠ²Π°, бСшС Ρ€Π°Π·Π²ΠΈΠ΅Π½ Π±Π΅ΠΊΠ΅Π½Π΄ Π·Π° llvm, кој ΠΎΠ²ΠΎΠ·ΠΌΠΎΠΆΡƒΠ²Π° Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π°ΡšΠ΅ Π±Π°Ρ˜Ρ‚Π΅ΠΊΠΎΠ΄ Π·Π° Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°Ρ‚Π° BPF.

BPF Π·Π° Π½Π°Ρ˜ΠΌΠ°Π»ΠΈΡ‚Π΅, ΠΏΡ€Π² Π΄Π΅Π»: ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ΅Π½ BPF

АрхитСктурата BPF бСшС Π΄ΠΈΠ·Π°Ρ˜Π½ΠΈΡ€Π°Π½Π°, Π΄Π΅Π»ΡƒΠΌΠ½ΠΎ, Π΄Π° Ρ€Π°Π±ΠΎΡ‚ΠΈ Сфикасно Π½Π° соврСмСни машини. Π—Π° Π΄Π° ΠΌΠΎΠΆΠ΅ ΠΎΠ²Π° Π΄Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½ΠΈΡ€Π° Π²ΠΎ пракса, BPF Π±Π°Ρ˜Ρ‚Π΅ΠΊΠΎΠ΄ΠΎΡ‚, ΠΎΡ‚ΠΊΠ°ΠΊΠΎ ќС сС Π²Ρ‡ΠΈΡ‚Π° Π²ΠΎ ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚, сС ΠΏΡ€Π΅Π²Π΅Π΄ΡƒΠ²Π° Π²ΠΎ ΠΌΠ°Ρ˜Ρ‡ΠΈΠ½ ΠΊΠΎΠ΄ ΠΊΠΎΡ€ΠΈΡΡ‚Π΅Ρ˜ΡœΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° Π½Π°Ρ€Π΅Ρ‡Π΅Π½Π° JIT ΠΊΠΎΠΌΠΏΠ°Ρ˜Π»Π΅Ρ€ (Jуста In TΠ²Ρ€Π΅ΠΌΠ΅). Π‘Π»Π΅Π΄Π½ΠΎ, Π°ΠΊΠΎ сС ΡΠ΅ΡœΠ°Π²Π°Ρ‚Π΅, Π²ΠΎ класичниот BPF ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° бСшС Π²Ρ‡ΠΈΡ‚Π°Π½Π° Π²ΠΎ ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚ ΠΈ ΠΏΡ€ΠΈΠΊΠ°Ρ‡Π΅Π½Π° Π½Π° ΠΈΠ·Π²ΠΎΡ€ΠΎΡ‚ Π½Π° настанот атомски - Π²ΠΎ контСкст Π½Π° Π΅Π΄Π΅Π½ систСмски ΠΏΠΎΠ²ΠΈΠΊ. Π’ΠΎ Π½ΠΎΠ²Π°Ρ‚Π° Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°, ΠΎΠ²Π° сС случува Π²ΠΎ Π΄Π²Π΅ Ρ„Π°Π·ΠΈ - ΠΏΡ€Π²ΠΎ, ΠΊΠΎΠ΄ΠΎΡ‚ сС Π²Ρ‡ΠΈΡ‚ΡƒΠ²Π° Π²ΠΎ ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚ со помош Π½Π° систСмски ΠΏΠΎΠ²ΠΈΠΊ bpf(2)Π° ΠΏΠΎΡ‚ΠΎΠ°, ΠΏΠΎΠ΄ΠΎΡ†Π½Π°, ΠΏΡ€Π΅ΠΊΡƒ Π΄Ρ€ΡƒΠ³ΠΈ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠΈ ΠΊΠΎΠΈ Π²Π°Ρ€ΠΈΡ€Π°Π°Ρ‚ Π²ΠΎ зависност ΠΎΠ΄ Π²ΠΈΠ΄ΠΎΡ‚ Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π°, ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° сС ΠΏΡ€ΠΈΠΊΠ°Ρ‡ΡƒΠ²Π° Π½Π° ΠΈΠ·Π²ΠΎΡ€ΠΎΡ‚ Π½Π° настанот.

ОвдС Ρ‡ΠΈΡ‚Π°Ρ‚Π΅Π»ΠΎΡ‚ ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΈΠΌΠ° ΠΏΡ€Π°ΡˆΠ°ΡšΠ΅: Π΄Π°Π»ΠΈ бСшС ΠΌΠΎΠΆΠ½ΠΎ? Како сС Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€Π° бСзбСдноста Π½Π° ΠΈΠ·Π²Ρ€ΡˆΡƒΠ²Π°ΡšΠ΅Ρ‚ΠΎ Π½Π° Ρ‚Π°ΠΊΠΎΠ² ΠΊΠΎΠ΄? БСзбСдноста Π½Π° ΠΈΠ·Π²Ρ€ΡˆΡƒΠ²Π°ΡšΠ΅Ρ‚ΠΎ Π½ΠΈ Π΅ Π·Π°Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€Π°Π½Π° со Ρ„Π°Π·Π°Ρ‚Π° Π½Π° Π²Ρ‡ΠΈΡ‚ΡƒΠ²Π°ΡšΠ΅ Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ BPF Π½Π°Ρ€Π΅Ρ‡Π΅Π½Π° ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡƒΠ²Π°Ρ‡ (Π½Π° англиски ΠΎΠ²Π°Π° Ρ„Π°Π·Π° сС Π½Π°Ρ€Π΅ΠΊΡƒΠ²Π° ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡƒΠ²Π°Ρ‡ ΠΈ јас ќС ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ°ΠΌ Π΄Π° Π³ΠΎ користам англискиот Π·Π±ΠΎΡ€):

BPF Π·Π° Π½Π°Ρ˜ΠΌΠ°Π»ΠΈΡ‚Π΅, ΠΏΡ€Π² Π΄Π΅Π»: ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ΅Π½ BPF

ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡƒΠ²Π°Ρ‡ΠΎΡ‚ Π΅ статичСн Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€ кој осигурува Π΄Π΅ΠΊΠ° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° Π½Π΅ Π³ΠΎ Π½Π°Ρ€ΡƒΡˆΡƒΠ²Π° Π½ΠΎΡ€ΠΌΠ°Π»Π½ΠΎΡ‚ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½ΠΈΡ€Π°ΡšΠ΅ Π½Π° ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚. Ова, ΠΏΠ°Ρ‚Π΅ΠΌ, Π½Π΅ Π·Π½Π°Ρ‡ΠΈ Π΄Π΅ΠΊΠ° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° Π½Π΅ ΠΌΠΎΠΆΠ΅ Π΄Π° сС мСша Π²ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚Π° Π½Π° систСмот - ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ BPF, Π²ΠΎ зависност ΠΎΠ΄ Π²ΠΈΠ΄ΠΎΡ‚, ΠΌΠΎΠΆΠ°Ρ‚ Π΄Π° Ρ‡ΠΈΡ‚Π°Π°Ρ‚ ΠΈ ΠΏΡ€Π΅ΠΏΠΈΡˆΡƒΠ²Π°Π°Ρ‚ Π΄Π΅Π»ΠΎΠ²ΠΈ ΠΎΠ΄ ΠΌΠ΅ΠΌΠΎΡ€ΠΈΡ˜Π°Ρ‚Π° Π½Π° Ρ˜Π°Π΄Ρ€ΠΎΡ‚ΠΎ, Π΄Π° Π²Ρ€Π°ΡœΠ°Π°Ρ‚ врСдности Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Π΄Π° скратуваат, Π΄ΠΎΠ΄Π°Π²Π°Π°Ρ‚, ΠΏΡ€Π΅ΠΏΠΈΡˆΡƒΠ²Π°Π°Ρ‚ ΠΏΠ° Π΄ΡƒΡ€ΠΈ ΠΈ ΠΏΡ€Π΅ΠΏΡ€Π°ΡœΠ°ΡšΠ΅ ΠΌΡ€Π΅ΠΆΠ½ΠΈ ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ. Π’Π΅Ρ€ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ΠΎΡ‚ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€Π° Π΄Π΅ΠΊΠ° ΠΈΠ·Π²Ρ€ΡˆΡƒΠ²Π°ΡšΠ΅Ρ‚ΠΎ Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° BPF Π½Π΅ΠΌΠ° Π΄Π° Π³ΠΎ ΡΡ€ΡƒΡˆΠΈ ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚ ΠΈ Π΄Π΅ΠΊΠ° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° ΡˆΡ‚ΠΎ, спорСд ΠΏΡ€Π°Π²ΠΈΠ»Π°Ρ‚Π°, ΠΈΠΌΠ° пристап Π·Π° Π·Π°ΠΏΠΈΡˆΡƒΠ²Π°ΡšΠ΅, Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈΡ‚Π΅ Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΡ‚ ΡˆΡ‚ΠΎ ΠΎΠ΄ΠΈ, Π½Π΅ΠΌΠ° Π΄Π° ΠΌΠΎΠΆΠ΅ Π΄Π° ја ΠΏΡ€Π΅Π·Π°ΠΏΠΈΡˆΠ΅ ΠΌΠ΅ΠΌΠΎΡ€ΠΈΡ˜Π°Ρ‚Π° Π½Π° ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚ Π½Π°Π΄Π²ΠΎΡ€ ΠΎΠ΄ ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΡ‚. ЌС Π³ΠΎ Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ Π²Π΅Ρ€ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ΠΎΡ‚ ΠΌΠ°Π»ΠΊΡƒ ΠΏΠΎΠ΄Π΅Ρ‚Π°Π»Π½ΠΎ Π²ΠΎ соодвСтниот Π΄Π΅Π», ΠΎΡ‚ΠΊΠ°ΠΊΠΎ ќС сС Π·Π°ΠΏΠΎΠ·Π½Π°Π΅ΠΌΠ΅ со ситС Π΄Ρ€ΡƒΠ³ΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΈ Π½Π° BPF.

Π—Π½Π°Ρ‡ΠΈ, ΡˆΡ‚ΠΎ Π½Π°ΡƒΡ‡ΠΈΠ²ΠΌΠ΅ досСга? ΠšΠΎΡ€ΠΈΡΠ½ΠΈΠΊΠΎΡ‚ ΠΏΠΈΡˆΡƒΠ²Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° Π²ΠΎ C, ја Π²Ρ‡ΠΈΡ‚ΡƒΠ²Π° Π²ΠΎ ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚ ΠΊΠΎΡ€ΠΈΡΡ‚Π΅Ρ˜ΡœΠΈ систСмски ΠΏΠΎΠ²ΠΈΠΊ bpf(2), ΠΊΠ°Π΄Π΅ ΡˆΡ‚ΠΎ сС ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡƒΠ²Π° ΠΎΠ΄ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡƒΠ²Π°Ρ‡ ΠΈ сС ΠΏΡ€Π΅Π²Π΅Π΄ΡƒΠ²Π° Π½Π° ΠΌΠ°Ρ˜Ρ‡ΠΈΠ½ Π±Π°Ρ˜Ρ‚Π΅ΠΊΠΎΠ΄. ΠŸΠΎΡ‚ΠΎΠ° истиот ΠΈΠ»ΠΈ Π΄Ρ€ΡƒΠ³ корисник ја ΠΏΠΎΠ²Ρ€Π·ΡƒΠ²Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° со ΠΈΠ·Π²ΠΎΡ€ΠΎΡ‚ Π½Π° настанот ΠΈ Ρ‚Π°Π° Π·Π°ΠΏΠΎΡ‡Π½ΡƒΠ²Π° Π΄Π° сС ΠΈΠ·Π²Ρ€ΡˆΡƒΠ²Π°. ΠžΠ΄Π²ΠΎΡ˜ΡƒΠ²Π°ΡšΠ΅Ρ‚ΠΎ Π½Π° Π±Π°Π³Π°ΠΆΠ½ΠΈΠΊΠΎΡ‚ ΠΈ ΠΏΠΎΠ²Ρ€Π·ΡƒΠ²Π°ΡšΠ΅Ρ‚ΠΎ Π΅ Π½Π΅ΠΎΠΏΡ…ΠΎΠ΄Π½ΠΎ ΠΎΠ΄ Π½Π΅ΠΊΠΎΠ»ΠΊΡƒ ΠΏΡ€ΠΈΡ‡ΠΈΠ½ΠΈ. ΠŸΡ€Π²ΠΎ, водСњС Π½Π° ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡƒΠ²Π°Ρ‡ Π΅ Ρ€Π΅Π»Π°Ρ‚ΠΈΠ²Π½ΠΎ скапо ΠΈ со ΠΏΡ€Π΅Π·Π΅ΠΌΠ°ΡšΠ΅ Π½Π° истата ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° Π½Π΅ΠΊΠΎΠ»ΠΊΡƒ ΠΏΠ°Ρ‚ΠΈ Π³ΡƒΠ±ΠΈΠΌΠ΅ Π²Ρ€Π΅ΠΌΠ΅ Π½Π° ΠΊΠΎΠΌΠΏΡ˜ΡƒΡ‚Π΅Ρ€ΠΎΡ‚. Π’Ρ‚ΠΎΡ€ΠΎ, Ρ‚ΠΎΡ‡Π½ΠΎ ΠΊΠ°ΠΊΠΎ Π΅ ΠΏΠΎΠ²Ρ€Π·Π°Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° зависи ΠΎΠ΄ Π½Π΅Ρ˜Π·ΠΈΠ½ΠΈΠΎΡ‚ Ρ‚ΠΈΠΏ, Π° Π΅Π΄Π΅Π½ β€žΡƒΠ½ΠΈΠ²Π΅Ρ€Π·Π°Π»Π΅Π½β€œ ΠΈΠ½Ρ‚Π΅Ρ€Ρ„Π΅Ρ˜Ρ Ρ€Π°Π·Π²ΠΈΠ΅Π½ ΠΏΡ€Π΅Π΄ Π΅Π΄Π½Π° Π³ΠΎΠ΄ΠΈΠ½Π° ΠΌΠΎΠΆΠ΅Π±ΠΈ Π½Π΅ Π΅ ΠΏΠΎΠ³ΠΎΠ΄Π΅Π½ Π·Π° Π½ΠΎΠ²ΠΈ Ρ‚ΠΈΠΏΠΎΠ²ΠΈ Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ. (Иако сСга ΠΊΠΎΠ³Π° Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°Ρ‚Π° станува ΠΏΠΎΠ·Ρ€Π΅Π»Π°, постои идСја Π΄Π° сС ΠΎΠ±Π΅Π΄ΠΈΠ½ΠΈ овој ΠΈΠ½Ρ‚Π΅Ρ€Ρ„Π΅Ρ˜Ρ Π½Π° Π½ΠΈΠ²ΠΎ libbpf.)

Π’Π½ΠΈΠΌΠ°Ρ‚Π΅Π»Π½ΠΈΠΎΡ‚ Ρ‡ΠΈΡ‚Π°Ρ‚Π΅Π» ΠΌΠΎΠΆΠ΅ Π΄Π° Π·Π°Π±Π΅Π»Π΅ΠΆΠΈ Π΄Π΅ΠΊΠ° сè ΡƒΡˆΡ‚Π΅ Π½Π΅ смС Π·Π°Π²Ρ€ΡˆΠΈΠ»Π΅ со сликитС. Навистина, сСто Π³ΠΎΡ€Π΅Π½Π°Π²Π΅Π΄Π΅Π½ΠΎ Π½Π΅ ΠΎΠ±Ρ˜Π°ΡΠ½ΡƒΠ²Π° Π·ΠΎΡˆΡ‚ΠΎ BPF Ρ„ΡƒΠ½Π΄Π°ΠΌΠ΅Π½Ρ‚Π°Π»Π½ΠΎ ја ΠΌΠ΅Π½ΡƒΠ²Π° сликата Π²ΠΎ спорСдба со класичниот BPF. Π”Π²Π΅ ΠΈΠ½ΠΎΠ²Π°Ρ†ΠΈΠΈ ΠΊΠΎΠΈ Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»Π½ΠΎ Π³ΠΎ ΠΏΡ€ΠΎΡˆΠΈΡ€ΡƒΠ²Π°Π°Ρ‚ опсСгот Π½Π° примСнливост сС моТноста Π·Π° ΠΊΠΎΡ€ΠΈΡΡ‚Π΅ΡšΠ΅ Π½Π° сподСлСна ΠΌΠ΅ΠΌΠΎΡ€ΠΈΡ˜Π° ΠΈ помошни Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π½Π° ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚. Π’ΠΎ BPF, сподСлСната ΠΌΠ΅ΠΌΠΎΡ€ΠΈΡ˜Π° сС ΠΈΠΌΠΏΠ»Π΅ΠΌΠ΅Π½Ρ‚ΠΈΡ€Π° со ΠΊΠΎΡ€ΠΈΡΡ‚Π΅ΡšΠ΅ Π½Π° Ρ‚Π°ΠΊΠ°Π½Π°Ρ€Π΅Ρ‡Π΅Π½ΠΈΡ‚Π΅ ΠΌΠ°ΠΏΠΈ - сподСлСни структури Π½Π° ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈ со спСцифичСн API. Π’Π΅Ρ€ΠΎΡ˜Π°Ρ‚Π½ΠΎ Π³ΠΎ Π΄ΠΎΠ±ΠΈΠ»Π΅ ΠΎΠ²Π° ΠΈΠΌΠ΅ Π·Π°Ρ‚ΠΎΠ° ΡˆΡ‚ΠΎ ΠΏΡ€Π²ΠΈΠΎΡ‚ Ρ‚ΠΈΠΏ Π½Π° ΠΌΠ°ΠΏΠ° ΡˆΡ‚ΠΎ сС појавил Π΅ Ρ…Π΅Ρˆ-Ρ‚Π°Π±Π΅Π»Π°. ΠŸΠΎΡ‚ΠΎΠ° сС појавија Π½ΠΈΠ·ΠΈ, Π»ΠΎΠΊΠ°Π»Π½ΠΈ (ΠΏΠΎ процСсорски) Ρ…Π°Ρˆ Ρ‚Π°Π±Π΅Π»ΠΈ ΠΈ Π»ΠΎΠΊΠ°Π»Π½ΠΈ Π½ΠΈΠ·ΠΈ, стСбла Π·Π° ΠΏΡ€Π΅Π±Π°Ρ€ΡƒΠ²Π°ΡšΠ΅, ΠΌΠ°ΠΏΠΈ ΠΊΠΎΠΈ содрТат ΠΏΠΎΠΊΠ°ΠΆΡƒΠ²Π°Ρ‡ΠΈ ΠΊΠΎΠ½ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ BPF ΠΈ ΠΌΠ½ΠΎΠ³Ρƒ повСќС. Она ΡˆΡ‚ΠΎ Π½ΠΈ Π΅ интСрСсно сСга Π΅ Π΄Π΅ΠΊΠ° BPF ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ сСга ΠΈΠΌΠ°Π°Ρ‚ моТност Π΄Π° ја ΠΎΠΏΡΡ‚ΠΎΡ˜ΡƒΠ²Π°Π°Ρ‚ ΡΠΎΡΡ‚ΠΎΡ˜Π±Π°Ρ‚Π° ΠΏΠΎΠΌΠ΅Ρ“Ρƒ ΠΏΠΎΠ²ΠΈΡ†ΠΈΡ‚Π΅ ΠΈ Π΄Π° ја сподСлуваат со Π΄Ρ€ΡƒΠ³ΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ ΠΈ со корисничкиот простор.

Π”ΠΎ ΠΌΠ°ΠΏΠΈ сС пристапува ΠΎΠ΄ кориснички процСси ΠΊΠΎΡ€ΠΈΡΡ‚Π΅Ρ˜ΡœΠΈ систСмски ΠΏΠΎΠ²ΠΈΠΊ bpf(2), ΠΈ ΠΎΠ΄ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ BPF ΠΊΠΎΠΈ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ Π²ΠΎ Ρ˜Π°Π΄Ρ€ΠΎΡ‚ΠΎ ΠΊΠΎΡ€ΠΈΡΡ‚Π΅Ρ˜ΡœΠΈ помошни Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ. ΠŸΠΎΠΊΡ€Π°Ρ˜ Ρ‚ΠΎΠ°, ΠΏΠΎΠΌΠΎΡˆΠ½ΠΈΡ†ΠΈΡ‚Π΅ ΠΏΠΎΡΡ‚ΠΎΡ˜Π°Ρ‚ Π½Π΅ само Π·Π° Ρ€Π°Π±ΠΎΡ‚Π° со ΠΌΠ°ΠΏΠΈ, Ρ‚ΡƒΠΊΡƒ ΠΈ Π·Π° пристап Π΄ΠΎ Π΄Ρ€ΡƒΠ³ΠΈ способности Π½Π° ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚. На ΠΏΡ€ΠΈΠΌΠ΅Ρ€, BPF ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ ΠΌΠΎΠΆΠ°Ρ‚ Π΄Π° користат помошни Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π·Π° ΠΏΡ€Π΅ΠΏΡ€Π°ΡœΠ°ΡšΠ΅ ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ Π΄ΠΎ Π΄Ρ€ΡƒΠ³ΠΈ ΠΈΠ½Ρ‚Π΅Ρ€Ρ„Π΅Ρ˜ΡΠΈ, Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π°ΡšΠ΅ Π½Π° настани Π½Π° perf, пристап Π΄ΠΎ структуритС Π½Π° Ρ˜Π°Π΄Ρ€ΠΎΡ‚ΠΎ ΠΈΡ‚Π½.

BPF Π·Π° Π½Π°Ρ˜ΠΌΠ°Π»ΠΈΡ‚Π΅, ΠΏΡ€Π² Π΄Π΅Π»: ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ΅Π½ BPF

Накратко, BPF ΠΎΠ±Π΅Π·Π±Π΅Π΄ΡƒΠ²Π° моТност Π·Π° Π²Ρ‡ΠΈΡ‚ΡƒΠ²Π°ΡšΠ΅ Π½Π° ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»Π΅Π½, Ρ‚.Π΅., тСстиран ΠΎΠ΄ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡƒΠ²Π°Ρ‡, кориснички ΠΊΠΎΠ΄ Π²ΠΎ просторот Π½Π° Ρ˜Π°Π΄Ρ€ΠΎΡ‚ΠΎ. Овој ΠΊΠΎΠ΄ ΠΌΠΎΠΆΠ΅ Π΄Π° ја Π·Π°Ρ‡ΡƒΠ²Π° ΡΠΎΡΡ‚ΠΎΡ˜Π±Π°Ρ‚Π° ΠΏΠΎΠΌΠ΅Ρ“Ρƒ ΠΏΠΎΠ²ΠΈΡ†ΠΈΡ‚Π΅ ΠΈ Π΄Π° Ρ€Π°Π·ΠΌΠ΅Π½ΡƒΠ²Π° ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈ со корисничкиот простор, Π° исто Ρ‚Π°ΠΊΠ° ΠΈΠΌΠ° пристап Π΄ΠΎ потсистСми Π½Π° Ρ˜Π°Π΄Ρ€ΠΎΡ‚ΠΎ Π΄ΠΎΠ·Π²ΠΎΠ»Π΅Π½ΠΈ ΠΎΠ΄ овој Ρ‚ΠΈΠΏ Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°.

Ова Π΅ вСќС слично Π½Π° моТноститС ΡˆΡ‚ΠΎ Π³ΠΈ ΠΎΠ±Π΅Π·Π±Π΅Π΄ΡƒΠ²Π°Π°Ρ‚ ΠΌΠΎΠ΄ΡƒΠ»ΠΈΡ‚Π΅ Π½Π° Ρ˜Π°Π΄Ρ€ΠΎΡ‚ΠΎ, Π²ΠΎ спорСдба со ΠΊΠΎΠΈ BPF ΠΈΠΌΠ° Π½Π΅ΠΊΠΎΠΈ прСдности (сС Ρ€Π°Π·Π±ΠΈΡ€Π°, ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° спорСдуватС само слични Π°ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΠΈ, Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€, систСмско слСдСњС - Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Π½Π°ΠΏΠΈΡˆΠ΅Ρ‚Π΅ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»Π΅Π½ Π΄Π²ΠΈΠ³Π°Ρ‚Π΅Π» со BPF). МоТС Π΄Π° Π·Π°Π±Π΅Π»Π΅ΠΆΠΈΡ‚Π΅ ΠΏΠΎΠΌΠ°Π» ΠΏΡ€Π°Π³ Π·Π° Π²Π»Π΅Π· (Π½Π΅ΠΊΠΎΠΈ услуТни ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ ΠΊΠΎΠΈ користат BPF Π½Π΅ Π±Π°Ρ€Π°Π°Ρ‚ ΠΎΠ΄ корисникот Π΄Π° ΠΈΠΌΠ° Π²Π΅ΡˆΡ‚ΠΈΠ½ΠΈ Π·Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ€Π°ΡšΠ΅ Π½Π° Ρ˜Π°Π΄Ρ€ΠΎΡ‚ΠΎ, ΠΈΠ»ΠΈ ΠΎΠΏΡˆΡ‚ΠΎ програмски Π²Π΅ΡˆΡ‚ΠΈΠ½ΠΈ), бСзбСдност ΠΏΡ€ΠΈ ΠΈΠ·Π²Ρ€ΡˆΡƒΠ²Π°ΡšΠ΅ (ΠΊΡ€Π΅Π½Π΅Ρ‚Π΅ ја Ρ€Π°ΠΊΠ°Ρ‚Π° Π²ΠΎ ΠΊΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΡ‚Π΅ Π·Π° ΠΎΠ½ΠΈΠ΅ ΠΊΠΎΠΈ Π½Π΅ Π³ΠΎ ΡΠΊΡ€ΡˆΠΈΠ»Π΅ систСмот ΠΊΠΎΠ³Π° ΠΏΠΈΡˆΡƒΠ²Π°Π»Π΅ ΠΈΠ»ΠΈ ΠΌΠΎΠ΄ΡƒΠ»ΠΈ Π·Π° Ρ‚Π΅ΡΡ‚ΠΈΡ€Π°ΡšΠ΅), атомност - ΠΈΠΌΠ° ΠΏΡ€Π΅ΠΊΠΈΠ½ΠΈ ΠΏΡ€ΠΈ ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎ Π²Ρ‡ΠΈΡ‚ΡƒΠ²Π°ΡšΠ΅ Π½Π° ΠΌΠΎΠ΄ΡƒΠ»ΠΈΡ‚Π΅, Π° потсистСмот BPF осигурува Π΄Π΅ΠΊΠ° Π½ΠΈΡ‚Ρƒ Π΅Π΄Π΅Π½ настан Π½Π΅ Π΅ ΠΏΡ€ΠΎΠΏΡƒΡˆΡ‚Π΅Π½ (Π΄Π° Π±ΠΈΠ΄Π΅ΠΌΠ΅ Ρ„Π΅Ρ€, ΠΎΠ²Π° Π½Π΅ Π²Π°ΠΆΠΈ Π·Π° ситС Ρ‚ΠΈΠΏΠΎΠ²ΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ BPF).

ΠŸΡ€ΠΈΡΡƒΡΡ‚Π²ΠΎΡ‚ΠΎ Π½Π° Ρ‚Π°ΠΊΠ²ΠΈ способности Π³ΠΎ ΠΏΡ€Π°Π²ΠΈ BPF ΡƒΠ½ΠΈΠ²Π΅Ρ€Π·Π°Π»Π½Π° Π°Π»Π°Ρ‚ΠΊΠ° Π·Π° ΠΏΡ€ΠΎΡˆΠΈΡ€ΡƒΠ²Π°ΡšΠ΅ Π½Π° ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚, ΡˆΡ‚ΠΎ сС ΠΏΠΎΡ‚Π²Ρ€Π΄ΡƒΠ²Π° ΠΈ Π²ΠΎ пракса: сС повСќС ΠΈ повСќС Π½ΠΎΠ²ΠΈ Π²ΠΈΠ΄ΠΎΠ²ΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ сС Π΄ΠΎΠ΄Π°Π²Π°Π°Ρ‚ Π²ΠΎ 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 (Π·Π° XDP) ΠΈΠ»ΠΈ структура struct __sk_buff (Π·Π° Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ ΠΌΡ€Π΅ΠΆΠ½ΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ) ΠΈΠ»ΠΈ структура struct pt_regs (Π·Π° Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ Π²ΠΈΠ΄ΠΎΠ²ΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ Π·Π° слСдСњС) ΠΈΡ‚Π½.

Π—Π½Π°Ρ‡ΠΈ, ΠΈΠΌΠ°Π²ΠΌΠ΅ сСт Π½Π° рСгистри, ΠΏΠΎΠΌΠΎΡˆΠ½ΠΈΡ†ΠΈ Π½Π° ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚, стСк, контСкстуалСн ΠΏΠΎΠΊΠ°ΠΆΡƒΠ²Π°Ρ‡ ΠΈ сподСлСна ΠΌΠ΅ΠΌΠΎΡ€ΠΈΡ˜Π° Π²ΠΎ Ρ„ΠΎΡ€ΠΌΠ° Π½Π° ΠΌΠ°ΠΏΠΈ. НС Π΄Π΅ΠΊΠ° сСто Ρ‚ΠΎΠ° Π΅ апсолутно Π½Π΅ΠΎΠΏΡ…ΠΎΠ΄Π½ΠΎ Π½Π° ΠΏΠ°Ρ‚ΡƒΠ²Π°ΡšΠ΅Ρ‚ΠΎ, Π½ΠΎ...

АјдС Π΄Π° Π³ΠΎ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠΈΠΌΠ΅ описот ΠΈ Π΄Π° Ρ€Π°Π·Π³ΠΎΠ²Π°Ρ€Π°ΠΌΠ΅ Π·Π° ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΈΠΎΡ‚ систСм Π·Π° Ρ€Π°Π±ΠΎΡ‚Π° со ΠΎΠ²ΠΈΠ΅ ΠΎΠ±Ρ˜Π΅ΠΊΡ‚ΠΈ. Π‘ΠΈΡ‚Π΅ (РСчиси ситС) Π˜Π½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΠΈΡ‚Π΅ Π·Π° BPF ΠΈΠΌΠ°Π°Ρ‚ фиксна 64-Π±ΠΈΡ‚Π½Π° Π³ΠΎΠ»Π΅ΠΌΠΈΠ½Π°. Ако ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅Ρ‚Π΅ Π΅Π΄Π½Π° ΠΈΠ½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡ˜Π° Π½Π° 64-Π±ΠΈΡ‚Π½Π° Big Endian машина, ќС Π²ΠΈΠ΄ΠΈΡ‚Π΅

BPF Π·Π° Π½Π°Ρ˜ΠΌΠ°Π»ΠΈΡ‚Π΅, ΠΏΡ€Π² Π΄Π΅Π»: ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ΅Π½ BPF

Π’ΡƒΠΊΠ° Code - ΠΎΠ²Π° Π΅ ΠΊΠΎΠ΄ΠΈΡ€Π°ΡšΠ΅ Π½Π° ΠΈΠ½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡ˜Π°Ρ‚Π°, Dst/Src сС ΡˆΠΈΡ„Ρ€ΠΈΡ€Π°ΡšΠ°Ρ‚Π° Π½Π° ΠΏΡ€ΠΈΠΌΠ°Ρ‡ΠΎΡ‚ ΠΈ ΠΈΠ·Π²ΠΎΡ€ΠΎΡ‚, соодвСтно, Off - 16-Π±ΠΈΡ‚Π½Π° ΠΏΠΎΡ‚ΠΏΠΈΡˆΠ°Π½Π° Π²ΠΎΠ²Π»Π΅ΠΊΡƒΠ²Π°ΡšΠ΅ ΠΈ Imm Π΅ 32-Π±ΠΈΡ‚Π΅Π½ ΠΏΠΎΡ‚ΠΏΠΈΡˆΠ°Π½ Ρ†Π΅Π» Π±Ρ€ΠΎΡ˜ кој сС користи Π²ΠΎ Π½Π΅ΠΊΠΎΠΈ инструкции (слично Π½Π° cBPF константата K). ΠšΠΎΠ΄ΠΈΡ€Π°ΡšΠ΅ Code ΠΈΠΌΠ° Π΅Π΄Π΅Π½ ΠΎΠ΄ Π΄Π²Π°Ρ‚Π° Π²ΠΈΠ΄Π°:

BPF Π·Π° Π½Π°Ρ˜ΠΌΠ°Π»ΠΈΡ‚Π΅, ΠΏΡ€Π² Π΄Π΅Π»: ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ΅Π½ BPF

ΠšΠ»Π°ΡΠΈΡ‚Π΅ Π½Π° инструкции 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. Кога ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡ˜Π½ΠΎ ја ΠΏΡ€ΠΎΡƒΡ‡ΡƒΠ²Π°Ρ‚Π΅ Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°Ρ‚Π° ΠΈ/ΠΈΠ»ΠΈ Π°Π½Π°Π»ΠΈΠ·ΠΈΡ€Π°Ρ‚Π΅ Π±ΠΈΠ½Π°Ρ€Π½ΠΈ Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠΈ, ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Π½Π°Ρ˜Π΄Π΅Ρ‚Π΅ сСмантика Π²ΠΎ слСднитС ΠΈΠ·Π²ΠΎΡ€ΠΈ, ΠΏΠΎΠ΄Ρ€Π΅Π΄Π΅Π½ΠΈ ΠΏΠΎ слоТСност: ΠΠ΅ΠΎΡ„ΠΈΡ†ΠΈΡ˜Π°Π»Π½ΠΈ спСцификации Π·Π° eBPF, Π Π΅Ρ„Π΅Ρ€Π΅Π½Ρ‚Π΅Π½ Π²ΠΎΠ΄ΠΈΡ‡ Π·Π° BPF ΠΈ XDP, сСт Π½Π° инструкции, Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡ˜Π°/Π²ΠΌΡ€Π΅ΠΆΡƒΠ²Π°ΡšΠ΅/Ρ„ΠΈΠ»Ρ‚Π΅Ρ€.txt ΠΈ, сС Ρ€Π°Π·Π±ΠΈΡ€Π°, Π²ΠΎ ΠΈΠ·Π²ΠΎΡ€Π½ΠΈΠΎΡ‚ ΠΊΠΎΠ΄ Π½Π° Linux - Π²Π΅Ρ€ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€, JIT, BPF ΠΏΡ€Π΅Π²Π΅Π΄ΡƒΠ²Π°Ρ‡.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€: Ρ€Π°ΡΠΊΠ»ΠΎΠΏΡƒΠ²Π°ΡšΠ΅ Π½Π° BPF Π²ΠΎ Π²Π°ΡˆΠ°Ρ‚Π° Π³Π»Π°Π²Π°

АјдС Π΄Π° ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π²ΠΎ кој составувамС ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° readelf-example.c ΠΈ ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅Ρ‚Π΅ Π³ΠΎ Π΄ΠΎΠ±ΠΈΠ΅Π½ΠΈΠΎΡ‚ Π±ΠΈΠ½Π°Ρ€. ЌС ја ΠΎΡ‚ΠΊΡ€ΠΈΠ΅ΠΌΠ΅ ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»Π½Π°Ρ‚Π° содрТина readelf-example.c ΠΏΠΎΠ΄ΠΎΠ»Ρƒ, ΠΎΡ‚ΠΊΠ°ΠΊΠΎ ќС ја Π²Ρ€Π°Ρ‚ΠΈΠΌΠ΅ Π½Π΅Π³ΠΎΠ²Π°Ρ‚Π° Π»ΠΎΠ³ΠΈΠΊΠ° ΠΎΠ΄ Π±ΠΈΠ½Π°Ρ€Π½ΠΈ ΠΊΠΎΠ΄ΠΎΠ²ΠΈ:

$ clang -target bpf -c readelf-example.c -o readelf-example.o -O2
$ llvm-readelf -x .text readelf-example.o
Hex dump of section '.text':
0x00000000 b7000000 01000000 15010100 00000000 ................
0x00000010 b7000000 02000000 95000000 00000000 ................

ΠŸΡ€Π²Π° ΠΊΠΎΠ»ΠΎΠ½Π° Π½Π° ΠΈΠ·Π»Π΅Π· readelf Π΅ Π²ΠΎΠ²Π»Π΅ΠΊΡƒΠ²Π°ΡšΠ΅ ΠΈ Π·Π°Ρ‚ΠΎΠ° Π½Π°ΡˆΠ°Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° сС состои ΠΎΠ΄ Ρ‡Π΅Ρ‚ΠΈΡ€ΠΈ ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ:

Code Dst Src Off  Imm
b7   0   0   0000 01000000
15   0   1   0100 00000000
b7   0   0   0000 02000000
95   0   0   0000 00000000

ΠšΠΎΠΌΠ°Π½Π΄Π½ΠΈΡ‚Π΅ ΡˆΠΈΡ„Ρ€ΠΈ сС Π΅Π΄Π½Π°ΠΊΠ²ΠΈ b7, 15, b7 ΠΈ 95. ΠŸΠΎΡ‚ΡΠ΅Ρ‚Π΅Ρ‚Π΅ сС Π΄Π΅ΠΊΠ° Π½Π°Ρ˜ΠΌΠ°Π»ΠΊΡƒ Π·Π½Π°Ρ‡Π°Ρ˜Π½ΠΈΡ‚Π΅ Ρ‚Ρ€ΠΈ Π±ΠΈΡ‚Π° сС класата Π½Π° инструкции. Π’ΠΎ Π½Π°ΡˆΠΈΠΎΡ‚ ΡΠ»ΡƒΡ‡Π°Ρ˜, Ρ‡Π΅Ρ‚Π²Ρ€Ρ‚ΠΈΠΎΡ‚ Π±ΠΈΡ‚ ΠΎΠ΄ ситС инструкции Π΅ ΠΏΡ€Π°Π·Π΅Π½, Ρ‚Π°ΠΊΠ° ΡˆΡ‚ΠΎ класитС Π½Π° инструкции сС 7, 5, 7, 5, соодвСтно. BPF_ALU64, Π° 5 Π΅ BPF_JMP. Π—Π° Π΄Π²Π΅Ρ‚Π΅ класи, Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΎΡ‚ Π½Π° инструкциитС Π΅ ист (Π²ΠΈΠ΄ΠΈ ΠΏΠΎΠ³ΠΎΡ€Π΅) ΠΈ ΠΌΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° ја ΠΏΡ€Π΅Ρ€Π°Π±ΠΎΡ‚ΠΈΠΌΠ΅ Π½Π°ΡˆΠ°Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° Π²Π°ΠΊΠ° (Π²ΠΎ исто Π²Ρ€Π΅ΠΌΠ΅ ќС Π³ΠΈ ΠΏΡ€Π΅Ρ€Π°Π±ΠΎΡ‚ΠΈΠΌΠ΅ прСостанатитС ΠΊΠΎΠ»ΠΎΠ½ΠΈ Π²ΠΎ Ρ‡ΠΎΠ²Π΅Ρ‡ΠΊΠ° Ρ„ΠΎΡ€ΠΌΠ°):

Op S  Class   Dst Src Off  Imm
b  0  ALU64   0   0   0    1
1  0  JMP     0   1   1    0
b  0  ALU64   0   0   0    2
9  0  JMP     0   0   0    0

ΠžΠΏΠ΅Ρ€Π°Ρ†ΠΈΡ˜Π° b класа ALU64 - Π”Π°Π»ΠΈ BPF_MOV. Вој ΠΌΡƒ Π΄ΠΎΠ΄Π΅Π»ΡƒΠ²Π° врСдност Π½Π° ΠΎΠ΄Ρ€Π΅Π΄ΠΈΡˆΠ½ΠΈΠΎΡ‚ рСгистар. Ако Π±ΠΈΡ‚ΠΎΡ‚ Π΅ поставСн s (ΠΈΠ·Π²ΠΎΡ€), Ρ‚ΠΎΠ³Π°Ρˆ врСдноста сС Π·Π΅ΠΌΠ° ΠΎΠ΄ ΠΈΠ·Π²ΠΎΡ€Π½ΠΈΠΎΡ‚ рСгистар, Π° Π°ΠΊΠΎ, ΠΊΠ°ΠΊΠΎ Π²ΠΎ Π½Π°ΡˆΠΈΠΎΡ‚ ΡΠ»ΡƒΡ‡Π°Ρ˜, Π½Π΅ Π΅ поставСна, Ρ‚ΠΎΠ³Π°Ρˆ врСдноста сС Π·Π΅ΠΌΠ° ΠΎΠ΄ ΠΏΠΎΠ»Π΅Ρ‚ΠΎ Imm. Π—Π½Π°Ρ‡ΠΈ Π²ΠΎ ΠΏΡ€Π²Π°Ρ‚Π° ΠΈ Ρ‚Ρ€Π΅Ρ‚Π°Ρ‚Π° ΠΈΠ½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡ˜Π° ја ΠΈΠ·Π²Ρ€ΡˆΡƒΠ²Π°ΠΌΠ΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡ˜Π°Ρ‚Π° r0 = Imm. ΠŸΠΎΠ½Π°Ρ‚Π°ΠΌΡƒ, ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡ˜Π°Ρ‚Π° JMP класа 1 Π΅ BPF_JEQ (скок Π°ΠΊΠΎ Π΅ Π΅Π΄Π½Π°ΠΊΠΎΠ²). Π’ΠΎ Π½Π°ΡˆΠΈΠΎΡ‚ ΡΠ»ΡƒΡ‡Π°Ρ˜, ΠΎΠ΄ ΠΌΠ°Π»ΠΊΡƒ S Π΅ Π½ΡƒΠ»Π°, ја спорСдува врСдноста Π½Π° ΠΈΠ·Π²ΠΎΡ€Π½ΠΈΠΎΡ‚ рСгистар со ΠΏΠΎΠ»Π΅Ρ‚ΠΎ Imm. Ако врСдноститС сС совпаѓаат, Ρ‚ΠΎΠ³Π°Ρˆ сС случува Ρ‚Ρ€Π°Π½Π·ΠΈΡ†ΠΈΡ˜Π°Ρ‚Π° Π½Π° PC + OffΠΊΠ°Π΄Π΅ PC, ΠΊΠ°ΠΊΠΎ ΠΈ ΠΎΠ±ΠΈΡ‡Π½ΠΎ, ја содрТи адрСсата Π½Π° слСдната ΠΈΠ½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡ˜Π°. ΠšΠΎΠ½Π΅Ρ‡Π½ΠΎ, JMP Класа 9 ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡ˜Π° Π΅ BPF_EXIT. Оваа ΠΈΠ½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡ˜Π° ја ΠΏΡ€Π΅ΠΊΠΈΠ½ΡƒΠ²Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π°, Π²Ρ€Π°ΡœΠ°Ρ˜ΡœΠΈ сС Π²ΠΎ ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚ r0. АјдС Π΄Π° Π΄ΠΎΠ΄Π°Π΄Π΅ΠΌΠ΅ Π½ΠΎΠ²Π° ΠΊΠΎΠ»ΠΎΠ½Π° Π½Π° Π½Π°ΡˆΠ°Ρ‚Π° Ρ‚Π°Π±Π΅Π»Π°:

Op    S  Class   Dst Src Off  Imm    Disassm
MOV   0  ALU64   0   0   0    1      r0 = 1
JEQ   0  JMP     0   1   1    0      if (r1 == 0) goto pc+1
MOV   0  ALU64   0   0   0    2      r0 = 2
EXIT  0  JMP     0   0   0    0      exit

МоТСмС Π΄Π° Π³ΠΎ ΠΏΡ€Π΅Ρ€Π°Π±ΠΎΡ‚ΠΈΠΌΠ΅ ΠΎΠ²Π° Π²ΠΎ ΠΏΠΎΠΏΠΎΠ³ΠΎΠ΄Π½Π° Ρ„ΠΎΡ€ΠΌΠ°:

     r0 = 1
     if (r1 == 0) goto END
     r0 = 2
END:
     exit

Ако сС сСтимС ΡˆΡ‚ΠΎ ΠΈΠΌΠ° Π²ΠΎ рСгистарот r1 Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° сС прСнСсува ΠΏΠΎΠΊΠ°ΠΆΡƒΠ²Π°Ρ‡ ΠΊΠΎΠ½ контСкстот ΠΎΠ΄ ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚ ΠΈ Π²ΠΎ рСгистарот r0 врСдноста сС Π²Ρ€Π°ΡœΠ° Π²ΠΎ ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚, Ρ‚ΠΎΠ³Π°Ρˆ ΠΌΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° Π²ΠΈΠ΄ΠΈΠΌΠ΅ Π΄Π΅ΠΊΠ° Π°ΠΊΠΎ ΠΏΠΎΠΊΠ°ΠΆΡƒΠ²Π°Ρ‡ΠΎΡ‚ Π½Π° контСкстот Π΅ Π½ΡƒΠ»Π°, Ρ‚ΠΎΠ³Π°Ρˆ Π²Ρ€Π°ΡœΠ°ΠΌΠ΅ 1, Π° Π²ΠΎ спротивно - 2. АјдС Π΄Π° ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΠΌΠ΅ Π΄Π°Π»ΠΈ смС Π²ΠΎ ΠΏΡ€Π°Π²ΠΎ глСдајќи Π³ΠΎ ΠΈΠ·Π²ΠΎΡ€ΠΎΡ‚:

$ cat readelf-example.c
int foo(void *ctx)
{
        return ctx ? 2 : 1;
}

Π”Π°, Ρ‚ΠΎΠ° Π΅ бСсмислСна ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°, Π½ΠΎ сС ΠΏΡ€Π΅Π²Π΅Π΄ΡƒΠ²Π° Π²ΠΎ само Ρ‡Π΅Ρ‚ΠΈΡ€ΠΈ Сдноставни инструкции.

Π˜ΡΠΊΠ»ΡƒΡ‡ΠΎΠΊ ΠΏΡ€ΠΈΠΌΠ΅Ρ€: 16-Π±Π°Ρ˜Ρ‚Π½Π° ΠΈΠ½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡ˜Π°

ΠŸΡ€Π΅Ρ‚Ρ…ΠΎΠ΄Π½ΠΎ спомСнавмС Π΄Π΅ΠΊΠ° Π½Π΅ΠΊΠΎΠΈ инструкции Π·Π°Π·Π΅ΠΌΠ°Π°Ρ‚ повСќС ΠΎΠ΄ 64 Π±ΠΈΡ‚Π°. Ова сС однСсува, Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π·Π° инструкциитС lddw (Π¨ΠΈΡ„Ρ€Π° = 0x18 = BPF_LD | BPF_DW | BPF_IMM) β€” Π²Ρ‡ΠΈΡ‚Π°Ρ˜Ρ‚Π΅ Π΄Π²ΠΎΠ΅Π½ Π·Π±ΠΎΡ€ ΠΎΠ΄ ΠΏΠΎΠ»ΠΈΡšΠ°Ρ‚Π° Π²ΠΎ рСгистарот Imm. Π€Π°ΠΊΡ‚ Π΅ Π΄Π΅ΠΊΠ° Imm ΠΈΠΌΠ° Π³ΠΎΠ»Π΅ΠΌΠΈΠ½Π° ΠΎΠ΄ 32, Π° Π΄Π²ΠΎΠ΅Π½ Π·Π±ΠΎΡ€ Π΅ 64 Π±ΠΈΡ‚Π°, Ρ‚Π°ΠΊΠ° ΡˆΡ‚ΠΎ Π²Ρ‡ΠΈΡ‚ΡƒΠ²Π°ΡšΠ΅Ρ‚ΠΎ Π½Π° 64-Π±ΠΈΡ‚Π½Π° нСпосрСдна врСдност Π²ΠΎ рСгистарот Π²ΠΎ Π΅Π΄Π½Π° 64-Π±ΠΈΡ‚Π½Π° ΠΈΠ½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡ˜Π° Π½Π΅ΠΌΠ° Π΄Π° Ρ€Π°Π±ΠΎΡ‚ΠΈ. Π—Π° Π΄Π° Π³ΠΎ Π½Π°ΠΏΡ€Π°Π²ΠΈΡ‚Π΅ ΠΎΠ²Π°, Π΄Π²Π΅ сосСдни инструкции сС користат Π·Π° ΡΠΊΠ»Π°Π΄ΠΈΡ€Π°ΡšΠ΅ Π½Π° Π²Ρ‚ΠΎΡ€ΠΈΠΎΡ‚ Π΄Π΅Π» ΠΎΠ΄ 64-Π±ΠΈΡ‚Π½Π°Ρ‚Π° врСдност Π²ΠΎ ΠΏΠΎΠ»Π΅Ρ‚ΠΎ Imm... ΠŸΡ€ΠΈΠΌΠ΅Ρ€:

$ cat x64.c
long foo(void *ctx)
{
        return 0x11223344aabbccdd;
}
$ clang -target bpf -c x64.c -o x64.o -O2
$ llvm-readelf -x .text x64.o
Hex dump of section '.text':
0x00000000 18000000 ddccbbaa 00000000 44332211 ............D3".
0x00000010 95000000 00000000                   ........

Π’ΠΎ Π±ΠΈΠ½Π°Ρ€Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° ΠΈΠΌΠ° само Π΄Π²Π΅ инструкции:

Binary                                 Disassm
18000000 ddccbbaa 00000000 44332211    r0 = Imm[0]|Imm[1]
95000000 00000000                      exit

ЌС сС срСтнСмС ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎ со инструкции lddw, ΠΊΠΎΠ³Π° Π·Π±ΠΎΡ€ΡƒΠ²Π°ΠΌΠ΅ Π·Π° прСсСлби ΠΈ Ρ€Π°Π±ΠΎΡ‚Π° со ΠΌΠ°ΠΏΠΈ.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€: Ρ€Π°ΡΠΊΠ»ΠΎΠΏΡƒΠ²Π°ΡšΠ΅ Π½Π° BPF со помош Π½Π° стандардни Π°Π»Π°Ρ‚ΠΊΠΈ

Π—Π½Π°Ρ‡ΠΈ, Π½Π°ΡƒΡ‡ΠΈΠ²ΠΌΠ΅ Π΄Π° Ρ‡ΠΈΡ‚Π°ΠΌΠ΅ BPF Π±ΠΈΠ½Π°Ρ€Π½ΠΈ ΠΊΠΎΠ΄ΠΎΠ²ΠΈ ΠΈ ΠΏΠΎΠ΄Π³ΠΎΡ‚Π²Π΅Π½ΠΈ смС Π΄Π° Π³ΠΈ Π°Π½Π°Π»ΠΈΠ·ΠΈΡ€Π°ΠΌΠ΅ ситС инструкции Π΄ΠΎΠΊΠΎΠ»ΠΊΡƒ Π΅ ΠΏΠΎΡ‚Ρ€Π΅Π±Π½ΠΎ. Π‘Π΅ΠΏΠ°ΠΊ, Π²Ρ€Π΅Π΄ΠΈ Π΄Π° сС ΠΊΠ°ΠΆΠ΅ Π΄Π΅ΠΊΠ° Π²ΠΎ пракса Π΅ ΠΏΠΎΡƒΠ΄ΠΎΠ±Π½ΠΎ ΠΈ ΠΏΠΎΠ±Ρ€Π·ΠΎ Π΄Π° сС расклопат ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ ΠΊΠΎΡ€ΠΈΡΡ‚Π΅Ρ˜ΡœΠΈ стандардни Π°Π»Π°Ρ‚ΠΊΠΈ, Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€:

$ llvm-objdump -d x64.o

Disassembly of section .text:

0000000000000000 <foo>:
 0: 18 00 00 00 dd cc bb aa 00 00 00 00 44 33 22 11 r0 = 1234605617868164317 ll
 2: 95 00 00 00 00 00 00 00 exit

Π–ΠΈΠ²ΠΎΡ‚Π½ΠΈΠΎΡ‚ циклус Π½Π° ΠΎΠ±Ρ˜Π΅ΠΊΡ‚ΠΈΡ‚Π΅ BPF, Π΄Π°Ρ‚ΠΎΡ‚Π΅Ρ‡Π΅Π½ систСм bpffs

(ΠŸΡ€Π²ΠΎ Π½Π°ΡƒΡ‡ΠΈΠ² Π½Π΅ΠΊΠΎΠΈ ΠΎΠ΄ Π΄Π΅Ρ‚Π°Π»ΠΈΡ‚Π΅ опишани Π²ΠΎ ΠΎΠ²Π°Π° ΠΏΠΎΡ‚ΡΠ΅ΠΊΡ†ΠΈΡ˜Π° ΠΎΠ΄ постот АлСксСј Π‘Ρ‚Π°Ρ€ΠΎΠ²ΠΎΠΈΡ‚ΠΎΠ² Π²ΠΎ Π‘Π»ΠΎΠ³ Π½Π° BPF.)

ΠžΠ±Ρ˜Π΅ΠΊΡ‚ΠΈΡ‚Π΅ Π½Π° BPF - ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ ΠΈ ΠΌΠ°ΠΏΠΈ - сС ΠΊΡ€Π΅ΠΈΡ€Π°Π°Ρ‚ ΠΎΠ΄ корисничкиот простор ΠΊΠΎΡ€ΠΈΡΡ‚Π΅Ρ˜ΡœΠΈ ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ BPF_PROG_LOAD ΠΈ BPF_MAP_CREATE систСмски ΠΏΠΎΠ²ΠΈΠΊ bpf(2), ќС Π·Π±ΠΎΡ€ΡƒΠ²Π°ΠΌΠ΅ Π·Π° Ρ‚ΠΎΠ° ΠΊΠ°ΠΊΠΎ Ρ‚ΠΎΡ‡Π½ΠΎ сС случува ΠΎΠ²Π° Π²ΠΎ слСдниот Π΄Π΅Π». Ова создава структури Π½Π° ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈ Π½Π° Ρ˜Π°Π΄Ρ€ΠΎΡ‚ΠΎ ΠΈ Π·Π° сСкоја ΠΎΠ΄ Π½ΠΈΠ² refcount (Π±Ρ€ΠΎΡ˜ΠΎΡ‚ Π½Π° Ρ€Π΅Ρ„Π΅Ρ€Π΅Π½Ρ†ΠΈ) Π΅ поставСн Π½Π° Π΅Π΄Π΅Π½, Π° дСскрипторот Π½Π° Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ°Ρ‚Π° ΡˆΡ‚ΠΎ ΠΏΠΎΠΊΠ°ΠΆΡƒΠ²Π° Π½Π° ΠΎΠ±Ρ˜Π΅ΠΊΡ‚ΠΎΡ‚ сС Π²Ρ€Π°ΡœΠ° Π½Π° корисникот. ΠžΡ‚ΠΊΠ°ΠΊΠΎ ќС сС Π·Π°Ρ‚Π²ΠΎΡ€ΠΈ Ρ€Π°Ρ‡ΠΊΠ°Ρ‚Π° refcount ΠΎΠ±Ρ˜Π΅ΠΊΡ‚ΠΎΡ‚ сС Π½Π°ΠΌΠ°Π»ΡƒΠ²Π° Π·Π° Π΅Π΄Π΅Π½, Π° ΠΊΠΎΠ³Π° ќС достигнС Π½ΡƒΠ»Π°, ΠΏΡ€Π΅Π΄ΠΌΠ΅Ρ‚ΠΎΡ‚ сС ΡƒΠ½ΠΈΡˆΡ‚ΡƒΠ²Π°.

Ако ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° користи ΠΌΠ°ΠΏΠΈ, Ρ‚ΠΎΠ³Π°Ρˆ refcount ΠΎΠ²ΠΈΠ΅ ΠΊΠ°Ρ€Ρ‚ΠΈ сС Π·Π³ΠΎΠ»Π΅ΠΌΡƒΠ²Π°Π°Ρ‚ Π·Π° Π΅Π΄Π΅Π½ ΠΏΠΎ Π²Ρ‡ΠΈΡ‚ΡƒΠ²Π°ΡšΠ΅Ρ‚ΠΎ Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π°, Ρ‚.Π΅. Π½ΠΈΠ²Π½ΠΈΡ‚Π΅ дСскриптори Π½Π° Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠΈ ΠΌΠΎΠΆΠ΅ Π΄Π° сС Π·Π°Ρ‚Π²ΠΎΡ€Π°Ρ‚ ΠΎΠ΄ корисничкиот процСс ΠΈ ΡƒΡˆΡ‚Π΅ refcount Π½Π΅ΠΌΠ° Π΄Π° станС Π½ΡƒΠ»Π°:

BPF Π·Π° Π½Π°Ρ˜ΠΌΠ°Π»ΠΈΡ‚Π΅, ΠΏΡ€Π² Π΄Π΅Π»: ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ΅Π½ BPF

По ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΡ‚ΠΎ Π²Ρ‡ΠΈΡ‚ΡƒΠ²Π°ΡšΠ΅ Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π°, ΠΎΠ±ΠΈΡ‡Π½ΠΎ ја ΠΏΡ€ΠΈΠΊΠ°Ρ‡ΡƒΠ²Π°ΠΌΠ΅ Π½Π° нСкој Π²ΠΈΠ΄ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ Π½Π° настани. На ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΌΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° Π³ΠΎ ставимС Π½Π° ΠΌΡ€Π΅ΠΆΠ΅Π½ ΠΈΠ½Ρ‚Π΅Ρ€Ρ„Π΅Ρ˜Ρ Π·Π° Π΄Π° Π³ΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΈΠΌΠ΅ Π΄ΠΎΡ˜Π΄ΠΎΠ²Π½ΠΈΡ‚Π΅ ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ ΠΈΠ»ΠΈ Π΄Π° Π³ΠΎ ΠΏΠΎΠ²Ρ€Π·Π΅ΠΌΠ΅ со Π½Π΅ΠΊΠΎΠΈ tracepoint Π²ΠΎ Ρ˜Π°Π΄Ρ€ΠΎΡ‚ΠΎ. Π’ΠΎ овој ΠΌΠΎΠΌΠ΅Π½Ρ‚, Ρ€Π΅Ρ„Π΅Ρ€Π΅Π½Ρ‚Π½ΠΈΠΎΡ‚ Π±Ρ€ΠΎΡ˜Π°Ρ‡ исто Ρ‚Π°ΠΊΠ° ќС сС Π·Π³ΠΎΠ»Π΅ΠΌΠΈ Π·Π° Π΅Π΄Π΅Π½ ΠΈ ќС ΠΌΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° Π³ΠΎ Π·Π°Ρ‚Π²ΠΎΡ€ΠΈΠΌΠ΅ дСскрипторот Π½Π° Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ°Ρ‚Π° Π²ΠΎ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° Π·Π° Π²Ρ‡ΠΈΡ‚ΡƒΠ²Π°ΡšΠ΅.

Π¨Ρ‚ΠΎ ќС сС случи Π°ΠΊΠΎ сСга Π³ΠΎ исклучимС ΠΏΠΎΠ΄ΠΈΠ³Π½ΡƒΠ²Π°Ρ‡ΠΎΡ‚? Π’ΠΎΠ° зависи ΠΎΠ΄ Ρ‚ΠΈΠΏΠΎΡ‚ Π½Π° Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ Π½Π° настани (ΠΊΡƒΠΊΠ°). Π‘ΠΈΡ‚Π΅ ΠΌΡ€Π΅ΠΆΠ½ΠΈ ΠΊΡƒΠΊΠΈ ќС ΠΏΠΎΡΡ‚ΠΎΡ˜Π°Ρ‚ ΠΎΡ‚ΠΊΠ°ΠΊΠΎ ќС Π·Π°Π²Ρ€ΡˆΠΈ Π½Π°Ρ‚ΠΎΠ²Π°Ρ€ΡƒΠ²Π°Ρ‡ΠΎΡ‚, Ρ‚ΠΎΠ° сС Ρ‚Π°ΠΊΠ°Π½Π°Ρ€Π΅Ρ‡Π΅Π½ΠΈΡ‚Π΅ Π³Π»ΠΎΠ±Π°Π»Π½ΠΈ ΠΊΡƒΠΊΠΈ. И, Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ Π·Π° Ρ‚Ρ€Π°Π³Π° ќС Π±ΠΈΠ΄Π°Ρ‚ објавСни ΠΎΡ‚ΠΊΠ°ΠΊΠΎ ќС Π·Π°Π²Ρ€ΡˆΠΈ процСсот ΡˆΡ‚ΠΎ Π³ΠΈ создал (ΠΈ Π·Π°Ρ‚ΠΎΠ° сС Π½Π°Ρ€Π΅ΠΊΡƒΠ²Π°Π°Ρ‚ Π»ΠΎΠΊΠ°Π»Π½ΠΈ, ΠΎΠ΄ β€žΠ»ΠΎΠΊΠ°Π»Π½ΠΎ Π²ΠΎ ΠΏΡ€ΠΎΡ†Π΅Ρβ€œ). Π’Π΅Ρ…Π½ΠΈΡ‡ΠΊΠΈ, Π»ΠΎΠΊΠ°Π»Π½ΠΈΡ‚Π΅ ΠΊΡƒΠΊΠΈ сСкогаш ΠΈΠΌΠ°Π°Ρ‚ соодвСтСн дСскриптор Π½Π° Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ° Π²ΠΎ корисничкиот простор ΠΈ Π·Π°Ρ‚ΠΎΠ° сС Π·Π°Ρ‚Π²ΠΎΡ€Π°Π°Ρ‚ ΠΊΠΎΠ³Π° процСсот Π΅ Π·Π°Ρ‚Π²ΠΎΡ€Π΅Π½, Π½ΠΎ Π³Π»ΠΎΠ±Π°Π»Π½ΠΈΡ‚Π΅ ΠΊΡƒΠΊΠΈ Π½Π΅ΠΌΠ°Π°Ρ‚. На слСдната слика, ΠΊΠΎΡ€ΠΈΡΡ‚Π΅Ρ˜ΡœΠΈ Ρ†Ρ€Π²Π΅Π½ΠΈ крстови, сС ΠΎΠ±ΠΈΠ΄ΡƒΠ²Π°ΠΌ Π΄Π° ΠΏΠΎΠΊΠ°ΠΆΠ°ΠΌ ΠΊΠ°ΠΊΠΎ ΠΏΡ€Π΅ΠΊΠΈΠ½ΡƒΠ²Π°ΡšΠ΅Ρ‚ΠΎ Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° Π·Π° Π²Ρ‡ΠΈΡ‚ΡƒΠ²Π°ΡšΠ΅ влијаС Π½Π° ΠΆΠΈΠ²ΠΎΡ‚Π½ΠΈΠΎΡ‚ Π²Π΅ΠΊ Π½Π° ΠΎΠ±Ρ˜Π΅ΠΊΡ‚ΠΈΡ‚Π΅ Π²ΠΎ ΡΠ»ΡƒΡ‡Π°Ρ˜ Π½Π° Π»ΠΎΠΊΠ°Π»Π½ΠΈ ΠΈ Π³Π»ΠΎΠ±Π°Π»Π½ΠΈ ΠΊΡƒΠΊΠΈ.

BPF Π·Π° Π½Π°Ρ˜ΠΌΠ°Π»ΠΈΡ‚Π΅, ΠΏΡ€Π² Π΄Π΅Π»: ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ΅Π½ BPF

Π—ΠΎΡˆΡ‚ΠΎ постои Ρ€Π°Π·Π»ΠΈΠΊΠ° ΠΏΠΎΠΌΠ΅Ρ“Ρƒ Π»ΠΎΠΊΠ°Π»Π½ΠΈ ΠΈ Π³Π»ΠΎΠ±Π°Π»Π½ΠΈ ΠΊΡƒΠΊΠΈ? Π˜Π·Π²Ρ€ΡˆΡƒΠ²Π°ΡšΠ΅Ρ‚ΠΎ Π½Π° Π½Π΅ΠΊΠΎΠΈ Π²ΠΈΠ΄ΠΎΠ²ΠΈ ΠΌΡ€Π΅ΠΆΠ½ΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ ΠΈΠΌΠ° смисла Π±Π΅Π· кориснички простор, Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€, замислСтС Π·Π°ΡˆΡ‚ΠΈΡ‚Π° ΠΎΠ΄ DDoS - ΠΏΠΎΠ΄ΠΈΠ³Π½ΡƒΠ²Π°Ρ‡ΠΎΡ‚ Π³ΠΈ ΠΏΠΈΡˆΡƒΠ²Π° ΠΏΡ€Π°Π²ΠΈΠ»Π°Ρ‚Π° ΠΈ ја ΠΏΠΎΠ²Ρ€Π·ΡƒΠ²Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° BPF со ΠΌΡ€Π΅ΠΆΠ½ΠΈΠΎΡ‚ ΠΈΠ½Ρ‚Π΅Ρ€Ρ„Π΅Ρ˜Ρ, ΠΏΠΎ ΡˆΡ‚ΠΎ ΠΏΠΎΠ΄ΠΈΠ³Π½ΡƒΠ²Π°Ρ‡ΠΎΡ‚ ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΎΠ΄ΠΈ ΠΈ Π΄Π° сС ΡƒΠ±ΠΈΠ΅. Од Π΄Ρ€ΡƒΠ³Π° страна, замислСтС ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° Π·Π° Ρ‚Ρ€Π°Π³Π° Π·Π° Π΄Π΅Π±Π°Π³ΠΈΡ€Π°ΡšΠ΅ ΡˆΡ‚ΠΎ стС ја напишалС Π½Π° ΠΊΠΎΠ»Π΅Π½Π° Π·Π° дСсСт ΠΌΠΈΠ½ΡƒΡ‚ΠΈ - ΠΊΠΎΠ³Π° ќС Π·Π°Π²Ρ€ΡˆΠΈ, Π±ΠΈ сакалС Π΄Π° Π½Π΅ΠΌΠ° Ρ“ΡƒΠ±Ρ€Π΅ Π²ΠΎ систСмот, Π° Π»ΠΎΠΊΠ°Π»Π½ΠΈΡ‚Π΅ ΠΊΡƒΠΊΠΈ ќС Π³ΠΎ осигураат Ρ‚ΠΎΠ°.

Од Π΄Ρ€ΡƒΠ³Π° страна, замислСтС Π΄Π΅ΠΊΠ° сакатС Π΄Π° сС ΠΏΠΎΠ²Ρ€Π·Π΅Ρ‚Π΅ со Ρ‚Ρ€Π°Π³Π° Ρ‚ΠΎΡ‡ΠΊΠ° Π²ΠΎ ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚ ΠΈ Π΄Π° собиратС статистика Π²ΠΎ Ρ‚Π΅ΠΊΠΎΡ‚ Π½Π° ΠΌΠ½ΠΎΠ³Ρƒ Π³ΠΎΠ΄ΠΈΠ½ΠΈ. Π’ΠΎ овој ΡΠ»ΡƒΡ‡Π°Ρ˜, Π±ΠΈ сакалС Π΄Π° Π³ΠΎ ΠΊΠΎΠΌΠΏΠ»Π΅Ρ‚ΠΈΡ€Π°Ρ‚Π΅ корисничкиот Π΄Π΅Π» ΠΈ ΠΎΠ΄Π²Ρ€Π΅ΠΌΠ΅-Π½Π°Π²Ρ€Π΅ΠΌΠ΅ Π΄Π° сС Π²Ρ€Π°ΡœΠ°Ρ‚Π΅ Π½Π° статистиката. Π”Π°Ρ‚ΠΎΡ‚Π΅Ρ‡Π½ΠΈΠΎΡ‚ систСм bpf ја Π΄Π°Π²Π° ΠΎΠ²Π°Π° моТност. Π’ΠΎΠ° Π΅ псСвдо-Π΄Π°Ρ‚ΠΎΡ‚Π΅Ρ‡Π΅Π½ систСм Π²ΠΎ ΠΌΠ΅ΠΌΠΎΡ€ΠΈΡ˜Π°Ρ‚Π° ΡˆΡ‚ΠΎ ΠΎΠ²ΠΎΠ·ΠΌΠΎΠΆΡƒΠ²Π° создавањС Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠΈ ΡˆΡ‚ΠΎ Ρ€Π΅Ρ„Π΅Ρ€Π΅Π½Ρ†ΠΈΡ€Π°Π°Ρ‚ BPF ΠΎΠ±Ρ˜Π΅ΠΊΡ‚ΠΈ ΠΈ со Ρ‚ΠΎΠ° сС Π·Π³ΠΎΠ»Π΅ΠΌΡƒΠ²Π°Π°Ρ‚ refcount ΠΏΡ€Π΅Π΄ΠΌΠ΅Ρ‚ΠΈ. По ΠΎΠ²Π°, Π½Π°Ρ‚ΠΎΠ²Π°Ρ€ΡƒΠ²Π°Ρ‡ΠΎΡ‚ ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΈΠ·Π»Π΅Π·Π΅, Π° ΠΎΠ±Ρ˜Π΅ΠΊΡ‚ΠΈΡ‚Π΅ ΡˆΡ‚ΠΎ Π³ΠΈ создал ќС останат ΠΆΠΈΠ²ΠΈ.

BPF Π·Π° Π½Π°Ρ˜ΠΌΠ°Π»ΠΈΡ‚Π΅, ΠΏΡ€Π² Π΄Π΅Π»: ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ΅Π½ BPF

ΠšΡ€Π΅ΠΈΡ€Π°ΡšΠ΅Ρ‚ΠΎ Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠΈ Π²ΠΎ bpffs ΠΊΠΎΠΈ ΡƒΠΏΠ°Ρ‚ΡƒΠ²Π°Π°Ρ‚ Π½Π° BPF ΠΎΠ±Ρ˜Π΅ΠΊΡ‚ΠΈ сС Π½Π°Ρ€Π΅ΠΊΡƒΠ²Π° β€žΠ·Π°ΠΊΠ°Ρ‡ΡƒΠ²Π°ΡšΠ΅β€œ (ΠΊΠ°ΠΊΠΎ Π²ΠΎ слСдната Ρ„Ρ€Π°Π·Π°: β€žΠΏΡ€ΠΎΡ†Π΅ΡΠΎΡ‚ ΠΌΠΎΠΆΠ΅ Π΄Π° Π·Π°ΠΊΠ°Ρ‡ΠΈ BPF ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° ΠΈΠ»ΠΈ ΠΌΠ°ΠΏΠ°β€œ). Π‘ΠΎΠ·Π΄Π°Π²Π°ΡšΠ΅Ρ‚ΠΎ ΠΎΠ±Ρ˜Π΅ΠΊΡ‚ΠΈ Π½Π° Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠΈ Π·Π° ΠΎΠ±Ρ˜Π΅ΠΊΡ‚ΠΈΡ‚Π΅ BPF ΠΈΠΌΠ° смисла Π½Π΅ само Π·Π° ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΡƒΠ²Π°ΡšΠ΅ Π½Π° ΠΆΠΈΠ²ΠΎΡ‚Π½ΠΈΠΎΡ‚ Π²Π΅ΠΊ Π½Π° Π»ΠΎΠΊΠ°Π»Π½ΠΈΡ‚Π΅ ΠΎΠ±Ρ˜Π΅ΠΊΡ‚ΠΈ, Ρ‚ΡƒΠΊΡƒ ΠΈ Π·Π° употрСбливоста Π½Π° Π³Π»ΠΎΠ±Π°Π»Π½ΠΈΡ‚Π΅ ΠΎΠ±Ρ˜Π΅ΠΊΡ‚ΠΈ - Π²Ρ€Π°ΡœΠ°Ρ˜ΡœΠΈ сС Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΡ‚ со Π³Π»ΠΎΠ±Π°Π»Π½Π°Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° Π·Π° Π·Π°ΡˆΡ‚ΠΈΡ‚Π° Π½Π° DDoS, сакамС Π΄Π° ΠΌΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° дојдСмС ΠΈ Π΄Π° ја Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ статистиката ΠΎΠ΄ Π²Ρ€Π΅ΠΌΠ΅ Π½Π° Π²Ρ€Π΅ΠΌΠ΅.

Π”Π°Ρ‚ΠΎΡ‚Π΅Ρ‡Π½ΠΈΠΎΡ‚ систСм BPF ΠΎΠ±ΠΈΡ‡Π½ΠΎ Π΅ ΠΌΠΎΠ½Ρ‚ΠΈΡ€Π°Π½ /sys/fs/bpf, Π½ΠΎ ΠΌΠΎΠΆΠ΅ Π΄Π° сС ΠΌΠΎΠ½Ρ‚ΠΈΡ€Π° ΠΈ Π»ΠΎΠΊΠ°Π»Π½ΠΎ, Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π²Π°ΠΊΠ°:

$ mkdir bpf-mountpoint
$ sudo mount -t bpf none bpf-mountpoint

Π˜ΠΌΠΈΡšΠ°Ρ‚Π° Π½Π° Π΄Π°Ρ‚ΠΎΡ‚Π΅Ρ‡Π½ΠΈΠΎΡ‚ систСм сС ΠΊΡ€Π΅ΠΈΡ€Π°Π°Ρ‚ со помош Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄Π°Ρ‚Π° BPF_OBJ_PIN BPF систСмски ΠΏΠΎΠ²ΠΈΠΊ. Π—Π° ΠΈΠ»ΡƒΡΡ‚Ρ€Π°Ρ†ΠΈΡ˜Π°, Π΄Π° Π·Π΅ΠΌΠ΅ΠΌΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°, Π΄Π° ја ΠΊΠΎΠΌΠΏΠ°Ρ˜Π»ΠΈΡ€Π°ΠΌΠ΅, Π΄Π° ја ΠΏΠΎΠ΄ΠΈΠ³Π½Π΅ΠΌΠ΅ ΠΈ Π΄Π° ја Π·Π°ΠΊΠ°Ρ‡ΠΈΠΌΠ΅ bpffs. ΠΠ°ΡˆΠ°Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° Π½Π΅ ΠΏΡ€Π°Π²ΠΈ Π½ΠΈΡˆΡ‚ΠΎ корисно, Π½ΠΈΠ΅ само Π³ΠΎ ΠΏΡ€Π΅Π·Π΅Π½Ρ‚ΠΈΡ€Π°ΠΌΠ΅ ΠΊΠΎΠ΄ΠΎΡ‚ Π·Π° Π΄Π° ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Π³ΠΎ Ρ€Π΅ΠΏΡ€ΠΎΠ΄ΡƒΡ†ΠΈΡ€Π°Ρ‚Π΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΡ‚:

$ cat test.c
__attribute__((section("xdp"), used))
int test(void *ctx)
{
        return 0;
}

char _license[] __attribute__((section("license"), used)) = "GPL";

АјдС Π΄Π° ја составимС ΠΎΠ²Π°Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° ΠΈ Π΄Π° создадСмС Π»ΠΎΠΊΠ°Π»Π½Π° копија ΠΎΠ΄ Π΄Π°Ρ‚ΠΎΡ‚Π΅Ρ‡Π΅Π½ систСм bpffs:

$ clang -target bpf -c test.c -o test.o
$ mkdir bpf-mountpoint
$ sudo mount -t bpf none bpf-mountpoint

Π‘Π΅Π³Π° Π΄Π° ја ΠΏΡ€Π΅Π·Π΅ΠΌΠ΅ΠΌΠ΅ Π½Π°ΡˆΠ°Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° ΠΊΠΎΡ€ΠΈΡΡ‚Π΅Ρ˜ΡœΠΈ ја Π°Π»Π°Ρ‚ΠΊΠ°Ρ‚Π° bpftool ΠΈ ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅Ρ‚Π΅ Π³ΠΈ ΠΏΡ€ΠΈΠ΄Ρ€ΡƒΠΆΠ½ΠΈΡ‚Π΅ систСмски ΠΏΠΎΠ²ΠΈΡ†ΠΈ bpf(2) (Π½Π΅ΠΊΠΎΠΈ ΠΈΡ€Π΅Π»Π΅Π²Π°Π½Ρ‚Π½ΠΈ Π»ΠΈΠ½ΠΈΠΈ сС отстранСти ΠΎΠ΄ ΠΈΠ·Π»Π΅Π·ΠΎΡ‚ Π½Π° траса):

$ sudo strace -e bpf bpftool prog load ./test.o bpf-mountpoint/test
bpf(BPF_PROG_LOAD, {prog_type=BPF_PROG_TYPE_XDP, prog_name="test", ...}, 120) = 3
bpf(BPF_OBJ_PIN, {pathname="bpf-mountpoint/test", bpf_fd=3}, 120) = 0

ОвдС ја Π²Ρ‡ΠΈΡ‚Π°Π²ΠΌΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° ΠΊΠΎΡ€ΠΈΡΡ‚Π΅Ρ˜ΡœΠΈ BPF_PROG_LOAD, Π΄ΠΎΠ±ΠΈ дСскриптор Π½Π° Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ° ΠΎΠ΄ ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚ 3 ΠΈ ΠΊΠΎΡ€ΠΈΡΡ‚Π΅Ρ˜ΡœΠΈ ја ΠΊΠΎΠΌΠ°Π½Π΄Π°Ρ‚Π° BPF_OBJ_PIN Π³ΠΎ Π·Π°ΠΊΠ°Ρ‡ΠΈ овој дСскриптор Π½Π° Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ° ΠΊΠ°ΠΊΠΎ Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ° "bpf-mountpoint/test". По ΠΎΠ²Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° Π·Π° ΠΏΠΎΠ΄ΠΈΠ³Π½ΡƒΠ²Π°Ρ‡ bpftool Π·Π°Π²Ρ€ΡˆΠΈ со Ρ€Π°Π±ΠΎΡ‚Π°, Π½ΠΎ Π½Π°ΡˆΠ°Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° остана Π²ΠΎ ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚, ΠΈΠ°ΠΊΠΎ Π½Π΅ ја ΠΏΡ€ΠΈΠΊΠ°Ρ‡ΠΈΠ²ΠΌΠ΅ Π½Π° Π½ΠΈΡ‚Ρƒ Π΅Π΄Π΅Π½ ΠΌΡ€Π΅ΠΆΠ΅Π½ ΠΈΠ½Ρ‚Π΅Ρ€Ρ„Π΅Ρ˜Ρ:

$ sudo bpftool prog | tail -3
783: xdp  name test  tag 5c8ba0cf164cb46c  gpl
        loaded_at 2020-05-05T13:27:08+0000  uid 0
        xlated 24B  jited 41B  memlock 4096B

МоТСмС Π½ΠΎΡ€ΠΌΠ°Π»Π½ΠΎ Π΄Π° Π³ΠΎ ΠΈΠ·Π±Ρ€ΠΈΡˆΠ΅ΠΌΠ΅ ΠΎΠ±Ρ˜Π΅ΠΊΡ‚ΠΎΡ‚ Π½Π° Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ°Ρ‚Π° unlink(2) Π° ΠΏΠΎΡ‚ΠΎΠ° соодвСтната ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° ќС Π±ΠΈΠ΄Π΅ ΠΈΠ·Π±Ρ€ΠΈΡˆΠ°Π½Π°:

$ sudo rm ./bpf-mountpoint/test
$ sudo bpftool prog show id 783
Error: get by id (783): No such file or directory

Π‘Ρ€ΠΈΡˆΠ΅ΡšΠ΅ ΠΎΠ±Ρ˜Π΅ΠΊΡ‚ΠΈ

Π—Π±ΠΎΡ€ΡƒΠ²Π°Ρ˜ΡœΠΈ Π·Π° Π±Ρ€ΠΈΡˆΠ΅ΡšΠ΅ ΠΎΠ±Ρ˜Π΅ΠΊΡ‚ΠΈ, Π½Π΅ΠΎΠΏΡ…ΠΎΠ΄Π½ΠΎ Π΅ Π΄Π° сС Ρ€Π°Π·Ρ˜Π°ΡΠ½ΠΈ Π΄Π΅ΠΊΠ° ΠΎΡ‚ΠΊΠ°ΠΊΠΎ ќС ја исклучимС ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° ΠΎΠ΄ ΠΊΡƒΠΊΠ°Ρ‚Π° (Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ Π½Π° настани), Π½ΠΈΡ‚Ρƒ Π΅Π΄Π΅Π½ Π½ΠΎΠ² настан Π½Π΅ΠΌΠ° Π΄Π° Π³ΠΎ Π°ΠΊΡ‚ΠΈΠ²ΠΈΡ€Π° Π½Π΅Π³ΠΎΠ²ΠΎΡ‚ΠΎ Π»Π°Π½ΡΠΈΡ€Π°ΡšΠ΅, ΠΌΠ΅Ρ“ΡƒΡ‚ΠΎΠ°, ситС Ρ‚Π΅ΠΊΠΎΠ²Π½ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΡ†ΠΈ Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° ќС Π±ΠΈΠ΄Π°Ρ‚ Π·Π°Π²Ρ€ΡˆΠ΅Π½ΠΈ Π²ΠΎ Π½ΠΎΡ€ΠΌΠ°Π»Π΅Π½ рСдослСд .

НСкои Ρ‚ΠΈΠΏΠΎΠ²ΠΈ BPF ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ Π²ΠΈ Π΄ΠΎΠ·Π²ΠΎΠ»ΡƒΠ²Π°Π°Ρ‚ Π΄Π° ја Π·Π°ΠΌΠ΅Π½ΠΈΡ‚Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° Π²ΠΎ Π»Π΅Ρ‚, Ρ‚.Π΅. ΠΎΠ±Π΅Π·Π±Π΅Π΄ΡƒΠ²Π°Π°Ρ‚ атомичност Π½Π° Π½ΠΈΠ·Π°Ρ‚Π° replace = detach old program, attach new program. Π’ΠΎ овој ΡΠ»ΡƒΡ‡Π°Ρ˜, ситС Π°ΠΊΡ‚ΠΈΠ²Π½ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΡ†ΠΈ Π½Π° старата Π²Π΅Ρ€Π·ΠΈΡ˜Π° Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° ќС ја Π·Π°Π²Ρ€ΡˆΠ°Ρ‚ ΡΠ²ΠΎΡ˜Π°Ρ‚Π° Ρ€Π°Π±ΠΎΡ‚Π°, Π° ΠΎΠ΄ Π½ΠΎΠ²Π°Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° ќС сС создадат Π½ΠΎΠ²ΠΈ ΡƒΠΏΡ€Π°Π²ΡƒΠ²Π°Ρ‡ΠΈ Π½Π° настани, Π° β€žΠ°Ρ‚ΠΎΠΌΠΈΡ‡Π½ΠΎΡΡ‚Π°β€œ ΠΎΠ²Π΄Π΅ Π·Π½Π°Ρ‡ΠΈ Π΄Π΅ΠΊΠ° Π½Π΅ΠΌΠ° Π΄Π° сС ΠΏΡ€ΠΎΠΏΡƒΡˆΡ‚ΠΈ Π½ΠΈΡ‚Ρƒ Π΅Π΄Π΅Π½ настан.

ΠŸΡ€ΠΈΠΊΠ°Ρ‡ΡƒΠ²Π°ΡšΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ Π½Π° ΠΈΠ·Π²ΠΎΡ€ΠΈ Π½Π° настани

Π’ΠΎ ΠΎΠ²Π°Π° ΡΡ‚Π°Ρ‚ΠΈΡ˜Π°, Π½Π΅ΠΌΠ° ΠΎΠ΄Π΄Π΅Π»Π½ΠΎ Π΄Π° опишСмС ΠΏΠΎΠ²Ρ€Π·ΡƒΠ²Π°ΡšΠ΅ Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ со ΠΈΠ·Π²ΠΎΡ€ΠΈ Π½Π° настани, бидСјќи ΠΈΠΌΠ° смисла Π΄Π° сС ΠΏΡ€ΠΎΡƒΡ‡ΡƒΠ²Π° ΠΎΠ²Π° Π²ΠΎ контСкст Π½Π° спСцифичСн Ρ‚ΠΈΠΏ Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°. Π¦ΠΌ. ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΏΠΎΠ΄ΠΎΠ»Ρƒ, Π²ΠΎ која ΠΏΠΎΠΊΠ°ΠΆΡƒΠ²Π°ΠΌΠ΅ ΠΊΠ°ΠΊΠΎ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ ΠΊΠ°ΠΊΠΎ XDP сС ΠΏΠΎΠ²Ρ€Π·Π°Π½ΠΈ.

ΠœΠ°Π½ΠΈΠΏΡƒΠ»ΠΈΡ€Π°ΡšΠ΅ со ΠΎΠ±Ρ˜Π΅ΠΊΡ‚ΠΈ ΠΊΠΎΡ€ΠΈΡΡ‚Π΅Ρ˜ΡœΠΈ Π³ΠΎ систСмскиот ΠΏΠΎΠ²ΠΈΠΊ bpf

BPF ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ

Π‘ΠΈΡ‚Π΅ BPF ΠΎΠ±Ρ˜Π΅ΠΊΡ‚ΠΈ сС ΠΊΡ€Π΅ΠΈΡ€Π°Π½ΠΈ ΠΈ ΡƒΠΏΡ€Π°Π²ΡƒΠ²Π°Π½ΠΈ ΠΎΠ΄ корисничкиот простор со помош Π½Π° систСмски ΠΏΠΎΠ²ΠΈΠΊ bpf, со слСдниов ΠΏΡ€ΠΎΡ‚ΠΎΡ‚ΠΈΠΏ:

#include <linux/bpf.h>

int bpf(int cmd, union bpf_attr *attr, unsigned int size);

Π•Π²Π΅ Π³ΠΎ Ρ‚ΠΈΠΌΠΎΡ‚ cmd Π΅ Π΅Π΄Π½Π° ΠΎΠ΄ врСдноститС Π½Π° Ρ‚ΠΈΠΏΠΎΡ‚ enum bpf_cmd, attr β€” ΠΏΠΎΠΊΠ°ΠΆΡƒΠ²Π°Ρ‡ Π½Π° ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈ Π·Π° ΠΎΠ΄Ρ€Π΅Π΄Π΅Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° ΠΈ size β€” Π³ΠΎΠ»Π΅ΠΌΠΈΠ½Π°Ρ‚Π° Π½Π° ΠΎΠ±Ρ˜Π΅ΠΊΡ‚ΠΎΡ‚ спорСд ΠΏΠΎΠΊΠ°ΠΆΡƒΠ²Π°Ρ‡ΠΎΡ‚, Ρ‚.Π΅. ΠΎΠ±ΠΈΡ‡Π½ΠΎ ΠΎΠ²Π° sizeof(*attr). Π’ΠΎ ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚ 5.8 систСмскиот ΠΏΠΎΠ²ΠΈΠΊ bpf ΠΏΠΎΠ΄Π΄Ρ€ΠΆΡƒΠ²Π° 34 Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ ΠΈ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡƒΠ²Π°ΡšΠ΅ Π½Π° union bpf_attr Π·Π°Ρ„Π°ΡœΠ° 200 Π»ΠΈΠ½ΠΈΠΈ. Но, Π½Π΅ Ρ‚Ρ€Π΅Π±Π° Π΄Π° сС плашимС ΠΎΠ΄ ΠΎΠ²Π°, бидСјќи ќС сС Π·Π°ΠΏΠΎΠ·Π½Π°Π΅ΠΌΠ΅ со ΠΊΠΎΠΌΠ°Π½Π΄ΠΈΡ‚Π΅ ΠΈ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΡ‚Π΅ Π²ΠΎ Ρ‚Π΅ΠΊΠΎΡ‚ Π½Π° Π½Π΅ΠΊΠΎΠ»ΠΊΡƒ статии.

Π”Π° ΠΏΠΎΡ‡Π½Π΅ΠΌΠ΅ со Ρ‚ΠΈΠΌΠΎΡ‚ BPF_PROG_LOAD, кој создава ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ Π·Π° BPF - Π·Π΅ΠΌΠ° сСт ΠΎΠ΄ инструкции Π·Π° BPF ΠΈ Π³ΠΎ Π²Ρ‡ΠΈΡ‚ΡƒΠ²Π° Π²ΠΎ ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚. Π’ΠΎ ΠΌΠΎΠΌΠ΅Π½Ρ‚ΠΎΡ‚ Π½Π° Π²Ρ‡ΠΈΡ‚ΡƒΠ²Π°ΡšΠ΅, ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡƒΠ²Π°Ρ‡ΠΎΡ‚ сС стартува, Π° ΠΏΠΎΡ‚ΠΎΠ° JIT ΠΊΠΎΠΌΠΏΠ°Ρ˜Π»Π΅Ρ€ΠΎΡ‚ ΠΈ ΠΏΠΎ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΡ‚ΠΎ ΠΈΠ·Π²Ρ€ΡˆΡƒΠ²Π°ΡšΠ΅, дСскрипторот Π½Π° програмската Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ° сС Π²Ρ€Π°ΡœΠ° Π½Π° корисникот. Π’ΠΈΠ΄ΠΎΠ²ΠΌΠ΅ ΡˆΡ‚ΠΎ сС случува со Π½Π΅Π³ΠΎ ΠΏΠΎΠ½Π°Ρ‚Π°ΠΌΡƒ Π²ΠΎ ΠΏΡ€Π΅Ρ‚Ρ…ΠΎΠ΄Π½ΠΈΠΎΡ‚ Π΄Π΅Π» Π·Π° ΠΆΠΈΠ²ΠΎΡ‚Π½ΠΈΠΎΡ‚ циклус Π½Π° BPF ΠΎΠ±Ρ˜Π΅ΠΊΡ‚ΠΈΡ‚Π΅.

Π‘Π΅Π³Π° ќС напишСмС сопствСна ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° која ќС Π²Ρ‡ΠΈΡ‚Π° Сдноставна ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° BPF, Π½ΠΎ ΠΏΡ€Π²ΠΎ Ρ‚Ρ€Π΅Π±Π° Π΄Π° ΠΎΠ΄Π»ΡƒΡ‡ΠΈΠΌΠ΅ ΠΊΠ°ΠΊΠ²Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° сакамС Π΄Π° Π²Ρ‡ΠΈΡ‚Π°ΠΌΠ΅ - ќС Ρ‚Ρ€Π΅Π±Π° Π΄Π° ΠΈΠ·Π±Π΅Ρ€Π΅ΠΌΠ΅ Π’ΠΈΠΏ ΠΈ Π²ΠΎ Ρ€Π°ΠΌΠΊΠΈΡ‚Π΅ Π½Π° овој Ρ‚ΠΈΠΏ Π½Π°ΠΏΠΈΡˆΠ΅Ρ‚Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° која ќС Π³ΠΎ ΠΏΠΎΠ»ΠΎΠΆΠΈ тСстот Π·Π° Π²Π΅Ρ€ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΡ˜Π°. Π‘Π΅ΠΏΠ°ΠΊ, Π·Π° Π΄Π° Π½Π΅ Π³ΠΎ ΠΊΠΎΠΌΠΏΠ»ΠΈΡ†ΠΈΡ€Π°ΠΌΠ΅ процСсот, Π΅Π²Π΅ Π³ΠΎ Π³ΠΎΡ‚ΠΎΠ²ΠΎ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅: ќС Π·Π΅ΠΌΠ΅ΠΌΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° ΠΊΠ°ΠΊΠΎ BPF_PROG_TYPE_XDP, ΡˆΡ‚ΠΎ ќС ја Π²Ρ€Π°Ρ‚ΠΈ врСдноста XDP_PASS (прСскокнСтС Π³ΠΈ ситС ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ). Π’ΠΎ асСмблСрот BPF ΠΈΠ·Π³Π»Π΅Π΄Π° ΠΌΠ½ΠΎΠ³Ρƒ Сдноставно:

r0 = 2
exit

ΠžΡ‚ΠΊΠ°ΠΊΠΎ ќС сС ΠΎΠ΄Π»ΡƒΡ‡ΠΈΠΌΠ΅ Π·Π° Π΄Π΅ΠΊΠ° ќС испратимС, ΠΌΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° Π²ΠΈ ΠΊΠ°ΠΆΠ΅ΠΌΠ΅ ΠΊΠ°ΠΊΠΎ ќС Π³ΠΎ Π½Π°ΠΏΡ€Π°Π²ΠΈΠΌΠ΅ Ρ‚ΠΎΠ°:

#define _GNU_SOURCE
#include <string.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <linux/bpf.h>

static inline __u64 ptr_to_u64(const void *ptr)
{
        return (__u64) (unsigned long) ptr;
}

int main(void)
{
    struct bpf_insn insns[] = {
        {
            .code = BPF_ALU64 | BPF_MOV | BPF_K,
            .dst_reg = BPF_REG_0,
            .imm = XDP_PASS
        },
        {
            .code = BPF_JMP | BPF_EXIT
        },
    };

    union bpf_attr attr = {
        .prog_type = BPF_PROG_TYPE_XDP,
        .insns     = ptr_to_u64(insns),
        .insn_cnt  = sizeof(insns)/sizeof(insns[0]),
        .license   = ptr_to_u64("GPL"),
    };

    strncpy(attr.prog_name, "woo", sizeof(attr.prog_name));
    syscall(__NR_bpf, BPF_PROG_LOAD, &attr, sizeof(attr));

    for ( ;; )
        pause();
}

Π˜Π½Ρ‚Π΅Ρ€Π΅ΡΠ½ΠΈΡ‚Π΅ настани Π²ΠΎ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° Π·Π°ΠΏΠΎΡ‡Π½ΡƒΠ²Π°Π°Ρ‚ со Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ†ΠΈΡ˜Π° Π½Π° Π½ΠΈΠ·Π° insns - Π½Π°ΡˆΠ°Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° BPF Π²ΠΎ машински ΠΊΠΎΠ΄. Π’ΠΎ овој ΡΠ»ΡƒΡ‡Π°Ρ˜, сСкоја ΠΈΠ½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡ˜Π° ΠΎΠ΄ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° BPF Π΅ спакувана Π²ΠΎ структурата bpf_insn. ΠŸΡ€Π²ΠΈΠΎΡ‚ Π΅Π»Π΅ΠΌΠ΅Π½Ρ‚ insns Π΅ Π²ΠΎ согласност со упатствата r0 = 2, Π²Ρ‚ΠΎΡ€ΠΈΠΎΡ‚ - exit.

ΠŸΠΎΠ²Π»Π΅ΠΊΡƒΠ²Π°ΡšΠ΅. ΠˆΠ°Π΄Ρ€ΠΎΡ‚ΠΎ Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ€Π° ΠΏΠΎΠΏΠΎΠ³ΠΎΠ΄Π½ΠΈ ΠΌΠ°ΠΊΡ€ΠΎΠ° Π·Π° ΠΏΠΈΡˆΡƒΠ²Π°ΡšΠ΅ машински ΠΊΠΎΠ΄ΠΎΠ²ΠΈ ΠΈ ΠΊΠΎΡ€ΠΈΡΡ‚Π΅ΡšΠ΅ Π½Π° Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ°Ρ‚Π° Π·Π° Π·Π°Π³Π»Π°Π²ΠΈΠ΅ Π½Π° Ρ˜Π°Π΄Ρ€ΠΎΡ‚ΠΎ tools/include/linux/filter.h Π±ΠΈ ΠΌΠΎΠΆΠ΅Π»Π΅ Π΄Π° ΠΏΠΈΡˆΡƒΠ²Π°ΠΌΠ΅

struct bpf_insn insns[] = {
    BPF_MOV64_IMM(BPF_REG_0, XDP_PASS),
    BPF_EXIT_INSN()
};

Но, бидСјќи ΠΏΠΈΡˆΡƒΠ²Π°ΡšΠ΅Ρ‚ΠΎ BPF ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ Π²ΠΎ ΠΌΠ°Ρ˜Ρ‡ΠΈΠ½ ΠΊΠΎΠ΄ Π΅ ΠΏΠΎΡ‚Ρ€Π΅Π±Π½ΠΎ само Π·Π° ΠΏΠΈΡˆΡƒΠ²Π°ΡšΠ΅ тСстови Π²ΠΎ ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚ ΠΈ статии Π·Π° BPF, отсуството Π½Π° ΠΎΠ²ΠΈΠ΅ ΠΌΠ°ΠΊΡ€ΠΎΠ° навистина Π½Π΅ Π³ΠΎ ΠΊΠΎΠΌΠΏΠ»ΠΈΡ†ΠΈΡ€Π° ΠΆΠΈΠ²ΠΎΡ‚ΠΎΡ‚ Π½Π° Ρ€Π°Π·Π²ΠΈΠ²Π°Ρ‡ΠΎΡ‚.

По Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ€Π°ΡšΠ΅Ρ‚ΠΎ Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° BPF, ΠΏΡ€Π΅ΠΌΠΈΠ½ΡƒΠ²Π°ΠΌΠ΅ ΠΊΠΎΠ½ нСјзино Π²Ρ‡ΠΈΡ‚ΡƒΠ²Π°ΡšΠ΅ Π²ΠΎ ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚. ΠΠ°ΡˆΠΈΠΎΡ‚ минималистички сСт Π½Π° ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈ attr Π³ΠΈ Π²ΠΊΠ»ΡƒΡ‡ΡƒΠ²Π° Ρ‚ΠΈΠΏΠΎΡ‚ Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π°, мноТСството ΠΈ Π±Ρ€ΠΎΡ˜ΠΎΡ‚ Π½Π° инструкции, ΠΏΠΎΡ‚Ρ€Π΅Π±Π½Π°Ρ‚Π° Π»ΠΈΡ†Π΅Π½Ρ†Π° ΠΈ ΠΈΠΌΠ΅Ρ‚ΠΎ "woo", кој Π³ΠΎ користимС Π·Π° Π΄Π° ја ΠΏΡ€ΠΎΠ½Π°Ρ˜Π΄Π΅ΠΌΠ΅ Π½Π°ΡˆΠ°Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° Π½Π° систСмот ΠΏΠΎ ΠΏΡ€Π΅Π·Π΅ΠΌΠ°ΡšΠ΅Ρ‚ΠΎ. ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π°, ΠΊΠ°ΠΊΠΎ ΡˆΡ‚ΠΎ Π΅ Π²Π΅Ρ‚Π΅Π½ΠΎ, сС Π²Ρ‡ΠΈΡ‚ΡƒΠ²Π° Π²ΠΎ систСмот со помош Π½Π° систСмски ΠΏΠΎΠ²ΠΈΠΊ bpf.

На ΠΊΡ€Π°Ρ˜ΠΎΡ‚ ΠΎΠ΄ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° Π·Π°Π²Ρ€ΡˆΡƒΠ²Π°ΠΌΠ΅ Π²ΠΎ бСсконСчна јамка која Π³ΠΎ симулира Ρ‚ΠΎΠ²Π°Ρ€ΠΎΡ‚. Π‘Π΅Π· Π½Π΅Π³ΠΎ, ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° ќС Π±ΠΈΠ΄Π΅ ΡƒΠ±ΠΈΠ΅Π½Π° ΠΎΠ΄ ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚ ΠΊΠΎΠ³Π° ќС сС Π·Π°Ρ‚Π²ΠΎΡ€ΠΈ дСскрипторот Π½Π° Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ°Ρ‚Π° ΡˆΡ‚ΠΎ Π½ΠΈ Π³ΠΎ Π²Ρ€Π°Ρ‚ΠΈ систСмскиот ΠΏΠΎΠ²ΠΈΠΊ bpf, ΠΈ Π½Π΅ΠΌΠ° Π΄Π° Π³ΠΎ Π²ΠΈΠ΄ΠΈΠΌΠ΅ Π²ΠΎ систСмот.

Па, Π½ΠΈΠ΅ смС ΠΏΠΎΠ΄Π³ΠΎΡ‚Π²Π΅Π½ΠΈ Π·Π° Ρ‚Π΅ΡΡ‚ΠΈΡ€Π°ΡšΠ΅. АјдС Π΄Π° ја составимС ΠΈ ΠΈΠ·Π²Ρ€ΡˆΠΈΠΌΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° ΠΏΠΎΠ΄ straceΠ·Π° Π΄Π° ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚Π΅ Π΄Π°Π»ΠΈ сè Ρ€Π°Π±ΠΎΡ‚ΠΈ ΠΊΠ°ΠΊΠΎ ΡˆΡ‚ΠΎ Ρ‚Ρ€Π΅Π±Π°:

$ clang -g -O2 simple-prog.c -o simple-prog

$ sudo strace ./simple-prog
execve("./simple-prog", ["./simple-prog"], 0x7ffc7b553480 /* 13 vars */) = 0
...
bpf(BPF_PROG_LOAD, {prog_type=BPF_PROG_TYPE_XDP, insn_cnt=2, insns=0x7ffe03c4ed50, license="GPL", log_level=0, log_size=0, log_buf=NULL, kern_version=KERNEL_V
ERSION(0, 0, 0), prog_flags=0, prog_name="woo", prog_ifindex=0, expected_attach_type=BPF_CGROUP_INET_INGRESS}, 72) = 3
pause(

Π‘Π΅ Π΅ Π²ΠΎ Ρ€Π΅Π΄, bpf(2) Π½ΠΈ ја Π²Ρ€Π°Ρ‚ΠΈ Ρ€Π°Ρ‡ΠΊΠ°Ρ‚Π° 3 ΠΈ ΠΎΡ‚ΠΈΠ΄ΠΎΠ²ΠΌΠ΅ Π²ΠΎ бСсконСчна јамка со pause(). АјдС Π΄Π° сС ΠΎΠ±ΠΈΠ΄Π΅ΠΌΠ΅ Π΄Π° ја најдСмС Π½Π°ΡˆΠ°Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° Π²ΠΎ систСмот. Π—Π° Π΄Π° Π³ΠΎ Π½Π°ΠΏΡ€Π°Π²ΠΈΡ‚Π΅ ΠΎΠ²Π°, ќС ΠΎΠ΄ΠΈΠΌΠ΅ Π½Π° Π΄Ρ€ΡƒΠ³ Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π» ΠΈ ќС ја користимС Π°Π»Π°Ρ‚ΠΊΠ°Ρ‚Π° bpftool:

# bpftool prog | grep -A3 woo
390: xdp  name woo  tag 3b185187f1855c4c  gpl
        loaded_at 2020-08-31T24:66:44+0000  uid 0
        xlated 16B  jited 40B  memlock 4096B
        pids simple-prog(10381)

Π“Π»Π΅Π΄Π°ΠΌΠ΅ Π΄Π΅ΠΊΠ° ΠΈΠΌΠ° Π²Ρ‡ΠΈΡ‚Π°Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° Π½Π° систСмот woo Ρ‡ΠΈΡ˜ΡˆΡ‚ΠΎ Π³Π»ΠΎΠ±Π°Π»Π΅Π½ ID Π΅ 390 ΠΈ ΠΌΠΎΠΌΠ΅Π½Ρ‚Π°Π»Π½ΠΎ Π΅ Π²ΠΎ Ρ‚Π΅ΠΊ simple-prog ΠΈΠΌΠ° дСскриптор Π½Π° ΠΎΡ‚Π²ΠΎΡ€Π΅Π½Π° Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ° ΡˆΡ‚ΠΎ ΠΏΠΎΠΊΠ°ΠΆΡƒΠ²Π° Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° (ΠΈ Π°ΠΊΠΎ simple-prog Ρ‚ΠΎΠ³Π°Ρˆ ќС ја Π·Π°Π²Ρ€ΡˆΠΈ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚Π° woo ќС исчСзнС). ΠžΡ‡Π΅ΠΊΡƒΠ²Π°Π½ΠΎ, ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° woo Π·Π΅ΠΌΠ° 16 Π±Π°Ρ˜Ρ‚ΠΈ - Π΄Π²Π΅ инструкции - ΠΎΠ΄ Π±ΠΈΠ½Π°Ρ€Π½ΠΈ ΠΊΠΎΠ΄ΠΎΠ²ΠΈ Π²ΠΎ Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°Ρ‚Π° BPF, Π½ΠΎ Π²ΠΎ Π½Π΅Ρ˜Π·ΠΈΠ½Π°Ρ‚Π° ΠΌΠ°Ρ‚ΠΈΡ‡Π½Π° Ρ„ΠΎΡ€ΠΌΠ° (x86_64) вСќС Π΅ 40 Π±Π°Ρ˜Ρ‚ΠΈ. АјдС Π΄Π° ја ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ Π½Π°ΡˆΠ°Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° Π²ΠΎ Π½Π΅Ρ˜Π·ΠΈΠ½Π°Ρ‚Π° ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»Π½Π° Ρ„ΠΎΡ€ΠΌΠ°:

# bpftool prog dump xlated id 390
   0: (b7) r0 = 2
   1: (95) exit

Π½Π΅ΠΌΠ° ΠΈΠ·Π½Π΅Π½Π°Π΄ΡƒΠ²Π°ΡšΠ°. Π‘Π΅Π³Π° Π΄Π° Π³ΠΎ ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ ΠΊΠΎΠ΄ΠΎΡ‚ Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π°Π½ ΠΎΠ΄ ΠΊΠΎΠΌΠΏΠ°Ρ˜Π»Π΅Ρ€ΠΎΡ‚ JIT:

# bpftool prog dump jited id 390
bpf_prog_3b185187f1855c4c_woo:
   0:   nopl   0x0(%rax,%rax,1)
   5:   push   %rbp
   6:   mov    %rsp,%rbp
   9:   sub    $0x0,%rsp
  10:   push   %rbx
  11:   push   %r13
  13:   push   %r14
  15:   push   %r15
  17:   pushq  $0x0
  19:   mov    $0x2,%eax
  1e:   pop    %rbx
  1f:   pop    %r15
  21:   pop    %r14
  23:   pop    %r13
  25:   pop    %rbx
  26:   leaveq
  27:   retq

Π½Π΅ ΠΌΠ½ΠΎΠ³Ρƒ Сфикасни Π·Π° exit(2), Π½ΠΎ искрСно, Π½Π°ΡˆΠ°Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° Π΅ ΠΏΡ€Π΅ΠΌΠ½ΠΎΠ³Ρƒ Сдноставна, Π° Π·Π° Π½Π΅Ρ‚Ρ€ΠΈΠ²ΠΈΡ˜Π°Π»Π½ΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ, сСкако, сС ΠΏΠΎΡ‚Ρ€Π΅Π±Π½ΠΈ ΠΏΡ€ΠΎΠ»ΠΎΠ³ΠΎΡ‚ ΠΈ Π΅ΠΏΠΈΠ»ΠΎΠ³ΠΎΡ‚ Π΄ΠΎΠ΄Π°Π΄Π΅Π½ΠΈ ΠΎΠ΄ ΠΊΠΎΠΌΠΏΠ°Ρ˜Π»Π΅Ρ€ΠΎΡ‚ JIT.

Мапи

BPF ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ ΠΌΠΎΠΆΠ°Ρ‚ Π΄Π° користат структурирани мСмориски области ΠΊΠΎΠΈ сС достапни ΠΈ Π·Π° Π΄Ρ€ΡƒΠ³ΠΈΡ‚Π΅ BPF ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ ΠΈ Π·Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ Π²ΠΎ корисничкиот простор. ОвиС ΠΎΠ±Ρ˜Π΅ΠΊΡ‚ΠΈ сС Π½Π°Ρ€Π΅ΠΊΡƒΠ²Π°Π°Ρ‚ ΠΌΠ°ΠΏΠΈ ΠΈ Π²ΠΎ овој Π΄Π΅Π» ќС ΠΏΠΎΠΊΠ°ΠΆΠ΅ΠΌΠ΅ ΠΊΠ°ΠΊΠΎ Π΄Π° ΠΌΠ°Π½ΠΈΠΏΡƒΠ»ΠΈΡ€Π°ΠΌΠ΅ со Π½ΠΈΠ² ΠΊΠΎΡ€ΠΈΡΡ‚Π΅Ρ˜ΡœΠΈ систСмски ΠΏΠΎΠ²ΠΈΠΊ bpf.

Π’Π΅Π΄Π½Π°Ρˆ Π΄Π° ΠΊΠ°ΠΆΠ΅ΠΌΠ΅ Π΄Π΅ΠΊΠ° моТноститС Π½Π° ΠΌΠ°ΠΏΠΈΡ‚Π΅ Π½Π΅ сС ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈ само Π½Π° пристап Π΄ΠΎ Π·Π°Π΅Π΄Π½ΠΈΡ‡ΠΊΠ° ΠΌΠ΅ΠΌΠΎΡ€ΠΈΡ˜Π°. ΠŸΠΎΡΡ‚ΠΎΡ˜Π°Ρ‚ ΠΌΠ°ΠΏΠΈ Π·Π° ΡΠΏΠ΅Ρ†ΠΈΡ˜Π°Π»Π½Π° Π½Π°ΠΌΠ΅Π½Π° ΠΊΠΎΠΈ содрТат, Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΏΠΎΠΊΠ°ΠΆΡƒΠ²Π°Ρ‡ΠΈ ΠΊΠΎΠ½ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ BPF ΠΈΠ»ΠΈ ΠΏΠΎΠΊΠ°ΠΆΡƒΠ²Π°Ρ‡ΠΈ Π½Π° ΠΌΡ€Π΅ΠΆΠ½ΠΈΡ‚Π΅ ΠΈΠ½Ρ‚Π΅Ρ€Ρ„Π΅Ρ˜ΡΠΈ, ΠΌΠ°ΠΏΠΈ Π·Π° Ρ€Π°Π±ΠΎΡ‚Π° со настани Π½Π° ΠΏΠ΅Ρ€Ρ„ ΠΈΡ‚Π½. Π—Π° Π½ΠΈΠ² Π½Π΅ΠΌΠ° Π΄Π° Π·Π±ΠΎΡ€ΡƒΠ²Π°ΠΌΠ΅ ΠΎΠ²Π΄Π΅, Π·Π° Π΄Π° Π½Π΅ Π³ΠΎ Π·Π±ΡƒΠ½ΠΈΠΌΠ΅ Ρ‡ΠΈΡ‚Π°Ρ‚Π΅Π»ΠΎΡ‚. ОсвСн ΠΎΠ²Π°, Π³ΠΈ ΠΈΠ³Π½ΠΎΡ€ΠΈΡ€Π°ΠΌΠ΅ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΈΡ‚Π΅ Π·Π° ΡΠΈΠ½Ρ…Ρ€ΠΎΠ½ΠΈΠ·Π°Ρ†ΠΈΡ˜Π°, бидСјќи Ρ‚ΠΎΠ° Π½Π΅ Π΅ Π²Π°ΠΆΠ½ΠΎ Π·Π° Π½Π°ΡˆΠΈΡ‚Π΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΈ. ΠšΠΎΠΌΠΏΠ»Π΅Ρ‚Π½Π° листа Π½Π° достапни Ρ‚ΠΈΠΏΠΎΠ²ΠΈ ΠΌΠ°ΠΏΠΈ ΠΌΠΎΠΆΠ΅ Π΄Π° сС најдС Π²ΠΎ <linux/bpf.h>, Π° Π²ΠΎ овој Π΄Π΅Π» ΠΊΠ°ΠΊΠΎ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ќС Π³ΠΎ Π·Π΅ΠΌΠ΅ΠΌΠ΅ историски ΠΏΡ€Π²ΠΈΠΎΡ‚ Ρ‚ΠΈΠΏ, Ρ…Π΅Ρˆ Ρ‚Π°Π±Π΅Π»Π° BPF_MAP_TYPE_HASH.

Ако ΠΊΡ€Π΅ΠΈΡ€Π°Ρ‚Π΅ Ρ…Π΅Ρˆ-Ρ‚Π°Π±Π΅Π»Π° Π²ΠΎ, Π΄Π° Ρ€Π΅Ρ‡Π΅ΠΌΠ΅, C++, Π±ΠΈ Ρ€Π΅ΠΊΠ»Π΅ unordered_map<int,long> woo, ΡˆΡ‚ΠΎ Π½Π° руски Π·Π½Π°Ρ‡ΠΈ β€žΠœΠΈ Ρ‚Ρ€Π΅Π±Π° маса woo Π½Π΅ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½Π° Π³ΠΎΠ»Π΅ΠΌΠΈΠ½Π°, Ρ‡ΠΈΠΈ ΠΊΠ»ΡƒΡ‡Π΅Π²ΠΈ сС ΠΎΠ΄ Ρ‚ΠΈΠΏΠΎΡ‚ int, Π° врСдноститС сС Ρ‚ΠΈΠΏΠΎΡ‚ long" Π—Π° Π΄Π° создадСмС Ρ…Π°Ρˆ-Ρ‚Π°Π±Π΅Π»Π° BPF, Ρ‚Ρ€Π΅Π±Π° Π΄Π° Π³ΠΎ Π½Π°ΠΏΡ€Π°Π²ΠΈΠΌΠ΅ истото, освСн ΡˆΡ‚ΠΎ Ρ‚Ρ€Π΅Π±Π° Π΄Π° ја ΠΎΠ΄Ρ€Π΅Π΄ΠΈΠΌΠ΅ максималната Π³ΠΎΠ»Π΅ΠΌΠΈΠ½Π° Π½Π° Ρ‚Π°Π±Π΅Π»Π°Ρ‚Π° ΠΈ намСсто Π΄Π° Π³ΠΈ спСцифицирамС Ρ‚ΠΈΠΏΠΎΠ²ΠΈΡ‚Π΅ Π½Π° ΠΊΠ»ΡƒΡ‡Π΅Π²ΠΈ ΠΈ врСдности, Ρ‚Ρ€Π΅Π±Π° Π΄Π° Π³ΠΈ спСцифицирамС Π½ΠΈΠ²Π½ΠΈΡ‚Π΅ Π³ΠΎΠ»Π΅ΠΌΠΈΠ½ΠΈ Π²ΠΎ Π±Π°Ρ˜Ρ‚ΠΈ. . Π—Π° Π΄Π° ΠΊΡ€Π΅ΠΈΡ€Π°Ρ‚Π΅ ΠΌΠ°ΠΏΠΈ користСтС ја ΠΊΠΎΠΌΠ°Π½Π΄Π°Ρ‚Π° BPF_MAP_CREATE систСмски ΠΏΠΎΠ²ΠΈΠΊ bpf. АјдС Π΄Π° ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ повСќС ΠΈΠ»ΠΈ ΠΏΠΎΠΌΠ°Π»ΠΊΡƒ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° ΡˆΡ‚ΠΎ создава ΠΌΠ°ΠΏΠ°. По ΠΏΡ€Π΅Ρ‚Ρ…ΠΎΠ΄Π½Π°Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° ΡˆΡ‚ΠΎ Π³ΠΈ Π²Ρ‡ΠΈΡ‚ΡƒΠ²Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ BPF, ΠΎΠ²Π°Π° Ρ‚Ρ€Π΅Π±Π° Π΄Π° Π²ΠΈ ΠΈΠ·Π³Π»Π΅Π΄Π° Сдноставна:

$ cat simple-map.c
#define _GNU_SOURCE
#include <string.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <linux/bpf.h>

int main(void)
{
    union bpf_attr attr = {
        .map_type = BPF_MAP_TYPE_HASH,
        .key_size = sizeof(int),
        .value_size = sizeof(int),
        .max_entries = 4,
    };
    strncpy(attr.map_name, "woo", sizeof(attr.map_name));
    syscall(__NR_bpf, BPF_MAP_CREATE, &attr, sizeof(attr));

    for ( ;; )
        pause();
}

ОвдС Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ€Π°ΠΌΠ΅ Π·Π±ΠΈΡ€ Π½Π° ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈ attr, Π²ΠΎ која Π²Π΅Π»ΠΈΠΌΠ΅ β€žΠœΠΈ Ρ‚Ρ€Π΅Π±Π° Ρ…Π°Ρˆ Ρ‚Π°Π±Π΅Π»Π° со ΠΊΠ»ΡƒΡ‡Π΅Π²ΠΈ ΠΈ врСдности Π·Π° Π³ΠΎΠ»Π΅ΠΌΠΈΠ½Π° sizeof(int), Π²ΠΎ кој ΠΌΠΎΠΆΠ°ΠΌ Π΄Π° ставам Π½Π°Ρ˜ΠΌΠ½ΠΎΠ³Ρƒ Ρ‡Π΅Ρ‚ΠΈΡ€ΠΈ Π΅Π»Π΅ΠΌΠ΅Π½Ρ‚ΠΈβ€œ. Кога ΠΊΡ€Π΅ΠΈΡ€Π°Ρ‚Π΅ ΠΌΠ°ΠΏΠΈ BPF, ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Π½Π°Π²Π΅Π΄Π΅Ρ‚Π΅ Π΄Ρ€ΡƒΠ³ΠΈ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈ, Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π½Π° ист Π½Π°Ρ‡ΠΈΠ½ ΠΊΠ°ΠΊΠΎ Π²ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΡ‚ со ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π°, Π³ΠΎ Π½Π°Π²Π΅Π΄ΠΎΠ²ΠΌΠ΅ ΠΈΠΌΠ΅Ρ‚ΠΎ Π½Π° ΠΎΠ±Ρ˜Π΅ΠΊΡ‚ΠΎΡ‚ ΠΊΠ°ΠΊΠΎ "woo".

АјдС Π΄Π° ја ΠΊΠΎΠΌΠΏΠ°Ρ˜Π»ΠΈΡ€Π°ΠΌΠ΅ ΠΈ ΠΈΠ·Π²Ρ€ΡˆΠΈΠΌΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π°:

$ clang -g -O2 simple-map.c -o simple-map
$ sudo strace ./simple-map
execve("./simple-map", ["./simple-map"], 0x7ffd40a27070 /* 14 vars */) = 0
...
bpf(BPF_MAP_CREATE, {map_type=BPF_MAP_TYPE_HASH, key_size=4, value_size=4, max_entries=4, map_name="woo", ...}, 72) = 3
pause(

Π•Π²Π΅ Π³ΠΎ систСмскиот ΠΏΠΎΠ²ΠΈΠΊ bpf(2) Π½ΠΈ Π³ΠΎ Π²Ρ€Π°Ρ‚ΠΈ дСскрипторот Π½Π° ΠΌΠ°ΠΏΠ°Ρ‚Π° 3 Π° ΠΏΠΎΡ‚ΠΎΠ° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π°, ΠΊΠ°ΠΊΠΎ ΡˆΡ‚ΠΎ сС ΠΎΡ‡Π΅ΠΊΡƒΠ²Π°ΡˆΠ΅, Ρ‡Π΅ΠΊΠ° Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»Π½ΠΈ инструкции Π²ΠΎ систСмскиот ΠΏΠΎΠ²ΠΈΠΊ pause(2).

Π‘Π΅Π³Π° Π΄Π° ја испратимС Π½Π°ΡˆΠ°Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° Π²ΠΎ ΠΏΠΎΠ·Π°Π΄ΠΈΠ½Π° ΠΈΠ»ΠΈ Π΄Π° ΠΎΡ‚Π²ΠΎΡ€ΠΈΠΌΠ΅ Π΄Ρ€ΡƒΠ³ Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π» ΠΈ Π΄Π° Π³ΠΎ ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ Π½Π°ΡˆΠΈΠΎΡ‚ ΠΎΠ±Ρ˜Π΅ΠΊΡ‚ ΠΊΠΎΡ€ΠΈΡΡ‚Π΅Ρ˜ΡœΠΈ ја Π°Π»Π°Ρ‚ΠΊΠ°Ρ‚Π° bpftool (ΠΌΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° ја Ρ€Π°Π·Π»ΠΈΠΊΡƒΠ²Π°ΠΌΠ΅ Π½Π°ΡˆΠ°Ρ‚Π° ΠΊΠ°Ρ€Ρ‚Π° ΠΎΠ΄ Π΄Ρ€ΡƒΠ³ΠΈΡ‚Π΅ ΠΏΠΎ Π½Π΅Ρ˜Π·ΠΈΠ½ΠΎΡ‚ΠΎ ΠΈΠΌΠ΅):

$ sudo bpftool map
...
114: hash  name woo  flags 0x0
        key 4B  value 4B  max_entries 4  memlock 4096B
...

Π‘Ρ€ΠΎΡ˜ΠΎΡ‚ 114 Π΅ Π³Π»ΠΎΠ±Π°Π»Π½ΠΈΠΎΡ‚ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ Π½Π° Π½Π°ΡˆΠΈΠΎΡ‚ ΠΎΠ±Ρ˜Π΅ΠΊΡ‚. БСкоја ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° Π½Π° систСмот ΠΌΠΎΠΆΠ΅ Π΄Π° Π³ΠΎ користи овој ID Π·Π° Π΄Π° ΠΎΡ‚Π²ΠΎΡ€ΠΈ постоСчка ΠΌΠ°ΠΏΠ° ΠΊΠΎΡ€ΠΈΡΡ‚Π΅Ρ˜ΡœΠΈ ја ΠΊΠΎΠΌΠ°Π½Π΄Π°Ρ‚Π° BPF_MAP_GET_FD_BY_ID систСмски ΠΏΠΎΠ²ΠΈΠΊ bpf.

Π‘Π΅Π³Π° ΠΌΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° си ΠΈΠ³Ρ€Π°ΠΌΠ΅ со Π½Π°ΡˆΠ°Ρ‚Π° Ρ…Π°Ρˆ-Ρ‚Π°Π±Π΅Π»Π°. Π”Π° ја ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ Π½Π΅Π³ΠΎΠ²Π°Ρ‚Π° содрТина:

$ sudo bpftool map dump id 114
Found 0 elements

ΠŸΡ€Π°Π·Π΅Π½. АјдС Π΄Π° ставимС врСдност Π²ΠΎ Ρ‚ΠΎΠ° hash[1] = 1:

$ sudo bpftool map update id 114 key 1 0 0 0 value 1 0 0 0

АјдС ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎ Π΄Π° ја ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ Ρ‚Π°Π±Π΅Π»Π°Ρ‚Π°:

$ sudo bpftool map dump id 114
key: 01 00 00 00  value: 01 00 00 00
Found 1 element

Π£Ρ€Π°! УспСавмС Π΄Π° Π΄ΠΎΠ΄Π°Π΄Π΅ΠΌΠ΅ Π΅Π΄Π΅Π½ Π΅Π»Π΅ΠΌΠ΅Π½Ρ‚. Π—Π°Π±Π΅Π»Π΅ΠΆΠ΅Ρ‚Π΅ Π΄Π΅ΠΊΠ° ΠΌΠΎΡ€Π° Π΄Π° Ρ€Π°Π±ΠΎΡ‚ΠΈΠΌΠ΅ Π½Π° Π½ΠΈΠ²ΠΎ Π½Π° Π±Π°Ρ˜Ρ‚ΠΈ Π·Π° Π΄Π° Π³ΠΎ Π½Π°ΠΏΡ€Π°Π²ΠΈΠΌΠ΅ ΠΎΠ²Π°, бидСјќи bptftool Π½Π΅ Π·Π½Π°Π΅ ΠΊΠ°ΠΊΠΎΠ² Ρ‚ΠΈΠΏ сС врСдноститС Π²ΠΎ Ρ‚Π°Π±Π΅Π»Π°Ρ‚Π° Π·Π° Ρ…Π°Ρˆ. (Ова знаСњС ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΈ сС прСнСсС со помош Π½Π° BTF, Π½ΠΎ повСќС Π·Π° Ρ‚ΠΎΠ° сСга.)

Како Ρ‚ΠΎΡ‡Π½ΠΎ bpftool Ρ‡ΠΈΡ‚Π° ΠΈ Π΄ΠΎΠ΄Π°Π²Π° Π΅Π»Π΅ΠΌΠ΅Π½Ρ‚ΠΈ? АјдС Π΄Π° ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ ΠΏΠΎΠ΄ Ρ…Π°ΡƒΠ±Π°Ρ‚Π°:

$ sudo strace -e bpf bpftool map dump id 114
bpf(BPF_MAP_GET_FD_BY_ID, {map_id=114, next_id=0, open_flags=0}, 120) = 3
bpf(BPF_MAP_GET_NEXT_KEY, {map_fd=3, key=NULL, next_key=0x55856ab65280}, 120) = 0
bpf(BPF_MAP_LOOKUP_ELEM, {map_fd=3, key=0x55856ab65280, value=0x55856ab652a0}, 120) = 0
key: 01 00 00 00  value: 01 00 00 00
bpf(BPF_MAP_GET_NEXT_KEY, {map_fd=3, key=0x55856ab65280, next_key=0x55856ab65280}, 120) = -1 ENOENT

ΠŸΡ€Π²ΠΎ ја ΠΎΡ‚Π²ΠΎΡ€ΠΈΠ²ΠΌΠ΅ ΠΌΠ°ΠΏΠ°Ρ‚Π° со Π½Π΅Ρ˜Π·ΠΈΠ½ΠΈΠΎΡ‚ Π³Π»ΠΎΠ±Π°Π»Π΅Π½ ID ΠΊΠΎΡ€ΠΈΡΡ‚Π΅Ρ˜ΡœΠΈ ја ΠΊΠΎΠΌΠ°Π½Π΄Π°Ρ‚Π° BPF_MAP_GET_FD_BY_ID ΠΈ bpf(2) Π½ΠΈ Π³ΠΎ Π²Ρ€Π°Ρ‚ΠΈ дСскрипторот 3. ΠŸΠΎΠ½Π°Ρ‚Π°ΠΌΠΎΡˆΠ½ΠΎ ΠΊΠΎΡ€ΠΈΡΡ‚Π΅ΡšΠ΅ Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄Π°Ρ‚Π° BPF_MAP_GET_NEXT_KEY Π³ΠΎ најдовмС ΠΏΡ€Π²ΠΈΠΎΡ‚ ΠΊΠ»ΡƒΡ‡ Π²ΠΎ Ρ‚Π°Π±Π΅Π»Π°Ρ‚Π° со полагањС NULL ΠΊΠ°ΠΊΠΎ ΠΏΠΎΠΊΠ°ΠΆΡƒΠ²Π°Ρ‡ Π½Π° ΠΊΠΎΠΏΡ‡Π΅Ρ‚ΠΎ β€žΠΏΡ€Π΅Ρ‚Ρ…ΠΎΠ΄Π½ΠΎβ€œ. Ако Π³ΠΎ ΠΈΠΌΠ°ΠΌΠ΅ ΠΊΠ»ΡƒΡ‡ΠΎΡ‚, ΠΌΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° Π½Π°ΠΏΡ€Π°Π²ΠΈΠΌΠ΅ BPF_MAP_LOOKUP_ELEMкој Π²Ρ€Π°ΡœΠ° врСдност Π½Π° ΠΏΠΎΠΊΠ°ΠΆΡƒΠ²Π°Ρ‡ΠΎΡ‚ value. Π‘Π»Π΅Π΄Π½ΠΈΠΎΡ‚ Ρ‡Π΅ΠΊΠΎΡ€ Π΅ Π΄Π° сС ΠΎΠ±ΠΈΠ΄Π΅ΠΌΠ΅ Π΄Π° Π³ΠΎ најдСмС слСдниот Π΅Π»Π΅ΠΌΠ΅Π½Ρ‚ со ΠΏΡ€Π΅Π΄Π°Π²Π°ΡšΠ΅ ΠΏΠΎΠΊΠ°ΠΆΡƒΠ²Π°Ρ‡ Π½Π° Ρ‚Π΅ΠΊΠΎΠ²Π½ΠΈΠΎΡ‚ ΠΊΠ»ΡƒΡ‡, Π½ΠΎ Π½Π°ΡˆΠ°Ρ‚Π° Ρ‚Π°Π±Π΅Π»Π° содрТи само Π΅Π΄Π΅Π½ Π΅Π»Π΅ΠΌΠ΅Π½Ρ‚ ΠΈ ΠΊΠΎΠΌΠ°Π½Π΄Π°Ρ‚Π° BPF_MAP_GET_NEXT_KEY сС Π²Ρ€Π°ΡœΠ° ENOENT.

Π”ΠΎΠ±Ρ€ΠΎ, ајдС Π΄Π° ја ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈΠΌΠ΅ врСдноста со ΠΊΠ»ΡƒΡ‡ΠΎΡ‚ 1, Π΄Π° Ρ€Π΅Ρ‡Π΅ΠΌΠ΅ Π΄Π΅ΠΊΠ° Π½Π°ΡˆΠ°Ρ‚Π° Π΄Π΅Π»ΠΎΠ²Π½Π° Π»ΠΎΠ³ΠΈΠΊΠ° Π±Π°Ρ€Π° Ρ€Π΅Π³ΠΈΡΡ‚Ρ€Π°Ρ†ΠΈΡ˜Π° hash[1] = 2:

$ sudo strace -e bpf bpftool map update id 114 key 1 0 0 0 value 2 0 0 0
bpf(BPF_MAP_GET_FD_BY_ID, {map_id=114, next_id=0, open_flags=0}, 120) = 3
bpf(BPF_MAP_UPDATE_ELEM, {map_fd=3, key=0x55dcd72be260, value=0x55dcd72be280, flags=BPF_ANY}, 120) = 0

Како ΡˆΡ‚ΠΎ сС ΠΎΡ‡Π΅ΠΊΡƒΠ²Π°ΡˆΠ΅, Ρ‚ΠΎΠ° Π΅ ΠΌΠ½ΠΎΠ³Ρƒ Сдноставно: ΠΊΠΎΠΌΠ°Π½Π΄Π°Ρ‚Π° BPF_MAP_GET_FD_BY_ID ја ΠΎΡ‚Π²ΠΎΡ€Π° Π½Π°ΡˆΠ°Ρ‚Π° ΠΊΠ°Ρ€Ρ‚Π° ΠΏΠΎ ID, ΠΈ ΠΊΠΎΠΌΠ°Π½Π΄Π°Ρ‚Π° BPF_MAP_UPDATE_ELEM Π³ΠΎ ΠΏΡ€Π΅ΠΏΠΈΡˆΡƒΠ²Π° Π΅Π»Π΅ΠΌΠ΅Π½Ρ‚ΠΎΡ‚.

Π—Π½Π°Ρ‡ΠΈ, ΠΎΡ‚ΠΊΠ°ΠΊΠΎ ќС ΠΊΡ€Π΅ΠΈΡ€Π°ΠΌΠ΅ Ρ…Π΅Ρˆ-Ρ‚Π°Π±Π΅Π»Π° ΠΎΠ΄ Π΅Π΄Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°, ΠΌΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° ја Ρ‡ΠΈΡ‚Π°ΠΌΠ΅ ΠΈ ΠΏΠΈΡˆΡƒΠ²Π°ΠΌΠ΅ Π½Π΅Ρ˜Π·ΠΈΠ½Π°Ρ‚Π° содрТина ΠΎΠ΄ Π΄Ρ€ΡƒΠ³Π°. Π—Π°Π±Π΅Π»Π΅ΠΆΠ΅Ρ‚Π΅ Π΄Π΅ΠΊΠ° Π°ΠΊΠΎ ΠΌΠΎΠΆΠ΅Π²ΠΌΠ΅ Π΄Π° Π³ΠΎ Π½Π°ΠΏΡ€Π°Π²ΠΈΠΌΠ΅ ΠΎΠ²Π° ΠΎΠ΄ ΠΊΠΎΠΌΠ°Π½Π΄Π½Π°Ρ‚Π° линија, Ρ‚ΠΎΠ³Π°Ρˆ која Π±ΠΈΠ»ΠΎ Π΄Ρ€ΡƒΠ³Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° Π½Π° систСмот ΠΌΠΎΠΆΠ΅ Π΄Π° Π³ΠΎ Π½Π°ΠΏΡ€Π°Π²ΠΈ Ρ‚ΠΎΠ°. ΠŸΠΎΠΊΡ€Π°Ρ˜ ΠΊΠΎΠΌΠ°Π½Π΄ΠΈΡ‚Π΅ опишани ΠΏΠΎΠ³ΠΎΡ€Π΅, Π·Π° Ρ€Π°Π±ΠΎΡ‚Π° со ΠΌΠ°ΠΏΠΈ ΠΎΠ΄ корисничкиот простор, Π‘Π»Π΅Π΄Π½ΠΈΠ²Π΅:

  • BPF_MAP_LOOKUP_ELEM: Π½Π°Ρ˜Π΄Π΅Ρ‚Π΅ врСдност ΠΏΠΎ ΠΊΠ»ΡƒΡ‡
  • BPF_MAP_UPDATE_ELEM: Π°ΠΆΡƒΡ€ΠΈΡ€Π°ΡšΠ΅/создадСтС врСдност
  • BPF_MAP_DELETE_ELEM: ΠΈΠ·Π²Π°Π΄Π΅Ρ‚Π΅ Π³ΠΎ ΠΊΠ»ΡƒΡ‡ΠΎΡ‚
  • BPF_MAP_GET_NEXT_KEY: Π½Π°Ρ˜Π΄Π΅Ρ‚Π΅ Π³ΠΎ слСдниот (ΠΈΠ»ΠΈ ΠΏΡ€Π²ΠΈΠΎΡ‚) ΠΊΠ»ΡƒΡ‡
  • BPF_MAP_GET_NEXT_ID: Π²ΠΈ ΠΎΠ²ΠΎΠ·ΠΌΠΎΠΆΡƒΠ²Π° Π΄Π° Π³ΠΈ ΠΏΠΎΠΌΠΈΠ½Π΅Ρ‚Π΅ ситС постоСчки ΠΌΠ°ΠΏΠΈ, Ρ‚Π°ΠΊΠ° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½ΠΈΡ€Π° bpftool map
  • BPF_MAP_GET_FD_BY_ID: ΠΎΡ‚Π²ΠΎΡ€Π΅Ρ‚Π΅ постоСчка ΠΊΠ°Ρ€Ρ‚Π° спорСд Π½Π΅Ρ˜Π·ΠΈΠ½ΠΈΠΎΡ‚ Π³Π»ΠΎΠ±Π°Π»Π΅Π½ 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 (Π½ΠΈΠ΅ ΠΎΠΏΠΈΡˆΡƒΠ²Π°ΠΌΠ΅ ΠΊΠ°ΠΊΠΎ Π΄Π° Π³ΠΎ Π½Π°ΠΏΡ€Π°Π²ΠΈΡ‚Π΅ ΠΎΠ²Π° Π²ΠΎ Π΄Π΅Π»ΠΎΡ‚ Алатки Π·Π° Ρ€Π°Π·Π²ΠΎΡ˜. ΠœΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚Π΅ Π΄Π°Π»ΠΈ Π²Π°ΡˆΠΈΠΎΡ‚ ΠΊΠ΅Ρ€Π½Π΅Π» Π΅ ΠΈΠ·Π³Ρ€Π°Π΄Π΅Π½ со 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]. Π‘Π΅ΠΏΠ°ΠΊ, сС ΠΎΠ΄Ρ€ΠΆΡƒΠ²Π° посСбно ΡΠΊΠ»Π°Π΄ΠΈΡˆΡ‚Π΅ Π·Π° ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅ Π½Π° Π°ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΠΈΡ‚Π΅ ΠΊΠΎΠΈ ΠΆΠΈΠ²Π΅Π°Ρ‚ Π½Π°Π΄Π²ΠΎΡ€ ΠΎΠ΄ ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚ https://github.com/libbpf/libbpf Π²ΠΎ која Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°Ρ‚Π° Π½Π° Ρ˜Π°Π΄Ρ€ΠΎΡ‚ΠΎ Π΅ прСсликана Π·Π° пристап Π·Π° Ρ‡ΠΈΡ‚Π°ΡšΠ΅ повСќС ΠΈΠ»ΠΈ ΠΏΠΎΠΌΠ°Π»ΠΊΡƒ ΠΊΠ°ΠΊΠΎ ΡˆΡ‚ΠΎ Π΅.

Π’ΠΎ овој Π΄Π΅Π» ќС ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ ΠΊΠ°ΠΊΠΎ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° ΠΊΡ€Π΅ΠΈΡ€Π°Ρ‚Π΅ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ ΡˆΡ‚ΠΎ користи libbpf, Π΄Π° напишСмС Π½Π΅ΠΊΠΎΠ»ΠΊΡƒ (повСќС ΠΈΠ»ΠΈ ΠΏΠΎΠΌΠ°Π»ΠΊΡƒ бСсмислСни) ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ Π·Π° Ρ‚Π΅ΡΡ‚ΠΈΡ€Π°ΡšΠ΅ ΠΈ Π΄Π΅Ρ‚Π°Π»Π½ΠΎ Π΄Π° Π°Π½Π°Π»ΠΈΠ·ΠΈΡ€Π°ΠΌΠ΅ ΠΊΠ°ΠΊΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½ΠΈΡ€Π° сСто Ρ‚ΠΎΠ°. Ова ќС Π½ΠΈ ΠΎΠ²ΠΎΠ·ΠΌΠΎΠΆΠΈ полСсно Π΄Π° објаснимС Π²ΠΎ слСднитС Π΄Π΅Π»ΠΎΠ²ΠΈ Ρ‚ΠΎΡ‡Π½ΠΎ ΠΊΠ°ΠΊΠΎ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ BPF ΠΊΠΎΠΌΡƒΠ½ΠΈΡ†ΠΈΡ€Π°Π°Ρ‚ со ΠΌΠ°ΠΏΠΈ, ΠΏΠΎΠΌΠ°Π³Π°Ρ‡ΠΈ Π½Π° ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚, BTF ΠΈΡ‚Π½.

ΠžΠ±ΠΈΡ‡Π½ΠΎ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΈ користат libbpf Π΄ΠΎΠ΄Π°Π΄Π΅Ρ‚Π΅ ΡΠΊΠ»Π°Π΄ΠΈΡˆΡ‚Π΅ Π½Π° GitHub ΠΊΠ°ΠΊΠΎ ΠΏΠΎΠ΄ΠΌΠΎΠ΄ΡƒΠ» Π·Π° git, Π½ΠΈΠ΅ ќС Π³ΠΎ сторимС истото:

$ mkdir /tmp/libbpf-example
$ cd /tmp/libbpf-example/
$ git init-db
Initialized empty Git repository in /tmp/libbpf-example/.git/
$ git submodule add https://github.com/libbpf/libbpf.git
Cloning into '/tmp/libbpf-example/libbpf'...
remote: Enumerating objects: 200, done.
remote: Counting objects: 100% (200/200), done.
remote: Compressing objects: 100% (103/103), done.
remote: Total 3354 (delta 101), reused 118 (delta 79), pack-reused 3154
Receiving objects: 100% (3354/3354), 2.05 MiB | 10.22 MiB/s, done.
Resolving deltas: 100% (2176/2176), done.

ОдСњС Π½Π° libbpf ΠΌΠ½ΠΎΠ³Ρƒ Сдноставно:

$ cd libbpf/src
$ mkdir build
$ OBJDIR=build DESTDIR=root make -s install
$ find root
root
root/usr
root/usr/include
root/usr/include/bpf
root/usr/include/bpf/bpf_tracing.h
root/usr/include/bpf/xsk.h
root/usr/include/bpf/libbpf_common.h
root/usr/include/bpf/bpf_endian.h
root/usr/include/bpf/bpf_helpers.h
root/usr/include/bpf/btf.h
root/usr/include/bpf/bpf_helper_defs.h
root/usr/include/bpf/bpf.h
root/usr/include/bpf/libbpf_util.h
root/usr/include/bpf/libbpf.h
root/usr/include/bpf/bpf_core_read.h
root/usr/lib64
root/usr/lib64/libbpf.so.0.1.0
root/usr/lib64/libbpf.so.0
root/usr/lib64/libbpf.a
root/usr/lib64/libbpf.so
root/usr/lib64/pkgconfig
root/usr/lib64/pkgconfig/libbpf.pc

ΠΠ°ΡˆΠΈΠΎΡ‚ слСдСн ΠΏΠ»Π°Π½ Π²ΠΎ овој Π΄Π΅Π» Π΅ ΠΊΠ°ΠΊΠΎ ΡˆΡ‚ΠΎ слСдува: ќС напишСмС BPF ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° ΠΊΠ°ΠΊΠΎ BPF_PROG_TYPE_XDP, исто ΠΊΠ°ΠΊΠΎ ΠΈ Π²ΠΎ ΠΏΡ€Π΅Ρ‚Ρ…ΠΎΠ΄Π½ΠΈΠΎΡ‚ ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π½ΠΎ Π²ΠΎ C, Π³ΠΎ ΠΊΠΎΠΌΠΏΠ°Ρ˜Π»ΠΈΡ€Π°ΠΌΠ΅ ΠΊΠΎΡ€ΠΈΡΡ‚Π΅Ρ˜ΡœΠΈ clang, ΠΈ Π½Π°ΠΏΠΈΡˆΠ΅Ρ‚Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° Π·Π° помош која ќС ја Π²Ρ‡ΠΈΡ‚Π° Π²ΠΎ Ρ˜Π°Π΄Ρ€ΠΎΡ‚ΠΎ. Π’ΠΎ слСднитС Π΄Π΅Π»ΠΎΠ²ΠΈ ќС Π³ΠΈ ΠΏΡ€ΠΎΡˆΠΈΡ€ΠΈΠΌΠ΅ моТноститС ΠΈ Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° BPF ΠΈ Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° Π·Π° помошник.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€: создавањС Π½Π° ΠΏΠΎΠ»Π½ΠΎΠΏΡ€Π°Π²Π½Π° Π°ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΡ˜Π° ΠΊΠΎΡ€ΠΈΡΡ‚Π΅Ρ˜ΡœΠΈ libbpf

Π—Π° ΠΏΠΎΡ‡Π΅Ρ‚ΠΎΠΊ, ја користимС Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ°Ρ‚Π° /sys/kernel/btf/vmlinux, ΡˆΡ‚ΠΎ бСшС спомСнато ΠΏΠΎΠ³ΠΎΡ€Π΅, ΠΈ ΠΊΡ€Π΅ΠΈΡ€Π°Ρ˜Ρ‚Π΅ Π³ΠΎ Π½Π΅Π³ΠΎΠ²ΠΈΠΎΡ‚ Π΅ΠΊΠ²ΠΈΠ²Π°Π»Π΅Π½Ρ‚ Π²ΠΎ Ρ„ΠΎΡ€ΠΌΠ° Π½Π° Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ° Π·Π° Π·Π°Π³Π»Π°Π²ΠΈΠ΅:

$ bpftool btf dump file /sys/kernel/btf/vmlinux format c > vmlinux.h

Оваа Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ° ќС Π³ΠΈ складира ситС структури Π½Π° ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈ достапни Π²ΠΎ Π½Π°ΡˆΠΈΠΎΡ‚ ΠΊΠ΅Ρ€Π½Π΅Π», Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π²Π°ΠΊΠ° сС Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ€Π° Π·Π°Π³Π»Π°Π²ΠΈΠ΅Ρ‚ΠΎ IPv4 Π²ΠΎ ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚:

$ grep -A 12 'struct iphdr {' vmlinux.h
struct iphdr {
    __u8 ihl: 4;
    __u8 version: 4;
    __u8 tos;
    __be16 tot_len;
    __be16 id;
    __be16 frag_off;
    __u8 ttl;
    __u8 protocol;
    __sum16 check;
    __be32 saddr;
    __be32 daddr;
};

Π‘Π΅Π³Π° ќС ја напишСмС Π½Π°ΡˆΠ°Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° BPF Π²ΠΎ C:

$ cat xdp-simple.bpf.c
#include "vmlinux.h"
#include <bpf/bpf_helpers.h>

SEC("xdp/simple")
int simple(void *ctx)
{
        return XDP_PASS;
}

char LICENSE[] SEC("license") = "GPL";

Иако Π½Π°ΡˆΠ°Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° сС ΠΏΠΎΠΊΠ°ΠΆΠ° ΠΊΠ°ΠΊΠΎ ΠΌΠ½ΠΎΠ³Ρƒ Сдноставна, сСпак Ρ‚Ρ€Π΅Π±Π° Π΄Π° ΠΎΠ±Ρ€Π½Π΅ΠΌΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° ΠΌΠ½ΠΎΠ³Ρƒ Π΄Π΅Ρ‚Π°Π»ΠΈ. ΠŸΡ€Π²ΠΎ, ΠΏΡ€Π²Π°Ρ‚Π° Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ° со Π·Π°Π³Π»Π°Π²ΠΈΠ΅ ΡˆΡ‚ΠΎ ја Π²ΠΊΠ»ΡƒΡ‡ΡƒΠ²Π°ΠΌΠ΅ Π΅ vmlinux.h, кој ΡˆΡ‚ΠΎΡ‚ΡƒΠΊΡƒ Π³ΠΎ Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π°Π²ΠΌΠ΅ ΠΊΠΎΡ€ΠΈΡΡ‚Π΅Ρ˜ΡœΠΈ Π³ΠΎ bpftool btf dump - сСга Π½Π΅ Ρ‚Ρ€Π΅Π±Π° Π΄Π° Π³ΠΎ инсталирамС ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΡ‚ ΠΊΠ΅Ρ€Π½Π΅Π»-заглавија Π·Π° Π΄Π° Π΄ΠΎΠ·Π½Π°Π΅ΠΌΠ΅ ΠΊΠ°ΠΊΠΎ ΠΈΠ·Π³Π»Π΅Π΄Π°Π°Ρ‚ структуритС Π½Π° Ρ˜Π°Π΄Ρ€ΠΎΡ‚ΠΎ. Π‘Π»Π΅Π΄Π½Π°Ρ‚Π° Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ° со Π·Π°Π³Π»Π°Π²ΠΈΠ΅ Π΄ΠΎΠ°Ρ“Π° кај нас ΠΎΠ΄ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°Ρ‚Π° libbpf. Π‘Π΅Π³Π° Π½ΠΈ Ρ‚Ρ€Π΅Π±Π° само Π·Π° Π΄Π° Π³ΠΎ Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ€Π°ΠΌΠ΅ ΠΌΠ°ΠΊΡ€ΠΎΡ‚ΠΎ SEC, кој Π³ΠΎ ΠΈΡΠΏΡ€Π°ΡœΠ° Π·Π½Π°ΠΊΠΎΡ‚ Π΄ΠΎ соодвСтниот Π΄Π΅Π» ΠΎΠ΄ Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ°Ρ‚Π° со ΠΎΠ±Ρ˜Π΅ΠΊΡ‚ ELF. ΠΠ°ΡˆΠ°Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° Π΅ содрТана Π²ΠΎ Π΄Π΅Π»ΠΎΡ‚ xdp/simple, ΠΊΠ°Π΄Π΅ ΡˆΡ‚ΠΎ ΠΏΡ€Π΅Π΄ коса Ρ†Ρ€Ρ‚Π° Π³ΠΎ Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ€Π°ΠΌΠ΅ Ρ‚ΠΈΠΏΠΎΡ‚ Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° BPF - ΠΎΠ²Π° Π΅ ΠΊΠΎΠ½Π²Π΅Π½Ρ†ΠΈΡ˜Π°Ρ‚Π° ΡˆΡ‚ΠΎ сС користи Π²ΠΎ libbpf, Π²Ρ€Π· основа Π½Π° ΠΈΠΌΠ΅Ρ‚ΠΎ Π½Π° Π΄Π΅Π»ΠΎΡ‚ ќС Π³ΠΎ Π·Π°ΠΌΠ΅Π½ΠΈ Ρ‚ΠΎΡ‡Π½ΠΈΠΎΡ‚ Ρ‚ΠΈΠΏ ΠΏΡ€ΠΈ ΡΡ‚Π°Ρ€Ρ‚ΡƒΠ²Π°ΡšΠ΅ bpf(2). Π‘Π°ΠΌΠ°Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° BPF Π΅ C - ΠΌΠ½ΠΎΠ³Ρƒ Сдноставно ΠΈ сС состои ΠΎΠ΄ Π΅Π΄Π½Π° линија return XDP_PASS. ΠšΠΎΠ½Π΅Ρ‡Π½ΠΎ, посСбСн Π΄Π΅Π» "license" Π³ΠΎ содрТи ΠΈΠΌΠ΅Ρ‚ΠΎ Π½Π° Π»ΠΈΡ†Π΅Π½Ρ†Π°Ρ‚Π°.

МоТСмС Π΄Π° ја ΠΊΠΎΠΌΠΏΠ°Ρ˜Π»ΠΈΡ€Π°ΠΌΠ΅ Π½Π°ΡˆΠ°Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° ΠΊΠΎΡ€ΠΈΡΡ‚Π΅Ρ˜ΡœΠΈ llvm/clang, Π²Π΅Ρ€Π·ΠΈΡ˜Π° >= 10.0.0, ΠΈΠ»ΠΈ ΡƒΡˆΡ‚Π΅ ΠΏΠΎΠ΄ΠΎΠ±Ρ€ΠΎ, ΠΏΠΎΠ³ΠΎΠ»Π΅ΠΌΠ° (Π²ΠΈΠ΄ΠΈ Π΄Π΅Π» Алатки Π·Π° Ρ€Π°Π·Π²ΠΎΡ˜):

$ clang --version
clang version 11.0.0 (https://github.com/llvm/llvm-project.git afc287e0abec710398465ee1f86237513f2b5091)
...

$ clang -O2 -g -c -target bpf -I libbpf/src/root/usr/include xdp-simple.bpf.c -o xdp-simple.bpf.o

ΠœΠ΅Ρ“Ρƒ интСрСснитС карактСристики: ја посочувамС Ρ†Π΅Π»Π½Π°Ρ‚Π° Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π° -target bpf ΠΈ ΠΏΠ°Ρ‚ΠΎΡ‚ Π΄ΠΎ Π·Π°Π³Π»Π°Π²ΠΈΡ˜Π°Ρ‚Π° libbpf, кој Π½Π΅ΠΎΠ΄Π°ΠΌΠ½Π° Π³ΠΎ инсталиравмС. Π˜ΡΡ‚ΠΎ Ρ‚Π°ΠΊΠ°, Π½Π΅ Π·Π°Π±ΠΎΡ€Π°Π²Π°Ρ˜Ρ‚Π΅ Π·Π° -O2, Π±Π΅Π· ΠΎΠ²Π°Π° ΠΎΠΏΡ†ΠΈΡ˜Π° ΠΌΠΎΠΆΠ΅ Π΄Π° Π²Π΅ Ρ‡Π΅ΠΊΠ°Π°Ρ‚ ΠΈΠ·Π½Π΅Π½Π°Π΄ΡƒΠ²Π°ΡšΠ° Π²ΠΎ ΠΈΠ΄Π½ΠΈΠ½Π°. Π”Π° Π³ΠΎ ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ Π½Π°ΡˆΠΈΠΎΡ‚ ΠΊΠΎΠ΄, Π΄Π°Π»ΠΈ успСавмС Π΄Π° ја напишСмС ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° ΡˆΡ‚ΠΎ ја сакавмС?

$ llvm-objdump --section=xdp/simple --no-show-raw-insn -D xdp-simple.bpf.o

xdp-simple.bpf.o:       file format elf64-bpf

Disassembly of section xdp/simple:

0000000000000000 <simple>:
       0:       r0 = 2
       1:       exit

Π”Π°, успСа! Π‘Π΅Π³Π°, ΠΈΠΌΠ°ΠΌΠ΅ Π±ΠΈΠ½Π°Ρ€Π½Π° Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ° со ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° ΠΈ сакамС Π΄Π° создадСмС Π°ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΡ˜Π° која ќС ја Π²Ρ‡ΠΈΡ‚Π° Π²ΠΎ ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚. Π—Π° Ρ‚Π°Π° Ρ†Π΅Π» Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°Ρ‚Π° libbpf Π½ΠΈ Π½ΡƒΠ΄ΠΈ Π΄Π²Π΅ ΠΎΠΏΡ†ΠΈΠΈ - користСтС API ΠΎΠ΄ пониско Π½ΠΈΠ²ΠΎ ΠΈΠ»ΠΈ API ΠΎΠ΄ повисоко Π½ΠΈΠ²ΠΎ. ЌС ΠΎΠ΄ΠΈΠΌΠ΅ Π½Π° Π²Ρ‚ΠΎΡ€ΠΈΠΎΡ‚ Π½Π°Ρ‡ΠΈΠ½, бидСјќи сакамС Π΄Π° Π½Π°ΡƒΡ‡ΠΈΠΌΠ΅ ΠΊΠ°ΠΊΠΎ Π΄Π° ΠΏΠΈΡˆΡƒΠ²Π°ΠΌΠ΅, Π²Ρ‡ΠΈΡ‚Π°ΠΌΠ΅ ΠΈ ΠΏΠΎΠ²Ρ€Π·ΡƒΠ²Π°ΠΌΠ΅ BPF ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ со ΠΌΠΈΠ½ΠΈΠΌΠ°Π»Π΅Π½ Π½Π°ΠΏΠΎΡ€ Π·Π° Π½ΠΈΠ²Π½ΠΎ послСдоватСлно ΠΏΡ€ΠΎΡƒΡ‡ΡƒΠ²Π°ΡšΠ΅.

ΠŸΡ€Π²ΠΎ, Ρ‚Ρ€Π΅Π±Π° Π΄Π° Π³ΠΎ Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π°ΠΌΠ΅ β€žΡΠΊΠ΅Π»Π΅Ρ‚ΠΎΡ‚β€œ Π½Π° Π½Π°ΡˆΠ°Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° ΠΎΠ΄ Π½Π΅Ρ˜Π·ΠΈΠ½Π°Ρ‚Π° бинарност ΠΊΠΎΡ€ΠΈΡΡ‚Π΅Ρ˜ΡœΠΈ ја истата Π°Π»Π°Ρ‚ΠΊΠ° bpftool β€” ΡˆΠ²Π°Ρ˜Ρ†Π°Ρ€ΡΠΊΠΈΠΎΡ‚ Π½ΠΎΠΆ Π½Π° свСтот Π½Π° BPF (ΡˆΡ‚ΠΎ ΠΌΠΎΠΆΠ΅ Π΄Π° сС сфати Π±ΡƒΠΊΠ²Π°Π»Π½ΠΎ, бидСјќи Π”Π°Π½ΠΈΠ΅Π» Π‘ΠΎΡ€ΠΊΠΌΠ°Π½, Π΅Π΄Π΅Π½ ΠΎΠ΄ ΠΊΡ€Π΅Π°Ρ‚ΠΎΡ€ΠΈΡ‚Π΅ ΠΈ ΠΎΠ΄Ρ€ΠΆΡƒΠ²Π°Ρ‡ΠΈΡ‚Π΅ Π½Π° BPF, Π΅ Π¨Π²Π°Ρ˜Ρ†Π°Ρ€Π΅Ρ†):

$ bpftool gen skeleton xdp-simple.bpf.o > xdp-simple.skel.h

Π’ΠΎ Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ° xdp-simple.skel.h Π³ΠΎ содрТи Π±ΠΈΠ½Π°Ρ€Π½ΠΈΠΎΡ‚ ΠΊΠΎΠ΄ Π½Π° Π½Π°ΡˆΠ°Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π·Π° ΡƒΠΏΡ€Π°Π²ΡƒΠ²Π°ΡšΠ΅ - Π²Ρ‡ΠΈΡ‚ΡƒΠ²Π°ΡšΠ΅, ΠΏΡ€ΠΈΠΊΠ°Ρ‡ΡƒΠ²Π°ΡšΠ΅, Π±Ρ€ΠΈΡˆΠ΅ΡšΠ΅ Π½Π° Π½Π°ΡˆΠΈΠΎΡ‚ ΠΎΠ±Ρ˜Π΅ΠΊΡ‚. Π’ΠΎ Π½Π°ΡˆΠΈΠΎΡ‚ СдноставСн ΡΠ»ΡƒΡ‡Π°Ρ˜ ΠΎΠ²Π° ΠΈΠ·Π³Π»Π΅Π΄Π° ΠΊΠ°ΠΊΠΎ ΠΏΡ€Π΅Ρ‚Π΅Ρ€ΡƒΠ²Π°ΡšΠ΅, Π½ΠΎ исто Ρ‚Π°ΠΊΠ° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½ΠΈΡ€Π° ΠΈ Π²ΠΎ ΡΠ»ΡƒΡ‡Π°Ρ˜ ΠΊΠΎΠ³Π° Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ°Ρ‚Π° со ΠΎΠ±Ρ˜Π΅ΠΊΡ‚ содрТи ΠΌΠ½ΠΎΠ³Ρƒ BPF ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ ΠΈ ΠΌΠ°ΠΏΠΈ ΠΈ Π·Π° Π΄Π° Π³ΠΎ Π²Ρ‡ΠΈΡ‚Π°ΠΌΠ΅ овој џиновски ELF, само Ρ‚Ρ€Π΅Π±Π° Π΄Π° Π³ΠΎ Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π°ΠΌΠ΅ скСлСтот ΠΈ Π΄Π° ΠΏΠΎΠ²ΠΈΠΊΠ°ΠΌΠ΅ Π΅Π΄Π½Π° ΠΈΠ»ΠΈ Π΄Π²Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΎΠ΄ приспособСната Π°ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΡ˜Π° ΡˆΡ‚ΠΎ ја ΠΈΠΌΠ°ΠΌΠ΅. ΠΏΠΈΡˆΡƒΠ²Π°Π°Ρ‚ АјдС Π΄Π° ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠΈΠΌΠ΅ сСга.

Π‘Ρ‚Ρ€ΠΎΠ³ΠΎ ΠΊΠ°ΠΆΠ°Π½ΠΎ, Π½Π°ΡˆΠ°Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° Π·Π° Π²Ρ‡ΠΈΡ‚ΡƒΠ²Π°ΡšΠ΅ Π΅ Ρ‚Ρ€ΠΈΠ²ΠΈΡ˜Π°Π»Π½Π°:

#include <err.h>
#include <unistd.h>
#include "xdp-simple.skel.h"

int main(int argc, char **argv)
{
    struct xdp_simple_bpf *obj;

    obj = xdp_simple_bpf__open_and_load();
    if (!obj)
        err(1, "failed to open and/or load BPF objectn");

    pause();

    xdp_simple_bpf__destroy(obj);
}

Π’ΡƒΠΊΠ° struct xdp_simple_bpf Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ€Π°Π½ΠΈ Π²ΠΎ Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ°Ρ‚Π° xdp-simple.skel.h ΠΈ ја ΠΎΠΏΠΈΡˆΡƒΠ²Π° Π½Π°ΡˆΠ°Ρ‚Π° Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ° со ΠΎΠ±Ρ˜Π΅ΠΊΡ‚:

struct xdp_simple_bpf {
    struct bpf_object_skeleton *skeleton;
    struct bpf_object *obj;
    struct {
        struct bpf_program *simple;
    } progs;
    struct {
        struct bpf_link *simple;
    } links;
};

МоТСмС Π΄Π° Π²ΠΈΠ΄ΠΈΠΌΠ΅ Ρ‚Ρ€Π°Π³ΠΈ ΠΎΠ΄ API Π½Π° ниско Π½ΠΈΠ²ΠΎ ΠΎΠ²Π΄Π΅: структурата struct bpf_program *simple ΠΈ struct bpf_link *simple. ΠŸΡ€Π²Π°Ρ‚Π° структура ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎ ја ΠΎΠΏΠΈΡˆΡƒΠ²Π° Π½Π°ΡˆΠ°Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°, напишана Π²ΠΎ Π΄Π΅Π»ΠΎΡ‚ xdp/simple, Π° Π²Ρ‚ΠΎΡ€ΠΈΠΎΡ‚ ΠΎΠΏΠΈΡˆΡƒΠ²Π° ΠΊΠ°ΠΊΠΎ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° сС ΠΏΠΎΠ²Ρ€Π·ΡƒΠ²Π° со ΠΈΠ·Π²ΠΎΡ€ΠΎΡ‚ Π½Π° настанот.

Π€ΡƒΠ½ΠΊΡ†ΠΈΡ˜Π° xdp_simple_bpf__open_and_load, ΠΎΡ‚Π²ΠΎΡ€Π° ΠΎΠ±Ρ˜Π΅ΠΊΡ‚ ELF, Π³ΠΎ Π°Π½Π°Π»ΠΈΠ·ΠΈΡ€Π°, Π³ΠΈ создава ситС структури ΠΈ подструктури (ΠΏΠΎΠΊΡ€Π°Ρ˜ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π°, ELF содрТи ΠΈ Π΄Ρ€ΡƒΠ³ΠΈ Π΄Π΅Π»ΠΎΠ²ΠΈ - ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈ, ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈ само Π·Π° Ρ‡ΠΈΡ‚Π°ΡšΠ΅, ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ Π·Π° Π΄Π΅Π±Π°Π³ΠΈΡ€Π°ΡšΠ΅, Π»ΠΈΡ†Π΅Π½Ρ†Π° ΠΈΡ‚Π½.), Π° ΠΏΠΎΡ‚ΠΎΠ° Π³ΠΎ Π²Ρ‡ΠΈΡ‚ΡƒΠ²Π° Π²ΠΎ ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚ ΠΊΠΎΡ€ΠΈΡΡ‚Π΅Ρ˜ΡœΠΈ систСм Ρ˜Π°Π²Π΅Ρ‚Π΅ сС bpf, ΡˆΡ‚ΠΎ ΠΌΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° Π³ΠΎ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΠΌΠ΅ со ΠΊΠΎΠΌΠΏΠ°Ρ˜Π»ΠΈΡ€Π°ΡšΠ΅ ΠΈ ΠΈΠ·Π²Ρ€ΡˆΡƒΠ²Π°ΡšΠ΅ Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π°:

$ clang -O2 -I ./libbpf/src/root/usr/include/ xdp-simple.c -o xdp-simple ./libbpf/src/root/usr/lib64/libbpf.a -lelf -lz

$ sudo strace -e bpf ./xdp-simple
...
bpf(BPF_BTF_LOAD, 0x7ffdb8fd9670, 120)  = 3
bpf(BPF_PROG_LOAD, {prog_type=BPF_PROG_TYPE_XDP, insn_cnt=2, insns=0xdfd580, license="GPL", log_level=0, log_size=0, log_buf=NULL, kern_version=KERNEL_VERSION(5, 8, 0), prog_flags=0, prog_name="simple", prog_ifindex=0, expected_attach_type=0x25 /* BPF_??? */, ...}, 120) = 4

АјдС сСга Π΄Π° ја ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ Π½Π°ΡˆΠ°Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° ΠΊΠΎΡ€ΠΈΡΡ‚Π΅Ρ˜ΡœΠΈ ја bpftool. АјдС Π΄Π° ја најдСмС Π½Π΅Ρ˜Π·ΠΈΠ½Π°Ρ‚Π° Π»ΠΈΡ‡Π½Π° ΠΊΠ°Ρ€Ρ‚Π°:

# bpftool p | grep -A4 simple
463: xdp  name simple  tag 3b185187f1855c4c  gpl
        loaded_at 2020-08-01T01:59:49+0000  uid 0
        xlated 16B  jited 40B  memlock 4096B
        btf_id 185
        pids xdp-simple(16498)

ΠΈ dump (користимС скратСна Ρ„ΠΎΡ€ΠΌΠ° Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄Π°Ρ‚Π° bpftool prog dump xlated):

# bpftool p d x id 463
int simple(void *ctx):
; return XDP_PASS;
   0: (b7) r0 = 2
   1: (95) exit

ΠΠ΅ΡˆΡ‚ΠΎ Π½ΠΎΠ²ΠΎ! ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° ΠΎΡ‚ΠΏΠ΅Ρ‡Π°Ρ‚ΠΈ Π΄Π΅Π»ΠΎΠ²ΠΈ ΠΎΠ΄ Π½Π°ΡˆΠ°Ρ‚Π° ΠΈΠ·Π²ΠΎΡ€Π½Π° Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ° C. Ова бСшС Π½Π°ΠΏΡ€Π°Π²Π΅Π½ΠΎ ΠΎΠ΄ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°Ρ‚Π° libbpf, кој Π³ΠΎ најдС Π΄Π΅Π»ΠΎΡ‚ Π·Π° ΠΎΡ‚ΡΡ‚Ρ€Π°Π½ΡƒΠ²Π°ΡšΠ΅ Π³Ρ€Π΅ΡˆΠΊΠΈ Π²ΠΎ Π±ΠΈΠ½Π°Ρ€Π½ΠΈΠΎΡ‚, Π³ΠΎ ΠΊΠΎΠΌΠΏΠ°Ρ˜Π»ΠΈΡ€Π° Π²ΠΎ ΠΎΠ±Ρ˜Π΅ΠΊΡ‚ BTF, Π³ΠΎ Π²Ρ‡ΠΈΡ‚Π° Π²ΠΎ ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚ ΠΊΠΎΡ€ΠΈΡΡ‚Π΅Ρ˜ΡœΠΈ BPF_BTF_LOAD, Π° ΠΏΠΎΡ‚ΠΎΠ° Π½Π°Π²Π΅Π΄Π΅Ρ‚Π΅ Π³ΠΎ Π΄ΠΎΠ±ΠΈΠ΅Π½ΠΈΠΎΡ‚ дСскриптор Π½Π° Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ°Ρ‚Π° ΠΏΡ€ΠΈ Π²Ρ‡ΠΈΡ‚ΡƒΠ²Π°ΡšΠ΅ Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° со ΠΊΠΎΠΌΠ°Π½Π΄Π°Ρ‚Π° BPG_PROG_LOAD.

ΠŸΠΎΠΌΠΎΡˆΠ½ΠΈΡ†ΠΈ Π½Π° Ρ˜Π°Π΄Ρ€ΠΎΡ‚ΠΎ

ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ BPF ΠΌΠΎΠΆΠ°Ρ‚ Π΄Π° ΠΈΠ·Π²Ρ€ΡˆΡƒΠ²Π°Π°Ρ‚ β€žΠ½Π°Π΄Π²ΠΎΡ€Π΅ΡˆΠ½ΠΈβ€œ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ - ΠΏΠΎΠΌΠ°Π³Π°Ρ‡ΠΈ Π½Π° ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚. ОвиС помошни Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈΠΌ ΠΎΠ²ΠΎΠ·ΠΌΠΎΠΆΡƒΠ²Π°Π°Ρ‚ Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ BPF Π΄Π° пристапуваат Π΄ΠΎ структуритС Π½Π° Ρ˜Π°Π΄Ρ€ΠΎΡ‚ΠΎ, Π΄Π° ΡƒΠΏΡ€Π°Π²ΡƒΠ²Π°Π°Ρ‚ со ΠΌΠ°ΠΏΠΈ, Π° исто Ρ‚Π°ΠΊΠ° Π΄Π° ΠΊΠΎΠΌΡƒΠ½ΠΈΡ†ΠΈΡ€Π°Π°Ρ‚ со β€žΡ€Π΅Π°Π»Π½ΠΈΠΎΡ‚ ΡΠ²Π΅Ρ‚β€œ - Π΄Π° создаваат настани Π½Π° ΠΏΠ΅Ρ€Ρ„, Π΄Π° ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΠΈΡ€Π°Π°Ρ‚ Ρ…Π°Ρ€Π΄Π²Π΅Ρ€ (Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΏΡ€Π΅Π½Π°ΡΠΎΡ‡ΡƒΠ²Π°ΡšΠ΅ Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ) ΠΈΡ‚Π½.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€: bpf_get_smp_processor_id

Π’ΠΎ Ρ€Π°ΠΌΠΊΠΈΡ‚Π΅ Π½Π° ΠΏΠ°Ρ€Π°Π΄ΠΈΠ³ΠΌΠ°Ρ‚Π° β€žΡƒΡ‡Π΅ΡšΠ΅ ΠΏΡ€Π΅ΠΊΡƒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€β€œ, Π΄Π° Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ Π΅Π΄Π½Π° ΠΎΠ΄ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈΡ‚Π΅ Π½Π° ΠΏΠΎΠΌΠΎΡˆΠ½ΠΈΠΊΠΎΡ‚. bpf_get_smp_processor_id(), ΠΎΠ΄Ρ€Π΅Π΄Π΅Π½ΠΈ Π²ΠΎ Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ° kernel/bpf/helpers.c. Π“ΠΎ Π²Ρ€Π°ΡœΠ° Π±Ρ€ΠΎΡ˜ΠΎΡ‚ Π½Π° процСсорот Π½Π° кој Ρ€Π°Π±ΠΎΡ‚ΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° BPF ΡˆΡ‚ΠΎ ја ΠΏΠΎΠ²ΠΈΠΊΠ°. Но, Π½ΠΈΠ΅ Π½Π΅ смС Ρ‚ΠΎΠ»ΠΊΡƒ заинтСрСсирани Π·Π° Π½Π΅Π³ΠΎΠ²Π°Ρ‚Π° сСмантика ΠΊΠ°ΠΊΠΎ Π·Π° Ρ„Π°ΠΊΡ‚ΠΎΡ‚ Π΄Π΅ΠΊΠ° Π½Π΅Ρ˜Π·ΠΈΠ½Π°Ρ‚Π° ΠΈΠΌΠΏΠ»Π΅ΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡ˜Π° Ρ‚Ρ€Π°Π΅ Π΅Π΄Π½Π° линија:

BPF_CALL_0(bpf_get_smp_processor_id)
{
    return smp_processor_id();
}

Π”Π΅Ρ„ΠΈΠ½ΠΈΡ†ΠΈΠΈΡ‚Π΅ Π·Π° ΠΏΠΎΠΌΠΎΡˆΠ½Π°Ρ‚Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡ˜Π° Π½Π° BPF сС слични Π½Π° Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ†ΠΈΠΈΡ‚Π΅ Π·Π° систСмски ΠΏΠΎΠ²ΠΈΡ†ΠΈ Π½Π° Linux. ОвдС, Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π΅ Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ€Π°Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡ˜Π° која Π½Π΅ΠΌΠ° Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΈ. (Π€ΡƒΠ½ΠΊΡ†ΠΈΡ˜Π° која Π·Π΅ΠΌΠ°, Π΄Π° Ρ€Π΅Ρ‡Π΅ΠΌΠ΅, Ρ‚Ρ€ΠΈ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΈ сС Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ€Π° со помош Π½Π° ΠΌΠ°ΠΊΡ€ΠΎΡ‚ΠΎ BPF_CALL_3. ΠœΠ°ΠΊΡΠΈΠΌΠ°Π»Π½ΠΈΠΎΡ‚ Π±Ρ€ΠΎΡ˜ Π½Π° Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΈ Π΅ ΠΏΠ΅Ρ‚.) Π‘Π΅ΠΏΠ°ΠΊ, ΠΎΠ²Π° Π΅ само ΠΏΡ€Π²ΠΈΠΎΡ‚ Π΄Π΅Π» ΠΎΠ΄ Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ†ΠΈΡ˜Π°Ρ‚Π°. Π’Ρ‚ΠΎΡ€ΠΈΠΎΡ‚ Π΄Π΅Π» Π΅ Π΄Π° сС Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ€Π° структурата Π½Π° Ρ‚ΠΈΠΏΠΎΡ‚ struct bpf_func_proto, кој содрТи опис Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡ˜Π°Ρ‚Π° помошник ΡˆΡ‚ΠΎ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡƒΠ²Π°Ρ‡ΠΎΡ‚ ја Ρ€Π°Π·Π±ΠΈΡ€Π°:

const struct bpf_func_proto bpf_get_smp_processor_id_proto = {
    .func     = bpf_get_smp_processor_id,
    .gpl_only = false,
    .ret_type = RET_INTEGER,
};

Π Π΅Π³ΠΈΡΡ‚Ρ€ΠΈΡ€Π°ΡšΠ΅ Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π·Π° помошник

Π—Π° Π΄Π° ΠΌΠΎΠΆΠ°Ρ‚ BPF ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ ΠΎΠ΄ ΠΎΠ΄Ρ€Π΅Π΄Π΅Π½ Ρ‚ΠΈΠΏ Π΄Π° ја користат ΠΎΠ²Π°Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡ˜Π°, Ρ‚ΠΈΠ΅ ΠΌΠΎΡ€Π° Π΄Π° ја рСгистрираат, Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π·Π° Ρ‚ΠΈΠΏΠΎΡ‚ BPF_PROG_TYPE_XDP Π²ΠΎ ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚ Π΅ Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ€Π°Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡ˜Π° xdp_func_proto, ΡˆΡ‚ΠΎ ΠΎΠ΄Ρ€Π΅Π΄ΡƒΠ²Π° ΠΎΠ΄ ID Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡ˜Π°Ρ‚Π° помошник Π΄Π°Π»ΠΈ XDP ја ΠΏΠΎΠ΄Π΄Ρ€ΠΆΡƒΠ²Π° ΠΎΠ²Π°Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡ˜Π° ΠΈΠ»ΠΈ Π½Π΅. ΠΠ°ΡˆΠ°Ρ‚Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡ˜Π° Π΅ ΠΏΠΎΠ΄Π΄Ρ€ΠΆΡƒΠ²Π°:

static const struct bpf_func_proto *
xdp_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
{
    switch (func_id) {
    ...
    case BPF_FUNC_get_smp_processor_id:
        return &bpf_get_smp_processor_id_proto;
    ...
    }
}

НовитС Ρ‚ΠΈΠΏΠΎΠ²ΠΈ Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ BPF сС β€žΠ΄Π΅Ρ„ΠΈΠ½ΠΈΡ€Π°Π½ΠΈβ€œ Π²ΠΎ Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ°Ρ‚Π° include/linux/bpf_types.h ΠΊΠΎΡ€ΠΈΡΡ‚Π΅Ρ˜ΡœΠΈ ΠΌΠ°ΠΊΡ€ΠΎ BPF_PROG_TYPE. Π”Π΅Ρ„ΠΈΠ½ΠΈΡ€Π°Π½ΠΎ Π²ΠΎ Π½Π°Π²ΠΎΠ΄Π½ΠΈΡ†ΠΈ Π·Π°Ρ‚ΠΎΠ° ΡˆΡ‚ΠΎ Π΅ Π»ΠΎΠ³ΠΈΡ‡ΠΊΠ° Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ†ΠΈΡ˜Π°, Π° Π²ΠΎ Ρ‚Π΅Ρ€ΠΌΠΈΠ½ΠΈΡ‚Π΅ Π½Π° Ρ˜Π°Π·ΠΈΠΊΠΎΡ‚ C Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ†ΠΈΡ˜Π°Ρ‚Π° Π½Π° Ρ†Π΅Π» сСт бСтонски конструкции сС Ρ˜Π°Π²ΡƒΠ²Π° Π½Π° Π΄Ρ€ΡƒΠ³ΠΈ мСста. ΠšΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎ, Π²ΠΎ досиСто kernel/bpf/verifier.c ситС Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ†ΠΈΠΈ ΠΎΠ΄ Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ°Ρ‚Π° bpf_types.h сС користат Π·Π° создавањС Π½ΠΈΠ·Π° структури bpf_verifier_ops[]:

static const struct bpf_verifier_ops *const bpf_verifier_ops[] = {
#define BPF_PROG_TYPE(_id, _name, prog_ctx_type, kern_ctx_type) 
    [_id] = & _name ## _verifier_ops,
#include <linux/bpf_types.h>
#undef BPF_PROG_TYPE
};

Односно, Π·Π° сСкој Ρ‚ΠΈΠΏ Π½Π° BPF ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°, сС Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ€Π° ΠΏΠΎΠΊΠ°ΠΆΡƒΠ²Π°Ρ‡ ΠΊΠΎΠ½ структура Π½Π° ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈ ΠΎΠ΄ Ρ‚ΠΈΠΏΠΎΡ‚ struct bpf_verifier_ops, кој сС ΠΈΠ½ΠΈΡ†ΠΈΡ˜Π°Π»ΠΈΠ·ΠΈΡ€Π° со врСдноста _name ## _verifier_opsΡ‚.Π΅. xdp_verifier_ops Π·Π° xdp. Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π° xdp_verifier_ops ΡƒΡ‚Π²Ρ€Π΄Π΅Π½ΠΈ ΠΎΠ΄ Π²ΠΎ Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ° net/core/filter.c ΠΊΠ°ΠΊΠΎ ΡˆΡ‚ΠΎ слСдува:

const struct bpf_verifier_ops xdp_verifier_ops = {
    .get_func_proto     = xdp_func_proto,
    .is_valid_access    = xdp_is_valid_access,
    .convert_ctx_access = xdp_convert_ctx_access,
    .gen_prologue       = bpf_noop_prologue,
};

ОвдС ја Π³Π»Π΅Π΄Π°ΠΌΠ΅ Π½Π°ΡˆΠ°Ρ‚Π° ΠΏΠΎΠ·Π½Π°Ρ‚Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡ˜Π° xdp_func_proto, кој ќС Π³ΠΎ Π°ΠΊΡ‚ΠΈΠ²ΠΈΡ€Π° ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡƒΠ²Π°Ρ‡ΠΎΡ‚ сСкогаш ΠΊΠΎΠ³Π° ќС Π½Π°ΠΈΠ΄Π΅ Π½Π° ΠΏΡ€Π΅Π΄ΠΈΠ·Π²ΠΈΠΊ нСкој Π²ΠΈΠ΄ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π²ΠΎ BPF ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°, Π²ΠΈΠ΄ΠΈ verifier.c.

АјдС Π΄Π° ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ ΠΊΠ°ΠΊΠΎ Ρ…ΠΈΠΏΠΎΡ‚Π΅Ρ‚ΠΈΡ‡ΠΊΠ° BPF ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° ја користи Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡ˜Π°Ρ‚Π° bpf_get_smp_processor_id. Π—Π° Π΄Π° Π³ΠΎ Π½Π°ΠΏΡ€Π°Π²ΠΈΡ‚Π΅ ΠΎΠ²Π°, ја ΠΏΡ€Π΅ΠΏΠΈΡˆΡƒΠ²Π°ΠΌΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° ΠΎΠ΄ Π½Π°ΡˆΠΈΠΎΡ‚ ΠΏΡ€Π΅Ρ‚Ρ…ΠΎΠ΄Π΅Π½ Π΄Π΅Π» Π½Π° слСдниов Π½Π°Ρ‡ΠΈΠ½:

#include "vmlinux.h"
#include <bpf/bpf_helpers.h>

SEC("xdp/simple")
int simple(void *ctx)
{
    if (bpf_get_smp_processor_id() != 0)
        return XDP_DROP;
    return XDP_PASS;
}

char LICENSE[] SEC("license") = "GPL";

симбол bpf_get_smp_processor_id ΡƒΡ‚Π²Ρ€Π΄Π΅Π½ΠΈ ΠΎΠ΄ Π² <bpf/bpf_helper_defs.h> Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ libbpf ΠΊΠ°ΠΊΠΎ

static u32 (*bpf_get_smp_processor_id)(void) = (void *) 8;

Ρ‚ΠΎΠ° Π΅, bpf_get_smp_processor_id Π΅ функциски ΠΏΠΎΠΊΠ°ΠΆΡƒΠ²Π°Ρ‡ Ρ‡ΠΈΡ˜Π° врСдност Π΅ 8, ΠΊΠ°Π΄Π΅ ΡˆΡ‚ΠΎ 8 Π΅ врСдноста BPF_FUNC_get_smp_processor_id Ρ‚ΠΈΠΏ enum bpf_fun_id, ΡˆΡ‚ΠΎ Π½ΠΈ Π΅ Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ€Π°Π½ΠΎ Π²ΠΎ Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ°Ρ‚Π° vmlinux.h (Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ° bpf_helper_defs.h Π²ΠΎ ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚ сС Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π° скрипта, Ρ‚Π°ΠΊΠ° ΡˆΡ‚ΠΎ β€žΠΌΠ°Π³ΠΈΡ‡Π½ΠΈΡ‚Π΅β€œ Π±Ρ€ΠΎΠ΅Π²ΠΈ сС Π²ΠΎ Ρ€Π΅Π΄). Оваа Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡ˜Π° Π½Π΅ Π·Π΅ΠΌΠ° Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΈ ΠΈ Π²Ρ€Π°ΡœΠ° врСдност ΠΎΠ΄ Ρ‚ΠΈΠΏΠΎΡ‚ __u32. Кога ќС Π³ΠΎ ΠΈΠ·Π²Ρ€ΡˆΠΈΠΌΠ΅ Π²ΠΎ Π½Π°ΡˆΠ°Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°, clang Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π° ΠΈΠ½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡ˜Π° BPF_CALL β€žΠ²ΠΈΡΡ‚ΠΈΠ½ΡΠΊΠΈΠΎΡ‚ Π²ΠΈΠ΄β€œ АјдС Π΄Π° ја составимС ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° ΠΈ Π΄Π° Π³ΠΎ ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ Π΄Π΅Π»ΠΎΡ‚ xdp/simple:

$ clang -O2 -g -c -target bpf -I libbpf/src/root/usr/include xdp-simple.bpf.c -o xdp-simple.bpf.o
$ llvm-objdump -D --section=xdp/simple xdp-simple.bpf.o

xdp-simple.bpf.o:       file format elf64-bpf

Disassembly of section xdp/simple:

0000000000000000 <simple>:
       0:       85 00 00 00 08 00 00 00 call 8
       1:       bf 01 00 00 00 00 00 00 r1 = r0
       2:       67 01 00 00 20 00 00 00 r1 <<= 32
       3:       77 01 00 00 20 00 00 00 r1 >>= 32
       4:       b7 00 00 00 02 00 00 00 r0 = 2
       5:       15 01 01 00 00 00 00 00 if r1 == 0 goto +1 <LBB0_2>
       6:       b7 00 00 00 01 00 00 00 r0 = 1

0000000000000038 <LBB0_2>:
       7:       95 00 00 00 00 00 00 00 exit

Π’ΠΎ ΠΏΡ€Π²Π°Ρ‚Π° линија Π³Π»Π΅Π΄Π°ΠΌΠ΅ инструкции call, ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Π°Ρ€ IMM ΡˆΡ‚ΠΎ Π΅ Π΅Π΄Π½Π°ΠΊΠ²ΠΎ Π½Π° 8, ΠΈ SRC_REG - Π½ΡƒΠ»Π°. Π‘ΠΏΠΎΡ€Π΅Π΄ Π΄ΠΎΠ³ΠΎΠ²ΠΎΡ€ΠΎΡ‚ ABI ΡˆΡ‚ΠΎ Π³ΠΎ користи Π²Π΅Ρ€ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ΠΎΡ‚, ΠΎΠ²Π° Π΅ ΠΏΠΎΠ²ΠΈΠΊ Π΄ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡ˜Π°Ρ‚Π° помошник Π±Ρ€ΠΎΡ˜ осум. ΠžΡ‚ΠΊΠ°ΠΊΠΎ ќС сС стартува, Π»ΠΎΠ³ΠΈΠΊΠ°Ρ‚Π° Π΅ Сдноставна. Π’Ρ€Π°Ρ‚Π΅Ρ‚Π΅ ја врСдноста ΠΎΠ΄ рСгистарот r0 ΠΊΠΎΠΏΠΈΡ€Π°Π½ΠΈ Π½Π° r1 Π° Π½Π° Π»ΠΈΠ½ΠΈΠΈΡ‚Π΅ 2,3 сС ΠΏΡ€Π΅Ρ‚Π²ΠΎΡ€Π° Π²ΠΎ Ρ‚ΠΈΠΏ u32 β€” Π³ΠΎΡ€Π½ΠΈΡ‚Π΅ 32 Π±ΠΈΡ‚Π° сС ΠΈΠ·Π±Ρ€ΠΈΡˆΠ°Π½ΠΈ. На Π»ΠΈΠ½ΠΈΠΈΡ‚Π΅ 4,5,6,7 Π²Ρ€Π°ΡœΠ°ΠΌΠ΅ 2 (XDP_PASS) ΠΈΠ»ΠΈ 1 (XDP_DROP) Π²ΠΎ зависност ΠΎΠ΄ Ρ‚ΠΎΠ° Π΄Π°Π»ΠΈ ΠΏΠΎΠΌΠΎΡˆΠ½Π°Ρ‚Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡ˜Π° ΠΎΠ΄ Π»ΠΈΠ½ΠΈΡ˜Π°Ρ‚Π° 0 Π²Ρ€Π°Ρ‚ΠΈΠ»Π° Π½ΡƒΠ»Ρ‚Π° ΠΈΠ»ΠΈ Π½Π΅Π½ΡƒΠ»Ρ‚Π° врСдност.

АјдС Π΄Π° сС тСстирамС: Π²Ρ‡ΠΈΡ‚Π°Ρ˜Ρ‚Π΅ ја ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° ΠΈ ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅Ρ‚Π΅ Π³ΠΎ ΠΈΠ·Π»Π΅Π·ΠΎΡ‚ bpftool prog dump xlated:

$ bpftool gen skeleton xdp-simple.bpf.o > xdp-simple.skel.h
$ clang -O2 -g -I ./libbpf/src/root/usr/include/ -o xdp-simple xdp-simple.c ./libbpf/src/root/usr/lib64/libbpf.a -lelf -lz
$ sudo ./xdp-simple &
[2] 10914

$ sudo bpftool p | grep simple
523: xdp  name simple  tag 44c38a10c657e1b0  gpl
        pids xdp-simple(10915)

$ sudo bpftool p d x id 523
int simple(void *ctx):
; if (bpf_get_smp_processor_id() != 0)
   0: (85) call bpf_get_smp_processor_id#114128
   1: (bf) r1 = r0
   2: (67) r1 <<= 32
   3: (77) r1 >>= 32
   4: (b7) r0 = 2
; }
   5: (15) if r1 == 0x0 goto pc+1
   6: (b7) r0 = 1
   7: (95) exit

Π’ΠΎ Ρ€Π΅Π΄, ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡƒΠ²Π°Ρ‡ΠΎΡ‚ Π³ΠΎ најдС Ρ‚ΠΎΡ‡Π½ΠΈΠΎΡ‚ помошник Π½Π° Ρ˜Π°Π΄Ρ€ΠΎΡ‚ΠΎ.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€: ΠΏΡ€Π΅Π½Π΅ΡΡƒΠ²Π°ΡšΠ΅ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΈ ΠΈ Π½Π° ΠΊΡ€Π°Ρ˜ΠΎΡ‚ водСњС Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π°!

Π‘ΠΈΡ‚Π΅ помошни Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π½Π° Π½ΠΈΠ²ΠΎ Π½Π° Ρ€Π°Π±ΠΎΡ‚Π° ΠΈΠΌΠ°Π°Ρ‚ ΠΏΡ€ΠΎΡ‚ΠΎΡ‚ΠΈΠΏ

u64 fn(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5)

ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΡ‚Π΅ Π·Π° ΠΏΠΎΠΌΠΎΡˆΠ½ΠΈΡ‚Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ сС прСнСсуваат Π²ΠΎ рСгистри r1-r5, Π° врСдноста сС Π²Ρ€Π°ΡœΠ° Π²ΠΎ рСгистарот r0. НСма Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΊΠΎΠΈ Π·Π΅ΠΌΠ°Π°Ρ‚ повСќС ΠΎΠ΄ ΠΏΠ΅Ρ‚ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΈ, Π° ΠΏΠΎΠ΄Π΄Ρ€ΡˆΠΊΠ°Ρ‚Π° Π·Π° Π½ΠΈΠ² Π½Π΅ сС ΠΎΡ‡Π΅ΠΊΡƒΠ²Π° Π΄Π° Π±ΠΈΠ΄Π΅ Π΄ΠΎΠ΄Π°Π΄Π΅Π½Π° Π²ΠΎ ΠΈΠ΄Π½ΠΈΠ½Π°.

АјдС Π΄Π° Π³ΠΎ ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ Π½ΠΎΠ²ΠΈΠΎΡ‚ помошник Π½Π° ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚ ΠΈ ΠΊΠ°ΠΊΠΎ BPF Π³ΠΈ прСнСсува ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΡ‚Π΅. АјдС Π΄Π° ΠΏΡ€Π΅ΠΏΠΈΡˆΠ΅ΠΌΠ΅ xdp-simple.bpf.c ΠΊΠ°ΠΊΠΎ ΡˆΡ‚ΠΎ слСдува (останатиот Π΄Π΅Π» ΠΎΠ΄ Ρ€Π΅Π΄ΠΎΠ²ΠΈΡ‚Π΅ Π½Π΅ сС ΠΏΡ€ΠΎΠΌΠ΅Π½Π΅Ρ‚ΠΈ):

SEC("xdp/simple")
int simple(void *ctx)
{
    bpf_printk("running on CPU%un", bpf_get_smp_processor_id());
    return XDP_PASS;
}

ΠΠ°ΡˆΠ°Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° Π³ΠΎ ΠΏΠ΅Ρ‡Π°Ρ‚ΠΈ Π±Ρ€ΠΎΡ˜ΠΎΡ‚ Π½Π° процСсорот Π½Π° кој Ρ€Π°Π±ΠΎΡ‚ΠΈ. АјдС Π΄Π° Π³ΠΎ ΠΊΠΎΠΌΠΏΠ°Ρ˜Π»ΠΈΡ€Π°ΠΌΠ΅ ΠΈ Π΄Π° Π³ΠΎ ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ ΠΊΠΎΠ΄ΠΎΡ‚:

$ llvm-objdump -D --section=xdp/simple --no-show-raw-insn xdp-simple.bpf.o

0000000000000000 <simple>:
       0:       r1 = 10
       1:       *(u16 *)(r10 - 8) = r1
       2:       r1 = 8441246879787806319 ll
       4:       *(u64 *)(r10 - 16) = r1
       5:       r1 = 2334956330918245746 ll
       7:       *(u64 *)(r10 - 24) = r1
       8:       call 8
       9:       r1 = r10
      10:       r1 += -24
      11:       r2 = 18
      12:       r3 = r0
      13:       call 6
      14:       r0 = 2
      15:       exit

Π’ΠΎ Ρ€Π΅Π΄ΠΎΠ²ΠΈΡ‚Π΅ 0-7 ја ΠΏΠΈΡˆΡƒΠ²Π°ΠΌΠ΅ Π½ΠΈΠ·Π°Ρ‚Π° running on CPU%un, Π° ΠΏΠΎΡ‚ΠΎΠ° Π½Π° Π»ΠΈΠ½ΠΈΡ˜Π°Ρ‚Π° 8 ја стартувамС ΠΏΠΎΠ·Π½Π°Ρ‚Π°Ρ‚Π° bpf_get_smp_processor_id. На Π»ΠΈΠ½ΠΈΠΈΡ‚Π΅ 9-12 Π³ΠΈ ΠΏΠΎΠ΄Π³ΠΎΡ‚Π²ΡƒΠ²Π°ΠΌΠ΅ ΠΏΠΎΠΌΠΎΡˆΠ½ΠΈΡ‚Π΅ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΈ bpf_printk - рСгистри r1, r2, r3. Π—ΠΎΡˆΡ‚ΠΎ ΠΈΠΌΠ° Ρ‚Ρ€ΠΈ, Π° Π½Π΅ Π΄Π²Π΅? Π‘ΠΈΠ΄Π΅Ρ˜ΡœΠΈ bpf_printkΠΎΠ²Π° Π΅ ΠΌΠ°ΠΊΡ€ΠΎ ΠΎΠ±Π²ΠΈΠ²ΠΊΠ° ΠΎΠΊΠΎΠ»Ρƒ вистинскиот помошник bpf_trace_printk, кој Ρ‚Ρ€Π΅Π±Π° Π΄Π° ја ΠΏΠΎΠΌΠΈΠ½Π΅ Π³ΠΎΠ»Π΅ΠΌΠΈΠ½Π°Ρ‚Π° Π½Π° Π½ΠΈΠ·Π°Ρ‚Π° Π·Π° Ρ„ΠΎΡ€ΠΌΠ°Ρ‚.

АјдС сСга Π΄Π° Π΄ΠΎΠ΄Π°Π΄Π΅ΠΌΠ΅ Π½Π΅ΠΊΠΎΠ»ΠΊΡƒ Π»ΠΈΠ½ΠΈΠΈ xdp-simple.cΡ‚Π°ΠΊΠ° ΡˆΡ‚ΠΎ Π½Π°ΡˆΠ°Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° сС ΠΏΠΎΠ²Ρ€Π·ΡƒΠ²Π° со ΠΈΠ½Ρ‚Π΅Ρ€Ρ„Π΅Ρ˜ΡΠΎΡ‚ lo ΠΈ навистина Π·Π°ΠΏΠΎΡ‡Π½Π°!

$ cat xdp-simple.c
#include <linux/if_link.h>
#include <err.h>
#include <unistd.h>
#include "xdp-simple.skel.h"

int main(int argc, char **argv)
{
    __u32 flags = XDP_FLAGS_SKB_MODE;
    struct xdp_simple_bpf *obj;

    obj = xdp_simple_bpf__open_and_load();
    if (!obj)
        err(1, "failed to open and/or load BPF objectn");

    bpf_set_link_xdp_fd(1, -1, flags);
    bpf_set_link_xdp_fd(1, bpf_program__fd(obj->progs.simple), flags);

cleanup:
    xdp_simple_bpf__destroy(obj);
}

ОвдС ја користимС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡ˜Π°Ρ‚Π° bpf_set_link_xdp_fd, кој Π³ΠΈ ΠΏΠΎΠ²Ρ€Π·ΡƒΠ²Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ BPF ΠΎΠ΄ Ρ‚ΠΈΠΏΠΎΡ‚ XDP со ΠΌΡ€Π΅ΠΆΠ½ΠΈΡ‚Π΅ ΠΈΠ½Ρ‚Π΅Ρ€Ρ„Π΅Ρ˜ΡΠΈ. Π“ΠΎ ΡˆΠΈΡ„Ρ€ΠΈΡ€Π°Π²ΠΌΠ΅ Π±Ρ€ΠΎΡ˜ΠΎΡ‚ Π½Π° ΠΈΠ½Ρ‚Π΅Ρ€Ρ„Π΅Ρ˜ΡΠΎΡ‚ lo, ΡˆΡ‚ΠΎ Π΅ сСкогаш 1. Ја ΠΈΠ·Π²Ρ€ΡˆΡƒΠ²Π°ΠΌΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡ˜Π°Ρ‚Π° Π΄Π²Π°ΠΏΠ°Ρ‚ΠΈ Π·Π° ΠΏΡ€Π²ΠΎ Π΄Π° ја ΠΎΡ‚ΠΊΠ°Ρ‡ΠΈΠΌΠ΅ старата ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° Π΄ΠΎΠΊΠΎΠ»ΠΊΡƒ Π΅ ΠΏΡ€ΠΈΠΊΠ°Ρ‡Π΅Π½Π°. Π—Π°Π±Π΅Π»Π΅ΠΆΠ΅Ρ‚Π΅ Π΄Π΅ΠΊΠ° сСга Π½Π΅ Π½ΠΈ Ρ‚Ρ€Π΅Π±Π° ΠΏΡ€Π΅Π΄ΠΈΠ·Π²ΠΈΠΊ pause ΠΈΠ»ΠΈ бСсконСчна јамка: Π½Π°ΡˆΠ°Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° Π·Π° Π²Ρ‡ΠΈΡ‚ΡƒΠ²Π°ΡšΠ΅ ќС ΠΈΠ·Π»Π΅Π·Π΅, Π½ΠΎ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° BPF Π½Π΅ΠΌΠ° Π΄Π° Π±ΠΈΠ΄Π΅ ΡƒΠ±ΠΈΠ΅Π½Π° бидСјќи Π΅ ΠΏΠΎΠ²Ρ€Π·Π°Π½Π° со ΠΈΠ·Π²ΠΎΡ€ΠΎΡ‚ Π½Π° настанот. По ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ ΠΏΡ€Π΅Π·Π΅ΠΌΠ°ΡšΠ΅ ΠΈ ΠΏΠΎΠ²Ρ€Π·ΡƒΠ²Π°ΡšΠ΅, ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° ќС сС стартува Π·Π° сСкој ΠΌΡ€Π΅ΠΆΠ΅Π½ ΠΏΠ°ΠΊΠ΅Ρ‚ ΡˆΡ‚ΠΎ ќС пристигнС lo.

АјдС Π΄Π° ја ΠΏΡ€Π΅Π·Π΅ΠΌΠ΅ΠΌΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° ΠΈ Π΄Π° Π³ΠΎ ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ ΠΈΠ½Ρ‚Π΅Ρ€Ρ„Π΅Ρ˜ΡΠΎΡ‚ lo:

$ sudo ./xdp-simple
$ sudo bpftool p | grep simple
669: xdp  name simple  tag 4fca62e77ccb43d6  gpl
$ ip l show dev lo
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 xdpgeneric qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    prog/xdp id 669

ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° ΡˆΡ‚ΠΎ ја ΠΏΡ€Π΅Π·Π΅ΠΌΠ°Π²ΠΌΠ΅ ΠΈΠΌΠ° ID 669 ΠΈ Π³ΠΎ Π³Π»Π΅Π΄Π°ΠΌΠ΅ истиот ID Π½Π° ΠΈΠ½Ρ‚Π΅Ρ€Ρ„Π΅Ρ˜ΡΠΎΡ‚ lo. ЌС испратимС Π½Π΅ΠΊΠΎΠ»ΠΊΡƒ ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ Π΄ΠΎ 127.0.0.1 (Π±Π°Ρ€Π°ΡšΠ΅ + ΠΎΠ΄Π³ΠΎΠ²ΠΎΡ€):

$ ping -c1 localhost

Π° сСга Π΄Π° ја ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ содрТината Π½Π° Π²ΠΈΡ€Ρ‚ΡƒΠ΅Π»Π½Π°Ρ‚Π° Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ° Π·Π° ΠΎΡ‚ΡΡ‚Ρ€Π°Π½ΡƒΠ²Π°ΡšΠ΅ Π³Ρ€Π΅ΡˆΠΊΠΈ /sys/kernel/debug/tracing/trace_pipe, Π²ΠΎ која bpf_printk Π³ΠΈ ΠΏΠΈΡˆΡƒΠ²Π° своитС ΠΏΠΎΡ€Π°ΠΊΠΈ:

# cat /sys/kernel/debug/tracing/trace_pipe
ping-13937 [000] d.s1 442015.377014: bpf_trace_printk: running on CPU0
ping-13937 [000] d.s1 442015.377027: bpf_trace_printk: running on CPU0

Π‘Π΅Π° Π·Π°Π±Π΅Π»Π΅ΠΆΠ°Π½ΠΈ Π΄Π²Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ lo ΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π΅Π½Π° Π½Π° CPU0 - Π½Π°ΡˆΠ°Ρ‚Π° ΠΏΡ€Π²Π° ΠΏΠΎΠ»Π½ΠΎΠΏΡ€Π°Π²Π½Π° бСсмислСна ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° BPF Ρ€Π°Π±ΠΎΡ‚Π΅ΡˆΠ΅!

Π’Ρ€Π΅Π΄ΠΈ Π΄Π° сС Π½Π°ΠΏΠΎΠΌΠ΅Π½Π΅ Π΄Π΅ΠΊΠ° bpf_printk НС Π΅ Π·Π° џабС ΡˆΡ‚ΠΎ ΠΏΠΈΡˆΡƒΠ²Π° Π²ΠΎ Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ°Ρ‚Π° Π·Π° ΠΎΡ‚ΡΡ‚Ρ€Π°Π½ΡƒΠ²Π°ΡšΠ΅ Π³Ρ€Π΅ΡˆΠΊΠΈ: ΠΎΠ²Π° Π½Π΅ Π΅ Π½Π°Ρ˜ΡƒΡΠΏΠ΅ΡˆΠ½ΠΈΠΎΡ‚ помошник Π·Π° ΡƒΠΏΠΎΡ‚Ρ€Π΅Π±Π° Π²ΠΎ производството, Π½ΠΎ Π½Π°ΡˆΠ°Ρ‚Π° Ρ†Π΅Π» бСшС Π΄Π° ΠΏΠΎΠΊΠ°ΠΆΠ΅ΠΌΠ΅ Π½Π΅ΡˆΡ‚ΠΎ Сдноставно.

ΠŸΡ€ΠΈΡΡ‚Π°ΠΏ Π΄ΠΎ ΠΌΠ°ΠΏΠΈ ΠΎΠ΄ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ BPF

ΠŸΡ€ΠΈΠΌΠ΅Ρ€: ΠΊΠΎΡ€ΠΈΡΡ‚Π΅ΡšΠ΅ Π½Π° ΠΌΠ°ΠΏΠ° ΠΎΠ΄ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° BPF

Π’ΠΎ ΠΏΡ€Π΅Ρ‚Ρ…ΠΎΠ΄Π½ΠΈΡ‚Π΅ Π΄Π΅Π»ΠΎΠ²ΠΈ Π½Π°ΡƒΡ‡ΠΈΠ²ΠΌΠ΅ ΠΊΠ°ΠΊΠΎ Π΄Π° ΠΊΡ€Π΅ΠΈΡ€Π°ΠΌΠ΅ ΠΈ користимС ΠΌΠ°ΠΏΠΈ ΠΎΠ΄ корисничкиот простор, Π° сСга Π΄Π° Π³ΠΎ ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ Π΄Π΅Π»ΠΎΡ‚ Π½Π° ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚. Π”Π° ΠΏΠΎΡ‡Π½Π΅ΠΌΠ΅, ΠΊΠ°ΠΊΠΎ ΠΈ ΠΎΠ±ΠΈΡ‡Π½ΠΎ, со ΠΏΡ€ΠΈΠΌΠ΅Ρ€. АјдС Π΄Π° ја ΠΏΡ€Π΅Ρ€Π°Π±ΠΎΡ‚ΠΈΠΌΠ΅ Π½Π°ΡˆΠ°Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° xdp-simple.bpf.c ΠΊΠ°ΠΊΠΎ ΡˆΡ‚ΠΎ слСдува:

#include "vmlinux.h"
#include <bpf/bpf_helpers.h>

struct {
    __uint(type, BPF_MAP_TYPE_ARRAY);
    __uint(max_entries, 8);
    __type(key, u32);
    __type(value, u64);
} woo SEC(".maps");

SEC("xdp/simple")
int simple(void *ctx)
{
    u32 key = bpf_get_smp_processor_id();
    u32 *val;

    val = bpf_map_lookup_elem(&woo, &key);
    if (!val)
        return XDP_ABORTED;

    *val += 1;

    return XDP_PASS;
}

char LICENSE[] SEC("license") = "GPL";

На ΠΏΠΎΡ‡Π΅Ρ‚ΠΎΠΊΠΎΡ‚ Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° Π΄ΠΎΠ΄Π°Π΄ΠΎΠ²ΠΌΠ΅ Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ†ΠΈΡ˜Π° Π·Π° ΠΌΠ°ΠΏΠ° woo: Ова Π΅ Π½ΠΈΠ·Π° со 8 Π΅Π»Π΅ΠΌΠ΅Π½Ρ‚ΠΈ ΡˆΡ‚ΠΎ складира врСдности ΠΊΠ°ΠΊΠΎ u64 (Π²ΠΎ C Π±ΠΈ Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ€Π°Π»Π΅ Ρ‚Π°ΠΊΠ²Π° Π½ΠΈΠ·Π° ΠΊΠ°ΠΊΠΎ u64 woo[8]). Π’ΠΎ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° "xdp/simple" Π³ΠΎ Π΄ΠΎΠ±ΠΈΠ²Π°ΠΌΠ΅ Ρ‚Π΅ΠΊΠΎΠ²Π½ΠΈΠΎΡ‚ Π±Ρ€ΠΎΡ˜ Π½Π° процСсорот Π²ΠΎ ΠΏΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ²Π° key Π° ΠΏΠΎΡ‚ΠΎΠ° со помош Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡ˜Π°Ρ‚Π° помошник bpf_map_lookup_element Π΄ΠΎΠ±ΠΈΠ²Π°ΠΌΠ΅ ΠΏΠΎΠΊΠ°ΠΆΡƒΠ²Π°Ρ‡ Π΄ΠΎ соодвСтниот запис Π²ΠΎ Π½ΠΈΠ·Π°Ρ‚Π°, кој Π³ΠΎ Π·Π³ΠΎΠ»Π΅ΠΌΡƒΠ²Π°ΠΌΠ΅ Π·Π° Π΅Π΄Π΅Π½. ΠŸΡ€Π΅Π²Π΅Π΄Π΅Π½ΠΎ Π½Π° руски: Π½ΠΈΠ΅ прСсмСтувамС статистика Π·Π° Ρ‚ΠΎΠ° кој процСсорот Π³ΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΡƒΠ²Π°Π» Π΄ΠΎΡ˜Π΄ΠΎΠ²Π½ΠΈΡ‚Π΅ ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ. АјдС Π΄Π° сС ΠΎΠ±ΠΈΠ΄Π΅ΠΌΠ΅ Π΄Π° ја ΠΈΠ·Π²Ρ€ΡˆΠΈΠΌΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π°:

$ clang -O2 -g -c -target bpf -I libbpf/src/root/usr/include xdp-simple.bpf.c -o xdp-simple.bpf.o
$ bpftool gen skeleton xdp-simple.bpf.o > xdp-simple.skel.h
$ clang -O2 -g -I ./libbpf/src/root/usr/include/ -o xdp-simple xdp-simple.c ./libbpf/src/root/usr/lib64/libbpf.a -lelf -lz
$ sudo ./xdp-simple

АјдС Π΄Π° ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΠΌΠ΅ Π΄Π°Π»ΠΈ Π΅ ΠΏΠΎΠ²Ρ€Π·Π°Π½Π° со lo ΠΈ испратСтС Π½Π΅ΠΊΠΎΠ»ΠΊΡƒ ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ:

$ ip l show dev lo
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 xdpgeneric qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    prog/xdp id 108

$ for s in `seq 234`; do sudo ping -f -c 100 127.0.0.1 >/dev/null 2>&1; done

Π‘Π΅Π³Π° Π΄Π° ја ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ содрТината Π½Π° Π½ΠΈΠ·Π°Ρ‚Π°:

$ sudo bpftool map dump name woo
[
    { "key": 0, "value": 0 },
    { "key": 1, "value": 400 },
    { "key": 2, "value": 0 },
    { "key": 3, "value": 0 },
    { "key": 4, "value": 0 },
    { "key": 5, "value": 0 },
    { "key": 6, "value": 0 },
    { "key": 7, "value": 46400 }
]

РСчиси ситС процСси Π±Π΅Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π΅Π½ΠΈ Π½Π° CPU7. Ова Π½Π΅ Π½ΠΈ Π΅ Π²Π°ΠΆΠ½ΠΎ, Π³Π»Π°Π²Π½Π°Ρ‚Π° Ρ€Π°Π±ΠΎΡ‚Π° Π΅ ΡˆΡ‚ΠΎ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° Ρ€Π°Π±ΠΎΡ‚ΠΈ ΠΈ Ρ€Π°Π·Π±ΠΈΡ€Π°ΠΌΠ΅ ΠΊΠ°ΠΊΠΎ Π΄Π° пристапимС Π΄ΠΎ ΠΌΠ°ΠΏΠΈ ΠΎΠ΄ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ BPF - ΠΊΠΎΡ€ΠΈΡΡ‚Π΅Ρ˜ΡœΠΈ Ρ…Π΅Π»ΠΏΠ΅Ρ€ΠΎΠ² bpf_mp_*.

ΠœΠΈΡΡ‚ΠΈΡ‡Π΅Π½ индСкс

Π—Π½Π°Ρ‡ΠΈ, ΠΌΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° пристапимС Π΄ΠΎ ΠΊΠ°Ρ€Ρ‚Π°Ρ‚Π° ΠΎΠ΄ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° BPF ΠΊΠΎΡ€ΠΈΡΡ‚Π΅Ρ˜ΡœΠΈ ΠΏΠΎΠ²ΠΈΡ†ΠΈ ΠΊΠ°ΠΊΠΎ

val = bpf_map_lookup_elem(&woo, &key);

ΠΊΠ°Π΄Π΅ ΡˆΡ‚ΠΎ ΠΈΠ·Π³Π»Π΅Π΄Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡ˜Π°Ρ‚Π° помошник

void *bpf_map_lookup_elem(struct bpf_map *map, const void *key)

Π½ΠΎ Π½ΠΈΠ΅ ΠΏΠΎΠΌΠΈΠ½ΡƒΠ²Π°ΠΌΠ΅ ΠΏΠΎΠΊΠ°ΠΆΡƒΠ²Π°Ρ‡ &woo Π½Π° Π½Π΅ΠΈΠΌΠ΅Π½ΡƒΠ²Π°Π½Π° структура struct { ... }...

Ако Π³ΠΎ ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ асСмблСрот Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π°, ќС Π²ΠΈΠ΄ΠΈΠΌΠ΅ Π΄Π΅ΠΊΠ° врСдноста &woo Π²ΡΡƒΡˆΠ½ΠΎΡΡ‚ Π½Π΅ Π΅ Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ€Π°Π½ΠΎ (линија 4):

llvm-objdump -D --section xdp/simple xdp-simple.bpf.o

xdp-simple.bpf.o:       file format elf64-bpf

Disassembly of section xdp/simple:

0000000000000000 <simple>:
       0:       85 00 00 00 08 00 00 00 call 8
       1:       63 0a fc ff 00 00 00 00 *(u32 *)(r10 - 4) = r0
       2:       bf a2 00 00 00 00 00 00 r2 = r10
       3:       07 02 00 00 fc ff ff ff r2 += -4
       4:       18 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r1 = 0 ll
       6:       85 00 00 00 01 00 00 00 call 1
...

ΠΈ Π΅ содрТан Π²ΠΎ ΠΏΡ€Π΅ΠΌΠ΅ΡΡ‚ΡƒΠ²Π°ΡšΠ°Ρ‚Π°:

$ llvm-readelf -r xdp-simple.bpf.o | head -4

Relocation section '.relxdp/simple' at offset 0xe18 contains 1 entries:
    Offset             Info             Type               Symbol's Value  Symbol's Name
0000000000000020  0000002700000001 R_BPF_64_64            0000000000000000 woo

Но, Π°ΠΊΠΎ ја ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ вСќС Π²Ρ‡ΠΈΡ‚Π°Π½Π°Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°, Π³Π»Π΅Π΄Π°ΠΌΠ΅ ΠΏΠΎΠΊΠ°ΠΆΡƒΠ²Π°Ρ‡ ΠΊΠΎΠ½ ΠΏΡ€Π°Π²ΠΈΠ»Π½Π°Ρ‚Π° ΠΊΠ°Ρ€Ρ‚Π° (линија 4):

$ sudo bpftool prog dump x name simple
int simple(void *ctx):
   0: (85) call bpf_get_smp_processor_id#114128
   1: (63) *(u32 *)(r10 -4) = r0
   2: (bf) r2 = r10
   3: (07) r2 += -4
   4: (18) r1 = map[id:64]
...

Π’Π°ΠΊΠ°, ΠΌΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° Π·Π°ΠΊΠ»ΡƒΡ‡ΠΈΠΌΠ΅ Π΄Π΅ΠΊΠ° Π²ΠΎ ΠΌΠΎΠΌΠ΅Π½Ρ‚ΠΎΡ‚ Π½Π° ΡΡ‚Π°Ρ€Ρ‚ΡƒΠ²Π°ΡšΠ΅ Π½Π° Π½Π°ΡˆΠ°Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° Π·Π° Π²Ρ‡ΠΈΡ‚ΡƒΠ²Π°ΡšΠ΅, врската Π΄ΠΎ &woo бСшС Π·Π°ΠΌΠ΅Π½Π΅Ρ‚ со Π½Π΅ΡˆΡ‚ΠΎ со Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° libbpf. ΠŸΡ€Π²ΠΎ ќС Π³ΠΎ Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ ΠΈΠ·Π»Π΅Π·ΠΎΡ‚ strace:

$ sudo strace -e bpf ./xdp-simple
...
bpf(BPF_MAP_CREATE, {map_type=BPF_MAP_TYPE_ARRAY, key_size=4, value_size=8, max_entries=8, map_name="woo", ...}, 120) = 4
bpf(BPF_PROG_LOAD, {prog_type=BPF_PROG_TYPE_XDP, prog_name="simple", ...}, 120) = 5

Π“ΠΎ Π³Π»Π΅Π΄Π°ΠΌΠ΅ Ρ‚ΠΎΠ° libbpf создадС ΠΌΠ°ΠΏΠ° woo Π° ΠΏΠΎΡ‚ΠΎΠ° ја ΠΏΡ€Π΅Π·Π΅ΠΌΠ°Π²ΠΌΠ΅ Π½Π°ΡˆΠ°Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° simple. АјдС Π²Π½ΠΈΠΌΠ°Ρ‚Π΅Π»Π½ΠΎ Π΄Π° ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ ΠΊΠ°ΠΊΠΎ ја Π²Ρ‡ΠΈΡ‚ΡƒΠ²Π°ΠΌΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π°:

  • Ρ˜Π°Π²Π΅Ρ‚Π΅ сС xdp_simple_bpf__open_and_load ΠΎΠ΄ Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ° xdp-simple.skel.h
  • ΡˆΡ‚ΠΎ ΠΏΡ€Π΅Π΄ΠΈΠ·Π²ΠΈΠΊΡƒΠ²Π° xdp_simple_bpf__load ΠΎΠ΄ Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ° xdp-simple.skel.h
  • ΡˆΡ‚ΠΎ ΠΏΡ€Π΅Π΄ΠΈΠ·Π²ΠΈΠΊΡƒΠ²Π° bpf_object__load_skeleton ΠΎΠ΄ Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ° libbpf/src/libbpf.c
  • ΡˆΡ‚ΠΎ ΠΏΡ€Π΅Π΄ΠΈΠ·Π²ΠΈΠΊΡƒΠ²Π° bpf_object__load_xattr Π½Π° libbpf/src/libbpf.c

ΠŸΠΎΡΠ»Π΅Π΄Π½Π°Ρ‚Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡ˜Π°, ΠΌΠ΅Ρ“Ρƒ Π΄Ρ€ΡƒΠ³ΠΎΡ‚ΠΎ, ќС сС јави bpf_object__create_maps, кој создава ΠΈΠ»ΠΈ ΠΎΡ‚Π²ΠΎΡ€Π° постоСчки ΠΌΠ°ΠΏΠΈ, ΠΏΡ€Π΅Ρ‚Π²ΠΎΡ€Π°Ρ˜ΡœΠΈ Π³ΠΈ Π²ΠΎ дСскриптори Π½Π° Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠΈ. (ОвдС Π³Π»Π΅Π΄Π°ΠΌΠ΅ BPF_MAP_CREATE Π²ΠΎ ΠΈΠ·Π»Π΅Π·ΠΎΡ‚ strace.) ΠŸΠΎΡ‚ΠΎΠ° сС ΠΏΠΎΠ²ΠΈΠΊΡƒΠ²Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡ˜Π°Ρ‚Π° bpf_object__relocate ΠΈ Ρ‚Π°Π° Π΅ Ρ‚Π°Π° ΡˆΡ‚ΠΎ Π½Π΅ интСрСсира, бидСјќи сС сСќавамС ΡˆΡ‚ΠΎ Π²ΠΈΠ΄ΠΎΠ²ΠΌΠ΅ woo Π²ΠΎ Ρ‚Π°Π±Π΅Π»Π°Ρ‚Π° Π·Π° ΠΏΡ€Π΅ΠΌΠ΅ΡΡ‚ΡƒΠ²Π°ΡšΠ΅. Π˜ΡΡ‚Ρ€Π°ΠΆΡƒΠ²Π°Ρ˜ΡœΠΈ Π³ΠΎ, Π½Π° ΠΊΡ€Π°Ρ˜ΠΎΡ‚ сС Π½Π°ΠΎΡ“Π°ΠΌΠ΅ Π²ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡ˜Π° bpf_program__relocate, ΠΊΠΎΠΈ сС Π·Π°Π½ΠΈΠΌΠ°Π²Π° со ΠΏΡ€Π΅ΠΌΠ΅ΡΡ‚ΡƒΠ²Π°ΡšΠ΅ Π½Π° ΠΊΠ°Ρ€Ρ‚ΠΈ:

case RELO_LD64:
    insn[0].src_reg = BPF_PSEUDO_MAP_FD;
    insn[0].imm = obj->maps[relo->map_idx].fd;
    break;

Π—Π°Ρ‚ΠΎΠ°, Π³ΠΈ Π·Π΅ΠΌΠ°ΠΌΠ΅ Π½Π°ΡˆΠΈΡ‚Π΅ упатства

18 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r1 = 0 ll

ΠΈ Π·Π°ΠΌΠ΅Π½Π΅Ρ‚Π΅ Π³ΠΎ ΠΈΠ·Π²ΠΎΡ€Π½ΠΈΠΎΡ‚ рСгистар Π²ΠΎ Π½Π΅Π³ΠΎ со BPF_PSEUDO_MAP_FD, ΠΈ ΠΏΡ€Π²ΠΈΠΎΡ‚ IMM Π½Π° дСскрипторот Π½Π° Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ°Ρ‚Π° Π½Π° Π½Π°ΡˆΠ°Ρ‚Π° ΠΊΠ°Ρ€Ρ‚Π° ΠΈ, Π°ΠΊΠΎ Π΅ Π΅Π΄Π½Π°ΠΊΠΎΠ² Π½Π°, Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€, 0xdeadbeef, Ρ‚ΠΎΠ³Π°Ρˆ ΠΊΠ°ΠΊΠΎ Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚ ќС ја Π΄ΠΎΠ±ΠΈΠ΅ΠΌΠ΅ ΠΈΠ½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡ˜Π°Ρ‚Π°

18 11 00 00 ef eb ad de 00 00 00 00 00 00 00 00 r1 = 0 ll

Ова Π΅ Π½Π°Ρ‡ΠΈΠ½ΠΎΡ‚ Π½Π° кој ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈΡ‚Π΅ Π·Π° ΠΊΠ°Ρ€Ρ‚Π°Ρ‚Π° сС прСнСсуваат Π½Π° ΠΎΠ΄Ρ€Π΅Π΄Π΅Π½Π° Π²Ρ‡ΠΈΡ‚Π°Π½Π° BPF ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°. Π’ΠΎ овој ΡΠ»ΡƒΡ‡Π°Ρ˜, ΠΌΠ°ΠΏΠ°Ρ‚Π° ΠΌΠΎΠΆΠ΅ Π΄Π° сС ΠΊΡ€Π΅ΠΈΡ€Π° со ΠΊΠΎΡ€ΠΈΡΡ‚Π΅ΡšΠ΅ BPF_MAP_CREATE, ΠΈ сС ΠΎΡ‚Π²ΠΎΡ€ΠΈ со ID ΠΊΠΎΡ€ΠΈΡΡ‚Π΅Ρ˜ΡœΠΈ BPF_MAP_GET_FD_BY_ID.

Π’ΠΊΡƒΠΏΠ½ΠΎ, ΠΏΡ€ΠΈ ΠΊΠΎΡ€ΠΈΡΡ‚Π΅ΡšΠ΅ libbpf Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠΎΡ‚ Π΅ ΠΊΠ°ΠΊΠΎ ΡˆΡ‚ΠΎ слСдува:

  • Π·Π° Π²Ρ€Π΅ΠΌΠ΅ Π½Π° ΠΊΠΎΠΌΠΏΠΈΠ»Π°Ρ†ΠΈΡ˜Π°Ρ‚Π°, Π²ΠΎ Ρ‚Π°Π±Π΅Π»Π°Ρ‚Π° Π·Π° ΠΏΡ€Π΅ΠΌΠ΅ΡΡ‚ΡƒΠ²Π°ΡšΠ΅ сС ΠΊΡ€Π΅ΠΈΡ€Π°Π°Ρ‚ записи Π·Π° врски Π΄ΠΎ ΠΌΠ°ΠΏΠΈ
  • libbpf ја ΠΎΡ‚Π²ΠΎΡ€Π° ΠΊΠ½ΠΈΠ³Π°Ρ‚Π° со ΠΎΠ±Ρ˜Π΅ΠΊΡ‚ΠΈ ELF, Π³ΠΈ Π½Π°ΠΎΡ“Π° ситС користСни ΠΌΠ°ΠΏΠΈ ΠΈ создава дСскриптори Π½Π° Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠΈ Π·Π° Π½ΠΈΠ²
  • дСскрипторитС Π½Π° Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠΈΡ‚Π΅ сС Π²Ρ‡ΠΈΡ‚ΡƒΠ²Π°Π°Ρ‚ Π²ΠΎ ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚ ΠΊΠ°ΠΊΠΎ Π΄Π΅Π» ΠΎΠ΄ ΠΈΠ½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡ˜Π°Ρ‚Π° LD64

Како ΡˆΡ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° замислитС, прСтстои ΡƒΡˆΡ‚Π΅ повСќС ΠΈ ќС ΠΌΠΎΡ€Π°ΠΌΠ΅ Π΄Π° ја Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ ΡΡƒΡˆΡ‚ΠΈΠ½Π°Ρ‚Π°. Π—Π° ΡΡ€Π΅ΡœΠ°, ΠΈΠΌΠ°ΠΌΠ΅ ΠΏΠΎΠΈΠΌ - Π³ΠΎ запишавмС Π·Π½Π°Ρ‡Π΅ΡšΠ΅Ρ‚ΠΎ BPF_PSEUDO_MAP_FD Π²ΠΎ ΠΈΠ·Π²ΠΎΡ€Π½ΠΈΠΎΡ‚ рСгистар ΠΈ ΠΌΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° Π³ΠΎ Π·Π°ΠΊΠΎΠΏΠ°ΠΌΠ΅, ΡˆΡ‚ΠΎ ќС Π½Π΅ ΠΎΠ΄Π²Π΅Π΄Π΅ Π΄ΠΎ ΡΠ²Π΅Ρ‚ΠΈΡšΠ°Ρ‚Π° Π½Π° ситС свСтци - kernel/bpf/verifier.c, ΠΊΠ°Π΄Π΅ ΡˆΡ‚ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡ˜Π°Ρ‚Π° со карактСристично ΠΈΠΌΠ΅ Π·Π°ΠΌΠ΅Π½ΡƒΠ²Π° дСскриптор Π½Π° Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ° со адрСса Π½Π° структура ΠΎΠ΄ Ρ‚ΠΈΠΏΠΎΡ‚ struct bpf_map:

static int replace_map_fd_with_map_ptr(struct bpf_verifier_env *env) {
    ...

    f = fdget(insn[0].imm);
    map = __bpf_map_get(f);
    if (insn->src_reg == BPF_PSEUDO_MAP_FD) {
        addr = (unsigned long)map;
    }
    insn[0].imm = (u32)addr;
    insn[1].imm = addr >> 32;

(ΠΌΠΎΠΆΠ΅ Π΄Π° сС најдС цСлосниот ΠΊΠΎΠ΄ ΠΏΠΎ ссылкС). Π’Π°ΠΊΠ°, ΠΌΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° Π³ΠΎ ΠΏΡ€ΠΎΡˆΠΈΡ€ΠΈΠΌΠ΅ Π½Π°ΡˆΠΈΠΎΡ‚ Π°Π»Π³ΠΎΡ€ΠΈΡ‚Π°ΠΌ:

  • Π΄ΠΎΠ΄Π΅ΠΊΠ° ја Π²Ρ‡ΠΈΡ‚ΡƒΠ²Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π°, Π²Π΅Ρ€ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ΠΎΡ‚ ја ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡƒΠ²Π° ΠΏΡ€Π°Π²ΠΈΠ»Π½Π°Ρ‚Π° ΡƒΠΏΠΎΡ‚Ρ€Π΅Π±Π° Π½Π° ΠΊΠ°Ρ€Ρ‚Π°Ρ‚Π° ΠΈ ја ΠΏΠΈΡˆΡƒΠ²Π° адрСсата Π½Π° соодвСтната структура struct bpf_map

Кога ја ΠΏΡ€Π΅Π·Π΅ΠΌΠ°Ρ‚Π΅ Π±ΠΈΠ½Π°Ρ€Π½Π°Ρ‚Π° ELF ΠΊΠΎΡ€ΠΈΡΡ‚Π΅Ρ˜ΡœΠΈ libbpf Има ΡƒΡˆΡ‚Π΅ ΠΌΠ½ΠΎΠ³Ρƒ Ρ€Π°Π±ΠΎΡ‚ΠΈ, Π½ΠΎ ќС Ρ€Π°Π·Π³ΠΎΠ²Π°Ρ€Π°ΠΌΠ΅ Π·Π° Ρ‚ΠΎΠ° Π²ΠΎ Π΄Ρ€ΡƒΠ³ΠΈ статии.

Π’Ρ‡ΠΈΡ‚ΡƒΠ²Π°ΡšΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ ΠΈ ΠΌΠ°ΠΏΠΈ Π±Π΅Π· libbpf

Како ΡˆΡ‚ΠΎ Π²Π΅Ρ‚ΠΈΠ²ΠΌΠ΅, Π΅Π²Π΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π·Π° Ρ‡ΠΈΡ‚Π°Ρ‚Π΅Π»ΠΈΡ‚Π΅ ΠΊΠΎΠΈ сакаат Π΄Π° Π·Π½Π°Π°Ρ‚ ΠΊΠ°ΠΊΠΎ Π΄Π° ΠΊΡ€Π΅ΠΈΡ€Π°Π°Ρ‚ ΠΈ Π²Ρ‡ΠΈΡ‚Π°Π°Ρ‚ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° ΡˆΡ‚ΠΎ користи ΠΌΠ°ΠΏΠΈ, Π±Π΅Π· помош libbpf. Ова ΠΌΠΎΠΆΠ΅ Π΄Π° Π±ΠΈΠ΄Π΅ корисно ΠΊΠΎΠ³Π° Ρ€Π°Π±ΠΎΡ‚ΠΈΡ‚Π΅ Π²ΠΎ срСдина Π·Π° која Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° создаватС зависности, ΠΈΠ»ΠΈ Π΄Π° Π³ΠΎ Π·Π°Ρ‡ΡƒΠ²ΡƒΠ²Π°Ρ‚Π΅ сСкој Π΄Π΅Π» ΠΈΠ»ΠΈ ΠΊΠΎΠ³Π° ΠΏΠΈΡˆΡƒΠ²Π°Ρ‚Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° ΠΊΠ°ΠΊΠΎ ply, кој Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π° Π±ΠΈΠ½Π°Ρ€Π΅Π½ ΠΊΠΎΠ΄ BPF Π²ΠΎ Π»Π΅Ρ‚.

Π—Π° полСсно Π΄Π° сС слСди Π»ΠΎΠ³ΠΈΠΊΠ°Ρ‚Π°, ќС Π³ΠΎ ΠΏΡ€Π΅Ρ€Π°Π±ΠΎΡ‚ΠΈΠΌΠ΅ Π½Π°ΡˆΠΈΠΎΡ‚ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π·Π° ΠΎΠ²ΠΈΠ΅ Ρ†Π΅Π»ΠΈ xdp-simple. ЦСлосниот ΠΈ ΠΌΠ°Π»ΠΊΡƒ ΠΏΡ€ΠΎΡˆΠΈΡ€Π΅Π½ ΠΊΠΎΠ΄ Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° дискутирана Π²ΠΎ овој ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΌΠΎΠΆΠ΅ Π΄Π° сС најдС Π²ΠΎ ΠΎΠ²Π° Ρ„ΠΈΠ³ΡƒΡ€Π°.

Π›ΠΎΠ³ΠΈΠΊΠ°Ρ‚Π° Π½Π° Π½Π°ΡˆΠ°Ρ‚Π° Π°ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΡ˜Π° Π΅ слСдна:

  • ΠΊΡ€Π΅ΠΈΡ€Π°Ρ˜Ρ‚Π΅ ΠΌΠ°ΠΏΠ° Π½Π° Ρ‚ΠΈΠΏ BPF_MAP_TYPE_ARRAY ΠΊΠΎΡ€ΠΈΡΡ‚Π΅Ρ˜ΡœΠΈ ја ΠΊΠΎΠΌΠ°Π½Π΄Π°Ρ‚Π° BPF_MAP_CREATE,
  • ΠΊΡ€Π΅ΠΈΡ€Π°Ρ˜Ρ‚Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° ΡˆΡ‚ΠΎ ја користи ΠΎΠ²Π°Π° ΠΊΠ°Ρ€Ρ‚Π°,
  • ΠΏΠΎΠ²Ρ€Π·Π΅Ρ‚Π΅ ја ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° со ΠΈΠ½Ρ‚Π΅Ρ€Ρ„Π΅Ρ˜ΡΠΎΡ‚ lo,

ΡˆΡ‚ΠΎ сС ΠΏΡ€Π΅Π²Π΅Π΄ΡƒΠ²Π° Π²ΠΎ Ρ‡ΠΎΠ²Π΅Ρ‡ΠΊΠΎ ΠΊΠ°ΠΊΠΎ

int main(void)
{
    int map_fd, prog_fd;

    map_fd = map_create();
    if (map_fd < 0)
        err(1, "bpf: BPF_MAP_CREATE");

    prog_fd = prog_load(map_fd);
    if (prog_fd < 0)
        err(1, "bpf: BPF_PROG_LOAD");

    xdp_attach(1, prog_fd);
}

Π’ΡƒΠΊΠ° map_create создава ΠΊΠ°Ρ€Ρ‚Π° Π½Π° ист Π½Π°Ρ‡ΠΈΠ½ ΠΊΠ°ΠΊΠΎ ΡˆΡ‚ΠΎ Π½Π°ΠΏΡ€Π°Π²ΠΈΠ²ΠΌΠ΅ Π²ΠΎ ΠΏΡ€Π²ΠΈΠΎΡ‚ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π·Π° систСмскиот ΠΏΠΎΠ²ΠΈΠΊ bpf - β€žΠˆΠ°Π΄Ρ€ΠΎ, Ρ‚Π΅ ΠΌΠΎΠ»Π°ΠΌ Π½Π°ΠΏΡ€Π°Π²ΠΈ ΠΌΠΈ Π½ΠΎΠ²Π° ΠΌΠ°ΠΏΠ° Π²ΠΎ Ρ„ΠΎΡ€ΠΌΠ° Π½Π° Π½ΠΈΠ·Π° ΠΎΠ΄ 8 Π΅Π»Π΅ΠΌΠ΅Π½Ρ‚ΠΈ ΠΊΠ°ΠΊΠΎ __u64 ΠΈ Π²Ρ€Π°Ρ‚Π΅Ρ‚Π΅ ΠΌΠΈ Π³ΠΎ дСскрипторот Π½Π° Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ°Ρ‚Π°β€œ:

static int map_create()
{
    union bpf_attr attr;

    memset(&attr, 0, sizeof(attr));
    attr.map_type = BPF_MAP_TYPE_ARRAY,
    attr.key_size = sizeof(__u32),
    attr.value_size = sizeof(__u64),
    attr.max_entries = 8,
    strncpy(attr.map_name, "woo", sizeof(attr.map_name));
    return syscall(__NR_bpf, BPF_MAP_CREATE, &attr, sizeof(attr));
}

ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° Π΅ исто Ρ‚Π°ΠΊΠ° лСсна Π·Π° Π²Ρ‡ΠΈΡ‚ΡƒΠ²Π°ΡšΠ΅:

static int prog_load(int map_fd)
{
    union bpf_attr attr;
    struct bpf_insn insns[] = {
        ...
    };

    memset(&attr, 0, sizeof(attr));
    attr.prog_type = BPF_PROG_TYPE_XDP;
    attr.insns     = ptr_to_u64(insns);
    attr.insn_cnt  = sizeof(insns)/sizeof(insns[0]);
    attr.license   = ptr_to_u64("GPL");
    strncpy(attr.prog_name, "woo", sizeof(attr.prog_name));
    return syscall(__NR_bpf, BPF_PROG_LOAD, &attr, sizeof(attr));
}

Π’Π΅ΡˆΠΊΠΈΠΎΡ‚ Π΄Π΅Π» prog_load Π΅ Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ†ΠΈΡ˜Π°Ρ‚Π° Π½Π° Π½Π°ΡˆΠ°Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° BPF ΠΊΠ°ΠΊΠΎ Π½ΠΈΠ·Π° структури struct bpf_insn insns[]. Но, бидСјќи користимС ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° ΡˆΡ‚ΠΎ ја ΠΈΠΌΠ°ΠΌΠ΅ Π²ΠΎ C, ΠΌΠΎΠΆΠ΅ΠΌΠ΅ ΠΌΠ°Π»ΠΊΡƒ Π΄Π° ΠΈΠ·ΠΌΠ°ΠΌΠΈΠΌΠ΅:

$ llvm-objdump -D --section xdp/simple xdp-simple.bpf.o

0000000000000000 <simple>:
       0:       85 00 00 00 08 00 00 00 call 8
       1:       63 0a fc ff 00 00 00 00 *(u32 *)(r10 - 4) = r0
       2:       bf a2 00 00 00 00 00 00 r2 = r10
       3:       07 02 00 00 fc ff ff ff r2 += -4
       4:       18 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r1 = 0 ll
       6:       85 00 00 00 01 00 00 00 call 1
       7:       b7 01 00 00 00 00 00 00 r1 = 0
       8:       15 00 04 00 00 00 00 00 if r0 == 0 goto +4 <LBB0_2>
       9:       61 01 00 00 00 00 00 00 r1 = *(u32 *)(r0 + 0)
      10:       07 01 00 00 01 00 00 00 r1 += 1
      11:       63 10 00 00 00 00 00 00 *(u32 *)(r0 + 0) = r1
      12:       b7 01 00 00 02 00 00 00 r1 = 2

0000000000000068 <LBB0_2>:
      13:       bf 10 00 00 00 00 00 00 r0 = r1
      14:       95 00 00 00 00 00 00 00 exit

Π‘Π΅Π²ΠΊΡƒΠΏΠ½ΠΎ, Ρ‚Ρ€Π΅Π±Π° Π΄Π° напишСмС 14 инструкции Π²ΠΎ Ρ„ΠΎΡ€ΠΌΠ° Π½Π° структури ΠΊΠ°ΠΊΠΎ struct bpf_insn (совСт: Π·Π΅ΠΌΠ΅Ρ‚Π΅ Π³ΠΎ Π΄Π΅ΠΏΠΎΠ½ΠΈΡ˜Π°Ρ‚Π° ΠΎΠ΄ΠΎΠ·Π³ΠΎΡ€Π°, ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎ ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Ρ˜Ρ‚Π΅ Π³ΠΎ Π΄Π΅Π»ΠΎΡ‚ Π·Π° инструкции, ΠΎΡ‚Π²ΠΎΡ€Π΅Ρ‚Π΅ 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 Π±Π΅Π° ΠΎΠ΄ онлајн Π·Π°Π΅Π΄Π½ΠΈΡ†Π°Ρ‚Π° Линукс, ΡˆΡ‚ΠΎ Π·Π½Π°Ρ‡ΠΈ Π΄Π΅ΠΊΠ° ја користСа ΠΎΠ½Π°Π° ΡˆΡ‚ΠΎ ΠΈΠΌ Π΅ Π½Π°Ρ˜ΠΏΠΎΠ·Π½Π°Ρ‚Π° (Π½ΠΎ Π½Π΅ ΠΈ Π½ΠΎΡ€ΠΌΠ°Π»Π½ΠΎ Π»ΡƒΡ“Π΅) ΠΈΠ½Ρ‚Π΅Ρ€Ρ„Π΅Ρ˜Ρ Π·Π° ΠΈΠ½Ρ‚Π΅Ρ€Π°ΠΊΡ†ΠΈΡ˜Π° со ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚: netlink ΠΏΡ€ΠΈΠΊΠ»ΡƒΡ‡ΠΎΡ†ΠΈ, исто Ρ‚Π°ΠΊΠ° Π²ΠΈΠ΄ΠΈ RFC3549. ΠΠ°Ρ˜Π΅Π΄Π½ΠΎΡΡ‚Π°Π²Π½ΠΈΠΎΡ‚ Π½Π°Ρ‡ΠΈΠ½ Π·Π° ΠΈΠΌΠΏΠ»Π΅ΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡ˜Π° xdp_attach Π³ΠΎ ΠΊΠΎΠΏΠΈΡ€Π° ΠΊΠΎΠ΄ΠΎΡ‚ ΠΎΠ΄ libbpf, ΠΈΠΌΠ΅Π½ΠΎ, ΠΎΠ΄ Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ°Ρ‚Π° netlink.c, ΡˆΡ‚ΠΎ ΠΈ Π³ΠΎ Π½Π°ΠΏΡ€Π°Π²ΠΈΠ²ΠΌΠ΅, ΡΠΊΡ€Π°Ρ‚ΡƒΠ²Π°Ρ˜ΡœΠΈ Π³ΠΎ ΠΌΠ°Π»ΠΊΡƒ:

Π”ΠΎΠ±Ρ€Π΅Π΄ΠΎΡ˜Π΄ΠΎΠ²Ρ‚Π΅ Π²ΠΎ свСтот Π½Π° Π½Π΅Ρ‚Π»ΠΈΠ½ΠΊ ΠΏΡ€ΠΈΠΊΠ»ΡƒΡ‡ΠΎΡ†ΠΈΡ‚Π΅

ΠžΡ‚Π²ΠΎΡ€Π΅Ρ‚Π΅ Ρ‚ΠΈΠΏ Π½Π° ΠΌΡ€Π΅ΠΆΠ΅Π½ ΠΏΡ€ΠΈΠΊΠ»ΡƒΡ‡ΠΎΠΊ NETLINK_ROUTE:

int netlink_open(__u32 *nl_pid)
{
    struct sockaddr_nl sa;
    socklen_t addrlen;
    int one = 1, ret;
    int sock;

    memset(&sa, 0, sizeof(sa));
    sa.nl_family = AF_NETLINK;

    sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
    if (sock < 0)
        err(1, "socket");

    if (setsockopt(sock, SOL_NETLINK, NETLINK_EXT_ACK, &one, sizeof(one)) < 0)
        warnx("netlink error reporting not supported");

    if (bind(sock, (struct sockaddr *)&sa, sizeof(sa)) < 0)
        err(1, "bind");

    addrlen = sizeof(sa);
    if (getsockname(sock, (struct sockaddr *)&sa, &addrlen) < 0)
        err(1, "getsockname");

    *nl_pid = sa.nl_pid;
    return sock;
}

Π§ΠΈΡ‚Π°ΠΌΠ΅ ΠΎΠ΄ овој сокСт:

static int bpf_netlink_recv(int sock, __u32 nl_pid, int seq)
{
    bool multipart = true;
    struct nlmsgerr *errm;
    struct nlmsghdr *nh;
    char buf[4096];
    int len, ret;

    while (multipart) {
        multipart = false;
        len = recv(sock, buf, sizeof(buf), 0);
        if (len < 0)
            err(1, "recv");

        if (len == 0)
            break;

        for (nh = (struct nlmsghdr *)buf; NLMSG_OK(nh, len);
                nh = NLMSG_NEXT(nh, len)) {
            if (nh->nlmsg_pid != nl_pid)
                errx(1, "wrong pid");
            if (nh->nlmsg_seq != seq)
                errx(1, "INVSEQ");
            if (nh->nlmsg_flags & NLM_F_MULTI)
                multipart = true;
            switch (nh->nlmsg_type) {
                case NLMSG_ERROR:
                    errm = (struct nlmsgerr *)NLMSG_DATA(nh);
                    if (!errm->error)
                        continue;
                    ret = errm->error;
                    // libbpf_nla_dump_errormsg(nh); too many code to copy...
                    goto done;
                case NLMSG_DONE:
                    return 0;
                default:
                    break;
            }
        }
    }
    ret = 0;
done:
    return ret;
}

ΠšΠΎΠ½Π΅Ρ‡Π½ΠΎ, Ρ‚ΡƒΠΊΠ° Π΅ Π½Π°ΡˆΠ°Ρ‚Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡ˜Π° која ΠΎΡ‚Π²ΠΎΡ€Π° сокСт ΠΈ ΠΈΡΠΏΡ€Π°ΡœΠ° посСбна ΠΏΠΎΡ€Π°ΠΊΠ° Π΄ΠΎ Π½Π΅Π³ΠΎ ΡˆΡ‚ΠΎ содрТи дСскриптор Π½Π° Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ°:

static int xdp_attach(int ifindex, int prog_fd)
{
    int sock, seq = 0, ret;
    struct nlattr *nla, *nla_xdp;
    struct {
        struct nlmsghdr  nh;
        struct ifinfomsg ifinfo;
        char             attrbuf[64];
    } req;
    __u32 nl_pid = 0;

    sock = netlink_open(&nl_pid);
    if (sock < 0)
        return sock;

    memset(&req, 0, sizeof(req));
    req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
    req.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
    req.nh.nlmsg_type = RTM_SETLINK;
    req.nh.nlmsg_pid = 0;
    req.nh.nlmsg_seq = ++seq;
    req.ifinfo.ifi_family = AF_UNSPEC;
    req.ifinfo.ifi_index = ifindex;

    /* started nested attribute for XDP */
    nla = (struct nlattr *)(((char *)&req)
            + NLMSG_ALIGN(req.nh.nlmsg_len));
    nla->nla_type = NLA_F_NESTED | IFLA_XDP;
    nla->nla_len = NLA_HDRLEN;

    /* add XDP fd */
    nla_xdp = (struct nlattr *)((char *)nla + nla->nla_len);
    nla_xdp->nla_type = IFLA_XDP_FD;
    nla_xdp->nla_len = NLA_HDRLEN + sizeof(int);
    memcpy((char *)nla_xdp + NLA_HDRLEN, &prog_fd, sizeof(prog_fd));
    nla->nla_len += nla_xdp->nla_len;

    /* if user passed in any flags, add those too */
    __u32 flags = XDP_FLAGS_SKB_MODE;
    nla_xdp = (struct nlattr *)((char *)nla + nla->nla_len);
    nla_xdp->nla_type = IFLA_XDP_FLAGS;
    nla_xdp->nla_len = NLA_HDRLEN + sizeof(flags);
    memcpy((char *)nla_xdp + NLA_HDRLEN, &flags, sizeof(flags));
    nla->nla_len += nla_xdp->nla_len;

    req.nh.nlmsg_len += NLA_ALIGN(nla->nla_len);

    if (send(sock, &req, req.nh.nlmsg_len, 0) < 0)
        err(1, "send");
    ret = bpf_netlink_recv(sock, nl_pid, seq);

cleanup:
    close(sock);
    return ret;
}

Π—Π½Π°Ρ‡ΠΈ, сè Π΅ ΠΏΠΎΠ΄Π³ΠΎΡ‚Π²Π΅Π½ΠΎ Π·Π° Ρ‚Π΅ΡΡ‚ΠΈΡ€Π°ΡšΠ΅:

$ cc nolibbpf.c -o nolibbpf
$ sudo strace -e bpf ./nolibbpf
bpf(BPF_MAP_CREATE, {map_type=BPF_MAP_TYPE_ARRAY, map_name="woo", ...}, 72) = 3
bpf(BPF_PROG_LOAD, {prog_type=BPF_PROG_TYPE_XDP, insn_cnt=15, prog_name="woo", ...}, 72) = 4
+++ exited with 0 +++

АјдС Π΄Π° Π²ΠΈΠ΄ΠΈΠΌΠ΅ Π΄Π°Π»ΠΈ Π½Π°ΡˆΠ°Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° Π΅ ΠΏΠΎΠ²Ρ€Π·Π°Π½Π° со lo:

$ ip l show dev lo
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 xdpgeneric qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    prog/xdp id 160

АјдС Π΄Π° испратимС ΠΏΠΈΠ½Π³ ΠΈ Π΄Π° ја ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ ΠΌΠ°ΠΏΠ°Ρ‚Π°:

$ for s in `seq 234`; do sudo ping -f -c 100 127.0.0.1 >/dev/null 2>&1; done
$ sudo bpftool m dump name woo
key: 00 00 00 00  value: 90 01 00 00 00 00 00 00
key: 01 00 00 00  value: 00 00 00 00 00 00 00 00
key: 02 00 00 00  value: 00 00 00 00 00 00 00 00
key: 03 00 00 00  value: 00 00 00 00 00 00 00 00
key: 04 00 00 00  value: 00 00 00 00 00 00 00 00
key: 05 00 00 00  value: 00 00 00 00 00 00 00 00
key: 06 00 00 00  value: 40 b5 00 00 00 00 00 00
key: 07 00 00 00  value: 00 00 00 00 00 00 00 00
Found 8 elements

Π£Ρ€Π°, сè Ρ€Π°Π±ΠΎΡ‚ΠΈ. Π—Π°Π±Π΅Π»Π΅ΠΆΠ΅Ρ‚Π΅, ΠΏΠ°Ρ‚Π΅ΠΌ, Π΄Π΅ΠΊΠ° Π½Π°ΡˆΠ°Ρ‚Π° ΠΊΠ°Ρ€Ρ‚Π° ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎ Π΅ ΠΏΡ€ΠΈΠΊΠ°ΠΆΠ°Π½Π° Π²ΠΎ Ρ„ΠΎΡ€ΠΌΠ° Π½Π° Π±Π°Ρ˜Ρ‚ΠΈ. Ова сС Π΄ΠΎΠ»ΠΆΠΈ Π½Π° Ρ„Π°ΠΊΡ‚ΠΎΡ‚ Π΄Π΅ΠΊΠ°, Π·Π° Ρ€Π°Π·Π»ΠΈΠΊΠ° ΠΎΠ΄ libbpf Π½Π΅ Π²Ρ‡ΠΈΡ‚Π°Π²ΠΌΠ΅ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ Π·Π° Ρ‚ΠΈΠΏΠΎΡ‚ (BTF). Но, слСдниот ΠΏΠ°Ρ‚ ќС Π·Π±ΠΎΡ€ΡƒΠ²Π°ΠΌΠ΅ повСќС Π·Π° ΠΎΠ²Π°.

Алатки Π·Π° Ρ€Π°Π·Π²ΠΎΡ˜

Π’ΠΎ овој Π΄Π΅Π», ќС Π³ΠΎ Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»Π½ΠΈΠΎΡ‚ ΠΏΠ°ΠΊΠ΅Ρ‚ со Π°Π»Π°Ρ‚ΠΊΠΈ Π·Π° Ρ€Π°Π·Π²ΠΈΠ²Π°Ρ‡ΠΈ Π½Π° BPF.

ΠžΠΏΡˆΡ‚ΠΎ Π·Π΅ΠΌΠ΅Π½ΠΎ, Π½Π΅ Π²ΠΈ Ρ‚Ρ€Π΅Π±Π° Π½ΠΈΡˆΡ‚ΠΎ посСбно Π·Π° Π΄Π° Ρ€Π°Π·Π²ΠΈΠ΅Ρ‚Π΅ BPF ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ - BPF Ρ€Π°Π±ΠΎΡ‚ΠΈ Π½Π° ΠΊΠΎΠ΅ Π±ΠΈΠ»ΠΎ ΠΏΡ€ΠΈΡΡ‚ΠΎΡ˜Π½ΠΎ Ρ˜Π°Π΄Ρ€ΠΎ Π·Π° Π΄ΠΈΡΡ‚Ρ€ΠΈΠ±ΡƒΡ†ΠΈΡ˜Π°, Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ сС ΠΈΠ·Π³Ρ€Π°Π΄Π΅Π½ΠΈ со ΠΊΠΎΡ€ΠΈΡΡ‚Π΅ΡšΠ΅ clang, кој ΠΌΠΎΠΆΠ΅ Π΄Π° сС Π½Π°Π±Π°Π²ΠΈ ΠΎΠ΄ ΠΏΠ°ΠΊΡƒΠ²Π°ΡšΠ΅Ρ‚ΠΎ. Π‘Π΅ΠΏΠ°ΠΊ, ΠΏΠΎΡ€Π°Π΄ΠΈ Ρ„Π°ΠΊΡ‚ΠΎΡ‚ ΡˆΡ‚ΠΎ BPF Π΅ Π²ΠΎ Ρ€Π°Π·Π²ΠΎΡ˜, ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚ ΠΈ Π°Π»Π°Ρ‚ΠΊΠΈΡ‚Π΅ ΠΏΠΎΡΡ‚ΠΎΡ˜Π°Π½ΠΎ сС ΠΌΠ΅Π½ΡƒΠ²Π°Π°Ρ‚, Π°ΠΊΠΎ Π½Π΅ сакатС Π΄Π° ΠΏΠΈΡˆΡƒΠ²Π°Ρ‚Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ Π·Π° BPF ΠΊΠΎΡ€ΠΈΡΡ‚Π΅Ρ˜ΡœΠΈ старомодни ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈ ΠΎΠ΄ 2019 Π³ΠΎΠ΄ΠΈΠ½Π°, Ρ‚ΠΎΠ³Π°Ρˆ ќС ΠΌΠΎΡ€Π° Π΄Π° ΠΊΠΎΠΌΠΏΠ°Ρ˜Π»ΠΈΡ€Π°Ρ‚Π΅

  • llvm/clang
  • pahole
  • Π½Π΅Π³ΠΎΠ²ΠΎΡ‚ΠΎ Ρ˜Π°Π΄Ρ€ΠΎ
  • bpftool

(Π—Π° Ρ€Π΅Ρ„Π΅Ρ€Π΅Π½Ρ†Π°, овој Π΄Π΅Π» ΠΈ ситС ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΈ Π²ΠΎ ΡΡ‚Π°Ρ‚ΠΈΡ˜Π°Ρ‚Π° Π±Π΅Π° ΠΈΠ·Π²Ρ€ΡˆΠ΅Π½ΠΈ Π½Π° Debian 10.)

llvm/clang

BPF Π΅ ΠΏΡ€ΠΈΡ˜Π°Ρ‚Π΅Π»ΡΠΊΠΈ располоТСн со LLVM ΠΈ, ΠΈΠ°ΠΊΠΎ Π½Π΅ΠΎΠ΄Π°ΠΌΠ½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ Π·Π° BPF ΠΌΠΎΠΆΠ΅ Π΄Π° сС ΠΊΠΎΠΌΠΏΠ°Ρ˜Π»ΠΈΡ€Π°Π°Ρ‚ со ΠΊΠΎΡ€ΠΈΡΡ‚Π΅ΡšΠ΅ Π½Π° gcc, Ρ†Π΅Π»ΠΈΠΎΡ‚ Ρ‚Π΅ΠΊΠΎΠ²Π΅Π½ Ρ€Π°Π·Π²ΠΎΡ˜ Π΅ ΠΈΠ·Π²Ρ€ΡˆΠ΅Π½ Π·Π° LLVM. Π—Π°Ρ‚ΠΎΠ°, ΠΏΡ€Π΅Π΄ сè, ќС ја ΠΈΠ·Π³Ρ€Π°Π΄ΠΈΠΌΠ΅ Ρ‚Π΅ΠΊΠΎΠ²Π½Π°Ρ‚Π° Π²Π΅Ρ€Π·ΠΈΡ˜Π° clang ΠΎΠ΄ git:

$ sudo apt install ninja-build
$ git clone --depth 1 https://github.com/llvm/llvm-project.git
$ mkdir -p llvm-project/llvm/build/install
$ cd llvm-project/llvm/build
$ cmake .. -G "Ninja" -DLLVM_TARGETS_TO_BUILD="BPF;X86" 
                      -DLLVM_ENABLE_PROJECTS="clang" 
                      -DBUILD_SHARED_LIBS=OFF 
                      -DCMAKE_BUILD_TYPE=Release 
                      -DLLVM_BUILD_RUNTIME=OFF
$ time ninja
... ΠΌΠ½ΠΎΠ³ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ спустя
$

Π‘Π΅Π³Π° ΠΌΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΠΌΠ΅ Π΄Π°Π»ΠΈ сè сС собрало ΠΏΡ€Π°Π²ΠΈΠ»Π½ΠΎ:

$ ./bin/llc --version
LLVM (http://llvm.org/):
  LLVM version 11.0.0git
  Optimized build.
  Default target: x86_64-unknown-linux-gnu
  Host CPU: znver1

  Registered Targets:
    bpf    - BPF (host endian)
    bpfeb  - BPF (big endian)
    bpfel  - BPF (little endian)
    x86    - 32-bit X86: Pentium-Pro and above
    x86-64 - 64-bit X86: EM64T and AMD64

(Упатство Π·Π° ΡΠΊΠ»ΠΎΠΏΡƒΠ²Π°ΡšΠ΅ clang ΠΏΡ€Π΅Π·Π΅ΠΌΠ΅Π½ΠΎ ΠΎΠ΄ ΠΌΠ΅Π½Π΅ ΠΎΠ΄ bpf_devel_QA.)

НСма Π΄Π° Π³ΠΈ инсталирамС ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ ΡˆΡ‚ΠΎ ΡˆΡ‚ΠΎΡ‚ΡƒΠΊΡƒ Π³ΠΈ ΠΈΠ·Π³Ρ€Π°Π΄ΠΈΠ²ΠΌΠ΅, Ρ‚ΡƒΠΊΡƒ само Π΄Π° Π³ΠΈ Π΄ΠΎΠ΄Π°Π΄Π΅ΠΌΠ΅ Π²ΠΎ Π½ΠΈΠ² PATH, Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€:

export PATH="`pwd`/bin:$PATH"

(Ова ΠΌΠΎΠΆΠ΅ Π΄Π° сС Π΄ΠΎΠ΄Π°Π΄Π΅ Π½Π° .bashrc ΠΈΠ»ΠΈ Π²ΠΎ посСбна Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ°. Π›ΠΈΡ‡Π½ΠΎ, Π΄ΠΎΠ΄Π°Π²Π°ΠΌ Π²Π°ΠΊΠ²ΠΈ Ρ€Π°Π±ΠΎΡ‚ΠΈ ~/bin/activate-llvm.sh ΠΈ ΠΊΠΎΠ³Π° Π΅ ΠΏΠΎΡ‚Ρ€Π΅Π±Π½ΠΎ Π³ΠΎ ΠΏΡ€Π°Π²Π°ΠΌ Ρ‚ΠΎΠ° . activate-llvm.sh.)

ΠŸΠ°Ρ…ΠΎΠ» ΠΈ Π‘Π’Π€

Алатка pahole сС користи ΠΏΡ€ΠΈ Π³Ρ€Π°Π΄Π΅ΡšΠ΅ Π½Π° ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚ Π·Π° ΠΊΡ€Π΅ΠΈΡ€Π°ΡšΠ΅ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ Π·Π° Π΄Π΅Π±Π°Π³ΠΈΡ€Π°ΡšΠ΅ Π²ΠΎ BTF Ρ„ΠΎΡ€ΠΌΠ°Ρ‚. Π’ΠΎ ΠΎΠ²Π°Π° ΡΡ‚Π°Ρ‚ΠΈΡ˜Π° Π½Π΅ΠΌΠ° Π΄Π° Π½Π°Π²Π»Π΅Π³ΡƒΠ²Π°ΠΌΠ΅ Π²ΠΎ Π΄Π΅Ρ‚Π°Π»ΠΈ Π·Π° Π΄Π΅Ρ‚Π°Π»ΠΈΡ‚Π΅ Π·Π° BTF Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΡ˜Π°Ρ‚Π°, освСн Ρ„Π°ΠΊΡ‚ΠΎΡ‚ Π΄Π΅ΠΊΠ° Π΅ ΠΏΠΎΠ³ΠΎΠ΄Π½Π° ΠΈ сакамС Π΄Π° ја користимС. Π—Π½Π°Ρ‡ΠΈ, Π°ΠΊΠΎ сакатС Π΄Π° Π³ΠΎ ΠΈΠ·Π³Ρ€Π°Π΄ΠΈΡ‚Π΅ Π²Π°ΡˆΠΈΠΎΡ‚ ΠΊΠ΅Ρ€Π½Π΅Π», ΠΏΡ€Π²ΠΎ ΠΈΠ·Π³Ρ€Π°Π΄ΠΈ pahole (Π±Π΅Π· pahole Π½Π΅ΠΌΠ° Π΄Π° ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Π³ΠΎ ΠΈΠ·Π³Ρ€Π°Π΄ΠΈΡ‚Π΅ ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚ со ΠΎΠΏΡ†ΠΈΡ˜Π°Ρ‚Π° CONFIG_DEBUG_INFO_BTF:

$ git clone https://git.kernel.org/pub/scm/devel/pahole/pahole.git
$ cd pahole/
$ sudo apt install cmake
$ mkdir build
$ cd build/
$ cmake -D__LIB=lib ..
$ make
$ sudo make install
$ which pahole
/usr/local/bin/pahole

ΠˆΠ°Π΄Ρ€Π° Π·Π° Π΅ΠΊΡΠΏΠ΅Ρ€ΠΈΠΌΠ΅Π½Ρ‚ΠΈΡ€Π°ΡšΠ΅ со BPF

Кога Π³ΠΈ истраТувам моТноститС Π½Π° BPF, сакам Π΄Π° Π³ΠΎ собСрам сопствСното Ρ˜Π°Π΄Ρ€ΠΎ. Ова, Π³Π΅Π½Π΅Ρ€Π°Π»Π½ΠΎ ΠΊΠ°ΠΆΠ°Π½ΠΎ, Π½Π΅ Π΅ Π½Π΅ΠΎΠΏΡ…ΠΎΠ΄Π½ΠΎ, бидСјќи ќС ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Π³ΠΈ ΠΊΠΎΠΌΠΏΠ°Ρ˜Π»ΠΈΡ€Π°Ρ‚Π΅ ΠΈ Π²Ρ‡ΠΈΡ‚Π°Ρ‚Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ BPF Π½Π° ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚ Π·Π° Π΄ΠΈΡΡ‚Ρ€ΠΈΠ±ΡƒΡ†ΠΈΡ˜Π°, Π½ΠΎ сСпак, ΠΏΠΎΡΠ΅Π΄ΡƒΠ²Π°ΡšΠ΅Ρ‚ΠΎ сопствСн ΠΊΠ΅Ρ€Π½Π΅Π» Π²ΠΈ ΠΎΠ²ΠΎΠ·ΠΌΠΎΠΆΡƒΠ²Π° Π΄Π° Π³ΠΈ користитС Π½Π°Ρ˜Π½ΠΎΠ²ΠΈΡ‚Π΅ карактСристики Π½Π° BPF, ΠΊΠΎΠΈ Π²ΠΎ Π½Π°Ρ˜Π΄ΠΎΠ±Π°Ρ€ ΡΠ»ΡƒΡ‡Π°Ρ˜ ќС сС ΠΏΠΎΡ˜Π°Π²Π°Ρ‚ Π²ΠΎ Π²Π°ΡˆΠ°Ρ‚Π° Π΄ΠΈΡΡ‚Ρ€ΠΈΠ±ΡƒΡ†ΠΈΡ˜Π° Π·Π° Π½Π΅ΠΊΠΎΠ»ΠΊΡƒ мСсСци. , ΠΈΠ»ΠΈ, ΠΊΠ°ΠΊΠΎ Π²ΠΎ ΡΠ»ΡƒΡ‡Π°Ρ˜ΠΎΡ‚ со Π½Π΅ΠΊΠΎΠΈ Π°Π»Π°Ρ‚ΠΊΠΈ Π·Π° Π΄Π΅Π±Π°Π³ΠΈΡ€Π°ΡšΠ΅, Π²ΠΎΠΎΠΏΡˆΡ‚ΠΎ Π½Π΅ΠΌΠ° Π΄Π° Π±ΠΈΠ΄Π°Ρ‚ спакувани Π²ΠΎ Π΄ΠΎΠ³Π»Π΅Π΄Π½Π° ΠΈΠ΄Π½ΠΈΠ½Π°. Π˜ΡΡ‚ΠΎ Ρ‚Π°ΠΊΠ°, Π½Π΅Π³ΠΎΠ²ΠΎΡ‚ΠΎ сопствСно Ρ˜Π°Π΄Ρ€ΠΎ ΠΏΡ€Π°Π²ΠΈ Π΄Π° сС чувствува Π²Π°ΠΆΠ½ΠΎ Π΄Π° сС СкспСримСнтира со ΠΊΠΎΠ΄ΠΎΡ‚.

Π—Π° Π΄Π° ΠΈΠ·Π³Ρ€Π°Π΄ΠΈΡ‚Π΅ ΠΊΠ΅Ρ€Π½Π΅Π», ΠΏΠΎΡ‚Ρ€Π΅Π±Π΅Π½ Π²ΠΈ Π΅, ΠΏΡ€Π²ΠΎ, самиот ΠΊΠ΅Ρ€Π½Π΅Π», ΠΈ Π²Ρ‚ΠΎΡ€ΠΎ, Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ° Π·Π° ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ˜Π° Π½Π° Ρ˜Π°Π΄Ρ€ΠΎΡ‚ΠΎ. Π—Π° Π΄Π° СкспСримСнтирамС со BPF ΠΌΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° Π³ΠΎ користимС Π²ΠΎΠΎΠ±ΠΈΡ‡Π°Π΅Π½ΠΎΡ‚ΠΎ Π²Π°Π½ΠΈΠ»Π° Ρ˜Π°Π΄Ρ€ΠΎ ΠΈΠ»ΠΈ Π΅Π΄Π½ΠΎ ΠΎΠ΄ Ρ€Π°Π·Π²ΠΎΡ˜Π½ΠΈΡ‚Π΅ ΠΊΠ΅Ρ€Π½Π΅Π»ΠΈ. Π˜ΡΡ‚ΠΎΡ€ΠΈΡΠΊΠΈ Π³Π»Π΅Π΄Π°Π½ΠΎ, Ρ€Π°Π·Π²ΠΎΡ˜ΠΎΡ‚ Π½Π° BPF сС ΠΎΠ΄Π²ΠΈΠ²Π° Π²ΠΎ Ρ€Π°ΠΌΠΊΠΈΡ‚Π΅ Π½Π° ΠΌΡ€Π΅ΠΆΠ½Π° Π·Π°Π΅Π΄Π½ΠΈΡ†Π° Π½Π° Линукс ΠΈ Π·Π°Ρ‚ΠΎΠ° ситС ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈ ΠΏΠΎΡ€Π°Π½ΠΎ ΠΈΠ»ΠΈ ΠΏΠΎΠ΄ΠΎΡ†Π½Π° ΠΎΠ΄Π°Ρ‚ ΠΏΡ€Π΅ΠΊΡƒ Π”Π΅Ρ˜Π²ΠΈΠ΄ ΠœΠΈΠ»Π΅Ρ€, ΠΎΠ΄Ρ€ΠΆΡƒΠ²Π°Ρ‡ΠΎΡ‚ Π½Π° ΠΌΡ€Π΅ΠΆΠΈ Π½Π° Линукс. Π’ΠΎ зависност ΠΎΠ΄ Π½ΠΈΠ²Π½Π°Ρ‚Π° ΠΏΡ€ΠΈΡ€ΠΎΠ΄Π° - ΡƒΡ€Π΅Π΄ΡƒΠ²Π°ΡšΠ° ΠΈΠ»ΠΈ Π½ΠΎΠ²ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ - ΠΌΡ€Π΅ΠΆΠ½ΠΈΡ‚Π΅ ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈ спаѓаат Π²ΠΎ Π΅Π΄Π½ΠΎ ΠΎΠ΄ Π΄Π²Π΅Ρ‚Π΅ Ρ˜Π°Π΄Ρ€Π° - net ΠΈΠ»ΠΈ net-next. ΠŸΡ€ΠΎΠΌΠ΅Π½ΠΈΡ‚Π΅ Π·Π° BPF сС распрСдСлуваат Π½Π° ист Π½Π°Ρ‡ΠΈΠ½ ΠΏΠΎΠΌΠ΅Ρ“Ρƒ bpf ΠΈ bpf-next, ΠΊΠΎΠΈ ΠΏΠΎΡ‚ΠΎΠ° сС Π·Π΄Ρ€ΡƒΠΆΡƒΠ²Π°Π°Ρ‚ Π²ΠΎ net ΠΈ net-next, соодвСтно. Π—Π° повСќС Π΄Π΅Ρ‚Π°Π»ΠΈ, Π²ΠΈΠ΄Π΅Ρ‚Π΅ bpf_devel_QA ΠΈ netdev-ЧПП. Π—Π°Ρ‚ΠΎΠ° ΠΈΠ·Π±Π΅Ρ€Π΅Ρ‚Π΅ Ρ˜Π°Π΄Ρ€ΠΎ Π²Ρ€Π· основа Π½Π° Π²Π°ΡˆΠΈΠΎΡ‚ вкус ΠΈ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅ Π·Π° стабилност Π½Π° систСмот Π½Π° ΠΊΠΎΡ˜ΡˆΡ‚ΠΎ Π³ΠΎ тСстиратС (*-next ΠΊΠ΅Ρ€Π½Π΅Π»ΠΈΡ‚Π΅ сС Π½Π°Ρ˜Π½Π΅ΡΡ‚Π°Π±ΠΈΠ»Π½ΠΈ ΠΎΠ΄ Π½Π°Π²Π΅Π΄Π΅Π½ΠΈΡ‚Π΅).

Надвор ΠΎΠ΄ опсСгот Π½Π° ΠΎΠ²Π°Π° ΡΡ‚Π°Ρ‚ΠΈΡ˜Π° Π΅ Π΄Π° сС Π·Π±ΠΎΡ€ΡƒΠ²Π° Π·Π° Ρ‚ΠΎΠ° ΠΊΠ°ΠΊΠΎ Π΄Π° ΡƒΠΏΡ€Π°Π²ΡƒΠ²Π°Ρ‚Π΅ со Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠΈΡ‚Π΅ Π·Π° ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ˜Π° Π½Π° ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚ - сС прСтпоставува Π΄Π΅ΠΊΠ° ΠΈΠ»ΠΈ вСќС Π·Π½Π°Π΅Ρ‚Π΅ ΠΊΠ°ΠΊΠΎ Π΄Π° Π³ΠΎ Π½Π°ΠΏΡ€Π°Π²ΠΈΡ‚Π΅ ΠΎΠ²Π°, ΠΈΠ»ΠΈ ΠΏΠΎΠ΄Π³ΠΎΡ‚Π²Π΅Π½ΠΈ Π·Π° ΡƒΡ‡Π΅ΡšΠ΅ сам ΠΏΠΎ сСбС. Π‘Π΅ΠΏΠ°ΠΊ, слСднитС инструкции Ρ‚Ρ€Π΅Π±Π° Π΄Π° Π±ΠΈΠ΄Π°Ρ‚ повСќС ΠΈΠ»ΠΈ ΠΏΠΎΠΌΠ°Π»ΠΊΡƒ Π΄ΠΎΠ²ΠΎΠ»Π½ΠΈ Π·Π° Π΄Π° Π²ΠΈ Π΄Π°Π΄Π°Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»Π΅Π½ систСм со ΠΎΠ²ΠΎΠ·ΠΌΠΎΠΆΠ΅Π½ BPF.

ΠŸΡ€Π΅Π·Π΅ΠΌΠ΅Ρ‚Π΅ Π΅Π΄Π½ΠΎ ΠΎΠ΄ Π³ΠΎΡ€Π΅Π½Π°Π²Π΅Π΄Π΅Π½ΠΈΡ‚Π΅ ΠΊΠ΅Ρ€Π½Π΅Π»ΠΈ:

$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git
$ cd bpf-next

Π˜Π·Π³Ρ€Π°Π΄Π΅Ρ‚Π΅ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»Π½Π° Ρ€Π°Π±ΠΎΡ‚Π½Π° ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ˜Π° Π½Π° ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚:

$ cp /boot/config-`uname -r` .config
$ make localmodconfig

ΠžΠ²ΠΎΠ·ΠΌΠΎΠΆΠ΅Ρ‚Π΅ BPF ΠΎΠΏΡ†ΠΈΠΈ Π²ΠΎ Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ°Ρ‚Π° .config ΠΏΠΎ ваш ΠΈΠ·Π±ΠΎΡ€ (Π½Π°Ρ˜Π²Π΅Ρ€ΠΎΡ˜Π°Ρ‚Π½ΠΎ CONFIG_BPF вСќС ќС Π±ΠΈΠ΄Π΅ ΠΎΠ²ΠΎΠ·ΠΌΠΎΠΆΠ΅Π½ΠΎ бидСјќи systemd Π³ΠΎ користи). Π•Π²Π΅ список Π½Π° ΠΎΠΏΡ†ΠΈΠΈ ΠΎΠ΄ ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚ ΡˆΡ‚ΠΎ сС користи Π·Π° ΠΎΠ²Π°Π° ΡΡ‚Π°Ρ‚ΠΈΡ˜Π°:

CONFIG_CGROUP_BPF=y
CONFIG_BPF=y
CONFIG_BPF_LSM=y
CONFIG_BPF_SYSCALL=y
CONFIG_ARCH_WANT_DEFAULT_BPF_JIT=y
CONFIG_BPF_JIT_ALWAYS_ON=y
CONFIG_BPF_JIT_DEFAULT_ON=y
CONFIG_IPV6_SEG6_BPF=y
# CONFIG_NETFILTER_XT_MATCH_BPF is not set
# CONFIG_BPFILTER is not set
CONFIG_NET_CLS_BPF=y
CONFIG_NET_ACT_BPF=y
CONFIG_BPF_JIT=y
CONFIG_BPF_STREAM_PARSER=y
CONFIG_LWTUNNEL_BPF=y
CONFIG_HAVE_EBPF_JIT=y
CONFIG_BPF_EVENTS=y
CONFIG_BPF_KPROBE_OVERRIDE=y
CONFIG_DEBUG_INFO_BTF=y

ΠŸΠΎΡ‚ΠΎΠ° ΠΌΠΎΠΆΠ΅ΠΌΠ΅ лСсно Π΄Π° Π³ΠΈ собСрСмС ΠΈ инсталирамС ΠΌΠΎΠ΄ΡƒΠ»ΠΈΡ‚Π΅ ΠΈ ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚ (ΠΏΠ°Ρ‚Π΅ΠΌ, ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Π³ΠΎ составитС ΠΊΠΎΡ€ΠΈΡΡ‚Π΅Ρ˜ΡœΠΈ Π³ΠΎ новособраниот clangсо додавањС CC=clang):

$ make -s -j $(getconf _NPROCESSORS_ONLN)
$ sudo make modules_install
$ sudo make install

ΠΈ сС рСстартира со Π½ΠΎΠ²ΠΎΡ‚ΠΎ Ρ˜Π°Π΄Ρ€ΠΎ (јас Π³ΠΎ користам Π·Π° ΠΎΠ²Π° kexec ΠΎΠ΄ ΠΏΠ°ΠΊΡƒΠ²Π°ΡšΠ΅Ρ‚ΠΎ kexec-tools):

v=5.8.0-rc6+ # Ссли Π²Ρ‹ пСрСсобираСтС Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π΅ ядро, Ρ‚ΠΎ ΠΌΠΎΠΆΠ½ΠΎ Π΄Π΅Π»Π°Ρ‚ΡŒ v=`uname -r`
sudo kexec -l -t bzImage /boot/vmlinuz-$v --initrd=/boot/initrd.img-$v --reuse-cmdline &&
sudo kexec -e

bpftool

ΠΠ°Ρ˜Ρ‡Π΅ΡΡ‚ΠΎ користСната Π°Π»Π°Ρ‚ΠΊΠ° Π²ΠΎ ΡΡ‚Π°Ρ‚ΠΈΡ˜Π°Ρ‚Π° ќС Π±ΠΈΠ΄Π΅ Π°Π»Π°Ρ‚ΠΊΠ°Ρ‚Π° bpftool, доставСн ΠΊΠ°ΠΊΠΎ Π΄Π΅Π» ΠΎΠ΄ ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚ Линукс. Напишан Π΅ ΠΈ ΠΎΠ΄Ρ€ΠΆΡƒΠ²Π°Π½ ΠΎΠ΄ BPF ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ΅Ρ€ΠΈ Π·Π° BPF ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ΅Ρ€ΠΈ ΠΈ ΠΌΠΎΠΆΠ΅ Π΄Π° сС користи Π·Π° ΡƒΠΏΡ€Π°Π²ΡƒΠ²Π°ΡšΠ΅ со ситС Π²ΠΈΠ΄ΠΎΠ²ΠΈ BPF ΠΎΠ±Ρ˜Π΅ΠΊΡ‚ΠΈ - Π²Ρ‡ΠΈΡ‚ΡƒΠ²Π°ΡšΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ, ΠΊΡ€Π΅ΠΈΡ€Π°ΡšΠ΅ ΠΈ ΡƒΡ€Π΅Π΄ΡƒΠ²Π°ΡšΠ΅ ΠΌΠ°ΠΏΠΈ, ΠΈΡΡ‚Ρ€Π°ΠΆΡƒΠ²Π°ΡšΠ΅ Π½Π° ΠΆΠΈΠ²ΠΎΡ‚ΠΎΡ‚ Π½Π° СкосистСмот BPF ΠΈΡ‚Π½. МоТС Π΄Π° сС најдС Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡ˜Π° Π²ΠΎ Ρ„ΠΎΡ€ΠΌΠ° Π½Π° ΠΈΠ·Π²ΠΎΡ€Π½ΠΈ ΠΊΠΎΠ΄ΠΎΠ²ΠΈ Π·Π° man-страници Π²ΠΎ Ρ˜Π°Π΄Ρ€ΠΎΡ‚ΠΎ ΠΈΠ»ΠΈ, вСќС составСно, Π½Π° ΠΌΡ€Π΅ΠΆΠ°Ρ‚Π°.

Π’ΠΎ Π²Ρ€Π΅ΠΌΠ΅Ρ‚ΠΎ Π½Π° ΠΎΠ²Π° ΠΏΠΈΡˆΡƒΠ²Π°ΡšΠ΅ bpftool Π΄ΠΎΠ°Ρ“Π° Π³ΠΎΡ‚ΠΎΠ² само Π·Π° RHEL, Fedora ΠΈ Ubuntu (Π²ΠΈΠ΄ΠΈ, Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΎΠ²Π°Π° нишка, кој ја раскаТува Π½Π΅Π΄ΠΎΠ²Ρ€ΡˆΠ΅Π½Π°Ρ‚Π° ΠΏΡ€ΠΈΠΊΠ°Π·Π½Π° Π·Π° ΠΏΠ°ΠΊΡƒΠ²Π°ΡšΠ΅Ρ‚ΠΎ bpftool Π²ΠΎ Π”Π΅Π±ΠΈΠ°Π½). Но, Π°ΠΊΠΎ вСќС стС Π³ΠΎ ΠΈΠ·Π³Ρ€Π°Π΄ΠΈΠ»Π΅ Π²Π°ΡˆΠΈΠΎΡ‚ ΠΊΠ΅Ρ€Π½Π΅Π», Ρ‚ΠΎΠ³Π°Ρˆ ΠΈΠ·Π³Ρ€Π°Π΄ΠΈ bpftool лСсно ΠΊΠ°ΠΊΠΎ ΠΏΠΈΡ‚Π°:

$ cd ${linux}/tools/bpf/bpftool
# ... ΠΏΡ€ΠΎΠΏΠΈΡˆΠΈΡ‚Π΅ ΠΏΡƒΡ‚ΠΈ ΠΊ послСднСму clang, ΠΊΠ°ΠΊ рассказано Π²Ρ‹ΡˆΠ΅
$ make -s

Auto-detecting system features:
...                        libbfd: [ on  ]
...        disassembler-four-args: [ on  ]
...                          zlib: [ on  ]
...                        libcap: [ on  ]
...               clang-bpf-co-re: [ on  ]

Auto-detecting system features:
...                        libelf: [ on  ]
...                          zlib: [ on  ]
...                           bpf: [ on  ]

$

(Ρ‚ΡƒΠΊΠ° ${linux} - ΠΎΠ²Π° Π΅ Π²Π°ΡˆΠΈΠΎΡ‚ Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΡƒΠΌ Π½Π° Ρ˜Π°Π΄Ρ€ΠΎΡ‚ΠΎ.) По ΠΈΠ·Π²Ρ€ΡˆΡƒΠ²Π°ΡšΠ΅Ρ‚ΠΎ Π½Π° ΠΎΠ²ΠΈΠ΅ ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ bpftool ќС Π±ΠΈΠ΄Π°Ρ‚ собрани Π²ΠΎ Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΡƒΠΌ ${linux}/tools/bpf/bpftool ΠΈ ΠΌΠΎΠΆΠ΅ Π΄Π° сС Π΄ΠΎΠ΄Π°Π΄Π΅ Π½Π° ΠΏΠ°Ρ‚Π΅ΠΊΠ°Ρ‚Π° (ΠΏΡ€Π΅Π΄ сС Π½Π° корисникот root) ΠΈΠ»ΠΈ само ΠΊΠΎΠΏΠΈΡ€Π°Ρ˜Ρ‚Π΅ Π²ΠΎ /usr/local/sbin.

Π‘ΠΎΠ±Π΅Ρ€ΠΈ bpftool Π½Π°Ρ˜Π΄ΠΎΠ±Ρ€ΠΎ Π΅ Π΄Π° сС користи Π²Ρ‚ΠΎΡ€ΠΎΡ‚ΠΎ clang, склопСн ΠΊΠ°ΠΊΠΎ ΡˆΡ‚ΠΎ Π΅ опишан ΠΏΠΎΠ³ΠΎΡ€Π΅ ΠΈ ΠΏΡ€ΠΎΠ²Π΅Ρ€Π΅Ρ‚Π΅ Π΄Π°Π»ΠΈ Π΅ ΠΏΡ€Π°Π²ΠΈΠ»Π½ΠΎ склопСн - ΠΊΠΎΡ€ΠΈΡΡ‚Π΅Ρ˜ΡœΠΈ, Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΊΠΎΠΌΠ°Π½Π΄Π°Ρ‚Π°

$ sudo bpftool feature probe kernel
Scanning system configuration...
bpf() syscall for unprivileged users is enabled
JIT compiler is enabled
JIT compiler hardening is disabled
JIT compiler kallsyms exports are enabled for root
...

ΡˆΡ‚ΠΎ ќС ΠΏΠΎΠΊΠ°ΠΆΠ΅ ΠΊΠΎΠΈ карактСристики Π½Π° BPF сС ΠΎΠ²ΠΎΠ·ΠΌΠΎΠΆΠ΅Π½ΠΈ Π²ΠΎ Π²Π°ΡˆΠΈΠΎΡ‚ ΠΊΠ΅Ρ€Π½Π΅Π».

ΠŸΠ°Ρ‚Π΅ΠΌ, ΠΏΡ€Π΅Ρ‚Ρ…ΠΎΠ΄Π½Π°Ρ‚Π° ΠΊΠΎΠΌΠ°Π½Π΄Π° ΠΌΠΎΠΆΠ΅ Π΄Π° сС ΠΈΠ·Π²Ρ€ΡˆΠΈ ΠΊΠ°ΠΊΠΎ

# bpftool f p k

Ова сС ΠΏΡ€Π°Π²ΠΈ ΠΏΠΎ аналогија со ΠΊΠΎΠΌΡƒΠ½Π°Π»Π½ΠΈΡ‚Π΅ услуги ΠΎΠ΄ ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΡ‚ iproute2, ΠΊΠ°Π΄Π΅ ΡˆΡ‚ΠΎ ΠΌΠΎΠΆΠ΅ΠΌΠ΅, Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π΄Π° ΠΊΠ°ΠΆΠ΅ΠΌΠ΅ ip a s eth0 намСсто ip addr show dev eth0.

Π—Π°ΠΊΠ»ΡƒΡ‡ΠΎΠΊ

BPF Π²ΠΈ ΠΎΠ²ΠΎΠ·ΠΌΠΎΠΆΡƒΠ²Π° Π΄Π° ΠΎΠ±Π»Π΅Ρ‡Π΅Ρ‚Π΅ Π±ΠΎΠ»Π²Π° Π·Π° Сфикасно ΠΌΠ΅Ρ€Π΅ΡšΠ΅ ΠΈ ΠΌΠ΅Π½ΡƒΠ²Π°ΡšΠ΅ Π½Π° функционалноста Π½Π° Ρ˜Π°Π΄Ρ€ΠΎΡ‚ΠΎ Π½Π° ΠΏΠ°Ρ‚. БистСмот сС ΠΏΠΎΠΊΠ°ΠΆΠ° ΠΊΠ°ΠΊΠΎ ΠΌΠ½ΠΎΠ³Ρƒ ΡƒΡΠΏΠ΅ΡˆΠ΅Π½, спорСд Π½Π°Ρ˜Π΄ΠΎΠ±Ρ€ΠΈΡ‚Π΅ Ρ‚Ρ€Π°Π΄ΠΈΡ†ΠΈΠΈ Π½Π° UNIX: СдноставСн ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·Π°ΠΌ кој Π²ΠΈ ΠΎΠ²ΠΎΠ·ΠΌΠΎΠΆΡƒΠ²Π° Π΄Π° Π³ΠΎ (Ρ€Π΅)ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ€Π°Ρ‚Π΅ ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚ ΠΎΠ²ΠΎΠ·ΠΌΠΎΠΆΠΈ ΠΎΠ³Ρ€ΠΎΠΌΠ΅Π½ Π±Ρ€ΠΎΡ˜ Π»ΡƒΡ“Π΅ ΠΈ ΠΎΡ€Π³Π°Π½ΠΈΠ·Π°Ρ†ΠΈΠΈ Π΄Π° СкспСримСнтираат. И, ΠΈΠ°ΠΊΠΎ СкспСримСнтитС, ΠΊΠ°ΠΊΠΎ ΠΈ Ρ€Π°Π·Π²ΠΎΡ˜ΠΎΡ‚ Π½Π° самата инфраструктура Π½Π° BPF, сС Π΄Π°Π»Π΅ΠΊΡƒ ΠΎΠ΄ Π·Π°Π²Ρ€ΡˆΠ΅Π½ΠΈ, систСмот вСќС ΠΈΠΌΠ° стабилСн ABI ΡˆΡ‚ΠΎ Π²ΠΈ ΠΎΠ²ΠΎΠ·ΠΌΠΎΠΆΡƒΠ²Π° Π΄Π° ΠΈΠ·Π³Ρ€Π°Π΄ΠΈΡ‚Π΅ сигурна, ΠΈ ΡˆΡ‚ΠΎ Π΅ најваТно, Π΅Ρ„Π΅ΠΊΡ‚ΠΈΠ²Π½Π° Π΄Π΅Π»ΠΎΠ²Π½Π° Π»ΠΎΠ³ΠΈΠΊΠ°.

Π‘ΠΈ сакал Π΄Π° Π·Π°Π±Π΅Π»Π΅ΠΆΠ°ΠΌ Π΄Π΅ΠΊΠ°, спорСд ΠΌΠΎΠ΅ мислСњС, Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΡ˜Π°Ρ‚Π° стана Ρ‚ΠΎΠ»ΠΊΡƒ ΠΏΠΎΠΏΡƒΠ»Π°Ρ€Π½Π° Π·Π°Ρ‚ΠΎΠ° ΡˆΡ‚ΠΎ, ΠΎΠ΄ Π΅Π΄Π½Π° страна, ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΈΠ³Ρ€Π° (Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°Ρ‚Π° Π½Π° ΠΌΠ°ΡˆΠΈΠ½Π°Ρ‚Π° ΠΌΠΎΠΆΠ΅ Π΄Π° сС Ρ€Π°Π·Π±Π΅Ρ€Π΅ повСќС ΠΈΠ»ΠΈ ΠΏΠΎΠΌΠ°Π»ΠΊΡƒ Π²ΠΎ Π΅Π΄Π½Π° Π²Π΅Ρ‡Π΅Ρ€), Π° ΠΎΠ΄ Π΄Ρ€ΡƒΠ³Π° страна Π΄Π° сС Ρ€Π΅ΡˆΠ°Π²Π°Π°Ρ‚ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΈ ΠΊΠΎΠΈ Π½Π΅ ΠΌΠΎΠΆΠ΅Π»Π΅ Π΄Π° сС Ρ€Π΅ΡˆΠ°Ρ‚ (прСкрасно) ΠΏΡ€Π΅Π΄ Π½Π΅Ρ˜Π·ΠΈΠ½ΠΎΡ‚ΠΎ ΠΏΠΎΡ˜Π°Π²ΡƒΠ²Π°ΡšΠ΅. ОвиС Π΄Π²Π΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΈ Π·Π°Π΅Π΄Π½ΠΎ Π³ΠΈ ΠΏΡ€ΠΈΠ½ΡƒΠ΄ΡƒΠ²Π°Π°Ρ‚ Π»ΡƒΡ“Π΅Ρ‚ΠΎ Π΄Π° СкспСримСнтираат ΠΈ Π΄Π° сонуваат, ΡˆΡ‚ΠΎ Π΄ΠΎΠ²Π΅Π΄ΡƒΠ²Π° Π΄ΠΎ појава Π½Π° сС повСќС ΠΈ повСќС ΠΈΠ½ΠΎΠ²Π°Ρ‚ΠΈΠ²Π½ΠΈ Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ˜Π°.

Оваа ΡΡ‚Π°Ρ‚ΠΈΡ˜Π°, ΠΈΠ°ΠΊΠΎ Π½Π΅ Π΅ особСно ΠΊΡ€Π°Ρ‚ΠΊΠ°, Π΅ само Π²ΠΎΠ²Π΅Π΄ Π²ΠΎ свСтот Π½Π° BPF ΠΈ Π½Π΅ ΠΎΠΏΠΈΡˆΡƒΠ²Π° β€žΠ½Π°ΠΏΡ€Π΅Π΄Π½ΠΈβ€œ карактСристики ΠΈ Π²Π°ΠΆΠ½ΠΈ Π΄Π΅Π»ΠΎΠ²ΠΈ ΠΎΠ΄ Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°Ρ‚Π°. ΠŸΠ»Π°Π½ΠΎΡ‚ Π·Π° ΠΏΠΎΠ½Π°Ρ‚Π°ΠΌΡƒ Π΅ ΠΎΡ‚ΠΏΡ€ΠΈΠ»ΠΈΠΊΠ° Π²Π°ΠΊΠ°: слСдната ΡΡ‚Π°Ρ‚ΠΈΡ˜Π° ќС Π±ΠΈΠ΄Π΅ ΠΏΡ€Π΅Π³Π»Π΅Π΄ Π½Π° Ρ‚ΠΈΠΏΠΎΠ²ΠΈΡ‚Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ Π½Π° BPF (ΠΏΠΎΡΡ‚ΠΎΡ˜Π°Ρ‚ 5.8 Ρ‚ΠΈΠΏΠΎΠ²ΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ ΠΏΠΎΠ΄Π΄Ρ€ΠΆΠ°Π½ΠΈ Π²ΠΎ ΠΊΠ΅Ρ€Π½Π΅Π»ΠΎΡ‚ 30), ΠΏΠΎΡ‚ΠΎΠ° ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎ ќС ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ ΠΊΠ°ΠΊΠΎ Π΄Π° Π½Π°ΠΏΠΈΡˆΠ΅Ρ‚Π΅ вистински BPF Π°ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΊΠΎΡ€ΠΈΡΡ‚Π΅Ρ˜ΡœΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ Π·Π° слСдСњС Π½Π° Ρ˜Π°Π΄Ρ€ΠΎΡ‚ΠΎ ΠΊΠ°ΠΊΠΎ ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Ρ‚ΠΎΠ³Π°Ρˆ Π΅ Π²Ρ€Π΅ΠΌΠ΅ Π·Π° ΠΏΠΎΠ΄Π»Π°Π±ΠΎΠΊ курс Π·Π° Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°Ρ‚Π° BPF, прослСдСн со ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΈ Π½Π° BPF Π²ΠΌΡ€Π΅ΠΆΡƒΠ²Π°ΡšΠ΅ ΠΈ бСзбСдносни Π°ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΠΈ.

ΠŸΡ€Π΅Ρ‚Ρ…ΠΎΠ΄Π½ΠΈ написи ΠΎΠ΄ ΠΎΠ²Π°Π° ΡΠ΅Ρ€ΠΈΡ˜Π°

  1. BPF Π·Π° Π½Π°Ρ˜ΠΌΠ°Π»ΠΈΡ‚Π΅, Π΄Π΅Π» Π½ΡƒΠ»Π°: класичСн BPF

Врски

  1. Π Π΅Ρ„Π΅Ρ€Π΅Π½Ρ‚Π΅Π½ Π²ΠΎΠ΄ΠΈΡ‡ Π·Π° BPF ΠΈ XDP β€” Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡ˜Π° Π·Π° BPF ΠΎΠ΄ Ρ†ΠΈΠ»ΠΈΡƒΠΌ, ΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎ ΠΎΠ΄ Π”Π°Π½ΠΈΠ΅Π» Π‘ΠΎΡ€ΠΊΠΌΠ°Π½, Π΅Π΄Π΅Π½ ΠΎΠ΄ ΠΊΡ€Π΅Π°Ρ‚ΠΎΡ€ΠΈΡ‚Π΅ ΠΈ ΠΎΠ΄Ρ€ΠΆΡƒΠ²Π°Ρ‡ΠΈΡ‚Π΅ Π½Π° BPF. Ова Π΅ Π΅Π΄Π΅Π½ ΠΎΠ΄ ΠΏΡ€Π²ΠΈΡ‚Π΅ сСриозни описи, кој сС Ρ€Π°Π·Π»ΠΈΠΊΡƒΠ²Π° ΠΎΠ΄ Π΄Ρ€ΡƒΠ³ΠΈΡ‚Π΅ ΠΏΠΎ Ρ‚ΠΎΠ° ΡˆΡ‚ΠΎ Π”Π°Π½ΠΈΠ΅Π» Ρ‚ΠΎΡ‡Π½ΠΎ Π·Π½Π°Π΅ Π·Π° ΡˆΡ‚ΠΎ ΠΏΠΈΡˆΡƒΠ²Π° ΠΈ Ρ‚Π°ΠΌΡƒ Π½Π΅ΠΌΠ° Π½ΠΈΠΊΠ°ΠΊΠ²ΠΈ Π³Ρ€Π΅ΡˆΠΊΠΈ. ΠšΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎ, овој Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ ΠΎΠΏΠΈΡˆΡƒΠ²Π° ΠΊΠ°ΠΊΠΎ Π΄Π° сС Ρ€Π°Π±ΠΎΡ‚ΠΈ со ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ BPF ΠΎΠ΄ Ρ‚ΠΈΠΏΠΎΠ²ΠΈΡ‚Π΅ XDP ΠΈ TC ΠΊΠΎΡ€ΠΈΡΡ‚Π΅Ρ˜ΡœΠΈ ја Π΄ΠΎΠ±Ρ€ΠΎ ΠΏΠΎΠ·Π½Π°Ρ‚Π°Ρ‚Π° Π°Π»Π°Ρ‚ΠΊΠ° ip ΠΎΠ΄ ΠΏΠ°ΠΊΡƒΠ²Π°ΡšΠ΅Ρ‚ΠΎ iproute2.

  2. Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡ˜Π°/Π²ΠΌΡ€Π΅ΠΆΡƒΠ²Π°ΡšΠ΅/Ρ„ΠΈΠ»Ρ‚Π΅Ρ€.txt β€” ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»Π½Π° Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ° со Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡ˜Π° Π·Π° класичСн, Π° ΠΏΠΎΡ‚ΠΎΠ° ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ΅Π½ BPF. Π”ΠΎΠ±Ρ€ΠΎ Ρ‡ΠΈΡ‚Π°ΡšΠ΅ Π°ΠΊΠΎ сакатС Π΄Π° истраТуватС Π²ΠΎ асСмблСрскиот јазик ΠΈ Ρ‚Π΅Ρ…Π½ΠΈΡ‡ΠΊΠΈΡ‚Π΅ архитСктонски Π΄Π΅Ρ‚Π°Π»ΠΈ.

  3. Π‘Π»ΠΎΠ³ Π·Π° BPF ΠΎΠ΄ Π€Π΅Ρ˜ΡΠ±ΡƒΠΊ. Π‘Π΅ Π°ΠΆΡƒΡ€ΠΈΡ€Π° Ρ€Π΅Ρ‚ΠΊΠΎ, Π½ΠΎ соодвСтно, ΠΊΠ°ΠΊΠΎ ΡˆΡ‚ΠΎ ΠΏΠΈΡˆΡƒΠ²Π°Π°Ρ‚ Ρ‚Π°ΠΌΡƒ АлСксСј Π‘Ρ‚Π°Ρ€ΠΎΠ²ΠΎΠΈΡ‚ΠΎΠ² (Π°Π²Ρ‚ΠΎΡ€ Π½Π° eBPF) ΠΈ ΠΠ½Π΄Ρ€ΠΈΡ˜ Накриико - (ΠΎΠ΄Ρ€ΠΆΡƒΠ²Π°Ρ‡). libbpf).

  4. Π’Π°Ρ˜Π½ΠΈΡ‚Π΅ Π½Π° bpftool. Π—Π°Π±Π°Π²Π½Π° нишка Π½Π° Π’Π²ΠΈΡ‚Π΅Ρ€ ΠΎΠ΄ ΠšΠ²Π΅Π½Ρ‚ΠΈΠ½ МонС со ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΈ ΠΈ Ρ‚Π°Ρ˜Π½ΠΈ Π·Π° ΠΊΠΎΡ€ΠΈΡΡ‚Π΅ΡšΠ΅ bpftool.

  5. НурнСтС Π²ΠΎ BPF: список Π½Π° ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΡ˜Π°Π» Π·Π° Ρ‡ΠΈΡ‚Π°ΡšΠ΅. ΠžΠ³Ρ€ΠΎΠΌΠ½Π° (ΠΈ сè ΡƒΡˆΡ‚Π΅ ΠΎΠ΄Ρ€ΠΆΡƒΠ²Π°Π½Π°) листа Π½Π° Π»ΠΈΠ½ΠΊΠΎΠ²ΠΈ Π΄ΠΎ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡ˜Π°Ρ‚Π° Π½Π° BPF ΠΎΠ΄ ΠšΠ²Π΅Π½Ρ‚ΠΈΠ½ МонС.

Π˜Π·Π²ΠΎΡ€: www.habr.com

Π”ΠΎΠ΄Π°Π΄Π΅Ρ‚Π΅ ΠΊΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€