BPF bakeng sa bana ba banyenyane, karolo ea pele: BPF e atolositsoeng

Qalong ho ne ho na le theknoloji mme e ne e bitsoa BPF. Re ile ra mo sheba pejana, sehlooho sa Testamente ea Khale letotong lena. Ka selemo sa 2013, ka boiteko ba Alexei Starovoitov le Daniel Borkman, mofuta oa eona o ntlafalitsoeng, o ntlafalitsoeng bakeng sa mechini ea sejoale-joale ea 64-bit, e ile ea ntlafatsoa mme ea kenyeletsoa ho Linux kernel. Theknoloji ena e ncha e ile ea bitsoa ka bokhutšoanyane BPF ea ka hare, ea ntan'o rehoa lebitso la Extended BPF, 'me joale, ka mor'a lilemo tse ngata, bohle ba e bitsa BPF.

Ka mantsoe a mang, BPF e u lumella ho tsamaisa khoutu e fanoeng ke basebelisi sebakeng sa Linux kernel, 'me moaho o mocha o atlehile hoo re tla hloka lingoloa tse ling tse XNUMX ho hlalosa lits'ebetso tsohle tsa ona. (Ntho feela eo bahlahisi ba sa e etsang hantle, joalo ka ha u bona khoutung ea ts'ebetso e ka tlase, e ne e le ho theha logo e ntle.)

Sehlooho sena se hlalosa sebopeho sa mochine oa sebele oa BPF, li-interfaces tsa kernel bakeng sa ho sebetsa le BPF, lisebelisoa tsa ntlafatso, hammoho le tlhaloso e khutšoanyane, e khutšoanyane haholo ea bokhoni bo teng, ke hore. tsohle tseo re tla li hloka nakong e tlang bakeng sa boithuto bo tebileng ba ts'ebeliso e sebetsang ea BPF.
BPF bakeng sa bana ba banyenyane, karolo ea pele: BPF e atolositsoeng

Kakaretso ea sehlooho

Kenyelletso ea meralo ea BPF. Taba ea pele, re tla sheba sebopeho sa BPF ka leihlo le le leng ebe re hlalosa likarolo tsa mantlha.

Ngoliso le sistimi ea litaelo ea mochini o hlakileng oa BPF. Kaha re se re ntse re e-na le mohopolo oa meralo ka kakaretso, re tla hlalosa sebopeho sa mochini o sebetsang oa BPF.

Potoloho ea bophelo ea lintho tsa BPF, bpffs file system. Karolong ena, re tla shebisisa bophelo ba lintho tsa BPF - mananeo le limmapa.

Ho laola lintho ka ho sebelisa mohala oa sistimi ea bpf. Ka kutloisiso e itseng ea tsamaiso e seng e ntse e le teng, qetellong re tla sheba mokhoa oa ho theha le ho laola lintho ho tloha sebakeng sa mosebedisi ho sebelisa mohala o khethehileng oa tsamaiso - bpf(2).

Пишем программы BPF с помощью libbpf. Ehlile, o ka ngola mananeo o sebelisa mohala oa sistimi. Empa ho thata. Bakeng sa boemo ba sebele haholoanyane, baetsi ba mananeo a nyutlelie ba ile ba qapa laebrari libbpf. Re tla theha skeleton ea mantlha ea ts'ebeliso ea BPF eo re tla e sebelisa mehlaleng e latelang.

Bathusi ba Kernel. Mona re tla ithuta kamoo mananeo a BPF a ka fihlelang mesebetsi ea kernel helper - sesebelisoa seo, hammoho le limmapa, se holisang bokhoni ba BPF e ncha ha e bapisoa le ea khale.

Ho fihlella limmapa ho tsoa mananeong a BPF. Mothating ona, re tla tseba ho lekana ho utloisisa hantle hore na re ka etsa mananeo a sebelisang limmapa joang. Mme ha re shebeng kapele ho netefatso e kholo le e matla.

Lisebelisoa tsa ntlafatso. Karolo ea thuso mabapi le mokhoa oa ho kopanya lisebelisoa tse hlokahalang le kernel bakeng sa liteko.

Sephetho. Qetellong ea sehlooho sena, ba balang ho fihlela mona ba tla fumana mantsoe a susumetsang le tlhaloso e khutšoanyane ea se tla etsahala lihloohong tse latelang. Re tla boela re thathamise lihokelo tse 'maloa bakeng sa boithuto bakeng sa ba se nang takatso kapa bokhoni ba ho emela ho tsoela pele.

Selelekela ho BPF Architecture

Pele re qala ho nahana ka meralo ea BPF, re tla bua ka lekhetlo la ho qetela (oh) ho BPF ea khale, e ileng ea ntlafatsoa e le karabelo ea ho fihla ha mechine ea RISC le ho rarolla bothata ba ho sefa lipakete hantle. Mohaho ona o ile oa atleha hoo, kaha o hlahile lilemong tsa bo-XNUMX Berkeley UNIX, o ile oa fetisetsoa ho mekhoa e mengata ea ts'ebetso e teng, e pholohile ho fihlela lilemong tsa bohlanya 'me e ntse e fumana likopo tse ncha.

BPF e ncha e ile ea ntlafatsoa e le karabelo ho bongata ba mechini ea 64-bit, lits'ebeletso tsa maru le tlhoko e ntseng e eketseha ea lisebelisoa tsa ho theha SDN (Shangata-defile nho sebetsa). E ntlafalitsoe ke lienjiniere tsa marang-rang tsa kernel e le phetisetso e ntlafalitsoeng ea BPF ea khale, BPF e ncha ka mor'a likhoeli tse tšeletseng e ile ea fumana lits'ebetso mosebetsing o boima oa ho latela lits'ebetso tsa Linux, 'me joale, lilemo tse ts'eletseng kamora ho hlaha ha eona, re tla hloka sengoloa se latelang feela. thathamisa mefuta e fapaneng ea mananeo.

Litšoantšo tse qabolang

Bohareng ba eona, BPF ke mochini oa sandbox o u lumellang hore u tsamaise khoutu ea "khang" sebakeng sa kernel ntle le ho senya ts'ireletso. Mananeo a BPF a thehiloe sebakeng sa basebelisi, a kenngoa ka har'a kernel, 'me a hokahane le mohloli o mong oa ketsahalo. Ketsahalo e ka 'na ea e-ba, mohlala, ho fana ka pakete ho sebopeho sa marang-rang, ho qalisoa ha mosebetsi o mong oa kernel, joalo-joalo. Tabeng ea sephutheloana, lenaneo la BPF le tla ba le phihlello ea data le metadata ea sephutheloana (bakeng sa ho bala le, mohlomong, ho ngola, ho latela mofuta oa lenaneo); molemong oa ho tsamaisa tšebetso ea kernel, likhang tsa ts'ebetso, ho kenyelletsa le lintlha tse lebisang mohopolong oa kernel, joalo-joalo.

A re ke re shebisiseng tshebetso ena. Ho qala, a re ke re bue ka phapang ea pele ho tloha BPF ea khale, mananeo a neng a ngotsoe ka assembler. Phetolelong e ncha, mohaho o ile oa atolosoa e le hore mananeo a ka ngoloa ka lipuo tse phahameng, haholo-holo, ha e le hantle, ho C. Bakeng sa sena, ho ile ha thehoa backend bakeng sa llvm, e leng se u lumellang hore u hlahise bytecode bakeng sa mohaho oa BPF.

BPF bakeng sa bana ba banyenyane, karolo ea pele: BPF e atolositsoeng

Mohaho oa BPF o ne o etselitsoe, ka karolo e 'ngoe, hore o sebetse hantle ka mechini ea sejoale-joale. Ho etsa hore sena se sebetse, BPF bytecode, hang ha e kentsoe ka har'a kernel, e fetoleloa ho khoutu ea matsoalloa ho sebelisoa karolo e bitsoang JIT compiler (Jho joalo In Time). Ka mor'a moo, haeba u hopola, ka BPF ea khale, lenaneo le ne le kenngoa ka har'a kernel 'me le khomaretsoe mohloling oa ketsahalo ka atomically - molemong oa mohala o le mong oa tsamaiso. Moahong o mocha, sena se etsahala ka mekhahlelo e 'meli - ea pele, khoutu e kenngoa ka har'a kernel ho sebelisoa mohala oa sistimi. bpf(2)'me joale, hamorao, ka mekhoa e meng e fapaneng ho itšetlehile ka mofuta oa lenaneo, lenaneo le khomarela mohloli oa ketsahalo.

Mona 'mali a ka ba le potso: na ho ne ho ka khoneha? Tšireletseho ea ts'ebetso ea khoutu e joalo e tiisitsoe joang? Tšireletseho ea ts'ebetso e tiisetsoa ho rona ka mohato oa ho kenya mananeo a BPF a bitsoang verifier (ka Senyesemane sethaleng sena se bitsoa verifier 'me ke tla tsoelapele ho sebelisa lentsoe la Senyesemane):

BPF bakeng sa bana ba banyenyane, karolo ea pele: BPF e atolositsoeng

Verifier ke analyzer e tsitsitseng e netefatsang hore lenaneo ha le sitise ts'ebetso e tloaelehileng ea kernel. Sena, ka tsela, ha se bolele hore lenaneo le ke ke la kena-kenana le ts'ebetso ea tsamaiso - mananeo a BPF, ho itšetlehile ka mofuta, a ka bala le ho ngola likarolo tsa mohopolo oa kernel, ho khutlisa boleng ba mesebetsi, ho fokotsa, ho kenyelletsa, ho ngola hape. esita le ho fetisa lipakete tsa marang-rang. Verifier e tiisa hore ho tsamaisa lenaneo la BPF ho ke ke ha senya kernel le hore lenaneo leo, ho ea ka melao, le nang le phihlello ea ho ngola, mohlala, data ea pakete e tsoang, le ke ke la khona ho hlakola mohopolo oa kernel ka ntle ho pakete. Re tla sheba verifier ka ho qaqileng haholoanyane karolong e lumellanang, ka mor'a hore re tloaelane le likarolo tse ling tsa BPF.

Joale re ithutile eng ho fihlela joale? Mosebelisi o ngola lenaneo ka C, a le kenya ka har'a kernel a sebelisa mohala oa sistimi bpf(2), moo e hlahlojoang ke mohlahlobi ebe e fetoleloa ho bytecode ea matsoalloa. Ebe mosebelisi ea tšoanang kapa e mong o hokahanya lenaneo ho mohloli oa ketsahalo mme e qala ho e phetha. Ho arola boot le ho hokahanya hoa hlokahala ka mabaka a 'maloa. Taba ea pele, ho sebelisa verifier ho batla ho bitsa chelete e ngata 'me ka ho khoasolla lenaneo le le leng ka makhetlo a mangata re senya nako ea k'homphieutha. Taba ea bobeli, hantle hore na lenaneo le amana joang le mofuta oa lona, ​​​​'me sebopeho se le seng sa "universal" se ntlafalitsoeng selemong se fetileng se kanna sa se tšoanelehe bakeng sa mefuta e mecha ea mananeo. (Le hoja hona joale mohaho o ntse o hōla haholoanyane, ho na le mohopolo oa ho kopanya sebopeho sena boemong ba libbpf.)

