He Whakataki Poto mo te BPF me te eBPF

Kia ora, Habr! E hiahia ana matou ki te whakamohio atu kei te whakarite pukapuka mo te tuku."Linux Observability me te BPF".

He Whakataki Poto mo te BPF me te eBPF
I te mea kei te tipu haere tonu te miihini mariko BPF me te whakamahi kaha i roto i nga mahi, kua whakamaoritia e matou mo koe tetahi tuhinga e whakaatu ana i ona kaha matua me te ahuatanga o naianei.

I nga tau tata nei, kua piki haere te rongonui o nga taputapu hotaka me nga tikanga ki te utu mo nga herenga o te kernel Linux i roto i nga keehi e hiahiatia ana te tukatuka putea mahi teitei. Ko tetahi o nga tikanga tino rongonui o tenei momo ka kiia kakano hipa (kernel bypass) me te tuku, ma te takahi i te paparanga whatunga kernel, ki te mahi i nga mahi tukatuka katoa mai i te waahi kaiwhakamahi. Ko te maataki i te kernel ka uru ano ki te whakahaere i te kaari whatunga mai wāhi kaiwhakamahi. I etahi atu kupu, ka mahi tahi me te kaari whatunga, ka whakawhirinaki matou ki te taraiwa wāhi kaiwhakamahi.

Ma te whakawhiti i te mana whakahaere katoa o te kaari whatunga ki te hotaka mokowā-kaiwhakamahi, ka whakaitihia e matou te kernel i runga ake (te whakawhiti horopaki, te tukatuka paparanga whatunga, te aukati, me etahi atu), he mea tino nui ki te rere i te tere o te 10Gb/s teitei ake ranei. Kirikiri karo me te huinga o etahi atu ahuatanga (tukatuka puranga) me te ata whakarite mahi (NUMA kaute, Wehenga PTM, me etahi atu) e rite ana ki nga kaupapa o te tukatuka whatunga mahi nui i roto i te waahi kaiwhakamahi. Tena pea he tauira tino pai mo tenei huarahi hou ki te tukatuka kete DPDK mai i te Intel (Kete Whanaketanga Papa Raraunga), ahakoa tera ano etahi atu taputapu me nga tikanga rongonui, tae atu ki a Cisco's VPP (Vector Packet Processing), Netmap me, o te akoranga, Pakimaki.

Ko te whakarite i nga taunekeneke whatunga i roto i te waahi kaiwhakamahi he maha nga ngoikoretanga:

  • Ko te kernel OS he paparanga tangohanga mo nga rauemi taputapu. Na te mea me whakahaere tika nga kaupapa mokowā kaiwhakamahi i o raatau rauemi, me whakahaere ano e ratou a raatau ake taputapu. Ko te tikanga o tenei me whakarite i a koe ake taraiwa.
  • Na te mea ka tukuna katoatia e matou te mokowā kernel, ka tukuna katoatia e matou nga mahi whatunga katoa e whakaratohia ana e te kernel. Ko nga kaupapa mokowā-kaiwhakamahi me whakatinana ano i nga mahi kua tukuna e te kernel, te punaha whakahaere ranei.
  • Ka mahi nga papatono i roto i te aratau pouaka kirikiri, e tino whakawhāiti ana i a raatau taunekeneke me te aukati i a raatau ki te whakauru ki etahi atu waahanga o te punaha whakahaere.

Ko te tikanga, i te wa e hono ana i te waahi kaiwhakamahi, ka puta nga hua mahi ma te neke i te tukatuka paatete mai i te kernel ki te waahi kaiwhakamahi. He rereke te mahi a XDP: ka nukuhia e ia nga kaupapa whatunga mai i te waahi kaiwhakamahi (nga whiriwhiringa, nga kaiwhakatikatika, te ararere, me etahi atu) ki te mokowā kernel. Ka taea e XDP te mahi i tetahi mahi whatunga ina pa ana te paakete ki tetahi atanga whatunga me mua i te tiimata ka neke ake ki roto i te punaha whatunga kernel. Ko te mutunga, ka tino piki ake te tere o te tukatuka paatete. Heoi, me pehea e taea ai e te kernel te kaiwhakamahi ki te whakahaere i a raatau kaupapa ki te mokowā kernel? I mua i te whakautu i tenei patai, me titiro tatou he aha te BPF.

BPF me te eBPF

Ahakoa te ingoa rangirua, ko te BPF (Berkeley Packet Filtering), he tauira miihini mariko. I hangaia tenei miihini mariko i te tuatahi ki te hapai i te tātari paatete, no reira te ingoa.

