د BPF او eBPF لنډه پیژندنه

سلام، حبر! موږ غواړو تاسو ته خبر درکړو چې موږ د خپریدو لپاره یو کتاب چمتو کوو."د BPF سره د لینکس مشاهده".

د BPF او eBPF لنډه پیژندنه
څرنګه چې د BPF مجازی ماشین پرمختګ ته دوام ورکوي او په فعاله توګه په عمل کې کارول کیږي، موږ ستاسو لپاره یوه مقاله ژباړلې چې د هغې اصلي وړتیاوې او اوسني حالت بیانوي.

په وروستي کلونو کې، د پروګرام کولو وسیلې او تخنیکونه په زیاتیدونکي توګه مشهور شوي ترڅو د لینکس کرنل محدودیتونو ته تاوان ورکړي په هغه قضیو کې چې د لوړ فعالیت پاکټ پروسس کولو ته اړتیا وي. د دې ډول خورا مشهور تخنیکونو څخه یو نومیږي کرنل بای پاس (کرنل بای پاس) او اجازه ورکوي، د کرنل شبکې پرت څخه تېر شي، د کارن له ځای څخه د بسته بندي ټول پروسس ترسره کړي. د کرنل بای پاس کول د شبکې کارت کنټرول هم شامل دی د کارونکي ځای. په بل عبارت، کله چې د شبکې کارت سره کار کوي، موږ په موټر چلوونکي تکیه کوو د کارونکي ځای.

د کارونکي ځای پروګرام ته د شبکې کارت بشپړ کنټرول په لیږدولو سره، موږ د کرنل سر سر ټیټ کوو (د شرایطو بدلول، د شبکې پرت پروسس کول، مداخلې، او نور)، کوم چې خورا مهم دی کله چې د 10Gb/s یا لوړ سرعت سره چلیږي. د کرنل بای پاس او د نورو ځانګړتیاو ترکیب (بیچ پروسس کول) او په احتیاط سره د فعالیت تنظیم کول (د NUMA محاسبه, د CPU جلا کول، او داسې نور) د کارونکي ځای کې د لوړ فعالیت شبکې پروسس کولو اساساتو سره مطابقت لري. شاید د پیکټ پروسس کولو لپاره د دې نوې طریقې یوه بیلګه وي DPDK د انټل څخه (د ډیټا الوتکې پراختیا کټ)، که څه هم نور مشهور وسایل او تخنیکونه شتون لري، پشمول د سیسکو VPP (ویکټر پاکټ پروسس کول)، نیټ میپ او البته، صیب.

د کارونکي ځای کې د شبکې متقابل عمل تنظیم کول یو شمیر زیانونه لري:

  • د OS کرنل د هارډویر سرچینو لپاره د خلاصون پرت دی. ځکه چې د کاروونکي ځای پروګرامونه باید خپلې سرچینې په مستقیم ډول اداره کړي، دوی باید خپل هارډویر هم اداره کړي. دا ډیری وختونه پدې معنی دي چې ستاسو خپل چلوونکي برنامه کړئ.
  • ځکه چې موږ د کرنل ځای په بشپړه توګه ورکوو، موږ د کرنل لخوا چمتو شوي د شبکې ټول فعالیت هم ورکوو. د کارن ځای پروګرامونه باید هغه ځانګړتیاوې بیا پلي کړي چې ممکن مخکې د کرنل یا عملیاتي سیسټم لخوا چمتو شوي وي.
  • پروګرامونه د سینڈ باکس حالت کې کار کوي، کوم چې په جدي توګه د دوی تعامل محدودوي او د عملیاتي سیسټم نورو برخو سره د یوځای کیدو مخه نیسي.

په اصل کې، کله چې د کاروونکي ځای کې شبکه کول، د فعالیت لاسته راوړنې د پیکټ پروسس کولو له کرنل څخه د کاروونکي ځای ته لیږدول کیږي. XDP بالکل برعکس کار کوي: دا د شبکې پروګرامونه د کارونکي ځای (فلټرونه، حل کونکي، روټینګ، او نور) څخه د کرنل ځای ته حرکت کوي. XDP موږ ته اجازه راکوي چې د شبکې فعالیت ترسره کړو هرڅومره ژر چې یو کڅوړه د شبکې انٹرفیس ته ننوځي او مخکې لدې چې دا د کرنل شبکې فرعي سیسټم ته حرکت پیل کړي. د پایلې په توګه، د پاکټ پروسس سرعت د پام وړ وده کوي. په هرصورت، د کرنل څنګه کارونکي ته اجازه ورکوي چې خپل پروګرامونه د کرنل په ځای کې اجرا کړي؟ مخکې له دې چې دې پوښتنې ته ځواب ووایو، راځئ وګورو چې BPF څه شی دی.