'Mali ea hlokolosi a ka hlokomela hore ha re e-so qete ka litšoantšo. Ehlile, tsohle tse kaholimo ha li hlalose hore na ke hobaneng ha BPF e fetola setšoantšo ha se bapisoa le BPF ea khale. Litlhahiso tse peli tse eketsang boholo ba ho sebetsa ke bokhoni ba ho sebelisa memori e arolelanoang le mesebetsi ea mothusi oa kernel. Ho BPF, mohopolo o arolelanoang o kengoa ts'ebetsong ho sebelisoa seo ho thoeng ke limmapa - libopeho tsa data tse arolelanoang le API e itseng. Mohlomong ba na le lebitso lena hobane mofuta oa pele oa 'mapa o ileng oa hlaha e ne e le tafole ea hash. Joale ho ile ha hlaha li-arrays, litafole tsa li-hash tsa lehae (per-CPU) le lihlopha tsa lehae, lifate tsa ho batla, limmapa tse nang le lintlha tsa mananeo a BPF le tse ling tse ngata. Se re khahlang hona joale ke hore mananeo a BPF joale a na le bokhoni ba ho phehella boemo lipakeng tsa mehala le ho e arolelana le mananeo a mang le sebaka sa basebelisi.

Limmapa li fumaneha ho tsoa lits'ebetsong tsa basebelisi ho sebelisa mohala oa sistimi bpf(2), le ho tsoa mananeong a BPF a sebetsang ka har'a kernel a sebelisa mesebetsi ea mothusi. Ho feta moo, bathusi ba teng eseng feela ho sebetsa le limmapa, empa hape le ho fihlella bokhoni bo bong ba kernel. Ka mohlala, mananeo a BPF a ka sebelisa mesebetsi ea bathusi ho fetisetsa lipakete ho li-interfaces tse ling, ho hlahisa liketsahalo tsa perf, ho fihlella mehaho ea kernel, joalo-joalo.

BPF bakeng sa bana ba banyenyane, karolo ea pele: BPF e atolositsoeng

Ka bokhuts'oane, BPF e fana ka bokhoni ba ho jarisa ka mokhoa o sa reroang, ke hore, ho lekoa ka netefatso, khoutu ea mosebelisi sebakeng sa kernel. Khoutu ena e ka boloka naha lipakeng tsa mehala le data ea phapanyetsano ka sebaka sa mosebelisi, hape e na le phihlello ea li-subsystem tsa kernel tse lumelletsoeng ke mofuta ona oa lenaneo.

Sena se se se ntse se tšoana le bokhoni bo fanoeng ke li-module tsa kernel, ha li bapisoa le tseo BPF e nang le melemo e itseng (ehlile, o ka bapisa lits'ebetso tse ts'oanang feela, mohlala, ts'ebetso ea sistimi - u ke ke ua ngola mokhanni ea sa tsotelleng le BPF). U ka ela hloko moeli o tlase oa ho kena (lisebelisoa tse ling tse sebelisang BPF ha li hloke hore mosebelisi a be le litsebo tsa ho hlophisa kernel, kapa tsebo ea ho etsa mananeo ka kakaretso), polokeho ea nako ea ho sebetsa (phahamisa letsoho la hau litlhalosong bakeng sa ba sa kang ba senya sistimi ha ba ngola. kapa li-modules tsa ho hlahloba), atomicity - ho na le nako ea ho theola ha ho tsosolosoa li-module, 'me tsamaiso e nyenyane ea BPF e tiisa hore ha ho na liketsahalo tse fetotsoeng (ho bua ka toka, sena ha se nnete bakeng sa mefuta eohle ea mananeo a BPF).

Ho ba teng ha bokhoni bo joalo ho etsa hore BPF e be sesebelisoa sa bokahohleng bakeng sa ho atolosa kernel, e tiisitsoeng ka ts'ebetso: mefuta e mengata e mecha ea mananeo a eketsoa ho BPF, lik'hamphani tse ngata tse kholo li sebelisa BPF ho li-server tsa ntoa 24 × 7, ho feta le ho feta. ba qalang ba theha khoebo ea bona holim'a tharollo e thehiloeng ho BPF. BPF e sebelisoa hohle: ho sireletsa khahlanong le litlhaselo tsa DDoS, ho theha SDN (mohlala, ho kenya ts'ebetsong marang-rang bakeng sa kubernetes), e le sesebelisoa se ka sehloohong sa ho latela mokhoa oa tsamaiso le lipalo-palo, lits'ebetsong tsa ho lemoha ho kenella le mekhoa ea sandbox, joalo-joalo.

Ha re phetheleng karolo ea kakaretso ea sengoloa mona 'me re shebe mochini o sebetsang le tikoloho ea BPF ka botlalo.

Phatoha: lisebelisoa

E le hore u tsebe ho tsamaisa mehlala likarolong tse latelang, u ka 'na ua hloka lisebelisoa tse ngata, bonyane llvm/clang ka tšehetso ea bpf le bpftool. Karolong Lisebelisoa tsa ntlafatso U ka bala litaelo tsa ho bokella lisebelisoa, hammoho le kernel ea hau. Karolo ena e behiloe ka tlaase e le hore e se ke ea sitisa ho lumellana ha nehelano ea rōna.

BPF Virtual Machine Registers le Tsamaiso ea Litaelo

Mehaho le tsamaiso ea litaelo ea BPF e ile ea ntlafatsoa ho nahanoa ka taba ea hore mananeo a tla ngoloa ka puo ea C 'me, ka mor'a ho kenngoa ka har'a kernel, a fetoleloe ka khoutu ea matsoalloa. Ka hona, palo ea li-registas le sete sa litaelo li khethiloe ka leihlo ho ea mateanong a litsela, ka kutloisiso ea lipalo, ea bokhoni ba mechine ea kajeno. Ho phaella moo, lithibelo tse fapa-fapaneng li ne li behiloe mananeong, mohlala, ho fihlela morao tjena ho ne ho sa khonehe ho ngola loops le subroutines, 'me palo ea litaelo e ne e lekanyelitsoe ho 4096 (hona joale mananeo a nang le tokelo a ka kenya litaelo tse ka bang milione).

BPF e na le lirejisetara tse leshome le motso o mong tse fihlellehang ke basebelisi ba 64-bit r0-r10 le khaontara ea lenaneo. Ngodisa r10 e na le sesupo sa foreimi mme e baloa feela. Mananeo a na le phihlello ea 512-byte stack ka nako ea ho sebetsa le palo e sa lekanyetsoang ea memori e arolelanoang ka mokhoa oa limmapa.

Mananeo a BPF a lumelloa ho tsamaisa sehlopha se itseng sa bathusi ba kernel ba mofuta oa lenaneo, 'me haufinyane tjena, mesebetsi e tloaelehileng. E 'ngoe le e' ngoe e bitsoang ts'ebetso e ka nka likhang tse ka bang hlano, tse fetisitsoeng ka lirejistante r1-r5, mme boleng ba ho khutlisa bo fetisetsoa ho r0. Ho netefalitsoe hore ka mor'a ho khutla mosebetsing, litaba tsa li-registas r6-r9 E ke ke ea fetoha.

Bakeng sa phetolelo e sebetsang hantle ea lenaneo, ngoliso r0-r11 bakeng sa meralo eohle e tšehelitsoeng e entsoe 'mapa ka mokhoa o ikhethileng ho ngoliso ea nnete, ho nahanoa ka likarolo tsa ABI tsa meaho ea hajoale. Ka mohlala, bakeng sa x86_64 diresetara r1-r5, e sebelisetsoang ho fetisa liparamente tsa ts'ebetso, li hlahisoa rdi, rsi, rdx, rcx, r8, tse sebelisetsoang ho fetisa liparamente ho sebetsa x86_64. Mohlala, khoutu e ka letsohong le letšehali e fetolela khoutu e ka ho le letona tjena:

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

Ngolisa r0 e boetse e sebelisoa ho khutlisa sephetho sa ts'ebetso ea lenaneo, le ho rejisetara r1 lenaneo le fetisetsoa pointer ho moelelo - ho itšetlehile ka mofuta oa lenaneo, sena se ka ba, mohlala, sebopeho struct xdp_md (bakeng sa XDP) kapa sebopeho struct __sk_buff (bakeng sa mananeo a fapaneng a marang-rang) kapa sebopeho struct pt_regs (bakeng sa mefuta e fapaneng ea mananeo a ho latedisa), jj.

Kahoo, re ne re e-na le li-registerers, bathusi ba kernel, stack, pointer ea moelelo le mohopolo o arolelanoang ka mokhoa oa limmapa. Eseng hore sena sohle se hlokahala leetong, empa ...

Ha re tsoeleng pele ka tlhaloso mme re bue ka tsamaiso ea litaelo bakeng sa ho sebetsa le lintho tsena. Tsohle (Hoo e ka bang kaofela) Litaelo tsa BPF li na le boholo bo tsitsitseng ba 64-bit. Haeba u sheba taelo e le 'ngoe mochining o moholo oa 64-bit o tla bona

BPF bakeng sa bana ba banyenyane, karolo ea pele: BPF e atolositsoeng

ke Code - ena ke encoding ea litaelo, Dst/Src ke li-encodings tsa moamoheli le mohloli, ka ho latellana, Off - 16-bit saennweng indentation, le Imm ke palo e saennoeng ea 32-bit e sebelisoang litaelong tse ling (e ts'oanang le cBPF e sa fetoheng ea K). Khouto Code e na le mefuta e 'meli:

BPF bakeng sa bana ba banyenyane, karolo ea pele: BPF e atolositsoeng

Lihlopha tsa litaelo 0, 1, 2, 3 li hlalosa litaelo tsa ho sebetsa ka mohopolo. Bona li bitsoa, BPF_LD, BPF_LDX, BPF_ST, BPF_STX, ka ho latellana. Sehlopha sa 4, 7 (BPF_ALU, BPF_ALU64) etsa sehlopha sa litaelo tsa ALU. Sehlopha sa 5, 6 (BPF_JMP, BPF_JMP32) li na le litaelo tsa ho tlola.

Morero o tsoelang pele oa ho ithuta tsamaiso ea litaelo tsa BPF ke ka tsela e latelang: ho e-na le ho thathamisa ka hloko litaelo tsohle le litekanyetso tsa tsona, re tla sheba mehlala e 'maloa karolong ena' me ho tsoa ho eona ho tla hlaka hore na litaelo li sebetsa joang le hore na qhaqha ka letsoho faele efe kapa efe ea binary bakeng sa BPF. Ho kopanya litaba hamorao sehloohong sena, re tla boela re kopane le litaelo tsa motho ka mong likarolong tse mabapi le Verifier, JIT compiler, phetolelo ea BPF ea khale, hammoho le ha u ithuta limmapa, mesebetsi ea ho letsetsa, joalo-joalo.

Ha re bua ka litaelo tsa motho ka mong, re tla bua ka lifaele tsa mantlha bpf.h и bpf_common.h, e hlalosang linomoro tsa litaelo tsa BPF. Ha u ithuta ka boqapi ka bouena le/kapa ha u bala li-binaries, u ka fumana li-semantics mehloling e latelang, e hlophisitsoeng ho latela ho rarahana: Litlhaloso tse sa tloaelehang tsa eBPF, BPF le XDP Reference Guide, Setha sa Taelo, Documentation/networking/filter.txt 'me, ehlile, ho khoutu ea mohloli oa Linux - verifier, JIT, mofetoleli oa BPF.

Mohlala: ho qhaqha BPF hloohong ea hau

A re shebeng mohlala oo ho oona re bokellang lenaneo readelf-example.c 'me u shebe sephetho sa binary. Re tla senola litaba tsa mantlha readelf-example.c ka tlase, kamora hore re khutlisetse mohopolo oa eona ho tsoa ho likhoutu tsa 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 ................

Kholomo ea pele ea tlhahiso readelf ke indentation mme lenaneo la rona ka hona le na le litaelo tse 'ne:

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

Likhoutu tsa taelo lia lekana b7, 15, b7 и 95. Hopola hore likaroloana tse tharo tsa bohlokoa ke sehlopha sa litaelo. Tabeng ea rona, karolo ea bone ea litaelo tsohle ha e na letho, kahoo lihlopha tsa litaelo ke 7, 5, 7, 5, ka ho latellana. BPF_ALU64,mme 5 ke BPF_JMP. Bakeng sa lihlopha tsena ka bobeli, mokhoa oa litaelo o tšoana (sheba ka holimo) 'me re ka ngola lenaneo la rona ka tsela ena (ka nako e ts'oanang re tla ngola litšiea tse setseng ka sebōpeho sa motho):

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