Ko tetahi o nga taputapu rongonui ma te whakamahi i te BPF tcpdump. I te wa e hopu ana i nga paatete ma te whakamahi tcpdump ka taea e te kaiwhakamahi te whakaatu i tetahi korero hei tātari i nga paatete. Ko nga paatete e rite ana ki tenei korero ka hopukina. Hei tauira, ko te kupu “tcp dst port 80” e tohu ana ki nga paatete TCP katoa ka tae mai ki te tauranga 80. Ka taea e te kaikoipi te whakapoto i tenei korero ma te huri ki te BPF bytecode.

$ sudo tcpdump -d "tcp dst port 80"
(000) ldh [12] (001) jeq #0x86dd jt 2 jf 6
(002) ldb [20] (003) jeq #0x6 jt 4 jf 15
(004) ldh [56] (005) jeq #0x50 jt 14 jf 15
(006) jeq #0x800 jt 7 jf 15
(007) ldb [23] (008) jeq #0x6 jt 9 jf 15
(009) ldh [20] (010) jset #0x1fff jt 15 jf 11
(011) ldxb 4*([14]&0xf)
(012) ldh [x + 16] (013) jeq #0x50 jt 14 jf 15
(014) ret #262144
(015) ret #0

Koinei te mahi o te kaupapa i runga ake nei:

  • Tohutohu (000): Ka utaina te kete ki te 12, hei kupu moka-16, ki roto i te whakaemi. Ko te Whakawhitiwhiti 12 e rite ana ki te momo ethertype o te kete.
  • Tohutohu (001): ka whakataurite i te uara i roto i te kaikohikohi ki te 0x86dd, ara, me te uara ethertype mo IPv6. Mena he pono te hua, ka haere te porotiti papatono ki te tohutohu (002), ki te kore, ka haere ki te (006).
  • Tohutohu (006): ka whakataurite i te uara ki te 0x800 (te uara momo mo te IPv4). Mena he pono te whakautu, ka haere te kaupapa ki te (007), ki te kore, ka haere ki te (015).

A pera tonu tae noa ki te whakahokinga mai o te kaupapa tātari paatete. Ko te tikanga he Boolean tenei. Ko te whakahoki i te uara kore-kore (tohutohu (014)) ko te tikanga i whakaaehia te kete, me te whakahoki i te uara kore (te tohutohu (015)) ko te tikanga kaore i whakaaehia te kete.

Na Steve McCann raua ko Van Jacobson te miihini mariko BPF me tana bytecode i te mutunga o te tau 1992 i te whakaputanga o ta raua pepa. Tātari Pākete BSD: Hangahanga Hou mo te Hopu Pakete Taumata-kaiwhakamahi, i tukuna tuatahitia tenei hangarau ki te huihuinga o Usenix i te takurua o te tau 1993.

Na te mea he miihini mariko te BPF, ka tautuhia e ia te taiao e rere ai nga kaupapa. I tua atu i te bytecode, ka tautuhi ano i te tauira mahara o te puranga (ka uru nga tohutohu kawenga ki te puranga), nga rehita (A me te X; rehita whakaemi me te tohu tohu), te rokiroki mahara raraku, me te porotiti hotaka. He mea whakamiharo, i whakatauirahia te BPF bytecode i muri i te Motorola 6502 ISA. I maumahara a Steve McCann i tana purongo hui hui i Sharkfest '11, i waia ia ki te hanga 6502 mai i ana hotaka o nga ra kura tuarua i runga i te Apple II, a na tenei matauranga i awe ki tana mahi hoahoa i te BPF bytecode.

Ka whakatinanahia te tautoko BPF i roto i te kernel Linux i roto i nga putanga v2.5 me te teitei ake, ka taapirihia e nga mahi a Jay Schullist. I noho tonu te waehere BPF tae noa ki te tau 2011, i te wa i hoahoa ano a Eric Dumaset i te kaiwhakamaori BPF kia rere ki te aratau JIT (Source: JIT mo nga whiriwhiringa putea). I muri i tenei, ka taea e te kernel, hei utu mo te whakamaori i te BPF bytecode, ka taea te huri tika i nga kaupapa BPF ki te hoahoanga whaainga: x86, ARM, MIPS, etc.

I muri mai, i te 2014, ka whakaarohia e Alexey Starovoitov he tikanga JIT hou mo te BPF. Ko te tikanga, ko tenei JIT hou i noho hei hoahoanga-a-BPF hou, ka kiia ko eBPF. Ki taku whakaaro i noho tahi nga VM e rua mo etahi wa, engari i tenei wa ka whakatinanahia te tātari paatete i runga i te eBPF. Inaa, i roto i nga tauira maha o nga tuhinga hou, ko te BPF he eBPF, ko te BPF puāwai e kiia nei ko cBPF.

