ProHoster > Blog > Tsamaiso > BPF bakeng sa bana ba banyenyane, karolo ea pele: BPF e atolositsoeng
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.
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.
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.
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):
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.
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:
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
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:
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.
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:
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:
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:
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:
(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:
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.
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.
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:
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):
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 moelelounion 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:
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
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:
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:
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:
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:
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".
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:
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:
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
$ 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:
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:
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:
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):
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?
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:
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:
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:
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:
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:
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[]:
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_opsikemiselitse ka faele net/core/filter.c ka tsela e latelang:
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:
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:
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:
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_printk - ena 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!
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:
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:
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
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
$ 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):
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:
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;
'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:
(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":
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:
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):
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:
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
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:
(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.
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.
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.
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).
Liphiri tsa bpftool. Khoele e monate ea twitter e tsoang ho Quentin Monnet e nang le mehlala le liphiri tsa ho sebelisa bpftool.