Ts'ebetso b класса ALU64 - sena ke BPF_MOV. E fana ka boleng ho rejisetara ea sebaka seo u eang ho sona. Haeba hanyane e behiloe s (mohloli), joale boleng bo nkiloe bukeng ea mohloli, 'me haeba, joaloka tabeng ea rona, e sa behoa, joale boleng bo nkiloe tšimong. Imm. Kahoo ka litaelo tsa pele le tsa boraro re etsa opereishene r0 = Imm. Ho feta moo, ts'ebetso ea sehlopha sa 1 sa JMP e BPF_JEQ (tlola haeba ho lekana). Tabeng ea rona, ho tloha hanyenyane S ke zero, e bapisa boleng ba ngoliso ea mohloli le tšimo Imm. Haeba litekanyetso li lumellana, joale phetoho e etsahala ho PC + Offkae PC, joalo ka tloaelo, e na le aterese ea taelo e latelang. Qetellong, Ts'ebetso ea JMP Class 9 e BPF_EXIT. Taelo ena e emisa lenaneo, e khutlela ho kernel r0. Ha re kenye kholomo e ncha tafoleng ea rona:

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

Re ka ngola sena hape ka mokhoa o bonolo haholoanyane:

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

Haeba re hopola hore na ho ngolisoeng r1 lenaneo le fetisetsoa pointer ho moelelo ho tloha kernel, le ho ngolisa r0 boleng bo khutlisetsoa ho kernel, joale re ka bona hore haeba pointer ea moelelo oa taba e le zero, joale re khutlisetsa 1, 'me ho seng joalo - 2. A re hlahlobeng hore na re nepahetse ka ho sheba mohloli:

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

E, ke lenaneo le se nang moelelo, empa le fetolela ka litaelo tse bonolo tse 'nè feela.

Mohlala o ikhethang: litaelo tsa 16-byte

Re boletse pejana hore litaelo tse ling li nka li-bits tse fetang 64. Sena se sebetsa, ho etsa mohlala, ho litaelo lddw (Khoutu = 0x18 = BPF_LD | BPF_DW | BPF_IMM) - kenya mantsoe a mabeli ho tloha masimong ho ea rejiseteng Imm. 'Nete ke hore Imm e na le boholo ba 32, 'me lentsoe le habeli ke li-bits tse 64, kahoo ho kenya boleng ba 64-bit hang-hang ka har'a rejisetara ka taelo e le' ngoe ea 64-bit ho ke ke ha sebetsa. Ho etsa sena, litaelo tse peli tse haufi li sebelisoa ho boloka karolo ea bobeli ea boleng ba 64-bit tšimong. Imm. Mohlala:

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

Ho na le litaelo tse peli feela lenaneong la binary:

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

Re tla kopana hape ka litaelo lddw, ha re bua ka phalliso le ho sebetsa ka limmapa.

Mohlala: ho qhaqha BPF ho sebelisa lisebelisoa tse tloaelehileng

Kahoo, re ithutile ho bala likhoutu tsa binary tsa BPF mme re ikemiselitse ho fetisa taelo efe kapa efe ha ho hlokahala. Leha ho le joalo, ho bohlokoa ho bolela hore ts'ebetsong ho bonolo ebile ho potlakile ho arola mananeo ka lisebelisoa tse tloaelehileng, mohlala:

$ 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 ea lintho tsa BPF, bpffs file system

(Ke ithutile pele tse ling tsa lintlha tse hlalositsoeng karolongana ena ho tsoa ho poso Alexei Starovoitov ka boeena BPF Blog.)

Lintho tsa BPF - mananeo le limmapa - li entsoe ho tsoa sebakeng sa basebelisi ho sebelisoa litaelo BPF_PROG_LOAD и BPF_MAP_CREATE pitso ea tsamaiso bpf(2), re tla bua hantle hore na sena se etsahala joang karolong e latelang. Sena se theha meaho ea data ea kernel le bakeng sa e 'ngoe le e' ngoe ea tsona refcount (reference count) e behiloe ho e le 'ngoe, 'me tlhaloso ea faele e supang ntho e khutlisetsoa ho mosebedisi. Ka mor'a hore leqheka le koetsoe refcount ntho e fokotsoa ke e le 'ngoe, 'me ha e fihla ho zero, ntho e senyeha.

Haeba lenaneo le sebelisa limmapa, joale refcount limmapa tsena li eketsoa ka e 'ngoe ka mor'a ho kenya lenaneo, ke hore. litlhaloso tsa bona tsa faele li ka koaloa ts'ebetsong ea mosebelisi mme li ntse li le teng refcount e ke ke ea fetoha zero:

BPF bakeng sa bana ba banyenyane, karolo ea pele: BPF e atolositsoeng

Kamora ho kenya lenaneo ka katleho, hangata re le hokahanya le mofuta o itseng oa jenereithara ea ketsahalo. Ka mohlala, re ka e beha holim'a marang-rang a marang-rang ho sebetsana le lipakete tse kenang kapa ho li hokahanya le tse ling tracepoint bohareng. Nakong ena, counter counter e tla boela e eketsehe ka e le 'ngoe' me re tla khona ho koala tlhaloso ea faele lenaneong la loader.