Ka whakawhānuihia e te eBPF te miihini mariko BPF matarohia i roto i nga huarahi maha:

  • I runga i nga hoahoanga 64-bit hou. Ka whakamahia e te eBPF nga rehita moka-64 me te whakanui ake i te maha o nga rehita e waatea ana mai i te 2 (whakaemi me te X) ki te 10. Ka tukuna ano e eBPF etahi atu opcodes (BPF_MOV, BPF_JNE, BPF_CALL...).
  • Wewetehia mai i te punaha iti paparanga whatunga. I herea a BPF ki te tauira raraunga puranga. I te mea i whakamahia mo te tātari paatete, ko tana waehere kei roto i te punaha iti e whakarato ana i nga whakawhitinga whatunga. Heoi, kua kore e herea te miihini mariko eBPF ki te tauira raraunga ka taea te whakamahi mo tetahi kaupapa. Na, inaianei ka taea te hono te kaupapa eBPF ki te tracepoint, kprobe ranei. Ma tenei ka whakatuwhera i te huarahi ki te taputapu eBPF, te tātari mahi, me te maha atu o nga keehi whakamahi i roto i te horopaki o etahi atu punaha riaka. Inaianei ko te waehere eBPF kei tona ake ara: kernel/bpf.
  • Ko nga toa raraunga o te ao e kiia nei ko Mahere. Ko nga Mahere he toa nui-uara e taea ai te whakawhiti raraunga i waenga i te mokowā kaiwhakamahi me te mokowā kernel. Ka whakaratohia e te eBPF etahi momo mapi.
  • Nga mahi tuarua. Otirā, ki te tuhi anō i tētahi mōkihi, ki te tātai i te kaute arowhai, ki te whakakao rānei i tētahi mōkihi. Ka rere enei mahi ki roto i te kernel, ehara i te kaupapa mokowā-kaiwhakamahi. Ka taea hoki e koe te waea punaha mai i nga kaupapa eBPF.
  • Whakamutua nga waea. Ko te rahi o te papatono i roto i te eBPF he iti ki te 4096 paita. Ko te ahuatanga karanga hiku ka taea e tetahi kaupapa eBPF te whakawhiti mana ki tetahi kaupapa eBPF hou, na reira ka karo i tenei here (tae atu ki te 32 nga kaupapa ka taea te hono penei).

eBPF: tauira

He maha nga tauira mo te eBPF i roto i nga puna kernel Linux. E waatea ana i nga tauira/bpf/. Hei whakahiato i enei tauira, tomo noa:

$ sudo make samples/bpf/

Kaore au e tuhi i tetahi tauira hou mo te eBPF ake, engari ka whakamahi i tetahi o nga tauira e waatea ana i roto i nga tauira/bpf/. Ka titiro au ki etahi wahanga o te waehere me te whakamarama me pehea te mahi. Hei tauira, i whiriwhiria e au te kaupapa tracex4.

I te nuinga o te waa, e rua nga konae kei ia tauira i roto i nga tauira/bpf/. I tenei take:

  • tracex4_kern.c, kei roto te waehere puna kia mahia i roto i te kernel hei eBPF bytecode.
  • tracex4_user.c, kei roto he papatono mai i te mokowā kaiwhakamahi.

I tenei keehi, me whakahiato tatou tracex4_kern.c ki te eBPF bytecode. I tenei wa kei roto gcc karekau he tuara mo te eBPF. Waimarie, clang ka taea te whakaputa eBPF bytecode. Makefile whakamahinga clang mo te whakahiato tracex4_kern.c ki te kōnae ahanoa.

I korero ahau i runga ake ko tetahi o nga ahuatanga tino pai o te eBPF he mapi. Ka tautuhia e tracex4_kern tetahi mapi:

struct pair {
    u64 val;
    u64 ip;
};  

struct bpf_map_def SEC("maps") my_map = {
    .type = BPF_MAP_TYPE_HASH,
    .key_size = sizeof(long),
    .value_size = sizeof(struct pair),
    .max_entries = 1000000,
};

BPF_MAP_TYPE_HASH Ko tetahi o nga momo kaari maha e tukuna ana e eBPF. I roto i tenei take, he hash noa. Kua kite pea koe i tetahi panui SEC("maps"). He tonotono te SEC hei hanga i tetahi waahanga hou o te konae rua. Mau, i roto i te tauira tracex4_kern e rua ano nga waahanga kua tautuhia:

SEC("kprobe/kmem_cache_free")
int bpf_prog1(struct pt_regs *ctx)
{   
    long ptr = PT_REGS_PARM2(ctx);

    bpf_map_delete_elem(&my_map, &ptr); 
    return 0;
}
    