BPF او eBPF

د مغشوش نوم سره سره ، BPF (د برکلي پاکټ فلټر کول) په حقیقت کې د مجازی ماشین ماډل دی. دا مجازی ماشین په اصل کې د پاکټ فلټر کولو اداره کولو لپاره ډیزاین شوی و، له همدې امله نوم.

د BPF په کارولو سره یو له خورا مشهور وسیلو څخه دی tcpdump. کله چې په کارولو سره بسته بندي کول tcpdump کارونکی کولی شي د پاکټونو فلټر کولو لپاره څرګندونه مشخص کړي. یوازې د دې بیان سره سمون لرونکي کڅوړې به ونیول شي. د مثال په توګه، بیان "tcp dst port 80ټولو TCP پاکټونو ته اشاره کوي چې پورټ 80 ته راځي. کمپیلر کولی شي دا بیان د BPF بایټکوډ ته په بدلولو سره لنډ کړي.

$ 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

دا هغه څه دي چې پورته برنامه اساسا کوي:

  • لارښوونه (000): بسته په 12 کې د 16-bit کلمې په توګه، په جمع کونکي کې بار کړئ. آفسیټ 12 د پاکټ ایتر ډول سره مطابقت لري.
  • لارښوونه (001): په جمع کونکي کې ارزښت د 0x86dd سره پرتله کوي ، دا د IPv6 لپاره د ایټرټایپ ارزښت سره. که پایله سمه وي، نو بیا د پروګرام کاونټر لارښوونې (002) ته ځي، او که نه، نو بیا (006).
  • لارښوونه (006): ارزښت د 0x800 سره پرتله کوي (د IPv4 لپاره د ایټر ډول ارزښت). که ځواب سم وي، نو پروګرام (007) ته ځي، که نه، نو بیا (015) ته ځي.

او داسې نور تر هغه چې د پاکټ فلټر کولو برنامه پایله بیرته راوړي. دا معمولا یو بولین دی. د غیر صفر ارزښت (لارښوونې (014)) بیرته راګرځول پدې معنی دي چې کڅوړه منل شوې وه ، او د صفر ارزښت بیرته راستنیدل (لارښوونه (015)) پدې معنی ده چې کڅوړه نه وه منل شوې.

د BPF مجازی ماشین او د هغې بایټ کوډ د 1992 په وروستیو کې د سټیو مک کین او وان جیکوبسن لخوا وړاندیز شوی و کله چې د دوی مقاله خپره شوه د BSD پاکټ فلټر: د کارونکي کچې پاکټ نیول لپاره نوی جوړښتدا ټیکنالوژي د لومړي ځل لپاره د 1993 په ژمي کې د Usenix کنفرانس کې وړاندې شوه.

ځکه چې BPF یو مجازی ماشین دی، دا چاپیریال تعریفوي په کوم کې چې پروګرامونه پرمخ ځي. د بایټ کوډ سربیره ، دا د بیچ حافظې ماډل هم تعریفوي (د بار لارښوونې په قطعي ډول په بیچ کې پلي کیږي) ، راجسترونه (A او X؛ جمع کونکي او شاخص راجسترونه) ، د سکریچ حافظې ذخیره ، او د برنامه برنامه کاونټر. په زړه پورې خبره دا ده چې د BPF بایټکوډ د موټروولا 6502 ISA وروسته ماډل شوی و. لکه څنګه چې سټیو مک کین په خپل کې یادونه وکړه بشپړ راپور په Sharkfest '11 کې، هغه په ​​Apple II کې د خپل عالي لیسې د ورځو پروګرام کولو څخه د 6502 جوړولو سره آشنا و، او دې پوهې د BPF بایټ کوډ ډیزاین کولو کې د هغه کار اغیزمن کړ.