Ho etsahala'ng haeba joale re koala bootloader? E itšetlehile ka mofuta oa jenereithara ea ketsahalo (hook). Li-hook tsohle tsa marang-rang li tla ba teng ka mor'a hore mochine oa thepa o phethe, tsena ke tse bitsoang li-hook tsa lefats'e. 'Me, ka mohlala, mananeo a trace a tla lokolloa ka mor'a hore ts'ebetso e ba entseng e khaotse ('me ka hona e bitsoa sebakeng sa heno, ho tloha "sebakeng ho ea ho ts'ebetso"). Ha e le hantle, li-hook tsa lehae li lula li na le tlhaloso ea faele e tsamaellanang sebakeng sa mosebelisi mme ka hona e koala ha ts'ebetso e koetsoe, empa lihoko tsa lefats'e ha li joalo. Setšoantšong se latelang, ke sebelisa lifapano tse khubelu, ke leka ho bontša hore na ho felisoa ha lenaneo la loader ho ama bophelo bohle ba lintho joang tabeng ea li-hook tsa lehae le tsa lefats'e.

BPF bakeng sa bana ba banyenyane, karolo ea pele: BPF e atolositsoeng

Ke hobane'ng ha ho na le phapang pakeng tsa hook ea lehae le ea lefatše lohle? Ho matha mefuta e meng ea mananeo a marang-rang hoa utloahala ntle le sebaka sa mosebedisi, mohlala, nahana ka ts'ireletso ea DDoS - bootloader e ngola melao mme e kopanya lenaneo la BPF ho sebopeho sa marang-rang, ka mor'a moo bootloader e ka ea le ho ipolaea. Ka lehlakoreng le leng, ak'u inahanele ka lenaneo la ho lokisa liphoso leo u le ngotseng ka mangole ka metsotso e leshome - ha le qetile, u ka rata hore ho se ke ha e-ba le litšila tse setseng tsamaisong, 'me li-hook tsa sebakeng seo li tla netefatsa seo.

Ka lehlakoreng le leng, nahana hore u batla ho hokela ho tracepoint kernel le ho bokella lipalo-palo ka lilemo tse ngata. Tabeng ena, o tla batla ho tlatsa karolo ea mosebedisi le ho khutlela ho lipalo-palo nako le nako. Sistimi ea faele ea bpf e fana ka monyetla ona. Ke sistimi ea pseudo-file ea mohopolong feela e lumellang hore ho thehoe lifaele tse buang ka lintho tsa BPF mme ka hona li eketsehe. refcount dintho. Ka mor'a sena, loader e ka tsoa, ​​'me lintho tseo e li entseng li tla lula li phela.

BPF bakeng sa bana ba banyenyane, karolo ea pele: BPF e atolositsoeng

Ho theha lifaele ka bpffs tse supang lintho tsa BPF ho bitsoa "pinning" (joalo ka poleloaneng e latelang: "mosebetsi o ka penya lenaneo kapa 'mapa oa BPF"). Ho theha lintho tsa faele bakeng sa lintho tsa BPF hoa utloahala eseng feela bakeng sa ho lelefatsa bophelo ba lintho tsa lehae, empa hape le bakeng sa ts'ebeliso ea lintho tsa lefats'e - ho khutlela mohlala ka lenaneo la ts'ireletso la lefats'e la DDoS, re batla ho khona ho tla ho sheba lipalo-palo. nako le nako.

Sistimi ea faele ea BPF hangata e kentsoe kahare /sys/fs/bpf, empa e ka beoa sebakeng sa heno, mohlala, tjena:

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

Mabitso a sistimi ea faele a entsoe ho sebelisoa taelo BPF_OBJ_PIN Pitso ea tsamaiso ea BPF. Ho etsa mohlala, ha re nkeng lenaneo, re le bokelle, re le kenye, 'me re le penya bpffs. Lenaneo la rona ha le thuse letho, re hlahisa khoutu feela hore o tsebe ho hlahisa mohlala:

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

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

Ha re bokelleng lenaneo lena mme re thehe kopi ea lehae ea sistimi ea faele bpffs:

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

Joale ha re khoasolle lenaneo la rona re sebelisa sesebelisoa bpftool 'me u shebelle mehala ea sistimi e tsamaeang le eona bpf(2) (mehala e meng e sa sebetseng e tlositsoe ho 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

Mona re kentse lenaneo re sebelisa BPF_PROG_LOAD, e fumane tlhaloso ea faele ho tsoa kernel 3 le ho sebedisa taelo BPF_OBJ_PIN e kentse tlhaloso ea faele ena e le faele "bpf-mountpoint/test". Ka mor'a moo, kenya lenaneo la bootloader bpftool e qetile ho sebetsa, empa lenaneo la rona le ile la lula le le kernel, leha re sa ka ra le hokahanya le sebopeho sa marang-rang:

$ 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

Re ka hlakola ntho ea faele ka tloaelo unlink(2) 'me ka mor'a moo lenaneo le lumellanang le tla hlakoloa:

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

Ho hlakolwa ha dintho

Ha re bua ka ho hlakola lintho, hoa hlokahala ho hlakisa hore ka mor'a hore re khaotse lenaneo ho tloha hook (jenereithara ea ketsahalo), ha ho ketsahalo e le 'ngoe e ncha e tla qala ho qalisoa, leha ho le joalo, liketsahalo tsohle tsa hona joale tsa lenaneo li tla phethoa ka tatellano e tloaelehileng. .

Mefuta e meng ea mananeo a BPF e u lumella ho nkela lenaneo sebaka ka fofa, ke hore. fana ka tatellano ea atomicity replace = detach old program, attach new program. Tabeng ena, liketsahalo tsohle tse sebetsang tsa mofuta oa khale oa lenaneo li tla qeta mosebetsi oa tsona, 'me batšoantšisi ba bacha ba tla bōptjoa ho tsoa lenaneong le lecha,' me "atomicity" mona e bolela hore ha ho ketsahalo e le 'ngoe e tla hloloheloa.

Ho hokela mananeo ho mehloli ea liketsahalo

Sehloohong sena, re ke ke ra hlalosa ka thoko ho hokahanya mananeo le mehloli ea liketsahalo, kaha hoa utloahala ho ithuta sena ho latela mofuta o itseng oa lenaneo. Cm. mohlala ka tlase, moo re bonts'ang hore na mananeo a kang XDP a hokahane joang.

Ho laola lintho ka ho sebelisa bpf System Call

Mananeo a BPF

Lintho tsohle tsa BPF li entsoe ebile li laoloa ho tsoa sebakeng sa mosebelisi ho sebelisoa mohala oa sistimi bpf, e nang le mohlala o latelang:

#include <linux/bpf.h>

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

Sehlopha ke sena cmd ke e 'ngoe ea litekanyetso tsa mofuta enum bpf_cmd, attr - sesupo sa liparamente bakeng sa lenaneo le itseng le size - boholo ba ntho ho latela pointer, i.e. hangata sena sizeof(*attr). Ho kernel 5.8 mohala oa sistimi bpf e tšehetsa 34 litaelo tse fapaneng, le moelelo union bpf_attr e nka mela e 200. Empa ha rea ​​​​lokela ho tšosoa ke sena, kaha re tla tloaelana le litaelo le liparamente nakong ea lingoliloeng tse 'maloa.

Ha re qale ka sehlopha BPF_PROG_LOAD, e hlahisang mananeo a BPF - e nka sete ea litaelo tsa BPF ebe e e kenya ka har'a kernel. Ka nako ea ho kenya, ho qalisoa mohlahlobi, 'me joale moqapi oa JIT 'me, ka mor'a ho sebetsa ka katleho, tlhaloso ea faele ea lenaneo e khutlisetsoa ho mosebedisi. Re bone se mo etsahallang se latelang karolong e fetileng mabapi le potoloho ea bophelo ea lintho tsa BPF.

Hona joale re tla ngola lenaneo la tloaelo le tla laela lenaneo le bonolo la BPF, empa pele re lokela ho etsa qeto ea hore na re batla ho kenya lenaneo la mofuta ofe - re tla tlameha ho khetha. mofuta 'me ka har'a moralo oa mofuta ona, ngola lenaneo le tla feta tlhahlobo ea verifier. Leha ho le joalo, e le hore u se ke ua thatafatsa mokhoa ona, mona ke tharollo e lokiselitsoeng: re tla nka lenaneo le kang BPF_PROG_TYPE_XDP, e tla khutlisa boleng XDP_PASS (tlola liphutheloana tsohle). Ho BPF assembler e shebahala e le bonolo haholo:

r0 = 2
exit

Ka mor'a hore re etse qeto hore re tla kenya, re ka u bolella hore na re tla e etsa joang:

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

Liketsahalo tse khahlisang lenaneong li qala ka tlhaloso ea lethathamo insns - Lenaneo la rona la BPF ka khoutu ea mochini. Tabeng ena, taelo e 'ngoe le e' ngoe ea lenaneo la BPF e kenngoa mohahong bpf_insn. Ntho ea pele insns e dumellana le ditaelo r0 = 2, ea bobeli - exit.

Khutla. Kernel e hlalosa li-macros tse bonolo haholoanyane bakeng sa ho ngola likhoutu tsa mochini, le ho sebelisa faele ea hlooho ea kernel tools/include/linux/filter.h re ne re ka ngola

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

Empa kaha ho ngola mananeo a BPF ka khoutu ea matsoalloa ho hlokahala feela bakeng sa ho ngola liteko ka kernel le lingoliloeng tse mabapi le BPF, ho ba sieo ha li-macros tsena ha ho hlile ha ho thatafatse bophelo ba moqapi.

Ka mor'a ho hlalosa lenaneo la BPF, re fetela pele ho e kenya ka har'a kernel. Li-parameter tsa rona tsa minimalist attr e kenyelletsa mofuta oa lenaneo, sete le palo ea litaelo, laesense e hlokahalang, le lebitso "woo", eo re e sebelisang ho fumana lenaneo la rona ho sistimi ka mor'a ho e jarolla. Lenaneo, joalo ka ha le ts'episitsoe, le kenngoa ka har'a sistimi ho sebelisoa mohala oa sistimi bpf.

Qetellong ea lenaneo re qetella re le mocheng o sa feleng o etsisang mojaro oa moputso. Ntle le eona, lenaneo le tla bolaoa ke kernel ha tlhaloso ea faele eo mohala oa tsamaiso e khutliselitsoeng ho rona e koetsoe. bpf, 'me re ke ke ra e bona tsamaisong.

Ho lokile, re se re loketse tlhahlobo. A re bokelleng 'me re tsamaise lenaneo tlas'a straceho etsa bonnete ba hore tsohle li sebetsa ka tsela e nepahetseng:

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

Tsohle di lokile, bpf(2) e khutlisitse handle 3 ho rona mme ra kena ka har'a loop e sa feleng le pause(). Ha re leke ho fumana lenaneo la rona tsamaisong. Ho etsa sena re tla ea ho terminal e 'ngoe ebe re sebelisa sesebelisoa 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)

Rea bona hore ho na le lenaneo le laetsoeng tsamaisong woo eo ID ea hae ea lefats 390 e ntseng e tsoela pele simple-prog ho na le tlhaloso ea faele e bulehileng e supang lenaneo (le haeba simple-prog o tla qeta mosebetsi, he woo tla nyamela). Joalokaha ho lebeletsoe, lenaneo woo e nka li-byte tse 16 - litaelo tse peli - tsa likhoutu tsa binary mohahong oa BPF, empa ka mokhoa oa eona oa tlhaho (x86_64) e se e le li-byte tse 40. Ha re shebeng lenaneo la rona ka sebopeho sa lona sa mantlha:

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

ha ho tse makatsang. Joale ha re shebeng khoutu e hlahisitsoeng ke moqapi oa JIT:

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

ha e sebetse haholo bakeng sa exit(2), empa ka toka, lenaneo la rona le bonolo haholo, 'me bakeng sa mananeo a sa reng letho selelekela le epilogue e kenyellelitsoeng ke motlalehi oa JIT, ehlile, lia hlokahala.

Limmapa

Mananeo a BPF a ka sebelisa libaka tsa memori tse hlophisitsoeng tse fumanehang ho mananeo a mang a BPF le mananeong a sebakeng sa basebelisi. Lintho tsena li bitsoa limmapa mme karolong ena re tla bonts'a mokhoa oa ho li qhekella ka mohala oa sistimi bpf.

Ha re re hang-hang hore bokhoni ba limmapa ha bo felle feela ho fihlella mohopolong o arolelanoeng. Ho na le limmapa tse nang le sepheo se ikhethileng tse nang le, mohlala, lisupa ho mananeo a BPF kapa lisupa ho likhokahano tsa marang-rang, limmapa tsa ho sebetsa ka liketsahalo tsa perf, jj. Ha re na ho bua ka tsona mona, e le hore re se ke ra ferekanya 'mali. Ntle le sena, re iphapanyetsa litaba tsa khokahano, kaha sena ha se bohlokoa ho mehlala ea rona. Lethathamo le felletseng la mefuta e fumanehang ea limmapa le ka fumanoa ho <linux/bpf.h>, 'me karolong ena re tla nka e le mohlala mofuta oa pele oa histori, tafole ea hash BPF_MAP_TYPE_HASH.

Haeba u theha tafole ea hash, e re, C ++, u ka re unordered_map<int,long> woo, eo ka Serussia e bolelang “Ke hloka tafole woo boholo bo se nang moeli, eo linotlolo tsa eona e leng tsa mofuta int, mme boleng ke mofuta long" Bakeng sa ho theha tafole ea BPF hash, re hloka ho etsa ntho e ts'oanang, ntle le hore re tlameha ho hlalosa boholo ba tafole, mme sebakeng sa ho hlalosa mefuta ea linotlolo le boleng, re hloka ho hlakisa boholo ba tsona ka li-byte. . Ho etsa limmapa sebelisa taelo BPF_MAP_CREATE pitso ea tsamaiso bpf. Ha re shebeng lenaneo le fokolang haholo le etsang 'mapa. Kamora lenaneo le fetileng le laelang mananeo a BPF, ena e lokela ho bonahala e le bonolo ho uena:

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

Mona re hlalosa sehlopha sa li-parameter attr, moo re reng "Ke hloka tafole ea hash e nang le linotlolo le litekanyetso tsa boholo sizeof(int), eo ho eona nka behang boholo ba likarolo tse 'nè." Ha u theha limmapa tsa BPF, u ka hlakisa liparamente tse ling, mohlala, ka tsela e ts'oanang le mohlala oa lenaneo, re boletse lebitso la ntho e le "woo".

Ha re hlophise le ho tsamaisa lenaneo:

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

Mohala oa sistimi ke ona bpf(2) re khutlisitse nomoro ea 'mapa e hlalosang 3 ebe lenaneo, joalo ka ha ho lebeletsoe, le emela litaelo tse ling ho mohala oa sistimi pause(2).

