BPF ya ana aang'ono, gawo limodzi: BPF yowonjezera

Pachiyambi panali teknoloji ndipo inkatchedwa BPF. Tinayang'ana pa iye m'mbuyomu, Nkhani ya Chipangano Chakale ya mpambo uno. Mu 2013, chifukwa cha zoyesayesa za Alexei Starovoitov ndi Daniel Borkman, mtundu wake wowongoka, wokometsedwa pamakina amakono a 64-bit, adapangidwa ndikuphatikizidwa mu kernel ya Linux. Tekinoloje yatsopanoyi idatchedwa mwachidule BPF Yamkati, kenako idasinthidwanso BPF Yowonjezera, ndipo tsopano, patatha zaka zingapo, aliyense amangoyitcha BPF.

Mwachidule, BPF imakulolani kuti mugwiritse ntchito kachidindo kamene kamaperekedwa ndi ogwiritsa ntchito mosasamala mu Linux kernel space, ndipo zomangamanga zatsopano zinakhala zopambana kotero kuti tidzafunika zolemba khumi ndi ziwiri kuti tifotokoze ntchito zake zonse. (Chinthu chokha chomwe opanga sanachite bwino, monga mukuwonera m'chithunzichi pansipa, chinali kupanga logo yabwino.)

Nkhaniyi ikufotokoza kapangidwe ka makina a BPF pafupifupi, mawonekedwe a kernel ogwirira ntchito ndi BPF, zida zachitukuko, komanso mwachidule, mwachidule za kuthekera komwe kulipo, i.e. chilichonse chomwe tingafunike mtsogolomo kuti tiphunzire mozama momwe BPF imathandizira.
BPF ya ana aang'ono, gawo limodzi: BPF yowonjezera

Chidule cha nkhaniyi

Chiyambi cha zomangamanga za BPF. Choyamba, tiwona momwe mbalame zimakhalira ndi zomangamanga za BPF ndikufotokozera zigawo zikuluzikulu.

Registry ndi command system ya BPF virtual machine. Pokhala ndi lingaliro lazomangamanga zonse, tifotokoza kapangidwe ka makina a BPF.

Kuzungulira kwa moyo wa BPF zinthu, bpffs file system. M'chigawo chino, tiwona mozama za moyo wa zinthu za BPF - mapulogalamu ndi mamapu.

Kuwongolera zinthu pogwiritsa ntchito foni ya bpf system. Ndi kumvetsetsa pang'ono kwa dongosololi lomwe lilipo kale, tiwona momwe tingapangire ndikusintha zinthu kuchokera pamalo ogwiritsa ntchito pogwiritsa ntchito foni yapadera - bpf(2).

ПишСм ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ BPF с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ libbpf. Inde, mukhoza kulemba mapulogalamu pogwiritsa ntchito foni yamakono. Koma ndizovuta. Kuti zinthu zitheke, opanga mapulogalamu a zida za nyukiliya anapanga laibulale libbpf. Tipanga mafupa oyambira a BPF omwe tidzagwiritsa ntchito m'zitsanzo zotsatila.

Othandizira Kernel. Apa tiphunzira momwe mapulogalamu a BPF angapezere ntchito zothandizira kernel - chida chomwe, pamodzi ndi mamapu, chimakulitsa luso la BPF yatsopano poyerekeza ndi yachikale.

Kupeza mamapu kuchokera kumapulogalamu a BPF. Pofika pano, tidzadziwa mokwanira kuti timvetsetse momwe tingapangire mapulogalamu omwe amagwiritsa ntchito mamapu. Ndipo tiyeni tiyang'ane mwachangu mu chitsimikizo chachikulu komanso champhamvu.

Zida zachitukuko. Gawo lothandizira la momwe mungasonkhanitsire zofunikira ndi kernel pazoyeserera.

Mapeto. Kumapeto kwa nkhaniyo, amene akuΕ΅erenga mpaka pano adzapeza mawu olimbikitsa ndi malongosoledwe achidule a zimene zidzachitike m’nkhani zotsatirazi. Tidzalembanso maulalo angapo odziwerengera okha omwe alibe chikhumbo kapena kuthekera kodikirira kupitiriza.

Chiyambi cha BPF Architecture

Tisanayambe kulingalira za zomangamanga za BPF, tidzatchula nthawi yomaliza (o) ku BPF yapamwamba, yomwe idapangidwa ngati yankho pakubwera kwa makina a RISC ndikuthetsa vuto la kusefa kwapaketi koyenera. Zomangamangazo zidakhala zopambana kotero kuti, atabadwa m'zaka za makumi asanu ndi anayi ku Berkeley UNIX, adawonetsedwa ku machitidwe ambiri omwe analipo kale, adapulumuka mpaka zaka makumi awiri ndipo akupezabe ntchito zatsopano.

BPF yatsopano idapangidwa kuti iyankhe pakufalikira kwa makina a 64-bit, ntchito zamtambo komanso kufunikira kowonjezereka kwa zida zopangira SDN (Szambiri-defined nntchito). Wopangidwa ndi mainjiniya a kernel network monga choloweza m'malo mwa BPF yachikale, BPF yatsopanoyo patapita miyezi isanu ndi umodzi idapeza ntchito muntchito yovuta kutsatira machitidwe a Linux, ndipo tsopano, patatha zaka zisanu ndi chimodzi ikuwonekera, tidzafunika nkhani yotsatira kuti tchulani mitundu yosiyanasiyana ya mapulogalamu.

Zithunzi zoseketsa

Pachimake, BPF ndi makina a sandbox omwe amakulolani kuti mugwiritse ntchito code "mopanda pake" mu kernel space popanda kusokoneza chitetezo. Mapulogalamu a BPF amapangidwa m'malo ogwiritsira ntchito, amalowetsedwa mu kernel, ndikulumikizidwa ndi zochitika zina. Chochitika chikhoza kukhala, mwachitsanzo, kubweretsa paketi kumalo ochezera a pa Intaneti, kukhazikitsidwa kwa ntchito ina ya kernel, ndi zina zotero. Pankhani ya phukusi, pulogalamu ya BPF idzakhala ndi mwayi wopeza deta ndi metadata ya phukusi (powerenga komanso, mwinamwake, kulemba, kutengera mtundu wa pulogalamu); pakuchita ntchito ya kernel, mikangano ya ntchito, kuphatikiza zolozera ku kernel memory, etc.

Tiyeni tione mwatsatanetsatane ndondomekoyi. Poyamba, tiyeni tikambirane kusiyana koyamba kwa tingachipeze powerenga BPF, mapulogalamu amene analembedwa assembler. M'mawonekedwe atsopano, zomangamanga zinakulitsidwa kotero kuti mapulogalamu akhoza kulembedwa m'zinenero zapamwamba, makamaka, ndithudi, mu C. Pachifukwa ichi, kumbuyo kwa llvm kunapangidwa, zomwe zimakulolani kupanga bytecode kwa zomangamanga za BPF.

BPF ya ana aang'ono, gawo limodzi: BPF yowonjezera

Zomangamanga za BPF zidapangidwa, mwa zina, kuti ziziyenda bwino pamakina amakono. Kuti izi zitheke, BPF bytecode, ikangoyikidwa mu kernel, imamasuliridwa m'mawu achikhalidwe pogwiritsa ntchito chigawo chotchedwa JIT compiler (Ju In Tine). Chotsatira, ngati mukukumbukira, mu BPF yachikale pulogalamuyo idakwezedwa mu kernel ndikumangidwira ku gwero la chochitikacho atomiki - potengera kuyimba kamodzi. Muzomangamanga zatsopano, izi zimachitika mu magawo awiri - choyamba, code imayikidwa mu kernel pogwiritsa ntchito foni yamakono. bpf(2)ndiyeno, pambuyo pake, kudzera munjira zina zomwe zimasiyana malinga ndi mtundu wa pulogalamuyo, pulogalamuyo imamangiriza ku gwero la zochitika.

Apa wowerenga akhoza kukhala ndi funso: zidatheka? Kodi chitetezo chotsatira malamulo otere chimatsimikiziridwa bwanji? Chitetezo chakupha chimatsimikiziridwa kwa ife potsegula mapulogalamu a BPF otchedwa verifier (mu Chingerezi siteji iyi imatchedwa verifier ndipo ndipitiriza kugwiritsa ntchito liwu lachingerezi):

BPF ya ana aang'ono, gawo limodzi: BPF yowonjezera

Verifier ndi static analyzer yomwe imawonetsetsa kuti pulogalamu sisokoneza magwiridwe antchito a kernel. Izi, mwa njira, sizikutanthauza kuti pulogalamuyo silingasokoneze kayendetsedwe kake - mapulogalamu a BPF, malingana ndi mtundu wake, amatha kuwerenga ndikulembanso zigawo za kernel memory, kubwereranso kwa ntchito, kuchepetsa, kuwonjezera, kulembanso. komanso ngakhale mapaketi a netiweki. Wotsimikizira amatsimikizira kuti kuyendetsa pulogalamu ya BPF sikungawononge kernel komanso kuti pulogalamu yomwe, malinga ndi malamulo, ili ndi mwayi wolembera, mwachitsanzo, deta ya paketi yotuluka, sichitha kulembera kernel kukumbukira kunja kwa paketi. Tidzayang'ana verifier mwatsatanetsatane mu gawo lolingana, titadziwana ndi zigawo zina zonse za BPF.

Ndiye taphunzira chiyani mpaka pano? Wogwiritsa ntchito amalemba pulogalamu mu C, ndikuyiyika mu kernel pogwiritsa ntchito foni bpf(2), pomwe imawunikiridwa ndi wotsimikizira ndikumasuliridwa ku bytecode. Kenako wogwiritsa ntchito yemweyo kapena wina amalumikiza pulogalamuyo kugwero la zochitikazo ndipo imayamba kuchita. Kulekanitsa jombo ndi kulumikizana ndikofunikira pazifukwa zingapo. Choyamba, kuyendetsa verifier ndikokwera mtengo ndipo potsitsa pulogalamu yomweyi kangapo timawononga nthawi ya kompyuta. Kachiwiri, ndendende momwe pulogalamu imagwirizanirana zimatengera mtundu wake, ndipo mawonekedwe "apadziko lonse" omwe adapangidwa chaka chapitacho sangakhale oyenera pamitundu yatsopano yamapulogalamu. (Ngakhale tsopano kuti zomangamanga zikukula kwambiri, pali lingaliro logwirizanitsa mawonekedwewa pamlingo libbpf.)

Wowerenga mwachidwi angazindikire kuti sitinathebe ndi zithunzizo. Zowonadi, zonse zomwe tafotokozazi sizikufotokoza chifukwa chake BPF imasintha chithunzicho poyerekeza ndi BPF yapamwamba. Zatsopano ziwiri zomwe zimakulitsa kwambiri kuchuluka kwa kugwiritsidwa ntchito ndikutha kugwiritsa ntchito kukumbukira komwe kugawana ndi ntchito zothandizira kernel. Mu BPF, kukumbukira kogawana kumayendetsedwa pogwiritsa ntchito zomwe zimatchedwa mamapu - zida zogawana zomwe zili ndi API inayake. Mwinamwake ali ndi dzinali chifukwa mtundu woyamba wa mapu kuwonekera unali tebulo la hashi. Kenako zidawonekera, matebulo am'deralo (per-CPU) ndi magulu am'deralo, mitengo yosaka, mamapu okhala ndi zolozera ku mapulogalamu a BPF ndi zina zambiri. Chosangalatsa kwa ife tsopano ndikuti mapulogalamu a BPF tsopano ali ndi kuthekera kolimbikira pakati pa mafoni ndikugawana ndi mapulogalamu ena komanso malo ogwiritsa ntchito.

Mapu amafikiridwa kuchokera kumayendedwe a ogwiritsa ntchito pogwiritsa ntchito kuyimba foni bpf(2), ndi kuchokera ku mapulogalamu a BPF omwe akuyenda mu kernel pogwiritsa ntchito ntchito zothandizira. Kuphatikiza apo, othandizira alipo osati kuti azigwira ntchito ndi mamapu, komanso kuti athe kupeza maluso ena a kernel. Mwachitsanzo, mapulogalamu a BPF angagwiritse ntchito ntchito zothandizira kuti atumize mapaketi kumalo ena, kupanga zochitika za perf, kupeza mapangidwe a kernel, ndi zina zotero.

BPF ya ana aang'ono, gawo limodzi: BPF yowonjezera

Mwachidule, BPF imapereka kuthekera kokweza mosasamala, mwachitsanzo, kuyesedwa kotsimikizika, kachidindo wa ogwiritsa ntchito mu kernel space. Khodi iyi ikhoza kupulumutsa dziko pakati pa mafoni ndi kusinthanitsa deta ndi malo ogwiritsira ntchito, komanso amatha kupeza ma subsystems a kernel omwe amaloledwa ndi pulogalamu yamtunduwu.

Izi zikufanana kale ndi mphamvu zomwe zimaperekedwa ndi ma module a kernel, poyerekeza ndi zomwe BPF ili ndi ubwino wina (zowona, mungathe kufananitsa ntchito zofanana, mwachitsanzo, kufufuza dongosolo - simungathe kulemba dalaivala wosasamala ndi BPF). Mutha kuzindikira malo otsika olowera (zinthu zina zomwe zimagwiritsa ntchito BPF sizifuna kuti wogwiritsa ntchitoyo akhale ndi luso la pulogalamu ya kernel, kapena luso la pulogalamu yonse), chitetezo chanthawi yothamanga (kwezerani dzanja lanu mu ndemanga kwa omwe sanaswe dongosolo polemba. kapena kuyesa ma modules), atomiki - pali nthawi yochepetsera pamene mukutsegulanso ma modules, ndipo gawo laling'ono la BPF limatsimikizira kuti palibe zochitika zomwe zaphonya (kukhala chilungamo, izi sizowona kwa mitundu yonse ya mapulogalamu a BPF).

Kukhalapo kwa kuthekera kotereku kumapangitsa BPF kukhala chida chapadziko lonse lapansi chokulitsa kernel, chomwe chimatsimikiziridwa muzochita: mitundu yatsopano yowonjezereka ya mapulogalamu ikuwonjezeredwa ku BPF, makampani ochulukirachulukira amagwiritsa ntchito BPF pamaseva olimbana 24 Γ— 7, mochulukirachulukira. oyambitsa amapanga bizinesi yawo pamayankho ozikidwa pa BPF. BPF imagwiritsidwa ntchito paliponse: poteteza motsutsana ndi DDoS, kupanga SDN (mwachitsanzo, kukhazikitsa maukonde a kubernetes), monga chida chachikulu chotsata ndi kusonkhanitsa ziwerengero, pamakina ozindikira zolowera ndi makina a sandbox, ndi zina zambiri.

Tiyeni titsirize mwachidule gawo la nkhaniyi ndikuwona makina enieni komanso chilengedwe cha BPF mwatsatanetsatane.

Kupatuka: zothandiza

Kuti mutha kuyendetsa zitsanzo m'magawo otsatirawa, mungafunike zingapo zothandizira, osachepera llvm/clang ndi chithandizo cha bpf ndi bpftool. Mu gawo Zida Zachitukuko Mutha kuwerenga malangizo osonkhanitsira zofunikira, komanso kernel yanu. Gawoli laikidwa pansipa kuti lisasokoneze kugwirizana kwa ulaliki wathu.

BPF Virtual Machine Registers and Instruction System

Zomangamanga ndi malamulo a BPF zidapangidwa poganizira kuti mapulogalamu adzalembedwa m'chilankhulo cha C ndipo, atatsitsa mu kernel, amamasuliridwa m'makhodi achilengedwe. Choncho, chiwerengero cha zolembera ndi ndondomeko ya malamulo anasankhidwa ndi diso ku mphambano, m'lingaliro la masamu, luso la makina amakono. Kuphatikiza apo, zoletsa zosiyanasiyana zidayikidwa pamapulogalamu, mwachitsanzo, mpaka posachedwapa sikunali kotheka kulemba malupu ndi ma subroutines, ndipo malangizowo anali ochepa mpaka 4096 (tsopano mapulogalamu mwayi amatha kutsitsa mpaka malangizo miliyoni).

BPF ili ndi zolembera khumi ndi chimodzi zopezeka ndi 64-bit r0-r10 ndi kauntala pulogalamu. Register r10 ili ndi cholozera chimango ndipo imawerengedwa kokha. Mapulogalamu ali ndi mwayi wopeza ma 512-byte stack panthawi yothamanga komanso kukumbukira kosawerengeka komwe kumagawana munjira yamapu.

Mapulogalamu a BPF amaloledwa kuyendetsa gulu linalake la othandizira kernel ndipo, posachedwa, ntchito zokhazikika. Ntchito iliyonse yomwe imatchedwa imatha kutenga mfundo zisanu, zoperekedwa m'kaundula r1-r5, ndipo mtengo wobwezera umaperekedwa r0. Zimatsimikiziridwa kuti mutabwerera kuchokera kuntchito, zomwe zili m'mabuku r6-r9 Sizisintha.

Kuti mumasulire pulogalamu yabwino, regista r0-r11 Zomangamanga zonse zothandizidwa zimajambulidwa mwapadera ku zolembera zenizeni, poganizira za ABI zamamangidwe apano. Mwachitsanzo, kwa x86_64 olembetsa r1-r5, zomwe zimagwiritsidwa ntchito podutsa magawo a ntchito, zimawonetsedwa rdi, rsi, rdx, rcx, r8, zomwe zimagwiritsidwa ntchito popereka magawo kuti azigwira ntchito x86_64. Mwachitsanzo, code yomwe ili kumanzere imamasulira kumanja kumanja motere:

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

Register r0 amagwiritsidwanso ntchito kubweza zotsatira za kukhazikitsidwa kwa pulogalamu, komanso mu kaundula r1 pulogalamuyo imaperekedwa cholozera ku nkhani - kutengera mtundu wa pulogalamu, izi zitha kukhala, mwachitsanzo, kapangidwe struct xdp_md (ya XDP) kapena kapangidwe struct __sk_buff (kwa mapulogalamu osiyanasiyana a netiweki) kapena kapangidwe struct pt_regs (zamitundu yosiyanasiyana yamapulogalamu otsatirira), etc.

Chifukwa chake, tinali ndi zolembera, othandizira kernel, stack, pointer pointer ndikugawana kukumbukira monga mamapu. Osati kuti zonsezi ndizofunikira paulendo, koma ...

Tiyeni tipitilize kufotokoza ndikulankhula za dongosolo lamalamulo logwirira ntchito ndi zinthu izi. Zonse (Pafupifupi onse) Malangizo a BPF ali ndi kukula kwa 64-bit. Mukayang'ana malangizo amodzi pamakina a 64-bit Big Endian mudzawona

BPF ya ana aang'ono, gawo limodzi: BPF yowonjezera

ndi Code - uku ndiko kusindikiza kwa malangizo, Dst/Src ndi ma encoding a wolandila ndi gwero, motsatana, Off - 16-bit osaina indentation, ndi Imm ndi nambala yosainidwa ya 32-bit yomwe imagwiritsidwa ntchito m'malangizo ena (ofanana ndi cBPF yokhazikika K). Encoding Code ili ndi imodzi mwa mitundu iwiri:

BPF ya ana aang'ono, gawo limodzi: BPF yowonjezera

Makalasi ophunzitsira 0, 1, 2, 3 amatanthauzira malamulo ogwirira ntchito ndi kukumbukira. Iwo Amayitanidwa, BPF_LD, BPF_LDX, BPF_ST, BPF_STX, motero. Maphunziro 4, 7BPF_ALU, BPF_ALU64) amapanga malangizo a ALU. Magulu 5, 6 (BPF_JMP, BPF_JMP32) ali ndi malangizo a kudumpha.