د BPF مالتړ په لینکس کرنل کې په v2.5 او لوړو نسخو کې پلي کیږي، په عمده توګه د جې شولیسټ د هڅو لخوا اضافه شوی. د BPF کوډ تر 2011 پورې بدل نه و، کله چې ایریک ډوماسیټ د BPF ژباړونکي د JIT حالت کې د چلولو لپاره بیا ډیزاین کړ (سرچینه: د پاکټ فلټرونو لپاره JIT). له دې وروسته، کرنل، د BPF بایټکوډ تشریح کولو پرځای، کولی شي په مستقیم ډول د BPF پروګرامونه د هدف جوړښت ته واړوي: x86، ARM، MIPS، او نور.

وروسته، په 2014 کې، Alexey Starovoitov د BPF لپاره د نوي JIT میکانیزم وړاندیز وکړ. په حقیقت کې، دا نوی JIT د BPF پر بنسټ یو نوی جوړښت شو او د eBPF په نوم یاد شو. زه فکر کوم چې دواړه VMs د یو څه وخت لپاره یوځای شوي، مګر دا مهال د پیکټ فلټر کول د eBPF پراساس پلي کیږي. په حقیقت کې، د عصري اسنادو په ډیری مثالونو کې، BPF د eBPF په توګه پیژندل کیږي، او کلاسیک BPF نن د cBPF په نوم پیژندل کیږي.

eBPF د کلاسیک BPF مجازی ماشین په څو لارو غزوي:

  • د عصري 64-bit جوړښتونو پراساس. eBPF 64-bit راجسترونه کاروي او د شته راجسترونو شمیر له 2 (اکومولیټر او X) څخه 10 ته زیاتوي. eBPF اضافي اپکوډونه هم چمتو کوي (BPF_MOV, BPF_JNE, BPF_CALL...).
  • د شبکې پرت فرعي سیسټم څخه جلا شوی. BPF د بیچ ډیټا ماډل سره تړلی و. څرنګه چې دا د پاکټ فلټر کولو لپاره کارول کیده، د دې کوډ په فرعي سیسټم کې موقعیت درلود چې د شبکې ارتباطات چمتو کوي. په هرصورت، د eBPF مجازی ماشین نور د ډیټا ماډل سره تړلی ندی او د هر هدف لپاره کارول کیدی شي. نو، اوس د eBPF برنامه د ټریس پواینټ یا kprobe سره وصل کیدی شي. دا د eBPF وسیلو ته لاره پرانیزي، د فعالیت تحلیل، او د نورو کرنل فرعي سیسټمونو په شرایطو کې د کارونې ډیری نورو قضیو کې. اوس د eBPF کوډ په خپله لاره کې موقعیت لري: kernel/bpf.
  • نړیوال ډیټا پلورنځي د نقشې په نوم یادیږي. نقشې د ارزښت وړ پلورنځي دي چې د کارونکي ځای او د کرنل ځای ترمنځ د معلوماتو تبادله وړوي. eBPF ډیری ډوله نقشې چمتو کوي.
  • ثانوي دندې. په ځانګړي توګه ، د کڅوړې بیا لیکلو لپاره ، چیکسم محاسبه کړئ ، یا کڅوړه کلون کړئ. دا افعال د کرنل دننه پرمخ ځي او د کاروونکي ځای پروګرامونه ندي. تاسو کولی شئ د eBPF برنامو څخه سیسټم تلیفونونه هم وکړئ.
  • زنګونه ختم کړئ. په eBPF کې د پروګرام اندازه تر 4096 بایټ پورې محدوده ده. د ټیل کال فیچر د eBPF برنامه ته اجازه ورکوي چې کنټرول نوي eBPF برنامه ته انتقال کړي او پدې توګه دا محدودیت له پامه غورځوي (تر 32 پورې برنامې پدې ډول تړل کیدی شي).

eBPF: مثال

د لینکس کرنل سرچینو کې د eBPF لپاره ډیری مثالونه شتون لري. دوی په نمونو/bpf/ کې شتون لري. د دې مثالونو راټولولو لپاره، په ساده ډول دننه کړئ:

$ sudo make samples/bpf/