Joale ha re romelleng lenaneo la rona ka morao kapa re bule terminal e 'ngoe ebe re sheba ntho ea rona re sebelisa ts'ebeliso bpftool (re ka khetholla 'mapa oa rona ho ba bang ka mabitso a ona):

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

Nomoro ea 114 ke ID ea lefats'e ea ntho ea rona. Lenaneo lefe kapa lefe la sistimi le ka sebelisa ID ena ho bula 'mapa o teng o sebelisa taelo BPF_MAP_GET_FD_BY_ID pitso ea tsamaiso bpf.

Hona joale re ka bapala ka tafole ea rona ea hash. Ha re shebeng litaba tsa eona:

$ sudo bpftool map dump id 114
Found 0 elements

Ha ho letho. A re ke re behe boleng ho eona hash[1] = 1:

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

Ha re shebeng tafole hape:

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

Hooray! Re khonne ho kenya elemente e le 'ngoe. Hlokomela hore re tlameha ho sebetsa maemong a byte ho etsa sena, kaha bptftool ha e tsebe hore na boleng ba tafole ea hash ke ba mofuta ofe. (Tsebo ena e ka fetisetsoa ho eena ka ho sebelisa BTF, empa ho feta moo hona joale.)

Hantle-ntle bpftool e bala le ho eketsa lintlha joang? A re shebeng tlas'a 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

Pele re ile ra bula 'mapa ka ID ea eona ea lefats'e re sebelisa taelo BPF_MAP_GET_FD_BY_ID и bpf(2) e khutlisitse tlhaloso ea 3 ho rona BPF_MAP_GET_NEXT_KEY re fumane senotlolo sa pele tafoleng ka ho feta NULL joalo ka sesupo sa konopo "e fetileng". Haeba re na le senotlolo re ka se etsa BPF_MAP_LOOKUP_ELEMe khutlisetsang boleng ho sesupa value. Mohato o latelang ke hore re leka ho fumana ntho e latelang ka ho fetisa pointer ho senotlolo sa hona joale, empa tafole ea rona e na le ntho e le 'ngoe feela le taelo. BPF_MAP_GET_NEXT_KEY kgutlisetso ENOENT.

Ho lokile, ha re fetoleng boleng ka senotlolo sa 1, ha re re mohopolo oa rona oa khoebo o hloka ho ingolisa 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

Joalokaha ho lebelletsoe, ho bonolo haholo: taelo BPF_MAP_GET_FD_BY_ID e bula 'mapa oa rona ka ID, le taelo BPF_MAP_UPDATE_ELEM e fetisa ntlha.

Kahoo, ka mor'a ho theha tafole ea hash ho tsoa lenaneong le le leng, re ka bala le ho ngola litaba tsa eona ho tsoa ho e 'ngoe. Hlokomela hore haeba re khonne ho etsa sena ho tsoa molaong oa taelo, joale lenaneo leha e le lefe le leng tsamaisong le ka le etsa. Ntle le litaelo tse hlalositsoeng ka holimo, bakeng sa ho sebetsa le limmapa tse tsoang sebakeng sa basebelisi, e latelang:

  • BPF_MAP_LOOKUP_ELEM: fumana boleng ka senotlolo
  • BPF_MAP_UPDATE_ELEM: update/etsa boleng
  • BPF_MAP_DELETE_ELEM: tlosa senotlolo
  • BPF_MAP_GET_NEXT_KEY: fumana senotlolo se latelang (kapa sa pele).
  • BPF_MAP_GET_NEXT_ID: e u lumella ho tsamaea ka limmapa tsohle tse teng, ke kamoo e sebetsang kateng bpftool map
  • BPF_MAP_GET_FD_BY_ID: bula 'mapa o teng ka ID ea ona ea lefats'e
  • BPF_MAP_LOOKUP_AND_DELETE_ELEM: ntlafatsa boleng ba ntho ka liathomo ebe u khutlisetsa ea khale
  • BPF_MAP_FREEZE: etsa hore 'mapa o se ke oa fetoha ho tsoa sebakeng sa basebelisi (ts'ebetso ena e ke ke ea etsolloa)
  • BPF_MAP_LOOKUP_BATCH, BPF_MAP_LOOKUP_AND_DELETE_BATCH, BPF_MAP_UPDATE_BATCH, BPF_MAP_DELETE_BATCH: ts'ebetso ea bongata. Ka mohlala, BPF_MAP_LOOKUP_AND_DELETE_BATCH - Ena ke eona feela tsela e tšepahalang ea ho bala le ho seta bocha boleng ba 'mapa

Ha se litaelo tsena kaofela tse sebetsang bakeng sa mefuta eohle ea limmapa, empa ka kakaretso ho sebetsa le mefuta e meng ea limmapa ho tsoa sebakeng sa basebelisi ho shebahala ho tšoana hantle le ho sebetsa ka litafole tsa hash.

Molemong oa taolo, ha re phetheng liteko tsa rona tsa tafole ea hash. Hopola hore re thehile tafole e ka ba le linotlolo tse ka bang nne? Ha re kenye lintlha tse ling tse 'maloa:

$ 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

Ke khotsofetse ho fihlela hajoale:

$ 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

Ha re leke ho eketsa e 'ngoe hape:

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

Joalokaha ho ne ho lebelletsoe, ha rea ​​atleha. Ha re shebeng phoso ka botlalo:

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

Tsohle li lokile: joalo ka ha ho lebelletsoe, sehlopha BPF_MAP_UPDATE_ELEM e leka ho theha senotlolo se secha, sa bohlano, empa ea senyeha E2BIG.

Kahoo, re ka theha le ho kenya mananeo a BPF, hammoho le ho theha le ho laola limmapa ho tsoa sebakeng sa basebelisi. Joale hoa utloahala ho sheba hore na re ka sebelisa limmapa tse tsoang mananeong a BPF joang ka botsona. Re ka bua ka sena ka puo ea mananeo a thata ho bala ka har'a likhoutu tse kholo tsa mochini, empa ha e le hantle nako e fihlile ea ho bonts'a hore na mananeo a BPF a hlile a ngoloa le ho hlokomeloa joang - a sebelisa. libbpf.

(Bakeng sa babali ba sa khotsofalang ke khaello ea mohlala oa boemo bo tlase: re tla sekaseka ka botlalo mananeo a sebelisang limmapa le mesebetsi ea bathusi e entsoeng ho sebelisoa. libbpf mme ke o bolelle se etsahalang maemong a thuto. Bakeng sa babali ba sa khotsofalang haholo, re ekelitse mohlala sebakeng se loketseng sengolong.)

Ho ngola mananeo a BPF ho sebelisa libbpf

Ho ngola mananeo a BPF ho sebelisa likhoutu tsa mochini ho ka khahla khetlo la pele feela, ebe ho khora ho kena. Ka nako ena o hloka ho lebisa tlhokomelo ea hau ho llvm, e nang le mokokotlo oa ho hlahisa khoutu bakeng sa meralo ea BPF, hammoho le laeborari libbpf, e u lumellang hore u ngole lehlakore la mosebelisi oa lits'ebetso tsa BPF le ho kenya khoutu ea mananeo a BPF a hlahisoang a sebelisoa llvm/clang.

Ha e le hantle, joalokaha re tla bona sehloohong sena le se latelang, libbpf e etsa mosebetsi o mongata ntle le eona (kapa lisebelisoa tse tšoanang - iproute2, libbcc, libbpf-go, joalo-joalo) ha ho khonehe ho phela. E 'ngoe ea likarolo tse bolaeang tsa morero libbpf ke BPF CO-RE (Compile Once, Run Everywhere) - morero o u lumellang hore u ngole mananeo a BPF a nkehang habonolo ho tloha kernel e 'ngoe ho ea ho e' ngoe, ka bokhoni ba ho sebetsa ho li-API tse fapaneng (mohlala, ha sebopeho sa kernel se fetoha ho fetolela). E le hore u tsebe ho sebetsa le CO-RE, kernel ea hau e tlameha ho bokelloa ka tšehetso ea BTF (re hlalosa mokhoa oa ho etsa sena karolong Lisebelisoa tsa ntlafatso. U ka hlahloba hore na kernel ea hau e hahiloe ka BTF kapa che - ka boteng ba faele e latelang:

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

Faele ena e boloka tlhahisoleseling mabapi le mefuta eohle ea data e sebelisoang kernel mme e sebelisoa mehlaleng eohle ea rona e sebelisoa libbpf. Re tla bua ka ho qaqileng ka CO-RE sehloohong se latelang, empa ho sena - iketsetse kernel ka CONFIG_DEBUG_INFO_BTF.

laebrari libbpf e phela ka har'a bukana tools/lib/bpf kernel le nts'etsopele ea eona e etsoa ka lethathamo la mangolo [email protected]. Leha ho le joalo, polokelo e arohaneng e bolokiloe bakeng sa litlhoko tsa lits'ebetso tse lulang kantle ho kernel https://github.com/libbpf/libbpf eo ho eona laeborari ea kernel e bonts'itsoeng bakeng sa phihlello ea ho bala haholoanyane kapa ka tlase kamoo ho leng ka teng.

Karolong ena re tla sheba kamoo u ka thehang morero o sebelisang libbpf, a re ngoleng mananeo a mangata a teko (ho feta kapa a se nang moelelo) 'me re hlahlobe ka ho qaqileng hore na kaofela ha ona o sebetsa joang. Sena se tla re fa monyetla oa ho hlalosa habonolo likarolong tse latelang hore na mananeo a BPF a sebelisana joang le limmapa, bathusi ba kernel, BTF, joalo-joalo.

Hangata, merero e sebelisoang libbpf eketsa polokelo ea GitHub joalo ka git submodule, re tla etsa se tšoanang:

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

Ho ea ho libbpf e bonolo haholo:

$ 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

Morero oa rona o latelang karolong ena ke o latelang: re tla ngola lenaneo la BPF joalo ka BPF_PROG_TYPE_XDP, ho tšoana le mohlaleng o fetileng, empa ho C, re e bokella ka ho sebelisa clang, 'me u ngole lenaneo la mothusi le tla le kenya ka har'a kernel. Likarolong tse latelang re tla holisa bokhoni ba lenaneo la BPF le lenaneo la mothusi.

Mohlala: ho theha sesebelisoa se felletseng ka ho sebelisa libbpf

Ho qala, re sebelisa file /sys/kernel/btf/vmlinux, e boletsoeng ka holimo, 'me u thehe e lekanang le eona ka mokhoa oa faele ea hlooho:

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

Faele ena e tla boloka libopeho tsohle tsa data tse fumanehang kernel ea rona, mohlala, ke kamoo sehlooho sa IPv4 se hlalosoang kateng 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;
};

Joale re tla ngola lenaneo la rona la BPF ho 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";

Le hoja lenaneo la rōna le ile la bonahala le le bonolo haholo, re ntse re lokela ho ela hloko lintlha tse ngata. Taba ea pele, faele ea hlooho ea pele eo re e kenyelletsang ke vmlinux.h, eo re sa tsoa e hlahisa re e sebelisa bpftool btf dump - joale ha ho hlokahale hore re kenye sephutheloana sa lihlooho tsa kernel ho fumana hore na meaho ea kernel e shebahala joang. Faele e latelang e ka sehloohong e tla ho rona ho tsoa laebraring libbpf. Hona joale re e hloka feela ho hlalosa macro SEC, e romelang sebopeho ho karolo e loketseng ea faele ea ntho ea ELF. Lenaneo la rona le teng karolong eo xdp/simple, moo pele ho slash re hlalosa mofuta oa lenaneo la BPF - ena ke kopano e sebelisoang ho libbpf, e ipapisitse le lebitso la karolo e tla nkela mofuta o nepahetseng ha o qala bpf(2). Lenaneo la BPF ka bolona le C - e bonolo haholo mme e na le mola o le mong return XDP_PASS. Qetellong, karolo e arohaneng "license" e na le lebitso la laesense.

Re ka bokella lenaneo la rona re sebelisa llvm/clang, version>= 10.0.0, kapa ho feta leha ho le joalo, e kholoanyane (sheba karolo Lisebelisoa tsa ntlafatso):

$ 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

Har'a likarolo tse khahlisang: re bonts'a meaho e reriloeng -target bpf le tsela ya dihlogo libbpf, eo re sa tsoa e kenya. Hape, u se ke ua lebala ka -O2, ntle le khetho ena u ka ba le lintho tse makatsang nakong e tlang. Ha re shebe khoutu ea rona, na re khonne ho ngola lenaneo leo re neng re le batla?

$ 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