Ndondomeko yowonjezera yophunzirira dongosolo la malangizo a BPF ili motere: m'malo molemba mosamala malangizo onse ndi magawo awo, tiwona zitsanzo zingapo m'gawoli ndipo kuchokera kwa iwo zidzamveka bwino momwe malangizowo amagwirira ntchito komanso momwe angachitire. phatikizani pamanja fayilo iliyonse ya binary ya BPF. Kuti tiphatikize zomwe zili pambuyo pake m'nkhaniyi, tidzakumananso ndi malangizo pawokha m'magawo onena za Verifier, JIT compiler, kumasulira kwa BPF yapamwamba, komanso powerenga mamapu, kuyimbira foni, ndi zina zambiri.

Tikamalankhula za malangizo aumwini, tidzatchula mafayilo apakati bpf.h ΠΈ bpf_common.h, zomwe zimatanthauzira manambala a malangizo a BPF. Mukamawerenga zomanga nokha komanso/kapena pogawa ma binariji, mutha kupeza semantics m'magawo otsatirawa, osankhidwa motengera zovuta: Zosavomerezeka za eBPF, BPF ndi XDP Reference Guide, Instruction Set, Documentation/networking/filter.txt ndipo, ndithudi, mu Linux source code - verifier, JIT, BPF womasulira.

Chitsanzo: Kuthyola BPF m’mutu

Tiyeni tiwone chitsanzo chomwe timapanga pulogalamu readelf-example.c ndipo yang'anani zotsatira za binary. Tiwulula zomwe zili zoyambira readelf-example.c pansipa, titabwezeretsa malingaliro ake kuchokera ku ma code binary:

$ 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 ................

Gawo loyamba pazotulutsa readelf ndi indentation ndipo pulogalamu yathu imakhala ndi malamulo anayi:

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

Ma code code ndi ofanana b7, 15, b7 ΠΈ 95. Kumbukirani kuti magawo atatu ofunikira kwambiri ndi gulu la malangizo. Kwa ife, gawo lachinayi la malangizo onse liribe kanthu, kotero makalasi ophunzitsira ndi 7, 5, 7, 5 motsatira. BPF_ALU64,ndi 5 ndi BPF_JMP. M'makalasi onse awiri, ndondomeko ya malangizo ndi yofanana (onani pamwambapa) ndipo tikhoza kulembanso pulogalamu yathu monga chonchi (nthawi yomweyo tidzalembanso mizati yotsalayo mu mawonekedwe aumunthu):

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