زه به پخپله د eBPF لپاره نوې بیلګه ونه لیکم، مګر په نمونو/bpf/ کې موجود نمونې به وکاروم. زه به د کوډ ځینې برخې وګورم او تشریح کړم چې دا څنګه کار کوي. د مثال په توګه، ما برنامه غوره کړه tracex4.

په عموم کې، په نمونو/bpf/ کې هر یو مثال دوه فایلونه لري. په دې حالت کې:

  • tracex4_kern.c، د سرچینې کوډ لري چې د eBPF بایټ کوډ په توګه په کرنل کې اجرا کیږي.
  • tracex4_user.c، د کارن ځای څخه یو برنامه لري.

په دې حالت کې، موږ باید تالیف وکړو tracex4_kern.c eBPF بایټکوډ ته. اوس مهال په کې gcc د eBPF لپاره هیڅ ملاتړ نشته. خوشبختانه، clang کولی شي د eBPF بایټکوډ تولید کړي. Makefile کاروي clang د تالیف لپاره tracex4_kern.c د اعتراض فایل ته.

ما پورته یادونه وکړه چې د eBPF یو له خورا زړه پورې ځانګړتیاو څخه نقشه ده. tracex4_kern یوه نقشه تعریفوي:

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 د eBPF لخوا وړاندیز شوي کارتونو ډیری ډولونو څخه یو دی. په دې حالت کې، دا یوازې یو هش دی. تاسو ممکن یو اعلان هم لیدلی وي SEC("maps"). SEC یو میکرو دی چې د بائنری فایل نوې برخې جوړولو لپاره کارول کیږي. په حقیقت کې، په مثال کې tracex4_kern دوه نورې برخې تعریف شوي:

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

دا دوه دندې تاسو ته اجازه درکوي چې د نقشې څخه یو ننوتل حذف کړئ (kprobe/kmem_cache_free) او په نقشه کې نوې ننوتۍ اضافه کړئ (kretprobe/kmem_cache_alloc_node). ټول فنکشن نومونه چې په لوی لیکونو کې لیکل شوي د میکرو سره مطابقت لري چې تعریف شوي bpf_helpers.h.

که زه د اعتراض فایل برخې ډمپ کړم، زه باید وګورم چې دا نوې برخې لا دمخه تعریف شوي دي:

$ 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

هم شته tracex4_user.c، اصلي پروګرام. په اصل کې، دا پروګرام پیښو ته غوږ نیسي kmem_cache_alloc_node. کله چې داسې پیښه رامنځ ته شي، اړونده eBPF کوډ اجرا کیږي. کوډ د اعتراض IP خاصیت په نقشه کې خوندي کوي، او اعتراض بیا د اصلي پروګرام له لارې لوپ کیږي. بېلګه:

$ 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

د کاروونکي ځای پروګرام او د eBPF پروګرام څنګه تړاو لري؟ په پیل کې tracex4_user.c د اعتراض فایل پورته کوي tracex4_kern.o د فنکشن په کارولو سره 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;
}

په کولو load_bpf_file د eBPF فایل کې تعریف شوي تحقیقات اضافه شوي /sys/kernel/debug/tracing/kprobe_events. اوس موږ د دې پیښو لپاره اورو او زموږ برنامه کولی شي یو څه وکړي کله چې دوی پیښیږي.

$ 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

نور ټول پروګرامونه په نمونه/bpf/ کې ورته جوړښت لري. دوی تل دوه فایلونه لري:

  • XXX_kern.c: eBPF پروګرام.
  • XXX_user.c: اصلي پروګرام

د eBPF برنامه د یوې برخې سره تړلې نقشې او دندې پیژني. کله چې کرنل د یو ځانګړي ډول پیښه مسله کوي (د مثال په توګه ، tracepoint)، تړل شوي دندې اجرا کیږي. کارتونه د کرنل برنامه او د کارونکي ځای برنامې ترمینځ اړیکه چمتو کوي.

پایلې

دا مقاله په عمومي شرایطو کې د BPF او eBPF په اړه بحث کوي. زه پوهیږم چې نن ورځ د eBPF په اړه ډیر معلومات او سرچینې شتون لري، نو زه به د نورو مطالعې لپاره یو څو نورې سرچینې وړاندیز وکړم

زه د لوستلو وړاندیز کوم:

سرچینه: www.habr.com

Add a comment