E, e ile ea sebetsa! Hona joale, re na le faele ea binary e nang le lenaneo, 'me re batla ho etsa kopo e tla e kenya ka har'a kernel. Bakeng sa morero ona laebrari libbpf e re fa likhetho tse peli - sebelisa API ea boemo bo tlase kapa API ea boemo bo holimo. Re tla tsamaea ka tsela ea bobeli, kaha re batla ho ithuta ho ngola, ho kenya le ho hokahanya mananeo a BPF ka boiteko bo fokolang bakeng sa thuto ea bona e latelang.

Taba ea pele, re hloka ho hlahisa "skeleton" ea lenaneo la rona ho tsoa ho binary ea eona re sebelisa sesebelisoa se tšoanang bpftool - thipa ea Switzerland ea lefats'e la BPF (e ka nkoang e le ea sebele, kaha Daniel Borkman, e mong oa baqapi le bahlokomeli ba BPF, ke Switzerland):

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

Ka faele xdp-simple.skel.h e na le khoutu ea binary ea lenaneo la rona le mesebetsi ea ho laola - ho kenya, ho kenya, ho tlosa ntho ea rona. Tabeng ea rona e bonolo sena se shebahala joaloka overkill, empa e boetse e sebetsa tabeng eo faele ea ntho e nang le mananeo a mangata a BPF le limmapa le ho kenya ELF ena e kholo re hloka feela ho hlahisa skeleton le ho letsetsa ts'ebetso e le 'ngoe kapa tse peli ho tloha ts'ebetsong eo re e tloaetseng. lia ngola Ha re tsoeleng pele joale.

Ha e le hantle, lenaneo la rona la loader ha le na letho:

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

ke struct xdp_simple_bpf e hlalosoang faeleng xdp-simple.skel.h mme e hlalosa faele ea rona ea ntho:

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

Re ka bona mesaletsa ea API ea boemo bo tlase mona: sebopeho struct bpf_program *simple и struct bpf_link *simple. Sebopeho sa pele se hlalosa ka ho khetheha lenaneo la rona, le ngotsoeng karolong xdp/simple, 'me ea bobeli e hlalosa hore na lenaneo le amana joang le mohloli oa ketsahalo.

Mosebetsi xdp_simple_bpf__open_and_load, e bula ntho ea ELF, ea e arola, e theha mehaho eohle le likaroloana (ntle le lenaneo, ELF e boetse e na le likarolo tse ling - data, data ea ho bala feela, tlhahisoleseding ea debugging, laesense, joalo-joalo), ebe e e kenya ka har'a kernel e sebelisa tsamaiso. letsa bpf, eo re ka e hlahlobang ka ho hlophisa le ho tsamaisa lenaneo:

$ 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

Ha re shebeng lenaneo la rona re sebelisa bpftool. Ha re fumane ID ea hae:

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

le ho lahla (re sebelisa mokhoa o khutsufalitsoeng oa taelo bpftool prog dump xlated):

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

Ntho e ncha! Lenaneo le hatisitse likarolo tsa faele ea rona ea mohloli oa C. Sena se entsoe ke laeborari libbpf, e fumaneng karolo ea debug ho binary, ea e kopanya ho ba ntho ea BTF, ea e kenya ka har'a kernel e sebelisa BPF_BTF_LOAD, ebe o hlalosa tlhaloso ea faele e hlahisoang ha o kenya lenaneo ka taelo BPG_PROG_LOAD.

Bathusi ba Kernel

Mananeo a BPF a ka tsamaisa mesebetsi ea "ka ntle" - bathusi ba kernel. Mesebetsi ena ea bathusi e lumella mananeo a BPF ho fihlella meaho ea kernel, ho laola limmapa, le ho buisana le "lefats'e la sebele" - ho theha liketsahalo tsa perf, ho laola hardware (mohlala, ho tsamaisa lipakete), joalo-joalo.

Mohlala: bpf_get_smp_processor_id

Ka har'a moralo oa paradigm ea "ho ithuta ka mohlala", ha re nahaneng ka e 'ngoe ea mesebetsi ea mothusi, bpf_get_smp_processor_id(), tse itseng ka faele kernel/bpf/helpers.c. E khutlisa palo ea processor eo lenaneo la BPF le le bitsitseng le sebetsang ho eona. Empa ha re thahaselle semantics ea eona joalo ka taba ea hore ts'ebetsong ea eona e nka mola o le mong:

BPF_CALL_0(bpf_get_smp_processor_id)
{
    return smp_processor_id();
}

Litlhaloso tsa tšebetso ea mothusi oa BPF li tšoana le litlhaloso tsa mohala oa sistimi ea Linux. Mona, mohlala, mosebetsi o hlalosoa o se nang likhang. (Mosebetsi o nkang, o re, likhang tse tharo o hlalosoa ho sebelisoa macro BPF_CALL_3. Palo e phahameng ea likhang ke tse hlano.) Leha ho le joalo, ena ke karolo ea pele feela ea tlhaloso. Karolo ea bobeli ke ho hlalosa sebopeho sa mofuta struct bpf_func_proto, e nang le tlhaloso ea ts'ebetso ea mothusi eo mohlahlobi a e utloisisang:

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

Ngoliso ea Mesebetsi ea Thuso

E le hore mananeo a BPF a mofuta o itseng a sebelise mosebetsi ona, a tlameha ho o ngolisa, mohlala bakeng sa mofuta BPF_PROG_TYPE_XDP mosebetsi o hlalosoa ka har'a kernel xdp_func_proto, e khethang ho tsoa ho ID ea tšebetso ea mothusi hore na XDP e tšehetsa tšebetso ena kapa che. Mosebetsi oa rona ke litšehetso:

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

Mefuta e mecha ea mananeo a BPF "e hlalosoa" faeleng include/linux/bpf_types.h ho sebelisa macro BPF_PROG_TYPE. E hlalositsoe ka mantsoe a qotsitsoeng hobane e le tlhaloso e utloahalang, 'me ka mantsoe a puo ea C tlhaloso ea sete e feletseng ea mehaho ea konkreite e hlaha libakeng tse ling. Haholo-holo, ka faele kernel/bpf/verifier.c litlhaloso tsohle ho tsoa faeleng bpf_types.h di sebedisoa ho bopa letoto la meaho 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
};

Ke hore, bakeng sa mofuta o mong le o mong oa lenaneo la BPF, ho hlalosoa pointer ho sebopeho sa data sa mofuta ona struct bpf_verifier_ops, e qalisoang ka boleng _name ## _verifier_ops, ke hore, xdp_verifier_ops etsoe xdp. Sebopeho xdp_verifier_ops ikemiselitse ka faele net/core/filter.c ka tsela e latelang:

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

Mona re bona ts'ebetso ea rona e tloaelehileng xdp_func_proto, e tla tsamaisa se netefatsang nako le nako ha e kopana le phephetso mofuta o itseng e sebetsa ka har'a lenaneo la BPF, bona verifier.c.

Ha re shebeng hore na lenaneo la boikaketsi la BPF le sebelisa tšebetso joang bpf_get_smp_processor_id. Ho etsa sena, re ngola lenaneo hape ho tsoa karolong ea rona e fetileng ka tsela e latelang:

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

Letšoao bpf_get_smp_processor_id ikemiselitse в <bpf/bpf_helper_defs.h> lilaebrari libbpf kamoo

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

ke hore, bpf_get_smp_processor_id ke pontshi ya tshebetso eo boleng ba yona e leng 8, moo 8 e leng boleng BPF_FUNC_get_smp_processor_id mofuta enum bpf_fun_id, e hlalosoang bakeng sa rona faeleng vmlinux.h (faele bpf_helper_defs.h kernel e hlahisoa ke script, kahoo linomoro tsa "boselamose" li lokile). Ts'ebetso ena ha e nke likhang mme e khutlisa boleng ba mofuta __u32. Ha re e tsamaisa lenaneong la rona, clang e hlahisa taelo BPF_CALL "mofuta o nepahetseng" Ha re bokelleng lenaneo mme re shebe karolo 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

Moleng oa pele re bona litaelo call, parameter IMM e lekanang le 8, le SRC_REG - zero. Ho ea ka tumellano ea ABI e sebelisoang ke verifier, ena ke pitso ea nomoro ea borobeli ea ts'ebetso ea mothusi. Hang ha e se e qalisoa, logic e bonolo. Khutlisetsa boleng ho tsoa ho rejisetara r0 kopitsoa ho r1 mme meleng ea 2,3 e fetoleloa ho mofuta u32 - li-bits tse ka holimo tsa 32 li hlakotsoe. Meleng ea 4,5,6,7 re khutlisetsa 2 (XDP_PASS) kapa 1 (XDP_DROP) ho ipapisitse le hore na mothusi ea sebetsang moleng oa 0 o khutlisitse boleng ba lefela kapa e seng lefela.

Ha re itlhahlobeng: laela lenaneo mme re shebe tlhahiso 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

Ho lokile, verifier e fumane kernel-helper e nepahetseng.

Mohlala: ho fetisa likhang mme qetellong ho tsamaisa lenaneo!

Mesebetsi eohle ea li-run-level helper e na le prototype

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

Mekhahlelo ea mesebetsi ea mothusi e fetisetsoa lirejiseteng r1-r5, 'me boleng bo khutlisetsoa bukeng r0. Ha ho na mesebetsi e nkang likhang tse fetang tse hlano, 'me ha hoa lebelloa hore li tla eketsoa nakong e tlang.

Ha re shebeng mothusi e mocha oa kernel le hore na BPF e fetisa liparamente joang. Ha re ngoleng hape xdp-simple.bpf.c ka tsela e latelang (melala e meng kaofela ha e so fetohe):

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

Lenaneo la rona le hatisa palo ea CPU eo e sebetsang ho eona. Ha re e hlophise 'me re shebe khoutu:

$ 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

Meleng ea 0-7 re ngola khoele running on CPU%un, ebe moleng oa 8 re tsamaisa e tloaelehileng bpf_get_smp_processor_id. Meleng ea 9-12 re lokisa likhang tsa bathusi bpf_printk - lirekoto r1, r2, r3. Ke hobane'ng ha ba le bararo eseng ba babeli? Hobane bpf_printkena ke macro wrapper ho pota mothusi wa sebele bpf_trace_printk, e hlokang ho fetisa boholo ba khoele ea sebopeho.

Ha re eketse mela e 'maloa ho xdp-simple.ce le hore lenaneo la rona le hokahane le sebopeho lo 'me ka sebele qala!

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

Mona re sebelisa ts'ebetso bpf_set_link_xdp_fd, e kopanyang mananeo a BPF a mofuta oa XDP le likhokahano tsa marang-rang. Re kentse nomoro ea interface lo, eo kamehla e leng 1. Re tsamaisa mosebetsi ka makhetlo a mabeli ho qala ho tlosa lenaneo la khale haeba le ne le khomaretsoe. Hlokomela hore joale ha re hloke qholotso pause kapa loop e sa feleng: lenaneo la rona la loader le tla tsoa, ​​empa lenaneo la BPF le ke ke la bolaoa kaha le hokahane le mohloli oa ketsahalo. Ka mor'a ho khoasolla ka katleho le khokahanyo, lenaneo le tla qalisoa bakeng sa pakete e 'ngoe le e' ngoe ea marang-rang e fihlang lo.

A re ke re thowuni lenaneo le sheba segokanyimmediamentsi sa sebolokigolo 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