Ntchito b kalasi ALU64 Ndi BPF_MOV. Imapereka mtengo ku kaundula wa kopita. Ngati pang'ono yakhazikitsidwa s (gwero), ndiye mtengo umatengedwa kuchokera ku kaundula wa gwero, ndipo ngati, monga momwe ziliri ifeyo, sizinakhazikitsidwe, ndiye kuti mtengowo umachotsedwa kumunda. Imm. Kotero mu malangizo oyambirira ndi achitatu timachita opareshoni r0 = Imm. Komanso, ntchito ya JMP kalasi 1 ndi BPF_JEQ (lumpha ngati ofanana). Kwa ife, kuyambira pang'ono S ndi ziro, imafananiza mtengo wa kaundula wa gwero ndi munda Imm. Ngati zikhalidwe zikugwirizana, ndiye kuti kusintha kumachitika PC + Offkumene PC, monga mwachizolowezi, ili ndi adiresi ya malangizo otsatirawa. Pomaliza, JMP Class 9 Operation ndi BPF_EXIT. Malangizowa amathetsa pulogalamuyo, kubwerera ku kernel r0. Tiyeni tiwonjezere gawo latsopano patebulo lathu:

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

Titha kulembanso izi mwanjira yabwino:

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

Ngati tikumbukira zomwe zili mu kaundula r1 pulogalamu imaperekedwa cholozera ku nkhani kuchokera ku kernel, ndi mu kaundula r0 mtengo umabwezeredwa ku kernel, ndiye titha kuwona kuti ngati cholozera pamutuwu ndi zero, ndiye kuti tibwerera 1, ndipo mwanjira ina - 2. Tiyeni tiwone kuti tikulondola poyang'ana gwero:

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

Inde, ndi pulogalamu yopanda tanthauzo, koma imamasulira mu malangizo anayi osavuta.

Kupatulapo chitsanzo: malangizo a 16-byte

Tidanena kale kuti malangizo ena amatenga ma bits opitilira 64. Izi zimagwira ntchito, mwachitsanzo, ku malangizo lddw (Kodi = 0x18 = BPF_LD | BPF_DW | BPF_IMM) - tsitsani mawu awiri kuchokera m'minda kupita ku kaundula Imm. Zoona zake n’zakuti Imm ali ndi kukula kwa 32, ndipo mawu awiri ndi 64 bits, kotero kukweza mtengo wa 64-bit mwamsanga mu registry mu malangizo amodzi a 64-bit sikungagwire ntchito. Kuti muchite izi, malangizo awiri oyandikana amagwiritsidwa ntchito kusunga gawo lachiwiri la mtengo wa 64-bit m'munda. Imm. Chitsanzo:

$ 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                   ........

Pali malangizo awiri okha mu pulogalamu ya binary:

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

Tidzakumananso ndi malangizo lddw, tikamalankhula za kusamuka ndikugwira ntchito ndi mamapu.

Chitsanzo: kumasula BPF pogwiritsa ntchito zida zokhazikika

Chifukwa chake, taphunzira kuwerenga manambala a binary a BPF ndipo tili okonzeka kugawa malangizo aliwonse ngati kuli kofunikira. Komabe, ndiyenera kunena kuti pochita ndizosavuta komanso mwachangu kugawa mapulogalamu pogwiritsa ntchito zida zokhazikika, mwachitsanzo:

$ 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

Lifecycle ya zinthu za BPF, bpffs file system

(Ndinaphunzira poyamba zina mwazambiri zomwe zafotokozedwa muchigawo chino positi Alexei Starovoitov BPF Blog.)

Zinthu za BPF - mapulogalamu ndi mamapu - amapangidwa kuchokera kumalo ogwiritsa ntchito pogwiritsa ntchito malamulo BPF_PROG_LOAD ΠΈ BPF_MAP_CREATE kuyitana kwadongosolo bpf(2), tikambirana ndendende momwe izi zimachitikira mu gawo lotsatira. Izi zimapanga kernel data structures ndi aliyense wa iwo refcount (reference count) imayikidwa ku imodzi, ndipo fayilo yofotokozera yomwe ikulozera ku chinthucho imabwezeretsedwa kwa wogwiritsa ntchito. Pambuyo chogwirira chatsekedwa refcount chinthucho chimachepetsedwa ndi chimodzi, ndipo chikafika pa ziro, chinthucho chimawonongedwa.

Ngati pulogalamuyo imagwiritsa ntchito mamapu, ndiye refcount mamapu awa amachulukitsidwa ndi imodzi pambuyo potsitsa pulogalamuyi, i.e. mafayilo awo ofotokozera akhoza kutsekedwa kuchokera ku ndondomeko ya wosuta ndipo komabe refcount sizikhala zero:

BPF ya ana aang'ono, gawo limodzi: BPF yowonjezera

Pambuyo potsegula bwino pulogalamu, nthawi zambiri timayiyika ku mtundu wina wa jenereta. Mwachitsanzo, titha kuyiyika pa intaneti kuti tigwiritse ntchito mapaketi omwe akubwera kapena kuwalumikiza ndi ena tracepoint mu mtima. Panthawiyi, kauntala yowonetsera idzawonjezekanso ndi imodzi ndipo tidzatha kutseka ndondomeko ya fayilo mu pulogalamu ya loader.

