BPF استعمال ڪندي سڀ کان وڌيڪ مشهور اوزارن مان هڪ آهي tcpdump. جڏهن استعمال ڪندي پيڪيجز کي پڪڙڻ tcpdump استعمال ڪندڙ فلٽر پيڪيٽ لاء هڪ اظهار بيان ڪري سگهي ٿو. صرف هن ايڪسپريس سان ملندڙ پيڪيٽ کي پڪڙيو ويندو. مثال طور، اظهار "tcp dst port 80” بندرگاهه 80 تي پهچندڙ سڀني TCP پيڪٽس ڏانهن اشارو آهي. مرتب ڪندڙ هن اظهار کي مختصر ڪري سگهي ٿو ان کي 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
اھو اھو آھي جيڪو مٿي ڏنل پروگرام بنيادي طور تي ڪندو آھي:
ھدايتون (000): پيڪٽ لوڊ ڪريو آفسيٽ 12 تي، 16-bit لفظ جي طور تي، جمع ڪندڙ ۾. آفسٽ 12 پيڪٽ جي ايٿٽائپ سان ملندڙ جلندڙ آهي.
ھدايتون (001): 0x86dd سان گڏ ڪندڙ ۾ قدر جو مقابلو ڪري ٿو، اھو آھي، IPv6 لاءِ ايٿرائپ جي قيمت سان. جيڪڏهن نتيجو سچو آهي، ته پوء پروگرام جو انسداد وڃي ٿو هدايتون (002)، ۽ جيڪڏهن نه، ته پوء (006).
ھدايتون (006): 0x800 (IPv4 لاءِ ethertype ويل) سان قدر جي ڀيٽ ڪري ٿو. جيڪڏهن جواب صحيح آهي ته پوءِ پروگرام وڃي (007)، جيڪڏهن نه، ته پوءِ (015) ڏانهن.
۽ پوءِ تيستائين پيڪٽ فلٽرنگ پروگرام جو نتيجو موٽائي. اهو عام طور تي هڪ Boolean آهي. هڪ غير صفر قدر واپس ڪرڻ (هدايت (014)) جو مطلب آهي ته پيڪٽ قبول ڪيو ويو، ۽ صفر قيمت واپس ڪرڻ (هدايت (015)) جو مطلب آهي ته پيڪٽ قبول نه ڪيو ويو.
BPF ورچوئل مشين ۽ ان جو بائيٽ ڪوڊ 1992 جي آخر ۾ اسٽيو ميڪن ۽ وان جيڪبسن پاران تجويز ڪيو ويو جڏهن انهن جو پيپر شايع ڪيو ويو. بي ايس ڊي پيڪٽ فلٽر: نئين آرڪيٽيڪچر لاءِ يوزر-ليول پيڪٽ ڪيپچرهن ٽيڪنالاجي پهريون ڀيرو 1993 جي سياري ۾ Usenix ڪانفرنس ۾ پيش ڪيو ويو.
ڇاڪاڻ ته بي پي ايف هڪ مجازي مشين آهي، اهو ماحول کي بيان ڪري ٿو جنهن ۾ پروگرام هلن ٿا. بائيٽ ڪوڊ کان علاوه، اهو پڻ وضاحت ڪري ٿو بيچ ميموري ماڊل (لوڊ هدايتون واضح طور تي بيچ تي لاڳو ٿين ٿيون)، رجسٽرز (A ۽ X؛ جمع ڪندڙ ۽ انڊيڪس رجسٽرز)، اسڪريچ ميموري اسٽوريج، ۽ هڪ امڪاني پروگرام ڪائونٽر. دلچسپ ڳالهه اها آهي ته، BPF بائيٽ ڪوڊ موٽرولا 6502 ISA کان پوءِ ماڊل ڪيو ويو. جيئن Steve McCann پنهنجي ۾ ياد ڪيو مڪمل رپورٽ Sharkfest '11 تي، هو ايپل II تي پنهنجي هاءِ اسڪول جي ڏينهن جي پروگرامنگ کان 6502 کان واقف هو، ۽ هن ڄاڻ هن جي ڪم کي متاثر ڪيو BPF بائيٽ ڪوڊ ڊزائين ڪرڻ.
BPF سپورٽ لينڪس ڪرنل ۾ ورزن v2.5 ۽ اعليٰ ۾ لاڳو ڪئي وئي آهي، خاص طور تي Jay Schullist جي ڪوششن سان شامل ڪيو ويو آهي. BPF ڪوڊ 2011 تائين تبديل نه ٿيو، جڏهن Eric Dumaset BPF مترجم کي JIT موڊ ۾ هلائڻ لاءِ نئين سر ترتيب ڏنو (ذريعو: پيڪٽ فلٽرن لاءِ JIT). ان کان پوء، ڪرنل، BPF bytecode جي تعبير ڪرڻ بدران، سڌو BPF پروگرامن کي ٽارگيٽ فن تعمير ۾ تبديل ڪري سگھي ٿو: x86، ARM، MIPS، وغيره.
بعد ۾، 2014 ۾، Alexey Starovoitov BPF لاء نئين JIT ميڪانيزم جي تجويز پيش ڪئي. حقيقت ۾، هي نئين JIT هڪ نئين BPF تي ٻڌل فن تعمير بڻجي وئي ۽ سڏيو ويو eBPF. منهنجو خيال آهي ته ٻئي VMs ڪجهه وقت لاءِ گڏ هئا، پر في الحال پيڪٽ فلٽرنگ لاڳو ڪئي وئي آهي اي بي پي ايف جي بنياد تي. حقيقت ۾، جديد دستاويزن جي ڪيترن ئي مثالن ۾، BPF کي eBPF سمجهيو ويندو آهي، ۽ ڪلاسيڪل BPF اڄ cBPF طور سڃاتو وڃي ٿو.
eBPF ڪيترن ئي طريقن سان کلاسک BPF ورچوئل مشين کي وڌايو:
جديد 64-bit آرڪيٽيڪچر جي بنياد تي. eBPF 64-bit رجسٽر استعمال ڪري ٿو ۽ دستياب رجسٽرن جو تعداد وڌائي ٿو 2 (accumulator and X) کان 10 تائين. eBPF اضافي اپڪوڊس پڻ مهيا ڪري ٿو (BPF_MOV, BPF_JNE, BPF_CALL...).
نيٽ ورڪ پرت سبسسٽم کان ڌار. بي پي ايف بيچ ڊيٽا ماڊل سان ڳنڍيل هو. جيئن ته اهو پيڪيٽ فلٽرنگ لاءِ استعمال ڪيو ويو، ان جو ڪوڊ سب سسٽم ۾ واقع هو جيڪو نيٽ ورڪ ڪميونيڪيشن مهيا ڪري ٿو. بهرحال، eBPF ورچوئل مشين هاڻي ڊيٽا ماڊل سان ڳنڍيل ناهي ۽ ڪنهن به مقصد لاءِ استعمال ٿي سگهي ٿي. تنهن ڪري، هاڻي eBPF پروگرام کي ڳنڍي سگھجي ٿو tracepoint يا kprobe سان. اهو رستو کوليندو آهي اي بي پي ايف اوزار، ڪارڪردگي تجزيي، ۽ ٻين ڪنيل سب سسٽم جي حوالي سان ٻين ڪيترن ئي استعمال جي ڪيسن ۾. ھاڻي eBPF ڪوڊ پنھنجي رستي ۾ واقع آھي: kernel/bpf.
گلوبل ڊيٽا اسٽورن کي Maps سڏيو ويندو آهي. نقشا اھم قدر اسٽور آھن جيڪي صارف جي جڳھ ۽ ڪرنل اسپيس جي وچ ۾ ڊيٽا جي مٽاسٽا کي فعال ڪن ٿا. eBPF ڪيترن ئي قسمن جا نقشا مهيا ڪري ٿو.
ثانوي ڪم. خاص طور تي، هڪ پيڪيج کي ٻيهر لکڻ لاء، هڪ چيڪسم کي ڳڻڻ، يا هڪ پيڪيج کي کلون ڪرڻ لاء. اهي ڪم ڪارنيل اندر هلندا آهن ۽ صارف-اسپيس پروگرام نه آهن. توهان پڻ ڪري سگهو ٿا سسٽم ڪالون اي بي پي ايف پروگرامن مان.
ڪال ختم ڪريو. اي بي پي ايف ۾ پروگرام جي سائيز 4096 بائيٽ تائين محدود آهي. دم ڪال جي خصوصيت هڪ اي بي پي ايف پروگرام کي اجازت ڏئي ٿي ته ڪنٽرول کي نئين اي بي پي ايف پروگرام ڏانهن منتقل ڪري ۽ اهڙيءَ طرح هن حد کان پاسو ڪيو (32 پروگرامن تائين هن طريقي سان ڳنڍيل ٿي سگهن ٿا).
eBPF: مثال
لينڪس ڪنييل ذريعن ۾ اي بي پي ايف لاء ڪيترائي مثال آهن. اهي نموني/bpf/ تي دستياب آهن. انهن مثالن کي گڏ ڪرڻ لاء، صرف داخل ڪريو:
$ sudo make samples/bpf/
مان پاڻ eBPF لاءِ نئون مثال نه لکندس، پر نمونن/bpf/ ۾ موجود نمونن مان ھڪڙو استعمال ڪندس. مان ڪوڊ جا ڪجهه حصا ڏسندس ۽ وضاحت ڪندس ته اهو ڪيئن ڪم ڪري ٿو. مثال طور، مون پروگرام چونڊيو tracex4.
عام طور تي، نمونن ۾ هر هڪ مثال/bpf/ ٻن فائلن تي مشتمل آهي. هن معاملي ۾:
tracex4_kern.c, تي مشتمل آهي سورس ڪوڊ جنهن تي عمل ڪيو وڃي ٿو ڪنيل ۾ eBPF bytecode طور.
tracex4_user.c, استعمال ڪندڙ جي جاء کان هڪ پروگرام تي مشتمل آهي.
هن معاملي ۾، اسان کي گڏ ڪرڻ جي ضرورت آهي tracex4_kern.c eBPF bytecode ڏانهن. في الحال ۾ gcc eBPF لاءِ ڪو به پسمنظر ناهي. خوشقسمتيءَ سان، clang eBPF bytecode ڪڍي سگھي ٿو. Makefile استعمال ڪري ٿو clang گڏ ڪرڻ لاء tracex4_kern.c اعتراض فائل ڏانهن.
مون مٿي ذڪر ڪيو آهي ته اي بي پي ايف جي سڀ کان دلچسپ خاصيتن مان هڪ نقشا آهن. tracex4_kern ھڪڙو نقشو بيان ڪري ٿو:
پڻ آهي 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
يوزر اسپيس پروگرام ۽ اي بي پي ايف پروگرام ڪيئن لاڳاپيل آهن؟ شروعات تي 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;
}
نموني/bpf/ ۾ ٻيا سڀئي پروگرام ساڳيا ترتيب ڏنل آهن. اهي هميشه ٻن فائلن تي مشتمل آهن:
XXX_kern.c: eBPF پروگرام.
XXX_user.c: مکيه پروگرام.
eBPF پروگرام نقشن جي سڃاڻپ ڪري ٿو ۽ ھڪڙي حصي سان لاڳاپيل ڪم. جڏهن ڪنيل هڪ خاص قسم جو واقعو جاري ڪري ٿو (مثال طور، tracepoint)، پابند افعال تي عمل ڪيو وڃي ٿو. ڪارڊ ڪنييل پروگرام ۽ يوزر اسپيس پروگرام جي وچ ۾ رابطي کي مهيا ڪن ٿا.
ٿڪل
هن مقالي ۾ عام اصطلاحن ۾ BPF ۽ eBPF تي بحث ڪيو ويو. مون کي خبر آهي ته اڄڪلهه اي بي پي ايف بابت تمام گهڻي معلومات ۽ وسيلا موجود آهن، تنهنڪري آئون وڌيڪ مطالعي لاءِ ڪجهه وڌيڪ وسيلن جي سفارش ڪندس
eBPF جو مڪمل تعارف برينڊن گريگ. LWN.net کان آرٽيڪل. برينڊن اڪثر ڪري اي بي پي ايف بابت ٽوئيٽ ڪندو آهي ۽ هن جي موضوع تي وسيلن جي فهرست برقرار رکندو آهي. بلاگ پوسٽ.
BPF ۽ eBPF تي نوٽس جوليا ايوانز. سوچيڪرا شرما پاران پيش ڪيل پيشڪش تي تبصرا ”دي بي ايس ڊي پيڪٽ فلٽر: هڪ نئون آرڪيٽيڪچر فار يوزر ليول پيڪٽ ڪيپچر“. تبصرا سٺا آهن ۽ حقيقت ۾ توهان جي سلائڊ کي سمجهڻ ۾ مدد ڪن ٿا.
eBPF، حصو 1: ماضي، حال ۽ مستقبل فيرس ايلس. سان گڏ ڊگهو تسلسل، پر اهو پڙهڻ جي لائق آهي. ھڪڙو بھترين مضمونن مان جيڪو مون وٽ آيو آھي اي بي پي ايف تي.