Lenaneo leo re le jarollotseng le na le ID 669 mme re bona ID e tšoanang sebopehong lo. Re tla romella liphutheloana tse 'maloa ho 127.0.0.1 (kopo + araba):

$ ping -c1 localhost

'me joale ha re shebeng litaba tsa "debug virtual file". /sys/kernel/debug/tracing/trace_pipe, eo ho eona bpf_printk o ngola melaetsa ea hae:

# 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

Ho ile ha bonoa liphutheloana tse peli lo mme ya sebetswa ho CPU0 - lenaneo la rona la pele la BPF le se nang moelelo le sebeditse!

Ke habohlokoa ho hlokomela seo bpf_printk Hase ha ho letho leo e ngollang faele ea debug: ena hase mothusi ea atlehileng ka ho fetisisa bakeng sa ho sebelisoa tlhahiso, empa sepheo sa rona e ne e le ho bontša ntho e bonolo.

Ho fihlella limmapa ho tsoa mananeong a BPF

Mohlala: ho sebelisa 'mapa oa lenaneo la BPF

Likarolong tse fetileng re ithutile ho theha le ho sebelisa limmapa ho tsoa sebakeng sa basebelisi, 'me joale a re shebeng karolo ea kernel. Ha re qaleng, joalo ka tloaelo, ka mohlala. Ha re ngoleng lenaneo la rona bocha xdp-simple.bpf.c ka tsela e latelang:

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

Qalong ea lenaneo re kentse tlhaloso ea 'mapa woo: Ena ke karolo ea 8-element e bolokang boleng joalo ka u64 (ho C re ka hlalosa lethathamo le joalo ka u64 woo[8]). Lenaneong "xdp/simple" re fumana nomoro ea hona joale ea processor ho fetoha key ebe o sebelisa ts'ebetso ea mothusi bpf_map_lookup_element re fumana pointer ho keno e lumellanang ka har'a sehlopha, eo re e eketsang ka e le 'ngoe. E fetoletsoe ho Serussia: re bala lipalo-palo tseo CPU e sebelitseng liphutheloana tse kenang. Ha re leke ho tsamaisa lenaneo:

$ 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

Ha re hlahlobeng hore na o hoketsoe ke mang lo 'me u romelle lipakete tse ling:

$ 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

Joale a re shebeng litaba tsa sehlopha:

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

Hoo e ka bang lits'ebetso tsohle li sebetsitsoe ho CPU7. Sena ha se bohlokoa ho rona, ntho e ka sehloohong ke hore lenaneo le sebetsa mme re utloisisa mokhoa oa ho fumana limmapa ho tsoa mananeong a BPF - ho sebelisa хелперов bpf_mp_*.

Lethathamo la mohlolo

Kahoo, re ka fihlella 'mapa ho tsoa lenaneong la BPF re sebelisa mehala e kang

val = bpf_map_lookup_elem(&woo, &key);

moo mosebetsi wa mothusi o shebahalang teng

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

empa re fetisa pontshi &woo ho sebopeho se sa boleloang ka lebitso struct { ... }...

Haeba re sheba lenaneo assembler, re bona hore boleng &woo ha e hlile ha e hlalosoe (mola oa 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
...

'me e fumaneha ho phalliso:

$ 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

Empa ha re sheba lenaneo le seng le laetsoe, re bona sesupo ho 'mapa o nepahetseng (mola oa 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]
...

Kahoo, re ka fihlela qeto ea hore nakong ea ho qala lenaneo la rona la loader, sehokelo sa &woo e ile ea nkeloa sebaka ke ntho e ’ngoe e nang le laebrari libbpf. Pele re tla sheba tlhahiso 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

Re bona seo libbpf etsa 'mapa woo ebe o khoasolla lenaneo la rona simple. Ha re shebeng ka botlalo hore na re kenya lenaneo joang:

  • letsa xdp_simple_bpf__open_and_load ho tsoa faeleng xdp-simple.skel.h
  • e bakang xdp_simple_bpf__load ho tsoa faeleng xdp-simple.skel.h
  • e bakang bpf_object__load_skeleton ho tsoa faeleng libbpf/src/libbpf.c
  • e bakang bpf_object__load_xattr ho tswa libbpf/src/libbpf.c

Mosebetsi oa ho qetela, har'a lintho tse ling, o tla bitsa bpf_object__create_maps, e bopang kapa e bulang limmapa tse seng li ntse li le teng, e li fetola litlhaloso tsa lifaele. (Ke mona moo re bonang BPF_MAP_CREATE tlhahisong strace.) E latelang tshebetso e bitsoa bpf_object__relocate ’me ke eena ea re thahasellang, kaha re hopola seo re se boneng woo tafoleng ea phalliso. Ho e hlahloba, qetellong re iphumana re le mosebetsing bpf_program__relocate, eo e sebetsana le phalliso ea 'mapa:

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

Kahoo re nka litaelo tsa rona

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

'me u nkele sebaka sa ngoliso ea mohloli ho eona ka BPF_PSEUDO_MAP_FD, le IMM ea pele ho tlhaloso ea faele ea 'mapa oa rona,' me, haeba e lekana, ka mohlala, 0xdeadbeef, joale ka lebaka leo re tla fumana taeo

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

Ena ke tsela eo litaba tsa 'mapa li fetisetsoang lenaneong le ikhethileng la BPF. Tabeng ena, 'mapa o ka etsoa ho sebelisoa BPF_MAP_CREATE, 'me e butsoe ka ID ho sebelisoa BPF_MAP_GET_FD_BY_ID.

Kakaretso, ha u sebelisa libbpf algorithm e tjena:

  • nakong ea ho bokella, ho etsoa lirekoto tafoleng ea phalliso bakeng sa lihokelo tsa limmapa
  • libbpf e bula buka ea ntho ea ELF, e fumana limmapa tsohle tse sebelisitsoeng ebe e ba etsetsa litlhaloso tsa lifaele
  • Litlhaloso tsa faele li kenngoa ka har'a kernel e le karolo ea taelo LD64

Joalo ka ha u ka inahanela, ho na le ho hong ho tlang mme re tla tlameha ho sheba mantlha. Ka lehlohonolo, re na le leseli - re ngotse moelelo BPF_PSEUDO_MAP_FD ka har'a rejistara ea mohloli 'me re ka e pata, e tla re isa ho sehalalelo sa bahalaleli bohle - kernel/bpf/verifier.c, moo tšebetso e nang le lebitso le ikhethang e nkang sebaka se hlalosang faele ka aterese ea sebopeho sa mofuta 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;

(Khoutu e felletseng e ka fumanoa link tsa). Kahoo re ka holisa algorithm ea rona:

  • ha o ntse o kenya lenaneo, verifier e hlahloba tšebeliso e nepahetseng ea 'mapa mme o ngola aterese ea sebopeho se lumellanang struct bpf_map

Ha u khoasolla binary ea ELF u sebelisa libbpf Ho na le tse ling tse ngata tse ntseng li tsoela pele, empa re tla tšohla seo lihloohong tse ling.

E kenya mananeo le limmapa ntle le libbpf

Joalokaha ho tšepisitsoe, bona ke mohlala bakeng sa babali ba batlang ho tseba ho theha le ho kenya lenaneo le sebelisang limmapa, ntle le thuso. libbpf. Sena se ka ba molemo ha o sebetsa tikolohong eo o sa khoneng ho theha litšepe ho eona, kapa ho boloka karoloana e 'ngoe le e' ngoe, kapa ho ngola lenaneo le kang. ply, e hlahisang BPF binary code on the fly.

Ho etsa hore ho be bonolo ho latela mohopolo, re tla ngola mohlala oa rona hape molemong oa merero ena xdp-simple. Khoutu e felletseng le e atolositsoeng hanyenyane ea lenaneo le tšohloang mohlaleng ona e ka fumanoa ho sena mokoena.

The logic ea kopo ea rona ke e latelang:

  • theha 'mapa oa mofuta BPF_MAP_TYPE_ARRAY ka ho sebedisa taelo BPF_MAP_CREATE,
  • theha lenaneo le sebelisang 'mapa ona,
  • hokela lenaneo ho segokanyimmediamentsi sa sebolokigolo lo,

e fetolelang ho motho joalo ka

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

ke map_create e theha 'mapa ka mokhoa o ts'oanang le oo re entseng mohlaleng oa pele mabapi le mohala oa sistimi bpf - "kernel, ke kopa o nketsetse 'mapa o mocha ka sebopeho sa likarolo tse 8 joalo ka __u64 'me u mphe se hlalosang faele":

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

Lenaneo le boetse le bonolo ho le kenya:

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

Karolo e qhekellang prog_load ke tlhaloso ea lenaneo la rona la BPF e le letoto la meaho struct bpf_insn insns[]. Empa kaha re sebelisa lenaneo leo re nang le lona ho C, re ka qhekella hanyane:

$ 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

Ka kakaretso, re hloka ho ngola litaelo tse 14 ka mokhoa oa mehaho e kang struct bpf_insn (keletso: nka thotobolo e tsoang holimo, bala hape karolo ea litaelo, bula linux/bpf.h и linux/bpf_common.h le ho leka ho tseba struct bpf_insn insns[] u le mong):

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

Boikoetliso bakeng sa ba sa kang ba ngola sena ka bobona - fumana map_fd.

Ho na le karolo e 'ngoe hape e sa boleloang e setseng lenaneong la rona - xdp_attach. Ka bomalimabe, mananeo a kang XDP ha a khone ho hokeloa ho sebelisoa mohala oa sistimi bpf. Batho ba thehileng BPF le XDP ba ne ba tsoa sechabeng sa Linux tsa marang-rang, ho bolelang hore ba sebelisitse eo ba e tloaetseng haholo (empa eseng ho tloaelehileng people) bakeng sa ho sebelisana le kernel: li-sockets tsa netlink, bona hape RFC3549. Mokhoa o bonolo oa ho kenya ts'ebetsong xdp_attach e kopitsa khoutu ho libbpf, e leng, ho tsoa faeleng netlink.c, ke seo re se entseng, re khutsufatsa hanyenyane:

Rea u amohela lefatšeng la li-netlink sockets

Bula mofuta oa sokete ea 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;
}

Re bala ho tsoa ho socket ena:

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

Qetellong, mona ke ts'ebetso ea rona e bulang sokete ebe e romella molaetsa o ikhethileng ho eona o nang le tlhaloso ea faele:

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

Kahoo, tsohle li loketse ho hlahlojoa:

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

Ha re boneng hore na lenaneo la rona le hokahane le 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

Ha re romelle li-pings 'me re shebe' mapa:

$ 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, tsohle lia sebetsa. Hlokomela, ka tsela, hore 'mapa oa rona o boetse o hlahisoa ka mokhoa oa li-byte. Sena se bakoa ke taba ea hore, ho fapana le libbpf ha rea ​​ka ra kenya tlhahisoleseling ea mofuta (BTF). Empa re tla bua haholoanyane ka taba ena nakong e tlang.

Lisebelisoa tsa ntlafatso

Karolong ena, re tla sheba bonyane ba lisebelisoa tsa ntlafatso ea BPF.