Kodi chimachitika ndi chiyani ngati titseka bootloader? Zimatengera mtundu wa jenereta ya zochitika (mbeza). Nkhokwe zonse za netiweki zidzakhalapo pambuyo poti chojambulira chatha, izi ndizomwe zimatchedwa mbedza zapadziko lonse lapansi. Ndipo, mwachitsanzo, mapulogalamu otsatirira adzatulutsidwa pambuyo pa kutha kwa njira yomwe adawapanga (ndipo chifukwa chake amatchedwa am'deralo, kuchokera ku "local to process"). Mwaukadaulo, mbedza zakomweko nthawi zonse zimakhala ndi fayilo yofananira pamalo ogwiritsira ntchito ndipo zimatseka njira ikatsekedwa, koma mbedza zapadziko lonse lapansi sizitero. Pachithunzi chotsatirachi, pogwiritsa ntchito mitanda yofiira, ndikuyesera kusonyeza momwe kutha kwa pulogalamu yapamtunda kumakhudzira moyo wa zinthu pazochitika za mbedza zam'deralo ndi zapadziko lonse.

BPF ya ana aang'ono, gawo limodzi: BPF yowonjezera

Chifukwa chiyani pali kusiyana pakati pa mbedza zam'deralo ndi zapadziko lonse lapansi? Kuthamanga mitundu ina ya mapulogalamu a pa intaneti kumakhala komveka popanda malo ogwiritsira ntchito, mwachitsanzo, ganizirani chitetezo cha DDoS - bootloader imalemba malamulo ndikugwirizanitsa pulogalamu ya BPF ku mawonekedwe a intaneti, pambuyo pake bootloader ikhoza kupita ndi kudzipha yokha. Kumbali inayi, taganizirani pulogalamu yowonongeka yomwe mudalemba pa mawondo anu mumphindi khumi - ikatha, mukufuna kuti pasakhale zinyalala zomwe zatsala m'dongosolo, ndipo mbedza zakomweko zidzatsimikizira zimenezo.

Kumbali inayi, yerekezani kuti mukufuna kulumikizana ndi tracepoint mu kernel ndikusonkhanitsa ziwerengero pazaka zambiri. Pankhaniyi, mungafune kumaliza gawo la ogwiritsa ntchito ndikubwerera ku ziwerengerozo nthawi ndi nthawi. Makina a fayilo a bpf amapereka mwayi uwu. Ndi fayilo ya pseudo-memory yokha yomwe imalola kupanga mafayilo omwe amalozera zinthu za BPF ndikuwonjezera. refcount zinthu. Pambuyo pake, chojambuliracho chikhoza kutuluka, ndipo zinthu zomwe adapanga zidzakhalabe zamoyo.

BPF ya ana aang'ono, gawo limodzi: BPF yowonjezera

Kupanga mafayilo mu bpffs omwe amalozera zinthu za BPF amatchedwa "pinning" (monga m'mawu otsatirawa: "ndondomeko imatha kuyika pulogalamu ya BPF kapena mapu"). Kupanga zinthu zamafayilo pazinthu za BPF ndizomveka osati kungowonjezera moyo wa zinthu zam'deralo, komanso kugwiritsidwa ntchito kwa zinthu zapadziko lonse lapansi - kubwereranso ku chitsanzo ndi pulogalamu yachitetezo cha DDoS yapadziko lonse lapansi, tikufuna kuti titha kubwera ndikuwona ziwerengero. nthawi ndi nthawi.

Mafayilo a BPF nthawi zambiri amayikidwa mkati /sys/fs/bpf, koma imathanso kukwera kwanuko, mwachitsanzo, motere:

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

Mayina amtundu wa fayilo amapangidwa pogwiritsa ntchito lamulo BPF_OBJ_PIN Kuyitana kwa dongosolo la BPF. Kuti tichitire fanizo, tiyeni titenge pulogalamu, tiyipange, ikweze, ndikuyikanikiza bpffs. Pulogalamu yathu sichita chilichonse chothandiza, tikungopereka ma code kuti mutha kupanganso chitsanzo:

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

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

Tiyeni tipange pulojekitiyi ndikupanga kopi yakomweko yamafayilo bpffs:

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

Tsopano tiyeni titsitse pulogalamu yathu pogwiritsa ntchito zofunikira bpftool ndipo yang'anani pama foni omwe akutsatira bpf(2) (mizere ina yosafunikira yachotsedwa pa strace output):

$ 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

Apa tatsitsa pulogalamuyo pogwiritsa ntchito BPF_PROG_LOAD, adalandira chofotokozera fayilo kuchokera ku kernel 3 ndi kugwiritsa ntchito lamulo BPF_OBJ_PIN adasindikiza chofotokozera fayilo ngati fayilo "bpf-mountpoint/test". Pambuyo pake, pulogalamu ya bootloader bpftool tidamaliza kugwira ntchito, koma pulogalamu yathu idakhalabe mu kernel, ngakhale sitinayiphatikize ndi mawonekedwe aliwonse a netiweki:

$ 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

Tikhoza kufufuta chinthu file bwinobwino unlink(2) ndipo pambuyo pake pulogalamu yofananirayo idzachotsedwa:

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

Kuchotsa zinthu

Ponena za kuchotsa zinthu, ndikofunikira kumveketsa bwino kuti titatha kuletsa pulogalamuyi ku mbedza (jenereta ya zochitika), palibe chochitika chimodzi chatsopano chomwe chidzayambitse kukhazikitsidwa kwake, komabe, zochitika zonse zamakono za pulogalamuyi zidzakwaniritsidwa mwadongosolo. .

Mitundu ina ya mapulogalamu a BPF amakulolani kuti musinthe pulogalamuyo pa ntchentche, i.e. kupereka ndondomeko ya atomiki replace = detach old program, attach new program. Pachifukwa ichi, zochitika zonse zamtundu wakale wa pulogalamuyi zidzamaliza ntchito yawo, ndipo otsogolera atsopano adzapangidwa kuchokera ku pulogalamu yatsopano, ndipo "atomicity" apa ikutanthauza kuti palibe chochitika chimodzi chomwe chidzaphonyedwe.

Kulumikiza mapulogalamu kumagwero a zochitika

M'nkhaniyi, sitidzafotokozera padera kugwirizanitsa mapulogalamu kuzinthu zomwe zikuchitika, chifukwa ndizomveka kuti tiphunzire izi potengera mtundu wina wa pulogalamu. Cm. chitsanzo pansipa, momwe tikuwonetsa momwe mapulogalamu ngati XDP amalumikizirana.

Kuwongolera Zinthu Pogwiritsa Ntchito Bpf System Call

Pulogalamu ya BPF

Zinthu zonse za BPF zimapangidwa ndikuyendetsedwa kuchokera kumalo ogwiritsa ntchito pogwiritsa ntchito kuyimba kwadongosolo bpf, okhala ndi prototype iyi:

#include <linux/bpf.h>

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

Nayi timu cmd ndi chimodzi mwazinthu zamtundu enum bpf_cmd, attr - cholozera ku magawo a pulogalamu inayake ndi size - kukula kwa chinthu molingana ndi cholozera, i.e. kawirikawiri izi sizeof(*attr). Mu kernel 5.8 kuyimba kwadongosolo bpf amathandiza 34 malamulo osiyanasiyana, ndi tanthauzo union bpf_attr ali ndi mizere 200. Koma sitiyenera kuchita mantha ndi izi, chifukwa tikhala tikudziwa bwino za malamulo ndi magawo m'nkhani zingapo.

Tiyeni tiyambe ndi timu BPF_PROG_LOAD, yomwe imapanga mapulogalamu a BPF - imatenga malangizo a BPF ndikuyiyika mu kernel. Panthawi yotsitsa, chotsimikizira chimayambitsidwa, ndiyeno wopanga JIT ndipo, atachita bwino, chofotokozera cha fayilo chimabwezeretsedwa kwa wogwiritsa ntchito. Tinaona zimene zidzamuchitikire m’gawo lapitalo za kayendedwe ka moyo wa BPF zinthu.

Tsopano tilemba pulogalamu yomwe idzatsegule pulogalamu yosavuta ya BPF, koma choyamba tiyenera kusankha mtundu wa pulogalamu yomwe tikufuna kuyika - tiyenera kusankha. mtundu ndipo mkati mwa chimango chamtunduwu, lembani pulogalamu yomwe idzapambana mayeso otsimikizira. Komabe, kuti tisasokoneze njirayi, nayi njira yokonzekera: titenga pulogalamu ngati BPF_PROG_TYPE_XDP, zomwe zidzabweza mtengo XDP_PASS (dumphani mapepala onse). Mu BPF assembler imawoneka yosavuta kwambiri:

r0 = 2
exit

Titatha kuganiza kuti tidzakweza, titha kukuuzani momwe tichitire:

#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();
}

Zochitika zosangalatsa mu pulogalamu zimayamba ndi tanthauzo la mndandanda insns - pulogalamu yathu ya BPF pamakina. Pachifukwa ichi, malangizo aliwonse a pulogalamu ya BPF amadzazidwa ndi dongosolo bpf_insn. Chinthu choyamba insns imagwirizana ndi malangizo r0 = 2, chachiwiri - exit.

Kubwerera. Kernel imatanthauzira ma macros osavuta polemba manambala amakina, ndikugwiritsa ntchito fayilo yamutu wa kernel tools/include/linux/filter.h tikhoza kulemba

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

Koma popeza kulemba mapulogalamu a BPF m'makhodi achilengedwe ndikofunikira polemba mayeso mu kernel ndi zolemba za BPF, kusowa kwa macros sikumasokoneza moyo wa wopangayo.

Pambuyo pofotokozera pulogalamu ya BPF, timapita kukayiyika mu kernel. Magawo athu a minimalist attr zikuphatikiza mtundu wa pulogalamu, seti ndi kuchuluka kwa malangizo, chilolezo chofunikira, ndi dzina "woo", zomwe timagwiritsa ntchito kuti tipeze pulogalamu yathu pamakina pambuyo potsitsa. Pulogalamuyi, monga momwe idalonjezedwera, imayikidwa mu dongosolo pogwiritsa ntchito kuyimba foni bpf.

Kumapeto kwa pulogalamuyo timakhala mu chipika chopanda malire chomwe chimafanana ndi malipiro. Popanda izo, pulogalamuyo idzaphedwa ndi kernel pamene fayilo yofotokozera kuti kuyitana kwadongosolo kwabwerera kwa ife kutsekedwa. bpf, ndipo sitidzaziwona mu dongosolo.

Chabwino, takonzeka kuyesa. Tiyeni tisonkhanitse ndikuyendetsa pulogalamuyo stracekuti muwone ngati zonse zikuyenda momwe ziyenera kukhalira:

$ 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(

Zonse zili bwino, bpf(2) adabweza chogwirira 3 kwa ife ndipo tidalowa mopanda malire pause(). Tiyeni tiyese kupeza pulogalamu yathu mu dongosolo. Kuti tichite izi tipita ku terminal ina ndikugwiritsa ntchito zofunikira 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)

Tikuwona kuti pali pulogalamu yodzaza pa dongosolo woo omwe ID yawo yapadziko lonse lapansi ndi 390 ndipo ikuchitika pano simple-prog pali fayilo yotseguka yolozera pulogalamuyo (ndipo ngati simple-prog adzamaliza ntchito, ndiye woo zidzatha). Monga zikuyembekezeredwa, pulogalamu woo zimatenga ma byte 16 - malangizo awiri - a ma code binary mumapangidwe a BPF, koma m'mawonekedwe ake (x86_64) ali kale ma byte 40. Tiyeni tiwone pulogalamu yathu mwanjira yake yoyambira:

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

palibe zodabwitsa. Tsopano tiyeni tiwone khodi yopangidwa ndi JIT compiler:

# 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

osathandiza kwambiri kwa exit(2), koma mwachilungamo, pulogalamu yathu ndi yophweka kwambiri, ndipo pamapulogalamu osakhala ang'onoang'ono mawu oyamba ndi epilogue owonjezeredwa ndi JIT compiler ndizofunikira.

Maps

Mapulogalamu a BPF amatha kugwiritsa ntchito malo okumbukira omwe amatha kupezeka ndi mapulogalamu ena a BPF komanso mapulogalamu omwe ali pamalo ogwiritsira ntchito. Zinthuzi zimatchedwa mamapu ndipo m'gawo lino tikuwonetsa momwe tingawagwiritsire ntchito pogwiritsa ntchito kuyimbira foni bpf.

Tinene nthawi yomweyo kuti kuthekera kwa mamapu sikungokhala ndi mwayi wogawana nawo kukumbukira. Pali mamapu acholinga chapadera okhala, mwachitsanzo, zolozera ku mapulogalamu a BPF kapena zolozera pamanetiweki, mamapu ogwirira ntchito ndi zochitika za perf, ndi zina zambiri. Sitilankhula za iwo pano, kuti tisasokoneze owerenga. Kupatula izi, timanyalanyaza nkhani zamalumikizidwe, popeza izi sizofunikira pazitsanzo zathu. Mndandanda wathunthu wamitundu yomwe ilipo ikupezekamo <linux/bpf.h>, ndipo m'gawo lino titenga mwachitsanzo mtundu woyamba wa mbiri yakale, tebulo la hashi BPF_MAP_TYPE_HASH.

Ngati mupanga tebulo la hashi mkati, nenani, C ++, munganene unordered_map<int,long> woo, lomwe m’Chirasha limatanthauza β€œNdikufuna tebulo woo kukula kopanda malire, omwe makiyi ake ndi amtundu int, ndipo zikhalidwe ndizo mtundu long" Kuti tipange tebulo la hashi la BPF, tiyenera kuchita chimodzimodzi, kupatula kuti tiyenera kufotokozera kukula kwake kwa tebulo, ndipo m'malo mofotokozera mitundu ya makiyi ndi zikhalidwe, tiyenera kufotokoza kukula kwake mu ma byte. . Kuti mupange mapu gwiritsani ntchito lamulo BPF_MAP_CREATE kuyitana kwadongosolo bpf. Tiyeni tiwone pulogalamu yocheperako yomwe imapanga mapu. Pambuyo pa pulogalamu yapitayi yomwe imadzaza mapulogalamu a BPF, iyi iyenera kuwoneka yosavuta kwa inu:

$ 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();
}

Apa tikufotokozera magawo angapo attr, momwe timati "Ndikufuna tebulo la hashi ndi makiyi ndi kukula kwake sizeof(int), m'mene ndingathe kuyikamo zinthu zinayi zosapitirira malire." Popanga mapu a BPF, mutha kufotokozera magawo ena, mwachitsanzo, monga momwe ziliri ndi pulogalamuyo, tidatchula dzina la chinthucho ngati. "woo".

Tiyeni tipange ndikuyendetsa pulogalamuyi:

$ 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(

Nayi kuyimbira kwadongosolo bpf(2) adatibwezera nambala ya mapu ofotokozera 3 ndiyeno pulogalamuyo, monga ikuyembekezeka, imadikirira malangizo ena mukuyimbira foni pause(2).

Tsopano tiyeni titumize pulogalamu yathu kumbuyo kapena titsegule terminal ina ndikuyang'ana chinthu chathu pogwiritsa ntchito zofunikira bpftool (titha kusiyanitsa mapu athu ndi ena ndi mayina ake):

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

Nambala 114 ndi ID yapadziko lonse ya chinthu chathu. Pulogalamu iliyonse pamakina imatha kugwiritsa ntchito ID iyi kutsegula mapu omwe alipo pogwiritsa ntchito lamulo BPF_MAP_GET_FD_BY_ID kuyitana kwadongosolo bpf.

Tsopano titha kusewera ndi tebulo lathu la hashi. Tiyeni tiwone zomwe zili mkati mwake:

$ sudo bpftool map dump id 114
Found 0 elements

Chopanda kanthu. Tiyeni tiyike mtengo mmenemo hash[1] = 1:

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

Tiyeni tionenso patebulopo:

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

Uwu! Tinatha kuwonjezera chinthu chimodzi. Dziwani kuti tiyenera kugwira ntchito pamlingo wa byte kuti tichite izi, popeza bptftool sindikudziwa kuti zomwe zili patebulo la hashi ndi zamtundu wanji. (Chidziwitso ichi chikhoza kusamutsidwa kwa iye pogwiritsa ntchito BTF, koma zambiri pa izo tsopano.)

Kodi bpftool imawerengera bwanji ndikuwonjezera zinthu? Tiyeni tiwone pansi pa hood:

$ 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

Choyamba tidatsegula mapu ndi ID yake yapadziko lonse lapansi pogwiritsa ntchito lamulo BPF_MAP_GET_FD_BY_ID ΠΈ bpf(2) anabweretsanso chofotokozera 3. Pogwiritsa ntchito lamulo BPF_MAP_GET_NEXT_KEY tinapeza kiyi yoyamba patebulo podutsa NULL monga cholozera ku kiyi "yam'mbuyo". Ngati tili ndi kiyi titha kuchita BPF_MAP_LOOKUP_ELEMzomwe zimabweretsa mtengo ku cholozera value. Chotsatira ndikuyesa kupeza chinthu chotsatira podutsa cholozera ku kiyi yamakono, koma tebulo lathu lili ndi chinthu chimodzi ndi lamulo. BPF_MAP_GET_NEXT_KEY zobwerera ENOENT.

Chabwino, tiyeni tisinthe mtengo ndi kiyi 1, tinene kuti malingaliro athu abizinesi amafuna kulembetsa 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

Monga kuyembekezera, ndizosavuta: lamulo BPF_MAP_GET_FD_BY_ID imatsegula mapu athu ndi ID, ndi lamulo BPF_MAP_UPDATE_ELEM amachotsa chinthucho.

Chifukwa chake, mutatha kupanga tebulo la hashi kuchokera ku pulogalamu imodzi, titha kuwerenga ndikulemba zomwe zili mkati mwake. Dziwani kuti ngati tidatha kuchita izi kuchokera pamzere wolamula, ndiye kuti pulogalamu ina iliyonse padongosolo ikhoza kuchita. Kuphatikiza pa malamulo omwe afotokozedwa pamwambapa, pogwira ntchito ndi mamapu kuchokera kumalo ogwiritsa ntchito, zotsatirazi:

  • BPF_MAP_LOOKUP_ELEM: pezani mtengo ndi kiyi
  • BPF_MAP_UPDATE_ELEM: sinthani / pangani mtengo
  • BPF_MAP_DELETE_ELEM: chotsani kiyi
  • BPF_MAP_GET_NEXT_KEY: pezani kiyi yotsatira (kapena yoyamba).
  • BPF_MAP_GET_NEXT_ID: imakulolani kuti mudutse mamapu onse omwe alipo, ndi momwe zimagwirira ntchito bpftool map
  • BPF_MAP_GET_FD_BY_ID: tsegulani mapu omwe alipo ndi ID yake yapadziko lonse lapansi
  • BPF_MAP_LOOKUP_AND_DELETE_ELEM: sinthani mtengo wa chinthu ndikubwezera chakale
  • BPF_MAP_FREEZE: pangani mapu kuti asasinthe kuchokera kumalo ogwiritsa ntchito (ntchitoyi siyingathe kusinthidwa)
  • BPF_MAP_LOOKUP_BATCH, BPF_MAP_LOOKUP_AND_DELETE_BATCH, BPF_MAP_UPDATE_BATCH, BPF_MAP_DELETE_BATCH: ntchito zambiri. Mwachitsanzo, BPF_MAP_LOOKUP_AND_DELETE_BATCH - Iyi ndi njira yokhayo yodalirika yowerengera ndikukhazikitsanso zikhalidwe zonse pamapu

Sikuti malamulo onsewa amagwira ntchito pamapu amitundu yonse, koma kugwira ntchito ndi mitundu ina ya mamapu kuchokera kumalo ogwiritsira ntchito kumawoneka chimodzimodzi ndikugwira ntchito ndi matebulo a hashi.

Chifukwa cha dongosolo, tiyeni timalize kuyesa kwathu pa tebulo la hashi. Kumbukirani kuti tidapanga tebulo lomwe limatha kukhala ndi makiyi anayi? Tiyeni tiwonjezere zina zingapo:

$ 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

Pakadali pano, zili bwino:

$ 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

Tiyeni tiyese kuwonjezera ina:

$ sudo bpftool map update id 114 key 5 0 0 0 value 1 0 0 0
Error: update failed: Argument list too long

Monga momwe timayembekezera, sitinapambane. Tiyeni tiwone cholakwikacho mwatsatanetsatane:

$ 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 +++

Chilichonse chili bwino: monga momwe amayembekezera, gulu BPF_MAP_UPDATE_ELEM amayesa kupanga makiyi atsopano, achisanu, koma akuwonongeka E2BIG.

Chifukwa chake, titha kupanga ndikuyika mapulogalamu a BPF, komanso kupanga ndikuwongolera mamapu kuchokera pamalo ogwiritsa ntchito. Tsopano ndizomveka kuyang'ana momwe tingagwiritsire ntchito mapu kuchokera ku mapulogalamu a BPF okha. Titha kulankhula za izi m'chinenero cha mapulogalamu ovuta kuwerenga mu makina akuluakulu, koma nthawi yafika yosonyeza momwe mapulogalamu a BPF amalembedwera ndi kusungidwa - pogwiritsa ntchito libbpf.

(Kwa owerenga omwe sakukhutira ndi kusowa kwa chitsanzo chotsika: tidzasanthula mwatsatanetsatane mapulogalamu omwe amagwiritsa ntchito mapu ndi ntchito zothandizira zomwe zimapangidwa pogwiritsa ntchito libbpf ndikuuzeni zomwe zimachitika pamlingo wa malangizo. Kwa owerenga omwe sakukhutira kwambiri, tawonjezera chitsanzo m’malo oyenera m’nkhaniyo.)

Kulemba mapulogalamu a BPF pogwiritsa ntchito libbpf

Kulemba mapulogalamu a BPF pogwiritsa ntchito makina amakina kumatha kukhala kosangalatsa koyamba kokha, kenako kukhuta kumayamba. Panthawiyi muyenera kutembenukira ku chidwi chanu llvm, yomwe ili ndi backend yopangira ma code omanga a BPF, komanso laibulale libbpf, zomwe zimakulolani kuti mulembe mbali ya ogwiritsa ntchito BPF ndikuyika ma code a BPF opangidwa pogwiritsa ntchito llvm/clang.

M'malo mwake, monga momwe tidzaonera m'nkhani ino ndi yotsatira, libbpf imagwira ntchito zambiri popanda izo (kapena zida zofananira - iproute2, libbcc, libbpf-go, etc.) nzosatheka kukhala ndi moyo. Chimodzi mwazinthu zakupha za polojekitiyi libbpf ndi BPF CO-RE (Compile Once, Run Everywhere) - pulojekiti yomwe imakulolani kuti mulembe mapulogalamu a BPF omwe amatha kunyamula kuchokera ku kernel kupita ku inzake, ndikutha kuthamanga pa ma API osiyanasiyana (mwachitsanzo, pamene kernel imasintha kuchokera ku mtundu wina. ku version). Kuti muthe kugwira ntchito ndi CO-RE, kernel yanu iyenera kupangidwa ndi thandizo la BTF (tikufotokoza momwe mungachitire izi mugawoli. Zida Zachitukuko. Mutha kuwona ngati kernel yanu idamangidwa ndi BTF kapena ayi mophweka - ndi kukhalapo kwa fayilo iyi:

$ ls -lh /sys/kernel/btf/vmlinux
-r--r--r-- 1 root root 2.6M Jul 29 15:30 /sys/kernel/btf/vmlinux

Fayiloyi imasunga zambiri zamitundu yonse yomwe imagwiritsidwa ntchito mu kernel ndipo imagwiritsidwa ntchito m'zitsanzo zathu zonse libbpf. Tidzakambirana mwatsatanetsatane za CO-RE m'nkhani yotsatira, koma mu iyi - ingodzipangira nokha kernel CONFIG_DEBUG_INFO_BTF.

Library libbpf amakhala mu ndandanda tools/lib/bpf kernel ndi kakulidwe kake kumachitika kudzera pamndandanda wamakalata [email protected]. Komabe, malo osiyana amasungidwa pazosowa za mapulogalamu omwe amakhala kunja kwa kernel https://github.com/libbpf/libbpf momwe laibulale ya kernel imawonetsedwa kuti muwerenge zambiri kapena mochepera momwe zilili.

M'chigawo chino tiwona momwe mungapangire polojekiti yomwe imagwiritsa ntchito libbpf, tiyeni tilembe mapulogalamu oyesera angapo (ochulukirapo kapena opanda tanthauzo) ndikusanthula mwatsatanetsatane momwe zonsezi zimagwirira ntchito. Izi zitithandiza kufotokoza mosavuta m'magawo otsatirawa momwe mapulogalamu a BPF amalumikizirana ndi mamapu, othandizira kernel, BTF, ndi zina zambiri.

Kawirikawiri ntchito ntchito libbpf onjezani chosungira cha GitHub ngati git submodule, tichita zomwezo:

$ 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.

Kupita ku libbpf zosavuta:

$ 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

Dongosolo lathu lotsatira mu gawoli lili motere: tilemba pulogalamu ya BPF ngati BPF_PROG_TYPE_XDP, mofanana ndi chitsanzo chapitachi, koma mu C, timapanga pogwiritsa ntchito clang, ndi kulemba pulogalamu yothandizira yomwe idzayike mu kernel. M'magawo otsatirawa tidzakulitsa luso la pulogalamu ya BPF ndi pulogalamu yothandizira.

Chitsanzo: kupanga pulogalamu yathunthu pogwiritsa ntchito libbpf

Poyamba, timagwiritsa ntchito fayilo /sys/kernel/btf/vmlinux, zomwe zatchulidwa pamwambapa, ndikupanga zofanana zake ngati fayilo yamutu:

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

Fayiloyi idzasunga zonse zomwe zilipo mu kernel yathu, mwachitsanzo, umu ndi momwe mutu wa IPv4 umatanthauzidwira mu kernel:

$ 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;
};

Tsopano tilemba pulogalamu yathu ya BPF mu 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";

Ngakhale kuti pulogalamu yathu inali yophweka, tifunikabe kumvetsera zambiri. Choyamba, fayilo yoyamba yamutu yomwe timaphatikizapo ndi vmlinux.h, zomwe tangopanga kumene pogwiritsa ntchito bpftool btf dump - tsopano sitiyenera kuyika phukusi la kernel-headers kuti tidziwe momwe ma kernel amawonekera. Fayilo yamutu yotsatirayi imabwera kwa ife kuchokera ku laibulale libbpf. Tsopano tikungofunikira kuti tifotokoze macro SEC, yomwe imatumiza khalidwe ku gawo loyenera la fayilo ya chinthu cha ELF. Pulogalamu yathu ili mu gawoli xdp/simple, pomwe tisanayambe slash timafotokozera mtundu wa BPF - uwu ndi msonkhano womwe umagwiritsidwa ntchito libbpf, kutengera dzina la gawolo lidzalowa m'malo mwa mtundu wolondola poyambira bpf(2). Pulogalamu ya BPF yokha ndiyo C - yosavuta kwambiri ndipo imakhala ndi mzere umodzi return XDP_PASS. Pomaliza, gawo losiyana "license" lili ndi dzina lachiphaso.

Titha kupanga pulogalamu yathu pogwiritsa ntchito llvm/clang, mtundu> = 10.0.0, kapena kuposa apo, chachikulu (onani gawo Zida Zachitukuko):

$ 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

Zina mwazinthu zosangalatsa: tikuwonetsa zomanga zomwe tikufuna -target bpf ndi njira yopita kumitu libbpf, zomwe taziyika posachedwapa. Komanso, musaiwale za -O2, popanda njira iyi mutha kukhala ndi zodabwitsa m'tsogolomu. Tiyeni tiwone code yathu, tinakwanitsa kulemba pulogalamu yomwe timafuna?

$ 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

Inde, zinathandiza! Tsopano, tili ndi fayilo ya binary ndi pulogalamuyi, ndipo tikufuna kupanga pulogalamu yomwe idzayike mu kernel. Pachifukwa ichi laibulale libbpf amatipatsa zosankha ziwiri - gwiritsani ntchito API yotsika kapena API yapamwamba. Tidzapita njira yachiwiri, popeza tikufuna kuphunzira kulemba, kukweza ndi kulumikiza mapulogalamu a BPF ndi khama lochepa pakuphunzira kwawo kotsatira.

Choyamba, tiyenera kupanga "mafupa" a pulogalamu yathu kuchokera ku binary pogwiritsa ntchito zomwezo bpftool - mpeni waku Swiss wa dziko la BPF (lomwe lingatengedwe kwenikweni, popeza a Daniel Borkman, m'modzi mwa omwe adalenga ndi osamalira BPF, ndi Swiss):

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

Mu fayilo xdp-simple.skel.h ili ndi code binary ya pulogalamu yathu ndi ntchito zowongolera - kutsitsa, kulumikiza, kuchotsa chinthu chathu. M'malo athu osavuta izi zikuwoneka ngati kuchulukirachulukira, koma zimagwiranso ntchito pomwe fayilo ya chinthu ili ndi mapulogalamu ambiri a BPF ndi mamapu ndikukweza ELF yayikuluyi timangofunika kupanga chigoba ndikuyitanitsa ntchito imodzi kapena ziwiri kuchokera ku pulogalamu yomwe timakonda. akulemba Tiyeni tipitirire tsopano.

Kunena zowona, pulogalamu yathu yonyamula katundu ndiyochepa:

#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);
}

ndi struct xdp_simple_bpf kufotokozedwa mu fayilo xdp-simple.skel.h ndikufotokozera fayilo yathu:

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;
};