SEC("kretprobe/kmem_cache_alloc_node") 
int bpf_prog2(struct pt_regs *ctx)
{
    long ptr = PT_REGS_RC(ctx);
    long ip = 0;

    // получаем ip-адрес вызывающей стороны kmem_cache_alloc_node() 
    BPF_KRETPROBE_READ_RET_IP(ip, ctx);

    struct pair v = {
        .val = bpf_ktime_get_ns(),
        .ip = ip,
    };
    
    bpf_map_update_elem(&my_map, &ptr, &v, BPF_ANY);
    return 0;
}   

Ko enei mahi e rua ka taea e koe te muku i tetahi urunga mai i te mapi (kprobe/kmem_cache_free) ka taapirihia he urunga hou ki te mapi (kretprobe/kmem_cache_alloc_node). Ko nga ingoa mahi katoa kua tuhia ki nga reta matua e rite ana ki nga tonotono kua tautuhia ki roto bpf_helpers.h.

Mena ka makahia e au nga waahanga o te konae ahanoa, me kite ahau kua tautuhia enei waahanga hou:

$ objdump -h tracex4_kern.o

tracex4_kern.o: file format elf64-little

Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000000 0000000000000000 0000000000000000 00000040 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 kprobe/kmem_cache_free 00000048 0000000000000000 0000000000000000 00000040 2**3
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
2 kretprobe/kmem_cache_alloc_node 000000c0 0000000000000000 0000000000000000 00000088 2**3
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
3 maps 0000001c 0000000000000000 0000000000000000 00000148 2**2
CONTENTS, ALLOC, LOAD, DATA
4 license 00000004 0000000000000000 0000000000000000 00000164 2**0
CONTENTS, ALLOC, LOAD, DATA
5 version 00000004 0000000000000000 0000000000000000 00000168 2**2
CONTENTS, ALLOC, LOAD, DATA
6 .eh_frame 00000050 0000000000000000 0000000000000000 00000170 2**3
CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA

Kei reira ano tracex4_user.c, kaupapa matua. Ko te tikanga, ka whakarongo tenei hotaka ki nga huihuinga kmem_cache_alloc_node. Ka puta he huihuinga pera, ka mahia te waehere eBPF e rite ana. Ka tiakina e te waehere te huanga IP o te ahanoa ki roto i te mapi, ka huri te ahanoa i roto i te kaupapa matua. Tauira:

$ sudo ./tracex4
obj 0xffff8d6430f60a00 is 2sec old was allocated at ip ffffffff9891ad90
obj 0xffff8d6062ca5e00 is 23sec old was allocated at ip ffffffff98090e8f
obj 0xffff8d5f80161780 is 6sec old was allocated at ip ffffffff98090e8f

He pehea te hononga o te hotaka mokowā kaiwhakamahi me te kaupapa eBPF? I te arawhitinga tracex4_user.c ka utaina he kōnae ahanoa tracex4_kern.o te whakamahi i te mahi load_bpf_file.

int main(int ac, char **argv)
{
    struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
    char filename[256];
    int i;

    snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);

    if (setrlimit(RLIMIT_MEMLOCK, &r)) {
        perror("setrlimit(RLIMIT_MEMLOCK, RLIM_INFINITY)");
        return 1;
    }

    if (load_bpf_file(filename)) {
        printf("%s", bpf_log_buf);
        return 1;
    }

    for (i = 0; ; i++) {
        print_old_objects(map_fd[1]);
        sleep(1);
    }

    return 0;
}

Ma te mahi load_bpf_file ka taapirihia nga tirotiro kua tautuhia ki te konae eBPF /sys/kernel/debug/tracing/kprobe_events. Inaianei ka whakarongo matou mo enei huihuinga ka taea e ta maatau kaupapa te mahi i te waa ka tupu.

$ sudo cat /sys/kernel/debug/tracing/kprobe_events
p:kprobes/kmem_cache_free kmem_cache_free
r:kprobes/kmem_cache_alloc_node kmem_cache_alloc_node

He rite tonu te hanganga o etahi atu papatono i roto i te tauira/bpf/. E rua tonu nga konae kei roto:

  • XXX_kern.c: hōtaka eBPF.
  • XXX_user.c: kaupapa matua.

Ko te kaupapa eBPF he tohu mapi me nga mahi e hono ana ki tetahi waahanga. Ina tukuna e te kernel tetahi huihuinga o tetahi momo (hei tauira, tracepoint), ka mahia nga mahi here. Ko nga kaari ka tuku korero i waenga i te kaupapa kernel me te kaupapa mokowā kaiwhakamahi.

mutunga

I korero tenei tuhinga mo te BPF me te eBPF i nga tikanga whanui. E mohio ana ahau he maha nga korero me nga rauemi mo te eBPF i tenei ra, no reira ka tūtohu ahau etahi atu rauemi mo te ako ano

Ka tūtohu ahau ki te panui:

Source: will.com

Tāpiri i te kōrero