Ka kakaretso, ha u hloke letho le ikhethang ho nts'etsapele mananeo a BPF - BPF e sebetsa ho kernel efe kapa efe e ntle ea kabo, 'me mananeo a hahiloe ho sebelisoa. clang, e ka fanoang ka sephutheloana. Leha ho le joalo, ka lebaka la hore BPF e ntse e ntlafatsoa, ​​kernel le lisebelisoa li lula li fetoha, haeba u sa batle ho ngola mananeo a BPF u sebelisa mekhoa ea khale ea 2019, joale u tla tlameha ho bokella.

  • llvm/clang
  • pahole
  • motheo oa eona
  • bpftool

(Bakeng sa litšupiso, karolo ena le mehlala eohle sengolong li ne li tsamaisoa ho Debian 10.)

llvm/clang

BPF e na le botsoalle le LLVM 'me, leha mananeo a morao-rao a BPF a ka hlophisoa ho sebelisoa gcc, nts'etsopele eohle ea hajoale e etsoa bakeng sa LLVM. Ka hona, pele ho tsohle, re tla haha ​​​​phetolelo ea hona joale clang ho tloha ho 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
... много времени спустя
$

Joale re ka hlahloba hore na tsohle li kopane hantle:

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

(Litaelo tsa kopano clang nkiloeng ke 'na ho tloha bpf_devel_QA.)

Re ke ke ra kenya mananeo ao re sa tsoa a haha, empa re a eketsa feela PATHmohlala:

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

(Sena se ka ekeletsoa ho .bashrc kapa ho faele e arohaneng. Ka bonna, ke eketsa lintho tse kang tsena ho ~/bin/activate-llvm.sh mme ha ho hlokahala kea e etsa . activate-llvm.sh.)

Pahole le BTF

Tšebeliso pahole e sebelisitsoeng ha ho hahoa kernel ho theha tlhahisoleseling ea debugging ka sebopeho sa BTF. Re ke ke ra bua ka botlalo sehloohong sena mabapi le lintlha tsa theknoloji ea BTF, ntle le taba ea hore e bonolo ebile re batla ho e sebelisa. Kahoo haeba u tla haha ​​​​kernel ea hau, haha ​​​​pele pahole (ntle le pahole u ke ke ua khona ho haha ​​​​kernel ka khetho 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

Lithako tsa ho etsa liteko ka BPF

Ha ke hlahloba menyetla ea BPF, ke batla ho bokella motheo oa ka. Sena, ka kakaretso, ha se hlokahale, kaha u tla khona ho bokella le ho kenya mananeo a BPF ho kernel ea kabo, leha ho le joalo, ho ba le kernel ea hau ho u lumella ho sebelisa likarolo tsa morao-rao tsa BPF, tse tla hlaha kabong ea hau ka likhoeli tse ngata ka ho fetisisa. , kapa, joalo ka ha lisebelisoa tse ling tsa ho lokisa liphoso li ke ke tsa pakoa ho hang nakong e tlang e lebelletsoeng. Hape, motheo oa eona o etsa hore ho ikutloe ho le bohlokoa ho leka khoutu.

E le hore u hahe kernel u hloka, pele, kernel ka boeona, 'me ea bobeli, faele ea tlhophiso ea kernel. Ho etsa liteko ka BPF re ka sebelisa e tloaelehileng Vanilla kernel kapa enngwe ya ditholwana tsa ntshetsopele. Ho latela nalane, nts'etsopele ea BPF e etsahala ka har'a sechaba sa marang-rang sa Linux mme ka hona liphetoho tsohle haufinyane li tla feta David Miller, mohlokomeli oa marang-rang oa Linux. Ho ipapisitse le sebopeho sa bona - liphetoho kapa likarolo tse ncha - liphetoho tsa marang-rang li oela ho e 'ngoe ea li-cores tse peli - net kapa net-next. Liphetoho tsa BPF li ajoa ka tsela e tšoanang pakeng tsa bpf и bpf-next, tseo joale li kopantsoeng ho letlooa le letlooa le latelang, ka ho latellana. Bakeng sa lintlha tse ling, bona bpf_devel_QA и netdev-FAQ. Kahoo khetha kernel ho latela tatso ea hau le litlhoko tsa botsitso tsa sistimi eo u lekang ho eona (*-next lithollo ke tsona tse sa tsitsang ho feta tse thathamisitsoeng).

Ho feta boholo ba sengoloa sena ho bua ka mokhoa oa ho laola lifaele tsa kernel - ho nahanoa hore u se u ntse u tseba ho etsa sena, kapa e loketse ho ithuta ka bowena. Leha ho le joalo, litaelo tse latelang li lokela ho ba tse ngata kapa tse fokolang ho lekana ho u fa tsamaiso e sebetsang ea BPF.

Khoasolla e 'ngoe ea lithollo tse kaholimo:

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

Theha tlhophiso e fokolang ea kernel e sebetsang:

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

Numella likhetho tsa BPF faeleng .config khetho ea hau (haholo-holo CONFIG_BPF e tla be e se e ntse e buletsoe kaha systemd e e sebelisa). Mona ke lethathamo la likhetho tse tsoang ho kernel e sebelisitsoeng bakeng sa sengoloa sena:

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

Ebe re ka bokella habonolo le ho kenya li-module le kernel (ka tsela, o ka bokella kernel o sebelisa tse sa tsoa bokelloa. clangka ho eketsa CC=clang):

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

'me u qale hape ka kernel e ncha (ke e sebelisetsa sena kexec ho tloha sephutheloana 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

Sesebelisoa se sebelisoang ka ho fetesisa sengoloeng se tla ba sesebelisoa bpftool, e fanoeng e le karolo ea Linux kernel. E ngotsoe le ho hlokomeloa ke baetsi ba BPF bakeng sa baetsi ba BPF mme e ka sebelisoa ho laola mefuta eohle ea lintho tsa BPF - ho kenya mananeo, ho theha le ho hlophisa limmapa, ho hlahloba bophelo ba tikoloho ea BPF, joalo-joalo. Litokomane ka mokhoa oa mekhoa ea mohloli bakeng sa maqephe a motho li ka fumanoa bohareng kapa, e seng e hlophisitsoe, neteng.

Nakong ea ha ho ngoloa sena bpftool e tla e lokiselitsoe feela bakeng sa RHEL, Fedora le Ubuntu (bona, mohlala, khoele ena, e bolelang pale e sa phethoang ea ho paka bpftool ka Debian). Empa haeba u se u ntse u hahile kernel ea hau, joale haha bpftool e bonolo joaloka 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  ]

$

(Mona ${linux} - ena ke kernel directory ea hau.) Kamora ho phethahatsa litaelo tsena bpftool e tla bokelloa bukeng ${linux}/tools/bpf/bpftool mme e ka eketsoa tseleng (pele ho tsohle ho mosebelisi root) kapa kopitsa feela ho /usr/local/sbin.

Bokella bpftool ho molemo ho sebelisa ea morao-rao clang, e bokelloa joalokaha e hlalositsoe ka holimo, 'me u hlahlobe hore na e bokelloa ka nepo - ho sebelisa, mohlala, taelo

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

e tla bonts'a hore na ke likarolo life tsa BPF tse kentsoeng kernel ea hau.

Ka tsela, taelo e fetileng e ka tsamaisoa joalo ka

# bpftool f p k

Sena se etsoa ka papiso le lisebelisoa tse tsoang sephutheloaneng iproute2, moo re ka khonang, mohlala, ho re ip a s eth0 sebakeng sa ip addr show dev eth0.

fihlela qeto e

BPF e u lumella ho roala letsetse ho lekanya hantle le ho fofa hang-hang ho fetola ts'ebetso ea mantlha. Sistimi e ile ea atleha haholo, litloaelong tse ntle ka ho fetisisa tsa UNIX: mokhoa o bonolo o u lumellang ho (re) lenaneo la kernel le lumelletse palo e kholo ea batho le mekhatlo ho etsa liteko. 'Me, le hoja liteko, hammoho le nts'etsopele ea mekhoa ea motheo ea BPF ka boeona, e se e le hōle le ho fela, tsamaiso e se e ntse e e-na le ABI e tsitsitseng e u lumellang ho haha ​​​​mokhoa oa khoebo o tšepahalang, oa bohlokoa ka ho fetisisa.

Ke rata ho hlokomela hore, ka maikutlo a ka, theknoloji e se e tumme haholo hobane, ka lehlakoreng le leng, e ka khona bapala (mohaho oa mochine o ka utloisisoa ho feta kapa ka tlase mantsiboeeng a le mong), 'me ka lehlakoreng le leng, ho rarolla mathata a neng a ke ke a rarolloa (ka bokhabane) pele ho ponahalo ea oona. Likarolo tsena tse peli hammoho li qobella batho ho etsa liteko le ho lora, e leng se lebisang ho hlahisoeng ha litharollo tse ngata tse ncha.

Sengoliloeng sena, le hoja se se sekhutšoane ka ho khetheha, ke selelekela sa lefats'e la BPF mme ha se hlalose likarolo tse "tsoetseng pele" le likarolo tsa bohlokoa tsa meralo. Morero oa ho ea pele ke ntho e kang ena: sengoloa se latelang e tla ba kakaretso ea mefuta ea mananeo a BPF (ho na le mefuta e 5.8 ea mananeo e tšehelitsoeng ho 30 kernel), ebe qetellong re tla sheba mokhoa oa ho ngola lits'ebetso tsa BPF tsa 'nete re sebelisa mananeo a ho latedisa kernel. e le mohlala, joale ke nako ea hore ho be le thupelo e tebileng haholoanyane mabapi le meralo ea BPF, e lateloe ke mehlala ea marang-rang a BPF le lits'ebetso tsa ts'ireletso.

Lihlooho tse fetileng letotong lena

  1. BPF bakeng sa bana ba banyenyane, karolo ea zero: BPF ea khale

Lihokelo

  1. BPF le XDP Reference Guide - litokomane tse mabapi le BPF ho tsoa ho cilium, kapa ka nepo ho tsoa ho Daniel Borkman, e mong oa baqapi le bahlokomeli ba BPF. Ena ke e ’ngoe ea litlhaloso tsa pele tse tebileng, tse fapaneng le tse ling ka hore Daniele o tseba hantle seo a ngolang ka sona ’me ha ho liphoso moo. Haholo-holo, tokomane ena e hlalosa mokhoa oa ho sebetsa le mananeo a BPF a mefuta ea XDP le TC ho sebelisa lisebelisoa tse tsebahalang. ip ho tloha sephutheloana iproute2.

  2. Documentation/networking/filter.txt - faele ea mantlha e nang le litokomane tsa BPF ea khale ebe e atolosoa. E bala hantle haeba u batla ho tseba ka puo ea kopano le lintlha tsa meralo ea tekheniki.

  3. Blog ka BPF ho tloha facebook. E nchafatsoa ka seoelo, empa ka nepo, joalo ka ha Alexei Starovoitov (mongoli oa eBPF) le Andrii Nakryiko - (mohlokomeli) ba ngola moo. libbpf).

  4. Liphiri tsa bpftool. Khoele e monate ea twitter e tsoang ho Quentin Monnet e nang le mehlala le liphiri tsa ho sebelisa bpftool.

  5. Ikakhele ka setotsoana ho BPF: lethathamo la lintho tse baloang. Lenane le leholo (le le ntseng le hlokometsoe) la likhokahano tsa litokomane tsa BPF tse tsoang ho Quentin Monnet.

Source: www.habr.com

Eketsa ka tlhaloso