Titha kuwona zotsatizana za API yotsika apa: kapangidwe kake struct bpf_program *simple ΠΈ struct bpf_link *simple. Mapangidwe oyambirira amafotokoza mwachindunji pulogalamu yathu, yolembedwa mu gawoli xdp/simple, ndipo yachiwiri ikufotokoza momwe pulogalamuyo imagwirizanirana ndi gwero la zochitika.

ntchito xdp_simple_bpf__open_and_load, imatsegula chinthu cha ELF, kuyikapo, kupanga mapangidwe onse ndi zigawo (kupatula pulogalamuyo, ELF ilinso ndi zigawo zina - deta, deta yowerengera, chidziwitso chosokoneza, chilolezo, ndi zina zotero), ndikuchiyika mu kernel pogwiritsa ntchito dongosolo. kuitana bpf, zomwe titha kuziwona polemba ndikuyendetsa pulogalamuyi:

$ 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

Tiyeni tsopano tiwone pulogalamu yathu yogwiritsira ntchito bpftool. Tipeze ID yake:

# 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)

ndi kutaya (timagwiritsa ntchito njira yofupikitsa ya lamulo bpftool prog dump xlated):

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

Chinachake chatsopano! Pulogalamuyi inasindikiza zidutswa za fayilo yathu ya C. Izi zidachitidwa ndi laibulale libbpf, yomwe idapeza gawo la debug mu binary, idayipanga kukhala chinthu cha BTF, ndikuyiyika mu kernel pogwiritsa ntchito BPF_BTF_LOAD, ndiyeno tchulani chofotokozera chotsatira cha fayilo mukamatsitsa pulogalamuyo ndi lamulo BPG_PROG_LOAD.

Othandizira Kernel

Mapulogalamu a BPF amatha kugwira ntchito "zakunja" - othandizira kernel. Ntchito zothandizira izi zimalola mapulogalamu a BPF kuti azitha kupeza mawonekedwe a kernel, kuyang'anira mamapu, komanso kuyankhulana ndi "dziko lenileni" - pangani zochitika za perf, control hardware (mwachitsanzo, kuwongolera mapaketi), ndi zina.

Chitsanzo: bpf_get_smp_processor_id

Mkati mwa dongosolo la "kuphunzira mwachitsanzo" paradigm, tiyeni tiganizire chimodzi mwa ntchito zothandizira, bpf_get_smp_processor_id(), ndithu mu file kernel/bpf/helpers.c. Imabwezeranso nambala ya purosesa yomwe pulogalamu ya BPF yomwe idayitcha ikugwira ntchito. Koma tilibe chidwi ndi semantics yake monga momwe kukhazikitsa kwake kumatenga mzere umodzi:

BPF_CALL_0(bpf_get_smp_processor_id)
{
    return smp_processor_id();
}

Mafotokozedwe a BPF othandizira ndi ofanana ndi matanthauzidwe oyitanitsa a Linux. Apa, mwachitsanzo, ntchito imatanthauzidwa kuti ilibe mikangano. (Ntchito yomwe imatenga, kunena, mikangano itatu imatanthauzidwa pogwiritsa ntchito macro BPF_CALL_3. Kuchuluka kwa mikangano ndi zisanu.) Komabe, ili ndilo gawo loyamba la kutanthauzira. Gawo lachiwiri ndikutanthauzira mawonekedwe amtundu struct bpf_func_proto, yomwe ili ndi kufotokozera kwa ntchito yothandizira yomwe wotsimikizira amamvetsetsa:

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

Kulembetsa Ntchito Zothandizira

Kuti mapulogalamu a BPF amtundu wina agwiritse ntchito ntchitoyi, ayenera kulembetsa, mwachitsanzo pa mtundu wake BPF_PROG_TYPE_XDP ntchito imatanthauzidwa mu kernel xdp_func_proto, yomwe imatsimikizira kuchokera ku ID yothandizira ngati XDP imathandizira ntchitoyi kapena ayi. Ntchito yathu ndi zogwiriziza:

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;
    ...
    }
}

Mitundu yatsopano ya mapulogalamu a BPF "amatanthauzidwa" mufayilo include/linux/bpf_types.h pogwiritsa ntchito macro BPF_PROG_TYPE. Kutanthauziridwa m'mawu chifukwa ndi tanthauzo lomveka, ndipo m'mawu a C chilankhulo kutanthauzira kwamitundu yonse ya konkriti kumachitika m'malo ena. Makamaka, mu fayilo kernel/bpf/verifier.c matanthauzo onse kuchokera ku fayilo bpf_types.h amagwiritsidwa ntchito popanga magulu osiyanasiyana 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
};

Ndiko kuti, pamtundu uliwonse wa pulogalamu ya BPF, cholozera ku dongosolo la deta la mtunduwo chimatanthauzidwa struct bpf_verifier_ops, yomwe imayambitsidwa ndi mtengo _name ## _verifier_ops, i.e. xdp_verifier_ops chifukwa xdp. Kapangidwe xdp_verifier_ops kutsimikiza ndi mu file net/core/filter.c motere:

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,
};

Apa tikuwona ntchito yathu yodziwika bwino xdp_func_proto, yomwe imayendetsa chotsimikizira nthawi iliyonse ikakumana ndi zovuta mtundu wina imagwira ntchito mkati mwa pulogalamu ya BPF, onani verifier.c.

Tiyeni tiwone momwe pulogalamu yongopeka ya BPF imagwiritsira ntchito ntchitoyi bpf_get_smp_processor_id. Kuti tichite izi, timalembanso pulogalamu kuchokera kugawo lathu lapitalo motere:

#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";

Chizindikiro bpf_get_smp_processor_id kutsimikiza ndi Π² <bpf/bpf_helper_defs.h> malaibulale libbpf momwe

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

ndiye, bpf_get_smp_processor_id ndi cholozera ntchito chomwe mtengo wake ndi 8, pomwe 8 ndiye mtengo wake BPF_FUNC_get_smp_processor_id mtundu enum bpf_fun_id, zomwe zimatanthauzidwa kwa ife mu fayilo vmlinux.h (file bpf_helper_defs.h mu kernel amapangidwa ndi script, kotero manambala a "matsenga" ali bwino). Izi sizimatengera zotsutsana ndipo zimabweretsa mtengo wamtundu __u32. Tikamayendetsa mu pulogalamu yathu, clang amapanga malangizo BPF_CALL "zabwino" Tiyeni tipange pulogalamuyo ndikuyang'ana gawolo 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

Mu mzere woyamba tikuwona malangizo call, parameter IMM zomwe zikufanana ndi 8, ndi SRC_REG -ziro. Malinga ndi mgwirizano wa ABI wogwiritsidwa ntchito ndi verifier, uku ndi kuyitanira kwa wothandizira nambala eyiti. Ikangoyambitsidwa, malingaliro ake ndi osavuta. Bweretsani mtengo kuchokera ku register r0 kukopera ku r1 ndipo pa mizere 2,3 imasinthidwa kukhala mtundu u32 - ma bits 32 apamwamba amachotsedwa. Pa mizere 4,5,6,7 tikubwerera 2 (XDP_PASSkapena 1 (XDP_DROP) kutengera ngati wothandizira akugwira ntchito kuchokera pamzere 0 adabweza mtengo wa ziro kapena wopanda ziro.

Tiyeni tidziyese tokha: kwezani pulogalamuyo ndikuyang'ana zomwe zatuluka 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

Chabwino, wotsimikizira adapeza wothandizira kernel wolondola.

Chitsanzo: kupatutsa mikangano n’kuyendetsa pulogalamuyo!

Ntchito zonse zothandizira ma run-level zili ndi prototype

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

Ma parameters ku ntchito zothandizira amaperekedwa m'kaundula r1-r5, ndipo mtengowo umabwezeredwa mu kaundula r0. Palibe ntchito zomwe zimatenga mfundo zopitilira zisanu, ndipo chithandizo chawo sichikuyembekezeka kuwonjezeredwa mtsogolo.

Tiyeni tiwone wothandizira kernel watsopano ndi momwe BPF imadutsa magawo. Tiyeni tilembenso xdp-simple.bpf.c motere (mizere ina yonse sinasinthe):

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

Pulogalamu yathu imasindikiza nambala ya CPU yomwe ikugwira ntchito. Tiyeni tipange ndikuyang'ana pa code:

$ 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

M'mizere 0-7 timalemba chingwe running on CPU%un, ndiyeno pamzere 8 timayendetsa omwe timawadziwa bwino bpf_get_smp_processor_id. Pa mizere 9-12 timakonzekera mikangano yothandizira bpf_printk - olembetsa r1, r2, r3. Chifukwa chiyani alipo atatu osati awiri? Chifukwa bpf_printkiyi ndi macro wrapper kuzungulira mthandizi weniweni bpf_trace_printk, yomwe imayenera kudutsa kukula kwa chingwe chamtundu.

Tiyeni tsopano tiwonjezeko mizere ingapo xdp-simple.ckotero kuti pulogalamu yathu imalumikizana ndi mawonekedwe lo ndipo zidayambadi!

$ 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);
}

Apa timagwiritsa ntchito bpf_set_link_xdp_fd, yomwe imalumikiza mapulogalamu amtundu wa XDP-mtundu wa BPF kumalo olumikizirana netiweki. Tinasindikiza nambala ya mawonekedwe lo, yomwe nthawi zonse imakhala 1. Timayendetsa ntchitoyi kawiri kuti tiyambe kuchotsa pulogalamu yakale ngati idalumikizidwa. Zindikirani kuti tsopano sitikusowa chotsutsa pause kapena kuzungulira kopanda malire: pulogalamu yathu yonyamula katundu ituluka, koma pulogalamu ya BPF siiphedwa chifukwa imalumikizidwa ndi gwero la chochitika. Pambuyo kutsitsa bwino ndi kulumikizana, pulogalamuyo idzayambika pa paketi iliyonse ya netiweki ikafika lo.

Tiyeni kukopera pulogalamu ndi kuyang'ana mawonekedwe 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

Pulogalamu yomwe tidatsitsa ili ndi ID 669 ndipo tikuwona ID yomweyi pamawonekedwe lo. Titumiza mapaketi angapo ku 127.0.0.1 (pempho + yankhani):

$ ping -c1 localhost

ndipo tsopano tiyeni tiyang'ane zomwe zili mu fayilo ya debug virtual /sys/kernel/debug/tracing/trace_pipe, mu bpf_printk akulemba mameseji ake:

# 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

Maphukusi awiri adawonedwa lo ndikukonzedwa pa CPU0 - pulogalamu yathu yoyamba yopanda tanthauzo ya BPF idagwira ntchito!

Tiyenera kudziwa kuti bpf_printk Sizopanda pake zomwe zimalembera fayilo yowonongeka: uyu siwothandiza kwambiri kuti agwiritsidwe ntchito popanga, koma cholinga chathu chinali kusonyeza chinthu chophweka.

Kupeza mamapu kuchokera kumapulogalamu a BPF

Chitsanzo: kugwiritsa ntchito mapu a pulogalamu ya BPF

M'magawo apitawa taphunzira kupanga ndi kugwiritsa ntchito mamapu kuchokera kumalo ogwiritsira ntchito, ndipo tsopano tiyeni tiwone gawo la kernel. Tiyeni tiyambe, monga mwachizolowezi, ndi chitsanzo. Tiyeni tilembenso pulogalamu yathu xdp-simple.bpf.c motere:

#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";

Kumayambiriro kwa pulogalamuyi tinawonjezera tanthauzo la mapu woo: Ichi ndi mndandanda wazinthu 8 zomwe zimasunga zinthu ngati u64 (mu C tingatanthauze mndandanda ngati u64 woo[8]). Mu pulogalamu "xdp/simple" timapeza nambala ya purosesa yamakono kukhala yosinthika key ndiyeno kugwiritsa ntchito wothandizira bpf_map_lookup_element timapeza cholozera cholowera chofananira mugulu, zomwe timawonjezera ndi chimodzi. Kutanthauziridwa ku Chirasha: timawerengera momwe CPU idasinthira mapaketi obwera. Tiyeni tiyese kuyendetsa pulogalamuyi:

$ 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

Tiyeni tiwone ngati walumikizidwa lo ndi kutumiza mapaketi ena:

$ 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

Tsopano tiyeni tiwone zomwe zili mugululi:

$ 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 }
]

Pafupifupi njira zonse zidakonzedwa pa CPU7. Izi sizofunikira kwa ife, chachikulu ndikuti pulogalamuyi imagwira ntchito ndipo timamvetsetsa momwe tingapezere mamapu kuchokera ku mapulogalamu a BPF - kugwiritsa ntchito Ρ…Π΅Π»ΠΏΠ΅Ρ€ΠΎΠ² bpf_mp_*.

Mystical index

Chifukwa chake, titha kupeza mapu kuchokera ku pulogalamu ya BPF pogwiritsa ntchito mafoni ngati

val = bpf_map_lookup_elem(&woo, &key);

kumene ntchito yothandizira ikuwoneka ngati

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

koma tikudutsa cholozera &woo ku dongosolo losatchulidwa dzina struct { ... }...

Tikayang'ana pulogalamu yosonkhanitsa, timawona kuti mtengo wake &woo sichikufotokozedwa (mzere 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
...

ndipo ili mu kusamuka:

$ 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

Koma ngati tiyang'ana pulogalamu yomwe yadzaza kale, tikuwona cholozera pamapu olondola (mzere 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]
...

Chifukwa chake, titha kunena kuti panthawi yoyambitsa pulogalamu yathu yojambulira, ulalo wa &woo inalowedwa m’malo ndi chinachake chokhala ndi laibulale libbpf. Choyamba tiwona zotsatira zake 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

Ife tikuziwona izo libbpf adapanga mapu woo kenako dawunilodi pulogalamu yathu simple. Tiyeni tiwone mwatsatanetsatane momwe timayika pulogalamuyo:

  • kuitana xdp_simple_bpf__open_and_load kuchokera fayilo xdp-simple.skel.h
  • zomwe zimayambitsa xdp_simple_bpf__load kuchokera fayilo xdp-simple.skel.h
  • zomwe zimayambitsa bpf_object__load_skeleton kuchokera fayilo libbpf/src/libbpf.c
  • zomwe zimayambitsa bpf_object__load_xattr kuchokera libbpf/src/libbpf.c

Ntchito yomaliza, mwa zina, idzayitana bpf_object__create_maps, yomwe imapanga kapena kutsegula mapu omwe alipo, kuwasandutsa ofotokozera mafayilo. (Apa ndi pamene tikuwona BPF_MAP_CREATE mu zotuluka strace.) Kenako ntchitoyo imatchedwa bpf_object__relocate ndipo ndi iye amene amatikonda, popeza timakumbukira zomwe tidaziwona woo pa tebulo losamuka. Kuzifufuza, potsirizira pake tidzipeza tiri mu ntchitoyi bpf_program__relocate, amene ikukhudzana ndi kusamutsa mapu:

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

Choncho timatenga malangizo athu

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

ndi kusintha kaundula gwero mmenemo ndi BPF_PSEUDO_MAP_FD, ndi IMM yoyamba yofotokozera mapu athu ndipo, ngati ili yofanana, mwachitsanzo, 0xdeadbeef, ndiye zotsatira zake tidzalandira malangizo

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

Umu ndi momwe zidziwitso zamapu zimasamutsidwira ku pulogalamu inayake ya BPF yodzaza. Pankhaniyi, mapu akhoza kupangidwa pogwiritsa ntchito BPF_MAP_CREATE, ndi kutsegulidwa ndi ID pogwiritsa ntchito BPF_MAP_GET_FD_BY_ID.

Total, pamene ntchito libbpf algorithm ili motere:

  • pakuphatikiza, zolemba zimapangidwa patebulo losamutsidwa kuti zigwirizane ndi mamapu
  • libbpf amatsegula buku la chinthu cha ELF, amapeza mamapu onse ogwiritsidwa ntchito ndikupanga zofotokozera zamafayilo
  • Zofotokozera zamafayilo zimayikidwa mu kernel ngati gawo la malangizo LD64

Monga momwe mungaganizire, pali zambiri zomwe zikubwera ndipo tiyenera kuyang'ana pachimake. Mwamwayi, tili ndi chidziwitso - talemba tanthauzo lake BPF_PSEUDO_MAP_FD m'kaundula wa gwero ndipo titha kuziyika, zomwe zingatifikitse ku oyera a oyera onse - kernel/bpf/verifier.c, pomwe ntchito yokhala ndi dzina losiyana imalowa m'malo mwa fayilo yofotokozera ndi adilesi yamtundu wamtundu 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;

(kodi yonse ingapezeke kugwirizana). Chifukwa chake titha kuwonjezera ma algorithm athu:

  • potsitsa pulogalamuyo, wotsimikizira amayang'ana momwe mapu amagwiritsidwira ntchito moyenera ndikulemba adilesi yofananira struct bpf_map

Mukatsitsa binary ya ELF pogwiritsa ntchito libbpf Pali zambiri zomwe zikuchitika, koma tidzakambirana m'nkhani zina.

Kutsegula mapulogalamu ndi mamapu opanda libbpf

Monga momwe analonjezedwa, apa pali chitsanzo kwa owerenga omwe akufuna kudziwa momwe angapangire ndikuyika pulogalamu yomwe imagwiritsa ntchito mapu, popanda thandizo. libbpf. Izi zitha kukhala zothandiza ngati mukugwira ntchito m'malo omwe simungathe kupanga zodalira, kapena kusunga pang'ono, kapena kulemba pulogalamu ngati. ply, yomwe imapanga BPF binary code pa ntchentche.

Kuti zikhale zosavuta kutsatira malingaliro, tidzalembanso chitsanzo chathu pazifukwa izi xdp-simple. Khodi yathunthu komanso yokulitsidwa pang'ono ya pulogalamu yomwe yafotokozedwa mu chitsanzo ichi imapezeka mu izi mfundo.

Malingaliro akugwiritsa ntchito kwathu ndi awa:

  • pangani mtundu wa mapu BPF_MAP_TYPE_ARRAY pogwiritsa ntchito lamulo BPF_MAP_CREATE,
  • pangani pulogalamu yomwe imagwiritsa ntchito mapu awa,
  • gwirizanitsani pulogalamuyo ku mawonekedwe lo,

zomwe zimatanthawuza kuti munthu

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);
}

ndi map_create amapanga mapu mofanana ndi momwe tinachitira mu chitsanzo choyamba cha kuyitana kwadongosolo bpf - "kernel, chonde ndipangireni mapu atsopano mumndandanda wazinthu 8 monga __u64 ndipo ndibwezereni fayilo yofotokozera":

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));
}

Pulogalamuyi ndi yosavuta kutsegula:

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));
}

Gawo lovuta prog_load ndiye tanthauzo la pulogalamu yathu ya BPF ngati mndandanda wamapangidwe struct bpf_insn insns[]. Koma popeza tikugwiritsa ntchito pulogalamu yomwe tili nayo mu C, titha kubera pang'ono:

$ 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

Pazonse, tiyenera kulemba malangizo 14 mu mawonekedwe a zomanga ngati struct bpf_insn (malangizo: tengani zotayira pamwamba, werenganinso gawo la malangizo, tsegulani linux/bpf.h ΠΈ linux/bpf_common.h ndi kuyesa kudziwa struct bpf_insn insns[] pawekha):

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
    },
};

Zochita kwa iwo omwe sanalembe izi okha - pezani map_fd.

Pali gawo linanso lomwe silinafotokozedwe mu pulogalamu yathu - xdp_attach. Tsoka ilo, mapulogalamu ngati XDP sangathe kulumikizidwa pogwiritsa ntchito foni yam'manja bpf. Anthu omwe adapanga BPF ndi XDP anali ochokera mgulu la Linux pa intaneti, zomwe zikutanthauza kuti adagwiritsa ntchito zomwe amazidziwa kwambiri (koma osati zabwinobwino people) mawonekedwe olumikizirana ndi kernel: zitsulo za netlink, onaninso Zogulitsa. Njira yosavuta kukhazikitsa xdp_attach amakopera kodi libbpf, ndiye, kuchokera pa fayilo netlink.c, zomwe tidachita, kuzifupikitsa pang'ono:

Takulandilani kudziko la netlink sockets

Tsegulani mtundu wa socket wa netlink NETLINK_ROUTE:

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

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

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

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

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

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

    *nl_pid = sa.nl_pid;
    return sock;
}

Timawerenga kuchokera ku socket iyi:

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;
}

Pomaliza, nayi ntchito yathu yomwe imatsegula socket ndikutumiza uthenga wapadera kwa iyo yomwe ili ndi chofotokozera fayilo:

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;
}

Chifukwa chake, zonse zakonzeka kuyesedwa:

$ 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 +++

Tiyeni tiwone ngati pulogalamu yathu yalumikizidwa ndi 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

Tiyeni titumize ma pings ndikuwona mapu:

$ 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

Hurray, zonse zimagwira ntchito. Zindikirani, mwa njira, kuti mapu athu akuwonetsedwanso ngati ma byte. Izi ndichifukwa choti, mosiyana libbpf sitinakweze zambiri zamtundu (BTF). Koma tidzakambirana zambiri za izi nthawi ina.

Zida Zachitukuko

M'chigawo chino, tiwona zida zochepa zopangira BPF.

Nthawi zambiri, simukusowa chilichonse chapadera kuti mupange mapulogalamu a BPF - BPF imayenda pa kernel yabwino yogawa, ndipo mapulogalamu amapangidwa pogwiritsa ntchito clang, yomwe ingaperekedwe kuchokera phukusi. Komabe, chifukwa chakuti BPF ikupangidwa, kernel ndi zida zikusintha nthawi zonse, ngati simukufuna kulemba mapulogalamu a BPF pogwiritsa ntchito njira zakale za 2019, ndiye kuti muyenera kusonkhanitsa.

  • llvm/clang
  • pahole
  • maziko ake
  • bpftool

(Kuti mufotokozere, gawo ili ndi zitsanzo zonse zomwe zili m'nkhaniyi zidayendetsedwa pa Debian 10.)

llvm/ku

BPF ndi yaubwenzi ndi LLVM ndipo, ngakhale mapulogalamu aposachedwa a BPF atha kupangidwa pogwiritsa ntchito gcc, zonse zomwe zikuchitika pano zikuchitika ku LLVM. Choncho, choyamba, tidzamanga mtundu wamakono clang kuchokera ku 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
... ΠΌΠ½ΠΎΠ³ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ спустя
$

Tsopano titha kuwona ngati zonse zidagwirizana bwino:

$ ./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

(Malangizo a msonkhano clang zotengedwa ndi ine kuchokera bpf_devel_QA.)

Sitidzayika mapulogalamu omwe tangopanga kumene, koma m'malo mwake tingowawonjezera PATH, mwachitsanzo:

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

(Izi zikhoza kuwonjezeredwa ku .bashrc kapena ku fayilo ina. Payekha, ndimawonjezera zinthu ngati izi ~/bin/activate-llvm.sh ndipo pakufunika ndimachita . activate-llvm.sh.)

Pahole ndi BTF

Zothandiza pahole amagwiritsidwa ntchito pomanga kernel kuti apange zambiri zosokoneza mu mtundu wa BTF. Sitidzafotokozera mwatsatanetsatane mwatsatanetsatane zaukadaulo wa BTF, kupatula kuti ndiyosavuta ndipo tikufuna kuigwiritsa ntchito. Chifukwa chake ngati mupanga kernel yanu, pangani kaye pahole (wopanda pahole simungathe kupanga kernel ndi mwayi 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

Kernels zoyesera ndi BPF

Ndikafufuza zotheka za BPF, ndikufuna kusonkhanitsa maziko anga. Izi, nthawi zambiri, sizofunikira, chifukwa mutha kupanga ndikuyika mapulogalamu a BPF pa kernel yogawa, komabe, kukhala ndi kernel yanu kumakupatsani mwayi wogwiritsa ntchito zida zaposachedwa za BPF, zomwe ziziwoneka pakugawa kwanu m'miyezi yabwino kwambiri. , kapena, monga momwe zilili ndi zida zina zowongolera sizidzapakidwa konse m'tsogolomu. Komanso pachimake chake chimapangitsa kukhala kofunikira kuyesa kachidindo.

Kuti mupange kernel muyenera, choyamba, kernel yokha, ndipo kachiwiri, fayilo yokonzekera kernel. Kuyesera ndi BPF titha kugwiritsa ntchito mwachizolowezi vanila kernel kapena imodzi mwa maso otukuka. M'mbuyomu, chitukuko cha BPF chimachitika m'magulu ochezera a pa intaneti a Linux motero zonse zimasintha posachedwa kudzera mwa David Miller, woyang'anira maukonde a Linux. Kutengera mawonekedwe awo - zosintha kapena zatsopano - zosintha pamaneti zimagwera m'modzi mwazinthu ziwiri - net kapena net-next. Kusintha kwa BPF kumagawidwa mofanana pakati bpf ΠΈ bpf-next, zomwe kenako zimaphatikizidwa mu ukonde ndi ukonde wotsatira, motsatana. Kuti mudziwe zambiri, onani bpf_devel_QA ΠΈ netdev-FAQ. Chifukwa chake sankhani kernel kutengera kukoma kwanu komanso kukhazikika kwa dongosolo lomwe mukuyesa (*-next maso ndiwo osakhazikika kwambiri mwa omwe atchulidwa).

Ndizoposa kukula kwa nkhaniyi kuti tikambirane za momwe mungasamalire mafayilo osinthika a kernel - akuganiza kuti mukudziwa kale momwe mungachitire izi, kapena wokonzeka kuphunzira payekha. Komabe, malangizo otsatirawa ayenera kukhala ochulukirapo kapena ocheperako kuti akupatseni kachitidwe kogwiritsa ntchito BPF.

Tsitsani nsonga imodzi yomwe ili pamwambapa:

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

Pangani kernel yocheperako yogwirira ntchito:

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

Yambitsani zosankha za BPF mufayilo .config mwa kusankha kwanu (mwina CONFIG_BPF idzayatsidwa kale popeza systemd imagwiritsa ntchito). Nawu mndandanda wazosankha kuchokera ku kernel zomwe zagwiritsidwa ntchito pankhaniyi:

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

Kenako titha kusonkhanitsa ndikuyika ma module ndi kernel (mwa njira, mutha kusonkhanitsa kernel pogwiritsa ntchito zomwe zasonkhanitsidwa kumene. clangpowonjezera CC=clang):

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

ndikuyambiranso ndi kernel yatsopano (ndimagwiritsa ntchito izi kexec kuchokera phukusi 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

Zomwe zimagwiritsidwa ntchito kwambiri m'nkhaniyi zidzakhala zothandiza bpftool, yoperekedwa ngati gawo la Linux kernel. Imalembedwa ndikusungidwa ndi opanga BPF kwa opanga BPF ndipo itha kugwiritsidwa ntchito kuyang'anira mitundu yonse ya zinthu za BPF - kutsitsa mapulogalamu, kupanga ndikusintha mamapu, kufufuza moyo wa chilengedwe cha BPF, ndi zina zambiri. Zolemba zamtundu wa magwero amasamba amunthu zitha kupezeka mu mtima kapena, zalembedwa kale, pa ukonde.

Pa nthawi yolemba izi bpftool zimangopangidwira RHEL, Fedora ndi Ubuntu (onani, mwachitsanzo, ulusi uwu, yomwe imafotokoza nkhani yosamalizidwa ya kulongedza bpftool mu Debian). Koma ngati mwamanga kale kernel yanu, pangani bpftool zosavuta ngati pie:

$ 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  ]

$

(Pano ${linux} - iyi ndiye bukhu lanu la kernel.) Pambuyo pochita malamulowa bpftool zidzasonkhanitsidwa mu chikwatu ${linux}/tools/bpf/bpftool ndipo ikhoza kuwonjezeredwa panjira (choyamba kwa wogwiritsa ntchito root) kapena ingotengerani ku /usr/local/sbin.

Sungani bpftool ndi bwino kugwiritsa ntchito yomaliza clang, zosonkhanitsidwa monga tafotokozera pamwambapa, ndipo fufuzani ngati zasonkhanitsidwa molondola - pogwiritsa ntchito, mwachitsanzo, lamulo

$ 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
...

zomwe zikuwonetsa zomwe BPF imayatsidwa mu kernel yanu.

Mwa njira, lamulo lapitalo likhoza kuyendetsedwa ngati

# bpftool f p k

Izi zimachitidwa ndi fanizo ndi zofunikira kuchokera phukusi iproute2, kumene tingathe, mwachitsanzo, kunena ip a s eth0 mmalo mwa ip addr show dev eth0.

Pomaliza

BPF imakulolani kuti muvale utitiri kuti muyese bwino ndikusintha momwe zimagwirira ntchito pachimake. Dongosololi linakhala lopambana kwambiri, mu miyambo yabwino ya UNIX: njira yosavuta yomwe imakulolani (kukonzanso) ndondomeko ya kernel inalola anthu ambiri ndi mabungwe kuyesa. Ndipo, ngakhale zoyesera, komanso chitukuko cha zomangamanga za BPF palokha, sizikutha, dongosololi lili ndi ABI yokhazikika yomwe imakulolani kuti mumange malingaliro odalirika, komanso ofunika kwambiri, ogwira ntchito zamalonda.

Ndikufuna kuzindikira kuti, mwa lingaliro langa, teknoloji yakhala yotchuka kwambiri chifukwa, kumbali imodzi, imatha play (mamangidwe a makina amatha kumveka mochuluka kapena pang'ono madzulo amodzi), ndipo kumbali ina, kuthetsa mavuto omwe sakanatha (mokongola) asanawonekere. Zigawo ziwirizi palimodzi zimakakamiza anthu kuyesa ndikulota, zomwe zimapangitsa kuti pakhale njira zowonjezera zowonjezera.

Nkhaniyi, ngakhale kuti siifupikitsa, ndi chiyambi chabe cha dziko la BPF ndipo sichimalongosola "zotsogola" ndi mbali zofunika za zomangamanga. Dongosolo lomwe likupita patsogolo ndiloti: Nkhani yotsatira ikhala mwachidule mitundu ya pulogalamu ya BPF (pali mitundu 5.8 yamapulogalamu yomwe imathandizidwa mu 30 kernel), ndiye pomaliza tiwona momwe tingalembere mapulogalamu enieni a BPF pogwiritsa ntchito mapulogalamu otsata kernel. mwachitsanzo, ndiye nthawi ya maphunziro mozama pa BPF zomangamanga, kutsatiridwa ndi zitsanzo za BPF maukonde ndi ntchito chitetezo.

Nkhani zam'mbuyo za mndandanda uno

  1. BPF ya ana aang'ono, gawo la ziro: BPF yapamwamba

Maulalo

  1. BPF ndi XDP Reference Guide - zolembedwa pa BPF kuchokera ku cilium, kapena ndendende kuchokera kwa a Daniel Borkman, m'modzi mwa omwe adalenga ndi osamalira BPF. Ili ndi limodzi mwa mafotokozedwe oyambirira aakulu, amene amasiyana ndi ena onse chifukwa Danieli ankadziwa bwino lomwe zimene akulemba ndipo palibe zolakwa. Makamaka, chikalatachi chikufotokoza momwe mungagwiritsire ntchito ndi mapulogalamu a BPF a XDP ndi TC mitundu pogwiritsa ntchito zida zodziwika bwino. ip kuchokera phukusi iproute2.

  2. Documentation/networking/filter.txt - Fayilo yoyambirira yokhala ndi zolemba zakale kenako ndi BPF yowonjezera. Kuwerenga kwabwino ngati mukufuna kuphunzira chilankhulo cha msonkhano komanso tsatanetsatane wa zomangamanga.

  3. Blog za BPF kuchokera ku facebook. Imasinthidwa kawirikawiri, koma moyenera, monga Alexei Starovoitov (mlembi wa eBPF) ndi Andrii Nakryiko - (wosamalira) amalembera pamenepo. libbpf).

  4. Zinsinsi za bpftool. Ulusi wosangalatsa wa twitter wochokera kwa Quentin Monnet wokhala ndi zitsanzo ndi zinsinsi zogwiritsa ntchito bpftool.

  5. Dzilowetseni mu BPF: mndandanda wazinthu zowerengera. Mndandanda waukulu (komanso wosungidwa) wamalumikizidwe ku zolemba za BPF kuchokera kwa Quentin Monnet.

Source: www.habr.com

Kuwonjezera ndemanga